30个最常见的Java8面试题及答案整理

Java面试 潘老师 2年前 (2022-02-09) 2470 ℃ (0) 扫码查看



在本篇文章中,我们提供了最重要最常见的 Java 8 面试问题及其答案整理,当前还包含代码示例和说明:

本文中列出的所有重要问题都特定于 Java 8。随着新版本的推出,Java 已经(随着时间的推移)发生了很大的变化。对于每个版本,都会有一些新增功能,而现在企业中比较主流的仍然是Java8。本文将介绍相关重要的面试知识点。

这些是非常常见的问题,在任何需要高级技能的 Java 面试中都会问到这些问题。也是一些大厂非常喜欢问的问题。本文将非常适合 Java 开发人员以及 Java 测试人员/自动化测试人员或任何在同一领域追求更高薪水的人。

最常见的 Java 8 面试题及答案

面试题1: 列​​出 Java 8 中引入的新特性?

答: Java 8 中引入的新特性如下:

  • Lambda 表达式:Lambda 允许把函数作为一个方法的参数(函数作为参数传递到方法中)。
  • 方法引用:方法引用提供了非常有用的语法,可以直接引用已有Java类或对象(实例)的方法或构造器。与lambda联合使用,方法引用可以使语言的构造更紧凑简洁,减少默认方法: 默认方法就是一个在接口里面有了一个实现的方法。
  • 新工具:新的编译工具,如:Nashorn引擎 jjs、 类依赖分析器jdeps。
  • Optional 类: Optional 类已经成为 Java 8 类库的一部分,用来解决空指针异常。
  • Nashorn, JavaScript 引擎: Java 8提供了一个新的Nashorn javascript引擎,它允许我们在JVM上运行特定的javascript应用。
  • Stream API:新添加的Stream API(java.util.stream) 把真正的函数式编程风格引入到Java中。
  • Date Time API: 加强对日期与时间的处理。

面试题2: 什么是FunctionalInterface ?

答:FunctionalInterface也称为“函数式接口”, 是只有一个抽象方法的接口。这些接口的实现是使用 Lambda 表达式提供的,这意味着要使用 Lambda 表达式,需要创建一个新的函数式接口,或者可以使用Java 8 的预定义函数式接口。

用于创建新FunctionalInterface 的注解是@FunctionalInterface

JDK中的函数式接口举例如下:

  • java.lang.Runnable,
  • java.awt.event.ActionListener,
  • java.util.Comparator,
  • java.util.concurrent.Callable
  • java.util.function包下的接口,如Consumer、Predicate、Supplier等

面试题3: 什么是Optional 类?

答:Optional 类是 Java 8 中引入的一个特殊包装类,用于避免 NullPointerException。这个类存在于 java.util 包下。当我们未能执行 Null 检查时会发生 NullPointerException。

面试题4: 默认方法是什么?

答:简单说,默认方法就是接口可以有实现方法,而且不需要实现类去实现其方法。我们只需在方法名前面加个 default 关键字即可实现默认方法。

语法:

public interface questions{
        default void print() {
                System.out.println("www.panziye.com");
        }
}

面试题5: Lambda表达式的主要特点是什么?

  • 定义为 Lambda 表达式的方法可以作为参数传递给另一个方法。
  • 方法可以独立存在而不属于某个类。
  • 无需声明参数类型,因为编译器可以从参数值中获取类型。
  • 使用多个参数时可以使用括号,但使用单个参数时不需要括号。
  • 如果表达式主体只有一条语句,则无需包含花括号。

面试题6:旧版本的日期和时间有什么缺点?

答: 下面列出的是旧日版本期和时间的缺点:

  • java.util.Date 是可变的并且不是线程安全的,而新的 Java 8 日期和时间 API 是线程安全的。
  • Java 8 日期和时间 API 符合 ISO 标准,而旧的日期和时间设计不佳。
  • 它为日期引入了几个 API 类,如 LocalDate、LocalTime、LocalDateTime 等。
  • 谈到两者之间的性能,Java 8 比旧的日期和时间机制运行得更快。

面试题7: Collection API 和 Stream API 有什么区别?

答: Stream API 和 Collection API 的区别可以从下表中理解:
30个最常见的Java8面试题及答案整理

面试题8:如何创建函数式接口?

答:可以用注解@FunctionalInterface自定义一个函数式接口。一旦定义了功能接口,就只能有一个抽象方法。由于您只有一个抽象方法,因此您可以编写多个静态方法和默认方法。

下面是为两个数字相乘而编写的 FunctionalInterface 的编程示例。

