堆空間的內存是動態分配的,通常存放對象,而且須要手動釋放內存malloc()/free()或new/delete。linux
棧空間的內存是由系統自動分配,通常存放局部變量,好比對象的地址等值,不須要程序員對這塊內存進行管理,好比,函數中的局部變量的做用範圍(生命週期)就是在調完這個函數以後就結束了。程序員
指針常量——指針類型的常量(int *const p)。本質上一個常量,指針用來講明常量的類型,表示該常量是一個指針類型的常量。在指針常量中,指針自身的值是一個常量,不可改變,始終指向同一個地址。在定義的同時必須初始化。golang
常量指針——指向「常量」的指針(const int p, int const p)。常量指針本質上是一個指針,常量表示指針指向的內容,說明該指針指向一個「常量」。在常量指針中,指針指向的內容是不可改變的,指針看起來好像指向了一個常量。面試
須要C/C++ Linux高級服務器架構師學習資料後臺加羣812855908(包括C/C++,Linux,golang技術,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒體,CDN,P2P,K8S,Docker,TCP/IP,協程,DPDK,ffmpeg等)編程
結構體struct內存對齊的3大規則:數組
struct CAT_s { int ld; char Color; unsigned short Age; char *Name; void(*Jump)(void); }Garfield;
按照上面的3大規則直接來進行分析:服務器
聯合體union內存對齊的2大規則:數據結構
//x64 typedef union { long i; int k[5]; char c; }D
要計算union的大小,首先要找到佔用字節最多的成員,本例中是long,佔用8個字節,int k[5]中都是int類型,仍然是佔用4個字節的,而後union的字節數必須是佔用字節最多的成員的字節的倍數,並且須要可以容納其餘的成員,爲了要容納k(20個字節),就必需要保證是8的倍數的同時還要大於20個字節,因此是24個字節。架構
內存對齊做用:併發
TCP與UDP屬於傳輸層
vector stack queue set
C++ map用法參考連接
hash_map和map的區別參考連接
因爲電腦內存不夠,因此不能一次將數據所有讀取,只能實行分而治之的方法,才能知足空間的需求。能夠建立一個hash表,將數據按必定的Key value分類,可使用了將IP轉化成長整形,而後取其後三位轉化成字符串做爲Key value,這樣就能將全部IP按後三位分類。
1.概念
1)vector:
連續存儲的容器,動態數組,在堆上分配空間。
底層實現:數組。
兩倍容量增加:vector 增長(插入)新元素時,若是未超過當時的容量,則還有剩餘空間,那麼直接添加到最後(插入指定位置),而後調整迭代器。若是沒有剩餘空間了,則會從新配置原有元素個數的兩倍空間,而後將原空間元素經過複製的方式初始化新空間,再向新空間增長元素,最後析構並釋放原空間,以前的迭代器會失效。
性能:
訪問:時間複雜度O(1)
插入:在最後插入(空間夠):很快。時間複雜度O(1)。
在最後插入(空間不夠):須要內存申請和釋放,以及對以前數據進行拷貝。時間複雜度O(n)。
在中間插入(空間夠):內存拷貝
在中間插入(空間不夠):須要內存申請和釋放,以及對以前數據進行拷貝。
刪除:在最後刪除:很快。
在中間刪除:內存拷貝。
適用場景:常常隨機訪問,且不常常對非尾節點進行插入刪除。
2)list:
動態鏈表,在堆上分配空間,每插入一個元數都會分配空間,每刪除一個元素都會釋放空間。
底層:雙向鏈表。
性能:
訪問:隨機訪問性能不好,只能快速訪問頭尾節點。
插入:很快,通常是常數開銷。
刪除:很快,通常是常數開銷。
適用場景:常常插入刪除大量數據。
2.區別
3.應用
vector擁有一段連續的內存空間,所以支持隨機訪問,若是須要高效的隨即訪問,而不在意插入和刪除的效率,使用vector。
list擁有一段不連續的內存空間,若是須要高效的插入和刪除,而不關心隨機訪問,則應使用list。
重載:兩個函數名相同,可是參數列表不一樣(個數,類型),返回值類型沒有要求,在同一做用域中。
重載的實現是:編譯器根據函數不一樣的參數表,對同名函數的名稱作修飾,而後這些同名函數就成了不一樣的函數(至少對於編譯器來講是這樣的)。如,有兩個同名函數:function func(p:integer):integer;和function func(p:string):integer;。那麼編譯器作過修飾後的函數名稱多是這樣的:int_func、str_func。對於這兩個函數的調用,在編譯器間就已經肯定了,是靜態的(記住:是靜態)。也就是說,它們的地址在編譯期就綁定了(早綁定),所以,重載和多態無關!
覆蓋:子類繼承了父類,父類中的函數是虛函數,在子類中從新定義了這個虛函數
真正和多態相關的是「覆蓋」。當子類從新定義了父類的虛函數後,父類指針根據賦給它的不一樣的子類指針,動態(記住:是動態!)的調用屬於子類的該函數,這樣的函數調用在編譯期間是沒法肯定的(調用的子類的虛函數的地址沒法給出)。所以,這樣的函數地址是在運行期綁定的(晚邦定)。結論就是:重載只是一種語言特性,與多態無關,與面向對象也無關!引用一句Bruce Eckel的話:「不要犯傻,若是它不是晚邦定,它就不是多態。」
1.基本概念:
進程是對運行時程序的封裝,是系統進行資源調度和分配的的基本單位,實現了操做系統的併發;
線程是進程的子任務,是CPU調度和分派的基本單位,用於保證程序的實時性,實現進程內部的併發;線程是操做系統可識別的最小執行和調度單位。每一個線程都獨自佔用一個虛擬處理器:獨自的寄存器組,指令計數器和處理器狀態。每一個線程完成不一樣的任務,可是共享同一地址空間(也就是一樣的動態內存,映射文件,目標代碼等等),打開的文件隊列和其餘內核資源。
2.區別:
進程間通訊主要包括管道、系統IPC(包括消息隊列、信號量、信號、共享內存等)、以及套接字socket(面試官強調)。
讀寫鎖實際是一種特殊的自旋鎖,它把對共享資源的訪問者劃分紅讀者和寫者,讀者只對共享資源進行讀訪問,寫者則須要對共享資源進行寫操做。這種鎖相對於自旋鎖而言,能提升併發性,由於在多處理器系統中,它容許同時有多個讀者來訪問共享資源,最大可能的讀者數爲實際的邏輯CPU數。寫者是排他性的,一個讀寫鎖同時只能有一個寫者或多個讀者(與CPU數相關),但不能同時既有讀者又有寫者。
有了原子操做,就能夠了製做控制臨界區的鎖機制了。自旋鎖就是其中的一個表明。自旋鎖機制能夠用門和鎖的例子來比喻。進程執行到某個臨界區,至關於要進入一棟房子,這是進程會檢查屋內是否有人(進程),若是屋內沒有人,則直接拿起鑰匙進入並把門鎖上(進入臨界區);若是屋內有人(進程),則在門口等待(忙等待)屋內的進程出來再進去。能夠看出,自旋鎖最多隻能被一個進程持有,若是有新的進程但願獲取自旋鎖,它將會一直忙等待直到前一個持有自旋鎖的進程釋放鎖。
在多道程序系統中,因爲多個進程的併發執行,改善了系統資源的利用率並提升了系統 的處理能力。然而,多個進程的併發執行也帶來了新的問題——死鎖。所謂死鎖是指多個進程因競爭資源而形成的一種僵局(互相等待),若無外力做用,這些進程都將沒法向前推動。