网络练习册
每道题后附答案与解析,建议先独立完成再对照。
一、选择题
第 1 题
OSI 七层模型中,HTTP 属于哪一层?
A. 传输层
B. 网络层
C. 应用层
D. 会话层
查看答案与解析
答案:C
解析:HTTP 是应用层协议,直接为用户应用提供服务。传输层典型协议是 TCP/UDP,网络层是 IP。
第 2 题
TCP 三次握手的主要目的是什么?
A. 加速数据传输
B. 确认双方收发能力正常,防止历史连接请求造成错误
C. 压缩数据
D. 直接开始传输数据
查看答案与解析
答案:B
解析:三次握手是为了同步双方初始序列号,确认双方都能收发数据。两次握手无法确认客户端的接收能力,也可能因网络延迟导致已失效的连接请求被服务器误处理。
第 3 题
HTTP/2 相比 HTTP/1.1 最重要的改进是什么?
A. 使用 UDP 代替 TCP
B. 支持多路复用,一个 TCP 连接可并行传输多个请求
C. 不支持头部压缩
D. 完全解决了队头阻塞
查看答案与解析
答案:B
解析:HTTP/2 通过二进制分帧和多路复用,解决了 HTTP/1.1 的队头阻塞。但 TCP 层的队头阻塞仍然存在,HTTP/3 基于 QUIC/UDP 才基本解决。
第 4 题
以下哪种 DNS 记录用于把域名映射到 IPv4 地址?
A. CNAME
B. MX
C. A
D. TXT
查看答案与解析
答案:C
解析:A 记录是 Address 记录,把域名解析为 IPv4 地址。AAAA 对应 IPv6,CNAME 是别名,MX 是邮件交换记录,TXT 是文本记录。
第 5 题
关于 WebSocket,以下说法正确的是?
A. WebSocket 基于 HTTP 长轮询
B. WebSocket 连接建立后仍使用 HTTP 协议通信
C. WebSocket 通过 HTTP 升级握手建立全双工 TCP 连接
D. WebSocket 不能跨域
查看答案与解析
答案:C
解析:WebSocket 先通过 HTTP 协议发送 Upgrade 请求,服务器返回 101 后升级为 WebSocket 协议,之后使用独立的帧格式全双工通信。
二、填空题
第 6 题
TCP/IP 四层模型从上到下依次是:应用层、______、网络层、网络接口层。
查看答案与解析
答案:传输层
解析:TCP/IP 模型四层为应用层、传输层、网络层、网络接口层。
第 7 题
HTTP 状态码中,______ 表示请求成功,______ 表示资源未找到,______ 表示服务器内部错误。
查看答案与解析
答案:200、404、500
解析:2xx 表示成功,4xx 表示客户端错误,5xx 表示服务器错误。常见:200 OK、404 Not Found、500 Internal Server Error。
第 8 题
CDN 的核心思想是把内容缓存到离用户最近的 ______ 节点,从而降低访问延迟。
查看答案与解析
答案:边缘(Edge)
解析:CDN 通过在全球部署边缘节点,让用户就近获取资源。边缘节点未命中时回源站获取。
第 9 题
RESTful 设计中,创建资源通常使用 HTTP 的 ______ 方法,删除资源通常使用 ______ 方法。
查看答案与解析
答案:POST、DELETE
解析:RESTful 用 URL 表示资源,用 HTTP 方法表示操作。POST 创建、GET 查询、PUT/PATCH 更新、DELETE 删除。
第 10 题
HTTPS 在 HTTP 和 TCP 之间加入了 ______ 协议层,用于加密通信。
查看答案与解析
答案:TLS(Transport Layer Security)/ SSL
解析:HTTPS = HTTP + TLS。TLS 提供加密、身份认证和数据完整性保护。
三、代码分析题
第 11 题
分析以下 HTTP 响应头,说明缓存行为。
Cache-Control: max-age=3600, must-revalidate
ETag: "abc123"查看答案与解析
答案:
max-age=3600:资源在 3600 秒(1 小时)内可直接使用本地缓存,不发请求。must-revalidate:缓存过期后必须向服务器验证,不能使用过期缓存。ETag:用于协商缓存,过期后浏览器会带If-None-Match询问服务器。
解析:强缓存和协商缓存可共存。max-age 控制强缓存,ETag 控制协商缓存。
第 12 题
下面 RESTful API 设计有哪些问题?
GET /getUser?id=123
POST /deleteUser
GET /users/delete/123查看答案与解析
答案:
/getUser?id=123:URL 中不应包含动词get,应改为GET /users/123。POST /deleteUser:不应使用 POST + 动词表示删除,应改为DELETE /users/123。GET /users/delete/123:GET 方法不应用于删除操作,且 URL 中不应有delete动词。
解析:RESTful 设计强调用 URL 表示资源,用 HTTP 方法表示动作,保持语义清晰。
第 13 题
分析 TCP 四次挥手为什么需要四次,而不是三次。
查看答案与解析
答案:
TCP 是全双工通信,双方都有独立的发送和接收通道。关闭连接时:
- 主动方发送 FIN,表示不再发送数据(但仍可接收)。
- 被动方 ACK 确认。
- 被动方处理完数据后也发送 FIN。
- 主动方 ACK 确认。
因为被动方可能还有数据要发送,所以不能把 ACK 和 FIN 合并,需要四次。
解析:三次握手可以合并 SYN+ACK,是因为双方同时开始连接。四次挥手双方关闭时机不同,无法合并。
第 14 题
分析 GraphQL 查询相比 REST 的优势和不足。
query {
user(id: 1) { name posts { title } }
}查看答案与解析
答案:
优势:
- 一次请求获取用户信息和文章列表,避免多次 REST 调用。
- 客户端精确指定字段,避免过度获取。
不足:
- 服务器需要实现解析器和 Schema,复杂度增加。
- HTTP 缓存不如 REST 成熟。
- 错误处理、文件上传需要额外设计。
解析:GraphQL 适合复杂数据聚合场景,REST 适合简单、缓存友好的场景,应结合实际选择。
四、编程实践题
第 15 题
实现一个简单的 fetch 超时封装。
查看答案与解析
参考答案:
function fetchWithTimeout(url, options = {}, timeout = 5000) {
return Promise.race([
fetch(url, options),
new Promise((_, reject) =>
setTimeout(() => reject(new Error("Request timeout")), timeout)
)
]);
}解析:
- 使用
Promise.race让 fetch 和定时器竞争。 - 超时时间内 fetch 未完成则 reject。
- 生产环境建议配合 AbortController 取消请求,避免资源浪费。
第 16 题
实现一个带重试机制的 fetch 函数。
查看答案与解析
参考答案:
async function fetchWithRetry(url, options = {}, maxRetries = 3, delay = 1000) {
let lastError;
for (let i = 0; i <= maxRetries; i++) {
try {
const res = await fetch(url, options);
if (!res.ok) throw new Error(`HTTP ${res.status}`);
return res;
} catch (err) {
lastError = err;
if (i < maxRetries) await new Promise(r => setTimeout(r, delay));
}
}
throw lastError;
}解析:
- 循环执行 fetch,失败则等待后重试。
- 达到最大重试次数后抛出最后一次错误。
- 实际项目中应根据错误类型决定是否重试(如 4xx 不应重试)。
第 17 题
实现一个简单的 WebSocket 重连封装。
查看答案与解析
参考答案:
class ReconnectingWebSocket {
constructor(url, options = {}) {
this.url = url;
this.maxRetries = options.maxRetries || 5;
this.retryDelay = options.retryDelay || 1000;
this.retries = 0;
this.listeners = {};
this.connect();
}
connect() {
this.ws = new WebSocket(this.url);
this.ws.onopen = (e) => {
this.retries = 0;
this.emit("open", e);
};
this.ws.onmessage = (e) => this.emit("message", e);
this.ws.onclose = () => this.reconnect();
this.ws.onerror = (e) => this.emit("error", e);
}
reconnect() {
if (this.retries >= this.maxRetries) {
this.emit("maxretry");
return;
}
this.retries++;
setTimeout(() => this.connect(), this.retryDelay * this.retries);
}
send(data) { this.ws.send(data); }
on(event, handler) { this.listeners[event] = handler; }
emit(event, data) { this.listeners[event]?.(data); }
}解析:
- 监听 onclose 自动重连。
- 限制最大重试次数,采用退避策略避免频繁重连。
- 实际生产还需处理心跳、消息队列等。
第 18 题
实现一个简单的 RESTful 客户端方法。
查看答案与解析
参考答案:
class HttpClient {
constructor(baseURL) { this.baseURL = baseURL; }
async request(method, path, data) {
const options = {
method,
headers: { "Content-Type": "application/json" }
};
if (data) options.body = JSON.stringify(data);
const res = await fetch(`${this.baseURL}${path}`, options);
if (!res.ok) throw new Error(`HTTP ${res.status}`);
return res.json();
}
get(path) { return this.request("GET", path); }
post(path, data) { return this.request("POST", path, data); }
put(path, data) { return this.request("PUT", path, data); }
patch(path, data) { return this.request("PATCH", path, data); }
delete(path) { return this.request("DELETE", path); }
}解析:
- 封装通用请求方法。
- 提供 RESTful 常用方法。
- 生产环境需补充错误处理、拦截器、取消请求等。
第 19 题
实现一个 DNS 预解析和预连接的 HTML 片段。
查看答案与解析
参考答案:
<head>
<link rel="dns-prefetch" href="//cdn.example.com">
<link rel="preconnect" href="https://cdn.example.com">
<link rel="prefetch" href="https://example.com/next-page.html">
</head>解析:
dns-prefetch:提前解析域名。preconnect:提前建立 TCP/TLS 连接。prefetch:提前下载下一个页面可能用到的资源。- 注意不要滥用,否则浪费带宽。
第 20 题
实现一个请求合并函数:对于相同的 GET 请求,在并发场景下只发一次网络请求。
查看答案与解析
参考答案:
function createDeduplicatedFetch() {
const pending = new Map();
return function dedupFetch(url) {
if (pending.has(url)) return pending.get(url);
const promise = fetch(url)
.then(res => res.json())
.finally(() => pending.delete(url));
pending.set(url, promise);
return promise;
};
}
const fetchOnce = createDeduplicatedFetch();
Promise.all([fetchOnce("/api/user"), fetchOnce("/api/user")])
.then(([a, b]) => console.log(a === b)); // true,只发一次请求解析:
- 用 Map 缓存正在进行的请求 Promise。
- 相同 URL 的并发请求共享同一个 Promise。
- 请求完成后从 Map 中移除。
第 16 题
为以下 RESTful 接口选择合适的 HTTP 状态码:
- 用户成功登录并返回 Token。
- 用户请求的管理员接口,但当前用户只是普通角色。
- 请求体中手机号格式错误。
- 后端数据库连接失败。
- 客户端在 1 秒内请求了 100 次接口。
查看答案与解析
参考答案:
- 200 OK(或 201 Created,如果认为登录创建了会话资源)。
- 403 Forbidden。
- 400 Bad Request。
- 500 Internal Server Error(不应暴露具体数据库错误)。
- 429 Too Many Requests。
解析:
- 401 是未认证,403 是已认证但无权限。
- 参数校验失败用 400。
- 服务端内部异常用 500 系列。
- 限流用 429。
第 17 题
补全 WebRTC 获取本地摄像头并展示的基本代码。
async function startLocalVideo(videoElement) {
const stream = await navigator.mediaDevices.________({
video: true,
audio: true
});
videoElement.srcObject = stream;
}查看答案与解析
参考答案:
横线处应填入 getUserMedia。
完整代码:
async function startLocalVideo(videoElement) {
const stream = await navigator.mediaDevices.getUserMedia({
video: true,
audio: true
});
videoElement.srcObject = stream;
}解析:
getUserMedia用于获取用户的摄像头和麦克风媒体流。- 需要在 HTTPS 或 localhost 环境下调用。
- 调用前应考虑权限处理和错误捕获。
练习建议
- 使用 Wireshark 或 Chrome Network 面板观察 TCP 握手和 HTTP/2 帧。
- 搭建本地 HTTP/2 或 WebSocket 服务,验证协议行为。
- 分析自己项目的网络请求,找出可优化点(如重复请求、缓存策略)。
- 用 WebRTC 实现一个本地双人视频通话 Demo。
领域编号:F04 网络
最后更新:2026-06-24