路线图

面试 · 系统串联题

星辉 2026-07-02 阅读 10 min 2,019 字 路线图
面试 · 系统串联题 封面

这份是什么? 前面 1-5 类(概念解释 / 对比辨析 / 原理追问 / 场景排查 / 方案设计)是 building blocks——一块块拆开的知识点。 这份「系统串联题」凌驾于它们之上:每道题都是一个真实运维里反复出现的场景,一个问题能炸开成一整棵知识树,考官顺着追问一路深入。它把散落在 1-5 类里的知识点串成一条线,考的是你能不能把零件组装成系统级的排障/原理能力。

入选标准(三条同时满足 + 一条加分)

  1. 高杠杆——学会终身受用,真实运维反复用到;
  2. 高频必问——Linux 面试几乎跑不掉;
  3. 能串联——一题炸开成一棵知识树,区分度极高;
  4. 加分——每题都带「踩坑细节」,是"真做过"才知道的东西,不是教科书答案。

建议:考前把这 8 道当"总题"重点刷。能把每题的追问链顺下来,1-5 类的零散知识点自然就被盘活了。

发行版基线(2026):CentOS 7/8 均已 EOL,示例以 Rocky/AlmaLinux(RHEL 系)与 Ubuntu/Debian 系为准;网络工具统一用 ss/ip(不用 netstat/ifconfig);服务管理用 systemctl(不用 service/chkconfig)。


锚点题 1:服务器 load 飙高 / CPU 打满 / 系统卡死,你怎么一步步定位?#

为什么是锚点题:这是 Linux 排障的"总题"。一问就能看出你是背命令还是真懂——真懂的人先分类(是 CPU 忙、I/O 卡、还是 softirq 打满),背命令的人上来就 top 然后卡壳。几乎每场运维/SRE 面试都会问。

会串出的知识点地图

text
load 飙高 / 系统卡
├── load average 到底是什么(1/5/15 分钟)
│   └── Linux 特殊:load = 可运行(R) + 不可中断(D) 进程数 → load 高 ≠ CPU 忙
├── CPU 时间分解 us / sy / ni / id / wa / hi / si / st
│   ├── us 高 → 应用层 CPU(死循环 / 正则 / 加解密 / GC)
│   ├── sy 高 → 系统调用/上下文切换过多、fork 风暴
│   ├── wa 高 → I/O 瓶颈(磁盘慢 / 等 I/O)
│   ├── si 高 → 软中断(高 pps 网络、单核 softirq 打满)
│   └── st 高 → 云主机被"邻居"抢 CPU(超卖 / steal)
├── 进程 → 线程 → 调用栈 逐层下钻
├── D 态进程(不可中断睡眠)→ 卡在内核 I/O
└── 工具链:top/htop · uptime · vmstat · iostat · pidstat · mpstat · sar · perf · strace

