都是語言,為什麼英語比c++難這麼多呢?
chapter 1
chapter 2
chapter 3
chapter 4
程式設計基礎
物件導向基礎
標準模板庫
編譯及除錯
c/c++的內容又多又雜,常常看到有人羅列相關書單,覺得毫無意義,我不相信他們真的完全掌握了其中任何一本。學習任何東西,首先要掌握基本概念,基礎不牢地動山搖,因為高階的內容都是通過低階的概念來描述的。當基本概念都沒理解透,學習再多都是空中樓閣。這裡羅列了一些聽基本的問題,雖然看著不難,但是精確理解每句話中的每個詞真的並不容易。
變數宣告和定義區別?
"零值比較"?
strlen和sizeof區別?
同一不同物件可以互相賦值嗎?
結構體內存對齊問題?
static作用是什麼?在c和c++中有何區別?
結構體和類的區別?
- 結構體不可以繼承,類可以。 c++中結構體也可以繼承。
malloc和new的區別?
指標和引用區別?
- 引用只是別名,不占用具體儲存空間,只有宣告沒有定義;指標是具體變數,需要占用儲存空間。
巨集定義和函式有何區別?
巨集定義和const區別?
巨集定義和typedef區別?
巨集定義和內聯函式(inline)區別?
條件編譯#ifdef, #else, #endif作用?
區別以下幾種變數?
const int a;
int const a;
const int *a;
int *const a;
volatile有什麼作用?
什麼是常引用?
區別以下指標型別?
int *p[10]
int (*p)[10]
int *p(int)
int (*p)(int)
常量指標和指標常量區別?
a和&a有什麼區別?
假設陣列int a[10];
int (*p)[10] = &a;
陣列名和指標(這裡為指向陣列首元素的指標)區別?
野指標是什麼?
堆和棧的區別?
申請大小限制不同。
申請效率不同。
delete和delete區別?
能夠準確理解下面這些問題是從c程式設計師向c++程式設計師高階的基礎。當然了,這只是一部分。
物件導向三大特性?
public/protected/private的區別?
物件儲存空間?
c++空類有哪些成員函式?
建構函式能否為虛函式,析構函式呢?
建構函式:
構造函式呼叫順序,析構函式呢?
拷貝建構函式中深拷貝和淺拷貝區別?
拷貝建構函式和賦值運算子過載的區別?
注:類中有指標變數時要重寫析構函式、拷貝建構函式和賦值運算子
虛函式和純虛函式區別?
覆蓋、過載和隱藏的區別?
在main執行之前執行的**可能是什麼?
哪幾種情況必須用到初始化成員列表?
什麼是虛指標?
過載和函式模板的區別?
this指標是什麼?
類模板是什麼?
建構函式和析構函式呼叫時機?
stl內容雖然看起來很多,單獨成書都不是問題(《stl原始碼剖析》),但從實際使用狀況來看,我認為只需要知道以下幾點就可以了:
string
vector
用法:
定義:
vectorvec;
插入元素:
vec.push_back(element);
vec.insert(iterator, element);
刪除元素:
vec.pop_back();
vec.erase(iterator);
修改元素:
vec[position] = element;
遍歷容器:
for(auto it = vec.begin(); it != vec.end(); ++it)
其他:vec.empty(); //判斷是否空
vec.size(); // 實際元素
vec.capacity(); // 容器容量
vec.begin(); // 獲得首迭代器
vec.end(); // 獲得尾迭代器
vec.clear(); // 清空
實現:
模擬vector實現
需要連續的物理儲存空間。
每當大小不夠時,重新分配記憶體(*2),並複製原內容。
錯誤避免:
迭代器失效
刪除元素
map
用法:
定義:
mapmymap;
插入元素:
mymap.insert(pair(key, value)); // 同key不插入
mymap.insert(map::value_type(key, value)); // 同key不插入
mymap[key] = value; // 同key覆蓋
刪除元素:
mymap.erase(key); // 按值刪
mymap.erase(iterator); // 按迭代器刪
修改元素:
mymap[key] = new_value;
遍歷容器:
for(auto it = mymap.begin(); it != mymap.end(); ++it)
實現:
rbtree實現
rbtree本身也是二叉排序樹的一種,key值有序,且唯一。
基於紅黑樹實現的map結構(實際上是map, set, multimap,multiset底層均是紅黑樹),不僅增刪資料時不需要移動資料,其所有操作都可以在o(logn)時間範圍內完成。另外,基於紅黑樹的map在通過迭代器遍歷時,得到的是key按序排列後的結果,這點特性在很多操作中非常方便。
面試時候現場寫紅黑樹**的概率幾乎為0,但是紅黑樹一些基本概念還是需要掌握的。
它是二叉排序樹(繼承二叉排序樹特顯):
它滿足如下幾點要求:
查詢時間一定可以控制在o(logn)。
紅黑樹的節點定義如下:
enum color ;
struct rbtreenode ;
所以對紅黑樹的操作需要滿足兩點:1.滿足二叉排序樹的要求;2.滿足紅黑樹自身要求。通常在找到節點通過和根節點比較找到插入位置之後,還需要結合紅黑樹自身限制條件對子樹進行左旋和右旋。
相比於**l樹,紅黑樹平衡性要稍微差一些,不過建立紅黑樹時所需的旋轉操作也會少很多。相比於最簡單的bst,bst最差情況下查詢的時間複雜度會上公升至o(n),而紅黑樹最壞情況下查詢效率依舊是o(logn)。所以說紅黑樹之所以能夠在stl及linux核心中被廣泛應用就是因為其折中了兩種方案,既減少了樹高,又減少了建樹時旋轉的次數。
從紅黑樹的定義來看,紅黑樹從根到null的每條路徑擁有相同的黑節點數(假設為n),所以最短的路徑長度為n(全為黑節點情況)。因為紅節點不能連續出現,所以路徑最長的情況就是插入最多的紅色節點,在黑節點數一致的情況下,最可觀的情況就是黑紅黑紅排列......最長路徑不會大於2n,這裡路徑長就是樹高。
set
編譯
預處理編譯
鏈結各個源**模組獨立的被編譯,然後將他們組裝起來成為乙個整體,組裝的過程就是鏈結。被鏈結的各個部分本本身就是二進位制檔案,所以在被鏈結時需要將所有目標檔案的**段拼接在一起,然後將所有對符號位址的引用加以修正。
如果僅僅像上面的步驟是沒有辦法正常使用庫的,我們可以通過加-lpath指定搜尋庫檔案的目錄(-l.表示當前目錄),預設情況下會到環境變數ld_library_path指定的目錄下搜尋庫檔案,預設情況是/usr/lib,我們可以將庫檔案拷貝到那個目錄下再鏈結。
比較靜態庫和動態庫我們可以得到二者的優缺點。
動態庫另乙個有點就是更新很容易,當庫發生變化時,如果介面沒變只需要用新的動態庫替換掉就可以了。但是如果是靜態庫的話就需要重新被編譯。
不過靜態庫也有優點,主要就是靜態庫一次性完成了所有內容的繫結,執行時就不必再去考慮鏈結的問題了,執行效率會稍微高一些。
makefile編寫
對於大的工程通常涉及很多標頭檔案和原始檔,編譯起來很很麻煩,makefile正是為了自動化編譯產生的,makefile像是編譯說明書,指示編譯的步驟和條件,之後被make命令解釋。
鏈結
符號解析
重定位可執行目標檔案
載入
C 細節問題
參 本質 引用是別名,指標是位址,具體的 指標可以在執行時改變其所指向的值,引用一旦和某個物件繫結就不再改變 從記憶體上看,指標會分配記憶體區域,而引用不會,它僅僅是乙個別名 在引數傳遞時,引 用會做型別檢查,而指標不會 引用不能為空,指標可以為空 參 本質 define只是字串替換,const參與...
專案問題細節
最近專案很有問題,關於客戶需求,我們表現出來的就是很沒有經驗,很不專業。1.客戶要求的急,需要24小時不停的解決,但是由於人數有限,不可能不讓人睡覺,在這種高度緊張的條件下,發布的版本的質量也可想而知。2.客戶發現乙個問題就出版本,然後測試,又發現了新的問題,又出版本,這樣頻繁的折騰,最後只會像電腦...
synchronized細節問題
一 synchronized有鎖重入的特點,某個執行緒得到物件的鎖後,再次請求此物件可以再次得到改物件的鎖。如下示例,在method1中呼叫method2,在method2中呼叫method3,而method1 method2和method3都是加了synchronized關鍵字的。public c...