六年安卓開發的技術回顧和展望

語言: CN / TW / HK

本文字數:7190 字,閱讀完需:約 5 分鐘

大家好,我是 shixin。

一轉眼,我從事安卓開發工作已經六年有餘,對安卓開發甚至軟體開發的價值,每年都有更進一步的認識。對未來的方向,也從剛入行的迷茫到現在逐漸清晰。我想是時候做一個回顧和展望了。

這篇文章會先回顧我從入行至今的一些關鍵點,然後講一下經過這些年,我對軟體開發的認知變化,最後分享一下後面的規劃。

回顧

人太容易在瑣碎生活中迷失,我們總是需要記住自己從哪裡來,才能清楚要到哪裡去。

入行至今的一些關鍵節點

2014~2015:開始安卓開發之旅

說起為什麼做安卓開發,我很有感慨,差一點就“誤入歧途”😄。

當初在大學時,加入了西電金山俱樂部,俱樂部裡有很多方向:後端、前端、安卓、Windows Phone 等。

由於我當時使用的是三星 i917,WindowsPhone,所以就選了 WinPhone 方向。

當時還是 iOS、安卓、WinPhone、塞班四足鼎立的時代,WinPhone 的磁貼式設計我非常喜歡,加上裝置的流暢性、畫素高,一度讓我覺得它可能會統治移動市場。

結果在學習不到 2 個月以後,我的 WinPhone 意外進水了!我當時非常難過,一方面是對手機壞了的傷痛,另一方面也是對無法繼續做 WinPhone 開發很遺憾。對於當時的我來說,再換一臺 WinPhone 過於昂貴,只好換一臺更加便宜的安卓機,因此也就轉向學習安卓開發。

後面的故事大家都知道了,因為 WindowsPhone 缺乏良好的開發生態,支援應用很少,所以使用者也少,使用者少導致開發者更少,惡性迴圈,如今市場份額已經少的可憐。

現在回想起來,對於這件事還很有感慨,有些事當時覺得是壞事,拉長時間線去看,未必是這樣。

當時還有一件目前看來非常重要的決定:開始寫部落格,記錄自己的所學所得。

在開發專案時,我經常需要去網上搜索解決方案,後來搜尋的多了,覺得總不能一直都是索取,我也可以嘗試去寫一下。於是在 CSDN 註冊了賬號,並於 2014 年 10 月釋出了我的第一篇原創文章

後來工作學習裡新學到什麼知識,我都會盡可能地把它轉換成別人看得懂的方式,寫到播客裡。這個不起眼的開始,讓我逐漸有了解決問題後及時沉澱、分享的習慣,受益匪淺。

2015~2017:明白專案迭代的全流程

在學習安卓開發時,我先看了一本明日科技的《Android 從入門到精通》,然後看了些校內網的視訊,逐漸可以做一些簡單的應用。安卓開發所見即所得的特點,讓我很快就可以得到正反饋。後來又去參加一些地方性的比賽,獲得一些名次,讓我逐漸加強了從事這個行業的信心。

在 2015 年時,偶然參加了一家公司的招聘會,在面試時,面試官問了一些簡單的 Java 、安卓和演算法問題。其中印象最深的就是會不會使用四大元件和 ListView。在當時移動網際網路市場飛速發展時,招聘要求就是這麼低。以至於現在很多老安卓回憶起當初,都很有感慨:“當初會個 ListView 就能找工作了,現在都是八股文” 哈哈。

到公司實習後,我感觸很多,之前都是自己拍腦袋寫一些簡單的功能,沒有開發規範、釋出規範,也沒有工程結構設計、系統設計,更沒有考慮效能是否有問題。真正的去開發一個商業專案,讓我發現自己不足的太多了。

因此在完成工作的同時,我觀察並記錄了專案迭代的各個流程,同時對自己的技術點做查漏補缺,輸出了一些 Java 原始碼分析、Android 進階、設計模式文章,也是從那個時候開始,養成了定期覆盤的習慣,每次我想回顧下過去,都會看看我的成長專欄

2017~2020:提升複雜專案的架構能力和做事意識

第一個專案中我基本掌握了從 0 到 1 開發一個安卓應用的流程,但對安卓專案架構還只停留在表面,沒有足夠實踐。

