面试题答案
一键面试1. 线程池和缓冲区机制优化思路
- 线程池:在高并发场景下,创建过多线程会带来线程创建、销毁开销以及资源竞争问题。使用线程池可以复用一定数量的线程,减少线程创建和销毁的开销,提高系统性能。
- 缓冲区机制:大量的控制台输出如果直接进行,会因为频繁的I/O操作而产生性能瓶颈。通过设置缓冲区,先将数据写入缓冲区,当缓冲区满或者达到一定条件时,再一次性将缓冲区的数据输出到控制台,这样可以减少I/O操作次数,提高输出性能。
2. 代码示例
use std::sync::{Arc, Mutex};
use std::thread;
use std::sync::mpsc::{channel, Sender};
use threadpool::ThreadPool;
// 定义缓冲区结构
struct ConsoleBuffer {
buffer: Vec<String>,
capacity: usize,
}
impl ConsoleBuffer {
fn new(capacity: usize) -> Self {
ConsoleBuffer {
buffer: Vec::with_capacity(capacity),
capacity,
}
}
fn push(&mut self, message: String) {
self.buffer.push(message);
if self.buffer.len() >= self.capacity {
self.flush();
}
}
fn flush(&mut self) {
for line in self.buffer.drain(..) {
println!("{}", line);
}
}
}
fn main() {
let buffer = Arc::new(Mutex::new(ConsoleBuffer::new(100)));
let (tx, rx): (Sender<String>, _) = channel();
// 创建线程池
let pool = ThreadPool::new(4);
// 启动一个线程用于处理缓冲区输出
let buffer_clone = buffer.clone();
thread::spawn(move || {
for message in rx {
let mut buffer = buffer_clone.lock().unwrap();
buffer.push(message);
}
buffer_clone.lock().unwrap().flush();
});
// 模拟高并发任务
for i in 0..1000 {
let tx = tx.clone();
pool.execute(move || {
let message = format!("Task {} is running", i);
tx.send(message).unwrap();
});
}
// 等待所有任务完成
drop(tx);
}
在上述代码中:
ConsoleBuffer
结构体用于管理缓冲区,push
方法将消息推送到缓冲区,并在缓冲区满时调用flush
方法将缓冲区内容输出到控制台。- 使用
threadpool
库创建了一个线程池,模拟高并发任务。 - 使用
std::sync::mpsc
模块中的通道(channel
)将任务产生的消息发送到处理缓冲区的线程。 - 处理缓冲区的线程不断从通道接收消息并写入缓冲区,最终在任务结束时确保缓冲区数据全部输出。