(一)C語言
作為一名C程序員,熟練掌握C語言是最基本的一項(xiàng)技能。關(guān)于如何學(xué)好C語言,以及C語言話題的討論,網(wǎng)上有很多經(jīng)典的文章。很多人工作一段時(shí)間以后都自認(rèn)為自己的C語言水平已經(jīng)很高了??蓪?shí)際在工作中,接觸的東西也多了,開源項(xiàng)目多了以后,才發(fā)現(xiàn)自己的C語言能力太一般了。宏函數(shù)千變?nèi)f化的寫法,指針百花繚亂的用法…等等。寫代碼時(shí),應(yīng)常常問自己:這個(gè)行為是C語言規(guī)范定義的嗎?如果是,是C89還是C99?我現(xiàn)在用的編譯器支持嗎?如果不是C語言規(guī)范定義的,那么在程序運(yùn)行的這個(gè)平臺(tái),行為是確定的嗎?所以建議大家平時(shí)可以多想想這些問題,查查資料,相信一定會(huì)對(duì)C語言有更深的理解。
(二)UNIX/Linux系統(tǒng)編程
在UNIX/Linux系統(tǒng)上開發(fā)程序,掌握系統(tǒng)編程API是必不可少的技能。而這方面的經(jīng)典書籍都是一些大部頭的英文著作,讓人望而生畏。首先可以先找一本口碑不錯(cuò)的中文書先看一下,了解一下都有哪些種類的API。這樣以后用到時(shí),再去精讀經(jīng)典英文著作里的相關(guān)章節(jié),或是查man手冊(cè)。此外,如果有時(shí)間,可以學(xué)習(xí)一下經(jīng)典的開源項(xiàng)目,了解這些開源項(xiàng)目是如何使用這些API的。舉個(gè)例子,Redis是很多人推薦的一個(gè)很不錯(cuò)的學(xué)習(xí)C語言的開源項(xiàng)目。在閱讀代碼時(shí),會(huì)看到保存數(shù)據(jù)到文件時(shí)會(huì)用到fsync函數(shù),再去深入地了解一下這個(gè)函數(shù)的作用。這樣比單純地去看那些著作效果要好很多。
(三)網(wǎng)絡(luò)編程及相關(guān)知識(shí)
關(guān)于網(wǎng)絡(luò)方面,以下三點(diǎn)是必會(huì)的技能:
a)網(wǎng)絡(luò)協(xié)議。在日常的工作中,大家接觸和使用最多的無疑是TCP/IP協(xié)議族。此外,由于工作領(lǐng)域不同,也可能用到其它的協(xié)議。比方說,做電信相關(guān)的程序開發(fā),平時(shí)可能接觸SCTP協(xié)議會(huì)更多一些。對(duì)于這些協(xié)議,掌握最基本的知識(shí)是必須的,其它的邊邊角角知識(shí)可以等到用時(shí)再查。舉例來說,TCP協(xié)議的“三次握手”,“四次揮手”,“TIME-WAIT狀態(tài)”這些基本的知識(shí)點(diǎn)要弄明白,其它的邊角知識(shí)學(xué)完老不用忘得也快,還是用時(shí)google一下效率更高。
b)Socket編程。Socket編程的經(jīng)典書籍一點(diǎn)不比講系統(tǒng)編程的書薄,所以可以選一本相對(duì)薄點(diǎn),口碑不錯(cuò)的精讀一下,這樣基本就掌握的百分之五、六十了。另外有時(shí)間還是看一下經(jīng)典的開源代碼。這里還拿Redis舉例,Redis里關(guān)于處理網(wǎng)絡(luò)連接和通信的代碼量不大,而且基本涵蓋了所有常見的UNIX平臺(tái),看完以后一定受益匪淺。
c)協(xié)議分析工具。TCPdump、snoop(Solaris平臺(tái)工具)、wireshark等這些工具不僅能幫助我們抓取數(shù)據(jù)包,還能分析數(shù)據(jù)包,這對(duì)debug網(wǎng)絡(luò)程序有非常大的幫助。所以,我們至少要掌握這些工具最常用的功能。此外,對(duì)于開放源代碼的工具,我們更是可以從代碼中學(xué)到很多知識(shí)。舉例來說,做短信相關(guān)的項(xiàng)目,可以從wireshark的分析短信協(xié)議的代碼里學(xué)到很多東西,這可以幫助開發(fā)者對(duì)短信協(xié)議有了更清晰的理解。
(四)腳本編程能力
一提到腳本編程,大家首先想到的可能就是Bash shell腳本編程了。不錯(cuò),在Unix/Linux上,Bash shell也許就是用的最廣泛的腳本編程語言。應(yīng)用開發(fā)工程師主要用Bash shell做兩個(gè)方面的工作:a)用于編寫監(jiān)控服務(wù)腳本;b)寫一些簡(jiǎn)單的單元測(cè)試腳本,比如循環(huán)發(fā)一些命令,等等。但是Bash shell的功能遠(yuǎn)遠(yuǎn)要比這些強(qiáng)大。一些高手用Bash shell編程語言寫出了很好玩的游戲,也有人做出了很cool的網(wǎng)絡(luò)應(yīng)用。所以建議大家有興趣可以多了解一下Unix/Linux的這層“殼”。當(dāng)然,你也可以選擇學(xué)習(xí)Python、Perl、Ruby等。不過相比這些語言,Bash shell至少你不用自己去安裝,而且它能做的事同樣很強(qiáng)大。
(五)操作系統(tǒng)及CPU體系結(jié)構(gòu)
也許有一天,你會(huì)碰到這樣的情景:你的程序在Solaris上會(huì)發(fā)生core dump,在Linux上卻運(yùn)行的好好的。經(jīng)過一番艱苦的debug,最后得到的原因是兩種操作系統(tǒng)對(duì)線程的調(diào)度策略不一樣,這會(huì)使一個(gè)對(duì)全局變量沒有加鎖就訪問的bug在Linux上很難出現(xiàn)。所以你需要盡可能地去了解你使用的操作系統(tǒng),這樣無論對(duì)寫程序還是debug都會(huì)有很大的幫助。比如,你需要了解進(jìn)程的內(nèi)存布局,這樣你就知道棧和堆到底在內(nèi)存的哪段空間,為什么內(nèi)存寫越界有時(shí)會(huì)core dump,有時(shí)沒事。
除了操作系統(tǒng),了解CPU的體系結(jié)構(gòu)也是一門必修課。比方說,SPARC CPU要求字節(jié)對(duì)齊,而X86 CPU則沒有這個(gè)要求。又比如SPARC CPU是大端模式,而X86 CPU是小端模式,這就要求你對(duì)像位域這樣的定義要格外小心。你還要了解你使用的CPU的匯編語言,至少能大概看懂。因?yàn)橛行r(shí)候,當(dāng)你從C代碼中找不出bug的原因時(shí),就需要你“透過現(xiàn)象看本質(zhì)”,從匯編代碼層面看看到底發(fā)生了什么。
(六)編譯器和調(diào)試器
“工欲善其事,必先利其器”。編譯器負(fù)責(zé)把源代碼生成可執(zhí)行文件,而調(diào)試器則是在程序出現(xiàn)bug時(shí),用來“降妖除魔”的不二神器。以大家最熟悉的gcc和gdb為例子。
gcc有很多編譯選項(xiàng),除了要熟悉像-O,-g這些最基本的選項(xiàng),建議大家可以多了解一些其它不常見的選項(xiàng)。因?yàn)檫@些選項(xiàng)很可能幫助我們找到程序的一些bug。舉個(gè)例子,在比較新的gcc版本里,增加了-fstack-protector這個(gè)選項(xiàng),而它可以幫助我們檢查到緩沖區(qū)溢出這種bug。此外,你還可能碰到這種情況,一個(gè)bug總是發(fā)生在程序優(yōu)化后的版本,而不會(huì)出現(xiàn)在沒經(jīng)過優(yōu)化的版本。所以,多了解你的編譯器,你就可以更好地了解你的程序是如何生成的。
一個(gè)程序員不可能不碰到bug,而這個(gè)時(shí)候,調(diào)試器就是最好的工具。可以說,在遇到bug時(shí)調(diào)試技巧和手段是否豐富是衡量一個(gè)程序員的能力和水平的重要參考。除此以外,gdb另一個(gè)重要用途就是分析程序的core dump文件。程序的core dump文件好比一樁刑事案件的“犯罪現(xiàn)場(chǎng)”,而gdb則是刑偵官員用來在現(xiàn)場(chǎng)提取線索的工具。對(duì)gdb越熟悉,就越能從core dump文件提取有價(jià)值的信息,也就越有助于我們定位到程序bug的“root cause”。
(七)DTrace/SystemTap
DTrace是由Sun的幾位才華橫溢的工程師開發(fā)的,最開始只支持Solaris操作系統(tǒng),現(xiàn)在FreeBSD和Mac OS X也都支持了。Linux上類似的工具有SystemTap,也有人把DTrace移植到Linux上,不過效果似乎并不好。簡(jiǎn)單地說,DTrace可以幾乎不會(huì)在對(duì)整個(gè)系統(tǒng)有任何性能影響下,讓你了解你的程序所發(fā)生的一切。這對(duì)分析程序的熱點(diǎn)(“Hot spot”),了解程序的執(zhí)行流程,定位程序bug都有很大的幫助。有些時(shí)候,DTrace可能是你唯一的工具。舉例來說,有個(gè)程序只發(fā)生在生產(chǎn)環(huán)境,而在實(shí)驗(yàn)室環(huán)境無法復(fù)現(xiàn)(當(dāng)然,理論上任何bug都可以復(fù)現(xiàn),只是我們沒有找到復(fù)現(xiàn)條件。)。你不可能在你懷疑的代碼打上斷點(diǎn),然后用gdb去調(diào)試。這時(shí)你只能借助于DTrace,通過它去了解程序到底是如何運(yùn)行的,當(dāng)時(shí)的變量值是什么。此外,DTrace還可以幫你了解操作系統(tǒng)的kernel,這會(huì)滿足很多geek的好奇心。
本文版權(quán)歸傳智播客C++培訓(xùn)學(xué)院所有,歡迎轉(zhuǎn)載,轉(zhuǎn)載請(qǐng)注明作者出處。謝謝!
作者:傳智播客C/C++培訓(xùn)學(xué)院
首發(fā):http://xamj520.com/c/