开始学习Java面试专题(day1),还想问问大家27届现在做完力扣100和苍穹外卖还需要做什么呢
Java面试专题
职业技能:
springboot + ssm + redis + 数据库 ::其他技术(微服务、ES、MQ、源码、高并发、JVM、技术选型、设计能力
比如(要针对性的写一些):
1.熟练使用Redis等非关系型数据库 ❌
2.精通Redis,深入理解Redis线程模型以及Redis的核心数据结构和使用场景,熟悉多级缓存架构,比如:缓存雪崩、穿透、击穿、双写一致、缓存失效等;自主搭建过Redis高可用集群✔
Redis
使用场景:
flowchart TD
A[使用场景]
B[缓存]
C[分布式锁]
D[计数器]
E[保存token]
F[消息队列]
G[延迟队列]
A --> B
A --> C
A --> D
A --> E
A --> F
A --> G
H[穿透、击穿、雪崩<br>双写一致、持久化<br>数据过期、淘汰策略]
I[setnx、redisson]
J[数据类型]
B --> H
C --> I
E --> J
F --> J
G --> J
- Redis的数据持久化策略有哪些
- 什么是缓存穿透,怎么解决
- 什么是布隆过滤器
- 什么是缓存击穿,怎么解决
- 什么是缓存雪崩,怎么解决
- redis双写问题
- Redis分布式锁如何实现
- Redis实现分布式锁如何合理的控制锁的有效时长
- Redis的数据过期策略有哪些
- Redis的数据淘汰策略有哪些
其他面试题:
flowchart TD
A[其他面试题]
B[集群]
C[事务]
D[Redis为什么快]
A --> B
A --> C
A --> D
E[主从 哨兵 集群]
B --> E
- Redis集群有哪些方案,知道嘛
- 什么是Redis主从同步
- 你们使用Redis是单点还是集群?哪种集群
- Redis分片集群中数据是怎么存储和读取的
- redis集群脑裂
- 怎么保证redis的高并发高可用
- 你们用过Redis的事务吗?事务的命令有哪些
- Redis是单线程的,但是为什么还那么快?
一、使用场景
- 我看你做的项目中,都用到了redis,你在最近的项目中哪些场景使用了redis呢?
结合项目
●一是验证你的项目场景的真实性,二是为了作为深入发问的切入点
● 缓存:缓存三兄弟(穿透、击穿、雪崩)、双写一致、持久化、数据过期策略,数据淘汰策略
●分布式锁:setnx, redisson
●消息队列、延迟队列:何种数据类型
- 如果发生了缓存穿透、击穿、雪崩,该如何解决?
1.缓存-缓存穿透
例:一个get请求:api/news/getById/1
缓存穿透:查询一个不存在的数据,MySQL查询不到数据也不会直接写入缓存,就会导致每次请求都查数据库。
为什么会这样呢?:通常是有人恶意攻击你的系统
-
解决方案一:缓存空数据,查询返回的数据为空,仍把这个空结果进行缓存
{key:1, value:null优点:简单
缺点:消耗内存,可能会发生不一致的问题(比如id为1,一开始为空,缓存;但后来有值了,就不一致)
-
解决方案二:布隆过滤器
优点:内存占用较少,没有多余key
缺点:实现复杂,存在误判
布隆过滤器
bitmap(位图):相当于是一个以**(bit)位**为单位的数组,数组中每个单元只能存储二进制数0或1
布隆过滤器作用:布隆过滤器可以用于检索一个元素是否在一个集合中。
初始都为0
存在误判:
误判率:数组越小误判率就越大,数组越大误判率就越小,但同时也带来了更多的内存消耗。
!误判率不可能不存在
布隆过滤器实现方案:Redisson、Guava
添加数据时,可设置误判率0.05,5%以内的误判率一般的项目也能接受,不至于高并发下压倒数据库。
总结:
- Redis的使用场景
● 根据自己简历上的业务进行回答
● 缓存 : 穿透、击穿、雪崩、双写一致、持久化、数据过期、淘汰策略
● 分布式锁 : setnx, redisson
- 什么是缓存穿透,怎么解决
● 缓存穿透:查询一个不存在的数据,mysql查询不到数据也不会直接写入缓存,就会导致每次请求都查数据库
● 解决方案一:缓存空数据
● 解决方案二:布隆过滤器
2.缓存-缓存击穿
**缓存击穿:**给某一个key设置了过期时间,当key过期的时候,恰好这时间点对这个key有大量的并发请求过来,这些并发的请求可能会瞬间把DB压垮
缓存重建可能会消耗时间(有时候多个表汇总的结果),然后一直请求数据库
-
解决方案一:互斥锁(分布式锁)
强一致、性能差
比如与钱相关的业务
-
解决方案二:逻辑过期
高可用、性能优
互联网行业
不设置过期时间,那怎么判断过期?:存储数据时新增一个过期时间的字段
key value 1 {"id":"123", "title":"sncjskdh", "expire":153213455}
总结:
● 缓存击穿:给某一个key设置了过期时间,当key过期的时候,恰好这时间点对这个key有大量的并发请求过来,这些并发的请求可能会瞬间把DB压垮
● 解决方案一:互斥锁,强一致,性能差
● 解决方案二:逻辑过期,高可用,性能优,不能保证数据绝对一致
3.缓存-缓存雪崩
缓存雪崩是指在同一时段大量的缓存key同时失效或者Redis服务宕机,导致大量请求到达数据库,带来巨大压力。
大量key过期:采用了相同的过期时间
解决方案:
- 给不同的key的TTL (生存时间)添加随机值
- 利用Redis集群提高服务的可用性 (哨兵模式、集群模式)
- 给缓存业务添加降级限流策略 (nginx或spring cloud gateway)
降级可做为系统的保底策略,适用于穿透、击穿、雪崩
- 给业务添加多级缓存 (Guava或Caffeine)
与缓存击穿的区别:雪崩是很多key,击穿是某一个key
4.缓存-双写一致性
- redis作为缓存,MySQL的数据如何与redis进行同步呢?(双写一致性)
!!!一定要设置前提,先介绍自己的业务背景(因为有两种业务情况)
- 一致性要求高
- 允许延迟一致
双写一致性:当修改了数据库的数据也要同时更新缓存的数据,缓存和数据库的数据要保持一致
- 读操作:缓存命中,直接返回;缓存未命中查询数据库,写入缓存,设定超时时间
- 写操作:延迟双删
有脏数据的风险,做不到强一致!!
1.先删除缓存,还是先修改数据库(其实都会有问题)
初始:缓存:10;数据库:10
- 先删除缓存,再操作数据库
正常情况下:缓存:20;数据库:20
有问题时:缓存:10;数据库:20(脏数据)
将还没修改的10写入了缓存
- 先操作数据库,再删除缓存
正常情况下:缓存:20;数据库:20
有问题时:缓存:10;数据库:20
查询时缓存过期
2.为什么要删除两次缓存?
-降低脏数据的出现
3.为什么要延时删除?
-因为主从数据库架构
为了对抗主从复制延迟,防止旧数据被重新写入缓存,从而保证系统的最终一致性。
一般放入缓存中的数据,都是读多写少
- 共享锁:读锁readLock,加锁之后,其他线程可以共享读操作
- 排他锁:独占锁writeLock也叫,加锁之后,阻塞其他线程读写操作
强一致、性能低
异步通知保证数据的最终一致性
允许延时:
-
MQ:
-
canal:
canal是基于MySQL的主从同步来实现的
二进制日志(BINLOG)记录了所有的DDL(数据定义语言)语句和DML(数据操纵语言)语句,但不包括数据查询(SELECT、SHOW)语句。
总结:
- redis做为缓存,mysql的数据如何与redis进行同步呢?(双写一致性)
-
介绍自己简历上的业务,我们当时是把文章的热点数据存入到了缓存中,虽然是热点数据,但是实时 要求性并没有那么高,所以,我们当时采用的是异步的方案同步的数据
-
我们当时是把抢券的库存存入到了缓存中,这个需要实时的进行数据同步,为了保证数据的强一致, 我们当时采用的是redisson提供的读写锁来保证数据的同步
- 那你来介绍一下异步的方案(你来介绍一下redisson读写锁的这种方案)
● 允许延时一致的业务,采用异步通知
- 使用MQ中间件,更新数据之后,通知缓存删除(要保证MQ的可靠性)
- 利用canal中间件,不需要修改业务代码,伪装为mysql的一个从节点,canal通过读取binlog数据更新缓存
- 延时双删
● *强一致性的,*采用Redisson提供的读写锁
- 共享锁:读锁readLock,加锁之后,其他线程可以共享读操作
- 排他锁:独占锁writeLock也叫,加锁之后,阻塞其他线程读写操作
二、分布式锁
三、其他面试问题
#数据人的面试交流地##笔试##简历中的项目经历要怎么写##大厂面试问八股多还是项目多?##一人推荐一个值得做的项目#开始看黑马Java面试,27届的,大家有什么建议欢迎来说哟