360-c++開發(fā)面經(jīng)(一)
點(diǎn)擊藍(lán)字關(guān)注我們,獲取更多面經(jīng)



面向?qū)ο蟮娜筇匦裕悍庋b、繼承、多態(tài)
封裝:就是把客觀事物封裝成抽象的類,并且類可以把自己的數(shù)據(jù)和方法只讓可信的類或?qū)ο蟛僮鳎瑢?duì)不可信的進(jìn)行信息隱藏。一個(gè)類就是一個(gè)封裝了數(shù)據(jù)以及操作這些數(shù)據(jù)的代碼的邏輯實(shí)體。在一個(gè)對(duì)象內(nèi)部,某些代碼或某些數(shù)據(jù)可以是私有的,不能被外界訪問。通過這種方式,對(duì)象內(nèi)部數(shù)據(jù)提供了不同級(jí)別的保護(hù),以防止程序中無關(guān)的部分意外的改變或錯(cuò)誤的使用了對(duì)象的私有部分。
繼承:指可以讓某個(gè)類型的對(duì)象獲得另一個(gè)類型的對(duì)象的屬性的方法。它支持按級(jí)分類的概念,它可以使用現(xiàn)有類的所有功能,并在無需重新編寫原來的類的情況下對(duì)這些功能進(jìn)行擴(kuò)展。通過繼承創(chuàng)建的新類稱為“子類”或“派生類”,被繼承的類稱為“基類”、“父類”或“超類”。繼承的實(shí)現(xiàn)過程,就是從一般到特殊的過程。要實(shí)現(xiàn)繼承,可以通過“繼承”和“組合”來實(shí)現(xiàn)。集成概念的實(shí)現(xiàn)方式有二類:實(shí)現(xiàn)繼承與接口繼承。
實(shí)現(xiàn)繼承:是指直接使用基類的屬性和方法而無需額外編碼的能力;
接口繼承:是指僅使用屬性和方法的名稱、但是子類必須提供實(shí)現(xiàn)的能力。
多態(tài):是指一個(gè)類實(shí)例的相同方法在不同情況下有不同表現(xiàn)形式。多態(tài)機(jī)制使具有不同內(nèi)部結(jié)構(gòu)的對(duì)象可以共享相同的外部接口。這意味著,雖然針對(duì)不同對(duì)象的具體操作不同,但通過一個(gè)公共的類,它們(那些操作)可以通過相同的方式予以調(diào)用。



屬性
new/delete是C++關(guān)鍵字,需要編譯器支持。malloc/free是庫函數(shù),需要頭文件支持。
參數(shù)
使用new操作符申請(qǐng)內(nèi)存分配時(shí)無須指定內(nèi)存塊的大小,編譯器會(huì)根據(jù)類型信息自行計(jì)算。而malloc則需要顯式地指出所需內(nèi)存的尺寸。
返回類型
new操作符內(nèi)存分配成功時(shí),返回的是對(duì)象類型的指針,類型嚴(yán)格與對(duì)象匹配,無須進(jìn)行類型轉(zhuǎn)換,故new是符合類型安全性的操作符。而malloc內(nèi)存分配成功則是返回void * ,需要通過強(qiáng)制類型轉(zhuǎn)換將void*指針轉(zhuǎn)換成我們需要的類型。
分配失敗
new內(nèi)存分配失敗時(shí),會(huì)拋出bac_alloc異常。malloc分配內(nèi)存失敗時(shí)返回NULL。
自定義類型
new會(huì)先調(diào)用operator new函數(shù),申請(qǐng)足夠的內(nèi)存(通常底層使用malloc實(shí)現(xiàn))。然后調(diào)用類型的構(gòu)造函數(shù),初始化成員變量,最后返回自定義類型指針。delete先調(diào)用析構(gòu)函數(shù),然后調(diào)用operator delete函數(shù)釋放內(nèi)存(通常底層使用free實(shí)現(xiàn))。
malloc/free是庫函數(shù),只能動(dòng)態(tài)的申請(qǐng)和釋放內(nèi)存,無法強(qiáng)制要求其做自定義類型對(duì)象構(gòu)造和析構(gòu)工作。
重載
C++允許重載new/delete操作符,特別的,布局new的就不需要為對(duì)象分配內(nèi)存,而是指定了一個(gè)地址作為內(nèi)存起始區(qū)域,new在這段內(nèi)存上為對(duì)象調(diào)用構(gòu)造函數(shù)完成初始化工作,并返回此地址。而malloc不允許重載。
內(nèi)存區(qū)域
new操作符從自由存儲(chǔ)區(qū)(free store)上為對(duì)象動(dòng)態(tài)分配內(nèi)存空間,而malloc函數(shù)從堆上動(dòng)態(tài)分配內(nèi)存。自由存儲(chǔ)區(qū)是C++基于new操作符的一個(gè)抽象概念,凡是通過new操作符進(jìn)行內(nèi)存申請(qǐng),該內(nèi)存即為自由存儲(chǔ)區(qū)。而堆是操作系統(tǒng)中的術(shù)語,是操作系統(tǒng)所維護(hù)的一塊特殊內(nèi)存,用于程序的內(nèi)存動(dòng)態(tài)分配,C語言使用malloc從堆上分配內(nèi)存,使用free釋放已分配的對(duì)應(yīng)內(nèi)存。自由存儲(chǔ)區(qū)不等于堆,如上所述,布局new就可以不位于堆中。


