1.說下你所知道的設(shè)計(jì)模式與使用場(chǎng)景
建造者模式:
觀察者模式:
代理模式:
門面模式:
單例模式:
生產(chǎn)者消費(fèi)者模式:
2.Java語言的特點(diǎn)與OOP思想
這個(gè)通過對(duì)比來描述,比如面向?qū)ο蠛兔嫦蜻^程的對(duì)比,針對(duì)這兩種思想的對(duì)比,還可以舉個(gè)開發(fā)中的例子,比如播放器的實(shí)現(xiàn),面向過程的實(shí)現(xiàn)方式就是將播放視頻的這個(gè)功能分解成多個(gè)過程,比如,加載視頻地址,獲取視頻信息,初始化解碼器,選擇合適的解碼器進(jìn)行解碼,讀取解碼后的幀進(jìn)行視頻格式轉(zhuǎn)換和音頻重采樣,然后讀取幀進(jìn)行播放,這是一個(gè)完整的過程,這個(gè)過程中不涉及類的概念,而面向?qū)ο笞畲蟮奶攸c(diǎn)就是類,封裝繼承和多態(tài)是核心,同樣的以播放器為例,一面向?qū)ο蟮姆绞絹韺?shí)現(xiàn),將會(huì)針對(duì)每一個(gè)功能封裝出一個(gè)對(duì)象,每一個(gè)功能對(duì)應(yīng)一個(gè)對(duì)象,由這個(gè)對(duì)象來完成對(duì)應(yīng)的功能,并且遵循單一職責(zé)原則,一個(gè)對(duì)象只做它相關(guān)的事情
3.說下java中的線程創(chuàng)建方式,線程池的工作原理。
Java中有三種創(chuàng)建線程的方式,或者說四種
1.繼承Thread類實(shí)現(xiàn)多線程
2.實(shí)現(xiàn)Runnable接口
3.實(shí)現(xiàn)Callable接口
4.通過線程池
線程池的工作原理:
線程池可以減少創(chuàng)建和銷毀線程的次數(shù),從而減少系統(tǒng)資源的消耗,當(dāng)一個(gè)任務(wù)提交到線程池時(shí).
a. 首先判斷核心線程池中的線程是否已經(jīng)滿了,如果沒滿,則創(chuàng)建一個(gè)核心線程執(zhí)行任務(wù),否則進(jìn)入下一步.
b. 判斷工作隊(duì)列是否已滿,沒有滿則加入工作隊(duì)列,否則執(zhí)行下一步.
c. 判斷線程數(shù)是否達(dá)到了最大值,如果不是,則創(chuàng)建非核心線程執(zhí)行任務(wù),否則執(zhí)行飽和策略,默認(rèn)拋出異常.
4.說下handler原理
Handler,Message,looper和MessageQueue構(gòu)成了安卓的消息機(jī)制,handler創(chuàng)建后可以通過sendMessage將消息加入消息隊(duì)列,然后looper不斷的將消息從MessageQueue中取出來,回調(diào)到Hander的handleMessage方法,從而實(shí)現(xiàn)線程的通信。
從兩種情況來說,第一在UI線程創(chuàng)建Handler,此時(shí)我們不需要手動(dòng)開啟looper,因?yàn)樵趹?yīng)用啟動(dòng)時(shí),在ActivityThread的main方法中就創(chuàng)建了一個(gè)當(dāng)前主線程的looper,并開啟了消息隊(duì)列,消息隊(duì)列是一個(gè)無限循環(huán),為什么無限循環(huán)不會(huì)ANR?因?yàn)榭梢哉f,應(yīng)用的整個(gè)生命周期就是運(yùn)行在這個(gè)消息循環(huán)中的,安卓是由事件驅(qū)動(dòng)的,Looper.loop不斷的接收處理事件,每一個(gè)點(diǎn)擊觸摸或者Activity每一個(gè)生命周期都是在Looper.loop的控制之下的,looper.loop一旦結(jié)束,應(yīng)用程序的生命周期也就結(jié)束了。
我們可以想想什么情況下會(huì)發(fā)生ANR?
第一,事件沒有得到處理
第二,事件正在處理,但是沒有及時(shí)完成,而對(duì)事件進(jìn)行處理的就是looper,所以只能說事件的處理如果阻塞會(huì)導(dǎo)致ANR,而不能說looper的無限循環(huán)會(huì)ANR
另一種情況就是在子線程創(chuàng)建Handler,此時(shí)由于這個(gè)線程中沒有默認(rèn)開啟的消息隊(duì)列,所以我們需要手動(dòng)調(diào)用looper.prepare(),并通過looper.loop開啟消息
主線程Looper從消息隊(duì)列讀取消息,當(dāng)讀完所有消息時(shí),主線程阻塞。子線程往消息隊(duì)列發(fā)送消息,并且往管道文件寫數(shù)據(jù),主線程即被喚醒,從管道文件讀取數(shù)據(jù),主線程被喚醒只是為了讀取消息,當(dāng)消息讀取完畢,再次睡眠。因此loop的循環(huán)并不會(huì)對(duì)CPU性能有過多的消耗。
5.內(nèi)存泄漏的場(chǎng)景和解決辦法
1.非靜態(tài)內(nèi)部類的靜態(tài)實(shí)例
非靜態(tài)內(nèi)部類會(huì)持有外部類的引用,如果非靜態(tài)內(nèi)部類的實(shí)例是靜態(tài)的,就會(huì)長期的維持著外部類的引用,組織被系統(tǒng)回收,解決辦法是使用靜態(tài)內(nèi)部類
2.多線程相關(guān)的匿名內(nèi)部類和非靜態(tài)內(nèi)部類
匿名內(nèi)部類同樣會(huì)持有外部類的引用,如果在線程中執(zhí)行耗時(shí)操作就有可能發(fā)生內(nèi)存泄漏,導(dǎo)致外部類無法被回收,直到耗時(shí)任務(wù)結(jié)束,解決辦法是在頁面退出時(shí)結(jié)束線程中的任務(wù)
3.Handler內(nèi)存泄漏
Handler導(dǎo)致的內(nèi)存泄漏也可以被歸納為非靜態(tài)內(nèi)部類導(dǎo)致的,Handler內(nèi)部message是被存儲(chǔ)在MessageQueue中的,有些message不能馬上被處理,存在的時(shí)間會(huì)很長,導(dǎo)致handler無法被回收,如果handler是非靜態(tài)的,就會(huì)導(dǎo)致它的外部類無法被回收,
解決辦法是
1.使用靜態(tài)handler,外部類引用使用弱引用處理
2.在退出頁面時(shí)移除消息隊(duì)列中的消息
4.Context導(dǎo)致內(nèi)存泄漏
根據(jù)場(chǎng)景確定使用Activity的Context還是Application的Context,因?yàn)槎呱芷诓煌?,?duì)于不必須使用Activity的Context的場(chǎng)景(Dialog),一律采用Application的Context,單例模式是最常見的發(fā)生此泄漏的場(chǎng)景,比如傳入一個(gè)Activity的Context被靜態(tài)類引用,導(dǎo)致無法回收
5.靜態(tài)View導(dǎo)致泄漏
使用靜態(tài)View可以避免每次啟動(dòng)Activity都去讀取并渲染View,但是靜態(tài)View會(huì)持有Activity的引用,導(dǎo)致無法回收
解決辦法是在Activity銷毀的時(shí)候?qū)㈧o態(tài)View設(shè)置為null(View一旦被加載到界面中將會(huì)持有一個(gè)Context對(duì)象的引用,在這個(gè)例子中,這個(gè)context對(duì)象是我們的Activity,聲明一個(gè)靜態(tài)變量引用這個(gè)View,也就引用了activity)
6.WebView導(dǎo)致的內(nèi)存泄漏
WebView只要使用一次,內(nèi)存就不會(huì)被釋放,所以WebView都存在內(nèi)存泄漏的問題,通常的解決辦法是為WebView單開一個(gè)進(jìn)程,使用AIDL進(jìn)行通信,根據(jù)業(yè)務(wù)需求在合適的時(shí)機(jī)釋放掉
7.資源對(duì)象未關(guān)閉導(dǎo)致
如Cursor,F(xiàn)ile等,內(nèi)部往往都使用了緩沖,會(huì)造成內(nèi)存泄漏,一定要確保關(guān)閉它并將引用置為null
8.集合中的對(duì)象未清理
集合用于保存對(duì)象,如果集合越來越大,不進(jìn)行合理的清理,尤其是入股集合是靜態(tài)的
9.Bitmap導(dǎo)致內(nèi)存泄漏
bitmap是比較占內(nèi)存的,所以一定要在不使用的時(shí)候及時(shí)進(jìn)行清理,避免靜態(tài)變量持有大的bitmap對(duì)象
10.監(jiān)聽器未關(guān)閉
很多需要register和unregister的系統(tǒng)服務(wù)要在合適的時(shí)候進(jìn)行unregister,手動(dòng)添加的listener也需要及時(shí)移除
6.如何避免OOM?
1.使用更加輕量的數(shù)據(jù)結(jié)構(gòu):
如使用ArrayM
《安卓學(xué)習(xí)筆記總結(jié)+最新移動(dòng)架構(gòu)視頻+大廠安卓面試真題+項(xiàng)目實(shí)戰(zhàn)源碼講義》瀏覽器打開
完整開源項(xiàng)目:docs.qq.com/doc/DSkNLaERkbnFoS0ZF
ap/SparseArray替代HashMap,HashMap更耗內(nèi)存,因?yàn)樗枰~外的實(shí)例對(duì)象來記錄Mapping操作,SparseArray更加高效,因?yàn)樗苊饬薑ey Value的自動(dòng)裝箱,和裝箱后的解箱操作
2.枚舉的使用
可以用靜態(tài)常量或者注解@IntDef替代
3.Bitmap優(yōu)化:
a.尺寸壓縮:
通過InSampleSize設(shè)置合適的縮放
b.顏色質(zhì)量:
設(shè)置合適的format,ARGB_6666/RBG_545/ARGB_4444/ALPHA_6,存在很大差異.
c.inBitmap:
使用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)存大小,但復(fù)用存在一些限制,具體體現(xiàn)在:在Android 4.4之前只能重用相同大小的Bitmap的內(nèi)存,而Android 4.4及以后版本則只要后來的Bitmap比之前的小即可。使用inBitmap參數(shù)前,每創(chuàng)建一個(gè)Bitmap對(duì)象都會(huì)分配一塊內(nèi)存供其使用,而使用了inBitmap參數(shù)后,多個(gè)Bitmap可以復(fù)用一塊內(nèi)存,這樣可以提高性能
d.StringBuilder替代String: 在有些時(shí)候,代碼中會(huì)需要使用到大量的字符串拼接的操作,這種時(shí)候有必要考慮使用StringBuilder來替代頻繁的“+”
e.避免在類似onDraw這樣的方法中創(chuàng)建對(duì)象,因?yàn)樗鼤?huì)迅速占用大量內(nèi)存,引起頻繁的GC`甚至內(nèi)存抖動(dòng)
f.減少內(nèi)存泄漏也是一種避免OOM的方法
最后
其實(shí)Android開發(fā)的知識(shí)點(diǎn)就那么多,面試問來問去還是那么點(diǎn)東西。所以面試沒有其他的訣竅,只看你對(duì)這些知識(shí)點(diǎn)準(zhǔn)備的充分程度。so,出去面試時(shí)先看看自己復(fù)習(xí)到了哪個(gè)階段就好。
雖然 Android 沒有前幾年火熱了,已經(jīng)過去了會(huì)四大組件就能找到高薪職位的時(shí)代了。這只能說明 Android 中級(jí)以下的崗位飽和了,現(xiàn)在高級(jí)工程師還是比較缺少的,很多高級(jí)職位給的薪資真的特別高(錢多也不一定能找到合適的),所以努力讓自己成為高級(jí)工程師才是最重要的。
這里附上上述的面試題相關(guān)的幾十套字節(jié)跳動(dòng),京東,小米,騰訊、頭條、阿里、美團(tuán)等公司21年的面試題。把技術(shù)點(diǎn)整理成了視頻和PDF(實(shí)際上比預(yù)期多花了不少精力),包含知識(shí)脈絡(luò) + 諸多細(xì)節(jié)。
由于篇幅有限,這里以圖片的形式給大家展示一小部分。
網(wǎng)上學(xué)習(xí) Android的資料一大堆,但如果學(xué)到的知識(shí)不成體系,遇到問題時(shí)只是淺嘗輒止,不再深入研究,那么很難做到真正的技術(shù)提升。希望這份系統(tǒng)化的技術(shù)體系對(duì)大家有一個(gè)方向參考。文章來源:http://www.zghlxwxcb.cn/news/detail-847405.html
mg-PNsqyAXj-1709273282763)]
網(wǎng)上學(xué)習(xí) Android的資料一大堆,但如果學(xué)到的知識(shí)不成體系,遇到問題時(shí)只是淺嘗輒止,不再深入研究,那么很難做到真正的技術(shù)提升。希望這份系統(tǒng)化的技術(shù)體系對(duì)大家有一個(gè)方向參考。
本文已被CODING開源項(xiàng)目:《Android學(xué)習(xí)筆記總結(jié)+移動(dòng)架構(gòu)視頻+大廠面試真題+項(xiàng)目實(shí)戰(zhàn)源碼》收錄文章來源地址http://www.zghlxwxcb.cn/news/detail-847405.html
到了這里,關(guān)于android原生開發(fā)教程,安卓開發(fā)入門到精通的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!