面试题答案
一键面试状态管理
- 使用
Arc
和Mutex
Arc
(原子引用计数)用于在多个线程间共享数据,Mutex
(互斥锁)用于保护数据的安全访问。- 示例代码:
use std::sync::{Arc, Mutex};
use tokio::task;
#[tokio::main]
async fn main() {
let shared_state = Arc::new(Mutex::new(0));
let shared_state_clone = shared_state.clone();
let handle = task::spawn(async move {
let mut state = shared_state_clone.lock().unwrap();
*state += 1;
});
handle.await.unwrap();
let state = shared_state.lock().unwrap();
println!("Final state: {}", *state);
}
RefCell
与Rc
- 在单线程环境下,
RefCell
与Rc
组合可以提供内部可变性。Rc
用于引用计数,RefCell
允许在运行时检查借用规则。 - 示例代码:
- 在单线程环境下,
use std::cell::RefCell;
use std::rc::Rc;
fn main() {
let shared_state = Rc::new(RefCell::new(0));
let shared_state_clone = shared_state.clone();
let closure = || {
let mut state = shared_state_clone.borrow_mut();
*state += 1;
};
closure();
let state = shared_state.borrow();
println!("Final state: {}", *state);
}
资源回收
- 自动资源管理
- Rust 的所有权系统在任务结束时会自动回收资源。例如,当一个包含堆分配内存的结构体离开作用域时,其
Drop
实现会被调用以释放内存。 - 示例代码:
- Rust 的所有权系统在任务结束时会自动回收资源。例如,当一个包含堆分配内存的结构体离开作用域时,其
struct MyResource {
data: Vec<u8>,
}
impl Drop for MyResource {
fn drop(&mut self) {
println!("Dropping MyResource");
}
}
async fn my_task() {
let resource = MyResource { data: vec![1, 2, 3] };
// 任务结束时,resource 离开作用域,自动调用 Drop 方法回收资源
}
- 使用
Weak
引用Weak
引用可以用于解决循环引用导致的内存泄漏问题。它不会增加引用计数,当所有强引用(如Arc
)消失时,资源会被回收。- 示例代码:
use std::sync::{Arc, Weak};
struct Node {
data: i32,
next: Option<Arc<Node>>,
prev: Weak<Node>,
}
fn main() {
let node1 = Arc::new(Node {
data: 1,
next: None,
prev: Weak::new(),
});
let node2 = Arc::new(Node {
data: 2,
next: None,
prev: Arc::downgrade(&node1),
});
node1.next = Some(node2.clone());
// 这里 node1 和 node2 相互引用,但是通过 Weak 引用避免了循环引用导致的内存泄漏
}
在异步任务调度中,合理运用这些方法可以有效地进行状态管理并妥善处理资源回收问题,避免内存泄漏和其他资源相关错误。