android部分面試題

很不幸,今年是一個非常不平平凡的年,由於種種原因,現在加入找工作的行列中,記錄面試中所問到的基礎與技術問題。

1、內存泄露如何查看和解決

概念:有些對象只有有限的生命週期,當他們的任務完成之後,它們將被垃圾回收,如果在對象的生命週期本該結束的時候,這個對象還被一系列的引用,着就會導致內存泄露。
解決方法:使用開源框架LeakCanary檢測針對性解決
常見的內存泄露有:
單例造成的內存泄露,例如單例中的Context生命週期大於本身Context生命週期
線程使用Hander造成的內存卸扣,當activity已經結束,線程依然在運行更新UI
非靜態類使用靜態變量導致無法回收釋放造成泄露
WebView網頁過多造成內存泄露
資源未關閉造成泄露,例如數據庫使用完之後關閉連接

2、Service啓動方式
1.startService

①.定義一個類繼承service

②.在manifest.xml文件中配置該service

③.使用context的startService(intent)啓動該service

④.不再使用時,調用stopService(Intent)停止該服務

2.bindService

①.創建bindService服務段,繼承自service並在類中,創建一個實現binder接口的實例對象並提供公共方法給客戶端調用

②.從onbind()回調方法返回此binder實例

③.在客戶端中,從onserviceconnected()回調方法接收binder,並使用提供的方法調用綁定服務

3,談MVC ,MVP,MVVM

MVC:View是可以直接訪問Model的!從而,View裏會包含Model信息,不可避免的還要包括一些 業務邏輯。 在MVC模型裏,更關注的Model的不變,而同時有多個對Model的不同顯示,及View。所以,在MVC模型裏,Model不依賴於View,但是 View是依賴於Model的。不僅如此,因爲有一些業務邏輯在View裏實現了,導致要更改View也是比較困難的,至少那些業務邏輯是無法重用的。
MVP:MVP 是從經典的模式MVC演變而來,它們的基本思想有相通的地方:Controller/Presenter負責邏輯的處理,Model提供數據,View負 責顯示。作爲一種新的模式,MVP與MVC有着一個重大的區別:在MVP中View並不直接使用Model,它們之間的通信是通過Presenter (MVC中的Controller)來進行的,所有的交互都發生在Presenter內部,而在MVC中View會從直接Model中讀取數據而不是通過 Controller。
MVVM:數據雙向綁定,通過數據驅動UI,M提供數據,V視圖,VM即數據驅動層

4、Hander原理

Handler,loop輪詢檢測發送消息到MessagerQuery,MessageQuery對Message入列,Handler回調方法處理消息,重寫handMessage方法刷新ui

5、重載(Overloading)與重寫(Overriding)

重載:
重載發生在本類,方法名相同,參數列表不同,與返回值無關,只和方法名,參數列表,參數的類型有關.

重載(Overload):首先是位於一個類之中或者其子類中,具有相同的方法名,但是方法的參數不同,返回值類型可以相同也可以不同。

(1):方法名必須相同

(2):方法的參數列表一定不一樣。

(3):訪問修飾符和返回值類型可以相同也可以不同。

例:

public class Test {
    public void out(){
        System.out.println("參數"+null);
    }
    //參數數目不同
    public void out(Integer n){
        System.out.println("參數"+n.getClass().getName());
    }
 
    //參數類型不同
    public void out(String string){
        System.out.println("參數"+string.getClass().getName());
    }
 
    public void out(Integer n ,String string){
        System.out.println("參數"+n.getClass().getName()+","+string.getClass().getName());
    }
    //參數順序不同
    public void out(String string,Integer n){
        System.out.println("參數"+string.getClass().getName()+","+n.getClass().getName());
    }
    
    public static void main(String[] args) {
        Test test = new Test();
        test.out();
        test.out(1);
        test.out("string");
        test.out(1,"string");
        test.out("string",1);
    }

}

重寫
重寫發生在父類子類之間,比如所有類都是繼承與Object類的,Object類中本身就有equals,hashcode,toString方法等.在任意子類中定義了重名和同樣的參數列表就構成方法重寫.

重寫(override):一般都是表示子類和父類之間的關係,其主要的特徵是:方法名相同,參數相同,但是具體的實現不同。

重寫的特徵:

(1):方法名必須相同,返回值類型必須相同

(2):參數列表必須相同

(3):訪問權限不能比父類中被重寫的方法的訪問權限更低。例如:如果父類的一個方法被聲明爲public,那麼在子類中重寫該方法就不能聲明爲protected。

(4):子類和父類在同一個包中,那麼子類可以重寫父類所有方法,除了聲明爲private和final的方法。

(5):構造方法不能被重寫,
例:


class Test{
    public void out(){
        System.out.println("我是父類方法");
    }
}
 
public class Test1 extends Test{
    @Override
    //方法簽名完全一致
    public void out() {
        System.out.println("我是重寫後的子類方法");
    }
 
