0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

字節(jié)很會(huì)面試,追著項(xiàng)目技術(shù)拷打

小林coding ? 來源:小林coding ? 2023-08-04 16:02 ? 次閱讀

大家好,我是小林。

周五了,還是得卷一卷。今天分享一篇字節(jié)后端面經(jīng),因?yàn)轫?xiàng)目是搞了黑馬點(diǎn)評(píng),這個(gè)是用 redis 比較多的項(xiàng)目。

所以這次面經(jīng)重點(diǎn)拷打了 redis 問題,什么大key,熱 key 問題。其余還拷打了mysql、操作系統(tǒng)、網(wǎng)絡(luò)、java 問題。

Redis

你用到了Redis,那么Redis還可以做什么?

Redis 是一種基于內(nèi)存的數(shù)據(jù)庫,對(duì)數(shù)據(jù)的讀寫操作都是在內(nèi)存中完成,因此讀寫速度非常快,常用于緩存,消息隊(duì)列、分布式鎖等場(chǎng)景。

43491be2-3299-11ee-9e74-dac502259ad0.jpg

img

Redis 提供了多種數(shù)據(jù)類型來支持不同的業(yè)務(wù)場(chǎng)景,比如 String(字符串)、Hash(哈希)、 List (列表)、Set(集合)、Zset(有序集合)、Bitmaps(位圖)、HyperLogLog(基數(shù)統(tǒng)計(jì))、GEO(地理信息)、Stream(流),并且對(duì)數(shù)據(jù)類型的操作都是原子性的,因?yàn)閳?zhí)行命令由單線程負(fù)責(zé)的,不存在并發(fā)競(jìng)爭(zhēng)的問題。

除此之外,Redis 還支持事務(wù) 、持久化、Lua 腳本、多種集群方案(主從復(fù)制模式、哨兵模式、切片機(jī)群模式)、發(fā)布/訂閱模式,內(nèi)存淘汰機(jī)制、過期刪除機(jī)制等等。

講下Redis的ZSet

Zset 類型的底層數(shù)據(jù)結(jié)構(gòu)是由壓縮列表或跳表實(shí)現(xiàn)的:

如果有序集合的元素個(gè)數(shù)小于 128 個(gè),并且每個(gè)元素的值小于 64 字節(jié)時(shí),Redis 會(huì)使用壓縮列表作為 Zset 類型的底層數(shù)據(jù)結(jié)構(gòu);

如果有序集合的元素不滿足上面的條件,Redis 會(huì)使用跳表作為 Zset 類型的底層數(shù)據(jù)結(jié)構(gòu);

在 Redis 7.0 中,壓縮列表數(shù)據(jù)結(jié)構(gòu)已經(jīng)廢棄了,交由 listpack 數(shù)據(jù)結(jié)構(gòu)來實(shí)現(xiàn)了。

ZSet 的范圍查詢時(shí)間復(fù)雜度是多少?

Redis的ZSet的范圍查詢命令ZRANGE的時(shí)間復(fù)雜度是O(log(N)+M),其中N是有序集合的元素?cái)?shù)量,M是返回的元素?cái)?shù)量。

講一下跳表

鏈表在查找元素的時(shí)候,因?yàn)樾枰鹨徊檎?,所以查詢效率非常低,時(shí)間復(fù)雜度是O(N),于是就出現(xiàn)了跳表。跳表是在鏈表基礎(chǔ)上改進(jìn)過來的,實(shí)現(xiàn)了一種「多層」的有序鏈表,這樣的好處是能快讀定位數(shù)據(jù)。

那跳表長什么樣呢?我這里舉個(gè)例子,下圖展示了一個(gè)層級(jí)為 3 的跳表。

4352ca7a-3299-11ee-9e74-dac502259ad0.png

img

圖中頭節(jié)點(diǎn)有 L0~L2 三個(gè)頭指針,分別指向了不同層級(jí)的節(jié)點(diǎn),然后每個(gè)層級(jí)的節(jié)點(diǎn)都通過指針連接起來:

L0 層級(jí)共有 5 個(gè)節(jié)點(diǎn),分別是節(jié)點(diǎn)1、2、3、4、5;

L1 層級(jí)共有 3 個(gè)節(jié)點(diǎn),分別是節(jié)點(diǎn) 2、3、5;

L2 層級(jí)只有 1 個(gè)節(jié)點(diǎn),也就是節(jié)點(diǎn) 3 。

如果我們要在鏈表中查找節(jié)點(diǎn) 4 這個(gè)元素,只能從頭開始遍歷鏈表,需要查找 4 次,而使用了跳表后,只需要查找 2 次就能定位到節(jié)點(diǎn) 4,因?yàn)榭梢栽陬^節(jié)點(diǎn)直接從 L2 層級(jí)跳到節(jié)點(diǎn) 3,然后再往前遍歷找到節(jié)點(diǎn) 4。

可以看到,這個(gè)查找過程就是在多個(gè)層級(jí)上跳來跳去,最后定位到元素。當(dāng)數(shù)據(jù)量很大時(shí),跳表的查找復(fù)雜度就是 O(logN)。

跳表是怎么設(shè)置層高的?

跳表在創(chuàng)建節(jié)點(diǎn)時(shí)候,會(huì)生成范圍為[0-1]的一個(gè)隨機(jī)數(shù),如果這個(gè)隨機(jī)數(shù)小于 0.25(相當(dāng)于概率 25%),那么層數(shù)就增加 1 層,然后繼續(xù)生成下一個(gè)隨機(jī)數(shù),直到隨機(jī)數(shù)的結(jié)果大于 0.25 結(jié)束,最終確定該節(jié)點(diǎn)的層數(shù)。

哈希表是怎么擴(kuò)容的?

為了避免 rehash 在數(shù)據(jù)遷移過程中,因拷貝數(shù)據(jù)的耗時(shí),影響 Redis 性能的情況,所以 Redis 采用了漸進(jìn)式 rehash,也就是將數(shù)據(jù)的遷移的工作不再是一次性遷移完成,而是分多次遷移。

漸進(jìn)式 rehash 步驟如下:

給「哈希表 2」 分配空間;

在 rehash 進(jìn)行期間,每次哈希表元素進(jìn)行新增、刪除、查找或者更新操作時(shí),Redis 除了會(huì)執(zhí)行對(duì)應(yīng)的操作之外,還會(huì)順序?qū)ⅰ腹1?1 」中索引位置上的所有 key-value 遷移到「哈希表 2」 上;

隨著處理客戶端發(fā)起的哈希表操作請(qǐng)求數(shù)量越多,最終在某個(gè)時(shí)間點(diǎn)會(huì)把「哈希表 1 」的所有 key-value 遷移到「哈希表 2」,從而完成 rehash 操作。

這樣就巧妙地把一次性大量數(shù)據(jù)遷移工作的開銷,分?jǐn)偟搅硕啻翁幚碚?qǐng)求的過程中,避免了一次性 rehash 的耗時(shí)操作。

在進(jìn)行漸進(jìn)式 rehash 的過程中,會(huì)有兩個(gè)哈希表,所以在漸進(jìn)式 rehash 進(jìn)行期間,哈希表元素的刪除、查找、更新等操作都會(huì)在這兩個(gè)哈希表進(jìn)行。

哈希表擴(kuò)容的時(shí)候,有讀請(qǐng)求怎么查?

查找一個(gè) key 的值的話,先會(huì)在「哈希表 1」 里面進(jìn)行查找,如果沒找到,就會(huì)繼續(xù)到哈希表 2 里面進(jìn)行找到。

Redis大key如何解決?

對(duì)大Key進(jìn)行拆分。例如將含有數(shù)萬成員的一個(gè)HASH Key拆分為多個(gè)HASH Key,并確保每個(gè)Key的成員數(shù)量在合理范圍。在Redis集群架構(gòu)中,拆分大Key能對(duì)數(shù)據(jù)分片間的內(nèi)存平衡起到顯著作用。

對(duì)大Key進(jìn)行清理。將不適用Redis能力的數(shù)據(jù)存至其它存儲(chǔ),并在Redis中刪除此類數(shù)據(jù)。注意,要使用異步刪除。

監(jiān)控Redis的內(nèi)存水位??梢酝ㄟ^監(jiān)控系統(tǒng)設(shè)置合理的Redis內(nèi)存報(bào)警閾值進(jìn)行提醒,例如Redis內(nèi)存使用率超過70%、Redis的內(nèi)存在1小時(shí)內(nèi)增長率超過20%等。

對(duì)過期數(shù)據(jù)進(jìn)行定期清。堆積大量過期數(shù)據(jù)會(huì)造成大Key的產(chǎn)生,例如在HASH數(shù)據(jù)類型中以增量的形式不斷寫入大量數(shù)據(jù)而忽略了數(shù)據(jù)的時(shí)效性??梢酝ㄟ^定時(shí)任務(wù)的方式對(duì)失效數(shù)據(jù)進(jìn)行清理。

什么是熱key?

通常以其接收到的Key被請(qǐng)求頻率來判定,例如:

QPS集中在特定的Key:Redis實(shí)例的總QPS(每秒查詢率)為10,000,而其中一個(gè)Key的每秒訪問量達(dá)到了7,000。

帶寬使用率集中在特定的Key:對(duì)一個(gè)擁有上千個(gè)成員且總大小為1 MB的HASH Key每秒發(fā)送大量的HGETALL操作請(qǐng)求。

