谈谈前端面试中遇到的问题(一)

前言

歇了一个多月,终因而拿了驾照,也算是完成了人生计划中的其中一个,没有过去2019年。css

2019年的所有计划估计是完不成了,想要完成多少,仍是要看接下来的努力。react

歇息了一个月,最近刚刚开始面试,前两个面试是一点准备都没有,去面试也仅仅是考虑一下本身如今的状况,有目的的去准备面试。面试

一个多月,感受忘记了不少,在此记下面试中遇到的问题,以来自勉。redux

题目

一、React context是如何工做的?数组

更多的时候,咱们在组件层级间进行数据传递,都会用到props,可是若是须要传递的子属性太多,个人组件属性就有可能会写得很长。而这时候,context或许是个解决方案。promise

context做用是为了不在组件间层层传递变量。咱们能够经过createContext(null)来建立一个新的context,新建立的context包含一个Provider以及一个Consumer。浏览器

若是咱们想要在组件间层层传递变量,则须要用Provider来包裹父组件,在Provider包裹下的层层组件,均可以经过Consumer包裹子组件来读取传递的变量。缓存

二、react兄弟组件间通讯方式服务器

第一种笨方法,子组件1传递给父组件,接着传递给子组件2.app

第二种利用事件的发布订阅。

第三种你们都知道,用redux管理数据。原理和第一种+第二种差很少,不过是更规范的数据管理和数据流传递和事件发布订阅方式。

三、setState原理

先说明,setState既能够同步也能够异步。好比在setTimeout的包裹中setState会当即执行。咱们正常方式下的setState是异步状态,由于React中的状态合并,使得屡次操做,在最终的一次时间点作数据更新,避免每次都执行DOM操做耗费性能。

那么setState的原理大体能够描述为:设置新的state会将这个新的state存储在一个状态队列,若是达到批量更新的节点,则进行状态合并,更新成组件最终的state或者props。

而setState就是将新的状态放置在状态队列中的操做函数,由此也能够知道,若是直接更改state,如this.state = 1这样的操做,并不会直接更新状态队列的,因此这个操做是无效的。

这个只是简单的回答,若是要从源码上回答,还得知道setState的事务机制。

四、PureComponent和Component的区别

PureComponent会帮助咱们在shouldComponentUpdate生命周期中进行一次浅比较。

浅比较只检查值类型的值和引用类型的引用是否相等,若是要作比较深刻的判断,仍是应该在shouldComponentUpdate生命周期自行判断。

五、如何避免重复渲染。

这个问题,其实也至关因而React性能问题的一个。

首先,不要在render中为函数绑定参数,每次参数更改都会建立新的函数,则会刷新组件或者子组件。

其次,尽可能不要使用派生数据绑定到组件属性,每次传递props都会生成新的数据,即便数据同样,也会致使重复渲染。

还有,组件设定的key值要和里和固定,这样当数据一致和key一致的时候,组件也不会从新渲染。

最终,你还能够修改shouldComponentUpdate生命周期返回值来手动达到不重复渲染的目的。

六、getDerivedStateFromProps干了什么?

getDerivedStateFromProps是React16.3中新增的一个静态的生命周期函数,将来即将移除的神明周期有三个:componentWillMount `,componentWillReceiveProps ,componentWillUpdate

这个生命周期是映射props到state上,至关因而执行setState操做。因此,每次父组件发生props变化,都会执行setState操做。这也可能致使重复渲染,感受尽可能也减小使用吧。

getDerivedStateFromProps 是一个静态方法, 是一个和组件自身"不相关"的角色. 在这个静态方法中, 除了两个默认的位置参数 nextProps 和 currentState 之外, 你没法访问任何组件上的数据.

七、解析HTTP 304 状态码

数据请求的时候,若是服务器发现客户端有缓存,而且时间没过时,则返回304状态。

请求头中的Last Modified和f Modified Since来进行比较判断是否须要返回304,或者更新数据返回200.

八、什么是高阶组件?

咱们知道函数的参数是函数,返回的是新的函数,则称为高阶函数。

高阶组件是返回组件的组件,也就是传递参数是组件,对这个组件进行加工成为一个新的组件并返回。

他用来干什么?通常用来属性代理,也就是把本来的props和新的props组合成一个新的组件的属性。因此,咱们若是要建立一个loading效果组件,或者是成功失败等状态组件,能够用高阶组件来实现。

九、for...of能遍历什么?

可迭代对象。如Arrays(数组), Strings(字符串), Maps(映射), Sets(集合)等。

十、如何避免遍历到原型上的属性?

第1、for..in + hasOwnProperty方法

第2、Object.keys()

十一、事件循环。

JavaScript是单线程执行模型,执行的时候将会区分为主线程和任务队列。主线程执行完毕,会从任务队列中读取新的任务放入主线程进行执行,这个读取过程是循环读取,因此也叫事件循环。

任务队列分为宏任务和微任务,同层次,先执行微任务,再执行宏任务。

微任务:promise.then()、process.nextTick()

宏任务:setTimeOut()、setInterval()

十二、浏览器的渲染流程

这个问题应该就是输入url到页面呈现问题的变种,只不过此时的侧重点是获取完数据以后进行的渲染流程。

根据李兵老师的浏览器工做原理一节作以下回答:

第一步,HTML转换成DOM

第二步,CSS转换成浏览器可理解的styleSheets,而后计算DOM节点的样式

第三步,建立布居树,计算元素的布局信息

第四步,对布居树进行分层,构建分层树

第五步,为每一个图层生产绘制列表,并将其提交到合成线程

第六步,合成线程将图层转化为图块,进而将图块转化成位图

第七步,合成线程发送绘制命令给浏览器

第八步,浏览器根据绘制命令生成页面,并显示到显示器上。

1三、deffer和async的区别

浏览器脚本,在普通的状况下,是会依次执行。可是咱们能够用deffer和async关键字来让脚本异步执行。

可是,deffer是按照加载顺序执行DOMContentLoaded以前执行,可是async则是脚本加载完毕以后当即执行(不考虑依赖以及DOM的加载状态),通常来讲,deffer要比async好一点。

1四、DOM选择器中,querySelectorAll和getElementByClass的区别?

querySelectorAll 返回的是一个 Static Node List,而 getElementsBy 系列的返回的是一个 Live Node List。

因此静态节点列表至关因而快照,不影响文档操做,因此咱们能够遍历循环querySelectorAll生产的数据。

可是动态节点列表,若是咱们的一些查询和操做就会变成死循环。

从性能上来说,getElementByClass要更快。

1五、map和forEach的区别

forEach返回undefined,map会返回新的数组。

forEach没办法停止循环,可是map能够经过返回false或者出错来停止。

1六、call、apply以及bind的区别。

三者都是改变this执行,不一样的是,call和apply是直接生成了函数调用,而bind则是返回了一个函数,你须要再次执行才会达到相同的效果。

call和apply又是由于参数的传递方式不同,apply传递的是数组,call传递的单个参数的陈列。

bind则是以函数调用参数的方式传递参数。

1七、css中的box-sizing

懵逼了,不知道是啥,以前根本没用过。

查了下,box-sizing 属性容许你以某种方式定义某些元素,以适应指定区域。例如,假如您须要并排放置两个带边框的框,可经过将 box-sizing 设置为 "border-box"。这可令浏览器呈现出带有指定宽度和高度的框,并把边框和内边距放入框中。

box-sizing的值有三个,content-box:只有内容、border-box:包括边框、inherit:继承自父元素。

总结

刚开始面试,有些生疏,而且有时候明明记得,却死活想不起来,大概是太长时间没有思考技术的缘由。过后仔细思考,以为这些问题都是很基础,很简单的题目,只要好好准备一下,应该仍是慢慢会好起来的。

个人博客:http://www.gaoyunjiao.fun/?p=163

相关文章
相关标签/搜索