2024年最新版Java八股文复习

最新版本Java八股文复习,每天更新一篇,博主正在持续努力更新中~~~

    • 一、Java基础篇
      • 1、怎么理解面向对象?简单说说封装、继承、多态三大特性?
      • 2、多态体现在哪几个方面?
      • 3、面向对象的设计原则你知道有哪些吗?
      • 4、重载与重写有什么区别?
      • 5、深拷贝和浅拷贝的区别?
      • 6、实现深拷贝的三种方法是什么?
      • 7、 什么是泛型?
      • 8、java创建对象有哪些方式?
      • 9、什么是反射?
      • 10、有什么异常,分为什么类型
      • 11、== 与 equals 有什么区别?
      • 12、StringBuffer和StringBuild区别是什么?
      • 13、completableFuture是什么的?
      • 14、怎么把一个对象从一个jvm转移到另一个jvm?
    • 二、Java集合篇
      • 1、说说Java中的集合?
      • 2、Java中的线程安全的集合是什么?
      • 3、Collections和Collection的区别
      • 4、为什么ArrayList不是线程安全的,具体来说是哪里不安全?
      • 5、ArrayList的扩容机制说一下
      • 6、线程安全的 List, CopyonWriteArraylist是如何实现线程安全的
      • 7、HashMap的底层原理介绍一下
      • 8、了解的哈希冲突解决方法有哪些?
      • 9、hashmap的put过程介绍一下?
      • 10、ConcurrentHashMap怎么实现的?
      • 11、ConcurrentHashMap用了悲观锁还是乐观锁?
      • 12、HashTable 底层实现原理是什么?
      • 13、Set集合有什么特点?如何实现key无重复的?
      • 14、有序的Set是什么?记录插入顺序的集合是什么?
    • 三、Java并发篇
      • 1、Java的线程安全在三个方面的体现
      • 2、保证数据的一致性有哪些方案呢?
      • 3、线程的创建方式有哪些?
      • 4、Java线程的状态有哪些?
      • 5、wait 状态下的线程如何进行恢复到 running 状态?
      • 6、如何保证多线程安全?
      • 7、Java中有哪些常用的锁?
      • 8、synchronized和reentrantlock的工作原理
      • 9、详细介绍一下Java中的wait,join,sleep方法
      • 10、synchronized和Reentrantlock区别?
      • 11、如何理解可重入锁?
      • 12、ReentrantLock和synchronized 如何实现可重入锁的?
      • 13、syncronized锁升级的过程讲一下
      • 14、什么是AQS和CAS
      • 15、Threadlocal作用,原理,具体里面存的key value是啥,会有什么问题,如何解决?
      • 16、悲观锁和乐观锁的区别?
      • 17、Java中想实现一个乐观锁,都有哪些方式?
      • 18、CAS 有什么缺点?
      • 19、voliatle关键字有什么作用?
      • 20、什么是公平锁和非公平锁?
      • 21、介绍一下线程池的工作原理
      • 22、线程池的参数有哪些?
      • 23、线程池工作队列满了有哪些拒接策略?
      • 24、线程池种类有哪些?
    • 四、Spring+SpringBoot+SpringCloud篇
      • 1、Spring框架的核心特性有什么?
      • 2、Spring IOC、Spring IOC容器分别是什么?二者有何区别?
      • 3、Spring AOP介绍一下?
      • 4、IOC和AOP是通过什么机制来实现的?
      • 5、静态代理和动态代理的区别是什么?
      • 6、spring是如何解决循环依赖的?以及循环产生的原因是什么?
      • 7、Spring三级缓存是什么,过程是怎么样的?
      • 8、Spring三级缓存的数据结构是什么?
      • 9、Spring框架中都用到了哪些设计模式?
      • 10、Spring、Spring MVC、Spring Boot常用的注解?
      • 11、Spring生命周期中的实例化和初始化阶段有何区别?
      • 12、Spring 中Bean的生命周期说一下?
      • 13、Spring bean的作用域有哪些?
      • 14、MVC分层介绍一下
      • 15、为什么使用springboot,比Spring好在哪里?
      • 16、SpringBoot自动装配原理是什么?
      • 17、Mybatis里的 #{} 和 ${} 的区别?
      • 18、负载均衡有哪些算法?
    • 五、MySQL篇
      • 1、数据库三大范式是什么
      • 2、MySQL 怎么连表查询?
      • 3、MySQL如何避免重复插入数据
      • 4、CHAR 和 VARCHAR有什么区别?
      • 5、mysql中的一些基本函数,你知道哪些?
      • 6、SQL查询语句的执行顺序是如何的?
      • 7、MySQL引擎有哪些,你有什么了解?
      • 8、MySQL的InnoDB与MyISAM的区别?
      • 9、索引的分类是什么?
      • 10、MySQL聚簇索引和非聚簇索引的区别是什么?
      • 11、索引失效有哪些?
      • 12、什么情况回进行回表查询?
      • 13、什么是覆盖索引?
      • 14、如何进行索引优化?
      • 15、事务的特性是什么?详细说说
      • 16、MySQL中,什么是脏读,不可重复读,幻读
      • 17、对于并发问题mysql有什么方法解决?
      • 18、事务的隔离级别有哪些?
      • 19、MySQL默认的隔离级别是什么?
      • 20、MVCC是什么?
      • 21、MysSQL中有哪些锁?
      • 22、日志文件是分成了哪几种?
      • 23、MySQL中explain有什么作用,并详细说说它的参数?
      • 24、MySQL主从复制了解吗,具体复制过程是什么?

一、Java基础篇

1、怎么理解面向对象?简单说说封装、继承、多态三大特性?

面向对象是一种编程范式,它将现实世界中的事物抽象为对象,对象具有属性(称为字段或属性)和行为(称为方法)。面向对象编程的设计思想是以对象为中心,通过对象之间的交互来完成程序的功能,具有灵活性和可扩展性,通过封装和继承可以更好地应对需求变化。

Java面向对象的三大特性包括:继承、封装、多态

  • 封装: 封装是指将对象的属性(数据)和行为(方法)结合在一起,对外隐藏对象的内部细节,仅通过对象提供的接口与外界交互。封装的目的是增强安全性和简化编程,使得对象更加独
  • 继承: 继承是指一个类(子类)可以继承另一个类(父类)的属性和方法。继承使得代码能够复用,减少重复代码,同时也支持创建层次结构。
  • 多态: 指同一个接口或基类可以表示多个不同类型的接口或者对象。

2、多态体现在哪几个方面?

  • 方法重载
  • 方法重写
  • 接口与实现

3、面向对象的设计原则你知道有哪些吗?

  • 单一职责原则(SRP):一个类应该只有一个引起它变化的原因,即一个类应该只负责一项职责。例子:考虑一个员工类,它应该只负责管理员工信息,而不应负责其他无关工作。
  • 开放封闭原则(OCP):软件实体应该对扩展开放,对修改封闭。例子:通过制定接口来实现这一原则,比如定义一个图形类,然后让不同类型的图形继承这个类,而不需要修改图形类本身。
  • 里氏替换原则(LSP):子类对象应该能够替换掉所有父类对象。例子:一个正方形是一个矩形,但如果修改一个矩形的高度和宽度时,正方形的行为应该如何改变就是一个违反里氏替换原则的例子。
  • 接口隔离原则(ISP):客户端不应该依赖那些它不需要的接口,即接口应该小而专。例子:通过接口抽象层来实现底层和高层模块之间的解耦,比如使用依赖注入。
  • 依赖倒置原则(DIP):高层模块不应该依赖低层模块,二者都应该依赖于抽象;抽象不应该依赖于细节,细节应该依赖于抽象。例子:如果一个公司类包含部门类,应该考虑使用合成/聚合关系,而不是将公司类继承自部门类。

4、重载与重写有什么区别?

  • 重载(Overloading):指的是在同一个类中,可以有多个同名方法,它们具有不同的参数列表参数类型、:参数个数或参数顺序不同),编译器根据调用时的参数类型来决定调用哪个方法。

  • 重写(Overriding)指的是子类可以重新定义父类中的方法,方法名、参数列表和返回类型必须与父类中的方法一致,通过@override注解来明确表示这是对父类方法的重写。
    重载是指在同一个类中定义多个同名方法,而重写是指子类重新定义父类中的方法。

5、深拷贝和浅拷贝的区别?

一、浅拷贝
1、定义

指创建一个新的对象,这个新的对象会复制原对象中的所有非引用类型的数据(如基本数据类型),而对于引用类型的数据(如对象、数组),只会复制引用地址而进行引用,与原来对象指向同一个对象。

2.、特点

  • 基本数据类型:复制的是值。
  • 引用数据类型:复制的是引用地址。

二、深拷贝(Deep Copy)
1、定义
深拷贝是指创建一个新的对象,这个新的对象会复制原对象中的所有数据,无论是基本数据类型还是引用数据类型,都会创建新的副本,而不是共享引用地址。

2、特点

  • 基本数据类型:复制的是值。
  • 引用数据类型:复制的是引用所指向的实际数据,而不是引用地址。

6、实现深拷贝的三种方法是什么?

  1. 实现 Cloneable 接口并重写 clone() 方法
  2. 使用序列化和反序列化
  3. 手动递归复制

7、 什么是泛型?

泛型(Generics)是编程语言中的一种特性,允许在定义类、接口和方法时使用类型参数。这些类型参数在实际运行时会被具体的类型替换,从而使代码更加灵活和复用。

8、java创建对象有哪些方式?

  • new关键字
  • 使用Class.newInstance()方法

在这里插入图片描述

  • 反射:在运行时动态创建对象,适用于需要灵活性的场景。
  • 工厂方法:通过工厂类创建对象,适用于需要统一管理对象创建的场景。
  • 单例模式:确保一个类只有一个实例,适用于需要全局唯一实例的场景。
  • 克隆方法:创建对象的副本,适用于需要复制对象的场景。
  • 对象反序列化:从字节流中恢复对象,适用于需要持久化对象的场景。

9、什么是反射?

在运行状态中,动态获取类的所有信息包括属性,方法等,以及动态调用对象的方法和动态生成对象。

10、有什么异常,分为什么类型

  1. Error(错误)
  2. Exception(异常)
    • 非运行异常
    • 运行时异常(RuntimeException),常见有:空指针(NullPointerException),数组越界(ArrayIndexOutOfBoundsException)

11、== 与 equals 有什么区别?

  • ==:比较的是两个字符串的内存地址
  • equals():比较的是两个字符串的内容

12、StringBuffer和StringBuild区别是什么?

  • StringBuffer:线程安全
  • StringBuild:线程不安全,速度快

13、completableFuture是什么的?

CompletableFuture对Future进行了扩展,可以通过设置回调的方式处理计算结果,同时也支持组合操作,支持进一步的编排,同时一定程度解决了回调函数的问题。

14、怎么把一个对象从一个jvm转移到另一个jvm?

  • 序列化和反序列化
  • 消息传递机制

二、Java集合篇

1、说说Java中的集合?

1)List(有序集合)

  • ArrayList:动态数组,底层是基于数组实现的,当扩容时候,会创建更大的数组,并把原数组复制到新数组。
  • LinkedList本质是一个双向链表,与ArrayList相比,,其插入和删除速度更快,但随机访问速度更慢。

2)Set(无序,唯一)不允许存在重复的元素,与List不同,Set中的元素是无序的。常用的实现有HashSet,LinkedHashSet和TreeSet。

  • HashSet通过HashMap实现,使用HashMap的Key 存储的元素,所有Key都是用相同的Value,这样Key保证了唯一性,但不保证有序性。由于HashSet是HashMap实现的,因此线程不安全。
  • LinkedHashSet继承自HashSet,通过LinkedHashMap实现,使用双向链表维护元素插入顺序。
  • TreeSet通过TreeMap实现的,添加元素到集合时按照比较规则将其插入合适的位置,保证插入后的集合仍然有序。

3)Map 是一个键值对集合Key 无序,唯一;value 不要求有序,允许重复。Map 没有继承于 Collection 接口,从 Map 集合中检索元素时,只要给出键对象,就会返回对应的值对象。主要实现有TreeMap、HashMap.HashTable、LinkedHashMap、ConcurrentHashMap。

  • HashMap:JDK1.8之前HashMap主要由数组+链表构成,数组是HashMap主体。

2、Java中的线程安全的集合是什么?

  • Vector:线程安全的动态数组,其内部方法基本都经过synchronized修饰
  • Hashtable:线程安全的哈希表,加锁的方式是给每个方法加锁,导致所致的是整个Table对象。
  • ConcurrentHashMap:它与HashTable的主要区别是二者加锁力度不同。JDK1.7加的是分段锁,也就是所谓的Segment锁,每个Segment锁含有整个table的一部分,这样不同分段之间的并发操作就互不影响。在JDK1.8,他取消了Segment字段,直接在table元素上锁,实现对每一行进行加锁,进一步减少了并发冲突
  • ConcurrentSkipListSet。
  • CopyOnWriteArraySet
  • CopyOnWriteArrayList

3、Collections和Collection的区别

4、为什么ArrayList不是线程安全的,具体来说是哪里不安全?

高并发添加数据下

  • 部分值为null
  • 索引越界异常
  • size与我们add的数量不符

5、ArrayList的扩容机制说一下

6、线程安全的 List, CopyonWriteArraylist是如何实现线程安全的

7、HashMap的底层原理介绍一下

JDK1.7
JDK1.8优化了1.7中数组扩容的方案,解决了Entry链表死循环和数据丢失问题,就是把尾插法变成了头插法

8、了解的哈希冲突解决方法有哪些?

9、hashmap的put过程介绍一下?

7、扩容操作

  • 创建一个新的两倍大小的数组。
  • 将旧数组中的键值对重新计算哈希码并分配导新数组中的位置。

10、ConcurrentHashMap怎么实现的?

JDK1.7
JDK1.8

11、ConcurrentHashMap用了悲观锁还是乐观锁?

12、HashTable 底层实现原理是什么?

13、Set集合有什么特点?如何实现key无重复的?

  • Set集合特点:Set集合中的元素是唯一的,不会出现重复的元素,且是无序的。
  • Set实现原理:Set集合底层是哈希表,通过hashCode值来确定元素的存储位置,然后通过equals方法判断是否已经存在相同的元素,如果存在不插入,保证了元素的唯一性。

14、有序的Set是什么?记录插入顺序的集合是什么?

  • TreeSet:基于红黑树实现,保证元素的自然顺序。
  • LinkedHashSet:基于双重链表和哈希表的结合来实现元素的有序存储,保证元素添加的自然顺序

三、Java并发篇

1、Java的线程安全在三个方面的体现

  • 原子性
  • 可见性
  • 有序性

2、保证数据的一致性有哪些方案呢?

  • 事务管理
  • 锁机制
  • 版本控制:可以通过乐观锁的方式,在更新数据时记录数据的版本信息,从而避免同时对同一数据进行修改,进而保证数据的一致性。

3、线程的创建方式有哪些?

  1. 继承Thread类
