大家好!在过去的几年里,我分享了很多 Java 面试题 和相关讨论。我的很多读者都要求我把它们整理在一起,以便他们能够在一个地方查看,因此这篇文章应运而生。

这篇文章包含了超过 50 个 Java 面试问题,涵盖了所有重要主题,例如 Java 基础知识、Java 集合框架Java 多线程与并发Java IOJDBCJVM 内部原理编码问题面向对象编程等等。

这些问题也在面试中经常出现,但它们并不是很难。你可能已经在电话或现场面试中碰到过它们了。

这些问题也非常适用于回顾像多线程和集合这样的重要主题。此外,我还分享了一些很有用的进阶资源,例如 The Complete Java MasterClass,它们不仅能帮你提高 Java 技能,还能填补技能空白。

那我们还等什么呢?这里列出了一些面试中最常问的 Java 问题,这些问题对初学者和有经验的 Java 开发者都适用。

为 2-3 年经验程序员准备的 50+ Java 面试题

我就不浪费你的时间了,这里就是我为初级程序员(初学者和 2-3 年经验的开发者)整理的常见 Java 面试题

1) Java 是如何实现跨平台的?(答案
提示:字节码和 Java 虚拟机。

2) Java 中的 ClassLoader 是什么?(答案
提示:它是 JVM 的一部分,用来帮类加载字节码。你可以写自己的 ClassLoader

3) 写一个 Java 程序判断一个数字是偶数还是奇数?(答案
提示:你可以使用位运算符,例如按位与(AND)。记住,偶数的二进制格式的末尾为 0,而奇数的二进制格式末尾为 1。

4) ArrayListHashSet 有什么不同?(答案
提示:ListSet 之间的所有差异在这里都适用,例如有序性、元素的重复性、随机搜索等等。若想学习更多有关 ArrayList、HashSet 和 Java 中其它重要集合的知识,你可以查看 Richard Warburton 的Java Fundamentals: Collections

68747470733a2f2f63646e2d6d656469612d312e66726565636f646563616d702e6f72672f696d616765732f75654f774d4164354742647734626c434f704542704f644d4f7463732d6574366e505941

5) 什么是单例模式中的双重检查锁(double checking locking)?(答案
提示:两次检查一个实例是否初始化,第一次无锁,而第二次有锁。

6) 你如何在 Java 中创建一个线程安全的单例?(答案
提示:方法有很多,例如使用枚举类、双重检查锁或嵌套静态类。

7) 何时在 Java 中使用 volatile 变量?(答案
提示:当你需要告知 JVM 某个变量可能被多个线程修改,并提示 JVM 不要缓存该变量的值的时候。

8) 何时使用 transient 变量?(答案
提示:当你想让一个实现了 Serializable 接口的类中的某个变量不会被序列化的时候。换句话说,当你不想在序列化对象时保存某个变量的值,你就可以用 transient 关键字修饰这个变量。若想了解更多有关 Java 中 transient 变量的信息,你可以查看 The Complete Java MasterClass

9) Java 中的 transient 变量和 volatile 变量有什么不同?(答案
提示:完全不同,一个用于序列化,而另一个用于并发。

10) Java 中的 Serializable 和 Externalizable 有什么区别?(答案
提示:Externalizable 可以让你更好地控制序列化过程。

11) 我们能重写 Java 中的私有方法吗?(答案
提示:不能。因为 Java 中要求被重写的父类方法在子类中是可见的,而父类的私有方法对子类不可见。

12) Java 中的 HashtableHashMap 有什么不同?(答案
提示:不同点有几个,但最重要的是:Hashtable 是同步的,而 HashMap 不是。和 HashMap 相比,Hashtable 是历史遗留类并且很慢。

13) Java 中的 ListSet 有什么不同?(答案
提示:List 有序并允许重复元素,Set无序并不允许重复元素。

14) Java 中的 ArrayListVector 有什么不同(答案
提示:不同点有很多,但最重要的是:ArrayList 是非同步的并且很快,而 Vector 是同步的并且很慢。Vector 也和 Hashtable 一样是历史遗留类。

15) Java 中的 HashtableConcurrentHashMap 有什么不同?(答案
提示:后者的可扩展性更强。查看 Richard Warburton 的 Java Fundamentals: Collections 以了解更多相关信息。

16) ConcurrentHashMap 是如何实现可扩展性的?(答案
提示:通过将 map 分割为段(segment)并且只在写操作时加锁。

17) 要将某个 Object 用作 HashMapKey,你需要重写哪两个方法?(答案
提示:equals 和 hashcode。

18) Java 中的 wait 和 sleep 有什么不同?(答案
提示:wait() 方法会释放锁或 monitor,而 sleep 不会。

19) Java 中的 notifynotifyAll 有什么不同?(答案
提示:notify 随机通知一个等待该锁的线程,而 notifyAll 通知所有等待该锁的线程。如果你非常确定只有一个线程在等待锁,就使用 notify,否则使用 notifyAll 会更好。若想了解更多线程相关的基础知识,你可以参阅 Java 大师 Heinz Kabutz 的 Threading Essentials Mini-Course

20) 在 Java 中,为什么你要一起重写 hashcode 和 equals() ?(答案
提示:为了符合 equals 和 hashcode 的约定,当你将对象存储到集合类(例如 HashMapArrayList)中时,你就需要这么做。

21) HashMap 的负载因子(load factor)的有什么含义?(答案
提示:负载因子就是触发 HashMap 重新调整容量的阈值,通常为 0.75,表示 HashMap 在容量达到了 75% 后就会调整自身大小。

22) Java 中的 ArrayListLinkedList 有什么区别?(答案
提示:与数组和链表一样,一个允许随机搜索而另一个不允许。链表上的插入和删除很容易,而数组上的查询很容易。若想了解更多有关 Java 数据结构的信息,你可以查看 Richard Warburton 在 Pluralsight 上的课程 Java Fundamentals: Collections

23) Java 中的 CountDownLatchCyclicBarrier 有什么不同?(答案
提示:你可以在屏障(barrier)被打破之后重用 CyclicBarrier,但你不能在计数达到零之后重用 CountDownLatch

24) 在 Java 中,何时使用 Runnable 而不是 Thread ?(答案
提示:永远都使用 Runnable

25) 为什么说 Java 中的枚举类(Enum)是类型安全的?(答案
提示:这意味着你不能将其它枚举类型的实例赋值给一个枚举变量。例如,如果你已经有了一个叫做 DayOfWeek 的枚举变量,你就不能再将 DayOfMonth 的值赋给它了。

26) Java 中 Integer 的自动装箱是如何实现的?(答案
提示:通过使用 valueOf() 方法。

27) PATHClassPath 有什么区别?(答案
提示:PATH 由操作系统使用,而 Classpath 是 JVM 用来定位 Java 二进制文件(例如 JAR 文件或 Class 文件)的。查看 Java Fundamentals: The Core Platform 以了解更多有关 PATHClasspath 和其它 Java 环境变量的信息。

68747470733a2f2f63646e2d6d656469612d312e66726565636f646563616d702e6f72672f696d616765732f696f2d6c504536376f4d47316f42683230344c76506d363174376b41634c4676702d4236

28) Java 中方法的重载与重写有什么区别?(答案
提示:重写发生在子类中,而重载发生在同一个类中。此外,重写发生在运行时,而重载在编译时就解析了。

29) 在 Java 中,如何防止一个类被继承?(答案
提示:直接把该类的构造函数设置为私有的。

30) 如何防止你的类被客户端使用?(答案
提示:将构造函数设置为私有,或直接在构造函数中抛出一个异常。

31) Java 中的 StringBuilderStringBuffer 有什么不同?(答案
提示:StringBuilder 不是同步的,而 StringBuffer 是同步的。

32) Java 中的多态与继承有什么区别?(答案
提示:继承允许代码重用并能建立类之间的关系,这正是多态所需要的。多态提供动态行为。查看 Java Fundamentals: Object-Oriented Design 以了解更多 OOP 的特性。

33) 在 Java 中,我们能重写静态方法吗?(答案
提示:不能,因为重写在运行时才解析,而静态方法调用在编译期间就解析了。

34) 在 Java 中,我们能访问私有方法吗?(答案
提示:能,在同一个类中就可以,在类之外则不行。

35) Java 中的接口与抽象类有什么不同?(答案
提示:从 Java 8 开始,二者的差异不再那么明显了。然而,一个 Java 类还是可以实现多个接口,却只能继承一个类。

36) Java 中的 DOM 和 SAX 解析器有什么区别?(答案
提示:DOM 将整个 XML 文件都载入内存,而 SAX 没有这么做。SAX 是一个基于事件的解析器,可以解析大文件,但 DOM 更快,是小文件的首选。

37) Java 中的 throw 和 throws 关键字有什么区别?(答案
提示:throws 声明一个方法在出错时可能抛出的异常,而 throw 关键字实际上会抛出一个异常。查看 Java Fundamentals: Exception Handling 以了解更多有关 Java 异常处理的信息。

68747470733a2f2f63646e2d6d656469612d312e66726565636f646563616d702e6f72672f696d616765732f5153714b442d623937447233366b5669563165546476714e564e67645a5270353244376e

38) Java 中的 fail-safe 和 fail-fast 迭代器有什么区别?(答案
提示:fail-safe 不会抛出 ConcurrentModificationException,而 fail-fast 在迭代集合的过程中检测到集合被修改时会抛出这个异常。

39) Java 中的 Iterator 与 Enumeration 有什么区别?(答案
提示:Iterator 还允许你在迭代时删除元素,而 Enumeration 不允许你这么做。

40) Java 中的 IdentityHashMap 是什么?(答案
提示:它是一个用 == 而不是 equals() 方法判断相等性的 Map

41) Java 中的 String 池是什么?(答案
提示:一个 String 字面量池。记住, JDK 7 已经将它从永久代移到堆中了。

42) 在 Java 中,一个实现了 Serializable 接口的类可以包含不可序列化的字段吗?(答案
提示:可以,但是你需要将它设置为 static 的或者 transient 的。

43) Java 中的 this 和 super 有什么区别?(答案
提示:this 指向的是当前实例,而 super 指向的是父类的一个实例。

44) Java 中的 ComparatorComparable 有什么区别?(答案
提示:Comparator 定义的是自定义顺序,而 Comparable 定义的是对象的自然顺序,例如 String 的字母顺序。若想了解更多有关 Java 中排序的信息,你可以查看 The Complete Java MasterClass

68747470733a2f2f63646e2d6d656469612d312e66726565636f646563616d702e6f72672f696d616765732f444f4347467464544d686a6a3366615241695136395a535478663270666679726f466676

45) Java 中的 java.util.Datejava.sql.Date 有什么不同?(答案
提示:前者既包含日期又包含时间,而后者只包含日期部分。

46) 为什么 Java 中的 wait 和 notify 方法被声明在 Object 类中?(答案
提示:因为它们需要锁,而这个锁只能从对象上获取。

47) 为什么 Java 不支持多继承?(答案
提示:因为多继承在 C++ 中使用很糟糕。但是在 Java 8 中,多继承在某种程度上是支持的——现在的 Java 中只是不支持 Type 的多继承。

48) Java 中的受检异常和非受检异常有什么区别?(答案
提示:如果是受检异常,你必须使用 catch 块进行处理。而非受检异常的没这个限制,编译过程中也不会出现任何问题。

49) Java 中的错误(Error)和异常(Exception)有什么区别?(答案
提示:我打字打累了,直接看答案吧。

50) Java 中的竞态条件(Race condition)和死锁(Deadlock)有什么区别?(答案
提示:二者都是并发程序中出现的问题,前者发生在线程调度的过程中,而后者是糟糕的代码导致的。查看 Multithreading and Parallel Computing in Java 以了解更多有关死锁、竞态条件和其它多线程问题的信息。

结语

感谢你阅读本文!祝你面试顺利!虽然面试很难,这份路线图的指导会让你离 DevOps 工程师 更进一步。

如果你喜欢这篇文章,请把它分享给你的朋友和同事,别忘了在 Twitter 上关注 javinpaul 哦!

更多资源

P.S. — 如果你需要一些 免费 的 Java 学习资源,你可以从 free Java courses 开始。

P. S. S. — 我还没有回答图片“How many String objects are created in the code?”中的那个面试问题。你能试着回答一下吗?

原文:Review these 50 questions to crack your Java programming interview,作者:javinpaul