2019最新Android中級面試題目彙總解答

注:由於實際開發與參考答案會有所不一樣,再者怕誤導你們,因此這些面試題答案仍是本身去理解!面試官會針對簡歷中提到的知識點由淺入深提問,因此不要背答案,多理解。

Android進階延伸點

一、如何進行單元測試,如何保證App穩定 ?

參考回答:面試

要測試Android應用程序,一般會建立如下類型自動單元測試編程

  • 本地測試:只在本地機器JVM上運行,以最小化執行時間,這種單元測試不依賴於Android框架,或者即便有依賴,也很方便使用模擬框架來模擬依賴,以達到隔離Android依賴的目的,模擬框架如Google推薦的Mockito;
  • 檢測測試:真機或模擬器上運行的單元測試,因爲須要跑到設備上,比較慢,這些測試能夠訪問儀器(Android系統)信息,好比被測應用程序的上下文,通常地,依賴不太方便經過模擬框架模擬時採用這種方式;
注意:單元測試不適合測試複雜的UI交互事件

App的穩定主要決定於總體的系統架構設計,同時也不可忽略代碼編程的細節規範,正所謂「千里之堤,潰於蟻穴」,一旦考慮不周,看似可有可無的代碼片斷可能會帶來總體軟件系統的崩潰,因此上線以前除了本身本地化測試以外還須要進行Monkey壓力測試安全

少部分面試官可能會延伸,如Gradle自動化測試、機型適配測試等微信

2.Android中如何查看一個對象的回收狀況 ?

參考回答:網絡

  • 首先要了解Java四種引用類型的場景和使用(強引用、軟引用、弱引用、虛引用)
  • 舉個場景例子:SoftReference對象是用來保存軟引用的,但它同時也是一個Java對象,因此當軟引用對象被回收以後,雖然這個SoftReference對象的get方法返回null,但SoftReference對象自己並非null,而此時這個SoftReference對象已經再也不具備存在的價值,須要一個適當的清除機制,避免大量SoftReference對象帶來的內存泄露
  • 所以,Java提供ReferenceQueue來處理引用對象的回收狀況。當SoftReference所引用的對象被GC後,JVM會先將softReference對象添加到ReferenceQueue這個隊列中。當咱們調用ReferenceQueue的poll()方法,若是這個隊列中不是空隊列,那麼將返回並移除前面添加的那個Reference對象。

3.Apk的大小如何壓縮 ?

參考回答:架構

3.1一個完整APK包含如下目錄(將APK文件拖到Android Studio):
  • META-INF/:包含CERT.SF和CERT.RSA簽名文件以及MANIFEST.MF 清單文件。
  • assets/:包含應用可使用AssetManager對象檢索的應用資源。
  • res/:包含未編譯到的資源 resources.arsc。
  • lib/:包含特定於處理器軟件層的編譯代碼。該目錄包含了每種平臺的子目錄,像armeabi,armeabi-v7a, arm64-v8a,x86,x86_64,和mips
  • resources.arsc:包含已編譯的資源。該文件包含res/values/ 文件夾全部配置中的XML內容。打包工具提取此XML內容,將其編譯爲二進制格式,並將內容歸檔。此內容包括語言字符串和樣式,以及直接包含在*resources.arsc8文件中的內容路徑 ,例如佈局文件和圖像。
  • classes.dex:包含以Dalvik / ART虛擬機可理解的DEX文件格式編譯的類。
  • AndroidManifest.xml:包含核心Android清單文件。該文件列出應用程序的名稱,版本,訪問權限和引用的庫文件。該文件使用Android的二進制XML格式。

  • lib、class.dex和res佔用了超過90%的空間,因此這三塊是優化Apk大小的重點(實際狀況不惟一)
3.2.減小res,壓縮圖文文件

圖片文件壓縮是針對jpg和png格式的圖片。咱們一般會放置多套不一樣分辨率的圖片以適配不一樣的屏幕,這裏能夠進行適當的刪減。在實際使用中,只保留一到兩套就足夠了(保留一套的話建議保留xxhdpi,兩套的話就加上hdpi),而後再對剩餘的圖片進行壓縮(jpg採用優圖壓縮,png嘗試採用pngquant壓縮)app