在 2017 年,我開始做喜馬拉雅直播專案,由於喜馬拉雅在當時已經有比較多年的技術積累,加上業務比較複雜,在架構設計、編譯加速、快速迭代相關都做了比較多的工作,讓我大飽眼福。

同時直播業務本身也是比較複雜的,在一個頁面裡會整合 IM、推拉流等功能,同時還有大量的訊息驅動 UI 重新整理操作,要保證業務快速迭代,同時使用者體驗較好,需要下不少功夫。

為了能夠提升自己的技術,在這期間我學習了公司內外很多框架的原始碼,通過分析這些框架的優缺點、核心機制、架構層級、設計模式,對如何開發一個框架算是有了基本的認識,也輸出了一些文章,比如 《Android 進階之路:深入理解常用框架實現原理》

有了這些知識,再去做複雜業務需求、基礎框架抽取、內部 SDK 和優化,就容易多了。

在開發一些需求或者遇到複雜的問題時,我會先想想,之前看的這些三方框架或者系統原始碼裡有沒有類似的問題,它們是怎麼解決的? 比如開發 PK 功能,這個需求的複雜性在於業務流程很多,分很多狀態,咋一看好像很複雜,但如果瞭解了狀態機模式,就會發現很簡單。借用其他庫的設計思路幫我解決了很多問題,這讓我確信了學習優秀框架原始碼的價值

除了技術上的提升,在這幾年裡,我的專案全域性思考能力也提升很多。

由於我性格外向,和各個職能的同學溝通交流比較順暢,領導讓我去做一個十人小組的敏捷組長,負責跟進需求的提出、開發、測試、上線、運營各個環節,保證專案及時交付並快速迭代。

一開始我還有些不習慣,寫程式碼時總是被不同的人打斷,比如產品需求評審、測試 bug 反饋、運營反饋線上資料有問題等等,經常剛想清楚程式碼怎麼寫,正準備動手,就被叫去開會,回來後重新尋找思路。

後來在和領導溝通、看一些書和分享後,逐漸對寫程式碼和做事,有了不同的認識。程式碼只是中間產物,最終我們還是要拿到對使用者有價值、給公司能帶來收入的產品,要做到這個,眼裡除了程式碼,還需要關注很多。

2020~至今:深入底層技術

在進入位元組做基礎技術後,我的眼界再一次被開啟。

位元組有多款億級使用者的產品,複雜的業務常常會遇到各種意想不到的問題,這些問題需要深入底層,對安卓系統的整個架構都比較熟悉,才能夠解決。

上圖是安卓系統架構圖,之前我始終停留在一二層,在這一時期,終於有了縱深的實踐經驗。

比如幫業務方解決一個記憶體問題,除了要了解記憶體指標監控方式,還要知道分析不同型別記憶體使用的工具及基本原理,最後知道是哪裡出了問題後,還要想如何進行體系化的工具,降低學習成本,提升排查效率。

問題驅動是非常好的學習方式。每次幫助業務解決一個新問題,我的知識庫都會多一個點,這讓我非常興奮。之前不知道學來幹什麼的 Linux 程式設計、Android 虛擬機器,終於在實際問題中明白了使用場景,學起來效率也高了很多。

對軟體開發的認識

前面講了個人的一些經歷,包括我怎麼入的行,做了什麼專案,過程中有什麼比較好的實踐。下面講一下我從這些具體的事裡面,沉澱出哪些東西有價值的結論。

主要聊下對這兩點的認識:

  • 職業發展的不同階段
  • 技術的價值

職業發展的不同階段

第一點是對職業發展的認識。我們在工作時,要對自己做的事有一個清晰的認識,它大概屬於哪一個階段,怎樣做可以更好。

結合我這些年的工作內容、業內大佬所做的事情,我把軟體開發者的職業發展分這幾個階段:

  1. 使用某個技術方向的一個點開發簡單專案
  2. 使用某個技術方向的多個點及某條線,開發一個較為複雜的業務或系統
  3. 掌握某個方向的通用知識,有多個線的實踐,可以從整體上認識和規劃
  4. 不限於該方向,能從產品指標方面出發,提供全方位的技術支援業務角度,端到端關注指標

第一個階段就是使用某個技術方向的一個點完成業務需求。拿安卓開發者來說,比如使用 Android SDK 自定義佈局,完成產品要求的介面功能。這個階段比較簡單,只要能夠仔細學習官方文件或者看一些書即可勝任。拿後端來說,比如剛接手一個小專案,日常工作就是使用 Spring 等庫開發簡單的介面,不涉及到上下游通訊、資料庫優化等。

第二個階段,你做的專案更加複雜了,會涉及到一個技術方向的多個點,這時你需要能把這些點連起來,給出一個更體系化的解決方案。

拿安卓開發者來說,比如在自定義佈局時,發現介面很卡頓,要解決這個問題的話,你就要去了解這個自定義 View 的哪些程式碼流程影響了這個頁面的重新整理速度。這就相當於是從一個點到另一個點。怎麼連起來呢?你需要去研究渲染的基本原理,分析卡頓的工具,找到導致卡頓的原因,進行優化。這個過程會對流暢性有整體的認識,能夠對相關問題有比較全面的分析思路、解決手段,從而可以開發相關的分析工具或優化庫。 如果能達到這個程度,基本就算是一個高階工程師了,不只是做一個模組,還能夠負責一個具體細分方向的工作。

第三個階段,掌握某個技術方向的通用知識,有多個線的實踐,能夠連線為面,同時給工作做中長期的技術規劃。

拿安卓開發來說,剛才提到你通過解決卡頓問題,在流暢性這方面有了比較多的實踐;然後你又發現記憶體有問題,去了解了記憶體分配、回收原理,做出記憶體分析優化工具,這樣就也有了記憶體的一個體系化的實踐。再加一些其他的優化經驗,比如啟動速度、包大小等。把這些線連起來,就得到了一個性能監控平臺,這就是有把多條線連成一個面。

還有比如說你發現專案打包和釋出過程中的一些痛點,並且能夠做一些實踐解決,最後如果能夠把這些優化項連起來做一個統一的系統,給出完整的 DevOps 方案,提升開發、釋出、運維的效率。能夠把這個系統搭建起來,有比較深入的經驗,那就可以成為“技術專家”了。

再往上走就不只是做技術,而要更多思考業務。技術最終都是要為業務服務。職業發展的第四個階段,就是不侷限於某個技術方向,能夠從產品的業務規劃、業務指標出發,給產品提供技術支援。

你首先要明白公司業務的核心指標是什麼,比如說拿一個短視訊應用來說,它核心指標除了常規的日活、使用者量,還更關注視訊的播放率、停留時長、頁面滲透率等。瞭解這些指標以後,你要思考做什麼可以有助於公司提升這些指標。結合業務指標反思當前的專案哪裡存在優化空間。

有了這個思路並且知道可以做什麼以後,你可以做一個較為全面的規劃,然後拉領導去討論可行性。這時你不能再侷限於某一端,不能說我只是個安卓開發,其他部分都找別人做。一般在專案的價值沒有得到驗證之前,領導不會輕易給你資源,因此第一個版本迭代肯定是要靠你自己,從前到後獨立完成,做一個 MVP 版本,然後讓領導認可了這個系統的價值,才有可能會分給你更多的資源做這件事。

總結一下對職業發展的認識:第一階段只做一些具體的點;第二階段做多個點,需要能夠連點成線;第三個階段需要圍繞這些線提煉出通用的知識,然後做到對業務/技術專案有整體的認識;第四階段能夠從業務指標出發,做出有價值的系統/平臺。

技術的價值

說完職業發展的不同階段,接下來聊下技術對業務的價值。

技術是為業務服務的。根據業務的不同階段,技術的價值也有所不同:

  1. 業務從 0 到 1 時,幫助業務快速確定模式
  2. 業務從 1 到 100 時,幫助業務快速擴大規模
  3. 最卓越的,用技術創新帶動業務有新的發展 (Google、AWS、阿里雲)

業務從 0 到 1 時

我一開始做的工作,業務就是處於確定模式期間。業務上反覆試錯,專案常常推倒重來,會讓程式設計師覺得很有挫敗感。

這個階段很多程式設計師都會發揮複製貼上大法,產品經理說要新增一個功能,就複製一份程式碼稍微改一改。

如果說目前就是在這種業務中,該怎麼做呢?如果我回到當時那個情景,我可以做什麼讓公司業務變得更好呢?

我總結了兩點:在高效高質量完成業務的同時,思考如何讓業務試錯成本更低。

如何讓業務試錯成本更低呢?大概可以有這些方式:

  • 提供可複用的框架
  • 提供便捷的資料反饋機制
  • 多瞭解一些競品業務,在產品不確定的時候,給一些建議

第一點:儘可能的抽象相似點,減少重複成本。

如果產品每次都給你類似的需求,你可以考慮如何把這些重複需求抽象成一些可以複用的邏輯,做一個基本的框架,然後在下次開發的時候能夠去直接用框架,而不是每次都從頭開始。我平時工作也常常問自己“我現在做的事有哪些是重複的,哪些是可以下沉的”。

就安卓開發來說,這個階段,可以做好基礎建設,提供外掛化、熱修復、動態化框架,幫助業務快速發版,自研還是第三方看公司財力。

如果你說這些太複雜了我做不來,那就從更小的層面做起,比如某個功能原本需要多個介面多個介面,看能不能改成介面引數可配置,介面根據引數動態生成(也就是 DSL)。

第二點:提供便捷的資料反饋機制

在產品提需求時,你可以問問產品這個需求出於什麼考慮,有沒有資料支撐?比如說產品需求是某個按鈕換個位置,那你要搞清楚,為什麼要換,換完之後會導致頁面開啟率提升嗎?要有這種資料驅動的理念。

如果公司做決策時缺乏相應的資料,你可以主動地去提供這種資料反饋機制。比如說開發一個埋點平臺、資料監控平臺。儘可能地讓業務有資料可看,能夠資料驅動,而不是像無頭蒼蠅一樣盲目嘗試。

如果無法做一個這麼大的系統,那可以先從力所能及的做起,比如說戰略上重視資料;做好資料埋點;思考做的功能,目前有哪些資料是核心的,這些資料有沒有上報,不同版本的資料是升還是降等。

好,這是第一個階段,技術對業務價值就是幫助業務快速確定模式。第二個階段就是業務快速擴大規模時,技術的核心價值是什麼呢?

業務從 1 到 100 時

業務正在快速擴大規模時,需要把當前跑通的業務模式複製到更多的地方,同時能夠服務更多的使用者。這個階段,技術能夠提供的價值主要是兩點。

  1. 快速迭代(這一點其實無論什麼階段)
  2. 提升質量(使用者規模日活上億和日活一萬,需要面對的挑戰差異也是這個數量級)

第一點:快速迭代

雖然快速迭代是業務各個階段都需要做到,但和從 0 到 1 相比,從 1 到 100 的階段會有更多的挑戰,除了個人速度,更要關注團隊的速度。

團隊的速度如何提升?可以參考後端的單體到微服務、前端的單倉到多倉的演變過程及原因。

這個階段主要有這幾點問題:

  1. 多人協作程式碼衝突
  2. 釋出速度慢
  3. 出問題影響大,不好定位

具體到安卓專案,幾百人開發和三兩個人開發的,複雜度也是幾百倍。我們可以做的是:

  1. 下沉基礎元件,定義元件規範,收斂核心流程
  2. 拆分業務模組,設計業務模板,單獨維護迭代
  3. 探索適合業務的新方式:跨端(RN Flutter KotlinMultiplatform)、動態化、多端邏輯一致(C/C++ Rust)

第二點:提升質量

和日活幾萬的專案相比,日活千萬甚至上億的產品,需要應對的質量問題更加顯著。在這個階段,我們不僅要滿足於實現功能,還要能夠寫的好,更要能夠了解底層原理,才能應對這樣大的業務量。

有了大規模的使用者後,你會遇到很多奇怪的問題,不能疲於每天去解決一樣重複的問題,那你就需要從這些問題中找到一些共通的點,然後提煉出來,輸出工具、解決方案甚至平臺。

這就需要你從問題中磨練本領,站在更高的層面思考自己該具體的能力、思路和工具。

在解決問題的時候,除了當下這個問題,更需要做的是把這個問題解構、歸類,抽象出不同問題的相似和差異,得出問題分析流程圖。

同樣是分析記憶體洩漏,有的人可能只知道使用 Leakcanary,但你還可以思考的更深入,比如:

  • 先定義問題。什麼是洩露?
  • 洩露是申請了沒有釋放或者建立了沒有回收
  • 記憶體洩露怎麼分析?
  • 找到建立和銷燬的點
  • 在建立的時候儲存記錄,銷燬的時候刪除這個記錄,最終剩下來的就是洩露的

有了基礎的邏輯,就可以把它套用到各種問題上:

  • Native 記憶體洩漏:在 Native 記憶體分配和釋放 API,做記錄
  • 圖片使用不當:在圖片建立、釋放的 API 裡做記錄
  • 執行緒過多:線上程建立、釋放的 API 裡做記錄

在遇到一個新問題時,發現和之前解決過的有點像,但又不知道哪裡像。怎麼辦?回頭去思考新舊的兩個問題,它們的本質是什麼?有什麼相似的分析思路?

這個思考訓練的目的,就是提升舉一反三的能力。大規模應用可能各種問題,需要你一方面提升技術,另一方面分析問題的思路和能力上也要提升,不能看著一個問題就是一個問題,要做到看到一個問題,想到一類問題。

展望(後面的規劃)

技術上達到一專多能,軟實力上持續提升。 

硬實力

專業

如果你是安卓開發,最好在某個有細分領域很擅長,比如音視訊、跨端、動態化、效能優化。

我目前主要是做優化,後面需要繼續補充的知識:

  • Linux 核心原理
  • Android 虛擬機器原理
  • 專案從開發、編譯、釋出、資料分析各個流程的效率提升方式

多能

前面提到職業發展的第四個階段:

不限於該方向,能從產品指標方面出發,提供全方位的技術支援

我希望可以具備獨立完成一個系統從前到後的能力。

目前已有的經驗:

  • 使用 TypeScript + React + Electron 開發桌面端軟體
  • 使用 SpringMVC 開發簡單的內部系統

後面需要加強的點:

  • 熟練掌握前端的 JS、打包、優化等知識
  • 後端技術達到中級

還有這些點需要長期關注:

  • Flutter 更新頻繁,有一些嘗試效果還不錯,一套程式碼多端執行,節省開發成本
  • 掌握 DevOps 理念及實踐

最終目的:

  • 具備獨立完成一個有價值的系統的能力
  • 具備對研發整個流程的完善、優化能力

軟實力

除了技術規劃,我也有很多軟實力需要繼續提升,今年主要想提升的就是同頻對話的能力。

什麼是同頻對話?

同頻對話就是根據聽眾的角色和他的思考角度去轉換你的表達內容。

比如說我們在和領導彙報的時候,你要去講你做的一個系統,你就要從他角度去表達。他可能關注的是整體流程、系統的難點、瓶頸在哪裡,帶來的收益是什麼。那你就不能只講某個模組的細節,而要從更高的層面去思考和表達。

為什麼要提升呢?

隨著工作年限的增加,市場對我們的要求是越來越高的,除了寫程式碼,對錶達能力的要求也是越來越高的。

一開始剛入行,你就是做一個執行者,只要多動耳朵、眼睛、手,實現別人要求你做的功能。

後來你的能力逐漸提升以後,有機會設計一個模組的時候,你就需要多動腦力去思考,去復設計這個系統的輸入輸出、內部資料流轉等。

再往後走的話,你可能會有一些資源,那就需要能把你的想法完整地表達出來,讓別人幫你去貫徹落地。這其實是一種比較難得的能力。我今年計劃通過多分享、多與不同的人交流等方式,提升自己的這種能力,爭取做到滿意的程度。

結束語

好了,這篇文章就到這裡了,這就是我這六年的技術回顧和展望,感謝你的閱讀❤️。

人生的多重境界:看山是山、看水是水;看山不是山、看水不是水;看山還是山、看水還是水。

我想,我對軟體開發,還沒有達到第三層,相信用不了多久,就會有不同的觀點冒出來。

但,怕什麼真理無窮,進一寸有一寸的歡喜!

如果給你什麼啟發,歡迎留言交流,共同進步✋!