楼层: 首页/ 软件技术/ Linux/ 进阶路线与高频面试题
12

进阶路线与高频面试题

Roadmap & Interview

书读完了,然后呢?这一章给你一张从菜鸟到高手的路线图,再把面试最常问的二十个问题折成 details,点开对答案。

成长路线图:七层爬楼

阶段练什么
1. 命令层第 3 章那三四十条命令,练到不查手册。
2. 脚本层第 5 章 Bash,能写自动备份、批量处理脚本。
3. 服务层systemd、nginx、数据库,把一个 web 服务完整跑起来。
4. 网络层IP/DNS/防火墙/SSH,能排"为什么访问不到"。
5. 安全层第 11 章加固清单,能配一台"敢放公网"的机器。
6. 性能调优CPU/内存/磁盘/网络瓶颈排查(下面细说)。
7. 内核与架构内核参数调优、容器/Docker/K8s、高可用——这是工程师到架构师的路。

优性能调优的排查思路(万能套路)

系统慢了,按四个维度顺藤摸瓜:CPU(top 看谁占满,是计算密集还是上下文切换多)→ 内存(free 看 available,是不是 swap 用爆了、有没有 OOM)→ 磁盘 IO(iostat 看 util%,是不是某块盘被打满)→ 网络(ss、tcpdump 看连接堆积、丢包)。没有定位就调优,等于闭眼踩油门。

进阶深挖一:LVM 逻辑卷管理(盘不够了在线扩容)

引子:你分区时给 /home 分了 50G,跑了一年数据涨到 80G,根分区还剩 100G 空闲。传统分区下你只能哭——因为 /home 和 / 是两块互不相干的盘。LVM 就是来救场的:它在"物理盘"和"文件系统"之间加了一层软的抽象,让你像调水龙头一样在线给分区扩容、缩容。

本章要学什么:三层概念,一张图看懂

物理盘 /dev/sdb /dev/sdc
裸硬盘(可多块)
→
PV 物理卷
pvcreate 把盘切成小块(PE)
→
VG 卷组
把多个 PV 攒成一个大池子
→
LV 逻辑卷
从池子里划一块给某个分区用
→
文件系统 /home
mkfs + mount

论为什么传统分区不够用

传统分区像一次性切好的蛋糕,切多切少都改不了。LVM 把多块硬盘拼成一个"大水池"(VG),你从水池里按需"舀水"(LV)给某个目录。水池水多了(加新盘),就给任何一个 LV 多灌点,全程不用关机、不用重新分区、不用搬数据。这就是它在线扩容的魔力。

完整操作:建 PV → 建 VG → 建 LV → 格式化挂载

# 1. 把两块新盘初始化成物理卷 PV sudo pvcreate /dev/sdb /dev/sdc # 2. 把两块 PV 合成一个卷组 VG,名字叫 data_vg sudo vgcreate data_vg /dev/sdb /dev/sdc # 3. 从 VG 里划出一个 100G 的逻辑卷 LV,名字叫 home_lv sudo lvcreate -L 100G -n home_lv data_vg # 4. 格式化成 ext4,再挂载(生产建议 xfs:mkfs.xfs) sudo mkfs.ext4 /dev/data_vg/home_lv sudo mount /dev/data_vg/home_lv /home # 5. 开机自动挂载,写进 /etc/fstab(blkid 拿 UUID 最稳) echo "/dev/data_vg/home_lv /home ext4 defaults 0 0" | sudo tee -a /etc/fstab
$ pvs # 看有哪些 PV PV VG Fmt Attr PSize PFree /dev/sdb data_vg lvm2 a-- 200.00g 100.00g /dev/sdc data_vg lvm2 a-- 200.00g 200.00g $ vgs # 看 VG 还剩多少空间 VG #PV #LV #SN VSize VFree data_vg 2 1 0 400.00g 300.00g

磁盘快满了,在线扩容(这是 LVM 最值钱的场景)

# /home 涨到 100G 不够了,VG 里还有 300G 空闲 # 第一步:逻辑卷直接加 50G sudo lvextend -L +50G /dev/data_vg/home_lv # 第二步:文件系统也跟着长大(ext4 用 resize2fs) sudo resize2fs /dev/data_vg/home_lv # 如果是 xfs,这一步换成:sudo xfs_growfs /home # 如果 VG 也没空间了,先加新盘: sudo pvcreate /dev/sdd sudo vgextend data_vg /dev/sdd # 把新盘塞进 VG 池子 sudo lvextend -l +100%FREE /dev/data_vg/home_lv # 一口气吃光剩余空间
LVM 扩容最容易忘的坑

很多人 lvextend 之后就完事,结果 df -h 一看大小没变。因为逻辑卷长大了,文件系统还不知道。必须再跑 resize2fs(ext4)或 xfs_growfs(xfs)。还有:xfs 只能扩不能缩,ext4 才能缩,缩之前必须先卸载并 e2fsck 检查,搞不好数据没了。生产上只扩不缩。

应用场景:云服务器磁盘扩容、数据库数据盘在线加大、把多块小盘拼成一个大存储池。防坑:操作前 vgdisplay/lvdisplay 看清楚是哪个 VG、哪个 LV,别在错误的盘上瞎扩容。

进阶深挖二:RAID 磁盘阵列(多块盘怎么组合才不丢数据)

引子:一块硬盘坏了,上面的数据就没了。RAID(磁盘阵列)就是把好几块盘按规矩组合成一个整体,要么换更快,要么换更安全。面试常考 RAID 0/1/5/10 的区别。

四种常见 RAID 级别,背下来
级别原理最少盘数特点 / 代价
RAID 0条带化,数据切成块轮流写各盘2最快、容量全用,但坏一块全盘完蛋,纯加速无安全
RAID 1镜像,两盘写一模一样2最安全,坏一块还能活;容量只能用一半,浪费
RAID 5分布式奇偶校验,校验信息分散在各盘3坏一块能靠校验算回来,容量 = N-1 块,最常用
RAID 10先做镜像(1)再条带化(0)4又快又安全,坏一半盘也能活,但贵,容量一半

软件 RAID:用 mdadm 在 Linux 上组一个 RAID 1(两块盘互为镜像)

# 安装 mdadm(以 Debian/Ubuntu 为例) sudo apt install -y mdadm # 组 RAID 1:2 块盘,设备名 /dev/md0 sudo mdadm --create /dev/md0 --level=1 --raid-devices=2 /dev/sdb /dev/sdc # 看状态 cat /proc/mdstat # 保存配置,防止重启后阵列名变了 sudo mdadm --detail --scan | sudo tee -a /etc/mdadm/mdadm.conf
$ cat /proc/mdstat md0 : active raid1 sdc[1] sdb[0] 10485760 blocks super 1.2 [2/2] [UU] # [UU] 表示两块盘都在线;如果坏了一块会变成 [U_]
RAID 不是备份

RAID 只防"盘硬件坏了",不防"你不小心 rm -rf 删错了"。你在 RAID 1 上删文件,两块盘一起被删,数据照样没。RAID 是高可用手段,备份(rsync、快照、异地拷贝)才是数据安全手段,两码事。另外生产上要么用硬 RAID 卡(带电池缓存),要么直接上云盘,软件 RAID 只适合学习。

进阶深挖三:Docker 容器入门(应用搬家的"集装箱")

引子:"在我机器上明明能跑"——这是程序员背了几十年的锅。应用依赖一堆库和环境配置,从开发机搬到生产机就崩。Docker 把应用和它需要的所有环境(代码、库、配置)打成一个标准化的"集装箱",到哪台机器上都一模一样地跑。这就是它的核心价值。

论容器和虚拟机的区别

虚拟机(VM)是连操作系统一起虚拟化,每个都装个完整 Guest OS,重、慢、占几个 G。容器不一样:它共享宿主机的内核,只隔离进程、文件系统和网络,不单独装 OS,所以一个容器只有几十 MB,启动秒级。你可以理解成:虚拟机是"带全套装修的独栋别墅",容器是"拎包入住的标准间"——快、标准化、随便搬。

三个核心命令:跑、看、进

# 1. 跑一个 nginx 容器:-d 后台,-p 把宿主机 8080 映射到容器 80 docker run -d --name my-nginx -p 8080:80 nginx:1.27 # 2. 看跑着哪些容器 docker ps # 3. 钻进容器里看它的文件系统(像 SSH 进去一样) docker exec -it my-nginx bash # 停掉、删掉 docker stop my-nginx docker rm my-nginx
$ docker ps CONTAINER ID IMAGE STATUS PORTS NAMES a1b2c3d4e5f6 nginx:1.27 Up 2 minutes 0.0.0.0:8080->80/tcp my-nginx # 浏览器访问 http://localhost:8080 就能看到 nginx 欢迎页

Dockerfile:把你的应用打包成镜像

# 一个最小的 Spring Boot 应用镜像 FROM eclipse-temurin:17-jre # 基础镜像:带 JDK 17 运行环境 WORKDIR /app # 容器里的工作目录 COPY target/demo.jar app.jar # 把本地 jar 拷进镜像 EXPOSE 8080 # 声明服务端口 ENTRYPOINT ["java", "-jar", "app.jar"] # 容器启动时跑这个命令
$ docker build -t demo:1.0 . # 构建镜像(最后那个点是上下文) $ docker run -d -p 8080:8080 demo:1.0
容器的三个认知误区

① 容器里的数据不持久化。容器删了,里面写的文件就没了。数据库这种要存数据的,必须挂 -v 宿主机目录:/容器目录 卷。② 别在容器里手动改东西。要改就改 Dockerfile 重新 build,手动改的一重启就丢。③ 镜像别装太大。基础镜像选 alpine 或 jre 这种瘦版,别拿带图形界面的当底。

应用场景:一键部署应用、微服务拆成一个个容器、CI/CD 流水线。K8s 就是管一大堆 Docker 容器的"调度大脑",那是后话。

进阶深挖四:sysctl 内核参数调优(改操作系统的"隐藏开关")

引子:你的程序并发一高就报"too many open files"、TIME_WAIT 堆积一堆端口用不上。这些不是应用的错,是内核默认参数太保守。sysctl 就是查看和修改内核运行时参数的工具。

# 查看所有内核参数(量很大,配合 grep 找) sysctl -a | grep somaxconn # 临时改一个(重启失效):把 TCP 连接队列从默认 128 调到 1024 sudo sysctl -w net.core.somaxconn=1024 # 永久生效:写进 /etc/sysctl.conf 或 /etc/sysctl.d/99-custom.conf cat >> /etc/sysctl.d/99-custom.conf <<'EOF' # TCP 连接队列加大,扛高并发 net.core.somaxconn = 1024 # 内核更积极地回收连接,别攒一堆 TIME_WAIT net.ipv4.tcp_tw_reuse = 1 # 内存压力大时尽量少用 swap(0~100,0=尽量不用磁盘交换) vm.swappiness = 10 EOF # 让配置立即生效 sudo sysctl -p /etc/sysctl.d/99-custom.conf
改内核参数别瞎抄网上的

网上一堆"高并发 sysctl 神配置",直接抄可能把系统搞崩。每个参数都有副作用:tcp_tw_reuse 是安全的,但老教程里的 tcp_tw_recycle 在 NAT 环境下会导致连不上,现代内核已经废了。原则:一次只改一两个,观察效果再调下一个。改完 sysctl -p 确认没报错,再压测验证。

进阶四件套练习(点开展开)

1.(LVM 排错)你 lvextend 给 /home 加了 20G,但 df -h 里 /home 大小没变,下一步该干嘛?

查看答案

逻辑卷长大了但文件系统没跟着长。ext4 跑 resize2fs /dev/mapper/xxx,xfs 跑 xfs_growfs /home。这是 LVM 扩容最经典的坑,别怀疑 lvextend 失败了。

2.(RAID 选型)既要磁盘快,又要坏一块盘不丢数据,最少需要几块盘、组哪个级别?

查看答案

最少 4 块盘组 RAID 10:两两镜像(1)再条带化(0)。RAID 5 只要 3 块也能坏一块,但写性能差;RAID 10 又快又安全,代价是容量只能用一半。

3.(Docker)为什么说"容器不是虚拟机"?它启动快的根本原因是什么?

查看答案

容器共享宿主机内核,不单独装完整操作系统,只是用 namespace/cgroup 做了进程隔离。所以没有 Guest OS 启动那几十秒,一个容器秒级就能跑起来。

4.(sysctl)改完一个内核参数,怎么让它立即生效又能开机自动生效?

查看答案

把参数写进 /etc/sysctl.d/xxx.conf(永久),再跑 sudo sysctl -p 文件名 立即加载。只 sysctl -w 是临时的,重启就没。

记
进阶四件套小结

① LVM = PV→VG→LV 三层抽象,磁盘不够在线 lvextend + resize2fs,是运维最实用的一招。

② RAID 0 快不安全、RAID 1 安全不快、RAID 5 平衡、RAID 10 又快又安全;记住 RAID 不是备份。

③ Docker 把应用连同环境打成集装箱,run/ps/exec 三件套入门;容器数据要挂卷,删容器不删卷。

④ sysctl 改内核隐藏开关,改配置文件 + sysctl -p 永久生效,别瞎抄网上神配置。

费曼三问 · 合上书本,用自己的话回答

第一问:为什么用了 LVM 之后,加硬盘就不用停机重装系统了?

查看答案

因为 LVM 在物理盘和文件系统之间加了 VG 这个"大水池"抽象层。新盘 pvcreate 后 vgextend 进水池,任何 LV 都能 lvextend 从水池里取水,文件系统在线 resize,全程不需要重新分区或搬数据。

第二问:RAID 1 已经有镜像了,为什么还要做异地备份?

查看答案

RAID 1 只防"盘坏"。误删、勒索病毒、机房着火这种事会让两块盘同时遭殃。镜像保证硬件冗余,备份保证逻辑错误和灾难可恢复,缺一不可。

第三问:Docker 镜像和容器是什么关系?删了容器,镜像还在吗?

查看答案

镜像是只读模板(类),容器是镜像跑起来的实例(对象)。一个镜像可以同时跑出多个容器。删容器(docker rm)不影响镜像,镜像还在本地仓库里,随时能再 run 出新容器。

高频面试题二十道

点开对答案,别偷看
1. Linux 下怎么找占用 80 端口的进程?

ss -tulpn | grep :80(老写法 netstat -tulpn | grep :80),输出里的 users: 后面就是进程名和 PID。

2. 一个进程 CPU 100%,怎么定位是哪段代码?

先 top 找到 PID,再 top -Hp PID 看是哪个线程,最后用 perf top -p PID 或 pstack 看它在跑什么函数。

3. rm -rf 误删了文件怎么办?

别再往磁盘写数据(覆盖就真没了)。马上卸载该分区或把文件移到只读,用 extundelete、testdisk 等工具尝试恢复。生产事故先做这个,别慌着重启。

4. 软链接和硬链接的区别?

软链接是快捷方式,能跨分区、能链目录,原文件删了就断;硬链接是同一个 inode 的第二个名字,不能跨分区不能链目录,原文件删了数据还在。

5. 755 和 644 分别是什么权限?

755 = rwxr-xr-x(所有者读写执行,其他人读+执行),给脚本和目录;644 = rw-r--r--(所有者读写,其他人只读),给普通文件。

6. 怎么让一个程序后台运行且关掉终端也不死?

nohup ./app &,或者交给 systemd(第 7 章写 .service,Restart=always)。生产上后者更标准。

7. nohup、&、systemd 三者怎么选?

临时跑一次用 nohup ... &;长期跑、要开机自启和挂掉自动重启,必须用 systemd 管。

8. /etc/passwd 和 /etc/shadow 区别?

passwd 所有用户可读,存账号信息(密码位是 x 占位);shadow 只有 root 可读,存加密密码和有效期,所以普通用户读不到别人密码。

9. find 和 grep 的区别?

find 找文件本身(按名、大小、时间);grep 找文件内容里的字符串。grep -r "xxx" . 是内容检索,find . -name "xxx" 是文件检索。

10. 查看实时日志用什么?

tail -f /var/log/xxx.log;systemd 服务用 journalctl -u 服务 -f。

11. 磁盘快满了,怎么排查大文件?

df -h 确认;du -h --max-depth=1 / | sort -rh 一层层往下找大目录;常见元凶是日志和被删但没释放的句柄(lsof | grep deleted)。

12. kill、kill -9、killall 的区别?

kill PID 发 SIGTERM 让进程自己退出;kill -9 PID 发 SIGKILL 强杀不给清理机会;killall 按进程名杀所有实例。先 kill,无效再 -9。

13. crontab 的 * * * * * 分别是什么?

分、时、日、月、周。30 2 * * * 是每天 2:30。

14.怎么排查"机器上不了网"?

分层查:ip addr 看有没有 IP → ping 网关 看内网通不通 → ping 8.8.8.8 看外网通不通 → nslookup baidu.com 看 DNS 好不好。哪层断了问题就在哪。

15. chmod、chown、chgrp 的区别?

chmod 改权限位(rwx);chown 改属主和属组;chgrp 只改组。

16. 怎么看一个命令的可执行文件在哪?

which 命令 看路径;whereis 命令 连配置和手册位置一起列。

17. tar -czf 和 -xzf 的区别?

-czf 打包并 gzip 压缩;-xzf 解压。c=create,x=extract,z=gzip,f=指定文件。

18. systemctl reload 和 restart 区别?

reload 重载配置不断连接,restart 彻底重启会短暂中断。能 reload 就 reload。

19. SSH 安全加固做哪几条?

密钥登录、禁 root 直登、改默认端口、装 fail2ban、AllowUsers 白名单。

20. Linux 一切皆文件怎么理解?

普通文件、目录、设备(硬盘 /dev/sda)、进程信息(/proc)、管道,全都通过"读写文件"这一套接口访问,所以操作方式高度统一。