MST

星途 面试题库

面试题:优化JavaScript数组并发迭代以适应不同环境

在JavaScript的数组并发迭代场景下,不同的运行环境(如浏览器、Node.js)对资源的限制和性能表现有所不同。请设计一个通用的数组并发迭代解决方案,该方案可以根据运行环境动态调整并发数量以达到最佳性能。在实现过程中,需要考虑如何检测运行环境,以及如何根据不同环境的特点(如浏览器中的内存限制、Node.js中的CPU核心数等)来优化并发策略。请详细描述设计思路并给出核心代码实现。
30.2万 热度难度
编程语言JavaScript

知识考点

AI 面试

面试题答案

一键面试

设计思路

  1. 检测运行环境
    • 在JavaScript中,可以通过检测全局对象来判断运行环境。在浏览器中,全局对象是window,而在Node.js中,全局对象是global
    • 对于Node.js,还可以使用process对象获取更多环境相关信息,比如CPU核心数process.env.NUM_CPUS
  2. 动态调整并发数量
    • 浏览器环境:由于浏览器存在内存限制,并发数量不宜过高。可以根据经验设置一个初始并发数,比如10,然后可以通过性能测试动态调整。
    • Node.js环境:可以根据CPU核心数来设置并发数,通常可以设置为CPU核心数的倍数,例如2倍。这样可以充分利用多核CPU的性能。
  3. 数组并发迭代
    • 使用Promiseasync/await来管理并发操作。将数组分成多个子数组,每个子数组对应一个并发任务。

核心代码实现

function getEnvironment() {
    if (typeof window!== 'undefined') {
        return 'browser';
    } else if (typeof global!== 'undefined' && typeof process!== 'undefined') {
        return 'node';
    }
    return 'unknown';
}

async function asyncMapConcurrent(arr, callback, concurrency) {
    const results = [];
    const queue = [];
    const executeTask = async () => {
        const item = queue.shift();
        if (item!== undefined) {
            const index = item.index;
            const value = item.value;
            const result = await callback(value, index, arr);
            results[index] = result;
            await executeTask();
        }
    };
    for (let i = 0; i < arr.length; i++) {
        queue.push({ index: i, value: arr[i] });
        if (queue.length >= concurrency) {
            await executeTask();
        }
    }
    while (queue.length > 0) {
        await executeTask();
    }
    return results;
}

async function main() {
    const env = getEnvironment();
    let concurrency;
    if (env === 'browser') {
        concurrency = 10;
    } else if (env === 'node') {
        const numCPUs = require('os').cpus().length;
        concurrency = numCPUs * 2;
    } else {
        concurrency = 5;
    }
    const arr = [1, 2, 3, 4, 5];
    const result = await asyncMapConcurrent(arr, async (value) => {
        return value * 2;
    }, concurrency);
    console.log(result);
}

main();

在上述代码中:

  1. getEnvironment函数用于检测当前运行环境。
  2. asyncMapConcurrent函数实现了数组的并发迭代,它使用一个队列和递归的方式来控制并发任务的执行。
  3. main函数根据不同的运行环境设置并发数,并执行并发迭代操作。