基于飛算JavaAI實現布隆過濾器防止緩存穿透:原理、實踐與全流程解析

引言:當緩存失效時,系統如何避免“雪崩式崩潰”?

在互聯網高并發場景中(如電商秒殺、社交平臺熱點新聞),緩存是提升系統性能的核心手段——將頻繁訪問的數據(如商品詳情、用戶信息)存儲在內存(如Redis)中,避免每次請求都查詢數據庫。但緩存并非萬能,當出現**“緩存穿透”**時,系統可能面臨嚴重風險:

什么是緩存穿透?

用戶請求的數據既不在緩存中,也不在數據庫中(例如惡意攻擊者故意查詢不存在的商品ID=999999),此時請求會直接穿透緩存層,打到數據庫上。若這類請求量巨大(如每秒數千次),數據庫會因無法承受負載而崩潰,最終導致整個服務不可用。

傳統解決方案的局限性

常見的防穿透方案包括:

  1. 緩存空值:當數據庫查詢結果為空時,仍緩存一個特殊標記(如null),但會浪費內存且需處理緩存與空值的邏輯;
  2. 接口校驗:對請求參數(如ID范圍)做基礎校驗(如ID必須大于0),但無法攔截精心構造的非法請求;
  3. 布隆過濾器:通過概率型數據結構快速判斷“某個數據一定不存在”,從根本上攔截無效請求,且內存占用極低。

其中,**布隆過濾器(Bloom Filter)**是業界公認的高效解決方案——它用極小的內存空間(例如存儲1億個數據僅需約100MB)記錄“可能存在的數據集合”,當請求到來時,先通過布隆過濾器判斷目標數據是否“可能存在于緩存/數據庫中”,若判斷為“一定不存在”,則直接攔截請求,避免無效查詢。

本文將基于飛算JavaAI低代碼平臺,詳細講解如何快速實現布隆過濾器防穿透方案,包含原理通俗解析、系統設計流程圖、關鍵代碼邏輯(附注釋)、飛算AI輔助生成的代碼示例,以及如何通過可視化配置降低開發門檻。最后還會用餅圖展示不同方案的優缺點對比,幫助讀者直觀理解技術選型依據。

一、布隆過濾器核心原理:用概率換效率的“黑魔法”

1.1 基礎概念:它到底是什么?

布隆過濾器是一種空間效率極高的概率型數據結構,用于判斷一個元素是否在一個集合中。它的特點是:

  • 如果判斷“可能存在”(可能誤判):實際不存在的元素可能被誤判為存在(但概率極低,可調節);
  • 如果判斷“一定不存在”(絕對準確):只要布隆過濾器說“不存在”,則該元素100%不在集合中;

核心優勢:用極小的內存(例如存儲1億個URL僅需約114MB)實現高效查詢(時間復雜度O(k),k為哈希函數個數),且支持快速插入和判斷。

1.2 工作原理:通過多個哈希函數“標記”數據

布隆過濾器的底層是一個長度為m的二進制位數組(初始全為0),以及k個不同的哈希函數(如 MurmurHash、SHA-1 等)。當插入一個元素時,執行以下操作:

  1. 用k個哈希函數分別計算該元素的哈希值,得到k個位置(范圍在0到m-1之間);
  2. 將位數組中這k個位置的值置為1;

當判斷一個元素是否存在時:

  1. 同樣用k個哈希函數計算該元素的k個位置;
  2. 檢查位數組中這k個位置是否全部為1
    • 如果全部為1 → 元素“可能存在”(可能有其他元素哈希到了相同位置,導致誤判);
    • 如果有任意一個位置為0 → 元素“一定不存在”(因為插入時所有位置都會被置為1);

1.3 關鍵參數:如何平衡內存與誤判率?

