阿里P8大牛:你還在拿5000塊的死工資嗎?有時候逆襲就在一瞬之間 前言

前言

不知道大家面試的時候,有沒有遇到這種情況,面試工資談的是10K,最後幹着40K的活!說着冠冕堂皇,提升大家能力的話,做着死命壓榨員工,996996.成了程序員心裏的魔咒!

初級安卓開發工程師(10K-15K)

掌握紮實的java基礎,瞭解各種設計模式,熟練掌握Android UI控件、Android Java層API的相關使用。往中級層次發展時,繼續深入學習java編程技術,掌握更多Android開發需要的庫,還要精通ml、json解析,會做socket c/s端的程序。

中級安卓開發工程師(15K-30K)

除了上面提到的必備技能外,中級開發人員需要延伸到精通NDK JNI方式的開發,熟悉Android framework,會移植類似Fmpeg、Mplayer這樣的開源項目,並在Android上運行。

高級安卓開發工程師(50K-100K)

作爲高級app開發工程師,你只需瞭解,並不需要親自操作初級和中級工程師的工作流程,但是,你需要有一個整體知識構架,安卓開發各方面所涉及的知識你都有要了解,並有自己獨到的見解。需要熟練掌握Linux驅動開發,並對Linux內核結構很精通,掌握Android移植,包括硬件移植。

現如今做開發的門檻越來越高,市場一直在升級,很多人說Android不好做了,其實是市場對Android程序員的要求越來越高了!

但是,術業有專攻,總有一些技術牛逼的程序員可以吊打、碾壓面試官!

本人經常隔段時間就偷偷投點簡歷,請假出去面試幾次,目的不是想跳槽,主要是爲了看看市場上的技術流行趨勢,順便檢驗一下自己的水平,當然,如果面到了心儀的公司或者大廠,那不是更好嘛,哈哈哈!

前段時間收到了字節跳動的面試,雖然有點小震驚,但還是用平常心對待了。結果一不小心,面試的時候就吊打了面試官。


阿里面試題

說下你所知道的設計模式與使用場景

a.建造者模式:
將一個複雜對象的構建與它的表示分離,使得同樣的構建過程可以創建不同的表示。
使用場景比如最常見的AlertDialog,拿我們開發過程中舉例,比如Camera開發過程中,可能需要設置一個初始化的相機配置,設置攝像頭方向,閃光燈開閉,成像質量等等,這種場景下就可以使用建造者模式

裝飾者模式:動態的給一個對象添加一些額外的職責,就增加功能來說,裝飾模式比生成子類更爲靈活。裝飾者模式可以在不改變原有類結構的情況下曾強類的功能,比如Java中的BufferedInputStream 包裝FileInputStream,舉個開發中的例子,比如在我們現有網絡框架上需要增加新的功能,那麼再包裝一層即可,裝飾者模式解決了繼承存在的一些問題,比如多層繼承代碼的臃腫,使代碼邏輯更清晰
觀察者模式:
代理模式:
門面模式:
單例模式:
生產者消費者模式:

java語言的特點與OOP思想

這個通過對比來描述,比如面向對象和麪向過程的對比,針對這兩種思想的對比,還可以舉個開發中的例子,比如播放器的實現,面向過程的實現方式就是將播放視頻的這個功能分解成多個過程,比如,加載視頻地址,獲取視頻信息,初始化解碼器,選擇合適的解碼器進行解碼,讀取解碼後的幀進行視頻格式轉換和音頻重採樣,然後讀取幀進行播放,這是一個完整的過程,這個過程中不涉及類的概念,而面向對象最大的特點就是類,封裝繼承和多態是核心,同樣的以播放器爲例,一面向對象的方式來實現,將會針對每一個功能封裝出一個對象,吧如說Muxer,獲取視頻信息,Decoder,解碼,格式轉換器,視頻播放器,音頻播放器等,每一個功能對應一個對象,由這個對象來完成對應的功能,並且遵循單一職責原則,一個對象只做它相關的事情

說下java中的線程創建方式,線程池的工作原理。

java中有三種創建線程的方式,或者說四種
1.繼承Thread類實現多線程
2.實現Runnable接口
3.實現Callable接口
4.通過線程池

線程池的工作原理:線程池可以減少創建和銷燬線程的次數,從而減少系統資源的消耗,當一個任務提交到線程池時
a. 首先判斷核心線程池中的線程是否已經滿了,如果沒滿,則創建一個核心線程執行任務,否則進入下一步
b. 判斷工作隊列是否已滿,沒有滿則加入工作隊列,否則執行下一步
c. 判斷線程數是否達到了最大值,如果不是,則創建非核心線程執行任務,否則執行飽和策略,默認拋出異常

說下 handler 原理

Handler,Message,looper 和 MessageQueue 構成了安卓的消息機制,handler創建後可以通過 sendMessage 將消息加入消息隊列,然後 looper不斷的將消息從 MessageQueue 中取出來,回調到 Hander 的 handleMessage方法,從而實現線程的通信。

從兩種情況來說,第一在UI線程創建Handler,此時我們不需要手動開啓looper,因爲在應用啓動時,在ActivityThread的main方法中就創建了一個當前主線程的looper,並開啓了消息隊列,消息隊列是一個無限循環,爲什麼無限循環不會ANR?因爲可以說,應用的整個生命週期就是運行在這個消息循環中的,安卓是由事件驅動的,Looper.loop不斷的接收處理事件,每一個點擊觸摸或者Activity每一個生命週期都是在Looper.loop的控制之下的,looper.loop一旦結束,應用程序的生命週期也就結束了。我們可以想想什麼情況下會發生ANR,第一,事件沒有得到處理,第二,事件正在處理,但是沒有及時完成,而對事件進行處理的就是looper,所以只能說事件的處理如果阻塞會導致ANR,而不能說looper的無限循環會ANR

另一種情況就是在子線程創建Handler,此時由於這個線程中沒有默認開啓的消息隊列,所以我們需要手動調用looper.prepare(),並通過looper.loop開啓消息

主線程Looper從消息隊列讀取消息,當讀完所有消息時,主線程阻塞。子線程往消息隊列發送消息,並且往管道文件寫數據,主線程即被喚醒,從管道文件讀取數據,主線程被喚醒只是爲了讀取消息,當消息讀取完畢,再次睡眠。因此loop的循環並不會對CPU性能有過多的消耗。

內存泄漏的場景和解決辦法

1.非靜態內部類的靜態實例
非靜態內部類會持有外部類的引用,如果非靜態內部類的實例是靜態的,就會長期的維持着外部類的引用,組織被系統回收,解決辦法是使用靜態內部類

2.多線程相關的匿名內部類和非靜態內部類
匿名內部類同樣會持有外部類的引用,如果在線程中執行耗時操作就有可能發生內存泄漏,導致外部類無法被回收,直到耗時任務結束,解決辦法是在頁面退出時結束線程中的任務

3.Handler內存泄漏
Handler導致的內存泄漏也可以被歸納爲非靜態內部類導致的,Handler內部message是被存儲在MessageQueue中的,有些message不能馬上被處理,存在的時間會很長,導致handler無法被回收,如果handler是非靜態的,就會導致它的外部類無法被回收,解決辦法是1.使用靜態handler,外部類引用使用弱引用處理2.在退出頁面時移除消息隊列中的消息

4.Context導致內存泄漏
根據場景確定使用Activity的Context還是Application的Context,因爲二者生命週期不同,對於不必須使用Activity的Context的場景(Dialog),一律採用Application的Context,單例模式是最常見的發生此泄漏的場景,比如傳入一個Activity的Context被靜態類引用,導致無法回收

5.靜態View導致泄漏
使用靜態View可以避免每次啓動Activity都去讀取並渲染View,但是靜態View會持有Activity的引用,導致無法回收,解決辦法是在Activity銷燬的時候將靜態View設置爲null(View一旦被加載到界面中將會持有一個Context對象的引用,在這個例子中,這個context對象是我們的Activity,聲明一個靜態變量引用這個View,也就引用了activity)

6.WebView導致的內存泄漏
WebView只要使用一次,內存就不會被釋放,所以WebView都存在內存泄漏的問題,通常的解決辦法是爲WebView單開一個進程,使用AIDL進行通信,根據業務需求在合適的時機釋放掉

7.資源對象未關閉導致
如Cursor,File等,內部往往都使用了緩衝,會造成內存泄漏,一定要確保關閉它並將引用置爲null

8.集合中的對象未清理
集合用於保存對象,如果集合越來越大,不進行合理的清理,尤其是入股集合是靜態的

9.Bitmap導致內存泄漏
bitmap是比較佔內存的,所以一定要在不使用的時候及時進行清理,避免靜態變量持有大的bitmap對象

10.監聽器未關閉
很多需要register和unregister的系統服務要在合適的時候進行unregister,手動添加的listener也需要及時移除

如何避免OOM?

1.使用更加輕量的數據結構:如使用ArrayMap/SparseArray替代HashMap,HashMap更耗內存,因爲它需要額外的實例對象來記錄Mapping操作,SparseArray更加高效,因爲它避免了Key Value的自動裝箱,和裝箱後的解箱操作

2.便面枚舉的使用,可以用靜態常量或者註解@IntDef替代

3.Bitmap優化:
a.尺寸壓縮:通過InSampleSize設置合適的縮放
b.顏色質量:設置合適的format,ARGB_6666/RBG_545/ARGB_4444/ALPHA_6,存在很大差異
c.inBitmap:使用inBitmap屬性可以告知Bitmap解碼器去嘗試使用已經存在的內存區域,新解碼的Bitmap會嘗試去使用之前那張Bitmap在Heap中所佔據的pixel data內存區域,而不是去問內存重新申請一塊區域來存放Bitmap。利用這種特性,即使是上千張的圖片,也只會僅僅只需要佔用屏幕所能夠顯示的圖片數量的內存大小,但複用存在一些限制,具體體現在:在Android 4.4之前只能重用相同大小的Bitmap的內存,而Android 4.4及以後版本則只要後來的Bitmap比之前的小即可。使用inBitmap參數前,每創建一個Bitmap對象都會分配一塊內存供其使用,而使用了inBitmap參數後,多個Bitmap可以複用一塊內存,這樣可以提高性能

4.StringBuilder替代String: 在有些時候,代碼中會需要使用到大量的字符串拼接的操作,這種時候有必要考慮使用StringBuilder來替代頻繁的“+”

5.避免在類似onDraw這樣的方法中創建對象,因爲它會迅速佔用大量內存,引起頻繁的GC甚至內存抖動

6.減少內存泄漏也是一種避免OOM的方法


面試時要注意,準備什麼?

注意

第一個問題就是“不求甚解”。

何爲不求甚解?其大多數的問題就是在於大量的使用第三方的jar包,問他個原理一點也答不上來,甚至是最基礎的。舉個例子說明,比如我問他json數據怎麼解析,都知道哪些解析器,直接不知道,因爲現在的開發者都直接去使用GJSON,從來不去了解解析的整個過程和原理,更不會寫。雖然用google提供的工具可以輕鬆實現,但是原理和過程還是得要學習的。學了總會有用,現在第三方的jar包多的是,封裝的也都比較好,不是不能用,但是一定要學習原理和機制,這樣才能提高自己,舉一反三,如果只會用第三方,只會粘貼複製,你還僅僅處在碼畜的級別,甚至有可能還不如。這個問題你犯了嗎?記得要對號入座哦!

第二個問題就是不思進取,或者說叫技術落後。

怎麼說呢,技術是不斷在進步的,不斷的在革新,尤其是我們程序員這個行業。很多程序猿一旦學習完了,工作了,雖然用舊的知識和技術也能實現這種效果,但是從不會考慮效率,不去學習新的技術,明明有更好的控件提供了,也不知道,或者知道並不去學習,還停留在以前的知識,面試時要的工資還挺高。再舉個例子,面試時,問他們ListView的複用,大家答的都挺好的,都非常明白,我再問一句:Android5.0提供了新的控件替代了它,你們知道嗎?用過嗎?就全都啞火了。

我都不知道該說什麼好?程序猿之所以累,之所以叫猿就是因爲他要時時刻刻保持一顆活到老學到老的心,要利用最新的技術知識解決新的難題。

