精选十道前端面试题

532 阅读9分钟

最近一直在面试候选人,总结了一些出现频率非常高的10道面试题,分享给大家。

1. 说说输入URL回车后的过程

1.读取缓存: 
        搜索自身的 DNS 缓存。(如果 DNS 缓存中找到IP 地址就跳过了接下来查找 IP 地址步骤,直接访问该 IP 地址。)
2.DNS 解析:将域名解析成 IP 地址
3.TCP 连接:TCP 三次握手,简易描述三次握手
           客户端:服务端你在么? 
           服务端:客户端我在,你要连接我么? 
           客户端:是的服务端,我要链接。 
           连接打通,可以开始请求来
4.发送 HTTP 请求
5.服务器处理请求并返回 HTTP 报文
6.浏览器解析渲染页面
7.断开连接:TCP 四次挥手

关于第六步浏览器解析渲染页面又可以聊聊如果返回的是html页面
根据 HTML 解析出 DOM 树
根据 CSS 解析生成 CSS 规则树
结合 DOM 树和 CSS 规则树,生成渲染树
根据渲染树计算每一个节点的信息
根据计算好的信息绘制页面


2. JavaScript的深拷贝浅拷贝是指什么,有什么区别?

浅拷贝:浅拷贝通过ES6新特性Object.assign()或者通过扩展运算法...来达到浅拷贝的目的,浅拷贝修改
副本,不会影响原数据,但缺点是浅拷贝只能拷贝第一层的数据,且都是值类型数据,如果有引用型数据,修改
副本会影响原数据。

深拷贝:通过利用JSON.parse(JSON.stringify())来实现深拷贝的目的,但利用JSON拷贝也是有缺点的,
当要拷贝的数据中含有undefined/function/symbol类型是无法进行拷贝的,当然我们想项目开发中需要
深拷贝的数据一般不会含有以上三种类型,如有需要可以自己在封装一个函数来实现。

引申问题:什么是引用类型?实现深拷贝函数的思路是什么?

3. 说说CSS实现垂直居中有哪些方式?

1. 子元素 line-height 值为父元素 height2. table布局,display: table-cell;
3. flex布局,align-items: center;
4. 绝对定位,top: 50%;transform: translate( 0, -50%);
5. display: inline-block;和vertical-align: middle同时使用。

4. 前端安全XSS和CSRF分别指什么?如何预防?

1. XSS:跨站脚本攻击

攻击者想尽一切办法将可以执行的代码注入到网页中

存储型(server端):
场景:见于带有用户保存数据的网站功能,如论坛发帖、商品评论、用户私信等。
攻击者将恶意代码提交到目标网站的数据库中用户打开目标网站时,服务端将恶意代码从数据库中取出来,拼接在HTML中返回给浏览器

反射型(Server端)
场景:通过 URL 传递参数的功能,如网站搜索、跳转等。
攻击者构造出特殊的 URL,其中包含恶意代码。用户打开带有恶意代码的 URL 时,网站服务端将恶意代码从 URL 中取出,拼接在 

Dom 型(浏览器端)
DOM 型 XSS 攻击中,取出和执行恶意代码由浏览器端完成,属于前端 JavaScript 自身的安全漏洞,而其他两种 XSS 都属于服务端的安全漏洞。


预防方案:(防止攻击者提交恶意代码,防止浏览器执行恶意代码)
1. 对数据进行严格的输出编码:如HTML元素的编码,JS编码,CSS编码,URL编码等等
避免拼接 HTML;Vue/React 技术栈,避免使用 v-html / dangerouslySetInnerHTML
2. CSP HTTP Header,即 Content-Security-Policy、X-XSS-Protection
增加攻击难度,配置CSP(本质是建立白名单,由浏览器进行拦截)
Content-Security-Policy: default-src 'self' -所有内容均来自站点的同一个源(不包括其子域名)
Content-Security-Policy: default-src 'self' *.trusted.com-允许内容来自信任的域名及其子域名 (域名不必须与CSP设置所在的域名相同)
Content-Security-Policy: default-src https://yideng.com-该服务器仅允许通过HTTPS方式并仅从yideng.com域名来访问文档
3. 输入验证:比如一些常见的数字、URL、电话号码、邮箱地址等等做校验判断
4. 开启浏览器XSS防御:Http Only cookie,禁止 JavaScript 读取某些敏感 Cookie,攻击者完成 XSS 注入后也无法窃取此 Cookie。
5. 验证码

2. CSRF:跨站请求伪造

攻击者诱导受害者进入第三方网站,在第三方网站中,向被攻击网站发送跨站请求。利用受害者在被攻击网站已经获取的注册凭证,绕过后台的用户验证,达到冒充用户对被攻击的网站执行某项操作的目的


攻击流程:
1. 受害者登录 a.com,并保留了登录凭证(Cookie2. 攻击者引诱受害者访问了b.com
3. b.coma.com 发送了一个请求:a.com/act=xx浏览器会默认携带a.comCookie
4. a.com接收到请求后,对请求进行验证,并确认是受害者的凭证,误以为是受害者自己发送的请求
5. a.com以受害者的名义执行了act=xx
6. 攻击完成,攻击者在受害者不知情的情况下,冒充受害者,让a.com执行了自己定义的操作

攻击类型:
1. GET型:如在页面的某个 img 中发起一个 get 请求
2. POST型:通过自动提交表单到恶意网站
3. 链接型:需要诱导用户点击链接

预防方案:

1. 同源检测:通过Header中的Origin HeaderReferer Header 确定,但不同浏览器可能会有不一样的实现,不能完全保证
2. CSRF Token 校验:将CSRF Token输出到页面中(通常保存在Session中),页面提交的请求携带这个Token,服务器验证Token是否
正确
3. 双重cookie验证:在用户访问网站页面时,向请求域名注入一个Cookie,内容为随机字符串(例如csrfcookie=v8g9e4ksfhw)
,在前端向后端发起请求时,取出Cookie,并添加到URL的参数中,后端接口验证Cookie中的字段与URL参数中的字段是否一致,不一致则拒绝。
4. Samesite Cookie属性

5. 谈谈前端工程化、模块化、组件化

1. 前端工程化

1、将前端项目当成一项系统工程进行分析、组织和构建从而达到项目结构清晰、分工明确、团队配合默契、开发效率提高的目的
2、工程化思维就是“结构、样式和动作分离”。如目录分为assets,components,router,util

2. 前端模块化

1、可以简单的认为模块化和组件化是工程化的表现形式
2、JS模块化方案很多有AMD/CommonJS/UMD/ES6 Module等,CSS模块化开发大多是在less、sass、stylus

3. 前端组件化

1、组件化将页面视为一个容器,页面上各个独立部分例如:头部、导航、焦点图、侧边栏、底部等视为独立组件,不同的页面根据内容的需要,去盛放相关组件即可组成完整的页面。
2、模块化和组件化一个最直接的好处就是复用+分治

6. 说说Vue双向绑定怎么实现的?

Vue是采用数据劫持配合发布者-订阅者模式,通过Object.defineProperty来()来劫持各个属性的getter和setter
在数据发生变化的时候,发布消息给依赖收集器,去通知观察者,做出对应的回调函数去更新视图。

具体就是:
MVVM作为绑定的入口,整合Observe,Compil和Watcher三者,通过Observe来监听model的变化
通过Compil来解析编译模版指令,最终利用Watcher搭起Observe和Compil之前的通信桥梁
从而达到数据变化 => 更新视图,视图交互变化(input) => 数据model变更的双向绑定效果。

引申问题:vue3.0的双向绑定有什么改变,优点是什么?

7. 谈谈babel的作用,流程是什么?

概述:

Babel是一个工具,主要用于将 ECMAScript 2015+ 版本的代码转换为向后兼容的 JavaScript 语法,以便能够运行在当前和旧版本的浏览器或其他环境中。

流程:
解析: 将代码(其实就是字符串)转换成 AST( 抽象语法树)
转换: 访问 AST 的节点进行变换操作生成新的 AST
生成: 以新的 AST 为基础生成代码

AST是一种树形结构,用来描述代码的变量声明、赋值、括号、函数调用等等

Babel 在转译的时候,会将源代码分成 语法(syntax) 和 特性(api) 两部分来处理:

1. syntax:类似于展开对象、optional chain、let、const 等语法。
2. api:类似于 [1,2,3].includes ,map等函数、方法。


8. 说说前端性能优化方案

多个方面来说明前端性能优化

常规:
webapck优化与开启gzip压缩
    1.babel-loader用 include 或 exclude 来帮我们避免不必要的转译,不转译node_moudules中的js文件
    其次在缓存当前转译的js文件,设置loader: 'babel-loader?cacheDirectory=true'
    2.文件采用按需加载等等
    3.具体的做法非常简单,只需要你在你的 request headers 中加上这么一句:
    accept-encoding:gzip
    4.图片优化,采用svg图片或者字体图标
    5.浏览器缓存机制,它又分为强缓存和协商缓存
缓存:

本地存储——从 Cookie 到 Web Storage、IndexedDB
    说明一下SessionStorage和localStorage还有cookie的区别和优缺点

跨界:

React Native,Flutter,HTTP2,3等等。

9. 遇到白屏问题如何分析和解决?

检测白屏:

1. 检测页面关键DOM的是否渲染

2. 通用的DOM渲染监听

3. H5截图(canvas绘图)检测

4. native截图(容器截屏)检测

5. 利用performance.getEntries("paint")获取fp/fcp来感知渲染

原因分析:

1. 网络状态
2. 脚本报错
3. js,css和浏览器或者webview兼容性问题

解决方案:

1. 骨架屏
2. 启用服务端渲染SSR
3. 首屏静态html
4. 离线包或者PWA

10. 你在工作中遇到哪些复杂问题,解决方法是什么?

开放题