CodeRoadMap
首页路线题库资源库文章社区
CodeRoadMap

程序员的学习成长路线图。内容免费开放,登录后可同步路线图与课时进度。

由 程序员柏风 独立维护 · 关于作者

学习

  • 路线图
  • 课程
  • 面试题
  • 文章
  • 我

更多

  • 资源
  • 社区
  • 关于作者
  • 内容说明

© 2026 CodeRoadMap

津ICP备2026012044号-1·津公网安备12011002026155号·coderoadmap@126.com
计算机科学入门/课时/计算机网络
RawBlame
课时目录12 节

计算机科学入门

  1. 01计算机如何工作
  2. 02数据结构
  3. 03算法与搜索排序
  4. 04复杂度分析
  5. 05离散数学基础
  6. 06操作系统概念
  7. 07数据库原理
  8. 08计算机网络
  9. 09系统设计入门
  10. 10安全基础
  11. 11设计模式与 UML
  12. 12综合练习

计算机网络

OSI/TCP-IP、HTTP、DNS、Socket。

35 分钟

计算机网络

这一课你将能做到

  1. 对应 OSI 七层与 TCP/IP 四层模型,说出每一层解决什么问题、有哪些代表协议
  2. 描述 TCP 三次握手、四次挥手与可靠传输的基本机制,区分 TCP 与 UDP
  3. 说清一次 HTTPS 请求从 DNS 解析到 TLS 握手再到 HTTP 响应的完整链路

为什么要学

分布式系统的本质是「通过网络协作的多台计算机」。判题平台里几乎每个动作都在走网络:浏览器用 HTTPS 调后端接口,后端用 JDBC 连 MySQL、用 RESP 协议连 Redis,微服务之间走 HTTP/gRPC,判题结果通过 WebSocket 实时推给用户。

网络知识直接决定排查问题的能力:接口超时是连不上还是对端慢?DNS 偶尔解析失败怎么办?为什么 HTTPS 多一次往返?TIME_WAIT 太多端口耗尽怎么处理?只会 @GetMapping 无法回答这些问题。本课建立分层模型与三个关键协议(TCP、TLS、HTTP)的直觉。

先建立图像

分层模型对照(数据自上而下逐层加「信封」)
OSI 七层            TCP/IP 四层     代表协议/设备        典型问题
7 应用层            应用层          HTTP/HTTPS, DNS     状态码、接口语义
6 表示层                            TLS, JSON, gzip     编码、加密
5 会话层                            WebSocket
4 传输层            传输层          TCP / UDP           端口、可靠/快速
3 网络层            网际层          IP, ICMP            寻址、路由、ping
2 数据链路层        网络接口层      以太网, ARP, MAC    局域网内投递
1 物理层                            网线/光纤/比特流

一次请求的旅程
浏览器
  │ 1.DNS: 域名 → IP(递归查询:缓存→本地DNS→根→顶级→权威)
  │ 2.TCP 三次握手建立连接
  │ 3.TLS 握手:协商算法、交换证书与密钥(非对称加密换出对称密钥)
  │ 4.HTTP 请求/响应(后续都用对称密钥加密)
  ▼
Nginx/负载均衡 ──▶ Spring Boot ──▶ MySQL/Redis

跟着做

步骤 1:亲手观察网络分层与连接

# 从下到上观察
ipconfig / ifconfig          # 看本机 IP、MAC(网络接口层/网际层信息)
ping judge.example.cn        # ICMP:测 IP 层连通性与延迟
nslookup judge.example.cn    # DNS:看域名解析到哪个 IP
tracert judge.example.cn     # Windows / traceroute:看经过哪些路由跳数

# 观察传输层连接(Linux/macOS)
netstat -an | grep ESTABLISHED      # 或 ss -tan:看 TCP 连接状态
curl -v https://judge.example.cn/api/problems   # -v 把 DNS、TCP、TLS、HTTP 全过程打出来

curl -v 是最值得养成的习惯:它依次打印解析到的 IP、TCP 连接建立、TLS 证书校验与加密套件协商、HTTP 请求头和响应状态码。一个命令看完整张分层图。

步骤 2:理解 TCP 三次握手与可靠传输

三次握手(建立连接,确认双方收发能力都正常)
  客户端              服务端
    ── SYN, seq=x ───────▶   我想连,我的序号是 x
    ◀── SYN+ACK, seq=y,
        ack=x+1 ─────────    我收到了,也想连,确认你
    ── ACK, ack=y+1 ────▶   确认你,连接建立
  为什么不是两次?要防止一个迟到的旧连接请求突然到达,
  白白让服务端建立连接并等待资源。

可靠传输四件套
  序号 + 确认ACK:每个字节有序号,没收到确认就重传
  超时重传:       计时器到期未确认 → 重发
  滑动窗口:       批量发送而不是发一个等一个,流量控制
  拥塞控制:       慢启动/拥塞避免,探测网络容量,避免灌爆网络

TCP vs UDP:TCP 面向连接、可靠、有序,代价是握手开销和头部较大(网页、文件、数据库连接都用它);UDP 无连接、不保证可靠但延迟低、头部小(DNS 查询、视频通话、游戏同步、QUIC/HTTP3 在 UDP 上自建可靠性)。判题平台的实时状态推送用 WebSocket(基于 TCP),对延迟敏感的判题心跳可考虑 UDP 但要自己补确认。

步骤 3:用 Java Socket 写一个最小 TCP 通信

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

public class MiniTcp {

    // 判题 Worker:监听端口,收到题目ID后回送「已受理」
    static class JudgeServer {
        public static void main(String[] args) throws Exception {
            try (ServerSocket server = new ServerSocket(9000)) {
                System.out.println("判题机已启动,等待任务...");
                try (Socket socket = server.accept();
                     BufferedReader in = new BufferedReader(
                             new InputStreamReader(socket.getInputStream()));
                     PrintWriter out = new PrintWriter(socket.getOutputStream(), true)) {
                    String problemId = in.readLine();
                    System.out.println("收到判题任务: " + problemId);
                    out.println("ACCEPTED:" + problemId);
                }
            }
        }
    }

    // 调度中心:发起连接并发送任务
    static class Scheduler {
        public static void main(String[] args) throws Exception {
            try (Socket socket = new Socket("localhost", 9000);
                 PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
                 BufferedReader in = new BufferedReader(
                         new InputStreamReader(socket.getInputStream()))) {
                out.println("problem-1024");
                System.out.println("调度中心收到: " + in.readLine());
            }
        }
    }

    public static void main(String[] args) {
        new Thread(() -> {
            try { JudgeServer.main(args); } catch (Exception e) { e.printStackTrace(); }
        }).start();
        Thread.sleep(500);
        Scheduler.main(args);
    }
}

这就是所有网络通信的骨架:IP 定位机器、端口定位进程内的程序、Socket 抽象出字节流。HTTP、JDBC、Redis 协议全部是在这个字节流上约定的「对话格式」。

步骤 4:HTTPS 与 TLS——在不可靠网络上建立可信通道

TLS 握手直觉(混合密码体系:非对称加密负责「安全地交换钥匙」,
之后用对称加密传输数据,因为对称加密快得多)

1. Client Hello:支持的 TLS 版本、加密套件、随机数
2. Server Hello:选定套件 + 随机数 + 数字证书(含公钥,由 CA 签名)
3. 客户端验证证书链与域名合法性,生成 pre-master secret,用服务端公钥加密发出
4. 双方用三个随机数算出会话密钥,互发 Finished 验证
5. 之后 HTTP 数据全部用会话密钥做对称加密 + 完整性校验

要点:证书解决「你连的服务器是不是真的」(信任链锚定到系统内置的根 CA);TLS 同时提供机密性(别人看不懂)和完整性(数据被篡改能发现),还防重放。生产中 Nginx/网关终止 TLS,内部链路可加密或在内网信任域内;证书过期是最常见的线上事故之一,要做到期监控。

讲清楚要点

  1. 分层的意义是分工与解耦:每层只解决一类问题并向上层提供服务;数据包在发送端逐层封装、接收端逐层解封。排查问题时按层定位(先 ping 再 curl),不要跨层乱猜。
  2. IP 负责「送到哪台机器」,端口负责「交给哪个程序」:端口 16 位,HTTP 80、HTTPS 443、MySQL 3306、Redis 6379;NAT 让多台内网机器共享公网 IP。
  3. TCP 的状态机要眼熟:LISTEN → SYN_SENT/RCVD → ESTABLISHED;主动关闭方进入 FIN_WAIT → TIME_WAIT(等待 2MSL,确保最后 ACK 到达和旧报文消亡)。高并发短连接下 TIME_WAIT 堆积会耗尽端口,解法是连接池、长连接、调内核参数。
  4. HTTP 是无状态的请求-响应协议:Cookie/Session、JWT 用来在无状态之上识别用户;常见状态码要会:301/302 重定向、304 协商缓存、400 参数错、401 未认证、403 无权限、404 不存在、429 限流、500 服务端错、502/503/504 网关与超时。
  5. DNS 是网络的电话簿:浏览器/OS 多级缓存 + 递归查询;它基于 UDP(快),响应过大或区域传送用 TCP;DNS 故障表现为「IP 能 ping 通但域名打不开」。

