記錄2019年安卓面試

  • 你在項目里都用到了那些設(shè)計模式酬屉,以及你了解知道的設(shè)計模式负懦,和運(yùn)用場景。

a. 建造者模式:將一個復(fù)雜的對象的構(gòu)建拆分缩滨,一個復(fù)雜的對象可能存在多種不同的表現(xiàn)形式势就,使用同樣的構(gòu)造過程,可以創(chuàng)建出來不同的表現(xiàn)脉漏。

比如:常見的安卓使用這種模式的有AlertDialog苞冯,在開發(fā)的例子Camera開發(fā)過程中,可能需要設(shè)置一個初始化的相機(jī)配置侧巨,設(shè)置攝像頭方向舅锄,閃光燈開閉,成像質(zhì)量等等司忱,這種場景下就可以使用建造者模式巧娱。

b.裝飾者模式:動態(tài)地給一個對象添加一些額外的職責(zé)碉怔。裝飾者可以在不改變原有類的結(jié)構(gòu)上增強(qiáng)類的功能。

比如:需要擴(kuò)展一個類的功能禁添,或給一個類增加附加功能時撮胧,可以使用裝飾者模式,這樣的話就可以使用裝飾者模式老翘,比如在項目里面封裝好的網(wǎng)絡(luò)請求芹啥,在后期開發(fā)中,需要添加新的功能铺峭,可以在向外包裝一層墓怀。

c.觀察者模式:定義對象間的一種一個對多個的依賴關(guān)系,當(dāng)一個對象的狀態(tài)發(fā)生變化的時候卫键,所有依賴它的對象都要得到通知并自動更新傀履。

比如:項目中有用到的地方可以說在網(wǎng)絡(luò)框架這里,封裝網(wǎng)絡(luò)狀態(tài)的時候莉炉,跟住不同的網(wǎng)路狀態(tài)來設(shè)置不同的功能钓账,比如WIFI,移動網(wǎng)絡(luò)絮宁,或者是無網(wǎng)絡(luò)的時候的一些處理梆暮,可以通過觀察網(wǎng)絡(luò)的狀態(tài)來實現(xiàn)。

  • 說說java的線程绍昂,以及你對線程池的理解啦粹。
線程的創(chuàng)建方法

1.繼承Thread類實現(xiàn)多線程
2.實現(xiàn)Runnable接口
3.實現(xiàn)Callable接口

線程與進(jìn)程的區(qū)別

進(jìn)程包括線程,一個進(jìn)程可以有多個線程窘游,不同的進(jìn)程使用不同的內(nèi)存空間唠椭,所有的線程同享同一個內(nèi)存空間。

Java中Runnable和Callable有什么不同忍饰?

Runnable和Callable都代表著在不同線程里面執(zhí)行的任務(wù)贪嫂。Ruannable是在java1.0出來的,而Callable是在java1.5后出來的喘批,主要區(qū)別是Callable的call()方法有返回值或者拋出異常,而runnable的run()沒有這個功能铣揉。Callable可以返回裝載有計算結(jié)果的Future對象饶深。

java中的關(guān)鍵字volatile是什么

volatile關(guān)鍵字只能作用在成員變量上,被volatile修飾的變量逛拱,可以保證下一個讀取操作會在前一個寫操作之后發(fā)生敌厘。

一個線程發(fā)生異常會怎么樣?

簡單的說朽合,如果異常沒有被捕獲的話俱两,該線程就會被停止饱狂。
對于沒有捕獲的異常,我們的方法是通過給線程設(shè)置UncaughtExceptionHandler,即對未知異常的處理宪彩,這時你就可以進(jìn)行相關(guān)日志操作了.

