1. 程式人生 > >Android面試可能會問到的問題

Android面試可能會問到的問題

       由於自己最近在準備面試,所以也找了些面試題,以下內容是自己的總結,通過從多次的面試經驗中提取出了一些高頻的可能會問到的問題,這些面試問題的答案僅供參考。

1.     什麼是ANR,如何避免它?

應用程式有一段時間反應不靈敏,系統會向用戶顯示一個對話方塊,提示應用程式無響應。預設情況下,在androidActivity的最長執行時間是5BroadcastReceiver的最長執行時間則是10秒。

Android應用程式通常是執行在一個單獨的執行緒(例如,main)裡。這意味著你的應用程式所做的事情如果在主執行緒裡佔用了太長的時間的話,就會引發ANR對話方塊,因為你的應用程式並沒有給自己機會來處理輸入事件或者Intent廣播。

因此,執行在主執行緒裡的任何方法都儘可能少做事情。特別是,Activity應該在它的關鍵生命週期方法(如onCreate()和onResume())裡儘可能少的去做建立操作。潛在的耗時操作,例如網路或資料庫操作,或者高耗時的計算如改變點陣圖尺寸,應該在子執行緒裡(或者以資料庫操作為例,通過非同步請求的方式)來完成。替代的方法是,主執行緒應該為子執行緒提供一個Handler,以便完成時能夠提交給主執行緒。以這種方式設計你的應用程式,將能保證你的主執行緒保持對輸入的響應性並能避免由於5秒輸入事件的超時引發的ANR對話方塊。這種做法應該在其它顯示UI的執行緒裡效仿,因為它們都受相同的超時影響。

2.     四大元件

ActivityBroadcast ReceiverContent provideService

3.     OOM

可能出現的情況:
1.資料庫的cursor沒有關閉
2.構造adapter時,沒有使用快取convertView
        衍生listview的優化問題—–減少建立view的物件,充分使用convertView,可以使用靜態類來優化處理getview的過程
3.Bitmap物件不使用時採用recycle()釋放記憶體
4.activity中的物件的生命週期大於activity

參考:

1. 使用更加輕量的資料結構例如,我們可以考慮使用ArrayMap/SparseArray而不是HashMap等傳統資料結構。通常的HashMap的實現方式更加消耗記憶體,因為它需要一個額外的例項物件來記錄Mapping 操作。另外,SparseArray更加高效,在於他們避免了對key與value的自動裝箱(autoboxing),並且避免了裝箱後的解箱。

2. 避免在Android裡面使用Enum,Android官方培訓課程提到過“Enums often require more than twice as much memory as staticconstants. You should strictly avoid using enums on Android.”, 具體原理請參考《Android效能優化典範(三)》,所以請避免在Android裡面使用到列舉。

3. 減小Bitmap物件的記憶體佔用 Bitmap是一個極容易消耗記憶體的大胖子,減小創建出來的Bitmap的記憶體佔用可謂是重中之重,通常來說有以下2個措施:inSampleSize:縮放比例,在把圖片載入記憶體之前,我們需要先計算出一個合適的縮放比例,避免不必要的大圖載入。decode format:ARGB_6666/RBG_545/ARGB_4444/ALPHA_6,解碼格式,選擇的不同存在很大差異。

4.Bitmap物件的複用縮小Bitmap的同時,也需要提高BitMap物件的複用率,避免頻繁建立BitMap物件,複用的方法有以下2個措施LRUCache :“最近最少使用演算法”在Android中有極其普遍的應用。 ListView與GridView等顯示大量圖片的控制元件裡,就是使用LRU的機制來快取處理好的Bitmap,把近期最少使用的資料從快取中移除,保留使用最頻繁的資料,inBitMap高階特性:利用inBitmap的高階特性提高Android系統在Bitmap分配與釋放執行效率。使用inBitmap屬性可以告知Bitmap解碼器去嘗試使用已經存在的記憶體區域,新解碼的Bitmap會嘗試去使用之前那張Bitmap在Heap中所佔據的pixel data記憶體區域,而不是去問記憶體重新申請一塊區域來存放Bitmap。利用這種特性,即使是上千張的圖片,也只會僅僅只需要佔用螢幕所能夠顯示的圖片數量的記憶體大小。

