CodeGym /Java Blog /Toto sisi /探索 Java 開發人員職位面試中的問題和答案。第 6 部分
John Squirrels
等級 41
San Francisco

探索 Java 開發人員職位面試中的問題和答案。第 6 部分

在 Toto sisi 群組發布
你好世界!對於任何開發人員來說,永遠不要停止成長至關重要。畢竟,如果你停下來,你就有可能失去需求並完全退出就業市場。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