2019android面試匯總

https://github.com/whatshappen/Android_Question

面試題1.

Android開發(fā)過程中的版本適配問題?

  • Android4.4適配:
    uri轉(zhuǎn)path需要適配

  • Android5.0適配:
    分包適配 -〉在5.0及以上在appgradle文件中配置multiDexEnabled true即可色难,但是5.0以下需要倒入jar七蜘,然后在Applicationattch方法中進行初始化

  • Android6.0:
    權(quán)限適配 -〉敏感權(quán)限動態(tài)申請;

  • Android7.0:
    Uri.fromFile()適配 -〉使用FileProvider進行適配遮咖;
    Android出于安全考慮關(guān)閉了網(wǎng)絡(luò)/拍照/錄像系統(tǒng)廣播;

  • Android8.0:
    Service啟動方式適配 -〉需要使用startForegroundService()啟動服務(wù);
    Notification適配 -〉添加了渠道和組的概念非春;
    軟件安裝適配 -〉Android8.0去掉了“允許未知來源”選項,需要用戶手動確定缓屠,所以安裝程序需要在AndroidManifest.xml文件中添加REQUEST_INSTALL_PACKAGES權(quán)限奇昙;
    廣播適配 -〉AndroidManifest.xml中注冊的廣播不能使用隱式,需要明確指定敌完。
    權(quán)限適配-〉讀寫權(quán)限分離

面試題2.

關(guān)于協(xié)程的概念
簡單的介紹:協(xié)程又稱微線程储耐,是一個線程執(zhí)行。協(xié)程看上去也是子程序滨溉,但是不同的是可以在子程序內(nèi)部中斷轉(zhuǎn)而去執(zhí)行其他子程序什湘,然后在合適的時候再返回中斷位置繼續(xù)執(zhí)行。
協(xié)程特點
執(zhí)行效率高:沒有多線程的線程間切換的開銷晦攒;
不需要多線程的鎖機制:因為只有一個線程闽撤,所以不需要

面試題3.

synchronizedlock的區(qū)別?
synchronized會主動釋放鎖脯颜,而lock需要手動調(diào)用unlock釋放鎖哟旗;

synchronizedjava內(nèi)置的關(guān)鍵字,而lock是個java類;

面試題4.

Handler機制如何保證消息不錯亂热幔?消息延遲是如何實現(xiàn)的乐设?Handler、Looper绎巨、MessageQueue三者對應(yīng)關(guān)系近尚?內(nèi)存泄漏如何避免?Looper中的死循環(huán)為什么不會引器主線程ANR场勤?
1.handler機制中多個handler共有一個looper不會錯亂是因為在handler 發(fā)送消息的時候戈锻,會將當(dāng)前的handler對象綁定到messagetarget屬性上,然后在Looper取到消息后通過msg.target拿到之前的handler對象和媳,然后調(diào)用handlerhandleMessage方法格遭。

2.消息延遲的原理:handler發(fā)送延遲消息,會將當(dāng)前的延遲時間綁定到msgwhen屬性上留瞳,然后在循環(huán)MessageQUeue獲取msg時判斷如果當(dāng)前有延遲就進行阻塞拒迅,通過計時器計算時間,時間通過系統(tǒng)啟動計算時間她倘,然后等待阻塞時間結(jié)束之后將其喚醒璧微,在阻塞過程中會將之后的消息放在消息隊列的頭部去處理。

3.同一個線程中可以有多個Handler硬梁,只有一個Looper前硫,而MessageQueuelooper中初始化的,所以也只有一個MessageQueue荧止。因此對應(yīng)關(guān)系是:Handler:Looper = 多對一屹电,Looper:MeesageQueue = 一對一,Handler:MessageQueue = 多對一跃巡。

4.Handler的內(nèi)存泄漏是由于Handler持有外部類的引用危号,使其無法釋放。
解決辦法:(1)定義成靜態(tài)內(nèi)部類瓷炮,使其不持有外部類的引用葱色;(2)可以使用弱引用;
還需要在外部類銷毀的時候娘香,移除所有的消息。

5.可以說整個應(yīng)用的生命周期都是在looper.loop()控制之下的(在應(yīng)用啟動的入口main函數(shù)中初始化ActivityThread办龄,Handler烘绽,Looper,然后通過handlerlooper去控制初始化應(yīng)用)俐填。而looper.loop采用的是Linux的管道機制安接,在沒有消息的時候會進入阻塞狀態(tài),釋放CPU執(zhí)行權(quán)英融,等待被喚醒盏檐。真正會卡死主線程的操作是在回調(diào)方法onCreate/onStart/onResume等操作時間過長歇式,會導(dǎo)致掉幀,甚至發(fā)生ANR胡野,looper.loop本身不會導(dǎo)致應(yīng)用卡死材失。

面試題5.

開發(fā)過程中如果想替換第三方jar中的某個class文件,或者在開發(fā)時你的class文件與jar中的重名硫豆,但是你想使用自己的應(yīng)該如何解決龙巨?如果你替換掉某個方法又該怎么解決?
可以獲取到j(luò)ar的源碼或者將jar反編譯獲取到java項目熊响,然后替換掉自己想要的.java文件或者方法旨别;
方式二:可以通過類加載器將目標(biāo)class替換成自己的class

面試題6.

IONIO的區(qū)別汗茄?

image.png

第一點:IO是面向流的秸弛,NIO是面向緩沖區(qū)的。
IO面向流意味著每次從流中讀一個或多個字節(jié)洪碳,直至讀取所有字節(jié)胆屿,它們沒有被緩存在任何地方。此外偶宫,它不能前后移動流中的數(shù)據(jù)非迹。
NIO是面向緩存的。數(shù)據(jù)讀取到一個緩沖區(qū)纯趋,需要時可在緩沖區(qū)中前后移動憎兽。這就增加了處理過程中的靈活性。但是吵冒,還需要檢查是否該緩沖區(qū)中包含所有您需要處理的數(shù)據(jù)纯命。而且要確保當(dāng)更多的數(shù)據(jù)讀入緩沖區(qū)時,不要覆蓋緩沖區(qū)中未處理的數(shù)據(jù)痹栖。

第二點:IO的各種流是阻塞的亿汞。這意味著,當(dāng)一個線程調(diào)用read()write()時揪阿,該線程被阻塞疗我,直到有一些數(shù)據(jù)被讀取,或數(shù)據(jù)完全寫入南捂。該線程在此期間不能再干任何事情吴裤。NIO的非阻塞模式,使一個線程從某通道發(fā)送請求讀取數(shù)據(jù)溺健,但是它僅能得到目前可用的數(shù)據(jù)麦牺,如果目前沒有數(shù)據(jù)可用時,就什么都不會獲取,而不是保持線程阻塞剖膳,在數(shù)據(jù)可讀之前魏颓,該線程可以繼續(xù)做其他的事情。 非阻塞寫也是如此吱晒。一個線程請求寫入一些數(shù)據(jù)到某通道甸饱,但不需要等待它完全寫入,這個線程同時可以去做別的事情枕荞。 線程通常將非阻塞IO的空閑時間用于在其它通道上執(zhí)行IO操作柜候,所以一個單獨的線程現(xiàn)在可以管理多個輸入和輸出通道(channel)

面試題7.

單例模式有幾種寫法以及各自的優(yōu)劣躏精?
1.餓漢式:

public class SingleInstance {
    
    private static SingleInstance mInstance = new SingleInstance();
    
    private SingleInstance(){}
    
    public static SingleInstance getInstance(){
        return mInstance;
    }
}

缺點:存在內(nèi)存損耗問題渣刷,如果當(dāng)前類沒有用到也會被實例化

2.懶漢式:

public class SingleInstance {

    private static SingleInstance mInstance = null;

    private SingleInstance(){}

    public static SingleInstance getInstance(){
        if(mInstance==null){
            synchronized (SingleInstance.class){
                if(mInstance==null){
                    mInstance = new SingleInstance();
                }
            }
        }
        return mInstance;
    }
}

