2019年Android崗位BAT等大廠面試題,但願對新的一年的你有所幫助

2019年Android崗位BAT等大廠面試題知識點小結

2019年了蒐集了不少面試題,但願能對你們有所幫助html

1.View的繪製流程;自定義View如何考慮機型適配;自定義View的事件分發機制;View和ViewGroup分別有哪些事件分發相關的回調方法;自定義View如何提供獲取View屬性的接口。java

 

View的繪製流程:android

流程一:mesarue()過程;面試

流程二:layout佈局過程;算法

流程三:draw()繪圖過程。segmentfault

詳情:http://blog.csdn.net/qinjuning/article/details/7110211/緩存

 

自定義View如何考慮機型適配:網絡

這篇博文解決了Android適配的絕大多數問題:數據結構

http://blog.csdn.net/zhaokaiqiang1992/article/details/45419023app

 

自定義View的事件分發機制:

對於 dispatchTouchEvent,onTouchEvent,return true是終結事件傳遞。return false 是回溯到父View的onTouchEvent方法。

ViewGroup 想把本身分發給本身的onTouchEvent,須要攔截器onInterceptTouchEvent方法return true 把事件攔截下來。

ViewGroup 的攔截器onInterceptTouchEvent 默認是不攔截的,因此return super.onInterceptTouchEvent()=return false;

View 沒有攔截器,爲了讓View能夠把事件分發給本身的onTouchEvent,View的dispatchTouchEvent默認實現(super)就是把事件分發給本身的onTouchEvent。

對於ACTION_MOVE、ACTION_UP總結:ACTION_DOWN事件在哪一個控件消費了(return true), 那麼ACTION_MOVE和ACTION_UP就會從上往下(經過dispatchTouchEvent)作事件分發往下傳,就只會傳到這個控件,不會繼續往下傳,若是ACTION_DOWN事件是在dispatchTouchEvent消費,那麼事件到此爲止中止傳遞,若是ACTION_DOWN事件是在onTouchEvent消費的,那麼會把ACTION_MOVE或ACTION_UP事件傳給該控件的onTouchEvent處理並結束傳遞。

 

詳情:http://www.jianshu.com/p/e99b5e8bd67b

以及下面這個的第五部分:

http://imtianx.cn/2016/12/17/Android%20View%20%E7%9A%84%E4%BA%8B%E4%BB%B6%E4%BD%93%E7%B3%BB/

 

View和ViewGroup分別有哪些事件分發相關的回調方法:

View中跟事件分發機制有關的就是兩個方法:dispatchTouchEvent和onTouchEvent。整個View的事件轉發流程是:

View.dispatchEvent->View.setOnTouchListener->View.onTouchEvent

在dispatchTouchEvent中會進行OnTouchListener的判斷,若是OnTouchListener不爲null且返回true,則表示事件被消費,onTouchEvent不會被執行;不然執行onTouchEvent。

 

對於ViewGroup中的分發事件:

若是ViewGroup找到了可以處理該事件的View,則直接交給子View處理,本身的onTouchEvent不會被觸發;

能夠經過複寫onInterceptTouchEvent(ev)方法,攔截子View的事件(即return true),把事件交給本身處理,則會執行本身對應的onTouchEvent方法

子View能夠經過調用getParent().requestDisallowInterceptTouchEvent(true); 阻止ViewGroup對其MOVE或者UP事件進行攔截;

詳情:http://blog.csdn.net/lmj623565791/article/details/38960443

http://blog.csdn.net/lmj623565791/article/details/39102591

 

自定義View如何提供獲取View屬性的接口:

關於View所要具有的通常功能,View類中都有了基本的實現,好比肯定位置,它有layout方法,固然,這個只適用於ViewGroup,實現本身的ViewGroup時,才須要修改該方法。肯定大小,它有onMeasure方法,若是你不滿意默認的確認大小的方法,也能夠本身定義。改變默認的繪製,就覆寫onDraw方法。

詳情:http://www.jianshu.com/p/d507e3514b65

 

2.Art和Dalvik對比;虛擬機原理,如何本身設計一個虛擬機(內存管理,類加載,雙親委派);JVM內存模型及類加載機制;內存對象的循環引用及避免

 

Art和Dalvik對比:

Dalvik是Google公司本身設計用於Android平臺的虛擬機。

ART即Android Runtime

Dalvik和ART的幾點區別:

