java面试题

java基础

  1. JDK 和 JRE 有什么区别?

jdk是开发公具包,里面包含了jre以及jvm

jvm是java运行环境

  1. == 和 equals 的区别是什么?

对于基本类型,== 是比较值

对于引用类型,== 是比较地址

equals不能用于基本类型

如果没有重写equals,equals就相当于==

如果重写了equals,equals比较的是对象的内容

(==判断对象物理地址。

equals判断对象Value是否相等。)

  1. final 在 java 中有什么作用?

修饰变量,创建时必须赋值,赋值后不能更改

修饰方法,不能被子类重写

final类中的方法默认是final的

  1. java为什么可以跨平台?

因为java是运行在jvm上的,jvm有windows版本,有Linux,还有其他的,java运行依赖jdk内的jvm,所以可以处处运行.

JAVA中级面试题_李日兴的博客-CSDN博客

  1. Synchronized和lock有什么区别?

  1. 首先,synchronize是java内置关键字,在jvm层面,lock是个java类

  1. synchronize可以给类、方法、代码块加锁,lock只能给代码块加锁。

  1. synchronize不需要手动获取锁和释放锁,发生异常时会自动释放锁,不会造成死锁,而lock需要自己去加锁和释放锁,使用不当容易出现死锁。

  1. 通过lock可以知道有没有成功获取锁,但是synchronize无法办到。

  1. 抽象类必须要有抽象方法吗?

不是必须,抽象类可以没有抽象方法。

  1. arryList的扩容机制?

扩容的本质的计算出扩容数组的size后实例化,将原有的数组内容复制到新的数组中去。(不是原数组,而是新数组给与数组对象地址)。

默认情况下,新的容量是原来的1.5倍。ArrayList是通过动态数组来实现的,我们初始化一个ArrayList还没有添加元素时,他是一个空数组,当我们添加第一个元素是,内部会调用扩容方法并返回最小容量10,也就是说ArrayList的初始容量为10(前期容量是10,当添加第11个元素就开始扩容)ArrayList的真正计算是在grow()里面,数组大小是原来的1.5倍,如果扩容之后还不能满足最小容量,则会再次扩容,扩容后的大小是最小容量,后面会调用一个Arrays.copyof()方法,这是真正实现扩容的步骤。

  1. mysql 调优?

  1. 硬件角度:数据库所在的主机硬盘采用好一些的,固态硬盘比机械硬盘IO读取快很多

  1. 数据库部署架构:采用集群模式,读写分离(采用多个副本机制,当主机不可以,可以从从机中选一台作为主机,减少宕机风险,群集可以提升数据库的并发响应能力。 缺点:数据冗余)

  1. 从整体应用架构出发:可以架设一层缓存,缓存一些热点数据,常规的可以采用redis,ehcache,

如果架设了缓存,需要防范缓存击穿,穿透,雪崩等问题。

  1. 在表中建立索引,优先考虑where,group by使用到的字段

  1. 尽量避免使用select *

  1. RAbbitMQ有什么优点?

解耦,异步,肖峰;

  1. 如何保证RabbitMQ不被重复消费?

为什么会被重复消费:正常情况下,消费者消费消息后会发送一个确认信息给消息队列,消息队列就知道这个消息被消费了。

但是因为网络传输故障导致确认消息没有发送成功,导致消费过的消息被多次发送给消费者。

针对以上问题,一个解决思路:保证消息的唯一性,就算多次传输,不要让消息的多次传输带来影响;保证消息等幂性。

  1. java线程的生命周期?

新建,就绪,运行,阻塞,销毁

  1. java中的异常有哪几类?分别怎么使用?

分为检出异常(非运行时异常)和非检出异常(运行时异常)

检出异常,必须通过检查处理的,否则不能通过编译

非检出异常,一般都会用try-catch-finally捕捉或者抛出异常

□ ArithmeticException:数学计算异常。

□ NullPointerException:空指针异常。

□ NegativeArraySizeException:负数组长度异常。

□ ArrayOutOfBoundsException:数组索引越界异常。

□ ClassNotFoundException:类文件未找到异常。

□ ClassCastException:类型强制转换异常。

□ SecurityException:违背安全原则异常。

  1. 常用的集合有哪些?list如何排序?

分三种,一种是实现set接口,一种是实现list接口,还有map。

  1. set:主要用到hashSet,treeSet两种,hashSet在工作中一般都是用于去重。