@FunctionalInterface
interface FuncInterface {
 
    public int multiply(int a, int b);
}
public class Java8 {
 
   public static void main(String args[]) {
        FuncInterface Total = (a, b) -> a * b;
        System.out.println("Result: "+Total.multiply(30, 60));
    }
}

面试题9: 什么是 SAM 接口?

答: Java 8 引入了 FunctionalInterface 的概念,它只能有一个抽象方法。由于这些接口仅指定一种抽象方法,因此有时将它们称为 SAM 接口。SAM 代表“单一抽象方法”。

面试题10:什么是方法引用?

答:在 Java 8 中,引入了一个新特性,称为方法引用。这是用来指函数式接口的方法。在引用方法时,它可以用来替换 Lambda 表达式。

//例如:如果使用 Lambda 表达式:

number -> System.out.println(number )
//那么相应的方法引用如下:
System.out::println

其中::是区分类名和方法名的运算符。

面试题11:解释以下代码含义

String:: Valueof表达式

答:是对String类的ValueOf 方法的静态方法引用。System.out::println 是对 System 类的 out 对象的 println 方法的静态方法引用。它返回所传递参数的相应字符串表示形式。参数可以是字符、整数、布尔值等。

面试题12:什么是Stream API?为什么我们需要 Stream API?

答: Stream API 是 Java 8 中添加的新功能。它是一个特殊的类,用于处理来自 Collection 等数据源的对象。

我们需要 Stream API,因为:

  • 它支持聚合操作,使处理变得简单。
  • 它支持函数式编程。
  • 它的处理速度更快。因此,它易于获得更好的性能。
  • 它允许并行操作。

面试题13: Java 8 中的 limit() 方法的目的是什么?

答: Stream.limit() 方法指定元素的限制。您在 limit(X) 中指定的大小,它将返回大小为“X”的 Stream。它是 java.util.stream.Stream 的一个方法

面试题14:limit和skip有什么区别?

答: limit() 方法用于返回指定大小的Stream。例如, 如果您提到了 limit(5),那么输出元素的数量将为 5。让我们考虑以下示例。此处的输出返回六个元素,因为限制设置为“6”。

import java.util.stream.Stream;
 
public class Java8 {
     
    public static void main(String[] args) {
        Stream.of(0,1,2,3,4,5,6,7,8)
        .limit(6)         
        /*limit is set to 6, hence it will print the 
        numbers starting from 0 to 5 
        */
        .forEach(num->System.out.print("\n"+num));
    }
}
//输出0 1 2 3 4 5

而 skip() 方法用于跳过元素。让我们考虑以下示例。在输出中,元素是 6、7、8,这意味着它已经跳过元素直到第 6 个索引(从 1 开始)。

import java.util.stream.Stream;
 
public class Java8 {
     
    public static void main(String[] args) {
        Stream.of(0,1,2,3,4,5,6,7,8)
        .skip(6)
        /*
         It will skip till 6th index. Hence 7th, 8th and 9th
         index elements will be printed
         */
        .forEach(num->System.out.print("\n"+num));
    }
}
//输出6 7 8

面试题15:你将如何使用 Java 8 日期和时间 API 获取当前日期和时间?

答:下面的程序是借助 Java 8 中引入的新 API 编写的。我们使用了 LocalDate、LocalTime 和 LocalDateTime API 来获取当前日期和时间。

在第一个和第二个打印语句中,我们从系统时钟中检索了当前日期和时间,并将时区设置为默认值。在第三个打印语句中,我们使用了 LocalDateTime API,它将打印日期和时间。

class Java8 {
    public static void main(String[] args) {
        System.out.println("Current Local Date: " + java.time.LocalDate.now());
        //Used LocalDate API to get the date
        System.out.println("Current Local Time: " + java.time.LocalTime.now());
        //Used LocalTime API to get the time
        System.out.println("Current Local Date and Time: " + java.time.LocalDateTime.now());
        //Used LocalDateTime API to get both date and time
    }
}

面试题16: 在 Java 8 中使用 forEach 编写一个程序来打印 5 个随机数?

答:下面的程序在 Java 8 中借助 forEach 生成 5 个随机数。您可以根据要生成的随机数的数量将限制变量设置为任意数字。

import java.util.Random;
 
class Java8 {
    public static void main(String[] args) {
 
        Random random = new Random();
        random.ints().limit(5).forEach(System.out::println);
        /* limit is set to 5 which means only 5 numbers will be printed
        with the help of terminal operation forEach
        */
 
    }
}

