spring AI 的簡單使用

1. 引入

Spring 官?推出的?個穩定版??智能(AI)集成框架. 旨在幫助 Java/Spring 開發者更便捷地在企業級應?中集成 AI 能? (如?語?模型、機器學習、向量數據庫、圖像?成等)。
它主要提供了以下功能:
? ?持主要的AI模型提供商, ?如 Anthropic、OpenAI、Microsoft、Amazon、Google 和 Ollama, 此外它?持的模型種類也?常多, ?如: 聊天模型, 嵌?模型, 圖像模型, ?頻模型, 內容審核等.
? 跨 AI 提供商的可移植 API ?持. ?持聊天 (Chat) , ?本到圖像 (text-to-image) 和嵌?(Embedding) 模型的統?接?, 同時提供同步和流式 API 選項. ?持訪問模型特定功能.
總之, Spring AI 為 ?AI專家的開發者也能快速調??語?模型, 提供了構建 AI 應?的基礎抽象層, 允許開發?員通過極少的代碼修改即可輕松替換組件, 簡化集成了AI功能的應?程序開發。
spring AI 官網 鏈接

2. 術語介紹

2.1 模型

模型是人工智能系統的核心組件,通過算法和大量數據訓練而成,能夠執行特定任務,如預測、分類或生成內容,?如ChatGPT、DeepSeek、通義千問等等. 每種模型能?不同, 適合的任務也不同。
我們給模型的叫 輸入;模型返回給我們的叫 輸出

Spring AI 的能讓我們在 Java/Spring 應?中, 能更方便地:① 選擇不同的 模型 ;
② 構造和發送 輸? (Prompt) ;③接收并處理 輸出 (AI 的響應) 。

2.2 LLM

LLMLarge Language Model 大語言模型,也稱?型語?模型。是??智能模型中專?處理?本的?種類型, 屬于語?模型的范疇。
特點是:規模龐?, 參數數量通常在數百億到萬億級別。
以下是幾個代表模型:
? GPT-5(OpenAI)
? ?持 128K?上下?(128K token的上下文長度大約可以支持128,000個漢字) , 在多輪復雜推理、創意寫作中表現突出
? DeepSeek R1(深度求索)
? 開源, 專注于邏輯推理與數學求解, ?持128K?上下?和多語? (20+語?) , 在科技領域表現突出
? Qwen2.5-72B-Instruct (阿?巴巴)
? 通義千問開源模型家族重要成員, 擅?代碼?成結構化數據 (如JSON) 處理??扮演對話等, 尤其適合企業級復雜任務, ?持包括中?英?法語等29種語?
? Gemini 2.5 Pro (Google)
? 多模態融合標桿 , ?持圖像/代碼/?本混合輸?, 適合跨模態任務 (如圖??成、技術?檔解析)

2.3 提示詞

提示詞是用戶或系統提供給大語言模型 (LLM) 的指令或文本 ,用于引導模型生成特定輸出。
用戶提示詞:我們使用 ai 工具時,發給 它 的文字,文件等就屬于 用戶提示詞。
系統提示詞:一般是開發者預設的,它 對 ai 進行了行為預設,劃定邊界等,像你使用 ai 時,它告訴你問題暫時不能回答之類的,就是受到了系統提示詞的規范。

2.4 詞元

詞元(即 Token)是自然語言處理(NLP)中的基本單位,指文本分割后的最小語義單元。使文本被拆解為模型可理解的離散單元.。

詞元具體形式取決于分詞策略,可以是單詞、子詞(Subword)、字符或符號。例如,英文句子“I love NLP”可能被拆分為詞元 [“I”, “love”, “NLP”],而中文句子“我喜歡NLP”可能被拆分為 [“我”, “喜歡”, “NLP”]。不同模型的分詞策略不同, 同一個詞在不同模型中可能被拆分成不同詞元。

前面的 模型的上下文 (如128K) 指的就是詞元數量限制, 此外,如果充值使用 AI 的 API,就會知道收費通常按詞元數計費。 詞元數越多, 計算耗時和內存占用越?,因此在使用時, 應盡量避免冗余詞(如請, 謝謝) ,這樣不僅能省錢,還可以給 AI 減負。