class MyExceptionHandler implements UncaughtExceptionHandler {
    @Override
    public void uncaughtException(Thread t, Throwable e) {//在這你可以記錄相關(guān)錯誤日志到文件中
        System.out.printf("An exception has been captured\n");
      System.out.printf("Thread:%s\n", t.getName());
      System.out.printf("Exception: %s: %s:\n", e.getClass().getName(), e.getMessage());
      System.out.printf("Stack Trace:\n");
      e.printStackTrace();
      System.out.printf("Thread status:%s\n", t.getState());
}
//然后把你創(chuàng)建的異常處理類休讳,設(shè)置給你的線程就可以了。
  Thread thread = new Thread(new ThreadTest1()); 
        thread.setUncaughtExceptionHandler(new MyExceptionHandler());
        thread.start();
如何在多線程中共享數(shù)據(jù)

這個問題你首先要想到的是我們常舉得例子尿孔,賣票和存款的例子俊柔。
賣票的例子是做的同一個操作,也就是多個線程使用同一個runnable就可以活合。
存款的例子是讓封裝共同數(shù)據(jù)雏婶,讓共享數(shù)據(jù)成為成員變量,書寫不同的runnable白指,來調(diào)用共享類的成員變量留晚,使用像阻塞隊列這樣并發(fā)的數(shù)據(jù)結(jié)構(gòu)。用wait和notify方法可以實現(xiàn)生產(chǎn)者消費(fèi)者模型告嘲。實現(xiàn)數(shù)據(jù)的共享错维。

java中堆和棧有什么不同

每個線程都有自己的棧內(nèi)存,而多個線程共享同一個堆內(nèi)存状蜗。最主要的區(qū)別就是棧內(nèi)存用來存儲局部變量和方法調(diào)用需五。而堆內(nèi)存用來存儲Java中的對象。無論是成員變量轧坎,局部變量宏邮,還是類變量,它們指向的對象都存儲在堆內(nèi)存中缸血。

活鎖與死鎖

活鎖:優(yōu)先級相同的線程蜜氨,互相禮讓,都不執(zhí)行捎泻,最終導(dǎo)致活鎖
死鎖:多個線程需要互相等待對方的操作資源的時候飒炎,其他線程持有資源不釋放而導(dǎo)致的,常見的情況就是線程持有的鎖不同而導(dǎo)致的笆豁。其實就是互相不禮讓郎汪,最終導(dǎo)致死鎖。
餓死:有一個線程一直禮讓闯狱,最終導(dǎo)致這個線程的任務(wù)一直不執(zhí)行煞赢。

單例模式的雙檢鎖問題
public class Singleton {
 //正確的是加上 volatile關(guān)鍵字  private static volatile Singleton uniqueInstance; 
    private static Singleton uniqueInstance; 


    private Singleton(){
    }

