前端面试题(三)

1. Vue组件通信?

1、 通过props进行父子组件的通信
2、全局事件总线:eventBus
3、消息订阅与发布:pubsub第三方库
4、本地存储:localStorage与sessionStorage
5、vuex集中式状态管理工具

2. 说说你对vuex的理解?写出其原理的核心代码?

什么是vuex
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式 + 库。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。

vuex五大核心属性:state,getter,mutation,action,module
state:存储数据,存储状态;在根实例中注册了store 后,用this.$store.state来访问;对应vue里面的data;存放数据方式为响应式,vue组件从store中读取数据,如数据发生变化,组件也会对应的更新。

getter:可以认为是 store 的计算属性,它的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算。

mutation:更改 Vuex 的 store 中的状态的唯一方法是提交 mutation。

action:包含任意异步操作,通过提交 mutation 间接更变状态。

module:将 store 分割成模块,每个模块都具有state、mutation、action、getter、甚至是嵌套子模块。

Vuex原理
个人理解它就是通过 全局混入 一个对象,在该对象的 beforeCreate 声明周期函数中,对每一个组件添加了一个属性 $store,值就是使用Vuex时所创建的Vuex实例。

核心代码

3. 说说React生命周期中有哪些坑?如何避免?

避免生命周期中的坑需要做好两件事:
不在恰当的时候调用了不该调用的代码;
在需要调用时,不要忘了调用。

那么主要有这么 7 种情况容易造成生命周期的坑。

getDerivedStateFromProps 容易编写反模式代码,使受控组件与非受控组件区分模糊。

componentWillMount 在 React 中已被标记弃用,不推荐使用,主要原因是新的异步渲染架构会导致它被多次调用。所以网络请求及事件绑定代码应移至 componentDidMount 中。

componentWillReceiveProps 同样被标记弃用,被 getDerivedStateFromProps 所取代,主要原因是性能问题。

shouldComponentUpdate 通过返回 true 或者 false 来确定是否需要触发新的渲染。主要用于性能优化。

componentWillUpdate 同样是由于新的异步渲染机制,而被标记废弃,不推荐使用,原先的逻辑可结合 getSnapshotBeforeUpdate 与 componentDidUpdate 改造使用。

如果在 componentWillUnmount 函数中忘记解除事件绑定,取消定时器等清理操作,容易引发 bug。

如果没有添加错误边界处理,当渲染发生异常时,用户将会看到一个无法操作的白屏,所以一定要添加。

4. 说说你对React中虚拟dom的理解?

理解
实际上它只是一层对真实DOM的抽象,以JavaScript 对象 (VNode 节点) 作为基础的树,用对象的属性来描述节点,最终可以通过一系列操作使这棵树映射到真实环境上
创建虚拟DOM就是为了更好将虚拟的节点渲染到页面视图中,所以虚拟DOM对象的节点与真实DOM的属性一一照应

实现原理
React虚拟DOM的实现原理,通过JS模拟网页文档节点,生成JS对象树(虚拟DOM),然后再进一步生成真实的DOM树,再绘制到屏幕。如果后面有内容发生改变,React会重新生成一棵全新的虚拟DOM树,再与前面的虚拟DOM树进行比对diff,把差异的部分打包成patch,再应用到真实DOM,然后渲染到屏幕浏览器。

5. 调和阶段setState干了什么?

(1)代码中调用 setState 函数之后,React 会将传入的参数对象与组件当前的状态合并,然后触发所谓的调和过程(Reconciliation)。
(2)经过调和过程,React 会以相对高效的方式根据新的状态构建 React 元素树并且着手重新渲染整个 UI 界面;
(3)在 React 得到元素树之后,React 会自动计算出新的树与老树的节点差异,然后根据差异对界面进行最小化重渲染;
(4)在差异计算算法中,React 能够相对精确地知道哪些位置发生了改变以及应该如何改变,这就保证了按需更新,而不是全部重新渲染。

6. React组件之间如何通信?

