Rust高级代码题 - 手写一个 LRU Cache

Hi guys, this is Kevin here. 今天想给大家锻炼一个rust的底层数据结构的设计能力的题目,同时为了帮自己加深对rust的理解。好的,现在直接进入正题。

题目

实现:

rust 复制代码
struct LruCache<K, V>{...}

支持:

  • new(capacity: usize) -> Self
  • get(&mut self, key: &K) -> Option<&V>
  • put(&mut self, key: K, value: V)
  • 超过容量时淘汰最近最少使用的元素 要求:
  • get 后要更新最近使用顺序
  • 时间复杂度尽量做到接近 O(1)

考点

  • HashMap
  • 双向链表
  • Rc<RefCell<_>> / Box / 裸指针取舍
  • 可变借用冲突怎么规避
  • 数据结构设计能力

实现思路: LRU - 全称least-recent-used(最近最少使用)

Solution 1:

Hashmap + Vec

rust 复制代码
因为hashmap查找复杂度0(1), 更新顺序的话: 0(n) Vec中需要移除并添加
所以这个不太满足

Solution 2:

HashMap + 双向链表 + 裸指针

rust 复制代码
HashMap<K, *mut Node<V>>  // 直接存指针
性能: 最优
风险: 内存安全性难以保证,容易段错误
不推荐用于生产环境

Solution 3:

HashMap + 双向链表 + Rc<RefCell<_>>

rust 复制代码
HashMap<K, Rc<RefCell<Node<V>>>>
性能: O(1)
安全性: 完全的内存安全
可维护性: 高

关键结构:

rust 复制代码
struct Node<V> {
    value: V,
    prev: Option<Rc<RefCell<Node<V>>>>,
    next: Option<Rc<RefCell<Node<V>>>>,
}

struct LruCache<K, V> {
    capacity: usize,
    cache: HashMap<K, Rc<RefCell<Node<V>>>>,
    head: Option<Rc<RefCell<Node<V>>>>,  // 最近使用
    tail: Option<Rc<RefCell<Node<V>>>>,  // 最少使用
}

See complete implementation, please refers to:

github.com/KevinSheera...

同时,unit test已经都pass了

最后的summary

好啦,其实如果手动实现的话,确实需要做一个详细的分析,才能真正从中领悟他的hashmap的底层实现和所有权机制。今天的分享就到这里, thanks for reading.

相关推荐
货拉拉技术2 分钟前
复杂业务规则太多?我们搭了一个规则可视化配置平台
后端
爱勇宝31 分钟前
AI 都能写代码了,还要学计算机吗?
前端·后端·程序员
cfm_291433 分钟前
Spring监听器
java·spring boot·后端
逝水无殇34 分钟前
C# 特性详解
开发语言·后端·c#
cfm_291436 分钟前
SpringBoot 数据库全栈整合
数据库·spring boot·后端
xn713338 分钟前
别再把 MCP Roots 当安全沙箱:一个符号链接就能逃逸目录
人工智能·后端·mcp
SamDeepThinking40 分钟前
Java面向对象在JVM里怎么实现
java·后端·面试
学以智用43 分钟前
HTTP 请求头 Headers 完整详解
前端·后端
妙码生花1 小时前
从 PHP 到 AI + Golang,程序员自救转型手记(三十五):控制台静态页面、深入研究时间格式化方案
后端·go·ai编程
程序猿大帅1 小时前
Java 虚拟线程发布两年后,我们把它从生产环境移除了
后端