面试 | Linux

文章目录

Linux 面试完全指南(Go 校招向)


一、文件系统

目录结构

复制代码
/
├── bin/      # 基础命令(ls、cp、mv)
├── sbin/     # 系统管理命令(root 才能用)
├── etc/      # 配置文件(nginx.conf、hosts)
├── home/     # 普通用户主目录
├── root/     # root 用户主目录
├── var/      # 可变数据(日志、缓存)
├── tmp/      # 临时文件(重启后清空)
├── proc/     # 虚拟文件系统,映射内核和进程状态(不占磁盘)
├── sys/      # 虚拟文件系统,硬件和内核信息
├── dev/      # 设备文件(磁盘、终端)
├── lib/      # 共享库
├── usr/      # 用户程序和数据
└── mnt/      # 临时挂载点

重要/proc 目录不是真实文件,是内核暴露给用户空间的接口:

bash 复制代码
cat /proc/cpuinfo          # CPU 信息
cat /proc/meminfo          # 内存信息
cat /proc/1234/status      # PID 1234 的进程状态
cat /proc/net/tcp          # 网络连接状态

inode 与文件存储原理(面试高频)

Linux 文件系统中,文件由两部分组成:

复制代码
inode(索引节点)                  数据块(block)
┌─────────────────────┐          ┌─────────────────────┐
│ 文件类型             │    ┌────▶│  文件实际内容         │
│ 权限(rwx)          │    │    └─────────────────────┘
│ 所有者/组            │    │
│ 文件大小             │    │
│ 时间戳(atime/mtime)│    │
│ 数据块指针 ──────────┼────┘
└─────────────────────┘

目录文件内容:
  文件名 → inode 号 的映射表

核心 :文件名存在目录中,inode 不存文件名。删除文件 = 目录中删除文件名→inode 映射 + inode 引用计数减 1,计数归零才真正释放数据块。

硬链接 vs 软链接

bash 复制代码
# 硬链接:两个文件名指向同一个 inode
ln file.txt hard_link.txt
# 特点:删除原文件,硬链接仍可访问;不能跨文件系统;不能链接目录

# 软链接(符号链接):类似快捷方式,存储的是目标路径
ln -s file.txt soft_link.txt
# 特点:删除原文件,软链接失效;可跨文件系统;可链接目录

面试答法:inode 是文件的元数据结构,存储权限、大小、数据块位置等,不含文件名。硬链接是同一 inode 的多个目录项,引用计数归零才删除数据;软链接是存储目标路径的特殊文件,原文件删除则失效。


文件权限

复制代码
-  rwx  r-x  r--
│   │    │    └── other(其他用户):只读
│   │    └─────── group(同组用户):读+执行
│   └──────────── owner(所有者):读+写+执行
└──────────────── 文件类型(-普通文件,d目录,l链接,b块设备)

权限数字:r=4,w=2,x=1
rwxr-xr-- = 754
bash 复制代码
chmod 755 script.sh          # 设置权限
chmod +x script.sh           # 添加执行权限
chown user:group file.txt    # 修改所有者

# 特殊权限
chmod u+s /usr/bin/passwd    # SUID:以文件所有者身份执行
chmod g+s /shared/           # SGID:新建文件继承目录的组

二、进程管理

进程状态

复制代码
创建(fork) → 就绪(R) ─── 获得CPU ──→ 运行(R)
                                        │
              ←── CPU时间片用完 ────────┤
                                        │
              ←── 等待I/O/锁/信号 ────▶ 睡眠
                                        │可中断(S) / 不可中断(D)
              ←── 收到信号唤醒 ─────────┘
                                        │
                                       终止
                                        │
                              父进程未回收 → 僵尸(Z)

D 状态(不可中断睡眠):进程在等待磁盘 I/O 或内核操作,不响应任何信号(包括 kill -9)。D 状态过多通常意味着 I/O 问题。

僵尸进程(Z) :进程已退出,但父进程未调用 wait() 回收,PCB 残留。大量僵尸进程会耗尽 PID 资源。


进程 vs 线程 vs 协程

对比项 进程 线程 协程(Go goroutine)
资源隔离 独立地址空间 共享进程地址空间 共享线程栈
切换开销 大(页表切换) 中(寄存器切换) 极小(用户态切换)
通信方式 IPC(管道/消息队列/共享内存) 共享内存+锁 channel
创建开销 极小(初始栈 2KB)
崩溃影响 不影响其他进程 影响整个进程 panic 影响整个进程

进程间通信(IPC)

复制代码
管道(Pipe)         ─── 单向、只能父子进程间用
命名管道(FIFO)     ─── 单向、任意进程间用,有文件路径
消息队列            ─── 有结构的消息传递
共享内存            ─── 最快的 IPC,直接映射同一块内存
信号量(Semaphore) ─── 进程间同步/互斥
信号(Signal)      ─── 异步通知(kill -9、SIGTERM)
Socket             ─── 可跨机器通信

共享内存为什么最快:不需要内核参与数据拷贝,进程直接读写同一块物理内存,没有系统调用开销。代价是需要自己做同步(信号量)。


常用进程命令

bash 复制代码
ps aux                       # 查看所有进程
ps aux | grep go-service     # 查找特定进程
top                          # 动态查看进程(CPU/内存排序)
htop                         # 更友好的 top(需安装)

kill -9 <PID>                # 强制杀死进程(SIGKILL,不可忽略)
kill -15 <PID>               # 优雅终止(SIGTERM,可捕获处理)
kill -l                      # 列出所有信号

pstree -p                    # 进程树
lsof -p <PID>                # 查看进程打开的文件
lsof -i :8080                # 查看占用 8080 端口的进程
strace -p <PID>              # 追踪进程系统调用(排查卡死)

三、内存管理

虚拟内存

每个进程拥有独立的虚拟地址空间 ,通过页表映射到物理内存:

复制代码
进程A虚拟地址空间          物理内存
┌────────────────┐        ┌──────────┐
│ 内核空间        │        │ 进程A数据 │
│───────────────│        │ 进程B数据 │
│ 栈(向下增长)  │──┐     │ 共享库    │
│               │  │     │ 内核      │
│ 堆(向上增长)  │──┼────▶│ ...      │
│               │  │     └──────────┘
│ BSS(未初始化)│  │
│ Data(已初始化)│  │     磁盘(Swap)
│ Text(代码段)  │──┘     ┌──────────┐
└────────────────┘        │ 换出的页  │
                          └──────────┘

缺页中断:访问的虚拟地址对应物理页不在内存中,触发中断,内核从磁盘载入数据到内存,更新页表,继续执行。

Swap 空间:物理内存不足时,将不常用的内存页换出到磁盘,为当前进程腾出空间。频繁 Swap 会导致性能下降(磁盘 I/O 远慢于内存)。


内存分配

复制代码
malloc/new 申请内存
    │
    ├─ 小内存(< 128KB):调整 brk 指针,扩展堆
    └─ 大内存(≥ 128KB):mmap 映射一块匿名内存

Go 内存分配:
    goroutine 栈(初始 2KB,按需增长)
    堆(GC 管理,tcmalloc 思路,分级 span)

内存相关命令

bash 复制代码
free -h                     # 查看内存使用(-h 人性化显示)
# 输出示例:
#              total    used    free   shared  buff/cache  available
# Mem:          15Gi    8Gi    2Gi    500Mi      5Gi        6Gi
# available = free + buff/cache 中可回收的部分,是真正可用内存

vmstat 1                    # 每秒刷新:内存、swap、I/O、CPU
cat /proc/meminfo           # 详细内存信息

# 查看进程内存
cat /proc/<PID>/status | grep VmRSS  # 物理内存占用
pmap -x <PID>               # 进程内存映射详情

四、I/O 模型(面试核心)

五种 I/O 模型

以"读取网络数据"为例,整个过程分两个阶段:

  1. 等待数据到达内核缓冲区

  2. 将数据从内核缓冲区拷贝到用户空间

    1. 阻塞 I/O(Blocking I/O)
      用户进程: recv() ────阻塞等待──────────────▶ 返回
      内核: 等待数据 → 数据到达 → 拷贝到用户空间
      特点:两个阶段都阻塞,简单但一个线程只能处理一个连接

    2. 非阻塞 I/O(Non-blocking I/O)
      用户进程: recv() → 立即返回EAGAIN → 轮询 → recv() → 数据就绪 → 返回
      特点:第一阶段不阻塞,但需要不断轮询,消耗 CPU

    3. I/O 多路复用(Multiplexing)← 最重要
      用户进程: select/poll/epoll(fd集合) ─阻塞─▶ 某fd就绪 → recv() → 返回
      特点:一个线程监听多个 fd,有数据才读,不浪费

    4. 信号驱动 I/O
      用户进程: 注册 SIGIO 信号 → 继续执行 → 收到信号 → 调用 recv()
      特点:第一阶段异步,实际拷贝还是同步,较少使用

    5. 异步 I/O(AIO)
      用户进程: aio_read() → 立即返回 → 继续干别的 → 收到完成通知
      特点:两个阶段全异步,真正的异步,Linux 支持不完善


select / poll / epoll 对比(面试必考)

复制代码
select:
  - 传入一个 fd_set 位图,内核遍历所有 fd 检查是否就绪
  - 返回后用户还要遍历所有 fd 找就绪的
  - 最大限制 1024 个 fd
  - 每次调用都要把 fd_set 从用户空间拷贝到内核

poll:
  - 用链表替代位图,无 1024 限制
  - 其他问题与 select 相同(仍是 O(n) 遍历)

epoll:
  - epoll_create:创建 epoll 实例(内核红黑树 + 就绪链表)
  - epoll_ctl:注册/修改/删除监听的 fd(加入红黑树)
  - epoll_wait:只返回就绪的 fd(从就绪链表取),O(1)
  - 使用事件驱动(fd 就绪时内核回调加入就绪链表)
  - 无 fd 数量限制,性能不随连接数增长而下降
对比项 select poll epoll
fd 数量限制 1024
时间复杂度 O(n) O(n) O(1)
fd 拷贝 每次调用拷贝 每次调用拷贝 只注册时拷贝一次
就绪通知 遍历全部 fd 遍历全部 fd 只返回就绪 fd
适用场景 连接少 连接少 高并发(Nginx/Redis)

epoll 两种工作模式

  • LT(水平触发,默认):只要 fd 有数据,每次 epoll_wait 都通知。数据没读完下次还会通知,编程容易。
  • ET(边缘触发):fd 状态变化时只通知一次。必须一次性读完所有数据(循环 read 直到 EAGAIN),性能更高但编程复杂。Nginx 使用 ET 模式。

面试答法:epoll 相比 select/poll 的核心优势是 O(1) 的就绪检测。epoll 在内核维护一棵红黑树存所有监听的 fd,一个就绪链表存就绪的 fd。fd 就绪时内核通过回调直接加入就绪链表,epoll_wait 只需从链表取结果,不用遍历所有 fd,因此高并发下性能不退化。


五、网络

TCP 三次握手 & 四次挥手(面试必背)

复制代码
三次握手(建立连接):
Client                          Server
  │─── SYN(seq=x) ────────────▶ │  SYN_SENT → SYN_RCVD
  │◀── SYN+ACK(seq=y,ack=x+1) ──│
  │─── ACK(ack=y+1) ───────────▶ │  ESTABLISHED
ESTABLISHED

为什么三次:两次不够(服务端不知道自己的发送能力正常),四次浪费(第二步合并了 SYN+ACK)

四次挥手(断开连接):
Client                          Server
  │─── FIN ───────────────────▶ │  CLOSE_WAIT
  │◀── ACK ────────────────────  │  (服务端可能还有数据要发)
  │                              │
  │◀── FIN ─────────────────── │  LAST_ACK
  │─── ACK ───────────────────▶ │  CLOSED
TIME_WAIT(等待 2MSL)
CLOSED

为什么四次:断开是单向的,各自独立关闭,所以多了一步
为什么 TIME_WAIT 等 2MSL:
  ① 确保最后一个 ACK 能到达(防止对端重发 FIN)
  ② 让本次连接的旧数据包在网络中消失,防止影响新连接

TCP vs UDP

对比项 TCP UDP
连接 面向连接(三次握手) 无连接
可靠性 可靠(确认、重传、排序) 不可靠
顺序 保证顺序 不保证
流量控制 有(滑动窗口)
拥塞控制
速度 较慢
适用场景 HTTP、数据库、文件传输 DNS、视频直播、游戏

常用网络命令

bash 复制代码
# 查看网络连接
netstat -antp               # 所有 TCP 连接及进程(-n 不解析域名)
ss -antp                    # 更快的 netstat 替代品
ss -s                       # 连接数量统计

# 查看端口占用
lsof -i :8080
ss -lntp | grep 8080

# 网络诊断
ping -c 4 google.com        # 测试连通性(ICMP)
traceroute google.com       # 路由追踪
curl -v http://api.example.com/health   # 测试 HTTP 接口
wget -O- http://example.com # 下载内容

# 网络抓包
tcpdump -i eth0 port 8080 -w capture.pcap    # 抓包保存
tcpdump -i eth0 'tcp and port 80'            # 过滤 HTTP

# 查看网络接口
ip addr                     # 查看 IP 地址
ip route                    # 查看路由表

六、磁盘与 I/O

