Android工程師之Android面試大綱
正處于秋招時(shí)期,在此,作者要求我?guī)兔で笠环莼ヂ?lián)網(wǎng)公司2018年校招的安卓開(kāi)發(fā)崗位,希望和志同道合的同志一起奮發(fā)向上,有朋友有職位推薦可留下聯(lián)系方式,或者直接聯(lián)系作者,謝謝。
微信:510402535
郵箱:xyj510402535@qq.com
文章目錄如下:
Activity面試題
Fragment面試題
Service面試題
Broadcast Receiver面試題
WebView面試題
Binder面試題
Handler面試題
AsyncTask面試題
HandlerThread面試題
IntentService面試題
視圖工作機(jī)制面試題
事件分發(fā)機(jī)制面試題
ListView面試題
Android項(xiàng)目構(gòu)建面試題
ANR面試題
OOM面試題
Bitmap面試題
UI卡頓面試題
內(nèi)存泄漏面試題
內(nèi)存管理面試題
冷啟動(dòng)和熱啟動(dòng)面試題
其他優(yōu)化面試題
架構(gòu)模式面試題
插件化面試題
熱更新面試題
進(jìn)程?;蠲嬖囶}
Lint面試題
Kotlin面試題
1Activity面試題
1、Activity是什么
Activity是四大組件之一,它提供一個(gè)界面讓用戶點(diǎn)擊和各種滑動(dòng)操作,這就是Activity
2、Activity四種狀態(tài)
runing
paused
stopped
killed
3、Activity生命周期
onCreate()
onStart()
onResume()
onPause()
onStop()
onDestroy()
onRestart()
4、進(jìn)程的優(yōu)先級(jí)
空進(jìn)程
后臺(tái)進(jìn)程
服務(wù)進(jìn)程
可見(jiàn)進(jìn)程
前臺(tái)進(jìn)程
5、Activity任務(wù)棧
先進(jìn)后出
6、Activity啟動(dòng)模式
standard
singletop
singletask
singleinstance
7、scheme跳轉(zhuǎn)協(xié)議
Android中的scheme是一種頁(yè)面內(nèi)跳轉(zhuǎn)協(xié)議,通過(guò)定義自己的scheme協(xié)議,可以跳轉(zhuǎn)到app中的各個(gè)頁(yè)面
服務(wù)器可以定制化告訴app跳轉(zhuǎn)哪個(gè)頁(yè)面
App可以通過(guò)跳轉(zhuǎn)到另一個(gè)App頁(yè)面
可以通過(guò)H5頁(yè)面跳轉(zhuǎn)頁(yè)面
2Fragment面試題
1、Fragment為什么被稱(chēng)為第五大組件
Fragment比Activity更節(jié)省內(nèi)存,其切換模式也更加舒適,使用頻率不低于四大組件,且有自己的生命周期,而且必須依附于Activity
2、Activity創(chuàng)建Fragment的方式
靜態(tài)創(chuàng)建
動(dòng)態(tài)創(chuàng)建
3、FragmentPageAdapter和FragmentPageStateAdapter的區(qū)別
FragmentPageAdapter在每次切換頁(yè)面的的時(shí)候,是將Fragment進(jìn)行分離,適合頁(yè)面較少的Fragment使用以保存一些內(nèi)存,對(duì)系統(tǒng)內(nèi)存不會(huì)多大影響
FragmentPageStateAdapter在每次切換頁(yè)面的時(shí)候,是將Fragment進(jìn)行回收,適合頁(yè)面較多的Fragment使用,這樣就不會(huì)消耗更多的內(nèi)存
4、Fragment生命周期
onAttach()
onCreate()
onCreateView()
onActivityCreated()
onStart()
onResume()
onPause()
onStop()
onDestroyView()
onDestroy()
onDetach()
5、Fragment的通信
Fragment調(diào)用Activity中的方法:getActivity
Activity調(diào)用Fragment中的方法:接口回調(diào)
Fragment調(diào)用Fragment中的方法:FragmentManager.findFragmentById
6、Fragment的replace、add、remove方法
replace:替代Fragment的棧頂頁(yè)面
add:添加Fragment到棧頂頁(yè)面
remove:移除Fragment棧頂頁(yè)面
3Service面試題
1、Service是什么
Service是四大組件之一,它可以在后臺(tái)執(zhí)行長(zhǎng)時(shí)間運(yùn)行操作而沒(méi)有用戶界面的應(yīng)用組件
2、Service和Thread的區(qū)別
Service是安卓中系統(tǒng)的組件,它運(yùn)行在獨(dú)立進(jìn)程的主線程中,不可以執(zhí)行耗時(shí)操作。Thread是程序執(zhí)行的最小單元,分配CPU的基本單位,可以開(kāi)啟子線程執(zhí)行耗時(shí)操作
Service在不同Activity中可以獲取自身實(shí)例,可以方便的對(duì)Service進(jìn)行操作。Thread在不同的Activity中難以獲取自身實(shí)例,如果Activity被銷(xiāo)毀,Thread實(shí)例就很難再獲取得到
3、Service啟動(dòng)方式
startService
bindService
4、Service生命周期
startService
onCreate()
onStartCommand()
onDestroy()
bindService
onCreate()
onBind()
onUnbind()
onDestroy()
4Broadcast Receiver面試題
1、Broadcast Receiver是什么
Broadcast是四大組件之一,是一種廣泛運(yùn)用在應(yīng)用程序之間傳輸信息的機(jī)制,通過(guò)發(fā)送Intent來(lái)傳送我們的數(shù)據(jù)
2、Broadcast Receiver的使用場(chǎng)景
同一App具有多個(gè)進(jìn)程的不同組件之間的消息通信
不同App之間的組件之間的消息通信
3、Broadcast Receiver的種類(lèi)
普通廣播
有序廣播
本地廣播
Sticky廣播
4、Broadcast Receiver的實(shí)現(xiàn)
靜態(tài)注冊(cè):注冊(cè)后一直運(yùn)行,盡管Activity、進(jìn)程、App被殺死還是可以接收到廣播
動(dòng)態(tài)注冊(cè):跟隨Activity的生命周期
5、Broadcast Receiver實(shí)現(xiàn)機(jī)制
自定義廣播類(lèi)繼承BroadcastReceiver,復(fù)寫(xiě)onReceiver()
通過(guò)Binder機(jī)制向AMS進(jìn)行注冊(cè)廣播
廣播發(fā)送者通過(guò)Binder機(jī)制向AMS發(fā)送廣播
AMS查找符合相應(yīng)條件的廣播發(fā)送到BroadcastReceiver相應(yīng)的循環(huán)隊(duì)列中
消息隊(duì)列執(zhí)行拿到廣播,回調(diào)BroadcastReceiver的onReceiver()
6、LocalBroadcastManager特點(diǎn)
本地廣播只能在自身App內(nèi)傳播,不必?fù)?dān)心泄漏隱私數(shù)據(jù)
本地廣播不允許其他App對(duì)你的App發(fā)送該廣播,不必?fù)?dān)心安全漏洞被利用
本地廣播比全局廣播更高效
以上三點(diǎn)都是源于其內(nèi)部是用Handler實(shí)現(xiàn)的
5WebView面試題
1、WebView安全漏洞
API16之前存在遠(yuǎn)程代碼執(zhí)行安全漏洞,該漏洞源于程序沒(méi)有正確限制使用WebView.addJavascriptInterface方法,遠(yuǎn)程攻擊者可通過(guò)使用Java反射機(jī)制利用該漏洞執(zhí)行任意Java對(duì)象的方法
2、WebView銷(xiāo)毀步驟
WebView在其他容器上時(shí)(如:LinearLayout),當(dāng)銷(xiāo)毀Activity時(shí),需要在onDestroy()中先移除容器上的WebView,然后再將WebView.destroy(),這樣就不會(huì)導(dǎo)致內(nèi)存泄漏
3、WebView的jsbridge
客戶端和服務(wù)端之間可以通過(guò)Javascript來(lái)互相調(diào)用各自的方法
4、WebViewClient的onPageFinished
WebViewClient的onPageFinished在每次完成頁(yè)面的時(shí)候調(diào)用,但是遇到未加載完成的頁(yè)面跳轉(zhuǎn)其他頁(yè)面時(shí),就會(huì)一直調(diào)用,使用WebChromeClient.onProgressChanged可以替代
5、WebView后臺(tái)耗電
在WebView加載頁(yè)面的時(shí)候,會(huì)自動(dòng)開(kāi)啟線程去加載,如果不很好的關(guān)閉這些線程,就會(huì)導(dǎo)致電量消耗加大,可以采用暴力的方法,直接在onDestroy方法中System.exit(0)結(jié)束當(dāng)前正在運(yùn)行中的java虛擬機(jī)
6、WebView硬件加速
Android3.0引入硬件加速,默認(rèn)會(huì)開(kāi)啟,WebView在硬件加速的情況下滑動(dòng)更加平滑,性能更加好,但是會(huì)出現(xiàn)白塊或者頁(yè)面閃爍的副作用,建議WebView暫時(shí)關(guān)閉硬件加速
7、WebView內(nèi)存泄漏
由于WebView是依附于Activity的,Activity的生命周期和WebView啟動(dòng)的線程的生命周期是不一致的,這會(huì)導(dǎo)致WebView一直持有對(duì)這個(gè)Activity的引用而無(wú)法釋放,解決方案如下
獨(dú)立進(jìn)程,簡(jiǎn)單暴力,不過(guò)可能涉及到進(jìn)程間通信(推薦)
動(dòng)態(tài)添加WebView,對(duì)傳入WebView中使用的Context使用弱引用
6Binder面試題
1、Linux內(nèi)核的基本知識(shí)
進(jìn)程隔離/虛擬地址空間:進(jìn)程間是不可以共享數(shù)據(jù)的,相當(dāng)于被隔離,每個(gè)進(jìn)程被分配到不同的虛擬地址中
系統(tǒng)調(diào)用:Linux內(nèi)核對(duì)應(yīng)用有訪問(wèn)權(quán)限,用戶只能在應(yīng)用層通過(guò)系統(tǒng)調(diào)用,調(diào)用內(nèi)核的某些程序
binder驅(qū)動(dòng):它負(fù)責(zé)各個(gè)用戶的進(jìn)程,通過(guò)binder通信內(nèi)核來(lái)進(jìn)行交互的模塊
2、為什么使用Binder
性能上,相比傳統(tǒng)的Socket更加高效
安全性高,支持協(xié)議雙方互相校驗(yàn)
3、Binder通信模型