缺點:加了synchronized鎖會影響性能
有次被問到為什么要有兩次空判斷?
第一次空判斷和好理解矗烛,可以很大程度上減少鎖機制的次數(shù)辅柴;
第二次判空是因為,如果a瞭吃,b兩個線程都到了synchronized處碌嘀,而假設(shè)a拿到了鎖,進入到代碼塊中創(chuàng)建了對象歪架,然后釋放了鎖股冗,由于b線程在等待鎖,所以a釋放后和蚪,會被b拿到止状,因此此時判空就保證了實例的唯一性。

3.靜態(tài)內(nèi)部類:

public class SingleInstance {
    private SingleInstance(){}
    public static SingleInstance getInstance(){
        return Builder.mInstance;
    }    
    private static class Builder{        
        private static SingleInstance mInstance = new SingleInstance();
    }
}

優(yōu)點:解決了內(nèi)存浪費問題攒霹,同時也避免了加鎖性能問題
為什么這種寫法是線程安全的怯疤?
因為類加載過程是安全的,而靜態(tài)變量是隨著類的加載進行初始化的催束。

4.枚舉形式:

public enum SingleInstance {
     INSTANCE;
}

優(yōu)點:不存在反射和反序列化的問題集峦。
缺點:通過查看枚舉類生成的class文件發(fā)現(xiàn),有多少變量抠刺,就會在靜態(tài)代碼塊中創(chuàng)建多少對象塔淤,所以不建議使用。

定義一些有意義的常量矫付,如果不用枚舉凯沪,怎么解決?
可以使用注解的形式买优,例如:

@IntDef({DataType.INT, DataType.STRING, DataType.FLOAT, DataType.DOUBLE, DataType.OBJECT})
public @interface DataType {
    int INT = 0;
    int STRING = 1;
    int FLOAT = 2;
    int DOUBLE = 3;
    int OBJECT = 4;
}

面試題8.

ArrayList 和LinketList區(qū)別?hashmap的實現(xiàn)原理?hashmap與hashtable的區(qū)別杀赢?
ArrayList與LinketList差別

image.png

ArrayList基于數(shù)組實現(xiàn)烘跺,所以getset操作效率較高脂崔;
LinketList基于鏈表實現(xiàn)(雙向鏈表)滤淳,所以add,remove操作效率較高砌左;

如何實現(xiàn)高效率的查詢和插入結(jié)構(gòu)脖咐?
二叉樹或者散列表
HashMap實現(xiàn)原理
hashmap是由數(shù)組+鏈表結(jié)構(gòu)現(xiàn)實的。獲取到keyhashcode汇歹,然后對數(shù)組長度取余屁擅,找到對應(yīng)的數(shù)組位置index,然后在對應(yīng)的鏈表中判斷是否有當(dāng)前key产弹,從而進行查詢/添加/替換等操作派歌。
HashMap與HashTable區(qū)別

image.png

面試題9.

gson序列化數(shù)據(jù)時如何排除某個字段憋活?
方式一:給字段加上 transient 修飾符

方式二:排除Modifier指定類型的字段黍少。這個方法需要用GsonBuilder定制一個GSON實例。

方式三:使用@expose注解谈况。沒有被 @expose 標(biāo)注的字段會被排除

面試題10.

ButterKnifeXutils注解的區(qū)別斤斧?以及Retrofit中的注解是如何處理的早抠?
ButterKnife采用的是編譯時注解,在編譯時生成輔助類撬讽,在運行時通過輔助類完成操作蕊连。編譯時注解運行效率較高,不需要反射操作锐秦。
XUtils采用的是運行時注解咪奖,在運行時通過反射進行操作。運行時注解相對效率較低酱床。

RetrofitEventBus采用的都是運行時注解羊赵,也就是通過反射技術(shù)處理的。

面試題11.

jvm的類加載機制扇谣?
類加載分類:
BootstrapClassLoader(負責(zé)加載java_home中的jre/lib/rt.jar中的class昧捷,不是ClassLoader的子類)
ExtensionClassLoader(負責(zé)加載java平臺中擴展的一些jar中的class)
AppClassLoader(負責(zé)加載classpath中指定的jarclass文件)
CustomClassLoader(自定義的classloader

JVM的類加載機制采用的是雙親委派模型。


jvm類加載機制.png

類加載過程:
由底層類加載器開始查找是否已經(jīng)加載罐寨,如果底層已經(jīng)加載靡挥,則視為已經(jīng)加載,上層就無需再加載鸯绿,避免重復(fù)加載跋破。如果沒有加載簸淀,則向上層類加載器查找,以此類推毒返,直到頂層類加載器租幕。如果最后發(fā)現(xiàn)頂層類加載器也沒有加載,則先交由頂層類加載器嘗試加載拧簸,如果無法加載劲绪,則交由下層類加器加載,直至底層類加載器盆赤,如果還是無法加載贾富,則JVM會拋出相應(yīng)的類加載異常。

面試題12.

列舉一些git版本控制的常用操作符牺六?

面試題13.

AsyncTask的原理以及弊端颤枪?AsyncTask為什么要求在主線程加載,對象為什么要在主線程創(chuàng)建兔乞?

面試題14.

Android開發(fā)中的屏幕適配方案汇鞭?
swsmallestWidth最小寬度)適配;

通過修改系統(tǒng)的density值進行適配庸追;

面試題15.

多線程中sleepwait的區(qū)別霍骄?
sleepThread的靜態(tài)方法;waitObject中的方法淡溯;

sleep過程中不會釋放鎖读整,不會讓出系統(tǒng)資源;wait會釋放鎖資源咱娶,將其放入等待池中米间,讓出系統(tǒng)資源,讓cpu可以執(zhí)行其他線程膘侮;

sleep之后可以主動釋放鎖屈糊;wait需要手動去notify

面試題16.

輸出字符串中的第一個不重復(fù)的字符琼了,例如:
hello”輸出 ‘h’
“abbac”輸出 ‘c’
“abdabe”輸出‘d’
利用LinketHashMap數(shù)組的有序性和鍵的唯一性來處理:

private void printChar(String source) {
        if (source == null) {
            return;
        }
        String soureTrim = source.replaceAll(" ", "");//去掉字符串中的所有空格
        char[] chars = soureTrim.toCharArray();//拿到字符串對應(yīng)的char[]
        int length = chars.length;
        //用map鍵的唯一性去處理記錄重復(fù)數(shù)據(jù)逻锐,而選擇LinkedHashMap是為了保證有序
        LinkedHashMap<Character, Integer> map = new LinkedHashMap<>();
        //循環(huán)檢測或插入數(shù)據(jù),然后通過value的值記錄當(dāng)前字符出現(xiàn)次數(shù)
        for (int i = 0; i < length; i++) {
            char key = chars[i];
            Integer value = map.get(key);
            if (value == null) {
                map.put(key, 1);
            } else {
                map.put(key, value+1);
            }
        }
        //value=1雕薪,說明只出現(xiàn)一次
        Set<Character> keys = map.keySet();
        for (Character key : keys) {
            Integer integer = map.get(key);
            if (integer == 1) {
                System.out.println("current frist only char is = " + key);
                break;
            }
        }
    }

面試題17.

對有序int數(shù)組去重昧诱,并輸出去重后的長度,并打印出來所袁,要求時間復(fù)雜度為O(n)盏档,空間復(fù)雜度為O(1)。
例如:int[] array = {-1,0,0,2,4,4,4,6};
長度為:5燥爷,打印結(jié)果為:-1蜈亩,0懦窘,2,4勺拣,6

面試題18.

假設(shè)有A奶赠,B鱼填,C三個線程药有,在A線程的執(zhí)行過程中去執(zhí)行B線程,并且等待B線程的執(zhí)行結(jié)果苹丸,然后去執(zhí)行C線程愤惰,然后當(dāng)C線程執(zhí)行完成后,返回結(jié)果給A線程赘理。不阻塞線程宦言,如何實現(xiàn)?(相關(guān)描述我也記不太清了商模,可能有些不準(zhǔn)確奠旺,考點就是Future)

面試題19.

