? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 首先祝大家都能找到中意的工作堰燎!
????????????????????????????????????然后 ? 開始干貨~
JAVA 相關(guān)
1.靜態(tài)內(nèi)部類掏父、內(nèi)部類、匿名內(nèi)部類秆剪,為什么內(nèi)部類會(huì)持有外部類的引用?持有的引用是this?還是其它?
靜態(tài)內(nèi)部類:使用static修飾的內(nèi)部類
內(nèi)部類:就是在某個(gè)類的內(nèi)部又定義了一個(gè)類赊淑,內(nèi)部類所嵌入的類稱為外部類
匿名內(nèi)部類:使用new生成的內(nèi)部類
因?yàn)閮?nèi)部類的產(chǎn)生依賴于外部類爵政,持有的引用是類名.this
2.Java中try catch finally的執(zhí)行順序
先執(zhí)行try中代碼,如果發(fā)生異常執(zhí)行catch中代碼陶缺,最后一定會(huì)執(zhí)行finally中代碼
3.equals與==的區(qū)別:
==是判斷兩個(gè)變量或?qū)嵗遣皇侵赶蛲粋€(gè)內(nèi)存空間 equals是判斷兩個(gè)變量或?qū)嵗赶虻膬?nèi)存空間的值是不是相
4.Object有哪些公用方法?
方法equals測(cè)試的是兩個(gè)對(duì)象是否相等
方法clone進(jìn)行對(duì)象拷貝
方法getClass返回和當(dāng)前對(duì)象相關(guān)的Class對(duì)象
方法notify,notifyall,wait都是用來對(duì)給定對(duì)象進(jìn)行線程同步的
5.String钾挟、StringBuffer與StringBuilder的區(qū)別
String 類型和 StringBuffer 類型的主要性能區(qū)別其實(shí)在于 String 是不可變的對(duì)象
StringBuffer和StringBuilder底層是 char[]數(shù)組實(shí)現(xiàn)的
StringBuffer是線程安全的,而StringBuilder是線程不安全的
6.Java的四種引用的區(qū)別
強(qiáng)引用:如果一個(gè)對(duì)象具有強(qiáng)引用饱岸,它就不會(huì)被垃圾回收器回收掺出。即使當(dāng)前內(nèi)存空間不足,JVM 也不會(huì)回收它苫费,而是拋出 OutOfMemoryError 錯(cuò)誤汤锨,使程序異常終止。如果想中斷強(qiáng)引用和某個(gè)對(duì)象之間的關(guān)聯(lián)百框,可以顯式地將引用賦值為null闲礼,這樣一來的話,JVM在合適的時(shí)間就會(huì)回收該對(duì)象
軟引用:在使用軟引用時(shí)琅翻,如果內(nèi)存的空間足夠位仁,軟引用就能繼續(xù)被使用,而不會(huì)被垃圾回收器回收方椎,只有在內(nèi)存不足時(shí)聂抢,軟引用才會(huì)被垃圾回收器回收。
弱引用:具有弱引用的對(duì)象擁有的生命周期更短暫棠众。因?yàn)楫?dāng) JVM 進(jìn)行垃圾回收琳疏,一旦發(fā)現(xiàn)弱引用對(duì)象,無論當(dāng)前內(nèi)存空間是否充足闸拿,都會(huì)將弱引用回收空盼。不過由于垃圾回收器是一個(gè)優(yōu)先級(jí)較低的線程,所以并不一定能迅速發(fā)現(xiàn)弱引用對(duì)象
虛引用:顧名思義新荤,就是形同虛設(shè)揽趾,如果一個(gè)對(duì)象僅持有虛引用,那么它相當(dāng)于沒有引用苛骨,在任何時(shí)候都可能被垃圾回收器回收篱瞎。
7.介紹垃圾回收機(jī)制
標(biāo)記回收法:遍歷對(duì)象圖并且記錄可到達(dá)的對(duì)象,以便刪除不可到達(dá)的對(duì)象痒芝,一般使用單線程工作并且可能產(chǎn)生內(nèi)存碎片
標(biāo)記-壓縮回收法:前期與第一種方法相同俐筋,只是多了一步,將所有的存活對(duì)象壓縮到內(nèi)存的一端严衬,這樣內(nèi)存碎片就可以合成一大塊可再利用的內(nèi)存區(qū)域澄者,提高了內(nèi)存利用率
復(fù)制回收法:把現(xiàn)有內(nèi)存空間分成兩部分,gc運(yùn)行時(shí),它把可到達(dá)對(duì)象復(fù)制到另一半空間粱挡,再清空正在使用的空間的全部對(duì)象赠幕。這種方法適用于短生存期的對(duì)象,持續(xù)復(fù)制長生存期的對(duì)象則導(dǎo)致效率降低抱怔。
分代回收發(fā):把內(nèi)存空間分為兩個(gè)或者多個(gè)域劣坊,如年輕代和老年代,年輕代的特點(diǎn)是對(duì)象會(huì)很快被回收屈留,因此在年輕代使用效率比較高的算法。當(dāng)一個(gè)對(duì)象經(jīng)過幾次回收后依然存活测蘑,對(duì)象就會(huì)被放入稱為老年的內(nèi)存空間灌危,老年代則采取標(biāo)記-壓縮算法
集合、數(shù)據(jù)結(jié)構(gòu)相關(guān)
1.你用過哪些集合類
數(shù)據(jù)結(jié)構(gòu)中用于存儲(chǔ)數(shù)據(jù)的有哪些
數(shù)組
數(shù)組存儲(chǔ)區(qū)間是連續(xù)的碳胳,占用內(nèi)存嚴(yán)重勇蝙,故空間復(fù)雜的很大。但數(shù)組的二分查找時(shí)間復(fù)雜度小挨约,為O(1);數(shù)組的特點(diǎn)是:尋址容易味混,插入和刪除困難;
鏈表
鏈表存儲(chǔ)區(qū)間離散,占用內(nèi)存比較寬松诫惭,故空間復(fù)雜度很小翁锡,但時(shí)間復(fù)雜度很大则披,達(dá)O(N)陈醒。鏈表的特點(diǎn)是:尋址困難芯侥,插入和刪除容易莲兢。
2.說說hashMap是怎樣實(shí)現(xiàn)的
哈希表:由數(shù)組+鏈表組成的
當(dāng)我們往HashMap中put元素的時(shí)候承璃,先根據(jù)key的hashCode重新計(jì)算hash值迎罗,根據(jù)hash值得到這個(gè)元素在數(shù)組中的位置(即下標(biāo))
如果數(shù)組該位置上已經(jīng)存放有其他元素了杠愧,那么在這個(gè)位置上的元素將以鏈表的形式存放喳钟,新加入的放在鏈頭篮撑,最先加入的放在鏈尾减细。
如果數(shù)組該位置上沒有元素,就直接將該元素放到此數(shù)組中的該位置上赢笨。
3.ArrayList,LinkedList的區(qū)別
ArrayList是實(shí)現(xiàn)了基于動(dòng)態(tài)數(shù)組的數(shù)據(jù)結(jié)構(gòu)未蝌,LinkedList基于鏈表的數(shù)據(jù)結(jié)構(gòu)。
對(duì)于隨機(jī)訪問get和set质欲,ArrayList覺得優(yōu)于LinkedList树埠,因?yàn)長inkedList要移動(dòng)指針。
對(duì)于新增和刪除操作add和remove嘶伟,LinedList比較占優(yōu)勢(shì)怎憋,因?yàn)锳rrayList要移動(dòng)數(shù)據(jù)。
4.ArrayList和Vector的主要區(qū)別是什么?
ArrayList 和Vector底層是采用數(shù)組方式存儲(chǔ)數(shù)據(jù)
Vector:
線程同步
當(dāng)Vector中的元素超過它的初始大小時(shí),Vector會(huì)將它的容量翻倍绊袋,
ArrayList:
線程不同步毕匀,但性能很好
當(dāng)ArrayList中的元素超過它的初始大小時(shí),ArrayList只增加50%的大小
5.HashMap和 HashTable 的區(qū)別:
HashTable比較老癌别,是基于Dictionary 類實(shí)現(xiàn)的皂岔,HashTable 則是基于 Map接口實(shí)現(xiàn)的
HashTable 是線程安全的, HashMap 則是線程不安全的
HashMap可以讓你將空值作為一個(gè)表的條目的key或value
算法相關(guān)
1.排序算法和穩(wěn)定性展姐,快排什么時(shí)候情況最壞?
2.給最外層的rootview躁垛,把這個(gè)根視圖下的全部button背景設(shè)置成紅色,手寫代碼圾笨,不許用遞歸
算法原理:
Android的view視圖是按樹形結(jié)構(gòu)分布教馆,所以按樹形結(jié)構(gòu)遍歷
循環(huán)判斷每一層的ViewGroup元素,將其入棧;否則判斷當(dāng)前view是否是Button類實(shí)例擂达,是則改寫背景色
當(dāng)前ViewGroup檢查childView完成后土铺,判斷棧是否非空,取出棧頂元素ViewGroup重復(fù)步驟2直至棧為空板鬓。
void changeAllBtnBGColor(View view, int color) {if (view == null || !(view instanceof ViewGroup))return; Stack m = new Stack<>();while (view != null) { ViewGroup tmpGroup = (ViewGroup) view; int count = tmpGroup.getChildCount(); for (int i = 0; i < count; i++) { View child = tmpGroup.getChildAt(i);if (child instanceof ViewGroup) m.add(child); else if (child instanceof Button) { child.setBackgroundColor(color);} } if (m.isEmpty()) break; else view = m.pop();} }
Thread悲敷、AsynTask相關(guān)
1.wait()和sleep()的區(qū)別
sleep來自Thread類,和wait來自O(shè)bject類
調(diào)用sleep()方法的過程中俭令,線程不會(huì)釋放對(duì)象鎖后德。而 調(diào)用 wait 方法線程會(huì)釋放對(duì)象鎖
sleep睡眠后不出讓系統(tǒng)資源,wait讓出系統(tǒng)資源其他線程可以占用CPU
sleep(milliseconds)需要指定一個(gè)睡眠時(shí)間唤蔗,時(shí)間一到會(huì)自動(dòng)喚醒
2.若Activity已經(jīng)銷毀探遵,此時(shí)AsynTask執(zhí)行完并且返回結(jié)果,會(huì)報(bào)異常嗎?
當(dāng)一個(gè)App旋轉(zhuǎn)時(shí)妓柜,整個(gè)Activity會(huì)被銷毀和重建箱季。當(dāng)Activity重啟時(shí),AsyncTask中對(duì)該Activity的引用是無效的棍掐,因此onPostExecute()就不會(huì)起作用藏雏,若AsynTask正在執(zhí)行,折會(huì)報(bào) view not attached to window manager 異常
同樣也是生命周期的問題作煌,在 Activity 的onDestory()方法中調(diào)用Asyntask.cancal方法掘殴,讓二者的生命周期同步
3.Activity銷毀但Task如果沒有銷毀掉,當(dāng)Activity重啟時(shí)這個(gè)AsyncTask該如何解決?
還是屏幕旋轉(zhuǎn)這個(gè)例子粟誓,在重建Activity的時(shí)候奏寨,會(huì)回掉Activity.onRetainNonConfigurationInstance()重新傳遞一個(gè)新的對(duì)象給AsyncTask,完成引用的更新
4.Android 線程間通信有哪幾種方式(重要)
共享內(nèi)存(變量);
文件鹰服,數(shù)據(jù)庫;
Handler;
Java 里的 wait()病瞳,notify()揽咕,notifyAll()
5.請(qǐng)介紹下 AsyncTask的內(nèi)部實(shí)現(xiàn),適用的場(chǎng)景是
AsyncTask 內(nèi)部也是 Handler 機(jī)制來完成的套菜,只不過 Android 提供了執(zhí)行框架來提供線程池來
執(zhí)行相應(yīng)地任務(wù)亲善,因?yàn)榫€程池的大小問題,所以 AsyncTask 只應(yīng)該用來執(zhí)行耗時(shí)時(shí)間較短的任務(wù)逗柴,
比如 HTTP 請(qǐng)求蛹头,大規(guī)模的下載和數(shù)據(jù)庫的更改不適用于 AsyncTask,因?yàn)闀?huì)導(dǎo)致線程池堵塞戏溺,沒有
線程來執(zhí)行其他的任務(wù)渣蜗,導(dǎo)致的情形是會(huì)發(fā)生 AsyncTask 根本執(zhí)行不了的問題。
網(wǎng)絡(luò)相關(guān)
1.TCP三次握手2.為什么TCP是可靠的旷祸,UDP早不可靠的?為什么UDP比TCP快?
TCP/IP協(xié)議高袍睡,因?yàn)槠鋼碛腥挝帐蛛p向機(jī)制,這一機(jī)制保證校驗(yàn)了數(shù)據(jù)肋僧,保證了他的可靠性。
UDP就沒有了控淡,udp信息發(fā)出后,不驗(yàn)證是否到達(dá)對(duì)方,所以不可靠嫌吠。
但是就速度來說,還是UDP協(xié)議更高掺炭,畢竟其無需重復(fù)返回驗(yàn)證辫诅,只是一次性的
3.http協(xié)議了解多少,說說里面的協(xié)議頭部有哪些字段?
http(超文本傳輸協(xié)議)是一個(gè)基于請(qǐng)求與響應(yīng)模式的涧狮、無狀態(tài)的炕矮、應(yīng)用層的協(xié)議;http請(qǐng)求由三部分組成,分別是:請(qǐng)求行者冤、消息報(bào)頭肤视、請(qǐng)求正文。
HTTP消息報(bào)頭包括普通報(bào)頭涉枫、請(qǐng)求報(bào)頭邢滑、響應(yīng)報(bào)頭、實(shí)體報(bào)頭
4.https了解多少
HTTPS(全稱:Hyper Text Transfer Protocol over Secure Socket Layer)愿汰,是以安全為目標(biāo)的HTTP通道困后,簡單講是HTTP的安全版。即HTTP下加入SSL層衬廷,HTTPS的安全基礎(chǔ)是SSL摇予,因此加密的詳細(xì)內(nèi)容就需要SSL。
5.談?wù)?HTTP 中Get 和 Post 方法的區(qū)別
GET - 從指定的服務(wù)器中獲取數(shù)據(jù)吗跋,明文發(fā)送內(nèi)容
POST - 提交數(shù)據(jù)給指定的服務(wù)器處理
POST請(qǐng)求不能被緩存下來
POST請(qǐng)求不會(huì)保存在瀏覽器瀏覽記錄中
以POST請(qǐng)求的URL無法保存為瀏覽器書簽
POST請(qǐng)求沒有長度限制
6.推送心跳包是TCP包還是UDP包或者HTTP包
心跳包的實(shí)現(xiàn)是調(diào)用了socket.sendUrgentData(0xFF)這句代碼實(shí)現(xiàn)的侧戴,所以,當(dāng)然是TCP包。
7.如何實(shí)現(xiàn)文件斷點(diǎn)上傳
在 Android 中上傳文件可以采用 HTTP 方式救鲤,也可以采用 Socket 方式久窟,但是 HTTP 方式不能上傳
大文件,這里介紹一種通過 Socket 方式來進(jìn)行斷點(diǎn)續(xù)傳的方式本缠,服務(wù)端會(huì)記錄下文件的上傳進(jìn)度斥扛,
當(dāng)某一次上傳過程意外終止后,下一次可以繼續(xù)上傳丹锹,這里用到的其實(shí)還是 J2SE 里的知識(shí)稀颁。
這個(gè)上傳程序的原理是:客戶端第一次上傳時(shí)向服務(wù)端發(fā)送
“Content-Length=35;filename=WinRAR_3.90_SC.exe;sourceid=“這種格式的字符串,服務(wù)端 收到后會(huì)查找該文件是否有上傳記錄楣黍,如果有就返回已經(jīng)上傳的位置匾灶,否則返回新生成的 sourceid 以及 position 為 0,類似 sourceid=2324838389;position=0“這樣的字符串租漂,客戶端收到返回后 的字符串后再從指定的位置開始上傳文件阶女。
Fragment相關(guān)
1.Fragment 如何實(shí)現(xiàn)類似 Activity 棧的壓棧和出棧效果的?
Fragment 的事物管理器內(nèi)部維持了一個(gè)雙向鏈表結(jié)構(gòu),該結(jié)構(gòu)可以記錄我們每次 add 的
Fragment 和 replace 的 Fragment哩治,然后當(dāng)我們點(diǎn)擊 back 按鈕的時(shí)候會(huì)自動(dòng)幫我們實(shí)現(xiàn)退棧操作秃踩。
2.Fragment 在你們項(xiàng)目中的使用
Fragment 是 android3.0 以后引入的的概念,做局部內(nèi)容更新更方便业筏,原來為了到達(dá)這一點(diǎn)要
把多個(gè)布局放到一個(gè) activity 里面憔杨,現(xiàn)在可以用多 Fragment 來代替,只有在需要的時(shí)候才加載
Fragment蒜胖,提高性能消别。
Fragment 的好處:
Fragment 可以使你能夠?qū)?activity 分離成多個(gè)可重用的組件,每個(gè)都有它自己的生命周期和
UI台谢。
Fragment 可以輕松得創(chuàng)建動(dòng)態(tài)靈活的 UI 設(shè)計(jì)寻狂,可以適應(yīng)于不同的屏幕尺寸。從手機(jī)到平板電
腦对碌。
Fragment 是一個(gè)獨(dú)立的模塊,緊緊地與 activity 綁定在一起荆虱。可以運(yùn)行中動(dòng)態(tài)地移除朽们、加入怀读、
交換等。
Fragment 提供一個(gè)新的方式讓你在不同的安卓設(shè)備上統(tǒng)一你的 UI骑脱。
Fragment 解決 Activity 間的切換不流暢菜枷,輕量切換。
Fragment 替代 TabActivity 做導(dǎo)航叁丧,性能更好啤誊。
Fragment 在 4.2.版本中新增嵌套 fragment 使用方法岳瞭,能夠生成更好的界面效果
3.如何切換 fragement,不重新實(shí)例化
正確的切換方式是 add(),切換時(shí) hide()蚊锹,add()另一個(gè) Fragment;再次切換時(shí)瞳筏,只需 hide()當(dāng)前, show()另一個(gè)
四大組件相關(guān)
1.Activity和Fragment生命周期有哪些?
Activity——onCreate->onStart->onResume->onPause->onStop->onDestroy
Fragment——onAttach->onCreate->onCreateView->onActivityCreated->onStart->onResume->onPause->onStop->onDestroyView->onDestroy->onDetach
2.廣播的兩種注冊(cè)方式及有什么區(qū)別
3.內(nèi)存不足時(shí)牡昆,怎么保持Activity的一些狀態(tài)姚炕,在哪個(gè)方法里面做具體操作?
Activity的 onSaveInstanceState() 和 onRestoreInstanceState()并不是生命周期方法,它們不同于 onCreate()丢烘、onPause()等生命周期方法柱宦,它們并不一定會(huì)被觸發(fā)。當(dāng)應(yīng)用遇到意外情況(如:內(nèi)存不足播瞳、用戶直接按Home鍵)由系統(tǒng)銷毀一個(gè)Activity掸刊,onSaveInstanceState() 會(huì)被調(diào)用。但是當(dāng)用戶主動(dòng)去銷毀一個(gè)Activity時(shí)赢乓,例如在應(yīng)用中按返回鍵忧侧,onSaveInstanceState()就不會(huì)被調(diào)用。除非該activity是被用戶主動(dòng)銷毀的牌芋,通常onSaveInstanceState()只適合用于保存一些臨時(shí)性的狀態(tài)苍柏,而onPause()適合用于數(shù)據(jù)的持久化保存。
4.啟動(dòng)service的兩種方法?有什么區(qū)別?
一種是startService(),另一種是bindService()姜贡。這兩者的區(qū)別是第一種方式調(diào)用者開啟了服務(wù),即會(huì)與服務(wù)失去聯(lián)系棺棵,兩者沒有關(guān)聯(lián)楼咳。即使訪問者退出了,服務(wù)仍在運(yùn)行烛恤。如需解除服務(wù)必須顯式的調(diào)用stopService方法母怜。主要用于調(diào)用者與服務(wù)沒有交互的情況下,也就是調(diào)用者不需要獲取服務(wù)里的業(yè)務(wù)方法缚柏。比如電話錄音苹熏。而后者調(diào)用者與服務(wù)綁定在一起的。當(dāng)調(diào)用者退出的時(shí)候币喧,服務(wù)也隨之退出轨域。用于需要與服務(wù)交互。
5.Android中的Context, Activity杀餐,Appliction有什么區(qū)別?
相同:Activity和Application都是Context的子類干发。
Context從字面上理解就是上下文的意思,在實(shí)際應(yīng)用中它也確實(shí)是起到了管理上下文環(huán)境中各個(gè)參數(shù)和變量的總用史翘,方便我們可以簡單的訪問到各種資源枉长。
不同:維護(hù)的生命周期不同冀续。 Context維護(hù)的是當(dāng)前的Activity的生命周期,Application維護(hù)的是整個(gè)項(xiàng)目的生命周期必峰。
使用context的時(shí)候洪唐,小心內(nèi)存泄露,防止內(nèi)存泄露吼蚁,注意一下幾個(gè)方面:
不要讓生命周期長的對(duì)象引用activity context凭需,即保證引用activity的對(duì)象要與activity本身生命周期是一樣的。
對(duì)于生命周期長的對(duì)象桂敛,可以使用application功炮,context。
避免非靜態(tài)的內(nèi)部類术唬,盡量使用靜態(tài)類薪伏,避免生命周期問題,注意內(nèi)部類對(duì)外部對(duì)象引用導(dǎo)致的生命周期變化粗仓。
6.Context是什么?
它描述的是一個(gè)應(yīng)用程序環(huán)境的信息嫁怀,即上下文。
該類是一個(gè)抽象(abstract class)類借浊,Android提供了該抽象類的具體實(shí)現(xiàn)類(ContextIml)塘淑。
通過它我們可以獲取應(yīng)用程序的資源和類,也包括一些應(yīng)用級(jí)別操作蚂斤,例如:啟動(dòng)一個(gè)Activity存捺,發(fā)送廣播,接受Intent曙蒸,信息捌治,等。
7.Service 是否在 main thread 中執(zhí)行, service 里面是否能執(zhí)行耗時(shí)的操
作?
默認(rèn)情況,如果沒有顯示的指 servic 所運(yùn)行的進(jìn)程, Service 和 activity 是運(yùn)行在當(dāng)前 app 所在進(jìn)
程的 main thread(UI 主線程)里面纽窟。
service 里面不能執(zhí)行耗時(shí)的操作(網(wǎng)絡(luò)請(qǐng)求,拷貝數(shù)據(jù)庫,大文件 )
特殊情況 ,可以在清單文件配置 service 執(zhí)行所在的進(jìn)程 ,讓 service 在另外的進(jìn)程中執(zhí)行
? 1 2 3 4 5?
8.Activity 怎么和 Service 綁定肖油,怎么在 Activity 中啟動(dòng)自己對(duì)應(yīng)的
Service?
Activity 通過 bindService(Intent service, ServiceConnection conn, int flags)跟 Service 進(jìn)行
綁定,當(dāng)綁定成功的時(shí)候 Service 會(huì)將代理對(duì)象通過回調(diào)的形式傳給 conn臂港,這樣我們就拿到了
Service 提供的服務(wù)代理對(duì)象森枪。
在 Activity 中可以通過 startService 和 bindService 方法啟動(dòng) Service。一般情況下如果想獲取
Service 的服務(wù)對(duì)象那么肯定需要通過 bindService()方法审孽,比如音樂播放器县袱,第三方支付等。如
果僅僅只是為了開啟一個(gè)后臺(tái)任務(wù)那么可以使用 startService()方法佑力。
9.說說 Activity显拳、Intent、Service 是什么關(guān)系
他們都是 Android 開發(fā)中使用頻率最高的類搓萧。其中 Activity 和 Service 都是 Android 四大組件
之一杂数。他倆都是 Context 類的子類 ContextWrapper 的子類宛畦,因此他倆可以算是兄弟關(guān)系吧。不過
兄弟倆各有各自的本領(lǐng)揍移,Activity 負(fù)責(zé)用戶界面的顯示和交互次和,Service 負(fù)責(zé)后臺(tái)任務(wù)的處理。Activity
和 Service 之間可以通過 Intent 傳遞數(shù)據(jù)那伐,因此可以把 Intent 看作是通信使者踏施。
10.請(qǐng)描述一下 BroadcastReceiver
BroadCastReceiver 是 Android 四大組件之一,主要用于接收系統(tǒng)或者 app 發(fā)送的廣播事件罕邀。
廣播分兩種:有序廣播和無序廣播畅形。
內(nèi)部通信實(shí)現(xiàn)機(jī)制:通過 Android 系統(tǒng)的 Binder 機(jī)制實(shí)現(xiàn)通信。
無序廣播:完全異步诉探,邏輯上可以被任何廣播接收者接收到日熬。優(yōu)點(diǎn)是效率較高。缺點(diǎn)是一個(gè)接收者不
能將處理結(jié)果傳遞給下一個(gè)接收者肾胯,并無法終止廣播 intent 的傳播竖席。
有序廣播:按照被接收者的優(yōu)先級(jí)順序,在被接收者中依次傳播敬肚。比如有三個(gè)廣播接收者 A毕荐,B,C艳馒,
優(yōu)先級(jí)是 A > B > C憎亚。那這個(gè)消息先傳給 A,再傳給 B弄慰,最后傳給 C虽填。每個(gè)接收者有權(quán)終止廣播,比
如 B 終止廣播曹动,C 就無法接收到。此外 A 接收到廣播后可以對(duì)結(jié)果對(duì)象進(jìn)行操作牲览,當(dāng)廣播傳給 B 時(shí)墓陈,
B 可以從結(jié)果對(duì)象中取得 A 存入的數(shù)據(jù)。
在通過 Context.sendOrderedBroadcast(intent, receiverPermission, resultReceiver, scheduler,
initialCode, initialData, initialExtras)時(shí)我們可以指定 resultReceiver 廣播接收者第献,這個(gè)接收者我們
可以認(rèn)為是最終接收者贡必,通常情況下如果比他優(yōu)先級(jí)更高的接收者如果沒有終止廣播,那么他的
onReceive 會(huì)被執(zhí)行兩次庸毫,第一次是正常的按照優(yōu)先級(jí)順序執(zhí)行仔拟,第二次是作為最終接收者接收。
如果比他優(yōu)先級(jí)高的接收者終止了廣播飒赃,那么他依然能接收到廣播
11.為什么要用 ContentProvider?它和 sql 的實(shí)現(xiàn)上有什么差別?
ContentProvider 屏蔽了數(shù)據(jù)存儲(chǔ)的細(xì)節(jié),內(nèi)部實(shí)現(xiàn)對(duì)用戶完全透明,用戶只需要關(guān)心操作數(shù)據(jù)的
uri 就可以了利花,ContentProvider 可以實(shí)現(xiàn)不同 app 之間共享科侈。
Sql 也有增刪改查的方法,但是 sql 只能查詢本應(yīng)用下的數(shù)據(jù)庫炒事。而 ContentProvider 還可
以去增刪改查本地文件. xml 文件的讀取等臀栈。
12.說說 ContentProvider、ContentResolver挠乳、ContentObserver 之間的關(guān)系
a. ContentProvider 內(nèi)容提供者权薯,用于對(duì)外提供數(shù)據(jù)
b. ContentResolver.notifyChange(uri)發(fā)出消息
c. ContentResolver 內(nèi)容解析者,用于獲取內(nèi)容提供者提供的數(shù)據(jù)
d. ContentObserver 內(nèi)容監(jiān)聽器睡扬,可以監(jiān)聽數(shù)據(jù)的改變狀態(tài)
e. ContentResolver.registerContentObserver()監(jiān)聽消息盟蚣。
View 相關(guān)
1.onInterceptTouchEvent()和onTouchEvent()的區(qū)別
onInterceptTouchEvent()用于攔截觸摸事件
onTouchEvent()用于處理觸摸事件
2.RemoteView在哪些功能中使用
APPwidget和Notification中
SurfaceView和View的區(qū)別是什么?
SurfaceView中采用了雙緩存技術(shù),在單獨(dú)的線程中更新界面
View在UI線程中更新界面
4.View的繪制過程
一個(gè)View要顯示在界面上卖怜,需要經(jīng)歷一個(gè)View樹的遍歷過程屎开,這個(gè)過程又可以分為三個(gè)過程,也就是自定義View中的三要素:大小韧涨,位置牍戚,畫什么,即onMesure()虑粥,onLayout(),onDraw()如孝。
1.onMesure()確定一個(gè)View的大小;
2.onLayout()確定View在父節(jié)點(diǎn)上的位置;
3.onDraw()繪制View 的內(nèi)容;
5.如何自定義ViewGroup
1.指定的LayoutParams
2.onMeasure中計(jì)算所有childView的寬和高,然后根據(jù)childView的寬和高娩贷,計(jì)算自己的寬和高第晰。(當(dāng)然,如果不是wrap_content彬祖,直接使用父ViewGroup傳入的計(jì)算值即可)
3.onLayout中對(duì)所有的childView進(jìn)行布局茁瘦。
6.View中onTouch,onTouchEvent储笑,onClick的執(zhí)行順序
dispatchTouchEvent—->onTouch—->onTouchEvent—–>onClick甜熔。在所有ACTION_UP事件之后才觸發(fā)onClick點(diǎn)擊事件。
性能優(yōu)化相關(guān)
1.ListView卡頓的原因與性能優(yōu)化突倍,越多越好
重用converView: 通過復(fù)用converview來減少不必要的view的創(chuàng)建腔稀,另外Infalte操作會(huì)把xml文件實(shí)例化成相應(yīng)的View實(shí)例,屬于IO操作羽历,是耗時(shí)操作焊虏。
減少findViewById()操作: 將xml文件中的元素封裝成viewholder靜態(tài)類,通過converview的setTag和getTag方法將view與相應(yīng)的holder對(duì)象綁定在一起秕磷,避免不必要的findviewbyid操作
避免在 getView 方法中做耗時(shí)的操作: 例如加載本地 Image 需要載入內(nèi)存以及解析 Bitmap 诵闭,都是比較耗時(shí)的操作,如果用戶快速滑動(dòng)listview,會(huì)因?yàn)間etview邏輯過于復(fù)雜耗時(shí)而造成滑動(dòng)卡頓現(xiàn)象疏尿。用戶滑動(dòng)時(shí)候不要加載圖片瘟芝,待滑動(dòng)完成再加載,可以使用這個(gè)第三方庫glide
Item的布局層次結(jié)構(gòu)盡量簡單润歉,避免布局太深或者不必要的重繪
盡量能保證 Adapter 的 hasStableIds() 返回 true 這樣在 notifyDataSetChanged() 的時(shí)候模狭,如果item內(nèi)容并沒有變化,ListView 將不會(huì)重新繪制這個(gè) View踩衩,達(dá)到優(yōu)化的目的
在一些場(chǎng)景中嚼鹉,ScollView內(nèi)會(huì)包含多個(gè)ListView,可以把listview的高度寫死固定下來驱富。 由于ScollView在快速滑動(dòng)過程中需要大量計(jì)算每一個(gè)listview的高度锚赤,阻塞了UI線程導(dǎo)致卡頓現(xiàn)象出現(xiàn),如果我們每一個(gè)item的高度都是均勻的褐鸥,可以通過計(jì)算把listview的高度確定下來线脚,避免卡頓現(xiàn)象出現(xiàn)
使用 RecycleView 代替listview: 每個(gè)item內(nèi)容的變動(dòng),listview都需要去調(diào)用notifyDataSetChanged來更新全部的item叫榕,太浪費(fèi)性能了浑侥。RecycleView可以實(shí)現(xiàn)當(dāng)個(gè)item的局部刷新,并且引入了增加和刪除的動(dòng)態(tài)效果晰绎,在性能上和定制上都有很大的改善
ListView 中元素避免半透明: 半透明繪制需要大量乘法計(jì)算寓落,在滑動(dòng)時(shí)不停重繪會(huì)造成大量的計(jì)算,在比較差的機(jī)子上會(huì)比較卡荞下。 在設(shè)計(jì)上能不半透明就不不半透明伶选。實(shí)在要弄就把在滑動(dòng)的時(shí)候把半透明設(shè)置成不透明,滑動(dòng)完再重新設(shè)置成半透明尖昏。
盡量開啟硬件加速: 硬件加速提升巨大仰税,避免使用一些不支持的函數(shù)導(dǎo)致含淚關(guān)閉某個(gè)地方的硬件加速。當(dāng)然這一條不只是對(duì) ListView抽诉。
2.如何避免 OOM 問題的出現(xiàn)
使用更加輕量的數(shù)據(jù)結(jié)構(gòu) 例如陨簇,我們可以考慮使用ArrayMap/SparseArray而不是HashMap等傳統(tǒng)數(shù)據(jù)結(jié)構(gòu)。通常的HashMap的實(shí)現(xiàn)方式更加消耗內(nèi)存迹淌,因?yàn)樗枰粋€(gè)額外的實(shí)例對(duì)象來記錄Mapping操作河绽。另外,SparseArray更加高效巍沙,在于他們避免了對(duì)key與value的自動(dòng)裝箱(autoboxing),并且避免了裝箱后的解箱荷鼠。
避免在Android里面使用Enum Android官方培訓(xùn)課程提到過“Enums often require more than twice as much memory as static constants. You should strictly avoid using enums on Android.”句携,具體原理請(qǐng)參考《Android性能優(yōu)化典范(三)》,所以請(qǐng)避免在Android里面使用到枚舉允乐。
減小Bitmap對(duì)象的內(nèi)存占用 Bitmap是一個(gè)極容易消耗內(nèi)存的大胖子矮嫉,減小創(chuàng)建出來的Bitmap的內(nèi)存占用可謂是重中之重削咆,,通常來說有以下2個(gè)措施: inSampleSize:縮放比例蠢笋,在把圖片載入內(nèi)存之前拨齐,我們需要先計(jì)算出一個(gè)合適的縮放比例,避免不必要的大圖載入昨寞。 decode format:解碼格式瞻惋,選擇ARGB_6666/RBG_545/ARGB_4444/ALPHA_6,存在很大差異
Bitmap對(duì)象的復(fù)用 縮小Bitmap的同時(shí)援岩,也需要提高BitMap對(duì)象的復(fù)用率歼狼,避免頻繁創(chuàng)建BitMap對(duì)象,復(fù)用的方法有以下2個(gè)措施 LRUCache : “最近最少使用算法”在Android中有極其普遍的應(yīng)用享怀。ListView與GridView等顯示大量圖片的控件里羽峰,就是使用LRU的機(jī)制來緩存處理好的Bitmap,把近期最少使用的數(shù)據(jù)從緩存中移除添瓷,保留使用最頻繁的數(shù)據(jù)梅屉, inBitMap高級(jí)特性:利用inBitmap的高級(jí)特性提高Android系統(tǒng)在Bitmap分配與釋放執(zhí)行效率。使用inBitmap屬性可以告知Bitmap解碼器去嘗試使用已經(jīng)存在的內(nèi)存區(qū)域鳞贷,新解碼的Bitmap會(huì)嘗試去使用之前那張Bitmap在Heap中所占據(jù)的pixel data內(nèi)存區(qū)域坯汤,而不是去問內(nèi)存重新申請(qǐng)一塊區(qū)域來存放Bitmap。利用這種特性悄晃,即使是上千張的圖片玫霎,也只會(huì)僅僅只需要占用屏幕所能夠顯示的圖片數(shù)量的內(nèi)存大小
使用更小的圖片 在涉及給到資源圖片時(shí),我們需要特別留意這張圖片是否存在可以壓縮的空間妈橄,是否可以使用更小的圖片庶近。盡量使用更小的圖片不僅可以減少內(nèi)存的使用,還能避免出現(xiàn)大量的InflationException眷蚓。假設(shè)有一張很大的圖片被XML文件直接引用鼻种,很有可能在初始化視圖時(shí)會(huì)因?yàn)閮?nèi)存不足而發(fā)生InflationException,這個(gè)問題的根本原因其實(shí)是發(fā)生了OOM沙热。
StringBuilder 在有些時(shí)候叉钥,代碼中會(huì)需要使用到大量的字符串拼接的操作,這種時(shí)候有必要考慮使用StringBuilder來替代頻繁的“+”篙贸。
避免在onDraw方法里面執(zhí)行對(duì)象的創(chuàng)建 類似onDraw等頻繁調(diào)用的方法投队,一定需要注意避免在這里做創(chuàng)建對(duì)象的操作,因?yàn)樗麜?huì)迅速增加內(nèi)存的使用爵川,而且很容易引起頻繁的gc敷鸦,甚至是內(nèi)存抖動(dòng)。
避免對(duì)象的內(nèi)存泄露
3.三級(jí)緩存的原理
從緩存中加載。
從本地文件中加載(數(shù)據(jù)庫扒披,SD)
從網(wǎng)絡(luò)加載值依。
a.加載 bitmap 的時(shí)候無需考慮 bitmap 加載過程中出現(xiàn)的 oom(內(nèi)存溢出)和 android 容器快速
滑動(dòng)的時(shí)候出現(xiàn)的圖片錯(cuò)位等現(xiàn)象。(16M)
b. 支持加載網(wǎng)絡(luò)圖片和本地圖片碟案。
c. 內(nèi)存管理使用的 lru 算法(移除里面是有頻率最少的對(duì)象)愿险,更好的管理 bitmap 的內(nèi)存
Android其他
1.講一下android中進(jìn)程的優(yōu)先級(jí)?
前臺(tái)進(jìn)程
可見進(jìn)程
服務(wù)進(jìn)程
后臺(tái)進(jìn)程
空進(jìn)程
2.介紹Handle的機(jī)制
Handler通過調(diào)用sendmessage方法把消息放在消息隊(duì)列MessageQueue中,Looper負(fù)責(zé)把消息從消息隊(duì)列中取出來价说,重新再交給Handler進(jìn)行處理辆亏,三者形成一個(gè)循環(huán)
通過構(gòu)建一個(gè)消息隊(duì)列,把所有的Message進(jìn)行統(tǒng)一的管理熔任,當(dāng)Message不用了褒链,并不作為垃圾回收,而是放入消息隊(duì)列中疑苔,供下次handler創(chuàng)建消息時(shí)候使用甫匹,提高了消息對(duì)象的復(fù)用,減少系統(tǒng)垃圾回收的次數(shù)
每一個(gè)線程惦费,都會(huì)單獨(dú)對(duì)應(yīng)的一個(gè)looper兵迅,這個(gè)looper通過ThreadLocal來創(chuàng)建,保證每個(gè)線程只創(chuàng)建一個(gè)looper薪贫,looper初始化后就會(huì)調(diào)用looper.loop創(chuàng)建一個(gè)MessageQueue恍箭,這個(gè)方法在UI線程初始化的時(shí)候就會(huì)完成,我們不需要手動(dòng)創(chuàng)建
3.Dalvik虛擬機(jī)與JVM有什么區(qū)別
Dalvik 基于寄存器瞧省,而 JVM 基于棧扯夭。基于寄存器的虛擬機(jī)對(duì)于更大的程序來說鞍匾,在它們編譯的時(shí)候交洗,花費(fèi)的時(shí)間更短。
Dalvik執(zhí)行.dex格式的字節(jié)碼橡淑,而JVM執(zhí)行.class格式的字節(jié)碼构拳。
4.每個(gè)應(yīng)用程序?qū)?yīng)多少個(gè)Dalvik虛擬機(jī)
每一個(gè)Android應(yīng)用在底層都會(huì)對(duì)應(yīng)一個(gè)獨(dú)立的Dalvik虛擬機(jī)實(shí)例,其代碼在虛擬機(jī)的解釋下得以執(zhí)行 梁棠,而所有的Android應(yīng)用的線程都對(duì)應(yīng)一個(gè)Linux線程
5.應(yīng)用常駐后臺(tái)置森,避免被第三方殺掉的方法
Service設(shè)置成START_STICKY kill 后會(huì)被重啟(等待5秒左右),重傳Intent符糊,保持與重啟前一樣
通過 startForeground將進(jìn)程設(shè)置為前臺(tái)進(jìn)程凫海, 做前臺(tái)服務(wù),優(yōu)先級(jí)和前臺(tái)應(yīng)用一個(gè)級(jí)別男娄,除非在系統(tǒng)內(nèi)存非常缺行贪,否則此進(jìn)程不會(huì)被 kill
雙進(jìn)程Service: 讓2個(gè)進(jìn)程互相保護(hù)對(duì)方把兔,其中一個(gè)Service被清理后,另外沒被清理的進(jìn)程可以立即重啟進(jìn)程
用C編寫守護(hù)進(jìn)程(即子進(jìn)程) : Android系統(tǒng)中當(dāng)前進(jìn)程(Process)fork出來的子進(jìn)程瓮顽,被系統(tǒng)認(rèn)為是兩個(gè)不同的進(jìn)程。當(dāng)父進(jìn)程被殺死的時(shí)候围橡,子進(jìn)程仍然可以存活暖混,并不受影響(Android5.0以上的版本不可行
聯(lián)系廠商,加入白名單
6.根據(jù)自己的理解描述下Android數(shù)字簽名翁授。
所有的應(yīng)用程序都必須有數(shù)字證書拣播,Android系統(tǒng)不會(huì)安裝一個(gè)沒有數(shù)字證書的應(yīng)用程序
Android程序包使用的數(shù)字證書可以是自簽名的,不需要一個(gè)權(quán)威的數(shù)字證書機(jī)構(gòu)簽名認(rèn)證
如果要正式發(fā)布一個(gè)Android程序收擦,必須使用一個(gè)合適的私鑰生成的數(shù)字證書來給程序簽名贮配,而不能使用adt插件或者ant工具生成的調(diào)試證書來發(fā)布。
數(shù)字證書都是有有效期的塞赂,Android只是在應(yīng)用程序安裝的時(shí)候才會(huì)檢查證書的有效期泪勒。如果程序已經(jīng)安裝在系統(tǒng)中,即使證書過期也不會(huì)影響程序的正常功能宴猾。
7.Dalvik基于JVM的改進(jìn)
幾個(gè)class變?yōu)橐粋€(gè)dex圆存,constant pool,省內(nèi)存
Zygote仇哆,copy-on-write shared,省內(nèi)存沦辙,省cpu,省電
基于寄存器的bytecode讹剔,省指令油讯,省cpu,省電
Trace-based JIT,省cpu延欠,省電,省內(nèi)存
8.ARGB_8888占用內(nèi)存大小
本題的答案陌兑,是4byte,即ARGB各占用8個(gè)比特來描述衫冻。
9.apk安裝卸載的原理
安裝過程:復(fù)制apk安裝包到data/app目錄下诀紊,解壓并掃描安裝包,把dex文件(dalvik字節(jié)碼)保存到dalvik-cache目錄隅俘,并data/data目錄下創(chuàng)建對(duì)應(yīng)的應(yīng)用數(shù)據(jù)目錄邻奠。
卸載過程:刪除安裝過程中在上述三個(gè)目錄下創(chuàng)建的文件及目錄。
10.通過Intent傳遞一些二進(jìn)制數(shù)據(jù)的方法有哪些?
使用Serializable接口實(shí)現(xiàn)序列化为居,這是Java常用的方法碌宴。
實(shí)現(xiàn)Parcelable接口,這里Android的部分類比如Bitmap類就已經(jīng)實(shí)現(xiàn)了蒙畴,同時(shí)Parcelable在Android AIDL中交換數(shù)據(jù)也很常見的贰镣。
11.橫豎屏切換時(shí)Activity的生命周期
此時(shí)的生命周期跟清單文件里的配置有關(guān)系呜象。
不設(shè)置Activity的android:configChanges時(shí),切屏?xí)匦抡{(diào)用各個(gè)生命周期默認(rèn)首先銷毀當(dāng)前activity,然后重新加載碑隆。
設(shè)置Activity android:configChanges=”orientation|keyboardHidden|screenSize”時(shí)恭陡,切屏不會(huì)重新調(diào)用各個(gè)生命周期,只會(huì)執(zhí)行onConfigurationChanged方法
12.Serializable 和 Parcelable 的區(qū)別
在使用內(nèi)存的時(shí)候上煤,Parcelable 類比 Serializable 性能高休玩,所以推薦使用 Parcelable 類。
Serializable 在序列化的時(shí)候會(huì)產(chǎn)生大量的臨時(shí)變量劫狠,從而引起頻繁的 GC拴疤。
Parcelable 不能使用在要將數(shù)據(jù)存儲(chǔ)在磁盤上的情況。盡管 Serializable 效率低點(diǎn)独泞,但在這
種情況下呐矾,還是建議你用 Serializable 。
13.Android 中如何捕獲未捕獲的異常
自 定 義 一 個(gè) Application 懦砂, 比 如 叫 MyApplication 繼 承 Application 實(shí) 現(xiàn)
UncaughtExceptionHandler蜒犯。
覆寫 UncaughtExceptionHandler 的 onCreate 和 uncaughtException 方法。
14.Android 的權(quán)限規(guī)則
Android 中的 apk 必須簽名
基于 UserID 的進(jìn)程級(jí)別的安全機(jī)制
默認(rèn) apk 生成的數(shù)據(jù)對(duì)外是不可見的
AndroidManifest.xml 中的顯式權(quán)限聲明
15.多線程間通信和多進(jìn)程之間通信有什么不同荞膘,分別怎么實(shí)現(xiàn)?
一愧薛、進(jìn)程間的通信方式
管道( pipe ):管道是一種半雙工的通信方式,數(shù)據(jù)只能單向流動(dòng)衫画,而且只能在具有親緣關(guān)系的
進(jìn)程間使用毫炉。進(jìn)程的親緣關(guān)系通常是指父子進(jìn)程關(guān)系。
有名管道 (namedpipe) : 有名管道也是半雙工的通信方式削罩,但是它允許無親緣關(guān)系進(jìn)程間的
通信瞄勾。
信號(hào)量(semophore ) : 信號(hào)量是一個(gè)計(jì)數(shù)器,可以用來控制多個(gè)進(jìn)程對(duì)共享資源的訪問弥激。它
常作為一種鎖機(jī)制进陡,防止某進(jìn)程正在訪問共享資源時(shí),其他進(jìn)程也訪問該資源微服。因此趾疚,主要作為進(jìn)
程間以及同一進(jìn)程內(nèi)不同線程之間的同步手段。
消息隊(duì)列( messagequeue ) : 消息隊(duì)列是由消息的鏈表以蕴,存放在內(nèi)核中并由消息隊(duì)列標(biāo)識(shí)符
標(biāo)識(shí)糙麦。消息隊(duì)列克服了信號(hào)傳遞信息少、管道只能承載無格式字節(jié)流以及緩沖區(qū)大小受限等缺點(diǎn)丛肮。
信號(hào) (sinal ) : 信號(hào)是一種比較復(fù)雜的通信方式赡磅,用于通知接收進(jìn)程某個(gè)事件已經(jīng)發(fā)生。
共享內(nèi)存(shared memory ) :共享內(nèi)存就是映射一段能被其他進(jìn)程所訪問的內(nèi)存宝与,這段共享內(nèi)
存由一個(gè)進(jìn)程創(chuàng)建焚廊,但多個(gè)進(jìn)程都可以訪問冶匹。共享內(nèi)存是最快的 IPC 方式,它是針對(duì)其他進(jìn)程間
通信方式運(yùn)行效率低而專門設(shè)計(jì)的咆瘟。它往往與其他通信機(jī)制嚼隘,如信號(hào)兩,配合使用袒餐,來實(shí)現(xiàn)進(jìn)程間
的同步和通信嗓蘑。
套接字(socket ) : 套解口也是一種進(jìn)程間通信機(jī)制,與其他通信機(jī)制不同的是匿乃,它可用于不同
及其間的進(jìn)程通信。
二豌汇、線程間的通信方式
1. 鎖機(jī)制:包括互斥鎖幢炸、條件變量、讀寫鎖
互斥鎖提供了以排他方式防止數(shù)據(jù)結(jié)構(gòu)被并發(fā)修改的方法拒贱。
讀寫鎖允許多個(gè)線程同時(shí)讀共享數(shù)據(jù)宛徊,而對(duì)寫操作是互斥的。
條件變量可以以原子的方式阻塞進(jìn)程逻澳,直到某個(gè)特定條件為真為止闸天。對(duì)條件的測(cè)試是在互斥鎖
的保護(hù)下進(jìn)行的。條件變量始終與互斥鎖一起使用斜做。
2. 信號(hào)量機(jī)制(Semaphore):包括無名線程信號(hào)量和命名線程信號(hào)量
3. 信號(hào)機(jī)制(Signal):類似進(jìn)程間的信號(hào)處理
線程間的通信目的主要是用于線程同步苞氮,所以線程沒有像進(jìn)程通信中的用于數(shù)據(jù)交換的通信機(jī)
制。
16.說說 LruCache 底層原理
LruCache 使用一個(gè) LinkedHashMap 簡單的實(shí)現(xiàn)內(nèi)存的緩存瓤逼,沒有軟引用笼吟,都是強(qiáng)引用票堵。如果添
加的數(shù)據(jù)大于設(shè)置的最大值乏梁,就刪除最先緩存的數(shù)據(jù)來調(diào)整內(nèi)存。
maxSize 是通過構(gòu)造方法初始化的值柒瓣,他表示這個(gè)緩存能緩存的最大值是多少诱告。
size 在添加和移除緩存都被更新值撵枢,他通過 safeSizeOf 這個(gè)方法更新值。safeSizeOf 默認(rèn)返回 1精居,
但一般我們會(huì)根據(jù) maxSize 重寫這個(gè)方法锄禽,比如認(rèn)為 maxSize 代表是 KB 的話,那么就以 KB 為單位返回該項(xiàng)所占的內(nèi)存大小靴姿。
除異常外首先會(huì)判斷 size 是否超過 maxSize沟绪,如果超過了就取出最先插入的緩存,如果不為空就 刪掉空猜,并把 size 減去該項(xiàng)所占的大小绽慈。這個(gè)操作將一直循環(huán)下去恨旱,直到 size 比 maxSize 小或者緩存 空。
作者:Near尼爾
鏈接:http://www.reibang.com/p/5dc32744c2a3
來源:簡書
著作權(quán)歸作者所有坝疼。商業(yè)轉(zhuǎn)載請(qǐng)聯(lián)系作者獲得授權(quán)搜贤,非商業(yè)轉(zhuǎn)載請(qǐng)注明出處。