0
点赞
收藏
分享

微信扫一扫

抖音三面-HARD难度针对谁?


写在前面的话

这两年因为疫情以及种种原因吧,互联网的大环境明显不比前几年了,尤其是去年后半年到今年前半年,各个社区、群聊,猎头那边都充满了裁员、大厂HC锁定的消息。似乎以前外面一直都有坑,随时随地可以提桶跑路的大环境都没有了。有一份固定的工作,公司不裁员,车加的起油,房贷能还上,似乎都要感恩戴德了。

时间来到6、7月份,好像春风又吹拂了大地,市场好像回暖了。开始有猎头朋友不停的在Call介绍国内的一些独角兽,或者是海外的一些岗位,如亚马逊、虾皮等。

终究是架不住好友的多次拉扯,去面试了抖音某部门,为了避免尴尬就不说是那个具体部门了。

抖音三面-HARD难度针对谁?_滑动窗口

面试过程

一面、二面没啥特别的,大多都是前端程序员必备基础知识:

  1. HTTP2相关;
  2. 网络缓存(强缓存和协商缓存);
  3. EventLoop(浏览器和Node.js区别);
  4. 多端适配方案;
  5. 手写Promise;
  6. 手写EventEmitter;
  7. 小程序开发经验;

还有些其他的问题,也都是常见的,记不太清了。

顺带要点赞下线上面试系统,不用大老远的跑过去。甚是好!

三面:

三面整体感觉难度加深许多,深入的聊了些项目架构、主R视角、项目推动落地。

重点1:项目中做的性能优化策略以及收益(前后关键性指标对比,如TTL、LCP、FMP等)。

在这里要着重提醒各位,如果你做了性能优化,在做之前和做之后一定要确定参考性指标,前后数据的收集,非常重要!!!

重点2:社区开源项目、社区影响力

在这里再着重推荐一下,胡哥搞的零成本式路由权限解决方案的​​react-router-middleware-plus​​。

​​NPM地址​​

​​GitHub地址​​

欢迎大家​​Star​​​和​​PR​​,一起为开源社区做贡献吧!

重点3:宇宙条的经典特色 HARD难度的算法题: 求滑动窗口的最大值!!!​​LeetCode原题点这里​​

题目要求:

给定一个数组 ​​nums​​​ 和滑动窗口的大小 ​​k​​,请找出所有滑动窗口里的最大值。

这个提供大家一个套路面试官的攻略,让他逐步看到你解决问题的能力以及整个过程的思考。

这道HARD难度的问题,提供两个思路,由浅入深来看。

首先在看到这道题的时候,你可以直接快速的说出​​双层循环​​的方法,依次比较范围内的最大值,最终得出结果。 附上解题思路:

function maxSlidingWindow(nums: number[], k: number): number[] {
// 缓存数组的长度
const len = nums.length;
// 定义存储最大值的数组
const res: number[] = [];

// 临界点判定
if (len === 0) {
return res;
}

// 外层循环,控制起点位置,注意结束点索引的临界条件是len - k + 1
for (let i = 0; i < len - k + 1; i++) {
// 每次都初始化最大值
let max = -Infinity;

// 判断从当前位置开始的k个数中的最大值
for (let j = i; j < i + k; j++) {
if (nums[j] > max) {
max = nums[j]
}
}

// 每次将最大值放入数组中
res.push(max);

// 下次开启循环的时候,相当于从下一个新的起点开始了

抖音三面-HARD难度针对谁?_缓存_02

是可以得到结果,但是性能相当的不理想呀!

停顿一下,在等面试官内心稍微想嘲讽你的时候,你再说出来,这种方式的算法复杂度是,性能不理想,肯定不是我们想要的。提出第二种算法复杂度为的方案。

在上面的实现中,相对于每次起点的值,都执行了​​k​​次判断,是没有必要的。

双端队列实现

我们知道队列具有“先进先出”的特点,而双端队列呢,是支持在队头和队尾都支持元素进队、出队操作。

假定我们维护一个队列,在队列的首位一致记录当前​​k​​个元素的最大值;

如果新出现的值比队尾的值小,则进行进队操作;

如果新出现的值比当前队尾的值大,则从队尾开始依次进行出队操作,知道前一个值比当前值大;

每次向前走一步,则队头元素要进行移除操作。

附上解题思路:

function maxSlidingWindow(nums: number[], k: number): number[] {
// 缓存数组长度
const len = nums.length;

// 存储结果
const res: number[] = [];

// 设置队列,队列中存储索引,便于计算k范围
const queue = [];

// 遍历元素
for (let i = 0; i < len; i++) {
// 首先判断队尾元素与当前值nums[i]的比对
while (queue.length && nums[queue[queue.length - 1]] < nums[i]) {
// 进行出队操作
queue.pop();
}

// 将当前值放入,注意是索引
queue.push(i);

// 当队首元素索引与当前索引i的差值>=k时,需要将队首元素移除,说明这个范围已经过了k个元素了
if(queue.length && queue[0] <= i - k) {
// 队首元素移除
queue.shift();
}

// 什么时候开始取值呢,只要开始满足有k个数之后,就可以取值了
if (i >= k - 1) {
res.push(nums[queue[0]])
}
}

// 返回结果
return

抖音三面-HARD难度针对谁?_数组_05

对于数组​​nums​​​中的元素,都是经历了一次入队、一次出队操作。每次取滑动窗口中元素的最大值时,都是直接取的​​queue​​​的队首元素。实际的算法复杂度就是

此时此刻,你和面试官内心都是非常开心的。面试官心中感叹茫茫人海中我又遇到了一个好苗子!你内心就可以窃喜今年薪资是不是又有double的机会了。

最后

如果后面有合适的,可以更新的,也会写下来。

大家可以蹲个坑!

举报

相关推荐

0 条评论