当前位置: 首页 > news >正文

8. Spring Ai之入门到精通(超级详细)

简介

        2024年5月30号Spring AI 的 1.0.0 里程碑 1 版本发布。表明版本已正在巩固,并且大部分主要错误和问题已经解决,API基本已确定,不会发生很大的变化。

       在与大模型集成方面,继LangChain4j之后,又一重大的框架诞生。标志着在人工智能的浪潮中,Java不会因此被边缘化,让生成式人工智能应用程序不仅适用于Python,也适用于Java。

Spring Ai官网:Spring AI

前置准备

        Spring Ai除了支持国外的大模型外,也支持国内很多大模型,比如清华的智普Ai,百度的千帆和月之暗面的 kimi。集成Spring Ai需要用到 api-key,大家按照自己的需要,去Ai开放平台申请。

        下面我主要用到OpenAi和智普Ai来讲解案例代码,OpenAi是国外的,需要我们要有个国外手机号(亚洲很多被封了,用不了),登录OpenAi官网创建apikey(需要用到魔法软件科学上网)。下面给出各个注册渠道.

Open-AI:

  • OpenAi-HK  GPT4.0 API KEY By OPENAI HK 中转ChatGPT  (本文用这种,不用翻)

  • AiCore API  New API

  • OpenAi购买平台 首页 | OpenAI_GPT4_购买平台_OpenAI API - eylink官网

ZhiPu-AI:

  • 官网 智谱AI开放平台

概念和案例实践

 新建SpringBoot工程,然后添加以下依赖:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.2.4</version></parent><modelVersion>4.0.0</modelVersion><groupId>org.gorgor</groupId><artifactId>spring-ai-demo</artifactId><version>1.0-SNAPSHOT</version><properties><maven.compiler.source>17</maven.compiler.source><maven.compiler.target>17</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><dependencyManagement><dependencies><dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-bom</artifactId><version>1.0.0-M1</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-openai-spring-boot-starter</artifactId></dependency><dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-zhipuai-spring-boot-starter</artifactId></dependency></dependencies><repositories><repository><id>spring-milestones</id><name>Spring Milestones</name><url>https://repo.spring.io/milestone</url><snapshots><enabled>false</enabled></snapshots></repository><repository><id>spring-snapshots</id><name>Spring Snapshots</name><url>https://repo.spring.io/snapshot</url><releases><enabled>false</enabled></releases></repository></repositories>
</project>

    添加application.yml配置文件

        需要配置智普api-key和openai api-key.

server:port: 10096
spring:application:name: ai-demoai:zhipuai:api-key: ${ZHIPUAI_API_KEY}chat:options:model: glm-3-turboembedding:enabled: falseopenai:api-key: ${OPENAI_API_KEY}base-url: https://api.openai-hk.comchat:options:model: gpt-4o-miniembedding:enabled: true
 1. ChatClient 和 ChatModel

        ChatClient是SpringAI 0.8.0版本的概念,到1.0.0版本变成了ChatModel,但同时保留了ChatClient,ChatClient底层还是调用ChatModel,ChatClient支持Fluent Api,ChatModel不支持。两者都是表示某个模型,具体是什么模型,需要看配置。

    基于ChatClient 和 ChatModel 实现聊天效果:

@Configuration
public class ChatConfig {@Autowiredprivate OpenAiChatModel openAiChatModel;@Beanpublic ChatClient chatClient() {return ChatClient.builder(openAiChatModel).build();}
}

Controller层代码:

@RestController
public class ChatDemoController {@Autowiredprivate ChatClient chatClient;@Autowiredprivate ZhiPuAiChatModel chatModel;@Autowiredprivate OpenAiChatModel openAiChatModel;/*** openAi 聊天** @param message* @return*/@GetMapping("/ai/openAiChat")public Map openAiChat(@RequestParam(value = "message", defaultValue = "Tell me a joke") String message) {return Map.of("generation", openAiChatModel.call(message));}/*** zhipuAi 聊天** @param message* @return*/@GetMapping("/ai/generate")public Map generate(@RequestParam(value = "message", defaultValue = "Tell me a joke") String message) {return Map.of("generation", chatModel.call(message));}/*** ChatClient使用(流式调用)* @param message* @param voice* @return*/@GetMapping("/ai/chatClient")Map<String, String> completion(@RequestParam(value = "message", defaultValue = "Tell me a joke") String message, String voice) {return Map.of("completion",chatClient.prompt().system(sp -> sp.param("voice", voice)).user(message).call().content());}
}
2. 文生图
@RestController
public class ChatDemoController {@Autowiredprivate OpenAiImageModel imageModel;/*** 图片生成(文生图)** @param message* @return*/@GetMapping("/ai/imageGeneration")public Map imageGeneration(@RequestParam(value = "message", defaultValue = "Tell me a joke") String message) {OpenAiImageOptions imageOptions = OpenAiImageOptions.builder().withQuality("hd").withN(1).withHeight(1024).withWidth(1024).build();ImagePrompt imagePrompt = new ImagePrompt(message, imageOptions);ImageResponse response = imageModel.call(imagePrompt);return Map.of("generation", response.getResult().getOutput().getUrl());}
}
3. 多模态

多模态(Multimodal)指的是数据或信息的多种表现形式。在人工智能领域,我们经常会听到这个词,尤其是在近期大型模型(如GPT-4)开始支持多模态之后。

  •  模态:模态是指数据的一种形式,例如文本、图像、音频等。每一种形式都是一种模态。
  • 多模态:多模态就是将不同模态的数据结合起来,以更全面、更丰富的方式来处理信息。比如,我们可以同时处理文本、图像、语音等多种类型的数据。

举个例子,如果我想告诉你“我有一个苹果”,我可以用文字写出来,也可以用语言说出来,还可以用图片画出来。这就是相同信息的多种模态表现形式。

同样地,给大模型一副图片,可以上大模型对这张图片进行详细地描述。给大模型一段文本,可以让大模型进行概要提取,内容总结等。

@RestController
public class ChatDemoController {@Autowiredprivate OpenAiChatModel openAiChatModel;/*** 多模态** @param message* @return* @throws MalformedURLException*/@GetMapping("/ai/multimodal")public String Multimodal(@RequestParam(value = "message", defaultValue = "解释一下你在这张图片上看到了什么?") String message) throws MalformedURLException {var userMessage = new UserMessage(message,List.of(new Media(MimeTypeUtils.IMAGE_PNG,new URL("https://docs.spring.io/spring-ai/reference/1.0-SNAPSHOT/_images/multimodal.test.png"))));ChatResponse response = openAiChatModel.call(new Prompt(List.of(userMessage),OpenAiChatOptions.builder().withModel(OpenAiApi.ChatModel.GPT_4_O.getValue()).build()));return response.getResult().getOutput().getContent();}
}
4. 语音转文字

        语音文件需要在spring-ai中下载spring-ai/models/spring-ai-openai/src/test/resources/speech at main · spring-projects/spring-ai · GitHubAn Application Framework for AI Engineering. Contribute to spring-projects/spring-ai development by creating an account on GitHub.icon-default.png?t=N7T8https://github.com/spring-projects/spring-ai/tree/main/models/spring-ai-openai/src/test/resources/speech

@RestController
public class ChatDemoController {@Autowiredprivate OpenAiAudioTranscriptionModel openAiAudioTranscriptionModel;@Value("classpath:/speech/jfk.flac")private Resource audioFile;/*** 语音转文字*/@GetMapping("/ai/audioTranscription")private String audioTranscription(){OpenAiAudioTranscriptionOptions transcriptionOptions = OpenAiAudioTranscriptionOptions.builder().withResponseFormat(OpenAiAudioApi.TranscriptResponseFormat.TEXT).withTemperature(0f).build();AudioTranscriptionPrompt transcriptionRequest = new AudioTranscriptionPrompt(audioFile, transcriptionOptions);AudioTranscriptionResponse response = openAiAudioTranscriptionModel.call(transcriptionRequest);return response.getResult().getOutput();}
}
5. Function Calling 工具调用

        大模型是基于历史数据进行训练的,回答我们的问题也是基于历史数据进行回复, 如果你想要大模型具备获取最新消息的能力, 此时,就需要用到工具机制,它能帮助大模型获取最新的数据消息.

Function Calling 工作原理图:

  执行流程,如下图:

  首先,当我们发送问题给大模型的时候,比如“今天是几号?”,大模型会响应一个结果给我们,这个结果不是问题的答案,而是大模型告诉我们需要执行哪个工具。我们执行工具后,才能得到问题的答案,但这个答案可能不太像人回复的,不太符合自然语言的样子,比如工具结果是“2024-07-13 11:23:00”,此时我们需要把问题,执行工具请求和工具执行结果一起发给大模型,得到最好的答案。

工具定义:

  • 实现 java.util.function.Function 接口
  • @Description注解: 注释是可选的,它提供了一个函数描述,帮助模型理解何时调用函数。它是一个重要的属性,可以帮助AI模型确定要调用的客户端函数。

  • @JsonClassDescription注解: 对方法进行描述.

  • @JsonPropertyDescription注解: 对参数进行描述.

 代码实现:

@Component
@Description("先获取指定地点,再获取当前时间")
public class DateService implements Function<DateService.Request, DateService.Response> {@JsonClassDescription("地点请求")public record Request(@JsonPropertyDescription("地点")String address) { }public record Response(String date) { }@Overridepublic Response apply(Request request) {System.out.println(request.address);return new Response(String.format("%s的当前时间是%s", request.address, LocalDateTime.now()));}
}

工具调用:

@RestController
public class ChatDemoController {@Autowiredprivate OpenAiChatModel openAiChatModel;/*** 工具调用*/@GetMapping("/ai/function")public String function(@RequestParam String message) {Prompt prompt = new Prompt(message, OpenAiChatOptions.builder().withFunction("dateService").build());
//        Prompt prompt = new Prompt(message, OpenAiChatOptions.builder().withFunctionCallbacks(
//                List.of(FunctionCallbackWrapper.builder(new DateService())
//                        .withName("dateService")
//                        .withDescription("获取指定地点的当前时间").build())
//        ).build());Generation generation = openAiChatModel.call(prompt).getResult();return (generation != null) ? generation.getOutput().getContent() : "";}
}
6.  Embeddings文本向量化

        什么叫向量?  向量可以理解为平面坐标中的一个坐标点(x,y),在编程领域,一个二维向量就是一个大小为float类型的数组。也可以用三维坐标系中的向量表示一个空间中的点.  而文本向量化是指,利用大模型可以把一个字,一个词或一段话映射为一个多维向量.

        为什么要向量化? 当我们把所有的文本生成向量后, 就可以利用向量的特点,进行相似度搜索.这种搜索算法比elasticsearch的分词算法更好.

Spring AI 支持的向量数据库:

  • Azure Vector Search - The Azure vector store.

  • Apache Cassandra - The Apache Cassandra vector store.

  • Chroma Vector Store - The Chroma vector store.

  • Elasticsearch Vector Store - The Elasticsearch vector store.

  • GemFire Vector Store - The GemFire vector store.

  • Milvus Vector Store - The Milvus vector store.

  • MongoDB Atlas Vector Store - The MongoDB Atlas vector store.

  • Neo4j Vector Store - The Neo4j vector store.

  • PgVectorStore - The PostgreSQL/PGVector vector store.

  • Pinecone Vector Store - PineCone vector store.

  • Qdrant Vector Store - Qdrant vector store.

  • Redis Vector Store - The Redis vector store.

  • SAP Hana Vector Store - The SAP HANA vector store.

  • Weaviate Vector Store - The Weaviate vector store.

  • SimpleVectorStore - A simple implementation of persistent vector storage, good for educational purposes.

以下我们使用Redis作为向量数据库

然后需要注意的是,普通的Redis是不支持向量存储和查询的,需要额外的redisearch模块,我这边是直接使用docker来运行一个带有redisearch模块的redis容器的,命令为:

docker run -p 6379:6379 redis/redis-stack-server:latest

注意端口6379不要和你现有的Redis冲突了。

引入redis依赖

        <dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-redis-store</artifactId></dependency><dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>5.1.0</version></dependency>

 定义向量模型和Redis向量数据库 Bean

@Configuration
public class RedisConfig {@Autowiredprivate EmbeddingModel openAiEmbeddingModel;@Beanpublic RedisVectorStore vectorStore() {RedisVectorStore.RedisVectorStoreConfig config = RedisVectorStore.RedisVectorStoreConfig.builder().withURI("redis://127.0.0.1:6379")
//                .withIndexName("rag_index")
//                .withPrefix("rag:").withMetadataFields(RedisVectorStore.MetadataField.text("filename"),RedisVectorStore.MetadataField.text("question")).build();return new RedisVectorStore(config, openAiEmbeddingModel,true);}@Beanpublic EmbeddingModel openAiEmbeddingModel() {// Can be any other EmbeddingModel implementation.return new OpenAiEmbeddingModel(new OpenAiApi(System.getenv("OPENAI_API_KEY")));}
}

 定义向量存储和搜索核心逻辑代码

文本读取,解析和存储,SpringAi提供了以下核心概念:

Document

  1. DocumentReader:用来读取TXT、PDF等文件内容                                          
    • JsonReader:读取JSON格式的文件
    •  TextReader:读取txt文件
    • PagePdfDocumentReader:使用Apache PdfBox读取PDF文件
    • TikaDocumentReader:使用Apache Tika来读取PDF, DOC/DOCX, PPT/PPTX, and HTML等文件
  2. DocumentTransformer:用来解析文件内容
    • tokenTextSplitter:按照token进行解析。

