J-LangChain - Agent - 编排一个 ReAct + Function Call 反应链
系列文章索引
J-LangChain 入门
介绍
j‑langchain 是一款基于 Java 的 AIGC 编排框架,致力于集成多种大模型(LLM)调用及 RAG 工具。自 1.0.8 版本起,我们引入了工具函数
(Function Call)调用能力,正式实现了 Tools
功能,并将其与 ReAct(Reasoning + Acting)
模式结合,从而构建出功能丰富、交互智能的 Agent
系统。
在本文中,我们将通过一个详实的实例,展示如何利用 Tools 功能编排一个具备 ReAct 反应链的 Agent。不仅能够体验 j‑langchain 的 Function Call 功能,还能深入了解大模型在 ReAct 反应链中如何一步步调用外部工具,实现复杂推理与动态响应。
示例场景
假设我们需要构建一个智能代理,能够回答类似于“上海的天气如何?”的等问题。为此,我们需要:
-
定义一个提示模板(Prompt Template),指导代理如何处理问题。
-
配置工具(Tools),例如获取天气和时间的函数。
-
实现一个带有工具调用的循环逻辑,确保代理能在必要时获取外部信息。
-
解析并返回最终答案。
以下是实现这一功能的完整代码解析。
代码解析
1. 定义提示模板
提示模板是代理的核心,它告诉模型如何思考和行动。我们使用 PromptTemplate 类定义了一个结构化的模板:
PromptTemplate prompt = PromptTemplate.fromTemplate("""Answer the following questions as best you can. You have access to the following tools:${tools}Use the following format:Question: the input question you must answerThought: Consider whether you already have enough information to answer the question. If so, proceed directly to the final answer.If additional information is needed, take the following steps:- Identify what specific information is missing.- Call the appropriate tool to obtain that information.- Analyze the new information and determine if the question can now be answered.When using tools, follow this structured approach:Action: the action to take, should be one of [${toolNames}]Action Input: the input to the actionObservation: the result of the action- You may use tools **up to 3 times**. If you still lack a complete answer after 3 attempts, summarize the best possible response.- If a tool's result is **irrelevant or does not improve understanding**, do not call the same tool again. Instead, attempt to derive an answer from available information.Thought: Based on the gathered information, determine if you can now provide a final answer. If yes, proceed to:Final Answer: the final answer to the original input question.If not, provide the best possible answer with a note on any remaining uncertainties.Begin!Question: ${input}Thought:""");
${tools}
和${toolNames}
是占位符,会在运行时被替换为实际的工具列表和工具名称。${input}
使用户提出的问题。- 模板中明确了代理的思考步骤:先判断是否需要更多信息,若需要则调用工具,最后给出答案。
2. 配置语言模型
我们使用 ChatOllama
作为语言模型,设置 temperature 为 0 以确保输出稳定:
ChatOllama llm = ChatOllama.builder().model("llama3:8b").temperature(0f).build();
当然你可以调试更聪明的模型,但此实例中 llama3:8b
已经可以达到效果。
3. 定义工具
工具是代理获取外部信息的关键。我们定义了两个简单工具:获取天气和获取时间:
Tool getWeather = Tool.builder().name("get_weather").params("location: String").description("Get city weather information and enter the city name").func(location -> String.format("The weather in %s is sunny with a temperature of 25°C", location)).build();Tool getTime = Tool.builder().name("get_time").params("city: String").description("Get city the current time and enter the city name").func(location -> String.format("%s The current time is 12:00 PM", location)).build();List<Tool> tools = List.of(getWeather, getTime);
prompt.withTools(tools);
Tool.builder()
提供了简洁的方式来定义工具的名称、参数、描述和执行逻辑。prompt.withTools(tools)
将工具注入提示模板。
4. 辅助节点
为了实现 ReAct
形式交互,我们需要设计一个循环,并实现一些节点处理中间结果,和循环的退出判断,辅助流程:
4.1 处理工具调用的中间结果
TranslateHandler<AIMessage, AIMessage> cut = new TranslateHandler<>(llmResult -> {if (llmResult == null || StringUtils.isEmpty(llmResult.getContent()) || !llmResult.getContent().contains("Observation:")) {return llmResult;}String prefix = llmResult.getContent().substring(0, llmResult.getContent().indexOf("Observation:"));llmResult.setContent(prefix);return llmResult;
});
cut
处理器截取模型输出中工具调用前的部分,确保后续逻辑只处理必要内容。
4.2 解析模型输出
TranslateHandler<Map<String, String>, AIMessage> trans = new TranslateHandler<>(llmResult -> PromptUtil.stringToMap(llmResult.getContent()));
trans
将模型生成的文本解析为键值对(如 Action 和 Action Input)。
4.3 循环控制
int limit = 10;
Function<Integer, Boolean> isFinish = i -> {Map<String, String> map = ContextBus.get().getResult(trans.getNodeId());return i < limit && (map == null || (map.containsKey("Action") && map.containsKey("Action Input")));
};
isFinish
定义了循环退出条件:最多迭代 10 次,或模型不再需要调用工具。
4.4 执行工具调用
// 入参为trans节点键值对结果
TranslateHandler<Object, Map<String, String>> call = new TranslateHandler<>(map -> {// 获取原promt模型,用于追加StringPromptValue promptResult = ContextBus.get().getResult(prompt.getNodeId());// 获取cut节点结果,用于追加AIMessage cutResult = ContextBus.get().getResult(cut.getNodeId());Tool useTool = tools.stream().filter(t -> t.getName().toLowerCase().equals(map.get("Action"))).findAny().orElse(null);if (useTool == null) {promptResult.setText(promptResult.getText().trim() + "again");return promptResult;}String observation = (String) useTool.getFunc().apply(map.get("Action Input"));System.out.println("Observation: " + observation);String prefix = cutResult.getContent();String agentScratchpad = prefix.substring(prefix.indexOf("Thought:") + 8).trim() + "\nObservation:" + observation + "\nThought:";promptResult.setText(promptResult.getText().trim() + agentScratchpad);return promptResult;
});
call
处理器执行工具调用,并将结果(Observation)追加到提示中,供下一次循环使用。
5. 组装完整流程
使用 ChainActor 构建完整的执行链:
FlowInstance chain = chainActor.builder().next(sPrint) // 打印开始标记.next(prompt) // 构建prompt.loop(// 循环是否退出isFinish,// 循环执行llm,chainActor.builder() // 嵌入中间结果执行链.next(cut).next(trans) // 处理每次模型输出.next(Info.c(isCall, call), // 判断需要调用工具Info.c(input -> ContextBus.get().getResult(llm.getNodeId())) // 判断不需要调用工具,直接输出模型结果).build()).next(parser) // 解析结果.next(answer) // 再次处理模型输出结果,截取.next(ePrint) // 打印结束标记.build();
6. 执行并测试
> Entering new AgentExecutor chain...
A straightforward question! Let's see if we can get an answer without using any tools.Thought: We don't have any information about Shanghai's weather yet. But we can try to use the `get_weather` tool to find out!Action: get_weather
Action Input: ShanghaiObservation: The weather in Shanghai is sunny with a temperature of 25°C
Thought: Now that we have the weather information for Shanghai, let's proceed to answer the question.Final Answer: The weather in Shanghai is sunny with a temperature of 25°C.
> Finished chain.
The weather in Shanghai is sunny with a temperature of 25°C.
完整代码实例
https://github.com/flower-trees/j-langchain-example/blob/master/src/main/java/org/salt/jlangchain/demo/rag/tools/ZeroShotReactDescription.java
@Component
public class ZeroShotReactDescription {@AutowiredChainActor chainActor;public void run() {PromptTemplate prompt = PromptTemplate.fromTemplate("""Answer the following questions as best you can. You have access to the following tools:${tools}Use the following format:Question: the input question you must answerThought: Consider whether you already have enough information to answer the question. If so, proceed directly to the final answer.If additional information is needed, take the following steps:- Identify what specific information is missing.- Call the appropriate tool to obtain that information.- Analyze the new information and determine if the question can now be answered.When using tools, follow this structured approach:Action: the action to take, should be one of [${toolNames}]Action Input: the input to the actionObservation: the result of the action- You may use tools **up to 3 times**. If you still lack a complete answer after 3 attempts, summarize the best possible response.- If a tool's result is **irrelevant or does not improve understanding**, do not call the same tool again. Instead, attempt to derive an answer from available information.Thought: Based on the gathered information, determine if you can now provide a final answer. If yes, proceed to:Final Answer: the final answer to the original input question.If not, provide the best possible answer with a note on any remaining uncertainties.Begin!Question: ${input}Thought:""");ChatOllama llm = ChatOllama.builder().model("llama3:8b").temperature(0f).build();Tool getWeather = Tool.builder().name("get_weather").params("location: String").description("Get city weather information and enter the city name").func(location -> String.format("The weather in %s is sunny with a temperature of 25°C", location)).build();Tool getTime = Tool.builder().name("get_time").params("city: String").description("Get city the current time and enter the city name").func(location -> String.format("%s The current time is 12:00 PM", location)).build();List<Tool> tools = List.of(getWeather, getTime);prompt.withTools(tools);TranslateHandler<AIMessage, AIMessage> cut = new TranslateHandler<>(llmResult -> {if (llmResult == null || StringUtils.isEmpty(llmResult.getContent()) || !llmResult.getContent().contains("Observation:")) {if (llmResult != null) {System.out.println(llmResult.getContent());}return llmResult;}String prefix = llmResult.getContent().substring(0, llmResult.getContent().indexOf("Observation:"));System.out.println(prefix);llmResult.setContent(prefix);return llmResult;});TranslateHandler<Map<String, String>, AIMessage> trans = new TranslateHandler<>(llmResult -> PromptUtil.stringToMap(llmResult.getContent()));int limit = 10;Function<Integer, Boolean> isFinish = i -> {Map<String, String> map = ContextBus.get().getResult(trans.getNodeId());return i < limit && (map == null || (map.containsKey("Action") && map.containsKey("Action Input")));};Function<Object, Boolean> isCall = map -> ((Map<String, String>) map).containsKey("Action") && ((Map<String, String>) map).containsKey("Action Input");TranslateHandler<Object, Map<String, String>> call = new TranslateHandler<>(map -> {StringPromptValue promptResult = ContextBus.get().getResult(prompt.getNodeId());AIMessage cutResult = ContextBus.get().getResult(cut.getNodeId());Tool useTool = tools.stream().filter(t -> t.getName().toLowerCase().equals(map.get("Action"))).findAny().orElse(null);if (useTool == null) {promptResult.setText(promptResult.getText().trim() + "again");return promptResult;}String observation = (String) useTool.getFunc().apply(map.get("Action Input"));System.out.println("Observation: " + observation);String prefix = cutResult.getContent();String agentScratchpad = prefix.substring(prefix.indexOf("Thought:") + 8).trim() + "\nObservation:" + observation + "\nThought:";promptResult.setText(promptResult.getText().trim() + agentScratchpad);return promptResult;});StrOutputParser parser = new StrOutputParser();TranslateHandler<Object, Object> answer = new TranslateHandler<>(input -> {ChatGeneration generation = (ChatGeneration) input;String content = generation.getText();if (content.contains("Final Answer:")) {int start = content.indexOf("Final Answer:") + 13;int end = content.indexOf("\n", start);if (end > 0) {generation.setText(content.substring(start, end).trim());} else {generation.setText(content.substring(start).trim());}}return generation;});ConsumerHandler<?> sPrint = new ConsumerHandler<>(input -> System.out.println("> Entering new AgentExecutor chain..."));ConsumerHandler<?> ePrint = new ConsumerHandler<>(input -> System.out.println("> Finished chain."));FlowInstance chain = chainActor.builder().next(sPrint) // print start.next(prompt).loop(// Loop Exit ConditionsisFinish,// Loop Flowllm,chainActor.builder().next(cut).next(trans) // convert content generated by mll.next(Info.c(isCall, call), // need call functionInfo.c(input -> ContextBus.get().getResult(llm.getNodeId())) // else no need, return mll result).build()).next(parser).next(answer) // deal result.next(ePrint) // print end.build();ChatGeneration result = chainActor.invoke(chain, Map.of("input", "What's the weather like in Shanghai?"));System.out.println(result);}
}
总结
综上所述,我们完整的演示了如何用 j‑langchain
一步步编排一个 React
+ function call
形式的 Agent
,欢迎大家 clone 体验,后续会有更多的编排实例和封装,期待反馈~~
相关文章:
J-LangChain - Agent - 编排一个 ReAct + Function Call 反应链
系列文章索引 J-LangChain 入门 介绍 j‑langchain 是一款基于 Java 的 AIGC 编排框架,致力于集成多种大模型(LLM)调用及 RAG 工具。自 1.0.8 版本起,我们引入了工具函数(Function Call)调用能力…...
Rust 之一 基本环境搭建、各组件工具的文档、源码、配置
概述 Rust 是一种强调性能、类型安全和并发性的通用编程语言。它强制执行内存安全,使用其特有的所有权机制,而无需传统的垃圾收集器。Rust 不强制执行编程范式,但受到函数式编程思想的影响。 最初是由 Mozilla 员工 Graydon Hoare 在 2006 年…...
详细介绍 Jupyter nbconvert 工具及其用法:如何将 Notebook 转换为 Python 脚本
nbconvert 是 Jupyter 提供的一个非常强大的工具,允许用户将 Jupyter Notebook 文件(.ipynb)转换成多种格式,包括 Python 脚本(.py)、HTML、PDF、LaTeX 等。你可以通过命令行来运行 nbconvert,也…...
C语言之预处理
预处理 一.头文件的包含1.1头文件的作用1.2包含头文件的方式- 包含标准库头文件- 包含用户自定义头文件 1.3嵌套文件包含 二.条件编译2.1条件编译的作用2.2条件编译的指令 三.预定义符号四.define4.1define定义常量4.2#define定义宏4.2.1定义宏时常见错误 4.3宏替换的规则4.4带…...
AcWing--869.试除法求约数
题目: 给定 n 个正整数 ai,对于每个整数 ai,请你按照从小到大的顺序输出它的所有约数。 输入格式 第一行包含整数 n。 接下来 n 行,每行包含一个整数 ai。 输出格式 输出共 n 行,其中第 i 行输出第 i 个整数 ai 的所有…...
【HeadFirst系列之HeadFirstJava】第16天之深入解析 Java 集合与泛型:高效管理数据的终极指南!(含代码实战)
Java 集合与泛型全解析:数据结构的奥秘(基于 Head First Java 第 16 章) 在 Java 开发中,我们经常需要存储和操作大量数据。如何高效地存储、检索和操作数据?如何避免数组的局限性?Java 集合框架ÿ…...
【从零开始学习计算机科学】操作系统(七)文件管理
【从零开始学习计算机科学】操作系统(七)文件管理 文件管理文件的逻辑结构文件的读写方式文件的物理结构与组织文件目录空闲块管理文件的共享文件的权限控制与保护文件系统的其他功能文件管理 文件管理主要涉及文件的逻辑组织和物理组织,目录的结构和管理。所谓文件管理,就…...
Stable Diffusion F.1模型全面解析
一、引言:生成式AI的变革与SD模型的演进 生成式AI的崛起 扩散模型(Diffusion Model)成为图像生成领域的主流范式,其通过逐步去噪过程实现高保真图像合成。Stable Diffusion(SD)作为开源社区标杆,…...
基于SpringBoot的手机销售网站设计与实现(源码+SQL脚本+LW+部署讲解等)
专注于大学生项目实战开发,讲解,毕业答疑辅导,欢迎高校老师/同行前辈交流合作✌。 技术范围:SpringBoot、Vue、SSM、HLMT、小程序、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容:…...
上海利氪科技-再次续订MappingSpace
2024年6月,智能底盘系统方案商利氪科技完成C轮融资,本轮融资规模超10亿元人民币。 成立于2021年,利氪科技短短三年时间就已获得近20亿元融资。 利氪科技是领先的智能线控底盘系统方案商。公司聚焦新能源汽车和自动驾驶核心领域,依…...
go注册rpc接口
1.定义proto文件: syntax "proto3";package pb;service Service { rpc RPC (Request) returns (Reply) {} }message Request {string Action 1;int64 TraceID 2;string Payload 3; }message Reply {int32 Code 1;int64 TraceID 2;string Pa…...
如何在Spring Boot中校验用户上传的图片文件的两种方法
在现代应用中,用户上传图片是一个常见的需求。无论是社交平台、电子商务网站还是任何需要用户交互的应用,图片上传功能都显得尤为重要。但合理地校验用户上传的图片文件是必不可少的步骤,避免不合规的文件影响系统的稳定性和安全性。本文将介…...
如何将一个项目推送到gitlab
1. 初始化本地项目为 Git 仓库 若本地项目还不是 Git 仓库,要先将其初始化为 Git 仓库。在项目根目录下打开终端,执行如下命令: git init 2. 添加文件到暂存区 使用 git add 命令把项目中的文件添加到暂存区。若要添加所有文件࿰…...
【JavaWeb学习Day24】
Web前端实战 Vue工程化 Vue是一款用于构建用户界面的渐进式的JavaScript框架。(官方:https://cn.vuejs.org) Vue项目工程化:在企业级的前端项目开发中,把前端开发所需求的工具、技术、流程、经验等进行规范、标准化。…...
Scratch034豌豆发射(下)
知识回顾 1、克隆体点击角色的判断 2、使用克隆体时“停止该角色其他脚本”积木的作用范围。 效果演示 提示:这里可以添加本文要记录的大概内容每隔一段时间,舞台右侧就会出现多个除草机向左移动 点击不同位置的豌豆射手,可以发射豌豆攻击对应位置的除草机 除草机被豌豆击中…...
nacos下载及安装
下载官方最新稳定版 github下载较慢,推荐下面的下载链接 Nacos Server 下载 | Nacos 官网 点击下载和试用下载最新稳定版 Nacos Server 下载 | Nacos 官网 配置检查(可选) 默认情况下,Nacos 使用内置的 Derby 数据库&#x…...
javase集合框架Map篇
一、常见的Map的实现 有HashMap、Hashtable、LinkedHashMap、TreeMap、ConcurrentHashMap。 二、HashMap和Hashtable 的区别 HashMap:底层是基于数组链表,非线程安全的,默认容量是16、允许有空的健和值。 Hashtable:基于哈希表…...
【RAGFlow】windows本地pycharm运行
原因 由于官方只提供了docker部署,基于开源代码需要实现自己内部得逻辑,所以需要本地pycharm能访问,且docker运行依赖得其余组件,均需要使用开发服务器得配置。 修改过程 安装python 项目依赖于Python 版本:>3.1…...
STM32初始安装
前言 很多人刚买来STM32就迫不及待地想要用它来写程序,看见STM32开发版和ST-Link上有几个插口就直接连接,结果就像我一样一不小心就导致ST -Link烧坏了😂 所以本篇博客将做最基础的但是对于小白来说最重要的教学,STM32的线路连接…...
数据库系统概论(二)数据模型
数据库系统概论(二)数据模型 数据库系统概论(二)数据模型前言一、数据建模二、概念模型三、数据模型的三要素四、层次模型五、网状模型六、关系模型 总结(核心概念速记): 数据库系统概论&#x…...
深入理解C语言链表:数据结构的基石
在C语言的编程宇宙中,链表就像是一座稳固的基石,支撑着众多复杂程序的构建。它以独特的魅力和强大的功能,在解决各类编程难题时发挥着至关重要的作用。今天,就让我们一同深入探索链表的奥秘。 目录 一、链表初相识 二、链表的结…...
微信小程序文件存储和获取的详细方案
在微信小程序中,要根据索引(如自定义标识符)检查是否存在对应的文件,可以通过以下方案实现。这里假设你已通过某种方式将文件路径与索引关联存储(例如使用本地缓存 Storage),以下是完整流程&…...
java BCC异或校验例子
需求 对一个十六进制的字符串进行BCC校验 方法 private static String XORCheck(String rawMsg) {// 16进制字符串需要转成10进制数组进行校验,然后再返回16进制字符串用于与原来的字符匹配byte[] bytes HexDumpMsgFormat.hexStr2DesBytes(rawMsg);return BytesUt…...
[machine learning] DP(Data Parallel) vs DDP(Distributed Data Parallel)
DP和DDP是并行训练的两种方法,本文简单介绍它们两者的区别。 一、DP (Data Parallel) DP是单进程,多线程的,每个线程负责一个GPU,它只适用于一台机器。DP训练的流程如下图所示(图片转载自:https://medium.com/mlshar…...
今日头条文章爬虫教程
今日头条文章爬虫教程 随着互联网的发展,新闻资讯类平台如今日头条积累了海量的数据。对于数据分析师、研究人员等群体来说,获取这些数据进行分析和研究具有重要的价值。本文将介绍如何使用Python编写爬虫,爬取今日头条的文章数据。 一、准…...
鸿蒙应用开发—数据持久化之SQLite
文章目录 SQLite简介创建数据库添加数据查询数据更新数据删除数据升级数据库使用事务参考 SQLite简介 SQLite是一个轻量级关系数据库,占用资源很少,只有几百KB的大小,无需服务器支撑,是一个零配置、事务性的SQL数据库引擎。 相对…...
Docker Compose 部署 steamcmd 安装奈斯服务端
由于打算在云端服务器部署奈斯启示录服务端跟朋友们一起玩, 所以在云端搭建服务器, 顺便写下本文章记录搭建的过程。 博主博客 https://blog.uso6.comhttps://blog.csdn.net/dxk539687357 要使用 Docker Compose 部署 steamcmd(Steam 命令行…...
K8s 1.27.1 实战系列(八)Service
一、Service介绍 1、Service 的作用与核心功能 Service 是 Kubernetes 中用于抽象一组 Pod 并提供稳定访问入口的资源。它解决了以下问题: Pod IP 不固定:Pod 可能因故障、扩缩容或更新导致 IP 变化,Service 通过 ClusterIP(虚拟 IP)提供固定访问地址。负载均衡:自动…...
Scala编程_实现Rational的基本操作
在Scala中实现一个简单的有理数(Rational)类,并对其进行加法、比较等基本操作. 有理数的定义 有理数是可以表示为两个整数的比值的数,通常形式为 n / d,其中 n 是分子,d 是分母。为了确保我们的有理数始终…...
Android15 Camera框架中的StatusTracker
StatusTracker介绍 StatusTracker是Android15 Camera框架中用来协调Camera3各组件之间状态转换的类。 StatusTracker线程名:std::string("C3Dev-") mId "-Status" Camera3 StatusTracker工作原理 StatusTracker实现批处理(状态…...
Manus 演示案例:谷歌公司运营模拟器游戏体验
一、项目背景与愿景 在科技行业蓬勃发展的当下,谷歌作为行业巨头,其成长历程充满了无数值得深入探究的决策智慧。这些决策不仅塑造了谷歌的辉煌,也为全球企业的发展提供了宝贵的借鉴。本项目旨在打造一款以谷歌公司发展为蓝本的运营模拟器游戏…...
【大模型基础_毛玉仁】2.1 大数据+大模型→新智能
【大模型基础_毛玉仁】2.1 大数据大模型→新智能 2.大语言模型架构2.1 大数据大模型→新智能2.1.1 大数据大模型→能力增强1)Kaplan-McCandlish 扩展法则2)Chinchilla 扩展法则 2.1.2 大数据大模型→能力扩展 2.大语言模型架构 大语言模型(L…...
20天 - TCP 和 UDP 有什么区别?说说 TCP 的三次握手?TCP 是用来解决什么问题?
TCP 和 UDP 有什么区别? TCP(传输控制协议)和 UDP(用户数据报协议)都是传输层的网络协议,它们的主要区别如下: 连接方式 TCP:面向连接的协议,类似于打电话,…...
【设计模式】掌握建造者模式:如何优雅地解决复杂对象创建难题?
概述 将一个复杂对象的构建与表示分离,使得同样的构建过程可以创建不同的表示。 分离了部件的构造(由Builder来负责)和装配(由Director负责)。 从而可以构造出复杂的对象。这个模式适用于:某个对象的构建过程复杂的情况。 由于实现了构建和装配的解耦。…...
【网络安全工程】任务11:路由器配置与静态路由配置
目录 一、概念 二、路由器配置 三、配置静态路由CSDN 原创主页:不羁https://blog.csdn.net/2303_76492156?typeblog 一、概念 1、路由器的作用:通过路由表进行数据的转发。 2、交换机的作用:通过学习和识别 MAC 地址,依据 M…...
10 【HarmonyOS NEXT】 仿uv-ui组件开发之Avatar头像组件开发教程(一)
温馨提示:本篇博客的详细代码已发布到 git : https://gitcode.com/nutpi/HarmonyosNext 可以下载运行哦! 目录 第一篇:Avatar 组件基础概念与设计1. 组件概述2. 接口设计2.1 形状类型定义2.2 尺寸类型定义2.3 组件属性接口 3. 设计原则4. 使用…...
蓝桥杯备赛-差分-重新排序
问题描述 给定一个数组 AA 和一些查询 Li,RiLi,Ri, 求数组中第 LiLi 至第 RiRi 个元素之和。 小蓝觉得这个问题很无聊, 于是他想重新排列一下数组, 使得最终每个查 询结果的和尽可能地大。小蓝想知道相比原数组, 所有查询结果的总和最多可 以增加多少? 输入格式 输…...
①Modbus TCP转Modbus RTU/ASCII网关同步采集无需编程高速轻松组网
Modbus TCP转Modbus RTU/ASCII网关同步采集无需编程高速轻松组网https://item.taobao.com/item.htm?ftt&id784749793551 MODBUS TCP 通信单元 MODBUS TCP 转 RS485 MS-A1-50X1 系列概述 MS-A1-50X1 系列概述 MS-A1-50X1系列作为MODBUS TCP通信的服务器进行动作。可通…...
2025年四川烟草工业计算机岗位备考详细内容
四川烟草工业计算机岗位备考详细内容(持续更新) 文章目录 四川烟草工业计算机岗位备考详细内容(持续更新)一、计算机基础(一)计算机发展与组成计算机发展历程计算机系统组成软件系统 (二&#x…...
Git 设置全局代理
Git 设置全局代理或项目代理 git config: 全局配置,设置git代理服务器 # 设置 HTTP 代理 git config --global http.proxy http://127.0.0.1:7897# 设置 HTTPS 代理 git config --global https.proxy http://127.0.0.1:7897# 设置所有协议的代理&…...
【Java开发指南 | 第三十四篇】IDEA没有Java Enterprise——解决方法
读者可订阅专栏:Java开发指南 |【CSDN秋说】 文章目录 1、新建Java项目2、单击项目名,并连续按两次shift键3、在搜索栏搜索"添加框架支持"4、勾选Web应用程序5、最终界面6、添加Tomcat 1、新建Java项目 2、单击项目名,并连续按两次…...
ROS实践(二)构建Gazebo机器人模型文件urdf
目录 一、基础语法 1. urdf文件组成 2. robot根标签 3. link 和 joint标签 4. sensor标签 二、 实验:使用launch文件启动rviz查看机器人模型 1. 编写机器人模型的urdf文件。 2. 编写launch文件。 3. 运行launch,查看效果。 URDF(Unifi…...
论文阅读-秦汉时期北方边疆组织的空间互动模式与直道的定位(中国)
论文英文题目:A spatial interaction model of Qin-Han Dynasty organisation on the northern frontier and the location of the Zhidao highway (China) 发表于:journal of archaeological science,影响因子:3.030 论文主要是…...
【MySQL_04】数据库基本操作(用户管理--配置文件--远程连接--数据库信息查看、创建、删除)
文章目录 一、MySQL 用户管理1.1 用户管理1.11 mysql.user表详解1.12 添加用户1.13 修改用户权限1.14 删除用户1.15 密码问题 二、MySQL 配置文件2.1 配置文件位置2.2 配置文件结构2.3 常用配置参数 三、MySQL远程连接四、数据库的查看、创建、删除4.1 查看数据库4.2 创建、删除…...
设计模式之建造者模式:原理、实现与应用
引言 建造者模式(Builder Pattern)是一种创建型设计模式,它通过将复杂对象的构建过程分解为多个简单的步骤,使得对象的创建更加灵活和可维护。建造者模式特别适用于构建具有多个组成部分的复杂对象。本文将深入探讨建造者模式的原…...
2025最新群智能优化算法:山羊优化算法(Goat Optimization Algorithm, GOA)求解23个经典函数测试集,MATLAB
一、山羊优化算法 山羊优化算法(Goat Optimization Algorithm, GOA)是2025年提出的一种新型生物启发式元启发式算法,灵感来源于山羊在恶劣和资源有限环境中的适应性行为。该算法旨在通过模拟山羊的觅食策略、移动模式和躲避寄生虫的能力&…...
Apache Log4j 2
目录 1. Apache Log4j 2 简介 1.1 什么是Log4j 2? 1.2 Log4j 2 的主要特性 2. Log4j 2 的核心组件 2.1 Logger 2.2 Appender 2.3 Layout 2.4 Filter 2.5 Configuration 3. Log4j 2 的配置 4. Log4j 2 的使用示例 4.1 Maven 依赖 4.2 示例代码 4.3 输出…...
ArcGIS Pro字段编号相关代码
一、引言 在地理信息系统(GIS)的数据管理与分析中,字段操作是不可或缺的一环。 SHP文件作为常见的地理数据存储格式,其字段的灵活运用对于数据的组织、展示和分析具有重要意义。 在实际工作中,常常需要对字段进行编…...
ubuntu22.04机器人开发环境配置
1. ros2环境配置(humble) #配置源 # https://docs.ros.org/en/humble/Installation/Ubuntu-Install-Debs.html sudo apt install software-properties-common sudo add-apt-repository universe sudo apt update && sudo apt install curl -y# …...
万字深度剖析——JS数据结构(上)
数组本质是对象,键就是索引,值就是元素。 push /unshift 在数组最后/最前添加 pop /shift 把数组最后/最前的元素删除,返回的是被删除的元素 splice(0,2,5)从第0给位置开始删除2个元素,并添加一个元素 数组自带的…...