自旋鎖與互斥鎖有點(diǎn)類似,只是自旋鎖不會(huì)引起調(diào)用者睡眠,如果自旋鎖已經(jīng)被別的執(zhí)行單元保持,調(diào)用者就一直循環(huán)在那里看是 否該自旋鎖的保持者已經(jīng)釋放了鎖,"自旋"一詞就是因此而得名。其作用是為了解決某項(xiàng)資源的互斥使用。因?yàn)樽孕i不會(huì)引起調(diào)用者睡眠,所以自旋鎖的效率遠(yuǎn) 高于互斥鎖。雖然它的效率比互斥鎖高,但是它也有些不足之處:
1、自旋鎖一直占用CPU,他在未獲得鎖的情況下,一直運(yùn)行--自旋,所以占用著CPU,如果不能在很短的時(shí) 間內(nèi)獲得鎖,這無疑會(huì)使CPU效率降低。
2、在用自旋鎖時(shí)有可能造成死鎖,當(dāng)遞歸調(diào)用時(shí)有可能造成死鎖,調(diào)用有些其他函數(shù)也可能造成死鎖,如 copy_to_user()、copy_from_user()、kmalloc()等。
因此我們要慎重使用自旋鎖,自旋鎖只有在內(nèi)核可搶占式或SMP的情況下才真正需要,在單CPU且不可搶占式的內(nèi)核下,自旋鎖的操作為空操作。自旋鎖適用于鎖使用者保持鎖時(shí)間比較短的情況下。
兩種鎖的加鎖原理
互斥鎖:線程會(huì)從sleep(加鎖)——>running(解鎖),過程中有上下文的切換,cpu的搶占,信號(hào)的發(fā)送等開銷。
自旋鎖:線程一直是running(加鎖——>解鎖),死循環(huán)檢測(cè)鎖的標(biāo)志位,機(jī)制不復(fù)雜。
互斥鎖屬于sleep-waiting類型的鎖。例如在一個(gè)雙核的機(jī)器上有兩個(gè)線程(線程A和線程B),它們分別運(yùn)行在Core0和 Core1上。假設(shè)線程A想要通過pthread_mutex_lock操作去得到一個(gè)臨界區(qū)的鎖,而此時(shí)這個(gè)鎖正被線程B所持有,那么線程A就會(huì)被阻塞 (blocking),Core0 會(huì)在此時(shí)進(jìn)行上下文切換(Context Switch)將線程A置于等待隊(duì)列中,此時(shí)Core0就可以運(yùn)行其他的任務(wù)(例如另一個(gè)線程C)而不必進(jìn)行忙等待。而自旋鎖則不然,它屬于busy-waiting類型的鎖,如果線程A是使用pthread_spin_lock操作去請(qǐng)求鎖,那么線程A就會(huì)一直在 Core0上進(jìn)行忙等待并不停的進(jìn)行鎖請(qǐng)求,直到得到這個(gè)鎖為止。
兩種鎖的區(qū)別
互斥鎖的起始原始開銷要高于自旋鎖,但是基本是一勞永逸,臨界區(qū)持鎖時(shí)間的大小并不會(huì)對(duì)互斥鎖的開銷造成影響,而自旋鎖是死循環(huán)檢測(cè),加鎖全程消耗cpu,起始開銷雖然低于互斥鎖,但是隨著持鎖時(shí)間,加鎖的開銷是線性增長(zhǎng)。
兩種鎖的應(yīng)用
互斥鎖用于臨界區(qū)持鎖時(shí)間比較長(zhǎng)的操作,比如下面這些情況都可以考慮
1 臨界區(qū)有IO操作
2 臨界區(qū)代碼復(fù)雜或者循環(huán)量大
3 臨界區(qū)競(jìng)爭(zhēng)非常激烈
4 單核處理器
至于自旋鎖就主要用在臨界區(qū)持鎖時(shí)間非常短且CPU資源不緊張的情況下,自旋鎖一般用于多核的服務(wù)器。


1、class是引用類型,struct是值類型;
2、class可以繼承類、接口和被繼承,struct只能繼承接口,不能被繼承;
3、class有默認(rèn)的無參構(gòu)造函數(shù),有析構(gòu)函數(shù),struct沒有默認(rèn)的無參構(gòu)造函數(shù),且只能聲明有參的構(gòu)造函數(shù),沒有析構(gòu)函數(shù);
4、class可以使用abstract和sealed,有protected修飾符,struct不可以用abstract和sealed,沒有protected修飾符;
5、class必須使用new初始化,結(jié)構(gòu)可以不用new初始化;
6、class實(shí)例由垃圾回收機(jī)制來保證內(nèi)存的回收處理,而struct變量使用完后立即自動(dòng)解除內(nèi)存分配;
7、從職能觀點(diǎn)來看,class表現(xiàn)為行為,而struct常用于存儲(chǔ)數(shù)據(jù);
8、作為參數(shù)傳遞時(shí),class變量以按址方式傳遞,而struct變量是以按值方式傳遞的。
更多面經(jīng)
掃描二維碼
獲取更多面經(jīng)
扶搖就業(yè)
