干爆前端!最新大厂面试真题及答案(第二期)

点击上方蓝字关注前端真好玩,从此前端进阶不再难

干爆前端是笔者新搞的一个仓库,一网打尽前端面试、学习路径、优秀好文、面试资料等各类内容,帮助大家一年内拿到期望的 offer!

其中一部分内容是「每日更新一道大厂原题」,笔者前段时间靠着人脉收集了一波目前最新各个大厂的面试题,绝不是大规模传播的那种,适合有跳槽计划的读者学习。

目前参与人数众多,笔者建了个打卡群,每天都有数十人参与打卡学习,群内学习氛围相当浓厚,如果你也想参与学习的话可以扫描二维码,备注打卡

这里是仓库地址:https://github.com/KieSun/fucking-frontend。目前内容包括大厂真题、十五万字面试资料及数百岗位的内推信息,内容还在持续更新,欢迎大家 star 关注。

公众号每周会整合真题及答案,以下是今天的内容:

第一题

页面上有三个按钮,分别为 A、B、C,点击各个按钮都会发送异步请求且互不影响,每次请求回来的数据都为按钮的名字。

请实现当用户依次点击 A、B、C、A、C、B 的时候,最终获取的数据为 ABCACB。

这道题目主要两个考点:

  1. 请求不能阻塞,但是输出可以阻塞。比如说 B 请求需要耗时 3 秒,其他请求耗时 1 秒,那么当用户点击 BAC 时,三个请求都应该发起,但是因为 B 请求回来的慢,所以得等着输出结果。

  2. 如何实现一个队列?

其实我们无需自己去构建一个队列,直接利用 promise.then 方法就能实现队列的效果了。

class Queue {
  promise = Promise.resolve();

  excute(promise) {
    this.promise = this.promise.then(() => promise);
    return this.promise;
  }
}

const queue = new Queue();

const delay = (params) => {
  const time = Math.floor(Math.random() * 5);
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve(params);
    }, time * 500);
  });
};

const handleClick = async (name) => {
  const res = await queue.excute(delay(name));
  console.log(res);
};

handleClick('A');
handleClick('B');
handleClick('C');
handleClick('A');
handleClick('C');
handleClick('B');

第二题

异步请求通过 Promise.all 处理,怎么让其中失败的所有请求重试。

Promise.all([A, B, C, D])
// 4 个请求完成后发现 AD 请求失败了,如果让 AD 请求重试

这个题目其实很简单,因为 Promise.all 中一个 promise 挂了就挂了,所以我们直接在接口上处理 catch 就行了。

看了些答案,结果是对的,但是处理方式是错误的。比如说在 resolve 中去判断是否要重试。一般我们业务中请求都是封装过的函数,出现错误肯定直接 reject 了,不可能 resolve 出来。

答案摘自 vandvassily

其他类似优秀答案:yancongwen

function request(name, count = 0) {
  return new Promise((resolve, reject) => {
    const isSuccess = Math.random() > 0.5;
    console.log(`接口${name}: ${isSuccess}`);
    setTimeout(() => {
      isSuccess > 0.5 ? resolve(name) : reject(name);
    }, Math.random() * 1000);
  }).catch((err) => {
    count++;

    if (count > 2) {
      return Promise.reject(`后端大爷${name}接口写的666`);
    }
    return request(name, count);
  });
}

let queue = [request('A'), request('B'), request('C'), request('D')];

Promise.all(queue)
  .then((arr) => {
    console.log(arr);
  })
  .catch((err) => {
    console.log(err);
  });

第三题

/**
 * @param input
 * @param size
 * @returns {Array}
 */
_.chunk(['a', 'b', 'c', 'd'], 2)
// => [['a', 'b'], ['c', 'd']]

_.chunk(['a', 'b', 'c', 'd'], 3)
// => [['a', 'b', 'c'], ['d']]

_.chunk(['a', 'b', 'c', 'd'], 5)
// => [['a', 'b', 'c', 'd']]

_.chunk(['a', 'b', 'c', 'd'], 0)
// => []

这道题目其实就是让大家实现一个 lodash 里的函数,这边我们需要注意的一个点是不能更改原数组,虽然题目没有提到,但是我们得想到这个。

笔者这里推荐几个答案,分别是不同的写法,难度从低到高吧。

首先是遍历的写法:

答案链接

function chunk(arr, num) {
  if (num === 0) return [];
  if (Array.isArray(arr) && typeof num === "number") {
    let result = [];
    let i = 0;
    while (i < arr.length) {
      result.push(arr.slice(i, i + num));
      i += num;
    }
    return result;
  } else {
    console.log("params type error");
  }
}

我们也可以使用 reduce 来解题:

答案链接

const chunk = (arr, len) => arr.reduce((pre, cur, index) => {
  if (index % len === 0) {
    pre.push([cur])
    return pre
  }
  const temp = pre[pre.length - 1]
  temp && temp.push(cur)
  return pre
}, [])

甚至直接优化到一行:

答案链接

function chunk(arr, size){
  return Array.from({length: (size = Number.parseInt(size)) ? Math.ceil(arr.length/size) : 0})
    .map((a,i) => arr.slice(i*size, (i+1)*size))
}

如果觉得不错,素质三连、或者点个「赞」、「在看」都是对笔者莫大的支持,谢谢各位大佬啦~

我的付费社区「前端怎么玩」

在这里你能获得些什么?

  • 我学习的路径,平时看到的好文章、想法、资料、新技术都会整理好分享出来,帮助你更快成长,开阔眼界,拓宽技术栈。

  • 你的疑问,工作上、技术、职业等等无限次提问,不方便暴露隐私还可以匿名提问,我能回答的肯定会聊聊我的想法。

  • 不定期的线上学习活动组织,打卡分享。

  • 一月一期的高质量分享及答疑,包括简历修改、模拟面试等。

  • 一个高质量的微信群。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值