面试题答案
一键面试设计思路
- 数据接收:使用
std::io::stdin
从标准输入读取数据块。由于每次输入大小不定,需要逐行读取或者按缓冲区读取。 - 并行计算:使用Rust的
std::thread
或async
/await
来实现并行计算。对于每个数据块,启动多个线程分别计算单词数量、字符数量和行数量。 - 资源竞争:为避免资源竞争,在多线程计算时,每个线程操作独立的数据副本。若使用
async
/await
,可利用Mutex
等同步原语来保护共享资源。 - 错误处理:在读取输入和计算过程中可能会出现错误,如输入格式错误等,需要使用
Result
类型进行错误处理。
核心代码实现
use std::io::{self, BufRead};
use std::sync::{Arc, Mutex};
use std::thread;
fn main() {
let stdin = io::stdin();
let lines = stdin.lock().lines();
for line in lines {
let line = line.expect("Failed to read line");
let data = Arc::new(Mutex::new(line));
let word_count_thread = thread::spawn({
let data = data.clone();
move || {
let data = data.lock().unwrap();
data.split_whitespace().count()
}
});
let char_count_thread = thread::spawn({
let data = data.clone();
move || {
let data = data.lock().unwrap();
data.chars().count()
}
});
let line_count = 1;
let word_count = word_count_thread.join().expect("Failed to join word count thread");
let char_count = char_count_thread.join().expect("Failed to join char count thread");
println!("Words: {}, Chars: {}, Lines: {}", word_count, char_count, line_count);
}
}
在这段代码中:
io::stdin().lock().lines()
逐行读取标准输入数据。- 使用
Arc<Mutex<String>>
来安全地在多线程间共享数据。 - 分别启动两个线程来计算单词数量和字符数量。
- 最后将计算结果输出到标准输出。
如果希望使用async
/await
实现:
use std::io::{self, BufRead};
use tokio::sync::Mutex;
#[tokio::main]
async fn main() {
let stdin = io::stdin();
let lines = stdin.lock().lines();
for line in lines {
let line = line.expect("Failed to read line");
let data = Mutex::new(line);
let word_count_future = async {
let data = data.lock().await;
data.split_whitespace().count()
};
let char_count_future = async {
let data = data.lock().await;
data.chars().count()
};
let line_count = 1;
let word_count = word_count_future.await;
let char_count = char_count_future.await;
println!("Words: {}, Chars: {}, Lines: {}", word_count, char_count, line_count);
}
}
这段async
代码使用tokio::sync::Mutex
来保护共享数据,通过async
/await
语法异步计算单词数量和字符数量。