天天看點

Java工程師 計算機網絡(四) 面試題(Day31)

1 介紹一下HTTPS的流程。

參考回答

HTTPS在傳輸的過程中會涉及到三個密鑰:伺服器端的公鑰和私鑰,用來進行非對稱加密;用戶端生成的随機密鑰,用來進行對稱加密。一個HTTPS請求實際上包含了兩次HTTP傳輸,如下圖可以細分為以下8步:

Java工程師 計算機網絡(四) 面試題(Day31)

用戶端向伺服器發起HTTPS請求,連接配接到伺服器的443端口

伺服器端有一個密鑰對,即公鑰和私鑰,是用來進行非對稱加密使用的,伺服器端儲存着私鑰,不能将其洩露,公鑰可以發送給任何人。

伺服器将自己的公鑰發送給用戶端。

用戶端收到伺服器端的公鑰之後,會對公鑰進行檢查,驗證其合法性,如果發現發現公鑰有問題,那麼HTTPS傳輸就無法繼續。嚴格的說,這裡應該是驗證伺服器發送的數字證書的合法性,關于用戶端如何驗證數字證書的合法性,下文會進行說明。如果公鑰合格,那麼用戶端會生成一個随機值,這個随機值就是用于進行對稱加密的密鑰,我們将該密鑰稱之為client key,即用戶端密鑰,這樣在概念上和伺服器端的密鑰容易進行區分。然後用伺服器的公鑰對用戶端密鑰進行非對稱加密,這樣用戶端密鑰就變成密文了,至此,HTTPS中的第一次HTTP請求結束。

用戶端會發起HTTPS中的第二個HTTP請求,将加密之後的用戶端密鑰發送給伺服器。

伺服器接收到用戶端發來的密文之後,會用自己的私鑰對其進行非對稱解密,解密之後的明文就是用戶端密鑰,然後用用戶端密鑰對資料進行對稱加密,這樣資料就變成了密文。

然後伺服器将加密後的密文發送給用戶端。

用戶端收到伺服器發送來的密文,用用戶端密鑰對其進行對稱解密,得到伺服器發送的資料。這樣HTTPS中的第二個HTTP請求結束,整個HTTPS傳輸完成。

2 介紹一下HTTP的失敗碼。

參考回答

HTTP的錯誤碼包含用戶端錯誤4XX 和服務端錯誤5XX ,兩種錯誤分别如下:

用戶端錯誤 4XX

這類的狀态碼是适用于用戶端似乎有錯誤的情況。除了響應給HEAD請求外,伺服器應該包含一個包括錯誤情況描述的實體,和它是暫時的還是永久性的。這些狀态碼适用于任何請求方法。使用者代理應該展示所有包含的實體給使用者。

如果用戶端正在發送資料,使用TCP的伺服器應該在伺服器關閉輸對外連結接時,仔細確定用戶端确認收到包含響應的資料包(receipt of the packet(s) ) 。如果用戶端繼續在伺服器關閉後發送資料,伺服器的TCP棧将會發生一個重置包給用戶端,這可能會在 HTTP 應用程式讀取和解釋用戶端的未确認輸入緩沖區(input buffers)之前将其擦除。

400(錯誤請求) 伺服器不了解請求的文法。

401(未授權) 請求要求進行身份驗證。登入後,伺服器可能會傳回對頁面的此響應。

403(已禁止) 伺服器拒絕請求。如果在 Googlebot 嘗試抓取您網站上的有效網頁時顯示此狀态代碼(您可在 Google 網站管理者工具中診斷下的網絡抓取頁面上看到此狀态代碼),那麼,這可能是您的伺服器或主機拒絕 Googlebot 對其進行通路。

404(未找到) 伺服器找不到請求的網頁。例如,如果請求是針對伺服器上不存在的網頁進行的,那麼,伺服器通常會傳回此代碼。

如果您的網站上沒有 robots.txt 檔案,而您在 Google 網站管理者工具”診斷”标簽的 robots.txt 頁上發現此狀态,那麼,這是正确的狀态。然而,如果您有 robots.txt 檔案而又發現了此狀态,那麼,這說明您的 robots.txt 檔案可能是命名錯誤或位于錯誤的位置。(該檔案應當位于頂級域名上,且應當名為 robots.txt)。

如果您在 Googlebot 嘗試抓取的網址上發現此狀态(位于”診斷”标簽的 HTTP 錯誤頁上),那麼,這表示 Googlebot 所追蹤的可能是另一網頁中的無效連結(舊連結或輸入有誤的連結)。

405(方法禁用) 禁用請求中所指定的方法。

406(不接受) 無法使用請求的内容特性來響應請求的網頁。

407(需要代理授權) 此狀态代碼與 401(未授權)類似,但卻指定了請求者應當使用代理進行授權。如果伺服器傳回此響應,那麼,伺服器還會指明請求者應當使用的代理。

408(請求逾時) 伺服器等候請求時逾時。

409(沖突) 伺服器在完成請求時發生沖突。伺服器必須包含有關響應中所發生的沖突的資訊。伺服器在響應與前一個請求相沖突的 PUT 請求時可能會傳回此代碼,同時會提供兩個請求的差異清單。

410(已删除) 如果請求的資源已被永久删除,那麼,伺服器會傳回此響應。該代碼與 404(未找到)代碼類似,但在資源以前有但現在已經不複存在的情況下,有時會替代 404 代碼出現。如果資源已被永久删除,那麼,您應當使用 301 代碼指定該資源的新位置。

411(需要有效長度) 伺服器不會接受包含無效内容長度标頭字段的請求。

412(未滿足前提條件) 伺服器未滿足請求者在請求中設定的其中一個前提條件。

413(請求實體過大) 伺服器無法處理請求,因為請求實體過大,已超出伺服器的處理能力。

414(請求的 URI 過長) 請求的 URI(通常為網址)過長,伺服器無法進行處理。

415(不支援的媒體類型) 請求的格式不受請求頁面的支援。

416(請求範圍不符合要求) 如果請求是針對網頁的無效範圍進行的,那麼,伺服器會傳回此狀态代碼。

417(未滿足期望值) 伺服器未滿足”期望”請求标頭字段的要求。

服務端錯誤 5XX

響應狀态碼已數字5開頭,表明了這類伺服器知道其錯誤或者無法執行請求的情況。出了響應HEAD請求外,伺服器應該包括一個包含錯誤情況說明的實體,以及他是暫時地還是永久性的,使用者代理應該将所有包含的實體展示給使用者。這些響應代碼适用于任何請求方法。

500(伺服器内部錯誤) 伺服器遇到錯誤,無法完成請求。

501(尚未實施) 伺服器不具備完成請求的功能。例如,當伺服器無法識别請求方法時,伺服器可能會傳回此代碼。

502(錯誤網關) 伺服器作為網關或代理,從上遊伺服器收到了無效的響應。

503(服務不可用) 目前無法使用伺服器(由于超載或進行停機維護)。通常,這隻是一種暫時的狀态。

504(網關逾時) 伺服器作為網關或代理,未及時從上遊伺服器接收請求。

505(HTTP 版本不受支援) 伺服器不支援請求中所使用的 HTTP 協定版本。

3 說一說你知道的http狀态碼。

參考回答

HTTP狀态碼由三個十進制數字組成,第一個十進制數字定義了狀态碼的類型,後兩個數字沒有分類的作用。HTTP狀态碼共分為5種類型,分類及分類描述如下表:

Java工程師 計算機網絡(四) 面試題(Day31)

各類别常見狀态碼有如下幾種:

2xx (3種)

200 OK:表示從用戶端發送給伺服器的請求被正常處理并傳回;

204 No Content:表示用戶端發送給用戶端的請求得到了成功處理,但在傳回的響應封包中不含實體的主體部分(沒有資源可以傳回);

206 Patial Content:表示用戶端進行了範圍請求,并且伺服器成功執行了這部分的GET請求,響應封包中包含由Content-Range指定範圍的實體内容。

3xx (5種)

301 Moved Permanently:永久性重定向,表示請求的資源被配置設定了新的URL,之後應使用更改的URL;

302 Found:臨時性重定向,表示請求的資源被配置設定了新的URL,希望本次通路使用新的URL;

301與302的差別:前者是永久移動,後者是臨時移動(之後可能還會更改URL)

303 See Other:表示請求的資源被配置設定了新的URL,應使用GET方法定向擷取請求的資源;

302與303的差別:後者明确表示用戶端應當采用GET方式擷取資源

304 Not Modified:表示用戶端發送附帶條件(是指采用GET方法的請求封包中包含if-Match、If-Modified-Since、If-None-Match、If-Range、If-Unmodified-Since中任一首部)的請求時,伺服器端允許通路資源,但是請求為滿足條件的情況下傳回該狀态碼;

307 Temporary Redirect:臨時重定向,與303有着相同的含義,307會遵照浏覽器标準不會從POST變成GET;(不同浏覽器可能會出現不同的情況);

4xx (4種)

400 Bad Request:表示請求封包中存在文法錯誤;

401 Unauthorized:未經許可,需要通過HTTP認證;

403 Forbidden:伺服器拒絕該次通路(通路權限出現問題)

404 Not Found:表示伺服器上無法找到請求的資源,除此之外,也可以在伺服器拒絕請求但不想給拒絕原因時使用;

5xx (2種)

500 Inter Server Error:表示伺服器在執行請求時發生了錯誤,也有可能是web應用存在的bug或某些臨時的錯誤時;

503 Server Unavailable:表示伺服器暫時處于超負載或正在進行停機維護,無法處理請求;

4 301和302有什麼差別?

參考回答

301和302的差別在于,301重定向是永久的重定向,搜尋引擎在抓取新内容的同時也将舊的網址交換為重定向之後的網址。302重定向是暫時的重定向,搜尋引擎會抓取新的内容而儲存舊的網址。由于效勞器前往302代碼,搜尋引擎以為新的網址隻是暫時的。

5 302和304有什麼差別?

參考回答

302和304是網頁請求的兩個不同的響應狀态碼。302 (臨時移動)表示 伺服器目前從不同位置的網頁響應請求,但請求者應繼續使用原有位置來進行以後的請求。 304 (未修改)表示 自從上次請求後,請求的網頁未修改過。 伺服器傳回此響應時,不會傳回網頁内容。

6 請描述一次完整的HTTP請求的過程。

參考回答

Java工程師 計算機網絡(四) 面試題(Day31)

DNS解析流程圖

首先用戶端位置是一台電腦或手機,在打開浏覽器以後,比如輸入http://www.zdns.cn的域名,它首先是由浏覽器發起一個DNS解析請求,如果本地緩存伺服器中找不到結果,則首先會向根伺服器查詢,根伺服器裡面記錄的都是各個頂級域所在的伺服器的位置,當向根伺服器請求http://www.zdns.cn的時候,根伺服器就會傳回.cn伺服器的位置資訊;

遞歸伺服器拿到.cn的權威伺服器位址以後,就會尋問.cn的權威伺服器,知不知道http://www.zdns.cn的位置。這個時候.cn權威伺服器查找并傳回http://zdns.cn伺服器的位址;

繼續向http://zdns.cn的權威伺服器去查詢這個位址,由http://zdns.cn的伺服器給出了位址:202.173.11.10;

最終進入http的連結,順利通路網站;

補充說明:一旦遞歸伺服器拿到解析記錄以後,就會在本地進行緩存,如果下次用戶端再請求本地的遞歸域名伺服器相同域名的時候,就不會再這樣一層一層查了,因為本地伺服器裡面已經有緩存了,這個時候就直接把http://www.zdns.cn的記錄傳回給用戶端就可以了。

7 什麼是重定向?

參考回答

重定向(Redirect)就是通過各種方法将各種網絡請求重新定個方向轉到其它位置(如:網頁重定向、域名的重定向、路由選擇的變化也是對資料封包經由路徑的一種重定向)。

答案解析

需要重定向的情況

(1)網站調整(如改變網頁目錄結構);

(2)網頁被移到一個新位址;

(3)網頁擴充名改變(如應用需要把.php改成.Html或.shtml)。

這幾種情況下,如果不做重定向,則使用者收藏夾或搜尋引擎資料庫中舊位址隻能讓通路客戶得到一個404 頁面錯誤資訊,通路流量白白喪失;再者某些注冊了多個域名的網站,也需要通過重定向讓通路這些域名的使用者自動跳轉到主站點等。

