LRU缓存算法缓存设计和

什么是缓存?

举个例子,去图书馆查资料,一般情况下我们会集中把我们有可能查阅的几本书从书架取下来,放在我们的桌面上,以便交叉查阅,从而避免频繁的从座位上跑到书架旁去取书。在这个例子里,书桌所扮演的就是缓存的角色。

缓存有两个特点:

  • 能在某种程度上降低访问数据的成本;
  • 其容量远小于外部存储的容量,如本例子中,书桌上能容纳的书本数就远小于书架的。

什么是 LRU 缓存?

LRU(Least Recently Used) 缓存是一种以 LRU 策略为缓存策略的缓存。而所谓的缓存策略,就是当缓存满了之后,又有新数据需要加入到缓存中时,我们怎么从缓存中删除旧数据为新数据腾出空间的策略。

依旧以图书馆为例,假设我们的书桌上只能容纳 3 本书,并且已经放了 3 本书在上面,此时我们需要查阅第 4 本书,那么我们就必须权衡将原先书桌上的 3 本书的中的哪一本放回书架去。这个权衡的过程就是所谓的缓存策略。

LRU,Least Recently Used 的简写,即近期最少使用算法。该算法依据于程序的局部性原理, 其淘汰旧数据的策略是,距离当前最久没有被访问过的数据应该被淘汰。

基于双链表 的LRU实现:

传统意义的LRU算法是为每一个Cache对象设置一个计数器,每次Cache命中则给计数器+1,而Cache用完,需要淘汰旧内容,放置新内容时,就查看所有的计数器,并将最少使用的内容替换掉。

它的弊端很明显,如果Cache的数量少,问题不会很大, 但是如果Cache的空间过大,达到10W或者100W以上,一旦需要淘汰,则需要遍历所有计算器,其性能与资源消耗是巨大的。效率也就非常的慢了。

它的原理: 将Cache的所有位置都用双连表连接起来,当一个位置被命中之后,就将通过调整链表的指向,将该位置调整到链表头的位置,新加入的Cache直接加到链表头中。

这样,在多次进行Cache操作后,最近被命中的,就会被向链表头方向移动,而没有命中的,而想链表后面移动,链表尾则表示最近最少使用的Cache。

当需要替换内容时候,链表的最后位置就是最少被命中的位置,我们只需要淘汰链表最后的部分即可。

上面说了这么多的理论, 下面用代码来实现一个LRU策略的缓存。
我们用一个对象来表示Cache,并实现双链表。

这个问题在面试被问了,然后说了一句:这个我不会,回来查阅一下,大致了解一下。

你可能感兴趣的:(Linux,面试题)