Java面试题基础部分整理

1.java的平台版本及功能

JavaME:小型版,为开发电子消费产品和嵌入式设备提供解决方案
JavaSE:标准版,为开发普通桌面和商务应用程序解决方案
JavaEE:企业版,为开发企业环境下应用程序提供解决方案

2.jdk、jre、jvm的关系?

jdk包含jre和开发工具
jre包含jvm和核心类库
jdk开发完成的java交由jre去运行,jvm保证了程序的跨平台性

3.jdk环境配置内容与功能?

classpath:jdk1.5以后默认配置,无需配置,配置源代码编译后生成位置
JAVA_HOME:用来配置jdk的安装路径,提供第三方软件支持
path:使bin下的工具可以在任意路径下使用

4. 什么是注释?注释的分类有哪些?

注解是对代码解释和说明的文字,可以提高代码的阅读性
注释会在代码的编译期间自动忽略,不会编写在.class文件中
单行注释:/ /
多行注释:/** /
文档注释/** */

5.java中关键字、保留字分别是什么?

关键字是java中被赋予特殊含义的字符(51)
保留字是以后可能成为关键字的字 const goto(2)

6.java中基本数据类型有哪些,byte取值范围?

byte(1) short(2) int(4) long(8)
boolean(1) char(2) float(4) double(8)
byte的取值范围 :
一个字节 8位(其中一个符号位) -128~127

7.标识符命名规则与规范

标识符:用于给类,包,变量,常量等命名
规范:以美元符号,下划线,字母与数字组成 但不能以数字开头

8.byte b1=3,b2=4,b3;b3=b1+b2;b3=3+4;哪行代码会出错?怎么解决

第二行 出错 在Java中,当进行算术运算时,byte、short 和 char 类型的值都会被提升为 int 类型
因此 b1+b2 的结果是一个int类型 因此不能直接赋值给byte的b3
需要将结果强转成byte类型之后 再赋值给b3

9.如何快速计算3*8

先进行2的位运算
3*2<<3

10.短路运算符与非短路运算符的区别

非短路运算符,符号两端全部判断才能得到结论
而短路运算符
与运算,符号前若为假,就可以直接得到结论
或运算,符号前若为真,也可以直接得到结论

11.&与&&的区别

&为逻辑与,符号前后都需要进行判断
&&为短路与,若符号前为假,值可以直接得出为假结论
&还可以理解为按位的与运算

12.for循环与while循环的区别

for循环通常用于循环次数已知的情况,需要规定循环的开始条件和结束条件以及步幅
while循环次数知不知道都可以使用,需要规定循环的结束条件和步幅

13.java中数组的特点

java数组用于存储同一类型的数据,且数组的规定后不能再改变。
数组中通过下标索引确定元素位置
java数组初始化分为静态初始化和动态初始化。
静态初始化,直接给出元素。
动态初始化,给出数组的大小。

14. 方法重载与方法重写的区别

方法重载:在同一个类中,方法名相同,参数列表不同(个数、类型、顺序)称之为发生了方法的重载,或多个方法互为重载

方法重写:在继承过程中,子类继承父类非私有方法,父类方法运行不能满足子类需求,子类重写父类方法(修饰符大于或等于父类、返回值,方法名,参数列表必须与父类相同、方法体按照需求修改)
位置区别:方法重载发生在同一个类中,方法重写发生在存在继承关系的父类与子类中
可修改区别:方法重载可以任意修改修饰符 返回值类型 参数列表 方法体,方法重写一般只修改方法体
校验区别:方法重载是在书写完毕后,编译时进行校验,方法重写通过书写Override注解进行限制

15.面向对象的思想是什么?特点是什么?

这里的对象泛指现实中一切事物,每种事物都具备自己的属性和行为。 强调的是通过调用对象的行为来实现功能,而不是自己一步一步的去 操作实现。

16.面向对象的三大特征

封装:java中现在的封装大多指的是使用访问权限修饰符 对类 属性 方法 进行封装(更多是对属性) 使其只对可见类的访问,提高安全性。更多的是属性的封装,将属性隐藏起来,若需要访问某个属性,提供公共方法对其访问。
继承:就是子类继承父类的属性和行为,使得子类对象具有与父类相同的属性、相同的行为。子类可以直接访问父类中的非私有的属性和行为 ,子类自动拥有父类非私有的成员,子类也可以拥有自己的成员。Java只支持单继承,不支持多继承,但支持多层继承。继承提高了代码的复用性。继承使类与类之间产生关系也是多态的前提。
多态:同一个对象,在不同时刻表现出来的形态是不同的。提高程序的扩展性。定义方法时候,使用父类型作为参数,在使用的时候,使用具体的子类型参与操作

17.类与对象的关系

类是对一类事物的描述,是抽象的 类是大量对象共性的抽象
对象是一类事物的实例,是具体的 对象是类在客观世界中的具体表现
类是对象的模板,对象是类的实体 类是创建对象的模板

18.构造方法可以不可以被继承?

构造方法的名字是与类名一致的。所以子类是无法继承父类构造方法的。
但是子类的构造方法默认调用父类的构造方法,用来存储父类的属性调用父类的方法

19.this与super的区别

super:代表父类的存储空间标识(可以理解为父亲的引用)。
this:代表当前对象的引用(谁调用就代表谁)。
子类的每个构造方法中均有默认的super(),调用父类的空参构造。手动调用父类构造会覆盖默认的super()。
super()和this()都必须是在构造方法的第一行,所以不能同时出现。

20.抽象类与接口的区别

成员区别:
抽象类:变量,常量;有构造方法;有抽象方法,也有非抽象方法。
接口:静态常量;抽象方法。
关系区别:
类与类:继承,单继承
类与接口:实现,可以单实现,也可以多实现
接口与接口:继承,单继承,多继承
设计理念区别:
抽象类:为了继承而来,让子类强制重写中的抽象方法
接口:对行为抽象,主要是行为,主要用于功能的扩展

21.内部类的概念与分类

概念:
将一个类A定义在另一个类B里面,里面的那个类A就称为内部类,B则称为外部类。
分类:成员内部类,局部内部类,匿名内部类
成员内部类:
-内部类可以直接访问外部类的成员,包括私有成员。
-外部类要访问内部类的成员,必须要建立内部类的对象。
局部内部类:
将一个类定义在一个方法中,该类就称之为是局部内部类
局部内部类只能在该方法内部使用

22.final、finally、finalize()的区别

final是修饰符,表示常量,被final修饰的变量一但赋值不能修改,被final修饰的方法不能被重写,被final修饰的类不能被继承
finally用于异常处理,搭配trycatch使用,表示不管是否抛出异常,finally包裹的代码一定会执行用于释放资源
finalize()是Object方法,当一个对象没有任何引用指向他时,虚拟机会自动调用这个方法,目的是为了在对象被垃圾回收之前可以释放资源

23.java中为什么重写equals方法也要重写hashCode方法

在java中 a = =b 比较的是对象的在内存中的物理地址,equals()方法的作用本来和==相同,也是比较两者的物理地址,但String类重写了equals()方法,于是String类的equals方法变成了比较两个字符串对象的字符串内容是否相等。
hashCode()方法的作用是确定对象在散列存储结构例如HashMap、HashSet中的存储地址。
如果重写了equals()方法,没有重写hashCode()方法的话,如果a.equals(b),但a的hashCode与b的hashCode不相等,则当我们将a、b同时加入散列存储结构map、set时,就可能出现数据结构中存在两个值相等的对象的情况,从而导致混淆。所以,重写equals()方法同时尽量也要重写hashcode()方法。

24.String、StringBuilder、StringBuffer的区别

String是不可变的,底层使用的是数组保存的是字符串常量,使用加号拼接时都会创建一个新的字符串,StringBuffer,Stringbuilder有缓冲区,底层是字符串,每次进行拼接时不会创建新的对象会修改本身,如果考虑到线程是否安全就用stringBUff而,如果不考虑就是用StringBuilder,如果不频繁修改字符串,就用String

25.异常的分类与处理

异常分为编译时异常和运行时异常。
编译时异常在编译时期就会检查,如果没有处理就会编译失败,
运行时异常在运行时期检查异常处理方法有在控制台输出异常程序停止执行,使用throws抛出异常表示当前方法不处理异常提醒该方法的调用者去处理异常和try-catch处理异常

26.List集合与Set集合的区别

List是有序的,意味着元素按照插入的顺序排序,可以通过索引访问元素,
set是无序的,存储元素的顺序与取出元素顺序可能不一致,
list允许元素重复,set不允许元素重复,
遍历方式不同list支持for循环也可以通过迭代器遍历,set只能通过迭代器

27.ArrayList与LinkedList的区别

ArrayList底层是一个可扩容的Object数组,LinkedList底层是双向链表,每个节点包含元素本身及指向前后节点的引用,Array增删慢(不包括末尾元素)查询快,因为在增删操作时,都需要移动后续元素以保持连续性,在进行查询操作时,因为底层是数组具有索引可以直接访问到元素,LinkedList增删快,查询慢(不包括首尾,有getfirst和getlast方法),在进行增删操作时只需要改变相应节点的引用关系即可

28.哈希表的存储结构

哈希表也称为散列表,使用哈希函数将键映射到数组的特定索引上,这个函数将键转换为数组的下标,决定数据在数组中的存储位置。哈希表通常由数组和链表组成,数组的每个元素都存储着链表的头结点,链表用于存储具有相同哈希值的记录,这种现象称为哈希冲突或哈希碰撞。解决哈希冲突的主要策略,开放地址法通过探测数组中的下一个可用位置来处理冲突,而拉链法则是在数组中为每个哈希值维护一个链表,将所有具有相同哈希值的记录链接在一起,在jdk1.8中哈希表存储采用数组+链表+红黑树实现,当链表长度超过阈值8时,将列表转化为红黑树,这样大大减少查找时间,当长度减少到6时会还原成链表,使得数据的查找和存储更加高效。

29.HashSet存储数据的流程

当向hashset添加对象时,首先调用该对象的hashcode方法返回哈希码,然后使用对象的哈希码通过某种特定的哈希函数将其映射到hashset底层数据结构通常是hashmap的哈希桶数组的一个索引位置上,到达数据指定索引位置后如果该位置为空就是空桶,那就直接存入,如果如果该位置已经有元素,就是非空桶,需要对链表进行遍历,再通过equals方法对新元素和每个元素比较,如果有相等那么会根据不可重复的规则,新对象不会被添加,否则将新对象作为链表的新节点插入到适当位置,如果该位置的链表长度达到一定阈值默认8,为了提高查询效率链表就会转换为红黑树,同样也需要equals方法确定元素的唯一性,如果在添加过程中发现哈希桶已经接近饱和,也就是0.75,hashset会扩容,并重新计算索引的元素的哈希码以确定其在新数据中的位置,然后转移到新数组,重哈希