5 使用更小的圖片 在涉及給到資源圖片時,我們需要特別留意這張圖片是否存在可以壓縮的空間,是否可 以使用更小的圖片。儘量使用更小的圖片不僅可以減少記憶體的使用,還能避免出現大量的 InflationException。假設有一張很大的圖片被XML檔案直接引用,很有可能在初始化檢視時會因為記憶體 不足而發生InflationException,這個問題的根本原因其實是發生了OOM。

6.StringBuilder 在有些時候,程式碼中會需要使用到大量的字串拼接的操作,這種時候有必要考慮使用 StringBuilder來替代頻繁的“+”。

7.避免在onDraw方法裡面執行物件的建立 類似onDraw等頻繁呼叫的方法,一定需要注意避免在這裡做 建立物件的操作,因為他會迅速增加記憶體的使用,而且很容易引起頻繁的gc,甚至是記憶體抖動。

4.     Activity生命週期

瞭解Activity的生命週期的根本目的就是為了設計使用者體驗更加良好的應用。因為Activity就相當於MVC中的View層,是為了更好的向用戶展現資料,並與之互動。瞭解Activity的生命週期和各回調方法的觸發時機,我們可以更好的在合適的地方向使用者展現資料(因為每個應用每個Activity的作用不同,所以具體每個回撥方法的最佳時間不好把握,但是隻要遵循最基本的原則即可),保證資料的完整性和程式的良好執行。


簡要說明:
onCreate(BundlesavedInstanceState):建立activity時呼叫。設定在該方法中,還以Bundle中可以提出用於建立該 Activity 所需的資訊。
onStart():activity變為在螢幕上對使用者可見時,即獲得焦點時,會呼叫。
onResume():activity開始與使用者互動時呼叫(無論是啟動還是重新啟動一個活動,該方法總是被呼叫的)。
onPause():activity被暫停或收回cpu和其他資源時呼叫,該方法用於儲存活動狀態的。。
onStop():activity被停止並轉為不可見階段及後續的生命週期事件時,即失去焦點時調  用。
onRestart():重新啟動activity時呼叫。該活動仍在棧中,而不是啟動新的活動。
onDestroy():activity被完全從系統記憶體中移除時呼叫,該方法被呼叫可能是因為有人直接呼叫 finish()方法 或者系統決定停止該活動以釋放資源。

1、不設定Activity的android:configChanges時,切屏會重新呼叫各個生命週期,切橫屏時會執行一次,切豎屏時也是一次

2、設定Activityandroid:configChanges="orientation"時,切屏還是會重新呼叫各個生命週期,切橫、豎屏時只會執行一次,但是低版本的系統,不會重新呼叫。

3、設定Activityandroid:configChanges="orientation|keyboardHidden|screenSize"時,切屏不會重新呼叫各個生命週期,只會執行onConfigurationChanged方法.

鎖定屏與解鎖螢幕只會呼叫onPause(),而不會呼叫onStop方法,開屏後則呼叫onResume().

 點選MainActivity按鈕跳轉到AnotherAcitivty,再回到MainActivity.寫出兩者相應生命週期呼叫順序

AnotherActivity通過Back鍵返回Main

Main(onPause)-->Anoth(onCreate,onStart,onResume)-->Main(onStop)-->Anoth(onPause)--->Main(onRestart,onStart,onResume)--->Anoth(onStop,onDestroy)

AnotherActivity通過Intent跳轉返回Main

Main(onPause)-->Anoth(onCreate,onStart,onResume)-->Main(onStop)-->Anoth(onPause)--->Main(onCreate,onStart,onResume)--->Anoth(onStop)

5.     MVC

mvcmodel,view,controller的縮寫,mvc包含三個部分:模型(model)物件:是應用程式的主體部分,所有的業務邏輯都應該寫在該層。檢視(view)物件:是應用程式中負責生成使用者介面的部分。也是在整個mvc架構中使用者唯一可以看到的一層,接收使用者的輸入,顯示處理結果。控制器(control)物件:是根據使用者的輸入,控制使用者介面資料顯示及更新model物件狀態的部分,控制器更重要的是一種導航功能,響應使用者觸發的相關事件,交給m處理。

1)檢視層(view):一般採用xml檔案進行介面的描述,使用的時候可以非常方便的引入,當然,如何你對android瞭解的比較的多了話,就一定可以想到在android中也可以使用javascript+html等的方式作為view層,當然這裡需要進行javajavascript之間的通信,幸運的是,android提供了它們之間非常方便的通訊實現。
2)
控制層(controller):android的控制層的重任通常落在了眾多的acitvity的肩上,這句話也就暗含了不要在acitivity中寫程式碼,要通過activity交割model業務邏輯層處理,這樣做的另外一個原因是android中的acitivity的響應時間是5s,如果耗時的操作放在這裡,程式就很容易被回收掉。
3)
模型層(model):對資料庫的操作、對網路等的操作都應該在model裡面處理,當然對業務計算等操作也是必須放在的該層的。

6.     Handler

andriod提供了Handler和Looper來滿足執行緒間的通訊。Handler先進先出原則。Looper類用來管理特定執行緒內物件之間的訊息交換(MessageExchange)。UI thread 通常就是mainthread,而Android啟動程式時會替它建立一個Message Queue。

1) Message:Message是線上程之間傳遞訊息,它可以在內部攜帶少量的訊息,用於在不同的執行緒中交換資料。

2) Looper: 一個執行緒可以產生一個Looper物件,由它來管理此執行緒裡的MessageQueue(訊息佇列)。呼叫Looper的loop()方法後,就會進入到一個無限迴圈當中,然後每當發現Message Queue中有訊息時,都會將其傳遞到Handle的handleMessage()方法中。每個執行緒中也只會有一個Looper物件。
3) Message Queue(訊息佇列):用來存放通過handle傳送的訊息,等待被處理。每個執行緒中只會有一個Message Queue.
 4) Handler: 你可以構造Handler物件來與Looper溝通,以便push新訊息到Message Queue裡;或者接收Looper從Message Queue所送來的訊息。

7.     Android 動畫有哪幾種?描述一下

Android3.0(即API Level11)以前,Android僅支援2種動畫:分別是Frame Animation(逐幀動畫)和Tween Animation(補間動畫),在3.0之後Android支援了一種新的動畫系統,稱為:Property Animation(屬性動畫)

(1)Frame Animation(幀動畫)主要用於播放一幀幀準備好的圖片,類似GIF圖片,優點是使用簡單方便、缺點是需要事先準備好每一幀圖片;

(2)Tween Animation(補間動畫)僅需定義開始與結束的關鍵幀,而變化的中間幀由系統補上,優點是不用準備每一幀,缺點是隻改變了物件繪製,而沒有改變View本身屬性。因此如果改變了按鈕的位置,還是需要點選原來按鈕所在位置才有效。有平移、縮放、旋轉、透明等四種實現方式。

(3)Property Animation(屬性動畫)是3.0後推出的動畫,優點是使用簡單、降低實現的複雜度、直接更改物件的屬性、幾乎可適用於任何物件而僅非View類,3.0之前的版本可使用github第三方開源庫nineoldandroids.jar進行支援

8.     返回鍵與Home鍵區別?

back鍵預設行為是finish處於前臺的Activity的即Activity的狀態為Destroy狀態為止,再次啟動該Activity是從onCreate開始的(不會呼叫onSaveInstanceState方法)。Home鍵預設是stop前臺的Activity即狀態為onStop為止而不是Destroy,若再次啟動它,會呼叫onSaveInstanceState方法,保持上次Activity的狀態則是從OnRestart開始的---->onStart()--->onResume()。

9.     請介紹下ContentProvider是如何實現資料共享的。一個程式可以通過實現一個Content provider的抽象介面將自己的資料完全暴露出去,而且Content providers是以類似資料庫中表的方式將資料暴露。Content providers儲存和檢索資料,通過它可以讓所有的應用程式訪問到,這也是應用程式之間唯一共享資料的方法。要想使應用程式的資料公開化,可通過2種方法:建立一個屬於你自己的Content provider或者將你的資料新增到一個已經存在的Content provider中,前提是有相同資料型別並且有寫入Content provider的許可權。

10. String和stringbuffer、stringbuilder

String:字串常量 是物件不是基本資料型別.
           為不可變物件,一旦被建立,就不能修改它的值.
          對於已經存在的String物件的修改都是重新建立一個新的物件,然後把新的值儲存進去.
           String 是final類,即不能被繼承.

StringBuffer:字串變數(執行緒安全)          是一個可變物件,當對他進行修改的時候不會像String那樣重新建立物件
           它只能通過建構函式來建立,
          StringBuffer sb = newStringBuffer();
          物件被建立以後,在記憶體中就會分配記憶體空間,並初始儲存一個null.通過它的append方法向其賦值.

       sb.append("hello");

字串連線操作中StringBuffer的效率要明顯比String高,且節省空間

   StringBuilder 字串變數(非執行緒安全)

大多數情形下,建議採用此類。因為在大多數實現中,它比 StringBuffer要快。兩者的方法基本相同。

我們的程式是在單執行緒下執行,或者是不必考慮到執行緒同步問題,我們應該優先使用StringBuilder類;當然,如果要保證執行緒安全,自然非StringBuffer莫屬了。

String物件是不可變物件,每次操作Sting 都會重新建立新的物件來儲存新的值。

為什麼要把String類設計成不可變類,是它的用途決定的。不可變類有一些優點,比如因為它的物件是隻讀的,所以多執行緒併發訪問也不會有任何問題。當然也有一些缺點,比如每個不同的狀態都要一個物件來代表,可能會造成效能上的問題

StringBuffer物件例項化後,只對這一個物件操作。

11.抽象類和介面的區別

含有 abstract方法的類必須定義為abstractclass, abstract class類中的方法不必是抽象的。 abstract class類中定義抽象方法必須在具體(Concrete)子類中實現,所以,不能有抽象構造方法或抽象靜態方法。如果的子類沒有實現抽象父類中的所有抽象方法,那麼子類也必須定義abstract型別。

介面(interface)可以說成是抽象類的一種特例,介面中的所有方法都必須是抽象的。介面中的方法定義預設為public abstract型別,介面中的成員變數型別預設為public static final。 

下面比較一下兩者的語法區別:

1.抽象類可以有構造方法,介面中不能有構造方法。

2.抽象類中可以有普通成員變數,介面中沒有普通成員變數

3.抽象類中可以包含非抽象的普通方法,介面中的所有方法必須都是抽象的,不能有非抽象的普通方法。

4. 抽象類中的抽象方法的訪問型別可以是public,protected 和(預設型別,雖然

eclipse 下不報錯,但應該也不行),但介面中的抽象方法只能是public型別的並且預設即為publicabstract型別。

5. 抽象類中可以包含靜態方法,介面中不能包含靜態方法

6. 抽象類和介面中都可以包含靜態成員變數,抽象類中的靜態成員變數的訪問型別可以任意,但介面中定義的變數只能是 public static final型別,並且預設即為public static final型別。

12. 什麼時候用抽象類什麼時候用介面?

它用於要建立一個體現某些基本行為的類,併為該類宣告方法,但不能在該類中實現該類的情況;

介面(interface)是抽象類的變體。在介面中,所有方法都是抽象的。

介面和抽象類都是多型的一種表現,介面和抽象類都能描述一般性的公有特徵。

由於子類只能擴充套件一個父類,而能實現多個介面,所以介面比抽象類更靈活但是介面不能包括具體的方法(即沒有方法體,只有方法名),而抽象類可以(比如非抽象的方法),要將兩種好處結合起來,可以建立一個介面和一個實現該介面的抽象類(便利類),然後根據情況決定使用哪個。

13.java抽象類或介面被繼承後方法一定要重寫嗎

抽象類中的非抽象方法不用重寫,其他必須重寫,介面的方法必須重寫;

繼承自抽象類的,如果子類不是抽象的話,那所有抽象方法必須從寫普通方法不用重寫;如果子類是抽象的那就所有的方法都不用必須重寫

14.java三大特徵封裝、繼承、多型

封裝:把對同一事物進行操作的方法和相關方法放在同一個類中,使用者不必關心類的具體實現細節,隱藏物件的內部結構,增加安全性、簡化程式設計;

繼承:子類共享父類的資料和方法,實現程式碼的複用性,減少程式碼冗餘,使維護和擴充套件變得簡單;

多型:同一個操作作用於不同物件,會有不同的結果,增加了類的靈活性、可替換性、可擴充性。

15.過載和重寫的區別

1、過載:是一個類裡面,寫了多了同名的方法,引數列表不同,各個方法的返回值型別可以不一樣。

2、重寫:

也叫覆蓋,指在子類中定義一個與父類中方法同名同參數列表的方法。因為子類會繼承父類的方法,而重寫就是將從父類繼承過來的方法重新定義一次,重新填寫方法中的程式碼。

16.final, finally, finalize 的區別。

final 用於宣告屬性,方法和類,分別表示屬性不可變,方法不可覆蓋,類不可繼承。

內部類要訪問區域性變數,區域性變數必須定義成 final型別。

finally是異常處理語句結構的一部分,表示總是執行。

finalize Object類的一個方法,在垃圾收集器執行的時候會呼叫被回收物件的此方法,可以覆蓋此方法提供垃圾收集時的其他資源回收,例如關閉檔案等。JVM不保證此方法總被呼叫

17.error 和 exception有什麼區別?

error表示系統級的錯誤和應用程式本身無法克服和恢復的一種嚴重問題。比如說記憶體溢位。不可能指望程式能處理這樣的情況。

exception表示一種設計或實現問題。也就是說,它表示如果程式執行正常,從不會發生的情況。表示需要捕捉或者需要程式進行處理的異常,使用者可以克服並解決的,是程式必須處理的,程式不應該死掉。

18. 

19.請寫出你最常見到的 5 個 runtime exception

1ClassCastException

Object x = new Integer(0);

    System.out.println((String)x);

當試圖將物件強制轉換為不是例項的子類時,丟擲該異常(ClassCastException)

2ArithmeticException

int a=5/0;

一個整數“除以零”時,丟擲ArithmeticException異常。

3, NullPointerException

String s=null;

int size=s.size();

當應用程式試圖在需要物件的地方使用 null 時,丟擲NullPointerException異常

4, IndexOutOfBoundsException

"hello".indexOf(-1);

指示索引或者為負,或者超出字串的大小,丟擲IndexOutOfBoundsException異常

5, NegativeArraySizeException

String[] ss=new String[-1];

如果應用程式試圖建立大小為負的陣列,則丟擲NegativeArraySizeException異常。

sleep指執行緒被呼叫時,佔著CPU不工作,形象地說明為“佔著CPU睡覺”,此時,系統的CPU部分資源被佔用,其他執行緒無法進入,會增加時間限制。

wait指執行緒處於進入等待狀態,形象地說明為“等待使用CPU”,此時執行緒不佔用任何資源,不增加時間限制

第一種解釋:

功能差不多,都用來進行執行緒控制,他們最大本質的區別是:sleep()不釋放同步鎖,wait()釋放同步鎖.  還有用法的上的不同是:sleep(milliseconds)可以用時間指定來使他自動醒過來,如果時間不到你只能呼叫interreput()來強行打斷;wait()可以用notify()直接喚起.

第二種解釋:

sleepThread類的靜態方法。sleep的作用是讓執行緒休眠制定的時間,在時間到達時恢復,也就是說sleep將在接到時間到達事件時恢復執行緒執行,例如:

try{
System.out.println("I'm going to bed");
Thread.sleep(1000);
System.out.println("I wake up");
}
catch(IntrruptedException e) {
}


wait
Object的方法,也就是說可以對任意一個物件呼叫wait方法,呼叫wait方法將會將呼叫者的執行緒掛起,直到其他執行緒呼叫同一個物件的notify方法才會重新啟用呼叫者,例如:


//Thread 1

try{
obj.wait();//suspend thread until obj.notify() is called
}
catch(InterrputedException e) {
}

第三種解釋:

這兩者的施加者是有本質區別的
sleep()
是讓某個執行緒暫停執行一段時間,其控制範圍是由當前執行緒決定,也就是說,線上程裡面決定.好比如說,我要做的事情是 "點火->燒水->煮麵",而當我點完火之後我不立即燒水,我要休息一段時間再燒.對於執行的主動權是由我的流程來控制.

wait(),首先,這是由某個確定的物件來呼叫的,將這個物件理解成一個傳話的人,當這個人在某個執行緒裡面說"暫停!",也是 thisOBJ.wait(),這裡的暫停是阻塞,還是"點火->燒水->煮飯",thisOBJ就好比一個監督我的人站在我旁邊,本來該線程應該執行1後執行2,再執行3,而在2處被那個物件喊暫停,那麼我就會一直等在這裡而不執行3,但正個流程並沒有結束,我一直想去煮飯,但還沒被允許,直到那個物件在某個地方說"通知暫停的執行緒啟動!",也就是thisOBJ.notify()的時候,那麼我就可以煮飯了,這個被暫停的執行緒就會從暫停處繼續執行.

其實兩者都可以讓執行緒暫停一段時間,但是本質的區別是一個執行緒的執行狀態控制,一個是執行緒之間的通訊的問題

java.lang.Thread類中,提供了sleep()java.lang.Object類中提供了wait() notify()notifyAll()方法來操作執行緒
sleep()
可以將一個執行緒睡眠,引數可以指定一個時間。wait()可以將一個執行緒掛起,直到超時或者該執行緒被喚醒。
   wait
有兩種形式wait()wait(milliseconds).
sleep
wait的區別有:
  1
,這兩個方法來自不同的類分別是ThreadObject
  2
,最主要是sleep方法沒有釋放鎖,而wait方法釋放了鎖,使得其他執行緒可以使用同步控制塊或者方法。
  3
waitnotifynotifyAll只能在同步控制方法或者同步控制塊裡面使用,而sleep可以在任何地方使用
   synchronized(x){
       x.notify()
      //
或者wait()
      }
   4,sleep
必須捕獲異常,而waitnotifynotifyAll不需要捕獲異常

21.同步和非同步有何異同,在什麼情況下分別使用他們?舉例說明。

如果資料將線上程間共享。例如正在寫的資料以後可能被另一個執行緒讀到,或者正在讀的資料可能已經被另一個執行緒寫過了,那麼這些資料就是共享資料,必須進行同步存取。當應用程式在物件上呼叫了一個需要花費很長時間來執行的方法,並且不希望讓程式等待方法的返回時,就應該使用非同步程式設計,在很多情況下采用非同步途徑往往更有效率。

22.程序和執行緒以及他們的區別

簡而言之,一個程式至少有一個程序,一個程序至少有一個執行緒.

執行緒的劃分尺度小於程序,使得多執行緒程式的併發性高。

另外,程序在執行過程中擁有獨立的記憶體單元,而多個執行緒共享記憶體,從而極大地提高了程式的執行效率。

執行緒在執行過程中與程序還是有區別的。每個獨立的執行緒有一個程式執行的入口、順序執行序列和程式的出口。但是執行緒不能夠獨立執行,必須依存在應用程式中,由應用程式提供多個執行緒執行控制。

從邏輯角度來看,多執行緒的意義在於一個應用程式中,有多個執行部分可以同時執行。但作業系統並沒有將多個執行緒看做多個獨立的應用,來實現程序的排程和管理以及資源分配這就是程序和執行緒的重要區別。

23.執行緒安全和執行緒不安全

如果你的程式碼所在的程序中有多個執行緒在同時執行,而這些執行緒可能會同時執行這段程式碼。如果每次執行結果和單執行緒執行的結果是一樣的,而且其他的變數的值也和預期的是一樣的,就是執行緒安全的。

執行緒安全問題都是由全域性變數靜態變數引起的。

若每個執行緒中對全域性變數靜態變數只有讀操作,而無寫操作,一般來說,這個全域性變數是執行緒安全的;若有多個執行緒同時執行寫操作,一般都需要考慮執行緒同步,否則的話就可能影響執行緒安全。

執行緒安全就是多執行緒訪問時,採用了加鎖機制,當一個執行緒訪問該類的某個資料時,進行保護,其他執行緒不能進行訪問直到該執行緒讀取完,其他執行緒才可使用。不會出現資料不一致或者資料汙染。

執行緒不安全就是不提供資料訪問保護,有可能出現多個執行緒先後更改資料造成所得到的資料是髒資料

24.List和Map的區別

List是儲存單列資料的集合,Map是儲存鍵和值這樣的雙列資料的集合List中儲存的資料是有先後順序,並且允許重複,Map中儲存的資料是沒有順序的(除了Treemap,由於底層是二叉樹實現的),其鍵是不能重複的,它的值是可以有重複的。

25.HashMap 和Hashtable的區別

HashMapHashtable的輕量級實現(非執行緒安全的實現),他們都完成了Map介面,主要區別在於HashMap允許空(null)鍵值(key,由於非執行緒安全,在只有一個執行緒訪問的情況下,效率要高於Hashtable

HashMap 允許將null作為一個 entrykey或者 value,而Hashtable不允許。

251ArrayListLinkedListVector的區別

ArrayList,Vector底層是由陣列實現,LinkedList底層是由雙線連結串列實現,從底層的實現可以得出它們的效能問題,ArrayList,Vector插入速度相對較慢,查詢速度相對較快,而LinkedList插入速度較快,而查詢速度較慢。再者由於Vevtor使用了執行緒安全鎖,所以ArrayList的執行效率高於Vector

26.位元組流與字元流的區別

位元組流在操作的時候本身是不會用到緩衝區(記憶體)的,是與檔案本身直接操作的,而字元流在操作的時候是使用到緩衝區的

位元組流在操作檔案時,即使不關閉資源(close方法),檔案也能輸出,但是如果字元流不使用close方法的話,則不會輸出任何內容,說明字元流用的是緩衝區,並且可以使用flush方法強制進行重新整理緩衝區,這時才能在不close的情況下輸出內容

那開發中究竟用位元組流好還是用字元流好呢?

在所有的硬碟上儲存檔案或進行傳輸的時候都是以位元組的方法進行的,包括圖片也是按位元組完成,而字元是隻有在記憶體中才會形成的,所以使用位元組的操作是最多的

    如果要java程式實現一個拷貝功能,應該選用位元組流進行操作(可能拷貝的是圖片),並且採用邊讀邊寫的方式(節省記憶體)。

27.Heap和stack有什麼區別

java的記憶體分為兩類,一類是棧記憶體,一類是堆記憶體。棧記憶體是指程式進入一個方法時,會為這個方法單獨分配一塊私屬儲存空間,用於儲存這個方法內部的區域性變數,當這個方法結束時,分配給這個方法的棧會釋放,這個棧中的變數也將隨之釋放。

堆記憶體用於存放由new建立的物件和陣列,在堆中分配的記憶體,由 Java虛擬機器的自動垃圾回收器來管理,例如,使用 new建立的物件都放在堆裡,所以,它不會隨方法的結束而消失。方法中的區域性變數使用 final修飾後,放在堆中,而不是棧中。

28.Java資料結構有哪些

資料結構是計算機儲存、組織資料的方式。資料結構是指相互之間存在一種或多種特定關係的資料元素的集合。主要是2family   collection (List,Set,Queue) map
list:      linkedlist,arraylist,vector 存放有序、可重複的元素
set:     treeset,hashset 存放不可重複的元素,除了treeSet底層由於是二叉樹實現的,所以是有序的,其他的hashSet,AbstractSet等是無序的。

Queue Deque
map:    treemap,hashmap,sortedmap 存放鍵不重複的元素,除了treemap底層是二叉樹實現的,所以是有序的,其他的hashmap,AbstractMap等是無序的

29.Activity和service的通訊方式

1. 在Activity不繫結Service的前提下(如果綁定了,Activity掛了Service也就掛了)進行相互傳輸資料,Activity向Service傳輸資料可以使用Intent,Service向Activity傳輸資料可以使用廣播機制

2. Activity呼叫bindService(Intent service, ServiceConnection conn, int flags)方法,得到Service物件的一個引用,這樣Activity可以直接呼叫到Service中的方法,如果要主動通知Activity,我們可以利用回撥方法

3. 如果要與另外一個程序的Service進行通訊,則可以用Messenger其實實現IPC的方式,還有AIDL(介面定義語言),但推薦使用Messenger

30.Java中物件序列化的作用是什麼?

簡單說就是為了儲存在記憶體中的各種物件的狀態,並且可以把儲存的物件狀態再讀出來。雖然你可以用你自己的各種各樣的方法來儲存Object States,但是Java給你提供一種應該比你自己好的儲存物件狀態的機制,那就是序列化。

a)當你想把的記憶體中的物件儲存到一個檔案中或者資料庫中時候;

b)當你想用套接字在網路上傳送物件的時候;

31.基本資料型別

java提供了一組基本資料型別,包括boolean, byte, char, short,  int, long, float, doublejava也提供了這些型別的封裝類,分別為Boolean, Byte, Character, Short, Integer, Long, Float, Double

既然提供了基本型別,為什麼還要使用封裝類呢

某些情況下,資料必須作為物件出現,此時必須使用封裝類來將簡單型別封裝成物件。

比如,如果想使用List來儲存數值,由於List中只能新增物件,因此我們需要將資料封裝到封裝類中再加入List。在JDK5.0以後可以自動封包,可以簡寫成list.add(1)的形式,但新增的資料依然是封裝後的物件。

另外,有些情況下,我們也會編寫諸如func(Object o)的這種方法,它可以接受所有型別的物件資料,但對於簡單資料型別,我們則必須使用封裝類的物件。

某些情況下,使用封裝類使我們可以更加方便的操作資料。比如封裝類具有一些基本型別不具備的方法,比如valueOf(), toString(),以及方便的返回各種型別資料的方法,如IntegershortValue(), longValue(), intValue()等。

另 java swicth 的作用物件有哪些?

int型(包括其包裝類)的,String型,列舉型。

其中因為 byte,short,char是可以自動轉型為int

String是JDK1.7版本以後才支援的

32 Java的四種引用,強弱軟虛,用到的場景 

1.強引用,這是使用最普遍的引用。如果一個物件具有強引用,那就類似於必不可少的生活用品,垃圾回收器絕不會回收它。當記憶體空間不足,Java虛擬機器寧願丟擲

OutOfMemoryError錯誤,使程式異常終止,也不會靠隨意回收具有強引用的物件來解決記憶體不足問題。

2.軟引用,如果一個物件只具有軟引用,那就類似於可有可無的生活用品。如果記憶體空間足夠,垃圾回收器就不會回收它,如果記憶體空間不足了,就會回收這些物件的記憶體。

3.弱引用,如果一個物件只具有弱引用,那就類似於可有可無的生活用品。弱引用與軟引用的區別在於:只具有弱引用的物件擁有更短暫的生命週期。在垃圾回收器執行緒掃描它所管轄的記憶體區域的過程中,一旦發現了只具有弱引用的物件,不管當前記憶體空間足夠與否,都會回收它的記憶體。 

4.虛引用,"虛引用"顧名思義,就是形同虛設,與其他幾種引用都不同,虛引用並不會決定物件的生命週期。如果一個物件僅持有虛引用,那麼它就和沒有任何引用一樣,在任何時候都可能被垃圾回收,具有不確定性。

33.ThreadPool的用法和優劣

執行緒池是為突然大量爆發的執行緒設計的,通過有限的幾個固定執行緒為大量的操作服務,減少了建立和銷燬執行緒所需的時間,從而提高效率。 FixedThreadPool(int nThreads):建立一個可重用的固定執行