2016 最新Android面試題庫

技術負責人:Android源碼中有哪些用到了設計模式?
我:比如dialog的設置,用的是build設計模式,Bitmap用的是工廠設計模式
技術負責人:如果要你設計一個計算器,你從設計模式的角度看,應該怎麼設計呢?
我:寫一個接口,定義一個方法,傳入倆參數,返回一個得數,具體的實現寫在實現類中,然後用工廠設計模式,要什麼方法就生產什麼類來實現。
技術負責人:IO流中有一些流爲了性能更好,我們要定義一個緩存,API中自己實現緩存的是什麼?
我:ByteArrayOutPutStream,先把數據存到內存,再一次輸出 。
技術負責人:內存溢出怎麼檢查?
我:DDMS中有一個heap可以查看進程的內存佔用情況,可以通過它來檢查頁面,也有一個插件mat可以很詳細的看到具體每一個對象的內存佔用情況。
技術負責人:通常怎麼導致內存溢出?
我:內存泄露,比如某一個長期存在的對象引用了某個Activity,那麼當Activity關閉的時候,它佔用的內存並不會被釋放。還有就是內存佔用過多,比如加載一張很大的圖片。
技術負責人:如果我要你加載一個1080p的圖片呢?
我:那可以根據屏幕的分辨率來壓縮圖片,因爲超過屏幕分辨率的圖片顯示在屏幕上效果是一樣的。還可以開一個進程去專門處理這個請求,一個app可以申請十個進程,而每個進程都有16、32這樣的默認app的內存大小。
技術負責人:你的網絡實現是怎麼實現的?
我:一開始是自己用線程池封裝一下android的網絡API,然後調用,後來用的是volley等實現,最後用的是Retrofit。
技術負責人:知道斷點下載麼?
我:(這個問題很熱門啊,我當時說了下斷點下載和多線程下載的原理,黑馬教程中有,上個月樑老師的面試貼中也有,我就不寫了)
技術負責人:對於屏幕適配有什麼瞭解?
我:一個是可以在代碼中動態設置控件大小,一個是設置多個分辨率的圖片,用9patch圖片,單位用dp,一個是用fragment來適配不同大小的屏幕
筆試題:
1.說說你知道的設計模式有哪些?對你熟悉的設計模式做重點介紹?
按照目的來分,設計模式可以分爲創建型模式、結構型模式和行爲型模式。
創建型模式用來處理對象的創建過程;結構型模式用來處理類或者對象的組合;行爲型模式用來對類或對象怎樣交互和怎樣分配職責進行描述。

創建型模式用來處理對象的創建過程,主要包含以下5種設計模式:
? 工廠方法模式(Factory Method Pattern)
? 抽象工廠模式(Abstract Factory Pattern)
? 建造者模式(Builder Pattern)
? 原型模式(Prototype Pattern)
? 單例模式(Singleton Pattern)

結構型模式用來處理類或者對象的組合,主要包含以下7種設計模式:
? 適配器模式(Adapter Pattern)
? 橋接模式(Bridge Pattern)
? 組合模式(Composite Pattern)
? 裝飾者模式(Decorator Pattern)
? 外觀模式(Facade Pattern)
? 享元模式(Flyweight Pattern)
? 代理模式(Proxy Pattern)

行爲型模式用來對類或對象怎樣交互和怎樣分配職責進行描述,主要包含以下11種設計模式:
? 責任鏈模式(Chain of Responsibility Pattern)
? 命令模式(Command Pattern)
? 解釋器模式(Interpreter Pattern)
? 迭代器模式(Iterator Pattern)
? 中介者模式(Mediator Pattern)
? 備忘錄模式(Memento Pattern)
? 觀察者模式(Observer Pattern)
? 狀態模式(State Pattern)
? 策略模式(Strategy Pattern)
? 模板方法模式(Template Method Pattern)
? 訪問者模式(Visitor Pattern)

單例模式實現1:
public class Singleton {
    // 類共享實例對象
    private static Singleton singleton = null;
    // 私有構造方法
    private Singleton() {
        System.out.println("-- this is Singleton!!!");
    }
    // 獲得單例方法
    public synchronized static Singleton getInstance() {
        // 判斷 共享對象是否爲null ,如何爲null則new一個新對象
        if (singleton == null) {
            singleton = new Singleton();
        }
        return singleton;
    }
}

單例模式實現2:
public class Singleton {
    // 類共享實例對象 實例化
    private static Singleton singleton = new Singleton();
    // 私有構造方法
    private Singleton() {
        System.out.println("-- this is Singleton!!!");
    }
    // 獲得單例方法
    public static Singleton getInstance() {
        // 直接返回共享對象
        return singleton;
    }
}
2.String和StringBuffer有什麼區別?在什麼情況下使用它們?
String:
是對象不是原始類型.
爲不可變對象,一旦被創建,就不能修改它的值.
對於已經存在的String對象的修改都是重新創建一個新的對象,然後把新的值保存進去.
String 是final類,即不能被繼承.

StringBuffer:
是一個可變對象,當對他進行修改的時候不會像String那樣重新建立對象
它只能通過構造函數來建立.

效率比較:StringBuffer比String高。因爲StringBuffer有預留空間一直追加,只是對一個對象進行操作。而String是不能被修改的,只能重複的去創建對象來實現修改。——如果頻繁的對字符串進行追加、替換、修改、插入、刪除操作,最好使用StringBuffer。如果必須用String可以使用StringBuffer調用toString()來轉換成String即可。
3.handler機制的原理?
Handler 是一個消息分發對象。而消息分發,有賴於消息循環,也就是 Looper。在一個線程中,Looper 阻塞線程,等待消息構成循環,有了消息,分配到對應的 Handler,讓他進一步分發處理,如是。
4.什麼是MVC?
 MVC(Model/View/Controller)模式是國外用得比較多的一種設計模式,分爲:
 1、模型(Model) 
 2、視圖(View) 
 3、控制器(controller) 
模型-視圖-控制器(MVC)是80年代Smalltalk-80出現的一種軟件設計模式,現在已經被廣泛的使用。 
1、模型(Model) 

模型是應用程序的主體部分。模型表示業務數據,或者業務邏輯. 

2、視圖(View) 

視圖是應用程序中用戶界面相關的部分,是用戶看到並與之交互的界面。 

3、控制器(controller) 

控制器工作就是根據用戶的輸入,控制用戶界面數據顯示和更新model對象狀態。 

5.Activity的生命週期?
Activity中有fvc7個與生命週期有關的函數。其中onCreated()是activity第一次被啓動時執行的,主要是初始化一些變量,onRestart()是當前activity重新被啓動時調用的;綁定一些監聽器等;onStart()是activity界面被顯示出來的時候執行的;onResume()是當該activity與用戶能進行交互時被執行;onPause()是另一個activity被啓動,當前的activity就被暫停了,一般在該函數中執行保存當前的數據;onStop()表示另一個activity被啓動完成時,當前activity對用戶同時又完全不可見時才調用的;onDestroy()是退出當前activity時調用的,當然如果程序中調用finish()或者說android系統當前資源不夠用時就會被調用。
當用多個activity在執行時,這時候android系統會自動將這些activity壓入棧中並且總是顯示最頂的那個activity,這個棧在android叫做task,但是這個棧只支持壓入和彈出操作,不支持排序插入等操作。
Activity的7個生命週期函數中的onStop()函數被調用時是在其對應的activity被另外的activity完全遮擋的時候,如果只有部分遮擋,則不會被調用。部分遮擋一般是以消息activtiy的形式出現,這個只需在AndroidManifest.xml中將其對於的activity的主題設置theme中更改即可。
這7個周期函數,當系統資源不夠時,其中onPause(),onStop(),onDestroy()是有可能被系統kill掉的,但其它4個是不會被kill掉。
6.Activity有哪幾種啓動模式,請簡要介紹他們分別的適用場景?
當應用運行起來後就會開啓一條線程,線程中會運行一個任務棧,當Activity實例創建後就會放入任務棧中。Activity啓動模式的設置在AndroidManifest.xml文件中,通過配置Activity的屬性android:launchMode=""設置。

1. Standared模式(默認)
我們平時直接創建的Activity都是這種模式的Activity,這種模式的Activity的特點是:只要你創建了Activity實例,一旦激活該Activity,則會向任務棧中加入新創建的實例,退出Activity則會在任務棧中銷燬該實例。

2. SingleTop模式
這種模式會考慮當前要激活的Activity實例在任務棧中是否正處於棧頂,如果處於棧頂則無需重新創建新的實例,會重用已存在的實例,否則會在任務棧中創建新的實例。

3. SingleTask模式
如果任務棧中存在該模式的Activity實例,則把棧中該實例以上的Activity實例全部移除,調用該實例的newInstance()方法重用該Activity,使該實例處於棧頂位置,否則就重新創建一個新的Activity實例。

4. SingleInstance模式
當該模式Activity實例在任務棧中創建後,只要該實例還在任務棧中,即只要激活的是該類型的Activity,都會通過調用實例的newInstance()方法重用該Activity,此時使用的都是同一個Activity實例,它都會處於任務棧的棧頂。此模式一般用於加載較慢的,比較耗性能且不需要每次都重新創建的Activity。
16:
筆試題:
1.進入多個Activit後如何一次退出?
市面上普通的方法是拋出異常,或者在每個activity的onDestroy方法中循環退出。我是通過創建一個ActivityCollector類,管理activity。其中有addActivity,removeActivity和finishAll三個方法。再創建一個BaseActivity去讓所有的activity繼承。在onCreate方法中調用ActivityCollector的addActivity,onDestory方法中調用removeActivity方法。最後在你想要一鍵退出程序的地方調用finishAll方法即可。
2.註冊廣播接收器的方式,談談優缺點與優先級?
首先寫一個類要繼承BroadcastReceiver
第一種是在配置文件裏面進行靜態註冊,第二種是在代碼中進行動態註冊

兩種註冊類型的區別:
靜態註冊是當程序關閉後,如果有廣播發過來,還能啓動程序
動態註冊的生命週期跟程序的生命週期是一樣的,程序關閉後動態註冊的廣播是不能再接收到廣播的

動態註冊的優點:在Android的廣播機制中,動態註冊的優先級高於靜態註冊的優先級,因此在必要情況下,我們需要動態註冊廣播接收器。
靜態註冊的優點:動態註冊廣播接收器還有一個缺點就是當用來註冊廣播的Activity關閉後,廣播也就失效了,同時反映了靜態註冊廣播的一個優勢,就是無需擔心廣播接收器是否關閉,只要設備處於開啓狀態,廣播接收器就能接收。
3.代碼混淆有什麼作用?哪些代碼不能混淆,爲什麼?
混淆器的作用不僅僅是保護代碼,它也有精簡編譯後程序大小的作用。
     Android系統組件,系統組件有固定的方法被系統調用。

  被Android Resource 文件引用到的。名字已經固定,也不能混淆,比如自定義的View 。

  Android Parcelable ,需要使用android 序列化的。

  其他Anroid 官方建議 不混淆的,如

  android.app.backup.BackupAgentHelper
  android.preference.Preference
  com.android.vending.licensing.ILicensingService
  Java序列化方法,系統序列化需要固定的方法。

  枚舉 ,系統需要處理枚舉的固定方法。

  本地方法,不能修改本地方法名

  annotations 註釋

  數據庫驅動

  有些resource 文件

  用到反射的地方
