天天看點

Java面試題

都是一些非常非常基礎的題,是我最近參加各大IT公司筆試後靠記憶記下來的,經過整理獻給與我一樣參

 http://www.cnblogs.com/lanxuezaipiao/p/3371224.html

下面都是我自己的答案非官方,僅供參考,如果有疑問或錯誤請一定要提出來,大家一起進步啦~~~

1. 下面哪些是Thread類的方法()

A start()       B run()       C exit()       D getPriority()

答案:ABD

解析:看Java API docs吧:http://docs.oracle.com/javase/7/docs/api/,exit()是System類的方法,如System.exit(0)。

2. 下面關于java.lang.Exception類的說法正确的是()

A 繼承自Throwable      B Serialable      CD 不記得,反正不正确

答案:A

解析:Java異常的基類為java.lang.Throwable,java.lang.Error和java.lang.Exception繼承 Throwable,RuntimeException和其它的Exception等繼承Exception,具體的RuntimeException繼承RuntimeException。

擴充:錯誤和異常的差別(Error vs Exception) 

1) java.lang.Error: Throwable的子類,用于标記嚴重錯誤。合理的應用程式不應該去try/catch這種錯誤。絕大多數的錯誤都是非正常的,就根本不該出現的。

java.lang.Exception: Throwable的子類,用于訓示一種合理的程式想去catch的條件。即它僅僅是一種程式運作條件,而非嚴重錯誤,并且鼓勵使用者程式去catch它。

2)  Error和RuntimeException 及其子類都是未檢查的異常(unchecked exceptions),而所有其他的Exception類都是檢查了的異常(checked exceptions).

checked exceptions: 通常是從一個可以恢複的程式中抛出來的,并且最好能夠從這種異常中使用程式恢複。比如FileNotFoundException, ParseException等。檢查了的異常發生在編譯階段,必須要使用try…catch(或者throws)否則編譯不通過。

unchecked exceptions: 通常是如果一切正常的話本不該發生的異常,但是的确發生了。發生在運作期,具有不确定性,主要是由于程式的邏輯問題所引起的。

比如ArrayIndexOutOfBoundException,

ClassCastException等。從語言本身的角度講,程式不該去catch這類異常,雖然能夠從諸如RuntimeException這樣的異

常中catch并恢複,但是并不鼓勵終端程式員這麼做,因為完全沒要必要。因為這類錯誤本身就是bug,應該被修複,出現此類錯誤時程式就應該立即停止執

行。 是以,面對Errors和unchecked

exceptions應該讓程式自動終止執行,程式員不該做諸如try/catch這樣的事情,而是應該查明原因,修改代碼邏輯。

RuntimeException:RuntimeException體系包括錯誤的類型轉換、數組越界通路和試圖通路空指針等等。

處理RuntimeException的原則是:

如果出現

RuntimeException,那麼一定是程式員的錯誤。例如,可以通過檢查數組下标和數組邊界來避免數組越界通路異常。其他

(IOException等等)checked異常一般是外部錯誤,例如試圖從檔案尾後讀取資料等,這并不是程式本身的錯誤,而是在應用環境中出現的外部

錯誤。 

3. 下面程式的運作結果是()

答案:false

解析:因為str2中的llo是新申請的記憶體塊,而==判斷的是對象的位址而非值,是以不一樣。如果是String str2 = str1,那麼就是true了。

4. 下列說法正确的有()

A. class中的constructor不可省略

B. constructor必須與class同名,但方法不能與class同名

C. constructor在一個對象被new時執行

D.一個class隻能定義一個constructor

答案:C 

解析:這裡可能會有誤區,其實普通的類方法是可以和類名同名的,和構造方法唯一的區分就是,構造方法沒有傳回值。

5. 具體選項不記得,但用到的知識如下:

String []a = new String[10];

則:a[0]~a[9] = null

a.length = 10

如果是int []a = new int[10];

則:a[0]~a[9] = 0

6. 下面程式的運作結果:()

A pingpong        B pongping       C pingpong和pongping都有可能       D 都不輸出

答案:B

析:這裡考的是Thread類中start()和run()方法的差別了。start()用來啟動一個線程,當調用start方法後,系統才會開啟一個新

的線程,進而調用run()方法來執行任務,而單獨的調用run()就跟調用普通方法是一樣的,已經失去線程的特性了。是以在啟動一個線程的時候一定要使

用start()而不是run()。

7. 下列屬于關系型資料庫的是()

A. Oracle    B MySql    C IMS     D MongoDB

