文章目錄
- 🍺 來源
- 🍺 C++
- 🍻 new 和 malloc 的區別?+2
- 🍻 delete 和 delete[] 的區別?+0
- 🍻 內存泄漏是什么?如何避免?+1
- 🍺 計算機網絡
- 🍻 URL 輸入后發生了什么?+1
- 🍻 TLS 握手的過程?+1
- 🍻 三次握手為什么不能為兩次?+1
- 🍻 四次揮手為什么不能為三次?+1
- 🍻 TCP 和 UCP 的區別?應用場景?+1
- 🍻 HTTP 1.0、1.1 和 2.0 的區別?
- 🍺 操作系統
- 🍻 進程、線程和協程的區別?+1
- 🍻 線程間的通信方式有哪些?+2
- 🍻 如何查看磁盤空間?+1
- 🍻 如何通過端口號查找進程?+1
- 🍻 缺頁中斷是什么?+0
- 🍺 MySQL
- 🍻 InnoDB 和 MylSAM 的區別?+1
- 🍻 索引的注意事項?+1
- 🍺 算法
- 🍻 實現線程池?+0
🍺 來源
[蘇小妍]、[快手]、
🍺 C++
🍻 new 和 malloc 的區別?+2
🔸 new 是 C++ 的關鍵字,需要編譯器支持;而 malloc 是庫函數,需要頭文件支持。
🔸 new 申請動態內存時不需要指定大小,編譯器會自動計算;而 malloc 申請動態內存時,需要手動計算大小。
🔸 new 分配內存成功時,會返回一個指向對象的指針;而 malloc 會返回一個 void* 類型的指針,需要強制類型轉換為其他類型。
🔸 new 分配內存失敗時,會拋出異常;而 malloc 則會返回 NULL。
🔸 new 分配內存時,會調用 operator new 申請足夠多的內存,然后調用對象的構造函數初始化成員變量;而 malloc 只能申請動態,無法進行對象的構造工作。
🍻 delete 和 delete[] 的區別?+0
🍻 內存泄漏是什么?如何避免?+1
🔸 內存泄漏通常是指堆中內存的泄漏,當使用 new,malloc 分配堆中內存時,使用完畢后未使用 delete,free 進行釋放,導致這塊內存就無法被再次使用。
🔸 采用記數法,當使用 new 或 malloc 時,讓計數器加一,當是用 delete 或 free 時,讓計數器減一,程序執行完畢后檢查計數器,如果不為 0 則存在內存泄漏。
🔸 析構函數需要聲明為虛函數,防止父類指針指向子類對象時,編輯器實施靜態綁定只會調用父類的析構函數,造成子類對象的析構不完全,導致內存泄漏。
🔸 使用智能指針,自動釋放動態內存,避免內存忘記釋放而導致的內存泄漏。
🍺 計算機網絡
🍻 URL 輸入后發生了什么?+1
🔸 首先瀏覽器會對 URL 進行解析,生成發送給服務器的請求報文。
🔸 查詢服務器域名對應的 IP 地址,瀏覽器會先查詢本地緩存,本地緩存沒有的話,就從通過 DNS 服務器進行查詢。
🔸 查詢到服務器的 IP 地址后,向服務器請求連接,進行 TCP 的三次握手,連接后始終保持通信。
🔸 期間瀏覽器可以向服務器發送 GET,POST 等請求,比如獲取、修改數據庫中的信息等。
🔸 服務器會對瀏覽器的請求進行處理,并生成響應報文發送給瀏覽器。
🔸 瀏覽器獲取響應報文,并進行內容的解析,渲染網頁呈現在屏幕上。
🍻 TLS 握手的過程?+1
🔸 TLS 采用混合加密機制,首先采用非對稱密鑰來加密用于傳輸的對稱密鑰,確保對稱密鑰傳輸的安全性。之后使用對稱密鑰來加密傳輸的數據,確保數據通信的效率。
🔸 首先客戶端會生成一個隨機數,給出協議版本號和自己支持的加密算法。
🔸 服務端確認好雙方的加密算法后,會生成一個隨機數,給出自己的數字證書。
🔸 客戶端確認數字證書有效后,會生成一個新的隨機數,并使用數字證書中的公鑰加密這個新隨機數。
🔸 服務端通過自己的私鑰,對客戶端發送來的新隨機數進行解密。
🔸 最后客戶端和服務端使用之前所生成的三個隨機數,生成對話密鑰,用來加密之后的整個對話過程。
🍻 三次握手為什么不能為兩次?+1
🔸 第一次握手主要是為了說明客戶端有發送的能力,服務端有接收的能力。第二,三次握手主要是為了說明服務端和客戶端具有發送和接收的能力。因此需要三次握手才能確保客戶端和服務端的發送接收能力都是正常的。
🔸 兩次握手還會出現歷史連接的問題。當客戶端發送的 SYN 被網絡阻塞,同時客戶端宕機時,客戶端重啟后會重新發送一個新的 SYN。由于服務端并不知道先前的 SYN 是歷史連接,會進行無效的數據傳輸,造成資源浪費。
🍻 四次揮手為什么不能為三次?+1
🔸 當服務器收到客戶端發送的 FIN 報文時,會先發送一個 ACK 表示自己已經收到信息。
🔸 但此時服務端可能還有數據沒有處理完,所以并不會馬上關閉連接。只有當服務端的數據全部處理完畢后,才發送 FIN 報文,因此這兩個報文通常不會合并發送。
🍻 TCP 和 UCP 的區別?應用場景?+1
🔸 TCP 是面向連接的協議,傳輸前需要先建立連接;而 UDP 可以不建立連接直接傳輸。
🔸 TCP 具有可靠性,數據可以無差錯,有序,完整的傳輸;而 UDP 是盡最大可能的交付,不具備可靠性。
🔸 TCP 是一對一的點到點服務;而 UDP 支持一對一,一對多,多對一的服務。
🔸 TCP 有流量控制,擁塞控制,可以調節發送方的發送速率;而 UDP 沒有。
🔸 TCP 首部長,開銷較大,至少 20 字節;而 UDP 首部較小,只有固定 8 字節。
🔸 TCP 是基于字節流的傳輸,無邊界但是有序;而 UDP 是基于包的傳輸,有邊界但是無序。
🔸 TCP 是面向連接且可靠的,因此主要用于文件傳輸這種對數據完整性要求高的場景;而 UDP 是無連接不可靠但數據傳輸比較快的,可以用于音視頻通話這種對實時性要求比較高的場景。
🍻 HTTP 1.0、1.1 和 2.0 的區別?
🔸 HTTP 1.0 是一種無狀態協議,瀏覽器每次請求都需要與服務器建立一個 TCP 連接,處理完請求之后立即斷開連接,不記錄過去的狀態。
🔸 HTTP 1.1 支持長連接,在一個 TCP 連接期間可以同時處理多個 HTTP 請求和響應,減少了網絡延遲。
🔸 HTTP 2 增加了二進制分幀,多路復用和請求優先級等功能,網絡的傳輸效率得到很大的提高。
🍺 操作系統
🍻 進程、線程和協程的區別?+1
🔸 進程是資源分配的基本單位;線程是 CPU 調度的基本單位;協程是輕量級線程,是線程內部調度的基本單位。
🔸 進程擁有 CPU 資源,內存資源,文件資源等;而線程和協程只擁有自己的寄存器,棧等資源。
🔸 進程和線程的切換內容都保存在用戶態,切換時會涉及到用戶態到內核態的切換,但是因為線程需要的切換內容比較少,所以效率會更高些;協程的切換內容保存在用戶態中,不涉及用戶態到內核態的切換,因此切換效率更高。
🔸 進程和線程的切換者是操作系統,切換時機由系統決定;而協程的切換者是用戶,切換時機由用戶來決定。
🍻 線程間的通信方式有哪些?+2
🔸 線程之間資源共享,所以線程間通信的主要目的是為了線程同步。
🔸 互斥鎖:它是為了在任意時間內,僅有一個線程可以訪問共享資源。比如當線程 A 加鎖成功時,那么線程 B 再加鎖就會失敗并進入阻塞睡眠狀態,并會釋放 CPU 讓給其他線程。等待鎖被釋放后,內核會喚醒線程 B 去加鎖繼續執行業務。
🔸 自旋鎖:它也是為了在任意時間內,僅有一個線程可以訪問共享資源。但是當線程獲取自旋鎖失敗時,不會立即釋放CPU,而是一直循環嘗試獲取鎖,直到獲取鎖成功。因此自旋鎖一般用于加鎖時間很短的場景,減少了線程上下文切換的開銷。
🔸 讀寫鎖:它由讀鎖和寫鎖兩部分構成,如果只讀取共享資源用讀鎖加鎖,如果需要修改共享資源則需要用寫鎖加鎖,可以同時有多個線程進行讀,但是最多只能有一個線程進行寫。它主要用于可以明確區分讀操作和寫操作的場景,在讀多寫少的場景下可以發揮出優勢。
🔸 條件變量:條件變量是一種同步機制,可能使線程進入阻塞狀態,并在滿足某個條件時解除阻塞繼續執行業務。
🔸 信號量:它是一個整形的計數器,主要用于實現進程間的互斥和同步。信號量的值代表可用資源的數量,控制信號量的方式有 P 操作和 V 操作,分別發生在進入共享資源,離開共享資源時。
🔸 信號:它是線程間的一種異步通信機制,可以在任何時候發送信號給某一線程。信號的來源有硬件來源(ctrl+c 終止進程)和軟件來源(kill 命令)等。
🍻 如何查看磁盤空間?+1
🔸 可以用 df 和 du 命令查看磁盤空間。
🔸 df 以磁盤分區為單位查看文件系統,可以獲取硬盤被占用了多少空間,還剩下多少空間。
🔸 du 用于查看當前目錄下磁盤空間的使用情況。
🍻 如何通過端口號查找進程?+1
🔸 可以通過 ps 和 netstat 查找到進程。
🔸
ps -ef | grep $pid
🔸netstat -ntp | grep $pid
🍻 缺頁中斷是什么?+0
🍺 MySQL
🍻 InnoDB 和 MylSAM 的區別?+1
🔸 InnoDB 支持事務,具有 ACID 屬性;而 MyISAM 不支持事務,適用于讀多寫少的場景。
🔸 InnoDB 支持行級鎖,僅鎖定實際需要的數據;而 MyISAM 只支持表級鎖,需要對整張表鎖定。
🔸 InnoDB 支持外鍵,建立表與表之間的聯系,保障了數據的完整性;而 MyISAM 不支持外鍵。
🔸 InnoDB 在崩潰后可以自動恢復;MyISAM 崩潰后需要手動恢復,比較麻煩。
🔸 InnoDB 支持熱備份,即在數據庫運行的時候進行備份;MyISAM 只支持冷備份。
🍻 索引的注意事項?+1
🔸 不要在列上使用函數,運算符,否定操作符,這將會導致索引失效而進行全局掃描。
🔸 進行單列的索引合不能有效提高數據的查詢效率,應該使用多列的組合索引。
🔸 使用組合索引應該遵循最左前綴原則,即查詢中使用了組合索引的第一個字段,索引才會被使用。
🔸 如果索引中存在所查詢字段的值,此時會使用覆蓋索引,根據索引的查詢結果直接返回數據,而不需要回表二次查詢。
🔸 對于某一列如果有 NULL 值存在,則不會去使用索引。對于組合索引,只要某列出現 NULL 值,該列對于組合索引就是無效的。
🔸 當查詢條件左右兩端的數據類型不匹配時,會進行隱式類型轉換,可能會導致索引失效而全表掃描。
🔸 當使用 like 進行模糊查詢時,查詢只有右邊有 % 的數據時支持索引,如果左右兩邊都有 % 會導致索引失效進行全表掃描。