2020 前端面试


2020 前端面试 | 第二波面试题总结


前言

哈,看样子年后跳槽还是大家比较关心的一件事情了,继第一波面试题汇总的反响和评论,观看和点赞的朋友们很多,我继续将后续面试的一些内容写出来,有很多面试题答案我自己写的比较含糊,但是在面试的过程中是描述的表较多的。毕竟写文字要写出来太多了。我也只是写了一个大概,如果对答案不太满意的同学可以自行查询标准答案哈。

2020 前端面试 | 第一波面试题总结

对了,有很多朋友说面试题过于简单都是基础之类的,实际上我本身也就是一个初中级的水平,所以面试的公司职位和对应的薪资匹配的就是这类的问题,算法题基本很少面试到。

薪资范围:11k-14k

技术能力:自身能力强和扩展性高的可以自己跟HR多谈多要

面试建议:请勿态度高冷,聊天请等对方说完再回答,切勿抱怨和说上家公司的缺点

面试重点:JavaScript基础需要掌握得好,即使有些框架的原理和区别说不上来也没事

最后总结:本人还在面试中,如有贵公司在招聘初中级请联系我哈

面试题汇总

  • 请描述一下 React 和 Vue的区别

这道题你如果熟知的话,从各个方面的不同点,原理,为什么这样实现来描述,起吗聊个半个小时。后续就不会问你太多问题了。

<code>1.设计思想
vue的官网中说它是一款渐进式框架,采用自底向上增量开发的设计。

react主张函数式编程,所以推崇纯组件,数据不可变,单向数据流,当然需要双向的地方也可以手动实现,
比如借助 onChange 和 setState 来实现一个双向的数据流。
2.编写语法
Vue推荐的做法是webpack+vue-loader的单文件组件格式,vue保留了html、css、js分离的写法

React的开发者可能知道,react是没有模板的,直接就是一个渲染函数,它中间返回的就是一个虚拟DOM树,

React推荐的做法是 JSX + inline style, 也就是把HTML和CSS全都写进JavaScript了,即'all in js'。
3.构建工具
vue提供了CLI 脚手架,可以帮助你非常容易地构建项目。

React 在这方面也提供了 create-react-app,但是现在还存在一些局限性,不能配置等等
4.数据绑定
vue是实现了双向数据绑定的mvvm框架,当视图改变更新模型层,当模型层改变更新视图层。
在vue中,使用了双向绑定技术,就是View的变化能实时让Model发生变化,而Model的变化也能实时更新到View。
(这里我们可以继续深入讲解一下双向数据绑定的原理,我之前的文章手写Vue源码可参考)

react是单向数据流,react中属性是不允许更改的,状态是允许更改的。
react中组件不允许通过this.state这种方式直接更改组件的状态。自身设置的状态,可以通过setState来进行更改。
(注意:React中setState是异步的,导致获取dom可能拿的还是之前的内容,
所以我们需要在setState第二个参数(回调函数)中获取更新后的新的内容。)

【这里如果你了解深入的话可以尝试描述一下React中setState的异步操作是怎么实现的,Vue中的更新是通过微任务等】

5.diff算法
vue中diff算法实现流程:
1.在内存中构建虚拟dom树
2.将内存中虚拟dom树渲染成真实dom结构
3.数据改变的时候,将之前的虚拟dom树结合新的数据生成新的虚拟dom树
4.将此次生成好的虚拟dom树和上一次的虚拟dom树进行一次比对(diff算法进行比对),来更新只需要被替换的DOM,
而不是全部重绘。在Diff算法中,只平层的比较前后两棵DOM树的节点,没有进行深度的遍历。
5.会将对比出来的差异进行重新渲染

react中diff算法实现流程:
DOM结构发生改变-----直接卸载并重新create
DOM结构一样-----不会卸载,但是会update变化的内容
所有同一层级的子节点.他们都可以通过key来区分-----同时遵循1.2两点
(其实这个key的存在与否只会影响diff算法的复杂度,换言之,你不加key的情况下,
diff算法就会以暴力的方式去根据一二的策略更新,但是你加了key,diff算法会引入一些另外的操作)/<code>

