天天看點

Java實習生正常技術面試題每日十題Java基礎(八)

目錄

1.解釋記憶體中的棧(stack)、堆(heap)和靜态區(static area)的用法。

2.怎樣将GB2312編碼的字元串轉換為ISO-8859-1編碼的字元串?

3.運作時異常與受檢異常有何異同?

4.列出一些你常見的運作時異常?

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

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

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

8.請說出與線程同步以及線程排程相關的方法。

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

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

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

12.如何通過反射建立對象?

13.Enumeration接口和Iterator接口的差別有哪些?

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

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

代碼如下所示:
String s1 = "你好";

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

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

- 不要将異常處理用于正常的控制流(設計良好的API不應該強迫它的調用者為了正常的控制流而使用異常)

- 對可以恢複的情況使用受檢異常,對程式設計錯誤使用運作時異常

- 避免不必要的使用受檢異常(可以通過一些狀态檢測手段來避免異常的發生)

- 優先使用标準的異常

- 每個方法抛出的異常都要有文檔

- 保持異常的原子性

- 不要在catch中忽略掉捕獲到的異常

ArithmeticException(算術異常)   5/0

ClassCastException (類轉換異常)

IllegalArgumentException (非法參數異常)

IndexOutOfBoundsException (下标越界異常)

NullPointerException (空指針異常)

SecurityException (安全異常)

NumberFormatException   (數字格式異常 Integer.parseInt(“a1b2”))

FileNotFoundException (檔案找不到異常)

ClassNotFoundException (類找不到異常)

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

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

① sleep()方法給其他線程運作機會時不考慮線程的優先級,是以會給低優先級的線程以運作的機會;yield()方法隻會給相同優先級或更高優先級的線程以運作的機會;

② 線程執行sleep()方法後轉入阻塞(blocked)狀态,而執行yield()方法後轉入就緒(ready)狀态;

③ sleep()方法聲明抛出InterruptedException,而yield()方法沒有聲明任何異常;

④ sleep()方法比yield()方法(跟作業系統CPU排程相關)具有更好的可移植性。

- wait():使一個線程處于等待(阻塞)狀态,并且釋放所持有的對象的鎖;

- sleep():使一個正在運作的線程處于睡眠狀态,是一個靜态方法,調用此方法要處理InterruptedException異常;

- notify():喚醒一個處于等待狀态的線程,當然在調用此方法的時候,并不能确切的喚醒某一個等待狀态的線程,而是由JVM确定喚醒哪個線程,而且與優先級無關;

- notityAll():喚醒所有處于等待狀态的線程,該方法并不是将對象的鎖給所有線程,而是讓它們競争,隻有獲得鎖的線程才能進入就緒狀态;

同步:指發送一個請求,需要等待傳回,然後才能夠發送下一個請求,有個等待過程,如果某個操作非常耗時,則會使後續的功能處于等待狀态,産生假死/阻塞效果。

異步:指發送一個請求,不需要等待傳回,随時可以再發送下一個請求,即不需要等待。 

差別:一個需要等待,一個不需要等待,在部分情況下,我們的項目開發中都會優先選擇不需要等待的異步互動方式。銀行的轉賬系統,對資料庫的儲存操作等等,都會使用同步互動操作,其餘情況都優先使用異步互動。

Java中的某個方法可以通過Synchronized關鍵字使其變為同步,進而解決線程中的異步資源安全問題。

Java中将一個類實作Serializable接口(實際是空接口,起辨別作用),則該類的對象就可以被序列化。
序列化就是将類的對象進行流化,被流化後的對象可以在網絡中傳輸或者以檔案的形式進行儲存,然後在需要的時候可以進行反序列化,将流化的對象還原為原始對象,并且資料都保持原來的狀态。具體操作是使用writeObject()方法進行寫,然後使用時再通過readObject()方法進行對象讀取還原。

- 方法1:類型.class,例如:String.class

- 方法2:對象.getClass(),例如:”hello”.getClass()

- 方法3:Class.forName(),例如:Class.forName(“java.lang.String”)

- 方法1:通過類對象調用newInstance()方法,例如:String.class.newInstance()

- 方法2:通過類對象的getConstructor()或getDeclaredConstructor()方法獲得構造器(Constructor)對象并調用其newInstance()方法建立對象,例如:

String.class.getConstructor(String.class).newInstance(“Hello”);           

Enumeration速度是Iterator的2倍,同時占用更少的記憶體。但是,Iterator遠遠比Enumeration安全,因為其他線程不能夠修改正在被iterator周遊的集合裡面的對象。同時,Iterator允許調用者删除底層集合裡面的元素,這對Enumeration來說是不可能的。

吞吐量收集器使用并行版本的新生代垃圾收集器,它用于中等規模和大規模資料的應用程式。

而串行收集器對大多數的小應用(在現代處理器上需要大概100M左右的記憶體)就足夠了。

其他面試題:

Java實習生正常技術面試題每日十題Java基礎(八)

Java實習生正常技術面試題每日十題Java基礎(七)

Java實習生正常技術面試題每日十題Java基礎(六)

Java實習生正常技術面試題每日十題Java基礎(五)

Java實習生正常技術面試題每日十題Java基礎(四)

Java實習生正常技術面試題每日十題Java基礎(三)

Java實習生正常技術面試題每日十題Java基礎(二)

Java實習生正常技術面試題每日十題Java基礎(一)

本文來自部落格園,作者:明金同學,轉載請注明原文連結:https://www.cnblogs.com/vmuu/p/15663291.html

公衆号:【明金同學】

繼續閱讀