真实面经题目 · 原创解析
Redis 常见数据结构有哪些?
这题不只是列 Redis 类型,还要能按访问模式、底层编码、复杂度和大 key 风险说明为什么这样建模。
真实面经题目 · 原创解析
这题不只是列 Redis 类型,还要能按访问模式、底层编码、复杂度和大 key 风险说明为什么这样建模。
Redis 常见 value 类型有 String、Hash、List、Set、ZSet,也有 Bitmap、HyperLogLog、Geo、Stream 等结构。回答时按场景选型:String 做缓存、计数和分布式锁值;Hash 存对象字段;List 做简单队列;Set 做去重和集合运算;ZSet 做排行榜和延迟队列;Stream 更适合消费组消息流。再补充底层编码会随元素数量和大小变化,例如 SDS、listpack、intset、hashtable、skiplist,并说明命令复杂度和 big key 风险。
点查缓存和计数用 String,字段级对象更新用 Hash,去重和交并差用 Set,按分数排序或范围分页用 ZSet,可靠消费组消息更适合 Stream。
`GET/SET/INCR` 对应 String,`HGET/HSET` 对应 Hash,`LPUSH/BRPOP` 对应 List,`SADD/SISMEMBER` 对应 Set,`ZADD/ZRANGE/ZREVRANK` 对应 ZSet。面试时要能说出常用命令的大致复杂度。
String 基于 SDS;小 Hash、List、ZSet 可能用 listpack;小整数 Set 可能用 intset;规模变大后会转 hashtable 或 skiplist 加 dict。编码转换会影响内存和性能。
Bitmap 适合签到和布尔状态集合;HyperLogLog 估算 UV 但有误差;Geo 适合经纬度半径查询;Stream 提供消息 ID、消费组、pending 列表,比 List 更适合可追踪消费。
超大 Hash、Set、ZSet 会阻塞主线程、拖慢删除和迁移。范围扫描优先用渐进式命令,删除大 key 用异步删除或拆分 key,避免线上直接 `KEYS` 扫全库。
ZSet 同时维护 member 和 score,能按分数排序、查排名、取区间和更新分数,天然适合排行榜。
不一定。Hash 支持字段级更新,小对象可能更省内存;但字段太多会变成 big key,JSON 读写简单但更新要整体替换。
List 更像简单阻塞队列,缺少消费组、ack 和 pending 管理;Stream 更适合多消费者组和可追踪重试。
不能。它用于基数估算,内存小但有误差;精确去重要用 Set、Bitmap 或外部存储。