布隆過濾器的性能由三個參數決定:

  • 預期元素數量(n):需要存儲的數據總量(例如緩存中所有有效商品ID共100萬個);
  • 誤判率(p):可接受的“誤判為存在”的概率(通常設為0.01%1%,即1%100個請求中可能有1個誤判);
  • 位數組長度(m)和哈希函數個數(k):根據n和p通過公式計算得出:
    • 位數組長度:m=?nln?p(ln?2)2m = -\frac{n \ln p}{(\ln 2)^2}m=?(ln2)2nlnp? (例如n=100萬,p=0.01時,m≈9.6MB);
    • 哈希函數個數:k=mnln?2k = \frac{m}{n} \ln 2k=nm?ln2 (通常為5~10個);

實際開發中無需手動計算,Java開源庫(如Google的Guava)已提供封裝好的布隆過濾器實現,只需指定預期元素數量和誤判率即可。

二、系統設計:如何用飛算JavaAI集成布隆過濾器?

2.1 整體架構圖(文字描述+簡化流程)

我們將基于Spring Boot+Redis+飛算JavaAI構建一個防緩存穿透的商品查詢服務,架構分為四層:

  1. 客戶端層:用戶發起請求(如查詢商品ID=1001的詳情);
  2. 網關/接口層:接收請求,調用業務服務;
  3. 業務服務層(核心)
    • 布隆過濾器層:先判斷請求的商品ID是否“可能存在于有效數據集合中”;
      • 若布隆過濾器返回“一定不存在” → 直接攔截請求,返回“商品不存在”(避免查緩存和數據庫);
      • 若布隆過濾器返回“可能存在” → 繼續查詢緩存;
    • 緩存層(Redis):若緩存命中,直接返回數據;
    • 數據庫層(MySQL):若緩存未命中,查詢數據庫,并將結果寫入緩存(同時更新布隆過濾器,若為新數據);
  4. 數據存儲層:Redis(緩存)、MySQL(持久化數據)。

關鍵點:布隆過濾器需在服務啟動時預熱(加載所有有效商品ID),并在新增商品時動態更新(保證新數據能被正確判斷)。

2.2 核心流程圖(文字描述+步驟分解)

一定不存在
可能存在
緩存命中
緩存未命中
數據庫命中
數據庫未命中
用戶請求商品ID
布隆過濾器判斷
直接返回商品不存在
查詢Redis緩存
返回緩存數據
查詢MySQL數據庫
寫入Redis緩存
并更新布隆過濾器
返回商品不存在
返回數據庫數據

三、基于飛算JavaAI的實現步驟:低代碼如何簡化開發?

3.1 飛算JavaAI的核心助力

飛算JavaAI作為低代碼平臺,可通過可視化配置和AI輔助編碼,快速生成以下功能:

  • 布隆過濾器的初始化與預熱(自動生成加載有效數據到布隆過濾器的代碼);
  • 攔截邏輯的封裝(自動生成判斷“是否存在”的代碼,并集成到請求處理流程中);
  • 緩存與數據庫的交互邏輯(自動生成Redis查詢、MySQL查詢及緩存更新的代碼);

業務人員只需通過界面配置參數(如預期商品數量、誤判率),AI即可生成高可用的Java代碼,無需手動編寫復雜的位數組操作或哈希函數邏輯。

3.2 關鍵模塊實現詳解

模塊1:布隆過濾器初始化與預熱(服務啟動時加載有效數據)
需求細節:

系統啟動時,需要將數據庫中所有有效的商品ID(例如狀態為“上架”的商品)加載到布隆過濾器中,確保后續請求能正確判斷“可能存在”。

飛算JavaAI的解決方案:

通過可視化配置工具定義“數據源(MySQL表)→ 過濾條件(如status=1)→ 布隆過濾器參數(預期數量=10萬,誤判率=0.01)”,平臺自動生成初始化代碼。

關鍵代碼邏輯(飛算AI生成,簡化注釋版)
// 1. 布隆過濾器工具類(基于Guava庫,由飛算AI封裝)
@Component
public class BloomFilterUtil {private static BloomFilter<Long> productBloomFilter; // 商品ID布隆過濾器(假設商品ID為Long類型)private static final int EXPECTED_INSERTIONS = 100000; // 預期商品數量(根據業務配置)private static final double FPP = 0.01; // 誤判率1%@PostConstruct // Spring啟動時自動執行初始化public void init() {// 初始化布隆過濾器(Guava提供的高效實現)productBloomFilter = BloomFilter.create(Funnels.longFunnel(), // 指定數據類型為Long(商品ID)EXPECTED_INSERTIONS, FPP);// 從數據庫加載所有有效商品ID(狀態=1表示上架)List<Long> validProductIds = productService.loadValidProductIds(); for (Long productId : validProductIds) {productBloomFilter.put(productId); // 將有效ID加入過濾器}System.out.println("布隆過濾器預熱完成,已加載 " + validProductIds.size() + " 個商品ID");}// 判斷商品ID是否可能存在(供業務層調用)public static boolean mightContain(Long productId) {return productBloomFilter.mightContain(productId);}// 新增商品時更新布隆過濾器(如商品上架接口調用)public static void put(Long productId) {productBloomFilter.put(productId);}
}// 2. 商品服務:加載有效商品ID(由飛算AI生成數據庫查詢邏輯)
@Service
public class ProductService {@Autowiredprivate JdbcTemplate jdbcTemplate; // Spring Boot數據庫操作工具public List<Long> loadValidProductIds() {// 查詢狀態為1(上架)的商品IDString sql = "SELECT id FROM product WHERE status = 1";return jdbcTemplate.queryForList(sql, Long.class); // 返回所有有效商品ID列表}
}
關鍵點說明:
  • 自動預熱:通過@PostConstruct注解,服務啟動時自動執行init()方法,從數據庫加載有效商品ID并填充到布隆過濾器;
  • 參數可配置:預期數量(EXPECTED_INSERTIONS)和誤判率(FPP)可通過飛算AI的可視化界面調整(如業務方告知“預計有50萬商品”,則修改為500000,AI自動重新計算位數組大小);
  • 動態更新:當新增商品上架時(如調用productService.addProduct()),需同步調用BloomFilterUtil.put(productId)更新過濾器(后續會講解)。
模塊2:攔截無效請求(請求到來時先判斷布隆過濾器)
需求細節:

用戶請求商品詳情時,先通過布隆過濾器判斷該商品ID是否“可能存在于有效集合中”:

  • 若判斷為“一定不存在”(即布隆過濾器返回false)→ 直接返回“商品不存在”,避免查詢緩存和數據庫;
  • 若判斷為“可能存在” → 繼續查詢Redis緩存;
飛算JavaAI的解決方案:

通過可視化配置“攔截邏輯位置(Controller層)→ 判斷條件(調用BloomFilterUtil.mightContain)”,平臺自動生成請求攔截代碼。

關鍵代碼邏輯(飛算AI生成,簡化注釋版)
// 1. 商品詳情Controller(接收用戶請求)
@RestController
@RequestMapping("/api/product")
public class ProductController {@Autowiredprivate ProductService productService; // 業務服務@GetMapping("/{productId}")public ResponseEntity<Product> getProduct(@PathVariable Long productId) {// 第一步:通過布隆過濾器攔截無效請求(飛算AI自動生成判斷邏輯)if (!BloomFilterUtil.mightContain(productId)) {return ResponseEntity.status(HttpStatus.NOT_FOUND).body(null); // 直接返回404}// 第二步:查詢緩存(由飛算AI生成Redis交互邏輯)Product cachedProduct = redisService.getProductFromCache(productId);if (cachedProduct != null) {return ResponseEntity.ok(cachedProduct); // 緩存命中}// 第三步:查詢數據庫(由飛算AI生成MySQL交互邏輯)Product dbProduct = productService.getProductFromDb(productId);if (dbProduct != null) {// 寫入緩存并更新布隆過濾器(若為新商品)redisService.cacheProduct(dbProduct);if (!BloomFilterUtil.mightContain(productId)) { // 可能是新上架的商品BloomFilterUtil.put(productId); }return ResponseEntity.ok(dbProduct);}// 數據庫也未找到(理論上不會發生,因為布隆過濾器已攔截)return ResponseEntity.status(HttpStatus.NOT_FOUND).body(null);}
}// 2. Redis服務(簡化版,由飛算AI生成緩存操作邏輯)
@Service
public class RedisService {@Autowiredprivate RedisTemplate<String, Product> redisTemplate;public Product getProductFromCache(Long productId) {String key = "product:" + productId;return redisTemplate.opsForValue().get(key); // 從Redis獲取緩存}public void cacheProduct(Product product) {String key = "product:" + product.getId();redisTemplate.opsForValue().set(key, product, 1, TimeUnit.HOURS); // 緩存1小時}
}
關鍵點說明:
  • 前置攔截:在Controller的最開始處調用BloomFilterUtil.mightContain(),無效請求直接返回,減少后續邏輯執行;
  • 動態更新處理:若查詢數據庫發現商品存在但布隆過濾器未包含(例如新上架商品未預熱),則調用BloomFilterUtil.put()更新過濾器(避免后續請求被誤攔截);
  • 緩存交互:Redis操作通過Spring Data Redis的RedisTemplate實現,飛算AI自動生成序列化/反序列化邏輯(如Product對象轉JSON存儲)。
模塊3:緩存與數據庫的完整交互流程
補充說明:

當請求的商品ID通過布隆過濾器攔截后,系統會按以下順序查詢數據:

  1. 查緩存(Redis):若命中,直接返回(最快路徑);
  2. 查數據庫(MySQL):若命中,寫入緩存并更新布隆過濾器(若為新商品),再返回;
  3. 均未命中:返回“商品不存在”(理論上布隆過濾器已攔截,此分支極少觸發)。
關鍵代碼邏輯(飛算AI生成的數據庫查詢)
// 商品服務中的數據庫查詢方法(由飛算AI生成)
@Service
public class ProductService {@Autowiredprivate JdbcTemplate jdbcTemplate;public Product getProductFromDb(Long productId) {String sql = "SELECT id, name, price, status FROM product WHERE id = ?";try {return jdbcTemplate.queryForObject(sql, new Object[]{productId}, (rs, rowNum) -> {Product product = new Product();product.setId(rs.getLong("id"));product.setName(rs.getString("name"));product.setPrice(rs.getDouble("price"));product.setStatus(rs.getInt("status"));return product;});} catch (EmptyResultDataAccessException e) {return null; // 數據庫未找到}}
}

四、飛算JavaAI的可視化配置示例:如何降低開發門檻?

4.1 可視化參數配置界面(模擬說明)

業務人員通過飛算平臺的Web界面配置以下參數(無需寫代碼):

