面試遇到的問題:
美團:
1. 網絡七層體系結構
滴滴:
1.網絡體系結構(七層、五層、TCP/Ip),各層的作用和協議。
2.TCP/IP在哪一層
3. TCP/UDP區別和應用場景
4. TCP如何保證它的可靠性
5. TCP如何面向連接?三次握手、四次釋放過程?為什么是三次握手不是兩次或者四次?
6. HTTP是哪一層?有哪幾種操作?
7. GET和POST區別,其中,GET請求可以提交嗎?(URL中包含用戶名和密碼,那它可以提交嗎)?
8. 有配置過服務器嗎?你們用的是什么類型的服務器?
9. 一個請求訪問首頁的URL,到達服務器后具體的操作?如何調用本地的方法的?
一、 TCP/IP協議族
TCP/IP模型由四層結構組成:網絡接口層、網際層、傳輸層、應用層,每層分別具有不同的協議和功能。TCP/IP協議族是一組在不同層的多個協議的組合,各層在實現自身功能時,為上層提供服務。
1.封裝
在源主機,通過TCP/UDP傳送用戶數據時,將用戶數據送入TCP/IP協議棧,然后自上而下通過每一層,最后被當作一串比特流傳入網絡。 其中每一層對收到的數據都需要增加一些首部信息,有時還需要增加尾部信息。這些操作過程稱為封裝。
2. 拆封
二、五層模型
**1. 在瀏覽器中輸入 www.baidu.com 后執行的全部過程
1. 應用層上使用了HTTP協議
1)首先客戶端通過DNS解析域名請求(UDP協議),得到URL對應的IP地址。DNS解析過程:
- 瀏覽器緩存。(2~30min)
- 系統緩存(windows:gethostbyname)
- 路由器緩存
- ISP DNS緩存
- 遞歸搜索:從根域名服務器開始遞歸搜索。其中,為了消除例如微博這種多個IP對應一個域名的問題,使用
2)瀏覽器客戶端發起一個HTTP請求到這個IP地址(HTTP協議是以ASCII傳輸)
2. 在傳輸層使用了TCP協議建立連接,通過流量控制、擁塞控制、差錯控制保證數據傳輸的穩定性。
- 把HTTP請求分成報文段,添加源和目的端口,封裝成TCP協議報。
- 例如服務器端使用80端口監聽客戶端請求,客戶端由系統隨機選擇一個端口如5000,與服務器進行交換,服務器把相應的請求返回客戶端的5000端口。
- 輸入網絡層
3. 網絡層:使用IP、ICMP、ARP、RARP協議
1)首先,進行尋址和路由。使用路由表確定到達服務器的路徑以及ARP協議將IP地址轉化成服務器MAC地址。ARP解析過程(廣播發送ARP請求,單播發送ARP響應):
- 首先,每個主機在自己的ARP緩存區,建立一個ARP列表,包含IP和MAC的對應關系
- 當源主機要發送數據時,首先檢查ARP列表中是否有對應IP和MAC地址,如果不存在,則廣播發送ARP請求,包含了:自己的IP、MAC和目的IP地址
- 在廣播域中的主機,接受到ARP數據包后,首先檢查是否是自己的IP地址,如果不是,則忽略;如果是,則單播給源主機自己的MAC地址。
它是IPv4網絡層必不可少的協議,不過在IPv6中已不再適用,並被鄰居發現協議(NDP)所替代
2)同時使用ICMP協議,對數據報進行差錯控制
3)然后對IP數據報進行拆分和重裝,添加IP信息,傳入數據鏈路層。
4. 數據鏈路層:
將IP數據報加上控制信息:校驗碼/驗證碼+幀定界符,封裝成數據幀,傳入物理層
5. 物理層:
將數據幀轉換成0,1比特流。最后,使用真正的電信號通過多種傳輸介質傳輸到百度的服務器。
當電信號到達服務器,對數據幀進行拆分,直到應用層。
服務器:
對於Tomcat,有一個Context容器,也就是Servlet容器。
1. 當Servlet啟動時,它會部署加載所有的Web應用,
- 每個應用都創建一個Servlet Context(Servlet上下文),保存在內存中。Servlet Context對象就是已知路徑的根,定義了一組方法的API:http://localhost:8080/項目名
- 處理Web應用的web.xml文件,一次性創建在web.xml中定義的servlet、Filter、Listener,同樣保存在內存中。
2. 當Servlet容器關閉時,它會卸載所有的web應用和ServletContext,所有的Servlet、Filter、Listener都會被銷毀
3. 每個Servlet都有:init()、service()、destroy()函數。
- init():在啟動調用時用於初始化參數
- service():完成服務
- destroy():容器銷毀時,調用
4. 那么Servlet容器接受HTTP請求的過程:
當客戶端發送一個HTTP請求時,Servlet容器會創建一個新的HTTPServletRequest對象和HTTPServletResponse對象。
- HttpServletRequest對象把客戶的請求信息封裝起來,然后調用servlet的service(request, respones),然后轉向doGet()或doPost(),完成Servlet的執行
- 接着把Servlet的執行返回到HTTPServletResponse對象中
- 最后Servlet容器把客戶的請求發送給客戶,完成客戶一次服務過程。
一、傳輸層
**1. TCP 三次握手/四次釋放
TCP協議是傳輸層的協議,特點是:面向連接、通信可靠
面向連接:在傳送TCP報文之前,必須先建立TCP連接,數據傳輸完成后要進行鏈路釋放
1. 三次握手的步驟:
第一次握手:客戶端通過向服務器發送一個SYN報文段(SYN=1, ACK =0)來請求創建連接,並且生成一個隨機序列號seq=x。
第二次握手:服務器端收到用戶SYN報文后,為該TCP連接分配一個緩存和變量,並生成一個允許建立連接的報文:SYN=1,ACK=1,同時設置ack確認碼為x+1(即告訴客戶端,希望下次收到的序列號從x+1開始),此時,該SYN/ACK序列號seq = y。
第三次握手:客戶端收到服務器端的報文后,也要為該連接分配緩存和變量。同時發送一個ACK報文段(SYN=0,ACK=1)表示確認,此時,ack=y+1(表示下次希望收到的序列號從y+1開始),seq=x+1(表示此次數據序列號從x+1開始)。當服務器端收到這個報文以后,就完成了建立。
2. 為什么需要第三次握手?
第三次握手的目的是為了防止已失效的客戶機請求建立報文段突然又傳送到了服務器,因而產生錯誤。
例如:當客戶端發送一次連接請求SYN報文段,因為網絡原因,在一定時間內沒有收到允許連接的報文。所以客戶端會重傳這個報文段。客戶端發出了兩個請求建立報文,服務器響應了第二個報文段,並且建立了連接,完成了數據傳輸,關閉連連。在這個時候,如果服務器收到了第一個請求建立報文,就會允許建立連接,等待傳送資源。
如果沒有第三次握手,服務器會認為客戶端在傳輸資源過程中而白白等待——浪費資源
有了第三次握手以后,服務器在一定時間內,沒有收到客戶端的第三次確認ACK報文段,會自動釋放資源。
3. 四次釋放
無論是客戶端還是服務器端都可以提出終止連接的請求,連接釋放后,兩端的資源(緩存和變量)都會釋放,分為四步:
第一步:通訊中任意一方(例如客戶端)提出連接釋放請求報文,FIN=1,此時進入“釋放等待-1”狀態。序列號seq=客戶端發送的最后一個序列號+1(u),ack=v(確認收到服務器v-1以前的字節)
第二步:服務器收到“連接釋放請求報文”以后,發送“連接釋放請求確認報文”,ack=u+1, seq=v,ACK=1,允許該方向TCP連接的釋放。至此,從客戶端到服務器端這個方向的TCP連接就釋放了,但是服務器端到客戶端的連接還沒釋放,稱為“半關閉狀態”:客戶端進入“FIN-WAIT-2”狀態,服務器進入“CLOSER_WAIT”狀態
第三步:服務器的高層應用已經沒有數據需要發送時,服務器端發送“連接釋放請求報文”給客戶端。此時FIN=1,ACK=1,seq=w,ack=u+1,數據部分不攜帶數據。服務器端經過“LAST-ACk”狀態進入“LISTEN”狀態。
第四步:客戶端向服務器端回復一個確認該方向連接釋放的報文段,其中ACK=1,seq=u+1,ack=w+1。等待一個固定時間,真正關閉TCP連接。
4. 為什么要等待一個固定時間?(為什么是四次釋放,第四次釋放丟失怎么辦?)
當B在第三步發送了“連接釋放請求”報文段后,A發送“確認連接釋放請求”,並等待一個固定時間,有兩個主要原因:
1. 為了保證A最后的確認報文段能夠到達B。即這個報文段可能會丟失,那么B會重傳讓A在一次確認。如果沒有等待時間,A在發出了確認報文段后立即釋放資源,那么B無法重傳(連接已經釋放,任何數據不能傳了),則無法獲得確認進入CLOSED狀態。
2. 防止已失效的連接請求報文段出現在連接中。經過這個固定時間,滯留在網絡中的任何報文段都可以發送到目的地,不會滯留在網絡中,這樣的話,下一次的連接中就不會出現上一個連接遺留的報文段了。
5. TCP怎么進行流量控制的?
流量控制的目的:控制發送端發送速率,使之不超過接受端的接受速率
實現機制:面向字節的滑動窗口——接受端根據接受能力選擇一個合適的接受窗口值,將它寫在發送給通信對方的TCP報頭,將接受的狀態通知給發送方,發送方的發送窗口不能超過接受窗口。
(1)當接收端的應用進程從緩存中讀取字節的速度>=發送方的發送速度時,接受端在每一個確認中發送一個非零的窗口通知。
(2)當接受端的處理速度<發送方的發送速度時,接受端在每一個確認中發送一個零窗口通知,此時接受端停止發送,直到下一次接收到一個非零窗口通知。
6. TCP怎么進行擁塞控制
1)為什么無法使用流量控制?
流量控制是控制端到端的流量,無法控制進入網絡的總體流量,擁塞控制的重點是進入網絡報文總量的全局控制上,是在整個網絡的輸入負載超過了網絡能夠承受的程度。
2)解決方法:讓每一個發送方根據感知的網絡擁塞情況,來限制其向網絡發送的速率。如果一個發送方感知到從它到目的主機的網絡暢通,則增加發送的速率;反之若感知到網絡的擁塞,則降低發送速率。
7. TCP如何進行差錯控制?
有三個工具:
1. 校驗和:檢測受到損傷的報文段
2. 確認:確認已經收到的報文段。
- 累計確認:確認已經正確接收到的數據流中最大序列號
- 選擇確認SACK:用來報告時許的數據快和重復的數據快。並不是代替ACK,而是向發送端發送特定的信息。例如:我們已經收到了0-1000, 2000-3000,中間未收到1001~19999,這個時候SACK就會發送未接受的數據字節流的兩個邊界(10001,1999)。
3. 超時。
- 當發送端發送數據時,會啟動一個計時器
- 當接收端收到發送端發送的數據時,需要回復一個確認
- 如果在計時器到點之前,沒有收到接收端的確認,則發送法重傳數據
自適應的超時重傳機制:
TCP監視每一連接中的當前延遲,並適配重發定時器來適應通信條件的變化。
8. 快速重傳為什么是三次冗余ack,這個三次是怎么定下來的?
包的丟失有三種情況:1)校驗和錯誤(時序);2)網絡擁塞;3)網絡斷開
對於收到兩次相同ack可能是亂序,接收到三次以上的相同ack表明網絡擁塞。
8. TCP的差錯控制
8. TCP和UDP區別和應用
TCP | UDP | |
本質 |
面向連接的、可靠的數據流傳遞
|
非面向連接的不可靠的 |
傳輸單位 | TCP報文段 | 用戶數據報 |
特點 | 注重數據安全性 | 數據傳輸快,不需要連接等待 |
對應的應用層協議 | FTP:文件傳輸協議:21 文件、郵件傳輸 |
DNS:域名解析服務,53 視頻 |
6. 什么是Socket
Socket本質是API編程接口,封裝了TCP/IP,在應用層用來實現不同主機間進程的通信。具體而言,我們用IP地址+協議號+端口號來標記一個進程,然后利用socket來進行通信。
socket是一種"打開—讀/寫—關閉"模式的實現,服務器和客戶端各自維護一個"文件",在建立連接打開后,可以向自己文件寫入內容供對方讀取或者讀取對方內容,通訊結束時關閉文件。
Socket通信機制:
服務器:服務器端先初始化Socket,然后與端口綁定(bind),對端口進行監聽(listen),調用accept阻塞,等待客戶端連接。在這時如果有個客戶端初始化一個Socket,然后連接服務器(connect),如果連接成功,這時客戶端與服務器端的連接就建立了。客戶端發送數據請求,服務器端接收請求並處理請求,然后把回應數據發送給客戶端,客戶端讀取數據,最后關閉連接,一次交互結束。具體過程:
服務器:
1)socket():服務器首先根據地址類型(IPV4/IPV6)、socket類型及協議初始化socket。
2)bind():為socket綁定IP地址和端口號
3)listen():監聽端口號請求,隨時准備接受客戶端發來的連接,這時服務器的socket並沒有打開。
客戶端:
4)socket:客戶端創建socket()
5)connect():根據服務器的Ip地址和端口號試圖連接服務器socket
服務器:
6)服務器socket接收到客戶端socket的請求,被動打開,開始接收客戶端請求,直到客戶端返回連接信息。這時候socket處於阻塞狀態。(TCP的三次連接)
客戶端:
7)客戶端連接成功,向服務器發送連接狀態信息。
服務器端:
8)服務器端accept()方法返回,連接成功
客戶端:
9)客戶端向socket寫入信息
服務器
10)服務器讀取信息
客戶端
11)客戶端關閉
服務器端
12)服務器端關閉
二、網絡層
三、應用層
1. HTTP和HTTPS
1)HTTP狀態碼
1xx: 信息性狀態碼
100, 101
2xx: 成功狀態碼
200:OK
3xx: 重定向狀態碼
301: 永久重定向, Location響應首部的值仍為當前URL,因此為隱藏重定向;
302: 臨時重定向,顯式重定向, Location響應首部的值為新的URL
304:Not Modified 未修改,比如本地緩存的資源文件和服務器上比較時,發現並沒有修改,服務器返回一個304狀態碼,
告訴瀏覽器,你不用請求該資源,直接使用本地的資源即可。
4xx: 客戶端錯誤狀態碼
403: Forbidden 404: Not Found 請求的URL資源並不存在
5xx: 服務器端錯誤狀態碼
500: Internal Server Error 服務器內部錯誤
502: Bad Gateway 前面代理服務器聯系不到后端的服務器時出現
504:Gateway Timeout 這個是代理能聯系到后端的服務器,但是后端的服務器在規定的時間內沒有給代理服務器響應
2)HTTPS:安全套接字層超文本傳輸協議
安全性 |
端口 |
|
HTTP |
以明文方式發送內容,不提供任何方式的數據加密 |
80 |
HTTPS |
+SSL協議 握手:客戶端產生一個對稱密鑰,服務器端通過證書來交換密鑰 |
443 |
2. HTTP1.0和HTTP1.1
連續性 | 流水線 | Host請求頭字段 | 請求頭和響應頭 | |
HTTP1.0 | 非持續連接: 每一個應答響應對應一個TCP連接 |
非流水線: 客戶端在接收到前一個應答才會發送下一個請求 |
不支持 | |
HTTP1.1 | 多個客戶與服務器的請求/應答報文可以通過一個TCP連接來完成 | 流水線:客戶端可以連續的發送請求,服務器端可以連續的發送應答 | 支持:Web瀏覽器可以使用主機頭名來表明將要訪問服務器的哪個Web站點, 實現了在一台WEB服務器上可以在同一個IP地址和端口號上使用不同的主機名來創建多個虛擬WEB站點 |
還提供了:與身份認證、狀態管理、Cache緩存等機制相關的請求頭和響應頭 |
3. Cookie和Session
引入的原因:HTTP協議是無狀態的協議,而用戶的所有請求操作應該屬於同一會話
Cookie | Session | |
存儲位置 | 客戶端 | 服務器端 |
目的 |
跟蹤會話,也可以保存用戶偏好設置或者用戶密碼 | 跟蹤會話 |
安全性 | 不安全 | 安全 |
session技術是要使用到cookie的,之所以出現session技術,主要是為了安全。
4. HTTP協議包含哪些請求
GET:獲取URL下的資源、提交表單信息(用戶名、密碼)
POST:向服務器提交更新數據(創建或更新服務器資源)
PUT:存儲一個資源到請求的URL
DELETE:刪除給定的URL所標志的資源
HEAD:返回URL標志的頭信息
TRACE:返回TRACE請求附帶的頭字段
OPTION:返回服務器支持的HTTP請求
5. Post和Get
GET | POST | |
作用 | 從給定的URL下請求資源,或提交表單信息 | 向指定的資源提交要處理的數據(更新或新建資源) |
冪等性 | 具有冪等性,不產生副作用(后退、刷新沒有變化) | 不具備冪等性(重新提交表格) |
做書簽 | 可做書簽 | 不可做書簽 |
緩存 | 能被緩存 | 不能被緩存 |
對數據類型的限制 | ASCII字符 | 無限制,可以為二進制 |
其中,最重要的兩個差別就是:作用和冪等性。
另外:網絡上還有一些理解是不正確的:
1. GET用URL或者Cookie傳遞參數,POST同BODY傳參:
現代的WebServer都是支持GET中包含BODY這樣請求。GET和POST與數據傳遞沒有關系
2. GET的URL會有長度限制,而POST數據可以很大
HTTP協議對GET和POST沒有長度限制,URL上的限制主要從服務器的安全性、穩定性的考慮。
3. GET信息在URL中傳遞,不安全
6. 冪等(Idempotence)
HTTP方法的冪等性是指一次和多次請求某一個資源應該具有同樣的副作用。(注意是副作用)
1)GET http://www.bank.com/account/123456:獲取這個URI下面的資源,不會改變資源的狀態。
注意:這里強調的是“副作用”,雖然可能每次返回的GET結果可能不同。
——GET具有冪等性
2)DELETE http://www.forum.com/article/4231:刪除資源,有副作用,但DELETE應該滿足冪等性。
調用一次和N次對系統產生的副作用是相同的,即刪掉id為4231的帖子;因此,調用者可以多次調用或刷新頁面而不必擔心引起錯誤。
3)POST http://www.forum.com/articles:POST所對應的URI並非創建的資源本身,而是資源的接收者。
這句話語義是在http://www.forum.com/articles下創建一篇帖子,HTTP響應中應包含帖子的創建狀態以及帖子的URI。兩次相同的POST請求會在服務器端創建兩份資源,它們具有不同的URI;所以,POST方法不具備冪等性。
4)PUT http://www.forum/articles/4231PUT所對應的URI是要創建或更新的資源本身。
這句話語義是:建或更新ID為4231的帖子。對同一URI進行多次PUT的副作用和一次PUT是相同的;因此,PUT方法具有冪等性。
7. 網站用戶密碼保存
使用明文保存——>明文Hash后保存(如:md5)——>MD5+SALT方式(SALT:系統隨機產生一些值)
8. RESTful架構
RESTful框架,是一種互聯網軟件架構,它滿足REST原則,結構清晰、符合標准、易於理解、擴展方便。
REST原則:
1)每一個資源對應一個URI
2)客戶端和服務器之間,傳遞這個資源的某種表示層
3)客戶端通過四個HTTP動詞,對服務器資源進行操作,實現“表示層轉化”
(詳細而言:)
1. 資源Resources
網絡中每一個實體、資源——>URI(統一資源對應符)
2. 表示層(Representation)
我們把"資源"具體呈現出來的形式,叫做它的"表現層。例如:HTML格式、XML格式、JSON格式
3. 狀態轉化(State Transfer)
訪問一個網站,就代表了客戶端和服務器的一個互動過程。在這個過程中,勢必涉及到數據和狀態的變化。
HTTP有四個操作:GET用來獲取資源,POST用來新建資源(也可以用於更新資源),PUT用來更新資源,DELETE用來刪除資源。
總結而言:
進化的順序: RPC -> SOAP -> RESTful
9. WebService
10. CSRF和XSS
CSRF(Cross-site request forgery)跨站請求偽造
XSS(Cross the Scripting)跨站腳本攻擊
11. Ajax
AJAX:Asynchronous JavaScript and XML(異步的 JavaScript 和 XML)。
是與在不重新加載整個頁面的情況下,與服務器交換數據並更新部分網頁的技術。
12. forward & sendRedirect 比較
轉向forward | 重定向redirect | |
本質 | 客戶端發送http請求,服務器接受這個請求,調用內部的一個方法在容器內完成該請求和轉發動作, 將目標資源發送給客戶端。 |
1. 客戶端發送http請求,服務器端接受次請求,回復301響應碼和新的URL地址給客戶端 2. 客戶端發現是302請求,自動再發出一個http請求,請求URL是新的地址 服務器根據這個新的URL尋找資源發送給客戶端。 |
請求次數 | 一次http請求 | 至少兩次http請求: |
地址欄顯示 | 不變,轉發路徑必須是同一個web容器下的URL | 新的URL,地址可以是任意的 |
數據共享 | 轉發頁面和轉發到的頁面可以共享request里面的數據. | 不可以共享 |
作用 | 一般作用於用戶登錄時,根據角色轉發到相應的模塊 | 一般用於用戶注銷登陸時返回主頁面和跳轉到其它的網站等. |
效率 | 高 | 低 |
其中兩個動作的工作流程:
1. 轉發過程(forward):
客戶瀏覽器發送Http請求——>web服務器接受該請求——>調用內部的一個方法在容器內完成請求處理和轉發動作——>將目標資源發送給客戶
上面直接轉發請求的過程:
1)瀏覽器向Servlet1發出請求
2)Servlet1調用forward()方法,在服務器端將請求轉發給Servlet2
3)最終由Servlet2做出相應
舉例:A向B借錢,B沒有錢,向C借錢,借沒有借到錢都會將消息回復給A
- 在這里,轉發的路徑必須是同一個web容器下的url,其不能轉向到其他的web路徑上去,
- 中間傳遞的是自己的容器內的request。
- 在客 戶瀏覽器路徑欄顯示的仍然是其第一次訪問的路徑,也就是說客戶是感覺不到服務器做了轉發的。轉發行為是瀏覽器只做了一次訪問請求。
2. 重定向過程(sendRedirect):
客戶瀏覽器發送Http請求——>web服務器接受此請求后,發送302響應碼以及新的location給客戶瀏覽器——>客戶瀏覽器發現是302響應,則自動再發送一個新的Http請求,請求url是新的location地址——>服務器根據此請求尋找資源發送給客戶。
具體而言:
1)瀏覽器向Servlet1發出訪問請求
2)Servlet1調用sendRedirect()方法,將瀏覽器重定向到Servlet2
3)瀏覽器向Servlet2發出請求
4)最終由Servlet2做出相應
舉例:它一般用於避免用戶的非正常訪問。例如:用戶在沒有登錄的情況下訪問后台資源,Servlet可以將該HTTP請求重定向到登錄頁面,讓用戶登錄以后再訪問。
A向B借錢,B沒有錢讓A向C借錢。
- 在這里 location可以重定向到任意URL
- 既然是瀏覽器重新發出了請求,則就沒有什么request傳遞的概念了。
- 在客戶瀏覽器路徑欄顯示的是其重定向的 路徑,客戶可以觀察到地址的變化的。
- 重定向行為是瀏覽器做了至少兩次的訪問請求的。
四、數據鏈路層: