Linux 常见面试题总结:权限、进程、性能与线上排障
前言
这是 JavaGuide 面试突击版本,只保留最常问的面试题,并对重点内容进行了 ⭐️ 标注。提供亮色和暗色两个主题,需要打印的朋友请选择亮色版本。
时间充裕的朋友,推荐使用 JavaGuide 网站系统学习,内容更全面深入。
如果你想要付费支持/面试辅导(比如简历优化、一对一提问、高频考点突击资料等)的话,欢迎了解我的知识星球。已经坚持维护六年,内容持续更新,虽白菜价(0.4元/天)但质量很高,主打一个良心!
面试突击最新版可在公众号回复「PDF」获取(知识星球会提前同步最新版)。

重要说明
本站所有面试题保持年度系统性优化完善,严格同步 Java 技术生态与招聘市场的最新动态,确保内容时效性与前瞻性。
这部分内容以 JavaGuide 的 Linux 基础知识总结 为基础,补充了后端面试常见的线上排障问题。操作系统原理相关内容见 操作系统常见面试题总结。
Linux 命令没有必要整本背。面试时更常见的问法是给出一个现象,让你说明先看什么、怎么缩小范围,以及哪些指标容易误判。
文件与权限
⭐️Linux 文件权限中的 r、w、x 分别表示什么?
Linux 把权限分为文件所有者(user)、所属组(group)和其他用户(others)三组,每组都可以配置读、写、执行权限。

对普通文件来说:
r:读取文件内容。w:修改文件内容。x:把文件作为程序执行。
对目录来说,含义有所不同:
r:读取目录项,可以列出目录中的名称。w:创建、删除或重命名目录项,通常还需要目录的x权限。x:进入或穿过目录,并访问已知名称的目录项。
因此,拥有某个文件的写权限,不代表一定能删除它。删除文件修改的是父目录中的目录项,主要取决于父目录权限,以及 Sticky Bit、ACL 等额外规则。
chmod 755 和 chmod 644 分别表示什么?
数字权限把 r、w、x 分别记为 4、2、1,再按所有者、所属组、其他用户三组相加:
| 权限 | 所有者 | 所属组 | 其他用户 | 常见用途 |
|---|---|---|---|---|
| 755 | rwx | r-x | r-x | 需要执行的脚本、公共可读目录 |
| 644 | rw- | r-- | r-- | 普通配置文件、文本文件 |
chmod -R 777 会把目录下的文件全部开放给所有用户读、写和执行,通常不应该用它解决权限报错。更合适的做法是确认进程用户、文件所有者、所属组、目录穿越权限和实际需要的最小权限。
⭐️硬链接和软链接有什么区别?
| 对比项 | 硬链接 | 软链接 |
|---|---|---|
| 指向对象 | 与原目录项指向同一个 inode | 保存另一个路径 |
| 跨文件系统 | 通常不支持 | 支持 |
| 链接目录 | 普通用户通常不能为目录创建硬链接 | 支持 |
| 原路径被删除 | 数据仍可通过其他硬链接访问 | 可能变成悬空链接 |
| inode | 与目标文件相同 | 链接本身有独立 inode |

