支付宝面试复盘

失败是排除一种通向成功的方式

Q:说说你做的VR编辑器项目
A:这是一个针对与全景照片的在线编辑平台,用户上传全景照片后,可以在编辑器里添加热点,图片,文字等素材,最终生产一个全景项目。接手这个项目时已经迭代了4个大版本,做了非常多的功能,但是业务逻辑混杂,代码组织混乱,维护成本非常高,所以我的主要任务是对这个系统重构,我把系统分为3个层级,基础业务层,扩展模块层,View显示层,设计了模块扩展标准,目前重构已经完成80%左右,正在带领几个同事做扩展模块

Q:你是如何确保重构后的正确性的?
A:目前使用的是人工测试,考虑过做单元测试,计算了一下投入产出比,觉得还是人工测试比较高效

Q:说说你对工程化的认识
A:我觉得工程化本质上是解决重复性的问题,使用脚本完成人为操作时容易出错的工作,最基本比如说代码打包,单元测试,持续集成,自动部署等等

Q:对模块化有什么看法?
A:额…..(一段持续了15s的尴尬沉默),我觉得模块化就是把单一的功能放到一个文件里,让它可以被别的文件使用,这样做可以降低代码耦合性,提升代码复用性等等
复盘:对于这个问题我一时没找到切入点,平时觉得模块化是件理所当然的事情,并没有什么特别的看法,然后几乎是尬聊式的回答了一点,我有时候经常听不懂别人到底在问什么,于是就强行扯一些回答不到点子上的事情,自己觉得很累,听的人估计也很着急,其实这种情况可以让提问者问一些具体的问题,比如这样说:我觉得模块化在很多场景里有不同的形式,不知道你问的是具体是在什么方面的?

Q:对 AMD/CMD/ES module 的演进历史了解吗?
A:最早人们是手动管理模块加载的,一些互相有依赖关系的文件必须以正确的顺序出现在页面上,后来才有人做了 AMD/CMD 这种模块化规范,模块可以声明自己的依赖,在运行时自动去加载这些依赖,现在使用的最多的是 webpack,在构建阶段通过代码静态分析,把模块代码按照正确的顺序打包成 bundle

Q:做 H5 项目时遇到过兼容性问题吗?
A:没回答出来
复盘:当时脑子确实一片空白,我知道一定是解决过一些的,毕竟做过几个移动端的项目呢,可是我对于只解决过一次的 BUG 通常没什么特别的印象,除非再次遇到,实在想不起来最多回去翻一下代码,其实最常见的,就是 css 前缀这个东西,还有 ios 的 click 延迟 300ms 问题,ios 视频无法自动播放,ios 滚动条滚动不平滑问题等等,如果能想起来随便一两个也不至于交白卷,另一方面来说也确实大半年多来没处理过移动端了,在上家公司虽说是主做移动端的,但是主要框架开发完后,大部分时间都在做业务开发,兼容性问题在早期都解决的差不多了,不过以后遇到 BUG 性质的问题,最好还是记一下,让自己有更深刻的理解

Q:什么是 GPU 加速?
A:GPU 加速是利用了 GPU 相比 CPU 有更多的计算单元,在做一些动画效果时,使用 css3 会让浏览器开启 GPU 运算,相比 js 的 CPU 运算在性能上会好很多
复盘:当时我觉得我回答的还不错,后来查了一下好像没回答到点子上,https://www.jianshu.com/p/f8b1d6e598db,https://div.io/topic/1348

Q:React 中虚拟 dom 为什么如此高性能?
A: JS 更新 DOM 是很慢的,但 JS 本身运算非常快,react 将 dom 抽象成数据,在内存中进行对比,将真正具有差异的 dom 节点更新到页面上
复盘:DOM为什么慢?一个DOM的属性是非常庞大的,而且还有很多陷阱,比如对一些属性访问(甚至是读操作!!)时触发reflow。什么是虚拟DOM?
用 JavaScript 对象结构表示 DOM 树的结构;然后用这个树构建一个真正的 DOM 树,插到文档当中当状态变更的时候,重新构造一棵新的对象树。然后用新的树和旧的树进行比较,记录两棵树差异把2所记录的差异应用到步骤1所构建的真正的DOM树上,视图就更新了。Virtual DOM 本质上就是在 JS 和 DOM 之间做了一个缓存。可以类比 CPU 和硬盘,既然硬盘这么慢,我们就在它们之间加个缓存:既然 DOM 这么慢,我们就在它们 JS 和 DOM 之间加个缓存。CPU(JS)只操作内存(Virtual DOM),最后的时候再把变更写入硬盘(DOM)。

