面试题答案
一键面试设计思路
- 并发控制:使用一个队列来管理待处理的任务,并设置一个最大并发数,以避免内存溢出和CPU过度负载。
- 任务取消:为每个任务添加取消功能,通过
AbortController
实现。 - 资源管理:当任务取消时,释放其占用的资源(如关闭文件描述符等,由于题目未提及具体资源,这里仅做理论处理)。
核心代码实现
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
函数进行修改,以确保资源正确释放。