面试题练习第二篇
- 1.Vue组件通信?
- 2.说说你对vuex的理解?写出其原理的核心代码?
- 3.说说React生命周期中有哪些坑?如何避免?
- 4.说说你对React中虚拟dom的理解?
- 5.调和阶段setState干了什么?
- 6.React组件之间如何通信?
- 7.说说redux的实现原理是什么,写出其原理的核心代码?
- 8.说说Connect组件的原理是什么?
- 9.说说react 中jsx语法糖的本质?
- 10.说说你对redux中间件的理解?常用的中间件有哪些?实现原理?
- 11.props和state相同点和不同点?render方法在哪些情况下会执行?
- 12.react新出来两个钩子函数是什么?和删掉的will系列有什么区别?
- 13.CDN的特点及意义?
- 14.什么是闭包,应用场景是什么?
- 15.从浏览器地址栏输入url到显示页面的步骤?
- 16.介绍一下你对浏览器内核的理解?
- 17.清除浮动的几种方式?各自的优缺点?
- 18.说说你对koa中洋葱模型的理解?
- 19.如果需要手动写动画,你认为最小时间间隔是多久,为什么?
- 20.说说你对webSocket的理解?
1.Vue组件通信?
- props 和 $emit (常用)
- ref / refs
- eventBus-中央事件总线($emit / $on)(非父子组件间通信)
- $attrs 和 $listeners
- $parent和 $children
- provide和inject (依赖注入)
- vuex
vue组件之间的通信6种
父子通信:props
/ $emit
兄弟通信:eventBus
($emit
/ $on
)
vue 的状态管理器,存储的数据是响应式:vuex
多级组件嵌套:$attrs
/ $listeners
/ inheritAttrs
注入依赖:provide
/inject
组件访问:$parent
/ $children
与 ref
props和 $emit
父组件向子组件传递数据是通过prop
传递的,子组件传递数据给父组件是通过$emit
触发事件来做到的。
ref / refs
为子组件绑定 ref
,父组件通过调用refs
调用子组件的方法或属性
eventBus-中央事件总线($emit / $on)
eventBus
事件总线适用于父子组件、非父子组件等之间的通信
新建一个Vue
事件bus
对象,然后通过bus.$emit
触发事件,bus.$on
监听触发的事件。
$attrs/ $listeners 针对跨级通信
对于多层嵌套比较方便,每层都去绑定事件和属性,
$attrs
和 $listeners
是两个对象,$attrs
里存放的是父组件中绑定的非 props
属性,$listeners
里存放的是父组件中绑定的非原生事件。inheritAttrs
选项则为是否挂载到组件元素的attribute
。
$parent 和 $children
在组件内部可以直接通过子组件$parent
对父组件进行操作,父组件通过$children
对子组件进行操作
provide/inject
父组件通过provide
提供值
子组件通过inject
获取值
vuex处理组件之间的数据交互
如果业务逻辑复杂,很多组件之间需要同时处理一些公共的数据,这个时候才有上面这一些方法可能不利于项目的维护,vuex
的做法就是将这一些公共的数据抽离出来,然后其他组件就可以对这个公共数据进行读写操作,这样达到了解耦的目的。
父子通信:
- 父向子传递数据是通过
props
,子向父是通过events
($emit
) - 通过父链 / 子链也可以通信(
$parent / $children
) ref
也可以访问组件实例provide / inject API
$attrs/$listeners
兄弟通信:
Bus
Vuex
跨级通信:
Bus
Vuex
provide / inject
$attrs / $listeners
2.说说你对vuex的理解?写出其原理的核心代码?
什么是vuex
Vuex
是一个专为 Vue.js
应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
通过定义和隔离状态管理中的各种概念并通过强制规则维持视图和状态间的独立性,我们的代码将会变得更结构化且易维护。
Vuex
是专门为Vue.js
设计的状态管理库,以利用 Vue.js 的细粒度数据响应机制
来进行高效的状态更新。
vuex的五大核心属性:state,getter,mutation,action,module
state:用于存储维护组件的公共状态
state:存储数据,存储状态;在根实例中注册了
store
后,用this.$store.state
来访问;对应vue
里面的data
;存放数据方式为响应式,vue
组件从store
中读取数据,如数据发生变化,组件也会对应的更新。
getters:用于对state中的数据进行相关处理后并返回,类似于计算属性
getter:可以认为是
store
的计算属性,它的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算。
mutations:是修改state的唯一途径,进行的是同步操作
mutation:更改
Vuex
的store
中的状态的唯一方法是提交mutation
。
actions:要执行的操作,可以是同步或异步事件
action:包含任意异步操作,通过提交
mutation
间接更变状态。
modules:内部可以存放多个仓库配置对象,用于对仓库进行模块划分
module:将
store
分割成模块,每个模块都具有state
、mutation
、action
、getter
、甚至是嵌套子模块。
vuex的工作流程
- 通过
dispatch
去提交一个actions
- 在
actions
接收到事件后,在actions
中执行一些同步或异步操作 - 根据不同的情况分发给不同的
mutations
,actions
通过commit
触发mutations
mustations
在触发后就会去更新state
- 在
state
更新完毕后,就会通知vue
进行渲染
3.说说React生命周期中有哪些坑?如何避免?
-
getDerivedStateFromProps
容易编写反模式代码,使受控组件和非受控组件区分模糊 -
componentWillMount
在React
中已被标记弃用,不推荐使用,主要的原因是因为新的异步架构会导致它被多次调用,所以网络请求以及事件绑定应该放到componentDidMount
中 -
componentWillReceiveProps
同样也被标记弃用,被getDerivedStateFromProps
所取代,主要原因是性能问题。 -
shouldComponentUpdate
通过返回true
或者false
来确定是否需要触发新的渲染。主要用于性能优化。 -
componentWillUpdate
同样是由于新的异步渲染机制,而被标记废弃,不推荐使用,原先的逻辑可结合getSnapshotBeforeUpdate
与componentDidUpdate
改造使用。
如果在 componentWillUnmount
函数中忘记解除事件绑定,取消定时器等清理操作,容易引发 bug
。
如果没有添加错误边界处理,当渲染发生异常时,用户将会看到一个无法操作的白屏,所以一定要添加。
4.说说你对React中虚拟dom的理解?
虚拟 DOM
不会进行排版与重绘操作,而真实 DOM
会频繁重排与重绘
使用虚拟 DOM
的优势如下:
简单方便: 如果使用手动操作真实 DOM
来完成页面,繁琐又容易出错,在大规模应用下维护起来也很困难
性能方面: 使用 Virtual DOM
,能够有效避免真实 DOM
数频繁更新,减少多次引起重绘与回流,提高性能
跨平台:React
借助虚拟 DOM
,带来了跨平台的能力,一套代码多端运行
缺点:
- 在一些性能要求极高的应用中
虚拟 DOM
无法进行针对性的极致优化 - 首次渲染大量
DOM
时,由于多了一层虚拟 DOM
的计算,速度比正常稍慢
5.调和阶段setState干了什么?
(1)代码中调用 setState
函数之后,React
会将传入的参数对象与组件当前的状态合并,然后触发所谓的调和过程(Reconciliation
)。
(2)经过调和过程,React
会以相对高效的方式根据新的状态构建 React
元素树并且着手重新渲染整个 UI 界面;
(3)在 React
得到元素树之后,React
会自动计算出新的树与老树的节点差异,然后根据差异对界面进行最小化重渲染;
(4)在差异计算算法中,React
能够相对精确地知道哪些位置发生了改变以及应该如何改变,这就保证了按需更新,而不是全部重新渲染。
6.React组件之间如何通信?
-
父组件向子组件通讯:
父组件可以向子组件传入props
的方式,向子组件进行通讯。 -
子组件向父组件通讯:
props
+回调的方式,父组件向子组件传递props
进行通讯,此props
为作用域为父组件自身的函数,子组件调用该函数,将子组件想要传递的信息,作为参数,传递到⽗组件的作⽤域中。 -
兄弟组件通信:
兄弟组件之间的传递,则父组件作为中间层来实现数据的互通,通过使用父组件传递
例:组件A – 传值 --> 父组件 – 传值 --> 组件B -
跨层级通讯:
Context
设计⽬的是为了共享那些对于⼀个
组件树⽽⾔是“全局”的数据,
使用context
提供了组件之间通讯的一种方式,可以共享数据,其他数据都能读取对应的数据
例如当前认证的⽤户、主题或⾸选语⾔,对于跨越多层的全局数据通过Context
通信再适合不过。 -
发布订阅者模式:
发布者发布事件,订阅者监听事件并做出反应,我们可以通过引⼊event
模块进⾏通信。 -
全局状态管理工具:
借助Redux
或者Mobx
等全局状态管理⼯具进⾏通信,这种⼯具会维护⼀个全局状态中⼼Store
,并根据不同的事件产⽣新的状态。
7.说说redux的实现原理是什么,写出其原理的核心代码?
原理
- 将应用的状态统一放到
state
中,由store
来管理state
。 reducer
的作用是 返回一个新的state
去更新store
中对用的state
。- 按
redux
的原则,UI层
每一次状态的改变都应通过action
去触发,action
传入对应的reducer
中,reducer
返回一个新的state
更新store
中存放的state
,这样就完成了一次状态的更新 subscribe
是为store
订阅监听函数,这些订阅后的监听函数是在每一次dipatch
发起后依次执行- 可以添加中间件对提交的
dispatch
进行重写
核心API
createStore
创建仓库,接受reducer
作为参数bindActionCreator
绑定store.dispatch
和action
的关系combineReducers
合并多个reducers
applyMiddleware
洋葱模型的中间件,介于dispatch
和action
之间,重写dispatch
compose
整合多个中间件
8.说说Connect组件的原理是什么?
connect
是一个高阶函数,它真正连接 Redux
和 React
,包在我们的容器组件的外一层,接收上面 Provider
提供的 store
里面的 state
和 dispatch
,传给一个构造函数,返回一个对象,以属性形式传给我们的容器组件。
原理:
首先传入mapStateToProps
、mapDispatchToProps
,然后返回一个生产Component
的函数(wrapWithConnect
),然后再将真正的Component
作为参数传入wrapWithConnect
,这样就生产出一个经过包裹的Connect
组件,该组件具有:
(1)通过props.store
获取祖先Component
的store
(2)props
包括stateProps
、dispatchProps
、parentProps
,合并在一起得到nextState
,作为props
传给真正的Component
(3)componentDidMount
时,添加事件this.store.subscribe(this.handleChange)
,实现页面交互
(4)shouldComponentUpdate
时判断是否有避免进行渲染,提升页面性能,并得到nextState
(5)componentWillUnmount
时移除注册的事件this.handleChange
9.说说react 中jsx语法糖的本质?
Jsx
是语法糖,实质是js函数
,需要babel
来解析,核心函数是React.createElement(tag,{attrbuties},children)
,参数tag
是标签名可以是html
标签和组件名,attrbuties
参数是标签的属性,children
参数是tag
的子元素。用来创建一个vnode
,最后渲染到页面上。
10.说说你对redux中间件的理解?常用的中间件有哪些?实现原理?
理解:
中间件是介于应用系统和系统软件之间的一类软件,它使用系统软件所提供的基础服务(功能),衔接网络上应用系统的各个部分或不同的应用,能够达到资源共享、功能共享的目的
Redux
中,中间件就是放在就是在dispatch
过程,在分发action
进行拦截处理
本质上一个函数,对store.dispatch
方法进行了改造,在发出 Action
和执行 Reducer
这两步之间,添加了其他功能
常用中间件:
redux-thunk:
用于异步操作
redux-logger:
用于日志记录
实现原理:
所有中间件被放进了一个数组chain
,然后嵌套执行,最后执行store.dispatch
。可以看到,中间件内部(middlewareAPI
)可以拿到getState
和dispatch
这两个方法内部会将dispatch
进行一个判断,然后执行对应操作
11.props和state相同点和不同点?render方法在哪些情况下会执行?
不同点:
- props 是外部传递给组件的,而 state 是在组件内被组件自己管理的,一般在 constructor 中初始化
- props 在组件内部是不可修改的,但 state 在组件内部可以进行修改
- state 是多变的、可以修改
相同点:
- 两者都是 JavaScript 对象
- 两者都是用于保存信息
- props 和 state 都能触发渲染更新
触发时机
render
的执行时机主要分成了两部分:
- 类组件调用
setState
修改状态 - 函数组件通过
useState hook
修改状态
12.react新出来两个钩子函数是什么?和删掉的will系列有什么区别?
新增了下面两个生命周期方法:
getDerivedStateFromProps
getSnapshotBeforeUpdate
getDerivedStateFromProps 该方法类似于 componentWillReceiveProps
,可以用来控制 props
更新 state
的过程。它返回一个对象表示新的 state
。如果不需要更新组件,返回 null
即可。
用 getDerivedStateFromProps替换了 compoentWillMount
和compontWillReceiveProps
生命周期函数,解决还未渲染完成Dom
导致绑定的方法存在内存中,造成内存泄露
getSnapshotBeforeUpdate 方法在 React
对视图做出实际改动(如 DOM
更新)发生前被调用,返回值将作为 componentDidUpdate
的第三个参数。
用getSnapshotBeforeUpdate函数替换componetWillUpdate
方法,避免和CompoentDidUpdate
函数中获取数据不一致的问题
13.CDN的特点及意义?
CDN 意为内容分发网络,是基于现有网络的智能虚拟网络,分布在世界各地的边缘服务器上。
基本思路:
避免互联网上可能影响数据传输速度和稳定性的瓶颈和环节,使内容传输更快更稳定。
特点
本地缓存加速: 提高了企业网站(尤其是包含大量图片和静态页面的网站)的访问速度,大大提高了上述网站的稳定性。
镜像服务: 消除了不同运营商之间互联瓶颈带来的影响,实现了跨运营商的网络加速,保证了不同网络的用户都能获得良好的接入质量。
远程加速: 远程访问用户根据DNS
负载均衡技术智能自动选择缓存服务器,选择最快的缓存服务器加速远程访问。
带宽优化: 自动生成服务器的远程镜像缓存服务器。远程用户访问时,可以从缓存服务器读取数据,减少远程访问的带宽,分担网络流量,减轻原WEB
服务器的负载。
集群抗攻击: 广泛分布的CDN
节点加上节点间的智能冗余机制,可以有效防止黑客入侵,降低各种D.D.O.S
攻击对网站的影响,同时保证更好的服务质量。
14.什么是闭包,应用场景是什么?
闭包(closure
)指有权访问另一个函数作用域中变量的函数。
简单理解就是 ,一个作用域可以访问另外一个函数内部的局部变量。
闭包形成的条件
- 函数嵌套
- 将内部函数作为返回值返回
- 内部函数必须使用到外部的变量
闭包的使用场景
setTimeout
- 回调
- 函数防抖
- 封装私有变量
15.从浏览器地址栏输入url到显示页面的步骤?
- 浏览器的地址栏输入URL并按下回车。
- 浏览器查找当前URL是否存在缓存,并比较缓存是否过期。
- DNS解析URL对应的IP。
- 根据IP建立TCP连接(三次握手)。
- 发起HTTP请求。
- 服务器处理请求,浏览器接收HTTP响应。
- 渲染页面,构建DOM树。
- 关闭TCP连接(四次挥手)。
16.介绍一下你对浏览器内核的理解?
浏览器内核是浏览器的核心,也称“渲染引擎
”,用来解释网页语法并渲染到网页上,浏览器内核决定了浏览器该如何显示网页内容以及页面的格式信息
浏览器内核主要分成两部分: 渲染引擎(layout engineer
或Rendering Engine
)和JS引擎。
渲染引擎:
负责取得网页的内容(HTML
、XML
、图像等等)、整理讯息(例如加入CSS
等),以及计算网页的显示方式,然后会输出至显示器或打印机。
JS引擎:
解析和执行javascript
来实现网页的动态效果。
17.清除浮动的几种方式?各自的优缺点?
方法一:额外标签法
给谁清除浮动,就在其后额外添加一个空白标签 ,给其设置clear:both
。
优点: 通俗易懂,书写方便。
缺点: 添加许多无意义的标签,结构化比较差。
clear:both
:本质就是闭合浮动, 就是让父盒子闭合出口和入口,不让子盒子出来 。
方法二:父元素添加overflow:hidden 通过触发BFC方式,实现清除浮动
优点: 代码简洁
缺点: 内容增多的时候容易造成不会自动换行导致内容被隐藏掉,无法显示要溢出的元素。
方法三:使用after伪元素清除浮动
优点: 符合闭合浮动思想,结构语义化正确。
缺点:ie6-7
不支持伪元素:after
,使用zoom:1
触发
方法四:使用before和after双伪元素清除浮动
优点: 代码更简洁
缺点: 用zoom:1
触发hasLayout
.
方法五:为父元素设置高度
优点: 简单粗暴直接有效,清除了浮动带来的影响
缺点: 需要手动添加高度,如何后面的高度发生变化,还要再次修改高度,给后期的维护带来麻烦。
18.说说你对koa中洋葱模型的理解?
Koa
Koa
是一个精简的node
框架,被认为是第二代Node
框架,其最大的特点就是独特的中间件流程控制,是一个典型的洋葱模型,它的核心工作包括下面两个方面:
- 将
node
原生的req
和res
封装成为一个context
对象。 - 基于
async/await
的中间件洋葱模型机制。
洋葱模型
Koa
的洋葱模型是以next()
函数为分割点,先由外到内执行Request
的逻辑,然后再由内到外执行Response
的逻辑,这里的request
的逻辑,我们可以理解为是next
之前的内容,response
的逻辑是next
函数之后的内容,也可以说每一个中间件都有两次处理时机。洋葱模型的核心原理主要是借助compose
方法
19.如果需要手动写动画,你认为最小时间间隔是多久,为什么?
大多数显示器的默认频率是60hz(即一秒刷新60次),每刷新一次时间需要1000ms/60=16.7ms,所以理论上最小时间间隔是16.7ms。
20.说说你对webSocket的理解?
理解
WebSocket
是HTML5
下一种新的协议(websocket
协议本质上是一个基于tcp
的协议)
它实现了浏览器与服务器全双工通信,能更好的节省服务器资源和带宽并达到实时通讯的目的
Websocket是一个持久化的协议
原理
websocket
约定了一个通信的规范,通过一个握手的机制,客户端和服务器之间能建立一个类似tcp
的连接,从而方便它们之间的通信
在websocket
出现之前,web
交互一般是基于http协议
的短连接或者长连接
websocket
是一种全新的协议,不属于http无状态协议,协议名为"ws"