不折騰的前端,和鹹魚有什麼區別前端
目錄 |
---|
一 目錄 |
二 前言 |
三 正文 |
四 刷題 |
返回目錄
返回目錄
經過從輸出 URL 到頁面呈現咱們能夠知道,瀏覽器若是每次都要請求加載頁面,會至關費時間。git
而若是咱們將某些網頁存儲到瀏覽器緩存中,這樣當咱們打開一個網頁的時候,就會去查詢瀏覽器緩存,看是否有請求的文件。github
若是有,那就攔截請求,返回緩存文件,並結束請求,而不會去服務器下載。算法
使用過 360 等殺毒軟件的人都知道,它會時不時提醒你瀏覽器有多少緩存能夠清理了……數組
由於瀏覽器中的緩存是一種本地保存資源副本,它的大小是有限的,當咱們請求次數過多的時候,緩存空間就會被塞滿。瀏覽器
這個時候,就須要判斷哪些緩存數據須要被保留,哪些數據須要被清理。緩存
所以,瀏覽器緩存也有屬於本身的策略:瀏覽器緩存淘汰策略。服務器
最多見的淘汰策略有 FIFO(先進先出)、LFU(最少使用)、LRU(最近最少使用)。網絡
LRU(Least recently used),即最近最少使用算法,該算法根據數據的歷史訪問記錄來進行淘汰數據,其核心思想是 「若是數據最近被訪問過,那麼未來被訪問的概率也更高」。數據結構
簡單來講:瀏覽器緩存空間很小,只能緩存 10 個網頁,那麼只會保存最近訪問的 10 個網頁。
通用實現原理:
返回目錄
話很少說,咱們刷下題就懂了:
運用你所掌握的數據結構,設計和實現一個 LRU (最近最少使用) 緩存機制。 它應該支持如下操做: 獲取數據 get 和 寫入數據 put 。 獲取數據 get(key): 若是關鍵字 (key) 存在於緩存中, 則獲取關鍵字的值(老是正數),不然返回 -1。 寫入數據 put(key, value): 若是關鍵字已經存在,則變動其數據值; 若是關鍵字不存在,則插入該組「關鍵字/值」。 當緩存容量達到上限時, 它應該在寫入新數據以前刪除最久未使用的數據值, 從而爲新的數據值留出空間。 進階:你是否能夠在 O(1) 時間複雜度內完成這兩種操做? 示例: LRUCache cache = new LRUCache( 2 /* 緩存容量 */ ); cache.put(1, 1); cache.put(2, 2); cache.get(1); // 返回 1 cache.put(3, 3); // 該操做會使得關鍵字 2 做廢 cache.get(2); // 返回 -1 (未找到) cache.put(4, 4); // 該操做會使得關鍵字 1 做廢 cache.get(1); // 返回 -1 (未找到) cache.get(3); // 返回 3 cache.get(4); // 返回 4 來源:力扣(LeetCode) 連接:https://leetcode-cn.com/problems/lru-cache 著做權歸領釦網絡全部。商業轉載請聯繫官方受權,非商業轉載請註明出處。
給定方法體:
/** * @param {number} capacity */ var LRUCache = function(capacity) { }; /** * @param {number} key * @return {number} */ LRUCache.prototype.get = function(key) { }; /** * @param {number} key * @param {number} value * @return {void} */ LRUCache.prototype.put = function(key, value) { }; /** * Your LRUCache object will be instantiated and called as such: * var obj = new LRUCache(capacity) * var param_1 = obj.get(key) * obj.put(key,value) */
答案(詳細看註釋,更多不解釋):
/** * @name LRU算法 * @param {number} capacity 緩存容量 */ const LRUCache = function(capacity) { // 設置哈希映射 this.hash = {}; // 設置 key 值列表 this.keys = []; // 設置 length 長度 this.capacity = capacity; // 讀取數據:key - 關鍵字(輸出 value 值,沒有返回 -1) this.get = (key) => { // 查找當前 hash 是否有對應的映射 if (this.hash[key]) { // 將這個鍵刪除並添加到數組頭部 this.keys.splice(this.keys.indexOf(key), 1); this.keys.unshift(key); // 若是有返回對應值 return this.hash[key]; } else { // 若是沒有返回 -1 return -1; } }; // 寫入數據:key - 關鍵字;value - 值(不須要輸出) this.put = (key, value) => { // 查找這個 key 是否存在於當前列表 const index = this.keys.indexOf(key); // 若是存在,那就刪除 if (index > -1) { const outKey = this.keys.splice(index, 1); delete this.hash[outKey]; } else if (index !== -1 || this.keys.length >= this.capacity) { // 若是不存在且當前數組長度超限,則推出最末尾的 const outKey = this.keys.pop(); delete this.hash[outKey]; } // 最後插入鍵值對 this.hash[key] = value; this.keys.unshift(key); }; }; const cache = new LRUCache(2); cache.put(1, 1); cache.put(2, 2); console.log(cache.get(1)); // 返回 1 cache.put(3, 3); // 該操做會使得關鍵字 2 做廢 console.log(cache.get(2)); // 返回 -1 (未找到) cache.put(4, 4); // 該操做會使得關鍵字 1 做廢 console.log(cache.get(1)); // 返回 -1 (未找到) console.log(cache.get(3)); // 返回 3 console.log(cache.get(4)); // 返回 4
jsliang 的文檔庫由 梁峻榮 採用 知識共享 署名-非商業性使用-相同方式共享 4.0 國際 許可協議 進行許可。<br/>基於 https://github.com/LiangJunrong/document-library 上的做品創做。<br/>本許可協議受權以外的使用權限能夠從 https://creativecommons.org/licenses/by-nc-sa/2.5/cn/ 處得到。