Java SE 8面试问题与答案(第二部分)

在我的先前的帖子中,我讨论了一些重要的Java SE 8面试问题和答案。在这篇帖子中,我们将讨论一些更多的Java SE 8面试问题和答案。在阅读本文之前,请查阅我的先前的帖子:“Java SE 8面试问题(第1部分)”。

Java SE 8面试问题

  1. 什么是Java SE 8中的内部迭代?
  2. 外部迭代和内部迭代之间的区别?
  3. 外部迭代的主要缺点是什么?
  4. 相对于外部迭代,内部迭代的主要优势是什么?
  5. 内部迭代相对于外部迭代的主要缺点是什么?
  6. 外部迭代相对于内部迭代的主要优势是什么?
  7. 何时需要使用内部迭代?何时需要使用外部迭代?
  8. Java 8流API的中间操作和终端操作之间有什么区别?
  9. 在Java接口中是否可以提供方法实现?如果可能,我们如何提供它们?
  10. 什么是默认方法?为什么我们需要Java 8接口中的默认方法?
  11. 什么是静态方法?为什么我们需要Java 8接口中的静态方法?
  12. 功能性编程与面向对象编程的区别?
  13. 解释旧版Java日期API的问题?Java 8日期和时间API相对于旧日期API和Joda Time API的优势是什么?
  14. 为什么我们需要Java SE 8中的新日期和时间API?解释Java SE 8日期和时间API如何解决旧版Java日期API的问题?
  15. Java的旧日期API和Java 8的日期和时间API之间的区别是什么?
  16. 什么是多继承?Java 8如何支持多继承?
  17. 接口中由于默认方法而导致的“菱形问题”是什么?Java 8如何解决这个问题?

Java SE 8面试问题与回答

什么是Java SE 8中的内部迭代?

在Java 8之前,我们没有内部迭代的概念。Java 8引入了一项新功能,称为“内部迭代”。在Java 8之前,Java语言只有外部迭代来迭代聚合对象的元素,如集合、数组等。内部迭代意味着“通过Java API在内部逐个迭代聚合对象的元素”。与Java应用程序在外部执行迭代不同,我们要求Java API在内部执行此任务。

外部迭代和内部迭代之间有哪些区别?

S.No. External Iteration Internal Iteration
1. Available before Java 8 too. It is introduced in Java SE 8
2. Iterating an Aggregated Object elements externally. Iterating an Aggregated Object elements internally (background).
3. Iterate elements by using for-each loop and Iterators like Enumeration, Iterator, ListIterator. Iterate elements by using Java API like “forEach” method.
4. Iterating elements in Sequential and In-Order only. Not required to iterate elements in Sequential order.
5. It follows OOP approach that is Imperative Style. It follows Functional Programming approach that is Declarative Style.
6. It does NOT separate responsibilities properly that is, it defines both “What is to be done” and “How it is to be done”. It defines only “What is to be done”. No need to worry about “How it is to be done”. Java API takes care about “How to do”.
7. Less Readable Code. More Readable code.

外部迭代的主要缺点是什么?

外部迭代具有以下缺点:

  • 我们需要以命令式风格编写代码。
  • 责任之间没有明确的分离。在“要做什么”和“如何做”代码之间存在紧密耦合。
  • 代码可读性较差。
  • 代码冗长且啰嗦。
  • 我们必须按顺序迭代元素。
  • 不支持良好的并发和并行处理。

内部迭代相对于外部迭代的主要优势是什么?

与外部迭代相比,内部迭代具有以下优势:

  • 由于遵循函数式编程风格,我们可以编写声明式代码。
  • 更易读且简洁的代码。
  • 避免编写冗长和样板式的代码。
  • 无需按顺序迭代元素。
  • 它正确地支持并发和并行性。
  • 我们可以编写并行代码来提高应用程序的性能。
  • 明确的责任分离。在“要做什么”和“如何做”的代码之间存在松耦合。
  • 我们只需编写关于“要做什么”的代码,Java API 负责处理“如何做”的代码。

内部迭代相对于外部迭代的主要缺点是什么?

与外部迭代相比,内部迭代有一个主要缺点:

  • 在内部迭代中,由于Java API在内部处理迭代元素,我们对迭代过程没有控制权。

外部迭代相对于内部迭代的主要优势是什么?

与内部迭代相比,外部迭代有一个主要优势:

  • 在外部迭代中,由于Java API不处理迭代元素,我们对迭代过程有更多控制权。

何时需要使用内部迭代?何时需要使用外部迭代?

我们需要了解何时使用内部迭代或外部迭代的情境。

  • 当我们需要更多对迭代过程的控制权时,我们可以使用外部迭代。
  • 当我们不需要更多对迭代过程的控制权时,我们可以使用内部迭代。
  • 当我们需要开发高度并发和并行应用程序时,我们应该使用内部迭代。

Java 8的Stream API中,中间操作和终端操作有什么区别?

S.No. Stream Intermediate Operations Stream Terminal Operations
1. Stream Intermediate operations are not evaluated until we chain it with Stream Terminal Operation. Stream Terminal Operations are evaluated on it’s own. No need other operations help.
2. The output of Intermediate Operations is another Stream. The output of Intermediate Operations is Not a Stream. Something else other than a Stream.
3. Intermediate Operations are evaluated Lazily. Terminal Operations are evaluated Eagerly.
4. We can chain any number of Stream Intermediate Operations. We can NOT chain Stream Terminal Operations.
5. We can use any number of Stream Intermediate Operations per Statement. We can use only one Stream Terminal Operation per Statement.

在Java接口中是否可以提供方法实现?如果可以,我们如何提供这些实现?

在Java 7或更早的版本中,无法在接口中提供方法实现。从Java 8开始,这是可能的。在Java SE 8中,我们可以通过使用以下两个新概念在接口中提供方法实现:

  • 默认方法
  • 静态方法

什么是默认方法?为什么在Java 8接口中需要默认方法?

A Default Method is a method which is implemented in an interface with “default” keyword. It’s new featured introduced in Java SE 8. We need Default Methods because of the following reasons:

  • 它允许我们在接口中提供方法的实现。
  • 向接口添加新功能,而不会破坏实现该接口的类。
  • 提供优雅的向后兼容功能。
  • 便于扩展现有功能。
  • 便于维护现有功能。

什么是静态方法?为什么我们需要 Java 8 接口中的静态方法?

A Static Method is an Utility method or Helper method, which is associated to a class (or interface). It is not associated to any object. We need Static Methods because of the following reasons:

  • 我们可以将特定于接口的辅助或实用方法保留在同一接口中,而不是放在单独的实用程序类中。
  • 我们不需要单独的实用程序类,比如 Collections、Arrays 等来保留实用方法。
  • 责任的清晰分离。这意味着我们不需要一个实用程序类来保存集合 API(如 Collections 等)的所有实用方法。
  • 易于扩展 API。
  • 易于维护 API。

函数式编程和面向对象编程之间的区别?

Functional Programming OOP
Does not exist State Exists State
Uses Immutable data Uses Mutable data
It follows Declarative Programming Model It follows Imperative Programming Model
Stateless Programming Model Stateful Programming Model
Main Fcous on: “What you are doing” Main focus on “How you are doing”
Good for Parallel (Concurrency) Programming Poor for Parallel (Concurrency) Programming
Good for BigData processing and analysis NOT Good for BigData processing and analysis
Supports pure Encapsulation It breaks Encapsulation concept
Functions with No-Side Effects Methods with Side Effects
Functions are first-class citizens Objects are first-class citizens
Primary Manipulation Unit is “Function” Primary Manipulation Unit is Objects(Instances of Classes)
Flow Controls: Function calls, Function Calls with Recursion Flow Controls: Loops, Conditional Statements
It uses “Recursion” concept to iterate Collection Data. It uses “Loop” concept to iterate Collection Data. For example:-For-each loop in Java
Order of execution is less importance. Order of execution is must and very important.
Supports both “Abstraction over Data” and “Abstraction over Behavior”. Supports only “Abstraction over Data”.
We use FP when we have few Things with more operations. We use OOP when we have few Operations with more Things. For example: Things are classes and Operations are Methods in Java.