React会逐个对节点进行更新,转换到目标节点。而最后插入新的节点,涉及到的DOM操作非常多。diff总共就是移动、删除、增加三个操作,而如果给每个节点唯一的标识(key),那么React优先采用移动的方式,能够找到正确的位置去插入新的节点。

vue会跟踪每一个组件的依赖关系,不需要重新渲染整个组件树。而对于React而言,每当应用的状态被改变时,全部组件都会重新渲染,所以react中会需要shouldComponentUpdate这个生命周期函数方法来进行控制。

以上内容来自于Vue 和 React 的优点分别是什么?,大家说的越多理解的越深越好。我只说了其中的三点。

  • 前端常用的数据请求格式有哪些?都有些什么特点?

这个问题在http中已经回答了一部分了,这里就在单独详细的描述一下使用场景

<code>Get/Post/Delete/Patch/Put经常用的这五种,其他的就不说了

通常:
我们使用Get请求来获取数据
我们使用Post请求来发送数据
我们使用Put请求来更新数据
我们使用Delete请求来删除数据
我们使用Patch请求用于对资源应用部分修改。
Get和Post的区别:
1.Get 请求能缓存,Post 不能
2.Post 相对 Get 安全一点点,因为Get 请求都包含在 URL 里,

(当然你想写到 body 里也是可以的),且会被浏览器保存历史纪录。Post 不会,但是在抓包的情况下都是一样的。
4.URL有长度限制,会影响 Get 请求,但是这个长度限制是浏览器规定的,不是 RFC 规定的
5.Post 支持更多的编码类型且不对数据类型限制/<code>
  • 二次封装axios,描述一下你在项目中封装axios的思路和想法
<code>关于axios等封装,我之前有一篇简易封装axios的文章,大家可以简单参考。

通常来说,我们在二次封装axios,一般会引入UI组件的一些Message和Loading组件用来做提示信息。
1.通过获取存储在浏览器端,或者是vuex中的token信息,判断是否跳转登录页面
2.在获取到token的情况下设置自定义请求头部信息
3.在响应事件中,根据返回的不同状态码,根据业务需求,使用switch判断跳转页面还是发出提示信息。
4.封装请求和响应事件的返回结果,使用Promise封装。
5.增加请求loading和提示信息。
简单版本大致如上,复杂版本需要根据业务进行对应的封装。/<code>
  • 请介绍一下this
<code>其实大部分情况下可以用一句话来概括,this总是指向调用该函数的对象。

对于常规的函数来说,谁调用该函数,this就指向该调用者,全局环境下调用函数执行,this指向window

对于箭头函数的this总结如下:

箭头函数不绑定this,箭头函数中的this相当于普通变量。

箭头函数的this寻值行为与普通变量相同,在作用域中逐级寻找。

箭头函数的this无法通过bind,call,apply来直接修改(可以间接修改)。

改变作用域中this的指向可以改变箭头函数的this。

描述this问题,这里我们可以扩展说明如何去改变this指向,通过bind,call,apply,然后说说他们的区别,懂得多的话,
可以说说他们的实现原理,或者手写bind,call,apply的实现。/<code>
  • 请介绍一下节流函数和防抖函数,简单实现节流函数和防抖函数
<code>“节流”与“防抖”的本质: 这两个东西都以闭包的形式存在。

它们通过对事件对应的回调函数进行包裹、以自由变量的形式缓存时间信息,最后用 setTimeout 来控制事件的触发频率。

防抖函数:有这样一个按钮,他提供查看你未来老婆的样子,当你在一定时间内多次点击查询时,他只会在你最后一次点击以后,
采取执行查询操作。

节流函数:当你在玩LOL的时候,你在放出大招后的一段时间内,再次点击放大招是不启作用的,因为有一个冷却时间。

代码我就不写在这里了,简易版本的很简单,完整版封装一般我们都使用lodash封装好的。/<code>
  • 请介绍一下Eventloop(事件循环)
<code>搞懂 Event Loop,是理解 Vue 对 DOM 操作优化的第一步。

Micro-Task 与 Macro-Task
事件循环中的异步队列有两种:macro(宏任务)队列和 micro(微任务)队列。

常见的 macro-task 比如:
setTimeout、setInterval、 setImmediate、script(整体代码)、 I/O 操作、UI 渲染等。
常见的 micro-task 比如:
process.nextTick、Promise、MutationObserver 等。

