Linux后臺C++學習之路 & 面經知識點收錄
面經知識點收錄
C++
extern "C"的作用:可以把程序編譯成匯編文件,然后從匯編代碼去看它的作用
C/C++ const關鍵字:再了解一下C++字符串常量以及普通const常量的內存布局,還有與volatile一起使用的效果,然后可以看出C里的const與C++里的const還是有一定差別的...
C/C++ static關鍵字:了解一下ELF(參見《深入理解計算機系統》第七章:鏈接),然后從符號表的角度去分析static關鍵字的作用,注意:C++不像python等解釋性語言,它不會執行類定義的代碼,所以類的靜態數據成員必須在類外定義(除了靜態常量),這個時候static的作用跟普通的static語義不同...還有,static函數在單例模式中有一個應用(參見《Effective C++》條款4:確定對象被使用前已先被初始化)
C/C++ volatile關鍵字:在底層代碼中用得多(之前調試linux文件系統的時候,想要獲得一個file_struct對象指針,然后這個指針總是被優化掉,不清楚是不是跟volatile有關...)
C/C++ restrict關鍵字:在函數庫接口中用得多
C/C++內存分配管理:C++中的new只是對malloc進行了一層封裝,malloc的具體實現可以看glibc的malloc源碼,然后調用system call,最終會接觸操作系統的內存管理模塊,所以最終還是需要了解操作系統的堆管理(簡單堆管理參閱《深入理解計算機系統》第九章:虛擬存儲器,linux中內存管理具體實現可以閱讀linux源碼),需要特別了解內存池的實現(可以閱讀sgi stl源碼)還有伙伴系統與slab...
C++反射:工廠模式以及C++17了解一下
C++異常機制:網上有很多講C++異常機制的博客
C++智能指針:可以按照接口要求自己實現一下四個簡單的智能指針,其中share_ptr里的析構器其實是一個仿函數,然后可以自己想辦法去實現一下function,any之類的模板類
C++四種類型轉換:http://www.cplusplus.com/doc/tutorial/typecasting
C++ string實現原理:其實實現與vector差不多,具體實現參閱sgi stl源碼
C++ map、set實現原理:封裝了一顆紅黑樹,紅黑樹重要的就是旋轉,還有平衡度(根據黑高證明),具體實現參閱sgi stl源碼
C++函數重載、覆蓋、隱藏:重載可以從匯編代碼去看(根據參數類型去重命名函數名),覆蓋可以去從虛函數表去分析,隱藏可以從作用域去理解
C++編譯時多態與運行時多態:類的多態(運行時多態)一定要看看《深度探索C++對象模型》這本書,stack overflow上有一個帖子深度討論了類的多態、虛繼承這些,講到了構造析構過程中vptr的變化,然后可以自己去適當理解為什么虛函數的具體調用依賴于構造析構的當前進度(鏈接:https://stackoverflow.com/questions/6258559/what-is-the-vtt-for-a-class. )。注意,函數模板不能局部特例化,不然就是模板重載,不得不多說一句,函數模板實例化后的函數與普通函數不在同一命名空間中(不是C++語言支持的namespace,是編譯器所用的命名空間),所以能夠出現具有相同名字相同參數類型的函數,實際上,從匯編代碼去看,其實最終的名字還是不同的
C++為什么構造函數不能設置為虛函數:vptr還沒有被設置,會出現先有雞還是先有蛋的矛盾
new/delete和 malloc/free的區別:《Effective C++》定制new和delete(條款49~52)了解一下
如何實現只能動態分配類對象,不能靜態分配:只是要求不能在棧上分配,必須在堆上分配
動態鏈接庫與靜態鏈接庫的區別
設計模式
單例模式(static函數可以實現)
策略模式(舉例:share_ptr的析構器)
簡單工廠、工廠方法、抽象工廠模式
裝飾模式(閉包:C++ lambda、Python decorator了解一下)
代理模式(舉例:iterator有點代理模式的意思)
原型模式(舉例:實現boost庫中的any時需要用到的clone方法)
模板方法模式(《Effective C++》條款35:考慮virtual函數以外的其他選擇 有介紹,但是舉的例子感覺不是很好,感覺最大的突出點是事前和事后,之后看了《大話設計模式》對模板方法的介紹,感覺它的最大特點應該是實現最大化代碼復用)
適配器模式(舉例:STL中的容器適配器)
迭代器模式(舉例:iterator)
數據庫
數據庫基本操作:可能還會要求通過sql語句對數據庫進行調優
數據庫索引:索引數據結構的實現,如何設置索引、以及復合索引內部的順序(比如說,假設有一個復合主鍵包含A、B兩列,索引AB與索引BA對數據庫的影響)
數據庫事務:底層如何實現事務
數據庫引擎
數據庫存儲過程
數據庫的第一二三范式
delete、truncate、drop的區別及應用場所
計算機網絡
HTTP狀態碼
流量控制
擁塞控制:高延遲擁塞控制會降低tcp傳輸效率,這個時候需要自己實現擁塞控制或者避免擁塞控制,所以需要封裝udp或者ip數據報(如果需要重寫擁塞控制算法,可以了解一下BBR算法)
TCP連接的建立與終止:從tcp三次握手可以引入Ddos攻擊
TIME_WAIT:作用以及如何避免
Ddos攻擊原理:listen隊列
長肥管道
7+5層模型協議、設備
簡單ftp服務器socket編程:注意盡量使用一個請求一個線程/進程模型
算法
一定要把《劍指offer》刷到滾瓜爛熟,里面的算法最好能全部手寫出來,一般面試的手撕算法幾乎都來源于這本書
大數據處理:大數據top 100啊之類的問題很常見
大整數計算:轉為字符串計算或者很強的可以自己用位運算實現一下...
如何設計好的散列函數
動態規劃:了解一下動態規劃基本概念以及有哪些常見算法
貪心算法:了解一下貪心算法基本概念以及有哪些常見算法
排序算法:快速排序、堆排序、歸并排序、插值排序、冒泡排序、選擇排序、計數排序(了解一下)、基數排序(了解一下),除了兩個需要了解的,其他六個都需要快速寫出來,而且知道它們的平均、最壞時間、空間復雜度
搜索算法:折半查找(一定要能快速寫出來,還有其變種),二叉樹查找,hash查找
數據結構-堆
數據結構-鏈表:數據結構-跳表、算法:二叉搜索樹轉為雙向鏈表、鏈表回環、反轉、復雜鏈表的復制...
數據結構-樹:數據結構-AVL樹、紅黑樹、B+樹,算法:二叉樹的前中后序遍歷,還有《劍指offer》上的樹算法
數據結構-圖:dfs、bfs、dijkstra、floyd、prim、kruskal都要能夠寫出來
字符串算法:kmp、boyer-moore都要能夠寫出來、正則算法了解一下
手撕算法:手撕算法的代碼量一般都不是很大,所以應該去權衡一下什么算法更容易被考到什么不容易被考到。除了《劍指offer》,還有很多跟程序魯棒性和性能有關的手撕代碼題:strcpy,實現單例模式...,還有一些題來源于leetcode,但是幾乎都是easy或者medium程度的題
操作系統/Linux 內核
中斷:介紹中斷的作用,要是再能從硬件、匯編級別去介紹一下中斷會發生什么就更棒了
信號:幾乎所有講操作系統的書都有介紹信號,linux信號參閱《Unix環境高級編程》第10章:信號,以及《深入理解linux內核》第11章:信號,需要了解可靠信號與不可靠信號的區別,還需要特別了解SIGCHLD、SIGCLD信號
進程與線程:輕量級進程、系統級線程、用戶級線程、進程,這些可以讀linux內核源碼以及一些資料很容易理解,協程(Python中yield的效果以及它的具體實現(C源碼)了解一下),可以去網上找找C++的協程庫去讀一讀
linux常見的調度算法:知道這些算法的思想就行,讀個linux源碼就更棒
linux文件系統:《深入理解linux內核》第12章:虛擬文件系統 以及 第18章:Ext2和Ext3文件系統 以及 第16章:訪問文件,可以讓你深入了解linux文件系統
linux IPC:System V、Posix IPC熟悉一下,可以參閱《Unix環境高級編程 進程間通信》,以及清楚它們的作用與優缺點,當然還是推薦去閱讀一下IPC的linux內核源碼
如何實現linux的高并發,線程池的思想:github上有好多好多線程庫,抓一個下來自己讀一讀,代碼量不是很大,很推薦自己動手寫一寫
死鎖產生的四個必要條件及如何預防
編寫linux的并發測試程序:生產者消費者并發程序要求能夠寫得出來
驚群效應:舉例子講一下驚群現象,然后去了解一下如何避免。內核中存在兩個驚群的例子,accept驚群與epoll驚群,linux內核經過改進避免了一些驚群,可以從內核源碼去解釋一下它是怎么做的
fork、vfork、clone的區別:這個真的只能讀源碼才能深入了解了,注意,phtread線程庫就是使用的clone
僵尸進程:清楚一下概念以及它的危害,然后知道如何去避免僵尸進程
select、poll、epoll的區別:從內核源碼去分析,select與poll實現差不多,讀了一個源碼差不多很快就能讀懂第二個,epoll設計很獨特也很有意思,趕快去讀一讀
linux內核伙伴系統、slab緩存(實現原理、與普通內存分配的區別以及優勢):簡單介紹參閱《深入理解linux內核》第8章:內存管理,深入了解就去讀linux內核源碼...
學習方法
收到好幾條私信評論,問我學習方法,知道自己很菜,雖然有時候會盲目自信,但是跟一些大牛比起來還是會深深感到自卑...沒了解學習過一個領域,看到別人在這方面有見解,然后就會覺得別人特別牛,可是一旦了解,就會發現并沒有想象中的那么厲害,所以說我真的很菜的(并沒有裝逼,是真心話)...
適合一個人的學習方法,不一定適合另一個人,所以在這發表的見解,大家取其精華去其糟粕...
有好幾個非cs專業的同學問我學習方法,那么先貼一個鏈接:http://study.163.com/curricula/cs/grade-1.htm. ,這里有cs專業大一到大四開的所有課程,可能這里有些課程質量不是很好,但是還是可以了解一下具體開過哪些課,然后自己去找教程去認真學習。這些課程中開的數據結構課感覺還不錯,可以去認真看看...
看到好幾個同學說,問別人學習方法都是推薦了一大堆書,哪看的完...其實很多東西只有看書才能看得明白的也能看得更透徹,我幾乎都是看書看源碼,遇到一些很難的就google或者找視頻看...因為如果所有東西都看別人講(google看博客或者看視頻),就可能遇到一個知識點不同的人不同的看法,然后自己就弄弄不明白還會被帶歪然后就心情爆炸...所以我還是會推薦大家看書或者看源碼,但是會講重點哪些地方應該看哪些地方簡單了解一下,這樣對大家的時間還是能省一點的...
大家一定要有明確的目標,知道自己該學些什么又有哪些東西學了對主線沒有幫助的,目的明確一點真的很重要,我明知我是linux后臺C++,以前還花了很長時間去學習windows下的編程,雖然學習了一點東西,但是對我的發展并沒有多大幫助而且真的很浪費時間,因為我把它當成主線來認真學習了...就算是這樣,以后還是接觸linux,windows用得少了也很快就會忘記,所以希望大家能好好權衡...
我很強調動手以及發散思維,發散思維比如說學到一個東西能很快聯想到之前學過的另一個東西,以及遇到新的東西希望能夠從更底層去猜測它的實現,要是等以后再接觸到它的實現的時候,可以將具體實現與之前自己的猜測進行比較...動手是真的巨重要,我討厭伸手黨,也討厭紙上談兵,遇到問題我會盡量去用代碼或者實現源碼去解決問題,有時候跟蹤程序的具體過程可能還要反匯編,有時候遇到很難很難的調試問題,比如說之前調試linux文件系統,我真的花了巨長巨長的時間,這個時候需要很強的耐心還有明確的目的,因為有時候調試著調試著突然忘記了自己想要干嗎...
我從很早開始使用linux作為自己的日常工作環境,為了學習《Unix環境高級編程》,我幾乎嘗試了所有linux發行版還有其他unix系統(這些作為虛擬機部署),部署其實也是一件很有趣的事,也能讓你更加深入的了解類unix系統...推薦大家使用linux作為自己的學習環境,而且還能克制自己玩大部分游戲...
ok,開始吧...
C++語言
在學習C++之前,我只有C基礎。我是啃《C++ Primer》這本書,當時是第五版,那個時候最新的還是C++11標準,也推薦大家看這本書,因為C++14、17都還是太新,用的很少,而且大多公司也才從C++98過渡到C++11。這本書我讀了很多遍,重點是STL與類,模板編程與OO幾乎都占了C++的半壁江山。關于C++面向對象,讀《C++ Primer》這本書關于類的講解還有《深度探索C++對象模型》,然后這部分內容就差不多了。把細節列出來吧:拷貝控制(默認構造、值構造、拷貝構造、移動構造、拷貝復制、移動復制、析構)這些需要很熟練很熟練的了解,這其中初值列與隱含的析構列很重要,對象模型(簡單繼承、含有虛函數的繼承、含有虛基類的繼承)它們的內存布局需要很清楚的知道,還有看上面那個stack overflow的帖子...命名返回值優化順便了解一下(見《深度探索C++對象模型》),然后就能理解為什么有時候類實例的創建沒有按照正確流程...模板編程首先我推薦一定要把SGI STL庫源碼閱讀一遍,就算源碼沒有看過,STL還是得會熟練的使用,重點在set/map、string/vector,要是能自己寫一寫就最好了,很喜歡侯捷先生的兩句話:“源碼之下,了無秘密”,“天下大事,必作于細”。內存分配器、幾個容器、幾個容器適配器、幾個范型算法,代碼量大約在1~2w行左右,然后可以自己再實現更多的東西,例如可以再實現一些boost庫中的東西、四個智能指針、any、tuple之類的,然后能真正讓你體會到模板元編程的樂趣...模板編程幾個重要細節列出來:函數模板--顯式實例化、特例化,類模板--顯式實例化、全特化、局部特例化,模板容易出現的問題見《Effective C++》條款43:學習處理模板化基類內的名稱以及條款46:需要類型轉換時請為模板定義非成員函數,可能會幫到你。還有一個很容易出現的問題應該就是關于模板的鏈接錯誤了(提示沒有找到指定的函數),其實就是沒有模板實例化,具體問題去google...C++11還有很多特性,右值呀、lambda呀、function呀,RTTI呀...右值可以從匯編角度去看;lambda也可以從匯編角度去看,lambda其實就是個閉包,在C++中lambda沒有一個具體的類型,將一個捕獲列表與一個函數捆綁在了一起,所以從匯編去看的話,返回一個lambda其實就是返回捕獲列表中捕獲的數據;function運用了類型擦除,具體實現可以google,其實boost庫中的any也用了類型擦除,RTTI的話其實讀完《深度探索C++對象模型》,從虛函數表中應該已經知道了它的原理;還有一些高級部分:類型萃取呀、tuple呀這些...,類型萃取讀完SGI STL源碼之后應該已經能夠深刻的理解了,tuple的話就是用了模板遞歸這些嘛,一些模板元編程...書籍推薦:《C++ Primer》、《深度探索C++對象模型》、《STL源碼剖析》、《C++標準程序庫》(參閱)、《Boost程序庫完全開發指南》(簡單讀一讀)、《Effective C++》(想要更好的學習C++強烈推薦)、《More Effective Modern C++》(讓你更好的了解C++11,但是這本書目前還沒有中文版,但是感興趣的同學可以啃一啃...)
設計模式
推薦閱讀《大話設計模式》,提醒一下,設計模式面試考得不多,但是想要了解的話還是去看一看...其中好幾個設計模式可以聯系已學過的東西加深印象,學習設計模式最好最快的辦法就是理解它的UML圖...
數據庫
我的數據庫不是很好,快速、基本地學習數據庫推薦閱讀《Sql必知必會》(很薄的一本書)
計算機網絡
《Tcp/ip詳解》(卷一)了解一下,看上面收錄的面試知識點,著重去學習重要的那些。詳細介紹tcp可以閱讀《計算機網絡》(謝希仁)(對也就是大多學校發的那本教材)第7章:運輸層,其中的tcp可靠傳輸相關的一定要認真認真讀!!,列出細節吧:滑動窗口、擁塞控制、還有狀態圖、還有TIME_WAIT(重中之重),socket編程可以閱讀《Unix網絡編程 套接字聯網API》,其中跟SCTP相關的可以忽略掉,其實再省略一點的話只讀第一二部分就行了...
算法
上面收錄的面試知識點基本已經全部講了,也就是面試的時候所有數據結構與算法都可能會考到。我算法還是有點薄弱,因為花了太多的時間去學習專業課然后沒有太多的時間去刷題,但是強烈建議大家多去刷刷題,ACM盡量參加,含金量特別特別高。leetcode、牛客算法都該做做,尤其是牛客上關于《劍指offer》的專題一定要全部刷到滾瓜爛熟...剛刷算法可能會很困難,但是堅持去做,做完去看看題解還是會很有進步的。上面我還給了網易云課堂的鏈接,里面有開數據結構的課,學習基礎可以去看看...推薦書籍《Algorithms 4th Edition》(英文版,所以可能有點難讀,英語不是很好的話就參閱),《算法導論》
操作系統
還是上面給的網易云課堂鏈接,里面有一門操作系統的課,簡單學習的話可以去看看。
linux內核
先簡單讀一遍《Linux內核設計與實現》,偶爾可對照一下linux內核源碼。但是呢,這本書其中感覺有很多錯誤,不是很嚴謹,所以不推薦作為深入學習linux內核的書籍,只是作為簡單的入門。深入學習linux內核的話,可以認真讀linux內核源碼然后對照《深入理解linux內核》這本書,當然,重點還是讀源碼...讀了《Linux內核設計與實現》之后已經有了基礎了,然后其實已經可以有能力自己讀懂源碼了...可能會覺得還是有困難,講一下我的linux入門之路吧...我先讀了一遍《Linux內核設計與實現》,當時對照著源碼讀的,當然啦,書上不可能所有東西都講,只是挑一些特別重要的講,其他的還是需要自己去看去理解...讀完這本書之后,大致的內存管理、進程控制之類的還是了解了,我真正入門是在讀多路復用select、poll、epoll源碼的時候,這三個函數源碼真的很簡單,讀懂之后能很有效地增強自信心,然后就覺得很有趣,然后就開始了真正的linux學習之路。之后慢慢地linux文件系統、內存管理、IPC之類的都能看懂,不懂google,看博客,然后繼續讀...linux內核源碼其實并沒有特別難學習,難的是不知道怎么入門...這里有奧特曼的epoll源碼總結:https://www.nowcoder.com/discuss/26226. ,之后要是有時間我再把我對do_fork、select、poll、epoll、ipc、文件系統、內存管理、大多數系統調用、進程調度呀之類的源碼總結貼出來...
匯編
對了,走C++后臺這條路,就是需要與底層進行接觸,所以了解匯編是必不可少的。盡早學會匯編,對以后學習任何高級語言、操作系統都會很有幫助。推薦閱讀《匯編語言》(王爽),《X86匯編語言 從實模式到保護模式》,《匯編語言程序設計》(簡單閱讀一下,了解AT&T匯編格式)
帖子內容沒用md把格式做好,所以將就讀一讀吧...雖然很菜,但是還是希望上面的總結能夠幫助到大家...有什么學習相關的問題可以私信我或者給我評論...
面經已發布:https://www.nowcoder.com/discuss/77507.
原文鏈接:http://www.lxweimin.com/p/3427b2bee081.