Java基础高频面试题汇总
五、String、StringBuffer、StringBuilder的区别
一、面向对象
相较于面向过程,是两种不同的处理问题的角度。
面向过程更注重事情的每⼀个步骤及顺序。
面向对象更注重事情有哪些参与者(对象)、及各自需要什么。
例如:洗衣机洗衣服
(1)站在面向过程的角度,会将任务拆解成⼀系列的步骤。
打开洗衣机----->放衣服----->放洗衣粉----->清洗----->烘干衣服
(2)站在面向对象的角度,会拆出人和洗衣机两个对象,然后分析两个对象分别要做什么事。
a. 人:打开洗衣机 放衣服 放洗衣粉
b. 洗衣机:清洗 烘干
从以上例子能看出,面向过程比较直接高效,而面向对象更易于复用、扩展和维护。
封装
明确标识出允许外部使用的所有成员函数和数据项,内部细节对外部调用透明,外部调用无需修改或者关心内部实现。
(1)JavaBean
JavaBean的属性私有,提供了getter,setter方法进行访问,这样属性的赋值or获取逻辑只能由JavaBean本身决定,而不能由外部胡乱修改。
private String name;
public void setName(String name) {
this.name = "Harmony_" + name;
}
例如我们规定设置值的时候,必须以“Harmony_”为前缀,如果我们不用private加以限制,让外部使用属性名.name的方式,就可能会违背这一规则。
(2)ORM框架
我们不关心链接怎么建立,SQL怎么写,只要引入MyBatis,调用方法即可。
继承
继承基类的方法,并做出自己的改变or扩展。
子类共性的方法或者属性直接使用父类的,而不需要自己再定义(达到代码复用的效果),只需扩展自己个性化的。
多态
基于对象所属类的不同,外部对同⼀个方法的调用,实际执行的逻辑不同。
前提:继承、方法重写、父类引用指向子类对象。
父类类型 变量名 = new 子类对象();
变量名.方法名(); //调用的实际上是子类的方法
但是无法调用子类对象特有的方法。
二、JDK、JRE、JVM之间的区别
JDK:Java Develpment Kit Java开发工具
JRE:Java Runtime Environment Java运行时环境
JVM:java Virtual Machine Java虚拟机
JRE = JVM + lib库
JDK = JRE + Java工具
Java是跨平台的,通过javac编译的.class文件可以“到处运行”,.class文件再由JVM进行解释。
三、==和equals方法之间的区别
"==":
如果是基本数据类型,比较两者的值是否相等。
如果是引用数据类型,不仅要比较两者的值是否相等,而且还要比较两者的引用是否指向同一个对象(同一个内存地址)。
"equals()":
仅仅比较数值是否相等。
public class test {
public static void main(String[] args) {
String a = new String("foo");
String b = new String("foo");
System.out.println("==:" + (a == b));
// false;
System.out.println("equals:" + a.equals(b));
// true;
}
}
四、final关键字的作用是什么?
修饰类:表示类不可被继承,final类中的一切方法都是final。
修饰方法:表示方法不可被子类覆盖,但是可以重载
修饰变量:表示变量⼀旦被赋值就不可以更改它的值。
- (1) 修饰成员变量
如果final修饰的是类变量,只能在静态初始化块中指定初始值 或者 声明该类变量时赋值(2处)。
如果final修饰的是成员变量,可以在非静态初始化块、声明该变量、构造器中赋值(3处)。
- (2) 修饰局部变量
系统不会为局部变量进⾏初始化,局部变量必须由程序员显示初始化。因此使⽤final修饰局部变量时, 即可以在定义时指定默认值(后⾯的代码不能对变量再赋值),也可以不指定默认值,⽽在后⾯的代码 中对final变量赋初值(仅⼀次)
public class FinalVar {
// 类变量
final static int a = 0;//在声明的时候就需要赋值 或者静态代码块赋值
static {
a = 0;
}
// 成员变量
final int b = 0; //在声明的时候就需要赋值 或者代码块中赋值 或者构造器赋值
{
b = 0;
}
public static void main(String[] args) {
// 局部变量
final int localA;
//局部变量只声明没有初始化,不会报错,与final⽆关。
localA = 0;
//在使⽤之前⼀定要赋值
//localA = 1; 但是不允许第⼆次赋值
}
}
- (3) 修饰基本类型数据和引用类型数据
如果是基本数据类型的变量,则其数值⼀旦在初始化之后便不能更改;
如果是引⽤类型的变量,则在对其初始化之后便不能再让其指向另⼀个对象。但是引⽤的值是可变 的
public class Demo{
public static void main() {
final int[] iArr={1,2,3,4};
iArr[2]=-3;//合法
iArr=null;//⾮法,对iArr不能重新赋值
final Person p = new Person(25);
p.setAge(24);//合法
p=null;//⾮法
}
五、String、StringBuffer、StringBuilder的区别
String是由final修饰的,是不可变的,如果尝试去修改,会新生成⼀个字符串对象(导致内存浪费)
StringBuffer和StringBuilder是可变的
StringBuffer是线程安全的,StringBuilder是线程不安全的。
StringBuffer方法都是由synchronized关键字修饰的。所以在单线程环境下StringBuilder效率会更高。
性能:StringBuilder > StringBuffer > String
使用场景:经常要改变字符串内容的,使用后面两个;优先使用StringBuilder,多线程使用共享变量时使用StringBuffer
六、重载和重写的区别
重载:
发生在同⼀个类中,方法名必须相同,参数类型不同、个数不同、顺序不同,方法返回值和访问修饰符可以不同,发生在编译时。
重写:
发生在父子类中,方法名、参数列表必须相同。
返回值范围小于等于父类,抛出的异常范围 小于等于父类,访问修饰符范围大于等于父类。
如果父类方法访问修饰符为private、final则子类就不能重写该方法。
七、接口和抽象类的区别(重点)
(1)抽象类可以存在普通成员函数,而接口中只能存在public abstract 方法(只能有抽象方法)。
(2)抽象类中的成员变量可以是各种类型的,而接⼝中的成员变量只能是public static final类型的。
(3)抽象类只能继承⼀个,接口可以实现多个。
[public] interface interface_name [extends interface1_name[, interface2_name,…]] {
// 接口体,其中可以包含定义常量和声明方法
[public] [static] [final] type constant_name = value; // 定义常量
[public] [abstract] returnType method_name(parameter_list); // 声明方法
}
public、abstract、static、final都是可以省略的!
详细说明(深入说明)
接口的设计目的,是对类的行为进行约束(更准确的说是⼀种“有”约束,因为接⼝不能规定类不可以有 什么行为),也就是提供⼀种机制,可以强制要求不同的类具有相同的⾏为。它只约束了行为的有无, 但不对如何实现行为进行限制。
抽象类的设计目的,是代码复用。当不同的类具有某些相同的行为,可以让这些类都派生出⼀个抽象类。一定是先有子类再有抽象类!将子类中共性的方法抽取出来形成抽象类。抽象类不能被实例化,这是因为抽象类有一些方法是没有被实现!
接口是对行为的抽象,表达的是 like a 的关系。比如: Bird like a Aircraft 。接口的核心是定义行为,即实现类可以做什么,至于实现类主体是谁、是如何实现的,接口并不关心。
抽象类是对类本质的抽象,表达的是 is a 的关系,比如: BMW is a Car 。抽象类包含并实现子类的通用特性,将子类存在差异化的特性进行抽象,交由子类去实现。
使用场景
当你关注⼀个事物的本质的时候,用抽象类;当你关注⼀个操作的时候,用接口。
抽象类的功能要远超过接口,但是,定义抽象类的代价高。因为高级语言来说(从实际设计上来说也是)每个类只能继承一个类。
在这个类中,你必须继承或编写出其所有子类的所有共性。虽然接口在功能上会弱化许多,但是它只是针对⼀个动作的描述。而且你可以在一个类中同时实现多个接口。在设计阶段会降低难度。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)