日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當(dāng)前位置:首頁(yè) > 科技  > 軟件

還得是騰訊,撈了我一把!

來(lái)源: 責(zé)編: 時(shí)間:2024-01-08 09:18:12 235觀(guān)看
導(dǎo)讀大家好,我是小林。原來(lái)薪資開(kāi)太高,也會(huì)讓人猶豫。最近知道國(guó)內(nèi)某新能源公司和跨境電商的公司校招月薪很多都開(kāi) 30-35K,超過(guò)了一線(xiàn)BAT ,很多同學(xué)都覺(jué)得太高了,都不太敢接。給低了也不想接,給太高也不敢接,真有趣。說(shuō)到校招,很

大家好,我是小林。mwo28資訊網(wǎng)——每日最新資訊28at.com

原來(lái)薪資開(kāi)太高,也會(huì)讓人猶豫。最近知道國(guó)內(nèi)某新能源公司和跨境電商的公司校招月薪很多都開(kāi) 30-35K,超過(guò)了一線(xiàn)BAT ,很多同學(xué)都覺(jué)得太高了,都不太敢接。給低了也不想接,給太高也不敢接,真有趣。mwo28資訊網(wǎng)——每日最新資訊28at.com

說(shuō)到校招,很多公司秋招階段沒(méi)有招滿(mǎn)人,就會(huì)繼續(xù)進(jìn)行補(bǔ)錄,面試官大部分都是從簡(jiǎn)歷池?fù)迫似饋?lái)面試,補(bǔ)錄的時(shí)候被撈起來(lái)面試,很大概率是能撿漏 offer 的,我接觸到很多同學(xué)其實(shí)都是在 12 月份補(bǔ)錄的環(huán)節(jié)中,突然就上岸大廠(chǎng)了。mwo28資訊網(wǎng)——每日最新資訊28at.com

這次分享一位 12 月末被騰訊撈起來(lái)面試的 Java 后端同學(xué),同學(xué)穩(wěn)打穩(wěn)扎經(jīng)歷了一二面,坐等三面,我把一二面比較通用問(wèn)題做了下分類(lèi)和解答。mwo28資訊網(wǎng)——每日最新資訊28at.com

除開(kāi)實(shí)習(xí)和項(xiàng)目問(wèn)題,考察的知識(shí)內(nèi)容主要是Java 集合+Java并發(fā)+JVM+MySQL+Redis+網(wǎng)絡(luò)+操作系統(tǒng)+數(shù)據(jù)結(jié)構(gòu)與算法這幾大塊,整體上就是后端開(kāi)發(fā)+計(jì)算機(jī)基礎(chǔ)。mwo28資訊網(wǎng)——每日最新資訊28at.com

這幾大塊是后端開(kāi)發(fā)面試中比較常見(jiàn)的類(lèi)型的,所以同學(xué)們?cè)跍?zhǔn)備面試或者學(xué)習(xí)的時(shí)候,需要重點(diǎn)學(xué)習(xí)這幾大塊的原理知識(shí),以面試問(wèn)題反推復(fù)習(xí)的方向,是最高效和快速的方式。mwo28資訊網(wǎng)——每日最新資訊28at.com

MySQL

MySQL索引原理介紹一下

索引的作用是為了加快查詢(xún)效率,MySQL 默認(rèn)存儲(chǔ)引擎 Innodb 的索引結(jié)構(gòu)是用了 B+樹(shù),B+樹(shù)索引按照索引列的值進(jìn)行排序,并將數(shù)據(jù)分層存儲(chǔ)在索引樹(shù)的節(jié)點(diǎn)中,這樣可以通過(guò)比較索引值,快速定位到符合條件的數(shù)據(jù)行。mwo28資訊網(wǎng)——每日最新資訊28at.com

B+樹(shù)B+樹(shù)mwo28資訊網(wǎng)——每日最新資訊28at.com

B+和B樹(shù)平衡二叉樹(shù)區(qū)別是什么?

數(shù)據(jù)庫(kù)的索引和數(shù)據(jù)都是存儲(chǔ)在硬盤(pán)的,我們可以把讀取一個(gè)節(jié)點(diǎn)當(dāng)作一次磁盤(pán) I/O 操作。mwo28資訊網(wǎng)——每日最新資訊28at.com

B+Tree 存儲(chǔ)千萬(wàn)級(jí)的數(shù)據(jù)只需要 3-4 層高度就可以滿(mǎn)足,這意味著從千萬(wàn)級(jí)的表查詢(xún)目標(biāo)數(shù)據(jù)最多需要 3-4 次磁盤(pán) I/O,所以B+Tree 相比于 B 樹(shù)和二叉樹(shù)來(lái)說(shuō),最大的優(yōu)勢(shì)在于查詢(xún)效率很高,因?yàn)榧词乖跀?shù)據(jù)量很大的情況,查詢(xún)一個(gè)數(shù)據(jù)的磁盤(pán) I/O 依然維持在 3-4次。mwo28資訊網(wǎng)——每日最新資訊28at.com

1、B+Tree vs B Treemwo28資訊網(wǎng)——每日最新資訊28at.com

B+Tree 只在葉子節(jié)點(diǎn)存儲(chǔ)數(shù)據(jù),而 B 樹(shù) 的非葉子節(jié)點(diǎn)也要存儲(chǔ)數(shù)據(jù),所以 B+Tree 的單個(gè)節(jié)點(diǎn)的數(shù)據(jù)量更小,在相同的磁盤(pán) I/O 次數(shù)下,就能查詢(xún)更多的節(jié)點(diǎn)。mwo28資訊網(wǎng)——每日最新資訊28at.com

另外,B+Tree 葉子節(jié)點(diǎn)采用的是雙鏈表連接,適合 MySQL 中常見(jiàn)的基于范圍的順序查找,而 B 樹(shù)無(wú)法做到這一點(diǎn)。mwo28資訊網(wǎng)——每日最新資訊28at.com

2、B+Tree vs 二叉樹(shù)mwo28資訊網(wǎng)——每日最新資訊28at.com

對(duì)于有 N 個(gè)葉子節(jié)點(diǎn)的 B+Tree,其搜索復(fù)雜度為O(logdN),其中 d 表示節(jié)點(diǎn)允許的最大子節(jié)點(diǎn)個(gè)數(shù)為 d 個(gè)。mwo28資訊網(wǎng)——每日最新資訊28at.com

在實(shí)際的應(yīng)用當(dāng)中, d 值是大于100的,這樣就保證了,即使數(shù)據(jù)達(dá)到千萬(wàn)級(jí)別時(shí),B+Tree 的高度依然維持在 3~4 層左右,也就是說(shuō)一次數(shù)據(jù)查詢(xún)操作只需要做 3~4 次的磁盤(pán) I/O 操作就能查詢(xún)到目標(biāo)數(shù)據(jù)。mwo28資訊網(wǎng)——每日最新資訊28at.com

而二叉樹(shù)的每個(gè)父節(jié)點(diǎn)的兒子節(jié)點(diǎn)個(gè)數(shù)只能是 2 個(gè),意味著其搜索復(fù)雜度為 O(logN),這已經(jīng)比 B+Tree 高出不少,因此二叉樹(shù)檢索到目標(biāo)數(shù)據(jù)所經(jīng)歷的磁盤(pán) I/O 次數(shù)要更多。mwo28資訊網(wǎng)——每日最新資訊28at.com

3、B+Tree vs Hashmwo28資訊網(wǎng)——每日最新資訊28at.com

Hash 在做等值查詢(xún)的時(shí)候效率賊快,搜索復(fù)雜度為 O(1)。mwo28資訊網(wǎng)——每日最新資訊28at.com

但是 Hash 表不適合做范圍查詢(xún),它更適合做等值的查詢(xún),這也是 B+Tree 索引要比 Hash 表索引有著更廣泛的適用場(chǎng)景的原因。mwo28資訊網(wǎng)——每日最新資訊28at.com

MySQL引擎有哪些,特點(diǎn)有哪些 ?

  • InnoDB:InnoDB是MySQL的默認(rèn)存儲(chǔ)引擎,具有ACID事務(wù)支持、行級(jí)鎖、外鍵約束等特性。它適用于高并發(fā)的讀寫(xiě)操作,支持較好的數(shù)據(jù)完整性和并發(fā)控制。
  • MyISAM:MyISAM是MySQL的另一種常見(jiàn)的存儲(chǔ)引擎,具有較低的存儲(chǔ)空間和內(nèi)存消耗,適用于大量讀操作的場(chǎng)景。然而,MyISAM不支持事務(wù)、行級(jí)鎖和外鍵約束,因此在并發(fā)寫(xiě)入和數(shù)據(jù)完整性方面有一定的限制。
  • Memory:Memory引擎將數(shù)據(jù)存儲(chǔ)在內(nèi)存中,適用于對(duì)性能要求較高的讀操作,但是在服務(wù)器重啟或崩潰時(shí)數(shù)據(jù)會(huì)丟失。它不支持事務(wù)、行級(jí)鎖和外鍵約束。

Redis

Redis可以用來(lái)做什么?

Redis 是一種基于內(nèi)存的數(shù)據(jù)庫(kù),對(duì)數(shù)據(jù)的讀寫(xiě)操作都是在內(nèi)存中完成,因此讀寫(xiě)速度非常快,常用于緩存,消息隊(duì)列、分布式鎖等場(chǎng)景。mwo28資訊網(wǎng)——每日最新資訊28at.com

Redis用途Redis用途mwo28資訊網(wǎng)——每日最新資訊28at.com

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

除此之外,Redis 還支持事務(wù) 、持久化、Lua 腳本、多種集群方案(主從復(fù)制模式、哨兵模式、切片機(jī)群模式)、發(fā)布/訂閱模式,內(nèi)存淘汰機(jī)制、過(guò)期刪除機(jī)制等等。mwo28資訊網(wǎng)——每日最新資訊28at.com

BitMap和布隆過(guò)濾器的區(qū)別?

BitMap是用一個(gè)bit位來(lái)標(biāo)記某個(gè)元素,如果該元素存在,則將對(duì)應(yīng)的比特位設(shè)置為1,否則設(shè)置為0。mwo28資訊網(wǎng)——每日最新資訊28at.com

BitMapBitMapmwo28資訊網(wǎng)——每日最新資訊28at.com

由于采用了Bit為單位來(lái)存儲(chǔ)數(shù)據(jù),因此在存儲(chǔ)空間方面,可以大大節(jié)省BitMap適用于對(duì)大量的離散元素進(jìn)行快速判斷和計(jì)數(shù),例如IP地址統(tǒng)計(jì)、重復(fù)元素判斷等。mwo28資訊網(wǎng)——每日最新資訊28at.com

布隆過(guò)濾器是用于判斷一個(gè)元素是否屬于一個(gè)集合。布隆過(guò)濾器通過(guò)多個(gè)哈希函數(shù)和一個(gè)位數(shù)組來(lái)表示集合中的元素,將元素映射到位數(shù)組中的多個(gè)位上。當(dāng)一個(gè)元素經(jīng)過(guò)多個(gè)哈希函數(shù)映射后,對(duì)應(yīng)的位都被置為1。mwo28資訊網(wǎng)——每日最新資訊28at.com

舉個(gè)例子,假設(shè)有一個(gè)位圖數(shù)組長(zhǎng)度為 8,哈希函數(shù) 3 個(gè)的布隆過(guò)濾器。mwo28資訊網(wǎng)——每日最新資訊28at.com

布隆過(guò)濾器布隆過(guò)濾器mwo28資訊網(wǎng)——每日最新資訊28at.com

布隆過(guò)濾器判斷一個(gè)元素是否存在時(shí),只需要檢查對(duì)應(yīng)的位是否都為1:mwo28資訊網(wǎng)——每日最新資訊28at.com

  • 若有任意位為0,則可以確定元素不存在;
  • 若都為1,則可能存在,但存在一定的誤判概率。

查詢(xún)布隆過(guò)濾器說(shuō)數(shù)據(jù)存在,并不一定證明數(shù)據(jù)庫(kù)中存在這個(gè)數(shù)據(jù),但是查詢(xún)到數(shù)據(jù)不存在,數(shù)據(jù)庫(kù)中一定就不存在這個(gè)數(shù)據(jù)。布隆過(guò)濾器適用于對(duì)大規(guī)模數(shù)據(jù)進(jìn)行快速的去重或判重操作,例如網(wǎng)絡(luò)爬蟲(chóng)的URL去重、緩存的緩存命中判斷等。mwo28資訊網(wǎng)——每日最新資訊28at.com

Redis為什么使用跳表而不是用B+樹(shù)?