请注意:有关FP、IP和OOP比较的更多信息,请参阅我之前的帖子:“比较FP、OOP(IP)

解释旧Java日期API的问题?Java 8的日期和时间API相对于旧日期API和Joda Time API有哪些优点?

Java的旧Java日期API指的是Java SE 8之前可用的日期API,即Date、Calendar、SimpleDateFormat等。Java的旧日期API与Java 8的日期和时间API以及Joda Time API相比存在以下问题或缺点。

  • 大多数API已被弃用。
  • 可读性较差。
  • java.util.Date可变且不是线程安全的。
  • java.text.SimpleDateFormat不是线程安全的。
  • 性能较差。

Java SE 8的日期和时间API相对于Java的旧日期API具有以下优点。

  • 非常易于使用。
  • 人类可读的语法,更易读。
  • 所有API都是线程安全的。
  • 性能更好。

为什么我们需要 Java SE 8 中的新日期和时间 API?解释一下 Java SE 8 日期和时间 API 如何解决旧的 Java 日期 API 的问题。

我们需要 Java 8 的日期和时间 API 来开发高性能、线程安全和高可伸缩性的 Java 应用程序。Java 8 的日期和时间 API 通过遵循不可变性和线程安全原则解决了所有 Java 旧日期 API 的问题。

Java 的旧日期 API 与 Java 8 的日期和时间 API 有哪些区别?

Java 的旧日期 API 与 Java 8 的日期和时间 API 之间的区别:

S.No. Java’s OLD Java Date API Java 8’s Date and Time API
1. Available before Java 8 too. It is introduced in Java SE 8
2. Not Thread Safe. Thread Safe.
3. Mutable API. Immutable API.
4. Less Performance. Better Performance.
5. Less Readability. More Readability.
6. It’s not recommended to use as its deprecated. It’s always recommended to use.
7. Not Extendable. Easy to Extend.
8. It defines months values from 0 to 11, that is January = 0. It defines months values from 1 to 12, that is January = 1.
9. It’s an old API. It’s a new API.

什么是多重继承?Java 8如何支持多重继承?

多重继承意味着一个类可以从多个父类中继承或扩展特性和特征。在Java 7或更早版本中,不支持多重继承,因为Java遵循“一个类应该只能扩展一个类或抽象类”的规则。然而,通过使用接口,可以实现多重实现继承,因为Java遵循“一个类可以扩展任意数量的接口”的规则。然而,Java 8通过引入新特性:接口中的默认方法,支持“在接口中实现方法”。由于这一特性,Java 8在一定程度上支持多重继承,但有一些限制。

接口中的菱形问题是什么,由于默认方法,Java 8是如何解决这个问题的?

Java 8默认方法在类实现多个接口时可能引发钻石问题。当一个类扩展了具有相同方法实现(默认方法)的多个接口时,就会发生这种情况。示例Java SE 8代码展示了接口默认方法的钻石问题。

interface A {
	default void display() {
		System.out.println("A");
	}
}

interface B extends A {
	default void display() {
		System.out.println("B");
	}
}

interface C extends A {
	default void display() {
		System.out.println("C");
	}
}

class D implements B, C {
}

在上述代码片段中,类D出现编译时错误,显示“从类型C和B继承的具有参数()和()的重复默认方法display()”。这是因为Java编译器会对在类D中使用哪个display()方法感到困惑。类D从接口B和C中都继承了display()方法。为了解决这个问题,Java 8提供了以下解决方案。

class D implements B, C {

	@Override
	public void display() {
		B.super.display();
	}
	
}

使用B.super.display();可以解决这个钻石问题。如果想使用C接口的默认方法,则使用C.super.display();。这就是关于Java 8面试问题的全部内容。在我的后续帖子中,我们将讨论更多关于Java SE 8的面试问题。如果喜欢我的帖子或有任何问题/建议,请留下评论。

Source:
https://www.digitalocean.com/community/tutorials/javase8-interview-questions-part2