dalvik是執行的時候編譯+運行,安裝比較快,開啓應用比較慢,應用佔用空間小

ART是安裝的時候就編譯好了,執行的時候直接就能夠運行的,安裝慢,開啓應用快,佔用空間大

用個比喻來講就是,騎自行車

dalvik 是已經摺疊起來的自行車,每次騎都要先組裝自行車才能騎

ART 是已經組裝好的自行車,每次騎直接上車就能走人

詳情:http://www.jb51.net/article/88708.htm

 

虛擬機原理,如何本身設計一個虛擬機(內存管理,類加載,雙親委派):

在加載階段,java虛擬機須要完成如下3件事:

a.經過一個類的全限定名來獲取定義此類的二進制字節流。

b.將定義類的二進制字節流所表明的靜態存儲結構轉換爲方法區的運行時數據結構。

c.在java堆中生成一個表明該類的java.lang.Class對象,做爲方法區數據的訪問入口。

 

類加載:

從類被加載到虛擬機內存中開始,到卸載出內存爲止,類的生命週期包括加載(Loading)、驗證(Verification)、準備(Preparation)、解析(Resolution)、初始化(Initialization)、使用(Using)和卸載(Unloading)7個階段

 

雙親委派:

系統提供的類加載器主要有下面3個:

.啓動類加載器(Bootstarp ClassLoader)

.擴展類加載器(Extension ClassLoader)

.應用程序類加載器(Application ClassLoader)

注意:上述三個JDK提供的類加載器雖然是父子類加載器關係,可是沒有使用繼承,而是使用了組合關係。

詳情:http://blog.csdn.net/ochangwen/article/details/51473120

http://blog.csdn.net/ochangwen/article/details/51472311

 

JVM內存模型及類加載機制:

JVM要想執行class文件,首先會將文件載入虛擬機的方法區內,根據類文件的格式相應的存放數據。在須要產生對象時,從方法區中獲取對應的類信息,在堆中創建對象。

詳情:http://blog.csdn.net/dragon_cat_han/article/details/52150955

 

內存對象的循環引用及避免:

若是有兩個或者以上的對象,它們彼此引用,就會形成循環引用。

避免:引用計數GC處理,引用遍歷GC處理。

詳情:http://www.wtoutiao.com/p/11elsk6.html

 

3.內存回收機制與GC算法(各類算法的優缺點以及應用場景);GC原理時機以及GC對象;內存泄露場景及解決方法;OOM的避免及解決方法 

 

內存回收機制與GC算法(各類算法的優缺點以及應用場景):

GC是經過對象是否存活來決定是否進行回收,最經常使用的斷定算法是引用計數算法以及Java中使用的斷定算法爲根搜索算法(GC Roots Tracing)

經常使用的垃圾收集算法

a、標記——清除算法(Mark——Sweep)

首先標記出全部須要回收的對象,在標記完成後統一回收掉全部被標記的對象。

缺點:效率問題,標記和清除過程的效率不高;

b、複製算法(Copying)

爲了解決標記清除算法的效率問題,複製算法將可用的內存按容量劃分爲大小相等的兩塊,每次只使用其中的一塊。當這一塊的內存用完了,就將還存活的對象複製到另外一塊上,而後再把已使用過的內存空間一次清理掉。

優勢:實現簡單,運行高效

缺點:對內存空間的利用不高,可用內存變成一半,這代價太高

c、標記——整理算法(Mark——Compact)

與標記清除算法的標記階段相同,但標記後會將全部存活的對象向一端移動,而後直接清理掉端邊界之外的內存。這種算法通常用於老年代的內存回收上,由於老年代中對象的存活時間都比較長,可能存在100%存活的極端狀況,所以不能選擇Copying算法來進行回收。

d、分代收集算法(Generational Collection)

這種算法只是根據對象的存活週期的不一樣將內存劃分爲幾塊,通常都劃分爲新生代和老年代,這樣能夠根據各個年代的特色採用最適當的收集算法。新生代中,每次垃圾收集時都發現有大批對象死去,只有少許存活,所以選取複製算法,只須要付出少許存活對象的複製成本就能夠完成收集;老年代中由於對象存活率高,沒有額外的空間對它進行分配擔保,就必須使用「標記——清除」或是「標記——整理」算法來進行回收。在以前的三種算法中已經有所描述。

 

詳情:http://www.open-open.com/lib/view/open1380593930103.html

 