  3. DocumentWriter:用来写入文件内容到向量数据库
    • VectorStore:DocumentWriter的子类。

流程如下:

/**
*
*文本解析
*/
public class CustomerTextSplitter extends TextSplitter {@Overrideprotected List<String> splitText(String text) {return List.of(split(text));}public String[] split(String text) {return text.split("\\s*\\R\\s*\\R\\s*");}
}
@Component
public class DocumentService {@Value("classpath:meituan-qa.txt")private Resource resource;@Autowiredprivate RedisVectorStore vectorStore;/*** 向量存储* @return*/public List<Document> loadText() {//文本读取TextReader textReader = new TextReader(resource);textReader.getCustomMetadata().put("filename", "meituan-qa.txt");List<Document> documents = textReader.get();CustomerTextSplitter customerTextSplitter= new CustomerTextSplitter();List<Document> list = customerTextSplitter.apply(documents);// 把问题存到元数据中list.forEach(document -> document.getMetadata().put("question", document.getContent().split("\\n")[0]));// 向量存储(文本存储)vectorStore.add(list);return list;}/*** 向量搜索* @param message* @return*/public List<Document> search(String message) {List<Document> documents = vectorStore.similaritySearch(message);return documents;}/*** 元数据搜索* @param message* @param question* @return*/public List<Document> metadataSearch(String message, String question) {return vectorStore.similaritySearch(SearchRequest.query(message)
//                        .withTopK(5).withSimilarityThreshold(0.1).withFilterExpression(String.format("question in ['%s']", question)));}
}

   需要向量的文本 meituan-qa.txt

Q:在线支付取消订单后钱怎么返还?
订单取消后,款项会在一个工作日内,直接返还到您的美团账户余额。Q:怎么查看退款是否成功?
退款会在一个工作日之内到美团账户余额,可在“账号管理——我的账号”中查看是否到账。Q:美团账户里的余额怎么提现?
余额可到美团网(meituan.com)——“我的美团→美团余额”里提取到您的银行卡或者支付宝账号,另外,余额也可直接用于支付外卖订单(限支持在线支付的商家)。Q:余额提现到账时间是多久?
1-7个工作日内可退回您的支付账户。由于银行处理可能有延迟,具体以账户的到账时间为准。Q:申请退款后,商家拒绝了怎么办?
申请退款后,如果商家拒绝,此时回到订单页面点击“退款申诉”,美团客服介入处理。Q:怎么取消退款呢?
请在订单页点击“不退款了”,商家还会正常送餐的。Q:前面下了一个在线支付的单子,由于未付款,订单自动取消了,这单会计算我的参与活动次数吗?
不会。如果是未支付的在线支付订单,可以先将订单取消(如果不取消需要15分钟后系统自动取消),订单无效后,此时您再下单仍会享受活动的优惠。Q:为什么我用微信订餐,却无法使用在线支付?
目前只有网页版和美团外卖手机App(非美团手机客户端)订餐,才能使用在线支付,请更换到网页版和美团外卖手机App下单。Q:如何进行付款?
美团外卖现在支持货到付款与在线支付,其中微信版与手机触屏版暂不支持在线支付。

    Controller层代码实现

@RestController
public class ChatDemoController {@Autowiredprivate DocumentService documentService;/*** 向量存储*/@GetMapping("/ai/vectorStore")public Map vectorStore() {List<Document> documents = documentService.loadText();return Map.of("generation", documents);}/*** 向量搜索* @param message* @return*/@GetMapping("/ai/documentSearch")public List<Document> documentSearch(@RequestParam String message) {return documentService.search(message);}/*** 元数据搜索* @param message* @param question* @return*/@GetMapping("/ai/metadataSearch")public List<Document> documentMetadataSearch(@RequestParam String message, @RequestParam String question) {return documentService.metadataSearch(message, question);}
}
7. RAG 检索增强生成

        RAG是什么?检索增强生成又是什么意思?大模型的知识仅限于它所训练的数据,如果你问大模型,你们公司的xxx产品有什么作用,大模型肯定会回答不出来。如果你想让大模型拥有你们公司知识库的数据, 此时就可以用到RAG。

        简单的讲,RAG的原理是,根据用户输入的问题,先从你们公司的知识库查询出答案,再把用户输的问题和搜索出来的答案,让大模型根据我们的答案回复用户的问题。

