乐趣区

关于前端:阿里蚂蚁集团前端秋招一面面经

电话面,不定时忽然打过去问当初是否不便面试。
次要考察点:我的项目的具体实现,我的项目中遇到的难点,框架底层原理的意识。感觉问的比个别面试难,很重视细节和深度

一. 问简历上某个我的项目的具体实现,有没有遇到什么难点

二. 有哪个我的项目是你独立负责的,负责的我的项目从构建,部署,打包,框架选型是如何思考的

三. react 和 vue 的比拟,我的项目开发中怎么确定用哪个

1. 相似之处

  • 都是用于创立 UI 的 JavaScript 库;
  • 都疾速轻便(专一于发明前端的富利用。不同于晚期的 JavaScript 框架“功能齐全”,)
  • 都有基于组件的架构;
  • 都是用虚构 DOM;
  • 都可放入单个 HTML 文件中,或者成为更简单 webpack 设置中的模块;
  • 都有独立但罕用的路由器和状态治理库(Reat 与 Vue 只有框架的骨架,其余的性能如路由、状态治理等是框架拆散的组件。)

它们之间的最大区别是 Vue 通常应用 HTML 模板文件,而 React 则齐全是 JavaScript。Vue 有双向绑定语法糖。

2.区别:

  1. 监听数据变动的实现原理不同

    Vue 通过 getter/setter 以及一些函数的劫持,能准确晓得数据变动。

    React 默认是通过比拟援用的形式(diff)进行的,如果不优化可能导致大量不必要的 VDOM 的从新渲染。为什么 React 不准确监听数据变动呢?这是因为 Vue 和 React 设计理念上的区别,Vue 应用的是可变数据,而 React 更强调数据的不可变,两者没有好坏之分,Vue 更加简略,而 React 构建大型利用的时候更加鲁棒。

  2. 数据流不同

    Vue1.0 中能够实现两种双向绑定:父子组件之间,props 能够双向绑定;组件与 DOM 之间能够通过 v -model 双向绑定。Vue2.x 中去掉了第一种,也就是父子组件之间不能双向绑定了(然而提供了一个语法糖主动帮你通过事件的形式批改),并且 Vue2.x 曾经不激励组件对本人的 props 进行任何批改了。

    React 始终不反对双向绑定,提倡单向数据流,称为 onChange/setState()模式。

  3. 模板渲染形式不同

    在表层上,模板的语法不同,React 通过 JSX 渲染模板。Vue 通过一种拓展的 HTML 语法进行渲染,但其实这只是表面现象,毕竟 React 并不必须依赖 JSX。

    在深层上,模板的原理不同,这才是他们的本质区别:React 是在组件 JS 代码中,通过原生 JS 实现模板中的常见语法,比方插值,条件,循环等,都是通过 JS 语法实现的,更加纯正更加原生。而 Vue 是在和组件 JS 代码拆散的独自的模板中,通过指令来实现的,比方条件语句就须要 v-if 来实现对这一点,这样的做法显得有些独特,会把 HTML 弄得很乱。

  4. 框架实质不同

    Vue 实质是 MVVM 框架,由 MVC 倒退而来;

    React 是前端组件化框架,由后端组件化发展而来。

3. 各自的长处

React

  • 通过模块化的构造使其领有灵便的代码,节省时间和老本。
  • 助力简单应用程序的高性能的实现。
  • 应用 React 前端开发可能更容易去做代码保护。
  • 反对实用于 Android 和 iOS 平台的挪动端原生应用程序。

Vue

  • 它的体积玲珑,便于装置和下载。
  • 假使咱们正确利用,咱们就能够在多处重用 Vue。
  • Vue.js 容许咱们更新网页中的元素,而无需渲染整个 DOM,因为它是虚构的 DOM。
  • 须要较少的优化。
  • 减速 Web 应用程序的开发,并容许大佬将模板到虚构 DOM 与编译器离开。
  • 通过验证的兼容性和灵活性。
  • 不论应用程序的规模如何,代码库都不会变。

4. 技术选型

