本文的題目出自博客
http://www.54tianzhisheng.cn/2018/07/12/youzan/
可是做者沒有給出答案,博主斗膽來製做答案版。css
說在前面的話:
本文適合人羣:急等着換工做的人
我認可刷面試題頗有用的,縱觀幾年來的JAVA面試題,你會發現每家都差很少。好比,你仔細觀察,你會發現,HashMap的出現概率未免也過高了吧!連考察的知識點都同樣,什麼hash碰撞啊,併發問題啊!再好比JVM,無外乎考內存結構,GC算法等!所以,若是是爲了面試,徹底是有套路能夠準備的!記住,基礎再好,也架不住面試官天馬行空的問,因此刷面試題仍是頗有必要的!html
本文不適合人羣:專攻JAVA某方面技術的人
由於這類人專攻JAVA某塊技術,知識容易出現死角。貿然閱讀本文,發現本身一堆題目都不會,會以爲有一種挫敗感,發現本身連校招生都不如。然而,會點面試題不算什麼,畢竟Homebrew做者也出現過解不出面試題,被Google拒絕,原因就是,由於他不會翻轉二叉樹。難道你能說Homebrew的做者水平有問題!java
一、自我介紹
評註:這個地方答什麼隨意,大部分面試官不會聽你介紹,這個時間都在看簡歷。若是是電話面,回答時間控制在40秒到1分鐘左右就行。若是是現場面,那就好辦了,你注意看面試官何時擡頭看你,通常面試官放下簡歷,擡頭看你的時候,趕忙收尾!
回答:我叫xx,畢業於xxx,興趣xx,作過xx項目....mysql
二、Map 的底層結構?(HashMap)
評註:老題目了,各位面試的人員必須熟記!
回答:Map是以鍵值對來存儲對象的,它的底層其實是數組和鏈表來組成的,經典的一張圖以下(別人畫的);
當使用put方法時,先查找出數組位置是否存在對象,經過key.hashcode對數組長度取餘;存在,則把裏面的鏈表拿出來,判斷鏈表裏面是否存在key值與傳遞過來的key值同樣的對象,存在,則把傳遞過來的value取代鏈表key對應的value,不存在,則直接經過鏈表的add()方法加到鏈表後面;面試
當使用get方法時,先查找出數組位置是否存在對象,經過key.hashcode對數組長度取餘;若是不存在,則返回爲空,若是存在,則遍歷鏈表,判斷鏈表裏面是否存在key值與傳遞過來的key值同樣的對象,存在,則把key值對應的value取出返回,不存在,則返回爲空;redis
三、線程安全的 Map (concurrentHashMap)簡單的說了下這兩 1.7 和 1.8的區別,本想問下要不要深刻的講下(源碼級別),結果面試官說不用了。
評註:老題目了,若是有時間,再去了解一下,解決HashMap線程安全的各類方法,以及原理!此題只能大概回答一下結構的變化,由於其中的實現代碼都變了,細說能夠說好久,估計面試官也沒時間聽!
回答:
jdk1.7中採用 Segment + HashEntry的方式進行實現,結構以下:
Segment數組的意義就是將一個大的table分割成多個小的table來進行加鎖,而每個Segment元素存儲的是HashEntry數組+鏈表,這個和HashMap的數據存儲結構同樣
而jdk1.8中則
去除 Segment
+ HashEntry
+ Unsafe
的實現,
改成 Synchronized
+ CAS
+ Node
+ Unsafe
的實現
其結構圖以下:
如上圖所示,取消了Segment字段,數組中存儲的就是Node。它與HashMap中的HashEntry定義很類似,可是有一些差異。它對value和next屬性設置了volatile同步鎖,它不容許調用setValue方法直接改變Node的value域。
另外,將原先table數組+單向鏈表的數據結構,變動爲table數組+單向鏈表+紅黑樹的結構,在hash碰撞過多的狀況下會將鏈表轉化成紅黑樹。算法
四、項目 MySQL 的數據量和併發量有多大?
評註:此題爲走向題,你的回答不一樣,後面問題走向就變了。
關於容量:單錶行數超過 500 萬行或者單表容量超過2GB,此時就要答分庫分表的中間件了!那後面題目的走向就變爲mycat、sharing-jdbc等分庫分表中間件的底層原理了!
關於併發量:若是併發數過1200,此時就要答利用MQ或者redis等中間件,做爲補償措施,而不能直接操做數據庫。那後面的題目走向就是redis、mq的原理了!
介於面試者仍是一個應屆生,我斗膽猜想面試者是這麼答的
回答:數據量估計就三四百萬吧,併發量就五六百左右!spring
五、你對數據庫瞭解多少?
評註:由於你答的數據量和併發量不大,所以中間件這塊沒啥好問的。所以,題目走向變爲數據庫底層!另外,此題爲引導題,面試官在給你機會引向你最擅長的方面!
回答:瞭解常見數據庫調優方法,索引優化等!sql
六、你說下數據庫的索引實現和非主鍵的二級索引
評註:這個問題是根據上面,你的回答而問出來的!記得引向本身最擅長的數據庫基礎知識!默認是回答mysql數據庫的
回答:
從數據結構角度:
B-Tree索引,數據結構就是一顆B+樹。
Hash索引,Hash索引比較的是進行Hash運算以後的Hash值,因此它只能用於等值的過濾,不能用於基於範圍的過濾。基本不用!
R-Tree索引,僅支持geometry數據類型,也基本不用!數據庫
至於非主鍵的二級索引,這個實際上問的就是非聚簇索引!非聚簇索引自己就是一顆B+樹,其根節點指向聚簇索引的B+樹,具體的請看這篇文章《MySQL(Innodb)索引的原理》
七、項目用的是 SpringBoot ,你能說下 Spring Boot 與 Spring 的區別嗎?
評註:基礎題,會spring boot的,基本都答的上來。就算沒準備過,當場思考下均可以回答的出來!也是屬於引導題!
回答:
八、SpringBoot 的自動配置是怎麼作的?
評註:此題也是根據你的第七問,進一步提問而得出。
回答:
先答爲何須要自動配置?
顧名思義,自動配置的意義是利用這種模式代替了配置 XML 繁瑣模式。之前使用 Spring MVC ,須要進行配置組件掃描、調度器、視圖解析器等,使用 Spring Boot 自動配置後,只須要添加 MVC 組件便可自動配置所須要的 Bean。全部自動配置的實現都在 spring-boot-autoconfigure 依賴中,包括 Spring MVC 、Data 和其它框架的自動配置。
接着答spring-boot-autoconfigure 依賴的工做原理?
spring-boot-autoconfigure 依賴的工做原理很簡單,經過 @EnableAutoConfiguration 核心註解初始化,並掃描 ClassPath 目錄中自動配置類對應依賴。好比工程中有木有添加 Thymeleaf 的 Starter 組件依賴。若是有,就按按必定規則獲取默認配置並自動初始化所須要的 Bean。
其實還能再繼續答@EnableAutoConfiguration 註解的工做原理!不過篇幅太長,答到上面那個地步就夠了!
九、MyBatis 定義的接口,怎麼找到實現的?
評註:mybatis底層原理題,考察有沒有看過mybatis的原理。博主恰好曾經本身寫過一個mybatis,因此此題恰巧答的上來。
博主心裏活動:"如今校招的都這麼牛逼了麼!"
回答:一共五步
十、Java 內存結構
評註:基礎題,這個應該學JAVA的都會吧!送分題!若是博主沒理解錯應該是在問JVM的內存結構!
回答:JVM內存結構主要有三大塊:堆內存、方法區和棧。堆內存是JVM中最大的一塊由年輕代和老年代組成,而年輕代內存又被分紅三部分,Eden空間、From Survivor空間、To Survivor空間,默認狀況下年輕代按照8:1:1的比例來分配;
方法區存儲類信息、常量、靜態變量等數據,是線程共享的區域,爲與Java堆區分,方法區還有一個別名Non-Heap(非堆);棧又分爲java虛擬機棧和本地方法棧主要用於方法的執行。
十一、對象是否可 GC?
評註:這個問題就是在問,JVM如何判斷對象是否須要被回收!不用答引用計數法,答可達性分析算法就行。
回答:
這個算法的基本思路是經過一些列稱爲「GC Roots」的對象做爲起始點,從這些點開始向下搜索,搜索走過的路徑稱爲引用鏈,當一個對象到GC Roots沒有任何引用鏈相連時,則證實對象須要被回收.
如圖:
上圖中o3,o4對象沒有任何GC Roots可達到,全部這兩個對象不可用了,須要被GC回收
Java可做爲GC Roots的對象包括下面幾種:
十二、Minor GC 和 Full GC
評註:基礎題,會JVM調優的,基本都會!我只是奇怪,怎麼沒問Major GC呢?咱們仍是把Major GC也給答了吧!
回答:
堆內存是JVM中最大的一塊由年輕代和老年代組成。
那麼,從年輕代空間(包括 Eden 和 Survivor 區域)回收內存被稱爲 Minor GC。
Major GC 是清理老年代。
Full GC 是清理整個堆空間—包括年輕代和老年代。
1三、垃圾回收算法
評註:基礎題,博主斗膽猜想,應該是在問垃圾回收算法有哪些。面試官應該沒有耐心去聽你一個個去背算法概念!
回答:
標記-清除算法、標記整理算法、複製算法、分代收集算法
1四、垃圾回收器 G1
評註:上面的題目更深刻的問法。JVM能夠配置不一樣的回收器。好比Serial, Parallel和CMS幾種垃圾回收器。以Serial Collector(串行回收器)爲例,它在在年輕代是一個使用標記-複製算法的回收器。在老年代使用的是標記-清掃-整理算法。
另外,關於G1回收器能夠問的點不少,此題做者沒有描述清楚究竟問的是G1回收器的那個點,就滿回答一下概念吧!
若是是我來問,我就直接給你場景,問你該用哪一種回收器了。直接問回收器,那就比較容易了!
經常使用參數:
*-XX:+UseSerialGC:在新生代和老年代使用串行收集器
-XX:+UseParNewGC:在新生代使用並行收集器
//本身查詢吧,太多了!
回答:
G1 GC是Jdk7的新特性之1、Jdk7+版本均可以自主配置G1做爲JVM GC選項。 G1 將整個堆劃分爲一個個大小相等的小塊(每一塊稱爲一個region),每一塊的內存是連續的,每一個塊也會充當 Eden、Survivor、Old三種角色,可是它們不是固定的,這使得內存使用更加地靈活。以下圖所示
執行垃圾收集時,收集線程在標記階段和應用程序線程併發執行,標記結束後,G1 也就知道哪些區塊基本上是垃圾,存活對象極少,G1 會先從這些區塊下手,由於從這些區塊能很快釋放獲得很大的可用空間,這也是爲何 G1 被取名爲 Garbage-First 的緣由。
1五、項目裏用過 ElasticSearch 和 Hbase,有深刻了解他們的調優技巧嗎?
評註:一個應屆生搭的ElasticSearch 和 Hbase,通常都只是demo級別的,懂基本的CRUD的使用便可!通常不會去深刻了解調優技巧的!這個問題若是答深刻了解過,是給本身挖坑!由於這個問題,答案太廣了!
回答:並無深刻了解過!
1六、Spring RestTemplate 的具體實現
評註:這題問的博主有點懵!若是是我來問,我會先問訪問Rest服務的客戶端這麼多,爲何選Spring RestTemplate?而後纔來原理。這個忽然就冒出一個具體實現,我是有點懵啦!
回答:
其實RestTemplate和sl4fj這種門面框架很像,本質就是在Http的網絡請求中增長一個馬甲,自己並無本身的實現。對此有疑問的,能夠看個人另外一篇
《架構師必備,帶你弄清混亂的JAVA日誌體系!》
底層能夠支持多種httpclient的http訪問,上層爲ClientHttpRequestFactory接口爲,底層以下所示:
那麼RestTemplate則封裝了組裝、發送 HTTP消息,以及解析響應的的底層細節。
答到這個份上能夠了,難道你還要把類之間關係的引用圖,畫出來?太不現實了!
1七、描述下網頁一個 Http 請求,到後端的整個請求過程
評註:基礎題,感受屬於常識題!必會!
回答:
利用DNS進行域名解析 --> 發起TCP的3次握手 --> 創建TCP鏈接後發起http請求 --> 服務器響應http請求,瀏覽器獲得html代碼 --> 瀏覽器解析html代碼,並請求html代碼中的資源(如js、css、圖片等) --> 瀏覽器對頁面進行渲染呈現給用戶
1八、多線程的經常使用方法和接口類及線程池的機制
評註:基礎題,基本會點線程知識的,多多少少都會答點!可是這道題,我感受範圍有點大啊!多是做者沒表述清楚吧!
回答:
經常使用方法:
start,run,sleep,wait,notify,notifyAll,join,isAlive,currentThread,interrupt
經常使用接口類:
Runnable、Callable、Future、FutureTask
線程池的機制:
在面向對象編程中,建立和銷燬對象是很費時間的,由於建立一個對象要獲取內存資源或者其它更多資源。因此提升服務程序效率的一個手段就是儘量減小建立和銷燬對象的次數,因此出現了池化技術!。
簡單的線程池包括以下四個組成部分便可:
1九、總結個人 Java 基礎仍是不錯,可是一些主流的框架源碼仍是處在使用的狀態,須要繼續去看源碼
評註:坦白說,我沒看出來哪些問題體現出主流的框架仍是處在使用的狀態。
20、死鎖
評註:牛客網原題!把緣由一塊兒答了吧!
回答:
死鎖是指兩個或兩個以上的進程在執行過程當中,因爭奪資源而形成的一種互相等待的現象,若無外力做用,它們都將沒法推動下去,若是系統資源充足,進程的資源請求都可以獲得知足,死鎖出現的可能性就很低,不然就會因爭奪有限的資源而陷入死鎖。
產生死鎖的緣由主要是:
2一、本身研究比較新的技術,說下成果!
評註:嗯,凸顯本身的潛力,你們自由發揮!
2二、你有什麼想問的?我就問了下公司那邊的狀況,這個自由發揮!
評註:問問工做內容便可,千萬別問什麼福利啊,加班狀況啊!這種問題,不要在技術面的時候問!
本文就對一面的題目作出了回答,二面的題目,哪天有時間再寫吧!