Java面试题-2022
- java基础
- 1. JVM、JRE和JDK的关系
- 2.为什么JAVA可以跨平台
- 3.什么是java程序的主类
- 4.Java有哪些数据类型
- 5.装箱和拆箱
- 6.java 基本类型与引用类型的区别
- 7.java常见的修饰符有哪些
- 8.Final、 finally的区别
- 9.this和super
- 10.break ,continue ,return 的区别及作用
- 11.什么是面向对象,面向对象和面向过程的区别
- 12. 面向对象三大特性
- 13.面向对象五大基本原则是什么
- 14.抽象类和接口的区别
- 15.内部类是什么?内部类的分类有哪些
- 16.==和 equals 的区别是什么
- 17.Java中 IO 流分为几种
- 18.什么是反射机制
- 19.反射机制优缺点
- 20.TCP/IP协议和三次握手四次挥手
- 21.为什么TCP连接的时候是3次?2次不可以吗?
- 22.为什么TCP连接的时候是3次,关闭的时候却是4次
- 23.为什么在第四次挥手的时候,客户端需要等待2MSL(4分钟)才会发送确认信息给服务器
- 24.String 是基本的数据类型吗
- 25.String为什么是不可变的
- 26.String真的是不可变的吗?
- 27.如何将字符串反转?
- 28.数组有没有 length()方法?String 有没有 length()方法
- 29.在使用 HashMap 的时候,用 String 做 key 有什么好处?
- 30.栈、堆、方法区存储的内容
- 31.什么是集合
- 32.List、Set、Map三者的区别?
- 33.有什么常用的集合实现类
- 34.ArrayList的优缺点
- 35.LinkedList的优缺点
- HashMap
- Spring
- MyBatis
- MySql
java基础
1. JVM、JRE和JDK的关系
JVM:Java虚拟机
JRE:包括Java虚拟机和Java程序所需的核心类库,如果想要运行一个开发好的Java程序,计算机中只需要安装JRE即可。
JDK:Java的开发工具,也包括了JRE
JDK>JRE>JVM
2.为什么JAVA可以跨平台
Java程序是通过java虚拟机在系统平台上运行的,只要该系统可以安装相应的java虚拟机,该系统就可以运行java程序
3.什么是java程序的主类
主类是指包含main()方法的类
4.Java有哪些数据类型
基本数据类型
- 数值型
- 整数类型(byte,short,int,long)
- 浮点类型(float,double)
- 字符型(char)
- 布尔型(boolean)
引用数据类型
- 类(class)
- 接口(interface)
- 数组([])
5.装箱和拆箱
装箱将基本类型用它们对应的引用类型包装起来
拆箱将包装类型转换为基本数据类型
类型 | 内容 |
---|---|
原始类型 | boolean,char,byte,short,int,long,float,double |
封装类型 | Boolean,Character,Byte,Short,Integer,Long,Float,Double |
6.java 基本类型与引用类型的区别
基本类型保存原始值,引用类型保存的是生成一个指针指向此对象
7.java常见的修饰符有哪些
访问控制修饰符
public : 公有
private :私有
非访问控制修饰符
static:静态
void:无返回值
final:
被final修饰的类不可以被继承
被final修饰的方法不可以被重写
被final修饰的变量不可以被改变
8.Final、 finally的区别
final:
被final修饰的类不可以被继承
被final修饰的方法不可以被重写
被final修饰的变量不可以被改变
finally:一般作用在try-catch代码块中,不管是否出现异常,该代码块都会执行
9.this和super
this:对象本身
super:表示父类对象
10.break ,continue ,return 的区别及作用
break:结束当前的循环体
continue:跳过本次循环
return:无返回值时结束方法,有返回值时结束方法并返回对象
11.什么是面向对象,面向对象和面向过程的区别
面向对象的底层其实还是面向过程,把面向过程抽象成类,然后封装,方便我们使用的就是面向对象
12. 面向对象三大特性
封装、继承、多态
封装:将具有共同属性或行为的类抽取出来就是封装
继承:子类继承父类的方法,目的是让方法可以复用,父类不可以调用子类定义的方法
多态:声明父类的对象指向子类对象,多态的主要表现就是重载和重写
13.面向对象五大基本原则是什么
单一闭合原则:类的功能要单一,不能包罗万象
开发关闭原则:对增加功能是开放的,对修改是关闭的
里式交替原则:子类可以替父类出现在如何地方
依赖倒置原则:程序要依赖于接口,不要依赖于具体实现
接口分离原则:设计时采用多个有关的接口比采用一个通用的接口要好
14.抽象类和接口的区别
接口:只能存在常量和抽象方法,接口之间可以被继承,一个类可以继承多个接口
抽象类:可以存在抽象方法也能存在非抽象方法,但是抽象类一定要被继承
15.内部类是什么?内部类的分类有哪些
内部类是在一个类的内部又声明了一个类
成员内部类、局部内部类、匿名内部类和静态内部类
16.==和 equals 的区别是什么
==:
基础数据类型是判断两边的值是否现同
引用数据类型是判断两边的内存地址是否相同
equals:判断两个对象是否相等
17.Java中 IO 流分为几种
- 按照流的流向来分,可以划分为输入流和输出流
- 按照操作单元划分,可以划分为字节流和字符流
- 按照流的角色划分,可以划分节点流和处理流
18.什么是反射机制
反射是java提供的一个重要的功能,可以在运行检查类、接口、方法和变量等信息,无需指定类的方法和方法名,还可以在运行时实例化新对象、调用方法以及设置和获取变量
19.反射机制优缺点
- 优点: 动态加载类,提高代码灵活度。
- 缺点:反射相当于一系列解释操作,通知 JVM 要做的事情,性能比直接的java代码要慢很多。
20.TCP/IP协议和三次握手四次挥手
三次握手:
- 概念:指在发送数据的准备阶段,服务器和客户端之间需要三次交互
- 第一次握手:建立连接时,客户端向服务器发送一个包,并进入发送状态,客户端等待服务器的确认信息
- 第二次握手:当服务器收到客户端的请求后,此时要给客户端给一个确认信息,同时发送建立联机的包,此时服务器进入 同步记录的状态
- 第三次握手:客户端收到服务器发的 确认连接+建立联机的包后,向服务器发送确认信息,发送完毕之后,客户端和服务器进成功连接(TCP连接成功)状态,完成三次握手
- 故事理解:A(客户端)要去朋友B(服务器)的家玩,到了B家门口,喊了几声都没人来开门,A就打了一个电话给B(第一次握手,客户端正在等待),B接到电话(服务器收到客户端的请求),B就询问A的身份,你真的是A吗?A的姓名是xxx,长得xxx样,回答得上来,那么B就给A开门(给客户端发一个确认信息,同时建立连接),A听到后就回答了那些问题,并且再次确实自己就是A(客户端收到服务器发的 确认连接+建立联机),B就去开门了(服务器发送确认信息,完成三次握手)
四次挥手:
- 概念:所谓四次挥手就是说关闭TCP连接的过程,当断开一个TCP连接时,需要客户端和服务器共发送四个包确认
- 第一次挥手:客户端发送一个结束信息,用来关闭客户端到服务器的数据传输,客户端进入结束等待状态
- 第二次挥手:服务器收到结束信息后,发送一个确认信息给客户端,确认序号为收到序号+1(与建立联机相同,一个结束信息占用一个序号),服务器进入等待状态
- 第三次挥手:服务器发送一个结束信息,用来关闭服务器到客户端的数据传输,服务器进入最后一次确认状态
- 第四次挥手:客户端收到结束信息后,客户端进入等待状态,接着发送一个确认信息给服务器,确认序号为收到序号+1,服务器进入关闭状态,完成四次挥手
- 故事理解:A跟B说,A想回家了(客户端发送一个结束信息给服务器,客户端进入等待状态),B反问,A你真的想回家了?(服务器收到结束信息后,发送一个确认信息给客户端),B表示,如果A真的想回家那B送A到门口吧(服务器发送一个结束信息,服务器进入最后一次确认状态),A想了4分钟后,认真的说,是的真的想回家了(客户端收到结束信息后,客户端进入等待状态,接着发送一个确认信息给服务器),B表示好吧,便让A离开并把门关上了(服务器进入关闭状态,完成四次挥手)
21.为什么TCP连接的时候是3次?2次不可以吗?
如果只是握手2次,会出现丢包的问题,如果是三次握手,即便发生丢包也不会有问题
详细解释:如果第三次握手客户端发的确认信息丢失,服务端在一段时间内没有收到确认信息的话就会重新进行第二次握手,客户端收到重发信息后会再次给服务端发送确认信息。
22.为什么TCP连接的时候是3次,关闭的时候却是4次
在关闭连接的时候,当服务器收到结束信息的时候,服务器很可能并不会立刻关闭,所以只能先回个确认信息来应答,只有等服务器把所有报文都发完了才能发送结束信息,因此不能一起发送,所有需要四步。
23.为什么在第四次挥手的时候,客户端需要等待2MSL(4分钟)才会发送确认信息给服务器
要考虑丢包的问题,如果第四次挥手的信息丢失,服务端没收到确认的信息,那抹服务器就会重发第三次挥手,这样一去一回最长时间就是2MSL,所以需要等这么长时间来确认服务端确实已经收到了。
24.String 是基本的数据类型吗
不是,String是引用数据类型
25.String为什么是不可变的
String 是只读字符串,对它进行任何操作,其实都是创建一个新的对象,再把引用指向该对象
简单来说就是String类利用了final修饰的char类型数组存储字符
26.String真的是不可变的吗?
是的
27.如何将字符串反转?
使用 StringBuilder 或者 stringBuffer 的 reverse() 方法。、
28.数组有没有 length()方法?String 有没有 length()方法
数组又length属性,String又length()方法
29.在使用 HashMap 的时候,用 String 做 key 有什么好处?
HashMap 内部实现是通过 key 的 hashcode 来确定 value 的存储位置,因为字符串是不可变的,所以当创建字符串时,它的 hashcode 被缓存下来,不需要再次计算,所以相比于其他对象更快。
30.栈、堆、方法区存储的内容
堆区:
- 存储的全部是对象,每个对象都包含一个与之对应的class的信息。(class的目的是得到操作指令)
- jvm只有一个堆区(heap)被所有线程共享,堆中不存放基本类型和对象引用,只存放对象本身 。
栈区:
- 每个线程包含一个栈区,栈中只保存基础数据类型的值和对象以及基础数据的引用
- 每个栈中的数据(基础数据类型和对象引用)都是私有的,其他栈不能访问。
- 栈分为3个部分:基本类型变量区、执行环境上下文、操作指令区(存放操作指令)。
方法区:
- 又叫静态区,跟堆一样,被所有的线程共享。方法区包含所有的class和static变量。
- 方法区中包含的都是在整个程序中永远唯一的元素,如class,static变量。
31.什么是集合
用于存储数据的容器
32.List、Set、Map三者的区别?
List有序且可以重复
Set无序且不可重复
Map使用key、value的形式存储数据,key无序,value不要求有序,value允许重复
33.有什么常用的集合实现类
LIst:ArrayList、LinkedList(两个都是线程不安全)
Map:HashMap(线程不安全)、HashTable(线程安全)
34.ArrayList的优缺点
查询的时候快,增加和删除数据时慢
35.LinkedList的优缺点
因为是使用双向链表的数据结构,增加和删除快,查询慢
HashMap
这里就不讲arraylist了,面试问得少,知道hashmap的实现原理就已经可以给面试官留下个好印象了,不过有时间还是要去看看arraylist的源码学习一下的
36.HashMap的数据结构
数组 + 链表 + 红黑树
37.HashMap在jdk1.7和jdk1.8中有什么区别
HashMap在1.7中是使用数组 + 链表
在1.8后才使用数组 + 链表 + 红黑树
38.HashMap中Put方法的具体流程
调用Put方法时,实际调用的是PutVal方法,此方法第一个参数是要Key的hashcode值,所以调用了一个hash方法,此hash方法中对key进行了一次hash运算取得了hashcode,之后复制了一份hashcode并且进行了右移16位,两个hashcode进行按位与运算后获得一份全新的hashcode并成为参数传到PutVal方法中
PutVal方法中一开始就来判断table(数组)是否创建,如果没有创建就按照默认值(16)为大小进行创建,创建后获取table的长度
通过table长度 - 1 之后的值与 全新的hashcode进行异或运算可以得到一个数组下标,将数据存到这个数组下标的位置便完成了一次put操作
39.HashMap的扩容
当数组中的数量已经大于等于 数组大小 X 0.75 后(16x0.75=12),便会调用resize方法进行扩容
每次扩容都是原本大小的2倍,扩展后node对象的位置要不就是和旧数组的位置一样,要不就是
等于 旧数组的大小 + 旧数组的下标 = 新数组的下标位置
40.HashMap的table的容量如何确定?
官方定的默认值为16,因为 2的次方数 - 1 这个数的二进制都是为左0右1的格式
15的二进制:0000 1111
因为 这种左边0右边1的结构,按位与 上任何数,都小于它本身
而且 这个下标也不是随便定的,要有一定的规范,因为数组的大小为16,那通过计算得到的下表最大不能超过15,而且这个数要0~15分配平均,不能老是出现同一个数
41.什么是哈希冲突?HashMap是如何解决哈希冲突的?
当两个不同的输入值,根据同一散列函数计算出相同的散列值的现象,我们就把它叫做碰撞(哈希碰撞/冲突)
HashMap是如何解决哈希冲突?这里要回到Put方法的具体流程中,讲了调用hash方法进行对key进行hash运算
将复制一份的hashcode进行右移了16位,这里就是HashMap是如何解决哈希冲突重要知识点
为什么要右移16位?当数组的长度很短时,只有低位数的hashcode值能参与运算。而让高16位参与运算可以更好的均匀散列,减少碰撞,进一步降低hash冲突的几率。并且使得高16位和低16位的信息都被保留了
42.如果key进行hashcode运算后指向了一个位置,但是位置上已经有数据了,请问会发生什么?
一开始会进行key的判断,判断新的key与旧的key是否相同,如果相同,则会将新value赋值到旧value中,并返回旧value
43.链表?红黑树?
当新节点进来的key与旧节点的key不一致时,则会以链表的形式存到旧节点的后面,此时旧节点的next值指向新节点
当链表的节点大于等于8时,会调用转换红黑树的方法,转换红黑树的方法内也不是一开始就直接转成红黑树,要先判断这个数组的长度是否到达最大值(64),如果没有到达最大值,会先进行扩容,到达最大值后才会真真正正的进行链表向红黑树的转换
44.为什么HashMap中的String、Integer这样的包装类适合作为Key
String、Integer等包装类的特性能够保证Hash值的不可更改性和计算准确性,能够有效的减少Hash碰撞的几率
Spring
45.什么是Spring
Spring是一个轻量级Java开发框架
46.Spring优缺点
优点
- 方便解耦,简化开发
- AOP编程的支持
- 声明式事务的支持
- 方便程序的测试
- 方便集成各种优秀框架
缺点
- Spring依赖反射,反射影响性能
Spring控制反转(IOC)
47.什么是IOC?
IOC:控制反转
将创建对象的权力从人为创建交给spring容器创建并且管理
控制反转不是什么技术,而是一种设计思想。它的目的是指导我们设计出更加松耦合的程序。
48.简单说一下IOC的实现原理
IOC的目的是降低耦合度,解耦合的原则是编译期不依赖,而运行期依赖
- 将要创建的类以bean的形式存到xml文件中
- 解析这个xml文件,以bean标签获取要被创建的对象并存入一个list中
- 遍历这个list,创建对应的对象
- 创建一个map,k为对象的name,v为对象的实例,将创建好的对象存入map中
- 提供一个get方法让其他类能调用这个map
49.BeanFactory 和 ApplicationContext有什么区别?
BeanFactory和ApplicationContext是Spring的两大核心接口,都可以当做Spring的容器。
其中ApplicationContext是BeanFactory的子接口。
BeanFactroy采用的是延迟加载形式来注入Bean的,即只有在使用到某个Bean时(调用getBean()),才对该Bean进行加载实例化。
ApplicationContext,它是在容器启动时,一次性创建了所有的Bean。
50.Bean实例化的三种方式
无参构造方法实例化
工厂静态方法实例化
工厂普通方法实例化
51.Bean的生命周期
1.解析xml配置文件或者注解配置的类得到BeanDefinition
2.通过解析BeanDefinition反射获得Bean对象
3.对Bean对象进行属性填充
4.回调实现Aware接口方法
5.调用BeanPostcessor的初始化前方法
6.调用init初始化方法
7.调用BeanPostProcessor的初始化方法后会进行AOP
8.将创建的Bean对象放入到一个Map中
9.使用Bean
10.Spring容器关闭时调用DisposableBean的destory方法对Bean进行关闭
52.请说说你常用的IOC注解
@Component:实例化普通Bean
@Controller:实例化web层上的Bean
@Service:实例化Service层上的Bean
@respository:实例化Dao层上的Bean
@Autowired:在字段上根据类型进行依赖注入
Spring的面向切面编程(AOP)
53.什么是面向切面编程
AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高
程序的可重用性,同时提高了开发的效率
AOP的优势:
在程序运行期间,在不修改源码的情况下对方法进行功能增强
逻辑清晰,开发核心业务的时候,不必关注增强业务的代码
减少重复代码,提高开发效率,便于后期维护
54.AOP底层实现
AOP 的底层是通过 Spring 提供的的动态代理技术实现的。
采用了JDK代理和CGLIB代理,当代理对象有父类时用JDK代理,无则用CGLIB代理
AOP的使用(复习点)
- 创建目标接口、目标实现类(Service层)
- 创建通知类(MyAdvice)
- 在xml中使用aop标签进行配置
<!--先使用IOC创建目标类对象以及通知类-->
<!--目标类交给IOC容器-->
<bean id="accountService" class="com.ganmaoyu.service.impl.AccountServiceImpl"> </bean>
<!--通知类交给IOC容器-->
<bean id="通知类id" class="com.ganmaoyu.advice.MyAdvice"></bean>
<aop:config>
<!--引入通知类-->
<aop:pointcut ref="通知类id" expression="execution(* com.ganmaoyu.service..*.* (..))">
<!--配置目标类的目标方法执行时,使用通知类的before方法进行前置增强-->
<aop:before :前置通知
method="before"
pointcut="execution(public void com.ganmaoyu.service.impl.目标实现类.目标方法())">
</aop:before>
</aop:aspect>
</aop:config>
55.请说说你AOP注解/xml标签
<aop:before>:前置通知
<aop:afterReturning>:后置通知
<aop:afterThrowing>:异常通知
<aop:after>:最终通知
<aop:around>:环绕通知
@Before:前置通知
@AfterReturning:后置通知
@AfterThrowing:异常通知
@After:最终通知
@Around:环绕通知
当前四个通知组合在一起时,执行顺序如下:
@Before -> @After -> @AfterReturning(如果有异常:@AfterThrowing)
56.Spring支持的事务管理类型有哪些
编程式事务管理:麻烦,难维护
声明式事务管理:方便,只需用注解和XML配置来管理事务,推荐使用
MyBatis
57.MyBatis是什么?
MyBatis是一个优秀的基于ORM的半自动轻量级持久层框架
58.Mybatis优缺点?
优点:SQL写在XML里,解除sql与程序代码的耦合,便于统一管理;提供XML标签,支持编写动态SQL语句,并可重用
缺点:SQL语句依赖于数据库,导致数据库移植性差,不能随意更换数据库
59.ORM是什么?
ORM:对象关系映射
O:对象模型
R:关系型数据库的数据结构
M:映射
人话:
O:User类
R:User表
M:建立User类与User表的映射关系 -->mybatis映射文件:.xml
60.MyBatis编程步骤是什么样的?
- 创建SqlSessionFactory
- 通过SqlSessionFactory创建SqlSession
- 通过sqlsession执行数据库操作
- 调用session.commit()提交事务
- 调用session.close()关闭会话
61. #{}和${}有什么区别
#{}是占位符
${}是拼接符,字符串替换
62.模糊查询like要怎么用
使用CONCAT
select * from user where username like CONCAT('%',#{username},'%')
63.如何在插入一条数据后立刻返回此数据的id?
<insert id="saveUser" parameterType="user">
INSERT INTO user(name,pwd,)
VALUES(#{name},#{pwd}
<selectKey resultType="int" order="AFTER" keyProperty="id">
SELECT LAST_INSERT_ID();
</selectKey>
</insert>
64.动态SQL
<set> --> insert里面的那个set
<where> --> where
<foreach> --> 循环
<tirm> --> 于去除sql语句中多余的and关键字,逗号,
--> 或者给sql语句前拼接 “where“、“set“以及“values(“ 等前缀,或者添加“)“等后缀
<if> --> 判断
MySql
为什么要使用数据库
使用SQL语句,查询方便效率高,管理数据方便
什么是数据库事务?
事务是逻辑上的一组操作,要么都执行,要么都不执行。
ACID是什么
A:Atomicity 原子性
C:Consistency 一致性
I:Isolation 隔离性
D:durability 持久性
什么是脏读?幻读?不可重复读?
脏读:某个事务已更新一份数据,另一个事务在此时查询了同一份数据,由于某些原因,后一个事务所读取的数据就会是不正确
不可重复读:一个事务的两次查询之中数据不一致,这可能是两次查询过程中间插入了一个事务更新了原有的数据
幻读:在一个事务的两次查询中数据笔数不一致