分享幾個重要的Android面試題

想念你的Android發表於2018-12-11

說一下JAVA多型的理解,以及接繼承,和介面的理解

於哥在這裡只講多型,其他自己上網體會

對於多型的定義

不同類的物件對統一函式做出不同對的響應或者動作。

作用

主要是消除類之間的耦合性,靈活性比較強,利於程式碼的編寫和修改。尤其在處理大量的運算和操作時,可以靈活地簡化,替換或者是修改程式碼!

Android群653583088進群私聊管理員可以免費獲得Android架構資料和原始碼解析資料以及10年經驗大佬講解

三個必要條件

1、一個凳子(繼承extends)

2、重寫

3、父類引用指向子類物件

for example

測試結果:

測試結果

OKHTTP的 原理

1.同步和非同步:

  • 1.非同步使用了Dispatcher來將儲存在 Deque 中的請求分派給執行緒池中各個執行緒執行。
  • 2.當任務執行完成後,無論是否有異常,finally程式碼段總會被執行,也就是會呼叫Dispatcher的finished函式,它將正在執行的任務Call從佇列runningAsyncCalls中移除後,主動的把快取佇列向前走了一步。

2.連線池:

  • 1.一個Connection封裝了一個socket,ConnectionPool中儲存s著所有的Connection,StreamAllocation是引用計數的一個單位
  • 2.當一個請求獲取一個Connection的時候要傳入一個StreamAllocation,Connection中存著一個弱引用的StreamAllocation列表,每當上層應用引用一次Connection,StreamAllocation就會加一個。反之如果上層應用不使用了,就會刪除一個。
  • 3.ConnectionPool中會有一個後臺任務定時清理StreamAllocation列表為空的Connection。5分鐘時間,維持5個socket

3.選擇路線與建立連線

  • 1.選擇路線有兩種方式:
    • 1.無代理,那麼在本地使用DNS查詢到ip,注意結果是陣列,即一個域名有多個IP,這就是自動重連的來源
    • 2.有代理HTTP:設定socket的ip為代理地址的ip,設定socket的埠為代理地址的埠
    • 3.代理好處:HTTP代理會幫你在遠端伺服器進行DNS查詢,可以減少DNS劫持。
  • 2.建立連線
    • 1.連線池中已經存在連線,就從中取出(get)RealConnection,如果沒有命中就進入下一步
    • 2.根據選擇的路線(Route),呼叫Platform.get().connectSocket選擇當前平臺Runtime下最好的socket庫進行握手
    • 3.將建立成功的RealConnection放入(put)連線池快取
    • 4.如果存在TLS,就根據SSL版本與證照進行安全握手
    • 5.構造HttpStream並維護剛剛的socket連線,管道建立完成

4.職責鏈模式:快取、重試、建立連線等功能存在於攔截器中網路請求相關,主要是網路請求優化。網路請求的時候遇到的問題

執行緒同步的問題,常用的執行緒同步

1.sycn:保證了原子性、可見性、有序性

2.鎖:保證了原子性、可見性、有序性

  • 1.自旋鎖:可以使執行緒在沒有取得鎖的時候,不被掛起,而轉去執行一個空迴圈。
    • 1.優點:執行緒被掛起的機率減少,執行緒執行的連貫性加強。用於對於鎖競爭不是很激烈,鎖佔用時間很短的併發執行緒。
    • 2.缺點:過多浪費CPU時間,有一個執行緒連續兩次試圖獲得自旋鎖引起死鎖
  • 2.阻塞鎖:沒得到鎖的執行緒等待或者掛起,Sycn、Lock
  • 3.可重入鎖:一個執行緒可多次獲取該鎖,Sycn、Lock
  • 4.悲觀鎖:每次去拿資料的時候都認為別人會修改,所以會阻塞全部其他執行緒 Sycn、Lock
  • 5.樂觀鎖:每次去拿資料的時候都認為別人不會修改,所以不會上鎖,但是在更新的時候會判斷一下在此期間別人有沒有去更新這個資料,可以使用版本號等機制。cas
  • 6.顯示鎖和內建鎖:顯示鎖用Lock來定義、內建鎖用synchronized。
  • 7.讀-寫鎖:為了提高效能,Java提供了讀

3.volatile

  • 1.只能保證可見性,不能保證原子性
  • 2.自增操作有三步,此時多執行緒寫會出現問題

4.cas

  • 1.操作:記憶體值V、舊的預期值A、要修改的值B,當且僅當預期值A和記憶體值V相同時,將記憶體值修改為B並返回true,否則什麼都不做並返回false。
  • 2.解釋:本地副本為A,共享記憶體為V,執行緒A要把V修改成B。某個時刻執行緒A要把V修改成B,如果A和V不同那麼就表示有其他執行緒在修改V,此時就表示修改失敗,否則表示沒有其他執行緒修改,那麼把V改成B。
  • 3.侷限:如果V被修改成V1然後又被改成V,此時cas識別不出變化,還是認為沒有其他執行緒在修改V,此時就會有問題
  • 4.侷限解決:將V帶上版本。

5.執行緒不安全到底是怎麼回事:

  • 1.一個執行緒寫,多個執行緒讀的時候,會造成寫了一半就去讀
  • 2.多執行緒寫,會造成髒資料

