# 校招前端面试常见问题【4】——网络及浏览器

## 1、网络相关

### Q：请简述一下 HTTP 协议，以及 HTTP1.0/1.1/2.0/3.0 的区别？

HTTP 协议：超文本传输协议，使用 TCP/IP 协议传输数据。是一个应用层的协议。

HTTP1.0：HTTP 1.0 规定浏览器与服务器只保持短暂的连接，浏览器的每次请求都需要与服务器建立一个 TCP 连接，服务器完成请求处理后立即断开 TCP 连接，服务器不跟踪每个客户也不记录过去的请求。因此 HTTP 1.0 存在很大的性能缺陷——当访问一个包含有许多资源文件的网页时，每次请求和响应都需要建立一个单独的连接，每次连接只是传输一个文档和图像，请求之间完全分离。即使图像文件都很小，但是客户端和服务器端每次建立和关闭连接却是一个相对比较费时的过程，会严重影响到性能。

HTTP 1.1：支持长连接的 HTTP 协议，在一个 TCP 连接上可以传送多个 HTTP 请求和响应。一个包含有许多图像的网页文件的多个请求和应答可以在一个连接中传输，但每个单独的网页文件的请求和应答仍然需要使用各自的连接。

HTTP2.0：支持多路复用的 HTTP 协议。 HTTP 2.0 允许同时通过单一的 HTTP 2.0 连接发起多重的请求-响应消息。所有通信都在一个连接上完成，这个连接可以承载任意数量的双向数据流。由于 TCP 有慢启动的特点，如果 HTTP 连接很多，就会十分低效。HTTP/2 通过让所有数据流共用同一个连接，可以更有效地使用 TCP 连接。

HTTP3.0：也就是 QUIC (quick udp internet connection)协议，是由 google 提出的使用 udp 进行多路并发传输的协议。通过使用 UDP 协议，省去了 TCP 握手和慢启动的时间，拥有极低的建立连接延时。

### Q：请简述一下 HTTPS 协议？

HTTPS 在传输数据之前需要客户端与服务器之间进行一次握手，在握手过程中将确立双方加密传输数据的密码信息。TLS/SSL 协议不仅仅是一套加密传输的协议，TLS/SSL 中使用了非对称加密，对称加密以及 HASH 算法。

握手过程的简单描述如下：
1、客户端将自己支持的加密规则发送给服务器。

2、网站从中选出加密算法和 HASH 算法，将证书发回给浏览器。证书里面包含了网站地址，加密公钥，以及证书的颁发机构等信息。

3、获得证书之后客户端要做以下工作：
a) 验证证书（颁发证书的机构是否合法，证书中包含的网站地址是否与正在访问的地址一致等）。
b) 如果通过验证，浏览器会生成一串随机数的密码，并用证书中提供的公钥加密
c) 计算握手信息的 HASH，然后将握手信息也一并加密，最后将所有信息发送给网站。

4、网站接收浏览器发来的数据之后要做以下的操作：
a) 使用自己的私钥将信息解密取出密码，使用密码解密握手消息，判断 HASH 是否一致。
b) 计算握手的 HASH，并使用密码加密握手消息，发送给浏览器。

5、浏览器解密并计算握手消息的 HASH，如果与服务端发来的 HASH 一致，此时握手过程结束，之后所有的通信数据将由之前浏览器生成的随机密码进行加密。

### Q：请简述一下 HTTP 协议中的缓存策略？

HTTP 的缓存策略有两种：强缓存和协商缓存。

强缓存是利用 http 头中的 Expires 和 Cache-Control 两个字段来控制的，用来表示资源的缓存时间。强缓存中，普通刷新会忽略它，但不会清除它，需要强制刷新。

例如：
cache-control: max-age=691200 （HTTP 1.1）
expires: Fri, 14 Apr 2017 10:47:02 GMT （HTTP 1.0）

协商缓存主要涉及到两个 header 字段：E-Tag 和 Last-Modified。每次读取数据时客户单都会跟服务器通信，并且会增加缓存标识。在第一次请求服务器时，服务器会返回资源，并且返回一个资源的缓存标识，一起存到浏览器的缓存数据库。当第二次请求资源时，浏览器会首先将缓存标识发送给服务器，服务器拿到标识后判断标识是否匹配，如果不匹配，表示资源有更新，服务器会将新数据和新的缓存标识一起返回到浏览器；如果缓存标识匹配，表示资源没有更新，并且返回 304，浏览器就读取本地缓存服务器中的数据。

例如：
E-Tag: 123456abcd
Last-Modify: Thu,31 Dec 2037 23:59:59 GMT。

## 2、浏览器相关

### Q：请列举一下你知道的浏览器内核的种类？

Trident：IE6、IE7、IE8、IE9、IE10、360 浏览器和猎豹浏览器。
Gecko：firefox 浏览器。
Blink：opera 浏览器。
Webkit：sarfari 和 chrome 浏览器。

### Q：浏览器内核中的有哪些线程？

内核主要分成五部分：

![内核](http://www.shadowingszy.top/images/browser.png)

GUI 渲染线程：负责渲染浏览器界面，解析 HTML，CSS，构建渲染树，布局和绘制等。当界面需要重绘或回流时，该线程就会执行。注意，GUI 渲染线程与 JS 引擎线程是互斥的，

JS 引擎线程：解析和执行 javascript。

事件触发线程：归属于浏览器而不是 JS 引擎，用来控制事件循环。

定时器触发线程：setInterval 与 setTimeout 所在线程。浏览器定时计数器并不是由 JavaScript 引擎计数的，因此通过单独线程来计时并触发定时（计时完毕后，添加到事件队列中，等待 JS 引擎空闲后执行）。

异步 http 请求线程：在 XMLHttpRequest 在连接后是通过浏览器新开一个线程请求，将检测到状态变更时，如果设置有回调函数，异步线程就产生状态变更事件，将这个回调再放入事件队列中，再由 JavaScript 引擎执行。

### Q：请简述一下浏览器的渲染流程？

![渲染流程](http://www.shadowingszy.top/images/render.png)

接收到文档后，渲染引擎会对 HTML 文档进行解析生成 DOM 树、对 CSS 文件进行解析生成布局树；同时执行页面中的 JavaScript 代码；最终根据 DOM 树和布局树，计算样式生成渲染树，渲染树中，只会包含即将显示在页面中的元素及其样式信息（如 head 元素、display 为 hidden 的元素就不会包含在渲染树中）；根据渲染树需要进行布局来计算每个元素在页面上的位置；

接下来渲染引擎开始进行绘制（paint），这一步分为若干阶段：
1、根据渲染树绘制每层的各个元素。
2、栅格化绘制出的图像（将渲染树中的节点转换成屏幕上的实际像素）
3、显示在屏幕上。
每一层的绘制是由浏览器来完成的；最后的合成是由 GPU 来完成；而栅格化过程取决于浏览器的设置，chrome 默认开启 GPU 栅格化，否则由 CPU 进行。

### Q：浏览器从输入请求到呈现页面有哪几步？

1、URL 解析
2、DNS 查询
3、TCP 连接
4、处理请求
5、接受响应
6、渲染页面

### Q：localstorage、sessionstorage 的区别，以及使用场景是什么？

localStorage：生命周期是永久的，关闭页面或浏览器之后 localStorage 中的数据也不会消失。localStorage 除非主动删除数据，否则数据永远不会消失（只会存储 string）。

sessionStorage：生命周期是在仅在当前会话下有效。sessionStorage 引入了一个“浏览器窗口”的概念，sessionStorage 是在同源的窗口中始终存在的数据。只要这个浏览器窗口没有关闭，即使刷新页面或者进入同源另一个页面，数据依然存在。但是 sessionStorage 在关闭了浏览器窗口后就会被销毁。同时独立的打开同一个窗口同一个页面，sessionStorage 也是不一样的。

使用方法：

```javascript
window.localStorage
window.sessionStorage
```

API：

```javascript
setItem(key, value) // 保存数据，以键值对的方式储存信息。
getItem(key) // 获取数据，将键值传入，即可获取到对应的 value 值。
removeItem(key) // 删除单个数据，根据键值移除对应的信息。
clear() // 删除所有的数据
key(index) // 获取某个索引的 key
```