CPU使用時(shí)間占比集中在特定的Key:對(duì)一個(gè)擁有數(shù)萬個(gè)成員的Key(ZSET類型)每秒發(fā)送大量的ZRANGE操作請(qǐng)求。

如何解決熱key問題?

在Redis集群架構(gòu)中對(duì)熱Key進(jìn)行復(fù)制。在Redis集群架構(gòu)中,由于熱Key的遷移粒度問題,無法將請(qǐng)求分散至其他數(shù)據(jù)分片,導(dǎo)致單個(gè)數(shù)據(jù)分片的壓力無法下降。此時(shí),可以將對(duì)應(yīng)熱Key進(jìn)行復(fù)制并遷移至其他數(shù)據(jù)分片,例如將熱Key foo復(fù)制出3個(gè)內(nèi)容完全一樣的Key并名為foo2、foo3、foo4,將這三個(gè)Key遷移到其他數(shù)據(jù)分片來解決單個(gè)數(shù)據(jù)分片的熱Key壓力。

使用讀寫分離架構(gòu)。如果熱Key的產(chǎn)生來自于讀請(qǐng)求,您可以將實(shí)例改造成讀寫分離架構(gòu)來降低每個(gè)數(shù)據(jù)分片的讀請(qǐng)求壓力,甚至可以不斷地增加從節(jié)點(diǎn)。但是讀寫分離架構(gòu)在增加業(yè)務(wù)代碼復(fù)雜度的同時(shí),也會(huì)增加Redis集群架構(gòu)復(fù)雜度。不僅要為多個(gè)從節(jié)點(diǎn)提供轉(zhuǎn)發(fā)層(如Proxy,LVS等)來實(shí)現(xiàn)負(fù)載均衡,還要考慮從節(jié)點(diǎn)數(shù)量顯著增加后帶來故障率增加的問題。Redis集群架構(gòu)變更會(huì)為監(jiān)控、運(yùn)維、故障處理帶來了更大的挑戰(zhàn)。

mysql

索引優(yōu)化詳細(xì)講講

常見優(yōu)化索引的方法:

前綴索引優(yōu)化:使用前綴索引是為了減小索引字段大小,可以增加一個(gè)索引頁中存儲(chǔ)的索引值,有效提高索引的查詢速度。在一些大字符串的字段作為索引時(shí),使用前綴索引可以幫助我們減小索引項(xiàng)的大小。

覆蓋索引優(yōu)化:覆蓋索引是指 SQL 中 query 的所有字段,在索引 B+Tree 的葉子節(jié)點(diǎn)上都能找得到的那些索引,從二級(jí)索引中查詢得到記錄,而不需要通過聚簇索引查詢獲得,可以避免回表的操作。

主鍵索引最好是自增的:

如果我們使用自增主鍵,那么每次插入的新數(shù)據(jù)就會(huì)按順序添加到當(dāng)前索引節(jié)點(diǎn)的位置,不需要移動(dòng)已有的數(shù)據(jù),當(dāng)頁面寫滿,就會(huì)自動(dòng)開辟一個(gè)新頁面。因?yàn)槊看尾迦胍粭l新記錄,都是追加操作,不需要重新移動(dòng)數(shù)據(jù),因此這種插入數(shù)據(jù)的方法效率非常高。

如果我們使用非自增主鍵,由于每次插入主鍵的索引值都是隨機(jī)的,因此每次插入新的數(shù)據(jù)時(shí),就可能會(huì)插入到現(xiàn)有數(shù)據(jù)頁中間的某個(gè)位置,這將不得不移動(dòng)其它數(shù)據(jù)來滿足新數(shù)據(jù)的插入,甚至需要從一個(gè)頁面復(fù)制數(shù)據(jù)到另外一個(gè)頁面,我們通常將這種情況稱為頁分裂。頁分裂還有可能會(huì)造成大量的內(nèi)存碎片,導(dǎo)致索引結(jié)構(gòu)不緊湊,從而影響查詢效率。

防止索引失效:

當(dāng)我們使用左或者左右模糊匹配的時(shí)候,也就是 like %xx 或者 like %xx%這兩種方式都會(huì)造成索引失效;

當(dāng)我們?cè)诓樵儣l件中對(duì)索引列做了計(jì)算、函數(shù)、類型轉(zhuǎn)換操作,這些情況下都會(huì)造成索引失效;

聯(lián)合索引要能正確使用需要遵循最左匹配原則,也就是按照最左優(yōu)先的方式進(jìn)行索引的匹配,否則就會(huì)導(dǎo)致索引失效。

在 WHERE 子句中,如果在 OR 前的條件列是索引列,而在 OR 后的條件列不是索引列,那么索引會(huì)失效。

主鍵索引和非主鍵索引有什么區(qū)別?

主鍵索引和非主鍵索引的主要區(qū)別在于:

