臭名昭著aTrust隔离计划1.臭名昭著aTrust隔离计划2.VPN原理与aTrust隔离网络实践3.docker-easyconnect到底做了什么4.TUN(tunnel-隧道-虚拟网卡)模式
个人项目
personal(个人展示)GitHub Actions 自动部署个人展示项目
基于Quartz搭建的个人博客1.Quartz个人博客使用教程2.使用 rsync 增量部署 Quartz 博客3.使用 GitHub Actions 自动部署 Quartz 博客5.域名绑定6.CDN加速7.Google 搜索收录排查:为什么关键词搜得到别人,却搜不到我的网站?Obsidian、双向链接与知识图谱
架构设计
分布式分布式事务RPC原理
旅行
行程攻略青岛三日游行程攻略
前端
NginxNginx配置与反向代理入门
Nodenpm与npx的区别
数据库
mysql01.MySQL基础语法与约束02.MySQL数据库类型03.MySQL多表查询04.MySQL 索引05.MySQL 事务06.MySQL 隔离级别07.MySQL MVCC08.MySQL 锁09.EXPLAIN10.慢查询与 SQL 优化
mysql面试题01.索引问题02.事务与隔离级别03.锁机制04.存储引擎与性能优化05.用户权限、字符集与备份恢复
mysql实战01.EXPLAIN实战02.测试环境菜单误删排查与恢复03.MySQL IN 详解
网络
网络安全1.无线监听网卡苹果M系列虚拟机安装Kali Linux教程3.kali怎么使用RTL8812AU4.kali基础命令
网络基础进程之间怎样通过网络传递数据
网址常用网址
中间键
esElasticsearch 入门
mq
RabbitMQRabbitMQ高级RabbitMQ基础
1. MQ 基础2. MQ 核心角色与代码对应3. MQ Consumer Group 与消费模式4. SOFAMQ 账户变更代码实践5. MQ 可靠性问题6. 消息幂等
redis缓存击穿、穿透与雪崩Redis 分布式锁Redis 缓存问题Redis 数据结构
AI
使用说明
第三方插件&技能简介Archify使用与安装指南geekgeekRun使用OfferFlow使用指南Ponytail使用指南Skills Manager使用指南
CodexCodex CLI与IDE区别及使用指南Codex Hook单独配置与提交通知Codex MCP安装与使用指南Codex第三方插件安装与使用指南
Agent开发0-学习路线1.LLM、Token、上下文窗口与模型参数2.大模型 API、请求参数与响应结构3.Spring AI ChatClient4.Prompt、System Prompt、Prompt 模板6.结构化输出、JSON Schema7.SSE 流式响应8.会话 ID、聊天记录、Redis9.超时、重试、限流、降级10.*完成可运行聊天接口11.Function Calling、Tool Calling 原理12.用 Java 方法定义 Tool13.工具参数设计和校验14.实现订单查询工具15.实现物流查询工具16.实现库存查询工具17.多个工具自动选择18.工具异常、超时、重试
diy主机
主机零件学习1.CPU2.主板3.内存4.显卡5.硬盘6.散热7.风扇8.机箱热门型号价格表
捡垃圾diy-13600kf+5060diy-14600kf+5070
English高频词汇英文基础语法简单句子音标
GitGit常用命令Sublime Merge 使用指南
Java
工具库Caffeine本地缓存Reactor教程
工作实践如何使用@Async线程池使用与排查线上服务 CPU 使用率过高排查压测下RPC接口大量失败排查记录
基础1.HashMap2.ConcurrentHashMap3.HashSet4.final5.static6.volatile7.AtomicInteger8.String动态代理反射锁与线程同步线程注解
面试题1.HashMap 存储在方法内是线程安全的吗2.ArrayList参数传递与引用重新赋值3.== 和 equals 的区别、hashcode4.重载和重写的区别5.String、StringBuffer、StringBuilder区别及使用场景6.接口和抽象类7.ArrayList 与 LinkedList 的区别和扩容机制8.HashMap 和 Hashtable 的区别及底层实现9.Object 和 Objects 的区别10.ThreadLocal的原理和使用场景11.字节码是什么及作用12.Java类加载器有哪些13.双亲委派模型14.Java异常体系15.GC是什么16.GC如何判断对象可以被回收
面试总结0.HR面试模板1.面试一2.面试二3.面试三笔试
网络与 IO(黑马程序员-纯理论)01-网络编程基础02-IO模型与零拷贝03-BIO04-NIO基础与缓冲区05-NIO通道与选择器06-AIO
juc00-目录01-进程与线程02-线程同步与通信03-并发设计模式04-Java内存模型05-CAS与原子类06-ThreadLocal07-阻塞队列08-线程池使用与原理09-任务调度10-ForkJoin与享元模式11-AQS12-ReentrantLock13-读写锁14-并发协作工具15-ConcurrentHashMap16-CopyOnWrite与同步容器17-SkipListMap18-非阻塞队列
juc(工作常见)Java并发编程三个重点拆解
jvm1. JVM运行时数据区
Spring1.Spring IoC、DI与构造方法注入CGLIB、Byte Buddy 与 Spring AOPSpring 常用注解详解Spring Bean 生命周期
Spring MVC异常处理机制
linux常用命令
mac快捷键终端常用操作
python
基础01.Python是什么,为什么要安装Python02.Python项目中.venv是什么03.Python基础语法
基础实战sql替换
HTTPXHRMS员工详情接口调用(Python HTTPX)
windowswindows激活

一、💡 一句话理解

核心结论

Redis 不只是简单的 key-value 缓存:key 对应的 value 可以是 String、Hash、List、Set、Sorted Set 等结构。面试时重点讲清楚“结构特点、典型场景、常用命令和底层编码”。

二、🧭 理论:常见数据结构

2.1 五种经典数据结构

类型白话理解常见命令典型场景常见复杂度
String一个字符串、数字或二进制数据SET、GET、INCR缓存、计数器、分布式锁GET/SET 通常为 O(1)
Hash一个对象里的多个字段HSET、HGET、HGETALL用户信息、商品信息单字段读写通常为 O(1)
List按插入顺序排列的双端队列LPUSH、RPUSH、LPOP、LRANGE消息队列、最新列表两端插入删除通常为 O(1)
Set无序且不重复的集合SADD、SISMEMBER、SINTER标签、共同关注、去重添加和判断成员通常为 O(1)
Sorted Set每个成员带一个分数,按分数排序ZADD、ZRANGE、ZRANK排行榜、延时任务添加通常为 O(log N)

2.2 常见扩展结构

类型本质或特点典型场景
Bitmap在 String 上进行位操作用户签到、在线状态、布尔统计
Geospatial基于 Sorted Set 保存地理位置附近的人、门店距离
HyperLogLog用少量内存估算不重复元素数量,结果是近似值UV 统计
Stream类似可持久化的追加日志,支持消费组事件流、消息队列

面试范围

Redis 新版本还提供 JSON、时间序列、向量集合等能力,但常规 Java 面试优先掌握五种经典结构,以及 Bitmap、HyperLogLog、Geospatial、Stream。

三、⚙️ 理论:底层是怎么实现的

3.1 数据类型和底层编码不是一回事

用户看到的是 String、Hash、List 等逻辑类型;Redis 会根据元素数量、内容和配置选择更省内存或更高效的底层编码。数据增长超过阈值后,编码可能自动转换。

逻辑类型Redis 7+ 常见底层编码为什么这样设计
Stringint、embstr、raw整数直接存;短字符串减少内存分配;长字符串使用普通动态字符串
Hashlistpack、hashtable小对象紧凑存储;字段变多后使用哈希表提高查询效率
Listquicklist,节点内部通常使用 listpack同时兼顾两端操作效率和内存占用
Setintset、listpack、hashtable纯整数小集合紧凑存储;普通大集合用哈希表
Sorted Setlistpack,或 skiplist + hashtable小集合节省内存;大集合同时满足按成员查询和按分数排序

可以用下面的命令查看某个 key 当前采用的编码:

OBJECT ENCODING key

版本差异

老资料常写 ziplist。Redis 7.0 起,Hash 和 Sorted Set 的小对象编码已经使用 listpack;回答面试题时最好先说明版本。

3.2 为什么 Sorted Set 同时需要跳表和哈希表

  • 哈希表:根据成员快速找到分数。
  • 跳表:让成员按分数有序,方便排名和范围查询。
  • 两份索引指向同一批成员,因此用更多内存换取两类高效查询。

面试可直接回答:查某个成员靠哈希表,按分数排序和范围查找靠跳表。

3.3 如何选择数据结构

单值、计数器、缓存对象整体      → String
对象需要按字段读写              → Hash
要求顺序,并经常操作首尾         → List
要求去重、成员判断、交并差集      → Set
要求去重,同时还要排序或排名      → Sorted Set
只记录是或否                    → Bitmap
只需要近似统计不重复数量          → HyperLogLog
需要消费组和消息确认              → Stream

