java面試問題及答案

java經典面試題及參考答案

java面試問題及答案

1、作用域public,private,protected,以及不寫時的區別

答:區別如下:

作用域 當前類 同一package 子孫類 其他package

public √ √ √ √

protected √ √ √ ×

friendly √ √ × ×

private √ × × ×

不寫時默認為friendly

2、arraylist和vector的區別,hashmap和hashtable的區別

答:就arraylist與vector主要從二方面來説.

一.同步性:vector是線程安全的,也就是説是同步的,而arraylist是線程序不安全的,不是同步的

二.數據增長:當需要增長時,vector默認增長為原來一培,而arraylist卻是原來的一半

就hashmap與hashtable主要從三方面來説。

一.歷史原因:hashtable是基於陳舊的dictionary類的,hashmap是java 1.2引進的map接口的一個實現

二.同步性:hashtable是線程安全的,也就是説是同步的,而hashmap是線程序不安全的,不是同步的

三.值:只有hashmap可以讓你將空值作為一個表的條目的key或value

3、char型變量中能不能存貯一箇中文漢字?為什麼?

答:是能夠定義成為一箇中文的,因為java中以unicode編碼,一個char佔16個字節,所以放一箇中文是沒問題的

4、多線程有幾種實現方法,都是什麼?同步有幾種實現方法,都是什麼?

答:多線程有兩種實現方法,分別是繼承thread類與實現runnable接口

同步的實現方面有兩種,分別是synchronized,wait與notify

 java經典面試題及參考答案

1)transient和volatile是java關鍵字嗎?(瞬聯)

如果用transient聲明一個實例變量,當對象存儲時,它的值不需要維持。例如:

class t

{

transient int a; //不需要維持

int b; //需要維持

}

這裏,如果t類的一個對象寫入一個持久的存儲區域,a的內容不被保存,但b的將被保存。

volatile修飾符告訴編譯器被volatile修飾的變量可以被程序的其他部分改變。在多線程程序中,有時兩個或更多的線程共享一個相同的實例變量。考慮效率問題,每個線程可以自己保存該共享變量的私有拷貝。實際的變量副本在不同的時候更新,如當進入synchronized方法時。 用strictfp修飾類或方法,可以確保浮點運算(以及所有切斷)正如早期的java版本那樣準確。切斷隻影響某些操作的指數。當一個類被strictfp修飾,所有的方法自動被strictfp修飾。

strictfp的意思是fp-strict,也就是説精確浮點的意思。在java虛擬機進行浮點運算時,如果沒有指定strictfp關鍵字時,java的編譯器以及運行環境在對浮點運算的表達式是採取一種近似於我行我素的行為來完成這些操作,以致於得到的結果往往無法令你滿意。而一旦使用了strictfp來聲明一個類、接口或者方法時,那麼所聲明的範圍內java的編譯器以及運行環境會完全依照浮點規範ieee-754來執行。因此如果你想讓你的浮點運算更加精確,而且不會因為不同的硬件平台所執行的結果不一致的話,那就請用關鍵字strictfp。

你可以將一個類、接口以及方法聲明為strictfp,但是不允許對接口中的方法以及構造函數聲明strictfp關鍵字,例如下面的代碼:

strictfp interface a {}

public strictfp class fpdemo1 {

strictfp void f() {}

}

2. 錯誤的使用方法

interface a {

strictfp void f();

}

public class fpdemo2 {

strictfp fpdemo2() {}

}

一旦使用了關鍵字strictfp來聲明某個類、接口或者方法時,那麼在這個關鍵字所聲明的範圍內所有浮點運算都是精確的,符合ieee-754規範

的。例如一個類被聲明為strictfp,那麼該類中所有的方法都是strictfp的。

2)抽象類和接口有什麼區別?(瞬聯)

ract class 在 java 語言中表示的是一種繼承關係,一個類只能使用一次繼承關係。但是,一個類卻可以實現多個interface。

2.在abstract class 中可以有自己的數據成員,也可以有非abstarct的成員方法,而在interface中,只能夠有靜態的不能被修改的數據成員(也就是必須是static final的,不過在 interface中一般不定義數據成員),所有的成員方法都是abstract的。

ract class和interface所反映出的設計理念不同。其實abstract class表示的是"is-a"關係,interface表示的是"like-a"關係。

4.實現抽象類和接口的類必須實現其中的所有方法。抽象類中可以有非抽象方法。接口中則不能有實現方法。

5.接口中定義的變量默認是public static final 型,且必須給其初值,所以實現類中不能重新定義,也不能改變其值。

6.抽象類中的變量默認是 friendly 型,其值可以在子類中重新定義,也可以重新賦值。

7.接口中的方法默認都是 public,abstract 類型的。

3)能説一下java的反射(reflection)機制嗎?(瞬聯)

開放性和原因連接(causally-connected)是反射系統的兩大基本要素

4)在java中怎樣實現多線程?(瞬聯)

extends thread

implement runnable

方法一:繼承 thread 類,覆蓋方法 run(),我們在創建的 thread 類的子類中重寫 run() ,加入線程所要執行的代碼即可。下面是一個例子:

public class mythread extends thread

{

int count= 1, number;

public mythread(int num)

{

number = num;

tln

("創建線程 " + number);

}

public void run() {

while(true) {

tln

("線程 " + number + ":計數 " + count);

if(++count== 6) return;

}

}

public static void main(string args[])

{

for(int i = 0;i 〈 5; i++) new mythread(i+1)t();

}

}

這種方法簡單明瞭,符合大家的習慣,但是,它也有一個很大的缺點,那就是如果我們的類已經從一個類繼承(如小程序必須繼承自 applet 類),則無法再繼承 thread 類,這時如果我們又不想建立一個新的類,應該怎麼辦呢?

我們不妨來探索一種新的方法:我們不創建thread類的子類,而是直接使用它,那麼我們只能將我們的方法作為參數傳遞給 thread 類的實例,有點類似回調函數。但是 java 沒有指針,我們只能傳遞一個包含這個方法的類的實例。

那麼如何限制這個類必須包含這一方法呢?當然是使用接口!(雖然抽象類也可滿足,但是需要繼承,而我們之所以要採用這種新方法,不就是為了避免繼承帶來的限制嗎?)

java 提供了接口 able 來支持這種方法。

方法二:實現 runnable 接口

runnable接口只有一個方法run(),我們聲明自己的類實現runnable接口並提供這一方法,將我們的線程代碼寫入其中,就完成了這一部分的任務。但是runnable接口並沒有任何對線程的支持,我們還必須創建thread類的實例,這一點通過thread類的構造函數 public thread(runnable target);來實現。下面是一個例子:

public class mythread implements runnable

{

int count= 1, number;

public mythread(int num)

{

number = num;

tln("創建線程 " + number);

}

public void run()

{

while(true)

{

tln

("線程 " + number + ":計數 " + count);

if(++count== 6) return;

}

}

public static void main(string args[])

{

for(int i = 0; i 〈 5;i++) new thread(new mythread(i+1))t();

}

}

嚴格地説,創建thread子類的實例也是可行的,但是必須注意的是,該子類必須沒有覆蓋 thread 類的 run 方法,否則該線程執行的將是子類的 run 方法,而不是我們用以實現runnable 接口的類的 run 方法,對此大家不妨試驗一下。

使用 runnable 接口來實現多線程使得我們能夠在一個類中包容所有的代碼,有利於封裝,它的缺點在於,我們只能使用一套代碼,若想創建多個線程並使各個線程執行不同的代碼,則仍必須額外創建類,如果這樣的話,在大多數情況下也許還不如直接用多個類分別繼承 thread 來得緊湊。

綜上所述,兩種方法各有千秋,大家可以靈活運用。

下面讓我們一起來研究一下多線程使用中的一些問題。

三、線程的四種狀態

1. 新狀態:線程已被創建但尚未執行(start() 尚未被調用)。

2. 可執行狀態:線程可以執行,雖然不一定正在執行。cpu 時間隨時可能被分配給該線程,從而使得它執行。

3. 死亡狀態:正常情況下 run() 返回使得線程死亡。調用 stop()或 destroy() 亦有同樣效果,但是不被推薦,前者會產生異常,後者是強制終止,不會釋放鎖。

4. 阻塞狀態:線程不會被分配 cpu 時間,無法執行。

四、線程的優先級

線程的優先級代表該線程的重要程度,當有多個線程同時處於可執行狀態並等待獲得 cpu 時間時,線程調度系統根據各個線程的優先級來決定給誰分配 cpu 時間,優先級高的線程有更大的機會獲得 cpu 時間,優先級低的線程也不是沒有機會,只是機會要小一些罷了。

你可以調用 thread 類的方法 getpriority() 和 setpriority()來存取線程的優先級,線程的優先級界於1(min_priority)和10(max_priority)之間,缺省是5(norm_priority)。

5)你用過哪種設計模式?(瞬聯,ibm,aspentech)

設計:design

模式:pattern

框架:framework

創建模式,結構模式和行為模式

gof設計模式

a.創建模式

設計模式之factory(工廠模式)

使用工廠模式就象使用new一樣頻繁更新

設計模式之prototype(原型模式)

用原型實例指定創建對象的種類,並且通過拷貝這些原型創建新的對象。

設計模式之builder

汽車由車輪 方向盤 發動機很多部件組成,同時,將這些部件組裝成汽車也是一件複雜的工作,builder模式就是將這兩種情況分開進行。

設計模式之singleton(單態模式)

保證一個類只有一個實例,並提供一個訪問它的全局訪問點 XX/10/9更新

b.結構模式

設計模式之facade

可擴展的使用jdbc針對不同的數據庫編程,facade提供了一種靈活的實現.

設計模式之proxy

以jive為例,剖析代理模式在用户級別授權機制上的應用

設計模式之adapter

使用類再生的兩個方式:組合(new)和繼承(extends),這個已經在"thinking in java"中提到過.

設計模式之composite

就是將類用樹形結構組合成一個單位.你向別人介紹你是某單位,你是單位中的一個元素,別人和你做買賣,相當於和單位做買賣。文章中還對jive再進行了剖析。

設計模式之decorator

decorator是個油漆工,給你的東東的外表刷上美麗的顏色.

設計模式之bridge

將"牛郎織女"分開(本應在一起,分開他們,形成兩個接口),在他們之間搭建一個橋(動態的結合)

設計模式之flyweight

提供java運行性能,降低小而大量重複的類的開銷.

c.行為模式

設計模式之template

實際上向你介紹了為什麼要使用java 抽象類,該模式原理簡單,使用很普遍.

設計模式之memento

很簡單一個模式,就是在內存中保留原來數據的拷貝.

設計模式之observer

介紹如何使用java api提供的現成observer

設計模式之chain of responsibility

各司其職的類串成一串,好象擊鼓傳花,當然如果自己能完成,就不要推委給下一個.

設計模式之command

什麼是將行為封裝,command是最好的説明.

設計模式之state

狀態是編程中經常碰到的實例,將狀態對象化,設立狀態變換器,便可在狀態中輕鬆切換.

設計模式之strategy

不同算法各自封裝,用户端可隨意挑選需要的算法.

設計模式之mediator

mediator很象十字路口的紅綠燈,每個車輛只需和紅綠燈交互就可以.

設計模式之interpreter

主要用來對語言的分析,應用機會不多.

設計模式之visitor

訪問者在進行訪問時,完成一系列實質性操作,而且還可以擴展.

設計模式之iterator

這個模式已經被整合入java的collection.在大多數場合下無需自己製造一個iterator,只要將對象裝入collection中,直接使用iterator進行對象遍歷。