30.HashMap和HashTable的区别

1、继承的父类不同
HashTable继承Dictionary类,而hashMap继承了AbstractMap类,但是二者都实现了map接口。

2、线程安全性不同
Hashtable 线程安全,因为它每个方法中都加入了Synchronize。HashMap是线程不安全的。
1
​ HashMap底层是一个Entry数组,当发生hash冲突的时候,hashmap是采用链表的方式来解决的,在对应的数组位置存放链表的头结点。对链表而言,新加入的节点会从头结点加入。在hashmap做put操作的时候可能会造成数据丢失。现在假如A线程和B线程同时对同一个数组位置调用addEntry,两个线程会同时得到现在的头结点,然后A写入新的头结点之后,B也写入新的头结点,那B的写入操作就会覆盖A的写入操作造成A的写入操作丢失

3、是否提供contains方法
​ HashMap把Hashtable的contains方法去掉了,改成containsValue和containsKey,因为contains方法容易让人引起误解。

​ Hashtable则保留了contains,containsValue和containsKey三个方法,其中contains和containsValue功能相同。

4、key和value是否允许null值
​ Hashtable中,key和value都不允许出现null值。但是如果在Hashtable中有类似put(null,null)的操作,编译同样可以通过,因为key和value都是Object类型,但运行时会抛出NullPointerException异常,这是JDK的规范规定的。

​ HashMap中,null可以作为键,这样的键只有一个;可以有一个或多个键所对应的值为null。当get()方法返回null值时,可能是 HashMap中没有该键,也可能使该键所对应的值为null。因此,在HashMap中不能由get()方法来判断HashMap中是否存在某个键, 而应该用containsKey()方法来判断。

5、两个遍历方式的内部实现上不同
​ Hashtable、HashMap都使用了 Iterator。而由于历史原因,Hashtable还使用了Enumeration的方式 。

6、hash值不同
​ 哈希值的使用不同,HashTable直接使用对象的hashCode。而HashMap重新计算hash值。

​ hashCode是jdk根据对象的地址或者字符串或者数字算出来的int类型的数值。

​ Hashtable计算hash值,直接用key的hashCode(),而HashMap重新计算了key的hash值,Hashtable在求hash值对应的位置索引时,用取模运算,而HashMap在求位置索引时,则用与运算,且这里一般先用hash&0x7FFFFFFF后,再对length取模,&0x7FFFFFFF的目的是为了将负的hash值转化为正值,因为hash值有可能为负数,而&0x7FFFFFFF后,只有符号外改变,而后面的位都不变。

7、内部实现使用的数组初始化和扩容方式不同
​ HashTable在不指定容量的情况下的默认容量为11,而HashMap为16,Hashtable不要求底层数组的容量一定要为2的整数次幂,而HashMap则要求一定为2的整数次幂。

​ Hashtable和HashMap它们两个内部实现方式的数组的初始大小和扩容的方式。

​ HashTable中hash数组默认大小是11,增加的方式是 old*2+1。

​ HashMap中hash数组默认大小是16,增加的方式是 old*2。

31.throw和throws的区别

区别1:

throws:
跟在方法声明后面,后面跟的是异常类名

throw:
用在方法体内,后面跟的是异常类对象名
区别2:
throws:
可以跟多个异常类名,用逗号隔开

throw:
只能抛出一个异常对象名
区别3:
throws:
表示抛出异常,由该方法的调用者来处理

throw:
表示抛出异常,由该方法体内的语句来处理
区别4:
throws:
throws表示有出现异常的可能性,并不一定出现这些异常

throw:
throw则是抛出了异常,执行throw一定出现了某种异常

32.什么是包装类?什么是自动拆装箱?

包装类就是将基本类型转化为对象,这样可以利用面向对象的特性调用方法等,自动拆装箱就是在基本数据类型和其对应的包装类之间自动进行转换,简化了代码就,减少了潜在的错误

33.==与equals的区别

== 是一个运算符,用于比较两个值是否相等。它可以用于比较基本类型的值和引用类型的值。当用于基本数据类型时,比较的是值是否相同;当用于引用数据类型时,比较的是引用所指向的对象的地址是否相同。

equals 是一个方法,用于比较当前对象是否与另一个对象相等。这个方法在Object类中定义,所有Java对象都继承了这个方法。默认实现中,equals()方法通过比较对象的引用(即内存地址)来判断两个对象是否相等。但是,子类通常会重写equals()方法以提供更复杂的比较逻辑,例如比较对象的实际内容是否相同。

在运行速度方面,**** 的运行速度通常比equals()快,因为****只是简单地比较引用,而equals()可能需要执行更复杂的比较逻辑。

特别地,对于String和部分引用数据类型,equals()的比较行为被重写以比较对象的内容而不是引用地址的相等性。这是因为这些类(如String)希望提供基于内容而不是引用的等价性判断。

需要注意的是,如果自定义的类没有重写equals()方法,那么该类的equals()方法将继承自Object类,其默认行为是使用==运算符来比较引用地址的相等性。因此,在自定义类中重写equals()方法时,通常会同时重写hashCode()方法以确保满足Java的hashCode()和equals()方法的通用约定。

34.并发与并行的区别?

并发:指两个或多个事件在同一个时间段内发生。(单核)
并行:指两个或多个事件在同一时刻发生(同时发生,多核)

35.进程与线程的区别?

进程:是指一个内存中运行的应用程序,每个进程都有一个独立的内存空间,一个应用程序可以同时运行多个进程;进程也是程序的一次执行过程,是系统运行程序的基本单位;系统运行一个程序即是一个进程从创建,运行到消亡的过程。
线程:线程是进程中的一个执行单元,负责当前进程中程序的执行,一个进程中至少有一个线程。线程是操作系统进行调度的基本单位,一个进程中是可以有多个线程的,这个应用程序也可以称之为多线程程序。

36.多线程创建方式有哪些?

创建线程方式有四种:
继承Thread类,重写run方法
实现Runnable接口,实现run方法
实现Callable接口,通过包装器FutrueTask创建线程(有返回值)
线程池创建

37.继承Thread类创建线程与实现Runnable接口创建线程的区别?

Runnable接口适合多个相同的程序代码的线程去共享同一个资源。
可以避免Java中的单继承的局限问题
增加程序的健壮性,实现解耦操作,代码可以被多个线程共享,代码和线程独立
线程池只能放入实现Runnable或Callable类线程,不能直接放入继承Thread的类

38.为什么重写的是run方法调用的是start方法

1:start()方法是Java线程约定的内置方法,能够确保代码在新的线程上下文中运行。
2:start()方法包含了触创建新线程的特殊代码逻辑。run()方法是我们自己写的代码,很显然没有这个能力。
3:如果直接调用run()方法,那么它只是一个普通的方法调用,程序中依然只有一个主线程,并且只能顺序执行,需要等待run()方法执行结束后才能继续执行后面的代码。
4:我们创建线程的目的是为了更充分地利用CPU资源,如果直接调用run()方法,就失去了创建线程的意义了。

39.线程同步的方式有哪些?他们的区别是啥?

synchronized
Lock锁
原子变量
ThreadLocal
对比:ReentrantLock是显示锁,手动开启和关闭锁,别忘记关闭锁;
Synchronized 是隐式锁,出了作用域自动释放
ReentrantLock 只有代码块锁,synchronized有代码块锁和方法锁;
使用ReentrantLock锁,JVM将花费较少的时间来调度线程,线程更好,并且有更好的扩展性(提供更多子类);
优先使用顺序:ReentrantLock>synchronized同步代码块>synchronized同步方法

40.多线程的生命周期与对应的转换方法?

新建:创建线程对象
就绪:有执行的资格,没有执行权
运行:有执行的资格,有执行权
阻塞:由于一些操作让线程处于该状态。没有资格,没有执行权而另一些操作却可以把它激活,激活后处于就绪状态
死亡:线程对象变成垃圾,等回收

41.什么是死锁?产生死锁的原因是什么?怎么解决?

死锁是指多个进程因争夺资源而造成的一种僵局,如果没有外力作用,所有进程都不会向前推进。

42.wait与sleep的区别

1,这两个方法来自不同的类分别是Object和Thread
2,最主要是sleep方法没有释放锁,而wait方法释放了锁,使得其他线程可以使用同步控制块或者方法。
3,wait,notify和notifyAll只能在同步控制方法或者同步控制块里面使用,而sleep可以在
任何地方使用
synchronized(x){
x.notify()
//或者wait()
}
4,sleep必须捕获异常,而wait,notify和notifyAll不需要捕获异常

43.线程池的七个参数,四个拒绝策略

44.volatile的作用与原理

45.什么是设计模式?常用的设计模式有哪些?分类有哪些?

设计模式是一种处理常用简单需求的一个思想或者固定代码。设计模式分为创建型模式,结构型模式,行为型模式,总共有23种。
创建型模式,共五种:抽象工厂模式,工厂方法模式,建造者模式,原型模式,单列模式。
结构型模式,共七种:外观模式,装饰器模式,代理模式,适配器模式,桥接模式,组合模式,享元模式。
行为型模式,共十一种:观察者模式,中介者模式,访问者模式,策略模式,命令模式,状态模式,模板方法模式,责任链模式,迭代器模式,备忘录模式,解释器模式。

46.UDP与TCP的区别

连接性:
TCP:面向连接的协议。在开始数据传输之前,它需要先建立一个连接(三次握手),并在数据传输完成后关闭这个连接(四次挥手)。
UDP:无连接的协议。它不需要在发送数据之前建立连接,每个数据报都是一个独立的信息单元。
可靠性:
TCP:提供可靠的数据传输服务。它使用序列号、确认和重传机制来确保数据包的顺序性和完整性。
UDP:不保证数据的可靠传输。它不会跟踪数据包是否到达或是否按顺序到达,也不提供重传机制。因此,UDP被认为是不可靠的协议,但它比TCP更快,因为它减少了网络上的开销。
头部开销:
TCP:头部开销较大,通常至少为20字节(不包括选项)。
UDP:头部开销较小,只有8字节(不包括选项)。
传输方式:
TCP:基于流的传输。TCP将数据视为一个无结构的字节流,不关心发送方和接收方写入和读取的数据块的大小和边界。
UDP:基于数据报的传输。UDP将应用程序交下来的报文分成多个长度不超过64K(包括64K)的数据报,并在数据报的首部加上完整的地址信息,然后将数据报发往目的地。
拥塞控制:
TCP:具有拥塞控制机制,通过滑动窗口和慢启动等算法来避免网络拥塞。
UDP:没有拥塞控制机制,因此它可能会在网络拥塞时导致数据包丢失。
应用场景:
TCP:适用于需要可靠数据传输的场景,如文件传输、电子邮件、远程登录等。
UDP:适用于对实时性要求较高、但不需要可靠数据传输的场景,如视频流、语音通话、DNS查询等。
错误检测:
TCP和UDP都使用校验和来检测数据传输过程中的错误,但处理方式不同。TCP在检测到错误时会要求重传,而UDP只是简单地丢弃错误的数据报。
传输效率:
UDP的传输效率通常高于TCP,因为它不需要建立和关闭连接,也没有复杂的可靠性机制。这使得UDP在处理大量小数据包时具有优势。
流量控制:
TCP具有流量控制机制,可以根据接收方的缓冲区大小来调整发送方的发送速率。
UDP没有流量控制机制,它只是简单地发送数据报,不关心接收方是否能够及时处理这些数据。

