成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

真等不及了,沖阿里去了!

開(kāi)發(fā) 前端
聯(lián)合索引遵循最左匹配原則,即在查詢時(shí),只有按照索引字段的順序從最左邊開(kāi)始連續(xù)使用索引字段,索引才會(huì)被使用。因此,根據(jù)最常用作查詢條件的字段放在聯(lián)合索引的最左邊,可以提高索引的利用率。

大家好,我是小林。

阿里巴巴上周開(kāi)啟了 25 屆的實(shí)習(xí)招聘,阿里是Java 一線大廠,到底面試難度如何呢?同學(xué)們準(zhǔn)備好了嗎?

今天分享一位校招同學(xué)阿里的 Java 后端開(kāi)發(fā)的面經(jīng),阿里的風(fēng)格會(huì)比較關(guān)注 Java 和后端組件,而網(wǎng)絡(luò)和系統(tǒng)考察通常都比較少的,所以準(zhǔn)備面阿里的同學(xué) Java 和后端組件這兩方面的要準(zhǔn)備好。

這次的 Java 后端開(kāi)發(fā)的面經(jīng),考察的知識(shí)點(diǎn), 針對(duì)八股文的涉及的內(nèi)容,我?guī)痛蠹伊辛艘幌拢?/p>

  • Java 基礎(chǔ):面向?qū)ο蟆⒍鄳B(tài)、重載
  • Java 集合:HashMap 連環(huán)問(wèn)、紅黑樹(shù)
  • Java并發(fā):volatile、Synchronized、ReentrantLock
  • Java 線程池:線程池參數(shù)、核心線程數(shù)設(shè)置
  • MySQL:索引結(jié)構(gòu)、建立索引規(guī)則、explain、聯(lián)合索引

八股這塊一共問(wèn)了 30 分鐘,其余時(shí)間問(wèn)了項(xiàng)目方面的內(nèi)容。

Java基礎(chǔ)

講一下Java面向?qū)ο蟮奶攸c(diǎn)

封裝、繼承、多態(tài)是Java面向?qū)ο缶幊痰娜筇攸c(diǎn)。

  • 封裝(Encapsulation):封裝是面向?qū)ο缶幊痰幕咎攸c(diǎn)之一,它將數(shù)據(jù)和方法封裝在對(duì)象內(nèi)部,隱藏對(duì)象的內(nèi)部實(shí)現(xiàn)細(xì)節(jié),只暴露必要的接口供外部訪問(wèn)。通過(guò)封裝,可以實(shí)現(xiàn)信息的隱藏和保護(hù),提高代碼的安全性和可靠性。
  • 繼承(Inheritance):繼承是面向?qū)ο缶幊痰闹匾攸c(diǎn),它允許一個(gè)類(lèi)(子類(lèi))繼承另一個(gè)類(lèi)(父類(lèi))的屬性和方法。子類(lèi)可以重用父類(lèi)的代碼,并可以通過(guò)擴(kuò)展和重寫(xiě)來(lái)增加新的功能或修改現(xiàn)有功能。繼承提高了代碼的復(fù)用性和可維護(hù)性,同時(shí)也體現(xiàn)了類(lèi)與類(lèi)之間的關(guān)系。
  • 多態(tài)(Polymorphism):多態(tài)是面向?qū)ο缶幊痰暮诵母拍钪唬试S不同對(duì)象對(duì)同一消息作出不同的響應(yīng)。在Java中,多態(tài)性通過(guò)方法重載和方法重寫(xiě)來(lái)實(shí)現(xiàn)。方法重載是指在同一個(gè)類(lèi)中可以定義多個(gè)同名方法,但參數(shù)列表不同;方法重寫(xiě)是指子類(lèi)可以重寫(xiě)父類(lèi)的方法,實(shí)現(xiàn)不同的行為。多態(tài)性提高了代碼的靈活性和擴(kuò)展性,使得程序更易于理解和維護(hù)。

用過(guò)“多態(tài)”嗎?舉一個(gè)具體例子

一個(gè)具體的例子是,假設(shè)有一個(gè)動(dòng)物類(lèi)(Animal)和它的兩個(gè)子類(lèi):狗類(lèi)(Dog)和貓類(lèi)(Cat)。它們都有一個(gè)名為“makeSound”的方法,但是每種動(dòng)物發(fā)出的聲音是不同的。

class Animal {
    public void makeSound() {
        System.out.println("Some sound");
    }
}

class Dog extends Animal {
    public void makeSound() {
        System.out.println("Woof");
    }
}

class Cat extends Animal {
    public void makeSound() {
        System.out.println("Meow");
    }
}

public class PolymorphismExample {
    public static void main(String[] args) {
        Animal dog = new Dog();
        Animal cat = new Cat();
        
        dog.makeSound(); // 輸出:Woof
        cat.makeSound(); // 輸出:Meow
    }
}

通過(guò)多態(tài)性,可以創(chuàng)建一個(gè)Animal類(lèi)型的引用指向一個(gè)具體的Dog或Cat對(duì)象。當(dāng)調(diào)用這個(gè)引用的“makeSound”方法時(shí),根據(jù)實(shí)際指向的對(duì)象類(lèi)型,會(huì)執(zhí)行相應(yīng)子類(lèi)的方法,從而實(shí)現(xiàn)不同動(dòng)物發(fā)出不同聲音的效果。這樣就體現(xiàn)了多態(tài)的特性,同一個(gè)方法調(diào)用可以產(chǎn)生不同的行為,提高了代碼的靈活性和可擴(kuò)展性。

多態(tài)和重載有什么關(guān)系?

重載是一種編譯時(shí)多態(tài),而多態(tài)是一種運(yùn)行時(shí)多態(tài)。兩者都是實(shí)現(xiàn)多態(tài)性的方式,但發(fā)生的時(shí)間點(diǎn)和機(jī)制不同。

  • 重載是指在同一個(gè)類(lèi)中,方法名相同但參數(shù)列表不同的情況,通過(guò)參數(shù)個(gè)數(shù)、類(lèi)型或順序的不同來(lái)區(qū)分不同的方法。重載是靜態(tài)綁定的概念,編譯器在編譯期間根據(jù)方法的參數(shù)列表來(lái)確定調(diào)用哪個(gè)方法。
  • 多態(tài)是指同一個(gè)方法名可以在不同的類(lèi)中有不同的實(shí)現(xiàn),不同的子類(lèi)可以重寫(xiě)父類(lèi)的方法,通過(guò)父類(lèi)引用指向子類(lèi)對(duì)象時(shí),根據(jù)實(shí)際對(duì)象的類(lèi)型來(lái)確定調(diào)用哪個(gè)方法。多態(tài)是動(dòng)態(tài)綁定的概念,運(yùn)行時(shí)根據(jù)對(duì)象的實(shí)際類(lèi)型來(lái)確定調(diào)用哪個(gè)方法。

Java集合

Java中的HashMap了解嗎?

了解的,HashMap是Java中常用的一種數(shù)據(jù)結(jié)構(gòu),它基于哈希表實(shí)現(xiàn),用于存儲(chǔ)鍵值對(duì)

聊聊HashMap的底層結(jié)構(gòu)

在 JDK 1.7 版本之前, HashMap 數(shù)據(jù)結(jié)構(gòu)是數(shù)組和鏈表,HashMap通過(guò)哈希算法將元素的鍵(Key)映射到數(shù)組中的槽位(Bucket)。如果多個(gè)鍵映射到同一個(gè)槽位,它們會(huì)以鏈表的形式存儲(chǔ)在同一個(gè)槽位上,因?yàn)殒湵淼牟樵儠r(shí)間是O(n),所以沖突很?chē)?yán)重,一個(gè)索引上的鏈表非常長(zhǎng),效率就很低了。

所以在 JDK 1.8 版本的時(shí)候做了優(yōu)化,當(dāng)一個(gè)鏈表的長(zhǎng)度超過(guò)8的時(shí)候就轉(zhuǎn)換數(shù)據(jù)結(jié)構(gòu),不再使用鏈表存儲(chǔ),而是使用紅黑樹(shù),查找時(shí)使用紅黑樹(shù),時(shí)間復(fù)雜度O(log n),可以提高查詢性能,但是在數(shù)量較少時(shí),即數(shù)量小于6時(shí),會(huì)將紅黑樹(shù)轉(zhuǎn)換回鏈表。

圖片圖片

為什么要引入紅黑樹(shù),而不用其他樹(shù)?

  • 為什么不使用二叉排序樹(shù)?問(wèn)題主要出現(xiàn)在二叉排序樹(shù)在添加元素的時(shí)候極端情況下會(huì)出現(xiàn)線性結(jié)構(gòu)。比如由于二叉排序樹(shù)左子樹(shù)所有節(jié)點(diǎn)的值均小于根節(jié)點(diǎn)的特點(diǎn),如果我們添加的元素都比根節(jié)點(diǎn)小,會(huì)導(dǎo)致左子樹(shù)線性增長(zhǎng),這樣就失去了用樹(shù)型結(jié)構(gòu)替換鏈表的初衷,導(dǎo)致查詢時(shí)間增長(zhǎng)。所以這是不用二叉查找樹(shù)的原因。
  • 為什么不使用平衡二叉樹(shù)呢?紅黑樹(shù)不追求"完全平衡",而而AVL是嚴(yán)格平衡樹(shù),因此在增加或者刪除節(jié)點(diǎn)的時(shí)候,根據(jù)不同情況,旋轉(zhuǎn)的次數(shù)比紅黑樹(shù)要多。紅黑樹(shù)讀取略遜于AVL,維護(hù)強(qiáng)于AVL,空間開(kāi)銷(xiāo)與AVL類(lèi)似,內(nèi)容極多時(shí)略優(yōu)于AVL,維護(hù)優(yōu)于AVL。

基本上主要的幾種平衡樹(shù)看來(lái),紅黑樹(shù)有著良好的穩(wěn)定性和完整的功能,性能表現(xiàn)也很不錯(cuò),綜合實(shí)力強(qiáng),在諸如STL的場(chǎng)景中需要穩(wěn)定表現(xiàn)。

HashMap會(huì)出現(xiàn)紅黑樹(shù)一直增高變成無(wú)限高的情況嗎?

不能無(wú)限增長(zhǎng)。當(dāng)集合中的節(jié)點(diǎn)數(shù)超過(guò)了閾值,HashMap會(huì)進(jìn)行擴(kuò)容,這時(shí)原始的紅黑樹(shù)節(jié)點(diǎn)會(huì)被打散,可能會(huì)退化成鏈表結(jié)構(gòu)。

HashMap讀和寫(xiě)的時(shí)間復(fù)雜度是多少?

HashMap的讀取(查找)和寫(xiě)入(插入、更新、刪除)操作的時(shí)間復(fù)雜度均為O(1),即常數(shù)時(shí)間復(fù)雜度。

這是因?yàn)镠ashMap內(nèi)部使用哈希表來(lái)存儲(chǔ)鍵值對(duì),通過(guò)計(jì)算鍵的哈希值可以直接定位到對(duì)應(yīng)的存儲(chǔ)位置,從而實(shí)現(xiàn)快速的讀取和寫(xiě)入操作。

在理想情況下,HashMap可以在常數(shù)時(shí)間內(nèi)完成查找和插入操作,具有高效的性能表現(xiàn)。

HashMap是線程安全的嗎?怎么解決?

不是線程安全的。

  • JDK 1.7 HashMap 采用數(shù)組 + 鏈表的數(shù)據(jù)結(jié)構(gòu),多線程背景下,在數(shù)組擴(kuò)容的時(shí)候,存在 Entry 鏈死循環(huán)和數(shù)據(jù)丟失問(wèn)題。
  • JDK 1.8 HashMap 采用數(shù)組 + 鏈表 + 紅黑二叉樹(shù)的數(shù)據(jù)結(jié)構(gòu),優(yōu)化了 1.7 中數(shù)組擴(kuò)容的方案,解決了 Entry 鏈死循環(huán)和數(shù)據(jù)丟失問(wèn)題。但是多線程背景下,put 方法存在數(shù)據(jù)覆蓋的問(wèn)題。

解決的方式:

  • 使用ConcurrentHashMap:ConcurrentHashMap是Java提供的線程安全的哈希表實(shí)現(xiàn),它通過(guò)分段鎖(Segment)和CAS操作來(lái)保證線程安全性,適用于高并發(fā)環(huán)境。
  • 使用Collections.synchronizedMap:可以通過(guò)Collections工具類(lèi)中的synchronizedMap方法來(lái)創(chuàng)建一個(gè)線程安全的HashMap,該方法會(huì)返回一個(gè)同步的Map對(duì)象,但性能可能不如ConcurrentHashMap。

