天天看點

Android面試題——5.常見面試官提問Android面試題①

一般的面試流程是筆試完就接着是面試了,面試時技術經理會問你一些你工作中遇到的Android方面的問題,談談你所做的項目,和在項目中所扮演的角色。今天我就給大家整理一些,面試中常見的面試官提的一些問題?

1.要做一個盡可能流暢的ListView,你平時在工作中如何進行優化的? 

①Item布局,層級越少越好,使用hierarchyview工具檢視優化。 

②複用convertView 

③使用ViewHolder 

④item中有圖檔時,異步加載 

⑤快速滑動時,不加載圖檔 

⑥item中有圖檔時,應對圖檔進行适當壓縮 

⑦實作資料的分頁加載

2.對于Android 的安全問題,你知道多少 

①錯誤導出元件 

② 參數校驗不嚴 

③WebView引入各種安全問題,webview中的js注入 

④不混淆、不防二次打包 

⑤明文存儲關鍵資訊 

⑦ 錯誤使用HTTPS 

⑧山寨加密方法 

⑨濫用權限、記憶體洩露、使用debug簽名

3. 如何縮減APK包大小? 

代碼 

保持良好的程式設計習慣,不要重複或者不用的代碼,謹慎添加libs,移除使用不到的libs。 

使用proguard混淆代碼,它會對不用的代碼做優化,并且混淆後也能夠減少安裝包的大小。 

native code的部分,大多數情況下隻需要支援armabi與x86的架構即可。如果非必須,可以考慮拿掉x86的部分。 

資源 

使用Lint工具查找沒有使用到的資源。去除不使用的圖檔,String,XML等等。 assets目錄下的資源請確定沒有用不上的檔案。 

生成APK的時候,aapt工具本身會對png做優化,但是在此之前還可以使用其他工具如tinypng對圖檔進行進一步的壓縮預處理。 

jpeg還是png,根據需要做選擇,在某些時候jpeg可以減少圖檔的體積。 對于9.png的圖檔,可拉伸區域盡量切小,另外可以通過使用9.png拉伸達到大圖效果的時候盡量不要使用整張大圖。 

政策 

有選擇性的提供hdpi,xhdpi,xxhdpi的圖檔資源。建議優先提供xhdpi的圖檔,對于mdpi,ldpi與xxxhdpi根據需要提供有差異的部分即可。 

盡可能的重用已有的圖檔資源。例如對稱的圖檔,隻需要提供一張,另外一張圖檔可以通過代碼旋轉的方式實作。 

能用代碼繪制實作的功能,盡量不要使用大量的圖檔。例如減少使用多張圖檔組成animate-list的AnimationDrawable,這種方式提供了多張圖檔很占空間。

4.Android與伺服器互動的方式中的對稱加密和非對稱加密是什麼? 

對稱加密,就是加密和解密資料都是使用同一個key,這方面的算法有DES。 

非對稱加密,加密和解密是使用不同的key。發送資料之前要先和服務端約定生成公鑰和私鑰,使用公鑰加密的資料可以用私鑰解密,反之。這方面的算法有RSA。ssh 和 ssl都是典型的非對稱加密。

5.裝置橫豎屏切換的時候,接下來會發生什麼? 

1、不設定Activity的android:configChanges時,切屏會重新調用各個生命周期,切橫屏時會執行一次,切豎屏時會執行兩次 

2、設定Activity的android:configChanges=”orientation”時,切屏還是會重新調用各個生命周期,切橫、豎屏時隻會執行一次 

3、設定Activity的android:configChanges=”orientation|keyboardHidden”時,切屏不會重新調用各個生命周期,隻會執行onConfigurationChanged方法

6.Android啟動Service的兩種方式是什麼? 它們的适用情況是什麼? 

如果背景服務開始後基本可以獨立運作的話,可以用startService。音樂播放器就可以這樣用。它們會一直運作直到你調用 stopSelf或者stopService。你可以通過發送Intent或者接收Intent來與正在運作的背景服務通信,但大部分時間,你隻是啟動服務并讓它獨立運作。如果你需要與背景服務通過一個持續的連接配接來比較頻繁地通信,建議使用bind()。比如你需要定位服務不停地把更新後的地理位置傳給UI。Binder比Intent開發起來複雜一些,但如果真的需要,你也隻能使用它。 

startService:生命周期與調用者不同。啟動後若調用者未調用stopService而直接退出,Service仍會運作 

bindService:生命周期與調用者綁定,調用者一旦退出,Service就會調用unBind->onDestroy

7.談談你對Android中Context的了解? 

Context:包含上下文資訊(外部值) 的一個參數. Android 中的 Context 分三種,Application Context ,Activity Context ,Service Context. 

它描述的是一個應用程式環境的資訊,通過它我們可以擷取應用程式的資源和類,也包括一些應用級别操作,例如:啟動一個Activity,發送廣播,接受Intent資訊等

8.Service的onCreate回調在UI線程中嗎? 

Service生命周期的各個回調和其他的應用元件一樣,是跑在主線程中,會影響到你的UI操作或者阻塞主線程中的其他事情

9.請介紹下AsyncTask的内部實作,适用的場景是? 

AsyncTask内部也是Handler機制來完成的,隻不過Android提供了執行架構來提供線程池來執行相應地任務,因為線程池的大小問題,是以AsyncTask隻應該用來執行耗時時間較短的任務,比如HTTP請求,大規模的下載下傳和資料庫的更改不适用于AsyncTask,因為會導緻線程池堵塞,沒有線程來執行其他的任務,導緻的情形是會發生AsyncTask根本執行不了的問題。

10.談談你對binder機制的了解? 

binder是一種IPC機制,程序間通訊的一種工具. 

Java層可以利用aidl工具來實作相應的接口.

11.Android中程序間通信有哪些實作方式? 

Intent,Binder(AIDL),Messenger,BroadcastReceiver

12.介紹下實作一個自定義view的基本流程 

1、自定義View的屬性 編寫attr.xml檔案 

2、在layout布局檔案中引用,同時引用命名空間 

3、在View的構造方法中獲得我們自定義的屬性 ,在自定義控件中進行讀取(構造方法拿到attr.xml檔案值) 

4、重寫onMesure 

5、重寫onDraw

13.Android中touch事件的傳遞機制是怎樣的? 

1.Touch事件傳遞的相關API有dispatchTouchEvent、onTouchEvent、onInterceptTouchEvent 

2.Touch事件相關的類有View、ViewGroup、Activity 

3.Touch事件會被封裝成MotionEvent對象,該對象封裝了手勢按下、移動、松開等動作 

4.Touch事件通常從Activity#dispatchTouchEvent發出,隻要沒有被消費,會一直往下傳遞,到最底層的View。 

5.如果Touch事件傳遞到的每個View都不消費事件,那麼Touch事件會反向向上傳遞,最終交由Activity#onTouchEvent處理. 

6.onInterceptTouchEvent為ViewGroup特有,可以攔截事件. 

7.Down事件到來時,如果一個View沒有消費該事件,那麼後續的MOVE/UP事件都不會再給它

14.Android多線程的實作方式有哪些? 

Thread & AsyncTask 

Thread 可以與Loop 和 Handler 共用建立消息處理隊列 

AsyncTask 可以作為線程池并行處理多任務

15.Android開發中何時使用多程序?使用多程序的好處是什麼? 

要想知道如何使用多程序,先要知道Android裡的多程序概念。一般情況下,一個應用程式就是一個程序,這個程序名稱就是應用程式包名。我們知道程序是系統配置設定資源和排程的基本機關,是以每個程序都有自己獨立的資源和記憶體空間,别的程序是不能任意通路其他程序的記憶體和資源的。 

那如何讓自己的應用擁有多個程序? 

很簡單,我們的四大元件在AndroidManifest檔案中注冊的時候,有個屬性是android:process,1.這裡可以指定元件的所處的程序。預設就是應用的主程序。指定為别的程序之後,系統在啟動這個元件的時候,就先建立(如果還沒建立的話)這個程序,然後再建立該元件。你可以重載Application類的onCreate方法,列印出它的程序名稱,就可以清楚的看見了。再設定android:process屬性時候,有個地方需要注意:如果是android:process=”:deamon”,以:開頭的名字,則表示這是一個應用程式的私有程序,否則它是一個全局程序。私有程序的程序名稱是會在冒号前自動加上包名,而全局程序則不會。一般我們都是有私有程序,很少使用全局程序。他們的具體差別不知道有沒有誰能補充一下。

2.使用多程序顯而易見的好處就是分擔主程序的記憶體壓力。我們的應用越做越大,記憶體越來越多,将一些獨立的元件放到不同的程序,它就不占用主程序的記憶體空間了。當然還有其他好處,有心人會發現Android背景程序裡有很多應用是多個程序的,因為它們要常駐背景,特别是即時通訊或者社交應用,不過現在多程序已經被用爛了。典型用法是在啟動一個不可見的輕量級私有程序,在背景收發消息,或者做一些耗時的事情,或者開機啟動這個程序,然後做監聽等。還有就是防止主程序被殺守護程序,守護程序和主程序之間互相監視,有一方被殺就重新啟動它。應該還有還有其他好處,這裡就不多說了。

3.壞處的話,多占用了系統的空間,大家都這麼用的話系統記憶體很容易占滿而導緻卡頓。消耗使用者的電量。應用程式架構會變複雜,應為要處理多程序之間的通信。這裡又是另外一個問題了。

16.ANR是什麼?怎樣避免和解決ANR? 

ANR:Application Not Responding,即應用無響應 

ANR一般有三種類型: 

1:KeyDispatchTimeout(5 seconds) –主要類型 

按鍵或觸摸事件在特定時間内無響應

2:BroadcastTimeout(10 seconds) 

BroadcastReceiver在特定時間内無法處理完成

3:ServiceTimeout(20 seconds) –小機率類型 

Service在特定的時間内無法處理完成

逾時的原因一般有兩種: 

(1)目前的事件沒有機會得到處理(UI線程正在處理前一個事件沒有及時完成或者looper被某種原因阻塞住) 

(2)目前的事件正在處理,但沒有及時完成

UI線程盡量隻做跟UI相關的工作,耗時的工作(資料庫操作,I/O,連接配接網絡或者其他可能阻礙UI線程的操作)放入單獨的線程處理,盡量用Handler來處理UI thread和thread之間的互動。

UI線程主要包括如下: 

Activity:onCreate(), onResume(), onDestroy(), onKeyDown(), onClick() 

AsyncTask: onPreExecute(), onProgressUpdate(), onPostExecute(), onCancel() 

Mainthread handler: handleMessage(), post(runnable r) 

other

17.Android下解決滑動沖突的常見思路是什麼? 

相關的滑動元件 重寫onInterceptTouchEvent,然後判斷根據xy值,來決定是否要攔截目前操作

18.如何把一個應用設定為系統應用? 

成為系統應用,首先要在 對應裝置的 Android 源碼 SDK 下編譯,編譯好之後: 

此 Android 裝置是 Debug 版本,并且已經 root,直接将此 apk 用 adb 工具 push 到 system/app 或 system/priv-app 下即可。 

如果非 root 裝置,需要編譯後重新燒寫裝置鏡像即可。

有些權限(如 WRITE_SECURE_SETTINGS ),是不開放給第三方應用的,隻能在對應裝置源碼中編譯然後作為系統 app 使用。

19、Android記憶體洩露研究 

Android記憶體洩漏指的是程序中某些對象(垃圾對象)已經沒有使用價值了,但是它們卻可以直接或間接地引用到gc roots導緻無法被GC回收。無用的對象占據着記憶體空間,使得實際可使用記憶體變小,形象地說法就是記憶體洩漏了。 

場景 

類的靜态變量持有大資料對象 

靜态變量長期維持到大資料對象的引用,阻止垃圾回收。 

非靜态内部類的靜态執行個體 

非靜态内部類會維持一個到外部類執行個體的引用,如果非靜态内部類的執行個體是靜态的,就會間接長期維持着外部類的引用,阻止被回收掉。 

資源對象未關閉 

資源性對象如Cursor、File、Socket,應該在使用後及時關閉。未在finally中關閉,會導緻異常情況下資源對象未被釋放的隐患。 

注冊對象未反注冊 

未反注冊會導緻觀察者清單裡維持着對象的引用,阻止垃圾回收。 

Handler臨時性記憶體洩露 

Handler通過發送Message與主線程互動,Message發出之後是存儲在MessageQueue中的,有些Message也不是馬上就被處理的。在Message中存在一個 target,是Handler的一個引用,如果Message在Queue中存在的時間越長,就會導緻Handler無法被回收。如果Handler是非靜态的,則會導緻Activity或者Service不會被回收。 

由于AsyncTask内部也是Handler機制,同樣存在記憶體洩漏的風險。 

此種記憶體洩露,一般是臨時性的。

20.記憶體洩露檢測有什麼好方法? 

檢測: 

1、DDMS Heap發現記憶體洩露 

dataObject totalSize的大小,是否穩定在一個範圍内,如果操作程式,不斷增加,說明記憶體洩露 

2、使用Heap Tool進行記憶體快照前後對比 

BlankActivity手動觸發GC進行前後對比,對象是否被及時回收

定位: 

1、MAT插件打開.hprof具體定位記憶體洩露: 

檢視histogram項,選中某一個對象,檢視它的GC引用鍊,因為存在GC引用鍊的,說明無法回收 

2、AndroidStudio的Allocation Tracker: 

觀測到期間的記憶體配置設定,哪些對象被建立,什麼時候建立,進而準确定位

繼續閱讀