bash 复制代码
# 磁盘使用
df -h                       # 文件系统磁盘使用(-h 人性化)
du -sh /var/log/*           # 目录大小(-s 汇总,-h 人性化)
du -sh * | sort -rh | head  # 找出最大的目录/文件

# I/O 性能
iostat -x 1                 # 每秒刷新磁盘 I/O 统计
                            # %util 接近 100% = 磁盘瓶颈
iotop                       # 查看哪个进程在做 I/O(需 root)

# 文件查找
find /var/log -name "*.log" -mtime -7        # 7天内修改的 log 文件
find / -size +100M                           # 大于 100MB 的文件

七、性能排查(面试超级加分)

系统负载高排查思路

bash 复制代码
# 第一步:看整体
top / htop
# 关注:
#   load average:1/5/15 分钟平均负载,> CPU核数说明过载
#   %CPU us/sy/wa:用户态/内核态/等待I/O 的 CPU 占比
#   wa (iowait) 高 → I/O 瓶颈
#   sy 高 → 系统调用过多或内核问题

uptime                      # 只看负载

# 第二步:找问题进程
ps aux --sort=-%cpu | head  # CPU 占用最高的进程
ps aux --sort=-%mem | head  # 内存占用最高的进程

# 第三步:深入分析
strace -p <PID>             # 进程在执行什么系统调用
lsof -p <PID>               # 进程打开了哪些文件/连接
cat /proc/<PID>/stack       # 进程内核调用栈(排查 D 状态)

CPU 高排查

bash 复制代码
# 1. 找到高 CPU 进程
top → 按 P 排序(CPU)

# 2. 找到该进程内哪个线程高
top -H -p <PID>             # 显示线程级 CPU 使用

# 3. 转换线程 ID 为 16 进制
printf "%x\n" <TID>

# 4. Go 程序:使用 pprof
# 代码中添加:
import _ "net/http/pprof"
go func() { http.ListenAndServe(":6060", nil) }()

# 采集 30s CPU profile
go tool pprof http://localhost:6060/debug/pprof/profile?seconds=30
# 在 pprof 交互界面:top10 / web(可视化火焰图)

内存高排查

bash 复制代码
# 1. 查看内存使用
free -h
cat /proc/meminfo | grep -E "MemAvailable|Cached|Buffers"

# 2. 找内存大户
ps aux --sort=-%mem | head

# 3. Go 程序内存泄漏排查
curl http://localhost:6060/debug/pprof/heap > heap.prof
go tool pprof heap.prof
# top10 查看内存分配热点
# list <函数名> 查看具体行

磁盘 I/O 高排查

bash 复制代码
iostat -x 1
# 关注 %util(使用率)、await(平均等待时间,ms)
# %util > 80% 说明磁盘接近饱和

# 找 I/O 大户
iotop -o                    # 只显示有 I/O 的进程

# 查看写入最多的文件
lsof -p <PID> | grep REG   # 进程打开的普通文件

网络问题排查

bash 复制代码
# 连接数异常
ss -s                       # 查看各状态连接数
ss -antp | grep TIME_WAIT | wc -l   # TIME_WAIT 数量

# TIME_WAIT 过多的处理
# /etc/sysctl.conf 添加:
net.ipv4.tcp_tw_reuse = 1           # 允许复用 TIME_WAIT 连接
net.ipv4.tcp_fin_timeout = 30       # 减少 FIN_WAIT2 等待时间
net.ipv4.tcp_max_tw_buckets = 5000  # 限制 TIME_WAIT 最大数量

# 丢包排查
netstat -s | grep -E "retransmit|failed"

八、常用文本处理命令

bash 复制代码
# grep:文本搜索
grep -r "ERROR" /var/log/               # 递归搜索
grep -n "panic" app.log                 # 显示行号
grep -v "DEBUG" app.log                 # 排除 DEBUG 行
grep -E "ERROR|WARN" app.log            # 正则,多关键字
grep -A 3 -B 3 "panic" app.log          # 显示匹配行的前后 3 行

# awk:列处理
awk '{print $1, $4}' access.log         # 打印第 1、4 列
awk -F: '{print $1}' /etc/passwd        # 以 : 为分隔符
awk '$9 == "500" {print}' access.log    # 过滤 HTTP 500 日志
awk '{sum += $1} END {print sum}' data  # 求和

# sed:流编辑
sed 's/old/new/g' file.txt              # 替换(不修改文件)
sed -i 's/old/new/g' file.txt           # 替换(直接修改文件)
sed -n '10,20p' file.txt                # 打印第 10-20 行
sed '/DEBUG/d' app.log                  # 删除含 DEBUG 的行

# sort & uniq:排序去重
sort -rn file.txt                       # 按数字逆序排
sort | uniq -c | sort -rn               # 统计词频

# 组合使用(分析日志)
# 统计 Nginx 访问最多的 IP Top10:
awk '{print $1}' access.log | sort | uniq -c | sort -rn | head -10

# 统计 HTTP 状态码分布:
awk '{print $9}' access.log | sort | uniq -c | sort -rn

九、Shell 脚本基础

bash 复制代码
#!/bin/bash
set -e          # 任意命令失败则退出
set -u          # 使用未定义变量则报错

# 变量
NAME="world"
echo "Hello, ${NAME}"

# 条件判断
if [ -f "/etc/config" ]; then       # -f 文件存在
    echo "config exists"
elif [ -d "/etc/config.d" ]; then   # -d 目录存在
    echo "dir exists"
else
    echo "not found"
fi

# 字符串比较用 [[ ]],更安全
if [[ "$NAME" == "world" ]]; then
    echo "match"
fi

# 循环
for i in {1..5}; do
    echo $i
done

for file in /var/log/*.log; do
    echo "processing: $file"
done

# 函数
check_service() {
    local service=$1        # local 限制变量作用域
    if systemctl is-active "$service" &>/dev/null; then
        echo "$service is running"
        return 0
    else
        echo "$service is stopped"
        return 1
    fi
}
check_service nginx

# 常用判断
[ -z "$VAR" ]   # 字符串为空
[ -n "$VAR" ]   # 字符串非空
[ $a -eq $b ]   # 数字相等(-ne -lt -gt -le -ge)

十、系统管理常用命令

bash 复制代码
# 系统信息
uname -a                    # 内核版本
cat /etc/os-release         # 发行版信息
hostname                    # 主机名
date                        # 当前时间
uptime                      # 运行时间和负载

# 用户管理
whoami                      # 当前用户
id                          # 用户 UID/GID
su - username               # 切换用户
sudo command                # 以 root 执行
last                        # 登录历史

# 服务管理(systemd)
systemctl start nginx
systemctl stop nginx
systemctl restart nginx
systemctl status nginx
systemctl enable nginx      # 开机自启
systemctl disable nginx
journalctl -u nginx -f      # 查看服务日志(-f 实时)
journalctl -u nginx --since "1 hour ago"

# 定时任务
crontab -e                  # 编辑当前用户 crontab
crontab -l                  # 列出当前用户定时任务

# 格式:分 时 日 月 周 命令
# 0 2 * * * /opt/backup.sh    # 每天凌晨 2 点执行备份
# */5 * * * * /opt/check.sh   # 每 5 分钟执行

# 环境变量
export PATH=$PATH:/usr/local/go/bin
env                         # 查看所有环境变量
echo $PATH
source ~/.bashrc            # 重新加载配置

十一、文件描述符与限制

bash 复制代码
# 查看系统文件描述符限制
ulimit -n                   # 当前用户最大打开文件数(默认 1024)
ulimit -n 65535             # 临时修改(当前会话)

# 永久修改:/etc/security/limits.conf 添加:
# *    soft    nofile    65535
# *    hard    nofile    65535

# 查看进程的 fd 使用
ls -la /proc/<PID>/fd | wc -l    # 进程打开的 fd 数量
cat /proc/sys/fs/file-max        # 系统级最大 fd 数

# 高并发服务器必做的内核参数优化(/etc/sysctl.conf)
net.core.somaxconn = 65535           # TCP 全连接队列大小
net.ipv4.tcp_max_syn_backlog = 65535 # 半连接队列大小
net.ipv4.tcp_tw_reuse = 1            # 复用 TIME_WAIT
net.ipv4.ip_local_port_range = 1024 65535  # 可用端口范围
vm.swappiness = 10                   # 尽量少用 Swap

十二、面试高频问题速答

Q:Linux 中进程和线程的区别?

进程是资源分配的基本单位,有独立的地址空间;线程是 CPU 调度的基本单位,共享进程的地址空间和资源。创建线程比进程开销小,但线程崩溃会影响整个进程,进程间不互相影响。Go 中的 goroutine 是用户态的轻量级"线程",由 Go runtime 调度,初始栈只有 2KB,切换开销极小。

Q:select、poll、epoll 的区别?

select 和 poll 每次调用都要把所有 fd 从用户空间拷贝到内核,然后遍历所有 fd 检查就绪状态,时间复杂度 O(n),select 还有 1024 限制。epoll 用红黑树在内核中维护监听的 fd,fd 就绪时通过回调加入就绪链表,epoll_wait 只需从链表取结果,时间复杂度 O(1),适合高并发场景。

Q:TCP 为什么是三次握手,不是两次?

两次握手只能保证一方知道双方都能收发,但不能保证另一方也知道。第三次握手是客户端告诉服务端"我收到你的 SYN+ACK 了",双方都确认了各自的发送和接收能力。另外,两次握手无法防止历史失效的连接请求导致的资源浪费。

Q:TIME_WAIT 状态是什么,为什么要等 2MSL?

主动关闭连接的一方在发送最后一个 ACK 后进入 TIME_WAIT,等待 2MSL(最大报文存活时间,通常 60s)。原因:① 确保最后的 ACK 能到达对端,若对端没收到会重发 FIN,2MSL 足够等待重传;② 让本次连接的所有报文在网络中失效,防止旧报文影响新连接。

Q:inode 是什么?删除文件时发生了什么?

inode 是存储文件元数据的结构,包含权限、大小、数据块地址等,不包含文件名。删除文件时,先从目录中删除文件名到 inode 的映射,inode 的硬链接计数减 1,当计数为 0 时才真正释放 inode 和数据块。这就是为什么文件被进程占用时删除,进程仍可访问文件,直到进程关闭 fd 才释放空间。

Q:Linux 系统 CPU 使用率高怎么排查?

分步骤:① top 看整体,确认是用户态(us)还是内核态(sy)还是 I/O 等待(wa)高;② ps aux --sort=-%cpu 找高 CPU 进程;③ top -H -p <PID> 找高 CPU 线程;④ Go 程序用 pprof 生成 CPU profile 分析热点函数;⑤ strace -p <PID> 看进程在执行什么系统调用。

Q:什么是零拷贝?

传统文件发送需要 4 次数据拷贝:磁盘→内核缓冲区→用户缓冲区→Socket 缓冲区→网卡。零拷贝使用 sendfile 系统调用,数据直接从内核缓冲区传到 Socket 缓冲区,跳过用户空间,只需 2 次拷贝,减少 CPU 开销和上下文切换。Kafka、Nginx 都利用零拷贝提升性能。

Q:如何查看一个端口是否被占用?

ss -lntp | grep <端口号>lsof -i :<端口号>,可以看到占用的进程名和 PID。

Q:load average 和 CPU 使用率有什么区别?

CPU 使用率是 CPU 的繁忙程度(0-100%)。load average 是平均活跃进程数,包括正在运行(R状态)和等待 I/O(D状态)的进程。CPU 使用率高但 load 不高说明是 CPU 密集;load 高但 CPU 使用率不高说明是 I/O 等待(磁盘/网络瓶颈)。load average 超过 CPU 核数说明有进程在排队等待。


十三、一张图记住核心

复制代码
文件系统:
  inode(元数据)+ 数据块(内容)+ 目录(文件名→inode映射)
  硬链接共享 inode,软链接存路径,引用计数归零才释放

进程:
  Namespace 隔离 + Cgroups 限制 = 容器基础
  进程间通信:管道 / 消息队列 / 共享内存(最快)/ Signal / Socket

I/O 模型(从低到高):
  阻塞 → 非阻塞轮询 → I/O多路复用(epoll) → 异步I/O
  epoll:红黑树存fd + 就绪链表 + 事件回调 = O(1) 高并发

排查三板斧:
  CPU 高  → top → pprof
  内存高  → free/ps → pprof heap
  I/O 高  → iostat/iotop → lsof
  网络问题 → ss/netstat → tcpdump

总结 :Linux 面试核心考点是 I/O 模型 (epoll 原理)、进程与线程TCP 握手挥手文件系统(inode),以及能不能用命令排查线上问题。掌握这几个方向,加上能说出排查思路,Linux 面试基本没问题。

相关推荐
iPadiPhone2 小时前
Spring Boot 核心注解全维度解析与面试复盘
java·spring boot·后端·spring·面试
菜_小_白2 小时前
高并发定时任务调度系统
linux·c++
HAPPY酷2 小时前
Linux 网络命令速查:告别 `ifconfig`,拥抱 `ip`
linux·网络·tcp/ip
ErizJ2 小时前
面试 | Kafka
面试·kafka
我不听你讲话2 小时前
Nginx核心功能
linux·服务器·python
草莓熊Lotso2 小时前
MySQL 数据类型核心指南:选型、实战与避坑
linux·运维·服务器·数据库·c++·人工智能·mysql
啊哈的哲学路途2 小时前
【esp-idf 指令】
linux·stm32
iPadiPhone2 小时前
性能优化的“快车道”:Spring @Async 注解深度原理与大厂实战
java·后端·spring·面试·性能优化
fanjinhong_85212 小时前
Docker 镜像与容器关系解析
linux·docker