對於一個C編程人員來説,精通C語言是一項基本技能。網上有許多經典文章討論如何學好C語言,以及C語言的主題。許多人在工作了一段時間後,自認為自己已經掌握了C語言。可以實際工作了,接觸的東西也多了,開源項目多了之後,才發現自己的C語言能力太一般了。宏函式不斷變化的寫法,指針繁複繁複的用法,等等。在編寫代碼時,應該經常問自己:這種行為是否由C規範定義?假如有,是89還是99?目前我使用的編譯支持嗎?在這個由C規範定義的程序運行的平台上,行為是否被確定?因此建議大家平時可以多想想這些問題,查一下資料,相信一定會對C語言有更深的瞭解。
編寫UNIX/Linux系統。
掌握系統編程API是在UNIX/Linux系統上開發程序的一項基本技能。而且這方面的經典書籍都是一些大篇幅的英文書,令人望而生畏。先找一本口碑不錯的中文書先看看,瞭解一下里面都有哪些類型的API。因此,在以後使用時,要仔細閲讀經典英文著作中的相關章節,或查閲man手冊。另外,如果有時間,你可以學習一些經典的開源項目,看看它們是如何使用這些API的。例如,Redis就是許多人推薦的一個非常好的學習C語言的開源項目。讀代碼時,您會發現,當將數據保存到文件中時,fsync函數將被使用,然後再深入分析這個函數的功能。這遠比單純看書的效果要好得多。
網絡編程及相關知識。
在網絡方面,需要具備以下三項技能:
(a)網絡協定。每天的工作中,大家接觸使用最多的無疑就是TCP/IP協議族了。另外,由於工作領域不同,也可以使用其他協議。比如説,做電信相關的程序開發,平時可能接觸的SCTP協議會多些。在這些協議中,掌握最基本的知識是必須的,其他的邊角知識可以在使用的時候再查。例如,TCP的“三握”、“四揮”、“TIME-WAIT狀態”等基本知識點都要弄清楚,其他邊角知識學完老不忘也快了,還是用時google一下更有效。
(b)Socket程序。《Socket編程》的經典書籍一點也不比《系統編程》的書少,所以可以選擇比較薄一點,口碑很好的精讀一下,這樣基本就能把握五六十分。還有時間還是去看看經典的開源代碼吧。以Redis為例,Redis中只有很少的代碼用於處理網絡連接和通信,並且基本上覆蓋了所有通用的UNIX平台,看完之後一定會受益匪淺。
(c)協議分析工具。snoop(Solaris平台工具),wireshark等等這些工具不僅可以幫助我們獲取數據包,還可以分析數據包,這對於debug網絡程序是很有幫助的。因此,我們至少應該掌握這些工具的最常用功能。另外,對於開放源代碼的工具,我們可以從代碼中學到更多。例如,做與SMS相關的項目,可以從wireshark的代碼中學習到很多關於分析SMS協議的知識,這有助於開發人員更清楚地瞭解SMS協議。
腳本編程能力
談到腳本編程,大家第一個想到的可能是Bashshell腳本編程。很好,Bashshell可能是Unix/Linux上使用最廣泛的腳本編程語言。在Bashshell中,應用開發工程師主要完成兩項任務:a)編寫監控服務腳本;b)編寫一些簡單的單元測試腳本,例如在循環中發送一些命令等等。但Bashshell遠比這些更強大。有些高手用Bashshell編程語言寫出了非常有趣的遊戲,也有人制作了非常實用的網絡應用程序。因此,對於Unix/Linux,建議您可以瞭解更多關於它的“外殼”。你也可以選擇學習Python,Perl,Ruby等等。Bashshell相對於這些語言來説,至少你不需要自己安裝它,它的功能也同樣強大。
操作系統及CPU體系結構
有朝一日,您可能會遇到這樣的情況:coredump程序會在Solaris上運行,而在Linux上運行得很好。在經歷了大量的debug之後,最終得出這個結果的原因是,兩個操作系統對線程的調度策略不同,這使得在Linux中訪問全局變量時不加鎖的bug很難出現。因此,您需要儘可能地瞭解您所使用的操作系統,因此,不管是編寫程序還是debug,都將非常有用。例如,您需要了解進程的內存佈局,以便您知道棧和堆究竟位於內存的哪個部分,以及為什麼內存寫入超出限制,有時是coredump,有時是好的。
除操作系統外,瞭解CPU架構也是一個必要的課程。比如,SPARCCPU要求字節對齊,而X86CPU不要求字節對齊。例如,SPARCCPU是大端模式,X86CPU是小端模式,這就需要你特別注意像位域這樣的定義。您還需要了解您使用的CPU的彙編語言,至少可以大致瞭解它們。有時,當你無法從C語言中找到錯誤的原因時,你需要“透過現象來看本質”,從彙編代碼的層面上來看到底發生了什麼。
編譯器和調試器
「工欲善其事,必先利其器。」編譯器負責生成源代碼的可執行文件,而調試器是一個不二神器,當程序出現bug時,它會被用於“降妖除魔”。例如,我們最熟悉的gcc和gdb。
除了熟悉諸如-O,-g等最基本的選項之外,gcc還有許多編譯選項,建議您可以瞭解更多其他不常用的選項。由於這些選項可以幫助我們發現程序中的一些錯誤。例如,在比較新的gcc版本時,添加了-fstack-protector選項,這有助於我們檢查bug的緩衝區溢出。另外,您可能會遇到這樣的情況:bug總是出現在經過程序優化的版本中,而不出現在未經優化的版本中。因此,瞭解更多關於編譯器的知識,您就能更好地理解程序是如何生成的。
編程人員不可能不遇到bug,此時調試器就是最好的工具。當遇到bug時,調試技巧和方法是否豐富是衡量一個程序員的能力和水平的重要參考。除此之外,gdb的另一個重要用途是用於分析程序的coredump文件。coredump程序就像是一個刑事案件的“犯罪現場”,而gdb就像是刑偵人員用於提取現場線索的工具。越熟悉gdb,就越能夠從coredump文件中提取有價值的信息,並且越有助於找到程序bug的“rootcause”。
DTrace/SystemTap
DTrace是由Sun公司的一些優秀工程師開發的,他們最初只支持Solaris操作系統,現在也支持FreeBSD和MacOSX。linux中有SystemTap,還有人將DTrace移植到linux中,但效果並不理想。簡而言之,DTrace可以讓您瞭解您的程序所發生的事情,而這幾乎不會對整個系統造成性能影響。對於分析程序熱點(“Hotspot”)、理解程序執行過程、查找程序bug都是非常有用的。有時候,DTrace可能是你唯一的工具。例如,有一個程序只發生在生產環境中,而不能在實驗室環境中再現(當然,理論上任何錯誤都能再現,但我們找不到再現條件)。您無法對您懷疑的代碼進行斷點處理,然後使用gdb進行調試。此時,您只能藉助於DTrace,通過它來理解程序實際如何運行,以及變量在當時的值是什麼。另外,DTrace可以幫助您瞭解操作系統的kernel,它滿足了許多geek的好奇心。