常用的重定向的方式

(1)301 redirect-----永久性轉移

當使用者或搜尋引擎向網站伺服器發出浏覽請求時,伺服器傳回的HTTP資料流中頭資訊(header)中的狀态碼的一種,表示本網頁永久性轉移到另一個位址。

(2)302 redirect-----暫時性轉移 (Temporarily Moved )

也被認為是暫時重定向(temporary redirect),一條對網站浏覽器的指令來顯示浏覽器被要求顯示的不同的URL,當一個網頁經曆過短期的URL的變化時使用。一個暫時重定向是一種伺服器端的重定向,能夠被搜尋引擎蜘蛛正确地處理。

新舊重定向方式的差別

302重定向是暫時的重定向,搜尋引擎會抓取新的内容而儲存舊的網址。由于效勞器前往302代碼,搜尋引擎以為新的網址隻是暫時的;

301重定向是永久的重定向,搜尋引擎在抓取新内容的同時也将舊的網址交換為重定向之後的網址。

為什麼302 重定向和網址劫持有關聯

從網址A 做一個302 重定向到網址B 時,主機伺服器的隐含意思是網址A 随時有可能改主意,重新顯示本身的内容或轉向其他的地方。大部分的搜尋引擎在大部分情況下,當收到302 重定向時,一般隻要去抓取目标網址就可以了,也就是說網址B。如果搜尋引擎在遇到302 轉向時,百分之百的都抓取目标網址B 的話,就不用擔心網址URL 劫持了。問題就在于,有的時候搜尋引擎,尤其是Google,并不能總是抓取目标網址。

比如說,有的時候A 網址很短,但是它做了一個302 重定向到B 網址,而B 網址是一個很長的亂七八糟的URL 網址,甚至還有可能包含一些問号之類的參數。很自然的,A 網址更加使用者友好,而B 網址既難看,又不使用者友好。這時Google 很有可能會仍然顯示網址A。由于搜尋引擎排名算法隻是程式而不是人,在遇到302 重定向的時候,并不能像人一樣的去準确判定哪一個網址更适當,這就造成了網址URL 劫持的可能性。也就是說,一個不道德的人在他自己的網址A 做一個302 重定向到你的網址B,出于某種原因, Google 搜尋結果所顯示的仍然是網址A,但是所用的網頁内容卻是你的網址B 上的内容,這種情況就叫做網址URL 劫持。你辛辛苦苦所寫的内容就這樣被别人偷走了。

302 重定向所造成的網址URL 劫持現象,已經存在一段時間了。不過到目前為止,似乎也沒有什麼更好的解決方法。在正在進行的資料中心轉換中,302 重定向問題也是要被解決的目标之一。從一些搜尋結果來看,網址劫持現象有所改善,但是并沒有完全解決。

8 重定向和請求轉發有什麼差別?

參考回答

請求轉發

客戶首先發送一個請求到伺服器端,伺服器端發現比對的servlet,并指定它去執行,當這個servlet執行完之後,它要調用getRequestDispacther()方法,把請求轉發給指定的student_list.jsp,整個流程都是在伺服器端完成的,而且是在同一個請求裡面完成的,是以servlet和jsp共享的是同一個request,在servlet裡面放的所有東西,在student_list中都能取出來,是以,student_list能把結果getAttribute()出來,getAttribute()出來後執行完把結果傳回給用戶端。整個過程是一個請求,一個響應。

重定向

客戶發送一個請求到伺服器,伺服器比對servlet,servlet處理完之後調用了sendRedirect()方法,立即向用戶端傳回這個響應,響應行告訴用戶端你必須要再發送一個請求,去通路student_list.jsp,緊接着用戶端收到這個請求後,立刻發出一個新的請求,去請求student_list.jsp,這裡兩個請求互不幹擾,互相獨立,在前面request裡面setAttribute()的任何東西,在後面的request裡面都獲得不了。可見,在sendRedirect()裡面是兩個請求,兩個響應。(伺服器向浏覽器發送一個302狀态碼以及一個location消息頭,浏覽器收到請求後會向再次根據重定向位址送出請求)

二者差別

(1)請求次數:重定向是浏覽器向伺服器發送一個請求并收到響應後再次向一個新位址送出請求,轉發是伺服器收到請求後為了完成響應跳轉到一個新的位址;重定向至少請求兩次,轉發請求一次;

(2)位址欄不同:重定向位址欄會發生變化,轉發位址欄不會發生變化;

(3)是否共享資料:重定向兩次請求不共享資料,轉發一次請求共享資料(在request級别使用資訊共享,使用重定向必然出錯);

(4)跳轉限制:重定向可以跳轉到任意URL,轉發隻能跳轉本站點資源;

(5)發生行為不同:重定向是用戶端行為,轉發是伺服器端行為。

9 介紹一下DNS尋址的過程。

參考回答

Java工程師 計算機網絡(四) 面試題(Day31)

DNS解析流程圖

首先用戶端位置是一台電腦或手機,在打開浏覽器以後,比如輸入http://www.zdns.cn的域名,它首先是由浏覽器發起一個DNS解析請求,如果本地緩存伺服器中找不到結果,則首先會向根伺服器查詢,根伺服器裡面記錄的都是各個頂級域所在的伺服器的位置,當向根伺服器請求http://www.zdns.cn的時候,根伺服器就會傳回.cn伺服器的位置資訊;

遞歸伺服器拿到.cn的權威伺服器位址以後,就會尋問.cn的權威伺服器,知不知道http://www.zdns.cn的位置。這個時候.cn權威伺服器查找并傳回http://zdns.cn伺服器的位址;

繼續向http://zdns.cn的權威伺服器去查詢這個位址,由http://zdns.cn的伺服器給出了位址:202.173.11.10;

最終進入http的連結,順利通路網站;

補充說明:一旦遞歸伺服器拿到解析記錄以後,就會在本地進行緩存,如果下次用戶端再請求本地的遞歸域名伺服器相同域名的時候,就不會再這樣一層一層查了,因為本地伺服器裡面已經有緩存了,這個時候就直接把http://www.zdns.cn的記錄傳回給用戶端就可以了。

答案解析

什麼是DNS

DNS就是域名系統,是網際網路中的一項核心服務,是用于實作域名和IP位址互相映射的一個分布式資料庫,能夠使使用者更友善的通路網際網路,而不用去記住能夠被機器直接讀取的IP數串。通過主機名,得到該主機名對應的IP位址的過程叫做域名解析(或主機名解析)。

域名解析結構

Java工程師 計算機網絡(四) 面試題(Day31)

如上圖所示,域名結構是樹狀結構,樹的最頂端代表根伺服器,根的下一層就是由我們所熟知的.com、.net、.cn等通用域和.cn、.uk等國家域組成,稱為頂級域。網上注冊的域名基本都是二級域名,比如http://baidu.com、http://taobao.com等等二級域名,它們基本上是歸企業和運維人員管理。接下來是三級或者四級域名,這裡不多贅述。總體概括來說域名是由整體到局部的機制結構。

10 說一說你對TIME_WAIT的了解。

參考回答

出現 TIME_WAIT的狀态原因

TIME_WAIT狀态之是以存在,是為了保證網絡的可靠性。由于TCP連接配接是雙向的,是以在關閉連接配接的時候,兩個方向各自都需要關閉。先發FIN包的一方執行的是主動關閉,後發送FIN包的一方執行的是被動關閉。主動關閉的一方會進入TIME_WAIT狀态,并且在此狀态停留2MSL時長。如果Server端一直沒有向client端發送FIN消息(調用close() API),那麼這個CLOSE_WAIT會一直存在下去。

MSL概念

其指的是封包段的最大生存時間。如果封包段在網絡中活動了MSL時間,還沒有被接收,那麼就會被丢棄。關于MSL的大小,RFC 793協定中給出的建議是2分鐘,不過Linux中,通常是半分鐘。

TIME_WAIT持續兩個MSL的作用

首先,可靠安全地關閉TCP連接配接。比如網絡擁塞,如果主動關閉方最後一個ACK沒有被被動關閉方接收到,這時被動關閉方會對FIN進行逾時重傳,在這時尚未關閉的TIME_WAIT就會把這些尾巴問題處理掉,不至于對新連接配接及其他服務産生影響。其次,防止由于沒有持續TIME_WAIT時間導緻的新的TCP連接配接建立起來,延遲的FIN重傳包會幹擾新的連接配接。

TIME_WAIT占用的資源

少量記憶體(大概4K)和一個檔案描述符fd。

TIME_WAIT關閉的危害

首先,當網絡情況不好時,如果主動方無TIME_WAIT等待,關閉前個連接配接後,主動方與被動方又建立起新的TCP連接配接,這時被動方重傳或延時過來的FIN包到達後會直接影響新的TCP連接配接;其次,當網絡情況不好時,同時沒有TIME_WAIT等待時,關閉連接配接後無新連接配接,那麼當接收到被動方重傳或延遲的FIN包後,會給被動方回送一個RST包,可能會影響被動方其他的服務連接配接。

答案解析

Java工程師 計算機網絡(四) 面試題(Day31)

當client端傳輸完成資料,或者需要斷開連接配接時:

Client端發送一個FIN封包給Server端。表示要終止Client到Server這個方向的連接配接。通過調用close(socket) API。表示Client不再會發送資料到Server端。(但Server還能繼續發給Client端)。Client狀态變為FIN_WAIT_1。

Server端收到FIN後,發送一個ACK封包給Client端(序号為M+1)。Server狀态變為CLOSE_WAIT,Client收到序号為(M+1)的ACK後狀态變為FIN_WAIT_2。Server端也發送一個FIN封包給Client端。(序号為N) 表示Server也要終止到Client端這個方向的連接配接。通過調用close(socket) API。Server端狀态變為LAST_ACK。

Client端收到封包FIN後,也發送一個ACK封包給伺服器。(序号N+1),Client狀态變為TIME_WAIT。

Server端收到序号為(N+1)的ACK, Server的狀态變為CLOSED。

等帶2MSL之後,Client的狀态也變為CLOSE。

至此,一個完整的TCP連接配接就關閉了。

11 TIME_WAIT、CLOSE_WAIT狀态發生在哪一步?

參考回答

TIME_WAIT狀态發生在用戶端主動關閉連接配接時,發送最後一個ack後;CLOSE_WAIT狀态發生在在Sever端收到Client的FIN消息之後。

出現 TIME_WAIT的狀态原因

TIME_WAIT狀态之是以存在,是為了保證網絡的可靠性。由于TCP連接配接是雙向的,是以在關閉連接配接的時候,兩個方向各自都需要關閉。先發FIN包的一方執行的是主動關閉,後發送FIN包的一方執行的是被動關閉。主動關閉的一方會進入TIME_WAIT狀态,并且在此狀态停留2MSL時長。如果Server端一直沒有向client端發送FIN消息(調用close() API),那麼這個CLOSE_WAIT會一直存在下去。

出現CLOSE_WAIT的狀态原因

假設最終的ACK丢失,server将重發FIN,client必須維護TCP狀态資訊以便可以重發最終的ACK,否則會發送RST,結果server認為發生錯誤。TCP實作必須可靠地終止連接配接的兩個方向(全雙工關閉),client必須進入 TIME_WAIT 狀态,因為client可能面臨重發最終ACK的情形。

為什麼 TIME_WAIT 狀态需要保持 2MSL 這麼長的時間?

如果 TIME_WAIT 狀态保持時間不足夠長(比如小于2MSL),第一個連接配接就正常終止了。第二個擁有相同相關五元組的連接配接出現,而第一個連接配接的重複封包到達,幹擾了第二個連接配接。TCP實作必須防止某個連接配接的重複封包在連接配接終止後出現,是以讓TIME_WAIT狀态保持時間足夠長(2MSL),連接配接相應方向上的TCP封包要麼完全響應完畢,要麼被丢棄。建立第二個連接配接的時候,不會混淆。

答案解析

Java工程師 計算機網絡(四) 面試題(Day31)

當client端傳輸完成資料,或者需要斷開連接配接時:

Client端發送一個FIN封包給Server端。表示要終止Client到Server這個方向的連接配接。通過調用close(socket) API。表示Client不再會發送資料到Server端。(但Server還能繼續發給Client端)。Client狀态變為FIN_WAIT_1。

Server端收到FIN後,發送一個ACK封包給Client端(序号為M+1)。Server狀态變為CLOSE_WAIT,Client收到序号為(M+1)的ACK後狀态變為FIN_WAIT_2。Server端也發送一個FIN封包給Client端。(序号為N) 表示Server也要終止到Client端這個方向的連接配接。通過調用close(socket) API。Server端狀态變為LAST_ACK。

Client端收到封包FIN後,也發送一個ACK封包給伺服器。(序号N+1),Client狀态變為TIME_WAIT。

Server端收到序号為(N+1)的ACK, Server的狀态變為CLOSED。

等帶2MSL之後,Client的狀态也變為CLOSE。

至此,一個完整的TCP連接配接就關閉了。

12 有大量的TIME_WAIT狀态怎麼辦?

參考回答

time_wait 狀态的影響

TCP 連接配接中,主動發起關閉連接配接的一端,會進入 time_wait 狀态,time_wait 狀态,預設會持續 2 MSL(封包的最大生存時間),一般是 2x2 mins,time_wait 狀态下,TCP 連接配接占用的端口,無法被再次使用,TCP 端口數量,上限是 6.5w(65535,16 bit),大量 time_wait 狀态存在,會導緻建立 TCP 連接配接會出錯,address already in use : connect異常。

解決辦法

(1)用戶端:HTTP 請求的頭部,connection 設定為 keep-alive,保持存活一段時間:現在的浏覽器,一般都這麼進行了 。

(2)伺服器端

a. 允許 time_wait狀态的 socket 被重用

b. 縮減 time_wait 時間,設定為 1 MSL(即,2 mins)

13 請介紹socket通信的具體步驟。

參考回答

sockets(套接字)程式設計有三種:流式套接字(SOCK_STREAM),資料報套接字(SOCK_DGRAM),原始套接字(SOCK_RAW);基于TCP的socket程式設計是采用的流式套接字。

伺服器端程式設計的步驟

(1)加載套接字庫,建立套接字(WSAStartup()/socket());

(2)綁定套接字到一個IP位址和一個端口上(bind());

(3)将套接字設定為監聽模式等待連接配接請求(listen());

(4)請求到來後,接受連接配接請求,傳回一個新的對應于此次連接配接的套接字(accept());

(5)用傳回的套接字和用戶端進行通信(send()/recv());

(6)傳回,等待另一連接配接請求;

(7)關閉套接字,關閉加載的套接字庫(closesocket()/WSACleanup())。

用戶端程式設計的步驟:

(1)加載套接字庫,建立套接字(WSAStartup()/socket());

(2)向伺服器發出連接配接請求(connect());

(3)和伺服器端進行通信(send()/recv());

(4)關閉套接字,關閉加載的套接字庫(closesocket()/WSACleanup())。

答案解析

//代碼執行個體(伺服器) 
#include <stdio.h> 
#include <Winsock2.h> 
void main() {  
WORD wVersionRequested;  
WSADATA wsaData;  int err;     wVersionRequested = MAKEWORD( 1, 1 );     
err = WSAStartup( wVersionRequested, &wsaData );  
if ( err != 0 ) {   return;  }     
if ( LOBYTE( wsaData.wVersion ) != 1 ||         HIBYTE( wsaData.wVersion ) != 1 ) {   WSACleanup( );   
return;  
}  SOCKET sockSrv=socket(AF_INET,SOCK_STREAM,0);    SOCKADDR_IN addrSrv;  addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY);  addrSrv.sin_family=AF_INET;  addrSrv.sin_port=htons(6000);     
bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));    listen(sockSrv,5);    
SOCKADDR_IN addrClient;  int len=sizeof(SOCKADDR);  while(1)  {   SOCKET sockConn=accept(sockSrv,(SOCKADDR*)&addrClient,&len);   
char sendBuf[50];   sprintf(sendBuf,"Welcome %s to here!",inet_ntoa(addrClient.sin_addr));   send(sockConn,sendBuf,strlen(sendBuf)+1,0);   char recvBuf[50];   recv(sockConn,recvBuf,50,0);   printf("%s\n",recvBuf);   closesocket(sockConn);  }   }
           
//代碼執行個體(用戶端) 
#include <stdio.h> 
#include <Winsock2.h> void main() {  
WORD wVersionRequested;  
WSADATA wsaData;  
int err;    
wVersionRequested = MAKEWORD( 1, 1 );    
err = WSAStartup( wVersionRequested, &wsaData );  
if ( err != 0 ) {   return; 
 }    
 if ( LOBYTE( wsaData.wVersion ) != 1 ||         HIBYTE( wsaData.wVersion ) != 1 ) {   WSACleanup( );   
 return;  }  
 SOCKET sockClient=socket(AF_INET,SOCK_STREAM,0); 
    SOCKADDR_IN addrSrv;  addrSrv.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");  addrSrv.sin_family=AF_INET;
      addrSrv.sin_port=htons(6000);  connect(sockClient,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR)); 
       send(sockClient,"hello",strlen("hello")+1,0);  char recvBuf[50];  
       recv(sockClient,recvBuf,50,0);  printf("%s\n",recvBuf);   
        closesocket(sockClient);  WSACleanup(); }
           

14 服務端怎麼提高處理socket連接配接的性能?

參考回答

提高處理socket連接配接的性能,請遵循以下技巧:

最小化封包傳輸的延時。

最小化系統調用的負載。

為 Bandwidth Delay Product 調節 TCP 視窗。

動态優化 GNU/Linux TCP/IP 棧。

答案解析

最小化封包傳輸的延時。

在通過 TCP socket 進行通信時,資料都拆分成了資料塊,這樣它們就可以封裝到給定連接配接的 TCP payload(指 TCP 資料包中的有效負荷)中了。TCP payload 的大小取決于幾個因素(例如最大封包長度和路徑),但是這些因素在連接配接發起時都是已知的。為了達到最好的性能,我們的目标是使用盡可能多的可用資料來填充每個封包。當沒有足夠的資料來填充 payload 時(也稱為最大封包段長度(maximum segment size)或 MSS),TCP 就會采用 Nagle 算法自動将一些小的緩沖區連接配接到一個封包段中。這樣可以通過最小化所發送的封包的數量來提高應用程式的效率,并減輕整體的網絡擁塞問題。

