Android面試題——進階篇

你如世間春秋發表於2018-10-10

上一篇整理了一些Android方面的基礎面試題,這倆天自己也是一直在整理之前學習過程中所記錄的筆記。工作這麼久,有的時候感覺身邊的人都不斷的再進步,唯獨只有自己還在原地踏步。就是想著是不是該換個方式去走接下來的路。

面試時技術經理可能會問我們一些工作中遇到的Android方面的問題,談談我們所做的專案,和在專案中所扮演的角色。下面整理下自己之前記錄的一些知識點:

1、什麼是嵌入式實時作業系統, Android 作業系統屬於實時作業系統嗎?

實時作業系統是指當外界事件或資料產生時,能夠接受並以足夠快的速度予以處理,其處理的結果又能在規定的時間之內來控制生產過程或對處理系統作出快速響應,並控制所有實時任務協調一致執行的嵌入式作業系統。主要用於工業控制、軍事裝置、航空航天等領域對系統的響應時間有苛刻的要求,這就需要使用實時系統。又可分為軟實時和硬實時兩種,而Android是基於Linux核心的,因此屬於軟實時。

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裡的多程式概念。一般情況下,一個應用程式就是一個程式,這個程式名稱就是應用程式包名。我們知道程式是系統分配資源和排程的基本單位,所以每個程式都有自己獨立的資源和記憶體空間,別的程式是不能任意訪問其他程式的記憶體和資源的。

1.如何讓自己的應用擁有多個程式?

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

2、多執行緒的優劣

使用多程式顯而易見的好處就是分擔主程式的記憶體壓力。我們的應用越做越大,記憶體越來越多,將一些獨立的元件放到不同的程式,它就不佔用主程式的記憶體空間了。當然還有其他好處,有心人會發現Android後臺程式裡有很多應用是多個程式的,因為它們要常駐後臺,特別是即時通訊或者社交應用,不過現在多程式已經被用爛了。典型用法是在啟動一個不可見的輕量級私有程式,在後臺收發訊息,或者做一些耗時的事情,或者開機啟動這個程式,然後做監聽等。還有就是防止主程式被殺守護程式,守護程式和主程式之間相互監視,有一方被殺就重新啟動它。 壞處的話,多佔用了系統的空間,大家都這麼用的話系統記憶體很容易佔滿而導致卡頓。消耗使用者的電量。應用程式架構會變複雜,應為要處理多程式之間的通訊。這裡又是另外一個問題了。

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)

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回收。無用的物件佔據著記憶體空間,使得實際可使用記憶體變小,形象地說法就是記憶體洩漏了。

場景

1、類的靜態變數持有大資料物件 2、靜態變數長期維持到大資料物件的引用,阻止垃圾回收。 3、非靜態內部類的靜態例項 4、非靜態內部類會維持一個到外部類例項的引用,如果非靜態內部類的例項是靜態的,就會間接長期維持著外部類的引用,阻止被回收掉。。 5、資源物件未關閉 6、資源性物件如Cursor、File、Socket,應該在使用後及時關閉。未在finally中關閉,會導致異常情況下資源物件未被釋放的隱患。 7、註冊物件未反註冊 8、未反註冊會導致觀察者列表裡維持著物件的引用,阻止垃圾回收。 9、Handler臨時性記憶體洩露 10、Handler通過傳送Message與主執行緒互動,Message發出之後是儲存在MessageQueue中的,有些Message也不是馬上就被處理的。在Message中存在一個 target,是Handler的一個引用,如果Message在Queue中存在的時間越長,就會導致Handler無法被回收。如果Handler是非靜態的,則會導致Activity或者Service不會被回收。 11、由於AsyncTask內部也是Handler機制,同樣存在記憶體洩漏的風險。此種記憶體洩露,一般是臨時性的。

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

檢測

1、DDMS Heap發現記憶體洩露 dataObject totalSize的大小,是否穩定在一個範圍內,如果操作程式,不斷增加,說明記憶體洩露 2、使用Heap Tool進行記憶體快照前後對比 BlankActivity手動觸發GC進行前後對比,物件是否被及時回收

定位

1、MAT外掛開啟.hprof具體定位記憶體洩露: 檢視histogram項,選中某一個物件,檢視它的GC引用鏈,因為存在GC引用鏈的,說明無法回收 2、AndroidStudio的Allocation Tracker: 觀測到期間的記憶體分配,哪些物件被建立,什麼時候建立,從而準確定位

21、多程式應該能為我們帶來什麼呢

Android平臺對應用都有記憶體限制,其實這個理解有點問題,應該是說android平臺對每個程式有記憶體限制,比如某機型對對程式限制是24m,如果應用有兩個程式,則該應該的總記憶體限制是2*24m。使用多程式就可以使得我們一個apk所使用的記憶體限制加大幾倍。所以可以藉此圖片平臺對應用的記憶體限制,比如一些要對圖片、視訊、大檔案程式處理的好記憶體的應用可以考慮用多程式來解決應用操作不流暢問題。

相關文章