高頻java基礎(chǔ)數(shù)據(jù)庫(kù)面試題及答案_第1頁(yè)
高頻java基礎(chǔ)數(shù)據(jù)庫(kù)面試題及答案_第2頁(yè)
高頻java基礎(chǔ)數(shù)據(jù)庫(kù)面試題及答案_第3頁(yè)
高頻java基礎(chǔ)數(shù)據(jù)庫(kù)面試題及答案_第4頁(yè)
高頻java基礎(chǔ)數(shù)據(jù)庫(kù)面試題及答案_第5頁(yè)
已閱讀5頁(yè),還剩20頁(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基礎(chǔ)數(shù)據(jù)庫(kù)面試題及答案Java中equals()和hashCode()的關(guān)系是什么?equals()用于判斷兩個(gè)對(duì)象是否“邏輯相等”,hashCode()返回對(duì)象的哈希碼。根據(jù)規(guī)范,若兩個(gè)對(duì)象equals()返回true,則它們的hashCode()必須相同;若hashCode()不同,則equals()一定為false。但hashCode()相同,equals()可能為false(哈希沖突)。例如,自定義類重寫equals()時(shí)必須重寫hashCode(),否則放入HashMap/HashSet時(shí)會(huì)破壞數(shù)據(jù)一致性——兩個(gè)equals()為true的對(duì)象會(huì)被視為不同的鍵,導(dǎo)致無法正確查找或去重。String、StringBuilder、StringBuffer的區(qū)別是什么?String是不可變類,內(nèi)部通過finalchar[]存儲(chǔ)字符,所有修改操作(如concat()、replace())都會(huì)提供新的String對(duì)象。StringBuilder和StringBuffer是可變的,內(nèi)部使用可擴(kuò)展的char[]。StringBuilder線程不安全,性能較高;StringBuffer通過synchronized實(shí)現(xiàn)線程安全,性能略低。場(chǎng)景選擇:?jiǎn)尉€程字符串拼接用StringBuilder,多線程用StringBuffer,不需要修改時(shí)優(yōu)先用String(利用字符串常量池減少內(nèi)存占用)。重載(Overload)和重寫(Override)的區(qū)別是什么?重載發(fā)生在同一個(gè)類中,指多個(gè)方法名相同但參數(shù)列表不同(參數(shù)類型、順序、數(shù)量),與返回值類型無關(guān)。例如publicvoidprint(inta)和publicvoidprint(Stringb)是重載。重寫發(fā)生在子類與父類之間,子類重新定義父類的非final方法,要求方法名、參數(shù)列表、返回值類型完全相同(子類返回值可為父類返回值的子類,即協(xié)變返回),訪問權(quán)限不能嚴(yán)于父類(如父類方法是protected,子類不能是private)。重寫體現(xiàn)多態(tài),重載是編譯時(shí)多態(tài),重寫是運(yùn)行時(shí)多態(tài)。final關(guān)鍵字的作用有哪些?final修飾類時(shí),類不可被繼承(如String、Math);修飾方法時(shí),方法不可被重寫(但可重載);修飾變量時(shí),變量成為常量,基本類型賦值后值不可變,引用類型賦值后引用不可變(但對(duì)象內(nèi)容可修改)。例如finalinta=10,a不能重新賦值;finalListlist=newArrayList(),list不能指向其他對(duì)象,但可以調(diào)用add()修改內(nèi)容。Java異常處理中,throw和throws的區(qū)別是什么?throw用于手動(dòng)拋出異常對(duì)象,位于方法體內(nèi)部,如if(condition)thrownewIllegalArgumentException("參數(shù)錯(cuò)誤")。throws用于聲明方法可能拋出的異常類型,位于方法簽名后,告訴調(diào)用者需要處理該異常。例如publicvoidreadFile()throwsIOException,表示該方法可能拋出IO異常,調(diào)用者需用try-catch捕獲或繼續(xù)throws。RuntimeException及其子類(如NullPointerException)可不用顯式聲明throws,非運(yùn)行時(shí)異常(如IOException)必須聲明或處理。ArrayList和LinkedList的區(qū)別是什么?ArrayList基于動(dòng)態(tài)數(shù)組實(shí)現(xiàn),支持隨機(jī)訪問(get(i)時(shí)間復(fù)雜度O(1)),但插入/刪除元素(尤其中間位置)需移動(dòng)數(shù)組元素,時(shí)間復(fù)雜度O(n)。默認(rèn)初始容量10,擴(kuò)容時(shí)新容量為原容量的1.5倍(intnewCapacity=oldCapacity+(oldCapacity>>1))。LinkedList基于雙向鏈表實(shí)現(xiàn),插入/刪除元素(僅需修改前后節(jié)點(diǎn)指針)時(shí)間復(fù)雜度O(1)(若已知節(jié)點(diǎn)位置),但隨機(jī)訪問需遍歷鏈表,時(shí)間復(fù)雜度O(n)。此外,LinkedList還實(shí)現(xiàn)了Deque接口,可作為隊(duì)列或棧使用。選擇時(shí),頻繁查詢用ArrayList,頻繁增刪(非首尾)用LinkedList(實(shí)際中因數(shù)組緩存友好性,小數(shù)據(jù)量時(shí)ArrayList增刪性能可能更好)。HashMap的底層實(shí)現(xiàn)是怎樣的?JDK7和JDK8有何不同?JDK7中HashMap基于“數(shù)組+鏈表”實(shí)現(xiàn),數(shù)組是Entry<K,V>[]table,每個(gè)Entry包含key、value、next(指向鏈表下一個(gè)節(jié)點(diǎn))。哈希沖突時(shí),新元素插入鏈表頭部(頭插法)。JDK8優(yōu)化為“數(shù)組+鏈表+紅黑樹”,當(dāng)鏈表長(zhǎng)度≥8且數(shù)組長(zhǎng)度≥64時(shí),鏈表轉(zhuǎn)換為紅黑樹(樹化),查詢時(shí)間復(fù)雜度從O(n)降為O(logn);當(dāng)紅黑樹節(jié)點(diǎn)數(shù)≤6時(shí),退化為鏈表(反樹化)。JDK8中Entry改為Node,哈希計(jì)算簡(jiǎn)化(hash=key.hashCode()^(hash>>>16)),插入方式改為尾插法(避免多線程擴(kuò)容時(shí)的循環(huán)鏈表問題)。擴(kuò)容機(jī)制:初始容量16,負(fù)載因子0.75(閾值=容量×負(fù)載因子),當(dāng)元素?cái)?shù)量超過閾值時(shí),數(shù)組擴(kuò)容為原來的2倍(保證容量始終是2的冪次,便于通過位運(yùn)算計(jì)算索引:(n-1)&hash)。ConcurrentHashMap如何保證線程安全?JDK7和JDK8的實(shí)現(xiàn)有何差異?JDK7中ConcurrentHashMap使用分段鎖(Segment),每個(gè)Segment繼承ReentrantLock,默認(rèn)16個(gè)Segment,相當(dāng)于將數(shù)據(jù)分成16個(gè)段,每個(gè)段獨(dú)立加鎖,不同段的操作可并行,提高并發(fā)效率。每個(gè)Segment包含一個(gè)HashEntry數(shù)組,存儲(chǔ)鍵值對(duì)。JDK8中放棄分段鎖,采用CAS(Compare-And-Swap)+synchronized實(shí)現(xiàn)線程安全:數(shù)組節(jié)點(diǎn)(Node)用volatile修飾,保證可見性;插入元素時(shí),若節(jié)點(diǎn)為空,用CAS嘗試插入;若節(jié)點(diǎn)非空且是鏈表頭節(jié)點(diǎn),用synchronized鎖住該節(jié)點(diǎn),再進(jìn)行鏈表或紅黑樹的插入/更新操作。這種優(yōu)化減少了鎖的粒度(從Segment到單個(gè)節(jié)點(diǎn)),并發(fā)度更高。HashSet如何保證元素不重復(fù)?HashSet底層基于HashMap實(shí)現(xiàn),元素存儲(chǔ)在HashMap的key中,value統(tǒng)一為PRESENT(一個(gè)靜態(tài)的Object對(duì)象)。添加元素時(shí),調(diào)用HashMap的put(key,PRESENT)方法。HashMap的put()方法會(huì)先計(jì)算key的hashCode(),找到對(duì)應(yīng)的桶位置,然后遍歷鏈表/紅黑樹檢查是否存在equals()為true的key:若存在,覆蓋value(不影響,因?yàn)関alue都是PRESENT);若不存在,插入新節(jié)點(diǎn)。因此,HashSet的去重依賴于key的hashCode()和equals()方法的正確實(shí)現(xiàn)。若自定義類未重寫這兩個(gè)方法,默認(rèn)使用Object的實(shí)現(xiàn)(hashCode()基于內(nèi)存地址,equals()比較內(nèi)存地址),會(huì)導(dǎo)致不同對(duì)象即使邏輯相同也被視為不同元素。線程的創(chuàng)建方式有哪些?各自的優(yōu)缺點(diǎn)是什么?Java中線程創(chuàng)建主要有三種方式:1.繼承Thread類,重寫run()方法。優(yōu)點(diǎn)是簡(jiǎn)單,直接調(diào)用start()啟動(dòng)。缺點(diǎn)是單繼承限制(Java不支持多繼承),無法復(fù)用其他類的功能。2.實(shí)現(xiàn)Runnable接口,重寫run()方法。優(yōu)點(diǎn)是避免單繼承限制,更靈活。缺點(diǎn)是run()無返回值,無法直接獲取線程執(zhí)行結(jié)果。3.實(shí)現(xiàn)Callable接口,重寫call()方法(有返回值,可拋出異常),配合FutureTask使用。例如FutureTask<Integer>task=newFutureTask<>(()->{return100;});Threadthread=newThread(task);thread.start();可通過task.get()獲取返回值。優(yōu)點(diǎn)是能獲取異步執(zhí)行結(jié)果,適合需要返回值的場(chǎng)景;缺點(diǎn)是代碼略復(fù)雜。實(shí)際開發(fā)中推薦使用后兩種方式(接口實(shí)現(xiàn)),避免單繼承限制。線程池(如ExecutorService)也基于Runnable或Callable創(chuàng)建線程。synchronized和Lock的區(qū)別是什么?synchronized是Java關(guān)鍵字,JVM層面實(shí)現(xiàn)鎖;Lock是Java.util.concurrent.locks包下的接口(如ReentrantLock),基于AQS(AbstractQueuedSynchronizer)實(shí)現(xiàn)。主要區(qū)別:1.鎖的獲取方式:synchronized自動(dòng)釋放鎖(同步塊/方法執(zhí)行完畢或異常退出時(shí));Lock需手動(dòng)調(diào)用unlock()釋放(通常在finally塊中)。2.鎖的特性:synchronized是非公平、可重入鎖;Lock支持公平鎖(按等待隊(duì)列順序獲取)和非公平鎖(默認(rèn)),可中斷(lockInterruptibly())、可超時(shí)(tryLock(longtimeout,TimeUnitunit))。3.條件變量:synchronized配合wait()/notify()/notifyAll()實(shí)現(xiàn)等待/通知;Lock通過newCondition()獲取Condition對(duì)象,支持多個(gè)等待隊(duì)列(如生產(chǎn)者-消費(fèi)者模型中,生產(chǎn)者和消費(fèi)者可使用不同的Condition)。4.性能:早期版本synchronized性能較差(重量級(jí)鎖),JDK6后引入偏向鎖、輕量級(jí)鎖、自旋鎖等優(yōu)化,性能與Lock接近。高競(jìng)爭(zhēng)場(chǎng)景下,Lock的可中斷、可超時(shí)特性更靈活。volatile的作用是什么?volatile是輕量級(jí)同步機(jī)制,保證變量的可見性和禁止指令重排序,但不保證原子性??梢娦灾府?dāng)一個(gè)線程修改了volatile變量的值,其他線程能立即看到最新值(通過內(nèi)存屏障實(shí)現(xiàn),寫操作后強(qiáng)制刷新到主內(nèi)存,讀操作前強(qiáng)制從主內(nèi)存讀?。?。指令重排序指編譯器/CPU為優(yōu)化性能,可能調(diào)整指令執(zhí)行順序,volatile變量通過內(nèi)存屏障禁止編譯器和處理器對(duì)其相關(guān)指令進(jìn)行重排序。例如,單例模式的雙重檢查鎖定(DCL)中,實(shí)例變量需聲明為volatile,防止“實(shí)例分配內(nèi)存但未初始化”時(shí)其他線程獲取到半初始化對(duì)象(new操作分為分配內(nèi)存、初始化對(duì)象、設(shè)置引用三步,可能被重排序?yàn)榉峙鋬?nèi)存、設(shè)置引用、初始化對(duì)象)。線程池的核心參數(shù)有哪些?拒絕策略有哪些?線程池通過ThreadPoolExecutor創(chuàng)建,核心參數(shù):corePoolSize:核心線程數(shù),即使空閑也不會(huì)被銷毀(除非設(shè)置allowCoreThreadTimeOut為true)。maximumPoolSize:最大線程數(shù),線程池允許的最大線程數(shù)量。keepAliveTime:非核心線程(超過corePoolSize的線程)的空閑存活時(shí)間,超時(shí)后被銷毀。unit:keepAliveTime的時(shí)間單位。workQueue:任務(wù)隊(duì)列,存儲(chǔ)待執(zhí)行的Runnable任務(wù),常用類型有ArrayBlockingQueue(有界)、LinkedBlockingQueue(無界,可能導(dǎo)致OOM)、SynchronousQueue(不存儲(chǔ)任務(wù),直接提交給線程)。threadFactory:線程工廠,用于創(chuàng)建線程(可自定義命名規(guī)則,方便調(diào)試)。handler:拒絕策略,當(dāng)任務(wù)隊(duì)列已滿且線程數(shù)達(dá)到maximumPoolSize時(shí),新任務(wù)的處理方式。JDK提供四種拒絕策略:1.AbortPolicy(默認(rèn)):拋出RejectedExecutionException異常。2.CallerRunsPolicy:由調(diào)用線程(提交任務(wù)的線程)直接執(zhí)行該任務(wù)。3.DiscardPolicy:靜默丟棄新任務(wù),不做任何處理。4.DiscardOldestPolicy:丟棄任務(wù)隊(duì)列中最老的任務(wù)(隊(duì)首),然后嘗試重新提交新任務(wù)。實(shí)際開發(fā)中建議使用有界隊(duì)列(如ArrayBlockingQueue)并自定義拒絕策略(如記錄日志或觸發(fā)告警),避免無界隊(duì)列導(dǎo)致內(nèi)存溢出。死鎖發(fā)生的條件是什么?如何避免死鎖?死鎖的四個(gè)必要條件:1.互斥條件:資源同一時(shí)間只能被一個(gè)線程占用。2.不可搶占條件:線程已占用的資源不能被其他線程強(qiáng)行搶占,只能主動(dòng)釋放。3.請(qǐng)求與保持條件:線程持有至少一個(gè)資源,同時(shí)請(qǐng)求其他資源(被其他線程持有),且不釋放已持有的資源。4.循環(huán)等待條件:多個(gè)線程形成環(huán)狀的資源等待鏈(線程A等線程B的資源,線程B等線程A的資源)。避免死鎖的方法:破壞互斥條件:無法完全破壞(部分資源本身是互斥的,如文件),但可通過資源轉(zhuǎn)換(如用讀寫鎖替代互斥鎖)減少互斥范圍。破壞不可搶占條件:使用可搶占的鎖(如Lock的tryLock(),設(shè)置超時(shí)),超時(shí)后釋放已持有的資源。破壞請(qǐng)求與保持條件:一次性申請(qǐng)所有需要的資源(如設(shè)計(jì)資源獲取順序,按順序申請(qǐng))。破壞循環(huán)等待條件:對(duì)資源進(jìn)行編號(hào),所有線程按統(tǒng)一順序申請(qǐng)資源(如先申請(qǐng)編號(hào)小的,再申請(qǐng)編號(hào)大的)。例如,兩個(gè)線程都需要鎖A和鎖B,若都按先A后B的順序獲取,就不會(huì)形成循環(huán)等待。JVM的內(nèi)存區(qū)域是如何劃分的?JVM內(nèi)存區(qū)域(運(yùn)行時(shí)數(shù)據(jù)區(qū))分為以下部分:1.程序計(jì)數(shù)器(PC寄存器):記錄當(dāng)前線程執(zhí)行的字節(jié)碼指令地址,線程私有。若執(zhí)行本地方法,值為undefined。2.虛擬機(jī)棧:線程私有,每個(gè)方法調(diào)用對(duì)應(yīng)一個(gè)棧幀(包含局部變量表、操作數(shù)棧、動(dòng)態(tài)鏈接、方法出口等)。棧深度超過限制會(huì)拋出StackOverflowError(如遞歸未終止),擴(kuò)展失敗拋出OutOfMemoryError(OOM)。3.本地方法棧:與虛擬機(jī)棧類似,用于本地方法(Native方法,如用C實(shí)現(xiàn)的方法)的調(diào)用,HotSpot虛擬機(jī)將其與虛擬機(jī)棧合并。4.堆(Heap):線程共享,存儲(chǔ)對(duì)象實(shí)例和數(shù)組。是GC的主要區(qū)域,分為新生代(Eden區(qū)、Survivor0、Survivor1)和老年代。堆內(nèi)存不足時(shí)拋出OOM。5.方法區(qū):線程共享,存儲(chǔ)類信息(類名、字段、方法、接口)、常量、靜態(tài)變量、即時(shí)編譯器編譯后的代碼等。JDK7前用永久代實(shí)現(xiàn)(受堆內(nèi)存限制),JDK8后用元空間(MetaSpace,使用本地內(nèi)存,默認(rèn)無限制,可通過-XX:MaxMetaspaceSize設(shè)置)。運(yùn)行時(shí)常量池是方法區(qū)的一部分,存儲(chǔ)編譯期提供的字面量和符號(hào)引用(JDK7后字符串常量池移至堆)。此外,直接內(nèi)存(DirectMemory)不屬于JVM運(yùn)行時(shí)數(shù)據(jù)區(qū),但通過Unsafe或NIO的ByteBuffer.allocateDirect()分配,可能導(dǎo)致OOM(總內(nèi)存超過物理內(nèi)存限制)。常見的垃圾回收算法有哪些?各有什么優(yōu)缺點(diǎn)?1.標(biāo)記-清除(Mark-Sweep):先標(biāo)記需要回收的對(duì)象(可達(dá)性分析:從GCRoots出發(fā),標(biāo)記所有可達(dá)對(duì)象,未標(biāo)記的為可回收),然后清除。缺點(diǎn)是會(huì)產(chǎn)生內(nèi)存碎片(空閑內(nèi)存不連續(xù)),可能導(dǎo)致大對(duì)象無法分配時(shí)提前觸發(fā)GC。2.復(fù)制(Copying):將內(nèi)存分為大小相等的兩塊,每次只使用一塊?;厥諘r(shí),將存活對(duì)象復(fù)制到另一塊,然后清空當(dāng)前塊。優(yōu)點(diǎn)是無內(nèi)存碎片,缺點(diǎn)是可用內(nèi)存減半(空間浪費(fèi))。適用于對(duì)象存活率低的場(chǎng)景(如新生代,Eden區(qū)和Survivor區(qū)的8:1:1劃分,實(shí)際只用Eden+一個(gè)Survivor,復(fù)制到另一個(gè)Survivor)。3.標(biāo)記-整理(Mark-Compact):標(biāo)記存活對(duì)象后,將其向內(nèi)存一端移動(dòng)(整理),然后清除邊界外的內(nèi)存。避免了內(nèi)存碎片,適用于對(duì)象存活率高的場(chǎng)景(如老年代)。4.分代收集(GenerationalCollection):根據(jù)對(duì)象存活周期劃分不同區(qū)域(新生代、老年代),采用不同的回收算法。新生代用復(fù)制算法(對(duì)象存活率低),老年代用標(biāo)記-清除或標(biāo)記-整理(對(duì)象存活率高)。HotSpot虛擬機(jī)的Serial、ParNew等收集器在新生代用復(fù)制算法,CMS(ConcurrentMarkSweep)在老年代用標(biāo)記-清除(并發(fā)收集,低停頓),G1(Garbage-First)將堆劃分為多個(gè)Region,混合使用標(biāo)記-整理和復(fù)制算法,目標(biāo)是減少停頓時(shí)間。類加載的過程是怎樣的?類加載器有哪些?類加載過程分為加載、驗(yàn)證、準(zhǔn)備、解析、初始化五個(gè)階段:加載:通過類加載器將.class文件的字節(jié)碼加載到方法區(qū),提供對(duì)應(yīng)的Class對(duì)象。驗(yàn)證:檢查字節(jié)碼的正確性(如文件格式、元數(shù)據(jù)、字節(jié)碼、符號(hào)引用驗(yàn)證),防止惡意或錯(cuò)誤的字節(jié)碼破壞JVM。準(zhǔn)備:為類的靜態(tài)變量分配內(nèi)存并設(shè)置初始值(如int類型初始為0,引用類型為null)。靜態(tài)常量(staticfinal)在編譯時(shí)確定值,準(zhǔn)備階段直接賦值。解析:將符號(hào)引用(如類名、方法名的字符串表示)替換為直接引用(內(nèi)存地址或句柄)。初始化:執(zhí)行類的<clinit>()方法(靜態(tài)變量賦值和靜態(tài)代碼塊的合并),按順序執(zhí)行。類的初始化是惰性的,只有在首次主動(dòng)使用時(shí)觸發(fā)(如創(chuàng)建實(shí)例、調(diào)用靜態(tài)方法、反射獲取類等)。類加載器分為:?jiǎn)?dòng)類加載器(BootstrapClassLoader):C++實(shí)現(xiàn),加載JRE/lib下的核心類(如rt.jar)。擴(kuò)展類加載器(ExtensionClassLoader):Java實(shí)現(xiàn),加載JRE/lib/ext下的擴(kuò)展類。應(yīng)用類加載器(ApplicationClassLoader):Java實(shí)現(xiàn),加載classpath下的用戶類。自定義類加載器:繼承ClassLoader,重寫findClass()方法,用于加載特定路徑或加密的類(如Tomcat的WebappClassLoader)。類加載遵循雙親委派模型:加載類時(shí),先委托父類加載器加載,父類無法加載時(shí)再自己加載。避免重復(fù)加載,保證核心類的安全性(如用戶自定義的java.lang.String不會(huì)被加載)。MySQL中InnoDB和MyISAM存儲(chǔ)引擎的區(qū)別是什么?1.事務(wù)支持:InnoDB支持ACID事務(wù)(默認(rèn)隔離級(jí)別為可重復(fù)讀),MyISAM不支持事務(wù)。2.鎖粒度:InnoDB支持行級(jí)鎖(通過索引實(shí)現(xiàn),非索引條件查詢會(huì)升級(jí)為表鎖),MyISAM僅支持表級(jí)鎖(寫鎖會(huì)阻塞所有讀寫操作)。3.外鍵支持:InnoDB支持外鍵約束,MyISAM不支持。4.索引類型:InnoDB的主鍵索引(聚簇索引)存儲(chǔ)數(shù)據(jù)行,輔助索引存儲(chǔ)主鍵值(需回表查詢);MyISAM的索引(非聚簇)存儲(chǔ)數(shù)據(jù)行的物理地址。5.崩潰恢復(fù):InnoDB通過redolog和undolog實(shí)現(xiàn)崩潰恢復(fù)(CRUD操作先寫日志,再更新數(shù)據(jù)),MyISAM崩潰后可能丟失數(shù)據(jù)。6.統(tǒng)計(jì)總行數(shù):MyISAM的COUNT()效率高(存儲(chǔ)總行數(shù)的元數(shù)據(jù)),InnoDB需遍歷索引統(tǒng)計(jì)(可通過近似值優(yōu)化,如SHOWTABLESTATUS)。7.適用場(chǎng)景:InnoDB適合高并發(fā)、事務(wù)要求高的場(chǎng)景(如訂單系統(tǒng));MyISAM適合讀多寫少、無事務(wù)要求的場(chǎng)景(如日志表)。MySQL5.5及以后默認(rèn)存儲(chǔ)引擎為InnoDB。索引的類型有哪些?如何優(yōu)化索引使用?索引類型按不同維度劃分:數(shù)據(jù)結(jié)構(gòu):B+樹索引(最常用,InnoDB和MyISAM默認(rèn))、哈希索引(Memory引擎支持,等值查詢快,范圍查詢慢)、全文索引(InnoDB5.6+支持,用于文本搜索)。邏輯類型:主鍵索引(唯一且非空)、唯一索引(值唯一,允許null)、普通索引(無約束)、復(fù)合索引(多列組合)。物理存儲(chǔ):聚簇索引(數(shù)據(jù)行與索引存儲(chǔ)在一起,InnoDB主鍵為聚簇索引)、非聚簇索引(索引與數(shù)據(jù)分離,需回表)。索引優(yōu)化方法:選擇區(qū)分度高的列作為索引(如用戶表的user_id比gender區(qū)分度高)。復(fù)合索引遵循最左匹配原則(查詢條件需包含索引的左前綴,如索引(a,b,c)支持a、a+b、a+b+c的查詢,但不支持b或c單獨(dú)查詢)。避免在索引列上使用函數(shù)、計(jì)算或類型轉(zhuǎn)換(如WHEREDATE(create_time)='2023-01-01'會(huì)導(dǎo)致索引失效)。左模糊查詢(LIKE'%xxx')無法使用索引,右模糊(LIKE'xxx%')可以。覆蓋索引(查詢字段都包含在索引中)避免回表,提高效率(如SELECTa,bFROMtWHEREa=1,索引(a,b)是覆蓋索引)。定期分析索引使用情況(通過EXPLAIN查看執(zhí)行計(jì)劃,檢查type是否為ref/eq_ref,Extra是否有Usingindex)。注意:索引不是越多越好,會(huì)增加寫操作(INSERT/UPDATE/DELETE)的開銷(需更新索引),應(yīng)根據(jù)查詢需求合理設(shè)計(jì)。事務(wù)的四大特性(ACID)是什么?MySQL的事務(wù)隔離級(jí)別有哪些?ACID指:原子性(Atomicity):事務(wù)是最小執(zhí)行單位,要么全部提交,要么全部回滾。一致性(Consistency):事務(wù)執(zhí)行前后,數(shù)據(jù)庫(kù)從一個(gè)一致狀態(tài)變?yōu)榱硪粋€(gè)一致狀態(tài)(如轉(zhuǎn)賬后總金額不變)。隔離性(Isolation):多個(gè)事務(wù)并發(fā)執(zhí)行時(shí),互不干擾,避免臟讀、不可重復(fù)讀、幻讀。持久性(Durability):事務(wù)提交后,修改永久保存(通過redolog實(shí)現(xiàn))。MySQL的事務(wù)隔離級(jí)別(由低到高):1.READUNCOMMITTED(讀未提交):允許讀取未提交的事務(wù)修改,存在臟讀(讀取到其他事務(wù)未提交的數(shù)據(jù))。2.READCOMMITTED(讀已提交):只能讀取已提交的數(shù)據(jù),解決臟讀,但存在不可重復(fù)讀(同一事務(wù)內(nèi)兩次查詢結(jié)果不同)。3.REPEATABLEREAD(可重復(fù)讀,默認(rèn)):保證同一事務(wù)內(nèi)多次查詢結(jié)果一致,解決不可重復(fù)讀,但可能存在幻讀(查詢范圍內(nèi)新增數(shù)據(jù),如SELECT后另一個(gè)事務(wù)INSERT,再次SELECT會(huì)看到新數(shù)據(jù))。InnoDB通過MVCC(多版本并發(fā)控制,行記錄的多個(gè)版本)和間隙鎖(鎖定索引間隙)解決幻讀。4.SERIALIZABLE(可串行化):事務(wù)串行執(zhí)行,解決所有并發(fā)問題(臟讀、不可重復(fù)讀、幻讀),但并發(fā)性能最低。選擇隔離級(jí)別時(shí)需權(quán)衡一致性和性能,大多數(shù)場(chǎng)景使用默認(rèn)的REPEATABLEREAD。悲觀鎖和樂觀鎖的區(qū)別是什么?如何實(shí)現(xiàn)?悲觀鎖認(rèn)為并發(fā)沖突概率高,每次操作都先加鎖,防止其他線程修改。MySQL中通過SELECT...FORUPDATE(行鎖,需在事務(wù)中使用)實(shí)現(xiàn),適用于寫多的場(chǎng)景(如庫(kù)存扣減)。樂觀鎖認(rèn)為并發(fā)沖突概率低,不加鎖,更新時(shí)檢查數(shù)據(jù)是否被修改。常見實(shí)現(xiàn):版本號(hào)(Version):表中增加version字段,更新時(shí)WHEREversion=舊值,并version+1。例如UPDATEtSETvalue=新值,version=version+1WHEREid=1ANDversion=舊版本。時(shí)間戳(Timestamp):類似版本號(hào),用最后修改時(shí)間作為條件。樂觀鎖通過CAS(Compare-And-Swap)思想實(shí)現(xiàn),適用于讀多寫少的場(chǎng)景(如評(píng)論點(diǎn)贊)。需注意ABA問題(值從A→B→A,版本號(hào)可解決,因?yàn)榘姹咎?hào)遞增)。如何優(yōu)化慢SQL??jī)?yōu)化慢SQL的步驟:1.定位慢SQL:通過MySQL的慢查詢?nèi)罩荆╯low_query_log)或性能分析工具(如pt-query-digest),記錄執(zhí)行時(shí)間超過long_query_time的SQL。2.分析執(zhí)行計(jì)劃:使用EXPLAIN查看SQL的執(zhí)行計(jì)劃,關(guān)注以下字段:type:訪問類型,從好到差為system>const>eq_ref>ref>range>index>ALL(ALL表示全表掃描,需優(yōu)化)。key:實(shí)際使用的索引,若為null表示未使用索引。rows:MySQL估計(jì)掃描的行數(shù),值越大性能越差。Extra:額外信息,如Usingfilesort(文件排序,需添加索引避免)、Usingtemporary(使用臨時(shí)表,優(yōu)化索引或調(diào)整查詢)。3.優(yōu)化索引:檢查是否缺少合適的索引(如復(fù)合索引),避免索引失效(如函數(shù)、類型轉(zhuǎn)換、左模糊)。4.優(yōu)化查詢語句:避免SELECT,只查詢需要的字段(減少數(shù)據(jù)傳輸量,可能使用覆蓋索引)。減少子查詢,改用JOIN(MySQL對(duì)JOIN的優(yōu)化通常優(yōu)于子查詢)。分頁(yè)查詢優(yōu)化(如LIMIT100000,10,可通過覆蓋索引記錄上次查詢的最大ID,改為WHEREid>last_idLIMIT10)。5.表結(jié)構(gòu)優(yōu)化:拆分大表(垂直拆分按列,水平拆分按行),避免字段過多或數(shù)據(jù)量過大。6.數(shù)據(jù)庫(kù)配置優(yōu)化:調(diào)整innodb_buffer_pool_size(緩沖池大小,建議占物理內(nèi)存50%-70%)、max_connections(最大連接數(shù))等參數(shù)。例如,慢SQL為SELECTFROMordersWHEREuser_id=100ANDstatus=1ORDERBYcreate_timeDESCLIMIT10,若未使用索引,可添加復(fù)合索引(user_id,status,create_time),覆蓋查詢條件和排序,避免全表掃描和文件排序。JDBC的基本操作步驟是什么?PreparedStatement相比Statement有什么優(yōu)點(diǎn)?JDBC操作步驟:1.加載數(shù)據(jù)庫(kù)驅(qū)動(dòng)(如Class.forName("com.mysql.cj.jdbc.

溫馨提示

  • 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)論