GC原理時機以及GC對象:

JVM 分別對新生代和舊生代採用不一樣的垃圾回收機制

Java中那些不可達的對象就會變成垃圾。那麼什麼叫作不可達?其實就是沒有辦法再引用到該對象了。主要有如下狀況使對象變爲垃圾:

1.對非線程的對象來講,全部的活動線程都不能訪問該對象,那麼該對象就會變爲垃圾。

2.對線程對象來講,知足上面的條件,且線程未啓動或者已中止。

GC將負責回收全部「不可達」對象的內存空間。

 

詳情:https://segmentfault.com/a/1190000002579346

 

內存泄露場景及解決方法:

由於靜態變量形成的內存泄漏;

Handler 的錯誤使用;

非靜態內部類的靜態實例的錯誤使用;

不正確使用線程,形成內存泄漏;

資源沒有及時關閉;

 

詳情例子解決方案參見:http://blog.csdn.net/adrian24/article/details/53248255

或者http://www.jianshu.com/p/51072faadf51

 

OOM的避免及解決方法:

高效加載大圖片:

在展現高分辨率圖片的時候,最好先將圖片進行壓縮。壓縮後的圖片大小應該和用來展現它的控件大小相近,在一個很小的ImageView上顯示一張超大的圖片不會帶來任何視覺上的好處,但卻會佔用咱們至關多寶貴的內存,並且在性能上還可能會帶來負面影響。下面咱們就來看一看,如何對一張大圖片進行適當的壓縮,讓它可以以最佳大小顯示的同時,還能防止OOM的出現。

使用圖片緩存技術:

內存緩存技術對那些大量佔用應用程序寶貴內存的圖片提供了快速訪問的方法。其中最核心的類是LruCache (此類在android-support-v4的包中提供) 。這個類很是適合用來緩存圖片,它的主要算法原理是把最近使用的對象用強引用存儲在 LinkedHashMap 中,而且把最近最少使用的對象在緩存值達到預設定值以前從內存中移除。

 

詳情:http://blog.csdn.net/guolin_blog/article/details/9316683

 

4.四大組件及生命週期;ContentProvider的權限管理(讀寫分離,權限控制-精確到表級,URL控制);Activity的四種啓動模式對比;Activity狀態保存於恢復

都是一些基礎知識,詳情歸類下:

Activity:詳細知識:http://blog.csdn.net/amazing7/article/details/51244219

Service:詳細知識:http://blog.csdn.net/amazing7/article/details/51305911

ContentProvider:詳細知識:http://blog.csdn.net/amazing7/article/details/51324022

BroadcastReceiver:詳細知識:http://blog.csdn.net/amazing7/article/details/51352139

ContentProvider的權限管理:http://blog.csdn.net/robertcpp/article/details/51337891

Activity的四種啓動模式對比:http://blog.csdn.net/knlnzhao/article/details/8005277

Activity狀態保存於恢復:http://blog.csdn.net/js331455217/article/details/40930157

 

5.Fragment生命週期;Fragment狀態保存

生命週期及相關:http://blog.csdn.net/amazing7/article/details/51282082

狀態保存:http://www.jianshu.com/p/75dc2f51cd63

 

6.startActivityForResult是哪一個類的方法,在什麼狀況下使用,若是在Adapter中使用應該如何解耦

startActivityForResult是Activity類裏的方法,在原Activity裏經過Intent跳轉到其餘類再跳回到原Activity裏時候,回傳數據所用

詳情:http://blog.csdn.net/sunchaoenter/article/details/6612039

 

在Adapter以及其餘非Activity類使用的時候,能夠將由原Activity類傳入的Context強轉爲Activity類,再在原Activity裏重寫onActivityResult方法接受到返回值。

 

7.AsyncTask原理及不足;IntentService原理

AsyncTask是一個輕量級的異步類,繼承時候有三個泛型參數:

1. Params,在執行AsyncTask時須要傳入的參數,可用於在後臺任務中使用;

2. Progress,後臺任務執行時,若是須要在界面上顯示當前的進度,則使用這裏指定的泛型做爲進度單位;

3. Result,當任務執行完畢後,若是須要對結果進行返回,則使用這裏指定的泛型做爲返回值類型。

須要重寫四個方法(至少是2個,2和4):

1. onPreExecute(),這個方法會在後臺任務開始執行之間調用,用於進行一些界面上的初始化操做,好比顯示一個進度條對話框等。

2. doInBackground(Params...),這個方法中的全部代碼都會在子線程中運行,咱們應該在這裏去處理全部的耗時任務。任務一旦完成就能夠經過return語句來將任務的執行結果進行返回,若是AsyncTask的第三個泛型參數指定的是Void,就能夠不返回任務執行結果。注意,在這個方法中是不能夠進行UI操做的,若是須要更新UI元素,好比說反饋當前任務的執行進度,能夠調用publishProgress(Progress...)方法來完成。

3. onProgressUpdate(Progress...),當在後臺任務中調用了publishProgress(Progress...)方法後,這個方法就很快會被調用,方法中攜帶的參數就是在後臺任務中傳遞過來的。在這個方法中能夠對UI進行操做,利用參數中的數值就能夠對界面元素進行相應的更新。

4. onPostExecute(Result),當後臺任務執行完畢並經過return語句進行返回時,這個方法就很快會被調用。返回的數據會做爲參數傳遞到此方法中,能夠利用返回的數據來進行一些UI操做,好比說提醒任務執行的結果,以及關閉掉進度條對話框等。

AnsycTask執行任務時,內部會建立一個進程做用域的線程池來管理要運行的任務,也就就是說當你調用了AsyncTask.execute()後,AsyncTask會把任務交給線程池,由線程池來管理建立Thread和運行Therad,本質上是對Thread+Handler的良好封裝,減小了開發者處理問題的複雜度,提升了開發效率。

AsyncTask缺陷:

最大的缺點:在使用多個異步操做和並須要進行Ui變動時,就變得複雜起來。

其餘的參考下面的文章。

詳情:http://blog.csdn.net/liuhe688/article/details/6532519

http://blog.csdn.net/boyupeng/article/details/49001215

IntentService原理

IntentService是繼承於Service並處理異步請求的一個類,在IntentService內有一個工做線程來處理耗時操做,啓動IntentService的方式和啓動傳統Service同樣,同時,當任務執行完後,IntentService會自動中止,而不須要咱們去手動控制。

詳情:http://blog.csdn.net/qq_18402085/article/details/50753005

http://blog.csdn.net/ryantang03/article/details/8146154/

 

8.AstncTask+HttpClient與AsyncHttpClient有什麼區別

AsyncHttpClient來自android-async-http庫是在Apache的HttpClient庫的基礎上開發構建而成的,這裏的異步,是指它全部的網絡請求都是在app的UI線程以外的獨立工做線程中執行。而開發者經過利用Android的消息處理機制,把咱們所須要編寫的回調函數放在這個回調函數的建立線程中執行(通常就是UI線程),因此使用起來很是方便除了能應用在開發普通App上,還能夠用來開發Service或後臺線程,async-http-client庫能夠自已分辨是被用在哪種應用下,不須要額外的設置。

詳情:https://my.oschina.net/u/725054/blog/494494

http://blog.csdn.net/wangpeng047/article/details/19624529

 

9.如何保證一個後臺服務不被殺死;比較省電的方式是什麼

服務不被殺死分3種來討論

1.系統根據資源分配狀況殺死服務

2.用戶經過 settings -> Apps -> Running -> Stop 方式殺死服務

3.用戶經過 settings -> Apps -> Downloaded -> Force Stop 方式殺死服務

第一種狀況:

用戶不干預,徹底靠系統來控制,辦法有不少。好比 onStartCommand() 方法的返回值設爲 START_STICKY ,服務就會在資源緊張的時候被殺掉,而後在資源足夠的時候再恢復。固然也可設置爲前臺服務,使其有高的優先級,在資源緊張的時候也不會被殺掉。

第二種狀況:

用戶干預,主動殺掉運行中的服務。這個過程殺死服務會經過服務的生命週期,也就是會調用 onDestory() 方法,這時候一個方案就是在 onDestory() 中發送廣播開啓本身。這樣殺死服務後會當即啓動。

固然,從理論上來說這個方案是可行的,實驗一下也能夠。但有些狀況下,發送的廣播在消息隊列中排的靠後,就有可能服務還沒接收到廣播就銷燬了(這是我對實驗結果的猜測,具體執行步驟暫時還不瞭解)。因此爲了能讓這個機制完美運行,能夠開啓兩個服務,相互監聽,相互啓動。服務A監聽B的廣播來啓動B,服務B監聽A的廣播來啓動A。通過實驗,這個方案可行,而且用360殺掉後幾秒後服務也仍是能自啓的。到這裏再說一句,若是不是某些功能須要的服務,不建議這麼作,會下降用戶體驗。

第三種狀況:

強制關閉就沒有辦法。這個好像是從包的level去關的,並不走完整的生命週期。因此在服務里加代碼是沒法被調用的。處理這個狀況的惟一方法是屏蔽掉 force stop和 uninstall 按鈕,讓其不可用。方法本身去找吧。固然有些手機自帶的清理功能就是從這個地方清理的,好比華爲的清理。因此第三種狀況我也沒有什麼更好的辦法了。

詳情:http://www.tuicool.com/articles/iu22QnF

 

10.如何經過廣播攔截和abort一條短信;廣播是否能夠請求網絡;廣播引發anr的時間限制

目前找到方法都是適用於Android4.4默認短信應用之前的方法:

第一步:新建一個類繼承BroadcastReceiver,並重寫onReceive()方法.

第二步:訂閱短信的廣播Intent,訂閱方法有兩種:

1:使用代碼進行訂閱

2:在AndroidManifest.xml文件中的<application>節點中進行訂閱

 

在Android中,每次廣播消息到來時都會建立BroadcastReceiver實例並執行onReceive() 方法,

onReceive() 方法執行完後,BroadcastReceiver 的實例就會被銷燬。攔截短信的方法就寫在onReceive() 方法裏便可。

 

詳情:http://blog.csdn.net/jason0539/article/details/11720419

 

廣播能夠監聽網絡狀態,網絡變化等,好像不能請求網絡。

 

在 Android中,程序的響應(Responsive)被活動管理器(Activity Manager)和窗口管理器(Window Manager)這兩個系統服務所監視,當BroadcastReceiver在10秒內沒有執行完畢,Android會認爲該程序無響應,因此在 BroadcastReceiver裏不能作一些比較耗時的操做,不然會彈出ANR(Application No Response)的對話框。若是須要完成一項比較耗時的工做,應該經過發送Intent給Service,由Service來完成,而不是使用子線程的方法來解決,由於BroadcastReceiver的生命週期很短(在onReceive()執行後BroadcastReceiver的實例就會被銷燬),子線程可能尚未結束BroadcastReceiver就先結束了。若是BroadcastReceiver結束了,它的宿主進程還在運行,那麼 子線程還會繼續執行。但宿主進程此時很容易在系統須要內在時被優先殺死。由於它屬於空進程(沒有任何活動組件的進程)。

詳情:http://blog.csdn.net/wufen1103/article/details/7839107

 

11.進程間通訊,AIDL

aidl是 Android Interface definition language的縮寫,一看就明白,它是一種android內部進程通訊接口的描述語言,經過它咱們能夠定義進程間的通訊接口

詳情:http://blog.csdn.net/stonecao/article/details/6425019

 

12.Handler機制及底層實現

詳情:http://www.jianshu.com/p/9e4d1fab0f36

http://blog.csdn.net/itachi85/article/details/8035333

 

13.Binder機制及底層實現

詳情:http://blog.csdn.net/weijinqian0/article/details/52233529

 

14.ApplicationContext和ActivityContext的區別

Context,中文直譯爲「上下文」,它是一個抽象類,描述的是一個應用程序環境的信息,經過它咱們能夠獲取應用程序的資源和類,也包括一些應用級別操做。

應用程序建立Context實例的狀況一共有三種:

一、建立Application 對象時

二、建立Service對象時

三、建立Activity對象時

其中對於ApplicationContext,每一個應用程序在第一次啓動時,都會首先建立Application對象。若是對應用程序啓動一個Activity(startActivity)流程比較清楚的話,建立Application的時機在建立handleBindApplication()方法中,該函數位於 ActivityThread.java類中;

對於ActivityContext,經過startActivity()或startActivityForResult()請求啓動一個Activity時,若是系統檢測須要新建一個Activity對象時,就會回調handleLaunchActivity()方法,該方法繼而調用performLaunchActivity()方法,去建立一個Activity實例,而且回調onCreate(),onStart()方法等, 函數都位於 ActivityThread.java類。

 

 

 

詳情:http://blog.csdn.net/qinjuning/article/details/7310620

 

 https://www.jianshu.com/p/0f89f93c8faf

相關文章
相關標籤/搜索