MST

星途 面试题库

面试题:Rust并发场景下内部可变性的应用

假设你正在开发一个多线程的缓存系统,缓存数据需要在不同线程间共享且可能被修改。请使用Rust的内部可变性原语(如`Mutex`、`RwLock`等)和`RefCell`设计一个简单的缓存结构,要求写时保证数据一致性,读时允许多线程并发读取。请给出关键代码示例并解释设计思路。
45.9万 热度难度
编程语言Rust

知识考点

AI 面试

面试题答案

一键面试
  1. 设计思路

    • 为了保证写时数据一致性,我们可以使用Mutex或者RwLockRwLock更适合这种读多写少的场景,因为读操作可以并发执行,而写操作会独占锁,从而保证数据一致性。
    • 对于缓存数据的管理,我们可以使用RefCell,它在运行时检查借用规则,这样我们可以在需要时在内部修改数据。
    • 我们将设计一个缓存结构体,它内部包含一个RwLock包裹的RefCellRefCell中存放实际的缓存数据。
  2. 关键代码示例

use std::sync::{Arc, RwLock};
use std::cell::RefCell;

// 定义缓存结构体
struct Cache<T> {
    data: Arc<RwLock<RefCell<Option<T>>>>
}

impl<T> Cache<T> {
    // 创建新的缓存实例
    fn new() -> Self {
        Cache {
            data: Arc::new(RwLock::new(RefCell::new(None)))
        }
    }

    // 获取缓存数据
    fn get(&self) -> Option<T> {
        let lock = self.data.read().unwrap();
        let inner = lock.borrow();
        inner.clone()
    }

    // 设置缓存数据
    fn set(&self, value: T) {
        let mut lock = self.data.write().unwrap();
        let mut inner = lock.borrow_mut();
        *inner = Some(value);
    }
}

在上述代码中:

  • Cache结构体包含一个Arc<RwLock<RefCell<Option<T>>>>类型的data字段。Arc用于在多线程间共享数据,RwLock提供读写锁,RefCell允许内部可变性,Option<T>用于表示缓存数据可能为空。
  • new方法用于创建一个新的Cache实例。
  • get方法首先获取读锁self.data.read().unwrap(),然后通过RefCellborrow方法获取不可变借用,最后返回缓存数据的克隆。
  • set方法获取写锁self.data.write().unwrap(),再通过RefCellborrow_mut方法获取可变借用,然后设置新的缓存数据。