Skip to content

问答文档2


一、自我介绍与项目经验类

Q1: 请做一个简短的自我介绍

好的,我叫褚成志,之前主要从事智能运维和项目交付实施相关的工作。

在过往经历中,我接触过AIOps智能运维平台的落地实施,参与过监控系统的部署与运维,包括Zabbix、Prometheus、Grafana等主流监控工具的使用和二次开发。我也负责过日志分析平台(ELK Stack)的建设,能够独立完成从日志采集、解析到可视化的全流程搭建。

在项目经验方面,我参与过运营商客户的运维平台建设项目,主要负责系统部署、告警策略配置、故障排查和客户培训等工作。平时工作中Shell和Python脚本写得比较多,主要用于自动化巡检、日志分析和告警数据处理。

我对新华三AIO产品有过关注了解到AIO 3.0版本在智能运维、智算运维运营方面有很强的能力,特别是基于大模型的故障诊断和根因分析功能,我很感兴趣加入这个团队深入学习。


Q2: 你参与的印象最深刻的项目是什么?请介绍一下项目的背景、你的职责和难点。

我印象比较深的是参与某省级运营商的运维监控平台建设项目

项目背景: 该客户之前使用多套独立监控工具,数据分散、告警泛滥,一线运维人员每天要处理几百条告警,但真正需要关注的故障反而容易被淹没。项目目标是建设统一的智能运维平台,实现全栈监控覆盖和告警收敛。

我的职责: 我主要负责监控体系设计和告警策略配置。具体包括:根据业务系统架构梳理监控点,设计分级告警规则(比如核心业务系统故障要立即通知,小问题可以延迟处理),以及用Python脚本实现日志自动解析和异常初筛。

遇到的难点: 一是历史数据清理问题,客户积累了大量历史告警配置,很多已经失效,我们花了时间逐条梳理才能重建。二是告警收敛逻辑的设计,怎么把几十条相关告警收敛成一条有价值的通知,这需要理解业务依赖关系和故障传播路径。我们当时基于CMDB的拓扑数据,做了告警关联规则,取得了不错的效果。

最终成果: 平台上线后,告警数量下降70%左右,一线响应效率有明显提升。


Q3: 项目中遇到的最大技术挑战是什么?你是怎么解决的?

最大的挑战是在一个跨地域的分布式系统上做故障根因定位

当时的情况是:客户的生产环境有几十台服务器,运行着几十个微服务,某天突然出现大量业务告警,但告警来源分散,有的说数据库慢、有的说网络丢包、还有的说应用响应超时。传统方式要逐台登录查看日志,效率很低。

我的解决思路:

第一步,我先梳理了整体架构,搞清楚服务之间的调用依赖关系,这部分主要参考CMDB和之前的技术文档。

第二步,在现有监控基础上增加了链路追踪的能力,使用SkyWalking来做微服务的调用链分析,这样能看到一次请求经过哪些服务、每个环节的耗时。

第三步,针对日志分析,引入了ELK的日志关联分析功能,把关键服务的错误日志和性能指标做时间线对齐。

第四步,也是最关键的,我们建立了一个故障传播模型,把常见故障模式整理成规则,比如"数据库连接池耗尽→应用线程阻塞→前端超时"这种链路,当最末端的告警出现时,能自动向上追溯可能的根因。

效果: 后来遇到类似情况,定位时间从原来的平均40分钟缩短到了10分钟左右。


Q4: 你如何向非技术人员解释一个复杂的技术问题?

我会用类比的方式,让对方能在自己熟悉的场景中理解。

比如解释"为什么要做监控告警收敛",我会这样说:

"您平时网购的时候,有没有遇到过这种情况:快递明明早就发出了,但就是查不到物流信息,打客服电话问,客服说'这边显示仓库在打包',物流客服说'这边显示还没揽收',仓储客服又说'已经交给快递了'——三方都说自己没问题,但你就是收不到货。

我们做的工作就像给快递公司上一套'智能追踪系统',让系统自动判断到底是哪个环节出了问题:是仓库打包慢了,还是快递揽收慢了,还是物流分拣卡住了。而且系统会直接把结论推给能解决问题的人,而不是让所有人都收到通知一头雾水。

我们建设的智能运维平台就是这个作用,让机器自动分析、快速定位、少走弯路。"

这种类比方式容易让对方建立直观印象,也能体现你对业务价值的理解。


二、Linux系统类

Q5: Linux服务器突然SSH登录不上去,你怎么排查?

这是一个很经典的排查场景,我会按以下顺序来:

第一步:确认问题范围 先从自己的电脑能否ping通服务器开始,如果网络不通,可能是网络层面的问题,需要找网络工程师协助。

如果能ping通但ssh连不上,继续往下排查。

第二步:尝试其他方式确认服务器状态

  • 让同事帮忙去机房看看服务器的指示灯状态,键盘灯亮不亮
  • 通过IPMI/iLO/idrac等带外管理接口登录,查看服务器硬件状态和系统日志

第三步:常见原因逐项排查

  1. 服务挂了:让同事帮忙登录物理机,执行systemctl status sshd看ssh服务状态,如果停了尝试systemctl restart sshd

  2. 端口被占或监听异常netstat -tlnp | grep 22查看22端口监听情况

  3. 防火墙拦截iptables -L -nfirewall-cmd --list-all检查防火墙规则,确认22端口是否放行

  4. 资源耗尽

    • 内存不足会导致sshd无法fork新进程,看free -h
    • 磁盘满了sshd也可能异常,看df -h
    • 连接数达到上限:ss -s查看
  5. 用户/权限问题:检查/etc/passwd/etc/ssh/sshd_config配置

  6. 安全策略:看是否有fail2ban等工具把IP封禁了

  7. 日志分析journalctl -u sshd --no-pager -n 50cat /var/log/secure(CentOS)/ cat /var/log/auth.log(Ubuntu)查看登录失败原因

第四步:如果确认是资源问题

  • 内存不足可以先kill掉占用高的进程
  • 磁盘满了先清理日志或临时文件df -h --test定位大文件

Q6: 如何排查服务器负载高的问题?

**服务器负载高(Load Average高)**是常见问题,我的排查思路是"先定位瓶颈资源,再分析进程"。

第一步:确认负载情况

bash
uptime        # 查看负载值,1/5/15分钟平均负载
top           # 交互式查看CPU、内存占用,按M按P排序
w             # 查看谁登录了、在跑什么

第二步:定位瓶颈类型

bash
# CPU密集型?
top -H  # 按线程看,定位哪个进程CPU高
ps aux --sort=-%cpu | head

# 内存不足?
free -h
vmstat 1 5   # 查看si/so(swap in/out)如果值很大说明在用swap,内存瓶颈

# IO瓶颈?
iostat -x 1 5  # 查看%util、await
iotop         # 实时看哪个进程IO高

# 网络瓶颈?
netstat -i    # 查看网卡流量
ss -s         # 查看连接统计

第三步:如果是CPU问题

bash
# 定位高CPU进程
ps -eo pid,ppid,%cpu,%mem,cmd --sort=-%cpu | head

# 如果是Java进程,用jstack抓线程堆栈
jstack <pid> > thread.log
# 找出CPU占用高的线程tid,转换为16进制后在线程栈中定位

第四步:如果是IO问题

bash
# 查看哪些文件占用IO高
lsof +D /  # 慎用,会扫描全盘
# 或者用
iotop -ao  # 按IO排序实时显示

第五步:分析日志和计划任务

bash
# 是否有cron任务同时跑导致瞬时负载高
crontab -l
cat /var/log/cron

# dmesg看内核日志,是否有硬件故障(磁盘、网络控制器报错)
dmesg | tail -100

Q7: 如何查找一个占用内存过高的Java进程并分析原因?

定位进程和内存占用:

bash
# 查看Java进程内存占用
ps aux | grep java | grep -v grep
jps -lvm   # 查看Java进程

# 用ps查看内存占用排序
ps aux --sort=-%mem | head

详细分析:

bash
# 1. 查看JVM堆内存使用情况
jstat -gc <pid> 1000 5   # 每秒打印GC统计,观察堆使用

# 2. dump堆内存快照分析(需要curl远程执行jmx或重启前抓取)
jmap -dump:format=b,file=heap.hprof <pid>

# 3. 使用MAT(Memory Analyzer Tool)分析dump文件
# 可以找出内存泄漏的对象、占用最大的类

# 4. 查看JVM参数配置
jinfo -flags <pid>

常见原因:

  1. 内存泄漏:对象被持续引用无法回收,最典型的是集合类不断add不清理、静态集合持有对象引用、缓存没有过期机制
  2. JVM参数配置不当:堆内存设置过小(-Xmx),或者年轻代太小导致频繁Full GC
  3. 代码问题:一次性加载大对象到内存、字符串拼接效率低、大日志直接打印到控制台

快速应急处理:

bash
# 如果内存持续增长且无法立即定位,先重启恢复服务
# 记录下当前状态以便事后分析
jmap -histo <pid> > histo.log  # 打印对象直方图

Q8: 如何快速清理服务器上的大日志文件但不影响正在写入的进程?

核心思路:不能用rm直接删,会导致文件描述符问题。

正确做法:

bash
# 方法1:清空文件内容但保留文件描述符
> /path/to/logfile.log
# 或者
truncate -s 0 /path/to/logfile.log
# 或者
cat /dev/null > /path/to/logfile.log

# 方法2:用tee清空
tee /path/to/logfile.log </dev/null

# 方法3:用echo清空
echo "" > /path/to/logfile.log

然后通知应用重新打开日志文件:

bash
# 如果应用支持reload配置信号
kill -USR1 <pid>

# 对于Java应用,可能需要滚动日志配置或重启
# 对于nginx
kill -USR1 $(cat /var/run/nginx.pid)

更好的方案是配置日志轮转:

