2021春招衝刺-1225
2021春招衝刺
12.25日
前言:今天的內容感覺難起來了,第一眼沒有一個會的,而且每個問題其實都值得單獨地寫一篇部落格來從原理性地記錄 > - <,但是為了歸納方便還是以後積累多了再專門再寫相關分類的部落格吧。
寫到單例模式的感想:太多了55555 從零開始學習所以這一篇寫了兩天才寫完
1.計算機網路 | TCP與UDP的區別
邊記錄邊學,參考了很多部落格,主要有 參考部落格1 | 參考部落格2 | 參考部落格3 | 鄒大佬的部落格
1.關於TCP/IP
在介紹TCP與UDP之前,首先要介紹一下TCP/IP。它是一個協議簇,而TCP與UDP正是其中有兩個具有代表性的傳輸層協議。TCP/IP按照自底向上可以分為四層: 鏈路層、網路層、傳輸層和應用層。
- 鏈路層: 負責封裝和解封裝IP報文,傳送和接受ARP/RARP報文等
- 網路層: 負責路由以及把分組報文傳送給目標網路或主機。
包括Internet協議(IP)、Internet控制資訊協議(ICMP)、地址解析協議(ARP)、反向地址解析協議(RARP) - 傳輸層: 負責對報文進行分組和重組,並以TCP或UDP協議格式封裝報文。
- 應用層: 負責向用戶提供應用程式比如:
- 超文字傳輸協議(HTTP): 全球資訊網的基本協議;
- 件傳輸(TFTP): 簡單檔案傳輸協議;
- 遠端登入(Telnet): 提供遠端訪問其它主機功能, 它允許使用者登入internet主機,並在這臺主機上執行命令;
- 域名系統(DNS): 該系統用於在internet中將域名及其公共廣播的網路節點轉換成IP地址。
- 網路管理(SMTP): 該協議提供了監控網路裝置的方法, 以及配置管理,統計資訊收集,效能管理及安全管理等;
2.UDP
UDP協議全稱是使用者資料報協議,在網路中它與TCP協議一樣用於處理資料包,是一種無連線的協議。在OSI模型中,在第四層——傳輸層,處於IP協議的上一層。
- 特點
- 無連線:
知道對端的IP和埠號就直接進行傳輸, 不需要建立連線。而TCP需要TCP在傳送資料前進行三次握手建立連線。
同時因此也不需要維護連線狀態,包括收發狀態等, 一臺服務機可同時向多個客戶機傳輸相同的訊息。 - 不可靠:
沒有確認機制, 沒有重傳機制,沒有擁塞機制; 如果因為網路故障該段無法發到對方, UDP協議層不會給應用層返回任何錯誤資訊而導致丟包。
同時不關心傳送端是否收到了資料,也對資料進行校驗與備份。 - 面向報文:
不能夠靈活的控制讀寫資料的次數和數量,應用層交給UDP多長的報文, UDP原樣傳送, 既不會拆分, 也不會合並,而是保留這些報文的邊界。因此,應用程式需要選擇合適的報文大小。 - 有單播,多播,廣播的功能:
UDP 不止支援一對一的傳輸方式,同樣支援一對多,多對多,多對一的方式,也就是說 UDP 提供了單播,多播,廣播的功能。 - 頭部開銷小:
UDP 的首部開銷小,只有 8 個位元組,比 TCP 的 20 個位元組的首部要少得多。
UDP 頭部包含了以下幾個資料:
1)兩個十六位的埠號,分別為源埠(可選欄位)和目標埠。
2)整個資料報文的長度(十六位)。
3)整個資料報文的檢驗和(IPv4 可選 欄位),該欄位用於發現頭部資訊和資料中的錯誤(十六位)。
因此 UDP 的頭部開銷小,只有八位元組,相比 TCP 的至少二十位元組要少得多,在傳輸資料報文時是很高效的。
- 無連線:
- 適用場景
對當前網路通訊質量要求不高的時候,實時性要求高的地方都可以看到 UDP 的身影,要求網路通訊速度儘量的快,這時就使用UDP。
3.TCP
TCP協議全稱是傳輸控制協議是一種面向連線的、可靠的、基於位元組流的傳輸層通訊協議,由 IETF 的RFC793定義。
-
TCP建立連線過程
三次握手特點:- 沒有應用層的資料 ,SYN這個標誌位只有在TCP建立連線時才會被置1 ,握手完成後SYN標誌位被置0。
第一次握手:
- 客戶端向服務端傳送連線請求報文段(SYN J)。該報文段中包含自身的資料通訊初始序號。請求傳送後,客戶端便進入 SYN-SENT(請求連線)狀態。
第二次握手:
- 服務端收到連線請求報文段後,如果同意連線,則會發送一個應答,該應答中也會包含自身的資料通訊初始序號(SYN K,ACK,seq,ack=J+1),傳送完成後便進入 SYN-RECEIVED 狀態。
第三次握手:
- 當客戶端收到連線同意的應答後,還要向服務端傳送一個確認報文(ACK,seq,ack=K+1)。傳送完畢,客戶端和服務端都進入ESTABLISHED狀態,此時連線建立成功。
Question:為什麼 TCP 建立連線需要三次握手,而不是兩次:
1.防止出現失效的連線請求報文段被服務端接收的情況,從而產生錯誤
2.客戶端連結超時,會重新發送一次連線請求。當兩個SYN都抵達傳送了ACK時,雖然第一個ACK會被放棄,但是伺服器端會分配資源並一直維持這個資源,造成浪費。
-
TCP斷開連線過程
揮手特點:- TCP 是全雙工的,在斷開連線時兩端都需要傳送 FIN 和 ACK。
第一次揮手:
- 當主機A(客戶端) 完成資料傳輸後,將控制位FIN置1,提出停止TCP連線的請求
第二次揮手:
- B(服務端) 收到連線釋放請求後,會告訴應用層要釋放 TCP 連結。然後會發送 ACK 包(ack M+1),並進入 CLOSE_WAIT 狀態。
- 此時表明 A 到 B 的連線已經釋放,不再接收 A 發的資料了。但是因為 TCP 連線是雙向的,所以 B 仍舊可以傳送資料給 A。
第三次揮手:
- B果此時還有沒發完的資料會繼續傳送,完畢後會向 A 傳送連線釋放請求(FIN N),然後 B 便進入 LAST-ACK 狀態。
第四次揮手:
- A 收到釋放請求後,向 B 傳送確認應答,此時 A 進入 TIME-WAIT 狀態。
- 該狀態會持續 2MSL(最大段生存期,指報文段在網路中生存的時間,超時會被拋棄) 時間,若該時間段內沒有 B 的重發請求的話,就進入 CLOSED 狀態。當 B 收到確認應答後,也便進入 CLOSED 狀態。
-
TCP頭部格式
- 源埠 16位;目標埠 16位;序列號 32位;迴應序號 32位;TCP頭長度 4位;reserved 6位;控制程式碼 6位;視窗大小 16位;偏移量 16位;校驗和 16位;選項 32位(可選);
- 這樣我們得出了TCP包頭的最小長度,為20位元組。
-
TCP特點
- 面向連線的運輸層協議: 傳送資料之前必須在兩端建立連線,即進行三次握手。
- 可靠傳輸:
- 提供擁塞控制,當網路出現擁塞的時候,TCP能夠減小向網路注入資料的速率和數量,緩解擁塞。
- 誤碼靠的是TCP的段編號以及確認號判斷丟包。TCP為了保證報文傳輸的可靠,就給每個包一個序號,同時序號也保證了傳送到接收端實體的包的按序接收。然後接收端實體對已成功收到的位元組發回一個相應的確認(ACK);如果傳送端實體在合理的往返時延(RTT)內未收到確認,那麼對應的資料(假設丟失了)將會被重傳。
- 提供全雙工通訊: TCP允許通訊雙方的應用程式在任何時候都能傳送資料,因為TCP連線的兩端都設有快取,用來臨時存放雙向通訊的資料。當然,TCP可以立即傳送一個數據段,也可以快取一段時間以便一次傳送更多的資料段(最大的資料段大小取決於MSS)
- 僅支援單播傳輸: 每條TCP傳輸連線只能有兩個端點,只能進行點對點的資料傳輸,不支援多播和廣播傳輸方式。
- 面向位元組流: TCP不像UDP一樣那樣一個個報文獨立地傳輸,而是在不保留報文邊界的情況下以位元組流方式進行傳輸。
-
TCP與UDP的區別
TCP UDP 是否連線 面向連線,建立連線3次握手,斷開連線4次揮手 無連線 是否可靠 可靠傳輸,使用流量控制和擁塞控制 不可靠傳輸,不使用流量控制和擁塞控制 連線物件個數 只能是一對一通訊 支援一對一,一對多,多對一和多對多互動通訊 傳輸方式 面向位元組流 面向報文 首部開銷 首部最小20位元組,最大60位元組 首部開銷小,僅8位元組 適用場景 適用於要求可靠傳輸的應用,例如檔案傳輸 適用於實時應用(IP電話、視訊會議、直播等)
2.設計模式 | 用Class與Function的方式分別實現一個單例模式的案例
要命啊,每次都要先從原理搞起。啥都沒學,甚至不會java,先去弄懂什麼是單例模式了(淚目)接下來的內容全部來自菜鳥教程以及 搬運部落格
單例模式
單例模式(Singleton Pattern)是 Java 中最簡單的設計模式之一。這種型別的設計模式屬於建立型模式,它提供了一種建立物件的最佳方式。
這種模式涉及到一個單一的類,該類負責建立自己的物件,同時確保只有單個物件被建立。這個類提供了一種訪問其唯一的物件的方式,可以直接訪問,不需要例項化該類的物件。
-
注意:
- 單例類只能有一個例項。
- 單例類必須自己建立自己的唯一例項。
- 單例類必須給所有其他物件提供這一例項。
-
實現:
- 將該類的構造方法定義為私有方法,這樣其他處的程式碼就無法通過呼叫該類的構造方法來例項化該類的物件,只有通過該類提供的靜態方法來得到該類的唯一例項;
- 在該類內提供一個靜態方法,當我們呼叫這個方法時,如果類持有的引用不為空就返回這個引用,如果類保持的引用為空就建立該類的例項並將例項的引用賦予該類保持的引用
-
優點
- 在記憶體裡只有一個例項,減少了記憶體的開銷,尤其是頻繁的建立和銷燬例項(比如管理學院首頁頁面快取)。
- 避免對資源的多重佔用(比如寫檔案操作)。
- 為整個系統提供一個全域性訪問點。
-
缺點
- 沒有介面,不能繼承,與單一職責原則衝突,一個類應該只關心內部邏輯,而不關心外面怎麼樣來例項化。
- 如果例項化的物件長時間不被利用,系統會認為該物件是垃圾而被回收,這可能會導致物件狀態的丟失;
- 濫用單例將帶來一些負面問題,如為了節省資源將資料庫連線池物件設計為的單例類,可能會導致共享連線池物件的程式過多而出現連線池溢位;
- 不適用於變化頻繁的物件;
-
適用場景
- 要求生產唯一序列號。
- 需要頻繁例項化然後銷燬的物件。
- 建立物件時耗時過多或者耗資源過多,但又經常用到的物件,比如 I/O 與資料庫的連線等。
- 方便資源相互通訊的環境。
-
構造方法 · 使用class
- 餓漢式:
在類裝載的時候就完成例項化。避免了執行緒同步問題。同樣,在類裝載的時候就完成例項化,沒有達到Lazy Loading的效果。如果從始至終從未使用過這個例項,則會造成記憶體的浪費。// 餓漢式單例 public class Singleton1 { // 指向自己例項的私有靜態引用,主動建立 private static Singleton1 singleton1 = new Singleton1(); // 私有的構造方法 private Singleton1(){} // 以自己例項為返回值的靜態的公有方法,靜態工廠方法 public static Singleton1 getSingleton1(){ return singleton1; } }
- 懶漢式:
單例例項被延遲載入,即只有在真正使用的時候才會例項化一個物件並交給自己的引用。但是隻能在單執行緒下使用。如果在多執行緒下,一個執行緒進入了if (singleton == null)判斷語句塊,還未來得及往下執行,另一個執行緒也通過了這個判斷語句,這時便會產生多個例項。所以在多執行緒環境下不可使用這種方式。
看了鄒大佬的部落格感覺有點像懶漢法,如果不存在就建立,存在就返回?。// 懶漢式單例 public class Singleton2 { // 指向自己例項的私有靜態引用 private static Singleton2 singleton2; // 私有的構造方法 private Singleton2(){} // 以自己例項為返回值的靜態的公有方法,靜態工廠方法 //當然,可以使用同步方法public static synchronized Singleton2 getInstance2(),但是效率不高 public static Singleton2 getSingleton2(){ // 被動建立,在真正需要使用時才去建立 if (singleton2 == null) { singleton2 = new Singleton2(); } return singleton2; } }
- c#提供的靜態初始化
//阻止發生派生,而派生可能會增加例項 public sealed class Singleton { private Singleton() { } //在第一次引用類的任何成員時建立例項,公共語言執行庫負責處理變數初始化 private static readonly Singleton instance=new Singleton(); public static Singleton GetInstance() { return instance; } }
- java內部類式單例類
public class Singleton { private Singleton(){} private class SingletonHoledr(){ private static Singleton instance = new Singleton(); } private static Singleton getInstance(){ return SingletonHoledr.instance; } }
- 雙檢鎖方法由於nstance = new Singleton()這行程式碼在不同編譯器上的行為是無法預知的,導致在很多平臺和優化編譯器上是錯誤的,在此就不記錄。其實是因為大半夜電腦沒電了,記錄一下function閉包實現就byebye
- 餓漢式:
-
構造方法 · 使用function
直接去學長部落格看了參考答案,即使用閉包的方法。function SingleDog() { this.show = function () { console.log('w w w w') } } SingleDog.getInstance = (function () { let instance = null return function () { if (!instance) { instance = new SingleDog() } return instance } })() let a = SingleDog.getInstance() let b = SingleDog.getInstance() console.log(a === b) // true
3.瀏覽器 | 什麼是迴流與重繪?
-
瀏覽器渲染的流程
這一點在16號關於css的問題中其實已經提到,此處在那基礎上進行一點補充- 在頁面載入時,瀏覽器解析html檔案,生成DOM Tree(含了所有HTML標籤,包括display:none隱藏,還有用JS動態新增的元素等)
- 瀏覽器解析CSS檔案生成CSSOM Tree
- 將Dom Tree和CSSOM Tree結合,生成Render Tree (render tree能識別樣式,且其中每個NODE都有自己的style,而且render tree不包含隱藏的節點。比如display:none的節點,還有head節點。因為這些節點不會用於呈現,而且不會影響呈現的)
- 根據Render Tree渲染繪製,將畫素渲染到螢幕上。
-
什麼是迴流(Layout)(又稱重排)
- 當渲染樹中的一部分或者全部因為元素的尺寸、佈局、隱藏等改變而需要重新構建的時候,這時候就會發生迴流,得到節點的幾何資訊(位置、大小)。
- 每個頁面都至少發生一次迴流,也就是頁面第一次載入的時候,因為此時正在構建render tree。
- 在迴流的時候,瀏覽器會使渲染樹中受到影響的元素部分失效,並重新繪製這個部分的渲染樹。
-
什麼是重繪(Painting)
- 完成迴流以後,瀏覽器會重新繪製受到影響的部分元素到螢幕中,這個過程就是重繪,得到節點的絕對畫素。
- 當render tree中的一些元素需要更新屬性,而這些屬性只是影響元素的外觀,風格,而不會影響佈局的,比如background-color。則就叫稱為重繪。
-
什麼時候發生迴流與重繪
- 發生迴流
- 新增或刪除可見的DOM元素
- 元素的位置發生變化
- 元素的尺寸發生變化(包括外邊距、內邊框、邊框大小、高度和寬度等)
- 內容發生變化,比如文字變化或圖片被另一個不同尺寸的圖片所替代
- 頁面第一次渲染的時候
- 瀏覽器的視窗尺寸變化(因為迴流是根據視口的大小來計算元素的位置和大小的)
- 發生迴流一定會引起重繪,但是重繪不一定發生迴流
- 比如背景色、文字色、可見性(可見性這裡特指形如visibility: hidden這樣不改變元素位置和存在性的、單純針對可見性的操作,注意與display:none進行區分)等
- 發生迴流
4.瀏覽器 | 瀏覽器中儲存資料的方案有哪幾種
5.css | 實現一個雪花飄落的動畫