4.Property Animation與Tween Animation的區別?
Tween動畫通過view的matrix和alpha變量對view進行修改,但是並不會修改view自身屬性。
而Property動畫會修改view的自身屬性,動畫結束後的效果會實實在在的反應在view上。

5.如何解決ListView中加載大量圖片的內存溢出問題?請詳細談談解決思路。
方法一:
在從網絡或本地加載圖片的時候,把其變爲縮略圖。
方法二:
運用JAVA的軟引用,進行圖片緩存,將經常需要加載的圖片放在緩存裏,避免重複加載。
方法三:
使用第三方框架:volley,xUtils,Fresco等圖片緩存框架。

項目經理:那你們消息的推送是用的pull還是push,你是怎麼選擇的?
我:要獲取服務器上不定時更新的信息,一般來說有兩種方法:
第一種是客戶端使用Pull的方式,就是隔一段時間就去服務器上獲取一下信息,看是否有更新的信息出現。
第二種就是 服務器使用Push的方式,當服務器端有新信息了,則把最新的信息Push到客戶端上。這樣,客戶端就能自動的接收到消息。
雖然Pull和Push兩種方式都能實現獲取服務器端更新信息的功能,但是明顯來說Push方式比Pull方式更優越。
因爲Pull方式更費客戶端的網絡流量,更主要的是費電量,還需要我們的程序不停地去監測服務端的變化。(面試官在點頭)
項目經理:那你已經打開過這個app了,正在使用,現在後臺配置的應用下載變化了,你是怎麼做的這個動態變化?
我:這個問題我們也考慮到了,這就用到了上面提到的消息通知。服務端會推送一個應用推薦改變的消息,攜帶一個狀態碼,當客戶端接收到這個消息後,識別狀態碼,然後會主動地向服務端發起一個請求應用推薦列表的消息的請求。此時會刷新應用推薦的界面。
項目經理:xutils的多線程斷點下載怎麼實現的?
我:(這部分黑馬的課程裏有提過,還很詳細)其實之前我有研究過xutils的源碼,多線程那一部分其實沒太大的難度,用的是線程池的技術。我講一下斷點下載的思路吧。下載斷開之後,問題是在於怎麼從上一次斷開的位置繼續下載。因爲下載的流可以設置起始位置,那麼問題就轉化爲,你如何知道上一次下載了多少?換句話說下載了多少個byte?xutils用的是一個臨時文件記錄下載的byte數值,下載完畢把這個臨時文件給刪除掉,下次對同一文件啓動下載的時候,去判斷是否存在這個臨時文件,存在就意味着斷點下載,接着就讀取裏面的數值,設置下載的起始點就可以了。基本實現原理是這樣。(面試官其實也不一定知道原理,但看得出來,他對哥這答案挺滿意)
項目經理:嗯。在上家公司待了多久(面試官看來已經不打算面我技術了),爲什麼這個時候想離開?
面試官:#魅族和華爲這兩種機型是很特殊的機型,經常會有一些很奇葩的UI bug,你能不能講講你遇到的bug
我:#我記得之前有一個這樣的bug,在魅族手機上,ListView的Item中的EditText無法編輯,點擊EditText彈出軟鍵盤後,軟鍵盤會立即自動隱藏,當時在別的機型上測試沒問題,一直找不出原因,只在魅族上存在這個問題,非常地奇怪
面試官:#那後來怎麼解決的呢?
我:#將ListView換成RecyclerView,這個問題就不存在了。

