面试预备:Linux指令专题

📌 说明(请先看这一句)

这份笔记的原文内容出自 小林coding 的《Linux 命令面试题》 ,我这份是把原文和我自己在 DeepSeek Harness 里逐条追问、补充理解后搭配整理出来的学习笔记。

原本的笔记是小林coding 的,我们这是搭配来看的,我不是原作者。 原文版权归小林coding 所有,建议对着原文一起看:https://xiaolincoding.com/interview/linux.html

笔记里的标记约定:

标记 含义
重点·内存 内存相关的重点,面试高频,也是本篇着重标注的部分
🔤 命名溯源 这条命令/参数是由哪几个英文单词拼出来的
💡 补充理解 我在原文之外自己追问补充的内容
⚠️ 易错点 容易记混、写错的地方

Linux 命令面试题 · 学习笔记

⭐ 本篇重点(内存部分,优先看)

如果你时间不多,只想看内存,直接跳到第八节,按这个顺序看:

  1. top 和 free 都能看内存,区别在哪 → 8.1
  2. 怎么判断服务器内存够不够用 / 性能瓶颈是不是内存 → 8.2
  3. 如何判断内存是不是满了,用什么指标看使用率 → 8.3
  4. 怎么判断操作系统有没有在内存替换、怎么统计内存替换的频率8.4(压轴,含 pgscank/s pgscand/s pgsteal/s 的完整拆解)
  5. 「内存替换」到底是不是 Swap → 8.5

一、Linux 的常用命令了解过哪些?

按用途分类背,比背清单好记:

分类 命令
文件相关 mv mkdir cd ls
进程相关 ps top kill pkill
权限相关 chmod chown useradd groupadd
网络相关 netstat ip addr
测试相关 测试网络连通性 ping,测试端口连通性 telnet

🔤 命名溯源

命令 全称 拆解
ls l ist 列表
cd c hange directory 改变目录
mv m ove 移动(也用于重命名)
mkdir m ak e directory 创建目录
chmod ch ange mode 改变模式(权限位)
chown ch ange owner 改变属主
ps p rocess status 进程状态
kill kill 发送信号,不一定真「杀掉」

二、ps 命令里都有哪些选项,ps 展示哪些东西?

ps 展示的内容

字段 含义
PID 进程 ID
PPID 父进程 ID
USER 进程所属用户
%CPU CPU 占用率
%MEM 内存占用率
VSZ 虚拟内存大小
RSS 物理内存大小(常驻内存)
TTY 终端设备
STAT 进程状态
START 进程启动时间
TIME 进程累计 CPU 占用时间
COMMAND 进程命令或可执行文件

💡 VSZ = V irtual memory S iZ e,RSS = R esident S et S ize(常驻集大小,真正占着物理内存的那部分)。面试常问:VSZ 很大不代表真的占了很多物理内存,因为虚拟内存是「许诺」出去的地址空间,物理内存页是惰性分配的。

ps 的常用选项

选项 英文来源 含义
-a all 显示与终端关联的所有进程(含其他用户的,但不含会话首进程)。注意它并不等同于 -e
-u user 显示用户相关的进程信息
-x 无终端 显示没有控制终端的进程
-e every process 显示系统中所有进程,等同于 -A
-f full 显示详细进程信息(含父进程、运行状态等)
-l long 长格式输出(PID、PPID、CPU 占用率等)
-r running 只显示正在运行的进程
-o output format 自定义输出格式

⚠️ 易错点ps -aps -e 经常被当成一回事,其实不是。记法:-a 是「有终端的」,-e 是「全部」。


三、top 命令会展示什么,每一项都是什么数据?

区域 内容
Load average(平均负载) 系统在最近 1 分钟、5 分钟、15 分钟的平均负载
Tasks(任务) 当前运行、睡眠、停止、僵尸状态的进程数量
CPU usage(CPU 使用情况) 总体使用率 + 每个核心的使用率
Memory usage(内存使用) 物理内存的总量、已用、空闲、buffer、cache
Swap usage(交换空间) 交换空间的总量、已用、剩余
进程列表 PID、用户、CPU 占用率、内存占用率、状态、启动时间、命令

🔤 top 这个名字的常见解释是 table of processes(进程表格),更朴素的理解就是「把最活跃的进程排到最上面」,所以叫 top。

💡 在 top 里按数字 1,可以把 CPU 展开成每个核心一行 ------ 这就是「top 怎么查看有多少个 CPU 核心」的答案。


四、进程与线程:查看状态、杀进程

已知一个进程名,如何杀掉这个进程?

方式一:ps + kill 两步走

bash 复制代码
ps -ef | grep <进程名>   # 先找到 PID
kill <PID>              # 发 SIGTERM(15),优雅终止
kill -9 <PID>           # 发 SIGKILL(9),强制终止

方式二:直接按进程名杀(推荐)

bash 复制代码
pkill <进程名>       # 按进程名模糊匹配并杀死
pkill -9 <进程名>    # 强制终止
killall <进程名>     # 按进程名精确匹配,杀死所有同名进程

💡 原则:优先 SIGTERMkill <PID>),让进程做完清理再退出;只有在进程不响应、卡死时才用 SIGKILLkill -9 ,因为 -9 不给进程任何收尾机会,可能造成文件/锁/中间状态损坏。

🔤 命名溯源pkill = p attern kill (按模式匹配杀);killall = kill all(同名全杀)。

如何查看进程状态?

pstop。top 除了能看进程状态,还能看到系统信息(负载、内存、CPU 使用率)。

如何查看线程状态?

pstop 上加参数:

bash 复制代码
top -H
ps -eT | grep <进程名或线程名>

🔤 命名溯源(容易被问的参数)

写法 英文来源 说明
top -H tHreads 大写 -H 表示 Threads mode(线程模式),显示每个独立线程。它不是严格的「首字母」缩写------因为 T 已被别的用途占用了,所以取了 H
top -h help 小写 -h 通常是显示帮助信息,别写混
ps -e every process 显示所有进程
ps -T Threads 显示每个进程的线程

⚠️ top -H 里的大写 -H 是本节最容易记错的点:大小写敏感,-H 看线程、-h 看帮助


五、网络相关:连接、端口、连通性

如何查看网络连接情况?

bash 复制代码
netstat -napt

输出的是服务器上的 TCP 连接状态,可以看到每个 TCP 连接的状态,以及四元组信息(源 IP、目标 IP、源端口、目标端口)。

🔤 -napt 是四个短参数合并书写 ,等价于 -n -a -p -t

参数 英文 含义
-n numeric 用数字显示 IP 和端口,不做主机名/服务名解析
-a all 显示所有套接字(监听 + 已建立连接)
-p p rocess / program 显示占用套接字的进程信息
-t TCP 只显示 TCP 套接字

参数顺序可以调整,所以下面几种写法一般等价:

bash 复制代码
ss -napt
ss -ntap
ss -t -n -a -p

💡 现在更推荐 ss(socket statistics,套接字统计),它是较新的工具,通常比逐渐被淘汰的 netstat 更快。查看其他用户的进程信息可能需要 sudo

怎么查看哪个端口被哪个进程占用?

lsof

bash 复制代码
lsof -i :80
text 复制代码
COMMAND     PID  USER   FD   TYPE   DEVICE SIZE/OFF NODE NAME
nginx       929  root    6u  IPv4    15249      0t0  TCP *:http (LISTEN)
nginx       934 nginx    6u  IPv4    15249      0t0  TCP *:http (LISTEN)

netstat

bash 复制代码
netstat -napt | grep ':80 '
text 复制代码
tcp    0    0 0.0.0.0:80    0.0.0.0:*    LISTEN    929/nginx: master p

⚠️ 易错点:grep 80 会匹配所有含 "80" 的字符 (比如 8080、甚至 PID 里含 80 的行),过滤不准确。推荐用 grep ':80 '(冒号 + 空格)来精确定位端口字段,或者直接用:

bash 复制代码
ss -lntp sport = :80

🔤 命名溯源

命令 / 参数 全称 拆解
lsof L ist O pen Files 列出已打开的文件。Linux「一切皆文件」,所以网络连接、端口监听也算「文件」,lsof 才能查端口
-i internet address 选择网络文件
-n no hostname lookup 不把 IP 反解析成主机名
-P P no port-name conversion 不把端口号转换成服务名(注意是大写 -P
-sTCP:LISTEN state 只看 TCP 的 LISTEN 状态
netstat net work statistics 网络统计
ss s ocket statistics 套接字统计

最常用的组合:

bash 复制代码
sudo lsof -nP -iTCP -sTCP:LISTEN   # 谁监听了哪些 TCP 端口
sudo lsof -nP -i :8080            # 谁占用了 8080

端口通不通用什么命令?

方式一:telnet

bash 复制代码
telnet IP地址 端口号

能建立连接 = 端口通畅;连接失败或超时 = 端口不可访问。

方式二:nc(netcat)

bash 复制代码
nc -zv IP地址 端口号

💡 更现代的替代写法:

bash 复制代码
nc -vz 10.0.0.5 8080
curl -v http://10.0.0.5:8080

🔤 命名溯源(telnet 是常被问的)

text 复制代码
telnet = TELetype + NETwork
       (也常写作 TELecommunication NETwork,但更准确的历史来源是 TELeTYPE NETwork)

⚠️ Telnet 用户名、密码、数据都是明文传输 ,不适合远程登录,远程登录请用 ssh user@hosttelnet 现在主要用于临时测试 TCP 端口连通性


六、权限:修改文件权限用什么命令?

chmod

bash 复制代码
chmod 400 file.txt   # 只读
chmod 644 file.txt   # 属主读写,其他用户只读
chmod 755 file.txt   # 属主读写执行,所属组读执行,其他用户只读
chmod 755 directory/ # 目录同理

权限位从左到右依次是:

text 复制代码
u    g    o
属主  所属组  其他用户

数值由权限相加得出:

数值 权限 英文
4 read
2 write
1 执行 execute

所以 7 = 4+2+1 = rwx5 = 4+1 = r-x4 = r--

⚠️ 易错点:第三组不是「其他组员」,而是「其他所有用户」 (既不是文件属主、也没通过所属组匹配到的用户)。第一组也应说成文件属主,不一定等于当前执行命令的用户。

💡 ls -l 输出的最前面那个字符不是权限位 ,而是文件类型:- 普通文件、d 目录、l 符号链接。

text 复制代码
-rwxr-xr--  1 alice developers 1234 file
 │└┬┘└┬┘└┬┘
 │ u  g  o
 └ 文件类型

🔤 chmod = ch ange mode(改变模式)。


七、文本处理:sed / awk / grep 与日志统计

用 shell 命令替换一个文件中的字符串

bash 复制代码
sed -i 's/旧字符串/新字符串/g' 文件名
sed -i 's/Hello/Hi/g' example.txt
部分 英文来源 含义
sed s tream editor 流编辑器
-i in-place 直接修改原文件(不输出到标准输出)
s substitute 替换
g global 全局替换,一行中所有匹配项都换

💡 建议先备份:

bash 复制代码
sed -i.bak 's/Hello/Hi/g' example.txt   # 会生成 example.txt.bak

⚠️ sed -i 需要修改文件,因此对文件(通常还有所在目录,因为它可能创建临时文件再替换)必须有写权限。不要动不动就 chmod 777

sed 和 awk 有什么区别?

  • sed:主要用于对文本进行替换、删除、插入 ,适合对整行文本处理,支持正则匹配。
  • awk:能实现更复杂的文本处理逻辑,包括按字段操作、条件判断、循环 ,适合处理结构化文本(按列处理)。

一句话:sed 适合简单的替换编辑,awk 适合结构化数据的复杂处理。

🔤 命名溯源(awk 是最有名的「不是缩写」)

text 复制代码
awk 不是功能缩写,而是三位创始人姓氏的首字母:
  A --- Alfred Aho
  W --- Peter Weinberger
  K --- Brian Kernighan

awk 常见用法:

bash 复制代码
awk '{print $1}' file.txt        # 打印第 1 个字段
awk -F: '{print $1}' /etc/passwd # -F = Field separator,指定分隔符为冒号

查找日志中某个字符串出现的次数 / 匹配行的长度?

这里其实是两类不同需求,一定要分清:

需求一:统计包含某个字符串的每一行的长度(不是字符串本身的长度)

bash 复制代码
grep "search_string" log_file | awk '{ print length }'
  • grep "search_string" log_file:找出日志中包含 search_string 的所有行;
  • awk '{ print length }':输出每一行的字符数(length 默认等同于 length($0))。

需求二:统计某个字符串在日志中出现的次数

bash 复制代码
grep -o "search_string" log_file | wc -l   # 方式1:每一次匹配都算
grep -c "search_string" log_file           # 方式2:统计包含它的行数

🔤 相关命令/参数的字母来源:

写法 全称 含义
grep g /re /p 来自编辑器命令 g/re/pg lobal / re gular expression / print
grep -o only-matching 只输出匹配到的片段,不输出整行
grep -c count 统计匹配的行数
grep -i ignore case 忽略大小写
grep -F Fixed strings 按普通固定字符串搜索,不当正则
wc w ord count 统计工具
wc -l lines 行数
wc -c byte count 字节数
wc -m characters 字符数(UTF-8 下中文一个字算 1)
echo -n no newline 不追加换行符

⚠️ 易错点(原文也特意点出的一个误区)

bash 复制代码
grep "c" log_file | wc -m

这条命令会先取出所有包含 c 的整行 ,再统计这些行的总字符数 (通常还包含每行的换行符),结果和「字符 c 出现了几次」完全不同,千万别用它来统计字符出现次数

统计 c 出现了几次,应该用:

bash 复制代码
grep -o "c" log_file | wc -l

举个具体例子,文件内容:

text 复制代码
abc
cat
hello
success
命令 统计的是什么 结果
`grep "c" log_file wc -m` 匹配行的总字符数
`grep -o "c" log_file wc -l` 字符 c 的总出现次数
grep -c "c" log_file 包含 c 的行数 3

一句话记忆:grep -o | wc -l 数「出现次数」,grep -c 数「匹配行数」,| wc -m 数「整行总字符数」------三个完全不同的东西。

💡 顺带一个高频疑问:grep 抓出来的东西会打印到屏幕吗? 会------默认输出到标准输出(stdout)。它虽然显示在屏幕上,但本质是标准输出,所以还能继续用管道传下去:

bash 复制代码
grep "error" log_file            # 直接显示匹配的整行
grep "error" log_file | wc -l    # 交给 wc 统计,屏幕只显示数字
grep "error" log_file > result.txt   # > 重定向写文件,屏幕不显示
grep "error" log_file | tee result.txt  # tee:既显示又保存

日志里取耗时最高的 10 条

日志格式:第一列日期、第二列请求 IP、第三列请求耗时。

bash 复制代码
sort -k3 -nr 日志文件 | head -n 10
部分 英文来源 含义
sort sort 排序(默认按文本字典序,不是数值)
-k3 key 以第 3 个字段作为排序键
-n numeric sort 按数值大小排序
-r reverse 倒序(从大到小)
-nr -n -r 按数字从大到小
head head 取开头若干行
-n 10 number of lines 前 10 行
tail -n +2 --- 从第 2 行开始输出(跳过表头)
` ` pipe

⚠️ 易错点:严格来说 -k3 表示排序键「从第 3 列开始一直到行末」,后面还有第 4、5 列也可能参与比较。只想按第 3 列排,推荐写:

bash 复制代码
sort -k3,3 -n -r 日志文件 | head -n 10
sort -k3,3nr 日志文件 | head -n 10        # 等价简写

如果第一行是表头,别让它参与排序:

bash 复制代码
tail -n +2 日志文件 | sort -k3,3nr | head -n 10

🔤 为什么管道里的中间结果不显示?因为 sort 的输出进管道了,屏幕最终只会显示 head 的那 10 行。

⚠️ 安全提示sudo rm -f * 这种命令会删掉当前目录所有非隐藏文件(* 不匹配 .env.git 等以点开头的项),-f 还不询问确认。想先看看会匹配什么:

bash 复制代码
printf '%q\n' ./*     # 安全预览
ls -la

八、⭐ 内存专题(本篇重点)

这一节是全篇的重点。前面那些是「知道怎么写」,内存这块是「知道怎么判断」,面试和线上排障的分水岭都在这里。

8.1 ⭐ top 命令和 free 命令都可以查看内存,有什么区别?

free 专注看内存使用情况:

物理内存部分:

字段 含义
total 总物理内存大小
used 已使用的内存
free 未使用的内存
shared 共享内存大小
buff/cache 缓冲和缓存内存大小
available 当前可用的内存,考虑到了部分缓存可以被快速释放的情况

交换内存部分:totalusedfree

top 除了显示内存,还会显示系统任务情况、CPU 使用情况、各进程状态等信息。

核心区别一句话free 是「内存专用仪表盘」,top 是「系统全景仪表盘」,内存只是 top 的一个区块。
💡 补充理解(内存里第一个大坑) :看内存不要只看 free 。Linux 会主动把空闲内存拿去做 page cache(文件缓存),所以 free 很小经常是正常的 ,甚至是「内存被高效利用」的表现。真正代表「还能拿来用多少」的是 available

记法:free 小 ≠ 内存不够;available 低才是真的紧张。buff/cache 里的内容,大部分在需要时可以被内核立刻丢掉或写回,所以它被算进了 available

8.2 ⭐ 怎么判断服务器内存是否够用?如何查看服务器性能瓶颈是否是内存?

① 用 free 看总体情况

bash 复制代码
free -m
text 复制代码
              total        used        free      shared  buff/cache   available
Mem:           7982        1746        2523         155        3703        5818
Swap:          2047           6        2041

重点看:used(已用)、free(空闲)、available(真正可用,含可快速释放的缓存,最能代表实际可用内存)

available 的值长期很低,就可能表明内存不足。

② 观察是否频繁使用 Swap 空间

bash 复制代码
Swap:   2047    6    2041

如果 Swap 使用过多(例如接近 Swap total),说明物理内存不足。

③ 检查 dmesg 是否有 OOM

bash 复制代码
dmesg | grep -i "out of memory"

也可以看 /var/log/messages存在 OOM 错误,说明内存不足是明显问题。

🔤 命名溯源:dmesg 通常理解为 d iagnostic mes sag es(诊断消息),也有解释为 display messages。它读取的是 Linux 内核环形缓冲区(kernel ring buffer)里的消息,内核启动、驱动加载、磁盘/文件系统错误、OOM 都在里面。

bash 复制代码
dmesg -T          # -T:human-readable timestamps,把 [12345.6789] 转成可读日期时间
dmesg -w          # -w:follow/wait,持续等待并显示新消息
dmesg -l err,warn # -l:level,只看错误和警告等级
sudo dmesg        # 现代 Linux 普通用户可能读不到内核日志
journalctl -k     # systemd 环境下的替代,-k = kernel,只看内核日志

④ 用 vmstat 观测内存使用状况

bash 复制代码
vmstat 1     # 每秒刷新一次

特别关注:

  • si(swap in)和 so(swap out) :这两个值较高,说明系统频繁使用交换空间,表明物理内存可能不足
  • free:空闲内存;
  • buffcache:缓存和缓冲区使用情况。

🔤 vmstat = v irtual m emory statistics(虚拟内存统计)。

8.3 ⭐ 如何判断内存是否是满的情况?通过什么指标判断内存的使用率?

四条判据,逐条对照:

  1. freeavailable 都非常低,而 used 很高 → 内存基本上是满的;
  2. Swap 使用频繁且使用率较高 → 内存基本上是满的;
  3. dmesg 日志里出现 OOM 相关信息 → 内存不足已经导致进程被杀掉;
  4. pstop 显示大部分内存被少数几个进程占用 → 内存基本上是满的。

💡 补充理解 :这四条其实分别对应「当前状态」「换页行为」「历史事故」「责任方」四个维度------available 是当下快照,si/so 是动态行为,OOM 是已经发生过的结果,ps/top 用来定位是谁吃掉的。排障时按这个顺序走一遍,基本不会漏。

8.4 ⭐⭐ 怎么判断操作系统有没有在内存替换?或者说怎么统计内存替换的频率?(本篇压轴)

原文答案:用 sar -B 1 命令观察。

bash 复制代码
sar -B 1        # 每 1 秒输出一组分页统计数据
sar -B 1 5      # 每 1 秒采样一次,共输出 5 次
# Ctrl+C 停止
🔤 命名溯源:sar 这个名字是怎么拼出来的

sar = System Activity Reporter (系统活动报告器),也有写作 System Available Reporter 的说法。

也就是取 System + Activity + Reporter 这几个英文单词的(首)字母拼成的 s-a-r ,全小写就是命令名 sar

它通常包含在 sysstat 软件包中,用来持续采集并报告 CPU、内存、磁盘、网络等系统活动指标。它和 mpstatiostatpidstat 是同一个家族的工具,都是「stat / 统计类 」工具,采集的数据落在 /var/log/sa/ 下,所以 sar 还能回看历史(不写时间就是看今天)。

再看 -B 和无参数的 1

写法 含义
-B 查看 Paging statistics(内存分页统计) 相关指标。这里的大写 Bsar 规定的选项字母,不建议硬记成某个英文单词的首字母,重点记住它用于显示分页及内存回收情况
1 每隔 1 秒输出一组统计数据
⭐ 重点看哪三个指标
text 复制代码
pgscank/s    pgscand/s    pgsteal/s

原文图中红框标出的,就是后台内存回收直接内存回收的指标。

🧩 把这几个名字一个一个拆开
text 复制代码
pg     = page,内存页
scan   = 扫描
k      = kswapd,内核后台回收线程
d      = direct,直接(回收)
steal  = 回收、夺回
/s     = per second,每秒
指标 拆解 原文定义
pgscank/s pg + scan + k(swapd) + /s kswapd(后台回收线程)每秒扫描的 page 个数
pgscand/s pg + scan + d(irect) + /s 应用程序在内存申请过程中 每秒直接扫描的 page 个数
pgsteal/s pg + steal + /s 扫描的 page 中每秒被回收的个数

⭐⭐ 记忆点(建议背下来)

这几个指标名字里都带 scan,不是巧合------因为内核要判断一个内存页到底能不能回收、或者要回收多少内存,唯一的手段就是去「扫描」内存页。

区别只在于谁在扫、什么时候扫

  • pgscank/s内核的后台线程 kswapd 在扫,它提前、异步地扫,判断哪些页可以回收,扫完就顺手回收一部分;
  • pgscand/s应用程序自己「被逼着」现场扫(direct reclaim,直接内存回收),因为它申请内存时系统已经没有空闲内存了,只能同步扫描、腾出页面,扫完才能拿到内存;
  • pgsteal/s:不是另一个「扫描动作」,而是扫描之后真正成功回收走的页数------即「扫描」和「回收」是两件事:扫了很多页,不代表都能 steal 成功。

🔤 顺带记一下 kswapd = kernel swap daemon (内核交换守护进程),名字里的 swap 是历史沿用,它实际干的是页回收 + 必要时换出swap 这个词本身就是「交换」,daemon 是「守护进程」。

⭐ 三个指标怎么解读

pgscank/s 高:后台回收在干活

text 复制代码
内存开始紧张
    ↓
内核唤醒 kswapd
    ↓
kswapd 在后台扫描内存页
    ↓
回收一部分内存

出现一定的 pgscank/s 不一定说明系统有严重问题,因为后台回收本身就是正常机制。如果该指标长期很高,说明系统持续面临内存压力。

pgscand/s 高:⚠️ 这才是要警惕的

text 复制代码
Java 程序申请内存
    ↓
系统没有足够的空闲内存
    ↓
申请不能立即完成
    ↓
程序自己进入直接回收流程
    ↓
扫描并释放可回收页面
    ↓
继续申请内存

由于应用程序必须等待回收完成,这段时间表现为:请求延迟突然增高、程序偶尔卡住、系统周期性抖动、接口响应时间出现尖刺。

pgscand/s 持续较大,通常比 pgscank/s 较大更值得警惕。

pgsteal/s 高:确实回收掉了不少页

系统每秒成功回收了多少个内存页。

⚠️ 补充理解(原文这里有个容易误读的括号):原文写的是

text 复制代码
pgsteal/s: 扫描的 page 中每秒被回收的个数(pgscank+pgscand)

这里的 (pgscank+pgscand) 不是让你做加法 ,即下面这个等式通常不成立

text 复制代码
pgsteal/s = pgscank/s + pgscand/s   ❌

它只是想说「这两个来源扫出来的页合起来,最终有多少被回收」。正确关系是:

text 复制代码
pgscank/s = 后台扫描了多少页
pgscand/s = 直接回收扫描了多少页
pgsteal/s = 扫描后真正成功回收了多少页

举例:

text 复制代码
pgscank/s = 1000
pgscand/s = 500
pgsteal/s = 600

意思是:后台扫了 1000 页、直接回收扫了 500 页,最终成功回收 600 页------不是回收了 1500 页。

📊 看到输出怎么判断
text 复制代码
pgscank/s  pgscand/s  pgsteal/s
      0.00        0.00        0.00
    500.00        0.00      300.00
   1200.00      800.00      700.00
情况 现象 结论
⭐ 情况一 三个值基本都是 0.00 这个采样期间基本没有发生内存回收,内存压力通常不明显
⭐ 情况二 pgscank/s 较高,pgscand/s0 后台线程正在回收内存,但应用暂时没被迫直接回收。存在一定内存压力,但不一定造成明显卡顿,要结合其他指标
⭐ 情况三 pgscand/s 持续较高 ⚠️ 应用申请内存时触发了直接回收 。若与系统卡顿、接口延迟发生在同一时间段,很可能存在:内存压力 → 直接回收 → 应用被阻塞 → 系统抖动

⚠️ 不能仅凭某一次非零就认定系统有严重问题,要观察它是否:

  • 持续出现;
  • 数值很高;
  • 与延迟尖刺同时发生;
  • 同时伴随 available 很低或换页活动。
🍽️ 后台回收 vs 直接回收(餐厅打比方,很好记)
后台回收 kswapd 直接回收 direct reclaim
场景 餐厅发现空桌快不够了,服务员提前清理 客人已经到了却没有空桌,只能站着等服务员现场收拾
对应指标 pgscank/s pgscand/s
对应用的影响 相对间接 直接阻塞申请内存的程序,容易造成延迟和卡顿

⭐ 原文最后一句的大白话版本:

如果系统时不时发生抖动,并且在抖动的时间段里 sar -B 观察到 pgscand 数值很大,那大概率是因为「直接内存回收」导致的。

🧾 建议一起观察的指标组合
目的 命令 重点看
当前可用内存 free -h available(不要只看 free
内存回收活动 sar -B 1 pgscank/s pgscand/s pgsteal/s
是否在频繁换页 vmstat 1 si so
是否发生过 OOM `dmesg grep -Ei 'oom

没权限读内核日志时:

bash 复制代码
sudo dmesg | grep -Ei 'oom|out of memory|killed process'
journalctl -k | grep -Ei 'oom|out of memory|killed process'

8.5 ⭐ 「内存替换」中的「替换」就是 Swap 吗?

💡 结论:不完全是。 更准确的叫法是 内存回收(memory reclaim) ,而 Swap 只是内存回收可能采取的一种手段

原文说的「内存替换」容易让人误解,根据它讨论的 pgscank/spgscand/spgsteal/s,称为内存回收更加准确。

内存紧张时,Linux 主要有两种腾空间的方式:

text 复制代码
内存回收
├── ① 回收文件缓存:不一定使用 Swap
└── ② 换出匿名内存:使用 Swap

① 回收文件缓存(不涉及 Swap)

程序读过的文件内容会被缓存在内存里,内存不足时这些缓存页可以直接丢弃,因为以后需要时还能从磁盘文件重新读回来:

text 复制代码
文件缓存页 → 丢弃 → 腾出物理内存

② 换出匿名内存(这才涉及 Swap)

程序通过堆、栈使用的匿名内存没有对应的磁盘文件,不能直接丢掉,内核可能把暂时不用的匿名页写入 Swap:

text 复制代码
物理内存中的匿名页
      ↓ swap out
    Swap 空间
      ↓ swap in
  重新读回物理内存

这就是通常说的内存交换(swapping)

所以 sar -B 看到的不只是 Swap :它反映的是广义的内存扫描和回收,不能仅凭这些指标断定正在使用 Swap。

怎么确认是否真的在进行 Swap?

bash 复制代码
vmstat 1        # 重点看 si / so
text 复制代码
si   so
 0    0
 0    0
128  512     ← 这一行表示当前确实发生了 Swap 换入和换出
字段 英文 含义
si s wap in 每秒从 Swap 读回内存的数据量
so s wap out 每秒从内存写入 Swap 的数据量

也可以:

bash 复制代码
sar -W 1        # -W:显示交换活动
字段 英文 含义
pswpin/s p age sw ap in 每秒换入的页数
pswpout/s p age sw ap out 每秒换出的页数

一句话记忆内存回收不一定使用 Swap;只有把匿名内存页写到交换空间,才叫 Swap。

⚠️ 另外注意:Swap 已使用 ≠ 正在频繁换页 。系统可能过去把一些长期不用的页面放进了 Swap,而现在并没有频繁读写。判断当前 压力时,siso变化比单看 Swap 已用了多少更重要。


九、CPU 与平均负载

假如 CPU 跑到 100%,你的解决思路是什么?

  1. 先用 top 定位到占用 CPU 高的进程 PID
  2. top -H -p <进程ID>ps -T -p <进程ID> 找到该进程中占 CPU 高的线程 ID(TID)
  3. 查看对应线程的调用栈,按进程类型选工具:
    • Java 进程 :把线程 ID 转成十六进制,用 jstack <进程ID> 搜索对应线程的堆栈(jstack 仅适用于 JVM 进程);
    • C/C++ 或其他 native 进程 :用 perf top -p <进程ID>gdb -p <进程ID>strace -p <线程ID> 观察热点函数和系统调用;
  4. 根据堆栈信息回项目定位代码,看是否发生死循环、热点计算或频繁系统调用。

Linux 服务器如何查看负载情况?通过什么指标查看?

topuptime,看最后的系统平均负载(Load Average)

Load Average 的三个数字,依次是过去 1 分钟、5 分钟、15 分钟的平均负载。 通过三者大小可以判断负载趋势:

例子 趋势
1.00, 5.00, 10.00(依次增大) 过去 1 分钟负载 < 过去 15 分钟 → 负载在下降
10.00, 5.00, 1.00(依次降低) 过去 1 分钟负载 > 过去 15 分钟 → 负载在上升
0.07, 0.04, 0.00(基本相同) 负载平稳

负载值一般不超过 CPU 核数的 1~1.5 倍;超过 1.5 倍就要重视,此时会严重影响系统。

平均负载 ≠ CPU 使用率

  • 平均负载是单位时间内处于可运行状态和不可中断状态的进程数 ------不仅包括正在用 CPU 的进程,还包括等待 CPU等待 I/O 的进程;
  • CPU 使用率是单位时间内 CPU 繁忙情况的统计。所以:
场景 平均负载 CPU 使用率
CPU 密集型进程 升高 高(两者一致)
I/O 密集型进程 升高 不一定高
大量进程等待 CPU 调度 升高 也比较高

所以负载高了要先分清是 CPU 高还是 iowait 高:

bash 复制代码
mpstat -P ALL 1
text 复制代码
07:51:45 PM  CPU    %usr   %nice    %sys %iowait    %irq   %soft  %steal  %guest   %idle
07:51:50 PM  all   42.90    0.00   49.39    0.41    0.00    4.56    0.00    0.00    2.74
07:51:50 PM    0   44.38    0.00   48.67    0.41    0.00    2.86    0.00    0.00    3.68
07:51:50 PM    1   41.57    0.00   49.80    0.40    0.00    6.43    0.00    0.00    1.81

从上面可以看出 %usr 约 45%、%sys 约 50%、%iowait 只有 0.41%、%idle 只剩 2~3% ------ 可以推断是 CPU 使用率导致平均负载升高

反过来说,如果只有 %iowait%usr%sys 都很轻松,那负载升高就是 iowait 导致的

再定位是哪个进程导致的:

bash 复制代码
pidstat -u 1
text 复制代码
08:07:55 PM       PID    %usr %system  %guest    %CPU   CPU  Command
08:07:56 PM        11    0.00   16.00    0.00   16.00     0  events/0
08:07:56 PM        12    0.00   20.00    0.00   20.00     1  events/1

可以看到是 events/0events/1 这两个内核进程 CPU 使用率非常高,可能是它们导致平均负载升高。

🔤 命名溯源

命令 全称 拆解
mpstat M ultip rocessor Statistics 多处理器统计
pidstat P rocess ID Statistics 按进程 ID 统计
iostat I nput/O utput Statistics I/O 统计
vmstat V irtual M emory Statistics 虚拟内存统计
sar S ystem A ctivity Reporter 系统活动报告器
uptime up time 系统已运行时长(顺带给出负载)

mpstat 常见参数:

bash 复制代码
mpstat -P ALL 1     # -P:processor,指定处理器;ALL:所有 CPU;1:每 1 秒输出一次
mpstat -P 0 1       # 只看 0 号 CPU

它来自 sysstat 包,没有的话:sudo apt install sysstat(Debian/Ubuntu)或 sudo yum install sysstat(CentOS/RHEL)。

mpstat 输出字段:

字段 英文 含义
%usr user 用户态 CPU 使用率
%nice nice 调整过优先级的用户进程占用率
%sys system 内核态 CPU 使用率
%iowait I/O wait 等待 I/O 的时间比例
%irq interrupt request 硬中断占用率
%soft software interrupt 软中断占用率
%steal steal time 虚拟机被宿主机占用的时间
%idle idle CPU 空闲率

十、命令命名溯源总表(首字母 / 缩写来源)

面试里「这个命令/参数是由哪些英文单词组成的」几乎必问,集中放一张表,考前扫一眼。

命令名

命令 来源 拆解
ls list 列表
cd change directory 改变目录
mv move 移动/重命名
mkdir make directory 创建目录
chmod change mode 改变权限模式
chown change owner 改变属主
ps process status 进程状态
top table of processes 进程表格(把最活跃的排最上面)
free free memory 空闲内存
kill / pkill / killall pattern kill / kill all 按模式杀 / 全部杀
netstat network statistics 网络统计
ss socket statistics 套接字统计
lsof list open files 列出已打开的文件
telnet TELetype + NETwork 远程终端协议
nc netcat 网络工具
sed stream editor 流编辑器
awk Aho + Weinberger + Kernighan 三位创始人姓氏首字母
grep g/re/p global / regular expression / print
sort / head / tail 本义 排序 / 取头 / 取尾
wc word count 统计行、字、字节
sar System Activity Reporter 系统活动报告器(也有 System Available Reporter 的说法)
mpstat multiprocessor statistics 多处理器统计
pidstat process id statistics 按进程统计
vmstat virtual memory statistics 虚拟内存统计
iostat input/output statistics I/O 统计
dmesg diagnostic messages 诊断消息(内核环形缓冲区)
journalctl journal control systemd 日志查询
jstack JVM stack JVM 线程堆栈(仅 JVM)
strace system call trace 系统调用跟踪
perf performance 性能分析
kswapd kernel swap daemon 内核交换守护进程(实际做页回收/换出)

参数

参数 来源 含义
ps -a all 有终端的全部进程
ps -e every 所有进程
ps -u user 用户相关
ps -f full 完整信息
ps -l long 长格式
ps -o output 自定义输出
ps -T threads 显示线程
top -H tHreads 线程模式(大写 H,非严格首字母)
top -h help 帮助
netstat -n numeric 不解析主机名/服务名
netstat -a all 所有套接字
netstat -p process/program 显示进程
netstat -t TCP 只看 TCP
lsof -n no hostname lookup 不做反向解析
lsof -P no port-name conversion 不做端口到服务名转换
lsof -i internet address 网络文件
lsof -s state 状态过滤
chmod 数字 r=4 / w=2 / x=1 相加组合
sed -i in-place 原地修改
seds / g substitute / global 替换 / 全局
awk -F Field separator 字段分隔符
grep -o only-matching 只输出匹配片段
grep -c count 匹配行数
grep -i ignore case 忽略大小写
grep -F fixed strings 固定字符串
wc -l / -c / -m / -w lines / byte count / characters / words 行 / 字节 / 字符 / 词
echo -n no newline 不追加换行
sort -k key 排序键
sort -n numeric 数值排序
sort -r reverse 倒序
head -n number of lines 行数
nsenter-n numeric (同 netstat)
sar -B Paging statistics 分页统计(大写 B 是规定选项字母,不硬套单词)
sar -W sWap 交换活动
vmstatsi/so swap in / swap out 换入 / 换出
sar -Wpswpin/s pswpout/s page swap in/out per second 每秒换入/换出页数
mpstat -P processor 处理器
pidstat -u CPU 指标 CPU
dmesg -T human-readable timestamps 可读时间戳
dmesg -w follow/wait 持续输出
dmesg -l level 日志等级
journalctl -k kernel 只显示内核日志

十一、⚠️ 全篇易错点速查(考前扫这一块)

# 易错点 正解
1 top -H 写成 top -h 大写 -H 看线程;小写 -h 是帮助
2 以为 ps -a 等于 ps -e -a 是「与终端关联的」进程,-e 才是「全部」
3 grep 80 找端口 会误匹配 8080、PID 里的 80 → 用 grep ':80 'ss -lntp sport = :80
4 `grep "c" file wc -m` 当字符出现次数
5 grep -c 当出现总次数 它数的是包含该串的行数,一行多次只算 1
6 sort -k3 只按第 3 列 -k3 是「第 3 列到行末」;只排第 3 列用 -k3,3
7 sort 直接按数值排 默认是字典序,数值要加 -n
8 free 判断内存够不够 该看 availablefree 小常常是正常的缓存占用
9 「内存替换」= Swap 内存回收包含回收文件缓存(不涉及 Swap);只有匿名页写到交换空间才叫 Swap
10 pgsteal/s = pgscank/s + pgscand/s ❌ 不成立。前两个是扫描量pgsteal扫描后成功回收量
11 Swap 已用高就当内存不足 要看 si/so变化,历史换出过不代表现在在频繁换页
12 只看负载数值判断瓶颈 负载含等待 I/O 的进程;要配合 mpstat%iowait vs %usr/%sys
13 kill -9 当首选 SIGTERM(15) 优雅退出,卡死才 -9
14 chmod 777 解决权限问题 权限开太大,按最小必要给

十二、一句话记忆卡(内存部分)

text 复制代码
free 小            → 不一定内存不足(缓存占着);看 available
available 长期很低 → 内存不足
si / so 持续较高   → 正在频繁 Swap 换入换出,物理内存可能不足
dmesg 出现 OOM     → 内存不足已经杀过进程了

pgscank/s 高  → 内核后台线程 kswapd 在提前扫页回收
                 有内存压力,但不一定直接卡住应用
pgscand/s 高  → 应用申请内存时被迫现场扫页回收(direct reclaim)
                 ⚠️ 直接阻塞应用,容易造成卡顿和延迟抖动
pgsteal/s 高  → 系统确实回收掉了较多内存页
                 (≠ pgscank + pgscand,别做加法)

这三个指标都带 scan,因为内核判断页能不能回收、
要回收多少内存,唯一的办法就是去扫描内存页。

sar = System Activity Reporter(系统活动报告器)
      System + Activity + Reporter → s-a-r
sar -B 1  → 看分页/内存回收(pgscank/s、pgscand/s、pgsteal/s)
sar -W 1  → 看交换活动(pswpin/s、pswpout/s)

记住这句总结:后台回收是在应用「还没要内存」时提前腾内存;直接回收是在应用「急着要内存」时现场腾内存。后者会直接阻塞应用,所以更容易造成系统抖动。

所以这个知识点真正要理解的不是背指标名,而是:看到 pgscand/s 高,就要怀疑内存压力正在直接拖慢你的应用。


再次说明:原文出自 小林coding《Linux 命令面试题》https://xiaolincoding.com/interview/linux.html),我不是原作者,本笔记是搭配原文一起看的学习整理版,文中「💡 补充理解」部分是我自己的追问与展开。原文抓取时间:2026-09-20。

相关推荐
xbzb43 分钟前
Linux 进程调度与优先级调优避坑指南
linux·运维
金士顿44 分钟前
ASP.NET Core Native AOT + systemd 实战:把 Linux ARM64 程序变成可靠的设备服务
linux·嵌入式·asp.net core·arm64
Rabitebla1 小时前
【Linux 系统编程】权限(一):身份、提权,和那 9 个权限位
linux·数据结构·c++·算法
Hotchip_MEMS1 小时前
平板MEMS麦克风阵列如何赋能远程会议与远场拾音
人工智能·笔记·物联网·电脑·制造
東隅已逝,桑榆非晚1 小时前
List(类函数学习)
c++·笔记·学习
byte轻骑兵1 小时前
【BlueZ 】Linux 内核蓝牙子系统入门:hci_core 模块与 BlueZ 的交互
linux·人工智能·bluez·电脑蓝牙·嵌入式蓝牙
江屿风1 小时前
【Linux系统】【Linux 进程程序替换机制解析及自定义 Shell 核心逻辑实现 】流食般投喂
linux·运维·服务器·开发语言·笔记
好不玩呀1 小时前
一次PXE服务器上IPV6问题的记录
linux·运维·服务器
NamoAmitabha12810 小时前
libpng12-0 1.2.54-1ubuntu1.1 (amd64 binary) in ubuntu xenial
linux·ubuntu20.4