四大件知识
操作系统
死锁
是什么?
死锁:两个或两个以上的进程、线程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们将无法推进下去
满足条件
- 互斥条件
资源同一时间只能被一个线程占有(比如锁)。 - 请求与保持
线程已经持有一个资源,又去请求别的资源,且不释放已有的。 - 不可剥夺
资源只能由持有者主动释放,别人不能强行抢走。 - 循环等待
线程 A 等 B,B 等 C,C 等 A,形成一个环形等待链。
解决方法
破坏 4 个条件中的任意一个即可
- 破坏循环等待(最常用、最实用)
所有线程统一按固定顺序获取锁
比如:永远先锁 A 再锁 B,不反过来。 - 破坏请求与保持
要么一次性申请所有需要的锁,要么一个都不申请。 - 破坏不可剥夺
允许抢占资源,超时放弃锁。 - 破坏互斥
用无锁编程、CAS、乐观锁等(不太常用)
进程与线程
是什么?
进程 = 正在运行的程序实例,是资源分配的基本单位。
- 一个运行中的程序,比如打开一个浏览器、一个微信
- 拥有独立的资源:内存空间、文件句柄、网络连接等
- 进程之间相互独立,不能直接访问对方内存
- 一个进程至少有一个线程(主线程)
- 创建 / 销毁开销大
线程 = 进程内部的执行路径,是 CPU 调度的基本单位。
- 进程内部的执行单元
- 同一个进程内的线程共享进程资源(内存、文件等)
- 线程之间切换快、创建销毁开销小
- 线程自己几乎不占资源,只占栈、程序计数器等少量执行上下文
虚拟内存
是什么?
- 每个进程都有一套独立的虚拟地址空间(比如 4GB)
- 程序访问的都是虚拟地址,不是真实物理内存地址
- 操作系统通过页表把虚拟地址 → 翻译成物理地址
作用
- 扩大内存空间
- 进程隔离,更安全
- 内存使用更高效
- 方便程序加载运行
关键机制
- 把虚拟内存和物理内存都切成固定大小的页(Page),通常 4KB
- 每个进程有一张页表,记录:虚拟页号 → 物理页号 / 是否在内存 / 是否在硬盘
- CPU 访问地址时,硬件(MMU)自动查页表翻译
缺页中断
- 要访问的页不在物理内存,在硬盘上
- CPU 触发缺页中断
- 操作系统把页从 swap 读回物理内存
- 更新页表,继续执行程序
虚拟内存是计算机中用于临时存储数据的一种技术,操作系统给每个进程提供的独立虚拟地址空间,通过页表映射到物理内存或硬盘交换区。
它可以扩大可用内存、实现进程地址隔离、提高内存利用率,并通过分页和缺页中断完成地址翻译和数据换入换出。
计算机网络
网络分层
OSI 七层模型
- 应用层:给应用用的协议(HTTP、FTP、DNS)
- 表示层:数据加密、压缩、格式转换
- 会话层:建立、管理、断开会话
- 传输层:端到端传输(TCP、UDP)
- 网络层:寻址路由(IP、ARP)
- 数据链路层:帧传输、MAC 地址(以太网)
- 物理层:光电信号、网线、接口
应 表 会 传 网 链 物
TCP/IP 模型
- 应用层
对应 OSI 上三层:HTTP、HTTPS、DNS、FTP - 传输层
TCP、UDP - 网络层
IP、ARP、ICMP - 网络接口层(链路层)
设备驱动、网卡、MAC、以太网
协议
定义
描述网络通信协议,定义网络通信的规则,两者交流的的规则
分类
TCP 协议
规定了:
- 怎么建立连接(三次握手)
- 怎么断开连接(四次挥手)
- 数据怎么编号
- 丢了怎么重传
- 怎么保证不乱序
可靠、有序、慢 → 网页、文件、接口
特点:面向连接、可靠、基于字节流,全双工通信,有流量控制和拥塞控制,适用于对数据准确性要求高的场景。
UDP 协议
规定了:
- 怎么打包数据
- 怎么加上目标端口
- 发出去就行,不保证到达
不可靠、快、实时 → 直播、游戏、DNS
特点:无连接、不可靠、面向数据报、开销小、速度极快,适用于对数据实时性要求高的场景。
HTTP 协议
规定了:
- 客户端怎么发请求(GET / POST)
- 服务端怎么回响应
- 头怎么写、内容怎么放
- 状态码代表什么
应用层协议,底层用 TCP → 网页、接口
访问网站过程
- 先做 DNS 解析,域名转 IP
- 进行 TCP 三次握手 建立连接
- HTTPS 则进行 TLS 握手 加密
- 浏览器发送 HTTP 请求报文
- 服务器返回 HTTP 响应(HTML 等资源)
- 浏览器解析渲染,并加载图片、JS、CSS 等额外资源请求
- 最后 TCP 四次挥手 断开连接
域名解析过程
浏览器先查自身缓存,再查系统缓存和 hosts,没有就请求本地 DNS。
本地 DNS 依次问根 DNS、顶级域 DNS、权威 DNS,拿到 IP 后缓存并返回。
tcp三次握手
- 客户端向服务器发送SYN包,请求建立连接。c 发生带着syn标志和随机序列号seq的报文到s,C 进入状态:SYN_SENT,等待服务器返回ACK包。
- 服务器收到c的SYN包,回复ACK包和SYN包,序列号seq也随机生成,确认号是收到的序列号+1,s进入状态:SYN_RCVD,等待客户端返回ACK包。
- 客户端收到s的ACK包,回复ACK包和SYN包,序列号seq是第一次的+1,确认号是收到的序列号+1,进入状态:ESTABLISHED,完成三次握手,开始通信。
丢失其中的一次会怎么样?
第一次握手 SYN 丢失:
S 完全收不到任何包,无感知
C 在 SYN_SENT 等待 ACK
超时后,内核自动重传 SYN(指数退避重发)
重传多次仍失败 → 连接超时,建立失败第2次握手 ACK 丢失:
C:还在 SYN_SENT,收不到 ACK → 超时重传 SYN
S:已经进入 SYN_RCVD,但收不到第三次握手
S 会超时重传 SYN+ACK
结果:
重传多次失败 → 两端都认为连接失败
服务端 SYN_RCVD 队列会占用一个位置,极端情况可能导致 SYN 洪水第3次握手 ACK 丢失:
C 已经认为连接建立成功,进入 ESTABLISHED
S 还在 SYN_RCVD,没收到 ACK,认为连接没建好
S 超时后重传 SYN+ACK
C 收到重复的 SYN+ACK,会重新发送 ACK
若 S 最终收到 ACK → 连接正常建立
若一直收不到 → S 放弃连接,C 还以为连着,c发包会触发 RST重置连接。

