Files
interview/questions/03-缓存/Redis数据结构.md
yasinshaw 0e46a367c4 refactor: rename files to Chinese and organize by category
Organized 50 interview questions into 12 categories:
- 01-分布式系统 (9 files): 分布式事务, 分布式锁, 一致性哈希, CAP理论, etc.
- 02-数据库 (2 files): MySQL索引优化, MyBatis核心原理
- 03-缓存 (5 files): Redis数据结构, 缓存问题, LRU算法, etc.
- 04-消息队列 (1 file): RocketMQ/Kafka
- 05-并发编程 (4 files): 线程池, 设计模式, 限流策略, etc.
- 06-JVM (1 file): JVM和垃圾回收
- 07-系统设计 (8 files): 秒杀系统, 短链接, IM, Feed流, etc.
- 08-算法与数据结构 (4 files): B+树, 红黑树, 跳表, 时间轮
- 09-网络与安全 (3 files): TCP/IP, 加密安全, 性能优化
- 10-中间件 (4 files): Spring Boot, Nacos, Dubbo, Nginx
- 11-运维 (4 files): Kubernetes, CI/CD, Docker, 可观测性
- 12-面试技巧 (1 file): 面试技巧和职业规划

All files renamed to Chinese for better accessibility and
organized into categorized folders for easier navigation.

Generated with [Claude Code](https://claude.com/claude-code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
2026-03-01 00:10:53 +08:00

4.5 KiB
Raw Blame History

Redis 数据结构

问题

  1. Redis 有哪些数据结构?底层实现是什么?
  2. String 类型的应用场景?
  3. Hash 和 String 的区别?
  4. List 的应用场景?
  5. Set 和 ZSet 的区别?
  6. Bitmap、HyperLogLog、GEO 的应用?

标准答案

1. Redis 数据类型

类型 底层实现 应用场景
String SDS 缓存、计数器、分布式锁
Hash 压缩列表/哈希表 对象存储、购物车
List 双向链表/压缩列表 消息队列、最新列表
Set 哈希表/整数集合 标签、共同关注
ZSet 跳表/哈希表 排行榜、延时队列
Bitmap String位操作 签到、在线用户
HyperLogLog String基数统计 UV 统计
GEO ZSet经纬度编码 附近的人

2. StringSDS - Simple Dynamic String

结构

struct sdshdr {
    int len;        // 已使用长度
    int free;       // 剩余空间
    char buf[];     // 字节数组
};

优势

  • O(1) 获取长度
  • 防止缓冲区溢出
  • 减少内存分配次数

应用

# 缓存
SET user:1001 '{"id":1001,"name":"Alice"}'
GET user:1001

# 计数器
INCR view_count:1001
DECR stock:1001

# 分布式锁
SET lock:order:1001 "uuid" NX PX 30000

3. Hash

结构

HSET user:1001 name "Alice" age 25 email "alice@example.com"
HGET user:1001 name
HGETALL user:1001

底层

  • 字段少(< 512压缩列表ziplist
  • 字段多(≥ 512哈希表hashtable

应用

// 对象存储(推荐 Hash而非 String
redisTemplate.opsForHash().putAll("user:1001", Map.of(
    "name", "Alice",
    "age", "25"
));

// 购物车
redisTemplate.opsForHash().put("cart:1001", "product:1001", "2");

4. List

结构

LPUSH list:msgs "msg1" "msg2" "msg3"  # 左侧插入
RPOP list:msgs                        # 右侧弹出

底层

  • 元素少(< 512压缩列表ziplist
  • 元素多(≥ 512双向链表linkedlist
  • Redis 3.2+quicklistziplist + linkedlist

应用

# 消息队列
LPUSH queue:email '{"to":"alice@example.com","subject":"Hello"}'
RPOP queue:email

# 最新列表
LPUSH timeline:1001 "post1" "post2"
LRANGE timeline:1001 0 9  # 最新 10 条

5. Set vs ZSet

Set无序集合

SADD tags:article:1001 "java" "redis" "mysql"
SMEMBERS tags:article:1001
SISMEMBER tags:article:1001 "java"
SINTER tags:user:1001 tags:article:1001  # 交集

底层

  • 元素少(< 512整数集合intset
  • 元素多(≥ 512哈希表hashtable

ZSet有序集合

ZADD rank:score 100 "player1" 200 "player2" 150 "player3"
ZREVRANGE rank:score 0 9 WITHSCORES  # Top 10
ZRANK rank:score "player1"          # 排名
ZSCORE rank:score "player1"         # 分数

底层

  • 元素少(< 128压缩列表ziplist
  • 元素多(≥ 128跳表skiplist + 哈希表hashtable

6. Bitmap

原理:用 bit 位表示状态0 或 1

# 签到
SETBIT sign:2024:02:28:1001 0 1  # 用户 1001 在第 0 天签到
SETBIT sign:2024:02:28:1001 4 1  # 用户 1001 在第 4 天签到

# 统计签到天数
BITCOUNT sign:2024:02:28:1001

# 用户 1001 和 1002 共同签到的天数
BITOP AND result sign:2024:02:28:1001 sign:2024:02:28:1002
BITCOUNT result

7. HyperLogLog

用途:基数统计(不重复元素个数)

优点内存占用极小12 KB

PFADD uv:2024:02:28 user:1001 user:1002 user:1003
PFCOUNT uv:2024:02:28  # 3

# 合并多个 HyperLogLog
PFMERGE uv:2024:02:01-28 uv:2024:02:01 uv:2024:02:02 ...

误差率< 1%


8. GEO地理位置

# 添加位置
GEOADD locations:users 116.404 39.915 "user:1001"  # 北京

# 查找附近的人5 km 内)
GEORADIUS locations:users 116.404 39.915 5 km

# 计算距离
GEODIST locations:users user:1001 user:1002

底层ZSet经纬度编码为 score


9. 阿里 P7 加分项

深度理解

  • 理解 SDS 和 C 字符串的区别
  • 理解跳表的实现原理
  • 理解压缩列表的优缺点

实战经验

  • 有选择合适数据类型的经验
  • 有大数据量下的优化经验
  • 有 Redis 内存优化的经验

架构能力

  • 能设计基于 Redis 的业务方案
  • 能设计 Redis 集群方案
  • 能设计 Redis 监控体系