主要是從內(nèi)存占用、對(duì)范圍查找的支持、實(shí)現(xiàn)難易程度這三方面總結(jié)的原因:mwo28資訊網(wǎng)——每日最新資訊28at.com

  • 從內(nèi)存占用上來(lái)比較,跳表比平衡樹(shù)更靈活一些。平衡樹(shù)每個(gè)節(jié)點(diǎn)包含 2 個(gè)指針(分別指向左右子樹(shù)),而跳表每個(gè)節(jié)點(diǎn)包含的指針數(shù)目平均為 1/(1-p),具體取決于參數(shù) p 的大小。如果像 Redis里的實(shí)現(xiàn)一樣,取 p=1/4,那么平均每個(gè)節(jié)點(diǎn)包含 1.33 個(gè)指針,比平衡樹(shù)更有優(yōu)勢(shì)。
  • 在做范圍查找的時(shí)候,跳表比平衡樹(shù)操作要簡(jiǎn)單。在平衡樹(shù)上,我們找到指定范圍的小值之后,還需要以中序遍歷的順序繼續(xù)尋找其它不超過(guò)大值的節(jié)點(diǎn)。如果不對(duì)平衡樹(shù)進(jìn)行一定的改造,這里的中序遍歷并不容易實(shí)現(xiàn)。而在跳表上進(jìn)行范圍查找就非常簡(jiǎn)單,只需要在找到小值之后,對(duì)第 1 層鏈表進(jìn)行若干步的遍歷就可以實(shí)現(xiàn)。
  • 從算法實(shí)現(xiàn)難度上來(lái)比較,跳表比平衡樹(shù)要簡(jiǎn)單得多。平衡樹(shù)的插入和刪除操作可能引發(fā)子樹(shù)的調(diào)整,邏輯復(fù)雜,而跳表的插入和刪除只需要修改相鄰節(jié)點(diǎn)的指針,操作簡(jiǎn)單又快速。

Java

HashMap怎么處理哈希沖突的?

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

所以在 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),可以提高查詢(xún)性能,但是在數(shù)量較少時(shí),即數(shù)量小于6時(shí),會(huì)將紅黑樹(shù)轉(zhuǎn)換回鏈表。mwo28資訊網(wǎng)——每日最新資訊28at.com

HashMapHashMapmwo28資訊網(wǎng)——每日最新資訊28at.com

HashMap是線(xiàn)程安全的嗎?

不是的,會(huì)產(chǎn)生這些并發(fā)安全問(wèn)題:mwo28資訊網(wǎng)——每日最新資訊28at.com

  • JDK 1.7 HashMap 采用數(shù)組 + 鏈表的數(shù)據(jù)結(jié)構(gòu),多線(xiàn)程背景下,在數(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)題。但是多線(xiàn)程背景下,put 方法存在數(shù)據(jù)覆蓋的問(wèn)題。

并發(fā)環(huán)境下使用Map,怎么保證線(xiàn)程安全?

可以改用并發(fā)安全的 map 容器,比如ConcurrentHashMap 或者 hashtable,都是能保證線(xiàn)程安全的。mwo28資訊網(wǎng)——每日最新資訊28at.com

ConcurrentHashMap怎么保證線(xiàn)程安全?1.7和1.8的區(qū)別?

JDK 1.7 ConcurrentHashMapmwo28資訊網(wǎng)——每日最新資訊28at.com

在 JDK 1.7 中它使用的是數(shù)組加鏈表的形式實(shí)現(xiàn)的,而數(shù)組又分為:大數(shù)組 Segment 和小數(shù)組 HashEntry。Segment 是一種可重入鎖(ReentrantLock),在 ConcurrentHashMap 里扮演鎖的角色;HashEntry 則用于存儲(chǔ)鍵值對(duì)數(shù)據(jù)。一個(gè) ConcurrentHashMap 里包含一個(gè) Segment 數(shù)組,一個(gè) Segment 里包含一個(gè) HashEntry 數(shù)組,每個(gè) HashEntry 是一個(gè)鏈表結(jié)構(gòu)的元素。mwo28資訊網(wǎng)——每日最新資訊28at.com

JDK 1.7 ConcurrentHashMapJDK 1.7 ConcurrentHashMapmwo28資訊網(wǎng)——每日最新資訊28at.com

分段鎖技術(shù)將數(shù)據(jù)分成一段一段的存儲(chǔ),然后給每一段數(shù)據(jù)配一把鎖,當(dāng)一個(gè)線(xiàn)程占用鎖訪(fǎng)問(wèn)其中一個(gè)段數(shù)據(jù)的時(shí)候,其他段的數(shù)據(jù)也能被其他線(xiàn)程訪(fǎng)問(wèn),能夠?qū)崿F(xiàn)真正的并發(fā)訪(fǎng)問(wèn)。mwo28資訊網(wǎng)——每日最新資訊28at.com

JDK 1.8 ConcurrentHashMap

在 JDK 1.7 中,ConcurrentHashMap 雖然是線(xiàn)程安全的,但因?yàn)樗牡讓訉?shí)現(xiàn)是數(shù)組 + 鏈表的形式,所以在數(shù)據(jù)比較多的情況下訪(fǎng)問(wèn)是很慢的,因?yàn)橐闅v整個(gè)鏈表,而 JDK 1.8 則使用了數(shù)組 + 鏈表/紅黑樹(shù)的方式優(yōu)化了 ConcurrentHashMap 的實(shí)現(xiàn),具體實(shí)現(xiàn)結(jié)構(gòu)如下:mwo28資訊網(wǎng)——每日最新資訊28at.com

JDK 1.8 ConcurrentHashMapJDK 1.8 ConcurrentHashMapmwo28資訊網(wǎng)——每日最新資訊28at.com

JDK 1.8 ConcurrentHashMap 主要通過(guò) volatile + CAS 或者 synchronized 來(lái)實(shí)現(xiàn)的線(xiàn)程安全的。mwo28資訊網(wǎng)——每日最新資訊28at.com

添加元素時(shí)首先會(huì)判斷容器是否為空:mwo28資訊網(wǎng)——每日最新資訊28at.com

  • 如果為空則使用  volatile  加  CAS  來(lái)初始化,如果容器不為空,則根據(jù)存儲(chǔ)的元素計(jì)算該位置是否為空。

如果根據(jù)存儲(chǔ)的元素計(jì)算結(jié)果為空,則利用  CAS  設(shè)置該節(jié)點(diǎn);mwo28資訊網(wǎng)——每日最新資訊28at.com

如果根據(jù)存儲(chǔ)的元素計(jì)算結(jié)果不為空,則使用 synchronized  ,然后,遍歷桶中的數(shù)據(jù),并替換或新增節(jié)點(diǎn)到桶中,最后再判斷是否需要轉(zhuǎn)為紅黑樹(shù),這樣就能保證并發(fā)訪(fǎng)問(wèn)時(shí)的線(xiàn)程安全了。mwo28資訊網(wǎng)——每日最新資訊28at.com

如果把上面的執(zhí)行用一句話(huà)歸納的話(huà),就相當(dāng)于是ConcurrentHashMap通過(guò)對(duì)頭結(jié)點(diǎn)加鎖來(lái)保證線(xiàn)程安全的,鎖的粒度相比 Segment 來(lái)說(shuō)更小了,發(fā)生沖突和加鎖的頻率降低了,并發(fā)操作的性能就提高了。而且 JDK 1.8 使用的是紅黑樹(shù)優(yōu)化了之前的固定鏈表,那么當(dāng)數(shù)據(jù)量比較大的時(shí)候,查詢(xún)性能也得到了很大的提升,從之前的 O(n) 優(yōu)化到了 O(logn) 的時(shí)間復(fù)雜度。mwo28資訊網(wǎng)——每日最新資訊28at.com

分段鎖是可重入的嗎?

JDK 1.7 ConcurrentHashMap中的分段鎖是用了 ReentrantLock,是一個(gè)可重入的鎖。mwo28資訊網(wǎng)——每日最新資訊28at.com

你怎么理解可重入鎖?

可重入鎖是指同一個(gè)線(xiàn)程在獲取了鎖之后,可以再次重復(fù)獲取該鎖而不會(huì)造成死鎖或其他問(wèn)題。當(dāng)一個(gè)線(xiàn)程持有鎖時(shí),如果再次嘗試獲取該鎖,就會(huì)成功獲取而不會(huì)被阻塞。mwo28資訊網(wǎng)——每日最新資訊28at.com

ReentrantLock實(shí)現(xiàn)可重入鎖的機(jī)制是基于線(xiàn)程持有鎖的計(jì)數(shù)器。mwo28資訊網(wǎng)——每日最新資訊28at.com

  • 當(dāng)一個(gè)線(xiàn)程第一次獲取鎖時(shí),計(jì)數(shù)器會(huì)加1,表示該線(xiàn)程持有了鎖。在此之后,如果同一個(gè)線(xiàn)程再次獲取鎖,計(jì)數(shù)器會(huì)再次加1。每次線(xiàn)程成功獲取鎖時(shí),都會(huì)將計(jì)數(shù)器加1。
  • 當(dāng)線(xiàn)程釋放鎖時(shí),計(jì)數(shù)器會(huì)相應(yīng)地減1。只有當(dāng)計(jì)數(shù)器減到0時(shí),鎖才會(huì)完全釋放,其他線(xiàn)程才有機(jī)會(huì)獲取鎖。

這種計(jì)數(shù)器的設(shè)計(jì)使得同一個(gè)線(xiàn)程可以多次獲取同一個(gè)鎖,而不會(huì)造成死鎖或其他問(wèn)題。每次獲取鎖時(shí),計(jì)數(shù)器加1;每次釋放鎖時(shí),計(jì)數(shù)器減1。只有當(dāng)計(jì)數(shù)器減到0時(shí),鎖才會(huì)完全釋放。mwo28資訊網(wǎng)——每日最新資訊28at.com

ReentrantLock通過(guò)這種計(jì)數(shù)器的方式,實(shí)現(xiàn)了可重入鎖的機(jī)制。它允許同一個(gè)線(xiàn)程多次獲取同一個(gè)鎖,并且能夠正確地處理鎖的獲取和釋放,避免了死鎖和其他并發(fā)問(wèn)題。mwo28資訊網(wǎng)——每日最新資訊28at.com

什么是公平鎖和非公平鎖?

  • 公平鎖: 指多個(gè)線(xiàn)程按照申請(qǐng)鎖的順序來(lái)獲取鎖,線(xiàn)程直接進(jìn)入隊(duì)列中排隊(duì),隊(duì)列中的第一個(gè)線(xiàn)程才能獲得鎖。公平鎖的優(yōu)點(diǎn)在于各個(gè)線(xiàn)程公平平等,每個(gè)線(xiàn)程等待一段時(shí)間后,都有執(zhí)行的機(jī)會(huì),而它的缺點(diǎn)就在于整體執(zhí)行速度更慢,吞吐量更小。
  • 非公平鎖: 多個(gè)線(xiàn)程加鎖時(shí)直接嘗試獲取鎖,能搶到鎖到直接占有鎖,搶不到才會(huì)到等待隊(duì)列的隊(duì)尾等待。非公平鎖的優(yōu)勢(shì)就在于整體執(zhí)行速度更快,吞吐量更大,但同時(shí)也可能產(chǎn)生線(xiàn)程饑餓問(wèn)題,也就是說(shuō)如果一直有線(xiàn)程插隊(duì),那么在等待隊(duì)列中的線(xiàn)程可能長(zhǎng)時(shí)間得不到運(yùn)行。

非公平鎖吞吐量為什么比公平鎖大?

  • 公平鎖執(zhí)行流程:獲取鎖時(shí),先將線(xiàn)程自己添加到等待隊(duì)列的隊(duì)尾并休眠,當(dāng)某線(xiàn)程用完鎖之后,會(huì)去喚醒等待隊(duì)列中隊(duì)首的線(xiàn)程嘗試去獲取鎖,鎖的使用順序也就是隊(duì)列中的先后順序,在整個(gè)過(guò)程中,線(xiàn)程會(huì)從運(yùn)行狀態(tài)切換到休眠狀態(tài),再?gòu)男菝郀顟B(tài)恢復(fù)成運(yùn)行狀態(tài),但線(xiàn)程每次休眠和恢復(fù)都需要從用戶(hù)態(tài)轉(zhuǎn)換成內(nèi)核態(tài),而這個(gè)狀態(tài)的轉(zhuǎn)換是比較慢的,所以公平鎖的執(zhí)行速度會(huì)比較慢。
  • 非公平鎖執(zhí)行流程:當(dāng)線(xiàn)程獲取鎖時(shí),會(huì)先通過(guò) CAS 嘗試獲取鎖,如果獲取成功就直接擁有鎖,如果獲取鎖失敗才會(huì)進(jìn)入等待隊(duì)列,等待下次嘗試獲取鎖。這樣做的好處是,獲取鎖不用遵循先到先得的規(guī)則,從而避免了線(xiàn)程休眠和恢復(fù)的操作,這樣就加速了程序的執(zhí)行效率。

JVM

JVM內(nèi)存結(jié)構(gòu)有哪些?

圖片圖片mwo28資訊網(wǎng)——每日最新資訊28at.com

JVM的內(nèi)存結(jié)構(gòu)主要分為以下幾個(gè)部分:mwo28資訊網(wǎng)——每日最新資訊28at.com

  • 程序計(jì)數(shù)器(Program Counter Register):每個(gè)線(xiàn)程都有一個(gè)程序計(jì)數(shù)器。當(dāng)線(xiàn)程執(zhí)行 Java 方法時(shí),程序計(jì)數(shù)器保存當(dāng)前執(zhí)行指令的地址,以便在 JVM 調(diào)用其他方法或恢復(fù)線(xiàn)程執(zhí)行時(shí)重新回到正確的位置。
  • Java 虛擬機(jī)棧(Java Virtual Machine Stacks):每個(gè)線(xiàn)程都有一個(gè)虛擬機(jī)棧。虛擬機(jī)棧保存著方法執(zhí)行期間的局部變量、操作數(shù)棧、方法出口等信息。線(xiàn)程每調(diào)用一個(gè) Java 方法時(shí),會(huì)創(chuàng)建一個(gè)棧幀(Stack Frame),棧幀包含著該方法的局部變量、操作數(shù)棧、方法返回地址等信息。棧幀在方法執(zhí)行結(jié)束后會(huì)被彈出。
  • 本地方法棧(Native Method Stack):與 Java 虛擬機(jī)棧類(lèi)似,但是為本地方法服務(wù)。
  • Java 堆(Java Heap):Java 堆是 Java 虛擬機(jī)中最大的一塊內(nèi)存區(qū)域,用于存儲(chǔ)各種類(lèi)型的對(duì)象實(shí)例,也是垃圾收集器的主要工作區(qū)域,Java 堆根據(jù)對(duì)象存活時(shí)間的不同,Java 堆還被分為年輕代、老年代兩個(gè)區(qū)域,年輕代還被進(jìn)一步劃分為 Eden 區(qū)、From Survivor 0、To Survivor 1 區(qū)。
  • 方法區(qū)(Method Area):方法區(qū)也是所有線(xiàn)程共享的部分,它用于存儲(chǔ)類(lèi)的加載信息、靜態(tài)變量、常量池、方法字節(jié)碼等數(shù)據(jù)。在 Java 8 及以前的版本中,方法區(qū)被實(shí)現(xiàn)為永久代(Permanent Generation),在 Java 8 中被改為元空間(Metaspace)。

JVM為什么把堆區(qū)進(jìn)一步的劃分?

Java 堆還被分為年輕代、老年代兩個(gè)區(qū)域,年輕代還被進(jìn)一步劃分為 Eden 區(qū)、From Survivor 0、To Survivor 1 區(qū)。mwo28資訊網(wǎng)——每日最新資訊28at.com

不同的區(qū)域存放不同生命周期的對(duì)象,這樣可以根據(jù)不同的區(qū)域使用不同的垃圾回收算法,更具有針對(duì)性。mwo28資訊網(wǎng)——每日最新資訊28at.com

jvm-memoryjvm-memorymwo28資訊網(wǎng)——每日最新資訊28at.com

當(dāng)有對(duì)象需要分配時(shí),一個(gè)對(duì)象永遠(yuǎn)優(yōu)先被分配在年輕代的 Eden 區(qū),等到 Eden 區(qū)域內(nèi)存不夠時(shí),Java 虛擬機(jī)會(huì)啟動(dòng)垃圾回收。此時(shí) Eden 區(qū)中沒(méi)有被引用的對(duì)象的內(nèi)存就會(huì)被回收,而一些存活時(shí)間較長(zhǎng)的對(duì)象則會(huì)進(jìn)入到老年代。在 JVM 中有一個(gè)名為 -XX:MaxTenuringThreshold 的參數(shù)專(zhuān)門(mén)用來(lái)設(shè)置晉升到老年代所需要經(jīng)歷的 GC 次數(shù),即在年輕代的對(duì)象經(jīng)過(guò)了指定次數(shù)的 GC 后,將在下次 GC 時(shí)進(jìn)入老年代。mwo28資訊網(wǎng)——每日最新資訊28at.com

之所以要在堆區(qū)進(jìn)一步劃分,主要是為了提高垃圾回收的效率。虛擬機(jī)中的對(duì)象必然有存活時(shí)間長(zhǎng)的對(duì)象,也有存活時(shí)間短的對(duì)象,這是一個(gè)普遍存在的正態(tài)分布規(guī)律。如果我們將其混在一起,那么因?yàn)榇婊顣r(shí)間短的對(duì)象有很多,那么勢(shì)必導(dǎo)致較為頻繁的垃圾回收。而垃圾回收時(shí)不得不對(duì)所有內(nèi)存都進(jìn)行掃描,但其實(shí)有一部分對(duì)象,它們存活時(shí)間很長(zhǎng),對(duì)他們進(jìn)行掃描完全是浪費(fèi)時(shí)間mwo28資訊網(wǎng)——每日最新資訊28at.com

String保存在哪里呢?

String 保存在字符串常量池中,不同于其他對(duì)象,它的值是不可變的,且可以被多個(gè)引用共享。mwo28資訊網(wǎng)——每日最新資訊28at.com

說(shuō)一下JVM加載一個(gè)類(lèi)的過(guò)程

類(lèi)從被加載到虛擬機(jī)內(nèi)存開(kāi)始,到卸載出內(nèi)存為止,它的整個(gè)生命周期包括以下 7 個(gè)階段:mwo28資訊網(wǎng)——每日最新資訊28at.com

  • 加載
  • 驗(yàn)證
  • 準(zhǔn)備
  • 解析
  • 初始化
  • 使用
  • 卸載

驗(yàn)證、準(zhǔn)備、解析 3 個(gè)階段統(tǒng)稱(chēng)為連接。mwo28資訊網(wǎng)——每日最新資訊28at.com

Load ClassLoad Classmwo28資訊網(wǎng)——每日最新資訊28at.com

JVM 中類(lèi)的裝載是由類(lèi)加載器,也就是ClassLoader,和它的子類(lèi)來(lái)實(shí)現(xiàn)的,Java 中的類(lèi)加載器是一個(gè)重要的 Java 運(yùn)行時(shí)系統(tǒng)組件,它負(fù)責(zé)在運(yùn)行時(shí)查找和裝入類(lèi)文件中的類(lèi)。mwo28資訊網(wǎng)——每日最新資訊28at.com

由于 Java 的跨平臺(tái)性, 經(jīng)過(guò)編譯的 Java 源程序并不是一個(gè)可執(zhí)行程序, 而是一個(gè)或多個(gè)類(lèi)文件。當(dāng) Java 程序需要使用某個(gè)類(lèi)時(shí),JVM 會(huì)確保這個(gè)類(lèi)已經(jīng)被加載、連接( 驗(yàn)證、 準(zhǔn)備和解析)和初始化。mwo28資訊網(wǎng)——每日最新資訊28at.com

類(lèi)的加載是指把類(lèi)的.class 文件中的數(shù)據(jù)讀入到內(nèi)存中,通常是創(chuàng)建一個(gè)字節(jié)數(shù)組讀入.class 文件,然后產(chǎn)生與所加載類(lèi)對(duì)應(yīng)的 Class 對(duì)象。加載完成后, Class 對(duì)象還不完整, 所以此時(shí)的類(lèi)還不可用。當(dāng)類(lèi)被加載后就進(jìn)入連接階段, 這一階段包括驗(yàn)證、準(zhǔn)備( 為靜態(tài)變量分配內(nèi)存并設(shè)置默認(rèn)的初始值) 和解析( 將符號(hào)引用替換為直接引用) 三個(gè)步驟。mwo28資訊網(wǎng)——每日最新資訊28at.com

最后 JVM 對(duì)類(lèi)進(jìn)行初始化,包括:1)如果類(lèi)存在直接的父類(lèi)并且這個(gè)類(lèi)還沒(méi)有被初始化,那么就先初始化父類(lèi);2)如果類(lèi)中存在初始化語(yǔ)句, 就依次執(zhí)行這些初始化語(yǔ)句。mwo28資訊網(wǎng)——每日最新資訊28at.com

