前言
借此空閑時間整理下部分面試相關(guān)的題目答案當做筆記記錄下,同時分享給各位同學學習。答案結(jié)合各大相關(guān)書籍網(wǎng)絡知識匯總總結(jié),如有欠缺缺漏的地方還請見諒。烏拉~!
1.Activity生命周期
onCreate()、onStart()、onResume()、onPause()、onStop()、onRestart()、onDestroy()
2.Android四大組件
Activity、Service、BroadcastReceiver、ContentProvider
3.五種常用布局
ConstraintLayout(約束)、LinearLayout(線性)、RelativeLayout(相對)、FrameLayout(幀布局)、GridLayout(網(wǎng)格)
4.Activity四種啟動模式、解釋含義、生命周期的影響
Standard(標準模式)、SingleTop(棧頂復用模式)、SingleTask(棧內(nèi)復用模式) 、SingleInstance(單實例模式)
- Standard: 每次啟動一個Activity都會又一次創(chuàng)建一個新的實例入棧,無論這個實例是否存在。
生命周期: onCreate、onStart、onResume都會被調(diào)用 - SingleTop: Activity處于棧頂時,會直接復用棧頂?shù)腁ctivity,不會再創(chuàng)建新的Activity;若須要創(chuàng)建的Activity不處于棧頂,此時會又一次創(chuàng)建一個新的Activity入棧,同Standard。
生命周期: 棧頂被直接復用時,onCreate、onStart不會執(zhí)行,因為它并沒有發(fā)生改變。但是一個新的方法 onNewIntent會被回調(diào)(正常創(chuàng)建Activity時不會回調(diào)此方法)。 - SingleTask: Activity已經(jīng)處于棧中時,不會創(chuàng)建新的Activity,而是將存在棧中的Activity上面的其他Activity所有銷毀,移除出棧,使它成為棧頂。
生命周期: 同SingleTop 模式 - SingleInstance: 全局單例模式,加強的SingleTask。具有此模式的Activity僅僅能單獨位于一個任務棧中,只要啟動過就不再啟動。
生命周期: 觸發(fā)后onNewIntent()、onRestart()、onStart()、onResume()
(舉例SingleTask的一個運用: 用戶在主界面跳轉(zhuǎn)到其他頁面,運行多次操作后想返回到主頁)
5.Service啟動方式、區(qū)別及其生命周期
- startService: onCreate()--->onStartCommand() --->onDestroy()
- bindService: onCreate()--->onBind() --->onUnbind()--->onDestroy()
區(qū)別: - startService是調(diào)用service的 onCreate方法
bindService是調(diào)用service的 onBind方法 - startService多次只觸發(fā)一次onCreate回調(diào),但是會觸發(fā)了多次onStartCommand回調(diào)
bindService會自動去查找該服務是否啟動,如果沒有會走startService的啟動邏輯 - startService啟動的service需要stopService或者stopSelf進行停止
bindService啟動的service需要通過unBindService才能停止
如果先調(diào)用startService再調(diào)用bindService需要先stopService或者stopSelf再unBindService才能停止
6.說一下onStartCommand()函數(shù)返回的幾種狀態(tài)
START_NOT_STICKY、START_STICKY、START_REDELIVER_INTENT
7.BroadcastReceiver它的使用方式、類型和機制
廣播的方式為靜態(tài)(常駐)和動態(tài)(非常駐),sendBroadcast()、sendOrderedBroadcast()、sendStickyBroadcast();類型分為本地和全局廣播;機制分為 有序和無序
(一般不會問得這么淺顯易懂,還需要自己理解問題)
8.解釋下無序和有序
- 無序廣播: 所有的接收者都會接收事件,不可以被攔截,不可以被修改
- 有序廣播: 按照優(yōu)先級,一級一級的向下傳遞,接收者可以修改廣播數(shù)據(jù),也可以終止廣播事件
9.什么是ContentProvider和ContentResolver
- ContentProvider: 四大組件之一,主要用于不同的應用程序之間實現(xiàn)數(shù)據(jù)共享功能
- ContentResolver: 是數(shù)據(jù)調(diào)用者,ContentProvider將數(shù)據(jù)發(fā)布出來,通過ContentResolver對象結(jié)合Uri進行調(diào)用,通過ContentResolver對象可以調(diào)用ContentProvider的增刪改查
10.Android的數(shù)據(jù)存儲方式有哪些
- SharedPreferences
- 文件存儲
- SQLite數(shù)據(jù)庫
- ContentProvider
- 網(wǎng)絡存儲
11.什么是AIDL
全稱Android Interface Definition Language(接口定義語言),是用于定義服務器和客戶端通信接口的一種描述語言,用來實現(xiàn)進程間通信。一般分為服務和客戶兩端,調(diào)用AILD函數(shù)的應用稱為客戶端,提供AIDL函數(shù)的為服務端,客戶端通過綁定服務端的Service來進行交互
12.自定義View繪制流程
onMeasure()(測量)、onLayout()(位置)、onDraw()(繪制)
13.自定義view步驟
- 自定義View屬性(attrs)
- 構(gòu)造方法中獲得自定義的屬性
- 重寫onMesure
- 重寫onDraw
14.LinearLayout和RelativeLayout哪個繪制性能好一點
兩種使用都可以,非要說的有區(qū)別,那就是weight權(quán)重上有區(qū)分,linearlayout設置權(quán)重后會重繪多次(好像是兩次吧,應該在源碼800行左右開始)
15.什么是ANR
全稱Application Not Responding。5s內(nèi)無法響應用戶輸入事件(例如鍵盤輸入, 觸摸屏幕等),主線程阻塞,超過相應閥值則會觸發(fā)ANR異常。不要在主線程(UI線程)里面做繁重的操作
16.什么是OOM
俗稱內(nèi)存溢出,內(nèi)存占有量超過了VM所分配的最大值,虛擬機無法滿足。Android系統(tǒng)的APP每個進程或者虛擬機有最大內(nèi)存限制,一旦超過這個限制系統(tǒng)就會拋出OOM錯誤
17.那如何避免OOM
- 動態(tài)回收內(nèi)存,不用的對象設置為null,對象引用使用軟引用,如Handler
- 優(yōu)化Dalvik虛擬機的堆內(nèi)存分配
- 自定義堆內(nèi)存大小
- 避免使用Enum(枚舉)
- 使用軟引用的圖片資源,并且適當壓縮大小,如邊界壓縮
- 使用更小的圖片,減少Bitmap對象的內(nèi)存占用,不用的圖片直接recycle
- 使用更加輕量的數(shù)據(jù)結(jié)構(gòu)(SparseArray)
18.內(nèi)存泄露與內(nèi)存溢出的區(qū)別
- 內(nèi)存溢出: Android系統(tǒng)會給每個APP分配內(nèi)存,默認16M內(nèi)存,每個廠商的默認值不一樣,內(nèi)存占有量超過了系統(tǒng)分配的內(nèi)存,就會造成內(nèi)存溢出
- 內(nèi)存泄露: 對象回收不及時,當一個對象不再使用了,本應該被GC回收,但是這個對象由于被其他正在使用的對象所持有,造成無法被回收,導致一部分內(nèi)存一直被占有(長時間持有)。
- 兩者關(guān)聯(lián): 內(nèi)存泄露過多會導致內(nèi)存溢出
19.簡要說明HashMap原理
底層基于數(shù)組和鏈表,Hash表的Map實現(xiàn), Hash表就是Hash數(shù)組,Map實現(xiàn)是指實現(xiàn)了Map接口。主要是通過key的hashCode來計算hash值的。
(只要hashCode相同,計算出來的hash值就一樣 (面試的時候這句話可以不要說,但是要知道。因為這可能會有個hash沖突的提問,切記言多必失) )
20.概括下HashMap與HashTable的區(qū)別
- Hashtable是線程安全,HashMap是非線程安全,HashMap的性能會高于Hashtable
- HashMap可以使用null作為key,不過建議還是盡量避免這樣使用。HashMap以null作為key- 時,總是存儲在table數(shù)組的第一個節(jié)點上。而Hashtable則不允許null作為key
- HashMap繼承了AbstractMap,HashTable繼承Dictionary抽象類,兩者均實現(xiàn)Map接口
- HashMap的初始容量為16,Hashtable初始容量為11,兩者的填充因子默認都是0.75
- HashMap擴容時是當前容量翻倍即:2n,Hashtable擴容時是容量翻倍+1即:2n+1
- HashMap和Hashtable的底層實現(xiàn)都是數(shù)組+鏈表結(jié)構(gòu)實現(xiàn)
兩者計算hash的方法不同: - HashMap計算hash對key的hashcode進行了二次hash,以獲得更好的散列值,然后對table數(shù)組長度取摸
- Hashtable計算hash是直接使用key的hashcode對table數(shù)組的長度直接進行取模
(這里建議以上7條必須全部背過,不用一字不差,至少了解大概)
21.概括說明下TreeMap
- TreeMap繼承于AbstractMap,實現(xiàn)NavigableMap>>SortMap接口, 是一個有序的key-value集合,其底層數(shù)據(jù)結(jié)構(gòu)為紅黑樹,基于紅黑樹實現(xiàn)
- TreeMap支持克隆
- TreeMap支持序列化
- TreeMap取出來的是排序后的鍵值對。
- TreeMap是非同步的
- Iterator 方法返回的迭代器是fail-fastl的(不允許在遍歷的過程中對容器中的數(shù)據(jù)進行修改)
- 使用默認排序或者根據(jù)提供的 Comparator 進行排序,具體取決于使用的構(gòu)造方法
22.Android有哪幾種多線程方式
- Activity.runOnUiThread(Runnable)
- View.post(Runnable) ;
View.postDelay(Runnable , long) - Handler
- AsyncTask
23.在OnCreate中開啟一個Thread更新UI會怎樣
不會崩潰,正常更新顯示。因為這個階段ViewRootImpl還沒生成,不會檢查是否在主線程。
24.簡要說下你對Handler的理解
- 一個消息傳遞機制,在android里負責發(fā)送和處理消息
- Looper負責管理線程的消息隊列和消息循環(huán)
- Message是線程間通訊的消息載體
- MessageQueue是消息隊列,先進先出,保存有待線程處理的消息
- 它的目的就是將工作線程中需更新UI的操作信息 傳遞到 UI主線程,保證線程安全。
一般在在子線程中需要刷新UI時使用Handler
25.SharedPreferences中的commit與apply區(qū)別
- commit()方法有返回值,apply()方法沒有
- commit()方法是同步執(zhí)行,apply()方法是異步執(zhí)行
- commit是同步的提交到硬件磁盤,apply提交到內(nèi)存, 而后異步才提交到硬件磁盤
26.Get與Post區(qū)別
- Get是從服務器上獲取數(shù)據(jù),Post是向服務器傳送數(shù)據(jù)
- Get是把參數(shù)數(shù)據(jù)隊列加到提交表單的ACTION屬性所指的URL中,值和表單內(nèi)各個字段一 一對應,在URL中可以看到。Post是通過HTTP Post機制,將表單內(nèi)各個字段與其內(nèi)容放置在HTML HEADER內(nèi)一起傳送到ACTION屬性所指的URL地址。用戶看不到這個過程。
- Get傳送的數(shù)據(jù)量較小,不能大于2KB。Post傳送的數(shù)據(jù)量較大,一般被默認為不受限制
- Get安全性非常低,Post安全性較高。但是執(zhí)行效率卻比Post方法好
27.MVP的理解
- MVP 全稱是Model - View - Presenter ,是模型(model)-視圖(view)-協(xié)調(diào)器(presenter)的縮寫。
- Moder:業(yè)務邏輯和數(shù)據(jù)處理(數(shù)據(jù)庫存儲,網(wǎng)絡請求,耗時操作)
- View : 負責View的繪制以及與用戶交互,處理用戶事件和視圖部分的展示
- Presenter:負責完成View于Model間的交互,View和Modelde的橋梁
業(yè)務邏輯抽離到Presenter層,View層專注于UI的處理 - 分離視圖邏輯與業(yè)務邏輯,達到解耦的目。
- 提高代碼的閱讀性
- Presenter被抽象成接口,可以根據(jù)Presenter的實現(xiàn)方式進行單元測試
- 可拓展性強
- MVP中Model和View之間的沒有任何聯(lián)系,是兩個完全獨立的模塊,當Model模型發(fā)生數(shù)據(jù)改變時,通過Presenter通知View視圖發(fā)生相應的UI改變
28.Fragment生命周期
onAttach()、onCreate()、onCreateView()、onActivityCreated()、onStart()、onResume()、onPause()、onStop()、onDestroyView()、onDestroy()、onDetach()
29.Activity和Fragment之間如何通信?
事務傳遞、接口傳遞、通過getActivity()方法來獲得Activity的實例,可以調(diào)用一些例如findViewById()之類的方法。
30.Fragment和FragmentActivity之間的區(qū)別?
- FragmentActivity 繼承自Activity,用來解決Android 3.0之前無法使用Fragment的問題,使用時需要導入v4包,同時繼承 FragmentActivity
- Android 3.0之后直接繼承自Activity,并且在其中嵌入使用Fragment。
- 獲得FragmentManager的方式也不同
Android 3.0以下:getSupportFragmentManager()
Android 3.0以上:getFragmentManager()
31.事件分發(fā)
事件分發(fā)順序: Activity(Window) -> ViewGroup -> View
主要方法dispatchTouchEvent() 、onInterceptTouchEvent()和onTouchEvent()
super:調(diào)用父類方法
true:消費事件,即事件不繼續(xù)往下傳遞
false:不消費事件,事件繼續(xù)往下傳遞 / 交由給父控件onTouchEvent()處理
32.ScrollView嵌套ListView產(chǎn)生的問題
ListView高度顯示問題,只顯示一個item,解決辦法是ListView重寫onMeasure()方法,設置屬性為AT_MOST,同時ScrollView在xml中增加屬性
android:focusable="true"
android:focusableInTouchMode="true"
滑動沖突問題,達成效果焦點在ListView時滑動ListView,焦點在ScrollView時滑動ScrollView
設置ListView OnTouchListener監(jiān)聽
listView.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View arg0, MotionEvent arg1) {
scrollView.requestDisallowInterceptTouchEvent(true);
return false;
}});
33.裝飾器模式、代理模式有什么區(qū)別?
代理模式也叫委托模式,是結(jié)構(gòu)型設計模式。為其他對象提供一種代理以控制對這個對象的訪問。當一個對象不能或者不想直接訪問另一個對象時,可以通過一個代理對象來間接訪問
被訪問的對象不想暴露全部內(nèi)容時,可以通過代理去掉不想被訪問的內(nèi)容代理模式: 注重對對象某一功能的流程把控和輔助。它可以控制對象做某些事,重心是為了借用對象的功能完成某一流程,而非對象功能如何
裝飾模式: 注重對對象功能的擴展,它不關(guān)心外界如何調(diào)用,只注重對對象功能的加強,裝飾后還是對象本身
裝飾器模式: 能動態(tài)的新增或組合對象的行為
代理模式: 為其他對象提供一種代理以控制對這個對象的訪問
代理模式:
代理模式中的原類和代理類繼承同一父類;
原類對象與代理類對象接口相同,功能一致;
起到了隱藏原類的作用裝飾者模式:
以對 客戶端透明(客戶端需要指明裝飾的是哪個類)的方式 擴展對象的功能,是繼承關(guān)系的一個替代方案