2024Java面试题附答案(面试必会)

1.JDK和JRE区别

JRE(Java Runtime Enviroment)是运行Java程序所必须环境的集合,包含JVM标准实现及 Java核心类库。它包括Java虚拟机、Java平台核心类和支持文件。它不包含开发工具(编译器、调试器等)。
JDK(Java Development Kit)是Java开发工具包,它提供了Java的开发环境(提供了编译器javac等工具,用于将java文件编译为class文件)和运行环境(提供了JVM和Runtime辅助包,用于解析class文件使其得到运行)。

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

需要全套资料及答案的在【翻到文章底部,点击名片】即可免费获取 备注:“CSDN”

2.八大数据类型

分别是byte, short, int, long, char, float, double, boolean.
1.byte
byte属于Java中的整型,长度为1字节8bit,取值10000000(-128)到 01111111(127),变量初始化默认值为0,包装类Byte

2.short
short属于Java中的整型,长度为2字节16bit,取值10000000 00000000(-32768)到 01111111 11111111(32767),变量初始化默认值为0,包装类Short

3.int
int属于Java中的整型,长度为4字节32bit,取值-2^31 (-2,147,483,648)到 2^31-1(2,147,483,647),变量初始化默认值为0,包装类Integer

4.long
long属于Java中的整型,长度为8字节 64bit,取值-2^63 (-9,223,372,036,854,775,808‬)到 2^63-1(9,223,372,036,854,775,8087),变量初始化默认值为0或0L,包装类Long
5.float
float属于Java中的浮点型,也叫单精度浮点型,长度为4字节 32bit,变量初始化默认值0.0f,包装类Float,取值2-128~2128
6.double
double属于Java中的浮点型,也叫双精度浮点型,长度为8字节 64bit,变量初始化默认值0.0d,包装类Double,取值2-1024~21024
7.char
char属于java中的字符型,占2字节 16bit,可以赋值单字符以及整型数值, 变量初始化无默认值,包装类Character。
如:
char a = ‘a’;
char a = ‘中’;
char a = 12; // 取值范围0~65536,因为char类型在ASCII字符编码中,有对应的数值,可直接做运算,输出字符表中对应的字符

8.boolean
在JVM中并没有提供boolean专用的字节码指令,而boolean类型数据在经过编译后在JVM中会通过int类型来表示,此时boolean数据4字节32位,而boolean数组将会被编码成Java虚拟机的byte数组,此时每个boolean数据1字节占8bit.
仅有两个值true, false,变量初始化默认值false

3.equals和==区别

对于==,一般比较的是值是否相等 如果作用于基本数据类型的变量,则直接比较其存储的 “值”是否相等; 如果作用于引用类型的变量,则比较的是所指向的对象的地址

对于equals方法,一般为比较内容是否相同 如果没有对equals方法进行重写,则比较的是引用类型的变量所指向的对象的地址; 诸如String、Date等类对equals方法进行了重写的话,比较的是所指向的对象的内容。

4.String类的常用方法
  • public int length() //返回该字符串的长度
  • public char charAt(int index) //返回字符串中指定位置的字符;注意字符串中第一个字符索引是0,最后一个是length()-1。
  • public int compareTo(String anotherString) //该方法是对字符串内容按字典顺序进行大小比较,通过返回的整数值指明当前字符串与参数字符串的大小关系。若当前对象比参数大则返回正整数,反之返回负整数,相等返回0。
  • public String toLowerCase()//返回将当前字符串中所有字符转换成小写后的新串
  • public String toUpperCase()//返回将当前字符串中所有字符转换成大写后的新串
  • public String substring(int beginIndex)//该方法从beginIndex位置起,从当前字符串中取出剩余的字符作为一个新的字符串返回。
5.String不可变原理

String 被声明为 final,因此它不可被继承。(Integer 等包装类也不能被继承)
之所以设计成不可变,是为了安全,保证了线程安全,以及让常量池有意义
string不可变的设计出于性能考虑,当然背后的原理是string pool,当然string pool不可能使string类不可变,不可变的string更好的提高性能。

6.线程池三大方法,七大参数,四种拒绝策略

具体答案参考我之前的文章线程池三大方法,七大参数,四种拒绝策略_线程池policy=0-CSDN博客

7.ArrayList 和LinkedList 区别以及底层原理

ArrayList和LinkedList 都实现了list的接口,Al底层是数组,时间复杂度是O(1),Lk底层数据结构是双向循环链表 ,链表只有一个前驱和后继,时间复杂度O(n)
相对来说,Al是数组查找更容易,Lk因为是链表,所以插入、删除比较容易,但是更占内存,因为每一个节点存储了两个引用 ,一个指向前一个元素 一个后。

8.类的实例化顺序

父类静态代变量 父类静态代码块 子类静态变量 子类静态代码块
父类非静态变量 父类构造函数 子类非静态变量 子类构造

9.synchronized 和 ReentrantLock 区别是什么?

1.ReentrantLock 是 API 级别的,synchronized 是 JVM 级别的
2. ReentrantLock 可以实现公平锁
3 ReentrantLock 通过 Condition 可以绑定多个条件
4. 底层实现不一样, synchronized 是同步阻塞,使用的是悲观并发策略,lock 是同步非阻塞,采用的是乐观并发策略
5. Lock 是一个接口,而 synchronized 是 Java 中的关键字,synchronized 是内置的语言实现。
6. synchronized 在发生异常时,会自动释放线程占有的锁,因此不会导致死锁现象发生;
而 Lock 在发生异常时,如果没有主动通过 unLock()去释放锁,则很可能造成死锁现象,
因此使用 Lock 时需要在 finally 块中释放锁。
7.通过 Lock 可以知道有没有成功获取锁,而 synchronized 却无法办到。

10.HashMap底层原理(重点)

hashMap是线程不安全的,HashMap是数组+链表+红黑树(JDK1.8增加了红黑树部分)实现的,采用哈希表来存储的,hashMap是根据键的hashCode值存储数据,又很快的访问速度,但是遍历顺序不确定 hashMap是一对一或一对多的关系 键只允许有一个空值 value可以有多个 当键相同时 会覆盖掉value值
底层实现原理:
HashMap4种构造方法 指定初始大小和负载因子 指定初始大小和默认负载因子 都采用默认值 容量默认16 为了减少hash碰撞次数,折中,均匀泊松分布 。负载因子默认0.75 ,因为0.5 元素达到一半就扩容 扩容太浪费资源 ,查询效率会增加,但是空间利用率低 。1.0时空间利用率高了,但是耗费时间 。

11.HashMap的put(k,v)实现原理

(1)首先将k,v封装到Node对象当中(节点)。
(2)然后它的底层会调用K的hashCode()方法得出hash值。
(3)通过哈希表函数/哈希算法,将hash值转换成数组的下标,下标位置上如果没有任何元素,就把Node添加到这个位置上。如果说下标对应的位置上有链表。此时,就会拿着k和链表上每个节点的k进行equal。如果所有的equals方法返回都是false,那么这个新的节点将被添加到链表的末尾。如其中有一个equals返回了true,那么这个节点的value将会被覆盖。

12.HashMap的get(k,v)实现原理

(1)先调用k的hashCode()方法得出哈希值,并通过哈希算法转换成数组的下标。
(2)通过上一步哈希算法转换成数组的下标之后,在通过数组下标快速定位到某个位置上。如果这个位置上什么都没有,则返回null。如果这个位置上有单向链表,那么它就会拿着K和单向链表上的每一个节点的K进行equals,如果所有equals方法都返回false,则get方法返回null。如果其中一个节点的K和参数K进行equals返回true,那么此时该节点的value就是我们要找的value了,get方法最终返回这个要找的value。

13.Volatile

jvm提供的轻量级同步机制
三个特性:保证可见性 不保证原子性 禁止指令重排

14.线程几种状态,什么时候会阻塞

在Java当中,线程通常都有五种状态,创建、就绪、运行、阻塞和死亡。
第一是创建状态。在生成线程对象,并没有调用该对象的start方法,这是线程处于创建状态;
第二是就绪状态。当调用了线程对象的start方法之后,该线程就进入了就绪状态,但是此时线程调度程序还没有把该线程设置为当前线程,此时处于就绪状态。在线程运行之后,等待或者睡眠中回来之后,也会处于就绪状态
第三是运行状态。线程调度程序将处于就绪状态的线程设置为当前线程,此时线程就进入了运行状态,开始运行run函数当中的代码。
第四是阻塞状态。线程正在运行的时候,被暂停,通常是为了等待某个时间的发生(比如说某项资源就绪)之后再继续运行。sleep,suspend等方法都可以导致线程阻塞。
第五是死亡状态。如果一个线程的run方法执行结束,该线程就会死亡。对于已经死亡的线程,无法再使用start方法令其进入就绪状态。

15.为什么阿里巴巴Java手册不建议使用Executors创建线程池?

FixedThreadPool和SingleThreadExecutor => 允许的请求队列长度为Integer.MAX_VALUE,可能会堆积大量的请求,从而引起OOM异常
CachedThreadPool => 允许创建的线程数为Integer.MAX_VALUE,可能会创建大量的线程,从而引起OOM异常,这就是为什么禁止使用Executors去创建线程池,而是推荐自己去创建ThreadPoolExecutor的原因。

16.类加载过程

JVM类加载机制定义:
虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验、转换解析和初始化,最终形成可被虚拟机直接使用的Java类型的过程

类从被加载到虚拟机内存中开始、到卸载出内存为止,整个生命周期包括七个阶段:

  • 加载
  • 验证
  • 准备
  • 解析
  • 初始化
  • 使用
  • 卸载
17.Java中final、finally、finalize的区别与用法

final:java中的关键字,修饰符。
A).如果一个类被声明为final,就意味着它不能再派生出新的子类,不能作为父类被继承。因此,一个类不能同时被声明为abstract抽象类的和final的类。
B).如果将变量或者方法声明为final,可以保证它们在使用中不被改变.
  1)被声明为final的变量必须在声明时给定初值,而在以后的引用中只能读取,不可修改。
  2)被声明final的方法只能使用,不能重载。
  
finally:java的一种异常处理机制。
  finally是对Java异常处理模型的最佳补充。finally结构使代码总会执行,而不管无异常发生。使用finally可以维护对象的内部状态,并可以清理非内存资源。特别是在关闭数据库连接这方面,如果程序员把数据库连接的close()方法放到finally中,就会大大降低程序出错的几率。
  
finalize:Java中的一个方法名。
Java技术使用finalize()方法在垃圾收集器将对象从内存中清除出去前,做必要的清理工作。这个方法是由垃圾收集器在确定这个对象没被引用时对这个对象调用的。它是在Object类中定义的,因此所的类都继承了它。子类覆盖finalize()方法以整理系统资源或者执行其他清理工作。
finalize()方法是在垃圾收集器删除对象之前对这个对象调用的。

18.java中String、StringBuffer和StringBuilder的区别

StringBuffer是线程安全,可以不需要额外的同步用于多线程中;

StringBuilder是非同步,运行于多线程中就需要使用着单独同步处理,但是速度就比StringBuffer快多了;

StringBuffer与StringBuilder两者共同之处:可以通过append、indert进行字符串的操作。

String实现了三个接口:Serializable、Comparable、CarSequence

StringBuilder只实现了两个接口Serializable、CharSequence,相比之下String的实例可以通过compareTo方法进行比较,其他两个不可以。

19.线程安不安全指什么

线程安全就是说多线程访问同一代码,不会产生不确定的结果。编写线程安全的代码是低依靠线程同步。

20.Session 与 Token 的区别

session生成方式?
浏览器第一次访问服务器,服务器会创建一个session,然后同时为该session生成一个唯一的会话的key,也就是sessionid,然后,将sessionid及对应的session分别作为key和value保存到缓存中,也可以持久化到数据库中,然后服务器再把sessionid,以cookie的形式发送给客户端。这样浏览器下次再访问时,会直接带着cookie中的sessionid。然后服务器根据sessionid找到对应的session进行匹配;
还有一种是浏览器禁用了cookie或不支持cookie,这种可以通过URL重写的方式发到服务器;

