(推薦)爲什麼要走嵌入式?

我們從解讀幾個問題開始:

1、各種軟件技術之間是怎樣的關係?
    軟件技術分爲三個層次:
    問題域:計算機圖形學、音視頻編碼、信息安全、模式識別、信息檢索、自然語言分析、人工智能、科學計算、專家系統等;
    系統集成:C++和Java等面嚮對象語言、Python等解釋型語言、LISP等函數式編程語言、GUI、中間件、編譯器與解釋器、虛擬機、數據庫、網絡服務、並行計算、集羣、Peer2Peer、系統管理等;
    系統功能:硬件描述語言、計算機體系結構與編程模型、指令集與彙編語言、C語言、內核、文件系統、設備驅動、網絡協議、POSIX等。

    計算機最終是做什麼用的呢?最終是通過問題域的各種技術爲用戶解決問題的,這些技術都包含很高深的算法,然而它們必須在一個平臺上運行,它們需要利用平臺提供的各種基礎設施,比如計算能力、I/O能力和網絡互聯能力。系統功能和系統集成層就是用來實現這個平臺的。系統功能層實現計算、I/O和網絡的基本功能,系統集成層對這些基本功能做一些抽象和包裝,提供更方便靈活的接口。

    2、爲什麼要學習嵌入式技術?
    學習嵌入式系統,你將需要詳細瞭解系統功能層的各部分是如何工作的,也會在面向對象編程、GUI、數據庫、網絡服務等系統集成層的技術方向進行探索。嵌入式系統可說是麻雀雖小五臟俱全,雖然沒有PC和服務器那麼複雜,但計算機系統的各種組成一樣也不缺。因此,以嵌入式系統作爲切入點開始學習軟件技術是非常好的選擇,避開不必要的複雜性,把握計算機系統最根本的概念和技術要點。打下紮實的基礎之後,你的職業發展則完全不必侷限於嵌入式領域,即使你日後做PC或服務器開發,學習嵌入式所得的知識和技能同樣使你終生受益。正如庖丁解牛,心中有全牛,自然就能遊刃有餘。

    另一方面,你一定見到各大媒體都有大量的宣傳,說現在嵌入式行業前景空前的好,嵌入式人才緊缺,有幾百萬職位空缺等等。這些說法也是對的,但我們需要更深入地理解這說明了什麼問題。剛纔我們說,嵌入式系統也是一個完整的計算機系統,和PC或服務器沒有本質的區別,事實上,嵌入式、PC和服務器的界限已經越來越模糊了。以前的嵌入式就是單片機,只能做簡單的運算處理,現在的很多嵌入式處理器性能比從前的奔騰還強,打遊戲、看電影都沒問題,誰能說它不是PC呢?另外有些專用的嵌入式系統已經在充當服務器的功能了,而集羣技術更是可以使許多廉價的處理器組合在一起發揮大型服務器的作用。由於嵌入式越來越多地應用到家用電器、汽車和控制領域的各種設施上,無處不在,並且與PC、服務器呈融合的趨勢,所以嵌入式行業前景空前的好。

    那麼,爲什麼說嵌入式人才緊缺呢?其實,學嵌入式系統就是學計算機系統,本質上並沒有什麼特殊的只有嵌入式系統纔有的技術。說嵌入式人才緊缺,其本質上是說真正懂計算機的人才少。現在很多學校的所謂“軟件學院”培養的軟件人才都是一葉障目不見泰山的:只懂J2EE和.NET,即便學過C和彙編,也沒有把它們作爲核心課程;只會調庫函數sort(),而對各種排序算法一無所知;設計模式、軟件工程講得頭頭是道,卻不知道好的軟件還是要靠牛人靠智商來做的。培養人像蒸包子一樣一屜一屜地出,靠軟件工程搭一條生產線,然後讓熟練工人站在生產線上擰螺絲,幻想着這樣就能生產出好的軟件,那是把軟件工程和程序員的作用本末倒置了。現在嵌入式開發對程序員的素質要求更高了,以上這類“軟件人才”不能勝任了,因此說嵌入式人才緊缺。所以要培養一種有完整的計算機系統概念的軟件人才,而不是隻會擰螺絲的軟件工人。

    3、有人說軟件技術變化太快,現在學的東西過兩年就要完全淘汰,是嗎?
    你知道這話是什麼人說的嗎?必然是已經被淘汰的人說的。比如Delphi、BCB、PB這些開發工具和語言,都曾經很是風光了一陣,但現在已經完全被Java和.NET取代了。那麼Java和.NET會不會被取代呢,也許在相當長的時間內還不會。

       這些被淘汰的程序員有一些共同的特點:只會用鼠標拖拽控件,離開IDE就不知道如何工作,學點兒花拳繡腿的功夫就想吃一輩子,對學習新技術不感興趣,做一天和尚撞一天鐘。現在請回頭看看1,在整個軟件技術領域,這些變化快的技術其實只佔了很小的一塊,卻成了這些人的全部看家本領,這樣的人能不被淘汰嗎?

     與這些流行的開發工具和語言相反,很多技術和思想是很少變化的。比如,POSIX和SUS標準規定了一套系統函數接口和基本命令的語義,只有實現了這些纔可以稱作UNIX,因此今天的Linux、Solaris跟20多年前的UNIX在系統功能層上是基本一致的。而指導計算機科學發展的數學理論,甚至是老祖宗們在計算機還沒誕生的年代就替我們想好的:布爾代數發表於19世紀,直到一個世紀後發明了計算機和數字電路纔有了用武之地;數論在17世紀就出現了,一直都被數學家們當成一套好玩的理論,但只是好玩而已,直到計算機密碼學誕生後才發現它的實際用處。

    各種流行的開發工具和高級語言雖然變化很快,但是底層的編程語言卻非常穩定,各種操作系統的內核都是用C語言寫的,以前是這樣,以後也不會改變。另一方面,各種編程語言的設計思想也是非常穩定的。其實世界上只有兩種編程語言,一種是C,一種是LISP,前者是imperative的,是對計算機模型的抽象,後者是functional的,是對數學函數模型的抽象。面向對象是一種重要的軟件工程思想,卻算不上一種新的語言模型,應該歸在C的一類。屬於同一類的各種語言其實都大同小異,一個精通C++的人學習Java需要多長時間?熟悉語法一個星期,熟悉類庫三個星期,一個月足矣,以往的經驗都可以套到新的編程語言上。然而要想習得深厚的算法功底、邏輯思維和抽象思維修養,能夠真正說清楚“系統”是什麼,如何分析和設計“系統”,需要多長時間?恐怕要數十年。

    4、C和Java哪種語言更好?
       計算機科學與編程語言無關,甚至與計算機本身也沒太大關係,它研究的對象並不是計算機,而是人分析問題解決問題的方法論。程序寫出來最主要不是爲了給計算機執行的,而是爲了給人看的,使用編程語言和使用自然語言一樣是爲了表達和交流,只不過程序還可以順便給計算機執行而已。

       以上這些話並不是我說的,而是一位著名的計算機科學家說的。所以,在編程語言的層面上爭論是沒有意義的。很多初學者錯誤地認爲掌握了編程語言就等於學會了計算機,一種編程語言都還沒有掌握好,更沒有上升到方法論的層面,只有這種無知的人才會去爭論哪種語言好的問題。掌握了編程語言遠遠不等於學會了計算機,而只是最開始的一步,最簡單的一步,到了工作中,用到什麼語言就去學什麼語言,什麼語言過時了就丟掉,編程語言不需要積累因爲它太簡單了,真正需要積累的是方法論。

       很多人喜歡參與到這類爭論之中,毫無例外,每個人都在爲自己熟練掌握的編程語言辯護,就是“我會的語言最好,我不會的語言都不好”,其實這些人真正想說的是“我會的語言最好是千秋萬代,我就不必學新的語言,不必適應新的變化了”,概括起來說就是一個字,懶。真正的高手都是會很多編程語言的,國外有些做技術諮詢的,每年都要學好幾門新的編程語言,這樣才能應對市場的變化。不斷丟掉舊的編程語言學習新的,看起來好像完全是白費力氣,沒有積累,其實,每種編程語言的設計都有獨到之處,體現了每種語言的精髓,在融匯百家之後積累下來的正是方法論。

       爭論哪種語言能做的事情更多、功能更強是沒有意義的。從理論上說,任何一種符合圖靈機模型的編程語言,加上適當的I/O擴展都可以做任何事情,用shell腳本也可以寫出很像樣的遊戲來。只不過各種語言的設計目標不同,表達能力不同,做不同的事情所需的代碼量不同而已。

       另外一種錯誤認識是:哪種語言的市場最大,開發人員最多,哪種語言就最好。單從這種意義上說,Java的確比C更好,所以往屆有學員問我們爲什麼只教C語言。請你注意,操作系統內核是用C寫的,各種底層的應用程序包括Java虛擬機也是用C寫的。如果你想學Java,學習完嵌入式後你將有能力分析Java虛擬機的實現,站在計算機系統的高度來學Java纔會使你成爲真正的Java高手。

    在FAQ3裏說過,世界上有C和LISP兩種編程語言,你現在學了C,以後學了C++、Java、.NET等等,也仍然只認識了半個世界。LISP和Haskell構成了另外半個世界,現在很常見的Python和JavaScript等解釋型語言也借用了functional programming的思想。如果你只管悶着頭寫代碼,而不去廣泛涉獵,那麼你將錯過很多精彩。

    5、我聽說編程編到三十五歲就沒人要了一定要轉行找出路是嗎?
    這個觀點雖然很流行,但根本不值一駁。現在三十五歲轉行的那些人,都具有前面所說的那些特徵,對學習新技術不感興趣,對探索計算機的本質不感興趣,得過且過,下了班就是打遊戲、看電視,總之就是懶。如果是開出租、擺攤,勤快人懶人都有飯吃,而IT這一行對懶人是非常無情的,懶人就不該入IT這一行,不從自身找原因,卻到處散佈這種言論,怪社會不好,打擊新人的信心,着實可恨。

      另外一種情況,編程編到三十五歲,進入公司的管理層,或者自己創業,這都是很勤快的人,如果他們把這種勤快用在技術上肯定也可以做得更好,所以也無法證明編程編到三十五歲會因爲沒有出路而轉行。

      編程不是個體力活,需要高強度的思考和智力投入,分析能力、思考能力都需要時間積累起來,所以並不是越年輕幹得越好。相反,我認爲三十歲以前寫的代碼都是垃圾,三十歲以後才能寫出像樣的程序來。如果希望一輩子走技術的道路而不會被迫轉行,就要不斷地把自己的工作性質從“體力活”變成“腦力活”。什麼叫“不斷地”變呢?這裏的“體力活”並不是指種地、蓋房子這種勞動,而是指簡單重複地編寫代碼,這時你會感覺,派給你的工作都能憑以往的經驗輕鬆應付了,但是千萬不要滿足於現狀,就像溫水煮青蛙一樣,這是危險的處境!要擺脫這種處境就需要學習、思考、提高,讓公司派給你更有挑戰性的工作,在工作中應用新學到的知識和技術就是“腦力活”了,但是用得久了又會變成簡單重複的“體力活”,這時就需要再學習、再提高,所以叫做“不斷地”把自己的工作性質從“體力活”變成“腦力活”。如果有一天你發現,自己長期陷於簡單重複的勞動之中,並且業餘時間非常少,無法學習提高,這說明公司不會用人,你就該考慮跳糟了。

       從另外一個角度來說,如果希望一輩子走技術的道路,就要有自己的核心競爭力,這個核心競爭力決不是憑以往的經驗能夠做某些工作的能力,而是學習能力、思考能力和解決有挑戰性的新問題的潛力。在IT這一行,憑藉以往的經驗乾重復的活是幹不長久的,原因很簡單,一個問題不會被解決兩次,當你發現你的經驗能夠解決一類問題時,別人早把解決這一類問題的套路編寫成framework,新上手的人即使不具備你的這些經驗也可以調用framework中的類和函數來解決問題,然後在這個framework的基礎上積累新的經驗解決新的問題。正因爲如此,全世界開發人員的經驗纔會積累起來,促使軟件技術發展得如此迅速。這並不是說經驗完全沒有用,最關鍵的,學習和思考也是建立在以往經驗的基礎之上的。另一方面,現有的framework並不一定是某方面開發經驗的完美整合,也需要不斷髮展,用新的辦法重新解決老問題,以Web開發爲例,從早期的ASP、PHP到後來的.NET、J2EE,到現在的Ruby on Rails、Django等等,這些framework解決的是同一問題,就是如何快速有效地開發Web應用,這方面的經驗被不斷重新整合,推陳出新。總結一下,什麼纔是核心競爭力呢?應該是在經驗的基礎上學習新技術、解決新問題的能力。

    6、做驅動開發還是做應用開發更有前途?
    意思就是說,“你告訴我哪個更有前途,我就好好學哪個,另外一個就不用學了”。問這種問題的學員往往會同時問另外一些問題:我以後就想做驅動開發,你教我這些應用開發的技術有什麼用?C++用得多嗎?學了有什麼用?我以後不想做GUI,你教我Qt有什麼用?

    學習最忌諱的就是“有用的就學,沒有用的就不學”這種功利的態度。兩個問題:第一,在你還沒學進去、還不瞭解這種技術時,要如何判斷這種技術學了有沒有用?只能是根據道聽途說,看各種論壇上都怎麼說的,豈不知論壇上參與這種討論的100%都是菜鳥,有的水平還不如你。第二,就算你學的技術沒有用上,有什麼損失嗎?從嵌入式工程師可以從事各種各樣的開發工作,有做驅動的,有做系統編程的,有做GUI的,有做Web開發的,只要確定了做一類工作,就不可能把嵌入式所學的知識都用上,但至少也用得上3/4的知識,假設剩下的1/4你一輩子也沒機會用上了,那也就損失你一個月的學習時間而已,相比於你的收穫,這算是很大的損失嗎?請注意,上面的假設是不成立的,沒用上的那1/4也只是暫時沒用上而已,程序員要換工作或者換項目是很常見的,任何人都不可能只涉及一類開發工作,只要有紮實的基礎、完備的知識體系,任何工作都能輕鬆上手。

    紮實的基礎,完備的知識體系,我們在安排課程體系的時候,正是以這兩點爲依據的。有的課程內容很少有學員在以後工作中會用到,但是缺了這一環就不成爲一個完備的知識體系,例如通過C++來講面向對象編程,通過Qt來講面向對象、事件驅動和狀態機編程,這些編程思想是程序員必備的基本素質,而C++和Qt可能有些學員以後工作用不到,那這種課該不該上呢?毫無疑問該上。至於還有些人爭論說C++不如Java用得多,Qt不如GTK用得多,請翻回去看FAQ4,這種爭論是無意義的,有工夫爭論誰優誰劣,不如把兩種都學了,會更有收穫。

    回到做驅動開發還是做應用開發更有前途的問題。我只能說,做好了都有前途,做不好都沒有前途,只會做一樣而完全不懂另一樣是最沒前途的。不要以爲內核開發者就不寫應用程序,Linus寫了一個源代碼管理系統git來維護內核,因爲覺得現有的源代碼管理系統都不好用。牛人都是這樣,需要什麼就寫什麼,纔不管是kernel space還是user space。同樣,做應用開發如果不懂內核,也沒有辦法很好地利用內核提供的服務寫出性能最優的程序。做內核難,因爲調試難,要跟蹤大量的併發線程,因爲入門難,要寫一個hello world都需要學很多知識。做應用也難,回頭去看1,計算機科學從理論到實踐大部分都在上面兩層做文章。所以不存在哪個更難哪個更有前途的問題,任何關於哪個更難的討論都是too naive的。

    7、我一開始看什麼書都看不懂,怎麼才能理出一個學習順序?
    以前有個學員在學C語言時說,“C語言很多地方都很奇怪,都得用內核的知識去解釋,可是你又不先教我內核,我沒法學C語言。我只好自己看操作系統的書,看內核代碼,可是看不懂。”當然看不懂了,內核代碼都是用C寫的,如果不學內核就沒法學C語言,那不學C語言又怎麼可能看懂內核?看來這是一個雞生蛋還是蛋生雞的問題。

    懶真的是人的本性,就連學習的過程都希望是一條路順利地走下去,不用動腦就能學會的:身後走過的路都是“已知”,每走一步就把眼前新的“未知”變成“已知”,如此一路走來,把所有的“未知”都變成“已知”就算學成了。可惜,知識不是一條路,而是一個圈,你從任何一個地方跳進這個圈開始走,身後都是“未知”,眼前也都是“未知”。有的人就是不能容忍自己的身後是“未知”:看一本書,一個新的概念A是用我不瞭解的概念B、C來解釋的,我連B、C都不懂怎麼學A?沒法學了!

    不是人家書寫得不好,而是沒有任何辦法能把一個圈扯成一條直線的。學習的過程本質上就是一個循環往復的過程,唯一的辦法就是“存疑”:在本子上記着,有B、C這樣兩個概念是我暫時不理解的,然後就不再去想這回事,而是相信自己已經理解了B、C,基於自己的理解和假設去學習A,由A再去理解X、Y,這樣學下去,走完一圈之後再回來,自然就明白當初對B、C的假設正確不正確了,理解了這兩個概念,就從本子上劃掉,這時需要再走一圈,把原來的一些錯誤認識糾正過來。所以,任何書都要至少看兩遍,第二遍看的時候你會對很多概念有新的認識,因爲你看過這個概念後面的章節,在此基礎上產生了新的認識。古人早就明白這個道理,所以提出了“溫故而知新”。


    有哪些好書可以推薦一下嗎?
    能問出這個問題的都是聰明的人。看書學習是入門過程中非常重要的一環,如果用一本爛書入門,浪費時間還是小事,如果被誤導了就麻煩了,如果形成的錯誤認識不能及時糾正,變得根深蒂固了就更麻煩了。所以,看書一定要有“品牌意識”,在決定看書學習一門技術時先問問這一領域最權威的書是哪本,這裏列舉一些Bible級別的書:
    The C Programming Language, 2nd Edition;
    C++ Primer, 4th Edition;
    Structure and Interpretation of Computer Programs, 2nd Edition;
    Introduction to Algorithms, 2nd Edition;
    Compilers: Principles, Techniques, and Tools;
    Advanced Programming in the UNIX Environment, 2nd Edition;
    TCP/IP Illustrated, Volume 1: The Protocols;
    UNIX Network Programming Volume 1, 3rd Edition: The Sockets Networking API;
    Understanding the Linux Kernel, 3rd Edition;
    Linux Device Drivers, 3rd Edition。

    在學習過程中,眼界一定要開闊,不要學到一點東西就沾沾自喜,坐井觀天,以爲這就是技術的全部。要多和別人交流,多瞭解別人在看什麼書、別人對技術的認識是怎樣的。書是看不完的,活到老學到老,對於程序員來說尤其如此。

    9、如何處理打遊戲和學習的關係?
    《如何成爲一名黑客》這篇文章中也說過,黑客們都有一些特別的業餘愛好,並且往往是非理性思維的愛好,大概是需要換換腦子吧。典型的例子是因滑翔機事故去世Stevens,他寫了FAQ8所推薦的Bible當中的三本。愛打遊戲的優秀程序員肯定大有人在,有一些還成了優秀的遊戲開發人員。但是我認爲,要想成爲優秀的程序員,必須有兩點基本素質,一是對編程非常感興趣,二是對所有別的事情都不感興趣,或者都不如對編程感興趣。有人說,人的一天有24小時,8小時休息,8小時上班,另外的8小時在幹什麼就決定了你以後有多大發展。一有時間就看書學習,這就是一個程序員應該做的。今天打遊戲,明天看電影,後天炒股,那麼你就等着三十五歲下崗。如果你不能夠認同編程和思考是比其它事情更有吸引力的,那麼你不必學編程,集中精力去做最喜歡的事情或許會有更大的成就。

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