父传子:⽗组件可以通过向⼦组件传 props 的⽅式来实现
子传父:可以采用props+回调的方式
兄弟组件通信:可以通过兄弟节点的共同父节点,由父节点转发信息,实现兄弟间通信
跨层级通信:context状态树
发布者订阅者模式:发布者发布事件,订阅者监听到事件后做出反应,可以通过引⼊ event 模块进⾏
全局状态管理工具:可以借助 Redux 或 Mobx以及react-redux 等全局状态管理⼯具进⾏通信,它们会维护⼀个全局状态中⼼(Store),并可以根据不同的事件产⽣新的状态
hooks中帮我们封装好的:useContext和useReducer

7. 说说redux的实现原理是什么,写出其原理的核心代码?

(1)将应用的状态统一放到state中,由store来管理state。
(2)reducer的作用是返回一个新的state去更新store中对用的state。
(3)按redux的原则,UI层每一次状态的改变都应通过action去触发,action传入对应的reducer 中,reducer返回一个新的state更新store中存放的state,这样就完成了一次状态的更新
(4)subscribe是为store订阅监听函数,这些订阅后的监听函数是在每一次dipatch发起后依次执行
(5)可以添加中间件对提交的dispatch进行重写

核心代码

8. 说说Connect组件的原理是什么?

首先connect之所以会成功,是因为Provider组件:

在原应用组件上包裹一层,使原来整个应用成为Provider的子组件
接收Redux的store作为props,通过context对象传递给子孙组件上的connect
那connect做了些什么呢?

它真正连接 Redux 和 React,它包在我们的容器组件的外一层,它接收上面 Provider 提供的 store 里面的 state 和 dispatch,传给一个构造函数,返回一个对象,以属性形式传给我们的容器组件。

9. 说说react 中jsx语法糖的本质?

Jsx是语法糖,实质是js函数,需要babel来解析,核心函数是React.createElement(tag,{attrbuties},children),参数tag是标签名可以是html标签和组件名,attrbuties参数是标签的属性,children参数是tag的子元素。用来创建一个vnode,最后渲染到页面上

10. 说说你对redux中间件的理解?常用的中间件有哪些?实现原理?

中间件(Middleware)是介于应用系统和系统软件之间的一类软件,它使用系统软件所提供的基础服务(功能),衔接网络上应用系统的各个部分或不同的应用,能够达到资源共享、功能共享的目的
类似于插件,可以在不影响原本功能、并且不改动原本代码的基础上,对其功能进行增强。在Redux中,中间件主要用于增强dispatch函数。
Redux中,中间件就是放在就是在dispatch过程,在分发action进行拦截处理

常用的中间件

redux-thunk:通过action返回一个函数进行异步操作
redux-promise :通过action返回一个promise进行异步处理
redux-logger:用于日志记录

实现原理

中间件本身是一个函数,该函数接收一个store参数,表示创建的仓库,该仓库并非一个完整的仓库对象,仅包含getState,dispatch。该函数运行的时间,是在仓库创建之后运行。
由于创建仓库后需要自动运行设置的中间件函数,因此,需要在创建仓库时,告诉仓库有哪些中间件
需要调用applyMiddleware函数,将函数的返回结果作为createStore的第二或第三个参数。
中间件函数必须返回一个dispatch创建函数

11. props和state相同点和不同点?render方法在哪些情况下会执行?

props:
  props是一个从外部传进组件的参数,由于React具有单向数据流的特性,所以他的主要作用是从父组件向子组件中传递数据,它是不可改变的,如果想要改变它,只能通过外部组件传入新的props来重新渲染子组件,否则子组件的props和展示形式不会改变,props除了可以传字符串,数字,还可以传递对象,数组甚至是回调函数
  
state:
  state主要作用是用于组件保存,控制及修改自己的状态,它只能在constructor中初始化,state是可以被改变的,state放改动的一些属性,比如点击选中,再点击取消,类似这种属性就放入带state中,注意:没有state的叫做无状态组件,多用props少用state,多写无状态组件,注意:修改state的值时,必须通过调用setState方法,当我们调用this.setState方法时,React会更新组件的数据状态,并且重新调用render方法
  
不同点:
1.props不可以在组件内部修改,但state可以在组件内部修改

2.可以从父组件修改自组件的props,而不能从父组件修改自组件的state
  
相同点:
1.props和state都是导出HTML的原始数据。

2.props和state都是确定性的,如果我们写的组件为同一props和state的组合生成了不同的输出,那木我们肯定在哪里做错了
  
3.props和state都会触发渲染更新
  
4.props和state都是纯JS对象(用typeof来判断,结果都是object)
  
5.可以从父组件得到初始值props和state的初始值

render方法在哪些情况下会执行?

在类组件和函数组件中,render函数的形式是不同的。

在类组件中render函数指的就是render方法;而在函数组件中,指的就是整个函数组件。

在render函数中的jsx语句会被编译成我们熟悉的js代码

在render过程中,React 将新调用的 render函数返回的树与旧版本的树进行比较,这一步是决定如何更新 DOM 的必要步骤,然后进行 diff 比较,更新 DOM树

触发机制:

类组件调用 setState 修改状态
函数组件通过useState hook修改状态。函数组件通过useState这种形式更新数据,当数组的值不发生改变了,就不会触发render

总结:

render函数里面可以编写JSX,转化成createElement这种形式,用于生成虚拟DOM,最终转化成真实DOM

在React 中,类组件只要执行了 setState 方法,就一定会触发 render 函数执行,函数组件使用useState更改状态不一定导致重新render

组件的props 改变了,不一定触发 render 函数的执行,但是如果 props 的值来自于父组件或者祖先组件的 state

在这种情况下,父组件或者祖先组件的 state 发生了改变,就会导致子组件的重新渲染

所以,一旦执行了setState就会执行render方法,useState 会判断当前值有无发生改变确定是否执行render方法,一旦父组件发生渲染,子组件也会渲染

12. react新出来两个钩子函数是什么?和删掉的will系列有什么区别?

react新旧生命周期的区别:
1、新生命周期中去掉了三个will钩子,分别为componentWillMount、componentWillReceiveProps、componentWillUpdate;
2、新生命周期中新增了两个钩子,分别为getDerivedStateFromProps(从props中得到衍生的state)和getSnapshotBeforeUpdate。

react生命周期(旧): Alt
react生命周期(新):

Alt
新的生命周期新增了两个钩子,分别是:

1、getDerivedStateFromProps:从props中得到衍生的state

接受两个参数:props,state

返回一个状态对象或者null,用来修改state的值。

使用场景:若state的值在任何时候都取决于props,那么可以使用getDerivedStateFromProps

2、getSnapshotBeforeUpdate:在更新前拿到快照(可以拿到更新前的数据)

在更新DOM之前调用

返回一个对象或者null,返回值传递给componentDidUpdate

componentDidUpdate():更新DOM之后调用

接受三个参数:preProps,preState,snapshotValue

13. CDN的特点及意义?

什么是CDN

CDN 意为内容分发网络,是基于现有网络的智能虚拟网络,分布在世界各地的边缘服务器上。基本思路是避免互联网上可能影响数据传输速度和稳定性的瓶颈和环节,使内容传输更快更稳定。

CDN 表示将数据从原始服务器复制到其他服务器。当用户访问时,他们可以在复制了数据内容的服务器上进行访问。其目的是使用户能够更快更好地获取所需内容,解决网络拥塞情况,提高用户访问网站的响应速度。CDN 加速成本低,速度快,适合访问量比较大的网站。

CDN 具有以下主要功能
1.节省骨干网带宽,降低带宽需求;

2.提供服务器端加速,解决大量用户访问导致的服务器过载问题;

3.服务提供商可以利用Web Cache技术将用户访问的网页和对象缓存在本地,这样对相同对象的访问就不需要占用骨干网的出口带宽,相应的用户访问网页的时间要求也增加了;

4.可以克服网站分布不均的问题,降低网站自身的建设和维护成本;

5.减少“通信风暴”的影响,提高网络访问的稳定性。

CDN 的特点
1.本地缓存加速:提高了企业网站(尤其是包含大量图片和静态页面的网站)的访问速度,大大提高了上述网站的稳定性。

2.镜像服务:消除了不同运营商之间互联瓶颈带来的影响,实现了跨运营商的网络加速,保证了不同网络的用户都能获得良好的接入质量。

3.远程加速:远程访问用户根据DNS负载均衡技术智能自动选择缓存服务器,选择最快的缓存服务器加速远程访问。

4.带宽优化:自动生成服务器的远程镜像缓存服务器。远程用户访问时,可以从缓存服务器读取数据,减少远程访问的带宽,分担网络流量,减轻原WEB服务器的负载。

