1.偏頭痛楊的中高階java後端面試題攻略系列之java基礎篇(持續更新)
阿新 • • 發佈:2019-02-10
前戲即使不跳槽也建議每隔一段時間出去面試幾次,面試的目的不在於拿offer入職,而是在於你知道你自己目前的水平是幾斤幾兩,是否有被市場所淘汰的危機。終身學習,居安思危,保持危機意識。每個人的時間與精力都是有限的,有限的時間做有限的事情,不要什麼都學,做減法,要有自己的強項,知識是學不完的,要打造自己的優勢與強項,再擴充套件一些輔助知識,打造金字塔結構的知識體系。很多面試官問java基礎都只會問:集合、多執行緒、併發包、jvm、nio。那我們就把有限的時間與精力放到這些上面。自己要掌握結構化學習,自己的腦子裡把知識點分塊,分類,這樣記憶。不要死記硬背面試題,要理解,看完的樹與文章要覆盤與總結,過一段時間再複習一遍。 對於知識的掌握,有四個維度:瞭解——對該領域有初步的認知,具有學習經驗或實習經驗;掌握——具備基本的知識結構,可以運用本專業知識完成相關工作;熟練——具備系統的知識和應用能力,可以較快較好的完成相關工作;精通——對該領域有深刻的研究和認識,對本專業的各種問題都有很好的解決能力。如果你想進入BAT這種一線網際網路公司,不建議剛上來就投,失敗率很高,可以先投一些二三線,獲得面試經驗以及查缺補漏,招聘求職本來就是雙向選擇。java-core在中高階的java面試中,很少有面試官會問你變數有幾種、過載與重寫的區別等之類的很基礎問題,因為java基礎的面試重點在多執行緒、集合、nio、jvm、concurrent那邊,可以把重心適當調整。請按順序並按分類寫出java的8種基本資料型別? (這個就像英語中26個英文字母一樣,分類記憶法,記憶的更牢固。)整型byte(8位)、short(16位)、int(32位)、long(64位)浮點型float(32位),double(64位)字元型char(16位)布林型boolean(1位,但是java中沒有1位的單位,因此使用8位表示)Integer與int的區別?int是基本資料型別,直接存數值,而Integer是引用資料型別,用一個引用指向一個物件。Integer是int的包裝類,是int的擴充套件,定義了很多的轉換&工具方法。int的初始值是0,Integer的初始值是null。Object類中的方法的有什麼,其作用?clone() 建立並返回此物件的一個副本。equals(Object obj)指示某個其他物件是否與此物件“相等”。finalize()當垃圾回收器確定不存在對該物件的更多引用時,由物件的垃圾回收器呼叫此方法。getClass()返回一個物件的執行時類。hashCode()返回該物件的雜湊碼值,相當於物件在記憶體中的地址。notify()喚醒在此物件監視器上等待的單個執行緒。notifyAll()喚醒在此物件監視器上等待的所有執行緒。toString()返回該物件的字串表示。wait()導致當前的執行緒等待,直到其他執行緒呼叫此物件的 notify() 方法或 notifyAll() 方法。equals()與==的區別?==是比較兩個物件的記憶體地址是否一致,基本型別則是比較值,而equals()是Object類的方法,預設是與==一致,但像String這種類,會重寫equals()來自定義判斷邏輯,程式設計師也可以重寫euqals()。什麼時候需要重寫equals()與hashcode()?(要回答這個問題必須要弄懂HashMap的底層原理,雜湊表如何儲存如何查詢。)hashCode()主要用於在雜湊表儲存結構中快速查詢物件的儲存位置(快速定址)。(主要是Hash開頭的類,如HashMap、HashSet、Hashtable等等)hashCode()是Object類中的方法,hashCode()預設會返回物件在記憶體中的地址,用整數表示。HashSet與HashMap都不允許存放重複資料,那麼如何來界定重複與不重複呢?拿HashSet舉例子,最笨的方法遍歷集合中所有元素,再使用if()+equals(),但這樣比較low。於是有人發明一種hash演算法,直接通過物件的hashcode來計算集合中存放元素的位置,這樣就不用去遍歷if()+equals()了。(別忘了jdk1.8之前的HashMap底層實現方式是陣列+連結串列,那個位置就是數組裡的元素位置。)但hashcode是有可能重複的,因為整數是有限制的,如果遇到hashcode重複,那麼再用equals進行判斷,equals的執行概率很低(因為equals的執行效率也低所以沒問題)。那為什麼我們要重寫equals()與hashCode()呢?Object原生的equals()是比較記憶體地址,而hashCode是根據記憶體地址計算出來的整數。如果現在集合中放到都是Person這種自定義物件,那即使2個各種屬性都相同的Person物件在HashSet裡也會認為是不同的物件,因此我們需要重寫equals()與hashCode()。所以如果是使用HashSet(底層也是HashMap)或HashMap的key元素物件,必須重寫這2個方法。注意(這裡也是面試考點):不要去修改集合中已有物件的屬性,前提是這個屬性參加了hashcode運算,這樣會導致老物件“失蹤”,因為新物件與老物件的hashcode發生改變,而如果想去刪除集合中的老物件也會失敗,因為定址都是依靠hashcode,從而導致記憶體洩漏。(當然這種hash思想也可以用於資料庫的分庫分表以及閘道器的路由上)java物件有幾種引用,作用是什麼?強引用(strong reference)這是java中最常見的飲用方式。程式建立一個物件,並把這個物件賦給一個引用變數,程式通過該引用變數來操作實際的物件。當一個物件被一個或一個以上的引用變數所引用時,gc並不會回收,當沒有引用變數引用時,則會被gc回收。弱引用(weak reference,由WeakReference類實現)當被弱引用指向的物件除該弱引用之外不再有其他的引用指向這個物件時(被標記成垃圾時),這時這個物件依然可以通過弱引用訪問,一旦gc檢查到這個弱引用物件,就會把他回收。弱引用有個防止記憶體溢位的用途:物件放在HashMap裡面,當物件變成垃圾後,卻沒有從hashmap裡去掉,則gc不會回收,導致記憶體溢位風險。而把物件放在WeakHashMap裡面,WeakHashMap裡的鍵值物件均為弱引用,故gc會回收。軟引用(soft reference,由SoftReference類實現)當被軟引用指向的物件除該軟引用之外不再有其他的引用指向這個物件時(被標記成垃圾時),這時這個物件依然可以通過軟引用訪問,一旦gc檢查到這個軟引用物件,在記憶體不足時,gc會回收他,否則不會。軟引用最大的用途是用來做緩衝,儲存一些垃圾物件,延長其存活時間,只要記憶體不溢位還有富裕,物件不被gc回收,記憶體吃緊時,gc在丟擲記憶體溢位異常前才會回收這些垃圾物件。虛引用&幻影引用(phantom reference,由PhantomReference類實現)幻影引用不能延長垃圾物件的存活時間,必須和ReferenceQueue類(引用佇列)一起使用,當gc要回收被幻影引用指向的物件時,gc會將其掛在ReferenceQueue佇列中,起到類似訊息傳遞的作用,使物件記憶體在被回收前執行特定的pre-mortem操作。虛引用主要用於跟蹤垃圾物件回收的狀態。程式可以通過檢查引用佇列中是否已經包含了該虛引用,從而瞭解虛引用所引用的物件是否被回收。java類的初始化順序?1.父類靜態變數&父類靜態初始化塊2.子類靜態變數&子類靜態初始化塊3.父類例項變數&父類初始化塊4.父類構造5.子類例項變數&子類初始化塊6.子類構造注意:靜態變數與靜態初始化塊的執行順序與定義順序相同(誰寫在上面誰先走)。例項變數與初始化塊的執行順序與定義順序相同(誰寫在上面誰先走)。java的引數傳遞是值傳遞還是引用傳遞?java的引數傳遞方式只有一種,那就是值傳遞。值傳遞:將實參的副本複製傳入方法內作為形參,方法裡操作的是形參,而實參不會收到影響。引用資料型別也是值傳遞,至於物件的屬性值發生變化,是因為值傳遞中的值是物件的引用地址,方法內依然進行了副本的複製工作,只不過複製的不是物件,而是一個引用變數而已,使得實參與形參指向同一個引用地址。在方法內把物件賦值成null,待方法執行完畢再呼叫實參,結果並不是null。final, finally, finalize的區別?final用於宣告屬性,方法和類,分別表示屬性不可變,方法不可覆蓋,類不可繼承。finally是異常處理語句結構的一部分,表示總是執行。finalize是Object類的一個方法,在垃圾收集器執行的時候會呼叫被回收物件的此方法,可以覆蓋此方法提供垃圾收集時的其他資源回收,例如關閉檔案等。反射的底層原理?未完待續如何手寫出一個jdk的動態代理(Proxy,InvocationHandler)?未完待續