网络与操作系统核心知识体系
10年高级开发必备
目录
- 一、计算机网络基础
- 二、网络协议详解
- 三、网络编程与IO模型
- 四、网络安全
- 五、操作系统核心
- 六、进程与线程
- 七、内存管理
- 八、文件系统
- 九、系统性能优化
- 十、虚拟化与容器
- 十一、系统监控与调试
- 十二、高可用与负载均衡
一、计算机网络基础
1.1 OSI七层模型与TCP/IP五层模型
- 物理层:比特流传输、介质类型(双绞线、光纤、无线)、信号编码、调制解调
- 数据链路层:MAC地址、以太网帧结构、ARP/RARP、PPP、VLAN、MTU、MSS
- 网络层:IP协议(IPv4/IPv6)、ICMP、路由算法(RIP、OSPF、BGP)、子网划分、NAT
- 传输层:TCP、UDP、端口、连接管理、流量控制、拥塞控制
- 应用层:HTTP/HTTPS、DNS、FTP、SMTP、POP3、IMAP、SSH、Telnet
对比理解:
- TCP/IP是事实标准,OSI是理论模型
- 对应关系:应用层→应用层+表示层+会话层,传输层→传输层,网络层→网络层,网络接口层→数据链路层+物理层
1.2 IP协议
- IPv4
- 报文结构(版本、首部长度、TOS、总长度、标识、标志、片偏移、TTL、协议、首部校验和、源/目的IP)
- 分类(A/B/C/D/E)、子网划分(子网掩码、CIDR表示法)
- 私有IP范围(10.0.0.0/8、172.16.0.0/12、192.168.0.0/16)
- 广播地址、网络地址、回环地址(127.0.0.1)
- IPv6
- 128位地址、冒分十六进制
- 地址类型(单播、多播、任播)
- 与IPv4过渡技术(双栈、隧道、翻译)
- 报文结构简化、扩展头
- 子网掩码:计算网络地址、广播地址、可用IP范围
- 路由选择:路由表、路由协议、默认路由、静态路由、动态路由
- ICMP:Ping(回显请求/应答)、Traceroute(TTL超时)、目的不可达、源抑制
1.3 MAC地址与以太网
- MAC地址格式(48位,OUI + NIC特定)
- 以太网帧结构:前导码、目的MAC、源MAC、类型/长度、数据、FCS
- 交换机工作原理:MAC地址表学习、转发、泛洪
- VLAN(802.1Q):标签、Trunk、Access、Native VLAN
- STP(生成树协议):防止环路、BPDU、根桥选举
- ARP协议:IP到MAC映射、ARP缓存、ARP欺骗与防御
1.4 路由与交换机基础
- 路由器:三层设备、路由表、路由协议
- 三层交换机:二层交换+三层路由
- 二层交换机:MAC地址表、VLAN划分、生成树
- 路由算法
- 距离向量(RIP):跳数、无穷大、水平分割、毒性逆转
- 链路状态(OSPF):LSA、Dijkstra算法、区域划分
- 路径向量(BGP):AS、路径属性、路由策略
- 路由器负载均衡:等价多路径(ECMP)、不等价多路径
二、网络协议详解
2.1 TCP协议
2.1.1 TCP报文结构
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Source Port | Destination Port |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Sequence Number |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Acknowledgment Number |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Data | |U|A|P|R|S|F| |
| Offset| Reserved |R|C|S|S|Y|I| Window |
| | |G|K|H|T|N|N| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Checksum | Urgent Pointer |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Options |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| data |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2.1.2 TCP三次握手
Client Server
| -- SYN=1, seq=x ---------> |
| <-- SYN=1, ACK=1, |
| seq=y, ack=x+1 ------- |
| -- ACK=1, ack=y+1 ------> |
为什么是三次? 防止失效的连接请求导致错误,确保双方收发能力正常。
2.1.3 TCP四次挥手
主动关闭方 被动关闭方
| -- FIN=1, seq=u --------> |
| <-- ACK=1, ack=u+1 ------- |
| <-- FIN=1, ACK=1, |
| seq=v, ack=u+1 ------ |
| -- ACK=1, ack=v+1 ------> |
TIME_WAIT作用:
- 确保最后一个ACK到达对方(对方没收到会重传FIN)
- 等待足够时间让旧连接所有报文在网络中消失(2MSL)
2.1.4 TCP状态机
CLOSED → LISTEN → SYN_RCVD → ESTABLISHED → FIN_WAIT1 → FIN_WAIT2
↖_________↩ ↖______↩
SYN_SENT TIME_WAIT ← CLOSE_WAIT → LAST_ACK → CLOSED
2.1.5 TCP可靠性机制
- 序列号与确认号:字节流编号、累计确认
- 超时重传:RTT估计、RTO计算(Jacobson算法)
- 快速重传:3个重复ACK
- 选择性确认(SACK):告知哪些数据已收到,哪些丢失
- 流量控制:接收窗口(rwnd)限制发送速率
- 拥塞控制
- 慢启动(Slow Start):指数增长(每RTT×2)→ 阈值ssthresh
- 拥塞避免(Congestion Avoidance):线性增长(每RTT+1)
- 拥塞发生:3个重复ACK → 快速恢复(Fast Recovery);超时 → 慢启动
- 慢启动阈值(ssthresh)更新:超时设为当前窗口一半,快速重传设为 congestion window / 2
- 现代实现:CUBIC(Linux默认)、BBR(Google)
2.1.6 TCP粘包与拆包
- 问题原因:TCP是流协议,无消息边界
- 解决方案
- 固定长度
- 使用分隔符(换行符、特殊字符)
- 长度字段+数据(Length-field protocol)
- HTTP Content-Length/Transfer-Encoding: chunked
2.1.7 TCP优化
- Nagle算法:减少小包,合并发送(要求等待ACK或缓冲区满)
- 关闭:
TCP_NODELAYsocket选项
- 关闭:
- 延迟确认(Delayed ACK):等待更多数据或200ms
- 关闭:
TCP_QUICKACK
- 关闭:
- keep-alive:长连接保活
- 窗口缩放(Window Scaling):支持大于64K窗口
- 时间戳(Timestamp):RTT计算更准确、防止序列号回绕
2.2 UDP协议
- 无连接、不可靠、无顺序、无流量控制
- 应用场景:DNS、VoIP、视频流、游戏、广播/多播
- UDP报文结构:源端口、目的端口、长度、校验和、数据
- UDP校验和:伪头部+UDP头部+数据(可选)
2.3 HTTP/HTTPS协议
2.3.1 HTTP/1.1
- 请求格式:方法(GET/POST/PUT/DELETE/HEAD/OPTIONS/TRACE/CONNECT)、URI、版本、头部、实体
- 常见头部:
- 请求:Host、User-Agent、Accept、Accept-Encoding、Connection(keep-alive/close)、Cookie
- 响应:Status Code、Content-Type、Content-Length、Cache-Control、Expires、ETag、Set-Cookie
- 状态码:1xx(信息)、2xx(成功)、3xx(重定向)、4xx(客户端错误)、5xx(服务器错误)
- keep-alive:长连接,减少握手开销
- 管道化(Pipelining):请求可连续发送,但响应必须顺序返回(实际很少用)
- 问题:队头阻塞(HOL blocking)、冗余头部、不能复用
2.3.2 HTTP/2
- 二进制协议、分帧传输(HEADERS帧、DATA帧)
- 多路复用:单连接并行多个请求,解决HOL阻塞
- 头部压缩:HPACK算法(静态表、动态表、Huffman编码)
- 服务器推送(Server Push):主动推送资源到客户端
- 流优先级:客户端指定流优先级
- 流量控制:每个流独立窗口
- 连接特性:一个TCP连接,多个Stream,每个Stream有ID
2.3.3 HTTP/3(基于QUIC)
- 基于UDP,避免队头阻塞(传输层、应用层)
- 0-RTT/1-RTT握手,减少延迟
- 连接迁移:通过Connection ID,IP变化不影响连接
- 内置TLS 1.3
- 前向纠错(FEC)
2.3.4 HTTPS
- TLS握手过程:
- Client Hello(支持的密码套件、TLS版本、随机数)
- Server Hello(选择密码套件、TLS版本、随机数)、证书、Server Hello Done
- Client验证证书,生成Pre-master,用Server公钥加密发送
- 双方计算Master Secret → 会话密钥
- Change Cipher Spec,Finished消息
- 对称加密(AES、ChaCha20) vs 非对称加密(RSA、ECDHE)
- 数字证书:X.509格式、CA签发、证书链、CRL/OCSP吊销检查
- 中间人攻击(MITM)防护:证书验证、HSTS(HTTP Strict Transport Security)
- TLS 1.3改进:1-RTT、移除不安全算法、前向保密(PFS)
2.3.5 RESTful API设计
- 资源导向、URI设计规范
- HTTP方法语义(GET获取、POST创建、PUT全量更新、PATCH部分更新、DELETE删除)
- 状态码正确使用
- HATEOAS(超媒体驱动)
- OpenAPI 3.0规范(Swagger)
2.4 DNS协议
- 层次结构:根域 → 顶级域(.com/.org/.cn) → 二级域 → 子域
- 记录类型:
- A(IPv4)、AAAA(IPv6)
- CNAME(别名)
- MX(邮件服务器)
- NS(域名服务器)
- TXT、SRV
- 查询方式:递归查询、迭代查询
- DNS解析流程:本地hosts → 本地DNS缓存 → 系统配置DNS服务器 → 递归或迭代查询
- DNS负载均衡:轮询返回多个IP
- DNS缓存:TTL控制
- DNS安全:DNSSEC(域名系统安全扩展)、DNS劫持、DNS污染
2.5 CDN
- 原理:边缘节点缓存、就近访问、DNS重定向
- 架构:源站、CDN节点、用户、DNS
- 缓存策略:缓存键、过期时间、回源
- 动态加速:路由优化、协议优化
- HTTPS支持:边缘证书、OCSP Stapling
- 常用服务商:Cloudflare、Akamai、Fastly、阿里云CDN、腾讯云CDN
2.6 WebSocket
- 握手:HTTP Upgrade头,Upgrade: websocket,Connection: Upgrade
- 帧结构:FIN、RSV、Opcode(文本/二进制/关闭/心跳)、MASK、Payload
- 心跳机制:Ping/Pong帧
- 优点:全双工、低延迟、无HTTP头部冗余
- 适用场景:实时聊天、在线游戏、股票行情
2.7 WebRTC
- 点对点(P2P)实时通信
- 信令服务器(SDP交换)
- NAT穿透:STUN(Session Traversal Utilities for NAT)、TURN(Traversal Using Relays around NAT)
- ICE(Interactive Connectivity Establishment)
- 媒体流:音频、视频、数据通道
- 数据通道:SCTP over DTLS
2.8 网络地址转换(NAT)
- 类型:
- 静态NAT:一对一固定映射
- 动态NAT:多对多,从池中选择
- NAPT(PAT):多对一,使用端口号区分
- 工作原理:修改IP头部的源/目的IP和端口
- 问题:无法端到端通信,需NAT穿透技术
- NAT穿透:UPnP、ALG(应用层网关)、STUN/TURN
三、网络编程与IO模型
3.1 Socket编程
- socket() 系统调用:指定协议族(AF_INET/AF_INET6/AF_UNIX)、类型(SOCK_STREAM/SOCK_DGRAM)、协议
- bind():绑定IP和端口(通配符0.0.0.0)
- listen():监听连接(backlog队列长度)
- accept():接受连接,返回新socket描述符
- connect():客户端建立连接
- send()/recv() 或 write()/read()
- close():关闭连接(TIME_WAIT)
- setsockopt():设置socket选项(SO_REUSEADDR、SO_KEEPALIVE、TCP_NODELAY等)
- getsockopt():获取socket选项
服务端典型流程:
sockfd = socket(AF_INET, SOCK_STREAM, 0);
bind(sockfd, (struct sockaddr*)&addr, sizeof(addr));
listen(sockfd, backlog);
while(1) {
connfd = accept(sockfd, ...);
// 处理(fork线程或线程池)
}
客户端典型流程:
sockfd = socket(AF_INET, SOCK_STREAM, 0);
connect(sockfd, (struct sockaddr*)&addr, sizeof(addr));
send/recv
close(sockfd);
3.2 IO模型(5种)
- 阻塞IO(Blocking IO):调用 blocking,数据就绪前进程挂起
- 非阻塞IO(Non-blocking IO):返回EWOULDBLOCK,应用程序轮询
- IO多路复用(IO Multiplexing):
- select:bitmap限制(fd_set通常1024)、O(n)扫描、每次复制fd集合到内核
- poll:链表,fd无限制,但仍O(n)
- epoll(Linux):红黑树O(1)查找、事件驱动(ET/LT)、mmap共享内存
- kqueue(BSD/Mac):类似epoll
- 信号驱动IO(Signal-driven IO):通过SIGIO信号通知
- 异步IO(Asynchronous IO):kernel完成整个IO后通知(POSIX aio_*、Linux io_submit)
对比:
- 前4种(阻塞、非阻塞、多路复用、信号驱动)都是同步IO,数据拷贝由应用程序完成
- 第5种是异步IO,kernel完成数据拷贝后通知
3.3 Java NIO
- Buffer:HeapBuffer、DirectBuffer(堆外内存,避免一次拷贝)、flip()、clear()、compact()
- Channel:FileChannel、SocketChannel、ServerSocketChannel、DatagramChannel
- Selector:多路复用器、interestOps、selectedKeys、SelectionKey(OP_ACCEPT/OP_CONNECT/OP_READ/OP_WRITE)
- 非阻塞模式:channel.configureBlocking(false)
- 内存映射文件:MappedByteBuffer(mmap)
- 零拷贝:FileChannel.transferTo/transferFrom(sendfile系统调用)
Reactor模式:
- 单Reactor单线程:Acceptor + Handler
- 单Reactor多线程:Acceptor + Dispatcher(线程池)
- 主从Reactor多线程:MainReactor(Acceptor)+ SubReactors(读写处理)- Netty架构
3.4 Netty核心
- 组件:
Bootstrap/ServerBootstrapChannel(NioSocketChannel、NioServerSocketChannel)ChannelPipeline(双向链表,ChannelHandler)ChannelHandlerContextEventLoop(I/O线程,Reactor线程,通常线程数=CPU核心数×2)EventLoopGroup(一组EventLoop,parentGroup + childGroup)ChannelFuture(异步操作结果)
- 线程模型:
- Reactor模型(主从Reactor)
- 每个Channel绑定一个EventLoop(线程亲和)
- TaskQueue(用户任务排队,避免阻塞EventLoop)
- 编解码器:
ByteToMessageDecoder/MessageToByteEncoderLengthFieldBasedFrameDecoder(拆包)StringEncoder/StringDecoder- 自定义Codec
- Handler:
ChannelInboundHandlerAdapter(入站)ChannelOutboundHandlerAdapter(出站)SimpleChannelInboundHandler<I>(自动释放)
- 内存管理:
ByteBuf(抽象缓冲,引用计数,Pooled/Unpooled)PooledByteBufAllocator(池化,减少GC)CompositeByteBuf(组合缓冲,零拷贝)Slice、Duplicate
- 调试工具:
ResourceLeakDetector(内存泄露检测)
3.5 零拷贝(Zero-copy)
- 含义:数据不经过用户空间,直接在kernel空间移动
- 传统IO:
磁盘 → kernel buffer → user buffer → kernel socket buffer → 网卡- 2次上下文切换、2次数据拷贝(DMA to kernel、CPU to user,再DMA from kernel)
- 零拷贝(mmap + write / sendfile / splice)
磁盘 → kernel buffer → 网卡:1次DMA拷贝,无CPU拷贝sendfile():文件描述符直接到socket,减少一次用户空间拷贝
- Java实现:
FileChannel.transferTo()、transferFrom() - 适用场景:文件传输、大文件、高并发静态资源服务器
3.6 高并发网络编程要点
- Reactor vs Proactor:
- Reactor:同步IO,事件就绪后应用程序自己读取(epoll_wait后recv)
- Proactor:异步IO,kernel完成读取后通知(Windows IOCP、Linux AIO)
- 事件循环阻塞:避免在EventLoop执行阻塞操作(DB查询、RPC调用),丢到线程池
- 背压(Backpressure):处理速度慢于生产速度,需要流量控制(TCP窗口、应用层队列)
- 连接管理:连接数、文件描述符限制(ulimit -n)、SO_BACKLOG、SO_REUSEADDR
- 超时设置:SO_TIMEOUT(读超时)、TCP keep-alive、应用层心跳
- Epoll ET vs LT:
- LT(水平触发):缓冲区有数据一直通知,可阻塞读
- ET(边沿触发):状态变化只通知一次,需非阻塞读直到EAGAIN
- Thundering Herd(惊群):多个进程监听同一socket,connect到来唤醒所有,现代kernel已优化
四、网络安全
4.1 常见攻击与防御
- DDoS:
- SYN Flood:耗尽连接队列,防御:SYN Cookie、增大backlog、减少SYN_RCVD时间
- UDP Flood、ICMP Flood
- HTTP Flood(应用层)
-防御:流量清洗、CDN、负载均衡、限流
- MITM(中间人攻击):
- ARP欺骗、DNS劫持、SSL stripping
- 防御:HTTPS、证书锁定(Certificate Pinning)、HSTS
- XSS(跨站脚本):
- 存储型、反射型、DOM型
- 防御:输入过滤、输出编码(HTML实体编码)、CSP、HttpOnly Cookie
- CSRF(跨站请求伪造):
- 防御:Token、SameSite Cookie、双重验证、Referer检查
- SQL注入:
- 防御:参数化查询(PreparedStatement)、存储过程、ORM、最小权限
- 文件上传漏洞:
- 文件类型检查(MIME、后缀、magic number)、重命名、限制大小、防恶意代码、单独存储、权限控制
- 命令注入:
- 输入过滤、白名单、最小权限、沙箱
- 路径遍历:…/ 遍历,防御:规范化路径、限制目录
4.2 TLS/SSL
- 握手过程(TLS 1.2):
- Client Hello(支持的加密套件、随机数)
- Server Hello、证书、Server Hello Done
- 验证证书,Pre-master用公钥加密
- 计算会话密钥
- Change Cipher Spec,Finished
- 密钥交换:
- RSA:客户端用服务器公钥加密pre-master
- ECDHE:DH密钥交换,前向保密
- 对称加密:AES(CBC/CTR/GCM)、ChaCha20
- 完整性:HMAC、AEAD(AES-GCM、ChaCha20-Poly1305)
- 证书验证:CA链、有效期、域名匹配、CRL/OCSP
- TLS 1.3:1-RTT,仅支持AEAD、移除不安全的算法、支持0-RTT
4.3 WAF(Web应用防火墙)
- 规则检测:正则表达式、语义分析
- 防护能力:SQL注入、XSS、CSRF、文件包含、命令注入等
- 部署方式:反向代理、云WAF、主机WAF
- 误报/漏报问题
4.4 DDoS防护
- 流量清洗:识别异常流量,丢弃恶意包
- 限流:令牌桶、漏桶、计数器(滑动窗口)
- 负载均衡:分散流量,自动扩容
- Anycast:多个数据中心 advertise 相同IP,就近路由
- 黑洞路由:将攻击流量路由到null接口
五、操作系统核心
5.1 OS四大基本功能
- 进程管理:调度、同步、通信、死锁
- 内存管理:虚拟内存、分页、分段、页面置换
- 文件系统:目录结构、文件操作、磁盘调度
- 设备管理:I/O调度、缓冲区、设备驱动
5.2 系统调用(System Call)
- 进程控制:fork()、exec()、wait()、exit()
- 文件操作:open()、read()、write()、close()、lseek()
- 设备控制:ioctl()
- 信息维护:getpid()、getuid()、time()
- 通信:pipe()、shmget()、msgget()、semget()
- Linux系统调用架构:用户空间 → glibc → syscall → kernel
5.3 内核空间 vs 用户空间
- 保护环:Ring 0(内核)、Ring 3(用户)
- 上下文切换:用户态 ↔ 内核态(系统调用、中断、异常)
- 切换开销:保存/恢复寄存器、TLB flush、缓存失效
六、进程与线程
6.1 进程
- 定义:资源分配单位(虚拟地址空间、文件描述符、信号处理等)
- 进程状态:新建、就绪、运行、阻塞(等待事件)、就绪/阻塞、终止
- PCB(进程控制块):pid、状态、优先级、程序计数器、内存指针、I/O状态等
- 进程创建:
- fork():子进程完全复制父进程(写时复制Copy-on-Write)
- vfork():子进程共享父进程地址空间(直到exec),更轻量
- clone():Linux特有,可控制共享哪些资源(namespace、cgroups等)
- 进程终止:正常(exit()、return main)、异常(信号)、被其他进程杀死(kill)
- 孤儿进程:父进程先终止,init(PID=1)领养
- 僵尸进程:子进程终止,PCB未释放,父进程未wait,危害:占用进程号、PCB表项
- 守护进程(Daemon):无控制终端,后台运行,创建步骤:fork父进程退出→setsid→chdir(‘/’)→umask(0)→关闭文件描述符
6.2 线程
- 定义:CPU调度单位,同一进程共享地址空间、文件描述符、信号处理等
- 优点:创建切换开销小、通信简单(共享内存)
- 缺点:同步复杂、一个线程崩溃影响整个进程
- 线程实现:
- 用户级线程(User Thread):库管理,对kernel透明,协程本质
- 内核级线程(Kernel Thread):kernel调度,1:1模型(Linux pthreads)
- 混合模型:M:N(早期Solaris,复杂)
- 线程创建:pthread_create()(POSIX)、_beginthreadex()(Windows)、Java Thread / ExecutorService
- 线程状态:新建、就绪、运行、阻塞(等待锁、IO、sleep、join)、终止
- 线程属性:分离状态(detached)、栈大小、调度策略/优先级
6.3 进程/线程间通信(IPC)
6.3.1 进程间通信
- 管道(Pipe):
- 匿名管道:
pipe(),父子进程,单向,内核缓冲区(通常4KB-64KB),PIPE_BUF原子性 - 命名管道(FIFO):有路径,无关进程,
mkfifo()
- 匿名管道:
- 消息队列(Message Queue):
- 内核维护,面向消息,可指定消息类型,允许随机读取
- POSIX(mq_open, mq_send, mq_receive)& System V(msgget, msgsnd, msgrcv)
- 共享内存(Shared Memory):
- 最快,多个进程映射同一物理内存
- 需配合信号量同步
- System V(shmget, shmat, shmdt)& POSIX(shm_open, mmap)
- 信号量(Semaphore):
- 计数器,P/V操作(wait/signal),用于同步互斥
- System V(semget, semop)& POSIX(sem_init, sem_wait, sem_post)
- 信号(Signal):
- 异步通知机制(kill、 alarm、除零、非法内存等)
- 信号处理(signal、sigaction,SA_RESTART)
- 信号集(sigset_t)、信号掩码(sigprocmask)
- 可靠信号(实时信号)vs 不可靠信号(标准信号)
- 套接字(Socket):网络通信,也可本地(AF_UNIX)
- 内存映射文件(mmap):文件映射到内存,多进程共享
6.3.2 线程间通信
- 共享全局变量(需同步)
- 条件变量(Condition Variable):wait/signal/broadcast,配合mutex
- 读写锁(Read-Write Lock):允许多读,写独占
- 自旋锁(Spinlock):忙等待,短临界区,避免上下文切换
- 屏障(Barrier):多个线程等待到某点再继续
- 信号量(Semaphore):同上
6.4 调度算法
- 批处理系统:
- FCFS/FIFO: convoy effect(长作业阻塞短作业)
- SJF/SRTF(最短作业优先):可抢占,需要预知运行时间
- 最短剩余时间优先(SRTF):SJF的抢占版本
- 交互式系统:
- 时间片轮转(RR):公平,上下文切换开销
- 多级反馈队列(MLFQ):多级队列,时间片递增,I/O提升优先级
- 最短进程优先(SPN):需预估
- 比例份额(Fair-share):按历史占用CPU比例分配
- 实时系统:
- 最早截止时间优先(EDF):动态优先级,deadline越早优先级越高
- 速率单调调度(RMS):静态优先级,周期越短优先级越高
- Linux CFS(完全公平调度器):
- 虚拟运行时间(vruntime):
vruntime += runtime * (NICE_0_LOAD / load) - 红黑树选择vruntime最小的任务
- nice值影响权重(-20到19,0为默认)
- 虚拟运行时间(vruntime):
- Linux实时调度:
- SCHED_FIFO:先进先出,同优先级抢占,被高抢占或阻塞
- SCHED_RR:时间片轮转
6.5 同步与互斥
- 临界区、竞态条件
- ** Peterson算法 **(软件方法,仅两个进程)
- 测试且设置指令(TS)、交换指令(XCHG)等硬件原子操作
- 互斥锁(Mutex):
- 加锁/解锁,可递归(递归锁)
- 所有权(哪个线程加的锁应由该线程释放)
- 条件等待:pthread_cond_wait(原子释放锁并睡眠,被唤醒后重新获取锁)
- 读写锁:读共享、写互斥,适合读多写少
- 自旋锁:忙等,临界区短、多核CPU、不能睡眠
- RCU(Read-Copy-Update):Linux内核,读无锁,写时复制旧数据,更新指针,等待readers完成
- 无锁编程:CAS(Compare-And-Swap)、原子操作(atomic_int)
- ABA问题:版本号(版本戳)或指针标记
- 循环CAS直到成功
- 内存屏障(Memory Barrier):防止编译器/CPU重排序(acquire/release/full barrier)
6.6 死锁
- 必要条件(Coffman条件):
- 互斥:资源一次只能一个占用
- 占有并等待:持有资源同时等待其他
- 不可抢占:只能自愿释放
- 循环等待:A→B→C→A形成环路
- 死锁预防:破坏任一条件(难以全部破坏)
- 一次申请所有资源(破坏占有并等待)
- 资源有序分配(破坏循环等待)
- 死锁避免:银行家算法(需要知道最大需求,不实用)
- 死锁检测与恢复:
- 资源分配图简化法(系统周期性检测)
- 恢复:终止进程(全部/逐个)、资源剥夺
- 死锁忽略:大多数OS选择忽略,靠应用设计避免
七、内存管理
7.1 虚拟内存
- 目的:每个进程有独立地址空间,隔离、简化编程、大于物理内存
- 地址翻译:虚拟地址 → 物理地址(页表)
- 分页:
- 固定大小页(通常4KB)
- 页表项(PTE):有效位、保护位、修改位、访问位、页框号
- 多级页表(减少内存占用,TLB miss增加内存访问)
- 反向页表(按物理地址组织,哈希查找)
- 页表缓存(TLB):
- 翻译后备缓冲器,硬件实现,快速查找
- TLB命中:快,TLB未命中:查页表(TLB miss处理,可能上下文切换)
- ASID(地址空间标识符):区分不同进程的TLB条目
- TLB无效化:mttc指令
7.2 页面置换算法
- 目标:最小化缺页率(page fault rate)
- 算法:
- FIFO:Belady异常(增加页框反而缺页率上升)
- OPT(最优):理论,无法实现(需要预知未来)
- LRU(最近最少使用):近似OPT,需维护访问历史(计数器或栈)
- LRU近似:二次机会算法(Second Chance,环形扫描,引用位置0才替换)、时钟算法(Clock)
- LFU(最不经常使用)
- MFU(最经常使用):不太合理
- 工作集模型(Working Set):最近Δ时间的访问页面集合,基于局部性
- 页面缓冲算法(PBA):保留最近释放页,可能重用
- Linux:LRU链表(active、inactive),但实现复杂(考虑脏页、文件页/匿名页)
- 抖动(Thrashing):频繁缺页,大部分时间花在换页上,主要原因:CPU利用率高但吞吐低,缺页率高,解决方案:减少并发进程数、增加物理内存
7.3 分段
- 按逻辑分段:代码段、数据段、堆、栈等
- 段表:段基址、段界限、保护位
- 问题:外部碎片,不具备扩展性
- 段页式:先分段,每段内分页
7.4 段页式内存管理
- 虚拟地址:段号 + 段内页号 + 页内偏移
- 先查段表得页表基址,再查页表得物理页框,拼接偏移
- 两次内存访问(段表+页表),需TLB优化
7.5 内存分配(用户空间)
- malloc/free(C)、new/delete(C++)、new(Java)
- 分配策略:
- 首次适应(First Fit)
- 最佳适应(Best Fit)
- 最坏适应(Worst Fit)
- 快速适应(Quick Fit):维护不同大小的空闲链表
- 碎片问题:外部碎片(分段)、内部碎片(分页/分配单元)
- 伙伴系统(Linux内核):2的幂次大小,合并相邻块
- Slab分配器:针对频繁分配/释放的小对象(内核对象)
八、文件系统
8.1 文件系统基础
- 文件属性:inode(索引节点)、权限(rwx)、所有者、时间戳(atime、mtime、ctime)、大小
- 目录结构:
- 目录项(dentry):文件名 → inode号映射
- inode:文件元数据 + 数据块指针(直接、间接、双重间接、三重间接)
- 文件描述符(File Descriptor):进程打开文件表项 → 文件表(inode、偏移、访问模式)→ inode表
- 虚拟文件系统(VFS):抽象层,统一接口(open、read、write等),底层支持ext2/3/4、NTFS、FAT、NFS等
- 开销:磁盘I/O慢(ms级),内存缓存(Page Cache、Buffer Cache)
8.2 磁盘调度算法
- 目标:减少磁头移动(寻道时间)
- 算法:
- FCFS:先来先服务
- SSTF:最短寻道时间优先,可能导致饥饿(边缘磁道请求等待)
- SCAN(电梯):向一个方向扫描,依次服务,到达尽头反向
- C-SCAN:循环扫描,只在一个方向服务,到达尽头快速返回(均匀等待时间)
- LOOK:SCAN优化,不一定到尽头,到最远请求就反向
- C-LOOK:C-SCAN优化
- N-Step SCAN:分N个队列,每个队列SCAN,减少跨磁道
- FSCAN:双窗口,一个请求到达时,只扫描当前窗口
8.3 数据一致性
- 写时复制(Copy-on-Write):fork()后进程地址空间只读,写时复制新页
- 日志文件系统(Journaling):ext3、ext4、NTFS,先写日志,再写数据,崩溃恢复
- 写屏障(Write Barrier):保证写顺序(先数据后元数据,或日志先于数据)
- fsync()/fdatasync():强制刷盘
- O_SYNC/O_DSYNC:同步写
- 缓存一致性:Page Cache与磁盘数据一致性问题(写回策略:立即写、延迟写)
8.4 Linux文件系统
- ext2:传统,无日志
- ext3:日志外置(.journal文件),3种日志模式:writeback(只有元数据日志)、ordered(默认,数据先于元数据写)、journal(完整日志)
- ext4:
- 大文件支持(16TB)
- Extents(连续块范围,减少间接块)
- 延迟分配(delayed allocation)
- 日志校验和、多块分配、快速fsck
- XFS:高性能,大文件,分配组(allocation group)
- Btrfs:写时复制(CoW)、快照、RAID、压缩、校验和
- ZFS:类似Btrfs,功能强大,内存消耗大
九、系统性能优化
9.1 性能指标
- 吞吐量:单位时间完成请求数(QPS、TPS)
- 响应时间:平均、P50/P90/P95/P99
- 并发数:同时处理的请求/连接数
- 利用率:CPU、内存、磁盘、网络使用率
- 饱和度:系统过载程度(队列长度)
9.2 性能瓶颈分析
- CPU瓶颈:高CPU使用率、上下文切换频繁、可运行队列长(vmstat的r)
- 工具:top、pidstat、perf、strace
- 内存瓶颈:OOM、频繁交换(swap in/out)、内存泄漏
- 工具:free、vmstat(si/so)、smem、pmap、jmap(Java)、valgrind
- I/O瓶颈:高await、svctm(iostat),iowait高(top)
- 工具:iostat、iotop、blktrace、pidstat -d
- 网络瓶颈:带宽使用、丢包、重传、连接数限制
- 工具:netstat、ss、nethogs、iftop、tcpdump、Wireshark
9.3 性能工具
- 系统层面:
top/htop:CPU、内存、负载vmstat:虚拟内存统计(procs、memory、swap、io、cpu)mpstat:多核CPU使用率(%usr、%sys、%idle、%iowait)iostat:磁盘I/O(%util、await、svctm、tps)netstat/ss:网络连接、端口监听(ss更快)sar:系统活动报告,历史数据perf:性能剖析(CPU周期、缓存丢失、分支预测)strace/dtrace:系统调用跟踪tcpdump/Wireshark:网络包分析
- 进程层面:
ps:进程状态pstree:进程树lsof:打开文件、网络连接pidstat:进程CPU、内存、I/O统计pmap:进程内存映射
- 内存:
free:内存总量、used、free、buff/cache、swapslabtop:内核slab分配器统计
- Java应用:
jps、jstat(GC统计)、jstack(线程Dump)、jmap(堆Dump)、jinfo(参数)jcmd:多功能arthas:在线诊断visualvm、jprofiler、yourkit:GUI工具GC日志分析:-XX:+PrintGCDetails、-XX:+PrintGCDateStamps、GCeasy
9.4 性能优化方向
- CPU:
- 减少上下文切换:减少线程数、使用用户态线程(协程)、锁优化
- 减少缓存失效:数据局部性、减少分支预测失败
- 利用多核:并行化、无锁数据结构、线程池调优(核心数×2)
- 内存:
- 减少对象分配(对象池、重用)、选择合适数据结构(基本类型优于包装类)
- 避免内存泄漏、及时释放
- 调优JVM堆大小、GC选择
- I/O:
- 异步非阻塞(NIO、AIO)
- 缓存(Page Cache、应用缓存)
- 零拷贝(mmap、sendfile)
- 合并小请求
- 使用SSD、RAID优化
- 网络:
- 长连接、连接池
- 压缩(gzip)
- 缓存CDN、HTTP/2、TLS会话复用
- 调优内核参数(tcp_tw_reuse、tcp_fin_timeout、somaxconn)
9.5 操作系统调优
- 文件描述符限制:ulimit -n、系统fs.file-max
- 网络参数(/proc/sys/net/ipv4/):
- tcp_max_syn_backlog:SYN队列长度
- tcp_syn_retries:SYN重试次数
- tcp_fin_timeout:FIN_WAIT2超时
- tcp_tw_reuse / tcp_tw_recycle:TIME_WAIT重用/快速回收(注意NAT环境问题)
- tcp_keepalive_time / probes / interval:keep-alive参数
- net.ipv4.tcp_mem:TCP内存边界
- 内存参数:
- vm.swappiness:交换倾向(0-100,0尽量不用swap)
- vm.dirty_ratio / dirty_background_ratio:脏页比例触发回写
- overcommit_memory:内存分配策略(0检查、1允许、2严格)
- 进程调度:
- nice值(-20最高,19最低)
- 实时策略(SCHED_FIFO、SCHED_RR)
十、虚拟化与容器
10.1 虚拟化
- 全虚拟化:VMware ESXi、KVM、Xen(HVM),硬件完全虚拟化,无需修改Guest OS
- 半虚拟化:Xen(PV),Guest OS修改,性能更好
- 硬件辅助虚拟化:Intel VT-x、AMD-V
- Paravirtualization Drivers:virtio(磁盘/网络virtio-blk/virtio-net),高效
- 内存虚拟化:
- Shadow Page Table(影子页表):维护两组页表,开销大
- EPT(Intel Extended Page Tables)/ NPT(AMD Nested Page Tables):硬件支持,高效地址翻译
- I/O虚拟化:
- 设备模拟(Device Emulation,qemu-kvm模拟网卡/磁盘)
- Para-virtualized Drivers(virtio)
- SR-IOV(单根I/O虚拟化):直接分配PF/VF给VM
- 容器 vs VM:
- VM:硬件虚拟化,完整OS,强隔离,重量级
- 容器:OS级虚拟化,共享内核,轻量,隔离性较弱(namespace + cgroups)
10.2 容器技术
- Docker:
- 镜像:分层(UnionFS:AUFS/Overlay2)、只读、层缓存
- 容器:镜像运行实例,读写层
- Dockerfile:FROM、RUN、COPY、ADD、CMD、ENTRYPOINT、ENV、VOLUME、EXPOSE
- Docker Engine:dockerd、containerd、runc
- 网络:bridge(默认docker0)、host、overlay(Swarm/K8s)、macvlan
- 存储:volume、bind mount、tmpfs
- Kubernetes:
- Pod:最小部署单元,共享IPC、Network、UTS namespace,共享存储(emptyDir、volume)
- ReplicaSet / Deployment:副本管理、滚动更新
- Service:ClusterIP、NodePort、LoadBalancer、ExternalName,kube-proxy(iptables/IPVS)
- Ingress:HTTP/HTTPS路由
- ConfigMap / Secret:配置管理
- Namespace:虚拟集群
- PersistentVolume(PV) / PersistentVolumeClaim(PVC):存储抽象
- StatefulSet:有状态应用(稳定网络标识、持久存储、有序部署)
- DaemonSet:每个节点一个副本
- Job / CronJob:批处理
- HorizontalPodAutoscaler(HPA):基于CPU/内存/自定义指标扩缩容
- 运行时:
- OCI标准:runc(简单)、containerd(Docker后演进)、CRI-O(K8s专用)
- gVisor(用户态内核,安全)、Kata Containers(微型VM,安全+性能平衡)
- Firecracker(AWS,无VM管理程序)
- 容器网络:
- CNI插件:Flannel(VXLAN/host-gw)、Calico(BGP + network policy)、Weave、Cilium(eBPF)
- 服务发现:kube-dns / CoreDNS
- 网络策略(NetworkPolicy):Pod间访问控制(Calico支持)
- 容器存储:
- CSI(容器存储接口):统一存储插件
- 本地存储、云存储(云盘、对象存储)、分布式存储(Ceph RBD/CephFS)
- 资源限制(cgroups):
- CPU:quota、period、shares、cpuset
- 内存:limit、requests(K8s scheduling)
- 安全:
- 镜像安全:漏洞扫描、最小化镜像、非root运行
- 容器安全:seccomp、AppArmor、SELinux、Capability dropping
- Pod安全策略 / Pod Security Admission
- 沙箱(sandbox)
十一、系统监控与调试
11.1 Linux系统工具
- 进程管理:ps、top、htop、pgrep、pkill、kill、killall、nice、renice
- 系统状态:
uptime:负载(1/5/15分钟平均)w/who:登录用户vmstat:虚拟内存、进程、CPU、I/Ompstat:多核CPU统计iostat:I/O统计netstat/ss:网络 socket 统计
- 内存:free、slabtop、smem(实际内存RSS/PSS)
- 磁盘:df、du、iostat、iotop、iotop、lsof(打开文件)、fuser(使用文件进程)
- 网络:
ifconfig/ip:网络接口(已弃用 vs 推荐)route/ip route:路由表netstat/ss:连接、路由表、接口统计nslookup/dig/host:DNS查询ping/traceroute/mtrtcpdump/tshark:抓包nc/telnet:端口测试nmap:端口扫描iftop/nethogs:流量按进程
- 系统启动:dmesg、journalctl(systemd)、/var/log/syslog、/var/log/messages
- 性能剖析:
perf:CPU周期、cache-misses、branch-misses、调度延迟、锁争用strace:跟踪系统调用ltrace:跟踪库函数调用tusc:动态跟踪(类似SystemTap)bpftrace/bcc:eBPF脚本追踪
11.2 调试技巧
- 排除网络问题:
- 本地回环测试:ping 127.0.0.1
- 本机网络:ping 本机IP
- 同网段:ping 网关/其他主机
- DNS解析:nslookup、dig
- 端口可达:telnet IP Port / nc -zv
- 路由:traceroute
- 抓包:tcpdump ‘host IP and port Port’
- 防火墙:iptables / firewalld / security group检查
- 排除磁盘问题:
- df -h:空间
- du -sh:目录大小
- iostat:I/O等待
- lsof | deleted:已删除但仍被打开的大文件
- 排除内存问题:
- free:used、available
- top:RES、VIRT
- slabtop:内核slab
- vmstat:si/so(交换)
- oom-killer日志:/var/log/messages
十二、高可用与负载均衡
12.1 负载均衡算法
- 轮询(Round Robin):依次分发
- 加权轮询:按权重分配
- 最少连接(Least Connections):当前连接数最少的服务器
- 加权最少连接:加权+最少连接
- 源IP哈希:同一客户端固定服务器(会话保持)
- 一致性哈希:节点增减影响最小,常用于缓存
- 随机:随机或加权随机
12.2 LVS(Linux Virtual Server)
- 工作模式:
- NAT:修改请求/响应IP,通过DRAM转发,单点瓶颈
- TUN(IP隧道):IP封装,跨地域,单臂
- DR(直接路由):改写MAC地址,性能高,要求同网段
- 调度算法:rr、wrr、lc、wlc、lb(最少连接)、sh(源哈希)
- Keepalived:VRRP协议,VIP漂移,健康检查
- 架构:DS(Director Server) + RS(Real Server)
12.3 Nginx
- 事件驱动(epoll)、异步非阻塞
- 模块化(HTTP、Mail、Stream)
- 配置:worker_processes(CPU核心数)、worker_connections(单worker最大连接,通常1024+)、keepalive
- 负载均衡:upstream、proxy_pass、轮询/加权/ip_hash/least_conn
- 健康检查:max_fails、fail_timeout
- 缓存:proxy_cache
- 限流:limit_req_zone、limit_conn_zone
- 动静分离、gzip压缩
12.4 HAProxy
- 多层(4层/7层)代理
- 会话保持、健康检查(HTTP/TCP/MySQL)
- 负载均衡算法更丰富
- 监控统计页面(stats socket / stats page)
- 性能调优(nbproc、nbthread、maxconn)
12.5 高可用方案
- 双机热备:主备,VIP漂移(Keepalived、Heartbeat)
- 主从复制:数据库、缓存读写分离
- 多活:
- 单元化:按用户/业务分区,流量局部到机房
- 同城双活、异地灾备
- 故障转移:自动检测、切换、回切
- 脑裂(Split-brain)处理:Quorum机制、fencing(stonith)
12.6 优雅重启与蓝绿部署
- 优雅重启(Graceful Shutdown):
- 收到SIGTERM后,停止接收新请求,等待当前请求完成或超时,然后退出
- Nginx:
nginx -s reload(热重载),nginx -s quit(优雅退出) - Java:
SIGTERM→ 调用Runtime.addShutdownHook(),关闭服务器端口,等待处理完成
- 蓝绿部署:同时运行两套环境,流量从蓝切绿,有问题快速切回
- 金丝雀发布:小流量灰度,逐步扩大,监控指标
学习建议与总结
10年经验高级开发应达到的水平
- 深度:至少1-2个领域达到专家级(如网络编程、Linux内核、性能优化、分布式存储)
- 广度:所有领域都有基本认知,能快速定位、排查问题
- 实战:生产环境故障处理经验、性能分析案例
- 源码:阅读过核心库/框架源码(如Linux内核、Netty、Nginx、Redis)
- 架构:能设计高可用、可扩展、高性能系统,权衡取舍(Trade-off)
推荐学习资源
- 书籍:
- 《计算机网络:自顶向下方法》
- 《TCP/IP详解 卷1:协议》
- 《UNIX网络编程 卷1:套接字联网API》
- 《Linux高性能服务器编程》
- 《深入理解计算机系统》(CSAPP)
- 《现代操作系统》
- 《Linux内核设计与实现》
- 《性能之巅》(Systems Performance)
- 工具:man pages、man7.org、tldr
- 实践:自制小工具、参与开源项目、复盘线上问题
文档版本:v1.0
最后更新:2025年3月
评论区