LRU缓存机制,全称Least Recently Used,字面意思就是最近最少使用,是一种缓存淘汰策略。换句话说,LRU机制就是认为最近使用的数据是有用的,很久没用过的数据是无用的,当内存满了就优先删除很久没有使用的数据

基于LeetCode146,可以使用哈希链表或者自定义双端链表类+哈希表两种方法来实现LRU缓存机制。

它应该支持以下操作:获取数据get和 写入数据put

获取数据get(key):如果密钥 (key) 存在于缓存中,则获取密钥的值(总是正数),否则返回-1

写入数据put(key, value):如果密钥不存在,则写入其数据值。当缓存容量达到上限时,它应该在写入新数据之前删除最近最少使用的数据值,从而为新的数据值留出空间。

1. 基于LinkedHashMap实现LRU缓存机制

class LRUCache {
Map<Integer, Integer> map;
int capacity; public LRUCache(int capacity) {
this.capacity = capacity;
map = new LinkedHashMap<>();
} public int get(int key) {
// 若key不存在返回-1
if(!map.containsKey(key)) return -1;
// 若key存在则获取key对应的val
int val = map.get(key);
// 更新位置
put(key, val);
return val;
} public void put(int key, int val) {
// 若缓存命中则先删除数据在重新放入以更新位置
if(map.containsKey(key)) {
map.remove(key);
map.put(key, val);
} else {
// 若缓存未命中则先判断是否达到最大容量
// 超出容量则删除最久没有使用的数据(利用迭代器删除第一个)
if (capacity == map.size()) map.remove(map.keySet().iterator().next());
// 删除完成后存放新数据
map.put(key, val);
}
}
}

2. 基于DoubleList与HashMap实现LRU缓存机制

如果不使用LinkedHashMap,可以自己造轮子,自定义DoubleList类并结合HashMap实现与LinkedHashMap相同的功能。

class LRUCache {
int capacity;
DoubleList cache;
Map<Integer, Node> map; public LRUCache(int capacity) {
this.capacity = capacity;
cache = new DoubleList();
map = new HashMap<>();
} public int get(int key) {
if(!map.containsKey(key)) return -1;
int val = map.get(key).val;
put(key, val);
return val;
} public void put(int key, int val) {
Node node = new Node(key, val);
if(map.containsKey(key)) {
cache.remove(map.get(key));
cache.addFirst(node);
map.put(key, node);
} else {
if(capacity == cache.size) map.remove(cache.removeLast().key);
cache.addFirst(node);
map.put(key, node);
}
}
} class DoubleList {
Node head, tail;
int size; public DoubleList() {
head = new Node(0, 0);
tail = new Node(0, 0);
head.next = tail;
tail.prev = head;
size = 0;
} public void addFirst(Node node) {
Node temp = head.next;
node.next = temp;
temp.prev = node;
head.next = node;
node.prev = head;
size++;
} public void remove(Node node) {
Node temp = node.prev;
temp.next = node.next;
temp.next.prev = temp;
size--;
} public Node removeLast() {
if (size == 0) return null;
Node del = tail.prev;
remove(del);
return del;
}
} class Node {
int key, val;
Node prev, next; public Node(int key, int val) {
this.key = key;
this.val = val;
}
}

常见面试题之操作系统中的LRU缓存机制实现的更多相关文章

  1. 【转载】常见面试题:C#中String和string的区别分析

    在很多人面试C#开发工程师的时候,会遇到一个面试题,就是C#中String和string有啥区别.其实针对这个问题C#中String和string没有本质上的区别,两者在程序中都可使用,稍微的一个区别 ...

  2. JAVA常见面试题问题简述(持续更新中)

    JAVA常见面试题问题简述 1. springcloud和dubbo的区别 ①相比之下springcloud 的社区会更加活跃,解决问题的速度也会越来越快,dubbo相对来说如果碰到没有解决的问题,就 ...

  3. 常见面试题之ListView的复用及如何优化

    经常有人问我,作为刚毕业的要去面试,关于安卓开发的问题,技术面试官会经常问哪些问题呢?我想来想去不能一股脑的全写出来,我准备把这些问题单独拿出来写,并详细的分析一下,这样对于初学者是最有帮助的.这次的 ...

  4. 整理的最全 python常见面试题(基本必考)

    整理的最全 python常见面试题(基本必考) python 2018-05-17 作者 大蛇王 1.大数据的文件读取 ① 利用生成器generator ②迭代器进行迭代遍历:for line in ...

  5. 整理的最全 python常见面试题

      整理的最全 python常见面试题(基本必考)① ②③④⑤⑥⑦⑧⑨⑩ 1.大数据的文件读取: ① 利用生成器generator: ②迭代器进行迭代遍历:for line in file; 2.迭代 ...

  6. 【转载】JAVA常见面试题及解答(精华)

     JAVA常见面试题及解答(精华)       1)transient和volatile是java关键字吗?(瞬联) 如果用transient声明一个实例变量,当对象存储时,它的值不需要维持.例如: ...

  7. 【javascript常见面试题】常见前端面试题及答案

    转自:http://www.cnblogs.com/syfwhu/p/4434132.html 前言 本文是在GitHub上看到一个大牛总结的前端常见面试题,很多问题问的都很好,很经典.很有代表性.上 ...

  8. 夯实Java基础系列16:一文读懂Java IO流和常见面试题

    本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 https://github.com/h2pl/Java-Tutorial 喜欢的话麻烦点下 ...

  9. 【搞定 Java 并发面试】面试最常问的 Java 并发基础常见面试题总结!

    本文为 SnailClimb 的原创,目前已经收录自我开源的 JavaGuide 中(61.5 k Star![Java学习+面试指南] 一份涵盖大部分Java程序员所需要掌握的核心知识.欢迎 Sta ...

随机推荐

  1. Python os.stat_float_times() 方法

    概述 os.stat_float_times() 方法用于决定stat_result是否以float对象显示时间戳.高佣联盟 www.cgewang.com 语法 stat_float_times() ...

  2. 牛客练习赛63 牛牛的斐波那契字符串 矩阵乘法 KMP

    LINK:牛牛的斐波那契字符串 虽然sb的事实没有改变 但是 也不会改变. 赛时 看了E和F题 都不咋会写 所以弃疗了. 中午又看了一遍F 发现很水 差分了一下就过了. 这是下午和古队长讨论+看题解的 ...

  3. day11.函数的全局变量和局部变量

    一.定义 """ 局部变量 : 在函数内部定义的变量(局部命名空间) 全局变量 : 在函数外部定义的或者使用global在函数内部定义(全局命名空间) 作用域: 作用的范 ...

  4. beyond compare4 密钥 亲测可用

    beyond compare4过了试用期: 密钥: w4G-in5u3SH75RoB3VZIX8htiZgw4ELilwvPcHAIQWfwfXv5n0IHDp5hv1BM3+H1XygMtiE0-J ...

  5. “随手记”开发记录day19

    将软件推荐给父母,先尝试使用软件,观察bug,若有啥不足的,才能及时修改.

  6. Python解决网吧收费系统,远控网吧电脑设备!

    python破解网吧收费系统,远控网吧电脑设备! 很多人学习python,不知道从何学起.很多人学习python,掌握了基本语法过后,不知道在哪里寻找案例上手.很多已经做案例的人,却不知道如何去学习更 ...

  7. python获取系统内存占用信息的实例方法

    psutil是一个跨平台库(http://code.google.com/p/psutil/),能够轻松实现获取系统运行的进程和系统利用率(包括CPU.内存.磁盘.网络等)信息.它主要应用于系统监控, ...

  8. Python中匿名函数与内置高阶函数详解

    大家好,从今天起早起Python将持续更新由小甜同学从 初学者的角度 学习Python的笔记,其特点就是全文大多由 新手易理解 的 代码与注释及动态演示 .刚入门的读者千万不要错过! 很多人学习pyt ...

  9. MYSQL 按某个字段分组,然后取每组前3条记录

    先初始化一些数据,表名为 test ,字段及数据为: SQL执行结果为:每个 uid  都只有 3 条记录.   SQL语句为: SELECT   * FROM   test main WHERE   ...

  10. SpringBoot常用配置,引入外部配置文件信息,热加载

    SpringBoot的配置文件格式 yml规范 SpringBoot的配置文件支持properties和yml,甚至还支持json. 更推荐使用yml文件格式: yml文件,会根据换行和缩进帮助咱们管 ...