fifo算法_緩存算法FIFO、LFU、LRU

閱讀文本大概需要3分鐘。

0x01:FIFO算法

  FIFO(First in First out),先進先出。其實在操作系統的設計理念中很多地方都利用到了先進先出的思想,比如作業調度(先來先服務),為什么這個原則在很多地方都會用到呢?因為這個原則簡單、且符合人們的慣性思維,具備公平性,并且實現起來簡單,直接使用數據結構中的隊列即可實現。

  在FIFO Cache設計中,核心原則就是:如果一個數據最先進入緩存中,則應該最早淘汰掉。也就是說,當緩存滿的時候,應當把最先進入緩存的數據給淘汰掉。在FIFO Cache中應該支持以下操作;

  get(key):如果Cache中存在該key,則返回對應的value值,否則,返回-1;

  set(key,value):如果Cache中存在該key,則重置value值;如果不存在該key,則將該key插入到到Cache中,若Cache已滿,則淘汰最早進入Cache的數據。

  舉個例子:假如Cache大小為3,訪問數據序列為set(1,1),set(2,2),set(3,3),set(4,4),get(2),set(5,5)

  則Cache中的數據變化為:

  (1,1)?????????????????????????????? set(1,1)

  (1,1) (2,2)?????????????????????? set(2,2)

  (1,1) (2,2) (3,3)?????????????? set(3,3)

  (2,2) (3,3) (4,4)?????????????? set(4,4)

  (2,2) (3,3) (4,4)?????????????? get(2)

  (3,3) (4,4) (5,5)?????????????? set(5,5)

?  那么利用什么數據結構來實現呢?

  下面提供一種實現思路:

  利用一個雙向鏈表保存數據,當來了新的數據之后便添加到鏈表末尾,如果Cache存滿數據,則把鏈表頭部數據刪除,然后把新的數據添加到鏈表末尾。在訪問數據的時候,如果在Cache中存在該數據的話,則返回對應的value值;否則返回-1。如果想提高訪問效率,可以利用hashmap來保存每個key在鏈表中對應的位置。

0x02:LFU算法

  LFU(Least Frequently Used)最近最少使用算法。它是基于“如果一個數據在最近一段時間內使用次數很少,那么在將來一段時間內被使用的可能性也很小”的思路。

  注意LFU和LRU算法的不同之處,LRU的淘汰規則是基于訪問時間,而LFU是基于訪問次數的。舉個簡單的例子:

  假設緩存大小為3,數據訪問序列為set(2,2),set(1,1),get(2),get(1),get(2),set(3,3),set(4,4),

  則在set(4,4)時對于LFU算法應該淘汰(3,3),而LRU應該淘汰(1,1)。

  那么LFU Cache應該支持的操作為:

  get(key):如果Cache中存在該key,則返回對應的value值,否則,返回-1;

  set(key,value):如果Cache中存在該key,則重置value值;如果不存在該key,則將該key插入到到Cache中,若Cache已滿,則淘汰最少訪問的數據。

  為了能夠淘汰最少使用的數據,因此LFU算法最簡單的一種設計思路就是 利用一個數組存儲 數據項,用hashmap存儲每個數據項在數組中對應的位置,然后為每個數據項設計一個訪問頻次,當數據項被命中時,訪問頻次自增,在淘汰的時候淘汰訪問頻次最少的數據。這樣一來的話,在插入數據和訪問數據的時候都能達到O(1)的時間復雜度,在淘汰數據的時候,通過選擇算法得到應該淘汰的數據項在數組中的索引,并將該索引位置的內容替換為新來的數據內容即可,這樣的話,淘汰數據的操作時間復雜度為O(n)。

  另外還有一種實現思路就是利用 小頂堆+hashmap,小頂堆插入、刪除操作都能達到O(logn)時間復雜度,因此效率相比第一種實現方法更加高效。

  如果哪位朋友有更高效的實現方式(比如O(1)時間復雜度),不妨探討一下,不勝感激。

0x03:LRU算法

LRU算法的設計原則是:如果一個數據在最近一段時間沒有被訪問到,那么在將來它被訪問的可能性也很小。也就是說,當限定的空間已存滿數據時,應當把最久沒有被訪問到的數據淘汰。

而用什么數據結構來實現LRU算法呢?可能大多數人都會想到:用一個數組來存儲數據,給每一個數據項標記一個訪問時間戳,每次插入新數據項的時候,先把數組中存在的數據項的時間戳自增,并將新數據項的時間戳置為0并插入到數組中。每次訪問數組中的數據項的時候,將被訪問的數據項的時間戳置為0。當數組空間已滿時,將時間戳最大的數據項淘汰。

  這種實現思路很簡單,但是有什么缺陷呢?需要不停地維護數據項的訪問時間戳,另外,在插入數據、刪除數據以及訪問數據時,時間復雜度都是O(n)。

  那么有沒有更好的實現辦法呢?

  那就是利用鏈表和hashmap。當需要插入新的數據項的時候,如果新數據項在鏈表中存在(一般稱為命中),則把該節點移到鏈表頭部,如果不存在,則新建一個節點,放到鏈表頭部,若緩存滿了,則把鏈表最后一個節點刪除即可。在訪問數據的時候,如果數據項在鏈表中存在,則把該節點移到鏈表頭部,否則返回-1。這樣一來在鏈表尾部的節點就是最近最久未訪問的數據項。

  總結一下:根據題目的要求,LRU Cache具備的操作:

  1)set(key,value):如果key在hashmap中存在,則先重置對應的value值,然后獲取對應的節點cur,將cur節點從鏈表刪除,并移動到鏈表的頭部;若果key在hashmap不存在,則新建一個節點,并將節點放到鏈表的頭部。當Cache存滿的時候,將鏈表最后一個節點刪除即可。

  2)get(key):如果key在hashmap中存在,則把對應的節點放到鏈表頭部,并返回對應的value值;如果不存在,則返回-1。

推薦閱讀

Spring Boot 最流行的 16 條實踐

SSM框架的面試常見問題

【分布式】緩存穿透、緩存雪崩,緩存擊穿解決方案

阿里P7給出的一份超詳細 Spring Boot 知識清單

關注我每天進步一點點

aae1da1f8d0ff15c82f42f4c6058b864.png

5636d2ed77c3648864af360f63948b5a.png

你點的每個在看,我都認真當成了喜歡

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

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

相關文章

Pile 0009: Vim命令梳理