ThreadLocal作用?
ThreadLocal是一個線程內(nèi)的數(shù)據(jù)存儲類施流,可以通過它在指定線程中存儲數(shù)據(jù)响疚,并且只有在當(dāng)前線程可以獲取到存儲的數(shù)據(jù)。通常當(dāng)某些數(shù)據(jù)以線程為作用域并且不同線程具有不同的數(shù)據(jù)副本時使用瞪醋。
通過查看源碼可以知道忿晕,set方法會通過values()方法拿到當(dāng)前線程的ThreadLocal數(shù)據(jù)(Thread類中有個成員變量專門存儲ThreadLocal數(shù)據(jù):ThreadLocal.Values localValues),在localValues內(nèi)部有個數(shù)組Object[] table银受,用于存儲ThreadLocal的值践盼,而位置存儲在ThreadLocalreference的下一個位置。
get方法就是通過當(dāng)前線程的reference拿到localValuestable的位置宾巍,然后index+1獲取數(shù)據(jù)咕幻。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市顶霞,隨后出現(xiàn)的幾起案子肄程,更是在濱河造成了極大的恐慌,老刑警劉巖确丢,帶你破解...
    沈念sama閱讀 222,183評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件绷耍,死亡現(xiàn)場離奇詭異,居然都是意外死亡鲜侥,警方通過查閱死者的電腦和手機褂始,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,850評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來描函,“玉大人崎苗,你說我怎么就攤上這事狐粱。” “怎么了胆数?”我有些...
    開封第一講書人閱讀 168,766評論 0 361
  • 文/不壞的土叔 我叫張陵肌蜻,是天一觀的道長。 經(jīng)常有香客問我必尼,道長蒋搜,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,854評論 1 299
  • 正文 為了忘掉前任判莉,我火速辦了婚禮豆挽,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘券盅。我一直安慰自己帮哈,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 68,871評論 6 398
  • 文/花漫 我一把揭開白布锰镀。 她就那樣靜靜地躺著娘侍,像睡著了一般。 火紅的嫁衣襯著肌膚如雪泳炉。 梳的紋絲不亂的頭發(fā)上憾筏,一...
    開封第一講書人閱讀 52,457評論 1 311
  • 那天,我揣著相機與錄音胡桃,去河邊找鬼踩叭。 笑死,一個胖子當(dāng)著我的面吹牛翠胰,可吹牛的內(nèi)容都是我干的容贝。 我是一名探鬼主播,決...
    沈念sama閱讀 40,999評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼之景,長吁一口氣:“原來是場噩夢啊……” “哼斤富!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起锻狗,我...
    開封第一講書人閱讀 39,914評論 0 277
  • 序言:老撾萬榮一對情侶失蹤满力,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后轻纪,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體油额,經(jīng)...
    沈念sama閱讀 46,465評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,543評論 3 342
  • 正文 我和宋清朗相戀三年刻帚,在試婚紗的時候發(fā)現(xiàn)自己被綠了潦嘶。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,675評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡崇众,死狀恐怖掂僵,靈堂內(nèi)的尸體忽然破棺而出航厚,到底是詐尸還是另有隱情,我是刑警寧澤锰蓬,帶...
    沈念sama閱讀 36,354評論 5 351
  • 正文 年R本政府宣布幔睬,位于F島的核電站,受9級特大地震影響芹扭,放射性物質(zhì)發(fā)生泄漏麻顶。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 42,029評論 3 335
  • 文/蒙蒙 一冯勉、第九天 我趴在偏房一處隱蔽的房頂上張望澈蚌。 院中可真熱鬧,春花似錦灼狰、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,514評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至盈电,卻和暖如春蝴簇,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背匆帚。 一陣腳步聲響...
    開封第一講書人閱讀 33,616評論 1 274
  • 我被黑心中介騙來泰國打工熬词, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人吸重。 一個月前我還...
    沈念sama閱讀 49,091評論 3 378
  • 正文 我出身青樓互拾,卻偏偏與公主長得像,于是被迫代替她去往敵國和親嚎幸。 傳聞我的和親對象是個殘疾皇子颜矿,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,685評論 2 360