Hi,大家好,我们是阿里巴巴新成立的 BU 政务钉钉事业部(杭州同学在用的健康码是我 BU 联合其他 BU 共同设计的一个项目),目前还有大量的 Web 前端职位空缺。除此之外,我们已经开启校招通道,正在招聘优秀的实习生(今年 6 月份毕业的应届生通道已关闭)。希望想找我内推或者想了解更多招聘信息的同学可以加我微信:18768107826
gaearon :If it's an async request, it won't be fulfilled by the time the component mounts anyway, regardless of where you fire it. This is because JS is single threaded, and the network request can't "come back" and be handled while we are still rendering. So the difference between firing it earlier and later is often negligible.
You're right that it matters in some rare cases though and for those cases it might make sense to break the recommendation. But you should be extra cautious as state can update before mounting, and if your data depends on state, you might have to refetch in that case. In other words: when in doubt, do it in componentDidMount.
The specific recommendation to avoid side effects in the constructor and Will* lifecycles is related to the changes we are making to allow rendering to be asynchronous and interruptible (in part to support use cases like this better). We are still figuring out the exact semantics of how it should work, so at the moment our recommendations are more conservative. As we use async rendering more in production we will provide a more specific guidance as to where to fire the requests without sacrificing either efficiency or correctness. But for now providing a clear migration path to async rendering (and thus being more conservative in our recommendations) is more important.
编译成render function 后,调用$mount的mountComponent方法,先执行beforeMount钩子函数,然后核心是实例化一个渲染Watcher,在它的回调函数(初始化的时候执行,以及组件实例中监测到数据发生变化时执行)中调用updateComponent方法(此方法调用render方法生成虚拟 Node,最终调用update方法更新 DOM)。
调用render方法将render function渲染成虚拟的Node(真正的 DOM 元素是非常庞大的,因为浏览器的标准就把 DOM 设计的非常复杂。如果频繁的去做 DOM 更新,会产生一定的性能问题,而 Virtual DOM 就是用一个原生的 JavaScript 对象去描述一个 DOM 节点,所以它比创建一个 DOM 的代价要小很多,而且修改属性也很轻松,还可以做到跨平台兼容),render方法的第一个参数是createElement(或者说是h函数),这个在官方文档也有说明。
生成虚拟 DOM 树后,需要将虚拟 DOM 树转化成真实的 DOM 节点,此时需要调用update方法,update方法又会调用pacth方法把虚拟 DOM 转换成真正的 DOM 节点。需要注意在图中忽略了新建真实 DOM 的情况(如果没有旧的虚拟 Node,那么可以直接通过createElm创建真实 DOM 节点),这里重点分析在已有虚拟 Node 的情况下,会通过sameVnode判断当前需要更新的 Node节点是否和旧的 Node 节点相同(例如我们设置的key属性发生了变化,那么节点显然不同),如果节点不同那么将旧节点采用新节点替换即可,如果相同且存在子节点,需要调用patchVNode方法执行 DIFF 算法更新 DOM,从而提升 DOM 操作的性能。
前言
由于疫情关系,最近在掘金看到很多同学的工作情况内心还是蛮触动的(降薪、变相裁员、辞退等)。可能这并不是当下一个普遍的现象,但仍然使我感受到前端这碗青春饭不好混。于此同时联系我内推的同学很多都处于待业状态,能感受到他们内心的迷茫和焦灼。于是内心一直有声音督促我,赶紧写点面试相关的东西出来吧,哪怕对大家只有一丝丝的帮助。当然这次我会以面试官的角度出发(可能不是一个优秀的面试官),让大家更加了解阿里的面试流程、面试数据和面试场景等。接下来我会从以下几个模块来讲解:
更新日志
2020.04.12
2020.04.06
2020.03.29
2020.03.22
2020.03.19
招聘
Hi,大家好,我们是阿里巴巴新成立的 BU 政务钉钉事业部(杭州同学在用的健康码是我 BU 联合其他 BU 共同设计的一个项目),目前还有大量的 Web 前端职位空缺。除此之外,我们已经开启校招通道,正在招聘优秀的实习生(今年 6 月份毕业的应届生通道已关闭)。希望想找我内推或者想了解更多招聘信息的同学可以加我微信:18768107826
招聘流程
阿里的招聘流程可能相对较长,一般情况下如果走「内推」渠道,可能会经历以下几个步骤:
如果你运气够好,可能只需要 4 面左右(没有三轮技术面、二轮 HR 面)。如果你运气不好,那么可能存在 5 ~ 6 面的情况。
内推数据
入职半年以来断断续续收到掘友们的内推简历。这里将内推的数据整理了一下,供大家有个体感:
需要注意不是收到内推简历就会立即投递,会先有一个纯粹的简历筛选过程,因此上传简历和简历评估会有数量的差别。除此之外,当前还没有遇到被 HR 拒绝的情况。当然从内推数据可以看出,其中关键性的面试是简历评估和一轮技术面(通常对于应聘者而言是一面和二面)。
面试数据
由于进入公司不久,一般我都是作为简历评估的面试官,少数时候会作为一轮技术面的面试官,这里将我作为面试官的数据整理如下:
感觉和内推数据中的简历评估通过率相比,我在简历评估的时候会更加谨慎......
面试注意点
在面试的过程中,我印象最深的几点感受一定要告知大家:
关于第 2 点还是要说明一下,很多面试者回答问题没有逻辑性,在回答之前可以先思考一下,然后告诉面试官将从 n 个方面进行讲解,首先第 1 个方面是...,其次第 2 个方面是...
面试题解析
一般在面试开始前,我会根据应聘者的简历提前准备 8 道左右的面试题(在面试的过程中可能会有调整),最终分析了一下笔试题数据如下:
由于本身对 React 熟悉还不够,因此我遇到应聘者如果是 React 技术栈会相对吃亏一些。接下来我会重点讲解一些面试题,有些简单的面试题不会出解答思路(有些面试题可从《面试分享:两年工作经验成功面试阿里 P6 总结》中找到答案),没有给出答案的面试题希望大家在评论中给出,供别人参考。
HTML 篇
建设中...
参考链接
CSS 篇
解题思路
参考链接
解题思路
clear
属性 和 BFC 法可能追加的面试题(详见参考链接)
clear
属性清除浮动的原理是什么?clear
属性清除浮动相比的优势是什么?参考链接
解题思路
flex-direction: column
flex: 1
解题思路
margin
负值的作用(可参考 Bootstrap 3 中栅格容器.container
的样式)可能追加的面试题
解题思路
利用清除可以设置元素禁止浮动元素出现在它的左侧、右侧甚至是双侧。
3333333333333333333333333333333333333333333
由于 div1 浮动,p 和 div1 布局重叠,为了解决这个问题,可以使 p 元素左侧不允许有浮动元素,给 p 元素添加一个 clear:left 的样式之后
3333333333333333333333333333333333333333333
可以发现 p 的位置下移从而使 p 和 div1 布局不会重叠,其实是使用清除之后,自动增加了 p 元素的上外边距,确保它落在浮动元素 div1 的下面。CSS2.1 引入了清除区域的概念,清除区域是在元素上外边距之上增加的额外间隔(确保浮动元素不会与该元素重叠),不允许浮动元素进入这个范围,意味着设置 clear 属性的 p 元素的外边距并不改变,之所以该元素会向下移动是因为清除区域造成的。div1 和 div2 的高度分别是 100px 和 50px, 因此清除区域的高度在 50px 左右(不算 border 和浏览器代理初始样式等)。如果给 p 元素一个上外边距 margin-top:30px,则 p 元素并不会向下移动 30px,而是在解析完样式之后清除区域的高度变成了 50px - 30px 左右,而 p 元素仍然位置不变,如果要使 p 元素下移,则需要使 p 元素的 margin-top 值高于最大的清除区域高度 50px,并且向下位移的距离也是 margin-top 值减去最大的清除区域高度。
参考链接
《面试分享:两年工作经验成功面试阿里 P6 总结》
解题思路
vertical-align
属性值:baseline
、top
、middle
、bottom
text-top
、text-bottom
sub
、super
vertical-align
生效前提:span
、strong
、em
、img
、button
、input
等display
值为inline
、inline-block
、inline-table
或table-cell
的元素建设中...
参考链接
《面试分享:两年工作经验成功面试阿里 P6 总结》
可能追加的面试题
background-color
属性可以覆盖background-image
属性吗?参考链接
《面试分享:两年工作经验成功面试阿里 P6 总结》
建设中...
建设中...
JavaScript / TypeScript 篇
解题思路
可能追加的面试题
参考链接
解题思路
this
,然后再将父类的方法添加到this
上面。ES6 的继承机制完全不同,实质是先创造父类的实例对象this
(所以必须先调用super
方法),然后再用子类的构造函数修改this
。参考链接
解题思路
解题思路
面试题来源
应聘者简历里写了熟悉高性能 JavaScript 开发
解题思路
for
、for...of
、for...in
、forEach
、while
、do...while
等console.time
和console.timeEnd
进行测试++
和--
有没有区别可能追加的面试题
if-else
和switch
性能哪个高?解题思路
with
和catch
,除非是有必要的情况下window.location.href
参考链接
《面试分享:两年工作经验成功面试阿里 P6 总结》
解题思路:
await
会等待异步代码执行,会阻塞代码(使用时要考虑性能)async / await
在调试方面会更加方便解题思路
参考链接
React 篇
解题思路
props
的更新是异步的,因为re-render
父组件的时候,传入子组件的props
才变化;为了保持数据一致,state
也不直接更新,都是在flush
的时候更新state
的更新延缓到最后批量合并再去渲染对于应用的性能优化是有极大好处的,如果每次的状态改变都去重新渲染真实 DONM,那么它将带来巨大的性能消耗可能追加的面试题
setState
会进行同步操作?setState
特定情况下进行同步操作的优化方案是什么?setState
后想要拿到更新的state
值应该怎么处理?参考链接
setState
asynchronous?unstable_batchedUpdates
解题思路
localStorage 结合 Redux
url query
(注意长度限制)面试题来源
简历中写着使用 Hooks 结合高阶组件完成业务开发
解题思路
可能追加的面试题
参考链接
解题思路
gaearon :If it's an async request, it won't be fulfilled by the time the component mounts anyway, regardless of where you fire it. This is because JS is single threaded, and the network request can't "come back" and be handled while we are still rendering. So the difference between firing it earlier and later is often negligible.
You're right that it matters in some rare cases though and for those cases it might make sense to break the recommendation. But you should be extra cautious as state can update before mounting, and if your data depends on state, you might have to refetch in that case. In other words: when in doubt, do it in componentDidMount.
The specific recommendation to avoid side effects in the constructor and Will* lifecycles is related to the changes we are making to allow rendering to be asynchronous and interruptible (in part to support use cases like this better). We are still figuring out the exact semantics of how it should work, so at the moment our recommendations are more conservative. As we use async rendering more in production we will provide a more specific guidance as to where to fire the requests without sacrificing either efficiency or correctness. But for now providing a clear migration path to async rendering (and thus being more conservative in our recommendations) is more important.
JS 是单线程,Ajax 请求不会 "返回" 并且触发当我们正在 rendering 的时候(Ajax 的执行结果会放到任务队列中,等主线程执行完后采取读取任务队列中的任务进行执行),因为理论上放在哪里结果都一样,都会执行两次 render。
这样的话,就没必要在
componentWillMount
中调用 Ajax,以避免理解不到位,对state的结果预计错误。componentDidMount
的执行很明了,不会引起歧义,所以在componentDidMount
中最合理了。可能追加的面试题
componentDidMount
里进行处理,而不是放在componentWillMount
里进行处理?componentWillMount
里进行处理,且 Ajax 的返回结果在 render 之前,那么最终会执行几次 render ?参考链接
解题思路
可能追加的面试题
除此之外,在语法层面:
this
上(简直蛋疼),React 中的 JSX 万物皆可 JavaScript。可能追加的面试题
Vue 篇
面试题来源
简历中写着 Vue CLI 技术栈
解题思路
可能追加的面试题
面试题来源
简历上写着熟悉 React 和 Vue 技术栈
解题思路
template.json
)Creat React App 在工程化体系上没有 Vue CLI 3.x 更加的开箱即用,除此之外,Vue CLI 3.x 中的插件体系是一个非常棒的特性,它使自定义脚手架模板变得非常灵活(非常适合企业定制化脚手架)。当然 Create React App 是有它自己的设计理念的,对于简单的应用它是一种优势(不可配置化预先约定)。
面试题来源
简历中写着熟悉 Vue.js 源码,或者简历中只写着 Vue.js 技术栈,或者面试的过程找不到亮点
解题思路
这里简单的描述一下 Vue 2.x 的运行机制(需要注意分析的是 Runtime + Compiler 的 Vue.js)。
初始化流程:
init
过程会初始化生命周期,初始化事件中心,初始化渲染、执行beforeCreate
周期函数、初始化data
、props
、computed
、watcher
、执行created
周期函数等。$mount
方法对Vue实例进行挂载(挂载的核心过程包括模板编译、渲染以及更新三个过程)。render
方法而是定义了template
,那么需要经历编译阶段。需要先将template
字符串编译成render function
,template
字符串编译步骤如下 :parse
正则解析template
字符串形成 AST(抽象语法树,是源代码的抽象语法结构的树状表现形式)optimize
标记静态节点跳过 DIFF 算法(DIFF 算法是逐层进行比对,只有同层级的节点进行比对,因此时间的复杂度只有 O(n)。如果对于时间复杂度不是很清晰的,可以查看我写的文章ziyi2/algorithms-javascript/渐进记号)generate
将 AST 转化成render function
字符串render function
后,调用$mount
的mountComponent
方法,先执行beforeMount
钩子函数,然后核心是实例化一个渲染Watcher
,在它的回调函数(初始化的时候执行,以及组件实例中监测到数据发生变化时执行)中调用updateComponent
方法(此方法调用render
方法生成虚拟 Node,最终调用update
方法更新 DOM)。render
方法将render function
渲染成虚拟的Node(真正的 DOM 元素是非常庞大的,因为浏览器的标准就把 DOM 设计的非常复杂。如果频繁的去做 DOM 更新,会产生一定的性能问题,而 Virtual DOM 就是用一个原生的 JavaScript 对象去描述一个 DOM 节点,所以它比创建一个 DOM 的代价要小很多,而且修改属性也很轻松,还可以做到跨平台兼容),render
方法的第一个参数是createElement
(或者说是h
函数),这个在官方文档也有说明。update
方法,update
方法又会调用pacth
方法把虚拟 DOM 转换成真正的 DOM 节点。需要注意在图中忽略了新建真实 DOM 的情况(如果没有旧的虚拟 Node,那么可以直接通过createElm
创建真实 DOM 节点),这里重点分析在已有虚拟 Node 的情况下,会通过sameVnode
判断当前需要更新的 Node节点是否和旧的 Node 节点相同(例如我们设置的key
属性发生了变化,那么节点显然不同),如果节点不同那么将旧节点采用新节点替换即可,如果相同且存在子节点,需要调用patchVNode
方法执行 DIFF 算法更新 DOM,从而提升 DOM 操作的性能。需要注意在初始化阶段,没有详细描述数据的响应式过程,这个在响应式流程里做说明。
响应式流程:
init
的时候会利用Object.defineProperty
方法(不兼容 IE8)监听Vue实例的响应式数据的变化从而实现数据劫持能力(利用了 JavaScript 对象的访问器属性get
和set
,在未来的 Vue3 中会使用 ES6 的Proxy
来优化响应式原理)。在初始化流程中的编译阶段,当render function
被渲染的时候,会读取Vue实例中和视图相关的响应式数据,此时会触发getter
函数进行依赖收集(将观察者Watcher
对象存放到当前闭包的订阅者Dep
的subs
中),此时的数据劫持功能和观察者模式就实现了一个 MVVM 模式中的 Binder,之后就是正常的渲染和更新流程。setter
函数,setter
会通知初始化依赖收集中的Dep
中的和视图相应的Watcher
,告知需要重新渲染视图,Wather
就会再次通过update
方法来更新视图。可以发现只要视图中添加监听事件,自动变更对应的数据变化时,就可以实现数据和视图的双向绑定了。
可能追加的面试题
computed
/watch
实现的原理是什么?$nextTick
的原理是什么?它主要经历了哪些变化?为什么?参考链接
解题思路
可能追加的面试题
dispatch
和broadcast
是如何实现的?建设中...
可能追加的面试题
$nextTick
在几个版本迭代中都经历了什么变化?参考链接
建设中...
建设中...
面试题来源
简历中出现
keep-alive
信息可能追加的面试题
keep-alive
之后对组件渲染的生命周期有什么影响?keep-alive
有哪些特性?建设中...
解题思路
keep-alive
Object.freeze
可能追加的面试题
组件篇
面试题来源
简历写着抽取公共业务组件
解题思路
可能追加的面试题
参考链接
建设中...
面试题来源
简历写着设计和维护公司的组件库
解题思路
可能追加的面试题
参考链接
面试题来源
简历写着使用 Element UI 进行业务开发并自己设计过组件
参考链接
面试题来源
简历写着使用使用按需加载提升页面性能
解题思路
设计模式篇
面试题来源
简历中写着熟悉设计模式、Redis、Vue 源码等
可能追加的面试题
参考链接
参考链接
工程化篇
面试题来源
项目中写着使用 Webpack 进行构建速率优化
解题思路
可能追加的面试题
面试题来源
项目中写着使用 cz 规范 Git 提交
参考链接
建设中...
性能优化篇
建设中...
建设中...
服务篇
建设中...
建设中...
建设中...
建设中...
建设中...
建设中...
框架篇
建设中...
建设中...
可能追加的面试题
建设中...
建设中...
HTTP 篇
可能追加的面试题
建设中...
建设中...
可能追加的面试题
可能追加的面试题
建设中...
建设中...
建设中...
可能追加的面试题
建设中...
建设中...
建设中...
测试篇
建设中...
建设中...
优化篇
建设中...
可能追加的面试题
建设中...
业务篇
名词解析篇
建设中...
笔试篇
混沌篇
八卦篇