feat: add 180 questions (90 sc + 90 fb) for networking subtopics
Deploy Examination / deploy (push) Successful in 31s

Cover 9 subtopics from the computer networking documentation:
- http-handshake: TCP/TLS/HTTP2/HTTP3 handshakes
- http-connection-cost: connection resource overhead & million concurrency
- connection-pooling: pool reuse, HTTP/1.1 vs HTTP/2
- http-keepalive: Keep-Alive principle, head-of-line blocking
- keepalive-scenarios: when to enable/disable Keep-Alive
- domain-sharding: HTTP/1.1 hack, HTTP/2 obsolescence
- cdn: edge nodes, caching, DDoS protection
- cors: same-origin policy, preflight requests
- go-build-strip: -s -w flags, binary size optimization
This commit is contained in:
2026-09-02 21:33:09 +08:00
parent 0fbdefb626
commit df63692a18
28 changed files with 4143 additions and 1 deletions
@@ -0,0 +1,201 @@
{
"topic": "http-keepalive",
"type": "fill_blank",
"schema_version": "1.0.0",
"generated": "2026-09-02T21:20:00+08:00",
"questions": [
{
"id": "fb-001",
"type": "fill_blank",
"difficulty": 2,
"tags": [
"HTTP/1.0",
"TCP",
"连接模型"
],
"question": "HTTP/1.0 不支持 Keep-Alive,每次请求都需要建立一个新的 TCP 连接,即____模型。",
"answer": [
"一请求一连接",
"一次请求一个连接",
"短连接"
],
"answer_rule": "any",
"explanation": "HTTP/1.0 默认行为是每次 HTTP 请求都经历完整的 TCP 三次握手,请求完成后立即关闭连接。这意味着每次请求都要付出建立和拆除连接的开销,在页面包含大量资源时效率极低。这是后来引入 Keep-Alive 机制的直接动因。",
"source": null,
"related": []
},
{
"id": "fb-002",
"type": "fill_blank",
"difficulty": 2,
"tags": [
"HTTP/1.1",
"Keep-Alive",
"默认行为"
],
"question": "与 HTTP/1.0 不同,HTTP/1.1 默认启用____机制,无需显式声明即可复用 TCP 连接。",
"answer": [
"Keep-Alive",
"持久连接",
"keep-alive"
],
"answer_rule": "any",
"explanation": "HTTP/1.1 将 Keep-Alive(持久连接)作为默认行为。客户端和服务器建立连接后,可以在这个连接上依次发送和接收多个请求/响应,而不需要每次请求都重新建连。如果需要关闭连接,需要显式发送 Connection: close 头。",
"source": null,
"related": []
},
{
"id": "fb-003",
"type": "fill_blank",
"difficulty": 2,
"tags": [
"Connection头",
"Keep-Alive",
"HTTP头"
],
"question": "HTTP 协议通过 ____ 请求头来协商连接复用行为。当值为 Keep-Alive 表示____,当值为 close 表示____。",
"answer": [
"Connection,希望复用连接,请求完成后关闭连接",
"Connection 希望复用连接 请求完成后关闭连接"
],
"answer_rule": "any",
"explanation": "Connection 是 HTTP 中控制连接行为的首部字段。在 HTTP/1.1 中默认 Keep-Alive,通常不需要显式声明;但在 HTTP/1.0 中需要显式发送 Connection: Keep-Alive 才能启用复用。Connection: close 则用于告诉对端:这是最后一个请求,处理完请关闭连接。",
"source": null,
"related": []
},
{
"id": "fb-004",
"type": "fill_blank",
"difficulty": 3,
"tags": [
"Keep-Alive参数",
"timeout",
"max"
],
"question": "Keep-Alive 的 timeout 参数表示____,max 参数表示____,两者任一达到限制服务器即关闭连接。",
"answer": [
"空闲超时时间,最大请求次数",
"空闲超时时间 最大请求数量"
],
"answer_rule": "any",
"explanation": "timeout 指连接在空闲状态下(没有新请求)的最大存活时间,单位通常为秒;max 指该连接上允许处理的最大请求次数。例如 Keep-Alive: timeout=5, max=100 表示空闲超过 5 秒或已处理 100 个请求后关闭连接。服务器通过这两个参数防止连接被客户端长期占用。",
"source": null,
"related": []
},
{
"id": "fb-005",
"type": "fill_blank",
"difficulty": 3,
"tags": [
"队头阻塞",
"HTTP/1.1",
"串行"
],
"question": "HTTP/1.1 Keep-Alive 模式下,同一连接上的请求是严格____的,前一个请求的响应未返回之前不能发送下一个请求,这被称为____。",
"answer": [
"串行,队头阻塞",
"串行 队头阻塞"
],
"answer_rule": "any",
"explanation": "HTTP/1.1 的管道化(pipelining)虽然理论上允许客户端连续发送多个请求,但浏览器出于兼容性和安全性考虑基本未启用。实际中同一连接上的请求仍然是串行的——必须等上一个响应完全接收后才能发送下一个请求。这种「队头阻塞」(head-of-line blocking)是 HTTP/1.1 最大的性能瓶颈。",
"source": null,
"related": []
},
{
"id": "fb-006",
"type": "fill_blank",
"difficulty": 3,
"tags": [
"浏览器",
"并发连接",
"队头阻塞"
],
"question": "为规避 HTTP/1.1 的队头阻塞问题,主流浏览器对同一域名默认开启____个 TCP 连接来并行加载资源。",
"answer": [
"6"
],
"answer_rule": "all",
"explanation": "Chrome、Firefox 等主流浏览器对同一域名同时打开 6 个 TCP 连接(HTTP/1.1),将资源分配到不同连接上并行下载。这是一种工程上的折中:既利用了 Keep-Alive 复用,又通过多连接规避了串行问题。但这会消耗更多连接数和内存,也是推动 HTTP/2 普及的重要原因之一。",
"source": null,
"related": []
},
{
"id": "fb-007",
"type": "fill_blank",
"difficulty": 4,
"tags": [
"HTTP演进",
"Keep-Alive",
"HTTP/2",
"HTTP/3"
],
"question": "HTTP 连接复用的演进路线为:无 Keep-Alive(HTTP/1.0)→____(HTTP/1.1)→____(HTTP/2)→____(HTTP/3,基于 QUIC 解决 TCP 层队头阻塞)。",
"answer": [
"Keep-Alive,多路复用,QUIC"
],
"answer_rule": "ordered",
"explanation": "HTTP/1.0 每请求一连接;HTTP/1.1 引入 Keep-Alive 实现连接复用但有队头阻塞;HTTP/2 通过多路复用在单连接上交错传输多个流,解决了应用层队头阻塞;HTTP/3 基于 QUIC 协议用 UDP 替代 TCP,连传输层的队头阻塞也一并解决。这条演进路线的核心驱动力就是不断提升连接复用效率。",
"source": null,
"related": []
},
{
"id": "fb-008",
"type": "fill_blank",
"difficulty": 3,
"tags": [
"空闲连接",
"内存",
"文件描述符"
],
"question": "Keep-Alive 空闲连接虽然不传输数据,但仍占用服务器的____和____资源,大量空闲连接会导致资源耗尽。",
"answer": [
"内存,文件描述符",
"内存 fd",
"内存 socket"
],
"answer_rule": "any",
"explanation": "每条 TCP 连接在内核中需要维护 socket 缓冲区(消耗内存)和一个文件描述符(fd)。如果服务器对所有客户端保持大量空闲的 Keep-Alive 连接,内存和 fd 可能被耗尽,导致新连接无法建立。这就是为什么服务器必须配置合理的 keepalive_timeout 和 max connections 来限制空闲连接数。",
"source": null,
"related": []
},
{
"id": "fb-009",
"type": "fill_blank",
"difficulty": 3,
"tags": [
"服务器",
"连接关闭",
"RST"
],
"question": "当服务器单方面关闭了一个 Keep-Alive 空闲连接时,客户端可能并不知道连接已断开,下次请求时会收到____错误。",
"answer": [
"Connection reset by peer",
"连接被重置",
"连接重置"
],
"answer_rule": "any",
"explanation": "服务器因超时或负载原因关闭了空闲连接后发送 FIN 或 RST 包,但如果客户端此时没有监听,可能不会感知。当下次请求尝试使用这条已关闭的连接时,会收到 Connection reset by peer(对端重置连接)或 Broken pipe 错误。成熟的客户端库会自动重试新建连接来处理此情况。",
"source": null,
"related": []
},
{
"id": "fb-010",
"type": "fill_blank",
"difficulty": 2,
"tags": [
"Keep-Alive",
"利弊",
"权衡"
],
"question": "Keep-Alive 的核心优势是____,主要代价是空闲时____,需要根据场景权衡使用。",
"answer": [
"减少建连开销、提升吞吐,占用内存和文件描述符",
"减少握手开销 占用资源"
],
"answer_rule": "any",
"explanation": "Keep-Alive 通过复用 TCP 连接避免了反复建连和拆连的开销,显著提升高频请求场景的吞吐和延迟。但代价是空闲连接会持续占用服务器的内存和文件描述符资源。因此在高频访问的场景应开启,而对低频或一次性的请求,Keep-Alive 的收益很小,反而白白占用资源。",
"source": null,
"related": []
}
]
}
@@ -0,0 +1,50 @@
{
"slug": "http-keepalive",
"name": "Http Keepalive",
"description": "",
"tags": [
"Connection头",
"HTTP/1.0",
"HTTP/1.1",
"HTTP/2",
"HTTP/3",
"HTTP头",
"HTTP演进",
"Keep-Alive",
"Keep-Alive参数",
"RST",
"TCP",
"max",
"timeout",
"串行",
"内存",
"利弊",
"并发连接",
"文件描述符",
"服务器",
"权衡",
"浏览器",
"空闲连接",
"连接关闭",
"连接模型",
"队头阻塞",
"默认行为"
],
"difficulty_range": [
2,
4
],
"schema_version": "1.0.0",
"updated": "2026-09-02",
"question_files": [
"single_choice",
"fill_blank"
],
"stats": {
"total": 20,
"by_type": {
"single_choice": 10,
"fill_blank": 10
}
}
}
@@ -0,0 +1,210 @@
{
"topic": "http-keepalive",
"type": "single_choice",
"schema_version": "1.0.0",
"generated": "2026-09-02T21:20:00+08:00",
"questions": [
{
"id": "sc-001",
"type": "single_choice",
"difficulty": 2,
"tags": [
"Keep-Alive",
"HTTP/1.1"
],
"question": "HTTP/1.1 默认是否启用 Keep-Alive?",
"options": {
"A": "默认不启用",
"B": "默认启用",
"C": "需要手动配置",
"D": "仅 HTTPS 启用"
},
"answer": "B",
"explanation": "HTTP/1.1 默认启用 Keep-Alive,建一次连接后可以连续发多个请求,不用每次重新握手。这是 HTTP/1.1 最重要的默认优化。",
"source": null,
"related": []
},
{
"id": "sc-002",
"type": "single_choice",
"difficulty": 3,
"tags": [
"Keep-Alive",
"Connection头"
],
"question": "服务器通过哪个响应头告诉客户端连接可以复用?",
"options": {
"A": "Connection: close",
"B": "Connection: Keep-Alive",
"C": "Keep-Alive: true",
"D": "Reuse: true"
},
"answer": "B",
"explanation": "服务器通过 Connection: Keep-Alive 响应头告诉客户端这个连接可以复用。Connection: close 表示不要复用。",
"source": null,
"related": []
},
{
"id": "sc-003",
"type": "single_choice",
"difficulty": 3,
"tags": [
"Keep-Alive",
"timeout",
"max"
],
"question": "Keep-Alive: timeout=5, max=100 中 max=100 的含义是?",
"options": {
"A": "最大并发连接数为 100",
"B": "空闲超时 100 秒",
"C": "单连接最多处理 100 个请求后强制关闭",
"D": "最大响应大小 100KB"
},
"answer": "C",
"explanation": "max=100 表示单连接最多处理 100 个请求后强制关闭。timeout=5 表示空闲超过 5 秒没新请求就关闭连接。两者取先触发的那个。",
"source": null,
"related": []
},
{
"id": "sc-004",
"type": "single_choice",
"difficulty": 3,
"tags": [
"队头阻塞",
"HTTP/1.1"
],
"question": "Keep-Alive 引入了什么问题?",
"options": {
"A": "带宽不足",
"B": "队头阻塞",
"C": "DNS 解析慢",
"D": "TLS 握手失败"
},
"answer": "B",
"explanation": "Keep-Alive 解决了频繁握手问题,但引入了队头阻塞——同一连接上的请求严格串行,后一个请求必须等前一个响应返回。浏览器用多开 6 个连接来弥补。",
"source": null,
"related": []
},
{
"id": "sc-005",
"type": "single_choice",
"difficulty": 4,
"tags": [
"HTTP/1.1",
"浏览器",
"6连接"
],
"question": "HTTP/1.1 的 Keep-Alive 存在队头阻塞,浏览器用什么方式弥补?",
"options": {
"A": "使用 HTTP/2",
"B": "同时开 6 个 TCP 连接",
"C": "使用 UDP 协议",
"D": "增大窗口大小"
},
"answer": "B",
"explanation": "浏览器同时开 6 个 TCP 连接来弥补 HTTP/1.1 的队头阻塞问题——一条收银通道排队太慢,所以超市开了 6 个收银台,但每个收银台内部还是串行的。",
"source": null,
"related": []
},
{
"id": "sc-006",
"type": "single_choice",
"difficulty": 2,
"tags": [
"Keep-Alive",
"HTTP/1.0"
],
"question": "HTTP/1.0 的连接模型是怎样的?",
"options": {
"A": "一个连接串行多个请求",
"B": "一个请求一个连接,用完即弃",
"C": "一个连接并行多个请求",
"D": "使用 UDP 协议"
},
"answer": "B",
"explanation": "HTTP/1.0 没有 Keep-Alive,一个请求一个连接,用完即弃。每个资源都要走一遍握手流程,光握手就比传数据花的时间还多。",
"source": null,
"related": []
},
{
"id": "sc-007",
"type": "single_choice",
"difficulty": 4,
"tags": [
"Keep-Alive",
"空闲连接"
],
"question": "Keep-Alive 连接在空闲时会占用什么资源?",
"options": {
"A": "只占用 CPU",
"B": "占用内存和文件描述符",
"C": "不占用任何资源",
"D": "只占用网络带宽"
},
"answer": "B",
"explanation": "Keep-Alive 连接在空闲时仍然占内存和 fd。如果客户端长时间不发新请求,服务器应该主动关闭。合理设置 timeout 参数很重要。",
"source": null,
"related": []
},
{
"id": "sc-008",
"type": "single_choice",
"difficulty": 3,
"tags": [
"Keep-Alive",
"演进"
],
"question": "HTTP 连接复用的演进路线正确的是?",
"options": {
"A": "Keep-Alive → HTTP/1.0 → HTTP/2",
"B": "无 Keep-Alive → Keep-Alive → HTTP/2 多路复用 → HTTP/3 QUIC",
"C": "HTTP/2 → Keep-Alive → HTTP/3",
"D": "TCP → UDP → HTTP/3"
},
"answer": "B",
"explanation": "演进路线:HTTP/1.0 无 Keep-Alive → HTTP/1.1 默认 Keep-Alive → 浏览器并行连接缓解队头阻塞 → HTTP/2 多路复用 → HTTP/3 QUIC 基于 UDP 的多路复用。",
"source": null,
"related": []
},
{
"id": "sc-009",
"type": "single_choice",
"difficulty": 2,
"tags": [
"Keep-Alive",
"Connection头"
],
"question": "不想复用连接时,服务器应该返回什么头?",
"options": {
"A": "Connection: Keep-Alive",
"B": "Connection: close",
"C": "Keep-Alive: false",
"D": "Connection: none"
},
"answer": "B",
"explanation": "不想复用连接时,服务器返回 Connection: close,告诉客户端处理完当前请求后关闭连接。",
"source": null,
"related": []
},
{
"id": "sc-010",
"type": "single_choice",
"difficulty": 3,
"tags": [
"Keep-Alive",
"服务器"
],
"question": "服务器因超时关闭了连接,但客户端下次复用时才发现连接已死,这种情况应该怎么处理?",
"options": {
"A": "忽略错误",
"B": "开启连接健康检查或设置合理的超时",
"C": "增大连接池",
"D": "使用 HTTP/1.0"
},
"answer": "B",
"explanation": "服务器因超时关闭了连接,但客户端不知道,下次复用时才发现连接已死。需要开启连接健康检查或设置合理的超时来避免这个问题。",
"source": null,
"related": []
}
]
}