大家好,我是小林。
秋招進展中,有的同學(xué)投大廠后端沒什么面試機會,就會嘗試投測試開發(fā)崗位。
測試開發(fā)崗會伴隨開發(fā)+測試類的工作,開發(fā)主要是開發(fā)一些測試工具來提高測試效率,也會和根據(jù)業(yè)務(wù)團隊的需求開發(fā)一些工具。
測試開發(fā)的面試其實跟后端開發(fā)差不多,其實被問的問題不會太細節(jié)或者太底層,除此后端的內(nèi)容之外,還會考察一些測試相關(guān)的內(nèi)容。
比如,如何設(shè)計測試用例、黑盒測試和白盒測試有什么區(qū)別、手動測試和自動測試有什么區(qū)別、api 測試工具怎么用等等,甚至也會問,為什么要選擇做測試開發(fā)。所以這類問題, 同學(xué)們在投遞的時候,最好提前準備下。
今天分享一位同學(xué)大廠測開的秋招面試(面試已過),算法做了 2 題,面試問基礎(chǔ)內(nèi)容比較多,難度確實會比后端減少了很多。
面試記錄
1. 項目問題:rabbitmq進行了異步解耦,說說看?
回答:用作消息通知類似的
面試官:那你沒必要用消息隊列,異步任務(wù)就行了,感覺是為了學(xué)做的這個需求,感覺你喜歡把簡單的東西復(fù)雜化(心涼一半)
小林補充
可以說一下為什么要用到mq,比如同樣是掛了的情況,消息隊列有什么異常處理機制,確保消息不丟失這方面提到,當(dāng)然也是要看你的業(yè)務(wù)是否需要確保任務(wù)不丟失。
2. SpringBoot自動裝配介紹一下。
回答:講了一下原理,說了實現(xiàn)了一個starter,封裝了一些日志類,通用的類
3. MySQL查詢緩慢,排查過程?
回答:explain看看有沒有觸發(fā)索引,有慢查詢?nèi)罩镜脑捒梢钥纯慈罩?/p>
4. explain主要關(guān)注哪些字段?
回答:覆蓋索引 記得有個Condition index,還有一個字段是索引長度的記得(全靠回憶小林coding)
小林補充:
需要重點關(guān)注 type 和 extra 字段。
對于執(zhí)行計劃,參數(shù)有:
possible_keys 字段表示可能用到的索引;
key 字段表示實際用的索引,如果這一項為 NULL,說明沒有使用索引;
key_len 表示索引的長度;
rows 表示掃描的數(shù)據(jù)行數(shù)。
type 表示數(shù)據(jù)掃描類型,我們需要重點看這個。
type 字段就是描述了找到所需數(shù)據(jù)時使用的掃描方式是什么,常見掃描類型的執(zhí)行效率從低到高的順序為:
All(全表掃描);
index(全索引掃描);
range(索引范圍掃描);
ref(非唯一索引掃描);
eq_ref(唯一索引掃描);
const(結(jié)果只有一條的主鍵或唯一索引掃描)。
在這些情況里,all 是最壞的情況,因為采用了全表掃描的方式。index 和 all 差不多,只不過 index 對索引表進行全掃描,這樣做的好處是不再需要對數(shù)據(jù)進行排序,但是開銷依然很大。所以,要盡量避免全表掃描和全索引掃描。
range 表示采用了索引范圍掃描,一般在 where 子句中使用 < 、>、in、between 等關(guān)鍵詞,只檢索給定范圍的行,屬于范圍查找。從這一級別開始,索引的作用會越來越明顯,因此我們需要盡量讓 SQL 查詢可以使用到 range 這一級別及以上的 type 訪問方式。
ref 類型表示采用了非唯一索引,或者是唯一索引的非唯一性前綴,返回數(shù)據(jù)返回可能是多條。因為雖然使用了索引,但該索引列的值并不唯一,有重復(fù)。這樣即使使用索引快速查找到了第一條數(shù)據(jù),仍然不能停止,要進行目標值附近的小范圍掃描。但它的好處是它并不需要掃全表,因為索引是有序的,即便有重復(fù)值,也是在一個非常小的范圍內(nèi)掃描。
eq_ref 類型是使用主鍵或唯一索引時產(chǎn)生的訪問方式,通常使用在多表聯(lián)查中。比如,對兩張表進行聯(lián)查,關(guān)聯(lián)條件是兩張表的 user_id 相等,且 user_id 是唯一索引,那么使用 EXPLAIN 進行執(zhí)行計劃查看的時候,type 就會顯示 eq_ref。
const 類型表示使用了主鍵或者唯一索引與常量值進行比較,比如 select name from product where id=1。
需要說明的是 const 類型和 eq_ref 都使用了主鍵或唯一索引,不過這兩個類型有所區(qū)別,const 是與常量進行比較,查詢效率會更快,而 eq_ref 通常用于多表聯(lián)查中。
除了關(guān)注 type,我們也要關(guān)注 extra 顯示的結(jié)果。
這里說幾個重要的參考指標:
Using filesort :當(dāng)查詢語句中包含 group by 操作,而且無法利用索引完成排序操作的時候, 這時不得不選擇相應(yīng)的排序算法進行,甚至可能會通過文件排序,效率是很低的,所以要避免這種問題的出現(xiàn)。
Using temporary:使了用臨時表保存中間結(jié)果,MySQL 在對查詢結(jié)果排序時使用臨時表,常見于排序 order by 和分組查詢 group by。效率低,要避免這種問題的出現(xiàn)。
Using index:所需數(shù)據(jù)只需在索引即可全部獲得,不須要再到表中取數(shù)據(jù),也就是使用了覆蓋索引,避免了回表操作,效率不錯。
5. 索引失效有哪些場景
回答:%x,函數(shù),Or,表本來就不大。
小林補充:
當(dāng)我們使用左或者左右模糊匹配的時候,也就是 like %xx 或者 like %xx%這兩種方式都會造成索引失效;
當(dāng)我們在查詢條件中對索引列使用函數(shù),就會導(dǎo)致索引失效。
當(dāng)我們在查詢條件中對索引列進行表達式計算,也是無法走索引的。
MySQL 在遇到字符串和數(shù)字比較的時候,會自動把字符串轉(zhuǎn)為數(shù)字,然后再進行比較。如果字符串是索引列,而條件語句中的輸入?yún)?shù)是數(shù)字的話,那么索引列會發(fā)生隱式類型轉(zhuǎn)換,由于隱式類型轉(zhuǎn)換是通過 CAST 函數(shù)實現(xiàn)的,等同于對索引列使用了函數(shù),所以就會導(dǎo)致索引失效。
聯(lián)合索引要能正確使用需要遵循最左匹配原則,也就是按照最左優(yōu)先的方式進行索引的匹配,否則就會導(dǎo)致索引失效。
在 WHERE 子句中,如果在 OR 前的條件列是索引列,而在 OR 后的條件列不是索引列,那么索引會失效。
6. 常見索引哪幾類?
回答:非聚簇和聚簇,主鍵索引(淦,記得小林coding里有分,一時想不起來了)
小林補充
按「數(shù)據(jù)結(jié)構(gòu)」分類:B+tree索引、Hash索引、Full-text索引。
按「物理存儲」分類:聚簇索引(主鍵索引)、二級索引(輔助索引)。
按「字段特性」分類:主鍵索引、唯一索引、普通索引、前綴索引。
按「字段個數(shù)」分類:單列索引、聯(lián)合索引。
7. 你知道什么是唯一索引嗎?
回答:Unique
追問:一般干什么用的?只知道是unique不知道是干啥用的是吧?
小林補充
唯一索引主要是為了確保字段的唯一性,通常會對身份證號,學(xué)生號之類具有唯一性約束的字段建立唯一索引。唯一索引的更新性能沒有普通索引高,因為沒辦法利用 changebuffer 的優(yōu)化。
8. TCP和UDP區(qū)別
回答:
TCP面向連接,UDP不在話消息是否到達,QUIC基于UDP實現(xiàn)了類似TCP的可靠傳輸
TCP建立連接要三次握手 四次揮手斷開連接,擁塞控制,阻塞窗口
小林補充
連接方式:TCP是一種面向連接的協(xié)議,通信前需要建立連接。UDP是無連接的,發(fā)送數(shù)據(jù)前無需建立連接。
可靠性:TCP提供了數(shù)據(jù)包的順序、錯誤檢查和重發(fā)機制,因此是一種可靠的協(xié)議。UDP則不保證數(shù)據(jù)包的順序或是否會到達,所以是不可靠的。
速度:由于TCP的這些額外特性,它通常比UDP慢。UDP由于沒有錯誤檢查和重發(fā)機制,因此速度更快。
頭部大小:TCP的頭部大小為20-60字節(jié),而UDP的頭部大小為8字節(jié)。
9. TCP上層協(xié)議有哪些?
回答:Http https 不記得了
小林補充
FTP(文件傳輸協(xié)議)、SMTP(簡單郵件傳輸協(xié)議)
10. DNS是嗎?
回答:是吧
面試官:這個可能不太對 你下去再看看吧(寄)
小林補充
DNS(域名系統(tǒng))通常基于UDP(用戶數(shù)據(jù)報協(xié)議)而非TCP來運作,因為UDP對于DNS的快速請求-應(yīng)答通信模式更為高效。然而,在某些情況下,如當(dāng)DNS響應(yīng)的大小超過UDP的最大包大?。?12字節(jié))或進行區(qū)域傳輸時,DNS會使用TCP。所以,雖然DNS主要使用UDP,但在特定情況下也會使用TCP。
11. 進程和線程的區(qū)別?
回答:
cpu調(diào)度,內(nèi)存調(diào)度
進程獨立,線程基于進程
切換損耗
12. 死鎖是怎么發(fā)生的?
回答:四個必要條件和銀行家算法(上課學(xué)過)
小林補充
死鎖問題的產(chǎn)生是由兩個或者以上線程并行執(zhí)行的時候,爭奪資源而互相等待造成的。
死鎖只有同時滿足互斥、持有并等待、不可剝奪、環(huán)路等待這四個條件的時候才會發(fā)生。
互斥條件
互斥條件是指多個線程不能同時使用同一個資源。
比如下圖,如果線程 A 已經(jīng)持有的資源,不能再同時被線程 B 持有,如果線程 B 請求獲取線程 A 已經(jīng)占用的資源,那線程 B 只能等待,直到線程 A 釋放了資源。
img
持有并等待條件
持有并等待條件是指,當(dāng)線程 A 已經(jīng)持有了資源 1,又想申請資源 2,而資源 2 已經(jīng)被線程 C 持有了,所以線程 A 就會處于等待狀態(tài),但是線程 A 在等待資源 2 的同時并不會釋放自己已經(jīng)持有的資源 1。
img
不可剝奪條件
不可剝奪條件是指,當(dāng)線程已經(jīng)持有了資源 ,在自己使用完之前不能被其他線程獲取,線程 B 如果也想使用此資源,則只能在線程 A 使用完并釋放后才能獲取。
img
環(huán)路等待條件
環(huán)路等待條件指的是,在死鎖發(fā)生的時候,兩個線程獲取資源的順序構(gòu)成了環(huán)形鏈。
比如,線程 A 已經(jīng)持有資源 2,而想請求資源 1, 線程 B 已經(jīng)獲取了資源 1,而想請求資源 2,這就形成資源請求等待的環(huán)形圖。
img
所以要避免死鎖問題,就是要破壞其中一個條件即可,最常用的方法就是使用資源有序分配法來破壞環(huán)路等待條件。
13. os的內(nèi)存管理有分頁和分段了解嗎?
回答:
分段是邏輯方面的,比如函數(shù)會放在一個段,提高復(fù)用性
還能多想一點嗎 虛擬內(nèi)存是分頁還是分段
分頁,記得一個頁面置換
14. 頁面置換有哪些算法?
回答:純靠上課印象了 (LRU、LFU、時鐘)
小林補充
頁面置換算法的功能是,當(dāng)出現(xiàn)缺頁異常,需調(diào)入新頁面而內(nèi)存已滿時,選擇被置換的物理頁面,也就是說選擇一個物理頁面換出到磁盤,然后把需要訪問的頁面換入到物理頁。
那其算法目標則是,盡可能減少頁面的換入換出的次數(shù),常見的頁面置換算法有如下幾種:
最佳頁面置換算法(OPT)
先進先出置換算法(FIFO)
最近最久未使用的置換算法(LRU)
時鐘頁面置換算法(Lock)
最不常用置換算法(LFU)
最佳頁面置換算法
最佳頁面置換算法基本思路是,置換在「未來」最長時間不訪問的頁面。
所以,該算法實現(xiàn)需要計算內(nèi)存中每個邏輯頁面的「下一次」訪問時間,然后比較,選擇未來最長時間不訪問的頁面。
我們舉個例子,假設(shè)一開始有 3 個空閑的物理頁,然后有請求的頁面序列,那它的置換過程如下圖:
最佳頁面置換算法
在這個請求的頁面序列中,缺頁共發(fā)生了 7 次(空閑頁換入 3 次 + 最優(yōu)頁面置換 4 次),頁面置換共發(fā)生了 4 次。
這很理想,但是實際系統(tǒng)中無法實現(xiàn),因為程序訪問頁面時是動態(tài)的,我們是無法預(yù)知每個頁面在「下一次」訪問前的等待時間。
所以,最佳頁面置換算法作用是為了衡量你的算法的效率,你的算法效率越接近該算法的效率,那么說明你的算法是高效的。
先進先出置換算法
既然我們無法預(yù)知頁面在下一次訪問前所需的等待時間,那我們可以選擇在內(nèi)存駐留時間很長的頁面進行中置換,這個就是「先進先出置換」算法的思想。
還是以前面的請求的頁面序列作為例子,假設(shè)使用先進先出置換算法,則過程如下圖:
先進先出置換算法
在這個請求的頁面序列中,缺頁共發(fā)生了 10 次,頁面置換共發(fā)生了 7 次,跟最佳頁面置換算法比較起來,性能明顯差了很多。
最近最久未使用的置換算法
最近最久未使用(LRU)的置換算法的基本思路是,發(fā)生缺頁時,選擇最長時間沒有被訪問的頁面進行置換,也就是說,該算法假設(shè)已經(jīng)很久沒有使用的頁面很有可能在未來較長的一段時間內(nèi)仍然不會被使用。
這種算法近似最優(yōu)置換算法,最優(yōu)置換算法是通過「未來」的使用情況來推測要淘汰的頁面,而 LRU 則是通過「歷史」的使用情況來推測要淘汰的頁面。
還是以前面的請求的頁面序列作為例子,假設(shè)使用最近最久未使用的置換算法,則過程如下圖:
最近最久未使用的置換算法
在這個請求的頁面序列中,缺頁共發(fā)生了 9 次,頁面置換共發(fā)生了 6 次,跟先進先出置換算法比較起來,性能提高了一些。
雖然 LRU 在理論上是可以實現(xiàn)的,但代價很高。為了完全實現(xiàn) LRU,需要在內(nèi)存中維護一個所有頁面的鏈表,最近最多使用的頁面在表頭,最近最少使用的頁面在表尾。
困難的是,在每次訪問內(nèi)存時都必須要更新「整個鏈表」。在鏈表中找到一個頁面,刪除它,然后把它移動到表頭是一個非常費時的操作。
所以,LRU 雖然看上去不錯,但是由于開銷比較大,實際應(yīng)用中比較少使用。
時鐘頁面置換算法
那有沒有一種即能優(yōu)化置換的次數(shù),也能方便實現(xiàn)的算法呢?
時鐘頁面置換算法就可以兩者兼得,它跟 LRU 近似,又是對 FIFO 的一種改進。
該算法的思路是,把所有的頁面都保存在一個類似鐘面的「環(huán)形鏈表」中,一個表針指向最老的頁面。
當(dāng)發(fā)生缺頁中斷時,算法首先檢查表針指向的頁面:
如果它的訪問位位是 0 就淘汰該頁面,并把新的頁面插入這個位置,然后把表針前移一個位置;
如果訪問位是 1 就清除訪問位,并把表針前移一個位置,重復(fù)這個過程直到找到了一個訪問位為 0 的頁面為止;
我畫了一副時鐘頁面置換算法的工作流程圖,你可以在下方看到:
時鐘頁面置換算法
了解了這個算法的工作方式,就明白為什么它被稱為時鐘(Clock)算法了。
最不常用算法
最不常用(LFU)算法,這名字聽起來很調(diào)皮,但是它的意思不是指這個算法不常用,而是當(dāng)發(fā)生缺頁中斷時,選擇「訪問次數(shù)」最少的那個頁面,并將其淘汰。
它的實現(xiàn)方式是,對每個頁面設(shè)置一個「訪問計數(shù)器」,每當(dāng)一個頁面被訪問時,該頁面的訪問計數(shù)器就累加 1。在發(fā)生缺頁中斷時,淘汰計數(shù)器值最小的那個頁面。
看起來很簡單,每個頁面加一個計數(shù)器就可以實現(xiàn)了,但是在操作系統(tǒng)中實現(xiàn)的時候,我們需要考慮效率和硬件成本的。
要增加一個計數(shù)器來實現(xiàn),這個硬件成本是比較高的,另外如果要對這個計數(shù)器查找哪個頁面訪問次數(shù)最小,查找鏈表本身,如果鏈表長度很大,是非常耗時的,效率不高。
但還有個問題,LFU 算法只考慮了頻率問題,沒考慮時間的問題,比如有些頁面在過去時間里訪問的頻率很高,但是現(xiàn)在已經(jīng)沒有訪問了,而當(dāng)前頻繁訪問的頁面由于沒有這些頁面訪問的次數(shù)高,在發(fā)生缺頁中斷時,就會可能會誤傷當(dāng)前剛開始頻繁訪問,但訪問次數(shù)還不高的頁面。
那這個問題的解決的辦法還是有的,可以定期減少訪問的次數(shù),比如當(dāng)發(fā)生時間中斷時,把過去時間訪問的頁面的訪問次數(shù)除以 2,也就說,隨著時間的流失,以前的高訪問次數(shù)的頁面會慢慢減少,相當(dāng)于加大了被置換的概率。
算法(35min+):
數(shù)組中和最接近目標值的三個數(shù)
數(shù)組最大的組合數(shù){3,32,9,912} 組合成9912332
反問:
評價以及哪些方面需要學(xué)習(xí)?
測開崗干啥?
-
算法
+關(guān)注
關(guān)注
23文章
4577瀏覽量
92354 -
計數(shù)器
+關(guān)注
關(guān)注
32文章
2248瀏覽量
94185 -
數(shù)組
+關(guān)注
關(guān)注
1文章
412瀏覽量
25862
原文標題:后端太卷?沖測開去了!
文章出處:【微信號:小林coding,微信公眾號:小林coding】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關(guān)推薦
評論