梳理Langchain-Chatchat知识库API接口

news2024/11/24 0:53:47

一.Langchain-Chatchat 知识库管理

1.Langchain-Chatchat 对话和知识库管理界面

  Langchain-Chatchat v0.28 完整的界面截图,如下所示:

2.知识库中源文件和向量库

  知识库 test 中源文件和向量库的位置,如下所示:

3.知识库表结构

  knowledge_base 数据表内容,如下所示:

二.知识库操作 1

序号操作名字功能解释链接备注
1获取知识库列表就是上面的 samples(faiss @ bge-large-zh)和 test (faiss @ bge-large-zh)。http://127.0.0.1/knowledge_base/list_knowledge_bases-
2选择知识库选中一个知识库没有对应 API 接口-
3新建知识库新建一个知识库http://127.0.0.1/knowledge_base/create_knowledge_base,如下所示:{ "knowledge_base_name": "LLM", "vector_store_type": "faiss", "embed_model": "bge-large-zh"}创建知识库
4上传知识文件向知识库上传文件,比如限制每个文件 200MB,类型可为 HTML, MD, JSON, JSONL, CSV, PDF, PNG, JPG, JPEG, BMP, EML, MSG, EPUB, XLSX, XLSD, IPYNB, ODT, PY, RST, RTF, SRT, TOML, TSV, DOCX, DOC, XML, PPT, PPTX, TXT, HTM只是上传并显示了一个文件,并没有真的将文件上传到知识库中。-
5知识库介绍知识库描述http://127.0.0.1/knowledge_base/update_info,如下所示:{ "knowledge_base_name": "samples", "kb_info": "这是一个知识库"}-
6单段文本最大长度就是将长文本分割成多个较短的段落,每个段落的长度都不超过这个限制。可通过更新现有文件到知识库接口 update_docs 实现。-
7相邻文本重合长度将长文本分割成多个较短的段落时,相邻段落之间重复的文本的长度。这通常是为了确保 LLM 能够理解文本的上下文。可通过更新现有文件到知识库接口 update_docs 实现。-
8开启中文标题加强参考 kb_config.py 解释:1.是否开启中文标题加强,以及标题增强的相关配置;2.通过增加标题判断,判断哪些文本为标题,并在 metadata 中进行标记;3.然后将文本与往上一级的标题进行拼合,实现文本信息的增强。可通过更新现有文件到知识库接口 update_docs 实现。-
9添加文件到知识库将上传的文件添加到知识库中http://127.0.0.1/knowledge_base/upload_docs 说明:接口调用格式 POST -> Body -> form-data。-
1.获取知识库列表

  L:\20231106_ConversationSystem\ChatCopilot\Langchain\Langchain-Chatchat-0.2.8\server\api.py,如下所示:

app.get("/knowledge_base/list_knowledge_bases",
        tags=["Knowledge Base Management"],
        response_model=ListResponse,
        summary="获取知识库列表")(list_kbs)

  L:\20231106_ConversationSystem\ChatCopilot\Langchain\Langchain-Chatchat-0.2.8\server\knowledge_base\kb_api.py,如下所示:

def list_kbs():
    # Get List of Knowledge Base
    return ListResponse(data=list_kbs_from_db())

  L:\20231106_ConversationSystem\ChatCopilot\Langchain\Langchain-Chatchat-0.2.8\server\db\repository\knowledge_base_repository.py,如下所示:

@with_session
def list_kbs_from_db(session, min_file_count: int = -1):
    # 根据文件数量筛选知识库,-1表示不筛选,返回所有知识库
    kbs = session.query(KnowledgeBaseModel.kb_name).filter(KnowledgeBaseModel.file_count > min_file_count).all()
    # 遍历结果,取出知识库名称
    kbs = [kb[0] for kb in kbs]
    return kbs

  http://127.0.0.1/knowledge_base/list_knowledge_bases,返回结果:

{
    "code": 200,
    "msg": "success",
    "data": [
        "samples",
        "test"
    ]
}

2.选中知识库

  选中知识库并没有对应的接口,主要是选中知识库后,更新界面的(1)知识库介绍(2)知识库文档信息,包括源文件(遍历文件夹)和向量库(遍历数据库)。

(1)遍历文件夹

  比如 test 知识库对应的 L:\20231106_ConversationSystem\ChatCopilot\Langchain\Langchain-Chatchat-0.2.8\knowledge_base\test 文件夹。

(2)遍历数据库

  主要是 knowledge_file 数据表,包括 id、file_name、file_ext、kb_name、document_loader_name、text_splitter_name、file_version、file_mtime(文件修改时间)、file_size(单位)、custom_docs(自定义文档)、docs_count、create_time。

3.新建知识库

  L:\20231106_ConversationSystem\ChatCopilot\Langchain\Langchain-Chatchat-0.2.8\server\api.py,如下所示:

app.post("/knowledge_base/create_knowledge_base",
         tags=["Knowledge Base Management"],
         response_model=BaseResponse,
         summary="创建知识库"
         )(create_kb)

(1)拿到 FaissKBService 实例

  L:\20231106_ConversationSystem\ChatCopilot\Langchain\Langchain-Chatchat-0.2.8\server\knowledge_base\kb_api.py

def create_kb(knowledge_base_name: str = Body(..., examples=["samples"]),
            vector_store_type: str = Body("faiss"),
            embed_model: str = Body(EMBEDDING_MODEL),
            ) -> BaseResponse:
    # Create selected knowledge base
    if not validate_kb_name(knowledge_base_name):  # 验证知识库名称
        return BaseResponse(code=403, msg="Don't attack me")
    if knowledge_base_name is None or knowledge_base_name.strip() == "":  # 知识库名称不能为空
        return BaseResponse(code=404, msg="知识库名称不能为空,请重新填写知识库名称")

    kb = KBServiceFactory.get_service_by_name(knowledge_base_name)  # 验证知识库是否存在
    if kb is not None:  # 已存在同名知识库
        return BaseResponse(code=404, msg=f"已存在同名知识库 {knowledge_base_name}")  # 404

    kb = KBServiceFactory.get_service(knowledge_base_name, vector_store_type, embed_model)  # 返回FaissKBService实例
    try:
        kb.create_kb()  # 创建知识库
    except Exception as e:
        msg = f"创建知识库出错: {e}"
        logger.error(f'{e.__class__.__name__}: {msg}',
                     exc_info=e if log_verbose else None)
        return BaseResponse(code=500, msg=msg)

    return BaseResponse(code=200, msg=f"已新增知识库 {knowledge_base_name}")

(2)创建知识库

  L:\20231106_ConversationSystem\ChatCopilot\Langchain\Langchain-Chatchat-0.2.8\server\knowledge_base\kb_service\base.py,如下所示:

def create_kb(self):
    <em>"""</em>
<em>    创建知识库</em>
<em>    """</em>
<em>    </em>if not os.path.exists(self.doc_path):  # 如果文档路径不存在
        os.makedirs(self.doc_path)  # 创建文档路径
    self.do_create_kb()  # 创建知识库
    status = add_kb_to_db(self.kb_name, self.kb_info, self.vs_type(), self.embed_model)  # 添加知识库到数据库
    return status  # 返回状态

(3)添加知识库到数据库

  L:\20231106_ConversationSystem\ChatCopilot\Langchain\Langchain-Chatchat-0.2.8\server\db\repository\knowledge_base_repository.py,如下所示:

@with_session
def add_kb_to_db(session, kb_name, kb_info, vs_type, embed_model):
    # 创建知识库实例
    kb = session.query(KnowledgeBaseModel).filter_by(kb_name=kb_name).first()  # 查询知识库是否存在
    if not kb:  # 如果不存在,创建新的知识库
        kb = KnowledgeBaseModel(kb_name=kb_name, kb_info=kb_info, vs_type=vs_type, embed_model=embed_model)  # 创建知识库实例
        session.add(kb)  # 添加到数据库knowledge_base表中
    else:  # update kb with new vs_type and embed_model
        kb.kb_info = kb_info  # 更新知识库介绍
        kb.vs_type = vs_type  # 更新向量存储类型
        kb.embed_model = embed_model  # 更新嵌入模型
    return True

(4)接口调用

  http://127.0.0.1/knowledge_base/create_knowledge_base,如下所示:

{
    "knowledge_base_name": "LLM",
    "vector_store_type": "faiss",
    "embed_model": "bge-large-zh"
}

  特别说明:没有找到知识库简介字段(确定没有)。参考更新知识库介绍/knowledge_base/update_info。

  数据表 knowledge_base 信息,如下所示:

  LangChain-Chatchat 知识库管理界面信息,如下所示:

4.上传知识文件

  st.file_uploader 创建一个文件上传组件,显示一个选择文件的按钮。如下所示:

files = st.file_uploader("上传知识文件:",
                         [i for ls in LOADER_DICT.values() for i in ls],
                         accept_multiple_files=True,
                         )

  只是显示了一个文件,并没有真的将文件上传到知识库中。

5.知识库介绍

(1)知识库更新实现

  F:\ConversationSystem\ChatCopilot\Langchain\Langchain-Chatchat-0.2.8\server\api.py,如下所示:

app.post("/knowledge_base/update_info",
         tags=["Knowledge Base Management"],
         response_model=BaseResponse,
         summary="更新知识库介绍"
         )(update_info)

  对应的接口实现,如下所示:

def update_info(
        knowledge_base_name: str = Body(..., description="知识库名称", examples=["samples"]),
        kb_info: str = Body(..., description="知识库介绍", examples=["这是一个知识库"]),
):
    if not validate_kb_name(knowledge_base_name):
        return BaseResponse(code=403, msg="Don't attack me")

    kb = KBServiceFactory.get_service_by_name(knowledge_base_name)
    if kb is None:
        return BaseResponse(code=404, msg=f"未找到知识库 {knowledge_base_name}")
    kb.update_info(kb_info)

    return BaseResponse(code=200, msg=f"知识库介绍修改完成", data={"kb_info": kb_info})

  本质上还是更新数据库 knowledge_base,对知识库介绍字段进行更新。

(2)接口调用

http://127.0.0.1/knowledge_base/update_info,如下所示:

6.单段文本最大长度

  可通过更新现有文件到知识库接口 update_docs 实现。

7.相邻文本重合长度

  可通过更新现有文件到知识库接口 update_docs 实现。

8.开启中文标题加强

  可通过更新现有文件到知识库接口 update_docs 实现。

9.添加文件到知识库,并/或向量化

  F:\ConversationSystem\ChatCopilot\Langchain\Langchain-Chatchat-0.2.8\server\api.py,如下所示:

app.post("/knowledge_base/upload_docs",
         tags=["Knowledge Base Management"],
         response_model=BaseResponse,
         summary="上传文件到知识库,并/或进行向量化"
         )(upload_docs)

(1)upload_docs 函数

def upload_docs(
        file: List[UploadFile] = File(..., description="上传文件,支持多文件"),
        knowledge_base_name: str = Form(..., description="知识库名称", examples=["samples"]),
        override: bool = Form(False, description="覆盖已有文件"),
        to_vector_store: bool = Form(True, description="上传文件后是否进行向量化"),
        chunk_size: int = Form(CHUNK_SIZE, description="知识库中单段文本最大长度"),
        chunk_overlap: int = Form(OVERLAP_SIZE, description="知识库中相邻文本重合长度"),
        zh_title_enhance: bool = Form(ZH_TITLE_ENHANCE, description="是否开启中文标题加强"),
        docs: Json = Form({}, description="自定义的docs,需要转为json字符串",
                          examples=[{"test.txt": [Document(page_content="custom doc")]}]),
        not_refresh_vs_cache: bool = Form(False, description="暂不保存向量库(用于FAISS)"),
) -> BaseResponse:
序号字段名类型解释备注
1fileList[UploadFile]上传文件,支持多文件-
2knowledge_base_namestr知识库名称-
3overridebool覆盖已有文件-
4to_vector_storebool上传文件后是否进行向量化-
5chunk_sizeint知识库中单段文本最大长度就是将长文本分割成多个较短的段落,每个段落的长度都不超过这个限制。
6chunk_overlapint知识库中相邻文本重合长度将长文本分割成多个较短的段落时,相邻段落之间重复的文本的长度。这通常是为了确保 LLM 能够理解文本的上下文。
7zh_title_enhancebool是否开启中文标题加强参考 kb_config.py 解释:1.是否开启中文标题加强,以及标题增强的相关配置;2.通过增加标题判断,判断哪些文本为标题,并在 metadata 中进行标记;3.然后将文本与往上一级的标题进行拼合,实现文本信息的增强。
8docsJson自定义的 docs,需要转为 json 字符串推测自定义文档主要是为了测试用途(不清楚还有没有其它的用途)。
9not_refresh_vs_cachebool暂不保存向量库(用于 FAISS)目前支持 FAISS,是否保存向量库。