47.什么是双亲委派机制?好处是?

  • 当前ClassLoader首先从自己已经加载的类中查询是否此类已经加载,如果已经加载则直接返回原来已经加载的类。每个类加载器都有自己的加载缓存,当一个类被加载了以后就会放入缓存,等下次加载的时候就可以直接返回了。
  • 当前classLoader的缓存中没有找到被加载的类的时候,委托父类加载器去加载,父类加载器采用同样的策略,首先查看自己的缓存,然后委托父类的父类去加载, 一直到bootstrp ClassLoader.
  • 当所有的父类加载器都没有加载的时候,再由当前的类加载器加载,并将其放入它自己的缓存中,以便下次有加载请求的时候直接返回。
    好处:
    1.避免重复加载。当父亲已经加载了该类的时候,就没有必要子ClassLoader再加载一次。

2.为了安全。避免核心类,比如String被替换。

48.什么是反射?简单说下泛型擦除

反射是指在运行时去获取一个类的变量和方法信息。然后通过获取到的信息来创建对象,调用方法的一种机制。由于这种动态性,可以极大的增强程序的灵活性,程序不用在编译期就完成确定,在运行期仍然可以扩展。
泛型擦除:添加不同与原本泛型类型的类型。

49.SQL语句的分类

50.删除表中所有数据的方式有哪些?他们的区别是什么?

51.数据库引擎InnoDB与MyISAMD的区别

52.char和varchar的区别

1.char最大长度为255字节,varchar最大长度是65535字节
2.char是定长,不足的部分用隐藏空格填充,varchar是不定长的
3.char会浪费空间,varchar会更加节省空间
4.char查找效率会很高,varchar查找效率相对较低

53.count(*)与count(id)的关系

54.where和having的区别?

55.sql语句执行顺序

1.from
2.join
3.on
4.where
5.group by
6.聚合函数
7.having
8.select
9.distinct
10.order by
11.limit

56.什么是视图?视图的优缺点?

57.什么是索引?优缺点?什么时候使用?

58.索引失效的场景有哪些?

59.事务的四大特征ACID是什么

原子性:
原子性是指事务包含的所有操作要么全部成功,要么全部失败回滚。因此事务的操作如果成功就必须完全应用到数据库,如果操作失败不能对数据库有任何影响。
 例子:考虑银行转账操作,从一个账户扣除一定金额并存入另一个账户。如果扣除成功但存入失败,需要回滚,保持操作的原子性。
一致性:
一致性要求事务执行前后数据库的状态保持一致。事务执行过程中可能涉及多个操作,这些操作的结果必须满足数据库的约束和规则。
  例子:在购物网站上进行支付操作,支付前后库存、账户余额等信息必须保持一致,否则支付过程可能导致数据不一致。
  例如:那转账来说,假设用户A和用户B两者的钱加起来是5000,那么不管A和B之间如何转账,转几次账,事务结束后两个用户的钱加起来应该还得是5000,这就是事务的一致性。
隔离性:
隔离性是指当多个用户并发访问数据库时,比如操作同一张表时,数据库为每个用户开启的事务,不能被其他事务的操作干扰,多个并发事务要互相隔离。

即要达到一种效果:对于任意两个并发的事务T1和T2,在事务T1看来,T2要么在T1开始之前就已经结束,要么在T1结束之后开始,这样每个事务都感觉不到有其他的事务在并发执行。

关于事务的隔离性又提供了多种隔离级别,如读已提交、读未提交、可重复读、串行化,稍后会讲到。
持久性:
 持久性是指一个事务一旦被提交了,那么对数据库中的数据的改变是永久的,即便是在数据库系统中遇到故障的情况下也不会丢失提交事务的操作。

例如我们在使用JSDC操作数据库时,在提交事务后,提示用户事务操作完成,当我们程序执行完成直到看到提示后,就可以认定事务已经正确提交,即使数据库出现了问题,也必须要将我们的事务完全执行完成,否则会造成我们看到提示事务处理完毕,但是数据库因为故障而没有执行事务的重大错误。
  例子:用户在博客平台上发表文章,一旦用户点击发布并事务提交,该文章的修改应该是永久性的,即使系统在发布过程中发生了故障。

60.事务的隔离级别有哪些?会产生什么问题?

1.Read uncommitted (读未提交):最低级别,任何情况都无法保证。
2. Read committed (读已提交):可避免脏读的发生。
第二个隔离级别怕提交,因为提交会导致不可重复读。
3. Repeatable read (可重复读):可避免脏读、不可重复读的发生。*MySQL默认隔离级别
4. Serializable (串行化):可避免脏读、不可重复读、幻读的发生。

61.sql优化

1.避免使用select*:只选择真正需要的列,减少数据传输和内存使用,避免不必要的回表操作。
2.使用union all代替union:union会去除重复行,这可能导致额外的排序和比较操作。
3.小表驱动大表:使用小表的数据集来驱动大表的数据集,减少数据量大的表对性能的影响。
4.批量操作:将多次插入和更新操作合并为批量操作,减少与数据库的交互次数。
5.使用limit进行高效分页:通过指定返回结果行数来限制分页查询的数据量。
6.慎用in操作符:当in中的值过多时,可能会导致索引失效,从而进行全表扫描。对于连续的数值,可以使用between代替in.
7.用in来代替or:低效查询:SELECT * FROM t WHERE id = 10 OR id = 20 OR id = 30;高效查询:SELECT * FROM t WHERE id IN (10,20,30);另外,MySQL对于IN做了相应的优化,即将IN中的常量全部存储在一个数组里面,而且这个数组是排好序的。但是如果数值较多,产生的消耗也是比较大的。再例如:select id from table_name where num in(1,2,3) 对于连续的数值,能用 between 就不要用 in 了;再或者使用连接来替换。
8.优化join语句:减少join的表数量,注意join的类型(如inner join,left join等),并确保使用的索引能够优化join操作。
9.控制索引的数量:避免过度索引,因为这会影响插入,更新和删除操作的性能。
10.选择合理的字段类型:使用适当大小的数据类型,减少存储空间的占用。
11.提升group by的效率:通过优化索引和查询逻辑来提高分组操作的效率。
12.尽量避免使用子查询:select * from t1 where id=(select id from t2 where name=”mike”);
其子查询在Mysql5.6版本里面,内部执行计划是这样:先查外表再匹配内表,而不是先查内t2,当外表的数据很大时,查询速度会非常慢。在MariaDB10/Mysql5.6版本里,采用join关联方式对其进行了优化,这条SQL语句会自动转换为:SELECT t1.* FROM t1 JOIN t2 on t1.id = t2.id
但请注意的是:优化只针对SELECT有效,对UPDATE/DELETE子查询无效,固生产环境应避免使用子查询
13.最佳左前缀法则:如果索引了多列,要遵守最左前缀法则,指的是查询从索引的最左前列开始并且不跳过索引中的列。Mysql查询优化器会对查询的字段进行改进,判断查询的字段以那种形式组合能使查询更快,比如创建的是(a,b)索引,查询的(b,a),查询优化器会修改成(a,b)后使用索引查询。

62.数据库三大范式

第一范式,数据库表的每一列都是不可分割的原子项,第二范式基于第一范式,要求每个表都必须有主键,且非主键列必须完全依赖主键,第三范式基于第二范式要求每个非主属性不能依赖于其他非主属性就是非主键列之间不能传递依赖关系

63.简单介绍Http协议,请求与响应的格式是什么样的?

超文本传输协议HTTP是万维网的数据通信的基础。http是一个简单的请求-响应协议,它通常运行在TCP之上,是应用层基于请求与响应的无状态传输协议。
HTTP请求的格式主要由请求行、请求头和请求体三部分组成。其中,请求行包含了请求方法(如GET、POST等)、资源路径和协议版本;请求头存放了数据格式和相对应的功能,以键值对的形式表示;请求体则主要是POST请求的请求参数。
HTTP响应的格式则由状态行、响应头和响应体三部分组成。状态行包含了响应的HTTP版本、状态码和状态描述;响应头也包含了响应的各种信息,以键值对的形式表示;响应体则是实际返回的数据内容。

64.什么是Servlet?Servelt生命周期?

Servlet全称“Java Servlet”,中文意思为小服务程序或服务连接器,是运行在Web服务器或应用服务器上的程序,。Servlet具有独立于平台和协议的特性,主要功能在于交互式地浏览和生成数据,生成动态Web内容。 本质就是一个Servlet接口,通过实现该接口创建Servlet服务在web中执行
生命周期:
1.构造 servlet,然后使用 init 方法将其初始化。
第一次发送请求的时候。 执行一次(servlet可以看做是单例模式)
2.处理来自客户端的对 service 方法的所有调用。
客户端发送一次请求,调用service方法一次。执行多次

3.从服务中取出 servlet,然后使用 destroy 方法销毁它,最后进行垃圾回收并终止它。
tomcat服务器关闭的时候,销毁

65.get请求与post请求区别

get请求发送数据在url地址栏传输,post请求在请求体中传输
get请求相比post不安全
get请求可以被书签保存,但是post不可以(因为书签保存的是url可以保存请求的数据)
get请求根据不同浏览器设置请求数据上限不定(一般为2k),post请求可以看做无大小限制
get请求发送1次,post请求发送2次(请求会将数据同url一同发送,post则是请求地址响应后再次发送)
post请求服务器主动接受,会在服务器响应后才将数据发生给服务器
get请求在浏览器页面后退时无影响,post可能导致表单的重复提交
get请求浏览器会主动缓存相应的数据,post不会主动缓存
get请求页面编码与后台编码相同不会乱码,post可能会乱码
第六条也可以理解为,get请求服务器被动接收(你服务器接不接受数据我数据都随着请求地址发送过去了)

66.转发与重定向的区别

转发的地址栏不会发生改变,但是重定向会发生改变
转发是一次请求和一次响应,但是重定向是多次请求与响应
转发的状态码是2xx,重定向是3xx
转发可以使用request域对象传递数据,但是重定向不可以(必须将请求与响应对象传递)
转发本质请求转发指定服务执行后由当前服务进行返回,重定向当前服务结束客户端继续请求其他服务
转发发生在服务器内部,转发的资源不需要携带项目名,重定向可以重定到任何公开资源(需要带项目名)。
转发可以请求web-inf下的内部资源

67.cookie与session的区别

1、存储位置不同

cookie的数据信息存放在客户端浏览器上。

session的数据信息存放在服务器上
2、存储容量不同

单个cookie保存的数据<=4KB,一个站点最多保存20个Cookie。

对于session来说并没有上限,但出于对服务器端的性能考虑,session内不要存放过多的东西,并且设置session删除机制。
3、存储方式不同

cookie中只能保管ASCII字符串,并需要通过编码方式存储为Unicode字符或者二进制数据。

session中能够存储任何类型的数据,包括且不限于string,integer,list,map等。
4、隐私策略不同

cookie对客户端是可见的,别有用心的人可以分析存放在本地的cookie并进行cookie欺骗,所以它是不安全的。

session存储在服务器上,对客户端是透明对,不存在敏感信息泄漏的风险。
开发可以通过设置cookie的属性,达到使cookie长期有效的效果。
5、有效期上不同

开发可以通过设置cookie的属性,达到使cookie长期有效的效果。

session依赖于名为JSESSIONID的cookie,而cookie JSESSIONID的过期时间默认为-1,只需关闭窗口该session就会失效,因而session不能达到长期有效的效果。

6、服务器压力不同

cookie保管在客户端,不占用服务器资源。对于并发用户十分多的网站,cookie是很好的选择。

session是保管在服务器端的,每个用户都会产生一个session。假如并发访问的用户十分多,会产生十分多的session,耗费大量的内存。
7、浏览器支持不同

假如客户端浏览器不支持cookie:

cookie是需要客户端浏览器支持的,假如客户端禁用了cookie,或者不支持cookie,则会话跟踪会失效。关于WAP上的应用,常规的cookie就派不上用场了。

运用session需要使用URL地址重写的方式。一切用到session程序的URL都要进行URL地址重写,否则session会话跟踪还会失效。

假如客户端支持cookie:

cookie既能够设为本浏览器窗口以及子窗口内有效,也能够设为一切窗口内有效。

session只能在本窗口以及子窗口内有效。
8、跨域支持上不同

cookie支持跨域名访问。

session不支持跨域名访问。

68.简单解释下session的钝化与活化,以及解决了什么问题

(一)钝化

当服务器正常关闭时,还存活着的session(在设置时间内没有销毁) 会随着服务器的关闭被以文件(“SESSIONS.ser”)的形式存储在tomcat 的work 目录下,这个过程叫做Session 的钝化。

(二)活化

当服务器再次正常开启时,服务器会找到之前的“SESSIONS.ser” 文件,从中恢复之前保存起来的Session 对象,这个过程叫做Session的活化。

69.Mybatis与Hibernate的区别

70.什么是JPA,Myabtis是否实现了JPA

71.请简单Mybatis核心配置文件中配置的内容与作用

72.Mybatis中#{}与${}的区别

#{}是预编译处理,${}是字符串替换。

Mybatis在处理#{}时,会将sql中的#{}替换为?号,调用PreparedStatement的set方法来赋值;

Mybatis在处理时,就是把 {}时,就是把时,就是把{}替换成变量的值。

使用#{}可以有效的防止SQL注入,提高系统安全性。

73.Mybatis是否支持一二级缓存?分别存储的位置

74.Mybatis如何获取自增主键

75.Mybatis是否支持动态sql?常用的标签有哪些?功能是什么?

76.Spring实例化对象的方式有哪些?

Spring实例化对象的方式主要有以下几种:

  1. 使用构造函数实例化对象
  2. 使用静态工厂方法实例化对象
  3. 使用实例工厂方法实例化对象
  4. 使用FactoryBean实例化对象

具体介绍如下:

  1. 使用构造函数实例化对象:在Spring配置文件中,通过标签的constructor-arg元素指定该bean需要的参数,Spring会通过反射机制调用bean的构造函数来实例化对象。

  2. 使用静态工厂方法实例化对象:在Spring配置文件中,通过标签的class属性指定该bean的工厂类,再通过factory-method属性指定该工厂类中的静态方法来创建bean对象。

  3. 使用实例工厂方法实例化对象:在Spring配置文件中,通过标签的class属性指定该bean的工厂类,再通过factory-method属性指定该工厂类中的实例方法来创建bean对象。需要注意的是,在实例方法中需要手动创建该bean对象。

  4. 使用FactoryBean实例化对象:FactoryBean是一个接口,通过实现该接口来自定义bean的创建过程。在Spring配置文件中,通过标签的class属性指定该bean的FactoryBean实现类,在getObject()方法中实现创建bean对象的逻辑。

77.Spring注入方式有哪些?

78.@Resource与@Autowired的区别

79.jdk动态代理与cglib动态代理的区别?spring使用的是那种动态代理?

80.AOP专业名词解释(连接点、切入点、通知、切面类、织入)

81.spring核心功能IOC与AOP分别是什么?

82.SpringMVC的执行流程

①用户发送请求至前端控制器DispatcherServlet。

②DispatcherServlet收到请求调用HandlerMapping处理器映射器。

③处理器映射器找到具体的处理器(可以根据xml配置、注解进行查找),生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet。

④DispatcherServlet调用HandlerAdapter处理器适配器。

⑤HandlerAdapter经过适配调用具体的处理器(Controller,也叫后端控制器)。

