HTTP
1. HTTP协议的特点是什么?
-
分析:
-
HTTP 是灵活可扩展的、可以任意添加头字段实现任意功能;
-
HTTP 是可靠传输协议、基于 TCP/IP 协议“尽量保证数据的送达
-
HTTP 是应用层协议、比 FTP、SSH 等更通用功能更多、能够传输任意数据;
-
HTTP 使用了请求-应答模式,客户端主动发起请求、服务器被动回复请求;
-
HTTP 本质上是无状态的、每个请求都是互相独立、毫无关联的、协议不要求客户端或服务器记录请求相关的信息。
-
参考面试回答:
-
HTTP 具有简单、灵活可扩展、无状态等特点,是一种广泛应用于 Web 通信的协议。
-
基于文本:HTTP 的消息是以文本形式传输、明文传输协议
-
可扩展性:HTTP 协议本身不限制数据的内容和格式、可以通过扩展头部、方法等来支持新的功能。
-
灵活性:HTTP 支持不同的数据格式(如 HTML、JSON、XML 等),适用于多种应用场景。
-
请求应答模式:HTTP 协议使用的是请求-应答通信模式、请求方先发起连接和请求,是主动的、而应答方只有在收到请求后才能答复、是被动的、如果没有请求时不会有任何动作。
-
无状态:HTTP 每个请求之间相互独立、服务器不会保留之前请求的状态信息、需要通过其他手段(如 Cookies、Session)来维护状态。
2. HTTP 和 HTTPS 有什么区别
分析
从安全性、建立连接、端口号、证书三个方向来说明 HTTP 和 HTTPS 的区别。
参考面试回答:
理解主要有4个方面的区别:
-
安全性:HTTP是明文传输协议,数据在传输过程中不加密,容易被窃听和篡改。而HTTPS通过使用SSL/TLS协议对数据进行加密,提供了更高的安全性和数据保护。
-
建立连接:HTTP连接建立相对简单,TCP三次握手之后便可进行HTTP的报文传输。而HTTPS在TCP三次握手之后,还需进行SSL/TLS的握手过程,才可进入加密报文传输。
-
端口号:HTTP默认使用端口号80进行通信,而HTTPS默认使用端口号443。
-
证书:HTTPS需要使用数字证书来验证服务器的身份,并确保数据传输的安全性。证书由受信任的第三方机构颁发,用于证明服务器的身份和所有权。而HTTP没有使用证书进行身份验证和加密
3. HTTP 的报文结构
HTTP 报文格式分为请求行、请求头、请求体三个部分。
-
请求行的内容是 HTTP 方法、URL、HTTP 版本号、请求行里的字段之间是通过空格分割、请求行和请求头是通过 \r\n 分割的。
-
请求头的内容是多个键值对字段的集合、键和值通过冒号分割、每个字段之间通过 \r\n 分割
-
请求体的内容是实体数据、请求头和请求体之间是通过空白行分割的、即两个连续的 \r\n(回车符+换行符)。
参考面试回答:
HTTP 报文格式分为请求行、请求头、请求体三个部分:
-
请求行是请求或响应的基本信息、比如请求方法、URL、HTTP 版本信息
-
请求头使用 key-value 形式更详细地说明报文、比如 Host 字段、Connection 字段、Content-Length 字段
-
请求体是实际传输的数据、比如文本数据、图片数据
4. HTTP和HTTPS的默认端口是什么
HTTP默认端口是80 HTTPS默认端口是443
5. HTTP有什么方法
分析:
目前HTTP/1.1规定了八种方法 单词必必须都是大写
说常用的几个方法、比如 GET、POST、PUT、HEAD、DELETE
参考面试回答:
我了解到 HTTP 方法的有 GET、POST、PUT、HEAD、DELETE 这些方法,其中:
-
GET 方法是用来请求从服务器获取资源的;
-
HEAD 方法和 GET 方法类似、也是请求从服务器获取资源、但与 GET 请求不同的是、服务器不会返回请求的实体数据、只会传回响应头、也就是获取的是资源的元信息。
-
POST 方法是用来向服务器端提交数据、数据就放在报文的 body 里
-
PUT 方法和 POST 类似、也可以向服务器提交数据、区别在于 POST 是新增数据。PUT 是更新数据。
-
DELETE 方法是用来删除资源
在项目开发中 用的比较多是 GET 和 POST 请求。
6. 分析一下哪些 HTTP 方法是安全或者幂等的
分析
在 HTTP 协议里:
-
所谓的安全是指请求方法不会破坏服务器上的资源\即不会对服务器上的资源造成实质的修改。
-
所谓的幂等实际上是一个数学用语\被借用到了 HTTP 协议里\意思是多次执行相同的操作\结果也都是相同的,即多次幂后结果相等。
分类:
-
安全的方法:GET / HEAD
-
不安全的方法:POST / DELETE / PUT
-
幂等的方法:GET / HEAD / DELETE / PUT
-
不幂等的方法:POST
参考面试回答:
GET 和 HEAD 方法是安全且幂等的、因为它们是只读操作、只要开发者遵循规范要求的去处理请求、无论 GET 和 HEAD 操作多少次、服务器上的数据都是安全的。
而 POST/PUT/DELETE 这些方法都会增上改服务器上的资源、所以是不安全的。
DELETE 和 PUT 方法是幂等的、因为 DELETE 是删除资源、多次删除、效果都是资源不存在、所以也是幂等的,另一个 PUT 是更新数据、多次更新数据、结果都一样、所以是幂等的。
但是 POST 是不幂等的、因为多次 POST 请求、会创建多个资源、所以不是幂等的。
7. GET 和 POST 请求的区别?
分析
从几个角度分析:
-
两个请求的语义上的区别
-
两个请求的是否是安全且幂等的?
-
请求参数的区别
参考面试回答:
-
GET 请求是从服务器获取资源、POST 请求是向服务器提交数据。
-
GET 方法是只读操作、所以是安全且幂等的、而 POST 方法会修改服务器上的资源、并且多次 POST 请求,会创建多个资源,所以不是安全,也不是幂等的。
-
GET 请求的请求参数放在 URL 中的查询字符串中、浏览器对 URL 长度限制、所以 GET 请求的请求参数会有长度限制
-
而 POST 请求的请求参数是放在请求体中、POST 请求的请求参数长度没有限制
8. HTTP长连接和短连接的区别
参考面试回答:
-
短连接:每次通信请求都需要建立新的连接、请求完成后立即关闭连接。这样每次请求都需要建立连接和释放连接、会增加通信开销和延迟。
-
长连接:在通信过程中保持连接的持续性、多次请求可以共享同一个连接。在长连接中、客户端和服务器建立连接后可以进行多次请求和响应、减少了连接建立和释放的开销、提高了通信效率。
9. HTTP 长连接有什么好处?
分析:
-
短连接:在一次 TCP 连接中只能发送和响应一个 HTTP 请求
-
即:建立 TCP -> 请求资源 -> 响应资源 -> 释放连接
-
-
长连接:在一次 TCP 连接中可以发送和响应多个 HTTP 请求
-
即:建立 TCP -> 请求资源 -> 响应资源 -> 请求资源 -> 响应资源 -> 请求资源 -> 响应资源 -> .... -> 释放连接
-
参考面试回答:
长连接可以在一次 TCP 连接中可以发送和响应多个 HTTP 请求、可以减少了 TCP 连接资源创建和断开的开销。
10. HTTP/1.0 和 HTTP/1.1 的区别
分析
HTTP/1.0 和 HTTP/1.1 两者的主要区别体现在:
-
长连接:
-
在 HTTP/1.0 中、默认使用的是短连接、即每次请求都要重新建立一次连接。由于 HTTP 是基于 TCP/IP 协议的、每次建立或断开连接都需要经过三次握手和四次挥手的过程、如果每次请求都这样的话、开销会比较大。因此最好能维持一个长连接、可以用长连接来发送多个请求。从 HTTP 1.1 开始、默认使用长连接
-
-
请求管道化:
Host头字段:-
HTTP/1.0 没有
host
字段 -
HTTP/1.1 新增了
host
字段。通过 Host 头部字段、一个物理服务器可以承载多个域名或站点
-
HTTP 1.1 支持请求管道化、用的是TCP复用连接、即在一个持久连接上可以同时发送多个请求、而 HTTP 1.0 不支持请求管道化。在 HTTP/1.0 中、请求和响应必须是串行的、当一个请求和它的响应完成之后、才能发送下一个请求。而 HTTP/1.1 由于支持管道传输方式、因此可以并发发送 HTTP 请求、能够提高 HTTP 请求的效率。
-
-
错误响应码:
-
在 HTTP 1.1 中、新增了 24 个错误状态响应码、如 409(Conflict):表示请求的资源与资源的当前状态发生冲突。410(Gone):表示服务器上的某个资源被永久性的删除;
-
-
缓存处理:
-
HTTP 1.0 中:主要使用
header
头里的If-Modified-Since
、Expires
来做为缓存判断的标 -
HTTP 1.1:则引入了更多的缓存控制策略,如 Entity tag,If-Unmodified-Since,If-Match,If-None-Match 等
-
-
带宽优化及网络连接的使用:
-
HTTP 1.0 中:存在一些浪费带宽的现象、例如客户端只是需要某个对象的一部分、而服务器却将整个对象传送了过来、并且不支持断点续传功能。
-
HTTP 1.1 中:则在请求头引入了
range
头域,它允许只请求资源的某个部分、即返回码是 206(Partial Content)、这样方便开发者自由的选择、以便于充分利用带宽和连接
-
参考面试回答:
长连接:
- HTTP/1.1 默认的连接行为是长连接、而 HTTP/1.0 虽然也支持长连接、但是默认是使用短连接。
- 在 HTTP/1.0 中、默认使用的是短连接、即每次请求都要重新建立一次连接。由于 HTTP 是基于 TCP/IP 协议的、每次建立或断开连接都需要经过三次握手和四次挥手的过程、如果每次请求都这样的话、开销会比较大。因此最好能维持一个长连接、可以用长连接来发送多个请求。从 HTTP 1.1 开始、默认使用长连接
请求管道化:
- HTTP/1.1 支持请求管道传输的方式、HTTP/1.0 不支持这个模式。
- HTTP/1.0 请求和响应必须是串行的、当一个请求和它响应完成之后、才能发送下一个请求。
- 而 HTTP/1.1 由于支持管道传输方式、因此可以并发发送 HTTP 请求、即在一个持久连接上可以同时发送多个请求能够提高 HTTP 请求的效率、但是 HTTP 响应还是得按顺序响应。
host 字段:
- HTTP/1.0 没有
host
字段、HTTP/1.1 新增了 host 字段、通过 Host 头部字段、一个物理服务器可以承载多个域名或站点。
分析:
HTTP/1.1 存在队头阻塞问题:
在 HTTP/1.1 中、如果一个 TCP 连接上发送多个 HTTP 请求、这些请求必须按照发送顺序依次返回。如果第一个请求的处理速度很慢、或者由于网络问题导致第一个响应迟迟未到达、那么后续的请求都会被阻塞、即使它们已经准备好被发送或接收。
HTTP/1.1 的管道化: HTTP/1.1 引入了管道化、允许客户端在收到前一个请求的响应之前、发送多个请求。 这看起来像并发请求、但实际上服务器 必须 按照接收请求的顺序发送响应
-
队头阻塞 in HTTP/1.1: 如果服务器在处理第一个请求时遇到延迟(例如 数据库查询缓慢) 那么后续所有请求的响应都必须等待第一个请求完成。 即使后续请求已经准备好响应、它们也无法发送、因为服务器必须按照顺序发送响应。 这就是队头阻塞。 想象一下你在超市排队结账、如果排在第一个的人遇到了付款问题、后面所有的人都必须等待。
-
为什么不是完全并发 :虽然客户端可以并发发送请求(通过管道化)、但服务器不能 并发发送响应。 响应必须按顺序发送、限制了并发的程度、并导致队头阻塞。
11. HTTP/1.1 和 HTTP/2.0 的区别
分析
HTTP/2 相比 HTTP/1.1 性能上的改进:
-
并发传输(最重要的区别)
-
头部压缩+二进制格式
-
服务器主动推送资源
参考面试回答:
我认为 HTTP/1.1 和 HTTP/2.0 最大的区别在于:
-
HTTP/1.1 无法实现请求和响应的并发传输
-
HTTP/2.0 能够实现请求和响应的并发传输
HTTP/1.1 虽然支持了管道化请求模式、能够并发传输 HTTP 请求、但是 HTTP 响应还是需要按顺序返回、无法做到 HTTP 响应并发传输,
HTTP/2 引入了 stream
的概念、不同的 HTTP 请求和响应用不同的 stream
来区分、多个 stream
复用一条 TCP 连接、只需要一条连接就可以达到并发传输的效果。多路复用允许在同一个 TCP 连接上同时发送多个请求和响应、而无需按顺序等待。 这解决了 HTTP/1.1 中一部分的队头阻塞 的问题、显著提高了性能。
HTTP/2.0 在 HTTP 报文格式上也做了改进、HTTP/2.0 用了 HPACK
算法压缩了 HTTP 头部 减少了头部的大小、从而减少了带宽消耗、从而减少传输延迟。
同时将 HTTP/1.1 纯文本的格式改进成了二进制格式、提高了数据传输的效率。二进制分帧: HTTP/2.0 使用二进制分帧层、将 HTTP 消息分解为更小的帧、这些帧可以交错发送、并在接收端重新组装。 这使得多路复用成为可能、并且更容易进行错误检测和流控制。
HTTP/2.0 还支持服务器主动推送资源、比如客户端在从服务器获取 HTML 文件时、可能这个页面渲染还需要其他 CSS、这时候服务器可以接主动推送 CSS 文件、可以减少了消息传递的次数。
补充:
HTTP/2 仍然存在的队头阻塞:
虽然 HTTP/2 解决了头部压缩导致的队头阻塞、但它仍然存在以下类型的队头阻塞:
-
TCP 队头阻塞 :HTTP/2 仍然基于 TCP 协议、如果 TCP 连接上发生丢包、TCP 协议需要重传丢失的数据包、这会导致后续的数据包被阻塞、从而影响性能。
-
单个
Stream
内部的队头阻塞: 虽然 HTTP/2 允许多个Stream
在一个 TCP 连接上并发传输、但每个 Stream 内部的帧仍然需要按照发送顺序依次处理。如果一个Stream
内部的某个帧丢失或延迟、仍然会阻塞该Stream
的后续帧。
12. HTTP/2.0 和 HTTP/3.0 的区别
分析: 先提到 HTTP 2.0 的缺陷、存在 TCP 队头阻塞问题、然后再提 HTTP 3.0 是怎么解决的、最后再提 HTTP 3.0 还有什么新特性。
参考面试回答:
-
HTTP 2.0 和 3.0 最大区别在于传输层使用的协议不同、以前 HTTP 都是基于 TCP 协议进行传输、这次 HTTP 3.0 改 用 UDP 协议
-
HTTP/2.0 先发传输的特性、是在一条 TCP 连接上实现的、这里会有 TCP 队头阻塞的问题、在传输过程中、假设某个
Stream
发生了丢包、服务器端不仅不能处理这个Stream
、也不能处理其他Stream
、必须等这个包重传之后才能继续处理其他Stream
。为了解决这个问题、HTTP/3.0 将传输层改用 UDP 协议、并在 UDP 基础上实现了一个可靠传输的 QUIC 协议。当某个流发生丢包时、只会阻塞这个stream
、其他stream
不会受到影响。因此不存在 TCP 队头阻塞问题。
除此之外:
-
HTTP/3.0 直接建立连接比 HTTP/2.0 更高效、HTTP/2.0 建立连接时需要 3 次握手、HTTP/3.0 的 QUIC 协议只需要 1 次握手就能完成连接 + TLS 握手建立
-
改用UDP解决了
TIME_WAIT
的问题 -
最后还有一点:HTTP/3.0 的网络环境切换时可以不需要重新建立连接。以 HTTP 协议为基础时、TCP 是根据四元组信息来确认一个信息流是否发生变化、这时就需要断开连接、重新建立连接、比如 4G 移动到公共 WIFI 网络时、所有的 TCP 连接都要重新建立。
-
而 HTTP/3.0 是在应用层通过流式 ID 来识别、切换网络时不会影响原来的连接、减少重新建立的成本
13.面试官追问:现代化有什么改进TIME_WAIT的手段吗
用 HTTP/3 是一个从根本上避免 TCP TIME_WAIT 问题的方法。
我的理解是这样的:
- HTTP/3 的基础是 QUIC,而 QUIC 运行在 UDP 之上,而非 TCP。 这是最关键的区别。
- TIME_WAIT 状态是 TCP 协议为了保证连接可靠关闭而特有的状态。 它需要确保最后一个 ACK 到达对方,并处理网络中可能存在的延迟报文。
- UDP 是无连接的协议。 它没有像 TCP 那样的连接建立和拆除的握手过程、自然也就没有像 TIME_WAIT 这样的连接状态。QUIC 在 UDP 的基础上实现了自己的连接管理、可靠性(类似 TCP 的流控制、拥塞控制等)和安全性机制。
- 因此当应用层协议从基于 TCP 的 HTTP/1.1 或 HTTP/2 迁移到基于 QUIC/UDP 的 HTTP/3 时、传输层本身就不再有 TIME_WAIT 状态了。 这就从源头上消除了由于大量短连接导致服务器端积累过多 TIME_WAIT 状态而引起的端口耗尽、内存占用等问题。
相较于在 TCP 层面进行优化(如 tcp_tw_reuse)、推广和采用 HTTP/3 可以看作是一种更彻底的解决方案、直接绕过了 TCP 的 TIME_WAIT 机制。
14. 请你谈谈 HTTP/1.0、HTTP/1.1、HTTP/2.0 和 HTTP/3.0 的区别
HTTP 协议经过了几个重要的演进。最初的 HTTP/1.0 比较简单、用的是短连接。每次请求都要建立一个新的 TCP 连接、效率比较低。
为了解决这个问题:HTTP/1.1 引入了长连接、允许在一个 TCP 连接上发送多个请求、避免了频繁建立和断开连接的开销。它还支持管道化、可以并发发送请求、但响应必须按顺序返回、所以如果前面的请求慢了、后面的请求也会被阻塞、这就是会存在队头阻塞的问题
HTTP/2.0 在 HTTP/1.1 的基础上引入了多路复用、允许在一个 TCP 连接上同时发送多个请求和响应、解决了 HTTP/1.1 的队头阻塞问题。它还使用了头部压缩和二进制格式、提高了传输效率。
最新的 HTTP/3.0 则更进一步、它不再使用 TCP 协议、而是改用 UDP 协议、并在 UDP 之上构建了一个可靠的传输协议 QUIC。这样做的好处是、即使某个数据包丢失、也不会影响其他 Stream 的传输、彻底解决了队头阻塞问题。另外HTTP/3.0 还支持连接迁移、网络切换时不需要重新建立连接、提高了移动网络的体验。
15. HTTP报文格式
HTTP 报文格式分为请求行、请求头、请求体三个部分。
-
请求行的内容是HTTP方法、URL、HTTP版本号,请求行里的字段之间是通过空格分割,请求行和请求头是通过\r\n分割的。
-
请求头的内容是多个键值对字段的集合,键和值通过冒号分割,每个字段之间通过\r\n分割;
-
请求体的内容是实体数据,请求头和请求体之间是通过空白行分割的,即两个连续的\r\n(回车符+换行符)。
参考面试回答:
HTTP 报文格式分为请求行、请求头、请求体三个部分:
-
请求行是请求或响应的基本信息,比如请求方法、URL、HTTP版本信息;
-
请求头使用
key-value
形式更详细地说明报文,比如Host
字段、Connection
字段、Content-Length字段 -
请求体是实际传输的数据,比如文本数据、图片数据
请求行和请求头是通过\r\n分割的、请求头和请求体之间是通过空白行分割的、也就是两个连续的\r\n。
16. HTTP是无状态的吗
分析
HTTP是无状态的、这意味着每个请求都是独立的、服务器不会在多个请求之间保留关于客户端状态的信息
-
在每个HTTP请求中、服务器不会记住之前的请求或会话状态、因此每个请求都是相互独立的、因此服务器不知道请求两次之间是否是同一个用户。
这会带来一个问题、用户登录后、切换到其他界面、进行操作、服务器端是无法判断是哪个用户登录的、每次进行页面跳转的时候、得重新登录。
-
虽然HTTP本身是无状态的、但可以通过一些机制来实现状态保持、其中最常见的方式是使用Cookie、Session、Token来跟踪用户状态。通过在客户端存储会话信息或状态信息、服务器可以识别和跟踪特定用户的状态,以提供一定程度的状态保持功能。
参考面试回答:
是的HTTP是无状态的、一般我们会通过Cookie、Session、Token
这些机制来维护用户的状态。