1. 程式人生 > >面試投行的20個Java問題

面試投行的20個Java問題

如果你需要準備面試,可以看一下這篇部落格中20個為Java開發人員準備的面試投行的問題。

大量的Java開發人員面試例如巴克萊銀行(Barclays)、瑞士信貸集團(Credit Suisse)、花旗銀行(Citibank)這樣的投行的Java開發崗位,但是大多數人都不知道會被問什麼問題。

這篇文章中,我將分享一些對於3年經驗以上的程式設計師會被問的最多的問題。

對於兩年及兩年以下Java開發經歷的人,投行一般不會通過社招招聘,一般只有可能在畢業時候通過校招進去。

實際面試的時候並不保證一定會被問到這些問題,而且實際上,大概率問不到,但是通過這篇文章你能夠知道大概會被問什麼型別的問題。而且你準備的越充分,面試的時候表現的會越好。

Java程式設計師投行面試問題

問題1: 多執行緒環境下使用HashMap有什麼問題,什麼時候使用get()方法會進入死迴圈?

:沒什麼問題,會不會出問題取決於你怎麼用。例如,如果你在一個執行緒內初始化一個HashMap,所有執行緒只是讀取資料,那麼沒什麼問題。例如Map
包含配置資訊,服務啟動就不會更改。真正有問題的情況下是至少一個執行緒對HashMap做了改動,例如:增加、更新或者移除任何的鍵值對。因為put()操作會引起re-sizing,有可能導致死迴圈,所以應該使用Hashtable或者ConcurrentHashMap,後面這個更好一些。

給大家推薦一個程式設計師高階架構群:702895049

。群裡有分享的視訊,還有思維導圖
群公告有視訊,都是乾貨的,你可以下載來看。主要分享分散式架構、高可擴充套件、高效能、高併發、效能優化、Spring boot、Redis、ActiveMQ、Nginx、Mycat、Netty、Jvm大型分散式專案實戰學習架構師視訊。

問題2:如果你不重寫hashCode()方法,會有什麼後果嗎?

:這是一個好問題。根據我得理解,一個差的hashcode方法會導致HashMap的頻繁碰撞, 然後導致往hashMap中新增一個物件的時候耗時增加。

Java 8開始, key碰撞比之前Java版本的Key碰撞對效能影響要小一些,在大於某一個閾值後,

二叉樹會取代連結串列,連結串列最壞情況下O(n)的效能問題會減少到二叉樹的O(logN)

問題3:Java裡面所有的不變的屬性需要設定為final嗎?

:沒有必要,你可以實現相同的功能通過以下操作:設為非final的private 變數,且只有在建構函式中才能修改。不設set方法,如果是一個可變物件,不要洩露任何指向這個物件的引用。

設定一個引用變數為final 只能確保這個變數不會被賦予一個不同的引用,但是你仍然可以改變引用變數的屬性值。

這是面試官想要聽到的一個點。如果你想要知道更多Java中引用變數的知識,推薦加入Udemy的課程Complete Java Masterclass

問題4:String的substring()的實現原理

:substring取原來string的一部分建立一個新的物件。這個問題主要想問的是開發者是否熟悉substring可能導致的記憶體洩露風險。

直到Java1.7, substring 擁有原來的字元陣列的引用,這意味著即使是五字元這麼小的字串,也可能會導致一個1GB字元陣列無法被垃圾回收因為有一個強引用。

這個問題在Java1.7中已經被修復,原來的字元陣列不會被引用,但是會導致建立substring耗時會有點長,以前時間複雜度是O(1), Java 7之後時間複雜度是O(n)

問題5:寫一個單例模式的臨界區程式碼(答案)

: 這個問題實際上是想讓候選人寫一個雙重校驗鎖

記得使用volatile變數
確保單例執行緒安全

這是使用雙重校驗鎖寫的執行緒安全的單例程式碼:

 