講到這裏,兩個問題已經講完了,不知道你自己是否也有這樣的毛病呢?請記得對號入座哦。現在我們再說一說面試者的另一方面的事,那就是簡歷的書寫。

我相信大家寫面試簡歷肯定都有誇大的成分,都會吹牛,這不要緊,牛吹好了,工資自然高,但是別吹過頭,面試的時候我看到面試者的簡歷時,給我的感覺是:我靠,好屌,好厲害啊!這時一個情不自禁的想法就來了,我要問問他這方面的知識。

比如:一個面試應用層開發的,非把自己底層開發也寫的很牛逼,你真的像你簡歷上寫的那樣“精通”嗎?面試者把簡歷寫的每個技術知識點都是精通與熟練,有時候,反而是搬起石頭砸了自己的腳,吹牛可以,誇大也可以,都是爲了生存嗎?但是要適可而止,要在自己掌握的一個度裏,這樣既能自己面試的漂亮和順利,給面試官也有好的印象,這樣的情況不招你,招誰啊?

準備

  • 簡歷

先大概歸納下個人在簡歷篩選上的一些偏好吧:

1.技術人員的簡歷不要太多的頁數,最多兩個足矣,一頁最好;

2.個人的重要的基本信息還是要有的,如性別、出生日期(因爲有些面試官會在意年齡)、籍貫、基本的聯繫方式、畢業院校和專業、畢業時間等;

3.言簡意賅,突出重點和亮點。

其實,於招聘企業來說,在發出招聘信息時,已經有了一個大概的招聘要求,對於面試官來說,心中也已經有一定的。在龐雜的衆多簡歷中,如果能夠脫引而出,是每個應聘者需要好好考慮的。有時候,經常會聽到這樣一種觀點,技術人員沒必要弄那些虛的,紮紮實實的技術實力充分的體現在面試過程中就可以了。其實,我對此並不贊同。

1.簡歷簡歷,是陳述一個人的基本成長經歷,尤其是應聘目標崗位要求相關的經歷。這直接反應的是崗位的匹配度;

2.簡歷不僅僅是簡歷本身,同時也是應聘者對於過往經歷的回顧、總結與提煉,一份認真準備的簡歷也是應聘者應聘誠意的反應;

3.認真準備的簡歷,與虛不虛沒有關係,紮紮實實的技術實力固然可以充分的體現在面試過程中,但簡歷中的重點和亮點可以使得面試官更好的提問和交流,爲自己加分。

  • 刷題
    當然也是最重要的,畢竟我是有好幾年沒有過正規面試的經歷了,於是問我在阿里的同學要來了一份他們公司P8整理的一系列大廠面試題,刷到天昏地暗,如今我也已經入職了阿里,這些面試題對於我來說也沒什麼太大的用處,所以在這裏無償的分享給大家。

如果需要PDF版本可以在羣文件夾裏,自行領取!

進階學習視頻

附上:我們之前因爲秋招收集的二十套一二線互聯網公司Android面試真題 (含BAT、小米、華爲、美團、滴滴)和我自己整理Android複習筆記(包含Android基礎知識點、Android擴展知識點、Android源碼解析、設計模式彙總、Gradle知識點、常見算法題彙總。)

面試成功其實是必然的,因爲我做足了充分的準備工作,包括刷題啊,看一些Android核心的知識點,看一些面試的博客吸取大家面試的一些經驗,下面這份PDF是我翻閱了差不多1個月左右一些Android大博主的博客從他們那裏取其精華去其糟泊所整理出來的一些Android的核心知識點, 全部都是精華中的精華,我能面試到現在2-2資深開發人員跟我整理的這本Android核心知識點有密不可分的關係,在這裏本着共贏的心態分享給各位朋友。

這份PDF囊括了JVM,Java集合,Java多線程併發,Java基礎,生命週期,微服務, 進程,Parcelable 接口,IPC,屏幕適配,線程異步,ART,架構,Jetpack,NDK開發,計算機網絡基礎,類加載器,Android 開源庫源碼分析,設計模式彙總,Gradle 知識點彙總......

由於篇幅有限,就不做過多的介紹,大家請自行腦補,需要這份Android核心知識點及大廠面試題答案的朋友

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