答案:AB

解答:IMS(Information Management System )資料庫是IBM公司開發的兩種資料庫類型之一; 

一種是關系資料庫,典型代表産品:DB2;

另一種則是層次資料庫,代表産品:IMS層次資料庫。

非關系型資料庫有MongoDB、memcachedb、Redis等。

8. GC線程是否為守護線程?()

答案:是

解析:線程分為守護線程和非守護線程(即使用者線程)。

隻要目前JVM執行個體中尚存在任何一個非守護線程沒有結束,守護線程就全部工作;隻有當最後一個非守護線程結束時,守護線程随着JVM一同結束工作。

守護線程最典型的應用就是 GC (垃圾回收器)

9. volatile關鍵字是否能保證線程安全?()

答案:不能

解析:volatile關鍵字用在多線程同步中,可保證讀取的可見性,JVM隻是保證從主記憶體加載到線程工作記憶體的值是最新的讀取值,而非cache中。但多個線程對

volatile的寫操作,無法保證線程安全。例

如假如線程1,線程2 在進行read,load

操作中,發現主記憶體中count的值都是5,那麼都會加載這個最新的值,線上程1堆count進行修改之後,會write到主記憶體中,主記憶體中的

count變量就會變為6;線程2由于已經進行read,load操作,在進行運算之後,也會更新主記憶體count的變量值為6;導緻兩個線程及時用

volatile關鍵字修改之後,還是會存在并發的情況。

10. 下列說法正确的是()

A LinkedList繼承自List

B AbstractSet繼承自Set

C HashSet繼承自AbstractSet

D WeakMap繼承自HashMap

答案:AC

解析:下面是一張下載下傳的Java中的集合類型的繼承關系圖,一目了然。

11. 存在使i + 1 < i的數嗎()

答案:存在

解析:如果i為int型,那麼當i為int能表示的最大整數時,i+1就溢出變成負數了,此時不就<i了嗎。

擴充:存在使i > j || i <= j不成立的數嗎()

解析:比如Double.NaN或Float.NaN,感謝@BuilderQiu網友指出。

12. 0.6332的資料類型是()

A float     B double     C Float      D Double

解析:預設為double型,如果為float型需要加上f顯示說明,即0.6332f

13. 下面哪個流類屬于面向字元的輸入流(  )

A  BufferedWriter           B  FileInputStream          C  ObjectInputStream          D  InputStreamReader

 答案:D

 解析:Java的IO操作中有面向位元組(Byte)和面向字元(Character)兩種方式。

面向位元組的操作為以8位為機關對二進制的資料進行操作,對資料不進行轉換,這些類都是InputStream和OutputStream的子類。

面向字元的操作為以字元為機關對資料進行操作,在讀的時候将二進制資料轉為字元,在寫的時候将字元轉為二進制資料,這些類都是Reader和Writer的子類。

總結:以InputStream(輸入)/OutputStream(輸出)為字尾的是位元組流;

          以Reader(輸入)/Writer(輸出)為字尾的是字元流。

擴充:Java流類圖結構,一目了然,解決大部分選擇題:

14. Java接口的修飾符可以為()

A private     B protected     C final       D abstract

答案:CD

解析:接口很重要,為了說明情況,這裡稍微啰嗦點:

(1)接口用于描述系統對外提供的所有服務,是以接口中的成員常量和方法都必須是公開(public)類型的,確定外部使用者能通路它們;

(2)接口僅僅描述系統能做什麼,但不指明如何去做,是以接口中的方法都是抽象(abstract)方法;

(3)接口不涉及和任何具體執行個體相關的細節,是以接口沒有構造方法,不能被執行個體化,沒有執行個體變量,隻有靜态(static)變量;

(4)接口的中的變量是所有實作類共有的,既然共有,肯定是不變的東西,因為變化的東西也不能夠算共有。是以變量是不可變(final)類型,也就是常量了。

(5) 接口中不可以定義變量?如果接口可以定義變量,但是接口中的方法又都是抽象的,在接口中無法通過行為來修改屬性。有的人會說了,沒有關系,可以通過

實作接口的對象的行為來修改接口中的屬性。這當然沒有問題,但是考慮這樣的情況。如果接口 A 中有一個public 通路權限的靜态變量 a。按照

Java 的語義,我們可以不通過實作接口的對象來通路變量 a,通過 A.a = xxx; 就可以改變接口中的變量 a

的值了。正如抽象類中是可以這樣做的,那麼實作接口 A 的所有對象也都會自動擁有這一改變後的 a 的值了,也就是說一個地方改變了

a,所有這些對象中 a

的值也都跟着變了。這和抽象類有什麼差別呢,怎麼展現接口更高的抽象級别呢,怎麼展現接口提供的統一的協定呢,那還要接口這種抽象來做什麼呢?是以接口中

不能出現變量,如果有變量,就和接口提供的統一的抽象這種思想是抵觸的。是以接口中的屬性必然是常量,隻能讀不能改,這樣才能為實作接口的對象提供一個統

一的屬性。

通俗的講,你認為是要變化的東西,就放在你自己的實作中,不能放在接口中去,接口隻是對一類事物的屬性和行為更高層次的抽象。對修改關閉,對擴充(不同的實作 implements)開放,接口是對開閉原則的一種展現。

是以:

接口的方法預設是public abstract;

接口中不可以定義變量即隻能定義常量(加上final修飾就會變成常量)。是以接口的屬性預設是public static final 常量,且必須賦初值。

注意:final和abstract不能同時出現。

15. 不通過構造函數也能建立對象嗎()

A 是     B 否

解析:Java建立對象的幾種方式(重要):

(1) 用new語句建立對象,這是最常見的建立對象的方法。

(2) 運用反射手段,調用java.lang.Class或者java.lang.reflect.Constructor類的newInstance()執行個體方法。

(3) 調用對象的clone()方法。

(4) 運用反序列化手段,調用java.io.ObjectInputStream對象的 readObject()方法。

(1)和(2)都會明确的顯式的調用構造函數 ;(3)是在記憶體上對已有對象的影印,是以不會調用構造函數 ;(4)是從檔案中還原類的對象,也不會調用構造函數。

16. ArrayList list = new ArrayList(20);中的list擴充幾次()

A 0     B 1     C 2      D 3

解析:這裡有點迷惑人,大家都知道預設ArrayList的長度是10個,是以如果你要往list裡添加20個元素肯定要擴充一次(擴充為原來的1.5倍),但是這裡顯示指明了需要多少空間,是以就一次性為你配置設定這麼多空間,也就是不需要擴充了。

17. 下面哪些是對稱加密算法()

A DES   B AES   C DSA   D RSA

解析:常用的對稱加密算法有:DES、3DES、RC2、RC4、AES

常用的非對稱加密算法有:RSA、DSA、ECC

使用單向散列函數的加密算法:MD5、SHA

18.建立一個流對象,下面哪個選項的代碼是錯誤的?()

A)new BufferedWriter(new FileWriter("a.txt"));

B)new BufferedReader(new FileInputStream("a.dat"));

C)new GZIPOutputStream(new FileOutputStream("a.zip"));

D)new ObjectInputStream(new FileInputStream("a.dat"));

解析:請記得13題的那個圖嗎?Reader隻能用FileReader進行執行個體化。

19. 下面程式能正常運作嗎()

答案:能正常運作

解析:輸出為haha,因為null值可以強制轉

換為任何java類類型,(String)null也是合法的。但null強制轉換後是無效對象,其傳回值還是為null,而static方法的調用是和

類名綁定的,不借助對象進行通路是以能正确輸出。反過來,沒有static修飾就隻能用對象進行通路,使用null調用對象肯定會報空指針錯了。這裡和

C++很類似。這裡感謝@Florian網友解答。

20. 下面程式的運作結果是什麼()

答案:

解析:說實話我覺得這題很好,考查靜态語句塊、構造語句塊(就是隻有大括号的那塊)以及構造函數的執行順序。

對象的初始化順序:(1)類加載之後,按從上到下(從父類到子類)執行被static修飾的語句;(2)當static語句執行完之後,再執行main方法;(3)如果有語句new了自身的對象,将從上到下執行構造代碼塊、構造器(兩者可以說綁定在一起)。

下面稍微修改下上面的代碼,以便更清晰的說明情況:

此時輸出結果為:

21. getCustomerInfo()方法如下,try中可以捕獲三種類型的異常,如果在該方法運作中産生了一個IOException,将會輸出什麼結果()

A IOException!

BIOException!Exception!

CFileNotFoundException!IOException!

DFileNotFoundException!IOException!Exception!

析:考察多個catch語句塊的執行順序。當用多個catch語句時,catch語句塊在次序上有先後之分。從最前面的catch語句塊依次先後進行異常

類型比對,這樣如果父異常在子異常類之前,那麼首先比對的将是父異常類,子異常類将不會獲得比對的機會,也即子異常類型所在的catch語句塊将是不可到

達的語句。是以,一般将父類異常類即Exception老大放在catch語句塊的最後一個。

22. 下面代碼的運作結果為:()

A 代碼得到編譯,并輸出“s=”

B 代碼得到編譯,并輸出“s=null”

C 由于String s沒有初始化,代碼不能編譯通過

D 代碼得到編譯,但捕獲到 NullPointException異常

答案:C

解析:開始以為會輸出null什麼的,運作後才發現Java中所有定義的基本類型或對象都必須初始化才能輸出值。

23.  System.out.println("5" + 2);的輸出結果應該是()。

A 52                   B7                     C2                     D5

解析:沒啥好說的,Java會自動将2轉換為字元串。

24. 指出下列程式運作的結果 ()

A、 good and abc

B、 good and gbc

C、 test ok and abc

D、 test ok and gbc 

解析:大家可能以為Java中String和數組都是對象是以肯定是對象引用,然後就會選D,其實這是個很大的誤區:因為在java裡沒有引用傳遞,隻有值傳遞

這個值指的是實參的位址的拷貝,得到這個拷貝位址後,你可以通過它修改這個位址的内容(引用不變),因為此時這個内容的位址和原位址是同一位址,

但是你不能改變這個位址本身使其重新引用其它的對象,也就是值傳遞,可能說的不是很清楚,下面給出一個完整的能說明情況的例子吧:

View Code

程式有些啰嗦,但能反映問題,該程式運作結果為:

說明:不管是對象、基本類型還是對象數組、基本類型數組,在函數中都不能改變其實際位址但能改變其中的内容。

25. 要從檔案"file.dat"中讀出第10個位元組到變量c中,下列哪個方法适合? ()

A FileInputStream in=new FileInputStream("file.dat"); in.skip(9); int c=in.read();

B FileInputStream in=new FileInputStream("file.dat"); in.skip(10); int c=in.read();

C FileInputStream in=new FileInputStream("file.dat"); int c=in.read();

D RandomAccessFile in=new RandomAccessFile("file.dat"); in.skip(9); int c=in.readByte();

答案:A?D?

解析:long skip(long n)作用是跳過n個位元組不讀,主要用在包裝流中的,因為一般流(如FileInputStream)隻

能順序一個一個的讀不能跳躍讀,但是包裝流可以用skip方法跳躍讀取。那麼什麼是包裝流呢?各種位元組節點流類,它們都隻具有讀寫位元組内容的方法,以

FileInputStream與FileOutputStream為例,它們隻能在檔案中讀取或者向檔案中寫入位元組,在實際應用中我們往往需要在檔案中

讀取或者寫入各種類型的資料,就必須先将其他類型的資料轉換成位元組數組後寫入檔案,或者從檔案中讀取到的位元組數組轉換成其他資料類型,想想都很麻煩!!因

此想通過FileOutputStream将一個浮點小數寫入到檔案中或将一個整數寫入到檔案時是非常困難的。這時就需要包裝類DataInputStream/DataOutputStream,它提供了往各種輸入輸出流對象中讀入或寫入各種類型的資料的方法。

DataInputStream/DataOutputStream并沒有對應到任何具體的流裝置,一定要給它傳遞一個對應具體流裝置的輸入或輸出流對象,完成類似 DataInputStream/DataOutputStream功

能的類就是一個包裝類,也叫過濾流類或處理流類。它對InputOutStream/OutputStream流類進行了包裝,使程式設計人員使用起來更方

便。其中DataInputStream包裝類的構造函數文法:public DataInputStream(InputStream

in)。包裝類也可以包裝另外一個包裝類。

首先BC肯定 是錯的,那A正确嗎?按上面的解析應該也不對,但我試了下,發現A也是正确的,與網上解析的資料有些出入,下面是我的code:

那麼D呢,RandomAccessFile是IO包的類,但是其自成一派,從Object直接繼承而來。可以對檔案進行讀取和寫入。支援檔案的随機通路,即可以随機讀取檔案中的某個位置内容,這麼說RandomAccessFile肯定可以達到題目的要求,但是選項有些錯誤,比如RandomAccessFile的初始化是兩個參數而非一個參數,采用的跳躍讀取方法是skipBytes()而非skip(),即正确的寫法是:

這樣也能讀到第十個位元組,也就是A和D都能讀到第十個位元組,那麼到底該選哪個呢?A和D有啥不同嗎?求大神解答~~~

26. 下列哪種異常是檢查型異常,需要在編寫程式時聲明 ()

