LangChain开发(九)基于Rag实现文档问答
文章目录
- 关联阅读
- Rag是什么?
- Rag工作流
- 索引(Indexing)
- 检索和生成(Retrieval and generation)
- 文档问答
- 实现流程
- 代码实现
- 源码地址
- 参考资料
关联阅读
LangChain开发(一)LangChain介绍和对话demo
LangChain开发(二)LangChain提示词模板Template使用
LangChain开发(三)工作流编排(LCEL)
LangChain开发(四)服务监控(LangSmith、verbose、debug)
LangChain开发(五)消息管理与聊天历史存储
LangChain开发(六)多模态输入与自定义输出
LangChain开发(七)自定义输出格式(JSON/XML/YAML)
LangChain开发(八)自定义工具调用
Rag是什么?
大语言模型所实现的最强大的应用之一是复杂的问答(Q&A)聊天机器人。这些应用能够回答关于特定源信息的问题。这些应用使用一种称为检索增强生成(RAG)的技术。
RAG是一种用额外数据增强大语言模型知识的技术。
大语言模型可以对广泛的主题进行推理,但它们的知识仅限于训练时截止日期前得公开数据。如果你想构建能够对私有数据或模型截止日期后引入的数据进行推理的人工智能应用,你需要用特定信息来增强模型的知识。检索适当信息并将其插入模型提示的过程被称为检索增强生成(RAG)。
LangChain有许多组件旨在帮助构建问答应用,以及更广泛的RAG应用。
Rag工作流
一个典型的RAG应用有两个主要组成部分:
索引(Indexing):从数据源获取数据并建议索引的管道(pipeline)。这通常再离线状态下进行。
检索和生成(Retrieval and generation):实际的RAG链,在运行时接受用户查询,从索引中检索相关数据,然后将其传递给模型。
从原始数据到答案最常见完整顺序如下:
索引(Indexing)
- 加载(Load):首先我们需要加载数据。这是通过文档加载器Document Loaders完成的。
- 分割(Split): 文本分割器Text splitters 将大型文档(Documents)分割为更小的块(chunks)。这对于索引数据和将其传递给模型都很有用,因为大块数据很难搜索,而且不适合大模型有限的上下文窗口。
- 存储(Store):我们需要一个地方来存储和索引我们的分割(splits),以便后续可以对其进行搜索。这通常使用向量存储VectorStore和嵌入模型Embedding model来完成。
检索和生成(Retrieval and generation)
- 检索(Retrieve):给定用户输入,使用检索器Retriever从存储中检索相关的文本片段。
- 生成(Generate):ChatModel使用包含问题和检索到的数据的提示来生成答案。
文档问答
实现流程
一个RAG程序的APP主要有以下流程:
- 用户在RAG客户端上传一个pdf文件
- 服务器端接受客户端文件,存储在服务端
- 服务器端程序对文件进行读取
- 对文件内容进行拆分,防止一次性塞给Embedding模型超token限制
- 把Embedding后的内容存储在向量数据库,生成检索器
- 程序准备就绪,允许用户进行体温
- 用户提出问题,调用检索器检索文档,把相关片段找出来后,给大模型,大模型组织后,回复用户。
代码实现
使用Streamlit实现文件上传,这里只实现了pdf和txt文件上传,可以在type参数里面设置多个文件类型,在后面的检索器方法里面针对每个类型进行处理即可。
import os
import tempfile
import streamlit as st
from langchain.chat_models import ChatOpenAI
from langchain.document_loaders import PyPDFLoader
from langchain.memory import ConversationBufferMemory
from langchain.memory.chat_message_histories import StreamlitChatMessageHistory
from langchain.embeddings import HuggingFaceEmbeddings
from langchain.callbacks.base import BaseCallbackHandler
from langchain.chains import ConversationalRetrievalChain
from langchain.vectorstores import DocArrayInMemorySearch
from langchain.text_splitter import RecursiveCharacterTextSplitter
# pip install langchain
# pip install langchain-openai
# pip install langchain_community
# pip install sentence-transformers
# pip install docarray
# pip install pypdf
# 参考源码地址 https://github.com/langchain-ai/streamlit-agent/blob/634e1cecf23d7ca3a4c5e708944673e057765b2a/streamlit_agent/chat_with_documents.py
st.set_page_config(page_title="PDF文档问答", page_icon="🦜")
st.title("🦜 PDF文档问答") @st.cache_resource(ttl="1h")
def configure_retriever(uploaded_files): # Read documents docs = [] temp_dir = tempfile.TemporaryDirectory() for file in uploaded_files: temp_filepath = os.path.join(temp_dir.name, file.name) with open(temp_filepath, "wb") as f: f.write(file.getvalue()) loader = PyPDFLoader(temp_filepath) docs.extend(loader.load()) # Split documents text_splitter = RecursiveCharacterTextSplitter(chunk_size=1500, chunk_overlap=200) splits = text_splitter.split_documents(docs) # Create embeddings and store in vectordb embeddings = HuggingFaceEmbeddings(model_name="all-MiniLM-L6-v2") vectordb = DocArrayInMemorySearch.from_documents(splits, embeddings) # Define retriever retriever = vectordb.as_retriever(search_type="mmr", search_kwargs={"k": 2, "fetch_k": 4}) return retriever class StreamHandler(BaseCallbackHandler): def __init__(self, container: st.delta_generator.DeltaGenerator, initial_text: str = ""): self.container = container self.text = initial_text self.run_id_ignore_token = None def on_llm_start(self, serialized: dict, prompts: list, **kwargs): # Workaround to prevent showing the rephrased question as output if prompts[0].startswith("Human"): self.run_id_ignore_token = kwargs.get("run_id") def on_llm_new_token(self, token: str, **kwargs) -> None: if self.run_id_ignore_token == kwargs.get("run_id", False): return self.text += token self.container.markdown(self.text) class PrintRetrievalHandler(BaseCallbackHandler): def __init__(self, container): self.status = container.status("**Context Retrieval**") def on_retriever_start(self, serialized: dict, query: str, **kwargs): self.status.write(f"**Question:** {query}") self.status.update(label=f"**Context Retrieval:** {query}") def on_retriever_end(self, documents, **kwargs): for idx, doc in enumerate(documents): source = os.path.basename(doc.metadata["source"]) self.status.write(f"**Document {idx} from {source}**") self.status.markdown(doc.page_content) self.status.update(state="complete") openai_api_key = os.getenv("DASHSCOPE_API_KEY") uploaded_files = st.sidebar.file_uploader( label="上传PDF文件", type=["pdf"], accept_multiple_files=True
)
if not uploaded_files: st.info("上传PDF文档后使用") st.stop() retriever = configure_retriever(uploaded_files) # Setup memory for contextual conversation
msgs = StreamlitChatMessageHistory()
memory = ConversationBufferMemory(memory_key="chat_history", chat_memory=msgs, return_messages=True) # Setup LLM and QA chain
llm = ChatOpenAI( api_key=os.getenv("DASHSCOPE_API_KEY"), base_url="https://dashscope.aliyuncs.com/compatible-mode/v1", model="qwen-turbo"
)
qa_chain = ConversationalRetrievalChain.from_llm( llm, retriever=retriever, memory=memory, verbose=True
) if len(msgs.messages) == 0 or st.sidebar.button("Clear message history"): msgs.clear() msgs.add_ai_message("How can I help you?") avatars = {"human": "user", "ai": "assistant"}
for msg in msgs.messages: st.chat_message(avatars[msg.type]).write(msg.content) if user_query := st.chat_input(placeholder="Ask me anything!"): st.chat_message("user").write(user_query) with st.chat_message("assistant"): retrieval_handler = PrintRetrievalHandler(st.container()) stream_handler = StreamHandler(st.empty()) response = qa_chain.run(user_query, callbacks=[retrieval_handler, stream_handler])
安装完依赖后,使用以下命令启动
streamlit run .\11-rag\01-chat_with_documents.py
文档内容
公司休假制度员工每年有多少天年假?
员工每年享有15天的带薪年假,具体天数根据工龄有所调整。病假如何申请?
员工需提供医生证明,并通过人力资源部门的审批流程申请病假。法定节假日有哪些?
公司遵循国家规定的法定节假日,包括春节、国庆节、中秋节等。公司福利
公司提供哪些保险福利?公司为员工提供五险一金,包括养老保险、医疗保险、失业保险、工伤保险、生育保险和住房公积金是否有员工健康体检?
公司每年为员工安排一次免费的健康体检有哪些员工活动或俱乐部?公司定期组织团建活动,并有多个兴趣俱乐部,如球、书法、摄影等公司规章制度工作时间如何安排?
正常工作时间为周一至周五,上午9:00至下午6:00,每周工作40小时:
使用界面
源码地址
https://github.com/lys1313013/langchain-example/tree/main/11-rag
参考资料
https://github.com/langchain-ai/streamlit-agent/blob/634e1cecf23d7ca3a4c5e708944673e057765b2a/streamlit_agent/chat_with_documents.py
相关文章:
LangChain开发(九)基于Rag实现文档问答
文章目录 关联阅读Rag是什么?Rag工作流索引(Indexing)检索和生成(Retrieval and generation) 文档问答实现流程代码实现 源码地址参考资料 关联阅读 LangChain开发(一)LangChain介绍和对话demo…...
Netty——TCP 粘包/拆包问题
文章目录 1. 什么是 粘包/拆包 问题?2. 原因2.1 Nagle 算法2.2 滑动窗口2.3 MSS 限制2.4 粘包的原因2.5 拆包的原因 3. 解决方案3.1 固定长度消息3.2 分隔符标识3.3 长度前缀协议3.3.1 案例一3.3.2 案例二3.3.3 案例三 4. 总结 1. 什么是 粘包/拆包 问题?…...
探索抓包利器ProxyPin,实现手机APP请求抓包,支持https请求
以下是ProxyPin的简单介绍: - ProxyPin是一个开源免费HTTP(S)流量捕获神器,支持 Windows、Mac、Android、IOS、Linux 全平台系统- 可以使用它来拦截、检查并重写HTTP(S)流量,支持捕获各种应用的网络请求。ProxyPin基于Flutter开发࿰…...
【例3.5】位数问题(信息学奥赛一本通-1313)
【题目描述】 在所有的N位数中,有多少个数中有偶数个数字3?由于结果可能很大,你只需要输出这个答案对12345取余的值。 【输入】 读入一个数N(N≤1000)。 【输出】 输出有多少个数中有偶数个数字3。 【输入样例】 2 【输出样例】 73 【题解代码】 #incl…...
python之selenium中的窗口切换
前提:触发一个事件打开一个新的窗口 1,先获取所有的句柄: handles driver.windowhandlers2,获取当前窗口 cururl driver.current_url3,循环遍历所有句柄 for handle in handles:driver.switch_to.window(handle)i…...
青少年编程与数学 02-011 MySQL数据库应用 20课题、连接与ORM
青少年编程与数学 02-011 MySQL数据库应用 20课题、连接与ORM 一、数据库连接基本概念连接过程连接状态连接池技术 二、Go语言连接MySQL数据库安装MySQL驱动导入相关包建立数据库连接检查连接状态执行SQL操作查询操作插入操作更新操作删除操作 完整示例 三、Python语言连接MySQ…...
Java 大视界 -- 基于 Java 的大数据分布式系统的监控与运维实践(155)
💖亲爱的朋友们,热烈欢迎来到 青云交的博客!能与诸位在此相逢,我倍感荣幸。在这飞速更迭的时代,我们都渴望一方心灵净土,而 我的博客 正是这样温暖的所在。这里为你呈上趣味与实用兼具的知识,也…...
三维空间中点、线、面的关系
三维空间中点、线、面的关系 点相对于平面的位置关系直线相对于平面的位置关系1.根据三点计算平面方程 //根据3点计算平面方程#include <iostream> #include <cmath> #include <vector>...
Spring JdbcTemplate 万字详解(通俗易懂)
目录 Δ前言 一、什么是JdbcTemplate? 1.定义: 2.作用: 3.环境搭建: 二、JdbcTemplate的简单使用 1.通过JdbcTemplate实现数据的添加: 2.通过JdbcTemplate实现数据的修改: 三、JdbcTemplate的进阶使用 …...
centos 7 搭建ftp 基于虚拟用户用shell脚本搭建
#!/bin/bash# 步骤1: 更新系统并安装vsftpd yum update -y yum install vsftpd -y# 步骤2: 创建虚拟用户信息文件并转换为数据库文件 cat << EOF > /etc/vsftpd/virtual_users.txt ftpvuser 123456 EOFdb_load -T -t hash -f /etc/vsftpd/virtual_users.txt /etc/vsft…...
《Android低内存设备性能优化实战:深度解析Dalvik虚拟机参数调优》
1. 痛点分析:低内存设备的性能困局 现象描述:大应用运行时频繁GC导致卡顿 根本原因:Dalvik默认内存参数与硬件资源不匹配 解决方向:动态调整堆内存参数以平衡性能与资源消耗 2. 核心调优参数全景解析 关键参数矩阵࿱…...
【AI学习】概念了解
1,GPU 专门用于处理图形相关运算任务的微处理器,它起初主要聚焦于加速图形渲染,让计算机能够快速、流畅地显示高质量的图像、视频以及 3D 场景等内容,在电脑游戏、影视特效制作、动画设计等领域有着至关重要的作用。 与传统的中央处理器(CPU)相比,GPU 有着数量众多的核…...
WPF InkCanvas 控件详解
1. InkCanvas 是什么? InkCanvas 是 WPF 提供的一个手写绘图控件,它允许用户使用鼠标、触摸屏或手写笔在界面上进行绘图、标注等操作。 核心特点: ✅ 具备笔迹存储和管理功能。 ✅ 提供 Children 和 Strokes 两个集合,分别用于管理子控件和绘制的笔迹。 ✅ 通过 EditingM…...
数据库三级选择题(2)
C) 分布式数据库的事务管理包括恢复控制和并发控制,恢复控制一般采用的策略是基于两阶段提交协议 采用一定的计算方法定位数据的有 Ⅳ.散列(哈希)索引 下列提供逻辑独立性的是外模式/模式映像 UML所有活动有关判断的部分要用菱形表…...
ShapeCrawler:.NET开发者的PPTX操控魔法
引言 在当今的软件开发领域,随着数据可视化和信息展示需求的不断增长,处理 PPTX 文件的场景日益频繁。无论是自动化生成报告、批量制作演示文稿,还是对现有 PPT 进行内容更新与格式调整,开发者都需要高效的工具来完成这些任务。传…...
CAS(Compare And Swap)
CAS核心原理 操作流程 CAS 包含三个参数:内存值(V)、预期值(E)和新值(N)。执行步骤如下: 比较:检查当前内存值 V 是否等于预期值 E。 交换:如果相等&#…...
熔断降级(Sentinel解决)
问题概述 在微服务架构中一定要预防微服务雪崩问题,微服务雪崩问题就是指在微服务架构中,当一个服务出现故障时,由于服务之间的依赖关系,故障可能会传播到其他服务,从而导致了大规模的服务失败,系统无法正…...
Deepseek API+Python 测试用例一键生成与导出 V1.0.4 (接口文档生成接口测试用例保姆级教程)
接口文档生成接口测试用例保姆级教程 随着测试需求的复杂性增加,测试用例的设计和生成变得愈发重要。Deepseek API+Python 测试用例生成工具在 V1.0.4 中进行了全方位的优化和功能扩展,特别是对接口测试用例设计的支持和接口文档的智能解析处理。本文将详细介绍 V1.0.4 版本…...
git 基本操作命令
一、初始化本地git仓库 git init 二、将当前目录下所有文件加载到本地git仓库 git add .三、提交内容和备注 git commit -m 提交类容四、(复制仓库路径)然后提交到仓库 git remote add origin 提交的仓库路径五、提交到远程仓库,如果这里提交失败,在…...
学习本地部署DeepSeek的过程(基于LM Studio)
除了使用Ollama部署DeepSeek,还可以使用LM Studio部署DeepSeek,后者是一款允许用户在本地计算机上运行大型语言模型(LLMs)的桌面应用程序,旨在简化本地模型的使用,无需云端连接或复杂配置即可体验 AI 功能。…...
web爬虫笔记:js逆向案例十一 某数cookie(补环境流程)
web爬虫笔记:js逆向案例十一 某数cookie(补环境流程) 一、获取网页数据请求流程 二、目标网址、cookie生成(逐步分析) 1、目标网址:aHR0cHM6Ly9zdWdoLnN6dS5lZHUuY24vSHRtbC9OZXdzL0NvbHVtbnMvNy9JbmRleC5odG1s 2、快速定位入口方法 1、通过脚本监听、hook_cookie等操作可…...
游戏引擎学习第180天
我们将在某个时候替换C标准库函数 今天我们要进行的工作是替换C标准库函数,这是因为目前我们仍然在使用C语言开发,并且在某些情况下会调用C标准库函数,例如一些数学函数和字符串格式化函数,尤其是在调试系统中,我们使…...
测试用例生成平台通过大模型升级查询功能,生成智能测试用例
在测试工作中,查询功能是各类系统的核心模块,传统的测试用例编写往往耗时且重复。如何让老旧平台焕发新活力?本文将结合大模型技术,通过用户输入的字段信息,自动化生成高效、精准的测试用例。同时,我们还将…...
kafka零拷贝技术的底层实现
什么是 Sendfile? sendfile 是一种操作系统提供的系统调用(system call),用于在两个文件描述符(file descriptor)之间高效传输数据。它最初由 Linux 内核引入(从 2.1 版本开始)&…...
Win11+VS2022+CGAL5.6配置
1. CGAL库简介 CGAL(Computational Geometry Algorithms Library)是一个开源的计算几何算法库,主要用于处理几何问题和相关算法的实现。它提供了丰富的几何数据结构和高效算法,覆盖点、线、多边形、曲面等基本几何对象的表示与操…...
Linux编译器gcc/g++使用完全指南:从编译原理到动静态链接
一、gcc/g基础认知 在Linux开发环境中,gcc和g是我们最常用的编译器工具: gcc:GNU C Compiler,专门用于编译C语言程序g:GNU C Compiler,用于编译C程序(也可编译C语言) 📌…...
Vue3项目中的.vscode文件夹
.vscode 文件夹主要用于存放与 Visual Studio Code(VS Code)编辑器相关的项目配置文件,这些文件能让项目在 VS Code 里的开发体验更加个性化和高效。 extensions.json 在 .vscode 文件夹中,extensions.json 文件的作用是列出项目…...
蓝桥杯嵌入式十六届模拟三
由硬件框图可以知道我们要配置LED 和按键 一.LED 先配置LED的八个引脚为GPIO_OutPut,锁存器PD2也是,然后都设置为起始高电平,生成代码时还要去解决引脚冲突问题 二.按键 按键配置,由原理图按键所对引脚要GPIO_Input 生成代码,在文件夹中添加code文件夹,code中添加fun.…...
造成服务器网络连接不稳定的原因是什么?
服务器的稳定性会影响到网络的响应速度和用户的体验感,当服务器网络连接不稳定时,会到时用户在浏览网站的过程中出现页面卡顿或页面消失等情况,给企业造成一定的经济损失,本文就来介绍一下造成服务器网络连接不稳定的因素都有哪些…...
[FPGA基础学习]加法器、三八译码器及DE2-115基本使用方法和数码管显示
软件安装:QuartusLite安装说明及驱动更新 DE2-115上电及程序烧录 1.用包装盒里的USB 电缆将PC的USB端口和DE2-115开发板的USB Blaster连接器连接 起来,为了实现主机和开发板之间的通讯,必须安装USB Blaster 驱动软件 鼠标右击“USB-Blaster…...
VSCode 市场发现恶意扩展正在传播勒索软件!
在VSCode 市场中发现了两个隐藏着勒索软件的恶意扩展。其中一个于去年 10 月出现在微软商店,但很长时间没有引起注意。 这些是扩展ahban.shiba 和 ahban.cychelloworld,目前已从商店中删除。 此外,ahban.cychelloworld 扩展于 2024 年 10 月…...
树状数组 3 :区间修改,区间查询
【题目描述】 这是一道模板题。 给定数列 a[1],a[2],…,a[n],你需要依次进行q个操作,操作有两类: 1lrx:给定 l,r,x对于所有 i∈[l,r],将a[i]加上x(换言之,将 a[l],a[l1],…a[r] 分别加上 x&a…...
C++的IO流
1. C语言的输入与输出 C语言中我们用到的最频繁的输入输出方式就是scanf ()与printf()。 scanf(): 从标准输入设备(键盘)读取数据,并将值存放在变量中。printf(): 将指定的文字/字符串输出到标准输出设备(屏幕)。 注意宽度输出和精度输出控制。C语言借助了相应的缓…...
QLoRA和LoRA 微调
QLoRA 其实是一种结合了量化和 LoRA 微调技术的统一方法,而不是同时使用两种不同的微调方式。换句话说,QLoRA 的意思就是:先把大模型的主权重用低精度(例如 4-bit)量化,从而大幅减少存储需求;然…...
Android电话监听器的设计与实现:深入解析Service与TelephonyManager
目录 一、引言 二、Service核心机制解析 1. Service的本质特性 2. 生命周期管理 3. 服务类型全景 三、Service实战开发 1. 启动式Service开发(lesson1) 2. 绑定式Service开发 四、电话监听器完整实现(lesson3) 1. 系统架…...
java学习笔记7——面向对象
关键字:static 类变量 静态变量的内存解析: 相关代码: public class ChineseTest {public static void main(String[] args) {System.out.println(Chinese.nation); //null 没赋值前System.out.println(Chinese.nation); //中国 静态变量赋值…...
java学习——函数式编程(1)
函数式编程 Java 的函数式编程是一种以函数为核心构建逻辑的编程范式,强调不可变性、声明式代码和无副作用的操作。它通过Lambda表达式、函数式接口(如Function、Predicate、Consumer等)和Stream API等特性实现,将计算过程抽象为函数的组合与转换,而非传统的命令式步骤。…...
java 批量下载doc\excle\pdf
指定图片集合 下载到指定文件夹 import java.io.*; import java.net.HttpURLConnection; import java.net.URL; import java.util.Arrays; import java.util.List;public class OfficeFileDownloader {/*** 需要下载的Office文档URL列表*/private static final List<Strin…...
Python爬虫:Feapder 的详细使用和案例
更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 1. Feapder 概述1.1 Feapder介绍1.2 Feapder 核心特点1.3 Feapder 主要组件1.4 Feapder的安装2. 基础爬虫编写2.1 创建爬虫2.2 运行爬虫3. 数据采集案例3.1 新闻网站采集3.2 电商商品采集3.3 使用 Spider 类创建更强大爬…...
【江协科技STM32】读写备份寄存器RTC实时时钟(学习笔记)
参考相关文章理解: 【江协科技STM32】Unix时间戳(学习笔记)-CSDN博客 【江协科技STM32】BKP备寄存器&RTC实时时钟(学习笔记)_stm32断电保存时钟-CSDN博客 读写备份寄存器 接线图:VBAT是从STLINK的…...
Linux touch命令
参考资料 Linux 常用命令 - touch 【创建空文件与修改时间戳】 目录 一. 用法简介二. 配合扩展字符,批量创建文件三. 修改文件的时间戳3.1 -t 配置项3.2 -d 配置项3.3 配合find命令实现批量时间戳修改 四. 结合 find 批量创建相同时间的新文件 一. 用法简介 ⏹当指…...
PyTorch图像预处理--Compose
torchvision.transforms.Compose 是 PyTorch 中用于图像预处理的核心工具,可将多个图像变换操作组合成一个顺序执行的流水线。 1. 定义与作用 功能:将多个图像处理步骤(如缩放、裁剪、归一化等)串联为一个整体ÿ…...
CSP历年题解
CSP历年题解 csp历年题解,csp.cpp内容涵盖从2023年12月开始一直持续到第一次认证的所有前4题。所有的题解均为满分,在其中,有四道题非本人编写,而从网上搜集优质解答,并且已在文中附上了来源链接。其余则为自己编写&a…...
《索引江湖:B树索引与哈希索引的风云对决》
在数据库的神秘世界里,索引宛如一把把神奇的钥匙,帮助我们在海量数据中快速找到所需信息。而B树索引与哈希索引,则是其中两把最为耀眼的利刃,各自凭借独特的“武功秘籍”,在不同的应用场景中大放异彩。今天,…...
java八股文之JVM
1.什么是程序计数器 程序计数器是 JVM 管理线程执行的“定位器”,记录每个线程当前执行的指令位置,确保程序流程的连续性和线程切换的准确性。线程私有的,每个线程一份,内部保存的字节码的行号。用于记录正在执行的字节码指令的地…...
学习爬虫的第二天——分页爬取并存入表中
阅读提示:我现在还在尝试爬静态页面 一、分页爬取模式 以豆瓣Top250为例: 基础url:豆瓣电影 Top 250https://movie.douban.com/top250 分页参数:?start0(第一页)、?start25(第二页)等 每页显示25条数…...
Ubuntu与Windows之间相互复制粘贴的方法
一、打开Ubuntu终端 二、卸载已有的工具 sudo apt-get autoremove open-vm-tools 三、安装工具 sudo apt-get install open-vm-tools-desktop 四、重启 直接输入reboot 注:有任何问题欢迎评论区交流讨论或者私信!...
docker安装hyperf环境,连接本机redis问题处理
错误信息显示“Connection refused”,这通常说明 Docker 容器内的 Hyperf 项目无法连接到你本机的 Redis 服务。 1. 容器内的 127.0.0.1 指向问题 在 Docker 容器中,127.0.0.1 指的是容器本身,而不是宿主机(你的 Mac)…...
第12章:优化并发_《C++性能优化指南》notes
优化并发 一、并发基础与优化核心知识点二、关键代码示例与测试三、关键优化策略总结四、性能测试方法论多选题设计题答案与详解多选题答案: 设计题答案示例 一、并发基础与优化核心知识点 线程 vs 异步任务 核心区别:std::thread直接管理线程…...
Linux操作系统7- 线程同步与互斥7(RingQueue环形队列生产者消费者模型改进)
上篇文章:Linux操作系统7- 线程同步与互斥6(POSIX信号量与环形队列生产者消费者模型)-CSDN博客 本篇代码仓库:myLerningCode/l36 橘子真甜/Linux操作系统与网络编程学习 - 码云 - 开源中国 (gitee.com) 目录 一. 单生产单消费单保…...