原文地址: https://dzone.com/articles/10...html
有爲數很多的開發者但願能在像 Barclays、Credit Suisse、Citibank 等等那樣的投資銀行作 Java 開發工做,可是他們當中不少不知道本身會遇到什麼樣的面試題。java
本文介紹一些來自投資銀行的、針對三年以上經驗的 Java 開發人員面試題。之因此不針對兩年經驗或如下的新手程序員,是由於投資銀行一般會從畢業生那裏去招這種水平的人,而不是經過社招。mysql
也不是說這些問題必定會問到,只是給你一個印象,實際面試的時候會以哪些方面的題目爲主。程序員
固然,準備作得越充足就越好,因此若是這十道題對你來說還不夠,那麼能夠再看看電話面試四十題。這裏還有一個兩百多道題的大餐(譯註:這是在線課程廣告連接。後面的廣告連接我都將去除)等着你。面試
怎麼說呢,無論什麼東西,只要用對了就不會有問題。好比說一個 HashMap,你只用一個線程初始化,而後全部的線程都對它只讀,那是徹底沒問題的。spring
一個典型例子就是包含配置屬性的 Map 對象。若是有線程開始去寫這個 Map,去添加、修改或刪除裏面的鍵值對,哪怕只有一個線程,問題就來了。sql
put() 方法可能會觸發它內部的容量大小變動(re-sizing),這個過程可能會形成無限循環,這就是爲何你應該換用 Hashtable 或 ConcurrentHashMap(後者更佳)。編程
譯註:關於 HashMap 陷入無限循環的可能,請參考 這篇文章。
這個問題很棒,也很開放。據我所知,hashCode() 方法實現的很差,可能會致使 HashMap 頻繁出現衝突,增長了將對象放入 HashMap 的耗時。安全
不過從 Java 8 開始這種狀況有所改善,由於衝突到達必定級別後,HashMap 會改用二叉樹而不是鏈表來保存內容,這樣時間複雜度就從 O(N) 下降到了 O(log N)。多線程
這個問題屬於比較刁鑽的面試題之一,不少開發者只知道 hashCode() 和 equals() 之間的關係,不會想到性能方面可能出現的問題。
不是必須的。成員能夠聲明爲 private 而且只在構造函數裏面賦值,能達到一樣的效果。
關鍵是不要提供 setter 方法。若是該屬性是可變對象,還注意不要把它的引用泄露出去。
記住,將一個引用變量聲明爲 final 僅表示不容許對該變量從新賦值,你仍然能夠修改該變量值自身的屬性。若是求職者可以把問題闡明到這個層次,在面試官面前還能多拿點印象分哦。
不少開發人員會說:「這個方法就是從原始字符串中取出一部分,做爲新的 String 對象返回。」
這樣是沒回答到點子上的,由於這個問題其實是在考察你是否熟悉 substring() 方法形成內存泄漏的風險。
在 Java 1.7 以前,substring() 方法的返回值會持有原始字符串的引用,致使原始字符串沒法被回收,也就是說,哪怕 substring() 返回的字符串只有 5 個字節,也會令原始大小 1GB 的字符串沒法回收。
從 Java 1.7 開始這個問題被修復了,substring() 方法的返回值再也不引用原始字符串,不過相應的代價是執行時間有所增長,時間複雜度從以前的 O(1) 增長到最壞情形下的 O(N)。
本題屬於 Java 核心題目,跟上一題有一脈相承的關係。提問者會期待面試者寫出包含 雙重檢查鎖定模式 的代碼。
因此必定要記得在單例模式中使用 volatile 變量。
下面是一個使用雙重檢查鎖定模式來實現單例模式的示例:
public class Singleton { private static volatile Singleton _instance; /** * Double checked locking code on Singleton * @return Singelton instance */ public static Singleton getInstance() { if (_instance == null) { synchronized(Singleton.class) { if (_instance == null) { _instance = new Singleton(); } } } return _instance; } }
這個問題很開放,也是 Java 面試難題 之一。我是從一個朋友那裏聽到這個問題的,他也回答不出。
個人解決方案是,存儲過程中若是某些操做失敗,那麼應該返回一個錯誤代碼;但要是存儲過程自己調用失敗,那就只能捕獲 SQLException 了。
本題取自個人 「投資銀行鍼對有經驗的開發者的 五十個 Java 多線程面試題 列表」。這類問題愈來愈流行,由於企業對熟練掌握多線程開發的程序員的需求愈來愈多。若是你想認真打造本身的併發編程技能,我這裏順便推薦一下 Heinz Kabutz 的 Java 多線程實戰課程。
回到本題,前者返回的是一個 Future 對象,它用來從 Worker 線程中獲取處理結果。(譯註:後者即 execute() 方法沒有返回值)
還有一個區別就是對異常的處理。當 execute() 執行的任務發生異常時,該異常會進入未捕獲異常處理流程(若是你沒有提供本身的處理方式,則會從 System.err 將異常信息打印出來)。
當 submit() 執行的任務發生異常時,該異常會成爲返回值的一部分。若是任務由於異常而結束運行,那麼當調用 Future.get() 方法獲取返回值時,這個異常會被包裝在 ExecutionException 中再次拋出。
抽象工廠模式比工廠模式多了一層抽象。
一個抽象工廠能夠有多個不一樣的實現,它們各自負責建立不一樣種類的實際對象。以下圖所示:
單例就是指某個類在整個 Java 應用當中只有一個實例對象。好比 java.lang.Runtime 就是一個單例的類。在 Java 5 以前,設計單例類要很是當心容易出錯,但自從 Java 5 引進了枚舉以後,事情變得輕鬆多了。
請參考本人的文章 如何編寫線程安全的單例,該文詳細介紹瞭如何使用枚舉或雙重鎖定檢查模式來實現單例,這也是本面試題的目的所在。
這個題目也比較刁鑽,上面的答案給出了使用 while 和 for 循環來進行遍歷的例子。實際上,在 Java 中遍歷 Map 有四種方法。(譯註:分別是 for-keyset、while-keyset、for-entryset 和 while-entryset)
遍歷 keySet() 而後對每一個 key 調用 get() 方法來取值,這種方式相對效率較低。
另外一種方式就是遍歷 entrySet(),而後直接從 Entry 中取 key 或 value。這種方式效率較高,由於你無需再調用 get() 方法取值。若是該方法遇到了較長的鏈表(譯註:參考第二題),時間複雜度將會變成 O(N),雖然在 Java 8 中狀況會稍微好點,由於 Java 8 會用二叉樹代替鏈表。
以上就是投資銀行一般會出的 Java 面試題。若是你想在當中謀個 Java 開發者職位,那麼請作好面對大量有關 Java 多線程、併發、集合、JVM 內部實現、垃圾收集,以及 Java 應用性能調優的各類問題。