主鍵索引:主鍵是一種特殊的唯一索引,不允許有空值。每個(gè)表只能有一個(gè)主鍵。主鍵的主要作用是提供一種快速訪問表中特定信息的方式。

非主鍵索引:非主鍵索引,也稱為二級(jí)索引或輔助索引,可以有多個(gè)。非主鍵索引允許有空值,也允許有重復(fù)的值。

當(dāng)我們進(jìn)行索引覆蓋查詢的時(shí)候,在二級(jí)索引上查詢就可以了,就可以不需要回表,

MySQL的事務(wù)的幾個(gè)特性你知道嗎?

要遵守 4 個(gè)特性,分別如下:

原子性(Atomicity):一個(gè)事務(wù)中的所有操作,要么全部完成,要么全部不完成,不會(huì)結(jié)束在中間某個(gè)環(huán)節(jié),而且事務(wù)在執(zhí)行過程中發(fā)生錯(cuò)誤,會(huì)被回滾到事務(wù)開始前的狀態(tài),就像這個(gè)事務(wù)從來沒有執(zhí)行過一樣,就好比買一件商品,購買成功時(shí),則給商家付了錢,商品到手;購買失敗時(shí),則商品在商家手中,消費(fèi)者的錢也沒花出去。

一致性(Consistency):是指事務(wù)操作前和操作后,數(shù)據(jù)滿足完整性約束,數(shù)據(jù)庫保持一致性狀態(tài)。比如,用戶 A 和用戶 B 在銀行分別有 800 元和 600 元,總共 1400 元,用戶 A 給用戶 B 轉(zhuǎn)賬 200 元,分為兩個(gè)步驟,從 A 的賬戶扣除 200 元和對(duì) B 的賬戶增加 200 元。一致性就是要求上述步驟操作后,最后的結(jié)果是用戶 A 還有 600 元,用戶 B 有 800 元,總共 1400 元,而不會(huì)出現(xiàn)用戶 A 扣除了 200 元,但用戶 B 未增加的情況(該情況,用戶 A 和 B 均為 600 元,總共 1200 元)。

隔離性(Isolation):數(shù)據(jù)庫允許多個(gè)并發(fā)事務(wù)同時(shí)對(duì)其數(shù)據(jù)進(jìn)行讀寫和修改的能力,隔離性可以防止多個(gè)事務(wù)并發(fā)執(zhí)行時(shí)由于交叉執(zhí)行而導(dǎo)致數(shù)據(jù)的不一致,因?yàn)槎鄠€(gè)事務(wù)同時(shí)使用相同的數(shù)據(jù)時(shí),不會(huì)相互干擾,每個(gè)事務(wù)都有一個(gè)完整的數(shù)據(jù)空間,對(duì)其他并發(fā)事務(wù)是隔離的。也就是說,消費(fèi)者購買商品這個(gè)事務(wù),是不影響其他消費(fèi)者購買的。

持久性(Durability):事務(wù)處理結(jié)束后,對(duì)數(shù)據(jù)的修改就是永久的,即便系統(tǒng)故障也不會(huì)丟失。

操作系統(tǒng)

進(jìn)程和線程的區(qū)別

獨(dú)立性:進(jìn)程是系統(tǒng)資源分配的最小單位,線程是處理器調(diào)度的最小單位。每個(gè)進(jìn)程有自己獨(dú)立的地址空間和系統(tǒng)資源,而線程則共享所屬進(jìn)程的資源。

開銷:由于進(jìn)程有自己獨(dú)立的地址空間,所以進(jìn)程間的切換需要更大的開銷。線程間切換只需要保存和設(shè)置少量寄存器內(nèi)容,開銷小。

數(shù)據(jù)共享:同一進(jìn)程內(nèi)的線程共享進(jìn)程的資源,如內(nèi)存、文件描述符等,所以線程間的數(shù)據(jù)共享和通信更容易。進(jìn)程間需要通過進(jìn)程間通信機(jī)制來實(shí)現(xiàn)數(shù)據(jù)共享或通信。

分配給進(jìn)程的資源有哪些?

虛擬內(nèi)存、文件描述符、信號(hào)等等

進(jìn)程切換和線程切換的區(qū)別?

進(jìn)程切換:進(jìn)程切換涉及到更多的內(nèi)容,包括整個(gè)進(jìn)程的地址空間、全局變量、文件描述符等。因此,進(jìn)程切換的開銷通常比線程切換大。

線程切換:線程切換只涉及到線程的堆棧、寄存器和程序計(jì)數(shù)器等,不涉及進(jìn)程級(jí)別的資源,因此線程切換的開銷較小。

為什么并發(fā)執(zhí)行線程要加鎖?

并發(fā)執(zhí)行線程需要加鎖主要是為了保護(hù)共享數(shù)據(jù),防止出現(xiàn)"競(jìng)態(tài)條件"。