四、🚀 实践:从命令到验证

4.1 前置准备

下面示例适用于 Redis 7+。本机已安装 Redis 时,直接进入 redis-cli;也可以使用 Docker 启动临时实例:

docker run --name redis-interview -p 6379:6379 -d redis:7-alpine
docker exec -it redis-interview redis-cli

4.2 可以拿来干什么

4.2.1 String:缓存和计数

SET article:1001 "Redis"
GET article:1001
INCR article:1001:view-count

INCR 是原子操作,适合单个计数器;高并发下不需要先读取再写回。

4.2.2 Hash:保存对象字段

HSET user:1 name "Tom" age 20
HGET user:1 name
HGETALL user:1

适合字段较少、层级简单,并且需要单独修改某个字段的对象。

4.2.3 List:实现先进先出队列

LPUSH task:queue task1 task2
RPOP task:queue

左边放入、右边取出就是 FIFO 队列。不过需要消费组、确认和消息重试时,优先考虑 Stream,而不是只用 List 硬凑。

4.2.4 Set:去重和集合运算

SADD user:1:follow 10 20 30
SADD user:2:follow 20 30 40
SINTER user:1:follow user:2:follow

交集结果是 20、30,可用于共同关注。大集合执行交并差集可能消耗较多 CPU,不能只看单个命令是否简单。

4.2.5 Sorted Set:排行榜

ZADD game:rank 100 Alice 90 Bob 120 Carol
ZREVRANGE game:rank 0 2 WITHSCORES
ZRANK game:rank Alice

分数决定排序,成员必须唯一;更新同一成员时会覆盖其旧分数。

4.3 完整实践:一次验证五种结构

在 redis-cli 中依次执行:

FLUSHDB
 
SET demo:string hello
HSET demo:hash name Tom age 20
RPUSH demo:list A B C
SADD demo:set A A B
ZADD demo:zset 10 A 20 B
 
TYPE demo:string
TYPE demo:hash
TYPE demo:list
TYPE demo:set
TYPE demo:zset
 
GET demo:string
HGETALL demo:hash
LRANGE demo:list 0 -1
SMEMBERS demo:set
ZRANGE demo:zset 0 -1 WITHSCORES
 
OBJECT ENCODING demo:string
OBJECT ENCODING demo:hash
OBJECT ENCODING demo:list
OBJECT ENCODING demo:set
OBJECT ENCODING demo:zset

预期现象:

  • TYPE 分别返回 string、hash、list、set、zset。
  • Set 中重复添加的 A 只保留一份。
  • Sorted Set 按分数从小到大返回 A、B。
  • OBJECT ENCODING 的结果会受 Redis 版本、数据内容和配置阈值影响,不应死记某一次输出。

操作说明

FLUSHDB 会清空当前数据库,只能在临时练习实例中执行,不能在共享或生产环境中使用。

五、🎤 面试回答模板

5.1 如何介绍 Redis 数据结构

Redis 最常见的五种数据结构是 String、Hash、List、Set 和 Sorted Set。String 常用于缓存与计数;Hash 保存对象字段;List 适合双端队列;Set 用于去重和集合运算;Sorted Set 通过 score 排序,适合排行榜。除此之外还有 Bitmap、HyperLogLog、Geospatial 和 Stream。逻辑数据类型下面还会根据数据规模使用不同编码,例如 Hash 小数据使用 listpack,大数据转为 hashtable;Sorted Set 大数据通常使用跳表加哈希表。

5.2 List 和 Stream 怎么选

  • List 更简单,适合轻量队列和首尾操作。
  • Stream 支持消息 ID、消费组、待确认消息和消息确认,更适合可靠的事件消费。
  • 两者都不能自动等同于专业消息中间件,是否采用还要看可靠性、堆积量和运维要求。

5.3 Set 和 Sorted Set 有什么区别

  • 两者的成员都不重复。
  • Set 无序,擅长成员判断和交并差集。
  • Sorted Set 给每个成员关联一个 score,可按分数排序,但占用内存和操作成本通常更高。

六、📌 总结

  • 先记五种经典结构:String、Hash、List、Set、Sorted Set。
  • 选择结构时看四点:是否需要顺序、去重、排序,以及是否按字段访问。
  • 逻辑类型不等于底层编码;Redis 会在内存和性能之间做权衡。
  • Sorted Set 的高频面试点是“跳表负责排序,哈希表负责按成员查分数”。
  • 命令复杂度只是一部分,还要考虑大 key、大集合运算和版本差异。

七、🔗 官方资料