面试题答案
一键面试设计思路
- 检测运行环境:
- 在JavaScript中,可以通过检测全局对象来判断运行环境。在浏览器中,全局对象是
window
,而在Node.js中,全局对象是global
。 - 对于Node.js,还可以使用
process
对象获取更多环境相关信息,比如CPU核心数process.env.NUM_CPUS
。
- 在JavaScript中,可以通过检测全局对象来判断运行环境。在浏览器中,全局对象是
- 动态调整并发数量:
- 浏览器环境:由于浏览器存在内存限制,并发数量不宜过高。可以根据经验设置一个初始并发数,比如10,然后可以通过性能测试动态调整。
- Node.js环境:可以根据CPU核心数来设置并发数,通常可以设置为CPU核心数的倍数,例如2倍。这样可以充分利用多核CPU的性能。
- 数组并发迭代:
- 使用
Promise
和async/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();
在上述代码中:
getEnvironment
函数用于检测当前运行环境。asyncMapConcurrent
函数实现了数组的并发迭代,它使用一个队列和递归的方式来控制并发任务的执行。main
函数根据不同的运行环境设置并发数,并执行并发迭代操作。