"競(jìng)態(tài)條件"是指當(dāng)多個(gè)線程同時(shí)訪問和操作同一塊數(shù)據(jù)時(shí),最終結(jié)果依賴于線程的執(zhí)行順序,這可能導(dǎo)致數(shù)據(jù)的不一致性。

通過加鎖,我們可以確保在任何時(shí)刻只有一個(gè)線程能夠訪問共享數(shù)據(jù),從而避免"競(jìng)態(tài)條件",確保數(shù)據(jù)的一致性和完整性。

線程死鎖的條件?

死鎖問題的產(chǎn)生是由兩個(gè)或者以上線程并行執(zhí)行的時(shí)候,爭(zhēng)奪資源而互相等待造成的。

死鎖只有同時(shí)滿足互斥、持有并等待、不可剝奪、環(huán)路等待這四個(gè)條件的時(shí)候才會(huì)發(fā)生。

所以要避免死鎖問題,就是要破壞其中一個(gè)條件即可,最常用的方法就是使用資源有序分配法來破壞環(huán)路等待條件。

網(wǎng)絡(luò)

TCP和UDP的區(qū)別

連接:TCP 是面向連接的傳輸層協(xié)議,傳輸數(shù)據(jù)前先要建立連接。UDP 是不需要連接,即刻傳輸數(shù)據(jù)。

服務(wù)對(duì)象:TCP 是一對(duì)一的兩點(diǎn)服務(wù),即一條連接只有兩個(gè)端點(diǎn)。UDP 支持一對(duì)一、一對(duì)多、多對(duì)多的交互通信

可靠性:TCP 是可靠交付數(shù)據(jù)的,數(shù)據(jù)可以無差錯(cuò)、不丟失、不重復(fù)、按序到達(dá)。UDP 是盡最大努力交付,不保證可靠交付數(shù)據(jù)。

擁塞控制、流量控制:TCP 有擁塞控制和流量控制機(jī)制,保證數(shù)據(jù)傳輸?shù)陌踩浴DP 則沒有,即使網(wǎng)絡(luò)非常擁堵了,也不會(huì)影響 UDP 的發(fā)送速率。

傳輸方式:TCP 是流式傳輸,沒有邊界,但保證順序和可靠。UDP 是一個(gè)包一個(gè)包的發(fā)送,是有邊界的,但可能會(huì)丟包和亂序。

TCP的連接指的是什么東西

用于保證可靠性和流量控制維護(hù)的某些狀態(tài)信息,這些信息的組合,包括 Socket、序列號(hào)和窗口大小稱為連接。

436c2eca-3299-11ee-9e74-dac502259ad0.png

img

TCP三次握手過程描述一下?

建立連接是通過三次握手來進(jìn)行的。三次握手的過程如下圖:

437fe140-3299-11ee-9e74-dac502259ad0.png

TCP 三次握手

一開始,客戶端和服務(wù)端都處于 CLOSE 狀態(tài)。先是服務(wù)端主動(dòng)監(jiān)聽某個(gè)端口,處于 LISTEN 狀態(tài)。

客戶端會(huì)隨機(jī)初始化序號(hào)(client_isn),將此序號(hào)置于 TCP 首部的「序號(hào)」字段中,同時(shí)把 SYN 標(biāo)志位置為 1,表示 SYN 報(bào)文。接著把第一個(gè) SYN 報(bào)文發(fā)送給服務(wù)端,表示向服務(wù)端發(fā)起連接,該報(bào)文不包含應(yīng)用層數(shù)據(jù),之后客戶端處于 SYN-SENT 狀態(tài)。

服務(wù)端收到客戶端的 SYN 報(bào)文后,首先服務(wù)端也隨機(jī)初始化自己的序號(hào)(server_isn),將此序號(hào)填入 TCP 首部的「序號(hào)」字段中,其次把 TCP 首部的「確認(rèn)應(yīng)答號(hào)」字段填入 client_isn + 1, 接著把 SYN 和 ACK 標(biāo)志位置為 1。最后把該報(bào)文發(fā)給客戶端,該報(bào)文也不包含應(yīng)用層數(shù)據(jù),之后服務(wù)端處于 SYN-RCVD 狀態(tài)。

客戶端收到服務(wù)端報(bào)文后,還要向服務(wù)端回應(yīng)最后一個(gè)應(yīng)答報(bào)文,首先該應(yīng)答報(bào)文 TCP 首部 ACK 標(biāo)志位置為 1 ,其次「確認(rèn)應(yīng)答號(hào)」字段填入 server_isn + 1 ,最后把報(bào)文發(fā)送給服務(wù)端,這次報(bào)文可以攜帶客戶到服務(wù)端的數(shù)據(jù),之后客戶端處于 ESTABLISHED 狀態(tài)。

服務(wù)端收到客戶端的應(yīng)答報(bào)文后,也進(jìn)入 ESTABLISHED 狀態(tài)。

為什么要三次?

三個(gè)方面分析三次握手的原因:

三次握手才可以阻止重復(fù)歷史連接的初始化(主要原因)

三次握手才可以同步雙方的初始序列號(hào)

三次握手才可以避免資源浪費(fèi)

我們考慮一個(gè)場(chǎng)景,客戶端先發(fā)送了 SYN(seq = 90)報(bào)文,然后客戶端宕機(jī)了,而且這個(gè) SYN 報(bào)文還被網(wǎng)絡(luò)阻塞了,服務(wù)端并沒有收到,接著客戶端重啟后,又重新向服務(wù)端建立連接,發(fā)送了 SYN(seq = 100)報(bào)文(注意!不是重傳 SYN,重傳的 SYN 的序列號(hào)是一樣的)。

看看三次握手是如何阻止歷史連接的:

43bc33c0-3299-11ee-9e74-dac502259ad0.png

三次握手避免歷史連接

客戶端連續(xù)發(fā)送多次 SYN(都是同一個(gè)四元組)建立連接的報(bào)文,在網(wǎng)絡(luò)擁堵情況下:

一個(gè)「舊 SYN 報(bào)文」比「最新的 SYN」 報(bào)文早到達(dá)了服務(wù)端,那么此時(shí)服務(wù)端就會(huì)回一個(gè) SYN + ACK 報(bào)文給客戶端,此報(bào)文中的確認(rèn)號(hào)是 91(90+1)。

客戶端收到后,發(fā)現(xiàn)自己期望收到的確認(rèn)號(hào)應(yīng)該是 100 + 1,而不是 90 + 1,于是就會(huì)回 RST 報(bào)文。

服務(wù)端收到 RST 報(bào)文后,就會(huì)釋放連接。

后續(xù)最新的 SYN 抵達(dá)了服務(wù)端后,客戶端與服務(wù)端就可以正常的完成三次握手了。

上述中的「舊 SYN 報(bào)文」稱為歷史連接,TCP 使用三次握手建立連接的最主要原因就是防止「歷史連接」初始化了連接。

如果是兩次握手連接,就無法阻止歷史連接,那為什么 TCP 兩次握手為什么無法阻止歷史連接呢?

我先直接說結(jié)論,主要是因?yàn)樵趦纱挝帐值那闆r下,服務(wù)端沒有中間狀態(tài)給客戶端來阻止歷史連接,導(dǎo)致服務(wù)端可能建立一個(gè)歷史連接,造成資源浪費(fèi)。

你想想,在兩次握手的情況下,服務(wù)端在收到 SYN 報(bào)文后,就進(jìn)入 ESTABLISHED 狀態(tài),意味著這時(shí)可以給對(duì)方發(fā)送數(shù)據(jù),但是客戶端此時(shí)還沒有進(jìn)入 ESTABLISHED 狀態(tài),假設(shè)這次是歷史連接,客戶端判斷到此次連接為歷史連接,那么就會(huì)回 RST 報(bào)文來斷開連接,而服務(wù)端在第一次握手的時(shí)候就進(jìn)入 ESTABLISHED 狀態(tài),所以它可以發(fā)送數(shù)據(jù)的,但是它并不知道這個(gè)是歷史連接,它只有在收到 RST 報(bào)文后,才會(huì)斷開連接。

44019e4c-3299-11ee-9e74-dac502259ad0.png

兩次握手無法阻止歷史連接

可以看到,如果采用兩次握手建立 TCP 連接的場(chǎng)景下,服務(wù)端在向客戶端發(fā)送數(shù)據(jù)前,并沒有阻止掉歷史連接,導(dǎo)致服務(wù)端建立了一個(gè)歷史連接,又白白發(fā)送了數(shù)據(jù),妥妥地浪費(fèi)了服務(wù)端的資源。

因此,要解決這種現(xiàn)象,最好就是在服務(wù)端發(fā)送數(shù)據(jù)前,也就是建立連接之前,要阻止掉歷史連接,這樣就不會(huì)造成資源浪費(fèi),而要實(shí)現(xiàn)這個(gè)功能,就需要三次握手。

所以,TCP 使用三次握手建立連接的最主要原因是防止「歷史連接」初始化了連接

Java

GC算法有哪幾種?

垃圾收集(GC)算法主要有以下幾種:

標(biāo)記-清除(Mark-Sweep)算法:首先標(biāo)記出所有需要回收的對(duì)象,在標(biāo)記完成后統(tǒng)一回收所有被標(biāo)記的對(duì)象。

復(fù)制(Copying)算法:將內(nèi)存分為兩塊,每次只使用其中一塊,當(dāng)這塊內(nèi)存用完時(shí),就將還在使用的對(duì)象復(fù)制到另外一塊上面,然后再把已使用過的內(nèi)存空間一次清理掉。

