news 2026/8/12 10:55:49

LRU 缓存实现:先把链表原语和边界条件写清楚

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
LRU 缓存实现:先把链表原语和边界条件写清楚

LRU 缓存实现:先把链表原语和边界条件写清楚

LRU 的常见写法是哈希表加双向链表:哈希表按 key 找节点,链表记录最近使用顺序。只要两种操作都保持常数次指针变更,GetPut的平均时间复杂度就是 O(1)。难点不在概念,而在淘汰和移动节点时保持两个结构同步。

让指针变更集中

用虚拟头尾节点可减少空链表和首尾节点的分支。链表只负责插入、删除和取尾节点;缓存对象负责 map、容量和调用顺序。这样单元测试可以分别覆盖链表和缓存。

type node struct { key, value int prev, next *node } func (c *Cache) detach(n *node) { n.prev.next = n.next n.next.prev = n.prev } func (c *Cache) attachFront(n *node) { n.next = c.head.next n.prev = c.head c.head.next.prev = n c.head.next = n } func (c *Cache) Get(key int) (int, bool) { n, ok := c.items[key] if !ok { return 0, false } c.detach(n) c.attachFront(n) return n.value, true }

完整的Put需要覆盖已有 key、容量为零、满容量淘汰和新节点插入。淘汰尾节点时,先从链表删除,再从 map 删除;节点保留 key 正是为了完成这一步。

工程中的几个限制

这段代码本身不是并发安全的。并发缓存可在外层加互斥锁,或按 key 分片;RWMutex未必有收益,因为Get也会移动节点,是写操作。容量、TTL、缓存穿透和缓存预热属于上层策略,不能由一个 LRU 结构自动解决。

测试至少包含:连续覆盖同一 key、容量为一、淘汰后重新写入、随机操作与参考 map 的结果对照。不要把纳秒级基准数字当作通用结论;分配、锁和 value 大小都会改变结果。

把链表原语拆开不是为了让代码“更高级”,而是让每一次指针修改都有唯一的位置可检查。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/12 10:54:58

彻底解决Win10此电脑空白图标:注册表命名空间扩展清理指南

1. 问题现象与根源剖析你有没有遇到过这种让人抓狂的情况?在Windows 10的“此电脑”里,打开“设备和驱动器”那一栏,冷不丁就冒出来一个或者好几个空白的图标。它们没有名字,鼠标放上去也不显示任何信息,右键菜单里除了…

作者头像 李华
网站建设 2026/8/12 10:54:26

Android Studio安装配置全攻略:从环境搭建到项目创建

1. 项目概述:为什么Android Studio是移动开发的起点如果你正准备踏入移动应用开发的大门,或者从其他开发环境切换过来,那么安装和配置好Android Studio就是你必须要迈过的第一道坎。这不仅仅是一个简单的“下一步、下一步”的安装过程&#x…

作者头像 李华
网站建设 2026/8/12 10:49:06

FanControl终极指南:Windows风扇智能控制完整教程 [特殊字符]

FanControl终极指南:Windows风扇智能控制完整教程 🚀 【免费下载链接】FanControl.Releases This is the release repository for Fan Control, a highly customizable fan controlling software for Windows. 项目地址: https://gitcode.com/GitHub_T…

作者头像 李华
网站建设 2026/8/12 10:47:35

因子图优化资源整合:从理论到工程落地的系统化实践

1. 从“单打独斗”到“协同作战”:为什么我们需要资源整合 在机器人、自动驾驶、增强现实这些领域,我们每天都在和“状态估计”打交道。简单说,就是让机器知道自己在哪里、周围环境是什么样。过去十几年,因子图优化(Fa…

作者头像 李华