前端面试题整理(1)
- 1、bind、call、apply 区别?如何实现一个bind?
- 2、什么是防抖和节流?有什么区别?如何实现?
- 3、什么是响应式设计?响应式设计的基本原理是什么?如何做?
- 4、怎么理解回流跟重绘?什么场景下会触发?
- 5、说说vue中的diff算法
- 6、说说你对keep-alive的理解
- 7、如何解决跨域问题
- 8、Vue组件之间的通信方式都有哪些?
- 9、VUE路由的原理?
- 10、React 性能优化的手段有哪些
- 11、简述在浏览器中输入url地址 到浏览器呈现出页面发生的整个过程
- 12、SPA首屏加载速度慢的怎么解决
- 13、说说你对webSocket的理解
- 14、说说如何借助webpack来优化前端性能
- 15、AMD、CMD、commonJS模块化规范的区别?
- 16、说说Connect组件的原理是什么?
- 17、说说你对受控组件和非受控组件的理解?应用场景?
- 18、说说package.json中版本号的规则
- 19、说说你对koa中洋葱模型的理解?
- 20、说说javascript内存泄漏的几种情况?
- 21、谈谈你对BFC的理解?
- 22、说出三种前端清除浮动的方法
- 23、什么是强缓存和协商缓存
- 24·、说说git常用的命令有哪些?
- 25、说说你对git rebase 和git merge的理解?区别?
- 26、说说TCP为什么需要三次握手和四次挥手?
- 27、说说你对事件循环的理解?
- 28、React render方法的原理,在什么时候会触发?
- 29、说说你对vue中mixin的理解?
- 30、说说你对redux中间件的理解?常用的中间件有哪些?实现原理?
- ---未完待续---
1、bind、call、apply 区别?如何实现一个bind?
call、apply、bind作用是用来改变函数this指向的。
区别:
- apply和call都是接受两个参数,第一个参数是this指向,当第一个参数为null、undefined的时候,默认指向window(在浏览器中)。改变this指向后原函数会立即执行,且此方法只是临时改变this指向一次。
- apply第二个参数是函数接受的参数是以数组的形式传入,call第二个参数是一个参数列表[ ]
- bind:第一参数也是this的指向,后面传入的也是一个参数列表(但是这个参数列表可以分多次传入)。
如何实现bind?
- 修改this指向
- 动态传递参数
- 兼容new关键字
2、什么是防抖和节流?有什么区别?如何实现?
防抖:在用户多次触发事件,当用户停止触发事件,将事件执行一次。等待一段时间。
节流:在用户多次触发事件,会在多次触发的过程中,间隔执行事件。按照一定的频率执行。
区别:
相同点:
- 都可以通过使用 setTimeout 实现
- 目的都是,降低回调执行频率。节省计算资源
不同点:
- 函数防抖,在一段连续操作结束后,处理回调,利用clearTimeout和
setTimeout实现。函数节流,在一段连续操作中,每一段时间只执行一次,频率较高的事件中使用来提高性能 - 函数防抖关注一定时间连续触发的事件,只在最后执行一次,而函数节流一段时间内只执行一次
3、什么是响应式设计?响应式设计的基本原理是什么?如何做?
详解请查看这里=>
什么是响应式设计:
-
指在同一页面在不同屏幕尺寸下有不同的布局。能够使一张页面适配多种屏幕的布局方案。
-
响应式开发一套界面,通过检测视口分辨率,针对不同客户端在客户端做代码处理,来展现不同的布局和内容
如何实现?
-
rem
-
vw / vh
-
弹性盒子
-
媒体查询
-
浮动
-
百分比
4、怎么理解回流跟重绘?什么场景下会触发?
回流:布局引擎会根据各种样式计算每个盒子在页面的大小与位置。
重绘:当计算好盒模型的位置、大小及其他属性后,浏览器根据每个盒子特性进行绘制。
回流触发时机:
- 添加或删除可见的DOM元素
- 元素的位置发生变化
- 元素的尺寸发生变化(包括外边距、内边框、边框大小、高度和宽度等)
- 内容发生变化,比如文本变化或图片被另一个不同尺寸的图片所替代
- 页面一开始渲染的时候(这避免不了)
- 浏览器的窗口尺寸变化(因为回流是根据视口的大小来计算元素的位置和大小的)
重绘触发时机:
- 颜色的修改
- 文本方向的修改
- 阴影的修改
5、说说vue中的diff算法
diff算法是一种通过同层的树节点进行比较的高效算法。
只会在同层级比较,不会跨层级比较。
在diff算法的过程中,循环从两边向中间比较。
在vue中作用于虚拟dom渲染成真实dom的新旧节点比较。
原理是当数据发生改变时,订阅者就会给真实的dom打补丁,来更新相应的视图。
6、说说你对keep-alive的理解
- keep-alive是vue中内置的组件,能在组件切换过程中将状态保留在内存中,防止重复渲染DOM。
- keep-alive包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们。
- 使用了keep-alive的组件后,组件就会自动加上activated钩子和deactivated钩子。
- 可以用在查看表格某条数据详细页,可以查看填写的表单内容路由跳转返回是是否还在。
7、如何解决跨域问题
跨域的本质时浏览器基于同源策略的一种安全手段,同源是指协议、域名、端口号相同,不相同就会出现跨域问题。
解决跨域的方法:
- JSONP
- CORS
- Proxy事件代理
8、Vue组件之间的通信方式都有哪些?
- 父子组件之间的通信
- 兄弟组件之间的通信
- 祖孙与后代组件之间的通信
- 非关系组件间之间的通信
小结
- 父子关系的组件数据传递选择props与 $ emit进行传递,也可以选择ref
- 兄弟关系的组件数据传递选择$ bus,其次可以选择$parent进行传递。
- 祖先与后代组件数据传递可选择attrs与listeners或者 Provide与 Inject
- 复杂关系的组件数据传递可以通过vuex存放共享的变量
9、VUE路由的原理?
10、React 性能优化的手段有哪些
11、简述在浏览器中输入url地址 到浏览器呈现出页面发生的整个过程
- 首先,在浏览器地址栏种输入url
- 浏览器先查看浏览器缓存、路由器缓存、如果缓存中有,会直接在屏幕中显示页面内容。若没有,则跳转到第三步。
- 在发送http请求前,需要域名解析(DNS解析),解析获取相应的IP地址。
- 浏览器向服务器发起tcp连接,与浏览器tcp三次握手。
- 握手成功后,浏览器向服务器发送http请求,请求数据包。
- 服务器处理收到的请求,将数据返回至浏览器。
- 浏览器收到HTTP响应。
- 读取页面内容,浏览器渲染,解析html源码。
- 生成DOM树,解析css样式,js交互。
- 客户端和服务器交互
- ajax查询
12、SPA首屏加载速度慢的怎么解决
首屏时间,指的是浏览器从响应用户输入网址地址,到首屏内容渲染完成的时间,此时整个网页不一定要全部渲染完成,但需要展示当前视窗需要的内容。
加载慢的原因:
- 网络延时问题
- 资源文件体积是否过大
- 资源是否重复发送请求去加载了
- 加载脚本的时候,渲染内容堵塞了
解决方案:
- 减小入口文件积
- 静态资源本地缓存
- UI框架按需加载
- 图片资源的压缩
- 组件重复打包
- 开启GZip压缩
- 使用SSR
13、说说你对webSocket的理解
14、说说如何借助webpack来优化前端性能
一般项目在完成后,会通过webpack进行打包,利用webpack对前端项目性能优化是一个十分重要的环节。
如何优化:
- Js代码的压缩
- CSS代码压缩
- HTML文件代码的压缩
- 文件大小的压缩
- 图片压缩
- Tree Shaking
- 代码分离
- 内联chunk
总结: 关于webpack对前端性能的优化,可以通过文件体积大小入手,其次还可通过分包的形式、减少http请求次数等方式,实现对前端性能的优化
15、AMD、CMD、commonJS模块化规范的区别?
16、说说Connect组件的原理是什么?
connect是高阶组件,接受两个方法,返回的函数接收参数是组件,从而返回一个新的组件。
如下:
connect([mapStateToProps], [mapDispatchToProps])(component)
connect工作流程
Provider组件,在原应用组件上包裹一层,使原来整个应用成为Provider的子组件
接收Redux的store作为props,通过context对象传递给子孙组件上的connect
它真正连接 Redux 和 React,它包在我们的容器组件的外一层,它接收上面 Provider 提供的 store 里面的 state 和 dispatch,传给一个构造函数,返回一个对象,以属性形式传给我们的容器组件
connect 的作用
connect作用是让你把组件和store连接起来,产生一个新的组件(connect 是高阶组件)
17、说说你对受控组件和非受控组件的理解?应用场景?
受控组件
由React控制的输入表单元素而改变其值的方式,称为受控组件。
比如,给表单元素input绑定一个onChange事件,当input状态发生变化时就会触发onChange事件,从而更新组件的state。
非受控组件
非受控组件指的是,表单数据由DOM本身处理。即不受setState()的控制,与传统的HTML表单输入相似,input输入值即显示最新值。
在非受控组件中,可以使用一个ref来从DOM获得表单值。
18、说说package.json中版本号的规则
(ps:还未理解 …)
第一部分为主版本号,变化了表示有了一个不兼容上个版本的大更改
第二部分为次版本号,变化了表示增加了新功能,并且可以向后兼容
第三部分为修订版本号,变化了表示 有bug修复,并且可以向后兼容
第四部分为日期版本号加希腊字母版本号,希腊字母版本号共有五种,分别为base、alpha、 bela 、RCrelease。
19、说说你对koa中洋葱模型的理解?
Koa是一个精简的node框架,被认为是第二代Node框架,其最大的特点就是独特的中间件流程控制,是一个典型的洋葱模型,它的核心工作包括下面两个方面:
- 1.将node原生的req和res封装成为一个context对象
- 2.基于async/await的中间件洋葱模型机制
Koa的洋葱模型是以next()函数为分割点,先由外到内执行Request的逻辑,然后再由内到外执行Response的逻辑,这里的request的逻辑,我们可以理解为是next之前的内容,response的逻辑是next函数之后的内容,也可以说每一个中间件都有两次处理时机。洋葱模型的核心原理主要是借助compose方法。
20、说说javascript内存泄漏的几种情况?
内存泄漏的几种情况
-
意外的全局变量
一个未声明变量的引用会在全局对象中创建一个新的变量。
-
闭包引起的内存泄漏
闭包可以使变量常驻内存,但如果使用不当就会在成内存泄漏
-
DOM之外的引用
-
被遗漏的定时器和回调函数
-
反复重写同一个属性会造成内存大量占用。(关闭IE后内存会被释放)
怎么避免内存泄漏
1)减少不必要的全局变量,或者生命周期
较长的对象,及时对无用的数据进行垃圾回收;
2)注意程序逻辑,避免“死循环”之类的 ;
3)避免创建过多的对象 原则:不用了的东西要及时归还。
21、谈谈你对BFC的理解?
22、说出三种前端清除浮动的方法
23、什么是强缓存和协商缓存
24·、说说git常用的命令有哪些?
25、说说你对git rebase 和git merge的理解?区别?
26、说说TCP为什么需要三次握手和四次挥手?
三次握手(Three-way Handshake)其实就是指建立一个TCP连接时,需要客户端和服务器总共发送3个包。
主要作用就是为了确认双方的接收能力和发送能力是否正常、指定自己的初始化序列号为后面的可靠性传送做准备。
四次挥手指的是在tcp终止一个连接时,需要四次挥手,当服务器在收到客户端的断开请求报文后,并不会立即关闭连接,而是先接受一个收到关闭连接的请求,当服务器的所有请求报文发送完毕之后,才能断开连接。
27、说说你对事件循环的理解?
JavaScript 在设计之初便是单线程,即指程序运行时,只有一个线程存在,同一时间只能做一件事
为了解决单线程运行阻塞问题,JavaScript用到了计算机系统的一种运行机制,这种机制就叫做事件循环。
同步任务进入主线程,异步进入任务队列,等主线程任务执行完,异步任务再推入主线程执行,这就是事件循环。
28、React render方法的原理,在什么时候会触发?
首先,render函数在react中有两种形式,在类组件中,指的是render方法,在函数组件中,指的是函数组件本身。
在render过程中,通常会编写jsx代码,会通过babel进行转换成我们熟悉的jsx代码,转换成createElement这种形式,用于生成虚拟DOM,最终转换成真实DOM。react将新调用的render函数返回的树与旧版本的树进行比较,这一步是决定如何更新DOM的必要步骤,然后进行diff比较,更新DOM树。
什么时候触发?
- 在react中,类组件只要执行了setState方法,就一定会触发render函数执行,函数组件使用useState更新状态不一定导致重新render。
- 组件的props 改变了,不一定触发 render 函数的执行,但是如果 props 的值来自于父组件或者祖先组件的 state。
- 在这种情况下,父组件或者祖先组件的 state 发生了改变,就会导致子组件的重新渲染。所以,一旦执行了setState就会执行render方法,useState会判断当前值有无发生改变确定是否执行render方法,一旦父组件发生渲染,子组件也会渲染
29、说说你对vue中mixin的理解?
mixin是面向对象程序设计语言中的类,提供了方法的实现。其他类可以访问mixin类的方法而不必成为其子类。
mixin是一种类,在vue中就是js文件,主要的作用是作为功能模块引用。
因为在项目中,可能不同组件会有相同的功能
比如控制元素的显示和隐藏,如果他们的变量和规则也完全相同的话,就可以把这个功能单独提取出来,放在mixin.js中,再引入,就可以实现一样的功能了。
引入的方法也分为全局混入和局部混入,局部混入就是在每个组件中引入,全局混入就是在main.js中通过Vue.mixin()引入。
30、说说你对redux中间件的理解?常用的中间件有哪些?实现原理?
Redux中,中间件就是放在dispatch过程,在分布action进行拦截处理。当action发出之后,reducer立即算出state,整个过程是一个同步的操作,如果需要异步操作,就需要中间件的支持。
常用redux中间件:
Redux-thunk : 用于异步操作
Redux-promise : 用于异步操作
Redux-logger : 用于日志记录
中间件都需要通过applyMiddleWares进行注册,作用是将所有的中间件组成一个数组,一次执行,然后作为第二个参数传入到createStore中。
----------------------未完待续----------------------