Redis部分
1.什么是缓存穿透 ? 怎么解决
缓存穿透是指查询一个一定不存在 的数据,如果从存储层查不到数据则不写入缓存,这将导致这个不存在的数据每次请求都要到 DB 去查询,可能导致 DB 挂掉。这种情况大概率是遭到了攻击。解决方案的话,我们通常都会用布隆过滤器来解决它
2. 介绍一下布隆过滤器吗
布隆过滤器主要是用于检索一个元素是否在一个集合中。我们当时使用的是 redisson实现的布隆过滤器。 它的底层主要是先去初始化一个比较大数组,里面存放的二进制0 或 1 。在一 开始都是0 ,当一个 key 来了之后经过 3 次 hash 计算,模于数组长度找到数据 的下标然后把数组中原来的0 改为 1 ,这样的话,三个数组的位置就能标明一 个key 的存在。查找的过程也是一样的。当然是有缺点的,布隆过滤器有可能会产生一定的误判,我们一般可以设置 这个误判率,大概不会超过5% ,其实这个误判是必然存在的,要不就得增 加数组的长度,其实已经算是很划分了,5% 以内的误判率一般的项目也能接受,不至于高并发下压倒数据库。
3. 什么是缓存击穿 ? 怎么解决 ?
缓存击穿的意思是对于设置了过期时间的key ,缓存在某个时间点过期的时候,恰好这时间点对这个Key 有大量的并发请求过来,这些请求发现缓存过期一般都会从后端 DB 加载数据并回设到缓存,这个时候大并发的请求可能会瞬间把 DB 压垮解决方案有两种方式:第一可以使用互斥锁:当缓存失效时,不立即去load db ,先使用如 Redis 的setnx 去设置一个互斥锁,当操作成功返回时再进行 load db的操作并回设缓存,否则重试get缓存的方法第二种方案可以设置当前key 逻辑过期,大概是思路如下:①:在设置 key 的时候,设置一个过期时间字段一块存入缓存中,不给当前key设置过期时间②:当查询的时候,从 redis 取出数据后判断时间是否过期③:如果过期则开通另外一个线程进行数据同步,当前线程正常返回数据,这个数据不是最新当然两种方案各有利弊:如果选择数据的强一致性,建议使用分布式锁的方案,性能上可能没那么高,锁需要等,也有可能产生死锁的问题如果选择key的逻辑删除,则优先考虑的高可用性,性能比较高,但是数据 同步这块做不到强一致
4.什么是缓存雪崩 ? 怎么解决 ?
缓存雪崩意思是设置缓存时采用了相同的过期时间,导致缓存在某一时刻同 时失效,请求全部转发到DB, DB 瞬时压力过重雪崩。解决方案:主要是可以将缓存失效时间分散开,比如可以在原有的失效时间基 础上增加一个随机值,比如1-5 分钟随机,这样每一个缓存的过期时间的重 复率就会降低,就很难引发集体失效的事件
5. redis做为缓存,mysql的数据如何与redis进行同步呢?(双写一致性)
我们采用的是redisson实现的读写锁,在读的时候添加共享锁,可以保证读 读不互斥,读写互斥。当我们更新数据的时候,添加排他锁,它是读写,读读都互斥,这样就能保证在写数据的同时是不会让其他线程读数据的,避免了脏数据。这里面需要注意的是读方法和写方法上需要使用同一把锁才行。
6. 你听说过延时双删吗?为什么不用它呢?
延迟双删,如果是写操作,我们先把缓存中的数据删除,然后更新 数据库,最后再延时删除缓存中的数据,其中这个延时多久不太好确定,在 延时的过程中可能会出现脏数据,并不能保证强一致性,所以没有采用它。
7.redis做为缓存,数据的持久化是怎么做的?
在Redis中提供了两种数据持久化的方式:1、RDB 2、AOF
RDB是一个快照文件,它是把 redis 内存存储的数据写到磁盘上,当 redis实例宕机恢复数据的时候,方便从 RDB 的快照文件中恢复数据。AOF的含义是追加文件,当 redis 操作写命令的时候,都会存储这个文件中, 当redis 实例宕机恢复数据的时候,会从这个文件中再次执行一遍命令来恢复 数据
8.Redis的数据过期策略有哪些 ?
第一种是惰性删除,在设置该key 过期时间后,我们不去管它,当需要该key 时,我们在检查其是否过期,如果过期,我们就删掉它,反之返回该key。第二种是 定期删除,就是说每隔一段时间,我们就对一些key 进行检查,删除里面过期的key
9.Redis的数据淘汰策略有哪些 ?
默认是不删除数据,但是可以在配置文件中设置删除策略 LRU(近期最少使用)和LFU(最少使用频率)
10.Redis集群有哪些方案, 知道嘛
主从复制、哨兵模式、Redis 分片集群
MySQL
1.MySQL中,如何定位慢查询?
两种方案:
1.可以使用监控系统去查看
2.mysql自己有一个慢日志查询功能,可以设置多少时间后记录到日志中
2. 那这个SQL语句执行很慢, 如何分析呢?
1.首先去看是否用了索引
2.索引是否失效了
3.是否进行了回表(尽量别回这个否则要问聚集索引)
3. mysql的存储引擎是什么
InnoDB
数据结构是B+树
和B树的的区别是B+树数据都在叶子节点,B树非叶子节点也会存
4. 事务的特性是什么?可以详细说一下吗?
ACID ,分别指的是:原子性、一致性、隔离 性、持久性;
5.如何解决并发事务带来的脏读,不可重复读,幻读
MySQL支持四种隔离级别,分别有:未提交读,读已提交,可重复读,串行化
Spring框架
1.什么是AOP
aop是面向切面编程,在 spring 中用于将那些与业务无关,但却对多个对象产 生影响的公共行为和逻辑,抽取公共模块复用,降低耦合,一般比如可以做为公共日志保存,事务处理等项目中如何使用就是使用aop 来记录了系统的操作日志 主要思路是这样的,使用 aop 中的环绕通知 + 切点表达式,这个表达式就是要 找到要记录日志的方法,然后通过环绕通知的参数获取请求方法的参数,比 如类信息、方法信息、注解、请求方式等,获取到这些参数以后,保存到数据库
2.Spring中的事务是如何实现的
spring中事务本质就是Aop,在方法前后进行拦截,执行方法之前开启事务,在执行完目标方法之后根据执行情况提交或者回滚事务。
3.spring事务失效场景
1.没有交给spring管理
2.方法不是public修饰
3.方法有异常没有抛出去
4.Transactional注解后面的属性配置有问题
4. Spring的bean的生命周期
通过一个类(BeanDefinition)这个类里记录了bean的所有信息包括全路径,是否延迟加载,是否是单例.
创建bean的时候,第一步是调用构造函数实例化bean
第二步:bean的依赖注入,@Autowire或者set方法
第三步:处理Aware接口,如果一个bean实现了Aware接口,就会重写方法执行
第四步:查看是否实现了Processor接口
第五步:初始化方法,比如实现initializatingBean
第六步:执行processor,对bean进行增强
第七步:销毁
5. SpringMVC的执行流程知道嘛
1 、用户发送出请求到前端控制器 DispatcherServlet ,这是一个调度中心2 、 DispatcherServlet 收到请求调用 HandlerMapping (处理器映射器)。3 、 HandlerMapping 找到具体的处理器 ( 可查找 xml 配置或注解配置 ) ,生成处理器对象及处理器拦截器( 如果有 ) ,再一起返回给 DispatcherServlet 。4 、 DispatcherServlet 调用 HandlerAdapter (处理器适配器)。5 、 HandlerAdapter 经过适配调用具体的处理器( Handler/Controller )。6 、 Controller 执行完成返回 ModelAndView 对象。 7 、 HandlerAdapter 将 Controller 执行结果 ModelAndView 返回给 DispatcherServlet。8 、 DispatcherServlet 将 ModelAndView 传给 ViewReslover (视图解析器)。9 、 ViewReslover 解析后返回具体 View (视图)。10 、 DispatcherServlet 根据 View 进行渲染视图(即将模型数据填充至视图中)。11 、 DispatcherServlet 响应用户。
6.Springboot自动配置原理
通过注解@SpringBootApplication
SpringCloud
1.五大组件
注册中心 / 配置中心 Nacos负载均衡 Ribbon服务调用 Feign服务保护 sentinel服务网关 Gateway
2.负载均衡如何实现的、
在服务调用过程中的负载均衡一般使用SpringCloud 的 Ribbon 组件实现 , Feign的底层已经自动集成了 Ribbon , 使用起来非常简单 当发起远程调用时,ribbon 先从注册中心拉取服务地址列表,然后按照一定的路由策略选择一个发起远程调用,一般的调用策略是轮询
3.Ribbon负载均衡策略有哪些 ?
RoundRobinRule :简单轮询服务列表来选择服务器 WeightedResponseTimeRule :按照权重来选择服务器,响应时间越长,权重越小RandomRule :随机选择一个可用的服务器ZoneAvoidanceRule :区域敏感策略,以区域可用的服务器为基础进行服务器的选择。使用 Zone 对服务器进行分类,这个 Zone 可以理解为一个机房、一个机架等。而后再对 Zone 内的多个服务做轮询 ( 默认 )
4.你们项目中有没有做过限流 ? 怎么做的 ?
我们当时采用的 nginx 限流操作, nginx 使用的漏桶算法来实现过滤,让请求以固定的速率处理请求,可以应对突发流量,我们控制的速率是按照 ip 进行限流,限制的流量是每秒 20
5.什么是CAP理论?
一致性、可用性、分区容错性(分布式系统基本要求)
6.什么是Base理论
base理论就是哪怕达不到强一致性 ,也要想办法达到最终一致性
RabbitMQ
1.如何保证消息不丢失
第一种:开启消息确认机制,确保生产者的消息能到达队列,如果报错可以先记录到日志中,再去修复数据
第二种:开启持久化,确保消息未消费前在队列中不会丢失,其中的交换机、队列、和消息都要做持久化第三种开启消费者确认机制自动确认
2. RabbitMQ消息的重复消费问题如何解决的
这个我们还真遇到过,是这样的,我们当时消费者是设置了自动确认机制,当服务还没来得及给MQ确认的时候,服务宕机了,导致服务重启之后,又消费了一次消息。这样就重复消费了因为我们当时处理的支付(订单| 业务唯一标识),它有一个业务的唯一标识,我们再处理消息时,先到数据库查询一下,这个数据是否存在,如果不存在,说明没有处理过,这个时候就可以正常处理这个消息了。如果已经存在这个数据了,就说明消息重复消费了,我们就不需要再消费了
其实这个就是典型的幂等的问题,比如, redis 分布式锁、数据库的锁都是可以的
3.RabbitMQ中死信交换机 ? (RabbitMQ延迟队列有了解过嘛)
延迟队列就是用到了死信交换机+TTL(消息存活时间)实现
如果消息超时没有被消费就会变成死信,在RabbitMQ中如果消息成为死信,队列中可以绑定一个死信交换机,在死信交换机上可以绑定其他队列,在我们发送消息的时候设置一个TTL就可以实现延迟队列
其实也可以简单一点:安装一个死信插件就可以了,只需要在声明交换机的时候指定这个就是死信交换机,然后发送消息的时候设置超时时间就可以了
4.出现消息堆积怎么办
1.提高消费者的消费能力,使用多线程消费任务
2.增加消费者,提高消费速度,使用工作队列模式,设置多个消费者消费同一个队列中的消息
3.扩大队列容积(
可以使用 RabbitMQ 惰性队列,惰性队列的好处主要是① 接收到消息后直接存入磁盘而非内存② 消费者要消费消息时才会从磁盘中读取并加载到内存 ③ 支持数百万条的消息存储)