快速了解

搬运原地址 interviewcake

最近最少使用(LRU)高速缓存,使您能够快速确定哪些数据尚未使用的时间最长。想象一下晾衣架,衣服总是一侧悬挂。要查找最近最少使用的衣服,看晾衣架的另一侧便可。在底层,LRU缓存通常是通过将双链表与哈希映射表配对来实现的。

类型 复杂度
空间 O(n)
获取最近最少访问条目 O(1)
读取条目 O(1)

优点:

超快速访问:LRU高速缓存按最近使用到最少使用的顺序存储项目。这意味着两者都可以在时间O(1)获取。
超快速更新:每次访问项目,更新缓存时,需要O(1)时间。

缺点

空间笨重。LRU缓存跟踪n条目需要长度为n的链表,以及持有n条目的哈希图。需要两个O(n)空间的数据结构(而不是一个).

为什么要使用缓存?

假设您要管理一个有很多蛋糕食谱的烹饪场所。与任何网站一样,您希望尽快提供页面。

当用户请求配方时,您可以打开磁盘上的相应文件,读取HTML,然后通过网络发送。这可以工作,但是速度很慢,因为访问磁盘需要一段时间。

理想情况下,如果许多用户要求相同的配方,则只希望从磁盘读取一次,并将页面保留在内存中,以便您可以在需要时快速将其再次发送出去。很好,您刚刚添加了一个缓存。

缓存只是快速存储。从缓存中读取数据所需的时间少于从其他途径(例如硬盘)中读取数据的时间。

但是可用缓存空间很小。您无法将所有内容都放入缓存中,时常仍然需要更大,速度更慢的存储。

如果无法将所有内容都放入缓存中,那么如何确定缓存应存储的内容呢?

LRU驱逐

这是一个主意:如果缓存能存储n个条目的空间,n元素最近访问过。

为了具体起见,假设我们在磁盘上有以下四个配方:

描述数据的图标以不同的蛋糕配方表示:巧克力蛋糕,香草蛋糕,草莓酥饼,磅蛋糕。 假设我们的缓存最多只能存储三个配方(虽然有点小,但它会使该示例更容易理解)。

让我们逐步了解一下缓存的庐山真面目。

首先,用户请求巧克力蛋糕食谱。我们将从磁盘读取它,并将其保存到缓存中,然后再将其返回给用户。

接下来,有人请求香草蛋糕食谱:

请注意,巧克力蛋糕配方在缓存中的级别降低了,它不再是最近使用过的了。

接下来是草莓蛋糕食谱的要求:

还有一个用于巧克力:

我们已经将这三个食谱保存在缓存中了,因此我们可以跳过磁盘读取。我们还将其恢复到最近使用的位置,使其他所在位置下降。

接下来是磅蛋糕食谱的要求:

由于我们的缓存只能容纳三个食谱,因此我们不得不踢出一个来腾出空间。我们踢出了香草蛋糕食谱,因为它在缓存中的所有食谱中使用最少。这称为最近最少使用(LRU)驱逐策略。

我们可以使用很多策略来选择要摆脱的配方。我们将重点放在LRU上,因为LRU是编码面试中常见的一种。

一个LRU缓存是可以用来找出我们应该驱逐时,缓存满了一个高效的缓存数据结构。目标是始终将最近使用最少的项目放在O(1)时间。

LRU缓存实施

LRU缓存是通过组合两个数据结构来构建的: 双链表和哈希图。

我们将建立链接列表,在列表的顶部使用最近的项目,在列表的末尾使用最近的项目:

这使我们可以O(1)便可访问到列表的末尾。

如何访问缓存中的特定项目(例如,巧克力蛋糕)?

通常,在链表中查找项目是O(n)时间,因为我们需要遍历整个列表。但是缓存的重点是快速查找。我们如何加快速度?

我们将添加一个哈希映射,将映射到链表节点:

这样我们就可以在缓存的链表中找到一个元素是O(1)时间,而不是O(n)。

访问和逐出

这是每次访问项目时我们都要执行的步骤:

•在我们的哈希映射查找该条目。

•如果该项目在哈希表中,那么它已经在我们的缓存中了-这称为“缓存命中”

1.使用哈希表可以快速找到相应的链表节点。2.将项目的链表节点移到链表的头部,因为它是最近使用过的(因此不应该很快被驱逐)。

•如果该项目不在哈希表中,则我们有一个“缓存空缺”。我们需要将该条目加载到缓存中:

1.我们的缓存是否已满?如果是这样,我们需要腾出一些空间:找到最近最少使用的缓存项,它将位于链接列表的末尾。通过从链接列表和哈希图中删除该项目,可以从缓存中逐出该项目。2.为该项目创建一个新的链接列表节点。将其插入到链接列表的开头。3.将项目添加到我们的哈希图中,将新创建的链表节点存储为值。

