Files
interview/questions/redis-data-structure.md
yasinshaw fe2e6dc2f2 feat: add 50 backend interview questions and answers
Generated comprehensive interview preparation materials covering:
- Distributed systems (transactions, locks, ID generation, consistency)
- Database (indexing, sharding, replication, transactions)
- Caching (Redis, cache problems, distributed lock)
- Message queues (RocketMQ, Kafka)
- Concurrency (ThreadLocal, ConcurrentHashMap, thread pools)
- JVM (GC, memory, tuning)
- System design (seckill, short URL, IM, feed, LBS)
- Algorithms (B+ tree, LRU, Red-Black tree, Skip list, Timing wheel)
- Network (TCP/IP, HTTP/HTTPS)
- Security (encryption, SQL injection, XSS)
- Performance tuning
- Design patterns
- Microservices (Spring Boot, Gateway, Service Mesh)
- Container orchestration (Kubernetes, Docker)
- CI/CD, observability

Each file includes:
- Detailed questions
- Comprehensive answers
- Code examples
- Real project experience
- Alibaba P7 level requirements

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:09:50 +08:00

216 lines
4.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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
**结构**
```c
struct sdshdr {
int len; // 已使用长度
int free; // 剩余空间
char buf[]; // 字节数组
};
```
**优势**
- O(1) 获取长度
- 防止缓冲区溢出
- 减少内存分配次数
**应用**
```bash
# 缓存
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
**结构**
```bash
HSET user:1001 name "Alice" age 25 email "alice@example.com"
HGET user:1001 name
HGETALL user:1001
```
**底层**
- 字段少(< 512压缩列表ziplist
- 字段多(≥ 512哈希表hashtable
**应用**
```java
// 对象存储(推荐 Hash而非 String
redisTemplate.opsForHash().putAll("user:1001", Map.of(
"name", "Alice",
"age", "25"
));
// 购物车
redisTemplate.opsForHash().put("cart:1001", "product:1001", "2");
```
---
### 4. List
**结构**
```bash
LPUSH list:msgs "msg1" "msg2" "msg3" # 左侧插入
RPOP list:msgs # 右侧弹出
```
**底层**
- 元素少(< 512压缩列表ziplist
- 元素多(≥ 512双向链表linkedlist
- Redis 3.2+quicklistziplist + linkedlist
**应用**
```bash
# 消息队列
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无序集合**
```bash
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有序集合**
```bash
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
```bash
# 签到
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
```bash
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地理位置
```bash
# 添加位置
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 监控体系