简单来讲,用户访问的时候说他自己是张三,他骗你怎么办? 那就在服务器端保存张三的信息,给他一个id,让他下次用id访问。
token的生成方式?
答:浏览器第一次访问服务器,根据传过来的唯一标识userId,服务端会通过一些算法,如常用的HMAC-SHA256算法,然后加一个密钥,生成一个token,然后通过BASE64编码一下之后将这个token发送给客户端;客户端将token保存起来,下次请求时,带着token,服务器收到请求后,然后会用相同的算法和密钥去验证token,如果通过,执行业务操作,不通过,返回不通过信息;

21.java中四种修饰符的限制范围

1.public 公共的 可以被所有其他类访问
2.private 私有的 只可以被自己访问和修改
3.protected 保护的 可以被自己,子类,同一包下的类可以访问
4.default 默认 同一包中的类可以访问

22.Object 类中的方法

(1)getclass 返回运行时类
我们写一段代码 不运行 会生成.java文件,这就是编译时类。运行时类是java文件经过编译变成.class文件,这些文件不能直接运行,交给JVM来解析运行。
(2)hashCode方法

该方法用于哈希查找,重写了equals方法一般都要重写hashCode方法。这个方法在一些具有哈希功能的Collection中用到。

一般必须满足obj1.equals(obj2) = =true。可以推出obj1.hash- Code()= =obj2.hashCode(),但是hashCode相等不一定就满足equals。不过为了提高效率,应该尽量使上面两个条件接近等价。
(3)equals 比较地址是否相同 相当于==
重写equals方法
(4)clone 返回当前对象的副本
克隆分为深克隆和浅克隆
对于一个类只有基本类型,那深克隆和浅克隆是一样的。如果有引用类型,则不同。

  • 深克隆 :新开辟内存空间,值拷贝
  • 浅克隆:拷贝的是引用

(5)toString
返回对象的字符串表示形式
线程安全就是说多线程访问同一代码,不会产生不确定的结果。编写线程安全的代码是低依靠线程同步。
(6)finalize方法
该方法用于释放资源。因为无法确定该方法什么时候被调用,很少使用。

(7)wait方法

wait方法就是使当前线程等待该对象的锁,当前线程必须是该对象的拥有者,也就是具有该对象的锁。wait()方法一直等待,直到获得锁或者被中断。wait(long timeout)设定一个超时间隔,如果在规定时间内没有获得锁就返回。

调用该方法后当前线程进入睡眠状态,直到以下事件发生。

  • 其他线程调用了该对象的notify方法。
  • 其他线程调用了该对象的notifyAll方法。
  • 其他线程调用了interrupt中断该线程。
  • 时间间隔到了。

此时该线程就可以被调度了,如果是被中断的话就抛出一个InterruptedException异常。

(8)notify方法
该方法唤醒在该对象上等待的某个线程。

(9)notifyAll方法
该方法唤醒在该对象上等待的所有线程。

23.线程如何通信(面试常问)

方式一:使用 volatile 关键字
基于 volatile 关键字来实现线程间相互通信是使用共享内存的思想,大致意思就是多个线程同时监听一个变量,当这个变量发生变化的时候 ,线程能够感知并执行相应的业务。这也是最简单的一种实现方式
方式二:使用Object类的wait() 和 notify() 方法
众所周知,Object类提供了线程间通信的方法:wait()、notify()、notifyaAl(),它们是多线程通信的基础,而这种实现方式的思想自然是线程间通信。
方式三:使用JUC工具类 CountDownLatch
jdk1.5之后在java.util.concurrent包下提供了很多并发编程相关的工具类,简化了我们的并发编程代码的书写,***CountDownLatch***基于AQS框架,相当于也是维护了一个线程间共享变量state
方式四:使用 ReentrantLock 结合 Condition
方式五:基于LockSupport实现线程间的阻塞和唤醒

24.do while 和while的区别

while和do…while语句都是循环语句,功能都差不多,唯一的区别在于检验条件的时间上。while语句在进入循环体之前要先判断条件是否成立,如果成立的话则进入循环体。
而do…while语句则相反,是先执行循环体,然后再判断条件是否成立,如果成立的话则继续循环体,如果不成立则跳出循环,也就是说对于do…while语句,不管条件是否成立都要先执行一遍。

