面试阿里常被问到的十个 Java 面试题

1. 以满分十分来评估自己——你有多擅长 Java?

如果你并不完全确信你自己或是你对 Java 的熟练程度,那么这会是一个非常棘手的问题。如果有这种情况,你应该把打分调低一点。之后,你大概会得到与你承认的水平相符的问题。因此,假如你给自己满分,却不能回答一个有点难的问题,那将会对你不利。

2. 阐述 Java 7 和 Java 8 的区别。

实话说,两者有很多不同。如果你能列出最重要的,应该就足够了。你应该解释 Java 8 中的新功能。想要获得完整清单,请访问官网: Java 8 JDK

你应该知道以下几个重点:

  • lambda 表达式 ,Java 8 版本引入的一个新特性。lambda 表达式允许你将功能当作方法参数或将代码当作数据。lambda 表达式还能让你以更简洁的方式表示只有一个方法的接口 (称为函数式接口) 的实例。
  • 方法引用, 为已命名方法提供了易于阅读的 lambda 表达式。
  • 默认方法, 支持将新功能添加到类库中的接口,并确保与基于这些接口的旧版本的代码的二进制兼容性。
  • 重复注解, 支持在同一声明或类型上多次应用同一注解类型。
  • 类型注解, 支持在任何使用类型的地方应用注解,而不仅限于声明。此特性与可插入型系统一起使用时,可增强对代码的类型检查。

3. 你了解哪些集合类型?

你应该知道以下几个最重要的类型:

<pre class="hljs nginx" style="padding: 0.5em; font-family: Menlo, Monaco, Consolas, &quot;Courier New&quot;, monospace; color: rgb(68, 68, 68); border-radius: 4px; display: block; margin: 0px 0px 0.75em; font-size: 14px; line-height: 1.5em; word-break: break-all; word-wrap: break-word; white-space: pre; background-color: rgb(246, 246, 246); border: none; overflow-x: auto; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">ArrayList
LinkedList
HashMap
HashSet
</pre>

之后,你可能会被问到这样一些问题,比如何时应该使用此种特定类型,它比其他的好在哪里,它是怎么存储数据的以及隐匿在其后的数据结构是什么。

最好的方法是尽可能多地了解这些集合类型,因为这类问题几乎是无穷尽的。

4. Object 类包含哪些方法?

这是一个非常常见的问题,用来确定你对基础知识的熟悉程度。以下是每个对象都具有的方法:

java.lang 包中, Object 类位于类层次结构的顶端。每个类都是 Object 类直接或间接的子类。你使用或编写的每个类都继承了 Object 类中的实例方法。你并不需要使用这些方法中的任何一种,但是,如果你选择这样做,则可能需要用你的类的特定代码来重写这些方法。以下是本节所讨论的从 Object 类中继承的方法:

*   `protected Object clone() throws CloneNotSupportedException ` 创建并返回此对象的副本。
*   `public boolean equals(Object obj) ` 判断另一对象与此对象是否「相等」。
*   `protected void finalize() throws Throwable ` 当垃圾回收机制确定该对象不再被调用时,垃圾回收器会调用此方法。
*   `public final Class getClass() ` 返回此对象的运行时类。
*   `public int hashCode() ` 返回此对象的散列码值。
*   `public String toString() ` 返回此对象的字符串表示形式。

Object 类的 notifynotifyAllwait 方法都在同步程序中独立运行线程的活动方面发挥了作用,这将在后面的课程中讨论,在此不做介绍。其中有五种方法:

<pre class="prettyprint hljs java" style="padding: 0.5em; font-family: Menlo, Monaco, Consolas, &quot;Courier New&quot;, monospace; color: rgb(68, 68, 68); border-radius: 4px; display: block; margin: 0px 0px 1.5em; font-size: 14px; line-height: 1.5em; word-break: break-all; word-wrap: break-word; white-space: pre; background-color: rgb(246, 246, 246); border: none; overflow-x: auto; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">public final void notify()
public final void notifyAll()
public final void wait()
public final void wait(long timeout)
public final void wait(long timeout, int nanos) </pre>

5. 为什么 String 对象是不可变的?

  1. 字符串池 之所以可能,就是因为字符串在 Java 中是不可变的。由此 Java 运行时环境节省了大量堆空间,因为不同的 String 变量可以引用池中的同一 String 变量。如果 String 不是不可变的, 则字符串驻留( String interning )将是不可能的,因为一旦任一变量更改所引用的String对象的值,它也会反映在其他变量中。
  2. 如果字符串不是不可变的,那么它可能会对应用程序造成严重的安全威胁。例如,数据库用户名和密码都作为 String 传递以获取数据库连接, Socket 编程 的主机和端口信息也是如此。由于字符串是不可变的,因此其值不能被更改。否则,任何黑客都可以篡改其引用的值,这会导致应用程序中的安全问题。
  3. 由于 String 是不可变的,因此它对与 多线程处理 来说是安全的,并且可以在不同的线程之间共享单个 String 实例。这避免了为线程安全使用同步;字符串是隐式线程安全的。
  4. 字符串被用在 Java 类加载器中,其不可变性为 类加载器 加载正确的类提供了安全性。否则的话,请考虑这样一个危险的情况,在你尝试加载 java.sql.Connection 类时,你引用的值却被更改为 myhacked.Connection ,并且它能对数据库执行你不需要的操作。
  5. 由于 String 是不可变的,因此在它被创建时其散列码就被缓存,不需要再次计算。这使得它成为映射中键的理想对象,它的处理速度比其他 HashMap 键类型快。这就是为什么 String 是 HashMap 中最常用的键类型。

为什么 Java 中的字符串不可变? 点击这里了解更多。

6. final,finally,和 finalize 三者之间有什么不同?

这是我最喜欢的问题。

  • final 关键字用于在多个语境下定义只能分配一次的实体。
  • finally 代码块是用于执行重要代码 (如关闭连接、流等) 的代码块。无论是否处理异常, finally 代码块总会被执行。 finally 代码块紧随 try 代码块或 catch 代码块。
  • 这是在删除或销毁对象之前垃圾回收器总会调用的方法,该方法使得垃圾回收机制能够执行清理活动。

7. 什么是菱形继承问题?

菱形继承问题反映了为什么在 Java 中我们不被允许实现多继承。如果有两个类共同继承一个有特定方法的超类,那么该方法会被两个子类重写。然后,如果你决定同时继承这两个子类,那么在你调用该重写方法时,编译器不能识别你要调用哪个子类的方法。

![image](http://upload-images.jianshu.io/upload_images/12624762-e83bcd79f675fce6.png!web?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

我们把这个问题称为 菱形继承问题 。上图对它作了说明,它也得名于此。

8. 如何使一个类不可变?

我认为这是一个相当困难的问题。您需要对类进行多次修改,以实现不可变性:在此我向大家推荐一个架构学习交流裙。交流学习裙号:687810532,里面会分享一些资深架构师录制的视频录像

<pre class="hljs scala" style="padding: 0.5em; font-family: Menlo, Monaco, Consolas, &quot;Courier New&quot;, monospace; color: rgb(68, 68, 68); border-radius: 4px; display: block; margin: 0px 0px 0.75em; font-size: 14px; line-height: 1.5em; word-break: break-all; word-wrap: break-word; white-space: pre; background-color: rgb(246, 246, 246); border: none; overflow-x: auto;">final
private 
setter 
final 
getter 
</pre>

9. 什么是单例模式?

单例模式是指一个类仅允许创建其自身的一个实例,并提供对该实例的访问权限。它包含静态变量,可以容纳其自身的唯一和私有实例。它被应用于这种场景——用户希望类的实例被约束为一个对象。在需要单个对象来协调整个系统时,它会很有帮助。

10. 什么是依赖注入?

这是你必须知道的首要问题, 无论你是使用 Java EE 还是 Spring 框架。你可以看看我的文章,其中进一步地解释了这一点: 什么是依赖注入?

总结

在本文中,我们讨论了最常见的十个 Java 面试题 ——在我看来这是根据我的经验总结出的时下最重要的问题。如果你了解这些问题,我相信你能在面试中获得很大的优势。

推荐阅读更多精彩内容

  • (一)Java部分 1、列举出JAVA中6个比较常用的包【天威诚信面试题】 【参考答案】 java.lang;ja...
    独云阅读 4,775评论 0 62
  • 随着生活水平的提高,代步工具也越来越来,古代是由生口,马牛做坐骑,发展到现在的使用动力就可能的,由地上发展到天上,...
    AOAOAO姐阅读 113评论 0 0
  • 堆和栈最明显的区别是: 堆(Heap):队列优先,先进先出(FIFO—first in first out); 栈...
    正经三分阅读 5,245评论 0 0
  • 我们坐在饭馆里等着上菜的时候,看见鱼缸里的那条鱼。 中午。 阴天。 饭馆里人很多,我们坐在靠窗的位置上。玻璃鱼缸,...
    唐和宋阅读 298评论 0 0
  • PHP 脚本在服务器上执行,然后向浏览器发送回纯 HTML 结果。 基础 易PHP 语法 易PHP 脚本可放置于文...
    Crampsr阅读 92评论 0 0