java 基础面试题整理

本贴最后更新于 2488 天前,其中的信息可能已经时过境迁

以下面试题通过网络整理,参考了很多文章,并结合自己的一点理解进行描述,因参考文章较多,因此不再注明来源,望谅解。

HashMap 原理

HashMap 由数组和链表组成,在 HashMap 实现中,维护这一个数组结构,在 HashMap 中存入键值时,通过计算键的哈希值进而确定存放数组中的位置。然而,哈希值的计算过程中,有可能会出现哈希值一直样的情况,称为哈希冲突,也叫哈希碰撞。在这种情况下,HashMap 通过在数组中存储链表的方式解决了哈希冲突的问题。在每个数组中,同时又维护了一个链表结构,这样共同组成了 HashMap。

如果在对应数组中没有链表的存在,那么在插入数据和查询数据的操作效率都很高,因为不存在链表结构,只需要维护数组对应位置的一个 Entry 对象。

但是在如果数组位置上维护这链表情况下,查询效率会降低,因为要一个一个的遍历链表上的数据;但添加和删除操作效率更高。这也是和链表本身的结构特性相关的。

HashMap 是可以使用空键值对的,当 key 为 null 时,HashMap 会把对应的键值存放在内部数组索引为 0 的位置,如果通过 get 方法获取一个 key 为 null 的值时,HashMap 会直接从数组中的索引为 0 的位置获取对应的值进行返回。

此外,HashMap 是线程不安全的,在使用的时候应该注意。

HashMap 和 HashTable 的区别

  1. HashMap 是线程不安全的,而 HashTable 是线程安全的。
  2. HashMap 允许使用 null 键值存储,而 HashTable 不允许,无论是键或值为 null 键值会抛 NullPointerException 异常。

String 类为什么是 final 修饰的?

String 类使用 final 修饰的原因在于对 String 实例的安全性做考虑。在 String 类的内部实际上是维护这一个 final 修饰的 char 数组 value,而 final 修饰的数组实际上仅仅只是引用地址不能被修改,而数组内部的元素还是可以修改的。在 String 内部的各种对 string 进行操作的方法中,都刻意保证了 char 数组中的元素不会被修改。同时,通过 final 修饰的 String 类无法被其他类继承,这也就从根源阻止了子类对他的方法的覆盖,增加了 String 类的安全性。

ArrayList 和 LinkedList 各自实现和区别

ArrayList 内部维护着一个数组,该数组可以根据添加元素的数量进行扩容。ArrayList 可以对其中的元素实行精确定位,并可以指定元素添加的位置。在查询上效率比较高,而修改上效率会相对比较低下,因为修改元素后需要重新调整元素的位置。
LinkedList 内部维护这一个链表结构,在修改上效率会相对较高,而在元素查找时,LinkedList 需要遍历链表上的元素,效率相对低下。
此外,ArrayList 和 LinkedList 都不是线程安全的,在多线程并发访问情况下,应注意线程安全问题。

Java 中的队列都有哪些,有什么区别?

java 中的队列分为阻塞队列和普通队列。阻塞队里在添加元素时,如果队列已经满了,那添加会被阻塞,直到有空间才能继续添加;同时,在获取元素的时候,如果队列中的元素为空,获取动作会被阻塞,直到队列中有元素才能继续获取。
普通队列使用了非阻塞算法,通过使用低层次的并发原语,比如比较交换(CAS)取代了锁。

Class.forName 和 ClassLoader 的区别

Class.fornameClassLoader 都可以对类进行加载,区别如下:

  1. Class.forName:除了将类的.class 文件加载到 jvm 以外,还做了对类的解释,执行类中的 static 静态代码块。
  2. ClassLoader:ClassLoader 仅仅只会加载 class 文件到 jvm 中,而不会执行 static 静态代码块。只有在 newInstance 的时候去执行 static 静态代码块的代码。
Java 数组和链表两种结构的操作效率

相对而言,在数组中维护这元素的索引,所以在查询元素的时候,数组能够很快定位到元素的位置,效率会高些。而链表维护这元素的上一个元素和下一个元素的引用,在添加和删除的操作上效率会高很多,但是在查询是,因链表需要遍历所有元素进行比较,所以效率会相对较低。