3.3.減小dex文件大小
  • 添加資源混淆

  • shrinkResources爲true表示移除未引用資源,和代碼壓縮協同工做。
  • minifyEnabled爲true表示經過ProGuard啓用代碼壓縮,配合proguardFiles的配置對代碼進行混淆並移除未使用的代碼。
  • 代碼混淆在壓縮apk的同時,也提高了安全性。
3.4.減小lib文件大小
  • 因爲引用了不少第三方庫,lib文件夾佔用的空間一般都很大,特別是有so庫的狀況下。不少so庫會同時引入armeabi、armeabi-v7a和x86這幾種類型,這裏能夠只保留armeabi或armeabi-v7a的其中一個就能夠了,實際上微信等主流app都是這麼作的。
  • 只需在build.gradle直接配置便可,NDK配置同理

4.如何經過Gradle配置多渠道包?

參考回答:框架

首先要了解設置多渠道的緣由。在安裝包中添加不一樣的標識,配合自動化埋點,應用在請求網絡的時候攜帶渠道信息,方便後臺作運營統計,好比說統計咱們的應用在不一樣應用市場的下載量等信息編輯器

  • 這裏以友盟統計爲例工具

    • 首先在manifest.xml文件中設置動態渠道變量:

  • 接着在app目錄下的build.gradle中配置productFlavors,也就是配置打包的渠道:

  • 最後在編輯器下方的Teminal輸出命令行
  1. 執行./gradlew assembleRelease ,將會打出全部渠道的release包;
  2. 執行./gradlew assembleVIVO,將會打出VIVO渠道的release和debug版的包;
  3. 執行./gradlew assembleVIVORelease將生成VIVO的release包。

5.插件化原理分析

參考回答:

插件化是指將 APK 分爲宿主和插件的部分。把須要實現的模塊或功能當作一個獨立的提取出來,在 APP 運行時,咱們能夠動態的載入或者替換插件部分,減小宿主的規模

  • 宿主: 就是當前運行的APP。
  • 插件: 相對於插件化技術來講,就是要加載運行的apk類文件。

而熱修復則是從修復bug的角度出發,強調的是在不須要二次安裝應用的前提下修復已知的bug。能

類加載機制
Android中經常使用的兩種類加載器,DexClassLoader和PathClassLoader,它們都繼承於BaseDexClassLoader,二者區別在於PathClassLoader只能加載內部存儲目錄的dex/jar/apk文件。DexClassLoader支持加載指定目錄(不限於內部)的dex/jar/apk文件

插件通訊:經過給插件apk生成相應的DexClassLoader即可以訪問其中的類,可分爲單DexClassLoader和多DexClassLoader兩種結構。

  • 若使用多ClassLoader機制,主工程引用插件中類須要先經過插件的ClassLoader加載該類再經過反射調用其方法。插件化框架通常會經過統一的入口去管理對各個插件中類的訪問,而且作必定的限制。
  • 若使用單ClassLoader機制,主工程則能夠直接經過類名去訪問插件中的類。該方式有個弊端,若兩個不一樣的插件工程引用了一個庫的不一樣版本,則程序可能會出錯

資源加載

  • 原理在於經過反射將插件apk的路徑加入AssetManager中並建立Resource對象加載資源,有兩種處理方式:

合併式:addAssetPath時加入全部插件和主工程的路徑;因爲AssetManager中加入了全部插件和主工程的路徑,所以生成的Resource能夠同時訪問插件和主工程的資源。可是因爲主工程和各個插件都是獨立編譯的,生成的資源id會存在相同的狀況,在訪問時會產生資源衝突。

  • 獨立式:各個插件只添加本身apk路徑,各個插件的資源是互相隔離的,不過若是想要實現資源的共享,必須拿到對應的Resource對象。

6.組件化原理

參考回答:

引入組件化的緣由:項目隨着需求的增長規模變得愈來愈大,規模的增大致使了各類業務錯中複雜的交織在一塊兒, 每一個業務模塊之間,代碼沒有約束,帶來了代碼邊界的模糊,代碼衝突時有發生, 更改一個小問題可能引發一些新的問題, 牽一髮而動全身,增長一個新需求,須要熟悉相關的代碼邏輯,增長開發時間

  • 避免重複造輪子,能夠節省開發和維護的成本。
  • 能夠經過組件和模塊爲業務基準合理地安排人力,提升開發效率。
  • 不一樣的項目能夠共用一個組件或模塊,確保總體技術方案的統一性。
  • 爲將來插件化共用同一套底層模型作準備。