3. Spring AI 快速入門

3.1 環境要求

JDK 要至少 JDK17 或以上版本。
Spring Boot 版本至少 3.2 以上。
IDEA 使用 專業版。

3.2 條件準備

3.2.1 deepseek api 申請

DeepSeek 網址
在這里插入圖片描述
進入 API 開放平臺,先進行充值(1 塊錢一般就夠用了)。
在這里插入圖片描述

然后在 API keys 中進行 API 申請。
注意:這里要記住 API keys,因為它只在創建時顯示,后面都不顯示了。如果,手太快點了關閉,沒有記住那就再申請一個。
此外,別人如果知道了你的 API key 也是可以使用的,所有要妥善報存。

3.2.2 阿里云百煉平臺API-KEY 申請

阿里云百煉平臺 API 申請,
按照網頁說明進行申請,新人有 百萬 token 的免費額度
在這里插入圖片描述

3.3 基于 deepseek 的簡單使用

Spring AI 為OpenAI及兼容的API服務(如DeepSeek)設計了Starter spring-ai-openaispring-boot-starter , 用于快速集成大語?模型能力到 Spring Boot 應用中.
核心價值包括:
? 簡化配置:自動動封裝 OpenAI API 的請求/響應等邏輯
? 統?接口:提供 ChatClient 等標準化接口, 支持無縫切換不同模型提供商
? Spring ?態集成:與 Spring Boot 的?動配置、依賴注?等特性深度整合

3.3.1 項目創建

Spring AI 中
在這里插入圖片描述
在這里插入圖片描述

3.3.2 配置文件設置

這里用的 .yml 進行配置,不是 .properties

spring:ai:openai:api-key: sk-your-key  #你申請的 api keybase-url: https://api.deepseek.comchat:options:model: deepseek-chat  #使用的 deepseek 模型temperature: 0.7  
#在AI模型的temperature參數中,值的大小直接影響生成文本的特性:
#較低值(如0.1-0.3):輸出更加確定性和保守,傾向于選擇最高概率的詞匯,適合需要準確性和一致性的場景
#中等值(如0.4-0.7):在創造性和可靠性之間取得平衡,會產生適度變化的輸出
#較高值(如0.8-1.0):輸出更加隨機和創造性,適合需要多樣性和新穎性的場景
#您當前設置的0.7屬于中等偏高,會使模型輸出有一定創造性但不會過于隨機

3.3.3 ChatModel 使用

package com.example.saidemo;import org.springframework.ai.openai.OpenAiChatModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
@RequestMapping("/dp")
public class DPChat {@AutowiredOpenAiChatModel openAiChatModel;@RequestMapping("/chat")public String chat(String message){//call() 調用AIreturn openAiChatModel.call(message);}
}

前面說過,deepseek 的 API 是兼容的,這里使用 OpenAiChatModel
使用示例:
在這里插入圖片描述

3.3.4 ChatClient 使用

ChatModel 屬于底層接口,而 ChatClient 則是高階接口,它基于 ChatModel 進行了再次封裝。ChatClient 使用鏈式調用,可讀性更強。

簡單對話

@RestController
@RequestMapping("/dp")
public class DPChat {private final ChatClient chatClient;public DPChat(ChatClient.Builder chatClientBuilder) {this.chatClient = chatClientBuilder.build();}@RequestMapping("/chat2")public String chat2(String message){return chatClient.prompt().user(message).call().content();}
}

ChatClient 不支持使用用 @Autowired 進行直接注入,需要調用 ChatClient.Builder 下的 build() 才可以。
使用示例:
在這里插入圖片描述
角色預設
為了方便后續使用,我們將 ChatClient 單獨定義。

package com.example.saidemo;import org.springframework.ai.chat.client.ChatClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class ChatClientConfig {@Beanpublic ChatClient chatClient(ChatClient.Builder chatClientBuilder){return chatClientBuilder.build();}
}

這樣后面就可以直接使用 @Autowired 進行注入。

回顧前文,我們知道系統提示詞能夠對模型進行預設,為它指定規范。所以,這里的角色預設就是設置 系統提示詞
操作如下:

package com.example.saidemo;import org.springframework.ai.chat.client.ChatClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class ChatClientConfig {@Beanpublic ChatClient chatClient(ChatClient.Builder chatClientBuilder){return chatClientBuilder.defaultSystem("你叫小明,你是一個不專業的寫信者").build();}
}

使用 defaultSystem() 進行設置。
使用示例:
在這里插入圖片描述
結構化輸出
就是當你輸入提示詞后, AI 根據你所規定的結構,進行回答。
首先,我們使用JDK16提供的新關鍵詞 record 來定義?個實體類

    record Recipe(String dish, List<String> ingredients) {}

通過 entity() ?法將模型輸出轉為自定義實體,(模型會自動匹配并填充)。

package com.example.saidemo;import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.openai.OpenAiChatModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import java.util.List;@RestController
@RequestMapping("/dp")
public class DPChat {@AutowiredChatClient chatClient;record Recipe(String dish, List<String> ingredients) {}@RequestMapping("/chat3")public String chat1(String message){Recipe recipe = chatClient.prompt().user(String.format("請根據用戶的描述,生成一個菜譜。用戶的描述是:%s", message)).call().entity(Recipe.class);return recipe.toString();}
}    

使用示例:
在這里插入圖片描述
流式輸出
運行之前的代碼,你會發現和常用的 AI 工具不同,它是直接將完整結果發送過來,這就導致用戶等待時間過長。想要和使用的 AI 工具的輸出效果相同,就要采用流式輸出,逐步生成內容而非一次性返回完整結果。

package com.example.saidemo;import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.openai.OpenAiChatModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Flux;import java.util.List;@RestController
@RequestMapping("/dp")
public class DPChat {@AutowiredChatClient chatClient;@RequestMapping("/chat4")public Flux<String> chat1(String message){return chatClient.prompt().user(String.format("請根據用戶的描述,生成一個菜譜。用戶的描述是:%s", message)).stream().content();}
}

直接運行,你會發現輸出結果為亂碼:
在這里插入圖片描述
這是因為沒有對輸出結果的類型進行設置,對 @RequestMapping("/chat4") 進行如下修改,就能夠正確輸出了。

    @RequestMapping(value = "/chat4" ,produces = "text/html;charset=utf-8")

運行結果:
在這里插入圖片描述
(流式效果不好展示,這里只展示最終效果,感興趣的可以自己試一試)

打印日志
Spring AI 借助Advisors 來實現日志打印的功能.。

Advisors 是基于 AOP思想實現的, 在具體實現上進行了領域適配. 其設計核心借鑒了Spring AOP 的攔截機制, 各個Advisor以鏈式結構運?,序列中的每個Advisor都有機會對傳入的請求和傳出的響應進行處理。 這種鏈式處理機制確保了每個Advisor可以在請求和響應流中添加自己的邏輯, 從而實現更靈活和可定制的功能。如下圖:
在這里插入圖片描述
主要應用場景:
? 敏感詞過濾
? 建?聊天歷史
? 對話上下?管理

可以直接在Config 中添加,那么后續使用 ChatClient 都會有。

package com.example.saidemo;import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.client.advisor.SimpleLoggerAdvisor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class ChatClientConfig {@Beanpublic ChatClient chatClient(ChatClient.Builder chatClientBuilder){return chatClientBuilder.defaultSystem("你叫小明,你是一個不專業的寫信者").defaultAdvisors(new SimpleLoggerAdvisor()).build();}
}

同樣,也可以在單個接口中添加,僅對這一個起作用:

@RestController
@RequestMapping("/dp")
public class DPChat {@AutowiredChatClient chatClient;@RequestMapping(value = "/chat4" ,produces = "text/html;charset=utf-8")public Flux<String> chat1(String message){return chatClient.prompt().user(String.format("請根據用戶的描述,生成一個菜譜。用戶的描述是:%s", message)).advisors(new SimpleLoggerAdvisor()).stream().content();}
}

3.3.5 ChatModel 拓展

Ctrl + 左鍵進入之前代碼中的 call() 方法,會發現它調用了 參數類型為 Promptcall() 方法。

接下來使用 Prompt 來使用 call() 方法。
簡單使用

    @RequestMapping("/chatByPrompt")public String chatByPrompt (String msg) {Prompt prompt = new Prompt(msg);ChatResponse response = chatModel.call(prompt);return response.getResult().getOutput().getText();}

角色預設

    @RequestMapping("/role")public String role(String msg) {SystemMessage systemMessage = new SystemMessage("你叫dp,是對話ai機器人");UserMessage userMessage = new UserMessage(msg);Prompt prompt = new Prompt(userMessage,systemMessage);ChatResponse response = chatModel.call(prompt);return response.getResult().getOutput().getText();}

流式響應

    @RequestMapping(value = "/stream" ,produces = "text/html;charset=utf-8"  )public Flux<String> stream (String msg) {Prompt prompt = new Prompt(msg);Flux<ChatResponse> response = chatModel.stream(prompt);return response.map(x->x.getResult().getOutput().getText());}

.map(x->x.getResult().getOutput() .getText()) 方法,用于操作流中元素。
基于代碼可知,chatModel.stream(prompt); 的返回類型為 Flux<ChatResponse>。你可以理解為 response (流) 是一輛列車,是由很多節組成的連續一長串,這每一節都是 類型為 ChatResponse 的元素。

map 方法則是操作每一節,并返回生成新的 流,且不改變原流。這里 x 就代指 response 中的元素(也可以使用其他字母來代指),x 經過 getResult().getOutput().getText() 就變成了 String 類型,所以新的流就是 Flux<String> 類型。

3.3.6 Client & Model 對比

維度ChatModelChatClient
交互?式?動構建Prompt, 解析響應鏈式API, ?動封裝請求與響應
結構化輸出?動解析?本?持 .entity(Class) ?動映射POJO
擴展能?依賴外部組件內置Advisor機制, 提供更?級的功能, 如提供上下?記憶, RAG等功能
適合場景適合需要精細控制模型參數的場景, ?如模型實驗, 參數調優等定制需求適合快速構建AI服務, 如帶記憶的客服系統

3.4 流式編程 - 資料了解

HTTP 協議本身設計為無狀態的 請求-響應模式,嚴格來說, 是無法做到服務器主動推送消息到客戶端, 但通過Server-Sent Events (服務器發送事件, 簡稱SSE)技術可實現流式傳輸,允許服務器主動向瀏覽器推送數據流。
服務器會告訴客戶端,接下來要發送的是流消息(streaming), 這時客戶端不會關閉連接,會?直等待服務器發送過來新的數據流。
SSE(Server-Sent Events)是?種基于 HTTP 的輕量級實時通信協議,瀏覽器通過內置的
EventSource API接收并處理這些實時事件。
特點:
? 基于 HTTP 協議
復?標準了 HTTP/HTTPS 協議,?需額外端?或協議,兼容性好且易于部署 。
? 單向通信機制
SSE 僅支持服務器向客戶端的單向數據推送,客戶端通過普通 HTTP 請求建?連接后,服務器可持續發送數據流,但客戶端無法通過同?連接向服務器發送數據。
? 自動重連機制
?持斷線重連,連接中斷時,瀏覽器會?動嘗試重新連接(?持 retry 字段指定重連間隔)
? 自定義消息類型
客戶端發起請求后,服務器保持連接開放, 響應頭設置 Content-Type: text/event-stream,標識為事件流格式, 持續推送事件流。

數據格式
每?次發送的消息,由若干個message組成, 每個message之間由 \n\n 分隔, 每個message內部由若干行組成, 每?行都是如下格式:

[field]: value\n

前端代碼:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>SSE</title>
</head>
<body><div id="sse"></div>
</body>
<script>let eventSource = new EventSource('/sse/data')eventSource.onmessage = function (event) {document.getElementById('sse').innerHTML = event.data;}// eventSource.addEventListener('foo', (event) => {//     document.getElementById('sse').innerHTML = event.data;// })// eventSource.addEventListener('end', (event) => {//     eventSource.close()// })
</script>
</html>

EventSource('/sse/data') 中填寫的是后端接口。
后端代碼:

package com.example.saidemo;import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Flux;import java.awt.*;
import java.io.IOException;
import java.io.PrintWriter;
import java.time.Duration;
import java.util.Date;@Slf4j
@RequestMapping("/sse")
@RestController
public class SseController {@RequestMapping("/data")public void data(HttpServletResponse response) throws IOException, InterruptedException {log.info("返回響應:  data");response.setContentType("text/event-stream;charset=utf-8");PrintWriter writer = response.getWriter();for (int i = 0; i < 10; i++) {String s = "data: " + new Date() + "\n\n";writer.write(s);writer.flush();Thread.sleep(1000L);}}@RequestMapping("/retry")public void retry(HttpServletResponse response) throws IOException, InterruptedException {log.info("返回響應:  retry");response.setContentType("text/event-stream;charset=utf-8");PrintWriter writer = response.getWriter();String s = "retry: 2000\n";s += "data: " + new Date() + "\n\n";writer.write(s);writer.flush();}@RequestMapping("/event")public void event(HttpServletResponse response) throws IOException, InterruptedException {log.info("返回響應:  event");response.setContentType("text/event-stream;charset=utf-8");PrintWriter writer = response.getWriter();for (int i = 0; i < 10; i++) {String s = "event: foo\n";  //自定義事件,對應前端注釋掉的代碼s += "data: " + new Date() + "\n\n";writer.write(s);writer.flush();Thread.sleep(1000L);}}@RequestMapping("/end")public void end(HttpServletResponse response) throws IOException, InterruptedException {log.info("返回響應:  event");response.setContentType("text/event-stream;charset=utf-8");PrintWriter writer = response.getWriter();for (int i = 0; i < 10; i++) {String s = "event: foo\n";	//自定義事件,對應前端注釋掉的代碼s += "data: " + new Date() + "\n\n";writer.write(s);writer.flush();Thread.sleep(1000L);}writer.write("event: end\ndata: EOF\n\n");}@RequestMapping(value = "/stream",produces = MediaType.TEXT_EVENT_STREAM_VALUE)public Flux<String> stream() {return Flux.interval(Duration.ofSeconds(1)) //發送間隔.map(s->new Date().toString());  }
}

自動重連的體現:
在這里插入圖片描述
運行后,訪問前端頁面,發現數字一直在改變。但實際后端 /sse/data 接口中只定義發送 10 次。這是因為當該接口的完整邏輯執行完后,進行了自動重連。

3.5 基于 Spring AI Alibaba 的簡單使用

3.5.1 項目創建

項目創建時,添加的依賴:
在這里插入圖片描述

3.5.2 配置文件設置

pom 文件的配置:

<dependencyManagement><dependencies><dependency><groupId>com.alibaba.cloud.ai</groupId><artifactId>spring-ai-alibaba-bom</artifactId><version>1.0.0.2</version><type>pom</type><scope>import</scope></dependency></dependencies>
</dependencyManagement><dependencies><dependency><groupId>com.alibaba.cloud.ai</groupId><artifactId>spring-ai-alibaba-starter-dashscope</artifactId></dependency>
</dependencies>

.yml 文件配置:

spring:ai:dashscope:api-key: #你在百煉平臺申請的 API KEYchat:options:model: qwen-vl-max-latest #模型名稱multi-model: true #是否啟?多模型

3.5.3 ChatModel 使用

由于使用類似,不同的是 這里使用 ChatModel 類,不再使用 OpenAiChatModel
所以,不再細說,只進行代碼展示和必要說明。

package com.example.salidemo;import org.springframework.ai.chat.model.ChatModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
@RequestMapping("/ali")
public class AliController {@Autowiredprivate ChatModel chatModel;@RequestMapping("/chat")public String chat(String message){return chatModel.call(message);}
}

使用示例:
在這里插入圖片描述

3.5.4 ChatClient 使用

直接使用

package com.example.salidemo;import org.springframework.ai.chat.client.ChatClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Flux;import java.util.List;@RestController
@RequestMapping("/chat")
public class ChatController {private ChatClient chatClient;public ChatController(ChatClient.Builder chatClientBuilder) {this.chatClient = chatClientBuilder.build();}@RequestMapping("/chat")public String chat(String message){return chatClient.prompt().user(message).call().content();}
}    

角色預設
這里同樣將 ChatClient 單獨遷出,并使用 @Bean 注解進行注入。

單獨類:

package com.example.salidemo;import org.springframework.ai.chat.client.ChatClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class ChatConfiguration {@Beanpublic ChatClient chatClient(ChatClient.Builder chatClientBuilder){return chatClientBuilder.defaultSystem("你是一個專業的演員,在每次回復前加上{word}").build();}
}

這里的 {word} 就相當于占位符,在實際使用時可進行替換,否則 原樣輸出。像這樣:
在這里插入圖片描述