一、任務做不完的時候,怎麼辦?
我當時想,如果真做不完了只好加加班了。但是他想知道的肯定不僅僅是做不完的答案,而是通過這個問題看看你實際的經驗。
於是我說,我一般會在項目初期,做項目開發計劃的時候。採取一些預防措施:
1、比如在預估時間上,根據實際情況並且考慮到需求變化、除了寫代碼,人還要開會等(一天的coding時間其實沒有足8小時)。所以一般會在預估開發週期的時候把完成任務的時間預算提高兩倍。
2、在做程序設計的時候,我就把模塊細分成最小的功能點,做好甘特圖了,這樣能保證每天完成一個可以測試的功能點。
3、穩健就是快捷,我開發不迷信什麼快速開發。做好每個接口的單元測試,健壯、封裝良好的代碼才能保證項目的穩定開發。
4、如果以上的東西都沒法保證項目進度的時候,只能選擇加班了。但這也說明了這個項目當時的準備和計劃並沒有做好。
面試聽完後對我這些話點頭表示贊同。接着問了第二個問題:
二、能不能獨立開發?
我的回答:雖然上家公司是兩個人開發,但我們都是劃分好獨立模塊的,我覺得只要能獨立開發好一個模塊,那麼組成一個APP做獨立開發,我覺得我可以勝任!
項目經理:你們平時有遇到一些oom麼?
我:有的,oom一般是在處理大圖片,和網絡請求的時候會經常遇到。(先從總體上說一下,但是要留有餘想,一般情況下是這樣的,是不是還有特殊的情況,這就叫牽着鼻子走)。但是我認爲(要突出我,這樣顯得自信。),我們應該更多的從java的邏輯思考代碼,要養成良好的編程習慣,比如:我們儘量要少用hashmap ,因爲hashmap,會另外使用一個單獨的區域存儲mappIng映射。要多使用arrymap,他沒有這個問題,或者使用sparsearay稀疏數組,這個可以減少對象的裝箱操作。比如,還有我們要少使用一些enum,枚舉的類型,因爲adroid的官方文檔(始終站在android的角度)上已經說明使用枚舉會申請兩倍的內存。還有bitmap類型,兩種縮放圖片等。
項目經理:你給我講講你項目的架構?
我:旁白:(這個東西,上來很容易把人嚇一跳!),這個時候千萬淡定,這個題目的頻率還是挺高的。很多人對android中的框架有這樣或者那樣的理解,其實上,android中的框架和javaweb中不同,我們知道javaweb有spring,hurbenet,strust,但是android和他們不一樣,他沒有這些明顯的框架。我理解的android的框架(凸顯我)就是:我們在拿到需求後(多說一些關鍵的專業名詞),拿到項目原型圖後,開始着手做項目之前要首先佈局好的代碼。
這裏面,我認爲第一個需要考慮的問題是這四個方面:第一是網絡請求,第二是數據庫的管理(包括一些持久化),第三呢是:三級緩存的使用和大圖片加載。第四呢是:ui框架相關的部分。
除了這個我認爲還需要考慮的是——剛纔那四部分,待會回來講——公共類,你比如說baseaplication ,baseActivity,baseFragment,這些共有類,父類,裏面的一些操作是固定的。比如:我們在baseaplication ,初始化一些數據,綁定一些context,我們在baseActivity,裏面管理線程,使用線程池,管理請求,或者複寫他的返回鍵。(一定要結合項目)這些東西。
另外我們:還需要工具類,這些工具類,包括一些dip轉px的東西,一些數據類型轉換需要的,比如數組轉集合。
當我們考慮一個應用需要的基本部分的時候,比如網絡請求,是我們主要考慮的部分,我們可以利用andorid 原生的httpurlconection,但是他不是很好用,功能不夠強大,調用麻煩。所以一般不怎麼使用,還有一個是httpclient,他是apppchi公司提供的一個,andorid集成到系統中的,但是android 6.0之後(一定要提些新技術)。已經不提供這些api了(顯的自己很關心新技術好學)。,,,,
網絡上還有一些第三方的,我麼有時候要贏,節約成本(很多公司喜歡這種能爲公司考慮的園林工),例如:afinal volloy ,okhttp。這些框架分別有以下特點,我們要根據,,,你比如商城,,,他有請求頻繁,請求量不大的特點,,我們可以用vollery。
6:
1、問自己做的項目,藍牙、LED、WIFI等和硬件對接的項目
答:        藍牙和LED都是硬件已經搞定了,提供一個接口給我,然後我通過接口來讀寫硬件。WIFI的話,就是直接仿照的系統的WIFI功能,連接掃描管理什麼的,所以我就翻了系統的源碼,照着實現。

2、詢問自己做過的視頻項目,都對視頻進行了什麼操作
答:        一些常規的播放、快進、暫停、獲取縮略圖等。

3、有對視頻進行過什麼比如編輯啊裁剪啊等功能麼
答:        那倒沒有,只是一些視頻的播放方面的,不過編輯功能應該也不難,可以嘗試下。

4、開始介紹自己公司的項目流程,提到其中的技術難點
        用wifi與硬件對接,獲取視頻
答:                這個應該沒問題,藍牙、串口、wifi其實都是對數據進行讀寫,只不過是連接方式、讀寫方式不同,既然硬件那邊已經有了接口,根據接口調用就好了。
        對視頻進行編輯,裁剪、濾鏡等,濾鏡功能已經完成。
答:                裁剪的話雖然我沒做過,但是研究一下應該也沒什麼問題
        對視頻進行分享,要求一鍵分享到朋友圈,不用點擊選擇微信朋友圈、編輯
答:                用第三方分享,是要設置一些參數,然後啓動一個選擇分享對象的界面,但是我記得應該是可以不用選擇直接分享的,具體的參數需要查一下。如果第三方這邊沒有這個功能,可以直接和微信那邊交互,因爲只要求朋友圈嘛,直接調用微信分享應該可以實現。
2、你瞭解雲端麼
答        雲端其實也就是一些服務器,和雲端交互也就是和後臺交互,只不過數據的表現形式、存儲方式需要一些改變,本質上和普通的後臺交互沒什麼區別。
                                                                                                                                                                                                                                                         
3、對於一些額外的參數,比如說定位、當前的速度,需要寫進視頻中,應該怎麼獲取這些數據呢。因爲連接wifi的時候是沒有網絡的。
答:        這樣的話可以在傳輸完視頻數據之後,把wifi斷開,連上4G,獲取地理位置,我們是可以直接操作網絡的連接斷開的。要獲取當前的速度的話,手機肯定是在車上的,我們可以利用傳感器獲取當前的加速度參數,然後計算出速度。
安卓筆試題:
1、如何定位和避免內存溢出?
方法1 :  等比例縮小圖片  

                BitmapFactory.Options options = new BitmapFactory.Options();
                options.inSampleSize = 4;

方法2 :  對圖片採用軟引用,及時地進行recycle()操作

                SoftReference<Bitmap> bitmap;
                bitmap = new SoftReference<Bitmap>(pBitmap);
    if(bitmap != null){

            if(bitmap.get() != null && !bitmap.get().isRecycled()){
                bitmap.get().recycle();
                bitmap = null;
            }
        }

方法3 :  對複雜的listview進行合理設計與編碼:
              1.   注意重用Adapter裏面的 convertView  以及holder機制的運用   ----- 參考資料: api demo list 14. Efficient Adapter

 public View getView(int position, View convertView, ViewGroup parent) {
 if (convertView == null) {
            v = mInflater.inflate(resource, parent, false);
            final int[] to = mTo;
            final int count = to.length;
            final View[] holder = new View[count];
            for (int i = 0; i < count; i++) {
                holder[i] = v.findViewById(to[i]);
            }
            v.setTag(holder);
        } else {
        }

          2.  上述方法嘗試還未成功,可用 lazy loading data   ----- 參考資料:api demo  list 13

方法4 : 單個頁面,橫豎屏切換N次後 OOM
         1. 看看頁面佈局當中有沒有大的圖片,比如背景圖之類的。去除xml中相關設置,改在程序中設置背景圖(放在onCreate()方法中):
          Drawable bg = getResources().getDrawable(R.drawable.bg);
          XXX.setBackgroundDrawable(rlAdDetailone_bg);
          在Activity destory時注意,bg.setCallback(null); 防止Activity得不到及時的釋放

         2. 跟上面方法相似,直接把xml配置文件加載成view 再放到一個容器裏,然後直接調用 this.setContentView(View view);方法

         避免xml的重複加載

方法5 : 在頁面切換時儘可能少地重複使用一些代碼,比如:重複調用數據庫,反覆使用某些對象等等......

方法6 :Android堆內存也可自己定義大小 和  優化Dalvik虛擬機的堆內存分配 
    注意若使用這種方法:project build target 只能選擇 <= 2.2 版本,否則編譯將通不過。 所以不建議用這種方式 

    private final static int CWJ_HEAP_SIZE= 6*1024*1024;
    private final static float TARGET_HEAP_UTILIZATION = 0.75f;
    VMRuntime.getRuntime().setMinimumHeapSize(CWJ_HEAP_SIZE);
    VMRuntime.getRuntime().setTargetHeapUtilization(TARGET_HEAP_UTILIZATION);
2、什麼叫ANR,如何定位和避免ANR?
無響應問題,如果你在activity中有進行耗時長的問題,就會產生這個問題。
 在Android中, Activity Manager 和 Window Manager system services 會監控每個程序的運行,當程序出現如下三種情況的時候就會彈出ANR的提示對話框:        1.用戶在進行了一種操作後5秒鐘沒有響應。        2.broadCastReceiver所進行的操作在10秒內沒有完成。        3.Service在20秒內沒返回結果。
1.避免在主線程上進行復雜耗時的操作,比如說發送接收網絡數據/進行大量計算/操作數據庫/讀寫文件等。這個可以通過使用AsyncTask或者使用多線程來實現。
2.broadCastReceiver 要進行復雜操作的的時候,可以在onReceive()方法中啓動一個Service來處理
3.在設計及代碼編寫階段避免出現出現同步/死鎖或者錯誤處理不恰當等情況。
3、寫一個singleton?
class Singleton {
  private static Singleton s;
  private Singleton(){
   System.out.println("A Singleton Model example");
  }
  public static Singleton getSigleton()
  {
   if(s==null)s=new Singleton();
   return s;
  }
}
4、什麼叫observer,畫一下observer的模型?
Observer模式定義對象間的一對多的依賴關係,當一個對象的狀態發生改變時, 所有依賴於它的對象都得到通知並被自動更新。
5、五大布局?
android的佈局方式有五種,分別是:LinearLayout(線性佈局)、FrameLayout(單幀佈局)、RelativeLayout(相對佈局)、AbsoluteLayout(絕對佈局)和TableLayout(表格佈局)。
6、Intent和intentServer的區別?
Intent(意圖)主要是解決Android應用的各項組件之間的通訊。
Intent負責對應用中一次操作的動作、動作涉及數據、附加數據進行描述,Android則根據此Intent的描述,負責找到對應的組件,將 Intent傳遞給調用的組件,並完成組件的調用。
因此,Intent在這裏起着一個媒體中介的作用,專門提供組件互相調用的相關信息,實現調用者與被調用者之間的解耦。
IntentService:異步處理服務,新開一個線程:handlerThread在線程中發消息,然後接受處理完成後,會清理線程,並且關掉服務。
IntentService有以下特點:

(1)  它創建了一個獨立的工作線程來處理所有的通過onStartCommand()傳遞給服務的intents。

(2)  創建了一個工作隊列,來逐個發送intent給onHandleIntent()。

(3)  不需要主動調用stopSelft()來結束服務。因爲,在所有的intent被處理完後,系統會自動關閉服務。

(4)  默認實現的onBind()返回null

(5)  默認實現的onStartCommand()的目的是將intent插入到工作隊列中
7、寫一個代碼,獲取一個數組中,出現次數最多且數值最大的數?

8、反序一個字符串,要求時間複雜度和空間複雜度最低?
StringBuilder sb = new StringBuilder(str);

System.out.println(sb);

String[] s = str.split(" ");

String[] b = new String[s.length];

String temp = null;

for (int j = s.length - 1, i = 0; j >= 0; j--, i++) {

System.arraycopy(s, j, b, i, 1);

}
9、service的生命週期 ,開啓關閉方法?
Service以及描述下它的生命週期:
  Service是運行在後臺的android組件,沒有用戶界面,不能與用戶交互,可以運行在自己的進程,也可以運行在其他應用程序的上下文裏。
  Service隨着啓動形式的不同,其生命週期稍有差別。當用Context.startService()來啓動時,Service的生命週期依次爲:oncreate——>onStartCommand——>onDestroy 當用Context.bindService()啓動時:onStart——>onBind——>onUnbind——>onDestroy。
  Service啓動方式有兩種;一是Context.startService和Context.bindService。
  區別是通過startService啓動時Service組件和應用程序沒多大的聯繫;當用訪問者啓動之後,如果訪問者不主動關閉,Service就不會關閉,Service組件之間因爲沒什麼關聯,所以Service也不能和應用程序進行數據交互。而通過bindService進行綁定時,應用程序可以通過ServiceConnection進行數據交互。
  在實現Service時重寫的onBind方法中,其返回的對象會傳給ServiceConnection對象的onServiceConnected(ComponentName name, IBinder service)中的service參數;也就是說獲取了serivce這個參數就得到了Serivce組件返回的值。Context.bindService(Intent intent,ServiceConnection conn,int flag)其中只要與Service連接成功conn就會調用其onServiceConnected方法,停用Service使用Context.stopService。
10、36轉爲8進制,48轉爲2進制?
44,110000。
其它:Invalidate與PostInvalidate
android中實現view的更新有兩組方法,一組是invalidate,另一組是postInvalidate,其中前者是在UI線程自身中使用,而後者在非UI線程中使用。 
    Android提供了Invalidate方法實現界面刷新,但是Invalidate不能直接在線程中調用,因爲他是違背了單線程模型:Android UI操作並不是線程安全的,並且這些操作必須在UI線程中調用。 
  Android程序中可以使用的界面刷新方法有兩種,分別是利用Handler和利用postInvalidate()來實現在線程中刷新界面。
11.怎樣將apk安裝在模擬器上?
將xxx.apk拷貝到sdk下的adb的路徑下,也就是和adb在同一個文件夾然後進入cmd,進入到該路徑下,輸入adb install xxx.apk,等段時間後即可看到安裝成功,也有提示出現。當然前提是你的模擬器一定是要啓動好了。 
12.如何避免OOM之壓縮?
下面我們就來看一看,如何對一張大圖片進行適當的壓縮,讓它能夠以最佳大小顯示的同時,還能防止OOM的出現。
BitmapFactory這個類提供了多個解析方法(decodeByteArray, decodeFile, decodeResource等)用於創建Bitmap對象,我們應該根據圖片的來源選擇合適的方法。比如SD卡中的圖片可以使用decodeFile方法,網絡上的圖片可以使用decodeStream方法,資源文件中的圖片可以使用decodeResource方法。這些方法會嘗試爲已經構建的bitmap分配內存,這時就會很容易導致OOM出現。爲此每一種解析方法都提供了一個可選的BitmapFactory.Options參數,將這個參數的inJustDecodeBounds屬性設置爲true就可以讓解析方法禁止爲bitmap分配內存,返回值也不再是一個Bitmap對象,而是null。雖然Bitmap是null了,但是BitmapFactory.Options的outWidth、outHeight和outMimeType屬性都會被賦值。這個技巧讓我們可以在加載圖片之前就獲取到圖片的長寬值和MIME類型,從而根據情況對圖片進行壓縮。
13Android給TextView設置透明背景圓角邊框?
在drawable文件夾下新建一個文件設置背景樣式
在drawable文件夾下面新建text_view_border.xml
solid設置填充顏色,顏色值以#80開頭表示透明
stroke 設置邊框寬度,顏色值
corners設置圓角
14而INVISIBLE和GONE的主要區別是:

當控件visibility屬性爲INVISIBLE時,界面保留了view控件所佔有的空間;

而控件屬性爲GONE時,界面則不保留view控件所佔有的空間。
15.PagerAdapter-FragmentPagerAdapter-FragmentStataePagerAdapter的區別?
1---PagerAdapter(適合頁面數量多的)
針對於View視圖的裝載
2---FragmentPagerAdapter(適合於頁面數量少的)
專門針對於fraagment的適配器 繼承自 PagerAdapter 
--- 這裏使用fragment 所被用戶訪問過的頁面都會被緩存到內存
---這種適配器適合於頁面數量不多 且數據操作不多的頁面 一般頁面過多不使用這種適配器因爲很佔內存
3--FragmenStatePagerAdapter 繼承自 PagerAdapter (策略性的存儲方案)
這裏不是所用的被用戶訪問過的fragment會被緩存到內存
只有在當前頁面的左右兩側的fragment  這三個fragment會在內存中
並且每訪問下個fragment 舊的就會被onDetach 新的會onAttach
16.請簡要描述下MVP模式?
model-處理業務邏輯(主要是數據讀寫,或者與後臺通信(其實也是讀寫數據)),view-處理ui控件,presenter-主導器,操作model和view
17.單例模式最好的寫法
public class Singleton {

    private static volatile Singleton instance = null;

    // private constructor suppresses
    private Singleton(){
    }

    public static Singleton getInstance() {
        // if already inited, no need to get lock everytime
        if (instance == null) {
            synchronized (Singleton.class) {
                if (instance == null) {
                    instance = new Singleton();
                }
            }
        }

        return instance;
    }
}
18.new Thread的弊端如下:
1. 每次new Thread新建對象性能差。
2. 線程缺乏統一管理,可能無限制新建線程,相互之間競爭,及可能佔用過多系統資源導致死機或oom。
3. 缺乏更多功能,如定時執行、定期執行、線程中斷。
相比new Thread,Java提供的四種線程池的好處在於:
1. 重用存在的線程,減少對象創建、消亡的開銷,性能佳。
2 可有效控制最大併發線程數,提高系統資源的使用率,同時避免過多資源競爭,避免堵塞。
3. 提供定時執行、定期執行、單線程、併發數控制等功能。

1.對於io流,怎麼提升讀寫速度?
字符輸入流緩衝區BufferedReader和字符輸入流FileReader的區別就是多了個一次讀取一行的方法readLine();字符輸出流緩衝區BufferedWriter比字符輸出流FileWriter多了個換行方法newLine()。
2.Android中的動畫有哪幾類,它們的特點和區別是什麼?
三種,第一種是Tween動畫,第二種是Frame動畫,第三種是Property動畫。Tween動畫,這種實現方式可以使視圖組件移動、放大、縮小以及產生透明度的變化;另一種Frame動畫,傳統的動畫方法,通過順序的播放排列好的圖片來實現,類似電影;Property動畫是指通過改變實際的屬性來實現相應的動畫效果。
3.如何將Activity設置成窗口的樣式?
在清單文件中將對應的Activity的android:theme屬性設置爲android:theme="@android:style/Theme.Dialog"。
4.註冊廣播有幾種方式,有何優缺點?請談談Android引入廣播機制的用意。 
第一種方式:靜態註冊,在Manifest.xml中註冊廣播,是一種比較推薦的方法,因爲它不需要手動註銷廣播(如果廣播未註銷,程序退出時可能會出錯)。
第二種方式:動態註冊,直接在代碼中實現,但需要手動註冊註銷。
Android系統中的廣播是廣泛用於應用程序之間通信的一種手段,它類似於事件處理機制,不同的地方就是廣播的處理是系統級別的事件處理過程(一般事件處理是控件級別的)。靈活運用廣播處理機制,在關鍵之處往往能實現特別的效果。
5.簡單介紹一下Service和IntentService?
Service是android四大組件之一,在後臺運行,沒有界面,比如後臺的數據計算,後臺音樂播放等。IntentService是繼承於Service並處理異步請求的一個類,在IntentService內有一個工作線程來處理耗時操作。
6.Android數據存儲方式有哪些?
SharedPreference、SQLite數據庫存儲、File存儲、ContentProvider、網絡存儲。
7.Android的四種啓動模式?簡單介紹它們的區別。
Activity的啓動模式:默認是standard,每次使用intent啓動一個Activity,都會創建一個新的實例
SingleTop:一個Activity已經存在實例,並且位於棧頂,而且啓動模式是SingleTop的,那麼再次啓動該Activity時,不會創建新的實例,直接使用棧頂的;一個Activity已經存在實例,但不位於棧頂,即使啓動模式是SingleTop的,那麼再次啓動該Activity
時,還會創建新的實例。
調用已經存在的Activity實例時會自動執行回調方法
     @Override
    protected void onNewIntent(Intent intent) {
        // TODO Auto-generated method stub
        super.onNewIntent(intent);
        Log.i(TAG, "CActivity的啓動模式是 SingleTop,已經位於棧頂,不會創建新的實例");
    }
SingleTask:只有一個實例,允許相關聯的 Acitivty和它位於同一個任務中,當已經存在該Activity的實例,再次啓動時,直接使用已有的,會把其之上的所有的Activity實例銷燬。
SingleInstance:只有一個實例,不允許相關聯的 Acitivty和它位於同一個任務中,自己單獨在一個任務中,當已經存在該Activity的實例,再次啓動時,直接使用已有的。
8.Andriod中常用的5種佈局?
LinearLayout、RelativeLayout、FrameLayout、TableLayout、AbsoluteLayout。
9.ListView的優化方案,以及加載大圖片的優化?
listView優化方案
1、如果自定義適配器,那麼在getView方法中要考慮方法傳進來的參數contentView是否爲null,如果爲null就創建contentView並返回,如果不爲null則直接使用。在這個方法中儘可能少創建view。
2、給contentView設置tag(setTag()),傳入一個viewHolder對象,用於緩存要顯示的數據,可以達到圖像數據異步加載的效果。
3、如果listview需要顯示的item很多,就要考慮分頁加載。比如一共要顯示100條或者更多的時候,我們可以考慮先加載20條,等用戶拉到列表底部的時候再去加載接下來的20條。
通過設置BitmapFactory.Options來壓縮大圖片。
10.Android中Intent的作用?
Android中的Intent有兩大作用。
一:用來啓動其他新的Activity。
二:作爲傳遞數據和事件的橋樑。傳遞數據時的代碼有兩種:
第一種是:
Intent intent = new  Intent(CurrentActivity.this , OtherActivity.class); 
intent.putExtra(“data” , somedata); 
第二種是新建一個Bundle,再把該Bundle加入intent,如:
Bundle bundle = new Bundle() ; 
bundle.putString(“data” , somedata) ; 
intent.putExtras(bundle)。
11.如何退出Activity?如何安全退出?
直接finish當前Activity即可。
12.Fragment和Fragment之間怎麼通信?
在Fragment中定義回調接口,在相關聯的Activity中實現,以此間接地與另一個Activity通信。
通過FragmentManager的findFragmentById找到對應的Fragment並與之通信。

1.在android中,請簡述jni的調用過程。
1)安裝和下載Cygwin,下載 Android NDK;
2)在ndk項目中JNI接口的設計;
3)使用C/C++實現本地方法;
4)JNI生成動態鏈接庫.so文件;
5)將動態鏈接庫複製到java工程,在java工程中調用,運行java工程即可。
2.NDK是什麼?
NDK是一些列工具的集合,NDK提供了一系列的工具,幫助開發者迅速的開發C/C++的動態庫,並能自動將so和java 應用打成apk包。
NDK集成了交叉編譯器,並提供了相應的mk文件和隔離cpu、平臺等的差異,開發人員只需簡單的修改mk文件就可以創建出so。
3.面向對象設計的6大基本原則簡介。
開-閉原則,講的是設計要對擴展有好的支持,而對修改要嚴格限制。
里氏代換原則,很嚴格的原則,規則是“子類必須能夠替換基類,否則不應當設計爲其子類。”
依賴倒換原則,“設計要依賴於抽象而不是具體化”。
接口隔離原則,“將大的接口打散成多個小接口”。
合成聚合複用原則,設計者首先應當考慮複合/聚合,而不是繼承。
迪米特法則或最少知識原則,“一個對象應當儘可能少的去了解其他對象”。
單一職責原則。
4.Android常用的設計模式有哪些?
簡單工廠模式、抽象工廠模式、觀察者模式、單例模式、適配器模式,建造者模式。
建造者模式最明顯的標誌就是Build類,而在Android中最常用的就是Dialog的構建,Notification的構建也是標準的建造者模式。
書中以Intent介紹了原型模式,是通過實現Cloneable接口來做的。
靜態工廠方法在Android中比較明顯的例子應該就是BitmapFactory了,通過各種decodeXXX()就可以從不同渠道獲得Bitmap對象。
書中對於責任鏈模式選取的例子非常有代表性,那就是Android的觸摸機制。
書中介紹觀察者模式使用的是ListView的Adapter爲例子,我之前知道Adapter屬於適配器模式,不知道這裏還有觀察者模式的身影。
我覺得,模板方法模式的使用場景也是一句話:流程確定,具體實現細節由子類完成。
這裏要關注一下『流程』這個關鍵字,隨便拿一個抽象類,都符合”具體實現細節由子類完成”的要求,關鍵就在於是否有流程,有了流程,就叫模板方法模式,沒有流程,就是抽象類的實現。
書中講這個模式用的是AsyncTask,各個方法之間的執行符合流程,具體實現由我們完成,非常經典。
裝飾器模式關注於在一個對象上動態的添加方法,而代理模式關注於控制對對象的訪問。
代理模式,代理類可以對它的客戶隱藏一個對象的具體信息。因此,當使用代理模式的時候,我們常常在一個代理類中創建一個對象的實例。而當我們使用裝飾器模式的時候,通常的做法是將原始對象作爲一個參數傳給裝飾者的構造器。
5.如何將SQLite數據庫(dictionary.db文件)與apk文件一起發佈? 
可以將dictionary.db文件複製到Eclipse Android工程中的res raw目錄中。所有在res raw目錄中的文件不會被壓縮,這樣可以直接提取該目錄中的文件。可以將dictionary.db文件複製到res raw目錄中。
6.事件分發主要分爲兩部分:view的事件分發和viewgroup的事件分發。
1.view的事件分發:  dsipatchTouchEvent 方法:事件分發 和 onTouchEvent方法:事件消費。
2.viewGroup的事件分發:  dsipatchTouchEvent 方法:事件分發 和 onTouchEvent方法:事件消費  onInterceptTouchevent:事件攔截。
View和ViewGroup的事件分發和處理的總流程,當我們手指觸摸屏幕時,
事件會傳入到我們編寫的佈局文件的根佈局上,如上面我們自定義的MyLinearLayout中,
尋找MyLinearLayout的dispatchTouchEvent方法進行事件分發,由於LinearLayout中本身沒有該方法,
就往上尋找到其父類ViewGroup的dispatchTouchEvent方法,往下分發前查看該ViewGroup的
onInterceptTouchEvent方法判斷是否需要攔截掉該事件,如果不攔截遍歷其子ViewGroup或子View,
直到碰到該往下分發過程中被某個ViewGroup攔截掉,或者最後分發到手指按下的最裏面的View,
然後按照View的事件處理流程處理該事件。在ViewGroup事件分發過程中,會根據子View或者ViewGroup的
dispatchTouchEvent方法的返回值決定是否繼續遍歷分發下去。
7Android屏幕適配:
適配的最多的3個分辨率:1280*720,1920*1080,800*480。
解決方案:
1.支持各種屏幕尺寸:
    1.使用match_parent,wrap_content,weight。
    2.禁用絕對佈局。
    3.使用限定符。
        1.尺寸限定符。
        2.使用最小寬度限定符。
        3.使用佈局別名。
        4.使用屏幕方向限定符。
        5.使用自動拉伸圖9.png。
2.支持各種屏幕密度    
    1.使用費密度制約像素。
    2.提供備用位圖。
3.實施自適應用戶界面流程。
對不同大小的屏幕提供不同的常用單位大小,對不同的分辨率提供不同的尺寸資源文件。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章