    public static Singleton getInstance(){
        if(uniqueInstance == null){ //#1
            synchronized(Singleton.class){ //#2
                if(uniqueInstance == null){ //#3
                    uniqueInstance = new Singleton(); //#4
                    System.out.println(Thread.currentThread().getName() + ": uniqueInstance is initalized..."); //#5.1
                } else {
                    System.out.println(Thread.currentThread().getName() + ": uniqueInstance is not null now..."); //#5.2
                }
            }
        }
        return uniqueInstance;
    }
}

情況假如線程1進(jìn)來,走到#1哄孤,判斷實例為空照筑,讓出cpu的執(zhí)行權(quán)給線程2.
線程2進(jìn)來執(zhí)行#1 判斷為空,讓出cpu的執(zhí)行權(quán),給線程1凝危。
線程1一直走到#2波俄,#3,#4蛾默,出去懦铺,線程2進(jìn)來,由于線程2在#1中持有的實例為空趴生,所以也就會走#2阀趴,#3,#4.從而創(chuàng)建出兩個對象苍匆。
加上volatile后刘急,這個關(guān)鍵字可以及時更新每個線程里面的數(shù)據(jù)變化,也就是可以保證下一個讀取操作會在前一個寫操作之后發(fā)生浸踩。

什么是線程池叔汁,如何使用
  • 什么是線程池:java提供了Executor接口的實現(xiàn)用于創(chuàng)建線程池,線程池主要是用來管理線程的检碗。
    其中有四個常用的線程池
    ①newSingleThreadExecutor
    單個線程的線程池据块,即線程池中每次只有一個線程工作,單線程串行執(zhí)行任務(wù)
    ②newFixedThreadExecutor(n)
    固定數(shù)量的線程池折剃,沒提交一個任務(wù)就是一個線程另假,直到達(dá)到線程池的最大數(shù)量,然后后面進(jìn)入等待隊列直到前面的任務(wù)完成才繼續(xù)執(zhí)行
    ③newCacheThreadExecutor(推薦使用)
    可緩存線程池怕犁,當(dāng)線程池大小超過了處理任務(wù)所需的線程边篮,那么就會回收部分空閑(一般是60秒無執(zhí)行)的線程,當(dāng)有任務(wù)來時奏甫,又智能的添加新線程來執(zhí)行戈轿。
    ④newScheduleThreadExecutor
    大小無限制的線程池,支持定時和周期性的執(zhí)行線程
線程池的工作原理

線程池可以減少創(chuàng)建和銷毀線程的次數(shù)阵子,從而減少系統(tǒng)資源的消耗思杯,當(dāng)一個任務(wù)提交到線程池時

a. 首先判斷核心線程池中的線程是否已經(jīng)滿了,如果沒滿挠进,則創(chuàng)建一個核心線程執(zhí)行任務(wù)色乾,否則進(jìn)入下一步

b. 判斷工作隊列是否已滿,沒有滿則加入工作隊列领突,否則執(zhí)行下一步

c. 判斷線程數(shù)是否達(dá)到了最大值暖璧,如果不是,則創(chuàng)建非核心線程執(zhí)行
任務(wù)攘须,否則執(zhí)行飽和策略漆撞,默認(rèn)拋出異常
結(jié)合項目的例子:多張圖片的上傳,在使用線程池后可以減少上傳的時間于宙。原本上傳需要9秒浮驳,用線程池后需要2秒。

  • 內(nèi)存泄漏問題
  1. 非靜態(tài)內(nèi)部類造成的內(nèi)存泄漏
    非靜態(tài)的內(nèi)部類會持有外部類的指引捞魁,當(dāng)在內(nèi)部類中做一些不可控制生命周期的操作就有可能會產(chǎn)生內(nèi)存泄漏至会,比如在線程中執(zhí)行耗時操作就有可能發(fā)生內(nèi)存泄漏,導(dǎo)致外部類無法被回收谱俭,直到耗時任務(wù)結(jié)束奉件,解決辦法是在頁面退出時結(jié)束線程中的任務(wù)
  2. 非靜態(tài)內(nèi)部類的靜態(tài)實例造成的內(nèi)存泄漏。
    非靜態(tài)內(nèi)部類會持有外部類的指引昆著,如果非靜態(tài)內(nèi)部類的靜態(tài)實例县貌,就會長期持有外部類的指引,這樣外部類就不會被系統(tǒng)回收凑懂,解決方法是把非靜態(tài)內(nèi)部類寫成靜態(tài)內(nèi)部類煤痕。
  3. handler內(nèi)存泄漏
    handler也是非靜態(tài)內(nèi)部類造成的內(nèi)存泄漏幌缝,因為handler內(nèi)部有一個MessageQueue用來存放message狞悲,有些message不能被及時處理會長時間存在于內(nèi)存中唱星,導(dǎo)致handler無法被回收徽千,如果handler屬于非靜態(tài)內(nèi)部類萝玷,所以持有外部類的指引符匾,導(dǎo)致外部類不能被回收往湿,解決方法1.使用靜態(tài)handler研侣,外部類引用使用弱引用處理2.在退出頁面時移除消息隊列中的消息扫夜。
  4. Context導(dǎo)致的內(nèi)存泄漏
    跟住場景需要使用Activity還是Application的Context楞泼,因為他們的生命周期不一樣,一些不需要使用Activity的Context的地方就換成Application的Context历谍。最常見的就是單例傳入的上下文引起的內(nèi)存泄漏现拒,比如傳入一個Activity的Context被靜態(tài)類引用,導(dǎo)致無法回收望侈。
  5. 靜態(tài)View引起的內(nèi)存泄漏
    使用靜態(tài)View可以避免每次啟動Activity都去讀取并渲染View印蔬,但是靜態(tài)View會持有Activity的引用,導(dǎo)致無法回收脱衙,解決辦法是在Activity銷毀的時候?qū)㈧o態(tài)View設(shè)置為null(View一旦被加載到界面中將會持有一個Context對象的引用侥猬,在這個例子中,這個context對象是我們的Activity捐韩,聲明一個靜態(tài)變量引用這個View退唠,也就引用了activity)
  6. 資源對象未關(guān)閉導(dǎo)致的內(nèi)存泄漏
    file,Cursor荤胁,內(nèi)部都設(shè)置了緩存瞧预,在不適用的時候一定要關(guān)閉。
  7. bitmap造成的內(nèi)存泄漏
    bitmap是比較占內(nèi)存的,所以一定要在不使用的時候及時進(jìn)行清理垢油,避免靜態(tài)變量持有大的bitmap對象
  8. 集合造成的內(nèi)存泄漏
    集合用于保存對象盆驹,如果集合越來越大,不進(jìn)行合理的清理滩愁,尤其是入股集合是靜態(tài)的
  9. 監(jiān)聽器未關(guān)閉造成的內(nèi)存泄漏
    注冊的廣播啊躯喇,服務(wù)啊等,不用的時候一定要取消掉硝枉。
  • onRestart的調(diào)用場景

按home鍵后再回到界面
從A界面跳到B界面廉丽,又按返回鍵返回A界面
從本Activity切換到其他的應(yīng)用,然后再從其他應(yīng)用切換回來妻味,會調(diào)用onRestart()正压;

  • 橫豎屏切換時生命周期

1、不設(shè)置Activity的android:configChanges時责球,切屏?xí)匦抡{(diào)用各個生命周期蔑匣,切橫屏?xí)r會執(zhí)行一次,切豎屏?xí)r會執(zhí)行兩次

2棕诵、設(shè)置Activity的android:configChanges="orientation"時裁良,切屏還是會重新調(diào)用各個生命周期,切橫校套、豎屏?xí)r只會執(zhí)行一次

3价脾、設(shè)置Activity的android:configChanges="orientation|keyboardHidden"時,切屏不會重新調(diào)用各個生命周期笛匙,只會執(zhí)行onConfigurationChanged方法

  • SurfaceView與View的區(qū)別侨把。
  1. View是底層單緩沖機(jī)制,SurfaceView是雙緩沖機(jī)制
  2. View主要試用于主動更新妹孙,SurfaceView適用于被動更新秋柄,頻繁更新。
    3 .View的繪制是在UI主線程蠢正,SurfaceView的繪制是單獨(dú)開一個線程骇笔。

SurfaceView的內(nèi)容不在應(yīng)用窗口上,所以不能使用變換(平移嚣崭、縮放笨触、旋轉(zhuǎn)等)。也難以放在ListView或者ScrollView中雹舀,不能使用UI控件的一些特性比如View.setAlpha()

View:顯示視圖芦劣,內(nèi)置畫布,提供圖形繪制函數(shù)说榆、觸屏事件虚吟、按鍵事件函數(shù)等寸认;必須在UI主線程內(nèi)更新畫面,速度較慢串慰。

