首页 简历|笔试面试
您现在的位置:百分网 > 职场 > 笔试面试 > 综合

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

  • 25年9月4日 发布
  • 68.4MB 共313页
面渣逆袭Redis篇V2.0(暗黑版)面渣逆袭Redis篇V2.0(暗黑版)面渣逆袭Redis篇V2.0(暗黑版)面渣逆袭Redis篇V2.0(暗黑版)面渣逆袭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

开通会员 本次下载免费

所有资料全部免费下载! 推荐用户付费下载获取返佣积分! 积分可以兑换商品!
普通用户: 7.37元
网站会员:
本次下载免费

开通网站会员 享专属特权

  • 会员可免费

    下载全部资料!

  • 推荐用户下载

    获取返佣积分!

  • 积分可以

    兑换商品!

一键复制 下载文档 联系客服