这次不怕面试官再问LRU!

LRU是Least Recently Used的缩写,即最近最少使用,也叫最近最久未使用,最初应用于操作系统的页面置换算法。当发生缺页中断后,选择将最久未使用的那一个页面替换出去。实践表明,LRU可以最大化页面页面利用率。LRU除了应用在操作系统层面,常被应用到缓存系统的设计中,很多著名的缓存系统,比如iOS中的YYCache、远程字典服务Redis中都使用了LRU。

那么为什么要设计缓存系统呢?因为磁盘的访问速度要比内存的访问速度慢很多,如果所有数据都存储在磁盘上访问的时延会很大,而所有数据都存放到内存里内存又有可能不够,而且内存中的数据断电后就会被清除。当然,有访问时间存在差异的地方都可以做缓存,不一定是磁盘与内存。缓存系统设计的最主要的目的,就是加快访问速度降低时延。

为了清楚的说明LRU所做的事情,我们先举个例子。

我们假设内存一共就可以存放3个节点,其余的节点存放在磁盘上或者在服务器上(其余的节点存放在那里读者其实不用关心)。现在我们给节点编号,并依次访问以下编号的节点。

依次访问1、2、3、2、1、4、5、2;

我们把最左边的节点当作最近访问的节点,最右边的节点当作最久未使用的节点。

第一次访问的是1,此时内存中还是空的,直接将1加入即可,加入后内存中是:

[1];

第二次访问的是2,此时内存中有1个节点,还没有达到内存的最大容量3,因此也可以直接加入,加入后内存中是:

[2,1];

第三次访问的是3,此时内存中有2个节点,还没有达到内存的最大容量3,因此还可以直接加入,加入后内存中是:

[3,2,1];

第四次访问的是2,我们通过查找内存中的节点发现,2已经在内存中了,我们只需要挪动一下位置,把2放到最近使用的位置(最左边的位置),其余节点的相对位置保持不变:
[2,3,1];

第五次访问的是1,我们通过查找内存中的节点发现,1也已经在内存中了,我们只需要挪动一下位置,把1放到最近使用的位置(最左边的位置),其余节点的相对位置保持不变:

[1,2,3];

第六次访问的是4,我们通过查找内存中的节点发现,4还不在内存中(如果在操作系统的角度看,此时就是发生了缺页中断),我们需要将4加入内存中,但是此时内存中的节点数已经达到内存的最大容量3了,因此必须替换出去一个。根据LRU算法,应该把最久未使用的3替换出去,然后将4加入放到最近使用的位置,其余节点的相对位置保持不变:

[4,1,2];

第7次访问的是5,我们通过查找内存中的节点发现,5还不在内存中(如果在操作系统的角度看,此时就是发生了缺页中断),我们需要将5加入内存中,但是此时内存中的节点数已经达到内存的最大容量3了,因此必须替换出去一个。根据LRU算法,应该把最久未使用的2替换出去,然后将5加入放到最近使用的位置,其余节点的相对位置保持不变:

[5,4,1];

第8次访问的是2,虽然2曾经存在于内存中,但是其已经被替换出去了,此时仍然发生了缺页中断,因此需要把1替换出去,把2放到最近访问的位置,其余节点的相对位置保持不变:

[2,5,4]。

知道了LRU是什么后,剩下的就是设计LRU了。根据上面的例子,我们可以很容易地设计出这个缓存系统。缓存没满就直接往里加,缓存没满就挪动节点,保证最近访问的节点在最近访问的位置即可。

 

第一种方法:挪动位置法

这种方法本质上比较暴力,但是相对于其他暴力方法,这种暴力方法通过了LeetCode的测试。

数据上我们采用C++

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值