在链表节点周围移动时,保持所有指针笔直是很棘手的!尝试自己实施!看看您是否能明白为什么我们的链表是双向链接很重要。

所有这些步骤都是O(1),所以放在一起需要O(1)每次访问元素时更新缓存的时间。太酷了!

本文由博客群发一文多发等运营工具平台 OpenWrite 发布

LRU Cache 缓存相关推荐

  1. 单机 “5千万以上“ 工业级 LRU cache 实现

    文章目录 前言 工业级 LRU Cache 1. 基本架构 2. 基本操作 2.1 insert 操作 2.2 高并发下 insert 的一致性/性能 保证 2.3 Lookup操作 2.4 shar ...

  2. 代码写对了还挂了?程序媛小姐姐从 LRU Cache 带你看面试的本质

    来源 | 码农田小齐 责编 |  Carol 前言 在讲这道题之前,我想先聊聊「技术面试究竟是在考什么」这个问题. 技术面试究竟在考什么 在人人都知道刷题的今天,面试官也都知道大家会刷题准备面试,代码 ...

  3. 从 LRU Cache 带你看面试的本质

    前言 在讲这道题之前,我想先聊聊「技术面试究竟是在考什么」这个问题. 技术面试究竟在考什么 在人人都知道刷题的今天,面试官也都知道大家会刷题准备面试,代码大家都会写,那面试为什么还在考这些题?那为什么 ...

  4. 【hard】146. LRU Cache

    其实也米有很难--只是c++11的api这么好用的吗 Design and implement a data structure for Least Recently Used (LRU) cache ...

  5. 如何设计LRU Cache算法

    前言 相信有的伙伴在面试的过程中,或多或少的会被问到redis的内存淘汰策略,可能大部分人都知道都有哪些对应的策略,毕竟对于八股文的套路大家肯定早已铭记于心.但是当面试官问你如何实现或者让你去写一个对 ...

  6. 【LeetCode】LRU Cache 解决报告

    插话:只写了几个连续的博客,博客排名不再是实际"远在千里之外"该.我们已经进入2一万内. 再接再厉.油! Design and implement a data structure ...

  7. 内存淘汰机制 LRU cache

    LRU cache机制的目的是为了减少频繁查找的开销,包括磁盘IO等. (1).如果LRU中存在则从LRU缓存中查找,查找到了之后放到容器(list)的最前面 (2).如果缓存中没有,则从其地方(数据 ...

  8. 一种简单的LRU cache设计 C++

    最近在工作中需要用到LRU cache用作缓存来提高性能,经过查阅各种资料,了解了其运行的机制,如下: LRU cache可以用于在内存中保持当前的热点数据,下面实现一个有大小限制的lru cache ...

  9. 【重点】LeetCode 146. LRU Cache

    LeetCode 146. LRU Cache 1.Solution1 本博客转载自:http://www.cnblogs.com/grandyang/p/4587511.html 这道题让我们实现一 ...

最新文章

  1. 【C#】Out与ref是干什么的?
  2. 【Python基础】手把手教你数据可视化!(附实例讲解)
  3. 大脑使用交叉存储,来区分现在和过去
  4. 分布式环境下的并发问题
  5. 【自动驾驶】27.相机畸变_相机内参标定 整理
  6. Python爬虫入门(8):Beautiful Soup的用法
  7. vb6 判断打印机是否有效_智能收银机的热敏打印机打不出字怎么办?
  8. Chapter4:Using Standard Control(学习)
  9. Qt消息机制和事件概述(一)
  10. 为什么软件工程师找不到工作?我想分享四个“恐怖故事”
  11. P2048 [NOI2010] 超级钢琴(RMQ 贪心)
  12. [剑指offer][JAVA]面试题第[30]题[包含min函数的栈][双栈辅助栈][单栈]
  13. 2017.8.11 亚瑟王 失败总结
  14. 卢伟冰:小米Civi女性购买用户占比超60%
  15. 【BZOJ 1038】 1038: [ZJOI2008]瞭望塔
  16. Windows10上安装Keras 和 TensorFlow-GPU
  17. media query学习笔记
  18. centos系统上安装masscan
  19. 好家伙!MIT博士生凭借「扭动奥利奥饼干」发了篇论文!
  20. 一招解决网页文字无法复制

热门文章

  1. 基于JSP的网上在线租车系统平台设计与实现
  2. C++:内存管理:C++内存管理详解
  3. Centos逻辑卷扩容、合并
  4. colt mrr_Learning To Rank 介绍
  5. 新电脑配置显卡驱动及CUDA、CUDNN环境
  6. Excel的二级级联以及多级级联的实现
  7. linux移植街机模拟器,gngeo 游戏模拟器(街机)移植CE3100
  8. ios html js调用陀螺仪,Js 获取手机陀螺仪
  9. 第十四届蓝桥杯C++B组题解(不完全对)
  10. 7种SQL JOINS 的实现