网上始终找不到令自己满意的面试题,所以我打算自己整理面试题,从简单的到难的,尽量简单准确描述回答降低大家理解和背的难度,有错误或者有更好的回答请在评论回复我,感谢大家。
什么是java?
回答:Java是一种高级编程语言。(可以多说一说)
java的主要特点(优点)有什么?
回答:跨平台性、面向对象、多线程、安全性、动态性等(说几个后可能就某一个继续问,一般是提问面向对象)
什么是面向对象?
回答:它将现实世界中的实体抽象为对象,通过对象之间的交互来设计和构建软件系统。(最好回答三大特性)
面向对象的三大特性是什么?
回答:封装、继承、多态(可能就某一个继续问)
JDK和JRE的区别?
回答:
- JDK:Java开发工具包,用于开发Java应用程序。它提供了编译、调试和运行Java程序所需的所有工具和库。
- JRE:Java运行时环境,用于运行Java应用程序。它提供了运行Java程序所需的最小环境和库。
JDK是为Java开发者准备的,包含了编译、调试和运行Java程序所需的所有工具和库,而JRE是为最终用户准备的,只包含了运行Java程序所需的最小环境和库。
(如果可以把俩者包含的内容也记住:
- JDK:
javac
:Java编译器,用于将Java源代码编译成字节码。java
:Java运行时工具,用于运行编译后的Java程序。javadoc
:生成API文档的工具。jdb
:Java调试器,用于调试Java程序。- 各种其他工具,如
jar
(打包工具)、javadoc
(生成文档的工具)等。 - Java核心类库(也称为Java标准类库)。
- JRE:
- Java虚拟机(JVM),负责执行Java字节码。
- Java核心类库,但通常不包括开发工具。
- 用于运行Java应用程序的必需文件和设置。
)
java有几种基本数据类型,有哪些?
回答:有八种:byte,short,int,long,float,double,char,boolean.
技巧:整型数字类型从小往大背(byte,short,int,long),然后浮点型数字(float,double),布尔类型很容易记住,char容易忘。取值范围的话,就是:“正负字节×8-1(char只有正)”字节大小按顺序分别为:1,2,4,8,4,8,2。默认值也需要记住。String字符串是引用类型别记错了。
boolean占多少字节?
回答:
单独使用时:在Java虚拟机中,boolean类型单独使用时通常会被映射为int类型,占用4个字节。在数组中使用时:当boolean类型作为数组元素时,每个元素占用1个字节。
其他知识点也需要记:
boolean
数组可以通过循环来初始化为所有元素都为false
。boolean
类型不能与整数类型互相转换。boolean
不能参与数值运算,不能与其他类型进行强制类型转换。- 不能将0或1赋值给boolean类型的变量,也不能与0或1之间相互转换。
基本数据类型和引用数据类型的区别?
回答:
- 基本数据类型:通过值传递,方法内部对参数的修改不会影响外部变量的值。
- 引用数据类型:通过引用传递,方法内部对参数对象的修改会影响外部对象。
- 基本数据类型:变量名指向具体的数值。
- 引用数据类型:变量名指向存数据对象的内存地址,即变量名指向hash值。
什么是值传递什么是引用传递?
回答:
1.值传递:方法调用时,实际参数把它的值传递给对应的形式参数,方法执行中形式参数值的改变不影响实际参 数的值。
2.引用传递:也称为传地址。方法调用时,实际参数的引用(地址,而不是参数的值)被传递给方法中相对应的形式参数,在方法执行中,对形式参数的操作实际上就是对实际参数的操作,方法执行中形式参数值的改变将会影响实际参数的值。
为什么要用包装类?
回答:
1.面向对象要求:Java 是一门面向对象的编程语言,要求所有的数据都应该是对象。但是,基本数据类型(如int、char、double等)并不是对象,它们没有成员方法和其他面向对象的特性。为了满足面向对象编程的要求,Java 引入了包装类,将基本数据类型封装成对象,使得它们也具有面向对象的特性。(java基本都是类,一切皆对象,包装类也是为了这个出的)
泛型要求:泛型是 Java 中很重要的特性,它提供了类型安全和代码重用的功能。但是泛型要求类型参数必须是对象类型,不能是基本数据类型。因此,如果想在泛型中使用基本数据类型就需要使用对应的包装类。
3.null 值表示:包装类可以表示 null值,而基本数据类型不能。这在某些场景下很有用,比如在接口传参中,如果使用包装类及时前端不传参也不会报错,而使用基本数据类型,如果前端忘记传参就会报错。
基本类型和包装类的区别?
回答:
- 包装类变量必须实例化后才能使用,而基本类型不需要
- 包装类实际是对象的引用,当new一个包装类时,实际上是生成一个指针指向此对象;而基本类型则是直接存储数据值
- 包装类型的默认值是null,基本类默认值不能为null。
其他区别:
数据类型
基本类型:包括byte、short、int、long、float、double、char和boolean等8种基本数据类型。它们是直接存储数据值的,不具有方法和属性。
包装类:对应于每种基本类型,Java提供了相应的包装类,例如Byte、Short、Integer、Long、Float、Double、Character和Boolean等。包装类是引用类型,它们包装了对应基本类型的值,并提供了一些方法和属性来操作这些值。
对象和存储
基本类型:基本类型的变量直接存储在栈中,它们的值是直接存储的,没有指向其他对象的引用。
包装类:包装类是对象,存储在堆中,当创建包装类对象时,会在堆中分配内存,并将基本类型的值封装到包装类中。
性能
基本类型:由于基本类型直接存储值,因此处理速度更快,占用内存较少。
包装类:由于包装类是对象,需要额外的内存开销,并且在自动装箱和拆箱过程中会涉及到一些性能消耗。
什么是装箱和拆箱?
回答:
- 装箱:将基本类型转换成包装类对象
- 拆箱:将包装类对象转换成基本类型的值
“==”和"equals"的区别?
回答:
==:
如果比较的是基本数据类型,那么比较的是变量的值
如果比较的是引用数据类型,那么比较的是地址值(两个对象是否指向同一块内存)
equals:
如果没重写equals方法比较的是两个对象的地址值
如果重写了equals方法后我们比较的是对象中的属性的内容
equals方法是从Object类中继承的,默认的实现就是使用==
为什么重写equals()时,必须重写hashCode()?
回答:保证同一对象,如果不重写hashcode,可能会出现equals比较一样,但是hashcode不一样的情况
两个对象使用equals比较相同,hashCode一定相同
hashCode相同,equals()比较不一定相同,可能出现hash冲突
hashCode不同,equals()一定不同
为什么重写equals()时一定要重写hashCode()?_重写equals方法必须要重写hascode吗-CSDN博客
重载和重写的区别
回答:重载:发生在同一类中,函数名必须一样,参数类型、参数个数、参数顺序、返回值、修饰符可以不一样。
重写: 发生在父子类中,函数名、参数、返回值必须一样,访问修饰符必须大于等于父类,异常要小于等于父类,父类方法是private不能重写。(俩同俩大一小)
-
两同:
- 方法名相同:子类中的方法名必须与父类中的方法名完全相同。
- 参数列表相同:子类方法的参数列表必须与父类方法的参数列表完全相同,包括参数的类型和顺序。
-
两小:
- 返回值类型小于等于父类:子类方法的返回值类型必须小于或等于父类方法的返回值类型。具体规则如下:
- 如果父类方法的返回类型是
void
,则子类方法的返回类型也必须是void
。 - 如果父类方法的返回类型是基本数据类型(如
int
、float
等),则子类方法的返回类型也必须是相同的基本数据类型。 - 如果父类方法的返回类型是引用数据类型,则子类方法的返回类型可以是父类返回类型的子类或相同的类型。
- 如果父类方法的返回类型是
- 异常声明小于等于父类:子类方法抛出的异常必须小于或等于父类方法抛出的异常。这意味着子类方法不能抛出父类方法没有声明的异常,或者抛出更广泛的异常。
- 返回值类型小于等于父类:子类方法的返回值类型必须小于或等于父类方法的返回值类型。具体规则如下:
-
一大:
- 访问权限大于等于父类:子类方法的访问权限必须大于或等于父类方法的访问权限。访问权限从小到大依次为:
private
<默认
<protected
<public
。因此,如果父类方法是默认访问权限,子类重写的方法可以是默认、protected或public,但不能是private。
- 访问权限大于等于父类:子类方法的访问权限必须大于或等于父类方法的访问权限。访问权限从小到大依次为:
接口和抽象类的区别?
回答:
-
继承数量的限制:
- 抽象类(Abstract Class)只能被单继承,即一个类只能继承一个抽象类。
- 接口(Interface)则可以被多重实现,一个类可以实现多个接口。
-
构造方法:
- 抽象类可以有构造方法,这些构造方法可以被同一类层次结构中的子类调用。
- 接口在Java 8之前不能有构造方法,但可以从Java 9开始,接口可以有私有构造方法,仅限于静态成员的创建。
-
实例变量和常量:
- 抽象类可以包含实例变量和静态变量。
- 接口在Java 8之前只能包含静态常量和抽象方法。从Java 8开始,接口可以包含默认方法(非抽象方法)和静态方法。
- 从Java 9开始,接口可以包含私有方法。
-
方法的实现:
- 抽象类可以包含非抽象方法(即具体实现的方法)和抽象方法。
- 接口在Java 8之前只能包含抽象方法。从Java 8开始,接口可以包含默认方法(有具体实现的方法)和静态方法。
-
方法的修饰符:
- 抽象类中的方法可以有任意访问修饰符(public, protected, private)。
- 接口中的方法在Java 8之前默认是public的,不能有其他修饰符。从Java 9开始,接口中的方法可以是private的。
-
字段的修饰符:
- 抽象类中的字段可以有任意访问修饰符。
- 接口中的字段默认是public static final的,即它们是公共的、静态的、最终的常量。
-
设计目的:
- 抽象类用于表示一个不完整的类,它通常作为基类使用,定义一组相关功能的框架。
- 接口用于定义一个类的行为规范,它是一种形式的契约,规定实现类必须遵守的规则。
-
多继承解决方案:
- 由于Java不支持类的多继承,但可以通过实现多个接口来解决多继承问题,这是接口相比抽象类的一个重要优势。
-
实例化:
- 抽象类不能被实例化,但可以声明抽象类类型的引用指向子类的实例。
- 接口也不能被实例化,但可以声明接口类型的引用指向实现接口的类的实例。
静态变量和实例变量有什么区别
回答:(笔试题也容易出题考)
-
所属范围:
- 静态变量:也称为类变量,它们属于类本身,而不是类的某个特定实例。因此,静态变量在类加载时就被创建,并且在整个JVM中只有一个副本,所有实例共享这个变量。
- 实例变量:也称为非静态变量,它们属于类的特定实例。每个对象实例都有自己的一份实例变量的副本,不同实例之间互不影响。
-
内存分配:
- 静态变量:在Java堆的方法区(Java 8及以前)或元数据区(Java 9及以后)中分配内存,因为它们是与类关联的,而不是与对象实例关联的。
- 实例变量:在Java堆的新生代中为每个对象实例分配内存。每个对象实例都有自己的实例变量副本。
-
生命周期:
- 静态变量:生命周期与类的生命周期相同,从类加载开始,到类被卸载结束。
- 实例变量:生命周期与对象实例的生命周期相同,从对象创建开始,到对象被垃圾回收结束。
-
访问方式:
- 静态变量:可以通过类名直接访问,也可以通过实例访问,但推荐通过类名访问,以表明其静态性质。
- 实例变量:只能通过对象实例访问。
-
初始化时机:
- 静态变量:在类加载时初始化,即在任何对象创建之前就已经初始化。
- 实例变量:在对象创建时初始化,可以在声明时初始化,也可以在构造函数中初始化。
-
线程安全:
- 静态变量:由于所有实例共享同一个静态变量,因此需要特别注意线程安全问题。
- 实例变量:由于每个实例都有自己的副本,天然具有线程安全性。
finally、final、finalize区别
回答:
1.final可以修饰类、变量、方法,修饰类表示该类不能被继承、修饰方法表示该方法不能被重写、修饰变量表示该变量是一个常量不能被重新赋值。
2.finally一般作用在try-catch代码块中,在处理异常的时候,通常我们将一定要执行的代码方法finally代码块中,表示不管是否出现异常,该代码块都会执行,一般用来存放一些关闭资源的代码。
3.finalize是一个方法,属于Object类的一个方法,而Object类是所有类的父类,该方法一般由垃圾回收器来调用,当我们调用System.gc() 方法的时候,由垃圾回收器调用finalize(),回收垃圾,一个对象是否可回收的最后判断。
String、StringBuffer、StringBuilder的区别
回答:
String
类是不可变的,即一旦创建,其值就不能被改变。每次对字符串进行修改操作时,实际上都会生成一个新的String
对象。
StringBuffer
和StringBuilder
允许在原有对象上进行操作,这意味着它们可以修改对象的值而不创建新的对象
StringBuffer
是线程安全的(StringBuffer
的方法都是用synchronized
关键字修饰的,确保了线程安全。),这意味着它的方法是同步的,可以在多线程环境中安全使用。StringBuilder
不是线程安全的,它的方法没有同步,因此在多线程环境中使用时可能会导致问题。
在性能方面,StringBuilder>
StringBuffer>
String
。这是因为StringBuilder
不涉及线程安全的开销,StringBuffer
虽然有线程安全的开销,但比每次操作都创建新对象的String
要高效。