一個普通碼農的Linux之路

1.

Hi,大家好,我是奔跑的碼仔,是一名長期混跡於Linux江湖,靠Linux喫飯的程序員。生活在一個IT大環境不好的二線城市,大家也知道,這裏的程序員本來就很稀少,況且是Linux程序員呢,就更是稀有物種了!可是,不是有那麼一句老話嘛,物以稀爲貴。你還別說,雖然,這裏的Linux崗位較少,但是,薪資總體還是蠻有競爭力的。所以,纔會有時間來總結自己的Linux學習之路(不然,早就去加班掙生活費了,哈哈)。
但是,最近,自己總是焦慮一個事。那就是自己雖然一直以Linux爲生,這些年,也接觸了不少的Linux的技術(這些技術不管是工作上用的着的,還是自己感興趣利用業餘時間自學的)。但是,仔細一想,和Linux接觸這麼長時間,自己真正可以拿的出手的作品好像沒有多少,一些學習心得也沒有及時的形成文字記錄下來,在自己所從事的領域也沒有形成技術影響力。作爲一個技術人,每每想到這些,內心都十分的失落。所以,思來想去,爲了能夠更好的學習Linux,也爲了能夠接觸更多的志同道合的人,我決定,以文字的形式記錄下我自己的學習過程。順便,如果這些文字能夠能給大家帶來些許收穫,那我將感到十分的榮幸。其實,記錄自己的學習、成長軌跡是一個很好的學習方法,這些文字日後會形成寶貴的財富,這樣當自己回望過往時,就不會因爲碌碌無爲而悔恨和遺憾了。下面開始述說我自己的一些經歷和體驗。

2.

記得,第一次接觸Linux系統,是從大三的Linux高級程序設計這門課開始的。不知不覺,與Linux相伴已經有將近8個年頭了。依稀記得,當初剛開始接觸Linux時的那種迷茫、無助的感覺。因爲習慣了Windows“友好”的使用界面,常常被Linux命令行的使用模式而弄的狼狽不堪。而且,記得那會兒嘗試過很多種Linux桌面發行版本,什麼Ubuntu 9.10(時間過得真快,現在都19.10了)啦,Debian啦,CentOS啦,SUSE啦等等。有人可能會問,爲啥這麼花心,感情也太不專一啦!哈哈,說出來原因,大家可能會笑話,原因大概爲兩種:一種是系統老是崩潰,所以得重裝,重裝時就想試試其他的版本是不是好用,其實是因爲自己技術太菜;另一種就是不會安裝軟件,對於初學者編譯、安裝Linux下軟件簡直太痛苦了。那時候經常能夠遇到的場景就是,系統環境不支持某些應用,所以需要自己手動的配置依賴庫啦,安裝新的環境啦,但是不會啊(相信,這也是也是很多初學者入門Linux的障礙),又迫於完成作業或者課程設計,只能不斷的嘗試不同的發行版本,不同的搜索前人的解決方法,有時實在找不到解決辦法,最後只能不了了之!這就是我痛苦的Linux自我啓蒙階段。雖然,這個階段比較痛苦,但是,憑着那股子傻勁,最終沒有放棄Linux的學習,堅持了下來。想到這,內心還是有些許安慰的。

3.

後來,參加了工作,結束了之前非專業的學習、開發模式。開始接觸一些真正的項目了,真正的開始學習如何基於Linux系統進行開發。這也是我技術能力成長較快的一個階段。記得,那時開發的第一個項目是一個關於網絡數據分發的系統,底層框架是基於ACE的(那時候ACE是Linux系統下網絡開發的標準框架吧),我負責的是SNMP客戶端的設計、實現工作。也是從那時,我開始瞭解如何編寫Linux網絡程序、如何使用GDB調試Core文件以及如何使用Linux系統各種各樣的系統調用。也是在那段時間,我買了UNIX界的聖經《UNIX環境高級編程》,並開始研讀,這本書十分的系統,幾乎涉及到了類UNIX系統開發的方方面面,作者對技術的精準講解,令人歎爲觀止。工作中,大部分涉及到Linux系統的開發問題,幾乎都能在裏面找到答案,可謂是Linux開發者的良師益友。我覺得,如果選擇了Linux開發這個領域,這本書是不得不讀的,而且要反覆的讀,因爲大量技術細節不是一遍,兩遍就能理解的了的。還有,我發現,這本書有一個十分的神奇地方,那就是隨着自己工作經歷的增加,每次研讀,從書中我都會有新的收穫。這一方面說明自己對技術的理解力在不斷的提高,另一方面也說明,這本書裏不僅僅是對技術知識的單純講解,最重要的是,他是有思想和靈魂的,而這就是Linux能夠長盛不衰的根本原因吧。那段時間的工作經歷使我明白了Linux系統是什麼,基於它能實現什麼功能,以及如何基於它實現自己的想法。我覺得從那之後,自己算是入門了。後來,隨着工作的深入,我漸漸開始瞭解Linux的底層工作原理,像進程是啥,線程是啥,他們如何工作?進程和線程如何相互通信?Linux內存是如何管理的?Linux的TCP/IP協議棧是如何設計實現的等等。雖然,這些東西十分的硬核,學起來十分的痛苦。但是,越是不懂我就越覺得它神祕,也就越想去了解它,慢慢的的也就喜歡上了這種感覺。其實,對未知領域的探索,並最終能夠理解它的過程,是能給人帶來無盡的成就感的,那是一種美妙的享受。

