性能優化 - 案例篇:緩存_Guava#LoadingCache設計

文章目錄

  • Pre
  • 引言
  • 1. 緩存基本概念
  • 2. Guava 的 LoadingCache
    • 2.1 引入依賴與初始化
    • 2.2 手動 put 與自動加載(CacheLoader)
      • 2.2.1 示例代碼
    • 2.3 緩存移除與監聽(invalidate + removalListener)
  • 3. 緩存回收策略
    • 3.1 基于容量的回收(LRU)
    • 3.2 基于時間的回收
    • 3.3 基于 JVM GC 的回收
      • 3.3.1 GC 回收引發的緩存顛簸問題
  • 4. 常見緩存算法簡介
    • 4.1 FIFO(先進先出)
    • 4.2 LRU(最近最少使用)
    • 4.3 LFU(最近最不常用)
  • 5. 簡易 LRU 實現——LinkedHashMap
    • 5.1 功能局限與線程安全
  • 6. 操作系統層面的預讀與文件緩存
  • 7. 緩存優化的一般思路
  • 8. 緩存應用案例
  • 9. 小結

在這里插入圖片描述


Pre

性能優化 - 理論篇:常見指標及切入點

性能優化 - 理論篇:性能優化的七類技術手段

性能優化 - 理論篇:CPU、內存、I/O診斷手段

性能優化 - 工具篇:常用的性能測試工具

性能優化 - 工具篇:基準測試 JMH

性能優化 - 案例篇:緩沖區


  1. 引言:解釋緩存與緩沖的區別及緩存在性能優化中的重要性;
  2. 緩存基本概念:緩存的本質、應用場景、進程內 vs 進程外緩存;
  3. Guava LoadingCache(LC)示例:
    3.1 引入依賴與初始化配置;
    3.2 手動 put 與自動加載(CacheLoader)模式;
    3.3 緩存容量、初始大小與并發級別設置;
    3.4 緩存移除與監聽(invalidate + removalListener);
  4. 緩存回收策略:
    4.1 基于容量的回收(LRU);
    4.2 基于時間的回收(expireAfterWrite / expireAfterAccess);
    4.3 基于 JVM GC 的回收(weakKeys / weakValues / softValues);
    4.4 GC 回收引發的緩存顛簸問題與解決思路;
  5. 緩存算法簡述:FIFO、LRU、LFU 三種常見策略;
  6. 用 LinkedHashMap 實現簡易 LRU:
    6.1 LinkedHashMap 構造參數與訪問順序;
    6.2 覆蓋 removeEldestEntry 實現容量控制;
    6.3 線程安全與功能局限性說明;
  7. 操作系統層面的預讀與文件緩存:readahead 機制、完全加載策略;
  8. 緩存優化一般思路:何時用緩存、容量與命中率考量;
  9. 緩存的一些注意事項與示例:HTTP 304、CDN;

引言

在性能優化 - 案例篇:緩沖區中,介紹了“緩沖”這一優化手段——通過將數據暫存到內存緩沖區,批量順序讀寫來緩解設備間的速度差異。與緩沖相伴隨的“孿生兄弟”就是緩存(Cache)。緩存將常用數據放到相對高速的存儲層(如內存)中,從而在后續訪問時實現瞬時讀取,顯著提升性能。

舉例而言:

  • 瀏覽熱門頁面時,只要緩存中已有渲染結果,就可以實現“秒開”;
  • 對數據庫而言,引入緩存后,頻繁查詢熱點記錄可以直接命中緩存,數據庫幾乎無需負載。

緩存幾乎是軟件中最常見的優化技術。從 CPU L1/L2/L3 緩存到 Redis、Memcached 這樣的分布式緩存,無不圍繞“速度差異協調”這一核心展開。

接下來我們主要聚焦于進程內緩存——堆內緩存,以 Guava 的 LoadingCache 為示例講解堆內緩存設計思路、常見回收策略和算法實現。


1. 緩存基本概念

緩存的核心作用,是在兩個速度差異巨大的組件之間增加一層高速存儲:

  • 速度慢組件:如數據庫、文件存儲,訪問一次可能耗費幾毫秒或更長;
  • 速度快組件:如 CPU 寄存器、內存讀寫,只需幾十納秒;
  • 緩存層(中間層):通常部署在內存中,通過哈希映射、LRU 回收等策略,只要緩存命中就能以幾百納秒返回結果。

根據緩存所在的物理位置,可將其分為:

  1. 進程內緩存(堆內緩存):直接存放在 JVM 堆里,訪問速度最快,但容量受限于可用堆內存;
  2. 進程外緩存(進程間或分布式緩存):如 Redis、Memcached,通常運行在獨立進程或集群里,通過網絡訪問,雖然速度比數據庫快許多,但仍比堆內緩存慢一個數量級;

接下來重點講解 進程內緩存,常見實現包括 Guava Cache、Caffeine、Ehcache、JCache 等。它們都提供了基于內存分片、高并發訪問、靈活回收策略和統計監控的堆內緩存解決方案。

在這里插入圖片描述


2. Guava 的 LoadingCache

在這里插入圖片描述

Guava 提供了功能強大的 Cache 接口和 LoadingCache 實現,既支持手動存入(put()),也支持在緩存未命中時“自動加載”(CacheLoader)。下面通過示例逐步介紹其用法與內部配置要點。

2.1 引入依賴與初始化

首先,通過 Maven 將 Guava 庫加入項目:

<dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId><version>29.0-jre</version>
</dependency>

然后,使用 CacheBuilder 來創建一個 LoadingCache

LoadingCache<String, String> lc = CacheBuilder.newBuilder()// 設置最大緩存容量:達到上限后回收其他元素.maximumSize(1000)// 設置初始容量:底層 Hash 表的初始大小為 16(默認).initialCapacity(16)// 設置并發級別:將緩存分片成 4 個 segment,提升并發讀寫性能.concurrencyLevel(4).build(new CacheLoader<String, String>() {@Overridepublic String load(String key) throws Exception {// 緩存未命中時,自動調用 slowMethod 從外部數據源加載return slowMethod(key);}});
  • maximumSize(int):指定 緩存中可保留條目的最大數量,一旦超過,將根據回收策略(默認 LRU)移除舊元素;
  • initialCapacity(int):指定底層哈希表初始大小(bucket 數量),避免在緩存初始化時反復擴容;
  • concurrencyLevel(int):指定并發寫的“分段”數,Guava 會將內部數據結構拆分為 concurrencyLevel 個部分,以減少并發沖突;

2.2 手動 put 與自動加載(CacheLoader)

LoadingCache 支持兩種獲取方式:

  1. 手動 put()

    lc.put("key1", "value1");
    String v = lc.getIfPresent("key1");  // 立即返回 "value1"
    

    在這種模式下,開發者負責將外部數據同步寫入緩存。

  2. 自動加載 get()

在這里插入圖片描述

// 第一次調用:緩存中無 key "a",觸發 CacheLoader.load("a")
long start = System.nanoTime();
String result1 = lc.get("a");   // slowMethod("a") 需 1s
System.out.println("第一次調用耗時: " + (System.nanoTime() - start));
// 第二次調用:緩存命中,迅速返回
long start2 = System.nanoTime();
String result2 = lc.get("a");
System.out.println("第二次調用耗時: " + (System.nanoTime() - start2));

其中 load(String key) 方法可同步加載所需數據(如從數據庫或外部 API 拉取),并在返回值后自動存入緩存。

2.2.1 示例代碼

public class GuavaCacheDemo {// 模擬一個緩慢方法:睡眠 1 秒后返回結果static String slowMethod(String key) throws Exception {Thread.sleep(1000);return key + ".result";}public static void main(String[] args) throws Exception {LoadingCache<String, String> lc = CacheBuilder.newBuilder().maximumSize(1000).initialCapacity(16).concurrencyLevel(4).recordStats()   // 開啟統計信息收集.build(new CacheLoader<String, String>() {@Overridepublic String load(String key) throws Exception {return slowMethod(key);}});// 第一次 get,會調用 slowMethodlong t1 = System.nanoTime();String v1 = lc.get("a");long elapsed1 = System.nanoTime() - t1;System.out.println("第一次 get 用時: " + elapsed1 + " ns");// 第二次 get,立即返回long t2 = System.nanoTime();String v2 = lc.get("a");long elapsed2 = System.nanoTime() - t2;System.out.println("第二次 get 用時: " + elapsed2 + " ns");// 輸出命中率與加載次數等統計System.out.println("Cache Stats: " + lc.stats());}
}
  • recordStats():開啟緩存統計功能,可用于后續分析 hitRate()loadSuccessCount() 等指標;
  • CacheLoader.load():當 key 未命中時,自動調用并將結果寫回緩存;

