在看這份FAQ以前,你必須先讀完ESR的《如何成爲一名黑客》(本文末尾附有中譯版),該文所講過的道理我再也不重複。該文用很大的篇幅講什麼是黑客文化,雖然態度和信仰的確是成功的最關鍵因素,可是你確定會想,作不作黑客跟我不要緊,我只是想學個一技之長,找個好工做而已,對吧?那麼確定更但願得到一些具體的可操做的指導。
一、各類軟件技術之間是怎樣的關係?html
我把軟件技術分爲三個層次:
問題域:計算機圖形學、音視頻編碼、信息安全、模式識別、信息檢索、天然語言分析、人工智能、科學計算等;
系統集成:C++和Java等面嚮對象語言、Python等解釋型語言、LISP等函數式編程語言、GUI、中間件、編譯器與解釋器、虛擬機、數據庫、網絡服務、並行計算、集羣、Peer2Peer、系統管理等;
系統功能:硬件描述語言、計算機體系結構與編程模型、指令集與彙編語言、C語言、內核、文件系統、設備驅動、網絡協議、POSIX等。
計算機最終是作什麼用的呢?最終是經過問題域的各類技術爲用戶解決問題的,這些技術都包含很高深的算法,然而它們必須在一個平臺上運行,它們須要利用平臺提供的各類基礎設施,好比計算能力、I/O能力和網絡互聯能力。系統功能和系統集成層就是用來實現這個平臺的。系統功能層實現計算、I/O和網絡的基本功能,系統集成層對這些基本功能作一些抽象和包裝,提供更方便靈活的接口。
二、爲何要學習嵌入式技術?git
在亞嵌的學習期間,你將詳細瞭解系統功能層的各部分是如何工做的,也會在面向對象編程、GUI、數據庫、網絡服務等系統集成層的技術方向進行探索。嵌入式系統可說是麻雀雖小五臟俱全,雖然沒有PC和服務器那麼複雜,但計算機系統的各類組成同樣也不缺。所以,以嵌入式系統做爲切入點開始學習軟件技術是很是好的選擇,避開沒必要要的複雜性,把握計算機系統最根本的概念和技術要點。打下紮實的基礎以後,你的職業發展則徹底沒必要侷限於嵌入式領域,即便你往後作PC或服務器開發,在亞嵌所學的知識和技能一樣使你終生受益。正如庖丁解牛,心中有全牛,天然就能遊刃有餘。
另外一方面,你必定見到各大網站都有大量的宣傳,說如今嵌入式行業前景空前的好,嵌入式人才緊缺,有幾百萬職位空缺等等。這些說法也是對的,但咱們須要更深刻地理解這說明了什麼問題。剛纔咱們說,嵌入式系統也是一個完整的計算機系統,和PC或服務器沒有本質的區別,事實上,嵌入式、PC和服務器的界限已經愈來愈模糊了。之前的嵌入式就是單片機,只能作簡單的運算處理,如今的ARM處理器性能比從前的奔騰還強,打遊戲、看電影都沒問題,誰能說它不是PC呢?另外有些專用的嵌入式系統已經在充當服務器的功能了,而集羣技術更是可使許多廉價的處理器組合在一塊兒發揮大型服務器的做用。因爲嵌入式愈來愈多地應用到電器、汽車和各類設施上,無處不在,而且與PC、服務器呈融合的趨勢,因此嵌入式行業前景空前的好。
那麼,爲何說嵌入式人才緊缺呢?其實,學嵌入式系統就是學計算機系統,本質上並無什麼特殊的只有嵌入式系統纔有的技術。說嵌入式人才緊缺,其實質上是說真正懂計算機的人才緊缺。如今不少學校的所謂「軟件學院」培養的軟件人才都是一葉障目不見泰山的:只懂J2EE和.NET,沒學過C和彙編;只會調庫函數sort(),而對各類排序算法一無所知;設計模式、軟件工程講得頭頭是道,殊不知道好的軟件仍是要靠牛人靠智商來作的。培養人像蒸包子同樣一屜一屜地出,靠軟件工程搭一條生產線,而後讓熟練工人站在生產線上擰螺絲,幻想着這樣就能生產出好的軟件,那是把軟件工程和程序員的做用本末倒置了。如今嵌入式開發對程序員的素質要求更高了,以上這類「軟件人才」不能勝任了,所以說嵌入式人才緊缺。亞嵌的就業班雖然只有幾個月,但培養目標是有完整的計算機系統概念的軟件人才,而不是隻會擰螺絲的軟件工人,這正得益於咱們始終堅持作嵌入式培訓而不是Java或.NET培訓。
三、有人說軟件技術變化太快,如今學的東西過兩年就要徹底淘汰,是嗎?程序員
你知道這話是什麼人說的嗎?必然是已經被淘汰的人說的。好比Delphi、BCB、PB這些開發工具和語言,都曾經非常風光了一陣,但如今已經徹底被Java和.NET取代了。那麼Java和.NET會不會被取代呢,也許在至關長的時間內還不會,可是我看好Python。
這些被淘汰的程序員有一些共同的特色:只會用鼠標拖拽控件,離開IDE就不知道如何工做,學點兒花拳繡腿的功夫就想吃一生,對學習新技術不感興趣,作一天和尚撞一天鐘。如今請回頭看看FAQ1,在整個軟件技術領域,這些變化快的技術其實只佔了很小的一塊,卻成了這些人的所有看家本領,這樣的人能不被淘汰嗎?
與這些流行的開發工具和語言相反,不少技術和思想是不多變化的。好比,POSIX和SUS標準規定了一套系統函數接口和基本命令的語義,只有實現了這些才能夠稱做UNIX,所以今天的Linux、Solaris跟20多年前的UNIX在系統功能層上是基本一致的。而指導計算機科學發展的數學理論,甚至是老祖宗們在計算機還沒誕生的年代就替咱們想好的:布爾代數發表於19世紀,直到一個世紀後發明了計算機和數字電路纔有了用武之地;數論在17世紀就出現了,一直都被數學家們當成一套好玩的理論,但只是好玩而已,直到計算機密碼學誕生後才發現它的實際用處。
各類流行的開發工具和高級語言雖然變化很快,可是底層的編程語言卻很是穩定,各類操做系統的內核都是用C語言寫的,之前是這樣,之後也不會改變。另外一方面,各類編程語言的設計思想也是很是穩定的。其實世界上只有兩種編程語言,一種是C,一種是LISP,前者是imperative的,是對計算機模型的抽象,後者是functional的,是對數學函數模型的抽象。面向對象是一種重要的軟件工程思想,卻算不上一種新的語言模型,應該歸在C的一類。屬於同一類的各類語言其實都大同小異,一個精通C++的人學習Java須要多長時間?熟悉語法一個星期,熟悉類庫三個星期,一個月足矣,以往的經驗均可以套到新的編程語言上。然而要想習得深厚的算法功底、邏輯思惟和抽象思惟修養,可以真正說清楚「系統」是什麼,如何分析和設計「系統」,須要多長時間?恐怕要數十年。
四、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的思想。若是你只管悶着頭寫代碼,而不去普遍涉獵,那麼你將錯過不少精彩。
五、我據說編程編到三十五歲就沒人要了必定要轉行找出路是嗎?shell
這個觀點雖然很流行,但根本不值一駁。如今三十五歲轉行的那些人,都具備前面所說的那些特徵,對學習新技術不感興趣,對探索計算機的本質不感興趣,得過且過,下了班就是打遊戲、看電視,總之就是懶。若是是開出租、擺攤,勤快人懶人都有飯吃,而IT這一行對懶人是很是無情的,懶人就不應入IT這一行,不從自身找緣由,卻處處散佈這種言論,怪社會很差,打擊新人的信心,着實可恨。
另一種狀況,編程編到三十五歲,進入公司的管理層,或者本身創業,這都是很勤快的人,若是他們把這種勤快用在技術上確定也能夠作得更好,因此也沒法證實編程編到三十五歲會由於沒有出路而轉行。
編程不是個體力活,須要高強度的思考和智力投入,分析能力、思考能力都須要時間積累起來,因此並非越年輕幹得越好。相反,我認爲三十歲之前寫的代碼都是垃圾,三十歲之後才能寫出像樣的程序來。若是但願一生走技術的道路而不會被迫轉行,就要不斷地把本身的工做性質從「體力活」變成「腦力活」。什麼叫「不斷地」變呢?這裏的「體力活」並非指種地、蓋房子這種勞動,而是指簡單重複地編寫代碼,這時你會感受,派給你的工做都能憑以往的經驗輕鬆應付了,可是千萬不要知足於現狀,就像溫水煮青蛙同樣,這是危險的處境!要擺脫這種處境就須要學習、思考、提升,讓公司派給你更有挑戰性的工做,在工做中應用新學到的知識和技術就是「腦力活」了,可是用得久了又會變成簡單重複的「體力活」,這時就須要再學習、再提升,因此叫作「不斷地」把本身的工做性質從「體力活」變成「腦力活」。若是有一天你發現,本身長期陷於簡單重複的勞動之中,而且業餘時間很是少,沒法學習提升,這說明公司不會用人,你就該考慮跳糟了。
從另一個角度來講,若是但願一生走技術的道路,就要有本身的核心競爭力,這個核心競爭力決不是憑以往的經驗可以作某些工做的能力,而是學習能力、思考能力和解決有挑戰性的新問題的潛力。在IT這一行,憑藉以往的經驗乾重復的活是幹不長久的,緣由很簡單,一個問題不會被解決兩次,當你發現你的經驗可以解決一類問題時,別人早把解決這一類問題的套路編寫成framework,新上手的人即便不具有你的這些經驗也能夠調用framework中的類和函數來解決問題,而後在這個framework的基礎上積累新的經驗解決新的問題。正由於如此,全世界開發人員的經驗纔會積累起來,促使軟件技術發展得如此迅速。這並非說經驗徹底沒有用,最關鍵的,學習和思考也是創建在以往經驗的基礎之上的。另外一方面,現有的framework並不必定是某方面開發經驗的完美整合,也須要不斷髮展,用新的辦法從新解決老問題,以Web開發爲例,從早期的ASP、PHP到後來的.NET、J2EE,到如今的Ruby on Rails、Django等等,這些framework解決的是同一問題,就是如何快速有效地開發Web應用,這方面的經驗被不斷從新整合,推陳出新。總結一下,什麼纔是核心競爭力呢?應該是在經驗的基礎上學習新技術、解決新問題的能力。
六、作驅動開發仍是作應用開發更有前途?數據庫
意思就是說,「你告訴我哪一個更有前途,我就好好學哪一個,另一個就不用學了」。問這種問題的學員每每會同時問另一些問題:我之後就想作驅動開發,你教我這些應用開發的技術有什麼用?C++用得多嗎?學了有什麼用?我之後不想作GUI,你教我Qt有什麼用?
學習最忌諱的就是「有用的就學,沒有用的就不學」這種功利的態度。兩個問題:第一,在你還沒學進去、還不瞭解這種技術時,要如何判斷這種技術學了有沒有用?只能是根據道聽途說,看各類論壇上都怎麼說的,豈不知論壇上參與這種討論的100%都是菜鳥,有的水平還不如你。第二,就算你學的技術沒有用上,有什麼損失嗎?從亞嵌畢業的學員從事各類各樣的開發工做,有作驅動的,有作系統編程的,有作GUI的,有作Web開發的,只要肯定了作一類工做,就不可能把在亞嵌四個月學的知識都用上,但至少也用得上3/4的知識,假設剩下的1/4你一生也沒機會用上了,那也就損失你一個月的學習時間而已,相比於你的收穫,這算是很大的損失嗎?請注意,上面的假設是不成立的,沒用上的那1/4也只是暫時沒用上而已,程序員要換工做或者換項目是很常見的,任何人都不可能只涉及一類開發工做,只要有紮實的基礎、完備的知識體系,任何工做都能輕鬆上手。
紮實的基礎,完備的知識體系,咱們在安排就業班課程體系的時候,正是以這兩點爲依據的。有的課程內容不多有學員在之後工做中會用到,可是缺了這一環就不成爲一個完備的知識體系,例如MMU和Cache,那這種課該不應上呢?毫無疑問該上。有的課程培養一種基本的編程思想,例如經過C++來說面向對象編程,經過Qt來說面向對象、事件驅動和狀態機編程,這些編程思想是程序員必備的基本素質,而C++和Qt可能有些學員之後工做用不到,那這種課該不應上呢?毫無疑問該上。至於還有些人爭論說C++不如Java用得多,Qt不如GTK用得多,請翻回去看FAQ4,這種爭論是無心義的,有工夫爭論誰優誰劣,不如把兩種都學了,會更有收穫。
回到作驅動開發仍是作應用開發更有前途的問題。我只能說,作好了都有前途,作很差都沒有前途,只會作同樣而徹底不懂另外一樣是最沒前途的。不要覺得內核開發者就不寫應用程序,Linus寫了一個源代碼管理系統git來維護內核,由於以爲現有的源代碼管理系統都很差用。牛人都是這樣,須要什麼就寫什麼,才無論是kernel
space仍是user
space。一樣,作應用開發若是不懂內核,也沒有辦法很好地利用內核提供的服務寫出性能最優的程序。作內核難,由於調試難,要跟蹤大量的併發線程,由於入門難,要寫一個hello
world都須要學不少知識。作應用也難,回頭去看FAQ1,計算機科學從理論到實踐大部分都在上面兩層作文章。因此不存在哪一個更難哪一個更有前途的問題,任何關於哪一個更難的討論都是too
naive的。
七、我一開始看什麼書都看不懂,怎麼才能理出一個學習順序?編程
之前有個學員在學C語言時說,「C語言不少地方都很奇怪,都得用內核的知識去解釋,但是你又不先教我內核,我無法學C語言。我只好本身看操做系統的書,看內核代碼,但是看不懂。」固然看不懂了,內核代碼都是用C寫的,若是不學內核就無法學C語言,那不學C語言又怎麼可能看懂內核?看來這是一個雞生蛋仍是蛋生雞的問題。
懶真的是人的本性,就連學習的過程都但願是一條路順利地走下去,不用動腦就能學會的:身後走過的路都是「已知」,每走一步就把眼前新的「未知」變成「已知」,如此一路走來,把全部的「未知」都變成「已知」就算學成了。惋惜,知識不是一條路,而是一個圈,你從任何一個地方跳進這個圈開始走,身後都是「未知」,眼前也都是「未知」。有的人就是不能容忍本身的身後是「未知」:看一本書,一個新的概念A是用我不瞭解的概念B、C來解釋的,我連B、C都不懂怎麼學A?無法學了!
不是人家書寫得很差,而是沒有任何辦法能把一個圈扯成一條直線的。學習的過程本質上就是一個循環往復的過程,惟一的辦法就是「存疑」:在本子上記着,有B、C這樣兩個概念是我暫時不理解的,而後就再也不去想這回事,而是相信本身已經理解了B、C,基於本身的理解和假設去學習A,由A再去理解X、Y,這樣學下去,走完一圈以後再回來,天然就明白當初對B、C的假設正確不正確了,理解了這兩個概念,就從本子上劃掉,這時須要再走一圈,把原來的一些錯誤認識糾正過來。因此,任何書都要至少看兩遍,第二遍看的時候你會對不少概念有新的認識,由於你看過這個概念後面的章節,在此基礎上產生了新的認識。古人早就明白這個道理,因此提出了「溫故而知新」。
亞嵌的課程體系通過多年教學實踐的錘鍊,已經很好地理順了知識之間的關係,使你從最佳的位置跳進這個圈開始學習,所謂「最佳位置」是指,在你初學的時候須要容忍的「未知」儘量少,須要作的假設儘量少,但要想消除全部的「未知」是不可能的,例如沒有學內核就要學C語言。根據你以往的經驗和一些運氣因素,你對內核的一些假設可能正確也可能錯誤,但這並不影響你學C語言,對內核的一些錯誤假設可能會致使在學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。
在學習過程當中,眼界必定要開闊,不要學到一點東西就沾沾自喜,坐井觀天,覺得這就是技術的所有。要多和別人交流,多瞭解別人在看什麼書、別人對技術的認識是怎樣的。書是看不完的,活到老學到老,對於程序員來講尤爲如此。
九、如何處理打遊戲和學習的關係?安全
ESR的文章中也說過,黑客們都有一些特別的業餘愛好,而且每每是非理性思惟的愛好,大概是須要換換腦子吧。典型的例子是因滑翔機事故去世的Stevens,他寫了FAQ8所推薦的Bible當中的三本。愛打遊戲的優秀程序員確定大有人在,有一些還成了優秀的遊戲開發人員。可是我認爲,要想成爲優秀的程序員,必須有兩點基本素質,一是對編程很是感興趣,二是對全部別的事情都不感興趣,或者都不如對編程感興趣。有人說,人的一天有24小時,8小時休息,8小時上班,另外的8小時在幹什麼就決定了你之後有多大發展。一有時間就看書學習,這就是一個程序員應該作的。今天打遊戲,明天看電影,後天炒股,那麼你就等着三十五歲下崗。若是你不可以認同編程和思考是比其它事情更有吸引力的,那麼你沒必要學編程,集中精力去作最喜歡的事情或許會有更大的成就。 如何成爲一個優秀的程序員服務器
http://www.cnblogs.com/NeuqUstcIim/archive/2008/09/26/1299401.html