HashSet 无序,不允许重复。还有一个linkedHashSet可以记录插入顺序,看起来是有序的。

TreeSet 可以实现集合排序,可以自然排序以及自定义排序。

  1. list:分为ArrayList和linkedList,有序集合,允许重复。

排序的方法一般有两种,一种是通过comparable接口实现排序,一种是通过comparator接口实现排序。

  1. map分为hashMap 和linkedHashMap,主要以key-value的方式进行存储。

  1. ArrayList与linkedList之前的区别?

ArrayList是数组结构linkedList基于双向链表,ArrayList查询更快,linkedList插入更快.linkedList占用内存更大,节点除了存储数据,还有两个引用,一个指向上一节点,一个指向下一节点.

  1. 内存溢出是什么情况?

对象有被指向的引用,但是再也用不到它就是内存溢出.

GC机制:复制回收,标记清楚,引用计数(如果有循环引用后,会影响垃圾回收,所以jvm没有采用此方法进行垃圾回收).

  1. 线程安全的集合?

Set:

  1. CopyOnWriteArraySet:是一种基于CopyOnWrite技术的线程安全Set实现,使用写时复制技术,在写操作时复制一个新的数组进行修改,从而避免了数据竞争和锁的争用。适用于读多写少的场景。

  1. ConcurrentHashSet

List:

  1. Vector:是一个古老的线程安全List实现,使用了synchronized关键字来保证方法的同步性。但是由于其采用了粗粒度锁的方式,效率较低,已经不再推荐使用。

  1. CopyOnWriteArrayList:是一种高效的线程安全List实现,使用写时复制技术,在写操作时复制一个新的数组进行修改,从而避免了数据竞争和锁的争用。适用于读多写少的场景.

map:

  1. ConcurrentHashMap:线程安全的Map实现,支持高并发读写操作。

  1. hashCode方法的作用?

在hashMap中使用,把一个对象变成一个整形.

hashCode规范,如果equals返回true,那么hashCode一定相等,如果hashCode相等,equals不一定相等.

  1. NIO是什么,适用什么场景?

NIO就是newIO,接口都是异步的,非阻塞的.

  1. java中一个字节占几个字符,int long double占几个字节?

一个字节占两个字符 int 4 long double 8

  1. 创建一个对象有哪些方法?

new 反射.

  1. final/finally/finalize的区别?

final是变量,类,方法的修饰,修饰变量和方法不可改变,修饰类不可被继承.

finally一般用于try-catch后执行的finally

finalize是一个方法,在垃圾回收之前会调用这个方法.

List 和set的区别?

list  有序可重复 允许多个null元素对象,可以使用Iterator(迭代器)取出所有元素,再逐一遍历,还可以使用get(int index)获取指定的下标元素。

set 无序不能重复,只能允许一个null对象,只能使用Iterator取出所有元素。

ArrayList 和 LinkedList 有什么区别?

1.首先,他们的底层数据结构不同,ArrayList底层基于数据实现,LinkedList底层是基于链表实现的。

2.由于底层数据结构不同,ArrayList更适合随机查找,LinkedList更适合删除和添加,查询添加的复杂度不同

3.另外ArrayList和LinkedList都实现了List接口,但是LinkedList还额外实现了Deque接口,所以LinkedList还可以当做队列来使用。

 Jdk1.7到jdk1.8 hashMap发生了什么变化?

1.7中是基于数组+链表的方式实现的,1.8是基于数组+链表+红黑树实现的。加入红黑树的目的是为了提高hashMap的插入和查询速度。

1.7插入数据时使用的头插法,1.8用的是尾插法。因为需要判断链表的长度(当链表长度大于8,数组长度达到64会转为红黑树,所以正好使用尾插法。

1.7中的哈希算法比较复杂,存在各种右移与异或运算。1.8新增了红黑树,可以简化hash算法,节省CPU资源。

说一下hashMap 的put方法

1.根据key通过哈希算法与与运算得出数组下标。

2.找到下标之后,如果下标位置元素为空,则会将key-value封装成Entry对象(1.7是entry对象,1.8是Node对象)并放入该位置。

3.如果不为空

        a:如果是1.7版本,首先判断是否需要扩容,不扩容则生成entry对象,然后使用头插法添加到当前链表中。如果存在相同的key,就更新value。

        b:如果是1.8,链表长度小于8,就使用尾插法添加到链表尾部,添加侯长度大于8就会转为红黑树。如果链表长度大于8,则会封装成一个红黑树节点,并添加到红黑树中,存在相同的key就更新value。

entry 是先判断是否需要扩容再添加,node是先添加在判断是否需要扩容。

深拷贝与浅拷贝的去呗?

深拷贝和浅拷贝是值对象的拷贝,一个对象中存在两种类型的属性,一种是基本数据类型,一种是引用类型。

浅拷贝:只会拷贝基本来下的值,以及实例对象的引用地址,拷贝出来的对象指向同一个对象。

深拷贝:除了拷贝值,还会拷贝实例对象,深拷贝出来的,指向的不是同一个对象。

CopyOnWriteArrayList底层是什么样的?

1.首先CopyOnWriteArrayList底层也是基于数据实现的,在CopyOnWriteArrayList中添加元素时,会复制一个新的数组,写操作会在新的数组上执行,读操作在原来的数组上进行。

2.写的时候会加锁,防止并发写入丢失的情况。

3.写操作执行完毕后会指向新的数组。

4.CopyOnWriteArrayList允许再写的时候读操作,大大提高了读的性能,适合读多写少的情况。

5.因为每次写的时候会赋值新的数组,所以比较占内存,同时还会出现读取不到实时最新的数据,所以不适合实时性很高的场景。

java中的异常体系是怎么样的

所有的异常都是来自throwable。

throwable 有两个子类

一个是error ,一个是Exception

error表示严重的错误,比如java.lang.StackOverFlowError(栈溢出) 和 java.lang.OutOfMemoryError(内存溢出)。通常出现这种错误时,仅仅靠代码层面已经解决不了了,可能是虚拟机,磁盘,系统出现问题了,所以也不建议在代码中捕获这些Error。

Exception 表示异常,Exception出现时,是可以靠程序自己来解决的。比如空指针,下标越界等。

Exception又分为运行时异常以及非运行时异常。

在Java的异常处理机制中,什么时候应该抛出异常,什么时候捕获异常?

首先考虑这个异常自己能不能处理,能处理就自己捕获,自己无法处理就往上抛。

 Java中有哪些类加载器

jdk中自带了三个类加载器: bootstrapClassLoader, ExtClassLoader,AppClassLoader

bootstrap 是ExtClassLoader的父类加载器,默认负责加载 %JAVA_HOME%lib下的jar包和class文件。

ExtClassLoader是AppClassLoader的父类加载器,负责加载 %JAVA_HOME%lib/ext下的jar包和class文件。

AppClassLoader是自定义类加载器的父类,负责加载classpath下的类文件。

jvm

百度安全验证

  1. JVM的主要组成部分?及其作用?

class loader 类加载器: 加载类文件到内存,只要符合文件结构,就加载

exection engine 执行引擎:也叫解释器,负责解释命令,交由操作系统执行

native interface 本地接口:本地接口的作用是融合不同语言为java使用

Runtimedata area 运行数据区: 运行时数据区是jvm的重点,我们所写的程序会被加载到这里,然后才开始运行

stack栈内存: 是java程序的运行区,是在线程创建时创建,它的生命周期跟随线程的生命周期,线程结束栈内存释放;对于栈来说不存在垃圾回收的问题,只要线程一结束,该栈就结束。栈中的数据以栈帧的格式存在,栈帧是一个内存区块,是一个数据集,是一个有关方法和运行期数据的集合,当一个方法A被调用时就产生了一个栈帧F1,并被压入到栈中,A方法又调用了B方法,于是产生栈帧F2也被压入栈,执行完毕后,先弹出F2栈帧,再弹出F1栈帧,遵循“先进后出”原则。

堆内存:一个jvm实例只存在一个堆内存,堆内存大小是可以调节的. 类的加载器加载了类之后,会给类,方法常变量放到堆内存中去,以方便执行器执行. 堆内存分为三部分:永久存储区(用于存放jdk自身携带的class interface的元数据,也就是说它存储的是运行环境必须的类信息,被装载到这里的数据是不会被垃圾回收的,只有关闭jvm才会使用此区域的占用的内存),新生代,老年代

method area方法区:方法区是被所有线程共享,该区域保存所有的字段,以及字节方法码以及一些特殊方法如构造函数,接口代码也在此定义.

PC Register程序计数器:每个线程都有程序计数器,就是一个指针,指向方法区的方法字节码,由执行引擎读取下一条指令

  1. 说一下jvm运行时数据区?

不同的虚拟机的运行时数据区可能略微有所不同,但都会遵从java虚拟机规范,主要分为5个部分

  1. 程序计数器:分支、循环、跳转、异常处理线程恢复都需要依赖这个处理。

  1. java虚拟机栈:

  1. 本地方法栈:

  1. java堆

  1. 方法区:

  1. 队列和栈是什么?有什么区别?

  1. 队列和栈都是用来预存储数据的。

  1. 队列允许先进先出检索数据,但是也有例外的情况,Deque接口允许从两段检索元素

  1. 栈和队列很相似,但是它是后进先出进行检索

  1. 什么是双亲委派机制?

如果一个类加载器收到类加载请求,首先它不会主动去加载 ,而是委派给父类去加载,父类也会交给父类,直到顶层,若果父类加载不了,子类才会尝试去加载类。

  1. 类装载的执行过程

  1. 加载:根据查找路径找到相应的class文件然后导入;

  1. 检查: 检查class文件的正确性

  1. 准备:给类中的静态变量分配内存空间

  1. 解析:虚拟机将常量池中的符号引用替换成直接引用的过程。符号引用就理解成一个标示,而在直接引用直接指向内存中的地址。

  1. 初始化:对静态变量和静态代码块执行初始化工作。

  1. 怎么判断对象是否可以回收?

一般有两种方法:

  1. 引用计数器:为每一个对象创建引用计数,有对象引用时计数器+1,有对象被释放时计数器-1,当计数器为0时就可以被回收。缺点就是不能解决循环引用的问题。

  1. 可达性分析:从GC roots开始乡下搜索,搜索所走过的路径称为引用链。当一个对象到GC Roots时没有任何引用链相连时,则证明此对象是可以被回收的。

  1. java中有哪些引用类型?

  1. 强引用:发生gc时不会被回收。

  1. 软引用:有用但不是必须的对象,在发生内存溢出之前会被回收。

  1. 弱引用:有用但不是必须的对象,在下一次GC时一定会被回收。

  1. 虚引用:无法通过虚引用获得对象,用PhantomReference 实现虚引用,虚引用的用途是在GC时返回一个通知

  1. 说一下JVM有哪些垃圾回收算法?

  1. 标记-清除算法:标记无用对象,然后进行清除回收。缺点:效率不高,无法清除垃圾碎片。

  1. 标记-整理算法:标记无用对象,让所有存活的对象向一端移动,然后清除掉边界以外的内存。

  1. 复制算法:按照容量划分两个大小相同的内存区域,当一块快要用完的时候,将或者的对象复制到另一块上,然后把已使用的内存空间一次性清理掉。缺点:内存使用率不高,只有原来的一半。

  1. 分代算法:根据对象的存活周期的不同将内存划分为几块,一般是老年代和新生代,新生代采用复制算法,老年代采用标记-整理算法。

  1. 说一下jvm有哪些垃圾回收器?

  1. serial:最早的单线程串行垃圾回收器

  1. serial Old:serial垃圾回收器的老年版本,同样也是单线程的,可以作为CMS垃圾回收器的备选方案。

  1. ParNew:是serial的多线程版本。

  1. Parallel 和 ParNew 收集器类似,都是多线程的,但是parallel是吞吐量优先的收集器,可以牺牲等待时间换取系统的吞吐量。

  1. Parallel Old 是 Parallel 老生代版本,Parallel 使用的是复制的内存回收算法,Parallel Old 使用的是标记-整理的内存回收算法。

  1. CMS:一种以获得最短停顿时间为目标的收集器,非常适合B/S系统(B/S架构的软件一般都是通过访问一个网页的形式来使用)。

  1. G1:一种兼顾吞吐量和停顿时间的 GC 实现,是 JDK 9 以后的默认 GC 选项。

  1. 能保存GC执行吗?

不能,虽然可以调用System.gc()或者runtime.gc(),但是没办法保证gc的执行

  1. JVM内存结构,GC算法,CMS、G1的原理?

JVM内存结构:

Java虚拟机(JVM)的内存可分为以下几个部分:

1.程序计数器(Program Counter Register):用于记录正在执行的Java虚拟机字节码指令的地址。

2.Java虚拟机栈(Java Virtual Machine Stacks):用于存储方法的局部变量、操作数栈、动态链接、方法出口等信息。

3.本地方法栈(Native Method Stack):与Java虚拟机栈类似,但是用于执行本地方法的栈。

4.Java堆(Java Heap):用于存放对象实例和数组,是Java虚拟机中最大的一块内存区域。

5.方法区(Method Area):用于存储已被虚拟机加载的类信息、常量、静态变量等数据。

6.运行时常量池(Runtime Constant Pool):是方法区的一部分,用于存放编译期生成的各种字面量和符号引用。

7.直接内存(Direct Memory):不是JVM运行时数据区的一部分,但是也被频繁使用。直接内存是利用操作系统的内存管理进行分配和释放的,可以通过JVM的-XX:MaxDirectMemorySize参数来限制其大小。

GC算法:

Java虚拟机的垃圾回收算法主要有以下几种:

1.标记-清除算法(Mark and Sweep):首先标记所有活动对象,然后清除所有未标记对象。该算法会产生内存碎片,并且效率较低。

2.复制算法(Copying):将内存分成两块,每次只使用其中一块。当一块内存用完后,将还存活的对象复制到另一块内存上。该算法可以避免内存碎片,但是需要消耗更多的空间。

3.标记-整理算法(Mark and Compact):首先标记所有活动对象,然后将它们向一端移动,然后清理掉端部的所有垃圾对象。该算法可以避免内存碎片,但是效率较低。

4.分代算法(Generational):根据对象的年龄将其分为不同的代,如新生代和老年代。然后针对不同代使用不同的垃圾回收算法。例如,新生代通常使用复制算法,老年代通常使用标记-整理算法。

CMS、G1的原理:

Concurrent Mark Sweep(CMS):是一种基于标记-清除算法的垃圾回收器。在CMS垃圾回收过程中,应用程序可以继续运行,垃圾回收过程会和应用程序并发执行。CMS主要关注最小化停顿时间。

Garbage First(G1):是一种基于分代算法的垃圾回收器,旨在提高大堆内存情况下的垃圾回收性能。G1将堆划分为多个大小相等的区域,每个区域可能属于新生代或老年代。G1的垃圾回收过程分为四个阶段:初始标记、并发标记、重新标记和清理。在清理阶段,G1会优先清理那些垃圾最多的区域,从而避免因清理时间过长而导致的全局停顿。

Spring boot

  1. Springmvc用到的设计模式有哪些?

简单工厂,工厂方法,单例模式,适配器,观察者等模式

  1. 简单工厂模式:比如beanFactory.getBean()就会使用到这个模式,就是简单工厂模式的体现

  1. 工厂方法模式:在使用factoryBean调用getObjects获取Bean的时候就是使用工厂方法

  1. 单例模式:spring创建对象默认就是单例

  1. 适配器模式:在springMVC中HanderAdapter处理不同的controller就是使用的适配器模式

  1. 装饰器模式:在读源码的时候经常看到某个类带wrapper后缀,在Bean创建的时候,他就作为一个封装,封装到wrapper中去

  1. 动态代理:在aop中使用的就是代理模式

  1. 观察者模式:在spring中监听器,我们使用到listener时就会使用到观察者模式

  1. 策略模式:我们使用不同的resuorce时就会用到策略模式

  1. Spring中bean的生命周期?

  1. 创建前

  1. 准备阶段

  1. 创建实例阶段

  1. 依赖注入阶段

  1. 容器缓存阶段

  1. 销毁实例阶段

 如何理解springboot-starter

springboot-starter 是springboot中的核心特性之一,除此以外,springboot还有自动装配,Actuator监控等一些特性,这些特性都是为了让开发者在开发基于spring生态下的应用时更加专注于业务,减少对配置和外部环境的依赖。

starter 组件的主要作用

1.starter 是以功能为维度来维护对应jar包的版本依赖的,那么开发者就不需要去关心版本冲突这种容易出错的细节了。

2.starter组件会给对应功能的jar包全部导进来,避免开发者自己去引入依赖。

3.starter组件内部集成了自动装配这样一个机制。 程序依赖对应的一个starter组件以后,会自动加入到spring生态中,对于相关bean 的管理,也是基于自动装配机制来完成的。

4.依赖starter组件以后,这些组件对应的功能所需要维护的配置会自动集成到springboot中,我们只需要在yml中进行维护配置就好了

总结 : 在我看来,starter组件几乎完美的体现了springboot里面的约定优于配置这么一个理念。另外springboot官方提供了非常多的starter组件、如Redis,JPA,MongoDB等等,但是官方并不能去维护所有中间件的starter组件,所以对于第三方组件,第三方会自己主动的去维护。

官方starter 组件一般命名为spring-boot-starter-xxx  第三方一般命名为 xxx- spring-boot-starter,这也是一个约定优于配置的体现。

Spring cloud alibaba

1.分布式事务

2pc:事务协调者会发起指令,然后参与者开启事务执行业务,但是不提交,等所有参与响应,然后参与者发起确认或回滚执行。(数据库层面操作)

缺点:如果有个程序不可用,其他参与者会浪费很多资源。

3pc:在2pc基础上增加canCommit阶段,开始之前确认每个参与者是否可以执行,然后再执行2pc操作。

TCC(代码层面):颗粒度小

try阶段:给所有的数据准备好

confirm阶段:插入数据

cancel阶段:执行取消操作

saga(长事务,流水线比较长时使用,不要求隔离 在高并发情况下会引发超卖的问题):

参与者直接提交事务,出现问题侯执行反向回滚。

mq消息最终一致性:生产者发送消息给mq,mq发给指定的消费者消费,当生产者出现问题,mq直接返回false,如果消费者出现问题,会一直ack(重试),直到成功,如果一直不成功,只能采取人工干预的方式了。

Redis

1.Redis支持哪几种数据类型?

  1. String:最基本的数据类型,二进制安全的字符串,最大512M

  1. List:按照添加顺序保存的字符串列表

  1. set:无需的字符串集合,不存在重复的元素

  1. sorted set:已排序的字符串集合

  1. hash:key-value对的一种集合

2.Redis主要消耗什么物理资源?

redis是一种基于内存高性能的数据库,主要依赖于内存

3.Redis和数据库怎么保证数据一致性

都会出现脏数据, 更推荐先操作数据库,更加能保证数据的一致性。

删除出现删除失败的情况,可以采用mq执行异步操作,但是会出现高耦合的情况,可以使用canal客户端进行解耦

4. redis 是单线程还是多线程?

redis 在6.0之前都是单线程(客户端发起请求到服务端,服务端内部处理请求都是单线程操作)。

6.0之后,客户端发起请求到服务端,采用了多线程操作,主要利用CPU的多核来实现,但是服务端内部处理还是采用排队单线程处理。

客户端发起请求到服务端:也就是网络请求

服务端内部: 主要就是键值对的读写操作

5.redis 是单线程为什么速度这么快?

1.redis是基于内存操作的,所以他的效率会特别高

2.redis是单线程的,没有线程切换的资源损耗

3.redis基于IO的多路复用机制提升redis的I/O利用率

4.redis全局引用的hash表,数据结构更高效.

6.redis底层是如何利用跳表来存储的?

什么是跳表?

按分值从小到大排序,可以将zset 的有序链表改造为近似对半查找的算法,

比如我们有一个分为2,为5的链表,这是需要插入一个分值为3的元素,这个时候只需要让2的指针指向3,然后3指向5就完成了插入.

跳表查找的核心就是,每两个元素他会建一个冗余的元素,冗余的元素上面还可以建冗余的元素,查找的时候,比如查找一个分值为15的元素,会先从 1 -> 10 ->20中找到 10 ->20的区间  然后找到10-15的区间,然后找到15.

7.redis key过期了为啥没有释放内存?

主要有三种情况

1.比如 创建了一个键值对 并设置的了过期时间,但是后面又修改了里面的value,但是没有设置过期时间,那么这个key就会永不过期.

set name zhangsan EX 120

set name zhangsan1   这时候这个key会成为永不过期

2.惰性删除,这个key过期了但是不会立马删除,下次找到这个key的时候会判断是否过期,过期了才会删除.

3.定时删除,每次(默认100ms)删除一部分过期的key并不会删除全部的,所以如果存在大量过期的key,那么依旧会有一部分key没有得到删除

8.redis设置了过期时间,为什么会被清除?

redis有一个内存淘汰机制,当redis已用内存超出了maxmemory的值时,会触发主动清理策略

主要分为三种,一种是针对过期的key做清理,一种是针对所有的key做清理,还有一种是不处理,当有新的写操作都会报错.

被清除了可能就是redis中设置了针对所有key的清理策略引起的

详情可以看下图

9.redis  淘汰算法LRU 与 LFU的区别? 

RabbitMQ

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值