字節后端
什么叫進程?什么叫線程?他倆有什么區別和聯系?
進程是操作系統進行資源分配和調度的基本單位,是一個程序關于某數據集合上的一次運行活動,是系統進行資源分配和調度的獨立單位。
線程是進程的一個執行流,是CPU調度和分派的基本單位,它比進程更小,被包含在進程之中,是進程中實際運行工作的單位。
區別:
地址空間和其他資源:進程有獨立的地址空間,一個進程崩潰后,在保護模式下不會對其他進程產生影響。而線程是進程的一部分,一個線程崩潰可能直接造成整個進程的崩潰。
資源分配:進程是資源分配的單元,線程是CPU調度的單元。
相互關系:沒有進程就沒有線程,一個進程至少有一個線程,稱為主線程,而多線程可以并發執行。
聯系:
線程的切換更快,資源開銷小,但是線程依賴于進程,因為線程是由進程來提供可執行環境和必需資源的。一個程序至少有一個進程,一個進程至少有一個線程。
介紹一下MySQL的索引有哪些?底層數據結構是什么?哪些場景下索引會失效?
MySQL的索引主要有以下幾種:
- B-Tree索引:也就是我們常說的索引,用于等值和范圍查詢,左側前綴查找;
- 哈希索引:只用于等值查詢,不能用于排序和部分查找;
- 空間數據索引:主要用于空間數據查詢,比如地理數據查找;
- 全文索引:用于全文搜索。
底層數據結構:
- B-Tree索引:采用B+樹數據結構;
- 哈希索引:采用哈希表;
- 空間數據索引:采用R-Tree;
- 全文索引:采用倒排索引。
索引會失效的場景包括:
- 使用!=或<>操作符;
- 對字段進行運算或函數操作;
- 使用LIKE '%XXX’這樣以通配符開頭的模糊查詢;
- 數據類型不一致,比如用字符串類型的字段去匹配數字類型的索引;
- 在WHERE子句中使用OR,除非OR條件中的每個列都進行了索引。
- 對于NULL的查詢通常不會使用索引。
你有在服務器上布置過程序嗎?怎么部署的?將C++代碼布置到服務器上的時候,他的代碼在服務器上是怎么運行起來的?
部署程序到服務器一般需經過以下幾個步驟:
- 編寫代碼:首先在本地環境上編寫和測試好您的C++代碼。
- 編譯代碼:使用C++編譯器(如g++)將你的代碼編譯成可執行文件。
- 移動文件:通過FTP工具(如FileZilla)、或scp命令,將編譯后的可執行文件上傳到服務器對應位置。
- 運行程序:在服務器上通過命令行,運行上一步中移動到服務器的可執行文件。
C++代碼在服務器上的運行原理:
- CPU 將可執行文件加載到內存,然后執行其中的機器碼,C++代碼在編譯階段已經被翻譯為機器碼。
- 可執行文件的執行,實際上是操作系統為此程序啟動一個進程,該進程才是真正執行機器碼的實體。
- 操作系統負責管理和調度進程,確保每一個進程都有執行的資源和時間,從而使得你的C++程序得以運行。
了解過集群的概念嗎?
集群是一種技術,通過這種技術,可以將多臺計算機聯結起來,使它們可以一起作業,以提供比單個計算機更高的處理速度、可靠性和可擴展性。
主要特點有:
- 高可靠性:任何一個節點出現故障,不會影響到整個集群系統的工作。當某個節點出現故障后,其它節點可以接管故障節點的工作。
- 高性能:采用多節點并行處理技術,性能可以通過簡單地增加節點數目而線性或者接近線性增加。
- 高可擴展性:可以根據需要方便地添加新的節點。
集群的主要類型包括負載均衡集群、高可用集群、計算集群等。
介紹一下虛擬內存
虛擬內存是計算機管理內存的一種技術,它允許操作系統將硬盤空間用作臨時的內存使用。這種技術使得計算機能夠運行比實際物理內存更多的程序,并通過內存分頁來提高程序的運行效率。
其主要特點包括:
- 內存擴展:虛擬內存擴展了計算機的可用內存空間,使得系統能運行更多程序。
- 內存隔離:確保每個程序在自己的地址空間運行,互不干擾。
- 數據保護:保護數據不被未經授權的程序訪問。
- 交換:將不頻繁使用的數據暫時存放到硬盤上,以釋放物理內存。
工作原理上,虛擬內存將硬盤的一部分空間作為擴展內存(稱為交換空間或頁文件),并通過頁面置換算法,將正在使用和不常使用的數據在物理內存和硬盤之間交換,以高效地利用有限的物理內存資源。
介紹一下https
HTTPS是HTTP的安全版。它是一種用于安全通信的網絡協議,通過在HTTP下加入SSL/TLS協議,為網站身份認證提供了一種保障,同時確保數據傳輸的隱私和完整性。簡而言之,HTTPS通過以下機制增加網絡安全:
- 加密:數據在傳輸過程中被加密,即使被截獲,數據也無法被讀取。
- 身份驗證:確保訪問者與網站服務器之間的數據交換是安全的,防止“中間人攻擊”。
- 數據完整性:確保數據在傳輸過程中未被篡改。
介紹一下TCP和UDP的區別
TCP(傳輸控制協議)和UDP(用戶數據報協議)是兩種主要的網絡傳輸協議,主要區別在于它們數據傳輸的可靠性和速度:
- 可靠性:TCP是一種面向連接的協議,提供數據包的有序傳送和錯誤檢查,保證數據的完整性,但速度相對較慢。相反,UDP是一種無連接的協議,不提供有序傳送和錯誤檢查,因此傳送速度更快,但可能丟失數據包。
- 連接性:TCP需要建立連接后才能進行數據傳輸,而UDP不需要預先建立連接。
- 數據包順序:TCP保證數據包的順序,而UDP不保證。
- 速度:由于TCP需要確認機制,相比于UDP,TCP的傳輸速度較慢。
- 使用場景:TCP常用于需要可靠傳輸的應用,如Web頁面傳輸,電子郵件傳輸等。而UDP則常用在實時應用(如語音和視頻通話,直播)和簡單查詢服務(如DNS)。
- 頭部大小:TCP頭部最小為20字節,UDP頭部固定為8字節,因此UDP整體上較為輕量。
代碼題:
1、搜索旋轉排序數組(leetcode 33)
在旋轉排序數組中搜索給定目標值的問題,可以使用二分查找方法高效解決。核心思想是分析目標值與中間值的關系,確定下一步查找的區間。下面是解題的步驟:
-
初始化:設置左指針
left
為0,右指針right
為nums.length - 1
。 -
二分查找:
-
計算中間位置
mid = (left + right) / 2
。 -
如果
nums[mid]
等于目標值target
,直接返回mid
。 -
分析
nums[left]
至
nums[mid]
是否是遞增:
-
如果是遞增,判斷
target
是否在
nums[left]
和
nums[mid]
之間:
- 如果是,調整
right
至mid - 1
。 - 否則,調整
left
至mid + 1
。
- 如果是,調整
-
如果不是遞增,判斷
target
是否在
nums[mid]
和
nums[right]
之間:
- 如果是,調整
left
至mid + 1
。 - 否則,調整
right
至mid - 1
。
- 如果是,調整
-
-
-
返回結果:如果沒找到返回
-1
。
這種方法能在O(log n)的時間復雜度內找到目標值的位置。
2、排序鏈表(leetcode 148)
可以通過歸并排序算法來高效解決,時間復雜度為O(nlogn),空間復雜度為O(1)。排序鏈表的歸并排序實現步驟如下:
- 尋找中點:使用快慢指針找到鏈表的中點,快指針速度是慢指針的兩倍,當快指針到達鏈表尾部時,慢指針正好在鏈表中點。
- 分割鏈表:將鏈表從中點分割為兩個子鏈表。
- 遞歸排序:對兩個子鏈表遞歸地進行歸并排序。
- 合并鏈表:將兩個排序后的子鏈表合并為一個有序鏈表。
騰訊實習 云架構平臺
c++中struct和class的區別
區別在于默認的訪問權限和繼承權限:
- 默認訪問權限:
struct
成員默認是public
的,class
成員默認是private
的。 - 默認繼承權限:
struct
繼承默認是public
的,class
繼承默認是private
的。
虛函數內部的實現
虛函數在C++內部是通過虛函數表和虛函數指針來實現的:
- 虛函數表:每個包含虛函數的類(或派生類)都有一個相應的虛函數表,這個表中儲存著該類的虛函數的地址。
- 虛函數指針:每個類的對象都會有一個指向虛函數表的指針,當調用虛函數時,編譯器會通過這個指針找到虛函數表,從表中獲取相應虛函數的地址,然后調用。
純虛函數
純虛函數是一種在基類中聲明但不實現的虛函數,其語法為:virtual ReturnType FunctionName(Parameters...) = 0;
。純虛函數的存在使得基類成為抽象類,不能直接實例化,要求任何派生自該基類的子類必須實現這個純虛函數,從而實現多態。
如何避免指針被雙重刪除
避免指針雙重刪除的常見方法:
- 置空:在刪除指針后,立即將其設置為NULL。這樣,即使對其進行第二次刪除操作(delete NULL是安全的),也不會引發問題。
- 智能指針:使用C++智能指針(如unique_ptr或shared_ptr)。這些智能指針在離開作用域時會自動釋放內存,從而避免了雙重刪除。
- 避免復制:避免將裸指針復制給多個指針變量,以防止錯誤地刪除同一段內存。
\n與endl的區別
\n
只負責換行,不會刷新緩沖區,因此輸出速度較快。endl
除了換行外,還會強制刷新緩沖區,確保輸出立即顯示,但相對較慢。
TCP完成服務監聽的步驟
socket()
:創建一個新的套接字。bind()
:將套接字綁定到一個本地地址和端口上。listen()
:使得套接字進入被動監聽狀態。accept()
:等待客戶端的連接請求,接受連接并創建一個新的套接字用于通信。
長連接和短鏈接的區別
- 長連接:連接建立后,客戶端和服務器之間的連接會保持活躍,可以進行多次數據交換,直到一方主動關閉連接。
- 短連接:每次通信后,一旦數據交換完成,連接即被關閉,下次通信時需要重新建立連接。
長連接的優缺點
長連接的優點:
- 減少了頻繁建立和關閉連接的開銷。
- 提高數據傳輸效率,減少延遲。
- 適合實時性較高的應用場景。
長連接的缺點:
- 占用服務器資源較多,可能影響服務器并發處理能力。
- 若不加管理,可能導致資源泄露。
- 需要心跳維護,增加了一定的復雜度。
TCP擁塞控制的實現方式
- 慢啟動:以指數方式增加擁塞窗口大小,直到達到閾值。
- 擁塞避免:增加擁塞窗口大小的速率放慢,轉為線性增長。
- 快速重傳:接收方連續收到三個重復確認時,發送方立即重傳丟失的包,而不是等待超時。
- 快速恢復:在快速重傳后,將擁塞閾值設為當前窗口大小的一半,從而快速恢復傳輸速率。
滑動窗口最大可以是多少
窗口大小字段:在TCP頭部中,窗口大小字段是一個16位的數,所以它的最大值理論上是2的16次方減1(65535字節)。
為什么在timewait之后還要等兩個msl
- 確保最后一個確認報文能夠到達對方。如果這個確認報文丟失,對方將重新發送最后一個FIN包,此時等待兩個MSL可以確保有足夠的時間接收并響應這個重傳的FIN包。
- 防止“老”連接的報文段出現在后續新的連接中。等待兩個MSL確保了所有當前連接的報文段都從網絡中消失,避免影響新的連接。
連接期間拔掉網線會出現什么情況
- 數據傳輸中斷:正在進行的數據傳輸會因為丟失網絡連接而中斷。
- 超時重傳:TCP具有超時重傳機制,如果在預定的時間內沒有收到確認應答,發送方會嘗試重傳數據包。
- 連接超時關閉:如果重傳嘗試持續失敗,并超過了特定的超時閾值,TCP連接將被認為已經斷開,并且會關閉該連接。
如果沒有開keep-alive會是什么情況
- 靜默中斷:連接看似還是建立的狀態,因為無法立即檢測到斷線。
- 無自動檢測:因為沒有定期的探測包來驗證連接狀態,所以TCP連接不會主動發現對方已經斷線。
- 應用層超時:通常依賴于應用層實現的超時機制來檢測連接健康狀況,并做出響應處理。
DNS解析的步驟
- 客戶端請求:瀏覽器或其他客戶端向本地DNS服務器發起域名解析請求。
- 本地DNS服務器查詢:本地DNS服務器首先查看自己的緩存,如果沒有相應記錄,則向根DNS服務器發起請求。
- 根DNS服務器響應:根DNS服務器不解析域名,而是返回負責該頂級域名(如.com、.net)的頂級域名服務器的地址。
- 頂級域名服務器查詢:本地DNS服務器再向頂級域名服務器查詢,頂級域名服務器返回負責該域名的權威DNS服務器的地址。
- 權威DNS服務器響應:本地DNS服務器最后向權威DNS服務器查詢,權威DNS服務器返回域名對應的IP地址。
- 客戶端獲取IP地址:本地DNS服務器將解析的結果返回給客戶端,客戶端得到IP地址后,就可以直接訪問該地址的服務器了。
http與https的區別
- 安全性:HTTPS比HTTP更安全,因為HTTPS在傳輸數據時加密,而HTTP傳輸的數據是未加密的。
- 端口:HTTP的默認端口是80,HTTPS的默認端口是443。
- 性能:由于加密解密過程,HTTPS在性能上稍微慢于HTTP。
- 證書:HTTPS需要使用SSL/TLS證書來建立安全連接,而HTTP不需要。
https建立連接的步驟
- 客戶端發起請求:瀏覽器(客戶端)向服務器發起HTTPS請求,請求建立SSL連接。
- 服務器響應:服務器返回帶有公鑰的SSL證書給客戶端。
- 創建對話密鑰:瀏覽器生成一個隨機對話密鑰,然后用服務器的公鑰加密這個密鑰,并發送給服務器。
- 對話密鑰解密:服務器用其私鑰解密上一步瀏覽器發送的內容,獲取到瀏覽器生成的對話密鑰。
- 加密通信:服務器和瀏覽器之后的通信都會基于這個對話密鑰來進行加密,以保護數據的安全性。
I/O多路復用的原理
I/O多路復用指的是使用單一的I/O線程來處理多個I/O讀寫操作。其核心原理如下:
- 注冊文件描述符:程序向操作系統注冊一系列的文件描述符(可以是套接字的描述符,也可以是其他I/O操作的描述符)及其對應的事件(如讀或寫)。
- 阻塞等待:I/O線程阻塞等待事件發生。事件可能是文件描述符就緒(可讀或可寫),也可能是定時器超時。
- 處理就緒事件:一旦有事件發生,I/O線程被喚醒并依次處理所有就緒事件。對于每個就緒事件,I/O線程執行操作(如讀或寫),然后返回等待下一個事件。
進程間調度的方法
- 先來先服務(FCFS):按照進程到達的順序進行調度。這種方法簡單,但可能會導致長進程阻塞短進程。
- 短進程優先(SJF):優先調度估計運行時間最短的進程。這種方法可以最小化平均等待時間,但需要對進程運行時間進行預測。
- 優先級調度:每個進程根據其重要性和類型分配一個優先級,優先級高的進程優先執行。
- 時間片輪轉:所有進程輪流使用CPU,每個進程執行一個固定長度的時間片,然后將CPU讓給下一個進程。
- 多級反饋隊列:根據進程的行為和需求,將其放入不同優先級的隊列中,然后按照某種策略(如時間片輪轉或優先級)在每個隊列中調度。
當一個進程正在讀寫文件時,文件管理員把文件刪掉了會出現什么情況
在大多數現代操作系統中,如果一個進程正在讀寫文件而同時該文件被刪除(通常是通過文件管理員或命令行等操作),則文件的目錄條目會被移除,但是文件的實際數據不會立即從磁盤上刪除。進程對文件的讀寫操作可以繼續進行,直到所有對該文件的引用都被關閉。只有當最后一個引用(比如打開的文件描述符)被關閉后,操作系統才會釋放文件所占用的空間。
多線程中鎖的類型
- **互斥鎖:最基本的鎖類型,同一時間只允許一個線程持有鎖。
- **遞歸鎖:允許同一個線程多次獲得同一個鎖,通常用于遞歸函數中。
- **讀寫鎖:使多個讀線程同時訪問共享資源,但寫線程訪問時獨占資源。
- 自旋鎖:通過循環等待來嘗試獲取鎖,適用于鎖定時間短的情況。
- **條件變量:不是鎖本身,但通常與鎖配合使用,用來阻塞一個線程直至某個條件為真。
- **信號量:允許多個線程訪問一定數量的資源實例,常用于限制對資源的并發訪問數。
互斥鎖與自旋鎖的區別
- **互斥鎖:當一個線程試圖獲取已經被其他線程獲取的互斥鎖時,該線程會被阻塞并進入睡眠狀態,直到鎖被釋放。因此,互斥鎖在發生阻塞時不會消耗CPU時間,適合用于保護長時間操作的臨界區資源。
- **自旋鎖:當一個線程試圖獲取已被其他線程獲取的自旋鎖時,該線程會進入忙等待狀態,不斷地檢查鎖是否被釋放,而不進入睡眠。這會持續消耗CPU時間,因此自旋鎖適用于保護短時間操作的臨界區資源,以避免由于上下文切換帶來的額外開銷。
MySQL數據庫中有哪幾種常見的索引
- **主鍵索引:唯一標識表中的每一行,不允許有重復值。
- 唯一索引: 確保數據的唯一性,不允許重復的索引值。
- 普通索引:加快數據檢索速度的基本索引。
- 全文索引:對文本內容進行索引,用于全文搜索。
- **組合索引:在多個列上創建的索引,用于多條件查詢優化。
數據庫的事務特性
- **原子性:事務是最小的執行單元,不可再分,要么全部執行,要么全部不執行。
- **一致性:事務執行前后,數據庫從一個一致性狀態轉換到另一個一致性狀態。
- 隔離性:事務的執行不應互相干擾,多個并發事務的執行應相互隔離。
- **持久性:一旦事務提交,則其所做的更改就會被永久保存到數據庫中,即使系統崩潰也不會丟失。
樂觀鎖和悲觀鎖
- **悲觀鎖:假設沖突很可能發生,在數據處理過程中通過鎖機制阻止其他事務訪問該數據。
- 樂觀鎖:假設沖突很少發生,不會立即鎖定數據,而是在提交更新前檢查數據在讀取后是否被更改過。常通過版本號或時間戳實現。
delete,truncate,drop的區別
- DELETE:從表中刪除一行或多行數據,可以搭配WHERE子句進行條件刪除,操作可回滾。
- TRUNCATE:刪除表中所有行,但保留表結構以便之后使用,操作速度快,但不可回滾。
- DROP:刪除整個表,包括數據和表結構,操作不可回滾。
如果有自增字段用哪種方法刪除
如果表中包含自增字段并且希望刪除所有數據同時重置自增計數器,應使用TRUNCATE
命令,因為它會重置自增計數器到初始值。使用DELETE
命令將不會重置自增計數器。
關系型數據庫與kv型數據庫的區別
- 關系型數據庫:數據以表格的形式儲存,數據間有豐富的關系,如一對一、一對多、多對多等。支持復雜的事務和查詢操作,并且有良好的ACID特性。
- KV型數據庫:即鍵值對數據庫,其中每個鍵和值都是一個數據項,相互間沒有關聯。讀寫性能高,易用于分布式系統,但不支持復雜查詢。
redis的數據結構
- **字符串:最常見類型,可以包括字符串、整數或浮點數。
- 列表:有序集合,可以實現堆棧、隊列等。
- 集合:無序且唯一的元素集合,可以快速完成交集、并集等操作。
- 哈希:鍵值對集合,適用于存儲對象。
- 有序集合:不僅是集合,還有每個元素關聯的分數,可以按分數排序輸出。
redis的持久化機制
- RDB:在指定的時間間隔內生成數據集的時間點快照。
- AOF:記錄服務器接收到的每個寫操作命令,服務器啟動時會重新執行這些命令來恢復數據。
算法題: LRU
算法題: 和為k的子數組
收集整理了一份2024年最新C++開發學習資料,既有適合小白學習的零基礎資料,也有適合3年以上經驗的小伙伴深入學習提升的進階課程,涵蓋了95%以上C++開發知識點,真正體系化!
包含大廠面經、學習筆記、實戰項目、大綱路線、講解視頻 領取地址:
https://docs.qq.com/doc/DR2N4d25LRG1leU9Q
網上學習資料一大堆,但如果學到的知識不成體系,遇到問題時只是淺嘗輒止,不再深入研究,那么很難做到真正的技術提升。