RxJava
參考文章
中文文檔
Flowable
RxLifecycle
面試題
- 內部線程切換原理
- 操作符有哪些
- 如何解決內存泄漏
- RxJava 中 Observable、Flowable、Single、Maybe、Completable 使用時如何選擇?
- 為什么 subscribeOn() 只有第一次切換有效
- 操作符 map 和 flatmap 的區(qū)別?
Okhttp
1. 攔截器順序?
自定義攔截器——>RetryAndFollowUpInterceptor——>BridgeInterceptor——>CacheInterceptor——>ConnectInterceptor
——>NetworkInterceptors——>CallServerInterceptor
2. 網(wǎng)絡攔截器和普通攔截器有什么區(qū)別?
網(wǎng)絡攔截器:
網(wǎng)絡攔截器可以操作重定向和失敗重連的返回值
取緩存中的數(shù)據(jù)就不會去執(zhí)行Chain.proceed().所以就不能執(zhí)行網(wǎng)絡攔截器
通過網(wǎng)絡攔截器可以觀察到所有通過網(wǎng)絡傳輸?shù)臄?shù)據(jù)
請求服務連接的攔截器先于網(wǎng)絡攔截器執(zhí)行,所以在進行網(wǎng)絡攔截器執(zhí)行時,就可以看到Request中服務器請求連接信息,因為應用攔截器是獲取不到對應的連接信息的。
普通攔截器:
應用攔截器只會調用一次,即使數(shù)據(jù)來源于緩存
不需要關心是否重定向或者失敗重連
只考慮應用的初始意圖,不去考慮Okhhtp注入的Header比如:if-None-Match,意思就是不管其他外在因素只考慮最終的返回結果
應用攔截器可以決定是否執(zhí)行其他的攔截器,通過Chain.proceed().
可以執(zhí)行多次調用其他攔截器,通過Chain.proceed().
3. 它的線程池是怎樣的?如何管理的?
核心線程:0
非核心線程:Int.MAX_VALUE
Keeplive:60s
4. 緩存實現(xiàn)
1、如果在 OKHttpClient 中配置了 cache,則從緩存中獲取,但是不保證就存在
2、拿到當前請求,緩存拿到緩存策略對象
3、緩存檢測
4、禁止使用網(wǎng)絡(根據(jù)緩存策略),緩存又無效,直接返回
5、緩存有效,不使用網(wǎng)絡
6、緩存無效,執(zhí)行下一個攔截器
7、本地有緩存,根具條件選擇使用哪個響應
8、使用網(wǎng)絡響應
9、 緩存到本地
6. 連接池
通過 ConnectInterceptor 攔截器實現(xiàn)連接操作,Recall的initExchange方法尋找一個可用的連接
ConnectionPool代理類RealConnectionPool控制所有的連接操作,默認最大連接數(shù)5個,默認?;顣r間5分鐘
7.Http連接?;?/h3>
http長連接
TCP
理解TCP序列號(Sequence Number)和確認號(Acknowledgment Number)
-
TCP如何保證數(shù)據(jù)包的順序
發(fā)送機在每次發(fā)送數(shù)據(jù)時,會給每個數(shù)據(jù)包分配一個序列號,并在特定的時間內等待接收機對發(fā)送機分配序列號的確認。
發(fā)送機將已經(jīng)發(fā)送的數(shù)據(jù)存儲在緩存中,如果特定時間內沒有收到接收機對發(fā)送機分配序列號的確認,則重復發(fā)送此數(shù)據(jù)包,如果在定時器超時之前收到確認,則將數(shù)據(jù)包占用的緩存釋放。
接收機收到數(shù)據(jù)包后按照序列號將數(shù)據(jù)包按順序重組,并傳給上層使用。
-
TCP如何實現(xiàn)可靠性傳輸?
1.應用數(shù)據(jù)被分割成TCP認為最適合發(fā)送的數(shù)據(jù)塊。這和UDP完全不同,應用程序產(chǎn)生的數(shù)據(jù)長度將保持不變。由TCP傳遞給IP的信息單位稱為報文段或段(segment)。
2.當TCP發(fā)出一個段后,它啟動一個定時器,等待目的端確認收到這個報文段。如果不能及時收到一個確認,將重發(fā)這個報文段。當TCP收到發(fā)自TCP連接另一端的數(shù)據(jù),它將發(fā)送一個確認。TCP有延遲確認的功能,在此功能沒有打開,則是立即確認。功能打開,則由定時器觸發(fā)確認時間點。
3.TCP將保持它首部和數(shù)據(jù)的檢驗和。這是一個端到端的檢驗和,目的是檢測數(shù)據(jù)在傳輸過程中的任何變化。如果收到段的檢驗和有差錯,TCP將丟棄這個報文段和不確認收到此報文段(希望發(fā)端超時并重發(fā))。
4.既然TCP報文段作為IP數(shù)據(jù)報來傳輸,而IP數(shù)據(jù)報的到達可能會失序,因此TCP報文段的到達也可能會失序。如果必要,TCP將對收到的數(shù)據(jù)進行重新排序,將收到的數(shù)據(jù)以正確的順序交給應用層。
5.既然IP數(shù)據(jù)報會發(fā)生重復,TCP的接收端必須丟棄重復的數(shù)據(jù)。[2]
6.TCP還能提供流量控制。TCP連接的每一方都有固定大小的緩沖空間。TCP的接收端只允許另一端發(fā)送接收端緩沖區(qū)所能接納的數(shù)據(jù)。這將防止較快主機致使較慢主機的緩沖區(qū)溢出。
-
如果TCP傳輸過程中服務器掛了會發(fā)生什么
-
服務器主機崩潰
模擬操作:當客戶端和服務器成功連接之后,拔掉服務器的網(wǎng)線,此時從客戶端發(fā)送數(shù)據(jù)分節(jié)。這樣同時也模擬了客戶端發(fā)送的數(shù)據(jù)不可達服務端的情景(即建立連接后某些中間路由器不工作)。
產(chǎn)生后果:客戶端會持續(xù)重傳未收到確認的數(shù)據(jù)分節(jié)(TCP軟件負責),持續(xù)一段時間后仍未收到確認則放棄(通常是9分鐘)。如果是服務器崩潰則本機TCP軟件會向用戶進程顯示套接字錯誤并置錯誤碼,如果是中間路由器判定服務器主機不可達則會返回一個ICMP消息,那么TCP軟件收到該ICMP消息會向用戶進程顯示套接子錯誤并置錯誤碼。我們可以通過錯誤碼來判斷到底是哪種錯誤。
-
服務器崩潰后重啟
模擬操作:當客戶端和服務器成功連接之后,拔掉服務器的網(wǎng)線,然后將該服務器關機重啟。再重新插上網(wǎng)線。
產(chǎn)生后果:當服務器崩潰后重啟時,它已經(jīng)丟失了崩潰前所有的連接信息,因此服務器對于所收到的客戶數(shù)據(jù)分節(jié)響應一個RST分節(jié)。客戶端的TCP軟件收到RST分節(jié)之后會向 用戶進程顯示套接字錯誤并置錯誤碼。
-
服務器主機關機
Unix系統(tǒng)關機時,init進程通常會給所有的進程發(fā)送SIGTERM信號,等待一段時間后如果還有一些進程仍在運行,init進程會發(fā)送SIGKILL信號強行終止。當服務器進程被終止時,其所有打開的文件描述符被關閉,會發(fā)送FIN分節(jié)給對端。設計良好的客戶程序可以立即監(jiān)視該種情況的發(fā)生。
-
Http/Https
-
現(xiàn)代瀏覽器在與服務器建立了一個 TCP 連接后是否會在一個 HTTP 請求完成后斷開?什么情況下會斷開?
答:現(xiàn)代瀏覽器在與服務器建立了一個 TCP 連接后是否會在一個 HTTP 請求完成后斷開?什么情況下會斷開? 在 HTTP/1.0 中,一個服務器在發(fā)送完一個 HTTP 響應后,會斷開 TCP 鏈接。但是這樣每次請求都會重新建立和斷開 TCP 連接,代價過大。所以雖然標準中沒有設定,某些服務器對 Connection: keep-alive 的 Header 進行了支持。意思是說,完成這個 HTTP 請求之后,不要斷開 HTTP 請求使用的 TCP 連接。這樣的好處是連接可以被重新使用,之后發(fā)送 HTTP 請求的時候不需要重新建立 TCP 連接,以及如果維持連接,那么 SSL 的開銷也可以避免
-
一個 TCP 連接可以對應幾個 HTTP 請求?
答:一個 TCP 連接是可以發(fā)送多個 HTTP 請求的。
-
一個 TCP 連接中 HTTP 請求發(fā)送可以一起發(fā)送么(比如一起發(fā)三個請求,再三個響應一起接收)?
答:HTTP/1.1 存在一個問題,單個 TCP 連接在同一時刻只能處理一個請求,意思是說:兩個請求的生命周期不能重疊,任意兩個 HTTP 請求從開始到結束的時間在同一個 TCP 連接里不能重疊。
雖然 HTTP/1.1 規(guī)范中規(guī)定了 Pipelining 來試圖解決這個問題,但是這個功能在瀏覽器中默認是關閉的。
HTTP2 提供了 Multiplexing 多路傳輸特性,可以在一個 TCP 連接中同時完成多個 HTTP 請求。
-
為什么有的時候刷新頁面不需要重新建立 SSL 連接?
答:TCP 連接有的時候會被瀏覽器和服務端維持一段時間。TCP 不需要重新建立,SSL 自然也會用之前的。
-
瀏覽器對同一 Host 建立 TCP 連接到數(shù)量有沒有限制?
答:有。Chrome 最多允許對同一個 Host 建立六個 TCP 連接。不同的瀏覽器有一些區(qū)別。