1. 程式人生 > >Android面試中常見問題集錦

Android面試中常見問題集錦

Android面試中常會被問到的問題及解答方式:

1,PendingIntent 和Intent的區別:

PendingIntent就是一個Intent的描述,我們可以把這個描述交給別的程式,別的程式根據這個描述在後面的別的時間做你安排做的事情
換種說法Intent字面意思是意圖,即我們的目的,我們想要做的事情,在activity中,我們可以立即執行它
PendingIntent 相當於對intent執行了包裝,我們不一定一定要馬上執行它,我們將其包裝後,傳遞給其他activity或application
這時,獲取到PendingIntent的application 能夠根據裡面的intent來得知發出者的意圖,選擇攔截或者繼續傳遞或者執行。

Android的四個基本元件中:—— Activity,Service和Broadcast Receiver——都是通過Intent機制啟用的,不同型別的元件有不同的傳遞Intent方式:

    要啟用一個新的Activity,或者讓一個現有的Activity做新的操作,可以通過呼叫Context.startActivity()或者Activity.startActivityForResult()方法。
    要啟動一個新的Service,或者向一個已有的Service傳遞新的指令,呼叫Context.startService()方法或者呼叫Context.bindService()方法將呼叫此方法的上下文物件與Service繫結。
    Context.sendBroadcast()、Context.sendOrderBroadcast()、Context.sendStickBroadcast()這三個方法可以傳送Broadcast Intent。傳送之後,所有已註冊的並且擁有與之相匹配IntentFilter的BroadcastReceiver就會被啟用。

2,Android中的尺寸,以及dp,px,sp的區別和聯絡:

px:表示螢幕實際的畫素。  320*480 :標示:在橫向320個縱向480個畫素。

pt:標示一個點,時螢幕的物理尺寸,大小為1英寸的七十二分之一。

in:標示英寸,時螢幕的物理尺寸,每英寸等於2.54釐米。例如,形容手機大小為3.2英寸,是說螢幕對角線的大小。

dp與sp標尺單位的又來及計算方法:

畫素尺寸:240*320 320*240 320*480 480*800 480*854 640*960 720*1280,

螢幕物理尺寸:3.2、3.5、3.75、4.0、4.3、5.0、7、9.3、10.1

0.75   1.5    2xhdpi    xxhdpi3   4   8

android 程式程式碼部分 採用畫素為單位

程式的佈局所有的尺寸都是採用dp為單位。

公式 :一個dp數值轉換為px的數字:

    px = dp * (dpi/160)

例如:10dp --> 在mdpi  dpi = 160 ;因此  10dp = 10px。

畫素密度:dpi:每英寸畫素數:  如    手機為:240*320  畫素解析度,大小為:1.5*2 英寸。畫素密度:240/1.5 = 320/2 =160dpi。

譬如1280x720物理解析度,5英寸大小的螢幕,其dpi 的計算方法是:sqrt(1280*1280+720*720)/5 = 293.72 dpi

譬如1280x720物理解析度,5英寸大小的螢幕上,<dimen name="indicator_bar_width_large">54dp</dimen>
這個高度如何轉換成 px 呢,計算方法是:54dp * 293.72/160+0.5f = 99.6305px,約為 100px。

dpi = 60
Ldpi = 120 3
mpdpi = 160 4
hdpi= 240 6
xHdpi = 320 8

import android.content.Context;  
public class DensityUtil {  
 
    /**
     * 根據手機的解析度從 dp 的單位 轉成為 px(畫素)
     */  
    public static int dip2px(Context context, float dpValue) {  
        final float scale = context.getResources().getDisplayMetrics().density;  
        return (int) (dpValue * scale + 0.5f);  
    }  
 
    /**
     * 根據手機的解析度從 px(畫素) 的單位 轉成為 dp
     */  
    public static int px2dip(Context context, float pxValue) {  
        final float scale = context.getResources().getDisplayMetrics().density;  
        return (int) (pxValue / scale + 0.5f);  
    }  
} 

  dp,sp,px之間的區別和聯絡:

dp也就是dip,這個和sp基本類似。

若是   設定長度,高度等屬性時,可以使用dp,或者sp。但如果設定字型,需要使用sp。

dp是與密度無關,sp除了與密度無關外,還與scale無關。如果螢幕密度為160,這時dp和sp和px是一樣的。1dp = 1sp = 1px,但如果使用px作單位,如果螢幕大小不變(假設是3.2寸),而螢幕密度變為了320,那麼原來的TextView的寬度設定成160px,在密度為320的3.2寸螢幕裡看到要比在密度為160的3.2寸螢幕上看短了一半。但如果設定成160dp或者160sp的話。系統會自動將width屬性值設定成320px的。也就是160*320/160。其中320/160可稱為密度比例因子。

如果使用dp和sp,系統會根據螢幕密度的變化自動轉換。

3,關於scrool+ListView:

    1,所有的容器在顯示內容之前,都需要進行排版,排版的時候,都需要獲取內部子控制元件或子容器的尺寸,通過尺寸才可以進行排版。

    2,所有的View內部都有一個回撥的方法,onMeasure這個方法,

    3, ScroolView內部控制元件  進行尺寸計算 onMeasure()的時候,

        引數模式  是  UNSPECIFIED.

        ListView的onMeasure :方法,檢測模式  如果是 UNSPECINIED,listView則永遠只有一行。

4,Http請求資料,get,Post的區別:

     在HTTP請求訊息中,請求方式有GET、POST、HEAD、OPTIONS、DELETE、TRACE、PUT和CONNECT八種。而在以後們最常用的有兩種請求方式:POST請求、GET請求。

get和post區別:

GET:從指定的伺服器中獲取資料,POST-提交資料給指定的伺服器處理。

       1,使用GET方法時,查詢字串會以鍵值對的形式附加在action所指向的url的後面一起傳送到伺服器。
       2,使用POST方法時,查詢字串在POST資訊中單獨存在,和HTTP請求一起傳送到伺服器。
       3,get是從伺服器上獲取資料,post是用來向伺服器上傳遞資料。

特點:
    get:
        get請求  能  夠被快取下來。
        get請求 會  儲存在瀏覽器的  瀏覽記錄中。
        以GET  請求的URL能夠儲存為  瀏覽器書籤。
        GET請求的URL能夠  儲存為瀏覽器書籤。
        GET請求   有長度限制。
        GET請求   主要用以獲取資料。

    post:
        資料量大小為128k.

HTTP協議規範也沒有對URL長度進行限制。這個限制是特定的瀏覽器及伺服器對它的限制。IE對URL長度的限制是2083位元組(2K+35)。對於其他瀏覽器,如Netscape、FireFox等,理論上沒有長度限制,其限制取決於作業系統的支援。


http和https的區別:


         https 是以安全為目標的HTTP通道,簡單講是HTTP的安全版,即HTTP下加入SSL層,HTTPS的安全基礎是SSL,因此加密的詳細內容就需
要SSL。它是一個URI scheme(抽象識別符號體系)。句法類同http:體系。用於安全的HTTP資料傳輸。

    https:url表明它使用了HTTP,但HTTPS存在不同於HTTP的預設埠及一個加密/身份驗證與加密通訊方法。  被廣泛應用於全球資訊網上安全敏感的通訊,例如交易支付方面。

5,Handler的介紹:

android提供了Handler和Looper來滿足執行緒間的通訊,Handler先進先出原則,Looper類來管理特定執行緒內物件之間的訊息轉換。

     1,Looper:一個執行緒可以產生一個Looper物件,由他來管理此執行緒裡的MessageQueue(訊息佇列);
     2,Handler:用於push新訊息到MessageQueue裡,或者接受Looper從MessageQueue送來的訊息。
     3,MessageQueue:用來存放執行緒放入的訊息。
     4,Message物件:handler用於傳遞的資料資訊。

handler建立訊息:

    handler訊息機制中引入了訊息池,Handler建立訊息時首先查詢訊息池中是否有訊息存在。如果有直接從訊息池中取得,如果沒有則重新初始化一個訊息例項。訊息不被使用時,並不作為垃圾回收,而是放入訊息池。可供下次Handler建立訊息時使用。
Handler持有對UI主執行緒訊息佇列MessageQueue和迴圈Looper的引用。子執行緒可以通過Handler將訊息傳送到UI執行緒的訊息佇列MessageQueue中。

Handler處理訊息:

    UI主執行緒通過Looper迴圈查詢訊息佇列的UI_MQ,當發現有訊息存在時會將訊息從佇列中取出。首先分析訊息,通過訊息的引數判斷該訊息對應的Handler,然後將訊息分發到指定的Handler進行處理。

handler message messageQueue
每一個訊息傳送到主執行緒的MessageQueue中,MessageQueue遵循先進先出原則,傳送訊息不會阻塞執行緒,而接收執行緒會阻塞執行緒。Handler允許傳送並處理Message訊息,Message物件通過主執行緒的MessageQueue訊息佇列相關聯的Message和Runnable物件進行存取。每個Handler例項對Message訊息傳送和接收與對應主執行緒和主執行緒的訊息佇列有關。當建立一個新的Handler時,Handler就屬於當前主執行緒,主執行緒MessageQueue訊息佇列也同步建立,即Handler會繫結到建立該Handler的主執行緒/訊息佇列上。然後,Handler就可以通過主執行緒的訊息佇列傳送和接收Message訊息物件了。

6,java的記憶體機制:

記憶體:
    暫存器,方法區,棧,堆,本地方法區。
    方法區:存類的資訊,常量池,靜態方法區.
    棧(值型別):存放呼叫方法的區域性變數,
        儲存在棧中的變數,作用域結束立即消失.
    堆(引用型別):存陣列或者引用物件.

        特點:
            1,分配記憶體首地址。
            2,有預設值。
            3,有gc(垃圾回收機制)。

        本地方法區:實現類庫的呼叫.

    注意:常量池中,Java預設建立-128~127之間的常量物件.    對於字串常量會首先去常量池中查詢,如果不存在就建立字串常量.字串常量對像儲存在字串常量池中.

7,raw和assert中的資源有什麼區別:

raw和asserts資料夾的相同點:
    1,兩者目錄下的檔案在打包後會原封不動的儲存在apk包中。不會被編譯成二進位制。


不同點:
    1,raw資料夾中的檔案會被對映到R.java檔案中。訪問的時候直接使用資源id即R.id.fileName;assert不會被對映到R.java中。訪問的時候需要AssertManager類。
    2,raw不可以有目錄結構,而assert則可以有目錄結構,也就是assert下可以再建立資料夾。

讀取檔案資源:   
    inputStream is = getResources().openRawResource(R.id.filename);

讀取assert下的檔案資源,通過以下方式獲取輸入流來進行寫操作。
    AssertManager am = null;    am = getAssert();    InputStream   is = am.open("fileName");

8,fileInputStream 與dataInputStream區別

FileInputStream是實體流,也就是真實做事情的流,用來讀檔案的。使用該類建立物件時,系統會自動將需要讀的檔案轉換成該類的流物件,你可以直接讀取。DataInputStream是裝飾流,必須建立在其他實體流的基礎之上。如果用軟體來類比流的話,那麼作業系統就是實體流,而一般的應用軟體則是裝飾流。因為應用軟體以作業系統軟體為基礎

9,LayoutInfalter  的引數 兩個和三個引數的區別?

View inflate(int resource, ViewGroup root)
View inflate(int resource , ViewGroup root, boolean attachToRoot)

第二個引數   是指    例項的佈局所要放入的根檢視。一般我們在不需要將該佈局放入根檢視的時候都會把第二個數傳為null。

第三個   引數為   是否將   第二個檢視引用到第一個資原始檔上。。

10,Linux程序  和執行緒:

程序是程式執行時的一個例項,即它是程式已經執行到各種程度的資料結構的彙集。從核心的觀點看,程序的目的就是擔當分配系統資源(CPU時間、記憶體等)的基本單位。

執行緒是程序的一個執行流,是CPU排程和分派的基本單位,它是比程序更小的能獨立執行的基本單位。一個程序由幾個執行緒組成(擁有很多相對獨立的執行流的使用者程式共享應用程式的大部分資料結構),執行緒與同屬一個程序的其他的執行緒共享程序所擁有的全部資源。

11,android是什麼:

是基於Linux核心的軟體平臺和作業系統,早期由Google開發

Android平臺手機5大優勢:
      一、開放性.
     二、掙脫運營商的束縛.
      三、豐富的硬體選擇.
      四、不受任何限制的開發商
      五、無縫結合的Google應用

12,Intent的七大屬性:


data(Data屬性   通常用於向Action屬性提供操作的資料。Data屬性的值是個Uri物件)
extras(提供操作的額外資料,可以為各種物件)
category (類別)
flags(為Intent新增控制標記,同activity,LaunchMode)
action   
intentFalter (意圖過濾器,通過action查詢該intent。)
type(Type屬性用於指定Data所指定的Uri對應的MIME型別).


13,fragment和activity的生命週期

fragment生命週期

onAttach(); onCreate();  onCreateView(); onActivityCreated();  onStart(); onResume();

onPause();  onStop(); onDestoryView();   onDestory();   onDetach();


activity的生命週期:

onCreated(),onStart(),onRestart(),onResume(),onPaused(),onStoped(),onDestroyed()

14,事件分發機制:

TouchEvent事件發生時Activity的dispatchTouchEvent(MotionEvent ev)會以隧道方式從根元素依次往下傳遞直到內層子元素或在中間元素由於某一條件停止傳遞。

dispatchTouchEvent事件的分發邏輯:

    1,返回true,進行處理,事件分發給當前view的dispatchTouchEvent方法進行消費,同時事件會停止向下傳遞。
    2,返回false,事件向下分發,此時事件分發分為兩種:如果當前view獲取的事件來自Activity,則會將事件返回給父View的Activity的onTouchEvent進行消費。如果當前View獲取的事件來自父外層控制元件,則會將事件返回給父View的onTouchEvent進行消費。

    3,如果返回系統預設的super.dispatchTouchEvent(ev),事件會自動的分發給當前View的onInterceptTouchEvent方法。

事件攔截方法:onInterceptTouchEvent(MotionEvent ev)

    1,在外層的View的dispatchTouchEvent(MotionEvent ev) 方法返回系統預設的super.dispatchTouchEvent(ev)情況下,事件會自動的分發給當前View的onInterceptTouch
Event方法,onInterceptTouchEvent方法,onInterceptTouchEvent的事件攔截邏輯如下:
        1,如果onInterceptTouchEvent返回true 標示事件將進行攔截,並將攔截到的事件交由當前view的onTouchEvent進行處理。
        2,如果onInterceptTouchEvent返回false,則表示將事件放行,不進行攔截,當前view上的事件會被傳遞到子View上,再由子view的dispatchTouchEvent來開始這個事件的分發。
        3,如果返回super,則預設攔截並將攔截到的事件交由當前的View的onTouchEvent進行處理。

事件響應:onTouchEvent(MotionEvent ev)

    1,在dispatchTouchEvent返回super的情況下,  並且onInterceptTouchEvent返回false或者返回super的情況下onTouchEvent會被呼叫。onTouchEvent的事件相應邏輯如下:
        1,如果事件傳遞到當前View的onTouchEvent方法,而該方法返回了false,那麼這個事件會從當前View向上傳遞,並且都是由上一層View的onTouchEvent來接受,如果傳遞到上面的onTouchEvent也返回false,這個事件就會消失,而且接受不到下一次事件。

        2,如果改事件rue   則會接受消費該事件。
        3,如果返回super預設處理事件的邏輯和返回false相同。

15,IntentReceiver作用:

         當你希望你的應用能夠對一個外部的事件(如當電話呼入時,或者資料網路可用時,或者到了晚上時)做出響應,你可以使用一個IntentReceiver。雖然IntentReceiver 在感興趣的事件發生時,會使用NotificationManager通知使用者,但它並不能生成一個UI。IntentReceiver 在AndroidManifest.xml 中註冊,但也可以在程式碼中使用Context.registerReceiver()進行註冊。當一個intentreceiver 被觸發時,你的應用不必對請求呼叫intentreceiver,系統會在需要的時候啟動你的應用。各種應用還可以通過使用Context.broadcastIntent()將它們自己的intentreceiver 廣播給其它應用程式。

16,UDP和TCP,三次握手和四次揮手::

UDP():半雙工。傳輸快,不安全。資訊量要求速度的適用。

TCP:(請求響應方式)
三次握手:

第一次握手:建立連線時,客戶端傳送syn包(syn=j)到伺服器,並進入SYN_SEND狀態,等待伺服器確認;SYN:同步序列編號(Synchronize Sequence Numbers)。
第二次握手:伺服器收到syn包,必須確認客戶的SYN(ack=j+1),同時自己也傳送一個SYN包(syn=k),即SYN+ACK包,此時伺服器進入SYN_RECV狀態;
第三次握手:客戶端收到伺服器的SYN + ACK包,向伺服器傳送確認包ACK(ack=k+1),此包傳送完畢,客戶端和伺服器進入ESTABLISHED(TCP連線成功)狀態,完成三次握手。
連線終止協議(四次揮手):
  由於TCP連線是全雙工的,因此每個方向都必須單獨進行關閉。這原則是當一方完成它的資料傳送任務後就能傳送一個FIN來終止這個方向的連線。收到一個 FIN只意味著這一方向上沒有資料流動,一個TCP連線在收到一個FIN後仍能傳送資料。首先進行關閉的一方將執行主動關閉,而另一方執行被動關閉。

  (1) TCP客戶端傳送一個FIN,用來關閉客戶到伺服器的資料傳送(報文段4)。
  (2) 伺服器收到這個FIN,它發回一個ACK,確認序號為收到的序號加1(報文段5)。和SYN一樣,一個FIN將佔用一個序號。
  (3) 伺服器關閉客戶端的連線,傳送一個FIN給客戶端(報文段6)。
  (4) 客戶段發回ACK報文確認,並將確認序號設定為收到序號加1(報文段7)。


17,http1.1訪問網路的八種方式:

http協議請求由三部分組成,分別是:請求行、訊息報頭、請求正文。

請求行以一個方法符號開頭,以空格分開,後面跟著請求的URI和協議的版本,格式如下: 

Method Request-URI HTTP-Version CRLF

1,HTTP/1.0協議使用非持久連線,即在非持久連線下,一個tcp連線只傳輸一個Web物件,;
2,HTTP/1.1預設使用持久連線(然而,HTTP/1.1協議的客戶機和伺服器可以配置成使用非持久連線)。

OPTIONS:返回伺服器針對特定資源所支援的HTTP請求方法。也可以利用向Web伺服器傳送'*'的請求來測試伺服器的功能性。
HEAD:向伺服器索要與GET請求相一致的響應,只不過響應體將不會被返回。這一方法可以在不必傳輸整個響應內容的情況下,就可以獲取包含在響應訊息頭中的元資訊。
GET:向特定的資源發出請求。注意:GET方法不應當被用於產生“副作用”的操作中。
POST:向指定資源提交資料進行處理請求(例如提交表單或者上傳檔案)。資料被包含在請求體中。POST請求可能會導致新的資源的建立和/或已有資源的修改。
PUT:向指定資源位置上傳其最新內容。
DELETE:請求伺服器刪除Request-URI所標識的資源。
TRACE:回顯伺服器收到的請求,主要用於測試或診斷。
CONNECT:HTTP/1.1協議中預留給能夠將連線改為管道方式的代理伺服器

18,Fragment的優化:
hide  和  add
正確的切換方式是add(),切換時hide(),add()另一個Fragment;再次切換時,只需hide()當前,show()另一個。
/**
   * 切換頁面的過載,優化了fragment的切換
   *
   * @param f
   * @param descString
   */
  public void switchFragment(Fragment from, Fragment to) {
    if (from == null || to == null)
      return;
    FragmentTransaction transaction = getSupportFragmentManager()
        .beginTransaction().setCustomAnimations(R.anim.tran_pre_in,
            R.anim.tran_pre_out);
    if (!to.isAdded()) {
        // 隱藏   當前的fragment,add下一個到Activity中
        transaction.hide(from).add(R.id.fl_main, to).commit();
      } else {
        // 隱藏當前的fragment,顯示下一個
        transaction.hide(from).show(to).commit();
      }
    // 讓menu回去
    menu.toggle();
}


19:aidl執行緒間通訊介紹:

android系統中的程序之間不能共享記憶體,因此,需要提供一些機制在不同程序之間進行資料通訊。

aidl是一種介面定義語言,用與兩個程序間的通訊規則,共編譯器生成程式碼。實現android裝置上的兩個程序間通訊。

定義步驟:

    1,在專案中建立一個副檔名為aidl的檔案,該檔案的語法類似於java程式碼。
    2,如果aidl檔案的內容是正確的,工具會自動生成一個java介面檔案。
    3,建立一個服務類(service的子類)。
    4,實現由aidl檔案生成的java介面。
    5,在註冊檔案中配置AIDL服務,<action>標籤中的android:name的屬性就是客戶端要引用該服務的ID。也就是intent的引數值。
在Android 中,AiDL是一種介面定義語言,編譯器通過*.aidl檔案的描述資訊生成符合通訊協議的java程式碼,我們無需自己去寫這段繁雜的程式碼,只需要在需要的時候呼叫即可。通過這種方式我們就可以完成程序間的通訊工作。

20,單元測試的步驟和方法:


    第一步:
        在安卓註冊檔案的應用程式application程式碼塊中新增程式碼:
        <users-library android:name="android.test.runner"/>
        在application外部新增程式碼:
        <instrumentation android:name="android.test.InstrumentionTestRunner"
        android:targetPackage = "xx.xx.x.x" android:label = "Tests for My App"/>
    第二部 :
        新建普通類繼承 AndroidTestCase類。編寫測試方法:必須以public void開頭,儘量丟擲異常。在該方法中呼叫需要測試的方法或程式碼。

    第三步:將滑鼠放在測試程式碼的測試方法上,點選run as方法執行測試。


---整合測試:
    
    主要是在單元測試的基礎上測試介面訪問或者非同步任務是否正確。

21,數字簽名的作用:

1,目的是保證軟體包的完整性包含軟體釋出者的證書資訊。
2,作用:
        1,確保軟體包沒有被修改,
        2,android系統根據相同軟體id來區分軟體,如果相同的id,只要證書不同,那麼不允許安裝,除非卸
載原有程式,保護資料。
       3,證書可以包含有效期,如果一個軟體證書的有效期過期了,android不允許程式再運行了。

      1,Key Store:用於 儲存公鑰和私鑰,公鑰包含證書資訊;開發工具使用keystore檔案來進行數字簽名。
      2,團隊中應該使用相同的keystore檔案,進行程式碼的除錯和打包,主要針對百度地圖這種,需要證書資訊的,
      3,如公司已經提供keystore,那麼直接複製出來,放到自己的電腦上。
      4,若沒有提供,需要建立一個 放到工程中。

