拓展

(1). 说一下你对 HTTPS 的理解?

HTTPS 就是在 HTTP 和 TCP 协议中间加入了 SSL/TLS 安全套接层。

结合非对称加密和对称加密的各自优点,配合证书。既保证了安全性,也保证了传输效率。

目前应用最广泛的是 TLS1.2,实现原理如下:

  1. Client 发送 random1+对称加密套件列表+非对称加密套件列表
  2. Server 收到信息, 选择 对称加密套件+非对称加密套件 并和 random2+证书(公钥在证书中) 一起返回
  3. Client 验证证书有效性,并用 random1+random2 生成 pre-master 通过服务器公钥加密+浏览器确认 发送给 Server
  4. Server 收到 pre-master,根据约定的加密算法对 random1+random2+pre-master(解密)生成 master-secret,然后发送服务器确认
  5. Client 收到生成同样的 master-secert,对称加密秘钥传输完毕

TLS1.3 则简化了握手过程,完全握手只需要一个消息往返,提升了性能。不仅如此,还对部分不安全的加密算法进行了删减。

(2). 说一说你对 WebSocket 的理解?

WebSocket 是一种基于 TCP 的轻量级网络通信协议。和 HTTP/2 一样,都是为了解决 HTTP 某些方面的缺陷而诞生的。不过解决方式略有不同,HTTP/2 针对的是“队头阻塞 ”,WebSocket 针对的是“请求-应答”的通信模式。

我们知道“请求-应答”是半双工的通信模式,不具备服务器推送能力。这就限制了 HTTP 在实时通信领域的发展。虽然可以使用轮询来不停的向服务器发送 HTTP 请求,但是缺点也很大,反复的无效请求占用了大量的带宽和 CPU 资源。所以,WebSocket 应运而生。

WebSocket 是一个全双工通信协议,具备服务端主动推送的能力。本质上是对 TCP 做了一层包装,让它可以运行在浏览器环境里。

看过我这篇专栏「吐血整理」再来一打 Webpack 面试题 的同学们一定知道,Webpack 的热更新中就利用了这种协议。当然,在即时通讯、游戏以及可视化大屏展示等领域中也都有着 WebSocket 的身影。

(3). 说一说你对 DNS 的理解?

DNS (Domain Name System)是互联网中的重要基础设施,负责对域名的解析工作,为了保证高可用、高并发和分布式,它设计成了树状的层次结构。

由根 DNS 服务器、顶级域 DNS 服务器和权威 DNS 服务器组成。

解析顺序是首先从浏览器缓存、操作系统缓存以及本地 DNS 缓存 (/etc/hosts) 逐级查找,然后从本地 DNS 服务器、根 DNS、顶级 DNS 以及权威 DNS 层层递归查询。

还可以基于域名在内网、外网进行负载均衡。

不过传统的 DNS 有很多问题(解析慢、更新不及时),HTTPDNS 通过客户端 SDK 和服务端配合,直接通过 HTTP 调用解析 DNS 的方式,可以绕过传统 DNS 这些缺点,实现智能调度。

(4). 说一说你对 CDN 的理解?

CDN(Content Delivery Network)就是内容分发网络。

为了突破现实生活中的光速、传输距离等物理限制,CDN 投入了大量资金,在全球范围内各大枢纽城市建立机房,部署大量高存储高带宽的节点,构建跨运营商、跨地域的专用高速传输网络。

其中分为中心节点、区域节点、边缘节点等,在用户接入网络后,首先通过全局负载均衡 (Global Sever Load Balance),简称 GSLB 算法负责调度,找到离用户最合适的节点。然后通过 HTTP 缓存代理技术进行缓存,缓存命中就返回给用户,否则就回源站去取。CDN 擅长缓存静态资源(图片、音频等),当然也支持动态内容的缓存。

(5). 简单说一下 TCP 的三次握手和四次挥手

三次握手

1.客户端主动发起 SYN

2.服务端收到并返回 SYN 以及 ACK 客户端的 SYN

3.客户端收到服务端的 SYN 和 ACK 后,发送 ACK 的 ACK 给服务端,服务端收到后连接建立

Client -> SYN -> Server

Server -> SYN/ACK -> Client

Client -> ACK -> Server

四次挥手

1.客户端发送 FIN 给服务端

2.服务端收到后发送 ACK 给客户端

3.服务端发送 FIN 给客户端

4.客户端收到后,发送 ACK 的 ACK 给服务端,服务端关闭,客户端等待 2MSL 后关闭

Client -> FIN -> Server

Server -> ACK -> Client

Server -> FIN -> Client

Client -> ACK -> Server -> CLOSED

Client -> 2MSL 的时间 -> CLOSED

(6). HTTP 的缓存策略知道吗?

强缓存

服务器使用 Cache-Control 来设置缓存策略,常用 max-age 来表示资源的有效期。

(这里的 max-age 的时间计算起点是响应报文的创建时刻,而不是客户端收到报文的时刻。)

(浏览器也可以发送 Cache-Control 字段,使用 max-age=0 或 no-cache 来刷新数据)

如果想更精确的控制缓存策略,还可以使用 Cache-Control 的其他属性:

  • no-store:不允许缓存 (用于秒杀页面等变化频率非常高的场景)
  • no-cache:可以缓存,使用前必须要去服务端验证是否过期,是否是最新版本
  • must-revalidate:如果缓存不过期就可以继续使用,过期了就必须去服务端验证

协商缓存

验证资源是否失效就需要使用条件请求。常用的是 If-Modified-Since 和 If-None-Match,收到 304 状态码就可以复用缓存里的资源。

(If-None-Match 比 If-Modified-Since 优先级更高)

验证资源是否被修改的条件有两个 Last-modified 和 ETag (ETag 比 Last-modified 的精确度更高),需要预先在服务端的响应报文里设置,配合条件请求使用

(7). HTTP 如何进行内容协商?

内容协商就是每个 URI 指向的资源可以是任何事物,可以有很多不同的表述。对于文档来说,可以有不同的语言、不同的媒体格式,并针对不同的浏览器提供不同的压缩编码。

主动式内容协商

  • 客户端在请求头部中提出需要的表述形式,服务器根据其来进行特定表述

响应式内容协商

  • 服务端返回 300 或者 406,由客户端选择一种表述

协商要素

  • 质量因子 q:内容的质量、可接受类型的优先级
  • 媒体资源的 MIME 类型
  • 字符编码 (UTF-8)
  • 内容编码 (Accept-Encoding:gzip,deflate,br)
  • 表述语言 (Accept-Language:zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7)
  • 国际化与本地化 (i18n,l10n)

(8). 说一说 HTTP 的重定向

重定向是服务器发起的跳转,要求客户端使用新的 URI 重新发送请求。在响应头字段 Location 中指示了要跳转的 URI。使用 Refresh 字段,还可以实现延时重定向。

301 / 302 是常用的重定向状态码。分别代表永久性重定向和临时性重定向。

除此之外还有:

  • 303:类似于 302,重定向后的请求方法改为 GET 方法
  • 307:类似于 302,含义比 302 更明确,重定向后请求的方法和实体不允许变动
  • 308:类似于 301,代表永久重定向,重定向后请求的方法和实体不允许变动
  • 300:是一个特殊的重定向状态码,会返回一个有多个链接选项的页面,由用户自行选择
  • 304:是一个特殊的重定向状态码,服务端验证过期缓存有效后,要求客户端使用该缓存

参考文章:(1). https://zhuanlan.zhihu.com/p/57712655 (2). https://juejin.im/post/5e91d85ce51d4546c82d9d99#heading-32

(9). 你所谓的约定的加密算法应该是 ECDHE 椭圆算法吧?HTTP 传输消息都是明文的,黑客完全可以作为中间人劫持消息,再利用 ECDHE 算法,这样不就能破解密钥了吗?

ECDHE 算法利用了椭圆曲线和离散对数等思想,按照当下的计算机算力,很难在短时间进行破解。且每次握手时生成的都是一对临时的公钥和私钥,这样就保证每次的密钥对也不同。

即使大费力气破解了一次的密钥,之前的历史消息也不会受到影响,保证了前向安全。

当然,TLS 协议的安全性受限于当下最快的计算机运行速度,理论上绝对安全的是量子通讯传递密钥。

(10). TCP 和 UDP 区别?

TCP 和 UDP 都是传输层的协议,但二者有着截然不同的基因。

TCPUDP
面向连接无连接
面向字节流面向数据报
有状态无状态
保证可靠交付不保证可靠交付
具备拥塞控制不具备拥塞控制
点对点传播广播、多播
有序无序

(11). TCP/IP 网络分层模型是怎样分层的?

应用层、传输层、网际层、链接层

application layer、transport layer、internet layer、link layer

(12). TCP/IP 网络分层模型是怎样分层的?

那你说一下OSI 网络分层模型是怎样分层的? 应用层、表示层、会话层、传输层、网络层、数据链路层、物理层

application layer、presentation layer、session layer、transport layer、network layer、data link layer、physical layer

(13). HTTP 持久化连接

  Connection: keep-alive

以上就是 持久连接节省通信量 的字段。

HTTP 协议的初始版本中,每进行一次 HTTP 通信就要断开一次 TCP 连接。

以当年的通信情况来说,因为都是些容量很小的文本传输,所以即使 这样也没有多大问题。可随着 HTTP 的普及,文档中包含大量图片的 情况多了起来。 比如,使用浏览器浏览一个包含多张图片的 HTML页面时,在发送 请求访问 HTML页面资源的同时,也会请求该 HTML页面里包含的 其他资源。因此,每次的请求都会造成无谓的 TCP 连接建立和断 开,增加通信量的开销。

持久连接

为解决上述 TCP 连接的问题,HTTP/1.1 和一部分的 HTTP/1.0 想出了 持久连接(HTTP Persistent Connections,也称为 HTTP keep-alive 或 HTTP connection reuse)的方法。持久连接的特点是,只要任意一端 没有明确提出断开连接,则保持 TCP 连接状态。

持久连接的好处在于减少了 TCP 连接的重复建立和断开所造成的额 外开销,减轻了服务器端的负载。另外,减少开销的那部分时间,使 HTTP 请求和响应能够更早地结束,这样 Web 页面的显示速度也就相 应提高了。

在 HTTP/1.1 中,所有的连接默认都是持久连接,但在 HTTP/1.0 内并 未标准化。虽然有一部分服务器通过非标准的手段实现了持久连接, 但服务器端不一定能够支持持久连接。毫无疑问,除了服务器端,客 户端也需要支持持久连接。

管线化

持久连接使得多数请求以管线化(pipelining)方式发送成为可能。从前发送请求后需等待并收到响应,才能发送下一个请求。管线化技术出现后,不用等待响应亦可直接发送下一个请求。这样就能做到同时并行发送多个请求,而不需要一个接一个地等待响应了。

HTTP 是无状态协议,它不对之前发生过的请求和响应的状态进行管理。也就是说,无法根据之前的状态进行本次的请求处理。

不可否认,无状态协议当然也有它的优点。由于不必保存状态,自然 可减少服务器的 CPU 及内存资源的消耗。从另一侧面来说,也正是 因为 HTTP 协议本身是非常简单的,所以才会被应用在各种场景里。

保留无状态协议这个特征的同时又要解决类似的矛盾问题,于是引入 了 Cookie 技术。Cookie 技术通过在请求和响应报文中写入 Cookie 信 息来控制客户端的状态。

Cookie 会根据从服务器端发送的响应报文内的一个叫做 Set-Cookie 的 首部字段信息,通知客户端保存 Cookie。当下次客户端再往该服务器 发送请求时,客户端会自动在请求报文中加入 Cookie 值后发送出 去。

服务器端发现客户端发送过来的 Cookie 后,会去检查究竟是从哪一 个客户端发来的连接请求,然后对比服务器上的记录,最后得到之前 的状态信息。

(15). HTTP 缓存控制

浏览器在请求已经访问过的URL的时候,会判断是否使用缓存,。

判断是否使用缓存,主要通过判断缓存是否在有效期内, 通过两个字段来判断:

Expires,有效期,返回的是一个GMT时间,但是使用的是客户端时间,与服务器时间存在一定时间差。 Cache-Control => max-age,最大有效时间,单位是s,优先级比 expires 高,为了解决 expires 时间差的问题而出现的。 缓存过期后,浏览器不会直接去服务器上拿缓存,而是判断缓存是否有更新,能否继续使用,判断的方法有两种:

**Last-Modified / If-Modified-Since:**服务器会响应一个Last-Modified 字段,表示最近一次修改缓存的时间,当缓存过期后,浏览器就会把这个时间放在 If-Modified-Since 去请求服务器,判断缓存是否有更新。 **Etag / If-None-Match:**服务器会响应一个 Etag 字段,一个表示文件唯一的字符串, 一旦文件更新,Etag也会跟着更改;缓存过期后,浏览器会把这个字符串放在 If-None-Match 去请求服务器,判断是否有更新,Etag的优先级比Last-Modified 的更高, Etag 的出现, 是为了解决一个缓存文件在短时间内被多次修改的问题, 因为 Last-Modified 只能精确到秒。

(16). HTTP 请求/响应的步骤

  1. 客户端连接到Web服务器 一个 HTTP 客户端(通常是浏览器)与 Web 服务器的HTTP端口(默认 80)建立一个TCP套接字连接。

  2. 发送HTTP请求 通过 TCP 套接字,客户端向 Web 服务器发送一个文本的请求报文。

  3. 服务器接受请求并返回 HTTP 响应 Web 服务器解析请求,定位请求资源。服务器将资源复本写到 TCP 套接字,由客户端读取。

  4. 释放连接 TCP 连接 若 connection 模式为 close,则服务器主动关闭 TCP 连接,客户端被动关闭连接,释放 TCP 连接;若 connection 模式为 keepalive,则该连接会保持一段时间,在该时间内可以继续接收请求;

  5. 客户端浏览器解析HTML内容 客户端浏览器首先解析状态行,查看表明请求是否成功的状态代码。然后解析每一个响应头,响应头告知以下为若干字节的 HTML 文档和文档的字符集。客户端浏览器读取响应数据 HTML,根据 HTML 的语法对其进行格式化,并在浏览器窗口中显示。

生活中常见例子

在浏览器中输入 URL 地址,回车后:

  1. 浏览器向 DNS 服务器请求解析该 URL 中的域名所对应的 IP 地址

  2. 解析出 IP 地址后,根据该 IP 地址和默认端口 80,和服务器建立 TCP 连接

  3. 浏览器发出读取文件(URL 中域名后面部分对应的文件)的HTTP 请求,该请求报文作为 TCP 三次握手的第三个报文数据发送给服务器;

  4. 服务器对浏览器请求作出响应,并把对应的 html 文本发送给浏览器;

  5. 释放 TCP 连接

  6. 浏览器将该 html 文本并显示内容;

文章来源: https://juejin.im/post/6844904121510854664#heading-32

Last Updated:
Contributors: zerojs