正常模式(按Esc或Ctrl[進入) 左下角顯示文件名或為空插入模式(按i鍵進入) 左下角顯示--INSERT--可視模式(按v鍵進入) 左下角顯示--VISUAL-- i 在當前位置生前插入 I 在當前行首插入 a 在當前位置后插入 A 在…

Introduction of Version Control/Git, SVN

Introduction of Version Control/Git, SVN 什么是版本控制? 你可以把一個版本控制系統(縮寫VCS)理解為一個“數據庫”,在需要的時候,它可以幫你完整地保存一個項目的快照。當你需要查看一個之前的快照(稱之…

怎樣設置計算機遠程桌面,電腦如何設置遠程連接,手把手教你如何遠程

說起遠程桌面很多用戶都認為是從WIN2000 SERVER才開始引入的,實際上我們可以在WIN98甚至是DOS中看到他的身影。遠程桌面采用的是一種類似TELNET的技術,他是從TELNET協議發展而來的。那么如何設置自動開機,下面,我們就來看看如何設…

查看這些有用的ECMAScript 2015(ES6)提示和技巧

by rajaraodv通過rajaraodv 查看這些有用的ECMAScript 2015(ES6)提示和技巧 (Check out these useful ECMAScript 2015 (ES6) tips and tricks) EcmaScript 2015 (aka ES6) has been around for couple of years now, and various new features can be used in clever ways. I…

inputstream轉fileinputstream對象_FileInputStream類:文件字節輸入流

API ----IO ----字節輸入輸出流練習 java.lang.Object 繼承者 java.io.InputStream 繼承者 java.io.FileInputStreampublic FileInputStream類速查速記:直接包裝File用于從記事本中讀數據 in是針對java來說的,從記事本讀入到java* 構造方法:…

IBM將推NVMe存儲解決方案

先前,IBM曾對外宣稱將開發新的NVMe解決方案,并推動行業參與者進一步探索新協議,以支持更快的數據傳輸。周日,IBM表示新的語言協議——NVMe(非易失性存儲器)正在逐步取代SAS和SATA等舊有的固態硬盤存儲標準。…

html5中3個盒子怎樣設置,Web前端開發任務驅動式教程(HTML5+CSS3+JavaScript)任務10 盒子模型及應用.pptx...

第五單元 盒子模型任務10 盒子模型及應用學習目標盒子模型的概念掌握邊框的設置內邊距的設置外邊距的設置學習目標了解:利用盒子模型布局網頁的優勢任務目標實戰演練——制作古詩文欣賞網頁強化訓練——制作散文賞析網頁知識準備1. 盒子模型的概念知識準備1. 盒子模型的概念CSS…

SQL手工注入入門級筆記(更新中)

一、字符型注入 針對如下php代碼進行注入: $sql"select user_name from users where name$_GET[name]"; 正常訪問URL:http://url/xxx.php?nameadmin 此時實際數據庫語句: select user_name from users where nameadmin 利用以上結果可想到SQL注入構造語句…

materialize_使用Materialize快速介紹材料設計

materialize什么是材料設計? (What is Material Design?) Material Design is a design language created by Google. According to material.io, Material Design aims to combine:Material Design是Google創建的一種設計語言。 根據material.io ,Mate…

python處理完數據導入數據庫_python 將execl測試數據導入數據庫操作

import xlrd import pymysql # 打開execl表 book xlrd.open_workbook(XXXX測試用例.xlsx) sheet book.sheet_by_name(Sheet1) # print(sheet.nrows) # 創建mysql連接 conn pymysql.connect( host127.0.0.1, userroot, password123456, dbdemo1, port3306, charsetutf8 ) # 獲…

增刪改查類

<?php // 所有數據表的基類 abstract class Model {protected $tableName "";protected $pdo "";protected $sql"";function __construct() {$pdo new PDO( "mysql:host" . DB_HOST . ";dbname" . DB_NAME, DB_USERN…

html網頁和cgi程序編程,CGI 編程方式學習

1.大家都知道CGI是通用網關接口&#xff0c;可以用來編寫動態網頁。而且CGI可以用很多種語言來寫&#xff0c;用perl來編寫最常見&#xff0c;我這里就是用perl來編寫做例子。講到編寫CGI編程方式&#xff0c;編寫CGI有兩程編程風格。(1)功能型編程(function-oriented style)這…

20175305張天鈺 《java程序設計》第四周課下測試總結

第四周課下測試總結 錯題 某方法在父類的訪問權限是public&#xff0c;則子類重寫時級別可以是protected。 A .true B .false 正確答案&#xff1a;B 解析&#xff1a;書P122&#xff1a;子類不允許降低方法的訪問權限&#xff0c;但可以提高訪問權限。 復雜題&#xff08;易錯…

強化學習q學習求最值_通過Q學習更深入地學習強化學習

強化學習q學習求最值by Thomas Simonini通過托馬斯西蒙尼(Thomas Simonini) 通過Q學習更深入地學習強化學習 (Diving deeper into Reinforcement Learning with Q-Learning) This article is part of Deep Reinforcement Learning Course with Tensorflow ??. Check the syl…

BZOJ 1113: [Poi2008]海報PLA

1113: [Poi2008]海報PLA Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1025 Solved: 679[Submit][Status][Discuss]Description N個矩形,排成一排. 現在希望用盡量少的矩形海報Cover住它們. Input 第一行給出數字N,代表有N個矩形.N在[1,250000] 下面N行,每行給出矩形的長…

Python自動化運維之常用模塊—OS

os模塊的作用&#xff1a;  os&#xff0c;語義為操作系統&#xff0c;所以肯定就是操作系統相關的功能了&#xff0c;可以處理文件和目錄這些我們日常手動需要做的操作&#xff0c;就比如說&#xff1a;顯示當前目錄下所有文件/刪除某個文件/獲取文件大小……  另外&#…

opengl三維圖形圖形顏色_【圖形學基礎】基本概念

右手坐標系。類似OpenGL遵循的右手坐標系&#xff1a;首先它是三維的笛卡爾坐標系&#xff1a;原點在屏幕正中&#xff0c;x軸從屏幕左向右&#xff0c;最左是-1&#xff0c;最右是1&#xff1b;y軸從屏幕下向上&#xff0c;最下是-1&#xff0c;最上是1&#xff1b;z軸從屏幕里…

xp職稱計算機考試題庫,2015年職稱計算機考試XP題庫.doc

2015年職稱計算機考試XP題庫.doc (7頁)本資源提供全文預覽&#xff0c;點擊全文預覽即可全文預覽,如果喜歡文檔就下載吧&#xff0c;查找使用更方便哦&#xff01;9.90 積分&#xfeff;2015年職稱計算機考試XP題庫職稱計算機考試考點精編&#xff1a;工具欄的設置與操作XP中將…

Java基礎學習-Path環境變量的配置

1.為什么要進行Path環境變量的配置程序的編譯和執行需要使用到javac和java命令&#xff0c;所以只能在bin目錄下寫程序&#xff0c;而實際開發中&#xff0c;我們不可能將程序全部寫到bin目錄下&#xff0c;所以我們不許讓javac和java命令在任意目錄下都能夠被訪問。這時候&…

rails 共享變量_如何將Rails實例變量傳遞給Vue組件

rails 共享變量by Gareth Fuller由Gareth Fuller 如何將Rails實例變量傳遞給Vue組件 (How to pass Rails instance variables into Vue components) I’m currently working with a legacy Rails application. We are slowly transitioning the front-end from Rails views to…