String、StringBuilder、StringBuffer 区别

  1. String:string 是字符串常量,是不可变的,对 string 字符串进行拼接时,实际是重新创建了一个字符串对象,并把原来的变量引用指向新的字符串对象地址。
  2. StringBuffer:StringBuilder 是一个线程安全的动态字符串拼接方案,通过 StringBuilder 对字符串进行拼接不会重新创建字符串对象,而所有的操作都在同一个 StringBuilder 对象上完成,提高了代码执行的效率。
  3. StringBuilder:StringBuilder 在实现上通 StringBuffer 十分相似,但他不是线程安全的,在不考虑并发情况下,使用 StringBuilder 的效率要高于 StringBuffer。

检查异常和非检查异常的区别

  1. 检查异常:除了继承自 RuntimeException 的异常都是检查异常。检查异常即非运行时异常,此类异常由编译时产生,这类异常必须 try catch 或者 throw 出去,否则不能通过编译。比如:FileNotFoundException
  2. 非检查异常:相反,非检查异常则是继承自 RuntimeException 的异常,即运行时异常。此类异常不需要在编程中进行 try catch,发生此异常是在程序运行过程中,比如:ArrayIndexOutOfBoundsException

异常和错误的区别

  1. 异常:异常是应用程序中可预测、可恢复的问题,大多数异常表示为中、轻度问题,他是在程序运行过程中在特定环境操作下产生的。
  2. 错误:错误表示程序运行中比较严重的问题,大多数与程序编写无关,而是在 jvm 运行过程中出现问题产生的,比如:OutOfMemoryError

java 中基础数据类型和包装类有什么区别

  1. 声明方式不同,基础数据类型创建不需要通过 new 的方式创建,包装类需要。
  2. 包装类提供数据操作的方法,对象的调用是通过引用对象的地址。基础类型不是。
  3. 基础类型是值传递,包装类是引用传递。
  4. 存储位置不同,基础类型存储在栈中,包装类对象存储在堆中。
  5. 初始值不同。基础类型有自己独有的默认值,而包装类初始值为 null

java 的引用类型有哪几种

  1. 强引用:如果一个对象存在强引用,则绝不会被垃圾回收器回收。强引用示例:A a = new A();
  2. 软引用:如果一个对象存在软引用,当内存足够的时候垃圾回收器不会回收他。
  3. 弱引用:与软引用相比,弱引用具有更短的声明周期。在垃圾回收器管辖的内存范围内,如果发现对象是弱引用,不管内存是否足够,都会回收他,只是垃圾回收器不一定立即会回收而已。
  4. 虚引用:虚引用不会决定对象的生命周期,如果一个对象仅持有虚引用,垃圾回收器将随时会回收他。

接口和抽象类的区别

  1. 接口通过 interface 进行定义,而抽象类通过 abstract 进行修饰。
  2. 接口中的变量隐式的通过 public static final 进行修饰,而抽象类中可以自由定义。
  3. 接口中所有方法都没有具体实现,只有定义(在 java8 中接口可以有默认的方法实现),而抽象类中可以有方法的具体实现,也可以不实现。
  4. 接口可以多实现,抽象类只能单继承。

解决 hash 冲突的方法

  1. 开放地址法
  2. 再哈希法
  3. 链地址法
  4. 建立公共溢出区

IO 和 NIO 的区别

  1. IO 面向流,NIO 面向缓冲区。面向流即每次从流中读一个或多个字节,直到读完所有字节,在读取过程中没有缓存区,也不可以前后移动从流中读取的数据;而 NIO 读取数据到缓冲区,可以前后移动读取数据,但在读取数据到缓冲区时应注意不要覆盖已读的数据。
  2. IO 是阻塞的,NIO 是非阻塞的,从而 NIO 效率会更高。

什么时候用字节流,什么时候用字符流

处理字节或者二进制对象是用字节流;处理文字或者字符串用字符流。

  • Java

    Java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由 Sun Microsystems 公司于 1995 年 5 月推出的。Java 技术具有卓越的通用性、高效性、平台移植性和安全性。

    3187 引用 • 8213 回帖
  • 面试

    面试造航母,上班拧螺丝。多面试,少加班。

    325 引用 • 1395 回帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...
  • someone

    如果发现对象是软引用,不管内存是否足够,都会回收他,只是垃圾回收器不一定立即会回收而已。应该是弱引用打错字了。

  • someone

    确实打错字了,已经更改了,谢谢你!