这是《Linux 零基础实战指南》的独立章节版。本章从概念、实操和生产排查三个视角展开,代码块保留了原书可直接运行的版本。 Linux 面试不是背命令,而是考你能否从现象出发分层定位,能否解释指标含义,能否处理生产风险。本章按主题整理高频问题和回答思路。
30.1 基础命令
问题:load average 高怎么办?
回答思路:
1. 和 CPU 核数比较
2. 看 us/sy/wa/st
3. 看 r 和 b 队列
4. 定位进程和线程
5. 区分 CPU、IO、D 状态、虚拟化抢占
命令:
uptime
nproc
vmstat 1
pidstat -u 1
加分点:load 包含不可中断任务,高 load 不一定是 CPU 不足。
问题:磁盘空间不足如何排查?
df -hT
df -ih
du -sh /var/* /opt/*
lsof +L1
find / -xdev -type f -size +1G -ls
加分点:同时检查容量和 inode,注意已删除但仍被占用的文件。
30.2 权限与用户
问题:Permission denied 怎么排查?
id
ls -ld /opt/app /opt/app/conf
ls -l /opt/app/conf/app.yml
getfacl /opt/app/conf/app.yml
sudo -u app cat /opt/app/conf/app.yml
回答要点:
- 检查用户和组;
- 检查路径每一级目录执行权限;
- 检查文件权限和 ACL;
- 检查 SELinux 或 AppArmor;
- 用目标用户验证。
问题:sudo 和 su 的区别?
| 项 | sudo | su |
|---|---|---|
| 授权 | 当前用户密码或免密规则 | 目标用户密码 |
| 粒度 | 可限制命令 | 通常切换完整身份 |
| 审计 | sudo 日志 | 需要额外审计 |
| 原则 | 最小授权 | 便于共享 root,风险高 |
30.3 进程与信号
问题:kill -9 和 kill -15 区别?
SIGTERM 可被捕获,应用可以摘流、处理存量请求、释放资源。SIGKILL 不可捕获,进程立即终止,可能丢数据或留下锁。
生产顺序:
SIGTERM
-> 等待
-> 超时 SIGKILL
问题:进程退出码 137 是什么?
通常表示 128 + 9,即收到 SIGKILL。常见于编排系统超时停止或 OOM Killer。需要查:
dmesg -T | grep -Ei 'oom|killed process'
journalctl -u app
kubectl describe pod <pod>
30.4 文件系统
问题:软链接和硬链接区别?
| 项 | 硬链接 | 软链接 |
|---|---|---|
| 指向 | inode | 路径 |
| 跨文件系统 | 通常不可 | 可以 |
| 目录 | 一般不允许 | 可以 |
| 目标删除 | 数据仍可访问 | 可能悬空 |
问题:删除大日志为什么磁盘没释放?
文件名是目录项,进程持有 fd 时 inode 和数据块不会释放。
lsof +L1
ls -l /proc/<pid>/fd
处理:重载日志组件或安排重启,并修复轮转策略。
30.5 内存
问题:free 里 buffer/cache 高是否异常?
不一定是异常。Linux 用空闲内存做页缓存,提高读写性能。判断要看 available、swap、major fault 和 OOM。
free -h
vmstat 1
cat /proc/meminfo
问题:容器 OOMKilled 如何排查?
kubectl describe pod <pod>
cat /sys/fs/cgroup/<path>/memory.events
cat /sys/fs/cgroup/<path>/memory.stat
方向:
- memory limit 太小;
- 堆设置过大;
- 堆外内存泄漏;
- 请求量上升;
- 页缓存和内核内存计入 cgroup。
30.6 IO
问题:如何判断磁盘慢?
iostat -xz 1
pidstat -d 1
cat /proc/meminfo | grep -E 'Dirty|Writeback'
关注:
- await;
- util;
- 队列深度;
- IOPS 和吞吐;
- 进程写入量;
- 云盘规格。
加分点:多队列设备 util 100% 不一定代表饱和,await 和延迟分布更重要。
30.7 网络
问题:服务访问不通怎么排查?
DNS -> TCP -> TLS -> HTTP -> upstream
dig api.example.com
nc -vz api.internal 8080
openssl s_client -connect api.example.com:443 -servername api.example.com
curl -v --resolve api.example.com:443:192.0.2.10 https://api.example.com/healthz
ss -lntp
sudo tcpdump -ni any host <peer> and port <port>
加分点:区分云安全组、主机防火墙、conntrack、服务监听和应用拒绝。
问题:TIME_WAIT 和 CLOSE_WAIT 大量出现说明什么?
TIME_WAIT 通常在主动关闭方,常见于高频短连接,影响临时端口。
CLOSE_WAIT 在被动关闭方,对端已关闭而本端应用没有关闭 socket,通常是代码资源泄漏。
处理重点:
| 状态 | 重点 |
|---|---|
| TIME_WAIT | 连接池、长连接、复用、容量 |
| CLOSE_WAIT | 应用关闭逻辑 |
30.8 systemd
问题:为什么 systemd 服务读不到环境变量?
systemd 服务不是登录 Shell,不读取 ~/.bashrc 或 ~/.bash_profile。
正确方式:
[Service]
Environment="JAVA_HOME=/opt/java"
EnvironmentFile=-/etc/order/env
修改后:
sudo systemctl daemon-reload
sudo systemctl restart order
问题:daemon-reload 和 restart 区别?
daemon-reload 重新读取 unit 配置;restart 重启服务进程。修改 unit 后通常先 reload systemd,再 restart 服务。
30.9 安全
问题:服务器被入侵后第一件事做什么?
回答思路:
1. 确认影响面和是否仍在活动
2. 隔离主机,保留证据
3. 保护日志和内存现场
4. 禁用异常账号和 key
5. 轮换凭据
6. 排查横向移动
7. 按应急流程通知
不建议:在被控主机上反复手工安装工具或直接重装导致证据丢失。
问题:如何做 SSH 加固?
要点:
- 禁 root 登录;
- 禁密码登录;
- 只允许可信来源;
- 使用密钥或短期证书;
- MFA;
- 跳板机;
- sudo 最小授权;
- 集中审计;
- 保留会话修改配置。
30.10 场景设计
问题:设计一台 Java 应用服务器
回答框架:
用户:独立 app 用户
目录:releases + shared + logs + current
服务:systemd Type=simple
资源:LimitNOFILE、MemoryMax、CPUQuota
内存:堆占上限约 65%,预留堆外和系统
日志:结构化 + 轮转 + 采集
网络:只开放必要端口
发布:版本目录 + 灰度 + 回滚
监控:主机 + JVM + 应用 + 业务
问题:优化一次 P99 延迟上升
回答框架:
1. 确认影响范围和开始时间
2. 查发布、配置、流量、依赖变更
3. 看黄金指标
4. 检查 CPU throttling、GC、IO、网络
5. 抓应用 trace 定位慢请求
6. 复现或压测验证
7. 灰度修复
8. 前后指标对比
本章小结
Linux 面试要展示分层思维、证据意识、风险控制和生产经验。回答问题时先说判断路径,再给命令和原理,最后补充止损和复盘。
思考题
- 你如何回答“服务器慢”?
- CLOSE_WAIT 大量出现时应该检查什么?
- 如何证明磁盘是瓶颈?
- systemd 环境变量为什么和登录 Shell 不同?
- 为团队整理五个最常见的 Linux 应急场景。