1. 程式人生 > >Java面試題解構

Java面試題解構

針對性 算法 電腦 try 版本 不同的 uil 初級 null

有次一個同事讓我一同去面試一個候選人,沒仔細看簡歷,所以在問了設計模式之後就讓他談一談對內存泄漏和垃圾回收的理解,當時候選人一下子就懵了。後來才知道,他面的是初、中級開發職位,想來估計候選人心裏也在罵我吧。

我自己用過各式各樣的方法面試候選人,也被各式各樣的方式面試過。有讓拿電腦直接寫代碼的,有讓在白板上寫思路、畫結構的,或者挨個知識點問問題的。面試,應該是要測試候選人「是否有做好某些事情的能力」,而不應該是「知道某些事情的能力」。雖然這兩者往往是相關的,但有很大一部分問題卻是對「把事情做好」沒有任何幫助的。其中的一類是那些「你不用的時候只是大概知道,需要使用的時候花一分鐘就可以搞清楚」的問題,就算你是一個比較好學的開發者,平時會看一些跟工作關系不是那麽大的東西,並且可以搞得很清楚,但時間一長,再去問你細節,我想同樣會模糊不清,甚至會出錯。

本文並不是面試刷題的題庫。而是希望可以通過對面試的問題進行分類,幫助Java工程師在準備面試時,可以高屋建瓴,快速找到所需的知識點。同時會給出一些好的、壞的示例,希望可以幫助到一些人。

面試問題的分類

關於會被問到的Java方面的問題,大致可以分為以下幾類:

  1. Hotspot VM(Runtime、GC、JIT)相關問題

這些問題其實屬於要了解的東西,對指導編碼、問題排查、運行時邏輯的理解都有好處。

但如果非要問你G1、CMS、Serial垃圾回收器各自的實現方法及其不同,除非你面的就是做JVM調優的職位,那你也是倒了黴了,解決方案只能是面試前突擊鞏固這方面的知識。

  1. JDK中特定類的使用問題

如果你的工作會用到一些類,可能你會很熟悉,但老實說,還是會有很多類用了很多次,每次都要去源碼裏看註釋的情況……

有註釋為毛要浪費珍貴的腦容量。有病

  1. JDK中特定類(或操作符、關鍵字)的實現問題

相信很大一部分(有工作經驗的)工程師的工作內容是不需要考慮這些問題的,但很多有追求的工程師都很樂意去探索這些問題,比如HashMap的實現原理,TransferQueue的算法邏輯。

但是,那麽多類,誰能保證全部記得很清楚,如果有,一定是來面試前背過了。

  1. 其他一些變態的陷阱問題

各種亂花漸欲迷人眼的問題,如「重載和重寫的區別」「final、finally、finalize的區別」之流,實在無力吐槽。出這些題的人估計是想要考察你的基本功,但又懷著不耐煩的心情,所以挖個坑看你怎麽跳。

有種你編程不用搜索引擎啊。

這裏換個姿勢問,面試官的逼格立馬就顯現了。比如「JDK如何保證在try-catch-finally中的finally塊一定會被執行的?」,但這就屬於第3類問題了,如果回答不出來,應該引導他通過已有的知識和自己的想法去實現。

5. 解決實際問題

這是真正有價值的問題,可以考察人的思維及解決問題能力的問題。而且不論是業務相關,亦或是技術理論相關的,都可以問出有價值的問題。

如「自己設計一個ArrayList/LinkedBlockingQueue」,「設計一個秒殺系統」,「如果碰到XXX問題,你估計是哪裏出的問題」等等。

  1. 與Java無關的問題

這種問題通常是為了考察應聘者的性格、人品、知識面、學習能力等,比如「簡單描述一下HTTPS的工作流程」、「最近是否有在看書或者哪方面的知識」等。有些有套路,可以抱抱佛腳,通過刷題刷出來。其他的只能自求多福了。

相關問題示例

下面是一些從網上看到或者自己被問到過的一些問題,僅供參考。

第一類問題

  1. 簡單描述一下JVM的GC

A:隨意發揮……可以參考Java 9中的GC調優基礎

這是一個典型的比較有開放性的問題,面試者可以從自己了解的方面入手,如分代、運行時內存結構。如果對垃圾回收器比較了解,那更可以侃侃而談。

如果被問到了比較有針對性的問題,那就看你面試前的課補的好不好了。

  1. Java中有哪些多線程同步的手段

這個問題也可以延伸出很多知識,synchronized的實現原理、synchronized中的鎖膨脹、為什麽有時候使用volatile可以帶來更好的性能、悲觀鎖&樂觀鎖的概念、新一代的基於Lock的鎖機制,更甚者可能會問到Java的內存模型(JMM)。

第二類問題

  1. StringBuilder vs StringBuffer

A:前者是後者不加鎖的版本,使用場景BlaBla……

現在還有人問這個問題,只有兩種可能:1. 面試官或者候選人的水平比較初級;2. 面試官一下子想不到別的好問的。

  1. Java8比Java7添加了什麽新的特性

A:Lambda、streams、接口默認方法……

我要是背書背的好早學文科了。

  1. Java自帶線程池判斷線程池是否已經結束運行的方法叫什麽

A:isShutdown和isTerminated。

  1. BlockingQueue,CountDownLatch及Semeaphore的使用場景

  2. java.util.Date與java.sql.Date有什麽區別

A:繼承關系

不知道這個問題的意義在哪裏。

  1. 如果要從LinkedBlockingQueue中取出頭部對象,分別哪個方法會返回null、拋錯、阻塞

A:take - 阻塞,poll - 返回null,remove - 拋錯

第三類問題

  1. ThreadLocal的實現原理

A:就是一個只有當前線程可訪問的以ThreadLocal實例為Key的HashMap,其內部的Map實現和HashMap的實現差不多,這個Map的實例存儲在Thread對象上,所以通過封裝,能保證線程只訪問自己的ThreadLocal變量。

好吧,很可能面試官想聽到的就是這樣一句話。

但ThreadLocal之所以重要其實是其背後的設計思想,它將變量從共享的和需要多線程同步的環境轉移到了線程私有和不需要同步的環境內,這種思想可以用來解決很多不同的場景下的問題。

但是,誰關心這些呢?

  1. LinkedList的實現原理

A:它是一個雙向列表,實現了List、Deque、Cloneable等接口

老實說,Deque(雙向隊列)這個東西見過幾次,但沒用過,所以現在也說不太清楚它的特征和實際使用場景,所以也不想胡侃。

  1. ConcurrentHashMap的實現原理

A:它是一個對寫操作加了鎖的HashMap,不同的是它做了二次分割,元素被存儲在不同的桶裏,以見效鎖的數據範圍,提升性能。

在JDK8中對這種實現又進行了修改,JDK8中的ConcurrentHashmap基於CAS和TreeBin實現的,不需要對segment或者全局加鎖,只需要對單行枷鎖(hashCode相同),後邊的鏈表是鏈表加紅黑樹。對於單個值的修改使用CAS。

面試官很可能想聽到的是這樣,但這裏重要的是分治的概念。其實完全可以讓候選人嘗試自己去設計一個ConcurrentHashMap,然後引導他去拆分HashMap,這樣才是正道啊。

  1. hashcode()和equals()的關系

A:根據JVM標準,equals()相等的對象,hashcode()應該永遠相對,反之則不一定,詳見HashMap的實現。

這個問題其實挺好的,但如果只是簡單的問一下,沒有任何意義,仍然考的是記憶力。

  1. TransferQueue的算法是什麽樣的,它和BlockingQueue有哪些不同

A:源代碼裏有。

這麽回答肯定是不好的,還是去補補課吧。如果你覺得面試官問這個太無聊,可以拿到offer後醜拒。

第五類問題

  1. 用 wait-notify 寫一段代碼來解決生產者-消費者問題,更進一步,在分布式的環境下怎麽解決

A:哈哈哈,我們來寫段代碼吧……

wait()和notify()都是線程間通信的方法,可以直接對線程的行為進行操作。他們的本質其實是傳遞生產者-消費者各自的消息,理解了這一點,那麽在分布式環境下就很簡單了,只要找到一個第三方的可以用來傳遞消息的媒介(Zookeeper、Redis、Kafka等)就可以了。

  1. 設計一個線程池

A:可以參考Java線程池的理論與實踐

如果對JDK的線程池java.util.concurrent.ThreadPoolExecutor比較了解,可以把一些簡單的特性放上去。如果不了解,可以直接設計一個線程數組,然後加一些業務邏輯。所謂線程池,基本也就如此。

  1. 設計一個IOC容器

A:用反射,註解,還有IOC的理論

java交流群669823128

Java面試題解構