2.3 緩存移除與監聽(invalidate + removalListener)

  • 手動刪除

    lc.invalidate("a");  // 移除 key "a" 對應的緩存項
    
  • 監聽刪除事件

    LoadingCache<String, String> lc2 = CacheBuilder.newBuilder().removalListener(notification -> {System.out.println("移除: " + notification.getKey() + " 因為 " + notification.getCause());}).maximumSize(100).build(new CacheLoader<>() {@Overridepublic String load(String key) { return slowMethod(key); }});
    

    當緩存項因為容量、過期、顯式 invalidate() 等原因被移除時,監聽器會收到回調,可用于日志、監控或二次清理。


3. 緩存回收策略

在緩存容量有限的前提下,需設計合適的回收策略來剔除“冷”或不再需要的數據,以保證“熱點”數據得到優先保留。Guava 原生支持多種回收方式:

3.1 基于容量的回收(LRU)

  • maximumSize(long):當超過指定數量時,按照“最近最少使用(LRU)”策略移除最舊項;
  • LRU 意味著:每次緩存命中(get())或寫入(put())時,該條目被標記為“最近被使用”;容量滿時,優先移除最久未被訪問的條目;
  • 這是默認的回收策略,適合大多數“熱點覆蓋度有限”的場景。

3.2 基于時間的回收

  • expireAfterWrite(long duration, TimeUnit unit):在緩存項被寫入后,若在 duration 時間內未被訪問,自動過期移除;
  • expireAfterAccess(long duration, TimeUnit unit):在緩存項最后一次訪問后,若超過 duration,自動過期移除;
  • 這兩種策略可以組合使用,用于場景如“用戶會話緩存”、“短期熱點數據”。

3.3 基于 JVM GC 的回收

  • Guava 提供了 weakKeys(), weakValues(), softValues() 等方法,利用不同強度的引用進行回收:

    • weakKeys():將緩存 key 按弱引用存放,若 key 對象僅被緩存引用,則可隨時被 GC 回收,相應條目自動失效;
    • weakValues():將緩存 value 按弱引用存放,若 value 對象不再被強引用,則可被 GC 回收;
    • softValues():將 value 以軟引用存放,當 JVM 內存不足時,GC 會優先回收這些軟引用對象;
  • 典型語法:

    Cache<String, byte[]> cache = CacheBuilder.newBuilder().maximumSize(1000).weakValues().build();
    
  • 面試高頻:若同時設置 weakKeys()weakValues(),則當 key 或 value 都失去任何強引用后,該條目會被 GC 回收。

3.3.1 GC 回收引發的緩存顛簸問題

當緩存條目使用弱引用或軟引用,一旦 JVM 觸發 GC,就可能一次性清空大批緩存數據。若該緩存頻繁被訪問,緩存將被迅速重新加載,導致連續觸發多次 GC 和緩存“嘩啦啦回補”的現象——CPU 消耗驟增,卻無法留住數據。

解決思路

  • 僅對內存占用較大的非熱點對象使用 softValues(),而不是對所有緩存。一旦發現緩存顛簸,可考慮放寬 GC 壓力或降低緩存容量;
  • 盡量使用基于容量+時間的回收,避免過度依賴 JVM GC;
  • 在緩存加載邏輯中加入適當延遲,防止短時間內同一批 key 被重復加載。

4. 常見緩存算法簡介

在這里插入圖片描述

除了 Guava 提供的默認 LRU,緩存領域常見還有兩種算法:

4.1 FIFO(先進先出)

  • 按“插入順序”回收:

    • 緩存滿時,移除最早插入的條目;
    • 結構簡單,但不考慮條目熱度;
    • 適用于“日志隊列”、“任務處理隊列”這類只關心先來先服務的場景。

4.2 LRU(最近最少使用)

  • 按“訪問順序”回收:

    • 每次 get()put() 時,將條目移至最近位置;
    • 滿載時移除最久未被訪問的條目;
    • 適用于“熱點數據需長時間保留”的場景,是一般緩存中最為常見的策略。

4.3 LFU(最近最不常用)

  • 按“訪問頻率”回收:

    • 維護每個條目的訪問計數;
    • 緩存滿時,移除訪問計數最少的條目;若存在多項訪問計數相同,則移除“最久未使用”者;
    • 適用于需要保留“高訪問頻次”數據的場景,但實現較復雜,需要額外維護計數與優先級隊列。

5. 簡易 LRU 實現——LinkedHashMap

在 Java 中,要實現一個輕量級的 LRU 緩存,最便捷的方式是利用 LinkedHashMap 提供的“訪問順序”功能:

public class LRUCache<K, V> extends LinkedHashMap<K, V> {private final int capacity;public LRUCache(int capacity) {// 初始容量 16,負載因子 0.75,accessOrder=true 表示按訪問順序排列super(16, 0.75f, true);this.capacity = capacity;}// 當 put 后,自動調用此方法判斷是否需要移除最老條目@Overrideprotected boolean removeEldestEntry(Map.Entry<K, V> eldest) {return size() > capacity;}
}
  • 構造參數說明

    • initialCapacity:初始哈希表桶數,默認 16;
    • loadFactor:負載因子(0.75f);
    • accessOrder=true:按照“訪問順序”保持雙向鏈表;
  • removeEldestEntry:在每次 put() 后自動調用,若返回 true,則移除“最久未訪問”者,即 LRU 算法的核心。

在這里插入圖片描述

5.1 功能局限與線程安全

  • 優勢:代碼簡潔,無需自行維護優先級隊列或計數器;

  • 局限

    1. 僅基于“條目數量”控制容量,不能指定基于“內存占用大小”回收;
    2. 無法設置“基于時間過期”或“基于訪問次數”回收;
  • 線程安全LinkedHashMap 本身并非線程安全,如需并發訪問,應加鎖或改用 ConcurrentLinkedHashMap / Guava Cache / Caffeine。


6. 操作系統層面的預讀與文件緩存

在這里插入圖片描述

在操作系統層面,對文件 I/O 緩存設計也非常智能,進一步支撐了高性能緩存架構。Linux 下可以通過 free 命令查看內存狀態,其中 cached 區域往往十分龐大:

$ free -htotal        used        free      shared  buff/cache   available
Mem:           16Gi       4.2Gi       2.5Gi       128Mi       9.4Gi       11Gi
Swap:         2.0Gi       512Mi       1.5Gi
  • buff/cache:表示操作系統將磁盤塊緩存在內存中的容量,包括文件系統頁緩存、目錄緩存等;
  • Readahead(預讀):當進程順序讀取文件時,內核會自動嘗試以“頁面”為單位預讀后續若干頁面,以減少隨機讀時的磁盤尋道開銷。
    在這里插入圖片描述

例如,若應用以 4KB 為單位讀取大型文件,內核可能在后臺提前載入 128KB 或更多連續頁面,由此實現“順序讀取性能≈內存讀取性能”的效果。

  • 完全加載策略:若某一小文件(如幾 MB)訪問頻率極高,可在應用啟動時一次將整個文件 mmap()read() 到內存(posix_fadvise(..., POSIX_FADV_WILLNEED)),確保后續訪問都命中內核緩存;

7. 緩存優化的一般思路

在實際項目中,引入進程內緩存時,可根據以下幾個準則:

  1. 緩存目標場景

    • 存在穩定的數據熱點(某些 key 會被反復訪問);
    • 讀操作遠多于寫操作;
    • 下游服務(數據庫、遠程接口)性能低,成為瓶頸;
    • 緩存一致性要求相對寬松,偶爾允許短暫的“陳舊”數據。
  2. 緩存大小與容量

    • 緩存容量過小,會導致“熱點”數據被頻繁淘汰,命中率低,性能提升有限;
    • 緩存容量過大,會占用大量堆空間,增加 GC 頻率與時長;
    • 通常通過監控緩存命中率(cache.stats().hitRate())來調整容量,推薦至少達到 50% 的命中率,若低于 10% 就要重新評估是否需要緩存。

在這里插入圖片描述

  1. 回收策略選擇

    • 默認使用 LRU,即 maximumSize(...)
    • 對于需要“短期熱點”或“超時失效”的數據,可結合 expireAfterWrite(...)expireAfterAccess(...)
    • 若緩存數據對象非常大,且不想占用堆內存,可考慮 weakValues()softValues(),但要避免“緩存顛簸”現象。
  2. 監控與統計

    • 開啟 recordStats(),收集命中、加載、移除次數等數據;
    • 定期導出或打印 cache.stats(),分析緩存命中率(hitRate)與平均加載時間(averageLoadPenalty);
    • 若發現加載成本過高,可考慮加大緩存容量或優化加載算法;
  3. 緩存失效與一致性

    • 當緩存中數據與源數據庫數據不一致時,需要設計緩存更新/清理策略(如主動失效、定時刷新或消息通知觸發刷新);
    • 對于對一致性要求極高場景,可使用“雙寫+事務+消息隊列+雙刪失效”等方案,見后續“緩存一致性”課時。
  4. 預加載 vs 惰性加載

    • 惰性加載(Lazy Loading):在第一次訪問時加載到緩存,常見于 LoadingCache
    • 預加載(Preloading):在應用啟動時或定時調度時一次性加載所有熱點數據,減少首次訪問延遲;
    • 若熱點集合較小且可預見,可采用預加載;若熱點動態且數據量大,優先使用惰性加載。

8. 緩存應用案例

  1. HTTP 304(Not Modified)緩存

    • 瀏覽器發送條件性請求:帶上 If-Modified-SinceETag
    • 服務端判斷資源是否自上次修改以來未發生變化,若無改動則直接返回 304,讓瀏覽器使用本地緩存;否則返回 200 并攜帶新的資源與緩存頭;
    • 這樣可以在瀏覽器端節省一次完整的資源下載,并允許操作系統與瀏覽器在內存/硬盤層面做更深層次的緩存。
  2. CDN(內容分發網絡)緩存

    • 用戶訪問某個靜態資源時,會首先到就近的 CDN 節點請求;
    • 若該節點已有緩存,直接返回給用戶;否則節點會向**源站(Origin)**拉取一份并緩存在本地;
    • CDN 緩存策略包括 TTL(Time-To-Live)、LRU 或 LFU,來自不同運營商或網絡環境下的緩存命中率優化直接影響用戶體驗與帶寬成本。
  3. 數據庫二級緩存

    • ORM 框架(如 Hibernate)常集成二級緩存,將熱點實體緩存在本地 heap 或分布式緩存中;
    • 在事務提交或數據更新時,需要將對應緩存項失效或更新;
    • 緩存失效策略與事務邊界息息相關,需要設計清晰的緩存注解或 AOP 攔截器。

9. 小結

進程內緩存(堆內緩存) 的設計思路與常見實現:

  1. 緩存本質與應用場景

    • 緩存用于調和下游“慢”與上游“快”之間的速度差異;
    • 典型場景包括:熱點數據查詢、配置讀取、會話管理、短期臨時數據。
  2. Guava LoadingCache

    • CacheBuilder 提供靈活配置:maximumSizeinitialCapacityconcurrencyLevel
    • 支持手動 put() 與自動加載(CacheLoader)兩種模式;
    • 可通過 invalidate() 手動移除,并通過 removalListener 監聽刪除事件;
    • 回收策略包括基于容量(LRU)、基于時間(expireAfterWrite/Access)與 JVM 引用回收(weakKeys/weakValues/softValues);
    • 避免“軟引用緩存顛簸”帶來的頻繁 GC 問題。
  3. 常見緩存算法

    • FIFO:先進先出,簡單但不考慮熱點;
    • LRU:最近最少使用,當前最流行,保留熱點;
    • LFU:最近最不常用,保留高頻訪問數據,支持頻次計數;
  4. 簡易 LRU 實現

    • 利用 LinkedHashMap 構造參數 accessOrder=true,覆寫 removeEldestEntry
    • 整體邏輯簡單,但不支持過期時間與并發安全,需要在生產環境中慎用或加鎖。
  5. 操作系統緩存與預讀

    • Linux 內核會自動執行 readahead,預讀后續頁面到 cached 區域;
    • 可手動使用 mmap()posix_fadvise() 等方式實現“完全加載”,適用于小文件的高頻訪問。
  6. 緩存優化一般思路

    • 在緩存容量、命中率與 JVM GC 之間做折中;
    • CDC(緩存、數據庫、集群)技術棧常見組合;
    • 監控 cache.stats() 指標,命中率需 ≥ 50% 才有較好收益;若 < 10% 則應卸載或重構緩存策略。
  7. 示例應用

