Android性能優化面試題集錦

前言

很多人面試之前,可能沒有在互聯網公司工作過或者說工作過但年頭較短,不知道互聯網公司技術面試都會問哪些問題? 再加上可能自己準備也不充分,去面試沒幾個回合就被面試官幾個問題打蒙了,最後以慘敗收場。

下述是我收錄整理的Android面試題彙總,由於篇幅原因,在這隻把性能優化部分的題目列舉出來,後續還會更新其餘面試題內容,大家可以關注一下我,及時知曉我更新的知識點,同時這份面試集錦的整理也花費了我很多時間,有需要的朋友可以幫忙轉發分享下,點個贊~

性能優化

Android的性能優化,主要是從以下幾個方面進行優化的: 穩定(內存溢出、崩潰) 流暢(卡頓) 耗損(耗電、流量) 安裝包(APK瘦身) 影響穩定性的原因很多,比如內存使用不合理、代碼異常場景考慮不周全、代碼邏輯不合理等,都會對應用的穩定性造成影響。其中最常見的兩個場景是:Crash 和 ANR,這兩個錯誤將會使得程序無法使用。所以做好Crash全局監控,處理閃退同時把崩潰信息、異常信息收集記錄起來,以便後續分析;合理使用主線程處理業務,不要在主線程中做耗時操作,防止ANR程序無響應發生。

(一)穩定——內存優化

(1)Memory Monitor 工具:

它是Android Studio自帶的一個內存監視工具,它可以很好地幫助我們進行內存實時分析。通過點擊Android Studio右下角的Memory Monitor標籤,打開工具可以看見較淺藍色代表free的內存,而深色的部分代表使用的內存從內存變換的走勢圖變換,可以判斷關於內存的使用狀態,例如當內存持續增高時,可能發生內存泄漏;當內存突然減少時,可能發生GC等,如下圖所示。

(2)LeakCanary工具:

LeakCanary是Square公司基於MAT開發的一款監控Android內存泄漏的開源框架。其工作的原理是: 監測機制利用了Java的WeakReference和ReferenceQueue,通過將Activity包裝到WeakReference中,被WeakReference包裝過的Activity對象如果被回收,該WeakReference引用會被放到ReferenceQueue中,通過監測ReferenceQueue裏面的內容就能檢查到Activity是否能夠被回收(在ReferenceQueue中說明可以被回收,不存在泄漏;否則,可能存在泄漏,LeakCanary是執行一遍GC,若還未在ReferenceQueue中,就會認定爲泄漏)。

如果Activity被認定爲泄露了,就抓取內存dump文件(Debug.dumpHprofData);之後通過HeapAnalyzerService.runAnalysis進行分析內存文件分析;接着通過HeapAnalyzer (checkForLeak—findLeakingReference---findLeakTrace)來進行內存泄漏分析。最後通過DisplayLeakService進行內存泄漏的展示。

(3)Android Lint 工具:

Android Lint Tool 是Android Sutido種集成的一個Android代碼提示工具,它可以給你佈局、代碼提供非常強大的幫助。硬編碼會提示以級別警告,例如:在佈局文件中寫了三層冗餘的LinearLayout佈局、直接在TextView中寫要顯示的文字、字體大小使用dp而不是sp爲單位,就會在編輯器右邊看到提示。

(二)流暢——卡頓優化

卡頓的場景通常是發生在用戶交互體驗最直接的方面。影響卡頓的兩大因素,分別是界面繪製和數據處理。

界面繪製:主要原因是繪製的層級深、頁面複雜、刷新不合理,由於這些原因導致卡頓的場景更多出現在 UI 和啓動後的初始界面以及跳轉到頁面的繪製上。

數據處理:導致這種卡頓場景的原因是數據處理量太大,一般分爲三種情況,一是數據在處理 UI 線程,二是數據處理佔用 CPU 高,導致主線程拿不到時間片,三是內存增加導致 GC 頻繁,從而引起卡頓。

(1)佈局優化

在Android種系統對View進行測量、佈局和繪製時,都是通過對View數的遍歷來進行操作的。如果一個View數的高度太高就會嚴重影響測量、佈局和繪製的速度。Google也在其API文檔中建議View高度不宜哦過10層。現在版本種Google使用RelativeLayout替代LineraLayout作爲默認根佈局,目的就是降低LineraLayout嵌套產生布局樹的高度,從而提高UI渲染的效率。

佈局複用,使用標籤重用layout; 提高顯示速度,使用延遲View加載; 減少層級,使用標籤替換父級佈局; 注意使用wrap_content,會增加measure計算成本; 刪除控件中無用屬性;

(2)繪製優化

過度繪製是指在屏幕上的某個像素在同一幀的時間內被繪製了多次。在多層次重疊的 UI 結構中,如果不可見的 UI 也在做繪製的操作,就會導致某些像素區域被繪製了多次,從而浪費了多餘的 CPU 以及 GPU 資源。如何避免過度繪製?

佈局上的優化。移除 XML 中非必須的背景,移除 Window 默認的背景、按需顯示佔位背景圖片

自定義View優化。使用 canvas.clipRect() 幫助系統識別那些可見的區域,只有在這個區域內纔會被繪製。

(3)啓動優化

應用一般都有閃屏頁SplashActivity,優化閃屏頁的 UI 佈局,可以通過 Profile GPU Rendering 檢測丟幀情況。

(三)節省——耗電優化

