面试题答案
一键面试设计思路
- 使用
Arc
和Mutex
:Arc
用于在多个线程间共享资源,Mutex
用于保护共享资源,确保同一时间只有一个线程能访问和修改资源。 - 跨网络节点通信: 可以使用如
tokio
等异步库来处理网络通信,每个网络节点作为一个独立的线程或异步任务。
资源同步机制
- 锁机制: 通过
Mutex
的lock
方法获取锁,对共享资源进行操作,操作完成后释放锁。 - 网络同步: 节点间通过消息传递机制,如基于
TCP
或UDP
协议,同步资源状态。例如,一个节点修改了资源后,通过网络消息通知其他节点更新其本地副本。
处理网络故障
- 重试机制: 当网络请求失败时,使用重试策略,如指数退避算法,在一定次数内尝试重新连接和同步。
- 心跳检测: 节点间定期发送心跳消息,若某个节点长时间未收到心跳,标记该节点可能故障,并从集群中移除或尝试重新连接。
处理死锁
- 锁顺序: 确保所有线程以相同顺序获取锁,避免循环依赖。
- 超时机制: 使用
try_lock
方法并设置超时,若在超时时间内未能获取锁,放弃当前操作并释放已获取的锁,防止线程无限期等待。
关键代码片段
use std::sync::{Arc, Mutex};
use std::thread;
// 共享资源结构体
struct SharedResource {
data: i32,
}
fn main() {
// 使用Arc和Mutex包装共享资源
let shared_resource = Arc::new(Mutex::new(SharedResource { data: 0 }));
let mut handles = vec![];
for _ in 0..10 {
let resource_clone = shared_resource.clone();
let handle = thread::spawn(move || {
let mut resource = resource_clone.lock().unwrap();
resource.data += 1;
println!("Thread modified data to: {}", resource.data);
});
handles.push(handle);
}
for handle in handles {
handle.join().unwrap();
}
}
在实际跨网络场景中,结合异步网络库如tokio
的示例代码如下:
use std::sync::{Arc, Mutex};
use tokio::net::TcpStream;
use tokio::io::{AsyncReadExt, AsyncWriteExt};
// 共享资源结构体
struct SharedResource {
data: i32,
}
async fn handle_connection(mut stream: TcpStream, shared_resource: Arc<Mutex<SharedResource>>) {
let mut buffer = [0; 1024];
loop {
let n = stream.read(&mut buffer).await.unwrap();
if n == 0 {
break;
}
let mut resource = shared_resource.lock().unwrap();
// 假设接收到的数据用于更新资源
resource.data += 1;
stream.write(&resource.data.to_be_bytes()).await.unwrap();
}
}
#[tokio::main]
async fn main() {
let shared_resource = Arc::new(Mutex::new(SharedResource { data: 0 }));
let listener = TcpListener::bind("127.0.0.1:8080").await.unwrap();
loop {
let (stream, _) = listener.accept().await.unwrap();
let shared_resource_clone = shared_resource.clone();
tokio::spawn(handle_connection(stream, shared_resource_clone));
}
}