- 面對對象
1. 三大特性:封裝,繼承,多態
2. 封裝性:數據和代碼捆綁在一起,避免外界干擾和不確定性訪問。封裝可以使得代碼模塊化。
3. 繼承性:讓某種類型對象獲得另一個類型對象的屬性和方法。繼承可以擴展已存在的代碼。
4. 多態性:同一事物表現出不同事物的能力,即向不同對象發送同一消息,不同的對象在接收時會產生不同的行為(重載實現編譯時多態,虛函數實現運行時多態)。多態的目的則是為了接口重用。
5. 多態的底層實現:C++多態性是通過虛函數來實現的,虛函數允許子類重新定義成員函數,而子類重新定義父類的做法稱為覆蓋(override),或者稱為重寫。
6. 多態的底層實現:在C++中,通過基類的引用(或指針)調用虛函數時,發生動態綁定,引用(或指針)既可以指向基類也可以指向派生類,引用和指針的靜態類型和動態類型可以不同,這是c++用以支持多態性的基石。
C++
1. STL(標准模板庫):
(1)STL的一個重要特點是數據結構和算法的分離
(2)STL另一個重要特性是它不是面向對象的。為了具有足夠通用性,STL主要依賴於模板而不是封裝,繼承和虛函數(多態性)——OOP的三個要素。你在STL中找不到任何明顯的類繼承關系。這好像是一種倒退,但這正好是使得STL的組件具有廣泛通用性的底層特征。另外,由於STL是基於模板,內聯函數的使用使得生成的代碼短小高效。
(3)從邏輯層次來看,在STL中體現了泛型化程序設計的思想,引入了諸多新的名詞。
(4)從實現層次看,整個STL是以一種類型參數化的方式實現的,這種方式基於一個在早先C++標准中沒有出現的語言特性--模板(template)。
2. STL中六大組件:(1)容器(2)迭代器(3)算法(4)仿函數(5)適配器(6)分配器
3. 容器:(1)序列式容器:vector,deque,list(2)關聯式容器:set/multiset,map/multimap
4. vector和list的區別:
(1)vector和數組類似,擁有一段連續的內存空間,並且起始地址不變。因此,它能夠高效地進行隨機存取,時間復雜度是O(1)。但是,因為其內存空間是連續的,所以在進行插入和刪除操作時,會造成內存塊的拷貝,因此時間復雜度為O(n)。另外,當數組內存空間不夠時,會重新申請一塊內動空間並進行內存拷貝。
(2)list是由雙向鏈表實現的,因此內存空間是不連續的。其只能通過指針訪問數據,所以list的隨機存取效率很低,時間復雜度為O(n)。不過由於鏈表自身的特點,能夠進行高效的插入和刪除。
(3)vector和list對於迭代器的支持不同。相同點在於,vector< int >::iterator和list< int >::iterator都重載了 “++ ”操作。而不同點在於,在vector中,iterator支持 ”+“、”+=“,”<"等操作。而list中則不支持。
5. vector的risize底層實現:每個動態數組都分配有一定容量,當存儲的數據達到容量的上限的時候,就重新分配內存。一般來說后面的內存已經被占用了,在后面增加是不可能的。resize是重新開辟了一個數組,把之前的值放到復制到新開辟的數組中來。
6. c++智能指針:
(1)c++里面的四個智能指針,auto_ptr,unique_ptr,shared_ptr,weak_ptr,其中后三個是c++11支持,並且第一個已經被c++11棄用
(2)使用原因:智能指針的作用是管理一個指針,因為存在以下這種情況:申請的空間在函數結束時忘記釋放,造成內存泄漏。使用智能指針可以很大程度上的避免這個問題,因為智能指針是一個類,當超出了類的實例對象的作用域時,會自動調用對象的析構函數,析構函數會自動釋放資源。所以智能指針的作用原理就是在函數結束時自動釋放內存空間,不需要手動釋放內存空間。
(3)auto_ptr:采用所有權模式。p2剝奪了p1的所有權,但是當程序運行時訪問p1將會報錯。所以auto_ptr的缺點是:存在潛在的內存崩潰問題。
(4)unique_ptr:實現獨占式擁有或嚴格擁有概念,保證同一時間內只有一個智能指針可以指向該對象。它對於避免資源泄露(例如“以new創建對象后因為發生異常而忘記調用delete”)特別有用,可以通過標准庫的move()函數實現指針轉移。
(5)shared_ptr:實現共享式擁有概念。多個智能指針可以指向相同對象,該對象和其相關資源會在“最后一個引用被銷毀”時候釋放。從名字share就可以看出了資源可以被多個指針共享,它使用計數機制來表明資源被幾個指針共享。
(6)weak_ptr:是一種不控制對象生命周期的智能指針, weak_ptr 設計的目的是為配合 shared_ptr 而引入的一種智能指針來協助 shared_ptr 工作, 它只可以從一個 shared_ptr 或另一個 weak_ptr 對象構造, 它的構造和析構不會引起引用記數的增加或減少。
7. Qt是一個跨平台的C++應用程序開發框架。它提供給開發者建立圖形用戶界面所需的功能,廣泛用於開發GUI程序,也可用於開發非GUI程序。Qt是完全面向對象的,很容易擴展,並且允許真正地組件編程。Qt使用標准的C++和特殊的代碼生成擴展(稱為元對象編譯器Meta Object Compiler, moc)以及一些宏。
8. 信號槽是 Qt 框架引以為豪的機制之一。所謂信號槽,實際就是觀察者模式。當某個事件發生之后,比如,按鈕檢測到自己被點擊了一下,它就會發出一個信號(signal)。這種發出是沒有目的的,類似廣播。如果有對象對這個信號感興趣,它就會使用連接(connect)函數,意思是,將想要處理的信號和自己的一個函數(稱為槽(slot))綁定來處理這個信號。也就是說,當信號發出時,被連接的槽函數會自動被回調。這就類似觀察者模式:當發生了感興趣的事件,某一個操作就會被自動觸發。(這里提一句,Qt 的信號槽使用了額外的處理來實現,並不是 GoF 經典的觀察者模式的實現方式。)
信號和槽是Qt特有的信息傳輸機制,是Qt設計程序的重要基礎,它可以讓互不干擾的對象建立一種聯系。
槽的本質是類的成員函數,其參數可以是任意類型的。和普通C++成員函數幾乎沒有區別,它可以是虛函數;也可以被重載;可以是公有的、保護的、私有的、也可以被其他C++成員函數調用。
唯一區別的是:槽可以與信號連接在一起,每當和槽連接的信號被發射的時候,就會調用這個槽。
9. 常見的設計模式:
(1)工廠模式:簡單工廠模式、工廠方法模式、抽象工廠模式。工廠模式的主要作用是封裝對象的創建,分離對象的創建和操作過程,用於批量管理對象的創建過程,便於程序的維護和擴展。
(2)單例模式:保證一個類只有一個實例,並提供一個訪問它的全局訪問點,使得系統中只有唯一的一個對象實例。常用於管理資源,如日志、線程池。
(3)策略模式:策略模式定義了一系列的算法,並將每一個算法封裝起來,而且使它們還可以相互替換。策略模式讓算法獨立於使用它的客戶而獨立變化。
10. c++11新特性:
(1)C++11 引入了 nullptr 關鍵字,專門用來區分空指針、0
(2)C++11 引入了 auto 和 decltype 這兩個關鍵字實現了類型推導,讓編譯器來操心變量的類型
(3)C++11 引入了基於范圍的迭代寫法,我們擁有了能夠寫出像 Python 一樣簡潔的循環語句。
(4)std::array 保存在棧內存中,相比堆內存中的 std::vector,我們能夠靈活的訪問這里面的元素,從而獲得更高的性能。std::array 會在編譯時創建一個固定大小的數組,std::array 不能夠被隱式的轉換成指針,使用 std::array只需指定其類型和大小即可
(5)C++11 引入了兩組無序容器:std::unordered_map/std::unordered_multimap 和 std::unordered_set/std::unordered_multiset。無序容器中的元素是不進行排序的,內部通過 Hash 表實現,插入和搜索元素的平均復雜度為 O(constant)。
- 數據結構
1. B+樹和B樹:
(1)B+樹非葉子節點只存儲key,只有葉子結點存儲value,葉子結點包含了這棵樹的所有鍵值,每個葉子結點有一個指向相鄰葉子結點的指針,這樣可以降低B樹的高度。
(2)B+樹相比於B樹的優勢:(1)B+樹單一節點存儲更多的元素,使得查詢的IO次數更少(2)B+樹所有查詢都要查找到葉子節點,查詢效率更加穩定(3)B+樹所有葉子節點形成有序鏈表,便於范圍查詢,更有利於對數據庫的掃描
2. B+樹和B-樹的區別:
(1)B-樹的葉bai子結點不含任何信息,而B+樹的葉子結點含信息
(2)B-樹上的葉子結點不會指向它的兄弟結點,而B+樹上的葉子結點會指向它的兄弟結點
(3)B-樹只能進行分區間查找,而B+樹上可以有兩種查找:順序查找和分區間查找
3. 紅黑樹的五大特性:
(1)節點是紅色或黑色。
(2)根節點是黑色。
(3)每個葉子節點都是黑色的空節點(NIL節點)。
(4)每個紅色節點的兩個子節點都是黑色。(從每個葉子到根的所有路徑上不能有兩個連續的紅色節點)
(5)從任一節點到其每個葉子的所有路徑都包含相同數目的黑色節點。
4. 紅黑樹插入刪除操作的三個后續操作:變色,左旋,右旋
5. 基本的排序算法有哪些:
(1)插入排序,時間復雜度O(n^2),空間復雜度O(1),穩定
思想:將無序序列中的各元素依次插入到已經有序的線性表中,從而得到一個新的序列
(2)希爾排序,時間復雜度O(nlog2n),空間復雜度O(1),不穩定
(3)快速排序,時間復雜度O(nlog2n),空間復雜度O(log2n),不穩定
(4)冒泡排序,時間復雜度O(n^2),空間復雜度O(1),穩定
(5)簡單排序,時間復雜度O(n^2),空間復雜度O(1),不穩定
(6)堆排序,時間復雜度O(nlog2n),空間復雜度O(1),不穩定
(7)歸並排序,時間復雜度O(nlog2n),空間復雜度O(n),穩定
6. 快速排序的思路:通過一趟排序將待排序記錄分割成獨的兩部分,其中一部分記錄的關鍵字均比另一部分記錄的關鍵字小,再分別對這兩部分記錄繼續進行排序,以達到整個序列有序
- 網絡編程
1. socket:即套接字,用於描述地址和端口,是一個通信鏈的句柄。應用程序通過socket向網絡發出請求或者回應。
2. sockets編程有三種:流式套接字(SOCK_STREAM),數據報套接字(SOCK_DGRAM),原始套接字(SOCK_RAW);前兩種較常用。基於TCP的socket編程是采用的流式套接字。
(1)SOCK_STREAM:字節流傳輸,表示面向連接的數據傳輸方式。數據可以准確無誤地到達另一台計算機,如果損壞或丟失,可以重新發送,但效率相對較慢。常用的HTTP協議就使用SOCK_STREAM傳輸數據,因為要確保數據的正確性,否則網頁不能正常解析。
(2)SOCK_DGRAM:數據報傳輸,表示無連接的數據傳輸方式。計算機只管傳輸數據,不作數據校驗,如果數據在傳輸中損壞,或者沒有到達另一台計算機,是沒有辦法補救的。也就是說,數據錯了就錯了,無法重傳。因為SOCK_DGRAM所做的校驗工作少,所以效率比SOCK_STREAM高。
3. 服務端:建立socket,聲明自身的端口號和地址並綁定到socket,使用listen打開監聽,然后不斷用accept去查看是否有連接,如果有,捕獲socket,並通過recv獲取消息的內容,通信完成后調用closeSocket關閉這個對應accept到的socket,如果不再需要等待任何客戶端連接,那么用closeSocket關閉掉自身的socket。
4. 客戶端:建立socket,通過端口號和地址確定目標服務器,使用Connect連接到服務器,send發送消息,等待處理,通信完成后調用closeSocket關閉socket
5. 高並發:服務器使用select函數,客戶端使用多線程
6. 同步和異步的區別:
(1)同步:所有的操作都做完,才返回給用戶。這樣用戶在線等待的時間太長,給用戶一種卡死了的感覺(就是系統遷移中,點擊了遷移,界面就不動了,但是程序還在執行,卡死了的感覺)。這種情況下,用戶不能關閉界面,如果關閉了,即遷移程序就中斷了。
(2)異步:將用戶請求放入消息隊列,並反饋給用戶,系統遷移程序已經啟動,你可以關閉瀏覽器了。然后程序再慢慢地去寫入數據庫去。這就是異步。但是用戶沒有卡死的感覺,會告訴你,你的請求系統已經響應了。你可以關閉界面了。
(3)同步,是所有的操作都做完,才返回給用戶結果。即寫完數據庫之后,再響應用戶,用戶體驗不好。異步,不用等所有操作都做完,就相應用戶請求。即先響應用戶請求,然后慢慢去寫數據庫,用戶體驗較好。
(4)為了避免短時間大量的數據庫操作,就使用緩存機制,也就是消息隊列。先將數據放入消息隊列,然后再慢慢寫入數據庫。引入消息隊列機制,雖然可以保證用戶請求的快速響應,但是並沒有使得我數據遷移的時間變短(即80萬條數據寫入mysql需要1個小時,用了redis之后,還是需要1個小時,只是保證用戶的請求的快速響應。用戶輸入完http url請求之后,就可以把瀏覽器關閉了,干別的去了。如果不用redis,瀏覽器不能關閉)。
- 計算機網絡
1. TCP為什么要進行三次握手:(1)因為信道不可靠,而 TCP 想在不可靠信道上建立可靠地傳輸,那么三次通信是理論上的最小值(2)因為雙方都需要確認對方收到了自己發送的序列號,確認過程最少要進行三次通信(3)為了防止已失效的連接請求報文段突然又傳送到了服務端,因而產生錯誤。

