记一道有趣的面试题

这两天面试,遇到一道有趣的手写题,其实一开始挺懵逼的,因为是网页写代码,也不好调试,到最后也就完成了大概,还有剩下的缓存任务 和当只有一个job的判断没完成就自动交卷了。

题目如下

实现一个Scheduler,并发限制2个任务运行,

js 复制代码
class Scheduler {

  constructor() {}

  add(task) {
   
  }
}

/* 测试代码,请勿修改 */
const timeout = (time) =>
  new Promise((resolve) => {
    setTimeout(resolve, time);
  });

const scheduler = new Scheduler();
const addTask = (time, order) => {
  scheduler.add(() => timeout(time)).then(() => console.log(order));
};

addTask(1000, '1');
addTask(500, '2');
addTask(300, '3');
addTask(400, '4');

// output: 2 3 1 4
// 一开始,1、2两个任务进入队列
// 500ms时,2完成,输出2,任务3进队
// 800ms时,3完成,输出3,任务4进队
// 1000ms时,1完成,输出1
// 1200ms时,4完成,输出4

参考答案

js 复制代码
class Scheduler {
  jobArray = [];
  runJobsArray = [];
  freshing = false;
  isFrshing = false;
  seenJobArray = [];

  constructor() {}

  runJobs() {
    if (this.runJobsArray.length < 2) {
      const currentJob = this.jobArray.shift();
      if (currentJob != null) {
        this.runJobsArray.push(currentJob);
      } else if (currentJob == null) {
        const j = this.runJobsArray[0];
        const senndJobObj = this.seenJobArray.find((s) => s.j === j);

        if (senndJobObj) {
          senndJobObj.promise.then((res) => {
            j.resolve(res);
          });
        }
      }
    }

    if (this.runJobsArray.length === 2 && !this.isFrshing) {
      this.isFrshing = true;

      Promise.race(
        this.runJobsArray.map((j) => {
          const senndJobObj = this.seenJobArray.find((s) => s.j === j);

          if (senndJobObj) {
            return senndJobObj.promise.then((res) => {
              return {
                res,
                resolve: j.resolve,
              };
            });
          }

          const promise = j.task();

          if (senndJobObj == null) {
            this.seenJobArray.push({ j, promise });
          }

          return promise.then((res) => {
            return {
              res,
              resolve: j.resolve,
            };
          });
        })
      ).then((res) => {
        res.resolve(res);
        this.isFrshing = false;
        this.runJobsArray = this.runJobsArray.filter(
          (r) => r.resolve !== res.resolve
        );

        this.runJobs();
      });
    }
  }

  add(task) {
    let resolveValue;
    const promise = new Promise((resolve) => {
      resolveValue = resolve;
    });

    this.jobArray.push({ task, resolve: resolveValue });
    this.runJobs();

    return promise;
  }
}

/* 测试代码,请勿修改 */
const timeout = (time) =>
  new Promise((resolve) => {
    // console.log('执行了', time);
    setTimeout(resolve, time);
  });

const scheduler = new Scheduler();
const addTask = (time, order) => {
  scheduler.add(() => timeout(time)).then(() => console.log(order));
};

addTask(1000, '1');
addTask(500, '2');
addTask(300, '3');
addTask(400, '4');

// 输出
// output: 2 3 1 4
// 一开始,1、2两个任务进入队列
// 500ms时,2完成,输出2,任务3进队
// 800ms时,3完成,输出3,任务4进队
// 1000ms时,1完成,输出1
// 1200ms时,4完成,输出4
相关推荐
孟陬17 分钟前
Foobar 技术周刊#159:当看不懂代码时,如何高效排障调试。脏页陷阱:一条只读查询,写入数 TB 数据。推测解码:大模型加速利器
前端·人工智能·后端
Zhao-Jichao26 分钟前
AI Prompting for Everyone 课程笔记 - P17 图像生成 Imaging Generation
前端
Highcharts.js1 小时前
智能数据分析组件Orbit 正式发布与快速上手体验教程
前端·人工智能·信息可视化·数据分析系统·highcharts·orbit·智能可视化
Dream-Y.ocean1 小时前
鸿蒙PC平台星图遥感适配实战:基于 Electron 壳方案的纯 JavaScript 遥感图像处理引擎开发
javascript·electron·harmonyos
螺丝钉tina2 小时前
[Playwright ][16]Playwright + TypeScript API 自动化测试实战:API测试
前端·javascript·typescript
小天源2 小时前
智叟云集系统 · 架构与职责分层
服务器·前端·数据库
Highcharts.js4 小时前
React 中原生支持使用 JSX 组件配置自定义表格 Highcharts Grid
前端·javascript·react.js·前端框架·jsx·highcharts·自定义表格
Java后端的Ai之路4 小时前
【AIAgent开发】-Agent工具封装成CLI(纯干货!!!)
java·javascript·人工智能·agent·cli
薛定谔的猫-菜鸟程序员4 小时前
Electron开发超详细教程(从入门到放弃)
前端·javascript·electron
最强小杰5 小时前
DeepSeek V4 Flash + Codex CLI 接入教程:原生 Responses API 适配,从配置到跑通收藏这篇就够了(2026)
java·前端·python·ai