进程和线程
图片
图片
图片
图片
图片
图片
图片
死锁
图片
图片
图片
图片
IO多路复用
Q:什么是 IO 多路复用?
IO 多路复用的核心思想是:
IO 多路复用就是一个线程同时监听多个文件描述符,当某个连接可读可写时再去处理它。
它解决的是高并发场景下线程数量过多的问题,所以比传统 BIO 的"一连接一线程"模型更适合高并发。
常见实现有 select、poll、epoll,其中 epoll 的优势在于事件驱动和返回就绪 fd,所以在 Linux 下最常用。
Q:select、poll、epoll 有什么区别?
select:
- 有监听数量上限
- 每次调用都要把所有 fd 从用户态拷贝到内核态
- 遍历成本较高
poll: - 解决了 select 的数量上限问题
- 但本质上仍然需要轮询遍历
epoll: - 基于事件驱动
- 不需要每次完整遍历所有 fd
- 在大量连接场景下性能更好
所以高并发网络编程里,最常见的是 epoll。
epoll 的 LT 和 ET 模式
Q:什么是 LT 和 ET?
epoll 常见有两种触发模式: - LT(Level Trigger,水平触发)
只要缓冲区里还有数据没处理完,就会持续通知 - ET(Edge Trigger,边缘触发)
只有状态变化时通知一次,不会反复提醒
面试里最常问的是区别: - LT 更稳,更不容易漏处理
- ET 性能潜力更高,但要求一次把数据尽量读完,否则容易漏事件
如果你答 Netty,也可以补一句:
ET 模式通常要配合非阻塞 IO 一起用。
Q:为什么 epoll 比 select、poll 更高效?
关键是两个点:
- 监听集合管理更高效
- 返回的是就绪事件,不是所有 fd
也就是说,select/poll 的问题不只是"API 老",而是: - 每次都要把关注列表从用户态拷到内核态
- 每次都要遍历全量 fd
而 epoll 更接近"先注册、后通知"的模式,所以在连接数大、活跃连接比例低的场景下更有优势。
Q:阻塞/非阻塞、同步/异步有什么区别?
这四个概念最容易混。建议分成两个维度来答:
- 阻塞 / 非阻塞:调用线程会不会被挂起等待
- 同步 / 异步:结果是不是还要调用方主动参与处理
常见组合理解: - BIO:同步阻塞
- NIO 多路复用:同步非阻塞
- AIO:异步非阻塞
所以 IO 多路复用并不等于异步,它更准确地说是:
同步非阻塞的事件驱动模型。
Q:零拷贝是什么?
零拷贝关注的是 数据搬运路径优化,IO 多路复用关注的是 连接事件处理效率。
两者解决的问题不一样:
- IO 多路复用:减少线程数量,提升连接管理效率
- 零拷贝:减少用户态和内核态之间的数据复制、减少 CPU 参与
典型零拷贝手段有: - mmap
- sendfile
面试时不要把它们混成一个概念,但可以说明它们经常一起出现在高性能网络框架里。
Reactor 模型怎么理解
Q:IO 多路复用和 Reactor 有什么关系?
IO 多路复用提供的是"事件监听能力",Reactor 提供的是"事件分发模型"。
可以这样理解:
- epoll 负责告诉你"哪个连接就绪了"
- Reactor 负责把这个就绪事件分发给对应处理器
所以像 Java NIO、Netty,本质上都是: - 底层用 IO 多路复用监听事件
- 上层用 Reactor 组织事件处理流程
为什么要有 CPU 缓存
Q:为什么主存前面还要加多级缓存?
因为 CPU 的计算速度远快于主存访问速度,如果每次取数据都直接访问内存,CPU 会经常空等。
所以现代计算机一般会设计成: - L1 缓存
- L2 缓存
- L3 缓存
- 主存
这本质上是在解决 CPU 和内存速度不匹配 的问题。
Linux常用命令
查看进程和资源
Q:排查线上问题时,你常用哪些 Linux 命令?
我最常用的有:
- top / htop:看 CPU、内存、进程资源占用
- ps -ef:看进程信息
- free -m:看内存
- df -h:看磁盘空间
- du -sh:看目录大小
查看日志和网络
Q:常见日志和网络排查命令有哪些?
常见会用到: - tail -f:实时看日志
- grep:过滤关键字
- less:分页查看文件
- netstat / ss:看端口和连接
- lsof -i:看端口占用
如果是 Java 服务排障,还经常会配合 jps、jstack、jmap 一起用。
CPU 过高时看什么
Q:线上 CPU 飙高时,你一般怎么查?
我的排查顺序通常是: - top 看整体 CPU 占用
- top -Hp 看哪个线程最耗 CPU
- ps -mp -o THREAD,tid,time 辅助看线程
- 把线程 ID 转成 16 进制,再配合 jstack 找具体代码栈
如果是面试,建议把"命令 + 思路"一起说出来,不要只背命令名。
内存问题怎么查
Q:怀疑内存有问题时,你会用哪些命令?
常见组合是: - free -m:看整体内存和 swap
- top:看哪个进程吃内存
- vmstat:看内存、换页、上下文切换
- pmap -x :看具体进程内存映射
如果是 Java,还会继续配合: - jmap -histo
- jcmd GC.heap_info
磁盘和 IO 问题怎么查
Q:磁盘满了或者 IO 异常时怎么查?
我一般这么查: - df -h:先看分区整体使用率
- du -sh *:看哪个目录占空间大
- du -sh /path/* | sort -h:逐层缩小范围
- iostat -x:看磁盘读写压力和 util
磁盘类问题最常见的坑是: - 日志膨胀
- 临时文件没清理
- 大目录或大文件积压
网络问题怎么查
Q:端口占用、连接异常、超时问题怎么查?
常用命令有: - ss -lntp:看监听端口和对应进程
- lsof -i :端口号:看某个端口被谁占了
- netstat -anp:看连接状态
- ping:测连通性
- curl:测接口可达性和返回
如果连接很多,还要关注: - ESTABLISHED
- TIME_WAIT
- CLOSE_WAIT
这些 TCP 状态常常是面试追问点。
用户态和内核态
Q:什么是用户态和内核态?
用户态是应用程序运行的受限环境,权限较低;
内核态是操作系统内核运行的高权限环境,能直接操作硬件资源。
像网络 IO、磁盘 IO、进程调度等很多能力,都需要从用户态切到内核态完成。