路线图

面试 · 概念解释型

星辉 2026-07-02 阅读 6 min 1,103 字 路线图
面试 · 概念解释型 封面

考察目标:用自己的话讲清楚核心概念 24 题


题目1:什么是 inode?删文件为什么不等于删数据?#

参考答案

inode 是 Linux 文件系统的"身份证",存储文件的元数据(权限、大小、时间戳、数据块指针),不存文件名。文件名存于目录项中,目录项指向 inode。

删文件的本质是删除目录项(文件名),不是删除 inode。只有当 inode 的硬链接计数降为 0 且没有进程打开文件时,内核才真正释放数据块。

这在运维中常引发一个现象:df -h 显示磁盘满,但 du -sh 加起来远小于磁盘容量——因为有进程持有已删除文件的句柄,用 lsof | grep deleted 可以找到这些"幽灵文件"。


题目2:软链接和硬链接有什么区别?#

维度软链接 (symlink)硬链接 (hard link)
本质一个独立的文件,内容是目标路径同一个 inode 的多个目录项
跨文件系统支持不支持
链接目录支持不支持(防止环路)
删源文件后链接失效(断链)不受影响,数据仍存在
inode独立 inode共享 inode
链计数不影响每次 +1

运维中软链接常用于 /usr/bin/python/usr/bin/python3/etc/nginx/sites-enabled/sites-available/ 等场景。硬链接较少手工创建,常见于 rsync --link-dest 做增量备份。

完整对比表见「对比辨析型 题目1」,底层实现(i_nlink / S_IFLNK / 为何硬链接不能跨文件系统、不能链目录)见「原理追问型 题目6」。


题目3:SUID、SGID、Sticky bit 分别是什么意思?#

参考答案

特殊权限数字文件目录
SUID4以文件属主权限执行无意义
SGID2以文件属组权限执行新建文件继承目录属组
Sticky1无意义只有属主能删自己的文件

典型例子:/usr/bin/passwd 有 SUID(属主 root),普通用户执行时以 root 权限修改 /etc/shadow/tmp 有 Sticky bit(1777),任何人都可写但只能删自己的文件。SGID 目录常用于团队共享目录(/var/www 设 SGID,新建文件自动归属 www-data 组)。

高频易错点SUID 对脚本无效——Linux 内核出于安全(解释器竞态、注入风险)忽略脚本文件的 SUID 位,只对编译型二进制生效。想让脚本以高权限运行,用 sudo 规则或 capabilities(见题目23),而不是给脚本 chmod u+s。


题目4:Linux 进程状态 R/S/D/Z/T 各是什么?D 状态为什么 kill -9 也杀不掉?#

参考答案

状态含义典型原因
RRunning/就绪正在 CPU 或等待 CPU
SInterruptible Sleep等待事件(IO/信号),可被中断
DUninterruptible Sleep等待内核 IO 完成,不可中断
ZZombie进程已退出,父进程未回收
TStopped被 SIGSTOP/Ctrl+Z 暂停

D 状态不可 kill:进程正在内核态等待 IO 完成(如 NFS 无响应、磁盘故障),信号被挂起直到 IO 完成才处理。kill -9 的原理是发信号,而 D 状态的进程不处理任何信号。只能等 IO 超时(通常 120 秒)或重启节点。K8s 中 NFS PV 挂载故障常导致 Pod 卡在 Terminating 就是这个原因。


题目5:Linux 内存管理中 Buffer 和 Cache 有什么区别?#

参考答案

  • Buffer(缓冲区):缓存块设备的元数据(inode、目录项),解决写操作的缓冲问题
  • Cache(页缓存):缓存文件内容,解决读操作的加速问题

free -h 看到的 buff/cache 是两者之和。关键认知:Linux 会主动用空闲内存做缓存,available 内存才是真正可用的(available ≈ free + 可回收 buff/cache)。echo 3 > /proc/sys/vm/drop_caches 可手动释放(生产慎用)。


题目6:什么是 Swap?什么时候该用什么时候不该用?#

参考答案

