SpringAI + DeepSeek大模型應用開發 - 入門篇

?三、SpringAI

Spring AILangChain4j
Chat支持支持
Function支持支持
RAG支持支持
對話模型15+15+
向量模型10+15+
向量數據庫15+20+
多模態模型5+1
JDK178

1. 對話機器人

1.1 快速入門

步驟①:引入依賴(先去掉openai的starter依賴,因為要配置API_KEY)

<?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>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.4.3</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.itheima</groupId><artifactId>heima-ai</artifactId><version>0.0.1-SNAPSHOT</version><name>heima-ai</name><description>heima-ai</description><url/><licenses><license/></licenses><developers><developer/></developers><scm><connection/><developerConnection/><tag/><url/></scm><properties><java.version>17</java.version><spring-ai.version>1.0.0-M6</spring-ai.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-ollama-spring-boot-starter</artifactId></dependency><dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId><scope>runtime</scope></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><version>1.18.30</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency></dependencies><dependencyManagement><dependencies><dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-bom</artifactId><version>${spring-ai.version}</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>

注意將lombok的版本改為1.18.30,否則可能出現下面的錯誤

java: java.lang.NoSuchFieldError: Class com.sun.tools.javac.tree.JCTree$JCImport does not have member field 'com.sun.tools.javac.tree.JCTree qualid'

②配置模型

  • 如果用的是ollama
spring:application:name: heima-aiai:ollama:base-url: http://localhost:11434chat:model: deepseek-r1:7b
  • 如果用的是openai
spring:ai:openai:base-url: https://dashscope.aliyuncs.com/compatible-modeapi-key: ${OPENAI_API_KEY}chat:options:model: qwen-max  # 模型名稱temperature: 0.8  # 模型溫度,值越大,輸出結果越隨機

③配置客戶端

package com.itheima.ai.config;import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.ollama.OllamaChatModel;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class CommonConfiguration {@Beanpublic ChatClient chatClient(OllamaChatModel model) {return ChatClient.builder(model).defaultSystem("你是一個熱心、可愛的智能助手,你的名字叫小團團,請以小團團的身份和語氣回答問題。").build();}
}

④發起調用

package com.itheima.ai.controller;import lombok.RequiredArgsConstructor;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RequiredArgsConstructor
@RestController
@RequestMapping("/ai")
public class ChatController {private final ChatClient chatClient;@RequestMapping("/chat")public String chat(String prompt) {return chatClient.prompt().user(prompt).call().content();}
}

⑤啟動HeimaAiApplication 和 ollama 測試

http://localhost:8080/ai/chat?prompt=%E4%BD%A0%E6%98%AF%E8%B0%81

?

再次改用流式輸出進行測試:

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

?

1.2 會話日志

SpringAI利用AOP原理提供了AI會話時的攔截、增強等功能,也就是Advisor

?

①修改CommonConfiguration?

package com.itheima.ai.config;import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.client.advisor.SimpleLoggerAdvisor;
import org.springframework.ai.ollama.OllamaChatModel;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class CommonConfiguration {@Beanpublic ChatClient chatClient(OllamaChatModel model) {return ChatClient.builder(model).defaultSystem("你是一個熱心、可愛的智能助手,你的名字叫小團團,請以小團團的身份和語氣回答問題。").defaultAdvisors(new SimpleLoggerAdvisor(),).build();}
}

②在application.yaml添加日志級別

logging:level:org.springframework.ai: debugcom.itheima.ai: debug

