【橘子大模型】Runnable和Chain以及串行和并行
一、Runnable
前面我们实现了一些关于如何和大模型进行交互的操作。那么我们此时来回顾一下我们当前进行的结构。
我们已经很清楚这些操作的具体含义了,所以我这里就不在多介绍了。我们来看其中的几个点
1、用户那边就是客户,没啥说的。
2、langchain,这个是中间的框架。
3、template,关键就在这里,我们大部分业务编码其实都在这里到目前为止。
我们使用各种template来处理一些业务。
promptTemplate = ChatPromptTemplate([("system", "假如你是一个研究{cityMajor}的专家。"),("human", "介绍一下当前的经济环境。"),
])prompt = promptTemplate.invoke({"cityMajor": "山西经济"})
content = llm.invoke(prompt).content
print(f"大模型回答的结果正文是{content}")
我们构建起来一个模板之后,关键的一步就是执行invoke操作,包括llm也是执行invoke操作。而且除了invoke我们还可以执行stream,batch等操作。
我们先来看一下模板的文档,我们随便找一个,比如说BasePromptTemplate,他作为基类,文档比较全,下面那些子类忽略了一些文档,可能是他们不想重复写吧。
我们看到他说模板实现了标准的Runnable接口,该接口具有一系列方法,我们来看一下这个Runnable接口。
许多组件基本都基于这个抽象,我们来看一下这个模板类的文档
class BasePromptTemplate(RunnableSerializable[dict, PromptValue], Generic[FormatOutputType], ABC
):
我们看到他是实现了RunnableSerializable这个接口的。而RunnableSerializable的文档如下介绍。
RunnableSerializable implements the standard Runnable Interface. 🏃
他是实现了标准的Runnable接口的,所以这些组件实现了RunnableSerializable基本就是实现了Runnable接口
而Runnable接口是有这些方法的,所以其实我们可以大胆的下一个结论,你能看到的能调这几个方法的基本都是Runnable的实现类。
所以我们再来看我们的代码:
llm = ChatOllama(base_url = "http://127.0.0.1:11434",model = "deepseek-r1:8b",temperature = 0.5,num_predict = -2,max_tokens = 250
)promptTemplate = ChatPromptTemplate([("system", "假如你是一个研究{cityMajor}的专家。"),("human", "介绍一下当前的经济环境。"),
])prompt = promptTemplate.invoke({"cityMajor": "山西经济"})
content = llm.invoke(prompt).content
print(f"大模型回答的结果正文是{content}")
这里面promptTemplate.invoke, llm.invoke 其实promptTemplate和llm都是Runnable了。你去看他的类就知道,他们都是实现了RunnableSerializable的。所以我们的结构图中这部分就是Runnable。
ok,我们到这里为止,引入了一个概念叫做Runnable。那我们接下来看看这个Runnable
Runnable概念官方文档位于Runnable
我就不一个字一个字的去翻译这个文档了,这是翻译工具的活。我挑其中一段来说一下。
Runnable 方式定义了一个标准接口,允许 Runnable 组件:Invoked,Batched,Streamed等等操作。这些我们也都说过了。
但是他还有一个比较不错的功能,就是组合。
组合:可以使用 LangChain 表达式语言 (LCEL) 组合多个 Runnable 以协同工作,以创建复杂的管道。
这就是我们今天要说的第二个概念,LCEL组合Runnable
1、LCEL组合Runnable
他的功能很强大,而且非常多,具体可以去看文档。我们这里来做个分析操作来改造一下我们前面的代码。
我们说每一个组件现在都可以被我们认为成一个Runnable。其实就是一个任务,作为javaer可以理解为一个方法。
作为方法,必然就有输入(构建参数),输出(返回值)。那么我们多个Runnable也就是多个方法的时候,方法1的输出就可以作为方法2的输入。这种就可以形成一个链路。而LCEL就是做这个的,他可以整合我们的Runnable形成一个链路,然后顺着链路去调用。
我们先看一个没有LCEL的我们咋做的。
1.1常规做法
from langchain_core.prompts import ChatPromptTemplatepromptTemplate = ChatPromptTemplate([("system", "假如你是一个研究{cityMajor}的专家。"),("human", "介绍一下当前的经济环境。"),
])prompt = promptTemplate.invoke({"cityMajor": "山西经济"})
content = llm.invoke(prompt).content
print(f"大模型回答的结果正文是{content}")
常规做法我们是以前写烂了。那我们再来看看使用LCEL咋做。
1.2、LCEL
from langchain_core.prompts import ChatPromptTemplate
# llm是Runnable1# promptTemplate 是Runnable2
promptTemplate = ChatPromptTemplate([("system", "假如你是一个研究{cityMajor}的专家。"),("human", "介绍一下当前的经济环境。"),
])# LCEL使用管道符号串联两个Runnable
chain = promptTemplate | llm
content = chain.invoke({"cityMajor":"山西经济"})
print(f"大模型回答的结果正文是{content}")
我们看到我们用LCEL使用管道符号串联两个Runnable也就是promptTemplate | llm
这个操作其实就是等于promptTemplate执行的结果传递给llm执行,也就是我们之前的。
prompt = promptTemplate.invoke({"cityMajor": "山西经济"})
content = llm.invoke(prompt)
我想你大概知道这个操作的含义了,下面我们再串联一个组件进去玩一玩。
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import JsonOutputParser
from pydantic import BaseModel, Field, model_validator
from typing import List# 构建一个类,表示单个观点结构
class Opinion(BaseModel):num: str = Field(description="观点的标号")opinion: str = Field(description="回答的观点")# 构建一个集合类,表示多个观点结构
class OpinionsList(BaseModel):opinions: List[Opinion] = Field(description="包含多个观点的列表")# Runnable1
promptTemplate = ChatPromptTemplate([("system", "假如你是一个研究{cityMajor}的专家。"),("human", "介绍一下当前的经济环境,不要思考过程。请以JSON格式输出多条观点,注意一定是多条观点,而不是一个,格式如下:{{'opinions': [{{'num': '1', 'opinion': '观点1'}}, {{'num': '2', 'opinion': '观点2'}}]}}"),
])
# llm是Runnable2
# Runnable3
parser = JsonOutputParser(pydantic_object=OpinionsList)
# 串联起来,等于先运行一个promptTemplate得到prompt,然后输出给llm执行得到结果。把结果最后给JsonOutputParser按照结构解析成json输出
chain = promptTemplate | llm | parser
try:content = chain.invoke({"cityMajor": "山西经济"})print(f"大模型回答的结果正文是{content}")
except Exception as e:print(f"解析失败:{e}")
最后就得到的结果就是json结构的。
{'opinions': [{'num': '1', 'opinion': '山西近年来经济保持稳定增长,传统制造业和高新技术产业是主要驱动力。'}, {'num': '2', 'opinion': '山西吸引外资和优化营商环境取得进展,为企业发展提供了支持。'}, {'num': '3', 'opinion': '山西在纺织、食品加工等传统行业保持竞争力,同时高新技术产业快速崛起。'}, {'num': '4', 'opinion': '面对内地市场竞争和国际环境变化,山西需加强产品质量和创新能力。'}, {'num': '5', 'opinion': '山西应加强区域协作,与周边省份合作,以推动经济发展。'}]}
还有很多高级操作,可以按照文档来学习,后面我们争取多用用。
我们现在完成了多个Runnable的链路,得到的是一个我们称之为chain(链)的东西。我们看一下这个chain是啥类型。
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import JsonOutputParser
from pydantic import BaseModel, Field, model_validator
from typing import List# 单个观点结构
class Opinion(BaseModel):num: str = Field(description="观点的标号")opinion: str = Field(description="回答的观点")# 多个观点结构
class OpinionsList(BaseModel):opinions: List[Opinion] = Field(description="包含多个观点的列表")promptTemplate = ChatPromptTemplate([("system", "假如你是一个研究{cityMajor}的专家。"),("human", "介绍一下当前的经济环境,不要思考过程。请以JSON格式输出多条观点,注意一定是多条观点,而不是一个,格式如下:{{'opinions': [{{'num': '1', 'opinion': '观点1'}}, {{'num': '2', 'opinion': '观点2'}}]}}"),
])parser = JsonOutputParser(pydantic_object=OpinionsList)chain = promptTemplate | llm | parser
# python中可以用type函数来输出类型
type(chain)
结果为langchain_core.runnables.base.RunnableSequence
他的构造函数为:
class RunnableSequence(RunnableSerializable[Input, Output]):
我们看到他也实现了RunnableSerializable,所以多个Runnable链路运行的结果其实还是一个Runnable。那么既然是一个Runnable,是不是我们还可以继续组合。我们可以把一个chain当成一个完整的Runnable继续串。
也就是这样的结构:
我们的两个chain甚至可以是完全不一样的,背后的大模型都可以不一样,这样就可以任意组合了。比如有些模型比较擅长推理,有些适合做文字生成。那我们就可以让文字生成的生成一个好的描述,交给推理的模型。最后给我们一个好的结果。good。
why not,接下来我们就来看如何操作chain的组合。
2、LCEL组合chain
我们来构建一个需求:
1、我们需要两个chain
2、第一个分析山西经济学家视角下的经济环境,得到经济环境的描述。
3、第二个chain,拿到山西经济环境学家的分析结果,把结果中每一点的标题提取出来。这样就结束。
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser
from pydantic import BaseModel, Field, model_validator
from typing import List# 1、构建第一个chain的模板,根据这个模板让大模型为我们输出一个他作为cityMajor的专家的一个当前经济环境的结果。
getRespPromptTemplate = ChatPromptTemplate([("system", "假如你是一个研究{cityMajor}的专家。"),("human", "介绍一下当前的经济环境,不要思考过程。"),
])# 2、构建第一个chain,先获取模板,发给llm,最后结果通过一个字符串的parser解析输出为字符串
getRespChain = getRespPromptTemplate | llm | StrOutputParser()# 3、构建第二个chain的模板,这个模板有一个参数,就是上一个chain的输出作为输入,分析其中的内容,我们只要结果的标题小点的总结
getHeadingPromptTemplate = ChatPromptTemplate.from_template("""分析{resp},并且仅仅获取其中的每一点的标题,注意只获取每一点的标题,不要后面的描述,我只要标题点,并且不要思考过程""")
"""
4、构建第二个chain,第二个chain首先我们要把第一个chain的结果当成第一步传递给getHeadingPromptTemplate
因为getHeadingPromptTemplate需要第一个的结果去填充{resp},所以我们构建一个{}的map结构,得到第一个chain的输出给getHeadingPromptTemplate
getHeadingPromptTemplate填充完了发给llm
最后以字符串输出解析器解析为字符串。
"""
getHeadingChain = {"resp":getRespChain} | getHeadingPromptTemplate | llm | StrOutputParser()# 执行最后的chain,然后把第一个chain的参数可以传进去,此时他们是一个chain了,可以这么传
resp = getHeadingChain.invoke({"cityMajor":"山西经济"} )
print(resp)
输出结果如下:
1. 山西经济环境呈现多元化发展态势
2. 产业结构不断优化,制造业、科技服务业和绿色经济成为主要驱动力
3. 新兴产业如电子信息、生物医药等快速发展
4. 传统优势产业在升级改造后依然占据重要地位
5. 政策支持力度大,吸引了大量外资和内资
6. 基础设施建设不断完善,为经济发展提供了坚实支撑
7. 面临国内市场机遇与国际环境挑战,山西正积极推进数字经济和绿色低碳发展
8. 展现出较强的经济韧性和活力
我在这个代码中踩了一个坑,如下记录:
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser
from pydantic import BaseModel, Field, model_validator
from typing import ListgetRespPromptTemplate = ChatPromptTemplate([("system", "假如你是一个研究{cityMajor}的专家。"),("human", "介绍一下当前的经济环境,不要思考过程。"),
])
getRespChain = {"cityMajor":"山西经济"} | getRespPromptTemplate | llm | StrOutputParser()
getHeadingPromptTemplate = ChatPromptTemplate.from_template("""分析{resp},并且仅仅获取其中的每一点的总结的标题,注意只获取每一点的总结的标题,并且不要思考过程""")
getHeadingChain = {"resp":getRespChain} | getHeadingPromptTemplate | llm | StrOutputParser()
resp = getHeadingChain.invoke()
print(resp)
其实改动也不大,我只是在第一个chain的最前面模仿第二个chain把参数放前面了,这样是不对的,你要严格遵守一个原则,就是这种链路的每一个元素都是一个Runnable才行。getHeadingChain = {“resp”:getRespChain} | getHeadingPromptTemplate | llm | StrOutputParser()之所以可以是因为第一个{“resp”:getRespChain} 他是一个runnable结果,因为有getRespChain的存在。
而我把{“cityMajor”:“山西经济”}放前面这个只是一个map结构,啥也不是,所以不对。
ok,至此我们就完成了chain的串联。接下来我们再来看看如何让他们并行联动。
3、RunnableParallel
我们有时候有一些需求是需要同时执行然后一起返回的。这时候需要我们并行来运行多个Runnable或者Chain。这样可以提高效率。
但是注意这种需求不要运行那种有依赖的Chain,这样虽然是并行的操作,但是因为依赖,还是会先执行一个再根据输出执行另一个。其实还是串行执行。
我们这里来搞一个需求。
我们的ollama中有两个大模型,一个是deepseek-r1:8b,一个llama3.2:latest。我们构造两个chain,然后同时各自发去一个模型中,并行执行最后输出结果。
这个就需要用到RunnableParallel
此时我们需要构建两个llm,我们就使用另一个模型llama3.2:latest。而且ollama其实不用run模型,直接就能调。
from langchain_ollama import ChatOllamallm = ChatOllama(base_url = "http://127.0.0.1:11434",model = "deepseek-r1:8b",temperature = 0.5,num_predict = 10000,max_tokens = 250
)llmllama32 = ChatOllama(base_url = "http://127.0.0.1:11434",model = "llama3.2:latest",temperature = 0.5,num_predict = 10000,max_tokens = 250
)
然后我们来编写并行调用llm的操作。
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser
from langchain_core.runnables import RunnableParallel# 1、构建第一个chain的模板,去调用deepseek模型
dsPromptTemplate = ChatPromptTemplate([("system", "假如你是一个研究{dsCityMajor}的专家。"),("human", "介绍一下当前的经济环境,不要思考过程。"),
])# 2、构建第一个chain,先获取模板,发给deepseek llm,最后结果通过一个字符串的parser解析输出为字符串
dsRespChain = dsPromptTemplate | llm | StrOutputParser()# 3、构建第二个chain的模板,去调用llama模型
llamaPromptTemplate = ChatPromptTemplate([("system", "假如你是一个研究{llamaCityMajor}的专家。"),("human", "介绍一下当前的经济环境,不要思考过程。"),
])# 4、构建第二个chain,先获取模板,发给llama llm,最后结果通过一个字符串的parser解析输出为字符串
llamaRespChain = llamaPromptTemplate | llmllama32 | StrOutputParser()# 5、构建并行执行的Runnable 并行运行两个没有依赖关系的chain
parallelRunnable = RunnableParallel(dsChain=dsRespChain, llamaChain=llamaRespChain)# 6、执行Runnable
resp = parallelRunnable.invoke({"dsCityMajor" : "山西经济","llamaCityMajor" : "北京经济"})
print("deepseek:")
print(resp['dsChain'])print("llama:")
print(resp['llamaChain'])
输出结果如下:
deepseek:
当前,山西省经济正处于转型升级阶段,面临着传统产业转型与新兴产业发展双重任务。山西作为内陆开放枢纽,通过“双循环”新发展格局,推动区域经济一体化,在高科技、数字经济、新能源等领域取得了一定进展。同时,绿色低碳发展成为新时代的重要方向,山西省在可再生能源和环保治理方面也在积极作为。此外,山西还通过优化营商环境,加强基础设施建设,促进就业市场向高质量发展转型,为经济高质量发展奠定了坚实基础。llama:
另一方面,北京面临着一些挑战。例如,人口流动和城市化问题,导致了交通拥挤、住房短缺等问题。同时,环境保护和空气污染问题也在获得关注。
总体而言,北京的经济环境虽然有其挑战,但仍处于相对稳定的状态下,并且具有很大的发展潜力。
我们先不管输出质量,输出结构是符合我们预期的。此时我们再去langsmith中看一下。我们发现并行的已经监控到了。
我们看一下详细信息。基本是和我们的预期一样的。说明我们的并行请求成功被执行了。
ok,至此我们的串行和并行就都完成了。
相关文章:
【橘子大模型】Runnable和Chain以及串行和并行
一、Runnable 前面我们实现了一些关于如何和大模型进行交互的操作。那么我们此时来回顾一下我们当前进行的结构。 我们已经很清楚这些操作的具体含义了,所以我这里就不在多介绍了。我们来看其中的几个点 1、用户那边就是客户,没啥说的。 2、langchain&…...
数据结构 -- 图的存储
图的存储 邻接矩阵法 邻接矩阵存储不带权图 0 - 表示两个顶点不邻接 1 - 表示两个顶点邻接 在无向图中,每条边在矩阵中对应两个1 在有向图中,每条边在矩阵中对应一个1 //不带权图的邻接矩阵存储 #define MaxVertexNum 100 //顶点数目的最大值 typed…...
基于大模型预测不稳定性心绞痛的多维度研究与应用
目录 一、引言 1.1 研究背景与意义 1.2 研究目的 1.3 国内外研究现状 二、不稳定性心绞痛概述 2.1 定义与分类 2.2 发病机制 2.3 临床表现 三、大模型技术原理与应用基础 3.1 大模型介绍 3.2 在医疗领域的应用现状 3.3 用于不稳定性心绞痛预测的可行性 四、术前预…...
【Java集合】LinkedList源码深度分析
参考笔记:java LinkedList 源码分析(通俗易懂)_linkedlist源码分析-CSDN博客 目录 1.前言 2.LinkedList简介 3.LinkedList的底层实现 4.LinkedList 与 ArrayList 的对比 4.1 如何选择 4.2 对比图 5.LinkedList 源码Debug 5.1 add(E e) ÿ…...
Java 大视界 -- Java 大数据在智能供应链库存优化与成本控制中的应用策略(172)
💖亲爱的朋友们,热烈欢迎来到 青云交的博客!能与诸位在此相逢,我倍感荣幸。在这飞速更迭的时代,我们都渴望一方心灵净土,而 我的博客 正是这样温暖的所在。这里为你呈上趣味与实用兼具的知识,也…...
高并发系统架构设计核心要点的结构化提炼【大模型总结】
以下是对高并发系统架构设计核心要点的结构化提炼,结合技术深度与实践视角,以清晰的层次呈现关键策略与实现路径: 一、核心理念重塑 1. 容错优先思维 设计哲学:从"零故障"转向"可恢复性"设计,接…...
【C#深度学习之路】如何使用C#实现Stable Diffusion的文生图功能
【C#深度学习之路】如何使用C#实现Stable Diffusion的文生图功能 项目背景项目实现写在最后项目下载链接 本文为原创文章,若需要转载,请注明出处。 原文地址:https://blog.csdn.net/qq_30270773/article/details/147002073 项目对应的Github地…...
k8s的pod的概述和配置
概念 Pod 容器组 是一个k8s中一个抽象的概念,用于存放一组 container(可包含一个或多个 container 容器,即图上正方体),以及这些 container (容器)的一些共享资源。这些资源包括: 共享存储&…...
RTOS任务句柄的作用
任务句柄(Task Handle)在 FreeRTOS 中的作用详解 任务句柄(TaskHandle_t)是 FreeRTOS 中用于 唯一标识和管理任务 的核心机制,本质是一个指向任务控制块(TCB)的指针。说明即便创建的任务名相同,但对应的任务句柄一定是不同。 它在任务管理、通信、调试中起到关键作用,…...
OpenVLA-OFT——微调VLA的三大关键设计:并行解码、动作分块、连续动作表示以及L1回归目标
前言 25年3.26日,这是一个值得纪念的日子,这一天,我司「七月在线」的定位正式升级为了:具身智能的场景落地与定制开发商 ,后续则从定制开发 逐步过渡到 标准产品化 比如25年q2起,在定制开发之外࿰…...
LocaDate、LocalTime、LocalDateTime
Java8的时间处理 Java的时间处理在早期版本中存在诸多问题(如 java.util.Date 和 java.util.Calendar 的混乱设计),但Java8引入了引入了全新的 java.time包(基于JSR 310),提供了更清晰、线程安全且强大的时…...
哈密尔顿路径(Hamiltonian Path)及相关算法题目
哈密尔顿路径要求访问图中每个顶点恰好一次,通常用于解决旅行商问题(TSP)或状态压缩DP问题。 哈密尔顿路径(Hamiltonian Path)是指在一个图中经过每个顶点恰好一次的路径。如果这条路径的起点和终点相同(即…...
突破传统限制!全新端到端开放词汇多目标跟踪框架OVTR,开启视觉追踪新纪元
在自动驾驶和智能监控等场景中,多目标跟踪(MOT)技术需要应对现实世界中层出不穷的新物体类别。传统方法依赖预定义类别,面对“无人机配件”“新型宠物”等未知目标时往往失效。上海人工智能实验室团队提出的OVTR(Open-…...
Springboot + Vue + WebSocket + Notification实现消息推送功能
实现功能 基于Springboot与Vue架构,首先使用Websocket实现频道订阅,在实现点对点与群发功能后,在前端调用windows自带的消息通知,实现推送功能。 开发环境 Springboot 2.6.7vue 2.6.11socket-client 1.0.0 准备工作 在 Vue.js…...
Linux内核物理内存组织结构
一、系统调用sys_mmap 系统调用mmap用来创建内存映射,把创建内存映射主要的工作委托给do_mmap函数,内核源码文件处理:mm/mmap.c 二、系统调用sys_munmap 1、vma find_vma (mm, start); // 根据起始地址找到要删除的第一个虚拟内存区域 vma 2…...
Redis高级技能进阶
什么是事务的ACID 事务是由一系列对系统中数据进行访问或更新的操作组成的程序执行逻辑单元。这些操作要么都执行,要么都不执行。 为了保证数据库的一致性,在事务处理之前和之后,都应该遵循某些规则,也就是大家耳熟能详的ACID。 …...
PCB设计基础:面向嵌入式工程师的系统性指南
嵌入式系统的性能、稳定性和可靠性,很大程度上依赖于电路硬件的设计质量。在硬件设计中,PCB(Printed Circuit Board)设计是连接系统功能与实际运行的关键一环。本文将从嵌入式工程师的视角,系统性地介绍PCB设计的关键基…...
aspark 配置2
编写Hadoop集群启停脚本 1.建立新文件,编写脚本程序 在hadoop101中操作,在/root/bin下新建文件:myhadoop,输入如下内容: 2.分发执行权限 保存后退出,然后赋予脚本执行权限 [roothadoop101 ~]$ chmod x /r…...
【统计方法】LASSO筛变量
启 比较原始做LASSO包是library(glmnet) 若目标是纯 LASSO 分析,alpha 必须设为 1 标准化数据:LASSO 对特征的尺度敏感,需对数据进行标准化(均值为0,方差为1)。 cv.glmnet获得的lambda.m…...
拥抱健康生活,书写养生新篇
在快节奏的现代生活中,健康愈发成为人们关注的焦点。践行健康养生,并非是一种选择,而是我们对自己和家人应尽的责任。掌握正确的养生之道,不仅能提升生活品质,更能让生命焕发出新的活力。 合理饮食是健康的基石。一…...
Shiro学习(五):Shiro对权限的缓存
一、问题描述 由前边的学习中了解,用户的角色权限一般存储在数据库中,每次进行权限校验时都要从 数据库查询用户的角色权限信息;对数据库来说这样频繁的查询压力太大了,也影响程序的 性能。 Shiro 中执行权限角色校验时࿰…...
QGIS实战系列(六):进阶应用篇——Python 脚本自动化与三维可视化
欢迎来到“QGIS实战系列”的第六期!在前几期中,我们从基础操作到插件应用逐步提升了 QGIS 技能。这一篇,我们将迈入进阶领域,探索如何用 Python 脚本实现自动化,以及如何创建三维可视化效果,让你的 GIS 项目更高效、更立体。 第一步:Python 脚本自动化 QGIS 内置了 Py…...
redis-cpp-cpp如何使用lua脚本
1.前言 我今天要在项目中使用lua脚本,结果搞半天都没有弄明白这个函数怎么调用,而且也似乎很少有redis相关的博客介绍,ai也回答的不准确! 2.正文 今天用一个例子演示一下 下面是lua脚本 const std::string LuaScript R"…...
C# Winform 入门(6)之不同类之间的值传递
承接上一个教程,利用委托事件来进行值传递 声明变量 public static double plx, ply,plxx,plyy;声明委托、事件 //声明委托 //事件 public delegate void transferDistance(double dis); public static transferDistance doTransfer; 直接读取form1中的变量 publ…...
JWT 秘钥的作用机制
JWT 秘钥的作用并不是给前端使用的,而是用于后端服务器内部的一个重要安全机制。 JWT 秘钥的作用 签名与验证: 秘钥主要用于对 JWT(JSON Web Token)进行签名和验证后端使用这个秘钥对令牌进行签名,确保令牌的完整性…...
sun.misc.BASE64Encoder 和 sun.misc.BASE64Decoder包
1. 在将别人的项目导入eclipse之后,出现了"sun.misc.BASE64Encoder找不到jar"的错误,我解决的办法是:右键项目》属性》Java Build Path》jre System Library 》access rules 》resolution选择accessible,下面填上**点击确定即可࿰…...
Java面试黄金宝典34
1. 主键索引底层的实现原理 定义 主键索引是数据库中用于唯一标识表中每一行记录的索引,常见的底层实现是 B 树结构。B 树是一种平衡的多路搜索树,由内部节点和叶子节点组成。内部节点只存储索引键和指向下一层节点的指针,不存储实际数据&am…...
计算机系统---CPU
定义与功能 中央处理器(Central Processing Unit,CPU),是电子计算机的主要设备之一,是计算机的核心部件。CPU是计算机的运算核心和控制核心,负责执行计算机程序中的指令,进行算术运算、逻辑运算…...
AWS云安全基线:构建企业级安全防护体系的完整指南
1. 引言 随着越来越多的企业将其业务和数据迁移到云端,云安全已成为一个不容忽视的关键议题。AWS作为全球领先的云服务提供商,提供了丰富的安全工具和最佳实践。本文将深入探讨如何构建一个全面的AWS云安全基线,以确保您的企业在云环境中的安全性。 2. AWS共享责任模型 在深…...
(三十三)Dart 中使用 Pub 包管理系统与 HTTP 请求教程
Dart 中使用 Pub 包管理系统与 HTTP 请求教程 Pub 包管理系统简介 Pub 是 Dart 和 Flutter 的包管理系统,用于管理项目的依赖。通过 Pub,开发者可以轻松地添加、更新和管理第三方库。 使用 Pub 包管理系统 1. 找到需要的库 访问以下网址,…...
如何实现单例模式?
一、模式定义与核心价值 单例模式(Singleton Pattern)是一种创建型设计模式,保证一个类仅有一个实例,并提供全局访问点。其核心价值在于: 资源控制:避免重复创建消耗性资源(如数据库连…...
【51单片机】2-4【I/O口】震动传感器控制继电器
1.硬件 51最小系统继电器模块震动传感器模块 2.软件 #include "reg52.h"sbit vibrate P3^3;//震动传感器DO接到P3.3口 sbit switcher P1^1;//继电器控制端IN接到P1.1void Delay2000ms() //11.0592MHz {unsigned char i, j, k;// _nop_();i 15;j 2;k 235;do{…...
正点原子 迷你 miniSTM32用ST link烧录后程序不运行(已解决)
情况,在程序和配置都没有问题时检查 烧录使用ST linkv2 烧录后有时程序可行,有时不可行 解决方法 加USB供电配合SW烧录 建议直接用USB转串口烧录 不推荐JLINK供电,也不推荐ST linkv2供电...
如何确保MQ消息队列不丢失:Java实现与流程分析
前言 在分布式系统中,消息队列(Message Queue, MQ)是核心组件之一,用于解耦系统、异步处理和削峰填谷。然而,消息的可靠性传递是使用MQ时需要重点考虑的问题。如果消息在传输过程中丢失,可能会导致数据不一…...
Pascal语言的系统监控
Pascal语言的系统监控 引言 在现代计算机系统中,系统监控是确保计算机平稳运行的重要组成部分。无论是个人计算机还是大型服务器,监控系统的性能、资源使用及状态,都是提高系统效率、及时发现问题的关键。Pascal语言作为一种结构化编程语言…...
6.0 使用Qt+ OpenCV+Python加载图片
本例作为python图像处理的入门课程1,使用Qt+ OpenCV+Python加载图片。 主要有如下几个地方需要注意: 1. OpenCV 默认使用 BGR 格式,而 Qt 使用 RGB。显示前需要转换:cv2.cvtColor(img, cv2.COLOR_BGR2RGB),一般使用某个QLabel控件进行显示。 pic = cv2.cvtColor(pic, cv2.C…...
低成本训练垂直领域文娱大模型的技术路径
标题:低成本训练垂直领域文娱大模型的技术路径 内容:1.摘要 在文娱产业快速发展且对智能化需求日益增长的背景下,为降低垂直领域文娱大模型的训练成本,本研究旨在探索低成本训练的有效技术路径。采用对现有开源模型进行微调、利用轻量化模型架构以及优化…...
音视频入门基础:RTP专题(21)——使用Wireshark分析海康网络摄像机RTSP的RTP流
一、引言 使用vlc等播放器可以播放海康网络摄像机的RTSP流: 网络摄像机的RTSP流中,RTSP主要用于控制媒体流的传输,如播放、暂停、停止等操作。RTSP本身并不用于转送媒体流数据,而是会通过PLAY方法使用RTP来传输实际的音视频数据。…...
【Java网络编程详解】
文章目录 前言一、网络编程基础知识1. 什么是网络编程? 二、Java网络编程核心类三、TCP编程实现1. TCP通信原理2. TCP服务器端示例3. TCP客户端示例 四、UDP编程实现1. UDP通信原理2. UDP服务器端示例3. UDP客户端示例 五、使用HttpURLConnection发送HTTP请求1. GET…...
DuckDB系列教程:如何分析Parquet文件
Parquet 是一种强大的、基于列的存储格式,适用于实现更快捷和更高效的数据分析。您可以使用 DuckDB 这种内存型分析数据库来处理 Parquet 文件并运行查询以对其进行分析。 在这篇文章中,我们将逐步介绍如何使用 DuckDB 对存储在 Parquet 文件中的餐厅订单…...
uniapp的v-for不显示或者swiper-item的不显示
今天开发的时候碰见一个问题,在布局的时候发现v-for遍历的时候不显示内容 H5是正常的 但是在小程序就是不显示 最后排查的原因是同一个组件 swiper-item的 v-for不能用相同的名称 比如 <swiper-item v-for"i in 3" :key"i"><image …...
解决LeetCode“使括号有效的最少添加”问题
目录 问题描述 解题思路 复杂度分析 示例分析 暴力替换“不讲码德” 总结 问题描述 给定一个仅由 ( 和 ) 组成的字符串 s,我们需要通过添加最少数量的括号(( 或 ))使得字符串有效。有效字符串需满足: 空字符串是有效的。 …...
黑马点评_知识点
将手机验证码保存到HttpSession中进行验证(感觉已经过时) Controller中的参数有HttpSession,存验证码session.setAttribute(SystemConstants.VERIFY_CODE, code); 其他的都是逻辑代码 Cookie的缺点 什么是Session集群共享问题? …...
2025年渗透测试面试题总结-某腾讯-玄武实验室扩展(题目+回答)
网络安全领域各种资源,学习文档,以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具,欢迎关注。 目录 某腾讯-玄武实验室扩展 一、Web安全基础原理与关联漏洞 1.1 CSRF攻击原理深度解析 1.2 反序列化漏洞…...
管理系统 UI 设计:提升企业办公效率的关键
一、管理系统UI设计的基本原则 管理系统UI设计应遵循一系列基本原则,以确保界面友好、操作便捷、信息直观。这些原则包括: 简洁性:界面应去除冗余元素,保持简洁明了,避免用户迷失在复杂界面中。一致性:界…...
Apache Commons Lang3 中的 `isNotEmpty` 与 `isNotBlank`的区别
前言 在 Java 开发中,字符串的空值(null)、空字符串(“”)和空白字符串(如 " ")的判断是高频需求。Apache Commons Lang3 的 StringUtils 类提供了两个核心方法:isNotEmp…...
WPF 登录页面
效果 项目结构 LoginWindow.xaml <Window x:Class"PrismWpfApp.Views.LoginWindow"xmlns"http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x"http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d"http://schemas.…...
CExercise_05_1函数_2海伦公式求三角形面积
题目: 键盘录入三个边长(带小数),然后用海伦公式计算三角形的面积(如果它确实是一个三角形的话) 海伦公式求三角形面积: 要求基于下列两个函数完成这个编程题: // 判断abc是否可以组…...
Muduo网络库实现 [十五] - HttpContext模块
目录 设计思路 类的设计 解码过程 模块的实现 私有接口 请求函数 解析函数 公有接口 疑惑点 设计思路 记录每一次请求处理的进度,便于下一次处理。 上下文模块是Http协议模块中最重要的一个模块,他需要记录每一次请求处理的进度,需…...