Java经典面试,【Java面试题总结 14

  1. 不用考虑各种锁的问题,不存在加锁和释放锁的操作,没有因为可能出现死锁而导致的性能问题;

  2. 不存在多线程切换而消耗CPU;

  3. 无法发挥多核CPU的优势,但可以采用多开几个Redis实例来完善;

七、Redis真的是单线程的吗?


Redis6.0之前是单线程的,Redis6.0之后开始支持多线程;

redis内部使用了基于epoll的多路服用,也可以多部署几个redis服务器解决单线程的问题;

redis主要的性能瓶颈是内存和网络;

内存好说,加内存条就行了,而网络才是大麻烦,所以redis6内存好说,加内存条就行了;

而网络才是大麻烦,所以redis6.0引入了多线程的概念,

redis6.0在网络IO处理方面引入了多线程,如网络数据的读写和协议解析等,需要注意的是,执行命令的核心模块还是单线程的。

八、Redis持久化有几种方式?


redis提供了两种持久化的方式,分别是RDB(Redis DataBase)和AOF(Append Only File)。

RDB,简而言之,就是在不同的时间点,将redis存储的数据生成快照并存储到磁盘等介质上;

AOF,则是换了一个角度来实现持久化,那就是将redis执行过的所有写指令记录下来,在下次redis重新启动时,只要把这些写指令从前到后再重复执行一遍,就可以实现数据恢复了。

其实RDB和AOF两种方式也可以同时使用,在这种情况下,如果redis重启的话,则会优先采用AOF方式来进行数据恢复,这是因为AOF方式的数据恢复完整度更高。

如果你没有数据持久化的需求,也完全可以关闭RDB和AOF方式,这样的话,redis将变成一个纯内存数据库,就像memcache一样。

九、Redis和 memecache 有什么区别?


1、Redis相比memecache,拥有更多的数据结构和支持更丰富的数据操作。

(1)Redis支持key-value,常用的数据类型主要有String、Hash、List、Set、Sorted Set。

(2)memecache只支持key-value。

2、内存使用率对比,Redis采用hash结构来做key-value存储,由于其组合式的压缩,其内存利用率会高于memecache。

3、性能对比:Redis只使用单核,memecache使用多核。

4、Redis支持磁盘持久化,memecache不支持。

Redis可以将一些很久没用到的value通过swap方法交换到磁盘。

5、Redis支持分布式集群,memecache不支持。

十、Redis支持的 java 客户端都有哪些?


Redisson、Jedis、lettuce 等等,官方推荐使用 Redisson。

十一、jedis 和 redisson 有哪些区别?


Jedis 和 Redisson 都是Java中对Redis操作的封装。Jedis 只是简单的封装了 Redis 的API库,可以看作是Redis客户端,它的方法和Redis 的命令很类似。Redisson 不仅封装了 redis ,还封装了对更多数据结构的支持,以及锁等功能,相比于Jedis 更加大。但Jedis相比于Redisson 更原生一些,更灵活。

十二、什么是缓存穿透?怎么解决?


1、缓存穿透

一般的缓存系统,都是按照key去缓存查询,如果不存在对用的value,就应该去后端系统查找(比如DB数据库)。一些恶意的请求会故意查询不存在的key,请求量很大,就会对后端系统造成很大的压力。这就叫做缓存穿透。

2、怎么解决?

对查询结果为空的情况也进行缓存,缓存时间设置短一点,或者该key对应的数据insert之后清理缓存。

对一定不存在的key进行过滤。可以把所有的可能存在的key放到一个大的Bitmap中,查询时通过该Bitmap过滤。

3、缓存雪崩

当缓存服务器重启或者大量缓存集中在某一时间段失效,这样在失效的时候,会给后端系统带来很大的压力,导致系统崩溃。

4、如何解决?

  1. 在缓存失效后,通过加锁或者队列来控制读数据库写缓存的线程数量。比如对某个key只允许一个线程查询数据和写缓存,其它线程等待;

  2. 做二级缓存;

  3. 不同的key,设置不同的过期时间,让缓存失效的时间尽量均匀;

十三、怎么保证缓存和数据库数据的一致性?


1、淘汰缓存

数据如果为较为复杂的数据时,进行缓存的更新操作就会变得异常复杂,因此一般推荐选择淘汰缓存,而不是更新缓存。

2、选择先淘汰缓存,再更新数据库

假如先更新数据库,再淘汰缓存,如果淘汰缓存失败,那么后面的请求都会得到脏数据,直至缓存过期。

假如先淘汰缓存再更新数据库,如果更新数据库失败,只会产生一次缓存穿透,相比较而言,后者对业务则没有本质上的影响。

3、延时双删策略

如下场景:同时有一个请求A进行更新操作,另一个请求B进行查询操作。

  1. 请求A进行写操作,删除缓存

  2. 请求B查询发现缓存不存在

  3. 请求B去数据库查询得到旧值

  4. 请求B将旧值写入缓存

  5. 请求A将新值写入数据库

次数便出现了数据不一致问题。采用延时双删策略得以解决。


public void write(String key,Object data){

    redisUtils.del(key);

    db.update(data);

    Thread.Sleep(100);

    redisUtils.del(key);

}

这么做,可以将1秒内所造成的缓存脏数据,再次删除。这个时间设定可根据俄业务场景进行一个调节。

4、数据库读写分离的场景

两个请求,一个请求A进行更新操作,另一个请求B进行查询操作。

  1. 请求A进行写操作,删除缓存

  2. 请求A将数据写入数据库了,

  3. 请求B查询缓存发现,缓存没有值

  4. 请求B去从库查询,这时,还没有完成主从同步,因此查询到的是旧值

  5. 请求B将旧值写入缓存

  6. 数据库完成主从同步,从库变为新值

依旧采用延时双删策略解决此问题。

十四、Redis,什么是缓存穿透?怎么解决?


1、缓存穿透

一般的缓存系统,都是按照key去缓存查询,如果不存在对用的value,就应该去后端系统查找(比如DB数据库)。一些恶意的请求会故意查询不存在的key,请求量很大,就会对后端系统造成很大的压力。这就叫做缓存穿透。

2、怎么解决?

对查询结果为空的情况也进行缓存,缓存时间设置短一点,或者该key对应的数据insert之后清理缓存。

对一定不存在的key进行过滤。可以把所有的可能存在的key放到一个大的Bitmap中,查询时通过该Bitmap过滤。

3、缓存雪崩

当缓存服务器重启或者大量缓存集中在某一时间段失效,这样在失效的时候,会给后端系统带来很大的压力,导致系统崩溃。

4、如何解决?

  1. 在缓存失效后,通过加锁或者队列来控制读数据库写缓存的线程数量。比如对某个key只允许一个线程查询数据和写缓存,其它线程等待;

  2. 做二级缓存;

  3. 不同的key,设置不同的过期时间,让缓存失效的时间尽量均匀;

十五、Redis怎么实现分布式锁?


使用Redis实现分布式锁

redis命令:set users 10 nx ex 12   原子性命令


//使用uuid,解决锁释放的问题

@GetMapping

public void testLock() throws InterruptedException {

    String uuid = UUID.randomUUID().toString();

    Boolean b_lock = redisTemplate.opsForValue().setIfAbsent("lock", uuid, 10, TimeUnit.SECONDS);

    if(b_lock){

        Object value = redisTemplate.opsForValue().get("num");

        if(StringUtils.isEmpty(value)){

            return;

        }

        int num = Integer.parseInt(value + "");

        redisTemplate.opsForValue().set("num",++num);

        Object lockUUID = redisTemplate.opsForValue().get("lock");

        if(uuid.equals(lockUUID.toString())){

            redisTemplate.delete("lock");

        }

    }else{

        Thread.sleep(100);

        testLock();

    }

}

备注:可以通过lua脚本,保证分布式锁的原子性。

十六、Redis分布式锁有什么缺陷?


Redis 分布式锁不能解决超时的问题,分布式锁有一个超时时间,程序的执行如果超出了锁的超时时间就会出现问题。

Redis容易产生的几个问题:

  1. 锁未被释放

  2. B锁被A锁释放了

  3. 数据库事务超时

  4. 锁过期了,业务还没执行完

面试资料整理汇总

成功从小公司跳槽进蚂蚁定级P7,只因刷了七遍这些面试真题

成功从小公司跳槽进蚂蚁定级P7,只因刷了七遍这些面试真题

这些面试题是我朋友进阿里前狂刷七遍以上的面试资料,由于面试文档很多,内容更多,没有办法一一为大家展示出来,所以只好为大家节选出来了一部分供大家参考,需要全部文档的,关注小编后,点击这里即可免费领取

面试的本质不是考试,而是告诉面试官你会做什么,所以,这些面试资料中提到的技术也是要学会的,不然稍微改动一下你就凉凉了

Redis容易产生的几个问题:

  1. 锁未被释放

  2. B锁被A锁释放了

  3. 数据库事务超时

  4. 锁过期了,业务还没执行完

面试资料整理汇总

[外链图片转存中…(img-sM33ygGX-1628289407089)]

[外链图片转存中…(img-56ornyG7-1628289407091)]

这些面试题是我朋友进阿里前狂刷七遍以上的面试资料,由于面试文档很多,内容更多,没有办法一一为大家展示出来,所以只好为大家节选出来了一部分供大家参考,需要全部文档的,关注小编后,点击这里即可免费领取

面试的本质不是考试,而是告诉面试官你会做什么,所以,这些面试资料中提到的技术也是要学会的,不然稍微改动一下你就凉凉了

在这里祝大家能够拿到心仪的offer!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值