最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 阿里蚂蚁集团-前端秋招一面面经

    正文概述 掘金(sprina)   2021-08-26   557

    电话面,不定时突然打过来问现在是否方便面试。 主要考察点:项目的具体实现,项目中遇到的难点,框架底层原理的认识。感觉问的比一般面试难,很注重细节和深度

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

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

    三. 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.技术选型

    这里结合自己实际工作中的体会来讲会更好,找了个大佬的参考www.cnblogs.com/pengfei-nie…

    四. 讲一下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属性,当它在当前层级的位置发生了变化后。react diff算法通过新旧节点比较后,如果发现了key值相同的新旧节点,就会执行移动操作(然后依然按原策略深入节点内部的差异对比更新),而不会执行原策略的删除旧节点,创建新节点的操作。这无疑大大提高了React性能和渲染效率

    五. 讲一下 react 的生命周期

    挂载阶段

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

    • constructor

    • getDerivedStateFromProps

      取代之前的componentWillMount、componentWillReceiveProps和componentWillUpdate

    • componentWillMount

    • render

    • componentDidMount

    更新阶段

    当组件的props改变了,或组件内部调用了setState或者forceUpdate发生,会发生多次

    • componentWillReceiveProps/UNSAFE_componentWillReceiveProps

    • getDerivedStateFromProps

    • shouldComponentUpdate

      当组件接收到新属性,或者组件的状态发生改变时触发。组件首次渲染时并不会触发。一般我们通过该函数来优化性能:一个React项目需要更新一个小组件时,很可能需要父组件更新自己的状态。而一个父组件的重新更新会造成它旗下所有的子组件重新执行render()方法,形成新的虚拟DOM,再用diff算法对新旧虚拟DOM进行结构和属性的比较,决定组件是否需要重新渲染

      无疑这样的操作会造成很多的性能浪费,所以我们开发者可以根据项目的业务逻辑,在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的区别

    • get用来获取数据,post用来提交数据

    • get参数有长度限制(受限于url长度,具体的数值取决于浏览器和服务器的限制,最长2048字节),post无限制。

    • get请求的数据会附加在url之后,以 " ? "分割url和传输数据,多个参数用 "&"连接,数据在URL中可以看到。而post请求会把请求的数据放在http请求体中。

    • get是明文传输,post是放在请求体中,但是开发者可以通过抓包工具看到,也相当于是明文的。

    • get请求会保存在浏览器历史记录中,还可能保存在web服务器的日志中

    • GET产生的URL地址可以被Bookmark,而POST不可以。

    • GET请求会被浏览器主动cache,而POST不会,除非手动设置。

    • get方式,服务器端用Request.QueryString获取变量的值,对于post方式,服务器端用Request.Form获取提交的数据。
    • GET产生一个TCP数据包;POST产生两个TCP数据包。对于GET方式的请求,浏览器会把http header和data一并发送出去,服务器响应200(返回数据);而对于POST,浏览器先发送header,服务器响应100 continue,浏览器再发送data,服务器响应200 ok(返回数据)。

    参考

    Vue与React两个框架的区别和优势对比 segmentfault.com/a/119000003… react diffing算法中key的作用 juejin.cn/post/696762… get和post区别 www.cnblogs.com/logsharing/…


    起源地下载网 » 阿里蚂蚁集团-前端秋招一面面经

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元