在 Android5.0 以前,關於應用電量消耗的測試即麻煩又不準確,而5.0 之後Google專門引入了一個獲取設備上電量消耗信息的API—— Battery Historian。Battery Historian 是一款由 Google 提供的 Android 系統電量分析工具,直觀地展示出手機的電量消耗過程,通過輸入電量分析文件,顯示消耗情況。

最後提供一些可供參考耗電優化的方法:

(1)計算優化。算法、for循環優化、Switch..case替代if..else、避開浮點運算。

浮點運算:計算機裏整數和小數形式就是按普通格式進行存儲,例如1024、3.1415926等等,這個沒什麼特點,但是這樣的數精度不高,表達也不夠全面,爲了能夠有一種數的通用表示法,就發明了浮點數。浮點數的表示形式有點像科學計數法(.×10),它的表示形式是0.×10,在計算機中的形式爲 . e ±*),其中前面的星號代表定點小數,也就是整數部分爲0的純小數,後面的指數部分是定點整數。利用這樣的形式就能表示出任意一個整數和小數,例如1024就能表示成0.1024×10^4,也就是 .1024e+004,3.1415926就能表示成0.31415926×10^1,也就是 .31415926e+001,這就是浮點數。浮點數進行的運算就是浮點運算。浮點運算比常規運算更復雜,因此計算機進行浮點運算速度要比進行常規運算慢得多。

(2)避免 Wake Lock 使用不當。

Wake Lock是一種鎖的機制,主要是相對系統的休眠而言的,,只要有人拿着這個鎖,系統就無法進入休眠意思就是我的程序給CPU加了這個鎖那系統就不會休眠了,這樣做的目的是爲了全力配合我們程序的運行。有的情況如果不這麼做就會出現一些問題,比如微信等及時通訊的心跳包會在熄屏不久後停止網絡訪問等問題。所以微信裏面是有大量使用到了Wake_Lock鎖。系統爲了節省電量,CPU在沒有任務忙的時候就會自動進入休眠。有任務需要喚醒CPU高效執行的時候,就會給CPU加Wake_Lock鎖。大家經常犯的錯誤,我們很容易去喚醒CPU來工作,但是很容易忘記釋放Wake_Lock。

(3)使用 Job Scheduler 管理後臺任務。

在Android 5.0 API 21 中,google提供了一個叫做JobScheduler API的組件,來處理當某個時間點或者當滿足某個特定的條件時執行一個任務的場景,例如當用戶在夜間休息時或設備接通電源適配器連接WiFi啓動下載更新的任務。這樣可以在減少資源消耗的同時提升應用的效率。

(四)安裝包——APK瘦身

(1)安裝包的組成結構

assets文件夾。存放一些配置文件、資源文件,assets不會自動生成對應的 ID,而是通過 AssetManager 類的接口獲取。

res。res 是 resource 的縮寫,這個目錄存放資源文件,會自動生成對應的 ID 並映射到 .R 文件中,訪問直接使用資源 ID。

META-INF。保存應用的簽名信息,簽名信息可以驗證 APK 文件的完整性。

AndroidManifest.xml。這個文件用來描述 Android 應用的配置信息,一些組件的註冊信息、可使用權限等。

classes.dex。Dalvik 字節碼程序,讓 Dalvik 虛擬機可執行,一般情況下,Android 應用在打包時通過 Android SDK 中的 dx 工具將 Java 字節碼轉換爲 Dalvik 字節碼。

resources.arsc。記錄着資源文件和資源 ID 之間的映射關係,用來根據資源 ID 尋找資源。

(2)減少安裝包大小

代碼混淆。使用IDE 自帶的 proGuard 代碼混淆器工具 ,它包括壓縮、優化、混淆等功能。 資源優化。比如使用 Android Lint 刪除冗餘資源,資源文件最少化等。 圖片優化。比如利用 PNG優化工具 對圖片做壓縮處理。推薦目前最先進的壓縮工具Googlek開源庫zopfli。如果應用在0版本以上,推薦使用 WebP圖片格式。 避免重複或無用功能的第三方庫。例如,百度地圖接入基礎地圖即可、訊飛語音無需接入離線、圖片庫GlidePicasso等。 插件化開發。比如功能模塊放在服務器上,按需下載,可以減少安裝包大小。 可以使用微信開源資源文件混淆工具——AndResGuard。一般可以壓縮apk的1M左右大。

冷啓動與熱啓動

冷啓動在啓動應用時,系統中沒有該應用的進程,這時系統會創建一個新的進程分配給該應用;

熱啓動在啓動應用時,系統中已有該應用的進程(例:按back鍵、home鍵,應用雖然會退出,但是該應用的進程還是保留在後臺);

區別冷啓動:系統沒有該應用的進程,需要創建一個新的進程分配給應用,所以會先創建和初始化Application類,再創建和初始化MainActivity類(包括一系列的測量、佈局、繪製),最後顯示在界面上。 熱啓動: 從已有的進程中來啓動,不會創建和初始化Application類,直接創建和初始化MainActivity類(包括一系列的測量、佈局、繪製),最後顯示在界面上。

冷啓動流程Zygote進程中fork創建出一個新的進程; 創建和初始化Application類、創建MainActivity; inflate佈局、當onCreate/onStart/onResume方法都走完; contentView的measure/layout/draw顯示在界面上。

冷啓動優化 減少在Application和第一個Activity的onCreate()方法的工作量; 不要讓Application參與業務的操作; 不要在Application進行耗時操作; 不要以靜態變量的方式在Application中保存數據; 減少佈局的複雜性和深度;

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