CodeGym /Java 博客 /随机的 /探索 Java 开发人员职位面试中的问题和答案。第 8 部分
John Squirrels
第 41 级
San Francisco

探索 Java 开发人员职位面试中的问题和答案。第 8 部分

已在 随机的 群组中发布
实践还是理论?更重要的是什么呢?很多人自然会说,练习更重要。就像,练习直到太阳落山,你就会快乐。我敢于不同意这一点。 探索 Java 开发人员职位面试中的问题和答案。 第 8 - 1 部分在面试过程中,没有人会知道你练习时有多酷。相反,您将被要求展示您的理论能力。直到后来,当你通过了所有的面试层并被分配到一个项目时,你才会应用你的实践技能。你可能会反对,说有时候他们给你一个测试任务,所以还是需要练习。我并不反对,但我的观点是,有时会这样,但你总是需要在面试中展示理论知识。你感觉有什么不同吗?所有这些都意味着你必须有扎实的理论基础,这就是我们今天要继续建立的。更具体地说,我们将继续关注采访中经常提出的问题。

71. 如果我们不重写 Enum 的 toString() 方法会发生什么?

假设我们有以下枚举
public enum Role {
   STUDENT,
   TEACHER,
   DIRECTOR,
   SECURITY_GUARD;
}
让我们通过调用其toString()方法在控制台上显示STUDENT字段:
System.out.println(Role.STUDENT.toString());
结果,我们得到以下控制台输出:
学生
因此,我们看到对于 enum toString()的默认实现返回常量本身的名称。

72. 可以在 Enum 中声明构造函数吗?

是的当然。构造函数设置enum内部字段的值。例如,让我们向前面的枚举添加两个字段(ageFromageTo)来指示每个角色的年龄范围:
public enum Role {
   STUDENT(5,18),
   TEACHER(20,60),
   DIRECTOR(40,70),
   SECURITY_GUARD(18,50);

   int ageFrom;
   int ageTo;

   Role(int ageFrom, int ageTo) {
       this.ageFrom = ageFrom;
       this.ageTo = ageTo;
   }
}

73.==和equals()有什么区别?

这是未来的 Java 开发人员最常见的面试问题之一。首先,在比较简单值(intchardouble ...)时,我们使用==,因为这些变量包含可以直接比较的具体值。更重要的是,原始变量不是成熟的对象——它们不继承Object类,也没有equals()方法。如果我们讨论比较引用对象的变量,那么我们需要知道==仅比较引用的值,即它们是否引用同一个对象。即使一个对象中的所有数据与另一个对象中的所有数据相同,使用==进行比较也会产生负结果 ( false ),因为它们是单独的对象。正如您可能已经猜到的,我们使用equals()方法来比较引用变量。这是Object类的标准方法之一,对于对象的全面比较是必要的。但我需要立即指出,为了使此方法正常工作,必须重写它以准确指示应如何比较对象。如果您不重写该方法,那么您将获得默认实现,它使用==比较对象。在 IntelliJ IDEA 中,您可以使用 IDEA 快捷键自动覆盖它:Alt+Insert。在出现的窗口中,选择equals()hashCode()。然后选择需要涉及的字段。瞧!这些方法是自动实现的。下面的示例展示了自动生成的equals方法如何查找具有两个字段( intageString name )的最简单的Cat类:
@Override
public boolean equals(final Object o) {
   if (this == o) return true;
   if (o == null || this.getClass() != o.getClass()) return false;
   final Cat cat = (Cat) o;
   return this.age == cat.age &&
           Objects.equals(this.name, cat.name);
}
当谈到enum时, ==equals()之间没有实际区别。 探索 Java 开发人员职位面试中的问题和答案。 第 8 - 2 部分毕竟,枚举存储常量,即使我们使用==比较相同的值,我们也会得到true,因为比较的引用将始终指向相同的对象。使用equals()也能得到正确的结果。如果您进入Enum的equals方法主体,您将看到Enum类具有以下实现: 在内部我们可以看到一个很好的旧引用比较!总而言之,对于enum,我们可以使用==equals()进行正确比较。 探索 Java 开发人员职位面试中的问题和答案。 第 8 - 3 部分探索 Java 开发人员职位面试中的问题和答案。 第 8 - 4 部分

74. Enum 的 ordinal() 方法有什么作用?

当我们对枚举字段调用int ordinal()方法时,我们会在枚举值列表中获取该字段从零开始的索引。让我们在Role枚举中的字段上调用此方法,我们之前考虑过:
System.out.println(Role.DIRECTOR.ordinal());
相应地,控制台显示:
2

75. Enum 可以与 Java 中的 TreeSet 或 TreeMap 一起使用吗?

我们可以在TreeSetTreeMap中使用枚举类型。我们可以这样写:
TreeSet<Role> treeSet = new TreeSet<>();
treeSet.add(Role.SECURITY_GUARD);
treeSet.add(Role.DIRECTOR);
treeSet.add(Role.TEACHER);
treeSet.add(Role.STUDENT);
treeSet.forEach(System.out::println);
并且控制台会显示:
学生 教师 主任 SECURITY_GUARD
我们得到了输出,但不是按字母顺序排列的。要点是,如果我们使用枚举字段作为TreeSet值或TreeMap键,那么字段将按其自然顺序(按照它们在 enum 中指定的顺序排序。了解它的工作原理有助于我们编写更好的代码。

76. Enum 的ordinal() 和compareTo() 方法有何关系?

如前所述,ordinal()返回枚举字段列表中字段的索引。另外,在我们考虑上一个问题时,您看到当枚举字段放入 TreeSet 这是一个排序集)时,它们采用在 enum 中声明的顺序。正如我们所知,TreeSetTreeMap通过调用其Comparable接口的compareTo()方法对项目进行排序。这告诉我们Enum类实现了Comparable接口,这意味着它实现了compareTo()方法,该方法内部使用ordinal()方法来确定排序顺序。进入Enum类,我们可以确认我们的假设: 这是方法本身的主体: 这里没有调用ordinal ()方法。相反,使用序数变量,它是枚举中元素的索引号。ordinal ()方法本身 只不过是序数变量的 getter。 探索 Java 开发人员职位面试中的问题和答案。 第 8 - 5 部分探索 Java 开发人员职位面试中的问题和答案。 第 8 - 6 部分探索 Java 开发人员职位面试中的问题和答案。 第 8 - 7 部分

77. 编写一个枚举示例

在上面讨论的问题中,我已经给出了enum的示例。我认为没有理由在这里重复代码。例如,请参阅有关枚举中的构造函数的问题 72。

78. Enum 可以用在 switch case 中吗?

可以而且应该如此!根据我的经验,我会注意到枚举最常见的用途之一是逻辑结构,例如switch语句。在这种情况下,您可以提供所有可能的情况——一旦您为每个枚举字段编写了逻辑,您甚至不需要默认子句!毕竟,如果您使用String或数字值(例如int ),您可能会收到意外的值,但对于 enum 来说这是不可能。对于上面的示例, switch语句如下所示:
public void doSomething(Role role) {
   switch (role) {
       case STUDENT:
           // some logic for STUDENT
           break;
       case TEACHER:
           // some logic for TEACHER
           break;
       case DIRECTOR:
           // some logic for DIRECTOR
           break;
       case SECURITY_GUARD:
           // some logic for SECURITY_GUARD
           break;
   }
}

79. 如何获取 Enum 的所有可能值?