Service服務(wù)端通過(guò)Binder驅(qū)動(dòng)在ServiceManager的查找表中注冊(cè)O(shè)bject對(duì)象的add方法
Client客戶端通過(guò)Binder驅(qū)動(dòng)在ServiceManager的查找表中找到Object對(duì)象的add方法,并返回proxy的add方法,add方法是個(gè)空實(shí)現(xiàn),proxy也不是真正的Object對(duì)象,是通過(guò)Binder驅(qū)動(dòng)封裝好的代理類(lèi)的add方法
當(dāng)Client客戶端調(diào)用add方法時(shí),Client客戶端通過(guò)Binder驅(qū)動(dòng)將proxy的add方法,請(qǐng)求ServiceManager來(lái)找到Service服務(wù)端真正對(duì)象的add方法,進(jìn)行調(diào)用
4、AIDL
客戶端通過(guò)aidl文件的Stub.asInterface()方法,拿到Proxy代理類(lèi)
通過(guò)調(diào)用Proxy代理類(lèi)的方法,將參數(shù)進(jìn)行封包后,調(diào)用底層的transact()方法
transact()方法會(huì)回調(diào)onTransact()方法,進(jìn)行參數(shù)的解封
在onTransact()方法中調(diào)用服務(wù)端對(duì)應(yīng)的方法,并將結(jié)果返回
7Handler面試題
1、Handler是什么
Handler通過(guò)發(fā)送和處理Message和Runnable對(duì)象來(lái)關(guān)聯(lián)相對(duì)應(yīng)線程的MessageQueue
2、Handler使用方法
post(runnable)
sendMessage(message)
3、Handler工作原理
Android進(jìn)階——Android消息機(jī)制之Looper、Handler、MessageQueen
http://blog.csdn.net/qq_30379689/article/details/53394061
4、Handler引起的內(nèi)存泄漏
原因:非靜態(tài)內(nèi)部類(lèi)持有外部類(lèi)的匿名引用,導(dǎo)致Activity無(wú)法釋放
解決:?
Handler內(nèi)部持有外部Activity的弱引用
Handler改為靜態(tài)內(nèi)部類(lèi)
Handler.removeCallback()
8AsyncTask面試題
1、AsyncTask是什么
它本質(zhì)上就是一個(gè)封裝了線程池和Handler的異步框架
2、AsyncTask使用方法
三個(gè)參數(shù)
Params:表示后臺(tái)任務(wù)執(zhí)行時(shí)的參數(shù)類(lèi)型,該參數(shù)會(huì)傳給AysncTask的doInBackground()方法
Progress:表示后臺(tái)任務(wù)的執(zhí)行進(jìn)度的參數(shù)類(lèi)型,該參數(shù)會(huì)作為onProgressUpdate()方法的參數(shù)
Result:表示后臺(tái)任務(wù)的返回結(jié)果的參數(shù)類(lèi)型,該參數(shù)會(huì)作為onPostExecute()方法的參數(shù)
五個(gè)方法
onPreExecute():異步任務(wù)開(kāi)啟之前回調(diào),在主線程中執(zhí)行
doInBackground():執(zhí)行異步任務(wù),在線程池中執(zhí)行
onProgressUpdate():當(dāng)doInBackground中調(diào)用publishProgress時(shí)回調(diào),在主線程中執(zhí)行
onPostExecute():在異步任務(wù)執(zhí)行之后回調(diào),在主線程中執(zhí)行
onCancelled():在異步任務(wù)被取消時(shí)回調(diào)
3、AsyncTask工作原理
Android進(jìn)階——多線程系列之異步任務(wù)AsyncTask的使用與源碼分析
http://blog.csdn.net/qq_30379689/article/details/53203556
4、AsyncTask引起的內(nèi)存泄漏
原因:非靜態(tài)內(nèi)部類(lèi)持有外部類(lèi)的匿名引用,導(dǎo)致Activity無(wú)法釋放
解決:?
AsyncTask內(nèi)部持有外部Activity的弱引用
AsyncTask改為靜態(tài)內(nèi)部類(lèi)
AsyncTask.cancel()
5、AsyncTask生命周期
在Activity銷(xiāo)毀之前,取消AsyncTask的運(yùn)行,以此來(lái)保證程序的穩(wěn)定
6、AsyncTask結(jié)果丟失
由于屏幕旋轉(zhuǎn)、Activity在內(nèi)存緊張時(shí)被回收等情況下,Activity會(huì)被重新創(chuàng)建,此時(shí),舊的AsyncTask持有舊的Activity引用,這個(gè)時(shí)候會(huì)導(dǎo)致AsyncTask的onPostExecute()對(duì)UI更新無(wú)效
7、AsyncTask并行or串行
AsyncTask在Android 2.3之前默認(rèn)采用并行執(zhí)行任務(wù),AsyncTask在Android 2.3之后默認(rèn)采用串行執(zhí)行任務(wù)
如果需要在Android 2.3之后采用并行執(zhí)行任務(wù),可以調(diào)用AsyncTask的executeOnExecutor()
9HandlerThread面試題
1、HandlerThread產(chǎn)生背景
當(dāng)系統(tǒng)有多個(gè)耗時(shí)任務(wù)需要執(zhí)行時(shí),每個(gè)任務(wù)都會(huì)開(kāi)啟一個(gè)新線程去執(zhí)行耗時(shí)任務(wù),這樣會(huì)導(dǎo)致系統(tǒng)多次創(chuàng)建和銷(xiāo)毀線程,從而影響性能。為了解決這一問(wèn)題,Google提供了HandlerThread,HandlerThread是在線程中創(chuàng)建一個(gè)Looper循環(huán)器,讓Looper輪詢消息隊(duì)列,當(dāng)有耗時(shí)任務(wù)進(jìn)入隊(duì)列時(shí),則不需要開(kāi)啟新線程,在原有的線程中執(zhí)行耗時(shí)任務(wù)即可,否則線程阻塞
2、HanlderThread的特點(diǎn)、
HandlerThread本質(zhì)上是一個(gè)線程,繼承自Thread
HandlerThread有自己的Looper對(duì)象,可以進(jìn)行Looper循環(huán),可以創(chuàng)建Handler
HandlerThread可以在Handler的handlerMessage中執(zhí)行異步方法
HandlerThread優(yōu)點(diǎn)是異步不會(huì)堵塞,減少對(duì)性能的消耗
HandlerThread缺點(diǎn)是不能同時(shí)繼續(xù)進(jìn)行多任務(wù)處理,需要等待進(jìn)行處理,處理效率較低
HandlerThread與線程池不同,HandlerThread是一個(gè)串行隊(duì)列,背后只有一個(gè)線程。
10?IntentService面試題
1、IntentService是什么
IntentService是繼承自Service并處理異步請(qǐng)求的一個(gè)類(lèi),其內(nèi)部采用HandlerThread和Handler實(shí)現(xiàn)的,在IntentService內(nèi)有一個(gè)工作線程來(lái)處理耗時(shí)操作,其優(yōu)先級(jí)比普通Service高。當(dāng)任務(wù)完成后,IntentService會(huì)自動(dòng)停止,而不需要手動(dòng)調(diào)用stopSelf()。另外,可以多次啟動(dòng)IntentService,每個(gè)耗時(shí)操作都會(huì)以工作隊(duì)列的方式在IntentService中onHandlerIntent()回調(diào)方法中執(zhí)行,并且每次只會(huì)執(zhí)行一個(gè)工作線程
2、IntentService使用方法
創(chuàng)建Service繼承自IntentService
覆寫(xiě)構(gòu)造方法和onHandlerIntent()方法
在onHandlerIntent()中執(zhí)行耗時(shí)操作
11視圖工作機(jī)制面試題
Android進(jìn)階——Android視圖工作機(jī)制之measure、layout、draw
http://blog.csdn.net/qq_30379689/article/details/54588736
Android事件分發(fā)機(jī)制之dispatchTouchEvent、onInterceptTouchEvent、onTouchEvent
http://blog.csdn.net/qq_30379689/article/details/53967177
12ListView面試題
1、ListView是什么
ListView是能將一個(gè)數(shù)據(jù)集合以動(dòng)態(tài)滾動(dòng)的方式展示到用戶界面上的View
2、ListView的RecycleBin機(jī)制

3、ListView的優(yōu)化
重用convertView
使用ViewHolder
圖片三級(jí)緩存
監(jiān)聽(tīng)滑動(dòng)事件
少用透明View
開(kāi)啟硬件加速
13Android項(xiàng)目構(gòu)建面試題
1、android構(gòu)建流程

2、jenkins持續(xù)集成構(gòu)建
這里可參考蒲公英文檔
http://www.pgyer.com/doc/view/jenkins
3、Git常用命令
git init:倉(cāng)庫(kù)的初始化
git status:查看當(dāng)前倉(cāng)庫(kù)的狀態(tài)
git diff:查看倉(cāng)庫(kù)與上次修改的內(nèi)容
git add:將文件放進(jìn)暫存區(qū)
git commit:提交代碼
git clone:克隆代碼
git bransh:查看當(dāng)前分支
git checkout:切換當(dāng)前分支
4、git工作流
fork/clone(主流)?
fork:將別人的倉(cāng)庫(kù)代碼fork到自己的倉(cāng)庫(kù)上
clone:克隆下自己倉(cāng)庫(kù)的代碼
update、commit:修改代碼并提交到自己的倉(cāng)庫(kù)
push:提交到自己的倉(cāng)庫(kù)
pull request:請(qǐng)求添加到別人的倉(cāng)庫(kù)
clone
5、proguard是什么
ProGuard工具是用于壓縮、優(yōu)化和混淆我們的代碼,其主作用是移除或混淆代碼中無(wú)用類(lèi)、字段、方法和屬性
6、proguard技術(shù)功能
壓縮
優(yōu)化
混淆
預(yù)檢測(cè)
7、proguard工作原理
將無(wú)用的字段或方法存入到EntryPoint中,將非EntryPoint的字段和方法進(jìn)行替換
8、為什么要混淆
由于Java是一門(mén)跨平臺(tái)的解釋性語(yǔ)言,其源代碼被編譯成class字節(jié)碼來(lái)適應(yīng)其他平臺(tái),而class文件包含了Java源代碼信息,很容易被反編譯
14ANR面試題
1、什么是ANR
Application Not Responding,頁(yè)面無(wú)響應(yīng)的對(duì)話框
2、發(fā)生ANR的條件
應(yīng)用程序的響應(yīng)性是由ActivityManager和WindowManager系統(tǒng)服務(wù)監(jiān)視的,當(dāng)ANR發(fā)生條件滿足時(shí),就會(huì)彈出ANR的對(duì)話框
Activity超過(guò)5秒無(wú)響應(yīng)
BroadcastReceiver超過(guò)10秒無(wú)響應(yīng)
Service超過(guò)20秒無(wú)響應(yīng)
3、造成ANR的主要原因
主線程被IO操作阻塞
Activity的所有生命周期回調(diào)都是執(zhí)行在主線程的
Service默認(rèn)執(zhí)行在主線程中
BoardcastReceiver的回調(diào)onReceive()執(zhí)行在主線程中
AsyncTask的回調(diào)除了doInBackground,其他都是在主線程中
沒(méi)有使用子線程Looper的Handler的handlerMessage,post(Runnable)都是執(zhí)行在主線程中
4、如何解決ANR
使用AsyncTask處理耗時(shí)IO操作
使用Thread或HandlerThread提供優(yōu)先級(jí)
使用Handler處理工作線程的耗時(shí)操作
Activity的onCreate和onResume回調(diào)盡量避免耗時(shí)操作
15OOM面試題
1、什么是OOM
OOM指Out of memory(內(nèi)存溢出),當(dāng)前占用內(nèi)存加上我們申請(qǐng)的內(nèi)存資源超過(guò)了Dalvik虛擬機(jī)的最大內(nèi)存限制就會(huì)拋出Out of memory異常
2、OOM相關(guān)概念
內(nèi)存溢出:指程序在申請(qǐng)內(nèi)存時(shí),沒(méi)有足夠的空間供其使用
內(nèi)存泄漏:指程序分配出去的內(nèi)存不再使用,無(wú)法進(jìn)行回收
內(nèi)存抖動(dòng):指程序短時(shí)間內(nèi)大量創(chuàng)建對(duì)象,然后回收的現(xiàn)象
3、解決OOM
Bitmap相關(guān)
圖片壓縮
加載縮略圖
在滾動(dòng)時(shí)不加載圖片
回收Bitmap
使用inBitmap屬性
捕獲異常
其他相關(guān)
listview重用convertView、使用lru
避免onDraw方法執(zhí)行對(duì)象的創(chuàng)建
謹(jǐn)慎使用多進(jìn)程
16Bitmap面試題
1、recycle
在安卓3.0以前Bitmap是存放在堆中的,我們只要回收堆內(nèi)存即可
在安卓3.0以后Bitmap是存放在內(nèi)存中的,我們需要回收native層和Java層的內(nèi)存
官方建議我們3.0以后使用recycle方法進(jìn)行回收,該方法也可以不主動(dòng)調(diào)用,因?yàn)槔厥掌鲿?huì)自動(dòng)收集不可用的Bitmap對(duì)象進(jìn)行回收
recycle方法會(huì)判斷Bitmap在不可用的情況下,將發(fā)送指令到垃圾回收器,讓其回收native層和Java層的內(nèi)存,則Bitmap進(jìn)入dead狀態(tài)
recycle方法是不可逆的,如果再次調(diào)用getPixels()等方法,則獲取不到想要的結(jié)果
2、LruCache原理
LruCache是個(gè)泛型類(lèi),內(nèi)部采用LinkedHashMap來(lái)實(shí)現(xiàn)緩存機(jī)制,它提供get方法和put方法來(lái)獲取緩存和添加緩存,其最重要的方法trimToSize是用來(lái)移除最少使用的緩存和使用最久的緩存,并添加最新的緩存到隊(duì)列中
3、計(jì)算inSampleSize