你可能会懵的地方

  • 三次握手第三次握手丢了怎么办? 客户端认为连接已建立并可直接发数据;服务端处于 SYN_RCVD,它会重发 SYN+ACK。客户端若有数据发出,数据报文带 ACK,服务端收到也会转入 ESTABLISHED;若一直没确认,服务端超时后放弃。

  • 为什么挥手要四次而握手三次? 握手时服务端的 SYN 和 ACK 可以合并成一条。挥手时 TCP 全双工,两个方向要分别关闭:收到 FIN 只表示对方没数据发了,但自己可能还有数据要发,所以 ACK 和自己的 FIN 通常分开发,共四次。

  • HTTPS 一定安全吗?中间人能不能攻击? 用户正确校验证书链时,中间人无法伪造可信证书,攻击会被浏览器警告。但如果用户信任了恶意根证书、设备被装了抓包代理、或应用代码关闭了证书校验(信任全部证书),HTTPS 就形同虚设——客户端安全同样重要。

  • HTTP/1.1、HTTP/2、HTTP/3 差在哪? 1.1 长连接复用但仍有队头阻塞(一个请求慢,后面排队);2 改为二进制分帧、多路复用、头部压缩;3 基于 QUIC(UDP),解决 TCP 层队头阻塞、握手更快、连接迁移好。Spring Boot 3 + 现代 Nginx 已可开启 HTTP/2。

  • 连数据库用连接池和网络有什么关系? TCP 三次握手 + 认证有往返成本,频繁建连还会产生 TIME_WAIT 堆积;连接池复用长连接,同时限制数据库连接总数,是「网络成本 + 数据库负载」双方面的优化。

错法对照

错法问题正解
接口不设超时(connect/read timeout)对端挂起时线程被无限拖住两类超时都设,配合重试与熔断
失败就无脑重试三次非幂等操作重复执行、放大故障仅对幂等请求重试 + 指数退避 + 总次数上限
内网调用走公网域名/公网 IP延迟与带宽成本、安全面扩大内网 DNS/VIP/服务发现直接通信
代码里写死 IP 或第三方地址IP 变更即故障域名 + 配置中心;监控 DNS 与证书
高并发用短连接且不监控端口TIME_WAIT 堆积、端口耗尽连接池/长连接,监控连接状态分布

卡点急救

  1. 接口偶发超时:先 ping/curl -v 分段测量——是 DNS 慢、TCP 建连慢、TLS 慢还是响应慢;再看对端负载与网络丢包,不同环节不同解法。
  2. 域名整体打不开:用 nslookup 对比公共 DNS(如 223.5.5.5、8.8.8.8)判断是否解析故障; hosts 被改、权威 DNS、注册过期都可能,逐级排查。
  3. 服务出现大量 502/连接重置:检查后端是否重启、keep-alive 配置是否两端一致、连接池是否把已被对端关闭的连接发给了对方(开启连接有效性检测)。

面试常问

  • 从输入 URL 到页面展示发生了什么?(后端版) DNS 解析得到 IP;TCP 三次握手;TLS 握手交换证书与会话密钥;发送 HTTP 请求,经负载均衡到 Spring Boot;服务查缓存/数据库返回响应;浏览器渲染。能再深入讲 ARP、路由、NAT、CDN 是加分项。

  • TCP 如何保证可靠传输? 字节序号与确认应答、超时重传、滑动窗口做流量控制、拥塞控制(慢启动、拥塞避免、快重传快恢复)、校验和与去重。可靠性是这些机制叠加的结果。

  • TLS 握手为什么要用非对称加密?为什么之后又改用对称加密? 非对称加密解决在不安全信道上安全协商密钥的问题(公钥可公开、私钥解密),但计算昂贵;对称加密速度快,适合大批量数据。TLS 用前者安全换钥匙、用后者高效传内容,是混合密码体系的标准设计。

自测三问

  1. 不看资料默画 OSI/TCP-IP 对照表,并各层写一个协议或排查命令。
  2. 解释 TIME_WAIT 为什么存在、什么情况下会出问题、至少两种缓解手段。
  3. 判题平台从 HTTP 升级到 HTTPS,链路上哪些组件要改?证书过期前如何发现?

小结一句话

网络靠分层把「比特投递、机器寻址、进程通信、加密信任、应用语义」逐级解决——TCP 让字节流可靠有序,TLS 让它机密可信,HTTP 让它有业务含义,理解分层就掌握了排查分布式故障的路线图。

延伸

  • 《计算机网络:自顶向下方法》配套资源(Kurose & Ross)——网络入门权威教材,自顶向下契合后端视角
  • MDN:HTTPS 与 TLS 工作原理——TLS 机制的权威通俗讲解
  • RFC 9110:HTTP 语义(IETF 官方规范)
  • 下一课:系统设计入门——单机、单库、单网络链路都清楚之后,学习把多个组件组合成可扩展的系统:容量估算、负载均衡与缓存。
加载本节练习…
← 上一课数据库原理下一课 →系统设计入门