2024Java面试必备八股文

基础篇

面向对象

面向对象和面向过程是两中不同的问题的处理角度。

面向过程给更注重的是步骤和顺序,面向对象更注重的是参与者

面向过程比较高效,面向对象更易复用,维护,扩展

面向对象有三大特性:

封装:就是隐藏对象的内部实现细节对外暴漏一个接口,外部调用时无需知道内部是如何实现的

继承:基于基类的方法,并作出自己的改变或扩展

多态:多态的前提就是要有继承,方法重写,父类引用指向子类引用,基于对象所属的类不同,外部对同一个方法的调用,实现的是不同的逻辑,但无法调用子类独有的方法(不是对父类进行重写的)

多态的作用

多态的实现要有继承、重写,父类引用指向子类对象。它的好处是可以消除类型之间的耦合关系,增加类的可扩充性和灵活性。

篇幅限制下面就只能给大家展示小册部分内容了。包括了:Java面试、Spring、JVM、MyBatis、Redis、MySQL、并发编程、微服务、Linux、Springboot、SpringCloud、MQ、Kafka 面试专题

需要全套资料及答案的【点击此处即可,免费获取】 备注:“CSDN”

java程序是如何执行的?

先把Java代码编译为字节码,也就是将.java文件编译为.class文件

class文件放入Java虚拟机,这个虚拟机指的是Oracle官方自带的Hotspot JVM

Java虚拟机使用类加载器classLoad装载class文件

加载完成后会,会进行字节码校验,字节码校验通过后JVM解释器会把字节码翻译为机器码交由操作系统执行

静态变量和实例变量的区别

静态变量前static

实例变量属于某个对象的属性,必须创建实例对象,其中实例变量才会被分配空间,才能够使用这个实例变量。静态变量不属于对象,属于类,通常也叫类变量,只要程序加载了类的字节码,不用进行实例化,静态变量就会被分配空间,就能直接使用。

== 和 equals有什么区别?

==基本类型对比比的是值 == 引用类型对比的是地址

而equals方法是Object类中的方法,用于比较两个对象的内容是否相等,即判断两个对象的属性值是否相等。因此,两者的比较方式和比较的内容不同,使用时需要根据具体情况选择合适的方法。

重载和重写的区别

重载是在一个类中方法名称相同 参数列表不同返回值不同权限修饰符不同

重写:是发生在子类和父类之间的,子类继承父类实现父类的方法 方法名相同参数列表相同返回值范围小于等于父类抛出异常的范围要小于等于父类,访问修饰符要大于等于父类;子类为private不能进行重写。

finaly在Java中有什么作用

finaly修饰类类不能被继承

finaly修饰方法 方法不能被重写

finaly修饰变量 变量变为常量 不能被修改必须赋值

异常处理机制

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

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

String属不属于基本类型

不属于,基本数据类型包括:int、double、char、short、byte、boolean、long、float

Java中操作字符串的类,以及他们之间有什么区别?

String StringBuffer StringBuilder

String不是可变长字符串 StringBufferStringBUilder是可边长字符串

每次操作都会生成新的String对象,然后指针指向新生成的String对象,而StringBuffer、StringBuilder可以在原有的对象上进行操作,所以在经常改变字符串内容的情况不要使用String

StringBuffer不是线程安全的StringBUilder是线程安全的

StringBuffer效率比StringBuilder高

String str="i"和String str=new String("i")一样吗?

不一样String str="i"会分配的字符串常量池中,String str=new String("i")会分配到堆内存中

篇幅限制下面就只能给大家展示小册部分内容了。包括了:Java面试、Spring、JVM、MyBatis、Redis、MySQL、并发编程、微服务、Linux、Springboot、SpringCloud、MQ、Kafka 面试专题

需要全套资料及答案的【点击此处即可,免费获取】 备注:“CSDN”

String常用的方法有哪些

indexOf() :返回指定字符的索引

charAt() :根据索引返回指定字符

raplace() :字符串替换

trim() : 去除空格

split() : 根据指定字符分割字符串

getBytes() :返回字符串的byte类型数组

length() :返回字符串的长度

subString() :截取字符串

equals() :把字符串进行比较

toLowerCase() :将字符串转换为小写

toUpperCase() :将字符串转换为大写

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

不是 抽象类可以有非抽象的方法

抽象类和普通类有什么区别

抽象类不能实例化 普通类可以实例化

普通类不能有抽象方法 抽象类可以有抽象方法

抽象类能不能使用finaly

不能使用finally要是用了子类就不能继承就没有意义,编译是也会报错。

接口和抽象列的区别

相似点:

1)接口和抽象类都不能被实例化

2)实现接口或继承抽象类的普通子类都必须实现这些抽象方法

不同点:

1)抽象类可以包含普通方法和代码块,接口里只能包含抽象方法,静态方法和默认方法,

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

3)抽象类中的成员变量可以是各种类型的,接口的成员变量只能是 public static final 类型的,并且必须赋值

Java中的io流分为几类

输入流输出流 字节流字符流

BIO,NIO,AIO有什么区别

Files有什么常用的方法

什么是Java的反射

就是动态的访问类的基本属性和方法

对于任意的一个类,都可以知道他的属性和方法,对于任意一个对象都能调用他的属性和方法,这种动态获取到信息以及动态的调用对象方法的功能被称为Java的反射机制

自定义注解

集合容器

Collection和Cllections的区别

Collection是集合接口,提供了对集合进行基本操作的通用接口方法在Java类库中有很多具体实现

Collections是一个集合的工具类,提供了一系列的静态方法供集合使用

List,Set,Map的区别

List 和Set是conllection的子接口,Map不是和collection平级

List 是有序的 Set是无须的 map 也是无序的

List是不可重复的 Set是可重复的 Map的key是不可以重复的 value是可以重复的

HashMap和HashTable有什么区别

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

(2)HashTable的Key不允许为null HashMap,key不能重复,可以为null

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

(4)HashTable底层使用的数组加链表 hashMapJdk1.8以后是基于数组+链表+红黑树来实现的

篇幅限制下面就只能给大家展示小册部分内容了。包括了:Java面试、Spring、JVM、MyBatis、Redis、MySQL、并发编程、微服务、Linux、Springboot、SpringCloud、MQ、Kafka 面试专题

需要全套资料及答案的【点击此处即可,免费获取】 备注:“CSDN”

说一下HashMap的实现原理?

数据结构:数组+链表实现(扩容是扩容到原来的两倍)

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

原理:当我们向HashMap中put元素时,首先根据key的hashcode重新计算出hash值,再根据hash值得到元素在数组中的位置(下标),如果该数组在其位置存放了其他元素,那么这个位置上的元素将以链表的形式存放,如果链表的高度达到8并且数组长度超过64就会将链表替换成红黑树,如果该位置没有存放其他元素,就直接将该元素放到数组的该位置上

通过进行两次哈希,HashMap 能够尽可能地减少哈希冲突,提高键值对的存取效率。它可以在第一次哈希的基础上,再次进行调整,以找到一个合适的位置存储数据,使得键值对分散在整个哈希表中,尽量避免冲突。

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

(1)使用ConcurrentHashMap

(2)使用HashTable

(3)Collections.synchronizedHashMap()方法

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

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

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

什么是链表?

链表是物理存储单位上,非连续,非顺序的存储单位它是由一个个节点通过指针联系起来的,其中每个节点都包含数据和指针

说一下HashSet的实现原理?

HashSet是由HashMap实现的,Hash底层使用的HashMap来保存数据,所有实现比较简单

ArraysList和LinkedList的区别

ArrayList底层是数组结构LinkedList底层是链表接口

Array的查询效率比LinkedList的查询效率高

但是LinkedList的增加和删除的效率比ArrayList高,ArrayList是数组,在对其增删操作时,会对数据的下标索引造成影响,需要进行数据移动

如何实现数组和List之间的切换?

数组转换为List:使用数组的asList方法

List转换为数据:使用List的toArray()方法

ArrayList的原理

底层是数组实现的,

他的默认长度为十,检查元素的个数是否达到上线,要是达到上限就会进行扩容,扩容的数组是原来数组的1.5倍

ArrayList和Vecot的区别

ArrayList不是线程安全的Vecot是线程安全的

ArrayList的性能比Vecot的性能好

Vecot的扩容是每次都扩容已一倍Arratlist的扩容是扩容给50%

Arrray和ArrayList的区别

Array是能存储进本数据类型和对象ArrayList只能存储对象

Array是指定大小后不可变的,ArrayList是可变的

ArrayhemiArrayList那么多的功能

哪些集合类是线程安全的?

Vecot HashTable Statck enumeration(比较器)

迭代器Iterator是什么?

迭代器是一种设计模式,他是一个对象,它可以遍历并选择序列中的对象,通常称为轻量级对象,因为创建它的代价小

Iterator和IteratorList有什么区别?

Iterator可以来遍历Set和List集合,IteratorList只能用来遍历List集合

Iterator只能进行前向遍历,IteratorList即可以前向也可以后向遍历

IteratorList继承Iterator,并包含其他的功能

篇幅限制下面就只能给大家展示小册部分内容了。包括了:Java面试、Spring、JVM、MyBatis、Redis、MySQL、并发编程、微服务、Linux、Springboot、SpringCloud、MQ、Kafka 面试专题

需要全套资料及答案的【点击此处即可,免费获取】 备注:“CSDN”

多线程

.进程和线程的区别,进程间如何通信

进程:系统运行的基本单位,进程在运行过程中都是相互独立,但是线程之间运行可以相互影响。

线程:独立运行的最小单位,一个进程包含多个线程且它们共享同一进程内的系统资源

进程间通过管道、 共享内存、信号量机制、消息队列通信

. 什么是线程上下文切换

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

并行和并发的区别

并行是两个或多个事件在同一时间进行运行,并发是指两个或多个事件在同一时间间隔进行运行

并行是在不同实体类的多个事件,并发是在同一个实体类的多个事件

创建线程的几种方式

继承Thread类

实现Runnable接口

实现Callable接口

在线程池中创建线程

说一下runnable和callable有什么区别

Runnable和Callable 的返回值不同

Runnable的run方法没有返回值

Callable发call方法有返回值,是个泛型

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

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

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

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

线程有那些状态

创建线程:创建当前线程还没有执行start方法

就绪状态:调用的线程的start方法,线程进入就绪状态

运行状态:将就绪状态的线程设置为当前线程此状态的线程就为运行状态,调用run方法

堵塞状态:线程正在运行被停止

死亡状态:当前线程执行完run方法并且调用stop方法线程变为死亡状态

Sleep和wait有什么区别

Sleep是Thread中的方法 wait是Object的方法

调用Sleep方法不会释放类锁 调用wait方法会释放类锁
wait()要在同步方法或者同步代码块中执行,sleep()没有限制

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

Notify和NotifyAll有什么区别

Notify可能会产生死锁NotifyAll不会产生死锁

NotifyAll会将线程中的所有的睡眠状态的线程唤醒,Notify只会唤醒一个线程

Notify是Notify的一个优化

线程run和start有什么区别

Start方法是启动线程的方法 run方法是运行线程任务逻辑的方法 run方法可以调用多次start只能调用一个

创建线程四种方法的区别

Runnable和Thrable主进程不会获取运行线程的结果

Collable主进程可以获取线程的运行结果,x但是不利于控制服务器中的线程资源,会将资源消耗殆尽

线程池创建线程可以获取线程的运行结果,性能稳定,并能捕获异常,但是在复杂的业务中一个异步调用可能会调用另一个异步调用运行的结果

使用线程池的好处?

较低能量损耗

线程池重复使用已经创建的线程降低线程的创建和销毁损耗的资源

提高线程的响应速度

线程池中的线程数没有超过线程的最大线程数,有些线程进入等待状态,当有任务来临无需创建新的线程就能运行

提高线程的管理性

线程池会根据当前线程的状态来优化线程,减少创建和销毁的带来的损耗无限的创建线程不仅会耗资源还会较低系统的效率,使用线程池进行统一管理

线程池中submit()和execute()方法有什么区别?

接受的参数不同

Submint没有返回值exrcute()有返回值

Submit方便异常的处理

在java程序中怎么保证多线程的安全

体现在三个方面:

原子性:提供互斥访问,同一时刻只能有一个线程对数据操作(atomic,synchronized)

可见性:一个线程对主内存的修改可以被其他线程看到(volatile,synchronized)

有序性:一个线程观察其他线程中的指令执行顺序,由于指令重排序,该观察结果一般杂乱无序(happens-before原则)

什么是死锁

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

线程死锁是指在执行的过程中进行资源的抢夺形成的一种等待的僵局

怎么防止死锁

死锁产生的四个必要条件:

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

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

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

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

想要预防死锁,只需要破坏其中一个条件即可,比如使用定时锁、尽量让线程用相同的加锁顺序,还可以用银行家算法可以预防死锁

ThreadLocal原理

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

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

说一下synchronized底层实现原理?

Synchronized可以保证方法和代码块在运行时在同一时刻只有一个方法或者代码块执行

.Synchronized锁原理和优化

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

篇幅限制下面就只能给大家展示小册部分内容了。包括了:Java面试、Spring、JVM、MyBatis、Redis、MySQL、并发编程、微服务、Linux、Springboot、SpringCloud、MQ、Kafka 面试专题

需要全套资料及答案的【点击此处即可,免费获取】 备注:“CSDN”

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

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

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

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

什么是AQS锁?

AQS是一个抽象类,可以用来构造锁和同步类,如ReentrantLock,Semaphore,CountDownLatch,CyclicBarrier。

AQS的原理是,AQS内部有三个核心组件,一个是state代表加锁状态初始值为0,一个是获取到锁的线程,还有一个阻塞队列。当有线程想获取锁时,会以CAS的形式将state变为1,CAS成功后便将加锁线程设为自己。当其他线程来竞争锁时会判断state是不是0,不是0再判断加锁线程是不是自己,不是的话就把自己放入阻塞队列。这个阻塞队列是用双向链表实现的

可重入锁的原理就是每次加锁时判断一下加锁线程是不是自己,是的话state+1,释放锁的时候就将state-1。当state减到0的时候就去唤醒阻塞队列的第一个线程。

.为什么AQS使用的双向链表?

因为有一些线程可能发生中断 ,而发生中断时候就需要在同步阻塞队列中删除掉,这个时候用双向链表方便删除掉中间的节点

.有哪些常见的AQS锁

AQS分为独占锁和共享锁

ReentrantLock(独占锁):可重入,可中断,可以是公平锁也可以是非公平锁,非公平锁就是会通过两次CAS去抢占锁,公平锁会按队列顺序排队

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

应用场景:允许多个线程访问某个临界资源时,如上下车,买卖票

CountDownLatch(倒计数器):给计数器设置一个初始值,当调用CountDown()时计数器减一,当调用await() 时判断计数器是否归0,不为0就阻塞,直到计数器为0。

应用场景:启动一个服务时,主线程需要等待多个组件加载完毕,之后再继续执行

CyclicBarrier(循环栅栏):给计数器设置一个目标值,当调用await() 时会计数+1并判断计数器是否达到目标值,未达到就阻塞,直到计数器达到目标值

应用场景:多线程计算数据,最后合并计算结果的应用场景

MySql

什么是数据库 为什么要使用数据库

数据库就是数据管理的产物。

数据保存在内存

优点:存取速度快

缺点:数据不能永久保存

数据保存在文件

优点:数据永久保存

缺点:读取速度慢,查询数据不方便

数据保存在数据库

数据永久保存

查询方便效率高

管理数据方便

什么是SQL?

结构化查询语言(Structured Query Language)简称SQL,是一种数据库查询语言

作用:用于存储数据、查询、更新和管理关系数据库系统

MyIsAm和InnoDB的区别(数据库的存储引擎)

InnoDB有三大特性,分别是事务、外键、行级锁,这些都是MyIsAm不支持的,

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

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

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

MyIsAM的访问速度一般比InnoDB快,差异在于innodb的mvcc、行锁会比较消耗性能,还可能有回表的过程(先去辅助索引中查询数据,找到数据对应的key之后,再通过key回表到聚簇索引树查找数据)

数据库的三大范式?

第一范式:每个列都不可再拆分

第二范式:在第一范式的基础上,非主键列完全依赖于主键,而不能是依赖于主键的一部分

第三范式:在第二范式的基础上,非主键列只依赖于主键,不依赖于其他非组件

说一下ACID是什么(数据库的特性)?

Atomicity(原子性):一个事务的中的所有操作,要不全部完成,要不全部不完成,不会出现再中间某个环节结束

Consistency(一致性):在事务开始之前和事务结束以后,数据库的完整性没有被破坏

Isolation(隔离性):防止多个事务再并发执行时由于交叉执行而导致的数据不一致

Durability(持久性):事务结束后,对数据的修改就是永久的,即便系统故障页不会丢失

ACID靠什么保证的呢?

 A原子性(atomicity) 由undo log日志保证,它记录了需要回滚的日志信息,事务回滚时撤销已经执行成功的sql

 C一致性(consistency) 一般由代码层面来保证

 I隔离性(isolation) 由MVCC来保证

 D持久性(durability) 由内存+redo log来保证,mysql修改数据同时在内存和redo log记录这次操作,事务提交的时候通过redo log刷盘,宕机的时候可以从redo log恢复

.MVCC是什么

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

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

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

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

篇幅限制下面就只能给大家展示小册部分内容了。包括了:Java面试、Spring、JVM、MyBatis、Redis、MySQL、并发编程、微服务、Linux、Springboot、SpringCloud、MQ、Kafka 面试专题

需要全套资料及答案的【点击此处即可,免费获取】 备注:“CSDN”

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

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

mysql中的常用语句

- DDL(Data Definition Language):数字定义语句,主要进行定义/改变表的结构、数据类型、表之间的链接等操作。常用语句关键字有create、drop、alter等

- DML(Data Manipulation Language):数据操纵语句,主要对数据进行添加、修改、删除操作,关键字包括inster、delete、update等

- DQL(Data Query Language):数据查询语言,主要对数据库进行查询操作,常用的关键字包括select、from、where等

- DCL(Data Control Language):数据控制语句,主要用来设置/更改数据库用户权限,常用的关键字有grant、remove等

事务的隔离级别

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

先了解下几个概念:脏读、不可重复读、幻读。

脏读是指在一个事务处理过程里读取了另一个未提交的事务中的数据。

不可重复读是指在对于数据库中的某行记录,一个事务范围内多次查询却返回了不同的数据值,这是由于在查询间隔,另一个事务修改了数据并提交了。

幻读是针对数据插入(INSERT)操作来说的。假设事务A对某些行的内容作了更改,但是还未提交,此时事务B插入了与事务A更改前的记录相同的记录行,并且在事务A提交之前先提交了,而这时,在事务A中查询,会发现好像刚刚的更改对于某些数据未起作用,但其实是事务B刚插入进来的,让用户感觉很魔幻,感觉出现了幻觉,这就叫幻读。

读未提交: 允许一个事务读取另一个事务已提交的数据,脏读

读已提交:一个事务只能看见已经提交事务所做的改变。可避免脏读的发生

可重复读: MySQL的默认事务隔离级别,它确保同一事务的多个实例在并发读取数据时,会看到同样的数据行,解决了不可重复读的问题。

可串行化:通过强制事务排序,使之不可能相互冲突,从而解决幻读问题。

如何设计数据库?

(1)抽取实体,如用户信息,商品信息,评论

(2)分析其中属性,如用户信息:姓名、性别...

(3)分析表与表之间的关联关系

然后可以参考三大范式进行设计,设计主键时,主键要尽量小并且定义为自增和不可修改

mysql的视图?

视图是一种虚拟的表,具有和物理表相同的功能,可以对视图进行增、改、查操作,视图通常是有一个表或者多个表的行或列的子集。对视图的修改不影响基本表,它使得我们获取数据更容易,相比多表查询

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

内连接是把匹配的关联数据显示出来,左连接是把左边表的数据显示出来,右边的表显示出符合条件的数据,右连接则相反

索引是一种特殊的文件,它们包含着对数据表里所有引用的指针

索引是一种数据结构,数据库索引是数据库管理系统中一个排序的数据结构,以协助快速查询、更新数据库表中的数据。

通俗来说:索引就相当于目录,为了方便查找书中的内容,通过对内容建立索引形成目录,索引是个文件是要占据物理空间的。

索引有哪些优缺点?

优点:

大大加快数据的检索时间

使用索引可以在查询的过程中使用优化隐藏器,提高系统性能

缺点:

时间方面:创建索引和维护索引要耗费时间,具体的,当对表中的数据进行增删改时,索引也要动态维护,会降低增删改的执行效率

空间方面:索引需要占物理空间

索引的数据结构

索引的数据结构主要有B+树和哈希表,对应的索引分别为B+树索引和哈希索引。InnoDB引擎的索引类型有B+树索引和哈希索引,默认的索引类型为B+树索引。

Hash索引和B+树索引的区别?

哈希索引不支持排序,因为哈希表是无序的。

哈希索引不支持范围查找。

哈希索引不支持模糊查询及多列索引的最左前缀匹配。

因为哈希表中会存在哈希冲突,所以哈希索引的性能是不稳定的,而B+树索引的性能是相对稳定的,每次查询都是从根节点到叶子节点。

为什么B+树比B树更适合实现数据库索引?

B+数的数据储存是在叶子节点上的,叶子节点均为 索引方便扫库,B树的分支节点也同样存储数据我们要是查找数据还要进行再一次的遍历,就比较麻烦,因为在数据库中基于范围的查找都是比较频繁的所以使用B+树索引,

B+树的节点只存储索引key值,具体信息的地址存在于叶子节点的地址中。这样就可以存放更多的节点。

B+树的查询效率更加稳定,任何关键字的查找必须走一条从根结点到叶子结点的路。所有关键字查询的路径长度相同,导致每一个数据的查询效率相当。

MySQL有哪些索引

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

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

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

篇幅限制下面就只能给大家展示小册部分内容了。包括了:Java面试、Spring、JVM、MyBatis、Redis、MySQL、并发编程、微服务、Linux、Springboot、SpringCloud、MQ、Kafka 面试专题

需要全套资料及答案的【点击此处即可,免费获取】 备注:“CSDN”

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

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

0

哪些情况索引会失效

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

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

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

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

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

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

where和having的区别?

where是约束声明,having是过滤声明,where早于having执行,并且where不可以使用聚合函数,having可以

MySQL 锁的类型有哪些呢?

说两个维度:

共享锁(简称S锁)和排他锁(简称X锁)

读锁是共享的,可以通过lock in share mode实现,这时候只能读不能写。

写锁是排他的,它会阻塞其他的写锁和读锁。从颗粒度来区分,可以分为表锁和行锁两种。

表锁和行锁

表锁会锁定整张表并且阻塞其他用户对该表的所有读写操作,比如alter修改表结构的时候会锁表。

行锁又可以分为乐观锁和悲观锁

悲观锁可以通过for update实现

乐观锁则通过版本号实现

说一下乐观锁和悲观锁?

数据库中的并发控制是确保在多个事务同时存取数据库中同一数据时不破坏事务的隔离性和统一性以及数据库的统一性。乐观锁和悲观锁是并发控制主要采用的技术手段。

悲观锁:。假设会发生并发冲突,会对操作的数据进行加锁,直到事务提交,才会释放锁,其他的事务才能对数据进行修改

实现方式:使用数据库中的锁机制

乐观锁:假设不会发生并发冲突,只在提交操作时检查是否数据是否被修改过。给表增加version字段,在修改提交之前检查version与原来取到的version值是否相等,若相等,表示数据没有被修改,可以更新,否则,数据为脏数据,不能更新。

实现方式:乐观锁一般使用版本号机制或CAS算法实现。

什么是MySQL主从同步?

主从同步使得数据可以从一个数据库服务器复制到其他服务器上,在复制数据时,一个服务器充当主服务器(master),其余的服务器充当从服务器(slave)。

因为复制是异步进行的,所以从服务器不需要一直连接着主服务器,从服务器甚至可以通过拨号断断续续地连接主服务器。通过配置文件,可以指定复制所有的数据库,某个数据库,甚至是某个数据库上的某个表。

为什么要做主从同步?

读写分离,使数据库能支撑更大的并发。

在主服务器上生成实时数据,而在从服务器上分析这些数据,从而提高主服务器的性能。

数据备份,保证数据的安全。

讲一下MySQL架构?

MySQL主要分为 Server 层和存储引擎层:

