(1)是什么?
Least Recently Used (最近最少使用)
缓存淘汰算法中的一种。因为缓存是保存在内存中的,内存是很吃紧很宝贵的,所以要保证最热点的数据做缓存,冷门数据淘汰。
(2)具体在哪些场景使用?
Mysql的缓冲池,Linux OS 的虚拟文件系统VFS都有用到。
(3)具体实现步骤?
既然是缓存,那肯定就是List中存放着一大串 Key - Value 结构,我们查找目标数据的时候就是for这个List找到对应的Key,这个List可能很长,所以我们可以把热点数据排到较前面,冷门的放后面,如果超过了长度,就淘汰,移除缓存List。
传统的LRU如下:
(1)首先定义一条链表List,初始化之初,它连续加载1~6的磁盘块到缓存中
1->2->3->4->5->6 六个page cache缓存页
(2)查询3,则3的page cache命中,遍历List并且将3移至头部(加快下次检索速度)
3->1->2->4->5->6
(3)查询7,发现缓存链表中没有page cache 命中,则读磁盘,并将7加入到缓存List头部,剔除掉列尾元素6
7->3->1->2->4->5
(4)牛客也是有道LRU的算法题,描述的也是这个思路:
(5)思路很清晰,也比较好做,代码实现:
首先是比较简单的调用方法:
public class SplitApplication {
private static List resultArray = new ArrayList();
public static void main(String[] args) {
int[][] twoArray = new int[][]{{1,1,1},{1,2,2},{1,3,3},{2,1},{1,4,4},{2,2}};
int listSize = 3;
testLRU(twoArray, listSize);
}
public static void testLRU(int[][] twoArray, int listSize){
LRU lru = new LRU(3);
for (int i = 0; i < twoArray.length; i++) {
Map map = new HashMap<>(1);
int[] oneArray = twoArray[i];
System.out.println(Arrays.toString(oneArray));
// 操作标志位独立拿出来
int opt = oneArray[0];
// 获取剩下的参数
if (opt==1){
// 表示set(x, y)
lru.set(oneArray[1],oneArray[2]);
} else if (opt == 2){
// 表示get(x),若x未出现过或已被移除,则返回-1
int result = lru.get(oneArray[1]);
resultArray.add(result);
}
}
System.out.println("查询结果"+resultArray.toString());
}
}
然后重头戏当时是LRU 实体类的定义:
public class LRU {
private List
(1)在这里我们定义了List
(2)定义Set方法往缓存List放元素,同时判断是否超出了大小,如果是,移除最后一个元素。如果不是,设置新值到头部。
(3)定义get方法获取缓存List的缓存信息,遍历List并且根据Key获取Value。
(4)不管get还是set,进行操作后都要调用 resortList 方法对List中的元素进行重新的排序。
(5)resortList 的主要任务,就是把刚才操作的数据当作热点数据移到最前面。
(6)就这么简单,考察的更多的是基础的逻辑判断和容器的使用。
执行main方法看效果:
设计LRU缓存结构(Java实现)_whiteBearClimb的博客-CSDN博客_设计lru缓存结构