Linux 面试题
Linux 面试题
九、Linux 与容器
入门(补齐 20 题)
★ 绝对路径与相对路径区别? 绝对路径从根目录开始,相对路径依赖当前工作目录。脚本启动时明确工作目录,避免服务和终端运行得到不同文件。
文件描述符是什么? 进程用于访问文件、socket、管道等的整数句柄;0/1/2 通常是标准输入/输出/错误。句柄耗尽会影响新文件和连接。
★ 文件权限 rwx 怎么解释? 对文件是读、写、执行;对目录是列目录、改目录项和搜索/进入。只给文件可读但父目录无搜索权限,仍可能无法读取。
用户和用户组做什么? 用 UID/GID 表示身份和基本权限关系;容器内外同名用户不保证同 UID,挂载目录按数值身份决定访问。
硬链接与软链接区别? 硬链接共享 inode,通常不能跨文件系统;软链接是指向路径的独立对象,可悬空。删除一个名字不一定释放底层文件。
★ 管道和重定向是什么? 管道把前一进程输出接到后一进程输入;重定向选择文件描述符的目标。stdout/stderr 分别处理,别把错误日志当业务数据。
进程 PID 与 PPID 是什么? PID 标识进程,PPID 标识父进程;线程和命名空间会影响看到的 ID。PID 可重用,持久业务身份不能只用它。
★ kill 是杀进程命令吗? 本质是发信号,默认通常 SIGTERM;能用于通知进程清理和重载。SIGKILL 不可捕获,不能指望 finally 一定执行。
前台、后台与守护有什么区别? 终端后台不等于受可靠监管,退出终端可能影响子进程。长期服务由 systemd/编排器管理生命周期和日志。
环境变量会自动同步吗? 子进程通常继承创建时的环境,之后父进程修改不自动传播。变量值常是字符串,配置变更需重新加载或重启。
★ df 和 du 为什么不同? df 看文件系统分配,du 遍历可见文件。已删除但仍打开的文件、挂载覆盖和权限都可能造成差异。
inode 用完会怎样? 还有字节空间也可能无法创建文件;大量小文件会消耗 inode。用 df -i 等检查,清理先确认文件用途和保留规则。
★ load average 等于 CPU 使用率吗? 不是,Linux 中还包含部分不可中断等待任务;结合 CPU、运行队列和 IO 判断。8 核 load=4 与 1 核 load=4 含义不同。
内存 available 和 free 区别? free 是当前空闲,available 估可供应用使用的内存,含可回收部分;缓存不等于泄漏,容器还要看 cgroup 限制。
★ 怎么确认端口谁在监听? 用 ss/lsof 等查看地址、端口与进程,区分 127.0.0.1 和 0.0.0.0。容器内监听与宿主发布端口分别检查。
软限制和硬限制是什么? ulimit 相关软限制是当前生效值,硬限制是普通进程可提升的上界;systemd 与容器可能另有配置,需看实际进程。
僵尸进程与孤儿进程区别? 僵尸已退出待父进程回收,孤儿的父进程已退出后被接管。二者处理方法不同,僵尸本身不能再被 kill 杀一次。
★ 文件系统大小写问题在哪? Linux 常见文件系统区分大小写,某些本机默认配置不同。导入路径和资源名大小写不一致可能只在部署后失败。
为什么日志轮转有时不释放空间? 应用可能继续持有旧文件描述符,或轮转方式与日志程序不兼容。检查打开文件再按服务能力重开,不能只反复 rm 文件。
★ 为什么排障先收证据? 重启可能清掉内存、连接与时间线,先记录状态、日志和资源,再按影响止血。证据中去除凭证和个人数据。
中等
常用排查命令?
top/htop(CPU、内存)、free -h、df -h/du -sh *(磁盘)、ss -tnlp/netstat(端口和连接)、lsof -p <pid>(打开的文件)、ps aux | grep、tail -f/grep/awk(日志)、iostat(磁盘 IO)、vmstat、strace -p <pid>(系统调用)、curl -v。进程和线程? 进程是资源分配单位(独立地址空间),线程是调度单位(共享进程的内存)。
fork 和写时复制? fork 复制出子进程,父子共享物理内存页,任何一方写某页时才复制那一页。Redis 的 RDB、gunicorn 的
--preload都利用它。Docker 的原理? namespace 做隔离(PID、网络、挂载、UTS、IPC、用户)+ cgroup 做资源限制(CPU、内存)+ 联合文件系统(镜像分层)。容器和虚拟机的区别:容器共享宿主机内核,轻量、启动快,隔离弱一些。
Dockerfile 优化? 多阶段构建;变化少的层放前面(先装依赖再拷代码);
.dockerignore;合并 RUN 减少层数;slim 基础镜像。★ 怎么区分 CPU 忙和 IO 等待? 结合 top、vmstat、iostat 和进程状态,看 user/sys/iowait、运行队列与磁盘延迟;单个总体 CPU 百分比不足以定位。
如何定位高 CPU 线程? 找到 PID 后看线程级使用,再用语言 profiler/栈对应热点。先用低开销采样,避免排障工具本身影响敏感负载。
★ 文件描述符泄漏怎么查? 对比 /proc/PID/fd、lsof 与限制,按 socket/文件类型观察是否持续增长;结合代码路径找缺失 close,而不是只提高 nofile。
strace 可以观察什么? 系统调用、返回码和等待耗时,适合看卡在读、连接还是锁。附加有开销和权限要求,先缩小调用与时间范围。
★ 进程 D 状态是什么? 通常为不可中断睡眠,常见于存储等待;信号可能要等内核等待结束才处理。查对应设备/文件系统,不能只重复 kill -9。
TIME_WAIT 多就一定有问题吗? 不一定,它是正常 TCP 生命周期状态。结合连接建立率、端口范围、错误与复用判断,别为了降数量随便改内核参数。
★ SYN_RECV 与 ESTABLISHED 看什么? 区分握手压力和已建立连接,结合监听队列、连接数与丢包。连接数高不代表应用正在处理同样多业务。
磁盘满先查什么? 分清块空间、inode、日志、构建缓存、卷与已删除打开文件;先停止异常增长,再按保留策略处理,避免误删数据库文件。
★ cgroup v2 哪些指标有用? cpu.stat 看节流,memory.current/events 看内存与 OOM 事件,io.stat 看 IO;路径按运行环境确认,宿主总量不能代替容器实际限额。
namespace 与 cgroup 区别? namespace 隔离进程看到的对象,cgroup 归组并控制资源;二者解决不同问题。看不到别的进程不等于无法耗尽 CPU。
★ chroot 有什么局限? 主要改变路径解析根,不单独提供进程、网络与内核隔离;高权限进程仍可能突破。需配合身份、挂载、namespace 和资源控制。
软链接为什么影响路径授权? 字面路径在允许目录内,最终目标却可能指向外部;解析后检查仍要考虑检查到打开之间竞争,必要时用更安全的文件打开方式。
★ systemd 与 shell 启动差在哪? 环境、工作目录、身份、资源限制和输出位置可能不同;用服务实际配置复现,不靠在登录 shell 里手动成功推断部署正常。
定时任务为什么时间不对? 检查应用时区、系统时区、调度器与数据库时间,以及夏令时规则;日志显示时间与调度解释时区可能不是同一设置。
★ 如何读取日志更高效? 按关联 ID、时间范围和错误类别缩小,再关联版本与实例;流式工具避免整文件加载。先保护原始时间线,别只截最后一条异常。
高难
我们沙箱的隔离为什么用
unshare+chroot? 沙箱进程都是同一个 uid,用户之间能互读文件。unshare给每次执行建新的 mount 和 PID namespace(看不到别人的进程、挂载只影响自己),chroot把根目录换成该用户的目录。本质就是 Docker 的原理在进程级别的手动应用。代价:容器要SYS_ADMIN能力。没用 bubblewrap 是因为容器环境的限制。容器 OOM 了怎么排查?
docker inspect看OOMKilled;dmesg看内核 OOM 日志;容器内存限制是否太小;应用是否泄漏;注意 Python / Java 进程不一定感知 cgroup 限制(JVM 8u191+ 才默认感知)。多架构镜像?
docker buildx build --platform linux/amd64,linux/arm64 --push,同一个 tag 下是多个架构的 manifest list,拉取时自动选匹配的。我们客户服务器有 x86 也有 ARM。★ load 高但 CPU 很闲怎么查? 看 D 状态、磁盘/网络文件系统与内核等待栈,区分 IO 和锁;增加 CPU 对存储阻塞可能无效。
进程 RSS 不降一定泄漏吗? 不一定,分配器保留内存、页缓存和内存碎片会影响。比较活对象、堆与 RSS 的长期趋势,重任务结束后观察稳定基线。
★ 容器 CPU 看起来有空闲却变慢? 可能触发 quota 节流,宿主空闲不表示该 cgroup 还能用。查 cpu.stat/配额和请求延迟,再决定调并发还是资源。
fork 后为什么会死锁? 多线程父进程里其他线程持有的锁复制到子进程后,持有线程不在子进程中。控制 fork 时机或选干净启动方式,重建连接/锁资源。
★ SIGTERM 后仍超时退出怎么查? 按时间线看 PID1、信号转发、摘流、在途请求和资源关闭;容器强杀上限是最后边界,不保证应用宣称的等待时间都能用完。
已删除大文件为何还占空间? 只删目录项但进程仍持有文件,引用释放后空间才回收。定位持有者并按服务方式重开/关闭,直接改 fd 或重启需评估影响。
★ 高并发下 accept 失败可能是什么? 监听队列、fd、内存、连接跟踪与端口等资源都可能耗尽;对照具体 errno 和指标,不能只调 backlog。
如何处理磁盘延迟突增? 区分吞吐、随机 IO、队列长度和设备错误,关联备份/索引构建;限后台工作或迁移负载,扩容前确认存储类型和共享瓶颈。
★ 时钟差导致清扫误判怎么办? 让状态写入与超时比较使用同一权威钟;跨系统携带时间语义,时长测量用单调钟。扩大阈值只是缓解,不能根除跨钟偏差。
内核 OOM 与应用内存异常区别? 内核/cgroup 可直接杀进程,应用可能来不及抛异常或清理;应用异常则可能被捕获。查 OOM events、退出原因和当时峰值,别只找 Python traceback。
★ 沙箱 CPU/内存限制够不够? 还需文件大小、进程数、fd、磁盘、网络与执行时间预算;子进程也纳入同一边界,避免父进程限制未覆盖后代。
多节点文件偶尔缺失怎么查? 核对实际请求节点、挂载源和文件版本,本地路径一致不代表数据相同。共享存储/调度约束按需求选,不能用粘性路由假装可靠复制。
★ 网络慢如何分层定位? 分 DNS、握手、TLS、首字、下载和应用处理,逐跳比较;trace ID 关联代理与后端,别把所有耗时都归给数据库。
如何避免排障命令泄露凭证? 限制 inspect/env/命令行输出,按字段提取必要信息,日志脱敏。工具能读取配置不代表可以把全部配置贴到工单或文档。
★ 怎样验证资源限制实际生效? 读取目标进程所在 cgroup 和实际计数,在隔离本机负载下观测节流/拒绝;只看 compose 声明不能证明运行时支持并应用。
进程重启为何解决不了句柄泄漏根因? 重启暂时释放资源,缺失关闭的代码仍会累积。保存增长曲线和对象归属,修生命周期并复现回归,再用滚动回收作兜底。
★ Linux 命令在 macOS 都能用吗? 不能,/proc、ss、strace、GNU timeout 等可能没有或参数不同。确认执行平台,必要时在本机 Linux 容器/虚拟机验证,不把命令不存在当业务失败。