这里联合本人理论工作中的领会来讲会更好,找了个大佬的参考 https://www.cnblogs.com/pengf…

四. 讲一下 React Diffing 算法

传统 diff 算法的问题

传统的 diff 算法是应用循环递归对节点进行顺次比照,复杂度为 O(n^3), 效率低下。

为了优化 diff 算法,React 提出了两个假如:

  1. 两个不同类型的元素会产生出不同的树
  2. 开发者能够通过 key prop 来暗示哪些子元素在不同的渲染下能保持稳定

React diff 算法策略

  • 针对树结构(tree diff):对 UI 层的 DOM 节点跨层级的挪动操作进行疏忽。(因为这种操作的数量很少)
  • 针对组件构造 (component diff):领有雷同的两个组件生成类似的树形构造,领有不同 的两个组件会生成不同的属性构造。
  • 针对元素构造 (element-diff): 对于同一层级的一组节点,它们能够用 唯一性 的 id 辨别 (key 属性)

diff 具体优化

1.tree diff(树形构造)

  • React 通过应用 updateDepth 对 虚构 DOM 树进行档次遍历
  • 两棵树只对同一层级节点进行比拟,只有该节点不存在了,那么该节点与其所有子节点会被 齐全删除, 不在进行进一步比拟。
  • 只须要遍历一次,便实现对整个 DOM 树的比拟。

如果产生跨级操作,React 不能复用已有节点,可能会导致 React 进行大量从新创立操作,这会影响性能。所以 React 官网举荐尽量避免跨层级的操作。

2.component diff

  • 同类型组件,首先应用 shouldComponentUpdate()办法判断是否须要进行比拟,如果返回true,持续依照 React diff 策略比拟组件的虚构 DOM 树,否则不须要比拟
  • 不同类型的组件,则将该组件判断为 dirty component,替换整个组件及其下的所有子节点

3.element diff

对于处于同一层级的节点,React diff 提供了三种节点操作

  • 插入:新的组件不在原来的汇合中,是全新的节点,对汇合进行插入操作。
  • 删除:组件曾经在汇合中,但汇合曾经更新,此时节点就须要删除。
  • 挪动:组件并没有产生更新,只是地位产生扭转,例如:(A,B,C,D) → (A,D,B,C), 传统 diff 会在检测到旧汇合中第二位为 B,新汇合第二位为 D 时删除 B,插入 D,前面的所有节点都要从新加载,React diff 则是通过向同一层的节点增加 惟一 key 进行辨别,并且挪动。

补充:key 的作用

key 的作用次要是用来缩小没必要的 diff 算法比照,因为对于一个组件或者节点来说,只有父节点状态或者属性发生变化,该组件就会进行 diff 比照,即便该组件没变动,而如果为组件引入了 key 值,就能够在 diff 比照前先做一个校验,判断该组件是否须要 diff 比照,即便是 diff 比照,也能够判断该组件是间接更新操作还是销毁或者新建操作,从而进步了 diff 算法的效率;

特地在渲染同级同构造的组件们时,key 能够为它们加上了身份的标记,在 rerender 时,能够通过 key 来判断该组件是否曾经存在,是否须要跟新或者销毁,新建等操作,进步了 diff 算法在同级节点上的操

五. 讲一下 react 的生命周期

挂载阶段

组件的初始化阶段,将咱们的组件插入到 DOM 中,只会产生一次

  • constructor
  • getDerivedStateFromProps

    取代之前的 componentWillMount、componentWillReceiveProps 和 componentWillUpdate

  • componentWillMount
  • render
  • componentDidMount

更新阶段

