进大厂必备的Java八股文大全(2024最强精简易懂版,八股文中的八股文)备战秋招,赶快转发收藏起来吧~

最后

终极手撕架构师的学习笔记:分布式+微服务+开源框架+性能优化

image

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

2.linux的io模型

九.其他(RabitMQ、数据结构与算法、nginx、git、jwtd登录等…)


一、Java基础篇


1.接口和抽象类的区别

(1)抽象类可以有构造方法,而接口没有

(2)抽象类可以有抽象方法和具体方法,接口只能有抽象方法

(3)抽象类的成员4种权限修饰符都可以修饰,接口只能用private

2.重载和重写的区别

重载发生在同一个类中,方法名相同、参数列表、返回类型、权限修饰符可以不同

重写发生在子类中,方法名相、参数列表、返回类型都相同,权限修饰符要大于父类方法,声明异常范围要小于父类方法,但是final和private修饰的方法不可重写

3.==和equals的区别

==比较基本类型,比较的是值,==比较引用类型,比较的是内存地址

equlas是Object类的方法,本质上与==一样,但是有些类重写了equals方法,比如String的equals被重写后,比较的是内存地址,另外重写了equlas后,也必须重写hashcode()方法

4.异常处理机制

(1)使用try、catch、finaly捕获异常,finaly中的代码一定会执行,捕获异常后程序会继续执行

(2)使用throws声明该方法可能会抛出的异常类型,出现异常后,程序终止

5.HashMap原理

1.HashMap在Jdk1.8以后是基于数组+链表+红黑树来实现的,特点是,key不能重复,可以为null,线程不安全

2.HashMap的扩容机制:

HashMap的默认容量为16,默认的负载因子为0.75,当HashMap中元素个数超过容量乘以负载因子的个数时,就创建一个大小为前一次两倍的新数组,再将原来数组中的数据复制到新数组中。当数组长度到达64且链表长度大于8时,链表转为红黑树

3.HashMap存取原理:

(1)计算key的hash值,然后进行二次hash,根据二次hash结果找到对应的索引位置

(2)如果这个位置有值,先进性equals比较,若结果为true则取代该元素,若结果为false,就使用高低位平移法将节点插入链表(JDK8以前使用头插法,但是头插法在并发扩容时可能会造成环形链表或数据丢失,而高低位平移发会发生数据覆盖的情况)

6.想要线程安全的HashMap怎么办?

(1)使用ConcurrentHashMap

(2)使用HashTable

(3)Collections.synchronizedHashMap()方法

7.ConcurrentHashMap原如何保证的线程安全?

JDK1.7:使用分段锁,将一个Map分为了16个段,每个段都是一个小的hashmap,每次操作只对其中一个段加锁

JDK1.8:采用CAS+Synchronized保证线程安全,每次插入数据时判断在当前数组下标是否是第一次插入,是就通过CAS方式插入,然后判断f.hash是否=-1,是的话就说明其他线程正在进行扩容,当前线程也会参与扩容;删除方法用了synchronized修饰,保证并发下移除元素安全

8.HashTable与HashMap的区别

(1)HashTable的每个方法都用synchronized修饰,因此是线程安全的,但同时读写效率很低

(2)HashTable的Key不允许为null

(3)HashTable只对key进行一次hash,HashMap进行了两次Hash

(4)HashTable底层使用的数组加链表

9.ArrayList和LinkedList的区别

ArratList的底层使用动态数组,默认容量为10,当元素数量到达容量时,生成一个新的数组,大小为前一次的1.5倍,然后将原来的数组copy过来;

因为数组有索引,所以ArrayList查找数据更快,但是添加数据效率更低

LinkedList的底层使用链表,在内存中是离散的,没有扩容机制;LinkedList在查找数据时需要从头遍历,所以查找慢,但是添加数据效率更高

10.如何保证ArrayList的线程安全?

(1)使用collentions.synchronizedList()方法为ArrayList加锁

(2)使用Vector,Vector底层与Arraylist相同,但是每个方法都由synchronized修饰,速度很慢

(3)使用juc下的CopyOnWriterArrayList,该类实现了读操作不加锁,写操作时为list创建一个副本,期间其它线程读取的都是原本list,写操作都在副本中进行,写入完成后,再将指针指向副本。

