
hello 我是逆境凌晨两点十七分逆境的手机响了。监控群里只有一条冷冰冰的消息订单服务响应超时主机负载持续升高。他连上服务器先敲top发现 Load Average 已经到了 12又敲free -h空闲内存只剩两百多兆。更糟的是df -h显示磁盘使用率 100%可du怎么也找不到那么大的文件。如果这些命令只是背过屏幕上的数字就像体检报告上的缩写每个字都认识连在一起却不知道病在哪儿。Linux 面试也经常这样。面试官很少满足于“命令是什么”他会继续问负载高就一定是 CPU 不够吗文件删了磁盘空间为什么没回来kill -9发出去了进程怎么还在空闲内存很少系统是不是快崩了这篇文章就从这次夜间告警讲起。我们把 Linux 想成一栋一直营业的大楼内核是物业中控室进程是租户内存是房间文件描述符是取件号磁盘和网络则是两条最容易堵车的运输线。先看懂它怎么运转再背每一题末尾的“面试回答”。第一站进入大楼先认清 Linux 的结构逆境通过 SSH 登录服务器。命令行提示符出现的那一刻他已经在和 Shell 打交道了但 Shell 并不是 Linux 内核。1. Linux 系统由哪些部分组成可以先记住四层用户程序 ↓ Shell、系统工具和各种运行库 ↓ Linux 内核 ↓ CPU、内存、磁盘、网卡等硬件内核负责进程调度、内存管理、文件系统、网络协议栈和设备驱动。Shell 是命令解释器常见的有 Bash、Zsh。ls、ps、top这些命令属于用户态程序。所以严格来说 Linux 指的是内核日常说“Linux 系统”时通常把内核、GNU 工具、运行库和其他软件都算在里面。面试回答Linux 系统主要由内核、Shell、文件系统和用户态程序组成。内核负责调度、内存、文件、网络和设备管理Shell 负责解释用户命令应用程序通过系统调用向内核申请服务。2. 用户态和内核态有什么区别把内核想成物业中控室。普通租户不能随便拉电闸、改门禁用户程序同样不能直接访问硬件或任意内存。CPU 在用户态运行应用代码时权限受到限制。程序需要读取文件、申请内存或发送网络数据就通过系统调用进入内核态。处理完成后再回到用户态。这层隔离能保护系统却不是免费的。每次切换都要保存和恢复部分执行现场所以高频、细碎的系统调用会带来开销。面试回答用户态权限较低应用不能直接访问硬件和内核空间内核态拥有较高权限负责执行系统级操作。系统调用、中断和异常都可能让 CPU 从用户态进入内核态处理完成后再返回。3. 什么是系统调用逆境执行catapp.logcat自己不会从磁盘控制器里“掏”出数据。它会调用open()打开文件调用read()读取内容再调用write()把内容写到终端。常见系统调用可以按用途记文件open、read、write、close 进程fork、exec、wait、exit 网络socket、bind、listen、accept 内存mmap、brkShell 命令和系统调用不是一回事。cp是命令内部会使用open、read、write等系统调用完成复制。面试回答系统调用是用户程序进入内核、请求操作系统服务的接口。应用通过它完成文件读写、进程创建、网络通信和内存管理。命令属于用户程序命令内部通常还要调用多个系统调用。4. “Linux 一切皆文件”到底是什么意思普通文件当然是文件目录也是文件。磁盘设备可能出现在/dev进程信息能在/proc里读取网络 Socket 也能用文件描述符操作。这句话强调的是统一接口很多资源都可以执行“打开、读取、写入、关闭”这套动作。它是一种设计思想不是说所有资源都真的存放在磁盘文件里。例如/proc/cpuinfo看起来像文件内容却是内核在读取时动态提供的。面试回答“一切皆文件”指 Linux 将普通文件、目录、设备、管道和 Socket 等资源抽象成类似文件的接口程序可以通过文件描述符以及读写操作统一管理它们。它是接口抽象不代表所有资源都是磁盘文件。5. 常见 Linux 目录分别放什么逆境排障时最常去的是/etc、/var/log和/proc。/etc 系统与服务配置 /var 日志、缓存和经常变化的数据 /usr 大量用户程序、库和共享文件 /home 普通用户家目录 /root root 用户家目录 /tmp 临时文件 /dev 设备文件 /proc 进程与内核信息属于虚拟文件系统 /sys 设备和内核对象信息 /run 本次启动以来的运行时数据不必死背整棵目录树。面试中能说清配置去/etc、日志常在/var/log、进程状态看/proc已经抓住了最常用的部分。面试回答/etc放配置/var放日志等可变数据/usr放程序和库/home是普通用户目录/dev提供设备文件/proc和/sys提供内核、进程及设备的运行信息。第二站进程大厅谁在工作谁只剩一张登记表逆境输入ps -ef屏幕上滚过几百行进程。这里有正在工作的也有睡觉等消息的还有已经死亡却没有办完注销手续的。6. 进程和线程有什么区别进程像一家公司有自己的办公区和资源。线程像公司里的员工共用办公室、文件柜和电话但每个人都有自己的工作台。同一进程中的线程通常共享虚拟地址空间打开的文件描述符全局变量和堆每个线程又有独立的栈、寄存器和程序计数器。进程隔离更好一个进程崩溃通常不会直接破坏另一个进程的地址空间。线程之间通信方便切换成本一般也更低但共享数据时要处理锁、竞态条件和可见性问题。面试回答进程是资源分配和隔离的基本单位线程是 CPU 调度的基本单位。同一进程的线程共享地址空间和文件描述符但各自拥有栈、寄存器和程序计数器。线程通信方便、切换通常较轻代价是共享数据容易产生并发问题。7.fork()和exec()有什么区别Linux 创建新程序时常走两步父进程 ↓ fork 子进程 ↓ exec 新程序fork()复制出一个子进程。子进程有新的 PID开始时看起来和父进程很像。exec()则把当前进程的代码、数据和栈替换成另一个程序。exec()成功后不会返回到旧程序继续执行。它通常也不会创建新 PID变的是进程里运行的内容。面试回答fork()创建子进程父子进程从调用位置继续执行exec()用新程序替换当前进程的地址空间。常见模式是先fork()创建子进程再由子进程调用exec()运行目标程序。8.fork()会立刻复制父进程的全部内存吗通常不会。Linux 使用写时复制英文是 Copy-on-Write。刚执行完fork()时父子进程的虚拟地址会映射到相同的物理页面并把页面暂时设为只读。谁尝试修改内核才为谁复制对应的页面。这像两个人共用一份只读资料。没人改时不必复印有人要在某一页做笔记只复印那一页。写时复制节省了时间和内存尤其适合子进程马上调用exec()的场景。面试回答fork()通常采用写时复制不会立即复制全部物理内存。父子进程起初共享物理页当一方写入时触发缺页异常内核再复制对应页面。9. Linux 进程有哪些常见状态执行ps或top时经常能看到这些字母R 正在运行或已经准备好等待 CPU S 可中断睡眠通常在等待事件 D 不可中断睡眠常见于等待 I/O T 被暂停或正在被调试 Z 僵尸进程最容易误解的是R和D。R不只表示正在占用 CPU也包括已经排队等待 CPU。D状态下的进程通常正在等内核完成某项 I/O为了避免操作进行到一半被打断暂时不会响应普通信号。面试回答常见状态有运行或就绪的R、可中断睡眠的S、不可中断睡眠的D、暂停的T和僵尸状态Z。其中D常与磁盘或网络存储 I/O 等内核等待有关。10. 什么是僵尸进程子进程退出时会留下 PID、退出码和少量统计信息等父进程调用wait()或waitpid()来领取。如果父进程一直不领子进程已经不执行代码也不占正常的用户内存却仍占着进程表项。它就是僵尸进程。少量、短暂的僵尸进程不一定有问题。大量长期存在的僵尸进程说明父进程没有正确回收子进程最终可能耗尽 PID 或进程表资源。面试回答僵尸进程是已经退出、但父进程尚未调用wait()回收退出状态的子进程。它不再运行却保留进程表项。解决时应修复父进程的子进程回收逻辑而不是只盯着僵尸进程本身。11. 什么是孤儿进程它和僵尸进程一样吗不一样。孤儿进程仍在运行只是父进程先退出了。它通常会被 PID 1 或配置为 subreaper 的进程接管之后照常运行并被回收。僵尸进程已经结束只剩退出信息没人领取。一个是“孩子还活着家长先走了”另一个是“孩子已经退场家长没签收结果”。面试回答孤儿进程是父进程已经退出、子进程仍在运行的进程通常会被 PID 1 或 subreaper 接管僵尸进程则已经退出只是退出状态尚未被父进程回收。12.kill命令是直接杀进程吗kill的本意是发送信号。killPID# 默认发送 SIGTERM也就是 15kill-9PID# 发送 SIGKILLkill-HUPPID# 发送 SIGHUPSIGTERM是一次“请你退出”的通知。程序可以捕获它先停止接收请求、保存数据、关闭连接再结束。SIGKILL则由内核直接处理进程不能捕获、忽略或执行清理逻辑。所以生产环境通常先发SIGTERM超时后再考虑SIGKILL。还有一个面试陷阱处于D状态的进程即使收到了SIGKILL也可能暂时退不掉。它要等不可中断的内核操作返回才有机会处理退出。面试回答kill是发送信号默认发送可被处理的SIGTERM让进程有机会优雅退出。kill -9发送不可捕获的SIGKILL可能造成数据或资源来不及清理若进程卡在D状态它也不一定立刻消失。13. 什么是上下文切换为什么太多会变慢CPU 核心同一时刻只能执行有限数量的线程。它从任务 A 切到任务 B 时要保存 A 的寄存器和执行位置再恢复 B 的现场。这段交接时间没有直接处理业务还可能让 CPU 缓存失效。线程数量失控、锁竞争严重、频繁进行系统调用都可能增加上下文切换。常用观察命令vmstat1pidstat-w1vmstat中的cs可以观察每秒上下文切换次数但“多少算高”没有统一数字要和机器核数、负载及历史基线一起判断。面试回答上下文切换是 CPU 在任务之间切换时保存和恢复执行现场的过程。切换本身消耗 CPU也可能破坏缓存局部性。线程过多、锁竞争和频繁系统调用都会让切换增多。14. nice 值表示什么数值越大优先级越高吗恰好相反。普通进程的 nice 值通常在-20到19之间。数值越小调度优先级越高数值越大表示这个进程越“客气”愿意把 CPU 让给别人。nice-n10commandrenice5-pPIDnice 值只影响普通调度策略下的相对权重不等于实时调度优先级也不能保证某个进程一定先运行。面试回答nice 值用于影响普通进程的调度权重通常范围是-20到19值越小优先级越高。它表达的是相对倾向不是严格的执行顺序保证。15. 什么是守护进程systemd 又是什么守护进程是在后台长期运行、提供服务的进程例如 SSH 服务和定时任务服务。它们通常不依赖交互终端。现代 Linux 发行版常用 systemd 作为 PID 1负责系统启动、服务依赖、进程监管和日志配合。操作服务时经常用systemctl status nginx systemctl start nginx systemctl restart nginx systemctlenablenginx journalctl-unginxstart是现在启动enable是设置开机自动启动两者别混。面试回答守护进程是在后台长期运行并提供服务的进程。systemd 是常见的初始化和服务管理系统通常作为 PID 1 管理系统启动、服务生命周期和依赖关系。start控制当前状态enable控制是否开机自启。第三站CPU 候诊室负载 12 不等于 CPU 使用率 1200%回到那条告警。服务器有 8 个 CPU 核心Load Average 是12.40 10.83 7.16数字一路上涨但top里的 CPU 还有不少空闲。逆境这才意识到等待 CPU 的任务不是负载的全部。16. Load Average 到底统计什么Load Average 是过去 1、5、15 分钟的平均活跃任务数。Linux 主要统计两类任务正在运行或等待 CPU 的R状态任务处于不可中断睡眠的D状态任务所以负载高有两种常见方向CPU 队列太长或者大量任务卡在 I/O。它也不是“CPU 使用率的平均值”。负载是任务数量CPU 使用率是 CPU 时间花在各类工作的比例。面试回答Load Average 表示过去 1、5、15 分钟内处于运行、等待 CPU 和不可中断睡眠状态的平均任务数。它既可能反映 CPU 排队也可能反映 I/O 阻塞不能直接等同于 CPU 使用率。17. Load Average 多高算高先看 CPU 核数。在 8 核机器上长期负载接近 8说明平均每个核心大致有一个活跃任务长期明显超过 8说明任务正在排队。可这仍不是判决书。如果负载 12CPU 几乎跑满优先找高 CPU 进程。如果负载 12CPU 却很空闲就去看D状态进程、磁盘延迟和网络存储。短暂峰值也不一定值得惊慌。1 分钟负载很高、5 分钟和 15 分钟负载较低可能只是刚出现的一阵流量。面试回答负载要结合 CPU 核数、持续时间和 CPU 使用率判断。长期高于核心数通常说明有排队负载高但 CPU 不忙时应重点检查D状态任务和 I/O 等待。18.top里的us、sy、id、wa分别是什么常见字段可以这样记us 用户态程序使用的 CPU sy 内核态使用的 CPU id CPU 空闲时间 wa CPU 等待 I/O 的时间 st 虚拟机被宿主机拿走的 CPU 时间us高常见于业务计算、死循环、序列化或垃圾回收。sy高要留意频繁系统调用、网络包处理和内核工作。wa高通常把视线引向磁盘或远程存储但还要结合iostat验证。面试回答us是用户态 CPU 时间sy是内核态 CPU 时间id是空闲时间wa是等待 I/O 的时间虚拟化环境中的st表示被宿主机占用的时间。不同字段偏高对应的排查方向不同。19. CPU 使用率很高怎么找到原因逆境一般按三层往下找topps-eopid,ppid,cmd,%cpu--sort-%cputop-H-pPID pidstat-pPID1先找高 CPU 进程再看进程里的高 CPU 线程最后结合程序的线程栈、性能剖析和日志判断是死循环、热点计算、锁竞争还是频繁系统调用。Java 程序中常把 Linux 线程 ID 转成十六进制再到线程栈里寻找对应的nid。只背这一步不够面试时最好补一句线程栈应该多抓几次确认它持续卡在同一段代码而不是碰巧采到一次。面试回答先用top或ps找到高 CPU 进程再用top -H -p PID找高 CPU 线程最后结合线程栈、性能剖析和应用日志定位代码。还要区分用户态计算、内核态开销和上下文切换。20. 负载很高CPU 却不高可能是什么原因最常见的是 I/O 堵塞。大量任务在等待磁盘、NFS 或其他内核 I/O进入D状态它们会被计入负载却没有持续占用 CPU。可以继续看ps-eostate,pid,ppid,cmd|grep^Diostat-x1pidstat-d1如果是数据库服务器还要考虑存储延迟、慢查询和大量刷盘。面试回答高负载而 CPU 不高通常说明有大量D状态任务等待 I/O也可能存在锁或资源等待。应结合进程状态、iostat、pidstat和存储情况继续定位不能看到负载高就直接扩 CPU。第四站内存仓库空房间少不代表住满了free -h显示 free 很小。逆境的第一反应是内存不足但旁边的 available 还剩好几个 GB。Linux 不喜欢让内存闲着。暂时没人住的房间会先拿来堆放最近用过的文件。新租户来了这些房间大多能很快腾出来。21. 什么是虚拟内存每个进程看到的都是一套独立的虚拟地址空间。程序使用虚拟地址CPU 和内核再通过页表把它翻译成物理内存地址。这样做有几个直接好处进程彼此隔离不容易读写别人的内存程序看到连续地址底层物理页却可以分散多个进程可以共享同一份只读代码或共享内存暂时不用的页面可以换出文件也可以按需映射虚拟内存不是 Swap 的另一种叫法。Swap 只是虚拟内存机制可能使用的一块磁盘空间。面试回答虚拟内存为每个进程提供独立的虚拟地址空间再通过页表映射到物理内存。它实现了进程隔离、灵活分配、共享页面和按需加载。Swap 只是其中可能用到的后备存储不等于虚拟内存本身。22. 什么是分页为什么要按页管理内存Linux 把虚拟内存和物理内存切成固定大小的页常见基础页大小是 4 KB但具体值与架构和配置有关。分页让内核不必寻找一整块连续物理内存也方便设置每一页的读、写、执行权限。页表负责记录虚拟页和物理页之间的映射。代价也很明显页表本身要占空间地址翻译要花时间因此 CPU 会使用 TLB 缓存近期的地址映射。面试回答分页把虚拟地址空间和物理内存划分为固定大小的页通过页表建立映射。它便于离散分配、权限控制和内存共享但会带来页表空间和地址转换开销CPU 通常用 TLB 加速转换。23. 什么是缺页异常缺页就一定要读磁盘吗程序访问某个虚拟页时如果当前映射不满足访问要求CPU 会触发缺页异常把处理权交给内核。缺页不一定读磁盘Minor Page Fault数据已经在内存中可能只需建立页表映射。Major Page Fault所需内容不在内存需要从磁盘或其他后备存储读入。Major Fault 的代价通常大得多。写时复制第一次发生写入时也会通过缺页异常让内核复制页面。面试回答缺页异常发生在进程访问的虚拟页没有有效映射或权限不满足时。轻微缺页通常只需建立映射不必读盘严重缺页需要从磁盘加载数据。写时复制也会借助缺页异常完成页面复制。24. 什么是 Page CachePage Cache 是内核用内存缓存文件内容的机制。第一次读取文件可能要访问磁盘之后再读同一部分往往可以直接从内存返回。普通文件写入时数据也可能先进入 Page Cache变成脏页随后由内核异步刷盘。这解释了两个现象第二次读文件常比第一次快。write()成功通常表示数据交给了内核不一定已经安全落盘。需要严格持久化语义时要根据场景使用fsync()等机制。面试回答Page Cache 用内存缓存文件数据减少磁盘访问。读操作可以命中缓存写操作常先修改缓存页再异步刷盘。因此写系统调用返回不一定代表数据已经持久化到物理磁盘。25.free很小为什么系统可能仍然健康看这条命令free-hfree只表示完全没有被使用的内存。Linux 会把空闲内存用于 Page Cache 等用途需要时再回收所以free小很常见。更值得看的是available它估算了在不发生明显 Swap 的情况下系统还能提供给新程序的内存。判断内存压力时还应结合 Swap 活动、回收速度和应用延迟。面试回答Linux 会主动使用空闲内存作为缓存所以free很小不等于内存不足。通常更关注available再结合 Swap、页面换入换出、OOM 日志和应用表现判断真实压力。26. 什么是 Swap用了 Swap 就一定有问题吗Swap 是磁盘上的交换空间。物理内存紧张时内核可以把一部分不活跃的匿名页换出去为更活跃的数据腾位置。少量使用过 Swap不代表系统正在出故障。某些页面很久没再访问即使之后内存宽松也未必立刻换回。真正危险的是持续、频繁地换入换出。磁盘比内存慢得多系统可能把大量时间花在搬页面上这叫内存抖动。vmstat1可以关注si和so它们反映 Swap 换入和换出活动。面试回答Swap 用磁盘保存暂时不活跃的内存页可以缓解物理内存压力。Swap 有占用不一定异常但持续大量换入换出会造成严重延迟应结合vmstat的si、so和业务表现判断。27. 什么是 OOM Killer当内核已经很难满足新的内存分配也无法通过回收缓存或换出页面解决时可能启动 OOM Killer。它会根据进程内存占用、可回收性、oom_score_adj等因素选择牺牲对象终止某个或某些进程来保住系统。排查时先找证据dmesg|grep-ioom journalctl-k|grep-ioom容器环境还要区分主机 OOM 和容器内存限制触发的 OOM。一个 Java 进程堆没有占满也可能因为直接内存、线程栈或容器限制被杀。面试回答OOM Killer 是 Linux 在严重内存不足时的自救机制会根据评分选择进程终止并释放内存。排查要查看内核日志并区分主机内存不足、容器限制、堆内存和堆外内存等来源。28. 内存一直上涨怎么区分内存泄漏和缓存增长先看增长的是谁。free-hps-eopid,cmd,rss,%mem--sort-rss pmap-xPID如果 Page Cache 增长而available仍充足系统通常可以回收它。若某个进程的 RSS 长期上升、业务量回落后也不下降就要继续检查堆、直接内存、线程数量和内存映射。“内存没有立刻还给操作系统”也不一定是泄漏。语言运行时和内存分配器可能保留空闲区域以便复用。判断泄漏要看对象或分配是否失去控制地持续增长。面试回答先区分增长来自系统缓存还是进程常驻内存。Page Cache 通常可回收进程 RSS 长期增长且负载回落后仍不稳定才需要结合堆分析、线程、直接内存和内存映射继续判断。占用不下降不等于必然泄漏。第五站文件仓库文件名只是门牌号磁盘告警仍然没有解决。逆境先查容量又查 inode最后发现一个已经删除的日志文件仍被 Java 进程打开。想看懂这个问题得先把“文件名”和“文件本身”拆开。29. inode 是什么inode 保存文件的元数据和数据块位置信息例如文件类型和权限所有者与所属组文件大小和时间链接计数数据块位置文件名不在 inode 里。目录保存“文件名到 inode 编号”的映射。可以把 inode 看成房产档案文件名则是门牌。一个档案可以有多个门牌这就是硬链接能够存在的原因。面试回答inode 保存文件的元数据和数据块索引文件名保存在目录项中目录项负责把名字映射到 inode。文件系统查找文件时先根据目录项找到 inode再访问实际数据。30. 磁盘明明还有容量为什么创建不了文件可能是 inode 用完了。文件系统创建每个文件都需要 inode。大量小文件会先耗尽 inode即使数据区还剩几十 GB也无法继续创建文件。df-h# 看容量df-i# 看 inode缓存目录、会话文件和没有轮转的小日志碎片都是常见来源。面试回答磁盘空间包含数据块和 inode 两类资源。大量小文件可能耗尽 inode导致容量尚有剩余却无法创建新文件。可以用df -h查看容量用df -i查看 inode 使用情况。31. 硬链接和软链接有什么区别硬链接是给同一个 inode 再起一个名字lnsourcehard_link删除原文件名只是减少一次链接计数另一个硬链接仍能访问数据。硬链接通常不能跨文件系统也通常不允许普通用户为目录创建硬链接。软链接则是一个独立文件里面保存目标路径ln-ssourcesoft_link它可以跨文件系统也可以指向目录目标路径失效后软链接就会变成“断链”。面试回答硬链接与原文件指向同一个 inode删除其中一个名字不影响其他硬链接通常不能跨文件系统软链接有自己的 inode内容是目标路径可以跨文件系统和链接目录但目标删除后会失效。32.chmod 755是什么意思权限分为三组所有者 所属组 其他用户 rwx r-x r-x 7 5 5其中r4、w2、x1把同一组需要的权限相加即可。对普通文件来说r是读内容w是修改内容x是执行。目录稍有不同r列出目录项w创建、删除或重命名目录中的条目x进入目录并通过名字访问其中的条目这也是为什么“文件不可写”不一定阻止删除文件。删除动作修改的是父目录的目录项主要看父目录权限。面试回答755表示所有者拥有读写执行权限组用户和其他用户拥有读执行权限。目录的读权限控制列出内容写权限控制增删目录项执行权限控制进入和按名称访问。33. SUID、SGID 和 Sticky Bit 是什么它们是三种特殊权限。SUID 设置在可执行文件上时进程执行期间可以使用文件所有者的有效身份。典型例子是普通用户修改密码时使用的passwd。SGID 用在可执行文件上与组身份有关用在目录上时新文件通常继承目录的所属组适合共享目录。Sticky Bit 常见于/tmp。目录人人可写但用户通常只能删除自己的文件避免互相乱删。面试回答SUID 让可执行文件以文件所有者的有效身份运行SGID 可以让程序使用文件所属组身份设置在目录上时还能让新文件继承目录组Sticky Bit 用于共享可写目录限制用户删除他人的文件。34. 什么是文件描述符进程打开文件、管道或 Socket 后内核返回一个非负整数这就是文件描述符。0 标准输入 1 标准输出 2 标准错误文件描述符只是进程自己的索引。它会指向内核中的打开文件对象后者再关联 inode、当前偏移量和访问模式等信息。查看限制ulimit-ncat/proc/PID/limitsls/proc/PID/fd服务报Too many open files时不能只把限制调大。还要检查连接或文件是否没有关闭。面试回答文件描述符是进程访问已打开文件、管道和 Socket 的整数句柄。每个进程有自己的描述符表描述符再指向内核的打开文件对象。耗尽时既要检查上限也要排查资源泄漏。35.df和du为什么会统计不一致df从文件系统角度统计已经分配的数据块du遍历目录统计当前能通过目录项看到的文件。如果一个大日志已经被删除但进程仍然打开它目录项虽然没了文件数据还不能释放rm 删除文件名 ↓ 目录里已经看不见 ↓ 进程仍持有文件描述符 ↓ 数据块继续占用磁盘这时du找不到它df却仍认为空间被占用。lsofL1可以查找链接计数为 0、却仍被进程打开的文件。面试回答df按文件系统已分配块统计du按目录中可见文件统计。文件被删除但仍由进程打开时目录项已经消失数据块却没有释放因此会出现df高、du低。36. 文件已经删除怎样安全释放被占用的空间最稳妥的做法是让应用正常关闭文件描述符例如重新加载日志、滚动日志或重启对应服务。不要一看到大文件就粗暴处理。先确认占用进程和文件lsofL1某些紧急场景会通过/proc/PID/fd/FD截断文件但这可能影响应用的写入位置和日志行为不能当成通用方案。夜里那次故障中逆境先确认服务有两个实例再滚动重启持有旧日志的实例。磁盘空间随文件描述符关闭而释放订单没有整体中断。面试回答删除文件只移除目录项最后一个文件描述符关闭后数据块才会释放。应先用lsof L1找到占用进程再通过日志重开、滚动重启或正常关闭文件的方式释放空间。第六站I/O 与网络通道连接多不等于都在干活磁盘空间恢复后负载慢慢下降。但订单接口仍有一部分请求超时。逆境继续检查监听端口和连接状态。37. 阻塞、非阻塞、同步、异步有什么区别这两组概念经常被混在一起。阻塞与非阻塞描述调用线程在结果暂时拿不到时怎么办阻塞线程停下来等。非阻塞调用立即返回线程可以先做别的事。同步与异步更关心结果由谁完成、怎样通知同步调用方主动等待或轮询结果。异步任务完成后由系统通过回调、事件等方式通知。非阻塞不等于异步。例如线程反复调用非阻塞read()轮询仍然是调用方自己追着问结果。面试回答阻塞和非阻塞描述调用在结果未就绪时是否等待同步和异步描述结果完成及通知方式。非阻塞调用可以立即返回但如果调用方持续轮询它仍不等于真正的异步处理。38.select、poll、epoll有什么区别它们都用于同时等待多个文件描述符就绪。select每次都要传入描述符集合内核返回后应用还要遍历寻找谁就绪它通常还有集合大小限制。poll使用数组摆脱了select固定集合大小的常见限制但寻找就绪描述符仍要线性扫描。epoll在内核维护关注列表。应用注册事件后等待时主要获取已经就绪的描述符更适合“大量连接、少量活跃”的服务器场景。不要把epoll背成“任何情况都更快”。连接数很少或全部一直活跃时它的优势会缩小实际性能还受业务模型和实现影响。面试回答select和poll每次等待都需要传递或检查一批描述符查找就绪事件通常是线性的epoll在内核维护关注集合只返回就绪事件更适合大量连接、少量活跃的场景。39. epoll 的 LT 和 ET 有什么区别LT 是水平触发。只要接收缓冲区里还有数据每次等待时都可能继续提醒像水杯没喝空就一直亮灯。ET 是边缘触发。状态从“没数据”变为“有数据”时提醒一次像只在水刚流进来时响铃。如果这次没读完未必马上再提醒。ET 通常配合非阻塞 I/O并循环读到返回EAGAIN。否则剩余数据可能长时间得不到处理。面试回答LT 只要描述符仍处于就绪状态就会重复通知编程简单ET 通常只在状态变化时通知需要配合非阻塞 I/O一次处理到返回EAGAIN。ET 减少重复通知但更容易写错。40. 什么是零拷贝传统文件发送可能经历这样的过程磁盘 ↓ 内核缓冲区 ↓ 用户缓冲区 ↓ Socket 内核缓冲区 ↓ 网卡中间的数据复制和用户态、内核态切换会消耗 CPU。零拷贝技术尽量减少这些不必要的复制或切换例如 Linux 的sendfile()可以让文件数据在内核路径中直接送往 Socket。“零拷贝”通常不是物理上一次复制都没有而是避免数据在用户空间和内核空间之间来回搬运。具体复制次数与内核、网卡能力和实现有关。面试回答零拷贝通过sendfile、mmap等机制减少用户空间与内核空间之间的数据复制和上下文切换降低 CPU 开销。它通常表示减少不必要的复制不一定是整个硬件链路绝对零复制。41. 端口被占用怎么查先看谁在监听ss-lntpss-lntp|grep:8080lsof-i:8080ss中l 只看监听 n 不解析名称直接显示数字 t TCP p 显示进程找到 PID 后再确认它是旧实例、正常依赖还是意外启动的程序。不要条件反射地kill -9否则很可能把真正提供服务的进程干掉。面试回答可以使用ss -lntp或lsof -i :端口查找监听端口及对应进程。确认进程用途后再决定停止旧实例、修改端口还是修复重复启动问题。42. 进程还在为什么服务访问不了“进程存在”只说明进程表里还有它不代表服务已经能正常处理请求。排查顺序可以沿着请求路径走进程是否存活 ↓ 端口是否监听 ↓ 监听在 127.0.0.1 还是 0.0.0.0 ↓ 本机访问是否成功 ↓ 防火墙、安全组、路由是否放行 ↓ 反向代理和负载均衡是否正常 ↓ 应用线程池、连接池和下游依赖是否耗尽常用命令ps-efss-lntpcurl-vhttp://127.0.0.1:8080/health journalctl-uservice-name如果端口存在但请求一直挂起应用可能死锁、线程池耗尽、GC 停顿或者卡在数据库等下游服务。面试回答应沿请求链路排查先确认进程和监听端口再检查监听地址、本机访问、防火墙、代理和负载均衡最后查看线程池、连接池、日志及下游依赖。进程存活不等于服务可用。43. TCP 常见连接状态有哪些面试中最常问的是这几个LISTEN 服务端正在监听 ESTABLISHED 连接已经建立 SYN-SENT 主动发起连接等待回应 SYN-RECV 收到连接请求等待最后一次握手 TIME-WAIT 主动关闭方等待旧报文过期 CLOSE-WAIT 被动关闭方收到 FIN但本地应用还没关闭大量TIME-WAIT不一定是故障它是 TCP 主动关闭方的正常状态用于避免旧报文影响新连接并保证最后的 ACK 有机会重传。大量CLOSE-WAIT更值得检查常见原因是对端已经关闭连接本地程序却没有及时close()。面试回答TIME-WAIT通常出现在主动关闭连接的一方用来处理迟到报文和最后 ACK 重传大量CLOSE-WAIT往往说明对端已经关闭而本地应用没有及时释放连接应检查程序的连接关闭逻辑。第七站把排障过程说成一条线面试官问“服务器突然变慢怎么查”最怕听到的是一串没有顺序的命令top、free、df、netstat、jstack、iostat……命令都对但像把工具箱倒在地上。更好的回答是先分类再逐层定位。44. Linux 服务器整体变慢怎么排查逆境会先看四个方向uptime# 负载趋势top# CPU、内存、进程vmstat1# 运行队列、内存、换页、上下文切换free-h# 内存iostat-x1# 磁盘延迟和繁忙程度df-h# 磁盘容量df-i# inodess-s# 网络连接概况dmesg# 内核错误思路比命令更重要先确认影响范围是单个接口、单个进程还是整台机器。判断瓶颈在 CPU、内存、磁盘还是网络。从系统指标缩小到具体进程和线程。对照应用日志、发布时间和流量变化确认根因。比如 CPU 高就找高 CPU 线程负载高但 CPU 空闲就看 I/OSwap 持续进出就查内存压力只有某个接口慢则更可能是应用锁、数据库或下游调用。面试回答我会先确认影响范围和发生时间再用负载、CPU、内存、磁盘、网络指标确定瓶颈方向然后定位到具体进程、线程或连接最后结合应用日志、变更记录和流量验证根因。排查顺序是先系统、再进程、最后代码和依赖。45. 磁盘 I/O 很高怎么排查先确认是哪个磁盘慢再找谁在读写iostat-x1pidstat-d1iotopiostat -x中常关注await I/O 请求的平均等待时间 %util 设备忙碌程度 r/s 每秒读请求数 w/s 每秒写请求数不要只凭%util一个数字下结论。SSD、并行队列和云盘环境下设备特性差别很大。要把延迟、吞吐、队列和业务响应时间放在一起看。找到进程后再判断是日志暴增、数据库随机 I/O、大文件扫描、频繁fsync还是内存不足导致 Swap。面试回答先用iostat -x判断设备延迟、吞吐和繁忙程度再用pidstat -d或iotop找到高 I/O 进程最后结合应用行为判断是日志、数据库、文件扫描、刷盘还是 Swap。不能只看单个%util指标。46. 日志应该从哪里查服务由 systemd 管理时可以先看systemctl status service-name journalctl-uservice-name journalctl-uservice-name--since30 minutes ago传统日志常放在/var/log应用也可能写到自己的日志目录。内核问题看dmesgjournalctl-k排查时先对齐时间。服务器时区、容器时区和应用日志时区不一致常让人追错十几分钟甚至几个小时。面试回答systemd 服务可以通过systemctl status和journalctl -u查看传统系统日志常在/var/log内核问题看dmesg或journalctl -k。分析时要先确认时间范围和时区再关联告警、发布和请求日志。面试前十分钟把整栋 Linux 大楼画回来凌晨三点零八分订单接口恢复。故障链路并不神秘日志轮转脚本删掉了旧日志但 Java 进程仍握着原文件描述符磁盘空间没有释放后续写入开始失败部分请求反复重试存储 I/O 和系统负载随之升高。逆境在值班记录里画下这张图用户命令 ↓ Shell 与应用 ↓ 系统调用 Linux 内核 ├─ 调度进程和线程 ├─ 映射虚拟内存 ├─ 管理 inode 与文件描述符 └─ 处理磁盘和网络 I/O这几条线能串起大部分 Linux 面试题。看到 CPU就想到运行队列、上下文切换和 Load Average看到内存就想到虚拟地址、分页、Page Cache、Swap 和 OOM看到文件就想到目录项、inode、文件描述符看到高负载但 CPU 不高就去找D状态和 I/O。一页背诵提纲1. 系统 用户程序通过系统调用进入内核 一切皆文件说的是统一接口 /etc 看配置/var/log 看日志/proc 看进程和内核 2. 进程 进程管资源线程被调度 fork 创建exec 替换fork 常用写时复制 R 运行或就绪S 可中断睡眠D 不可中断睡眠Z 僵尸 僵尸已经退出未回收孤儿仍在运行但父进程已退出 kill 默认发 TERMkill -9 发不可捕获的 KILL 3. CPU Load Average 统计 R 和 D 状态任务 负载要结合核数、CPU 使用率和持续时间 us 看用户态sy 看内核态wa 看 I/O 等待 4. 内存 虚拟地址通过页表映射到物理页 Minor Fault 通常不读盘Major Fault 需要加载数据 free 小不等于内存不足重点看 available Page Cache 可回收持续 Swap 才值得警惕 OOM 是内核在严重内存不足时的自救 5. 文件 文件名在目录项里元数据和数据索引在 inode 里 硬链接共享 inode软链接保存目标路径 文件描述符是进程访问文件和 Socket 的整数句柄 df 看已分配块du 看目录中可见文件 文件删了仍占空间通常是进程还开着它 6. I/O 与网络 非阻塞不等于异步 epoll 适合大量连接、少量活跃 LT 会重复提醒ET 要读到 EAGAIN TIME-WAIT 常见于主动关闭方 CLOSE-WAIT 太多常查应用是否忘记关闭连接 7. 排障 先确认范围再分 CPU、内存、磁盘、网络 从系统指标定位到进程、线程和连接 最后结合日志、变更和流量确认根因最后一次自测合上文章试着回答为什么 Load Average 很高CPU 使用率却可能不高fork()为什么不需要立刻复制父进程的全部物理内存僵尸进程和孤儿进程分别处于什么状态为什么kill -9也可能无法让D状态进程立刻退出free很小为什么不能直接判断内存不足文件删除后df为什么可能不下降硬链接和软链接在 inode 上有什么区别为什么 ET 模式必须配合非阻塞 I/O并读到EAGAIN大量TIME-WAIT和大量CLOSE-WAIT哪个更像应用代码没有关闭连接如果服务器整体变慢你会按什么顺序排查能把这些问题用自己的话讲明白就不用把四十多道答案背成口令。面试官换一种问法你仍然能从运行链路里把答案推回来。