  • 布隆過濾器參數
    • 預期商品數量:輸入“100000”(根據數據庫統計);
    • 誤判率:選擇“1%”(平衡內存與準確性);
  • 數據源配置
    • 數據庫類型:MySQL;
    • 表名:product;
    • 過濾條件:status=1(只加載上架商品);
  • 攔截規則
    • 請求路徑:/api/product/{productId};
    • 攔截條件:布隆過濾器判斷為“不存在”時返回404;

平臺根據上述配置,自動生成對應的Java代碼(包括布隆過濾器初始化、攔截邏輯、緩存交互等),業務人員只需預覽生成的代碼并確認即可。

4.2 生成的代碼結構(簡化目錄)

src/main/java/
├── com/example/demo/
│   ├── config/               # 飛算AI生成的配置類
│   │   └── BloomFilterConfig.java  # 布隆過濾器參數配置
│   ├── controller/           # 控制器(自動生成攔截邏輯)
│   │   └── ProductController.java
│   ├── service/              # 業務服務(自動生成數據庫/緩存操作)
│   │   ├── ProductService.java
│   │   └── RedisService.java
│   ├── util/                 # 工具類(自動生成布隆過濾器工具)
│   │   └── BloomFilterUtil.java
│   └── entity/               # 數據模型
│       └── Product.java

五、方案對比:布隆過濾器 vs 傳統防穿透方法(餅圖可視化)

5.1 不同防穿透方案的優缺點對比

方案核心原理優點缺點內存占用適用場景
緩存空值對空結果也緩存(如緩存null)實現簡單,無需額外組件浪費內存(需緩存大量空標記);需處理空值邏輯高(尤其無效請求多時)無效請求極少的小型系統
接口校驗校驗參數合法性(如ID范圍)實現簡單,攔截明顯非法請求無法攔截精心構造的合法但不存在的ID(如ID=999999)極低輔助手段(不能單獨使用)
布隆過濾器概率型數據結構判斷“可能存在”內存占用極低(1億數據約100MB);絕對攔截“一定不存在”的請求有極低誤判率(可調節);需預熱和動態更新極低高并發、大流量系統首選

5.2 餅圖:內存占用對比(假設存儲100萬條數據)

0%100%0%存儲100萬條數據時的內存占用對比布隆過濾器(誤判率1%)緩存空值(每個空標記100字節)無防穿透(直接查庫)

說明:布隆過濾器僅需約9.6MB存儲100萬條數據,而緩存空值(假設每個空標記占100字節)需約100MB(實際更大),無防穿透方案則無額外內存開銷但數據庫壓力大。

六、項目落地流程總結:從需求到上線的關鍵步驟

6.1 階段1:需求分析與參數確認(0-1天)

  • 與業務方確認:預期數據量(如商品總數)、可接受的誤判率(通常1%)、無效請求的占比(用于評估防穿透必要性);

6.2 階段2:飛算JavaAI配置與代碼生成(0-1天)

  • 通過可視化界面配置布隆過濾器參數(預期數量、誤判率)、數據源(數據庫表及過濾條件);
  • 定義攔截規則(哪些接口需要防穿透,如商品查詢、訂單查詢);
  • 平臺自動生成初始化、攔截邏輯、緩存交互的Java代碼;

6.3 階段3:測試與優化(1天)

  • 壓測驗證:模擬大量無效請求(如查詢不存在的ID=999999),確認是否被攔截;
  • 調整參數:若誤判率過高(如業務要求更嚴格),通過飛算AI調整誤判率并重新生成代碼;
  • 動態更新測試:新增商品后,驗證布隆過濾器是否自動包含新ID;

6.4 階段4:上線與監控(持續)