25.Continue和Break区别

break:while循环break是用于永久终止循环。即不执行本次循环中break后面的语句,直接跳出循环。

continue:while循环continue是用于终止本次循环。即本次循环中continue后面的代码不执行,进行下一次循环的入口判断。

26. 面向对象的特征

面向对象的编程语言有封装、继承 、抽象、多态等4个主要的特征。

封装: 把描述一个对象的属性和行为的代码封装在一个模块中,也就是一个类中,属性用变量定义,行为用方法进行定义,方法可以直接访问同一个对象中的属性。
抽象: 把现实生活中的对象抽象为类。分为过程抽象和数据抽象 数据抽象 -->鸟有翅膀,羽毛等(类的属性) 过程抽象 鸟会飞,会叫(类的方法)
继承:子类继承父类的特征和行为。子类可以有父类的方法,属性(非private)。子类也可以对父类进行扩展,也可以重写父类的方法。缺点就是提高代码之间的耦合性。
多态:多态是指程序中定义的引用变量所指向的具体类型和通过该引用变量发出的方法调用在编程时并不确定,而是在程序运行期间才确定(比如:向上转型,只有运行才能确定其对象属性)。方法覆盖和重载体现了多态性。

27.Java创建对象有几种方式?

java中提供了以下四种创建对象的方式:

  1. new创建新对象
  2. 通过反射机制
  3. 采用clone机制
  4. 通过序列化机制
28. Java 中 IO 流分为几种?

按功能来分:输入流(input)、输出流(output)。

按类型来分:字节流和字符流。

字节流和字符流的区别是:字节流按 8 位传输以字节为单位输入输出数据,字符流按 16 位传输以字符为单位输入输出数据。

29.BIO、NIO、AIO 有什么区别?

BIO:Block IO 同步阻塞式 IO,就是我们平常使用的传统 IO,它的特点是模式简单使用方便,并发处理能力低。
NIO:Non IO 同步非阻塞 IO,是传统 IO 的升级,客户端和服务器端通过 Channel(通道)通讯,实现了多路复用。
AIO:Asynchronous IO 是 NIO 的升级,也叫 NIO2,实现了异步非堵塞 IO ,异步 IO 的操作基于事件和回调机制。

计算机网络

1.TCP三次握手,四次挥手

具体答案参考之前博客一篇博客理解tcp/ip协议三次握手、四次挥手_sound-cobranet-tcp/ip-CSDN博客

2.TCP和UDP区别以及长、短连接

具体答案参考之前博客UDP与TCP区别以及长、短连接_udp短连接-CSDN博客

3.OSI七层模型和TCP/IP四层协议

在这里插入图片描述

4.HTTP常见状态码

答案看我之前博客HTTP状态码_webserver internal redirect-CSDN博客

5.进程三种状态

进程:进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位。
进程状态:
一般来说,进程有三个状态,即就绪状态,运行状态,阻塞状态
在这里插入图片描述

6.进程和线程,进程可以没有线程吗

程序至少有一个进程,进程至少有一个线程
线程是进程中执行运算的最小单位,是进程中的一个实体,是被系统独立调度和分派的基本单位,线程自己不拥有系统资源,只拥有一点在运行中必不可少的资源,但它可与同属一个进程的其它线程共享进程所拥有的全部资源。一个线程可以创建和撤消另一个线程,同一进程中的多个线程之间可以并发执行。

7.从输入URL到页面展示的详细过程

1、输入网址
2、DNS解析
3、建立tcp连接
4、客户端发送HTTP请求
5、服务器处理请求 
6、服务器响应请求
7、浏览器展示HTML
8、浏览器发送请求获取其他在HTML中的资源。

JVM

g1 和 cms 区别

吞吐量优先和响应优先的垃圾收集器选择。
Cms是以获取最短回收停顿时间为目标的收集器。基于标记-清除算法实现。比较占用cpu资源,切易造成碎片。
G1是面向服务端的垃圾收集器,是jdk9默认的收集器,基于标记-整理算法实现。可利用多核、多cpu,保留分代,实现可预测停顿,可控。

