MST
星途 面试题库

面试题:Rust标准输入输出流的高性能与并发处理

你需要设计一个Rust程序,它从标准输入接收大量的文本数据块(每次输入大小不定),在接收到数据块后,需要对每个数据块进行以下操作:并行计算数据块中的单词数量、字符数量以及行数量,然后将这些统计信息(单词数、字符数、行数)输出到标准输出。要求使用Rust的并发特性来优化性能,并且处理好可能的资源竞争和错误情况。请详细描述你的设计思路,并给出核心代码实现。
29.2万 热度难度
编程语言Rust

知识考点

AI 面试

面试题答案

一键面试

设计思路

  1. 数据接收:使用std::io::stdin从标准输入读取数据块。由于每次输入大小不定,需要逐行读取或者按缓冲区读取。
  2. 并行计算:使用Rust的std::threadasync/await来实现并行计算。对于每个数据块,启动多个线程分别计算单词数量、字符数量和行数量。
  3. 资源竞争:为避免资源竞争,在多线程计算时,每个线程操作独立的数据副本。若使用async/await,可利用Mutex等同步原语来保护共享资源。
  4. 错误处理:在读取输入和计算过程中可能会出现错误,如输入格式错误等,需要使用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);
    }
}

在这段代码中:

  1. io::stdin().lock().lines()逐行读取标准输入数据。
  2. 使用Arc<Mutex<String>>来安全地在多线程间共享数据。
  3. 分别启动两个线程来计算单词数量和字符数量。
  4. 最后将计算结果输出到标准输出。

如果希望使用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语法异步计算单词数量和字符数量。