首页 > 编程语言 >Java高频面试题

Java高频面试题

时间:2024-03-02 18:00:47浏览次数:22  
标签:面试题 缓存 Java 过期 redis 获取 线程 高频 分布式

Redis

一、Redis的使用场景

① 缓存  ② 分布式锁  ③限流  ④购物车  ⑤Token存储  ⑥点赞关注  ⑦短信验证码存储  ⑧分布式Session  ⑨发布订阅  ⑩排行榜

1、缓存

  热点数据(经常查询,但不修改和删除)首选redis,性能高。

 2、分布式锁

注:锁,即在多线程环境下,对共享资源的访问造成线程安全问题,通过锁的机制来实现资源访问互斥;比如Java语言有线程锁:synchronize / Lock 等。

 分布式锁:在分布式环境下,所有应集群部署,锁(互斥)的范围发生了改变;

分布式锁是一种用于分布式系统中实现同步访问共享资源的机制。在分布式系统中,多个节点需要协调合作完成某项任务时,为避免资源竞争和数据不一致问题,可以使用分布式锁来确保在某一时刻只有一个节点可以访问共享资源。

 redis分布式锁实现:① Jedis   ② Lttuce   ③ RedisTemplete   ④ Redisson   

一。命令实现:setnx(获取锁) ,expire(设置锁的过期时间),del(删除锁,释放锁)

1、获取锁:setnx  key value

2、设置锁的过期时间:expire  key  30

3、执行业务代码

4、删除锁:del  key

二、Redisson实现

1、获取锁:redisson.getLock("lock");

       lock.lock();

2、执行业务代码

3、释放锁:lock.unlock();

Redisson实现的分布式锁是可重入的吗?  

注:可重入?   即可重复获取,它是指线程T获取到锁A之后,线程T再次去获取锁A是可以获取到的,Java中的synchronized、ReentrantLock都是可重入锁。

Redisson实现的分布式锁是可重入锁

redis实现分布式锁需要注意的问题?

1、不是原子操作

因为redis获取锁和设置锁的过期时间不是原子操作,在极端情况下就可以会出现问题,如果在获取锁后,redis宕机了,这个时候锁是没有过期时间的,会导致这个锁一直无法释放的情况。所以需要将获取锁和设置锁的过期时间在一个命令下执行,保证原子性。

2、没有释放锁

如果在执行业务代码后,服务突然宕机了,这个时候锁是还没有释放的,所以在获取锁的时候一定要设置过期时间,这样就算服务宕机了,我们没有手动释放锁,也会因为我们设置了锁的过期时间而自动释放锁,如果没有设置过期时间,会导致其他线程一直获取不到锁。

3、释放了锁。但业务还没有执行完

因为redis实现的分布式锁默认过期时间是30秒,但如果业务代码执行完要35秒,但是锁已经释放了,剩下的5秒内如果有线程进来获取锁并执行业务代码,这时就会有两个线程来执行业务代码,这样就会导致数据不一致,比如在减库存的时候会出现超卖的情况。所以锁的过期时间要让续期,redis已经提供了,是锁的过期时间的1/3。

4、释放了别人的锁

当前有两个线程,线程A和线程B,如果设置锁的过期时间是30s,但执行业务代码要35s,并且没有设置锁的过期时间的续期,此时线程A在执行,但锁已经释放了,然后线程B进来执行,因为线程A的锁已经过期了,此时线程A释放的锁是线程B的,这样就产生了释放了别人的锁的情况。在实现分布式锁时,要求自己的锁要自己释放,不允许释放别人的锁。线程可以在获取锁的时候,生成一个唯一的id,然后把这个id设置到key的值里面去,当要释放锁的时候,去判断当前锁是不是当前线程设置的。

5、大量请求竞争锁失败

① 重试,让锁自旋,重试3~5次,每一次获取失败间隔50ms,如果超过5次,就返回获取锁失败。

② 让业务执行尽可能短

③ 限流处理

6、多节点Redis主从复制的问题

 假设当前有两个线程,线程A和线程B,并且当前redis是哨兵模式的主从复制,一主二从,当线程A去主服务器去获取key,并且将key同步到两个从节点,但是还没有复制,这个主服务器就宕机了,然后从服务器升级成主服务器,这个时候线程B就开始去这个新的主服务器去获取key,这样两个线程都获取到了锁,都会区执行业务代码,这样数据会有安全问题。可以使用redis提供的红锁来解决。

解决:红锁会向所有的redis节点加锁,但这种方法性能很低,也很复杂,如果要在redis集群环境下使用分布式锁,建议使用zookeeper来实现分布式锁。redis是保证AP,zookeeper是保证CP。

7、锁的性能问题

分段锁。

8、锁的可重入性

Redisson实现的分布式锁就具有可重入性。

3、Token存储

在现在的前后端分离的开发模式下,redis存储token很常见。

用户在前端登录成功后会生成token,并将token写入redis,并且前端也会将token进行保存,后续用户需要进行访问其他接口时,会携带token请求,在后端中经过过滤器,拦截器等校验,最后会判断当前token是否和登录成功时存入redis的token进行比较,一致则将结果返回到前端。

4、短信验证码存储

用户在前端点击发送验证码,在后台生成验证码之后,将验证码存入redis,并且将验证码发送给用户,用户输入验证码后发起请求,将用户输入的验证码和在redis里的验证码进行比对,一致则成功。

5、计数器

 6、全局唯一id

 7、排行榜

使用redis的Zset数据结构

放入一些数据

 将这些数据按score从高到低排序

 增加分数

 8、限流

redis可以配合lua脚本来对数据进行限流

 9、购物车

可以使用redis的hash结构来存储用户的购物车数据

 10、点赞关注

点赞可以使用redis的hash结构,关注可以使用redis的set结构。

 

二、缓存穿透,缓存击穿,缓存雪崩

1、缓存穿透

缓存穿透是由于请求一个不存在的数据而导致的;如果数据库或者redis被一直这样恶意请求一个不存在的数据,会造成数据库的访问压力过大,导致数据库响应过慢,严重甚至会导致数据库宕机。

 解决:

① 缓存空值。在缓存中,之所以会发生穿透,就是因为没有将那些不存在的值的key缓存下来,从而导致每次查询请求都要请求到数据库。所以就可以为这样key对应的值设置为null并放到缓存当中,这样再出现查询这个key的时候,直接返回null即可

② 布隆过滤器(BloomFilter)。布隆过滤器用于检索一个元素是否在一个集合中。它是采用一个很长的二进制数组,通过一系列的hash函数来确定该数据是否存在。

布隆过滤器是一种比较巧妙的概率性数据结构,它可以告诉你数据一定不存在或者可能存在,相比Map,Set,List等传统的数据结构它占用内存少、结构更高效。

布隆过滤器添加元素时,会使用多个hash函数对元素进行哈希,然后用数组的长度取余数,算出一个索引位置值,再把数组的位置值设置为1,这样就完成了元素添加

向布隆过滤器查询元素时,和添加元素一样,也会对元素进行多次hash计算出数组的位置,然后查看数组的位置值是否都为1,只要有一个位置值为0,就表示布隆过滤器不存在该元素。如果这几个位置都为1,则表示元素可能存在(并不是一定存在)

③布隆过滤器为什么存在误判?

 具体实现:Guava,Hutool,Redisson,手动实现

redisson

 

标签:面试题,缓存,Java,过期,redis,获取,线程,高频,分布式
From: https://www.cnblogs.com/hwjres/p/18047842

相关文章

  • Java基础
    Java基础注释单行注释只能注释一行文字//多行注释可以注释多行文字/**/文档注释/***/JavaDocjavadoc命令是用来生成自己API文档的参数信息@author作者名@version版本号@since指明需要最早使用的jdk版本@param参数名@return返回值情况@throws异常抛出......
  • Java双亲委派机制
    Java双亲委派机制首先得了解一下JVM和ClassLoaderJVM当前主流的有三种JVM:Sun公司:HotSpotBEA:JRockitIBM:J9VM首先了解一下Java程序从编译到执行的整个生命周期:.java(经过javac.exe编译成class文件)=>.class(经过类加载器ClassLoader,具体过程有加载、链接、初始化)=>......
  • Java流程控制08:For循环详解
     For循环:条件.for1.虽然所有循环结构都可以用while或者do...while表示,但Java提供了另一种语句----->for循环,使一些循环结构变得更加简单。2.for循环语句是支持迭代的一种通用结构,是最有效、最灵活的循环机构。 3.for循环执行的次数是在执行前就确定的......
  • 初识JavaScript逆向——以网易云音乐和招标网站为例
    前言:需要掌握一定的JavaScript基础,能看懂基础的JavaScript代码。我们平常在浏览网站的时候会看到许多加密的参数,如果需要知道它的原始数据,就需要知道整个加密过程,所以本篇文章就来介绍一下本人在初学逆向的时候一些笔记。想要获取加密过程大概来说有以下两个方法:(1)通过浏览器的i......
  • Java流程控制07:DoWhile循环
    DoWhile循环2.do...while循环2.1对于while语句而言,如果不满足条件,则不能进入循环。但有时候我们需要及时不满足条件,也至少执行一次2.2do...while循环和while循环相似,不同的是,do...while循环至少会执行一次语法:......
  • Java流程控制06:While循环详解
    循环结构1.while循环1.1while循环最基本的循环,它的结构为:1.2只要布尔表达式为true,循环就会一直执行下去1.3大多数情况是会让循环停止下来,我们需要让一个表达式失效的方式来结束循环。1.4少部分情况需要循环一直执行,比如服务器的......
  • Java学习笔记——第二天
    进制知识二进制、八进制和十六进制二进制:只有0和1两个数字,按照逢2进1的方式表示数据。八进制:只有0~7八个数字,按照逢8进1的方式表示数据。十六进制:由0~9以及A,B,C,D,E,F,共十六个数字,按照逢16进1的方式表示数据,其中A,B,C,D,E,F分别代表十进制的10,11,12,13,14,15。Java程序中支持书写二进制、......
  • 前端 xlsx js javascript 处理excel 数据展示 日期格式处理
     1、参考https://blog.csdn.net/Seven71111/article/details/107375712https://blog.csdn.net/weixin_44987713/article/details/130129282 https://blog.csdn.net/qq_57952018/article/details/134812452 2、存在的问题a、千年虫b、定义一个转换日期格式的方法(转成......
  • Java 韩顺平老师的课,记的(前6章)笔记
    https://www.bilibili.com/video/BV1fh411y7R8/?p=110&spm_id_from=333.880.my_history.page.click&vd_source=92305fa48ea41cb7bedb3ab5e056d42d韩顺平老师在b站课的链接。 010,JDK的介绍 018,Java开发细节 6,一个源文件中最多只能有一个public类。其他类的个数不限。......
  • java调用接口
    longdateStr=System.currentTimeMillis()/1000;Stringurl="";//创建参数JSONObjectjsonObject=newJSONObject();jsonObject.put("Action","1111");jsonObject.put("DeviceType","2222&quo......