最小化系統調用的負載。

任何時候通過一個 socket 來讀寫資料時,都是在使用一個系統調用(system call)。這個調用(例如 read 或 write)跨越了使用者空間應用程式與核心的邊界。另外,在進入核心之前,該調用會通過 C 庫來進入核心中的一個通用函數(system_call())。從 system_call()中,這個調用會進入檔案系統層,核心會在這兒确定正在處理的是哪種類型的裝置。最後,調用會進入 socket 層,資料就是在這裡進行讀取或進行排隊進而通過 socket 進行傳輸的(這涉及資料的副本)。

這個過程說明系統調用不僅僅是在應用程式和核心中進行操作的,而且還要經過應用程式和核心中的很多層次。這個過程耗費的資源很高,是以調用次數越多,通過這個調用鍊進行的工作所需要的時間就越長,應用程式的性能也就越低。由于我們無法避免這些系統調用,是以唯一的選擇是最小化使用這些調用的次數。

為 Bandwidth Delay Product 調節 TCP 視窗。

TCP 的性能取決于幾個方面的因素。兩個最重要的因素是連結帶寬(link bandwidth)(封包在網絡上傳輸的速率)和 往返時間(round-trip time) 或 RTT(發送封包與接收到另一端的響應之間的延時)。這兩個值确定了稱為 Bandwidth Delay Product(BDP)的内容。

給定連結帶寬和 RTT 之後,就可以計算出 BDP 的值了,不過這代表什麼意義呢?BDP 給出了一種簡單的方法來計算理論上最優的 TCP socket 緩沖區大小(其中儲存了排隊等待傳輸和等待應用程式接收的資料)。如果緩沖區太小,那麼 TCP 視窗就不能完全打開,這會對性能造成限制。如果緩沖區太大,那麼寶貴的記憶體資源就會造成浪費。如果設定的緩沖區大小正好合适,那麼就可以完全利用可用的帶寬。

動态優化 GNU/Linux TCP/IP 棧。

标準的 GNU/Linux 發行版試圖對各種部署情況都進行優化。這意味着标準的發行版可能并沒有對現有的環境進行特殊的優化。GNU/Linux 提供了很多可調節的核心參數,可以使用這些參數為自己的作業系統進行動态配置。

15 介紹一下流量控制和擁塞控制。

參考回答

流量控制和擁塞控制定義

流量控制

如果發送方把資料發送得過快,接收方可能會來不及接收,這就會造成資料的丢失。流量控制就是讓發送方慢點,要讓接收方來得及接收。

擁塞控制

擁塞控制就是防止過多的資料注入到網絡中,這樣可以使網絡中的路由器或鍊路不緻過載。

流量控制和擁塞控制差別

流量控制是端到端的控制,例如A通過網絡給B發資料,A發送的太快導緻B沒法接收(B緩沖視窗過小或者處理過慢),這時候的控制就是流量控制,原理是通過滑動視窗的大小改變來實作。

擁塞控制是A與B之間的網絡發生堵塞導緻傳輸過慢或者丢包,來不及傳輸。防止過多的資料注入到網絡中,這樣可以使網絡中的路由器或鍊路不至于過載。擁塞控制是一個全局性的過程,涉及到所有的主機、路由器,以及與降低網絡性能有關的所有因素。

TCP流量控制解決方法

TCP的流量控制是利用滑動視窗機制實作的,接收方在傳回的資料中會包含自己的接收視窗的大小,以控制發送方的資料發送。

TCP擁塞控制解決方法

TCP擁塞控制的四種算法:慢開始、擁塞避免、快重傳、快恢複。

(1)慢開始算法:當主機開始發送資料時,并不清楚網絡的負載情況,是以由小到大逐漸增大擁塞視窗,每經過一個傳輸輪次沒有出現逾時就将擁塞視窗加倍。同時還需要設定一個慢開始門限,在擁塞視窗小于慢開始門限時使用慢開始算法,大于慢開始門限時,使用擁塞避免算法;

(2)擁塞避免算法:在擁塞視窗大于慢開始門限時,讓擁塞視窗按線性規律緩慢增長。即每經過一個傳輸輪次,擁塞視窗增大一個MSS最大封包段尺寸。(擁塞避免并非完全能夠避免擁塞,隻是使網絡比較不容易出現擁塞)

(3)快重傳算法:使發送方今早知道發生了個别封包段丢失,并不是出現網絡擁塞。

要求接受不要登塞自己發送資料時才進行捎帶确認,而是立即發送确認,即使收到了失序的封包段也要立即發出對已收到封包段的重複确認。而發送方一旦受到三個連續的重讀确認,就将相應的封包段立即重傳。

(4)快恢複算法:發送方知道隻有個别封包段丢失而不是網絡擁塞時,不啟動慢開始算法,而是執行快恢複算法,将慢開始門限和擁塞視窗值調整為目前視窗的一半,開始執行擁塞避免算法

16 對路由協定是否有所了解?

參考回答

有了解。

路由協定定義

路由協定(英語:Routing protocol)是一種指定資料包轉送方式的網上協定。Internet網絡的主要節點裝置是路由器,路由器通過路由表來轉發接收到的資料。轉發政策可以是人工指定的(通過靜态路由、政策路由等方法)。在具有較小規模的網絡中,人工指定轉發政策沒有任何問題。但是在具有較大規模的網絡中(如跨國企業網絡、ISP網絡),如果通過人工指定轉發政策,将會給網絡管理者帶來巨大的工作量,并且在管理、維護路由表上也變得十分困難。為了解決這個問題,動态路由協定應運而生。動态路由協定可以讓路由器自動學習到其他路由器的網絡,并且網絡拓撲發生改變後自動更新路由表。網絡管理者隻需要配置動态路由協定即可,相比人工指定轉發政策,工作量大大減少。

原理

路由協定通過在路由器之間共享路由資訊來支援可路由協定。路由資訊在相鄰路由器之間傳遞,確定所有路由器知道到其它路由器的路徑。總之,路由協定建立了路由表,描述了網絡拓撲結構;路由協定與路由器,執行路由選擇和資料包轉發功能。

路由器的作用以及常見的路由協定

路由協定主要運作于路由器上,路由協定是用來确定到達路徑的,起到一個地圖導航,負責找路的作用。它工作在網絡層。它包括RIP,IGRP(Cisco私有協定),EIGRP(Cisco私有協定),OSPF,IS-IS,BGP。以下為這六個協定的詳細說明:

(1)RIP(路由資訊協定)

RIP很早就被用在Internet上,是最簡單的路由協定。它是“路由資訊協定(Route Information Protocol)”的簡寫,主要傳遞路由資訊,通過每隔30秒廣播一次路由表,維護相鄰路由器的位置關系,同時根據收到的路由表資訊計算自己的路由表資訊。RIP是一個距離矢量路由協定,最大跳數為15跳,超過15跳的網絡則認為目标網絡不可達。此協定通常用在網絡架構較為簡單的小型網絡環境。分為RIPv1和RIPv2兩個版本,後者支援VLSM技術以及一系列技術上的改進。RIP的收斂速度較慢。

(2)IGRP(内部網關路由協定)

IGRP協定是“内部網關路由協定(Interior Gateway Routing Protocol)”的縮寫,由Cisco于二十世紀八十年代獨立開發,屬于Cisco私有協定。IGRP和RIP一樣,同屬距離矢量路由協定,是以在諸多方面有着相似點,如IGRP也是周期性的廣播路由表,也存在最大跳數(預設為100跳,達到或超過100跳則認為目标網絡不可達)。IGRP最大的特點是使用了混合路徑成本,同時考慮了鍊路的帶寬、延遲、負載、MTU、可靠性5個方面來計算路由的路徑成本,而不像其他IGP協定單純的考慮某一個方面來計算路徑成本。IGRP已經被Cisco獨立開發的EIGRP協定所取代,版本号為12.3及其以上的Cisco IOS(Internetwork Operating System)已經不支援該協定,已經罕有運作IGRP協定的網絡。

(3)EIGRP(增強型内部網關路由協定)

由于IGRP協定的種種缺陷以及不足,Cisco開發了EIGRP協定(增強型内部網關路由協定)來取代IGRP協定。EIGRP屬于進階距離矢量路由協定(又稱混合型路由協定),繼承了IGRP的混合路徑成本,最大特點在于引入了非等價負載均衡技術,并擁有極快的收斂速度。EIGRP協定在Cisco裝置網絡環境中廣泛部署。

(4)OSPF(開放式最短路徑優先)

OSPF協定是“開放式最短路徑優先(Open Shortest Path First)”的縮寫,屬于鍊路狀态路由協定。OSPF提出了“區域(area)”的概念,每個區域中所有路由器維護着一個相同的鍊路狀态資料庫(LSDB)。區域又分為骨幹區域(骨幹區域的編号必須為0)和非骨幹區域(非0編号區域),如果一個運作OSPF的網絡隻存在單一區域,則該區域可以是骨幹區域或者非骨幹區域。如果該網絡存在多個區域,那麼必須存在骨幹區域,并且所有非骨幹區域必須和骨幹區域直接相連。OSPF利用所維護的鍊路狀态資料庫,通過最短路徑優先算法(SPF算法)計算得到路由表。OSPF的收斂速度較快。由于其特有的開放性以及良好的擴充性,OSPF協定在各種網絡中廣泛部署。

(5)IS-IS(中間系統到中間系統)

IS-IS協定是Intermediate system to intermediate system(中間系統到中間系統)的縮寫,屬于鍊路狀态路由協定。标準IS-IS協定是由國際标準化組織制定的ISO/IEC 10589:2002所定義的,标準IS-IS不适合用于IP網絡,是以IETF制定了适用于IP網絡的內建化IS-IS協定(Integrated IS-IS)。和OSPF相同,IS-IS也使用了“區域”的概念,同樣也維護着一份鍊路狀态資料庫,通過最短生成樹算法(SPF)計算出最佳路徑。IS-IS的收斂速度較快。內建化IS-IS協定是ISP骨幹網上最常用的IGP協定。

(6)BGP(邊界網關協定)

為了維護各個ISP的獨立利益,标準化組織制定了ISP間的路由協定BGP。BGP是“邊界網關協定(Border Gateway Protocol)”的縮寫,處理各ISP之間的路由傳遞。但是BGP運作在相對核心的地位,需要使用者對網絡的結構有相當的了解,否則可能會造成較大損失。

17 直播可能需要使用到什麼樣的協定?

參考回答

視訊直播有多種協定,使用rtmp協定的就是rtmp直播。直播流就是視訊流,即傳遞的視訊資料。常見的協定有RTMP、RTSP、HTTP協定,這三個協定都屬于網際網路TCP/IP五層體系結構中應用層的協定。理論上這三種都可以用來做視訊直播或點播。但通常來說,直播一般用RTMP、RTSP,而點播用HTTP。下面分别介紹下三者的特點。

RTMP協定

(1)是流媒體協定;

(2)RTMP協定是Adobe的私有協定,未完全公開;

(3)RTMP協定一般傳輸的是flv,f4v格式流;

(4)RTMP一般在TCP1個通道上傳輸指令和資料。

RTSP協定

(1)是流媒體協定;

(2)RTSP協定是共有協定,并有專門機構做維護;

(3)RTSP協定一般傳輸的是ts、mp4格式的流;

(4)RTSP傳輸一般需要2-3個通道,指令和資料通道分離。

HTTP協定

(1)不是是流媒體協定;

(2)HTTP協定是共有協定,并有專門機構做維護;

(3)HTTP協定沒有特定的傳輸流;

(4)HTTP傳輸一般需要2-3個通道,指令和資料通道分離。

答案解析

擴充資料

一個完整的視訊直播過程,包括采集、處理、編碼、封裝、推流、傳輸、轉碼、分發、解碼、播放等。

采集

音頻采集音頻的采集過程主要通過裝置将環境中的模拟信号采內建 PCM 編碼的原始資料,然後編碼壓縮成 MP3 等格式的資料分發出去。常見的音頻壓縮格式有:MP3,AAC,HE-AAC,Opus,FLAC,Vorbis (Ogg),Speex 和 AMR等。

圖像采集 圖像的采集過程主要由攝像頭等裝置拍攝成 YUV 編碼的原始資料,然後經過編碼壓縮成 H.264 等格式的資料分發出去。常見的視訊封裝格式有:MP4、3GP、AVI、MKV、WMV、MPG、VOB、FLV、SWF、MOV、RMVB 和 WebM 等。

處理

視訊或者音頻完成采集之後得到原始資料,為了增強一些現場效果或者加上一些額外的效果,我們一般會在将其編碼壓縮前進行處理。

視訊:美顔、水印、路徑、自定義。

音頻:混音、降噪、特效、自定義。

編碼

對流媒體傳輸來說,編碼非常重要,它的編碼性能、編碼速度和編碼壓縮比會直接影響整個流媒體傳輸的使用者體驗和傳輸成本。

常見的視訊編碼器:

(1)H.264/AVC

(2)HEVC/H.265

(3)VP8

(4)VP9

(5)FFmpeg

音頻編碼器:Mp3, AAC等。

封裝

把編碼器生成的多媒體内容(視訊,音頻,字幕,章節資訊等)混合封裝在一起幾種常見的封裝格式:

(1)AVI 格式(字尾為 .avi)

(2)DV-AVI 格式(字尾為 .avi)

(3)QuickTime File Format 格式(字尾為 .mov)

(4)MPEG 格式(檔案字尾可以是 .mpg .mpeg .mpe .dat .vob .asf .3gp .mp4等)

(5)WMV 格式(字尾為.wmv .asf)

(6)Real Video 格式(字尾為 .rm .rmvb)

(7)Flash Video 格式(字尾為 .flv)

(8)Matroska 格式(字尾為 .mkv)

(9)MPEG2-TS 格式 (字尾為 .ts)

目前,我們在流媒體傳輸,尤其是直播中主要采用的就是 FLV 和 MPEG2-TS 格式,分别用于 RTMP/HTTP-FLV 和 HLS 協定。

推流

推流是指使用推流工具等内容抓取軟體把直播内容傳輸到伺服器的過程。推送協定主要有三種:

(1)RTSP(Real Time Streaming Protocol):實時流傳送協定,是用來控制聲音或影像的多媒體串流協定, 由Real Networks和Netscape共同提出的;

(2)RTMP(Real Time Messaging Protocol):實時消息傳送協定,是Adobe公司為Flash播放器和伺服器之間音頻、視訊和資料傳輸 開發的開放協定;

(3)HLS(HTTP Live Streaming):是蘋果公司(Apple Inc.)實作的基于HTTP的流媒體傳輸協定;RTMP是目前主流的流媒體傳輸協定,廣泛用于直播領域,市面上絕大多數的直播産品都采用了這個協定。

RTMP協定基于 TCP,是一種設計用來進行實時資料通信的網絡協定,主要用來在 flash/AIR 平台和支援 RTMP 協定的流媒體/互動伺服器之間進行音視訊和資料通信。支援該協定的軟體包括 Adobe Media Server/Ultrant Media Server/red5 等。它有三種變種:

(1)RTMP工作在TCP之上的明文協定,使用端口1935;

(2)RTMPT封裝在HTTP請求之中,可穿越防火牆;

(3)RTMPS類似RTMPT,但使用的是HTTPS連接配接;

RTMP協定就像一個用來裝資料包的容器,這些資料可以是AMF格式的資料,也可以是FLV中的視/音頻資料。一個單一的連接配接可以通過不同的通道傳輸多路網絡流。這些通道中的包都是按照固定大小的包傳輸的。

傳輸

推送出去的流媒體需要傳輸到觀衆,整個鍊路就是傳輸網絡。

轉碼

視訊直播播流端的碼率是根據推流端決定的,即播流端的碼率是與推流端的碼率一緻的。但是遇到以下場景會造成直播效果較差:推流端碼率與播流端帶寬不相比對。當推流端碼率較高而用戶端帶寬資源有限就會導緻播放出現卡頓,而當推流端碼率較低但是用戶端對于直播效率要求較高時會導緻播放效果較差。播放器插件需要實作多碼率切換。前端播放器插件常可以設定碼率切換,這就需要同一路推流可以同時提供多種碼率的播流位址。是以,視訊直播提供了實時轉碼功能對同一路推流位址同時提供多路不同碼率播流位址提供服務。

分發

流媒體伺服器的作用是負責直播流的釋出和轉播分發功能。

解碼

編碼器(Encoder):壓縮信号的裝置或程式;

解碼器(Decoder):解壓縮信号的裝置或程式;

編解碼器(Codec):編解碼器對。

播放器流播放主要是實作直播節目在終端上的展現。因為這裡使用的傳輸協定是RTMP, 是以隻要支援 RTMP 流協定的播放器都可以使用。

18 談談單工、雙工、半雙工的通信方式。

參考回答

單工:資料傳輸隻支援資料在一個方向上傳輸;在同一時間隻有一方能接受或發送資訊,不能實作雙向通信。舉例:電視,廣播。

半雙工:半雙工資料傳輸允許資料在兩個方向上傳輸,但是,在某一時刻,隻允許資料在一個方向上傳輸,它實際上是一種切換方向的單工通信;在同一時間隻可以有一方接受或發送資訊,可以實作雙向通信。舉例:對講機。

雙工:全雙工資料通信允許資料同時在兩個方向上傳輸,是以,全雙工通信是兩個單工通信方式的結合,它要求發送裝置和接收裝置都有獨立的接收和發送能力;在同一時間可以同時接受和發送資訊,實作雙向通信。舉例:電話通信。

答案解析

擴充資料:

單工、半雙工和全雙工是電信計算機網絡中的三種通信信道。這些通信信道可以提供資訊傳達的途徑。通信信道可以是實體傳輸媒體或通過多路複用媒體的邏輯連接配接。實體傳輸媒體是指能夠傳播能量波的材料物質,例如資料通信中的導線。并且邏輯連接配接通常指電路交換連接配接或分組模式虛拟電路連接配接,例如無線電信通道。由于通信信道的幫助,資訊可以無障礙地傳輸。

單工模式一般用在隻向一個方向傳輸資料的場合。例如計算機與列印機之間的通信是單工模式,因為隻有計算機向列印機傳輸資料,而沒有相反方向的資料傳輸。還有在某些通信信道中,如單工無線發送等。

歡迎大家加我微信交流讨論(請備注csdn上添加)

Java工程師 計算機網絡(四) 面試題(Day31)