【大模型】SpringBoot整合LangChain4j实现RAG检索实战详解

目录

一、前言

二、LangChain4j 介绍

2.1 什么是LangChain4j

2.2 LangChain4j 主要特点

2.3 Langchain4j 核心组件

三、RAG介绍

3.1 什么是RAG

3.2 RAG工作流程

3.2.1 补充说明

3.3 Embedding模型

3.3.1 RAG实际使用步骤

3.3.2 什么是Embedding

3.3.3 Embedding 技术优缺点

3.3.4 Embedding 技术在大模型中的价值

四、LangChain4j整合RAG操作实战

4.1 前置准备

4.1.1 导入核心依赖

4.1.2 搭建pgVector向量数据库

4.1.3 添加配置信息

4.1.4 Document Loader介绍

4.2 基于本地内存作为向量数据库操作过程

4.2.1 添加配置信息

4.2.2 添加测试文档

4.2.3 配置InMemoryEmbeddingStore

4.2.4 增加测试接口

4.2.5 效果测试

4.3 基于pgVector作为向量数据库操作过程

4.3.1 增加配置类

4.3.2 增加pgVector配置类

4.3.3 准备几个文档

4.3.4 提供文档加载接口

4.3.5 提供一个对话接口

4.3.6 文档加载优化补充

五、写在文末


一、前言

尽管AI大模型(如GPT-4、DeepSeek等)在自然语言处理任务中表现出色,但它们仍然存在一些局限性,而RAG(Retrieval-Augmented Generation,检索增强生成)技术可以很好地弥补这些不足。举例来说,企业或个人都希望拥有一款属于自己的AI助手,能够帮自己随时解决一些特定场景或特定领域的问题,在这种场景下,AI大模型中的RAG技术就派上用场了,简单来说,它就是一款可以问你量身打造的大模型知识库,当你需要某个知识的时候为你提供更贴合实际业务场景的回答。

二、LangChain4j 介绍

2.1 什么是LangChain4j

LangChain4j作为一款专注于AI大模型集成的开源库,近年来受到了广泛关注。它旨在为开发者提供一种简单且高效的方式来接入和利用各种AI大模型,从而提升应用程序的智能化水平。LangChain4j的核心优势在于其高度的灵活性和易用性,使得开发者可以在不改变现有架构的前提下,快速实现AI功能的集成。

开发者文档地址:Introduction | LangChain4j

git地址:GitCode - 全球开发者的开源社区,开源代码托管平台

2.2 LangChain4j 主要特点

LangChain4j 主要具备如下特点:

  • 模块化设计

    • LangChain4j 采用模块化架构,允许开发者根据需要选择和使用特定功能,如模型集成、数据加载、链式调用等。

  • 多模型支持

    • 支持多种 LLM 提供商,如 OpenAI、Hugging Face 等,方便切换和集成不同模型。

  • 链式调用

    • 提供链式调用功能,允许将多个任务串联,如文本生成后自动进行情感分析。

  • 数据加载与处理

    • 内置多种数据加载器和处理器,支持从不同来源加载数据并进行预处理。

  • 扩展性好

    • 提供丰富的 API 和扩展点,开发者可以自定义组件以满足特定需求。

  • 社区活跃

    • 拥有活跃的社区和详细的文档,便于开发者获取支持和学习。

2.3 Langchain4j 核心组件

Langchain4j 的强大之处正是在于其内置了丰富的可以做到开箱即用的组件能力,相比Spring AI,Langchain4j 的组件更加丰富,在使用的时候也更灵活,下面是一张关于Langchain4j 的组件全景图。

三、RAG介绍

3.1 什么是RAG

RAG(Retrieval-Augmented Generation)的核心思想是:将传统的信息检索(IR)技术与现代的生成式大模型(如chatGPT)结合起来。

具体来说,RAG模型在生成答案之前,会首先从一个大型的文档库或知识库中检索到若干条相关的文档片段。再将这些检索到的片段作为额外的上下文信息,输入到生成模型中,从而生成更为准确和信息丰富的文本。

3.2 RAG工作流程

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

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

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

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

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

3.2.1 补充说明

第2步骤中的信息检索,不一定必须使用向量数据库,可以是关系型数据库(如MySQL,PG)、全文搜索引擎(如Elasticsearch, ES),非关系数据库(Mongodb,Redis等)

  • 大模型应用场景广泛使用向量数据库的原因是:在大模型RAG的应用场景中,主要是要查询相似度高的某几个文档,而不是精确的查找某一条(MySQL、ES擅长)。
  • 相似度高的两个文档,可能不包含相同的关键词。例如,句子1: "他很高兴。" 句子2: "他感到非常快乐。" 虽然都是描述【他】很开心快乐的心情,但是不包含相同的关键词;
  • 包含相同的关键词的两个文档可能完全没有关联,例如:句子1: "他喜欢苹果。" 句子2: "苹果是一家大公司。" 虽然都包含相同的关键词【苹果】,但两句话的相似度很低。

3.3 Embedding模型

3.3.1 RAG实际使用步骤

基于上面的描述,在实际落地RAG应用的时候,通常的思路是,大模型+本地(私有化)向量数据库,简单来说分为下面两步:

  • 搭建私有化的向量数据库,可以是PG,es等,或者使用云上的付费向量数据库;

  • 基于企业自身的文档资料,或其他业务资料,将这些原始的资料加载到私有向量数据库;

  • 应用问题或知识检索时,大模型能力驱动,参考私有的向量数据库文档资料综合回答,这样给出的答案更符合企业的实际情况;

3.3.2 什么是Embedding

在上一步中,将本地的各类文档加载到向量数据库的过程中,向量数据库完成这一步骤的关键技术中,Embedding 技术在其中承担着非常重要的角色。

Embedding 技术是一种将高维数据映射到低维空间的方法,通常用于将离散的、非连续的数据转换为连续的向量表示,以便于计算机进行处理。

3.3.3 Embedding 技术优缺点

Embedding 技术优点:

  • 语义信息捕捉
    • Embedding 技术能够捕捉数据的语义信息,使得相似的数据在嵌入空间中更接近,有助于模型更好地理解数据之间的关系。
  • 维度约减
    • Embedding 技术将高维数据映射到低维空间,减少了计算和内存需求,提高了模型的效率。
  • 上下文感知
    • 嵌入向量通常是上下文感知的,可以考虑数据点与其周围数据点的关系,这对于自然语言处理等任务非常有用。
  • 可训练
    • 嵌入向量通常是可训练的,可以与模型一起训练,从而适应特定任务和数据集。
  • 泛化能力
    • 适当训练的嵌入可以提高模型的泛化能力,从而使其能够处理新数据和未知情况。

Embedding 技术缺点:

  • 数据依赖性
    • Embedding 技术的性能高度依赖于训练数据的质量和多样性。如果训练数据不足或不具代表性,嵌入可能不准确。
  • 维度选择
    • 选择适当的嵌入维度可以是挑战性的,太低的维度可能丧失信息,太高的维度可能增加计算成本。
  • 过拟合
    • 嵌入可以过度拟合训练数据,特别是在小数据集上。这可能导致模型在未见过的数据上表现不佳。
  • 计算复杂性
    • 在训练嵌入时,可能需要大量的计算资源和时间,尤其是对于大规模数据集和高维度嵌入。
  • 可解释性差
    • 嵌入向量通常是抽象的,难以解释。这使得难以理解模型为什么做出特定的预测或推荐。

3.3.4 Embedding 技术在大模型中的价值

大模型在文本生成上的优势很明显,但是大模型的特性也带来的一定的弱势;

  • 训练数据不实时(如ChatGPT是基于2021年9月之前的数据训练),重新训练成本过高,不现实。

  • 输入文本长度有限制,通常限制在几千到数万个tokens之间。

  • 无法访问不能公开的文档。

OpenAI发布了一篇文档,说明如何基于embedding使用两步搜索的方式来解决GPT无法处理长文本和最新数据的问题,即 RAG 技术。所以说Embedding是RAG应用落地的核心技术。其在很大程度上决定了搜索相关文本的质量以及影响大模型的输出效果。

下面是一张关于LangChain4j目前支持的嵌入模型

四、LangChain4j整合RAG操作实战

下面通过实际案例完整演示下如何在SpringBoot项目中使用LangChain4j完成RAG的完整使用过程。

4.1 前置准备

4.1.1 导入核心依赖

创建一个springboot工程,并导入下面的核心依赖

