【Android面試有章可循】知識點總結(jié)

分享一篇Android知識點總結(jié)文章 面試復(fù)習——Android工程師之Android面試大綱

后續(xù)我會在這個的基礎(chǔ)上,對每個知識點展開來講,并補充一些個人覺得需要掌握的知識點,希望對大家準備 Android開發(fā)崗春招秋招以及形成較完整的 Android知識體系 有幫助。

Activity面試題
Fragment面試題
Service面試題
Broadcast Receiver面試題
WebView面試題
Binder面試題
Handler面試題
AsyncTask面試題
HandlerThread面試題
IntentService面試題
視圖工作機制面試題
事件分發(fā)機制面試題
ListView面試題
Android項目構(gòu)建面試題
ANR面試題
OOM面試題
Bitmap面試題
UI卡頓面試題
內(nèi)存泄漏面試題
內(nèi)存管理面試題
冷啟動和熱啟動面試題
其他優(yōu)化面試題
架構(gòu)模式面試題
插件化面試題
熱更新面試題
進程保活面試題
Lint面試題
Kotlin面試題

Activity面試題

1、Activity是什么

  • Activity是四大組件之一,它提供一個界面讓用戶點擊和各種滑動操作,這就是Activity

2、Activity四種狀態(tài)

  • runing
  • paused
  • stopped
  • killed

3、Activity生命周期

  • onCreate()
  • onStart()
  • onResume()
  • onPause()
  • onStop()
  • onDestroy()
  • onRestart()

4、進程的優(yōu)先級

  • 空進程
  • 后臺進程
  • 服務(wù)進程
  • 可見進程
  • 前臺進程

5、Activity任務(wù)棧

  • 先進后出

6、Activity啟動模式

  • standard
  • singletop
  • singletask
  • singleinstance

7、scheme跳轉(zhuǎn)協(xié)議
Android中的scheme是一種頁面內(nèi)跳轉(zhuǎn)協(xié)議,通過定義自己的scheme協(xié)議,可以跳轉(zhuǎn)到app中的各個頁面

  • 服務(wù)器可以定制化告訴app跳轉(zhuǎn)哪個頁面
  • App可以通過跳轉(zhuǎn)到另一個App頁面
  • 可以通過H5頁面跳轉(zhuǎn)頁面

Fragment面試題

1、Fragment為什么被稱為第五大組件
Fragment比Activity更節(jié)省內(nèi)存,其切換模式也更加舒適,使用頻率不低于四大組件,且有自己的生命周期,而且必須依附于Activity

2、Activity創(chuàng)建Fragment的方式

  • 靜態(tài)創(chuàng)建
  • 動態(tài)創(chuàng)建

