【Java基础知识】
1. 所有的类都继承于 `Object` 类,这是Java语言的基础特性。`Object` 类是所有类的父类,包括我们自定义的类。`Object` 类提供了若干个直接子类,比如`Thread`、`ClassLoader`、`Runnable`等。而`Object` 类本身包含了一些常用方法,如`toString()`用于返回对象的字符串表示,`hashCode()`用于获取对象的哈希值,`equals()`用于比较两个对象是否相等,`clone()`用于复制对象,`finalize()`在垃圾回收前被调用,允许对象进行必要的清理工作。
2. `String`、`StringBuilder` 和 `StringBuffer` 主要用于处理字符串。`String` 是不可变的,修改字符串会创建新的对象,效率较低;`StringBuilder` 和 `StringBuffer` 可变,适用于频繁修改的场景,其中`StringBuilder`是线程不安全的,而`StringBuffer`是线程安全的。
3. `ArrayList` 和 `LinkedList` 是两种不同的列表实现。`ArrayList` 底层基于动态增长的数组,访问速度快,但插入和删除元素时性能较低;`LinkedList` 使用双向链表结构,插入和删除速度快,但随机访问慢。`HashMap` 和 `HashSet` 分别是键值对存储和无序唯一元素的集合,前者允许null键和值,后者不允许null元素。`HashMap`查询速度快,而`HashSet`实现了Set接口,不允许重复元素。
4. `==`和`equals()`的区别在于,`==`比较的是对象的引用,而`equals()`比较的是对象的内容。对于基本类型,`==`直接比较数值;对于对象,如果两个引用指向同一实例,`==`返回`true`,`equals()`需要重写才能比较对象内容。
5. `Throwable` 是所有异常的基类,分为`Error`和`Exception`两个主要子类。运行时异常(RuntimeException)如`NullPointerException`、`ArithmeticException`等,不需要显式捕获,程序运行时会立即抛出。
6. 创建线程有三种方式:继承`Thread`类并重写`run()`方法,实现`Runnable`接口并传入`Thread`构造器,或者使用Java 5引入的`ExecutorService`和`Callable`接口。
7. 对于`i++`这样的多线程访问,需要使用同步控制来避免数据竞争问题,可以使用`synchronized`关键字或者`Lock`接口如`ReentrantLock`。
8. 二分查找是一种高效的查找算法,适用于有序数组。它将目标值与数组中间元素比较,根据比较结果缩小搜索范围,直至找到目标值或确定不存在。
9. 常见的排序算法有快速排序、归并排序、冒泡排序、选择排序、插入排序、堆排序等。快速排序的基本思想是通过一趟排序将待排记录分隔成独立的两部分,其中一部分记录的关键字均比另一部分的关键字小,然后分别对这两部分记录继续进行排序,以达到整个序列有序。其平均时间复杂度为O(nlogn)。
10. Java中的垃圾回收机制是自动回收不再使用的对象所占用的内存,主要包括标记-清除、复制、标记-整理和分代收集等策略。它有助于防止内存泄漏,但不能保证100%消除。
11. Java可能会出现内存泄漏,比如持有引用导致对象无法被垃圾回收,或者静态变量引用大对象等。这种情况通常发生在长期运行的应用中,需要注意及时释放不再使用的资源。
12. 抽象类和接口都是Java中实现多态的方式。抽象类可以包含方法实现,可以有非抽象方法和字段,而接口只能声明方法(Java 8以后可以包含默认方法和静态方法),不能有字段和方法实现。一个类可以实现多个接口,但只能继承一个抽象类。
13. `String`类是final的,不能被继承。这是为了保证字符串常量池的高效性和安全性,避免因为继承而修改`String`的行为。
这些是Java开发中的一些基础概念和面试常见问题,理解和掌握它们对于成为一名合格的Java开发者至关重要。在实际开发中,这些知识将帮助你写出更高效、更稳定的代码。