【计算机网络面试篇】HTTP

目录

1. HTTP 是什么?

2. HTTP 常见的状态码有哪些?

3. HTTP 常见字段有哪些?

4. GET 和 POST 有什么区别?

5. GET 和 POST 方法都是安全和幂等的吗?

6. HTTP 缓存有哪些实现方式?什么是强制缓存?什么是协商缓存?

7. HTTP/1.1 的优缺点有哪些?HTTP/1.1 的性能如何?

8. HTTP 与 HTTPS 有哪些区别?

9. HTTPS 解决了 HTTP 的哪些问题?

10. HTTPS 是如何解决上面的三个风险的?

11. HTTPS 是如何建立连接的?其间交互了什么?

12. 客户端校验数字证书的流程是怎样的?

13. HTTPS 一定安全可靠吗?

14. HTTP/1.1 相比 HTTP/1.0 提高了什么性能?

15. 说下 HTTP1.0,1.1,2.0 的区别?

16. HTTP/2 有什么缺陷?

17. HTTP/3 了解吗?

18. HTTPS RSA 握手的缺陷?

19. HTTPS ECDHE 握手过程?

20. URI 和 URL 有什么区别?

21. 如何理解 HTTP 协议是无状态的?

22. 说说 Cookie 和 Session 有什么联系和区别?

23. 既然有 HTTP 协议,为什么还要有 RPC?

24. 什么是WebSocket和Socket?有什么区别?


1. HTTP 是什么?

HTTP 是超文本传输协议,也就是HyperText Transfer Protocol。

HTTP 是一个在计算机世界里专门在「两点」之间「传输」文字、图片、音频、视频等「超文本」数据的「约定和规范」

2. HTTP 常见的状态码有哪些?

3. HTTP 常见字段有哪些?

Host 字段

作用:客户端发送请求时,用来指定服务器的域名。

有了 Host 字段,就可以将请求发往「同一台」服务器上的不同网站。

Connection

  • 作用:管理 TCP 连接的持久性。

  • 常见值

    • keep-alive:长连接。告诉服务器处理完这个请求后不要关闭 TCP 连接,后续请求可以复用(HTTP/1.1 默认开启)。

    • close:短连接。请求结束即断开 TCP。

HTTP 长连接的特点是,只要任意一端没有明确提出断开连接,则保持 TCP 连接状态。

Content-Length

  • 作用:告诉对端本次传输的数据(Body)有多大(字节数)。

  • 重点

    • TCP 粘包/拆包:HTTP 基于 TCP,接收端需要知道从哪里切分数据,Content-Length 就是边界标识。

Content-Type

  • 作用:告诉对端数据的格式,以便正确解析。

  • 常见值

    • application/json:现在最常用的前后端交互格式。

    • application/x-www-form-urlencoded:传统的表单提交格式(key=value&key2=value2)。

    • multipart/form-data:文件上传必须用这个(因为它定义了 boundary 分隔符)。

    • text/html:网页。

4. GET 和 POST 有什么区别?

从 HTTP 规范来看,GET 用于获取资源,是安全且幂等的POST 用于处理资源(修改或提交数据),是不安全且非幂等的。

比较维度GETPOST深度解释 
数据位置写在URL 中HTTP 报文(Body)中GET 的 URL 有长度限制(见下文);POST Body 理论无限制。
参数可见性参数直接暴露在地址栏参数在报文内部,地址栏不可见注意:仅仅是“不可见”,不代表“安全”。HTTPS 才能真正保护数据不被窃听。
缓存机制主动缓存默认不缓存GET 请求会被浏览器主动缓存,这也是为什么静态资源(CSS/JS)通常用 GET。POST 除非手动设置 Cache-Control,否则不会缓存。
历史记录参数保留在浏览器历史/书签中参数不保留如果发送密码,用 GET 会导致密码留在浏览记录里,极不安全。
数据编码只支持 ASCII 字符支持多种编码 (二进制/Multipart)POST 可以上传文件(multipart/form-data),GET 不行。
长度限制有限制 无限制重点坑:HTTP 协议本身没有限制 URL 长度,是浏览器和服务器(如 Nginx)为了性能和安全自己做了限制。

5. GET 和 POST 方法都是安全和幂等的吗?

安全和幂等的概念

  • 在 HTTP 协议里,所谓的「安全」是指请求方法不会「破坏」服务器上的资源
  • 所谓的「幂等」,意思是多次执行相同的操作,结果都是「相同」的。

如果从 RFC 规定定义的语义来看:

  • GET 方法就是安全且幂等的,因为它是「只读」操作,无论操作多少次,服务器上的数据都是安全的,且每次的结果都是相同的。所以,可以对 GET 请求的数据做缓存,这个缓存可以做到浏览器本身(彻底避免浏览器发请求),也可以做到代理上(如 nginx),而且在浏览器中 GET 请求可以保存为书签。

  • POST 因为是「新增或提交数据」的操作,会修改服务器上的资源,所以是不安全的,且多次提交数据就会创建多个资源,所以不是幂等的。
    所以,浏览器一般不会缓存 POST 请求,也不能把 POST 请求保存为书签。

注意, 上面是从 RFC 规范定义的语义来分析的。

但是实际过程中,开发者不一定会按照 RFC 规范定义的语义来实现 GET 和 POST 方法。

Q1: DELETE 方法是幂等的吗?

  • Answer是幂等的

  • 解释

    • DELETE /user/123。

    • 第 1 次执行:删除了 ID 123。服务器上没有 123 了。

    • 第 2 次执行:服务器上还是没有 123(虽然可能返回 404 Not Found,但服务器状态依然是“没有 123”)。

    • 既然 N 次执行后,服务器的状态都是“没有 123”,所以它是幂等的。

Q2: PUT 和 POST 都是修改数据,区别在哪?

  • Answer核心区别在于幂等性

  • PUT (幂等):通常用于全量替换指定 ID 创建

    • PUT /article/1 (把 ID 为 1 的文章内容改为 "Hello")。

    • 无论你发多少次,ID 为 1 的文章内容永远是 "Hello",不会多出新文章。

  • POST (非幂等):通常用于新增(由服务器决定 ID)。

    • POST /article (发布一篇新文章)。

    • 发 10 次,就会生成 10 篇不同的文章。

6. HTTP 缓存有哪些实现方式?什么是强制缓存?什么是协商缓存?

HTTP 缓存有两种实现方式,分别是强制缓存和协商缓存

什么是强制缓存?

强制缓存指的是只要浏览器判断缓存没有过期,则直接使用浏览器的本地缓存,决定是否使用缓存的主动性在于浏览器这边。


如下图中,返回的是 200 状态码,但在 size 项中标识的是 from disk cache,就是使用了强制缓存

强缓存是利用下面这两个 HTTP 响应头部(Response Header)字段实现的,它们用来表示资源在客户端缓存的有效期:

  • Cache-Control,是一个相对时间;

  • Expires,是一个绝对时间;

如果 HTTP 响应头部同时有 Cache-Control 和 Expires 字段的话,Cache-Control 的优先级高于 Expires

Cache-Control 选项更多一些,设置更加精细,所以建议使用 Cache-Control 来实现强缓存。具体的实现流程如下:

  • 当浏览器第一次请求访问服务器资源时,服务器会在返回这个资源的同时,在 Response 头部加上 Cache-Control、Cache-Control 中设置过期时间大小;

  • 浏览器再次请求访问服务器中的该资源时,会先通过请求资源的时间与 Cache-Control 中设置的过期时间大小,来计算出该资源是否过期,如果没有,则使用该缓存,否则重新请求服务器;

  • 服务器再次收到请求后,会再次更新 Response 头部的 Cache-Control。

什么是协商缓存?

当我们在浏览器使用开发者工具的时候,你可能会看到过某些请求的响应码是 304 ,这个是告诉浏览器可以使用本地缓存的资源,通常这种通过服务端告知客户端是否可以使用缓存的方式被称为协商缓存。

上图就是一个协商缓存的过程,所以协商缓存就是与服务端协商之后,通过协商结果来判断是否使用本地缓存。

7. HTTP/1.1 的优缺点有哪些?HTTP/1.1 的性能如何?

HTTP/1.1优点

HTTP 最突出的问题是「简单、灵活和易于扩展、应用广泛和跨平台」。

1. 简单

HTTP 基本的报文格式就是 header + body,头部信息也是 key–value 简单文本的形式,易于理解,降低了学习和使用的门槛。

2. 灵活和易于扩展

HTTP 协议里的各类请求方法、URI/URL、状态码、头字段等每个组成要求都没有被固定死,都允许开发人员自定义和扩充

同时 HTTP 由于是工作在应用层(OSI 第七层),则它下层可以随意变化,比如:

  • HTTPS 就是在 HTTP 与 TCP 层之间增加了 SSL/TLS 安全传输层;

  • HTTP/1.1 和 HTTP/2.0 传输协议使用的是 TCP 协议,而到了 HTTP/3.0 传输协议改用了 UDP 协议。

3. 应用广泛和跨平台

互联网发展至今,HTTP 的应用范围非常广泛,从台式机的浏览器到手机上的各种 APP,从看新闻、贴吧到购物、理财、吃鸡,HTTP 的应用遍地开花,同时天然具有跨平台的优越性。

HTTP/1.1缺点

HTTP 协议里有优缺点一体的双刃剑,分别是「无状态、明文传输」,同时还有一大缺点「不安全」。

1. 无状态双刃剑

  • 无状态的好处:因为服务器不会去记忆 HTTP 的状态,所以不需要额外的资源来记录状态信息,这能减轻服务器的负担,能够把更多的 CPU 和内存用来对外提供服务。
  • 无状态的坏处:既然服务器没有记忆能力,它在完成有关联性的操作时会非常麻烦。例如登录 -> 添加购物车 -> 下单 -> 结算 -> 支付,这系列操作都要知道用户的身份才行。但服务器不知道这些请求是有关联的,每次都要问一遍身份信息。

2. 明文传输双刃剑

明文意味着在传输过程中的信息,是可方便阅读的,比如 Wireshark 抓包都可以直接肉眼查看,为我们调试工作带了极大的便利性。但是这正是这样,HTTP 的所有信息都暴露在了光天化日下,相当于信息裸奔。在传输的漫长的过程中,信息的内容都毫无隐私可言,很容易就能被窃取

3. 不安全

HTTP 比较严重的缺点就是不安全:

  • 通信使用明文(不加密),内容可能会被窃听。
  • 不验证通信方的身份,因此有可能遭遇伪装。
  • 无法证明报文的完整性,所以有可能已遭篡改。

HTTP 的安全问题,可以用 HTTPS 的方式解决,也就是通过引入 SSL/TLS 层,使得在安全上达到了极致。

HTTP/1.1 的性能如何?

HTTP 协议是基于 TCP/IP,并且使用了「请求 - 应答」的通信模式,所以性能的关键就在这两点里。

1. 长连接

早期 HTTP/1.0 性能上的一个很大的问题,那就是每发起一个请求,都要新建一次 TCP 连接(三次握手),而且是串行请求,做了无谓的 TCP 连接建立和断开,增加了通信开销。为了解决上述 TCP 连接问题,HTTP/1.1 提出了长连接的通信方式,也叫持久连接。这种方式的好处在于减少了 TCP 连接的重复建立和断开所造成的额外开销,减轻了服务器端的负载。持久连接的特点是,只要任意一端没有明确提出断开连接,则保持 TCP 连接状态。

2. 管道网络传输

HTTP/1.1 采用了长连接的方式,这使得管道(pipeline)网络传输成为了可能。即可在同一个 TCP 连接里面,客户端可以发起多个请求,只要第一个请求发出去了,不必等其回来,就可以发第二个请求出去,可以减少整体的响应时间。举例来说,客户端需要请求两个资源。以前的做法是,在同一个 TCP 连接里面,先发送 A 请求,然后等待服务器做出回应,收到后再发出 B 请求。那么,管道机制则是允许浏览器同时发出 A 请求和 B 请求,如下图:

但是服务器必须按照接收请求的顺序发送对这些管道化请求的响应。如果服务端在处理 A 请求时耗时比较长,那么后续的请求的处理都会被阻塞住,这称为「队头堵塞」。所以,HTTP/1.1 管道解决了请求的队头阻塞,但是没有解决响应的队头阻塞

实际上 HTTP/1.1 管道化技术不是默认开启,而且浏览器基本都没有支持,所以后面所有文章讨论 HTTP/1.1 都是建立在没有使用管道化的前提

3. 队头阻塞

「请求 - 应答」的模式会造成 HTTP 的性能问题。为什么呢?因为当顺序发送的请求序列中的一个请求因为某种原因被阻塞时,在后面排队的所有请求也一同被阻塞了,会招致客户端一直请求不到数据,这也就是「队头阻塞」,好比上班的路上塞车。

8. HTTP 与 HTTPS 有哪些区别?

  • HTTP 是超文本传输协议,信息是明文传输,存在安全风险的问题。HTTPS 则解决 HTTP 不安全的缺陷,在 TCP 和 HTTP 网络层之间加入了 SSL/TLS 安全协议,使得报文能够加密传输。
  • HTTP 连接建立相对简单, TCP 三次握手之后便可进行 HTTP 的报文传输。而 HTTPS 在 TCP 三次握手之后,还需进行 SSL/TLS 的握手过程,才可进入加密报文传输。
  • 两者的默认端口不一样,HTTP 默认端口号是 80,HTTPS 默认端口号是 443。
  • HTTPS 协议需要向 CA(证书权威机构)申请数字证书,来保证服务器的身份是可信的。

9. HTTPS 解决了 HTTP 的哪些问题?

HTTP 由于是明文传输,所以安全上存在以下三个风险:

  • 窃听风险,比如通信链路上可以获取通信内容。
  • 篡改风险,比如强制植入垃圾广告,视觉污染。
  • 冒充风险,比如冒充淘宝网站。

HTTPS 在 HTTP 与 TCP 层之间加入了 SSL/TLS 协议,可以很好的解决了上述的风险:

  • 信息加密:交互信息无法被窃取。
  • 校验机制:无法篡改通信内容,篡改了就不能正常显示。
  • 身份证书:证明淘宝是真的淘宝网。

10. HTTPS 是如何解决上面的三个风险的?

  • 混合加密的方式实现信息的机密性,解决了窃听的风险。
  • 摘要算法的方式来实现完整性,它能够为数据生成独一无二的「指纹」,指纹用于校验数据的完整性,解决了篡改的风险。
  • 将服务器公钥放入到数字证书中,解决了冒充的风险。

1. 混合加密

通过混合加密的方式可以保证信息的机密性,解决了窃听的风险。

HTTPS 采用的是对称加密非对称加密结合的「混合加密」方式:

  • 在通信建立前采用非对称加密的方式交换「会话秘钥」,后续就不再使用非对称加密。
  • 在通信过程中全部使用对称加密的「会话秘钥」的方式加密明文数据。

采用「混合加密」的方式的原因:

  • 对称加密只使用一个密钥,运算速度快,密钥必须保密,无法做到安全的密钥交换。
  • 非对称加密使用两个密钥:公钥和私钥,公钥可以任意分发而私钥保密,解决了密钥交换问题但速度慢。

2. 摘要算法 + 数字签名

为了保证传输的内容不被篡改,我们需要对内容计算出一个「指纹」,然后同内容一起传输给对方。对方收到后,先是对内容也计算出一个「指纹」,然后跟发送方发送的「指纹」做一个比较,如果「指纹」相同,说明内容没有被篡改,否则就可以判断出内容被篡改了。那么,在计算机里会用摘要算法(哈希函数)来计算出内容的哈希值,也就是内容的「指纹」,这个哈希值是唯一的,且无法通过哈希值推导出内容

通过哈希算法可以确保内容不会被篡改,但是并不能保证「内容+哈希值」不会被中间人替换,因为这里缺少对客户端收到的消息是否来源于服务端的证明。

那为了避免这种情况,计算机里会用非对称加密算法来解决,共有两个密钥:

  • 一个是公钥,这个是可以公开给所有人的;
  • 一个是私钥,这个必须由本人管理,不可泄露。

这两个密钥可以双向加解密的,比如可以用公钥加密内容,然后用私钥解密,也可以用私钥加密内容,公钥解密内容。

流程的不同,意味着目的也不相同:

  • 公钥加密,私钥解密。这个目的是为了保证内容传输的安全,因为被公钥加密的内容,其他人是无法解密的,只有持有私钥的人,才能解密出实际的内容;
  • 私钥加密,公钥解密。这个目的是为了保证消息不会被冒充,因为私钥是不可泄露的,如果公钥能正常解密出私钥加密的内容,就能证明这个消息是来源于持有私钥身份的人发送的。

一般我们不会用非对称加密来加密实际的传输内容,因为非对称加密的计算比较耗费性能的。

所以非对称加密的用途主要在于通过「私钥加密,公钥解密」的方式,来确认消息的身份,我们常说的数字签名算法,就是用的是这种方式,不过私钥加密内容不是内容本身,而是对内容的哈希值加密

私钥是由服务端保管,然后服务端会向客户端颁发对应的公钥。如果客户端收到的信息,能被公钥解密就说明该消息是由服务器发送的。

3. 数字证书

前面我们知道:

  • 可以通过哈希算法来保证消息的完整性;
  • 可以通过数字签名来保证消息的来源可靠性(能确认消息是由持有私钥的一方发送的);

但是这还远远不够,还缺少身份验证的环节,万一公钥是被伪造的呢?

11. HTTPS 是如何建立连接的?其间交互了什么?

建立一个 HTTPS 连接,实际上是分两步走的:

  1. TCP 三次握手:先建立可靠的 TCP 连接。(消耗 1.5 RTT)

  2. TLS 四次握手:在 TCP 之上,进行加密参数的协商和密钥交换。(消耗 2 RTT)

重点:也就是说,HTTPS 比 HTTP 建立连接要,因为多出了 TLS 握手的过程。

TLS 握手详细流程

为了方便记忆,我们可以把它看作是4 次交互(类似于 TCP 的三次握手,这里通常是 4 个包,或者合并成 3 个包)。

第 1 次交互:Client Hello(客户端打招呼)

  • 发送方:客户端(浏览器)

  • 内容

    1. TLS 版本号:例如 TLS 1.2。

    2. 随机数 (Random_C):客户端生成的第一个随机数,用于后续生成会话密钥

    3. 支持的密码套件列表 (Cipher Suites):告诉服务器“我会 RSA、ECDHE、AES-GCM... 你挑一个”。

第 2 次交互:Server Hello + Certificate(服务器回应)

  • 发送方:服务器

  • 内容

    1. 确认 TLS 版本

    2. 随机数 (Random_S):服务器生成的第二个随机数,也用于后续生成会话密钥

    3. 确认密码套件:服务器从客户端给的列表里选一个(比如 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256)。

    4. 服务器的数字证书 :把身份证(包含公钥)发给客户端。

    5. (可选) Server Key Exchange:如果是 ECDHE 算法,服务器会在这里发送密钥交换需要的参数。

第 3 次交互:Client Key Exchange(客户端交换密钥)

  • 动作 1:验证证书。验证通过后,取出公钥

  • 动作 2:生成第 3 个随机数。这个随机数叫 Pre-master Secret(预主密钥)

  • 发送内容

    1. Client Key Exchange

      • 如果是 RSA:用服务器的公钥加密这个 Pre-master Secret 发给服务器。

      • 如果是 ECDHE:发送客户端的椭圆曲线参数。

    2. Change Cipher Spec:告诉服务器“接下来的消息我要开始加密了”。

    3. Finished:把之前握手过程中所有的消息做一个摘要(Hash),再加密发给服务器。这是第一条加密消息,用来验证握手没被篡改。

第 4 次交互:Server Finish(握手结束)

  • 服务器处理

    • 收到 Pre-master Secret(用私钥解密 RSA,或者通过 ECDHE 计算得出)。

    • 关键步骤:此时,客户端和服务器都集齐了三个要素:Random_C + Random_S + Pre-master Secret。双方使用同样的算法,计算出最终的 会话密钥 (Session Key)

  • 发送内容

    1. Change Cipher Spec:告诉客户端“我也要开始加密了”。

    2. Finished:把之前的握手消息做个摘要并加密,发给客户端验证。

握手完成! 此后双方使用 Session Key 进行对称加密传输 HTTP 数据。

12. 客户端校验数字证书的流程是怎样的?

如下图图所示,为数字证书签发和验证流程

CA 签发证书的过程,如上图左边部分:

  • 首先 CA 会把持有者的公钥、用途、颁发者、有效时间等信息打成一个包,然后对这些信息进行 Hash 计算,得到一个 Hash 值;
  • 然后 CA 会使用自己的私钥将该 Hash 值加密,生成 Certificate Signature,也就是 CA 对证书做了签名;
  • 最后将 Certificate Signature 添加在文件证书上,形成数字证书;

客户端校验服务端的数字证书的过程,如上图右边部分:

  • 首先客户端会使用同样的 Hash 算法获取该证书的 Hash 值 H1;
  • 通常浏览器和操作系统中集成了 CA 的公钥信息,浏览器收到证书后可以使用 CA 的公钥解密 Certificate Signature 内容,得到一个 Hash 值 H2;
  • 最后比较 H1 和 H2,如果值相同,则为可信赖的证书,否则则认为证书不可信。

13. HTTPS 一定安全可靠吗?

直接给结论:在标准且正确的 HTTPS 通信下,即使有假基站转发了全部信息,假基站也无法获取解密后的信息,不会造成信息泄露。

只有一种情况会泄露,那就是客户端(用户)主动忽略了安全警告,或者客户端被植入了恶意根证书

为什么假基站无法窃取 HTTPS 信息?

假基站充当的是网络传输层面的“路由器”或“网关”角色,它可以截获所有数据包,但无法破解。

假基站虽然截获了所有 0 和 1 的比特流,但它没有协商好的会话密钥。所以,看到的是一堆乱码,无法还原成原本的 HTTP 请求。

如果假基站想看懂数据,它必须参与 TLS 握手,假装自己是“服务器”,要么只能发一个假证书给客户端,客户端会直接报错,要么就算能发一个真证书给客户端,后续也无法解密客户端发来的 Pre-master Secret。

什么情况下会导致泄露?

  • 用户主动忽略警告
  • 被安装了恶意根证书

14. HTTP/1.1 相比 HTTP/1.0 提高了什么性能?

HTTP/1.1 相比 HTTP/1.0 性能上的改进:

  • 使用长连接的方式改善了 HTTP/1.0 短连接造成的性能开销。
  • 支持管道(pipeline)网络传输,只要第一个请求发出去了,不必等其回来,就可以发第二个请求出去,可以减少整体的响应时间。

但 HTTP/1.1 还是有性能瓶颈:

  • 请求 / 响应头部(Header)未经压缩就发送,首部信息越多延迟越大。只能压缩 Body 的部分;
  • 发送冗长的首部。每次互相发送相同的首部造成的浪费较多;
  • 服务器是按请求的顺序响应的,如果服务器响应慢,会招致客户端一直请求不到数据,也就是队头阻塞
  • 没有请求优先级控制;
  • 请求只能从客户端开始,服务器只能被动响应。

15. 说下 HTTP1.0,1.1,2.0 的区别?

说下 HTTP1.0

  • 短连接:默认情况下,每个 HTTP 请求 / 响应对之后,连接会被关闭,属于短连接。这意味着对于同一个网站的每个资源请求,如 HTML 页面上的图片和脚本,都需要建立一个新的 TCP 连接。可以设置 Connection: keep-alive 强制开启长连接。

说下 HTTP1.1

  • 长连接:HTTP 1.1 引入了持久连接(也称为 HTTP keep-alive),默认情况下不会立即关闭连接,可以在一个连接上发送多个请求和响应。极大减轻了 TCP 连接的开销。
  • 管道通信:HTTP 1.1 支持客户端在前一个请求的响应到达之前发送下一个请求,以提高传输效率。

说下 HTTP2.0

  • 二进制协议:HTTP 2.0 使用二进制而不是文本格式来传输数据,解析更加高效。
  • 多路复用:一个 TCP 连接上可以同时进行多个 HTTP 请求 / 响应,不同的请求被切分成一个个小的二进制“帧”,乱序发送,然后在接收端根据帧里的“流 ID”重新组装。解决了 HTTP 1.x 的队头阻塞问题。

  • 头部压缩:HTTP/2 会压缩头(Header)如果你同时发出多个请求,他们的头是一样的或是相似的,那么,协议会帮你消除重复的部分
  • 服务端推送:服务器可以主动向客户端推送资源,而不需要客户端明确请求。

16. HTTP/2 有什么缺陷?

HTTP/2 虽然解决了应用层的队头阻塞,但它底层依然是 TCP

  • TCP 队头阻塞:TCP 是可靠传输,如果丢了一个包,TCP 为了保证数据顺序,会把后续所有的包都拦住,等待那个丢的包重传。

这就是 HTTP/2 队头阻塞问题。

17. HTTP/3 了解吗?

为了解决 TCP 队头阻塞的问题,HTTP/3 使用了基于UDP的 QUIC 协议

UDP 发送是不管顺序,也不管丢包的,所以不会出现像 HTTP/2 队头阻塞的问题。大家都知道 UDP 是不可靠传输的,但基于 UDP 的 QUIC 协议 可以实现类似 TCP 的可靠性传输

 QUIC 的关键特性 

1. 无队头阻塞

QUIC 有自己的一套机制可以保证传输的可靠性的。当某个流发生丢包时,只会阻塞这个流,其他流不会受到影响,因此不存在队头阻塞问题。这与 HTTP/2 不同,HTTP/2 只要某个流中的数据包丢失了,其他流也会因此受影响。

所以,QUIC 连接上的多个 Stream 之间并没有依赖,都是独立的,某个流发生丢包了,只会影响该流,其他流不受影响。

2. 更快的连接建立

  • 对比

    • HTTPS (TCP+TLS):先 TCP 握手 (1 RTT) + TLS 握手 (1-2 RTT) = 3 RTT。

    • HTTP/3 (QUIC):QUIC 内部包含了 TLS 1.3。它把传输层握手和加密层握手合并了。

  • 性能

    • 首次连接:只需要 1 RTT(握手+密钥交换同时进行)。

    • 再次连接 (0-RTT):客户端缓存了上次的密钥和参数,直接发加密数据,无需握手

3. 连接迁移

TCP 连接由 四元组(源IP、源端口、目的IP、目的端口)唯一标识。当你拿着手机从 Wi-Fi 切到 4G,你的 IP 变了,四元组变了,TCP 连接就断了,必须重新握手(看视频会卡顿一下)。

QUIC 使用一个 64位的 Connection ID (CID) 来标识连接,而不是 IP。

当你的网络切换(IP 变了),只要 CID 没变,服务器就知道还是你。连接不用断,数据接着传,用户实现无感切换。

18. HTTPS RSA 握手的缺陷?

RSA 不具备“前向安全性”

因为客户端传递随机数(用于生成对称加密密钥的条件之一)给服务端时使用的是公钥加密的,服务端收到后,会用私钥解密得到随机数。所以一旦服务端的私钥泄漏了,过去被第三方截获的所有 TLS 通讯密文都会被破解。

19. HTTPS ECDHE 握手过程?

“RSA 是通过公钥加密传输密钥,而 ECDHE 是通过算法协商出密钥,密钥本身不在网络传输。”

第 1 步:Client Hello (客户端打招呼)

  • 内容:和 RSA 握手一样。

    1. TLS 版本

    2. 随机数 1 (Random_C)

    3. 加密套件

第 2 步:Server Hello + Server Key Exchange (服务器发参) —— 关键区别

这里比 RSA 握手多了一个关键步骤:Server Key Exchange

  1. Server Hello

    • 确认加密套件,生成 随机数 2 (Random_S)

  2. Server Key Exchange (核心)

    • 服务器生成一对临时的椭圆曲线公私钥

    • 发送

      1. 曲线参数(告诉客户端用什么曲线)。

      2. 服务器的临时公钥。

      3. 签名重点! 服务器为了证明这个临时公钥是它生成的,会用手里长期持有的 RSA 私钥 对这堆数据进行数字签名

  3. Server Hello Done

第 3 步:Client Key Exchange (客户端算参)

客户端收到消息后:

  1. 验签:利用证书里的 RSA 公钥 验证服务器发来的签名。如果通过,说明那个“临时公钥”确实是服务器发的,不是黑客伪造的。

  2. 生成参数:客户端也生成一对临时的椭圆曲线公私钥

  3. 计算 Pre-master Secret

    • 客户端使用自己生成的 临时私钥 + 服务器发来的 临时公钥,利用 ECDH 算法算出 Pre-master Secret

  4. 发送消息

    • Client Key Exchange:把客户端的 临时公钥发给服务器。(注意:这里不需要加密,明文发就行,因为黑客截获了也没用)。

  5. Change Cipher Spec + Finished:同 RSA。

第 4 步:Server Finish (握手结束)

  1. 计算 Pre-master Secret

    • 服务器收到客户端的临时公钥后,结合自己的 临时私钥,利用 ECDH 算法算出 同一个 Pre-master Secret

    • 此时,双方都算出了 Pre-master,且这个秘密从未在网络上传输过!

  2. 生成会话密钥:双方利用 Random_C + Random_S + Pre-master 算出 Session Key

  3. Change Cipher Spec + Finished:同 RSA。

20. URI 和 URL 有什么区别?

URI 是统一资源标识符,URL 是统一资源定位符。URL 是 URI 的一个子集

URI 的作用是唯一标识一个资源,如 HTML 文档、图像、视频片段、程序等

URL 是通过提供资源的路径访问方法来找到这个资源。

21. 如何理解 HTTP 协议是无状态的?

HTTP 协议是无状态的,这意味着每个 HTTP 请求都是独立的,服务器不会保留任何关于客户端请求的历史信息。

  • 每个 HTTP 请求都包含了所必须的信息,服务器在处理当前请求时,不依赖于之前的任何请求信息。
  • 服务器不会记录任何客户端请求的状态,每次请求都像是第一次与服务器通信。

由于 HTTP 是无状态的,像用户的购物车状态就必须通过其他方式来保持,如在每次请求中传递用户的 ID,或者使用 Cookie 在客户端保存购物车状态。

22. 说说 Cookie 和 Session 有什么联系和区别?

先来看看什么是 Session 和 Cookie :

  • Cookie 是保存在客户端的一小块文本串的数据。客户端向服务器发起请求时,服务端会向客户端发送一个 Cookie,客户端就把 Cookie 保存起来。在客户端下次向同一服务器再发起请求时,Cookie 被携带发送到服务器。服务端可以根据这个 Cookie 判断用户的身份和状态。
  • Session 指的就是服务器和客户端一次会话的过程。它是另一种记录客户状态的机制。不同的是 cookie 保存在客户端浏览器中,而 session 保存在服务器上。客户端浏览器访问服务器的时候,服务器把客户端信息以某种形式记录在服务器上,这就是 session。客户端浏览器再次访问时只需要从该 session 中查找用户的状态。

Session 和 Cookie 的区别?

维度CookieSession面试深度解析
存储位置客户端 (浏览器)服务端 (内存/数据库/Redis)Cookie 数据保存在用户电脑上;Session 数据保存在服务器上。
安全性较高Cookie 容易被篡改、伪造或截获(可以看到明文)。Session 数据在服务器,客户端只拿一个 ID,相对安全。
数据类型仅支持 字符串 (String)支持 任意对象 (Object)Cookie 只能存 ASCII 字符串;Session 可以存 User 对象、List 等复杂结构。
大小限制 (单个约 4KB)无限制 (受限于服务器内存)浏览器对 Cookie 数量和大小有限制;Session 取决于服务器资源。

Session 和 Cookie 有什么关联呢?

可以使用 Cookie 记录 Session 的标识。

  1. 创建 Session:用户第一次访问服务器(比如登录),服务器在内存中创建一个 Session 对象,并生成一个唯一的 ID,叫 Session ID

  2. 下发 ID:服务器通过 HTTP 响应头 Set-Cookie: JSESSIONID=xxxxxx,把这个 ID 种到客户端的 Cookie 里。

  3. 携带 ID:用户后续发起请求时,浏览器自动在请求头 Cookie: JSESSIONID=xxxxxx 中带上这个 ID。

  4. 找回 Session:服务器收到请求,解析 Cookie 中的 Session ID,去内存里查找对应的 Session 对象,从而识别用户身份。

如果浏览器禁用了 Cookie,Session 还能用吗?

首先是 SessionID 的存储,可以使用客户端的本地存储,比如浏览器的 sessionStorage。

接下来怎么传呢?

  • 拼接到 URL 里:直接把 SessionID 作为 URL 的请求参数
  • 放到请求头里:把 SessionID 放到请求的 Header 里,比较常用。

分布式环境下 Session 怎么管理?

分布式环境下,客户端请求经过负载均衡,可能会分配到不同的服务器上,假如一个用户的请求两次没有落到同一台服务器上,那么在新的服务器上就没有记录用户状态的 Session。

可以使用 Redis 等分布式缓存来存储 Session,在多台服务器之间共享。

服务器不再把 Session 存在自己的 JVM 内存里,而是统一存在 Redis 集群中,所有服务器都去 Redis 里存取 Session。

23. 既然有 HTTP 协议,为什么还要有 RPC?

RPC(Remote Procedure cal),又叫做远程过程调用。它本身并不是一个具体的协议,而是一种调用方式。

  • RPC 本质上不算是协议,而是一种调用方式,而像 gRPC 和 Thrift 这样的具体实现,才是协议,它们是实现了 RPC 调用的协议。目的是希望程序员能像调用本地方法那样去调用远端的服务方法。同时 RPC 有很多种实现方式,不一定非得基于 TCP 协议
  • 从发展历史来说,HTTP 主要用于 B/S 架构,而 RPC 更多用于 C/S 架构。但现在其实已经没分那么清了,B/S 和 C/S 在慢慢融合。很多软件同时支持多端,所以对外一般用 HTTP 协议,而内部集群的微服务之间则采用 RPC 协议进行通讯。
  • RPC 其实比 HTTP 出现的要早,且比目前主流的 HTTP/1.1 性能要更好,所以大部分公司内部都还在使用 RPC。
  • HTTP/2.0 在 HTTP/1.1 的基础上做了优化,性能可能比很多 RPC 协议都要好,但由于是这几年才出来的,所以也不太可能取代掉 RPC。

24. 什么是WebSocket和Socket?有什么区别?

Socket 和 WebSocket 的关系,就像 Java 和 JavaScript、雷锋和雷锋塔的关系一样——虽然名字里都有 Socket,但它们根本不是一个层面的东西。

什么是 Socket?

Socket 不是一个协议,而是一个 API (应用程序接口) 或 抽象层。它是处于应用层传输层(TCP/UDP)之间的一组接口。它封装了 TCP/IP 协议复杂的握手、挥手、流控细节,提供给程序员简单的 open, write, read, close 方法。

什么是 WebSocket?

WebSocket 是应用层协议,用于 Web 实时通信。

  • 实现了浏览器与服务器之间的 全双工 (Full-duplex) 通信

  • 一旦建立连接,服务器和客户端可以随时向对方发送数据,不再需要客户端轮询。

WebSocket 是怎么建立的?

  • A: “通过 HTTP 协议升级而来。客户端发送带有 Upgrade: websocket 的 HTTP 请求,服务器返回 101 Switching Protocols,之后协议切换为 WebSocket,复用 TCP 连接。”

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值