Swap 是磁盘上的"虚拟内存",当物理内存不足时内核将不活跃的内存页换出到磁盘。如果物理内存充足,Swap 用作安全余量;如果内存紧张但程序必须运行,Swap 让系统不会立即 OOM Kill。

该用的场景:小内存机器跑非延迟敏感服务、数据库等有突发内存需求的服务。 不该用的场景:高性能计算/GPU 训练(Swap 严重拖慢速度)、对延迟敏感的服务。

生产建议:普通服务器不必彻底关 Swap,调 vm.swappiness=1 让内核尽量不用它。但 K8s 有坑:kubelet 默认 failSwapOn=true,节点上开着 Swap 会直接拒绝启动;Swap 支持从 1.22 alpha、1.28 beta 起才逐步可用,需显式 failSwapOn: false + NodeSwap 特性开关(1.34 已 GA/stable,LimitedSwap 模式)。所以传统 K8s 节点的标准做法仍是关 Swap,别想当然给它留 Swap。


题目7:systemd 替代 SysV init 解决了什么问题?#

参考答案

SysV init 的问题:

  1. 串行启动:按 /etc/rc.d/rcX.d/S##name 顺序逐个启动,几百个服务按顺序等,启动极慢
  2. 无依赖管理:只能人工保证启动顺序,没有自动依赖解析
  3. 进程管理弱:服务 fork 后 init 不知道它在哪,状态跟踪困难
  4. 日志分散:每个服务各自写 /var/log/xxx.log

systemd 的改进:

  1. 并行启动:自动解析依赖 DAG,无依赖的服务同时启动
  2. cgroup 集成:每个 service 一个 cgroup,进程绝不逃脱跟踪
  3. 统一日志:journalctl 统一管理所有服务日志
  4. socket/timer/dbus 激活:按需启动,不用开机全拉起来

题目8:Linux 启动过程是怎样的?#

参考答案

text
BIOS/UEFI → Bootloader(GRUB) → Kernel 加载 → initramfs → systemd(pid=1) → 启动服务

关键阶段:

  1. BIOS/UEFI:硬件自检,找到引导设备
  2. GRUB:加载内核映像 + initramfs 到内存
  3. Kernel:初始化驱动、挂载根文件系统(先只读)
  4. initramfs:临时的根文件系统,包含必需驱动(如 RAID/LVM 模块),帮助挂载真正的根文件系统
  5. systemd:作为 PID=1 启动,并行启动所有 target 依赖的服务

排查启动问题时常用 systemd-analyze blame 看服务耗时排序,dmesg 看内核阶段日志。


题目9:什么是 /proc 文件系统?列出 3 个你常用的 /proc 文件#

参考答案

/proc 是伪文件系统(pseudo filesystem),不占磁盘,内容由内核动态生成,是内核与用户空间的信息接口。

常用文件:

  1. /proc/cpuinfo — CPU 型号/核心数/缓存
  2. /proc/meminfo — 内存详细信息(比 free 更细)
  3. /proc/<pid>/status — 进程状态/内存/VmRSS
  4. /proc/<pid>/oom_scoreoom_score_adj — OOM 优先级
  5. /proc/sys/net/ipv4/tcp_tw_reuse 等 — 内核参数调优
  6. /proc/mounts — 当前挂载表

运维常用场景:查看容器内 CPU 核数 → nproc(实际读 /proc/cpuinfo),查进程 OOM 风险 → cat /proc/<pid>/oom_score


题目10:硬链接创建/删除时 inode 链接计数怎么变?#

参考答案

硬链接每 ln 一次,inode 的链接计数(i_nlink+1ls -l 第二列、statLinks 就是它。rm 本质是 unlink(),让计数 -1;当计数降为 0 且无进程打开该文件时,内核才回收 inode 和数据块(这正是「删了大文件空间没释放」的成因,见「场景排查型 题目8」)。软链接是独立 inode,不触碰目标的链接计数,删源文件后变断链。

验证

bash
touch a;  stat -c %h a     # 1
ln a b;   stat -c %h a     # 2(同一 inode 多了个名字)
rm b;     stat -c %h a     # 1

软/硬链接的完整对比见「对比辨析型 题目1」,底层实现见「原理追问型 题目6」。


题目11:Linux 的 IO 调度算法有哪些?什么时候用哪个?#

算法原理适用场景
none (noop)FIFO 简单队列SSD/NVMe,硬件自己调度
mq-deadline读写分开 + 截止时间混合负载 SATA SSD
bfq按 cgroup 公平分配带宽多租户/桌面系统
kyber基于延迟目标的调度低延迟敏感

cat /sys/block/sda/queue/scheduler 查看当前调度器。NVMe 盘建议 none(内核 5.0+ 对 NVMe 默认无调度器)。


题目12:什么是 cgroup?v1 和 v2 的主要区别?#

参考答案

cgroup(Control Group)是 Linux 内核的资源限制/隔离机制,用于限制进程组的 CPU、内存、IO 等资源。容器(Docker/K8s)的底层资源隔离依赖 cgroup。

v1 vs v2

  • v1:每个资源控制器(CPU/memory/blkio)独立的层级树,互不感知,存在"no internal process"限制
  • v2:单一统一层级树,所有控制器共享,支持 cgroup 线程模式,内存控制器增强(PSI 压力通知)

cgroup v2 在 K8s 1.25 GA(成为标准路径,但不是强制——v1 仍受支持);v1 已在 1.31 进入维护模式、并计划在 1.36 彻底移除(届时仍用 v1 的节点 kubelet 将无法启动)。查看当前版本:stat -fc %T /sys/fs/cgroupcgroup2fs=v2),或 mount | grep cgroup2(有输出即 v2)。


题目13:Linux 的实际内存和虚拟内存分别是什么?#

参考答案

实际内存(RSS, Resident Set Size):进程实际占用的物理内存页。ps aux 的 RSS 列或 /proc/<pid>/status 的 VmRSS。

虚拟内存(VSZ, Virtual Size):进程"认为自己可以用的"地址空间,包括映射的共享库、mmap、堆和栈。通常 VSZ >> RSS。

K8s 中的 OOMKill 基于容器 cgroup 的实际内存使用量(不是 RSS),超过 Limit 就杀。cat /sys/fs/cgroup/memory/memory.usage_in_bytes 可查看。


题目14:什么是内核参数 sysctl?常调哪些?#

参考答案

sysctl 是运行时修改内核参数的工具,对应 /proc/sys/ 下的文件。永久生效写 /etc/sysctl.conf/etc/sysctl.d/

常用调优:

参数作用
net.ipv4.tcp_tw_reuseTIME_WAIT 连接复用1
net.core.somaxconnlisten 全连接队列(accept 队列)上限;半连接队列由 tcp_max_syn_backlog65535
vm.swappiness倾向使用 Swap 的程度1-10
vm.max_map_countmmap 数量上限(ES 需要)262144
fs.file-max系统级文件描述符上限6553500
fs.inotify.max_user_watches文件监控数限制524288

应用方式:sysctl -w net.ipv4.tcp_tw_reuse=1(临时)或 echo "net.ipv4.tcp_tw_reuse=1" >> /etc/sysctl.conf && sysctl -p(永久)。


题目15:Linux 文件系统 ext4 和 xfs 的区别?什么时候选哪个?#

维度ext4xfs
最大文件系统1EB8EB
最大文件16TB8EB
在线扩容resize2fsxfs_growfs
缩容✅ 但须卸载离线resize2fs 缩小完全不支持缩小(只能备份重建)
性能小文件好大文件/高并发好
碎片更少更多
推荐通用场景大文件(数据库/日志/对象存储)

创建:mkfs.ext4 / mkfs.xfs关键差异:xfs 只能扩不能缩(xfs_growfs);ext4 更灵活(resize2fs 在线扩、离线缩)。默认文件系统:RHEL/Rocky/Alma 8·9、AWS AL2 默认 xfs(注意 CentOS 7 已于 2024-06-30 EOL,别再当"当前主流")。选盘时若预期可能要缩容,选 ext4。


题目16:什么是信号?列出 5 个常用信号及其含义#

参考答案

信号编号含义能否捕获
SIGTERM15终止进程(优雅退出),默认
SIGKILL9强制终止,不可捕获
SIGHUP1挂断,常用于重载配置
SIGINT2Ctrl+C 中断
SIGQUIT3Ctrl+\ core dump 退出
SIGSTOP19暂停进程
SIGCONT18继续暂停的进程

kill <pid> 不带参数默认发的就是 SIGTERM(不是 SIGKILL)。K8s 中 Pod 终止流程:先发 SIGTERM,等 terminationGracePeriodSeconds(默认 30s),超时后发 SIGKILL。应用需要在代码中捕获 SIGTERM 做 graceful shutdown。

进程被信号杀死的退出码约定 128+信号号(137=128+9 被 KILL、143=128+15 被 TERM、130=128+2 Ctrl+C),详见「原理追问型 题目8」。


题目17:什么是 Runlevel?target 和 runlevel 的对应关系?#

参考答案

Runlevel 是 SysV init 的系统运行级别(0-6),systemd 用 target 替代:

Runleveltarget含义
0poweroff.target关机
1rescue.target单用户救援模式
3multi-user.target多用户命令行
5graphical.target多用户图形界面
6reboot.target重启

systemctl get-default 查看默认 target,systemctl set-default multi-user.target 设置为命令行启动。


题目18:什么是 umask?为什么新建文件默认 644、目录 755?#

参考答案

umask 是"权限遮罩"——它是按位清除最终权限 = 默认权限 AND (NOT umask)),不是算术减法。默认权限:文件 666、目录 777(文件天生不给 x 位,安全考虑)。umask=022 时:

  • 文件 666 & ~022 = 666 & 755 → 644(rw-r--r--)
  • 目录 777 & ~022 = 777 & 755 → 755(rwxr-xr-x)

为什么必须强调"按位"而非"相减":022 这种"干净"掩码下两种算法结果碰巧相同,换成 umask 023 就露馅:

  • 按位(正确):文件 666 & ~023 = 644
  • 相减(错误):666 − 023 = 643(rw-r---wx,凭空算出个 x 位,荒谬)

umask(无参)看当前值,umask 027 临时设置;系统默认在 /etc/login.defsUMASK/etc/profile 或 PAM 的 pam_umask 中配置。


题目19:什么是 SSH 免密登录?ssh-keygen 做了什么?#

参考答案

SSH 免密登录基于非对称加密:用户生成公钥/私钥对,公钥放在远程服务器的 ~/.ssh/authorized_keys,连接时客户端用私钥签名,服务器用公钥验证。

过程:

  1. ssh-keygen -t ed25519 生成密钥对(推荐 ed25519,比 RSA 更安全更快)
  2. ssh-copy-id user@host 将公钥追加到远端 authorized_keys
  3. 之后的 ssh 连接用私钥认证,不再需要密码

运维场景:免密登录用于 Ansible、rsync 备份、Git SSH 拉取。私钥权限必须为 600(chmod 600 ~/.ssh/id_ed25519)。


题目20:文件描述符是什么?为什么 Linux 说"一切皆文件"?#

参考答案

文件描述符(File Descriptor, FD)是内核为每个进程维护的打开文件的整数索引。0=stdin、1=stdout、2=stderr(这三个标准 FD)。

"一切皆文件"意味着 Linux 把网络连接(socket)、管道(pipe)、设备(/dev/sda)、进程信息(/proc)都抽象为文件描述符,可以用统一的 read()/write()/close() 系统调用操作。

运维影响:ulimit -n 限制进程最大文件描述符数(含 socket 连接),当达到上限时出现 "Too many open files"。K8s 中 NOFILE 需要调大(如 1048576)。cat /proc/<pid>/limits 查看进程限制。


题目21:Linux 怎么添加到开机自启动?#

参考答案

systemd 时代的标准方法:

bash
# 1. 创建 service unit 文件
sudo vim /etc/systemd/system/myapp.service
# 2. 重载 systemd
sudo systemctl daemon-reload
# 3. 设为开机自启
sudo systemctl enable myapp

非 systemd 方式(备用):

  • crontab -e@reboot /path/to/script
  • /etc/rc.local(需 chmod +x

K8s 中开机自启由 kubelet 实现——节点启动后 kubelet 自动拉取并运行 DaemonSet、Deployment。


题目22:/etc/fstab 是什么?格式怎么读?#

参考答案

/etc/fstab 是文件系统挂载表,定义开机自动挂载的设备和选项。格式:设备 挂载点 文件系统 选项 dump pass

fstab
UUID=xxx   /          xfs   defaults      0 1
UUID=yyy   /data      ext4  defaults,noatime 0 2
192.168.1.1:/nfs   /mnt/nfs   nfs   defaults  0 0

pass 字段:1=根分区先检查,2=其他分区,0=不检查。生产注意:NFS/CIFS 网络挂载应加 _netdev,noauto 避免网络不可达时阻塞启动。


题目23:ugo 权限不够用时,ACL 和 capabilities 各解决什么问题?#

参考答案

传统 ugo(属主/属组/其他)只能表达三类主体,粒度太粗。两个"超越 ugo"的机制:

1. ACL(访问控制列表)——给单个用户/组单独授权,突破"一个文件只能属一个组"的限制。

bash
setfacl -m u:alice:rw file      # 单独给 alice 读写
setfacl -m g:dev:rx  dir        # 给 dev 组读+执行
getfacl file                    # 查看;ls -l 权限位末尾带 + 号即表示有 ACL
setfacl -d -m u:alice:rw dir    # default ACL:目录内新建文件自动继承

需文件系统挂载支持 acl(ext4/xfs 现代默认已开)。

2. capabilities(能力)——把 root 的"全能"拆成约 40 个细粒度能力,让程序只拿它需要的那一点特权,替代危险的 SUID-root。

bash
setcap 'cap_net_bind_service=+ep' /usr/sbin/nginx   # 不用 root 就能监听 80/443
getcap /usr/sbin/nginx

常见能力:CAP_NET_BIND_SERVICE(绑 <1024 端口)、CAP_NET_RAW(ping/抓包)、CAP_DAC_OVERRIDE(无视文件权限)、CAP_SYS_ADMIN("新 root",最危险)。

面试点:题目3 讲过 SUID 对脚本无效、且 SUID-root 是"全有或全无"的巨大攻击面;capabilities 只授予二进制真正需要的那一个能力,是更安全的替代。容器安全里 securityContext.capabilities.drop: ["ALL"] 再按需 add 就是这个思路。


题目24:systemd 的 unit 有哪些类型?enable 和 start 什么区别?journalctl 日志怎么持久化?#

参考答案

unit 类型(按后缀):.service(守护进程)、.socket(套接字激活)、.timer(定时任务,替代 cron)、.mount/.automount(挂载)、.target(一组 unit 的集合,替代 runlevel)、.path(路径变化触发)、.device.slice(cgroup 资源分片)。

enable vs start(高频混淆):

  • systemctl start立即启动,重启后不保留
  • systemctl enable:创建开机自启软链接(写入 *.wants/),不影响当前是否在跑
  • 两者都要 → systemctl enable --now myapp

daemon-reload:改了 unit 文件后必须 systemctl daemon-reload 让 systemd 重读,否则用的还是旧配置(改完直接 restart 却没生效,多半是漏了这步)。

journalctl 持久化:默认 Storage=auto——若 /var/log/journal/ 目录不存在,日志只存内存(/run/log/journal),重启即丢。开启持久化:

bash
mkdir -p /var/log/journal
systemctl restart systemd-journald    # 或在 journald.conf 里设 Storage=persistent
journalctl --list-boots               # 能看到历史 boot 才算持久化成功
journalctl -u myapp -b -1             # 看上一次开机时该服务的日志

小结#

概念解释型题目重在"说清楚本质 + 给实际例子"。Linux 核心概念(inode/进程状态/信号/cgroup/文件描述符)承载了容器、K8s、可观测性等上层技术的基础理解,面试中能讲清楚这些说明基础扎实。