这题应该见的不少了,写写记录一下. 实现该功能分析: (1) O(1) 时间完成查找,那除了 hash 别无选择. (2) LRU 最近最少使用算法,为了方便数据的淘汰.需要对最近访问的数据放未访问数据之前. 用双向链表实现即可.(通常情况下,双向链表读取.插入的时间复杂度都是O(n), 但是如果知道插入位置,则可以实现O(1)实现.) 实现: hash存key对应的数据在双向链表中的位置,就可以完成该功能. 具体代码: #include <iostream> #include <lis…
好吧,有人可能觉得我标题党了,但我想告诉你们的是,前阵子面试确实挂在了 RLU 缓存算法的设计上了.当时做题的时候,自己想的太多了,感觉设计一个 LRU(Least recently used) 缓存算法,不会这么简单啊,于是理解错了题意(我也是服了,还能理解成这样,,,,),自己一波操作写了好多代码,后来卡住了,再去仔细看题,发现自己应该是理解错了,就是这么简单,设计一个 LRU 缓存算法. 不过这时时间就很紧了,按道理如果你真的对这个算法很熟,十分钟就能写出来了,但是,自己虽然理解 LRU…
今天我们来聊聊“链表(Linked list)”这个数据结构.学习链表有什么用呢?为了回答这个问题,我们先来讨论一个经典的链表应用场景,那就是+LRU+缓存淘汰算法. 缓存是一种提高数据读取性能的技术,在硬件设计.软件开发中都有着非常广泛的应用,比如常见的+CPU+缓存.数据库缓存.浏览器缓存等等. 缓存的大小有限,当缓存被用满时,哪些数据应该被清理出去,哪些数据应该被保留?这就需要缓存淘汰策略来决定.常见的策略有三种:先进先出策略 FIFO(First In,First Out).最少使用策略…
一.什么是链表 和数组一样,链表也是一种线性表. 从内存结构来看,链表的内存结构是不连续的内存空间,是将一组零散的内存块串联起来,从而进行数据存储的数据结构. 链表中的每一个内存块被称为节点Node.节点除了存储数据外,还需记录链上下一个节点的地址,即后继指针next. 二.链表的优劣 插入.删除数据效率高O(1)级别(只需更改指针指向即可),随机访问效率低O(n)级别(需要从链头至链尾进行遍历). 和数组相比,内存空间消耗更大,因为每个存储数据的节点都需要额外的空间存储后继指针. 三.常用链表…
缓存淘汰策略: FIFO:先入先出策略 LFU:最少使用策略 LRU:最近最少使用策略   链表的数据结构: 可以看到,数组需要连续的内存空间,当内存空间充足但不连续时,也会申请失败触发GC,链表则可以是零散的.…
今天我们来聊聊“链表(Linked list)”这个数据结构.学习链表有什么用呢?为了回答这个问题,我们先来讨论一个经典的链表应用场景,那就是 LRU 缓存淘汰算法. 缓存是一种提高数据读取性能的技术,在硬件设计.软件开发中都有着非常广泛的应用,比如常见的 CPU 缓存.数据库缓存.浏览器缓存等等. 缓存的大小有限,当缓存被用满时,哪些数据应该被清理出去,哪些数据应该被保留?这就需要缓存淘汰策略来决定.常见的策略有三种:先进先出策略 FIFO(First In,First Out).最少使用策略…
阿里巴巴笔试考到了LRU,一激动忘了怎么回事了..准备不充分啊.. 缓存这个东西就是为了提高运行速度的,由于缓存是在寸土寸金的内存里面,不是在硬盘里面,所以容量是很有限的.LRU这个算法就是把最近一次使用时间离现在时间最远的数据删除掉.先说说List:每次访问一个元素后把这个元素放在 List一端,这样一来最远使用的元素自然就被放到List的另一端.缓存满了t的时候就把那最远使用的元素remove掉.但更实用的是HashMap.因为List太慢,要删掉的数据总是位于List底层数组的第一个位置,…
常见的缓存淘汰策略: 先进先出 FIFO 最少使用LFU(Least Frequently Used) 最近最少使用 LRU(Least Recently Used) 链表定义: 链表也是线性表的一种, 数组需要一块连续的内存空间来存储,对内存要求比较高, 链表恰恰相反,它并不需要一块连续的内存空间,它通过"指针"将一组零散的内存块 串联起来使用. 最常见的链表结构: 单链表 双向链表 循环链表 用空间换时间: 当内存空间充足的时候,如果更加追求代码的执行速度,可以选择空间复杂度相对较…
1. LinkedHashMap实现LRU缓存 LRU缓存核心是根据访问顺序排序, 自动移除队尾缓存, LinkedHashMap已经实现了这些要求: public LRUCache<K, V> extends LinkedHashMap<K, V> { private int cacheSize; public LRUCache(int cacheSize){ super(16, 0.75, true); // key1: true表示使用访问排序, 默认false表示插入排序…
什么是LRU算法? LRU是Least Recently Used的缩写,即最近最少使用,在有限的内容块中存储最近使用次数最多的数据,当内容块已满时,把最少使用的数据删除以便存储新的内容.…
import java.util.Hashtable; class DLinkedList { String key; //键 int value; //值 DLinkedList pre; //双向链表前驱 DLinkedList next; //双向链表后继 } public class LRUCache { private Hashtable<String,DLinkedList> cache = new Hashtable<String,DLinkedList>(); pr…
力扣链接:146. LRU 缓存机制 思路:哈希表 + 双向链表 为什么必须要用双向链表? 因为我们需要删除操作.删除一个节点不光要得到该节点本身的指针,也需要操作其前驱节点的指针,而双向链表才能支持直接查找前驱,保证操作的时间复杂度 O(1). 为什么要在链表中同时存储 key 和 val,而不是只存储 val? 当缓存容量已满,我们不仅仅要删除最后一个节点,还要把哈希表 中映射到该节点的 key 同时删除,而这个 key 只能由 节点得到.如果 节点结构中只存储 val,那么我们就无法得知…
最近遇到一个需求,需要频繁访问数据库,但是访问的内容只是 id + 名称 这样的简单键值对. 频繁的访问数据库,网络上和内存上都会给数据库服务器带来不小负担. 于是打算写一个简单的LRU缓存来缓存这样的键值对.考虑到tomcat的用户办法访问是多线程进行的. 所以还要保证cache是线程安全的.避免在用户操作的时候修改了cache导致其他用户读到不合法的信息.  构思 一, 数据结构选取 思路: 1.最简单的是用链表,最新访问的元素所在节点插入到头节点的后面,当要回收的时候就去释放链表尾部节点.…
前言 缓存是一种提高数据读取性能的技术,在计算机中cpu和主内存之间读取数据存在差异,CPU和主内存之间有CPU缓存,而且在内存和硬盘有内存缓存.当主存容量远大于CPU缓存,或磁盘容量远大于主存时,哪些数据应该被应该被清理,哪些数据应该被保留,这就需要缓存淘汰策略来决定.常见的策略有三种:先进先出策略FIFO(First In,First Out).最少使用策略LFU(Least Frequently Used).最近最少使用策略LRU(Least Recently Used). LRU描述 设…
LRU Cache的LinkedHashMap实现 LRU Cache的链表+HashMap实现 LinkedHashMap的FIFO实现 调用示例 LRU是Least Recently Used 的缩写,翻译过来就是“最近最少使用”,LRU缓存就是使用这种原理实现,简单的说就是缓存一定量的数据,当超过设定的阈值时就把一些过期的数据删除掉,比如我们缓存10000条数据,当数据小于10000时可以随意添加,当超过10000时就需要把新的数据添加进来,同时要把过期数据删除,以确保我们最大缓存1000…
今天我们来深入探索一下LinkedHashMap的底层原理,并且使用linkedhashmap来实现LRU缓存. 摘要: HashMap和双向链表合二为一即是LinkedHashMap.所谓LinkedHashMap,其落脚点在HashMap,因此更准确地说,它是一个将所有Entry节点链入一个双向链表的HashMap. 由于LinkedHashMap是HashMap的子类,所以LinkedHashMap自然会拥有HashMap的所有特性.比如,LinkedHashMap的元素存取过程基本与Ha…
Leetcode难题,题目为: 运用你所掌握的数据结构,设计和实现一个  LRU (最近最少使用) 缓存机制.它应该支持以下操作: 获取数据 get 和 写入数据 put . 获取数据 get(key) - 如果密钥 (key) 存在于缓存中,则获取密钥的值(总是正数),否则返回 -1.写入数据 put(key, value) - 如果密钥不存在,则写入其数据值.当缓存容量达到上限时,它应该在写入新数据之前删除最近最少使用的数据值,从而为新的数据值留出空间. 进阶: 你是否可以在 O(1) 时间…
LRU Cache的LinkedHashMap实现 LRU Cache的链表+HashMap实现 LinkedHashMap的FIFO实现 调用示例 LRU是Least Recently Used 的缩写,翻译过来就是“最近最少使用”,LRU缓存就是使用这种原理实现,简单的说就是缓存一定量的数据,当超过设定的阈值时就把一些过期的数据删除掉,比如我们缓存10000条数据,当数据小于10000时可以随意添加,当超过10000时就需要把新的数据添加进来,同时要把过期数据删除,以确保我们最大缓存1000…
算法:LRU(最近最少使用) 本文参考自小灰文章:https://mp.weixin.qq.com/s/B5xiVeW22ZumbI9KfrYJSg LRU算法 什么是LRU算法 LRU算法又称最近最少使用算法,它的基本思想是长期不被使用的数据,在未来被用到的几率也不大,所以当新的数据进来时我们可以优先把这些数据替换掉. 在LRU算法中,使用了一种有趣的数据结构,称为哈希链表.我们知道哈希表是由多个<Key,Value>对组成的,哈希链表是将这写节点链接起来,每一个节点都有一个前驱结点和后驱节…
运用你所掌握的数据结构,设计和实现一个  LRU (最近最少使用) 缓存机制.它应该支持以下操作: 获取数据 get 和 写入数据 put . 获取数据 get(key) - 如果密钥 (key) 存在于缓存中,则获取密钥的值(总是正数),否则返回 -1.写入数据 put(key, value) - 如果密钥不存在,则写入其数据值.当缓存容量达到上限时,它应该在写入新数据之前删除最近最少使用的数据值,从而为新的数据值留出空间. 进阶: 你是否可以在 O(1) 时间复杂度内完成这两种操作? 示例:…
今天为大家分享很出名的LRU算法,第一讲共包括4节. LRU概述 LRU使用 LRU实现 Redis近LRU概述 第一部分:LRU概述 LRU是Least Recently Used的缩写,译为最近最少使用.它的理论基础为“最近使用的数据会在未来一段时期内仍然被使用,已经很久没有使用的数据大概率在未来很长一段时间仍然不会被使用”由于该思想非常契合业务场景 ,并且可以解决很多实际开发中的问题,所以我们经常通过LRU的思想来作缓存,一般也将其称为LRU缓存机制.因为恰好leetcode上有这道题,所…
目录 1. LRU 缓存介绍 2. ConcurrentLinkedQueue简单介绍 3. ReadWriteLock简单介绍 4.ScheduledExecutorService 简单介绍 5. 徒手撸一个线程安全的 LRU 缓存 5.1. 实现方法 5.2. 原理 5.3. put方法具体流程分析 5.4. 源码 6. 实现一个线程安全并且带有过期时间的 LRU 缓存 最近被读者问到"不用LinkedHashMap的话,如何实现一个线程安全的 LRU 缓存?网上的代码太杂太乱,Guide哥…
前言 LRU 是 Least Recently Used 的简写,字面意思则是最近最少使用. 通常用于缓存的淘汰策略实现,由于缓存的内存非常宝贵,所以需要根据某种规则来剔除数据保证内存不被占满. 在redis的数据淘汰策略中就包含LRU淘汰算法 如何实现一个完整的LRU缓存呢?这个缓存要满足: 这个缓存要记录使用的顺序 随着缓存的使用变化,要能更新缓存的顺序 基于这种特点,可以使用一个常用的数据结构:链表 每次加入新的缓存时都添加到链表的头节点 当缓存再次被使用时移动缓存到头节点 当添加的缓存超…
当 Redis 作为缓存使用时,当你添加新的数据时,有时候很方便使 Redis 自动回收老的数据.LRU 实际上是被唯一支持的数据移除方法.Redis 的 maxmemory 指令,用于限制内存使用到一个固定的容量,也包含深入探讨 Redis 使用的 LRU 算法,一个近似准确的 LRU. maxmemory 配置指令(configuration directive) maxmemory 配置指令是用来配置 Redis 为数据集使用指定的内存容量大小.可以使用 redis.conf 文件来设置配…
引子: 我们平时总会有一个电话本记录所有朋友的电话,但是,如果有朋友经常联系,那些朋友的电话号码不用翻电话本我们也能记住,但是,如果长时间没有联系了,要再次联系那位朋友的时候,我们又不得不求助电话本,但是,通过电话本查找还是很费时间的.但是,我们大脑能够记住的东西是一定的,我们只能记住自己最熟悉的,而长时间不熟悉的自然就忘记了. 其实,计算机也用到了同样的一个概念,我们用缓存来存放以前读取的数据,而不是直接丢掉,这样,再次读取的时候,可以直接在缓存里面取,而不用再重新查找一遍,这样系统的反应能力…
当Redis用作缓存时,通常可以让它在添加新数据时自动逐出旧数据. 这种行为在开发人员社区中非常有名,因为它是流行的memcached系统的默认行为. LRU实际上只是支持的驱逐方法之一. 本页介绍了Redis maxmemory指令的更一般主题,该指令用于将内存使用限制为固定数量,并且它还深入介绍了Redis使用的LRU算法,实际上是精确LRU的近似值. 从Redis 4.0版开始,引入了新的LFU(最不常用,Least Frequently Used)驱逐策略. 本文档的单独部分对此进行了介…
当 Redis 作为缓存使用时,当你添加新的数据时,有时候很方便使 Redis 自动回收老的数据.LRU 实际上是被唯一支持的数据移除方法.Redis 的 maxmemory 指令,用于限制内存使用到一个固定的容量,也包含深入探讨 Redis 使用的 LRU 算法,一个近似准确的 LRU. maxmemory 配置指令(configuration directive) maxmemory 配置指令是用来配置 Redis 为数据集使用指定的内存容量大小.可以使用 redis.conf 文件来设置配…
LRU(Least Recently Used)  LRU是近期最少使用的算法,它的核心思想是当缓存满时,会优先淘汰那些近期最少使用的缓存对象. 采用LRU算法的缓存有两种:LrhCache和DisLruCache,分别用于实现内存缓存和硬盘缓存,其核心思想都是LRU缓存算法. 1.LruCache的介绍 LruCache是个泛型类,主要算法原理是把最近使用的对象用强引用(即我们平常使用的对象引用方式)存储在 LinkedHashMap 中.当缓存满时, 把最近最少使用的对象从内存中移除,并提供…
引子: 我们平时总会有一个电话本记录所有朋友的电话,但是,如果有朋友经常联系,那些朋友的电话号码不用翻电话本我们也能记住,但是,如果长时间没有联系 了,要再次联系那位朋友的时候,我们又不得不求助电话本,但是,通过电话本查找还是很费时间的.但是,我们大脑能够记住的东西是一定的,我们只能记住自己 最熟悉的,而长时间不熟悉的自然就忘记了. 其实,计算机也用到了同样的一个概念,我们用缓存来存放以前读取的数据,而不是直接丢掉,这样,再次读取的时候,可以直接在缓存里面取,而不用再重 新查找一遍,这样系统的反…
一.LRU简介 LRU是Least Recently Used的缩写,即:最近最少使用. 它是内存管理中的一种页面置换算法,对于在内存中但是又不用的数据块,操作系统会根据哪些数据属于LRU而将其移除内存而腾出空间来加载另外的数据. 二.redis LRU 官方文章:https://redis.io/topics/lru-cache#using-redis-as-an-lru-cache redis常常被用作缓存,当有新的数据进来的时候会自动驱逐旧的数据.LRU是memcached 默认的驱逐策略…