Server 层:主要包括连接器、查询缓存、分析器、优化器、执行器等,所有跨存储引擎的功能都在这一层实现,比如存储过程、触发器、视图,函数等,还有一个通用的日志模块 binglog 日志模块。

存储引擎: 主要负责数据的存储和读取。server 层通过api与存储引擎进行通信。

Server 层基本组件

连接器: 当客户端连接 MySQL 时,server层会对其进行身份认证和权限校验。

查询缓存: 执行查询语句的时候,会先查询缓存,先校验这个 sql 是否执行过,如果有缓存这个 sql,就会直接返回给客户端,如果没有命中,就会执行后续的操作。

分析器: 没有命中缓存的话,SQL 语句就会经过分析器,主要分为两步,词法分析和语法分析,先看 SQL 语句要做什么,再检查 SQL 语句语法是否正确。

优化器: 优化器对查询进行优化,包括重写查询、决定表的读写顺序以及选择合适的索引等,生成执行计划。

执行器: 首先执行前会校验该用户有没有权限,如果没有权限,就会返回错误信息,如果有权限,就会根据执行计划去调用引擎的接口,返回结果。

如何做mysql性能优化?

建立合适的索引

开启慢查询日志,记录执行速度慢的sql,对慢sql语句进行优化

优化sql语句执行效率的方案:

为搜索字段(where中的查询条件)、排序字段、select查询列,创建合适的索引

尽量建立组合索引并注意组合索引的创建顺序,按照顺序组织查询条件、尽量将筛选力度大的查询条件放到左边

尽量使用覆盖索引

select语句中尽量不要使用*

order by和group by语句尽量使用到索引

where条件中尽量不要使用1=1、not in语句(推荐使用not exists)

不用mysql的内置函数,内置函数不会建立查询缓存

尽量不用count(*) 、尽量使用使用count(主键)

MyBatis

什么是Mybatis?

MyBatis是一个半ORM(对象关系映射)框架,它对jdbc的操作数据库的过程进行封装,使开发者只需要关注 SQL 本身,而不需要花费精力去处理例如注册驱动、创建connection、创建statement、手动设置参数、结果集检索等jdbc繁杂的过程代码。他是为简化数据库操作而设计的。MyBatis通过配置文件或者注解即可将数据库数据与pojo实体类联系起来

Mybatis通过xml或注解的方式将要执行的各种statement配置起来,并通过java对象和statement中的sql进行映射生成最终执行的sql语句,最后由mybatis框架执行sql并将结果映射成java对象并返回。

由于MyBatis专注于SQL本身,灵活度高,所以比较适合对性能的要求很高,或者需求变化较多的项目,如互联网项目。

什么是 半自动化(半ORM)

Mybatis 在查询关联对象或关联集合对象时,需要手动编写 sql 来完成,所以,称之为半自动 ORM 映射工具

Mybaits的优缺点:

(1)优点:

消除jdbc中的重复代码

可以在XML或注解中直接 编写SQL语句,比较灵活,方便对SQL的优化和调整

SQL在XML中与代码解耦,按照对应关系方便管理

XML中提供了动态SQL的标签,方便根据条件拼接SQL

提供了XML、注解与Java对象的映射机制

与spring集成比较方便。

(2)缺点:

字段较多、关联表多时,编写SQL工作量较大

SQL语句依赖了数据库特性,会导致程序的移植性差,切换数据库困难

篇幅限制下面就只能给大家展示小册部分内容了。包括了:Java面试、Spring、JVM、MyBatis、Redis、MySQL、并发编程、微服务、Linux、Springboot、SpringCloud、MQ、Kafka 面试专题

需要全套资料及答案的【点击此处即可,免费获取】 备注:“CSDN”

#{}和${}的区别是什么?

${}是字符串替换,#{}是预处理;使用#{}可以有效的防止SQL注入,提高系统安全性。

Mybatis在处理${}时,就是把${}直接替换成变量的值。而Mybatis在处理#0{}时,会对sql语句进行预处理,将sql中的#{}替换为?号,调用PreparedStatement的set方法来赋值;

实体类中的属性名和表中的字段名不一致时,怎么办?

使用查询时sql语句定义别名,让字段名的别名和实体类的属性名对应

通过<ResultMap>来映射字段名和实体类属性名一一对应

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值