Java面试宝典

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中提供了两种数据持久化的方式:1RDB 2AOF

        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. Springbean的生命周期

         通过一个类(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 惰性队列,惰性队列的好处主要是
接收到消息后直接存入磁盘而非内存
消费者要消费消息时才会从磁盘中读取并加载到内存 支持数百万条的消息存储

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值