Java基礎知識(八)

Java基礎知識(八)

71. 解釋內存中的棧(stack)、堆(heap)和靜態區(static area)的用法

通常我們定義一個基本數據類型的變量,還有就是函數調用的現場保存都使用內存中的棧空間;
而通過 new 關鍵字和構造器創建的對象放在堆空間;程序中的字面量(literal)如直接書寫的 100、”
hello”和常量都是放在靜態區中。
棧空間操作起來最快但是棧很小,通常大量的對象都是放在堆空間,理論上整個內存沒有被其
他進程使用的空間甚至硬盤上的虛擬內存都可以被當成堆空間來使用。 String str = new String(“hello”); 上面的語句中變量 str 放在棧上,用 new 創建出來的字符串對象放在堆上,而”hello”這個字面
量放在靜態區。

72. 怎樣將 GB2312 編碼的字符串轉換爲 ISO-8859-1 編碼的字符串?

代碼如下所示:

String s1 = "你好"; 

String s2 = new String(s1.getBytes("GB2312"), "ISO-8859-1"); 

73. 運行時異常與受檢異常有何異同?

異常表示程序運行過程中可能出現的非正常狀態,運行時異常表示虛擬機的通常操作中可能遇
到的異常,是一種常見運行錯誤,只要程序設計得沒有問題通常就不會發生。受檢異常跟程序運行
的上下文環境有關,即使程序設計無誤,仍然可能因使用的問題而引發。Java 編譯器要求方法必須
聲明拋出可能發生的受檢異常,但是並不要求必須聲明拋出未被捕獲的運行時異常。異常和繼承一
樣,是面向對象程序設計中經常被濫用的東西,在 Effective Java 中對異常的使用給出了以下指導原
則:

  • 不要將異常處理用於正常的控制流(設計良好的 API 不應該強迫它的調用者爲了正常的控制
    流而使用異常)
  • 對可以恢復的情況使用受檢異常,對編程錯誤使用運行時異常
  • 避免不必要的使用受檢異常(可以通過一些狀態檢測手段來避免異常的發生)
  • 優先使用標準的異常
  • 每個方法拋出的異常都要有文檔
  • 保持異常的原子性
  • 不要在 catch 中忽略掉捕獲到的異常

74. 列出一些你常見的運行時異常?

ArithmeticException(算術異常)   5/0 
ClassCastException (類轉換異常) 
IllegalArgumentException (非法參數異常) 
IndexOutOfBoundsException (下標越界異常) 
NullPointerException (空指針異常) 
SecurityException (安全異常) 
NumberFormatException   (數字格式異常 Integer.parseInt(“a1b2”)) 
FileNotFoundException (文件找不到異常) 
ClassNotFoundException (類找不到異常) 

75. List、Set、Map 是否繼承自 Collection 接口?

List、Set 是,Map 不是。Map 是鍵值對映射容器,與 List 和 Set 有明顯的區別,而 Set 存儲的
零散的元素且不允許有重複元素(數學中的集合也是如此),List 是線性結構的容器,適用於按數
值索引訪問元素的情形。

76. Thread 類的 sleep()方法和對象的 wait()方法都可以讓線程暫停執行,它們有什 麼區別?

sleep()方法(休眠)是線程類(Thread)的靜態方法,調用此方法會讓當前線程暫停執行指定的
時間,將執行機會(CPU)讓給其他線程,但是對象的鎖依然保持,因此休眠時間結束後會自動恢
復。
wait()是 Object 類的方法,調用對象的 wait()方法導致當前線程放棄對象的鎖(線程暫停執行),
進入對象的等待池(wait pool),只有調用對象的 notify()方法(或 notifyAll()方法)時才能喚醒等待
池中的線程進入等鎖池(lock pool),如果線程重新獲得對象的鎖就可以進入就緒狀態。

77. 線程的 sleep()方法和 yield()方法有什麼區別?

① sleep()方法給其他線程運行機會時不考慮線程的優先級,因此會給低優先級的線程以運行的
機會;yield()方法只會給相同優先級或更高優先級的線程以運行的機會;
② 線程執行 sleep()方法後轉入阻塞(blocked)狀態,而執行 yield()方法後轉入就緒(ready)
狀態;
③ sleep()方法聲明拋出 InterruptedException,而 yield()方法沒有聲明任何異常;
④ sleep()方法比 yield()方法(跟操作系統 CPU 調度相關)具有更好的可移植性。

78. 請說出與線程同步以及線程調度相關的方法

  • wait():使一個線程處於等待(阻塞)狀態,並且釋放所持有的對象的鎖;
  • sleep():使一個正在運行的線程處於睡眠狀態,是一個靜態方法,調用此方法要處理
    InterruptedException 異常;
  • notify():喚醒一個處於等待狀態的線程,當然在調用此方法的時候,並不能確切的喚醒某一個
    等待狀態的線程,而是由 JVM 確定喚醒哪個線程,而且與優先級無關;
  • notityAll():喚醒所有處於等待狀態的線程,該方法並不是將對象的鎖給所有線程,而是讓它
    們競爭,只有獲得鎖的線程才能進入就緒狀態;

79. 舉例說明同步和異步。

同步:指發送一個請求,需要等待返回,然後才能夠發送下一個請求,有個等待過程,如果某個操
作非常耗時,則會使後續的功能處於等待狀態,產生假死/阻塞效果。
異步:指發送一個請求,不需要等待返回,隨時可以再發送下一個請求,即不需要等待。
區別:一個需要等待,一個不需要等待,在部分情況下,我們的項目開發中都會優先選擇不需
要等待的異步交互方式。銀行的轉賬系統,對數據庫的保存操作等等,都會使用同步交互操作,其
餘情況都優先使用異步交互。
Java 中的某個方法可以通過 Synchronized 關鍵字使其變爲同步,從而解決線程中的異步資源安
全問題。

80. Java 中如何實現序列化,有什麼意義?

Java 中將一個類實現 Serializable 接口(實際是空接口,起標識作用),則該類的對象就可以被
序列化。
序列化就是將類的對象進行流化,被流化後的對象可以在網絡中傳輸或者以文件的形式進行保
存,然後在需要的時候可以進行反序列化,將流化的對象還原爲原始對象,並且數據都保持原來的
狀態。具體操作是使用 writeObject()方法進行寫,然後使用時再通過 readObject()方法進行對象讀取
還原

81. 獲得一個類的類對象有哪些方式?

  • 方法 1:類型.class,例如:String.class
  • 方法 2:對象.getClass(),例如:”hello”.getClass()
  • 方法 3:Class.forName(),例如:Class.forName(“java.lang.String”)

82. 如何通過反射創建對象?

  • 方法 1:通過類對象調用 newInstance()方法,例如:String.class.newInstance()
  • 方法 2:通過類對象的 getConstructor()或 getDeclaredConstructor()方法獲得構造器(Constructor)
    對象並調用其 newInstance()方法創建對象,例如:
    String.class.getConstructor(String.class).newInstance(“Hello”);

83. Enumeration 接口和 Iterator 接口的區別有哪些?

Enumeration 速度是 Iterator 的 2 倍,同時佔用更少的內存。但是,Iterator 遠遠比 Enumeration
安全,因爲其他線程不能夠修改正在被 iterator 遍歷的集合裏面的對象。同時,Iterator 允許調用者刪
除底層集合裏面的元素,這對 Enumeration 來說是不可能的。

84. 串行(serial)收集器和吞吐量(throughput)收集器的區別是什麼?

吞吐量收集器使用並行版本的新生代垃圾收集器,它用於中等規模和大規模數據的應用程序。
而串行收集器對大多數的小應用(在現代處理器上需要大概 100M 左右的內存)就足夠了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章