<properties><maven.compiler.source>17</maven.compiler.source><maven.compiler.target>17</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><langchain.version>1.0.0-beta1</langchain.version><springboot.version>3.2.4</springboot.version>
</properties><dependencies><!-- JSON 处理 --><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId></dependency><dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-tika-document-reader</artifactId><version>1.0.0-M3</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>2.0.35</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><scope>provided</scope></dependency><!-- https://mvnrepository.com/artifact/com.alibaba/dashscope-sdk-java --><dependency><groupId>com.alibaba</groupId><artifactId>dashscope-sdk-java</artifactId><version>2.16.9</version></dependency><dependency><groupId>dev.langchain4j</groupId><artifactId>langchain4j-community-dashscope-spring-boot-starter</artifactId></dependency><dependency><groupId>dev.langchain4j</groupId><artifactId>langchain4j</artifactId><version>${langchain.version}</version></dependency><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-simple</artifactId><version>1.7.32</version> <!-- 使用最新版本 --></dependency><dependency><groupId>dev.langchain4j</groupId><artifactId>langchain4j-web-search-engine-searchapi</artifactId><version>${langchain.version}</version></dependency><dependency><groupId>dev.langchain4j</groupId><artifactId>langchain4j-pgvector</artifactId><version>${langchain.version}</version></dependency><dependency><groupId>dev.langchain4j</groupId><artifactId>langchain4j-easy-rag</artifactId><version>${langchain.version}</version></dependency></dependencies><dependencyManagement><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-dependencies</artifactId><version>${springboot.version}</version><type>pom</type><scope>import</scope></dependency><dependency><groupId>dev.langchain4j</groupId><artifactId>langchain4j-community-bom</artifactId><version>${langchain.version}</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement><repositories><repository><id>spring-milestones</id><name>Spring Milestones</name><url>https://repo.spring.io/milestone</url><snapshots><enabled>false</enabled></snapshots></repository>
</repositories><build><finalName>boot-docker</finalName><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins>
</build>

4.1.2 搭建pgVector向量数据库

向量数据库的选择有很多,比如pgVector,es,Milvus,Weaviate,Redis Stack,Chroma等,这里选择pgVector,首先使用docker命令快速部署一个pgVector服务

docker run -d --name pgvector -p 5432:5432  -v /root/pgv/data:/var/lib/postgresql/data -e POSTGRES_USER=postgres -e POSTGRES_PASSWORD=postgres pgvector/pgvector:pg17

4.1.3 添加配置信息

在工程的配置文件中,添加如下信息,在下面的配置文件中,为了后面使用向量数据库的能力,主要包括下面几块核心的配置信息:

  • langchain4j核心配置,基于langchain4j连接大模型的能力;

    • 这里选择了阿里云百炼大模型平台中的qwen-max这个大模型,apikey也是这个平台的;

    • 选择的模型,建议直接使用那些支持嵌入模型的;

  • pgvector配置;

    • 本地的文档将会加载到pgvector的向量数据库中进行存储;

server:port: 8081langchain4j:community:dashscope:chat-model:api-key: 你的阿里云百炼平台的apikeymodel-name: qwen-maxpgvector:database: springaihost: pgVector的服务器地址port : 5432user: postgrespassword: postgrestable: my_tablespring:ai:dashscope:api-key: sk-你的阿里云百炼平台的apikeyembedding:options:model: text-embedding-v2

4.1.4 Document Loader介绍

用于读取文件内容并写入到向量数据库中,在这里Langchain4j中集成了apache tika, 能够从许多种文件格式中提取文本内容。像功能比较强大的 Apache tika,入口:Introduction | LangChain4j

tika 内置以下几种读取文件的方式:

  1. FileSystemDocumentLoader : 根据文件绝对路径来读取

  2. ClassPathDocumentLoader : 根据classpath来读取

  3. UrlDocumentLoader : 根据提供的url来读取

其他一些loader示例

Document Loaders | LangChain4j

4.2 基于本地内存作为向量数据库操作过程

如果是为了快速验证效果,或者开发做测试,可以使用基于本地内存的方式进行模拟测试,在Langchain4j中提供了 InMemoryEmbeddingStore 这个对象,可用于作为内存级的向量数据库使用,参考下面的执行步骤。

4.2.1 添加配置信息

在配置文件中添加下面的配置信息

  • embedding-model 一定要配置,这里选择的是阿里云百炼大平台中的支持向量数据库的大模型;

server:port: 8081langchain4j:community:dashscope:chat-model:api-key: 阿里云百炼平台apikeymodel-name: qwen-maxembedding-model:api-key: 阿里云百炼平台apikeymodel: multimodal-embedding-v1#model-name: text-embedding-v2spring:ai:dashscope:api-key: 阿里云百炼平台apikeyembedding:options:model: multimodal-embedding-v1#model: text-embedding-v2

4.2.2 添加测试文档

在工程的resources目录下增加一个用于加载到向量数据库的txt文档,内容如下:

4.2.3 配置InMemoryEmbeddingStore

增加一个自定义配置类,将InMemoryEmbeddingStore 配置进去

@Configuration
@RequiredArgsConstructor
public class AssistantConfig {final ChatLanguageModel chatLanguageModel;@Beanpublic EmbeddingStore<TextSegment> initEmbeddingStore() {return new InMemoryEmbeddingStore<>();}@Beanpublic Assistant assistant(SearchApiWebSearchEngine engine, EmbeddingStore<TextSegment> embeddingStore){return AiServices.builder(Assistant.class).chatMemoryProvider(memoryId -> MessageWindowChatMemory.withMaxMessages(15)).contentRetriever(EmbeddingStoreContentRetriever.from(embeddingStore)).tools(new WebSearchTool(engine)).chatLanguageModel(chatLanguageModel).build();}}

4.2.4 增加测试接口

增加两个接口,加载文档到向量数据库的接口,和用于对话的接口,参考下面的代码

package com.congge.langchain4j;import com.congge.service.Assistant;
import dev.langchain4j.data.document.Document;
import dev.langchain4j.data.document.loader.FileSystemDocumentLoader;
import dev.langchain4j.data.document.splitter.DocumentByLineSplitter;
import dev.langchain4j.data.segment.TextSegment;
import dev.langchain4j.model.chat.ChatLanguageModel;
import dev.langchain4j.model.embedding.EmbeddingModel;
import dev.langchain4j.store.embedding.EmbeddingStore;
import dev.langchain4j.store.embedding.EmbeddingStoreIngestor;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;import java.util.List;@RestController
@RequestMapping("/api/rag")
@RequiredArgsConstructor
public class RagController {final ChatLanguageModel chatLanguageModel;final EmbeddingStore<TextSegment> embeddingStore;final EmbeddingModel embeddingModel;/*** 加载文件到向量数据库* localhost:8081/api/rag/load** @return*/@GetMapping("/load")public Object load() {List<Document> documents = FileSystemDocumentLoader.loadDocuments("E:\\code-self\\boot-consist\\src\\main\\resources\\file");EmbeddingStoreIngestor.ingest(documents, embeddingStore);;return "success";}final Assistant assistant;/*** 聊天对话* localhost:8081/api/rag/high/chat?message=AI去中心化与AI伦理成为焦点是什么** @return*/@GetMapping("/high/chat")public Object highChat(@RequestParam(value = "message") String message) {return assistant.chat( message);}}

4.2.5 效果测试

调用第一个接口进行文档加载

再调用第二个接口进行对话,不难看出,本次回答问题的时候明显是参考了本地加载的文档中的内容

4.3 基于pgVector作为向量数据库操作过程

下面来看如何在代码中进行整合集成,参考下面的步骤。

4.3.1 增加配置类

该配置类主要设置一些初始化的内置对象,配置到全局的bean中,提供其他地方直接调用

package com.congge.config;import com.congge.langchain4j.Calculator;
import com.congge.langchain4j.HighLevelCalculator;
import com.congge.service.Assistant;
import com.congge.util.DateCalculator;
import dev.langchain4j.data.segment.TextSegment;
import dev.langchain4j.memory.chat.MessageWindowChatMemory;
import dev.langchain4j.model.chat.ChatLanguageModel;
import dev.langchain4j.model.embedding.EmbeddingModel;
import dev.langchain4j.rag.content.retriever.EmbeddingStoreContentRetriever;
import dev.langchain4j.service.AiServices;
import dev.langchain4j.store.embedding.EmbeddingStore;
import dev.langchain4j.store.embedding.inmemory.InMemoryEmbeddingStore;
import dev.langchain4j.web.search.WebSearchTool;
import dev.langchain4j.web.search.searchapi.SearchApiWebSearchEngine;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
@RequiredArgsConstructor
public class AssistantConfig {final ChatLanguageModel chatLanguageModel;@Beanpublic Assistant assistant(SearchApiWebSearchEngine engine, EmbeddingStore<TextSegment> embeddingStore){return AiServices.builder(Assistant.class).chatMemoryProvider(memoryId -> MessageWindowChatMemory.withMaxMessages(15)).contentRetriever(EmbeddingStoreContentRetriever.from(embeddingStore)).tools(new WebSearchTool(engine)).chatLanguageModel(chatLanguageModel).build();}}

4.3.2 增加pgVector配置类

由于本次使用的是pgVector作为向量数据库,因此需要覆盖默认的向量数据库,如下:

1)读取配置文件中的pg配置类

@Configuration
@ConfigurationProperties(prefix = "pgvector")
@Data
public class PgConfig {private String host;private int port;private String database;private String user;private String password;private String table;}

2)自定义EmbeddingStore覆盖默认

import dev.langchain4j.data.segment.TextSegment;
import dev.langchain4j.store.embedding.EmbeddingStore;
import dev.langchain4j.store.embedding.pgvector.PgVectorEmbeddingStore;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
@RequiredArgsConstructor
public class EmbeddingStoreInit {final PgConfig pgConfig;@Beanpublic EmbeddingStore<TextSegment> initEmbeddingStore() {return PgVectorEmbeddingStore.builder().table(pgConfig.getTable()).dropTableFirst(true).createTable(true).host(pgConfig.getHost()).port(pgConfig.getPort()).user(pgConfig.getUser()).password(pgConfig.getPassword()).dimension(384).database(pgConfig.getDatabase()).build();}
}

4.3.3 准备几个文档

在本地随机提供几个文档,可以是txt,或者md、PDF等文件

4.3.4 提供文档加载接口

提供第一个接口,用于加载本地文档到向量数据库

final EmbeddingStore<TextSegment> embeddingStore;/*** 加载文件到向量数据库* localhost:8081/api/rag/load** @return*/
@GetMapping("/load")
public Object load() {List<Document> documents = FileSystemDocumentLoader.loadDocuments("E:\\code-self\\boot-consist\\src\\main\\resources\\file");EmbeddingStoreIngestor.ingest(documents, embeddingStore);;return "success";
}

接口执行成功后,连接pg数据库之后,可以看到本地的文档数据成功被加载到表中进行存储了

4.3.5 提供一个对话接口

像上文那样再提供一个对话接口,用于后面测试检索

final Assistant assistant;/*** 聊天对话* localhost:8081/api/rag/high/chat?message=勒布朗·詹姆斯获得过哪些荣誉** @return*/
@GetMapping("/high/chat")
public Object highChat(@RequestParam(value = "message") String message) {return assistant.chat( message);
}

基于上一步文档加载接口之后,调用一下对话接口

4.3.6 文档加载优化补充

在上面的加载文档接口中,我们使用了 EmbeddingStoreIngestor.ingest(documents, embeddingStore) 这个方法,对读取的文档进行向量数据库的加载,即没有对内部的参数进行特殊的配置,其实来说,在实际使用过程中,为了更合理的对拆分后存储到向量数据库中的文本长度进行控制,以兼顾存储容量和检索的效果,需要适当的做一些参数设置。

此处主要是用于对需要写入向量数据库的文本进行一定策略上的切分,可以让rag的检索效果更好,如果需要自定义Spliter策略的话可以实现DocumentSplitter接口

以下 是langchain4j内置提供的一些切分策略:

  1. DocumentByCharacterSplitter 基于指定的字符进行切分

  2. DocumentByLineSplitter 基于行切分

  3. DocumentByParagraphSplitter 基于段落切分,默认的切分方式

  4. DocumentByRegexSplitter 基于正则进行切分

  5. DocumentBySentenceSplitter 基于语义进行切分,需要依赖语义切分的模型

  6. DocumentByWordSplitter 基于单词进行切分

常用的拆分参数:

  • maxSegmentSizeInChars : 每个文本段最大的长度

  • maxOverlapSizeInChars :两个段之间重叠的数量

在上面的参数设置中,需要结合特定的向量数据库类型进行适配,如下这个参数:

下面是一个具体的自定义的文档切分参数后的测试接口

    final ChatLanguageModel chatLanguageModel;final EmbeddingStore<TextSegment> embeddingStore;final EmbeddingModel embeddingModel;/*** 加载文件到向量数据库* localhost:8081/api/rag/load** @return*/@GetMapping("/load")public Object load() {List<Document> documents = FileSystemDocumentLoader.loadDocuments("E:\\code-self\\boot-consist\\src\\main\\resources\\file");EmbeddingStoreIngestor.builder().embeddingStore(embeddingStore).embeddingModel(embeddingModel).documentSplitter(new DocumentByLineSplitter(30,20)).build().ingest(documents);;return "success";}

重新调用一下文档加载接口,调用成功后,不难发现,这一次设置并进行文档拆分存储之后,文档的片段长度更小了;

五、写在文末

本文通过较大的篇幅详细介绍了基于Langchain4j结合目前主流的AI大模型实现RAG的完整过程,并通过实际案例进行了演示,希望对看到的同学有用,本篇到此结束,感谢观看。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/76167.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于 Trae 的超轻量级前端架构设计与性能优化实践

一、技术背景与选型动因 在单页应用(SPA)复杂度指数级增长的今天&#xff0c;传统框架在千级列表渲染场景下普遍存在首屏延迟(>1.5s)、内存占用过高(>200MB)等问题。基于对 Webpack Bundle Analyzer 的长期观察&#xff0c;我们发现核心问题集中在&#xff1a; • 类组件…

dotnet core web api linux主机公网发布

效果: 发布流程: 创建一个ASP.NET Core Web API 工程 输入工程名 选择框架版本为.net 9.0及选择配置HTTPS和启用OPENAPI 启动调试 确认证书

WPS宏开发手册——JSA语法练习

目录 系列文章3、JSA语法练习3.1、运算练习3.2、比较练习3.3、if else练习3.4、for 练习3.5、字符串、数组方法练习3.6、语义转编程练习题 系列文章 使用、工程、模块介绍 JSA语法 JSA语法练习题 Excel常用Api 后续EXCEL实战、常见问题、颜色附录&#xff0c;持…

计算机网络面经(一)

以下为个人总结&#xff0c;图源大部分会来自网络和JavaGuide 网络分层模型 OSI七层模型 各层的常见协议 应用层 用户接口 HTTP, FTP, SMTP, DNS表示层 数据格式转换 SSL/TLS, JSON, JPEG会话层 会话管理 NetBIOS, RPC, SSH传输层 端到端通信 TCP, UDP, QUIC网络层 路由寻址…

《JVM考古现场(十四):混沌重启——从量子永生到宇宙热寂的终极编译》

开篇&#xff1a;熵火燎原量子递归的终极突围 "当《诛仙剑阵》的时空冻结算法遭遇量子递归暴走&#xff0c;当Project Omega的热寂代码在JVM的十三维堆内存中坍缩&#xff0c;此刻我们即将撕开归墟晶壁&#xff0c;直面从玻尔兹曼大脑到冯诺依曼架构的终极对决&#xff0…

【django】2-2 (django配置) 数据库配置、缓存配置

文章目录 5 数据库配置5.1 常用配置项5.2 数据库配置示例5.3 其它数据库配置选项 6 缓存6.1 常用配置项6.2 内置的缓存后端6.3 缓存配置示例6.4 缓存中间件的配置 创建django项目后&#xff0c;会自动生成初始的项目文件如下&#xff1a; manage.py # 管理django项目…

【博客】使用GithubAction自动同步obisidian和hexo仓库

使用Github Action自动同步obisidian和hexo仓库&#xff0c;避免手动操作。 本文首发于❄慕雪的寒舍 1. 烦恼 先来说说慕雪现在的笔记和博客是怎么管理的吧&#xff0c;我正在使用两套笔记软件 思源笔记&#xff1a;私密性高一些&#xff0c;不是博客的笔记都在这里面。由于思…

scala简介和基础语法

Scala简介 Scala 是一门多范式&#xff08;multi-paradigm&#xff09;的编程语言&#xff0c;设计初衷是要集成面向对象编程和函数式编程的各种特性。 Scala 运行在 Java 虚拟机上&#xff0c;并兼容现有的 Java 程序。Scala 源代码被编译成 Java 字节码&#xff0c;所以它可…

7.4考研408数据结构B树与B+树专题深度解析