3、FragmentPageAdapter和FragmentPageStateAdapter的區(qū)別

  • FragmentPageAdapter在每次切換頁面的的時候,是將Fragment進行分離,適合頁面較少的Fragment使用以保存一些內(nèi)存,對系統(tǒng)內(nèi)存不會多大影響
  • FragmentPageStateAdapter在每次切換頁面的時候,是將Fragment進行回收,適合頁面較多的Fragment使用,這樣就不會消耗更多的內(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的棧頂頁面
  • add:添加Fragment到棧頂頁面
  • remove:移除Fragment棧頂頁面

Service面試題

1、Service是什么

  • Service是四大組件之一,它可以在后臺執(zhí)行長時間運行操作而沒有用戶界面的應(yīng)用組件

2、Service和Thread的區(qū)別

  • Service是安卓中系統(tǒng)的組件,它運行在獨立進程的主線程中,不可以執(zhí)行耗時操作。Thread是程序執(zhí)行的最小單元,分配CPU的基本單位,可以開啟子線程執(zhí)行耗時操作
  • Service在不同Activity中可以獲取自身實例,可以方便的對Service進行操作。Thread在不同的Activity中難以獲取自身實例,如果Activity被銷毀,Thread實例就很難再獲取得到

3、Service啟動方式

  • startService
  • bindService

4、Service生命周期

  • startService

    • onCreate()
    • onStartCommand()
    • onDestroy()
  • bindService

    • onCreate()
    • onBind()
    • onUnbind()
    • onDestroy()

Broadcast Receiver面試題

1、Broadcast Receiver是什么

  • Broadcast是四大組件之一,是一種廣泛運用在應(yīng)用程序之間傳輸信息的機制,通過發(fā)送Intent來傳送我們的數(shù)據(jù)

2、Broadcast Receiver的使用場景

  • 同一App具有多個進程的不同組件之間的消息通信
  • 不同App之間的組件之間的消息通信

3、Broadcast Receiver的種類

  • 普通廣播
  • 有序廣播
  • 本地廣播
  • Sticky廣播

4、Broadcast Receiver的實現(xiàn)

  • 靜態(tài)注冊:注冊后一直運行,盡管Activity、進程、App被殺死還是可以接收到廣播
  • 動態(tài)注冊:跟隨Activity的生命周期

5、Broadcast Receiver實現(xiàn)機制

  • 自定義廣播類繼承BroadcastReceiver,復(fù)寫onReceiver()
  • 通過Binder機制向AMS進行注冊廣播
  • 廣播發(fā)送者通過Binder機制向AMS發(fā)送廣播
  • AMS查找符合相應(yīng)條件的廣播發(fā)送到BroadcastReceiver相應(yīng)的循環(huán)隊列中
  • 消息隊列執(zhí)行拿到廣播,回調(diào)BroadcastReceiver的onReceiver()

6、LocalBroadcastManager特點

  • 本地廣播只能在自身App內(nèi)傳播,不必擔心泄漏隱私數(shù)據(jù)
  • 本地廣播不允許其他App對你的App發(fā)送該廣播,不必擔心安全漏洞被利用
  • 本地廣播比全局廣播更高效
  • 以上三點都是源于其內(nèi)部是用Handler實現(xiàn)的

WebView面試題

1、WebView安全漏洞

  • API16之前存在遠程代碼執(zhí)行安全漏洞,該漏洞源于程序沒有正確限制使用WebView.addJavascriptInterface方法,遠程攻擊者可通過使用Java反射機制利用該漏洞執(zhí)行任意Java對象的方法

2、WebView銷毀步驟

  • WebView在其他容器上時(如:LinearLayout),當銷毀Activity時,需要在onDestroy()中先移除容器上的WebView,然后再將WebView.destroy(),這樣就不會導致內(nèi)存泄漏

3、WebView的jsbridge

  • 客戶端和服務(wù)端之間可以通過Javascript來互相調(diào)用各自的方法

4、WebViewClient的onPageFinished

  • WebViewClient的onPageFinished在每次完成頁面的時候調(diào)用,但是遇到未加載完成的頁面跳轉(zhuǎn)其他頁面時,就會一直調(diào)用,使用WebChromeClient.onProgressChanged可以替代

5、WebView后臺耗電

  • 在WebView加載頁面的時候,會自動開啟線程去加載,如果不很好的關(guān)閉這些線程,就會導致電量消耗加大,可以采用暴力的方法,直接在onDestroy方法中System.exit(0)結(jié)束當前正在運行中的java虛擬機

6、WebView硬件加速

  • Android3.0引入硬件加速,默認會開啟,WebView在硬件加速的情況下滑動更加平滑,性能更加好,但是會出現(xiàn)白塊或者頁面閃爍的副作用,建議WebView暫時關(guān)閉硬件加速

7、WebView內(nèi)存泄漏

  • 由于WebView是依附于Activity的,Activity的生命周期和WebView啟動的線程的生命周期是不一致的,這會導致WebView一直持有對這個Activity的引用而無法釋放,解決方案如下
  • 獨立進程,簡單暴力,不過可能涉及到進程間通信(推薦)
  • 動態(tài)添加WebView,對傳入WebView中使用的Context使用弱引用

Binder面試題

1、Linux內(nèi)核的基本知識

  • 進程隔離/虛擬地址空間:進程間是不可以共享數(shù)據(jù)的,相當于被隔離,每個進程被分配到不同的虛擬地址中
  • 系統(tǒng)調(diào)用:Linux內(nèi)核對應(yīng)用有訪問權(quán)限,用戶只能在應(yīng)用層通過系統(tǒng)調(diào)用,調(diào)用內(nèi)核的某些程序
  • binder驅(qū)動:它負責各個用戶的進程,通過binder通信內(nèi)核來進行交互的模塊

2、為什么使用Binder

  • 性能上,相比傳統(tǒng)的Socket更加高效
  • 安全性高,支持協(xié)議雙方互相校驗

3、Binder通信模型


  • Service服務(wù)端通過Binder驅(qū)動在ServiceManager的查找表中注冊O(shè)bject對象的add方法
  • Client客戶端通過Binder驅(qū)動在ServiceManager的查找表中找到Object對象的add方法,并返回proxy的add方法,add方法是個空實現(xiàn),proxy也不是真正的Object對象,是通過Binder驅(qū)動封裝好的代理類的add方法
  • 當Client客戶端調(diào)用add方法時,Client客戶端通過Binder驅(qū)動將proxy的add方法,請求ServiceManager來找到Service服務(wù)端真正對象的add方法,進行調(diào)用

4、AIDL

  • 客戶端通過aidl文件的Stub.asInterface()方法,拿到Proxy代理類
    通過調(diào)用Proxy代理類的方法,將參數(shù)進行封包后,調(diào)用底層的transact()方法
  • transact()方法會回調(diào)onTransact()方法,進行參數(shù)的解封
    在onTransact()方法中調(diào)用服務(wù)端對應(yīng)的方法,并將結(jié)果返回

Handler面試題

1、Handler是什么

  • Handler通過發(fā)送和處理Message和Runnable對象來關(guān)聯(lián)相對應(yīng)線程的MessageQueue
    2、Handler使用方法
  • post(runnable)
  • sendMessage(message)

3、Handler工作原理
Android進階——Android消息機制之Looper、Handler、MessageQueen

4、Handler引起的內(nèi)存泄漏

  • 原因:非靜態(tài)內(nèi)部類持有外部類的匿名引用,導致Activity無法釋放
  • 解決: Handler內(nèi)部持有外部Activity的弱引用
    Handler改為靜態(tài)內(nèi)部類
    Handler.removeCallback()

AsyncTask面試題

1、AsyncTask是什么

  • 它本質(zhì)上就是一個封裝了線程池和Handler的異步框架

2、AsyncTask使用方法

  • 三個參數(shù)

    • Params:表示后臺任務(wù)執(zhí)行時的參數(shù)類型,該參數(shù)會傳給AysncTask的doInBackground()方法
    • Progress:表示后臺任務(wù)的執(zhí)行進度的參數(shù)類型,該參數(shù)會作為onProgressUpdate()方法的參數(shù)
    • Result:表示后臺任務(wù)的返回結(jié)果的參數(shù)類型,該參數(shù)會作為onPostExecute()方法的參數(shù)
  • 五個方法

    • onPreExecute():異步任務(wù)開啟之前回調(diào),在主線程中執(zhí)行
    • doInBackground():執(zhí)行異步任務(wù),在線程池中執(zhí)行
    • onProgressUpdate():當doInBackground中調(diào)用publishProgress時回調(diào),在主線程中執(zhí)行
    • onPostExecute():在異步任務(wù)執(zhí)行之后回調(diào),在主線程中執(zhí)行
    • onCancelled():在異步任務(wù)被取消時回調(diào)

3、AsyncTask工作原理

4、AsyncTask引起的內(nèi)存泄漏

  • 原因:非靜態(tài)內(nèi)部類持有外部類的匿名引用,導致Activity無法釋放
  • 解決: AsyncTask內(nèi)部持有外部Activity的弱引用
    AsyncTask改為靜態(tài)內(nèi)部類
    AsyncTask.cancel()

5、AsyncTask生命周期

  • 在Activity銷毀之前,取消AsyncTask的運行,以此來保證程序的穩(wěn)定

6、AsyncTask結(jié)果丟失

  • 由于屏幕旋轉(zhuǎn)、Activity在內(nèi)存緊張時被回收等情況下,Activity會被重新創(chuàng)建,此時,舊的AsyncTask持有舊的Activity引用,這個時候會導致AsyncTask的onPostExecute()對UI更新無效

7、AsyncTask并行or串行

  • AsyncTask在Android 2.3之前默認采用并行執(zhí)行任務(wù),AsyncTask在Android 2.3之后默認采用串行執(zhí)行任務(wù)
  • 如果需要在Android 2.3之后采用并行執(zhí)行任務(wù),可以調(diào)用AsyncTask的executeOnExecutor()

HandlerThread面試題

1、HandlerThread產(chǎn)生背景

  • 當系統(tǒng)有多個耗時任務(wù)需要執(zhí)行時,每個任務(wù)都會開啟一個新線程去執(zhí)行耗時任務(wù),這樣會導致系統(tǒng)多次創(chuàng)建和銷毀線程,從而影響性能。為了解決這一問題,Google提供了HandlerThread,HandlerThread是在線程中創(chuàng)建一個Looper循環(huán)器,讓Looper輪詢消息隊列,當有耗時任務(wù)進入隊列時,則不需要開啟新線程,在原有的線程中執(zhí)行耗時任務(wù)即可,否則線程阻塞

2、HanlderThread的特點、

  • HandlerThread本質(zhì)上是一個線程,繼承自Thread
  • HandlerThread有自己的Looper對象,可以進行Looper循環(huán),可以創(chuàng)建Handler
  • HandlerThread可以在Handler的handlerMessage中執(zhí)行異步方法
    HandlerThread優(yōu)點是異步不會堵塞,減少對性能的消耗
  • HandlerThread缺點是不能同時繼續(xù)進行多任務(wù)處理,需要等待進行處理,處理效率較低
  • HandlerThread與線程池不同,HandlerThread是一個串行隊列,背后只有一個線程

IntentService面試題

1、IntentService是什么

  • IntentService是繼承自Service并處理異步請求的一個類,其內(nèi)部采用HandlerThread和Handler實現(xiàn)的,在IntentService內(nèi)有一個工作線程來處理耗時操作,其優(yōu)先級比普通Service高。當任務(wù)完成后,IntentService會自動停止,而不需要手動調(diào)用stopSelf()。
  • 另外,可以多次啟動IntentService,每個耗時操作都會以工作隊列的方式在IntentService中onHandlerIntent()回調(diào)方法中執(zhí)行,并且每次只會執(zhí)行一個工作線程

2、IntentService使用方法

  • 創(chuàng)建Service繼承自IntentService
  • 覆寫構(gòu)造方法和onHandlerIntent()方法
  • 在onHandlerIntent()中執(zhí)行耗時操作

視圖工作機制面試題

Android進階——Android視圖工作機制之measure、layout、draw

事件分發(fā)機制面試題

Android事件分發(fā)機制之dispatchTouchEvent、onInterceptTouchEvent、onTouchEvent

ListView面試題

1、ListView是什么

  • ListView是能將一個數(shù)據(jù)集合以動態(tài)滾動的方式展示到用戶界面上的View

2、ListView的RecycleBin機制


這里寫圖片描述

3、ListView的優(yōu)化

  • 重用convertView
  • 使用ViewHolder
  • 圖片三級緩存
  • 監(jiān)聽滑動事件
  • 少用透明View
  • 開啟硬件加速

Android項目構(gòu)建面試題

1、android構(gòu)建流程

這里寫圖片描述

2、jenkins持續(xù)集成構(gòu)建

3、Git常用命令

git init:倉庫的初始化
git status:查看當前倉庫的狀態(tài)
git diff:查看倉庫與上次修改的內(nèi)容
git add:將文件放進暫存區(qū)
git commit:提交代碼
git clone:克隆代碼
git bransh:查看當前分支
git checkout:切換當前分支

4、git工作流

fork/clone(主流) fork:將別人的倉庫代碼fork到自己的倉庫上
clone:克隆下自己倉庫的代碼
update、commit:修改代碼并提交到自己的倉庫
push:提交到自己的倉庫
pull request:請求添加到別人的倉庫
clone

5、proguard是什么

  • ProGuard工具是用于壓縮、優(yōu)化和混淆我們的代碼,其主作用是移除或混淆代碼中無用類、字段、方法和屬性

6、proguard技術(shù)功能

  • 壓縮
  • 優(yōu)化
  • 混淆
  • 預(yù)檢測

7、proguard工作原理

  • 將無用的字段或方法存入到EntryPoint中,將非EntryPoint的字段和方法進行替換

8、為什么要混淆

  • 由于Java是一門跨平臺的解釋性語言,其源代碼被編譯成class字節(jié)碼來適應(yīng)其他平臺,而class文件包含了Java源代碼信息,很容易被反編譯

ANR面試題

1、什么是ANR

  • Application Not Responding,頁面無響應(yīng)的對話框

2、發(fā)生ANR的條件

  • 應(yīng)用程序的響應(yīng)性是由ActivityManager和WindowManager系統(tǒng)服務(wù)監(jiān)視的,當ANR發(fā)生條件滿足時,就會彈出ANR的對話框
  • Activity超過5秒無響應(yīng)
  • BroadcastReceiver超過10秒無響應(yīng)
  • Service超過20秒無響應(yīng)

3、造成ANR的主要原因

  • 主線程被IO操作阻塞
  • Activity的所有生命周期回調(diào)都是執(zhí)行在主線程的
  • Service默認執(zhí)行在主線程中
  • BoardcastReceiver的回調(diào)onReceive()執(zhí)行在主線程中
  • AsyncTask的回調(diào)除了doInBackground,其他都是在主線程中
  • 沒有使用子線程Looper的Handler的handlerMessage,post(Runnable)都是執(zhí)行在主線程中

4、如何解決ANR

  • 使用AsyncTask處理耗時IO操作
  • 使用Thread或HandlerThread提高優(yōu)先級
  • 使用Handler處理工作線程的耗時操作
  • Activity的onCreate和onResume回調(diào)盡量避免耗時操作

OOM面試題

1、什么是OOM

  • OOM指Out of memory(內(nèi)存溢出),當前占用內(nèi)存加上我們申請的內(nèi)存資源超過了Dalvik虛擬機的最大內(nèi)存限制就會拋出Out of memory異常

2、OOM相關(guān)概念

  • 內(nèi)存溢出:指程序在申請內(nèi)存時,沒有足夠的空間供其使用
  • 內(nèi)存泄漏:指程序分配出去的內(nèi)存不再使用,無法進行回收
  • 內(nèi)存抖動:指程序短時間內(nèi)大量創(chuàng)建對象,然后回收的現(xiàn)象

3、解決OOM

  • Bitmap相關(guān)
  • 圖片壓縮
  • 加載縮略圖
  • 在滾動時不加載圖片
  • 回收Bitmap
  • 使用inBitmap屬性
  • 捕獲異常

其他相關(guān)

  • listview重用convertView、使用lru
  • 避免onDraw方法執(zhí)行對象的創(chuàng)建
  • 謹慎使用多進程

Bitmap面試題

1、recycle

  • 在安卓3.0以前Bitmap是存放在堆中的,我們只要回收堆內(nèi)存即可
    在安卓3.0以后Bitmap是存放在內(nèi)存中的,我們需要回收native層和Java層的內(nèi)存
  • 官方建議我們3.0以后使用recycle方法進行回收,該方法也可以不主動調(diào)用,因為垃圾回收器會自動收集不可用的Bitmap對象進行回收
  • recycle方法會判斷Bitmap在不可用的情況下,將發(fā)送指令到垃圾回收器,讓其回收native層和Java層的內(nèi)存,則Bitmap進入dead狀態(tài)
    recycle方法是不可逆的,如果再次調(diào)用getPixels()等方法,則獲取不到想要的結(jié)果

2、LruCache原理

  • LruCache是個泛型類,內(nèi)部采用LinkedHashMap來實現(xiàn)緩存機制,它提供get方法和put方法來獲取緩存和添加緩存,其最重要的方法trimToSize是用來移除最少使用的緩存和使用最久的緩存,并添加最新的緩存到隊列中

3、計算inSampleSize

public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;

if (height > reqHeight || width > reqWidth) {
    if (width > height) {
        inSampleSize = Math.round((float)height / (float)reqHeight);
    } else {
        inSampleSize = Math.round((float)width / (float)reqWidth);
    }
}
return inSampleSize;
}

4、縮略圖

public static Bitmap thumbnail(String path,int maxWidth, int maxHeight, boolean autoRotate) {
  BitmapFactory.Options options = new BitmapFactory.Options();
  options.inJustDecodeBounds = true;
  Bitmap bitmap = BitmapFactory.decodeFile(path, options);
  options.inJustDecodeBounds = false;
  int sampleSize = calculateInSampleSize(options, maxWidth, maxHeight);
  options.inSampleSize = sampleSize;
  options.inPreferredConfig = Bitmap.Config.RGB_565;
  options.inPurgeable = true;
  options.inInputShareable = true;
  if (bitmap != null && !bitmap.isRecycled()) {
    bitmap.recycle();
}
  bitmap = BitmapFactory.decodeFile(path, options);
  return bitmap;

}

5、保存Bitmap

public static String save(Bitmap bitmap,Bitmap.CompressFormat format, int quality, File destFile) {
try {
    FileOutputStream out = new FileOutputStream(destFile);
    if (bitmap.compress(format, quality, out)) {
        out.flush();
        out.close();
    }
    if (bitmap != null && !bitmap.isRecycled()) {
        bitmap.recycle();
    }
    return destFile.getAbsolutePath();
} catch (FileNotFoundException e) {
    e.printStackTrace();
} catch (IOException e) {
    e.printStackTrace();
}
return null;

}

6、保存到SD卡

public static String save(Bitmap bitmap,Bitmap.CompressFormat format, int quality, Context context) {
if (!Environment.getExternalStorageState()
        .equals(Environment.MEDIA_MOUNTED)) {
    return null;
}
File dir = new File(Environment.getExternalStorageDirectory()
        + "/" + context.getPackageName() + "/save/");
if (!dir.exists()) {
    dir.mkdirs();
}
File destFile = new File(dir, UUID.randomUUID().toString());
return save(bitmap, format, quality, destFile);

}

7、三級緩存

  • 網(wǎng)絡(luò)緩存
  • 本地緩存
  • 內(nèi)存緩存

UI卡頓面試題

1、UI卡頓原理

  • View的繪制幀數(shù)保持60fps是最佳,這要求每幀的繪制時間不超過16ms(1000/60),如果安卓不能在16ms內(nèi)完成界面的渲染,那么就會出現(xiàn)卡頓現(xiàn)象

2、UI卡頓的原因分析

  • 在UI線程中做輕微的耗時操作,導致UI線程卡頓
  • 布局Layout過于復(fù)雜,無法在16ms內(nèi)完成渲染
  • 同一時間動畫執(zhí)行的次數(shù)過多,導致CPU和GPU負載過重
  • overDraw,導致像素在同一幀的時間內(nèi)被繪制多次,使CPU和GPU負載過重
  • View頻繁的觸發(fā)measure、layout,導致measure、layout累計耗時過多和整個View頻繁的重新渲染
  • 頻繁的觸發(fā)GC操作導致線程暫停,會使得安卓系統(tǒng)在16ms內(nèi)無法完成繪制
  • 冗余資源及邏輯等導致加載和執(zhí)行緩慢
  • ANR

3、UI卡頓的優(yōu)化

  • 布局優(yōu)化
    • 使用include、ViewStub、merge
    • 不要出現(xiàn)過于嵌套和冗余的布局
    • 使用自定義View取代復(fù)雜的View
  • ListView優(yōu)化
    • 復(fù)用convertView
    • 滑動不加載
  • 背景和圖片優(yōu)化
    • 縮略圖
    • 圖片壓縮
  • 避免ANR
    • 不要在UI線程中做耗時操作

內(nèi)存泄漏面試題

1、Java內(nèi)存泄漏引起的主要原因

  • 長生命周期的對象持有短生命周期對象的引用就很可能發(fā)生內(nèi)存泄漏

2、Java內(nèi)存分配策略

  • 靜態(tài)存儲區(qū):又稱方法區(qū),主要存儲全局變量和靜態(tài)變量,在整個程序運行期間都存在
  • 棧區(qū):方法體的局部變量會在棧區(qū)創(chuàng)建空間,并在方法執(zhí)行結(jié)束后會自動釋放變量的空間和內(nèi)存
  • 堆區(qū):保存動態(tài)產(chǎn)生的數(shù)據(jù),如:new出來的對象和數(shù)組,在不使用的時候由Java回收器自動回收

3、Android解決內(nèi)存泄漏的例子

  • 單例造成的內(nèi)存泄漏:在單例中,使用context.getApplicationContext()作為單例的context
  • 匿名內(nèi)部類造成的內(nèi)存泄漏:由于非靜態(tài)內(nèi)部類持有匿名外部類的引用,必須將內(nèi)部類設(shè)置為static
  • Handler造成的內(nèi)存泄漏:使用static的Handler內(nèi)部類,同時在實現(xiàn)內(nèi)部類中持有Context的弱引用
  • 避免使用static變量:由于static變量會跟Activity生命周期一致,當Activity退出后臺被后臺回收時,static變量是不安全,所以也要管理好static變量的生命周期
  • 資源未關(guān)閉造成的內(nèi)存泄漏:比如Socket、Broadcast、Cursor、Bitmap、ListView等,使用完后要關(guān)閉
  • AsyncTask造成的內(nèi)存泄漏:由于非靜態(tài)內(nèi)部類持有匿名內(nèi)部類的引用而造成內(nèi)存泄漏,可以通過AsyncTask內(nèi)部持有外部Activity的弱引用同時改為靜態(tài)內(nèi)部類或在onDestroy()中執(zhí)行AsyncTask.cancel()進行修復(fù)

內(nèi)存管理面試題

1、Android內(nèi)存管理機制

  • 分配機制
  • 管理機制

2、內(nèi)存管理機制的特點

  • 更少的占用內(nèi)存
  • 在合適的時候,合理的釋放系統(tǒng)資源
  • 在系統(tǒng)內(nèi)存緊張的時候,能釋放掉大部分不重要的資源
  • 能合理的在特殊生命周期中,保存或還原重要數(shù)據(jù)

3、內(nèi)存優(yōu)化方法

  • Service完成任務(wù)后應(yīng)停止它,或用IntentService(因為可以自動停止服務(wù))代替Service
  • 在UI不可見的時候,釋放其UI資源
  • 在系統(tǒng)內(nèi)存緊張的時候,盡可能多的釋放非重要資源
  • 避免濫用Bitmap導致內(nèi)存浪費
  • 避免使用依賴注入框架
  • 使用針對內(nèi)存優(yōu)化過的數(shù)據(jù)容器
  • 使用ZIP對齊的APK
  • 使用多進程

冷啟動和熱啟動面試題

1、什么是冷啟動和熱啟動

  • 冷啟動:在啟動應(yīng)用前,系統(tǒng)中沒有該應(yīng)用的任何進程信息
  • 熱啟動:在啟動應(yīng)用時,在已有的進程上啟動應(yīng)用(用戶使用返回鍵退出應(yīng)用,然后馬上又重新啟動應(yīng)用)

2、冷啟動和熱啟動的區(qū)別
冷啟動:創(chuàng)建Application后再創(chuàng)建和初始化MainActivity
熱啟動:創(chuàng)建和初始化MainActivity即可

3、冷啟動時間的計算

  • 這個時間值從應(yīng)用啟動(創(chuàng)建進程)開始計算,到完成視圖的第一次繪制為止

4、冷啟動流程

  • Zygote進程中fork創(chuàng)建出一個新的進程
  • 創(chuàng)建和初始化Application類、創(chuàng)建MainActivity
  • inflate布局、當onCreate/onStart/onResume方法都走完
  • contentView的measure/layout/draw顯示在界面上

總結(jié):Application構(gòu)造方法 -> attachBaseContext() -> onCreate() -> Activity構(gòu)造方法 -> onCreate() -> 配置主題中背景等屬性 -> onStart() -> onResume() -> 測量布局繪制顯示在界面上

5、冷啟動優(yōu)化

  • 減少第一個界面onCreate()方法的工作量
  • 不要讓Application參與業(yè)務(wù)的操作
  • 不要在Application進行耗時操作
  • 不要以靜態(tài)變量的方式在Application中保存數(shù)據(jù)
  • 減少布局的復(fù)雜性和深度
  • 不要在mainThread中加載資源
  • 通過懶加載方式初始化第三方SDK

其他優(yōu)化面試題

1、Android不用靜態(tài)變量存儲數(shù)據(jù)

  • 靜態(tài)變量等數(shù)據(jù)由于進程已經(jīng)被殺死而被初始化
  • 使用其他數(shù)據(jù)傳輸方式:文件/sp/contentProvider

2、SharePreference安全問題

  • 不能跨進程同步
  • 文件不宜過大

3、內(nèi)存對象序列化

  • Serializeble:是java的序列化方式,Serializeble在序列化的時候會產(chǎn)生大量的臨時對象,從而引起頻繁的GC
  • Parcelable:是Android的序列化方式,且性能比Serializeble高,Parcelable不能使用在要將數(shù)據(jù)存儲在硬盤上的情況

4、避免在UI線程中做繁重的操作

架構(gòu)模式面試題

插件化面試題

1、插件化解決的問題

  • 動態(tài)加載APK(反射、類加載器)
  • 資源加載(反射、AssetManager、獨立資源、分段資源)
  • 代碼加載(反射獲取生命周期)

2、類加載器(Java中字節(jié)碼添加到虛擬機中)

  • DexClassLoader:能夠加載未安裝的jar/apk/dex,主要用于動態(tài)加載和代碼熱更新
  • PathClassLoader:只能加載系統(tǒng)中已經(jīng)安裝過的apk

熱更新面試題

1、熱更新主要流程

  • 線上檢查到Crash
  • 拉出Bugfix分支修復(fù)Crash問題
  • jenkins構(gòu)建和補丁生成
  • app通過推送或主動拉取補丁文件
  • 將Bugfix代碼合到master上

2、熱更新主流框架

  • Dexposed
  • AndFix
  • Nuwa

3、熱更新的原理

  • 在ClassLoader創(chuàng)建一個dexElements數(shù)組
  • 將修復(fù)好的dex文件存放在dexElements數(shù)組的最前面
  • ClassLoader會遍歷dexElements數(shù)組,找到最前面的dex文件優(yōu)先加載

進程保活面試題

1、進程的優(yōu)先級

  • 空進程
  • 后臺進程
  • 服務(wù)進程
  • 可見進程
  • 前臺進程

2、Android進程回收策略

  • Low memory Killer(定時執(zhí)行):通過一些比較復(fù)雜的評分機制,對進程進行打分,然后將分數(shù)高的進程判定為bad進程,殺死并釋放內(nèi)存
  • OOM_ODJ:判別進程的優(yōu)先級

3、Android保活方案

  • 利用系統(tǒng)廣播拉活
  • 利用系統(tǒng)Service機制拉活
  • 利用Native進程拉活
  • 利用JobScheduler機制拉活
  • 利用賬號同步機制拉活

Lint面試題

1、什么是Android Lint

  • Android Lint是一個靜態(tài)代碼分析工具,它能夠?qū)δ愕腁ndroid項目中潛在的Bug、可優(yōu)化的代碼、安全性、性能、可用性、可訪問性、國際化等進行檢查

2、Lint工作流程


這里寫圖片描述

3、配置Lint

  • 創(chuàng)建Lint.xml到根目錄下,自定義Lint安全等級等
  • 在Java文件中可以使用@suppressLint(“NewApi”)來忽視Lint的報錯
  • 在xml文件中可以使用tool:ignore(“UnusedResources”)來忽視Lint的報錯
  • 自定義Lint檢查,可以創(chuàng)建類,繼承Detector和實現(xiàn)JavaPsiScanner

Kotlin面試題

1、什么是Kotlin

  • Kotlin是一種基于JVM的編程語言
  • 對Java的一種拓展,比Java更簡潔
  • Kotlin支持函數(shù)式編程
  • Kotlin類和Java類可以相互調(diào)用

2、Kotlin環(huán)境搭建

  • 直接在Plugin中下載Kotlin插件即可
  • 系統(tǒng)會自動配置到Kotlin環(huán)境
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容