大家也知道了当我们执行 JS 代码的时候其实就是往执行栈中放入函数,当遇到异步的代码时,会被挂起并在需要执行的时候,
加入到 Task(有多种 Task) 队列中。
一旦执行栈为空,Event Loop 就会从 Task 队列中拿出需要执行的代码并放入执行栈中执行,
所以本质上来说 JS 中的异步还是同步行为。

所以 Event Loop 执行顺序如下所示:

首先执行同步代码,这属于宏任务
当执行完所有同步代码后,执行栈为空,查询是否有异步代码需要执行
执行所有微任务
当执行完所有微任务后,如有必要会渲染页面
然后开始下一轮 Event Loop,执行宏任务中的异步代码,也就是 setTimeout 中的回调函数

这里很多人会有个误区,认为微任务快于宏任务,其实是错误的。
因为宏任务中包括了>
  • 请用一个例子来形象的描述原型链

哈,这个问题我在沸点有发过一个形象的比喻,给面试官逗笑了。

<code>每个门派都有一个祖师爷。

学徒在山上学艺,学成下山后谨记师门教导,施展一身武艺。

恰逢一日对敌,面对敌人的怪异武功,师门好像未曾教过破解之法,便高喊一声祖师爷救我,

刹那间一道白光降于头顶,祖师爷灵魂附体,一套精绝凌厉的拳法杀得敌人措手不及。

但敌人也极是难缠,恐怕非要那门传说中从天而降的掌法才能制敌。

你心中暗自着急,催促着祖师爷赶快发招,这时只听身内传来了祖师的声音:

“MD这破掌法当年偷懒没学,我去把我师祖也叫来问问...”

每个门派(FunctionX)都有一个祖师爷(prototype)。

学徒(object)在山上学艺(= new FunctionX),学成下山后谨记师门教导,


施展一身武艺(http://object.xxxobject.xxx)。

恰逢一日对敌,面对敌人的怪异武功,师门好像未曾教过破解之法(object对象没有yyy方法),

便高喊一声祖师爷救我,刹那间一道白光降于头顶,祖师爷(__proto__)灵魂附体,

一套精绝凌厉的拳法杀得敌人措手不及(继续寻找原型中是否有yyy方法)。

但敌人也极是难缠,恐怕非要那门传说中从天而降的掌法才能制敌。你心中暗自着急,

催促着祖师爷赶快发招,这时只听身内传来了祖师的声音:

“MD这破掌法当年偷懒没学,我去把我师祖也叫来问问...”(如果原型中没有yyy方法,则继续查找原型的原型,是谓原型链)/<code>
  • 请介绍一下回流(Reflow)与重绘(Repaint)
<code>回流:当我们对 DOM 的修改引发了 DOM 几何尺寸的变化(比如修改元素的宽、高或隐藏元素等)时,
浏览器需要重新计算元素的几何属性(其他元素的几何属性和位置也会因此受到影响),

然后再将计算的结果绘制出来。这个过程就是回流(也叫重排)。

重绘:当我们对 DOM 的修改导致了样式的变化、却并未影响其几何属性(比如修改了颜色或背景色)时,
浏览器不需重新计算元素的几何属性、直接为该元素绘制新的样式(跳过了上图所示的回流环节)。这个过程叫做重绘。

由此我们可以看出,重绘不一定导致回流,回流一定会导致重绘。
硬要比较的话,回流比重绘做的事情更多,带来的开销也更大。但这两个说到底都是吃性能的,
所以都不是什么善茬。我们在开发中,要从代码层面出发,尽可能把回流和重绘的次数最小化。/<code>

尾声

至此2020年我所面试的公司大部分面试题都包含了以上内容,至于一些代码图解之类的问题我就没有写上去,太简单了,相信大家都会。后续一些细枝末节的地方我会补充。

最后希望我所总结的面试内容能够对你在2020年的面试中有所帮助。

❤️ 看完帮个忙

如果你觉得这篇内容对你挺有启发,我想邀请你帮我个小忙:

点赞/收藏/转发,让更多的人也能看到这篇内容(收藏不点赞,都是耍流氓 -_-)


分享到:


相關文章: