面试题答案
一键面试设计思路
- 数据结构:基于
std::collections::HashMap
作为内部存储结构。 - 并发原语:
- 使用
Mutex
或RwLock
实现对内部HashMap
的保护。Mutex
提供独占访问,适用于读写操作都需要严格同步的场景;RwLock
则区分读锁和写锁,允许多个读操作同时进行,但写操作需要独占锁,适用于读多写少的场景。 - 对于更细粒度的控制,可以使用
parking_lot::Mutex
或parking_lot::RwLock
,它们比标准库中的Mutex
和RwLock
性能更好。 - 考虑使用
Arc
(原子引用计数)来在多个线程间共享ConcurrentHashMap
实例,因为Arc
允许在多个线程间安全地共享数据。
- 使用
- 数据一致性和线程安全:
- 通过锁机制确保在同一时间只有一个线程能修改
HashMap
,从而保证数据一致性。 - 对于读操作,若使用
RwLock
,多个线程可同时读取,提高并发性能。若使用Mutex
,读操作也会被串行化,但能保证简单直接的线程安全。
- 通过锁机制确保在同一时间只有一个线程能修改
关键代码片段
use std::collections::HashMap;
use std::sync::{Arc, RwLock};
// 自定义的ConcurrentHashMap
pub struct ConcurrentHashMap<K, V> {
inner: Arc<RwLock<HashMap<K, V>>>,
}
impl<K, V> ConcurrentHashMap<K, V> {
pub fn new() -> Self {
ConcurrentHashMap {
inner: Arc::new(RwLock::new(HashMap::new())),
}
}
// 插入键值对
pub fn insert(&self, key: K, value: V)
where
K: std::hash::Hash + Eq,
{
let mut map = self.inner.write().unwrap();
map.insert(key, value);
}
// 获取值
pub fn get(&self, key: &K) -> Option<&V>
where
K: std::hash::Hash + Eq,
{
let map = self.inner.read().unwrap();
map.get(key)
}
}
在上述代码中:
ConcurrentHashMap
结构体包含一个被Arc<RwLock<HashMap<K, V>>>
包裹的内部HashMap
。Arc
用于线程间共享,RwLock
提供读写锁机制。insert
方法获取写锁并插入键值对。get
方法获取读锁并获取对应的值。