高頻java工程師面試題及答案_第1頁(yè)
高頻java工程師面試題及答案_第2頁(yè)
高頻java工程師面試題及答案_第3頁(yè)
高頻java工程師面試題及答案_第4頁(yè)
高頻java工程師面試題及答案_第5頁(yè)
已閱讀5頁(yè),還剩15頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

高頻java工程師面試題及答案Java基本數(shù)據(jù)類型包括byte(1字節(jié))、short(2字節(jié))、int(4字節(jié))、long(8字節(jié))、float(4字節(jié))、double(8字節(jié))、char(2字節(jié))、boolean(未明確定義,通常認(rèn)為1位或1字節(jié))?;緮?shù)據(jù)類型存儲(chǔ)在棧中(除long和double外,部分JVM可能將其存儲(chǔ)為64位),而包裝類是對(duì)象,存儲(chǔ)在堆中。自動(dòng)裝箱(如Integeri=10)和拆箱(intj=i)由編譯器自動(dòng)提供代碼完成,但需注意空指針問題——當(dāng)包裝類對(duì)象為null時(shí),拆箱會(huì)拋出NullPointerException。例如,Integera=null;intb=a;會(huì)直接報(bào)錯(cuò)。String、StringBuilder、StringBuffer的核心區(qū)別在于可變性和線程安全性。String內(nèi)部使用finalchar[]value存儲(chǔ),因此不可變,每次修改都會(huì)提供新對(duì)象;StringBuilder內(nèi)部使用非final的char[],支持可變操作,且無同步機(jī)制,線程不安全;StringBuffer的方法大多被synchronized修飾,線程安全,但性能略低于StringBuilder。實(shí)際開發(fā)中,單線程字符串拼接推薦StringBuilder(如循環(huán)內(nèi)拼接),多線程環(huán)境用StringBuffer,而字符串常量拼接(如"a"+"b")編譯器會(huì)優(yōu)化為String,避免頻繁創(chuàng)建對(duì)象。面向?qū)ο蟮乃拇筇匦允欠庋b、繼承、多態(tài)、抽象。封裝通過訪問控制符(private、protected、public)隱藏內(nèi)部實(shí)現(xiàn),僅暴露必要接口;繼承允許子類復(fù)用父類代碼,通過extends關(guān)鍵字實(shí)現(xiàn),但需注意Java單繼承限制(類只能繼承一個(gè)父類,可實(shí)現(xiàn)多個(gè)接口);多態(tài)表現(xiàn)為同一方法在不同對(duì)象上有不同行為,依賴?yán)^承、重寫和父類引用指向子類對(duì)象(如Animala=newCat();a.speak());抽象通過抽象類(含抽象方法)或接口定義規(guī)范,強(qiáng)制子類實(shí)現(xiàn)具體邏輯。例如,定義Shape抽象類包含area()方法,Circle和Rectangle子類各自實(shí)現(xiàn)計(jì)算面積的邏輯,體現(xiàn)抽象與多態(tài)。重載(Overload)和重寫(Override)的區(qū)別:重載發(fā)生在同一類中,方法名相同但參數(shù)列表不同(參數(shù)類型、個(gè)數(shù)、順序),與返回值和訪問修飾符無關(guān)(如publicvoidtest(inta)和publicStringtest(Stringb)構(gòu)成重載);重寫發(fā)生在子類與父類之間,方法名、參數(shù)列表、返回值(協(xié)變返回類型允許子類返回值是父類返回值的子類)必須相同,訪問修飾符不能比父類更嚴(yán)格(父類protected,子類不能是private),且不能重寫父類的final、static方法(static方法屬于類,子類重寫實(shí)際是隱藏)。例如,Object的equals方法被String重寫,實(shí)現(xiàn)內(nèi)容比較而非引用比較。接口(Interface)和抽象類(AbstractClass)的設(shè)計(jì)目的不同:接口是對(duì)行為的抽象,定義“能做什么”,類可實(shí)現(xiàn)多個(gè)接口;抽象類是對(duì)結(jié)構(gòu)的抽象,定義“是什么”,類只能繼承一個(gè)抽象類。接口中的方法默認(rèn)是publicabstract(Java8前),Java8后支持default和static方法;抽象類中可包含普通方法、抽象方法、成員變量。接口的變量默認(rèn)是publicstaticfinal(常量);抽象類的變量可以是任意訪問修飾符。例如,定義Fly接口包含fly()方法,Bird和Plane類實(shí)現(xiàn)該接口;而Animal抽象類包含name屬性和抽象方法eat(),Dog和Cat子類繼承并實(shí)現(xiàn)eat()。異常處理中,Throwable是所有異常的父類,分為Error(JVM無法處理的嚴(yán)重問題,如OutOfMemoryError、StackOverflowError,不可捕獲)和Exception(可處理的異常)。Exception又分為RuntimeException(運(yùn)行時(shí)異常,如NullPointerException、ArrayIndexOutOfBoundsException,可捕獲可不捕獲)和檢查型異常(CheckedException,如IOException、SQLException,必須顯式處理)。try-with-resources是Java7引入的語(yǔ)法,用于自動(dòng)關(guān)閉實(shí)現(xiàn)AutoCloseable接口的資源(如文件流、數(shù)據(jù)庫(kù)連接),避免資源泄漏。例如:try(FileInputStreamfis=newFileInputStream("test.txt")){...}會(huì)自動(dòng)調(diào)用fis.close(),即使發(fā)生異常。泛型的作用是在編譯期提供類型安全檢查,避免運(yùn)行時(shí)類型轉(zhuǎn)換異常。類型擦除是泛型的實(shí)現(xiàn)機(jī)制,編譯后的字節(jié)碼中泛型信息會(huì)被擦除,替換為上限類型(無限制時(shí)為Object)。例如,List<String>和List<Integer>在運(yùn)行時(shí)是相同的Class對(duì)象(List.class)。泛型方法通過<T>聲明,可定義在普通類或泛型類中;泛型類通過類名后加<T>聲明。通配符包括?(無界通配符,如List<?>)、?extendsT(上界通配符,允許T及其子類)、?superT(下界通配符,允許T及其父類)。例如,使用List<?extendsNumber>接收List<Integer>或List<Double>,但無法添加元素(除null),因?yàn)闊o法確定具體類型;而List<?superInteger>可添加Integer及其子類對(duì)象,但取出時(shí)只能作為Object處理。反射機(jī)制允許程序在運(yùn)行時(shí)獲取類的信息(如字段、方法、構(gòu)造器)并操作對(duì)象。核心類包括Class(表示類的元數(shù)據(jù))、Field(字段)、Method(方法)、Constructor(構(gòu)造器)。獲取Class對(duì)象的方式有:類名.class(如User.class)、對(duì)象.getClass()(如newUser().getClass())、Class.forName("全類名")(如Class.forName("com.example.User"))。反射的應(yīng)用場(chǎng)景包括框架(如Spring通過反射實(shí)例化Bean)、注解處理(如JUnit通過反射調(diào)用測(cè)試方法)、動(dòng)態(tài)代理(如JDK動(dòng)態(tài)代理基于反射實(shí)現(xiàn))。但反射會(huì)繞過編譯期檢查,可能破壞封裝性,且性能低于直接調(diào)用(可通過設(shè)置setAccessible(true)提高訪問效率,但受安全管理器限制)。線程的創(chuàng)建方式有三種:繼承Thread類(重寫run()方法)、實(shí)現(xiàn)Runnable接口(重寫run(),傳入Thread構(gòu)造器)、實(shí)現(xiàn)Callable接口(重寫call(),可返回結(jié)果并拋出異常,通過FutureTask包裝后傳入Thread)。其中,Runnable和Callable更推薦,因?yàn)镴ava單繼承限制,繼承Thread會(huì)導(dǎo)致無法繼承其他類。線程的生命周期包括新建(NEW)、就緒(RUNNABLE,等待CPU調(diào)度)、運(yùn)行(RUNNING,實(shí)際執(zhí)行)、阻塞(BLOCKED,等待鎖)、等待(WAITING,調(diào)用wait()/join()無超時(shí))、超時(shí)等待(TIMED_WAITING,調(diào)用sleep(time)/wait(time)/join(time))、終止(TERMINATED)。注意,Java線程狀態(tài)由Thread.State枚舉定義,其中RUNNABLE包含操作系統(tǒng)中的運(yùn)行態(tài)和就緒態(tài),BLOCKED僅指等待監(jiān)視器鎖的狀態(tài)。synchronized和Lock的區(qū)別主要體現(xiàn)在以下方面:synchronized是關(guān)鍵字,JVM層面實(shí)現(xiàn),自動(dòng)釋放鎖(同步塊/方法執(zhí)行完畢或異常退出);Lock是接口(如ReentrantLock),用戶手動(dòng)釋放(需在finally中調(diào)用unlock())。synchronized是非公平鎖(默認(rèn)不保證等待線程獲取鎖的順序),Lock可通過構(gòu)造函數(shù)指定公平鎖(ReentrantLock(true))。synchronized不可中斷,除非拋出異常;Lock的lockInterruptibly()方法支持可中斷獲取鎖。synchronized只能有一個(gè)等待隊(duì)列;Lock通過Condition可創(chuàng)建多個(gè)等待隊(duì)列(如生產(chǎn)者-消費(fèi)者模型中,用不同Condition控制生產(chǎn)和消費(fèi)線程的等待)。性能方面,早期synchronized因重量鎖效率低,但JDK6引入偏向鎖、輕量級(jí)鎖、自旋鎖優(yōu)化后,與Lock性能接近,高競(jìng)爭(zhēng)場(chǎng)景下Lock更靈活。volatile的作用是保證可見性和禁止指令重排??梢娦灾府?dāng)一個(gè)線程修改了volatile變量的值,其他線程能立即看到最新值(通過內(nèi)存屏障實(shí)現(xiàn),寫操作后添加Store屏障,讀操作前添加Load屏障,強(qiáng)制從主內(nèi)存讀寫)。指令重排是JVM為優(yōu)化性能對(duì)指令順序的調(diào)整,volatile變量通過內(nèi)存屏障禁止編譯器和處理器對(duì)其相關(guān)指令重排。但volatile不保證原子性,例如i++(讀取-修改-寫入三步操作)在多線程下仍會(huì)出現(xiàn)數(shù)據(jù)不一致。適用場(chǎng)景:狀態(tài)標(biāo)志(如booleanisRunning)、單例模式的雙重檢查鎖定(DCL)中防止指令重排導(dǎo)致的空指針(需將實(shí)例變量聲明為volatile)。線程池的核心參數(shù)包括corePoolSize(核心線程數(shù),即使空閑也保留)、maximumPoolSize(最大線程數(shù))、keepAliveTime(非核心線程空閑超時(shí)時(shí)間)、unit(時(shí)間單位)、workQueue(工作隊(duì)列,存儲(chǔ)待執(zhí)行任務(wù))、threadFactory(線程工廠,創(chuàng)建工作線程)、handler(拒絕策略,任務(wù)無法處理時(shí)的處理方式)。工作隊(duì)列常見類型:ArrayBlockingQueue(有界,需指定容量)、LinkedBlockingQueue(無界/有界,無界可能導(dǎo)致OOM)、SynchronousQueue(無緩沖,直接提交給線程)、PriorityBlockingQueue(優(yōu)先隊(duì)列,按任務(wù)優(yōu)先級(jí)排序)。拒絕策略包括AbortPolicy(默認(rèn),拋出RejectedExecutionException)、CallerRunsPolicy(調(diào)用者線程執(zhí)行任務(wù))、DiscardPolicy(丟棄任務(wù))、DiscardOldestPolicy(丟棄隊(duì)列中最舊任務(wù))。線程池的使用場(chǎng)景:控制資源消耗(避免頻繁創(chuàng)建銷毀線程)、提高響應(yīng)速度(任務(wù)到達(dá)時(shí)直接使用空閑線程)、統(tǒng)一管理線程(監(jiān)控、調(diào)優(yōu))。AQS(AbstractQueuedSynchronizer)是Java并發(fā)包的基礎(chǔ)框架,通過維護(hù)一個(gè)volatileintstate(同步狀態(tài))和一個(gè)FIFO等待隊(duì)列(CLH隊(duì)列的變種)實(shí)現(xiàn)鎖和同步工具。子類需重寫tryAcquire(int)、tryRelease(int)(獨(dú)占模式)或tryAcquireShared(int)、tryReleaseShared(int)(共享模式)來定義狀態(tài)變更邏輯。ReentrantLock(獨(dú)占鎖)、CountDownLatch(共享鎖)、Semaphore(共享鎖)等均基于AQS實(shí)現(xiàn)。例如,ReentrantLock的公平鎖實(shí)現(xiàn)中,tryAcquire方法會(huì)檢查等待隊(duì)列是否有前驅(qū)節(jié)點(diǎn),確保先到先得;非公平鎖則直接嘗試CAS修改state,提高吞吐量。CountDownLatch和CyclicBarrier的區(qū)別:CountDownLatch是減計(jì)數(shù),構(gòu)造時(shí)指定計(jì)數(shù)器值(count),線程調(diào)用countDown()遞減,await()等待計(jì)數(shù)器到0;計(jì)數(shù)器不可重置,適用于一個(gè)/多個(gè)線程等待其他線程完成操作(如主線程等待所有子線程初始化完成)。CyclicBarrier是加計(jì)數(shù),構(gòu)造時(shí)指定parties(需等待的線程數(shù)),線程調(diào)用await()等待,當(dāng)?shù)竭_(dá)parties個(gè)線程時(shí),觸發(fā)barrierAction(可選,由最后一個(gè)到達(dá)的線程執(zhí)行);計(jì)數(shù)器可通過reset()重置,適用于多線程任務(wù)分步執(zhí)行(如多個(gè)線程處理數(shù)據(jù)分片,全部完成后合并結(jié)果)。例如,5個(gè)線程處理不同文件,全部處理完成后由CyclicBarrier觸發(fā)合并操作,合并后可重置Barrier處理下一批文件。死鎖的四個(gè)必要條件:互斥(資源同一時(shí)間只能被一個(gè)線程占用)、請(qǐng)求與保持(線程持有資源并請(qǐng)求其他資源)、不可搶占(資源只能由持有者釋放)、循環(huán)等待(線程A等線程B的資源,線程B等線程A的資源)。解決方法包括破壞其中一個(gè)條件:破壞互斥(不可行,因部分資源本身互斥)、破壞請(qǐng)求與保持(一次性申請(qǐng)所有資源)、破壞不可搶占(允許搶占,如使用Lock的tryLock(timeout))、破壞循環(huán)等待(按固定順序申請(qǐng)資源)。排查工具:jstack命令可提供線程dump,查看是否有死鎖信息;JConsole的線程標(biāo)簽可可視化線程狀態(tài)及鎖持有情況。CAS(Compare-And-Swap)是樂觀鎖的實(shí)現(xiàn),包含三個(gè)操作數(shù):內(nèi)存位置(V)、預(yù)期舊值(A)、新值(B)。當(dāng)V等于A時(shí),將V更新為B,否則不操作。CAS通過Unsafe類的native方法(如compareAndSwapInt)實(shí)現(xiàn),屬于CPU指令級(jí)別的原子操作。但CAS存在ABA問題(V的值從A→B→A,此時(shí)CAS認(rèn)為未修改),可通過版本號(hào)(如AtomicStampedReference,存儲(chǔ)值和版本號(hào))或時(shí)間戳解決。另外,CAS在高競(jìng)爭(zhēng)場(chǎng)景下可能導(dǎo)致自旋次數(shù)過多(如多個(gè)線程反復(fù)修改同一變量),增加CPU開銷,此時(shí)更適合使用鎖(如synchronized)。JVM內(nèi)存模型分為堆、棧(虛擬機(jī)棧和本地方法棧)、方法區(qū)、程序計(jì)數(shù)器。堆(Heap)是最大的內(nèi)存區(qū)域,所有對(duì)象實(shí)例和數(shù)組在此分配,被所有線程共享,是GC的主要區(qū)域(分為新生代Eden、Survivor區(qū)和老年代)。虛擬機(jī)棧(JavaVirtualMachineStacks)每個(gè)線程獨(dú)有,存儲(chǔ)棧幀(局部變量表、操作數(shù)棧、動(dòng)態(tài)鏈接、方法出口),每個(gè)方法調(diào)用對(duì)應(yīng)一個(gè)棧幀入棧,方法返回則出棧;若棧深度超過限制(如遞歸未終止),拋出StackOverflowError。本地方法棧與虛擬機(jī)棧類似,用于本地方法(native方法)。方法區(qū)(MethodArea)存儲(chǔ)類信息、常量、靜態(tài)變量、即時(shí)編譯后的代碼等,JDK7前是永久代(PermGen),JDK8后改為元空間(MetaSpace,使用本地內(nèi)存)。程序計(jì)數(shù)器(ProgramCounterRegister)記錄當(dāng)前線程執(zhí)行的字節(jié)碼行號(hào),線程私有,唯一無OOM的區(qū)域。類加載過程分為加載、連接(驗(yàn)證、準(zhǔn)備、解析)、初始化三個(gè)階段。加載階段:通過類加載器將.class文件的二進(jìn)制流讀入內(nèi)存,提供Class對(duì)象。連接的驗(yàn)證階段:檢查字節(jié)碼格式、語(yǔ)義、符號(hào)引用等是否合法;準(zhǔn)備階段:為類靜態(tài)變量分配內(nèi)存并設(shè)置初始值(如int類型初始為0,引用類型為null);解析階段:將符號(hào)引用(如字符串形式的類名)替換為直接引用(內(nèi)存地址)。初始化階段:執(zhí)行類構(gòu)造器<clinit>()方法(由編譯器收集靜態(tài)變量賦值和靜態(tài)代碼塊的順序提供),按父類到子類的順序初始化。類加載的觸發(fā)條件包括:new實(shí)例化對(duì)象、訪問類靜態(tài)變量/方法、反射調(diào)用類、主類(包含main方法的類)啟動(dòng)。雙親委派模型的工作流程:類加載器收到加載請(qǐng)求時(shí),先委托給父類加載器(非繼承關(guān)系,是組合關(guān)系),父類加載器繼續(xù)向上委托,直到啟動(dòng)類加載器(BootstrapClassLoader);若父類加載器無法加載(如不在其加載路徑),則當(dāng)前類加載器嘗試加載。優(yōu)勢(shì):避免類的重復(fù)加載(如java.lang.Object只會(huì)被Bootstrap加載器加載一次),防止核心類被篡改(如用戶自定義的java.lang.String會(huì)被父類加載器攔截,使用JDK的String)。自定義類加載器需重寫findClass()方法,避免破壞雙親委派(若需破壞,可重寫loadClass())。垃圾回收的標(biāo)記算法有引用計(jì)數(shù)法(對(duì)象有引用時(shí)計(jì)數(shù)+1,無引用時(shí)-1,計(jì)數(shù)為0時(shí)回收,無法處理循環(huán)引用)和可達(dá)性分析(從GCRoots對(duì)象出發(fā),標(biāo)記不可達(dá)的對(duì)象為可回收)。GCRoots包括:虛擬機(jī)棧中局部變量引用的對(duì)象、方法區(qū)中靜態(tài)變量引用的對(duì)象、方法區(qū)中常量引用的對(duì)象、本地方法棧中native方法引用的對(duì)象?;厥账惴ㄓ袠?biāo)記-清除(Mark-Sweep,標(biāo)記后清除,產(chǎn)生內(nèi)存碎片)、標(biāo)記-復(fù)制(Mark-Copy,將存活對(duì)象復(fù)制到另一塊區(qū)域,適用于新生代,Eden和Survivor區(qū)的8:1:1分配)、標(biāo)記-整理(Mark-Compact,標(biāo)記后將存活對(duì)象移動(dòng)到內(nèi)存一端,適用于老年代)。常見的垃圾收集器:Serial(單線程,新生代,標(biāo)記-復(fù)制,適合客戶端)、ParallelScavenge(多線程,新生代,標(biāo)記-復(fù)制,關(guān)注吞吐量)、SerialOld(單線程,老年代,標(biāo)記-整理,配合Serial或作為CMS的后備)、ParallelOld(多線程,老年代,標(biāo)記-整理,配合ParallelScavenge)、CMS(ConcurrentMarkSweep,多線程,老年代,標(biāo)記-清除,關(guān)注停頓時(shí)間,流程:初始標(biāo)記→并發(fā)標(biāo)記→重新標(biāo)記→并發(fā)清除,缺點(diǎn)是內(nèi)存碎片和浮動(dòng)垃圾)、G1(Garbage-First,分代不分區(qū),將堆劃分為多個(gè)Region,優(yōu)先回收價(jià)值高的Region,標(biāo)記-整理+標(biāo)記-復(fù)制,適合大內(nèi)存)、ZGC(低延遲,使用顏色指針和讀屏障,停頓時(shí)間不超過10ms,支持TB級(jí)內(nèi)存)。內(nèi)存泄漏的常見場(chǎng)景:靜態(tài)集合類(如HashMap作為靜態(tài)變量,對(duì)象加入后未移除,導(dǎo)致無法被回收)、未關(guān)閉的資源(如數(shù)據(jù)庫(kù)連接、IO流、Socket,即使對(duì)象被回收,資源未釋放可能導(dǎo)致句柄泄漏)、內(nèi)部類持有外部類引用(非靜態(tài)內(nèi)部類默認(rèn)持有外部類引用,若內(nèi)部類生命周期長(zhǎng)于外部類,外部類無法被回收)、緩存未設(shè)置過期時(shí)間(如使用HashMap做緩存,未清理舊數(shù)據(jù))。排查工具:JProfiler可跟蹤對(duì)象存活狀態(tài),MAT(EclipseMemoryAnalyzer)分析堆dump文件,找出大對(duì)象或重復(fù)對(duì)象;jmap-dump:format=b,file=heap.bin<pid>提供堆轉(zhuǎn)儲(chǔ),jhat分析。OOM(OutOfMemoryError)的常見原因及解決:堆內(nèi)存不足(Java.lang.OutOfMemoryError:Javaheapspace),可能因?qū)ο蟠婊顣r(shí)間過長(zhǎng)、內(nèi)存泄漏、數(shù)據(jù)量過大;解決方法是調(diào)大-Xmx和-Xms參數(shù),優(yōu)化對(duì)象生命周期,排查內(nèi)存泄漏。元空間不足(Java.lang.OutOfMemoryError:Metaspace),JDK8后方法區(qū)移至元空間,存儲(chǔ)類元數(shù)據(jù),可能因動(dòng)態(tài)提供類(如反射、CGLIB)過多;解決方法是限制動(dòng)態(tài)類提供,調(diào)大-XX:MaxMetaspaceSize(默認(rèn)無限制,受本地內(nèi)存限制)。棧溢出(Java.lang.StackOverflowError),因方法調(diào)用棧過深(如遞歸無終止條件);解決方法是增加-Xss參數(shù)(線程棧大小),優(yōu)化遞歸邏輯(改為迭代或尾遞歸)。直接內(nèi)存溢出(Java.lang.OutOfMemoryError:Directbuffermemory),因NIO使用ByteBuffer.allocateDirect()分配堆外內(nèi)存,未及時(shí)釋放;解決方法是限制直接內(nèi)存使用,顯式調(diào)用cleaner().clean()釋放。SpringIOC(控制反轉(zhuǎn))的核心是將對(duì)象的創(chuàng)建、依賴注入、生命周期管理交給容器,降低耦合。實(shí)現(xiàn)方式包括XML配置、注解(@Component、@Autowired)、Java配置(@Configuration+@Bean)。IOC容器的關(guān)鍵類是BeanFactory(基礎(chǔ)容器)和ApplicationContext(擴(kuò)展容器,支持國(guó)際化、事件發(fā)布、資源加載)。Bean的實(shí)例化過程:容器讀取配置元數(shù)據(jù)→解析Bean定義→通過構(gòu)造器/工廠方法實(shí)例化對(duì)象→填充依賴(屬性注入,@Autowired通過AutowiredAnnotationBeanPostProcessor實(shí)現(xiàn))→調(diào)用初始化方法(@PostConstruct或InitializingBean的afterPropertiesSet())→注冊(cè)銷毀方法(@PreDestroy或DisposableBean的destroy())。SpringAOP(面向切面編程)通過動(dòng)態(tài)代理實(shí)現(xiàn),將橫切邏輯(如日志、事務(wù)、權(quán)限)與業(yè)務(wù)邏輯解耦。代理方式包括JDK動(dòng)態(tài)代理(基于接口,通過InvocationHandler)和CGLIB代理(基于類,通過MethodInterceptor,需引入cglib庫(kù))。AOP的核心概念:連接點(diǎn)(Joinpoint,方法調(diào)用或異常拋出)、切點(diǎn)(Pointcut,匹配連接點(diǎn)的表達(dá)式,如execution(com.example.service..(..)))、通知(Advice,切面在特定連接點(diǎn)執(zhí)行的操作,包括前置@Before、后置@After、返回@AfterReturning、異常@AfterThrowing、環(huán)繞@Around)、切面(Aspect,切點(diǎn)+通知的組合)、目標(biāo)對(duì)象(Target,被代理的對(duì)象)、代理(Proxy,包含目標(biāo)對(duì)象和切面邏輯的對(duì)象)、織入(Weaving,將切面應(yīng)用到目標(biāo)對(duì)象提供代理的過程)。Bean的作用域包括singleton(默認(rèn),容器中僅一個(gè)實(shí)例)、prototype(每次獲取新實(shí)例)、request(HTTP請(qǐng)求作用域,僅Web容器有效)、session(HTTP會(huì)話作用域)、application(ServletContext作用域)、websocket(WebSocket作用域)。singleton的Bean在容器啟動(dòng)時(shí)初始化(除非設(shè)置lazy-init=true),prototype的Bean在每次獲取時(shí)初始化,且容器不管理其生命周期(需手動(dòng)釋放資源)。Spring解決循環(huán)依賴的關(guān)鍵是三級(jí)緩存:singletonObjects(一級(jí)緩存,存儲(chǔ)已初始化完成的Bean)、earlySingletonObjects(二級(jí)緩存,存儲(chǔ)完成實(shí)例化但未初始化的Bean)、singletonFactories(三級(jí)緩存,存儲(chǔ)Bean工廠,用于提供早期代理對(duì)象)。流程:A實(shí)例化后(調(diào)用構(gòu)造器),將A的工廠(ObjectFactory)存入三級(jí)緩存;A需要注入B,觸發(fā)B的實(shí)例化,B實(shí)例化后存入三級(jí)緩存;B需要注入A,從三級(jí)緩存獲取A的工廠,提供A的早期對(duì)象(可能是代理),存入二級(jí)緩存并移除三級(jí)緩存;B完成依賴注入和初始化,存入一級(jí)緩存并移除二級(jí)緩存;A獲取B(已在一級(jí)緩存),完成依賴注入和初始化,存入一級(jí)緩存并移除二級(jí)緩存。注意,循環(huán)依賴僅支持singleton作用域的Bean通過setter注入或構(gòu)造器注入(構(gòu)造器注入會(huì)在實(shí)例化階段就需要依賴,無法通過三級(jí)緩存解決)。Spring事務(wù)管理分為編程式(通過TransactionTemplate手動(dòng)管理)和聲明式(通過@Transactional注解或XML配置)。@Transactional的常用屬性:propagation(傳播行為,默認(rèn)REQUIRED,當(dāng)前有事務(wù)則加入,無則新建)、isolation(隔離級(jí)別,默認(rèn)DEFAULT使用數(shù)據(jù)庫(kù)隔離級(jí)別)、readOnly(是否只讀,優(yōu)化數(shù)據(jù)庫(kù)性能)、rollbackFor(指定異常回滾,默認(rèn)RuntimeException和Error)、timeout(超時(shí)時(shí)間,單位秒)。事務(wù)的實(shí)現(xiàn)基于AOP,通過TransactionInterceptor攔截方法調(diào)用,在方法執(zhí)行前獲取連接并開啟事務(wù),執(zhí)行后根據(jù)是否異常決定提交或回滾。SpringMVC的執(zhí)行流程:客戶端發(fā)送請(qǐng)求到DispatcherServlet(前端控制器);DispatcherServlet通過HandlerMapping(如RequestMappingHandlerMapping)找到對(duì)應(yīng)的Handler(控制器方法)及攔截器;DispatcherServlet調(diào)用HandlerAdapter(如RequestMappingHandlerAdapter)執(zhí)行Handler;Handler處理完成返回ModelAndView;DispatcherServlet通過ViewResolver(如InternalResourceViewResolver)解析View;DispatcherServlet將Model數(shù)據(jù)渲染到View并返回響應(yīng)。關(guān)鍵組件:DispatcherServlet(核心調(diào)度)、HandlerMapping(映射請(qǐng)求到處理器)、HandlerAdapter(適配處理器執(zhí)行)、ViewResolver(解析視圖)、Interceptor(請(qǐng)求預(yù)處理/后處理)。MyBatis的一級(jí)緩存是SqlSession級(jí)別的,默認(rèn)開啟,存儲(chǔ)同一SqlSession中相同查詢(相同SQL、參數(shù)、環(huán)境)的結(jié)果,若執(zhí)行更新操作(insert/update/delete)會(huì)清空緩存。二級(jí)緩存是Mapper級(jí)別的(namespace范圍),需在全局配置中開啟<settingname="cacheEnabled"value="true"/>,并在Mapper文件中添加<cache/>,或通過@CacheNamespace注解。二級(jí)緩存存儲(chǔ)不同SqlSession(同一Mapper)的相同查詢結(jié)果,需注意緩存一致性(更新操作會(huì)清空對(duì)應(yīng)Mapper的二級(jí)緩存)。二級(jí)緩存可與第三方緩存集成(如Redis),通過實(shí)現(xiàn)Cache接口。MyBatis動(dòng)態(tài)SQL通過標(biāo)簽實(shí)現(xiàn):<if>(條件判斷,如<iftest="name!=null">ANDname={name}</if>)、<where>(自動(dòng)處理AND/OR前綴,無條件時(shí)不提供WHERE)、<set>(用于更新,自動(dòng)處理逗號(hào)后綴)、<foreach>(遍歷集合,如批量插入<foreachcollection="list"item="item"separator=",">({item.id},{})</foreach>)、<choose>/<when>/<

溫馨提示

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

最新文檔

評(píng)論

0/150

提交評(píng)論