11.String、StringBuffer、StringBuilder的区别

String 由 char[] 数组构成,使用了 final 修饰,对 String 进行改变时每次都会新生成一个 String 对象,然后把指针指向新的引用对象。

StringBuffer可变并且线程安全;

StringBuiler不可变并且线程不安全。

操作少量字符数据用 String;单线程操作大量数据用 StringBuilder;多线程操作大量数据用 StringBuffer。

二.Java多线程篇


1.进程和线程的区别

进程:系统运行的基本单位,包含多个线程

线程:独立运行的最小单位,是进程的实体,多个线程共享同一进程内的系统资源

2. 什么是线程上下文切换

当一个线程被剥夺cpu使用权时,切换到另外一个线程执行

3.什么是死锁

死锁指多个线程在执行过程中,因争夺资源造成的一种相互等待的僵局

4.死锁的必要条件

互斥条件:同一资源同时只能由一个线程读取

不可抢占条件:不能强行剥夺线程占有的资源

请求和保持条件:请求其他资源的同时对自己手中的资源保持不放

循环等待条件:在相互等待资源的过程中,形成一个闭环

想要预防死锁,只需要破坏其中一个条件即可,银行家算法可以预防死锁

5.Synchrpnized和lock的区别

(1)synchronized是关键字,lock是一个类

(2) synchronized在发生异常时会自动释放锁,lock需要手动释放锁

(3)synchronized是可重入锁、非公平锁、不可中断锁,lock是可重入锁,可中断锁,可以是公平锁

6.sleep()和wait()的区别

(1)wait()是Object的方法,sleep()是Thread类的方法

(2)wait()会释放锁,sleep()不会释放锁

(3)wait()要在同步方法或者同步代码块中执行,sleep()没有限制

(4)wait()要调用notify()或notifyall()唤醒,sleep()自动唤醒

7.yield()和join()区别

yield()调用后线程进入就绪状态

A线程中调用B线程的join() ,则B执行完前A进入阻塞状态

8.线程池七大参数

核心线程数:线程池中的基本线程数量

最大线程数:当阻塞队列满了之后,逐一启动

最大线程的存活时间:当阻塞队列的任务执行完后,最大线长的回收时间

最大线程的存活时间单位

阻塞队列:当核心线程满后,后面来的任务都进入阻塞队列

线程工厂:用于生产线程

任务拒绝策略:阻塞队列满后,拒绝任务,有四种策略(1)抛异常(2)丢弃任务不抛异常(3)打回任务(4)尝试与最老的线程竞争

9.Java内存模型

JMM(Java内存模型 )屏蔽了各种硬件和操作系统的内存访问差异,实现让Java程序在各平台下都能达到一致的内存访问效果,它定义了JVM如何将程序中的变量在主存中读取

具体定义为:所有变量都存在主存中,主存是线程共享区域;每个线程都有自己独有的工作内存,线程想要操作变量必须从主从中copy变量到自己的工作区,每个线程的工作内存是相互隔离的

由于主存与工作内存之间有读写延迟,且读写不是原子性操作,所以会有线程安全问题

10.保证并发安全的三大特性?

原子性:一次或多次操作在执行期间不被其他线程影响

可见性:当一个线程在工作内存修改了变量,其他线程能立刻知道

有序性:JVM对指令的优化会让指令执行顺序改变,有序性是禁止指令重排

11.volatile

保证变量的可见性和有序性,不保证原子性。使用了 volatile 修饰变量后,在变量修改后会立即同步到主存中,每次用这个变量前会从主存刷新。

单例模式双重校验锁变量为什么使用 volatile 修饰? 禁止 JVM 指令重排序,new Object()分为三个步骤:申请内存空间,将内存空间引用赋值给变量,变量初始化。如果不禁止重排序,有可能得到一个未经初始化的变量。

12.线程使用方式

(1)继承 Tread 类

(2)实现 Runnable 接口

(3)实现 Callable 接口:带有返回值

13.ThreadLocal原理

原理是为每个线程创建变量副本,不同线程之间不可见,保证线程安全。每个线程内部都维护了一个Map,key为threadLocal实例,value为要保存的副本。

但是使用ThreadLocal会存在内存泄露问题,因为key为弱引用,而value为强引用,每次gc时key都会回收,而value不会被回收。所以为了解决内存泄漏问题,可以在每次使用完后删除value或者使用static修饰ThreadLocal,可以随时获取value

14.什么是CAS锁

CAS锁可以保证原子性,思想是更新内存时会判断内存值是否被别人修改过,如果没有就直接更新。如果被修改,就重新获取值,直到更新完成为止。这样的缺点是

(1)只能支持一个变量的原子操作,不能保证整个代码块的原子操作

(2)CAS频繁失败导致CPU开销大

(3)ABS问题:线程1和线程2同时去修改一个变量,将值从A改为B,但线程1突然阻塞,此时线程2将A改为B,然后线程3又将B改成A,此时线程1将A又改为B,这个过程线程2是不知道的,这就是ABA问题,可以通过版本号或时间戳解决

15.Synchronized锁原理和优化

Synchronize是通过对象头的markwordk来表明监视器的,监视器本质是依赖操作系统的互斥锁实现的。操作系统实现线程切换要从用户态切换为核心态,成本很高,此时这种锁叫重量级锁,在JDK1.6以后引入了偏向锁、轻量级锁、重量级锁

偏向锁:当一段代码没有别的线程访问,此时线程去访问会直接获取偏向锁

轻量级锁:当锁是偏向锁时,有另外一个线程来访问,偏向锁会升级为轻量级锁,这个线程会通过自旋方式不断获取锁,不会阻塞,提高性能

重量级锁:轻量级锁自旋一段时间后线程还没有获取到锁,线程就会进入阻塞状态,该锁会升级为重量级锁,重量级锁时,来竞争锁的所有线程都会阻塞,性能降低

注意,锁只能升级不能降级

16.JUC常用辅助类

CountDownLatch:设定一个数,当调用CountDown()时数量减一,当调用await() 时判断计数器是否为0,不为0就阻塞,直到计数器为0

CyclicBarrier:设定一个数,当调用await() 时判断计数器是否达到目标值,未达到就阻塞,直到计数器达到目标值

Semaphore:设定一个信号量,当调用acquire()时判断是否还有信号,有就信号量减一线程继续执行,没有就阻塞等待其他线程释放信号量,当调用release()时释放信号量,唤醒阻塞线程

17.如何根据 CPU 核心数设计线程池线程数量

IO 密集型:核心数*2

计算密集型: 核心数+1

为什么加 1?即使当计算密集型的线程偶尔由于缺失故障或者其他原因而暂停时,这个额外的线程也能确保 CPU 的时钟周期不会被浪费。

三.JVM篇


1.JVM运行时数据区(内存结构)

线程私有区:

(1)虚拟机栈:每次调用方法都会在虚拟机栈中产生一个栈帧,每个栈帧中都有方法的参数、局部变量、方法出口等信息,方法执行完毕后释放栈帧

(2)本地方法栈:为native修饰的本地方法提供的空间,在HotSpot中与虚拟机合二为一

(3)程序计数器:保存指令执行的地址,方便线程切回后能继续执行代码

线程共享区:

(4)堆内存:Jvm进行垃圾回收的主要区域,存放对象信息,分为新生代和老年代

(5)方法区:存放类信息、静态变量、常量、运行时常量池等信息。JDK1.8之前用持久代实现,JDK1.8后用元空间实现,元空间使用的是本地内存,而非在JVM内存结构中

2.什么情况下会内存溢出?

堆内存溢出:(1)当对象一直创建而不被回收时(2)加载的类越来越多时(3)虚拟机栈的线程越来越多时

栈溢出:方法调用次数过多,一般是递归不当造成

3.JVM有哪些垃圾回收算法?

(1)标记清除算法: 标记不需要回收的对象,然后清除没有标记的对象,会造成许多内存碎片。

(2)复制算法: 将内存分为两块,只使用一块,进行垃圾回收时,先将存活的对象复制到另一块区域,然后清空之前的区域。用在新生代

(3)标记整理算法: 与标记清除算法类似,但是在标记之后,将存活对象向一端移动,然后清除边界外的垃圾对象。用在老年代