⑥Controller执行完成返回ModelAndView。

⑦HandlerAdapter将controller执行结果ModelAndView返回给DispatcherServlet。

⑧DispatcherServlet将ModelAndView传给ViewReslover视图解析器。

⑨ViewReslover解析后返回具体View。

⑩DispatcherServlet根据View进行渲染视图(即将模型数据填充至视图中)。DispatcherServlet响应用户。

83.过滤器与拦截器的区别

84. Spring中用到了那些设计模式

85.事务注解失效的原因

1、同一个类中,方法内部调用事务失效

2、事务方法被final、static修饰

3、当前类没有被Spring管理

4、非public修饰的方法(存在版本差异)

5、事务多线程调用

6、数据库本身不支持事务

7、异常被方法内部try catch捕获,没有重新抛出

8、嵌套事务回滚多了

9、rollbackFor属性设置错误

10、设置不支持事务的传播机制

86.linux常见命令

87.百万级数据的导入导出

导出:

1.使用SXSSFWorkbook,它是专门处理大数据的导出。百万数据的导出容易造成OOM,SXSSFWorkbook的原理很简单,用硬盘空间换内存,在创建对象的时候可以指定超过多少个对象后将数据写到到硬盘(默认是100个对象),以避免OOM的产生。实际上上千数据就可以使用了。

SXSSFWorkbook workbook = new SXSSFWorkbook(100);

2.还可以考虑分批导出

使用分页查询,每一页的数据就导出一次。避免一次性数据过大导致内存溢出

导入:

基于事件模式:它逐行扫描文档,一边扫描一边解析。由于应用程序只是在读取数据时检查数据,因此不需要将数据存储在内存中,这对于大型文档的解析是个巨大优势。

88.

  • 22
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: 面试题整理是为了帮助准备面试的候选人更好地了解面试的内容和要求。对于Java2021的面试题整理,可以从各个方面进行组织和分类,以便更好地帮助面试者准备。下面是我对Java2021面试题整理的一些建议。 1.基础知识:面试题可以包括Java语言的基本语法、关键字、数据类型、流程控制语句、异常处理等方面的问题。这些问题可以帮助面试者检验自己对Java语言基础知识的掌握程度。 2.面向对象:面试题可以涉及Java面向对象的概念、封装、继承、多态以及接口、抽象类等方面的问题。这些问题可以帮助面试者了解Java面向对象编程的特点和应用。 3.集合框架:面试题可以包括关于Java集合框架的知识,如ArrayList、LinkedList、HashSet、HashMap等的特性、用法和区别。这些问题可以帮助面试者检验自己对Java集合框架的理解和应用能力。 4.多线程:面试题可以涉及Java多线程编程的基本概念、线程的创建与启动、线程同步与互斥、线程池等方面的问题。这些问题可以帮助面试者了解多线程编程的原理和实践。 5.IO流:面试题可以包括关于Java IO流的知识,如输入输出流的分类、字符流和字节流的区别、文件读写操作等方面的问题。这些问题可以帮助面试者检验自己对IO流的理解和应用。 6.异常处理:面试题可以涉及Java异常处理的机制、try-catch语句的使用、自定义异常等方面的问题。这些问题可以帮助面试者了解异常处理的原理和常见应用。 7.Java虚拟机:面试题可以包括Java虚拟机(JVM)的基本概念、内存模型、垃圾回收算法等方面的问题。这些问题可以帮助面试者了解JVM的工作原理和性能优化。 8.框架和工具:面试题可以涉及Java常用的开发框架和工具,如Spring、Hibernate、MyBatis、Maven等方面的问题。这些问题可以帮助面试者了解开发框架的应用和工具的使用。 通过对这些方面的面试题整理,可以帮助面试者全面了解Java2021面试的内容和要求,并有针对性地准备和复习相关知识。面试者应该注重理论的学习,同时结合实践经验进行练习,以便在面试时能够更好地展示自己的能力和潜力。同时,面试者还应注意自己的沟通能力、问题分析能力和解决问题的能力,这些都是面试过程中重要的评估指标。 ### 回答2: Java2021面试题整理主要集中在以下几个方面: 1. 基础知识:Java中的基本数据类型、变量和常量、运算符、控制语句等内容是面试中常见的考点。面试官会通过这些问题判断候选人对Java基础知识的熟悉程度和掌握能力。 2. 面向对象编程:Java是一门面向对象的编程语言,所以面试中对面向对象的理解和应用也是重要的考点。常见的问题包括类和对象、继承和多态、封装和抽象等。 3. 异常处理:Java中的异常处理是编程中的重要内容,面试中会涉及到异常的概念、异常的分类、如何捕获和处理异常、自定义异常等。 4. 集合框架:Java集合框架是Java开发中常用的工具,常见的面试题会涉及到ArrayList、LinkedList、HashMap等集合的特点和应用场景,以及集合的遍历和使用方法。 5. 多线程:Java是一门支持多线程的语言,所以多线程的知识也是面试中的热点考点。常见的问题包括线程的生命周期、线程同步与互斥、线程间的通信、线程池等。 6. JVM相关知识:Java虚拟机(JVM)是Java运行的基础,所以对JVM的了解也是面试中的重要考点。常见问题包括JVM的结构、内存模型、垃圾回收机制等。 此外,面试中还可能涉及到数据库、网络编程、设计模式等其他相关知识。因此,面试前需要对Java的相关知识有全面的掌握,并且要能够灵活运用这些知识进行问题的解答。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值