前端专业面试真题(2)

1、说一下fetch 请求方式?

fetch是一种HTTP数据请求的方式,是XMLHttpRequest的一种替代方案。Fetch函数计算元素js,没有使用XMLHttpRequest对象。fetch()方法返回一个Promise解析Response来自Request显示状态(成功与否)的方法。使用XMLHttpRequest的问题是所以功能全部集中在一个对象上,容易书写出混乱而且不容易维护的代码,采用传统的事件驱动模式,无法适配新的Promise API Fetch API的特点是精细的功能分割:头部信息,请求信息,响应信息等均匀分布到不同的对象,更有利于处理各种复杂的数据交互场景;使用Promise API更有利于异步代码的书写,同源请求也可以自定义不带cookie,某些服务不需要cookie场景下能少些流量

2、说一下有什么方法可以保持前后端实时通信?

1.轮询、长轮询、 iframe流、WebSocket、SSE
2.轮询是客户端和服务器之间会一直进行连接,每隔一段时间就询问一次。
3.长轮询是对轮询的改进版,客户端发送HTTP给服务器之后,如果没有新消息,就一直等待。有新消息,才会返回给客户端。
4.iframe流方式是在页面中插入一个隐藏的iframe,利用其src属性在服务器和客户端之间创建一条长连接,服务器向iframe传输数据(通常是HTML,内有负责插入信息的javascript),来实时更新页面。
5. WebSocket是类似Socket的TCP长连接的通讯模式,一旦WebSocket连接建立后,后续数据都以帧序列的形式传输。
6.SSE(Server-Sent Event)是建立在浏览器与服务器之间的通信渠道,然后服务器向浏览器推送信息。
7.应用:
轮询适用于:小型应用,实时性不高
长轮询适用于:一些早期的对及时性有一些要求的应用:web IM 聊天
iframe适用于:客服通信等
WebSocket适用于:微信、网络互动游戏等
SSE适用于:金融股票数据、看板等

3、说一下浏览器输入URL发生了什么?

1、URL解析:判断浏览器输入的是搜索内容还是URL;

2、查找缓存:如果能找到缓存则直接返回页面,如果没有缓存则需要发送网络请求页面;3、DNS域名解析;

4、三次握手建立TCP连接;

5、发起HTTP请求;

6、服务器响应并返回结果;

7、通过四次挥手释放TCP连接;

8、浏览器渲染;

9、js引擎解析

4、说一下浏览器如何渲染页面的?

1. 获取html文件后,渲染引擎会对将HTML代码解析为DOM结构,同时获取CSS;

2. 将获取到的CSS解析为CSSOM树,与DOM树并发解析;

3.解析JS脚本对DOM树和CSSOM树进行修改。

4.将DOM树和CSSOM树合成为render树

5.对render树上节点进行布局,确定其位置,如果元素位置后续被改变而触发重新绘制叫做回流。

6.对摆好位置的节点进行色彩渲染,如果元素样式后续被改变而触发页面重新绘制叫做重绘。

7.加载剩余的img,video等媒体文件。

5、说一下重绘、重排区别如何避免?

重绘不一定引起重排、但重排一定会引起重绘。避免:使用translate替代top、使用visibility代替display:hidden、none、DOM离线后修改、使用class去修改样式、使用 absolute 或 fixed 脱离文档流 、使用GPU加速提升网站的动画渲染性能:transform、transform: translateZ(0); 或 transform: translate3d(0,0,0);不要选择table布局

6、说一下浏览器垃圾回收机制?

1、标记清除:对所有活动对象进行标记,清除阶段会将没有标记的对象清除;标记整理算法:标记结束后,算法将活动对象压入内存一端,则需要清理的对象在边界,直接被清理掉就行。(效率低)

 2、引用计数:将对象是否不再需要简化定义为有没有其他对象引用它,如果没有引用指向这个对象,则会被垃圾回收机制回收。(内存空间不连续)

7、说一说事件循环Event loop,宏任务与微任务?

eventloop,首先执行同步任务,并把同步任务里的异步任务放入队列中,当执行完同步任务后会执行队列中的异步任务,异步任务分为宏任务和微任务,首先执行宏任务,把宏任务里的微任务放入队列中,然后执行微任务。

宏任务有定时器,Dom事件,ajax事件,微任务有:promise的回调、MutationObserver 的回调 ,process.nextTick

8、说一说跨域是什么?如何解决跨域问题?

跨域:受浏览器同源策源(即协议,域名,端口号必须一致是浏览器的一种安全模式)的影响不能执行其他网站的脚本 解决的办法:

前端:

1.利用script中src属性发送jsonp请求但是这种方式只支持get请求无法解决其他的请求类型

2.前端配置一个代理服务器(proxy)代替浏览器去发送请求:因为服务器与服务器之间是可以通信的不受同源策略的影响。

服务端:

服务端通过配置cors来解决跨域,配置响应头:setHeader(access-control-allow-origin,对应的域名) 

9、说一说vue钩子函数?

1、概念:Vue实例创建和销毁过程中自动执行的函数;

2、常见的生命周期中的钩子函数:创建阶段:beforeCreate,create,beforeMount,mount;更新阶段:beforeUpdate,update,activeted;销毁阶段:beforeDestroy,destroy。

3、完整的父子组件生命周期执行顺序:- 加载渲染过程:父beforeCreate —> 父created —> 父beforeMount —> 子beforeCreate —> 子created —> 子beforeMount —> 子mounted —> 父mounted - 子组件更新过程:父beforeUpdate —> 子beforeUpdate —> 子updated —> 父updated - 父组件更新过程:父beforeUpdate —> 父updated - 销毁过程:父beforeDestroy —> 子beforeDestroy —> 子destroyed —> 父destroyed

10、说一说组件通信的方式?

Vue的组件通信一般分为三大类。

1:父子组件通信,最常见的使用props和emit,父组件通过props将数据传递给子组件,子组件通过emit触发父组件中的方法来修改数据。其次还可以通过$ref、$parent和$child进行通信。

2:祖孙组件之间的通信:这种通信一般也可以用props和emit只不过逐层传递会很麻烦,可以可以使用$listener和$attrs来进行通信。

3:兄弟组件之间的通信:可以创建eventBus事件总线,通过$emit和$on的方式进行通信。其次还有全局数据通信,我们可以使用Vuex作为全局状态管理来实现。

11、说一说computed和watch的区别?

computed是计算属性,依赖其他属性值,并且有缓存,只要他依赖的值发生改变了,下一次获取computed的值时才会重新计算computed的值;watch更多的是监听观察作用,支持异步,每当监听的数值发生变化时就会立即回调进行后续操作。

12、说一说 v-if 和 v-show区别?

v-if和v-show都是用来控制DOM元素是否显示在页面上,v-if是通过从DOM树上插入和删除实现控制DOM元素的显示,而v-show通过设置元素的css属性display控制DOM元素的显示。

13、说一说 vue 的 keep-alive ?

1、keep-alive是vue的内置组件,能在组件切换过程中将状态保留在内存中,相当于缓存,防止DOM的重复渲染;

2、keep-alive有三个属性:include(只有名字匹配的才会被缓存)、exclude(任何名字匹配的都不会被缓存)、max(最多可以缓存多少个组件)。

3、在路由router的中:相应组件下规定meta属性,定义keep-alive:true;

4、可以结合Vue组件实例加载顺序讲解,VNode->实例化->_updata->真实Node,在实例化的时候会判断该组件是否被keep-alive保存过,是的话则直接拿其中的DOM进行渲染。

14、说一说 Vue 中 $nextTick 作用与原理?

vue中更新dom是异步操作,在修改完数据后,视图不会立刻更新,而是当同一事件循环中的所有数据变化完成之后,再进行统一的更新,所以有的时候在修改完数据后想要获取更新后的dom,则需要在nextTick中获取,nextTick的作用就是在当前渲染完成后执行,,解决了异步获取不到更新后dom问题,本质是反回promise 

15、说一说 Vue 列表为什么加 key?

Vue列表加key的目的是为diff算法添加标识,因为diff算法判断新旧VDOM是否相同的依据是节点的tag和key。如果tag和key相同则会进一步进行比较,使得尽可能多的节点进行复用。此外,key绑定的值一般是一个唯一的值,比如id。如果绑定数组的索引index,则起不到优化diff算法的作用,因为一旦数组内元素进行增删,后续节点的绑定的key也会发生变化,导致diff进行多余的更新操作。

16、说一说vue-router 实现懒加载的方法?

懒加载的核心思想是按需加载,也叫做异步加载:只有请求到该组件的时候,才会对该组件进行网络请求并加载。懒加载有利于解决页面首次请求资源过多,导致白屏时间长的问题。 vue-router的懒加载即通过箭头函数的写法导入组件如 const Login = ()=> import('../路径');

17、说一说 HashRouter 和 HistoryRouter的区别和原理?

1.history和hash都是利用浏览器的2种特性实现前端路由,history是利用浏览历史记录栈的API实现,hash是监听location hash值变化事件来实现

2.history的url没有#号,hash有#号 3.相同的url,history会触发添加到浏览器历史记录栈中,hash不会触发,history需要后端配合,如果后端不配合刷新页面会出现404,hash不需要 hashRouter原理:通过window.onhashchange获取url中hash值 historyRouter原理:通过history.pushState,使用它做页面跳转不会触发页面刷新,使用window.onpopstate监听浏览器的前进和后退

18、说一说Vuex是什么,每个属性是干嘛的,如何使用 ?

Vuex是为Vue开发的管理状态模式,集中存储管理所有组件的状态。属性分别由state、getters、mutations、actions、module。

(1)state用来定义所要存储的数据,通过$store.state调用数据

(2)getters可以认为是store的计算属性,通过$store.getters调用属性

(3)mutations用来存放改变state数据的同步方法,每个方法接收的参数都是state,用$store.commit来调用mutations中的同步方法

(4)actions用来存放异步方法,接收的参数是context(mutations中的方法),通过$store.dispatch调用actions中的方法

(5)module将store分割成模块,每个模块有自己的state、getters、mutations、actions、甚至嵌套子模块,从上至下进行同步分割 前四个属性除了用$store的方法调用,还能通过import { mapState/mapGetters/... } from 'vuex'引入,再用...mapState/mapGetter/...(['属性/方法名'])的形式映射进来调用

19、说一说Vue2.0 双向绑定的原理与缺陷?

原理:通过数据劫持defineProperty+发布订阅者模式,当vue实例初始化后observer会针对实例中的data中的每一个属性进行劫持并通过defineProperty()设置值后在get()中向发布者添加该属性的订阅者,这里在编译模板时就会初始化每一属性的watcher,在数据发生更新后调用set时会通知发布者notify通知对应的订阅者做出数据更新,同时将新的数据根性到视图上显示。缺陷:只能够监听初始化实例中的data数据,动态添加值不能响应,要使用对应的Vue.set()。

缺陷:不能监听数组的push等方法,用其他方法实现的,defineProperty只能监听对象的单个属性,需要递归对所有属性的监听

缺点是不能监听新对象的新增属性和删除属性,不能监听通过下标改变数组对应数据

20、说一说Vue3.0 实现数据双向绑定的方法 ?

【Vue3.0 数据双向绑定】
1. 在Vue2.0的基础上将Object.definedproperty换成了功能更强大的Proxy,原理相同。在vue实例初始化的时候(vm._init()执行的时候)调用Observe类的实例方法observe,传入数据(若是对象则发生递归),将其中每个数据进行一遍数据劫持(get实现依赖收集,set实现事件派发(这里的模式为发布订阅模式))。
2. 相对vue2.0解决的问题:解决无法监听新增属性或删除属性的响应式问题、解决无法监听数组长度和index变化问题。
【关于Proxy】
1. Proxy是ES6新增的一个特性,实现的过程是在目标对象之前设置一层“拦截”,外界对该对象的访问都必须先通过这层拦截,因此提供了一种机制,可以对外界的访问进行过滤和改写。
2. 用法:ES6原生提供Proxy构造函数,用来生成Proxy实例。var proxy=new Proxy(target,handler)target是用Proxy包装的被代理对象(可以是任何类型的对象,包含原生数组,函数,甚至是另一个代理)。handler是一个对象,其声明了代理target的一些操作,其属性是当执行一个操作时定义代理的行为的函数。

21、React生命周期的各个阶段是什么?

在加载阶段React分为这么几个生命周期:

1.constructor 用于初始化state,执行父类的构造函数。

2:getSnapStateFromProps 在加载和更新过程中都会触发。

3:rende函数会将jsx生成的dom插入到目标节点中。

4:componentDidMount挂载完成,此时虚拟DOM已经变为真实DOM挂载到根节点上。

在更新过程中分为这么几个生命周期;getSnapStateFromProps,shouldConponentUpdate询问是否需要更新组件,render函数,componentDidUpdate。

在销毁过程中分为:componentWillUnMount

22、ReactRouter基本用法是什么?

得分点 路由的模式有两种、hash模式、history模式、路由的动态传参、重定向、高阶路由组件。

标准回答 react的路由保证了界面和URL的同步,拥有简单的API和强大的功能。react中的路由模式有两种,分别是:hash路由和history路由。 - 首先用析构的方法引入需要用到的路由方式,需要注意的是路由所有的配置都必须被包裹在hash路由或者history路由里面。 - 然后在路由标签内先再配置Route标签,它的参数有:path,路由匹配的路径。component,路由匹配成功之后渲染的组件。 - react中路由的跳转使用Link标签,它的参数to指路由匹配的路径,也需要引入。NavLink标签和Link的区别就是渲染成a标签之后会自带一个class属性,对应的是NavLink标签的active属性。 - react路由中有高阶路由组件withRouter,它和普通路由一样需要引入,主要作用是增加了路由跳转的方式,可以调用history方法进行函数中路由的跳转。 - react中路由的动态传值是一个重点,{/:属性名}和{/属性名/值}搭配的方式进行传值,在需要接收参数的组件通过this.props.match.params来进行接收。react中路由的query传值是通过问号的方法将参数拼接在url之后,在需要接收参数的组件通过url.parse(this.props.location.search).query获取参数。 - 路由的重定向需要用组件Redirect来完成,参数to是目标组件。 - 路由的懒加载需要从react中引入Suspense和lazy,引入组件时通过lazy(() => import())来引入,使用Suspense标签将Route包裹起来即可。 加分回答 react中路由模式分为hash路由和history路由。hash路由的原理是window.onhashchange监听,url前面会有一个#号,这个就是锚点,每个路由前面都会有#锚点,特点是#之后的数据改变不会发起请求,因此改变hash不会重新加载页面。history路由的原理是window.history API,在HTML5中新增了pushState和replaceState方法,这两个方法是在浏览器的历史记录栈上做文章,提供了对历史记录做修改的功能,虽然更改了url但是不会向服务器发起请求。history模式虽然去掉了hash模式的#锚点,但是它怕刷新,因为刷新时是真实的请求。而hash模式下,修改的是#锚点之后的信息,浏览器不会将#锚点之后的数据发送到服务器,所以没有问题。

23、React组件间传值的方法有哪些?

props:适用于父子组件的通信,props以单向数据流的形式可以很好的完成父子组件的通信
React Context:适用于父子组件以及隔代组件通信,React Context提供了一个无需为每层组件手动添加props就能在组件树间进行数据传递的方法。
Refs:适用于父子组件的通信,Refs提供了一种方式,允许我们访问DOM节点或在render方法中创建的React元素
EventBus:可以适用于任何情况的组件通信,在项目规模不大的情况下,完全可以使用中央事件总线EventBus 的方式,EventBus可以比较完美地解决包括父子组件、兄弟组件、隔代组件之间通信,实际上就是一个观察者模式
Redux:同样可以适用于任何情况的组件通信,Redux中提出了单一数据源Store用来存储状态数据,所有的组件都可以通过Action修改Store,也可以从Store中获取最新状态,使用了redux就可以解决多个组件的共享状态管理以及组件之间的通信问题。

24、setState是同步还是异步的?

setState在合成事件和生命周期函数中是异步的,在原生事件和定时器中都是同步的。
setState本身不分同步或者异步,而且取决于是否处于batch update中。组件中所有函数在执行时临时设置一个变量isBatchingUpdates=true,当遇到setState时,如果isBatchingUpdates是true,那么setState就是异步的,如果是false,那么setStete就是同步的。
那么什么时候isBatchingUpdate会被设置成false呢,就是当函数运行结束时isBatchingUpdates = false - 当函数遇到setTimeout、setInterval时isBatchingUpdates = false - 当dom添加自定义事件时isBatchingUpdates = false

25、React事件绑定原理

React中的event事件不是原生事件,是对原生event进行封装成新的合成事件。react17之前事件是挂载在document上,之后是挂载在root上。当事件发生并冒泡至root处时,react会将事件内容封装交由真正的函数执行,这样可以减少内存消耗,同时可以在组件挂载销毁时统一订阅和移除事件。想要阻止冒泡的话,需要调用event.preventDefault,调用event.stopPropagation是无效的。

采用合成事件的原因:
1. 兼容所有的浏览器和实现跨平台开发,
2. 统一挂载在document上,减少内存的消耗,方便在组件挂载/卸载时统一订阅和移除事件,
3. 方便事件统一管理

26、React中hooks的优缺点是什么?

【Hook的优点】:
1.让函数组件拥有自己的状态和生命周期。
2.使用函数组件加Hooks代码更加简洁。
3.不需要老是去纠结this指向的问题。
4.通过自定义hooks实现逻辑复用。

【缺点】:class组件的三个生命周期函数合并在一个生命周期函数内。

27、说一说前端性能优化手段?

前端资源比较庞大,包括HTML、CSS、JavaScript、Image、Flash、Media、Font、Doc等等,前端优化相对比较复杂,对于各种资源的优化都有不同的方式,按粒度大致可以分为两类:
一类是文件加载更快
1. 让传输的数据包更小(压缩文件/图片):图片压缩和文件压缩
2. 减少网络请求的次数:雪碧图/精灵图、节流防抖
3. 减少渲染的次数:缓存(HTTP缓存、本地缓存、Vue的keep-alive缓存等)

另一类是文件渲染更快
1. 提前渲染:ssr服务器端渲染
2. 避免渲染阻塞:CSS放在HTML的head中 JS放在HTML的body底部
3. 避免无用渲染:懒加载
4. 减少渲染次数:对dom查询进行缓存、将dom操作合并、使用减少重排的标签

在用户角度前端优化可以让页面加载得更快,对用户的操作响应得更及时,能够给用户提供更为友好的体验,在服务商角度前端优化能够减少页面请求数,减小请求所占带宽,能够节省服务器资源。

28、说一说性能优化有哪些性能指标,如何量化?

1.性能评估 Chrome Performance选项卡 / Lighthouse 生成性能检测报告
2.值得关注的性能指标
(1)LCP (Largest Contentful Paint 最大内容绘制 )
(2)首屏渲染时间(也叫白屏时间)
(3)FCP (Fitst Contentful Paint 首先内容绘制 )
(4)可交互时间 (Time to Interactive TTI)
(5) Network请求时间(jax,js等)
3.浏览器开发者工具什么都能看得到,可以调用性能监测API 或建立 前端监控系统(无痕埋点)

29、说一说服务端渲染?

【概念】
1.- 传统服务端渲染 : JSP/PHP等等(前后端不分离的旧时代,模板引擎,后端拿到前端页面替换数据,前后端耦合)
- 现代服务端渲染 : (Vue->Nuxt.js,React->Next.js,自己做SSR , 前后端分离的同时实现SSR)
2. 服务端渲染(SSR)即是在服务器端渲染完整的HTML后返回给客户端(通常是浏览器)。
3. 客户端渲染(CSR),也就是常见的单页面应用(SPA),由服务器端返回的初始 HTML 页面,由 JS 去异步加载数据,完成页面的渲染。由于ajax请求是异步 的,百度Google等搜索引擎抓取的页面是几乎空白的,可以右键查看网页源代码看是否完整的HTML结构判断是SSR还是CSR。
4. 同构渲染,就是将SSR和CSR结合在一起,服务端渲染首屏后,激活应用,按照SPA方式运行,结合CSR和SSR各自优点。

【服务端渲染优点】
从上可知,服务端渲染的优点是:
- 搜索引擎爬虫能爬取完整HTML,有利于做搜索引擎优化(SEO),提高网站流量和曝光率
- 首屏渲染在服务端就完成,所以有更快的首屏加载速度
- 只是首屏快,其他页面不像SPA一样是无感刷新,切换页面通过超链接进行页面跳转,体验稍差(传统PHP/JSP)

【服务端渲染缺点】
服务端渲染的缺点:
- 由于是在服务端进行渲染,需要占用更多服务器端资源(更多的CPU和内存)。
- 由于在服务端渲染,所以有些浏览器API无法使用,同样地 客户端一些生命周期在SSR也是不存在的。
- 部署和开发要求稍高,前后端耦合。

30、XSS攻击是什么?

1.XSS是跨站脚本攻击(Cross Site Scripting)
2.攻击者可以通过向Web页面里面插入script代码,当用户浏览这个页面时,就会运行被插入的script代码,达到攻击者的目的。
3.危害:泄露用户的登录信息cookie;恶意跳转:直接在页面中插入window.location.href进行跳转。
4.防止XSS攻击的方法:
1).对输入框内容进行过滤和转码。过滤掉用户输入的与事件有关的回调,如onclick,过滤掉用户输入的style标签,script标签。
3).设置cookie的httponly,告诉浏览器不对客户端开放访问权限。
1).对用户的输入做Html实体编码
3).不对html实体直接进行解码

31、CSRF攻击是什么?

1.概念:跨域请求伪造。
2. 目标站点仅使用cookie来验证,并且cookie是允许跨域的,这就使得恶意站点的页面能拿到用户的cookie.
2. 目标站点后端没有验证请求的来源,导致任何带有效cookie的请求都被处理。
3. 用户被诱导访问了恶意站点
预防CSRF攻击主要有以下策略:
-使用验证码,在表单中添加一个随机的数字或者字母验证码,强制要求用户和应用进行直接的交互,
-HTTP中Referer字段,检查是不是从正确的域名访问过来,他记录了HTTP请求的来源地址。
-使用token认证,在HTTP请求中添加token字段,并且在服务器建立一个拦截器验证这个token,如果token不对,就拒绝这个请求。

32、说一下Diff算法?

1、Diff算法主要就是在虚拟DOM树发生变化后,生成DOM树更新补丁的方式,对比新旧两株虚拟DOM树的变更差异,将更新补丁作用于真实DOM,以最小成本完成视图更新;

2、框架会将所有的结点先转化为虚拟节点Vnode,在发生更改后将VNode和原本页面的OldNode进行对比,然后以VNode为基准,在oldNode上进行准确的修改。(修改准则:原本没有新版有,则增加;原本有新版没有,则删除;都有则进行比较,都为文本结点则替换值;都为静态资源不处理;都为正常结点则替换)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值