Featured image of post SRE面试题汇总 | Linux

SRE面试题汇总 | Linux

CPU 使用率很高,怎么排查?

  1. 首先通过 top、ps 等命令,定位占用 CPU 最高的进程。

  2. 使用 top -Hp <PID>,定位进程中占用 CPU 最高的线程。

  3. 导出并分析线程堆栈。以 Java 为例,可以将线程 ID 转换为十六进制,再在 jstack 输出中匹配对应的线程,定位具体的方法和类。

    1
    2
    
    printf "%x\n" 1235
    jstack <PID>
    
  4. 常见原因及处理方式:

    • 死循环或密集计算: 代码中存在 while (true) 等没有退出条件的循环,或复杂的递归与大规模计算,需要优化算法或修复代码逻辑。
    • 频繁垃圾回收(GC): 内存不足或对象创建过于频繁,导致 Full GC 频繁触发,CPU 花费大量时间在垃圾回收上,可以使用 jstat -gcutil 进一步确认。
    • 高并发请求冲击: 系统本身没有故障,只是瞬时流量过大,超出了服务器的负载能力,需要考虑限流、扩容或优化请求处理逻辑。

CPU 性能指标速查

字段含义高负载场景常见原因排查工具与解决思路
us用户态 CPU 时间占比应用程序本身消耗了大量 CPU大量计算、QPS 增加、死循环、频繁 GC使用 top -H -p <PID>、perf top 及语言自带工具(如 Go 的 pprof、Java 的 jstack);优化算法、修复死循环或横向扩容
sy内核态 CPU 时间占比CPU 主要消耗在内核层面大量系统调用(open/read/write/futex)、频繁创建和销毁线程、上下文切换过多使用 strace -c -p <PID>、vmstat 1、pidstat -w;减少锁竞争,使用连接池/线程池,批量处理 I/O
ni由 nice 调整过的用户态进程所消耗的 CPU低优先级后台任务占用 CPU批处理任务、备份脚本等通常属于预期行为;可通过调整任务执行时间或 Nice 值进行控制
id空闲 CPU 时间占比id 很低表示 CPU 忙CPU 容量不足或存在突发流量结合 us、sy、wa 等指标判断 CPU 忙碌原因
wa等待 I/O 的 CPU 时间占比CPU 主要在等待 I/O 完成磁盘 IOPS 瓶颈、同步刷盘、磁盘故障导致延迟升高使用 iostat -xz 1、pidstat -d、iotop;排查磁盘、存储和 I/O 调用
hi硬件中断时间占比CPU 花费大量时间处理网卡、磁盘等硬件中断网络流量或硬件中断过多使用 cat /proc/interrupts 查看中断分布;配置网卡多队列和 irqbalance
si软件中断时间占比CPU 花费大量时间处理软件中断常见于网络包量大、TCP 连接建立和销毁频繁,也可能与定时器或块设备 I/O 有关使用 mpstat -I SUM -P ALL 1、sar -n DEV 1;优化网络连接复用、RPS/RFS 和相关内核参数
st被虚拟机宿主机占用的 CPU 时间占比虚拟机拿不到足够的 CPU宿主机超卖或其他虚拟机争抢资源联系云厂商排查宿主机负载,或迁移到其他节点/独占实例

CPU 使用率不高,但 Load 很高

CPU 使用率不高但 Load 很高,通常说明有大量进程处于可运行状态(R),或处于不可中断睡眠状态(D)。D 状态通常与磁盘、网络存储等 I/O 等待有关,也需要关注锁竞争、NFS 和文件系统问题。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
Load 高
  │
  ▼
1. 先确认是否真的异常
   uptime / nproc
  │
  ├─ 1min 高,5/15min 低
  │    └─ 可能是瞬时突发
  │       检查流量、定时任务、发布、批处理
  │
  └─ 1/5/15min 都高
       或 Load 持续高于 CPU 核数 / 历史基线
       │
       ▼
2. 查看 CPU 是总体高、单核高,还是不高
   top
   mpstat -P ALL 1 5
       │
       ├─ 某个 CPU Core 很高
       │    └─ 单核或绑核问题
       │       检查热点线程、CPU affinity、taskset
       │
       ├─ 所有 CPU Core 都高
       │    └─ CPU 容量不足
       │       检查高 CPU 进程、线程和业务流量
       │       top -H / pidstat -u -t 1
       │
       └─ 总体和单核 CPU 都不高
            └─ 重点排查资源等待
               │
               ▼
3. 使用 vmstat 对问题分类
   vmstat 1 5
               │
               ├─ b(不可中断进程)高或 wa(I/O 等待)高
               │    └─ 大量任务阻塞或等待 I/O
               │       进入「I/O 排查」
               │
               ├─ si / so 持续较高
               │    └─ 发生 Swap
               │       free -h
               │       swapon --show
               │       排查内存不足
               │
               ├─ st 高
               │    └─ 虚拟机被宿主机抢占 CPU
               │       排查宿主机超卖和资源争抢
               │
               ├─ r 高(等待运行的进程数),但 CPU 使用率不高
               │    └─ 任务等待 CPU,但 CPU 没有充分利用
               │       检查 CPU affinity、容器 CPU quota、
               │       CPU throttling 和虚拟机 steal time
               │
               └─ r、b、wa、si/so、st 都不明显
                    └─ 延长采样时间,并检查 D 状态、
                       锁竞争、NFS、文件系统和驱动

I/O 排查

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
I/O 排查
  │
  ▼
4. 查看是否存在大量 D 状态进程
   ps -eo pid=,ppid=,stat=,pcpu=,wchan:25=,comm= |
   awk '$3 ~ /^[DR]/'
   或 top -H
  │
  ├─ 没有大量 D 状态
  │    └─ 继续检查 R 状态、CPU 调度和 cgroup 限制
  │
  └─ 存在大量 D 状态
       │
       ▼
5. 查看进程卡在哪个内核等待点
   cat /proc/<PID>/wchan
   cat /proc/<PID>/stack
       │
       ▼
6. 检查磁盘和存储性能
   iostat -xz 1
   pidstat -d 1
   iotop
       │
       ├─ await、aqu-sz、%util 较高
       │    └─ 磁盘或底层存储性能不足
       │       检查 IOPS、吞吐、队列、慢盘、云盘、RAID、Ceph、SAN
       │
       ├─ 本地磁盘或云盘
       │    └─ df -h
       │       df -i
       │       dmesg -T
       │       journalctl -k
       │
       ├─ NFS、EFS、Ceph 或其他网络存储
       │    └─ findmnt / mount
       │       检查网络延迟、挂载状态和远端存储服务
       │
       └─ 磁盘指标正常
            └─ 继续排查锁竞争、文件系统、网络存储
               以及内核或驱动异常

进程、线程、协程

  • 进程:操作系统分配资源的基本单位,一个进程可以拥有多个线程,并拥有独立的地址空间和资源。
  • 线程:进程内的执行单位,同一进程中的线程共享进程的大部分资源,但拥有独立的栈和寄存器状态。
  • 协程:由用户态运行时调度的轻量级执行单元,不直接由内核调度,通常运行在线程之上。

Linux 中的进程优先级与设置方法

进程的优先级决定了其获取 CPU 时间片的顺序。优先级更高(数值更低)的进程会优先获取 CPU 时间片。 对于普通进程,Nice 值会影响其调度优先级,范围是 -20(最高优先级)到 19(最低优先级)。实时进程还使用独立的实时优先级。 默认情况下,进程的 Nice 值为 0。

  • nice 命令:nice 命令用于启动一个进程,并设置其 Nice 值。例如,nice -n 10 command 会以 Nice 值为 10 来启动 command。
  • renice 命令:renice 命令用于修改已经在运行的进程的 Nice 值。例如,renice +5 -p 1234 会将 PID 为 1234 的进程的 Nice 值增加 5。需要注意的是,只有 root 用户或具备 CAP_SYS_NICE 权限的进程才能降低 Nice 值、提高调度优先级。
  • 在代码中调用 nice() 或 setpriority() 函数:如果你正在编写一个程序,你可以在代码中调用 nice() 或 setpriority() 函数来改变你的进程的优先级。

