两年经验字节前端面经(可能是最简单的了)

13,966 阅读13分钟

两年之期已到,参见龙王。最近面了下字节,面之前看了好多掘金大佬的优秀文章,面完来反馈一下,虽然我面的内容真的是太简单了,可能是个假的,参考意义不大。

背景

我是18年毕业的,之前在一家出口电商公司。当年刚来的时候就打算两年后出来看看,虽然都说疫情大环境不好,我还是毅然决然的裸辞了。

一是履行当年之约(有内味儿了),二是在上家公司感觉没有什么上升空间了,疫情原因又出了各种事情。

7月16号离职,在家刷刷题,打打游戏。30号字节的hr加我微信,了解了一下,我说等我整理一下简历吧,8月5号给了简历,当天评估过了约了24号面试。

说一下为什么选24号。一是看了看掘金上的面经,感觉自己好菜,留一下准备时间,字节可以约30天内,我想了下也不打算太晚,17天总够了吧。二是因为好久没面试了,中间打算找家公司找找面试的感觉,结果后来面试时候还是紧张得不行。

下面从面经和面试准备两方面说。

面经

一面 50min

之前主要技术栈是Vue,后面有个项目是Reack + Mobx写的。面试官让自我介绍后就先从框架开始:

  1. 谈谈Vue和React的区别?
  2. Mobx的object和map有什么区别?底层实现?(这个没了解
  3. Hooks用过吗?(说了用过,然后就往下走了
  4. Vue如何实现双向绑定的?
  5. defineProperty有什么缺点?为什么用Proxy,对Proxy了解多少?
  6. 编程题 实现一个发布订阅模式 (给出框架,让具体实现
  7. Websocket怎么建立连接的?
  8. 对BFF有什么理解?Node为什么支持高并发?多线程除了上下文切换还有什么影响性能?
  9. 说说怎么通过阅读源码处理react-sticky的占位元素不能同步更新的问题
  10. 算法题 数组中第K大元素 (快排,我先说思路然后问了下时间复杂度,然后写
  11. 编程题 手动控制并发请求fetchWithLimit
  12. 有什么问题问我?

能记住的就这些了,除了编程算法其他基本从简历上问的,参考意义不大。

快排当时写的有点问题,面试管说你可以不用原地排序,我还跟面试官解释了一下,后面发现其实写错了,但是当时的用例是跑对了的。。。

fetchWithLimit写了个Promise.all的,面试官说不是最快的实现,因为时间关系就不写了,让我等五分钟下一轮

二面 50min

  1. 编程题 手动控制并发请求fetchWithLimit 尽量快的实现
  2. 算法题 数组去重,es5实现,区分数字和字符串
  3. 算法题 判断单向链表是否有环
  4. 谈谈IM项目有什么难点?
  5. 富文本为什么不用框架?
  6. 怎么获取粘贴事件?怎么判断是粘贴了图片?
  7. 怎么做图片压缩的?
  8. 为什么封装了Websocket?心跳是怎么做的?
  9. Koa和Express有什么区别?
  10. 模块化有了解吗,谈谈CommenJS和ES6的module?
  11. 谈谈你的开源项目,为什么做?
  12. 除了这些还有什么想说的,其他方向的有没有研究?
  13. Vue源码有看过吗?
  14. 谈谈http1.0 http1.1 http2.0 http3?知道多少说多少
  15. 说说缓存,怎么禁用强缓存?
  16. 还有什么想说的?
  17. 有什么问题问我?

二面上来做三道题,编程题跟一面一样,不过换了种说法,我一开始窃喜,直接一把梭就把一面的写出来了,他看了看说这不是最快的,能不能写个最快的,并解释了一下,我说我试试。结果写着写着卡主了,当时没想到怎么去循环执行(递归),问了下思路就先过了。接下来两道easy,然后就问项目了。

二面面试官给了很大的自由度,一直让我自己发挥,比如:讲讲这个项目,有什么可以说的,除了上面聊的还有什么想说的之类的。结果每次我大脑都一片空白不知道怎么说,然后他就笑笑,“算了,我来问吧。”

最后我问对我有什么评价或建议,说的是看得出来我是一个务实的人,但是可能深度上还要加强一下。比较中肯。晚上hr约了26号三面。

三面 40min

前两面这么简单搞的我很慌,感觉是被放弃了。但是还是要准备一下,感觉主要是编程和算法,所以去牛客上搜集了一下面经里的算法编程题刷了刷,后面会分享下题目。

三面是下午五点,面试官稍显严肃,搞的我也紧张,结果大部分时间聊的都是非技术的,技术上就这两个:

  1. 返回数组中和等于给定数的两数下标?
  2. https中间被篡改了怎么识别?

leetcode第一题。。很快写完了,问了下时间复杂度,然后又说三数之和呢,复杂度是多少,怎么做?说一下思路就可。https中间被篡改了怎么识别,这个不知道,先说了下先握手,然后后面的数据是对称加密的。这还能改?然后说不解密,就是破坏。这个就直说了没了解过。其实可以想一下如果自己遇到怎么处理。

非技术问题就是从各方面看你是个什么样的人,能不能胜任字节的工作,以后的打算等等。其中我说了下二面面试官的评价,他说深度这个也要看公司的项目的。以后的打算我把最近思考的说了下,后面他问“你是个有毅力的人吗,很多人说到做不到”,我说更多的是思想上的改变吧,感觉自己这两年啥也没干,天天打游戏,以前可能为了面试而去看一些东西,现在可能更多的是一种职业的态度。

其他的就不说了,反正这段时间感觉自己真的好菜,看校招生的面经都比我强好多,那我的优势在哪?可能只有积累的一点项目经验了吧。。

最后让我等20分钟,下一轮。

HR面 40min

没到20分钟我就问了下约面的HR,说过了,等会HR面,用Zoom。HR也会问好多好多。三到五个工作日出结果。

面试准备

数据结构和算法

我之前没刷过算法,提离职后开始准备的,推荐labuladong的算法小抄,讲各种类型题目的解题框架,任何事情都有方法论,掌握方法刷题很快的。我没全部看完,看了一部分,动规,回溯,滑动窗口,背包,股票等等,也就是必读系列看完差不多了。一开始看的比较慢,不过慢慢就从看到算法题一脸懵逼到看到算法题先想是什么问题了。

数据结构推荐极客时间《数据结构与算法之美》(我的链接购买会有返现),讲的生动形象,通俗易懂,结合实际应用,让我明白了很多之前不明白的事情。

直接开刷的话我这里列了下问到的题目和搜集的牛客字节面经的题目,大部分easy,个别hard,也可以看到很多剑指Offer的,有时间的话推荐把剑指Offer刷完(我只刷了37道)。到三面前我一共刷了123道 - 简单 58 中等 51 困难 14。结果面试问了这么简单的。不过也感受到算法其实挺有意思的,后面打算每日一题坚持做一做。

时间复杂度也了解一下,面试问了我好几次复杂度多少。

字符串/数组

链表

栈/队列

二叉树

动态规划

回溯

之前一位校招大佬的面经里的, 刷了点题看这个题就有思路了,之前也碰到过dp[n]表示以第n位为最后一个值的区间这种题目,不知道我这么做对不对:

/**
 * 给定一个正整数数列a, 对于其每个区间, 我们都可以计算一个X值;
 * X值的定义如下: 对于任意区间, 其X值等于区间内最小的那个数乘上区间内所有数和;
 * 现在需要你找出数列a的所有区间中, X值最大的那个区间;
 * 如数列a为: 3 1 6 4 5 2; 则X值最大的区间为6, 4, 5, X = 4 * (6+4+5) = 60;
 *
 * 作者:甘先森
 * 链接:https://juejin.cn/post/6844904088337907720
 * 来源:掘金
 * 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
 */

function getMaxX (array) {
  let n = array.length
  if (n === 0) return 0
  let min = [array[0]]
  let dp = [array[0] * array[0]]
  let max = dp[0]
  for (let i = 1; i < n; i++) {
    let val = array[i]
    let preMin = min[i - 1]
    min[i] = Math.min(preMin, val)
    let one = dp[i - 1] * min[i] / preMin + val * min[i]
    let two = val * val
    if (one > two) {
      dp[i] = one
    } else {
      dp[i] = two
      min[i] = val
    }
    max = Math.max(max, dp[i])
  }
  return max
}

console.log(getMaxX([3,1,6,4,5,2])) // 60

编程题

这篇文章不错,「一劳永逸」送你21道高频JavaScript手写面试题 。一定要自己写一遍,上面也不是一点问题都没有,也不一定就一种实现方法,面试可能会问你有没有其他方法,比如节流,重点是思路。我面试问的fetchWithLimit就类似里面的实现一个同时允许任务数量最大为n的函数

除此之外,比如手写Promise,浮点数运算,大数相乘等也可以看看。

再分享看到一个笔试题:头条前端笔试题 - 实现一个带并发限制的promise异步调度器,不过这老哥的答案是有问题的,题目都改了。

/** 
 * JS实现一个带并发控制的异步调度器,保证同时运动的任务最多有两个,完善下面代码
 */
class Scheduler {
  add (promiseCreator) { ... }
  //...
}

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)

我的实现:

class Scheduler {

  constructor (limit = 2) {
    this.limit = limit
    this.concurrent = 0
    this.stack = []
  }

  add (promiseCreator) {
    if (this.concurrent < this.limit) {
      this.concurrent++
      return promiseCreator().then(() => {
        this.concurrent--
        this.next()
      })
    } else {
      let resolve
      let p = new Promise(r => {
        resolve = r
      })
      this.stack.push(() => {
        promiseCreator().then(() => {
          resolve()
          this.concurrent--
          this.next()
        })
      })
      return p
    }
  }

  next () {
    if (this.stack.length > 0 && this.concurrent < this.limit) {
      let p = this.stack.shift()
      this.concurrent++
      p()
    }
  }
}

计算机基础,前端基础等等

这个就不说了,掘金一搜一大把。这次准备我自己整理了一波,挺多的,后面可能会分模块整理一下。

好文

也不要“尽信书”,比如这篇DOM, CSS, JS的阻塞,解析渲染顺序

红框内的有问题,导致我看懵了,说好的CSS不会阻塞DOM解析呢?最后自己写个Demo发现控制台打印是在前面的。

总结

这次面试包括准备面试期间给我的几点感受:

  1. 我太菜了
  2. 算法挺有意思的
  3. 少玩游戏多学习

最后,许愿offer~

(mdnice的全栈蓝主题超出字数限制了怎么解?