組件化開發流程就是把一個功能完整的App或模塊拆分紅多個子模塊(Module),每一個子模塊能夠獨立編譯運行,也能夠任意組合成另外一個新的 App或模塊,每一個模塊即不相互依賴但又能夠相互交互,可是最終發佈的時候是將這些組件合併統一成一個apk,遇到某些特殊狀況甚至能夠升級或者降級

舉個簡單的模型例子

App是主application,ModuleA和ModuleB是兩個業務模塊(相對獨立,互不影響),Library是基礎模塊,包含全部模塊須要的依賴庫,以及一些工具類:如網絡訪問、時間工具等

注意:提供給各業務模塊的基礎組件,須要根據具體狀況拆分紅 aar 或者 library,像登陸,基礎網絡層這樣較爲穩定的組件,通常直接打包成 aar,減小編譯耗時。而像自定義 View 組件,因爲隨着版本迭代會有較多變化,就直接以源碼形式抽離成 Library

7.跨組件通訊

參考回答:

7.1.跨組件通訊場景:
  • 第一種是組件之間的頁面跳轉 (Activity 到 Activity, Fragment 到 Fragment, Activity 到 Fragment, Fragment 到 Activity) 以及跳轉時的數據傳遞 (基礎數據類型和可序列化的自定義類類型)。
  • 第二種是組件之間的自定義類和自定義方法的調用(組件向外提供服務)。
7.2.跨組件通訊方案分析:
  • 第一種組件之間的頁面跳轉實現簡單,跳轉時想傳遞不一樣類型的數據提供有相應的 API便可
  • 第二種組件之間的自定義類和自定義方法的調用要稍微複雜點,須要 ARouter 配合架構中的 公共服務(CommonService) 實現:

    • 提供服務的業務模塊:
    • 在公共服務(CommonService) 中聲明 Service 接口 (含有須要被調用的自定義方法), 而後在本身的模塊中實現這個 Service 接口, 再經過 ARouter API 暴露實現類。
    • 使用服務的業務模塊:

經過 ARouter 的 API 拿到這個 Service 接口(多態持有, 實際持有實現類), 便可調用 Service 接口中聲明的自定義方法, 這樣就能夠達到模塊之間的交互。

  • 此外,可使用 AndroidEventBus 其獨有的 Tag, 能夠在開發時更容易定位發送事件和接受事件的代碼, 若是以組件名來做爲 Tag 的前綴進行分組, 也能夠更好的統一管理和查看每一個組件的事件, 固然也不建議你們過多使用 EventBus。
7.3.如何管理過多的路由表?
  • RouterHub 存在於基礎庫, 能夠被看做是全部組件都須要遵照的通信協議, 裏面不只能夠放路由地址常量, 還能夠放跨組件傳遞數據時命名的各類 Key 值, 再配以適當註釋, 任何組件開發人員不須要事先溝通只要依賴了這個協議, 就知道了各自該怎樣協同工做, 既提升了效率又下降了出錯風險, 約定的東西天然要比口頭上說強
  • Tips: 若是您以爲把每一個路由地址都寫在基礎庫的 RouterHub 中, 太麻煩了, 也能夠在每一個組件內部創建一個私有 RouterHub, 將不須要跨組件的路由地址放入私有 RouterHub 中管理, 只將須要跨組件的路由地址放入基礎庫的公有 RouterHub 中管理, 若是您不須要集中管理全部路由地址的話, 這也是比較推薦的一種方式。
7.4.ARouter路由原理:

ARouter維護了一個路由表Warehouse,其中保存着所有的模塊跳轉關係,ARouter路由跳轉實際上仍是調用了startActivity的跳轉,使用了原生的Framework機制,只是經過apt註解的形式製造出跳轉規則,並人爲地攔截跳轉和設置跳轉條件

常見的組件化方案以下

Android中級面試題目彙總解答到此就結束了想獲取更多Android方面的技術知識或者面試資料的能夠添加QQ羣:
Android開發交流羣:1018342383

相關文章
相關標籤/搜索