The front end of the junior college, three rounds of interviews, and finally missed Ali

For some reason, I have been looking for a job recently, coupled with the general environment of the cold winter of the Internet, from March to June, there has been no suitable opportunity

Let me talk about the background first, the current three and a half years of experience, base in Hangzhou, college degree + self-examination undergraduate

Just a few days ago, Boss received a delivery invitation from a certain team in Ali (the specific department will not be disclosed). Because of academic qualifications, basically the resumes of major factories will not pass the preliminary screening, but they still hold the broken jar and smash it. The mentality of submitting it to the other party, unexpectedly the resume evaluation passed, probably because there are two 开源项目and one 协同文档extra points.

Entering the interview link, first of all, there are two written test questions, which can be regarded as the pre-interview:

The first question is an algorithm question:

An array structure data is provided, and a querymethod return a new array. The query method has 过滤, 排序, 分组and other operations inside, and supports chain calls. Call the final executemethod to return the result:

const result = query(list)
  .where(item => item.age > 18)
  .sortBy('id')
  .groupBy('name')
  .execute();

console.log(result);

The specific implementation will not be posted here. The native array filtermethod , and the native array sortmethod is used for sorting. Grouping needs to be written by hand, similar to lodash/groupBythe method .

The implementation of filtering and sorting is relatively smooth. When implementing the grouping method, it is not very smooth. I have forgotten the idea, but I finally wrote it out. Regarding the chain call, the core thisis

The second question is a scene question:

It is required to use vue or react to implement a countdown ticket grabbing component. When the page is loaded, the countdown starts from 10s. After the countdown is over, click the button to request the interface to grab coupons, and update the copywriting and other functions. Because I am more familiar with react, I chose react here.

The knowledge points setTimeoutinvolved the encapsulation, 异步请求processing, investigation of 状态更新, CSS基本功etc. in the hook...

具体实现这里也不贴了,写了一堆自定义 hook,因为平时也在参与 ahooks 的维护工作,ahooks 源码背的滚瓜烂熟,所以直接搬过来了,这道题整体感觉没啥难度,算是比较顺利的。

笔试题整个过程中唯一不顺利的是在线编辑器没有类似 vscode 这样的 自动补全 功能,不管是变量还是保留字,很多单词想不起来怎么拼写,就很尴尬,英文太差是硬伤 :(

笔试过程最后中出现了一点小插曲,因为笔试有时间限制,需要在规定的时间内完成,但是倒计时还没结束,不知道为什么就自动交卷了,不过那个时候已经写的差不多了,功能全部实现了,还剩下卡片的样式没完成,css 还需要完善一下,于是就在 Boss 上跟对方解释了一下,说明了情况。

过了几分钟,对面直接回复笔试过了,然后约了面试。

一面:

  • 自我介绍

    这里大概说了两分钟,介绍了过往工作经历,做过的业务以及技术栈。

  • 七层网络模型、和 DNS 啥的

    计网这方面属于知识盲区了,听到这个问题两眼一黑,思索了一会儿,直接说回答不上来。

  • 然后问了一些 host 相关的东西

    • 很遗憾也没回答上来,尴尬。对方问我是不是计算机专业的,我坦诚的告诉对方是建筑工程。
  • React 代码层的优化可以说一下么?

    • 大概说了 class 组件和 function 组件两种情况,核心是通过减少渲染次数达到优化目的,具体的优化手段有 PureComponentshouldComponentUpdateReact.memoReact.useMemoReact.useCallbackReact.useRef 等等。
  • 说一下 useMemouseCallback 有什么区别

    • 很基础的问题,这里就不展开说了。
  • 说一下 useEffectuseLayoutEffect 有什么区别

    • 很基础的问题,这里就不展开说了。
  • 问了一下 useEffect 对应在 class 中都生命周期怎么写?

    • 很基础的问题,这里就不展开说了。
  • 如果在 if 里面写 useEffect 会有什么表现?

    • 开始没听清楚,误解对方的意思了,以为他说的是在 useEffect 里面写 if 语句,所以胡扯了一堆,后面对方纠正了一下,我才意识到对方在问什么,然后回答了在条件语句里面写 useEffect 控制台会出现报错,因为 hook 的规则就是不能在条件语句或者循环语句里面写,这点在 react 官方文档里面也有提到。
  • 说一下 React 的 Fiber 架构是什么

    • 这里说了一下 Fiber 本质上就是一个对象,是 React 16.8 出现的东西,主要有三层含义:

      1. 作为架构来说,在旧的架构中,Reconciler(协调器)采用递归的方式执行,无法中断,节点数据保存在递归的调用栈中,被称为 Stack Reconciler,stack 就是调用栈;在新的架构中,Reconciler(协调器)是基于 fiber 实现的,节点数据保存在 fiber 中,所以被称为 fiber Reconciler。

      2. 作为静态数据结构来说,每个 fiber 对应一个组件,保存了这个组件的类型对应的 dom 节点信息,这个时候,fiber 节点就是我们所说的虚拟 DOM。

      3. 作为动态工作单元来说,fiber 节点保存了该节点需要更新的状态,以及需要执行的副作用。

      (这里可以参考卡颂老师的《自顶向下学 React 源码》课程)

  • 前面提到,在 if 语句里面写 hook 会报错,你可以用 fiber 架构来解释一下吗?

    • 这里说了一下,因为 fiber 是一个对象,多个 fiber 之间是用链表连接起来的,有一个固定的顺序…… 其实后面还有一些没说完,然后对方听到这里直接打断了,告诉我 OK,这个问题直接过了。
  • 个人方面有什么规划吗?

    • 主要有两个方面,一个是计算机基础需要补补,前面也提到,我不是科班毕业的,计算机底层这方面比起其他人还是比较欠缺的,尤其是计网,另一方面就是英文水平有待提高,也会在将来持续学习。
  • 对未来的技术上有什么规划呢?

    • 主要从业务转型工程化,比如做一些工具链什么的,构建、打包、部署、监控几个大的方向,node 相关的,这些都是我感兴趣的方向,未来都可以去探索,当然了现在也慢慢的在做这些事情,这里顺便提了一嘴,antd 的 script 文件夹里面的文件是我迁移到 esm + ts 的,其中一些逻辑也有重构过,比如收集 css token、生成 contributors 列表、预发布前的一些检查等等…… 所以对 node 这块也有一些了解。
  • 能不能从技术的角度讲一下你工作中负责业务的复杂度?

    • 因为前两份工作中做的是传统的 B 端项目和 C 端项目,并没有什么可以深挖的技术难点,所以这里只说了第三份工作负责的项目,这是一个协同文档,既不算 B 端,也不算 C 端,这是一款企业级的多人协作数据平台,竞品有腾讯文档、飞书文档、语雀、WPS、维卡表格等等。

      协同文档在前端的难点主要有两个方面:

      1. 实时协同编辑的处理:当两个人同时进入一个单元格编辑内容,如果保证两个人看到的视图是同步的?那么这个时候就要提到冲突处理了,冲突处理的解决方案其实已经相对成熟,包括:

        • 编辑锁:当有人在编辑某个文档时,系统会将这个单元格锁定,避免其他人同时编辑,这种方法实现方式最简单,但也会直接影响用户体验。

        • diff-patch:基于 Git 等版本管理类似的思想,对内容进行差异对比、合并等操作,也可以像 Git 那样,在冲突出现时交给用户处理。

        • 最终一致性实现:包括 Operational Transformation(OT)、 Conflict-free replicated data type(CRDT,称为无冲突可复制数据类型)。

      2. 性能问题

        • 众所周知,互联网一线大厂的协同文档工具都是基于 canvas 实现,并且有一套自己的 canvas 渲染引擎,但是我们没有,毕竟团队规模没法跟大厂比,这个项目前端就 2 个人,所以只能用 dom 堆起来(另一个同事已经跑路,现在就剩下我一个人了)。这导致页面卡顿问题非常严重,即使做了虚拟滚动,但是也没有达到很好的优化效果。老板的要求是做到十万量级的数据,但是实际上几千行就非常卡了,根本原因是数据量太大(相当于一张很大的 Excel 表格,里面的每一个单元格都是一个富文本编辑器),渲染任务多,导致内存开销太大。目前没有很好的解决方案,如果需要彻底解决性能问题,那么就需要考虑用 canvas 重写,但是这个基本上不太现实。

        • 因为卡顿的问题,暴露出来另一个问题,状态更新时,视图同步缓慢,所以这时候不得不提到另一个优化策略:乐观更新。乐观更新的思想是,当用户进行交互的时候,先更新视图,然后再向服务端发送请求,如果请求成功,那么什么都不用管,如果请求失败,那么就回滚视图。这样做的好处是,用户体验会好很多,在一些强交互的场景,不会阻塞用户操作,比如抖音的点赞就是这样做的。但是也会带来一些问题,比如:如果用户在编辑某个单元格时,另一个用户也在编辑这个单元格,那么就会出现冲突,这个时候就需要用到前面提到的冲突处理方案了。

  • 可以讲一下你在工作中技术上的建设吗?

    • 这里讲了一下对 hooks 仓库的建设,封装了 100 多个功能 hook业务 hook,把不变的部分隐藏起来,把变化的部分暴露出去,在业务中无脑传参即可,让业务开发更加简单,同时也提高了代码的复用性。然后讲了一下数据流重构之类的 balabala……
  • 你有什么想问我的吗?

    • 问了一下面试结果大概多久能反馈给我,对方说两三天左右,然后就结束了。

结束之后不到 20 分钟,对方就在 Boss 上回复我说面试过了,然后约了二面。

二面:

  • 自我介绍

    • 跟上一轮一样,大概说了两分钟,介绍了过往工作经历,做过的业务以及技术栈。
  • 在 js 中原型链是一个很重要的概念,你能介绍一下它吗?

    • 要介绍原型链,首先要介绍一下原型,原型是什么…… 这块是纯八股,懒得打字了,直接省略吧。
  • object 的原型指向谁?

    • 回答了 null。(我也不知道对不对,瞎说的)
  • 能说一下原型链的查找过程吗?

    • 磕磕绊绊背了一段八股文,这里省略吧。
  • node 的内存管理跟垃圾回收机制有了解过吗?

    • 暗暗窃喜,这个问题问到点子上了,因为两年前被问到过,所以当时专门写了一篇文章,虽然已经过去两年了,但还是背的滚瓜烂熟:

    • 首先分两种情况:V8 将内存分成 新生代空间老生代空间

      • 新生代空间: 用于存活较短的对象

        • 又分成两个空间: from 空间 与 to 空间

        • Scavenge GC 算法: 当 from 空间被占满时,启动 GC 算法

          • 存活的对象从 from space 转移到 to space
          • 清空 from space
          • from space 与 to space 互换
          • 完成一次新生代 GC
      • 老生代空间: 用于存活时间较长的对象

        • 新生代空间 转移到 老生代空间 的条件(这个过程称为对象晋升

          • 经历过一次以上 Scavenge GC 的对象
          • 当 to space 体积超过 25%
        • 标记清除算法:标记存活的对象,未被标记的则被释放

          • 增量标记:小模块标记,在代码执行间隙执,GC 会影响性能
          • 并发标记:不阻塞 js 执行
  • js 中的基础类型和对象类型有什么不一样?

    • 基础类型存储在栈中,对象类型存储在堆中。
  • 看你简历上是用 React,你能简单的介绍一下 hooks 吗?

    • 本质上就是一个纯函数,大概介绍了一下 hooks 的优点,以及 hooks 的使用规则等等。
  • 简单说一下 useEffect 的用法:

    • useEffect 可以代替 class 中的一些生命周期,讲了一下大概用法,然后讲了一下 useEffect 的执行时机,以及 deps 的作用。
  • 说一下 useEffect 的返回值用来做什么?

    • 返回一个函数,用来做清除副作用的工作,比如:清除定时器清除事件监听等等。
  • 你知道 useEffect 第二个参数内部是怎么比较的吗?

    • 说了一下内部是浅比较,源码中用 for 循环配合 Object.is 实现。(感觉这个问题就是在考察有没有读过 React 源码)
  • 前端的话可能跟网络打交道比较多,网络你了解多少呢?

    • 这里直接坦诚的说了一下,网络是我的弱项,前面一面也问到了网络七层模型,没回答出来。
  • 那你回去了解过七层模型吗?我现在再问你一遍,你能回答出来吗?

    • 磕磕绊绊回答出来了。
  • 追问:http 是在哪一层实现的?

    • 应用层。
  • 说一下 getpost 有什么区别?

    • 两眼一黑,脑子一片空白,突然不知道说什么了,挤了半天挤出来一句:get 大多数情况下用来查询,post 大多数情况下用来提交数据。get 的入参拼在 url 上,post 请求的入参在 body 里面。面试官问我还有其它吗?我说想不起来了……
  • 说一下浏览器输入 url 到页面加载的过程:

    • 输入网址发生以下步骤:

      1. 通过 DNS 解析域名的实际 IP 地址
      2. 检查浏览器是否有缓存,命中则直接取本地磁盘的 html,如果没有命中强缓存,则会向服务器发起请求(先进行下一步的 TCP 连接)
      3. 强缓存协商缓存都没有命中,则返回请求结果
      4. 然后与 WEB 服务器通过三次握手建立 TCP 连接。期间会判断一下,若协议是 https 则会做加密,如果不是,则会跳过这一步
      5. 加密完成之后,浏览器发送请求获取页面 html,服务器响应 html,这里的服务器可能是 server、也可能是 cdn
      6. 接下来是浏览器解析 HTML,开始渲染页面
    • 顺便说了渲染页面的过程:

      1. 浏览器会将 HTML 解析成一个 DOM 树,DOM 树的构建过程是一个深度遍历过程:当前节点的所有子节点都构建好后才会去构建当前节点的下一个兄弟节点。
      2. 将 CSS 解析成 CSS Rule Tree(css 规则树)。
      3. 解析完成后,浏览器引擎会根据 DOM 树CSS 规则树来构造 Render Tree。(注意:Render Tree 渲染树并不等同于 DOM 树,因为一些像 Headerdisplay:none 的东西就没必要放在渲染树中了。)
      4. 有了 Render Tree,浏览器已经能知道网页中有哪些节点、各个节点的 CSS 定义以及他们的从属关系。下一步进行 layout,进入布局处理阶段,即计算出每个节点在屏幕中的位置。
      5. 最后一个步骤就是绘制,即遍历 RenderTree,层绘制每个节点。根据计算好的信息绘制整个页面。
    • 渲染完成之后,开始执行其它任务:

      1. dom 操作
      2. ajax 发起的 http 网络请求等等……
      3. 浏览器处理事件循环等异步逻辑等等……
  • 菜单左中右布局,两边定宽,中间自适应,说一下有几种实现方式

    • 比较经典的面试题,说了 flexfloat 两种方式。
  • 项目难点

    • 和一面一样,说了协同文档的两大难点,这里就不重复了。
  • 你有什么想问我的吗?

    • 和一面一样,问了一下面试结果大概多久能反馈给我,对方说两三天左右,然后就结束了。
  • 最后问了期望薪资什么的,然后就结束了。

二面结束之后,大概过了几个小时,在 Boss 上跟对方说了一声,如果没过的话也麻烦跟我说一下,然后这时候,对方在 Boss 上问我,第一学历是不是专科?我说是的,感觉到不太妙的样子,

然后又过了一会儿,对方说定级应该不会高,他后续看一下面试官的反馈如何……

然后又追问我,换工作的核心诉求是涨薪还是能力的提升,这里我回答的比较委婉,其实两个都想要 QAQ

今天已经是第二天了,目前没有下文,看起来二面是过了,但是因为学历不够,中止了三面的流程,基本上是失败了,我也不会报有什么希望了,所以写个面经记录一下。

最后,给自己打个广告!求职求职求职!!!

社交信息:

个人优势:

  • antd 团队成员、ahooks 团队成员,活跃于 github 开源社区,给众多知名大型开源项目提交过 PR,拥有丰富的 React + TS 实战经验
  • 熟悉前端性能优化的实现,例如代码优化、打包优化、资源优化,能结合实际业务场景进行优化
  • 熟悉 webpack / vite 等打包工具的基本配置, 能够对以上工具进行二次封装、基于以上工具搭建通用的开发环境
  • 熟悉 prettier / eslint 基本配置,有良好且严格的编码习惯,唯客户论,实用主义者
  • 熟悉代码开发到上线全流程,对协同开发分支管理项目配置等都有较深刻的最佳实践

可内推的大佬们麻烦联系我!在 github 主页有联系方式,或者直接在掘金私聊我也可,谢谢!!

Guess you like

Origin juejin.im/post/7239715208792342584