考官追问链

  1. 现象层:怎么快速判断"到底是 CPU 忙、还是 I/O 卡、还是内存/网络"?(uptime 看 load,top 看 CPU 那一行的分解)
  2. 机制层:load average 的数字到底代表什么?为什么 load 很高但 top%id(idle)还很大?(Linux 把 D 态也算进 load)
  3. 边界层:%wa 高一定是磁盘的锅吗?%st 高说明什么?(wa 是"CPU 空闲且有 I/O 在飞",st 是被虚拟化宿主抢走)
  4. 定位/验证层:怎么从"某个 CPU 100%"下钻到"哪个进程→哪个线程→哪一行代码/哪个系统调用"?(top -H / pidstat -tperf top / strace / 语言级 jstackpy-spy

参考答题骨架

  • 先分类(最关键的一步)uptime 看 load 和核数比(nproc 拿核数,load/核数 ≈ 1 算满载);top 看 CPU 行:
    • us 高 → 应用 CPU 密集 → 找进程找线程;
    • sy 高 → 系统调用/上下文切换多 → vmstat 1cs(上下文切换)、in(中断);
    • wa 高 → I/O 瓶颈 → 转 iostat -x 1(看 %utilawait、队列深度)+ pidstat -d 1 / iotop 找是谁在读写;
    • si 高 → 软中断 → mpstat -P ALL 1 看是不是某一核被打满、sar -n DEV 1 看网卡 pps;
    • st 高 → 云主机被超卖,是宿主机/邻居的问题,不是你应用的锅。
  • load 高但 CPU 空闲:几乎一定是 D 态进程堆积(卡 I/O)→ ps -eo state,pid,wchan,cmd | grep '^D'wchan 看卡在哪个内核函数(多半是磁盘/NFS)。
  • 下钻:找到进程 → top -H -p <pid>pidstat -t -p <pid> 1 定位到热点线程 → perf top -p <pid> 看热点函数 / strace -p <pid> 看卡在哪个系统调用 / 语言层用 jstackpy-spy dump 抓栈。
  • 兜底dmesg -T / journalctl -k 看内核有没有报错(磁盘 I/O error、OOM、网卡 reset)。

踩坑 / 加分点

  • load 高 ≠ CPU 忙——这是最经典的坑。见过 load 几十、%id 却还 60% 的机器,真相是 D 态卡在挂死的 NFS 上。答出"load 含 D 态"直接拉开区分度。
  • top 里进程 %CPU 可以 >100%——那是多线程按核累加(Irix 模式),按 I 键可切换成"整机百分比"。
  • %wa不代表 CPU 很忙,它是"CPU 空闲、但有未完成 I/O"的时间;wa 高时 CPU 其实可能很闲,别把 wa 当成"CPU 被 I/O 占用"。
  • vmstat 1第一行是开机以来的平均值,要看第二行起的实时值——好多人被第一行误导。
  • 云主机遇到 %st 高,先甩锅给宿主超卖是对的,但要能拿出证据(st 持续高 + 自己进程没那么忙)。

关联:CPU/进程状态细节见「原理追问型」进程调度部分;top/vmstat/iostat 逐命令见「网络诊断/存储」与「15-日志与排查思路」。


锚点题 2:磁盘明明有空间,却报 No space left on device,怎么回事?#

为什么是锚点题df -h 看着还剩一大半,写文件却报"没空间"——这个反直觉现象几乎人人踩过,是检验"是否真管过生产机"的照妖镜。高频且高杠杆。

会串出的知识点地图

text
No space left(但 df -h 有空间)
├── inode 耗尽         → df -i 看 IUse%(海量小文件:session/缓存/邮件队列)
├── 已删除但被进程占用 → lsof +L1 / lsof | grep deleted(du 和 df 对不上)
├── 文件系统预留块     → ext4 默认给 root 留 5%,普通用户先报满(tune2fs -m)
├── 写错了分区/挂载点   → df <目标路径> 确认到底落在哪个文件系统
├── 文件系统只读       → 出错后内核 remount ro(dmesg 有 EXT4-fs error)
└── 磁盘/项目配额 quota → quota -u / repquota

考官追问链

  1. 现象层:df -h 显示有空间,写入却报错,你第一反应查什么?(df -i——先排除 inode 耗尽)
  2. 机制层:为什么会 inode 耗尽?inode 和 block 是两套独立计数吗?(是;ext4 建文件系统时 inode 数就定死了,海量小文件耗光 inode,block 还剩一堆)
  3. 边界层:du -sh 加起来远小于 df 显示的已用,差的空间去哪了?(被"已删除但仍被进程打开"的文件占着)
  4. 定位/验证层:怎么找到并释放这些幽灵文件?删大日志正确姿势是什么?(lsof +L1 找 → reload/重启进程,或 truncate -s 0;别用 rm

参考答题骨架

  • 第一刀df -i。IUse% 100% 就是 inode 耗尽——海量小文件(PHP session、缓存碎片、邮件队列、大量空文件)。定位大户:for d in /*; do echo "$(find $d -xdev 2>/dev/null | wc -l) $d"; done | sort -rn
  • 第二刀df -h 有空间 + du -sh 对不上 → 已删除文件被进程占用。lsof +L1(列出链接数<1 即已删仍打开的文件)或 lsof | grep deleted。典型:日志被 rm 了但 nginx/tomcat 还在往那个 fd 写,空间死活不回来。
    • 解决:systemctl reload/重启持有进程;或不重启就 truncate -s 0 /proc/<pid>/fd/<n> 清空。
  • 再排查:预留块(tune2fs -l 看 Reserved block count,tune2fs -m 1 调低);写错分区(df /path 确认路径归属哪个文件系统);只读重挂(mount | grep ro + dmesg 看有没有文件系统报错);配额(repquota -a)。

踩坑 / 加分点

  • dudf 对不上,99% 就是"已删除文件被进程占用"——这是本题最值钱的一句话。
  • 删满盘的大日志,正确姿势是 truncate -s 0 file> file,绝不是 rmrm 后进程还持有 fd,空间不释放,反而更难救。
  • XFS 的 inode 是动态分配的,不像 ext4 建盘时定死,所以 XFS 上 inode 耗尽相对少见(但受 imaxpct 限制,极端海量小文件仍可能撞上)。
  • 别忘了 df -i——太多人只看 df -h,空间够就懵在原地。
  • 若报的是 Read-only file system 而非 No space,那是文件系统出错被内核保护性 remount ro 了,dmesg 里能看到,方向完全不同。

关联:inode 本质见「概念解释型 题目1」;删文件为何不释放空间见本档「锚点题 5」。


锚点题 3:一个进程 kill -9 都杀不掉,为什么?怎么办?#

为什么是锚点题kill -9 在很多人心里是"核武器、必杀"。能讲清楚它为什么也会失效,直接暴露你对进程状态和信号机制的理解深度。经典高区分度题。

会串出的知识点地图

text
kill -9 杀不掉
├── SIGKILL(9) 语义:不可捕获/不可忽略/不可阻塞,但——
├── D 态(TASK_UNINTERRUPTIBLE)→ 卡在内核态 I/O,信号排队等它醒;NFS 挂死/磁盘坏 → 永远醒不来
├── 僵尸态 Z(defunct)    → 进程已死,只剩退出状态等父进程回收;杀"死人"无效,要处理父进程
├── 内核线程([kworker] 等)→ 名字带方括号,不响应普通信号,也不该 kill
├── PID 1(systemd)        → 内核特殊保护
└── T 态(被 ptrace/调试器 stop)→ 需先 detach / SIGCONT
    └── 退出码:被信号 n 杀死 → $? = 128 + n(SIGKILL=137, SIGTERM=143, SIGSEGV=139)

考官追问链

  1. 现象层:kill -9 <pid> 敲了没反应,进程还在。你先看什么?(ps -o pid,stat,wchan,cmd——看 STAT 那一列)
  2. 机制层:SIGKILL 不是"不可阻塞、必杀"吗?什么情况下它也不生效?(D 态收不到信号、僵尸已经是死的)
  3. 边界层:D 态和僵尸态处理方式一样吗?(完全不一样:D 态是"活着卡在内核",查 I/O;僵尸是"已死没人收尸",处理父进程)
  4. 定位/验证层:怎么确认它到底卡在哪?怎么救?被信号杀死后退出码是多少?(cat /proc/<pid>/stack 看内核栈;D 态修底层 I/O 或最后 reboot;僵尸 kill 父进程;$?=128+n)

参考答题骨架

  • 先确诊状态ps -eo pid,ppid,stat,wchan,cmd | grep <pid>,看 STAT 首字母:
    • D(不可中断睡眠):进程在内核态等 I/O(磁盘、NFS、某些驱动),信号只在返回用户态时处理,D 态收不到,SIGKILL 只能排队。若底层 I/O 永不返回(NFS server 宕、磁盘坏),进程永远 D 态。救法:修复底层 I/O(恢复存储/NFS/卸载卡死挂载),实在不行只能 reboot。
    • Z / defunct(僵尸):进程已经死了,只剩一条 task_struct 保留退出状态,等父进程 wait() 回收。对死人发信号没用。救法:让父进程wait,或 kill 掉父进程——孤儿被 PID 1(systemd)收养并回收。
    • 内核线程[kworker/*][ksoftirqd],名字带方括号):不是普通进程,不响应普通信号,也不该动。
    • T(stopped):被调试器 ptrace 停住,先 kill -CONT 或 detach。
  • 退出码:进程被信号 n 终止,shell 里 $? = 128 + n。SIGKILL(9)→137,SIGTERM(15)→143,SIGSEGV(11)→139。反推能知道进程是被什么信号弄死的。
  • 深挖卡点cat /proc/<pid>/stack(需权限)看内核调用栈,wchan 看睡在哪个内核函数。

踩坑 / 加分点

  • "kill -9 杀不掉"90% 不是 D 态就是僵尸,而这两者处理天差地别(一个查 I/O、一个查/杀父进程),能一句话点破区别是加分点。
  • 僵尸进程不占 CPU/内存,只占一个 PID 和进程表项;真正的危害是大量僵尸把 PID 耗尽。所以"僵尸多"要治的是那个不回收子进程的父进程。
  • 别上来就 kill -9。正常流程先 SIGTERM(15) 让进程优雅退出(flush 数据、清临时文件、释放锁)。直接 -9 可能留下脏数据、残留锁文件、半截写的文件。
  • 有一种 TASK_KILLABLE 是"可被 SIGKILL 打断的 D 态变种",较新的内核代码路径会用,所以不是所有 D 态都绝对杀不动——但老驱动/老路径不保证。

关联:进程状态机、信号完整列表见「09-进程管理」;退出码 128+n 也在「14-Shell脚本」里出现。


锚点题 4:从敲下一条命令到看到输出,中间发生了什么?#

为什么是锚点题:这是操作系统与 Linux 的"世纪之问",一句话能把 shell、进程、系统调用、权限模型全串起来。答得越细,功底越深,几乎是资深岗必问的分水岭题。

会串出的知识点地图

text
敲 `ls -l /tmp > out.txt` 回车
├── shell 解析:分词 → 展开(alias→大括号→~→$变量→$()→算术→glob*→去引号) → 识别重定向 >
├── 命令类型判断:builtin(cd/echo) / 函数 / 外部程序(只有外部程序才走 PATH)
├── PATH 查找 + hash 缓存(hash -r 清)
├── fork()   → 子进程(COW 写时复制,不真复制内存)
├── 子进程里做重定向:open(out.txt) → dup2(fd, 1)
├── execve() → 加载 ELF、ld.so 链接 .so、替换进程镜像(PID 不变)
├── 权限检查:文件 x 位 + 路径每级目录 x 位 + inode mode/uid/gid(含 SUID/SGID)
├── 运行:系统调用读目录(getdents)/取元数据(stat)/write(1,...) → 因 fd1 已重定向,写进文件
└── 退出:exit → 父进程 wait() 收尸拿 $?(前台还涉及 tty/进程组/会话/SIGCHLD)

考官追问链

  1. 现象层:回车之后,shell 第一步做什么?(读一行 → 词法分析/分词 → 一系列展开)
  2. 机制层:shell 怎么知道该跑哪个程序?内建命令和外部命令有什么区别?(builtin 不 fork,外部命令才查 PATH、fork+exec)
  3. 边界层:> out.txt 这个重定向,是在 fork 之前还是之后生效的?为什么不会污染当前 shell?(在子进程里、exec 之前做 open+dup2,只影响子进程)
  4. 定位/验证层:为什么有时候报 command not found,有时候报 Permission denied?怎么区分?(前者 PATH 里没有;后者找到了但没 x 位、或路径上某级目录没 x)

参考答题骨架

  • shell 阶段:读入一行 → 分词 → 按固定顺序展开(alias → 大括号 {} → 波浪号 ~ → 变量 $ → 命令替换 $() → 算术 → 路径通配 * → 去引号),同时识别重定向/管道。
  • 定位命令:先判断是别名、shell 内建(cd/export/echo)、还是函数;都不是才当外部程序,按 $PATH 顺序查找(有 hash 表缓存,hash -r 清)。
  • 创建进程fork() 出子进程(COW 写时复制,不真复制父进程内存,因为马上要 exec)。
  • 子进程里配重定向open("out.txt", O_WRONLY|O_CREAT|O_TRUNC) 拿到 fd,dup2(fd, 1) 把 stdout 指到文件。管道则是 pipe() 把多个进程的 fd 串起来。
  • execve:加载 ELF,动态链接器 ld.so 加载依赖的共享库(ldd 可看),映射地址空间,进程镜像被替换但 PID 不变
  • 权限检查:执行需文件 x 位;进入 /tmp 需路径上每一级目录x(穿过)位;读目录内容需 r 位;内核按 inode 的 mode + owner/group 对你的 euid/egid 判定(SUID/SGID 会改变有效身份)。
  • 运行与收尾ls 通过系统调用 openat/getdents 读目录、stat 取元数据、write(1, ...) 输出——因 fd 1 已被重定向,内容落进 out.txt;进程 exit(),shell wait()/waitpid() 收尸拿到 $?

踩坑 / 加分点

  • fork 用 COW,不是立刻复制整个内存——因为紧接着就 exec 把镜像换掉了,复制开销近乎白费。能提 vfork/posix_spawn 优化更佳。
  • 重定向的 open+dup2 发生在 fork 之后、exec 之前的子进程里——所以只对被执行的命令生效,不会污染当前 shell 的 stdout。
  • command not found vs Permission denied 要能区分:前者 = PATH 里根本没这个可执行文件;后者 = 找到了但没 x 位,或路径上某级目录缺 x(进不去)。
  • 目录的 x 位是"能否进入/穿过",r 位是"能否列出内容"——只有 rx,能看到文件名但 stat 不了(ls -l 全是问号)。这点极多人搞混。
  • 内建命令为什么不能是外部程序cd 必须改当前 shell 的工作目录,如果 fork 出子进程去 cd,改的是子进程的目录,父 shell 根本不变——所以 cd 天生只能是 builtin。
  • hash 缓存会导致你更新/移动了二进制后 shell 还跑旧路径,hash -r 刷新。

关联:展开顺序/引号见「14-Shell脚本」;重定向与管道见「08-管道与重定向」;权限位见「04-权限系统」。


锚点题 5:一个文件/目录删不掉,或删了空间没释放,排查思路?#

为什么是锚点题:删文件看似最基础,却藏着一堆反直觉的坑(删权限看的是父目录、chattr 锁、幽灵文件占空间)。一道题把权限模型、inode/硬链接、文件系统状态全串起来,高频且能问很深。

会串出的知识点地图

text
文件删不掉 / 删了空间不释放
├── 权限:能删与否看【父目录】的 w+x,不是文件本身!
│   └── sticky bit(+t,如 /tmp 的 1777):只有属主/root 能删
├── inode 与硬链接计数:unlink 只是 i_nlink -1;=0 且无进程打开 才真正释放数据块
├── 删了空间不释放:i_nlink=0 但进程还持有 fd(deleted 状态)→ lsof +L1
├── 特殊删不掉
│   ├── chattr +i 不可变属性(root 也删不掉)→ lsattr 查、chattr -i 解
│   ├── 文件名含特殊字符/前导 -  → rm ./-x 或 find -inum <n> -delete
│   ├── 文件系统只读/损坏        → dmesg,先修复/重挂
│   └── 目录 device busy         → 有进程 cwd/占用:lsof +D / fuser -vm

考官追问链

  1. 现象层:普通用户能不能删掉一个属主是 root、权限 000 的文件?(能——只要你对父目录有 w+x)
  2. 机制层:为什么删权限看父目录而不是文件本身?rm 到底删了什么?(rm = unlink 目录项,改的是目录内容,所以要目录的写权限)
  3. 边界层:rm 完文件、i_nlink 到 0 了,为什么 df 空间还没回来?(还有进程持有该文件的 fd,数据块不释放)
  4. 定位/验证层:root 都删不掉一个文件,可能是什么原因?怎么查?(chattr +i 不可变属性 / 文件系统只读 / device busy——lsattrdmesglsof +D

参考答题骨架

  • 权限的真相rm 本质是 unlink——从父目录里删掉目录项。所以能不能删,取决于你对父目录有没有 w+x,跟文件本身权限无关(文件 000/只读也照删)。
  • sticky bit:目录设了 +t(如 /tmp1777),则只有文件属主、目录属主或 root 能删——防止公共目录里互删。
  • inode 与硬链接ls -i 看 inode 号,stat 看 Links 数。unlink 只是把链接计数减 1;只有链接数=0 且没有进程打开该文件时,数据块才真正释放
  • 删了空间不释放:链接数已到 0,但进程还持有 fd → 幽灵文件。lsof +L1 / lsof | grep deleted 找 → reload/重启进程,或 truncate -s 0 /proc/<pid>/fd/<n>。(同「锚点题 2」)
  • root 都删不掉
    • chattr +i(immutable):连 root 都改不了删不了,lsattr 查、chattr -i 先解锁;
    • 文件名含空格/控制字符/前导 -rm ./-filerm -- -file,或按 inode 删 find . -inum <n> -delete
    • 文件系统只读/损坏:dmesg 看 EXT4/XFS error,先 fsck/重挂读写;
    • 删目录报 Device or resource busy:有进程 cwd 在里面或打开了文件,lsof +D /path / fuser -vm /path 找出来。

踩坑 / 加分点

  • "文件是 root 的、权限 000,我普通用户能删吗?"——能! 只要对父目录有 w+x。这题极爱考,答"不能"直接挂,因为暴露了你不懂"删权限看父目录"。
  • chattr +i 是运维加固手段,也是黑客锁后门文件的常用招。遇到 root 都删不掉的文件,先 lsattr 看属性——很多人卡这里半天想不到。
  • 删满目录的大日志空间不回收 → truncate 而非 rm(进程持有 fd 时)。
  • 海量小文件 rm -rf 很慢(逐个 unlink + 遍历目录)。可用 rsync --delete 拿空目录去覆盖,或极端情况直接重建文件系统更快。
  • NFS 上删正在被打开的文件会留下 .nfsXXXX(silly rename),关掉持有进程即可。

关联:inode/硬链接见「概念解释型 题目1、2」与「原理追问型 题目6」;权限位见「04-权限系统」;空间不释放见本档「锚点题 2」。


锚点题 6:内存去哪了?free 里的 buffer/cache 是什么,OOM 是怎么触发的?#

为什么是锚点题free 看着"内存快满了"其实是新手最大误判来源。能讲清 buff/cache 可回收、available 才是真相、以及 OOM Killer 的选择逻辑,是内存这块的分水岭题。容器时代(cgroup 限制)更是必问。

会串出的知识点地图

text
内存去哪了
├── free 各列:total/used/free/shared/buff/cache/available
│   ├── buff/cache = 页缓存,可回收,不是真占用
│   └── available 才是应用真正还能用的(含可回收 cache)← 看这个,不是 free 列
├── 进程视角:RES(真实物理) vs VIRT(虚拟地址空间,别被吓到) vs SHR,更准用 smaps 的 Pss
├── 内核占用:slabtop(dentry/inode 缓存,海量小文件会撑大)
├── swap:vmstat 的 si/so,频繁换入换出 = thrashing = 系统假死般卡
└── OOM Killer:物理+swap 都不够又回收不了 → 按 oom_score 选进程杀
    └── cgroup(容器/systemd) 内存超限 → cgroup 级 OOM,只杀该组内进程

考官追问链

  1. 现象层:free -h 显示 free 只剩几百 M,是不是内存快满要出事了?(不一定——buff/cache 可回收,看 available
  2. 机制层:buff/cache 是什么?为什么 Linux 要把空闲内存拿去做 cache?(页缓存加速文件 I/O;"空闲内存是浪费",内存吃紧时自动回收)
  3. 边界层:进程 VIRT 几十 G 是不是吃了几十 G 内存?RES 和 Pss 有什么区别?(VIRT 是虚拟地址空间,未必占物理;看 RES,共享库重复计要看 Pss)
  4. 定位/验证层:进程被莫名杀了,怎么确认是 OOM?容器里内存明明够却被杀是为什么?(dmesg/journalctl -k 找 "Out of memory: Killed process";容器按 cgroup memory.max 算,不是宿主总内存)

参考答题骨架

  • free -h 的正确姿势:别盯 free 列,看 available——它估算了"包含可回收 cache 在内、应用还能拿到多少"。buff/cache 是内核用空闲内存做的页缓存,内存紧张时会自动回收,不算真占用。
  • 定位 used 高top 按内存排序(大写 M)或 ps aux --sort=-rss。看 RES(常驻物理内存),别看 VIRT(虚拟地址空间,含未落地的映射)。更精确用 /proc/<pid>/smaps_rollup 里的 Pss(共享库按比例分摊,RSS 会重复计)。
  • 内核内存slabtop 看 slab(dentry/inode 缓存),遍历海量小文件会把 dentry cache 撑很大。
  • swapswapon --show + vmstat 1si/so。持续换入换出 = thrashing,系统卡到"假死"——这种时候往往宁可让它 OOM 也别长期抖。
  • OOM Killer:物理内存 + swap 都不够、又回收不出来时触发。内核按 oom_score(受 oom_score_adj 调节)挑"性价比最高"的进程杀(通常是占内存最大的)。证据在 dmesg -T / journalctl -kOut of memory: Killed process <pid> (<name>)
  • 容器/cgroup:容器内存超 memory.max 会触发 cgroup 级 OOM,只杀该 cgroup 内进程。看 memory.events(oom_kill 计数)。

踩坑 / 加分点

  • 只看 free 列以为要爆、其实 buff/cache 可回收——最经典误判。一句"看 available"立刻显专业。(很老的 procps 没有 available 列,更容易被坑。)
  • VIRT 大 ≠ 吃内存:JVM 预留地址空间、mmap 大文件都会让 VIRT 巨大但 RES 不高。看 RES/Pss。
  • 容器里 free/top 看到的常是宿主机内存(除非新内核 + cgroup v2 感知),真正限制是 memory.max,OOM 也按 cgroup 算——"容器被 OOM 但宿主内存够"的坑就在这。排查容器内存必看 cgroup。
  • echo 3 > /proc/sys/vm/drop_caches 能手动放 cache,但生产别乱用:下次读全 miss,性能抖动,一般根本不需要。
  • OOM 杀的不一定是元凶:内核挑的是"占最多"的进程,真凶可能是那个疯狂申请内存、触发了这次分配的进程。别看到谁被杀就怪谁。

关联:内存概念/swap 见「概念解释型」;top/free/vmstat 命令见「09-进程管理」「15-日志与排查思路」。


锚点题 7:SSH 连不上服务器,给我一套完整的排查思路?#

为什么是锚点题:几乎人人被 SSH 卡过,而它天然串起"网络分层 + 服务 + 认证 + 权限 + SELinux + 磁盘"一整条链,是检验"分层排障思维"的最佳载体。运维面试的常青题。

会串出的知识点地图

text
SSH 连不上(按连接建立顺序自下而上)
├── 网络可达:ping / 路由(ICMP 可能被禁)
├── 名字解析:dig / getent hosts(连错 IP?)
├── 端口可达:服务端 ss -tlnp|grep :22(监听在 0.0.0.0 还是 127.0.0.1?)
│   └── refused(端到了没人听/被 reset) vs timeout(包被防火墙丢)← 分水岭
├── 防火墙/安全组:firewalld/nftables/iptables + 云安全组(timeout 常在这层)
├── sshd 服务:systemctl status sshd / journalctl -u sshd
├── 认证层
│   ├── ~/.ssh 700、authorized_keys 600、家目录不可组/他人可写(StrictModes)← 最高频坑
│   ├── sshd_config:PubkeyAuthentication/PasswordAuthentication/PermitRootLogin/AllowUsers
│   ├── 客户端 ssh -vvv 看协商断在哪一步
│   └── SELinux:authorized_keys context 不对 → restorecon(Rocky/Alma 坑)
└── 其它:磁盘满、hosts.deny、MaxStartups 限流、shell 是 /sbin/nologin、家目录不存在

考官追问链

  1. 现象层:连不上有两种表现——Connection refusedConnection timed out,它们指向的问题一样吗?(完全不同!refused=通到主机了、端口没服务/被拒;timeout=包被丢,一般防火墙/安全组/路由)
  2. 机制层:怎么确认 sshd 真的在监听、监听在哪个地址?(服务端 ss -tlnp | grep :22,看是 0.0.0.0 还是 127.0.0.1——后者只能本机连)
  3. 边界层:密钥登录一直失败、回退到要密码,最可能是什么?(~/.ssh 或家目录权限太开,sshd 因 StrictModes 静默拒绝公钥)
  4. 定位/验证层:怎么快速定位卡在哪一步?看哪些日志?(客户端 ssh -vvv;服务端 journalctl -u sshd + RHEL 系 /var/log/secure 或 Debian 系 /var/log/auth.log

参考答题骨架

  • 分层,从下往上
    1. 网络可达:ping(ICMP 可能被禁,不通不代表死)、路由;
    2. 解析:连域名时 dig/getent hosts 确认没连错 IP;
    3. 端口:服务端 ss -tlnp | grep :22 看 sshd 监听没、监听在哪个地址(0.0.0.0 全网 / 127.0.0.1 仅本机 / 特定 IP);客户端 nc -vz host 22 测通不通;
    4. 防火墙/安全组:本机 nft list ruleset / iptables -L -n + 云安全组;
    5. 服务:systemctl status sshdjournalctl -u sshd(配置写错会启动失败);
    6. 认证:公钥登录严查权限——~/.ssh 700、authorized_keys 600、家目录不能对组/其他人可写(否则 StrictModes 拒绝);sshd_configPubkeyAuthentication/PasswordAuthentication/PermitRootLogin/AllowUsers;客户端 ssh -vvv 逐步看协商。
  • 最有用的两个动作:客户端 ssh -vvv 看断在哪一步 + 服务端看 sshd 日志,两边对照。

踩坑 / 加分点

  • refused vs timeout 是排查方向的分水岭:refused = 已通到主机、是端口/应用层问题(sshd 没起、监听地址不对);timeout = 包被丢、往防火墙/安全组/路由查。答出这个区别立刻显功底。
  • 公钥登录失败 90% 是 ~/.ssh 或家目录权限太开(StrictModes)。家目录 777、.ssh 组可写都会让 sshd 静默拒绝公钥、回退密码,看着像"密钥没生效"。
  • Rocky/Alma/RHEL 系 vs Ubuntu/Debian 系差异是坑:日志前者在 /var/log/secure + 有 SELinuxauthorized_keys context 不对要 restorecon -Rv ~/.ssh),后者在 /var/log/auth.log + 无 SELinux(有 AppArmor)。
  • //var/tmp 磁盘满会让 SSH 登录失败或卡住(建不了会话、写不了 utmp/临时文件)——一个"看似认证问题"其实是磁盘满的经典串联坑。
  • 别只在客户端瞎试,一定上服务器看 sshd 日志和 ss 监听,否则永远在猜。

关联:本题在「场景排查型 题目1」有决策树版;ss/nc/防火墙命令见「11-网络诊断工具」。


锚点题 8:服务器从按下电源到出登录界面,中间发生了什么?#

为什么是锚点题:和「命令到输出」并列的两大"全过程"题。它把固件、引导、内核、initramfs、systemd 依赖体系全串起来,还直接连到"开机卡住/进不去系统怎么救"的实战。资深运维必问。

会串出的知识点地图

text
上电 → 登录界面
├── 固件 BIOS/UEFI:POST 自检 → 找启动设备(UEFI 读 ESP 的 .efi / BIOS 读 MBR)
├── Bootloader GRUB2:读 grub.cfg → 加载 vmlinuz + initramfs → 传内核参数(root=UUID..., ro)
├── 内核:解压初始化 → 挂 initramfs 当临时根
├── initramfs:装 LVM/RAID/LUKS/NVMe 等驱动 → 挂真正的根(先只读) → switch_root 切真根
├── systemd (PID 1):按 target 拉服务
│   ├── get-default(multi-user 命令行 / graphical 图形)
│   ├── 按 Wants/Requires/After/Before 解析依赖,能并行就并行
│   └── sysinit → basic → multi-user →(graphical):挂 fstab、起网络/日志/sshd
└── 登录:命令行 getty→login→PAM / 图形 gdm|sddm→桌面会话

考官追问链

  1. 现象层:开机大致分几个阶段?谁是第一个用户态进程?(固件→GRUB→内核→initramfs→systemd;PID 1 = systemd)
  2. 机制层:initramfs 是干嘛的、为什么需要它?(里面装了挂载真正根文件系统所需的驱动/模块,比如根在 LVM/RAID/加密盘/NVMe/NFS 上)
  3. 边界层:systemd 怎么决定服务启动顺序、为什么比老 SysV 快?(按 Wants/Requires + After/Before 解析依赖,无依赖的并行启动,不像 SysV 顺序跑脚本)
  4. 定位/验证层:开机很慢/卡住怎么排查?根挂不上掉进哪里、怎么救?(systemd-analyze blame/critical-chainjournalctl -b;根挂载失败掉进 initramfs/dracut 应急 shell,GRUB 里加 systemd.unit=rescue.target

参考答题骨架

  • 固件:BIOS/UEFI 上电自检(POST),初始化硬件,按启动顺序找设备——UEFI 从 ESP(EFI 系统分区)读 .efi 引导程序,BIOS 从 MBR 读引导代码。
  • Bootloader(GRUB2):读 grub.cfg,加载选定的内核 vmlinuzinitramfs 到内存,传内核命令行参数(root=UUID=...ro 等)。
  • 内核:解压、初始化,挂 initramfs 作为临时的内存根
  • initramfs:一个精简根环境,装着"挂载真正根文件系统"所需的驱动/模块(LVM、软 RAID、LUKS 加密、NVMe、根在 NFS 等)。加载驱动 → 找到并挂载真正的根(先只读)→ switch_root/pivot_root 切到真根。
  • systemd(PID 1):接管系统,按 target 拉起服务。默认 target 由 systemctl get-default 决定(multi-user.target 命令行 / graphical.target 图形)。按 Wants/Requires + After/Before 解析依赖,能并行的并行启动。关键链:sysinit → basic → multi-user →(graphical),其间挂载 /etc/fstab、起网络、日志、sshd 等。
  • 登录:命令行由 getty/agettylogin 提示 + PAM 认证;图形由 display-manager(gdm/sddm)接管 → 登录 → 桌面会话。
  • 排查/验证systemd-analyze(总耗时)、systemd-analyze blame(哪个服务拖慢)、systemd-analyze critical-chain(关键路径);journalctl -b(本次启动)、-b -1(上次)、-p err -b(只看错误)。开机卡住 → 进 GRUB 编辑内核参数(去掉 rhgb quiet 看详细,或加 systemd.unit=rescue.target/emergency.target 进救援)。

踩坑 / 加分点

  • 别再背 SysV init//etc/inittab/runlevel 那套。2026 的 Rocky/Alma/Ubuntu 早就是 systemd + GRUB2,用 systemctl(不是 service/chkconfig,虽有兼容层)。runlevel↔target 映射记一下:3=multi-user5=graphical
  • initramfs 里缺正确的存储驱动 → 根挂不上、直接开不了机——硬件迁移、P2V、内核升级后是高频事故。重建:RHEL 系 dracut -f,Debian 系 update-initramfs -u
  • 别手改 grub.cfg:改 /etc/default/grub 后再生成——RHEL 系 grub2-mkconfig -o /boot/grub2/grub.cfg,Debian 系 update-grub
  • UEFI vs BIOS 引导机制不同(ESP/efibootmgr vs MBR),装系统/修引导时启动方式搞错是经典坑。
  • systemd-analyze blame 会把 network-online 这类"等待型"服务算进去,容易误伤——判断真正瓶颈要看 critical-chain(关键路径),而不是单看 blame 排行。

关联:systemd 单元/依赖/target 见「13-服务管理systemd」;journalctl 用法见「15-日志与排查思路」。