跟着DW学习大语言模型-什么是知识库,如何构建知识库

  • 建立一个高效的知识库对于个人和组织来说非常重要。无论是为了个人学习和成长,还是为了组织的持续创新和发展,一个完善的知识管理系统都是不可或缺的。那么,如何建立一个高效的知识库呢?

    • 在建立知识库之前,首先需要确定清晰的目标。你想要将知识库用于什么目的?是为了提高团队的协作效率?还是为了更好地管理和传承组织内部的专业知识?或者是为了提供给客户和用户一个统一的知识查询平台?只有明确了目标,才能有针对性地选择和设计知识库系统。
    • 根据你的目标和需求,选择一个适合的知识库工具非常重要。市面上有许多知识库管理工具,例如Confluence、SharePoint、Notion等,它们都有各自的特点和功能。你可以根据自己的需求进行比较和选择,确保选择一个易用且符合你要求的工具。
    • 建立知识库的核心是收集和整理知识。你可以从多个渠道搜集知识,例如内部文档、培训资料、项目总结等。同时,你也可以鼓励团队成员贡献自己的知识和经验。在整理知识时,可以根据不同的主题和类别进行分类,采用标签、目录等方式进行组织,使得知识库结构清晰、易于查找。
    • 在建立知识库时,设计一个合理的知识库结构非常重要。你可以根据知识的类型、领域、层级等因素进行分类和组织。同时,你也可以根据不同的用户需求,设计不同的访问权限和查看方式,以便用户能够根据自己的需求获取到所需的知识。
    • 知识库的内容和知识是不断变化和更新的。为了保持知识库的有效性和及时性,你需要定期更新和维护知识库。你可以设立专门的知识库管理人员,负责对知识库的内容进行审核和更新。同时,你也可以鼓励团队成员积极参与到知识库的维护中来,使得知识库能够不断地完善和发展。
  • 同样是存储和记录,也许有些人会问,现在搜索引擎这么发达,想要的知道的东西搜一下就有,为什么还要建一个自己的知识库呢?因为在搜索引擎中搜索到的,只是信息,而不是知识。知识是阅读信息后,经过思考和理解的产物。搜索引擎里搜索到的信息,你依旧需要进行阅读处理,而不能直接使用。下图描述了从信息到知识的变化过程,信息是零散的点,而知识是经过处理后的产物。

    • 在这里插入图片描述

    • 在知识库里,过往积累的知识将变得容易追溯,每次读到自己过去的思考,都如同和自己过去的思想对话,思考后,或许又有新的发现。有时会发现自己的进步,修正过去的思想;有时又会惊讶于过去的思考,即便现在也让自己有启发,这种草稿拾遗的感觉很奇妙如何搭建知识库 - 少数派 (sspai.com)。

  • 在RAG(Retrieval Augmented Generation,检索增强生成)方面词向量的优势主要有两点:

    • 词向量比文字更适合检索。当我们在数据库检索时,如果数据库存储的是文字,主要通过检索关键词(词法搜索)等方法找到相对匹配的数据,匹配的程度是取决于关键词的数量或者是否完全匹配查询句的;但是词向量中包含了原文本的语义信息,可以通过计算问题与数据库中数据的点积、余弦距离、欧几里得距离等指标,直接获取问题与数据在语义层面上的相似度
    • 词向量比其它媒介的综合信息能力更强,当传统数据库存储文字、声音、图像、视频等多种媒介时,很难去将上述多种媒介构建起关联与跨模态的查询方法;但是词向量却可以通过多种向量模型将多种数据映射成统一的向量形式。
  • 在搭建 RAG 系统时,我们往往可以通过使用嵌入模型来构建词向量,我们可以选择:使用各个公司的 Embedding API;在本地使用嵌入模型将数据构建为词向量。

  • 词向量(Embeddings)是一种将非结构化数据,如单词、句子或者整个文档,转化为实数向量的技术。这些实数向量可以被计算机更好地理解和处理。在机器学习和自然语言处理(NLP)中,词向量嵌入背后的主要想法是,相似或相关的对象在嵌入空间中的距离应该很近。

  • 我们可以使用词嵌入(word embeddings)来表示文本数据。在词嵌入中,每个单词被转换为一个向量,这个向量捕获了这个单词的语义信息。例如,“king” 和 “queen” 这两个单词在嵌入空间中的位置将会非常接近,因为它们的含义相似。而 “apple” 和 “orange” 也会很接近,因为它们都是水果。而 “king” 和 “apple” 这两个单词在嵌入空间中的距离就会比较远,因为它们的含义不同。

  • 向量数据库是用于高效计算和管理大量向量数据的解决方案。向量数据库是一种专门用于存储和检索向量数据(embedding)的数据库系统。它与传统的基于关系模型的数据库不同,它主要关注的是向量数据的特性和相似性。在向量数据库中,数据被表示为向量形式,每个向量代表一个数据项。这些向量可以是数字、文本、图像或其他类型的数据。向量数据库使用高效的索引和查询算法来加速向量数据的存储和检索过程。

  • 向量数据库中的数据以向量作为基本单位,对向量进行存储、处理及检索。向量数据库通过计算与目标向量的余弦距离、点积等获取与目标向量的相似度。当处理大量甚至海量的向量数据时,向量数据库索引和查询算法的效率明显高于传统数据库

  • Chroma:是一个轻量级向量数据库,拥有丰富的功能和简单的 API,具有简单、易用、轻量的优点,但功能相对简单且不支持GPU加速,适合初学者使用。

  • Weaviate:是一个开源向量数据库。除了支持相似度搜索和最大边际相关性(MMR,Maximal Marginal Relevance)搜索外还可以支持结合多种搜索算法(基于词法搜索、向量搜索)的混合搜索,从而搜索提高结果的相关性和准确性。

  • Qdrant:Qdrant使用 Rust 语言开发,有极高的检索效率和RPS(Requests Per Second),支持本地运行、部署在本地服务器及Qdrant云三种部署模式。且可以通过为页面内容和元数据制定不同的键来复用数据。

  • 使用OpenAI API,本文对应源代码在[此处](https://github.com/datawhalechina/llm-universe/blob/main/notebook/C3 搭建知识库/2.使用 Embedding API.ipynb),如需复现可下载运行源代码。

    • import os
      from openai import OpenAI
      from dotenv import load_dotenv, find_dotenv
      # 读取本地/项目的环境变量。
      # find_dotenv()寻找并定位.env文件的路径
      # load_dotenv()读取该.env文件,并将其中的环境变量加载到当前的运行环境中 
      # 如果你设置的是全局的环境变量,这行代码则没有任何作用。
      _ = load_dotenv(find_dotenv())
      # 如果你需要通过代理端口访问,你需要如下配置
      os.environ['HTTPS_PROXY'] = 'http://127.0.0.1:7890'
      os.environ["HTTP_PROXY"] = 'http://127.0.0.1:7890'
      def openai_embedding(text: str, model: str=None):# 获取环境变量 OPENAI_API_KEYapi_key=os.environ['OPENAI_API_KEY']client = OpenAI(api_key=api_key)# embedding model:'text-embedding-3-small', 'text-embedding-3-large', 'text-embedding-ada-002'if model == None:model="text-embedding-3-small"response = client.embeddings.create(input=text,model=model)return response
      response = openai_embedding(text='要生成 embedding 的输入文本,字符串形式。')
      
    • API返回的数据为json格式,除object向量类型外还有存放数据的data、embedding model 型号model以及本次 token 使用情况usage等数据,具体如下所示:

    • {"object": "list","data": [{"object": "embedding","index": 0,"embedding": [-0.006929283495992422,... (省略)-4.547132266452536e-05,],}],"model": "text-embedding-3-small","usage": {"prompt_tokens": 5,"total_tokens": 5}
      }
      
    • 我们可以调用response的object来获取embedding的类型。

    • print(f'返回的embedding类型为:{response.object}')
      # 返回的embedding类型为:list
      print(f'embedding长度为:{len(response.data[0].embedding)}')
      print(f'embedding(前10)为:{response.data[0].embedding[:10]}')
      print(f'本次embedding model为:{response.model}')
      print(f'本次token使用情况为:{response.usage}')
      
  • 数据处理:为构建我们的本地知识库,我们需要对以多种类型存储的本地文档进行处理,读取本地文档并通过前文描述的 Embedding 方法将本地文档的内容转化为词向量来构建向量数据库。在本节中,我们以一些实际示例入手,来讲解如何对本地文档进行处理。

    • 我们选用 Datawhale 一些经典开源课程作为示例,具体包括:《机器学习公式详解》PDF版本;《面向开发者的LLM入门教程、第一部分Prompt Engineering》md版本。我们将知识库源数据放置在…/data_base/knowledge_db 目录下。

    • 可以使用 LangChain 的 PyMuPDFLoader 来读取知识库的 PDF 文件。PyMuPDFLoader 是 PDF 解析器中速度最快的一种,结果会包含 PDF 及其页面的详细元数据,并且每页返回一个文档。

    • from langchain.document_loaders.pdf import PyMuPDFLoader
      # 创建一个 PyMuPDFLoader Class 实例,输入为待加载的 pdf 文档路径
      loader = PyMuPDFLoader("../../data_base/knowledge_db/pumkin_book/pumpkin_book.pdf")
      # 调用 PyMuPDFLoader Class 的函数 load 对 pdf 文件进行加载
      pdf_pages = loader.load()
      
    • 文档加载后储存在 pages 变量中: page 的变量类型为 List;打印 pages 的长度可以看到 pdf 一共包含多少页

    • print(f"载入后的变量类型为:{type(pdf_pages)},",  f"该 PDF 一共包含 {len(pdf_pages)} 页")
      
    • page 中的每一元素为一个文档,变量类型为 langchain_core.documents.base.Document, 文档变量类型包含两个属性;page_content 包含该文档的内容。meta_data 为文档相关的描述性数据。

    • pdf_page = pdf_pages[1]
      print(f"每一个元素的类型:{type(pdf_page)}.", f"该文档的描述性数据:{pdf_page.metadata}", f"查看该文档的内容:\n{pdf_page.page_content}", sep="\n------\n")
      
    • 可以以几乎完全一致的方式读入 markdown 文档:

    • from langchain.document_loaders.markdown import UnstructuredMarkdownLoader
      loader = UnstructuredMarkdownLoader("../../data_base/knowledge_db/prompt_engineering/1. 简介 Introduction.md")
      md_pages = loader.load()
      
  • 数据清洗:期望知识库的数据尽量是有序的、优质的、精简的,因此我们要删除低质量的、甚至影响理解的文本数据。可以看到上文中读取的pdf文件不仅将一句话按照原文的分行添加了换行符\n,也在原本两个符号中间插入了\n,我们可以使用正则表达式匹配并删除掉\n

    • import re
      pattern = re.compile(r'[^\u4e00-\u9fff](\n)[^\u4e00-\u9fff]', re.DOTALL)
      pdf_page.page_content = re.sub(pattern, lambda match: match.group(0).replace('\n', ''), pdf_page.page_content)
      print(pdf_page.page_content)
      
    • 进一步分析数据,我们发现数据中还有不少的和空格,我们的简单实用replace方法即可。

    • pdf_page.page_content = pdf_page.page_content.replace('•', '')
      pdf_page.page_content = pdf_page.page_content.replace(' ', '')
      print(pdf_page.page_content)
      md_page.page_content = md_page.page_content.replace('\n\n', '\n')
      print(md_page.page_content)
      
  • 文档分割:由于单个文档的长度往往会超过模型支持的上下文,导致检索得到的知识太长超出模型的处理能力,因此,在构建向量知识库的过程中,我们往往需要对文档进行分割,将单个文档按长度或者按固定的规则分割成若干个 chunk,然后将每个 chunk 转化为词向量,存储到向量数据库中。在检索时,我们会以 chunk 作为检索的元单位,也就是每一次检索到 k 个 chunk 作为模型可以参考来回答用户问题的知识,这个 k 是我们可以自由设定的。Langchain 中文本分割器都根据 chunk_size (块大小)和 chunk_overlap (块与块之间的重叠大小)进行分割

    • chunk_size 指每个块包含的字符或 Token (如单词、句子等)的数量
    • chunk_overlap 指两个块之间共享的字符数量,用于保持上下文的连贯性,避免分割丢失上下文信息
  • Langchain 提供多种文档分割方式,区别在怎么确定块与块之间的边界、块由哪些字符/token组成、以及如何测量块大小

    • RecursiveCharacterTextSplitter(): 按字符串分割文本,递归地尝试按不同的分隔符进行分割文本。

    • CharacterTextSplitter(): 按字符来分割文本。

    • MarkdownHeaderTextSplitter(): 基于指定的标题来分割markdown 文件。

    • TokenTextSplitter(): 按token来分割文本。

    • SentenceTransformersTokenTextSplitter(): 按token来分割文本

    • Language(): 用于 CPP、Python、Ruby、Markdown 等。

    • NLTKTextSplitter(): 使用 NLTK(自然语言工具包)按句子分割文本。

    • SpacyTextSplitter(): 使用 Spacy按句子的切割文本。

    • ''' 
      * RecursiveCharacterTextSplitter 递归字符文本分割
      RecursiveCharacterTextSplitter 将按不同的字符递归地分割(按照这个优先级["\n\n", "\n", " ", ""]),这样就能尽量把所有和语义相关的内容尽可能长时间地保留在同一位置
      RecursiveCharacterTextSplitter需要关注的是4个参数:
      * separators - 分隔符字符串数组
      * chunk_size - 每个文档的字符数量限制
      * chunk_overlap - 两份文档重叠区域的长度
      * length_function - 长度计算函数
      '''
      #导入文本分割器
      from langchain.text_splitter import RecursiveCharacterTextSplitter
      # 知识库中单段文本长度
      CHUNK_SIZE = 500
      # 知识库中相邻文本重合长度
      OVERLAP_SIZE = 50
      # 使用递归字符文本分割器
      text_splitter = RecursiveCharacterTextSplitter(chunk_size=CHUNK_SIZE,chunk_overlap=OVERLAP_SIZE
      )
      text_splitter.split_text(pdf_page.page_content[0:1000])
      split_docs = text_splitter.split_documents(pdf_pages)
      print(f"切分后的文件数量:{len(split_docs)}")
      print(f"切分后的字符数(可以用来大致评估 token 数):{sum([len(doc.page_content) for doc in split_docs])}")
    • 注:如何对文档进行分割,其实是数据处理中最核心的一步,其往往决定了检索系统的下限。但是,如何选择分割方式,往往具有很强的业务相关性——针对不同的业务、不同的源数据,往往需要设定个性化的文档分割方式。因此,在本章,我们仅简单根据 chunk_size 对文档进行分割。

  • 数据准备好了之后,就可以搭建并使用向量数据库

    • import os
      from dotenv import load_dotenv, find_dotenv
      # 读取本地/项目的环境变量。
      # find_dotenv()寻找并定位.env文件的路径
      # load_dotenv()读取该.env文件,并将其中的环境变量加载到当前的运行环境中 
      # 如果你设置的是全局的环境变量,这行代码则没有任何作用。
      _ = load_dotenv(find_dotenv())
      # 如果你需要通过代理端口访问,你需要如下配置
      # os.environ['HTTPS_PROXY'] = 'http://127.0.0.1:7890'
      # os.environ["HTTP_PROXY"] = 'http://127.0.0.1:7890'
      # 获取folder_path下所有文件路径,储存在file_paths里
      file_paths = []
      folder_path = '../../data_base/knowledge_db'
      for root, dirs, files in os.walk(folder_path):for file in files:file_path = os.path.join(root, file)file_paths.append(file_path)
      print(file_paths[:3])from langchain.document_loaders.pdf import PyMuPDFLoader
      from langchain.document_loaders.markdown import UnstructuredMarkdownLoader
      # 遍历文件路径并把实例化的loader存放在loaders里
      loaders = []
      for file_path in file_paths:file_type = file_path.split('.')[-1]if file_type == 'pdf':loaders.append(PyMuPDFLoader(file_path))elif file_type == 'md':loaders.append(UnstructuredMarkdownLoader(file_path))
      # 下载文件并存储到text
      texts = []
      for loader in loaders: texts.extend(loader.load())
      
    • 载入后的变量类型为langchain_core.documents.base.Document, 文档变量类型同样包含两个属性:page_content 包含该文档的内容。meta_data 为文档相关的描述性数据。

    • text = texts[1]
      print(f"每一个元素的类型:{type(text)}.", f"该文档的描述性数据:{text.metadata}", f"查看该文档的内容:\n{text.page_content[0:]}", sep="\n------\n")from langchain.text_splitter import RecursiveCharacterTextSplitter
      # 切分文档
      text_splitter = RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=50)
      split_docs = text_splitter.split_documents(texts)
      
  • 构建Chroma向量库:Langchain 集成了超过 30 个不同的向量存储库。我们选择 Chroma 是因为它轻量级且数据存储在内存中,这使得它非常容易启动和开始使用。LangChain 可以直接使用 OpenAI 和百度千帆的 Embedding,同时,我们也可以针对其不支持的 Embedding API 进行自定义,例如,我们可以基于 LangChain 提供的接口,封装一个 zhipuai_embedding,来将智谱的 Embedding API 接入到 LangChain 中。

    • # 使用 OpenAI Embedding
      # from langchain.embeddings.openai import OpenAIEmbeddings
      # 使用百度千帆 Embedding
      # from langchain.embeddings.baidu_qianfan_endpoint import QianfanEmbeddingsEndpoint
      # 使用我们自己封装的智谱 Embedding,需要将封装代码下载到本地使用
      from zhipuai_embedding import ZhipuAIEmbeddings
      # 定义 Embeddings
      # embedding = OpenAIEmbeddings() 
      embedding = ZhipuAIEmbeddings()
      # embedding = QianfanEmbeddingsEndpoint()
      # 定义持久化路径
      persist_directory = '../../data_base/vector_db/chroma'
      # !rm -rf '../../data_base/vector_db/chroma'  # 删除旧的数据库文件(如果文件夹中有文件的话),windows电脑请手动删除
      from langchain.vectorstores.chroma import Chroma
      vectordb = Chroma.from_documents(documents=split_docs[:20], # 为了速度,只选择前 20 个切分的 doc 进行生成;使用千帆时因QPS限制,建议选择前 5 个docembedding=embedding,persist_directory=persist_directory  # 允许我们将persist_directory目录保存到磁盘上
      )
    • 在此之后,我们要确保通过运行 vectordb.persist 来持久化向量数据库,以便以后使用!

    • vectordb.persist()
      print(f"向量库中存储的数量:{vectordb._collection.count()}")
      
  • 向量检索

    • 当你需要数据库返回严谨的按余弦相似度排序的结果时可以使用similarity_search函数。

    • question="什么是大语言模型"
      sim_docs = vectordb.similarity_search(question,k=3)
      print(f"检索到的内容数:{len(sim_docs)}")
      for i, sim_doc in enumerate(sim_docs):print(f"检索到的第{i}个内容: \n{sim_doc.page_content[:200]}", end="\n--------------\n")
      
    • 如果只考虑检索出内容的相关性会导致内容过于单一,可能丢失重要信息。最大边际相关性 (MMR, Maximum marginal relevance) 可以帮助我们在保持相关性的同时,增加内容的丰富度。核心思想是在已经选择了一个相关性高的文档之后,再选择一个与已选文档相关性较低但是信息丰富的文档。这样可以在保持相关性的同时,增加内容的多样性,避免过于单一的结果。

    • mmr_docs = vectordb.max_marginal_relevance_search(question,k=3)
      for i, sim_doc in enumerate(mmr_docs):print(f"MMR 检索到的第{i}个内容: \n{sim_doc.page_content[:200]}", end="\n--------------\n")
      
  • LangChain 为基于 LLM 开发自定义应用提供了高效的开发框架,便于开发者迅速地激发 LLM 的强大能力,搭建 LLM 应用。LangChain 也同样支持多种大模型的 Embeddings,内置了 OpenAI、LLAMA 等大模型 Embeddings 的调用接口。但是,LangChain 并没有内置所有大模型,它通过允许用户自定义 Embeddings 类型,来提供强大的可扩展性。

  • 以智谱 AI 为例[llm-universe/notebook/C3 搭建知识库/附LangChain自定义Embedding封装讲解.ipynb at main · datawhalechina/llm-universe (github.com)](https://github.com/datawhalechina/llm-universe/blob/main/notebook/C3 搭建知识库/附LangChain自定义Embedding封装讲解.ipynb),讲述如何基于 LangChain 自定义 Embeddings。要实现自定义 Embeddings,需要定义一个自定义类继承自 LangChain 的 Embeddings 基类,然后定义两个函数:① embed_query 方法,用于对单个字符串(query)进行 embedding;②embed_documents 方法,用于对字符串列表(documents)进行 embedding。

    • 首先我们导入所需的第三方库:

    • from __future__ import annotations
      import logging
      from typing import Dict, List, Any
      from langchain.embeddings.base import Embeddings
      from langchain.pydantic_v1 import BaseModel, root_validator
      logger = logging.getLogger(__name__)
      # 定义一个继承自 Embeddings 类的自定义 Embeddings 类:
      class ZhipuAIEmbeddings(BaseModel, Embeddings):"""`Zhipuai Embeddings` embedding models."""client: Any"""`zhipuai.ZhipuAI"""
      
    • 在 Python 中,root_validator 是 Pydantic 模块中一个用于自定义数据校验的装饰器函数。root_validator 用于在校验整个数据模型之前对整个数据模型进行自定义校验,以确保所有的数据都符合所期望的数据结构。

    • root_validator 接收一个函数作为参数,该函数包含需要校验的逻辑。函数应该返回一个字典,其中包含经过校验的数据。如果校验失败,则抛出一个 ValueError 异常。这里我们只需将.env文件中ZHIPUAI_API_KEY配置好即可,zhipuai.ZhipuAI会自动获取ZHIPUAI_API_KEY

    • @root_validator()
      def validate_environment(cls, values: Dict) -> Dict:"""实例化ZhipuAI为values["client"]Args:values (Dict): 包含配置信息的字典,必须包含 client 的字段.Returns:values (Dict): 包含配置信息的字典。如果环境中有zhipuai库,则将返回实例化的ZhipuAI类;否则将报错 'ModuleNotFoundError: No module named 'zhipuai''."""from zhipuai import ZhipuAIvalues["client"] = ZhipuAI()return values
      
    • embed_query 是对单个文本(str)计算 embedding 的方法,这里我们重写该方法,调用验证环境时实例化的ZhipuAI来 调用远程 API 并返回 embedding 结果。

    • def embed_query(self, text: str) -> List[float]:"""生成输入文本的 embedding.Args:texts (str): 要生成 embedding 的文本.Return:embeddings (List[float]): 输入文本的 embedding,一个浮点数值列表."""embeddings = self.client.embeddings.create(model="embedding-2",input=text)return embeddings.data[0].embedding
      
    • embed_documents 是对字符串列表(List[str])计算embedding 的方法,对于这种类型输入我们采取循环方式挨个计算列表内子字符串的 embedding 并返回。

    • def embed_documents(self, texts: List[str]) -> List[List[float]]:"""生成输入文本列表的 embedding.Args:texts (List[str]): 要生成 embedding 的文本列表.Returns:List[List[float]]: 输入列表中每个文档的 embedding 列表。每个 embedding 都表示为一个浮点值列表。"""return [self.embed_query(text) for text in texts]
      
  • 基于大语言模型知识问答应用落地实践 – 知识库构建(上) | 亚马逊AWS官方博客 (amazon.com)

  • 从碎片到系统:设计师必备的知识库搭建指南 - 少数派 (sspai.com)

  • 一文教你基于LangChain和ChatGLM3搭建本地知识库问答_人工智能_华为云开发者联盟_InfoQ写作社区

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

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

相关文章

第3章 小功能大用处-事务与Lua

为了保证多条命令组合的原子性,Redis提供了简单的事务功能以及集成Lua脚本来解决这个问题。 首先简单介绍Redis中事务的使用方法以及它的局限性,之后重点介绍Lua语言的基本使用方法,以及如何将Redis和Lua脚本进行集成,最后给出Red…

项目实训-vue(十三)

项目实训-vue(十三) 文章目录 项目实训-vue(十三)1.概述2.处理按钮 1.概述 本篇博客将记录我在图片上传页面中的工作。 2.处理按钮 实现了图片的上传之后,还需要设置具体的上传按钮。 这段代码使用 Element UI 的 …

Spring学习02-[Spring容器核心技术IOC学习]

Spring容器核心技术IOC学习 什么是bean?如何配置bean?Component方式bean配合配置类的方式import导入方式 什么是bean? 被Spring管理的对象就是bean,和普通对象的区别就是里面bean对象里面的属性也被注入了。 如何配置bean? Component方式、bean配合配置类的方式、import…

C语言 | Leetcode C语言题解之第190题颠倒二进制位

题目: 题解: const uint32_t M1 0x55555555; // 01010101010101010101010101010101 const uint32_t M2 0x33333333; // 00110011001100110011001100110011 const uint32_t M4 0x0f0f0f0f; // 00001111000011110000111100001111 const uint32_t M8…

【containerd】Containerd高阶命令行工具nerdctl

前言 对于习惯了使用docker cli的用户来说,containerd的命令行工具ctr使用起来不是很顺手,此时别慌,还有另外一个命令行工具项目nerdctl可供我们选择。 nerdctl是一个与docker cli风格兼容的containerd的cli工具。 nerdctl已经作为子项目加入…

秋招突击——6/24——复习{完全背包问题——买书,状态转换机——股票买卖V}——新作{两数相除,LRU缓存实现}

文章目录 引言复习完全背包问题——买书个人实现 状态转换机——股票买卖V个人实现参考实现 新作两数相除个人实现 新作LRU缓存实现个人实现unordered_map相关priority_queue相关 参考实现自己复现 总结 引言 今天知道拼多多挂掉了,难受,那实习就是颗粒无…

汪汪队短视频:成都柏煜文化传媒有限公司

汪汪队短视频:萌宠与冒险的交织乐章 在数字时代的浪潮中,短视频以其短小精悍、内容丰富的特点,迅速占领了人们的闲暇时光。而在这些琳琅满目的短视频中,有一类作品以其独特的魅力吸引了无数观众的目光,那就是以萌宠为…

单门户上集成多种数据库查询入口

(作者:陈玓玏) 开源项目,欢迎star哦,https://github.com/tencentmusic/cube-studio 在一家公司,我们通常会有多种数据库,每种数据库因为其特性承担不同的角色,比如mysql这种轻量…

AI-024人工智能指数报告(三):经济

概述 人工智能融入经济会引发许多很迷人的问题。有人预测人工智能会推动生产力得到改进,但其影响程度仍未确定。其中一个主要关切是大规模劳动替代的可能性——工作究竟会在多大程度上被自动化还是人工智能主要起到增强作用?各个行业的企业已经在用各种…

基于FPGA的温湿度检测

初始化部分就不过多赘述,我会给出对应的文件,我只说明这部分里面涉及到使用的代码部分 1、数据的读取和校验 数据的读取和检验代码如下 always (posedge clk_us)if (data_temp[7:0] data_temp[39:32] data_temp[31:24] data_temp[23:16] data_te…

SpringBoot+Vue集成富文本编辑器

1.引入 我们常常在各种网页软件中编写文档的时候,常常会有富文本编辑器,就比如csdn写博客的这个页面,包含了富文本编辑器,那么怎么实现呢?下面来详细的介绍! 2.安装wangeditor插件 在Vue工程中,…

基于 SpringBoot + Vue 的图书购物商城项目

本项目是一个基于 SpringBoot 和 Vue 的图书购物商城系统。系统主要实现了用户注册、登录,图书浏览、查询、加购,购物车管理,订单结算,会员折扣,下单,个人订单管理,书籍及分类管理,用…

PCL 使用列文伯格-马夸尔特法计算变换矩阵

目录 一、算法原理1、计算过程2、主要函数3、参考文献二、代码实现三、结果展示本文由CSDN点云侠原创,原文链接。如果你不是在点云侠的博客中看到该文章,那么此处便是不要脸的爬虫与GPT。 一、算法原理 1、计算过程 2、主要函数 void pcl

EXCEL快速填充空白内容

** EXCEL快速填充空白内容 ** 1.全选所有需要填充的内容,按住电脑的F5或者CTRLG点击定位 2.可以看到空白处被自动选定,之后按电脑和⬆,最后CTRLenter 可以看到空白处已经被填充。

计网入门还没到放弃

TCP报文段格式 源端口:标识报文的返回地址 目的端口:指明计算机上的应用程序接口 序号:通过SYN包传给接收端主机,每传送一次就1,用来解决网络包乱序的问题。 确认号:期望下一次收到的数据的序列号&#xff…

酷开科技用酷开系统打造数字化家庭娱乐与教育的新天地

家庭教育的重要性不言而喻,俗话说:父母是孩子的第一任老师,也是终生的老师。一个人是否能够成长成才,家庭教育是基础和前提,学校教育能够起到促进和引导作用,社会教育也会对一个人的成长产生重要影响。在数…

【YOLOv5/v7改进系列】引入PConv——轻量快速的卷积块

一、导言 《奔跑吧,别走:追求更高的FLOPS以实现更快的神经网络》,主要探讨了如何设计快速且高效的神经网络模型。文章指出,尽管许多研究致力于减少浮点运算次数(FLOPs)来提升模型速度,但FLOPs的减少并不直接等同于延迟…

Zookeeper部署

Zookeeper部署 下载安装包Linux解压安装包修改配置文件编辑zoo.cf配置 启动服务停止服务常用zookeeper指令查看namespace列表创建namespace删除namespace 注意:该文章为简单部署操作,没有复杂的配置内容,用的是3.7.2版本。 下载安装包 进入z…

python爬虫需要什么HTTP代理?

用来爬虫的话,还是建议用高匿名代理,但显然题主用了高匿名代理还是出现了一部分问题,我们可以先找到问题关键再解决它,一般爬虫用了高匿名代理出现被封会有以下几种原因: 1.代理IP的质量不过关 一般来说每个网站都有…

秋招突击——6/20——复习{(单调队列优化)——最大子序列和,背包问题——宠物小精灵收服问题}——新作{两两交换链表中的节点}

文章目录 引言复习单调队列优化——最大子序列和思路分析实现代码参考实现 背包问题——宠物小精灵的收服问题个人实现参考实现 新作两两交换链表中的节点个人实现参考实现 删除有序数组中的重复项个人实现知识补全迭代器的访问和控制vector删除特定的元素erasevector底层删除元…