  • 生產環境部署,監控布隆過濾器的命中率(通過日志統計攔截的無效請求數量);
  • 定期優化:根據業務增長調整預期數據量(如商品總數從100萬增至500萬時,通過飛算AI重新配置參數)。

結語:布隆過濾器+飛算JavaAI=高并發系統的“防護盾”

緩存穿透是高并發系統的常見“殺手”,而布隆過濾器通過概率型數據結構以極低的內存代價實現了高效的攔截能力。本文基于飛算JavaAI平臺,展示了如何通過可視化配置和AI輔助編碼,快速實現從布隆過濾器初始化、請求攔截到緩存交互的全流程防穿透方案。

對于企業而言,這種方案不僅降低了開發門檻(業務人員可參與配置),還顯著提升了系統的穩定性和可維護性(代碼由平臺生成,減少人為錯誤)。未來,隨著飛算JavaAI對更多AI算法(如動態調整布隆過濾器參數)的支持,防穿透方案將更加智能和高效。

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

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

相關文章

DeepResearch開源與閉源方案對比

在這個AI不再只是聊天工具的時代&#xff0c;"深度研究"已經成為大語言模型&#xff08;LLM&#xff09;的一項新能力。先進的LLM不再只是給出快速的一次性回答&#xff0c;而是可以像研究助手一樣工作——搜索網上信息&#xff0c;調用各種工具&#xff08;比如搜索…

UniApp 頁面傳參方式詳解

在 UniApp 開發中&#xff0c;頁面間參數傳遞是核心功能之一。以下是 8 種常用的傳參方式&#xff0c;每種方式都有其適用場景和特點&#xff1a;一、URL 拼接傳參&#xff08;最常用&#xff09; 適用場景&#xff1a;簡單數據傳遞&#xff0c;如 ID、狀態值等基礎類型數據 實…

音頻分類標注工具

pyqt 分類標注工具&#xff1a;import glob import sys import json import os from PyQt5.QtWidgets import (QApplication, QMainWindow, QTableWidget, QTableWidgetItem,QSplitter, QVBoxLayout, QWidget, QPushButton, QRadioButton,QButtonGroup, QLabel, QHBoxLayout, Q…

云計算-Kubernetes+Istio 實現金絲雀發布:流量管理、熔斷、流量鏡像、ingreess、污點及pv案例實戰

介紹 在微服務架構中,如何安全、高效地實現服務發布與流量管理是保障業務穩定性的核心挑戰。金絲雀發布(Canary Release)、灰度發布等策略通過精細化的流量控制,可有效降低新版本上線風險, Istio 作為主流的服務網格(Service Mesh)工具。 此次Istio 在 Kubernetes 集群…

12.web api 3

定時器-間歇函數

ComfyUI進階:EchoMimic插件全解析,讓靜態肖像實現音頻驅動的精準口型動畫

在數字內容創作中&#xff0c;讓靜態肖像“開口說話”并做出自然表情&#xff0c;是提升交互感與沉浸感的關鍵。傳統動畫制作需專業人員逐幀調整口型與表情&#xff0c;成本高且效率低。ComfyUI的EchoMimic插件通過音頻驅動技術&#xff0c;實現了“輸入音頻→自動生成匹配口型…

鏈式前向星、vector存圖

場景設定 想象你是一個社交達人&#xff0c;要記錄你和所有朋友的關系&#xff08;這就是“圖”&#xff09;。每個朋友是一個節點&#xff0c;關系是一條邊。你需要快速回答&#xff1a;“我有哪些朋友&#xff1f;”&#xff08;遍歷鄰居&#xff09;。方式1&#xff1a;鏈式…

YAML 中定義 List 的幾種方式

在 YAML 配置文件中定義 List 并在 Spring 應用中注入是非常常見的操作&#xff0c;下面詳細介紹具體寫法和注入方式。一、YAML 中定義 List 的幾種方式1. 縮進式寫法&#xff08;推薦&#xff09;最常用的方式&#xff0c;通過短橫線 - 加空格表示列表項&#xff1a;yaml# app…

C# 反射和特性(自定義特性)

自定義特性 你或許已經注意到了&#xff0c;應用特性的語法和之前見過的其他語法有很大不同。你可能會覺得特 性是一種完全不同的結構類型&#xff0c;其實不是&#xff0c;特性只是一種特殊的類。 有關特性類的一些要點如下。 用戶自定義的特性類叫作自定義特性。所有特性類都…

科目二的四個電路

一.K21電動機單連續運轉接線(帶點動控制)1.電路圖2.主線路這可很明了,是一條直線,從上接到下就OK了,然后從熱繼電器出來,接到SB3按鈕的常閉觸點上接著往下走一端接到SB2的常閉觸點上,接著往下走&#xff0c;走到接觸器的線圈上,從L2借一條火線出來,從熔斷器的上端接入,另一端接…

【位運算】查詢子數組最大異或值|2693

本文涉及知識點 位運算、狀態壓縮、枚舉子集匯總 3277. 查詢子數組最大異或值 給你一個由 n 個整數組成的數組 nums&#xff0c;以及一個大小為 q 的二維整數數組 queries&#xff0c;其中 queries[i] [li, ri]。 對于每一個查詢&#xff0c;你需要找出 nums[li…ri] 中任…

HTML DOM 方法

HTML DOM 方法 引言 HTML DOM&#xff08;文檔對象模型&#xff09;是HTML文檔的編程接口&#xff0c;它允許開發者通過JavaScript來操作HTML文檔中的元素。DOM 方法是DOM編程的核心&#xff0c;它提供了豐富的操作手段來改變網頁的結構、樣式和行為。本文將詳細介紹HTML DOM中…

w嵌入式分享合集68

自己的原文哦~ https://blog.51cto.com/whaosoft/14133002 一、一鍵開關機電路的設計方案 方案一&#xff1a;電路圖 一鍵開關機電路分析如下&#xff1a; 電路工作流程如下&#xff1a; Key按下瞬間&#xff0c;Q2、Q1導通&#xff0c;7805輸入電壓在8.9V左右&…

FFmpeg QoS 處理

FFmpeg 中的 QoS (服務質量) 處理主要關注于實時流媒體傳輸中的時序控制、丟幀策略和網絡適應等方面。以下是 FFmpeg 中 QoS 相關的關鍵機制和配置方法。1. 基本 QoS 機制丟幀策略 (Frame Dropping)cAVDictionary *options NULL; av_dict_set(&options, "framedrop&q…

TexStudio中的Latex,PDFLatex,XeLatex和LuaLatex的區別

多種LaTeX編譯器一、多種LaTeX編譯器 1.1 PDFLaTeX&#xff08;1994年&#xff09; 默認、最常用的引擎。 輸入文件通常是 ASCII 或 UTF-8 編碼&#xff08;但中文需要 CJK 宏包或 ctex 宏包支持&#xff09;。 字體選擇受限&#xff1a;只能使用 TeX 自帶的字體或者 Type 1…

容器化部署:用Docker封裝機器翻譯模型與服務詳解

文章目錄一、機器翻譯容器化的技術棧選型1.1 為什么需要容器化MT模型&#xff1f;1.2 基礎鏡像選擇對比1.3 典型依賴分層方案1.4 性能對比&#xff08;容器化 vs 原生部署&#xff09;二、關鍵部署模式2.1 輕量級API服務封裝2.2 模型熱更新策略三、Docker鏡像構建3.1 編寫Docke…

leetcode_42 接雨水

1. 題意 給定 n 個非負整數表示每個寬度為 1 的柱子的高度圖&#xff0c;計算按此排列的柱子&#xff0c;下雨之后能接多少雨水。 2. 題解 這個題不會做&#xff0c;全部是看得題解捏。 不過能看懂題解感覺自己也很棒了&#xff01; 看完題解后感覺最難的是如何求出有多少…

Spring Boot 整合 Thymeleaf 模板引擎:從零開始的完整指南

引言&#xff1a;為什么選擇 Thymeleaf&#xff1f; Thymeleaf 是一個現代化的服務器端 Java 模板引擎&#xff0c;專為 Web 開發而設計。與 JSP 不同&#xff0c;Thymeleaf 模板是純 HTML 文件&#xff0c;可以直接在瀏覽器中預覽&#xff0c;無需后端服務器支持。這種"…

pytest介紹(python測試框架)(@pytest.mark.parametrize、@pytest.fixtures)

文章目錄**1. 核心特點**- **簡潔易用**&#xff1a;無需復雜的配置&#xff0c;只需編寫簡單的函數或類即可進行測試。- **豐富的斷言**&#xff1a;直接使用 Python 內置的 assert 語句&#xff0c;失敗時提供詳細的錯誤信息。- **自動發現測試**&#xff1a;通過約定的命名規…

[Python 基礎課程]繼承

在 Python 的面向對象編程&#xff08;OOP&#xff09;中&#xff0c;繼承&#xff08;Inheritance&#xff09; 是一種重要的機制&#xff0c;它允許一個類&#xff08;稱為子類或派生類&#xff09;從另一個類&#xff08;稱為父類、基類或超類&#xff09;中繼承屬性和方法。…