6.2 KiB
id, title, type, domain, stack, tags, level, related, week
| id | title | type | domain | stack | tags | level | related | week | |||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| devops.linux.interview | Linux 面试题 | interview | devops |
|
|
basic |
|
|
Linux 面试题
基础
【基础】怎么查看某个端口被哪个进程占用?
参考答案:ss -lntp | grep 8080(或旧命令 netstat -lntp、lsof -i :8080),输出里有进程名和 PID。没有 root 权限时可能看不到其他用户进程的信息。
追问:ss 和 netstat 的区别?→ ss 更新、更快,直接从内核获取信息;netstat 在很多新系统上默认不再安装。
【基础】怎么实时查看日志?怎么查找包含某个关键字的行?
参考答案:tail -f app.log 实时跟踪;grep -n "ERROR" app.log 查找并显示行号,grep -C 5 显示上下文,grep -r 递归目录;systemd 服务用 journalctl -u 服务名 -f。
追问:日志文件很大,怎么只看某个时间段?→ 用 sed -n '/开始时间/,/结束时间/p' 或 awk 按时间字段过滤;systemd 服务用 journalctl --since --until。
【基础】kill、kill -9、kill -15 有什么区别?
参考答案:kill 默认发送 SIGTERM(15),进程可以捕获它做清理后退出;kill -9 发送 SIGKILL,不能被捕获,进程立即被杀死,来不及释放资源。应该先 SIGTERM,等待超时后再 SIGKILL。
追问:为什么不建议直接使用 kill -9?→ 程序无法清理资源(关闭连接、刷新缓冲、删除临时文件),可能导致数据不完整;先发 SIGTERM,等待超时后再用 -9。
【基础】软链接和硬链接的区别?
参考答案:硬链接是同一个 inode 的另一个文件名,删除原文件后硬链接仍能访问,不能跨文件系统、不能链接目录;软链接是一个单独的文件,内容是目标路径,原文件删除后软链接失效,可以跨文件系统、可以链接目录。部署中常用软链接切换版本(current -> releases/v2)。
追问:删除源文件后,软链接和硬链接会怎样?→ 软链接失效(指向的路径不存在);硬链接仍然可以访问数据,因为数据要等到所有硬链接都删除后才释放。
进阶
【进阶】服务器负载很高,你怎么排查?
参考答案:uptime 看 load 和核数对比;top 看 CPU 的 us(用户态计算)、sy(内核态)、wa(IO 等待);wa 高查磁盘(iostat -x、iotop),us 高找占用最高的进程和线程(top -H -p),再用语言工具(Go pprof、py-spy)定位到函数;同时看内存是否在用 swap。
追问:负载高但 CPU 使用率低是什么情况?→ 负载包含等待 I/O(D 状态)的进程,可能是磁盘 I/O 瓶颈或 NFS 等存储问题,用 iostat、vmstat 查看 wa。
【进阶】TIME_WAIT 和 CLOSE_WAIT 过多分别说明什么?
参考答案:TIME_WAIT 出现在主动关闭连接的一方,大量出现通常是频繁创建短连接,应该复用连接(keep-alive、连接池)。CLOSE_WAIT 表示对方已关闭、本方还没关闭,大量出现基本是程序没有关闭连接(例如 Go 没有 resp.Body.Close()),属于代码 bug。
追问:CLOSE_WAIT 一般是谁的问题?→ 通常是自己程序的问题:对方已经关闭连接,自己没有调用 close(例如 HTTP 响应体没有关闭)。
【进阶】磁盘满了怎么处理?
参考答案:df -h 确认哪个分区满,df -i 检查 inode 是否用尽(大量小文件);du -sh /* | sort -h 逐层找大目录;常见是日志、临时文件、Docker 镜像和容器日志。删除正在被进程写的文件不会释放空间,用 lsof +L1 查找,清空文件内容或重启进程。长期方案:logrotate、Docker 日志大小限制、磁盘使用率告警。
追问:删除了大文件但磁盘空间没有释放,为什么?→ 文件还被进程打开着,用 lsof +L1 或 lsof | grep deleted 找到进程,重启进程或清空文件。
场景题
【场景题】Go 服务内存持续上涨,最后被系统杀掉,怎么定位?
参考答案:先在内核日志确认是 OOM(journalctl -k | grep -i oom);服务开启 pprof,在内存上涨过程中多次采集 heap,对比哪些对象在增长(go tool pprof -inuse_space、-base 对比);同时看 goroutine 数量是否持续增长(goroutine 泄漏也会占内存)。常见原因:无上限的缓存或 map、goroutine 阻塞泄漏、读取大文件 / 大响应到内存。修复后加内存告警和 MemoryMax 限制。
追问:怎么确认是被 OOM Killer 杀掉的?→ dmesg -T | grep -i oom 或 journalctl -k 查看内核日志;容器中看退出码 137 和 OOMKilled 状态。
【场景题】用户反馈接口偶尔很慢,但你登录服务器时一切正常,怎么办?
参考答案:需要事后可查的数据:Nginx 日志记录 $request_time 和 $upstream_response_time,用 awk 找出慢请求的时间点和接口;应用日志带请求 ID 和每一步耗时;数据库开慢查询日志;看云监控在对应时间点的 CPU、IO、网络曲线。根据时间点关联定时任务、备份、其他服务的批处理。长期方案是接入指标监控和链路追踪。
追问:怎么让偶发问题留下证据?→ 增加带请求 ID 的结构化日志和慢请求日志;监控历史指标(CPU、GC、连接数);在问题出现时自动保存现场(如 pprof 数据)。
【场景题】怎么把一个 Go 程序部署成开机自启、崩溃自动重启的服务?
参考答案:编写 systemd 单元文件:指定运行用户、工作目录、环境变量文件、ExecStart、Restart=on-failure、RestartSec、停止超时;systemctl daemon-reload、enable --now;日志用 journalctl -u 查看。程序本身要处理 SIGTERM 优雅退出。也可以用 Docker 的 restart: unless-stopped 实现类似效果。
追问:日志写到哪里?→ systemd 服务输出到标准输出,由 journald 收集,用 journalctl -u 服务名 查看;需要长期保存时配置日志轮转或采集到日志平台。