做化學(xué)題的網(wǎng)站百度搜索廣告價(jià)格
TCP和UDP區(qū)別
TCP
- 面向連接。在傳輸數(shù)據(jù)之前,通信雙方需要先建立一個(gè)連接(三次握手)。
- 可靠性。TCP提供可靠的數(shù)據(jù)傳輸,它通過(guò)序列號(hào)、確認(rèn)應(yīng)答、重傳機(jī)制和校驗(yàn)和等技術(shù)確保數(shù)據(jù)的正確傳輸。
- 數(shù)據(jù)順序:TCP保證數(shù)據(jù)按發(fā)送書(shū)序到達(dá)接收端。即使數(shù)據(jù)包在傳輸過(guò)程中拆分和重組,接收端也會(huì)按正確順序組裝數(shù)據(jù)。
- 流量控制:TCP 提供流量控制機(jī)制,通過(guò)滑動(dòng)窗口協(xié)議調(diào)整數(shù)據(jù)傳輸速率,防止發(fā)送端過(guò)快發(fā)送數(shù)據(jù)而導(dǎo)致接收端處理不過(guò)來(lái)。
- 擁塞控制:TCP 包含擁塞控制機(jī)制,避免網(wǎng)絡(luò)擁塞,保證網(wǎng)絡(luò)資源的有效利用。
TCP三次握手
第三次是必須的,為了防止已經(jīng)失效的連接請(qǐng)求報(bào)文突然又傳送給服務(wù)端,然后發(fā)生錯(cuò)誤、
TCP三次握手是建立可靠連接的過(guò)程,包括:
- 客戶端向服務(wù)端發(fā)送連接請(qǐng)求報(bào)文段,包含自身數(shù)據(jù)通訊初始序號(hào),進(jìn)入SYS_SENT狀態(tài)。
- 服務(wù)器收到連接請(qǐng)求報(bào)文段后,如果同意,發(fā)送應(yīng)答,包含自身數(shù)據(jù)通訊初始序號(hào),進(jìn)入SYN-RECEVICED狀態(tài)。
- 客戶端收到應(yīng)答,最后向服務(wù)器端發(fā)送確認(rèn)報(bào)文,進(jìn)入ESTABISHED狀態(tài),此時(shí)成功建立長(zhǎng)連接。
TCP四次揮手是關(guān)閉連接的過(guò)程:
- 客戶端希望關(guān)閉連接,發(fā)送一個(gè)FIN包給服務(wù)器,表示數(shù)據(jù)發(fā)送完畢,不再發(fā)送數(shù)據(jù)。這時(shí)客戶端進(jìn)入FIN_WAIT_1狀態(tài)。
- 服務(wù)器收到FIN包后,發(fā)送一個(gè)ACK包給客戶端,表示確認(rèn)收到客戶端的FIN包,這個(gè)包包含對(duì)客戶端FIN包的確認(rèn)序列號(hào)。服務(wù)器進(jìn)入CLOSE_WAIT狀態(tài),客戶端收到這個(gè)ACK包后進(jìn)入FIN_WAIT_2狀態(tài)。
- 服務(wù)器希望關(guān)閉連接,發(fā)送一個(gè)FIN包給客戶端,表示數(shù)據(jù)發(fā)送完畢,不再發(fā)送數(shù)據(jù)。服務(wù)器進(jìn)入LAST_ACK狀態(tài)。
- 客戶端收到服務(wù)器的FIN包后,發(fā)送一個(gè)ACK包給服務(wù)器,表示確認(rèn)收到服務(wù)器的FIN包,包括確認(rèn)序號(hào)??蛻舳诉M(jìn)入TIME_WAIT狀態(tài),等待一段時(shí)間(通常是兩倍的最大段壽命,MSL),確保服務(wù)器收到ACK包后在進(jìn)入CLOSED狀態(tài)。
- 服務(wù)器收到ACK包后,立即進(jìn)入CLOSE狀態(tài),連接正式關(guān)閉。
delete和free的區(qū)別
- delete是操作符,而free是函數(shù)
- delete用于釋放new分配的空間,free用于釋放mallo、calloc、realloc分配的空間
- delete會(huì)調(diào)用對(duì)象的析構(gòu)函數(shù),free不會(huì)
- 調(diào)用delete之前不用檢查指針是否為空,調(diào)用free時(shí)需要檢查
什么是面向?qū)ο?/h3>
面向過(guò)程思想
完成一個(gè)需求的步驟:首先搞清楚做什么,然后分析怎么做,最后在通過(guò)代碼體現(xiàn)。一步一步去實(shí)現(xiàn),而具體的每一步都需要我們?nèi)?shí)現(xiàn)和操作。這些步驟相互調(diào)用和協(xié)作,從而完成需求。在上面的每一個(gè)具體步驟中我們都是參與者,并且需要面對(duì)具體的每一個(gè)步驟和過(guò)程,這就是面向過(guò)程最直接的體現(xiàn)。
面向過(guò)程編程,其實(shí)就是面向著具體的每一個(gè)步驟和過(guò)程,把每一個(gè)步驟和過(guò)程完成,然后由這些功能函數(shù)相互調(diào)用,完成需求。
面向?qū)ο笏枷?br /> 面向?qū)ο蟮乃枷胧潜M可能模擬人類的思維方式,使得軟件的開(kāi)發(fā)方法與過(guò)程盡可能接近人類認(rèn)識(shí)世界。
面向?qū)ο笠詫?duì)象為核心,該思想認(rèn)為程序由一系列對(duì)象組成。是一種更符合人類思維習(xí)慣的思想,可以將復(fù)雜的問(wèn)題簡(jiǎn)單化。
- 封裝:將事務(wù)的屬性和行為封裝在一起,也就是C++中的類,便于管理,提高代碼的復(fù)用性。事物的屬性和行為分別對(duì)應(yīng)類中的成員變量和成員方法。
- 繼承:通過(guò)繼承父類的屬性和方法實(shí)現(xiàn)代碼的重用和擴(kuò)展。
- 多態(tài):多個(gè)子類可以通過(guò)繼承同一個(gè)父類,并以不同方式實(shí)現(xiàn)父類的同一方法,從而使得同一個(gè)接口可以調(diào)用不同的實(shí)現(xiàn)。
C++的重載和重寫(xiě)
重載
- 重載指不同的函數(shù)用相同的函數(shù)名,但是參數(shù)的類型、個(gè)數(shù)或順序不同(參數(shù)列表不同)。調(diào)用的時(shí)候根據(jù)函數(shù)的參數(shù)來(lái)區(qū)別不同的函數(shù),函數(shù)重載跟返回值無(wú)關(guān)。
- 重載的規(guī)則——函數(shù)名相同——參數(shù)列表不同
- 重載用來(lái)實(shí)現(xiàn)靜態(tài)多態(tài)
- 重載是多個(gè)函數(shù)或同一個(gè)類中的方法,是平行關(guān)系。
重寫(xiě)
- 重寫(xiě)也叫覆蓋,是指在派生類中重新對(duì)基類中的虛函數(shù)重新實(shí)現(xiàn)。即函數(shù)名和參數(shù)都一樣,只是函數(shù)的實(shí)現(xiàn)體不一樣。
- 重寫(xiě)的規(guī)則——方法聲明必須完全與父類中被重寫(xiě)的方法相同——訪問(wèn)修飾符的權(quán)限要大于或等于父類中被重寫(xiě)的方法的訪問(wèn)修飾符——子類重寫(xiě)的方法可以加virtual,也可以不加。
- 重寫(xiě)用于實(shí)現(xiàn)動(dòng)態(tài)多態(tài)(根據(jù)調(diào)用方法的對(duì)象的類型不同來(lái)執(zhí)行不同的函數(shù))。
- 重寫(xiě)是父類和子類之間的關(guān)系,是垂直關(guān)系。
重載在編譯時(shí)會(huì)將同名的函數(shù)或方法根據(jù)某種規(guī)則生成不同的函數(shù)或方法名。
C++中重寫(xiě)可以用來(lái)實(shí)現(xiàn)動(dòng)態(tài)多態(tài)。父類中需要重寫(xiě)的方法要加上virtual關(guān)鍵字。虛函數(shù)實(shí)現(xiàn)的原理是采用虛函數(shù)表,多態(tài)中每個(gè)對(duì)象內(nèi)存都有一個(gè)虛函數(shù)指針,指向虛函數(shù)表,表中記錄的是該類的所有虛函數(shù)的入口地址,所以對(duì)象能根據(jù)它自身的類型調(diào)用不同的函數(shù)。
淺拷貝和深拷貝
- 淺拷貝又稱為值拷貝,將源對(duì)象的值拷貝到目標(biāo)對(duì)象中,如果對(duì)象中有某個(gè)成員是指針類型數(shù)據(jù),并且是在堆區(qū)創(chuàng)建,則使用淺拷貝僅僅拷貝的是這個(gè)指針變量的值,也就是在目標(biāo)對(duì)象中該類指針類型數(shù)據(jù)和源對(duì)象中的該成員指向的是同一塊堆空間。這樣會(huì)帶來(lái)一個(gè)問(wèn)題,在析構(gòu)函數(shù)中釋放堆區(qū)數(shù)據(jù),會(huì)被釋放多次。默認(rèn)的拷貝構(gòu)造函數(shù)和默認(rèn)的賦值運(yùn)算符重載都是淺拷貝。
- 深拷貝,深拷貝在拷貝的時(shí)候先開(kāi)辟出和源對(duì)象大小一樣的空間,然后將源對(duì)象里的內(nèi)容拷貝到目標(biāo)對(duì)象中區(qū),這樣指針成員就指向了不同的內(nèi)存位置。并且里面的內(nèi)容是一樣的,兩個(gè)對(duì)象先后調(diào)用析構(gòu)函數(shù),分別釋放自己指針成員指向的內(nèi)存。
深拷貝:每次增加一個(gè)指針,便申請(qǐng)一塊新的內(nèi)存,并讓這個(gè)指針指向新的內(nèi)存,深拷貝情況下,不會(huì)出現(xiàn)重復(fù)釋放同一塊內(nèi)存的錯(cuò)誤。
C++中的多態(tài)
- 靜態(tài)多態(tài):靜態(tài)多態(tài)是編譯器在編譯期間完成的,編譯器會(huì)根據(jù)實(shí)參類型來(lái)選擇調(diào)用合適的參數(shù),如果有合適的參數(shù)就調(diào)用,沒(méi)有的話就會(huì)發(fā)出警告或者報(bào)錯(cuò)。靜態(tài)多態(tài)有函數(shù)重載、運(yùn)算符重載、泛型編程等。
- 動(dòng)態(tài)多態(tài):動(dòng)態(tài)多態(tài)是在程序運(yùn)行時(shí)根據(jù)基類的引用(指針)指向的對(duì)象來(lái)確定自己具體該調(diào)用哪一個(gè)類的虛函數(shù)。當(dāng)父類指針指向父類對(duì)象時(shí),就調(diào)用父類中定義的虛函數(shù);當(dāng)父類指針指向子類對(duì)象時(shí),就調(diào)用子類中定義的虛函數(shù)。
動(dòng)態(tài)多態(tài)行為的表現(xiàn)效果為:
- 同樣的調(diào)用語(yǔ)句在實(shí)際運(yùn)行時(shí)有多種不同的表現(xiàn)形態(tài)。
- 實(shí)現(xiàn)動(dòng)態(tài)多態(tài)的條件:要有繼承關(guān)系——要有虛函數(shù)重寫(xiě)——要有父類指針指向子類對(duì)象。
動(dòng)態(tài)多態(tài)的實(shí)現(xiàn)原理:當(dāng)類中聲明虛函數(shù)時(shí),編譯器會(huì)在類中生成一個(gè)虛函數(shù)表,虛函數(shù)表是一個(gè)存儲(chǔ)類虛函數(shù)指針的數(shù)據(jù)結(jié)構(gòu),虛函數(shù)表是由編譯器自動(dòng)生成與維護(hù)的。
virtual 成員函數(shù)會(huì)被編譯器放入虛函數(shù)表中,存在虛函數(shù)時(shí),每個(gè)對(duì)象中都有一個(gè)指向虛函數(shù)表的指針。在多態(tài)調(diào)用時(shí),虛函數(shù)指針就會(huì)根據(jù)這個(gè)對(duì)象在對(duì)應(yīng)類的虛函數(shù)表中查找被調(diào)用的函數(shù),從而找到函數(shù)的入口地址。
虛函數(shù)的實(shí)現(xiàn)原理
C++中的虛函數(shù)的作用主要是實(shí)現(xiàn)了動(dòng)態(tài)多態(tài)的機(jī)制。
動(dòng)態(tài)多態(tài),簡(jiǎn)單的說(shuō)就是父類型的指針指向其子類的實(shí)例,然后通過(guò)父類的指針調(diào)用實(shí)際子類的成員函數(shù)。這種技術(shù)可以讓父類的指針有多種形態(tài),這是一種泛型技術(shù)。
虛函數(shù)實(shí)現(xiàn)原理
編譯器處理虛函數(shù)時(shí),給每個(gè)對(duì)象添加一個(gè)隱藏的成員。隱藏的成員是一個(gè)指針類型的數(shù)據(jù),指向的是函數(shù)地址數(shù)組,這個(gè)數(shù)組被稱為虛函數(shù)表。
虛函數(shù)表中存儲(chǔ)的是虛函數(shù)的地址。
如果派生類重寫(xiě)了基類中的虛函數(shù),則派生類對(duì)象的虛函數(shù)表中保存的是派生類的虛函數(shù)地址,如果派生類沒(méi)有重寫(xiě)基類中的虛函數(shù),則派生類對(duì)象的虛函數(shù)表中保存的是父類的虛函數(shù)地址。
使用虛函數(shù)時(shí),對(duì)于內(nèi)存和執(zhí)行速度方面會(huì)有一定的成本:
- 每個(gè)對(duì)象都會(huì)變大,變大的量為存儲(chǔ)虛函數(shù)表指針;
- 對(duì)于每個(gè)類,編譯器都會(huì)創(chuàng)建一個(gè)虛函數(shù)表;
- 對(duì)于每次調(diào)用虛函數(shù),都需要額外執(zhí)行一個(gè)操作,就是到表中查找虛函數(shù)地址。
純虛函數(shù)
純虛函數(shù)是一種特殊的虛函數(shù),它的格式是:虛函數(shù)不給出具體的實(shí)現(xiàn),也就是后面沒(méi)有大括號(hào)實(shí)現(xiàn)體,而在后面加上=0。
class A{virtual 返回類型 函數(shù)名(參數(shù)列表) = 0;
};
很多情況下,在基類中不能對(duì)虛函數(shù)給出具體的有意義的實(shí)現(xiàn),就可以把它聲明為純虛函數(shù),它的實(shí)現(xiàn)留給該基類的派生類去做。
如果一個(gè)類中有純虛函數(shù),那么這個(gè)類也被稱為抽象類,這種類不能實(shí)例化對(duì)象,也就是不能創(chuàng)建該類的對(duì)象。除非在派生類中實(shí)現(xiàn)所有基類中的純虛函數(shù),否則派生類也是抽象類,不能實(shí)例化對(duì)象。
虛析構(gòu)函數(shù)
當(dāng)通過(guò)基類指針刪除派生類對(duì)象時(shí),虛析構(gòu)函數(shù)可以確保派生類的析構(gòu)函數(shù)被正確調(diào)用。
如果基類的析構(gòu)函數(shù)不是虛函數(shù),通過(guò)基類指針刪除派生類對(duì)象,只會(huì)調(diào)用基類的析構(gòu)函數(shù),不會(huì)調(diào)用派生類的析構(gòu)函數(shù)。這可能導(dǎo)致資源泄露,因?yàn)榕缮愄赜械馁Y源沒(méi)有被正確釋放。
class Base{
public:virtual ~Base(){}
}
虛析構(gòu)函數(shù)的主要作用是為了防止泄露資源的釋放,防止內(nèi)存泄漏。
重載、重寫(xiě)、隱藏的區(qū)別
- 重載:在同一作用域中,同名函數(shù)的形式參數(shù)不同時(shí),構(gòu)成函數(shù)重載,與返回值類型無(wú)關(guān)。
- 重寫(xiě):指不同作用域中定義的同名函數(shù)構(gòu)成隱藏。派生類成員函數(shù)隱藏與其同名的基類成員函數(shù)、類成員函數(shù)隱藏全局外部函數(shù)
C++中的四種類型轉(zhuǎn)換
使用C風(fēng)格的類型轉(zhuǎn)換可以把想要的任何東西轉(zhuǎn)換成我們需要的類型,但是這種類型轉(zhuǎn)換太過(guò)松散,對(duì)于這種松散的情況,C++提供了更嚴(yán)格的類型轉(zhuǎn)換,可以提供更好的控制轉(zhuǎn)換過(guò)程,并添加4個(gè)類型轉(zhuǎn)換運(yùn)算符。
- static_cast:用于在相關(guān)類型之間進(jìn)行轉(zhuǎn)換,比如數(shù)值類型之間、枚舉類型與整形之間、以及指針類型的向上和向下轉(zhuǎn)換。編譯器檢查轉(zhuǎn)換是否合法,不會(huì)在運(yùn)行時(shí)檢查。
int i = 10;
double b = static_cat<double>(i);
- dynamic_cast:用于在繼承體系中的指針或引用類型之間的轉(zhuǎn)換,并且在運(yùn)行時(shí)進(jìn)行類型檢查。它只能用于有虛函數(shù)的多態(tài)基類。
- const_cast用于在同類型的const和非const之間進(jìn)行轉(zhuǎn)換。唯一可以用于去除const屬性的類型轉(zhuǎn)換操作符。
- reinterpret_cast:用于進(jìn)行低級(jí)別的重新解釋轉(zhuǎn)換。
STL常見(jiàn)容器
STL中容器分為順序容器、關(guān)聯(lián)式容器、容器適配器三種類型。
- 順序容器 容器并非排序的,元素的插入位置同元素的值無(wú)關(guān)。包含vector、deque、list。
vector:動(dòng)態(tài)數(shù)組 元素在內(nèi)存連續(xù)存放。隨機(jī)存取任何元素都能在常數(shù)時(shí)間內(nèi)完成。在尾端增刪元素具有較佳的性能。
deque:雙端隊(duì)列,元素在內(nèi)存連續(xù)存放,隨機(jī)存取任何元素都能在常數(shù)時(shí)間內(nèi)完成,在兩端增刪元素具有較佳性能。
list:雙向鏈表,元素在內(nèi)存不連續(xù)存放。在任何位置增刪元素都能在常數(shù)時(shí)間完成。不支持隨機(jī)存取。
- 關(guān)聯(lián)式容器,元素是排序的。
通常以平衡二叉樹(shù)實(shí)現(xiàn)。
set、multiset
map、multimap
map中存放的元素有且僅有兩個(gè)成員變量,一個(gè)名為first,另一個(gè)名為second,map根據(jù)first值對(duì)元素從小到大排序。
- 容器適配器
封裝了一些基本的容器,使之具備了新的函數(shù)功能,包含 stack、queue、priority_queue。 - stack:棧 棧是項(xiàng)的有限序列,并滿足序列中被刪除、檢索和修改的項(xiàng)只能是最進(jìn)插入序列的項(xiàng)(棧頂?shù)捻?xiàng)),后進(jìn)先出。 - queue:隊(duì)列 插入只可以在尾部進(jìn)行,刪除、檢索和修改只允許從頭部進(jìn)行,先進(jìn)先出。
priority_queue:優(yōu)先級(jí)隊(duì)列,內(nèi)部維持某種有序,然后保證優(yōu)先級(jí)最高的位于頭部,第一個(gè)出隊(duì)列。
默認(rèn)情況下,priority_queue是最大堆,即優(yōu)先級(jí)最高的元素是最大的元素。
循環(huán)隊(duì)列
循環(huán)隊(duì)列(Circular Queue),也稱為環(huán)形隊(duì)列,是一種常見(jiàn)的數(shù)據(jù)結(jié)構(gòu),用于在固定大小的緩沖區(qū)內(nèi)進(jìn)行數(shù)據(jù)存儲(chǔ)。
循環(huán)隊(duì)列的最大特點(diǎn)是首尾相連,當(dāng)隊(duì)列的尾部指針到達(dá)緩沖區(qū)的末尾時(shí),如果有空間空間,它會(huì)繞回到緩沖區(qū)的開(kāi)頭繼續(xù)存儲(chǔ)數(shù)據(jù)。
- 通常,循環(huán)隊(duì)列可以用一個(gè)固定大小的數(shù)組和兩個(gè)指針來(lái)表示,一個(gè)指向隊(duì)列的頭部(front),一個(gè)指向隊(duì)列的尾部(rear)。
- 初始化:初始化時(shí),隊(duì)列為空,頭尾指針都指向數(shù)組的同一個(gè)位置,通??梢赃x擇0位置。
- 隊(duì)列為空的條件是頭尾指針相等,并且沒(méi)有存儲(chǔ)任何元素。
- 隊(duì)列滿的條件是尾指針的下一個(gè)位置等于頭指針。
- 入隊(duì):將新元素加入到隊(duì)列尾部,并將尾指針后移。如果尾指針到達(dá)數(shù)組末尾,則環(huán)繞到數(shù)組開(kāi)頭。
- 出隊(duì):從隊(duì)列頭部取出元素,并將頭指針后移,如果頭指針到達(dá)數(shù)組末尾,則環(huán)繞到數(shù)組開(kāi)頭。