標(biāo)記-整理(Mark-Compact)算法:標(biāo)記過程與"標(biāo)記-清除"算法一樣,但后續(xù)步驟不是直接對(duì)可回收對(duì)象進(jìn)行清理,而是讓所有存活的對(duì)象都向一端移動(dòng),然后直接清理掉端邊界以外的內(nèi)存。

分代收集(Generational Collection)算法:根據(jù)對(duì)象存活周期的不同將內(nèi)存劃分為幾塊。一般是把Java堆分為新生代和老年代,這樣我們就可以根據(jù)各個(gè)年代的特點(diǎn)采用最適當(dāng)?shù)氖占惴ā?/p>

增量(Incremental)算法:是一種漸進(jìn)式的垃圾收集算法,它將垃圾收集的工作分為多個(gè)小部分分別執(zhí)行,不需要一次性完成所有的垃圾收集工作,從而減少了垃圾收集時(shí)程序的暫停時(shí)間。

項(xiàng)目

介紹項(xiàng)目

項(xiàng)目架構(gòu)是怎么樣的?

項(xiàng)目里為什么要用消息隊(duì)列?

請(qǐng)求很多,消息堆積處理不過來了如何應(yīng)對(duì)?

項(xiàng)目都有哪些表?

算法

力扣:乘積最大子數(shù)組

歷史好文:我們又出成績了?。?拿了 7 個(gè)大廠 offer,我有話說! 被滴滴細(xì)節(jié)拷打,快頂不住了.... 拿下鵝廠一面! 被字節(jié)拷打了!基礎(chǔ)還是太重要了...

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 數(shù)據(jù)庫
    +關(guān)注

    關(guān)注

    7

    文章

    3842

    瀏覽量

    64549
  • 數(shù)據(jù)類型
    +關(guān)注

    關(guān)注

    0

    文章

    236

    瀏覽量

    13639
  • Redis
    +關(guān)注

    關(guān)注

    0

    文章

    376

    瀏覽量

    10899

原文標(biāo)題:字節(jié)很會(huì)面試,追著項(xiàng)目技術(shù)拷打