    @RequestMapping("/word")public String word(String message,String word){return chatClient.prompt().user(message).system(sp->sp.param("word",word)).call().content();}

system(sp->sp.param("word",word)) 替換操作。sp 是Lambda表達式的參數名稱,可以自由命名,但必須與后續調用保持一致。
如果有多個參數,使用方法如下:

//鏈式調用param方法:
.system(sp -> sp.param("word1", word1).param("word2", word2).param("word3", word3))//使用Map傳遞多個參數:
Map<String, Object> params = new HashMap<>();
params.put("word1", word1);
params.put("word2", word2);
.system(sp -> sp.params(params))//使用對象封裝參數(推薦):
record WordParams(String word1, String word2) {}
.system(sp -> sp.entity(new WordParams(word1, word2)))

之前的 基于 deepseek 的ChatClient 同樣適用。

結構化輸出

    record ActorFilms(String actor, List<String> films){}@RequestMapping("/entify")public String entify(String actor){return chatClient.prompt().user(String.format("幫我生成%S參演的作品",actor)).call().entity(ActorFilms.class).toString();}

流式輸出

    @RequestMapping(value = "/stream",produces = "text/html;charset=utf-8")public Flux<String> stream(String message){return this.chatClient.prompt().user(message).stream().content();}

3.5.5 多模態的使用。

多模態性指模型同時理解和處理文本、圖像、音頻及其他數據格式等多源信息的能力。
這里展示 處理圖片的能力。

@RestController
@RequestMapping("/multi")
public class MultiController {private final ChatClient chatClient;public MultiController(ChatClient.Builder chatClientBuilder) {this.chatClient = chatClientBuilder.build();}@RequestMapping("/image")public String image(String prompt) throws URISyntaxException, MalformedURLException {String url = "https://tse4-mm.cn.bing.net/th/id/OIP-C.TCq0ItOzbTzC11dudmqMrgHaLJ?w=195&h=294&c=7&r=0&o=5&dpr=1.5&pid=1.7";//網上隨便找的網圖List<Media> mediaList = List.of(new Media(MimeTypeUtils.IMAGE_JPEG, new URI(url).toURL().toURI()));//用戶提示詞UserMessage userMessage = UserMessage.builder().text(prompt).media(mediaList).build();//調用模型String response = chatClient.prompt(new Prompt(userMessage)).call().content();return response;}
}

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

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

相關文章

圖像去霧:從暗通道先驗到可學習融合——一份可跑的 PyTorch 教程

一、為什么“去霧”依然是好課題&#xff1f; 真實需求大&#xff1a;手機拍照、自動駕駛、遙感、監控都要在惡劣天氣下成像。 數據集相對干凈&#xff1a;與通用目標檢測相比&#xff0c;去霧只有“有霧/無霧”一對圖像&#xff0c;標注成本低。 傳統與深度并存&#xff1a;…

Ubuntu 22.04.1上安裝MySQL 8.0及設置root密碼

安裝MySQL 8.0 在 Ubuntu 22.04.1 系統需要遵循幾個明確的步驟&#xff0c;并在安裝過程中配置root密碼&#xff0c;以下是詳細的過程和相關的注意事項。步驟 1: 更新系統 使用終端更新系統軟件包列表以確保所有的包是最新的。sudo apt update sudo apt upgrade步驟 2: 安裝MyS…

用?content-visibility?即刻提速:那個被你忽略的 CSS 性能杠桿

我有一支技術全面、經驗豐富的小型團隊&#xff0c;專注高效交付中等規模外包項目&#xff0c;有需要外包項目的可以聯系我&#x1f50d; 引言長頁面、信息密集、滾動遲滯&#xff1f;**content-visibility** 這項相對較新的 CSS 屬性&#xff0c;允許瀏覽器跳過視口外元素的渲…

字符串(2)

4.字符串的常見函數代碼#include <stdio.h> #include <string.h> int main() {char* str1 "abc";char str2[100] "abc";char str3[5] { q,w,e,r ,\0 };printf("---------------------strlen&#xff08;長度&#xff09;-------------…

案例分享|企微智能會話風控系統:為尚豐盈鋁業筑牢溝通安全防線

企微智能會話安全風險分析系統是一款基于企業微信原生集成的高性能處理平臺&#xff0c;其核心在于通過智能監測和AI風險識別技術&#xff0c;對員工與內外部客戶的聊天內容進行多模態分析&#xff08;涵蓋文本、圖片、語音、視頻、文件等多種形式&#xff09;&#xff0c;利用…

Paimon——官網閱讀:配置

配置(Maintenance) 系統表 表特定系統表 表特定系統表包含關于每個表的元數據和信息&#xff0c;例如創建的快照以及正在使用的選項。用戶可以通過批量查詢來訪問系統表。 目前&#xff0c;Flink、Spark、Trino 和 StarRocks 支持查詢系統表。 在某些情況下&#xff0c;表…

阿里云對象存儲OSS的使用

文章目錄注冊阿里OSS注冊并登錄阿里云賬號開通對象存儲OSS創建Bucket修改權限創建AccessKey全局存儲到你的計算機(可以跳過)查看官方文檔(可以跳過)SSM使用引入依賴在spring-mvc.xml中加入配置創建上傳工具類AliOssUtil響應工具類ResultJSON編寫controller編寫前端代碼使用Elme…

香港云主機常見使用問題匯總

本文主要為初次或正在接觸香港云主機的用戶介紹&#xff0c;對于香港云服務器的一些問題進行解答&#xff0c;幫助用戶更好的了解香港云主機&#xff0c;熟悉香港云主機。1.香港云主機是否需要備案?香港云主機無需進行像內地服務器那樣的 ICP 備案&#xff0c;可直接部署使用。…

JAVA同城打車小程序APP打車順風車滴滴車跑腿源碼微信小程序打車源碼

JAVA同城打車系統源碼&#xff1a;多端融合的智能出行生態解決方案一、市場需求與行業背景在共享經濟蓬勃發展和數字化轉型加速的背景下&#xff0c;中國同城出行市場正迎來快速增長期。2025年中國同城出行市場規模預計突破8000億元&#xff0c;年復合增長率超過25%。基于Sprin…

AI入坑: Trae 通過http調用.net 開發的 mcp server

1. 為什么要寫這個 為什么要寫這個內容&#xff0c;前幾天開始加入到ai大軍&#xff0c;通過一周的學習&#xff0c;看了國外網站、看了b站教程、看了抖音教程&#xff0c;居然發現都是開發在本地的mcp server。本地mcp沒問題&#xff0c;個人使用都ok&#xff0c;或者通過npx下…

記錄Pycharm所使用虛擬環境與終端無法對應

在anaconda安裝時&#xff0c;本文中的安裝位置在D盤&#xff0c; D:\soware\anaconda 理論環境位置 D:\soware\anaconda\envs 經檢查PATH配置均未發現錯誤&#xff0c;其次問題并不在于Pycharm的設置中解譯器與終端的設置經過多次查找未發現可用解決方案 在anaconda建立虛擬環…

國產數據庫之YashanDB:新花怒放

YashanDB&#xff08;崖山數據庫&#xff09;是由深圳計算科學研究院自主研發的一款新型關系數據庫管理系統。 YashanDB 在經典數據庫理論基礎上&#xff0c;融入了原創的有界計算、近似計算、并行可擴展和跨模融合計算理論&#xff0c;可以滿足金融、政企、能源等關鍵行業對高…

Java基礎 9.5

1.異常處理基本介紹異常處理就是當異常發生的時候 對異常處理的方式異常處理方式try-catch-finally程序員在代碼中捕獲發生的異常 自行處理throws將發生的異常拋出 交給調用者&#xff08;方法&#xff09;處理 最頂級的處理者是JVM示意圖2.try-catch方式處理異常說明Java提供t…

B.50.10.06-NoSQL數據庫與電商應用

NoSQL數據庫核心原理與電商應用實戰核心思想: NoSQL (Not Only SQL) 數據庫是為了解決傳統關系型數據庫在超大規模數據、高并發和靈活數據模型方面的不足而設計的。它們通過犧牲部分一致性&#xff08;通常是最終一致性&#xff09;和事務的嚴格性&#xff0c;來換取極高的性能…

把開發環境丟云上,我的電腦風扇再也沒轉過!

Hello&#xff0c;兄弟們&#xff0c;我來啦作為一個天天搬磚的程序員&#xff0c;每天最讓我心態爆炸的是啥&#xff1f;不是產品又改需求&#xff0c;也不是 Bug 藏得深&#xff0c;而是TMD——配&#xff01;環&#xff01;境&#xff01;新項目 git clone 下來&#xff0c;…

驅動ft232h通信

FT232H是一個單通道USB 2.0高速&#xff08;480Mb/s&#xff09;轉換為UART/FIFO IC&#xff0c;具有多種工業標準串行或并行接口配置能力。 1.實驗板卡 FPGA型號&#xff1a; FT232H型號&#xff1a; FT232H SINGLE CHANNEL HI-SPEED USB TO MULTIPURPOSE UART/FIFO IC Da…

隔空盜刷、AI釣魚、代理劫持…金融黑產竟進化至此?

【導讀】中國工商銀行發布的《2024網絡金融黑產研究報告》&#xff0c;以深度洞察拆解黑產攻擊“新變種”、勾勒防護新路徑&#xff0c;自發布以來&#xff0c;成為金融安全行業的重要參考坐標。本文會提煉出報告中黑產攻擊的五大技術演變與體系化防護思路&#xff0c;再結合金…

服務器為啥離不開傳感器?一文看懂數據中心“隱形守護者”的關鍵角色

在現代數據中心或企業機房中&#xff0c;服務器不僅僅是“跑程序”的機器&#xff0c;它們還是一整套復雜系統的一部分。為了保證這些服務器穩定、高效、安全地運行&#xff0c;傳感器成了不可或缺的角色。那么&#xff0c;服務器為啥要有傳感器&#xff1f;這些傳感器到底是干…

React JSX 語法講解

&#x1f680; React JSX 語法講解 1. 課程概述 本課程旨在系統講解 JSX&#xff08;JavaScript XML&#xff09; 的核心概念與實戰應用。JSX 是 React 的核心語法擴展&#xff0c;它允許我們在 JavaScript 中編寫類似 HTML 的結構&#xff0c;使得構建用戶界面變得直觀和高效。…

軟件安裝教程(四):在 Windows 上安裝與配置 MATLAB(超詳細)

文章目錄前言1. 安裝前準備&#xff08;必看&#xff09;2. 下載 MATLAB&#xff08;推薦在線安裝&#xff09;3. 在 Windows 上安裝&#xff08;詳細步驟&#xff09;4. 激活 MATLAB&#xff08;在線與離線&#xff09;5. 首次啟動與界面入門6. 推薦的基本配置&#xff08;讓環…