4.GC如何判断对象可以被回收?

(1)引用计数法:已淘汰,为每个对象添加引用计数器,引用为0时判定可以回收,会有两个对象相互引用无法回收的问题

(2)可达性分析法:从GCRoot开始往下搜索,搜索过的路径称为引用链,若一个对象GCRoot没有任何的引用链,则判定可以回收

GCRoot有:虚拟机栈中引用的对象,方法区中静态变量引用的对象,本地方法栈中引用的对象

5.典型垃圾回收器

G1 :JDK1.9以后的默认垃圾回收器,支持并发,采用标记整理+复制算法,注重响应速度

6.类加载器和双亲委派机制

从父类加载器到子类加载器分别为:

BootStrapClassLoader    加载路径为:JAVA_HOME/jre/lib

ExtensionClassLoader    加载路径为:JAVA_HOME/jre/lib/ext

ApplicationClassLoader  加载路径为:classpath

还有一个自定义类加载器

当一个类加载器收到类加载请求时,会先把这个请求交给父类加载器处理,若父类加载器找不到该类,再由自己去寻找。该机制可以避免类被重复加载,还可以避免系统级别的类被篡改

7.类加载过程

(1)加载 :加载字节码文件,将字节码中的静态变量和常量转换到方法区中,在堆中生成class对象作为方法区入口

(2)连接:

验证:验证字节码文件的正确性。

准备:正式为类变量在方法区中分配内存,并设置初始值。

解析:将符号引用(如类的全限定名)解析为直接引用(类在实际内存中的地址)。()

(3)初始化 :执行类构造器(不是常规的构造方法),为静态变量赋初值并初始化静态代码块。

8.JVM中有哪些引用?

强引用:new的对象。哪怕内存溢出也不会回收

软引用:只有内存不足时才会回收

弱引用:每次垃圾回收都会回收

虚引用:必须配合引用队列使用,一般用于追踪垃圾回收动作

9.对象头中有哪些信息

对象头中有两部分,一部分是MarkWork,存储对象运行时的数据,如GC分代年龄、GC标记、锁的状态、线程ID等;另外一部分是指向对象类型的指针,如果是数组,还有一个部分存放数组长度

10.JVM内存参数

-Xmx[]:堆空间最大内存

-Xms[]:堆空间最小内存,一般设置成跟堆空间最大内存一样的

-Xmn[]:新生代的最大内存

-xx[use 垃圾回收器名称]:指定垃圾回收器

-xss:设置单个线程栈大小

一般设堆空间为最大可用物理地址的百分之80

11.JVM类初始化顺序

父类静态代码块和静态成员变量->子类静态代码块和静态成员变量->父类代码块和普通成员变量->父类构造方法->子类代码块和普成员变量->子类构造方法

四.Mysql篇


1.MyIAm和InnoDB的区别

InnoDB支持事务,MyIAm不支持

InnoDB支持外键,MyIAm不支持

InnoDB是聚簇索引,MyIAm是非聚簇索引

InnoDB支持行锁和表锁,MyIAm只支持表锁

InnoDB不支持全文索引,MyIAm支持

InnoDB支持自增和MVCC模式的读写,MyIAm不支持

2.mysql事务特性

原子性:一个事务内的操作统一成功或失败

一致性:事务前后的数据总量不变

隔离性:事务与事务之间相互不影响

持久性:事务一旦提交发生的改变不可逆

3.事务靠什么保证

原子性:由undolog日志保证,他记录了需要回滚的日志信息,回滚时撤销已执行的sql

一致性:由其他三大特性共同保证,是事务的目的

隔离性:由MVCC保证

持久性:由redolog日志和内存保证,mysql修改数据时内存和redolog会记录操作,宕机时可恢复

4.事务的隔离级别

在高并发情况下,并发事务会产生脏读、不可重复读、幻读问题,这时需要用隔离级别来控制

读未提交: 允许一个事务读取另一个事务已提交的数据,可能出现不可重复读,幻读。

读提交:    只允许事务读取另一个事务没有提交的数据可能出现不可重复读,幻读。

可重复读: 确保同一字段多次读取结果一致,可能出现欢幻读。

可串行化: 所有事务逐次执行,没有并发问日

Inno DB 默认隔离级别为可重复读级别,分为快照度和当前读,并且通过间隙锁解决了幻读问题。

5.什么是快照读和当前读

*快照读读取的是当前数据的可见版本,可能是会过期数据,不加锁的select就是快照都

*当前读读取的是数据的最新版本,并且当前读返回的记录都会上锁,保证其他事务不会并发修改这条记录。如update、insert、delete、select for undate(排他锁)、select lockin share mode(共享锁) 都是当前读

6.MVCC是什么

MVCC是多版本并发控制,为每次事务生成一个新版本数据,每个事务都由自己的版本,从而不加锁就决绝读写冲突,这种读叫做快照读。只在读已提交和可重复读中生效。

实现原理由四个东西保证,他们是

undolog日志:记录了数据历史版本

readView:事务进行快照读时产生的视图,记录了当前系统中活跃的事务id,控制哪个历史版本对当前事务可见

隐藏字段DB_TRC_ID: 最近修改记录的事务ID

隐藏字段DB_Roll_PTR: 回滚指针,配合undolog指向数据的上一个版本

7.MySQL有哪些索引

主键索引:一张表只能有一个主键索引,主键索引列不能有空值和重复值

唯一索引:唯一索引不能有相同值,但允许为空

普通索引:允许出现重复值

组合索引:对多个字段建立一个联合索引,减少索引开销,遵循最左匹配原则

全文索引:myisam引擎支持,通过建立倒排索引提升检索效率,广泛用于搜索引擎

8.聚簇索引和非聚簇索引的区别

聚簇索引:将索引和值放在了一起,根据索引可以直接获取值,如果主键值很大的话,辅助索引也会变得很大

非聚簇索引:叶子节点存放的是数据行地址,先根据索引找到数据地址,再根据地址去找数据

他们都是b+数结构

9.B和B+数的区别,为什么使用B+数

二叉树:索引字段有序,极端情况会变成链表形式

AVL数:树的高度不可控

B数:控制了树的高度,但是索引值和data都分布在每个具体的节点当中,若要进行范围查询,要进行多次回溯,IO开销大

B+树:非叶子节点只存储索引值,叶子节点再存储索引+具体数据,从小到大用链表连接在一起,范围查询可直接遍历不需要回溯7

10.MySQL有哪些锁

基于粒度:

*表级锁:对整张表加锁,粒度大并发小

*行级锁:对行加锁,粒度小并发大

*间隙锁:间隙锁,锁住表的一个区间,间隙锁之间不会冲突只在可重复读下才生效,解决了幻读

基于属性:

*共享锁:又称读锁,一个事务为表加了读锁,其它事务只能加读锁,不能加写锁

*排他锁:又称写锁,一个事务加写锁之后,其他事务不能再加任何锁,避免脏读问题

11.MySQL如果做慢查询优化

(1)分析sql语句,是否加载了不需要的数据列

(2)分析sql执行计划,字段有没有索引,索引是否失效,是否用对索引

(3)表中数据是否太大,是不是要分库分表

12.哪些情况索引会失效

(1)where条件中有or,除非所有查询条件都有索引,否则失效

(2)like查询用%开头,索引失效

(3)索引列参与计算,索引失效

(4)违背最左匹配原则,索引失效

(5)索引字段发生类型转换,索引失效

(6)mysql觉得全表扫描更快时(数据少),索引失效

13.Mysql内连接、左连接、右连接的区别

内连接取量表交集部分,左连接取左表全部右表匹部分,右连接取右表全部坐表匹部分

14.sql执行顺序

我单独写了一篇文章 http://t.csdn.cn/6a5Y3

五.Spring系列(spring全家桶)


1.Bean 的作用域

(1)Singleton:一个IOC容器只有一个

(2)Prototype:每次调用getBean()都会生成一个新的对象

(3)request:每个http请求都会创建一个自己的bean

(4)session:同一个session共享一个实例

(5)application:整个serverContext只有一个bean

(6)webSocket:一个websocket只有一个bean

2.Bean 生命周期

实例化 Instantiation->属性赋值 Populate->初始化 Initialization->销毁 Destruction

在这四步的基础上面,Spring 提供了一些拓展点:

*Bean 自身的方法: 包括了 Bean 本身调用的方法和通过配置文件中的 init-method 和 destroy-method 指定的方法

*Bean 级生命周期接口方法:包括了 BeanNameAware、BeanFactoryAware、InitializingBean 和 DiposableBean 这些接口的方法

*容器级生命周期接口方法:包括了 InstantiationAwareBeanPostProcessor 和 BeanPostProcessor 这两个接口实现,一般称它们的实现类为“后处理器”。

*工厂后处理器接口方法: 包括了 AspectJWeavingEnabler, ConfigurationClassPostProcessor, CustomAutowireConfigurer 等等非常有用的工厂后处理器接口的方法。工厂后处理器也是容器级的。在应用上下文装配配置文件之后立即调用。

3.Spring 事务原理?

spring事务有编程式和声明式,我们一般使用声明式,在某个方法上增加@Transactional注解,这个方法中的sql会统一成功或失败。

原理是:

当一个方法加上@Transactional注解,spring会基于这个类生成一个代理对象并将这个代理对象作为bean,当使用这个bean中的方法时,如果存在@Transactional注解,就会将事务自动提交设为false,然后执行方法,执行过程没有异常则提交,有异常则回滚、

4.spring事务失效场景

(1)事务方法所在的类没有加载到容器中

(2)事务方法不是public类型

(3)同一类中,一个没有添加事务的方法调用另外以一个添加事务的方法,事务不生效

(4)spring事务默认只回滚运行时异常,可以用rollbackfor属性设置

(5)业务自己捕获了异常,事务会认为程序正常秩序

5.spring事务的隔离级别

default:默认级别,使用数据库自定义的隔离级别

其它四种隔离级别与mysql一样

6.spring事务的传播行为

(1)支持当前事务,如果不存在,则新启一个事务

(2)支持当前事务,如果不存在,则抛出异常

(3)支持当前事务,如果不存在,则以非事务方式执行

(4)不支持当前事务,创建一个新事物

(5)不支持当前事务,如果已存在事务就抛异常

(6)不支持当前事务,始终以非事务方式执行

7.Spring IoC

20200904160557786.png

8.spring用了哪些设计模式

BeanFactory用了工厂模式,AOP用了动态代理模式,RestTemplate用来模板方法模式,SpringMVC中handlerAdaper用来适配器模式,Spring里的监听器用了观察者模式

9.SpringMV工作原理

SpringMVC工作过程围绕着前端控制器DispatchServerlet,几个重要组件有HandleMapping(处理器映射器)、HandleAdapter(处理器适配器)、ViewReslover(试图解析器)

工作流程:

(1)DispatchServerlet接收用户请求将请求发送给HandleMapping

(2)HandleMapping根据请求url找到具体的handle和拦截器,返回给DispatchServerlet

(3)DispatchServerlet调用HandleAdapter,HandleAdapter执行具体的controller,并将controller返回的ModelAndView返回给DispatchServler

(4)DispatchServerlet将ModelAndView传给ViewReslover,ViewReslover解析后返回具体view

(5)DispatchServerlet根据view进行视图渲染,返回给用户

10.springboot自动配置原理

启动类@SpringbootApplication注解下,有三个关键注解

(1)@springbootConfiguration:表示启动类是一个自动配置类

(2)@CompontScan:扫描启动类所在包外的组件到容器中

(3)@EnableConfigutarion:最关键的一个注解,他拥有两个子注解,其中@AutoConfigurationpackageu会将启动类所在包下的所有组件到容器中,@Import会导入一个自动配置文件选择器,他会去加载META_INF目录下的spring.factories文件,这个文件中存放很大自动配置类的全类名,这些类会根据元注解的装配条件生效,生效的类就会被实例化,加载到ioc容器中

11.springboot常用注解

@RestController                  :修饰类,该控制器会返回Json数据

@RequestMapping(“/path”) :修饰类,该控制器的请求路径

@Autowired                         :  修饰属性,按照类型进行依赖注入

@PathVariable                     :  修饰参数,将路径值映射到参数上

@ResponseBody                 :修饰方法,该方法会返回Json数据

@RequestBody(需要使用Post提交方式) :修饰参数,将Json数据封装到对应参数中

@Controller@Service@Compont:  将类注册到ioc容器

六.Redis系列


1.redis为什么快?

(1)完全基于内存操作,数据都存在内存中

(2)采用单线程,避免了不必要的上下文切换带来的性能问题,也不用考虑锁的问题

(3)基于非阻塞的io多路复用机制

(4)数据结构简单,对数据操作简单

2.redis持久化机制

(1)快照持久化RDB

redis的默认持久化机制,通过父进程fork一个子进程,子进程将redis的数据快照写入一个临时文件,等待持久化完毕后替换上一次的rdb文件。整个过程主进程不进行任何的io操作。持久化策略可以通过save配置单位时间内执行多少次操作触发持久化。所以RDB的优点是保证redis性能最大化,恢复速度数据较快,缺点是可能会丢失两次持久化之间的数据

(2)追加持久化AOF

以日志形式记录每一次的写入和删除操作,策略有每秒同步、每次操作同步、不同步,优点是数据完整性高,缺点是运行效率低,恢复时间长

3.Redis如何实现key的过期删除?

采用的定期过期+惰性过期

定期删除 :Redis 每隔一段时间从设置过期时间的 key 集合中,随机抽取一些 key ,检查是否过期,如果已经过期做删除处理。

惰性删除 :Redis 在 key 被访问的时候检查 key 是否过期,如果过期则删除。

4.Redis数据类型

最后总结我的面试经验

2021年的金三银四一眨眼就到了,对于很多人来说是跳槽的好机会,大厂面试远没有我们想的那么困难,摆好心态,做好准备,你也可以的。

另外,面试中遇到不会的问题不妨尝试讲讲自己的思路,因为有些问题不是考察我们的编程能力,而是逻辑思维表达能力;最后平时要进行自我分析与评价,做好职业规划,不断摸索,提高自己的编程能力和抽象思维能力。

BAT面试经验

实战系列:Spring全家桶+Redis等

其他相关的电子书:源码+调优

面试真题:

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

(2)采用单线程,避免了不必要的上下文切换带来的性能问题,也不用考虑锁的问题

(3)基于非阻塞的io多路复用机制

(4)数据结构简单,对数据操作简单

2.redis持久化机制

(1)快照持久化RDB

redis的默认持久化机制,通过父进程fork一个子进程,子进程将redis的数据快照写入一个临时文件,等待持久化完毕后替换上一次的rdb文件。整个过程主进程不进行任何的io操作。持久化策略可以通过save配置单位时间内执行多少次操作触发持久化。所以RDB的优点是保证redis性能最大化,恢复速度数据较快,缺点是可能会丢失两次持久化之间的数据

(2)追加持久化AOF

以日志形式记录每一次的写入和删除操作,策略有每秒同步、每次操作同步、不同步,优点是数据完整性高,缺点是运行效率低,恢复时间长

3.Redis如何实现key的过期删除?

采用的定期过期+惰性过期

定期删除 :Redis 每隔一段时间从设置过期时间的 key 集合中,随机抽取一些 key ,检查是否过期,如果已经过期做删除处理。

惰性删除 :Redis 在 key 被访问的时候检查 key 是否过期,如果过期则删除。

4.Redis数据类型

最后总结我的面试经验

2021年的金三银四一眨眼就到了,对于很多人来说是跳槽的好机会,大厂面试远没有我们想的那么困难,摆好心态,做好准备,你也可以的。

另外,面试中遇到不会的问题不妨尝试讲讲自己的思路,因为有些问题不是考察我们的编程能力,而是逻辑思维表达能力;最后平时要进行自我分析与评价,做好职业规划,不断摸索,提高自己的编程能力和抽象思维能力。

[外链图片转存中…(img-UWrkNgGt-1715709934659)]

BAT面试经验

实战系列:Spring全家桶+Redis等

[外链图片转存中…(img-M2giJA8X-1715709934659)]

其他相关的电子书:源码+调优

[外链图片转存中…(img-ZO42qws4-1715709934659)]

面试真题:

[外链图片转存中…(img-iz6zxBUs-1715709934660)]

[外链图片转存中…(img-lulhkQb0-1715709934660)]

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值