2025-06-17T10:18:45.596+08:00 DEBUG 32052 --- [heima-ai] [oundedElastic-1] o.s.a.c.c.advisor.SimpleLoggerAdvisor ? ?: request: AdvisedRequest[chatModel=org.springframework.ai.ollama.OllamaChatModel@614e1bca, userText=你是誰, systemText=你是一個熱心、可愛的智能助手,你的名字叫小團團,請以小團團的身份和語氣回答問題。, chatOptions=org.springframework.ai.ollama.api.OllamaOptions@6913c33b, media=[], functionNames=[], functionCallbacks=[], messages=[], userParams={}, systemParams={}, advisors=[org.springframework.ai.chat.client.DefaultChatClient$DefaultChatClientRequestSpec$1@54c6b5de, org.springframework.ai.chat.client.DefaultChatClient$DefaultChatClientRequestSpec$2@7a8b4de2, SimpleLoggerAdvisor, org.springframework.ai.chat.client.advisor.MessageChatMemoryAdvisor@799e357a, org.springframework.ai.chat.client.DefaultChatClient$DefaultChatClientRequestSpec$1@681ff1c8, org.springframework.ai.chat.client.DefaultChatClient$DefaultChatClientRequestSpec$2@916c150], advisorParams={}, adviseContext={}, toolContext={}]

1.3 會話記憶

步驟①:把資料中的spring-ai-nginx壓縮包放到不含中文和特殊字符的文件夾下并解壓:

?

②通過cmd運行項目

http://localhost:5173/

?

?

③配置CORS策略

package com.itheima.ai.config;import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;@Configuration
public class MvcConfiguration implements WebMvcConfigurer {@Overridepublic void addCorsMappings(CorsRegistry registry) {registry.addMapping("/**").allowedOrigins("*").allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS").allowedHeaders("*").exposedHeaders("Content-Disposition");}
}

④測試

?


大模型是不具備記憶能力的,要想讓大模型記住之前聊天的內容,唯一的辦法就是把之前聊天的內容與新的提示詞一起發給大模型。

?

步驟①:定義會話存儲方式

  • 方式1:使用Spring官方提供的InMemoryChatMemory
  • 方式2:自己實現ChatMemory接口,把會話存儲到Redis、MongoDB等中

(1)方式1:InMemoryChatMemory

  • ②配置會話記憶Advisor
package com.itheima.ai.config;import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.client.advisor.MessageChatMemoryAdvisor;
import org.springframework.ai.chat.client.advisor.SimpleLoggerAdvisor;
import org.springframework.ai.chat.memory.ChatMemory;
import org.springframework.ai.chat.memory.InMemoryChatMemory;
import org.springframework.ai.ollama.OllamaChatModel;
import org.springframework.context.annotation.Bean;@Configuration
public class CommonConfiguration {@Beanpublic ChatMemory chatMemory() {return new InMemoryChatMemory();}@Beanpublic ChatClient chatClient(OllamaChatModel model, ChatMemory chatMemory) {return ChatClient.builder(model).defaultSystem("你是一個熱心、可愛的智能助手,你的名字叫小團團,請以小團團的身份和語氣回答問題。").defaultAdvisors(new SimpleLoggerAdvisor(),new MessageChatMemoryAdvisor(chatMemory)  // 會話記憶).build();}
}
  • ③添加會話id
    @RequestMapping(value = "/chat", produces = "text/html;charset=utf-8")public Flux<String> chat(@RequestParam("prompt") String prompt,@RequestParam("chatId") String chatId) {return chatClient.prompt().user(prompt).advisors(a -> a.param(CHAT_MEMORY_CONVERSATION_ID_KEY, chatId)).stream().content();}

(2)方式2:實現ChatMemory接口,保存到Redis中

