Redis 緩存穿透、擊穿、雪崩:防御與解決方案大全

🛡? Redis 緩存穿透、擊穿、雪崩:防御與解決方案大全

文章目錄

  • 🛡? Redis 緩存穿透、擊穿、雪崩:防御與解決方案大全
  • 🧠 一、緩存穿透:防御不存在數據的攻擊
    • 💡 問題本質與危害
    • 🛡? 解決方案
    • 📊 布隆過濾器 vs 空值緩存
  • ? 二、緩存擊穿:保護熱點數據瞬間失效
    • 💡 問題本質與危害
    • 🛡? 解決方案
    • 📊 緩存擊穿解決方案對比
  • ?? 三、緩存雪崩:預防大規模緩存失效
    • 💡 問題本質與危害
    • 🛡? 解決方案
    • 📊 緩存雪崩解決方案對比
  • 🚀 四、實戰案例:電商與秒殺場景
    • 🛒 電商商品詳情頁防護
    • ? 秒殺系統緩存防護
    • 📊 電商場景防護策略對比
  • 💡 五、總結與最佳實踐
    • 📋 防護策略 Checklist
    • 🏗? 架構設計建議
    • 🔧 應急響應方案
    • 🚀 性能優化建議

🧠 一、緩存穿透:防御不存在數據的攻擊

💡 問題本質與危害

??緩存穿透????是指查詢????根本不存在的數據????,導致請求直接穿透緩存到達數據庫:

不存在
存在
惡意請求
查詢緩存
數據是否存在?
查詢數據庫
返回緩存數據
數據庫壓力劇增
系統崩潰風險

??攻擊場景??:

  1. 惡意請求隨機ID或不存在的關鍵詞
  2. 爬蟲遍歷所有可能的ID 業
  3. 務邏輯缺陷導致查詢無效數據

🛡? 解決方案

  1. 布隆過濾器(Bloom Filter)
    ??原理??:使用概率型數據結構快速判斷元素是否存在
public class BloomFilterProtection {private BloomFilter<String> bloomFilter;private Jedis jedis;public BloomFilterProtection() {// 初始化布隆過濾器this.bloomFilter = BloomFilter.create(Funnels.stringFunnel(StandardCharsets.UTF_8), 1000000, // 預期元素數量0.01     // 誤判率);// 預熱數據:將已有數據加入過濾器loadExistingData();}public Object getData(String key) {// 1. 首先檢查布隆過濾器if (!bloomFilter.mightContain(key)) {// 肯定不存在,直接返回return null;}// 2. 檢查緩存Object value = jedis.get(key);if (value != null) {return value;}// 3. 檢查數據庫value = database.get(key);if (value != null) {// 緩存并返回jedis.setex(key, 300, serialize(value));return value;} else {// 記錄不存在的Key,避免重復查詢jedis.setex(key, 60, "NULL"); // 緩存空值return null;}}private void loadExistingData() {// 從數據庫加載所有存在的KeyList<String> allKeys = database.getAllKeys();for (String key : allKeys) {bloomFilter.put(key);}}
}
  1. 空值緩存與惡意請求識別
public class NullCacheProtection {private static final String NULL_VALUE = "NULL";private static final int NULL_CACHE_TIME = 60; // 空值緩存60秒public Object getDataWithNullCache(String key) {// 1. 檢查緩存Object value = jedis.get(key);if (NULL_VALUE.equals(value)) {// 之前已確認為空值return null;}if (value != null) {return value;}// 2. 檢查數據庫value = database.get(key);if (value != null) {jedis.setex(key, 300, serialize(value));return value;} else {// 緩存空值,設置較短過期時間jedis.setex(key, NULL_CACHE_TIME, NULL_VALUE);// 記錄訪問頻率,識別惡意請求recordAccessPattern(key);return null;}}private void recordAccessPattern(String key) {String counterKey = "access:counter:" + key;long count = jedis.incr(counterKey);jedis.expire(counterKey, 60);if (count > 100) { // 60秒內超過100次訪問// 識別為惡意請求,加入黑名單jedis.sadd("blacklist:keys", key);jedis.expire(key, 3600); // 黑名單1小時}}
}

📊 布隆過濾器 vs 空值緩存

方案優點缺點適用場景
布隆過濾器內存占用小,判斷快有誤判率,需要預熱海量數據存在性判斷
空值緩存實現簡單,無額外依賴可能緩存大量無效Key數據量不大,惡意請求較少
組合方案綜合優勢,防護全面實現復雜度較高高安全要求場景

? 二、緩存擊穿:保護熱點數據瞬間失效

💡 問題本質與危害

??緩存擊穿????是指????熱點Key在過期瞬間????,大量并發請求直接訪問數據庫:

客戶端1客戶端2客戶端3Redis緩存數據庫熱點Key同時過期獲取熱點Key返回null(已過期)獲取熱點Key返回null(已過期)獲取熱點Key返回null(已過期)查詢數據查詢數據查詢數據瞬間高并發壓力返回數據返回數據返回數據客戶端1客戶端2客戶端3Redis緩存數據庫

🛡? 解決方案

  1. 互斥鎖(Mutex Lock)
    ??原理??:只允許一個線程重建緩存,其他線程等待
public class MutexLockSolution {private static final String LOCK_PREFIX = "lock:";private static final int LOCK_TIMEOUT = 3000; // 鎖超時3秒public Object getDataWithLock(String key) {// 1. 嘗試從緩存獲取Object value = jedis.get(key);if (value != null) {return value;}// 2. 獲取分布式鎖String lockKey = LOCK_PREFIX + key;boolean locked = tryLock(lockKey);if (locked) {try {// 3. 再次檢查緩存(雙重檢查鎖)value = jedis.get(key);if (value != null) {return value;}// 4. 查詢數據庫value = database.get(key);if (value != null) {// 5. 寫入緩存jedis.setex(key, 300, serialize(value));}return value;} finally {// 6. 釋放鎖releaseLock(lockKey);}} else {// 未獲取到鎖,短暫等待后重試try {Thread.sleep(100);} catch (InterruptedException e) {Thread.currentThread().interrupt();}return getDataWithLock(key); // 重試}}private boolean tryLock(String lockKey) {// 使用SETNX實現分布式鎖String result = jedis.set(lockKey, "locked", "NX", "PX", LOCK_TIMEOUT);return "OK".equals(result);}private void releaseLock(String lockKey) {jedis.del(lockKey);}
}
  1. 邏輯過期與永不過期策略
public class LogicalExpirationSolution {private static class CacheData {Object data;long expireTime; // 邏輯過期時間public boolean isExpired() {return System.currentTimeMillis() > expireTime;}}public Object getDataWithLogicalExpire(String key) {// 1. 從緩存獲取數據String cacheValue = jedis.get(key);if (cacheValue == null) {// 緩存不存在,正常加載return loadDataFromDb(key);}// 2. 反序列化CacheData cacheData = deserialize(cacheValue);// 3. 檢查是否邏輯過期if (!cacheData.isExpired()) {return cacheData.data;}// 4. 已過期,獲取鎖重建緩存String lockKey = "rebuild:" + key;if (tryLock(lockKey)) {try {// 再次檢查是否已被其他線程更新String latestValue = jedis.get(key);CacheData latestData = deserialize(latestValue);if (latestData.isExpired()) {// 重建緩存Object newData = database.get(key);CacheData newCacheData = new CacheData();newCacheData.data = newData;newCacheData.expireTime = System.currentTimeMillis() + 300000; // 5分鐘jedis.set(key, serialize(newCacheData));return newData;} else {return latestData.data;}} finally {releaseLock(lockKey);}} else {// 未獲取到鎖,返回舊數據return cacheData.data;}}
}
  1. 熱點數據預熱與監控
public class HotKeyMonitor {private static final double HOT_THRESHOLD = 1000; // QPS閾值public void monitorHotKeys() {// 定時分析熱點KeyScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);scheduler.scheduleAtFixedRate(() -> {Map<String, Long> accessStats = getAccessStatistics();for (Map.Entry<String, Long> entry : accessStats.entrySet()) {if (entry.getValue() > HOT_THRESHOLD) {// 發現熱點Key,提前刷新preloadHotKey(entry.getKey());}}}, 0, 30, TimeUnit.SECONDS); // 每30秒檢查一次}private void preloadHotKey(String key) {// 1. 獲取數據Object data = database.get(key);// 2. 異步刷新緩存(使用更長的過期時間)CompletableFuture.runAsync(() -> {jedis.setex(key, 3600, serialize(data)); // 1小時過期log.info("熱點Key {} 已預熱", key);});}
}

📊 緩存擊穿解決方案對比

方案優點缺點適用場景
互斥鎖保證數據一致性,實現簡單有等待時間,可能阻塞數據一致性要求高的場景
邏輯過期無等待時間,用戶體驗好可能返回舊數據,實現復雜可接受短暫數據不一致的場景
永不過期+異步更新完全避免擊穿,性能好數據更新延遲,復雜度高極少變更的熱點數據

?? 三、緩存雪崩:預防大規模緩存失效

💡 問題本質與危害

??緩存雪崩????是指????大量Key同時失效????,導致所有請求直接訪問數據庫:

大量緩存Key同時失效
海量請求直達數據庫
數據庫連接池占滿
數據庫響應變慢
應用線程阻塞
系統全面崩潰

典型場景??:

  1. 緩存服務器重啟
  2. 大量Key設置相同過期時間
  3. 緩存服務故障

🛡? 解決方案

  1. 隨機過期時間策略
public class RandomExpirationSolution {private static final int BASE_EXPIRE = 3600; // 基礎過期時間1小時private static final int RANDOM_RANGE = 600; // 隨機范圍10分鐘public void setWithRandomExpire(String key, Object value) {// 生成隨機過期時間int randomExpire = BASE_EXPIRE + ThreadLocalRandom.current().nextInt(RANDOM_RANGE);jedis.setex(key, randomExpire, serialize(value));}public void batchSetWithRandomExpire(Map<String, Object> dataMap) {for (Map.Entry<String, Object> entry : dataMap.entrySet()) {setWithRandomExpire(entry.getKey(), entry.getValue());}}
}
  1. 緩存永不過期 + 異步更新
public class NeverExpireSolution {private ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(5);public void setWithBackgroundRefresh(String key, Object value) {// 1. 設置永不過期的緩存jedis.set(key, serialize(value));// 2. 啟動后臺刷新任務scheduler.scheduleAtFixedRate(() -> {try {Object freshData = database.get(key);if (freshData != null) {jedis.set(key, serialize(freshData));}} catch (Exception e) {log.error("后臺刷新緩存失敗: {}", key, e);}}, 30, 30, TimeUnit.MINUTES); // 每30分鐘刷新一次}
}
  1. 多級緩存架構
public class MultiLevelCache {private LoadingCache<String, Object> localCache;private Jedis redis;public MultiLevelCache() {// 初始化本地緩存(Guava Cache)this.localCache = Caffeine.newBuilder().maximumSize(10000).expireAfterWrite(5, TimeUnit.MINUTES).refreshAfterWrite(1, TimeUnit.MINUTES).build(this::loadFromRedis);}public Object get(String key) {try {// 1. 首先嘗試本地緩存return localCache.get(key);} catch (Exception e) {// 2. 降級到Redisreturn loadFromRedis(key);}}private Object loadFromRedis(String key) {Object value = redis.get(key);if (value == null) {// 3. 最終降級到數據庫value = database.get(key);if (value != null) {redis.setex(key, 3600, serialize(value));}}return value;}
}
  1. 熔斷降級與限流保護
public class CircuitBreakerProtection {private final CircuitBreaker circuitBreaker;private static final int MAX_QPS = 1000;public Object getDataWithProtection(String key) {// 1. 檢查熔斷器狀態if (circuitBreaker.isOpen()) {return getFallbackData(key);}try {// 2. 限流保護if (!rateLimiter.tryAcquire()) {return getFallbackData(key);}// 3. 正常業務邏輯Object value = jedis.get(key);if (value == null) {value = database.get(key);if (value != null) {jedis.setex(key, 300, serialize(value));}}// 4. 記錄成功,重置熔斷器circuitBreaker.recordSuccess();return value;} catch (Exception e) {// 5. 記錄失敗,可能觸發熔斷circuitBreaker.recordFailure();return getFallbackData(key);}}private Object getFallbackData(String key) {// 降級策略:返回默認值或緩存舊數據return Collections.emptyMap();}
}

📊 緩存雪崩解決方案對比

方案優點缺點適用場景
隨機過期時間實現簡單,效果明顯不能完全避免雪崩預防性措施
永不過期+異步更新完全避免雪崩數據更新有延遲數據變更不頻繁的場景
多級緩存提供額外保護層增加系統復雜度高可用要求場景
熔斷降級保護數據庫免于崩潰影響用戶體驗極端情況下的保護措施

🚀 四、實戰案例:電商與秒殺場景

🛒 電商商品詳情頁防護

public class ProductDetailService {private static final String PRODUCT_PREFIX = "product:";private BloomFilter<String> bloomFilter;private RateLimiter rateLimiter;public ProductDetail getProductDetail(Long productId) {String key = PRODUCT_PREFIX + productId;// 1. 布隆過濾器防護if (!bloomFilter.mightContain(key)) {return null; // 肯定不存在}// 2. 限流防護if (!rateLimiter.tryAcquire()) {throw new RateLimitException("訪問過于頻繁");}// 3. 緩存查詢ProductDetail detail = jedis.get(key);if (detail != null) {return detail;}// 4. 互斥鎖重建緩存String lockKey = "lock:" + key;if (tryLock(lockKey)) {try {// 雙重檢查detail = jedis.get(key);if (detail != null) {return detail;}// 數據庫查詢detail = productDao.getById(productId);if (detail != null) {// 設置隨機過期時間int expireTime = 3600 + ThreadLocalRandom.current().nextInt(600);jedis.setex(key, expireTime, serialize(detail));} else {// 緩存空值jedis.setex(key, 300, "NULL");}return detail;} finally {releaseLock(lockKey);}} else {// 等待后重試try {Thread.sleep(100);return getProductDetail(productId);} catch (InterruptedException e) {Thread.currentThread().interrupt();throw new RuntimeException("獲取商品詳情失敗");}}}
}

? 秒殺系統緩存防護

public class SeckillService {private static final String STOCK_PREFIX = "seckill:stock:";private static final String ITEM_PREFIX = "seckill:item:";public SeckillResult seckill(Long userId, Long itemId) {String stockKey = STOCK_PREFIX + itemId;String itemKey = ITEM_PREFIX + itemId;// 1. 校驗商品是否存在if (!jedis.exists(itemKey)) {return SeckillResult.error("商品不存在");}// 2. Lua腳本保證原子性操作String script = """local stockKey = KEYS[1]local stock = tonumber(redis.call('GET', stockKey))if stock <= 0 thenreturn 0endredis.call('DECR', stockKey)return 1""";Long result = (Long) jedis.eval(script, 1, stockKey);if (result == 1) {// 3. 扣減成功,創建訂單String orderId = createOrder(userId, itemId);return SeckillResult.success(orderId);} else {return SeckillResult.error("庫存不足");}}public void preheatSeckillData(Long itemId, Integer stock) {// 預熱秒殺數據String stockKey = STOCK_PREFIX + itemId;String itemKey = ITEM_PREFIX + itemId;// 1. 設置庫存(永不過期)jedis.set(stockKey, stock.toString());// 2. 設置商品信息(邏輯過期)SeckillItem item = seckillDao.getItem(itemId);jedis.set(itemKey, serialize(item));// 3. 啟動后臺刷新任務startBackgroundRefresh(itemId);}
}

📊 電商場景防護策略對比

場景主要風險防護策略關鍵技術
商品詳情頁緩存穿透、擊穿布隆過濾器+互斥鎖存在性判斷、分布式鎖
秒殺活動緩存雪崩、超賣原子操作+庫存預熱Lua腳本、庫存隔離
購物車數據一致性多級緩存+異步更新本地緩存、數據同步
訂單查詢熱點數據邏輯過期+限流熔斷器、限流器

💡 五、總結與最佳實踐

📋 防護策略 Checklist

??預防緩存穿透??:

  • ? 布隆過濾器校驗數據存在性
  • ? 緩存空值并設置較短過期時間
  • ? 接口層參數校驗和限流
  • ? 惡意請求識別和黑名單機制

??預防緩存擊穿??:

  • ? 互斥鎖重建緩存
  • ? 邏輯過期時間策略
  • ? 熱點數據預加載和監控
  • ? 永不過期策略+后臺刷新

??預防緩存雪崩??:

  • ? 隨機過期時間分散失效
  • ? 多級緩存架構
  • ? 熔斷降級機制
  • ? 數據庫限流保護

🏗? 架構設計建議

??多級緩存架構??:

緩存命中
緩存命中
緩存未命中
限流熔斷
惡意攔截
客戶端
本地緩存
分布式緩存
數據庫
監控系統
防護系統

??監控指標體系??:

# 關鍵監控指標
metrics:- name: cache_penetration_ratedescription: 緩存穿透率threshold: < 0.1%- name: cache_breakdown_countdescription: 緩存擊穿次數threshold: < 10次/分鐘- name: cache_avalanche_riskdescription: 緩存雪崩風險threshold: 同時失效Key < 1%- name: database_qpsdescription: 數據庫查詢QPSthreshold: < 最大承載能力的60%- name: cache_hit_ratedescription: 緩存命中率threshold: > 90%

🔧 應急響應方案

??故障處理流程??:

監控告警
確定問題類型
問題分類
緩存穿透
緩存擊穿
緩存雪崩
啟用布隆過濾器
設置空值緩存
添加互斥鎖
調整過期策略
分散過期時間
啟用熔斷降級
驗證解決效果
恢復監控
總結優化

🚀 性能優化建議

??Redis 配置優化??:

# redis.conf 優化配置
maxmemory 16gb
maxmemory-policy allkeys-lru
timeout 300
tcp-keepalive 60# 持久化配置
appendonly yes
appendfsync everysec
aof-rewrite-incremental-fsync yes# 慢查詢配置
slowlog-log-slower-than 10000
slowlog-max-len 128

??客戶端優化??:

// 連接池配置
JedisPoolConfig config = new JedisPoolConfig();
config.setMaxTotal(1000);
config.setMaxIdle(500);
config.setMinIdle(100);
config.setMaxWaitMillis(2000);
config.setTestOnBorrow(true);// Pipeline批量操作
Pipeline pipeline = jedis.pipelined();
for (int i = 0; i < 100; i++) {pipeline.get("key:" + i);
}
List<Object> results = pipeline.syncAndReturnAll();

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

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

相關文章

量子計算機的發展對傳統密碼學的打擊

量子計算機的發展對傳統密碼學的核心威脅&#xff0c;源于其能高效解決傳統計算機“計算不可行”的數學問題——而這些問題正是當前主流密碼算法保障安全的基石。這種影響并非“全面摧毀”&#xff0c;而是針對傳統密碼學的不同分支&#xff08;非對稱密碼、對稱密碼、哈希函數…

《var, let, const:現代JS聲明指南》

文章目錄JavaScript 中 var、let、const 的差異1. 作用域&#xff08;Scope&#xff09;2. 變量提升&#xff08;Hoisting&#xff09;3. 重復聲明4. 變量值是否可變對比表5. 示例代碼總結JavaScript 中 var、let、const 的差異 1. 作用域&#xff08;Scope&#xff09; var 函…

在 Docker 中安裝 MySQL 教程

拉取 MySQL 鏡像docker pull mysql:8.0創建并啟動 MySQL 容器docker run -d \--name mysql8 \-p 3306:3306 \-e MYSQL_ROOT_PASSWORD123456 \-v mysql_data:/var/lib/mysql \mysql:8.0命令說明&#xff1a;-d&#xff1a;后臺運行容器 --name mysql8&#xff1a;給容器起個名字…

C#線程理解

目錄 一.線程類 1.基礎線程類&#xff08;Thread&#xff09; 2.線程池類&#xff08;Threadpool&#xff09; 3.任務并行庫&#xff08;Task&#xff09; 4.并行循環&#xff08;Parallel&#xff09; 二.線程池(threadPool)和Thread/Task之間的聯系 1.ThreadPool和Thr…

Java入門級教程16——JUC的安全并發包機制

目錄 1.JUC的安全并發包機制 1.1 包含 1.2 Barrier(柵欄)機制——CyclicBarrier&#xff08;循環屏障&#xff09; 1.2.1 定義 1.2.2 特性 1.2.1 模擬包車 1.2.2 模擬學生到齊上課 1.2.3 計算任務總耗時 1.3 CountDownLatch(閉鎖)機制 1.3.1 定義 1.3.2 特性 1.3.3…

【網絡通信】全面解析MAC地址:網絡設備的唯一標識

【網絡通信】全面解析MAC地址&#xff1a;網絡設備的唯一標識 文章目錄【網絡通信】全面解析MAC地址&#xff1a;網絡設備的唯一標識前言一、MAC 地址的定義&#xff1a;設備的 “網絡身份證”?二、MAC 地址的格式與組成&#xff1a;48 位的 “數字編碼”?三、MAC 地址的工作…

Perforce Klocwork 2025.2版本更新:默認啟用現代分析引擎、支持 MISRA C:2025 新規、CI構建性能提升等

Perforce Klocwork 現已更新至2025.2版本&#xff01;該版本增強了對 C/C的分析能力&#xff0c;提升了現代 C 分析的準確性&#xff0c;并改進了對源文件編碼的支持。該版本還為 MISRA C:2025 標準引入了新的分類體系&#xff0c;并增強了 Visual Studio Code 插件的可用性。 …

機器人馭風而行:低空經濟如何開啟智能新紀元【科普類】

新晉碼農一枚&#xff0c;小編會定期整理一些寫的比較好的代碼和知識點&#xff0c;作為自己的學習筆記&#xff0c;試著做一下批注和補充&#xff0c;轉載或者參考他人文獻會標明出處&#xff0c;非商用&#xff0c;如有侵權會刪改&#xff01;歡迎大家斧正和討論&#xff01;…

Java學習筆記四(繼承)

1 繼承繼承的實現&#xff1a;public class 子類 extends 父類 {… }注釋&#xff1a;子類可直接使用&#xff0c;父類&#xff08;保護&#xff0c;公開&#xff09;的屬性和方法優點&#xff1a;減少重復代碼&#xff0c;缺點&#xff1a;只能單繼承// 父類 public class Tes…

NAT技術:SNAT與DNAT區別詳解

1. 什么是NAT&#xff1f; 定義&#xff1a;NAT 是一種網絡技術&#xff0c;用于在私有網絡&#xff08;如家庭或企業局域網&#xff09; 與 公共網絡&#xff08;如互聯網&#xff09; 之間轉換IP地址。它允許使用私有IP地址的設備通過一個&#xff08;或多個&#xff09;公共…

java語言中,list<String>轉成字符串,逗號分割;List<Integer>轉字符串,逗號分割

java語言中&#xff0c;list<String 轉成字符串&#xff0c;逗號分割 在 Java 中&#xff0c;將 List<String> 轉成逗號分割的字符串有多種方法&#xff1a; 使用 String.join 方法 String.join 是 Java 8 引入的一個靜態方法&#xff0c;它可以方便地將集合中的元素用…

NineData云原生智能數據管理平臺新功能發布|2025年8月版

本月發布 11 項更新&#xff0c;其中重點發布 5項、功能優化 6 項。重點發布數據庫 DevOps - SQL 窗口支持 PolarDB 系列SQL 窗口新增支持 PolarDB PostgreSQL 與 PolarDB Oracle 數據源&#xff0c;擴展云原生數據庫管理能力。新增 AWS 數據源支持新增支持 AWS Aurora Postgre…

【ARDUINO】通過ESP8266連接WIFI,啟動TCP,接受TCP客戶端指令【測試中】

通過ESP8266連接WIFI&#xff0c;啟動TCP&#xff0c;接受TCP客戶端指令**記錄**2025年9月8日11:20:372025年9月9日08:45:342025年9月11日21:40:22**代碼**記錄 2025年9月8日11:20:37 【測試情況】 代碼可以跑到正確連接WIFI&#xff0c;也能獲得IP&#xff0c;但是啟動TCP服…

(網絡原理)核心知識回顧 網絡核心原理 get和post的理解 解析http 加密+請求和響應的一些關鍵字 Cookie和session 對密鑰的理解

目錄 核心知識回顧 網絡核心原理 get和post的理解 解析http 加密請求和響應的一些關鍵字 Cookie和session 對密鑰的理解 核心知識回顧 網絡編程---socket api UDP DatagramSocket DatagramPacket TCP ServerSocket Socket 1.讀寫數據通過Socket,通過Socket內置的 lnpu…

前端框架對比分析:離線PWA + Cloudflare Workers部署

目錄 概述 框架對比表格 詳細分析 1. Astro ????? **強烈推薦** 2. Next.js ???? **推薦** 3. Remix (現React Router) ????? **強烈推薦** 4. SvelteKit ???? **推薦** 5. Nuxt.js ??? **一般推薦** 6. Vite + React ??? **基礎選擇** 推薦方案 ?? …

9-10關于JS初學產生的問題

1.頁面添加加載完成事件監聽&#xff0c;頁面加載完成后&#xff0c;執行頁面初始化方法/函數; 這是什么意思 這句話描述的是前端開發中一種常見的操作&#xff1a;等待頁面完全加載完成后&#xff0c;再執行特定的初始化代碼。 簡單來說&#xff0c;就是要確保頁面上的所有元素…

項目中遇到pom文件里使用systemPath的例子記錄

項目中遇到pom文件里使用systemPath&#xff0c;很少見&#xff0c;問了下豆包&#xff0c;記錄下結果。在 Maven 的 pom.xml 中&#xff0c;<systemPath> 是 <dependency> 標簽內的一個可選配置&#xff0c;用于手動指定本地系統中某個依賴包&#xff08;通常是 J…

10、向量與矩陣基礎 - 深度學習的數學語言

學習目標:建立向量和矩陣的幾何直觀理解,掌握線性代數的核心概念,培養空間思維能力,為手搓大模型奠定扎實的數學基礎 想象一下,當你使用GPT進行對話時,每個詞匯都被轉換成高維向量,整個對話歷史變成一個巨大的矩陣。模型的"理解"過程,本質上就是在這個高維空…

【Python Tkinter】圖形用戶界面(GUI)開發及打包EXE指南

【Python Tkinter】圖形用戶界面&#xff08;GUI&#xff09;開發及打包EXE指南一、關于 Python Tkinter二、密碼生成器示例2.1 使用Python添加圖形用戶界面&#xff08;GUI&#xff09;2.2 使用工具PyInstaller將應用打包成exe文件三、總結一、關于 Python Tkinter Python Tk…

【設計模式】【觀察者模式】實例

一對多的統一監聽 —— 這就是 觀察者模式&#xff08;Observer Pattern&#xff09; 的經典應用場景。也就是說&#xff1a;一個事件源&#xff08;Subject&#xff09; → 可以注冊多個監聽器&#xff08;Observers&#xff09;&#xff1b;當事件發生時&#xff0c;一次性通…