JVM内存模型以及GC算法

参考之前博客:一篇博客了解JVM_新生代 三部分-CSDN博客

数据库(MySql、Redis)

1.数据库三种删除方式及其区别

1. 使用delete 语句

特点:

  • delete 属于数据库操纵语言DML,表示删除表中的数据,删除过程是每次从表中删除一行,并把该行删除操作作为事务记录在日志中保存

  • 可以配合事件(transaction)和 回滚(rollback)找回数据,且自增不会被重置

  • delete 既可以对table也可以对view

  • 可以全部删除,也可以按条件删除

2. 使用truncate 语句

特点:

  • truncate 属于数据库定义语言DDL,表示删除表中所有数据,DDL操作是隐性提交的!不能rollback
  • truncate一次性的从表中删除所有数据,不会保存到日志中,相当于直接删除整个表,再重新创建一个一模一样的表
  • 使用truncate 删除的数据不能恢复
  • truncate 只能对table,执行速度快

3.使用drop语句

特点:

  • drop 属于数据库定义语言DDL,表示删除表, 也可以用来删除数据库
2.事务的隔离级别

多个事务之间隔离的,相互独立的。但是如果多个事务操作同一批数据,则会引发一些问题,设置不同的隔离级别就可以解决这些问题*存在问题:
1.脏读:一个事务,读取到另一个事务中没有提交的数据

2.不可重复读(虚读):在同一个事务中,两次读取到的数据不一样。
3,幻读:一个事务操作(DNL)数据表中所有记录,另一个事务添加了一条数据,则第一个事务查询不到自己的修改。

隔离级别:

  1. read uncommitted :读未提交
    *产生的问题:脏读、不可重复读、幻读2. read committed :读已提交(oracle)*产生的问题:不可重复读、幻读
  2. repeatable read :可重复读(MysQL默认)*产生的问题:幻读
  3. serializable :串行化
    *可以解决所有的问题
    *注意:隔离级别从小到大安全性越来越高,但是效率越来越低

教据库查询隔离级别:
select @@tx_isolation;
数据库设置隔离级别:
set global transaction isolation level级别字符串;

3.MYSQL的两种存储引擎区别(事务、锁级别等等),各自的适用场景
引擎特性
MYISAM不支持外键,表锁,插入数据时,锁定整个表,查表总行数时,不需要全表扫描
INNODB支持外键,行锁,查表总行数时,全表扫描
4.索引的好处以及适合使用的场景

索引最大的好处是提高查询速度,
缺点是更新数据时效率低,因为要同时更新索引
对数据进行频繁查询进建立索引,如果要频繁更改数据不建议使用索引。

5.最左匹配原则

最左匹配原则是针对索引的
举例来说:两个字段(name,age)建立联合索引,如果where age=12这样的话,是没有利用到索引的,
这里我们可以简单的理解为先是对name字段的值排序,然后对age的数据排序,如果直接查age的话,这时就没有利用到索引了,
查询条件where name=‘xxx’ and age=xx 这时的话,就利用到索引了,再来思考下where age=xx and name=’xxx‘ 这个sql会利用索引吗,
按照正常的原则来讲是不会利用到的,但是优化器会进行优化,把位置交换下。这个sql也能利用到索引了

6.死锁怎么解决

找到进程号,kill掉即可!

7.limit分页

limit 【索引】【一页多少条数据】

<span style="color:#000000"><span style="background-color:#f3f4f5"><code class="language-java">例如:
#第二页 每页<span style="color:#c76b29">3</span>条数据
limit <span style="color:#c76b29">3</span> <span style="color:#c76b29">3</span>
</code></span></span>
  • 1
  • 2
  • 3
8. 分组查询,聚合函数

group by+字段 实现按字段分组查询
聚合函数有 count,min,max,average 等等

9. where和having区别

where:

  • where是一个约束声明,使用where来约束来自数据库的数据;
  • where是在结果返回之前起作用的;
  • where中不能使用聚合函数。

having:

  • having是一个过滤声明;
  • 在查询返回结果集以后,对查询结果进行的过滤操作;
  • 在having中可以使用聚合函数。
