整合SaToken 實現登錄功能

整合SaToken 實現登錄功能

1.整合redis

1.1添加相關依賴

        // 省略...<!-- Redis --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency><!-- Redis 連接池 --><dependency><groupId>org.apache.commons</groupId><artifactId>commons-pool2</artifactId></dependency>// 省略...

1.2添加配置

spring:datasource:// 省略...data:redis:database: 0 # Redis 數據庫索引(默認為 0)host: 127.0.0.1 # Redis 服務器地址port: 6379 # Redis 服務器連接端口password:  # Redis 服務器連接密碼(默認為空)timeout: 5s # 讀超時時間connect-timeout: 5s # 鏈接超時時間lettuce:pool:max-active: 200 # 連接池最大連接數max-wait: -1ms # 連接池最大阻塞等待時間(使用負值表示沒有限制)min-idle: 0 # 連接池中的最小空閑連接max-idle: 10 # 連接池中的最大空閑連接    

1.3自定義 RedisTemplate

@Configuration
public class RedisTemplateConfig {@Beanpublic RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();// 設置 RedisTemplate 的連接工廠redisTemplate.setConnectionFactory(connectionFactory);// 使用 StringRedisSerializer 來序列化和反序列化 redis 的 key 值,確保 key 是可讀的字符串redisTemplate.setKeySerializer(new StringRedisSerializer());redisTemplate.setHashKeySerializer(new StringRedisSerializer());// 使用 Jackson2JsonRedisSerializer 來序列化和反序列化 redis 的 value 值, 確保存儲的是 JSON 格式Jackson2JsonRedisSerializer<Object> serializer = new Jackson2JsonRedisSerializer<>(Object.class);redisTemplate.setValueSerializer(serializer);redisTemplate.setHashValueSerializer(serializer);redisTemplate.afterPropertiesSet();return redisTemplate;}
}

2.鑒權設計:RBAC 權限模型

什么是 RBAC 模型?

RBAC(Role-Based Access Control)是一種基于角色的訪問控制。它通過角色來管理用戶的權限。RBAC 的核心思想是將用戶與角色進行關聯,并將權限分配給角色,而不是直接分配給用戶。這樣,通過改變用戶的角色,就可以靈活地控制用戶的權限。

RBAC 的主要組成部分包括:

  • 用戶(User):系統的使用者。
  • 角色(Role):權限的集合,一個角色可以包含多個權限。
  • 權限(Permission):對系統資源的訪問操作,如讀取、寫入、刪除等。

RBAC 1:基于角色的層次模型(Role Hierarchies)

RBAC 1 在 RBAC 0 的基礎上增加了角色層次結構(Role Hierarchies)。角色層次結構允許角色之間存在繼承關系,一個角色可以繼承另一個角色的權限。

主要特點
  • 角色繼承:一個角色可以繼承另一個角色的所有權限。比如,角色B繼承角色 A 的權限,那么角色 B 不僅擁有自己定義的權限,還擁有角色 A 的所有權限。
  • 權限傳遞:繼承關系是傳遞的,如果角色 C 繼承角色 B,而角色 B 繼承角色 A,那么角色 C 將擁有角色 A 和角色 B 的所有權限。
優點
  • 簡化權限管理:通過角色繼承,可以減少重復定義權限的工作。
  • 提高靈活性:可以方便地對角色進行分層管理,滿足不同層次用戶的權限需求。
場景舉例

在一個企業系統中,高級經理(Senior Manager)角色繼承經理(Manager)角色的權限,經理角色繼承員工(Employee)角色的權限。這樣,高級經理角色不僅擁有自己的權限,還擁有經理和員工的所有權限。

RBAC 2:基于約束的 RBAC 模型(Constraints)

RBAC 2 同樣建立在 RBAC 0 基礎之上,但是增加了約束(Constraints)。約束是用于加強訪問控制策略的規則或條件,可以限制用戶、角色和權限的關聯方式。

主要特點
  • 互斥角色:某些角色不能同時賦予同一個用戶。例如,審計員和財務員角色不能同時賦予同一個用戶,以避免暗黑交易。
  • 先決條件:用戶要獲得某個角色,必須先擁有另一個角色。例如,公司研發人員要成為高級程序員,必須先成為中級程序員。
  • 基數約束:限制某個角色可以被賦予的用戶數量。例如,某個項目的經理角色只能賦予一個用戶,以確保項目的唯一責任人。
優點:
  • 加強安全性:通過約束規則,可以避免權限濫用和利益沖突。
  • 精細化管理:可以更精細地控制用戶的角色分配和權限管理。
場景舉例

在一個金融系統中,為了避免利益沖突,定義了互斥角色規則:審計員和財務員角色不能同時賦予同一個用戶。這樣可以確保審計員和財務員的職責分離,增強系統的安全性。

RBAC 3:統一模型(Consolidated Model)

RBAC 3 是最全面的 RBAC 模型,它結合了 RBAC1 的角色層次結構和 RBAC2 的約束,形成一個統一的模型,提供了最大程度的靈活性和安全性。

主要特點
  • 包含RBAC 1的所有功能:角色層次結構,角色繼承和權限傳遞。
  • 包含RBAC 2的所有功能:互斥角色、先決條件角色和角色卡數限制等約束規則。
  • 綜合管理:可以同時利用角色繼承和約束規則,提供最全面的權限管理解決方案。
優點
  • 高靈活性:可以滿足各種復雜的權限管理需求。
  • 高安全性:通過約束規則,進一步加強權限管理的安全性。
場景舉例

在一個大型企業系統中,需要復雜的權限管理策略。RBAC 3 模型可以通過角色層次結構定義不同層級的員工權限,通過約束規則確保權限分配的安全性。例如,高級經理角色繼承經理角色的權限,但為了避免利益沖突,財務員和審計員角色互斥,不能同時賦予同一個用戶。

基于 RBAC 的延展:用戶組

在實際業務場景中,舉個栗子,比如銷售部門,分配到此部門的員工都是銷售員,擁有同一類角色。如果要為每一個員工手動分配角色,就顯得非常繁瑣了,而且容易出錯。于是乎,在系統設計上,引入了用戶組的概念,我們可以把銷售部看成一個用戶組,對用戶組提前分配好角色,這樣后續只需將員工拉入該部門,即可擁有該部門已分配的權限。

RBAC 模型是為了更加靈活的控制權限。那么問題來了,需要控制的權限通常都有哪些?

在系統設計時,通常你需要考慮以下幾類權限:

  1. 菜單權限:控制用戶在管理后臺中,可以看到的菜單項與頁面。
  2. 操作權限:控制用戶可以執行的具體操作。比如新增、刪除、修改按鈕的權限。
  3. 數據權限:控制用戶可以訪問的數據范圍。比如只能看到本部門的數據,其他部門的員工登錄則無法查看。
  4. 字段權限:控制用戶可以查看或編輯的字段。
  5. 等等…

具體還得結合你的業務來,沒有絕對,畢竟技術服務于業務。

3.RBAC 權限表設計、微服務鑒權架構設計

  • 角色表;
  • 權限表;
  • 角色權限關聯表;
  • 用戶角色關聯表;
