python 安卓库_Android高级面试题资料(持续更新)
1. ThreadLocal的理解
可以保證線程的安全。在多個線程共享相同的數(shù)據(jù)的時候,會為每個線程創(chuàng)建單獨的副本,在單獨的副本上進(jìn)行數(shù)據(jù)的操作,不會對其它線程的數(shù)據(jù)產(chǎn)生影響,保證了線程安全。
2. HashMap HashSet HashTable的區(qū)別?
都是集合,底層都是Hash算法實現(xiàn)的。HashMap是Hashtable的替代品,這兩個都是雙列集合,而HashSet是單列集合。HashMap線程不安全、效率高、可以存儲null鍵和null值;Hashtable線程安全,效率低,不可以存儲null鍵和null值。
3. 如何讓HashMap可以線程安全?
HashMap 在并發(fā)執(zhí)行 put 操作時會引起死循環(huán),導(dǎo)致 CPU 利用率接近100%。因為多線程會導(dǎo)致 HashMap 的 Node 鏈表形成環(huán)形數(shù)據(jù)結(jié)構(gòu),一旦形成環(huán)形數(shù)據(jù)結(jié)構(gòu),Node 的 next 節(jié)點永遠(yuǎn)不為空,就會在獲取 Node 時產(chǎn)生死循環(huán)。
使用下面三種替換方式:
Hashtable
ConcurrentHashMap
Synchronized Map
4. Android對HashMap做了優(yōu)化后推出的新的容器類是什么?
SparseArray
它要比 HashMap 節(jié)省內(nèi)存,某些情況下比HashMap性能更好,按照官方問答的解釋,主要是因為SparseArray不需要對key和value進(jìn)行auto-boxing(將原始類型封裝為對象類型,比如把int類型封裝成Integer類型),結(jié)構(gòu)比HashMap簡單(SparseArray內(nèi)部主要使用兩個一維數(shù)組來保存數(shù)據(jù),一個用來存key,一個用來存value)不需要額外的額外的數(shù)據(jù)結(jié)構(gòu)(主要是針對HashMap中的HashMapEntry而言的)。
5. Java多線程之間如何通信
等待喚醒機(jī)制
6. 線程池的實現(xiàn)機(jī)制
向線程池提交任務(wù),會依次啟動核心線程,如果提交的任務(wù)數(shù)超過了核心線程數(shù),會將任務(wù)保存到阻塞隊列中,如果阻塞隊列也滿了,且繼續(xù)提交任務(wù),則會創(chuàng)建新線程執(zhí)行任務(wù),直到任務(wù)數(shù)達(dá)到最大線程數(shù)。此時如果再提交任務(wù)的話會拋出異常或者直接丟棄任務(wù)。通過Executor.execute()無法得到返回值,通過ExecutorService.submit()可以得到返回值。
7. RxJava中map和flatmap操作符的區(qū)別及底層實現(xiàn)
Map返回的是結(jié)果集,flatmap返回的是包含結(jié)果集的Observable。Map只能一對一,flatmap可以一對多、多對多。
RxJava是通過觀察者模式實現(xiàn)的。
8. 對消息機(jī)制中Looper的理解
Looper在消息機(jī)制中扮演的角色是創(chuàng)造無限循環(huán)從Messagequeue中取得消息然后分發(fā)。
9. 單例模式有哪些實現(xiàn)方式
餓漢模式(線程安全,調(diào)用效率高,但是不能延時加載)
懶漢模式(線程安全,調(diào)用效率不高,但是能延時加載)
雙重檢測鎖模式(由于JVM底層模型原因,偶爾會出問題,不建議使用)
靜態(tài)內(nèi)部類式(線程安全,調(diào)用效率高,可以延時加載)
枚舉類(線程安全,調(diào)用效率高,不能延時加載,可以天然的防止反射和反序列化調(diào)用)
10. 通過靜態(tài)內(nèi)部類實現(xiàn)單例模式有哪些優(yōu)點
線程安全,調(diào)用效率高,可以延時加載
11. synchronized volatile關(guān)鍵字有什么區(qū)別?以及還有哪些同樣功能的關(guān)鍵字
(1) volatile是變量修飾符,而synchronized則作用于一段代碼或者方法。
(2) volatile只是在線程內(nèi)存和main memory(主內(nèi)存)間同步某個變量的值;而synchronized通過鎖定和解鎖某個監(jiān)視器同步所有變量的值。顯然synchronized要比volatile消耗更多資源。
const、final、lock
12. 界面卡頓的原因有哪些?
UI線程(main)有耗時操作
視圖渲染時間過長,導(dǎo)致卡頓
13. 造成OOM/ANR 的原因?
OOM: (1)不恰當(dāng)?shù)厥褂胹tatic關(guān)鍵字 (2)內(nèi)部類對Activity的引用 (3)大量Bitmap的使用會導(dǎo)致程序包運行時的內(nèi)存消耗變大 (4)游標(biāo)Cursor對象用完應(yīng)該及時關(guān)閉 (5)加載對象過大 (6)相應(yīng)資源過多,來不及釋放。
ANR: (1)在5秒內(nèi)沒有響應(yīng)輸入的事件(IO操作耗時、數(shù)據(jù)庫操作復(fù)雜耗時、主線程非主線程產(chǎn)生死鎖等待、網(wǎng)絡(luò)加載/圖片操作耗時、硬件操作耗時) (2)BroadcastReceiver在10秒內(nèi)沒有執(zhí)行完畢(Service binder數(shù)量達(dá)到上限、Service忙導(dǎo)致超時無響應(yīng))
14. Activity與Fragment生命周期有何聯(lián)系
在創(chuàng)建的過程中,是Activity帶領(lǐng)著Fragment,在銷毀的過程中,是Fragment帶領(lǐng)著Activity。
這里寫圖片描述
15. Glide三級緩存
內(nèi)存緩存,磁盤緩存、網(wǎng)絡(luò)緩存(由于網(wǎng)絡(luò)緩存嚴(yán)格來說不算是緩存的一種,故也稱為二級緩存)。緩存的資源分為兩種:原圖(SOURCE)、處理圖(RESULT)(默認(rèn))。
內(nèi)存緩存:默認(rèn)開啟的,可以通過調(diào)用skipMemoryCache(true)來設(shè)置跳過內(nèi)存緩存,緩存最大空間:每個進(jìn)程可用的最大內(nèi)存*0.4。(低配手機(jī)0.33)
磁盤緩存:分為四種:ALL(緩存原圖)、NONE(什么都不緩存)、SOURCE(只緩存原圖)、RESULT(之后處理圖),通過diskCacheStrategy(DiskCacheStrategy.ALL)來設(shè)置,緩存大小250M。
16. MVC、MVP、MVVM的原理
(1) MVC,Model View Controller,是軟件架構(gòu)中最常見的一種框架,簡單來說就是通過controller的控制去操作model層的數(shù)據(jù),并且返回給view層展示。當(dāng)用戶發(fā)出事件的時候,view層會發(fā)送指令到controller層,接著controller去通知model層更新數(shù)據(jù),model層更新完數(shù)據(jù)以后直接顯示在view層上,這就是MVC的工作原理。
這里寫圖片描述
(2) MVP是MVC的演化。MVP的model層相對于MVC是一樣的,而activity和fragment不再是controller層,而是純粹的view層,所有關(guān)于用戶事件的轉(zhuǎn)發(fā)全部交由presenter層處理。presenter層充當(dāng)了橋梁的作用,用于操作view層發(fā)出的事件傳遞到presenter層中,presenter層去操作model層,并且將數(shù)據(jù)返回給view層。
這里寫圖片描述
(3) MVVM和MVP的區(qū)別貌似不大,只不過是presenter層換成了viewmodel層,還有一點就是view層和viewmodel層是相互綁定的關(guān)系,這意味著當(dāng)你更新viewmodel層的數(shù)據(jù)的時候,view層會相應(yīng)的變動ui。
這里寫圖片描述
17. 數(shù)據(jù)庫的操作類型有哪些,如何導(dǎo)入外部數(shù)據(jù)庫?
(1) 增刪改查
(2) 將外部數(shù)據(jù)庫放在項目的res/raw目錄下。因為安卓系統(tǒng)下數(shù)據(jù)庫要放在data/data/packagename/databases的目錄下,然后要做的就是將外部數(shù)據(jù)庫導(dǎo)入到該目錄下,操作方法是通過FileInputStream讀取外部數(shù)據(jù)庫,再用FileOutputStrean把讀取到的東西寫入到該目錄下。
18. 是否使用過 IntentService,作用是什么, AIDL 解決了什么問題?
(1) IntentService繼承自Service。由于Service運行在主線程,無法進(jìn)行耗時操作。所以你需要在Service中開啟一個子線程,并且在子線程中運行。為了簡化這一操作,Android中提供了IntentService來進(jìn)行這一處理。通過查看IntentService的源碼可以看到,在onCreate中,我們開啟了一個HandlerThread線程,之后獲取HandlerThread線程中的Looper,并通過這個Looper創(chuàng)建了一個Handler。然后在onStart方法中通過這個Handler將intent與startId作為Message的參數(shù)進(jìn)行發(fā)送到消息隊列中,然后交由Handler中的handleMessage中進(jìn)行處理。由于在onStart方法是在主線程內(nèi)運行的,而Handler是通過工作者線程HandlerThread中的Looper創(chuàng)建的。所以也就是在主線程中發(fā)送消息,在工作者接收到消息后便可以進(jìn)行一些耗時的操作。
(2) 進(jìn)程間通信
19. 是否使用過本地廣播,和全局廣播有什么差別?
本地廣播的數(shù)據(jù)在本應(yīng)用范圍內(nèi)傳播,不用擔(dān)心隱私數(shù)據(jù)泄露的問題。不用擔(dān)心別的應(yīng)用偽造廣播,造成安全隱患。相比在系統(tǒng)內(nèi)發(fā)送全局廣播,它更高效。
20. Activity、 Window、 View 三者的差別, fragment 的特點?
(1) Activity像一個工匠(控制單元),Window像窗戶(承載模型),View像窗花(顯示視圖) LayoutInflater像剪刀,Xml配置像窗花圖紙。
(2) a. Fragment可以作為Activity界面的一部分組成出現(xiàn);
可以在一個Activity中同時出現(xiàn)多個Fragment,并且一個Fragment也可以在多個Activity中使用;
在Activity運行過程中,可以添加、移除或者替換Fragment;
Fragment可以響應(yīng)自己的輸入事件,并且有自己的生命周期,它們的生命周期會受宿主Activity的生命周期影響。
21. Handler、 Thread 和 HandlerThread 的差別
從Android中Thread(java.lang.Thread -> java.lang.Object)描述可以看出,Android的Thread沒有對Java的Thread做任何封裝,但是Android提供了一個繼承自Thread的類HandlerThread(android.os.HandlerThread -> java.lang.Thread),這個類對Java的Thread做了很多便利Android系統(tǒng)的封裝。
android.os.Handler可以通過Looper對象實例化,并運行于另外的線程中,Android提供了讓Handler運行于其它線程的線程實現(xiàn),也是就HandlerThread。HandlerThread對象start后可以獲得其Looper對象,并且使用這個Looper對象實例Handler。
22. 低版本 SDK 實現(xiàn)高版本 api
自己實現(xiàn)或使用注解@TargetApi annotation
23. launch mode 應(yīng)用場景
(1) standard:標(biāo)準(zhǔn)的啟動模式。
這里寫圖片描述
(2) singleTop:單一頂部模式
如果Activity已經(jīng)被開啟,并且處于任務(wù)棧的棧頂,就不會創(chuàng)建新的Activity,而是復(fù)用這個已經(jīng)開啟的Activity。
為了防止出現(xiàn)一些奇怪的用戶體驗,推薦使用單一頂部模式,整個任務(wù)棧可以有多個實例存在.
應(yīng)用場景:短信發(fā)送界面.
這里寫圖片描述
(3)singletask:單一任務(wù)棧
在整個任務(wù)棧里面只允許有一個當(dāng)前Activity的實例存在
如果要開啟的Activity在任務(wù)棧中已經(jīng)存在,直接復(fù)用這個已經(jīng)存在的Activity,并且把這個Activity上面的所有的其他Activity給清空
應(yīng)用場景:如果一個Activity非常消耗內(nèi)存和cpu資源,建議把這個Activity做成singletask的模式。瀏覽器的browserActivity
這里寫圖片描述
(4)singleinstance:單一實例.
整個手機(jī)操作系統(tǒng)只有一個實例存在,并且是運行在自己單獨的任務(wù)棧里面.
應(yīng)用場景:通話界面的Activity
這里寫圖片描述
24. touch 事件傳遞流程
事件處理包括三種情況,分別為:傳遞—-dispatchTouchEvent()函數(shù)、攔截——onInterceptTouchEvent()函數(shù)、消費—-onTouchEvent()函數(shù)和OnTouchListener。
Android事件傳遞流程:
(1) 事件都是從Activity.dispatchTouchEvent()開始傳遞
(2) 事件由父View傳遞給子View,ViewGroup可以通過onInterceptTouchEvent()方法對事件攔截,停止其向子view傳遞
(3) 如果事件從上往下傳遞過程中一直沒有被停止,且最底層子View沒有消費事件,事件會反向往上傳遞,這時父View(ViewGroup)可以進(jìn)行消費,如果還是沒有被消費的話,最后會到Activity的onTouchEvent()函數(shù)。
(4) 如果View沒有對ACTION_DOWN進(jìn)行消費,之后的其他事件不會傳遞過來,也就是說ACTION_DOWN必須返回true,之后的事件才會傳遞進(jìn)來
(5) OnTouchListener優(yōu)先于onTouchEvent()對事件進(jìn)行消費
View不處理事件流程圖
View不處理事件流程圖
View處理事件流程圖
View處理事件流程圖
事件攔截
事件攔截
25.Android性能優(yōu)化
一、代碼優(yōu)化
1.使用AndroidLint分析結(jié)果進(jìn)行相應(yīng)優(yōu)化
2.不使用枚舉及IOC框架,反射性能低
3.常量加static
4.靜態(tài)方法
5.減少不必要的對象、成員變量
6.盡量使用線程池
7.適當(dāng)使用軟引用和弱引用
8.盡量使用靜態(tài)內(nèi)部類,避免潛在的內(nèi)存泄露
9.圖片緩存,采用內(nèi)存緩存LRUCache和硬盤緩存DiskLRUCache
10.Bitmap優(yōu)化,采用適當(dāng)分辨率大小并及時回收
二、布局優(yōu)化
避免OverDraw過渡繪制
優(yōu)化布局層級
避免嵌套過多無用布局
當(dāng)我們在畫布局的時候,如果能實現(xiàn)相同的功能,優(yōu)先考慮相對布局,然后在考慮別的布局,不要用絕對布局。
使用標(biāo)簽把復(fù)雜的界面需要抽取出來
使用標(biāo)簽,因為它在優(yōu)化UI結(jié)構(gòu)時起到很重要的作用。目的是通過刪減多余或者額外的層級,從而優(yōu)化整個Android Layout的結(jié)構(gòu)。核心功能就是減少冗余的層次從而達(dá)到優(yōu)化UI的目的!
ViewStub 是一個隱藏的,不占用內(nèi)存空間的視圖對象,它可以在運行時延遲加載布局資源文件。
三、ListView和GridView優(yōu)化
1.采用ViewHolder復(fù)用convertView
2.避免在getView中執(zhí)行耗時操作
3.列表在滑動狀態(tài)時不加載圖片
4.開啟硬件加速
26.Android內(nèi)存泄漏
內(nèi)存泄漏簡單地說就是申請了一塊內(nèi)存空間,使用完畢后沒有釋放掉。它的一般表現(xiàn)方式是程序運行時間越長,占用內(nèi)存越多,最終用盡全部內(nèi)存,整個系統(tǒng)崩潰。由程序申請的一塊內(nèi)存,且沒有任何一個指針指向它,那么這塊內(nèi)存就泄露了。可能的原因有:
1.注冊沒取消造成內(nèi)存泄露,如:廣播
2.靜態(tài)變量持有Activity的引用
3.單例模式持有Activity的引用
4.查詢數(shù)據(jù)庫后沒有關(guān)閉游標(biāo)cursor
5.構(gòu)造Adapter時,沒有使用 convertView 重用
6.Bitmap對象不在使用時調(diào)用recycle()釋放內(nèi)存
7.對象被生命周期長的對象引用,如activity被靜態(tài)集合引用導(dǎo)致activity不能釋放
8.使用Handler造成的內(nèi)存泄露
阿里云服務(wù)器:活動地址
購買可領(lǐng)取:阿里云代金券
總結(jié)
以上是生活随笔為你收集整理的python 安卓库_Android高级面试题资料(持续更新)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Packet Tracer官网下载
- 下一篇: python 多线程--重点知识