         而根据用户问题,从知识库搜索问题,需要用到上面所说的文本向量化。根据文本的相识度,从知识库中搜索出符合用户问题的答案出来。

RAG的工作原理

RAG的工作原理可以分为以下几个步骤:

1.接收请求:首先,系统接收到用户的请求(例如提出一个问题)。

2.信息检索(R):系统从一个大型文档库中检索出与查询最相关的文档片段。这一步的目标是找到那些可能包含答案或相关信息的文档。

3.生成增强(A):将检索到的文档片段与原始查询一起输入到大模型(如chatGPT)中,注意使用合适的提示词,比如原始的问题是XXX,检索到的信息是YYY,给大模型的输入应该类似于:请基于YYY回答XXXX。

4.输出生成(G):大模型基于输入的查询和检索到的文档片段生成最终的文本答案,并返回给用户。

RAG代码实现

@RestController
public class ChatDemoController {@Autowiredprivate OpenAiChatModel openAiChatModel;@Autowiredprivate DocumentService documentService;/*** RAG* @param message* @return*/@GetMapping("/ai/customerService")public String customerService(@RequestParam String message) {// 向量搜索List<Document> documentList = documentService.search(message);// 提示词模板PromptTemplate promptTemplate = new PromptTemplate("{userMessage}\n\n 用以下信息回答问题:\n {contents}");// 组装提示词Prompt prompt = promptTemplate.create(Map.of("userMessage", message, "contents", documentList));// 调用大模型return openAiChatModel.call(prompt).getResult().getOutput().getContent();}
}

8. Advisor机制

        Advisor是Spring AOP中的概念, 一个Advisor表示一个切面, 由Advice和PointCut组成,Advice表示切面的逻辑, PointCut表示切点, 也就是切那些方法.而Spring AI也用了Advisor的设计思想, 也具备前置切面和后置切面.

8.1 QuestionAnswerAdvisor

QuestionAnswerAdvisor的作用是对问题请求进行增强,增强逻辑为:

  1. 根据原始问题进行相似度搜索,得到匹配知识点
  2. 拼接RAG提示词模板

评估模型代码如下:

@RestController
public class ChatDemoController {@Autowiredprivate ChatClient chatClient;@Autowiredprivate RedisVectorStore vectorStore;@Autowiredprivate OpenAiChatModel chatModel;/*** 模型评估*/@GetMapping("/ai/evaluation")public EvaluationResponse evaluation(String message) {//RAGChatResponse response = chatClient.prompt().advisors(new QuestionAnswerAdvisor(vectorStore, SearchRequest.defaults())).user(message).call().chatResponse();// 评估器var relevancyEvaluator = new RelevancyEvaluator(ChatClient.builder(chatModel));// 评估请求EvaluationRequest evaluationRequest = new EvaluationRequest(message,(List<Content>) response.getMetadata().get(QuestionAnswerAdvisor.RETRIEVED_DOCUMENTS), response);// 评估结果EvaluationResponse evaluationResponse = relevancyEvaluator.evaluate(evaluationRequest);return evaluationResponse;}
}

        后续Spring AI会根据增强后的请求进行提示词模版的变量填充,得到请求最终的提示词,并将请求发送给大模型,得到大模型的返回结果,QuestionAnswerAdvisor也会对返回结果进行增强,会把匹配的知识点放入ChatResponse的metadata中。 

8.2 MessageChatMemoryAdvisor

        是一种Advisor,也是用来增强问答请求和响应的,而其中另外一个概念就是ChatMemory,默认实现为InMemoryChatMemory,它可以用来按conversationId进行历史对话记录的存储。

@RestController
public class ChatDemoController {@Autowiredprivate ChatClient chatClient;private InMemoryChatMemory chatMemory= new InMemoryChatMemory();/*** ChatMemory*/@GetMapping("/ai/chatMemory")private String chatMemory(String message,String userId){ChatResponse response = chatClient.prompt().advisors(new MessageChatMemoryAdvisor(chatMemory,userId,100)).system(sp -> sp.param("voice", "律师")).user(message).call().chatResponse();return response.getResult().getOutput().getContent();}
}

因此MessageChatMemoryAdvisor的作用就是将原始请求和向量添加到ChatMemory中。

8.3 PromptChatMemoryAdvisor

        也是用来记录历史对话记录的,和MessageChatMemoryAdvisor的不同点在于,MessageChatMemoryAdvisor是把每个历史请求和响应封装为Message增强到请求中,而PromptChatMemoryAdvisor是把所有请求和响应也会存到ChatMemory中,但是会把所有内容合并一条Message增强到请求中。

8.4 VectorStoreChatMemoryAdvisor