CREATE TABLE `t_role` (`id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT '主鍵ID',`role_name` varchar(32) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '角色名',`role_key` varchar(32) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '角色唯一標識',`status` tinyint NOT NULL DEFAULT '0' COMMENT '狀態(0:啟用 1:禁用)',`sort` int unsigned NOT NULL DEFAULT 0 COMMENT '管理系統中的顯示順序',`remark` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '備注',`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '創建時間',`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '最后一次更新時間',`is_deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '邏輯刪除(0:未刪除 1:已刪除)',PRIMARY KEY (`id`) USING BTREE,UNIQUE KEY `uk_role_key` (`role_key`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='角色表';
CREATE TABLE `t_permission` (`id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT '主鍵ID',`parent_id` bigint unsigned NOT NULL DEFAULT '0' COMMENT '父ID',`name` varchar(16) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '權限名稱',`type` tinyint unsigned NOT NULL COMMENT '類型(1:目錄 2:菜單 3:按鈕)',`menu_url` varchar(32) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '菜單路由',`menu_icon` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '菜單圖標',`sort` int unsigned NOT NULL DEFAULT 0 COMMENT '管理系統中的顯示順序',`permission_key` varchar(64) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '權限標識',`status` tinyint unsigned NOT NULL DEFAULT '0' COMMENT '狀態(0:啟用;1:禁用)',`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '創建時間',`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '更新時間',`is_deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '邏輯刪除(0:未刪除 1:已刪除)',PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='權限表';
CREATE TABLE `t_user_role_rel` (`id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT '主鍵ID',`user_id` bigint unsigned NOT NULL COMMENT '用戶ID',`role_id` bigint unsigned NOT NULL COMMENT '角色ID',`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '創建時間',`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '更新時間',`is_deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '邏輯刪除(0:未刪除 1:已刪除)',PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用戶角色表';
CREATE TABLE `t_role_permission_rel` (`id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT '主鍵ID',`role_id` bigint unsigned NOT NULL COMMENT '角色ID',`permission_id` bigint unsigned NOT NULL COMMENT '權限ID',`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '創建時間',`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '更新時間',`is_deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '邏輯刪除(0:未刪除 1:已刪除)',PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用戶權限表';

鑒權放哪里合適?

關于用戶認證(登錄),我們已經知道是通過認證服務來處理。那么問題來了,鑒權在哪一層處理呢?通常來說,有以下 3 種方案:

  1. 每個微服務各自鑒權
  2. 網關統一鑒權
  3. 混合策略
鑒權方案優點缺點
1. 每個微服務各自鑒權- 每個微服務獨立處理鑒權,權限控制更細粒度。- 鑒權邏輯重復,增加了維護成本。
- 不利于全局權限管理,可能存在權限漏斗。
- 每個服務需要單獨處理認證邏輯,可能影響性能。
2. 網關統一鑒權- 簡化了每個微服務的鑒權邏輯,避免重復實現。
- 可以集中管理認證和授權,減少安全風險。
- 更易于實現權限的統一管理和更新。
- 網關成了單點故障,性能瓶頸容易產生。
- 如果網關配置出現問題,所有服務的訪問都將受限。
- 可能增加網關的復雜度,影響響應速度。
3. 混合策略- 結合了兩者的優點,在網關層進行基礎鑒權,細粒度的權限控制在微服務內部處理。
- 靈活性高,可以針對不同場景選擇不同策略。
- 配置和管理較復雜,可能導致維護困難。
- 需要較強的服務協作和協調,增加了系統的復雜度。

權限數據獲取方案?

權限數據獲取方案優點缺點
1. 權限數據存儲在數據庫中,按需查詢- 權限數據存儲持久化,數據持久性強,修改權限時只需更新數據庫。
- 權限數據查詢靈活,可以支持復雜的查詢條件。
- 每次請求都需要查詢數據庫,增加了數據庫壓力,可能影響性能。
- 權限變化時需要及時同步到微服務或緩存。
2. 權限數據緩存到 Redis 中- 查詢速度更快,減少數據庫壓力,適用于高并發場景。
- 可以在緩存中存儲用戶的權限數據,快速獲取。
- 緩存過期機制可以保證數據的新鮮度。
- 數據一致性問題:緩存和數據庫之間可能會出現數據不同步的情況。
- 需要額外的緩存管理機制(如緩存失效、更新等)。
3. 權限數據靜態配置(硬編碼到應用中)- 訪問權限數據速度最快,直接嵌入到應用代碼中,無需查詢數據庫或緩存。
- 配置簡單,適合權限變化不頻繁的場景。
- 權限管理不靈活,變動時需要重新部署應用。
- 隨著權限管理的復雜性增加,代碼難以維護。

4.SaToken 整合 Redis

添加依賴

	// 省略...<!-- 統一依賴管理 --><dependencyManagement><dependencies>// 省略...<!-- Sa-Token 整合 Redis (使用 jackson 序列化方式) --><dependency><groupId>cn.dev33</groupId><artifactId>sa-token-redis-jackson</artifactId><version>${sa-token.version}</version></dependency>// 省略...</dependencies></dependencyManagement>// 省略...<!-- Sa-Token 整合 Redis (使用 jackson 序列化方式) --><dependency><groupId>cn.dev33</groupId><artifactId>sa-token-redis-jackson</artifactId></dependency><!-- Redis 連接池 --><dependency><groupId>org.apache.commons</groupId><artifactId>commons-pool2</artifactId></dependency>// 省略...// 省略...

為 SaToken 權限框架整合了 Redis , 讓會話數據存儲在了緩存中間件中,以保證項目重啟后,登錄狀態不會失效。

5.同步【角色-權限集合】數據到 Redis 中

在 Spring Boot 項目中,可以通過多種方式在項目啟動時執行初始化工作。以下是一些常見的方法:

1. 使用 @PostConstruct 注解

@PostConstruct 注解可以用于在 Spring 容器初始化 bean 之后立即執行特定的方法。

import org.springframework.stereotype.Component;import javax.annotation.PostConstruct;@Component
public class MyInitializer {@PostConstructpublic void init() {// 初始化工作System.out.println("初始化工作完成");}
}

2. 實現 ApplicationRunner 接口

ApplicationRunner 接口提供了一種在 Spring Boot 應用啟動后執行特定代碼的方式。

import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;@Component
public class MyApplicationRunner implements ApplicationRunner {@Overridepublic void run(ApplicationArguments args) throws Exception {// 初始化工作System.out.println("初始化工作完成");}
}

3. 實現 CommandLineRunner 接口

CommandLineRunner 接口類似于 ApplicationRunner,可以在應用啟動后執行代碼。

import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;@Component
public class MyCommandLineRunner implements CommandLineRunner {@Overridepublic void run(String... args) throws Exception {// 初始化工作System.out.println("初始化工作完成");}
}

4. 使用 @EventListener 注解監聽 ApplicationReadyEvent

通過監聽 ApplicationReadyEvent 事件,可以在 Spring Boot 應用完全啟動并準備好服務請求時執行初始化工作。

import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
import org.springframework.boot.context.event.ApplicationReadyEvent;@Component
public class MyApplicationReadyListener {@EventListener(ApplicationReadyEvent.class)public void onApplicationReady() {// 初始化工作System.out.println("初始化工作完成");}
}

5. 使用 SmartInitializingSingleton 接口

SmartInitializingSingleton 接口提供了一種在所有單例 bean 初始化完成后執行代碼的方式。

import org.springframework.beans.factory.SmartInitializingSingleton;
import org.springframework.stereotype.Component;@Component
public class MySmartInitializingSingleton implements SmartInitializingSingleton {@Overridepublic void afterSingletonsInstantiated() {// 初始化工作System.out.println("初始化工作完成");}
}

6. 使用 Spring Boot 的 InitializingBean 接口

通過實現 InitializingBean 接口的 afterPropertiesSet 方法,可以在 bean 的屬性設置完成后執行初始化工作。

import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;@Component
public class MyInitializingBean implements InitializingBean {@Overridepublic void afterPropertiesSet() throws Exception {// 初始化工作System.out.println("初始化工作完成");}
}

7. 總結

以上這些方法各有優缺點,可以根據具體的初始化需求選擇合適的方法。

  • @PostConstruct:適合簡單的初始化邏輯,執行時機較早。
  • ApplicationRunner 和 CommandLineRunner:適合需要訪問命令行參數的初始化邏輯,執行時機在 Spring Boot 應用啟動完成后。
  • ApplicationReadyEvent 監聽器:適合在整個應用準備好后執行的初始化邏輯。
  • SmartInitializingSingleton:適合需要在所有單例 bean 初始化完成后執行的初始化邏輯。
  • InitializingBean:適合需要在 bean 屬性設置完成后執行的初始化邏輯。

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

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

相關文章

Vue 項目中逐步引入 TypeScript 的類型檢查

在現有的 Vue 項目中逐步引入 TypeScript 的類型檢查 本文源于一道面試題&#xff1a;注&#xff1a;兩種問法一個意思哈&#xff01;&#xff01; 問題一&#xff1a;“ 老項目Js寫的&#xff0c;如何輕量方式享受 ts 類型&#xff1f;” 問題二&#xff1a;“如何 在現有的 …

python后端調用Deep Seek API

python后端調用Deep Seek API 需要依次下載 ●Ollama ●Deepseek R1 LLM模型 ●嵌入模型nomic-embed-text / bge-m3 ●AnythingLLM 參考教程&#xff1a; Deepseek R1打造本地化RAG知識庫:安裝部署使用詳細教程 手把手教你&#xff1a;deepseek R1基于 AnythingLLM API 調用本地…

本地部署MindSearch(開源 AI 搜索引擎框架),然后上傳到 hugging face的Spaces——L2G6

部署MindSearch到 hugging face Spaces上——L2G6 任務1 在 官方的MindSearch頁面 復制Spaces應用到自己的Spaces下&#xff0c;Space 名稱中需要包含 MindSearch 關鍵詞&#xff0c;請在必要的步驟以及成功的對話測試結果當中 實現過程如下&#xff1a; 2.1 MindSearch 簡…

matlab下載安裝圖文教程

【matlab介紹】 MATLAB是一款由美國MathWorks公司開發的專業計算軟件&#xff0c;主要應用于數值計算、可視化程序設計、交互式程序設計等高科技計算環境。以下是關于MATLAB的簡要介紹&#xff1a; MATLAB是MATrix LABoratory&#xff08;矩陣實驗室&#xff09;的縮寫&#…

捷米特 JM - RTU - TCP 網關應用 F - net 協議轉 Modbus TCP 實現電腦控制流量計

一、項目背景 在某工業生產園區的供水系統中&#xff0c;為了精確監測和控制各個生產環節的用水流量&#xff0c;需要對分布在不同區域的多個流量計進行集中管理。這些流量計原本采用 F - net 協議進行數據傳輸&#xff0c;但園區的監控系統基于 Modbus TCP 協議進行數據交互&…

4.1 Hugging Face Datasets實戰:構建企業級數據流水線

Hugging Face Datasets實戰:構建企業級數據流水線 一、Datasets庫核心優勢 1.1 企業級數據處理需求全景 # 支持的數據格式示例 data_formats = {"結構化數據": ["CSV", "Parquet", "SQL"]

深入解析隊列與廣度優先搜索(BFS)的算法思想:原理、實現與應用

目錄 1. 隊列的基本概念 2. 廣度優先搜索&#xff08;BFS&#xff09;的基本概念 3. 隊列在BFS中的作用 4. BFS的實現細節 5. C實現BFS 6. BFS的應用場景 7. 復雜度分析 8. 總結 1. 隊列的基本概念 隊列&#xff08;Queue&#xff09;是一種先進先出&#xff08;FIFO, …

【學術投稿-第四屆材料工程與應用力學國際學術會議(ICMEAAE 2025】材料工程與應用力學的探討

重要信息 官網&#xff1a;www.icmeaae.com 時間&#xff1a;2025年3月7-9日 地點&#xff1a;中國西安 簡介 第四屆材料工程與應用力學&#xff08;ICMEAAE 2025&#xff09;將于2025年3月7日至9日在中國西安召開。本次會議將重點討論材料科學、應用力學等領域的最新研究進…

間隔連續問題

間隔連續問題 1. 數據結構&#xff1a;某游戲公司記錄的用戶每日登錄數據 表名&#xff1a;game_user 字段名&#xff1a;id&#xff08;用戶id&#xff09;、dt&#xff08;日期&#xff09; 2. 需求&#xff1a; ① 創建表 ② 計算每個用戶最大的連續登錄天數&#xff0c…

EasyRTC輕量級SDK:智能硬件音視頻通信資源的高效利用方案

在智能硬件這片廣袤天地里&#xff0c;每一份資源的精打細算都關乎產品的生死存亡。隨著物聯網技術的疾速演進&#xff0c;實時音視頻通信功能已成為眾多設備的標配。然而&#xff0c;硬件資源的捉襟見肘&#xff0c;讓開發者們常常陷入兩難境地。EasyRTC&#xff0c;以它的極致…

神經網絡剪枝技術的重大突破:sGLP-IB與sTLP-IB

神經網絡剪枝技術的重大突破:sGLP-IB與sTLP-IB 在人工智能飛速發展的今天,深度學習技術已經成為推動計算機視覺、自然語言處理等領域的核心力量。然而,隨著模型規模的不斷膨脹,如何在有限的計算資源和存儲條件下高效部署這些復雜的神經網絡模型,成為了研究者們亟待解決的…

[AI相關]Unity的C#代碼如何簡寫

是一個某培訓機構的飛行棋教學源碼 不知道&#xff0c;是否有人想知道怎么可以簡寫 &#xff08;這個問AI&#xff0c;DeepSeek也應該找不到答案的&#xff09; 靜態變量 屬性引用 單例 注入 一些UnityEvent特性就不說了。。。 IL 注入 運算符號改寫

【Docker】容器被停止/刪除的方式及命令:全面解析與實踐指南

文章目錄 引言一、容器的生命周期二、停止容器的命令及方式1. docker stop 命令2. docker kill 命令3. docker pause 和 docker unpause 命令4. docker restart 命令 三、刪除容器的命令及方式1. docker rm 命令2. docker container prune 命令3. docker rm 與 docker rmi 的區…

Node.js技術原理分析系列——Node.js調試能力分析

本文由體驗技術團隊屈金雄原創。 Node.js 是一個開源的、跨平臺的 JavaScript 運行時環境&#xff0c;它允許開發者在服務器端運行 JavaScript 代碼。Node.js 是基于 Chrome V8引擎構建的&#xff0c;專為高性能、高并發的網絡應用而設計&#xff0c;廣泛應用于構建服務器端應…

輕松搭建本地大語言模型(二)Open-WebUI安裝與使用

文章目錄 前置條件目標一、安裝 Open-WebUI使用 Docker 部署 二、使用 Open-WebUI&#xff08;一&#xff09;訪問Open-WebUI&#xff08;二&#xff09;注冊賬號&#xff08;三&#xff09;模型選擇&#xff08;四&#xff09;交互 四、常見問題&#xff08;一&#xff09;容器…

阿里云百煉通義大模型

阿里云百煉通義大模型 Part one&#xff08;阿里云百煉大模型&#xff09;一、什么是百煉&#xff08;一&#xff09;調用大模型 二、支持的大模型三、模型總覽四、為什么選擇百煉&#xff1f;五、開始使用百煉Part two一、開發參考二、模型調用&#xff08;一&#xff09;通義…

Golang學習筆記_33——橋接模式

Golang學習筆記_30——建造者模式 Golang學習筆記_31——原型模式 Golang學習筆記_32——適配器模式 文章目錄 橋接模式詳解一、橋接模式核心概念1. 定義2. 解決的問題3. 核心角色4. 類圖 二、橋接模式的特點三、適用場景1. 多維度變化2. 跨平臺開發3. 動態切換實現 四、與其他…

低代碼(Low Code)全解析:從概念到應用,從選擇到價值

?在數字化浪潮席卷全球的當下&#xff0c;企業對軟件開發的效率與靈活性愈發重視&#xff0c;低代碼平臺應運而生并迅速掀起技術熱潮。 本文基于筆者 6 年的低代碼實踐經驗&#xff0c;深入剖析低代碼的諸多方面&#xff0c;涵蓋其定義、發展歷程、國內平臺對比、開發流程、與…

函數重載講解

雖然在初識C-CSDN博客中介紹過&#xff0c;但還是感覺要單發出來大概講解下 什么是函數重載&#xff1f; 函數重載是指在同一個作用域內&#xff0c;函數名相同&#xff0c;但它們的 參數列表 不同。C 允許你根據函數的參數個數、類型或者順序的不同來定義多個同名函數。編譯…

14-H指數

給你一個整數數組 citations &#xff0c;其中 citations[i] 表示研究者的第 i 篇論文被引用的次數。計算并返回該研究者的 h 指數。 根據維基百科上 h 指數的定義&#xff1a;h 代表“高引用次數” &#xff0c;一名科研人員的 h 指數 是指他&#xff08;她&#xff09;至少發…