(2025年)細選道Java技術(shù)面試題并有答案(包含部分阿里和華為的面試題)_第1頁
(2025年)細選道Java技術(shù)面試題并有答案(包含部分阿里和華為的面試題)_第2頁
(2025年)細選道Java技術(shù)面試題并有答案(包含部分阿里和華為的面試題)_第3頁
(2025年)細選道Java技術(shù)面試題并有答案(包含部分阿里和華為的面試題)_第4頁
(2025年)細選道Java技術(shù)面試題并有答案(包含部分阿里和華為的面試題)_第5頁
已閱讀5頁,還剩16頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

(2025年)細選道Java技術(shù)面試題并有答案(包含部分阿里和華為的面試題)1.說說Java中ArrayList和LinkedList的底層結(jié)構(gòu)及適用場景?ArrayList底層基于動態(tài)數(shù)組實現(xiàn),初始容量為10(JDK8后),當(dāng)元素超過容量時觸發(fā)擴容,擴容因子為1.5倍(新容量=舊容量+舊容量/2),通過Arrays.copyOf復(fù)制數(shù)組。支持O(1)時間的隨機訪問(通過索引定位),但插入/刪除元素(尤其是中間位置)需要移動后續(xù)元素,時間復(fù)雜度O(n)。LinkedList底層基于雙向鏈表(JDK1.6前為雙向循環(huán)鏈表),每個節(jié)點保存前驅(qū)和后繼指針。插入/刪除元素只需修改相鄰節(jié)點的指針,時間復(fù)雜度O(1)(已知節(jié)點位置時),但隨機訪問需要遍歷鏈表,時間復(fù)雜度O(n)。適用場景:ArrayList適合頻繁讀取、少量增刪的場景(如數(shù)據(jù)展示列表);LinkedList適合頻繁增刪、少量讀取的場景(如隊列、棧的實現(xiàn))。阿里面試中曾考察過“高并發(fā)下ArrayList擴容導(dǎo)致的線程安全問題”,需注意其非線程安全特性,多線程環(huán)境建議使用CopyOnWriteArrayList。2.如何理解Java的泛型擦除?編譯期和運行期泛型信息如何保留?泛型是JDK1.5引入的類型安全機制,本質(zhì)是編譯期的語法糖。編譯時編譯器會擦除所有泛型類型信息(如List<String>變?yōu)長ist),僅保留原始類型(RawType),但會在必要位置插入類型轉(zhuǎn)換代碼(如取出元素時轉(zhuǎn)為String)。編譯期泛型信息保留在Class文件的屬性表中(通過Signature屬性),可通過反射獲?。ㄈ鏣ypeVariable、ParameterizedType等接口)。運行期若泛型類型為具體類(非通配符),可通過反射獲取實際類型參數(shù)(如通過getGenericSuperclass()獲取父類的泛型參數(shù))。華為面試中曾考察“自定義注解如何獲取方法參數(shù)的泛型類型”,需結(jié)合Type接口和反射API實現(xiàn)。3.詳細說明synchronized和ReentrantLock的區(qū)別及各自適用場景?synchronized是JVM層面的關(guān)鍵字,依賴monitor對象實現(xiàn)鎖。JDK6后引入偏向鎖、輕量級鎖、自旋鎖等優(yōu)化,減少了線程阻塞的開銷。特性包括:可重入(同一線程可多次獲取同一鎖)、非公平性(默認不保證等待線程的順序)、隱式釋放(同步塊/方法結(jié)束自動釋放)。ReentrantLock是java.util.concurrent包下的類,基于AQS(AbstractQueuedSynchronizer)實現(xiàn)。支持可重入、可公平/非公平(構(gòu)造函數(shù)指定)、可中斷(lockInterruptibly())、超時獲?。╰ryLock(long,TimeUnit))、條件變量(Condition)等高級功能。適用場景:簡單同步需求(如方法同步)用synchronized(代碼簡潔);需要可中斷、超時、公平鎖或多個條件變量時用ReentrantLock(如生產(chǎn)者-消費者模型中精準(zhǔn)喚醒特定線程)。阿里面試曾問“ReentrantLock的tryLock在高并發(fā)下的性能優(yōu)勢”,需說明其非阻塞特性避免線程掛起/喚醒的開銷。4.簡述JVM類加載的全過程,雙親委派模型的作用及破壞場景?類加載過程分為加載、驗證、準(zhǔn)備、解析、初始化五個階段:-加載:通過類加載器將class文件字節(jié)碼加載到方法區(qū),提供對應(yīng)的Class對象。-驗證:校驗字節(jié)碼格式(如魔數(shù)0xCAFEBABE)、語義(如是否繼承final類)等,確保安全。-準(zhǔn)備:為類靜態(tài)變量分配內(nèi)存并設(shè)置默認值(如int默認0,引用默認null),常量(staticfinal)直接賦值。-解析:將符號引用(如類名、方法名)替換為直接引用(內(nèi)存地址)。-初始化:執(zhí)行類構(gòu)造器<clinit>()方法(靜態(tài)變量賦值和靜態(tài)代碼塊的合并),觸發(fā)時機包括new對象、調(diào)用靜態(tài)方法/變量(非final)、反射獲取類等。雙親委派模型:類加載器(啟動類、擴展類、應(yīng)用類)收到加載請求時,先委托父類加載器加載,父類無法加載時再自己加載。作用是避免類重復(fù)加載(如java.lang.Object只會被啟動類加載器加載一次),防止核心類被篡改(如自定義java.lang.String會被父類加載器攔截)。破壞場景:①熱部署(如Tomcat):每個Web應(yīng)用有獨立的類加載器,允許同名類不同版本共存。②線程上下文類加載器(如JDBC):父類加載器(啟動類)需要加載子類加載器(應(yīng)用類)的實現(xiàn)類(如MySQL的Driver),通過Thread.currentThread().getContextClassLoader()打破委派。③動態(tài)代理(如ASM提供字節(jié)碼):自定義類加載器直接加載提供的字節(jié)碼。5.如何分析Java內(nèi)存泄漏?常用工具及具體步驟?內(nèi)存泄漏指對象不再被使用但未被GC回收(通常因長生命周期對象持有短生命周期對象的引用)。常見場景:緩存未設(shè)置過期時間、靜態(tài)集合未清理、監(jiān)聽器/回調(diào)未注銷、ThreadLocal未remove()。分析工具及步驟:-日志監(jiān)控:通過-XX:+PrintGCDetails打印GC日志,觀察FullGC頻率和內(nèi)存占用趨勢(如老年代持續(xù)增長)。-堆轉(zhuǎn)儲(HeapDump):使用jmap-dump:format=b,file=heap.bin<pid>或JVM參數(shù)-XX:+HeapDumpOnOutOfMemoryError提供堆文件。-分析工具:①EclipseMAT(MemoryAnalyzerTool):通過OQL查詢大對象,查看DominatorTree(對象占用內(nèi)存占比),檢測LeakSuspects(常見泄漏模式)。②JProfiler:可視化分析對象引用鏈,定位未釋放的引用(如靜態(tài)Map中殘留的對象)。③阿里Arthas:通過heapdump命令提供堆文件,或使用ognl表達式實時查看對象數(shù)量(如ognl'map=@com.example.Cache@map,map.size()')。華為面試中曾考察“生產(chǎn)環(huán)境無法停機時如何快速定位內(nèi)存泄漏”,需結(jié)合Arthas的在線診斷功能,通過watch命令監(jiān)控關(guān)鍵方法的參數(shù)/返回值,或用sc/ss命令查找類的實例數(shù)量。6.詳細說明Spring循環(huán)依賴的解決機制,構(gòu)造器注入為何無法解決?Spring通過三級緩存解決單例Bean的循環(huán)依賴(原型Bean和構(gòu)造器注入無法解決)。三級緩存定義在DefaultSingletonBeanRegistry中:-singletonObjects(一級緩存):保存已初始化完成的單例Bean。-earlySingletonObjects(二級緩存):保存已實例化但未初始化的早期Bean(用于解決AOP代理問題)。-singletonFactories(三級緩存):保存ObjectFactory(創(chuàng)建早期Bean的工廠,用于提供代理對象)。解決流程(以A依賴B,B依賴A為例):①創(chuàng)建A:調(diào)用構(gòu)造器實例化A,將A的ObjectFactory(()->getEarlyBeanReference(beanName,mbd,bean))放入三級緩存。②A注入B:觸發(fā)B的創(chuàng)建,B實例化后將其ObjectFactory放入三級緩存。③B注入A:從三級緩存獲取A的ObjectFactory,提供早期A(可能是代理對象),放入二級緩存并移除三級緩存的工廠。④B完成初始化,放入一級緩存。⑤A獲取B(已在一級緩存),完成初始化,放入一級緩存。構(gòu)造器注入無法解決的原因:構(gòu)造器注入發(fā)生在實例化階段(Bean未創(chuàng)建完成),此時三級緩存中沒有對應(yīng)的ObjectFactory(工廠需在實例化后才創(chuàng)建),導(dǎo)致無法提前暴露早期Bean。阿里面試曾問“如果A和B都是@Async注解的Bean(需要代理),循環(huán)依賴是否仍能解決”,答案是可以,因為三級緩存的ObjectFactory會調(diào)用getEarlyBeanReference提供代理,確保早期Bean是代理對象。7.比較MySQL的InnoDB和MyISAM存儲引擎的差異,生產(chǎn)環(huán)境如何選擇?核心差異:-事務(wù)支持:InnoDB支持ACID事務(wù)(通過redo/undo日志),MyISAM不支持。-鎖粒度:InnoDB支持行鎖(基于索引)和表鎖,MyISAM僅支持表鎖(插入/更新時全表鎖定)。-索引類型:InnoDB主鍵索引(聚簇索引)存儲數(shù)據(jù),二級索引存儲主鍵值;MyISAM非聚簇索引,索引文件和數(shù)據(jù)文件分離。-外鍵支持:InnoDB支持外鍵約束,MyISAM不支持。-統(tǒng)計行數(shù):InnoDB的COUNT()需掃描索引(或全表),MyISAM維護全局行數(shù)計數(shù)器(O(1)時間)。生產(chǎn)選擇:-需事務(wù)、高并發(fā)寫(如訂單系統(tǒng))選InnoDB;-只讀/寫少讀多(如日志表、字典表)可選MyISAM(但MySQL8.0已廢棄);-需外鍵約束(如關(guān)聯(lián)表)必須選InnoDB。華為面試中曾考察“高并發(fā)下InnoDB行鎖失效場景”,需注意:無索引條件更新會升級為表鎖;索引字段類型不匹配(如varchar用int查詢)導(dǎo)致全表掃描,行鎖變表鎖。8.分布式鎖的實現(xiàn)方案(Redis和ZooKeeper),各自優(yōu)缺點及避坑點?Redis方案:通過setkeyvalueNXEXtimeout原子命令獲取鎖(NX保證只有一個客戶端能設(shè)置,EX防止死鎖)。釋放鎖時需校驗value(避免誤刪其他客戶端的鎖),使用Lua腳本保證原子性(ifredis.call('get',KEYS[1])==ARGV[1]thenredis.call('del',KEYS[1])end)。ZooKeeper方案:創(chuàng)建臨時順序節(jié)點(如/lock/seq-),客戶端獲取最小節(jié)點為鎖持有者,其他節(jié)點監(jiān)聽前一節(jié)點的刪除事件(避免驚群效應(yīng))。鎖自動釋放(會話超時或客戶端斷開時臨時節(jié)點刪除)。優(yōu)缺點對比:-Redis:性能高(單節(jié)點QPS約10萬),但主從切換可能導(dǎo)致鎖丟失(未同步到從節(jié)點時主節(jié)點宕機);-ZooKeeper:強一致性(基于ZAB協(xié)議),鎖可靠性高,但性能較低(QPS約1萬)。避坑點:-Redis:鎖超時時間需大于業(yè)務(wù)執(zhí)行時間,可通過“看門狗”機制(后臺線程自動續(xù)期)避免鎖提前釋放;-ZooKeeper:避免創(chuàng)建過多臨時節(jié)點(影響性能),會話超時時間需合理設(shè)置(過短易誤釋放,過長導(dǎo)致死鎖)。阿里面試曾問“Redlock(紅鎖)的爭議及改進方案”,需說明Redlock假設(shè)多個獨立Redis實例,通過多數(shù)派獲取鎖,但MartinKleppmann指出其在時鐘漂移場景下不可靠,改進建議是結(jié)合租約(Lease)機制或使用ZooKeeper。9.如何設(shè)計一個高并發(fā)的秒殺系統(tǒng)?需考慮哪些技術(shù)點?核心設(shè)計點:-流量攔截:①前端限流:按鈕防重復(fù)點擊(倒計時禁用)、驗證碼(防止腳本刷單);②網(wǎng)關(guān)層:Nginx限流(limit_req/limit_conn)、用戶鑒權(quán)(Token校驗);③業(yè)務(wù)層:預(yù)校驗(庫存是否>0、用戶是否已參與),減少數(shù)據(jù)庫壓力。-庫存優(yōu)化:①緩存預(yù)熱:活動前將庫存加載到Redis(如stock:1001=100),扣減庫存用Lua腳本(保證原子性:ifredis.call('get',KEYS[1])>0thenredis.call('decr',KEYS[1])return1elsereturn0end);②數(shù)據(jù)庫異步更新:緩存扣減成功后,將訂單信息寫入消息隊列(如RocketMQ),異步落庫(避免事務(wù)阻塞)。-分布式事務(wù):訂單創(chuàng)建、庫存扣減、支付回調(diào)需保證一致性,可使用Seata的AT模式(自動提供回滾日志)或TCC模式(自定義try/confirm/cancel)。-高可用:數(shù)據(jù)庫主從復(fù)制+讀寫分離,Redis哨兵/Cluster模式,應(yīng)用層多實例部署(K8s負載均衡)。華為面試中曾考察“秒殺場景下超賣問題的解決”,關(guān)鍵是保證庫存扣減的原子性(RedisLua腳本或數(shù)據(jù)庫樂觀鎖:updatestocksetcount=count-1whereid=1001andcount>0)。10.說說JVM垃圾回收器的演進(JDK8到JDK17),G1和ZGC的核心區(qū)別?JDK8默認使用ParallelScavenge(新生代)+ParallelOld(老年代);JDK9默認G1;JDK11引入ZGC;JDK17移除CMS。G1(Garbage-First):-分代:邏輯分代(Region劃分為Eden/Survivor/Old),物理不連續(xù);-目標(biāo):控制停頓時間(-XX:MaxGCPauseMillis),優(yōu)先回收垃圾多的Region(Garbage-First);-算法:標(biāo)記-復(fù)制(新生代)、標(biāo)記-整理(老年代);-停頓:STW時間可控(毫秒級),但大內(nèi)存(>16GB)下效率下降。ZGC:-分代:無分代(統(tǒng)一Region),支持NUMA架構(gòu);-算法:標(biāo)記-復(fù)制(使用顏色指針和讀屏障);-停頓:STW時間<10ms(與堆大小無關(guān),支持TB級堆);-優(yōu)化:并發(fā)標(biāo)記/轉(zhuǎn)移/重映射,僅在初始標(biāo)記和最終標(biāo)記有短暫STW。核心區(qū)別:G1側(cè)重停頓時間控制,適合大內(nèi)存(4-16GB);ZGC側(cè)重低延遲,適合超大型堆(4TB+)。阿里面試曾問“ZGC的讀屏障如何實現(xiàn)”,需說明讀屏障在訪問對象引用時動態(tài)更新指針(顏色指針的Marked0/Marked1/Remapped位),避免STW期間掃描所有對象。11.MyBatis的一級緩存和二級緩存的區(qū)別,如何避免緩存擊穿?一級緩存(SqlSession級):默認開啟,保存在BaseExecutor的localCache中。同一SqlSession內(nèi)執(zhí)行相同查詢(相同statementId、參數(shù)、分頁)會直接返回緩存結(jié)果。SqlSession關(guān)閉/提交或執(zhí)行增刪改操作時緩存失效。二級緩存(Mapper級):需手動開啟(<cache/>標(biāo)簽),保存在SqlSessionFactory層面。多個SqlSession共享緩存(需序列化對象),失效策略(LRU、FIFO)可配置。緩存擊穿:熱點數(shù)據(jù)緩存失效時大量請求直接查數(shù)據(jù)庫。MyBatis二級緩存可通過設(shè)置合理的過期時間(flushInterval),或結(jié)合Redis等分布式緩存(MyBatis作為二級緩存的裝飾器)。華為面試曾考察“MyBatis二級緩存的臟讀問題”,需注意:多數(shù)據(jù)源場景下(如主從庫),主庫更新后從庫未同步時,二級緩存可能返回舊數(shù)據(jù),解決方案是禁用二級緩存或使用Cache-Aside模式(先更新數(shù)據(jù)庫,再刪除緩存)。12.詳細說明TCP三次握手和四次揮手的過程,TIME_WAIT狀態(tài)的作用及優(yōu)化?三次握手:①客戶端發(fā)送SYN=1,seq=x(連接請求);②服務(wù)器回復(fù)SYN=1,ACK=1,seq=y,ack=x+1(確認請求,同步自己的seq);③客戶端發(fā)送ACK=1,seq=x+1,ack=y+1(確認服務(wù)器的確認)。四次揮手:①客戶端發(fā)送FIN=1,seq=u(關(guān)閉請求);②服務(wù)器回復(fù)ACK=1,seq=v,ack=u+1(確認關(guān)閉請求,可能仍有數(shù)據(jù)發(fā)送);③服務(wù)器發(fā)送FIN=1,ACK=1,seq=w,ack=u+1(數(shù)據(jù)發(fā)送完畢,主動關(guān)閉);④客戶端回復(fù)ACK=1,seq=u+1,ack=w+1(確認服務(wù)器關(guān)閉),進入TIME_WAIT狀態(tài)(持續(xù)2MSL,約2-4分鐘)。TIME_WAIT作用:-確保最后一次ACK到達服務(wù)器(超時則服務(wù)器重發(fā)FIN,客戶端重新發(fā)送ACK);-避免舊連接的報文干擾新連接(相同IP:port的新連接不會接收之前的延遲報文)。優(yōu)化(高并發(fā)服務(wù)端):-調(diào)整內(nèi)核參數(shù):net.ipv4.tcp_tw_reuse=1(允許重用TIME_WAIT連接,需時間戳開啟),net.ipv4.tcp_tw_recycle=0(關(guān)閉快速回收,避免NAT環(huán)境問題);-減少TIME_WAIT數(shù)量:使用短連接(HTTP/1.1長連接更優(yōu)),或調(diào)整應(yīng)用層邏輯(避免頻繁創(chuàng)建/關(guān)閉連接)。阿里面試曾問“三次握手時服務(wù)器SYN隊列滿的后果”,需說明會丟棄后續(xù)SYN包(或發(fā)送RST),可通過增大net.ipv4.tcp_max_syn_backlog參數(shù)或開啟syncookies(net.ipv4.tcp_syncookies=1)緩解。13.如何實現(xiàn)一個線程安全的單例模式?雙重檢查鎖定(DCL)為何需要volatile?餓漢式(線程安全):```javapublicclassSingleton{privatestaticfinalSingletonINSTANCE=newSingleton();privateSingleton(){}publicstaticSingletongetInstance(){returnINSTANCE;}}```懶漢式(DCL):```javapublicclassSingleton{privatestaticvolatileSingletonINSTANCE;//關(guān)鍵:volatile禁止指令重排privateSingleton(){}publicstaticSingletongetInstance(){if(INSTANCE==null){//第一次檢查,避免不必要的同步synchronized(Singleton.class){if(INSTANCE==null){//第二次檢查,防止多線程同時通過第一次檢查INSTANCE=newSingleton();//非原子操作:1.分配內(nèi)存2.初始化對象3.引用指向內(nèi)存}}}returnINSTANCE;}}```volatile的作用:禁止“INSTANCE=newSingleton()”的指令重排。若步驟2和3重排(先將引用指向未初始化的內(nèi)存,再初始化對象),其他線程可能獲取到未初始化的INSTANCE(此時INSTANCE!=null但對象未完成構(gòu)造)。volatile通過內(nèi)存屏障保證寫操作的可見性和有序性。華為面試曾問“靜態(tài)內(nèi)部類單例是否線程安全”,答案是肯定的:JVM保證類加載的線程安全,內(nèi)部類Holder在第一次調(diào)用getInstance()時加載,INSTANCE在類初始化時創(chuàng)建。14.解釋Spring的@Transactional事務(wù)傳播機制,嵌套事務(wù)如何實現(xiàn)?事務(wù)傳播機制定義了多個事務(wù)方法調(diào)用時的事務(wù)行為,通過Propagation枚舉類定義:-REQUIRED(默認):當(dāng)前有事務(wù)則加入,無則創(chuàng)建新事務(wù)。-REQUIRES_NEW:總是創(chuàng)建新事務(wù),掛起當(dāng)前事務(wù)(若有)。-NESTED:嵌套在當(dāng)前事務(wù)中(通過保存點SAVEPOINT實現(xiàn)),子事務(wù)回滾不影響父事務(wù)(但父事務(wù)回滾會導(dǎo)致子事務(wù)回滾)。-SUPPORTS:當(dāng)前有事務(wù)則加入,無則非事務(wù)執(zhí)行。-NOT_SUPPORTED:非事務(wù)執(zhí)行,掛起當(dāng)

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論