4.

之後,由於換了工作,開始接觸嵌入式Linux的開發。嵌入式Linux開發,需要更爲全面的Linux技術,而且是十分底層那種,因爲你常常需要解決的是如何從無到有的設計一個系統。例如,給你一個硬件平臺,你需要從零搭建BootLoader、Linux內核、根文件系統、系統工具這一整套系統。這就需要你不僅懂得如何基於Linux平臺開發應用程序,還需要理解諸如編譯器原理,Linux內核移植,文件系統的構造方式和原理,驅動程序的編寫,Make構建系統,shell腳本等等基礎知識。這個階段,我從系統層面瞭解了Linux系統在嵌入式系統上的應用方式和開發模式,進一步增強了對於計算機基礎原理的理解、認知。那麼,如何能夠快速入門嵌入式Linux呢?我的是方法是多看、多學習行業社區的實踐,然後將學到的技術及時的應用到工作中去,最終內化自己的技術。嵌入式Linux相關的社區有很多,比如,著名的路由器固件OpenWrt,系統構建系統buildroot、交叉工具鏈發佈者linaro等等。我們可以挑選自己關心的領域,然後積極的參與進去,社區裏高手林雲,我們可以和他們零距離的接觸,學習到很多高階的技術,這對於自己今後的技術職業道路大有裨益。最後,說一下,對於學習Linux內核的看法。嵌入式Linux開發,會或多或少的接觸到Linux內核的東西。但是,常常接觸到的都是某一個點的技術,常常有一種身在林中不見林的感覺。**這時候,個人經驗就是跳出固定的技術點,去嘗試理解這個點所在的”林“,也就是去理解整個子系統,重點搞懂子系統在整個系統的位置、作用,子系統的框架,抽象模型,然後就是如何基於子系統提供的模型進行功能模塊的設計、開發等。**例如,某款芯片基於I2C通信的,這時候,我們就需要去了解I2C子系統的框架和編程模式,然後再去實現具體的芯片的驅動程序的設計和開發。而且,Linux內核的各個子系統的設計思想是想通的,只要徹底搞明白幾個系統,其他的子系統大都類似,這樣,你就可以觸類旁通了。

5.

如今的Linux技術遍佈各個領域,比如,數據中心的服務器幾乎都是基於Linux系統構建的,IoT領域的設備端也有很大一部分是基於嵌入式Linux系統構建的,再比如,時下如火如荼的AI,也有很多的關鍵部件是基於Linux構建的。可以說,Linux無處不在,Linux已經成爲了整個計算機世界的基礎核心技術,相信未來的Linux技術必定大放異彩。但是,Linux的學習之路是十分陡峭的,剛開始的時候可能十分的痛苦。那如何才能避免Linux學習之路的”開始即結束“的困境呢?結合自己的親生經歷,談談一些感想:

1. 切勿好高騖遠,學習還需腳踏實地。

Linux世界的技術,紛繁複雜,其有很多的技術特別有吸引力。有些人一開始,爲了追求這些高精尖的技術,就奮不顧身的投入到了Linux內核的學習之中。比如,當前流行的容器技術,在沒有上手實踐容器應用之前,就開始學習Linux內核關於容器的實現原理,然後,一頭扎進浩如煙海的Linux內核代碼之中。這類人最後基本都是由於缺乏Linux基本技術認知,而最終“淹死”在Linux內核的海洋中。所以,對於剛開始接觸Linux的人來說,還是要腳踏實地的去學習Linux的最爲基本的技術。我的建議是,首先是丟掉之前靠鼠標點擊操作計算機的習慣,逼自己去習慣Linux命令行的操作模式。就從,最最簡單的命令開始學習,通過命令行操作去理解Linux系統的工作方式、運行原理。這裏,推薦《鳥哥的Linux私房菜》,這本書可以說是Linux入門的聖經,裏面詳實的講解了Linux系統方方面面的命令操作,是Linux命令的百科全書。可以說,這本完全可以幫你打開Linux的這扇大門。還有一點建議就是,對於Linux命令的學習,切記,不能紙上談兵,任何一個命令都得上機進行實操,只有這樣你才能直觀、真切的體會到命令的高效和價值。這是第一點建議。

2. 層層遞進,步步爲營。

在有了一定的Linux系統操作經驗之後,可以嘗試基於Linux系統做一些開發項目。可是,Linux系統的開發能力實在太強,可以做的事情實在太多太多了,對於新人來說可能感到無從下手。這裏,說三點建議:

  1. 第一就是以工作內容爲導向,由點及面,步步爲營
  2. 第二就是系統性的學習Linux的環境編程,這裏推薦通讀《UNIX環境高級編程》
  3. 第三就是選擇基於Linux的開源項目,分析其使用到了哪些Linux技術,以及如何運用的,而後如何形成一個系統,其系統框架是怎樣的等等。

其實,這三點存在層層遞進的關係:首先,工作中用的知識比較零散,經常遇到的問題大多隻涉及某個技術點,形成不了系統,而通過系統學習Linux環境開發相關的經典書籍可以加快促進將技術點形成技術面,從而最終系統化技術。之後,再通過對於優秀的開源項目的分析、學習,可以進一步的加深對於Linux系統的整體認知,豐富我們對於Linux技術的應用方式。經多幾次詳盡的開源項目分析,從而,最後逐步的掌握Linux系統開發的精髓。

最後,關於Linux系統API的使用談一下自己的建議。開發過程中,免不了會經常涉及到各種Linux系統API的使用,這其中包括系統調用和glibc函數。如何正確的使用這些API進行開發呢?我的建議是,拿到一個函數API之後,第一件事就是使用man手冊進行查看。爲什麼呢?因爲,man手冊的編寫者一般都是API的開發者或者維護者,裏面詳細介紹了該API的功能,基本原理,參數解析,返回值。更關鍵的是,它會詳細的說明API的注意事項,使用限制,存在的bugs等,這些可以讓你避免大多數坑,從而一開始就讓你寫出健壯的程序。所以,堅持man是學好Linux的良好的習慣,也是最有效的開發、學習捷徑。

3. 技術無止境,學習要更上一層樓。

在有了較長時間的Linux系統開發經驗之後,我們可能會不滿於簡單的使用linux進行應用開發了。那如何才能在Linux領域更上一層樓呢?其實,目前,我也處於這個階段,沒有太多的發言權。只能說一下自己的一些經驗,供大家參考。我的經驗有兩個:

  1. 第一個:根據自身行業特點,找到工作痛點,然後編程解決該痛點。 或者爲了提高開發效率,設計實現開發工具庫,甚至開發框架。拿我自己來說,以前拿到一個新項目後,總是需要從頭設計、開發各個基礎工具庫,比如日誌系統,線程管理模型,線程同步模型,字符串處理模型等,這樣大大降低了開發效率,極大的浪費了開發資源。後來,我整理了各個項目使用到的各種基礎構件,對其進行了重構,最終整合形成了一套應用的基礎開發庫。這樣做的好處有(1)極大的提升開發效率。(2)極大的提升系統的穩定性。對基礎庫的每次使用,其都是一次蛻變,bug越來越少,進而,提升系統穩定性。

  2. **第二個:有效的學習Linux內核。**對於Linux內核學習,我也是一個菜鳥。雖然,之前進行了一些內核移植和驅動的開發工作,但總覺得那些只是基於Linux內核在進行應用開發,沒有真正的從操作系統的角度學習到Linux的設計精髓。所以,我開始了對於內核的學習。但,我不建議,內核新人一開始就閱讀那些大部頭的內核經典,不是說它們的內容不好,相反,它們寫的太好了,只是不適合初學者。**我的理解是,這些經典,有一個問題是,對某個技術點詮釋的特別到位,但是對與內核的整體框架以及各個子系統之間的關係缺乏解釋。這就是十分容易使人陷入具體的細節之中,而不能對系統有一個整體的認識,最終,花了很多的精力還是不能理解內核。**我的做法是,對於某個系統的分析,不急於理解具體細節,首先梳理系統的各個主要流程,找到系統的各個關鍵點,對系統在腦子裏有一個總體的理解。然後,再深入去學習具體的實現方式。由於腦子裏,一直有一個總體的概念,不至於在學習的時候迷失方向。**就好像,在一個陌生的地方,手裏有一份地圖,無論怎麼走,都不太容易迷路一樣。**所以,內核的學習,我的方法是腦子裏先形成內核地圖,然後在再按圖索驥,各個擊破難點,最終理解整個內核。

6.

說了這麼多,都是自己這一路走來形成的一些想法。但由於個人技術能力的限制,肯定有很多理解的不恰當的地方,還望大家多多包涵。歡迎志同道合之士,前來切磋指教。最後,我想說的是,技術無止境,沒有所謂的萬能之法。作爲技術人,我們只有不斷的奔跑,積極的去面對變化,才能立於不敗之地。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章