網(wǎng)絡(luò)

tcp滑動(dòng)窗口是怎么實(shí)現(xiàn)的?

發(fā)送方的滑動(dòng)窗口

我們先來(lái)看看發(fā)送方的窗口,下圖就是發(fā)送方緩存的數(shù)據(jù),根據(jù)處理的情況分成四個(gè)部分,其中深藍(lán)色方框是發(fā)送窗口,紫色方框是可用窗口:mwo28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片mwo28資訊網(wǎng)——每日最新資訊28at.com

  • #1 是已發(fā)送并收到 ACK確認(rèn)的數(shù)據(jù):1~31 字節(jié)
  • #2 是已發(fā)送但未收到 ACK確認(rèn)的數(shù)據(jù):32~45 字節(jié)
  • #3 是未發(fā)送但總大小在接收方處理范圍內(nèi)(接收方還有空間):46~51字節(jié)
  • #4 是未發(fā)送但總大小超過(guò)接收方處理范圍(接收方?jīng)]有空間):52字節(jié)以后

在下圖,當(dāng)發(fā)送方把數(shù)據(jù)「全部」都一下發(fā)送出去后,可用窗口的大小就為 0 了,表明可用窗口耗盡,在沒(méi)收到 ACK 確認(rèn)之前是無(wú)法繼續(xù)發(fā)送數(shù)據(jù)了。mwo28資訊網(wǎng)——每日最新資訊28at.com

可用窗口耗盡可用窗口耗盡mwo28資訊網(wǎng)——每日最新資訊28at.com

在下圖,當(dāng)收到之前發(fā)送的數(shù)據(jù) 32~36 字節(jié)的 ACK 確認(rèn)應(yīng)答后,如果發(fā)送窗口的大小沒(méi)有變化,則滑動(dòng)窗口往右邊移動(dòng) 5 個(gè)字節(jié),因?yàn)橛?5 個(gè)字節(jié)的數(shù)據(jù)被應(yīng)答確認(rèn),接下來(lái) 52~56 字節(jié)又變成了可用窗口,那么后續(xù)也就可以發(fā)送 52~56 這 5 個(gè)字節(jié)的數(shù)據(jù)了。mwo28資訊網(wǎng)——每日最新資訊28at.com

32 ~ 36 字節(jié)已確認(rèn)32 ~ 36 字節(jié)已確認(rèn)mwo28資訊網(wǎng)——每日最新資訊28at.com

程序是如何表示發(fā)送方的四個(gè)部分的呢?

TCP 滑動(dòng)窗口方案使用三個(gè)指針來(lái)跟蹤在四個(gè)傳輸類(lèi)別中的每一個(gè)類(lèi)別中的字節(jié)。其中兩個(gè)指針是絕對(duì)指針(指特定的序列號(hào)),一個(gè)是相對(duì)指針(需要做偏移)。mwo28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片mwo28資訊網(wǎng)——每日最新資訊28at.com

SND.WND、SND.UN、SND.NXTmwo28資訊網(wǎng)——每日最新資訊28at.com

  • SND.WND:表示發(fā)送窗口的大小(大小是由接收方指定的);
  • SND.UNA(Send Unacknoleged):是一個(gè)絕對(duì)指針,它指向的是已發(fā)送但未收到確認(rèn)的第一個(gè)字節(jié)的序列號(hào),也就是 #2 的第一個(gè)字節(jié)。
  • SND.NXT:也是一個(gè)絕對(duì)指針,它指向未發(fā)送但可發(fā)送范圍的第一個(gè)字節(jié)的序列號(hào),也就是 #3 的第一個(gè)字節(jié)。
  • 指向 #4 的第一個(gè)字節(jié)是個(gè)相對(duì)指針,它需要 SND.UNA 指針加上 SND.WND 大小的偏移量,就可以指向 #4 的第一個(gè)字節(jié)了。

那么可用窗口大小的計(jì)算就可以是:mwo28資訊網(wǎng)——每日最新資訊28at.com

可用窗口大小 = SND.WND -(SND.NXT - SND.UNA)mwo28資訊網(wǎng)——每日最新資訊28at.com

接收方的滑動(dòng)窗口

接下來(lái)我們看看接收方的窗口,接收窗口相對(duì)簡(jiǎn)單一些,根據(jù)處理的情況劃分成三個(gè)部分:mwo28資訊網(wǎng)——每日最新資訊28at.com

  • #1 + #2 是已成功接收并確認(rèn)的數(shù)據(jù)(等待應(yīng)用進(jìn)程讀取);
  • #3 是未收到數(shù)據(jù)但可以接收的數(shù)據(jù);
  • #4 未收到數(shù)據(jù)并不可以接收的數(shù)據(jù);

接收窗口接收窗口mwo28資訊網(wǎng)——每日最新資訊28at.com

其中三個(gè)接收部分,使用兩個(gè)指針進(jìn)行劃分:mwo28資訊網(wǎng)——每日最新資訊28at.com

  • RCV.WND:表示接收窗口的大小,它會(huì)通告給發(fā)送方。
  • RCV.NXT:是一個(gè)指針,它指向期望從發(fā)送方發(fā)送來(lái)的下一個(gè)數(shù)據(jù)字節(jié)的序列號(hào),也就是 #3 的第一個(gè)字節(jié)。
  • 指向 #4 的第一個(gè)字節(jié)是個(gè)相對(duì)指針,它需要 RCV.NXT 指針加上 RCV.WND 大小的偏移量,就可以指向 #4 的第一個(gè)字節(jié)了。

tcp粘包怎么解決?

粘包的問(wèn)題出現(xiàn)是因?yàn)椴恢酪粋€(gè)用戶(hù)消息的邊界在哪,如果知道了邊界在哪,接收方就可以通過(guò)邊界來(lái)劃分出有效的用戶(hù)消息。mwo28資訊網(wǎng)——每日最新資訊28at.com

一般有三種方式分包的方式:mwo28資訊網(wǎng)——每日最新資訊28at.com

  • 固定長(zhǎng)度的消息;
  • 特殊字符作為邊界;
  • 自定義消息結(jié)構(gòu)。

固定長(zhǎng)度的消息

這種是最簡(jiǎn)單方法,即每個(gè)用戶(hù)消息都是固定長(zhǎng)度的,比如規(guī)定一個(gè)消息的長(zhǎng)度是 64 個(gè)字節(jié),當(dāng)接收方接滿(mǎn) 64 個(gè)字節(jié),就認(rèn)為這個(gè)內(nèi)容是一個(gè)完整且有效的消息。mwo28資訊網(wǎng)——每日最新資訊28at.com

但是這種方式靈活性不高,實(shí)際中很少用。mwo28資訊網(wǎng)——每日最新資訊28at.com

特殊字符作為邊界

我們可以在兩個(gè)用戶(hù)消息之間插入一個(gè)特殊的字符串,這樣接收方在接收數(shù)據(jù)時(shí),讀到了這個(gè)特殊字符,就把認(rèn)為已經(jīng)讀完一個(gè)完整的消息。mwo28資訊網(wǎng)——每日最新資訊28at.com

HTTP 是一個(gè)非常好的例子。mwo28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片mwo28資訊網(wǎng)——每日最新資訊28at.com

HTTP 通過(guò)設(shè)置回車(chē)符、換行符作為 HTTP 報(bào)文協(xié)議的邊界。mwo28資訊網(wǎng)——每日最新資訊28at.com

有一點(diǎn)要注意,這個(gè)作為邊界點(diǎn)的特殊字符,如果剛好消息內(nèi)容里有這個(gè)特殊字符,我們要對(duì)這個(gè)字符轉(zhuǎn)義,避免被接收方當(dāng)作消息的邊界點(diǎn)而解析到無(wú)效的數(shù)據(jù)。mwo28資訊網(wǎng)——每日最新資訊28at.com

自定義消息結(jié)構(gòu)

我們可以自定義一個(gè)消息結(jié)構(gòu),由包頭和數(shù)據(jù)組成,其中包頭包是固定大小的,而且包頭里有一個(gè)字段來(lái)說(shuō)明緊隨其后的數(shù)據(jù)有多大。mwo28資訊網(wǎng)——每日最新資訊28at.com

比如這個(gè)消息結(jié)構(gòu)體,首先 4 個(gè)字節(jié)大小的變量來(lái)表示數(shù)據(jù)長(zhǎng)度,真正的數(shù)據(jù)則在后面。mwo28資訊網(wǎng)——每日最新資訊28at.com

struct {     u_int32_t message_length;     char message_data[]; } message;

當(dāng)接收方接收到包頭的大小(比如 4 個(gè)字節(jié))后,就解析包頭的內(nèi)容,于是就可以知道數(shù)據(jù)的長(zhǎng)度,然后接下來(lái)就繼續(xù)讀取數(shù)據(jù),直到讀滿(mǎn)數(shù)據(jù)的長(zhǎng)度,就可以組裝成一個(gè)完整到用戶(hù)消息來(lái)處理了。mwo28資訊網(wǎng)——每日最新資訊28at.com

HTTP1.1和2.0的區(qū)別是什么?

HTTP/2 相比 HTTP/1.1 性能上的改進(jìn):mwo28資訊網(wǎng)——每日最新資訊28at.com

  • 頭部壓縮
  • 二進(jìn)制格式
  • 并發(fā)傳輸
  • 服務(wù)器主動(dòng)推送資源

1. 頭部壓縮

HTTP/2 會(huì)壓縮頭(Header)如果你同時(shí)發(fā)出多個(gè)請(qǐng)求,他們的頭是一樣的或是相似的,那么,協(xié)議會(huì)幫你消除重復(fù)的部分。mwo28資訊網(wǎng)——每日最新資訊28at.com

這就是所謂的 HPACK 算法:在客戶(hù)端和服務(wù)器同時(shí)維護(hù)一張頭信息表,所有字段都會(huì)存入這個(gè)表,生成一個(gè)索引號(hào),以后就不發(fā)送同樣字段了,只發(fā)送索引號(hào),這樣就提高速度了。mwo28資訊網(wǎng)——每日最新資訊28at.com

2. 二進(jìn)制格式

HTTP/2 不再像 HTTP/1.1 里的純文本形式的報(bào)文,而是全面采用了二進(jìn)制格式,頭信息和數(shù)據(jù)體都是二進(jìn)制,并且統(tǒng)稱(chēng)為幀(frame):頭信息幀(Headers Frame)和數(shù)據(jù)幀(Data Frame)。mwo28資訊網(wǎng)——每日最新資訊28at.com

HTTP/1 與 HTTP/2HTTP/1 與 HTTP/2mwo28資訊網(wǎng)——每日最新資訊28at.com

這樣雖然對(duì)人不友好,但是對(duì)計(jì)算機(jī)非常友好,因?yàn)橛?jì)算機(jī)只懂二進(jìn)制,那么收到報(bào)文后,無(wú)需再將明文的報(bào)文轉(zhuǎn)成二進(jìn)制,而是直接解析二進(jìn)制報(bào)文,這增加了數(shù)據(jù)傳輸?shù)男省?span style="display:none">mwo28資訊網(wǎng)——每日最新資訊28at.com

3. 并發(fā)傳輸

我們都知道 HTTP/1.1 的實(shí)現(xiàn)是基于請(qǐng)求-響應(yīng)模型的。同一個(gè)連接中,HTTP 完成一個(gè)事務(wù)(請(qǐng)求與響應(yīng)),才能處理下一個(gè)事務(wù),也就是說(shuō)在發(fā)出請(qǐng)求等待響應(yīng)的過(guò)程中,是沒(méi)辦法做其他事情的,如果響應(yīng)遲遲不來(lái),那么后續(xù)的請(qǐng)求是無(wú)法發(fā)送的,也造成了隊(duì)頭阻塞的問(wèn)題。mwo28資訊網(wǎng)——每日最新資訊28at.com

而 HTTP/2 就很牛逼了,引出了 Stream 概念,多個(gè) Stream 復(fù)用在一條 TCP 連接。mwo28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片mwo28資訊網(wǎng)——每日最新資訊28at.com

從上圖可以看到,1 個(gè) TCP 連接包含多個(gè) Stream,Stream 里可以包含 1 個(gè)或多個(gè) Message,Message 對(duì)應(yīng) HTTP/1 中的請(qǐng)求或響應(yīng),由 HTTP 頭部和包體構(gòu)成。Message 里包含一條或者多個(gè) Frame,F(xiàn)rame 是 HTTP/2 最小單位,以二進(jìn)制壓縮格式存放 HTTP/1 中的內(nèi)容(頭部和包體)。mwo28資訊網(wǎng)——每日最新資訊28at.com

針對(duì)不同的 HTTP 請(qǐng)求用獨(dú)一無(wú)二的 Stream ID 來(lái)區(qū)分,接收端可以通過(guò) Stream ID 有序組裝成 HTTP 消息,不同 Stream 的幀是可以亂序發(fā)送的,因此可以并發(fā)不同的 Stream ,也就是 HTTP/2 可以并行交錯(cuò)地發(fā)送請(qǐng)求和響應(yīng)。mwo28資訊網(wǎng)——每日最新資訊28at.com

比如下圖,服務(wù)端并行交錯(cuò)地發(fā)送了兩個(gè)響應(yīng):Stream 1 和 Stream 3,這兩個(gè) Stream 都是跑在一個(gè) TCP 連接上,客戶(hù)端收到后,會(huì)根據(jù)相同的 Stream ID 有序組裝成 HTTP 消息。mwo28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片mwo28資訊網(wǎng)——每日最新資訊28at.com