  • 定義Msg實體類:
package com.itheima.ai.entity.po;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.ai.chat.messages.*;import java.util.List;
import java.util.Map;@NoArgsConstructor
@AllArgsConstructor
@Data
public class Msg {MessageType messageType;String text;Map<String, Object> metadata;public Msg(Message message) {this.messageType = message.getMessageType();this.text = message.getText();this.metadata = message.getMetadata();}public Message toMessage() {return switch (messageType) {case SYSTEM -> new SystemMessage(text);case USER -> new UserMessage(text, List.of(), metadata);case ASSISTANT -> new AssistantMessage(text, metadata, List.of(), List.of());default -> throw new IllegalArgumentException("Unsupported message type: " + messageType);};}
}
  • 定義ChatMemory實現類:
package com.itheima.ai.repository;import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.itheima.ai.entity.po.Msg;
import lombok.RequiredArgsConstructor;
import org.springframework.ai.chat.memory.ChatMemory;
import org.springframework.ai.chat.messages.Message;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;import java.util.List;@RequiredArgsConstructor
@Component
public class RedisChatMemory implements ChatMemory {private final StringRedisTemplate redisTemplate;private final ObjectMapper objectMapper;private final static String PREFIX = "chat:";@Overridepublic void add(String conversationId, List<Message> messages) {if (messages == null || messages.isEmpty()) {return;}List<String> list = messages.stream().map(Msg::new).map(msg -> {try {return objectMapper.writeValueAsString(msg);} catch (JsonProcessingException e) {throw new RuntimeException(e);}}).toList();redisTemplate.opsForList().leftPushAll(PREFIX + conversationId, list);}@Overridepublic List<Message> get(String conversationId, int lastN) {List<String> list = redisTemplate.opsForList().range(PREFIX + conversationId, 0, lastN);if (list == null || list.isEmpty()) {return List.of();}return list.stream().map(s -> {try {return objectMapper.readValue(s, Msg.class);} catch (JsonProcessingException e) {throw new RuntimeException(e);}}).map(Msg::toMessage).toList();}@Overridepublic void clear(String conversationId) {redisTemplate.delete(PREFIX + conversationId);}
}
  • 引入redis依賴:
        <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency>
  • 配置會話記憶advisor:
package com.itheima.ai.config;import com.fasterxml.jackson.databind.ObjectMapper;
import com.itheima.ai.repository.RedisChatMemory;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.client.advisor.MessageChatMemoryAdvisor;
import org.springframework.ai.chat.client.advisor.SimpleLoggerAdvisor;
import org.springframework.ai.chat.memory.ChatMemory;
import org.springframework.ai.chat.memory.InMemoryChatMemory;
import org.springframework.ai.ollama.OllamaChatModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.StringRedisTemplate;@Configuration
public class CommonConfiguration {@Autowiredprivate StringRedisTemplate redisTemplate;private ObjectMapper objectMapper = new ObjectMapper();@Beanpublic ChatMemory chatMemory() {return new RedisChatMemory(redisTemplate, objectMapper);}@Beanpublic ChatClient chatClient(OllamaChatModel model, ChatMemory chatMemory) {return ChatClient.builder(model).defaultSystem("你是一個熱心、可愛的智能助手,你的名字叫小團團,請以小團團的身份和語氣回答問題。").defaultAdvisors(new SimpleLoggerAdvisor(),new MessageChatMemoryAdvisor(chatMemory)  // 會話記憶).build();}
}
  • 配置redis連接信息:
spring:data:redis:host: localhost

1.4 會話歷史

接口說明

查詢會話記錄列表查詢會話記錄詳情
請求方式GETGET
請求路徑/ai/history/{type}/ai/history/{type}/{chatId}
請求參數type: 業務類型type: 業務類型; chatId: 會話id
返回值["1234", "1246", "1248"][{role: "user", content: ""}]
  • 方式1:保存到JVM內存
  • 方式2:保存到Redis

步驟①:定義會話歷史接口ChatHistoryRepository?

package com.itheima.ai.repository;import java.util.List;public interface ChatHistoryRepository {/*** 保存會話記錄* @param type 業務類型,如:chat、service、pdf* @param chatId 會話ID*/void save(String type, String chatId);/*** 獲取會話ID列表* @param type 業務類型,如:chat、service、pdf* @return 會話ID列表*/List<String> getChatIds(String type);
}

②創建實現類

package com.itheima.ai.repository;import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.ai.chat.memory.ChatMemory;
import org.springframework.stereotype.Component;import java.util.*;@Slf4j
@Component
@RequiredArgsConstructor
public class InMemoryChatHistoryRepository implements ChatHistoryRepository {private Map<String, List<String>> chatHistory;private final ObjectMapper objectMapper;private final ChatMemory chatMemory;@Overridepublic void save(String type, String chatId) {/*if (!chatHistory.containsKey(type)) {chatHistory.put(type, new ArrayList<>());}List<String> chatIds = chatHistory.get(type);*/List<String> chatIds = chatHistory.computeIfAbsent(type, k -> new ArrayList<>());if (chatIds.contains(chatId)) {return;}chatIds.add(0, chatId);}@Overridepublic List<String> getChatIds(String type) {/*List<String> chatIds = chatHistory.get(type);return chatIds == null ? List.of() : chatIds;*/return chatHistory.getOrDefault(type, List.of());}
}

③請求模型前保存會話id