5.集群抗攻击:广泛分布的CDN 节点加上节点间的智能冗余机制,可以有效防止黑客入侵,降低各种D.D.o.S攻击对网站的影响,同时保证更好的服务质量。

14. 什么是闭包,应用场景是什么?

什么是闭包
闭包就是一个函数和对其周围状态(lexical environment,词法环境)的引用捆绑在一起(或者说函数被引用包围),这样的组合就是闭包(closure)

也就是说 闭包可以让你在一个内层函数中访问到其外层函数的作用域 , 也可以说是函数 + 上下文调用

在 JavaScript中,每当创建一个函数,闭包就会在函数创建的同时被创建出来,作为函数内部与外部连接起来的一座桥梁

应用场景

任何闭包的使用场景都离不开这两点:

1、创建私有变量
2、延长变量的生命周期

注意点

如果不是某些特定任务需要使用闭包,在其它函数中创建函数是不明智的,因为闭包在处理速度和内存消耗方面对脚本性能具有负面影响

15. 从浏览器地址栏输入url到显示页面的步骤?

详解图: Alt

1、首先,在浏览器地址栏中输入url

2、浏览器先查看浏览器缓存-系统缓存-路由器缓存,如果缓存中有,会直接在屏幕中显示页面内容。若没有,则跳到第三步操作。

3、在发送http请求前,需要域名解析(DNS解析),解析获取相应的IP地址。

4、浏览器向服务器发起tcp连接,与服务器建立tcp三次握手。

5、握手成功后,浏览器向服务器发送http请求,请求数据包。

6、服务器处理收到的请求,将数据返回至浏览器

7、浏览器收到HTTP响应。根据情况选择关闭TCP连接或者保留重用

8、如果得到的资源(静态)可以缓存,进行缓存

8、读取页面内容,浏览器渲染,解析html源码

9、生成Dom树、解析css样式、js交互

10、ajax(Asynchronous Javascript And XML)异步处理 可以在不重新加载整个网页的情况下,对网页的某部分进行更新

16. 介绍一下你对浏览器内核的理解?

主要分成两个部分:

渲染引擎(Render Engine)
和JS引擎。

渲染引擎:
负责取得网页的内容(html,xml和图像等),整理讯息(例如假如css),以及计算网页的显示方式,然后输出到显示器或打印机。浏览器的内核的不同对于网页的语法解释会有不同,所以渲染的效果也不同。所有网页浏览器、电子邮件客户端以及它需要编辑、显示网络内容的应用程序都需要内核。

JS引擎:
解析和执行JavaScript来实现网页的动态效果。
最开始渲染引擎和JS引擎并没有区分的很明确,后来JS引擎越来越独立,内核就倾向与只指渲染引擎。

常见的浏览器内核有哪些?

Trident内核:IE浏览器以Trident作为内核引擎。(遨游,世界之窗,腾讯TT……都是IE)。
Trident内核最慢。
Gecko内核:开放源代码,以C++编写的网页排版引擎,是跨平台的。
FireFox是基于Gecko开发。
presto内核(Opera前内核)(已废弃):该款引擎的特点就是渲染速度的优化达到了极致,然而代价却是牺牲了网页的兼容性。
Webkit内核:(Safari内核,Chrome内核原型,开源),它是苹果公司自己的内核,也是苹果的Safari浏览器使用的内核。
Webkit引擎包含WebCore排版引擎及JavaScriptCore解析引擎,均是从KDE的KHTML及KJS引擎衍生而来,它们都是自由软件,在GPL条约下授权,同时也支持BSD系统的开发。所有Webkit也是自由软件,同时开放源代码。在安全方面不受IE,FireFox的制约。
所以,Safari浏览器在国内还是很安全的。

17. 清除浮动的几种方式?各自的优缺点?

1.使用空标签清除浮动clear:both。
原理:添加一个空div,利用css提高的clear:both清除浮动,让父级div能自动获取到高度
优点:通俗易懂,容易掌握
缺点:会添加很多无意义的空标签,有违结构与表现的分离,在后期维护中将是噩梦
建议:不推荐使用,但此方法是以前主要使用的一种清除浮动方法

2.父级div定义overflow:hidden
原理:必须定义width或zoom:1,同时不能定义height,使用overflow:hidden时,浏览器会自动检查浮动区域的高度
优点:简单,代码少,浏览器支持好
缺点:不能和position配合使用,因为超出的尺寸的会被隐藏
建议:只推荐没有使用position或对overflow:hidden理解比较深的朋友使用

3、父级div定义伪类:after和zoom(用于非IE浏览器)
原理:IE8以上和非IE浏览器才支持:after,原理和方法1有点类似,zoom(IE转有属性)可解决ie6,ie7浮动问题
优点:浏览器支持好,不容易出现怪问题(目前:大型网站都有使用,如:腾迅,网易,新浪等等)。
缺点:代码多,要两句代码结合使用,才能让主流浏览器都支持
建议:推荐使用,建议定义公共类,以减少CSS代码

display:block 使生成的元素以块级元素显示,占满剩余空间;
height:0 避免生成内容破坏原有布局的高度。
visibility:hidden 使生成的内容不可见,并允许可能被生成内容盖住的内容可以进行点击和交互;
通过 content:".“生成内容作为最后一个元素,至于content里面是点还是其他都是可以的,例如oocss里面就有经典的 	content:“XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX”,有些版本可能content 里面内容为空,不推荐这样做的,firefox直到7.0 content:”” 仍然会产生额外的空隙;
zoom:1 触发IE hasLayout。

通过分析发现,除了clear:both用来清除浮动的,其他代码无非都是为了隐藏掉content生成的内容,这也就是其他版本的闭合浮动为什么会有font-size:0,line-height:0。

4、父级div定义height
原理:父级div手动定义height,就解决了父级div无法自动获取到高度的问题。
优点:简单,代码少,容易掌握
缺点:只适合高度固定的布局,要给出精确的高度,如果高度和父级div不一样时,会产生问题

5、父级div定义overflow:auto
原理:必须定义width或zoom:1,同时不能定义height,使用overflow:auto时,浏览器会自动检查浮动区域的高度
优点:简单,代码少,浏览器支持好
缺点:内部宽高超过父级div时,会出现滚动条。
建议:不推荐使用,如果你需要出现滚动条或者确保你的代码不会出现滚动条就使用吧。

18. 说说你对koa中洋葱模型的理解?

Koa是一个精简的node框架,被认为是第二代Node框架,其最大的特点就是独特的中间件流程控制,是一个典型的洋葱模型,它的核心工作包括下面两个方面:

将node原生的req和res封装成为一个context对象。
基于async/await的中间件洋葱模型机制。

什么是洋葱模型
Koa的洋葱模型是以next()函数为分割点,先由外到内执行Request的逻辑,然后再由内到外执行Response的逻辑,这里的request的逻辑,我们可以理解为是next之前的内容,response的逻辑是next函数之后的内容,也可以说每一个中间件都有两次处理时机。洋葱模型的核心原理主要是借助compose方法。

为什么需要洋葱模型
因为很多时候,在一个app里面有很多中间件,有些中间件需要依赖其他中间件的结果,用葱模型可以保证执行顺序,如果没有洋葱模型,执行顺序可能出乎我们的预期

19. 如果需要手动写动画,你认为最小时间间隔是多久,为什么?

多数显示器默认频率是60Hz,即1秒刷新60次,所以理论上最小间隔为1/60*1000ms = 16.7ms

20. 说说你对webSocket的理解?

WebSocket,是一种网络传输协议,位于OSI模型的应用层。可在单个TCP连接上进行全双工通信,能更好的节省服务器资源和带宽并达到实时通迅

客户端和服务器只需要完成一次握手,两者之间就可以创建持久性的连接,并进行双向数据传输
特点:

全双工
二进制帧
协议名
握手

优点:

较少的控制开销:数据包头部协议较小,不同于http每次请求需要携带完整的头部

更强的实时性:相对于HTTP请求需要等待客户端发起请求服务端才能响应,延迟明显更少

保持创连接状态:创建通信后,可省略状态信息,不同于HTTP每次请求需要携带身份验证

更好的二进制支持:定义了二进制帧,更好处理二进制内容

支持扩展:用户可以扩展websocket协议、实现部分自定义的子协议

更好的压缩效果:Websocket在适当的扩展支持下,可以沿用之前内容的上下文,在传递类似的数据时,可以显著地提高压缩率

应用场景:

弹幕

媒体聊天

协同编辑

基于位置的应用

体育实况更新

股票基金报价实时更新
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值