考研408数据结构B树与B+树专题深度解析 一、B树(B-Tree) 1.1 定义与性质 定义: B树是一种平衡多路查找树,满足以下条件: 阶数:每个结点最多有 m m m个子树( m ≥

WEB安全--RCE--RCE的危险函数

一、命令执行 1.1、命令执行原理 <?php $cmd $_GET[cmd]; // 直接获取用户输入 system($cmd); // 不安全 ?>#payload: http://example.com/vuln.php?cmdwhoami#结果: www-data 1.2、危险函数 1.2.1、system() 介绍&#xff1a; 执行外部命令&#xff0c;将命令…

Linux C++ 利用 io_uring 技术批量读取 tun 文件描述符的数据。

以下是参考的实现代码&#xff0c;IO_URING 操作必须要进行按页大小对齐&#xff08;仅在O_DIRECT直接I/O下&#xff09;&#xff0c;不能是非对称的&#xff0c;一般大多数操作系统页大小为&#xff1a;4KB。 批量读取、writev 批量简写。 static constexpr int MTU ITap::M…

时序数据库:InfluxDB命令行操作

学习 InfluxDB 的命令行操作至关重要&#xff0c;它不仅是与数据库直接交互的工具&#xff0c;也是理解 InfluxDB 核心概念的关键途径。通过命令行&#xff0c;用户可以高效地执行数据库管理、数据查询和插入等任务&#xff0c;深入掌握 InfluxQL 的语法及功能。这对于调试、快…

Bootstrap 表格:高效布局与动态交互的实践指南

Bootstrap 表格:高效布局与动态交互的实践指南 引言 Bootstrap 是一个流行的前端框架,它为开发者提供了丰富的组件和工具,使得构建响应式、美观且功能丰富的网页变得更加简单。表格是网页中常见的元素,用于展示数据。Bootstrap 提供了强大的表格组件,可以帮助开发者轻松…

⑥ ACG-系统管理

上网管理行为是指对员工在工作时间内使用公司网络的行为进行管理和监督。在企业中&#xff0c;系统管理是实施上网管理行为的重要方式之一。系统管理包括以下几个方面&#xff1a; 1. 访问控制&#xff1a;通过设置网络访问权限&#xff0c;对员工访问特定网站或使用特定应用程…

【Docker】Dockerfile 优化工具 hadolint

本文内容均来自个人笔记并重新梳理&#xff0c;如有错误欢迎指正&#xff01; 如果对您有帮助&#xff0c;烦请点赞、关注、转发、订阅专栏&#xff01; 专栏订阅入口 | 精选文章 | Kubernetes | Docker | Linux | 羊毛资源 | 工具推荐 | 往期精彩文章 【Docker】&#xff08;全…

接口自动化——初识pytest

缩写单词含义.passed通过Ffailed失败&#xff08;用例执行时报错&#xff09;Eerror出错&#xff08;fixture执行报错&#xff09;sskipped跳过Xxpassed预期外的通过&#xff08;不符合预期&#xff09;xxfailed预期内的失败&#xff08;符合预期&#xff09; 1.pytest 配置 1…

leetcode日记(100)填充每个节点的下一个右侧节点指针

和层序遍历差不多的思路&#xff0c;将节点储存在队列里&#xff0c;一边取出节点一边放入取出节点的左右节点&#xff0c;直到队列空。 /* // Definition for a Node. class Node { public:int val;Node* left;Node* right;Node* next;Node() : val(0), left(NULL), right(NU…

MySQL配置文件my.cnf详解

目前使用的服务器系统是CentOS8.5 ,针对MySql8.4的配置示例&#xff0c;自己根据实际情况修改。 安装MySql8.4时&#xff0c;MySql8.4没有默认的my.cnf,需要用户根据需要自行配置my.cnf文件&#xff0c;大概可看到下面这样的参数列表&#xff0c;可能不同版本的mysql参数多少会…

【解决】XCode不支持旧版本的iOS设备

办法&#xff1a; 手动添加设备支持文件&#xff08;暂时解决方式&#xff09; 如果您无法立即升级 Xcode&#xff0c;也可以通过下载设备支持文件来暂时解决问题。 检查当前设备的 iOS 版本&#xff1a; 连接设备到 Mac&#xff0c;打开 Xcode 查看提示的 iOS 版本。例如&…

每日c/c++题 备战蓝桥杯(全排列问题)

题目描述 按照字典序输出自然数 1 到 n 所有不重复的排列&#xff0c;即 n 的全排列&#xff0c;要求所产生的任一数字序列中不允许出现重复的数字。 输入格式 一个整数 n。 输出格式 由 1∼n 组成的所有不重复的数字序列&#xff0c;每行一个序列。 每个数字保留 5 个场…