1. 程式人生 > >Android面試總結

Android面試總結

1、自我介紹

    建議事先打個腹稿。不要念簡歷,主要介紹自己的經歷,讓自己脫穎而出。首先貼標籤,講故事,談願景。標籤:給自己貼的標籤要有點特色。看著像是缺點,細想還是有點。講故事:舉例說明。

2、專案介紹

    技術難點,亮點。這個在平時的開發過程中要做好總結。面試隨便哪一些來講就可以了。我就是因為平時沒有總結,所以在面試前要事先整理一下。

2、Java基礎

    建議事先複習Java基礎。

    (1)hashMap,hashTable,ConcurrentHashMap,LinkedHashMap

            HashMap是用散列表儲存鍵-值對,允許NULL鍵和NULL值,非執行緒同步,無序map;HashTable執行緒同步,不允許NULL鍵和NULL值,已廢棄,可用ConcurrentHashMap代替;ConcurrentHashMap執行緒安全,引入“分段鎖”概念,通過將整個map分為多個segment(類似HashTable)可以提供相同的執行緒安全,效率預設提供16倍;LinkedHashMap是HashMap + LinkedList,有序的map,LinkedList可以維護元素的先後順序,可以實現LRU演算法快取。詳細介紹請檢視:

   (2)序列化的方法:serializable和parcelable的優缺點

           序列化的主要目的是將資料轉換成可以儲存或傳輸的形式的過程。serializable可以將資料持久化,是通過IO流的形式將資料寫入硬碟。parcelable效能強於serializable,效率高,但是無法很好的將資料進行持久化。詳細介紹請看:

  (3)ThreadLocal和Volatile的區別

           Volatile可以看做是一個輕量級的synchronize,它的開銷比synchronize低,使用成本更小,但是不具備操作的原子性。ThreadLocal並不是用來解決在多執行緒併發環境下資源的共享問題的,而是用來提供執行緒內的區域性變數。ThreadLocal變數屬於執行緒內部管理。詳細介紹請看:

  (4)如何確定執行緒的執行順序

          執行子執行緒是,呼叫join方法:讓主執行緒等待子執行緒執行結束後再繼續執行。詳細介紹請檢視:

3、Android四大元件

    (1)Activity的啟動模式

            Activity有四種啟動模式:standard、singleTop、singleTask、singleInstance。standard是Activity的預設啟動模式,沒啟動一個Activity就回在棧頂建立一個新的例項,缺點是當Activity已經在棧頂時,再次啟動Activity還需要建立一個新的例項;singleTop模式會判斷要啟動的Activity例項是否位於棧頂,如果位於棧頂則直接複用,否則建立新的例項,缺點是如果Activity並未處於棧頂位置,則可能還會建立多個例項;singleTask模式使Activity在整個應用中只有一個例項,每次啟動Activity時系統首先檢查棧中是否存在當前Activity例項,如果有則直接複用,並把當前Activity之前的所有例項全部出棧;singleInstance模式會啟動一個新的任務來管理Activity例項,並且該例項在整個系統中只有一個,無論在哪個任務棧中啟動該Activity,都會是該Activity所在的任務棧轉移到前臺,主要目的是為了在不同的程式中共享一個Activity。詳細介紹請檢視: 

    (2)service的啟動模式

           service的主要作用:在後臺執行計算任務,執行結果可以跟外界通訊。啟動方式有兩種:startService()和bindService()。startService多次啟動時,onCreate()呼叫一次,onStartCommand()呼叫多次,只會建立一個例項,只需要呼叫一次stopService(),不能進行通訊。bindService啟動的服務是繫結狀態,可以通訊,多次呼叫時onCreate()方法呼叫一次,onBind()呼叫一次。停止的服務用unBindService()。服務可以執行耗時操作嗎?答案是不能,超過20s就回出現ANR。詳細介紹請檢視:

    (3)Broadcast Receiver

             Broadcast Receiver的主要作用是訊息的傳遞,監聽APP的廣播並相應。應用場景有①多執行緒通訊、②Android不同元件間的通訊(包含應用內/應用外)。使用觀察者模式,將傳送和接受解耦。

             有兩種註冊方式:靜態註冊、動態註冊。靜態註冊在AndroidManifest中註冊,不需要啟動應用也可以接受到相應的廣播。動態註冊需要通過Context.registerReceiver()來註冊。詳細介紹請檢視:

    (4)Content provider

             主要作用:作為一個平臺,提供資料的共享,並且提供資料的增刪改查,主要應用於應用間的資料共享。

4、常用的架構,例如:MVC,MVP,MVVM等。

     MVC最核心就是通過Control層來進行調控。Model主要是對資料的操作,View層主要是各種元件和自定義View,Control則主要是Activity。通過Control調控,將View展示和Model操作分離,但是兩者還是有互動,有一定的耦合。另外,Activity除了負責業務邏輯處理還要承載View,處理UI檢視顯示,所以會比較臃腫。

    MVP是對MVC的一種改良模式。Presenter層隔斷了View層和Model層,降低了耦合度。Activity不再同時承載Control和UI顯示,只單獨負責View展示。缺點就是Presenter層左右View層和Model層的橋樑,會很臃腫。而且基本上每個Activity要有相應的Presenter來處理。

     MVVM將Presenter替換成了ViewModel,並通過雙向的資料繫結來實現檢視和資料的互動。簡化了開發,資料和檢視只需要進行一次繫結即可。缺點就是實現方式還比較不完善規範。詳細介紹請檢視:

5、常見的設計模式,理解手寫單例模式、工廠模式等

     簡單說一下單例模式,單例模式可以分為懶漢式和餓漢式。懶漢式在載入類時,不進行初始化;餓漢式在載入類時進行初始化,所以速度會比較慢,但獲取物件的速度比較快。

6、圖片快取與優化(三級快取)

     為了避免OOM,應增加程式的可用記憶體,並及時回收不使用的物件,降低記憶體使用。可以從以下幾個方面進行考慮:

    ①處理圖片,如剪下、壓縮圖片。根據控制元件大小來裁剪圖片減少記憶體浪費。使用縮圖提高載入速度,如果是Bitmap,可以通過設定取樣率,減少BitMap的畫素。

     ②使用快取機制。快取可以提高載入速度,減少不必要的流量消耗。常用的快取機制有三級快取:記憶體、本地和網路。優先載入記憶體快取,如果載入不到則載入檔案快取,若還是載入不到,則網路請求,然後將請求到的資料儲存到記憶體和本地中。記憶體快取可以用LRUCashe實現,本地快取可以實現DisLURCashe,網路請求可以藉助第三方框架,例如Volley。

     ③自定義堆記憶體的大小。如在AndroidManifest的Application節點下加入Android:largeHeap="true"

     ④使用第三方開源圖片框架,比如Picasso、Glide等。他們在圖片的非同步載入、快取、記憶體管理和優化有很好的處理。詳細介紹請看:

7、記憶體洩漏及優化方案

    記憶體洩漏: 如果一個無用物件(不需要再使用的物件)仍然被其他物件持有引用,造成該物件無法被系統回收,以致該物件在堆中所佔用的記憶體單元無法被釋放而造成記憶體空間浪費。常見的記憶體洩漏有:

    ①單例導致記憶體洩漏。

     ②靜態變數導致記憶體洩漏。

     ③非靜態內部類導致記憶體洩漏。

     ④未取消註冊或回撥導致記憶體洩漏。詳細介紹請檢視:

8、記憶體優化之Bitmap

     對於BitMap的優化可以從一下幾個方面進行考慮:

     ①及時回收BitMap的記憶體。

     ②捕獲異常。

     ③快取常用的BitMap物件。

     ④壓縮圖片。詳細介紹請檢視:

9、介紹使用過的開源庫

      這個早面試前將自己平時開發使用過的、比較熟悉的開源庫整理一下就可以了。

10。演算法,理解了解常用的排序演算法

       有的公司會考查一些演算法。所以最好提前複習下常用的演算法。這裡簡單的介紹下氣泡排序。

       原理:比較兩個相鄰的元素,將值大的元素交換至右端。


void bubble_sort(int arr[], int len) {  
    int i, j, tmpValue;  
    for (i = 0; i < len - 1; i++) {        //外層迴圈控制趟數,總趟數為len-1
        for (j = 0; j < len - 1 - i; j++) {  //內層迴圈為當前i趟數 所需要比較的次數
            if (arr[j] > arr[j + 1]){  
                tmpValue = arr[j];
                arr[j]= arr[j + 1];
                arr[j + 1]= tmpValue;
            }
        }
    }          
}

      如果傳入的陣列是已經排序好的,使用上述方式氣泡排序就變成做無用功了,所以可以進一步優化氣泡排序。優化後代碼如下:

void bubble_sort(int arr[], int len) {  
    int i, j, tmpValue, flag;  
    for (i = 0; i < len - 1; i++) {        //外層迴圈控制趟數,總趟數為len-1
        flag = 0;                            //假設每次進入都是無序的
        for (j = 0; j < len - 1 - i; j++) {  //內層迴圈為當前i趟數 所需要比較的次數
            if (arr[j] > arr[j + 1]){  
                tmpValue = arr[j];
                arr[j]= arr[j + 1];
                arr[j + 1]= tmpValue;
                flag = 1;
            }
            if(flag == 1)
                break;
        }
    }          
}

       當然氣泡排序還可以進一步進行優化。這裡就不再進行介紹了。

11、JNI使用的理解

       JNI的具體使用如果有疑問,可以檢視:

12、介紹強引用、弱引用、軟引用的區別

      強引用,如果引用存在,垃圾回收器永遠不會回收;軟應用,只有軟引用的物件,在記憶體空間不足時,垃圾回收器會進行回收;弱引用,如果物件只有弱引用,一旦被垃圾回收器發現,會被回收。

15、C相關知識點:野指標、記憶體的分配方式、堆疊和堆記憶體的區別

       野指標:野指標指向一個已刪除的物件或未申請訪問受限記憶體區域的指標。

       記憶體的分配方式:靜態儲存區分配、棧區分配、堆區分配。

       靜態儲存區分配:此時的記憶體在程式編譯的時候已經分配好,並且在程式的整個執行期間都存在。全域性變數,static變數等在此儲存。

       棧區分配:相關程式碼執行時建立,執行結束時被自動釋放。區域性變數在此儲存。棧記憶體分配運算內置於處理器的指令集中,效率高,但容量有限。

       堆區分配:動態分配記憶體。用new/malloc時開闢,delete/free時釋放。生存期由使用者指定,靈活。但有記憶體洩露等問題。

瞭解更多Android乾貨帖,請關注微信公眾號:小牛安卓乾貨鋪: