MST

星途 面试题库

面试题:JavaScript多维数组并发操作的性能优化与资源管理

假设存在一个非常大的四维数组(例如表示一个大型图像的像素数据,数组规模可能是1000x1000x3x4),有一个计算密集型的异步函数 `async function complexCalculation(pixel) { // 这里进行复杂计算,可能涉及大量的数学运算和异步I/O操作 return result; }`,需要对这个四维数组的每个元素并发执行这个函数。请设计一个高性能的并发操作方案,在保证计算结果正确的同时,要考虑如何优化性能(如控制并发数量以避免内存溢出和CPU过度负载),并且有效地管理资源(如合理处理异步任务的取消、释放占用的资源等),请详细描述设计思路并给出核心代码实现。
28.5万 热度难度
编程语言JavaScript

知识考点

AI 面试

面试题答案

一键面试

设计思路

  1. 并发控制:使用一个队列来管理待处理的任务,并设置一个最大并发数,以避免内存溢出和CPU过度负载。
  2. 任务取消:为每个任务添加取消功能,通过AbortController实现。
  3. 资源管理:当任务取消时,释放其占用的资源(如关闭文件描述符等,由于题目未提及具体资源,这里仅做理论处理)。

核心代码实现

const { AbortController } = require('node:abort-controller');

// 模拟复杂计算函数
async function complexCalculation(pixel, signal) {
    // 模拟大量数学运算和异步I/O操作
    await new Promise((resolve) => setTimeout(resolve, 100));
    if (signal.aborted) {
        throw new DOMException('The operation was aborted', 'AbortError');
    }
    return pixel * 2;
}

async function processArrayWithConcurrencyLimit(array, maxConcurrency) {
    const resultArray = Array.from(array, () => Array());
    const taskQueue = [];
    const activeTasks = new Set();
    const controllerMap = new Map();

    function enqueueTask(x, y, z, w) {
        const controller = new AbortController();
        const { signal } = controller;
        controllerMap.set([x, y, z, w], controller);
        const task = async () => {
            try {
                const pixel = array[x][y][z][w];
                const result = await complexCalculation(pixel, signal);
                resultArray[x][y][z][w] = result;
            } catch (error) {
                if (!(error instanceof DOMException && error.name === 'AbortError')) {
                    console.error('计算错误:', error);
                }
            } finally {
                activeTasks.delete(task);
                if (taskQueue.length > 0) {
                    const [nextX, nextY, nextZ, nextW] = taskQueue.shift();
                    enqueueTask(nextX, nextY, nextZ, nextW);
                }
            }
        };
        taskQueue.push([x, y, z, w]);
        if (activeTasks.size < maxConcurrency) {
            const [nextX, nextY, nextZ, nextW] = taskQueue.shift();
            activeTasks.add(task);
            task().catch(console.error);
        }
    }

    for (let x = 0; x < array.length; x++) {
        for (let y = 0; y < array[x].length; y++) {
            for (let z = 0; z < array[x][y].length; z++) {
                for (let w = 0; w < array[x][y][z].length; w++) {
                    enqueueTask(x, y, z, w);
                }
            }
        }
    }

    return new Promise((resolve) => {
        const interval = setInterval(() => {
            if (activeTasks.size === 0 && taskQueue.length === 0) {
                clearInterval(interval);
                resolve(resultArray);
            }
        }, 100);
    });
}

// 示例使用
const largeArray = Array.from({ length: 1000 }, () =>
    Array.from({ length: 1000 }, () =>
        Array.from({ length: 3 }, () =>
            Array.from({ length: 4 }, (_, i) => i + 1)
        )
    )
);

processArrayWithConcurrencyLimit(largeArray, 10).then((result) => {
    console.log('计算结果:', result);
});

// 取消某个任务示例
// const [x, y, z, w] = [100, 200, 1, 2];
// const controller = controllerMap.get([x, y, z, w]);
// controller?.abort();

此代码通过队列和Set来管理并发任务,通过AbortController实现任务取消功能。processArrayWithConcurrencyLimit函数接收数组和最大并发数,返回处理后的结果数组。在实际应用中,可能需要根据具体的资源管理需求(如文件I/O等)对complexCalculation函数进行修改,以确保资源正确释放。