4、縮略圖

5、保存Bitmap

6、保存到SD卡

7、三級(jí)緩存
網(wǎng)絡(luò)緩存
本地緩存
內(nèi)存緩存
17UI卡頓面試題
1、UI卡頓原理
View的繪制幀數(shù)保持60fps是最佳,這要求每幀的繪制時(shí)間不超過(guò)16ms(1000/60),如果安卓不能在16ms內(nèi)完成界面的渲染,那么就會(huì)出現(xiàn)卡頓現(xiàn)象
2、UI卡頓的原因分析
在UI線程中做輕微的耗時(shí)操作,導(dǎo)致UI線程卡頓
布局Layout過(guò)于復(fù)雜,無(wú)法在16ms內(nèi)完成渲染
同一時(shí)間動(dòng)畫(huà)執(zhí)行的次數(shù)過(guò)多,導(dǎo)致CPU和GPU負(fù)載過(guò)重
overDraw,導(dǎo)致像素在同一幀的時(shí)間內(nèi)被繪制多次,使CPU和GPU負(fù)載過(guò)重
View頻繁的觸發(fā)measure、layout,導(dǎo)致measure、layout累計(jì)耗時(shí)過(guò)多和整個(gè)View頻繁的重新渲染
頻繁的觸發(fā)GC操作導(dǎo)致線程暫停,會(huì)使得安卓系統(tǒng)在16ms內(nèi)無(wú)法完成繪制
冗余資源及邏輯等導(dǎo)致加載和執(zhí)行緩慢
ANR
3、UI卡頓的優(yōu)化
布局優(yōu)化?
使用include、ViewStub、merge
不要出現(xiàn)過(guò)于嵌套和冗余的布局
使用自定義View取代復(fù)雜的View
ListView優(yōu)化?
復(fù)用convertView
滑動(dòng)不加載
背景和圖片優(yōu)化?
縮略圖
圖片壓縮
避免ANR?
不要在UI線程中做耗時(shí)操作
18內(nèi)存泄漏面試題
1、Java內(nèi)存泄漏引起的主要原因
長(zhǎng)生命周期的對(duì)象持有短生命周期對(duì)象的引用就很可能發(fā)生內(nèi)存泄漏
2、Java內(nèi)存分配策略
靜態(tài)存儲(chǔ)區(qū):又稱(chēng)方法區(qū),主要存儲(chǔ)全局變量和靜態(tài)變量,在整個(gè)程序運(yùn)行期間都存在
棧區(qū):方法體的局部變量會(huì)在棧區(qū)創(chuàng)建空間,并在方法執(zhí)行結(jié)束后會(huì)自動(dòng)釋放變量的空間和內(nèi)存
堆區(qū):保存動(dòng)態(tài)產(chǎn)生的數(shù)據(jù),如:new出來(lái)的對(duì)象和數(shù)組,在不使用的時(shí)候由Java回收器自動(dòng)回收
3、Android解決內(nèi)存泄漏的例子
單例造成的內(nèi)存泄漏:在單例中,使用context.getApplicationContext()作為單例的context
匿名內(nèi)部類(lèi)造成的內(nèi)存泄漏:由于非靜態(tài)內(nèi)部類(lèi)持有匿名外部類(lèi)的引用,必須將內(nèi)部類(lèi)設(shè)置為static
Handler造成的內(nèi)存泄漏:使用static的Handler內(nèi)部類(lèi),同時(shí)在實(shí)現(xiàn)內(nèi)部類(lèi)中持有Context的弱引用
避免使用static變量:由于static變量會(huì)跟Activity生命周期一致,當(dāng)Activity退出后臺(tái)被后臺(tái)回收時(shí),static變量是不安全,所以也要管理好static變量的生命周期
資源未關(guān)閉造成的內(nèi)存泄漏:比如Socket、Broadcast、Cursor、Bitmap、ListView等,使用完后要關(guān)閉
AsyncTask造成的內(nèi)存泄漏:由于非靜態(tài)內(nèi)部類(lèi)持有匿名內(nèi)部類(lèi)的引用而造成內(nèi)存泄漏,可以通過(guò)AsyncTask內(nèi)部持有外部Activity的弱引用同時(shí)改為靜態(tài)內(nèi)部類(lèi)或在onDestroy()中執(zhí)行AsyncTask.cancel()進(jìn)行修復(fù)
19內(nèi)存管理面試題
1、Android內(nèi)存管理機(jī)制
分配機(jī)制
管理機(jī)制
2、內(nèi)存管理機(jī)制的特點(diǎn)
更少的占用內(nèi)存
在合適的時(shí)候,合理的釋放系統(tǒng)資源
在系統(tǒng)內(nèi)存緊張的時(shí)候,能釋放掉大部分不重要的資源
能合理的在特殊生命周期中,保存或還原重要數(shù)據(jù)
3、內(nèi)存優(yōu)化方法
Service完成任務(wù)后應(yīng)停止它,或用IntentService(因?yàn)榭梢宰詣?dòng)停止服務(wù))代替Service
在UI不可見(jiàn)的時(shí)候,釋放其UI資源
在系統(tǒng)內(nèi)存緊張的時(shí)候,盡可能多的釋放非重要資源
避免濫用Bitmap導(dǎo)致內(nèi)存浪費(fèi)
避免使用依賴注入框架
使用針對(duì)內(nèi)存優(yōu)化過(guò)的數(shù)據(jù)容器
使用ZIP對(duì)齊的APK
使用多進(jìn)程
20冷啟動(dòng)和熱啟動(dòng)面試題
1、什么是冷啟動(dòng)和熱啟動(dòng)
冷啟動(dòng):在啟動(dòng)應(yīng)用前,系統(tǒng)中沒(méi)有該應(yīng)用的任何進(jìn)程信息
熱啟動(dòng):在啟動(dòng)應(yīng)用時(shí),在已有的進(jìn)程上啟動(dòng)應(yīng)用(用戶使用返回鍵退出應(yīng)用,然后馬上又重新啟動(dòng)應(yīng)用)
2、冷啟動(dòng)和熱啟動(dòng)的區(qū)別
冷啟動(dòng):創(chuàng)建Application后再創(chuàng)建和初始化MainActivity
熱啟動(dòng):創(chuàng)建和初始化MainActivity即可
3、冷啟動(dòng)時(shí)間的計(jì)算
這個(gè)時(shí)間值從應(yīng)用啟動(dòng)(創(chuàng)建進(jìn)程)開(kāi)始計(jì)算,到完成視圖的第一次繪制為止
4、冷啟動(dòng)流程
Zygote進(jìn)程中fork創(chuàng)建出一個(gè)新的進(jìn)程
創(chuàng)建和初始化Application類(lèi)、創(chuàng)建MainActivity
inflate布局、當(dāng)onCreate/onStart/onResume方法都走完
contentView的measure/layout/draw顯示在界面上
總結(jié):Application構(gòu)造方法->attachBaseContext()->onCreate()->Activity構(gòu)造方法->onCreate()->配置主題中背景等屬性->onStart()->onResume()->測(cè)量布局繪制顯示在界面上
5、冷啟動(dòng)優(yōu)化
減少第一個(gè)界面onCreate()方法的工作量
不要讓Application參與業(yè)務(wù)的操作
不要在Application進(jìn)行耗時(shí)操作
不要以靜態(tài)變量的方式在Application中保存數(shù)據(jù)
減少布局的復(fù)雜性和深度
不要在mainThread中加載資源
通過(guò)懶加載方式初始化第三方SDK
21其他優(yōu)化面試題
1、Android不用靜態(tài)變量存儲(chǔ)數(shù)據(jù)
靜態(tài)變量等數(shù)據(jù)由于進(jìn)程已經(jīng)被殺死而被初始化
使用其他數(shù)據(jù)傳輸方式:文件/sp/contentProvider
2、SharePreference安全問(wèn)題
不能跨進(jìn)程同步
文件不宜過(guò)大
3、內(nèi)存對(duì)象序列化
Serializeble:是java的序列化方式,Serializeble在序列化的時(shí)候會(huì)產(chǎn)生大量的臨時(shí)對(duì)象,從而引起頻繁的GC
Parcelable:是Android的序列化方式,且性能比Serializeble高,Parcelable不能使用在要將數(shù)據(jù)存儲(chǔ)在硬盤(pán)上的情況
4、避免在UI線程中做繁重的操作
22架構(gòu)模式面試題
Android基礎(chǔ)——框架模式MVC在安卓中的實(shí)踐
http://blog.csdn.net/qq_30379689/article/details/52909656
Android基礎(chǔ)——框架模式MVP在安卓中的實(shí)踐
http://blog.csdn.net/qq_30379689/article/details/52910567
Android基礎(chǔ)——框架模式MVVM之DataBinding的實(shí)踐
http://blog.csdn.net/qq_30379689/article/details/53037430
23插件化面試題
1、插件化解決的問(wèn)題
動(dòng)態(tài)加載APK(反射、類(lèi)加載器)
資源加載(反射、AssetManager、獨(dú)立資源、分段資源)
代碼加載(反射獲取生命周期)
2、類(lèi)加載器(Java中字節(jié)碼添加到虛擬機(jī)中)
DexClassLoader:能夠加載未安裝的jar/apk/dex,主要用于動(dòng)態(tài)加載和代碼熱更新
PathClassLoader:只能加載系統(tǒng)中已經(jīng)安裝過(guò)的apk
24熱更新面試題
1、熱更新主要流程
線上檢查到Crash
拉出Bugfix分支修復(fù)Crash問(wèn)題
jenkins構(gòu)建和補(bǔ)丁生成
app通過(guò)推送或主動(dòng)拉取補(bǔ)丁文件
將Bugfix代碼合到master上
2、熱更新主流框架
Dexposed
AndFix
Nuwa
Tinker
3、熱更新的原理
在ClassLoader創(chuàng)建一個(gè)dexElements數(shù)組
將修復(fù)好的dex文件存放在dexElements數(shù)組的最前面
ClassLoader會(huì)遍歷dexElements數(shù)組,找到最前面的dex文件優(yōu)先加載
25進(jìn)程保活面試題
1、進(jìn)程的優(yōu)先級(jí)
空進(jìn)程
后臺(tái)進(jìn)程
服務(wù)進(jìn)程
可見(jiàn)進(jìn)程
前臺(tái)進(jìn)程
2、Android進(jìn)程回收策略
Low memory Killer(定時(shí)執(zhí)行):通過(guò)一些比較復(fù)雜的評(píng)分機(jī)制,對(duì)進(jìn)程進(jìn)行打分,然后將分?jǐn)?shù)高的進(jìn)程判定為bad進(jìn)程,殺死并釋放內(nèi)存
OOM_ODJ:判別進(jìn)程的優(yōu)先級(jí)
3、Android保活方案
利用系統(tǒng)廣播拉活
利用系統(tǒng)Service機(jī)制拉活
利用Native進(jìn)程拉活
利用JobScheduler機(jī)制拉活
利用賬號(hào)同步機(jī)制拉活
26Lint面試題
1、什么是Android Lint
Android Lint是一個(gè)靜態(tài)代碼分析工具,它能夠?qū)δ愕腁ndroid項(xiàng)目中潛在的Bug、可優(yōu)化的代碼、安全性、性能、可用性、可訪問(wèn)性、國(guó)際化等進(jìn)行檢查
2、Lint工作流程

3、配置Lint
創(chuàng)建Lint.xml到根目錄下,自定義Lint安全等級(jí)等
在Java文件中可以使用@suppressLint(“NewApi”)來(lái)忽視Lint的報(bào)錯(cuò)
在xml文件中可以使用tool:ignore(“UnusedResources”)來(lái)忽視Lint的報(bào)錯(cuò)
自定義Lint檢查,可以創(chuàng)建類(lèi),繼承Detector和實(shí)現(xiàn)JavaPsiScanner
27Kotlin面試題
1、什么是Kotlin
Kotlin是一種基于JVM的編程語(yǔ)言
對(duì)Java的一種拓展,比Java更簡(jiǎn)潔
Kotlin支持函數(shù)式編程
Kotlin類(lèi)和Java類(lèi)可以相互調(diào)用
2、Kotlin環(huán)境搭建
直接在Plugin中下載Kotlin插件即可
系統(tǒng)會(huì)自動(dòng)配置到Kotlin環(huán)境