2. TCP 為什么要進行四次揮手:
因為 TCP 是全雙工模式,客戶端請求關閉連接后,客戶端向服務端的連接關閉(一二次揮手),服務端繼續傳輸之前沒傳完的數據給客戶端(數據傳輸),服務端向客戶端的連接關閉(三四次揮手)。所以 TCP 釋放連接時服務器的 ACK 和 FIN 是分開發送的(中間隔着數據傳輸),而 TCP 建立連接時服務器的 ACK 和 SYN 是一起發送的(第二次握手),所以 TCP 建立連接需要三次,而釋放連接則需要四次。
3. 擁塞控制:

TCP的擁塞控制:(1)原因:擁塞控制就是防止過多的數據注入到網絡中,可以使網絡中的路由器或鏈路不致過載(2)解決方法:慢啟動( slow-start );擁塞避免( congestion avoidance );快重傳( fast retransmit );快恢復( fast recovery)
4. TCP和UDP的區別:
(1)TCP面向連接、UDP是無連接的
(2)TCP提供可靠的服務,UDP不保證可靠交付
(3)TCP連接只能是點對點的,UDP支持一對多、多對一、多對多的交互通信
(4)TCP面向字節流(可能會出現黏包問題),UDP是面向報文的(不會出現黏包問題)
(5)UDP沒有擁塞控制,因此網絡出現擁塞不會使源主機的發送速率降低(對實時應用很有用,如IP電話,實時視頻會議等)
(6)TCP首部開銷20字節;UDP的首部開銷小,只有8字節
5. TCP的黏包問題:
(1)原因:TCP 是一個基於字節流的傳輸服務,“流” 意味着 TCP 所傳輸的數據是沒有邊界的,所以可能會出現兩個數據包黏在一起的情況
(2)解決辦法:發送定長包;包頭加上包體長度;在數據包之間設置邊界,如添加特殊符號 \r\n 標記;使用更加復雜的應用層協議
6. 基本I/O模型有哪些:(1)同步阻塞I/O模型(2)同步非阻塞I/O模型(3)I/O多路復用模型(4)信號驅動I/O模型(5)異步I/O模型
7. 進程:進程是對運行時程序的封裝,是系統進行資源調度和分配的基本單位,實現了操作系統的並發
- 操作系統
1. 進程:進程是對運行時程序的封裝,是系統進行資源調度和分配的基本單位,實現了操作系統的並發
2. 線程:線程是進程的子任務,是CPU調度和分派的基本單位
3. 進程和線程之間的區別:(1)一個程序至少有一個進程,一個進程至少有一個線程,線程依賴於進程而存在(2)進程在執行過程中擁有獨立的內存單元,而多個線程共享進程的內存
4. 進程的狀態:(1)就緒狀態(2)執行狀態(3)阻塞狀態
5. 進程間通信的幾種方式:(1)管道(2)消息隊列(3)共享內存(4)信號量(5)嵌套字
6. 進程調度算法:(1)先來先服務調度算法FCFS(2)最短作業優先調度算法SJF(3)高優先級調度算法HPF(4)時間片輪轉調度算法(可搶占的)RR(5)多級反饋隊列調度算法
7. 死鎖:兩個或多個進程無限期阻塞、 相互等待的一種狀態
8. 死鎖產生的四個必要條件:(1)互斥(2)占有並等待(3)非搶占(4)循環等待
9. 死鎖處理:
(1)預防死鎖:破壞產生死鎖的4個必要條件中的一個或者多個;實現起來比較簡單,但是如果限制過於嚴格會降低系統資源利用率以及吞吐量
(2)避免死鎖:在資源的動態分配中,防止系統進入不安全狀態
(3)監測死鎖
(4)解除死鎖:進程終止和資源搶占
