當前位置:概念範文網>簡歷資料>面試試題>

java面試問題

面試試題 閱讀(1.08W)

java面試問題

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 來得緊湊。

 華為java面試問題

question no: 1

publicclass test1 {

publicstaticvoid changestr(string str){

str="welcome";

}

publicstaticvoid main(string[] args) {

string str="1234";

changestr(str);

tln(str);

}

}

//輸出結果:1234

//這裡雖然是一個靜態方法,但是裡面的變數是一個區域性變數,

//所以這裡不因為是靜態方法,就誤認為裡面的變數也是靜態變量了

question no:2

publicclass test2 {

staticboolean foo(char c) {

t(c);

returntrue;

}

publicstaticvoid main(string[] argv) {

int i = 0;

//for(65;88&&(i<2);67)

for (foo('a'); foo('b') && (i < 2); foo('c')) {

i++;

foo('d');

}

}

}

/*

what is the result?

a. abdcbdcb

b. abcdabcd

c. compilation fails.

d. an exception is thrown at runtime.

//輸出結果是:abdcbdcb

分析:for迴圈裡面講究的條件要為真,與你的判斷式是什麼沒有關係

就像這裡,雖然是列印的字母,但是卻不是false,所以可以執行

第一次進行迴圈:

foo('a')列印字母a,(注:這裡不是false條件就預設為true條件)

foo('b')列印字母b,i=0,比較(i < 2),條件為true,進行迴圈體,foo('d')列印d

foo('c')列印字母c

第二次迴圈:

foo('b')列印b,i=1,比較(i < 2)為true,進行迴圈體,foo('d')列印d

foo('c')列印字母c

第三次迴圈:

foo('b')列印字母b,i=2,比較(i < 2)為false,退出迴圈,得結果

*/