    public static void main(String[] args) {
        Test test = new Test();
        test.out();
        test = new  Test1();
        test.out();
    }

6、內存泄漏與內存溢出 

1、內存泄漏memory leak :是指程序在申請內存後,無法釋放已申請的內存空間,一次內存泄漏似乎不會有大的影響,但內存泄漏堆積後的後果就是內存溢出。 
2、內存溢出 out of memory :指程序申請內存時,沒有足夠的內存供申請者使用,或者說,給了你一塊存儲int類型數據的存儲空間,但是你卻存儲long類型的數據,那麼結果就是內存不夠用,此時就會報錯OOM,即所謂的內存溢出
內存溢出的原因及解決方法:

內存泄漏:

也許是因爲活動已經被使用完畢,但是仍然在其他地方被引用,導致無法對其進行回收。我們只需要給對活動進行引用的類獨立出來或者將其變爲靜態類,該類隨着活動的結束而結束,也就沒有了當活動結束但仍然還被其他類引用的情況。
資源性對象在不使用的時候,應該調用它的close()函數將其關閉掉。。
集合容器中的內存泄露 ,我們通常把一些對象的引用加入到了集合容器(比如ArrayList)中,當我們不需要該對象時,並沒有把它的引用從集合中清理掉,這樣這個集合就會越來越大。如果這個集合是static的話,那情況就更嚴重了。
需要在退出程序之前,將集合裏的東西clear,然後置爲null,再退出程序。

WebView造成的泄露,當我們不使用WebView對象時,應該調用它的destory()函數來銷燬它,並釋放其佔用的內存,否則其長期佔用的內存也不能被回收,從而造成內存泄露。
我們應該爲WebView另外開啓一個進程,通過AIDL與主線程進行通信,WebView所在的進程可以根據業務的需要選擇合適的時機進行銷燬,從而達到內存的完整釋放。


內存溢出原因: 
1.內存中加載的數據量過於龐大,如一次從數據庫取出過多數據; 
2.集合類中有對對象的引用,使用完後未清空,使得JVM不能回收; 
3.代碼中存在死循環或循環產生過多重複的對象實體; 
4.使用的第三方軟件中的BUG; 
5.啓動參數內存值設定的過小
內存溢出的解決方案: 
第一步,修改JVM啓動參數,直接增加內存。(-Xms,-Xmx參數一定不要忘記加。)
第二步,檢查錯誤日誌,查看“OutOfMemory”錯誤前是否有其 它異常或錯誤。
第三步,對代碼進行走查和分析,找出可能發生內存溢出的位置。
重點排查以下幾點: 
1.檢查對數據庫查詢中,是否有一次獲得全部數據的查詢。一般來說,如果一次取十萬條記錄到內存,就可能引起內存溢出。這個問題比較隱蔽,在上線前,數據庫中數據較少,不容易出問題,上線後,數據庫中數據多了,一次查詢就有可能引起內存溢出。因此對於數據庫查詢儘量採用分頁的方式查詢。
2.檢查代碼中是否有死循環或遞歸調用。
3.檢查是否有大循環重複產生新對象實體。
4.檢查對數據庫查詢中,是否有一次獲得全部數據的查詢。一般來說,如果一次取十萬條記錄到內存,就可能引起內存溢出。這個問題比較隱蔽,在上線前,數據庫中數據較少,不容易出問題,上線後,數據庫中數據多了,一次查詢就有可能引起內存溢出。因此對於數據庫查詢儘量採用分頁的方式查詢。
5.檢查List、MAP等集合對象是否有使用完後,未清除的問題。List、MAP等集合對象會始終存有對對象的引用,使得這些對象不能被GC回收。
第四步,使用內存查看工具動態查看內存使用情況

7、、View的繪製流程

自定義控件:

1、組合控件。這種自定義控件不需要我們自己繪製,而是使用原生控件組合成的新控件。如標題欄。

2、繼承原有的控件。這種自定義控件在原生控件提供的方法外,可以自己添加一些方法。如製作圓角,圓形圖片。

3、完全自定義控件:這個View上所展現的內容全部都是我們自己繪製出來的。比如說製作水波紋進度條。

View的繪製流程:OnMeasure()——>OnLayout()——>OnDraw()

第一步:OnMeasure():測量視圖大小。從頂層父View到子View遞歸調用measure方法,measure方法又回調OnMeasure。

第二步:OnLayout():確定View位置,進行頁面佈局。從頂層父View向子View的遞歸調用view.layout方法的過程,即父View根據上一步measure子View所得到的佈局大小和佈局參數,將子View放在合適的位置上。

第三步:OnDraw():繪製視圖。ViewRoot創建一個Canvas對象,然後調用OnDraw()。六個步驟:①、繪製視圖的背景;②、保存畫布的圖層(Layer);③、繪製View的內容;④、繪製View子視圖,如果沒有就不用;

⑤、還原圖層(Layer);⑥、繪製滾動條。

8、Android中跨進程通訊的幾種方式

Android 跨進程通信,像intent,contentProvider,廣播,service都可以跨進程通信。

intent:這種跨進程方式並不是訪問內存的形式,它需要傳遞一個uri,比如說打電話。

contentProvider:這種形式,是使用數據共享的形式進行數據共享。

service:遠程服務,aidl

9、AsycTask與一般線程異步之間的差別
  1)是因爲AsyncTask使用了線程池技術,而且其中的方法很容易實現調用
  2)是因爲AsyncTask可以調用相關的方法,在開啓子線程前和後,進行界面的更新
  3)是因爲一旦任務多了,不用每次都new新的線程,可以直接使用
10、線程與進程

線程:線程是操作系統調度的最小單元,也叫輕量級進程。它被包含在進程之中,是進程中的實際運作單位。同一進程可以創建多個線程,每個進程都有自己獨立的一塊內存空間。並且能夠訪問共享的內存變量。”

進程:進程是併發執行程序在執行過程中資源分配和管理的基本單位(資源分配的最小單位)。進程可以理解爲一個應用程序的執行過程,應用程序一旦執行,就是一個進程。每個進程都有自己獨立的地址空間,每啓動一個進程,系統就會爲它分配地址空間,建立數據表來維護代碼段、堆棧段和數據段。

11、網絡請求框架庫

12、Android長連接怎麼處理心跳機制?

維護任何一個長連接都需要心跳機制,客戶端發送一個心跳給服務器,服務器給客戶端一個心跳應答,這樣就形成客戶端服務器的一次完整的握手。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章