bash
# 用logrotate自动管理
/etc/logrotate.d/your-app
"""
/path/to/logfile.log {
    daily                 # 每天轮转
    rotate 7              # 保留7份
    compress              # 压缩旧日志
    delaycompress         # 延迟压缩,保留最近一份不压缩
    missingok             # 文件不存在不报错
    notifempty            # 空文件不轮转
    dateext               # 加日期后缀
}

验证:

bash
# 确认原文件大小为0
ls -lh /path/to/logfile.log
# 确认进程仍在正常写入
lsof | grep logfile.log

Q9: 描述一下Linux的进程、线程、协程的区别

进程(Process):

  • 进程是资源分配的基本单位,有独立的内存空间(堆、栈、全局变量等)
  • 进程间通信需要用pipe、socket、消息队列、共享内存等方式
  • 创建和切换开销大,但隔离性好,一个进程崩溃不影响其他

线程(Thread):

  • 线程是CPU调度的基本单位,同一进程内的线程共享堆内存
  • 线程间通信方便(直接读写共享变量),但要注意同步问题
  • 创建和切换开销比进程小很多
  • 在Python中,由于GIL的存在,多线程不适合CPU密集型任务,但适合IO密集型

协程(Coroutine):

  • 协程是用户态的"轻量级线程",由程序自己控制调度,不涉及内核
  • 同一线程内可以有多个协程,通过await/yield切换,开销极小
  • 适合高并发IO场景(如网络请求),一个请求阻塞时可以切换到其他协程继续执行
  • Python中的asyncio就是协程实现,Go的goroutine也是类似概念

实际选择:

  • 高并发网络IO场景用协程或异步IO(如Python asyncio、Go)
  • CPU密集型用多进程绕过GIL(如Python multiprocessing)
  • 需要共享内存、通信方便用多线程
  • 追求稳定隔离用多进程(如nginx的worker进程模式)

Q10: Linux中软链接和硬链接的区别是什么?各自适用场景?

核心区别:

特性软链接(Symbolic Link)硬链接(Hard Link)
本质创建一个特殊文件,存储目标路径多个目录项指向同一个inode
跨文件系统支持不支持(必须在同一分区)
链接目录支持不支持
删除行为删除软链接不影响原文件所有硬链接都删了文件才真正删除
磁盘空间基本不占(只存路径字符串)不占额外空间

软链接使用场景:

bash
# 解决程序版本问题
ln -s /opt/app/v2.1.0 /opt/app/current

# 目录快捷方式
ln -s /usr/local/mysql /usr/mysql

# 解决长路径问题
ln -s /var/log/nginx/access.log /opt/access_log

硬链接使用场景:

bash
# 备份文件(防止误删)
ln /data/important.txt /backup/important.txt.bak

# 文件系统内快速复制(不占用额外空间)
ln /data/report.pdf /data/report_backup.pdf

注意事项:

  • 软链接的路径可以是相对路径,建议用绝对路径避免问题
  • 软链接指向不存在的文件会变成"断链"
  • 硬链接不能对目录创建,防止目录树循环

三、网络基础类

Q11: TCP三次握手和四次挥手的过程能描述一下吗?为什么需要四次挥手?

三次握手(建立连接):

客户端                      服务端
   |                          |
   |------- SYN (seq=x) ----->|   客户端发送SYN,请求建立连接
   |                          |
   |<---- SYN-ACK (seq=y, ack=x+1) ----|  服务端发送SYN+ACK,同意连接
   |                          |
   |------- ACK (ack=y+1) --->|   客户端发送ACK,连接建立
   |                          |

为什么需要三次:

  • 第一次握手:客户端证明自己能发
  • 第二次握手:服务端证明自己能收也能发
  • 第三次握手:客户端确认服务端收到了自己的消息

四次挥手(关闭连接):

客户端                      服务端
   |                          |
   |------- FIN ----->        |   客户端发送FIN,请求关闭
   |<- ------ ACK ---------   |   服务端发送ACK,我先收到关闭请求
   |                          |
   |<----- FIN ------------   |   服务端处理完数据后发送FIN
   |------- ACK ------>       |   客户端发送ACK确认
   |                          |

为什么需要四次:

  • 第一次挥手:客户端说"我没数据要发了"
  • 第二次挥手:服务端说"我收到,但我可能还有数据要发给你,先别断开"
  • 第三次挥手:等服务端发完,发送FIN
  • 第四次挥手:客户端确认,服务端才能最终关闭

TIME_WAIT状态的意义:

  • 客户端发送最后一个ACK后进入TIME_WAIT(通常2MSL)
  • 防止最后这个ACK丢失,服务端超时重发FIN
  • 等待期间,本端口所有数据包都消失,不会影响新连接

Q12: TCP和UDP的核心区别是什么?各自适用什么场景?

核心区别:

特性TCPUDP
连接性面向连接无连接
可靠性可靠交付不可靠
传输方式字节流数据报
拥塞控制
首部开销20-60字节8字节
传输效率相对低

TCP保证可靠的方式:

  • 确认应答(ACK)机制
  • 超时重传
  • 序列号:解决乱序问题
  • 校验和:检测数据损坏
  • 流量控制(滑动窗口):避免发送过快
  • 拥塞控制:慢启动、拥塞避免、快速恢复

适用场景:

TCP适用:

  • HTTP/HTTPS(网页、API)
  • SSH远程登录
  • 文件传输(FTP、SFTP)
  • 邮件(SMTP、POP3、IMAP)
  • 数据库连接(MySQL、PostgreSQL)
  • 任何对数据可靠性有要求的场景

UDP适用:

  • DNS查询
  • 视频/音频流(直播、VoIP)
  • 在线游戏(对实时性要求高,能容忍少量丢包)
  • 实时通信(WebRTC)
  • 物联网MQTT(QoS模式可选)
  • DHCP(动态IP分配)

Q13: HTTP和HTTPS的区别是什么?HTTPS是如何保证安全的?

HTTP vs HTTPS核心区别:

特性HTTPHTTPS
端口80443
协议明文传输加密传输
验证身份不验证证书验证服务器身份
数据完整性不保证MAC校验保证不被篡改
隐私性裸奔加密

HTTPS如何保证安全(SSL/TLS握手过程):

  1. 客户端发起HTTPS请求,告诉服务器支持的TLS版本、加密套件列表、随机数A

  2. 服务器响应,发送证书(包含公钥)、选定的加密套件、随机数B

  3. 客户端验证证书,检查证书是否由可信CA签发、是否过期、域名是否匹配

  4. 客户端生成随机数C(Pre-Master Secret),用服务器公钥加密后发送

  5. 双方用随机数A、B、C计算会话密钥(对称加密密钥)

  6. 之后数据传输用会话密钥加密(对称加密,效率高)

为什么HTTPS用混合加密:

  • 非对称加密:用于密钥交换(传递Pre-Master Secret),安全性高但效率低
  • 对称加密:用于实际数据传输,效率高

证书验证的信任链:

Root CA(根证书机构)
    └── Intermediate CA(中间证书机构)
            └── Server Certificate(服务器证书)

Q14: 如果用户反映网站访问很慢,你如何排查网络问题?

分层排查思路:

第一步:确认问题范围

  • 是所有用户都慢,还是个别用户?
  • 是所有页面慢,还是特定功能慢?
  • 是首次访问慢,还是每次都慢?(可能是CDN/缓存问题)

第二步:本地网络排查

bash
# ping测试连通性和延迟
ping -c 10 www.example.com

# traceroute/tracepath查看路由路径和延迟
traceroute www.example.com
# Windows用 tracert

# 查看DNS解析是否正常
nslookup www.example.com
dig www.example.com

# 测试具体端口响应时间
curl -o /dev/null -s -w "DNS: %{time_namelookup}s, TCP: %{time_connect}s, TTFB: %{time_starttransfer}s, Total: %{time_total}s\n" https://www.example.com

第三步:应用层排查

  • F12打开浏览器开发者工具,看是哪个阶段慢:
    • DNS解析慢 → 检查DNS服务器配置
    • TCP连接慢 → 网络/防火墙问题
    • SSL握手慢 → 证书问题或服务器性能
    • 首字节时间(TTFB)慢 → 后端应用问题
    • 内容下载慢 → 带宽瓶颈或资源大

第四步:服务端排查

bash
# 查看服务器负载
uptime, top, vmstat

# 查看网络连接状态
netstat -an | grep :80 | wc -l   # 连接数是否过高
ss -s

# 查看应用日志
tail -f access.log
# 统计响应时间分布
awk '{print $NF}' access.log | sort | uniq -c | sort -rn

第五步:监控数据

  • 查看Zabbix/Prometheus等监控平台的历史数据
  • 带宽使用率、CPU、内存是否有异常
  • 是否有突发流量

Q15: 什么是ARP协议?它的工作原理是什么?

ARP(Address Resolution Protocol)地址解析协议:

作用: 在同一个局域网内,根据IP地址找到对应的MAC地址。

为什么需要ARP?

  • 网络层(IP)关注的是逻辑地址
  • 数据链路层(以太网)关注的是物理地址(MAC)
  • 发送数据时需要知道目标MAC地址,ARP就是干这个转换的

工作过程:

场景:主机A(192.168.1.10)想给主机B(192.168.1.20)发数据
但A只知道B的IP,不知道B的MAC

1. A查看自己的ARP缓存,有没有192.168.1.20的映射
   没有则继续

2. A广播ARP请求(广播地址FF:FF:FF:FF:FF:FF)
   "谁是192.168.1.20?我的MAC是AA:BB:CC:DD:EE:FF,我的IP是192.168.1.10"

3. 同一局域网内所有主机都收到这个广播
   只有B(192.168.1.20)会响应

4. B单播ARP响应给A
   "192.168.1.20的MAC是11:22:33:44:55:66"

5. A收到响应后:
   - 把映射存入ARP缓存
   - 开始发送数据

ARP缓存:

bash
# 查看ARP缓存
arp -a

# 手动添加静态ARP映射(防止ARP欺骗)
arp -s 192.168.1.20 11:22:33:44:55:66

# 删除
arp -d 192.168.1.20

ARP欺骗攻击:

  • 攻击者发送伪造的ARP响应,让目标把错误的MAC和IP对应起来
  • 可以实现中间人攻击(流量被劫持到攻击者机器)
  • 防御:静态ARP表、ARP防火墙、交换机端口安全

Q16: 负载均衡的常见算法有哪些?各有优缺点?

常见负载均衡算法:

1. 轮询(Round Robin)

  • 顺序分配给后端服务器,每台依次处理
  • 优点:简单、公平
  • 缺点:不考虑服务器实际负载,闲的忙的一视同仁

2. 加权轮询(Weighted Round Robin)

  • 按权重比例分配,性能强的多分担
  • 优点:可以手动调配
  • 缺点:权重固定,不够灵活

3. 最少连接(Least Connections)

  • 把请求发给当前连接数最少的服务器
  • 优点:动态适应,考虑了服务器负载
  • 缺点:需要维护连接数统计

4. IP Hash

  • 根据客户端IP计算hash值,映射到特定服务器
  • 优点:同一IP的请求会打到同一台服务器(会话保持)
  • 缺点:服务器扩缩容时hash重新分配,会话丢失

5. 随机(Random)

  • 随机选择一台服务器
  • 优点:简单
  • 缺点:负载分布不够均匀

6. 一致性哈希(Consistent Hash)

  • 改进的hash,服务器扩缩容时影响最小
  • 优点:适合分布式缓存场景
  • 缺点:实现相对复杂

实际选择:

  • HTTP服务通常用加权轮询或最少连接
  • 长连接场景(数据库、SSH)用IP Hash或最少连接
  • 分布式缓存用一致性哈希

四、Python/Shell脚本类

Q17: 用Python写一个脚本来自动检测服务器磁盘使用率,超过80%告警

python
#!/usr/bin/env python3
import subprocess
import re
import json
from datetime import datetime

def get_disk_usage():
    """获取所有磁盘分区的使用情况"""
    result = subprocess.run(['df', '-h'], capture_output=True, text=True)
    lines = result.stdout.strip().split('\n')
    
    alerts = []
    disks = []
    
    for line in lines[1:]:  # 跳过标题行
        parts = line.split()
        if len(parts) >= 6:
            filesystem, size, used, available, percent, mountpoint = parts
            
            # 跳过虚拟文件系统
            if filesystem.startswith('/dev') and percent:
                try:
                    usage = int(percent.rstrip('%'))
                    disk_info = {
                        'filesystem': filesystem,
                        'mountpoint': mountpoint,
                        'usage_percent': usage,
                        'available_gb': available
                    }
                    disks.append(disk_info)
                    
                    # 检查是否超过阈值
                    if usage >= 80:
                        alerts.append(disk_info)
                except ValueError:
                    continue
    
    return disks, alerts

def send_alert(alerts):
    """发送告警(这里打印,可扩展为邮件/钉钉/Webhook)"""
    if alerts:
        print(f"🚨 告警: 发现 {len(alerts)} 个磁盘使用率超过80%")
        for alert in alerts:
            print(f"   - {alert['mountpoint']}: {alert['usage_percent']}% (剩余 {alert['available_gb']})")
    else:
        print("✅ 所有磁盘使用率正常")

def main():
    print(f"[{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}] 开始磁盘检查...")
    
    disks, alerts = get_disk_usage()
    
    print(f"\n磁盘使用情况:")
    for disk in disks:
        print(f"   {disk['mountpoint']:30} {disk['usage_percent']:3}% {disk['available_gb']:>8} 可用")
    
    send_alert(alerts)

if __name__ == '__main__':
    main()

使用方式:

bash
# 直接运行
python3 disk_check.py

# 加入crontab定时执行
crontab -e
# 添加: */30 * * * * /usr/bin/python3 /opt/scripts/disk_check.py >> /var/log/disk_check.log 2>&1

Q18: 用Shell写一个日志分析脚本,统计Nginx access log中每分钟的请求量和TOP 10 IP

bash
#!/bin/bash
# nginx_log_analysis.sh - Nginx访问日志分析

LOG_FILE=${1:-"/var/log/nginx/access.log"}
LIMIT=${2:-10}

echo "============================================"
echo "Nginx 日志分析报告"
echo "分析文件: $LOG_FILE"
echo "分析时间: $(date '+%Y-%m-%d %H:%M:%S')"
echo "============================================"

# 检查文件是否存在
if [[ ! -f "$LOG_FILE" ]]; then
    echo "错误: 文件 $LOG_FILE 不存在"
    exit 1
fi

# 1. 总体统计
echo -e "\n【总体统计】"
total_requests=$(wc -l < "$LOG_FILE")
unique_ips=$(awk '{print $1}' "$LOG_FILE" | sort -u | wc -l)
echo "总请求数: $total_requests"
echo "独立IP数: $unique_ips"
echo "平均QPS: $(echo "scale=2; $total_requests / 60" | bc)"

# 2. 每分钟请求量
echo -e "\n【每分钟请求量 TOP 20】"
awk '{print $4}' "$LOG_FILE" | \
    cut -d':' -f1,2 | \
    sort | \
    uniq -c | \
    sort -rn | \
    head -20 | \
    while read count time; do
        printf "   %-30s %s 请求\n" "$time" "$count"
    done

# 3. TOP 10 访问IP
echo -e "\n【访问量 TOP $LIMIT IP】"
echo "   IP地址                      请求数"
echo "   ----------------------------------------"
awk '{print $1}' "$LOG_FILE" | \
    sort | \
    uniq -c | \
    sort -rn | \
    head -"$LIMIT" | \
    while read count ip; do
        # 获取IP归属地(如果有whois命令)
        location=$(whois "$ip" 2>/dev/null | grep -i "country\|netname" | head -1 | awk '{print $2}')
        if [[ -z "$location" ]]; then
            location="-"
        fi
        printf "   %-30s %-8s %s\n" "$ip" "$count" "$location"
    done

# 4. HTTP状态码统计
echo -e "\n【HTTP状态码统计】"
awk '{print $9}' "$LOG_FILE" | \
    sort | \
    uniq -c | \
    sort -rn | \
    while read count status; do
        case "$status" in
            2*) desc="成功" ;;
            3*) desc="重定向" ;;
            4*) desc="客户端错误" ;;
            5*) desc="服务器错误" ;;
            *) desc="其他" ;;
        esac
        printf "   %s %-8s %s\n" "$status" "$count" "$desc"
    done

# 5. 5xx错误请求详情
echo -e "\n【5xx错误请求(最近20条)】"
awk '$9 ~ /^5[0-9][0-9]$/ {print $4, $7, $9, $10}' "$LOG_FILE" | \
    tail -20 | \
    while read time url status bytes; do
        echo "   $time | $status | $url"
    done

echo -e "\n============================================"

Q19: Python中装饰器是什么?实际工作中用过哪些装饰器场景?

装饰器(Decorator)基础理解:

装饰器本质上是一个函数,它接收一个函数作为参数,返回一个新的函数。用于在不修改原函数的前提下,给函数增加额外的功能。

简单示例:

python
import functools
import time

def log_execution_time(func):
    """记录函数执行时间的装饰器"""
    @functools.wraps(func)  # 保留原函数元信息
    def wrapper(*args, **kwargs):
        start = time.time()
        result = func(*args, **kwargs)
        end = time.time()
        print(f"{func.__name__} 执行耗时: {end - start:.2f}秒")
        return result
    return wrapper

@log_execution_time
def fetch_data():
    # 模拟耗时操作
    time.sleep(1)
    return "data"

实际工作中常用的装饰器场景:

1. 缓存装饰器(避免重复计算):

python
from functools import lru_cache

@lru_cache(maxsize=128)
def get_config(key):
    # 从数据库或远程获取配置,可能很耗时
    return db.query(f"SELECT * FROM config WHERE key='{key}'")

2. 重试装饰器(网络请求容错):

python
import time
from functools import wraps

def retry(max_attempts=3, delay=1):
    def decorator(func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            for attempt in range(max_attempts):
                try:
                    return func(*args, **kwargs)
                except Exception as e:
                    if attempt == max_attempts - 1:
                        raise
                    time.sleep(delay)
            return None
        return wrapper
    return decorator

@retry(max_attempts=3, delay=2)
def call_api(url):
    return requests.get(url)

3. 日志装饰器(记录调用日志):

python
def log_call(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        logger.info(f"调用 {func.__name__}, 参数: {args}, {kwargs}")
        try:
            result = func(*args, **kwargs)
            logger.info(f"{func.__name__} 执行成功")
            return result
        except Exception as e:
            logger.error(f"{func.__name__} 执行失败: {e}")
            raise
    return wrapper

4. 权限校验装饰器:

python
def require_permission(permission):
    def decorator(func):
        @wraps(func)
        def wrapper(user, *args, **kwargs):
            if permission not in user.permissions:
                raise PermissionError(f"需要 {permission} 权限")
            return func(user, *args, **kwargs)
        return wrapper
    return decorator

@require_permission("admin")
def delete_user(user, user_id):
    # 删除用户逻辑
    pass

Q20: Python中进程、线程、协程的区别?在爬虫场景下如何选择?

核心区别回顾:

特性进程线程协程
资源占用独立内存共享内存共享线程
创建开销极小
GIL影响
适合场景CPU密集IO密集(需绕过GIL用多进程)高并发IO

爬虫场景分析:

爬虫本质上是IO密集型任务(网络请求等待),CPU消耗相对较小。

方案选择:

1. 多线程 + requests(简单但有GIL限制):

python
import requests
from concurrent.futures import ThreadPoolExecutor

with ThreadPoolExecutor(max_workers=10) as executor:
    futures = [executor.submit(fetch_url, url) for url in urls]
    results = [f.result() for f in futures]
  • 优点:简单,requests是同步阻塞的
  • 缺点:Python GIL限制同一时刻只能有一个线程真正执行

2. 多进程 + requests(可绑过GIL但开销大):

python
from multiprocessing import Pool

def fetch_url(url):
    return requests.get(url).text

with Pool(4) as p:
    results = p.map(fetch_url, urls)
  • 优点:绑过GIL,真正并行
  • 缺点:进程开销大,数据传递有序列化成本

3. asyncio + aiohttp(推荐,高效):

python
import asyncio
import aiohttp

async def fetch(session, url):
    async with session.get(url) as response:
        return await response.text()

async def main(urls):
    async with aiohttp.ClientSession() as session:
        tasks = [fetch(session, url) for url in urls]
        return await asyncio.gather(*tasks)

results = asyncio.run(main(urls))
  • 优点:单线程实现高并发,内存占用低,效率最高
  • 缺点:需要异步库支持,代码风格不同

4. 异步 + 多进程(极高性能):

python
# 用aiometer控制并发,asyncio + 多进程
import asyncio
import aiohttp
from multiprocessing import Pool

# 每进程一个事件循环,处理更多并发

爬虫场景选择建议:

  • 小规模(几百个URL):asyncio + aiohttp
  • 中等规模:asyncio + 适当增大并发
  • 大规模分布式:用Scrapy框架或Celery分布式任务

Q21: 如何用Python实现一个简单的端口扫描工具?

python
#!/usr/bin/env python3
import socket
import concurrent.futures
import argparse
from datetime import datetime

def scan_port(host, port, timeout=1):
    """扫描单个端口"""
    try:
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.settimeout(timeout)
        result = sock.connect_ex((host, port))
        sock.close()
        
        if result == 0:
            # 尝试获取服务banner
            try:
                banner = get_banner(host, port, timeout)
            except:
                banner = "Unknown"
            return port, True, banner
        return port, False, None
    except Exception:
        return port, False, None

def get_banner(host, port, timeout):
    """获取服务banner信息"""
    try:
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.settimeout(timeout)
        sock.connect((host, port))
        sock.send(b"HEAD / HTTP/1.0\r\n\r\n")
        banner = sock.recv(1024).decode('utf-8', errors='ignore').strip()
        sock.close()
        return banner[:80]
    except:
        return None

def scan_ports(host, ports, max_workers=50, timeout=1):
    """并发扫描多个端口"""
    open_ports = []
    
    print(f"开始扫描 {host},共 {len(ports)} 个端口...")
    print(f"-" * 60)
    
    with concurrent.futures.ThreadPoolExecutor(max_workers=max_workers) as executor:
        future_to_port = {executor.submit(scan_port, host, port, timeout): port 
                          for port in ports}
        
        for future in concurrent.futures.as_completed(future_to_port):
            port, is_open, banner = future.result()
            if is_open:
                open_ports.append((port, banner))
                print(f"[+] 端口 {port:5d} 开放 | {banner}")
    
    return open_ports

def main():
    parser = argparse.ArgumentParser(description='简单端口扫描器')
    parser.add_argument('host', help='目标主机')
    parser.add_argument('-p', '--ports', default='1-1000', 
                        help='端口范围,如 1-1000 或 80,443,8080')
    parser.add_argument('-t', '--timeout', type=float, default=1.0,
                        help='连接超时时间(秒)')
    parser.add_argument('-w', '--workers', type=int, default=50,
                        help='并发线程数')
    
    args = parser.parse_args()
    
    # 解析端口范围
    if '-' in args.ports:
        start, end = map(int, args.ports.split('-'))
        ports = range(start, end + 1)
    else:
        ports = [int(p) for p in args.ports.split(',')]
    
    print(f"\n扫描目标: {args.host}")
    print(f"端口范围: {args.ports}")
    print(f"开始时间: {datetime.now()}")
    print(f"\n{'=' * 60}")
    
    open_ports = scan_ports(args.host, ports, args.workers, args.timeout)
    
    print(f"\n{'=' * 60}")
    print(f"扫描完成!发现 {len(open_ports)} 个开放端口")
    
    # 常见服务端口汇总
    common_services = {
        21: "FTP", 22: "SSH", 23: "Telnet", 25: "SMTP",
        53: "DNS", 80: "HTTP", 110: "POP3", 143: "IMAP",
        443: "HTTPS", 3306: "MySQL", 3389: "RDP",
        5432: "PostgreSQL", 6379: "Redis", 8080: "HTTP-Proxy",
        8443: "HTTPS-Alt", 27017: "MongoDB"
    }
    
    if open_ports:
        print("\n【服务汇总】")
        for port, banner in sorted(open_ports):
            service = common_services.get(port, "Unknown")
            print(f"   {port:5d}/tcp  {service:15s}")
    
if __name__ == '__main__':
    main()

五、监控与日志类

Q22: Zabbix的工作原理是什么?有哪些核心组件?

Zabbix工作原理:

Zabbix是一个**主动拉取(Pull)**模式的监控系统,核心是Server周期性向Agent发起数据请求。

架构流程:

[被监控主机]                    [Zabbix Server]              [数据库]
     |                                |                            |
     |<---- 周期性请求指标数据 ----->|                            |
     |                                |                            |
     |---- 返回: CPU, 内存, 磁盘... ->|-- 存储数据 ---------------->|
     |                                |                            |
                                    [Web界面]                      |
                                        |                          |
                                        |<--- 查询/展示 ------------|

核心组件:

  1. Zabbix Server

    • 核心组件,负责数据收集、存储、告警判断
    • 配置监控项、触发器、动作
    • 支持主动/被动两种数据收集模式
  2. Zabbix Agent

    • 部署在被监控主机上
    • 主动收集本地数据(CPU、内存、磁盘、网络)
    • 支持自定义监控项(UserParameter)
  3. Zabbix Proxy

    • 用于分布式监控,减轻Server压力
    • 代理Server收集数据,统一上报
    • 适合跨机房、跨地域场景
  4. Zabbix Database

    • 存储所有配置和监控数据
    • 支持MySQL、PostgreSQL、Oracle等
    • 数据量大时需要分区表优化
  5. Zabbix Web(Frontend)

    • PHP开发的Web界面
    • 配置监控、管理主机、查看图表

主动模式 vs 被动模式:

  • 被动模式(默认):Server主动向Agent发起请求
  • 主动模式:Agent主动上报数据,减轻Server压力,适合大规模环境

Q23: Zabbix如何实现自定义监控项?请举例说明

方式一:UserParameter(用户参数)

在Zabbix Agent配置文件中定义自定义监控键值:

bash
# /etc/zabbix/zabbix_agentd.d/userparameter_mysql.conf
UserParameter=mysql.status[*],mysql -e "show global status where Variable_name='$1'" | awk '{print $$2}'
UserParameter=mysql.ping,mysqladmin ping | grep -c alive
UserParameter=nginx.active,/usr/bin/curl -s http://127.0.0.1/status | awk '/Active/ {print $3}'

然后在Zabbix Web界面添加监控项,键值填写 mysql.pingnginx.active

方式二:Shell脚本 + UserParameter

bash
# 定义检查脚本
cat > /etc/zabbix/scripts/check_url.sh << 'EOF'
#!/bin/bash
URL=$1
HTTP_CODE=$(curl -o /dev/null -s -w "%{http_code}" "$URL")
echo "$HTTP_CODE"
EOF

chmod +x /etc/zabbix/scripts/check_url.sh

# 配置UserParameter
echo "UserParameter=check.http.code[*],/etc/zabbix/scripts/check_url.sh $1" >> /etc/zabbix/zabbix_agentd.d/userparameter_http.conf

systemctl restart zabbix-agent

方式三:Zabbix Sender(主动推送)

在应用端直接发送数据给Server或Proxy:

bash
# 脚本执行后主动发送数据
./zabb_sender -z 192.168.1.100 -p 10051 -s "web-server-01" -k url.http.code -o 200

Python脚本示例(监控业务指标):

python
#!/usr/bin/env python3
import subprocess
import json

# 模拟业务逻辑:获取当前在线用户数
def get_online_users():
    result = subprocess.run(['redis-cli', 'scard', 'online_users'], 
                           capture_output=True, text=True)
    return int(result.stdout.strip())

# 获取队列长度
def get_queue_length():
    result = subprocess.run(['rabbitmqctl', 'list_queues', '-q', 'name', 'messages'], 
                           capture_output=True, text=True)
    lines = result.stdout.strip().split('\n')
    return sum(int(line.split()[1]) for line in lines if line)

if __name__ == '__main__':
    import sys
    
    if len(sys.argv) == 2:
        key = sys.argv[1]
        if key == 'online_users':
            print(get_online_users())
        elif key == 'queue_length':
            print(get_queue_length())

Zabbix前端配置:

  1. 创建主机
  2. 创建应用集(如"业务监控")
  3. 创建监控项,键值填写自定义的key
  4. 配置图形和触发器

Q24: Prometheus的数据模型是什么?Counter和Gauge有什么区别?

Prometheus数据模型:

Prometheus采用**时序数据库(TSDB)**存储数据,核心概念:

  • Metric(指标):指标名称,如 http_requests_total
  • Labels(标签):键值对,用于区分同一指标的不同维度,如 method="GET", status="200", instance="server1:9100"
  • Sample(样本):一个具体的数据点,包含时间戳和值

一个完整的时序:

http_requests_total{method="GET", status="200", instance="server1:9100"}
    1638230400  12345
    1638230460  12356
    1638230520  12370

四种指标类型:

1. Counter(计数器)

yaml
# 只增不减(除非重启重置)
# 适用:请求总数、错误总数、已发送字节数

http_requests_total{path="/api/users", method="POST"}
# 值:125678(从0开始累计到125678)

使用方式:通常配合 rate() 函数计算变化速率

# 计算每秒请求数
rate(http_requests_total[5m])

# 计算5分钟内错误总数
increase(http_requests_errors_total[5m])

2. Gauge(仪表盘)

yaml
# 可增可减
# 适用:当前内存使用量、当前在线人数、温度

node_memory_MemAvailable_bytes{instance="server1"}
# 值:16777216000(8GB可用)

# 当前温度
temperature{location="room1"}
# 值:23.5

使用方式:直接显示当前值

# 当前内存使用率
(node_memory_MemTotal_bytes - node_memory_MemAvailable_bytes) / node_memory_MemTotal_bytes * 100

3. Histogram(直方图)

yaml
# 统计分布,记录数据分布情况
# 自动计算分位数:p50, p90, p99

http_request_duration_seconds_bucket{le="0.1"}
http_request_duration_seconds_bucket{le="0.5"}
http_request_duration_seconds_bucket{le="1"}
http_request_duration_seconds_bucket{le="+Inf"}

使用方式:计算分位数

histogram_quantile(0.99, rate(http_request_duration_seconds_bucket[5m]))

4. Summary(摘要)

yaml
# 类似直方图,但服务端计算分位数
# 注意:无法跨标签聚合

# 不能用于rate(),因为是客户端计算好的

选择建议:

  • 累计递增的值用Counter(如请求数、订单数)
  • 有峰谷波动的值用Gauge(如内存、CPU、连接数)
  • 需要分位数分析用Histogram(如延迟分布)

Q25: ELK Stack的各组件作用是什么?日志收集的典型架构是怎样的?

ELK Stack组件:

组件全称作用
ElasticsearchES分布式搜索引擎,存储和检索日志
LogstashLS数据收集、过滤、转换、输出
Kibana-数据可视化、Web界面
Beats-轻量级数据采集器(Filebeat、Metricbeat等)

传统架构(Logstash中心化):

[日志文件] -> [Filebeat] -> [Logstash] -> [Elasticsearch] -> [Kibana]
                                    |
                                 [Redis/Kafka]  (可选缓冲)

优化架构(引入Kafka缓冲):

[日志文件] -> [Filebeat] -> [Kafka] -> [Logstash] -> [Elasticsearch] -> [Kibana]
                                                           |
                                                      [ES集群]

各组件详解:

Filebeat(轻量采集):

  • 部署在应用服务器上
  • 资源占用低,适合生产环境
  • 支持多种日志类型:nginx、apache、mysql、json、普通文本
  • 配置示例:
yaml
filebeat.inputs:
- type: log
  paths:
    - /var/log/nginx/access.log
  fields:
    service: nginx
    env: prod

output.kafka:
  hosts: ["kafka1:9092", "kafka2:9092"]
  topic: 'nginx-logs'

Logstash(数据处理):

  • 收集、过滤、格式化
  • 常用filter:grok(解析日志格式)、date(时间戳转换)、mutate(字段操作)、geoip(IP地理位置)
ruby
filter {
  grok {
    match => { "message" => '%{IP:client} %{USER:ident} %{USER:auth} \[%{HTTPDATE:timestamp}\] "%{WORD:method} %{URIPATHPARAM:request} HTTP/%{NUMBER:httpversion}" %{NUMBER:response:int} %{NUMBER:bytes:int}' }
  }
  date {
    match => [ "timestamp", "dd/MMM/yyyy:HH:mm:ss Z" ]
    target => "@timestamp"
  }
  geoip {
    source => "client"
  }
}

Elasticsearch(存储检索):

  • 分布式全文搜索引擎
  • 存储结构化的JSON文档
  • 支持复杂的聚合查询
  • 建议:生产环境至少3节点集群

Kibana(可视化):

  • 仪表盘设计
  • 日志搜索(Discover)
  • 时序可视化
  • 安全特性(X-Pack)

Q26: 如何用Prometheus监控Kubernetes集群?

Kubernetes监控方案:

1. kube-state-metrics

yaml
# 部署kube-state-metrics获取K8s对象状态
apiVersion: apps/v1
kind: Deployment
metadata:
  name: kube-state-metrics
spec:
  selector:
    matchLabels:
      k8s-app: kube-state-metrics
  template:
    spec:
      containers:
      - name: kube-state-metrics
        image: registry.k8s.io/kube-state-metrics/kube-state-metrics:v2.8.0

采集的指标:

  • kube_pod_status_phase - Pod状态
  • kube_deployment_spec_replicas - Deployment期望副本数
  • kube_node_status_condition - 节点状态

2. node-exporter(节点级监控)

yaml
# DaemonSet方式部署到每个节点
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: node-exporter
spec:
  selector:
    matchLabels:
      app: node-exporter
  template:
    spec:
      hostNetwork: true
      containers:
      - name: node-exporter
        image: prom/node-exporter:v1.6.0
        ports:
        - containerPort: 9100

3. cAdvisor(容器级监控) cAdvisor已经集成在Kubelet中,直接通过 kubelet:10255/metrics/cadvisor 暴露

4. Prometheus配置:

yaml
# prometheus.yml
scrape_configs:
  # Kubernetes API Server
  - job_name: 'kubernetes-apiservers'
    kubernetes_sd_configs:
    - role: endpoints
    scheme: https
    tls_config:
      ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
    bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token

  # node-exporter
  - job_name: 'kubernetes-nodes'
    kubernetes_sd_configs:
    - role: node
    relabel_configs:
    - source_labels: [__address__]
      regex: '(.*):10250'
      replacement: '${1}:9100'
      target_label: __address__

  # kube-state-metrics
  - job_name: 'kube-state-metrics'
    kubernetes_sd_configs:
    - role: service
    relabel_configs:
    - source_labels: [__meta_kubernetes_service_name]
      regex: kube-state-metrics
      action: keep

  # Pod指标
  - job_name: 'kubernetes-pods'
    kubernetes_sd_configs:
    - role: pod
    relabel_configs:
    - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]
      regex: "true"
      action: keep

关键监控指标:

# Pod CPU使用率
sum(rate(container_cpu_usage_seconds_total{pod!=""}[5m])) by (pod)

# Pod内存使用
container_memory_usage_bytes{pod!=""}

# Pod重启次数
kube_pod_container_status_restarts_total

# 集群总体CPU使用
sum(rate(container_cpu_usage_seconds_total[5m])) / sum(kube_node_status_allocatable_cpu_cores) * 100

# 不健康的Pod数量
sum(kube_pod_status_phase{phase=~"Pending|Unknown|Failed"})

六、AIOps与智能运维类

Q27: 什么是AIOps?它和传统运维有什么区别?

AIOps(Artificial Intelligence for IT Operations)智能运维:

AIOps是利用机器学习、大数据分析、自动化技术来分析运维数据(指标、日志、事件、链路),实现异常检测、根因分析、故障预测、自动化修复的运维新范式。

核心能力:

  • 异常检测:从海量告警中识别真正的故障
  • 根因分析:快速定位故障根因,而非只看到表象
  • 故障预测:提前发现潜在风险
  • 告警收敛:把成百上千条告警收敛成几个真正需要关注的事件

传统运维 vs AIOps:

维度传统运维AIOps
告警处理静态阈值,告警泛滥动态基线,智能收敛
故障定位人工翻日志,耗时自动关联分析,快速
故障发现被动响应,用户报障主动预测,提前处置
运维效率依赖专家经验数据驱动
扩展性人工难以扩展自动适应规模增长

新华三AIO 3.0的特点:

  • 基于AI大模型与知识图谱
  • 实现"故障诊断→根因分析→策略推荐"的智能闭环
  • 面向智算运维、云原生运维等新场景

我的理解: AIOps不是要"替代"运维人员,而是做运维人员的"超级助手"。把重复性的工作(告警分拣、日志初筛)交给AI,把需要判断和决策的工作留给人类。核心价值是提升效率、降低人为错误


Q28: AIOps中常见的异常检测算法有哪些?各自适用场景?

异常检测是AIOps的核心能力之一。

常用算法分类:

1. 基于统计的方法

Z-Score(标准分):

python
# 计算数据点偏离均值的程度
z_score = (x - mean) / std_dev
# |z_score| > 3 认为是异常

适用:数据近似正态分布的场景,如高斯噪声监控

EWMA(指数加权移动平均):

python
# 平滑处理,减少噪声影响
ewma = alpha * current_value + (1 - alpha) * previous_ewma
# 检测当前值是否偏离EWMA超过阈值

适用:周期性不明显的数据平滑处理

2. 基于机器学习的方法

孤立森林(Isolation Forest):

python
# 核心思想:异常点更容易被"孤立"(few and different)
# 无需定义正常边界,擅长高维数据
from sklearn.ensemble import IsolationForest

clf = IsolationForest(contamination=0.1)
clf.fit(train_data)
predictions = clf.predict(test_data)  # -1为异常,1为正常

适用:多维指标综合判断、告警收敛场景

Prophet(时序预测):

python
from prophet import Prophet

m = Prophet(daily_seasonality=True, yearly_seasonality=True)
m.fit(df)
forecast = m.predict(future)
# 置信区间外的点视为异常

适用:有明显周期性的业务指标(访问量、订单量)

LSTM自编码器:

python
# 学习正常模式,异常输入重构误差大
# 适合复杂非线性时序数据

适用:复杂的应用层指标监控

3. 算法选择建议

场景推荐算法
简单单维指标Z-Score、EWMA
有周期性的业务指标Prophet
多维指标综合判断孤立森林
复杂时序、异常隐蔽LSTM-AE
需要实时检测流式异常检测(如SkyWalking内置)

实际项目中的经验:

  • 通常不会只用一种算法,而是多算法融合
  • 静态阈值 + 动态基线结合
  • 算法结果 + 规则兜底(如重要服务掉线必须告警)
  • 持续调优,根据误报漏报情况优化参数

Q29: 如何设计一个AIOps异常检测方案?请描述思路

设计思路分五步:

第一步:明确监控对象和目标

需要先回答:

  • 要监控什么?(系统指标、应用指标、业务指标)
  • 异常的定义是什么?(响应慢、错误率高、流量突变...)
  • 检测到异常后要做什么?(告警、自动处理、记录)

第二步:数据采集与治理

python
# 数据源梳理
metrics = ["cpu_usage", "memory_usage", "disk_io", "network_in", "request_count", "error_rate", "latency_p99"]
logs = ["nginx_access", "application_error", "system_dmesg"]
traces = ["http_request", "rpc_call", "database_query"]

需要考虑:

  • 数据质量(完整性、准确性)
  • 数据量级(存储成本、计算资源)
  • 实时性要求(秒级、分钟级)

第三步:特征工程

python
# 常用特征
features = {
    "基础指标": ["cpu_usage", "memory_usage"],
    "聚合特征": ["avg_5m_cpu", "max_5m_cpu", "std_5m_cpu"],
    "变化率": ["cpu_diff", "cpu_diff_rate"],
    "组合特征": ["cpu_mem_ratio", "io_wait_percent"]
}

第四步:算法选择与训练

python
# 分层检测策略
def anomaly_detection(metrics):
    results = []
    
    # 1. 规则层:兜底重要规则
    if service_down:
        results.append({"type": "rule", "alert": True, "severity": "critical"})
    
    # 2. 静态阈值层:已知的合理范围
    if cpu_usage > 95:
        results.append({"type": "threshold", "alert": True})
    
    # 3. 动态基线层:基于历史学习
    if is_anomaly_dynamic(cpu_usage):
        results.append({"type": "dynamic", "alert": True})
    
    # 4. 多维关联层:综合判断
    if multi_dim_anomaly(metrics):
        results.append({"type": "correlation", "alert": True})
    
    return results

第五步:告警收敛与输出

python
# 告警收敛策略
class AlertCorrelator:
    def __init__(self):
        self.topology = load_topology()  # 服务拓扑关系
    
    def correlate(self, alerts):
        # 1. 时间窗口合并:5分钟内同一服务告警合并
        alerts = self.group_by_time(alerts, window='5m')
        
        # 2. 依赖关系分析:按拓扑确定根因告警
        root_alerts = self.find_root_causes(alerts, self.topology)
        
        # 3. 告警分级:影响范围大的优先
        prioritized = self.prioritize(root_alerts)
        
        return prioritized

关键指标:

  • 检测准确率 ≥ 95%
  • 误报率 ≤ 5%
  • 检测延迟 ≤ 1分钟

Q30: 什么是根因分析(RCA)?AIOps中如何实现自动化的根因定位?

根因分析(RCA - Root Cause Analysis):

根因分析是找出故障真正原因的过程,不是只处理表面现象。比如用户反映"APP打不开",传统做法是告诉用户"系统正常",AIOps要做的是找出是DNS问题、还是后端服务挂了、还是数据库响应慢。

传统RCA vs AIOps RCA:

传统方式AIOps方式
人工逐台排查日志自动关联多源数据
依赖专家经验数据驱动分析
耗时30分钟-数小时分钟级定位
经验难以传承知识沉淀为规则/模型

AIOps根因分析技术:

1. 基于拓扑的传播路径分析

用户报障:支付失败

   应用层告警:支付服务响应慢

   中间件告警:订单队列堆积

   数据库告警:主库CPU 100%

   【根因】数据库慢查询导致

2. 基于时序关联分析

python
# 找出告警发生时间最接近的异常指标
def find_correlated_anomalies(incident_time, window=10):
    anomalies = []
    for metric in all_metrics:
        metric_anomalies = get_anomalies(metric, incident_time, window)
        if metric_anomalies:
            # 计算时间相关性
            time_diff = abs(metric_anomalies.time - incident_time)
            anomalies.append({
                'metric': metric,
                'time_diff': time_diff,
                'severity': metric_anomalies.severity
            })
    
    # 按时间接近度和严重程度排序
    return sorted(anomalies, key=lambda x: (x['time_diff'], -x['severity']))

3. 知识图谱推理

python
# 构建运维知识图谱
knowledge_graph = {
    "database": {
        "depends_on": ["storage", "network"],
        "symptoms": ["slow_query", "connection_error"],
        "causes": ["disk_full", "memory_pressure", "lock_contention"]
    },
    "application": {
        "depends_on": ["database", "cache", "message_queue"],
        "symptoms": ["timeout", "error_rate_increase"],
        "causes": ["downstream_failure", "oom", "config_error"]
    }
}

4. 根因定位流程:

python
def root_cause_analysis(incident):
    # 步骤1:获取告警关联的指标和日志
    metrics = get_related_metrics(incident)
    logs = get_related_logs(incident)
    traces = get_related_traces(incident)
    
    # 步骤2:时序对齐,找出时间最早的异常
    aligned_data = align_by_time(metrics, logs, traces)
    earliest_anomaly = find_earliest(aligned_data)
    
    # 步骤3:拓扑回溯
    root_candidates = []
    current_node = earliest_anomaly.node
    for i in range(5):  # 最多回溯5层
        dependencies = get_dependencies(current_node)
        if dependencies:
            # 检查依赖节点是否有异常
            abnormal_deps = [d for d in dependencies if is_abnormal(d)]
            if abnormal_deps:
                # 选择最可能导致当前异常的依赖
                root = select_most_likely_cause(abnormal_deps, current_node)
                root_candidates.append(root)
                current_node = root
            else:
                break
        else:
            break
    
    # 步骤4:输出根因和推理路径
    return {
        'root_cause': root_candidates[-1] if root_candidates else earliest_anomaly,
        'reasoning_chain': root_candidates,
        'confidence': calculate_confidence(root_candidates)
    }

Q31: 新华三AIO 3.0产品的核心能力是什么?你对这个产品有了解吗?

新华三AIO 3.0核心能力:

根据公开资料,AIO 3.0是新华三一站式运维管理服务,核心升级包括:

1. AIOps智能运维

  • 基于AI大模型与知识图谱
  • 实现"故障诊断→根因分析→策略推荐"的智能闭环
  • 灵犀运维智能体:聚合23年ICT运维经验、1.2亿台在网设备运维积累、百万级案例知识库

2. 云原生运维左移

  • 面向云原生架构的运维能力重构
  • 贯穿软件全生命周期:需求设计→开发→测试→运维
  • DevOps流水线优化、基础设施即代码、K8S应用编排治理

3. 智算运维运营

  • 面向智算中心的运维挑战(GPU监控、算力集群)
  • 实时监测GPU健康状态、训练任务进度
  • 模型推理服务保障

4. 融合安全服务

  • SecOps一体化安全运营框架
  • "预测-防御-检测-响应-验证"闭环

5. 远程运维交付创新

  • "云地协同"模式
  • 7×24远程+现场协同运维

与浙江移动的合作背景: 浙江移动是新华三的重要客户,浙江移动网管中心在AIOps方面有深入实践:

  • 基于私有云的AIOps智能运维
  • 大模型运维机器人(典型故障诊断从30分钟缩短到5分钟)
  • "四智"维营体系:智能基建、智能运维、智能运营、智能服务

我的理解: 新华三AIO产品的核心价值在于将AI能力融入传统运维工具链,让运维从"被动响应"转向"主动预防"。灵犀运维智能体是比较有特色的能力,它通过知识图谱和大模型,让系统能"理解"运维知识,而不只是机械匹配规则。


Q32: 浙江移动在AIOps方面有哪些实践?你了解吗?

浙江移动AIOps实践:

1. 大模型运维机器人(与中兴合作)

  • 解决痛点:传统OMC网管系统繁杂、故障诊断耗时
  • 效果:典型故障诊断从30分钟缩短到5分钟,效率提升80%
  • 典型案例:SPN网络故障端到端处理周期缩短30%

2. "四智"维营体系

  • 智能基建:算液联动寻优、算电联动寻优,节能20%-25%
  • 智能运维:端到端全栈监控(算力-模型-应用),智算业务可用度99.9%+
  • 智能运营:资源动态调度,单业务资源利用率提升10%+
  • 智能服务:参数自主调优,较人工效率提升8倍

3. 核心网运维智能体

  • 四大智能体:投诉处置、故障处理、操作配置、故障抢通
  • 在浙江等10余个省份部署,效率提升60%
  • 核心网告警平均分析时长从1.5小时缩短至0.2小时

4. 自智网络建设

  • 联合华为、中兴等厂商推进网络智能化
  • 获得TMF催化剂最佳项目奖
  • 自智网络评分集团第一

我的理解: 浙江移动的AIOps实践有几个特点:

  1. 与业务深度结合,不只是技术层面的监控
  2. 大模型落地应用,不只是传统机器学习
  3. 全流程自动化,从发现问题到解决问题闭环

七、Docker与容器类

Q33: Docker和传统虚拟机的区别是什么?Docker的核心优势?

Docker vs 虚拟机:

维度虚拟机(VM)Docker容器
隔离级别硬件级隔离,完全独立操作系统级隔离,共享内核
资源占用大(每个VM要运行完整OS)小(共享宿主机内核)
启动时间分钟级秒级
镜像大小GB级MB级
性能有虚拟化损耗接近原生性能
可移植性需整个VM打包轻量易分发
规模支持数十台可轻松管理上千容器

Docker架构:

[Docker Client] <--REST API--> [Docker Daemon]
                                      |
                         [Containerd] --> [container]
                                      |
                               [runc] <-- [shim]

Docker核心优势:

1. 环境一致性(Build Once, Run Anywhere)

bash
# 开发环境构建
docker build -t myapp:1.0 .

# 生产环境运行,完全一致
docker run myapp:1.0

2. 资源隔离与限制

yaml
# docker-compose.yml
services:
  web:
    image: nginx
    deploy:
      resources:
        limits:
          cpus: '0.5'
          memory: 512M
        reservations:
          cpus: '0.25'
          memory: 256M

3. 快速弹性伸缩

bash
# 几秒内扩容到10个实例
docker-compose up -d --scale web=10

# K8s中更是秒级伸缩
kubectl scale deployment myapp --replicas=20

4. CI/CD集成友好

dockerfile
# 多阶段构建,减小镜像体积
FROM golang:1.21 AS builder
WORKDIR /app
COPY . .
RUN go build -o myapp

FROM alpine:latest
COPY --from=builder /app/myapp /usr/local/bin/
CMD ["myapp"]

Q34: Dockerfile的常见指令有哪些?请解释FROM、RUN、CMD、ENTRYPOINT的区别

Dockerfile常用指令:

dockerfile
# 1. FROM - 指定基础镜像
FROM python:3.11-slim
FROM nginx:alpine
FROM ubuntu:22.04

# 2. LABEL - 添加元数据
LABEL maintainer="chuchengzhi@example.com"
LABEL version="1.0"
LABEL description="My application"

# 3. RUN - 执行命令,创建新层
RUN apt-get update && apt-get install -y \
    curl \
    vim \
    git \
    && rm -rf /var/lib/apt/lists/*

# 4. COPY / ADD - 复制文件
COPY ./app /app/
COPY requirements.txt /app/
ADD archive.tar.gz /app/  # ADD支持URL和自动解压

# 5. WORKDIR - 设置工作目录
WORKDIR /app

# 6. ENV - 设置环境变量
ENV NODE_ENV=production
ENV PATH="/usr/local/bin:${PATH}"

# 7. EXPOSE - 声明端口(文档作用)
EXPOSE 8080 443

# 8. USER - 设置用户
USER nginx

# 9. VOLUME - 声明持久化目录
VOLUME ["/data", "/logs"]

# 10. ARG - 构建参数
ARG VERSION=1.0

CMD vs ENTRYPOINT 区别:

dockerfile
# CMD - 容器启动默认命令,可被docker run参数覆盖
FROM ubuntu
CMD ["echo", "hello"]           # docker run 会输出 "hello"
# docker run image echo "hi" 会输出 "hi",覆盖CMD

# ENTRYPOINT - 固定入口,参数作为追加
FROM ubuntu
ENTRYPOINT ["echo", "hello"]
# docker run 总是输出 "hello"
# docker run image "hi" 输出 "hello hi"

# 组合使用:ENTRYPOINT定义可执行程序,CMD传默认参数
FROM python:3.11
ENTRYPOINT ["python", "app.py"]
CMD ["--port", "8080"]  # 默认参数,可被覆盖

最佳实践:

dockerfile
# 使用多阶段构建减小镜像体积
FROM python:3.11-slim AS builder
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

FROM python:3.11-slim
WORKDIR /app
COPY --from=builder /usr/local/lib/python3.11/site-packages /usr/local/lib/python3.11/site-packages
COPY app /app/
CMD ["python", "app.py"]

Q35: Docker容器的网络模式有哪些?各自的适用场景?

Docker网络模式:

模式说明容器间通信与宿主机通信与外部通信
bridge默认模式,NAT网络✅ 通过IP✅ 通过NAT
host共享宿主机网络✅ 直接通信✅ 共享
container共享另一个容器网络
none无网络
overlayDocker Swarm跨主机网络
macvlan给容器分配MAC地址

bridge模式(默认):

bash
# 查看默认bridge网络
docker network inspect bridge

# 创建自定义bridge网络(推荐)
docker network create --driver bridge --subnet 172.20.0.0/16 mynet

# 容器加入自定义网络,可以直接用容器名通信
docker run --network mynet --name web nginx
docker run --network mynet --name db redis
# web容器可以直接 ping db

host模式:

bash
# 容器共享宿主机网络,端口直接暴露
docker run --network host nginx
# nginx直接监听宿主机的80端口

适用:对网络性能要求高、无需隔离的场景

自定义网络的好处:

bash
# 容器间可以用名字直接通信(DNS自动解析)
docker network create mynet

docker run -d --name app --network mynet myapp
docker run -d --name redis --network mynet redis

# app容器内可以直接连接 redis:6379

Q36: 如何排查Docker容器网络问题?

排查步骤:

1. 检查容器网络状态

bash
# 查看容器网络信息
docker inspect <container> --format='{{json .NetworkSettings}}' | jq

# 查看容器分配的IP
docker inspect -f '{{.NetworkSettings.IPAddress}}' <container>

# 查看网络列表
docker network ls

# 查看网络详情
docker network inspect bridge

2. 进入容器内部排查

bash
# 进入容器bash
docker exec -it <container> /bin/bash

# 容器内检查
ip addr          # 查看网络接口
ip route         # 查看路由
cat /etc/resolv.conf  # 检查DNS配置
ping <gateway>    # 测试网关连通性
curl <address>    # 测试网络请求

3. 检查宿主机网络

bash
# 查看docker0网桥
ip link show docker0
brctl show docker0  # 查看桥接的接口

# 查看iptables NAT规则
iptables -t nat -L -n
iptables -t filter -L -n

# 查看宿主机端口监听
netstat -tlnp | grep docker
ss -tlnp | grep docker

常见问题与解决方案:

问题1:容器无法访问外网

bash
# 检查宿主机是否可以访问外网
ping 8.8.8.8
ping www.baidu.com

# 检查NAT转发是否开启
cat /proc/sys/net/ipv4/ip_forward

# 如果没开,手动开启
sysctl -w net.ipv4.ip_forward=1

问题2:容器间无法通信

bash
# 确认容器在同一网络
docker inspect -f '{{.NetworkSettings.Networks}}' <container1>
docker inspect -f '{{.NetworkSettings.Networks}}' <container2>

# 如果不在同一网络,手动加入
docker network connect mynet <container>

问题3:容器无法解析域名

bash
# 检查DNS配置
docker exec <container> cat /etc/resolv.conf

# 启动时指定DNS
docker run --dns 8.8.8.8 --dns 114.114.114.114 <image>

问题4:端口映射不生效

bash
# 检查端口映射
docker port <container>

# 检查宿主机端口是否被占用
netstat -tlnp | grep <port>

# 重新映射端口
docker stop <container>
docker rm <container>
docker run -d -p 8080:80 nginx

Q37: Kubernetes的核心概念有哪些?Pod、Service、Deployment的区别?

Kubernetes核心架构:

[Master Node]                           [Worker Node 1]
┌─────────────┐                         ┌─────────────┐
│ API Server  │                         │   Kubelet    │
│ Scheduler   │──────────┐              │   Kube-Proxy │
│ etcd        │          │              │   Pod        │
│ Controller  │          │              │   Pod        │
└─────────────┘          │              └─────────────┘

                    [kubectl CLI]

核心概念对比:

概念作用类比
Pod最小调度单元,包含一个或多个容器Docker Compose中的一个服务组
Deployment管理Pod副本数、滚动更新应用部署配置
Service统一入口,负载均衡Nginx/负载均衡器
ReplicaSet维护Pod副本数副本控制器
StatefulSet有状态应用适合数据库等

Pod vs Deployment:

yaml
# Pod是最小单元,通常不直接创建
apiVersion: v1
kind: Pod
metadata:
  name: myapp-pod
spec:
  containers:
  - name: myapp
    image: myapp:1.0
    ports:
    - containerPort: 8080
yaml
# Deployment管理Pod,推荐方式
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp
spec:
  replicas: 3  # 保持3个Pod副本
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - name: myapp
        image: myapp:1.0
        ports:
        - containerPort: 8080

Service的作用:

Deployment创建的Pod IP是动态的,Service提供稳定的访问入口:

yaml
apiVersion: v1
kind: Service
metadata:
  name: myapp-svc
spec:
  selector:
    app: myapp        # 关联带有app=myapp标签的Pod
  ports:
  - protocol: TCP
    port: 80          # Service端口
    targetPort: 8080  # Pod容器端口
  type: ClusterIP     # ClusterIP/NodePort/LoadBalancer

访问方式:

bash
# ClusterIP:集群内部访问
# NodePort:通过<NodeIP>:<NodePort>访问
# LoadBalancer:云厂商负载均衡器
# ExternalName:CNAME别名

八、数据库与SQL类

Q38: MySQL的索引原理是什么?为什么索引能加快查询?

MySQL索引原理:

MySQL默认使用B+Tree作为索引数据结构。

B+Tree vs B-Tree:

B-TreeB+Tree(MySQL InnoDB)
所有节点都存储数据只有叶子节点存储数据
查找可能在非叶子节点就找到必须查到叶子节点
树高相对较高树高更矮,IO次数更少

B+Tree结构特点:

        [15]                    <- 索引页(非叶子节点)
        /   \
    [5,10]    [20,25]          <- 索引页
    / | \     / | \
  [1][5][10][15][20][25]      <- 叶子节点(数据页,链表连接)

为什么能加快查询:

  1. 减少IO次数:不用全表扫描,B+Tree高扇出(每个节点可存很多指针),3层B+Tree可存千万级数据
  2. 范围查询友好:叶子节点链表连接,便于范围扫描
  3. 查询稳定:所有查询都需要查到叶子节点,不会突然变慢

最左前缀原则:

sql
-- 联合索引 (name, age, city)
-- 可以命中索引的情况:
WHERE name = '张三'              -- ✅ 命中name
WHERE name = '张三' AND age = 25 -- ✅ 命中name, age
WHERE name = '张三' AND city = '杭州' -- ✅ 命中name(跳过age,city用不上)

-- 不能命中索引的情况:
WHERE age = 25                   -- ❌ 不命中(跳过了name)
WHERE city = '杭州'              -- ❌ 不命中

Q39: 什么是慢查询?如何排查和优化?

慢查询定义: MySQL中执行时间超过long_query_time阈值(默认1秒)的SQL语句。

排查步骤:

1. 开启慢查询日志

sql
-- 查看慢查询配置
SHOW VARIABLES LIKE 'slow_query%';
SHOW VARIABLES LIKE 'long_query_time';

-- 开启慢查询日志
SET GLOBAL slow_query_log = 'ON';
SET GLOBAL long_query_time = 0.5;  -- 设为0.5秒

-- 设置日志文件位置
SET GLOBAL slow_query_log_file = '/var/log/mysql/slow.log';

2. 分析慢查询日志

bash
# 使用mysqldumpslow工具分析
mysqldumpslow -t 10 /var/log/mysql/slow.log    # Top 10最慢的SQL
mysqldumpslow -s c -t 5 /var/log/mysql/slow.log  # 按次数排序Top 5
mysqldumpslow -s r -t 10 /var/log/mysql/slow.log # 按返回行数排序

# 使用pt-query-digest(更强大)
pt-query-digest /var/log/mysql/slow.log

3. EXPLAIN分析执行计划

sql
EXPLAIN SELECT * FROM orders WHERE user_id = 123 AND status = 'paid' ORDER BY create_time DESC;

-- 查看结果解读:
-- type: 查询类型(const > eq_ref > ref > range > index > ALL)
-- key: 实际使用的索引
-- rows: 预计扫描行数
-- Extra: 额外信息(Using filesort/Using index等)

常见优化手段:

1. 优化索引

sql
-- 添加合适的索引
CREATE INDEX idx_orders_user_status ON orders(user_id, status, create_time DESC);

-- 删除冗余索引
ALTER TABLE orders DROP INDEX idx_user;

2. 优化SQL写法

sql
-- ❌ 避免
SELECT * FROM orders WHERE TO_DAYS(NOW()) - TO_DAYS(create_time) < 7;

-- ✅ 使用
SELECT * FROM orders WHERE create_time >= DATE_SUB(NOW(), INTERVAL 7 DAY);

-- ❌ 避免隐式类型转换
SELECT * FROM users WHERE phone = 13800138000;  -- phone是varchar

-- ✅ 使用
SELECT * FROM users WHERE phone = '13800138000';

3. 分页优化

sql
-- ❌ 低效的分页
SELECT * FROM logs ORDER BY id DESC LIMIT 100000, 20;

-- ✅ 优化方式1:基于ID
SELECT * FROM logs WHERE id < last_id ORDER BY id DESC LIMIT 20;

-- ✅ 优化方式2:延迟关联
SELECT l.* FROM logs l 
INNER JOIN (SELECT id FROM logs ORDER BY id DESC LIMIT 100000, 20) AS t 
ON l.id = t.id;

4. 表结构优化

  • 适当分表(按时间、按业务)
  • 读写分离
  • 使用合适的字段类型

Q40: SQL中IN和EXISTS的区别是什么?什么时候用哪个?

核心区别:

场景INEXISTS
原理先查子查询,结果集与外层比较对外层每一行,检查子查询是否有匹配
子查询表大小子查询结果集小效率高外层结果集小效率高
NULL处理IN (NULL) 结果为空EXISTS (NULL) 视情况
执行顺序先执行子查询外层驱动内层

示例对比:

sql
-- 场景:查询已下过订单的用户

-- IN:子查询先执行,得到所有下单用户ID,再匹配
SELECT * FROM users 
WHERE user_id IN (SELECT user_id FROM orders);

-- EXISTS:外层逐行扫描,对每行检查是否有订单
SELECT * FROM users u
WHERE EXISTS (SELECT 1 FROM orders o WHERE o.user_id = u.user_id);

-- 两者结果相同,但执行效率不同

选择建议:

用IN的情况:

sql
-- 1. 子查询结果集小、稳定
SELECT * FROM products 
WHERE category_id IN (1, 2, 3);  -- 常量列表,很小

-- 2. 子查询是单值列表,不涉及关联
SELECT * FROM logs 
WHERE level IN ('ERROR', 'WARN');

用EXISTS的情况:

sql
-- 1. 需要关联判断(相关子查询)
SELECT u.* FROM users u
WHERE EXISTS (
    SELECT 1 FROM orders o 
    WHERE o.user_id = u.user_id 
    AND o.amount > 1000
);

-- 2. 外层结果集小,子查询大
SELECT * FROM vip_users  -- 假设只有100条
WHERE EXISTS (
    SELECT 1 FROM all_logs  -- 假设有1亿条
    WHERE logs.user_id = vip_users.id
);

MySQL优化器行为:

  • MySQL会自动优化,大多数情况下性能差不多
  • 当有索引时,IN会被优化为EXISTS的等价形式
  • 复杂场景可以用EXPLAIN查看实际执行计划

Q41: Redis的数据结构有哪些?各自适用什么场景?

Redis 8种数据结构:

数据结构命令示例适用场景
StringGET/SET/MGET缓存、计数器、分布式锁
HashHSET/HGET/HGETALL对象存储、购物车
ListLPUSH/RPOP/LRANGE消息队列、任务队列、最新列表
SetSADD/SMEMBERS/SINTER标签系统、共同好友、UV统计
ZSetZADD/ZRANGE排行榜、延时队列
BitmapSETBIT/GETBIT签到、在线状态
HyperLogLogPFADD/PFCOUNT独立用户数统计
GEOGEOADD/GEORADIUS附近的人、LBS

实战场景示例:

1. 分布式锁

python
import redis

r = redis.Redis()

def acquire_lock(lock_name, timeout=10):
    """获取锁,返回True/False"""
    result = r.set(f"lock:{lock_name}", "1", nx=True, ex=timeout)
    return result

def release_lock(lock_name):
    """释放锁"""
    r.delete(f"lock:{lock_name}")

2. 缓存 + 缓存更新

python
def get_user(user_id):
    # 先查Redis缓存
    user = r.get(f"user:{user_id}")
    if user:
        return json.loads(user)
    
    # 缓存不存在,查数据库
    user = db.query(f"SELECT * FROM users WHERE id = {user_id}")
    
    # 写入缓存,设置过期时间
    r.setex(f"user:{user_id}", 3600, json.dumps(user))
    return user

3. 排行榜

python
# 增加用户积分
r.zadd("ranking", {"user_001": 100, "user_002": 200})

# 获取Top 10
top10 = r.zrevrange("ranking", 0, 9, withscores=True)

# 获取用户排名
rank = r.zrevrank("ranking", "user_001") + 1

4. 消息队列

python
# 生产者
r.lpush("task_queue", json.dumps({"task": "send_email", "to": "user@example.com"}))

# 消费者(阻塞)
while True:
    task = r.brpop("task_queue", timeout=0)  # 阻塞等待
    if task:
        execute_task(json.loads(task[1]))

九、场景题

Q42: 客户打电话说系统很慢,访问不了,你怎么快速定位问题?

快速定位思路(5分钟定位法):

第一步:确认范围(1分钟)

  • 问清是所有用户都慢,还是个别用户慢
  • 是所有功能慢,还是某个功能慢
  • 是突然变慢,还是一直慢

第二步:检查基础设施(2分钟)

bash
# 1. 检查服务器是否存活
ping <server_ip>

# 2. 检查端口是否可达
telnet <server_ip> 80

# 3. 检查资源使用
uptime
df -h
free -h

# 4. 快速查看错误日志
tail -50 /var/log/nginx/error.log
tail -50 /var/log/application/error.log

第三步:检查应用层(1分钟)

bash
# 查看应用进程状态
ps aux | grep java/python/node

# 检查进程数、连接数
netstat -an | grep :80 | wc -l

# 检查慢查询(如果是数据库问题)
SHOW FULL PROCESSLIST;

第四步:查看监控(1分钟)

  • 打开Zabbix/Grafana仪表盘
  • 看CPU、内存、IO、网络是否有异常
  • 看QPS、响应时间是否飙升
  • 看是否有大量错误日志

常见原因快速判断:

症状可能原因快速验证
ping不通网络/防火墙让运维检查网络
端口可达但超时后端服务挂了检查进程
CPU 100%代码死循环/GCjstack/top定位
内存爆满内存泄漏jmap看对象
磁盘100%日志堆积du -h找大文件
响应超时数据库慢/下游服务慢查慢查询/链路追踪
大量500错误代码bug查错误日志

应急处理:

  1. 先止血(重启服务、切换流量)
  2. 再排查根因
  3. 最后复盘预防

Q43: 半夜收到服务器告警CPU 100%,作为值班人员你如何处理?

处理流程:

第一步:确认告警(30秒)

  • 查看告警详情,确认是否真实
  • 确认影响范围:是否影响业务

第二步:快速止血(2分钟)

bash
# 1. 快速定位是哪个进程
top -c   # 按CPU排序,看%CPU高的进程

# 如果是Java进程
jps -l
ps aux | grep java | awk '{print $2}' | xargs -I {} top -b -n 1 -p {}

# 如果能判断是高负载进程,可以先kill(但要记录进程信息)
kill -STOP <pid>    # 先暂停(不是终止)

第三步:分析原因(5分钟)

bash
# 抓取CPU高时的堆栈信息
jstack <pid> > /tmp/jstack_$(date +%s).log

# 查看GC情况
jstat -gc <pid> 1000 10

# 如果是Python
ps aux | grep python
# 查看具体线程
ps -T -p <pid>

# 查看IO情况(可能是IO等待导致的CPU高)
iostat -x 1 5

第四步:定位根因

常见原因:

  • 死循环:某个请求处理逻辑有bug,循环处理
  • GC频繁:内存分配不合理,频繁Minor GC/Full GC
  • 正则回溯:复杂正则表达式导致CPU飙高
  • 加密/解密:大量加解密操作
  • 序列化:大对象序列化

第五步:处理

bash
# 如果确定是高负载进程的业务问题
# 方案1:重启应用(最快)
systemctl restart <service>

# 方案2:如果有集群,摘除故障节点
kubectl cordon <node>
kubectl delete pod <pod>

# 方案3:如果是外部调用导致,临时熔断
# 具体看应用配置

第六步:善后

bash
# 1. 确认服务恢复正常
curl -I http://service/health

# 2. 收集证据
jstack <pid> > /tmp/jstack_after.log
jstat -gc <pid> > /tmp/gc_stat.log

# 3. 通知相关人
# 4. 记录故障处理过程

预防措施:

  • 检查监控是否有异常趋势
  • 考虑增加CPU告警阈值或自动化处理
  • 后续做根因分析,避免再次发生

Q44: 如果你负责的多个任务同时到期,时间冲突,你怎么处理优先级?

优先级处理原则:

确定优先级维度:

  1. 业务影响:影响多少用户、什么级别的用户
  2. 紧急程度:业务中断还是可延迟
  3. 依赖关系:是否阻塞其他任务
  4. 完成时间窗口:各任务的时间要求

处理策略:

立即评估(5分钟):

┌─────────────────────────────────────────────────────┐
│  任务A:客户报告P0故障,系统无法下单               │
│  任务B:领导要求的周报,明天下班前                 │
│  任务C:监控告警配置优化,周五前完成               │
└─────────────────────────────────────────────────────┘

优先级排序:任务A > 任务B > 任务C

具体行动:

1. P0故障 - 立即处理

  • 暂停其他非紧急任务
  • 全力解决故障
  • 30分钟内给出临时方案

2. 评估任务B(周报)

  • 如果周报涉及故障汇报,合并处理
  • 如果是常规汇报,与领导沟通延期
  • 评估是否可以快速完成

3. 任务C(告警优化)

  • 与任务A无冲突,可以继续
  • 如果需要等待其他人配合,先推进其他工作

沟通协调:

python
# 与相关方沟通的要点:

# 1. 向领导说明情况
"""
领导,当前有两个紧急任务:
1. 客户系统故障(必须立即处理,影响业务)
2. 周报(明天下班前)

