深分页 SQL 导致数据库 CPU 打满的问题,核心原因并非数据量而是 SQL 写法。
问题根源:项目订单列表分页查询时,运营脚本从第一页查询到第 5000 页,原 SQL(SELECT * FROM orders LIMIT 100000,20)未走索引覆盖,每扫一条数据需回表查完整信息,10 万条数据回表 10 万次,打爆磁盘 I/O,数据库 CPU 从 30% 飙至 100%。
优化方案:视频提出 4 种优化方案,包括子查询走索引覆盖、记录上次查询最大 ID、限制分页深度、使用搜索引擎(如 ES 的 Scroll 或 Search After)。
注意细节:COUNT () 总数变慢可用缓存或每小时更新;ORDER 字段需加索引;优先使用索引覆盖,避免查询不必要字段。
视频提供了从简单到进阶的深分页 SQL 优化方案,并提及程序员大厂面试核心资料可领取。
该问题的核心考察点是高并发场景下 API 访问统计的技术选型与架构设计。
核心需求:视频明确提出三个核心需求,包括统计过去十分钟每个 API 的访问次数、保证数据实时更新、统计过程不拖慢主系统,以及看板展示访问量最高的前 N 个 API。
方案一:基于 Flink、Kafka、RabbitMQ 的实时流处理方案。通过 AOP 或过滤器拦截 API 请求并发送到消息队列,Flink 从 Kafka 消费数据并开启十分钟滑动窗口进行统计,结果实时更新到 Redis 的 Sorted Set 中,前端看板通过 GraphFinder 连接 Redis 展示 TopN 数据。
方案二:复用 ELK 日志体系。Logstash 采集 Web 服务器访问日志并解析,写入 Elasticsearch,利用其聚合功能统计最近十分钟 API 访问次数,通过 Kibana 创建 Dashboard 展示 TopN 数据。
方案对比:方案一优点是完全异步、不影响主系统性能,Flink 保证实时性和准确性,Redis 的 Sorted Set 高效获取 TopN;方案二优点是无需额外开发、开箱即用,便于日志回溯,缺点是实时性略差,有秒级到分钟级延迟,且需要维护 ELK 集群,资源开销较大。
选择方案需根据公司现有技术栈和实时性要求决定。
视频通过 MySQL 实操演示与规则拆解,揭示 MVCC 解决读写冲突的底层机制,而非仅依赖面试理论背诵。
核心问题:MVCC 为解决 MySQL 读写冲突设计,既避免读操作阻塞写操作导致性能下降,又防止直接读取未提交的脏数据。
底层三剑客:通过隐藏字段记录事务 ID(实操查看 innodb_trx 表获取事务 ID)、Undo log 生成历史版本链(演示 show engine innodb status 查看版本链)、Read View 快照判断数据可见性,三者配合实现读写不阻塞。
隔离级别差异:RC(读已提交)每次查询生成新 Read View,RR(可重复读)仅首次生成,导致前者不可重复读、后者可重复读。
局限性:仅解决读写冲突,写写冲突仍需加锁;RR 级别下普通查询缓解幻读但当前读仍可能遇到,需 Next-Key lock 配合;大事务会拉长 Undo log 版本链,增加空间开销。
视频强调日常开发需避免大事务,以减少 Undo log 版本链过长带来的空间开销。
直接使用定时任务处理订单自动取消的方案会被面试官判定为 "小白操作"。
定时任务缺陷:每分钟全表扫描数据库会浪费资源,且存在时间差导致商品库存被多占用。
Redis ZSet 方案:将订单按 30 分钟后的时间戳存入有序集合,后台进程监控集合头部订单,当前时间超过时间戳时执行取消操作。
RabbitMQ 私信队列:设置缓冲队列并配置 30 分钟存活时间,订单消息过期后通过死信交换转发至业务队列,由消费者执行取消操作。
时间轮算法:通过类似机械手表表盘的结构处理延时任务,任务按时间刻度挂载,秒针转动时检查对应刻度的任务,支持单机高效处理大量延时任务。
视频最后提出思考题:使用 Redis ZSet 方案时,多台机器并发处理过期订单如何避免重复取消。
四年经验的后端求职者因未识别秒杀场景中对象创建速度导致的 OOM 问题,暴露了对高并发系统内存模型的认知盲区。
核心问题:秒杀活动中每秒数千请求触发高频订单对象创建,GC 回收速度跟不上对象生成速度,导致堆内存溢出(OOM)。
三层防御:第一层需理解对象创建本质,通过逃逸分析优化内存分配、复用对象池;第二层需精细化配置 JVM 参数,包括堆大小设置、GC 收集器选型和日志监控;第三层需在网关层限流、依赖服务熔断降级、压力过大时优雅降级。
考察重点:题目核心考察从 "写代码" 到 "管内存" 的系统思维,而非单纯的并发控制能力。
视频指出高并发系统中内存模型、GC 策略、JVM 参数等细节直接决定系统稳定性。
视频通过模拟面试场景,拆解 JVM 垃圾回收机制的核心考点与回答逻辑。
对象存活判断:对比引用计数法(Python/PHP 使用,存在循环引用问题)与可达性分析法(Java 使用,从 GC Roots 出发判断对象存活),明确 GC Roots 包含虚拟机栈局部变量、静态属性、常量、JNI 引用等。
分代回收理论:Java 堆分为年轻代(标记 - 复制算法,对象朝生夕死)和老年代(标记 - 清除 / 整理算法,对象存活时间长),不同代使用不同算法以提高回收效率。
垃圾回收器:详细解析 Serial(单线程、STW、适合客户端)、Parallel(多线程、吞吐量优先、JDK8 默认)、CMS(低停顿、四阶段回收、存在 CPU 敏感 / 浮动垃圾 / 内存碎片问题)、G1(Region 分区、可预测停顿、JDK9 + 默认)的原理与适用场景。
面试追问:覆盖 System.gc () 触发机制、finalize () 方法作用、永久代与元空间区别等高频问题。
视频强调大厂面试更关注对原理、优缺点、适用场景及调优方法的理解,而非单纯概念记忆。