在我的先前的帖子中,我讨论了一些重要的Java SE 8面试问题和答案。在这篇帖子中,我们将讨论一些更多的Java SE 8面试问题和答案。在阅读本文之前,请查阅我的先前的帖子:“Java SE 8面试问题(第1部分)”。
Java SE 8面试问题
- 什么是Java SE 8中的内部迭代?
- 外部迭代和内部迭代之间的区别?
- 外部迭代的主要缺点是什么?
- 相对于外部迭代,内部迭代的主要优势是什么?
- 内部迭代相对于外部迭代的主要缺点是什么?
- 外部迭代相对于内部迭代的主要优势是什么?
- 何时需要使用内部迭代?何时需要使用外部迭代?
- Java 8流API的中间操作和终端操作之间有什么区别?
- 在Java接口中是否可以提供方法实现?如果可能,我们如何提供它们?
- 什么是默认方法?为什么我们需要Java 8接口中的默认方法?
- 什么是静态方法?为什么我们需要Java 8接口中的静态方法?
- 功能性编程与面向对象编程的区别?
- 解释旧版Java日期API的问题?Java 8日期和时间API相对于旧日期API和Joda Time API的优势是什么?
- 为什么我们需要Java SE 8中的新日期和时间API?解释Java SE 8日期和时间API如何解决旧版Java日期API的问题?
- Java的旧日期API和Java 8的日期和时间API之间的区别是什么?
- 什么是多继承?Java 8如何支持多继承?
- 接口中由于默认方法而导致的“菱形问题”是什么?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