我的建议:故障优先处理,预计2小时内解决。
周报我今晚加班完成,或者能否延期到后天上午?
"""

# 2. 向协作方说明
"""
XX,我们这边遇到紧急故障需要优先处理。
你说的XXX任务,我会在XX时间继续推进。
"""

# 3. 任务拆分
"""
任务B周报可以这样拆分:
- 今日完成:数据统计(1小时)
- 明日完成:分析撰写(1小时)
这样今晚故障处理完,明天上午就能完成周报
"""

多任务并行技巧:

  • 机械性任务利用碎片时间
  • 等待结果时可以处理其他工作
  • 与其他人协作的任务优先处理(不阻塞别人)

Q45: 客户现场发现一个偶发的故障,不好复现,你怎么排查?

偶发故障排查策略:

问题特点:

  • 发生频率低,可能几小时/几天才出现一次
  • 现场可能已经恢复,无法直接观测
  • 原因可能隐藏在日志、监控数据中

排查步骤:

1. 信息收集

python
# 向现场人员了解:
"""
- 故障发生的确切时间?
- 持续了多久?
- 影响范围多大?
- 操作了什么导致的?/ 什么都没做就出现了?
- 之前有没有类似的故障?
- 最近有没有发布、变更?
"""

2. 历史数据回溯

bash
# 查看监控数据
# 故障时间点前后是否有异常指标
# Zabbix/Grafana查看CPU、内存、网络、应用的曲线

# 查看日志
grep "2024-01-15 14:3[0-9]" /var/log/app/error.log

# 查看应用日志中的ERROR/WARN
awk '/2024-01-15 14:3/ && /ERROR/' /var/log/app/application.log

3. 建立假设

常见的偶发原因假设:

python
assumptions = [
    "并发竞争条件(race condition)",
    "资源竞争(连接池、线程池耗尽)",
    "缓存穿透/击穿",
    "第三方服务超时/抖动",
    "定时任务并发执行",
    "数据库慢查询积累",
    "网络抖动丢包",
    "内存泄漏导致OOM",
    "日志文件过大导致磁盘满"
]

4. 增加观测

yaml
# 在代码中增加详细日志
try:
    result = process_request()
    logger.info(f"请求处理成功,耗时{result.duration}ms")
except Exception as e:
    # 偶发问题要打详细日志
    logger.error(f"请求处理失败: {e}, "
                  f"请求参数={params}, "
                  f"当前线程={threading.current_thread().name}, "
                  f"连接池状态={pool.status()}, "
                  f"内存使用={psutil.virtual_memory().percent}%")

# 增加监控埋点
metrics.increment("request.error", tags={"reason": "timeout"})
metrics.gauge("connection.pool.used", pool.used_count)

5. 复现尝试

python
# 方案1:增加日志,等待下一次发生
# 优点:改动小
# 缺点:等待时间长

# 方案2:压测复现
import locust
# 模拟高并发场景,看是否能触发

# 方案3:代码审查
# 审查可能的并发问题:
# - 全局变量修改
# - 非线程安全的集合
# - 共享资源未加锁

# 方案4:混沌实验
# 模拟网络抖动、超时等场景

6. 长期方案

python
# 1. 增加链路追踪
from jaeger_client import JaegerTracer
tracer = JaegerTracer(config=Config(...))
with tracer.start_span('operation') as span:
    span.log_event('error', payload={'detail': str(e)})

# 2. 增加异常监控告警
# 即使恢复也要告警,方便事后回溯

# 3. 录屏/日志落盘
# 关键操作增加详细日志,异步写入不丢失

十、新华三与AIO产品认知类

Q46: 你为什么想加入新华三?对AIO产品有什么期待?

回答要点:

我对新华三的兴趣点:

  1. 行业地位与积累

    • 新华三是国内ICT领域的头部厂商
    • 23年运维经验、1.2亿台在网设备积累
    • 百万级运维案例知识库
    • 这些是难以复制的优势
  2. AIOps方向契合我的职业规划

    • 我之前做的是传统运维,现在想往智能运维方向发展
    • AIOps是运维领域的重要趋势,新华三在这个领域有深厚积累
    • 灵犀运维智能体等产品很有技术含量
  3. 浙江移动项目机会

    • 浙江移动是国内AIOps实践的标杆客户
    • 能参与这样的项目,对技术成长很有帮助
    • 有机会接触大模型在运维领域的实际应用

我对AIO产品的期待:

  1. 技术深度:希望深入了解AIOps的核心技术(知识图谱、大模型应用)
  2. 业务广度:了解不同行业的运维场景和解决方案
  3. 项目交付能力:提升大型项目的交付和实施能力

我的优势:

  • 有一定的监控平台建设经验
  • 熟悉Zabbix、Prometheus、ELK等主流工具
  • 有Shell/Python脚本能力
  • 有项目交付和客户沟通经验

Q47: 你对智能运维行业未来发展趋势怎么看?

发展趋势分析:

1. 大模型深度赋能

  • 从"小模型+规则"到"大模型+知识图谱"
  • 运维场景的LLM应用(故障诊断问答、运维脚本生成)
  • 多Agent协同(投诉处置、故障处理等智能体分工协作)

2. 自智网络加速演进

  • 中国移动目标2025年实现L4级自智网络
  • 浙江移动已在多个场景达到L4
  • 运营商是AIOps落地的重要场景

3. 智算运维成为新战场

  • 大模型训练/推理需要GPU集群运维
  • 算力运维、模型运维是新增需求
  • 新华三AIO 3.0也在布局这个方向

4. 云原生与AIOps融合

  • 容器化、微服务化带来新的可观测性需求
  • 服务网格带来的运维复杂度增加
  • 需要更智能的链路追踪和根因分析

5. 可观测性标准统一

  • OpenTelemetry成为事实标准
  • Metrics、Logs、Traces统一采集和分析
  • 降低多源数据整合的复杂度

我认为的机会:

  • 掌握AIOps核心技术栈(机器学习、大数据、自动化)
  • 深入理解业务场景(运营商、金融等行业的运维痛点)
  • 具备项目交付和客户沟通能力

Q48: 如果让你负责一个AIOps项目的交付,你会如何规划?

项目交付规划框架:

第一阶段:需求调研与方案设计(1-2周)

python
# 交付规划
phase1 = {
    "目标": "深入了解客户痛点,制定落地可行方案",
    "工作内容": [
        "现状调研:现有监控体系、IT架构、运维流程",
        "痛点收集:与一线运维人员访谈",
        "数据摸底:评估数据质量和完整性",
        "方案设计:监控补强→数据治理→智能分析→自动化闭环"
    ],
    "产出": [
        "现状调研报告",
        "客户痛点分析",
        "AIOps落地规划方案"
    ]
}

第二阶段:数据采集与治理(2-4周)

python
# 工作内容
phase2 = {
    "监控采集": [
        "主机/网络/存储基础监控",
        "应用埋点/链路追踪",
        "日志规范化采集"
    ],
    "数据治理": [
        "CMDB数据治理",
        "告警数据清洗",
        "历史故障梳理"
    ],
    "验收标准": "数据完整率>95%,采集延迟<1分钟"
}

第三阶段:智能分析能力建设(4-8周)

python
# 分层建设
phase3 = {
    "基础层": [
        "告警收敛",
        "基础异常检测",
        "运维知识库建设"
    ],
    "进阶层": [
        "根因分析",
        "趋势预测",
        "健康度评估"
    ],
    "高级层": [
        "大模型问答",
        "自动故障修复",
        "智能运维助手"
    ]
}

第四阶段:试点与优化(2-4周)

python
phase4 = {
    "试点范围": "选择1-2个核心系统试点",
    "验证指标": [
        "告警数量下降>50%",
        "故障定位时间缩短>30%",
        "MTTR下降>20%"
    ],
    "优化迭代": "根据实际效果调整算法和策略"
}

第五阶段:推广与培训(2-4周)

python
phase5 = {
    "全量推广": "推广到所有重要系统",
    "用户培训": [
        "平台使用培训",
        "新功能讲解",
        "案例分享"
    ],
    "文档交付": [
        "运维手册",
        "应急操作指南",
        "常见问题FAQ"
    ]
}

关键成功因素:

  • 客户高层支持
  • 数据质量是基础
  • 场景选择要务实(先简单场景再复杂)
  • 持续运营比一次性交付更重要

十一、HR与软素质类

Q49: 你的职业规划是什么?

回答建议:

短期规划(1-2年):

  • 深入学习AIOps核心技术
  • 掌握新华三AIO产品的使用和定制
  • 在项目中积累智能运维实践经验
  • 目标是成为能独当一面的运维专家

中期规划(3-5年):

  • 深入1-2个行业(运营商、金融等)
  • 具备大型项目的交付能力
  • 参与产品优化或解决方案设计
  • 目标:成为既懂技术又懂业务的复合型人才

长期规划:

  • 持续关注AIOps行业趋势
  • 沉淀方法论,形成自己的知识体系
  • 可能考虑技术管理或架构方向

表达要点:

  • 规划要与岗位契合
  • 体现学习意愿和成长性
  • 不要太虚,要有具体方向

Q50: 你如何看待加班?你能接受加班吗?

回答建议:

我的态度:

  • 运维工作有其特殊性,突发事件需要及时响应
  • 在紧急情况下(故障处理、重大保障),加班是职责所在
  • 不排斥必要的加班,但更关注效率

区分加班类型:

python
# 合理的加班:
- 生产故障需要处理
- 重大活动保障期间
- 项目关键里程碑

# 需要改进的加班:
- 日常工作低效导致的加班
- 无意义的"卷"
- 流程问题导致的重复劳动

我的做法:

  • 优先提升自己的工作效率
  • 推动自动化,减少重复性工作
  • 做好时间管理,尽量减少无效加班
  • 但该顶上的时候绝不推脱

Q51: 你在团队中通常扮演什么角色?如何与同事协作?

回答建议:

我的团队角色:

  • 通常是技术骨干的角色
  • 负责技术方案设计和核心代码开发
  • 也承担知识分享的工作,带新人

协作方式:

python
# 与同事协作的原则:

# 1. 技术沟通要清晰
"""
讲清楚技术方案的选择理由
充分听取不同意见
用数据和逻辑说服,而非职位
"""

# 2. 主动沟通
"""
遇到问题及时同步,不闷头自己扛
定期和团队同步进展
有问题早发现早处理
"""

# 3. 文档化
"""
代码写注释
方案留文档
故障后写复盘报告
"""

# 4. 帮助他人
"""
不吝啬分享经验
遇到问题愿意协助排查
团队成功才是真的成功
"""

与客户协作:

  • 理解客户业务目标和痛点
  • 用客户能理解的语言解释技术问题
  • 超出预期交付,建立信任

Q52: 你有什么问题想问我吗?

可以问的问题:

1. 关于团队和项目:

- 这个岗位日常工作会涉及哪些系统和技术栈?
- 浙江移动AIO项目的规模和目前的进展阶段?
- 团队的技术氛围怎么样?有没有技术分享?

2. 关于成长机会:

- 公司对这个岗位的期望是什么?未来一年的成长路径?
- 有没有外部培训、技术认证的机会?
- 能参与什么样的项目或客户?

3. 关于面试结果:

- 面试结果大概什么时候能确定?
- 后续还有几轮面试?

4. 关于工作环境:

- 日常是驻场还是需要出差?
- 工作时间弹性如何?

避免问的问题:

  • 薪资待遇(等HR主动谈)
  • 能不能摸鱼
  • 公司八卦

附:面试注意事项

面试前准备

markdown
1. 提前30分钟进入会议
2. 测试好网络、摄像头、麦克风
3. 准备简历和项目资料(电子版)
4. 关闭不必要的应用和通知
5. 找一个安静、光线好的环境

面试中技巧

markdown
1. 回答问题先说结论,再展开解释
2. 不懂的问题不要瞎猜,坦诚说"这个我不太确定"
3. 遇到场景题可以用STAR法则(Situation-Task-Action-Result)
4. 适当反问和互动
5. 保持自信但不傲慢

项目描述技巧

markdown
# 使用STAR法则:
Situation(背景):项目是什么?业务场景?
Task(任务):你的职责是什么?
Action(行动):你具体做了什么?
Result(结果):取得了什么成果?

# 示例:
"我参与了一个运营商监控平台建设项目(S),
我负责告警收敛模块的设计和开发(T),
通过建立告警关联规则和拓扑分析,将告警数量减少了70%(A),
项目上线后客户反馈很好,提升了运维效率(R)"

祝面试顺利! 🚀


十二、补充技术问题

Q53: 什么是Prometheus的联邦集群?如何配置?

联邦集群(Federation)应用场景:

当单机Prometheus无法满足大规模监控需求时,可以用联邦集群将监控数据聚合。

典型架构:

[Global Prometheus] <--抓取--> [Federation]
                                  |
              ┌───────────────────┴───────────────────┐
              |                   |                   |
    [Asia Prometheus]   [Europe Prometheus]  [America Prometheus]

配置示例:

yaml
# global Prometheus配置
scrape_configs:
  - job_name: 'federate'
    honor_labels: true
    metrics_path: '/federate'
    params:
      'match[]':
        - '{job="kubernetes-nodes"}'
    static_configs:
      - targets:
        - 'asia-prometheus:9090'

适用场景:

  • 多机房/多集群监控数据汇总
  • 按地域或业务隔离监控数据

Q54: Kafka的工作原理是什么?为什么适合做日志收集的缓冲?

Kafka核心概念:

概念说明
Producer消息生产者
Consumer消息消费者
Topic消息主题
Partition分区
Consumer Group消费者组

为什么适合日志收集:

  • 高吞吐量:每秒处理百万级消息
  • 持久化:消息写入磁盘,不会丢失
  • 解耦:Producer和Consumer解耦
  • 削峰填谷:日志突增时Kafka缓冲消息

Q55: 什么是CMDB?它在运维中的作用是什么?

CMDB(Configuration Management Database)配置管理数据库:

核心作用:

  • 记录IT资产的配置信息
  • 建立服务之间的依赖关系
  • 是运维自动化的数据基础

典型数据模型:

  • 主机/服务器信息
  • 应用/服务信息
  • 依赖关系

在告警收敛中的应用: 利用CMDB拓扑关系做告警关联,将多个相关告警收敛为一条根因告警。


Q56: 你用过哪些Ansible模块?请举例说明

常用Ansible模块:

yaml
# 复制文件
- name: 复制配置文件
  copy:
    src: ./nginx.conf
    dest: /etc/nginx/nginx.conf
    backup: yes

# 软件包管理
- name: 安装软件
  yum:
    name:
      - nginx
      - git
    state: present

# 服务管理
- name: 启动服务
  service:
    name: nginx
    state: started
    enabled: yes

Q57: 如何设计一个高可用的监控系统架构?

高可用监控系统设计:

关键组件HA配置:

  1. Prometheus高可用:使用联邦集群或Thanos架构
  2. AlertManager集群:主备+VIP配置
  3. Grafana高可用:MySQL共享session

架构设计原则:

  • 无单点故障
  • 数据持久化存储
  • 支持水平扩展
  • 告警渠道冗余

Q58: Git的工作流程你熟悉吗?分支管理策略是怎样的?

Git Flow(适合有固定发布周期的项目):

  • master/main: 主分支,只读
  • develop: 开发分支
  • feature: 功能分支
  • release: 发布分支
  • hotfix: 热修复分支

GitHub Flow(适合持续发布的项目):

bash
git checkout -b feature/add-login
git commit -m "feat: 添加登录功能"
git push origin feature/add-login
# 创建MR/PR,Code Review后合并到master

Q59: 如何做服务器的安全加固?

服务器安全加固清单:

1. 用户和访问控制:

bash
# 创建普通用户,禁止root直接登录
useradd deploy && usermod -aG wheel deploy
sed -i 's/PermitRootLogin yes/PermitRootLogin no/' /etc/ssh/sshd_config

2. 防火墙配置:

bash
firewall-cmd --permanent --add-service=ssh
firewall-cmd --permanent --add-service=https
firewall-cmd --reload

3. 内核参数加固:

bash
echo "net.ipv4.tcp_syncookies = 1" >> /etc/sysctl.conf
sysctl -p

Q60: 你了解哪些Python Web框架?Flask和Django的区别是什么?

Python Web框架对比:

特性FlaskDjango
架构微框架,灵活全功能框架
ORMSQLAlchemy(可选)内置Django ORM
Admin后台需要扩展内置admin
适用场景微服务、API大型Web应用

Flask示例:

python
from flask import Flask, jsonify

app = Flask(__name__)

@app.route('/health')
def health():
    return jsonify({'status': 'healthy'})

实际选择:

  • 运维平台、监控系统 → Flask
  • 企业后台管理系统 → Django

Q61: 如何实现一个高可用的Redis集群?

Redis集群方案对比:

方案数据分片故障转移适用场景
主从复制手动/哨兵小规模
Redis Sentinel自动高可用
Redis Cluster自动自动大规模

Redis Sentinel配置:

bash
sentinel monitor mymaster master_ip 6379 2
sentinel auth-pass mymaster your_password
sentinel down-after-milliseconds mymaster 5000

Q62: 什么是蓝绿部署和金丝雀发布?有什么区别?

1. 蓝绿部署(Blue-Green):

  • 维护两套环境(蓝和绿)
  • 切换时DNS指向新环境
  • 优点:回滚快
  • 缺点:资源占用多

2. 金丝雀发布(Canary):

  • 新版本只给少量用户使用(5%-10%)
  • 观察指标正常后逐步扩大
  • 优点:风险可控

选择建议:

  • 基础设施变更用蓝绿
  • 应用功能发布用金丝雀

Q63: 你遇到过最难解决的bug是什么?怎么排查的?

回答思路(STAR法则):

背景: 生产环境Java服务出现间歇性响应超时,持续30分钟后自动恢复。

排查过程:

  1. 时间线梳理:03:15开始,03:45恢复
  2. GC日志分析:发现Minor GC后有停顿
  3. 链路追踪:超时在数据库阶段
  4. 定时任务检查:发现03:15有全量数据同步任务

根因: 定时任务SQL锁定大表,导致连接池等待超时

结果: 优化SQL改成分批处理,增加告警监控


Q64: 如何保证线上服务的高可用?你有哪些实践经验?

高可用实践:

1. 应用层高可用(K8s):

yaml
spec:
  replicas: 3
  strategy:
    type: RollingUpdate
    maxUnavailable: 0

2. 健康检查:

yaml
livenessProbe:
  httpGet:
    path: /health
    port: 8080
  failureThreshold: 3

3. 限流和熔断:

  • Sentinel滑动窗口限流
  • Hystrix熔断保护

Q65: 你如何保持技术学习?有什么学习渠道?

技术学习方式:

1. 官方文档和源码:

  • 技术文档永远是最新最准的
  • GitHub看源码理解原理

2. 实践项目:

  • 学Docker:把个人网站容器化部署
  • 学Prometheus:监控自己的小项目
  • 学K8s:用Minikube本地实验

3. 我的学习方法:

  • 带着问题学:工作中遇到问题再去学
  • 多实践:看了不等于会了,要动手
  • 分享输出:讲出来才是真的理解了

附:快速复习清单

面试当天快速过一遍

【必背】
- TCP三次握手/四次挥手
- HTTP/HTTPS区别
- Docker vs 虚拟机
- K8s核心概念(Pod/Service/Deployment)
- Zabbix/Prometheus/ELK组件作用
- AIOps核心能力

【高频问题】
- 项目经历(用STAR法则准备2-3个)
- 故障排查思路(CPU高/网络不通/服务挂了)
- 监控指标设计
- 告警收敛原理

【新华三必问】
- AIO 3.0核心能力
- 浙江移动AIOps实践
- 对智能运维的理解

【代码能力】
- Python基础语法
- Shell常用命令
- 能手写简单的脚本

祝你面试成功! 🎉

褚成志 · 简历中心