5、Spring AI(MCPServer+MCPClient+Ollama)開發環境搭建_第一篇

前言:

該開發環境是在?3、后端持久化(SpringBoot3.5.0+MybatisPlus3.5.5+mysql8.4.0)環境搭建

上進行改造的,用到了后端持久化,主要改造的地方為數據庫把email字段改為height(身高),該開發環境主要是設計了一個灌籃高手籃球經理對球隊成員簡單的查詢,通過這個場景把MCPServer、MCPClient、大模型、用戶客戶端相互的職責和關系簡單捋一下,其他的改造和實現一邊貼代碼一邊解釋

1、數據庫表結構

數據庫表結構以及數據初始化、user_info表

ET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;-- ----------------------------
-- Table structure for user_info
-- ----------------------------
DROP TABLE IF EXISTS `user_info`;
CREATE TABLE `user_info`  (`id` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT 'ID主鍵',`user_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '用戶名',`sex` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '性別',`hobby` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '愛好',`special_skill` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '特長',`score` int(0) NULL DEFAULT NULL COMMENT '評分',`height` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '身高',PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci ROW_FORMAT = Dynamic;-- ----------------------------
-- Records of user_info
-- ----------------------------
INSERT INTO `user_info` VALUES ('3830a6dcd94e60e41e491a8701e10a48', '流川楓', '男', '睡覺', '大前鋒', 98, '187cm');
INSERT INTO `user_info` VALUES ('463097bd7d06c7fbf709c40207c356c3', '牧紳一', '男', '未知', '后衛', 98, '184cm');
INSERT INTO `user_info` VALUES ('552cef7ea26dcb134623891417527cff', '櫻木花道', '男', '赤木晴子', '大前鋒', 97, '188cm');
INSERT INTO `user_info` VALUES ('6ebee37985f6cdf0ff6e7520c5441616', '仙道彰', '男', '釣魚', '小前鋒', 98, '190cm');
INSERT INTO `user_info` VALUES ('716bd21e54e5964058e4b9ad78cbaca3', '宮城良田', '男', '井上彩子', '后衛', 96, '168cm');
INSERT INTO `user_info` VALUES ('821a92f51a87be2d5d052e10a7223e70', '三井壽', '男', '三分球', '小前鋒', 98, '184cm');
INSERT INTO `user_info` VALUES ('9f5553b0b67821bae5b5869fc8ff3a69', '赤木晴子', '女', '籃球迷', '啦啦隊', 60, '156cm');
INSERT INTO `user_info` VALUES ('af2ab75e939b5cff8a95569b306be911', '井上彩子', '女', '宮城良田', '籃球經理', 70, '163cm');
INSERT INTO `user_info` VALUES ('d3f967929558b8c834396dd8aaa24e24', '澤北榮治', '男', '打籃球', '小前鋒', 98, '186cm');
INSERT INTO `user_info` VALUES ('e6bf09db5717d9c60af41c9dde65f0d6', '赤木剛憲', '男', '吃香蕉', '中鋒', 97, '199cm');SET FOREIGN_KEY_CHECKS = 1;

該表中存儲了一些球員的基本信息,以便籃球經理查看

2、MCPServer搭建

(1)pom.xml文件

該文件在之前??3、后端持久化(SpringBoot3.5.0+MybatisPlus3.5.5+mysql8.4.0)環境搭建

的基礎上改動不多,整體如下:

<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.everything.autotest</groupId><artifactId>spring_ai_project</artifactId><version>1.0-SNAPSHOT</version><properties><maven.compiler.source>17</maven.compiler.source><maven.compiler.target>17</maven.compiler.target><java.version>17</java.version><spring-boot.version>3.5.0</spring-boot.version><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.5.0</version></parent><dependencies><!-- mcp-server-webmvc --><dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-starter-mcp-server-webmvc</artifactId><version>1.0.0</version></dependency><!-- Web 模塊 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><exclusions><exclusion><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-logging</artifactId></exclusion></exclusions></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId><exclusions><exclusion><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-logging</artifactId></exclusion></exclusions></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><!-- MyBatisPlus --><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-spring-boot3-starter</artifactId><version>3.5.5</version></dependency><dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId></dependency><!-- Selenium WebDriver --><dependency><groupId>org.seleniumhq.selenium</groupId><artifactId>selenium-java</artifactId><version>4.31.0</version></dependency><!-- WebDriver Manager --><dependency><groupId>io.github.bonigarcia</groupId><artifactId>webdrivermanager</artifactId><version>6.1.0</version></dependency><!-- SLF4J API --><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-api</artifactId><version>2.0.9</version></dependency><!-- Log4j2核心實現包 --><dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-core</artifactId><version>2.24.3</version></dependency><!-- SLF4J與Log4j2的橋接器 --><dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-slf4j2-impl</artifactId><version>2.24.3</version><exclusions><exclusion><artifactId>log4j-core</artifactId><groupId>org.apache.logging.log4j</groupId></exclusion></exclusions></dependency></dependencies></project>

只增加了一個MCPServer的必須文件,注意版本號,使用當前最新版本Spring AI 1.0.0,如下:

<!-- mcp-server-webmvc -->
<dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-starter-mcp-server-webmvc</artifactId><version>1.0.0</version>
</dependency>

(2)application.yml文件

文件加入了Spring AI所需要的最簡參數,整體application.yml如下:

server:port: 9091
spring:ai:mcp:server:name: slamdunk-mcp-serverversion: 1.0.0sse-endpoint: /sse/slamdunk-mcp-serverdatasource:url: jdbc:mysql://localhost:3306/everythingtest?useUnicode=true&characterEncoding=utf8&characterSetResults=utf8username: rootpassword: 1234driver-class-name: com.mysql.cj.jdbc.Driverdebug: true
mybatis-plus:mapper-locations: classpath:mapper/*.xmlglobal-config:db-config:id-type: ASSIGN_UUIDfield-strategy: NOT_EMPTYdb-type: MYSQLconfiguration:map-underscore-to-camel-case: truecall-setters-on-nulls: truelog-impl: org.apache.ibatis.logging.stdout.StdOutImpl

MCPServer的yml文件配置唯一注意的一點就是sse-endpoint: /sse/slamdunk-mcp-server

sse-endpoint這個參數需要在代碼里做一些特殊處理才能生效,處理完成后MCPClient調用時才不會報404錯誤

(3)java文件

UserInfoMCPServerFacade.java

package com.everything.autotest.demo.mcpserverdemo;import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.everything.autotest.demo.mybatisplus3demo.UserInfo;
import com.everything.autotest.demo.mybatisplus3demo.userinfo.UserInfoService;
import org.springframework.ai.tool.annotation.Tool;
import org.springframework.ai.tool.annotation.ToolParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import java.util.List;@Service
public class UserInfoMCPServerFacade {@AutowiredUserInfoService userInfoService;@Tool(name = "getInfo", description = "根據球員姓名獲取某個球員的詳細信息")public UserInfo getInfo(@ToolParam(description = "球員姓名") String userName) throws Exception {var userInfoQueryWrapper = new QueryWrapper<UserInfo>();userInfoQueryWrapper.like("user_name", userName);return userInfoService.getOne(userInfoQueryWrapper);}@Tool(name = "getList", description = "獲取所有球員信息")public List<UserInfo> getList() {return userInfoService.list();}
}

做一個簡單解釋:

1、簡單的可以理解為這個類相當于之前的Controller層,之前的Controller層的參數是從頁面或者第三方的restful調用過來,現在改為從MCPClient客戶端調用;調過來之后,后面處理的邏輯不變,依然是調用UserInfoService層來查詢數據庫和處理邏輯并返回到UserInfoMCPServerFacade

2、為什么這個類名后綴起成Facade,因為目前也沒啥標準規范,個人理解是,如果起名成Controller感覺有點怪怪的,如果起名成Service又和對應持久化層的Service有點混淆,所以干脆起成門面(Facade),這樣也有面子。

3、關于注解,及api使用方法會在后面更細節的分析,這篇先把運行環境搭起來

SlamDunkMCPRegisterConfiguration.java

package com.everything.autotest.demo.mcpserverdemo;import org.springframework.ai.tool.ToolCallbackProvider;
import org.springframework.ai.tool.method.MethodToolCallbackProvider;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class SlamDunkMCPRegisterConfiguration {@Beanpublic ToolCallbackProvider userInfoTools(UserInfoMCPServerFacade userInfoMCPServerFacade){return MethodToolCallbackProvider.builder().toolObjects(userInfoMCPServerFacade).build();}
}

把UserInfoMCPServerFacade搞進來

SlamDunkMCPServerConfig.java

package com.everything.autotest.demo.mcpserverdemo;import com.fasterxml.jackson.databind.ObjectMapper;
import io.modelcontextprotocol.server.transport.WebMvcSseServerTransportProvider;
import org.springframework.ai.mcp.server.autoconfigure.McpServerProperties;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.web.servlet.function.RouterFunction;
import org.springframework.web.servlet.function.ServerResponse;@Configuration
public class SlamDunkMCPServerConfig {@Bean@Primarypublic WebMvcSseServerTransportProvider webMvcSseServerTransportProvider(ObjectProvider<ObjectMapper> objectMapperProvider, McpServerProperties serverProperties) {ObjectMapper objectMapper = objectMapperProvider.getIfAvailable(ObjectMapper::new);return new WebMvcSseServerTransportProvider(objectMapper, serverProperties.getSseMessageEndpoint(),serverProperties.getSseEndpoint());}@Beanpublic RouterFunction<ServerResponse> mvcMcpRouterFunction(WebMvcSseServerTransportProvider transportProvider) {return transportProvider.getRouterFunction();}}

SlamDunkMCPServerConfig.java這個類完全就是為了讓sse-endpoint這個參數生效,其實可以不配sse-endpoint這個參數也行,但是感覺配出來高大上一點;

通過以上配置MCPServer就搭建完畢了,運行起來,瀏覽器輸入

http://localhost:9091/sse/slamdunk-mcp-server

如果界面是這樣,說明mcpServer配置成功

MCPServer搭建成功

3、MCPClient搭建

MCPClient和MCPServer是兩個不同的工程,最好不要寫在一個工程里分兩個Model,這樣容易串端口

在這之前,首先參考??4、大模型本地運行環境搭建?把本地大模型搭起來

然后瀏覽器輸入?http://localhost:11434/?如果顯示下圖,則說明大模型運行成功

(1)pom.xml文件

文件必要依賴如下:

<!-- mcp-client -->
<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-ollama</artifactId>
</dependency>
<dependencyManagement><dependencies><dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-bom</artifactId><version>1.0.0</version><type>pom</type><scope>import</scope></dependency></dependencies>
</dependencyManagement>

以上配置我不確定能不能生效,因為對于Client配置我改了很多次,又沒有重新install可能會有緩存,如果不生效或者有問題,請參考Server的配置,把版本號顯示寫

還是要注意:Spring AI的版本號一定要選1.0.0版本,當前最新版

(2)application.yml文件

server:port: 9100
spring:ai:ollama:base-url: http://localhost:11434chat:model: llama3.2mcp:client:enabled: truename: slamdunk-mcp-clientversion: 1.0.0
#        request-timeout: 30stype: syncsse:connections:server1:url: http://localhost:9091sse-endpoint: /sse/slamdunk-mcp-servertoolcallback:enabled: true

這里的sse-endpoint: /sse/slamdunk-mcp-server與服務器保持一致(注意:一定要用1.0.0版,別用M版本

(3)java文件

SlamDunkClientConfig.java

package com.gempharmatech.mcpclient;import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.client.advisor.SimpleLoggerAdvisor;
import org.springframework.ai.ollama.OllamaChatModel;
import org.springframework.ai.tool.ToolCallbackProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class SlamDunkClientConfig {@Autowiredprivate OllamaChatModel ollamaChatModel;@Autowiredprivate ToolCallbackProvider toolCallbackProvider;@Beanpublic ChatClient chatClient() {StringBuilder sb = new StringBuilder();sb.append("你是一個籃球經理,需要對籃球隊內的一切事務所處判斷和決策。");sb.append("根據球員姓名獲取某個球員的詳細信息。");sb.append("獲取所有球員信息。");sb.append("最后,可以通過詼諧幽默的方式回答出問題,重點是詼諧幽默,可以允許你自由發揮");return ChatClient.builder(ollamaChatModel).defaultSystem(sb.toString()).defaultAdvisors(new SimpleLoggerAdvisor()).defaultToolCallbacks(toolCallbackProvider).build();}
}
 

SlamDunkMCPClintController.java?

package com.gempharmatech.mcpclient;import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.annotation.Resource;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;@RestController
public class SlamDunkMCPClintController {@Resourceprivate ObjectMapper objectMapper;@Resourceprivate ChatClient chatClient;@PostMapping("/slamdunk/gogogo")public String getInfo(@RequestBody String jsonData) throws Exception {var node = objectMapper.readTree(jsonData);var message = node.get("message").asText();return chatClient.prompt().user(message).call().content();}
}

MCPClient搭建成功

4、整體測試各種場景

首先:說明一下UserInfoService中的兩個查詢方法

(1)數據庫列表全查,調用MybatisPlus封裝好的list()接口全查

(2)根據userName模糊查詢

(1)postman中輸入"把球員名字叫流川楓的信息詼諧幽默的展示一下"

感覺還行,這個大模型呆萌呆萌的

(2)postman中輸入"查詢分數排名前五的球員信息,每個人的信息一行展示"

從這個結果看,大模型雖然只返回給5條,但是并沒有按照分數最高的5個人返回,這一點可以在后面優化,讓大模型能更深入的理解返回正確結果

(3)postman中輸入"查詢性別是女性的球員信息,每個人的信息一行展示"

這個怎么說呢,大模型開起車來也是棒棒的,其實這個llama3.2大模型才2G,另外就是給大模型的指令可以更精細化,后面文章會講到,當前能做到這樣已經很不錯了,主要是萌新,后期會換個厲害點的模型

以上就是Spring AI(MCPServer+MCPClient+Ollama)開發環境搭建的第一篇,搭建完畢,大家也大致了解幾個組件之間的調用順序和配合關系了吧,下期見

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/83574.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/83574.shtml
英文地址,請注明出處:http://en.pswp.cn/web/83574.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

個典型的 Java 泛型在反序列化場景下“類型擦除 + 無法推斷具體類型”導致的隱性 Bug

今天遇到一個問題&#xff1a;一個典型的 Java 泛型在反序列化場景下“類型擦除 無法推斷具體類型”導致的隱性 Bug&#xff0c;尤其是在 RPC&#xff08;如 Dubbo、Feign 等&#xff09;和 本地 JVM 內直連調用共存時&#xff0c;這種問題會顯現得非常明顯。 A 服務暴露了一…

開發指南121-微服務的彈性伸縮

平臺的后臺服務表現形式就是各種各樣的微服務。微服務可以部署在不同的機器上。單一服務的伸縮很簡單&#xff1a; 部署在不同機器上&#xff0c;直接啟動關閉即可。 部署在同一機器上&#xff0c;可以復制為多個不同目錄&#xff0c;其中jar包&#xff0c;啟動文件是完全一樣…

【C++特殊工具與技術】優化內存分配(六):運行時類型識別

目錄 一、RTTI 的核心機制與設計背景 1.1 RTTI 的設計目標 1.2 RTTI 的啟動條件 二、dynamic_cast&#xff1a;動態類型轉換 2.1 語法與核心特性 2.2 轉換場景詳解 2.3 引用類型轉換與異常處理 2.4 性能注意事項 三、typeid&#xff1a;類型信息查詢 3.1 語法與核心特…

USB串口通信、握手協議、深度學習等技術要點

基于OpenMV的智能車牌識別系統&#xff1a;從硬件到算法的完整實現 前言 本文將詳細介紹一個基于OpenMV微控制器的智能車牌識別系統的設計與實現。該系統集成了嵌入式視覺處理、串口通信協議、深度學習OCR識別等多種技術&#xff0c;實現了從圖像采集到車牌識別的完整流程。 …

獵板PCB:手機主板pcb需要做哪些可靠性測試

在智能手機高度普及的今天&#xff0c;一塊指甲蓋大小的主板承載著通信、計算、影像等核心功能。當消費者為新機性能歡呼時&#xff0c;鮮少有人關注到主板PCB&#xff08;印刷電路板&#xff09;在幕后經歷的嚴苛考驗。這些隱藏在金屬外殼下的精密線路&#xff0c;需要經過多輪…

Java并發編程實戰 Day 21:分布式并發控制

【Java并發編程實戰 Day 21】分布式并發控制 文章簡述&#xff1a; 在高并發和分布式系統中&#xff0c;傳統的線程級鎖已無法滿足跨節點的同步需求。本文深入講解了分布式并發控制的核心概念與技術方案&#xff0c;包括分布式鎖、一致性算法&#xff08;如Paxos、Raft&#x…

C語言文件操作與預處理詳解

目錄 文件操作文件基本概念文件指針文件打開模式文件讀取操作字符讀取字符串讀取格式化讀取二進制讀取 文件寫入操作字符寫入字符串寫入格式化寫入二進制寫入 文件定位操作文件錯誤處理 預處理預處理基本概念常見預處理指令文件包含指令宏定義簡單宏帶參數的宏字符串化操作符(#…

水庫大壩安全監測之滲流監測

水庫大壩的滲流狀況直接關系到其結構穩定性與安全運行。滲流可能引發壩體內部土體的滲透變形&#xff0c;如管涌、流土等現象&#xff0c;削弱壩體強度&#xff0c;嚴重時甚至導致大壩垮塌&#xff0c;威脅下游人民生命財產安全。通過滲流監測&#xff0c;能夠實時掌握壩體及壩…

windows使用命令行查看進程信息

在 Windows 操作系統中&#xff0c;您可以使用多種命令行工具來查看進程信息。以下是幾種常用方法&#xff1a; 1. 使用 tasklist 命令&#xff08;最常用&#xff09; 查看所有進程的基本信息&#xff1a; tasklist輸出示例&#xff1a; 映像名稱 PID…

【C#】多級緩存與多核CPU

多級緩存&#xff08;如CPU的L1/L2/L3緩存&#xff09;與多核處理器之間存在緊密的協同與競爭關系&#xff0c;直接影響系統性能。以下是關鍵影響及優化策略&#xff1a; 一、緩存層級與多核的協作機制 緩存結構 L1緩存 私有緩存&#xff1a;每個CPU核心獨享&#xff0c;容量小…

PostgreSQL的擴展adminpack

PostgreSQL的擴展adminpack adminpack 是 PostgreSQL 提供的一個管理擴展&#xff0c;它包含多個實用函數&#xff0c;幫助數據庫管理員執行文件系統操作和維護任務。這個擴展通常由數據庫超級用戶使用&#xff0c;提供了一些服務器端的文件訪問功能。 一、adminpack 擴展概述…

Unity | AmplifyShaderEditor插件基礎(第九集:旗子進階版)

目錄 一、&#x1f44b;&#x1f3fb;前言 二、準備工作 1.下載安裝插件ProBuilder 2.下載安裝插件Polybrush 3.固定原理 4.旗子 三、頂點上色 1.創建一個可以頂點上色的材質 2.開始上色 a.上色功能說明 b.全部上色 c.調整刷子 四、shader的設置 1.幅度添加 2.頂…

Java 實現 Excel 轉化為 PDF

引言 在實際開發中&#xff0c;將 Excel 文件轉化為 PDF 格式是一項常見需求。例如在需要共享數據報表時&#xff0c;PDF 格式具有更好的兼容性和安全性。GrapeCity Documents for Excel&#xff08;GcExcel&#xff09;為 Java 開發者提供了強大的工具&#xff0c;可輕松實現…

Spring Boot3批式訪問Dify聊天助手接口

Spring Boot3批式訪問Dify聊天助手接口 前言 之前已經配置好Dify1.4.1及LM Studio集成&#xff1a; https://lizhiyong.blog.csdn.net/article/details/148607462 現在就可以借助Spring Boot3去訪問Dify的后端接口&#xff0c;讓前端展示大模型的返回內容。這是我等大數據資…

事務傳播行為詳解

一、事務傳播行為的基本概念 事務傳播行為是Spring 框架中事務管理的核心概念&#xff0c;用于定義當一個事務方法被另一個事務方法調用時&#xff0c;事務應如何傳播。通俗地說&#xff0c;它解決了 “多個事務方法嵌套調用時&#xff0c;新方法是加入現有事務還是創建新事務…

Java八股文——Spring「SpringMVC 篇」

MVC分層介紹一下 面試官您好&#xff0c;MVC是一種非常經典、影響深遠的軟件設計模式&#xff0c;它的全稱是Model-View-Controller。在我看來&#xff0c;它的核心目標就是解決早期Web開發中&#xff0c;業務邏輯、數據和界面顯示高度耦合的問題&#xff0c;從而實現“各司其…

FreeSWITCH mod_curl 和 mod_xml_rpc 測試

編輯 /usr/local/freeswitch/conf/autoload_configs/xml_rpc.conf.xml <configuration name"xml_rpc.conf" description"XML RPC"> <settings> <param name"http-port" value"8889"/> <param name&quo…

實時監控、秒級決策:鏡舟科技如何重塑融資融券業務數據處理模式

融資融券業務作為證券市場的重要組成部分&#xff0c;已成為金融機構核心業務增長點和利潤來源。截至 2023 年底&#xff0c;我國融資融券余額已突破 1.8 萬億元&#xff0c;業務量呈現爆發式增長。然而&#xff0c;在業務高速發展的同時&#xff0c;金融機構面臨著數據處理效率…

Linux與量子計算:面向未來的架構演進

Linux與量子計算&#xff1a;面向未來的架構演進 當經典計算遇上量子革命 引言&#xff1a;量子計算時代的黎明 量子計算正從理論走向工程實踐&#xff0c;Linux作為現代計算的基石&#xff0c;正在量子革命中扮演關鍵角色。據IBM預測&#xff0c;到2027年&#xff0c;量子優勢…

Java中wait()為何必須同步調用?

在 Java 中&#xff0c;wait() 方法必須在 synchronized 方法或代碼塊中調用&#xff0c;主要原因如下&#xff1a; 1. 監視器鎖&#xff08;Monitor&#xff09;機制 依賴對象鎖&#xff1a;wait() 方法需要操作對象的監視器鎖&#xff08;Monitor&#xff09;&#xff0c;調…