高級(jí)Java程序員:21道最新Java面試題剖析

高級(jí)Java程序員:21道最新Java面試題剖析

長(zhǎng)沙一度軟件培訓(xùn)      2022-04-19 10:14:01     14

高級(jí)Java程序員:21道最新Java面試題剖析,  縱觀(guān)幾年來(lái)的Java面試題,你會(huì)發(fā)現(xiàn)每家都差不多。你仔細(xì)觀(guān)察就會(huì)發(fā)現(xiàn),HashMap的出現(xiàn)幾率未免也太高了吧!連考察的知識(shí)點(diǎn)都

課程價(jià)格 請(qǐng)咨詢(xún)

上課時(shí)段: 授課校區(qū):

詳細(xì)介紹



  縱觀(guān)幾年來(lái)的Java面試題,你會(huì)發(fā)現(xiàn)每家都差不多。你仔細(xì)觀(guān)察就會(huì)發(fā)現(xiàn),HashMap的出現(xiàn)幾率未免也太高了吧!連考察的知識(shí)點(diǎn)都一樣,什么hash碰撞啊,并發(fā)問(wèn)題??!再比如JVM,無(wú)外乎考內(nèi)存結(jié)構(gòu),GC算法等!因此,如果是為了面試,完全是有套路可以準(zhǔn)備的!記住,基礎(chǔ)再好,也架不住面試官天馬行空的問(wèn),所以刷面試題還是很有必要的!


  面試題解析


  1、Map的底層結(jié)構(gòu)?(HashMap)


  評(píng)注:老題目了,各位面試的人員必須熟記!


  回答:Map是以鍵值對(duì)來(lái)存儲(chǔ)對(duì)象的,它的底層實(shí)際上是數(shù)組和鏈表來(lái)組成的,經(jīng)典的一張圖如下(別人畫(huà)的);

  當(dāng)使用put方法時(shí),先查找出數(shù)組位置是否存在對(duì)象,通過(guò)key.hashcode對(duì)數(shù)組長(zhǎng)度取余;存在,則把里面的鏈表拿出來(lái),判斷鏈表里面是否存在key值與傳遞過(guò)來(lái)的key值一樣的對(duì)象,存在,則把傳遞過(guò)來(lái)的value取代鏈表key對(duì)應(yīng)的value,不存在,則直接通過(guò)鏈表的add()方法加到鏈表后面;


  當(dāng)使用get方法時(shí),先查找出數(shù)組位置是否存在對(duì)象,通過(guò)key.hashcode對(duì)數(shù)組長(zhǎng)度取余;如果不存在,則返回為空,如果存在,則遍歷鏈表,判斷鏈表里面是否存在key值與傳遞過(guò)來(lái)的key值一樣的對(duì)象,存在,則把key值對(duì)應(yīng)的value取出返回,不存在,則返回為空;


  2、線(xiàn)程安全的Map(concurrentHashMap)簡(jiǎn)單的說(shuō)了下這兩1.7和1.8的區(qū)別,本想問(wèn)下要不要深入的講下(源碼級(jí)別),結(jié)果面試官說(shuō)不用了。


  評(píng)注:老題目了,如果有時(shí)間,再去了解一下,解決HashMap線(xiàn)程安全的各種方法,以及原理!此題只能大概回答一下結(jié)構(gòu)的變化,因?yàn)槠渲械膶?shí)現(xiàn)代碼都變了,細(xì)說(shuō)可以說(shuō)很久,估計(jì)面試官也沒(méi)時(shí)間聽(tīng)!


  回答:


  jdk1.7中采用Segment+HashEntry的方式進(jìn)行實(shí)現(xiàn),結(jié)構(gòu)如下:

  Segment數(shù)組的意義就是將一個(gè)大的table分割成多個(gè)小的table來(lái)進(jìn)行加鎖,而每一個(gè)Segment元素存儲(chǔ)的是HashEntry數(shù)組+鏈表,這個(gè)和HashMap的數(shù)據(jù)存儲(chǔ)結(jié)構(gòu)一樣


  而jdk1.8中則


  去除Segment+HashEntry+Unsafe的實(shí)現(xiàn),


  改為Synchronized+CAS+Node+Unsafe的實(shí)現(xiàn)


  其結(jié)構(gòu)圖如下:

  如上圖所示,取消了Segment字段,數(shù)組中存儲(chǔ)的就是Node。它與HashMap中的HashEntry定義很相似,但是有一些差別。它對(duì)value和next屬性設(shè)置了volatile同步鎖,它不允許調(diào)用setValue方法直接改變Node的value域。


  另外,將原先table數(shù)組+單向鏈表的數(shù)據(jù)結(jié)構(gòu),變更為table數(shù)組+單向鏈表+紅黑樹(shù)的結(jié)構(gòu),在hash碰撞過(guò)多的情況下會(huì)將鏈表轉(zhuǎn)化成紅黑樹(shù)。


  3、項(xiàng)目MySQL的數(shù)據(jù)量和并發(fā)量有多大?


  評(píng)注:此題為走向題,你的回答不同,后面問(wèn)題走向就變了。


  關(guān)于容量:單表行數(shù)超過(guò)500萬(wàn)行或者單表容量超過(guò)2GB,此時(shí)就要答分庫(kù)分表的中間件了!那后面題目的走向就變?yōu)閙ycat、sharing-jdbc等分庫(kù)分表中間件的底層原理了!


  關(guān)于并發(fā)量:如果并發(fā)數(shù)過(guò)1200,此時(shí)就要答利用MQ或者redis等中間件,作為補(bǔ)償措施,而不能直接操作數(shù)據(jù)庫(kù)。那后面的題目走向就是redis、mq的原理了!


  介于面試者還是一個(gè)應(yīng)屆生,我斗膽猜測(cè)面試者是這么答的


  回答:數(shù)據(jù)量估計(jì)就三四百萬(wàn)吧,并發(fā)量就五六百左右!


  4、你對(duì)數(shù)據(jù)庫(kù)了解多少?


  評(píng)注:因?yàn)槟愦鸬臄?shù)據(jù)量和并發(fā)量不大,因此中間件這塊沒(méi)啥好問(wèn)的。因此,題目走向變?yōu)閿?shù)據(jù)庫(kù)底層!另外,此題為引導(dǎo)題,面試官在給你機(jī)會(huì)引向你最擅長(zhǎng)的方面!


  回答:了解常見(jiàn)數(shù)據(jù)庫(kù)調(diào)優(yōu)方法,索引優(yōu)化等!


  5、你說(shuō)下數(shù)據(jù)庫(kù)的索引實(shí)現(xiàn)和非主鍵的二級(jí)索引


  評(píng)注:這個(gè)問(wèn)題是根據(jù)上面,你的回答而問(wèn)出來(lái)的!記得引向自己最擅長(zhǎng)的數(shù)據(jù)庫(kù)基礎(chǔ)知識(shí)!默認(rèn)是回答mysql數(shù)據(jù)庫(kù)的


  回答:


  從數(shù)據(jù)結(jié)構(gòu)角度:


  B-Tree索引,數(shù)據(jù)結(jié)構(gòu)就是一顆B+樹(shù)。


  Hash索引,Hash索引比較的是進(jìn)行Hash運(yùn)算之后的Hash值,所以它只能用于等值的過(guò)濾,不能用于基于范圍的過(guò)濾。基本不用!


  R-Tree索引,僅支持geometry數(shù)據(jù)類(lèi)型,也基本不用!


  至于非主鍵的二級(jí)索引,這個(gè)實(shí)際上問(wèn)的就是非聚簇索引!非聚簇索引本身就是一顆B+樹(shù),其根節(jié)點(diǎn)指向聚簇索引的B+樹(shù)。


  6、項(xiàng)目用的是SpringBoot,你能說(shuō)下SpringBoot與Spring的區(qū)別嗎?


  評(píng)注:基礎(chǔ)題,會(huì)springboot的,基本都答的上來(lái)。就算沒(méi)準(zhǔn)備過(guò),當(dāng)場(chǎng)思考下都可以回答的出來(lái)!也是屬于引導(dǎo)題!


  回答:


  SpringBoot可以建立獨(dú)立的Spring應(yīng)用程序;


  內(nèi)嵌了如Tomcat,Jetty和Undertow這樣的容器,也就是說(shuō)可以直接跑起來(lái),用不著再做部署工作了。


  無(wú)需再像Spring那樣搞一堆繁瑣的xml文件的配置;


  可以自動(dòng)配置Spring;


  提供了一些現(xiàn)有的功能,如量度工具,表單數(shù)據(jù)驗(yàn)證以及一些外部配置這樣的一些第三方功能;


  提供的POM可以簡(jiǎn)化Maven的配置


  7、SpringBoot的自動(dòng)配置是怎么做的?


  評(píng)注:此題也是根據(jù)你的第七問(wèn),進(jìn)一步提問(wèn)而得出。


  回答:


  先答為什么需要自動(dòng)配置?


  顧名思義,自動(dòng)配置的意義是利用這種模式代替了配置XML繁瑣模式。以前使用SpringMVC,需要進(jìn)行配置組件掃描、調(diào)度器、視圖解析器等,使用SpringBoot自動(dòng)配置后,只需要添加MVC組件即可自動(dòng)配置所需要的Bean。所有自動(dòng)配置的實(shí)現(xiàn)都在spring-boot-autoconfigure依賴(lài)中,包括SpringMVC、Data和其它框架的自動(dòng)配置。


  接著答spring-boot-autoconfigure依賴(lài)的工作原理?


  spring-boot-autoconfigure依賴(lài)的工作原理很簡(jiǎn)單,通過(guò)@EnableAutoConfiguration核心注解初始化,并掃描ClassPath目錄中自動(dòng)配置類(lèi)對(duì)應(yīng)依賴(lài)。比如工程中有木有添加Thymeleaf的Starter組件依賴(lài)。如果有,就按按一定規(guī)則獲取默認(rèn)配置并自動(dòng)初始化所需要的Bean。


  其實(shí)還能再繼續(xù)答@EnableAutoConfiguration注解的工作原理!不過(guò)篇幅太長(zhǎng),答到上面那個(gè)地步就夠了!


  8、MyBatis定義的接口,怎么找到實(shí)現(xiàn)的?


  評(píng)注:mybatis底層原理題,考察有沒(méi)有看過(guò)mybatis的原理。博主剛好曾經(jīng)自己寫(xiě)過(guò)一個(gè)mybatis,所以此題恰巧答的上來(lái)。


  博主內(nèi)心活動(dòng):"現(xiàn)在校招的都這么牛逼了么!"


  回答:一共五步


  1.Mapper接口在初始SqlSessionFactory注冊(cè)的。


  2.Mapper接口注冊(cè)在了名為MapperRegistry類(lèi)的HashMap中,key=Mapperclassvalue=創(chuàng)建當(dāng)前Mapper的工廠(chǎng)。


  3.Mapper注冊(cè)之后,可以從SqlSession中g(shù)et


  4.SqlSession.getMapper運(yùn)用了JDK動(dòng)態(tài)代理,產(chǎn)生了目標(biāo)Mapper接口的代理對(duì)象。


  5.動(dòng)態(tài)代理的代理類(lèi)是MapperProxy,這里邊最終完成了增刪改查方法的調(diào)用。


  9、Java內(nèi)存結(jié)構(gòu)


  評(píng)注:基礎(chǔ)題,這個(gè)應(yīng)該學(xué)JAVA的都會(huì)吧!送分題!如果博主沒(méi)理解錯(cuò)應(yīng)該是在問(wèn)JVM的內(nèi)存結(jié)構(gòu)!


  回答:JVM內(nèi)存結(jié)構(gòu)主要有三大塊:堆內(nèi)存、方法區(qū)和棧。堆內(nèi)存是JVM中最大的一塊由年輕代和老年代組成,而年輕代內(nèi)存又被分成三部分,Eden空間、FromSurvivor空間、ToSurvivor空間,默認(rèn)情況下年輕代按照8:1:1的比例來(lái)分配;


  方法區(qū)存儲(chǔ)類(lèi)信息、常量、靜態(tài)變量等數(shù)據(jù),是線(xiàn)程共享的區(qū)域,為與Java堆區(qū)分,方法區(qū)還有一個(gè)別名Non-Heap(非堆);棧又分為java虛擬機(jī)棧和本地方法棧主要用于方法的執(zhí)行。


  10、對(duì)象是否可GC?


  評(píng)注:這個(gè)問(wèn)題就是在問(wèn),JVM如何判斷對(duì)象是否需要被回收!不用答引用計(jì)數(shù)法,答可達(dá)性分析算法就行。


  回答:


  這個(gè)算法的基本思路是通過(guò)一些列稱(chēng)為“GCRoots”的對(duì)象作為起始點(diǎn),從這些點(diǎn)開(kāi)始向下搜索,搜索走過(guò)的路徑稱(chēng)為引用鏈,當(dāng)一個(gè)對(duì)象到GCRoots沒(méi)有任何引用鏈相連時(shí),則證明對(duì)象需要被回收.


  如圖:

  上圖中o3,o4對(duì)象沒(méi)有任何GCRoots可達(dá)到,所有這兩個(gè)對(duì)象不可用了,需要被GC回收


  Java可作為GCRoots的對(duì)象包括下面幾種:


  虛擬機(jī)棧中引用的對(duì)象


  方法區(qū)中類(lèi)靜態(tài)屬性引用的對(duì)象


  方法區(qū)中產(chǎn)量引用的對(duì)象


  本地方法棧中JNI引用的對(duì)象


  11、MinorGC和FullGC


  評(píng)注:基礎(chǔ)題,會(huì)JVM調(diào)優(yōu)的,基本都會(huì)!我只是奇怪,怎么沒(méi)問(wèn)MajorGC呢?我們還是把MajorGC也給答了吧!


  回答:


  堆內(nèi)存是JVM中最大的一塊由年輕代和老年代組成。


  那么,從年輕代空間(包括Eden和Survivor區(qū)域)回收內(nèi)存被稱(chēng)為MinorGC。


  MajorGC是清理老年代。


  FullGC是清理整個(gè)堆空間—包括年輕代和老年代。


  12、垃圾回收算法


  評(píng)注:基礎(chǔ)題,博主斗膽猜測(cè),應(yīng)該是在問(wèn)垃圾回收算法有哪些。面試官應(yīng)該沒(méi)有耐心去聽(tīng)你一個(gè)個(gè)去背算法概念!


  回答:


  標(biāo)記-清除算法、標(biāo)記整理算法、復(fù)制算法、分代收集算法


  13、垃圾回收器G1


  評(píng)注:上面的題目更深入的問(wèn)法。JVM可以配置不同的回收器。比如Serial,Parallel和CMS幾種垃圾回收器。以SerialCollector(串行回收器)為例,它在在年輕代是一個(gè)使用標(biāo)記-復(fù)制算法的回收器。在老年代使用的是標(biāo)記-清掃-整理算法。


  另外,關(guān)于G1回收器可以問(wèn)的點(diǎn)很多,此題作者沒(méi)有描述清楚究竟問(wèn)的是G1回收器的那個(gè)點(diǎn),就滿(mǎn)回答一下概念吧!


  如果是我來(lái)問(wèn),我就直接給你場(chǎng)景,問(wèn)你該用哪種回收器了。直接問(wèn)回收器,那就比較容易了!


  常用參數(shù):


  -XX:+UseSerialGC:在新生代和老年代使用串行收集器


  -XX:+UseParNewGC:在新生代使用并行收集器


  //自己查詢(xún)吧,太多了!


  回答:


  G1GC是Jdk7的新特性之一、Jdk7+版本都可以自主配置G1作為JVMGC選項(xiàng)。G1將整個(gè)堆劃分為一個(gè)個(gè)大小相等的小塊(每一塊稱(chēng)為一個(gè)region),每一塊的內(nèi)存是連續(xù)的,每個(gè)塊也會(huì)充當(dāng)Eden、Survivor、Old三種角色,但是它們不是固定的,這使得內(nèi)存使用更加地靈活。如下圖所示

  執(zhí)行垃圾收集時(shí),收集線(xiàn)程在標(biāo)記階段和應(yīng)用程序線(xiàn)程并發(fā)執(zhí)行,標(biāo)記結(jié)束后,G1也就知道哪些區(qū)塊基本上是垃圾,存活對(duì)象極少,G1會(huì)先從這些區(qū)塊下手,因?yàn)閺倪@些區(qū)塊能很快釋放得到很大的可用空間,這也是為什么G1被取名為Garbage-First的原因。


  14、項(xiàng)目里用過(guò)ElasticSearch和Hbase,有深入了解他們的調(diào)優(yōu)技巧嗎?


  評(píng)注:一個(gè)應(yīng)屆生搭的ElasticSearch和Hbase,一般都只是demo級(jí)別的,懂基本的CRUD的使用即可!一般不會(huì)去深入了解調(diào)優(yōu)技巧的!這個(gè)問(wèn)題如果答深入了解過(guò),是給自己挖坑!因?yàn)檫@個(gè)問(wèn)題,答案太廣了!


  回答:并沒(méi)有深入了解過(guò)!


  15、SpringRestTemplate的具體實(shí)現(xiàn)


  評(píng)注:這題問(wèn)的博主有點(diǎn)懵!如果是我來(lái)問(wèn),我會(huì)先問(wèn)訪(fǎng)問(wèn)Rest服務(wù)的客戶(hù)端這么多,為什么選SpringRestTemplate?然后才來(lái)原理。這個(gè)突然就冒出一個(gè)具體實(shí)現(xiàn),我是有點(diǎn)懵啦!


  回答:


  其實(shí)RestTemplate和sl4fj這種門(mén)面框架很像,本質(zhì)就是在Http的網(wǎng)絡(luò)請(qǐng)求中增加一個(gè)馬甲,本身并沒(méi)有自己的實(shí)現(xiàn)。


  底層可以支持多種httpclient的http訪(fǎng)問(wèn),上層為ClientHttpRequestFactory接口類(lèi),底層如下所示:

  那么RestTemplate則封裝了組裝、發(fā)送HTTP消息,以及解析響應(yīng)的底層細(xì)節(jié)。


  答到這個(gè)份上可以了,難道你還要把類(lèi)之間關(guān)系的引用圖,畫(huà)出來(lái)?太不現(xiàn)實(shí)了!


  16、描述下網(wǎng)頁(yè)一個(gè)Http請(qǐng)求,到后端的整個(gè)請(qǐng)求過(guò)程


  評(píng)注:基礎(chǔ)題,感覺(jué)屬于常識(shí)題!必會(huì)!


  回答:


  利用DNS進(jìn)行域名解析-->發(fā)起TCP的3次握手-->建立TCP連接后發(fā)起http請(qǐng)求-->服務(wù)器響應(yīng)http請(qǐng)求,瀏覽器得到html代碼-->瀏覽器解析html代碼,并請(qǐng)求html代碼中的資源(如js、css、圖片等)-->瀏覽器對(duì)頁(yè)面進(jìn)行渲染呈現(xiàn)給用戶(hù)


  17、多線(xiàn)程的常用方法和接口類(lèi)及線(xiàn)程池的機(jī)制


  評(píng)注:基礎(chǔ)題,基本會(huì)點(diǎn)線(xiàn)程知識(shí)的,多多少少都會(huì)答點(diǎn)!但是這道題,我感覺(jué)范圍有點(diǎn)大啊!可能是作者沒(méi)表述清楚吧!


  回答:


  常用方法:


  start,run,sleep,wait,notify,notifyAll,join,isAlive,currentThread,interrupt


  常用接口類(lèi):


  Runnable、Callable、Future、FutureTask


  線(xiàn)程池的機(jī)制:


  在面向?qū)ο缶幊讨?,?chuàng)建和銷(xiāo)毀對(duì)象是很費(fèi)時(shí)間的,因?yàn)閯?chuàng)建一個(gè)對(duì)象要獲取內(nèi)存資源或者其它更多資源。所以提高服務(wù)程序效率的一個(gè)手段就是盡可能減少創(chuàng)建和銷(xiāo)毀對(duì)象的次數(shù),所以出現(xiàn)了池化技術(shù)!。


  簡(jiǎn)單的線(xiàn)程池包括如下四個(gè)組成部分即可:


  線(xiàn)程池管理器(ThreadPoolManager):用于創(chuàng)建并管理線(xiàn)程池


  工作線(xiàn)程(WorkThread):線(xiàn)程池中線(xiàn)程


  任務(wù)接口(Task):每個(gè)任務(wù)必須實(shí)現(xiàn)的接口,以供工作線(xiàn)程調(diào)度任務(wù)的執(zhí)行


  任務(wù)隊(duì)列:用于存放沒(méi)有處理的任務(wù)。提供一種緩沖機(jī)制


  18、總結(jié)我的Java基礎(chǔ)還是不錯(cuò),但是一些主流的框架源碼還是處在使用的狀態(tài),需要繼續(xù)去看源碼


  評(píng)注:坦白說(shuō),我沒(méi)看出來(lái)哪些問(wèn)題體現(xiàn)出主流的框架還是處在使用的狀態(tài)。


  19、死鎖


  回答:


  死鎖是指兩個(gè)或兩個(gè)以上的進(jìn)程在執(zhí)行過(guò)程中,因爭(zhēng)奪資源而造成的一種互相等待的現(xiàn)象,若無(wú)外力作用,它們都將無(wú)法推進(jìn)下去,如果系統(tǒng)資源充足,進(jìn)程的資源請(qǐng)求都能夠得到滿(mǎn)足,死鎖出現(xiàn)的可能性就很低,否則就會(huì)因爭(zhēng)奪有限的資源而陷入死鎖。


  產(chǎn)生死鎖的原因主要是:


 ?。?)因?yàn)橄到y(tǒng)資源不足。


 ?。?)進(jìn)程運(yùn)行推進(jìn)的順序不合適。


  (3)資源分配不當(dāng)?shù)取?/p>


  20、自己研究比較新的技術(shù),說(shuō)下成果!


  評(píng)注:嗯,凸顯自己的潛力,大家自由發(fā)揮!


  21、你有什么想問(wèn)的?我就問(wèn)了下公司那邊的情況,這個(gè)自由發(fā)揮!


  以上就是長(zhǎng)沙一度軟件培訓(xùn)java培訓(xùn)機(jī)構(gòu)小編介紹的“高級(jí)Java程序員:21道最新Java面試題剖析”的內(nèi)容,希望對(duì)大家有幫助,更多java最新資訊請(qǐng)繼續(xù)關(guān)注長(zhǎng)沙一度軟件培訓(xùn)java培訓(xùn)機(jī)構(gòu)官網(wǎng),每天會(huì)有精彩內(nèi)容分享與你。

Java面試題

培訓(xùn)啦提醒您:交易時(shí)請(qǐng)核實(shí)對(duì)方資質(zhì),對(duì)于過(guò)大宣傳或承諾需謹(jǐn)慎!任何要求預(yù)付定金、匯款等方式均存在風(fēng)險(xiǎn),謹(jǐn)防上當(dāng)。