《2022年 Android 中高级面试题汇总》及答案整理(备战金九银十)
面試題分享
Android進程間通信的實現方式
Binder
Socket
文件共享(如sharedPreference)
intent
contentProvider
AIDL
廣播
服務
自定義view流程
繼承view或groupView或已有原生控件
如有需要自定義屬性
在onmeasure中確定view的大小
在ondraw中畫出內容
如有需要暴露設置屬性的方法
ANR是什么,怎么避免
ANR即Application not responsing,應用無響應
在Android系統中,activity5秒內無響應則出現ANR,廣播10秒,服務20秒
避免:將耗時的同步操作放到子線程執行(網絡請求,文件讀寫,海量數據處理等)
消息機制
消息機制中有四個關鍵類,Handler、Message、Looper、MessageQueue
Handler是用來輔助消息發送和處理的類,可通過復寫handleMessage來處理 Message,通過post或postDelay來發送消息
Message是消息的載體,what屬性是消息的標識,用int值來標記不同的消息類型,obj為消息中包含的信息,一般用于存放處理消息是要用到的數據;還有一些數組和數值的屬性是一些便捷的存放數據的屬性
MessageQueue是消息的隊列,名字雖然是隊列,但是MessageQueue是用單鏈表實現的,因為單鏈表在插入和刪除上表現較好;MessageQueue使用先進先出的原則,按序取出消息
Looper是一個不斷輪詢MessageQueue的類,會不斷取出MessageQueue中的消息;每一個線程中只能有一個Looper;主線程的Looper在線程創建的時候就自動創建并開始輪詢了
Looper的存放使用ThreadLocal實現,ThreadLocal用于創建一個線程的共享變量,當在一個已有Looper的線程中再次創建Looper,會拿到相同的Looper
性能優化
布局優化:盡量將減少布局的層級,很少情況下使用的布局可以使用stub標簽,使用include標簽減少重復布局的編寫
繪制優化:自定義控件中的ondraw方法盡量不要做耗時操作和盡量少的初始化操作,保證繪制的流暢性
線程優化:多線程開發時多使用線程池對線程進行管理,更好地復用線程以及對最大并發進行控制
內存泄漏優化:handler、AsynTask、靜態變量、廣播、contentReceiver等的使用注意處理潛在的內存泄漏問題
廣播注冊的方式與區別
靜態注冊:在清單文件中聲明廣播,這種廣播是常駐型廣播,長期占用內存,占用CPU資源,但這種廣播可以在app不運行的時候監聽,例如開機廣播
動態注冊:在Application或其他組件中用代碼動態聲明的廣播,非常駐型廣播,廣播的生命周期和組件綁定,但要在onDestroy的時候注銷廣播,否則容易造成內存泄漏
進程保活,避免service死亡
進程保活:可以使用AlarmManager或WorkManager定時啟動activity,當進程死亡后拉起;使用前臺服務來提高進程的優先級,提高進程的存活率
service保活:設置為前臺服務提高優先級;在進程中輪詢service是否死亡,死亡則重新啟動;在onStartCommand中返回STICKY,當service被殺死后,系統會盡量復活粘性服務;onDestroy時發送一個自定義廣播,收到廣播重啟service
怎么避免OOM,加載圖片OOM
出現OOM一個很大的原因是因為內存泄漏,久而久之內存就會被占滿從而出現OOM,代碼中處理好ML的問題可以減少OOM出現的概率;避免一次性聲明大量的對象或使用輕量級的對象;按需使用弱引用,使得發送GC的時候能夠釋放更多的內存
OOM還會出現在加載比較大圖片的情況下,比如加載多張大圖片到UI中,不進行處理的話,圖片就會直接加載到內存中,容易發生OOM,解決方法是加載圖片之前,先對圖片的大小進行估計,從而判斷是否需要進行圖片壓縮,而且不在使用中的圖片可以考慮釋放內存,需要用的時候重新加載
GC
Java有自動回收機制,即GC(Garbage Collection),當jvm判斷一個對象已經“無用”了,就會釋放其內存;是否“無用”jvm依靠一種引用鏈的機制判斷(弱引用除外,弱引用無論如何都會被回收)
只要這個對象在GC Root的引用鏈中的話,這個對象就是“有用”,反之為“無用”
GC Root有如下: 正在運行的線程、靜態變量、native中調用的方法、棧幀中的局部變量等
8ML的發生就是一個對象其實已經是無用的了,但是缺由于某種原因還存在于GC Root的引用鏈中,jvm判斷為“有用”,這時候就不會回收該對象從而發生內存泄漏
Fragment與Fragment、Activity之間的通信
Fragment:Fragment之間是不能直接通信的,需要通過宿主Activity為橋梁通信
Activity:Activity可以在添加Fragment的時候使用Bundle給Fragment傳遞數據;可以使用FragmentManager的方法findFragmentById和findFragmentByTag來得到Fragment實例來傳遞數據
Fragment可以通過在onAttach回調中獲取實現了自定義接口的Activity對象從而調用接口的方法進行向Activity傳輸數據;也可以使用getActivity獲取宿主Activity的實例;共用viewmodel也可以實現通信。
RecyclerView和ListView的區別
RecyclerView可以實現ListView的顯示效果,同時也可以實現瀑布流的效果;也可以設置滾動的方向
RecyclerView的item復用不用手動實現,已經封裝好了(viewHolder) RecyclerView可以實現局部刷新
需要使用動畫的情況下,RecyclerView的性能比ListView好,而且RecyclerView提供了使用動畫的API
單純顯示列表數據兩者區別不大
Glide框架的優缺點
優點:加載的生命周期與activity的生命周期綁定、儲存的圖片內存占用較小、多媒體緩存、可以設置優先級加載、支持okhttp和volley獲取網絡圖片
缺點:因為格式的問題,顯示的圖片清晰度不足,但可以設置不同的格式
常見網絡請求框架的比較
volley: google公司推出的一款輕量級的異步網絡請求框架
優點是封裝性好,使用門檻低,框架小,封裝了ImageLoader
缺點是不能用于上傳大數據
okhttp:
優點是性能好、封裝好了同步異步、線程池、錯誤處理等,API使用起來很方便
缺點是實際使用的時候一般需要再封裝一層以提高便捷性
retrofit: 基于okhttp的網絡請求框架
對okhttp的進一步封裝使得有更強的易用性,比如使用大量注解以減少代碼量等,跟Rxjava有很好的融合性,同時也繼承了okhttp的高性能
缺點是使用門檻較高
設計模式
單例模式:
單例模式是指某個對象在全局只存在唯一的一個實例,這樣的設計模式能避免一些內存占用較大的對象被頻繁創建,能在全局中提供一個唯一的實例(多用于管理類)
做法是將類構造方法私有化,然后在類中聲明一個該類的對象并向外提供獲取該對象的方法(一般是getInstance),該方法被調用時,先判斷內部類對象是否為空,為空則創建一個實例賦值給該對象并返回,不為空則直接返回該對象
單例模式的實現方法有:枚舉實現,單鎖式,雙鎖式,加載初始式、靜態內部對象式
建造者模式:
建造者模式能夠將構建具有復雜屬性的對象的過程變成鏈式調用,使得構建對象更加清晰明了
做法是在對象中定義一個靜態內部類Builder,定義一套跟外部類屬性完全相同的屬性,并定義一系列的設置方法,方法的返回都是this(實現鏈式調用)
最后定義一個build方法,用Builder中的屬性構建外部對象并返回
觀察者模式:
觀察者模式旨在響應,即被觀察者發生變化是會即時通知觀察者(可以是多個觀察者)
策略模式:
策略模式強調多個具有相同功能但實現不同的邏輯應該講功能抽象成接口
例如同一個功能支付,卻有支付寶、微信、銀聯卡等不同的具體實現邏輯,這時候應該講支付功能抽象成一個接口,不同的支付方式實現這個接口并定義具體的支付邏輯
好處是方便對不同實現邏輯的增刪改,面對接口編程,對修改關閉,對拓展開放
但只適用于程序掌握全部所有的邏輯的情況下
工廠模式:
工廠模式是一種創建對象的設計模式,該設計模式識具體的構建邏輯不會暴露,相當于你需要一臺汽車,你去工廠提車但并不需要知道這汽車是怎么造出來的
做法是定義一個接口對象(比如車),實現多個子類,子類里是具體的構建方法(紅色的車、柴油車、汽油車等的具體生產的方法),接著創建一個能根據具體需要創建對象的工廠類(汽車廠),使用工廠(向工廠提要求,比如我要一臺汽油車),工廠根據要求選擇相應的子類(汽油車的生產方法),構建一個接口對象返回(工廠交付一臺車)
由于文章的篇幅原因,面試題的分享就到這里
其實最重要的就是一句話,問問你自己:
你現在所擁有的技術層次真的有信心步入更高階的程序員當中嗎?
近段時間我這里整理了一份完整的《2022年 Android 中高級面試題匯總》; 這份資料包含了Java和Android兩大部分,由于篇幅原因,這里只展示部分知識點, 希望這份系統化的技術體系對大家有一個方向參考
有需要的朋友可以 在評論區下方留言“面試”或者直接私信我 即可 免費獲取
完整目錄如下:
《2022年 Android 中高級面試題匯總》
由于篇幅有限,僅展示部分內容
第一章 Java 基礎
第一節 靜態內部類和非靜態內部類的比較
1.1 靜態內部類和非靜態內部類的區別
1.2 擴展:內部類都有哪些?
1.3 同部內部類
1.4 匿名內部類:是一種沒有炎名的內部類
第二節 多態的理解與應用
2.1 多態概述
2.2 多態中成員的持點
2.3 instanceof關樁字
2.4 多態的轉型
2.5 多態案例
第三節 java 方法的多態性理解
3.1 什么是java的多態
3.2 遠行時多態3.3代碼理解
3.4 深一點
3.5 再深一點
3.6 最后一個煉習
第四節 java中接口和選承的區別
第五節 線程池的好處,詳解,單例(絕對好記)
5.1 線程池的好處
5.2 線程池的詳解
5.3 線程池的單例
第二章 Android 基礎
第一節 Activity 知識點(必問)
1.1 Activity 啟動過程全解析
1.2 啟動模式以及使用場景
1.3 onSavelnstanceStatelJBonRestorelnstar
1.4onConfigurationChanged使用以及問題解決
第二節 Fragment 知識點
2.1 Fragment的通信問題,新建Fragment為何不
2.2 為什么官方推薦Fragment.setArguments(B
2.3 Androidx下Fragment懶加載的新實現
2.4 Fragment全解析系列(一):那些年深過的
2.5 Google-Fragment 概覽
2.6 Google -與其他 Fragment 通信
第三節 Service 知識點
3.1 Handle 知識點(必問)
3.2 Android 主線程阻塞處理及優化
3.3深入聊聊Android消息機制中的消息隊列的
3.4深入理解MessageQueue
3.5 你真的懂Handler.postDelayed(的原理嗎?
3.6 Handler.postDelayed0是如何精確延遲指成
3.7 Handler 延遲消息執行機制,會阻塞嗎?
第四節Intent知識點
4.1 Android 跨進程傳遞大內存數據
4.2 數據存健
最后我想說:
技術是無止境的,你需要對自己提交的每一行代碼、使用的每一個工具負責,不斷挖掘其底層原理,才能使自己的技術升華到更高的層面
Android 架構師之路還很漫長,與君共勉
總結
以上是生活随笔為你收集整理的《2022年 Android 中高级面试题汇总》及答案整理(备战金九银十)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 无人机DLG生产作业流程
- 下一篇: MATLAB机器人工作空间三轴机器人sc