删除一个文件名时,系统会取消对应目录项与 inode 的关联。只有链接计数归零,并且没有进程继续打开该文件时,内核才会回收相应数据块。
df 和 du 有什么区别?为什么结果可能不一致?
df从文件系统角度报告已用和可用空间。du遍历目录项,累计当前能够看到的文件占用空间。
两者差距较大时,常见原因包括:
- 文件已经删除,但仍被进程打开。目录中看不到它,数据块却还没有释放。
du没有权限读取部分目录。- 目录下面挂载了其他文件系统,统计范围与预期不同。
- 文件系统为特权用户保留了空间,或存在元数据、快照等额外占用。
排查“删除日志后磁盘仍然没释放”时,可以使用 lsof +L1 查找链接计数为 0、仍被进程打开的文件。处理对应进程或让它重新打开日志后,空间才会真正释放。
进程、信号与服务
如何查看和定位 Linux 进程?
常用命令各自解决的问题不同:
# 按固定格式查看进程快照
ps -ef
# 按 CPU 或内存动态观察进程
top
# 按名称查找 PID,并显示完整命令行
pgrep -af java
# 查看一个进程的启动参数
tr '\0' ' ' < /proc/1234/cmdlineps 适合脚本和一次性查询,top 适合观察一段时间内的变化。使用 grep 查进程时会把 grep 自身也匹配出来,已知进程名时可以优先使用 pgrep。
⭐️kill -15 和 kill -9 有什么区别?
kill 命令发送的是信号,不是只能“杀死进程”。
kill -15 PID发送SIGTERM。进程可以捕获该信号,并在退出前停止接流量、提交或回滚事务、刷新缓冲区和释放资源。kill -9 PID发送SIGKILL。该信号不能被捕获、阻塞或忽略,内核会直接终止进程,应用没有机会执行清理逻辑。
正常停机应先发 SIGTERM,等待一段合理时间;进程失去响应且无法正常退出时,再考虑 SIGKILL。即便使用 SIGKILL,处于不可中断睡眠状态的任务也可能要等内核中的 I/O 返回后才真正消失。
什么是僵尸进程?如何处理?
子进程退出后,内核会暂时保留退出状态和少量统计信息,等待父进程通过 wait() 一类系统调用回收。如果父进程一直不回收,子进程就会处于 Zombie 状态,ps 中通常显示为 Z。
僵尸进程已经不再执行代码,给它发送 SIGKILL 没有意义。应排查父进程为什么没有正确处理 SIGCHLD 或调用 wait();必要时重启或修复父进程。父进程退出后,僵尸进程会被其他 reaper 进程接管并回收。
单个僵尸进程几乎不占用用户态内存,但会占用 PID 和进程表项。持续大量产生时,最终可能无法创建新进程。
如何排查 systemd 管理的服务启动失败?
先看服务状态和本次启动后的日志:
systemctl status my-service
journalctl -u my-service -b --no-pager需要持续观察日志时可以使用:
journalctl -u my-service -f常见原因包括启动命令路径错误、工作目录不存在、端口占用、环境变量未加载、服务用户没有文件权限、依赖服务未就绪,以及进程启动后立即退出。
不要一看到失败就反复执行 systemctl restart。先保存状态、日志和退出码,重启可能会覆盖最有价值的现场信息。
⭐️什么是文件描述符?Too many open files 怎么排查?
文件描述符(File Descriptor,FD)是进程访问打开文件、Socket、管道等内核对象时使用的整数编号。标准输入、标准输出和标准错误通常对应 0、1、2。
出现 Too many open files,表示进程或系统达到了相关文件描述符限制。可以按下面的顺序检查:
# 查看进程限制
grep 'open files' /proc/1234/limits
# 查看进程当前打开的 FD
ls /proc/1234/fd | wc -l
# 查看 FD 指向什么对象
ls -l /proc/1234/fd
# 统计不同进程打开的文件数量
lsof -nP | awk '{print $2}' | sort | uniq -c | sort -nr | head提高 ulimit -n 只能缓解限制过低的问题。如果 FD 数量持续增长,还要检查连接、文件流、HTTP 响应体和数据库资源是否按时关闭。systemd 服务的限制通常还受单元文件中 LimitNOFILE 的控制,不能只修改登录 Shell 的 ulimit。
CPU、负载与线程
⭐️Linux 的 Load Average 表示什么?
uptime 和 top 通常会显示最近 1 分钟、5 分钟和 15 分钟的平均负载。Linux 负载统计的不只是正在使用 CPU 的任务,还包括:
- 正在运行或等待 CPU 的可运行任务。
- 处于不可中断睡眠状态的任务,这类任务经常在等待磁盘、网络存储或某些内核资源。
因此,负载高不等于 CPU 使用率一定高。判断是否异常时还要结合可用 CPU 数量、CPU quota、运行队列、I/O 等待和业务基线。一个 8 核实例的负载为 8,和一个 2 核实例的负载为 8,压力完全不同。
⭐️服务器 CPU 使用率达到 100%,如何排查?
可以沿着“主机 → 进程 → 线程 → 代码或请求”逐层缩小范围:
- 使用
top、mpstat -P ALL 1确认是单核打满还是所有 CPU 都忙,并区分用户态、内核态、中断和 I/O wait。 - 使用
top或pidstat -u 1找到高 CPU 进程,确认它是否属于当前服务。 - 使用
top -H -p PID或pidstat -t -p PID 1找到高 CPU 线程。 - 结合对应运行时的线程栈、Profiler、请求日志和监控继续定位。例如 Java 可以使用
jcmd PID Thread.print、JFR 或 async-profiler。 - 判断是死循环、热点计算、频繁 GC、锁竞争、自旋、序列化、正则回溯,还是流量增长导致的正常计算量上升。
排查期间要先控制影响,例如摘除故障实例、限流或停止异常任务。直接重启虽然可能恢复服务,但会丢失线程栈、性能采样和异常请求等现场证据。
⭐️Linux 上如何定位 Java 进程中最耗 CPU 的线程?
假设 Java 进程 PID 为 1234:
# 找到高 CPU 线程的十进制 TID
top -H -p 1234
# 把 TID 转成十六进制,例如 5678 -> 162e
printf '%x\n' 5678
# 输出 Java 线程栈
jcmd 1234 Thread.print再在线程栈中搜索 nid=0x162e,就能把 Linux 线程与 Java 线程对应起来。连续抓取几次线程栈,才能判断某段代码是否持续占用 CPU;只看一次快照可能碰巧采到正在工作的正常线程。
如果 CPU 消耗来自 JIT 编译线程、GC 线程或本地库,还要结合 GC 日志、JFR、perf 或 async-profiler 继续分析,不能只盯业务线程栈。
为什么负载很高,但 CPU 使用率不高?
这类现象常见于大量任务处于不可中断睡眠状态,也就是 ps 中的 D 状态。任务可能在等待磁盘、NFS、块设备或内核中的其他资源,计入 Load Average,却没有持续执行用户态代码。
可以检查:
vmstat 1
iostat -xz 1
ps -eo state,pid,comm,wchan:32 | awk '$1 ~ /^D/'vmstat 可以观察运行队列、阻塞任务、换页和 CPU 时间;iostat 用于查看块设备延迟和队列。wchan 能提供任务当前等待的内核位置,但符号是否可见受权限和内核配置影响。
top 中的 us、sy、wa 分别表示什么?
us:CPU 执行普通用户态代码的时间比例。sy:CPU 执行内核代码的时间比例。wa:CPU 空闲且系统存在未完成 I/O 请求的时间比例。
wa 高通常提示要检查 I/O,但它不等于磁盘设备利用率,也不能单独证明某块磁盘是瓶颈。虚拟化环境、并发设备数量和采样方式都会影响解释,需要继续查看设备延迟、队列长度、吞吐量和应用请求耗时。
内存与磁盘
⭐️free 很小,是否说明内存不足?
不一定。Linux 会把暂时不用的内存用于 Page Cache 等缓存,在应用需要时回收。判断还能否启动新应用时,应优先关注 MemAvailable 或 free 命令中的 available,而不是只看 free 列。
free -h
grep -E 'MemTotal|MemFree|MemAvailable|Cached|Swap' /proc/meminfo真正的内存压力通常还伴随 available 持续偏低、频繁回收、Swap 活跃、Major Page Fault 增多、请求延迟上升,甚至触发 OOM Killer。Page Cache 很大本身通常不是内存泄漏。
⭐️服务器内存占用持续升高,如何排查?
先确认问题发生在主机、容器还是某个进程,再看增长的是匿名内存、文件缓存、共享内存还是内核内存:
# 查看整体内存和换页活动
free -h
vmstat 1
# 按常驻内存排序进程
ps -eo pid,comm,rss,vsz,%mem --sort=-rss | head
# 查看目标进程的内存摘要
cat /proc/1234/status
cat /proc/1234/smaps_rollupRSS 表示当前驻留在物理内存中的页面,但共享页面可能在多个进程中重复计算。需要更准确归因时可以关注 PSS;smaps_rollup 会提供进程映射的汇总信息。
如果目标是 Java 进程,还要区分 Java 堆、Metaspace、线程栈、Direct Buffer、JIT Code Cache 和本地库内存。堆使用正常不代表进程 RSS 一定正常,可以结合 GC 日志、Heap Dump、Native Memory Tracking 和线程数量继续检查。
什么是 OOM Killer?如何确认进程是否被它终止?
系统内存严重不足且无法满足分配请求时,Linux 可能触发 OOM Killer,选择一个或多个任务终止以回收内存。选择结果会受内存占用、oom_score_adj、cgroup 限制等因素影响。
可以查看内核日志:
journalctl -k -g 'Out of memory|Killed process'
dmesg -T | grep -Ei 'out of memory|killed process'容器可能先触发 cgroup 范围内的 OOM,宿主机整体内存并未耗尽。排查时要同时检查容器内存上限、实际用量、退出码和编排平台事件。
Java 抛出 OutOfMemoryError 与进程被 Linux OOM Killer 终止也不是一回事。前者由 JVM 发现某个内存区域无法继续分配,通常会留下 Java 错误和堆栈;后者可能让进程直接收到 SIGKILL。
⭐️磁盘空间满了,应该如何排查?
先判断耗尽的是数据块还是 inode:
df -h
df -idf -h接近 100%:按挂载点继续定位大目录和大文件。df -i接近 100%:通常是海量小文件耗尽 inode,即使还有可用容量也无法创建新文件。
定位大目录时不要直接从根目录跨越所有挂载点扫描,可以先锁定文件系统,再逐层缩小:
du -xhd1 /var | sort -h
find /var/log -xdev -type f -size +1G -ls
lsof +L1确认文件用途和保留策略后再清理。线上环境还应检查日志轮转、临时文件生命周期、上传文件配额、监控告警和磁盘扩容预案,避免靠定期手工删除维持运行。
磁盘 I/O 很高,如何定位来源?
可以先用 iostat -xz 1 观察设备吞吐、请求延迟和队列,再使用 pidstat -d 1、iotop 等工具找出高 I/O 进程。定位到进程后,结合 lsof -p PID、应用日志和调用链判断它正在访问哪些文件。
读写量大不一定代表异常,备份、批处理和日志归档可能按计划产生大量顺序 I/O。真正需要关注的是业务延迟是否上升、设备请求是否排队、I/O 模式是否突然改变,以及某个后台任务是否挤占了在线流量。
网络与日志排查
⭐️如何查看某个端口被哪个进程占用?
推荐使用 ss:
# 查看 TCP 监听端口及对应进程
ss -lntp
# 查看 8080 端口
ss -lntp 'sport = :8080'
# 也可以按端口查看打开的网络文件
lsof -nP -iTCP:8080 -sTCP:LISTEN查看其他用户的进程信息通常需要相应权限。netstat 在老系统中仍然常见,但现代 Linux 通常优先使用 iproute2 提供的 ss。
⭐️访问一个服务超时,如何排查网络问题?
不要只执行一次 ping 就下结论。可以按调用链逐段验证:
- 域名解析:使用
dig或getent hosts确认域名解析结果和应用实际使用的地址一致。 - 路由与接口:使用
ip addr、ip route get 目标IP检查本机地址和出站路由。 - 端口连通:使用
nc -vz 主机 端口或curl -v测试 TCP/TLS/HTTP 的具体阶段。 - 服务监听:在服务端使用
ss -lntp确认进程监听的地址和端口。只监听127.0.0.1时,外部无法访问。 - 中间设备:检查安全组、防火墙、负载均衡、代理、Service Mesh 和 NAT 的规则及日志。
- 抓包验证:必要时使用
tcpdump判断 SYN 是否到达、握手卡在哪一步、是否发生重传或对端复位。
ping 使用 ICMP,目标网络可能禁用它;Ping 不通不代表 TCP 端口一定不通,Ping 正常也不能证明应用层服务正常。
Linux 中如何快速检索和跟踪日志?
根据问题选择命令,比背一串固定组合更有效:
# 持续跟踪文件,即使日志轮转后重新创建也继续读取
tail -F app.log
# 显示行号,忽略大小写搜索错误
grep -nEi 'error|exception|timeout' app.log
# 搜索 gzip 压缩后的历史日志
zgrep -n 'orderId=123' app.log.*.gz
# 查看 systemd 服务最近一小时的日志
journalctl -u my-service --since '1 hour ago'大文件检索时先限定时间、请求 ID、用户 ID 或业务主键,避免无条件解压和全量扫描所有历史日志。日志分散在多台机器时,应使用集中日志系统,并保留实例、Trace ID、时间、级别和服务名等可检索字段。
管道、重定向和 2>&1 分别是什么?
- 管道
|把前一个命令的标准输出连接到后一个命令的标准输入。 >把标准输出覆盖写入文件,>>表示追加。2>重定向标准错误。2>&1让文件描述符 2 指向文件描述符 1 当前指向的位置。
顺序会影响结果:
# 标准输出和标准错误都写入 app.log
command > app.log 2>&1
# 标准错误仍指向原来的终端,只有标准输出写入 app.log
command 2>&1 > app.log第一条命令先把标准输出指向文件,再让标准错误复制这个去向。第二条命令先让标准错误指向当时的标准输出,也就是终端,之后只修改标准输出。
综合排障
⭐️遇到线上 Linux 性能问题,通用排查思路是什么?
先确认现象和影响范围:是单个接口、单个进程、单台机器,还是整个集群;问题从什么时间开始,错误率、延迟、吞吐量和资源指标发生了什么变化。
接着按证据缩小范围:
- 用监控和
uptime、vmstat、top判断问题更接近 CPU、内存、I/O、网络还是外部依赖。 - 找到异常进程和线程,检查资源增长是否与流量、发布或定时任务一致。
- 把系统指标与应用日志、线程栈、GC 日志、慢查询和分布式追踪对齐到同一时间段。
- 先限流、摘实例、降级或停止异常任务,控制故障影响;同时尽量保留现场。
- 修复后通过相同指标验证恢复情况,并补充告警、容量评估、故障演练和回滚方案。
面试回答中只罗列 top、free、df、netstat 通常不够。需要说明每个命令验证什么假设,以及看到不同结果后下一步怎么走。
容器里的 CPU 和内存指标为什么可能与宿主机不同?
容器中的进程仍由宿主机 Linux 内核调度,cgroup 决定它能使用的 CPU、内存和 I/O 等资源。容器看到的 CPU 数量、Load Average、free 输出与实际 quota 或内存上限不一定完全一致,具体表现还受运行时和工具版本影响。
cgroup v2 环境下,可以从当前 cgroup 对应目录查看 cpu.max、memory.current、memory.max 和 memory.events 等文件。排查容器问题时,应同时对照:
- 宿主机是否整体资源不足。
- 容器是否触发 CPU Throttling 或内存上限。
- 编排平台设置的 Request、Limit 和实例数量是否合理。
- JVM 等运行时是否正确识别容器限制。
只看宿主机资源还有大量空闲,不能排除某个容器已经被限流或发生 cgroup OOM。
参考资料
- JavaGuide:Linux 基础知识总结
- Linux Kernel:The
/procFilesystem - Linux Kernel:Control Group v2
- Linux man-pages:signal(7)
- Linux man-pages:proc_pid_fd(5)
- systemd:systemctl
- systemd:journalctl
- GNU Coreutils Manual
- iproute2:ss(8)
写在最后
感谢你能看到这里,也希望这篇文章对你有点用。
JavaGuide 坚持更新 6 年多,近 6000 次提交、600+ 位贡献者一起打磨。如果这些内容对你有帮助,非常欢迎点个免费的 Star 支持下(完全自愿,觉得有收获再点就好):GitHub | Gitee。
如果你想要付费支持/面试辅导(比如简历优化、一对一提问、高频考点突击资料等)的话,欢迎了解我的知识星球。已经坚持维护六年,内容持续更新,虽白菜价(0.4元/天)但质量很高,主打一个良心!


