iOS面試備戰-網絡篇

計算機網絡是計算機科學與技術專業的必修課,也是移動端,前端,後端都會涉及並用到的知識點,可想而知它的重要性。因此它也成爲了iOS面試中常常被問及的問題。準備面試的話,網絡相關的知識點必定不能錯過。這裏總結了一些我認爲有用的和最近面試遇到的網絡相關知識點。html

去年寫過一篇《圖解TCP/IP》總結的文章,也能夠對着看下。前端

計算機網絡是如何分層的

網絡有兩種分層模型,一種是ISO(國際標準化組織)制定的OSI(Open System Interconnect)模型,它將網絡分爲七層。一種是TCP/IP的四層網絡模型。OSI是一種學術上的國際標準,理想概念,TCP/IP是事實上的國際標準,被普遍應用於現實生活中。二者的關係能夠看這個圖:web

注:也有說五層模型的,它跟四層模型的區別就是,在OSI模型中的數據鏈路層和物理層,前者將其做爲兩層,後者將其合併爲一層稱爲網絡接口層。通常做爲面試題的話都是須要講出OSI七層模型的。面試

各個分層的含義以及它們之間的關係用這張圖表示:算法

Http協議

http協議特性

  • HTTP 協議構建於 TCP/IP 協議之上,是一個應用層協議,默認端口號是 80
  • 靈活:HTTP容許傳輸任意類型的數據對象。正在傳輸的類型由Content-Type加以標記。
  • 無狀態:無鏈接的含義是限制每次鏈接只處理一個請求。服務器處理完客戶的請求,並收到客戶的應答後,即斷開鏈接。
  • 無狀態:HTTP協議是無狀態協議。無狀態是指協議對於事務處理沒有記憶能力。缺乏狀態意味着若是後續處理須要前面的信息,則它必須重傳。

請求方法

  • GET:請求獲取Request-URI標識的資源,請求參數附加在url上,明文展現。數據庫

  • POST:在Request-URI所標識的資源後附加新的數據,經常使用於修改服務器資源或者提交資源到服務器。POST請求體是放到body中的,能夠指定編碼方式,更加安全。小程序

  • HEAD:請求獲取由Request-URI所標識的資源的響應消息報頭。後端

  • PUT:請求服務器存儲一個資源,並用Request-URI做爲其標識。瀏覽器

  • DELETE:請求服務器刪除Request-URI所標識的資源。緩存

  • TRACE:請求服務器回送收到的請求信息,主要用於測試或診斷。

  • OPTIONS:請求查詢服務器的性能,或者查詢與資源相關的選項和需求。

請求和響應報文

以該連接爲例:zhangferry.com/2019/08/31/…

在Chrome查看其請求的Headers信息。

General

這裏標記了請求的URL,請求方法爲GET。狀態碼爲304,表明文件未修改,能夠直接使用緩存的文件。遠程地址爲185.199.111.153:443,此IP爲Github 服務器地址,是由於個人博客是部署在GitHub上的。

除了304還有別的狀態碼,分別是:

  • 200 OK 客戶端請求成功
  • 301 Moved Permanently 請求永久重定向
  • 302 Moved Temporarily 請求臨時重定向
  • 304 Not Modified 文件未修改,能夠直接使用緩存的文件。
  • 400 Bad Request 因爲客戶端請求有語法錯誤,不能被服務器所理解。
  • 401 Unauthorized 請求未經受權。這個狀態代碼必須和WWW-Authenticate報頭域一塊兒使用
  • 403 Forbidden 服務器收到請求,可是拒絕提供服務。服務器一般會在響應正文中給出不提供服務的緣由
  • 404 Not Found 請求的資源不存在,例如,輸入了錯誤的URL
  • 500 Internal Server Error 服務器發生不可預期的錯誤,致使沒法完成客戶端的請求。
  • 503 Service Unavailable 服務器當前不可以處理客戶端的請求,在一段時間以後,服務器可能會恢復正常。

Response Headers

content-encoding:用於指定壓縮算法

content-length:資源的大小,以十進制字節數表示。

content-type:指示資源的媒體類型。圖中所示內容類型爲html的文本類型,文字編碼方式爲utf-8

last-modified:上次內容修改的日期,爲6月8號

status:304 文件未修改狀態碼

注:其中content-type在響應頭中表明,須要解析的格式。在請求頭中表明上傳到服務器的內容格式。

Request Headers

:method:GET請求

:path:url路徑

:scheme:https請求

accept:通知服務器能夠返回的數據類型。

accept-encoding:編碼算法,一般是壓縮算法,可用於發送回的資源