解決線程安全問(wèn)題還有哪些辦法?

  • 使用同步關(guān)鍵字synchronized:可以通過(guò)在方法或代碼塊上使用synchronized關(guān)鍵字來(lái)實(shí)現(xiàn)線程安全,確保同一時(shí)刻只有一個(gè)線程可以訪問(wèn)共享資源。
  • 使用volatile關(guān)鍵字:可以使用volatile關(guān)鍵字修飾變量,保證變量的可見(jiàn)性,即一個(gè)線程修改了變量的值,其他線程能立即看到最新值,從而避免數(shù)據(jù)不一致的問(wèn)題。
  • 使用線程安全的工具類(lèi):Java中提供了諸如AtomicInteger、AtomicLong、CountDownLatch等線程安全的工具類(lèi),可以幫助解決并發(fā)場(chǎng)景下的線程安全性問(wèn)題。
  • 使用并發(fā)容器:Java中提供了多種線程安全的并發(fā)容器,如ConcurrentLinkedQueue、CopyOnWriteArrayList等,可以替代傳統(tǒng)的非線程安全容器來(lái)解決多線程并發(fā)訪問(wèn)問(wèn)題。

Java并發(fā)

volatile關(guān)鍵字是如何保證內(nèi)存可見(jiàn)性的?底層是怎么實(shí)現(xiàn)的?

volatile關(guān)鍵字通過(guò)兩種機(jī)制來(lái)保證內(nèi)存可見(jiàn)性:

  • 禁止指令重排序:在程序運(yùn)行時(shí),為了提高性能,編譯器和處理器可能會(huì)對(duì)指令進(jìn)行重排序,這可能會(huì)導(dǎo)致變量的更新操作被延遲執(zhí)行或者亂序執(zhí)行,從而使得其他線程無(wú)法立即看到最新的值。使用volatile關(guān)鍵字修飾的變量會(huì)禁止指令重排序,保證變量的更新操作按照代碼順序執(zhí)行。
  • 內(nèi)存屏障(Memory Barrier):在多核處理器架構(gòu)下,每個(gè)線程都有自己的緩存,volatile關(guān)鍵字會(huì)在寫(xiě)操作后插入寫(xiě)屏障(Write Barrier),在讀操作前插入讀屏障(Read Barrier),確保變量的更新能夠立即被其他線程看到,保證內(nèi)存可見(jiàn)性。

通過(guò)禁止指令重排序和插入內(nèi)存屏障,volatile關(guān)鍵字能夠保證被修飾變量的更新操作對(duì)其他線程是可見(jiàn)的,從而有效解決了多線程環(huán)境下的內(nèi)存可見(jiàn)性問(wèn)題。

為什么需要保證內(nèi)存可見(jiàn)性?

如果不保證內(nèi)存可見(jiàn)性,就會(huì)出現(xiàn)數(shù)據(jù)臟讀,一個(gè)線程修改了共享變量的值,但其他線程無(wú)法立即看到最新值,導(dǎo)致其他線程讀取到了過(guò)期數(shù)據(jù),從而產(chǎn)生錯(cuò)誤的結(jié)果。

通過(guò)保證內(nèi)存可見(jiàn)性,避免數(shù)據(jù)不一致性和并發(fā)訪問(wèn)帶來(lái)的問(wèn)題,保證程序的正確性和穩(wěn)定性。

volatile為什么要禁止指令重排,能舉一個(gè)具體的指令重排出現(xiàn)問(wèn)題的例子嗎

禁止指令重排是為了確保程序的執(zhí)行順序與代碼編寫(xiě)順序一致,特別是在多線程環(huán)境下,避免出現(xiàn)意外的結(jié)果。具體來(lái)說(shuō),如果不禁止指令重排,可能會(huì)導(dǎo)致以下問(wèn)題:

舉例來(lái)說(shuō),假設(shè)有如下代碼片段:

int a = 0;
boolean flag = false;

// 線程1
a = 1;
flag = true;

// 線程2
if (flag) {
    System.out.println(a);
}

如果發(fā)生指令重排,可能會(huì)導(dǎo)致線程2在判斷flag時(shí)先于a的賦值操作,那么線程2就會(huì)打印出0,而不是預(yù)期的1。這種情況下,禁止指令重排可以確保線程2在看到flag為true時(shí),也能看到a被正確賦值為1,避免出現(xiàn)問(wèn)題。

因此,通過(guò)禁止指令重排,可以保證程序的執(zhí)行順序符合代碼邏輯,避免出現(xiàn)意外的行為,特別是在涉及多線程并發(fā)的情況下更為重要。

Synchronized的底層原理是什么?鎖升級(jí)的過(guò)程了解嗎?

  • 底層實(shí)現(xiàn):Synchronized關(guān)鍵字底層是使用monitor對(duì)象鎖實(shí)現(xiàn)的,每一個(gè)對(duì)象關(guān)聯(lián)一個(gè)monitor對(duì)象,而monitor對(duì)象可以看成是一個(gè)對(duì)象鎖,它采用互斥的方式讓同一時(shí)刻至多只有一個(gè)線程能持有對(duì)象鎖,其他線程再想獲取這個(gè)對(duì) 象鎖時(shí)會(huì)被阻塞住,這樣就能保證擁有鎖的線程可以安全的執(zhí)行臨界區(qū)的代碼。
  • 鎖升級(jí):是指JVM根據(jù)鎖的競(jìng)爭(zhēng)情況和對(duì)象的狀態(tài),將對(duì)象的鎖從偏向鎖、輕量級(jí)鎖升級(jí)為重量級(jí)鎖的過(guò)程。偏向鎖是指針對(duì)無(wú)競(jìng)爭(zhēng)的情況下,鎖會(huì)偏向于第一個(gè)獲取鎖的線程;輕量級(jí)鎖是指針對(duì)短時(shí)間內(nèi)只有一個(gè)線程競(jìng)爭(zhēng)鎖的情況下,使用CAS操作來(lái)避免阻塞;重量級(jí)鎖是指多個(gè)線程競(jìng)爭(zhēng)同一個(gè)鎖時(shí),通過(guò)操作系統(tǒng)的互斥量來(lái)實(shí)現(xiàn)線程阻塞和喚醒。鎖升級(jí)的過(guò)程是為了提高多線程并發(fā)訪問(wèn)的效率和性能。

線程是怎么確定拿到鎖的?

線程確定拿到鎖的過(guò)程:是通過(guò)檢查鎖的狀態(tài)并嘗試獲取鎖來(lái)實(shí)現(xiàn)的。在JVM中,鎖信息具體是存放在Java對(duì)象頭中的。

當(dāng)一個(gè)線程嘗試進(jìn)入synchronized代碼塊或方法時(shí),JVM會(huì)檢查對(duì)應(yīng)對(duì)象的鎖狀態(tài)。如果對(duì)象的鎖未被其他線程持有,即鎖狀態(tài)為可獲取,那么該線程將成功獲取鎖并進(jìn)入臨界區(qū)執(zhí)行代碼。

鎖信息具體放到哪的?

鎖的狀態(tài)信息是Java對(duì)象頭中的 Mark Word 字段,這個(gè)字段對(duì)象關(guān)于鎖的信息、垃圾回收信息等。

圖片圖片

Java 對(duì)象在內(nèi)存中的表示

JVM通過(guò)操作對(duì)象的頭部信息來(lái)實(shí)現(xiàn)鎖的獲取、釋放以及等待隊(duì)列的管理。當(dāng)線程成功獲取鎖后,對(duì)象的頭部信息會(huì)被更新為當(dāng)前線程的標(biāo)識(shí),表示該線程擁有了這個(gè)鎖。

其他線程在嘗試獲取同一個(gè)鎖時(shí),會(huì)檢查對(duì)象的頭部信息,如果鎖已經(jīng)被其他線程持有,它們將會(huì)被阻塞直到鎖被釋放。

Synchronized加鎖和ReentrantLock加鎖有什么區(qū)別?

