一、 Redis为啥什这么快?有哪些持久化方式?区别是怎样的?
回答
(一)redis是单线程,为什么这么快?
1、基于内存,绝大部分请求是纯粹的内存操作,
CPU
不是
Redis
的瓶颈
2、避免了不必要的
CPU
上下文切换和其他竞争条件,比如锁操作等
3、底层是使用多路
I/O
复用模型,非阻塞
IO
4、Redis6
后支持多线程,但是默认不开启
(二)redis有哪些持久化方式,分别说下他们的区别
1、支持
AOF
和
RDB
持久化
2、AOF
(1)以日志的形式记录服务器所处理的每一个写、删除操作,查询操作不会记录,以文本的方式记录
(2)支持秒级持久化、兼容性好,对于相同数量的数据集而言,
AOF
文件通常要大于
RDB
文件,所以恢复比RDB
慢
3、RDB
(1)在指定的时间间隔内将内存中的数据集快照写入磁盘,可以指定时间归档数据,但不能做到实时持久化
(2)文件紧凑,体积小,对于灾难恢复而言,
RDB
是非常不错的选择,相比于
AOF
机制,如果数据集很大,RDB
在恢复大数据集时的速度比
AOF
的恢复速度要快
二、ReentrantLock和synchronized使用的场景是什么,实现机制有什么不同
回答
ReentrantLock和synchronized都是独占锁
synchronized:
1、是悲观锁会引起其他线程阻塞,java内置关键字,
2、无法判断是否获取锁的状态,锁可重入、不可中断、只能是非公平
3、加锁解锁的过程是隐式的,用户不用手动操作,优点是操作简单但显得不够灵活
4、一般并发场景使用足够、可以放在被递归执行的方法上,且不用担心线程最后能否正确释放锁
5、synchronized操作的应该是对象头中mark word,参考原先原理图片
ReentrantLock:
1、是个Lock接口的实现类,是悲观锁,
2、可以判断是否获取到锁,可重入、可判断、可公平可不公平
3、需要手动加锁和解锁,且 解锁的操作尽量要放在finally代码块中,保证线程正确释放锁
4、在复杂的并发场景中使用在重入时要却确保重复获取锁的次数必须和重复释放锁的次数一样,否则可 能导致 其他线程无法获得该锁。
5、创建的时候通过传进参数true创建公平锁,如果传入的是false或没传参数则创建的是非公平锁
6、底层不同是AQS的state和FIFO队列来控制加锁
三、Spring里面 CGLib和JDK动态代理区别、选择策略
回答
(一)动态代理与静态代理相比较,最大的好处是接口中声明的所有方法都被转移到调用处理器一个集中的方法中处理,解耦和易维护
(二)两种动态代理的区别:
1、JDK
动态代理:要求目标对象
实现一个接口
,但是有时候目标对象只是一个单独的对象
,
并没有实现任何的接口,
这个时候就可以用
CGLib
动态代理
2、CGLib
动态代理
,
它是在内存中构建一个子类对象从而实现对目标对象功能的扩展
3、JDK
动态代理是自带的,
CGlib
需要引入第三方包
4、CGLib
动态代理基于继承来实现代理,所以无法对
fifinal
类、
private
方法和
static
方法实现代理
(二)Spring AOP中的代理使用的默认策略:
1、如果目标对象实现了接口,则默认采用
JDK
动态代理
2、如果目标对象没有实现接口,则采用
CgLib
进行动态代理
3、如果目标对象实现了接扣,程序里面依旧可以指定使用
CGlib
动态代理
四、对synchronized了解不,能否介绍下你对synchronized的理解
回答
synchronized是解决线程安全的问题,常用在 同步普通方法、静态方法、代码块中
非公平、可重入
每个对象有一个锁和一个等待队列,锁只能被一个线程持有,其他需要锁的线程需要阻塞等待。锁被释放后, 对象会从队列中取出一个并唤醒,唤醒哪个线程是不确定的,不保证公平性
两种形式:
方法:生成的字节码文件中会多一个 ACC_SYNCHRONIZED 标志位,当一个线程访问方法时,会去检查是否存在ACC_SYNCHRONIZED标识,如果存在,执行线程将先获取monitor,获取成功之后才能执行方法体,方法执行完后再释放monitor。在方法执行期间,其他任何线程都无法再获得同一个monitor对象,也叫隐式同步
代码块:加了 synchronized 关键字的代码段,生成的字节码文件会多出 monitorenter 和 monitorexit 两条指令,每个monitor维护着一个记录着拥有次数的计数器, 未被拥有的monitor的该计 数器为0,当一个线程获执行monitorenter后,该计数器自增1;当同一个线程执行monitorexit指令的时 候,计数器再自减1。当计数器为0的时候,monitor将被释放.也叫显式同步
两种本质上没有区别,底层都是通过monitor来实现同步, 只是方法的同步是一种隐式的方式来实现,无需通过字节码来完成
jdk1.6后进行了优化,你知道哪些大的变化
有得到锁的资源进入Block状态,涉及到操作系统用户模式和内核模式的切换,代价比较高
jdk6进行了优化,增加了从偏向锁到轻量级锁再到重量级锁的过渡,但是在最终转变为重量级锁之后,性能仍然较低
五、缓存淘汰策略你知道有哪些
回答
(一)有没看过缓存框架的源码,缓存空间不够怎么办?
1、一般会使用淘汰策略
2、常见的淘汰策略有
FIFO
、
LRU
、
LFU
(二)能分别说下
FIFO
、
LRU
、
LFU
这些策略不
1、先进先出
First In
,
First Out
新访问的数据插入
FIFO
队列尾部,数据在
FIFO
队列中顺序移动,淘汰
FIFO
队列头部的数据
2、最近最少使用
Least recently used
(1)根据数据的历史访问记录来进行数据淘汰,如果数据最近被访问过,那么将来被访问的几率也更高
(2)新数据插入到链表头部,每当缓存数据被访问,则将数据移到链表头部,当链表满的时候,将链表尾部的数据丢弃。
3、最近不经常使用
Least Frequently Used
(1)根据数据的历史访问频率来淘汰数据,如果数据过去被访问多次,那么将来被访问的频率也更高
(2)把数据加入到链表中,按频次排序,一个数据被访问过,把它的频次
+1
,发生淘汰的时候,把频次低的淘汰掉