10.有哪些数据库优化方式(重点)

推荐一篇文章,写的很好!
有哪些常见的数据库优化方法? - 知乎

11.索引

索引(Index)是帮助 MySQL 高效获取数据的数据结构。 常见的查询算法,顺序查找,二分查找,二叉排序树查找,哈希散列法,分块查找,平衡多路搜索树 B 树(B-tree ),索引是对数据库表中一个或多个列的值进行排序的结构,建立索引有助于快速获取信息。

mysql 有4种不同的索引:

  • 主键索引(PRIMARY)
  • 唯一索引(UNIQUE)
  • 普通索引(INDEX)
  • 全文索引(FULLTEXT)
    索引并非是越多越好,创建索引也需要耗费资源,一是增加了数据库的存储空间,二是在插入和删除时要花费较多的时间维护索引

索引加快数据库的检索速度索引降低了插入、删除、修改等维护任务的速度唯一索引可以确保每一行数据的唯一性通过使用索引,可以在查询的过程中使用优化隐藏器,提高系统的性能索引需要占物理和数据空间

12.数据库的三范式是什么(重要)

第一范式:列不可再分
第二范式:行可以唯一区分,主键约束
第三范式:表的非主属性不能依赖与其他表的非主属性 外键约束且三大范式是一级一级依赖的,第二范式建立在第一范式上,第三范式建立第一第二范式上 。

13.SQL优化

1、查询语句中不要使用select *
2、尽量减少子查询,使用关联查询(left join,right join,inner join)替代
3、减少使用IN或者NOT IN ,使用exists,not exists或者关联查询语句替代
4、or 的查询尽量用 union或者union all 代替(在确认没有重复数据或者不用剔除重复数据时,union all会更好)
5、应尽量避免在 where 子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫描。
6、应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描,如: select id from t where num is null 可以在num上设置默认值0,确保表中num列没有null值,然后这样查询: select id from t where num=0

14.什么是内联接、左外联接、右外联接?

内联接(Inner Join):匹配2张表中相关联的记录。
左外联接(Left Outer Join):除了匹配2张表中相关联的记录外,还会匹配左表中剩余的记录,右表中未匹配到的字段用NULL表示。
右外联接(Right Outer Join):除了匹配2张表中相关联的记录外,还会匹配右表中剩余的记录,左表中未匹配到的字段用NULL表示。在判定左表和右表时,要根据表名出现在Outer Join的左右位置关系

数据结构

数组和链表区别,单链表和双链表

数组静态分配内存,链表动态分配内存;数组在内存中连续,链表不连续;数组利用下标定位,时间复杂度为O(1),链表定位元素时间复杂度O(n);数组插入或删除元素的时间复杂度O(n),链表的时间复杂度O(1)。
数组优点:
随机访问性强(通过下标进行快速定位)
查找速度快
数组缺点:
插入和删除效率低(插入和删除需要移动数据)
可能浪费内存(因为是连续的,所以每次申请数组之前必须规定数组的大小,如果大小不合理,则可能会浪费内存)
内存空间要求高,必须有足够的连续内存空间。
数组大小固定,不能动态拓展

链表的优点:
插入删除速度快(因为有next指针指向其下一个节点,通过改变指针的指向可以方便的增加删除元素)
内存利用率高,不会浪费内存(可以使用内存中细小的不连续空间(大于node节点的大小),并且在需要空间的时候才创建空间)
大小没有固定,拓展很灵活。
链表的缺点:
不能随机查找,必须从第一个开始遍历,查找效率低

单链表:
在这里插入图片描述
双链表:
在这里插入图片描述

为什么市场上单链表的使用多于双链表呢?

从存储结构来看,每个双链表的节点要比单链表的节点多一个指针,而长度为n就需要
n*length(这个指针的length在32位系统中是4字节,在64位系统中是8个字节)
的空间,这在一些追求时间效率不高应用下并不适应,因为它占用空间大于单链表所占用的空间;这时设计者就会采用以时间换空间的做法,这时一种工程总体上的衡量。

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

需要全套资料及答案的在【翻到文章底部,点击名片】即可免费获取 备注:“CSDN”

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值