看了一些面经,不少人吐槽前端面试造火箭,入职拧螺丝。大多数问题感觉高大上,业务代码中几乎”用不到”。接下来整理一些常见高频的面试问题,及它们在工作中具体的应用场景和解决了什么问题。
HTTP 协议、HTTPS 协议、websocket
webSocket 和 ajax 的区别
dns 寻址过程?简述 cdn 原理
tcp 三次握手
最开始的时候客户端处于 Closed 的状态,服务端处于 Listen 状态。
接下来三次握手开始。
1、第一次握手:客户端给服务器发送 SYN 包,SYN=1,ACK=0 表示这是一个连接请求报文段,所以我们看到 SYN=1。同时初始化序列号 seq=x,此时客户端处于 SYN_SENT 状态。
2、第二次握手:服务器收到 SYN 包后,确认客户的 SYN,SYN=1,ACK=1 表示同意连接,所以我们看到服务器应答中 SYN=1,ACK=1。同时发送 ACK 报文,ack=x+1(客户端的序号(也就是 x)+1),并且初始化序列号 seq=y。此时服务器处于 SYN_REVD 状态。
3、第三次握手:客户端收到服务器的 SYN+ACK 包后,发送 ACK 报文,ack=y+1,标记序列号 seq=x+1(客户端序列号为 seq=x,第二个报文段所以要+1),此包发送完毕,客户端和服务器进入 ESTABLISHED(TCP 连接成功)状态。
注解:
序列号 seq: 用来标识从 TCP 源端向目的端发送的字节流,发起方发送数据时对此进行标记。
确认号 ack: 只有 ACK 标志位为 1 时,确认序号字段才有效,ack=seq+1。
https 有了解吗
加密过程
对称加密: 对称加密中使用的密钥叫做私钥,即同一个密钥既能加密又能解密,所以我们就能发现,如果被中间人拿到密钥,就没安全可言了。
非对称加密: 非对称加密使用的是一对密钥,即公钥和私钥。私钥只有服务器自己知道,公钥是公共的密钥。用公钥或私钥中的任何一个进行加密,用另一个进行解密。即公钥加密,私钥解密,或者私钥加密,公钥解密。这里我们再想一下,如果中间人拿到公钥,还是可以对服务端传来的数据进行解密,所以还不是安全的。
对称加密和非对称加密的结合
我们看下流程:
浏览器向服务器发送一个随机数和加密方法列表。
服务器接收到,返回另一个随机数、加密方法(从加密方法列表选择的一个方法)以及公钥。
浏览器接收,验证数字证书是否合法,如果验证不通过,拒绝执行。如果通过,会生成第三个随机数, 并且用公钥加密,传给服务器。
服务器用私钥解密加密过的第三个随机数。
浏览器和服务器用相同的加密方法混合这三个随机数,生成最终的密钥。
然后浏览器和服务器使用对称加密进行通信。中间人没有私钥,从而拿不到第三个随机数,也就无法生成最终的密钥了。简单讲了一下非对称加密的握手过程
证书签名过程和如何防止被串改
状态码
localstorage、sessionStorage 和 cookie 的区别
http2 的特点
http1 和 http2 有什么区别,http2 优势
跨域
webpack-dev-server 原理和如何处理跨域
nginx 转发
CROS 中的简单请求和非简单请求
非简单请求下发起的 options
JavaScript
我们都知道字符串是基本数据类型,基本类型是没有方法的,但为什么字符串还有很多方法?
JavaScript 为我们提供了三种特殊的包装用类型:String、Number 和 Boolean,方便我们操作对应的基本类型。在调用 length 的时候,JS 引擎会先对原始类型数据进行包装,术语叫装箱。
执行这段代码是,JS 引擎会从内存中读取 str 的值,然后会执行下面的操作:
创建 String 类型的一个实例 let newStr=new String();
在实例上调用该方法 let length=newStr.length;
销毁这个实例 newStr=null;
列出对数组产生副作用和没有副作用的方法
产生副作用的方法(改变了原来的数组):pop()、push() 、reverse() 、shift()、sort()、splice()、unshift()
没有副作用的方法(原来数组不变):concat()、join()、slice()、toString()、toLocaleString()、valueOf()
隐式转换
Common.js 和 es6 module 区别
- commonJs 是被加载的时候运行,esModule 是编译的时候运行
- commonJs 输出的是值的浅拷贝,esModule 输出值的引用
- webpack 中的 webpack_require 对他们处理方式不同
- webpack 的按需加载实现
weak-Set、weak-Map 和 Set、Map 区别
浏览器相关
- 浏览器加载/解析流程
- 浏览器渲染原理
- event loop 工作原理标准文档
缓存策略
- 强缓存 cache-control、express
- 协商缓存 304、ETag、modify
- 协商缓存相关的几个头部的之间的优先级关系
从 url 到页面显示
webpack
对 tree-shaking 的了解
讲讲 webpack 的性能优化
- 体积:讲了一下 tree-shaking 了解
- 打包速度:cache-loader、dll、多线程
写过 plugin 吗
webpack-dev-server 的 HMR 实现原理
框架相关
Vue nexttick
Vue 在更新 DOM 时是异步执行的。只要侦听到数据变化,Vue 将开启一个队列,并缓冲在同一事件循环中发生的所有数据变更。如果同一个 watcher 被多次触发,只会被推入到队列中一次。这种在缓冲时去除重复数据对于避免不必要的计算和 DOM 操作是非常重要的。然后,在下一个的事件循环“tick”中,Vue 刷新队列并执行实际 (已去重的) 工作。
参考链接
computed 和 watch 区别
computed 是计算属性,为了模板简洁和利于维护,我们把复杂逻辑,在 computed 里面实现。计算属性是基于它们的响应式依赖进行缓存的。只在相关响应式依赖发生改变时它们才会重新求值。也就是,它依赖的 data()里面的值如果变化,他就变化,反之,它的值不变。
watch 是监听属性,当需要在数据变化时执行异步或开销较大的操作时,这个方式是最有用的。
如果监听一个简单属性的变化,可以用 watch,如果是一个属性,依赖多个属性变化的时候,建议用 computed。
vue 路由实现原理
vue 是单页应用,所以当我们在页面进行一些操作改变路由的变化是,是不会向服务器发送请求的,浏览器监听到 url 的变化,从而更新页面。
有两种模式:
1、hash 例如 juejin.im/#/index
hash 模式是用 hashchange 的方法监听 url,当 URL 的 hash 部分改变时,页面不会重新加载。并且向服务端发送的请求是https://juejin.im/部分
注意: 页面刷新的时候,不会向服务器发送请求
2、history 例如 juejin.im/index
history 模式充分利用 history.pushStateAPI 来完成 URL 跳转而无须重新加载页面。主要使用 history.pushState 和 history.replaceState 改变 URL。使用 history 模式,我们需要在路由里面加这行代码 mode:history,然后需要后端配置一个覆盖所有情况的候选资源:如果 URL 匹配不到任何静态资源,则应该返回同一个 index.html 页面,这个页面就是你 app 依赖的页面。
router.push、 router.replace 和 router.go 跟 window.history.pushState、 window.history.replaceState 和 window.history.go 好像, 实际上它们确实是效仿 window.history API 的。
注意: 页面刷新的时候,会向服务器发送请求
谈下 vue 和 react 的差异
mvvm 模型和 mvc 模型区别
如何实现一个 mvvm 模型
说说 vnode 的了解
安全问题
xss、csrf 有了解过吗,如何防范
jsonp 如何防止 xss
cookie 有什么用?存在什么问题?如何解决?crsf 如何防范?
高级技巧
谈下对前端微服务的理解,有什么好处,有什么坏处
谈下对 serverless 架构的理解
前端适配方案
如果让你搭建一套前端监控方案,具体思路
如何定位内存泄露
前端监控(用户轨迹埋点、错误监控)
正则表达式
大型文件上传
requestAnimationFarme 和 setTimeout 区别
鉴权
- Seesion/cookie
- Token
- OAuth
- SSO
性能优化
dll 分包、按需加载、图片 base64、gzip 压缩
为什么要做这件事情(交代背景和原因)
实施过程是怎么样的,遇到了什么困难,如何解决?(确认你参与度)
最后取得了什么样的成效(最好能提供实际数据)?
拓展:在大量的用户(数据)环境下,会遇到什么样的问题?
比如:监控海量日志怎么样写入(小公司哪有海量日志,所以需要自己拓展思考)
node
流
洋葱模型
中间件实现逻辑
实现一个函数 compose([fn1,fn2,fn3..]) 转成 fn3(fn2(fn1()))
canvas
页面下雪
Typscript
- 接口
- 枚举
- 泛型
编程题-算法与数据结构
- 实现 Promise
- 实现 xss-filter
- 实现正则获取 url params
- 合并 n 个有序链表
- 渲染一个超长的 list,实现 dom 节点的复用
- random7 实现 random10
- 实现正则切分千分位(10000 => 10,000)
- 实现正则切分银行卡卡号(像实体卡一样四位一个空格)
- 实现 jsonp
- 判断一个 ipv4 地址是否存在已有的 1000 万条 ipv4 地址中(bitmap)
- 实现 call、apply、bind,实现 new,实现 instanceof
- 一次可以走一步或者两步,n 个阶梯的楼梯有多少种走法
- 实现扫雷(二维数组,随机分布地雷坐标)
- 计算累进税率
- 求一个数组中比左边和右边的元素都大的元素(On)
- 实现双向绑定
- 实现 InputNumber
- FIFO
- 最短优先
- 电梯算法
简历书写
对答过程
自我介绍
你有什么想问的?
面试官您好,我想知道您听完我的回答有什么比较好的建议么?(你谦虚好学)
进去之后的晋升机制是怎样的?会经常有技术交流的活动么?(积极上进)