文章出處:【微信號(hào):小林coding,微信公眾號(hào):小林coding】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    【C語言進(jìn)階】面試題:請(qǐng)使用宏定義實(shí)現(xiàn)字節(jié)對(duì)齊

    【C語言進(jìn)階】面試題:請(qǐng)使用宏定義實(shí)現(xiàn)字節(jié)對(duì)齊
    的頭像 發(fā)表于 07-11 09:21 ?2842次閱讀
    【C語言進(jìn)階】<b class='flag-5'>面試</b>題:請(qǐng)使用宏定義實(shí)現(xiàn)<b class='flag-5'>字節(jié)</b>對(duì)齊

    面試

    介紹(最好包括做過的項(xiàng)目);面試官會(huì)用英文2分鐘左右聊一些關(guān)于工作執(zhí)掌這些;3分鐘左右交流項(xiàng)目用到的技術(shù)的細(xì)節(jié);Q&A-你可以問一些問題本人對(duì)項(xiàng)目
    發(fā)表于 11-25 20:49

    【CANNON試用體驗(yàn)】面試

    今天不說技術(shù),說面試。上一周一直在深圳面試,沒有弄小鋼炮。那么就說點(diǎn)面試心得吧。給大家一點(diǎn)點(diǎn)參考意見。這幾天,深有體會(huì)。[fly]面而不死者,似為神也!你想檢驗(yàn)?zāi)愕?/div>
    發(fā)表于 03-09 14:31

    面試必看:java面試考點(diǎn)精講視頻教程

    面試必看:java面試考點(diǎn)精講視頻教程 Java作為目前比較火的計(jì)算機(jī)語言之一,連續(xù)幾年蟬聯(lián)最受程序員歡迎的計(jì)算機(jī)語言榜首,因此每年新入職Java程序員也數(shù)不勝數(shù)。很多java程序員在學(xué)成之后,會(huì)面
    發(fā)表于 07-06 12:46

    技術(shù)雜談】備戰(zhàn)秋招:國內(nèi)大廠技術(shù)面試指南,GitHub六千星

    最近,GitHub 上有一個(gè)項(xiàng)目很火,這個(gè)項(xiàng)目主要介紹了阿里、騰訊、百度、美團(tuán)、今日頭條等國內(nèi)互聯(lián)網(wǎng)大廠的面試題,還配備有答案和出題人分析等信息。這個(gè)項(xiàng)目或許對(duì)大家找工作
    發(fā)表于 07-23 09:52

    AI面試帶來的便利

    ?既然提出這個(gè)疑問,那么下面不妨就來解析一下,用機(jī)器人當(dāng)面試官的原因有哪些:1、為什么要用機(jī)器人招聘?對(duì)于企業(yè)的面試官來說,每一個(gè)崗位的招聘都會(huì)面試大量的人,幾乎是每天都會(huì)有各種崗位的人來面試
    發(fā)表于 07-30 14:42

    CVTE嵌入式面試相關(guān)資料分享

    遠(yuǎn)程面試過程:先是電話突襲面試,相當(dāng)于筆試,問進(jìn)程線程,TCP,UDP協(xié)議;再是??途W(wǎng),在線視頻代碼編寫, 詢問算法,比較基礎(chǔ)?,F(xiàn)場(chǎng)面試過程:一面主要問基礎(chǔ),***技術(shù)面。二面主要手寫
    發(fā)表于 10-27 06:14

    嵌入式技術(shù)面試的問題匯總

    嵌入式技術(shù)面試1 C/C++1.1 結(jié)構(gòu)體struct與union區(qū)別?struct與class區(qū)別?1.2 結(jié)構(gòu)體使用需要注意什么?字節(jié)對(duì)齊?1.3 帶參數(shù)宏與一個(gè)函數(shù)差別?1.4 有一個(gè)函數(shù)
    發(fā)表于 11-09 08:02

    神奇Arduino:被一個(gè)冰箱追著跑是怎樣的體驗(yàn)

    神奇Arduino:被一個(gè)冰箱追著跑是種怎樣的體驗(yàn)?
    的頭像 發(fā)表于 05-30 09:24 ?1394次閱讀
    神奇Arduino:被一個(gè)冰箱<b class='flag-5'>追著</b>跑是怎樣的體驗(yàn)

    工程師技術(shù)面試應(yīng)該準(zhǔn)備什么

    亞馬遜這樣的公司有 14 項(xiàng)領(lǐng)導(dǎo)原則 。他們不想僅僅雇傭一個(gè)數(shù)據(jù)科學(xué)家或軟件工程師。對(duì)于許多只進(jìn)行一次或兩次面試面試者來說,這可能沒有那么明顯,因?yàn)槟闾珜W⒂诨卮?b class='flag-5'>面試技術(shù)部分。但是
    的頭像 發(fā)表于 09-23 16:41 ?4083次閱讀

    嵌入式技術(shù)面試

    嵌入式技術(shù)面試1 C/C++1.1 結(jié)構(gòu)體struct與union區(qū)別?struct與class區(qū)別?1.2 結(jié)構(gòu)體使用需要注意什么?字節(jié)對(duì)齊?1.3 帶參數(shù)宏與一個(gè)函數(shù)差別?1.4 有一個(gè)函數(shù)
    發(fā)表于 11-04 09:21 ?16次下載
    嵌入式<b class='flag-5'>技術(shù)</b><b class='flag-5'>面試</b>

    華為射頻工程師面試經(jīng)驗(yàn)分享

    技術(shù)問題,接著開始聊項(xiàng)目,一面問的可能比較深些,結(jié)束以后面試官會(huì)對(duì)你做一個(gè)評(píng)價(jià),然后會(huì)告訴你通沒通過,如果通過了會(huì)去外面等下一輪面試,二面面試
    的頭像 發(fā)表于 04-14 16:42 ?2536次閱讀

    技術(shù)大牛分享快手面試面經(jīng)

    這段時(shí)間分享了很多校招的面經(jīng),有很多讀者說想看社招的,其實(shí)社招面試是基于你的工作項(xiàng)目來展開問的,比如你項(xiàng)目用了 xxx 技術(shù),那么面試就會(huì)追
    的頭像 發(fā)表于 04-15 15:39 ?1015次閱讀

    項(xiàng)目常見的線程池有哪些

    大家好,我是小林。 今天分享一篇一位同學(xué)暑期實(shí)習(xí)面試阿里Java后端崗位的一面的面經(jīng)。 主要拷打項(xiàng)目+Java 集合+Java并發(fā)+網(wǎng)絡(luò)+mysql,一場(chǎng)面試大概問了 20 個(gè)題目,
    的頭像 發(fā)表于 06-17 14:30 ?807次閱讀
    <b class='flag-5'>項(xiàng)目</b>常見的線程池有哪些

    字節(jié)跳動(dòng)否認(rèn)AI手機(jī)研發(fā)項(xiàng)目

    近日,有市場(chǎng)傳聞稱字節(jié)跳動(dòng)已在兩個(gè)月前秘密啟動(dòng)了AI手機(jī)研發(fā)項(xiàng)目,引發(fā)業(yè)界廣泛關(guān)注。然而,字節(jié)跳動(dòng)相關(guān)人士迅速對(duì)此作出回應(yīng),表示這些消息并不屬實(shí)。
    的頭像 發(fā)表于 06-12 15:54 ?630次閱讀