accept-language:通知服務器預期發送回的語言類型。這是一個提示,並不必定由用戶徹底控制:服務器應該始終注意不要覆蓋用戶的顯式選擇(好比從下拉列表中選擇語言)。

cookie:瀏覽器cookie

user-agent:用戶代理,標記系統和瀏覽器內核

更多請求頭的字段含義能夠參考這裏:HTTP headers

TCP三次握手和四次揮手的過程以及爲何要有三次和四次

在瞭解TCP握手以前咱們先看下TCP的報文樣式:

其中控制位(Control Flag)標記着握手階段的各個狀態。

TCP三次握手

示意圖以下:

三次握手是指創建一個TCP鏈接時,須要客戶端和服務器總共發送3個數據包。

一、第一次握手(SYN=1, seq=x)

客戶端發送一個 TCP 的 SYN 標誌位置1的包,指明客戶端打算鏈接的服務器的端口,以及初始序號 X,保存在包頭的序列號(Sequence Number)字段裏。

發送完畢後,客戶端進入 SYN_SEND 狀態。

二、第二次握手(SYN=1, ACK=1, seq=y, ACKnum=x+1)

服務器發回確認包(ACK)應答。即 SYN 標誌位和 ACK 標誌位均爲1。服務器端選擇本身 ISN 序列號,放到 Seq 域裏,同時將確認序號(Acknowledgement Number)設置爲客戶的 ISN 加1,即X+1。 發送完畢後,服務器端進入 SYN_RCVD 狀態。

三、第三次握手(ACK=1, ACKnum=y+1)

客戶端再次發送確認包(ACK),SYN 標誌位爲0,ACK 標誌位爲1,而且把服務器發來 ACK 的序號字段+1,放在肯定字段中發送給對方,而且在數據段放寫ISN的+1

發送完畢後,客戶端進入 ESTABLISHED 狀態,當服務器端接收到這個包時,也進入 ESTABLISHED 狀態,TCP 握手結束。

問題一:爲何須要三次握手呢?

在謝希仁著的《計算機網絡》裏說,『爲了防止已失效的鏈接請求報文段忽然又傳送到了服務端,於是產生錯誤』。怎麼理解呢,咱們假設一種狀況,有一個創建鏈接的第一次握手的報文段由於滯留到網絡中過了較長時間才發送到服務端。這時服務器是要作ACK應答的,若是隻有兩次握手就表明鏈接創建,那服務器此時就要等待客戶端發送創建鏈接以後的數據。而這只是一個因滯留而廢棄的請求,是否是白白浪費了不少服務器資源。

從另外一個角度看這個問題,TCP是全雙工的通訊模式,須要保證兩端都已經創建可靠有效的鏈接。在三次握手過程當中,咱們能夠確認的狀態是:

第一次握手:服務器確認本身接收OK,服務端確認客戶端發送OK。

第二次握手:客戶端確認本身發送OK,客戶端確認本身接收OK,客戶端確認服務器發送OK,客戶端確認服務器接收OK。

第三次握手:服務器確認本身發送OK,服務器確認客戶端接收OK。

只有握手三次才能達到全雙工的目的:確認本身和對方都可以接收和發送消息。

TCP四次揮手

示意圖以下:

四次揮手錶示要發送四個包,揮手的目的是斷開鏈接。

一、第一次揮手(FIN=1, seq=x)

假設客戶端想要關閉鏈接,客戶端發送一個 FIN 標誌位置爲1的包,表示本身已經沒有數據能夠發送了,可是仍然能夠接受數據。

發送完畢後,客戶端進入 FIN_WAIT_1 狀態。

二、第二次揮手(ACK=1,ACKnum=x+1)

服務器端確認客戶端的 FIN 包,發送一個確認包,代表本身接受到了客戶端關閉鏈接的請求,但尚未準備好關閉鏈接。

發送完畢後,服務器端進入 CLOSE_WAIT 狀態,客戶端接收到這個確認包以後,進入 FIN_WAIT_2 狀態,等待服務器端關閉鏈接。

三、第三次揮手(FIN=1,seq=y)

服務器端準備好關閉鏈接時,向客戶端發送結束鏈接請求,FIN 置爲1。

發送完畢後,服務器端進入 LAST_ACK 狀態,等待來自客戶端的最後一個ACK。

四、第四次揮手(ACK=1,ACKnum=y+1)

客戶端接收到來自服務器端的關閉請求,發送一個確認包,並進入 TIME_WAIT狀態,等待可能出現的要求重傳的 ACK 包。

服務器端接收到這個確認包以後,關閉鏈接,進入 CLOSED 狀態。

客戶端等待了某個固定時間(兩個最大段生命週期,2MSL,2 Maximum Segment Lifetime)以後,沒有收到服務器端的 ACK ,認爲服務器端已經正常關閉鏈接,因而本身也關閉鏈接,進入 CLOSED 狀態。

問題一:爲何揮手須要四次呢?爲何不能將ACK和FIN報文一塊兒發送?

當服務器收到FIN報文時,極可能並不會當即關閉SOCKET,因此只能先回復一個ACK報文,告訴客戶端『你發的FIN我收到了』。只有等到服務端全部的報文都發送完了,才能發FIN報文,因此要將ACK和FIN分開發送,這就致使須要四次揮手。

問題二:爲何TIMED_WAIT以後要等2MSL才進入CLOSED狀態?

MSL是TCP報文的最大生命週期,由於TIME_WAIT持續在2MSL就能夠保證在兩個傳輸方向上的還沒有接收到或者遲到的報文段已經消失,同時也是在理論上保證最後一個報文可靠到達。假設最後一個ACK丟失,那麼服務器會再重發一個FIN,這是雖然客戶端的進程不在了,可是TCP鏈接還在,仍然能夠重發LAST_ACK。

HTTPS的流程

HTTPS = HTTP + TLS/SSL,它使用的端口默認爲443,它的創建能夠用下圖表示:

一、客戶端首次請求服務器,告訴服務器本身支持的協議版本,支持的加密算法及壓縮算法,並生成一個隨機數(client random)告知服務器。

二、服務器確認雙方使用的加密方法,並返回給客戶端證書以及一個服務器生成的隨機數(server random)

三、客戶端收到證書後,首先驗證證書的有效性,而後生成一個新的隨機數(premaster secret),並使用數字證書中的公鑰,加密這個隨機數,發送給服務器。