ANullPointerException        BClassCastException      CFileNotFoundException       D IndexOutOfBoundsException 

解析:看第2題的解析。

27. 下面的方法,當輸入為2的時候傳回值是多少?()

A0                    B2                    C4                     D10

答案:D

解析:注意這裡case後面沒有加break,是以從case 2開始一直往下運作。

28. 選項中哪一行代碼可以替換題目中//add code here而不産生編譯錯誤?()

Apublic abstract void method(int a);

B constInt = constInt + 5;

C public int method();

D public abstract void anotherMethod() {}

解析:考察抽象類的使用。

抽象類遵循的原則:

(1)abstract關鍵字隻能修飾類和方法,不能修飾字段。

(2)抽象類不能被執行個體化(無法使用new關鍵字建立對象執行個體),隻能被繼承。

(3)抽象類可以包含屬性,方法,構造方法,初始化塊,内部類,枚舉類,和普通類一樣,普通方法一定要實作,變量可以初始化或不初始化但不能初始化後在抽象類中重新指派或操作該變量(隻能在子類中改變該變量)。

(4)抽象類中的抽象方法(加了abstract關鍵字的方法)不能實作。

(5)含有抽象方法的類必須定義成抽象類。

擴充:抽象類和接口的差別,做個總結吧:

(1)接口是公開的,裡面不能有私有的方法或變量,是用于讓别人使用的,而抽象類是可以有私有方法或私有變量的。

(2)abstract class 在 Java 語言中表示的是一種繼承關系,一個類隻能使用一次繼承關系。但是,一個類卻可以實作多個interface,實作多重繼承。接口還有辨別(裡面沒有任何方法,如Remote接口)和資料共享(裡面的變量全是常量)的作用。

(3)在abstract class 中可以有自己的資料成員,也可以有非abstarct的成員方法,而在interface中,隻能夠有靜态的不能被修改的資料成員(也就是必須是 static final的,不過在 interface中一般不定義資料成員),所有的成員方法預設都是 public abstract 類型的。

(4)abstract class和interface所反映出的設計理念不同。其實abstract class表示的是"is-a"關系,interface表示的是"has-a"關系。

(5)實作接口的一定要實作接口裡定義的所有方法,而實作抽象類可以有選擇地重寫需要用到的方法,一般的應用裡,最頂級的是接口,然後是抽象類實作接口,最後才到具體類實作。抽象類中可以有非抽象方法。接口中則不能有實作方法。

(6)接口中定義的變量預設是public static final 型,且必須給其初值,是以實作類中不能重新定義,也不能改變其值。抽象類中的變量預設是 friendly 型,其值可以在子類中重新定義,也可以在子類中重新指派。

29. 閱讀Shape和Circle兩個類的定義。在序列化一個Circle的對象circle到檔案時,下面哪個字段會被儲存到檔案中? (  )

Aname

B radius

C color

D type

解析:這裡有詳細的解釋:http://www.cnblogs.com/lanxuezaipiao/p/3369962.html

30.下面是People和Child類的定義和構造方法,每個構造方法都輸出編号。在執行new Child("mike")的時候都有哪些構造方法被順序調用?請選擇輸出結果 ( )

A312              B 32               C 432              D 132

解析:考察的又是父類與子類的構造函數調用次序。在Java中,子類的構造過程中必須調用其父類的構造函數,是因為有繼承關系存在時,子類要把父類的内容繼承下來。但如果父類有多個構造函數時,該如何選擇調用呢?

第一個規則:子類的構造過程中,必須調用其父類的構造方法。一個類,如果我們不寫構造方法,那麼編譯器會幫我們加上一個預設的構造方法(就是沒有參數的構造方法),但是如果你自己寫了構造方法,那麼編譯器就不會給你添加了,是以有時候當你new一個子類對象的時候,肯定調用了子類的構造方法,但是如果在子類構造方法中我們并沒有顯示的調用基類的構造方法,如:super();  這樣就會調用父類沒有參數的構造方法。    

第二個規則:如果子類的構造方法中既沒有顯示的調用基類構造方法,而基類中又沒有無參的構造方法,則編譯出錯,是以,通常我們需要顯示的:super(參數清單),來調用父類有參數的構造函數,此時無參的構造函數就不會被調用。

總之,一句話:子類沒有顯示調用父類構造函數,不管子類構造函數是否帶參數都預設調用父類無參的構造函數,若父類沒有則編譯出錯。

最後,給大家出個思考題:下面程式的運作結果是什麼?

繼續閱讀