Thought Coding實驗室2016年納新筆試題
姓名: _______ 班級: ________ 連絡方式: ________
Java部分
一、請看下面這段程式,回答問題
public class Test1 {public static void main(String[] args){StringBuffer a = new StringBuffer("Thought"); //語句1StringBuffer b = new StringBuffer("Coding"); //語句2operate(a, b);System.out.println("a = " + a);System.out.println("b = " + b);}static void operate(StringBuffer x, StringBuffer y){x.append(y); //語句3y = x;}}
1、這段程式的輸出結果是什麼。為什麼。
輸出:
a = ThoughtCoding
b = Coding
解釋:考察Java參數傳遞機制與StringBuffer的使用。
operat方法傳入兩個StringBuffer類型的控制代碼的副本(也可以說是指向堆記憶體中StringBuffer對象的指標的副本),一個是x,一個是y,執行”x.append(y);”後,y指向的StringBuffer對象內容”Coding”串連在x指向的StringBuffer對象的字串內容(底層是一個value[]數組)後,執行”y = x;”後,只是修改了y的指向,並沒有修改y指向的StringBuffer對象的字串內容,在方法執行結束後,x、y自然消亡。
2、把上述程式中的語句1、2、3分別修改為:
String a = "Thought";String b = new String("Coding");x = x + y;
輸出結果又是什麼。為什麼有這樣的區別。
輸出:
a = Thought
b = Coding
解釋:考察String的使用以及與StringBuffer區別。
String使用private final char value[]來實現字串的儲存,也就是說,String對象建立之後,就不能修改對象中儲存的字串內容。另外,Java對String重載了”+”操作符,可以直接使用”+”對兩個字串進行串連。
operate方法中,執行”x = x + y”,可分為兩步,第一步先建立一個新的String對象,它的內容為x與y指向的String對象內容串連後的字串;第二步使x指向新的String對象,所以a指向的原String內容並未改變。
3、通過引號””建立String對象與通過new關鍵字建立String對象有什麼區別。
解釋:考察String對象的建立與對Java運行時記憶體如常量池、堆記憶體的瞭解。
用引號建立String對象是在編譯期,在方法區的常量池中,如果常量池中已有字串內容相同的對象(用equals判定),則直接返回常量池中字串對象的引用。而使用new關鍵字會在堆記憶體中建立一個新對象,不管常量池中是否有值相同的對象,都返回堆記憶體中對象的引用。
4、”==”與equals的區別。為了比較兩個String對象的字串內容是否相同,請試著重寫Object類的equals方法。
解釋:考察”==”與equals區別。
“==”比較的是地址,Object類的equals()方法返回”==”比較結果。
public boolean equals(Object anObject)
{
//如果是同一個對象
if (this == anObject)
{
return true;
}
//如果傳遞進來的參數是String類的執行個體
if (anObject instanceof String)
{
String anotherString = (String)anObject;
int n = count;//字串長度
if (n == anotherString.count) //如果長度相等就進行比較
{
char v1[] = value;//取每一個位置的字元
char v2[] = anotherString.value;
int i = offset;
int j = anotherString.offset;
while (n-- != 0) //對於每一位置逐一比較
{
if (v1[i++] != v2[j++])
return false;
}
return true;
}
}
return false;
}
二、Java集合類在Java程式開發中使用極其頻繁,請回答相關問題
1、 請簡要說明什麼是ArrayList?如何使用。
2、 請簡要說明什麼是Hash演算法。以及HashMap如何通過Hash演算法實現資料存放區。
3、 通過無參構造方法構造HashMap:HashMap map = new HashMap();
現在往map中儲存28對key-value資料,請問map如何擴容,需擴容幾次。
4、 請簡要說明HashMap與 HashTable的區別。
5、 (選答,加分項)你是否瞭解Java並發集合類。
解釋:考察常見集合ArrayList的使用與HashMap的底層實現,可拓展提問其他集合類如HashSet(由封裝value的HashMap實現)等。
可參看部落格:給jdk寫注釋系列之jdk1.6容器(1):ArrayList源碼解析
三、請看下面這段程式,回答問題
public class Test3 {public static StringBuilder output= new StringBuilder();public static void foo(int i){try {if(i == 1){output.append("try1 ");throw new Exception();}output.append("try0 ");}catch (Exception e){output.append("catch ");return ;}finally {output.append("finally ");}output.append("end \n");}public static void main(String args[]){foo(0); foo(1); System.out.println(output);}}
1、 你瞭解Java的異常捕獲機制嗎。請根據你的理解寫出這段代碼的輸出結果。
輸出:
try0 finally end
try1 catch finally
解釋:考察StringBuilder的使用與Java異常捕獲機制、try-catch-finally的執行順序、return語句對執行順序的影響,可擴充提問,StringBuilder與StringBuffer區別與finally什麼情況下不執行。
try中是可能發生異常的程式段;
catch中依次編寫對應的異常處理器方法,當拋出異常後,由運行時系統在棧中從當前位置開始依次回查方法,直到找到合適的異常處理方法,如果未找到,則執行
finally或直接結束程式運行。
finally :無論是否捕獲或處理異常,finally塊裡的語句都會被執行。
注意(很重要,面試常問):當在try塊或catch塊中遇到return語句時,finally語句塊將在方法返回之前被執行。
在以下4種特殊情況下,finally塊不會被執行:
1)在finally語句塊中拋出了異常且未處理。
2)在前面的代碼中用了System.exit()退出程式。
3)程式所在的線程死亡。
4)CPU出現異常被關閉。
2、 你在平時編程時都遇到過哪些運行時異常。請舉例說明。
解釋:考察運行時異常的掌握情況與平時編程的積累。
1’ NullPointerException:null 指標異常。調用了不存在的對象或未經執行個體化或初始化的對象時會拋出,如當試圖操作一個Null 物件(賦值為null)的屬性、方法時就會拋出。
(執行個體化:通俗的理解就是為對象開闢空間,使其可在規定範圍內被調用。注意:User u;這隻是一個對象聲明,並沒有進行執行個體化或初始化。
初始化:就是把執行個體化後的對象中的基礎資料型別 (Elementary Data Type)欄位賦預設值或設定值,為非基本類型賦值null,對於static欄位只會初始化一次。)
2’ ArithmeticException:算術條件異常。最常見的就是0作除數時會拋出。
3’ ClassNotFoundException:類未找到異常。在通過反射Class.forName(“類名”)來擷取類時,如果未找到則會拋出異常。
4’ ArrayIndexOutOfBoundsException:數組索引越界異常。當試圖運算元組的索引值為負數或大於等於數組大小時會拋出。
5’ NegativeArraySizeException:數組長度為負值異常。一般在初始化數組大小為負值時拋出。
6’ ArrayStoreException:數群組類型不匹配值異常。例如將一個Object數組中加入一個Integer對象與一個String對象時,類型不符就會拋出。
7’ IllegalArgumentException:非法參數異常。會在使用Java類庫方法時傳入參數值越界時拋出。
四、單線程程式的功能往往非常有限,多線程與高並發環境開發已成為趨勢。Java提供了非常優秀的多線程支援,請回答相關問題
1、 Java有幾種建立線程的方式。有什麼區別。
解釋:考察線程類的掌握情況。
第一種是繼承Thread類重寫方法run(),不可以拋異常無傳回值
第二種是實現Runnable介面實現方法run()作為target傳入Thread類構造器不可以拋異常無傳回值適合多線程共用同一份資源情況
第三種是實現Callable<T>介面,介面中要覆蓋的方法是 public <T> call() 注意:此方法可以拋異常,而前兩種不能,而且此方法可以有傳回值,使用時用FutureTask對象封裝,作為target傳入Thread類構造器
請簡述線程的生命週期,Java中哪些方法會導致線程狀態變化。
解釋:考察線程狀態的掌握情況
2、 Thread類的sleep()方法和Object類的wait()方法都可以讓線程暫停執行,它們有什麼區別?
解釋:考察sleep()與wait()方法。注意這個問題百度比較好找,問的時候看是否真正理解了,比如可以讓解釋一下什麼叫不釋放對象鎖。
對於sleep()方法,我們首先要知道該方法是屬於Thread類中的。而wait()方法,則是屬於Object類中的。
sleep()方法導致了程式暫停執行指定的時間,讓出cpu該其他線程,但是他的監控狀態依然保持者,當指定的時間到了又會自動回復運行狀態。
在調用sleep()方法的過程中,線程不會釋放對象鎖。(形象的說是佔著CPU睡覺)
而當調用wait()方法的時候,線程會放棄對象鎖,進入等待此對象的等待鎖定池,只有針對此對象調用notify()方法後本線程才進入對象鎖定池準備。
五、(選答,加分項)
1、 你瞭解或使用過Json嗎。
2、 你瞭解或使用過什麼Java開源架構。(Oracle、Apache開源架構亦可)
3、 你開發過什麼Java或Android項目。