        这个就更加强大了,它既会进行RAG,也会把存储历史对话,只不过会把对话记录封装为Document存到向量数据库中。

相关文章:

8. Spring Ai之入门到精通(超级详细)

简介 2024年5月30号Spring AI 的 1.0.0 里程碑 1 版本发布。表明版本已正在巩固&#xff0c;并且大部分主要错误和问题已经解决&#xff0c;API基本已确定&#xff0c;不会发生很大的变化。 在与大模型集成方面&#xff0c;继LangChain4j之后&#xff0c;又一重大的框架诞生。标…...

寄存器和硬件的关系

寄存器也是一种存储器&#xff0c;只不过普通的存储器只能写和读。里面的数据并没有赋予什么实际意义。但是寄存器就不一样了&#xff0c;寄存器的每一位数据&#xff0c;都对应了硬件电路的状态。寄存器和外设的硬件电路&#xff0c;是可以进行互动的。所以&#xff0c;程序到…...

【WEB】ctfshow-萌新-web9-15

文章目录 题目介绍&#xff1a;题目分析&#xff1a;payload&#xff1a; 题目介绍&#xff1a; ctfshow-萌新计划-web9-15 <?php # flag in config.php include("config.php"); if(isset($_GET[c])){$c $_GET[c];if(preg_match("/system|exec|highlight…...

【Vulnhub靶场AI-WEB-1.0打靶教程】

第一步&#xff1a;查看虚拟机的ip 第二步&#xff1a;扫描ip下开放的80端口 第三步&#xff1a;扫描查到的ip地址下的目录 第四步&#xff1a;访问查到的目录 访问robot.txt 第五步:访问robot.txt显示出的目录 第六步&#xff1a;打开kali终端&#xff0c;使用sqlmap功能 sq…...

html实现酷炫美观的可视化大屏(十种风格示例,附源码)

文章目录 完整效果演示1.蓝色流线风的可视化大屏1.1 大屏效果1.2 大屏代码1.3 大屏下载 2.地图模块风的可视化大屏2.1 大屏效果2.2 大屏代码2.3 大屏下载 3.科技轮动风的可视化大屏3.1 大屏效果3.2 大屏代码3.3 大屏下载 4.蓝色海洋风的可视化大屏4.1 大屏效果4.2 大屏代码4.3 …...

【C++BFS算法 二分查找】2812. 找出最安全路径

本文涉及知识点 CBFS算法 C二分查找 LeetCode2812. 找出最安全路径 给你一个下标从 0 开始、大小为 n x n 的二维矩阵 grid &#xff0c;其中 (r, c) 表示&#xff1a; 如果 grid[r][c] 1 &#xff0c;则表示一个存在小偷的单元格 如果 grid[r][c] 0 &#xff0c;则表示一…...

轻触开关 KH-4.5X4.5X5.5H-STM

品  牌&#xff1a; kinghelm(金航标) 厂家型号&#xff1a; KH-4.5X4.5X5.5H-STM 封装&#xff1a; SMD 商品毛重&#xff1a; 0.317克(g) 包装方式&#xff1a; 编带...

3.redis客户端

1.命令行客户端 在安装redis的时候就已经安装好了&#xff0c;就是redis-cli redis-cli -h 127.0.0.1 -p 6379 -a 123456 -a 表示密码 -h 表示ip&#xff0c;不配置默认为本机 127.0.0.1 -p 表示端口&#xff0c;不配置默认为 6379 进入后可以输入ping&#xff0c;返回pong代表…...

Rust配置国内源,解决安装依赖慢问题

温馨提示&#xff1a;最新内容仅在原文更新。 国内源使用字节的RsProxy https://rsproxy.cn/ 解决rust-analyzer加载时间过长(请参考本文) 配置环境变量 Mac export RUSTUP_DIST_SERVER"https://rsproxy.cn" export RUSTUP_UPDATE_ROOT"https://rsproxy.cn/r…...

AI学习指南机器学习篇- Q学习的参数与调优

AI学习指南机器学习篇- Q学习的参数与调优 在强化学习领域中&#xff0c;Q学习是一种经典的算法&#xff0c;可以用来解决各种问题&#xff0c;包括游戏和机器人控制等。Q学习算法的性能很大程度上取决于一些重要的参数&#xff0c;例如学习率和折扣因子。本文将介绍这些参数的…...

《小迪安全》学习笔记02

域名默认存放目录和IP默认存放目录不一样。 IP地址是WWW文件里的&#xff0c;域名访问是WWW里的一个子目录里的&#xff08;比如是blog&#xff09;。 Nmap: Web源码拓展 拿到一个网站的源码&#xff0c;要分析这几个方面↑。 不同类型产生的漏洞类型也不一样 在网站中&…...

C语言:自定义类型进阶(结构体、联合体、枚举)

自定义类型&#xff08;结构体、联合体、枚举&#xff09; 一、结构体&#xff08;一&#xff09;结构体的内存对齐1、结构体内存对齐规则&#xff08;1&#xff09;引子&#xff08;2&#xff09;offsetof 宏函数&#xff08;3&#xff09;内存对齐原理&#xff08;4&#xff…...

SPSSAU | 最好最差权重BWM原理及案例实操分析

BWM&#xff08;best-worse-method&#xff0c;最好最差法&#xff09;是一种多准则决策方法&#xff0c;由Jafar Rezaei于2015年提出&#xff0c;其通常用于确定决策标准的权重。其原理是比如5个指标&#xff0c;如果以前AHP就需要5个指标两两的相对重要性数据。但是现在简化为…...

docker安装elasticsearch(es)最新版本

docker安装elasticsearch&#xff08;es&#xff09; docker官网 https://hub.docker.com/ https://www.cnblogs.com/balloon72/p/13177872.html 1、拉取最新项目elasticsearch docker pull elasticsearch:8.14.3lscpu 查看架构 2、构建环境 mkdir -p /data/elasticsear…...

02 RabbitMQ:下载安装

02 RabbitMQ&#xff1a;下载&安装 1. 下载&安装1.1. 官网1.2. Docker方式1.2.1. 下载镜像1.2.2. 启动1.2.3. 登录验证 1. 下载&安装 1.1. 官网 RabbitMQ: One broker to queue them all | RabbitMQ 1.2. Docker方式 1.2.1. 下载镜像 # docker pull 镜像名称[…...

mmcv库出现No module named ‘mmcv._ext

遇到 "No module named mmcv._ext" 这个错误通常意味着你的 Python 环境中缺少 mmcv 库的扩展模块 _ext。mmcv&#xff08;MMDetection 训练工具箱的核心库&#xff09;通常依赖于 _ext 模块来提供一些高性能的操作&#xff0c;这些操作是用 C/C 实现的&#xff0c;并…...

防止xss(跨站脚本攻击)

1、输出数据时进行转义&#xff1a;这是最基本的预防措施。确保在输出数据到HTML时对特殊字符进行适当的转义&#xff0c;以防止它们被解释为HTML或JavaScript代码。PHP中可以使用htmlspecialchars()、strip_tags()、htmlentities函数来实现这一点。 echo htmlspecialchars($d…...

django小型超市库存与销售管理系统-计算机毕业设计源码46608

摘 要 随着信息技术的快速发展&#xff0c;超市库存与销售管理面临着前所未有的挑战与机遇。为了提升超市的运营效率&#xff0c;优化库存管理&#xff0c;并增强销售数据的分析能力&#xff0c;我们基于Django框架设计并开发了一套小型超市库存与销售管理系统。该系统充分利用…...

项目实战_表白墙(简易版)

你能学到什么 一个比较简单的项目&#xff1a;表白墙&#xff08;简易版&#xff09;&#xff0c;浏览器&#xff1a;谷歌升级版将在下个博客发布 效果如下 正文 说明 我们是从0开始一步一步做这个项目的&#xff0c;里面的各种问题&#xff0c;我也会以第一人称视角来解…...

优化 Spring Boot 项目启动速度:高效管理大量 Bean 注入

个人名片 🎓作者简介:java领域优质创作者 🌐个人主页:码农阿豪 📞工作室:新空间代码工作室(提供各种软件服务) 💌个人邮箱:[2435024119@qq.com] 📱个人微信:15279484656 🌐个人导航网站:www.forff.top 💡座右铭:总有人要赢。为什么不能是我呢? 专栏导…...

《LeetCode热题100》---<5.普通数组篇六道>

本篇博客讲解LeetCode热题100道普通数组篇中的六道题 第一道&#xff1a;最大子数组和&#xff08;中等&#xff09; 第二道&#xff1a;合并区间&#xff08;中等&#xff09; 第一道&#xff1a;最大子数组和&#xff08;中等&#xff09; 法一&#xff1a;贪心算法 class So…...

【Hot100】LeetCode—169. 多数元素

目录 题目1- 思路2- 实现⭐169. 多数元素——题解思路 3- ACM 实现 题目 原题连接&#xff1a;169. 多数元素 1- 思路 定义两个变量 一个是 count&#xff1a;维护当前元素的出现次数一个是 ret &#xff1a;维护当前元素 思路 遍历整个数组**①如果 count 0 **&#xff…...

专科、本科、研究生是按照什么分类的?

高等教育按照阶段主要分为以下几类 一、专业学位教育 特点&#xff1a;职业导向 专业学位教育是针对特定职业领域的专业培训&#xff0c;如医学、法律、工程等&#xff0c;旨在使学生具备从事相关职业所需的专业知识和实践技能。 实践性 专业学位教育注重实践教学和职业技…...

关于实时ODS层数仓搭建的三个问题

目录 问题一&#xff1a;数据同步的实时性无法满足 问题二&#xff1a;批量数据同步计算处理效率低 问题三&#xff1a;没有稳定的数据传输管道 FineDataLink的解决方案 实战案例-销售部门与财务部门数据同步 设置ODS层实时同步任务 设置DW层增量数据同步 设置 DM 层任务汇总 关…...

微信仿H5支付是什么

仿H5支付是指一种模拟原生H5支付流程的非官方支付方式。这种支付方式通常是由第三方支付服务提供商开发和维护的&#xff0c;目的是为了绕过官方支付渠道的限制&#xff0c;如费率、审核等问题。然而&#xff0c;由于仿H5支付并非官方授权和认可的支付方式&#xff0c;其安全性…...

网络安全知识竞赛规则及流程方案

为普及网络安全知识&#xff0c;进一步提升网络安全意识&#xff0c;树立正确的网络安全观&#xff0c;营造安全健康文明的网络环境&#xff0c;在2023年国家网络安全宣传周到来之际&#xff0c;特举办网络安全知识有奖竞赛活动&#xff0c;通过竞赛活动普及国家法律法规、政策…...

赞!蚓链用数字化打造助农扶农电商平台!

助农扶农电商平台在推动农村经济发展、促进农民增收方面发挥着重要作用。蚓链数字化平台使用“防伪溯源”为农户、商户、平台、政府与消费者打造了全方位的信任链条和纽带。给各方带来众多价值&#xff01; &#xff08;一&#xff09;农户方面 1、拓宽销售渠道&#xff0c;降…...

RocketMQ延时消息

RocketMQ消息发送基本示例(推送消费者)-CSDN博客 RocketMQ消费者主动拉取消息示例-CSDN博客 RocketMQ顺序消息-CSDN博客 RocketMQ广播消息-CSDN博客 延时消息: 延时消息实现的效果就是产者调用 producer.send 方法后&#xff0c;消息会立即发送到 Broker&#xff0c;并被存…...

【C++/STL】:哈希的应用 -- 位图布隆过滤器

目录 &#x1f680;&#x1f680;前言一&#xff0c;位图1. 位图的概念2. STL库中的位图3. 位图的设计4. 位图的模拟实现5. 位图的优缺点6. 位图相关考察题⽬ 二&#xff0c;布隆过滤器1. 布隆过滤器的概念2. 布隆过滤器的实现3. 布隆过滤器删除问题4. 布隆过滤器的优缺点 点击…...

非线性面板数据实证模型及 Stata 具体操作步骤

目录 一、引言 二、文献综述 三、理论原理 四、实证模型 五、稳健性检验 六、程序代码及解释 一、引言 在当今的经济和社会研究中&#xff0c;非线性面板数据模型的应用日益广泛。这类模型能够更好地捕捉数据中的复杂关系&#xff0c;为研究者提供更深入和准确的分析结果。…...

网站手机端做app开发工具/写软文怎么接单子

1. SSR 的应用场景 SPA 页面内容是在浏览器中&#xff08;客户&#xff09;渲染&#xff0c;搜索引擎不友好互联网&#xff08;公众&#xff0c;天猫&#xff0c;京东&#xff0c;静态化 --- SSR &#xff09;企业应用&#xff08;内网&#xff0c;没有 SEO 需求&#xff0…...

thinkphp5来做网站吗/灵感关键词生成器

如果之前提交代码的时候&#xff0c;忘记写说明了的话 我们该怎么办呢&#xff1f;&#xff1f;&#xff1f;&#xff1f; https://git-scm.com/book/zh/v1/Git-%E5%B7%A5%E5%85%B7-%E9%87%8D%E5%86%99%E5%8E%86%E5%8F%B2 参考上面这个链接 方式如下&#xff1a; 1、我们先…...

那个网站使用bs做的/搜索关键词热度

2016年4月11日作业 一、法律法规和标准规范1、中国标准划分为哪四个层次&#xff1f;要求最低的是哪个&#xff1f;国家标准、行业标准、地方标准和企业标准&#xff0c;其中要求最低的是国家标准。2、国家标准的制订程序包括哪些&#xff1f;前期准备、立项、起草、征求意见、…...

南宁网站设计多少钱/有没有推广app的平台

Package gp in the OpenCASCADE eryar163.com China 一、简介 Introduction to Package gp gp是几何处理程序包&#xff08;Geometric Processor package&#xff09;&#xff0c;简称gp。包gp提供以下功能&#xff1a; 代数计算&#xff1b;如坐标计算、矩阵计算&#xff1b;…...

上海招聘用的最多的网站/陕西seo关键词优化外包

1&#xff0c;前言 Qt在开发软件界面方面有着极大的便捷性&#xff0c;灵活的ui设计器简直是把神器&#xff0c;以前MFC或DUI要调整半天的界面&#xff0c;Qt分分钟搞定。 另一个优点&#xff0c;就是融入了类似web的css样式表的方法&#xff0c;可以自由地对界面进行美化设计…...

网站模板上传工具/seo综合查询平台官网

angular分页插件tm.pagination二次触发问题解决歪方案参考文章&#xff1a; &#xff08;1&#xff09;angular分页插件tm.pagination二次触发问题解决歪方案 &#xff08;2&#xff09;https://www.cnblogs.com/qinglangsunny/p/9307773.html 备忘一下。...