面试大全
| 模块 | 题目数量 |
|---|---|
| Linux 基础 | 20 |
| Nginx | 10 |
| Java | 5 |
| shell | 12 |
| mysql | 11 |
| redis | 9 |
| zabbix+数据包进阶与内核 | 6 |
| iptables与web安全加固 | 5 |
| 高可用和高扩展 | 4 |
| Ansible 模块 | 6 |
| docker | 14 |
| Kubernetes | 19 |
| Prometheus | 4 |
一、Linux 基础面试题 TOP 20
1. Linux 系统平均负载的含义是什么?如何判断负载是否过高?
平均负载是单位时间内处于 可运行状态 和 不可中断睡眠状态 的进程平均数,显示为 1 分钟、5 分钟、15 分钟三个值。
判断负载是否过高要结合 CPU 核心数,4 核 CPU 负载持续超过 4 说明过载,8 核可承受 8 左右。1 分钟负载远高于 15 分钟说明负载在快速上升。如果负载高但 CPU 使用率不高,可能是 I/O 等待或锁竞争导致的,需要用 vmstat 或 iostat 进一步分析。
如果面试官追问:vmstat 和 iostat 具体看哪些指标?
vmstat 看 r(运行队列)、b(阻塞进程)、si/so(Swap 换入换出)、us/sy(用户态/内核态 CPU 占比)、cs(上下文切换)。如果 r 长期大于 CPU 核数说明 CPU 不够;如果 b 列有值说明有进程在等待 I/O;如果 si/so 频繁变化说明内存不足在频繁使用 Swap。
iostat 看 %util(磁盘繁忙程度)、await(平均等待时间)、r/s 和 w/s(读写次数)。%util 接近 100% 说明磁盘是瓶颈,await 过高说明磁盘响应慢。
2. 服务器 CPU 使用率突然飙升到 100%,如何排查?
先用 top 找到 CPU 占用最高的进程,记下 PID。然后用 top -Hp PID 看这个进程里哪个线程占用高。接着用 strace -p 线程ID 看它在执行什么系统调用,或者看应用日志有没有报错。
同时用 vmstat 1 看上下文切换是否频繁,用 dmesg 看内核日志有没有异常。如果查不到根因,先重启服务恢复业务,保留现场事后分析。
3. 磁盘空间显示已满但 du 统计不出大文件,如何处理?
通常是有文件被删除了但进程还在占用,文件句柄没释放,所以 df 看到空间没释放但 du 统计不到。
用 lsof | grep deleted 找到这些被删除但仍被进程占用的文件,找到进程号后重启该进程,空间就会释放。如果进程不能重启,可以进到该进程的 fd 目录下,找到对应文件描述符直接清空。
另外检查 inode 是否用完:df -i,大量小文件会占满 inode 导致无法创建新文件。
4. 僵尸进程是什么?如何产生?如何清理?
僵尸进程是子进程已终止但父进程没有调用 wait 回收它的退出状态,子进程的进程描述符还留在系统里。僵尸进程不占 CPU 和内存但占进程号,数量过多会导致无法创建新进程。
清理方法是杀死僵尸进程的父进程,父进程退出后僵尸会被 init 或 systemd 接管并回收。如果父进程是重要服务不能随便重启,可以尝试向父进程发送 SIGCHLD 信号让它主动回收子进程。
查看僵尸进程用 ps aux | grep Z。
5. 硬链接和软链接的区别是什么?
硬链接是在目录项中增加一个文件名指向同一个 inode,与原文件共享数据。删除原文件硬链接还在。硬链接不能跨文件系统,不能指向目录。
软链接是独立文件,有自己的 inode,内容存的是目标文件路径。可以跨文件系统,可以指向目录。原文件删除后软链接变死链接。
6. umask 0022 的含义是什么?文件和目录默认权限如何计算?
umask 是权限掩码,决定新建文件和目录的默认权限。计算公式:默认权限 = 最大权限 - umask。
文件最大权限 666,umask 0022 时默认权限为 644(属主读写,属组和其他人只读)。目录最大权限 777,默认权限为 755(属主读写执行,属组和其他人读和执行)。
7. 排查磁盘 I/O 高用什么命令?具体看哪些指标?
用 iostat -x 1 看磁盘 I/O,重点关注 %util(磁盘繁忙程度)、await(平均等待时间)、r/s 和 w/s(读写次数)。%util 接近 100% 说明磁盘成为瓶颈,await 过高说明磁盘响应慢。
用 iotop 看具体哪个进程在读写磁盘。用 pidstat -d 1 看每个进程的 I/O 统计。
排查思路:先用 iostat 确认哪个磁盘忙,再用 iotop 找具体进程,最后分析该进程为什么大量读写。
8. 日志文件太大占满磁盘,不停止服务如何清理?
不能直接 rm,进程还在写文件,直接删除后文件句柄未释放,df 显示空间不会释放,直到进程重启。
正确做法是 echo > 日志文件 或 cat /dev/null > 日志文件 截断清空,文件仍是同一个 inode,进程可继续写入。
也可以用 logrotate 配置 copytruncate 选项,先复制再清空,不中断进程。
9. free 命令中 buffer 和 cache 有什么区别?占用过高需要清理吗?
buffer 是块设备缓存,主要用于存储文件系统元数据,偏向加速写操作。cache 是页面缓存,缓存从磁盘读取的文件内容,偏向加速读操作。两者都是 Linux 利用空闲内存提升 I/O 性能的机制。
buffer/cache 占用高是正常的,应用程序需要内存时内核会自动回收,一般不需要手动清理。
如果必须清理:echo 1 > /proc/sys/vm/drop_caches。生产环境不建议随意执行,会导致 I/O 突增影响业务。判断内存是否够用要看 available 而不是 free。
10. 查看端口被哪个进程占用,有哪几种方法?
netstat -tlnp 查看所有 TCP 监听端口及对应进程。
ss -tlnp 是 netstat 的替代品,速度更快,推荐使用。
lsof -i :端口号 直接查特定端口,如 lsof -i :8080。
11. Swap 分区的作用是什么?为什么要关闭?如何关闭?
Swap 是交换分区,物理内存不足时将不活跃数据交换到磁盘,释放物理内存。但 Swap 读写远慢于物理内存,过度使用会导致性能严重下降。
Kubernetes 环境必须关闭 Swap,因为 Kubelet 要求关闭 Swap 才能正常工作。
临时关闭:swapoff -a。永久关闭:编辑 /etc/fstab 注释 swap 挂载行,然后 swapoff -a。查看:free -h 或 swapon -s。
12. iptables 放行 TCP 端口的命令是什么?
例如放行 80 端口:
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
13. DNS 解析失败如何排查?
先确认是全部域名都解析不了还是只有特定域名解析不了。
用 nslookup 或 dig 直接测目标域名,看能否正常返回 IP。查看 /etc/resolv.conf 中 nameserver 配置是否正确,ping DNS 服务器 IP 看网络是否可达。
用 tcpdump -i any port 53 抓 DNS 请求包,看请求有没有发出去、有没有收到响应。如果请求发出但没有响应,可能是 DNS 服务器挂了或网络不通。如果请求都没发出去,检查系统 DNS 相关配置是否正确。
14. SSH 免密登录如何配置?
客户端生成密钥对:ssh-keygen -t rsa。公钥传到目标服务器:ssh-copy-id user@host,自动追加到 ~/.ssh/authorized_keys。
之后直接 ssh user@host 无需密码。
15. 如何查看进程打开了哪些文件?卸载磁盘提示"设备正忙"怎么办?
用 lsof -p PID 查看进程打开的文件、网络连接、socket 等。用 lsof 文件名 看哪个进程正在使用该文件。
umount 报"设备正忙"时,用 lsof 挂载点 找到还在使用该目录的进程,关闭或重启该进程后再卸载。
16. grep、sed、awk 分别用在什么场景?
grep 用于文本搜索过滤,查找包含特定模式的行。
sed 是流编辑器,用于文本替换和编辑,sed -i 's/原/新/g' 文件 批量替换。
awk 用于提取和格式化字段,默认按空白分隔,awk '{print $1, $3}' 输出第一和第三列。
17. Shell 中 nohup 和 & 的区别是什么?
command & 让进程后台运行,但终端退出时进程收到 SIGHUP 信号而终止。
nohup command & 忽略 SIGHUP 信号,终端退出后进程不会停,输出默认写到 nohup.out。
生产环境常驻脚本建议用 systemd 管理,有自动重启和日志管理。
18. systemd 和 init 的区别是什么?如何查看 systemd 服务日志?
init 是传统初始化系统,启动串行执行,服务管理用 service 和 chkconfig。
systemd 是现代初始化系统,支持并行启动,用 Unit 文件管理服务,支持自动重启和依赖管理,服务管理用 systemctl。
查看 systemd 日志用 journalctl:journalctl -u 服务名、journalctl -f 实时跟踪、journalctl -n 100 限制行数。
19. Linux 中如何查看系统版本、内核版本和 CPU 信息?
查看系统版本用 cat /etc/os-release 或 cat /etc/redhat-release,不同发行版文件路径略有不同。
查看内核版本用 uname -r,想看更详细的信息用 uname -a。
查看 CPU 信息用 cat /proc/cpuinfo,主要看 model name(型号)、physical id(物理 CPU 个数)、cores(每个 CPU 核心数)。也可以用 lscpu 查看更直观的 CPU 架构汇总信息。
20. 进程 kill -9 和 kill -15 的区别是什么?
kill -15(SIGTERM)是优雅终止信号,进程收到后可以清理资源、保存状态再退出,进程可捕获处理。
kill -9(SIGKILL)是强制杀死,内核直接终止进程,进程无法做任何清理,可能导致数据丢失或临时文件残留。
生产环境优先用 kill -15,只有进程无法正常终止时才用 kill -9。
二、Nginx 运维面试题 TOP 10
1. Nginx 反向代理和正向代理的区别是什么?
正向代理是代理客户端请求,客户端配置代理访问外部网络,服务器只知道代理 IP。典型场景是内网用户通过代理上网。
反向代理是代理服务端,客户端请求发给反向代理,代理转发给后端真实服务器,客户端不知道后端是谁。典型场景是网站入口、负载均衡。
简单说:正向代理代理的是客户端,反向代理代理的是服务端。
2. Nginx 负载均衡支持哪些算法?
rr 轮询是默认算法,请求轮流分配,适合服务器配置相近的场景。
wrr 权重算法通过 weight 参数设权重值,高权重分配更多请求,适合服务器配置不一的情况。
ip_hash 根据客户端 IP 的哈希值分配,同一 IP 始终到同一台后端,适合会话保持的场景。
least_conn 将请求分配给连接数最少后端,适合长连接场景。
3. Nginx location 匹配优先级是怎样的?
优先级从高到低:
=精确匹配:完全匹配路径,匹配后立即停止^~路径前缀匹配:匹配后不再检查正则~和~*正则匹配:前者区分大小写,后者不区分- 普通前缀匹配:不带修饰符
匹配流程:先找所有普通前缀匹配和精确匹配,取最长匹配。然后按顺序检查正则,第一个命中的优先。^~ 跳过正则匹配阶段。
4. Nginx 502、503、504 状态码分别是什么?如何排查?
502 Bad Gateway:Nginx 没从上游收到有效响应。原因包括上游服务挂了、端口不对、防火墙拦截。重点排查确认上游服务是否正常运行。
503 Service Unavailable:服务不可用。原因包括上游过载主动拒绝、Nginx 限流触发、连接数达上限。排查检查连接数和限流配置。
504 Gateway Timeout:Nginx 等上游响应超时。原因包括上游处理慢、proxy_read_timeout 过短。排查检查超时配置,分析上游响应时间。
5. Nginx root 和 alias 的区别是什么?
root 指定根目录,访问路径拼接在 root 后面。比如 location /images/ 配 root /var/www,请求 /images/logo.png 去找 /var/www/images/logo.png。
alias 是路径别名,访问路径被替换。比如 location /images/ 配 alias /var/www/static/,请求 /images/logo.png 去找 /var/www/static/logo.png。
简单说:root 把路径追加在后面,alias 把路径替换掉。
6. Nginx 如何配置限流?limit_req 和 limit_conn 的区别是什么?
limit_req 是请求频率限流,基于漏桶算法控制每秒请求数,适合防 CC 攻击和接口防刷。
limit_conn 是并发连接数限流,限制同一时间最大连接数,适合控制资源占用。
区别:limit_req 控制 请求频率(每秒多少个),limit_conn 控制"并发连接数"(同时多少个连接)。
7. Nginx 怎么实现动静分离?
动静分离是将静态资源(图片、CSS、JS)和动态请求分开处理。
配置思路:用 location 匹配静态资源扩展名,用 root 指定本地目录让 Nginx 直接返回,加 expires 做浏览器缓存。动态请求用 proxy_pass 转发到后端应用服务器。
这样静态资源不占用后端服务器资源,响应更快。
8. Nginx 有哪些常见优化手段?
worker_processes 设为 CPU 核心数,worker_connections 根据系统调整,最大连接数是两者相乘。Linux 下用 epoll 事件模型。keepalive_timeout 减少频繁建连。
调整 proxy_buffer_size 和 proxy_buffers 提高代理效率。access_log 加 buffer 减少磁盘 I/O。系统层面调大 ulimit -n 文件句柄限制,配置内核参数减少 TIME_WAIT。
9. Nginx 如何配置 HTTPS?
准备 SSL 证书和私钥。在 nginx.conf 新建 server 块监听 443 端口,配置 ssl_certificate 和 ssl_certificate_key 指定证书路径。配置 ssl_protocols 只启用 TLSv1.2 和 TLSv1.3。
将 HTTP 的 80 端口重定向到 HTTPS,用 return 301 https://域名。
10. 统计 Nginx 访问日志中 TOP 10 IP 用什么命令?
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -10
先提取第一列 IP,排序,去重统计次数,按次数倒序,取前 10。
统计 TOP 10 URL:awk '{print $7}' access.log | sort | uniq -c | sort -rn | head -10。
统计 502 错误最多的 IP:awk '$9 == 502 {print $1}' access.log | sort | uniq -c | sort -rn | head -10。
三、Java 运维面试题 TOP 5
1. 你们公司 Java 应用突然响应变慢,作为运维你怎么排查?
先看系统资源,CPU 和内存是否异常。用 top 看 CPU 是否突高,用 free 看内存是否不足。
然后看 GC 情况,用 jstat -gcutil PID 1000 看 GC 是否频繁,如果 Full GC 频繁且耗时长,说明堆内存可能不够或有内存泄漏。
再看应用日志有没有报错,是不是连不上数据库或 Redis。检查外部依赖,比如数据库慢查询、Redis 超时。
最后看监控,是单台机器还是所有机器都慢,单台就踢掉这台,所有机器就检查上游,比如入口带宽、防火墙、DNS。
2. Java 应用 OOM 了,怎么处理?
先看日志确认是 OOM,dmesg | grep -i kill 看是否被系统杀掉。
用 jstat -gcutil PID 看各代内存使用率,是堆不够还是元空间不够。导出堆快照:jmap -dump:live,format=b,file=heap.hprof PID,用 MAT 分析哪个对象占用最多。
如果是容器环境,检查 JVM 有没有加 -XX:MaxRAMPercentage=75.0,没加的话 JVM 拿宿主机内存当参考,会超出容器限制被 kill。加了这个参数让 JVM 感知容器内存,堆大小自动适配容器 limits 的 70%-80%。
临时止血:重启应用。长期解决:调整堆大小参数或修复代码内存泄漏。
3. JVM 调优你做过哪些?改过什么参数?
堆内存相关:-Xms 和 -Xmx 设成一样,避免动态扩容,一般设为服务器内存的 50%-70%,容器环境用 -XX:MaxRAMPercentage=75.0。
GC 相关:大内存用 G1,-XX:+UseG1GC,设 -XX:MaxGCPauseMillis=200 控制最大暂停时间。
排查相关:-XX:+HeapDumpOnOutOfMemoryError 让 OOM 时自动导出堆快照,-Xloggc 记 GC 日志方便事后分析。
调参没有标准答案,都是先看监控发现问题,再改参数验证,逐步调整。
4. 排查 GC 问题用什么命令?主要看什么?
用 jstat -gcutil PID 1000 每秒看一次 GC 情况。
主要看这几列:YGC 和 FGC 是年轻代和老年代 GC 次数,YGCT 和 FGCT 是 GC 总耗时。如果 FGC 次数持续增长或 FGCT 占比过高,说明老年代 GC 频繁,有问题。
再用 jmap -heap PID 看堆内存各代配置和使用情况,确认堆大小设置是否合理。如果需要深度分析,导出堆快照用 MAT 看大对象谁占着内存不释放。
5. JVM 内存模型是怎样的?各区域的作用是什么?
JVM 内存主要分堆内存和栈内存。
堆内存是所有线程共享的,存储对象实例和数组,也是 GC 主要管理的地方。堆分为新生代和老年代,新生代放新创建的对象,熬过多次 GC 的会挪到老年代。
栈内存是线程私有的,每个线程都有一个,存方法的局部变量和调用信息,方法执行完栈帧就弹出,内存自动释放。
此外还有元空间(JDK 8 以后替代永久代),存类信息、常量、静态变量等,用的是本地内存而不是堆内存。
运维主要关注堆内存的使用率,以及 GC 是否频繁。
四、Shell模块(12题)
脚本执行
Shell脚本的执行方式有几种?
bash 文件路径
./文件名
source 文件路径
想把一个脚本做成开机自启动的,该怎么做?
1 首先要保证脚本是可以正常执行的
2 有两种方式事项开机自启动
1 写成systemctl的服务文件
2 写入到 rc.local 文件里面,然后让这个文件拥有执行权限
如果脚本执行中机房断电,重启后如何保证脚本能正常继续运行?
Shell 脚本本身没有断点续跑能力。断电进程直接消失,脚本不会自己恢复。
我们可以从如下的几个方面来解决:
如果是短周期 crontab 巡检脚本,不用做断点;服务器重启后 crontab 到时间自动执行下一轮巡检。
如果是耗时很长的脚本,比如备份迁移,就要对脚本进行改造,增加执行步骤的状态记录,做断点续跑的能力。
脚本设计
有一个文件,它的属性值是755,请问具体含义?
7 是所有者拥有rwx权限
5 是归属组拥有 rx权限
5 是其他人拥有 rx权限
你自己写过 Shell 脚本吗?
写过很多shell脚本,各种软件的部署脚本,ansible的自动化部署脚本、zabbix监控的item脚本等等很多。
如果写一个生产巡检脚本(检查CPU、内存、磁盘使用率,异常时告警),你怎么设计?
1 首先我能够保证要检查的内容是什么,命令能不能执行等
2 然后将梳理出来的、可以正常执行成功的命令放到脚本文件里面
3 将脚本改造为函数+脚本参数的方式来使用,便于和zabbix等软件进行item对接
脚本功能
数字场景下的条件判断,有哪些表达式?
-eq -ne -gt -lt -ge -le
如何查看一个文件的最后10行?如何实时监控文件内容变化?
tail -n 10 filename
tail -f filename
linux 磁盘满了,你会怎么排查?
首先我会先用 df -h 看整体磁盘使用率,区分两种情况:块空间满,还是 inode 耗尽。
1 如果 df -h 看到某分区 100%,这就表示块空间用完。
接着执行 du -sh /* 从根目录逐层扫描,一层一层 cd 进去往下深挖,找到大文件接下来rm掉即可。
如果文件已经 rm 删除,但进程还在用,磁盘空间不会释放。我会用 lsof | grep deleted 找出被删除但仍被进程打开的文件,重启对应业务进程即可释放空间。
2 如果 df -i 看到 inode 使用率 100%,表示块空间还有很多,是因为大量小文件导致的inode 耗尽。
使用 find 命令统计目录下文件数量,找到存放海量小文件的目录,清理无效小文件。
你对awk、grep、sed 熟悉不熟悉?
grep 侧重文本查找过滤。
sed 侧重行流编辑替换。
awk 侧重列处理、格式化、统计计算。
这三个,一般会结合管道一起使用。
你对于shell了解么?会用循环语句么?举个例子
会用,常见的shell循环有 for、while、until,后面两个往往做死循环。
for i in {a..z}
do
echo $i
done
查找/data/目录下所有 后缀为 .log 的文件,命令怎么写?
find /data -type f -name "*.log"
五、Mysql模块(11题)
Mysql的主从复制原理
准备工作:
1 主从复制两个节点的配置、目录、软件版本、大部分的配置都需要一样
2 需要提前做好全量数据同步,保证两个节点基础数据完全一样
3 在master节点上提前准备同步数据用的账号和密码
主从复制流程
1 在slave节点上,执行 change replication source to 创建集群的命令
2 在slave节点上,执行 start replica 命令,启动集群
3 slave节点上的io线程正常启动,然后根据配置连接到master节点上
4 master节点上启动dump线程,监听本地主机的二进制文件,一旦发现有增删改的新命令,就传递给slave节点
5 slave节点上的io线程将信息暂存到relay-log文件中
6 slave节点上的sql线程读取relay-log日志中的新内容,然后交给本地的mysql程序执行命令
7 最后两台节点的数据达到最终一致。
Mysql插入数据
如何往mysql环境中插入一条数据?
insert into table (字段) values(值);
写一个多表联合查询的 SQL,查询学生姓名、科目、分数,只查询有成绩的学生。
学生表 student,字段name、subject
分数表 score,字段score
SELECT s.sname,sc.subject,sc.score
FROM student s
INNER JOIN score sc ON s.sid = sc.sid;
Mysql备份
做过数据库备份吗?全量和增量备份怎么做的?
做过数据库备份,日常会做 全量备份 + 增量备份组合。
因为我们的数据量没有太多,所以全量备份使用的是mysqldump,基本上是每周做一次,保留31天,增量备份是6个小时做一次,保留7天。在一些比较重要的时间节点上的话,我们还会额外提前做一次全量备份。
我知道有一种物理的备份工具xtrabackup,它同时支持全量和增量备份。
备份是在主库还是从库进行?
我们是选择了一个从库节点,然后在这个节点上进行的备份动作,这样对主节点影响最少。
而且为了保证每次的备份是完整的,后面都做了备份后文件的检测工作
Mysql慢查询
你如何查询MySQL慢查询?
所谓的Mysql慢查询,就是业务操作过程中,某些语句执行的时间较长或者没有使用索引的一些语句,对于这些慢查询语句,我们一般会有监控,一旦发现大量的慢查询之后,会及时发现然后结合explain命令对慢查询sql语句进行针对性的分析和处理。
如果是复杂语句导致的慢查询,我们会反馈给研发人员,让他们改造一下语句,让语句简单一些。
如果是因为全表扫描因素导致的,我们会根据实际情况,在特定的表字段上添加索引,或者让研发人员改造一下sql语句使用索引来查询。
Mysql同步延迟
如何判断主从延迟?
关于mysql的主从数据同步的信息我们可以通过 show slave status\G 命令来检测
首先要保证 IO_Running 和 SQL_Running 的状态都是Yes,表示主从同步正常
关于延迟方面的内容,主要看如下几个参数
Seconds_Behind_Master 表示从库对比主库 binlog 时间戳算出的延迟
Master_Log_File、Read_Master_Log_Pos,确认从库已经读到主库哪个 binlog 文件、哪个位置。
Relay_Master_Log_File、Exec_Master_Log_Pos,确认从库已经执行完主库 binlog 哪个文件、哪个位置。
注意:
在mysql 8.4 里面 slave改造为 replica,master改造为source
从库如果有延迟,怎么进行排查?以及怎么进行规避?
思路:先区分是 IO 线程延迟,还是 SQL 线程回放延迟,再逐层定位根因,最后再执行规避手段
IO 延迟:从库拉取主库 binlog 慢;
排查点:
1. 网络:看主从节点之间网络质量;
2. 主库压力:主库 TPS 极高,短时间大量 binlog 生成,主库发送不过来;
3. 从库磁盘写压力:relay‑log 落盘慢,IO 打满,iostat 看 %util、await。
SQL 延迟:binlog 已经拉回来了,relay-log 本地回放执行慢,绝大多数现场都是 SQL 线程延迟。
排查点:
1. 看从库当前正在执行什么 SQL show processlist;
2. 查看从库系统资源 top、iostat、vmstat
3. 查看是否有从库慢 SQL、业务读从库带来锁
快速临时应急手段
1. 停止业务向从库压读流量;
2. 如果是大事务导致的延迟,不能重启 slave,否则延迟更大;只能等待回放完成;
3. 紧急业务:切换读写,直接切主库,放弃从库读,保障业务。
如何规避主从延迟
禁止大事务、binlog 格式设置为 ROW行模式、强一致性读请求直接读主库、多做监控
Mysql优化
比如说大表,比如说这表数据量特别多,你那一般怎么做?
一般来说,遇到数据量很大的大表,需要进行分库分表操作,但是我们的研发团队在面试这种情况的时候,并不是直接分库分表的,分几种情况处理:
如果有大量历史冷数据,优先做分区表或者数据归档,就算是删除数据也会小批量 limit 循环删除,避免大事务。
大表做DDL等操作,直接 alter table 会导致锁表隐患,可以使用pt‑osc工具可以直接处理
实在不行的话,再评估水平或者垂直分库分表,使用专业的分库分表工具来实现后续的处理
通用的处理措施
查询层面,优化索引,避免大 offset 分页,使用主键分页。
同时所有批量 DML 都要拆小事务,防止主从出现严重延迟。
大表 delete 千万行,为什么不能一次性删?
一次性删除千万行会生成巨大事务,undo 日志、binlog 暴涨;主库 IO 飙升;同时 binlog 推送到从库,从库 SQL 线程回放这个超大事务,主从延迟非常大,业务读从库就会读到旧数据。所以要分批小事务处理。
Mysql高可用
Mysql如何实现高可用?
可以通过 MGR 或者 PXC 方案来实现。
六、Redis (9题)
Redis的应用场景
缓存(热点数据)
会话存储(Session)
排行榜(ZSet)
实时计数
消息队列
分布式锁
限流(令牌桶)
Redis为什么快?
内存操作
单线程无锁
IO多路复用epoll
高效和简单的数据结构,很多操作时间复杂度 O (1)
网络优化pipeline
Redis是单线程吗?
Redis 命令执行是单线程的
但整体系统不是单线程,还有其它线程完成辅助功能
Redis 6+ 引入:网络 IO(读写 socket)可以多线程,命令执行仍然单线程
Redis做为缓存服务器使用时,出现缓存穿透,缓存击穿和缓存雪崩,什么意思?如何避免?
答案:
缓存穿透:查询根本不存在的数据,绕过缓存直达 DB。解决方案:缓存空值、参数校验、布隆过滤器。
缓存击穿:某一个热点 key 到期失效,大量并发请求打到数据库。可以加互斥锁,或者热点 key 不设置过期时间。
缓存雪崩:大量缓存 key 同一时间失效或者 Redis 挂掉,大量请求压垮数据库。给过期时间加随机偏移,搭建 Redis 集群,同时做限流降级。
解析:
缓存穿透 Cache Penetration
缓存穿透是指缓存和数据库中都没有的数据,而用户不断发起请求,比如: 发起为id为 “-1” 的数据或id为特别大不存在的数据。
这时的用户很可能是攻击者,攻击会导致数据库压力过大。
解决方法:
-
接口层增加校验,如用户鉴权校验,id做基础校验,
id<=0的直接拦截 -
从缓存取不到的数据,在数据库中也没有取到,这时也可以将key-value对写为key-null,缓存有效时间可以设置短点,如30秒(设置太长会导致正常情况也没法使用)。这样可以防止攻击用户反复用同一个id暴力攻击
缓存击穿 Cache breakdown
缓存击穿是指缓存中没有但数据库中有的数据,比如:热点数据的缓存时间到期后,这时由于并发用户特别多,同时读缓存没读到数据,又同时去数据库去取数据,引起数据库压力瞬间增大,造成过大压力
解决方法:
- 设置热点数据永远不过期。
缓存雪崩 Thunder Hurd Problem
缓存雪崩是指缓存中数据大批量到过期时间,而查询数据量巨大,引起数据库压力过大甚至down机。和缓存击穿不同的是,缓存击穿指并发查同一条数据,缓存雪崩是不同数据都过期了,很多数据都查不到从而查数据库。
解决方法:
-
缓存数据的过期时间设置随机,防止同一时间大量数据过期现象发生
-
如果缓存数据库是分布式部署,将热点数据均匀分布在不同搞得缓存数据库中
-
设置热点数据永远不过期
Redis的持久化如何实现?各有什么特点
答案:
Redis 持久化分为 RDB 和 AOF。
RDB 是基于时间点的静态数据快照,fork 子进程生成 rdb 二进制文件,恢复快,但会丢失部分数据。
AOF 记录每一条写操作命令,数据安全性更高,日志文件会比较大,可以做 AOF 重写压缩。
生产一般RDB+AOF 同时开启,默认使用 AOF 恢复,直接忽略rdb的恢复。
解析:
| 维度 | RDB(快照) | AOF(追加日志) |
|---|---|---|
| 本质 | 全量数据快照 | 增量操作日志 |
| 数据安全 | ❌ 可能丢失(取决快照间隔) | ✅ 较高(最多丢1秒) |
| 持久化方式 | 定时生成 dump.rdb | 持续追加写命令 |
| 文件大小 | 小(压缩二进制) | 大(文本日志) |
| 恢复速度 | ✅ 快 | ❌ 较慢 |
| 可读性 | ❌ 不可读 | ✅ 可读 |
| 性能影响 | 小 | 略高 |
| 是否支持实时 | ❌ 否 | ✅ 是 |
| fork 子进程 | ✅ 需要 | ✅ rewrite 时需要 |
| 适合场景 | 备份 / 灾难恢复 | 数据安全优先场景 |
Redis 支持哪些数据类型
1. String(字符串)
2. List(列表)
3. Set(集合)
4. Hash(哈希)
5. ZSet(有序集合)
主从复制工作原理
核心特点:
- 主节点(Master)负责写
- 从节点(Replica/Slave)负责读
- 异步复制(默认)
- 风险:主节点宕机 → 数据丢失
Redis sentinel 哨兵工作原理
哨兵是高可用监控组件。多个哨兵共同监控 redis 主从;先主观下线,多数哨兵确认后客观下线;选出领头哨兵,把从节点提升为新主,其余从跟随新主;客户端向哨兵查询主节点地址。
Redis cluster 的工作原理
Redis‑Cluster 一共 16384 个哈希槽,通过 CRC16 (key)%16384 计算 key 所属槽,数据分散到各个主节点;主节点配有从节点,主故障从自动升主;节点之间通过 Gossip 协议同步集群状态;不支持跨槽多 key 事务。
七、Zabbix模块(4题)
你平常监控哪些指标?
我主要监控四大块:主机系统、内核 TCP、中间件数据库、业务层。
1. 主机系统:
CPU、内存、负载、磁盘空间/inode、磁盘IO、网卡流量丢包等。
2. 网络 TCP 指标:
连接状态、重传率,重点看大量CLOSE_WAIT、TIME_WAIT异常。
3. 中间件数据库
- Nginx:QPS、响应时间、4xx/5xx 错误码、活跃连接
- MySQL:TPS/QPS、慢查询、连接数、缓冲池命中率、主从延迟
- Redis:内存占用、key 淘汰、客户端连接、复制延迟
4. 业务层面(SRE 黄金指标):【这个不用回答,如果你懂的话,可以说】
QPS、P95/P99 延迟、错误率、消息队列堆积。
同时还要监控 监控Agent服务存活,告警分级,避免告警风暴。
日常巡检,主要是巡检哪些东西?
主机状态方面,看看服务器是否在线,系统时间是否正常。
系统资源方面,主要看CPU、内存、系统负载,swap 有没有频繁使用、磁盘使用率、inode,磁盘IO等。
服务进程方面,关键业务服务是否运行正常,进程有没有挂掉。
日志查看方面,主要看系统日志、应用业务日志,看有没有报错。
网络方面,主要看基础网络连通性,服务应用端口监听是否正常。
备份检查方面,主要是确认备份任务是否执行成功。
等
监控数据采集频率是多久?
主机基础资源方面,一般是 1 分钟采集,而且很多监控软件的默认监控频率都是1分钟。
业务、中间件关键指标 30 秒采集一次,不建议采集过频,避免监控本身压力过大。
如果指标数据采集间隔时间太小,数据量暴涨,存储和IO压力大,一般故障 1 分钟粒度足够发现。
你们监控用的是什么方案,部署在哪里,介绍一下架构?
我们公司的监控软件解决方案,采用的是Zabbix方案。Zabbix Server 部署在独立监控服务器(4C16G)上,业务机器上所有部署 Zabbix-Agent。
Agent 在被监控主机采集各种监控指标,我们整体环境大概几千个 items,每个节点也就几十个item,然后传输给 Server。
Server 把这些数据交给mysql,然后存储到mysql环境里面,后面在zabbix server的web界面上定制自动化监控策略,实现自动化监控数据的效果,当然我们还实现了钉钉方式的及时告警效果。
八、数据包进阶与内核管理(2题)
tcp的三次握手 ,tcp的四次断开
三次握手
1 初始状态:双方处于未连接状态
2 第一次握手:主机a 发送包含 SYN标识位 的数据包给 主机b
3 第二次握手:主机b 返回包含 SYN和ACK标识位 的数据包给 主机a
4 第三次握手:主机a 返回包含 ACK标识位 的数据包给 主机b
5 最终状态:双方处于连接状态
四次断开
1 初始状态:双方处于已连接状态
2 第一次挥手:主机a 发送包含 FIN标识位 的数据包给 主机b
3 第二次挥手:主机b 返回包含 ACK标识位 的数据包给 主机a
4 第三次挥手:主机b 返回包含 FIN标识位 的数据包给 主机a
5 第三次挥手:主机a 返回包含 ACK标识位 的数据包给 主机b
6 最终状态:双方处于连接断开状态
如果我访问应用不成功,你会怎么排查?
参考如下的几个排查思路即可。
ifconfig、ip a,确保本地网络信息正常
ping 127.0.0.1,验证本地网卡协议栈是否正常
ping 网关IP,验证内网连通性
route -n,检查默认路由是否存在
traceroute/mtr 公网IP,定位外网路由丢包节点
tcpdump,抓取业务端口数据包,分析应用层通信异常
九、iptables与web安全加固(5题)
有做过系统的安全加固吗?
有做过系统安全加固,主要是针对CentOS、Ubuntu服务器做基线加固。
账号权限这块:清理系统无用账号;修改sudo权限,只给必要用户授权,禁止root远程直接登录等。
然后是网络层面:开启防火墙,只开放业务必需端口;SSH做加固,禁止root密码登录等。
还有文件与系统安全:修改关键文件权限防止被篡改,比如passwd、shadow;关闭系统不需要的开机自启服务等。
还有安全巡检:定期检查登录失败记录;定期更新系统补丁等。
加固完成后会做验证,测试端口访问、SSH 登录权限,确认加固策略生效。
你们登录服务器用的是什么账号?
我们远程登录不用root,使用独立的普通运维账号,通过SSH密钥登录,需要管理员权限时用sudo提权,一人一号,方便审计。
有做过系统调优吗?
做过系统调优,主要针对业务服务器的运行方面的,比如内核参数调整、web和数据库环境下文件描述符和资源限制等。比如遇到问题后,先用top、vmstat、iostat等工具定位,定位问题原因后,通过修改sysctl和limits.conf等文件属性,最后解决问题。当然了,优先在测试环境验证,再应用到生产,同时我们还会做好参数备份,便于异常情况下的回滚操作。
用的什么系统?linux漏洞修复怎么做的?
线上主要是CentOS7和Ubuntu20.04。
关于漏洞修复会有专门的文档,里面的流程是先扫描CVE后评估风险,然后在测试环境验证补丁
CentOS用yum安全更新,Ubuntu用apt升级;
如果修补漏洞涉及到内核补丁,修补完毕后会重启主机
如果主机很多的话,我们会分批操作并验证,不能重启的先做临时加固。
Linux中firewalld和iptables是什么区别?什么叫动态的规则、静态的规则?
firewalld和iptables都是Linux的防火墙,底层都调用netfilter内核框架,区别主要是管理方式、规则样式。
iptables 是静态防火墙;firewalld 是动态防火墙
iptables是按表、链结构去写规则,语法比较繁琐。
firewalld引入了区域的概念,基于区域管理访问策略,使用起来更简单。
firewalld底层仍然调用iptables,只是封装了一层,从而实现业务应用层面的便捷而已,但是我实践后,还是会觉得iptables简单一些。
十、高可用和高扩展(4题)
简单介绍一下 nginx高可用
Nginx高可用我们用Nginx+Keepalived方案。
两台Nginx服务器,一主一备。Keepalived 基于VRRP协议,对外提供一个VIP。
同时会写脚本监控 nginx 进程,如果 nginx 挂了但服务器还活着,就关闭本机 keepalived,触发 VIP 转移。
简单介绍一下,keepalived原理
Keepalived 主要基于VRRP,用来实现故障转移,做高可用。
多台服务器组成一个VRRP组,共用同一个VIP。节点分MASTER和BACKUP。
主节点正常持有VIP并发送通告;主节点故障,备节点超时没收到通告,自动接管VIP,实现故障自动转移。
负载这些用过吗?你就说一个整体的网络架构,你们那边用你用过的是什么样的?
用过负载均衡,我们线上整体架构是:
用户-->公网-->Nginx[Keepalived 高可用]做四层/七层负载均衡-->后端应用服务器集群,应用再连数据库。
前端Nginx两台主备,Keepalived提供VIP作为入口。Nginx做七层负载,分发HTTP请求到多台应用服务,后端应用是多台业务服务器,实现业务水平扩容。数据库单独部署,主从架构,读写分离。
网络方面,我们在防火墙上做安全加固,只对外开放80、443;内网业务服务器之间互通,不暴露公网。
监控这边用zabbix,监控VIP、Nginx进程、端口、CPU内存,异常告警等等信息
比如说你那边入口是什么?入口以后去经过哪些东西到你的机器上,然后机器是不是存数据库,就类似于这个链路,你讲一下。
用户请求从公网进来,入口是Keepalived的VIP,流量到Nginx做负载,Nginx转发内网请求到应用服务器;应用服务器再单独访问独立的数据库主从节点,应用机器本身不存放数据库。
链路:用户-->VIP-->Nginx-->应用集群-->数据库。
十一、Ansible模块(6题)
不应该先做免密再用 Ansible 连吗?直接用 Ansible 的模块可以连通吗?
是的,常规做法是先配置SSH免密登录,Ansible再批量管理主机。Ansible底层走SSH协议,默认就是用SSH连接目标机器,免密是我们生产环境最常用的方式,不用每次输密码。
但Ansible也支持带上SSH密码直接连接目标主机执行模块,只是不安全,一般只做初始化临时使用。
免密是通过命令实现,还是通过公钥私钥实现?
免密登录底层是公钥私钥非对称加密机制实现的。
我们执行的ssh-keygen、ssh-copy-id 这些命令,用来生成密钥对、把公钥传到目标机器。
我看到你还会用 Ansible,你是用 Ansible 的 Ad‑Hoc,还是自己写 Playbook 呢?
两种都在用,场景不一样。
临时批量执行简单命令用Ad-Hoc;多步骤的配置、部署、加固这类需要重复执行的场景,编写Playbook。
如果有个需求,就是从当前主机拷贝一个文件到所有远程主机中,你怎么拷贝?
如果是临时一次性拷贝,直接用Ansible的copy模块。
如果这个分发操作要反复执行,就在Playbook里使用copy模块
当然还有远程拉取的模块fetch。
copy本地推文件到远程,fetch从远程拉文件到本地
Ansible都用过哪些模块?
shell、command、copy、file、service、authorized_key、yum/apt、template等等
平常的业务场景多用专用的模块,但是遇到一些定制性的操作时候,我会用shell。
如果想给某一组节点,用APT装10个包,如何在Playbook里面实现?
- name: 给指定主机组安装10个软件包
hosts: web_group
become: true
tasks:
- name: 批量安装软件包
apt: name={{ item }} state=present update_cache=yes
loop:
- nginx
...
- wget
十二、Docker (14题)
容器和虚拟机什么区别
虚拟机是虚拟成一个完整的计算机,包括所有硬件和OS
容器基于内核 的namespace和cgroups,及Union File System等技术实现, 容器中只包括应用相关的文件,不包括OS内核
容器的核心技术是什么
namespace
control groups
联合文件系统: overlayfs
docker的常用命令有哪些
docker 的镜像管理
docker pull,push,images,rmi,inspect,tag,save,load
docker 的容器管理
docker run,rm,ps,start,stop,kill,logs,stats,top
如何将一个主机的所有镜像导入到另一台主机
docker save
docker load
容器无法启动,如何查看原因
docker inspect
docker ps
docker logs
如何进入容器
docker attach
docker exec
Dockerfile的指令有哪些
FROM
LABEL
ENV
RUN
COPY
ADD
CMD
ENTRYPOINT
ARG
EXPOSE
USER
VOLUME
WORKDIR
ONBUILD
STOPSIGNAL
HEALTHCHECK
ONBUILD
MAINTAINER
Dockerfile中ADD和COPY的区别
ADD 支持打包压缩文件的自动解包,并且支持URL远程下载文件
COPY 不支持
Dockerfile中CMD和ENTRYPOINT的区别
1)ENTRYPOINT和CMD 只存在一个时,都可以做为容器启动的默认命令
2)ENTRYPOINT和CMD 两者同时存在时,CMD将成为ENTRYPOINT的参数
3) ENTRYPOINT 是个脚本,结合exec "$@",将CMD变成默认启动命令,ENTRYPOINT 仅成为临时执行的环境初始化的脚本
4)docker run image CMD2 替换 CMD
5) docker run --entrypoint string 替换 ENTRYPOINT
Dockerfile 如何优化镜像体积?
- 使用 Alpine 这种较小的基础镜像
- 多阶段构建
- 合并 RUN 指令
- 清理缓存和不需要的文件
Docker的持久化有哪些方式
-
绑定挂载(Bind Mount)
绑定挂载,直接映射宿主机目录
-
卷(Volume)
这是 Docker 推荐的挂载方式。
卷是完全由 Docker 管理的文件目录,可以在容器之间共享和重用。
卷分为匿名卷和命名卷
-
tmpfs 挂载:
内存挂载, 所以此方式并不算一种持久化方案
tmpfs 挂载是临时的,只存留在容器宿主机的内存中。当容器停止时,tmpfs 挂载文件路径将被删除,在那里写入的文件不会被持久化。
Docker 和 Docker-compose 有什么区别
Docker-compose 是单机的多容器按项目管理的容器编排工具
docker是单机管理容器的工具,不支持按项目分组管理
docker的制品仓库用什么?Harbor 了解吗?
Harbor 是企业级镜像仓库,支持权限管理、镜像复制、漏洞扫描
Docker 的网络模式有哪些
Docker 常见的网络模式主要有5种:`bridge`、`host`、`none`、`container`、`network`(自定义网络)。其中前 3 种是最核心的网络模式。
bridge 每个容器使用独立网络,多个容器都桥接在一个网桥并通过 NAT 和外部通信
host 容器与宿主机共享网络栈
none 容器没有网络,
container 容器与指定的其它容器共享网络栈
自定义网络: 使用自定义网络的多个容器,可以使用指定的网络地址,并且支持通过容器名称相互访问
Docker 如何配置访问私有仓库Harbor的http访问
1)修改/etc/docker/daemon.json文件,添加下面行
"insecure-registries": ["harbor.wang.org"]
2)生效
systemctl restart docker
十三、Kubernetes (19题)
k8s 有哪些组件及功能
#控制平面
apiserver:集群管理的统一入口
etcd:存储集群数据
controller-manager:管理控制器,维持期望状态
scheduler:调度 Pod 到合适节点
#工作平面
kubelet:节点上管理 Pod 的代理
kube-proxy:维护网络规则,实现 Service
container runtime: 容器运行时
#插件
网络附件:flannel/calico
coredns
ingress-nginx
基于 kubeadm 部署的 K8S流程说明一下
在所有Master和Node节点上实现初始环境准备,包括主机名,内核,swap分区禁用,时间同步等
在所有Master和Node节点都安装和配置容器运行时
在所有Master和Node节点都安装kubeadm 、kubelet、kubectl(集群管理工具,在node节点可不安装)
在第一个 master 节点运行 kubeadm init 初始化命令,创建集群
在其它master节点运行kubeadm join 命令加入到控制平面集群中实现高可用
在所有node 节点使用 kubeadm join 命令加入集群 , 并验证 node 节点状态
在master 节点安装配置CNI规范的相关附件,比如flannel等
创建 pod 并启动容器测试访问 ,并测试网络通信
k8s 有哪些接口
CRI: 容器运行时接口
CNI: 容器网络接口
CSI: 容器存储接口
什么是Pod
一个 Pod 包含pause容器及用户定义的一个或多个紧密耦合的容器
一个Pod的所有容器共享网络命名空间、共享存储卷
Pod 是 K8s 里最小的可调度单元。
一个Pod中所有容器只能统一调度在同一个节点上。
Pod 出现 Pending状态,如何排查,有哪些原因
#排查方法
kubectl describe
kubectl get events
kubectl logs
#可能的原因
节点资源不足
PVC 未绑定 PV
网络插件异常
节点异常
调度策略不匹配
Pod 镜像拉取失败(ImagePullBackOff)可能原因
镜像地址错
认证失败
网络不通
磁盘满
Pod 分类
1)自主式 Pod:
2)由 Workload Controller 管控的 Pod
3)静态 Pod
Pod 探针有哪些?
startupProbe:启动探测,成功后才启动其他探针,失败会重启Pod
livenessProbe:探测是否存活,失败则重启容器
readinessProbe:探测是否就绪,失败则从 Service 摘除,不再将请求调度到此Pod
Pod的资源限制如何实现
Request:资源使用的下限
Limit:资源使用的上限,容器能使用的最大资源
DaemonSet 是什么?适用场景?
每个节点运行一个 Pod。一般用于系统应用,比如日志收集、监控 Agent、网络插件等
Service 类型有哪些?
ClusterIP:集群内部访问
NodePort:节点端口30000-32767暴露,外部可访问
LoadBalancer:对接云厂商 LB
ExternalName:映射外部 DNS
什么是 headless service
没有 clusterIP的 SVC, 常用于有状态服务
Service的域名结构是什么
<service_name>.<namespace>.svc.cluster.local
PV和PVC 是什么
PV 提供存储的具体实现,比如:NFS,hostPath等,大小,访问模式等
PVC 定义用户的存储需求,比如:大小,访问模式等
ConfigMap 和 Secret 有什么区别
ConfigMap:存储非敏感配置,比如:环境变量、配置文件,以明文保存
Secret:存储敏感信息,比如:密码、私钥、token,以base64 编码保存
Service 和 Ingress 的区别?
Service:基于内核中iptables或者IPVS实现的四层代理
Ingress:基于HTTP/HTTPS协议实现的七层代理,需要安装ingress controller才能实现
K8s Ingress访问的流量路径
用户 → DNS 域名解析 → ingress controller service IP (LoadBalancer/NodePort) → Ingress Controller Pod → Service → Pod
deployment和statefulset 有什么区别
Deployment:用于无状态应用,Pod 随机名称
StatefulSet:用于有状态应用,每个Pod的名称按顺序编号的,pod创建,扩缩容和滚动更新都有顺序的、一般会结合headless SVC和DNS实现每个Pod都有稳定域名、每个Pod 固定绑定独立的存储
Helm chart 包的目录结构是什么
mychart/
Chart.yaml #包含了该chart的描述
templates/ #包括了各种基于golang模板语法资源清单文件。比如: deployment,service等
values.yaml #此文件提供templates中使用变量的默认值
十四、Prometheus (4题)
Prometheus 哪些组件
Prometheus:抓取指标、存储
Alertmanager:告警管理
Grafana:可视化
pushgateway: 采集瞬时的指标,再发送给Prometheus
Exporters:针对各种应用用于暴露其指标
Prometheus 通常使用pull还是push?什么情况下使用push
prometheus 通常使用pull
监控端将瞬时指标数据使用 push发送给 pushgateway,再由prometheus利用pull 将指标取走
Prometheus 监控哪些指标?
系统指标:CPU、内存、磁盘、网络
应用层:连接数、QPS、延迟、错误率
业务层:订单量、登录成功率
容器层:Pod 状态、资源使用情况
Prometheus 支持几种指标类型
Counter、Gauge、Histogram、Summary
counter(计数器):只增不减,重启归零。例:请求总次数、错误总数。
Gauge(仪表盘):可增可减,瞬时值。例:当前内存、在线连接数、Pod 数量。
Histogram(直方图):统计样本分布,由服务器端计算生成,比如计算分位数 p95/p99
Summary(摘要):统计样本分布,由客户端生成,服务器端只需要存储