SurfaceView:基于view視圖進(jìn)行拓展的視圖類废麻,更適合2D游戲的開發(fā);是view的子類模庐,類似使用雙緩機(jī)制,在新的線程中更新畫面所以刷新界面速度比view快油宜,Camera預(yù)覽界面使用SurfaceView掂碱。

  • Android 中的線程有那些,原理與各自特點
  • ANR的原因

1.耗時的網(wǎng)絡(luò)訪問
2.大量的數(shù)據(jù)讀寫
3.數(shù)據(jù)庫操作
4.硬件操作(比如camera)
5.調(diào)用thread的join()方法、sleep()方法慎冤、wait()方法或者等待線程鎖的時候
6.service binder的數(shù)量達(dá)到上限
7.system server中發(fā)生WatchDog ANR
8.service忙導(dǎo)致超時無響應(yīng)
9.其他線程持有鎖疼燥,導(dǎo)致主線程等待超時
10.其它線程終止或崩潰導(dǎo)致主線程一直等待

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市蚁堤,隨后出現(xiàn)的幾起案子醉者,更是在濱河造成了極大的恐慌,老刑警劉巖披诗,帶你破解...
    沈念sama閱讀 206,968評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件撬即,死亡現(xiàn)場離奇詭異,居然都是意外死亡呈队,警方通過查閱死者的電腦和手機(jī)剥槐,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來宪摧,“玉大人粒竖,你說我怎么就攤上這事〖赣冢” “怎么了蕊苗?”我有些...
    開封第一講書人閱讀 153,220評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長沿彭。 經(jīng)常有香客問我朽砰,道長,這世上最難降的妖魔是什么喉刘? 我笑而不...
    開封第一講書人閱讀 55,416評論 1 279
  • 正文 為了忘掉前任锅移,我火速辦了婚禮,結(jié)果婚禮上饱搏,老公的妹妹穿的比我還像新娘非剃。我一直安慰自己,他們只是感情好推沸,可當(dāng)我...
    茶點故事閱讀 64,425評論 5 374
  • 文/花漫 我一把揭開白布备绽。 她就那樣靜靜地躺著券坞,像睡著了一般。 火紅的嫁衣襯著肌膚如雪肺素。 梳的紋絲不亂的頭發(fā)上恨锚,一...
    開封第一講書人閱讀 49,144評論 1 285
  • 那天,我揣著相機(jī)與錄音倍靡,去河邊找鬼猴伶。 笑死,一個胖子當(dāng)著我的面吹牛塌西,可吹牛的內(nèi)容都是我干的他挎。 我是一名探鬼主播,決...
    沈念sama閱讀 38,432評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼捡需,長吁一口氣:“原來是場噩夢啊……” “哼办桨!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起站辉,我...
    開封第一講書人閱讀 37,088評論 0 261
  • 序言:老撾萬榮一對情侶失蹤呢撞,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后饰剥,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體殊霞,經(jīng)...
    沈念sama閱讀 43,586評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,028評論 2 325
  • 正文 我和宋清朗相戀三年汰蓉,在試婚紗的時候發(fā)現(xiàn)自己被綠了脓鹃。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,137評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡古沥,死狀恐怖瘸右,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情岩齿,我是刑警寧澤太颤,帶...
    沈念sama閱讀 33,783評論 4 324
  • 正文 年R本政府宣布,位于F島的核電站盹沈,受9級特大地震影響龄章,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜乞封,卻給世界環(huán)境...
    茶點故事閱讀 39,343評論 3 307
  • 文/蒙蒙 一做裙、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧肃晚,春花似錦锚贱、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽监徘。三九已至,卻和暖如春吧碾,著一層夾襖步出監(jiān)牢的瞬間凰盔,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評論 1 262
  • 我被黑心中介騙來泰國打工倦春, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留户敬,地道東北人。 一個月前我還...
    沈念sama閱讀 45,595評論 2 355
  • 正文 我出身青樓睁本,卻偏偏與公主長得像尿庐,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子添履,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,901評論 2 345

推薦閱讀更多精彩內(nèi)容