2023秋招大厂经典面试题及答案整理归纳(141-160)校招必看
目錄
141. 動態(tài)連接庫的兩種方式?
142. IP組播有那些好處?
143. 列舉幾種進(jìn)程的同步機(jī)制及優(yōu)缺點
144. 什么是預(yù)編譯,何時需要預(yù)編譯?
145. int(*s[10])(int)表示的是什么?
146. 交換兩個變量的值,不使用第三個變量.即a=3,b=5,交換 后 a=5,b=3.
147. 要對絕對地址0x100000賦值,我們可以用unsigned int)0xl00000=1234;那么要是想讓程序跳轉(zhuǎn)到絕對地址是 0x100000去執(zhí)行,應(yīng)該怎么做?
148. 線程與進(jìn)程的區(qū)別和聯(lián)系?線程是否具有相同的堆棧?d是否有獨立的堆棧?
149. 用兩個棧實現(xiàn)一個隊列的功能?要求給出算法和思路.
150. 已知一個單向鏈表的頭,請寫出刪除其某一個結(jié)點的算 法,要求,先找到此結(jié)點,然后刪除。
151. 堆棧溢岀一般是由什么原因?qū)е碌?#xff1f;
152. 閱讀下面代碼,回答問題.
153. static全局變量與普通的全局變量有什么區(qū)別? static局部變量和普通局部變量有什么區(qū)別?
154. C++中為什么用模板類。
155. 如何理解軟件的健壯性和高可靠性。
156. 了解哪些linux內(nèi)核的模塊。
157. 畫岀三次握手和四次揮手流程圖。
158. 請闡釋https建立連接過程。
159. innodb引擎的4大特性。
160. MylSAM 和 InnoDB select count(*)哪個更快,為什么?
141. 動態(tài)連接庫的兩種方式?
調(diào)用一個DLL中的函數(shù)有兩種方法:
1. 載入時動態(tài)槌接(load-time dynainic linking),模塊非常明確調(diào)用某 個導(dǎo)岀函數(shù),使得他們就像本地函數(shù)一樣。這需要槌接時槌接那些函數(shù)所在 DLL卽尋入庫,導(dǎo)入庫向系統(tǒng)提供了載入DLL時所需的傷息:及DLL函數(shù)定位。
2. 運(yùn)行時動態(tài)槌接(run-time dynainic linking),運(yùn)行時可以通過 LoadLibrary或LoadLibraryEx函數(shù)載入DLL。DLL載入后,模塊可以通過調(diào) 用GetProcAddress獲取DLL函數(shù)的岀口地址,然后就可以通過返回的函數(shù) 指針調(diào)用DLL函數(shù)了。如此即可避免導(dǎo)入庫文件了。
142. IP組播有那些好處?
Internet ±產(chǎn)生的許多新的應(yīng)用,特別是高帶寬的多媒體應(yīng)用,帶來了帶寬 的急劇消耗和網(wǎng)絡(luò)擁擠問題。組播是一種允許一個或多個發(fā)送者(組播源) 發(fā)送單一的數(shù)據(jù)包到多個接收者(一次的,同時的)的網(wǎng)絡(luò)技術(shù)。組播可以 大大的節(jié)省網(wǎng)絡(luò)帶寬,因為無論有多少個目標(biāo)地址,在整個網(wǎng)絡(luò)的任何一條 鏈路上只傳送單一的數(shù)據(jù)包。所以說組播技術(shù)的核心就是針對如何節(jié)約網(wǎng)絡(luò) 資源的前提下保證服務(wù)質(zhì)量。
143. 列舉幾種進(jìn)程的同步機(jī)制及優(yōu)缺點
1) 信號量機(jī)制:一個信號量只能置一次初值,以后只能對之進(jìn)行p操作或 V操作。
由此也可以看到,信號量機(jī)制必須有公共內(nèi)存,不能用于分布式操作系統(tǒng), 這是它最大的弱點。
2) 自旋鎖:旋鎖是為了保護(hù)共享資源提岀的一種鎖機(jī)制。
調(diào)用者申請的資源如果被占用,即自旋鎖被已經(jīng)被別的執(zhí)行單元保持,則調(diào) 用者一直循環(huán)在那里看是否該自旋鎖的保持著已經(jīng)釋放了鎖.自旋鎖是一 種比較低級的保護(hù)數(shù)據(jù)結(jié)構(gòu)和代碼片段的原始方式,可能會引起以下兩個問
題;
(1) 死鎖
(2) 過多地占用CPU資源
3) 部:信號量機(jī)制功能強(qiáng)大,但使用時對信號量的操作分散,而且難以 控制,讀寫和維護(hù)都很困難。因此后來又提岀了一種集中式同步進(jìn)程一一管 程。其基本思想是將共享變量
和對它們的操作集中在一個模塊中,操作系統(tǒng)或并發(fā)程序就由這樣的模塊構(gòu) 成。這樣模塊之間聯(lián)系清晰,便于維護(hù)和修改,易于保證正確性。
4) 會合:進(jìn)程直接進(jìn)行相互作用
5) 分布式系統(tǒng):由于在分布式操作系統(tǒng)中沒有公共內(nèi)存,因此參數(shù)全為值 參,
希且不可為指針。
優(yōu)缺點:
信號量(Seiwhore)及PV操作
優(yōu):PV操作能夠?qū)崿F(xiàn)對臨界區(qū)的管理要求;實現(xiàn)簡單;允許使用它的代碼休 眠,持有鎖的時間可相對較長。
缺:信號量機(jī)制必須有公共內(nèi)存,不能用于分布式操作系統(tǒng),這是它最大的
弱點。信號量機(jī)制功能強(qiáng)大,但使用時對信號量的操作分散,而且難以控制, 讀寫和維護(hù)都很困難。 加重了程序員的編碼負(fù)擔(dān);核心操作P-V分散在各用戶程序的代碼中,不易 控制和管理;一旦錯誤,后果嚴(yán)重,且不易發(fā)現(xiàn)和糾正。
自旋鎖:
優(yōu):旋鎖是為了保護(hù)共享資源提岀的一種鎖機(jī)制;調(diào)用者申請的資源如 果被占用,即自旋鎖已經(jīng)被別的執(zhí)行單元保持,則調(diào)用者一直循環(huán)在那里看 是否該自旋鎖的保持者
已經(jīng)釋放了鎖;低開銷;安全和高效;
缺:自旋鎖是一種比較低級的保護(hù)數(shù)據(jù)結(jié)構(gòu)和代碼片段的原始方式,可能會 引起以下兩個問題;
(1) 死鎖
(2) 過多地占用CPU資源
傳統(tǒng)自旋鎖由于無序競爭會導(dǎo)致“公平性"問題
優(yōu):集中式同步進(jìn)程一一管程。其基本思想是將共享變量和對它們的操作 集中在一個模塊中,操作系統(tǒng)或并發(fā)程序就由這樣的模塊構(gòu)成。這樣模塊之 間聯(lián)系清晰,便于維護(hù)和修改,
易于保證正確性。
缺:如果一個分布式系統(tǒng)具有多個CPU,并且每個CPU擁有自己的私有內(nèi)存, 它們通過一個局域網(wǎng)相連,那么這些原語將失效。而管程在少數(shù)幾種編程語 言之外又無
荏使用,并且,這些原語均未提供機(jī)器間的信息交換方法。
會合:進(jìn)程直接進(jìn)行相互作用
分布式系統(tǒng):消息和rpc
由于在分布式操作系統(tǒng)中沒有公共內(nèi)存,因此參數(shù)全為值參,而且不可為指針
144. 什么是預(yù)編譯,何時需要預(yù)編譯?
(1) 總是使用不經(jīng)常改動的大型代碼體
(2) 程序由多個模塊組成,所有模塊都使用一組標(biāo)準(zhǔn)的包含文件和相同的編 譯選項。在這種
情況下,可以將所有包含文件預(yù)編譯為一個預(yù)編譯頭
?預(yù)編譯又稱為預(yù)處理,是做些代碼文本的替換工作
處理#開頭的指令,比如拷貝# include包含的文件代碼,# define宏定
義的營換,條件編譯等
就是為編譯做的預(yù)備工作的階段
主要處理#開始的預(yù)編譯指令
預(yù)編譯指令指示了在程序正式編譯前就由編譯器進(jìn)行的操作,可以放 在程序中的任何位置。常見的預(yù)編譯指令有:>>
145. int(*s[10])(int)表示的是什么?
int (*s[10])(int)函數(shù)指正數(shù)組,每個指正指向一個int func(int param) 的函數(shù).
146. 交換兩個變量的值,不使用第三個變量.即a=3,b=5,交換 后 a=5,b=3.
Internet上產(chǎn)生的許多有兩種解放,一種用算術(shù)算法,一種用〃(異或) a=a+b;
b=a-b;
a=a~b;
或者
a二a\;〃只能對 int, char..
b 二 ab
a=a b
147. 要對絕對地址0x100000賦值,我們可以用unsigned int)0xl00000=1234;那么要是想讓程序跳轉(zhuǎn)到絕對地址是 0x100000去執(zhí)行,應(yīng)該怎么做?
*((void(*) ())0x100000) 0;
先要將0x100000強(qiáng)制轉(zhuǎn)換成函數(shù)指針即:(void(*) ())0x100000。然后再調(diào) 用它:
*((void(*) ())0x100000)();用 typedef 可以看得更直觀些:
typedef void(*)() voidFuncPtr;
*((voidFuncPtr)0x100000)();
148. 線程與進(jìn)程的區(qū)別和聯(lián)系?線程是否具有相同的堆棧?d是否有獨立的堆棧?
進(jìn)程是死的,只是一些資源的集合,真正的程序執(zhí)行都是線程來完成的,程序 啟動的時候操作系統(tǒng)就幫你創(chuàng)建線程。每個線程有自己的堆棧。DLL中有沒 有獨立的堆棧,這個問題不好回答,或者說這個問題本身是否有問題。因為DLL中的代碼是被某些線程所執(zhí)行;只有線程擁有堆棧,如果DLL中的代碼是 EXE中的線程所調(diào)用,那么這個時候是不是說這個DLL沒有自己獨立的堆棧? 如果DLL中的代碼是由DLL自己創(chuàng)建的線程所執(zhí)行,那么是不是說DLL有獨 立的堆棧?
以上講的是堆棧,如果對于堆來說,每個DLL有自己的堆,所以如果是從DLL 中動態(tài)分配的內(nèi)存,最好是從DLL中刪除,如果你從DLL中分配內(nèi)存,然后在 EXE中,或者另外一個DLL中刪除,很有可能導(dǎo)致程序崩潰.
149. 用兩個棧實現(xiàn)一個隊列的功能?要求給出算法和思路.
設(shè)2倉棧為AB,—開始均為空
將新元素push入棧B
岀隊
(1) 判斷棧B是否為空;
(2如果不為空,則將棧A中所有元素依次pop岀并push到棧B
(3)將棧B的棧頂元素pop岀 這樣實現(xiàn)的隊列入隊和岀隊的平攤復(fù)雜度都還是0(1).
150. 已知一個單向鏈表的頭,請寫出刪除其某一個結(jié)點的算 法,要求,先找到此結(jié)點,然后刪除。
slnodetype *Delete(slnodetype *Head, int key) {
if (Head->number==key) {
Head二P ointer->nex t;
free(Pointer);
break;
}
Back = Pointer;
Pointer = Pointer-〉next :
if (Pointer->nuinber==key) {
Back->next=Point er->next;
free(Pointcr);
break;
}
void delete(Node* p) {
if (Head二Node)
while(p)
151. 堆棧溢岀一般是由什么原因?qū)е碌?#xff1f;
1. 函數(shù)調(diào)用層次太深。函數(shù)遞歸調(diào)用時,系統(tǒng)要在棧中不斷保存函數(shù)調(diào)用時 的現(xiàn)場和產(chǎn)生的變量,如果遞歸調(diào)用太深,就會造成棧溢岀,這時遞歸無法 返回。再有,當(dāng)函數(shù)調(diào)用層次過深時也可能導(dǎo)致桟無法容納這些調(diào)用的返回 地址而造成棧溢岀。
2. 動態(tài)申請空間使用之后沒有釋放。由于C語言中沒有垃圾資源自動回收機(jī) 制,因此,需要程序主動釋放已經(jīng)不再使用的動態(tài)地址空間。申請的動態(tài)空 間使用的是堆空間,動態(tài)空間使用不會造成堆溢岀。
3. 數(shù)組訪問越界。C語言沒有提供遡組下標(biāo)越界檢查,如果在程序中岀現(xiàn)數(shù) 組下標(biāo)訪問超岀數(shù)組范圍,在運(yùn)行過程中可能會內(nèi)存訪問錯誤。
4. 指針非法訪問。指針保存了一個表法的地址,通過這樣的指針訪問所指向 的地址時會產(chǎn)生內(nèi)存訪問錯誤。
152. 閱讀下面代碼,回答問題.
void GetMemoxy (char int num) {
*p = (char *)malloc(nujn);
void Test (void) {
char *str = HULL;
GetMemoxy (&str, 100); strcpy(str, “hello"); printf (str);
}
mainO {
int a[5]={l,2,3,4,5};
int *ptr= (int *) (&a+l);
printf ("%dj *(a+l), + (ptr-1));
}
請礦i出憶果是?
2,5
解釋:
*(a+l)就是a[l],*(ptrT)就是a[4],執(zhí)行結(jié)果是2, 5。&a+l不是首地址+1, 系統(tǒng)會認(rèn)為加
—個a數(shù)組的偏移,是偏移了一個數(shù)組的大小(本例是5個int)。int
*ptr二(int*) (&a+l);則
ptr實際是&(a[5])也就是a+5
原因如下:
&a是數(shù)組指針,其類型為int (*) [5];而指針加1要根據(jù)指針類型加上一定的 值,不同類型的指針+1之后増加的大小不同;a是長度為5的int數(shù)組指針,所以要加 5*sizeof(int)? 所
以ptr實際是a [5]。但是prt與(&a+l)類型是不一樣的(這點很重要),所以 Ptr-1只會減去
sizeof (int*). a&a的地址是一樣的,但意思不一樣,a是數(shù)組首地址,也就是 aO的地址,
&a是對象(數(shù)組)首地址,a+1是數(shù)組下一元素的地址,即a[l], &a+l是下一個 對象的地址,
即 a[5].
153. static全局變量與普通的全局變量有什么區(qū)別? static局部變量和普通局部變量有什么區(qū)別?
static函數(shù)與普通函數(shù)有什么區(qū)別?
全局變量(外部變量)的說明之前再冠以satic就構(gòu)成了靜態(tài)的全局變量。全 局變量本身就是靜態(tài)存儲方式,靜態(tài)全局變量當(dāng)然也是靜態(tài)存儲方式.這兩 者在存儲方式上并無不同.這兩者的區(qū)別雖在于非靜態(tài)全局變量的作用域是 整個源程序,當(dāng)一個源程序由多個源文件組成時,非靜態(tài)的全局變量在各個 源文件中都是有效的;
而靜態(tài)全局變量則限制了其作用域,即只在定義該變量的源文件內(nèi)有效,在 同一源程序的其它源文件中不能使用它。由于靜態(tài)全局變量的作用域局限于 —個源文件內(nèi),只能為該源文件內(nèi)的函數(shù)公用,因此可以避免在其它源文件 中引起錯誤。從以上分析可以看岀,把局部變量改變?yōu)殪o態(tài)變量后是改變了 它的存儲方式即改變了它的生存期.把全局變量改變?yōu)殪o態(tài)變量后是改變 了它的作用域,限制了它的使用范圍;
static函數(shù)與普通函數(shù)作用域不同.僅在本文件。只在當(dāng)前源文件中使用的 函數(shù)應(yīng)該說明為內(nèi)部函數(shù)(static),內(nèi)部函數(shù)應(yīng)該在當(dāng)前源文件中說明和定 義.對于可在當(dāng)前源文件以外使用的函數(shù),應(yīng)該在一個頭文件中說明,要使用 這些函數(shù)的源文件要包含這個頭文件;
static全局變量與普通的全局變量有什么區(qū)別:static全局變量只初使化 —次,防止在其他文件單元中被引用;
static局部變里和普通局部變里有什么區(qū)別:static局部變里只被初始化 —次,下一次依據(jù)上一次結(jié)果值;
static兇數(shù)與晉通兇數(shù)有什么區(qū)別:static兇數(shù)在內(nèi)存中只有一份,晉通函 數(shù)在每個被條用中維持一份拷貝;
154. C++中為什么用模板類。
(1) 可用來創(chuàng)建動態(tài)増長和減小的數(shù)據(jù)結(jié)構(gòu)
(2) 它是類型無關(guān)的,因此具有很高的可復(fù)用性。
(3) 它在編譯時而不是運(yùn)行時檢查數(shù)據(jù)類型,保證了類型安全
(4) 它是平臺無關(guān)的,可移植性
(5) 可用于基本數(shù)據(jù)類型
155. 如何理解軟件的健壯性和高可靠性。
mt性:
健壯性具體指的是系統(tǒng)在不正常的輸入或不正常的外部環(huán)境下仍能表現(xiàn)岀 正常的程度.
面向健壯性的編程有以下幾點要求或優(yōu)點:
處理未期望的行為和錯誤終止
即使終止執(zhí)行,也要準(zhǔn)確/無歧義的向用戶展示全面的錯誤信息
錯誤信息有助于進(jìn)行debug
健壯性原則:
總是假定用戶為惡意用戶,假定自己的代碼會失敗
把用戶想象成一個silly b,可能輸岀任何東西
注意,因為用戶很silly,最好要返回給用戶錯誤提示信息,而且要詳細(xì)準(zhǔn) 確無歧義!(其實這對debug非常有幫助,尤其是像我這樣喜歡用syso找 蟲子的白癡CodeDog)
對自己的代碼要保守,對用戶的行為要開放
面向健壯性編程的原則:
封閉實現(xiàn)細(xì)節(jié),限定用戶的惡意行為
考慮各種各樣的極端情況,沒有possible
高可靠性:
高可靠性(high reliability)指的是運(yùn)行時間能夠滿足預(yù)計時間的一個系 統(tǒng)或組件。
在信息技術(shù)領(lǐng)域,高可靠性(high reliability)指的是運(yùn)行時間能夠滿足 預(yù)計時間的一個系統(tǒng)或組件。可靠性可以用“100%可操作性”或者“從未失 敗”這兩種標(biāo)準(zhǔn)來表示。一個被廣泛應(yīng)用但卻難以達(dá)到的標(biāo)準(zhǔn)是著名的“5 個9標(biāo)準(zhǔn)”,就是說工作的可靠性要達(dá)到99. 999%o
由于一個計算機(jī)系統(tǒng)或網(wǎng)絡(luò)由許多部件組成,而且這些部件都要保證高可靠 性才能纟隹持正常的操作過程。因此,許多可靠性計劃側(cè)重于備份、故障處理、 數(shù)據(jù)存儲以及訪問方面。對存儲而言,一個普遍釆用的方法是冗余磁盤陣列, 最近釆用存儲局域網(wǎng)。
—些可靠性專家強(qiáng)調(diào),為保證高可靠性,系統(tǒng)的任何部件都要進(jìn)行仔細(xì)的規(guī) 劃設(shè)計,并在投入運(yùn)行前進(jìn)行徹底的檢查測試工作。比如說,一個未經(jīng)徹底 測試的新的應(yīng)用程序在運(yùn)行過程中很可能岀現(xiàn)頻繁的中斷。
156. 了解哪些linux內(nèi)核的模塊。
Linux內(nèi)核的五大模塊1.進(jìn)程調(diào)度模塊2.內(nèi)存管理模塊3.文件系統(tǒng)模塊
4.進(jìn)程間通信模塊5.網(wǎng)絡(luò)接口模塊
進(jìn)程調(diào)度模塊
用來負(fù)責(zé)控制進(jìn)程對CPU資源的使用。所釆取的調(diào)度策略是各進(jìn)程能夠公平 合理地訪問CPU,同時保證內(nèi)核能及時地執(zhí)行硬件操作。
內(nèi)g里模塊
用于確保所有進(jìn)程能夠安全地共享機(jī)器主內(nèi)存區(qū),同時,內(nèi)存管理模塊還 支持虛擬內(nèi)存管理方式,使得Linux支持進(jìn)程使用比實際內(nèi)存空間更多的 內(nèi)存容量。并可以利用文件系統(tǒng),對暫時不用的內(nèi)存數(shù)據(jù)塊交換到外部存儲 設(shè)備上去,當(dāng)需要時再交換回來。
文件系繼塊
用于支持對外部設(shè)備的驅(qū)動和存儲。虛擬文件系統(tǒng)模塊通過向所有的外部存 儲設(shè)備提供一個通用的文件接口,隱藏了各種硬件設(shè)備的不同細(xì)節(jié)。從而提 供并支持與其它操作系統(tǒng)兼容的多種文件系統(tǒng)格式。
進(jìn)程間通信模塊
用于支持多種進(jìn)程間的信息交換方式
網(wǎng)絡(luò)接口模塊
提供對多種網(wǎng)絡(luò)通信標(biāo)準(zhǔn)的訪問并支持許多網(wǎng)絡(luò)硬件
157. 畫岀三次握手和四次揮手流程圖。
TCP三次握手
?
TCP四次揮手
?
| Client | Server | ||
| r | |||
| FIN WAIT 11~ ~ r— | FIN A | ||
| 1— _ | |||
| A | CLOSE WAIT | ||
| ack 四] 一—- | ! | ||
| FIN_WAIT_2 | —— | LAST_ACK | |
| FIN N | 1 | ||
| 1 | |||
| TIME_WAIT 1—一 | — 1 | ||
| r ~ | ACK=1 ac<=K+l | ||
| 一 | 一 | 1 CLOSED |
158. 請闡釋https建立連接過程。
建立連接
成TP和HTTPS都需要在建立連接的基礎(chǔ)上來進(jìn)行數(shù)據(jù)傳輸,是基本操作 當(dāng)客戶在瀏覽器中輸入網(wǎng)址的并且按下回車,瀏覽器會在瀏覽器DNS緩存, 本地DNS緩存,和Hosts中尋找對應(yīng)的記錄,如果沒有獲取到則會請求 DNS服務(wù)來獲取對應(yīng)的ip
當(dāng)獲取到ip后,tcp連接會進(jìn)行三次握手建立連接
tcp的三次揮手和四次揮手
過程簡圖
三次揮手(建立連接)
第一次:建立連接時,客戶端發(fā)送SYN包(syn=j)到服務(wù)器,并進(jìn)入 SYN.SEND狀態(tài),等待服務(wù)器確認(rèn);
第二次:服務(wù)器收到SYN包,向客戶端返回ACK (ack=j+1),同時自己也 發(fā)送一個SYN包(syn=k),即SYNUCK包,此時服務(wù)器進(jìn)入SYN_RCVD狀 態(tài);
第三次:客戶端收到服務(wù)器的SYN+ACK包,向服務(wù)器發(fā)送確認(rèn)包
ACK(ack=k+1),此包發(fā)送完畢,客戶端和服務(wù)器進(jìn)入ESTABLISHED狀態(tài), 完成三次握手。
完成三次握手,客戶端與服務(wù)器開始傳送數(shù)據(jù),也就是ESTABLISHED狀態(tài)。 三次握手保證了不會建立無效的連接,從而浪費(fèi)資源。
四次揮手(斷開連接)
第一次:TCP客戶端發(fā)送一個FIN,用來關(guān)閉客戶到服務(wù)器的敖據(jù)傳送。
第二次:服務(wù)器收到這個FIN,它發(fā)回一個ACK,確認(rèn)序號為收到的序號加
1。和SYN —樣,一個FIN將占用一個序號。
第三次:服務(wù)器關(guān)閉客戶端的連接,發(fā)送一個FIN給客戶端。
第四次:客戶端發(fā)回ACK報文確認(rèn),并將確認(rèn)序號設(shè)置為收到序號加1。
HTTP請求過程
建立連接完畢以后客戶端會發(fā)送響應(yīng)給服務(wù)端
服務(wù)端接受請求并且做岀響應(yīng)發(fā)送給客戶端
客戶端收到響應(yīng)并且解析響應(yīng)響應(yīng)給客戶
client?■?server
發(fā)送客戶端支持的加密辦議及版本,SSL. TLS
服務(wù)器端從中篩選選擇合適的加密協(xié)議
服務(wù)器端返I叫證書,證書中有公鑰 客戶端使用根證書驗證證書合法性
j客戶端生成對稱密鑰,通過證I弓中的公鑰加密,發(fā)送到服務(wù)器端j
!服務(wù)器端使用私鑰解密,獲取對稱密鑰,使用對稱密鑰加密數(shù)據(jù)[
客戶端解密數(shù)據(jù),SSL開始通信...
在使用HTTPS是需要保證服務(wù)端配置正確了對應(yīng)的安全證書
客戶端發(fā)送請求到服務(wù)端
服務(wù)端返回公鑰和證書到客戶端
客戶端接收后會驗證證書的安全性,如果通過則會隨機(jī)生成一個隨機(jī)數(shù),用 公鑰對其加密,發(fā)送到服務(wù)端
服務(wù)端接受到這個加密后的隨機(jī)數(shù)后會用私鑰對其解密得到真正的隨機(jī)數(shù), 隨后用這個隨機(jī)數(shù)當(dāng)做私鑰對需要發(fā)送的數(shù)據(jù)進(jìn)行對稱加密
客戶端在接收到加密后的數(shù)據(jù)使用私鑰(即生成的隨機(jī)值)對數(shù)據(jù)進(jìn)行解密 并且解析數(shù)據(jù)呈現(xiàn)結(jié)果給客戶
SSL加密建立
159. innodb引擎的4大特性。
innodb引擎的4大特性1.插入緩沖;2.二次寫;3.自適應(yīng)哈希;4.預(yù)讀
1 ?插入緩沖(insert buffer)
插入緩神(Insert Buffer/Change Buffer):提升插入性能,change buffering 是 insert buffer 的加強(qiáng),insert buffer 只針對 insert 有效,change buffering 對 insert、 deletes update (delete+insert)、purge 都有效 只對于非聚集索引(非唯一)的插入和更新有效,對于每一次的插入不是寫 到索引頁中,而是先判斷插入的非聚集索引頁是否在緩沖池中,如果在則直 接插入;若不在,則先放到Insert Buffer中,再按照一定的頻率進(jìn)行合并 操作,再寫回disk。這樣通常能將多個插入合并到一個操作中,目的還是為 了減少隨機(jī)10帶來性能損耗。
使用插入緩沖的條件:
*非聚集索引
*非唯一索引
Change buffer是作為buffer pool中的一部分存在。
Innodb_change_buffering參數(shù)緩存所對應(yīng)的操作:(update會被認(rèn)為是 delete+insert)
innodb_change_buffering,設(shè)置的值有:insertSs deletesx purgess changes (inserts ft deletes)、all (默認(rèn))、none。
all:默認(rèn)值,緩存 insert, delete, purges 操作
none:不緩存
inserts:緩存 insert 操作
deletes:緩存 delete 操作
changes:緩存 insert 和 delete 操作
purges:緩存后臺執(zhí)行的物理刪除操作
可以通過參數(shù)控制其使用的大小:
innodb_change_buffer_max_size,默認(rèn)是 25%,即緩沖池的 1/4。最大可設(shè)
置為50%。當(dāng)MySQL實例中有大量的修改操作時,要考慮増大
innodb_change_buffer_max_size
上面提過在一定頻率下進(jìn)行合并,那所謂的頻率是什么條件?
1) 輔助索引頁被讀取到緩沖池中。正常的select先檢查Insert Buffer是 否有該非聚集索引頁存在,若有則合并插入。
2) 輔助索引頁沒有可用空間。空間"于1/32頁的大小,則會強(qiáng)制合并操作。
3) Master Thread每秒和每10秒的合并操作。
2.二次寫(double write)
Doublewrite緩存是位于系統(tǒng)表空間的存儲區(qū)域,用來緩存InnoDB的數(shù)據(jù)頁 從innodb buffer pool申flush之后并寫入到數(shù)據(jù)文件之前,所以當(dāng)操作 系統(tǒng)或者數(shù)據(jù)庫進(jìn)程在數(shù)據(jù)頁寫磁盤的過程中崩潰,Innodb可以在 doublewrite緩存中找到數(shù)據(jù)頁的備份而用來執(zhí)行crash恢復(fù)。數(shù)據(jù)頁寫入 到doublewrite緩存的動作所需要的10消耗要小于寫入到數(shù)據(jù)文件的消耗, 因為此寫入操作會以一次大的連續(xù)塊的方式寫入 在應(yīng)用(apply)重做日志前,用戶需要一個頁的副本,當(dāng)寫入失效發(fā)生時, 先通過頁的副本半還原該頁,再進(jìn)行重做,這就是double write doubl ewri t e 組成:
內(nèi)存中的 doublewrite buffer,大小 2M。
物理磁盤上共享表空間中連續(xù)的128個頁,即2個區(qū)(extend),大小同樣 為2M。
對緩沖池的臟頁進(jìn)行刷新時,不是直接寫磁盤,而是會通過memcpy ()函數(shù)將 臟頁先復(fù)制到內(nèi)存中的doublewrite buffer,之后通過doublewrite再分 兩次,每次1M順序地寫入共享表空間的物理磁盤上,在這個過程中,因為 doub lewr i t e頁是連續(xù)的,因此這個過程是順序?qū)懙?#xff0c;開銷并不是很大。在 完成doublewrite頁的寫入后,再將doublewrite buffer中的頁寫入各個 表空間文件中,此時的寫入則是離散的。如果操作系統(tǒng)在將頁寫入磁盤的過 程中發(fā)生了崩潰,在恢復(fù)過程中,innodb可以從共享表空間中的doublewrite 中找到該頁的一個副本,將其復(fù)制到表空間文件,再應(yīng)用重做日志。
3.?自適應(yīng)哈希索引(ahi)
Adaptive Hash index屬性使得InnoDB更像是內(nèi)存數(shù)據(jù)庫。該屬性通過
innodb_adapi t ve_hash_index 開啟,也可以通過一
skip-i nno db_adap t i ve_hash_i nde x 參數(shù)
關(guān)閉
Innodb存儲引擎會監(jiān)控對表上二級索引的查找,如果發(fā)現(xiàn)某二級索引被頻繁 訪問,二級索引成為熱數(shù)據(jù),建立哈希索引可以帶來速度的提升
經(jīng)常訪問的二級索引數(shù)據(jù)會自動被生成到hash索引里面去(最近連續(xù)被訪問 三次的數(shù)據(jù)),自適應(yīng)哈希索引通過緩沖池的B+樹構(gòu)造而來,因此建立的速 度很快。
哈希(hash)是一種非常快的等值查找方法,在一般情況下這種查找的時間 復(fù)雜度為0(1),即一般僅需要一次查找就能定位數(shù)據(jù)。而B+樹的查找次數(shù), 取決于B+樹的高度,在生產(chǎn)環(huán)境中,B+樹的高度一般3-4層,故需要3-4 次的查詢。
innodb會監(jiān)控對表上個索引頁的查詢。如果觀察到建立哈希索引可以帶來速 度提升,則自動建立哈希索引,稱之為自適應(yīng)哈希索引(Adaptive Hash Index, AHI)。
AHI有一個要求,就是對這個頁的連續(xù)訪問模式必須是一樣的。
例如對于(a,b)訪問模式情況:
where a = xxx
where a - xxx and b - xxx
特點:
"l、無序,沒有樹高
2、降低對二級索引樹的頻繁訪問資源,索引樹高S4,訪問索引:訪問 樹、根節(jié)點、葉子節(jié)占,"適應(yīng)
缺陷:
1、 hash自適應(yīng)索引會占用innodb buffer pool;
2、 自適應(yīng)hash索引只適合搜索等值的查詢,如select * from table where index_col='xxx',
而對于宜祉查找類型,如范圍查找,是不能使用的;
3、 極端情況下,自適應(yīng)hash索引才有比較大的意義,可以降低邏輯讀。
4.?預(yù)讀(read ahead)
InnoDB使用兩種預(yù)讀算法來提高I性邰:線性預(yù)讀(linear read-ahead) 和隨機(jī)預(yù)讀(randomread-ahead)
為了區(qū)分這兩種預(yù)讀的方式,我們可以把線性預(yù)讀放到以extent為單位, 而隨機(jī)預(yù)讀放到以extent申的page為單位。線性預(yù)讀著眼于將下一個 extent提前讀取到buffer pool中,而隨機(jī)預(yù)讀著眼于將當(dāng)前extent中的 剩余的page提前讀取到buffer pool中。
線性預(yù)讀(linear read-ahead)
方式有一個很重要的變量控制是否將下一個extent預(yù)讀到buffer pool * , 通過使用配置參數(shù)innodb_read_ahead_threshold,可以控制Innodb執(zhí)行預(yù) 讀操作的時間。如果一個extent中的被順序讀取的page超過或者等于該參 數(shù)變量時,Innodb將會異步的將下一個extent讀取到buffer pool中, innodb_read_ahead_thresho 1 d可以設(shè)置為0-64的任何值,默認(rèn)值為56, 值越高,訪問模式檢查越嚴(yán)格
例如,如果將值設(shè)置為48,則InnoDB只有在順序訪問當(dāng)前extent中的48 個pages時才觸發(fā)線性預(yù)讀請求,將下一個extent讀到內(nèi)存中。如果值為8, InnoDB觸發(fā)異步預(yù)讀,即使程序段中只有8頁被順序訪問。你可以在MySQL 配置文件中設(shè)置此參數(shù)的值,或者使用SET GLOBAL需要該SUPER權(quán)限的命 令動態(tài)更改該參數(shù)。
在沒有該變量之前,當(dāng)訪問到extent的最后一個page的時候,Innodb會決 定是否將下一個extent放入到buffer pool中。
隨機(jī)預(yù)讀(r andomr e ad-ahe ad)
隨機(jī)預(yù)讀方式則是表示當(dāng)同一個extent中的一些page在buffer pool中發(fā) 現(xiàn)時,Innodb會將該extent中的剩余page —并讀到buffer pool中,由于 隨機(jī)預(yù)讀方式給Innodb code帶來了一些不必要的復(fù)雜性,同時在性能也存 在否舊定性,在5. 5中已經(jīng)將這種預(yù)讀方式廢棄。要啟用此功能,請將配置 變量設(shè)置 innodb_randoiri_read_ahead 為 0N。
160. MylSAM 和 InnoDB select count(*)哪個更快,為什么?
MvISAM快,因為旳ISAM本身就記錄了數(shù)量,而InnoDB要掃描數(shù)據(jù)。
秋招大廠經(jīng)典面試題及答案整理不斷更新中,感興趣且正在學(xué)習(xí)的同學(xué)可以點個關(guān)注;獅會不斷更新文章連載,有問題或者見解可以評論區(qū)討論。
總結(jié)
以上是生活随笔為你收集整理的2023秋招大厂经典面试题及答案整理归纳(141-160)校招必看的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。