與此同時,最好能夠知道典型的設計模式,比如單例模式、工廠模式、裝飾模式等,如果你對這個感興趣,Design Pattern library 這個不錯。

file

問題6:Java中如何處理寫儲存過程或者讀儲存過程時遇到的錯誤?

: 這是Java面試中最難的問題之一。我的回答是一個儲存過程應該在操作錯誤時返回錯誤碼,但是如果儲存過程本身出問題,捕獲SQLException 是唯一選擇。

Effective Java:3rd Edition 中對於Java的異常和捕獲有很多好的建議,值得一讀。

給大家推薦一個程式設計師高階架構群:702895049。群裡有分享的視訊,還有思維導圖
群公告有視訊,都是乾貨的,你可以下載來看。主要分享分散式架構、高可擴充套件、高效能、高併發、效能優化、Spring boot、Redis、ActiveMQ、Nginx、Mycat、Netty、Jvm大型分散式專案實戰學習架構師視訊。

問題7:Executor.submit()Executer.execute()有什麼區別?

 這個面試問題來自於我的這篇文章50個多執行緒面試問題。隨著對於Java開發人員的併發技能要求的增加,
這個題目越來越受歡迎。

答案是,前者返回一個Future物件,可以用於找到工作執行緒的執行結果。

在異常處理上也不一樣,在任務丟擲異常時,如果是通過execute()提交的,會丟擲無需捕獲的異常(如果你沒有特殊處理,會列印錯誤棧道System.err)。如果是通過submit()提交的,任何異常,無論是不是checked exception,都是返回的一部分,Future.get將把異常包在ExecutionExeption中,向上層丟擲。

如果你想學習任何Future, Callable,非同步計算和提高併發程式設計技巧,建議你學習這個課程Java Concurrency Practice in Bundle.

這是一個基於Brian Goetz獨立編寫的併發程式設計實踐 的高階課程。這個課程絕對對得起你付出的錢和時間。併發程式設計很難而且有很多技巧,書和課程結合起來一起學是不錯的方式。

file

問題8: 工廠模式和抽象工廠模式有什麼區別?(答案)

:抽象工場模式提供一個多層級的抽象。考慮不同的工廠繼承自同一個抽象工廠,代表基於工廠的不同物件結構的建立,例如,AutomobileFactory,UserFactory, RoleFactory等都繼承自AbstractFactory。每一個獨立的工廠代表那種型別物體的創造器。

如果你想要學習更多關於抽象工廠設計模式,我建議你看Java設計模式 這個課程,提供了優秀的真實案例幫你更好的理解設計模式。

這裡是一個工廠模式和抽象工廠模式的UML圖:

file

如果你想要更多選擇,也可以看這個課程:5個設計模式

問題9: 什麼是單例?整個方法使用synchronized和只有臨界區使用synchronized哪個好?(答案)

:Java中的單例是指在整個Java應用中一個類只有一個例項。例如, java.lang.Runtime是一個單例類。

建立一個單例在Java 4之前非常難,但是自從Java 5 引入了列舉:enum, 它變得非常容易了。

你可以看我的這篇文章如何在Java中建立執行緒安全的單例,這裡使用了列舉和雙重校驗鎖的方式,這個題主要就是想問這個。

問題10: 你能基於Java 4,Java5裡面的HashMap如何迭代取值?

這個問題有點棘手,但是一般是使用while或者for迴圈。Java裡面迭代Map有四種方式。一種是使用keySet(),迭代每一個key的時候使用get()方法去取value,但是有點慢。第二種方法是使用entrySet()。然後使用for each迴圈或者Iterator.hashNext()方法來迭代取值即可。 (keySet, entrySet和foreach, Iterator進行組合,所以是4種。)

這個方法比較好,因為在每次迭代時,key 和 value 都已經取出來了,你不需要呼叫get()方法去取value,使用get()方法當你從一個桶裡面的大的連結串列中取資料,時間複雜度是O(n)。

你可以在我的部落格4種方法迭代Java Map 中檢視細節和示例程式碼。

問題11:什麼時候重寫 hashCode() 和 equals() 方法?(答案

:當你需要的時候,尤其是你想要通過業務邏輯校驗兩個物件是否相等,而不是通過兩個物件是否執行同一地址。例如兩個員工物件在emp_id 相等的時候相等,即使它們是通過不同的程式碼創建出來的兩個不同物件。

另外,如果你使用一個物件作為HashMap的key,你必須重寫這兩個方法。

作為java equals-hashcode約束的一部分,你當你重寫equals的時候,你必須重寫hashcode. 否則你不能再Set,Map這樣的類裡面使用,因為他們一來於equals()方法來保證邏輯正確性。

你也可以看我的這篇文章看理解重寫這兩個方法可能導致的問題: java equals中的5個技巧

給大家推薦一個程式設計師高階架構群:702895049。群裡有分享的視訊,還有思維導圖
群公告有視訊,都是乾貨的,你可以下載來看。主要分享分散式架構、高可擴充套件、高效能、高併發、效能優化、Spring boot、Redis、ActiveMQ、Nginx、Mycat、Netty、Jvm大型分散式專案實戰學習架構師視訊。

問題12:在重寫hashCode()方法的時候你遇到哪些問題?

:如果你不重寫equals方法,equals和hashcode中的約束不會生效。根據該約束,兩個物件通過equals()相等,一定有相同的hashcode。

在這種情況下,另一個物件可能返回一個不同的hashCode並存儲在該位置,將破壞HashMap類的不可變,因為它不支援重複的key。

當你使用put()方法新增物件時,它迭代之前在map中那個桶位置的所有的Map.Entry物件,並且更新到新值。如果Map已經包含了那個Key,如果hashCode沒有重寫,這個機制不會起作用。

如果你想要學習更多關於Java集合(Map, Set)中equals()hashCode()方法的作用,建議你看一下這個課程Java基礎:集合.

file

問題13:synchroize getInstance()方法的臨界區和synchronize 整個getInstance()方法哪個好?(答案)

: 答案是隻synchronize 臨界區。因為如果你鎖了整個方法,每次呼叫這個方法,都必須等,即使你並不是在建立物件。

換句話說,synchronization 只需要在你建立物件的時候生效。一旦物件被建立,不需要任何同步。實際上,這種方法耗時很少。同步方法耗時是隻同步臨界區的10到20倍。

這是單例模式的UML圖:

file

順便提一句,有幾種方法可以建立執行緒安全的單例,包括列舉,在這個問題裡面我們也能提一下、

如果你想多學點,可以看這個免費課學習Java建立型設計模式

問題14:在HashMapget()操作中,equals()方法和hashCode()方法什麼時候起作用?(答案

:這個問題是前面問題的更進一步,候選人需要知道一但你提hashCode,很有可能被問HashMap裡面的應用。

一但你提供一個key物件,hashcode方法會被呼叫用來計算桶位置。一個桶包含一個連結串列,每一個Map.Entry物件使用equals()方法來看是否已經存在相同key的value。

強烈推薦你閱讀我的部落格Java中HashMap如何工作, 可以幫助你學習這個主題。

file

問題15: Java中如何避免死鎖(答案)

: 死鎖發生是因為兩個執行緒試圖獲取被對方持有的資源。但是要想發生這種情況,必須滿足以下四個條件:

  1. 相互排斥——至少一個程序必須處於非共享模式
  2. 保持並等待——必須有一個程序持有一個資源並等待另一個資源
  3. 沒有搶佔—— 資源不能被搶佔
  4. 迴圈等待 —— 存在程序集合

通過中斷迴圈等待可以避免死鎖。可以通過在程式碼中指定獲取和釋放鎖的順序來達到這一目的。

如果多個鎖通過一致的順序被獲取和釋放,不會有互相等待對方釋放鎖的情況。

你可以看我的部落格如何避免死鎖, 檢視示例程式碼和更加詳細的解釋。 同時推薦在通用Java模式上使用併發和多執行緒 這個課程來更好的理解多執行緒模式。

file

問題16:雙引號直接建立字串和使用new()建立字串有什麼區別?

: 使用new()建立String物件,例項被建立在中, 不會被新增到String常量池中,當通過字面量 建立時,會被放到堆中的永久區的String常量池中。

String str = new String("Test") 不會把str放到String常量池中,我們需要呼叫String.intern()方法,會把它放到String常量池中。

當我們使用String字面量建立String物件時,如通過String s = "Test", java會自動放入String常量池中。

另外,如果我們把"Test"這樣的String字面量傳進去,也會建立另外一個物件:"Test" 在String常量池

這是我的知識盲區直到讀者在我的部落格 中給我提建議,如果想學習更多關於String字面量和String物件的知識,看這裡

給大家推薦一個程式設計師高階架構群:702895049。群裡有分享的視訊,還有思維導圖
群公告有視訊,都是乾貨的,你可以下載來看。主要分享分散式架構、高可擴充套件、高效能、高併發、效能優化、Spring boot、Redis、ActiveMQ、Nginx、Mycat、Netty、Jvm大型分散式專案實戰學習架構師視訊。

file

問題17:什麼是不可變物件?你可以寫一個不可變類嗎?(答案)

:不可變物件是指Java類的物件一單被建立,不能被修改。任何不可變物件物件的修改在建立時候就已經完成,例如,Java中String是不可變的

大多數不可變類是final的, 這樣可以防止因子類重寫方法而導致不可變失效。

你也可以實現相同的功能通過讓成員非final但是private,且除了構造方法任何其他方法無法修改。

另外,要確保沒有暴露不可變物件的內部,尤其是它包含可變成員的時候。

同時,當你從客戶端接收到可變的物件時,例如java.util.Date, 使用clone() 方法 來獲取一個獨立的拷貝,防止惡意修改可變物件帶來的風險。

相同的優化需要在返回一個可變成員時執行。返回另一個獨立拷貝給客戶端;不要返回可變物件的原始引用。你也可以看我的這篇部落格Java中如何建立一個不可變物件, 這裡有按步驟的引導和示例程式碼。

問題18:不用效能分析工具,給出一個簡單的辦法找到一個方法執行耗時

:請求前和請求後記錄時間,計算時間差值。如果一個方法耗時太小可能顯示0毫秒,那麼可以讓方法變的足夠大,比如重複執行足夠多次。算總時間。

問題19:當你使用Object作為HashMap裡面的key的時候,哪兩個方法需要實現?

:為了在hashMap或者hashtable中把物件作為key,它必須實現equalshashcode方法。

你也可以閱讀Java在HashMap中是如何工作的,瞭解相關實現細節。

問題20:如何防止客戶端直接例項化你的具體類?例如你有一個Cache介面和兩個實現類:MemoryCacheDiskCache。如何確保沒有任何這兩個類的物件通過new()關鍵字被創建出來?

:在我給答案之前,自己研究一下這個問題。我相信你可以找到正確答案,從程式碼維護的角度來,控制你的類是非常重要的。

給大家推薦一個程式設計師高階架構群:702895049。群裡有分享的視訊,還有思維導圖
群公告有視訊,都是乾貨的,你可以下載來看。主要分享分散式架構、高可擴充套件、高效能、高併發、效能優化、Spring boot、Redis、ActiveMQ、Nginx、Mycat、Netty、Jvm大型分散式專案實戰學習架構師視訊。

現在你已經準備好Java面試了

這是一些最通用的關於資料結構演算法的問題,他們可以幫忙你準備投行的技術面試。祝你好運!