    • HTTP 304、CDN 緩存;
    • 數據庫二級緩存;
    • Redis 作為分布式緩存,面向更大規模數據。

在這里插入圖片描述

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

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

相關文章

使用jstack排查CPU飆升的問題記錄

最近&#xff0c;看到短視頻傳播了一個使用jstack來協助排查CPU飆升的案例。我也是比較感興趣&#xff0c;參考了視頻博主的流程&#xff0c;自己做了下對應案例的實戰演練&#xff0c;在此&#xff0c;想做一下&#xff0c;針對相關問題模擬與排查演練的實戰過程記錄。 案例中…

Sql Server 中常用語句

1.創建用戶數據庫 --創建數據庫 use master --切換到master數據庫 go-- 終止所有與SaleManagerDB數據庫的連接 alter database SaleManagerDB set single_user with rollback immediate goif exists (select * from sysdatabases where nameSaleManagerDB) drop database Sal…

聯通專線賦能,億林網絡裸金屬服務器:中小企業 IT 架構升級優選方案

在當今數字化飛速發展的時代&#xff0c;中小企業面臨著日益增長的業務需求與復雜多變的市場競爭環境。如何構建高效、穩定且具性價比的 IT 架構&#xff0c;成為眾多企業突破發展瓶頸的關鍵所在。而億林網絡推出的 24 核 32G 裸金屬服務器&#xff0c;搭配聯通專線的千兆共享帶…

LangChain核心之Runnable接口底層實現

導讀&#xff1a;作為LangChain框架的核心抽象層&#xff0c;Runnable接口正在重新定義AI應用開發的標準模式。這一統一接口設計將模型調用、數據處理和API集成等功能封裝為可復用的邏輯單元&#xff0c;通過簡潔的管道符語法實現復雜任務的聲明式編排。 對于面臨AI應用架構選擇…

CSP嚴格模式返回不存在的爬蟲相關文件

文章目錄 說明示例&#xff08;返回404&#xff09;示例&#xff08;創建CSP例外&#xff09; 說明 日期&#xff1a;2025年6月4日。 CSP嚴格模式是default-src none&#xff0c;但有些web應用中&#xff0c;在爬蟲相關文件不存在的情況下&#xff0c;依舊返回了對應文件&…

DeviceNET從站轉EtherNET/IP主站在鹽化工行業的創新應用

在工業自動化飛速發展的今天&#xff0c;鹽化工行業也在積極探索智能化升級的路徑。其中&#xff0c;設備之間的高效通信與協同工作成為了提升生產效率和質量的關鍵。而JH-DVN-EIP疆鴻智能DeviceNET從站轉EtherNET/IP主站的技術應用&#xff0c;為鹽化工行業帶來了全新的解決方…

安裝 Nginx

個人博客地址&#xff1a;安裝 Nginx | 一張假鈔的真實世界 對于 Linux 平臺&#xff0c;Nginx 安裝包 可以從 nginx.org 下載。 Ubuntu: 版本Codename支持平臺12.04precisex86_64, i38614.04trustyx86_64, i386, aarch64/arm6415.10wilyx86_64, i386 在 Debian/Ubuntu 系統…

默認網關 -- 負責轉發數據包到其他網絡的設備(通常是路由器)

? 默認網關概括說明&#xff1a; 默認網關&#xff08;Default Gateway&#xff09;是網絡中一臺負責轉發數據包到其他網絡的設備&#xff08;通常是路由器&#xff09;。當一臺主機要訪問不在本地子網內的設備時&#xff0c;會將數據包發給默認網關&#xff0c;由它繼續轉發…

cv::FileStorage用法

cv::FileStorage 是 OpenCV 中的一個類&#xff0c;用于讀取和寫入結構化數據&#xff08;如 YAML、XML、JSON&#xff09;。它非常適合保存和加載諸如&#xff1a; 相機內參&#xff08;K、D&#xff09; 位姿&#xff08;R、T&#xff09; IMU 數據 配置參數 向量、矩陣、…

WebFuture:啟動服務提示Job webfuture.service/start failed with result ‘dependency‘處理辦法

問題分析&#xff1a; 當出現 Job webfuture.service/start failed with result dependency. 這樣的錯誤提示時&#xff0c;通常意味著 webfuture.service 這個服務在啟動時因為依賴關系的問題而未能成功啟動 解決辦法&#xff1a; 原因分析&#xff1a; webfuture.service 可…

Java 大視界 -- Java 大數據機器學習模型在遙感圖像變化檢測中的應用與改進(235)

??親愛的朋友們,熱烈歡迎來到 青云交的博客!能與諸位在此相逢,我倍感榮幸。在這飛速更迭的時代,我們都渴望一方心靈凈土,而 我的博客 正是這樣溫暖的所在。這里為你呈上趣味與實用兼具的知識,也期待你毫無保留地分享獨特見解,愿我們于此攜手成長,共赴新程!?? 全網…

HarmonyOS運動開發:精準估算室內運動的距離、速度與步幅

##鴻蒙核心技術##運動開發##Sensor Service Kit&#xff08;傳感器服務&#xff09;# 前言 在室內運動場景中&#xff0c;由于缺乏 GPS 信號&#xff0c;傳統的基于衛星定位的運動數據追蹤方法無法使用。因此&#xff0c;如何準確估算室內運動的距離、速度和步幅&#xff0c;…

商品模塊中的多規格設計:實現方式與電商/ERP系統的架構對比

在商品管理系統中&#xff0c;多規格設計&#xff08;Multi-Specification Product Design&#xff09;是一個至關重要但又極具挑戰性的領域。無論是面向消費者的電商系統&#xff0c;還是面向企業管理的ERP系統&#xff0c;對商品規格的處理方式直接影響庫存管理、訂單履約、數…

HTML 等價字符引用:系統化記憶指南

HTML 等價字符引用:系統化記憶指南 在 HTML 中,字符引用(Character Entity References)用于表示保留字符或特殊符號。我將提供一個系統化的方法來記憶這些重要實體,并解釋它們的實際應用。 什么是等價字符引用? HTML 字符引用有兩種形式: 命名實體:&entity_name…

Java 線程池原理詳解

Java 線程池原理詳解 一、引言 在高并發場景下&#xff0c;頻繁地創建與銷毀線程將帶來極大的性能開銷。為了提升資源復用性與程序響應速度&#xff0c;Java 提供了線程池機制&#xff08;java.util.concurrent 包&#xff09;。線程池通過復用線程、控制線程數量、任務排隊管…

Mybatis入門到精通

一&#xff1a;什么是Mybatis 二&#xff1a;Mybatis就是簡化jdbc代碼的 三&#xff1a;Mybatis的操作步驟 1&#xff1a;在數據庫中創建一個表&#xff0c;并添加數據 我們這里就省略了 2&#xff1a;Mybatis通過maven來導入坐標&#xff08;jar包&#xff09; 3&#xff1a…

化學方程式配平免費API接口教程

接口簡介&#xff1a; 根據反應物和生成物配平化學方程式。 請求地址&#xff1a; https://cn.apihz.cn/api/other/hxfcs.php 請求方式&#xff1a; POST或GET。 請求參數&#xff1a; 【名稱】【參數】【必填】【說明】 【用戶ID】【id】【是】【用戶中心的數字ID&#xff…

Spring學習筆記:Spring的基于注解的XML的詳細配置

按照劉Java的順序&#xff0c;應該是從基于XML的DI開始接著上面的關于IoC容器裝配。主要介紹學習Spring的XML基于注解的詳細配置。 第一步是搭建一個Spring的基礎工程&#xff08;maven管理&#xff09;&#xff0c;通過IoC機制獲取IoC容器的對象。 創建maven工程并在pom文件…

(四)動手實現多層感知機:深度學習中的非線性建模實戰

1 多層感知機&#xff08;MLP&#xff09; 多層感知機&#xff08;Multilayer Perceptron, MLP&#xff09;是一種前饋神經網絡&#xff0c;包含一個或多個隱藏層。它能夠學習數據中的非線性關系&#xff0c;廣泛應用于分類和回歸任務。MLP的每個神經元對輸入信號進行加權求和…

第十三篇:MySQL 運維自動化與可觀測性建設實踐指南

本篇重點介紹 MySQL 運維自動化的關鍵工具與流程&#xff0c;深入實踐如何構建高效可觀測體系&#xff0c;實現數據庫系統的持續穩定運行與故障快速響應。 一、為什么需要 MySQL 運維自動化與可觀測性&#xff1f; 運維挑戰&#xff1a; 手動備份容易遺漏或失敗&#xff1b; …