面试题整理,未分类
- 1.SPA(单页应用)首屏加载速度慢怎么解决?
- 2.Vue中自定义指令的理解,应用场景有哪些?
- 3.说说你对事件循环的理解?
- 4.说说javascript内存泄漏的几种情况?
- 5.大文件如何做断点续传?
- 6.原生js如何实现上拉加载下拉刷新?
- 7.说说设备像素、css像素、设备独立像素、dpr、ppi之间的区别?
- 8.谈谈你对BFC的理解?
- 9.说说TCP为什么需要三次握手和四次握手?
- 10.前端性能优化的手段有哪些?
- 11.最少说出三种前端清除浮动的方法?
- 12.什么是强缓存和协商缓存?
- 13.说说React jsx转换成真实DOM的过程?
- 14.说说你对@reduxjs/toolkit的理解?和react-redux有什么区别?
- 15.React render方法的原理,在什么时候会触发?
- 16.React性能优化的手段有哪些?
- 17.说说你对栈、队列的理解?应用场景?
- 18.说说你对git rebase 和git merge的理解?区别?
- 19.说说git常用的命令有哪些?
- 20.说说javascript内存泄漏的几种情况?
- 1.说说React生命周期中有哪些坑?如何避免?
- 2.说说Real diff算法是怎么运作的?
- 3.调和阶段setState干了什么?
- 4.说说redux的实现原理是什么,写出核心代码?
- 5.React合成事件的原理?
- 6.React组件之间如何通信?
- 7.为什么react元素有一个$$type属性?
- 8.说说Connect组件的原理是什么?
- 9.说说你对fiber架构的理解?解决了什么问题?
- 10.说说你对redux中间件的理解?常用的中间件有哪些?实现原理?
- 11.React性能优化的手段有哪些?
- 12.说说你对事件循环event loop的理解?
- 13.前端跨域的解决方案?
- 14.数组常用方法及作用,至少15个?
- 15.React render方法的原理,在什么时候会触发?
- 16.说说你对vue中mixin的理解?
- 17.for...in循环和for...of循环的区别?
- 18.Js数据类型判断都有哪几种方式?至少说出5种?它们的区别是什么?
- 19.说说你对Object.defineProperty()的理解?
- 20.说说你对webSocket的理解?
1.SPA(单页应用)首屏加载速度慢怎么解决?
(3条消息) 面试官:SPA(单页应用)首屏加载速度慢怎么解决?_动感超人,的博客-CSDN博客
减小入口文件体积
静态资源本地存储
UI框架按需加载
图片资源的压缩
组件重复打包
开启Gzip压缩
使用SSR
2.Vue中自定义指令的理解,应用场景有哪些?
在Vue2.0中,代码复用和抽象主要形式是组件,然而有的情况下,仍然需要对普通DOM元素进行底层操作,这时候就需要使用到自定义指令
应用场景:表单防止重复提交、图片懒加载、一键copy的功能
3.说说你对事件循环的理解?
面试官:说说你对事件循环的理解 | web前端面试 - 面试官系列 (vue3js.cn)
javaScript中实现单线程非阻塞的方法就是事件循环
它的一个执行机制就是:执行一个宏任务,如果遇到微任务就将它放到微任务的事件队列中,当前宏任务执行完成后,会查看微任务的事件队列,然后将里面的所有微任务依次执行完
4.说说javascript内存泄漏的几种情况?
意外使用全局变量(比如函数内部使用全局变量)
定时器,定时器不清除,一直占用内存,得不到释放,或者在定时器内调用外部函数,得不到释放
闭包,内部函数引用外部函数变量,得不到释放
不清理dom元素的引用
监听事件的解除,监听的时候addEventListener,在不监听的时候要使用
5.大文件如何做断点续传?
断点续传指的是在下载或上传时,将下载或上传任务人为的划分为几个部分
每一个部分采用一个线程进行上传或下载,如果碰到网络故障,可以从已经上传或下载的部分开始继续上传下载未完成的部分,而没有必要从头开始上传下载。用户可以节省时间,提高速度
一般实现方式有两种:服务器端返回,告知从哪开始;浏览器端自行处理
上传过程中将文件在服务器写为临时文件,等全部写完了(文件上传完),将此临时文件重命名为正式文件即可
如果中途上传中断过,下次上传的时候根据当前临时文件大小,作为在客户端读取文件的偏移量,从此位置继续读取文件数据块,上传到服务器从此偏移量继续写入文件即可
实现整体思路比较简单,拿到文件,保存文件唯一性标识,切割文件,分段上传,每次上传一段,根据唯一性标识判断文件上传进度,直到文件的全部片段上传完毕
6.原生js如何实现上拉加载下拉刷新?
上拉加载的本质是页面触底,或者快要触底时的动作
scrollTop:滚动视窗的高度距离window顶部的距离,它会随着往上滚动而不断增加,初始值是0,它是一个变化的值
clientHeight:它是一个定值,表示屏幕可视区域的高度
scrollHeight:页面不能滚动时是不存在的,body长度超过window时才会出现,所表示body所有元素的长度
简单实现
let clientHeight = document.documentElement.clientHeight; //浏览器高度
let scrollHeight = document.body.scrollHeight;
let scrollTop = document.documentElement.scrollTop;
let distance = 50; //距离视窗还用50的时候,开始触发;
if ((scrollTop + clientHeight) >= (scrollHeight - distance)) {
console.log(“开始加载数据”);
}
下拉刷新的本质是页面本身置于顶部时,用户下拉时需要触发的动作
监听原生touchstart事件,记录其初始位置的值,e.touches[0].pageY
监听原生touchmove事件,记录并计算当前滑动的位置值与初始位置值的差值,大于0表示向下拉动,并借助CSS3的translateY属性使元素跟随手势向下滑动对应的差值,同时也应设置一个允许滑动的最大值
监听原生touchend事件,若此时元素滑动达到最大值,则触发callback,同时将translateY重设为0,元素回到初始位置
7.说说设备像素、css像素、设备独立像素、dpr、ppi之间的区别?
CSS像素(css pixel, px): 适用于web编程,在 CSS 中以 px 为后缀,是一个长度单位
设备像素(device pixels),又称为物理像素;指设备能控制显示的最小物理单位,不一定是一个小正方形区块,也没有标准的宽高,只是用于显示丰富色彩的一个“点”而已
设备独立像素(Device Independent Pixel):与设备无关的逻辑像素,代表可以通过程序控制使用的虚拟像素,是一个总体概念,包括了CSS像素
dpr(device pixel ratio),设备像素比,代表设备独立像素到设备像素的转换关系,在JavaScript中可以通过 window.devicePixelRatio 获取
ppi (pixel per inch),每英寸像素,表示每英寸所包含的像素点数目,更确切的说法应该是像素密度。数值越高,说明屏幕能以更高密度显示图像
8.谈谈你对BFC的理解?
BFC(Block Formatting Context),即块级格式化上下文,它是页面中的一块渲染区域,并且有一套属于自己的渲染规则
内部的盒子会在垂直方向上一个接一个的放置
对于同一个BFC的俩个相邻的盒子的margin会发生重叠,与方向无关。
每个元素的左外边距与包含块的左边界相接触(从左到右),即使浮动元素也是如此
BFC的区域不会与float的元素区域重叠
计算BFC的高度时,浮动子元素也参与计算
BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素,反之亦然
BFC目的是形成一个相对于外界完全独立的空间,让内部的子元素不会影响到外部的元素
9.说说TCP为什么需要三次握手和四次握手?
三次挥手其实就是指建立一个TCP连接时,需要客户端和服务器总共发送3个包
主要作用就是为了确认双方得接受能力和发送能力是否正常,指定自己得初始化序列号为后面得可靠性传送做准备。
tcp终止一个连接,需要经过四次挥手
服务端在收到客户端断开连接Fin报文后,并不会立即关闭连接,而是先发送一个ACK包先告诉客户端收到关闭连接的请求,只有当服务器的所有报文发送完毕之后,才发送FIN报文断开连接,因此需要四次挥手
10.前端性能优化的手段有哪些?
https://blog.csdn.net/m0_51060602/article/details/123324547
加载优化(减少http请求数)、图片优化、使用CDN、开启Gzip(代码压缩)、样式表和JS文件的优化、减少不必要的Cookie、脚本优化、前端代码结构的优化、SEO优化
11.最少说出三种前端清除浮动的方法?
额外标签法:在需要清除浮动的元素前面加空 div 并设置 clear 为 both
浮动引起的父元素高度塌陷时,设置父元素 overflow 属性为hidden或auto
after 伪元素清除法浮动
12.什么是强缓存和协商缓存?
浏览器首次请求资源后,需要再次请求时,浏览器会首先获取该资源缓存的header信息,然后根据Cache-Control和expires来判断该资源在本地缓存否过期。若没过期则直接从本地缓存中获取资源信息,浏览器就不再向服务器重新请求资源,如过期则需重新发送请求,重新缓存资源,更新缓存时间。
强缓存是利用http请求头中的Expires和Cache-Control两个字段来进行控制,用来表示资源的缓存时间。
协商缓存是服务器用来确定缓存资源是否可用过期
因为服务器需要向浏览器确认缓存资源是否可用,二者要进行通信,而通信的过程就是发送请求,所以在header中就需要有专门的标识来让服务器确认请求资源是否可以缓存访问,所以就有了下面两组header字段
Etag和If-None-Match
Last-Modified和If-Modified-Since
13.说说React jsx转换成真实DOM的过程?
使用React.createElement或JSX编写React组件,实际上所有的 JSX 代码最后都会转换成React.createElement(…) ,Babel帮助我们完成了这个转换的过程。
createElement函数对key和ref等特殊的props进行处理,并获取defaultProps对默认props进行赋值,并且对传入的子节点进行处理,最终构造成一个虚拟DOM对象
ReactDOM.render将生成好的虚拟DOM渲染到指定容器上,其中采用了批处理、事务等机制并且对特定浏览器进行了性能优化,最终转换为真实DOM
14.说说你对@reduxjs/toolkit的理解?和react-redux有什么区别?
Redux Toolkit 是 Redux 官方强烈推荐,开箱即用的一个高效的 Redux 开发工具集。它旨在成为标准的 Redux 逻辑开发模式
Redux Toolkit 它最初是为了帮助解决有关 Redux 的三个常见问题而创建的
配置 Redux store 过于复杂;我必须添加很多软件包才能开始使用 Redux;Redux 有太多样板代码
15.React render方法的原理,在什么时候会触发?
render函数里面可以编写JSX,转化成createElement这种形式,用于生成虚拟DOM,最终转化成真实DOM
在React 中,类组件只要执行了 setState 方法,就一定会触发 render 函数执行,函数组件使用useState更改状态不一定导致重新render
组件的props 改变了,不一定触发 render 函数的执行,但是如果 props 的值来自于父组件或者祖先组件的 state
在这种情况下,父组件或者祖先组件的 state 发生了改变,就会导致子组件的重新渲染
所以,一旦执行了setState就会执行render方法,useState 会判断当前值有无发生改变确定是否执行render方法,一旦父组件发生渲染,子组件也会渲染
16.React性能优化的手段有哪些?
避免使用内联函数;事件的绑定方式;懒加载组件;服务器端渲染;数据的重复使用;组件的复用;
使用React.Memo来缓存组件、使用useMemo缓存大量的计算、使用React.PureComponent , shouldComponentUpdate、避免使用内联对象、避免使用匿名函数、延迟加载不是立即需要的组件、调整CSS而不是强制组件加载和卸载、使用React.Fragment避免添加额外的DOM
17.说说你对栈、队列的理解?应用场景?
栈(stack)又名堆栈,它是一种运算受限的线性表,限定仅在表尾进行插入和删除操作的线性表,表尾这一端被称为栈顶,相反地另一端被称为栈底,向栈顶插入元素被称为进栈、入栈、压栈,从栈顶删除元素又称作出栈
队列:跟栈十分相似,队列是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作。进行插入操作的端称为队尾,进行删除操作的端称为队头,当队列中没有元素时,称为空队列。在队列中插入一个队列元素称为入队,从队列中删除一个队列元素称为出队。因为队列只允许在一端插入,在另一端删除,所以只有最早进入队列的元素才能最先从队列中删除,故队列又称为先进先出
栈应用场景:借助栈的先进后出的特性,可以简单实现一个逆序数处的功能,首先把所有元素依次入栈,然后把所有元素出栈并输出
队列应用场景:当我们需要按照一定的顺序来处理数据,而该数据的数据量在不断地变化的时候,则需要队列来帮助解题;队列的使用广泛应用在广度优先搜索种,例如层次遍历一个二叉树的节点值(后续将到)
18.说说你对git rebase 和git merge的理解?区别?
这两种方法之间的最大区别在于,合并保留了作品的完整历史记录,包括按时间顺序排列,而Rebase使提交变得整洁,仅与分支上的作品相关。当审阅者审阅您的PR时,如果您选择合并,她将看到A,B,C,D,E,F提交,如果您选择Rebase,则只会看到C,D,E。
合并具有较高的可追溯性。无论与该公关相关如何,您都可以找到整个工作历史。但它可能对审稿人来说是痛苦的,因为该分支包括许多无关的犯罪,并且往往很难识别它们。
Rebase的确可以使PR整洁,干净且相关,而不会产生嘈杂的提交。审阅者可以轻松了解此PR的含义以及该分支内进行的更改。但是,如果您想跟踪存储库的详尽历史记录,可能并没有太大帮助。
Merge具有更高的可追溯性,而Rebase则更整洁且易于审核。
19.说说git常用的命令有哪些?
20.说说javascript内存泄漏的几种情况?
意外使用全局变量(比如函数内部使用全局变量)
定时器,定时器不清除,一直占用内存,得不到释放,或者在定时器内调用外部函数,得不到释放
闭包,内部函数引用外部函数变量,得不到释放
不清理dom元素的引用
监听事件的解除,监听的时候addEventListener,在不监听的时候要使用
1.说说React生命周期中有哪些坑?如何避免?
2.说说Real diff算法是怎么运作的?
3.调和阶段setState干了什么?
代码中调用setState函数之后react就会将传入的参数对象与组件当前的状态合并,然后去触发所谓的调和过程,经过调和过程,react会以相对高效的方式根据新的状态进行构建react元素并且着手重新渲染整个ui界面
4.说说redux的实现原理是什么,写出核心代码?
Redux就是一个实现集中管理的容器,遵循三大原则,单一数据源,state是只读的,使用纯函数来进行修改,需要注意的是redux并不是只应用在react还与其他的界面库一起使用。
工作原理:redux要求我们把数据放在一个state公共存储的空间中,一个组件改变了state里面的数据,其他组件就能感受到state的变化,再来获取store里的数据,从而间接的实现了这些数据传递的功能
使用步骤:创建一个store文件夹,新建一个index.js文件,文件中导入redux的createStore方法,用于创建公共数据区域,创建一个reducer纯函数,接收两个参数state、action分别表示数据和操作state的方法,返回state数据给组件页面,把reducer作为createStore的参数抛出在需要使用的页面导入store文件,通过store.getState获取数据,通过store.dispatch触发action修改state数据,使用store.subscrible方法监听store的改变,避免数据不更新
5.React合成事件的原理?
合成事件就是不在浏览器本身触发的事件,自己创建和触发的事件
原理:首先会在fiber节点进入render阶段的complete阶段的时候,将事件监听绑定在root上,然后调用ensureListeningTo事件绑定,生成时间合成对象,收集事件,触发真正的事件
6.React组件之间如何通信?
7.为什么react元素有一个$$type属性?
因为json不支持symbol类型,所以用户即使提交了message的信息,到最后服务器端也不会保存 t y p e o f 的属性,而在渲染的时候, r e a c t 会检测是否有 typeof的属性,而在渲染的时候,react会检测是否有 typeof的属性,而在渲染的时候,react会检测是否有typeof属性,如果没有这个属性则会拒绝处理该元素
8.说说Connect组件的原理是什么?
Connect有四个参数(两个不常用):第一个:mapStateToProps这个函数允许我们将store中的数据作为props绑定到数组上,主要原理就是将需要绑定的props作为一个函数传过来,在connect中传递给mapStateToProps一个真实store数据
第二个:mapDispatchToProps由于更改数据必须要触发action,因此在这个参数的主要功能就是将action作为props绑定到组加上
Connect是一个高阶函数,首先传入mapStateToProps、mapDispatchToProps,然后返回一个生产component的函数(wrapWithConnect),然后再将真正的component作为参数传入到wrapWithConnect组件
具体流程:通过props.store获取祖先component的store,props包括stateProps、dispatchProps、parentProps,合并到一起就得到了nextState,作为props传入给真正的Component,componentDidMount周期的时候,添加事件this.Store.subscribe(this.handleChange),实现页面交互,在shouleComponentUpdate的时候判断是否有效,避免无效渲染,并拿到nextState,最后在componentWillUnMount时移除this.handleChange
9.说说你对fiber架构的理解?解决了什么问题?
Fiber框架的应用目的,按照react官方的说法就是实现‘增量渲染’,通俗来说就是把一个渲染任务分解成多个渲染任务,而后分散到多个帧里面
Fiber架构的核心:可断点、可恢复和优先级
解决了JavaScript引擎和页面渲染引擎两个线程是互斥的,当其中一个线程执行的时候,另一个线程只能挂起等待,如果JavaScript线程长时间占用主线程那么渲染层面的更新不得不长时间的等待,界面长时间不更新就会导致页面响应变差,用户会感到卡顿,而fiber是在react渲染组件的时候,从开始到渲染完成整个过程是一气呵成无法中断的
10.说说你对redux中间件的理解?常用的中间件有哪些?实现原理?
Redux中,中间件就是放在dispatch过程,在分发action进行拦截处理
当action发出之后,reducer立即算出state,整个过程是一个同步的操作。如果需要支持异步操作,这个过程就可以用上中间件,其本质上就是一个函数,对store.dispatch方法进行了改造,在发出action和执行reducer这两步间添加了其他的功能
常用的中间件有:redux-thunk:用于异步操作、redux-logger:用于日志记录
中间件都需要通过applyMiddlewares进行注册,作用是将所有的中间件组成一个数组,依次执行,然后作为第二个参数传入到createStore中
Const store = createStore(
Reducer,
applyMiddlewares(thunk,logger)
);
11.React性能优化的手段有哪些?
避免使用内联函数、事件绑定方式,懒加载组件、服务端渲染、userMemo(缓存复杂运算的数据结果)、useCallBack(对传递的方法进行缓存,监听数据更新后才会重新调用方法)、虚拟dom(减少了对真实dom的操作)
12.说说你对事件循环event loop的理解?
Js是单线程,也就是在程序运行时只有一个线程在运行,同一时间只能做一件事,为了解决js单线程阻塞的问题,JavaScript用到计算机系统中的事件循环event loop
同步任务进入主线程,异步任务进入任务队列等候,主线程内的任务执行完成后为空,就会去任务队列中读取响应的任务,推入主线程执行这个过程的不断重复就是事件循环
13.前端跨域的解决方案?
解决跨域的方法:注意
- 如果是协议和端口造成的跨域,前端是没有办法的处理的
- 是否跨域,仅仅通过URl的首部来进行判断的话,不会通过域名对应的ip地址是都相同来判断,
- 跨域并不是请求发不出去,而是请求发出去了,也正常返回结果了,但是被浏览器拦截了
解决方法:
利用JSONP方式来解决跨域:利用script标签没有跨域的限制,网页可以从其他来源动态获取JSON数据,从而实现跨域;
利用CORS技术,需要前后端同时支撑,前端浏览器在IE9以上,后端在响应报头添加access-Control-Allow-Orgin标签,从而允许指定域的站点访问当前域的资源
跨域指的是游览器不能执行其他网站的脚本,它是由游览器的同源策略(即协议、域名、端口号必须相同)造成的,是游览器施加的安全限制。
游览器执行JavaScript脚本时,会检查这个脚本属于哪个页面,如果不是同源页面,就不会被执行。
vue中设置代理服务器
跨域问题只存在游览器,如果是服务器和服务器之间的通信是不存在跨域问题的。
可以在vue-cli中设置代理服务器实现跨域请求。
14.数组常用方法及作用,至少15个?
15.React render方法的原理,在什么时候会触发?
Render函数里面可以编写JSX,转化成createElement这种实行,用于生成虚拟dom,最终转化成真实dom。
在react中,类组件只要执行了setState方法就一定会触发render函数执行,函数组件使用useState更改状态不一定会导致重新render组件的props,但是如果props的值来自于父组件的state,在这种情况下,父组件state发生了改变就会导致子组件的重新渲染,所以一旦指令setState就会执行render,useState会判断当前值有没有发生改变,确定是否去执行render方法,一旦父组件发生渲染,子组件也就会发生渲染
16.说说你对vue中mixin的理解?
Vue中的mixin,提供了一种非常灵活的方式,来分发vue组件中的可复用功能,本质上就是一个js对象,他可以包含我们组件中任意功能选项data和methods等,我们只要将共有的功能以对象方式传入mixin选项中,mixin分为局部混入和全局混入
17.for…in循环和for…of循环的区别?
For…in循环:遍历的是数组则输出的是索引,如果遍历的是对象,输出的是对象的属性名,for…in循环需要分析出array中的每个属性,这个操作性能开销很大,用在key已知的数据上是非常不划算的,所以尽量不要使用for…in,除非不清楚要处理哪些属性,例如JSON对象这样的情况
For…of循环:循环一次,就要检查一下数组的长度,读取属性要比局部变量慢,尤其是当array里面存放的都是dom元素,因为每次读取都会扫描页面上的选择器相关元素,速度会大大降低
18.Js数据类型判断都有哪几种方式?至少说出5种?它们的区别是什么?
19.说说你对Object.defineProperty()的理解?
Object.defineProperty()方法会直接在一个对象上定义一个新的属性,或者修改一个对象上的现有属性,并返回该对象
Object.defineProperty()中的参数分别为obj(需要定义属性的对象),prop(要定义或者修改的属性的名称),des(要定义或者修改的属性描述符)