LLM MCP模型上下文协议快速入门(for Java)
什么是MCP
Model Control Protocol(MCP)是由AI研究机构Anthropic在2023年第二季度首次提出的新型协议规范,旨在解决大语言模型LLM应用中的上下文管理难题。作为LLM交互领域的创新标准,MCP协议在发布后短短一年内已进行了多次更新,最近一次更新是在2025-03-26(Key Changes - Model Context Protocol),包含 添加了一个基于 OAuth 2.1 的全面的授权框架 等内容变更:
协议定义与核心价值
MCP是一套开放式的通信协议,它通过标准化:
- 上下文结构化表示(JSON Schema)
- 多轮对话状态跟踪机制
- 模型控制指令集
使开发者能够精准控制LLM的上下文窗口,解决传统对话系统中存在的:
- 上下文丢失(Context Bleeding)
- 指令冲突
- 长文本处理低效等痛点
成熟度
目前MCP已被Claude系列模型原生支持,并在Llama 3、Mistral等开源模型中实现兼容。行业分析显示,超过43%的企业级LLM应用已开始采用MCP作为首选上下文管理方案(数据来源:2024 ML Stack调查报告)。
MCP的目标对象
刚开始接触MCP的开发者可能会进入一个误区,以为有了MCP后,LLM是不是可以直接调用MCP Server的能力(API)了,其实并不是,LLM实际上是无法感知MCP的存在的。
MCP(Model Control Protocol)的核心目标对象是LLM应用开发者,而不是LLM(大语言模型)本身。要理解这一点,我们需要明确LLM和LLM应用的区别:
1. LLM vs. LLM应用
- LLM(大语言模型):指底层的大模型(如GPT-4、Claude、Llama等),它们负责接收输入并生成文本输出,但本身不具备复杂的状态管理或上下文控制能力。
- LLM应用:指基于LLM构建的完整系统,如聊天机器人、AI助手、代码生成工具等。这些应用需要管理多轮对话、维护上下文、处理用户指令,并可能集成外部数据或API。
2. 为什么LLM不能直接使用MCP
LLM本身是“无状态”的——它们仅对当前输入做出响应,而不会自动记住之前的交互。MCP的作用是让LLM应用能更高效地管理上下文,例如:
- 维护对话历史(避免超出模型的上下文窗口限制)
- 动态调整提示词(prompt),确保LLM获得正确的背景信息
- 控制模型行为(如切换模式、调整生成参数)
MCP协议定义了一套标准化的接口,让LLM应用能以结构化的方式与LLM交互,而不是让LLM自己去解析或执行这些逻辑。
MCP作为外部协议而非模型内置机制,还有两大更关键原因:
-
训练成本问题:若MCP逻辑固化到LLM中,协议每次更新都需重新训练模型,带来极高的计算和迭代成本;
-
安全与权限挑战:若LLM直接通过MCP调用三方应用,权限管理(如数据访问、API鉴权)将难以控制,增加滥用风险。
因此,MCP设计为应用层协议,由外部系统管理上下文和资源,既保持LLM的通用性,又避免强耦合带来的运维负担。
3. MCP的目标用户
MCP主要面向:
- LLM应用开发者:需要构建复杂对话系统或AI代理的工程师
- AI平台架构师:设计LLM基础设施,优化上下文管理和推理效率
- 企业级AI解决方案:需要稳定、可扩展的LLM交互协议
简而言之,MCP不是让LLM自己“学会”管理上下文,而是为LLM应用提供一套标准化的控制机制,使开发者能更高效地构建可靠的AI系统。
MCP的主要角色和架构
MCP最核心的两个角色就是MCP客户端和MCP服务端。参见:Model Context Protocol (MCP) :: Spring AI Reference
MCP Client
MCP 客户端是模型上下文协议 (MCP) 架构中的关键组件,负责建立和管理与 MCP 服务器的连接。对,你没听错,MCP体系中,客户端才是最复杂的,而且通常这个客户端也是由服务端应用(也就是前面说的LLM应用)来“使用”。
它实现了协议的客户端功能,处理以下操作:
- 协议版本协商以确保与服务器的兼容性
- 能力协商以确定可用功能
- 消息传输和 JSON-RPC 通信
- 工具发现和执行
- 资源访问和管理
- 提示系统交互
- 可选功能:
- 根部管理
- 采样支持
- 同步和异步操作
- 通信选择:
- 基于 Stdio 的传输,用于基于进程的通信
- 基于 SSE 客户端传输
你可以看到,通常是MCP客户端在“调用” LLM 和 MCP服务端 。
MCP Server
MCP 服务器是模型上下文协议 (MCP) 架构中的基础组件,为客户端提供:
- 资源:上下文和数据,供用户或 AI 模型使用。它们通常是 只读的,AI 模型可以读取资源数据,但不会直接修改或执行它们,所以一般是指数据库查询。
- 提示:为用户提供模板化的消息和工作流程
- 工具:AI模型执行的功能。它们通常是 动态的、有副作用的(如修改数据、发送消息、触发操作),所以一般是指AI调用。
它实现了协议的服务器端,负责:
-
服务器端协议操作实现
-
工具曝光和发现
-
基于 URI 访问的资源管理
-
及时提供和处理模板
-
与客户进行能力谈判
-
结构化日志记录和通知
-
-
并发客户端连接管理
-
同步和异步 API 支持
-
通信实施:
-
基于 Stdio 的传输,用于基于进程的通信
-
基于 SSE 服务器传输
-
通常来说MCP服务器是不直接使用LLM的(当然,如果你这个MCP服务器也是另一些MCP服务器的MCP客户端时也有可能需要直接使用LLM),它通常是我们常见的一个个业务系统。
这里需要特殊说明的是如果MCP客户端和MCP服务器是部署在一起的,那么可以使用Stdio( Standard Input/Output(标准输入/输出) 的缩写,指计算机程序与外部环境(如终端、文件或其他程序)进行数据交互的标准方式。它是操作系统提供的基础通信机制,几乎所有编程语言都支持 stdio 操作)的方式来进行通信。
一言以蔽之
通过MCP的角色、架构分析,大家应该有所感知,MCP就是通过定义一套标准协议,同时标准化通过LLM来使用应用能力来解决我们之前直接使用LLM去编排Function Call难度大、复杂度高以及效率低的问题。
实战:构建MCP客户端和服务器(for Java)
说的再多都是虚的,得眼见为实,这里我们通过构建两个Spring应用来演示如何在本地来使用MCP。Spring框架早已提供对调用LLM能力的封装:Spring AI API :: Spring AI Reference,这里我们就使用Spring框架来构建MCP客户端和MCP服务器。
构建MCP服务器
MCP服务器相对比较简单,它负责把业务功能封装成一个个原子能力,供MCP客户端来使用,新建一个Maven项目mcp-server,pom.xml如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>com.manzhizhen.mcp</groupId><artifactId>mcp-study</artifactId><version>0.0.1-SNAPSHOT</version></parent><artifactId>mcp-server</artifactId><version>0.0.1-SNAPSHOT</version><packaging>jar</packaging><name>mcp-server</name><description>Demo project for mcp</description><properties><java.version>21</java.version><spring-ai.version>1.0.0-M7</spring-ai.version></properties><dependencies><dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-starter-mcp-server-webmvc</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupId>ch.qos.logback</groupId><artifactId>logback-classic</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency></dependencies></project>
这里和常规的Spring Boot项目不同的是加了spring-ai的依赖,而且我们计划使用SSE来进行通信(Stdio方式生产不常用):
<dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-starter-mcp-server-webmvc</artifactId></dependency>
接着,我们Copy官方的天气预报例子,构建一个通过经纬度查询天气预报(getWeatherForecastByLocation),另一个通过美国州代码来查询天气预报的接口(getAlerts),注意,这属于上面提到的MCP服务器提供的“工具Tool”类型。
我们先通过 org.springframework.ai.tool.annotation.Tool 注解完成工具的定义(参考 https://github.com/spring-projects/spring-ai-examples/tree/main/model-context-protocol/weather/starter-webmvc-server/src/main/java/org/springframework/ai/mcp/sample/server):
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.extern.slf4j.Slf4j;
import org.springframework.ai.tool.annotation.Tool;
import org.springframework.ai.tool.annotation.ToolParam;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestClient;
import org.springframework.web.client.RestClientException;import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;@Slf4j
@Service
public class WeatherService {private final RestClient restClient;public WeatherService() {this.restClient = RestClient.builder().baseUrl("https://api.weather.gov").defaultHeader("Accept", "application/geo+json").defaultHeader("User-Agent", "WeatherApiClient/1.0 (835576511@qq.com)").build();}/*** Get forecast for a specific latitude/longitude* @param latitude Latitude* @param longitude Longitude* @return The forecast for the given location* @throws RestClientException if the request fails*/@Tool(description = "Get weather forecast for a specific latitude/longitude")public String getWeatherForecastByLocation(double latitude, // Latitude coordinatedouble longitude // Longitude coordinate) {log.info("Fetching forecast for coordinates: {}, {}", latitude, longitude);var points = restClient.get().uri("/points/{latitude},{longitude}", latitude, longitude).retrieve().body(Points.class);var forecast = restClient.get().uri(points.properties().forecast()).retrieve().body(Forecast.class);String forecastText = forecast.properties().periods().stream().map(p -> {return String.format("""%s:Temperature: %s %sWind: %s %sForecast: %s""", p.name(), p.temperature(), p.temperatureUnit(), p.windSpeed(), p.windDirection(),p.detailedForecast());}).collect(Collectors.joining());return forecastText;}/*** Get alerts for a specific area* @param state Area code. Two-letter US state code (e.g. CA, NY)* @return Human readable alert information* @throws RestClientException if the request fails*/@Tool(description = "Get weather alerts for a US state")public String getAlerts(@ToolParam(description = "Two-letter US state code (e.g. CA, NY)") String state) {log.info("Fetching alerts for state: {}", state);Alert alert = restClient.get().uri("/alerts/active/area/{state}", state).retrieve().body(Alert.class);return alert.features().stream().map(f -> String.format("""Event: %sArea: %sSeverity: %sDescription: %sInstructions: %s""", f.properties().event(), f.properties.areaDesc(), f.properties.severity(),f.properties.description(), f.properties.instruction())).collect(Collectors.joining("\n"));}@JsonIgnoreProperties(ignoreUnknown = true)public record Points(@JsonProperty("properties") Props properties) {@JsonIgnoreProperties(ignoreUnknown = true)public record Props(@JsonProperty("forecast") String forecast) {}}@JsonIgnoreProperties(ignoreUnknown = true)public record Forecast(@JsonProperty("properties") Props properties) {@JsonIgnoreProperties(ignoreUnknown = true)public record Props(@JsonProperty("periods") List<Period> periods) {}@JsonIgnoreProperties(ignoreUnknown = true)public record Period(@JsonProperty("number") Integer number, @JsonProperty("name") String name,@JsonProperty("startTime") String startTime, @JsonProperty("endTime") String endTime,@JsonProperty("isDaytime") Boolean isDayTime,@JsonProperty("temperature") Integer temperature,@JsonProperty("temperatureUnit") String temperatureUnit,@JsonProperty("temperatureTrend") String temperatureTrend,@JsonProperty("probabilityOfPrecipitation") Map probabilityOfPrecipitation,@JsonProperty("windSpeed") String windSpeed,@JsonProperty("windDirection") String windDirection,@JsonProperty("icon") String icon, @JsonProperty("shortForecast") String shortForecast,@JsonProperty("detailedForecast") String detailedForecast) {}}@JsonIgnoreProperties(ignoreUnknown = true)public record Alert(@JsonProperty("features") List<Feature> features) {@JsonIgnoreProperties(ignoreUnknown = true)public record Feature(@JsonProperty("properties") Properties properties) {}@JsonIgnoreProperties(ignoreUnknown = true)public record Properties(@JsonProperty("event") String event, @JsonProperty("areaDesc") String areaDesc,@JsonProperty("severity") String severity,@JsonProperty("description") String description,@JsonProperty("instruction") String instruction) {}}
}
@Tool是 Spring AI 项目中的一个注解,用于将 Java 方法标记为可由 AI 模型(如 OpenAI、Azure OpenAI 或其他支持的 AI 服务)调用的工具(Tool)。它的主要作用是将你的方法暴露给 MCP客户端,使它够动态调用这些方法来完成特定任务。其中 @Tool 完成方法整体的功能描述,而@ToolParam 可以进一步完成参数的说明,如果你参数名足够清晰,也可以不用加@ToolParam。
同时在我们的Spring Boot启动类中增加ToolCallbackProvider,这样才能真正把Tool暴露出去给MCP Client调用:
import lombok.extern.slf4j.Slf4j;
import org.springframework.ai.tool.ToolCallbackProvider;
import org.springframework.ai.tool.method.MethodToolCallbackProvider;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;@Slf4j
@SpringBootApplication
public class McpServerApplication {public static void main(String[] args) {log.info("McpServerApplication 启动啦");SpringApplication.run(McpServerApplication.class, args);}/*** Tools* Allows servers to expose tools that can be invoked by language models.* The auto-configuration will automatically register the tool callbacks as MCP tools.* You can have multiple beans producing ToolCallbacks. The auto-configuration will merge them.* @param weatherService* @return*/@Beanpublic ToolCallbackProvider weatherTools(WeatherService weatherService) {return MethodToolCallbackProvider.builder().toolObjects(weatherService).build();}
}
细心的朋友会发现,前面不是说有Stdio和SSE两种方式来暴露吗?目前看代码上没有体现?其实前面在pom.xml中我们依赖的spring-ai-starter-mcp-server-webmvc里面就依赖了:
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency>
这里面就支持了SSE的实现,我们只需要在application.yml配置文件中配置一下即可:
server:port: 8090spring:application:name: mcp-servermain:banner-mode: offai:mcp:server:name: mcp-serverversion: 1.0.0type: SYNCsse-message-endpoint: /mcp/messages
这里的 sse-message-endpoint 就是配置SSE的path。注意这里暴露的是8090端口。到这里,一个简单的MCP Server就构建完成了。
构建MCP客户端
前面说过通常MCP客户端是需要使用LLM的,这里我们首选DeepSeek,然后在DeepSeek开放平台官网创建Api Keys 再充10块钱,这样你就有了可用DeepSeek Api Key了:
同样,我们建一个Maven项目叫做mcp-client,pom.xml配置如下:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>com.manzhizhen.mcp</groupId><artifactId>mcp-study</artifactId><version>0.0.1-SNAPSHOT</version></parent><artifactId>mcp-client</artifactId><version>0.0.1-SNAPSHOT</version><packaging>jar</packaging><name>mcp-client</name><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><java.version>22</java.version></properties><dependencies><dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-starter-mcp-client</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-starter-model-openai</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupId>ch.qos.logback</groupId><artifactId>logback-classic</artifactId></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>3.8.1</version><scope>test</scope></dependency><dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId><version>33.3.1-jre</version><scope>compile</scope></dependency></dependencies>
</project>
其中和其他项目不同的是我们依赖了:
<dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-starter-mcp-client</artifactId></dependency><dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-starter-model-openai</artifactId></dependency>
一个是为了支持mcp-client,一个是为了支持我们调用DeepSeek。由于只是做一个简单的演示,我们决定使用IDEA的控制台作为输入,来当做一个天气预报咨询平台。我们只需要修改启动类即可:
import io.modelcontextprotocol.client.McpSyncClient;
import lombok.extern.slf4j.Slf4j;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.tool.ToolCallbackProvider;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;import java.util.List;
import java.util.Scanner;@Slf4j
@SpringBootApplication
public class McpClientSseApplication {public static void main(String[] args) {SpringApplication.run(McpClientSseApplication.class, args);}@Beanpublic CommandLineRunner interactiveChatRunner(ChatClient.Builder chatClientBuilder,ToolCallbackProvider tools,ConfigurableApplicationContext context) {return args -> {var chatClient = chatClientBuilder.defaultTools(tools).build();Scanner scanner = new Scanner(System.in); // 用于读取控制台输入System.out.println("=== 聊天模式已启动(输入 'exit' 退出) ===");while (true) {System.out.print("\n>>> 你的问题: ");String userInput = scanner.nextLine().trim();// 输入 "exit" 退出聊天if ("exit".equalsIgnoreCase(userInput)) {System.out.println(">>> 聊天结束,程序退出。");break;}// 空输入则跳过if (userInput.isEmpty()) {continue;}// 调用 AI 并打印回复System.out.println("\n>>> AI 回复: " + chatClient.prompt(userInput).call().content());}context.close(); // 关闭 Spring 上下文};}
}
可以看到,为了能不断的在控制台提问,我们写了一个while循环,当你输入exit才退出。
这里有一个关键,就是不管我们mcp-client连接了多少个mcp-server以及使用了多少个mcp-server的能力(例如Tool),我们都不需要去太关心细节,一行代码“chatClient.prompt(userInput).call().content()”就搞定,mcp内置的库类会去调用AI来根据你的问题“合理”的使用mcp-server提供的一个或者多个能力来完成任务,之前用Function Call可没有这么丝滑。
对,mcp-client修改这一个类即可,接下来我们配置下application.yml:
spring:application:name: mcp-clientai:mcp:client:toolcallback:enabled: trueenabled: truename: my-mcp-clientversion: 1.0.0request-timeout: 30stype: SYNC # or ASYNC for reactive applicationssse:connections:server1:url: http://localhost:8090openai:api-key: 这里填写你的DeepSeek api keybase-url: https://api.deepseek.comchat:options:model: deepseek-chattemperature: 0.7embedding:enabled: false
可以看到,我们最重要的是要配置mcp-server的地址(这里由于mcp-server和mcp-client部署在一起,所以用的是localhost)以及我们的openai的类型和对于的api key。到这里,整个mcp-client示例我们也写完了。
看看效果
先运行mcp-server,再运行mcp-client,如果启动都没问题,那么我们在mcp-client的控制台可以进行天气预报咨询了:
>>> 你的问题: 帮我查下 纬度 (lat): 40.7128,经度 (lon): -74.0060 的天气>>> AI 回复: 以下是纬度 40.7128,经度 -74.0060 的天气预报:### 今天
- **温度**: 80°F
- **风速**: 10 到 23 mph,西南风
- **预报**: 上午8点前可能有零星小雨,随后可能有零星阵雨和雷暴。部分晴天,最高气温接近80°F。西南风10至23 mph,阵风高达39 mph。降水概率20%。### 今晚
- **温度**: 57°F
- **风速**: 15 到 22 mph,西风
- **预报**: 凌晨2点前可能有零星阵雨和雷暴。大部分多云,最低气温约57°F,夜间气温升至62°F左右。西风15至22 mph,阵风高达38 mph。降水概率20%。### 周日
- **温度**: 63°F
- **风速**: 15 到 20 mph,西北风
- **预报**: 大部分晴天,最高气温接近63°F。西北风15至20 mph。...
可以看到我的问题携带了经纬度,所以最终是mcp-server的WeatherService#getWeatherForecastByLocation 被调用了。
>>> 你的问题: 美国 WA 州 天气预报>>> AI 回复: 以下是美国华盛顿州(WA)的天气预报:### 今晚
- **温度**: 44°F
- **风速**: 9 mph 西北风
- **预报**: 多云,最低气温约44°F。西北风约9 mph,阵风高达22 mph。### 周六
- **温度**: 54°F
- **风速**: 9至13 mph 西北风
- **预报**: 大部分晴天,最高气温约54°F,下午气温降至约52°F。西北风9至13 mph,阵风高达29 mph。### 周六晚
- **温度**: 38°F
- **风速**: 10 mph 西北风
- **预报**: 部分多云,最低气温约38°F。西北风约10 mph,阵风高达28 mph。...
这个问题很明显想引导mcp-client去使用mcp-server的WeatherService#getAlerts,但由于getAlerts没有查到华盛顿州的数据,所以mcp-client最终通过DeepSeek拿到华盛顿州的经纬度47.7511, -120.7401 去调用了getWeatherForecastByLocation方法,真聪明!!!
总结
欢迎加作者WX sugarmq 一起来探讨技术话题。
相关文章:
LLM MCP模型上下文协议快速入门(for Java)
什么是MCP Model Control Protocol(MCP)是由AI研究机构Anthropic在2023年第二季度首次提出的新型协议规范,旨在解决大语言模型LLM应用中的上下文管理难题。作为LLM交互领域的创新标准,MCP协议在发布后短短一年内已进行了多次更新…...
CTF--秋名山车神
一、原网页: 二、步骤: 1.尝试用计算器计算: 计算器溢出,无法正常计算 2.使用python计算: 得出计算结果为:1864710043732437134701060769 3.多次刷新页面: 发现变量为value,要用pos…...
Windows桌面图标变白的解决方案
一、问题原因 桌面图标变白通常是由于系统图标缓存文件(IconCache.db)损坏或系统图表示现异常导致。图标缓存是Windows用于存储应用程序和文件夹图标图像的临时文件,当该文件损坏或系统未正确更新缓存时,图标会因无法加载原始图像…...
Linux学习——信号量
1.头文件-semaphore.h 2.信号量类型 sem_t sem; 加强版的互斥锁,是并行的 3.主要函数 初始化信号量 sem_init(sem_t *sem,int pshared,unsigned int value); 第一个参数 信号量类型 第二个参数 0-线程同步 1-进程同步 …...
蓝桥杯 蜗牛 动态规划
16.蜗牛 - 蓝桥云课https://www.lanqiao.cn/problems/4985/learning/?page1&first_category_id1&second_category_id3&sortdifficulty&asc1&tags%E5%8A%A8%E6%80%81%E8%A7%84%E5%88%92,%E9%80%92%E6%8E%A8,01%E8%83%8C%E5%8C%85,%E5%8C%BA%E9%97%B4DP,%E6…...
FiftyOne 管理数据
FiftyOne 管理数据 下载安装FiftyOne https://docs.voxel51.com/ 下载 coco-2017 使用 FiftyOne 查看 import fiftyone as fo import fiftyone.zoo as foz# 自定义路径 - 修改这些变量以匹配你的环境 image_path /media/wmx/ws3/AI/data/coco2017/train2017 annotations_…...
解决echarts饼图label显示不全的问题
解决办法 添加如下配置: labelLayout: {hideOverlap: false},...
2000-2017年各省城市天然气供气总量数据
2000-2017年各省城市天然气供气总量数据 1、时间:2000-2017年 2、来源:国家统计局、能源年鉴 3、指标:行政区划代码、城市、年份、城市天然气供气总量 4、范围:31省 5、指标说明:城市天然气供气总量是指在一定时间…...
Linux教程-常用命令系列二
文章目录 1. 系统管理常用命令1. useradd - 创建用户账户功能基本用法常用选项示例 2. passwd - 管理用户密码功能基本用法常用选项示例 3. kill - 终止进程功能基本用法常用信号示例 4. date - 显示和设置系统时间功能基本用法常用选项时间格式示例 5. bc - 高精度计算器功能基…...
苍穹外卖(菜品管理)
菜品管理 公共字段自动填充 实现思路 代码开发 自定义注解 AutoFill 自定义切面 AutoFillAspect 完善自定义切面 AutoFillAspect 的 autoFill 方法 在Mapper接口的方法上加入 AutoFill 注解 将业务层为公共字段赋值的代码注释掉 功能测试 新增菜品 需求分析和…...
Cril 截取字段-生成hostname
有些event 是不规则,需要用regular express 来加工一下, 下面说一下sample 数据: 2021-10-26 17:00:12 PDT sample log data from host eagle1 2021-10-26 17:00:12 PDT sample log data from host eagle2 2021-10-26 17:00:12 PDT sample log data from host eagle3 2021…...
免费将AI生成图像放大4倍的方法
有些人不需要任何高级工具和花哨的技巧;他们只需要一种简单的方法来提升图像分辨率而不损失任何质量 — 今天,我们将学习如何做到这一点。 生成AI图像最大的问题之一是什么?最终结果通常分辨率非常低。 这会导致很多不同的问题,特别是对于那些想要在内容或项目中使用这些…...
Map和Set相关练习
目录 1、只出现一次的数字 2、宝石与石头 3、坏键盘打字 4、复制带随机指针的链表 5、大量数据去重 6、大量数据重复次数 7、前K个高频单词 1、只出现一次的数字 oj:136. 只出现一次的数字 - 力扣(LeetCode) 思路: 1. 使用…...
移动自动化测试-appium
app自动化介绍 工具说明 主流工具 app自动化执行原理 app类型(技术) 环境搭建 所需环境 JDKandroid-sdkappium模拟器 1、JDK安装 说明:为什么要安装JDK? 安卓应用或开发工具是使用JAVA语言开发,必须使用jdk。…...
一个项目中多个Composer的使用方法
composer是依赖管理工具。 有时我们会在一个项目中使用到多个composer,且每个版本不同。 前提:例如项目xyz根目录vendor中存在阿里云的对应代码。我现在需要再composer腾讯云短信发送的SDK。 1、随便找个位置新建文件夹,存储腾讯云短信发送…...
Qt项目实现对西门子PLC的读写操作(snap7)——C++
实际项目中需要用到对西门子PLC进行通讯,故进行记录,方便后续回顾复习 实现功能: ①PLC连接与断开 ②往PLC指定位置读写操作(bit、real、string) PLC中的real相当于C中的float,4字节,32bit 1&…...
Python字典深度解析:高效键值对数据管理指南
一、字典核心概念解析 1. 字典定义与特征 字典(Dictionary)是Python中基于哈希表实现的无序可变容器,通过键值对存储数据,具有以下核心特性: 键值对结构:{key: value}形式存储数据快…...
Java虚拟机面试题:垃圾收集(下)
🧑 博主简介:CSDN博客专家,历代文学网(PC端可以访问:https://literature.sinhy.com/#/?__c1000,移动端可微信小程序搜索“历代文学”)总架构师,15年工作经验,精通Java编…...
9 C 语言变量详解:声明与定于、初始化与赋值、printf 输出与 scanf 输入、关键字、标识符命名规范
1 初识变量 1.1 变量的意义 在程序设计中,变量是程序中不可或缺的组成单位,最基本的存储单元。它如同现实生活中的容器,用于临时或长期保存各种类型的数据,为程序提供灵活的数据操作能力。 以选购手机为例,手机的各项…...
释放 Mac 存储空间:Ollama 模型迁移到外接 NVMe 磁盘
目录 背景一、准备工作1. 确认外接 NVMe 已挂载2. 创建模型目录 二、迁移已有模型数据(可选)三、配置模型目录1. 设置环境变量2. 使用软链接(强烈推荐) 四、测试是否成功 背景 在本地运行 Ollama 时,模型数据默认保存…...
spring-batch批处理框架(1)
学习链接 SpringBatch高效批处理框架详解及实战演练 spring-batch批处理框架(1) spring-batch批处理框架(2) spring batch官方文档 spring batch官方示例代码 - github 文章目录 学习链接一、课程目标课程目标课程内容前置知识适合人群 二、Spring Batch简介2.1 何为批处理…...
MCP系列:权限管理与隐私保护
前言 随着模型上下文协议(MCP)的广泛应用,安全性问题也逐步突显。在前几篇文章中,我们已经探讨了MCP的基本概念、技术架构、实践应用以及工具调用机制。本篇文章将聚焦于MCP的安全性考量,包括权限管理、隐私保护以及风险缓解策略。 对于企业和开发者而言,了解如何保障M…...
【25软考网工笔记】第二章(7)多路复用技术
目录 一、多路复用技术 1. 频分复用FDM 1)频分复用的基本概念 2)频分复用与相关技术 3)注意事项与扩展 2. 时分复用 1)同步时分复用 2)统计时分复用 3)同步时分复用与统计时分复用的对比 4&#…...
任意文字+即梦3.0的海报设计Prompt
即梦3.0版本发布后,对文字的呈现能力得到了极大的提升,网上也出现了各种文章教大家怎么写提示词。 但是你有没有发现一个问题,好的提示词是需要艺术细胞的,只有那些浸淫设计领域的专家总结的提示词才算上乘。 就像是给你一个主题…...
自动化测试相关协议深度剖析及A2A、MCP协议自动化测试应用展望
一、不同协议底层逻辑关联分析 1. OPENAPI协议 OPENAPI 协议核心在于定义 API 的规范结构,它使用 YAML 或 JSON 格式来描述 API 的端点、请求参数、响应格式等信息。其底层逻辑是构建一个清晰、标准化的 API 描述文档,方便不同的客户端和服务端进行对接…...
零基础上手Python数据分析 (18):Matplotlib 基础绘图 - 让数据“开口说话”
写在前面 —— 告别枯燥数字,拥抱可视化力量,掌握 Matplotlib 绘图基础 欢迎来到 “高效数据分析实战指南:Python零基础入门” 专栏! 经过前面 Pandas 模块的学习和实战演练,我们已经掌握了使用 Python 和 Pandas 进行数据处理、清洗、整合、分析的核心技能。 我们能够从…...
[特殊字符] AI 大模型的 Prompt Engineering 原理:从基础到源码实践
🌟 引言:Prompt Engineering - AI 大模型的"魔法咒语" 在 AI 大模型蓬勃发展的当下,它们展现出令人惊叹的语言处理能力,从文本生成到智能问答,从机器翻译到代码编写,几乎涵盖了自然语言处理的各…...
C++ 基于多设计模式下的同步异步⽇志系统-1准备工作
一.项目介绍 项⽬介绍 本项⽬主要实现⼀个⽇志系统, 其主要⽀持以下功能: • ⽀持多级别⽇志消息 • ⽀持同步⽇志和异步⽇志 • ⽀持可靠写⼊⽇志到控制台、⽂件以及滚动⽂件中 • ⽀持多线程程序并发写⽇志 • ⽀持扩展不同的⽇志落地⽬标地 二.日志系统的三种实现…...
c# MES生产进度看板,报警看板 热流道行业可用实时看生产进度
MES生产进度看板,报警看板 热流道行业可用实时看生产进度 背景 本软件是给宁波热流道行业客户开发的生产电子看板软件系统 功能 1.录入工艺流程图(途程图)由多个站别组成。可以手动设置每个工艺站点完成百分比。 2.可以看生成到哪个工…...
C语言学习之预处理指令
目录 预定义符号 #define的应用 #define定义常量 #define定义宏 带有副作用的宏参数 宏替换的规则 函数和宏定义的区别 #和## #运算符 ##运算符 命名约定 #undef 编辑 命令行定义 条件编译 头文件包含 头文件被包含的方式 1.本地头文件包含 2.库文件包含 …...
腾讯wxg企业微信 后端开发一面
UDP安全吗,怎么修改让其安全? packet header QUIC FrameHeader TCP的三个窗口 滑动 发送 拥塞, 怎么用UDP使用类似的功能 怎么确认消息是否收到? TCP的拥塞控制是怎么样的 HTTPS的握手流程 MySQL为什么用B树 红黑树等结构也能在叶子节点实现…...
【Hot100】 73. 矩阵置零
目录 引言矩阵置零我的解题优化优化思路分步解决思路为什么必须按照这个顺序处理?完整示例演示总结 🙋♂️ 作者:海码007📜 专栏:算法专栏💥 标题:【Hot100】 73. 矩阵置零❣️ 寄语ÿ…...
c++_csp-j算法 (2)
目录 BFS搜索(广度优先搜索) 讲解 BFS搜索算法原理 BFS搜索算法实现 BFS搜索算法的应用 例题(1) P1032 [NOIP 2002 提高组] 字串变换 例题(2) P1443 马的遍历 BFS搜索(广度优先搜索) 讲解 BFS搜索算法原理 广度优先搜索(BFS)算法是一种图的搜索算法,用于遍历…...
学习笔记: Mach-O 文件
“结构决定性质,性质决定用途”。如果不了解结构,是很难真正理解的。 通过一个示例的可执行文件了解Mach-O文件的结构 Mach-O基本结构 Header: :文件类型、目标架构类型等Load Commands:描述文件在虚拟内存中的逻辑结构、布局Data: 在Load commands中…...
基于GRPO将QWEN训练为和deepseek一样的推理模型!
GRPO 群体相对策略优化(GRPO)算法最初由deepseek团队提出,是近端策略优化(PPO)的一个变体。 GRPO 是一种在线学习算法,它通过使用训练过程中已训练模型自身生成的数据进行迭代改进。GRPO 目标背后的逻辑是在确保模型与参考策略保…...
STM32 外部中断EXTI
目录 外部中断基础知识 STM32外部中断框架 STM32外部中断机制框架 复用功能 重映射 中断嵌套控制器NVIC 外部中断按键控制LED灯 外部中断基础知识 STM32外部中断框架 中断的概念:在主程序运行过程中,出现了特点的中断触发条件,使得…...
Codex CLI - 自然语言命令行界面
本文翻译整理自:https://github.com/microsoft/Codex-CLI 文章目录 一、关于 Codex CLI相关链接资源 二、安装系统要求安装步骤 三、基本使用1、基础操作2、多轮模式 四、命令参考五、提示工程与上下文文件自定义上下文 六、故障排查七、FAQ如何查询可用OpenAI引擎&…...
健身会员管理系统(ssh+jsp+mysql8.x)含运行文档
健身会员管理系统(sshjspmysql8.x) 对健身房的健身器材、会员、教练、办卡、会员健身情况进行管理,可根据会员号或器材进行搜索,查看会员健身情况或器材使用情况。...
数据结构——快排和归并排序(非递归)
快速排序和归并排序一般都是用递归来实现的,但是掌握非递归也是很重要的,说不定在面试的时候面试官突然问你快排或者归并非递归实现,递归有时候并不好,在数据量非常大的时候效率就不好,但是使用非递归结果就不一样了&a…...
Trae,字节跳动推出的 AI 编程助手插件
Trae 插件是 Trae 旗下全新一代的人工智能编程助手(前身为 MarsCode 编程助手),以插件形式集成在本地开发环境中,具备极高的兼容性和灵活性,旨在提升开发效率和代码质量。它支持超过100种编程语言,兼容主流…...
Qt项目——Tcp网络调试助手服务端与客户端
目录 前言结果预览工程文件源代码一、开发流程二、Tcp协议三、Socket四、Tcp服务器的关键流程五、Tcp客户端的关键流程六、Tcp服务端核心代码七、客户端核心代码总结 前言 这期要运用到计算机网络的知识,要搞清楚Tcp协议,学习QTcpServer ,学…...
2021-11-10 C++蜗牛爬井进3退1求天数
缘由C大一编程题目。-编程语言-CSDN问答 int n 0, t 0;cin >> n;while ((n - 3)>0)n, t;cout << t << endl;...
玛哈特整平机:工业制造中的关键设备
在现代工业制造中,平整度是衡量材料加工质量的核心指标之一。无论是金属板材、塑料片材还是复合材料,若存在弯曲、翘曲或波浪形缺陷,将直接影响后续加工效率和成品质量。整平机(又称校平机、矫平机)作为解决这一问题的…...
LINUX419 更换仓库(没换成)find命令
NAT模式下虚拟机需与网卡处在同一个网段中吗 和VM1同个网段 会不会影响 这个很重要 是2 改成点2 倒是Ping通了 为啥ping百度 ping到别的地方 4399 倒是ping通了 准备下载httpd包 下不下来 正在替换为新版本仓库 报错 failure: repodata/repomd.xml from local: [Er…...
C# 预定义类型全解析
在 C# 编程中,预定义类型是基础且重要的概念。下面我们来详细了解 C# 的预定义类型。 预定义类型概述 C# 提供了 16 种预定义类型,包含 13 种简单类型和 3 种非简单类型。所有预定义类型的名称都由全小写字母组成。 预定义简单类型 预定义简单类型表…...
【仓颉 + 鸿蒙 + AI Agent】CangjieMagic框架(16):ReactExecutor
CangjieMagic框架:使用华为仓颉编程语言编写,专门用于开发AI Agent,支持鸿蒙、Windows、macOS、Linux等系统。 这篇文章剖析一下 CangjieMagic 框架中的 ReactExecutor。 这个执行器名字中的"React"代表"Reasoning and Acti…...
13.第二阶段x64游戏实战-分析人物等级和升级经验
免责声明:内容仅供学习参考,请合法利用知识,禁止进行违法犯罪活动! 本次游戏没法给 内容参考于:微尘网络安全 上一个内容:12.第二阶段x64游戏实战-远程调试 效果图: 如下图红框,…...
Linux疑难杂惑 | 云服务器重装系统后vscode无法远程连接的问题
报错原因:本地的known_hosts文件记录服务器信息与现服务器的信息冲突了,导致连接失败。 解决方法:找到本地的known_hosts文件,把里面的所有东西删除后保存就好了。 该文件的路径可以在报错中寻找:比如我的路径就是&a…...
使用EXCEL绘制平滑曲线
播主播主,你都多少天没更新了!!!泥在干什么?你还做这个账号麻?!!! 做的做的(哭唧唧),就是最近有些忙,以及…… 前言&…...
你的电脑在开“外卖平台”?——作业管理全解析
你的电脑在开“外卖平台”?——作业管理全解析 操作系统系列文章导航(点击跳转) 程序员必看:揭开操作系统的神秘面纱 :从进程、内存到设备管理,全面解析操作系统的核心机制与日常应用。告别电脑卡顿&#x…...