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

0 阅读1分钟

Hi guys, this is Kevin here. 今天想给大家锻炼一个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

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

Solution 2:

HashMap + 双向链表 + 裸指针

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

Solution 3:

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

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

关键结构:

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了

Cursor 2026-04-21 17.40.04.png

最后的summary

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