又是一年一度的秋季校招開始了,以往的校招各個公司都會在公司現場或者學校現場安排學生進行現場面試?可是今年因爲疫情的緣由,不容許讓同窗在現場進行一個面試,因此今年的面試形式就從線下轉到了線上,面試形式的轉變,可是咱們考覈學生的方式依舊沒有轉變。html
校招的同窗和社招的同窗有很大的不一樣,他們沒有豐富的工做經驗,沒有太多的項目經歷,那麼咱們如何去衡量一個校招的同窗呢?那就是基礎和潛力,怎麼去理解基礎呢?俗話說不積跬步,無以致千里,不積小流,無以成江海,若是沒有一個好的基礎那麼怎麼才能成爲一個優秀的工程師呢。如何去考察一個學生基礎的好壞呢?我以爲有三個方面比較重要,計算機網絡,操做系統以及算法和數據結構,一般來講計網考察得特別多,常見的一些問題:面試
上面列舉的問題只是其中一部分,這些問題基本在上課的書本中找到答案,若是你這些都不會那麼只能說基礎算是比較差了。因爲此次是視頻面試,我一般會問你以爲牛客網的視頻面試是用的TCP仍是UDP呢?在我揭曉答案以前你們也能夠想一想使用的是哪一個網絡協議,在面試的過程當中全部的同窗都回答了應該是使用的是UDP。我問爲何使用UDP?基本都會回答道UDP是一個無鏈接的協議,不用保證可靠性,傳輸速度快。我又問道若是UDP不保證可靠性,我們在視頻面試的時候我問你問題,若是你回答問題的視頻流丟包了,那麼你的答案我就聽不見了,那視頻面試的體驗將會很是低。很多同窗在這個時候就會改答案說那應該使用的是TCP吧,我這是又會問道TCP因爲須要保證可靠性,可是在公網的複雜環境下,想必應該常常會出現緩衝或者卡頓的現象吧,不少同窗這個時候就會啞口無言了。算法
其實這個問題的答案不難想出,咱們能夠將TCP和UDP的特性互相結合起來,讓這個協議既能夠保證可靠性,又能夠保證明時性,這也就是咱們所說的RUDP((Reliable UDP),常見的RUDP協議有QUIC,WebRTC,Aeron等等,我這裏主要介紹谷歌提出的QUIC,帶你們領略一下RUDP的精彩,看看他們是如何既能作到可靠又能保證效率。緩存
QUIC(Quick UDP Internet Connection)是Google公司提出的基於UDP的高效可靠協議,他和HTTP同樣一樣是應用層協議。安全
爲何高效呢?是由於其基於無鏈接的UDP而不是基於TCP去實現的。服務器
爲何可靠呢?由於其模仿TCP協議的可靠性,在應用層上作了可靠性的保證。markdown
互聯網已經發展了幾十年了,可是一提到網絡協議,傳輸層使用得最多的仍是TCP協議,應用層使用得最多的是HTTP協議,固然HTTP底層也是使用得TCP協議。雖然互聯網已經發展這麼久了可是對於TCP來講發展依舊緩慢,要說最大的改進應該是Google 在 ACM CoNEXT
會議上發表的用於改善 Web 應用響應延時TCP Fast Open,經過修改 TCP 協議利用三次握手時進行數據交換,這個在Linux內核 3.7.1 以及更高版本能夠支持。因爲修改TCP協議必然會修改內核從而致使系統升級,這個推進的難度很是之大。網絡
既然咱們修改內核不行,那麼Google就提出了在應用層協議上修改的辦法,也就有了QUIC。數據結構
首先使用它的人確定是谷歌,聽說谷歌有50%的請求都是QUIC協議,微博也在全面使用QUIC協議,同時還有一些視頻雲服務好比七牛也在使用,在騰訊內部也有不少部門在大量使用QUIC,因此不須要擔憂這個協議使用的問題。oop
RTT((Round-Trip Time)顧名思義就是往返時延的意思,0RTT的話意思就是QUIC能夠在第一次發送的時候就帶上數據,熟悉咱們TCP的同窗應該知道,TCP會有一個三次握手那麼實際上也就是會有1次RTT:
若是是HTTPS的話還會使用SSL/TLS的額外握手,就會有3次RTT:
那麼0RTT的創建連接QUIC是怎麼作到的呢?這裏得先說一下QUIC的0RTT並非徹底的0RTT,他一樣須要1RTT去作一次祕鑰協商,在QUIC中使用的是Diffie-Hellman密鑰交換,該算法是一種創建密鑰的方法,並不是加密方法,但其產生的密鑰可用於加密、密鑰管理或任何其它的加密方式,這種密鑰交換技術的目的在於使兩個用戶間能安全地交換密鑰(KEY)以便用於從此的報文加密。DH算法用了離散對數的相關知識,這裏就不擴展講解,有興趣的能夠下來搜索這種算法。QUIC經過DH算法建立一個安全的鏈接後,客戶端會緩存起來原始的鏈接信息等。在後續的過程當中只要和同一個服務器創建連接都是直接發送數據,不須要再次協商祕鑰,從而實現了後續的0RTT。
TCP的擁塞控制的算法特別多,好比基於丟包反饋的(Tahoe、Reno、New Reno、SACK), 基於延時反饋的(Vegas、Westwood),其中的Reno也就是咱們最爲熟悉的,它分爲四個階段:慢啓動,擁塞避免,快速重傳,快速恢復。
而在QUIC中使用了更爲優秀的機制來控制擁塞控制,它能夠針對不一樣業務,不一樣網絡制式,甚至不一樣的RTT,使用不一樣的擁塞控制算法。同時也會採用了packet pacing來探測網絡帶寬,來提高網絡使用率。
在重傳的機制中有一個比較重要的名詞,那就是RTO(Retransmission Timeout) 重傳超時時間,通常這個數據會根據RTT去進行計算,那麼咱們有一個更精確的RTT確定就能夠有一個更好的RTO。
在TCP中重傳的時候序列號不變,會致使咱們的RTT算得不許確,好比重傳的時候你不知道你此次請求究竟是和原始請求匹配仍是和重試請求匹配,就會致使咱們的採樣RTT不許確。
在QUIC中序列號都是遞增的,而且經過offset來肯定在包中的真實位置,這樣就能夠獲得更爲準確的RTT。
在TCP中計算RTT的方法就是發出的時間和響應回來的時間相減,可是這樣算出的時間不許確,在QUIC中會減去服務端Ack Delay的時間,這樣的話就更爲精準。
一樣的在TCP中有個SACK選項,該選項打開時用於記錄傳輸過程當中一些沒有被確認的數據的範圍,便於後續定向重傳多組丟失數據,而不是所有重傳,因此更多的範圍便於更多的選擇重傳,也意味着更少的重傳包頻率。但TCP最多支持3個SACK範圍,而QUIC能支持255個。
熟悉HTTP2.0的同窗應該知道在2.0中若是訪問同一個服務器只會有一個TCP鏈接,全部的請求都會走這條鏈接:
而每一個請求在Connection中叫作Stream,一個Connection中能夠有多個Stream,這裏有個問題是在TCP中的包是保證時序的,若是某個Stream丟了一個包,他同時也會影響其餘的Stream,在更爲嚴重的時候反而多路複用還不如HTTP1.1的多個連接。
而在QUIC中,由於底層是基於UDP,UDP不須要保證包的時序,只會在接收包的時候對包進行重組,因此不會存在這個問題。這也就是爲何Google提議在HTTP3中使用QUIC的緣由。
上面說了QUIC是多路複用的,在QUIC中能夠針對Stream和Connection都進行流量控制。
QUIC 的流量控制和 TCP 有點區別,TCP 爲了保證可靠性,窗口左邊沿向右滑動時的長度取決於已經確認的字節數。若是中間出現丟包,就算接收到了更大序號的 Segment,窗口也沒法超過這個序列號。 但 QUIC 不一樣,就算此前有些 packet 沒有接收到,它的滑動只取決於接收到的最大偏移字節數。
最重要的是咱們能夠進行動態配置,能夠在內存不足或者上游處理性能出現問題時,經過流量控制來限制傳輸速率,保障服務可用性。
如今在手機上移動流量和wifi的切換是一個比較常見的事,每次切換ip地址都會發生變化,若是是TCP的話鏈接就會中斷從而進行從新創建連接。
在QUIC再也不以 IP 及端口四元組標識,而是以一個 64 位的隨機數做爲 ID 來標識,經過這樣的方式能夠進行鏈接重複利用,不會從新創建新的鏈接。
在QUIC中還有更多的其餘的特性,好比:
這裏就不詳解介紹了,你們能夠自行查閱資料搜索。
其實這篇帖子也算是一個掃盲貼,相信有不少朋友沒有據說過RUDP相關的一些東西,或者說據說過可是一直覺得他是一個很複雜,很難理解的東西,其實在這裏攤開來說RUDP就是一個UDP+應用層可靠協議組成的,但願你們看完這篇文章後,能有所收穫。
若是你們以爲這篇文章對你有幫助,你的關注和轉發是對我最大的支持,O(∩_∩)O: