某厂的后端预备笔试题-数组随机遍历和简单消息队列的实现

1.随机遍历数组。一个长度为 n 的数组,每次随机挑选一个元素,尽可能快的遍历到全部元素,最终返回一个新的数组。

思路

开始的思路是生成随机数字当作原数组的索引的下标,用一个map结构构存数组的索引,标记是否遍历过。 仔细想下若不改变原数组的话,索引下标会重复,即使用map结构判断了是否遍历过,效率也不高,显然不满足题目中的“尽可能快的”要求。

javascript代码:

const array = [1, 5, 2, 4, 3, 6];
const indexMap = {};
const newArray = [];
while(newArray.length<array.length){
  const index = Math.round(Math.random() * (array.length - 1));
    if(!indexMap[index] === true){
        newArray.push(array[index]);
    }else{
        continue;
    }
    indexMap[index] = true;
}

复制代码

于是就想到js中原生操作数组的方法splice(从原数组的某个位置删除指定个数的元素,且添加若干元素,返回删除元素的数组,且改变原数组),删除的元素不会重复。生成的随机数的大小只要不超过原数组的最大索引就好。

javascript代码:

const array = [1, 5, 2, 4, 3, 6];
const arrayNew = [];
while (array.length !== 0) {
  arrayNew.push(array.splice(Math.round(Math.random() * (array.length - 1)), 1)[0]);
}
console.log('array', array);
console.log('arrayNew', arrayNew);
复制代码

result:

2.消息队列实现。实现一个消息队列,满足如下功能

  1. 可以添加任务,任务包含任务数据,任务延迟触发的等待时间。
  2. 在任务到达触发时间点时,自动触发执行此任务。
  3. 队列中任务保持先进先出原则:假设 A 任务的触发等待时间为 XB 任务的触发等待时间为 YBA 之后被添加入队列,则 A 的前驱任务执行完成后等待时间 X 后,才执行 A,同理在 A 执行完成后,等待时间 Y,才执行 B

思路: setTimeout实现延时处理; array顺序遍历保证处理顺序; async function 和Promise 保证队列执行完成状态的检测判断; array中放函数声明,加()调用执行;

javascript代码

const mq = [];
const addTask = (message, delay) => {
  mq.push(() => new Promise((resolve) => {
    setTimeout(() => {
      console.log(message);
      resolve(true);
    }, delay);
  }));
};
addTask('preA', 500);
addTask('A', 300);
addTask('B', 100);
const run = async () => {
  for (const item of mq) {
    await item();
  }
};
run();
复制代码

result:

⚠️:

以上仅为笔者的答案,并不代表最佳答案,欢迎大家讨论指正!

以上仅使用javascript实现,欢迎大家补充其它语言的实现方案。

猜你喜欢

转载自juejin.im/post/5e0463d8e51d455820602fca