1. 程式人生 > >Android專家級別的面試總結

Android專家級別的面試總結

1.. 自定義View流程
onMeasure, onLayout, onDraw, 採用深度優先,因為必須子view獲得測量結果,父view才能確定大小;

ViewGroup:
boolean dispatchTouchEvent(){
if(onInterceptTouchEvent() && onTouchEvent()){
return true;
}else{
return child.dispatchTouchEvent();
}
}

View:(View如果有OnTouch則先執行且返回true,則被OnTouch消費;否則如果返回false,則看是否可點選,可以點選的話,一定消費,至於是否是onClick消費看是否設定了OnClickListener,沒有的話,就是一個沒有反應的點選事件;如果不可點選,則view不消費此事件)
boolean dispatchTouchEvent(){
if(OnTouchListener() && OnTouch())
return true;
else if(clickable()){
onClick();
return true;
}else
return false;
}

一個事件系列(即DOWN–>MOVE…MOVE–>UP),如果一旦一個view接受處理此事件,那麼事件系列後續事件直接給它,不必再次呼叫onInterceptTouchEvent.

如果所有元素都不處理這個事件,那麼這個事件最終會交給Activity去處理,就是Activity的OnTouchEvent方法會被呼叫

Activity.java
/**
* Called when a touch screen event was not handled by any of the views
* under it. This is most useful to process touch events that happen
* outside of your window bounds, where there is no view to receive it.
*
* @param event The touch screen event being processed.
*
* @return Return true if you have consumed the event, false if you haven’t.
* The default implementation always returns false.
*/
public boolean onTouchEvent(MotionEvent event) {
if (mWindow.shouldCloseOnTouch(this, event)) {
finish();
return true;
}

    return false;
}

3.. Service啟動模式(startService bindService)
4.. Activity的啟動模式(standard, singleTop, singleTask(Home頁面常使用), singleInstance )
5.. Android 動畫有哪幾種?區別?
1). 幀動畫: 大量圖片播放,耗記憶體,容易OOM
2). 補間動畫(Tween動畫或者View動畫):並未真正改變位置
3). 屬性動畫 :真正改變位置

6.. handler, Looper,MessageQueue, Message之間的關係
7.. 效能優化有哪些方面可以提高效能的
View方面:
佈局減少巢狀, 多使用Drawable, Include, Merge, ViewStub,
懶載入

中間:
耗時任務放入子執行緒, 多執行緒併發的情況用執行緒池

底層:
DB的大量訪問改為事務處理
大量HTTP download改為一次性

8.. 如何診斷效能問題(log, TraceView, MAT)
9.. MVP框架的理解
10.. 多元件開發 和 外掛化開發 的理解
11.. 熱修復框架,原理?(AndFix, QZone …)
12.. 自動化測試框架(JUnit, Espresso)

14.. 用過哪些設計模式
單例,抽象工廠,觀察者模式,代理模式…

15.. 演算法考察

16.. java基礎(synchronize關鍵字理解, 鎖,jvm, 多執行緒,深拷貝,淺拷貝…)

17.. LRU Cache 演算法原理?用的什麼資料結構?(LinkedHashMap, 雙向連結串列,用的強引用可以控制,最近使用放到隊尾,當達到上限時刪除對頭即可)

18.. Android logcat 裡打出的 GC_FOR_ALLOC等等是什麼意思?LeakCanary檢測記憶體洩露原理? AndroidAnnotation原理?

19.. HashMap 怎麼實現的?和Hashcode關係?

20.. handler, AsyncTask 區別,什麼情況用,優缺點。
都是為了非同步執行緒而存在,handler實現更輕量級,需要自己實現. AsyncTask更重量級,但是封裝好,使用簡單方便。
AsyncTask缺點:
a). 當它為Activity的非靜態內部類,則如果後臺執行緒未完成任務,但是Activity已經銷燬,則發生記憶體洩露。
b). 當Activity在AsyncTask更新UI前已經銷燬,則崩潰,所以必須在銷燬之前取消 AsyncTask。
c). 內部是以執行緒池的方式提供,N+1個。

21.. 哪些情況會導致記憶體洩露.
a). 匿名內部類
b).沒有unregisterReceiver, EventBus unregister(this)等
c). 靜態變數持有Context沒有及時賦值為NULL

22.. 哪些情況容易OOM,如何有效避免
a). 大量圖片的載入,inSampleSize, ARGB_8888…
b). 物件池的複用 convertView
c). 地圖單車全量載入一次性23M資料,導致ANR,而且由於做了LoggingInterceptor, EncryptorInterceptor, 在做source.buffer().readString()時需要額外的同樣大小的陣列,導致一次性分配OOM。解決的辦法是對於這個介面單獨不做log和加密,或者從產品設計上講把圍欄劃分得更小(最好的方案)消除ANR和資料量大導致的OOM。
d). 相機掃碼獲取的幀資料進行剪裁和預處理後依然有分配陣列OOM。

25.. Android 哪些Context能startActivity?
I). Activity可以直接啟動
II). Service和Application也可以啟動,但是必須加上intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
III). BroadcastReceiver 和 ContentProvider 不能直接startActivity,但是可以 context.startActivity(…), 其中Context看是 I)還是II)來是否加NEW_TASK_FLAG。Context是註冊receiver的,比如是在Activity中動態註冊的receiver,那麼onReceive裡的context引數就是此Activity;如果是靜態註冊,那麼是applicationContext.

26.. Intent(context, MyActivity.class) 引數的意義
第一個引數只是為了獲取App的packageName,在此package中尋找第二個引數MyActivity的實現。所以第一個引數是任意的Context均可,比如activity, service, getApplicationContext()等等。

public Intent(Context packageContext, Class<?> cls) {
        mComponent = new ComponentName(packageContext, cls);
    }

public ComponentName(Context pkg, Class<?> cls) {
        mPackage = pkg.getPackageName();
        mClass = cls.getName();
    }

27.. View CANCEL事件什麼時候觸發?
當用戶保持按下操作,並從你的控制元件轉移到外層控制元件時,會觸發ACTION_CANCEL

28.. View DOWN UP事件的區別?
一個是點選下去時觸發,一個起來時觸發

29.. 哪些場景需要多開程序service,為什麼?
一般是為了App保活,或者新開程序做長連線,如JPUSH

30.. 如何解決DNS挾持問題?
HTTPS

31.. Android第三方工具如Bugly, 友盟,bugtags如何獲得Java崩潰異常,和Navtive崩潰,ANR的?
Java崩潰異常:註冊自己的UnCaughtExceptionHandler
Navtive崩潰: 在Navtive層Linux會產生異常訊號,而且Linux提供了Core Dump機制。通過JNI註冊自己的異常訊號捕獲sigaction處理不同的訊號異常即可。
具體見http://blog.csdn.net/leeo1010/article/details/50522892
ANR: 通過在主執行緒schedule一個runnable, 5秒一次,看看是否執行(比如在runnable計數);是,繼續迴圈;否,則說明有ANR發生。
http://blog.csdn.net/gaoanchen/article/details/51914690

32.. OKhttp有哪幾種攔截Interceptor型別? HTTP重定向是哪個header?
I. 應用層的攔截:主要對返回的respondeCode,response內容做處理. addInterceptor()
II. 網路層:可以改變, 增減header等。addNetworkInterceptor()
HTTP重定向是 Response裡的Location 欄位。發生在網路層。應用層是看不到的,即當有重定向發生時,應用層攔截器只會呼叫一次,而網路層攔截器會呼叫2次。
https://github.com/square/okhttp/wiki/Interceptors

33.. Android熱更新(HotPatch)方案有哪幾種?區別?
主要有騰訊的QZone方案(Class級別的替換,Java實現, 無相容性問題),阿里的AndFix(Method級的替換,JNI—>Native實現替換方法,Art虛擬機器相容性不好)。

34.. JNI命名規則,原理,能否相互呼叫?
java能通過JNI呼叫C,而C不能呼叫java。

Java 裡呼叫C:

java:
public static native int execAL(…);

C++裡對java裡的native的方法命名規則:
JNIEXPORT int JNICALL Java_[packageName]_[className]_execAL(….);
j[int, string …] 對應型別

C裡logcat 打log:
定義巨集 #define LOGW(…) android_log_print(ANDROID_LOG, “jni”, __VA_ARGS)

35.. Java和js能否相互呼叫?
可以。

java呼叫js:
mWebView.loadUrl(“javascript:androidCallJS(‘順便傳個引數給JS!’)”);

js呼叫java:
webview.addJavascriptInterface(obj, objStr)
那麼在js裡可以把objStr當做obj用,呼叫其任何方法。
window.objStr.xxx

36.. https 如何提高成功率
第一次連線成功後,可以在伺服器生成一個session key,後續此client再次發起https請求時帶著 sessionID = session key,伺服器可以直接驗證通過,提升了握手效率和成功率。

37.. 為什麼選型okhttp,而不是volley?
okhttp的攔截器比較強大,可以新增修改header以及針對某些response code做出統一反應。

39.. APK 加殼原理?
利用加密工具對源APK加密,然後和脫殼程式的DEX合併為新的DEX,然後替換掉脫殼程式的DEX成為新的APK,執行時,脫殼程式DEX負責解密源APK,並執行之。

40.. so層安全性?
so層加密

41.. 外掛化中為定義在宿主app的Manifest中的Activity是如何調起來的?
I. 在宿主app的Manifest中定義一個fakeActivity
II. 仍然startActivity(this, Target.class)
III. 在進入AMS之前HOOK掉Target.class為fakeActivity, 使其通過AMS對Manifest的檢查,然後出來之後,再次替換為Target,正確調起來

42.. Parcelable Serializable 區別?
Serializable 採用變物件為位元組流的方式,可以持久化在硬碟中,而Parcelable不行。Parcelable本質是通過把物件拆分為可以用intent傳輸的方式進行拆解和還原,因此其效率較高。

43.. SparseArray, ArrayMap 和Hashmap區別?
SparseArray是為了減少記憶體的使用,使用key[int], value[Obj],來分別儲存Key和value,沒有浪費記憶體。使用二分查詢來put, delete, 因此效率上稍低,但是對於delete有特殊的對待,只是標記為delete,無需移位。而Hashmap內部採用了陣列+連結串列,以及用hash的方式,會有很多記憶體空著也要佔用。而且其擴容是2的倍數,且需要重新hash把舊的資料放置在新的table中。其記憶體使用率比SparseArray低,但是put, delete效率較高。

44.. java中的鎖有?
Synchronized, ReentrantLock.保證多執行緒的同步,即操作的原子性。然後,它們還能保證變數的可見性,鎖內使用變數時會去主存獲取最新的變數值,釋放鎖之後把變數最新值從工作記憶體重新整理至主存中。

45.. volatile作用?
保證變數的可見性,多執行緒之間使用此變數時,會從主存讀取最新的變數值,然後會把最新的變數值從工作記憶體重新整理至主存中。
volatile保證有序性。
https://juejin.im/entry/58d8d57a1b69e6006bbddd5f/view

46.. 外部類和內部類的訪問許可權?
內部類能直接訪問外部類的任何修飾符的成員變數和方法。
原因是內部類在編譯期間編譯器會給內部類自動新增一個外部類的成員變數,構造方法引數新增一個外部類引數賦值給其外部類的成員變數。使其持有外部類的物件的引用。
反之,外部類不能直接訪問內部類的任何修飾符的成員變數和方法。因為,內部類必須依賴於外部類的物件而存在。
另外,內部類不能擁有static成員變數,道理同上。

47.. 類的修飾能有哪些?
頂級類只能是public 和default
內部類都可以修飾, public, protected,private, default(friendly).

48.. 泛型 T, ? 區別?
T是某一類確定的型別,?是未知型別。
?的上邊界extends,只能讀,下邊界super只能插入。
https://www.zhihu.com/question/20400700

50.. FragmentTransaction 裡的 add, replace 區別?
add不會重建,replace會remove之前此容器裡added過的所有fragment例項,然後再add現在的fragment。
http://blog.csdn.net/gsw333/article/details/51858524

51.. 執行緒的啟動方式?
// MyThread裡的資源不共享
new MyThread().start()

// m1裡的變數 資源共享
Runnable m1 = new Runnable();
new Thread(m1).start()
….
new Thread(m1).start()

52.. 終止執行緒的方式?
I. 共享變數flag法,volatile方式:終止正在執行的執行緒;但是無法終止一個被阻塞的執行緒(因為無法執行到flag來)。
II. thread.interrupt() 可以使一個被阻塞的執行緒丟擲一箇中斷異常,從而使執行緒提前結束阻塞狀態,退出堵塞程式碼。
http://www.cnblogs.com/luckygxf/p/4737655.html

53.. Service 與 IntentService 區別?
IntentService繼承Service,內部在OnCreate時自動建立了一個子執行緒,裡面維護了一個訊息佇列來順序執行每個onStartCommand的intent。而Service沒有,因此如果在Service的onStartCommand裡啟動一個執行緒的話, 那麼多次呼叫startService會使多個執行緒併發。

55.. 廣播和有序廣播(優先順序)區別?
有序廣播可以設定優先順序來優先獲取廣播(intentFilter.setPriority()),而且能夠把處理結果傳遞給下一個廣播優先順序接受者setResultExtras(Bundle bundle)/getResultExtras(Bundle bundle),也可以終止廣播傳播abortBroadcast()。
http://www.cnblogs.com/codingblock/p/4856559.html

56.. java裡的鎖有哪些?
synchronized, Lock(ReadWriteLock, ReentrantLock)

58.. onSaveInstanceState什麼時候觸發?在onstop之前嗎?
在Activity可能被系統殺掉的情況下觸發,1. 按Home鍵 2. 鎖屏 3. 螢幕旋轉。必然觸發,而且在onPause之後,和onStop之前。並且其中只有螢幕旋轉肯定會觸發onRestoreInstanceState,因為Activity真的被殺掉重新生成了。

59.. android 中多程序是共用一個Application嗎還是不同的Application?
多程序共用一個Application,因此可能會呼叫多次同一個Application的onCreate,因此可以在onCreate里根據不同的程序名來判斷執行不同的邏輯。