LangChain4j实战
基础
LangChain4j模型适配:
Provider | Native Image | Sync Completion | Streaming Completion | Embedding | Image Generation | Scoring | Function Calling |
OpenAI | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | |
Azure OpenAI | ✅ | ✅ | ✅ | ✅ | ✅ | ||
Hugging Face | ✅ | ✅ | |||||
Amazon Bedrock | ✅ | ✅ | ✅ | ✅ | |||
Google Vertex AI Gemini | ✅ | ✅ | ✅ | ✅ | |||
Google Vertex AI | ✅ | ✅ | ✅ | ✅ | |||
Mistral AI | ✅ | ✅ | ✅ | ✅ | |||
DashScope | ✅ | ✅ | ✅ | ||||
LocalAI | ✅ | ✅ | ✅ | ✅ | |||
Ollama | ✅ | ✅ | ✅ | ||||
Cohere | ✅ | ||||||
Qianfan | ✅ | ✅ | ✅ | ✅ | |||
ChatGLM | ✅ | ||||||
Nomic | ✅ | ||||||
Anthropic | ✅ | ✅ | ✅ | ✅ | |||
Zhipu AI | ✅ | ✅ | ✅ | ✅ |
Langchain实战应用场景:
https://github.com/lyhue1991/eat_chatgpt/blob/main/3_langchain_9_usecases.ipynb
官方文档:
LangChain4j | LangChain4j
官方LangChain4j使用示例
https://github.com/langchain4j/langchain4j-examples.git
基本使用示例是比较完整
官方SpringBoot整合示例
Spring Boot Integration | LangChain4j
SpringBoot实战使用示例
自己写的demo, 使用LangChain4j为内部系统生成有意义的测试数据
https://github.com/kvenLin/spring-langchain-demo
LangChain4j的实战用例讲解
核心功能
LangChain4j已经将很多和大模型进行复杂的操作进行了简化,对于后端程序员只需要调用指定的API即可
个人觉得还是需要提前理解LangChain的基础架构, 了解每个模块的作用, 使用起来才会更容易
LangChain4j主要的核心的几个功能就是:
- Chat and Language Models: 切换大模型
- Chat Memory: 对系统内聊天指定聊天memoryId进行区分, 可以根据memoryId来持续对话内容
- Model Parameters: 根据您选择的模型型号和提供程序,可以调整许多参数
- Response Streaming: 响应流式处理, LLM提供程序提供了一种逐个令牌流式传输响应的方法,而不是等待生成整个文本
- AI Services: 比较高级的核心功能, 通过代理的形式帮我们实现特定的Service层的服务, 只需要关注业务, 不需要关注底层实现
- Tools (Function Calling): 除了生成文本外,还可以触发操作。在tools层可以根据触发条件调用不同的函数, 也是比较核心的模块, 对于AI-Agent的实现是必须的.
- RAG (Retrieval-Augmented Generation): 根据特定的 文档+向量化 数据, 来扩展模型的知识库, 提高搜索的有效性
- Structured Data Extraction: 这里官方文档还没有完善, 但是examples中可以找打使用示例, 主要的作用是根据文本数据抽取我们需要的信息, 并封装成对Java有意义的自定义的结构化对象.
- Classification: 官方文档待完善...
- Embedding (Vector) Stores: 向量数据的存储功能, 提供了很多示例, 可以使用ES、Redis
- Chains: 官方文档待完善...
- Image Models: 官方文档待完善...
使用教程
AI Service
工作原理
官方解释: 将接口与低级组件一起提供 Class , AiServices 并 AiServices 创建实现此接口的代理对象。目前,它使用反射,但我们也在考虑替代方案。此代理对象处理输入和输出的所有转换。在本例中,输入是单个 String ,但我们使用ChatLanguageModel 作为 ChatMessage 输入。因此, AiService 会自动将其转换为 UserMessage 并调用 ChatLanguageModel .由于 chat 该方法的输出类型是 String ,在返回 AiMessage 后 ChatLanguageModel ,它会在从 chat 方法返回之前转换为 String。
实际上就是代理形式帮我们实现了定义的业务接口
POJO抽取
public class POJO_Extracting_AI_Service_Example {static ChatLanguageModel model = OpenAiChatModel.builder().baseUrl(ApiKeys.BASE_URL).apiKey(ApiKeys.OPENAI_API_KEY).logRequests(true).logResponses(true).timeout(ofSeconds(60)).build();static class Person {private String firstName;private String lastName;private LocalDate birthDate;@Overridepublic String toString() {return "Person {" +" firstName = \"" + firstName + "\"" +", lastName = \"" + lastName + "\"" +", birthDate = " + birthDate +" }";}}interface PersonExtractor {@UserMessage("Extract information about a person from {{it}}")Person extractPersonFrom(String text);}public static void main(String[] args) {PersonExtractor extractor = AiServices.create(PersonExtractor.class, model);String text = "In 1968, amidst the fading echoes of Independence Day, "+ "a child named John arrived under the calm evening sky. "+ "This newborn, bearing the surname Doe, marked the start of a new journey.";Person person = extractor.extractPersonFrom(text);System.out.println(person); // Person { firstName = "John", lastName = "Doe", birthDate = 1968-07-04 }}
}
- 自定义的业务需要的对象: Person对象
- 定义业务接口: PersonExtractor
- @UserMessage标注当前接口方法使用来做什么的
- text 会自动预处理, 在 @UserMessage 中进行替换{{it}}
最后得到的就是Service自动从文本中抽取数据并自动构建的Person对象
应用场景:
- 可以对用户模糊描述提取有用的信息, 进行精确的业务处理
- 对文档提取特定的数据进行业务处理
@SystemMessage的使用
限定AI角色区分service不同函数实现功能
public class AI_Service_with_System_and_User_Messages_Example {static ChatLanguageModel model = OpenAiChatModel.builder().baseUrl(ApiKeys.BASE_URL).apiKey(ApiKeys.OPENAI_API_KEY).logRequests(true).logResponses(true).timeout(ofSeconds(60)).build();interface TextUtils {@SystemMessage("You are a professional translator into {{language}}")@UserMessage("Translate the following text: {{text}}")String translate(@V("text") String text, @V("language") String language);@SystemMessage("Summarize every message from user in {{n}} bullet points. Provide only bullet points.")List<String> summarize(@UserMessage String text, @V("n") int n);}public static void main(String[] args) {TextUtils utils = AiServices.create(TextUtils.class, model);String translation = utils.translate("Hello, how are you?", "italian");System.out.println(translation); // Ciao, come stai?String text = "AI, or artificial intelligence, is a branch of computer science that aims to create "+ "machines that mimic human intelligence. This can range from simple tasks such as recognizing "+ "patterns or speech to more complex tasks like making decisions or predictions.";List<String> bulletPoints = utils.summarize(text, 3);bulletPoints.forEach(System.out::println);// [// "- AI is a branch of computer science",// "- It aims to create machines that mimic human intelligence",// "- It can perform simple or complex tasks"// ]}
}
文本分析情感
根据文本内容分析情感色彩, 积极、中立、消极
public class Sentiment_Extracting_AI_Service_Example {static ChatLanguageModel model = OpenAiChatModel.builder().baseUrl(ApiKeys.BASE_URL).apiKey(ApiKeys.OPENAI_API_KEY).logRequests(true).logResponses(true).timeout(ofSeconds(60)).build();enum Sentiment {POSITIVE, NEUTRAL, NEGATIVE;}interface SentimentAnalyzer {@UserMessage("Analyze sentiment of {{it}}")Sentiment analyzeSentimentOf(String text);@UserMessage("Does {{it}} have a positive sentiment?")boolean isPositive(String text);}public static void main(String[] args) {SentimentAnalyzer sentimentAnalyzer = AiServices.create(SentimentAnalyzer.class, model);Sentiment sentiment = sentimentAnalyzer.analyzeSentimentOf("It is good!");System.out.println(sentiment); // POSITIVEboolean positive = sentimentAnalyzer.isPositive("It is bad!");System.out.println(positive); // false}
}
文本数据类型转换
public class Number_Extracting_AI_Service_Example {static ChatLanguageModel model = OpenAiChatModel.builder().baseUrl(ApiKeys.BASE_URL).apiKey(ApiKeys.OPENAI_API_KEY).logRequests(true).logResponses(true).timeout(ofSeconds(60)).build();interface NumberExtractor {@UserMessage("Extract number from {{it}}")int extractInt(String text);@UserMessage("Extract number from {{it}}")long extractLong(String text);@UserMessage("Extract number from {{it}}")BigInteger extractBigInteger(String text);@UserMessage("Extract number from {{it}}")float extractFloat(String text);@UserMessage("Extract number from {{it}}")double extractDouble(String text);@UserMessage("Extract number from {{it}}")BigDecimal extractBigDecimal(String text);}public static void main(String[] args) {NumberExtractor extractor = AiServices.create(NumberExtractor.class, model);String text = "After countless millennia of computation, the supercomputer Deep Thought finally announced "+ "that the answer to the ultimate question of life, the universe, and everything was forty two.";int intNumber = extractor.extractInt(text);System.out.println(intNumber); // 42long longNumber = extractor.extractLong(text);System.out.println(longNumber); // 42BigInteger bigIntegerNumber = extractor.extractBigInteger(text);System.out.println(bigIntegerNumber); // 42float floatNumber = extractor.extractFloat(text);System.out.println(floatNumber); // 42.0double doubleNumber = extractor.extractDouble(text);System.out.println(doubleNumber); // 42.0BigDecimal bigDecimalNumber = extractor.extractBigDecimal(text);System.out.println(bigDecimalNumber); // 42.0}
}
public class Date_and_Time_Extracting_AI_Service_Example {static ChatLanguageModel model = OpenAiChatModel.builder().baseUrl(ApiKeys.BASE_URL).apiKey(ApiKeys.OPENAI_API_KEY).logRequests(true).logResponses(true).timeout(ofSeconds(60)).build();interface DateTimeExtractor {@UserMessage("Extract date from {{it}}")LocalDate extractDateFrom(String text);@UserMessage("Extract time from {{it}}")LocalTime extractTimeFrom(String text);@UserMessage("Extract date and time from {{it}}")LocalDateTime extractDateTimeFrom(String text);}public static void main(String[] args) {DateTimeExtractor extractor = AiServices.create(DateTimeExtractor.class, model);String text = "The tranquility pervaded the evening of 1968, just fifteen minutes shy of midnight,"+ " following the celebrations of Independence Day.";LocalDate date = extractor.extractDateFrom(text);System.out.println(date); // 1968-07-04LocalTime time = extractor.extractTimeFrom(text);System.out.println(time); // 23:45LocalDateTime dateTime = extractor.extractDateTimeFrom(text);System.out.println(dateTime); // 1968-07-04T23:45}
}
区分对话和记忆
public class ServiceWithMemoryExample {static ChatLanguageModel model = OpenAiChatModel.builder().baseUrl(ApiKeys.BASE_URL).apiKey(ApiKeys.OPENAI_API_KEY).logRequests(true).logResponses(true).timeout(ofSeconds(60)).build();interface Assistant {String chat(@MemoryId int memoryId, @UserMessage String userMessage);}public static void main(String[] args) {Assistant assistant = AiServices.builder(Assistant.class).chatLanguageModel(model).chatMemoryProvider(memoryId -> MessageWindowChatMemory.withMaxMessages(10)).build();System.out.println(assistant.chat(1, "Hello, my name is Klaus"));// Hi Klaus! How can I assist you today?System.out.println(assistant.chat(2, "Hello, my name is Francine"));// Hello Francine! How can I assist you today?System.out.println(assistant.chat(1, "What is my name?"));// Your name is Klaus.System.out.println(assistant.chat(2, "What is my name?"));// Your name is Francine.}
}
AI Tools
简单使用
public class _10_ServiceWithToolsExample {// Please also check CustomerSupportApplication and CustomerSupportApplicationTest// from spring-boot-example modulestatic class Calculator {@Tool("Calculates the length of a string")int stringLength(String s) {System.out.println("Called stringLength() with s='" + s + "'");return s.length();}@Tool("Calculates the sum of two numbers")int add(int a, int b) {System.out.println("Called add() with a=" + a + ", b=" + b);return a + b;}@Tool("Calculates the square root of a number")double sqrt(int x) {System.out.println("Called sqrt() with x=" + x);return Math.sqrt(x);}}interface Assistant {String chat(String userMessage);}public static void main(String[] args) {ChatLanguageModel model = OpenAiChatModel.builder().baseUrl(ApiKeys.BASE_URL).apiKey(ApiKeys.OPENAI_API_KEY).logRequests(false).build();Assistant assistant = AiServices.builder(Assistant.class).chatLanguageModel(model).tools(new Calculator()).chatMemory(MessageWindowChatMemory.withMaxMessages(10)).build();String question = "What is the square root of the sum of the numbers of letters in the words \"hello\" and \"world\"?";String answer = assistant.chat(question);System.out.println(answer);// The square root of the sum of the number of letters in the words "hello" and "world" is approximately 3.162.}
}
- @Tool: 添加对工具的描述, 告诉AI这个方法是的作用是什么
- AiServices构建的时候添加tools类, 模型就知道这个工具什么时候调用
- 当chat输入文本内容和tools中工具的方法含义相同时, 就会调用自定义的工具方法的函数进行处理得到结果
因为有些模型计算逻辑的处理并不是很好, 这样使用自定义的工具可以进行复杂的逻辑处理, AI只需要根据工具调用不同的方法拿到结果告诉用户即可
SpringBoot中进行使用
参考demo
GitHub - kvenLin/spring-langchain-demo: use LangChain4j dynamic generate meaningful test data for database
spring.application.name=spring-langchain-demo
langchain4j.open-ai.chat-model.api-key=${OPENAI_API_KEY}
langchain4j.open-ai.chat-model.base-url=${OPENAI_API_URL}
langchain4j.open-ai.chat-model.model-name=gpt-3.5-turbo
langchain4j.open-ai.chat-model.temperature=0.7
# 开启调用open-ai请求日志
langchain4j.open-ai.chat-model.log-requests=true
# 开启调用open-ai响应日志
langchain4j.open-ai.chat-model.log-responses=true
logging.level.dev.langchain4j=DEBUG
logging.level.dev.ai4j.openai4j=DEBUG
server.port=8081
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/spring-langchain-demo?useSSL=false&useUnicode=true&characterEncoding=UTF-8
spring.datasource.username=root
spring.datasource.password=123456
# MyBatis-Plus configuration
mybatis-plus.configuration.map-underscore-to-camel-case=true
mybatis-plus.configuration.auto-mapping-behavior=full
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
mybatis-plus.mapper-locations=classpath*:mapper/**/*Mapper.xml
mybatis-plus.global-config.db-config.logic-not-delete-value=1
mybatis-plus.global-config.db-config.logic-delete-value=0
这里的 ${OPENAI_API_KEY} 和 ${OPENAI_API_URL} 可以用系统环境变量的方式提供
国内使用open-ai的模型有一定限制, 所以这里使用的是三方代理地址: F2API - OpenAI API Key
自定义配置:
package com.louye.springlangchaindemo.config;import com.louye.springlangchaindemo.service.ai.AssistantService;
import com.louye.springlangchaindemo.service.ai.Factory;
import com.louye.springlangchaindemo.tool.AssistantTools;
import dev.langchain4j.memory.chat.MessageWindowChatMemory;
import dev.langchain4j.model.chat.ChatLanguageModel;
import dev.langchain4j.model.openai.OpenAiChatModel;
import dev.langchain4j.service.AiServices;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;import static java.time.Duration.ofSeconds;@Configuration
class AssistantConfiguration {@BeanAssistantService assistantService(ChatLanguageModel chatLanguageModel, AssistantTools assistantTools) {return AiServices.builder(AssistantService.class).chatLanguageModel(chatLanguageModel).chatMemory(MessageWindowChatMemory.builder().maxMessages(10).build()).tools(assistantTools).build();}@BeanFactory factoryService() {ChatLanguageModel chatLanguageModel = OpenAiChatModel.builder().baseUrl(System.getenv("OPENAI_API_URL")).apiKey(System.getenv("OPENAI_API_KEY")).timeout(ofSeconds(60))
// .responseFormat("json_object").build();return AiServices.create(Factory.class, chatLanguageModel);}}
ai-service定义:
package com.louye.springlangchaindemo.service.ai;import dev.langchain4j.service.SystemMessage;
import dev.langchain4j.service.spring.AiService;@AiService
public interface AssistantService {@SystemMessage("""you are system assistant, you can help me to do some works in this system.if user want to generate table data, must input the table name and the number of rows.""")String chat(String message);
}
public interface Factory {ProductDataList generateTestDataForProduct(TableDataGeneratePrompt prompt);CartDataList generateTestDataForCart(TableDataGeneratePrompt prompt);UserDataList generateTestDataForUser(TableDataGeneratePrompt prompt);
}
tools自定义: 让用户提供表名和新增数据量, tools会根据用户指定的表去对该表新增测试数据
package com.louye.springlangchaindemo.tool;import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.louye.springlangchaindemo.domain.Product;
import com.louye.springlangchaindemo.domain.aidata.CartDataList;
import com.louye.springlangchaindemo.domain.aidata.ProductDataList;
import com.louye.springlangchaindemo.domain.aidata.UserDataList;
import com.louye.springlangchaindemo.service.CartService;
import com.louye.springlangchaindemo.service.ProductService;
import com.louye.springlangchaindemo.service.UserService;
import com.louye.springlangchaindemo.service.ai.Factory;
import com.louye.springlangchaindemo.template.TableDataGeneratePrompt;
import dev.langchain4j.agent.tool.P;
import dev.langchain4j.agent.tool.Tool;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;import java.time.LocalTime;
import java.util.List;@Slf4j
@Component
public class AssistantTools {@Resourceprivate Factory factory;@Resourceprivate ProductService productService;@Resourceprivate CartService cartService;@Resourceprivate UserService userService;@Toolpublic String currentTime() {return LocalTime.now().toString();}@Tool("when user need to open the system")public String openSystem() {log.info("user need to open the system, do something here");return "success";}@Tool("when user need to generate test data for aim table")public String generateTestData(@P("tableName to generate test data") String tableName,@P("number of rows to generate") Integer num) {log.info("query table structure");String createTableDDL = userService.showTableDDL(tableName);if (StrUtil.isEmpty(createTableDDL)) {throw new RuntimeException("table not exisdt");}log.info("query table max id");Integer maxId = userService.maxIdForTable(tableName);TableDataGeneratePrompt prompt = new TableDataGeneratePrompt(tableName, num, maxId);if (tableName.equals("user")) {UserDataList userDataList = factory.generateTestDataForUser(prompt);log.info("userDataList: {}", userDataList);if (CollUtil.isNotEmpty(userDataList.getUserList())) {userService.saveBatch(userDataList.getUserList());}return userDataList.toString();} else if (tableName.equals("product")) {ProductDataList productDataList = factory.generateTestDataForProduct(prompt);log.info("productDataList: {}", productDataList);if (CollUtil.isNotEmpty(productDataList.getProductList())) {productService.saveBatch(productDataList.getProductList());}return productDataList.toString();}else if (tableName.equals("cart")) {CartDataList cartDataList = factory.generateTestDataForCart(prompt);log.info("cartDataList: {}", cartDataList);if (CollUtil.isNotEmpty(cartDataList.getCartList())) {cartService.saveBatch(cartDataList.getCartList());}return cartDataList.toString();}return "no handle tool for this table:" + tableName;}}
controller实现:
package com.louye.springlangchaindemo.controller;import com.louye.springlangchaindemo.tool.AssistantTools;
import com.louye.springlangchaindemo.service.ai.AssistantService;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;@Slf4j
@RequestMapping("/assistant")
@RestController
class AssistantController {@Resourceprivate AssistantService assistant;@Resourceprivate AssistantTools assistantTools;@GetMapping("/chat")public String chat(@RequestParam(value = "message", defaultValue = "What is the time now?") String message) {log.info("AssistantController.chat() called with message: {}", message);return assistant.chat(message);}
}
测试:
个人想法
后续AI的发展必然是AI-Agent的方向, 但是目前agent的工具大多都是提升生产力的工具, 而偏向系统使用方向的agent不太多, 感觉可能需要让AI明白一个系统如何使用并没有那么容易, 只有系统内部改造才能让AI明白什么时候调用什么函数, 这或许又涉及到业务重构等问题.
大方向上, 后续可能就不太需要用户再去在网站上点击操作了, 而是对话形式进行自己的业务处理改变数据库数据.但是这可能就涉及一些AI安全方向的, 可能这也是为什么目前为止还没有一些成熟的系统网站的agent的实现.
LangChain4j对于Java程序员来说, 更多的是提供了一种新的思路去设计系统的业务处理模式.期待后续LangChain4j的完善.
相关文章:

LangChain4j实战
基础 LangChain4j模型适配: Provider Native Image Sync Completion Streaming Completion Embedding Image Generation Scoring Function Calling OpenAI ✅ ✅ ✅ ✅ ✅ ✅ Azure OpenAI ✅ ✅ ✅ ✅ ✅ Hugging Face ✅ ✅ Amazon Bedrock ✅ ✅…...

57.Semaphore信号量
用来限制能同时访问共享资源的线程上限。只是适合限制单机线程数量。 Slf4j public class SemaphoreDemo {public static void main(String[] args) {Semaphore semaphore new Semaphore(3);for (int i 0; i < 10; i) {new Thread(() -> {try {semaphore.acquire();//…...
生成式人工智能 - 文本反转(Textual Inversion):一种微调稳定扩散模型的方法
一、简述 大型文本到图像稳定扩散模型已经展示了前所未有的能力,可以使用文本提示合成新场景。这些文本到图像模型提供了通过自然语言指导创作的自由。然而,它们的使用受到用户描述特定或独特场景、艺术创作或新实体产品的能力的限制。很多时候,用户被限制行使她的艺术自由来…...

minio的一个基础使用案例:用户头像上传
文章目录 一、minio下载安装(Windows)二、案例需求分析三、后端接口开发 一、minio下载安装(Windows) 1. 下载minio服务端和客户端 minio下载地址 2. 手动搭建目录 /minio/binmc.exeminio.exe/data/logs手动创建minio应用程序目…...

Linux用户和用户组的管理
目录 前言一、系统环境二、Linux用户组的管理2.1 新增用户组2.2 删除用户组2.3 修改用户组2.4 查看用户组 三、Linux用户的管理3.1 新增用户3.2 删除用户3.3 修改用户3.4 查看用户3.5 用户口令(密码)的管理 总结 前言 本篇文章介绍如何在Linux系统上实现…...

项目-五子棋双人对战:游戏房间的管理(5)
完整代码见: 邹锦辉个人所有代码: 测试仓库 - Gitee.com 之前我们已经实现了玩家匹配的功能, 我们都知道, 匹配完过后就可以进入游戏房间进行对战了, 所以我们下一步关注的重点就是对于游戏房间的管理. 模块详细讲解 功能需求 通过匹配的方式, 自动给玩家加入到一个游戏房间…...
LocalDate和Date有什么区别?两者如何转换?
LocalDate与Date 在Java中,LocalDate和Date是用来处理日期的两种不同的类。 区别: Date是Java早期的日期类,它包含了日期和时间的信息。但是在Java 8之后,Date类被标记为过时的,推荐使用新的日期时间API,…...

铝合金货物运输鉴定书办理 货物危险性鉴定
货物运输鉴定书/货物危险性鉴定 项目背景: 为了运输的安全,航空运输、公路运输、铁道运输、水路运输都必须了解货物的运输危险性。货物运输条件鉴定就是对货物的运输适宜性作出评价和建议。 货物运输条件鉴定一般依据IATA危险货物规章(DGR)2005、联合国危…...
php操作数据库
<?php session_start(); #面向过程 function create_connection(){ $conn mysqli_connect(127.0.0.1,root,123456,learn_2) or die("数据库连接失败"); mysqli_query($conn,"set names utf8"); return $conn; } #面向对象 function create_connection…...
python记录之集合
Python中的集合(Set)是一个无序且不包含重复元素的数据结构。集合主要用于成员检测和数据去重。 1. 集合的创建 在Python中,你可以使用大括号{}或set()函数来创建一个集合。注意,如果你使用大括号{}并且只包含一个元素ÿ…...
ResourceManager 的 rpc server 模型
一. yarn ResourceManager 的三种通信协议 ResourceTrackerProtocol NodeManager 和 ResourceManager 的 RPC 通信协议。其中 ResourceManager 充当RPC Server的角色,而 NodeManager 充当 RPC Client 的角色。NodeManager 通过该协议向 ResourceManager 注册、汇报…...

Java面试八股之什么是自动装箱和自动拆箱
什么是自动装箱和自动拆箱 在Java中,自动装箱(Autoboxing)和自动拆箱(Auto-unboxing)是两个与基本数据类型和它们对应的包装类之间的转换相关的特性。这两个概念自Java 5(也称为Java SE 5或JDK 5ÿ…...

OrangePi AIpro小试牛刀-目标检测(YoloV5s)
非常高兴参加本次香橙派AI Pro,香橙派联合华为昇腾打造的一款AI推理开发板评测活动,以前使用树莓派Raspberry Pi4B 8G版本,这次有幸使用国产嵌入式开发板。 一窥芳容 这款开发板搭载的芯片是和华为昇腾的Atlas 200I DK A2同款的处理器&#…...

QT案例 记录解决在管理员权限下QFrame控件获取拖拽到控件上的文件路径
参考知乎问答 Qt管理员权限如何支持拖放操作? 的回答和代码示例。 解决在管理员权限运行下,通过窗体的QFrame子控件获取到拖拽的内容。 目录标题 导读解决方案详解示例详细 【管理员权限】在QFrame控件中获取拖拽内容 【管理员权限】继承 IDropTarget 类…...

[HNCTF 2022 WEEK4]flower plus
第一种花指令 第二种花指令 根据两种花指令特征,写出去花指令脚本 saddr0x401000 eaddr0x435000 for i in range(saddr,eaddr):if get_wide_dword(i)0x01740275:print(hex(i),hex(get_wide_dword(i)))patch_byte(i-5,0x90)patch_dword(i-4,0x90909090)patch_dw…...
Mongo常用语法(java代码)
1、根据agentId字段分组,并对totalCustomerNum、refundCustomerNum字段 sum求和,同时取别名 Overridepublic List<AgentCountInfoBean> selectCurrentMonthNewResource(Set<String> orderTypeSet, List<String> agentIds,LocalDateTim…...

go语言后端开发学习(二)——基于七牛云实现的资源上传模块
前言 在之前的文章中我介绍过我们基于gin框架怎么实现本地上传图片和文本这类的文件资源(具体文章可以参考gin框架学习笔记(二) ——相关数据与文件的响应),但是在我们实际上的项目开发中一般却是不会使用本地上传资源的方式来上传的,因为文件的上传与读…...
探索微软新VLM Phi-3 Vision模型:详细分析与代码示例
引言 在最近的微软Build大会上,微软宣布了许多新内容,其中包括新款Copilot PC和围绕Copilot生态系统的一系列功能。其中最引人注目的是发布了一些新的Phi模型,特别是Phi-3 Vision模型。本文将详细探讨Phi-3 Vision模型的特性,并提…...

如何使用GPT-4o函数调用构建一个实时应用程序?
本教程介绍了如何使用OpenAI最新的LLM GPT-4o通过函数调用将实时数据引入LLM。 我们在LLM函数调用指南(详见https://thenewstack.io/a-comprehensive-guide-to-function-calling-in-llms/)中讨论了如何将实时数据引入聊天机器人和代理。现在,我们将通过将来自Fligh…...

[Vue-常见错误]浏览器显示Uncaught runtime errors
文章目录 错误描述正确写法具体如下 错误描述 当前端代码发生错误时,浏览器中出现以下错误提示。 正确写法 显然这不是我们所期望的,在vue.config.js中配置如下设置关闭Uncaught runtime errors显示 devServer: {client: {overlay: false}具体如下 …...

利用最小二乘法找圆心和半径
#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …...

手游刚开服就被攻击怎么办?如何防御DDoS?
开服初期是手游最脆弱的阶段,极易成为DDoS攻击的目标。一旦遭遇攻击,可能导致服务器瘫痪、玩家流失,甚至造成巨大经济损失。本文为开发者提供一套简洁有效的应急与防御方案,帮助快速应对并构建长期防护体系。 一、遭遇攻击的紧急应…...
零门槛NAS搭建:WinNAS如何让普通电脑秒变私有云?
一、核心优势:专为Windows用户设计的极简NAS WinNAS由深圳耘想存储科技开发,是一款收费低廉但功能全面的Windows NAS工具,主打“无学习成本部署” 。与其他NAS软件相比,其优势在于: 无需硬件改造:将任意W…...

【OSG学习笔记】Day 18: 碰撞检测与物理交互
物理引擎(Physics Engine) 物理引擎 是一种通过计算机模拟物理规律(如力学、碰撞、重力、流体动力学等)的软件工具或库。 它的核心目标是在虚拟环境中逼真地模拟物体的运动和交互,广泛应用于 游戏开发、动画制作、虚…...
3403. 从盒子中找出字典序最大的字符串 I
3403. 从盒子中找出字典序最大的字符串 I 题目链接:3403. 从盒子中找出字典序最大的字符串 I 代码如下: class Solution { public:string answerString(string word, int numFriends) {if (numFriends 1) {return word;}string res;for (int i 0;i &…...
【HarmonyOS 5 开发速记】如何获取用户信息(头像/昵称/手机号)
1.获取 authorizationCode: 2.利用 authorizationCode 获取 accessToken:文档中心 3.获取手机:文档中心 4.获取昵称头像:文档中心 首先创建 request 若要获取手机号,scope必填 phone,permissions 必填 …...
《C++ 模板》
目录 函数模板 类模板 非类型模板参数 模板特化 函数模板特化 类模板的特化 模板,就像一个模具,里面可以将不同类型的材料做成一个形状,其分为函数模板和类模板。 函数模板 函数模板可以简化函数重载的代码。格式:templa…...

NXP S32K146 T-Box 携手 SD NAND(贴片式TF卡):驱动汽车智能革新的黄金组合
在汽车智能化的汹涌浪潮中,车辆不再仅仅是传统的交通工具,而是逐步演变为高度智能的移动终端。这一转变的核心支撑,来自于车内关键技术的深度融合与协同创新。车载远程信息处理盒(T-Box)方案:NXP S32K146 与…...

七、数据库的完整性
七、数据库的完整性 主要内容 7.1 数据库的完整性概述 7.2 实体完整性 7.3 参照完整性 7.4 用户定义的完整性 7.5 触发器 7.6 SQL Server中数据库完整性的实现 7.7 小结 7.1 数据库的完整性概述 数据库完整性的含义 正确性 指数据的合法性 有效性 指数据是否属于所定…...

解析奥地利 XARION激光超声检测系统:无膜光学麦克风 + 无耦合剂的技术协同优势及多元应用
在工业制造领域,无损检测(NDT)的精度与效率直接影响产品质量与生产安全。奥地利 XARION开发的激光超声精密检测系统,以非接触式光学麦克风技术为核心,打破传统检测瓶颈,为半导体、航空航天、汽车制造等行业提供了高灵敏…...