如果您需要获取所有可能的枚举值,可以使用value()方法,该方法按自然顺序(即按照 enum 中指定的顺序返回枚举的所有可能值的数组。例子:
Role[] roles = Role.values();
for (Role role : roles) {
   System.out.println(role);
}
我们将在控制台上看到以下内容:
学生 教师 主任 SECURITY_GUARD

流媒体接口

80.Java中的Stream是什么?

Java Stream API是一种相对较新的与数据流交互的方式,使我们能够更方便、更紧凑地处理大数据,以及在一定数量的流中并行处理数据,从而有可能提高性能。

81. 命名交易的主要属性

这里的主题是 Stream API,但问题是关于事务的。嗯...首先,我们来了解一下什么是交易。事务是对数据库一组顺序操作。它代表一个逻辑工作单元。事务可以独立于其他并发事务完全且成功地执行,从而保持数据完整性,或者根本不执行,在这种情况下它没有任何影响。事务有四个主要属性,借助首字母缩略词ACID ,我们可以轻松记住它们。让我们看看这个缩写词的每个字母的含义: A代表Atomicity。此属性保证系统中没有事务被部分提交。要么它的所有子操作都将被执行,要么它们都不被执行(全部或全无)。 С代表一致性。此属性保证每个成功的事务只会提交有效的结果。换句话说,这是一个保证,如果交易成功,那么系统针对特定数据的所有规则都将得到遵守。如果交易不成功,则不会执行,系统数据将返回到之前的状态。 I代表隔离。此属性意味着当执行事务时,并发事务不得影响其结果。此属性是资源密集型的,因此通常会部分实现,从而允许解决特定隔离问题的特定隔离级别。我们将在下一个问题中更详细地讨论这一点。 D代表耐用性。此属性保证如果用户收到交易完成的确认,则他或她可以确定更改不会由于某些故障而被取消。也就是说,如果您已经收到交易成功完成的确认信息,则可以确定某些操作系统故障不会对您的数据产生任何影响。

82. 事务隔离级别是什么?

正如我之前所说,当涉及到 ACID 属性时,确保隔离是一个资源密集型过程。因此,该属性已部分实现。隔离有不同的级别:级别越高,对性能的影响越严重。在我们进入事务隔离级别之前,我们需要考虑由于事务隔离不足而出现的各种问题
  • 幻读:当同一请求在单个事务中多次调用时,由于另一个事务的插入而产生不同的结果;

  • 不可重复读取:当同一请求在单个事务中多次调用时,由于另一个事务的更改(更新)和删除而产生不同的数据;

  • 脏读:读取事务已添加或修改并随后回滚的尚未提交的数据;

  • 丢失更新:当一个数据块被不同的事务同时更改时,除了最后一个更改之外的所有更改都会丢失(类似于多线程中的竞争条件)。

事实上,事务隔离级别的特征在于它们可以防止哪些隔离问题。请考虑下表的隔离级别及其防止的问题:
隔离级别 幻读 不可重复读取 脏读 丢失更新
可串行化 + + + +
可重复读取 - + + +
已提交读 - - + +
未提交的阅读 - - - +
没有任何 - - - -
并且不要忘记另一面:隔离级别越高,处理事务所需的时间就越长(假设多个事务并行执行)。

83.Statement和PreparedStatement有什么区别?

这里我们突然改变了过渡到JDBC的功能。无论如何,我们首先要弄清楚声明的含义。它是一个用于形成 SQL 查询的对象。 JDBC使用三种类型:StatementPreparedStatementCallableStatement。我们今天不考虑CallableStatement相反,我们讨论的是StatementPreparedStatement之间的区别。
  1. 语句用于执行简单的 SQL 查询,无需运行时输入参数。PrepareStatement可以在运行时接受输入参数。

  2. 要为PreparedStatement设置参数,输入参数在请求中被写为问号,因此可以使用各种setter将它们替换为某个值,例如setDouble()setFloat()setInt()setTime() ...意味着您不会在请求中插入错误类型的数据。

  3. PreparedStatement是预编译的并使用缓存,因此它的执行速度比由Statement对象发出的请求稍快。因此,经常执行的 SQL 语句被创建为PreparedStatement对象,以提高性能。

  4. Statement很容易受到 SQL 注入的攻击,但PreparedStatement 可以防止它们。

至此,我们就到此为止了!
评论
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION