首页
技术小册
AIGC
面试刷题
技术文章
MAGENTO
云计算
视频课程
源码下载
PDF书籍
「涨薪秘籍」
登录
注册
01 | 合格程序员的第一步:算法与数据结构
02 | 如何事半功倍地学习算法与数据结构
03 | 如何计算算法的复杂度
04 | 如何通过LeetCode来进行算法题目练习
05 | 理论讲解:数组&链表
06 | 面试题:反转一个单链表&判断链表是否有环
07 | 理论讲解:堆栈&队列
08 | 面试题:判断括号字符串是否有效
09 | 面试题:用队列实现栈&用栈实现队列
10 | 理论讲解:优先队列
11 | 面试题:返回数据流中的第K大元素
12 | 面试题:返回滑动窗口中的最大值
13 | 理论讲解:哈希表
14 | 面试题:有效的字母异位词
15 | 面试题:两数之和
16 | 面试题:三数之和
17 | 理论讲解:树&二叉树&二叉搜索树
18 | 面试题:验证二叉搜索树
19 | 面试题:二叉树&二叉搜索树的最近公共祖先
20 | 理论讲解:二叉树遍历
21 | 理论讲解:递归&分治
22 | 面试题:Pow(x,n)
23 | 面试题:求众数
24 | 理论讲解:贪心算法
25 | 面试题:买卖股票的最佳时机
26 | 理论讲解:广度优先搜索
27 | 理论讲解:深度优先搜索
28 | 面试题:二叉树层次遍历
29 | 面试题:二叉树的最大和最小深度
30 | 面试题:生成有效括号组合
31 | 理论讲解:剪枝
32 | 面试题:N皇后问题
33 | 面试题:数独问题
34 | 理论讲解:二分查找
35 | 面试题:实现一个求解平方根的函数
36 | 理论讲解:字典树
37 | 面试题:实现一个字典树
38 | 面试题:二维网格中的单词搜索问题
39 | 理论讲解:位运算
40 | 面试题:统计位1的个数
41 | 面试题:2的幂次方问题&比特位计数问题
42 | 面试题:N皇后问题的另一种解法
43 | 理论理解:动态规划(上)
44 | 理论理解:动态规划(下)
45 | 面试题:爬楼梯
46 | 面试题:三角形的最小路径和
47 | 面试题:乘积最大子序列
48 | 面试题:股票买卖系列
49 | 面试题:最长上升子序列
50 | 面试题:零钱兑换
51 | 面试题:编辑距离
52 | 理论讲解:并查集
53 | 面试题:岛屿的个数&朋友圈(上)
54 | 面试题:岛屿的个数&朋友圈(下)
55 | 理论讲解: LRU Cache
56 | 面试题:设计和实现一个LRU Cache缓存机制
57 | 理论讲解:布隆过滤器
当前位置:
首页>>
技术小册>>
算法面试通关 50 讲
小册名称:算法面试通关 50 讲
### 55 | 理论讲解:LRU Cache 在算法与数据结构的世界中,LRU(Least Recently Used)缓存是一种非常经典且广泛应用的策略,尤其在处理缓存失效和内存管理问题时显得尤为关键。LRU缓存机制通过记录数据的最近访问顺序,确保当缓存容量达到上限时,能够优先淘汰那些最长时间未被访问的数据项,从而最大化缓存的利用率和命中率。本章节将深入剖析LRU Cache的理论基础、实现原理以及几种常见的实现方式。 #### 一、LRU Cache概述 LRU(Least Recently Used)缓存策略的核心思想是“最近最少使用”,即认为如果一个数据项在最近一段时间内没有被访问,那么在未来一段时间内被访问的可能性也很低。因此,当缓存空间不足时,应该优先淘汰这些最近最少被访问的数据项,以腾出空间给新的数据项或更频繁访问的数据项。 LRU缓存广泛应用于各种场景,包括但不限于操作系统中的页面置换、数据库查询缓存、Web服务器缓存、以及现代编程框架中的缓存机制等。 #### 二、LRU Cache的实现原理 LRU Cache的实现通常依赖于两种核心数据结构:哈希表(Hash Table)和双向链表(Doubly Linked List)。哈希表用于实现数据的快速查找和访问,而双向链表则用于记录数据项的访问顺序。 - **哈希表**:以数据项的键(Key)为索引,存储对应的节点指针或值(具体取决于实现方式)。哈希表的作用是实现O(1)时间复杂度的数据访问。 - **双向链表**:链表中的节点代表缓存中的数据项,节点之间的链接表示数据的访问顺序。链表的头部表示最近访问的数据项,尾部表示最久未访问的数据项。当数据被访问时,该数据对应的节点会被移动到链表的头部,以更新其访问顺序。 #### 三、LRU Cache的常见实现方式 ##### 1. 基于哈希表和双向链表的实现 这是最常见的LRU Cache实现方式,也是效率较高的实现之一。具体步骤如下: - **初始化**:创建一个哈希表和一个双向链表。哈希表的键为缓存项的键,值为对应链表节点的指针。双向链表的头尾分别指向最近访问和最久未访问的数据项。 - **访问数据**: - 首先在哈希表中查找数据项。 - 如果找到,则将该节点从当前位置移动到链表头部,表示最近访问。 - 如果未找到,则检查缓存是否已满: - 如果未满,则创建新节点,插入链表头部,并在哈希表中添加相应键值对。 - 如果已满,则删除链表尾部节点(最久未访问的数据项),在链表头部插入新节点,并在哈希表中更新或添加键值对。 - **添加数据**:类似于访问数据流程,但总是会在链表头部插入新节点,因为新添加的数据总是被视为最近访问的。 ##### 2. 伪代码示例 以下是一个简化的LRU Cache实现的伪代码: ```plaintext class ListNode: def __init__(self, key, value): self.key = key self.value = value self.prev = None self.next = None class LRUCache: def __init__(self, capacity: int): self.capacity = capacity self.cache = {} # 使用哑节点简化边界条件处理 self.head = ListNode(0, 0) self.tail = ListNode(0, 0) self.head.next = self.tail self.tail.prev = self.head def get(self, key: int) -> int: if key not in self.cache: return -1 node = self.cache[key] self._remove(node) self._add(node) return node.value def put(self, key: int, value: int) -> None: if key in self.cache: self._remove(self.cache[key]) newNode = ListNode(key, value) self._add(newNode) self.cache[key] = newNode if len(self.cache) > self.capacity: tail = self.tail.prev self._remove(tail) del self.cache[tail.key] def _remove(self, node): prev = node.prev next = node.next prev.next = next next.prev = prev def _add(self, node): node.prev = self.head node.next = self.head.next self.head.next.prev = node self.head.next = node ``` ##### 3. 性能分析 - **时间复杂度**:对于`get`和`put`操作,主要操作包括哈希表的查找、链表的节点移动和可能的节点删除与添加,这些操作均可在O(1)时间内完成。 - **空间复杂度**:O(n),其中n为缓存的容量,因为需要维护一个哈希表和一个双向链表来存储所有缓存项。 #### 四、LRU Cache的变种与扩展 在实际应用中,LRU Cache还可以与其他技术结合,形成更强大的缓存策略。例如: - **带权重的LRU(Weighted LRU)**:在LRU的基础上,为每个数据项分配权重,淘汰时优先考虑权重较低且最久未访问的数据项。 - **两级LRU(Two-Level LRU)**:使用两种不同大小的缓存级别,第一级缓存较小但访问速度快,第二级缓存较大但访问速度稍慢。数据首先进入第一级缓存,当第一级缓存满时,将数据移动到第二级缓存。 - **结合TTL(Time-To-Live)的LRU**:为缓存项设置生存时间,当数据项在缓存中停留时间超过TTL时,无论其访问频率如何,都将被自动淘汰。 #### 五、总结 LRU Cache作为一种高效的数据缓存策略,在多种场景下均有着广泛的应用。通过结合哈希表和双向链表,LRU Cache能够在O(1)时间复杂度内完成数据的访问、更新和淘汰操作,从而确保缓存的高效性和实时性。此外,LRU Cache还可以与其他技术结合,形成更复杂的缓存策略,以适应不同的应用场景和需求。掌握LRU Cache的原理和实现,对于深入理解缓存机制和优化系统性能具有重要意义。
上一篇:
54 | 面试题:岛屿的个数&朋友圈(下)
下一篇:
56 | 面试题:设计和实现一个LRU Cache缓存机制
该分类下的相关小册推荐:
业务开发实用算法精讲
数据结构与算法(中)
编程之道-算法面试(上)
数据结构与算法(上)
数据结构与算法(下)
数据结构与算法之美
编程之道-算法面试(下)