    @RequestMapping(value = "/chat", produces = "text/html;charset=utf-8")public Flux<String> chat(@RequestParam("prompt") String prompt,@RequestParam("chatId") String chatId) {// 1. 保存會話idchatHistoryRepository.save("chat", chatId);// 2. 請求模型return chatClient.prompt().user(prompt).advisors(a -> a.param(CHAT_MEMORY_CONVERSATION_ID_KEY, chatId)).stream().content();}

④定義MessageVo

package com.itheima.ai.entity.vo;import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.ai.chat.messages.Message;@NoArgsConstructor
@Data
public class MessageVO {private String role;private String content;public MessageVO(Message message) {this.role = switch (message.getMessageType()) {case USER -> "user";case ASSISTANT -> "assistant";case SYSTEM -> "system";default -> "";};this.content = message.getText();}
}

⑤根據業務類型、會話id查詢會話歷史詳情

package com.itheima.ai.controller;import com.itheima.ai.entity.vo.MessageVO;
import com.itheima.ai.repository.ChatHistoryRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.ai.chat.memory.ChatMemory;
import org.springframework.ai.chat.messages.Message;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import java.util.List;@RequiredArgsConstructor
@RestController
@RequestMapping("/ai/history")
public class ChatHistoryController {private final ChatHistoryRepository chatHistoryRepository;private final ChatMemory chatMemory;/*** 查詢會話歷史列表* @param type 業務類型,如:chat,service,pdf* @return chatId列表*/@GetMapping("/{type}")public List<String> getChatIds(@PathVariable("type") String type) {return chatHistoryRepository.getChatIds(type);}/*** 根據業務類型、chatId查詢會話歷史詳情* @param type 業務類型,如:chat,service,pdf* @param chatId 會話id* @return 指定會話的歷史消息*/@GetMapping("/{type}/{chatId}")public List<MessageVO> getChatHistory(@PathVariable("type") String type, @PathVariable("chatId") String chatId) {List<Message> messages = chatMemory.get(chatId, Integer.MAX_VALUE);if(messages == null) {return List.of();}return messages.stream().map(MessageVO::new).toList();}
}

⑥重啟進行HeimaAiApplication測試

⑦也可以選擇使用Redis來實現

package com.itheima.ai.repository;import lombok.RequiredArgsConstructor;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;import java.util.Collections;
import java.util.List;
import java.util.Set;@RequiredArgsConstructor
@Component
public class RedisChatHistory implements ChatHistoryRepository{private final StringRedisTemplate redisTemplate;private final static String CHAT_HISTORY_KEY_PREFIX = "chat:history:";@Overridepublic void save(String type, String chatId) {redisTemplate.opsForSet().add(CHAT_HISTORY_KEY_PREFIX + type, chatId);}@Overridepublic List<String> getChatIds(String type) {Set<String> chatIds = redisTemplate.opsForSet().members(CHAT_HISTORY_KEY_PREFIX + type);if(chatIds == null || chatIds.isEmpty()) {return Collections.emptyList();}return chatIds.stream().sorted(String::compareTo).toList();}
}

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

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

相關文章

ROS docker使用顯卡驅動rviz gazebo,以及接入外設和雷達

ROS docker使用顯卡驅動rviz gazebo&#xff0c;以及接入外設和雷達 由于我的電腦裝ubuntu22.04系統&#xff0c;想使用ros noetic開發&#xff0c;使用魚香ros一鍵安裝docker安裝。但是啟動dockek中rviz無法使用顯卡驅動&#xff0c;usb相機端口不顯示&#xff0c;網口雷達無…

ruoyi后端框架的mapper層復雜字段數據獲取問題

背景。如下是復雜字段。需要在mapper.java類注解中聲明autoResultMap true才會進行處理。前提是&#xff0c;創建后端程序代碼沒有添加mapp.xml文件。故用注解簡化代替。

產品推薦|一款具有單光子級探測能力的科學相機千眼狼Gloria 1605

在生命科學超分辨率成像、量子物理單光子探測、交叉領域單分子追蹤等應用場景中&#xff0c;具有單光子級探測能力的科學相機是科學實驗的關鍵設備。 千眼狼Gloria 1605采用16μm16μm大像元尺寸設計&#xff0c;基于Gpixel科學級背照式CMOS芯片&#xff0c;集成千眼狼底層圖像…

JS.Day2-堆選(Py)/三路快排-快速選擇-215,11,560,21,128,20,121

目錄 215.找第k大元素 三路的快速排序 快速選擇 法2.堆選 &#xff08;堆排序&#xff09; 11.盛更多水的容器 代碼1 代碼2 560.和為K的子數組&#xff08;題意&#xff01;&#xff09; 慣性思維 正解 21.合并生序鏈表 遞歸寫法 128.最長連續序列 20.有效的括號…

第8章 處理幾何圖形 面向 ArcGIS的Python腳本編程

一、折點坐標(.txt 或 .xlsx 或 .xls) > 點線面圖層(.shp) &#xff08;一&#xff09;.xlsx 或 .xls > .shp 新建一個文件夾&#xff0c;連接到該文件夾&#xff0c;并將其設置為工作空間 在該文件夾下&#xff0c;新建一個pts.xlsx的文件&#xff0c;并輸入下圖內容 …

使用(h3.js)繪制六角網格碼

今天來記錄一篇關于h3.js插件庫的使用&#xff0c;他可以很高效的計算出地球上某個經緯度坐標六邊形頂點。 前段時間領導突然給我個售前功能&#xff0c;要求是使用h3.js插件在地球上繪制出六邊形網格碼&#xff0c;本來以為挺棘手的&#xff0c;結果看完文檔后發現也挺簡單的…

GO 1.25

Go 1.25 發布說明&#xff08;草案&#xff09; Go 1.25 尚未發布。 本文檔是正在編寫中的發布說明。Go 1.25 預計于 2025 年 8 月發布。 語言變更 Go 1.25 中沒有影響 Go 程序的語法變更。然而&#xff0c;在語言規范中&#xff0c;“核心類型”&#xff08;core types&…

解析Android SETUP_DATA_CALL 鏈路信息字段

Android 對象返回的log信息經常都不是標準的JSON字符串,排查字段不直觀,比如下面的日志: 06-13 15:56:36.204 8076 8407 D RILJ : [1655]> SETUP_DATA_CALL,reason=NORMAL,accessNetworkType=EUTRAN,dataProfile=[DataProfile=[ApnSetting] IMS, 2318, 310260, ims,…

跨語言RPC:使用Java客戶端調用Go服務端的HTTP-RPC服務

在構建分布式系統時&#xff0c;實現不同編程語言之間的無縫通信是一個常見的需求。本文將詳細介紹如何使用Go語言創建一個HTTP-RPC服務&#xff0c;并通過Java客戶端進行遠程調用。我們將探索整個過程&#xff0c;包括服務端的實現、客戶端的編寫以及測試驗證。 一、背景介紹…

CVPR2024遷移學習《Unified Language-driven Zero-shot Domain Adaptation》

摘要 本文提出了一個名為 Unified Language-driven Zero-shot Domain Adaptation&#xff08;ULDA&#xff09;的新任務設置&#xff0c;旨在使單一模型能夠適應多種目標領域&#xff0c;而無需明確的領域標識&#xff08;domain-ID&#xff09;知識。現有語言驅動的零樣本領域…

AI安全風險監測平臺:全周期防護體系構建

AI安全風險監測平臺通過構建全生命周期防護體系&#xff0c;實現對人工智能系統研發、部署、運行、迭代各階段的安全風險動態監測。該平臺融合算法審計、行為分析、合規驗證等核心能力&#xff0c;建立覆蓋模型安全、數據安全、應用安全的立體防御網絡&#xff0c;為智能系統提…

數據集-目標檢測系列- 杯子 數據集 bottle >> DataBall

數據集-目標檢測系列- 杯子 數據集 bottle &#xff1e;&#xff1e; DataBall 貴在堅持&#xff01; * 相關項目 1&#xff09;數據集可視化項目&#xff1a;gitcode: https://gitcode.com/DataBall/DataBall-detections-100s/overview 2&#xff09;數據集訓練、推理相關…

視頻點播web端AI智能大綱(自動生成視頻內容大綱)的代碼與演示

通過AI技術將視頻課程自動生成結構化大綱和摘要&#xff0c;支持PPT教學視頻、企業內訓等場景應用。核心功能包括&#xff1a;自動匹配視頻知識點生成文本大綱、快速內容定位、降低課程制作成本。系統采用模塊化架構&#xff0c;包含Vue2.7前端組件、JS邏輯庫和演示項目&#x…

Linux: errno: EINPROGRESS-115

在connect接口的使用說明里&#xff0c;有這個錯誤&#xff1a;EINPROGRESS。 The socket is nonblocking and the connection cannot be completed immediately. It is possible to select(2) or poll(2) for completion by selecting the socket for writing. After select(2…

Node.js特訓專欄-基礎篇:3. Node.js內置模塊的使用

&#x1f525; 歡迎來到 Node.js 實戰專欄&#xff01;在這里&#xff0c;每一行代碼都是解鎖高性能應用的鑰匙&#xff0c;讓我們一起開啟 Node.js 的奇妙開發之旅&#xff01; Node.js 特訓專欄主頁 Node.js內置模塊&#xff1a;強大功能的基石 在Node.js的世界里&#xff…

基于MATLAB實現的Capon、MUSIC、ESPRIT和PM算法進行DOA

使用Capon、MUSIC、ESPRIT和PM多種算法進行doa估計&#xff0c;通過譜峰搜索函數估計到達角&#xff0c;并使用蒙特卡洛方法估計各算法的RMSE。&#xff08;可能計算時間較長&#xff0c;如需節省時間可以減小蒙特卡洛次數&#xff09; PM.m , 574 RMSE.m , 274 TLS_ESPRIT.m …

某網站極驗4滑塊驗證碼逆向分析

文章目錄 1. 寫在前面2. 接口分析3. w逆向分析4. JSON參數分析5. 距離識別6. RSA純算還原7. AES純算還原【??作者主頁】:吳秋霖 【??作者介紹】:擅長爬蟲與JS加密逆向分析!Python領域優質創作者、CSDN博客專家、阿里云博客專家、華為云享專家。一路走來長期堅守并致力于…

深入理解 C++ inline:三大語法特性 + 七大高頻考點全解析

一、什么是內聯函數 編譯器嘗試將 inline 函數的代碼直接插入調用處&#xff08;類似宏展開&#xff09;&#xff0c;避免函數調用的壓棧、跳轉、返回等額外開銷。適用于短小頻繁調用的函數&#xff1a;如簡單的 getter/setter、數學運算等。inline 只是 建議&#xff0c;編譯…

Flink 與 Hive 深度集成

引言 在大數據生態中&#xff0c;Flink 的流批一體化處理能力與 Hive 的數據存儲分析優勢結合&#xff0c;通過 Flink Connector for Hive 實現無縫對接&#xff0c;能顯著提升數據處理效率。本文將系統解析 Flink 與 Hive 集成的核心操作&#xff0c;涵蓋配置、讀寫、優化全流…

Axios面試常見問題詳解

axios面試常問題目及其詳解 以下是前端面試中關于 Axios 的常見問題及詳細解答&#xff0c;涵蓋核心原理、實戰場景和進階優化&#xff0c;幫助你在面試中清晰展示技術深度。 1. Axios 是什么&#xff1f;它與原生 Fetch API 有何區別&#xff1f; 回答要點&#xff1a; Axi…