什么是僵尸进程

僵尸进程是指一个已经终止运行、但父进程尚未回收其退出状态的进程。此时内核仍会保留少量进程描述信息,供父进程通过 wait() 等系统调用读取;进程占用的大部分资源已经释放。

什么是中断

中断是系统用来响应硬件设备请求的一种机制,会打断进程的正常调度和执行,然后调用内核的中断处理程序来响应设备的请求。 取外卖案例,不用苦苦等待,打电话的动作就是中断。 中断是一种异步处理机制,可以提高系统的并发处理能力。

软中断、硬中断、不可中断进程

Linux 通常将中断处理分为上半部分和下半部分: 上半部分直接处理硬件请求,特点是快速执行(硬中断)。 下半部分延后处理耗时工作,特点是延迟执行(软中断或其他下半部机制)。 不可中断进程(D 状态)表示进程正在等待某些不可中断的内核操作,常见于 I/O 等待。进程长时间处于 D 状态,通常需要排查存储、网络文件系统或驱动问题。

进程间通信的方式及其使用场景

  1. 管道(Pipe)和命名管道(Named pipe):管道通常用于具有父子关系的进程间通信;命名管道可以用于没有亲缘关系的进程。它们主要用于数据的流式传输,双向通信通常需要两个管道或使用 Socket。
  2. 消息队列(Message Queue):消息队列是一种列表结构,可以存储要发送的消息。进程可以向消息队列中添加消息,也可以从中读取消息。消息队列常用于不同进程间的数据交换和同步。
  3. 共享内存(Shared Memory):共享内存是最快的 IPC 方式,它允许两个或多个进程访问同一块内存区域。这种方式常用于大量数据的交换。
  4. 信号(Signal):信号是一种异步的通信方式,用于通知接收进程某个事件已经发生。例如,当一个进程结束时,它会发送一个 SIGCHLD 信号给其父进程。
  5. 套接字(Socket):套接字可以用于不同机器之间的进程通信,也可以用于同一机器上的进程通信。它支持 TCP、UDP 等多种协议,常用于网络通信。
  6. 信号量(Semaphore):信号量主要用于解决竞态条件,保护关键资源的访问。当多个进程需要访问同一资源时,可以使用信号量进行同步。
  7. 文件锁(File Locking):文件锁可以用于控制多个进程对同一文件的访问。当一个进程正在访问某个文件时,其他进程必须等待,直到该进程释放了文件锁。

cgroup 中限制 CPU 的方式有哪些

cgroups 是 control groups(控制组)的缩写,是 Linux 内核提供的资源管理机制,可以限制、控制和隔离进程使用的 CPU、内存、磁盘 I/O 等资源。 常见的 CPU 限制方式有两种:

  1. 基于 CPU 配额的硬限制:cgroup v1 使用 cpu.cfs_quota_us 和 cpu.cfs_period_us,cgroup v2 使用 cpu.max,限制进程在一个周期内最多使用的 CPU 时间。
  2. 基于相对权重的限制:cgroup v1 使用 cpu.shares,cgroup v2 使用 cpu.weight,用于 CPU 竞争时按比例分配资源,并不是绑定到固定的 CPU 核心。

内存中的 Buffers 与 Cached 的区别

设计目的是提升系统的 I/O 性能。

Buffers 是内核块设备缓冲区使用的内存,对应 /proc/meminfo 中的 Buffers 值。 Cache 是内核页缓存和可回收 Slab 使用的内存,对应 /proc/meminfo 中的 Cached 与 SReclaimable 等字段。

Buffers 是用于临时存储待写入硬盘的数据,而 Cached 是用于存储已经从硬盘读取的数据,以便快速访问。 Buffer 是对磁盘数据的缓存。而 Cache 是文件数据的缓存,它们既会用在读请求中,也会用在写请求中。

Linux是尽可能使用内存原则,内存会把剩余的空间申请为cache,而cache不属于free,当系统运行时间很长,我们会发现cache很大。

当我们看到系统内存使用率很高,free几乎为0时,并不代表系统内存容量有瓶颈!只是系统充分发挥了内存作用。而当有进程需要申请大文件内存时,内核会将部分cache空间回收,回收的内存再分配给进程程序使用。

栈内存和堆内存的区别

  1. 栈内存(Stack) 特点:栈内存是自动分配和释放的,具有先进后出(LIFO,Last In First Out)的特性。栈内存中的变量会在函数调用时创建,并在函数返回时自动销毁。其管理由编译器控制,因此效率较高。 用途:通常用于存储局部变量、函数参数等临时数据。栈内存的分配通常很快,因为它只是调整一个指针来跟踪当前的栈顶位置。 优点:内存分配和释放速度快,不容易产生内存碎片。 缺点:栈内存的大小通常有限,不能用于存储大量数据或长时间使用的数据。
  2. 堆内存(Heap) 特点:堆内存是动态分配的,大小不固定,需要程序员手动分配和释放。如果忘记释放,可能会导致内存泄漏。它没有严格的先进后出的顺序,可以在程序的任何位置请求内存分配。 用途:用于存储需要动态分配的大量数据,如对象、全局数据等。通过 malloc() 或 new 等操作分配,通过 free() 或 delete 等操作释放。 优点:适合长时间使用的数据或较大的数据结构,比如链表、树等。堆内存的大小相对栈来说几乎是无限的(受制于物理内存和系统限制)。 缺点:由于需要手动管理,堆内存分配和释放速度较慢,且容易导致内存碎片。

区别总结:

  • 生命周期:栈内存中的数据在函数调用期间有效,而堆内存的数据在手动释放前一直有效。
  • 分配方式:栈是由系统自动分配和管理,堆是由程序员动态分配和管理。
  • 效率:栈内存效率高,堆内存分配和释放较慢

进程最大数、最大线程数、进程打开的文件数,怎么调整

查看当前限制

以下限制针对当前 Shell 或当前用户会话:

1
2
3
ulimit -a
ulimit -u      # 当前用户可创建的进程/线程数
ulimit -n      # 单个进程可打开的文件描述符数

调整最大文件数

临时生效 ulimit -n 65535

永久生效 sudo vim /etc/security/limits.conf

添加如下内容

  • soft nofile 65535
  • hard nofile 65535

调整最大进程数 / 最大线程数

临时生效 ulimit -u 65535

永久生效 sudo vim /etc/security/limits.conf

添加如下内容

  • soft nproc 65535
  • hard nproc 65535

注意事项

soft 软限制:当前会话实际生效的限制,用户可以将它提高到 hard 限制以内。 hard 硬限制:软限制可以达到的上限,通常只有 root 或具备相应权限的用户才能提高。

/etc/sysctl.conf 用于配置系统级内核参数,可通过 sysctl -p 立即加载,通常不需要重启。 /etc/security/limits.conf 用于配置用户级限制,通常需要重新登录才能对新会话生效;systemd 服务还需要在 unit 中配置对应的 LimitNOFILE、TasksMax 等参数。

Load 和 CPU 使用率的区别

Load 平均负载是指一段时间内,处于可运行状态(R)和不可中断睡眠状态(D)的任务数的平均值。 CPU 使用率是指一段时间内,CPU 用于处理任务的时间占总时间的比例。

最理想的情况:平均负载接近 CPU 核心数,每个核心上都有一个可运行任务。

1
2
3
4
5
6
查看CPU核心数
grep 'model name' /proc/cpuinfo | wc -l


uptime
 06:44:50 up 190 days, 22:44,  4 users,  load average: 0.42, 0.14, 0.04

两者之间关系

  • CPU 密集型进程,使用大量 CPU 会导致平均负载升高,此时这两者是一致的
  • I/O 密集型进程,等待 I/O 也会导致平均负载升高,但 CPU 使用率不一定很高
  • 大量等待 CPU 的进程调度也会导致平均负载升高,此时的 CPU 使用率也会比较高

du、df 查看磁盘结果不一致

系统中可能存在大量被删除的文件(僵尸文件),且有运行的进程在使用这些文件的句柄。

当一个文件被删除后,如果有进程仍然打开着该文件,du 不会统计这部分空间,因为文件已经从目录结构中移除;然而,df 会统计这部分空间,因为磁盘空间实际上还被占用。

解决方法

  • 重启相关服务:重启仍持有文件句柄的进程,释放已删除文件占用的空间。生产环境应优先采用平滑重启。
  • 查找并关闭进程:使用 lsof 或 fuser 等工具查找并关闭使用僵尸文件的进程。
    1
    
    lsof | grep deleted
    
  • 如果暂时不能重启进程,可以结合业务情况,通过进程自身的日志切割或文件截断机制释放空间;不要重复删除已经显示为 deleted 的文件。

硬链接和软链接的区别

硬链接和软链接是两种不同类型的文件系统链接,用于在目录之间共享文件。

硬链接:

a. 具有相同inode节点号的多个文件互为硬链接文件; b. 硬链接文件是文件的另一个入口 c. 可以通过给文件设置硬链接文件来防止重要文件被误删; d. 删除硬链接文件或者删除源文件,文件实体不会被删除,只有都删除才会生效

软连接:

a. 软链接类似windows系统的快捷方式 b. 软链接里面存放的是源文件的路径,指向源文件 c. 删除源文件,软链接依然存在,但无法访问源文件内容 d. 软链接和源文件是不同的文件,文件类型也不同,inode号也不同;

LVM 怎么划分

  • 创建物理卷(PV)
  • 创建卷组(VG)
  • 创建逻辑卷(LV)
  • 格式化逻辑卷(LV)
  • 挂载逻辑卷(LV)

在公有云运维中,很少见到使用 LVM 划分云盘,这属于常见情况。

  • 云盘可以直接扩容,不需要 LVM 的 PV/VG/LV
  • 传统环境中,LVM 与 RAID 可以配合使用,但二者职责不同;云盘底层通常已经提供多副本和冗余能力
  • Kubernetes 弱化了主机侧 LVM 的使用,容器数据通常通过 PVC 管理

常见的 RAID 有哪些,使用场景是什么

常见的 RAID 级别有以下几种:

  • RAID 0:striping(条带化),将数据分成多个块,并行写入多个磁盘,提高读写速度。但不提供数据冗余,一旦磁盘故障,数据将丢失。
  • RAID 1:mirroring(镜像),将数据在多个磁盘上进行镜像备份,提供数据冗余。但写入速度受限于较慢的磁盘。
  • RAID 5:striping with parity(条带化加校验),将数据分成多个块,并行写入多个磁盘,同时存储校验信息,可容忍一块磁盘故障,但写入会产生额外的校验开销。
  • RAID 6:striping with double parity(条带化加双校验),在 RAID 5 的基础上增加一组校验信息,可容忍两块磁盘故障。

使用场景:

  • RAID 0:用于对性能要求较高的场景,如数据库、视频编辑等。
  • RAID 1:用于对数据冗余要求较高的场景,如企业关键数据存储。

如何创建和管理自定义 systemd 服务

自定义服务配置文件位置:/etc/systemd/system/

创建或者修改单元文件后需要重新加载配置生效 sudo systemctl daemon-reload

Linux 系统中 /proc 是做什么的

用户和内核交互的接口,性能工具数据(top、free、ps)的来源

1
2
3
4
5
启动当前进程的完整命令:
/proc/<进程号>/cmdline

当前进程的环境变量列表:
/proc/<进程号>/environ

/proc 中的部分文件使用 NUL 字符分隔内容,例如 cmdline,需要转换后才能按行阅读:

1
cat /proc/3824/cmdline | tr '\0' '\n'

lsof 命令使用场景

  • 查看某个进程打开的文件 lsof -p 1234
  • 查看哪个进程正在使用特定端口 lsof -i :80
  • 查看所有网络连接 lsof -i
  • 查看某个用户打开文件 lsof -u username
  • 文件已经被删除,但仍然被某个进程占用 lsof | grep deleted
Licensed under CC BY-NC-SA 4.0
最后更新于 Sep 09, 2026 15:51 +0800
Built with Hugo
Theme Stack designed by Jimmy 🚀
文章发布: 31 篇