synchronized 和 ReentrantLock 都是 Java 中提供的可重入鎖:

  • 用法不同:synchronized 可用來(lái)修飾普通方法、靜態(tài)方法和代碼塊,而 ReentrantLock 只能用在代碼塊上。
  • 獲取鎖和釋放鎖方式不同:synchronized 會(huì)自動(dòng)加鎖和釋放鎖,當(dāng)進(jìn)入 synchronized 修飾的代碼塊之后會(huì)自動(dòng)加鎖,當(dāng)離開(kāi) synchronized 的代碼段之后會(huì)自動(dòng)釋放鎖。而 ReentrantLock 需要手動(dòng)加鎖和釋放鎖
  • 鎖類(lèi)型不同:synchronized 屬于非公平鎖,而 ReentrantLock 既可以是公平鎖也可以是非公平鎖。
  • 響應(yīng)中斷不同:ReentrantLock 可以響應(yīng)中斷,解決死鎖的問(wèn)題,而 synchronized 不能響應(yīng)中斷。
  • 底層實(shí)現(xiàn)不同:synchronized 是 JVM 層面通過(guò)監(jiān)視器實(shí)現(xiàn)的,而 ReentrantLock 是基于 AQS 實(shí)現(xiàn)的。

Java 線程池

線程池了解過(guò)嗎?有哪些核心參數(shù)?

了解過(guò)的,線程池是為了減少頻繁的創(chuàng)建線程和銷(xiāo)毀線程帶來(lái)的性能損耗。

線程池分為核心線程池,線程池的最大容量,還有等待任務(wù)的隊(duì)列,提交一個(gè)任務(wù),如果核心線程沒(méi)有滿,就創(chuàng)建一個(gè)線程,如果滿了,就是會(huì)加入等待隊(duì)列,如果等待隊(duì)列滿了,就會(huì)增加線程,如果達(dá)到最大線程數(shù)量,如果都達(dá)到最大線程數(shù)量,就會(huì)按照一些丟棄的策略進(jìn)行處理。

圖片圖片

線程池的構(gòu)造函數(shù)有7個(gè)參數(shù):

圖片圖片

  • corePoolSize:線程池核心線程數(shù)量。默認(rèn)情況下,線程池中線程的數(shù)量如果 <= corePoolSize,那么即使這些線程處于空閑狀態(tài),那也不會(huì)被銷(xiāo)毀。
  • maximumPoolSize:線程池中最多可容納的線程數(shù)量。當(dāng)一個(gè)新任務(wù)交給線程池,如果此時(shí)線程池中有空閑的線程,就會(huì)直接執(zhí)行,如果沒(méi)有空閑的線程且當(dāng)前線程池的線程數(shù)量小于corePoolSize,就會(huì)創(chuàng)建新的線程來(lái)執(zhí)行任務(wù),否則就會(huì)將該任務(wù)加入到阻塞隊(duì)列中,如果阻塞隊(duì)列滿了,就會(huì)創(chuàng)建一個(gè)新線程,從阻塞隊(duì)列頭部取出一個(gè)任務(wù)來(lái)執(zhí)行,并將新任務(wù)加入到阻塞隊(duì)列末尾。如果當(dāng)前線程池中線程的數(shù)量等于maximumPoolSize,就不會(huì)創(chuàng)建新線程,就會(huì)去執(zhí)行拒絕策略。
  • keepAliveTime:當(dāng)線程池中線程的數(shù)量大于corePoolSize,并且某個(gè)線程的空閑時(shí)間超過(guò)了keepAliveTime,那么這個(gè)線程就會(huì)被銷(xiāo)毀。
  • unit:就是keepAliveTime時(shí)間的單位。
  • workQueue:工作隊(duì)列。當(dāng)沒(méi)有空閑的線程執(zhí)行新任務(wù)時(shí),該任務(wù)就會(huì)被放入工作隊(duì)列中,等待執(zhí)行。
  • threadFactory:線程工廠。可以用來(lái)給線程取名字等等
  • handler:拒絕策略。當(dāng)一個(gè)新任務(wù)交給線程池,如果此時(shí)線程池中有空閑的線程,就會(huì)直接執(zhí)行,如果沒(méi)有空閑的線程,就會(huì)將該任務(wù)加入到阻塞隊(duì)列中,如果阻塞隊(duì)列滿了,就會(huì)創(chuàng)建一個(gè)新線程,從阻塞隊(duì)列頭部取出一個(gè)任務(wù)來(lái)執(zhí)行,并將新任務(wù)加入到阻塞隊(duì)列末尾。如果當(dāng)前線程池中線程的數(shù)量等于maximumPoolSize,就不會(huì)創(chuàng)建新線程,就會(huì)去執(zhí)行拒絕策略。

為什么核心線程滿了之后是先加入阻塞隊(duì)列而不是直接加到總線程?

  • 線程池創(chuàng)建線程需要獲取mainlock這個(gè)全局鎖,會(huì)影響并發(fā)效率,所以使用阻塞隊(duì)列把第一步創(chuàng)建核心線程與第三步創(chuàng)建最大線程隔離開(kāi)來(lái),起一個(gè)緩沖的作用。
  • 引入阻塞隊(duì)列,是為了在執(zhí)行execute()方法時(shí),盡可能的避免獲取全局鎖。

核心線程數(shù)一般設(shè)置為多少?

假設(shè)機(jī)器有N個(gè)CPU:

  • 如果是CPU密集型應(yīng)用,則線程池大小設(shè)置為N+1,線程的應(yīng)用場(chǎng)景:主要是復(fù)雜算法
  • 如果是IO密集型應(yīng)用,則線程池大小設(shè)置為2N+1,線程的應(yīng)用場(chǎng)景:主要是:數(shù)據(jù)庫(kù)數(shù)據(jù)的交互,文件上傳下載,網(wǎng)絡(luò)數(shù)據(jù)傳輸?shù)鹊?/li>

對(duì)于同時(shí)有計(jì)算工作和IO工作的任務(wù),應(yīng)該考慮使用兩個(gè)線程池,一個(gè)處理計(jì)算任務(wù),一個(gè)處理IO任務(wù),分別對(duì)兩個(gè)線程池按照計(jì)算密集型和IO密集型來(lái)設(shè)置線程數(shù)。

IO密集型的線程數(shù)為什么一般設(shè)置為2N+1?

在IO密集型任務(wù)中,線程通常會(huì)因?yàn)镮O操作而阻塞,此時(shí)可以讓其他線程繼續(xù)執(zhí)行,充分利用CPU資源。設(shè)置為2N+1可以保證在有多個(gè)線程阻塞時(shí),仍有足夠的線程可以繼續(xù)執(zhí)行。

MySQL

聊聊MySQL的索引結(jié)構(gòu),為什么使用B+樹(shù)而不用B樹(shù)?

MySQL 默認(rèn)的存儲(chǔ)引擎 InnoDB 采用的是 B+ 作為索引的數(shù)據(jù)結(jié)構(gòu)。

圖片圖片

原因有:

  • B+ 樹(shù)的非葉子節(jié)點(diǎn)不存放實(shí)際的記錄數(shù)據(jù),僅存放索引,因此數(shù)據(jù)量相同的情況下,相比存儲(chǔ)即存索引又存記錄的 B 樹(shù),B+樹(shù)的非葉子節(jié)點(diǎn)可以存放更多的索引,因此 B+ 樹(shù)可以比 B 樹(shù)更「矮胖」,查詢底層節(jié)點(diǎn)的磁盤(pán) I/O次數(shù)會(huì)更少。
  • B+ 樹(shù)有大量的冗余節(jié)點(diǎn)(所有非葉子節(jié)點(diǎn)都是冗余索引),這些冗余索引讓 B+ 樹(shù)在插入、刪除的效率都更高,比如刪除根節(jié)點(diǎn)的時(shí)候,不會(huì)像 B 樹(shù)那樣會(huì)發(fā)生復(fù)雜的樹(shù)的變化;
  • B+ 樹(shù)葉子節(jié)點(diǎn)之間用鏈表連接了起來(lái),有利于范圍查詢,而 B 樹(shù)要實(shí)現(xiàn)范圍查詢,因此只能通過(guò)樹(shù)的遍歷來(lái)完成范圍查詢,這會(huì)涉及多個(gè)節(jié)點(diǎn)的磁盤(pán) I/O 操作,范圍查詢效率不如 B+ 樹(shù)。

你是怎么建立索引的?一般是建立哪些字段的索引呢?

索引最大的好處是提高查詢速度,我經(jīng)常針對(duì)下面場(chǎng)景來(lái)建立索引:

  • 字段有唯一性限制的,比如商品編碼;
  • 經(jīng)常用于 WHERE 查詢條件的字段,這樣能夠提高整個(gè)表的查詢速度,如果查詢條件不是一個(gè)字段,可以建立聯(lián)合索引。
  • 經(jīng)常用于 GROUP BY 和 ORDER BY 的字段,這樣在查詢的時(shí)候就不需要再去做一次排序了,因?yàn)槲覀兌家呀?jīng)知道了建立索引之后在 B+Tree 中的記錄都是排序好的。

怎么確定語(yǔ)句是否走了索引?

可以通過(guò) explian查看執(zhí)行計(jì)劃來(lái)確認(rèn)。

圖片圖片

img

對(duì)于執(zhí)行計(jì)劃,參數(shù)有:

  • possible_keys 字段表示可能用到的索引;
  • key 字段表示實(shí)際用的索引,如果這一項(xiàng)為 NULL,說(shuō)明沒(méi)有使用索引;
  • key_len 表示索引的長(zhǎng)度;
  • rows 表示掃描的數(shù)據(jù)行數(shù)。
  • type 表示數(shù)據(jù)掃描類(lèi)型,我們需要重點(diǎn)看這個(gè)。

如果 typy=all,代表沒(méi)有走索引,進(jìn)行了全表掃描。如果 key 不為 null,說(shuō)明用到了索引。

如果要建立聯(lián)合索引,字段的順序有什么需要注意嗎?

  • 最左匹配原則:聯(lián)合索引遵循最左匹配原則,即在查詢時(shí),只有按照索引字段的順序從最左邊開(kāi)始連續(xù)使用索引字段,索引才會(huì)被使用。因此,根據(jù)最常用作查詢條件的字段放在聯(lián)合索引的最左邊,可以提高索引的利用率。
  • 區(qū)分度高的字段放在前面:將區(qū)分度高的字段放在聯(lián)合索引的前面,可以減少索引的掃描范圍,提高查詢效率。

責(zé)任編輯:武曉燕 來(lái)源: 小林coding
相關(guān)推薦

2015-01-06 11:08:47

CES2015物聯(lián)網(wǎng)蘋(píng)果配件

2013-12-17 10:12:40

微軟CEO

2024-03-08 17:37:47

2023-11-10 17:04:33

2020-09-07 11:36:25

TikTok

2025-04-29 09:03:00

2021-12-06 09:35:38

英偉達(dá)人工智能軟件

2017-08-16 09:55:36

2012-05-18 14:41:04

傲游歌會(huì)

2013-10-21 09:34:26

4GTD-LTE中移動(dòng)

2021-06-30 06:49:49

Windows 11操作系統(tǒng)微軟

2013-12-04 09:31:35

小米路由器小米移動(dòng)電源雷軍

2021-01-19 05:27:44

HTTPSECDHE算法

2023-11-14 07:40:36

阿里云服務(wù)中斷事件

2013-12-15 11:03:59

Windows 9概念圖

2023-04-28 17:24:02

2018-01-18 10:36:05

微信

2011-05-19 13:09:50

Fedora 15

2012-03-26 21:55:34

Lumia 900
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 亚洲一区久久 | 日韩一区二区在线视频 | 国产网站在线 | 久久99成人| 成人免费在线 | 91精品国产综合久久久久久漫画 | 红桃视频一区二区三区免费 | 亚洲午夜精品久久久久久app | 色花av| 国产丝袜一区二区三区免费视频 | 久夜精品 | 日韩视频在线观看中文字幕 | 天天操夜夜操免费视频 | 精品久久久久久久久久久久久久 | 亚洲一区二区在线视频 | jizz中国日本 | 亚洲成人网在线播放 | 网站一区二区三区 | 欧美日韩精品一区 | 久久久久久国产精品 | 天堂中文在线观看 | 夜夜骑首页 | 日韩精品在线播放 | 日本在线一区二区 | 视频第一区 | 国产在线视频一区 | 青青久久av北条麻妃海外网 | 成人网在线观看 | 午夜三级视频 | 夜夜艹 | 国产一级特黄aaa大片评分 | 久久久久久成人 | 欧美一区不卡 | 久久一起草 | 婷婷五月色综合 | 国产精品福利久久久 | 91网站视频在线观看 | 中文字幕不卡在线观看 | 自拍偷拍av | 精品国产欧美一区二区三区成人 | 亚洲一区二区三区福利 |