当组件的 props 扭转了,或组件外部调用了 setState 或者 forceUpdate 产生,会产生屡次

  • componentWillReceiveProps/UNSAFE_componentWillReceiveProps
  • getDerivedStateFromProps
  • shouldComponentUpdate

    当组件接管到新属性,或者组件的状态产生扭转时触发。组件首次渲染时并不会触发。个别咱们通过该函数来优化性能:<u> 一个 React 我的项目须要更新一个小组件时,很可能须要父组件更新本人的状态。而一个父组件的从新更新会造成它旗下所有的子组件从新执行 render()办法,造成新的虚构 DOM,再用 diff 算法对新旧虚构 DOM 进行构造和属性的比拟,决定组件是否须要从新渲染 </u>

    无疑这样的操作会造成很多的性能节约,所以咱们开发者能够依据我的项目的业务逻辑,在 shouldComponentUpdate()中退出条件判断,从而优化性能(手动判断组件是否须要更新)

    例如 React 中的就提供了一个 PureComponent 的类,当咱们的组件继承于它时,组件更新时就会默认先比拟新旧属性和状态,从而决定组件是否更新。值得注意的是,PureComponent 进行的是浅比拟,所以组件状态或属性扭转时,都须要返回一个新的对象或数组

  • componentWillUpdate/UNSAFE_componentWillUpdate
  • render
  • getSnapshotBeforeUpdate

    这个办法在 render 之后,componentDidUpdate 之前调用。有两个参数 prevProps 和 prevState,示意之前的属性和之前的 state,这个函数有一个返回值,会作为第三个参数传给 componentDidUpdate

    代替 componentWillUpdate

  • componentDidUpdate

    组件被更新实现后触发。页面中产生了新的 DOM 的元素,能够进行 DOM 操作

卸载阶段

  • componentWillUnmount

componentWillUnmount

当咱们的组件被卸载或者销毁了就会调用,咱们能够在这个函数里去革除一些定时器,勾销网络申请,清理有效的 DOM 元素等垃圾清理工作

留神不要在这个函数里去调用 setState,因为组件不会从新渲染了

六.react 具体如何通过 shouldComponentUpdate 来缩小反复渲染,函数组件中怎么做

组件 state 或 props 被更新时能够通过这个生命周期判断是否持续渲染。

它承受两个参数nextPropsnextState,返回一个布尔值。

若不在代码中申明该生命周期,react 默认的解决是:

  shouldComponentUpdate(nextProps, nextState) {return true;}

编写代码的时候能够通过该生命周期来优化渲染

    shouldComponentUpdate(nextProps, nextState) {if (this.props.name === nextProps.name) {return false;}
        return true;
    }

应用 shouldComponentUpdate()以让 React 晓得以后状态或属性的扭转是否不影响组件的输入,默认返回 ture,返回 false 时不会重写 render,而且该办法并不会在初始化渲染或当应用 forceUpdate()时被调用,咱们要做的只是这样:

shouldComponentUpdate(nextProps, nextState) {return nextState.someData !== this.state.someData}

然而,state 里的数据这么多,还有对象,还有简单类型数据 React.PureComponent 解决这个问题

React.PureComponent

React.PureComponent 与 React.Component 简直完全相同,但 React.PureComponent 通过 props 和 state 的浅比照来实现 shouldComponentUpate()。如果对象蕴含简单的数据结构,它可能会因深层的数据不统一而产生谬误的否定判断(体现为对象深层的数据已扭转视图却没有更新)

函数组件用的是 useMemo

七. 讲一下 vue 的双向绑定,3.0 proxy 相比 2.0 的长处

八. 事件监听相干

事件代理应该留神什么

怎么设置在事件捕捉阶段去执行相应的函数

事件绑定 addventlisner 具体参数内容

九. 比拟两个对象是否相等 (不肯定是对象),JSON.stringify() 毛病

讲了两种,一种相似于深拷贝,递归遍历去比拟
第二种用 JSON.stringfy()转为 JSON 字符串去比拟,问这种办法的毛病是什么

十. 讲一下如何实现一个不定宽 div 的垂直居中

  1. flex
  2. position 定位,设本人的 position 为 absolute, 父元素为 relative,left: 50%,top:50% transform:translateX(-50%) translateY(-50%);

十一. get 和 post 的区别

参考

Vue 与 React 两个框架的区别和劣势比照 https://segmentfault.com/a/11…
react 中 key 的作用 https://segmentfault.com/a/11…

退出移动版