成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

一文帶你了解什么是 LRU 算法?

開發 前端
LRU (Least recently used:最近最少使用)算法在緩存寫滿的時候,會根據所有數據的訪問記錄,淘汰掉未來被訪問幾率最低的數據。也就是說該算法認為,最近被訪問過的數據,在將來被訪問的幾率最大。

緩存 是我們寫代碼過程中常用的一種手段,是一種空間換時間的做法。就拿我們經常使用的 HTTP 協議,其中也存在強緩存和協商緩存兩種緩存方式。當我們打開一個網站的時候,瀏覽器會查詢該請求的響應頭,通過判斷響應頭中是否有 Cache-Control、Last-Modified、ETag 等字段,來確定是否直接使用之前下載的資源緩存,而不是重新從服務器進行下載。

下面就是當我們訪問百度時,某些資源命中了協商緩存,服務端返回 304 狀態碼,還有一部分資源命中了強緩存,直接讀取了本地緩存。

但是,緩存并不是無限制的,會有大小的限制。無論是我們的 cookie(不同瀏覽器有所區別,一般在 4KB 左右),還是 localStorage(和 cookie 一樣,不同瀏覽器有所區別,有些瀏覽器為 5MB,有些瀏覽器為 10MB),都會有大小限制。

這個時候就需要涉及到一種算法,需要將超出大小限制的緩存進行淘汰,一般的規則是淘汰掉最近沒有被訪問到的緩存,也就是今天要介紹的主角:LRU (Least recently used:最近最少使用)。當然除了 LRU,常見的緩存淘汰還有 FIFO(first-in, first-out:先進先出) 和 LFU(Least frequently used:最少使用)。

什么是 LRU?

LRU (Least recently used:最近最少使用)算法在緩存寫滿的時候,會根據所有數據的訪問記錄,淘汰掉未來被訪問幾率最低的數據。也就是說該算法認為,最近被訪問過的數據,在將來被訪問的幾率最大。

為了方便理解 LRU 算法的全流程,畫了一個簡單的圖:

  1. 假設我們有一塊內存,一共能夠存儲 5 數據塊。
  2. 依次向內存存入A、B、C、D、E,此時內存已經存滿。
  3. 再次插入新的數據時,會將在內存存放時間最久的數據A淘汰掉。
  4. 當我們在外部再次讀取數據B時,已經處于末尾的B會被標記為活躍狀態,提到頭部,數據C就變成了存放時間最久的數據。
  5. 再次插入新的數據G,存放時間最久的數據C就會被淘汰掉。

算法實現

下面通過一段簡單的代碼來實現這個邏輯。

class LRUCache {
list = [] // 用于標記先后順序
cache = {} // 用于緩存所有數據
capacity = 0 // 緩存的最大容量
constructor (capacity) {
// 存儲 LRU 可緩存的最大容量
this.capacity = capacity
}
}

基本的結構如上所示,LRU需要實現的就是兩個方法:get 和 put。

class LRUCache {
// 獲取數據
get (key) { }
// 存儲數據
put (key, value) { }
}

我們現在看看如何進行數據的存儲:

class LRUCache {
// 存儲數據
put (key, value) {
// 存儲之前需要先判斷長度是否達到上限
if (this.list.length >= this.capacity) {
// 由于每次存儲后,都會將 key 放入 list 最后,
// 所以,需要取出第一個 key,并刪除cache中的數據。
const latest = this.list.shift()
delete this.cache[latest]
}
// 寫入緩存
this.cache[key] = value
// 寫入緩存后,需要將 key 放入 list 的最后
this.list.push(key)
}
}

然后,在每次獲取數據時,都需要更新 list,將當前獲取的 key 放到 list 的最后。

class LRUCache {
// 獲取數據
get (key) {
if (this.cache[key] !== undefined) {
// 如果 key 對應的緩存存在
// 在返回緩存之前,需要重新激活 key
this.active(key)
return this.cache[key]
}
return undefined
}
// 重新激活key,將指定 key 移動到 list 最后
active (key) {
// 先將 keylist 中刪除
const idx = this.list.indexOf(key)
if (idx !== -1) {
this.list.splice(idx, 1)
}
// 然后將 key 放到 list 最后面
this.list.push(key)
}
}

這個時候,其實還沒有完全實現,因為除了 get 操作,put 操作也需要將對應的 key 重新激活。

class LRUCache {
// 存儲數據
put (key, value) {
if (this.cache[key]) {
// 如果該 key 之前存在,將 key 重新激活
this.active(key)
this.cache[key] = value
// 而且此時緩存的長度不會發生變化
// 所以不需要進行后續的長度判斷,可以直接返回
return
}

// 存儲之前需要先判斷長度是否達到上限
if (this.list.length >= this.capacity) {
// 由于每次存儲后,都會將 key 放入 list 最后,
// 所以,需要取出第一個 key,并刪除cache中的數據。
const latest = this.list.shift()
delete this.cache[latest]
}
// 寫入緩存
this.cache[key] = value
// 寫入緩存后,需要將 key 放入 list 的最后
this.list.push(key)
}
}

可能會有人覺得這種算法在前端沒有什么應用場景,說起來,在 Vue 的內置組件 keep-alive 中就使用到了 LRU 算法。

后續應該還會繼續介紹一下 LFU 算法,敬請期待。

責任編輯:姜華 來源: 自然醒的筆記本
相關推薦

2022-09-29 13:09:38

DataClassPython代碼

2025-01-15 09:06:57

servlet服務器Java

2022-09-06 11:21:49

光網絡光纖

2019-07-04 15:16:52

數據挖掘大數據算法

2023-05-17 11:33:45

梯度下降機器學習

2019-04-19 14:03:52

APISDK接口

2023-04-11 08:01:32

Web 開發源代碼映射

2023-11-20 08:18:49

Netty服務器

2023-11-06 08:16:19

APM系統運維

2022-11-11 19:09:13

架構

2018-10-22 08:14:04

2019-11-14 09:16:56

物聯網技術路由器

2024-05-27 00:00:00

.NET游戲引擎C#

2023-10-27 08:15:45

2023-11-08 08:15:48

服務監控Zipkin

2022-02-24 07:34:10

SSL協議加密

2020-02-02 15:14:24

HTTP黑科技前端

2022-04-28 09:22:46

Vue灰度發布代碼

2020-10-08 14:32:57

大數據工具技術

2022-03-23 08:31:25

LRU 算法JavaScripLFU 緩存算法
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 精品久久一区二区三区 | 天天色影视综合 | 日日网| 电影午夜精品一区二区三区 | 69性欧美高清影院 | 亚洲精品4 | 久久久久久久av麻豆果冻 | 狠狠躁天天躁夜夜躁婷婷老牛影视 | 日韩一区二区在线视频 | 亚洲综合国产精品 | 国产一区二区精 | 精品久久久久久久久久久久久 | 欧美激情久久久 | 成年人在线视频 | 国产偷录视频叫床高潮对白 | 欧美一级欧美三级在线观看 | 在线播放国产一区二区三区 | 欧美一区二区视频 | 欧美网站一区 | 天天射影院 | 三级黄视频在线观看 | 在线精品国产 | 九九色九九 | 中文字字幕在线中文乱码范文 | 国产成人精品视频在线观看 | 成人精品鲁一区一区二区 | 婷婷色国产偷v国产偷v小说 | 久久久夜| 一区二区三区日本 | 一区二区三区欧美 | 国产精品.xx视频.xxtv | 久久久久久亚洲精品 | 夜夜草av| 中文字幕在线视频一区二区三区 | h肉视频 | 高清成人av | 亚洲国产精品一区二区第一页 | 一级做a爰片久久毛片 | 网站黄色在线免费观看 | 日韩不卡一区二区三区 | xx性欧美肥妇精品久久久久久 |