(2)先将上传的文件保存到磁盘

  不再解释,就是将上传的文件保存到知识库本地相应的文件夹中。

(3)对保存的文件进行向量化

  当 to_vector_store=True 时,调用更新知识库文档接口 update_docs。具体实现如下所示:

# 对保存的文件进行向量化
if to_vector_store:  # 如果需要向量化
    result = update_docs(  # 调用update_docs接口
        knowledge_base_name=knowledge_base_name,  # 知识库名称
        file_names=file_names,  # 文件名称
        override_custom_docs=True,  # 覆盖之前自定义的docs
        chunk_size=chunk_size,  # 知识库中单段文本最大长度
        chunk_overlap=chunk_overlap,  # 知识库中相邻文本重合长度
        zh_title_enhance=zh_title_enhance,  # 是否开启中文标题加强
        docs=docs,  # 自定义的docs
        not_refresh_vs_cache=True,  # 暂不保存向量库(只有FAISS实现了)
    )
    failed_files.update(result.data["failed_files"])  # 更新上传失败的文件
    if not not_refresh_vs_cache:  # 如果需要保存向量库
        kb.save_vector_store()  # 保存向量库

  默认 not_refresh_vs_cache=True,即暂不保存向量库。如果 not_refresh_vs_cache=False,那么执行 kb.save_vector_store()。FAISS 保存到磁盘(已实现),milvus 保存到数据库(未实现),PGVector 暂未支持(未实现)。具体实现,如下所示:

def save_vector_store(self):
    self.load_vector_store().save(self.vs_path)

(4)接口调用

  http://127.0.0.1/knowledge_base/upload_docs,如下所示:

  控制台输出,可以看到使用的加载器为 UnstructuredFileLoader,然后将向量库保存到磁盘(FAISS),如下所示:

2024-01-21 19:17:56,650 - utils.py[line:286] - INFO: UnstructuredFileLoader used for F:\ConversationSystem\ChatCopilot\Langchain\Langchain-Chatchat-0.2.8\knowledge_base\LLM\content\data.txt
文档切分示例:page_content='{"Q": "宪法规定的公民法律义务有"}\n{"Q": "属于专门人民法院的是"}\n{"Q": "无效婚姻的种类包括"}\n{"Q": "刑事案件定义"}' metadata={'source': 'F:\\ConversationSystem\\ChatCopilot\\Langchain\\Langchain-Chatchat-0.2.8\\knowledge_base\\LLM\\content\\data.txt'}
Batches: 100%|██████████| 1/1 [00:00<00:00,  4.44it/s]
2024-01-21 19:18:04,893 - faiss_cache.py[line:24] - INFO: 已将向量库 ('LLM', 'bge-large-zh') 保存到磁盘
INFO:     127.0.0.1:61524 - "POST /knowledge_base/upload_docs HTTP/1.1" 200 OK

(5)可能遇到的问题

  通过界面操作时,Browser files 上传一个文件之后,点击按钮"添加文件到知识库",出现如下所示:

INFO:     127.0.0.1:60656 - "POST /knowledge_base/upload_docs HTTP/1.1" 422 Unprocessable Entity
2024-01-21 19:10:25,208 - _client.py[line:1027] - INFO: HTTP Request: POST http://127.0.0.1:7861/knowledge_base/upload_docs "HTTP/1.1 422 Unprocessable Entity"

说明:暂未找到原因。

三.知识库操作 2

