Linux後台CPP學習之路 & 面經知識點收錄
來自專欄 學習編程
作者:叫小丁不叫小丁丁
鏈接:https://www.nowcoder.com/discuss/78222來源:牛客網一、面經知識點收錄
【1】C++extern "C"的作用:可以把程序編譯成彙編文件,然後從彙編代碼去看它的作用
C/CPP const關鍵字:再了解一下CPP字元串常量以及普通const常量的內存布局,還有與volatile一起使用的效果,然後可以看出C里的const與CPP里的const還是有一定差別的...C/CPP static關鍵字:了解一下ELF(參見《深入理解計算機系統》第七章:鏈接),然後從符號表的角度去分析static關鍵字的作用,注意:CPP不像python等解釋性語言,它不會執行類定義的代碼,所以類的靜態數據成員必須在類外定義(除了靜態常量),這個時候static的作用跟普通的static語義不同...還有,static函數在單例模式中有一個應用(參見《Effective CPP》條款4:確定對象被使用前已先被初始化)C/CPP volatile關鍵字:在底層代碼中用得多(之前調試linux文件系統的時候,想要獲得一個file\_struct對象指針,然後這個指針總是被優化掉,不清楚是不是跟volatile有關...)C/CPP restrict關鍵字:在函數庫介面中用得多C/CPP內存分配管理:CPP中的new只是對malloc進行了一層封裝,malloc的具體實現可以看glibc的malloc源碼,然後調用system call,最終會接觸操作系統的內存管理模塊,所以最終還是需要了解操作系統的堆管理(簡單堆管理參閱《深入理解計算機系統》第九章:虛擬存儲器,linux中內存管理具體實現可以閱讀linux源碼),需要特別了解內存池的實現(可以閱讀sgi stl源碼)還有夥伴系統與slab...
CPP反射:工廠模式以及CPP17了解一下CPP異常機制:網上有很多講CPP異常機制的博客CPP智能指針:可以按照介面要求自己實現一下四個簡單的智能指針,其中share\_ptr里的析構器其實是一個仿函數,然後可以自己想辦法去實現一下function,any之類的模板類CPP四種類型轉換:http://www.cplusplus.com/doc/tutorial/typecasting策略模式(舉例:share\_ptr的析構器)
簡單工廠、工廠方法、抽象工廠模式裝飾模式(閉包:CPP lambda、Python decorator了解一下)代理模式(舉例:iterator有點代理模式的意思)原型模式(舉例:實現boost庫中的any時需要用到的clone方法)模板方法模式(《Effective CPP》條款35:考慮virtual函數以外的其他選擇 有介紹,但是舉的例子感覺不是很好,感覺最大的突出點是事前和事後,之後看了《大話設計模式》對模板方法的介紹,感覺它的最大特點應該是實現最大化代碼復用)
適配器模式(舉例:STL中的容器適配器)迭代器模式(舉例:iterator)【3】資料庫資料庫基本操作:可能還會要求通過sql語句對資料庫進行調優資料庫索引:索引數據結構的實現,如何設置索引、以及複合索引內部的順序(比如說,假設有一個複合主鍵包含A、B兩列,索引AB與索引BA對資料庫的影響)TIME\_WAIT:作用以及如何避免
Ddos攻擊原理:listen隊列長肥管道7/5層模型協議、設備簡單ftp伺服器socket編程:注意盡量使用一個請求一個線程/進程模型【5】演算法一定要把《劍指offer》刷到滾瓜爛熟,裡面的演算法最好能全部手寫出來,一般面試的手撕演算法幾乎都來源於這本書大數據處理:大數據top 100啊之類的問題很常見大整數計算:轉為字元串計算或者很強的可以自己用位運算實現一下...如何設計好的散列函數動態規劃:了解一下動態規劃基本概念以及有哪些常見演算法貪心演算法:了解一下貪心演算法基本概念以及有哪些常見演算法排序演算法:快速排序、堆排序、歸併排序、插值排序、冒泡排序、選擇排序、計數排序(了解一下)、基數排序(了解一下),除了兩個需要了解的,其他六個都需要快速寫出來,而且知道它們的平均、最壞時間、空間複雜度搜索演算法:折半查找(一定要能快速寫出來,還有其變種),二叉樹查找,hash查找數據結構-堆數據結構-鏈表:數據結構-跳錶、演算法:二叉搜索樹轉為雙向鏈表、鏈表迴環、反轉、複雜鏈表的複製...數據結構-樹:數據結構-AVL樹、紅黑樹、B 樹,演算法:二叉樹的前中後序遍歷,還有《劍指offer》上的樹演算法數據結構-圖:dfs、bfs、dijkstra、floyd、prim、kruskal都要能夠寫出來字元串演算法:kmp、boyer-moore都要能夠寫出來、正則演算法了解一下手撕演算法:手撕演算法的代碼量一般都不是很大,所以應該去權衡一下什麼演算法更容易被考到什麼不容易被考到。除了《劍指offer》,還有很多跟程序魯棒性和性能有關的手撕代碼題:strcpy,實現單例模式...,還有一些題來源於leetcode,但是幾乎都是easy或者medium程度的題【6】操作系統/Linux 內核中斷:介紹中斷的作用,要是再能從硬體、彙編級別去介紹一下中斷會發生什麼就更棒了信號:幾乎所有講操作系統的書都有介紹信號,linux信號參閱《Unix環境高級編程》第10章:信號,以及《深入理解linux內核》第11章:信號,需要了解可靠信號與不可靠信號的區別,還需要特別了解SIGCHLD、SIGCLD信號進程與線程:輕量級進程、系統級線程、用戶級線程、進程,這些可以讀linux內核源碼以及一些資料很容易理解,協程(Python中yield的效果以及它的具體實現(C源碼)了解一下),可以去網上找找CPP的協程庫去讀一讀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後台CPP,以前還花了很長時間去學習windows下的編程,雖然學習了一點東西,但是對我的發展並沒有多大幫助而且真的很浪費時間,因為我把它當成主線來認真學習了...就算是這樣,以後還是接觸linux,windows用得少了也很快就會忘記,所以希望大家能好好權衡...我很強調動手以及發散思維,發散思維比如說學到一個東西能很快聯想到之前學過的另一個東西,以及遇到新的東西希望能夠從更底層去猜測它的實現,要是等以後再接觸到它的實現的時候,可以將具體實現與之前自己的猜測進行比較...動手是真的巨重要,我討厭伸手黨,也討厭紙上談兵,遇到問題我會盡量去用代碼或者實現源碼去解決問題,有時候跟蹤程序的具體過程可能還要反彙編,有時候遇到很難很難的調試問題,比如說之前調試linux文件系統,我真的花了巨長巨長的時間,這個時候需要很強的耐心還有明確的目的,因為有時候調試著調試著突然忘記了自己想要幹嗎...我從很早開始使用linux作為自己的日常工作環境,為了學習《Unix環境高級編程》,我幾乎嘗試了所有linux發行版還有其他unix系統(這些作為虛擬機部署),部署其實也是一件很有趣的事,也能讓你更加深入的了解類unix系統...推薦大家使用linux作為自己的學習環境,而且還能剋制自己玩大部分遊戲...ok,開始吧...【1】CPP語言在學習CPP之前,我只有C基礎。我是啃《CPP Primer》這本書,當時是第五版,那個時候最新的還是CPP11標準,也推薦大家看這本書,因為CPP14、17都還是太新,用的很少,而且大多公司也才從CPP98過渡到CPP11。這本書我讀了很多遍,重點是STL與類,模板編程與OO幾乎都佔了CPP的半壁江山。
關於CPP面向對象,讀《CPP Primer》這本書關於類的講解還有《深度探索CPP對象模型》,然後這部分內容就差不多了。
把細節列出來吧:
拷貝控制(默認構造、值構造、拷貝構造、移動構造、拷貝複製、移動複製、析構)這些需要很熟練很熟練的了解,這其中初值列與隱含的析構列很重要,對象模型(簡單繼承、含有虛函數的繼承、含有虛基類的繼承)它們的內存布局需要很清楚的知道,還有看上面那個stack overflow的帖子...命名返回值優化順便了解一下(見《深度探索CPP對象模型》),然後就能理解為什麼有時候類實例的創建沒有按照正確流程...
模板編程首先我推薦一定要把SGI STL庫源碼閱讀一遍,就算源碼沒有看過,STL還是得會熟練的使用,重點在set/map、string/vector,要是能自己寫一寫就最好了,很喜歡侯捷先生的兩句話:「源碼之下,了無秘密」,「天下大事,必作於細」。內存分配器、幾個容器、幾個容器適配器、幾個范型演算法,代碼量大約在1~2w行左右,然後可以自己再實現更多的東西,例如可以再實現一些boost庫中的東西、四個智能指針、any、tuple之類的,然後能真正讓你體會到模板元編程的樂趣...
模板編程幾個重要細節列出來:函數模板--顯式實例化、特例化,類模板--顯式實例化、全特化、局部特例化,模板容易出現的問題見《Effective CPP》條款43:學習處理模板化基類內的名稱以及條款46:需要類型轉換時請為模板定義非成員函數,可能會幫到你。還有一個很容易出現的問題應該就是關於模板的鏈接錯誤了(提示沒有找到指定的函數),其實就是沒有模板實例化,具體問題去google...CPP11還有很多特性,右值呀、lambda呀、function呀,RTTI呀...右值可以從彙編角度去看;lambda也可以從彙編角度去看,lambda其實就是個閉包,在CPP中lambda沒有一個具體的類型,將一個捕獲列表與一個函數捆綁在了一起,所以從彙編去看的話,返回一個lambda其實就是返回捕獲列表中捕獲的數據;function運用了類型擦除,具體實現可以google,其實boost庫中的any也用了類型擦除,RTTI的話其實讀完《深度探索CPP對象模型》,從虛函數表中應該已經知道了它的原理;還有一些高級部分:類型萃取呀、tuple呀這些...,類型萃取讀完SGI STL源碼之後應該已經能夠深刻的理解了,tuple的話就是用了模板遞歸這些嘛
一些模板元編程...書籍推薦:《CPP Primer》、《深度探索CPP對象模型》、《STL源碼剖析》、《CPP標準程序庫》(參閱)、《Boost程序庫完全開發指南》(簡單讀一讀)、《Effective CPP》(想要更好的學習CPP強烈推薦)、《More Effective Modern CPP》(讓你更好的了解CPP11,但是這本書目前還沒有中文版,但是感興趣的同學可以啃一啃...)
【2】設計模式推薦閱讀《大話設計模式》,提醒一下,設計模式面試考得不多,但是想要了解的話還是去看一看...其中好幾個設計模式可以聯繫已學過的東西加深印象,學習設計模式最好最快的辦法就是理解它的UML圖...【3】資料庫我的資料庫不是很好,快速、基本地學習資料庫推薦閱讀《Sql必知必會》(很薄的一本書)【4】計算機網路
《Tcp/ip詳解》(卷一)了解一下,看上面收錄的面試知識點,著重去學習重要的那些。詳細介紹tcp可以閱讀《計算機網路》(謝希仁)(對也就是大多學校發的那本教材)第7章:運輸層,其中的tcp可靠傳輸相關的一定要認真認真讀!!,列出細節吧:滑動窗口、擁塞控制、還有狀態圖、還有TIME\_WAIT(重中之重),socket編程可以閱讀《Unix網路編程 套接字聯網API》,其中跟SCTP相關的可以忽略掉,其實再省略一點的話只讀第一二部分就行了...【5】演算法上面收錄的面試知識點基本已經全部講了,也就是面試的時候所有數據結構與演算法都可能會考到。我演算法還是有點薄弱,因為花了太多的時間去學習專業課然後沒有太多的時間去刷題,但是強烈建議大家多去刷刷題,ACM盡量參加,含金量特別特別高。leetcode、牛客演算法都該做做,尤其是牛客上關於《劍指offer》的專題一定要全部刷到滾瓜爛熟...剛刷演算法可能會很困難,但是堅持去做,做完去看看題解還是會很有進步的。上面我還給了網易雲課堂的鏈接,裡面有開數據結構的課,學習基礎可以去看看...推薦書籍《Algorithms 4th Edition》(英文版,所以可能有點難讀,英語不是很好的話就參閱),《演算法導論》【6】操作系統
還是上面給的網易雲課堂鏈接,裡面有一門操作系統的課,簡單學習的話可以去看看。【7】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、文件系統、內存管理、大多數系統調用、進程調度呀之類的源碼總結貼出來...
【8】彙編對了,走CPP後台這條路,就是需要與底層進行接觸,所以了解彙編是必不可少的。儘早學會彙編,對以後學習任何高級語言、操作系統都會很有幫助。推薦閱讀《彙編語言》(王爽),《X86彙編語言 從實模式到保護模式》,《彙編語言程序設計》(簡單閱讀一下,了解AT&T彙編格式)帖子內容沒用md把格式做好,所以將就讀一讀吧...雖然很菜,但是還是希望上面的總結能夠幫助到大家...有什麼學習相關的問題可以私信我或者給我評論....跟我交流:https://www.nowcoder.com/discuss/78222
更多好文章:https://www.nowcoder.com/discuss?type=2&order=0
推薦閱讀:
※面試官問你:你有什麼想問的,你這麼回答會給你加分
※奇葩而有效的反向面試——王猛見桓溫
※「面試達人」面試官問「你的缺點是什麼?」來看最優解法!
※面試中的CV --- classification to detection
※HR在公司的地位如何?HR的職責、價值是什麼?