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.

相关推荐
子兮曰1 天前
jev-ultrafast 深度解析:7 秒订机票的浏览器 Agent 是如何炼成的
前端·后端·agent
子兮曰1 天前
Jev 爆发一周:7 秒 Agent 背后的 System One 生态与三场争议
前端·后端·ai编程
爱勇宝1 天前
ZCode 开源 24 小时:一份没有历史的账本,回答不了"有没有偷代码"
前端·后端·chatglm (智谱)
胡写代码1 天前
别再前后端各写一套表单校验了
java·后端
大勇前进1 天前
原生 PHP 还是 Laravel?小项目到底要不要上框架
后端
yuzhi_liu1 天前
我用 LangGraph4j 实现 Multi-Agent Supervisor
后端
alsmile1 天前
Node-RED 之外,国产规则引擎的新方案:基于标准语法,Go 先行实现
后端·开源·go
大白801 天前
PHP 内存溢出排查思路:看懂报错日志,精准定位问题
后端
二月龙1 天前
PHP 接口返回统一响应封装,让前后端对接更省心
后端
盖伦发发1 天前
软件工程SOLID 五大设计原则
后端·软件工程