class MyThreadextends Thread {@override
public void run(){
//线程执行的代码
public static void main(string[] args){MyThread t= new MyThread();t.start();
  1. 实现Runable接口
class MyRunnable implements Runnable {@override
public void run(){
// 线程执行的代码
public static void main(string[] args){
Thread t = new Thread(new MyRunnable());t.start();
  1. 实现Callable接口与FutureTask
class MyCallable implements callable<Integer>
@override
public Integer call()throws Exception {//线程执行的代码,这里返回一个整型结果return 1;
public static void main(string[] args){MyCallable task = new MyCallable();FutureTask<Integer>futureTask = new FutureTask<>(task);Thread t = new Thread(futureTask);t.start();
try {
Integer result= futureTask.get(); // 获取线程执行结果System.out.println("Result:"+ result);}catch(InterruptedExceptionExecutionException e){e.printstackTrace();
  1. 使用线程池

4、Java线程的状态有哪些?

  • New:尚未启动的线程状态,即所谓的线程创建,还未调用start方法
  • RUNNABLE:就绪状态(已经调用start,等待调度)+正在运行
  • BLOCKED:获取锁失败,陷入阻塞状态
  • WAITING:等待状态的线程正在等待另一个线程执行完毕
  • TIMED_WAITING:具有指定等待时间的等待状态
  • TERMINATED:线程终止状态。

5、wait 状态下的线程如何进行恢复到 running 状态?

  • 等待的线程被其他线程对象唤醒,notify()和notifyAll()

6、如何保证多线程安全?

  • 使用synchronized关键字
  • volatile关键字,保证变量对所有线程都是可见的
  • Lock接口和ReentrantLock类。
  • 线程局部变量:ThreadLocal线程变量副本。
  • 并发集合

7、Java中有哪些常用的锁?

  • 内置锁(synchronized)
  • ReentrantLock
  • 读写锁(ReadWriteLock):允许多个读取中同时访问共享资源,但是只允许一个写入者
  • 乐观锁和悲观锁
  • 自旋锁

8、synchronized和reentrantlock的工作原理

1、synchronized工作原理
使用synchronized之后,会在编译之后在同步的代码块前后加上monitorenter和monitorexit字节码指令,它依赖操作系统底层互斥锁实现。他的作用主要就是实现原子性操作和解决共享变量的内存可见性问题。
执行monitorenter指令时会尝试获取对象锁,如果对象没有被锁定或者已经获得了锁,锁的计数器+1。此时其他竞争锁的线程则会进入等待队列中。执行monitorexit指令时则会把计数器-1,当计数器值为0时,则锁释放,处于等待队列中的线程再继续竞争锁。
synchronized是排它锁,当一个线程获得锁之后,其他线程必须等待该线程释放锁后才能获得锁,而且由于Java中的线程和操作系统原生线程是-一对应的,线程被阻塞或者唤醒时时会从用户态切换到内核态,这种转换非常消耗性能。
从内存语义来说,加锁的过程会清除工作内存中的共享变量,再从主内存读取而释放锁的过程则是将工作内存中的共享变量写回主内存。
实际上大部分时候我认为说到monitorenter就行了,但是为了更清楚的描述,还是再具体一点。
如果再深入到源码来说,synchronized实际上有两个队列waitSet和entryList
1.当多个线程进入同步代码块时,首先进入entryList
2.有一个线程获取到monitor锁后,就赋值给当前线程,并且计数器+1。
3.如果线程调用wait方法,将释放锁,当前线程置为nul,计数器-1,同时进入waitset等待被唤醒,调用notify或者notifyAll之后又会进入entryList竞争锁
4.如果线程执行完毕,同样释放锁,计数器-1,当前线程置为null。

2、Reentranlock工作原理
在这里插入图片描述

9、详细介绍一下Java中的wait,join,sleep方法

  1. wait() 方法
    wait() 方法是 Object 类中的一个方法,任何对象都可以调用该方法。它用于使当前线程进入 等待状态,并释放当前对象的锁。wait() 必须在同步方法或同步代码块中调用。

主要特性:
释放锁:调用 wait() 后,当前线程释放对该对象的锁,并且进入等待队列中,直到被其他线程唤醒。
唤醒机制:当前线程被唤醒后(通过 notify() 或 notifyAll()),会重新争夺该对象的锁才能继续执行。
使用场景:wait() 方法常用于实现线程间的协调机制,例如生产者-消费者模式、线程间的同步等。

  1. join() 方法
    join() 方法是 Thread 类中的方法,作用是让当前线程等待调用 join() 方法的线程执行完毕。换句话说,它会让当前线程 加入到其他线程 的执行中,当前线程会等待被调用线程结束后再继续执行。

主要特性:
线程等待:调用 join() 后,当前线程会等待目标线程执行完毕,当前线程才会继续执行。
没有锁机制:join() 方法不涉及锁机制,主要是线程的执行顺序控制。
使用场景:join() 常用于在多线程环境中,需要等待某个线程完成后再继续执行其他操作的场景。

  1. sleep() 方法
    sleep() 是 Thread 类中的静态方法,用于让当前线程 休眠指定的时间,在此期间当前线程不占用 CPU 资源。

主要特性:
不释放锁:sleep() 只是让当前线程暂停执行指定的时间,不会释放持有的锁。
精确度:sleep() 的时间精度不一定很高,它是由操作系统来调度的,因此有可能在超时时间之前或之后被唤醒。
使用场景:sleep() 主要用于让线程暂停一段时间,例如定时任务、控制线程执行间隔等。

10、synchronized和Reentrantlock区别?

共同点:

  • 都是可重入锁
  • 都能保证数据的一致性

不同点:

  • 用法不同:synchronized可用来修饰方法、代码块,而Reentrantlock只能用在代码块上。
  • 获取锁和释放锁方式不同:synchronized会自动加锁和释放锁,当进入synchronized修饰的代码块之后就会自动加锁,当离开代码块时候自动释放锁。而Reentrantlock需要手动加锁和释放锁。
  • 锁类型不同:synchronized属于非公平锁而 ReentrantLock 既可以是公平锁也可以是非公平锁。
  • 响应中断不同:ReentrantLoeck 可以响应中断,解决死锁的问题,而 synchronized 不能响应中断
  • 底层实现不同:synchronized 是JVM层面通过监视器实现的,而ReentrantLoeck 是基于AQS实现的。

11、如何理解可重入锁?

可重入锁指的是同一个线程在获取了锁之后,可以再次重复获取该锁而不会造成死锁或者其他问题。

12、ReentrantLock和synchronized 如何实现可重入锁的?

1、ReentrantLock:

ReentrantLock实现可重入锁的机制是基于线程持有锁的计数器。
当一个线程第一次获取锁时,计数器会+1,表示该线程持有了锁。在此之后,如果同一个线程再次获取锁,计数器会再次加1。每次线程成功获取锁时,都会将计数器加1。当线程释放锁时,计数器会相应地减1。只有当计数器减到0时,锁才会完全释放,其他线程才有机会获取锁。
这种计数器的设计使得同一个线程可以多次获取同一个锁,而不会造成死锁或其他问题。每次获取锁时,计数器加1;每次释放锁时,计数器减1。只有当计数器减到0时,锁才会完全释放。
ReentrantLock通过这种计数器的方式,实现了可重入锁的机制。它允许同一个线程多次获取同一个锁,并且能够正确地处理锁的获取和释放,避免了死锁和其他并发问题。

2、synchronized
在底层实现上,synchronized 锁的重入性通过 锁的计数器 来实现。每当一个线程获取锁时,锁的计数器就增加 1。当该线程释放锁时,计数器减 1。只有当计数器减到 0 时,其他线程才能获得锁。

13、syncronized锁升级的过程讲一下

详细了解锁升级过程请前往:https://blog.csdn.net/a147775/article/details/141461091

14、什么是AQS和CAS

1、AQS
AQS 是 java.util.concurrent 包中的一个抽象类,用于构建同步器,锁。它为实现各种同步机制(如锁、信号量、读写锁等)提供了基础框架。
它的主要核心思想:通过队列化等待线程和原子状态更新来实现同步控制。

2、CAS
CAS 是一种原子操作,,它主要有三个操作数:内存地址、旧值、新值。主要作用就是比较内存中的值与旧值是否相等,如果相等就将内存中的值更新为新增。

3、总结
AQS:提供了一个基础框架,用于实现自定义同步器。它管理线程的等待队列和同步状态,支持多种同步机制的实现。
CAS:是一种无锁的原子操作,用于原子地比较和更新内存中的值,广泛用于构建无锁数据结构和高效的并发控制。

15、Threadlocal作用,原理,具体里面存的key value是啥,会有什么问题,如何解决?

详细了解请前往https://blog.csdn.net/a147775/article/details/141723123

16、悲观锁和乐观锁的区别?

  • 乐观锁:乐观锁认为不会有数据竞争发生,对数据不进行加锁操作,而是通过一些机制(如版本号、时间戳等)检查是否发生了冲突,如果发生冲突则回滚或者进行重试操作。
  • 悲观锁:认为数据竞争会发生,始终加锁防止并发冲突。

17、Java中想实现一个乐观锁,都有哪些方式?

  • CAS操作
  • 版本号控制
  • 时间戳

18、CAS 有什么缺点?

  • ABA问题:更新时候,读取到的是A值,然后准备进行赋值时候仍然是A,实际是A->B->A这个过程了
  • 循环时间开销大:自旋CAS的方式如果长时间不成功,会给CPU带来很大的开销
  • 只能保证一个共享变量的原子操作:只对一个共享变量操作可以保证原子性,多个就不行。

19、voliatle关键字有什么作用?

  • 保证变量对所有线程的可见性
  • 禁止指令重排序

20、什么是公平锁和非公平锁?

1、公平锁(Fair Lock)

公平锁的基本概念是:线程按请求锁的顺序来获取锁,即 先进先得(First Come, First Served)。在公平锁中,先请求锁的线程会先获得锁,后请求的线程必须等到前面的线程释放锁后才能获取锁,避免线程饥饿。

2、非公平锁(Non-fair Lock)

非公平锁的基本概念是:线程不严格按照请求锁的顺序获取锁,即任何线程都可以抢先获得锁。在非公平锁的策略中,如果锁当前没有被占用,任何线程都可以尝试获取锁,即使它们不是按请求顺序来的。非公平锁通常会优先让等待时间较短的线程或者刚进入的线程获取锁,而不是按照队列中的顺序来。

21、介绍一下线程池的工作原理

  1. 线程池中始终存在着核心线程数,提交任务时候会分配核心线程去执行,如果核心线程都在处理任务,此时加入任务就会将任务加入到等待队列,如果核心线程数始终在执行其他任务,任务一直在提交直到等待队列满了,此时会增加线程,如果达到最大线程数,再有任务提交就会执行一些丢弃的任务策略

22、线程池的参数有哪些?

  1. 核心线程数(corePoolSize)
  2. 最大线程数(maximumPoolSize)
  3. 空闲线程存活时间(keepAliveTime)
  4. Unit:存活时间单位
  5. 任务队列(workQueue)
  6. 线程工厂(threadFactory)
  7. 拒绝策略(rejectedExecutionHandler)

23、线程池工作队列满了有哪些拒接策略?

  • AbortPolicy(默认策略):抛出 RejectedExecutionException 异常,拒绝执行新任务。
  • CallerRunsPolicy:使用线程池的调用者所在的线程去执行被拒绝的任务
  • DiscardPolicy:直接丢弃任务,不做任何处理。
  • DiscardOldestPolicy:丢弃队列中最旧的任务,提交当前任务。

24、线程池种类有哪些?

1、Fixed Thread Pool(固定大小线程池)

FixedThreadPool 是一种固定大小的线程池。它创建的线程数固定,线程池中的线程数量不会动态调整。无论任务的数量如何,线程池中始终保持着相同数量的线程来处理任务。如果线程池中有线程处于空闲状态,它将等待新任务的到来。如果任务数超出了线程池的处理能力,任务将被放入任务队列中等待。

适用场景:线程数量固定、任务量较为均匀且系统负载不希望波动的情况

示例:

  public static void main(String[] args) {// 创建一个固定大小为 3 的线程池ExecutorService executor = Executors.newFixedThreadPool(3);// 提交任务for (int i = 0; i < 5; i++) {executor.submit(() -> {System.out.println(Thread.currentThread().getName() + " is executing task");});}// 关闭线程池executor.shutdown();}

2、 Cached Thread Pool(缓存线程池)

CachedThreadPool 是一种能够根据需求自动扩展的线程池。线程池中的线程数量是动态变化的:如果线程池中有空闲线程,它会复用这些线程来执行任务。如果所有的线程都在忙碌,线程池会创建新的线程来处理任务。当线程空闲超过一定时间(默认 60 秒),它们会被回收。

适用场景:任务执行时间短且任务量不确定的场景,适合高并发的任务,但不会造成线程过多的系统资源浪费。

示例:

public static void main(String[] args) {// 创建一个固定大小为 3 的线程池ExecutorService executor = Executors.newCachedThreadPool();// 提交任务for (int i = 0; i < 5; i++) {executor.submit(() -> {System.out.println(Thread.currentThread().getName() + " is executing task");});}// 关闭线程池executor.shutdown();}

3、Single Thread Executor(单线程池)

SingleThreadExecutor 是一种只有一个工作线程的线程池。这个线程池用于确保只有一个线程执行任务。所有提交的任务会按照顺序一个一个执行,不会并行执行。如果这个唯一的工作线程异常终止,线程池会创建一个新的线程来代替它。

适用场景:任务需要按顺序执行,且不希望并发执行,适用于顺序依赖的任务,或者需要保证任务执行顺序的场景。

4、 Scheduled Thread Pool(定时任务线程池)

ScheduledThreadPoolExecutor 是一种支持定时任务和周期性任务的线程池。它不仅可以执行定时任务,还可以周期性地执行任务(比如每隔一段时间执行一次任务)。它的主要用途是执行延迟任务或定时任务。

适用场景:需要延迟执行或者定时执行任务的场景,例如定时清理缓存、定期检查系统健康状态等。

5、Custom Thread Pool(自定义线程池)

除了使用 Executors 提供的线程池外,Java 也允许开发者根据业务需求自定义线程池。通过 ThreadPoolExecutor 构造器,可以手动配置线程池的参数,制定核心线程数、最大线程数、任务队列、线程工厂和拒绝策略等。

总结

FixedThreadPool:固定数量的线程池,适用于任务量稳定且线程数固定的场景。
CachedThreadPool:可根据需求动态扩展线程数,适用于任务执行时间短且任务量不确定的场景。
SingleThreadExecutor:只有一个线程的线程池,适用于需要按顺序执行的场景。
ScheduledThreadPoolExecutor:定时和周期性任务线程池,适用于定时任务。
ThreadPoolExecutor:自定义线程池,允许开发者根据具体业务需求配置线程池。

四、Spring+SpringBoot+SpringCloud篇

1、Spring框架的核心特性有什么?

  • IOC容器:Spring通过控制反转实现了对象的创建和依赖关系的管理。
  • AOP:面向切面编程。
  • 事务管理
  • MVC框架:采用了模型-视图-控制器架构。

2、Spring IOC、Spring IOC容器分别是什么?二者有何区别?

1、IOC
它是Spring框架的核心概念之一,翻译为控制反转。它是一种设计原则思想,意味着创建对象控制权的转移。在传统的编程模式下,对象的创建和管理都是通过程序员进行控制,但在IOC中,是通过容器来创建和管理对象的生命周期和依赖关系,从而实现了控制权的反转。

关键特性

  • 反转控制:程序员不再手动创建对象和处理依赖关系,Spring 容器会根据配置来创建对象并注入其所依赖的其他对象。
  • 依赖注入(DI):IOC 容器通过依赖注入的方式将对象的依赖关系自动注入,而不需要显示地通过代码来创建依赖对象。

2、IOC容器
它是 Spring 框架中用于实现IOC设计思想的核心组件,它是一个用来管理Spring 应用程序中对象的创建、管理对象的生命周期以及处理对象间依赖关系的容器
Spring 提供了两种主要的 IOC 容器:

BeanFactory:最简单的容器,提供了基本的 IOC 功能。它在创建 Bean 时是懒加载的。
ApplicationContext:是 BeanFactory 的扩展,提供了更多的功能(如事件传播、国际化支持等),通常应用于实际开发中。

3、总结:
Spring IOC 是一种设计思想和设计模式,它描述了如何将对象的创建和依赖关系交给容器来管理,以实现松耦合。
Spring IOC 容器 是 Spring 框架中实现该设计模式的核心组件,负责管理应用程序中的对象和其生命周期、依赖注入等操作。

3、Spring AOP介绍一下?

AOP是一种面向切面编程思想,它能够将那些与业务无关,却为业务模块锁共同调用的逻辑封装起来,便于减少系统中的重复代码,降低模块间的耦合度,并有利于未来的可扩展性和可维护性。

常用的注解包括

  • @Aspect:用于定义切面,标注在切面类上。
  • @Pointcut:定义切点,标注在方法上,用于指定连接点。。
  • @Before:在方法执行之前执行通知。
  • @After:在方法执行之后执行通知
  • @Around:在方法执行前后都执行通知。
  • @AfterReturning:在方法执行后返回结果后执行通知。
  • @AfterThrowing:在方法抛出异常后执行通知。
  • @Advice:通用的通知类型,可以替代@Before、@After等。

4、IOC和AOP是通过什么机制来实现的?

一、Spring IOC实现机制

  • 反射:通过反射机制,动态的创建对象。
  • 依赖注入:通过构造函数方法注入,属性注入或者方法注入依赖对象。
  • 设计模式-工厂模式
  • 容器实现:Spring lOC容器是实现IOC的核心,通常使用BeanFactory或ApplicationContext来管理Bean。Beanfactory是IOC容器的基本形式,提供基本的IOC功能:ApplicationContext是BeanFactory的扩展,并提供更多企业级功能。

二、Spring AOP实现机制

Spring AOP的实现依赖于动态代理技术。动态代理是在运行时动态生成代理对象,而不是在编译时,从而实现在不修改源码的情况下无侵入式增强方法的功能。

Spring AOP支持两种动态代理

  • 基于JDK的动态代理:代理类实现一个或者多个接口
  • CGLIB动态代理:代理类没有实现接口,可以使用CGLIB库生成一个被代理类的子类作为代理。CGLIB是一个第三方代码生产库,通过继承方式实现代理。

5、静态代理和动态代理的区别是什么?

  • 静态代理:由程序员本身是实现某个接口创建,在代码编译时就被确定了被代理的类是一个静态代理。
  • 动态代理:在运行时利用反射机制动态生成代理对象。

6、spring是如何解决循环依赖的?以及循环产生的原因是什么?

Bean相互依赖造成死循环的原因

假设没有三级缓存机制或其他机制来解决循环依赖,创建过程会是这样:

Spring 初始化 A:发现 A 需要 B,于是开始实例化 B。
Spring 初始化 B:发现 B 需要 A,但 A 还没有创建完成,因此 Spring 无法继续创建 B,也无法返回到创建 A。
死锁:A 和 B 互相等待对方完成实例化,因此无法继续,导致实例化过程无法完成。
总的来说就是相互依赖时,Spring无法确定哪个Bean应该先创建,导致实例化过程陷入死锁。

循环依赖产生:无非就是所谓的A依赖B,然后B依赖A,最后导致循环依赖。
在这里插入图片描述
主要情况:通过setter方法进行依赖注入在单例模式下产生的循环依赖问题。

解决单例模式下的循环依赖问题:主要方式通过三级缓存依赖解决。

7、Spring三级缓存是什么,过程是怎么样的?

Spring 三级缓存机制是 Spring IoC 容器在处理单例 Bean 创建时的一个优化机制,它通过三级缓存(singletonObjects、earlySingletonObjects、singletonFactories)管理 Bean 的不同生命周期阶段,以解决循环依赖和提升性能。

其中三级缓存包含的三个缓存:
1、singletonObjects:存放已经完全初始化的单例Bean。
2、earlySingletonObjects:存放还未完成初始化,但已经实例化的单例Bean,用于早起暴露引用,避免循环依赖。
3、singletonFactories:存放用来创建Bean的工程,实际上一个ObjectFactory,它在实例化是提供创建Bean的逻辑。

对于A依赖B,B依赖A通过三级缓存解决循环依赖过程:
1、创建 Bean A:

Spring 在创建 A 时,发现 A 依赖于 B,于是开始创建 B。
2、创建 Bean B:

在创建 B 时,Spring 发现 B 也依赖于 A,因此产生循环依赖。此时,Spring 会将 B 实例的工厂(ObjectFactory)放入 singletonFactories 中。
此时,Spring 会将 B 的早期引用放入 earlySingletonObjects 中,表示 B 已实例化,但还没有完成初始化(例如,依赖注入和生命周期回调还未完成)。

3、A 依赖 B:

当 A 继续创建时,Spring 会发现 A 依赖于 B(此时 B 已经实例化但尚未完成初始化)。Spring 会从 earlySingletonObjects 中获取 B 的早期引用,完成 A 的实例化。
完成 Bean 初始化:

4、A在实例化完成后:

将注入到B最终A 和 B 会被完全初始化,并被放入 singletonObjects 缓存中。

5、清理缓存:

一旦 A 和 B 完全初始化,earlySingletonObjects 和 singletonFactories 缓存中的数据会被清理,避免内存泄漏。

8、Spring三级缓存的数据结构是什么?

都是Map类型,key:bean的名称,vaule:实例

9、Spring框架中都用到了哪些设计模式?

  • 工厂模式
  • 单例模式
  • 代理模式

10、Spring、Spring MVC、Spring Boot常用的注解?

1、Spring

  • @Component:标记一个类为 Spring 管理的 Bean,Spring 会自动扫描并将其注册为一个 Bean。

  • @Service:表示一个服务层的组件,实际上是 @Component 的一种特化,通常用于标识服务层的业务逻辑类。

  • @Repository:表示一个数据访问层的组件,表示该类为 DAO(Data Access Object)层的组件,用于数据库操作。

  • @Controller:用于定义一个控制器类,处理请求。

  • @Configuration:标识一个配置类,通常用于替代传统的 XML 配置文件。

  • @Bean:用于在 Java 配置类中定义一个 Bean,类似于 XML 配置中的 元素。

  • @Autowired:自动注入依赖的 Bean,可以注入到字段、构造函数、方法上。

2、Spring MVC

  • @RequestMapping:映射 HTTP 请求到指定的方法或类上,支持 GET, POST 等请求类型。通常用于 Spring MVC 控制器类的方法。

  • @GetMapping:用于处理 HTTP GET 请求的快捷方式。

  • @PostMapping:用于处理 HTTP POST 请求的快捷方式。

  • @PutMapping:用于处理 HTTP PUT 请求的快捷方式。

  • @DeleteMapping:用于处理 HTTP DELETE 请求的快捷方式。

  • @RequestParam:用于从请求中获取参数,可以用于方法参数上,来获取请求中的查询参数或表单参数。

  • @PathVariable:用于从 URL 路径中获取动态参数。

@RequestBody:用于将 HTTP 请求体中的数据映射到 Java 对象。

  • @ResponseBody:用于将方法的返回值直接写入 HTTP 响应体中,通常用于返回 JSON 或 XML 格式的数据。

  • @RestControllerAdvice:全局异常处理可以定义多个异常处理方法,来处理不同的异常类型。通过 @ExceptionHandler 注解,方法会捕获指定的异常并返回相应的错误信息。

  • @ExceptionHandler:用于定义异常处理方法,处理控制器方法中抛出的异常。

11、Spring生命周期中的实例化和初始化阶段有何区别?

1、实例化
创建 Bean 实例的过程。Bean 的构造函数被调用,Spring 通过反射生成对象,但还没有进行任何的依赖注入、配置或初始化工作。

2、初始化实例化完成后,Spring 对 Bean 进行依赖注入,在依赖注入完成后,Spring 会调用 @PostConstruct 注解标记的方法。此时,Bean 已经准备好可以使用,并且可以进行一些后续的配置和资源初始化。

总结
实例化
仅仅是创建一个 Bean 对象,它没有进行任何依赖注入或其他配置。

初始化
是 Bean 生命周期中的一个重要阶段,发生在实例化之后,依赖注入完成后,Spring 会执行初始化方法,对 Bean 进行必要的配置和初始化操作。

12、Spring 中Bean的生命周期说一下?

  1. 进行实例化:通过反射机制创建Bean。
  2. 依赖注入: 将容器中的依赖注入到Bean中。
  3. 初始化:执行初始化回调方法。
  4. 可用:Bean可用于服务
  5. 销毁:容器关闭,执行销毁回调方法。

生命周期示意图

          +----------------------+| Bean 实例化           |+----------------------+|v+----------------------+| 依赖注入              |+----------------------+|v+----------------------+| 初始化(@PostConstruct|+----------------------+|v+----------------------+| Bean 可用阶段         |+----------------------+|v+----------------------+| 销毁(@PreDestroy|+----------------------+

13、Spring bean的作用域有哪些?

  • 单例(Singleton)
  • 原型(Prototype)
  • 会话(Session)
  • 请求(Request)

14、MVC分层介绍一下

MVC分层介绍一下
MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范。

  • 模型:存取数据的地方。
  • 视图:与用户直接进行交互界面的地方。
  • 控制器:用于将用户请求转发给对应的Model处理的地方。

15、为什么使用springboot,比Spring好在哪里?

  1. 简化配置
    在传统的 Spring 项目中,你需要大量的 XML 配置(或者在 Java 配置中通过注解进行配置)。这不仅复杂且容易出错,还需要开发人员手动进行许多冗长的配置工作。Spring Boot 的出现大大简化了这一步骤:

  2. 快速启动(快速开发):Spring Boot中提供了许多个"start"模块,并且还内嵌了服务器Tomcat

  3. 开箱即用的功能

16、SpringBoot自动装配原理是什么?

自动装配的核心是EnableAutoConfiguration注解
@EnableAutoConfiguration:启用自动装配,。
@ComponentScan:启用组件扫描,自动扫描当前包及其子包中的 Spring 组件(如 @Component、@Service、@Repository 等)。
@Configuration:指示该类是一个 Spring 配置类。

SpringBoot的自动配置原理是通过@EnableAutoConfiguration注解实现,这个注解包含@Import({AutoConfigurationImportSelector.class})注解,导入的这个类会去扫描 classpath下所有的METAINE/spring.factories中的文件,根据文件中指定的配置类加载相应的 Bean 的自动配置。
这 些Bean通常会使用@Conditional:这是一个核心注解,用来根据条件来决定是否创建某个 Bean等条件注解。来控制自动配置的加载条件,例如仅在类路径中存在某个类时,才加载某些配置。

17、Mybatis里的 #{} 和 ${} 的区别?

#{}:在运行时会传机预编译的SQL语句,将SQL中的#{}替换成?,可防止SQL注入。

${}:只是普通的SQL语句,然后再执行SQL语句时Mybatis将参数直接拼到SQL里,不能防止SQL注入。

18、负载均衡有哪些算法?

  • 简单轮询:将请求按顺序分发给后端服务器上,不关心服务器当前的状态。
  • 加权轮询:根据服务器自身的性能给服务器设置不同的权重。
  • 简单随机:将请求随机分发给后端服务器,请求越多,各个服务器接收到的请求越平均。
  • 加权随机:根据服务器自身的性能给服务器设置不同的权重,将请求按各个服务器的权重随机分发给后端服务器。
  • 一致性哈希
  • 最小活跃数

五、MySQL篇

1、数据库三大范式是什么

  1. 1NF:数据库的每一列都是不可分割的原子数据项。
  2. 2NF:在1NF基础上,非码属性必须完全依赖于候选码。即为每一列都必须和主键相关。
  3. 3NF:在2NF基础上,任何非主属性不依赖于其他非主属性。即为需要确保数据表中的每一列数据都和主键直接相关,而不能间接相关。

2、MySQL 怎么连表查询?

  1. 内连接
  2. 左外连接
  3. 右外连接
  4. 全连接
    在这里插入图片描述

3、MySQL如何避免重复插入数据

  • 使用唯一键约束
  • 使用INSERT IGNORE
  • 使用INSERT … ON DUPLICATE KEY UPDATE

4、CHAR 和 VARCHAR有什么区别?

CHAR
是固定长度的字符串类型,定义时需要指定长度,存储不够时会在末尾补足空格。
VARCHAR
是可变长度的字符串类型,定义时需要指定最大长度,实际存储根据实际长度占用空间计算。

5、mysql中的一些基本函数,你知道哪些?

1、字符串

  • CONCAT:合并字符串
  • LENGTH:计算字符串长度
  • SUBSTRING:截取字符串

2、日期和时间

  • NOW():返回当前日期和时间。
  • CURDATE():返回当前日期。

3、聚合函数

  • COUNT(column):计算指定列中的非NULL值的个数。
  • SUM(column):计算指定列的总和。
  • AVG(column):计算指定列的平均值。
  • MAX(column):返回指定列的最大值。
  • MIN(column):返回指定列的最小值。

6、SQL查询语句的执行顺序是如何的?

  1. 先通过连接器校验权限
  2. 利用分析器进行SQL语句的词法分析和语法分析,构建解析树
  3. 使用优化器选择合适的索引和表连接顺序,最终选择一个最佳的执行计划
  4. 利用执行器,调用引擎层查询数据,返回结果集给客户端。

7、MySQL引擎有哪些,你有什么了解?

  • InnoDB:InnoDB是MySQL的默认存储引擎,具有ACID事务支持、行级锁、外键约束等特性,使用于高并发的读写操作,支持较好的数据完整性和并发控制。
  • MyISAM:MyISAM是MySQL的另一种常见的存储引擎,具有较低的存储空间和内存消耗,适用于大量读操作的场景。然而,MISAM不支持事务、行级锁和外键约束,因此在并发写入和数据完整性方面有一定的限制。
  • Memory:Memory引擎将数据存储在内存中,适用于对性能要求较高的读操作,但是在服务器重启或崩溃时数据会丢失。它不支持事务、行级锁和外键约束。

8、MySQL的InnoDB与MyISAM的区别?

  • 锁:InnoDB支持最小粒度的行级锁,MyISAM不支持,只支持表锁。
  • 索引结构:InnoDB是聚簇索引,MyISAM是非聚簇索引。
  • 事务:InnoDB支持事务,MyISAM不支持

9、索引的分类是什么?

可从四个角度来分类索引。

  • 按(数据结构)分类:B+Tree索引、Hash索引、倒排索引。
  • 按(物理存储)分类:聚簇索引、二级索引。
  • 按(字段特性)分类:主键索引、唯一、普通、前缀索引。
  • 按(字段个数)分类:单列索引、联合索引

10、MySQL聚簇索引和非聚簇索引的区别是什么?

  • 存储位置:聚簇索引的叶子节点包含了实际的数据行,而非聚簇索引的叶子节点不包含完整的数据行。
  • 索引与数据关系,通过聚簇索引查找数据,可以直接从索引中获取数据行。非聚簇索引则需要找到对应的主键值,然后通过主键值回溯到聚簇索引中才能查找到数据,也就是所谓的"回表查询"。
  • 查询效率:聚簇索引更快,非聚簇索引需要进行回表查询数据比较慢。

聚簇索引示意图
在这里插入图片描述
非聚簇索引示意图
在这里插入图片描述

11、索引失效有哪些?

  • 对索引列使用函数
  • 对索引列进行表达式计算
  • 参数是字符串输入是数字类型导致的隐式类型转换
  • 进行模糊匹配:主要方式是:%xx 或者%x%
  • 联合索引最左匹配原则失效
  • where条件中,or前条件是索引列,后不是,索引失效。

12、什么情况回进行回表查询?

查询的数据在二级索引中查询不到就需要进行回表查询。

13、什么是覆盖索引?

覆盖索引:指的是一个索引包含了所需的所有列,不需要进行回表查询数据行就能完成查询。

14、如何进行索引优化?

  • 尽量进行覆盖索引,避免回表查询。
  • 使用前缀索引
  • 主键自增防止页分裂
  • 防止索引失效

15、事务的特性是什么?详细说说

  • 原子性(A):要么所有操作完成,要么回滚
  • 一致性(C):事务操作前后,数据库的数据保持一致状态。
  • 隔离性(I):允许多个并发事务对数据进行读写和修改,不会互相干扰。
  • 持久性(D):数据进行持久化到磁盘,不会丢失。
    MySQL是如何保证这四个特性的?
  • 原子性:通过undo log(回滚日志)保证
  • 持久性:通过redo log(重做日志)。
  • 隔离性:MVCC和锁机制
  • 一致性:上述三个保证

16、MySQL中,什么是脏读,不可重复读,幻读

1、脏读
一个事务读到了另外一个未提交事务修改的数据。
2、不可重复读
一个事务多次读取同一个数据,出现前后两次读到的数据不一致的情况。
3、幻读
一个事务多次查询某个符合条件的记录数量,结果出现前后两次查询到的记录数量不一样的情况。

17、对于并发问题mysql有什么方法解决?

  • MVCC
  • 事务隔离
  • 锁机制

18、事务的隔离级别有哪些?

  • 读未提交
  • 读提交:可解决脏读问题
  • 可重复读:可解决脏读+不可重复读问题
  • 串行化:可解决脏读+不可重复读+幻读

19、MySQL默认的隔离级别是什么?

可重复读

20、MVCC是什么?

MVCC是一种多版本并发控制机制,允许多个事务同时读取和写入数据库,而无需相互等待,从而提高数据库的并发性能。
实现原理
数据库为每个事务创建一个数据快照。每当数据被修改时,MySQL不会立即覆盖原有数据,而是生成新版本的记录。每个记录都保留了对应的版本号或时间戳。通过多版本之间串联起来形成了一条版本链,这样不同时刻启动的事务都可以无锁地获得不同版本的数据。

21、MysSQL中有哪些锁?

  • 全局锁

  • 表级锁

    • 表级锁:对整个表进行加锁,其他事务无法对该表进行任何读写操作。
      • 表共享读锁(lock tables 表明 read):当前客户端和其他客户端都只能进行读操作。
      • 表独占写锁(lock tables 表明 write):当前客户端读写都可以进行,其他客户端读写操作均不可进行
    • 元数据锁(MDL):维护开启事务后每个客户端的sql操作,主要是为了避免DML和DDL操作的冲突。
      • MDL读锁:CRUD关键字都会上锁。
      • MDL写锁:改变表结构时候(alter table)上锁,MDL读锁互斥。
    • 意向锁:为了避免DML执行时解决行锁与表锁的冲突,使得表锁不用检查每行数据是否加了锁,使用意向锁来减少表锁的检查。需要开启事务。
  • 行级锁(重点

    • 行级锁(也称记录锁):仅对特定的行加锁,允许其他事务并发访问不同的行
      • 共享锁**(S 重点)**:允许多个事务并发读取同一资源,但不允许修改。
      • 排他锁 (X 重点):只允许一个事务对资源进行读写,其他事务在获得排他锁之前无法访问资源
    • 间隙锁**(重点)**:针对索引中两个记录之间的间隙加锁,防止其他事务在这个间隙中插入新记录,从而防止出现幻读。
    • 临键锁**(重点)**:行级锁和间隙锁的结合,锁定具体行和其前面的间隙,确保在一个范围内不会出现幻读。常用于支持可重复读的隔离锁级别

22、日志文件是分成了哪几种?

  • redo log:重做日志,实现了事务的持久性
  • undo log:回滚日志,实现了事务的原子性,主要用于事务回滚和MVCC
  • bin log:二进制日志,主要用于数据备份和主从复制。
  • relay log:中继日志,用于主复制场景

23、MySQL中explain有什么作用,并详细说说它的参数?

用来查看sql语句的执行计划,分析sql语句的执行过程,判断是否有走索引等等。

其中主要参数

  1. possible_keys 字段表示可能用到的索引;
  2. key 字段表示实际用的索引,如果这一项为 NULL,说明没有使用索引;:
  3. key_len 表示索引的长度
  4. rows 表示扫描的数据行数。
  5. type 表示数据扫描类型。!!!重点
    type:
  • All(全表扫描)
  • index(全索引扫描)
  • range(索引范围扫描)
  • ref(非唯一索引扫描)
  • eq_ref(唯一索引扫描)
  • const(主键或者唯一索引扫描)

24、MySQL主从复制了解吗,具体复制过程是什么?

MySQL主从复制依赖于binlog,复制的过程就是将binlog中的数据从主库传输到从库中去。
具体详细复制过程

  1. MySQL 主库在收到客户端提交事务的请求之后,先写入 binlog,再提交事务,更新存储引擎中的数据,事务提交完成后,返回给客户端“操作成功“的响应。
  2. 从库会创建一个专门的 I/0 线程,连接主库的 log dump 线程,来接收主库的 binog 日志,再把 binlog 信息写入 relay log 的中继日志里,再返回给主库”复制成功“的响应。
  3. 从库会创建一个用于回放 binlog 的线程,去读 relay log 中继日志,然后回放 binlog 更新存储引擎中的数据,最终实现主从的数据一致性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/479011.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Notepad++ 替换所有数字给数字加单引号

前言 今天遇到这样一个场景&#xff1a; 要去更新某张表里 code1,2,3,4,5,6 的数据&#xff0c;把它的 name 设置为 ‘张三’ 但是 code在数据库里面的字段类型是 vachar(64)&#xff0c;它自身携带索引 原本可以这样写 SQL: update tableA set namezhangsan where code in …

前端图像处理(一)

目录 一、上传 1.1、图片转base64 二、图片样式 2.1、图片边框【border-image】 三、Canvas 3.1、把canvas图片上传到服务器 3.2、在canvas中绘制和拖动矩形 3.3、图片(同色区域)点击变色 一、上传 1.1、图片转base64 传统上传&#xff1a; 客户端选择图片&#xf…

推荐一款龙迅HDMI2.0转LVDS芯片 LT6211UX LT6211UXC

龙迅的HDMI2.0转LVDS芯片LT6211UX和LT6211UXC是两款高性能的转换器芯片&#xff0c;它们在功能和应用上有所差异&#xff0c;同时也存在一些共同点。以下是对这两款芯片的详细比较和分析&#xff1a; 一、LT6211UX 主要特性&#xff1a; HDMI2.0至LVDS和MIPI转换器。HDMI2.0输…

51单片机从入门到精通:理论与实践指南入门篇(二)

续51单片机从入门到精通&#xff1a;理论与实践指南&#xff08;一&#xff09;https://blog.csdn.net/speaking_me/article/details/144067372 第一篇总体给大家在&#xff08;全局&#xff09;总体上讲解了一下51单片机&#xff0c;那么接下来几天结束详细讲解&#xff0c;从…

STM32C011开发(3)----Flash操作

STM32C011开发----3.Flash操作 概述硬件准备视频教学样品申请源码下载参考程序生成STM32CUBEMX串口配置堆栈设置串口重定向FLASH数据初始化FLASH 读写演示 概述 STM32C011 系列微控制器内置 Flash 存储器&#xff0c;支持程序存储与数据保存&#xff0c;具备页面擦除、双字写入…

IDEA无法创建java8、11项目创建出的pom.xml为空

主要是由于Spring3.X版本不支持JDK8&#xff0c;JDK11&#xff0c;最低支持JDK17 解决的话要不就换成JDK17以上的版本&#xff0c;但是不太现实 另外可以参考以下方式解决 修改spring初始化服务器地址为阿里云的 https://start.aliyun.com/

【Unity3D】创建自定义字体

前置准备 如图所示&#xff0c;项目工程中需要用文件夹存储0-9的Sprite图片。 使用流程 直接右键存放图片的文件夹&#xff0c;选择【创建自定义字体】&#xff0c;之后会在脚本定义的FontOutputPath中生成材质球和字体。 源码 using System; using System.Collections.Gene…

logminer挖掘日志归档查找问题

--根据发生问题时间点查找归档文件 select first_time,NAME from gv$archived_log where first_time>2016-03-15 17:00:00 and first_time<2016-03-15 21:00:00; 2016-03-15 17:23:55 ARCH/jxdb/archivelog/2016_03_15/thread_1_seq_41588.4060.906577337 2016-03-15 17:…

电商项目高级篇06-缓存

电商项目高级篇06-缓存 1、docker下启动redis2、项目整合redis 缓存 流程图&#xff1a; data cache.load(id);//从缓存加载数据 If(data null){ data db.load(id);//从数据库加载数据 cache.put(id,data);//保存到 cache 中 } return data;在我们的单体项目中可以用Map作…

如何使用GCC手动编译stm32程序

如何不使用任何IDE&#xff08;集成开发环境&#xff09;编译stm32程序? 集成开发环境将编辑器、编译器、链接器、调试器等开发工具集成在一个统一的软件中&#xff0c;使得开发人员可以更加简单、高效地完成软件开发过程。如果我们不使用KEIL,IAR等集成开发环境&#xff0c;…

一个专为云原生环境设计的高性能分布式文件系统

大家好&#xff0c;今天给大家分享一款开源创新的分布式 POSIX 文件系统JuiceFS&#xff0c;旨在解决海量云存储与各类应用平台&#xff08;如大数据、机器学习、人工智能等&#xff09;之间高效对接的问题。 项目介绍 JuiceFS 是一款面向云原生设计的高性能分布式文件系统&am…

Vue-TreeSelect组件最下级隐藏No sub-options

问题&#xff1a;最下级没有数据的话&#xff0c;去除No sub-options信息 为什么没下级&#xff0c;会展示这个&#xff1f; 整个树形结构数据都是由后端构造好返回给前端的。默认子类没数据的话&#xff0c;children是一个空数组。也就是因为这最下级的空数组&#xff0c;导致…

k8s集群增加nfs-subdir-external-provisioner存储类

文章目录 前言一、版本信息二、本机安装nfs组件包三、下载nfs-subdir-external-provisioner配置文件并进行配置1.下载文件2.修改配置 三、进行部署备注&#xff1a;关于镜像无法拉取问题的处理 前言 手里的一台服务器搭建一个单点的k8s集群&#xff0c;然后在本机上使用nfs-su…

C语言数据结构-链表

C语言数据结构-链表 1.单链表1.1概念与结构1.2结点3.2 链表性质1.3链表的打印1.4实现单链表1.4.1 插入1.4.2删除1.4.3查找1.4.4在指定位置之前插入或删除1.4.5在指定位置之后插入或删除1.4.6删除指定位置1.4.7销毁链表 2.链表的分类3.双向链表3.1实现双向链表3.1.1尾插3.1.2头插…

【SpringCloud详细教程】-04-服务容错--Sentinel

精品专题&#xff1a; 01.《C语言从不挂科到高绩点》课程详细笔记 https://blog.csdn.net/yueyehuguang/category_12753294.html?spm1001.2014.3001.5482 02. 《SpringBoot详细教程》课程详细笔记 https://blog.csdn.net/yueyehuguang/category_12789841.html?spm1001.20…

【Python中while循环】

一、深拷贝、浅拷贝 1、需求 1&#xff09;拷贝原列表产生一个新列表 2&#xff09;想让两个列表完全独立开&#xff08;针对改操作&#xff0c;读的操作不改变&#xff09; 要满足上述的条件&#xff0c;只能使用深拷贝 2、如何拷贝列表 1&#xff09;直接赋值 # 定义一个…

在 Mac(ARM 架构)上安装 JDK 8 环境

文章目录 步骤 1&#xff1a;检查系统版本步骤 2&#xff1a;下载支持 ARM 的 JDK 8步骤 3&#xff1a;安装 JDK步骤 4&#xff1a;配置环境变量步骤 5&#xff1a;验证安装步骤 6&#xff1a;注意事项步骤7&#xff1a;查看Java的安装路径 在 Mac&#xff08;ARM 架构&#xf…

对比C++,Rust在内存安全上做的努力

简介 近年来&#xff0c;越来越多的组织表示&#xff0c;如果新项目在技术选型时需要使用系统级开发语言&#xff0c;那么不要选择使用C/C这种内存不安全的系统语言&#xff0c;推荐使用内存安全的Rust作为替代。 谷歌也声称&#xff0c;Android 的安全漏洞&#xff0c;从 20…

小程序基础:流程。

一、前言 该文章是个人的学习笔记&#xff0c;是学习了黑马程序的微信小程序开发视频后写的笔记&#xff0c;将老师所讲的内容重点汇总起来&#xff0c;目的是为了方便自己日后回顾&#xff0c;同时也方便大家学习和了解小程序的开发 想要入门小程序&#xff0c;那么看这一篇文…

【漏洞复现】CVE-2020-13925

漏洞信息 NVD - CVE-2020-13925 Similar to CVE-2020-1956, Kylin has one more restful API which concatenates the API inputs into OS commands and then executes them on the server; while the reported API misses necessary input validation, which causes the hac…