ASYNCTASK和執行緒池,GC相關(怎麼判斷哪些記憶體該GC,GC演算法)

1.Asynctask:非同步任務類,單執行緒執行緒池+Handler

2.執行緒池:

  • 1.ThreadPoolExecutor:通過Executors可以構造單執行緒池、固定數目執行緒池、不固定數目執行緒池。

  • 2.ScheduledThreadPoolExecutor:可以延時呼叫執行緒或者延時重複排程執行緒。

    3.GC相關:重要

  • 1.搜尋演算法:

    1.引用計數

    2.圖搜尋,可達性分析

  • 2.回收演算法:

    1.標記清除複製:用於青年代

    2.標記整理:用於老年代

  • 3.堆分割槽:

    1.青年區eden 80%、survivor1 10%、survivor2 10%

    2.老年區

  • 4.虛擬機器棧分割槽:

    1.區域性變數表

    2.運算元棧

    3.動態連結

    4.方法返回地址

  • 5.GC Roots:

    1.虛擬機器棧(棧楨中的本地變數表)中的引用的物件

    2.方法區中的類靜態屬性引用的物件

    3.方法區中的常量引用的物件

    4.本地方法棧中JNI的引用的物件

JAVA類載入過程:

  • 1.載入時機:建立例項、訪問靜態變數或方法、反射、載入子類之前
  • 2.驗證:驗證檔案格式、後設資料、位元組碼、符號引用的正確性
  • 3.載入:根據全類名獲取檔案位元組流、將位元組流轉化為靜態儲存結構放入方法區、生成class物件
  • 4.準備:在堆上為靜態變數劃分記憶體
  • 5.解析:將常量池中的符號引用轉換為直接引用
  • 6.初始化:初始化靜態變數

MVC、MVP、MVVM:

  • 1.mvc:資料、View、Activity,View將操作反饋給Activity,Activitiy去獲取資料,資料通過觀察者模式重新整理給View。迴圈依賴
    • 1.Activity重,很難單元測試
    • 2.View和Model耦合嚴重
  • 2.mvp:資料、View、Presenter,View將操作給Presenter,Presenter去獲取資料,資料獲取好了返回給Presenter,Presenter去重新整理View。PV,PM雙向依賴
    • 1.介面爆炸
    • 2.Presenter很重
  • 3.mvvm:資料、View、ViewModel,View將操作給ViewModel,ViewModel去獲取資料,資料和介面繫結了,資料更新介面更新。
    • 1.viewModel的業務邏輯可以單獨拿來測試
    • 2.一個view 對應一個 viewModel 業務邏輯可以分離,不會出現全能類
    • 3.資料和介面繫結了,不用寫垃圾程式碼,但是複用起來不舒服

APK瘦身:

1.classes.dex:通過程式碼混淆,刪掉不必要的jar包和程式碼實現該檔案的優化

2.資原始檔:通過Lint工具掃描程式碼中沒有使用到的靜態資源

3.圖片資源:使用tinypng和webP,下面詳細介紹圖片資源優化的方案,向量圖

4.SO檔案將不用的去掉,目前主流app一般只放一個arm的so包

ANR的形成,各個元件上出現ARN的時間限制是多少

1.只要是主執行緒耗時的操作就會ARN 如io

2.broadcast超時時間為10秒 按鍵無響應的超時時間為5秒 前臺service無響應的超時時間為20秒,後臺service為200秒

SERIALIZABLE和PARCELABLE 的區別

1.P 消耗記憶體小

2.網路傳輸用S 程式內使用P

3.S將資料持久化方便

4.S使用了反射 容易觸發垃圾回收 比較慢

SHAREDPREFERENCES原始碼簡述

1.儲存於硬碟上的xml鍵值對,資料多了會有效能問題

2.ContextImpl記錄著SharedPreferences的重要資料,檔案路徑和例項的鍵值對

3.在xml檔案全部內載入到記憶體中之前,讀取操作是阻塞的,在xml檔案全部內載入到記憶體中之後,是直接讀取記憶體中的資料

4.apply因為是非同步的沒有返回值, commit是同步的有返回值能知道修改是否提交成功

5.多併發的提交commit時,需等待正在處理的commit資料更新到磁碟檔案後才會繼續往下執行,從而降低效率; 而apply只是原子更新到記憶體,後呼叫apply函式會直接覆蓋前面記憶體資料,從一定程度上提高很多效率。 3.edit()每次都是建立新的EditorImpl物件.

ANR的形成,各個元件上出現ARN的時間限制是多少

1.只要是主執行緒耗時的操作就會ARN 如io

2.broadcast超時時間為10秒 按鍵無響應的超時時間為5秒 前臺service無響應的超時時間為20秒,後臺service為200秒

APK瘦身:

1.classes.dex:通過程式碼混淆,刪掉不必要的jar包和程式碼實現該檔案的優化

2.資原始檔:通過Lint工具掃描程式碼中沒有使用到的靜態資源

3.圖片資源:使用tinypng和webP,下面詳細介紹圖片資源優化的方案,向量圖

4.SO檔案將不用的去掉,目前主流app一般只放一個arm的so包

Android群653583088進群私聊管理員可以免費獲得Android架構資料和原始碼解析資料以及10年經驗大佬講解


相關文章