Java基础面试题中
大约 5 分钟
Java基础面试题中
Java 面向对象基础
1. 面向对象和面向过程的区别
- 面向过程:注重流程,程序设计就是按步骤实现功能。每一步骤处理不同的任务,适合小型、功能简单的程序。
- 面向对象:注重对象,将现实中的事物抽象为对象,通过对象来管理数据和功能。适合大型、复杂系统,因为面向对象有较好的扩展性和重用性。
例子:如果做一个家庭管理系统,面向过程可能是写一系列功能的代码,比如增加家庭成员、计算家庭总开销等。而面向对象会将家庭成员、支出等作为对象,每个对象有自己的属性和方法,更易维护和扩展。
2. 创建一个对象用什么运算符?
- new 运算符:在 Java 中创建一个对象使用
new运算符,它分配内存并调用构造方法来初始化对象。
例子:Person person = new Person(); 在这里,new 用来创建一个 Person 对象。
3. 对象实体与对象引用有何不同?
- 对象实体:是实际的数据和方法的存储空间,即对象本身,保存在内存中。
- 对象引用:是指向对象的一个变量,保存对象的地址。
例子:Person person1 = new Person(); 创建了一个 Person 对象,并赋值给引用 person1。这里 person1 只是一个引用,它指向实际的 Person 实体。
4. 对象的相等和引用相等的区别
- 对象相等:用
.equals()方法来比较两个对象的内容是否相等。 - 引用相等:用
==比较,判断两个引用是否指向同一个对象。
例子:Person person1 = new Person(); Person person2 = person1; 此时 person1 == person2 是 true,但如果两个对象内容相同而引用不同,== 可能为 false,equals() 可以判断它们的内容相等。
5. 如果一个类没有声明构造方法,该程序能正确执行吗?
- 是的。如果没有声明构造方法,Java 会自动提供一个无参的默认构造方法,所以程序可以正常执行。
6. 构造方法有哪些特点?是否可被 override?
- 特点:构造方法和类同名,没有返回值,用于创建和初始化对象。
- 不可
override:因为构造方法不能被继承,但可以重载(参数不同)。
7. 面向对象三大特征
- 封装:将数据和方法封装在类中,控制对数据的访问,保证数据的安全性。
- 继承:一个类可以继承另一个类的属性和方法,实现代码重用。
- 多态:同一个方法在不同对象上表现出不同行为,可以通过重写和接口实现。
例子:家族中的长辈和后代可以看作一个继承关系,后代继承长辈的特征(属性和行为),并且在不同家庭成员上有多态表现。
8. 接口和抽象类有什么共同点和区别?
- 共同点:两者都可以声明抽象方法,不直接实现。
- 区别:
- 抽象类可以有构造方法和已实现的方法,接口只能有抽象方法(Java 8 开始允许默认方法)。
- 类可以实现多个接口,但只能继承一个抽象类。
例子:接口就像是行为协议,比如“驾驶”行为,任何会驾驶的类都可以实现该接口;而抽象类更像是一种类型或基类,比如“车辆”。
9. 深拷贝和浅拷贝区别了解吗?什么是引用拷贝?
- 浅拷贝:只复制对象的引用,修改副本会影响原对象。
- 深拷贝:复制整个对象及其引用对象的内容,修改副本不影响原对象。
- 引用拷贝:和浅拷贝类似,指的是只拷贝引用而非实际对象。
例子:如果是浅拷贝,两本书的书签指向同一页;而深拷贝相当于每本书各自独立,不会相互影响。
10. Object 类的常见方法有哪些?
toString():返回对象的字符串表示。equals(Object obj):判断两个对象内容是否相等。hashCode():返回对象的哈希值。clone():用于创建对象的副本。
11. == 和 equals() 的区别
==:用于比较引用是否相等,即是否是同一个对象。equals():用于比较对象的内容是否相等。
12. hashCode() 有什么用?为什么要有 hashCode()?
- 作用:
hashCode()返回一个整数哈希值,用于对象在哈希表中的存储。 - 重要性:保证相等的对象有相同的哈希值,以便正确存储在哈希结构中(如
HashMap)。
13. 为什么重写 equals() 时必须重写 hashCode() 方法?
- 如果两个对象通过
equals()比较相等,它们的hashCode()也必须相等,保证在哈希表中正确工作。
String 相关面试题
1. String、StringBuffer、StringBuilder 的区别?
- String:不可变,一旦创建就无法更改内容。适合小量字符串拼接。
- StringBuffer:可变,线程安全,适合多线程场景下的字符串修改。
- StringBuilder:可变,非线程安全,适合单线程场景的字符串修改,效率比
StringBuffer高。
2. String 为什么是不可变的?
- 原因:为了安全和效率,
String不可变,可以在多个地方安全复用,不必担心其内容被修改。
3. 字符串拼接用“+” 还是 StringBuilder?
- 使用
StringBuilder效率更高,因为每次拼接+都会生成新对象,StringBuilder可以在原对象上操作。
4. String#equals() 和 Object#equals() 有何区别?
String#equals()比较的是字符串内容,而Object#equals()默认比较的是引用地址。
5. 字符串常量池的作用了解吗?
- 作用:节省内存,存储所有相同的字符串字面量,避免重复创建。
6. String s1 = new String("abc"); 这句话创建了几个字符串对象?
- 这段代码创建了 两个 字符串对象:一个在字符串池中("abc"),一个在堆内存中(
new String("abc"))。
7. String#intern 方法有什么作用?
- 将字符串放入常量池中,如果池中已存在相同字符串则返回池中的引用。
8. String 类型的变量和常量做“+”运算时发生了什么?
- 编译器会将常量拼接优化为一个字符串,而变量拼接则在运行时使用
StringBuilder完成拼接。