keyStore檔案的生成:

    1,推薦   在工程中建立keyStore檔案,團隊就可以協同工作了。
    2,名詞:key alias別名:在建立的時候,可以給每一個祕鑰對私鑰,指定一個名稱。
這樣就。

22,Android記憶體的優化:
android優化:記憶體控制,迴圈使用。圖片的優化(二次取樣)。

記憶體優化:
    1,減少記憶體佔有。
    2,及時的快取。
    3,把不適用的記憶體置空
    4,圖片比較大的   進行二次取樣。

android  程式碼優化的核心原則:   
       1、字串頻繁操作時,多用StringBuffer而少用String
       2、儘量使用本地變數,即反覆使用的變數要先儲存成臨時或區域性變數,尤其是迴圈中使用的變數
       3、String方法中Substring和indexOf都是native方法可以大量的使用。
       4、如果函式返回String型別,而且返回後的使用就是要加入到StringBuffer此時可以直接傳入StringBuffer
       5、用兩個一維陣列代替二維陣列 int[][]=====int[] int[]
       6、如果返回直接型別足夠了,就不應返回介面型別如假如返回Hashmap就足夠了,請不要返回Map
       7、如果一個方法不訪問(不修改)成員變數,請用static方法
       8、儘量不用getters和setters,如果你非要用的話請加上final關鍵字,編譯器會把它當成行內函數
       9、永遠不要在for迴圈第二個引數中使用方法呼叫
      10、不修改的static變數請用static final常量代替
      11、foreach可以用來處理陣列和arraylist,如果處理其他物件相當於Iterator
      12、避免使用列舉,請使用常量代替。
      13、慎用浮點數 float尤其是大量的數學運算
      14、不使用的引用變數要手動置null,提高記憶體被回收的機率
      15、慎用圖片操作,使用後要立即釋放資源。

23,fresco:第三方圖片載入庫介紹:

DraweeView 是Fresco的三大元件(Hierarchy、Controller、View) 之一,作為MVC模式中的 View,主要負責顯示由 Hierarchy 提供的資料,Controller 作為幕後,負責獲取資料。
       fresco是通過控制元件來實現它內部的優化快取處理的。
       Fresco原始碼解析,fresco原始碼:Fresco是一個MVC模型,由三大元件構成,

它們的對應關係如下所示:
     M ->DraweeHierarchy
     V -> DraweView
     C -> DraweeController。

M 所對應的 DraweeHierarchy 是一個有層次結構的資料結構,DraweeView 用來顯示位於 DraweeHierarchy 最頂層的影象(top level drawable),DraweeController則用來控制DraweeHierarchy的頂層影象是哪一個。
三者的互動關係很簡單,DraweeView 把獲得的 Event 轉發給 Controller,然後 Controller 根據 Event 來決定是否需要顯示和隱藏 (包括動畫)影象,而這些影象都儲存在 Hierarchy 中,最後 DraweeView 繪製時直接通過 getTopLevelDrawable 就可以獲取需要顯示的影象。

24,垃圾回收內部執行機制:

java中 垃圾回收機制的原理:

1,gc垃圾回收機制的工作原理:

        1,gc的工作原理:引用計數,標記複製。引用計數其實是一種簡單但速度很慢的垃圾回收技術,所有物件都需要有一個引用計數器,當有引用連線時計數器加1。當引用離開作用域時或者被置為null時,計數器-1.垃圾回收器會在所有包含物件引用的列表上進行遍歷,當發現某個物件的引用計數為0時,就釋放佔用的空間。
        2,“標記複製”的執行機制,垃圾回收器遍歷包含所引用的列表,當發現存活的物件引用時做上標記,這樣當遍歷完  所有物件引用並做上標記的時候,執行垃圾回收,將沒有標記的  物件   堆空間釋放。
        3,垃圾回收機制的特點:java的垃圾回收機制使得java程式設計師不用擔心記憶體空間的分配,減少了記憶體溢位。但同時也犧牲了一定的效能。

實現gc的演算法:
    引用計數法,tracing演算法,compacting演算法,copying演算法,generation演算法,adaptive演算法,

25,設計模式:


根據模式的目的劃分為三類:

   1,建立型模型:與物件的建立有關。2, 結構性模型:處理類與物件的組合。3,行為型模型:對類或物件怎樣互動和怎樣分配職責進行描述。
       
   1.建立型模式:
        (1).工廠方法模式        (2).抽象工廠模式        (3).建立者模式        (4).原型模式        (5).單例模式

   2.結構型模式:
         (6).介面卡模式        (7).橋模式        (8).組合模式        (9).裝飾模式        (10).外觀模式        (11).享元模式        (12).代理模式
   3.行為型模式
        (13).直譯器模式        (14).模板方法模式        (15).職責鏈模式        (16).命令模式        (17).迭代器模式        (18).中介者模式        (19).備忘錄模式        (20).觀察者模式        (21).狀態模式        (22).策略模式 -----:官方告訴大家我這裡有一個排序的介面ISort的sort()方法,然後民間各盡其能,實現這個排序的方法:冒泡,快速,堆等等。這些方法就是“不同的策略”。        (23).訪問者模式

MVC不是一種設計模式:
        Trygve Reenskaug最初提出MVC的目的是為了把資料(Model)和檢視(View)分離開來,然後用控制器(Controller)作膠水來粘合M和V之間的關係。目的是為了實現注意點分離這樣一個更高層次的設計理念,也就是讓專業的物件做專業的事情,View就只負責檢視相關的東西,Model就只負責描述資料模型,Controller負責總控,各自協作。

它其實是其它三個經典的設計模式的演變:觀察者模式(Observer)(Pub/Sub), 策略模式(Strategy)和組合模式(Composite)。

26,ViewStub介紹:


解決動態根據條件顯示哪個View或某個佈局:

android.view.ViewStub。

viewStub是一個輕量級的View。他是一個看不見的,不佔佈局的位置。佔用資源非常小的控制元件,可以為ViewStub制定一個佈局,在inflate佈局的時候,只有ViewStub會被初始化。然後當ViewStub被設定為可見的時候,或是呼叫了ViewStub.inflate()的時候,ViewStub所向的佈局就會被inflate和例項化。然後ViewStub的佈局屬性都會傳給它所指向的佈局。這樣,就可以使用ViewStub來方便的在執行時,要還是不要顯示某個佈局。

viewStub只能例項化一次,之後ViewStub物件會被置為null。

27,軟體測試的基本步驟:

軟體首先在開發中進行單元測試。

    開發完成後進行    整合測試(設計規格說明)-------》功能測試(系統功能需求)-----》效能
測試(其他軟體需求)-----》驗收測試(使用者需求規格說明書)-----》安裝測試(使用者環境)。

28,加密演算法:
資料加密:


    計算機的加密解密是由祕鑰控制實現的。祕鑰使使用者按照一種密碼制隨機選取。通常是一隨機字串。是控制明文和祕文變化的隨機引數。

       密碼技術除了提供資訊的加解密外,還提供對資訊來源的鑑別,保證資訊的完整和不可否認等功能,而這三種功能都是通過數字簽名實現。數字簽名時涉及資訊和簽名人私鑰的計算結果。首先簽名人的軟體對傳送的資訊進行雜湊函式運算後。生成資訊摘要。
    加密體制:
          根據祕鑰型別不同將現代密碼及技術分為兩類:對稱加密(祕鑰加密)系統,非對稱加密(公開祕鑰加密)。
對稱加密:
          加密和解密均採用一把祕金鑰匙,而且通訊演算法必須足夠強大。適合於大規模生產。
非對稱加密(公鑰加密):
    指加密和解密使用不同祕鑰的加密演算法。也稱為公私鑰加密,假設兩個使用者要加密交換。

MD5:訊息摘要(資訊摘要演算法),Message-Digest Algorithm 5   雜湊函式。
    
    將資料(如漢字)運算為另一固定長度的值。是緊湊演算法的基礎原理。
    它只是將資料按照指定演算法壓縮成長度固定的摘要資訊。

摘要演算法  就好比將一本書的每一頁第一個字的筆畫數計算出來,並拼接在一起,組成了一個很長的數字串。不論何時,按相同的演算法計算這本書的摘要,都是完全一樣的。但通過這個數字串,無法還原出書中的資料,即過程不可逆。md5演算法類似於這種計算摘要的思想,只是具體實現要複雜很多。

 MD5特點:


        1,壓縮性:任意長度的資料,算出的MD5的值都是固定的。
        2,容易計算:從元資料計算出MD5的值很容易。
        3,抗修改性:對原資料進行任何修改,哪怕只修改一個位元組,所得到的MD5值都有很大區別。
        4,強抗碰撞:已知原資料MD5值,想找到一個具有相同MD5值的資料(即偽造資料)是非常困難的。

    原理:
    1,對MD5演算法簡要的敘述可以為:MD5以512位分組來處理輸入的資訊,且每一分組又被劃分為16個32位子分組。經過了一系列的處理後,
            演算法的輸出有四個32位組成,將這四個32位分組級聯後生成一個128位雜湊值。
    2,例如字串: 計算資料的長度,對資料進行填充到512位(64個位元組)。然後將資料分成16個小組(16個數)。經過資料分組處理後,按照記憶體順序輸出即為最終結果。

RSA:非對稱加密原理:
  
    用到素數,互質數(公因數只有1的兩個數),指數運算,模運算(模運算即求餘運算)等幾個簡單的數學知識。   
    金鑰產生方法:yh
        隨機產生兩個不相等的質數計算乘機n轉為二進位制,二進位制的位數就是金鑰的位數。實際應用中RSA金鑰一般為1024位,重要場合為2048位。
        計算出n的尤拉函式,隨機選擇一個整數e(實際應用中,常常選擇65537),條件是1< e < φ(n),且e與φ(n) 互質。
        計算e對於φ(n)的  模反元素d。所謂"模反元素"就是指有一個整數d,可以使得ed被φ(n)除的餘數為1。
        將n和e封裝成公鑰,n和d封裝成私鑰。

    RSA缺點:
        產生金鑰很麻煩,受到產生素數技術的限制。
        分組長度太大,為保證安全性,n至少也要600bit以上。使運算代價很高,尤其是速度較慢。

DES演算法的入口引數有三個:Key、Data、Mode。其中Key為8個位元組共64位,是DES演算法的工作金鑰;Data也為8個位元組64位,是要被加密或被解密的資料;Mode為DES的工作方式,有兩種:加密或解密。

      DES演算法是這樣工作的:如Mode為加密,則用Key 去把資料Data進行加密, 生成Data的密碼形式(64位)作為DES的輸出結果;
如Mode為解密,則用Key去把密碼形式的資料Data解密,還原為Data明碼形式(64位)作為DES的輸出結果。    在通訊網路的兩端,雙方約定一致的Key,在通訊的源點用Key對核心資料進行DES加密,然後以密碼形式在公共通訊網(如電話網)中傳輸到通訊網路的終點,    資料到達目的地後,用同樣的Key對密碼資料進行解密,便再現了明碼形式的核心資料。這樣,便保證了核心資料(如PIN、MAC等)在公共通訊網中傳輸的安全性和可靠性。

29,activity的啟動模式:


standard(標準模式)   singleTop(棧頂)   singleTask()  singleInstance()

標準模式:每次都會建立一個新的Activity,不在任務棧中作任何存在性檢查。(對系統消耗過大,每次都會建立一個activity的例項)。

singleTop(棧頂模式):只對棧頂作存在性檢查,當啟動的activity已經位於棧頂時,只對棧頂作存在性檢查,直接使用。若沒有位於棧頂則直接建立。

singleTask(檢查棧中所有):系統會檢查棧中是否存在該活動的例項,如存在則直接使用該例項。

singleInstance:在開發程式中如果需要activity在整個體系中都只有一個例項則使用單例項模式。指定為singleInstance模式的activity會啟動一個新的任務棧來管理這個activity。

30,ListView 的優化:

     1,利用ListView自身的快取機制,他會快取一個條目的item,當listView第一屏顯示完成之後。就會出現一個快取條目,其實就是BaseAdapter裡面的public View getView(int position,View convertView,ViewGroup parent)。
    2,減少findViewById()的次數,findViewById是一個相對比較耗效能的操作,因為這個操作每次都需要到佈局中查詢檔案。把item裡面的控制元件封裝成一個javaBean,當item條目被載入的時候就去找相應的控制元件。
    3,利用時間去換取時間,比如開機優化,把一些重要的程式先啟動了,啟動系統完成之後再啟動其他程式。
    4,利用空間去換取時間,把要獲取的資料現價在到記憶體裡面,在處理資料的時候,直接從記憶體中獲取。減少資料庫的頻繁開啟和關閉和減少查詢的次數。

31,Thread和Runnable區別:

     如果一個類繼承Thread,則不適合資源共享,但是如果實現了Runnable介面的話,則很容易的實現資源共享。

    在程式開發中只要是多執行緒肯定以Runnable介面為主,因為實現Runnable介面相比繼承Thread類有如下好處:

    避免點繼承的侷限性,一個類可以繼承多個介面。
    適合於資源的共享。

32,surfaceView   view    GLSurfaceView:  區別:

View:顯示檢視,內建畫布,提供圖形繪製函式、觸屏事件、按鍵事件函式等;必須在UI主執行緒內更新畫面,速度較慢。

SurfaceView:基於view檢視進行拓展的檢視類,更適合2D遊戲的開發;是view的子類,類似使用雙緩機制,在新的執行緒中更新畫面所以重新整理介面速度比view快。

GLSurfaceView:基於SurfaceView檢視再次進行拓展的檢視類,專用於3D遊戲開發的檢視;是SurfaceView的子類,openGL專用。

33,android系統中具備6個啟動模式:


1,normal mode:一般啟動模式的功能是正常啟動方式,方法為關機狀態下按電源鍵啟動。

2,safe mode:此模式和正常啟動一樣,但沒有登記Google,所以不能訪問Market或使用你的Google賬號,操做方法為按住“menu”鍵,按電源鍵啟動手機,直至手機啟動完成鬆開“menu”鍵。

3,恢復模式(recovery mode):可開啟命令解釋程式(shell),重新整理映像檔案,執行備份等,。當然這一切取決於你手機上的recovery image版本。使用方法很簡單。就是home鍵和電源鍵一起按。

4,引導模式的功能,是從sd卡上安裝新的系統映像,只需再按一次電源鍵。值得一提為android手機獲取root許可權。就是使用這個模式,操做方法為照相鍵和電源鍵一起按。

5,fastboot模式主要是在電腦上使用fastboot命令重新整理映像檔案。使用方法為按住返回鍵,按電源鍵啟動手機,直至螢幕出現FASTBOOT字樣鬆開後返回鍵。

6,診斷模式(diagnostic mode)是為了測試手機各項功能的模式,刻意通過軌跡球中心鍵和電源鍵開啟。

34,Permission 的ProtectionLevel的屬性值:


    normal:低風險許可權,只要申請了就可以使用(在AndroidMainFest.xml中新增),安裝時不需要使用者確認。

    danerous:高風險許可權,安裝時需要使用者的確認才可使用。

    signature:只有當申請許可權的應用程式的數字簽名與宣告此許可權的應用程式的數字簽名相同時,才能將許可權授給他。

    signatureOrSystem:簽名相同,或者申請許可權的應用為系統應用(在system image中)。

35,記憶體溢位和記憶體洩露的區別:

記憶體溢位out of memory,是指程式在申請記憶體時,沒有足夠的記憶體空間供其使用,出現out of  memory;比如申請了一個integer,但給他存了long才能存下的數。

比如棧:棧滿時,進行進棧,記憶體溢位。棧空時,進行出棧,記憶體也會溢位。分配記憶體不足以放下資料項序列,稱為記憶體溢位。

記憶體洩露memory leak,是指程式在申請記憶體後,無法釋放已申請的記憶體空間,一次記憶體洩露危害可以忽略,但記憶體洩露堆積後果很嚴重,無論多少記憶體遲早會被佔光。   是指向系統中申請分配記憶體進行使用(new),但使用完後,卻沒有歸還。申請到的記憶體自己也不能再訪問,而系統也不能再次將它分配給需要的程式。

記憶體洩露會導致記憶體溢位。

36,java中有四種類型的引用:及區別:


1,強引用(Strong Reference):只要某個物件有強引用與之關聯,JVM必定不會回收這個物件,即使在記憶體不足的情況下,JVM寧願丟擲OutOfMemory錯誤也不會回收這種物件。

2,弱引用(Weak Refrence):如果一個物件只有弱引用指向它,垃圾回收器會立即回收該物件。

3,軟引用(SoftRefrence):只有在記憶體不足的時候JVM才會回收該物件。並且這個特性很適合用來實現快取:比如網頁快取、圖片快取等。

4,虛引用(PhantomReference):如果一個物件與虛引用關聯,則跟沒有引用與之關聯一樣,在任何時候都可能被垃圾回收器回收。

37,怎麼解決橫豎屏切換導致的   資料丟失?

activity橫豎屏切換時,當前的Activity會被銷燬,然後Activity上面的資料將全部丟失。
如ListView扇面的每個item的checkbox,橫豎屏切換時,複選框就丟失所有選中的資訊。

實現:
1,在註冊檔案中,activity 標籤中,使用android:configChanges = "orientation|keyboardHidden"標籤。
2,強制activity在   支援橫屏或者豎屏。landscape標識橫屏,portrait標識豎屏。
3,在activity中:通過複寫 onConfigurationChanged(Configuratiion newConfig)方法。實現在不同螢幕下的處理方式。

@Override  
    public void onConfigurationChanged(Configuration newConfig) {  
        // TODO Auto-generated method stub  
        super.onConfigurationChanged(newConfig);  
        /*
         * 橫豎屏檢測
         */  
        if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {  
            // 當前為橫屏  
          //實現程式碼  
 
        }  
        else if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {  
            // 當前為豎屏  
            //實現程式碼  
        }  
        /*
         *  實體鍵盤狀態檢測
         */  
        if (newConfig.hardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_NO) {  
            // 實體鍵盤處於推出狀態  
            //實現程式碼  
        }
        else if (newConfig.hardKeyboardHidden == onfiguration.HARDKEYBOARDHIDDEN_YES) {  
 
            // 實體鍵盤處於合上狀態  
            //實現程式碼  
        }  
  }


38,Volley請求和xUtils請求的區別:

Volley谷歌的:支援小資料大頻繁請求。
xUtils中國人開發的。

相同點:
    1,採用了網路資料快取機制。
    2,通過handler機制進行執行緒通訊。

不同點:

    1,Volley請求在android2.3版本之前是通過HttpClient,在之後的版本是URLHTTPConnextion.xUtils都是通過HttpClient請求資料資訊的(bitmap模組圖片是通過URLHTTPConnection)。URLHttpConnection預設支援GZIP壓縮。api操作簡單。

    2,Volley將Http請求資料先快取進Byte[],然後是分配給不同的請求轉化為需要的格式。  xUtils是直接轉換為需要的格式。 Volley的擴充套件性很好,但是不能存在大資料的請求,否則就報OOM。   XUtils不會快取如byte[]支援大資料的請求,速度要比Volley稍快。但擴充套件性低。

    3,Volley訪問網路資料時直接開啟固定個數的執行緒訪問網路資料,在run方法中執行死迴圈。阻塞等待請求佇列等。  XUtils是開啟執行緒池來管理執行緒。快取失效策略。volley的所有網路資料支援從http相應頭控制是否快取和讀取快取失效時間,每個請求可以控制是否快取和快取失效時間。  xUtils網路資料請求是統一自定義快取失效時間。

39,android5.0的新特性:

 1、Face unlock(面部解鎖):在Lollipop系統中,Google花費大力氣優化了面部解鎖功能。當用戶拿起手機處理鎖屏介面上的訊息通知時,面部解鎖功能便自動被啟用。隨意瀏覽幾條訊息之後,手機已經默默地完成了面部識別,解鎖就是這麼簡單!
  2,Lock screen notifications(鎖屏通知中心)
  Android Lollipop中加入了全新風格的通知系統,改進後的通知系統會優先顯示由使用者設定的重要的資訊,而將不太緊急的內容隱藏起來。使用者只需要向下滑動就可以檢視全部的通知內容,如果是簡訊、微信,就可以再通知欄裡直接進行回覆,非常人性化。
   3,Pin Apps(多工視窗)
  Lollipop在系統設定中提供了一項全新的功能——在多工視窗中,給app應用視窗新增pin鎖定程式碼。正如名字講的那樣,像是用別針鎖定app應用,只用當輸入正確的密碼才能退出該app介面。雖然說與iOS系統的Guided Access功能也很像,但Guest Mode使用時好像更加簡單快捷。
   4,Material Design
  Google重新設計了更加趨於扁平化的Lollipop系統UI,稱為Material Design。在今年6月26日舉辦的I/O 2014開發者大會上,許多人就已經提前領略到Material Design出色的功能了。到現在,它得到了更多的優化,例如給通訊錄聯絡人新增不同的顏色優先等級。新的UI設計,在基本元素的處理上,借鑑了傳統的印刷設計,從字型版式、網格系統,到空間、比例、配色、影象等方面,都驚醒了大膽的平面化的創新。這一舉措,無疑是加大了國產UI設計的難度與門檻。

    5,Android 5.0還支援新的電池模式、多賬戶登陸、訪客模式以及通過藍芽裝置解鎖等新功能。

Material Design新控制元件:

    支援的八個新控制元件:
        TextInputLayout:對EditText進行封裝,帶有提示資訊的輸入框。一個TextInputLayout只能巢狀一個EditText,內容過多會水平滾動進行檢視
        FloatingActionButton:一個負責顯示介面基本操作的懸浮圓形按鈕。繼承自ImageView,你可以使用android:src(更改圓形按鈕中間的圖片)或者ImageView的任意方法。懸浮按鈕的背景使用colorAccent屬性更改。
        Snackbar:一個介於Toast和AlertDialog之間的輕量級控制元件。他可以很方便的提供訊息的提示和動作反饋。
        TabLayout標籤佈局位置隨意,只能進行文字導航,既實現了固定的選項卡(View的寬度平均分配),也實現了可滾動的選項卡(View寬度不固定同時可以橫向滾動)
        NavigationView:
        CoorDinatorLayout: 效果1:滾動效果,例子如:讓浮動操作按鈕(FloatingActionButton)上下滑動,為Snackbar留出空間,實現方式:使用CoordinatorLayout作為基本佈局放在FloatingActionButton佈局外層,會自動實現上移下移的動畫.
        AppBarLayout:可把容器類的元件全部作為AppBar,例如把Toolbar和TabLayout放到了AppBarLayout中,讓他們當做一個整體作為AppBar.
        TooBayLayout:CollapsingToolbarLayout作用是提供了一個可以摺疊的Toolbar,它繼承至FrameLayout,給它設定layout_scrollFlags,它可以控制包含在CollapsingToolbarLayout中的控制元件(如:ImageView、Toolbar)在響應layout_behavior事件時作出相應的scrollFlags滾動事件(移除螢幕或固定在螢幕頂端)。