孟哥讲解了后端开发者使用 Redis 时易踩的五个高频性能陷阱及应对方法。
Keys 命令陷阱:生产环境使用 Keys*、Keysuser 等命令会锁住 Redis,导致请求卡住,需用渐进式扫描的 Scan 命令替代,百万 Key 场景下无感知。
单线程认知陷阱:Redis 从 6.0 版本开始引入多线程 IO 模型,核心命令执行仍为单线程,多线程仅处理网络 IO 和命令解析;修改配置开启 IO 线程,设置线程数为 CPU 核心数两倍,可使 QPS 从十万提升至十六万,延迟降低。
未用批量命令陷阱:单条发送多命令会浪费网络延迟,使用 Pipeline 等批量方式,可使批量导入系统吞吐量从每秒两千提升至一万六。
缓存问题混淆陷阱:缓存穿透是查不存在的 Key 直接打数据库,可用缓存空值或布隆过滤器解决;缓存击穿是热点 Key 过期导致大量请求打数据库,可用互斥锁或提前更新解决;缓存雪崩是大量 Key 同时过期,给过期时间加随机数可规避。
持久化策略陷阱:RDB 性能好但可能丢数据,AOF 可靠但性能稍差,Redis4.0 后支持的混合持久化可兼顾可靠性与性能,能将重启时间从二十分钟缩短至三分钟。
做好以上五点可让 Redis 应用运行稳定高效。
仅将网关理解为请求转发工具会限制面试表现,其实际是微服务架构的统一门面与多维度治理中枢。
统一入口解耦:作为微服务唯一入口,隔离客户端与后端服务,避免客户端因服务 IP / 端口变更修改代码。
统一鉴权处理:入口处验证 Token,解析用户 ID 传递给下游,实现关注点分离,避免重复开发鉴权逻辑。
流量控制防护:通过 Sentinel 或 Redis 令牌桶算法限流,熔断过载服务,防止后端被突发流量压垮。
协议转换适配:将外部 HTTP 请求转为内部 RPC 调用(如 Dubbo/GRPC),兼容内外协议差异。
BFF 数据裁剪:针对手机 / PC 等设备聚合或裁剪数据,返回适配字段,减轻后端负担。
网关选型建议:推荐 Nginx 做外层流量网关,Spring Cloud Gateway 处理复杂业务,二者组合为云原生黄金搭档。
配套学习资源:视频笔记整理进 Java+AI 面试题库,包含主流技术栈、项目场景题、简历模板及学习路线。
视频建议将简历中的 "了解网关" 改为 "精通网关",以体现架构设计能力。
视频讲解了 Java 面试中 RabbitMQ 与 Kafka 的核心区别及适配场景,用于考察 MQ 特性、架构与选型能力。
核心定位差异:RabbitMQ 是轻量级高可用消息中间件,侧重消息投递的精准性和可靠性;Kafka 是分布式高吞吐日志系统,侧重海量数据的高效传输和存储。
吞吐性能不同:Kafka 采用批量发送、顺序存储、零拷贝技术,吞吐率极高,适配海量数据场景;RabbitMQ 吞吐量较低,满足常规业务需求。
消息可靠性区别:RabbitMQ 支持确认机制、死信队列、事务消息,能保证消息不丢失、不重复,可靠性更强;Kafka 依赖副本机制和 ack 确认级别,默认允许少量数据丢失,可靠性略逊。
消息模式与路由:RabbitMQ 支持交换机,路由灵活复杂,可实现精准消息分发;Kafka 为主题 - 分区模型,路由简单,仅支持按分区 / 键值分发。
视频提及相关面试题答案整理在评论区。
小哲讲解了百万并发场景下的排行榜系统设计方案。
- MQ 缓冲写请求:玩家得分消息先存入消息队列,后台将消息按千条批量打包后,再更新 Redis 的 ZSET 分数,可将百万并发写压力压缩至几千,需标记消息避免重复加分。
- 两级缓存抗读并发:在业务服务器设置有效期为两三秒的本地缓存,存储排行榜前百名数据,仅在缓存过期时从 Redis 同步最新数据,减少 Redis 读请求。
- 业务分片解大 Key:单 ZSET 内存不足时,按服务器分区或时间周期拆分榜单;全服总榜可抽取各分区前几十名,在应用层排序后存入单独缓存。
- MySQL 兜底对账:将最终分数异步写入 MySQL,后台定期对账,Redis 故障时可通过 MySQL 数据重建排行榜。
该方案通过拆分读写流量、异步处理、分片拆解实现高并发支撑。
面试官通过真实事故案例与三层缓存防御思路,考察 3 年后端开发者的高并发缓存设计能力。
- 事故还原:电商商品详情页采用 "先删缓存再更新数据库" 方案,缓存刚删除时大量请求涌入,将旧数据写回缓存;数据库更新后缓存仍为旧数据,手动清缓存直接打崩数据库。
- 第一层防御:明确缓存是性能优化层而非数据源,并发场景下必然存在缓存与数据库的时间窗口,需控制不一致的时间和影响范围,而非追求绝对一致。
- 第二层防御:业务设计上减少缓存参与写逻辑,写操作仅删缓存;热点数据不设统一过期时间,同一 Key 写操作保证顺序;热点 Key 永不过期,用异步任务刷新。
- 第三层防御:设置缓存删除失败的重试机制(MQ / 定时任务);定时抽样比对数据库与缓存,自动修复不一致;缓存失效时启动降级方案,热点接口配置限流规则。
该面试题核心考察开发者应对缓存失效风险的系统设计思维。
视频详解 Java 不同版本 HashMap 的线程安全问题及面试应答要点。
- 1.7 死循环原因:JDK1.7 的 HashMap 底层为数组加链表,扩容时采用头插法迁移元素,头插法会使元素逆序排列;多线程并发扩容时,若两个线程持有链表不同部分且互相引用,会形成环形链表,后续 get 操作遍历到该环会导致 CPU 飙升、程序卡死。
- 1.8 改进与缺陷:JDK1.8 改用尾插法扩容,保证元素相对顺序,避免死循环;同时引入红黑树,链表长度超 8 时转红黑树提升查询效率。但仍存在线程不安全问题:多线程 put 时若 key 哈希碰撞,会出现数据覆盖;并发 put 触发扩容时,可能数据丢失或 size 计数不准;红黑树并发左旋右旋会破坏结构。
- 并发容器选择逻辑:并发场景下推荐用 ConcurrentHashMap,原因包括:1.7 用分段锁、1.8 用 CAS+synchronized 细粒度锁,锁竞争远小于给整个 HashMap 加锁;其 putIfAbsent、replace 等方法是原子性的,无需额外实现;迭代器为弱一致性,不会抛出 ConcurrentModificationException,适合并发遍历。
分版本讲清 HashMap 的线程安全细节,是大厂 Java 面试的核心应答要求。