[關于學習Android的三個終極問題](https://blog.csdn.net/thisway_diy/article/details/97012727)
**緣起**
讀研的時候,有一次和同學一起上自習。我在學習,他也在學習。我想,大家每天都一起上課,記筆記,上自習,完成作業,智商也差不多,為何考試的時候有時候差距會很大呢?這個問題我直到今天也沒有答案,這幾天和朋友閑聊說到這個事情。他們有得說是智商有差距,有得說是學習的時候心不在焉——看著在學習,其實已神游大千世界。…,不過,我自己從來沒有下過類似的結論。我武斷的猜測,這個問題應該是沒有讓人心服口服的答案。
從事軟件開發行業后,發現要學的東西越來越多。尤其是近幾年,發現未知的知識實在是太多。恐怕IT人活到老學到老的壓力是絕無逃避的可能性了。那么,關于學習,我們需要注意什么呢?2015年google開發者社區一個集會上,我曾經分享過一些思考。4年過去了,又積累了不少經驗教訓(其實就是老了不少),現在想總結這些年的觀察,做一個總結。我感覺可能需要至少兩篇文章才能說完。一個是本篇的關于Android學習的三個終極問題,另外一個是對一專多能的思考。
去年我在周愛明老師的《大道至簡》一書里看到對“反思”一詞的定義,深有感觸。書里說,反思,既不是設問,也不是反問,而是對一個問題的持續關注。這么來看,十余年來我對考試成績好壞原因的思考就是一種反思。
在繼續本文之前,我想說,我這個人講不出什么大道理,能講的東西都是自己想過、嘗試過、甚至在周圍朋友,同事身上一起試驗過的。即使不能從中學到什么有價值的東西,但看到像我這樣的一個圓臉中老禿胖其實一年也沒多少天是無憂無慮得,你也可以開心一下了。
**關于學習的三個終極問題**
關于學習,我認為有三個終極問題:

這三個終極問題是:
1. 學什么?2015年時還沒有flutter,RN我記得剛起。不知道在那個時候意氣風發的Android紅人們現在是不是會有點感觸了。過了4年了,現在該學什么?Flutter?AI、區塊鏈?是為了興趣愛好而學,還是為了保家衛國光宗耀祖揚眉吐氣世界更美好而學?
2. 怎么學?這是在你剛千思萬考解決第一個問題的時候接下來的另一個大難題。是ALL IN新知識?還是新舊知識兩手都要抓?不論哪種選擇,你都很難和長江后浪比精力,比速度。對待新知識、新技術,長江后浪是光腳不怕穿鞋的,靠試錯來成長。
3. 學到什么程度為止?最后,你開始學了,也知道怎么學了。然后呢?鉆研技術是無止境的,你要學到什么程度為止?夠用就行嗎?夠用是在哪個范圍夠用?我自學完寫個demo叫夠用嗎?還是說學完后要給公司創造多少多少價值才行?我公眾號的首篇文章“深入理解的目標是什么?”和這個問題有一點關聯。
很多時候,很多人并不會意識到學個知識還有什么三個終極問題。比如,周圍人都學某某技術,所以我要學。或者,學某某技術有前途和錢途,那我也學。坦白來講,我很羨慕這些人。在和平、穩定的年代,隨大流是穩妥的選擇。我很后悔讀研的最后不該聽了中科院某老師的授課。2007年,他“深度思考”了中國經濟,得出了一個結論,說咱們的經濟列車高速開了這么久了,肯定會下降的,然后房價會跌。所以,工作后的前3年我看著房價飛漲的時候依然堅信這個結論。幸好父母親果斷,舉債買房。當時我加班夜里回來后聽說自己背負了100多萬的房貸還很不開心。沒想再過幾年我發現自己居然少背了幾百萬的房貸。
所以,要是你沒有意識到有這三個問題,你是幸福和幸運的——如果環境沒有發生變化,你也無須改變。
上面三個問題是我自己在學習問題上的反思——反思的潛意思是我也沒有答案。我覺得也很少有人能給出明確的、普適的答案。我有一種強烈的預感,在關于學習的這三個終極問題上,每個人一定都是在自己的無人區里探索。
承認無人區的存在是有百利而無一害的。我以前每次換工作都要找機工的楊總編等朋友請教,但發現他們的意見總是不理想。終于有一天我明白了,原來我在自己的無人區中,里邊只有我一個人。我的家人,朋友都不能真正理解我,他們解決不了我的困惑。 不過,當在無人區里掙扎的我知道還有那么多親人、朋友是支持我的,勇氣就會更足。堅信總會有一天,我會短暫得從無人區出來,然后再走入下一個更高級的,更有挑戰的無人區。
對了,去年我才發現溫伯格原來早在《技術領導之路》一書里就曾提到過類似的情況,那一章的中文名叫“領導的成長”。
接下來,我要把這幾年從事Android開發相關工作中看到的東西結合自己的認識講一講。我覺得它們一定能幫助到在Android技術領域里謀生的一些兄弟姐妹們。
**關于Android學習方面的一些探討**
根據我的經歷和認識,Android技術領域劃分按從下到上可分為三個大的層次:
1. Android底層開發。這個領域的開發工作主要集中在設備廠商(比如華米OV)、芯片廠商(華為高通)等。最近這兩年,伴隨IoT技術的發展,一些有能力的互聯網公司也需要這方面的人才。
2. Android系統層開發。這個領域的開發也是集中在設備廠商。但我最近發現頭條這樣的互聯網公司也大量招聘懂Android Framework的工程師。另外,新興的車聯網、車企也對這方面人才有大量需求。
3. Android應用層開發。這個就不用說了,競爭非常激烈,技術迭代的速度飛快。
接下來,我會從知識范圍和主要工作內容、學習路線以及需要注意培養的專業素養這三個方面來考察下上述三個Android技術領域。
**Android底層開發**
Android底層開發涉及到的知識范圍和主要工作內容如下:

從事底層開發的碼農們叫BSP或驅動開發工程師。涉及的專業知識集中在Linux Kernel或驅動方面。
Linux Kernel是無數人為之傾倒的知識金礦。當年我也認認真真讀過毛德操老師的《Linux內核情景分析》這樣的源碼分析書籍。這本書對我的影響非常深,以至于我策劃的深入理解Android系列的幾本書可看做是毛老師的手法在Android系統上的復制。
底層開發的工作內容主要是移植和Bug Fix。在某些公司的日常工作中,只要找到解決bug的patch,打上去就好了。為什么會這樣?因為Kernel是一個比較穩定的軟件。在這里,穩定壓倒一切。當然,其中也有非常具有挑戰性的工作,比如優化相關的工作等。
如果你想從事Android底層開發,下面是這個領域的學習路線:

在這個領域里工作,請牢記“吃虧是福”這句話。吃虧意味著積攢經驗。這個領域里的經驗是至關重要的。所以,我在下面的基本素養里還會提到它:

**Android系統層開發**
接著來看Android系統層開發。它涉及的知識范圍和主要工作內容如下:

Android系統層開發的主要工作有因Android系統升級帶來的移植工作、或者是諸如華米OV各家系統的產品特性(因為原生Android系統沒有,所以需要自己開發)。
最后,隨著除手機外的智能設備興起(如智能POS、智能汽車),這些特定設備上也有許多在系統層需要開發的工作。
相比底層開發,系統層開發有更多的個性發揮空間。MIUI、EMUI、color OS等等就是系統層個性發揮的結果。簡單點說,如果可以把從事底層開發的公司看做是硬件公司,那么從事系統層開發的就可以看做是軟件公司了。
我這個說法肯定是不對的,但這里想說的是這兩個領域的思維方式不太一樣,因為要解決的問題也不一樣。
Android系統層的學習路線如下:

從編程語言上來說,Android系統層有很大一部分是用Java開發的。另外還有一大部分是用Native(C/C++)語言開發的,
所以,要想在這個領域做到游刃有余,對Java和C++語言要了解。題外話,還沒了解C++的同學可以直接上C++11。它和C++98/03不同(C++之父BjarneStroustrup甚至說過“C++11看起來像一門新的語言”)。
關于C++11的知識,我在CSDN博客上"C++11學習"一文(也是《深入理解Android JVM ART》一書的第五章,因為ART JVM幾乎都是C++11寫的)做過一個較為全面的介紹(地址在文后列出)。
Android系統層是相當吸引廣大開發者的一個領域。比如很多知名Android技術公眾號都會時不時講一講Handler的實現、UI繪制的流程、Binder的工作原理、消息傳遞機制等這樣的知識。 這些內容早在《深入理解Android》系列的卷1、卷2和卷3都覆蓋了。只不過時過境遷,年輕的人現在更適應新的傳播方式。
除了這些通用知識,Android系統層還有相當一部分屬于專業領域知識。比如,藍牙、Wi-Fi、NFC、Telephoney(其中的雙卡雙待功能算是中國特色的功能)。如果你從事類似這樣的專業領域的工作,請注意把精力放在專業知識本身,而不是Android里的代碼。比如,Wi-Fi、NFC、GPS、藍牙技術出現得遠比Android早。它們各自有非常深厚的專業、理論知識。
在Android中,你看到的相關代碼無非是它們在特定系統上的實現罷了。你務必要先了解這些專業、理論知識,才能看懂Android上的代碼實現。更未雨綢繆的說法是,如果將來沒有Android系統的話,你一樣可以靠著對專業理論知識的了解另起爐灶。
這也是我說“基于Android、高于Android”的意思。一個最近發生的例子是,有個幫我審稿JVM ART一書的審稿專家現在研究Flutter里的虛擬機。我相信他會比別人走得更快,更輕松一點。
Andriod系統層開發的基本素養:

系統層這幾年發展也很快(想想Android的發版速度),靠個人力量來追蹤這么一個復雜系統已經很困難了,需要大家一起來知識共享。
雖然很多公眾號會寫一些文章來介紹Android某個新系統的特點,但其實在設備廠商里是有不同的團隊來跟蹤新系統里不同模塊的變化得。比如,除了Google I/O外,谷歌給設備廠商還組織了一個叫Android Bootcamp這樣的類似培訓一樣的集會,里邊會比較詳細的、按功能、模塊來介紹新系統的特點。不過,參加Bootcamp所獲得的資料往往要保密。
**Android應用層開發**
接著來看最后一層——Android應用層開發的知識范圍和主要工作內容:

應用層開發的特點就是知識點多、更新速度極快。相信大家都有感覺。針對這個層面的開發者,我想,就不要拘泥于什么門派了,需要什么就學什么(注意,不是有什么就學什么)。相比其它兩個領域, 應用層開發是為業務需求服務的。所以,為了更好得服務業務需求,該學什么就學什么。
比如,我最近的方向轉到應用層開發了,但我所在行業的應用主要用H5+webview來承載業務邏輯,那么我就重點花時間學習了這塊的內容。

我個人認為從事應用層開發同學的比例最大,也是最能體會“跟不上知識更新步伐”感受的人。這一領域中有沒有什么基礎關鍵技術?我多年觀察下來覺得在應用層開發領域,多線程編程、網絡編程、設計模式等幾個是基礎關鍵知識,無論如何要想辦法抓在手里。
還有,軟件開發的方法論、甚至產品開發、項目管理都是這個領域里需要了解的。
另外,在某股技術“風”起的時候,要判斷下它是為了解決什么問題而產生的,你的業務需不需要這種技術?我對曾經一起干活的小伙伴們說過,寧愿你閑著沒事干,也不要亂學,瞎學。在這個領域,功利、目的性強一點好。不要為了學習而學習,也不要為了KPI去github上重復造輪子。這也是該領域的基本素養。

**頓悟及其它**
前幾年我一直在系統層和靠近底層的領域里搞事情,有時候也會做一些應用層的開發。近來我在轉入應用層開發的時候,花了一些時間研究應用層開發和系統層開發的一些區別:
1. 不得不說,底層和系統層是存在和需要個人英雄主義的。最常見的情況就是誰改bug最厲害誰就是英雄。所以,“深入理解的目標是什么”一文里提到的手撕鬼子一幕在這兩個領域里是有可能存在的。
2. 應用層技術的難度在于工程化。一個好的想法在demo上實驗成功了,要推廣并大規模使用并創造真正的價值一定是要工程化該想法的。而工程化的過程中,就需要業務、產品、前后端、測試等多個團隊配合。“深入理解的目標是什么”提到的虛竹如果沒有王語嫣、或者沒有很好的團隊支撐的話,是很難在這個地方發展起來的。
3. 另外,應用層開發如果找到現成的已經有工程化實踐經歷的開源庫,我建議能使用的話還是使用它們吧。不過,要用好人家的開源庫也不是一件容易的事情。因為人家所面臨的問題肯定和你的問題不一樣。
不知道你有沒有這樣的感覺。學習過程中,如果碰到一個問題,如果反反復復、長時間去思考它的話,總有一天會明白。這其中,有極少數的幾次會讓你有一種頓悟的感覺。到目前為止,我職業生涯里談得上頓悟的時候應該不超過3次。
·
最早一次是反復回顧用MFC開發一個自定義樹形控件總是有內存崩潰的bug從而頓悟到內存操作到底是在干什么。
·
另外一次是做DLNA的時候根據文檔協議編寫對應軟件的頓悟——很多時候編程只不過是把想法翻譯成計算機語言而已。而交流想法的形式可以是口述、規范文檔。所以,想法是本。
·
最后一次談得上頓悟的事情是在看完《信息簡史》后。此后我在開發軟件的時候仿佛能看到信息在流動。用戶從界面上輸入信息,流經網絡,后臺接收并處理信息,直到存儲信息。甚至當我看到領導在耳提面命下屬某個問題的具體處理細節時,我也深刻感受到他在“編程”——我們都是在處理信息罷了,領導對我們編程,我們對計算機編程。
**最后**
1. 深入理解Android系列有好幾本書已經不再出版了,我在CSDN上提供全文電子版下載https://blog.csdn.net/Innost/article/details/43342087
2. C++11的學習可參考CSDN博文https://blog.csdn.net/Innost/article/details/52583732
3. “深入理解的目標是什么”見https://mp.weixin.qq.com/s/hZrTlo3sSENtOQVbJ\_h2Dg
4. 看到太多同學在追求技術上所付出的努力以及所碰到的困惑。我自己總結過很多有價值的東西,但我覺得對具體知識的掌握并不是關鍵,更重要的是思考問題的方式和方法——這也是我在本篇開頭會提到我對考試成績好壞的思考。另外,我還想學習一些新的東西。這些,我都想通過某種方式分享給感興趣的朋友們。
在《深入理解Android JVM ART》這本厚達1000頁書籍寫完后,我給自己說,絕不要再寫這樣需要“操刀自宮"才能練成的書了。我應該把復雜的知識用簡單明白的方式表達出來,然后大家再結合自己的認知和經歷去體會、去利用這些知識就行。
最后的最后,我期望的結果不是朋友們從我的書、文章、博客后學會了什么知識,干成了什么,而應該是說,神農,我可是踩在你的肩膀上得喔。