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

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

已在 随机的 群组中发布
你好世界!对于任何开发人员来说,永远不要停止成长至关重要。毕竟,如果你停下来,你就有可能失去需求并完全退出就业市场。IT 世界在不断发展和前进——您需要随之前进。但与此同时,您不能总是采用最新技术,以免忘记“经典”(经典软件开发主题)。今天我想继续讨论Java开发者的“经典话题”。 探索 Java 开发人员职位面试中的问题和答案。 第 6 - 1 部分我要指出的是,我的答案并不是最终的答案。它们只是我对正确答案的看法——你可能不同意其中的一些答案。这很好,所以请随时在评论中分享您的意见。您可以在文章末尾找到评论前面部分的链接。 探索 Java 开发人员职位面试中的问题和答案。 第 6 - 2 部分

图书馆和标准

52.什么是休眠?JPA 和 Hibernate 有什么区别?

要回答这个问题,我想我们首先需要了解JPA是什么。它是一个描述简单 Java 对象的对象关系映射的规范,并提供用于存储、检索和操作此类对象的 API。也就是说,关系数据库 (DB) 表示为一组互连的表。JPA 是一种广泛采用的标准,它描述了对象如何与关系数据库交互。正如您所看到的,JPA 是抽象的、无形的东西。这就像想法本身、方法一样。 探索 Java 开发人员职位面试中的问题和答案。 第 6 - 3 部分Hibernate 是一个实现 JPA 范例的特定库。换句话说,您可以使用此库通过表示数据库(实体)中的数据的对象来处理关系数据库。据说这个库非常接近 JPA 的理想。这可能就是它流行的原因。正如您可以想象的那样,它的受欢迎程度证明了进一步开发和改进的必要性。此外,广泛的使用源于一个庞大的社区,该社区已经探索了与该工具相关的所有可能和不可能的问题。Hibernate 已经被彻底研究过,而且事实证明它是可靠的。即使是 Spring 中理想的 JPA 实现通常也会在底层使用 Hibernate,这是有充分理由的。

53.什么是级联?在Hibernate中是如何使用的?

正如我之前所说,Hibernate 中的通信是通过称为实体的数据对象进行的。这些实体代表数据库中的特定表,您可能还记得,Java 类可以包含对其他类的引用。这些关系也反映在数据库中。通常,它们要么是外键(对于 OneToOne、OneToMany、ManyToOne 关系),要么是中间表(对于 ManyToMany 关系)。当您的实体引用其他相关实体时,注释会放置在这些引用上方以指示关系类型:@OneToOne、@OneToMany、@ManyToOne、@ManyToMany。您可以在注释的级联属性中指定此关系的级联类型。JPA 有与实体交互的特定方法(持久、保存、合并...)。级联类型用于显示相关数据的行为方式;这些方法用于目标实体。那么级联策略(级联类型)有哪些呢?JPA 标准规定了六种级联类型的使用:
  • PERSIST — 保存操作以级联方式发生(对于save()persist()方法)。换句话说,如果我们保存与其他实体关联的实体,那么这些实体也会保存在数据库中(如果它们尚不存在)

  • MERGE — 更新操作以级联方式发生(对于merge()方法)

  • REMOVE — 删除操作以级联方式发生(remove()方法)

  • ALL — 同时包含三个级联操作 — PERSISTMERGEREMOVE

JPA 具有持久实体的概念 - 与其在数据库中的数据关联并由当前会话(连接)控制的实体。如果您更改它而不将更改保存到数据库,则数据库中实体的数据仍然会更改。
  • DETACH — 相关实体不由会话管理(detach()方法)。也就是说,当相关实体的数据发生更改时,数据库中的数据不会自动更新 - 它们从持久化转换为分离式(即实体不由 JPA 管理)

  • REFRESH — 每次使用数据库中的数据刷新实体(refresh() — 刷新分离的对象)时,其相关实体也会刷新。例如,您以某种方式更改了从数据库中获取的数据,并且您想要恢复原始值。在这种情况下,您会发现此操作很有用。

探索 Java 开发人员职位面试中的问题和答案。 第 6 - 4 部分Hibernate 支持所有这些标准级联操作,并且还引入了三个自己的操作:
  • REPLICATE — 当我们有多个数据源并且希望数据同步时使用(Hibernate 的复制方法)。所有实体都必须有标识符(id),以确保可以毫无问题地创建(保证同一个实体对于不同的数据库不会有不同的id)

  • SAVE_UPDATE — 级联保存/删除(对于 Hibernate 的saveOrUpdate方法)

  • LOCK — 与DETACHED操作相反:将分离的实体转换回持久状态,即当前会话将再次跟踪该实体

如果未选择级联类型,则对该实体的操作不会影响与其关联的其他实体。

54.实体类可以是抽象的吗?

根据JPA规范2.1实体类,“抽象类和具体类都可以是实体。 ”所以,答案是肯定的,抽象类可以是实体,并且可以用@Entity注解来标记。

55.什么是实体管理者?它负责什么?

首先,我想指出EntityManager是JPA的重要组成部分。它用于实体与数据库的交互。一般来说,实体与数据库交互的方法是在实体上调用的(持久、合并、删除、分离)...但我也注意到,这个组件通常不是整个应用程序的单例。它通常是轻量级的,删除一个,然后使用EntityManagerFactory创建一个新的。如果我们与JDBC进行类比,其中EntityManagerFactory类似于DataSource,那么EntityManager类似于Connection。前面我提到持久实体是由当前连接管理的实体。该实体由EntityManager 和 TransactionManager管理,EntityManager 与当前连接密切相关,TransactionManager负责打开/关闭事务。在下图中,您可以看到实体的生命周期: 探索 Java 开发人员职位面试中的问题和答案。 第 6 - 5 部分EntityManager在实体处于 Managed 阶段时对实体进行管理(当实体处于持久化状态时,因为它与 EntityManager 有连接。也就是说,它不是新的,也没有被删除。当一个实体是新建的或删除的时,我们可以说它也是分离的,因为 EntityManager管理它。EntityManager有不同的策略。您可以为整个应用程序拥有一个 EntityManager 单例,也可以每次为每个连接创建一个新的单例。如果您使用 Spring,EntityManager 的创建/删除会在后台自动管理(但这并不意味着您不能自己自定义它^^)。我需要提到的是,一个或多个 EntityManager 形成了一个持久化上下文持久化上下文是一个环境,其中实体实例与数据库中的类似实体同步(正如我所说,这只适用于持久化实体)。如果您深入研究JPA(我强烈推荐),您会经常遇到这个概念。

56.什么是Assert类?为什么使用它?

我在JPA中没有听说过这样的类,所以我假设这个问题是指在 JUnit 库中找到的用于单元测试的类。在这个库中,Assert类用于检查代码执行的结果(这里断言是指在代码中的特定位置具有特定状态/数据的断言)。例如,假设您正在测试一种应该创建一只猫的方法。运行该方法并得到一些结果:
Cat resultOfTest = createCat();
但您需要确保它已正确创建,对吗?因此,您手动创建一个特定的猫(预期的猫),其参数与您希望在从createCat()方法获取的猫中看到的参数完全相同。然后使用Assert类来验证结果:
Assert.assertEquals(resultOfTest, expectedCat);
如果猫不同,则会抛出断言错误,这告诉我们没有得到预期的结果。Assert类有许多不同的方法,涵盖了有助于验证预期结果各种操作。这里有几个:
  • assertTrue(<boolean>) — 作为参数传入的值预计为true

  • assertFalse(<boolean>) — 作为参数传入的值预计为false

  • assertNotEquals(<object1>, <object2>) — 使用 equals 进行比较时,作为参数传递的对象必须不同 ( false )

  • assertThrows(<ClassNameOfException>.class, <exceptionObject>) — 第二个参数应该是第一个参数抛出的异常(即第二个参数通常是应该抛出所需类型的异常的方法调用)

细绳

57.描述Java的String类

String是一个标准 Java 类,负责存储和操作字符串值(字符序列)。它是一个不可变类(我之前在这里 写过不可变类),即该类的对象的数据在创建后就不能更改。我想立即指出,StringBuilderStringBuffer类本质上是相同的 - 唯一的区别是其中一个类用于多线程环境(StringBuffer)。这些类类似于String,但不同之处在于它们是可变的。即使在创建它们之后,它们也允许您修改它们表示的字符串,而无需创建新对象。他们的方法与标准String方法不同,是为字符串操作而设计的(他们称其为构建器是有原因的)。

58.创建String对象有哪些方法?它是在哪里创建的?

创建字符串的最常见方法是在双引号中简单地指定我们想要的值:
String str = "Hello World!";
您还可以使用new明确地执行此操作:
String str = new String("Hello World!");
您还可以从字符数组创建字符串:
char[] charArr = {'H','e','l','l','o',' ', 'W','o','r','l','d','!'};
String str = new String(charArr);
我们可以通过调用某个对象的 toString方法 来做到这一点:
String str = someObject.toString();
我们可以通过调用任何其他返回字符串的方法来做到这一点。例子:
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
String str = reader.readLine();
您知道可以有很多很多方法来创建字符串。当创建String对象时,它将存储在字符串池中,我们将在下面的问题之一中更详细地讨论该对象。

59. 如何比较两个 Java 字符串,以及如何对它们进行排序?

Java 使用双等号 ( == ) 来执行比较。如果我们需要比较像整数这样的简单值,我们会使用它。但这种方法不适合比较成熟的对象。它只会比较引用,即引用是否指向同一个对象。这意味着如果我们使用==比较具有相同字段值的两个对象,我们将得到false。这些字段具有相同的值,但对象本身在内存中占据不同的位置。 字符串对象尽管看似简单,但仍然是对象。使用==比较它们也是不合适的(尽管存在字符串池)。正确的解决方案是Object类的标准equals方法,需要重写该方法才能正常工作(默认情况下,它使用==进行比较)。String类重写了它,所以我们只使用它实现:
String firstStr = "Hello World!";
String secondStr = "Hello World!";
boolean isEquals = firstStr.equals(secondStr);
探索 Java 开发人员职位面试中的问题和答案。 第 6 - 6 部分我们已经讨论过平等的比较。现在我们将找出排序的比较。毕竟,如果我们要对某些东西进行排序,我们需要知道我们将使用什么原则来排序。为此,您可以使用TreeSet(一个标准排序集)。这种数据结构依赖于红黑树算法,并根据指定的排序原则对集合进行排序。正如我之前所说,您需要了解如何对某种类型的对象进行排序。要指定排序的比较方法,请使用comparators 。您通常需要为要排序的类实现它们,但对于String来说,它们已经实现了。因此,我们只需将字符串添加到 TreeSet 中它就会为我们对它们进行排序:
TreeSet<String> sortedSet = new TreeSet<>();
sortedSet.add("B");
sortedSet.add("C");
sortedSet.add("A");
sortedSet.forEach(System.out::println);
控制台输出:
ABC

60.提供一种将字符串转换为字符的算法。编写相应的代码

正如我之前所说,String对象有许多不同的有用方法。其中之一是toCharArray。该方法将字符串转换为字符数组:
String str = "Hello world";
char[] charArr = str.toCharArray();
接下来,我们有一个可以通过索引引用的字符数组:
char firstChar = charArr[0]; // H

61. 如何将字符串与字节数组相互转换?编写相应的代码

String有一个getBytes方法,该方法与toCharArray方法类似,以字节数组形式返回字符串:
String str = "Hello world";
byte[] byteArr = str.getBytes();
byte firstChar = byteArr[6]; // 119
我们今天的审查得出了合乎逻辑的结论。谢谢阅读!
评论
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION