寫給所有Android工程師:沒有技術(shù)深度的苦惱
前言
最近有一位讀者去面試Android開發(fā),這位讀者師出名門(BAT中的一家公司),是有十年的軟件開發(fā)經(jīng)驗(yàn)的高級(jí)Android工程師,但卻以沒有技術(shù)深度拒絕了他。
昨天早上,我在給他做模擬面試的時(shí)候也發(fā)現(xiàn)了這個(gè)問題,因?yàn)閺暮?jiǎn)歷上看他的出身,呆過兩家知名的互聯(lián)網(wǎng)公司,面試官一定會(huì)不自覺的提升對(duì)他的期望。他雖然有豐富的項(xiàng)目經(jīng)驗(yàn),但真正交流下來又發(fā)現(xiàn)雖然在知名公司工作卻沒有掌握“核心科技”,他的優(yōu)勢(shì)一下就變成了劣勢(shì)。
隨著年齡的增長(zhǎng),你原來的優(yōu)勢(shì)都在慢慢變成你的劣勢(shì)。
寫給資深或即將資深的Android工程師
當(dāng)我們是初級(jí)工程師的時(shí)候,最希望的就是有豐富的項(xiàng)目經(jīng)驗(yàn),好把自己蒼白干癟的簡(jiǎn)歷填的炫麗飽滿。然而隨著時(shí)間的積累,簡(jiǎn)歷上的項(xiàng)目是挺“飽滿”的了,但我們只看“外表”的行為造成了自己另一個(gè)困境:看似很資深,其實(shí)又沒有做過什么有難度的事情,工作了十年可能只是1年的工作經(jīng)驗(yàn)用了9次。
正如這位去面試的讀者,從簡(jiǎn)歷上看確實(shí)是能看到他輝煌的項(xiàng)目經(jīng)歷,在經(jīng)歷之下會(huì)發(fā)現(xiàn)簡(jiǎn)歷中沒有深入的地方。有些雖然寫的很有技術(shù),但是確實(shí)只是在使用API的程度而已;有些解決問題的方式很有技巧,但還不成體系。
可惜沒有多走兩步,沒有去研究和擴(kuò)展。
那么如何改變呢?
對(duì)方也在問我這個(gè)問題,而且很迫切,迫切到希望我今天說明白之后他明天面試就可以變得深入。
我很無奈且直接的說明了這個(gè)多半不可能。如果是可能的話,別人也可以很快掌握核心技術(shù)變得很深入。但長(zhǎng)期的話我認(rèn)為是可能的,比如給自己半年的時(shí)間,對(duì)以前項(xiàng)目中的某一項(xiàng)技術(shù)框架進(jìn)行學(xué)習(xí)擴(kuò)展和實(shí)踐。***能利用一下你目前所在公司的資源,比如做這個(gè)框架的項(xiàng)目組,和他們搞好關(guān)系,向他們學(xué)習(xí)、和他們討論你遇到的每一個(gè)問題。
但是絕對(duì)沒有其他的方式,可以讓你通過看一下或者臨時(shí)準(zhǔn)備一下就提升到有深度的地步。如果你能做到,必然是已經(jīng)在某方面是個(gè)很精深的高手了,自然可以忽略我說的話。
沒有深度的原因
我們沒有技術(shù)深度,最重要的原因有兩個(gè):***是回避問題,第二是沒有興趣。
當(dāng)我們?cè)诠ぷ髦杏龅絾栴}的時(shí)候,***選擇往往是回避它,不管是從設(shè)計(jì)上還是從技術(shù)上,或者找到其他的替代方案,如可使用別人的開源庫,使用別人造出來的輪子。這樣做無可厚非,但如果我們想有更深一步的提升或者更有技術(shù)深度的話,我們一定要把這個(gè)問題搞明白,至少把別人是怎么能解決這個(gè)問題的思路和方式搞明白。
第二關(guān)于興趣,很多人沒有往更深入的地方多走兩步,很重要的一點(diǎn)就是沒有興趣,一點(diǎn)都不好奇。如果我們遇到一些很有意思的解決方案、框架或者一些詭異的問題,但我們完全不想去“招惹”它們,唯恐避之而不及,自然,我們也失去了在這些點(diǎn)上有突破與深入的機(jī)會(huì)。
如何提升自己的技術(shù)深度呢?
1. Java語言進(jìn)階與Android相關(guān)技術(shù)內(nèi)核
Android應(yīng)用是由Java語言進(jìn)行開發(fā)的,SDK也是由Java語言編寫,所以我們要學(xué)習(xí)java語言。另外,雖說kotlin語言得到了Android官方的熱推,但是kotlin也是編譯成了java語言再運(yùn)行的。對(duì)于Android來說,只要SDK沒有用kotlin重寫,那么Java語言是都需要學(xué)習(xí)的。而且Android apk的后臺(tái)服務(wù)器程序大概率是java語言構(gòu)建,所以學(xué)習(xí)java也是一種必然。那么Java中哪些東西是我們Android程序員需要學(xué)習(xí)的呢?由于Android程序員習(xí)慣了 C V 代碼塊,所以與Android中比較相關(guān)的稍微比較難的Java基礎(chǔ)幾乎都是一個(gè)門檻,像 泛型,多線程,反射,JVM,Java IO,注解,序列化等,都是被 CV 的對(duì)象,而程序員是不懂原理的。
2. App開發(fā)框架知識(shí)體系(APP亦對(duì)象)
這塊知識(shí)是現(xiàn)今使用者最多的,我們稱之為Android 2013~2016年的技術(shù),但是,即使是這樣的技術(shù),Android開發(fā)者也往往因?yàn)榫W(wǎng)上Copy代碼習(xí)慣了而導(dǎo)致對(duì)這塊經(jīng)常“使用”的代碼熟悉而又陌生:熟悉的是幾乎天天在和它們打交道,天天在復(fù)制這些代碼;陌生的是雖然天天和這些代碼打交道,但是并沒有深入研究過這些代碼的原理,代碼深處的內(nèi)涵。所以我們需要從新的角度去分析這些知識(shí)點(diǎn),深入研究他們,要學(xué)習(xí)源碼,模仿源碼,然后再hook源碼,這樣才能說自己懂這塊的知識(shí)。這些都是做Android開發(fā),做高級(jí)工程師的基礎(chǔ)。
3.Android App全方位性能調(diào)優(yōu)
一個(gè)app的性能好不好我們需要從兩個(gè)層面努力。***個(gè)層面:從寫代碼的時(shí)候就需要注意,讓自己的代碼是高性能高可用的代碼,這個(gè)過程是書寫高性能代碼;第二個(gè)層面:對(duì)已經(jīng)成型的代碼通過工具檢查代碼的問題,通過檢查到的問題來指導(dǎo)我們進(jìn)行代碼的刪改,這個(gè)過程被稱為調(diào)優(yōu)。
如何寫出高性能的代碼呢?那就需要我們具備深厚的代碼功底,這就是代碼的基礎(chǔ),如:數(shù)據(jù)結(jié)構(gòu)達(dá)到可以根據(jù)應(yīng)用場(chǎng)景寫出符合當(dāng)前場(chǎng)景的特殊結(jié)構(gòu),比如google針對(duì)Android平臺(tái)特征研發(fā)了sparseArray替代HashMap。另外,對(duì)常用的算法有自己獨(dú)到的見解,leetcode上有刷個(gè)上百道題,這樣差不多可以達(dá)到精通最常用的排序查找動(dòng)態(tài)規(guī)劃等算法的能力。再者,高效的算法以及節(jié)省內(nèi)存的數(shù)據(jù)結(jié)構(gòu)如果配合優(yōu)秀的符合應(yīng)用場(chǎng)景的設(shè)計(jì)模式,那么,這些就為高性能的代碼提供了實(shí)現(xiàn)依據(jù)。
另外一個(gè)就是對(duì)寫好的代碼進(jìn)行調(diào)優(yōu),那么調(diào)優(yōu)的方向就是使用Profiler工具進(jìn)行測(cè)試和檢查,看哪里有性能消耗大的操作,然后分析對(duì)于代碼的問題。調(diào)優(yōu)的方向就變成了如何對(duì)內(nèi)存調(diào)優(yōu),對(duì)耗電調(diào)優(yōu),對(duì)網(wǎng)絡(luò)流量調(diào)優(yōu),當(dāng)然,還有對(duì)啟動(dòng)速度,頁面切換效果與速度,開機(jī)白屏體驗(yàn),閃屏方面的原因等進(jìn)行分析和調(diào)優(yōu)。***再加上一個(gè)屏幕適配相機(jī)適配。
音視頻/高清大圖片/人工智能/直播/抖音等等這年與用戶最緊密,與我們生活最相關(guān)的技術(shù)一直都在尋找最終的技術(shù)落地平臺(tái),以前是windows系統(tǒng),而現(xiàn)在則是移動(dòng)系統(tǒng)了,移動(dòng)系統(tǒng)中又是以Android占比絕大部分為前提,所以Android NDK技術(shù)已經(jīng)是我們必備技能了。要學(xué)習(xí)好NDK,其中的關(guān)于C/C++,jni,Linux基礎(chǔ)都是需要學(xué)習(xí)的,除此之外,音視頻的編解碼技術(shù),流媒體協(xié)議,ffmpeg這些都是音視頻開發(fā)必備技能,而且OpenCV/OpenGl/ 這些又是圖像處理必備知識(shí),這些都是原理級(jí)的實(shí)戰(zhàn)項(xiàng)目。
由于篇幅原因,還有很多點(diǎn)需要大家提升的像混合開發(fā)、小程序開發(fā)、架構(gòu)專題等,在這邊就不進(jìn)行贅述了.
自己該在哪個(gè)點(diǎn)上深入呢?
我們工作了很多年之后,技術(shù)一定是需要具有一定的深度和廣度的,廣度自然不必說,你也會(huì)明白它的必要性。深度***是跟自己的興趣或者比較接近的工作模塊相關(guān),如果你在公司相關(guān)的模塊深入,你可以利用更多的資源?;蛘呤悄愀信d趣的模塊的話,即使沒有資源,由于你很有興趣,你也會(huì)有辦法去找到你需要用的東西的。
我們永遠(yuǎn)不缺方法。
帶領(lǐng)和被帶領(lǐng)
技術(shù)的深度是一個(gè)帶領(lǐng)和被帶領(lǐng)的關(guān)系。
關(guān)于這點(diǎn)我本身就有一個(gè)深刻的體會(huì),在我剛開始做Android開發(fā)的時(shí)候,我的工作是去維護(hù)Android自帶的系統(tǒng)應(yīng)用,客戶提的問題或者進(jìn)行二次開發(fā),我都能很好的解決。然后就會(huì)有一些空閑的時(shí)間,反正也是閑著,我就找了個(gè)系統(tǒng)應(yīng)用里面最簡(jiǎn)單的一個(gè)應(yīng)用(記事本)練練手。
我想既然這么簡(jiǎn)單,那我就自己照著寫一個(gè)吧,就從零開始實(shí)現(xiàn)一個(gè)記事本應(yīng)用。當(dāng)我開始寫時(shí),顛覆了我對(duì)安卓應(yīng)用的理解,我發(fā)現(xiàn)以前認(rèn)為懂的地方自己都沒懂,我遇到了很多毫無頭緒的問題,就這么一個(gè)簡(jiǎn)單的應(yīng)用,我要靠不停的對(duì)照原版的代碼實(shí)現(xiàn)才能發(fā)現(xiàn)自己的問題所在,然后才確信真正的做和看中間的差距有多大。
如果你只是在別人的基礎(chǔ)上去做事情解決問題,哪怕你覺得自己想出了很好的點(diǎn)子,好像靈光一閃,很巧妙的解決了客戶的問題,但其實(shí)這只是一種技巧,在怎么建造這個(gè)應(yīng)用、構(gòu)架和設(shè)計(jì)組織這種大的方向上,你并沒有多大的實(shí)質(zhì)進(jìn)步。
這個(gè)時(shí)候你只是一個(gè)跟隨者,你是被別人的源碼帶領(lǐng)著的。
即使你看過和使用過很多應(yīng)用框架,但紙上得來終覺淺,只是添加了些許紙上談兵的資本。你始終是一個(gè)被帶領(lǐng)的人,帶領(lǐng)者給你定好了框架,給你定好了一條大路,然后你在他定好的道路上耍了一下滑頭,卻生出一種假象:覺得自己很厲害,很有技巧。
而你自己寫一個(gè)這樣的框架,或者去設(shè)計(jì)一個(gè)思路,去指定一個(gè)方向和路徑的話,你會(huì)發(fā)現(xiàn)它沒有你想象中的那么簡(jiǎn)單。
你是要做帶領(lǐng)別人的人?還是要做一個(gè)被帶領(lǐng)的人呢?
小結(jié)
沒有技術(shù)深度是大多程序員的一種常態(tài)。
并不能說這是一種壞的或者好的現(xiàn)象,這只是一種合理的狀態(tài),因?yàn)楹芏喙ぷ鳎芏嗳藦氖碌捻?xiàng)目并不需要有多少技術(shù)深度。即使你有深度,你也可能發(fā)現(xiàn)用不上。對(duì)于大多數(shù)人,合乎理性的做法不是去追求技術(shù)深度而是夠用就可以了。
但轉(zhuǎn)到個(gè)人的話就不一樣了,在技術(shù)上你需要夠用,但是在某方面上你需要有一定的深度,以突出你自己的學(xué)習(xí)理解和運(yùn)用的能力,而且這個(gè)能力是要有成功案例來背書。
特別是當(dāng)你成為一個(gè)資深的工程師的時(shí)候,很多公司并不希望你還是那樣平庸,沒有深度。雖然你會(huì)納悶,我就算有深度你們也不一定用得上呀?然而到了這個(gè)級(jí)別的人需求量并不像初中級(jí)開發(fā)那么多,公司更理性和穩(wěn)妥的做法是選擇有深度的人,不是嗎?