面试知识库

00 - 项目总览与架构#

知识图谱#

技术栈一览#

层次技术用途
框架Spring Boot 2.3.12应用骨架
语言Java 8开发语言
ORMMyBatis-Plus数据库访问,IService/ServiceImpl 模式
数据库MySQL持久化存储
缓存Redis (StringRedisTemplate)分布式缓存、分布式锁、分布式ID、GEO查询
本地缓存CaffeineL1 本地热点缓存
分布式锁Redisson可重入锁、看门狗续期
消息队列Kafka秒杀异步下单、点赞事件处理
序列化Jackson (GenericJackson2JsonRedisSerializer)Redis value 序列化
工具库Hutool, Lombok简化开发
构建Maven依赖管理与构建

模块划分#

主应用 com.hmdp#

模块核心功能关联文档
商铺 Shop缓存查询(穿透/击穿)、GEO 附近商户01-Redis缓存09-GEO
博客 Blog发布、点赞(ZSet)、Feed流推送05-Feed流
优惠券 Voucher三种券(普通/限购/秒杀)、秒杀下单03-秒杀系统
用户 User登录注册、签到(Bitmap)、限流06-认证鉴权
关注 Follow关注/取关、共同关注(Set交集)08-关注与社交

点赞子系统 com.like#

独立于主应用的模块,有自己的 Controller / Service / Mapper / Event。通过 @SpringBootApplication(scanBasePackages = "com") 统一扫描。

核心特点:三层判重(布隆过滤器 + Redis ZSet + DB)、Kafka 异步持久化、本地缓存预热。

详见 → 07-点赞子系统

请求生命周期#

Redis 数据结构全景#

数据结构Key 模式用途详见
Stringcache:shop:{id}商铺缓存01
Stringlogin:code:{phone}验证码06
Stringlock:shop:{id}缓存重建互斥锁02
Hashlogin:token:{UUID}用户会话06
Hashseckill:stock:{voucherId}秒杀库存/时间窗口03
Hashseckill:buyCount:{voucherId}用户购买计数03
Setseckill:order秒杀订单ID集合03
Setfollows:{userId}关注列表08
ZSetblog:liked:{blogId}博客点赞用户(按时间)05
ZSetfeed:{userId}用户Feed收件箱05
ZSetlikeZset:userId:{id}用户点赞文章列表07
ZSetlikeZset:articleId:{id}文章被赞用户列表07
Bitmapsign:{userId}:yyyyMM签到记录06
GEOshop:geo:{typeId}商铺地理位置09
BloomFilterlike-behavior-bloom-filter点赞行为快速判重07

Lua 脚本清单#

脚本位置用途详见
seckill.luasrc/main/resources/seckill.lua原子扣减库存、校验时间窗口和限购03
rollback.luasrc/main/resources/rollback.lua秒杀失败时回滚 Redis 数据03
unlock.luasrc/main/resources/unlock.lua分布式锁原子释放(compare-and-delete)02
updateLikeCount.luasrc/main/resources/updateLikeCount.lua原子更新点赞计数07

Kafka Topic 清单#

Topic生产者消费者用途详见
createOrderVoucherOrderServiceImplKafkaOrderConsumer秒杀异步下单03, 10
save-order-failed-topicKafkaOrderConsumerKafkaOrderConsumer下单失败回滚03, 10
TOPIC_LIKE_BEHAVIORLikeBehaviorServiceImplKafkaLikeConsumer点赞事件07, 10
TOPIC_SAVE_DB_FAILEDKafkaLikeConsumerKafkaLikeConsumer点赞持久化失败07, 10

面试 Q&A#

Q1: 请介绍一下你的项目#

这是一个类似大众点评的社交点评平台,核心功能包括商铺查询与缓存、优惠券秒杀、博客Feed流、用户关注、点赞等。

技术上,使用 Spring Boot + Redis + Kafka + Redisson 构建。重点解决了几个典型分布式问题:

  • 缓存穿透/击穿/雪崩:封装了通用 CacheClient,提供三种策略
  • 高并发秒杀:Redis Lua 脚本原子扣减 + Kafka 异步落库,实现读写分离
  • 分布式锁:从手写 SimpleRedisLock 演进到 Redisson
  • Feed流:基于 Redis ZSet 的推模式 + 游标分页
  • 点赞系统:独立子系统,布隆过滤器 + ZSet + DB 三层判重

追问:项目有几个模块?为什么点赞要独立出来?#

两个 Java 根包:com.hmdp(主应用)和 com.like(点赞子系统)。

点赞独立出来是因为它在架构上可以作为独立微服务拆分——有自己的 Controller、Service、Mapper、Kafka Event,与主应用只通过 UserService 共享用户数据。这种设计为将来服务化做好了准备。

再追问:两个包是怎么被 Spring 同时扫描到的?#

HmDianPingApplication 上配置了 @SpringBootApplication(scanBasePackages = "com"),同时 @MapperScan({"com.hmdp.mapper", "com.like.mapper"}) 扫描两个 mapper 包。

Q2: 项目中用到了哪些 Redis 数据结构?分别解决什么问题?#

几乎用到了 Redis 全部核心数据结构:

  • String:缓存商铺数据、验证码存储、互斥锁、计数器
  • Hash:用户会话Token、秒杀库存信息
  • Set:关注列表(用于 SINTER 求共同关注)、秒杀订单集合
  • ZSet:博客点赞排行、Feed流收件箱、点赞记录
  • Bitmap:用户签到(每天1位,空间极优)
  • GEO:附近商户查询(5km 范围搜索)
  • Bloom Filter(Redisson):点赞行为快速判重

追问:为什么用 ZSet 而不是 List 做 Feed 流?#

ZSet 支持按 score(时间戳)范围查询 + 自动排序,而 List 只支持下标访问。Feed 流需要按时间倒序分页,且要处理同一时刻多条消息的情况,ZSet 的 ZREVRANGEBYSCORE + offset 可以精确定位游标位置,List 做不到。


加分回答#

  • 能画出完整的请求链路(从 HTTP 到 Redis/DB/Kafka)说明对架构理解深入
  • 主动提到项目中的设计取舍(如推模式 vs 拉模式、Lua vs 事务)展示批判性思维
  • 提到点赞子系统的独立设计暗示微服务拆分思路,面试官会认为你有架构意识
  • 主动列出项目中发现的 Bug(见 11-已知问题),展示代码审查能力

关联文档#