安卓面試小結.

安卓面試小結:

1.Retrofit框架的結構是什麼?底層是怎麼實現的?

簡述:(這裏可能理解不到位,鏈接裏面比較詳細)

Retrofit是對okhttp的進一步封裝,它使用的是動態代理的技術,通過掃描註解構造請求體,底層使用okhttp進行網絡請求,利用handler進行異步操作.

底層具體實現 : Retrofit2.0源碼解析


2.網絡框架是如何搭建的?Okhttp的底層實現是什麼,和Retrofit有什麼不同?

(1)Android學習之——自己搭建Http框架(1)

(2)Okhttp流處理底層使用了okio,具體實現推薦看看 OkHttp3源碼分析[綜述]

(3)Rtrofit就是對Okhttp進一步的封裝,請求體通過註解的形式逐步傳入,Rtrofit會自動封裝,底層網絡請求同樣使用的是okhttp,它與Rxjava搭配更靈活.

以上是簡單概括,給個鴻洋大神連接: Retrofit2 完全解析 探索與okhttp之間的關係


3.圖片加載框架Glide,Picasso,Fresco有什麼不同,各自的實現原理是什麼?如何搭建一個網絡框架?

Picasso:Square公司出品.

底層網絡請求使用的是okhttp.  

優點:體積小,使用簡單.圖片默認RGB_8888

尺寸大,不支持gif,對大圖片加載不方便.它底層實現就是對Handler進行的高效封裝。

Gilde:Google出品.

使用方法和picasso十分相像,支持gif,默認尺寸RGB_565.體積比Picasso大。

Fresco:Facebook出品

(1)使用的是android的匿名共享內存,不佔用虛擬機內存,節約應用內存使用,避免oom,減少bitmap回收提高應用性能

(2)支持圖片漸進加載

(3)可以設置圖片任意一點爲中心

(4)圖片展示操作在native中,不在虛擬機避免oom

(5)支持gif

不足之處只能使用固定的控件SimpleDraweeView,體積太大

網絡框架的搭建(講道理我也沒搞過)

若使用現有的api那就簡單了(相當於二次封裝)還是上連接吧 Android學習之——自己搭建Http框架(1)


4.冒泡 選擇 插入 快速基本算法的實現,單鏈表,雙鏈表,二叉樹,隊列數據結構的實現思路是什麼?

冒泡:


選擇:


插入:


快速:


(下面的是個人理解)

單鏈表,雙鏈表,二叉樹,不借助其它的工具類實現.由於java沒有指針這個東西,我們可以搞一個對象:

單鏈表:p.next(p);

雙鏈表:p.front(p); p.next(p);

二叉樹:p.front(p); p.left(p); p.right(p);

類似上面這種形式,當然也可以藉助LinkedhashMap這類的集合類


5.如何實現跨進程通信,什麼事AIDL,IPC機制,Binder機制的實現的原理

語言表達不行直接上超鏈接:

(1)AIDL,廣播,Content Provider,訪問其他應用程序的Activity

(2)AIDL : Android:學習AIDL,這一篇文章就夠了(上)

                   Android:學習AIDL,這一篇文章就夠了(下)

小Demo :  安卓漫漫路之AIDL傳遞簡單數據. 

(3)IPC  :  Android開發藝術探索 第2章 IPC機制 讀書筆記

(4)Binder :  Binder 牌膠水


6.三級緩存的底層實現?

(1)內存緩存

內存大小爲應用內存大小的1/8, 底層使用的是LruCache,最近最最少使用算法,使用的是雙向鏈表的數據結構(LinkedHashMap). 即最常使用的和新插入的數據會保存在鏈表頭部,不常使用的數據會在鏈表尾部.若鏈表存滿則刪除鏈表尾部最後的元素,在頭部插入新元素.

(2)本地緩存

底層使用的是DiskLruCache同爲最近最最少使用算,也是是雙向鏈表的數據結構(LinkedHashMap)同上.

(3)網絡緩存

在服務端進行的緩存,若客戶端無內存緩存,本地緩存則請求網絡,若服務器有緩存則直接返回緩存數據,未緩存,則直接返回請求數據並緩存.

三級緩存順序:

內存緩存->本地緩存->網絡緩存

l  發送網絡請求前先驗證內存緩存是否有緩存數據 , 有則直接從內存中取,否則驗證本地緩存。

l  內存緩存無緩存數據,驗證本地緩存,本地緩存有則取出本地緩存數據,並緩存進內存緩存。若無緩存則請求網絡。

l  本地緩存無緩存數據則通過網絡請求服務器,並將換回的數據緩存到內存和本地


7.通過開源框架的源碼分析如ButterKnife,EventBus,GreenDao,Ormlite,Dragger2,實現原理是什麼?

都是使用註解的形式來獲取對象,但是不同於後端J2ee註解。它們不屬於運行時註解,而是編譯型註解,即他們在App編譯時會通過掃描註解生成相關的代碼。實際上就是通過註解幫我們自動生成了相關代碼,例如ButterKnife我們通過向註解中傳入控件id就可以獲取到控件的實例,其實是ButterKnife幫我們做了findViewById的工作,這些代碼會在編譯時生成不會寫入到class。而運行時註解則是在軟件運行時通過反射拿到註解,這樣的耗時操作會影響軟件速度如xutils。

(這裏是個人理解,不對請您指正 )


8.HashMap底層實現,它和LinkHashMap有什麼區別?

hashMap底層是哈希表數據結構,允許存入null鍵null值,該集合是不同步的,將hashtable替代。

LinkhashMap繼承 hashMap,它具有HashMap的特性,但是它底層是雙向鏈表結構,插入移除元素更加的快速,靈活性比HashMap更強。

AsycTask機制,實現原理:

對Handler高度封裝,避免了手動開闢子線程,實現異步操作。

下面是簡單的AsycTask機制源碼分析:

初始化AsyncTask對象時,內部會得到mWorker和mFuture兩個對象,mWorker是一個callable對象,它裏面主要是對傳入的數據進行操作操作(內部會調用doInBackground(),onProgressUpdate()方法)。mFuture對象傳入了mWorker,mFuture它是一個Runnable接口,這個對象最終會交給線程池,處理mWorker中數據的相關操作。

執行execute()方法時會調用內部的executeOnExecutor(Excutor exec,Params... params)方法,首先內部會先執行onPreExecute()方法。接着執行exec.execute(mFuture),exec是executeOnExecutor的第一個參數,見名知意它就是傳入的線程池變量,它是在Executor類中初始化好的final型變量直接傳入executeOnExecutor方法的,這一步就是將mFuture扔給線程池。接下來會執行mFuture(Runnable)中的run方法,run方法中會調用Sync內部類的innerRun()方法,裏面會執行callable.call()就是mWorker的call方法,call方法中會調用postResult(doInBackground()),在進入這個方法就會發現它裏面就是通過handler將doInBackground()的結果發送到主線程,由InternalHandler接收,若結果爲MESSAGE_POST_RESULT執行onPostExecute()並關閉AsyncTask任務。若爲MESSAGE_POST_PROGRESS則執行onProgressUpdate()方法,只有在doInBackground()方法中調用publishProgress()方法纔會有MESSAGE_POST_PROGRESS這個結果,onProgressUpdate()方法纔會接收到數據。

以上分析的是3.0版本以後的源碼,和3.0之前區別是:

3.0之前:

只能同時執行5個線程,線程池大小爲128,若達到5個線程,開啓第6個線程則會進入等待隊列,當線程數量超過128個時直接崩潰

3.0之後

默認的線程池,同時只能執行1個線程。但是這個線程池可自定義,就是說自定義可以同時執行n條線程,大小爲m。n,m並不是越大越好。比3.0之前固定的線程池更靈活。

弊端:

 容易內存泄漏,例如下載一個文件,有進度顯示,在下載未下載完畢直接退出Activity的話AsyncTask並不會關閉任務,這樣一來就會導致Activity得不到釋放。就是它不方便關閉。


9.Handler消息機制,postDelayed會造成線程阻塞嗎?對內存有什麼影響?

上圖:


不管在主線程還是在子線程想要通過handler發送消息必須要有Looper對象,在子線程中可通過Looper.prepare()獲取,而在主線程中默認會被創建這個不用操心,爲什麼請百度Activity的源代碼。

在條件都滿足的情況下由handler發送消息,經過一系列的函數最終會進入到sendMessageAtTime()這個函數,說白了這個函數就是構建MssageQueue這個消息池,通過時間排序。之後就是我們的Looper對象了,它內部有一個死循環,在死循環內部有一個dispatchMessage()方法(屬於handler的方法),這個方法就是根據時間順序分發MssageQueue中的消息,也就是調用handleMessage()方法。

以上是粗略分析,詳情還要看源代碼。


10.Debug和Release狀態的區別?

  鏈接:Android簽名詳解(debug和release)

debug簽名和release簽名的區別:

1)debug簽名的應用程序不能在Android Market上架銷售,它會強制你使用自己的簽名;Debug模式下簽名用的證書(默認是Eclipse/ADT和Ant編譯)自從它創建之日起,1年後就會失效。

2)debug.keystore在不同的機器上所生成的可能都不一樣,就意味着如果你換了機器進行apk版本升級,那麼將會出現上面那種程序不能覆蓋安裝的問題,相當於軟件不具備升級功能!


如有問題請多指正,您的指正使我更正確的前行.



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章