Java基础面试题(2022版)(持续更新·····中)

文章目录


一、JVM、JRE及JDK的关系

JDK(Java development kit)是针对java开发员的产品,是整个Java的核心,包括了Java的运行环境JRE、Java工具和Java基础类库。
JRE(Java runtime environment)是运行Java程序所必须的环境的集合,包括JVM标准实现及Java核心类库。
JVM(Java Virtual machine)是Java虚拟机的缩写,是整个Java实现跨平台的最核心的部分,能够运行Java语言写作的软件程序。
直白的说,就是jdk是Java的开发工具,jre是开发程序运行所需要的环境,JVM是Java虚拟机,他们之间的关系是jdk包含jre和jvm,jre包含jvm。

二、JAVA语言特点

  • Java是一种面向对象的语言
  • Java通过Java虚拟机实现了平台无关性,一次编译,到处运行
  • 支持多线程
  • 支持网络编程
  • 具有较高的安全性和可靠性

三、JAVA和C++的区别

面试时记住前面四个就行

  • Java通过虚拟机从而实现跨平台特性,但是C++依赖于特定的平台。
  • Java没有指针,它的引用可以理解为安全指针,而C++具有和C一样的指针。
  • Java支持自动垃圾回收,而C++需要手动回收。
  • Java不支持多重继承,只能通过实现多个接口来达到相同目的,而C++支持多重继承。
  • Java不支持操作符重载,虽然可以对两个string对象通过执行加法运算,但是这是语言内置支持的操作,不属于操作符重载,而C++可以。
  • Java的goto是保留字,但是不可用,C++可以使用goto。

四、Java的基本数据类型

注意String不是Java的基本数据类型,易混淆

类型 关键字 包装器类型 占用内存(字节) (重要) 取值范围 默认值
字节型 byte Byte 1 -128(-2^7) ~ 127(2^7-1) 0
短整型 short Short 2 -2^15 ~ 2^15-1 0
整型 int Integer 4 -2^31 ~ 2^31-1 0
长整型 long Long 8 -2^63 ~ 2^63-1 0L
单精度浮点型 float Float 4 3.4e-45 ~ 1.4e38 0.0F
双精度浮点型 double Double 8 4.9e-324 ~ 1.8e308 0.0D
字符型 char Character 2 ‘\u0000’
布尔型 boolean Boolean 1 true/flase flase

五、隐式(自动)类型转换和显示(强制)类型转换

  • 隐式类型转换(自动):从存储范围小的类型到存储范围大的类型。

    byte→short(char)→int→long→float→double

  • 显示类型转换(强制):从存储范围大的类型到存储范围小的类型。

    double→float→long→int→short(char)→byte
    该类类型转换很可能存在精度的损失
    例如:

short s =1;
s = s + 1;

运行报错,原因:这里的1int型,s+1会自动转换成int型,将int型直接赋值给short型会报错。

修改(自动进行强制转换):

short s =1;
s += 1;

short s = 1; s = (short)(s + 1);

六、Java的自动装箱与拆箱

Java的自动装箱:将基本类型用包装器类型包装起来
Java的自动拆箱:将包装器类型转换成基本类型	

1、下程序的运行结果

public class Main { 
		public static void main(String[] args) { 
					Long l1 = 128L;
					Long l2 = 128L;
					System.out.print(l1 == l2); //1
					System.out.print(l1 == 128L); //2
					Long l3 = 127L;
					Long l4 = 127L;
					System.out.print(l3 == l4); //3
					System.out.print(l3 == 127L); //
	} 
}

运行结果:

false
true
true
true

分析:

对于注释1的语句,Long包装类型常量cache为-128到127之间,所以l1和l2
变量是两个对象,== 比较的是对象的地址,所以打印为false。
对于注释2的语句,由于包装类型在表达式中且表达式中至少有一个不是包
装类型,所以Longl1==128L中l1自动拆箱退化为基本类型比较,所以数值
比较为true。
对于注释3的语句,Long包装类型-128到127之间的值维护在一个常量池
中,所以l3和l4引用同一个对象,故打印true。
对于注释4的语句类似注释2语句,所以打印为true。

2、java是否存在使得语句i>j||i<=j结果为false的i、j值?(没机会见到应该。太恶心了)

Double a = Double.NaN;
Double b = Double.NaN;
System.out.println(a>b||a<=b)

分析:
java中的NaN代表 Not A Nubmer 一个不是数字的数字 (这个题想吐,巨
恶心)。

3、java1.5的自动装箱拆箱机制是编译特性还是虚拟机运行时特性?分 别是怎么实现的?

java1.5开始的自动装箱拆箱机制其实是编译时自动完成替换的,装箱阶段
自动替换为了valueOf方法,拆箱阶段自动替换为了xxxValue方法。
对于Integer、Short、Byte、Character、Long类型的valueOf方法,参数
如果是-128~127之间的值会直接返回内部缓存池中已经存在对象的引用,
参数是其他范围值则返回新建对象;
Double、Float类型与Integer类型类似,一样会调用Double、Float
valueOf方法,但是不管传入的参数值是多少都会new一个对象来表达该数
值,因为在某个范围内的整型数值的个数是有限的,而浮点数却不是。

4、java语句Integer i=1;i+=1;做了哪些事情?

首先 Integer i = 1; 做了自动装箱(使用 Integer.valueOf() 方法将 int 装箱
为 Integer 类型),接着 i += 1; 先将 Integer 类型的 i 自动拆箱成 int(使
用Integer.intValue() 方法将 Integer 拆箱为 int),完成加法运行之后的 i
再装箱成 Integer 类型。

5、问:下面程序的运行结果是什么?

Integer i1 = new Integer(127);
Integer i2 = new Integer(127);
System.out.println(i1 == i2);//false
System.out.println(i1.equals(i2));//true

注意:new Integer(xxx)这种创建对象的方法不是自动装箱,没有用到
cache,因此i1 == i2是false。

6、谈谈Integer i = new Integer(xxx)和Integer i =xxx;这两种方式的区别。

1)第一种方式不会触发自动装箱的过程;而第二种方式会触发。
2)在执行效率和资源占用上的区别。第二种方式的执行效率和资源占用在
一般性情况下要优于第一种情况(注意这并不是绝对的),因为会用到
cache

七、Java中的string的不可改变性

在Java 8 中,string内部使用char数组存储数据,并且被声明为final,因此它的不可被继承。

public final class String implements java.io.Serializable, Comparable, CharSequence { 
			private final char value[]; 
}

不可变性的好处:

1.可以缓存hash值

因为Stringhash值经常被使用,例如String用作HashMapkey。不可变得特性可以使得hash值变得不可变,因此只需要进行一次计算。

2.常量池优化

String对象创建之后,会在字符串常量池中进行缓存,如果下次创建同样的对象时,会直接返回缓存的作用。

3.线程安全

String不可变性天生具备线程安全,可以在多个线程中安全使用。

八、Java中的String类的常用方法都有那些

  • length():返回字符串的长度
  • charAt():返回指定索引处的字符
  • substring():截取字符串
  • trim():去除字符串两端空白
  • split():分割字符串,返回一个分割后的字符串数组
  • replace():字符串替换
  • indexOf():返回指定的字符索引
  • toLowerCase():将字符串转换成小写字符
  • toUpperCase():将字符串转成大写字符

九、Java中的String和StringBuffer、StringBulider的区别是什么?

如图所示:

可变性 线程安全性 性能
String 不可变 安全
StringBuffer 可变 不安全
StringBulider 可变 安全 较高

十、switch是否能作用在byte上,是否能作用在long上,是否能作用在String上

switch可以作用在char byte short int 及它们对应的包装类型,switch不可以作用于long double float boolean 及它们的包装类型。在jdk1.5之后可以作用于枚举类型,在jdk1.7之后可以作用于String类型。

十一、Java中的final、finally、finalize区别

  • final主要用于修饰类、变量和方法
  • finally一般作用在finally代码块中,在处理异常的时候,通常我们将一定要执行的代码方法finally中,表示不管是否出现异常,该代码块都会执行,一般用来存放一些关闭资源的代码。
  • finalize是一个属于object类的一个方法,该方法一般由 垃圾回收器来调用,当我们调用System.gc()方法的时候,由垃圾回收器调用finalize(),回收垃圾,但Java语言规范并不保证inalize方法会被及时的执行,而根本不会保证它们会被执行。

十二、面向对象的三大特性(封装、继承、多态)

1.封装

封装就是将一个对象内部的属性封装起来,对外提供公共的方法进行访问修改

封装的意义:
1.保证对象内部的安全性,属性不能随意修改
2.可以在修改和访问属性的时候,做额外的操作

public void setxxx(int age){
	this.age = age;
	sout("年龄修改为了:xxx");
}

2.继承

对现实生活中的父子关系进行了抽象化
在子类对象里面开辟一个父类空间,用来保存父类的相关信息
如果要使用某个成员变量或成员方法的时候,先去子类对象中找有没有,然后才去父类空间中找。
this -> 当前对象
super -> 父类空间

3.多态

一个东西的不同表现方式
运行时多态:
父类引用指向子类对象 向上转型

Fu fu = new Zi()

需要满足的条件
1.继承
2.子类重写父类方法
3.父类引用指向子类对象

多态的意义

1.可扩展性

因为一个接口/类可能有很多的实现类/子类,使用多态的话就避免使用子类的特有的方法,当需要切换一个实现类/子类使用的时候,避免修改以前的代码

2.灵活性

十三、Java程序的执行过程

.java -> java.exe -> .class ->	jvm运行
编译   ->   编写   ->  编译   ->   运行 

十四、除了Java和javac以外,你还接触过那些工具?

1.jar.exe

把javase项目打包成jar包 web项目打包成war包,部署一个web项目,直接把war包放在webapps这个文件下面

2.Javadoc.exe

如果我的项目按照Javadoc的标准来编写注释的话,javadoc就会自动帮你生成api文档
api文档很重要!后端提供数据 前端调用后端接口来访问数据,中间通过json进行数据交换

3.javap.exe

.class文件反编译 .class文件交给jvm运行的时候,会变成一条条的指令进行执行。

十五、Java的gc机制

1.垃圾的意义

没有引用指向的对象。

2.什么时候触发gc?

jvm内存满了就触发,没满就不会触发。

3.gc机制会调用什么?

Object超类的一个方法finalize()

4.jvisualvm.exe

监视JVM的运行情况,从而发现gc,堆内存存在的问题。

十六、==和equals的区别

==

对于基本数据类型,==比较的是值;对于引用类型,==比较的是内存地址。

equals

对于重写equals方法的类,equals方法和==作用类似;对于重写过equals方法的类,equals比较的是值。

十七、为什么重写equals方法要重写hashcode

1.因为如果不重写hashcode可能会出现两个相等的对象,有不一样的hash值。
2.如果不重写的话,hashmap不可用。

十八、深拷贝和浅拷贝

浅拷贝:复制出来的对象在新的地址里,但是里面的引用数据类型和以前的对象一样。

深拷贝:复制出来的对象和以前的对象没有任何关系。

十九、Java中的this和super的区别

  • 不同点: super()主要是对父类构造函数的调用,this()是对重载构造函数的调用 super()主要是在继承了父类的子类的构造函数中使用,是在不同类中的使用;this()主要是在同一类的不同构造函数中的使用
  • 相同点:super()this()都必须在构造函数的第一行进行调用,否则就是错误的 this()super()都指的是对象,所以,均不可以在static环境中使用。

this()和super()为什么必须写在第一行?
因为:super()不写在第一行的话,相当于子类都开始执行方法了,父类空间还没生成

二十、LikedList和ArrayList有什么区别

  • 底层实现不同: LinkedList是双向循环链表,ArrayList是动态数组
  • 与ArrayList相比,LinkedList的增删操作效率更高,而查改操作效率
    较低。

总结

都看到这里了,点个赞呗!
关注,持续更新

相关文章

暂无评论

暂无评论...