4、服務(wù)器推送

HTTP/2 還在一定程度上改善了傳統(tǒng)的「請(qǐng)求 - 應(yīng)答」工作模式,服務(wù)端不再是被動(dòng)地響應(yīng),可以主動(dòng)向客戶(hù)端發(fā)送消息。mwo28資訊網(wǎng)——每日最新資訊28at.com

客戶(hù)端和服務(wù)器雙方都可以建立 Stream, Stream ID 也是有區(qū)別的,客戶(hù)端建立的 Stream 必須是奇數(shù)號(hào),而服務(wù)器建立的 Stream 必須是偶數(shù)號(hào)。mwo28資訊網(wǎng)——每日最新資訊28at.com

比如下圖,Stream 1 是客戶(hù)端向服務(wù)端請(qǐng)求的資源,屬于客戶(hù)端建立的 Stream,所以該 Stream 的 ID 是奇數(shù)(數(shù)字 1);Stream 2 和 4 都是服務(wù)端主動(dòng)向客戶(hù)端推送的資源,屬于服務(wù)端建立的 Stream,所以這兩個(gè) Stream 的 ID 是偶數(shù)(數(shù)字 2 和 4)。mwo28資訊網(wǎng)——每日最新資訊28at.com

圖片mwo28資訊網(wǎng)——每日最新資訊28at.com

再比如,客戶(hù)端通過(guò) HTTP/1.1 請(qǐng)求從服務(wù)器那獲取到了 HTML 文件,而 HTML 可能還需要依賴(lài) CSS 來(lái)渲染頁(yè)面,這時(shí)客戶(hù)端還要再發(fā)起獲取 CSS 文件的請(qǐng)求,需要兩次消息往返,如下圖左邊部分:mwo28資訊網(wǎng)——每日最新資訊28at.com

圖片mwo28資訊網(wǎng)——每日最新資訊28at.com

如上圖右邊部分,在 HTTP/2 中,客戶(hù)端在訪(fǎng)問(wèn) HTML 時(shí),服務(wù)器可以直接主動(dòng)推送 CSS 文件,減少了消息傳遞的次數(shù)。mwo28資訊網(wǎng)——每日最新資訊28at.com

操作系統(tǒng)

講講IO多路復(fù)用的實(shí)現(xiàn)原理,select和epoll的區(qū)別是什么?

I/O 的多路復(fù)用,可以只在一個(gè)進(jìn)程里處理多個(gè)文件的 I/O,Linux 下有三種提供 I/O 多路復(fù)用的 API,分別是:select、poll、epoll。mwo28資訊網(wǎng)——每日最新資訊28at.com

select 和 poll 并沒(méi)有本質(zhì)區(qū)別,它們內(nèi)部都是使用「線(xiàn)性結(jié)構(gòu)」來(lái)存儲(chǔ)進(jìn)程關(guān)注的 Socket 集合。mwo28資訊網(wǎng)——每日最新資訊28at.com

在使用的時(shí)候,首先需要把關(guān)注的 Socket 集合通過(guò) select/poll 系統(tǒng)調(diào)用從用戶(hù)態(tài)拷貝到內(nèi)核態(tài),然后由內(nèi)核檢測(cè)事件,當(dāng)有網(wǎng)絡(luò)事件產(chǎn)生時(shí),內(nèi)核需要遍歷進(jìn)程關(guān)注 Socket 集合,找到對(duì)應(yīng)的 Socket,并設(shè)置其狀態(tài)為可讀/可寫(xiě),然后把整個(gè) Socket 集合從內(nèi)核態(tài)拷貝到用戶(hù)態(tài),用戶(hù)態(tài)還要繼續(xù)遍歷整個(gè) Socket 集合找到可讀/可寫(xiě)的 Socket,然后對(duì)其處理。mwo28資訊網(wǎng)——每日最新資訊28at.com

很明顯發(fā)現(xiàn),select 和 poll 的缺陷在于,當(dāng)客戶(hù)端越多,也就是 Socket 集合越大,Socket 集合的遍歷和拷貝會(huì)帶來(lái)很大的開(kāi)銷(xiāo),因此也很難應(yīng)對(duì) C10K。mwo28資訊網(wǎng)——每日最新資訊28at.com

圖片mwo28資訊網(wǎng)——每日最新資訊28at.com

epoll 是解決 C10K 問(wèn)題的利器,通過(guò)兩個(gè)方面解決了 select/poll 的問(wèn)題。mwo28資訊網(wǎng)——每日最新資訊28at.com

  • epoll 在內(nèi)核里使用「紅黑樹(shù)」來(lái)關(guān)注進(jìn)程所有待檢測(cè)的 Socket,紅黑樹(shù)是個(gè)高效的數(shù)據(jù)結(jié)構(gòu),增刪改一般時(shí)間復(fù)雜度是 O(logn),通過(guò)對(duì)這棵黑紅樹(shù)的管理,不需要像 select/poll 在每次操作時(shí)都傳入整個(gè) Socket 集合,減少了內(nèi)核和用戶(hù)空間大量的數(shù)據(jù)拷貝和內(nèi)存分配。
  • epoll 使用事件驅(qū)動(dòng)的機(jī)制,內(nèi)核里維護(hù)了一個(gè)「鏈表」來(lái)記錄就緒事件,只將有事件發(fā)生的 Socket 集合傳遞給應(yīng)用程序,不需要像 select/poll 那樣輪詢(xún)掃描整個(gè)集合(包含有和無(wú)事件的 Socket ),大大提高了檢測(cè)的效率。

本文鏈接:http://www.www897cc.com/showinfo-26-57939-0.html還得是騰訊,撈了我一把!

聲明:本網(wǎng)頁(yè)內(nèi)容旨在傳播知識(shí),若有侵權(quán)等問(wèn)題請(qǐng)及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。郵件:2376512515@qq.com

上一篇: 分享元服務(wù)「心情盲盒」開(kāi)發(fā)經(jīng)歷

下一篇: Spring 七種事務(wù)傳播性介紹

標(biāo)簽:
  • 熱門(mén)焦點(diǎn)
Top 主站蜘蛛池模板: 凤庆县| 育儿| 务川| 偃师市| 柳林县| 鄢陵县| 泾川县| 麦盖提县| 静安区| 英德市| 四平市| 桐柏县| 双江| 上犹县| 衡南县| 南投市| 明星| 奉新县| 新民市| 伊川县| 双城市| 阿城市| 高碑店市| 鄂托克旗| 新民市| 满城县| 莫力| 黄石市| 乌拉特中旗| 尉氏县| 房产| 双牌县| 务川| 上林县| 佛教| 台州市| 姚安县| 金湖县| 大姚县| 炎陵县| 福贡县|