序号操作名字功能解释链接备注
1下载选中文档选中一个文档,然后下载,可以是源文件,也可以是向量库。http://127.0.0.1/knowledge_base/download_doc-
2重新添加至向量库1.如果是源文件,执行"添加至向量库"操作 2.如果是向量库,执行"重新添加至向量库"操作http://127.0.0.1/knowledge_base/upload_docs-
3从向量库删除1.如果选中的是源文件,那么该按钮为灰色。2.如果选中的是向量库,那么该按钮可操作。http://127.0.0.1/knowledge_base/delete_docs-
4从知识库中删除1.如果是源文件,那么该按钮可操作。2.如果是向量库,那么该按钮可操作。http://127.0.0.1/knowledge_base/delete_docs-
5依据源文件重建向量库该操作针对的是整个知识库,根据源文件重建向量库,并不针对某个具体的源文件或者向量库文件。http://127.0.0.1/knowledge_base/recreate_vector_store-
6删除知识库就是把整个知识库删除掉
1.下载选中文档

(1)download_doc 接口

  F:\ConversationSystem\ChatCopilot\Langchain\Langchain-Chatchat-0.2.8\server\api.py,如下所示:

app.get("/knowledge_base/download_doc",
        tags=["Knowledge Base Management"],
        summary="下载对应的知识文件")(download_doc)

download_doc 接口主要是根据知识库名字和文件名字拿到文件路径,然后返回 FileResponse 对象。

(2)接口调用

  http://127.0.0.1/knowledge_base/download_doc,如下所示:

(3)界面操作

  无论是下载源文件,还是向量库文件,都是先选中,然后下载。下载的向量库文件,和下载的源文件内容都是一样的,都是源文件的内容,而不是编码后的内容。

2.添加至向量库/重新添加至向量库

(1)界面操作

  当选择源文件时,显示添加至向量库,如下所示:

  当选择向量库文件时,显示重新添加至向量库,如下所示:

(2)接口调用

  无论是"添加至向量库",还是"重新添加至向量库"都是调用的 upload_docs 接口,"添加至向量库"控制台日志如下所示:

2024-01-21 23:59:11,127 - utils.py[line:286] - INFO: UnstructuredFileLoader used for F:\ConversationSystem\ChatCopilot\Langchain\Langchain-Chatchat-0.2.8\knowledge_base\LLM\content\data.txt
文档切分示例:page_content='{"Q": "宪法规定的公民法律义务有"}\n{"Q": "属于专门人民法院的是"}\n{"Q": "无效婚姻的种类包括"}\n{"Q": "刑事案件定义"}' metadata={'source': 'F:\\ConversationSystem\\ChatCopilot\\Langchain\\Langchain-Chatchat-0.2.8\\knowledge_base\\LLM\\content\\data.txt'}
2024-01-21 23:59:21,557 - faiss_cache.py[line:80] - INFO: loading vector store in 'LLM/vector_store/bge-large-zh' from disk.
2024-01-21 23:59:21,611 - SentenceTransformer.py[line:66] - INFO: Load pretrained SentenceTransformer: F:\HuggingFaceModel\bge-large-zh
2024-01-21 23:59:22,878 - loader.py[line:54] - INFO: Loading faiss with AVX2 support.
2024-01-21 23:59:22,878 - loader.py[line:58] - INFO: Could not load library with AVX2 support due to: ModuleNotFoundError("No module named 'faiss.swigfaiss_avx2'")
2024-01-21 23:59:22,878 - loader.py[line:64] - INFO: Loading faiss.
2024-01-21 23:59:23,050 - loader.py[line:66] - INFO: Successfully loaded faiss.
Batches: 100%|██████████| 1/1 [00:00<00:00,  5.64it/s]
2024-01-21 23:59:23,294 - faiss_cache.py[line:24] - INFO: 已将向量库 ('LLM', 'bge-large-zh') 保存到磁盘
2024-01-21 23:59:23,297 - _client.py[line:1027] - INFO: HTTP Request: POST http://127.0.0.1:7861/knowledge_base/update_docs "HTTP/1.1 200 OK"
INFO:     127.0.0.1:50606 - "POST /knowledge_base/update_docs HTTP/1.1" 200 OK

  "重新添加至向量库"控制台日志如下所示:

2024-01-22 00:14:56,917 - utils.py[line:286] - INFO: UnstructuredFileLoader used for F:\ConversationSystem\ChatCopilot\Langchain\Langchain-Chatchat-0.2.8\knowledge_base\LLM\content\data.txt
文档切分示例:page_content='{"Q": "宪法规定的公民法律义务有"}\n{"Q": "属于专门人民法院的是"}\n{"Q": "无效婚姻的种类包括"}\n{"Q": "刑事案件定义"}' metadata={'source': 'F:\\ConversationSystem\\ChatCopilot\\Langchain\\Langchain-Chatchat-0.2.8\\knowledge_base\\LLM\\content\\data.txt'}
Batches: 100%|██████████| 1/1 [00:00<00:00,  4.71it/s]
2024-01-22 00:14:57,713 - faiss_cache.py[line:24] - INFO: 已将向量库 ('LLM', 'bge-large-zh') 保存到磁盘
2024-01-22 00:14:57,716 - _client.py[line:1027] - INFO: HTTP Request: POST http://127.0.0.1:7861/knowledge_base/update_docs "HTTP/1.1 200 OK"
INFO:     127.0.0.1:51617 - "POST /knowledge_base/update_docs HTTP/1.1" 200 OK
3.从向量库删除

(1)基本删除思路

  只能删除向量库文件,不能删除源文件。因为当选中源文件时,这个按钮是禁用状态。基本删除思路为:删除向量库中的内容(比如 faiss),删除数据库中的内容(knowledge_file 数据表)。F:\ConversationSystem\ChatCopilot\Langchain\Langchain-Chatchat-0.2.8\server\api.py,如下所示:

app.post("/knowledge_base/delete_docs",
         tags=["Knowledge Base Management"],
         response_model=BaseResponse,
         summary="删除知识库内指定文件"
         )(delete_docs)

(2)接口调用

http://127.0.0.1/knowledge_base/delete_docs,如下所示:

4.从知识库中删除

(1)基本思路

  无论是向量库文件,还是源文件都是可以删除的。基本删除思路为:删除向量库中的内容(比如 faiss),删除数据库中的内容(knowledge_file 数据表),删除上传文件夹中的文件。

(2)接口调用

  查看源码,从向量库删除和从知识库删除区别,前者"delete_content": false,而后者为"delete_content": true。这个字段主要是控制着是否删除文件夹。http://127.0.0.1/knowledge_base/delete_docs,如下所示:

5.依据源文件重建向量库

  F:\ConversationSystem\ChatCopilot\Langchain\Langchain-Chatchat-0.2.8\server\api.py,如下所示:

app.post("/knowledge_base/recreate_vector_store",
         tags=["Knowledge Base Management"],
         summary="根据content中文档重建向量库,流式输出处理进度。"
         )(recreate_vector_store)

  本质上就是将原来的向量库清空,然后重建操作。http://127.0.0.1/knowledge_base/recreate_vector_store 接口调用如下所示:

  上述英文内容翻译:从内容重新创建矢量存储。当用户可以直接将文件复制到内容文件夹而不是通过网络上传时,这很有用。默认情况下,get_service_by_name 只返回 info.db 中的知识库并在其中包含文档文件。将 allow_empty_kb 设置为 True 使其应用于不在 info.db 中或没有文档的空知识库。

6.删除知识库

  本质上是删除向量库、数据库信息和文件夹。F:\ConversationSystem\ChatCopilot\Langchain\Langchain-Chatchat-0.2.8\server\api.py,如下所示:

app.post("/knowledge_base/delete_knowledge_base",
         tags=["Knowledge Base Management"],
         response_model=BaseResponse,
         summary="删除知识库"
         )(delete_kb)

http://127.0.0.1/knowledge_base/接口调用如下所示:

  除此之外,还有一些接口没有介绍实现逻辑,可参考文献[1]。如果不查看源代码,可能很难较为深入的理解每个操作步骤的具体实现逻辑。

参考文献

[1] Langchain-Chatchat API Server:http://127.0.0.1/docs

[2] https://github.com/chatchat-space/Langchain-Chatchat/releases/tag/v0.2.8

[3] 梳理Langchain-Chatchat知识库API接口(原文链接):https://z0yrmerhgi8.feishu.cn/wiki/XN7AwrH6DiCpMIkaNnAcPd7znZc

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

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

相关文章

JavaWeb之开发介绍 --黑马笔记

什么是 Web &#xff1f; Web&#xff1a;全球广域网&#xff0c;也称为万维网(www World Wide Web)&#xff0c;能够通过浏览器访问的网站。 Web 网站的工作流程 上图解释&#xff1a; 当你在浏览器中输入网址或点击一个链接时&#xff0c;浏览器会向前端服务器发起请求&…

CSAPP fall2015 深入理解计算机系统 Cache lab详解

Cache Lab cache lab 缓存实验 代码下载 从CSAPP上面下载对应的lab代码 http://csapp.cs.cmu.edu/3e/labs.html 环境准备 需要安装 valgrind。可以参考文章Valgrind centos。 安装好以后执行valgrind --version可以看到版本号。 Cache simulator cache simulator not a …

API接口安全总结

接口分类 HTTP接口 RPC接口&#xff08;客户端和服务器端的连接 例如游戏登陆&#xff09;非web协议&#xff0c;PRC 远程过程调用 Remote Procedure Call&#xff0c;其就是一个节点请求另外一个节点提供的服务。当两个物理分离的子系统需要建立逻辑上的关联时&#xff0c;R…

第08章_面向对象编程(高级)(static,单例设计模式,理解mian方法,代码块,final,抽象类与抽象方法,接口,内部类,枚举类,注解,包装类)

文章目录 第08章_面向对象编程(高级)本章专题与脉络1. 关键字&#xff1a;static1.1 类属性、类方法的设计思想1.2 static关键字1.3 静态变量1.3.1 语法格式1.3.2 静态变量的特点1.3.3 举例1.3.4 内存解析 1.4 静态方法1.4.1 语法格式1.4.2 静态方法的特点1.4.3 举例 1.5 练习 …

小土堆pytorch学习笔记001

1、Pytorch环境的配置与安装。 &#xff08;1&#xff09;建议安装&#xff1a;Anaconda &#xff08;2&#xff09;检查显卡&#xff1a;GPU &#xff08;3&#xff09;管理环境&#xff08;不同版本的pytorch 版本不同&#xff09;&#xff1a; conda create -n pytorch…

【开源】基于JAVA+Vue+SpringBoot的农家乐订餐系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 用户2.2 管理员 三、系统展示四、核心代码4.1 查询菜品类型4.2 查询菜品4.3 加购菜品4.4 新增菜品收藏4.5 新增菜品留言 五、免责说明 一、摘要 1.1 项目介绍 基于JAVAVueSpringBootMySQL的农家乐订餐系统&#xff0c…

防御保护----信息安全

网络安全概述 信息安全&#xff1a;防止任何对数据进行未授权访问的措施&#xff0c;或者防止造成信息有意无意泄露、破坏、丢失等问题的发生&#xff0c;让数据处于远离危险、免于威胁的状态和特性。 网络安全&#xff1a;计算机网络环境下的信息安全。 网络安全背景 网络空间…

STM32单片机学习5--STM32中断

文章目录 一、前言二、NVIC中断控制器2.1、NVIC结构体成员2.2、抢占优先级和响应优先级2.3、NVIC的优先级组 三、EXTI外部中断四、中断实战4.1、确定连线4.2、配置中断控制端口4.3、配置中断端口4.4、配置中断服务函数4.5、主函数调用 一、前言 单片机无系统执行逻辑&#xff…

央视:人工智能规模达5000亿元,企业超4400家,生成式AI发展进入快车道

2023年&#xff0c;对世界和中国来讲都是非常不平凡的一年。新一代信息技术&#xff0c;如5G、大数据和云计算&#xff0c;正在引领全球科技和产业变革的潮流。这些技术已经深深地融入了经济社会发展的各个领域&#xff0c;推动信息通信业实现了跨越式的发展。 1、AI助力产业发…

教你三个方法去除图片上的涂鸦快收藏起来吧

在数字时代&#xff0c;我们经常需要在图片上进行各种编辑和修改&#xff0c;以使其符合我们的需求。然而&#xff0c;有时候我们会遇到一些图片上的涂鸦&#xff0c;这些涂鸦不仅影响了图片的美观度&#xff0c;还破坏了图片的整体效果。那么图片上的涂鸦怎么去掉&#xff0c;…

Hive 行列转换

行列转换 列转行 使用 lateral view explode(array|map) 或 lateral view inline(array_struct) 可以将列转换为行。 单列转多行&#xff0c;降维&#xff08;单列数组或键值对&#xff09; 示例1&#xff1a;explode(array(…)) select ..., A from T lateral view exp…

RT-DETR 模型改进 | AKConv:具有任意采样形状和任意参数数量的卷积核

基于卷积操作的神经网络在深度学习领域取得了显著的成果,但标准卷积操作存在两个固有缺陷。一方面,卷积操作受限于局部窗口,无法捕捉其他位置的信息,而其采样形状是固定的。另一方面,卷积核的大小固定为kk,呈固定的正方形形状,而参数数量往往随大小呈平方增长。显然,不…

【Godot4自学手册】第三节设置主人公的动画

继续&#xff0c;今天是第三节&#xff0c;我们主要实现主人公的动画效果&#xff0c;共有两种方法实现动画效果 一、通过AnimationPlayer节点实现动画效果 我们首先在player场景下&#xff0c;player节点下添加AnimationPlayer节点&#xff0c;添加方法是&#xff0c;在play…

嵌入式学习-网络编程-Day6、7

嵌入式学习-网络编程-Day6 一、思维导图 二、作业 1.基于UDP的网络聊天室&#xff08;2024.1.21号前上交&#xff09; 项目需求&#xff1a; 1.如果有用户登录&#xff0c;其他用户可以收到这个人的登录信息 2.如果有人发送信息&#xff0c;其他用户可以收到这个人的群聊信息…

【论文代码】基于隐蔽带宽的汽车控制网路鲁棒认证-到达时间间隔通道的Java实现(二)

文章目录 五、TransmissionThread 抽象类5.1 IAT_thread类5.2 DLC_Thread 六、AttestationProtocol 接口6.1 HardCodedAttestation 七、FilterMash 类7.1 FilterValue 八、其他类8.1 CANAuthMessage8.2 USBtinException8.3 USBtinLibDemo8.4 CANMessage8.5 NoiseThread8.6 Filt…

Vulnhub靶机:FunBox 4

一、介绍 运行环境&#xff1a;Virtualbox 攻击机&#xff1a;kali&#xff08;10.0.2.15&#xff09; 靶机&#xff1a;FunBox 4&#xff08;10.0.2.29&#xff09; 目标&#xff1a;获取靶机root权限和flag 靶机下载地址&#xff1a;https://download.vulnhub.com/funbo…

11.什么档次的原型模式和我写的一样

在《生化危机》系列电影中&#xff0c;克隆人是个频频出现的话题。保护伞公司为了需求复制出另一个战力相当的战士Alice&#xff0c;不惜克隆成百上千个Alice&#xff0c;然而直到最后&#xff0c;非但没有真正克隆出另一个完美的Alice&#xff0c;就连Alice自己也被证实是保护…

华为OD机试之阿里巴巴找黄金宝箱(IV) C++

题目背景 贫如洗的椎夫阿里巴巴在去砍柴的路上&#xff0c;无意中发现了强盗集团的藏宝地&#xff0c;藏宝地有编号从0-N的箱子&#xff0c;每个箱子上面有一人数字&#xff0c;箱子排列成一个环&#xff0c;编号最大的箱子的下一个是编号为0的箱子。请输出每个箱了贴的数字之…

REVIT二次开发万能刷

将这两个参数赋予其他参数 步骤2 将来做个可以调控的版本 using System; using System.Collections.Generic; using System.Lin

常用界面设计组件 —— 数字输入和显示组件

2.3 数字输入和显示组件2.3.1 QSpinBox 与 QDoubleSpinBox2.3.2其它数值输入和显示组件 2.3 数字输入和显示组件 2.3.1 QSpinBox 与 QDoubleSpinBox QSpinBox用于整数的显示和输入&#xff0c;一般显示十进制 数&#xff0c;也可以显示二进制、十六进制数&#xff0c;而且可以…