Q:React 的 diff 是如何实现的?
A:不太清楚,我猜测 react 用一个 js 对象来表示 dom 树,然后进行对象之间的 diff,可能是将树转换成一位数组进行对比。
复盘:大致上没有猜得很离谱,细节问题没有思考过。react diff 算法大致可以分为3个步骤:
一:抽象 dom 树
二:DIFF 两颗树,将用于描述差异的对象放进数组
三:将差异应用到 DOM 树上
参考 如何理解虚拟DOM? - 戴嘉华的回答 - 知乎

Q:React 如何阻止更新?
A: shouldComponentUpdate
复盘:什么时候需要写shouldComponentUpdate?
只有经过测量,发现有了shouldComponentUpdate后组件的渲染速度确实有可察觉的提升,你才应该用它。
react 本身就是一个优秀的 shouldComponentUpdate 实现,我们自己写shouldComponentUpdate容易引起难以排查的bug,参考 什么时候要在React组件中写shouldComponentUpdate?

Q:用过哪些性能优化的方法?
A:一些常规的,减少文件体积、减少 http 请求、缓存,用一些 webpack plugin 对 react 优化
复盘:除此之外还有 CDN,code-splitting,Tree-shaking,font icon,HTTP2,DNS预热(dns-prefetch),gzip,service worker(PWA)

Q:jQuery 中的 ready 方法是如何实现的?
A:没具体了解过,我猜测 ready 首先是解决了一些兼容性问题,如果已经ready了,设置一个标识,每次执行ready时先去判断这个标识是否存在,如果存在就直接执行 function,否则就添加到队列中,等浏览器真正ready后执行队列
复盘:猜的还行,补充一个与window.onload的区别会更好jquery $(document).ready() 与window.onload的区别 jQuery的ready方法实现原理分析

Q:说说 http 中的 post 和 get 的区别
A:首先是语义上的区别,get表示获取资源,post表示添加资源,get 可以做缓存,post则不行,post可以在请求体中添加数据,get不行,
复盘:以前不是没有整理过区别的,面试的时候都没有想起来,前端面试题收集 - GET和POST的区别

Q:http 有哪些状态?
A:1xx消息,2xx成功,3xx重定向,4xx客户端错误,5xx服务器错误

Q:304 代表什么?如何实现的?
A:嘶……(沉默),我猜吧,服务器返回一个资源时,带上最后更新时间,客户端下次再请求这个文件时带上这个时间,服务器进行对比,如果没有更新呢么就返回304
复盘:猜的可以,原理的具体阐述可参考 网络—关于HTTP 304状态码的理解

Q:Cookies 和 session 是什么?
A: HTTP 本身没有状态的,cookies/session 是一种保存 http 状态的方案,当回话开始是,服务器产生一个 session 标识,返回给客户端进行保存,客户端每次的请求会带上这个 cookies 给服务器匹配,匹配成功则表示继续维持会话状态
复盘:Cookie/Session机制详解

Q:query-string 的大小限制是多少?
A: 每个浏览器貌似不太一样,具体我记不清了,服务器也可以设置 query-string
复盘:这个问题并不是考是否能背出这个数据,而是要看是否理解 query string 存在限制 ,HTTP协议中没有对 url 长度有要求,通常来说浏览器都支持上千个字符。URL最大长度问题

Q:HTTP2了解吗?
A: 不了解,我知道有一个服务器推送,在请求并发的性能有一些提升。
复盘: 一个质的区别,http1.x的解析是基于文本,http2.0的协议解采用二进制格式,header压缩,多路复用,Server Push
HTTP/2.0 相比1.0有哪些重大改进? - victor yu的回答 - 知乎

Q:你认为自己的优势是什么?
A:我对设计代码很有兴趣,也很擅长,然后又比较多的0-1项目开发经验,能快速创建产品
复盘:实际回答时其实很不流畅,平时也没怎么思考过,语言都是临时拼凑的,比这个要琐碎的多,我觉得我最大的优势在于,有长期从业带来的技术直觉,这些直觉是建立在对事物本质的理解上产生的,我在思考问题时,首先会去弄懂本质是什么,这样的习惯让我在很多问题上比别人更容易找到关键

Q:有什么想问的吗?
A:没有

总结

让我出乎意料的是,凭直觉猜的题目几乎都对了,拥有良好的直觉是双刃剑,用的好就是才思敏捷,用的不好就是不懂装懂,偏离事实,做技术的人应该扎根于脚下,永远对知识保持敬畏之心

在自信心方面表现的不太足,有些问题其实答得还不错,但是面试官一逼问就会有点犹豫了,主要还是基础不扎实

对于找不到关键点的问题不要强行尬聊,再问问清楚不会很丢人

虽然最后结果是凉了,总结失败的原因还是基础问题,想虚拟dom这些问题其实研究一下也就几个小时,平时不太注意这些细节,然后对于解决过的 bug 也没有复盘过解决思路,项目经验上偏重于从头开发,缺少大型项目的优化经验,日后在工作中,多留意细节,似懂非懂的问题尽量去弄懂,BUG解决了停下来总结一下,多提问,多思考,多总结