MST

星途 面试题库

面试题:JavaScript的Node工作线程任务复杂分配

假设你有一个包含大量计算任务的Node.js应用,这些任务可以并行处理。请设计一个方案,合理利用工作线程来分配这些任务,同时要考虑到任务之间可能存在的数据依赖关系。阐述你的设计思路并给出关键代码片段。
14.3万 热度难度
编程语言JavaScript

知识考点

AI 面试

面试题答案

一键面试

设计思路

  1. 任务分解:将大的计算任务分解为多个小的子任务,每个子任务可以独立执行。
  2. 数据依赖分析:分析子任务之间的数据依赖关系,确定执行顺序。
  3. 工作线程管理:使用Node.js的worker_threads模块创建多个工作线程,将子任务分配给这些线程执行。
  4. 任务调度:根据数据依赖关系,调度子任务的执行顺序,确保有依赖的任务在其依赖的任务完成后再执行。
  5. 结果汇总:收集每个工作线程执行任务的结果,并汇总得到最终结果。

关键代码片段

  1. 主线程代码
const { Worker, isMainThread, parentPort, workerData } = require('worker_threads');
const taskList = [/* 包含所有子任务的数组 */];
const taskDependencies = new Map(); // 存储任务依赖关系,例如 { task1: [task2, task3] }
const taskResults = new Map(); // 存储任务执行结果

// 分析任务依赖关系
function analyzeDependencies() {
    // 逻辑实现,例如遍历任务列表,构建依赖关系Map
}

// 调度任务
function scheduleTasks() {
    const readyTasks = [];
    taskList.forEach(task => {
        if (!taskDependencies.has(task) || taskDependencies.get(task).every(dep => taskResults.has(dep))) {
            readyTasks.push(task);
        }
    });

    readyTasks.forEach(task => {
        const worker = new Worker(__dirname + '/worker.js', { workerData: task });
        worker.on('message', result => {
            taskResults.set(task, result);
            scheduleTasks();
        });
        worker.on('error', error => {
            console.error(`Worker error: ${error}`);
        });
        worker.on('exit', code => {
            if (code!== 0) {
                console.error(`Worker stopped with exit code ${code}`);
            }
        });
    });
}

if (isMainThread) {
    analyzeDependencies();
    scheduleTasks();
}
  1. 工作线程代码(worker.js)
const { isMainThread, parentPort, workerData } = require('worker_threads');

if (!isMainThread) {
    // 执行具体任务
    function executeTask(task) {
        // 任务执行逻辑,例如复杂计算
        return result;
    }

    const result = executeTask(workerData);
    parentPort.postMessage(result);
}