面渣逆袭Redis篇V2.0(暗黑版)




⾯渣逆袭 Redis篇第⼆版-让天下所有的⾯渣都能逆袭
No. 1 / 314
⾯渣逆袭 Redis篇第⼆版-让天下所有的⾯渣都能逆袭
前⾔
4.6 万字 286 张⼿绘图,详解 57 道 Redis ⾯试⾼频题(让天下没有难背的⼋股),⾯渣背会
这些 Redis ⼋股⽂,这次吊打⾯试官,我觉得稳了(⼿动 dog)。整理:沉默王⼆,戳转载
链接,作者:三分恶,戳原⽂链接。
亮⽩版本更适合拿出来打印,这也是很多学⽣党喜欢的⽅式,打印出来背诵的效率会更⾼。
2025 年 04 ⽉ 27 ⽇开始着⼿第⼆版更新。
对于⾼频题,会标注在《Java ⾯试指南(付费)》中出现的位置,哪家公司,原题是什
么,并且会加 ,⽬录⼀⽬了然;如果你想节省时间的话,可以优先背诵这些题⽬,尽
快做到知彼知⼰,百战不殆。
区分⼋股精华回答版本和原理底层解释,让⼤家知其然知其所以然,同时⼜能做到⾯试时
的⾼效回答。
结合项⽬(技术派、pmhub)来组织语⾔,让⾯试官最⼤程度感受到你的诚意,⽽不是
机械化的背诵。
No. 2 / 314
⾯渣逆袭 Redis篇第⼆版-让天下所有的⾯渣都能逆袭
修复第⼀版中出现的问题,包括球友们的私信反馈,⽹站留⾔区的评论,以及 GitHub 仓
库中的 issue,让这份⾯试指南更加完善。
增加⼆哥编程星球的球友们拿到的⼀些 offer,对⾯渣逆袭的感谢,以及对简历修改的⼀
些认可,以此来激励⼤家,给⼤家更多信⼼。
优化排版,增加⼿绘图,重新组织答案,使其更加⼝语化,从⽽更贴近⾯试官的预期。
⻓按识别下⾯的⼆维码,关注⼆哥的公众号,回复【222】即可拉取最新版本。
No. 3 / 314
⾯渣逆袭 Redis篇第⼆版-让天下所有的⾯渣都能逆袭
当然了,请允许我的⼀点点私⼼,那就是星球的 PDF 版本会⽐公众号早⼀个⽉时间,毕竟星
球⽤户都付费过了,我有必要让他们先享受到⼀点点福利。相信⼤家也都能理解,毕竟在线
版是免费的,CDN、服务器、域名、OSS 等等都是需要成本的。
更别说我付出的时间和精⼒了,⼤家觉得有帮助还请给个⼝碑,让你身边的同事、同学都能
受益到。
No. 4 / 314
⾯渣逆袭 Redis篇第⼆版-让天下所有的⾯渣都能逆袭
我把⼆哥的 Java 进阶之路、JVM 进阶之路、并发编程进阶之路,以及所有⾯渣逆袭的版本都
放进来了,涵盖 Java基础、Java集合、Java并发、JVM、Spring、MyBatis、计算机⽹络、
操作系统、MySQL、Redis、RocketMQ、分布式、微服务、设计模式、Linux 等 16 个⼤的
主题,共有 40 多万字,2000+张⼿绘图,可以说是诚意满满。
展示⼀下暗⿊版本的 PDF 吧,排版清晰,字体优雅,更加适合夜服,晚上看会更舒服⼀点。
No. 5 / 314
⾯渣逆袭 Redis篇第⼆版-让天下所有的⾯渣都能逆袭
基础
1. 说说什么是 Redis?
Redis 是⼀种基于键值对的 NoSQL 数据库。
No. 6 / 314
⾯渣逆袭 Redis篇第⼆版-让天下所有的⾯渣都能逆袭
它主要的特点是把数据放在内存当中,相⽐直接访问磁盘的关系型数据库,读写速度会快很
多,基本上能达到微秒级的响应。
所以在⼀些对性能要求很⾼的场景,⽐如缓存热点数据、防⽌接⼝爆刷,都会⽤到 Redis。
不仅如此,Redis 还⽀持持久化,可以将内存中的数据异步落盘,以便服务宕机重启后能恢复
数据。
Redis 和 MySQL 的区别?
Redis 属于⾮关系型数据库,数据是通过键值对的形式放在内存当中的;MySQL 属于关系型
数据库,数据以⾏和列的形式存储在磁盘当中。
No. 7 / 314
⾯渣逆袭 Redis篇第⼆版-让天下所有的⾯渣都能逆袭
实际开发中,会将 MySQL 作为主存储,Redis 作为缓存,通过先查 Redis,未命中再查
MySQL 并写回Redis 的⽅式来提⾼系统的整体性能。
项⽬⾥哪⾥⽤到了 Redis?
在技术派实战项⽬当中,有很多地⽅都⽤到了 Redis,⽐如说⽤户活跃排⾏榜⽤到了 zset,作
者⽩名单⽤到了 set。
No. 8 / 314
⾯渣逆袭 Redis篇第⼆版-让天下所有的⾯渣都能逆袭
还有⽤户登录后的 Session、站点地图 SiteMap,分别⽤到了 Redis 的字符串和哈希表两种数
据类型。
No. 9 / 314
⾯渣逆袭 Redis篇第⼆版-让天下所有的⾯渣都能逆袭
其中⽐较有挑战性的⼀个应⽤是,通过 Lua 脚本封装 Redis 的 setnex 命令来实现分布式锁,
以保证在⾼并发场景下,热点⽂章在短时间内的⾼频访问不会击穿 MySQL。
No. 10 / 314
⾯渣逆袭 Redis篇第⼆版-让天下所有的⾯渣都能逆袭
部署过 Redis 吗?
第⼀种回答版本:
我只在本地部署过单机版,下载 Redis 的安装包,解压后运⾏ redis-server 命令即可。
第⼆种回答版本:
我有在⽣产环境中部署单机版 Redis,从官⽹下载源码包解压后执⾏ make && make
install 编译安装。然后编辑 redis.conf ⽂件,开启远程访问、设置密码、限制内存、设
置内存过期淘汰策略、开启 AOF 持久化等:
No. 11 / 314
⾯渣逆袭 Redis篇第⼆版-让天下所有的⾯渣都能逆袭
bind 0.0.0.0 # 允许远程访问
requirepass your_password # 设置密码
maxmemory 4gb # 限制内存,避免 OOM
maxmemory-policy allkeys-lru # 内存淘汰策略
appendonly yes # 开启 AOF 持久化
第三种回答版本:
我有使⽤ Docker 拉取 Redis 镜像后进⾏容器化部署。
docker run -d --name redis -p 6379:6379 redis:7.0-alpine
Redis 的⾼可⽤⽅案有部署过吗?
有部署过哨兵机制,这是⼀个相对成熟的⾼可⽤解决⽅案,我们⽣产环境部署的是⼀主两从
的 Redis 实例,再加上三个 Sentinel 节点监控它们。Sentinel 的配置相对简单,主要设置了
故障转移的判定条件和超时阈值。
主节点配置:
port 6379
appendonly yes
从节点配置:
replicaof 192.168.1.10 6379
哨兵节点配置:
sentinel monitor mymaster 192.168.1.10 6379 2
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 60000
sentinel parallel-syncs mymaster 1
No. 12 / 314
⾯渣逆袭 Redis篇第⼆版-让天下所有的⾯渣都能逆袭
当主节点发⽣故障时,Sentinel 能够⾃动检测并协商选出新的主节点,这个过程⼤概需要 10-
15 秒。
另⼀个⼤型项⽬中,我们使⽤了 Redis Cluster 集群⽅案。该项⽬数据量⼤且增⻓快,需要⽔
平扩展能⼒。我们部署了 6 个主节点,每个主节点配备⼀个从节点,形成了⼀个 3主3从 的初
始集群。Redis Cluster 的设置⽐ Sentinel 复杂⼀些,需要正确配置集群节点间通信、分⽚映
射等。
redis-server redis-7000.conf
redis-server redis-7001.conf
...
# 使⽤ redis-cli 创建集群
# Redis 会⾃动将 key 哈希到 16384 个槽位
# 主节点均分槽位,从节点⾃动跟随
redis-cli --cluster create
127.0.0.1:7000 127.0.0.1:7001 127.0.0.1:7002
127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005
--cluster-replicas 1
Redis Cluster 最⼤的优势是数据⾃动分⽚,我们可以通过简单地增加节点来扩展集群容量。
此外,它的故障转移也很快,通常在⼏秒内就能完成。
对于⼀些轻量级应⽤,我也使⽤过主从复制加⼿动故障转移的⽅案。主节点负责读写操作,
从节点负责读操作。⼿动故障转移时,我们会先将从节点提升为主节点,然后重新配置其他
从节点。
# 1. 取消从节点身份
redis-cli -h <slave-ip> slaveof no one
# 2. 将其他从节点指向新的主节点
redis-cli -h <other-slave-ip> slaveof <new-master-ip> <port>
1. Java ⾯试指南(付费)收录的华为⼀⾯原题:说下 Redis 和 HashMap 的区别
No. 13 / 314
⾯渣逆袭 Redis篇第⼆版-让天下所有的⾯渣都能逆袭
2. Java ⾯试指南(付费)收录的字节跳动商业化⼀⾯的原题:Redis 和 MySQL 的
区别
3. Java ⾯试指南(付费)收录的农业银⾏⾯经同学 7 Java 后端⾯试原题:Redis
相关的基础知识
4. Java ⾯试指南(付费)收录的华为 OD ⾯经同学 1 ⼀⾯⾯试原题:Redis 的了
解, 部署⽅案?
5. Java ⾯试指南(付费)收录的农业银⾏⾯经同学 3 Java 后端⾯试原题:项⽬⾥
哪⾥⽤到了 Redis
6. Java ⾯试指南(付费)收录的 360 ⾯经同学 3 Java 后端技术⼀⾯⾯试原题:⽤
过 redis 吗 ⽤来⼲什么
7. Java ⾯试指南(付费)收录的招商银⾏⾯经同学 6 招银⽹络科技⾯试原题:了
解 MySQL、Redis 吗?
8. Java ⾯试指南(付费)收录的百度⾯经同学 1 ⽂⼼⼀⾔ 25 实习 Java 后端⾯试
原题:项⽬中什么地⽅使⽤了 redis 缓存,redis 为什么快?
9. Java ⾯试指南(付费)收录的国企零碎⾯经同学 9 ⾯试原题:数据库⽤什么多
(说了 Mysql 和 Redis)
10. Java ⾯试指南(付费)收录的荣耀⾯经同学 4 ⾯试原题:Redis和MySQL的区
别?
11. Java ⾯试指南(付费)收录的海康威视同学 4⾯试原题:Redis部署
12. Java ⾯试指南(付费)收录的华为 OD ⾯经同学 1 ⼀⾯⾯试原题:Redis 的了
解, 部署⽅案?
13. Java ⾯试指南(付费)收录的同学 30 腾讯⾳乐⾯试原题:redis的部署⽅式都
有哪些呢,各⾃有什么优缺点?
2.Redis 可以⽤来⼲什么?
Redis 可以⽤来做缓存,⽐如说把⾼频访问的⽂章详情、商品信息、⽤户信息放⼊ Redis 当
中,并通过设置过期时间来保证数据⼀致性,这样就可以减轻数据库的访问压⼒。
No. 14 / 314
⾯渣逆袭 Redis篇第⼆版-让天下所有的⾯渣都能逆袭
Redis 的 Zset 还可以⽤来实现积分榜、热搜榜,通过 score 字段进⾏排序,然后取前 N 个元
素,就能实现 TOPN 的榜单功能。
No. 15 / 314
⾯渣逆袭 Redis篇第⼆版-让天下所有的⾯渣都能逆袭
利⽤ Redis 的 SETNX 命令或者 Redisson 还可以实现分布式锁,确保同⼀时间只有⼀个节点
可以持有锁;为了防⽌出现死锁,可以给锁设置⼀个超时时间,到期后⾃动释放;并且最好
开启⼀个监听线程,当任务尚未完成时给锁⾃动续期。
No. 16 / 314
⾯渣逆袭 Redis篇第⼆版-让天下所有的⾯渣都能逆袭
如果是秒杀接⼝,还可以使⽤ Lua 脚本来实现令牌桶算法,限制每秒只能处理 N 个请求。
-- KEYS[1]: 令牌桶的key
-- ARGV[1]: 桶容量
-- ARGV[2]: 令牌⽣成速率(每秒)
-- ARGV[3]: 当前时间戳(秒)
local bucket = redis.call('HMGET', KEYS[1], 'tokens', 'timestamp')
local tokens = tonumber(bucket[1]) or ARGV[1]
local last_time = tonumber(bucket[2]) or ARGV[3]
local rate = tonumber(ARGV[2])
local capacity = tonumber(ARGV[1])
local now = tonumber(ARGV[3])
-- 计算新令牌数
No. 17 / 314
⾯渣逆袭 Redis篇第⼆版-让天下所有的⾯渣都能逆袭
local delta = math.max(0, now - last_time)
local add_tokens = delta * rate
tokens = math.min(capacity, tokens + add_tokens)
last_time = now
local allowed = 0
if tokens >= 1 then
tokens = tokens - 1
allowed = 1
end
redis.call('HMSET', KEYS[1], 'tokens', tokens, 'timestamp', last_time)
redis.call('EXPIRE', KEYS[1], 3600) -- 过期时间可⾃定义
return allowed
在 Java 中调⽤ Lua 脚本:
// 令牌桶参数
int capacity = 10; // 桶容量
int rate = 2; // 每秒2个令牌
long now = System.currentTimeMillis() / 1000;
String key = "token_bucket:user:123";
// 调⽤ Lua 脚本,返回 1 表示通过,0 表示被限流
Long allowed = (Long) redis.eval(luaScript, 1, key,
String.valueOf(capacity), String.valueOf(rate), String.valueOf(now));
1. Java ⾯试指南(付费)收录的农业银⾏⾯经同学 7 Java 后端⾯试原题:Redis
相关的基础知识
2. Java ⾯试指南(付费)收录的字节跳动同学 7 Java 后端实习⼀⾯的原题:讲⼀
下为什么要⽤ Redis 去存权限列表?
3. Java ⾯试指南(付费)收录的字节跳动同学 20 测开⼀⾯的原题:redis 有什么
好处,为什么⽤ redis
No. 18 / 314
⾯渣逆袭 Redis篇第⼆版-让天下所有的⾯渣都能逆袭
memo:2025 年 4 ⽉ 28 ⽇修改⾄此,今天帮球友修改简历的时候,碰到⼀位东南⼤学本硕
连读的球友,星球能来这么多优秀的球友,真的很开⼼啊。
3. Redis有哪些数据类型?
Redis ⽀持五种基本数据类型,分别是字符串、列表、哈希、集合和有序集合。
No. 19 / 314
⾯渣逆袭 Redis篇第⼆版-让天下所有的⾯渣都能逆袭
还有三种扩展数据类型,分别是⽤于位级操作的 Bitmap、⽤于基数估算的 HyperLogLog、⽀
持存储和查询地理坐标的 GEO。
详细介绍下字符串?
字符串是最基本的数据类型,可以存储⽂本、数字或者⼆进制数据,最⼤容量是 512 MB。
适合缓存单个对象,⽐如验证码、token、计数器等。
详细介绍下列表?
列表是⼀个有序的元素集合,⽀持从头部或尾部插⼊/删除元素,常⽤于消息队列或任务列
表。
详细介绍下哈希?
No. 20 / 314
⾯渣逆袭 Redis篇第⼆版-让天下所有的⾯渣都能逆袭
哈希是⼀个键值对集合,适合存储对象,如商品信息、⽤户信息等。⽐如说 value =
{name: '沉默王⼆', age: 18} 。
详细介绍下集合?
集合是⽆序且不重复的,⽀持交集、并集操作,查询效率能达到 O(1) 级别,主要⽤于去
重、标签、共同好友等场景。
No. 21 / 314
⾯渣逆袭 Redis篇第⼆版-让天下所有的⾯渣都能逆袭
详细介绍下有序集合?
有序集合的元素按分数进⾏排序,⽀持范围查询,适⽤于排⾏榜或优先级队列。
详细介绍下Bitmap?
Bitmap 可以把⼀组⼆进制位紧凑地存储在⼀块连续内存中,每⼀位代表⼀个对象的状态,⽐
如是否签到、是否活跃等。
No. 22 / 314
⾯渣逆袭 Redis篇第⼆版-让天下所有的⾯渣都能逆袭
⽐如⽤户 0 的已签到 1、⽤户 1 未签到 0、⽤户 2 已签到,Redis 就会把这些状态放进⼀个连
续的⼆进制串 101 ,1 亿⽤户签到仅需 100,000,000 / 8 / 1024 ≈ 12MB 的空间,真的省
到离谱。
详细介绍下HyperLogLog?
HyperLogLog 是⼀种⽤于基数统计的概率性数据结构,可以在仅有 12KB 的内存空间下,统
计海量数据集中不重复元素的个数,误差率仅 0.81%。
底层基于 LogLog 算法改进,先把每个元素哈希成⼀个⼆进制串,然后取前 14 位进⾏分组,
放到 16384 个桶中,记录每组最⼤的前导零数量,最后⽤⼀个近似公式推算出总体的基数。
No. 23 / 314
⾯渣逆袭 Redis篇第⼆版-让天下所有的⾯渣都能逆袭
$2^{14}$个桶,每个桶 6 Bit,刚好 16384 * 6 /8 / 1024 K = 12KB ,8 bit = 1
byte。
举个超简单的例⼦,假设有⼀个神奇的哈希函数,可以把元素散列成⼀个⼆进制数,⽐如:
元素 哈希值 前导零个数
userA 000100101… 3
userB 001010011… 2
userC 000000101… 6
可以发现,哈希值越⻓前导零越多,也就说明集合⾥的元素越多。
⼤型⽹站 UV 统计系统示例:
No. 24 / 314
⾯渣逆袭 Redis篇第⼆版-让天下所有的⾯渣都能逆袭
public class UVCounter {
private Jedis jedis;
public void recordVisit(String date, String userId) {
String key = "uv:" + date;
jedis.pfadd(key, userId);
}
public long getUV(String date) {
return jedis.pfcount("uv:" + date);
}
public long getUVBetween(String startDate, String endDate) {
List<String> keys = getDateKeys(startDate, endDate);
return jedis.pfcount(keys.toArray(new String[0]));
}
}
详细介绍下GEO?
GEO ⽤于存储和查询地理位置信息,可以⽤来计算两点之间的距离,查找某位置半径内的其
他元素。
常⻅的应⽤场景包括:附近的⼈或者商家、计算外卖员和商家的距离、判断⽤户是否进⼊某
个区域等。
底层基于 ZSet 实现,通过 Geohash 算法把经纬度编码成 score。
No. 25 / 314
⾯渣逆袭 Redis篇第⼆版-让天下所有的⾯渣都能逆袭
⽐如说查询附近的商家时,Redis 会根据中⼼点经纬度反推可能的 Geohash 范围,
在 ZSet 上做范围查询,拿到候选点后,⽤ Haversine 公式精确计算球⾯距离,筛选出最终符
合要求的位置。
public class NearbyShopService {
private Jedis jedis;
private static final String SHOP_KEY = "shops:geo";
// 添加商铺
public void addShop(String shopId, double longitude, double
latitude) {
jedis.geoadd(SHOP_KEY, longitude, latitude, shopId);
}
// 查询附近的商铺
public List<GeoRadiusResponse> getNearbyShops(
double longitude,
double latitude,
No. 26 / 314
⾯渣逆袭 Redis篇第⼆版-让天下所有的⾯渣都能逆袭
double radiusKm) {
return jedis.georadius(SHOP_KEY,
longitude,
latitude,
radiusKm,
GeoUnit.KM,
GeoRadiusParam.geoRadiusParam()
.withCoord()
.withDist()
.sortAscending()
.count(20));
}
// 计算两个商铺之间的距离
public double getShopDistance(String shop1Id, String shop2Id) {
return jedis.geodist(SHOP_KEY,
shop1Id,
shop2Id,
GeoUnit.KILOMETERS);
}
}
为什么使⽤ hash 类型⽽不使⽤ string 类型序列化存储?
Hash 可以只读取或者修改某⼀个字段,⽽ String 需要⼀次性把整个对象取出来。
No. 27 / 314
⾯渣逆袭 Redis篇第⼆版-让天下所有的⾯渣都能逆袭
⽐如说有⼀个⽤户对象 user = {name: '沉默王⼆', age: 18} ,如果使⽤ Hash 存储,可以
直接修改 age 字段:
redis.hset("user:1", "age", 19);
如果使⽤ String 存储,需要先取出整个对象,修改后再存回去:
No. 28 / 314
⾯渣逆袭 Redis篇第⼆版-让天下所有的⾯渣都能逆袭
String userJson = redis.get("user:1");
User user = JSON.parseObject(userJson, User.class);
user.setAge(19);
redis.set("user:1", JSON.toJSONString(user));
1. Java ⾯试指南(付费)收录的字节跳动商业化⼀⾯的原题:说说 Redis 的
zset,什么是跳表,插⼊⼀个节点要构建⼏层索引
2. Java ⾯试指南(付费)收录的字节跳动⾯经同学 9 ⻜书后端技术⼀⾯⾯试原
题:Redis 的数据类型,ZSet 的实现
3. Java ⾯试指南(付费)收录的⼩⽶暑期实习同学 E ⼀⾯⾯试原题:你对 Redis
了解多少,说说常⻅的数据结构和应⽤场景
4. Java ⾯试指南(付费)收录的腾讯⾯经同学 23 QQ 后台技术⼀⾯⾯试原题:
Redis 的数据类型
5. Java ⾯试指南(付费)收录的快⼿⾯经同学 7 Java 后端技术⼀⾯⾯试原题:说
⼀下 Redis 常⽤的数据结构
6. Java ⾯试指南(付费)收录的农业银⾏⾯经同学 7 Java 后端⾯试原题:Redis
相关的基础知识
7. Java ⾯试指南(付费)收录的华为⾯经同学 11 ⾯试原题:项⽬中使⽤了
redis,redis 有哪些数据类型?分别使⽤的场景是什么?什么使⽤ hash 类型⽽
不使⽤ string 类型序列化存储?
8. Java ⾯试指南(付费)收录的 OPPO ⾯经同学 1 ⾯试原题:Redis常⻅数据结
构
9. Java ⾯试指南(付费)收录的美团同学 9 ⼀⾯⾯试原题:redis的数据结构类
型?
10. Java ⾯试指南(付费)收录的阿⾥云⾯经同学 22 ⾯经:redis⾼级数据结构的
使⽤场景
11. Java ⾯试指南(付费)收录的腾讯⾯经同学 29 Java 后端⼀⾯原题:Redis保证
incr命令原⼦性的原理是什么?
memo:2025 年 4 ⽉ 29 ⽇修改⾄此,今天有球友发信息说拿到了亚⻢逊的 offer,⼯资还给
的很⾼,问我要不要选? 真的恭喜了 。
No. 29 / 314
⾯渣逆袭 Redis篇第⼆版-让天下所有的⾯渣都能逆袭
No. 30 / 314