大量的Java開發人員面試例如巴克萊銀行(Barclays)、瑞士信貸集團(Credit Suisse)、花旗銀行(Citibank)這樣的投行的Java開發崗位,可是大多數人都不知道會被問什麼問題。html
這篇文章中,我將分享一些對於3年經驗以上的程序員會被問的最多的問題。java
對於兩年及兩年如下Java開發經歷的人,投行通常不會經過社招招聘,通常只有可能在畢業時候經過校招進去。mysql
實際面試的時候並不保證必定會被問到這些問題,並且實際上,大機率問不到,可是經過這篇文章你可以知道大概會被問什麼類型的問題。並且你準備的越充分,面試的時候表現的會越好。程序員
答:沒什麼問題,會不會出問題取決於你怎麼用。例如,若是你在一個線程內初始化一個HashMap,全部線程只是讀取數據,那麼沒什麼問題。例如Map
包含配置信息,服務啓動就不會更改。真正有問題的狀況下是至少一個線程對HashMap
作了改動,例如:增長、更新或者移除任何的鍵值對。由於put()
操做會引發re-sizing,有可能致使死循環,因此應該使用Hashtable或者ConcurrentHashMap,後面這個更好一些。面試
給你們推薦一個程序員高級架構羣:702895049。羣裏有分享的視頻,還有思惟導圖
羣公告有視頻,都是乾貨的,你能夠下載來看。主要分享分佈式架構、高可擴展、高性能、高併發、性能優化、Spring boot、Redis、ActiveMQ、Nginx、Mycat、Netty、Jvm大型分佈式項目實戰學習架構師視頻。算法
答:這是一個好問題。根據我得理解,一個差的hashcode方法會致使HashMap的頻繁碰撞, 而後致使往hashMap
中添加一個對象的時候耗時增長。sql
從Java 8開始, key碰撞比以前Java版本的Key碰撞對性能影響要小一些,在大於某一個閾值後,二叉樹會取代鏈表,鏈表最壞狀況下O(n)
的性能問題會減小到二叉樹的O(logN)
。編程
答:沒有必要,你能夠實現相同的功能經過如下操做:設爲非final的private 變量,且只有在構造函數中才能修改。不設set方法,若是是一個可變對象,不要泄露任何指向這個對象的引用。設計模式
設置一個引用變量爲final 只能確保這個變量不會被賦予一個不一樣的引用,可是你仍然能夠改變引用變量的屬性值。數組
這是面試官想要聽到的一個點。若是你想要知道更多Java中引用變量的知識,推薦加入Udemy的課程Complete Java Masterclass
答:substring取原來string的一部分建立一個新的對象。這個問題主要想問的是開發者是否熟悉substring可能致使的內存泄露風險。
直到Java1.7, substring 擁有原來的字符數組的引用,這意味着即便是五字符這麼小的字符串,也可能會致使一個1GB字符數組沒法被垃圾回收由於有一個強引用。
這個問題在Java1.7中已經被修復,原來的字符數組不會被引用,可是會致使建立substring耗時會有點長,之前時間複雜度是O(1)
, Java 7以後時間複雜度是O(n)
。
答: 這個問題其實是想讓候選人寫一個雙重校驗鎖。
記得使用volatile變量
確保單例線程安全
這是使用雙重校驗鎖寫的線程安全的單例代碼:
與此同時,最好可以知道典型的設計模式,好比單例模式、工廠模式、裝飾模式等,若是你對這個感興趣,Design Pattern library 這個不錯。
答: 這是Java面試中最難的問題之一。個人回答是一個存儲過程應該在操做錯誤時返回錯誤碼,可是若是存儲過程自己出問題,捕獲SQLException
是惟一選擇。
Effective Java:3rd Edition 中對於Java的異常和捕獲有不少好的建議,值得一讀。
給你們推薦一個程序員高級架構羣:702895049。羣裏有分享的視頻,還有思惟導圖
羣公告有視頻,都是乾貨的,你能夠下載來看。主要分享分佈式架構、高可擴展、高性能、高併發、性能優化、Spring boot、Redis、ActiveMQ、Nginx、Mycat、Netty、Jvm大型分佈式項目實戰學習架構師視頻。
答 這個面試問題來自於個人這篇文章50個多線程面試問題。隨着對於Java開發人員的併發技能要求的增長,
這個題目愈來愈受歡迎。
答案是,前者返回一個Future
對象,能夠用於找到工做線程的運行結果。
在異常處理上也不同,在任務拋出異常時,若是是經過execute()
提交的,會拋出無需捕獲的異常(若是你沒有特殊處理,會打印錯誤棧道System.err)。若是是經過submit()
提交的,任何異常,不管是否是checked exception,都是返回的一部分,Future.get將把異常包在ExecutionExeption
中,向上層拋出。
若是你想學習任何Future, Callable,異步計算和提升併發編程技巧,建議你學習這個課程Java Concurrency Practice in Bundle.
這是一個基於Brian Goetz獨立編寫的併發編程實踐 的高級課程。這個課程絕對對得起你付出的錢和時間。併發編程很難並且有不少技巧,書和課程結合起來一塊兒學是不錯的方式。
答:抽象工場模式提供一個多層級的抽象。考慮不一樣的工廠繼承自同一個抽象工廠,表明基於工廠的不一樣對象結構的建立,例如,AutomobileFactory,UserFactory, RoleFactory
等都繼承自AbstractFactory
。每個獨立的工廠表明那種類型物體的創造器。
若是你想要學習更多關於抽象工廠設計模式,我建議你看Java設計模式 這個課程,提供了優秀的真實案例幫你更好的理解設計模式。
這裏是一個工廠模式和抽象工廠模式的UML圖:
若是你想要更多選擇,也能夠看這個課程:5個設計模式
答:Java中的單例是指在整個Java應用中一個類只有一個實例。例如, java.lang.Runtime
是一個單例類。
建立一個單例在Java 4以前很是難,可是自從Java 5 引入了枚舉:enum, 它變得很是容易了。
你能夠看個人這篇文章如何在Java中建立線程安全的單例,這裏使用了枚舉和雙重校驗鎖的方式,這個題主要就是想問這個。
這個問題有點棘手,可是通常是使用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 中查看細節和示例代碼。
答:當你須要的時候,尤爲是你想要經過業務邏輯校驗兩個對象是否相等,而不是經過兩個對象是否執行同一地址。例如兩個員工對象在emp_id
相等的時候相等,即便它們是經過不一樣的代碼建立出來的兩個不一樣對象。
另外,若是你使用一個對象做爲HashMap
的key,你必須重寫這兩個方法。
做爲java equals-hashcode約束的一部分,你當你重寫equals的時候,你必須重寫hashcode. 不然你不能再Set,Map這樣的類裏面使用,由於他們一來於equals()
方法來保證邏輯正確性。
你也能夠看個人這篇文章看理解重寫這兩個方法可能致使的問題: java equals中的5個技巧
給你們推薦一個程序員高級架構羣:702895049。羣裏有分享的視頻,還有思惟導圖
羣公告有視頻,都是乾貨的,你能夠下載來看。主要分享分佈式架構、高可擴展、高性能、高併發、性能優化、Spring boot、Redis、ActiveMQ、Nginx、Mycat、Netty、Jvm大型分佈式項目實戰學習架構師視頻。
答:若是你不重寫equals方法,equals和hashcode中的約束不會生效。根據該約束,兩個對象經過equals()
相等,必定有相同的hashcode。
在這種狀況下,另外一個對象可能返回一個不一樣的hashCode
並存儲在該位置,將破壞HashMap類的不可變,由於它不支持重複的key。
當你使用put()
方法添加對象時,它迭代以前在map中那個桶位置的全部的Map.Entry
對象,而且更新到新值。若是Map已經包含了那個Key,若是hashCode沒有重寫,這個機制不會起做用。
若是你想要學習更多關於Java集合(Map, Set)中equals()
和hashCode()
方法的做用,建議你看一下這個課程Java基礎:集合.
答: 答案是隻synchronize 臨界區。由於若是你鎖了整個方法,每次調用這個方法,都必須等,即便你並非在建立對象。
換句話說,synchronization 只須要在你建立對象的時候生效。一旦對象被建立,不須要任何同步。實際上,這種方法耗時不多。同步方法耗時是隻同步臨界區的10到20倍。
這是單例模式的UML圖:
順便提一句,有幾種方法能夠建立線程安全的單例,包括枚舉,在這個問題裏面咱們也能提一下、
若是你想多學點,能夠看這個免費課學習Java建立型設計模式
答:這個問題是前面問題的更進一步,候選人須要知道一但你提hashCode
,頗有可能被問HashMap
裏面的應用。
一但你提供一個key對象,hashcode方法會被調用用來計算桶位置。一個桶包含一個鏈表,每個Map.Entry
對象使用equals()
方法來看是否已經存在相同key的value。
強烈推薦你閱讀個人博客Java中HashMap如何工做, 能夠幫助你學習這個主題。
答: 死鎖發生是由於兩個線程試圖獲取被對方持有的資源。可是要想發生這種狀況,必須知足如下四個條件:
經過中斷循環等待能夠避免死鎖。能夠經過在代碼中指定獲取和釋放鎖的順序來達到這一目的。
若是多個鎖經過一致的順序被獲取和釋放,不會有互相等待對方釋放鎖的狀況。
你能夠看個人博客如何避免死鎖, 查看示例代碼和更加詳細的解釋。 同時推薦在通用Java模式上使用併發和多線程 這個課程來更好的理解多線程模式。
答: 使用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大型分佈式項目實戰學習架構師視頻。
答:不可變對象是指Java類的對象一單被建立,不能被修改。任何不可變對象對象的修改在建立時候就已經完成,例如,Java中String是不可變的
大多數不可變類是final的, 這樣能夠防止因子類重寫方法而致使不可變失效。
你也能夠實現相同的功能經過讓成員非final可是private,且除了構造方法任何其餘方法沒法修改。
另外,要確保沒有暴露不可變對象的內部,尤爲是它包含可變成員的時候。
同時,當你從客戶端接收到可變的對象時,例如java.util.Date
, 使用clone() 方法 來獲取一個獨立的拷貝,防止惡意修改可變對象帶來的風險。
相同的優化須要在返回一個可變成員時執行。返回另外一個獨立拷貝給客戶端;不要返回可變對象的原始引用。你也能夠看個人這篇博客Java中如何建立一個不可變對象, 這裏有按步驟的引導和示例代碼。
答:請求前和請求後記錄時間,計算時間差值。若是一個方法耗時過小可能顯示0毫秒,那麼可讓方法變的足夠大,好比重複執行足夠屢次。算總時間。
答:爲了在hashMap
或者hashtable
中把對象做爲key,它必須實現equals和hashcode方法。
你也能夠閱讀Java在HashMap中是如何工做的,瞭解相關實現細節。
答:在我給答案以前,本身研究一下這個問題。我相信你能夠找到正確答案,從代碼維護的角度來,控制你的類是很是重要的。
給你們推薦一個程序員高級架構羣:702895049。羣裏有分享的視頻,還有思惟導圖
羣公告有視頻,都是乾貨的,你能夠下載來看。主要分享分佈式架構、高可擴展、高性能、高併發、性能優化、Spring boot、Redis、ActiveMQ、Nginx、Mycat、Netty、Jvm大型分佈式項目實戰學習架構師視頻。