對過去的兩三年作個總結,或許能幫助到些人,或者從中能得一些建議。此次出去面試主要是兩個星期的時間,第一個星期主要是投簡歷,第二個星期主要是面試,一天安排了2-3個面試。
下面是我總結的一些準備面試的Tips以及面試必備的注意事項java
1.準備一份本身的自我介紹,面試的時候根據面試對象適當進行修改(突出重點,突出本身的優點在哪裏,切忌流水帳);android
2.注意隨身帶上本身的成績單和簡歷複印件; (有的公司在面試前都會讓你交一份成績單和簡歷當作面試中的參考。)git
3.若是須要筆試就提早刷一些筆試題,大部分在線筆試的類型是選擇題+編程題,有的還會有簡答題。(平時空閒時間多的能夠刷一下筆試題目(牛客網上有不少),可是不要只刷面試題,不動手code,程序員不是爲了考試而存在的。)另外,注意抓重點,由於題目太多了,可是有不少題目幾乎次次遇到,像這樣的題目必定要搞定。程序員
4.提早準備技術面試。 搞清楚本身面試中可能涉及哪些知識點、那些知識點是重點。面試中哪些問題會被常常問到、本身改如何回答。(強烈不推薦背題)
第一: 經過背這種方式你能記住多少?能記住多久?
第二: 背題的方式的學習很難堅持下去!github
5.面試以前作好定向複習。 也就是專門針對你要面試的公司來複習。好比你在面試以前能夠在網上找找有沒有你要面試的公司的面經。面試
6.準備好本身的項目介紹。 若是有項目的話,技術面試第一步,面試官通常都是讓你本身介紹一下你的項目。你能夠從下面幾個方向來考慮:算法
①對項目總體設計的一個感覺(面試官可能會讓你畫系統的架構圖;
②在這個項目中你負責了什麼、作了什麼、擔任了什麼角色;
③ 從這個項目中你學會了那些東西,使用到了那些技術,學會了那些新技術的使用;
④項目描述中,最好能夠體現本身的綜合素質,好比你是如何協調項目組成員協同開發的或者在遇到某一個棘手的問題的時候你是如何解決的又或者說你在這個項目用了什麼技術實現了什麼功能好比:Android Bitmap壓縮策略;關於HandlerThread的使用場景以及怎樣使用 HandlerThread?
提早知道有哪些技術問題常問: HashMap源碼分析、熱修復,handler等等問題我以爲面試中實在太常見了,好好準備!後面的文章會我會分類詳細介紹到那些問題最常問。編程
提早熟悉一些常問的非技術問題: 面試的時候有一些常見的非技術問題好比「面試官問你的優勢是什麼,應該如何回答?」、「面試官問你的缺點是什麼,應該如何回答?」、「若是面試官問"你有什麼問題問我嗎?"時,你該如何回答」等等,對於這些問題,如何回答本身內心要有個數,別面試的時候出了亂子。設計模式
6.面試以後記得覆盤。 面試遭遇失敗是很正常的事情,因此善於總結本身的失敗緣由纔是最重要的。若是失敗,不要灰心;若是經過,切勿狂喜。緩存
以上的面試題,主要是Android應用層知識,須要面試以前造造火箭的,還須要平時的耕耘、積累和總結。
Java中引用類型分爲四類: 強引用、軟引用、弱引用、虛引用。
強引用: 強引用指的是經過new對象建立的引用,垃圾回收器即便是內存不足也不會回收強引用指向的對象。
軟引用: 軟引用是經過SoftRefrence實現的,它的生命週期比強引用短,在內存不足,拋出OOM以前,垃圾回收器會回收軟引用引用的對象。軟引用常見的使用場景是存儲一些內存敏感的緩存,當內存不足時會被回收。
弱引用: 弱引用是經過WeakRefrence實現的,它的生命週期比軟引用還短,GC只要掃描到弱引用的對象就會回收。弱引用常見的使用場景也是存儲一些內存敏感的緩存。
虛引用: 虛引用是經過FanttomRefrence實現的,它的生命週期最短,隨時可能被回收。若是一個對象只被虛引用引用,咱們沒法經過虛引用來訪問這個對象的任何屬性和方法。它的做用僅僅是保證對象在finalize後,作某些事情。虛引用常見的使用場景是跟蹤對象被垃圾回收的活動,當一個虛引用關聯的對象被垃圾回收器回收以前會收到一條系統通知。
通常提到volatile,就不得不提到內存模型相關的概念。咱們都知道,在程序運行中,每條指令都是由CPU執行的,而指令的執行過程當中,勢必涉及到數據的讀取和寫入。程序運行中的數據都存放在主存中,這樣會有一個問題,因爲CPU的執行速度是要遠高於主存的讀寫速度,因此直接從主存中讀寫數據會下降CPU的效率。爲了解決這個問題,就有了高速緩存的概念,在每一個CPU中都有高速緩存,它會事先從主存中讀取數據,在CPU運算以後在合適的時候刷新到主存中。
這樣的運行模式在單線程中是沒有任何問題的,但在多線程中,會致使緩存一致性的問題。舉個簡單的例子:i=i+1 ,在兩個線程中執行這句代碼,假設i的初始值爲0。咱們指望兩個線程運行後獲得2,那麼有這樣的一種狀況,兩個線程都從主存中讀取i到各自的高速緩存中,這時候兩個線程中的i都爲0。在線程1執行完畢獲得i=1,將之刷新到主存後,線程2開始執行,因爲線程2中的i是高速緩存中的0,因此在執行完線程2以後刷新到主存的i仍舊是1。
因此這就致使了對共享變量的緩存一致性的問題,那麼爲了解決這個問題,提出了緩存一致性協議:當CPU在寫數據時,若是發現操做的是共享變量,它會通知其餘CPU將它們內部的這個共享變量置爲無效狀態,當其餘CPU讀取緩存中的共享變量時,發現這個變量是無效的,它會重新從主存中讀取最新的值。
在Java的多線程開發中,有三個重要概念:原子性、可見性、有序性。
原子性: 一個或多個操做要麼都不執行,要麼都執行。
可見性: 一個線程中對共享變量(類中的成員變量或靜態變量)的修改,在其餘線程當即可見。
有序性: 程序執行的順序按照代碼的順序執行。
把一個變量聲明爲volatile,其實就是保證了可見性和有序性。
可見性我上面已經說過了,在多線程開發中是頗有必要的。這個有序性仍是得說一下,爲了執行的效率,有時候會發生指令重排,這在單線程中指令重排以後的輸出與咱們的代碼邏輯輸出仍是一致的。但在多線程中就可能發生問題,volatile在必定程度上能夠避免指令重排。
volatile的原理是在生成的彙編代碼中多了一個lock前綴指令,這個前綴指令至關於一個內存屏障,這個內存屏障有3個做用:
AIDL 、廣播、文件、socket、管道
Android中經常使用的性能優化工具包括這些:Android Studio自帶的Android Profiler、LeakCanary、BlockCanary
Android自帶的Android Profiler其實就很好用,Android Profiler能夠檢測三個方面的性能問題:CPU、MEMORY、NETWORK。
LeakCanary是一個第三方的檢測內存泄漏的庫,咱們的項目集成以後LeakCanary會自動檢測應用運行期間的內存泄漏,並將之輸出給咱們。
BlockCanary也是一個第三方檢測UI卡頓的庫,項目集成後Block也會自動檢測應用運行期間的UI卡頓,並將之輸出給咱們。
PathClassLoader,只能加載系統中已經安裝過的apk
DexClassLoader,能夠加載jar/apk/dex,能夠從SD卡中加載未安裝的apk
Android中動畫大體分爲3類: 幀動畫、補間動畫(View Animation)、屬性動畫(Object Animation)。
幀動畫: 經過xml配置一組圖片,動態播放。不多會使用。
補間動畫(View Animation): 大體分爲旋轉、透明、縮放、位移四類操做。不多會使用。
屬性動畫(Object Animation
): 屬性動畫是如今使用的最多的一種動畫,它比補間動畫更增強大。屬性動畫大體分爲兩種使用類型,分別是ViewPropertyAnimator
和ObjectAnimator
。前者適合一些通用的動畫,好比旋轉、位移、縮放和透明,使用方式也很簡單經過View.animate()
便可獲得ViewPropertyAnimator
,以後進行相應的動畫操做便可。後者適合用於爲咱們的自定義控件添加動畫,固然首先咱們應該在自定義View中添加相應的getXXX()
和setXXX()
相應屬性的getter
和setter
方法,這裏須要注意的是在setter方法內改變了自定義View中的屬性後要調用invalidate()
來刷新View的繪製。以後調用ObjectAnimator.of
屬性類型()返回一個ObjectAnimator
,調用start()
方法啓動動畫便可。
補間動畫與屬性動畫的區別:
說到Handler,就不得不提與之密切相關的這幾個類:Message
、MessageQueue
,Looper
。
target
和callback
。target其實就是發送消息的Handler對象,callback是當調用handler.post(runnable)
時傳入的Runnable
類型的任務。post事件的本質也是建立了一個Message
,將咱們傳入的這個runnable賦值給建立的Message
的callback
這個成員變量。MessageQueue
中的next()
方法,它會返回下一個待處理的消息。Looper.prepare()
建立Looper,以後還得調用Looper.loop()
開啓輪詢。咱們着重看一下這兩個方法。prepare()
。這個方法作了兩件事:首先經過ThreadLocal.get()
獲取當前線程中的Looper,若是不爲空,則會拋出一個RunTimeException,意思是一個線程不能建立2個Looper。若是爲null則執行下一步。第二步是建立了一個Looper,並經過ThreadLocal.set(looper)
。將咱們建立的Looper與當前線程綁定。這裏須要提一下的是消息隊列的建立其實就發生在Looper的構造方法中。
loop()
。這個方法開啓了整個事件機制的輪詢。它的本質是開啓了一個死循環,不斷的經過MessageQueue
的next()
方法獲取消息。拿到消息後會調用msg.target.dispatchMessage()
來作處理。其實咱們在說到Message的時候提到過,msg.target其實就是發送這個消息的handler。這句代碼的本質就是調用handler的dispatchMessage()
。Handler。上面作了這麼多鋪墊,終於到了最重要的部分。Handler的分析着重在兩個部分:發送消息和處理消息
發送消息。其實發送消息除了sendMessage
以外還有sendMessageDelayed
和post以及postDelayed等等不一樣的方式。但它們的本質都是調用了sendMessageAtTime
。在sendMessageAtTime
這個方法中調用了enqueueMessage
。在enqueueMessage
這個方法中作了兩件事:經過msg.target = this
實現了消息與當前handler的綁定。而後經過queue.enqueueMessage
實現了消息入隊。
處理消息。消息處理的核心其實就是dispatchMessage()
這個方法。這個方法裏面的邏輯很簡單,先判斷msg.callback
是否爲null,若是不爲空則執行這個runnable
。若是爲空則會執行咱們的handleMessage
方法。
Android中的性能優化在我看來分爲如下幾個方面:內存優化、佈局優化、網絡優化、安裝包優化。
內存優化: 下一個問題就是。
佈局優化: 佈局優化的本質就是減小View的層級。常見的佈局優化方案以下
網絡優化: 常見的網絡優化方案以下
安裝包優化: 安裝包優化的核心就是減小apk的體積,常見的方案以下
Android的內存優化在我看來分爲兩點: 避免內存泄漏、擴大內存,其實就是開源節流。
其實內存泄漏的本質就是較長生命週期的對象引用了較短生命週期的對象。
常見的內存泄漏:
擴大內存,爲何要擴大咱們的內存呢?有時候咱們實際開發中不可避免的要使用不少第三方商業的SDK,這些SDK其實有好有壞,大廠的SDK可能內存泄漏會少一些,但一些小廠的SDK質量也就不太靠譜一些。那應對這種咱們沒法改變的狀況,最好的辦法就是擴大內存。
擴大內存一般有兩種方法:一個是在清單文件中的Application下添加largeHeap=」true」這個屬性,另外一個就是同一個應用開啓多個進程來擴大一個應用的總內存空間。第二種方法其實就很常見了,比方說我使用過個推的SDK,個推的Service其實就是處在另一個單獨的進程中。
Android中的內存優化總的來講就是開源和節流,開源就是擴大內存,節流就是避免內存泄漏。
在Linux中,爲了不一個進程對其餘進程的干擾,進程之間是相互獨立的。在一個進程中其實還分爲用戶空間和內核空間。這裏的隔離分爲兩個部分,進程間的隔離和進程內的隔離。
既然進程間存在隔離,那其實也是存在着交互。進程間通訊就是IPC,用戶空間和內核空間的通訊就是系統調用。
Linux爲了保證獨立性和安全性,進程之間不能直接相互訪問,Android是基於Linux的,因此也是須要解決進程間通訊的問題。
其實Linux進程間通訊有不少方式,好比管道、socket等等。爲何Android進程間通訊採用了Binder而不是Linux已有的方式,主要是有這麼兩點考慮:性能和安全
性能。在移動設備上對性能要求是比較嚴苛的。Linux傳統的進程間通訊好比管道、socket等等進程間通訊是須要複製兩次數據,而Binder則只須要一次。因此Binder在性能上是優於傳統進程通訊的。
安全。傳統的Linux進程通訊是不包含通訊雙方的身份驗證的,這樣會致使一些安全性問題。而Binder機制自帶身份驗證,從而有效的提升了安全性。
Binder是基於CS架構的,有四個主要組成部分。
Binder機制主要的流程是這樣的:
整體發現整個面試下來,投簡歷發現今年996的公司還蠻多的,前兩年沒有這麼多。有的人事,boss會直接說是996,要麼本身面試過程當中問是否是996,996的公司是拒絕的,壓根不想去。面試的過程當中發現本身的信心不夠,技術能力也不夠、本身也着急。面試想一想這幾點要特別注意。
寫代碼總結如下幾點:
1.須要確認需求的,理解有誤差的。寫代碼以前必定要和產品經理溝通交流。寧願多花時間去和測試的、設計師溝通,也不要去埋頭寫代碼。一樣的,認真想一想怎麼實現這樣一個功能,思路理清了在敲代碼。
2.養成良好的編碼習慣,風格。多看看Google開源的在github上示例,或者其它知名公司的。
3.六大設計原則、一些經常使用的設計模式理解透牢記於心,多在編碼過程當中使用。
4.代碼要有思路,寫好註釋,寫的代碼不僅僅是本身要看,也是給別人看的。
5.平時學習須要多總結、多體會、代碼須要多動手敲。
更多面試內容分析,分享,學習筆記整理,視頻整理。核心筆記PDF
https://github.com/xiangjiana...
(點個star。專一分享技術乾貨/編程資源/求職面試/成長感悟等,關注送983頁PDF面試資源,免費下載CSDN資源。領取PDF面試大全,附送CSDN下載資源)