太原Java培訓
達內太原java培訓中心

18035108441

熱門課程

JAVA常見面試題及解答


  • Java的垃圾回收總結  淺談Java中的內部類
           JAVA常見面試題及解答(精華)  2009-05-20 14:47:25|  分類: 編程語言 |  標簽: |字號大
           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)抽象類和接口有什么區別?(瞬聯)
    1.abstract class 在 Java 語言中表示的是一種繼承關系,一個類只能使用一次繼承關系。但是,一個類卻可以實現多個interface。
    2.在abstract class 中可以有自己的數據成員,也可以有非abstarct的成員方法,而在interface中,只能夠有靜態的不能被修改的數據成員(也就是必須是 static final的,不過在 interface中一般不定義數據成員),所有的成員方法都是abstract的。
    3.abstract 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)
    {
    umber = num;
    System.out.println
    ("創建線程 " + number);
    }
    public void run() {
    while(true) {
    System.out.println
    ("線程 " + number + ":計數 " + count);
    if(++count== 6) return;
    }
    }
    public static void main(String args[])
    {
    for(int i = 0;i 〈 5; i++) new MyThread(i+1).start();
    }
    }
    這種方法簡單明了,符合大家的習慣,但是,它也有一個很大的缺點,那就是如果我們的類已經從一個類繼承(如小程序必須繼承自 Applet 類),則無法再繼承 Thread 類,這時如果我們又不想建立一個新的類,應該怎么辦呢?
    我們不妨來探索一種新的方法:我們不創建Thread類的子類,而是直接使用它,那么我們只能將我們的方法作為參數傳遞給 Thread 類的實例,有點類似回調函數。但是 Java 沒有指針,我們只能傳遞一個包含這個方法的類的實例。
    那么如何限制這個類必須包含這一方法呢?當然是使用接口?。m然抽象類也可滿足,但是需要繼承,而我們之所以要采用這種新方法,不就是為了避免繼承帶來的限制嗎?)
    Java 提供了接口 java.lang.Runnable 來支持這種方法。
    方法二:實現 Runnable 接口
    Runnable接口只有一個方法run(),我們聲明自己的類實現Runnable接口并提供這一方法,將我們的線程代碼寫入其中,就完成了這一部 分的任務。但是Runnable接口并沒有任何對線程的支持,我們還必須創建Thread類的實例,這一點通過Thread類的構造函數 public Thread(Runnable target);來實現。下面是一個例子:
    public class MyThread implements Runnable
    {
    int count= 1, number;
    public MyThread(int num)
    {
    umber = num;
    System.out.println("創建線程 " + number);
    }
    public void run()
    {
    while(true)
    {
    System.out.println
    ("線程 " + 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)).start();
    }
    }
    嚴格地說,創建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)。

預約申請免費試聽課程

         

上一篇:常見的JAVA面試題
下一篇:太原達內java培訓教程之java修飾符
選擇城市和中心
江西省

貴州省

廣西省

海南省

草莓成视频人app在线看