網絡相關的面試題

網絡相關的面試題

  • 服務器端不調用accept會發生什麼

不調用accept時,也能建立連接,即三次握手完成。但不能進行API的控制,即不能進行繼續通訊。以及建立好連接的隊列大大小爲:backlog。從而在Unix系統服務器中,若客戶端調用 connect() ,客戶端連接超時失敗。而在Linux系統中,若客戶端調用 connect()。TCP 的連接隊列滿後,Linux 服務器不會拒絕連接,只是有些會延時連接,有些立刻連接。

詳情參考https://blog.csdn.net/hycxag/article/details/82974484

  • 瀏覽器中輸入www.baidu.com,按回車鍵以後做了哪些操作

  • 先要解析出www.baidu.com域名對應的ip地址

  1. 先要知道主機默認的網關MAC:即使用ARP來獲取默認網關的MAC地址。
  2. 組織數據,發送給默認網關(IP對應的時DNS服務器,而MAC地址是默認網關的MAC地址)
  3. 默認網關擁有轉發數據的能力,把數據轉發給路由器
  4. 路由器根據自己的路由協議,來選擇一個合適的較快的路徑轉發數據給目的網關
  5. 目的網關(DNS服務器所在的網關)把數據發給DNS服務器
  6. DNS服務器查詢解析出www.baidu.com域名對應的IP地址,並把此IP地址組織成數據包,按原路返回方式,發給請求這個域名的客戶端
  • 得到www.baidu.com對應的IP地址以後,會發送TCP的三次握手進行連接
  • 連接成功後,使用http協議發送請求數據給web服務器
  • web服務器收到數據請求之後,通過查詢自己的服務器得到相應的結果,並原路返回給瀏覽器
  • 瀏覽器接收到數據之後,通過瀏覽器自己的渲染功能來顯示這個頁面
  • 瀏覽器關閉TCP連接,即四次揮手。
  • 端口號與進程號的區別

os爲了區分進程,os會分配一個pid來識別進程。但兩臺電腦進行交互的戶的時候,很難獲取另外一臺電腦運行進程的pid。故需要引入另外一種區分進程的方法——端口,每個進程的端口號一般是固定的,從而可以進兩臺電腦進行交互。(若人爲更改進程的端口號,則常規的兩臺電腦交互會失敗) 。故pid用於一臺電腦區分進程,端口號是爲了多臺電腦交互時,來區分進程 。

端口號分配佔用2個字節:故編號爲0到65535。而知名的端口號在0-1023,例如:80端口:http服務器;21端口:ftp服務器;69端口:tftp服務器。動態端口(不固定分配某種服務,而是動態分配 ):從1024到65535。用netstat -an來查看進程的端口號。

  • TCP和UDP的區別

  1. TCP提供面向連接的傳輸,通信前要先建立連接(三次握手機制);UDP提供無連接的傳輸,通信前不需要建立連接。
  2. TCP提供可靠的傳輸(有序(序列號),無差錯(校驗和),不丟失(超時重傳),不重複(序列號));UDP提供不可靠的傳輸。
  3. TCP面向字節流的傳輸,因此它能將信息分割成組,並在接收端將其重組;UDP是面向數據報的傳輸,沒有分組開銷。
  4. TCP提供擁塞控制和流量控制機制;UDP不提供擁塞控制和流量控制機制。
  • 流量控制和擁塞控制的實現機制

TCP採用大小可變的滑動窗口機制實現流量控制功能。窗口的大小是字節。在TCP報文段首部的窗口字段寫入的數值就是當前給對方設置發送窗口的數據的上限。

在數據傳輸過程中,TCP提供了一種基於滑動窗口協議的流量控制機制,用接收端接收能力(緩衝區的容量)的大小來控制發送端發送的數據量。

採用滑動窗口機制還可對網絡進行擁塞控制,將網絡中的分組(TCP報文段作爲其數據部分)數量維持在一定的數量之下,當超過該數值時,網絡的性能會急劇惡化。傳輸層的擁塞控制有慢開始(Slow-Start)、擁塞避免(Congestion Avoidance)、快重傳(Fast Retransmit)和快恢復(Fast Recovery)四種算法。
擁塞: 大量數據報涌入同一交換節點(如路由器),導致該節點資源耗盡而必須丟棄後面到達的數據報時,就是擁塞。

  • 滑動窗口機制

TCP 採用大小可變的滑動窗口進行流量控制。窗口大小的單位是字節。在 TCP 報文段首部的窗口字段寫入的數值就是當前給對方設置的發送窗口數值的上限。發送窗口在連接建立時由雙方商定。但在通信的過程中,接收端可根據自己的資源情況,隨時動態地調整對方的發送窗口上限值(可增大或減小)。

  • 重傳機制

TCP每發送一個報文段,就設置一次定時器。只要定時器設置的重發時間到而還沒有收到確認,就要重發這一報文段。 在TCP環境中,報文往返時間不定、有很大差別,例如:A、B在一個局域網絡,往返時延很小;A、C在一個互聯網內,往返時延很大。因此,A很難確定一個固定的、與B、C通信都適用的定時器時間

TCP採用了一種自適應算法。這種算法記錄每一個報文段發出的時間,以及收到相應的確認報文段的時間。這兩個時間之差就是報文段的往返時延。將各個報文段的往返時延樣本加權平均,就得出報文段的平均往返時延T。

  • time_wait狀態產生的原因,危害,如何避免

  • 如何產生:首先調用close()發起主動關閉的一方,在發送最後一個ACK之後會進入time_wait的狀態,也就說該發送方會保持2MSL時間之後纔會回到初始狀態。MSL值得是數據包在網絡中的最大生存時間。產生這種結果使得這個TCP連接在2MSL連接等待期間。
  • 產生的原因:
  1. 爲實現TCP全雙工連接的可靠釋放:假設發起主動關閉的一方(client)最後發送的ACK在網絡中丟失,由於TCP協議的重傳機制,執行被動關閉的一方(server)將會重發其FIN,在該FIN到達client之前,client必須維護這條連接狀態,也就說這條TCP連接所對應的資源(client方的local_ip,local_port)不能被立即釋放或重新分配,直到另一方重發的FIN達到之後,client重發ACK後,經過2MSL時間週期沒有再收到另一方的FIN之後,該TCP連接才能恢復初始的CLOSED狀態。
  2. 爲使舊的數據包在網絡因過期而消失:因爲TIME_WAIT狀態持續2MSL,就可以保證當成功建立一個TCP連接的時候,來自先前的重複分組(傳輸分組由於超時而重發)來到server時,讓它自行消失。
     
  • 危害:  在高併發短連接的TCP服務器上,當服務器處理完請求後立刻主動正常關閉連接。這個場景下會出現大量socket處於TIME_WAIT狀態。如果客戶端的併發量持續很高,此時部分客戶端就會顯示連接不上。(在實際業務場景中,一般長連接對應的業務的併發量並不會很高。)
  • 如何避免:
  1. 首先服務器可以設置SO_REUSEADDR套接字選項來通知內核,如果端口忙,但TCP連接位於TIME_WAIT狀態時可以重用端口。在一個非常有用的場景就是,如果你的服務器程序停止後想立即重啓,而新的套接字依舊希望使用同一端口,此時SO_REUSEADDR選項就可以避免TIME_WAIT狀態。
  2. 由於time_wait狀態是在主動關閉的一方出現的,所以在設計協議邏輯的時候,儘量由客戶端主動關閉,避免服務端出現time_wait
  3. so_linger設置 l_onoff爲非0,l_linger爲0,則強制關閉套接字並斷開TCP的連接,TCP將丟棄保留在套接字發送緩衝區中的任何數據併發送一個RST給對方,而不是通常的四分組終止序列,這避免了TIME_WAIT狀態;
  • tcp建立連接爲什麼需要3次,斷開爲什麼需要4次

建立三次需要三次的原因:由於tcp是全雙工通信,若兩次建立連接,發生客戶端發出的第一個連接請求報文段並沒有丟失,而是在某些網絡節點長時間滯留了,以致延誤到連接釋放以後的某個時間才能到達服務端,於是客戶端會再次發生一個連接請求。若服務器發出確認,建立新的連接。故服務器將會與這個客戶端建立多個連接,而這些連接大多數一直等待這個客戶端發數據,浪費了Socket資源。而不是4次的原因是:由於tcp是全雙工通信,服務器端把兩步合成了一步,這樣效率進一步提高

揮手需要四次的原因:因爲TCP是全雙工的通信方式,即一方斷開連接後,不能向另一方發送數據,但是此時另一方可以向自己發送數據,所以雙方斷開連接是獨立的,所以需要四次。

  • tcp建立連接和斷開連接的各種過程中的狀態轉換細節:

客戶端:主動打開SYN_SENT--->ESTABLISHED--->主動關閉FIN_WAIT_1--->FIN_WAIT_2--->TIME_WAIT--->CLOSED

服務器端:LISTEN(被動打開)--->SYN_RCVD--->ESTABLISHED--->CLOSE_WAIT(被動關閉)--->LAST_ACK--->CLOSED

外加一個CLOSING,此狀態是由於服務器和客戶端同時進行關閉FIN_WAIT_1--->CLOSING--->TIME_WAIT--->CLOSED。

  • epoll與select的區別

當需要讀兩個以上的I/O的時候,如果使用阻塞式的I/O,那麼可能長時間的阻塞在一個描述符上面,另外的描述符雖然有數據但是不能讀出來,這樣實時性不能滿足要求,大概的解決方案有以下幾種:

  1. 使用多進程或者多線程,但是這種方法會造成程序的複雜,而且對與進程與線程的創建維護也需要很多的開銷。(Apache服務器是用的子進程的方式,優點可以隔離用戶)
  2. 用一個進程,但是使用非阻塞的I/O讀取數據,當一個I/O不可讀的時候立刻返回,檢查下一個是否可讀,這種形式的循環爲輪詢(polling),這種方法比較浪費CPU時間,因爲大多數時間是不可讀,但是仍花費時間不斷反覆執行read系統調用。
  3. 異步I/O(asynchronous I/O),當一個描述符準備好的時候用一個信號告訴進程,但是由於信號個數有限,多個描述符時不適用。
  4. 一種較好的方式爲I/O多路複用(I/O multiplexing:在沒有開闢多進程,多線程以及其他方式的前提下,也能完成併發服務器的開發)。先構造一張有關描述符的列表(epoll中爲隊列),然後調用一個函數,直到這些描述符中的一個準備好時才返回,返回時告訴進程哪些I/O就緒。select和epoll這兩個機制都是多路I/O機制的解決方案,select爲POSIX標準中的,而epoll爲Linux所特有的。

區別(epoll相對select優點)主要如下:

  1. select的句柄數目受限,在linux/posix_types.h頭文件有這樣的聲明:#define __FD_SETSIZE    1024  表示select最多同時監聽1024個fd。而epoll沒有,它的限制是最大的打開文件句柄數目。而poll只解決select中監聽套接字的上限問題,但仍然採用輪詢方式。
  2. epoll的最大好處是不會隨着FD的數目增長而降低效率,在selec中採用輪詢處理(單進程非阻塞服務器中的for遍歷編程 ),其中的數據結構類似一個數組的數據結構,而epoll是維護一個隊列,直接看隊列是不是空就可以了。epoll只會對"活躍"的socket進行操作---這是因爲在內核實現中epoll是根據每個fd上面的callback函數實現的。那麼,只有"活躍"的socket纔會主動的去調用 callback函數(把這個句柄加入隊列),其他idle狀態句柄則不會,在這點上,epoll實現了一個"僞"AIO。但是如果絕大部分的I/O都是“活躍的”,每個I/O端口使用率很高的話,epoll效率不一定比select高(可能是要維護隊列複雜)。
  3. 使用mmap加速內核與用戶空間的消息傳遞。無論是select,poll還是epoll都需要內核把FD消息通知給用戶空間,如何避免不必要的內存拷貝就很重要,在這點上,epoll是通過內核於用戶空間mmap同一塊內存實現的。
  • epoll中的et和lt的區別和實現原理

epoll有2種工作方式:LT和ET。

  1. LT(level triggered)是缺省的工作方式,並且同時支持block和no-block socket.在這種做法中,內核告訴你一個文件描述符是否就緒了,然後你可以對這個就緒的fd進行IO操作。如果你不作任何操作,內核還是會繼續通知你 的,所以,這種模式編程出錯誤可能性要小一點。傳統的select/poll都是這種模型的代表。
  2. ET (edge-triggered)是高速工作方式,只支持no-block socket。在這種模式下,當描述符從未就緒變爲就緒時,內核通過epoll告訴你。然後它會假設你知道文件描述符已經就緒,並且不會再爲那個文件描述 符發送更多的就緒通知,直到你做了某些操作導致那個文件描述符不再爲就緒狀態了(比如,你在發送,接收或者接收請求,或者發送接收的數據少於一定量時導致 了一個EWOULDBLOCK 錯誤)。但是請注意,如果一直不對這個fd作IO操作(從而導致它再次變成未就緒),內核不會發送更多的通知(only once),不過在TCP協議中,ET模式的加速效用仍需要更多的benchmark確認。

epoll只有epoll_create,epoll_ctl,epoll_wait 3個系統調用。

  • 內存池,進程池,線程池

自定義內存池的思想通過這個"池"字表露無疑,應用程序可以通過系統的內存分配調用預先一次性申請適當大小的內存作爲一個內存池,之後應用程序自己對內存的分配和釋放則可以通過這個內存池來完成。只有當內存池大小需要動態擴展時,才需要再調用系統的內存分配函數,其他時間對內存的一切操作都在應用程序的掌控之中。 應用程序自定義的內存池根據不同的適用場景又有不同的類型。 從線程安全的角度來分,內存池可以分爲單線程內存池和多線程內存池。單線程內存池整個生命週期只被一個線程使用,因而不需要考慮互斥訪問的問題;多線程內存池有可能被多個線程共享,因此則需要在每次分配和釋放內存時加鎖。相對而言,單線程內存池性能更高,而多線程內存池適用範圍更廣。
從內存池可分配內存單元大小來分,可以分爲固定內存池和可變內存池。所謂固定內存池是指應用程序每次從內存池中分配出來的內存單元大小事先已經確定,是固定不變的;而可變內存池則每次分配的內存單元大小可以按需變化,應用範圍更廣,而性能比固定內存池要低。

 

 

 

 

 

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章