面试题17:编写一个程序,在 Java 8 中使用 forEach 按排序顺序打印 5 个随机数?

答:下面的程序在 Java 8 中借助 forEach 生成 5 个随机数。您可以根据要生成的随机数的数量将限制变量设置为任意数字。您唯一需要在此处添加的是 sorted() 方法。

import java.util.Random;
 
class Java8 {
 
    public static void main(String[] args) {
 
        Random random = new Random();
        random.ints().limit(5).sorted().forEach(System.out::println);
        /* sorted() method is used to sort the output after
         terminal operation forEach
         */
 
    }
}

面试题18: 编写一个 Java 8 程序来获取list集合中所有数字的总和?

答:在这个程序中,我们使用 ArrayList 来存储元素。然后,在 sum() 方法的帮助下,我们计算了 ArrayList 中存在的所有元素的总和。然后将其转换为 Stream 并在 mapToInt() 和 sum() 方法的帮助下添加每个元素。

import java.util.*;
 
class Java8 {
    public static void main(String[] args) {
        ArrayList<Integer> list = new ArrayList<Integer>();
 
        list.add(10);
        list.add(20);
        list.add(30);
        list.add(40);
        list.add(50);
        // Added the numbers into Arraylist
        System.out.println(sum(list));
    }
 
    public static int sum(ArrayList<Integer> list) {
        return list.stream().mapToInt(i -> i).sum();
        // Found the total using sum() method after 
        // converting it into Stream
    }
}

面试题19: 编写一个 Java 8 程序对数字集合进行平方,然后过滤掉大于 100 的数字,然后求剩余数字的平均值?

答:在这个程序中,我们采用了一个整数数组并将它们存储在一个列表中。然后在 mapToInt() 的帮助下,我们对元素进行平方并过滤掉大于 100 的数字。最后,计算剩余数字(大于 100)的平均值。

import java.util.Arrays;
import java.util.List;
import java.util.OptionalDouble;
 
public class Java8 {
    public static void main(String[] args) {
        Integer[] arr = new Integer[] { 100, 100, 9, 8, 200 };
        List<Integer> list = Arrays.asList(arr);
        // Stored the array as list
        OptionalDouble avg = list.stream().mapToInt(n -> n * n).filter(n -> n > 100).average();
         
        /* Converted it into Stream and filtered out the numbers
            which are greater than 100. Finally calculated the average 
        */
         
        if (avg.isPresent())
            System.out.println(avg.getAsDouble());
    }
}

面试题20: Stream 的 findFirst() 和 findAny() 有什么区别?

答:顾名思义,findFirst() 方法用于从流中查找第一个元素,而 findAny() 方法用于从流中查找任何元素。findFirst() 本质上是预定论,而 findAny() 是非确定性的。在编程中,确定性意味着输出基于系统的输入或初始状态。

面试题21: Iterator 和 Spliterator 有什么区别?

答:以下是迭代器和拆分器之间的区别。
30个最常见的Java8面试题及答案整理

面试题22:什么是Consumer 功能接口?

答:Consumer 函数接口也是单参数接口(如 Predicate 和 Function)。它属于 java.util.function.Consumer。这不会返回任何值。
在下面的程序中,我们使用了 accept 方法来检索 String 对象的值。

import java.util.function.Consumer;
 
public class Java8 {
 
    public static void main(String[] args) 
 
        Consumer<String> str = str1 -> System.out.println(str1);
        str.accept("Saket");
         
        /* We have used accept() method to get the 
         value of the String Object
         */
    }
}

面试题23:什么是Supplier功能接口?

答:Supplier功能接口不接受输入参数。它属于 java.util.function.Supplier。这将使用 get 方法返回值。在下面的程序中,我们使用了 get 方法来检索 String 对象的值。

import java.util.function.Supplier;
 
public class Java8 {
 
    public static void main(String[] args) {
 
        Supplier<String> str = () -> "Saket";
        System.out.println(str.get());
         
        /* We have used get() method to retrieve the 
           value of String object str.
         */
    }
}

面试题24: Java 8 中的 Nashorn 是什么?

答: Java 8 中的 Nashorn 是一个基于 Java 的引擎,用于执行和评估 JavaScript 代码。

面试题25: Map 和 flatMap 流操作有什么区别?

答: Map Stream 操作为每个输入值提供一个输出值,而 flatMap Stream 操作为每个输入值提供零个或多个输出值。

面试题26: Java 8 中的 MetaSpace 是什么?

答:在 Java 8 中,引入了一个新特性来存储类。存储在 Java 8 中的所有类的区域称为 MetaSpace。MetaSpace 已取代 PermGen。

在 Java 7 之前,Java 虚拟机使用 PermGen 来存储类。由于 MetaSpace 是动态的,因为它可以动态增长并且没有任何大小限制,Java 8 用 MetaSpace 取代了 PermGen。

面试题26: 什么是 JJS?

答: JJS 是一个命令行工具,用于在控制台执行 JavaScript 代码。在 Java 8 中,JJS 是新的可执行文件,它是一个 JavaScript 引擎。

面试题27:解释 Java 8 中的 StringJoiner 类?我们如何使用 StringJoiner 类实现连接多个字符串?

答:在 Java 8 中,包 java.util 中引入了一个新类,称为 StringJoiner。通过这个类,我们可以连接多个由分隔符分隔的字符串,并为它们提供前缀和后缀。

在下面的程序中,我们将学习如何使用 StringJoiner 类连接多个字符串。在这里,我们将“,”作为两个不同字符串之间的分隔符。然后我们在 add() 方法的帮助下添加了五个不同的字符串。最后,打印 String Joiner。

import java.util.StringJoiner;
 
public class Java8 {
    public static void main(String[] args) {
 
        StringJoiner stj = new StringJoiner(",");
        // Separated the elements with a comma in between.
         
        stj.add("Saket");
        stj.add("John");
        stj.add("Franklin");
        stj.add("Ricky");
        stj.add("Trevor");
         
        // Added elements into StringJoiner “stj”
         
        System.out.println(stj);
    }
}

面试题28:编写一个 Java 8 程序来删除集合中的重复元素?

答:在这个程序中,我们将元素存储到一个数组中,并将它们转换为一个列表。此后,我们使用了流并在“Collectors.toSet()”方法的帮助下将其收集到“Set”。

import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
 
public class Java8 {
    public static void main(String[] args) {
        Integer[] arr1 = new Integer[] { 1, 9, 8, 7, 7, 8, 9 };
        List<Integer> listdup = Arrays.asList(arr1);
         
        // Converted the Array of type Integer into List
 
        Set<Integer> setNoDups = listdup.stream().collect(Collectors.toSet());
         
        // Converted the List into Stream and collected it to “Set”
        // Set won't allow any duplicates
         
        setNoDups.forEach((i) -> System.out.print(" " + i));
         
    }
}

面试题29: 编写一个 Java 8 程序来连接两个 Stream?

答:在这个程序中,我们从两个已经创建的列表中创建了两个 Stream,然后使用 concat() 方法将它们连接起来,其中两个列表作为参数传递。最后,打印连接流的元素。

import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;
 
public class Java8 {
    public static void main(String[] args) {
 
        List<String> list1 = Arrays.asList("Java", "8");
        List<String> list2 = Arrays.asList("explained", "through", "programs");
 
        Stream<String> concatStream = Stream.concat(list1.stream(), list2.stream());
         
        // Concatenated the list1 and list2 by converting them into Stream
 
        concatStream.forEach(str -> System.out.print(str + " "));
         
        // Printed the Concatenated Stream
         
    }
}

面试题30: 编写一个 Java 8 程序来查找长度大于 5 的列表中的字符串数?

答:在这个程序中,使用 add() 方法将四个字符串添加到列表中,然后借助 Stream 和 Lambda 表达式,我们统计了长度大于 5 的字符串。

import java.util.ArrayList;
import java.util.List;
 
public class Java8 {
    public static void main(String[] args) {
        List<String> list = new ArrayList<String>();
        list.add("Saket");
        list.add("Saurav");
        list.add("Softwaretestinghelp");
        list.add("Steve");
         
        // Added elements into the List
 
        long count = list.stream().filter(str -> str.length() > 5).count();
         
        /* Converted the list into Stream and filtering out
           the Strings whose length more than 5
           and counted the length
           */
        System.out.println("We have " + count + " strings with length greater than 5");
 
    }
}

总结

以上就是30个最常见的Java8面试题及答案整理,你学会了吗?


版权声明:本站文章,如无说明,均为本站原创,转载请注明文章来源。如有侵权,请联系博主删除。
本文链接:https://www.panziye.com/javainterview/4208.html
喜欢 (1)
请潘老师喝杯Coffee吧!】
分享 (0)
用户头像
发表我的评论
取消评论
表情 贴图 签到 代码

Hi,您需要填写昵称和邮箱!

  • 昵称【必填】
  • 邮箱【必填】
  • 网址【可选】