四、服務器接收到加密後的隨機數後,使用私鑰進行解密,獲取這個隨機數(premaster secret

五、服務器和客戶端根據約定的加密方法,使用前面的三個隨機數(client random, server random, premaster secret),生成『對話密鑰』(session key),用來加密接下來的整個對話過程(對稱加密)。

有一篇由淺入深介紹HTTPS的文章能夠閱讀一下:看圖學HTTPS

問題一:爲何握手過程須要三個隨機數,並且安全性只取決於第三個隨機數?

前兩個隨機數是明文傳輸,存在被攔截的風險,第三個隨機數是經過證書公鑰加密的,只有它是通過加密的,因此它保證了整個流程的安全性。前兩個隨機數的目的是爲了保證最終對話密鑰的『更加隨機性』。

問題二:Charles如何實現HTTPS的攔截?

Charles要實現對https的攔截,須要在客戶端安裝Charles的證書並信任它,而後Charles扮演中間人,在客戶端面前充當服務器,在服務器面前充當客戶端。

問題三:爲何有些HTTPS請求(例如微信)抓包結果還是加密的,如何實現的?

我在聊天過程當中並無抓到會話的請求,在小程序啓動的時候到是抓到了一個加密內容。我手動觸發該連接會下載一個加密文件,我猜想這種加密是內容層面的加密,它的解密是由客戶端完成的,而不是在HTTPS創建過程完成的。

另外在研究這個問題的過程當中,又發現了一些有趣的問題:

一、圖中所示的三個https請求分別對應三個不一樣類型的圖標,它們分別表明什麼意思呢?

二、第三個請求https://mtalk.google.com:5228圖標和請求內容都加了鎖,這個加鎖是在https之上又加了一層鎖嗎?

這些問題暫時沒有確切的答案,但願瞭解的小夥伴告知一下哈。

DNS解析流程

DNS(Domain name system)域名系統。DNS是因特網上做爲域名和IP地址相互映射的一個分佈式數據庫,可以使用戶經過域名訪問到對應的服務器(IP地址)。具體的解析流程是這樣的:

一、瀏覽器中輸入想要訪問的網站域名,操做系統會檢查本地hosts文件是否有這個網址的映射關係,若是有就調用這個IP地址映射,完成域名解析。沒有的話就走第二步。

二、客戶端迴向本地DNS服務器發起查詢,若是本地DNS服務器收到請求,並能夠在本地配置區域資源中查到該域名,就將對應結果返回爲給客戶端。若是沒有就走第三步。

三、根據本地DNS服務器的設置,採用遞歸或者迭代查詢,直至解析完成。

其中遞歸查詢和迭代查詢能夠用以下兩圖表示。

遞歸查詢

如圖所示,遞歸查詢是由DNS服務器一級一級查詢傳遞的。

迭代查詢

若是所示,迭代查詢是找到指定DNS服務器,由客戶端發起查詢。

DNS劫持

DNS劫持發生在DNS服務器上,當客戶端請求解析域名時將其導向錯誤的服務器(IP)地址。

常見的解決辦法是使用本身的解析服務器或者是將域名以IP地址的方式發出去以繞過DNS解析。

Cookie和Session的區別

HTTP 是無狀態協議,說明它不能以狀態來區分和管理請求和響應。也就是說,服務器單從網絡鏈接上無從知道客戶身份。

但是怎麼辦呢?就給客戶端們頒發一個通行證吧,每人一個,不管誰訪問都必須攜帶本身通行證。這樣服務器就能從通行證上確認客戶身份了。這就是Cookie的工做原理。

  • Cookie:Cookie是客戶端保存用戶信息的一種機制,用來記錄用戶的一些信息,實際上Cookie是服務器在本地機器上存儲的一小段文本,並隨着每次請求發送到服務器。Cookie技術經過請求和響應報文中寫入Cookie信息來控制客戶端的狀態。

  • Session:Session機制是一種服務器端的機制,服務器使用一種相似於散列表的結構來保存信息。當有用戶請求建立一個session時,服務器會先檢查這個客戶端裏是否已經包含了一個Session標識(session id),若是有就經過session id把session檢索出來。若是沒有就建立一個對應此Session的session id。這個session id會在本次響應中返回給客戶端。

二者有如下區別:

一、存儲位置:Cookie存放在客戶端上,Session數據存放在服務器上。

二、Session 的運行依賴 session id,而 session id 是存在 Cookie 中的,也就是說,若是瀏覽器禁用了 Cookie ,同時 Session 也會失效

三、安全性:Cookie存在瀏覽器中,可能會被一些程序複製,篡改;而Session存在服務器相對安全不少。

四、性能:Session會在必定時間內保存在服務器上,當訪問增多,會對服務器形成必定的壓力。考慮到減輕服務器壓力,應當使用Cookie

CDN是幹什麼用的

CDN(Content Delivery Network),根本做用是將網站的內容發佈到最接近用戶的網絡『邊緣』,以提升用戶訪問速度。歸納的來講:CDN = 鏡像(Mirror) + 緩存(Cache) + 總體負載均衡(GSLB)。

目前CDN都以緩存網站中的靜態數據爲主,如CSS、JS、圖片和靜態網頁等數據。用戶在從主站服務器請求到動態內容後再從CDN上下載這些靜態數據,從而加速網頁數據內容的下載速度,如淘寶有90%以上的數據都是由CDN來提供的。

CDN工做流程

一個用戶訪問某個靜態文件(如CSS),這個靜態文件的域名假如是www.baidu.com,而這個域名最終會被指向CDN全局中CDN負載均衡服務器,再由這個負載均衡服務器來最終分配是哪一個地方的訪問用戶,返回給離這個訪問用戶最近的CDN節點。以後用戶就直接去這個CDN節點訪問這個靜態文件了,若是這個節點中請求的文件不存在,就會再回到源站去獲取這個文件,而後再返回給用戶。

參考:深刻理解Http請求、DNS劫持與解析

Socket的做用

socket位於應用層和傳輸層之間:

它的做用是爲了應用層可以更方便的將數據經由傳輸層來傳輸。因此它的本質就是對TCP/IP的封裝,而後應用程序直接調用socket API便可進行通訊。上文中說的三次握手和四次揮手便是經過socket完成的。

咱們能夠從iOS中網絡庫分層找到BSD Sockets,它是位於CFNetwork之下。在CFNetwork中還有一個CFSocket,推測是對BSD Sockets的封裝。

WebRTC是幹什麼用的

WebRTC是一個能夠用在視頻聊天,音頻聊天或P2P文件分享等Web App中的 API。藉助WebRTC,你能夠在基於開放標準的應用程序中添加實時通訊功能。它支持在同級之間發送視頻,語音和通用數據,從而使開發人員可以構建功能強大的語音和視頻通訊解決方案。該技術可在全部現代瀏覽器以及全部主要平臺的本機客戶端上使用。WebRTC項目是開源的,並獲得Apple,Google,Microsoft和Mozilla等的支持。

若是某一請求只在某一地特定時刻失敗率較高,會有哪些緣由

這個是某公司二面時的問題,是一個開放性問題,我總結了如下幾點可能:

一、該時刻請求量過大

二、該地的網絡節點較不穩定

三、用戶行爲習慣,好比該時刻爲上班高峯期,或者某個羣體的特定習慣

若是有對網絡方面比較熟悉的小夥伴也能夠補充。

相關文章
相關標籤/搜索