android外掛化面試,大廠Android開發面試解答,你掌握了多少?
前言
碎碎念:二本渣校,卻拿到了位元組跳動Offer!我是如何做到的,我把經歷寫成文章分享給大家,希望對你們能有一些幫助!之前在牛客許願,後來來了offer就忘記了要發,現在趕緊補上。三次面試是一天內完成的,意向書是面試結束後過了一週拿到的。
我投的大方向是:抖音/抖音火山版/直播。覆盤一下:其實我總共被問得問題並不多,主要是實習問的較多,所以建議大家實習做的東西一定要保證能說出目的意義,講清楚技術實現,以及相關的技術延伸
一.Android中高階面試題
1、Activity生命週期?
onCreate()
-> onStart()
-> onResume()
-> onPause()
onStop()
-> onDetroy()
2、Service生命週期?
service 啟動方式有兩種,一種是通過startService()
方式進行啟動,另一種是通過bindService()
方式進行啟動。不同的啟動方式他們的生命週期是不一樣.
通過startService()
這種方式啟動的service,生命週期是這樣:呼叫startService()
--> onCreate()
--> onStartConmon()
--> onDestroy()
。這種方式啟動的話,需要注意一下幾個問題,
第一:當我們通過startService
被呼叫以後,多次在呼叫startService()
onCreate()
方法也只會被呼叫一次,而onStartConmon()
會被多次呼叫當我們呼叫stopService()
的時候,onDestroy()
就會被呼叫,從而銷燬服務。第二:當我們通過
startService
啟動時候,通過intent傳值,在onStartConmon()
方法中獲取值的時候,一定要先判斷intent是否為null。
通過bindService()
方式進行繫結,這種方式繫結service,生命週期走法:bindService
-->onCreate()
-->onBind()
-->unBind()
-->onDestroy()
? bingservice
ServiceConnection
物件,通過ServiceConnection
來獲取service中內部類的類物件,然後通過這個類物件就可以呼叫類中的方法,當然這個類需要繼承Binder物件
3、Activity的啟動過程(不要回答生命週期)
app啟動的過程有兩種情況,第一種是從桌面launcher上點選相應的應用圖示,第二種是在activity中通過呼叫startActivity
來啟動一個新的activity。
我們建立一個新的專案,預設的根activity都是MainActivity
,而所有的activity都是儲存在堆疊中的,我們啟動一個新的activity就會放在上一個activity上面,而我們從桌面點選應用圖示的時候,由於launcher本身也是一個應用,當我們點選圖示的時候,系統就會呼叫startActivitySately()
,一般情況下,我們所啟動的activity的相關資訊都會儲存在intent中,比如action,category等等。我們在安裝這個應用的時候,系統也會啟動一個PackaManagerService
的管理服務,這個管理服務會對AndroidManifest.xml
檔案進行解析,從而得到應用程式中的相關資訊,比如service,activity,Broadcast等等,然後獲得相關元件的資訊。
當我們點選應用圖示的時候,就會呼叫startActivitySately()
方法,而這個方法內部則是呼叫startActivty()
,而startActivity()
方法最終還是會呼叫startActivityForResult()
這個方法。而在startActivityForResult()
這個方法。因為startActivityForResult()
方法是有返回結果的,所以系統就直接給一個-1,就表示不需要結果返回了。
而startActivityForResult()
這個方法實際是通過Instrumentation類中的execStartActivity()
方法來啟動activity,Instrumentation這個類主要作用就是監控程式和系統之間的互動。而在這個execStartActivity()
方法中會獲取ActivityManagerService
的代理物件,通過這個代理物件進行啟動activity。啟動會就會呼叫一個checkStartActivityResult()
方法,如果說沒有在配置清單中配置有這個元件,就會在這個方法中丟擲異常了。當然最後是呼叫的是Application.scheduleLaunchActivity()
進行啟動activity,而這個方法中通過獲取得到一個ActivityClientRecord
物件,而這個ActivityClientRecord
通過handler來進行訊息的傳送,系統內部會將每一個activity元件使用ActivityClientRecord
物件來進行描述,而ActivityClientRecord
物件中儲存有一個LoaderApk
物件,通過這個物件呼叫handleLaunchActivity
來啟動activity元件,而頁面的生命週期方法也就是在這個方法中進行呼叫。
4、Broadcast註冊方式與區別?
5、HttpClient與HttpUrlConnection的區別?
此處延伸:Volley裡用的哪種請求方式(2.3前HttpClient
,2.3後HttpUrlConnection
)
首先HttpClient
和HttpUrlConnection
這兩種方式都支援Https
協議,都是以流的形式進行上傳或者下載資料,也可以說是以流的形式進行資料的傳輸,還有ipv6,以及連線池等功能。HttpClient這個擁有非常多的API,所以如果想要進行擴充套件的話,並且不破壞它的相容性的話,很難進行擴充套件,也就是這個原因,Google在Android6.0的時候,直接就棄用了這個HttpClient.
而HttpUrlConnection
相對來說就是比較輕量級了,API比較少,容易擴充套件,並且能夠滿足Android大部分的資料傳輸。比較經典的一個框架volley,在2.3版本以前都是使用HttpClient
,在2.3以後就使用了HttpUrlConnection
。
6、java虛擬機器和Dalvik虛擬機器的區別?
Java虛擬機器:
- java虛擬機器基於棧。?基於棧的機器必須使用指令來載入和操作棧上資料,所需指令更多更多。
- java虛擬機器執行的是java位元組碼。(java類會被編譯成一個或多個位元組碼.class檔案)
Dalvik虛擬機器:
- dalvik虛擬機器是基於暫存器的
- Dalvik執行的是自定義的.dex位元組碼格式。(java類被編譯成.class檔案後,會通過一個dx工具將所有的.class檔案轉換成一個.dex檔案,然後dalvik虛擬機器會從其中讀取指令和資料
- 常量池已被修改為只使用32位的索引,以 簡化直譯器。
- 一個應用,一個虛擬機器例項,一個程序(所有android應用的執行緒都是對應一個linux執行緒,都執行在自己的沙盒中,不同的應用在不同的程序中執行。每個android dalvik應用程式都被賦予了一個獨立的linux PID(app_*))
7、程序保活(不死程序)
此處延伸:程序的優先順序是什麼
8、講解一下Context?
Context是一個抽象基類。在翻譯為上下文,也可以理解為環境,是提供一些程式的執行環境基礎資訊。Context下有兩個子類,ContextWrapper
是上下文功能的封裝類,而ContextImpl
則是上下文功能的實現類。
而ContextWrapper
又有三個直接的子類, ContextThemeWrapper
、Service
和Application
。其中,ContextThemeWrapper
是一個帶主題的封裝類,而它有一個直接子類就是Activity,所以Activity和Service以及Application的Context是不一樣的,只有Activity需要主題,Service不需要主題。Context一共有三種類型,分別是Application、Activity和Service。這三個類雖然分別各種承擔著不同的作用,但它們都屬於Context的一種,而它們具體Context的功能則是由ContextImpl
類去實現的,因此在絕大多數場景下,Activity、Service和Application這三種類型的Context都是可以通用的。不過有幾種場景比較特殊,比如啟動Activity,還有彈出Dialog。
出於安全原因的考慮,Android是不允許Activity或Dialog憑空出現的,一個Activity的啟動必須要建立在另一個Activity的基礎之上,也就是以此形成的返回棧。而Dialog則必須在一個Activity上面彈出(除非是System Alert型別的Dialog),因此在這種場景下,我們只能使用Activity型別的Context,否則將會出錯。
getApplicationContext()
和getApplication()
方法得到的物件都是同一個application物件,只是物件的型別不一樣。
Context數量 = Activity數量 + Service數量 + 1 (1為Application)
9、理解Activity,View,Window三者關係
這個問題真的很不好回答。所以這裡先來個算是比較恰當的比喻來形容下它們的關係吧。Activity像一個工匠(控制單元),Window像窗戶(承載模型),View像窗花(顯示檢視)LayoutInflater
像剪刀,Xml
配置像窗花圖紙。
1 Activity構造的時候會初始化一個Window,準確的說是
PhoneWindow
。
2 這個PhoneWindow
有一個“ViewRoot
”,這個“ViewRoot
”是一個View或者說ViewGroup
,是最初始的根檢視。
3 “ViewRoot
”通過addView
方法來一個個的新增View。比如TextView
,Button
等
4 這些View的事件監聽,是由WindowManagerService
來接受訊息,並且回撥Activity函式。比如onClickListener
,onKeyDown
等。
10、四種LaunchMode及其使用場景
此處延伸:棧(First In Last Out)與佇列(First In First Out)的區別
棧與佇列的區別:
1.?佇列先進先出,棧先進後出
2.?對插入和刪除操作的"限定"。 棧是限定只能在表的一端進行插入和刪除操作的線性表。 佇列是限定只能在表的一端進行插入和在另一端進行刪除操作的線性表。
3.?遍歷資料速度不同
standard 模式
這是預設模式,每次啟用Activity時都會建立Activity例項,並放入任務棧中。使用場景:大多數Activity。
singleTop 模式
如果在任務的棧頂正好存在該Activity的例項,就重用該例項( 會呼叫例項的 onNewIntent()
),否則就會建立新的例項並放入棧頂,即使棧中已經存在該Activity的例項,只要不在棧頂,都會建立新的例項。使用場景如新聞類或者閱讀類App的內容頁面。
singleTask 模式
如果在棧中已經有該Activity的例項,就重用該例項(會呼叫例項的 onNewIntent()
)。重用時,會讓該例項回到棧頂,因此在它上面的例項將會被移出棧。如果棧中不存在該例項,將會建立新的例項放入棧中。使用場景如瀏覽器的主介面。不管從多少個應用啟動瀏覽器,只會啟動主介面一次,其餘情況都會走onNewIntent
,並且會清空主介面上面的其他頁面。
singleInstance 模式
在一個新棧中建立該Activity的例項,並讓多個應用共享該棧中的該Activity例項。一旦該模式的Activity例項已經存在於某個棧中,任何應用再啟用該Activity時都會重用該棧中的例項( 會呼叫例項的 onNewIntent()
)。其效果相當於多個應用共享一個應用,不管誰啟用該 Activity 都會進入同一個應用中。使用場景如鬧鈴提醒,將鬧鈴提醒與鬧鈴設定分離。singleInstance
不要用於中間頁面,如果用於中間頁面,跳轉會有問題,比如:A -> B (singleInstance
) -> C,完全退出後,在此啟動,首先開啟的是B。
11、View的繪製流程
12、View,ViewGroup事件分發
13、儲存Activity狀態
14、Android中的幾種動畫
幀動畫:指通過指定每一幀的圖片和播放時間,有序的進行播放而形成動畫效果,比如想聽的律動條。
補間動畫:指通過指定View的初始狀態、變化時間、方式,通過一系列的演算法去進行圖形變換,從而形成動畫效果,主要有Alpha、Scale、Translate、Rotate四種效果。注意:只是在檢視層實現了動畫效果,並沒有真正改變View的屬性,比如滑動列表,改變標題欄的透明度。
屬性動畫:在Android3.0的時候才支援,通過不斷的改變View的屬性,不斷的重繪而形成動畫效果。相比於檢視動畫,View的屬性是真正改變了。比如view的旋轉,放大,縮小。
15、Android中跨程序通訊的幾種方式
16、AIDL理解
此處延伸:簡述Binder
?AIDL: 每一個程序都有自己的Dalvik VM例項,都有自己的一塊獨立的記憶體,都在自己的記憶體上儲存自己的資料,執行著自己的操作,都在自己的那片狹小的空間裡過完自己的一生。而aidl就類似與兩個程序之間的橋樑,使得兩個程序之間可以進行資料的傳輸,跨程序通訊有多種選擇,比如 BroadcastReceiver
, Messenger 等,但是 BroadcastReceiver
佔用的系統資源比較多,如果是頻繁的跨程序通訊的話顯然是不可取的;Messenger 進行跨程序通訊時請求佇列是同步進行的,無法併發執行。
Binde機制簡單理解:
在Android系統的Binder機制中,是有Client
,Service
,ServiceManager
,Binder
驅動程式組成的,其中Client
,service
,Service Manager
執行在使用者空間,Binder驅動程式是執行在核心空間的。而Binder就是把這4種元件粘合在一塊的粘合劑,其中核心的元件就是Binder驅動程式,Service Manager
提供輔助管理的功能,而Client和Service正是在Binder驅動程式和Service Manager
提供的基礎設施上實現C/S 之間的通訊。其中Binder驅動程式提供裝置檔案/dev/binder與使用者控制元件進行互動,
Client
、Service
,Service Manager
通過open和ioctl檔案操作相應的方法與Binder驅動程式進行通訊。而Client和Service之間的程序間通訊是通過Binder驅動程式間接實現的。而Binder Manager是一個守護程序,用來管理Service,並向Client提供查詢Service介面的能力。
17、Handler的原理
Android中主執行緒是不能進行耗時操作的,子執行緒是不能進行更新UI的。所以就有了handler,它的作用就是實現執行緒之間的通訊。
handler整個流程中,主要有四個物件,handler
,Message
,MessageQueue
,Looper
。當應用建立的時候,就會在主執行緒中建立handler物件,
我們通過要傳送的訊息儲存到Message
中,handler通過呼叫sendMessage
方法將Message
傳送到MessageQueue
中,Looper
物件就會不斷的呼叫loop()方法
不斷的從MessageQueue
中取出Message交給handler進行處理。從而實現執行緒之間的通訊。
18、Binder機制原理
在Android系統的Binder機制中,是有Client
,Service
,ServiceManager
,Binder
驅動程式組成的,其中Client
,service
,Service Manager
執行在使用者空間,Binder驅動程式是執行在核心空間的。而Binder就是把這4種元件粘合在一塊的粘合劑,其中核心的元件就是Binder驅動程式,Service Manager
提供輔助管理的功能,而Client
和Service
正是在Binder驅動程式和Service Manager
提供的基礎設施上實現C/S 之間的通訊。其中Binder驅動程式提供裝置檔案/dev/binder與使用者控制元件進行互動,Client
、Service
,Service Manager
通過open和ioctl檔案操作相應的方法與Binder驅動程式進行通訊。而Client和Service之間的程序間通訊是通過Binder驅動程式間接實現的。而Binder Manager
是一個守護程序,用來管理Service,並向Client提供查詢Service介面的能力。
19、熱修復的原理
我們知道Java虛擬機器 —— JVM 是載入類的class檔案的,而Android虛擬機器——Dalvik/ART VM 是載入類的dex
檔案,
而他們載入類的時候都需要ClassLoader,ClassLoader
有一個子類BaseDexClassLoader
,而BaseDexClassLoader
下有一個
陣列——DexPathList
,是用來存放dex
檔案,當BaseDexClassLoader
通過呼叫findClass
方法時,實際上就是遍歷陣列,
找到相應的dex
檔案,找到,則直接將它return。而熱修復的解決方法就是將新的dex
新增到該集合中,並且是在舊的dex
的前面,
所以就會優先被取出來並且return返回。
20、Android記憶體洩露及管理
21、Fragment與Fragment、Activity通訊的方式
22、Android UI適配
23、app優化
24、圖片優化
(1) 對圖片本身進行操作。儘量不要使用
setImageBitmap
、setImageResource
、BitmapFactory.decodeResource
來設定一張大圖,因為這些方法在完成decode後,
最終都是通過java層的createBitmap
來完成的,需要消耗更多記憶體.
(2) 圖片進行縮放的比例,SDK中建議其值是2的指數值,值越大會導致圖片不清晰。
(3) 不用的圖片記得呼叫圖片的recycle()方法
25、HybridApp WebView和JS互動
26、JAVA GC原理
27、ANR
28、設計模式
29、RxJava
30、MVP,MVC,MVVM
此處延伸:手寫mvp例子,與mvc之間的區別,mvp的優勢
MVP模式,對應著Model--業務邏輯和實體模型,view--對應著activity,負責View的繪製以及與使用者互動,Presenter--負責View和Model之間的互動,MVP模式是在MVC模式的基礎上,將Model與View徹底分離使得專案的耦合性更低,在Mvc中專案中的activity對應著mvc中的C--Controllor
,而專案中的邏輯處理都是在這個C中處理,同時View與Model之間的互動,也是也就是說,mvc中所有的邏輯互動和使用者互動,都是放在Controllor
中,也就是activity中。
View和model是可以直接通訊的。而MVP模式則是分離的更加徹底,分工更加明確Model--業務邏輯和實體模型,view--負責與使用者互動,Presenter 負責完成View於Model間的互動,MVP和MVC最大的區別是MVC中是允許Model和View進行互動的,而MVP中很明顯,Model與View之間的互動由Presenter
完成。還有一點就是Presenter
與View
之間的互動是通過介面的
31、手寫演算法(選擇冒泡必須要會)
32、JNI?
(1) 安裝和下載Cygwin,下載 Android NDK
(2) 在ndk專案中JNI介面的設計
(3) 使用C/C++實現本地方法
(4) JNI生成動態連結庫.so檔案
(5) 將動態連結庫複製到java工程,在java工程中呼叫,執行java工程即可
33、RecyclerView和ListView的區別
RecyclerView
可以完成ListView
,GridView
的效果,還可以完成瀑布流的效果。同時還可以設定列表的滾動方向(垂直或者水平);
RecyclerView
中view的複用不需要開發者自己寫程式碼,系統已經幫封裝完成了
RecyclerView
可以進行區域性重新整理。
RecyclerView
提供了API來實現item的動畫效果。
在效能上:
如果需要頻繁的重新整理資料,需要新增動畫,則RecyclerView
有較大的優勢。
如果只是作為列表展示,則兩者區別並不是很大。
34、Universal-ImageLoader,Picasso,Fresco,Glide對比
35、Xutils, OKhttp, Volley, Retrofit對比
學習路線+知識梳理
花了很長時間,就為了整理這張詳細的知識路線腦圖。當然由於時間有限、能力也都有限,畢竟嵌入式全體系實在太龐大了,包括我那做嵌入式的同學,也不可能什麼都懂,有些東西可能沒覆蓋到,不足之處,還希望小夥伴們一起交流補充,一起完善進步。
本文在開源專案:Android開發不會這些?如何面試拿高薪 中已收錄,裡面包含不同方向的自學程式設計路線、面試題集合/面經、及系列技術文章等,資源持續更新中...
這次就分享到這裡吧,下篇見。