JAVA面試寶典

引用變量與對象

A aa=new A();

這個最基本語句的含義是,使用new在heap中創建一個A類的對象,並把這個A類對象的引用賦值給aa,即aa本身不是A類的對象,而是A類對象的引用變量,也稱爲句柄,這點本質上和C++是一個意思。

JAVA字符串與常量池

(1)    常量池Constant Pool。由於JAVA中包含大量字符串,每個字符串都是一個對象,每個對象都要在heap中佔據空間,針對上述問題,JAVA爲了節省內容空間和提高運行時間,在編譯時將所有字符串文字放到常量池中,將所有相同的字符串常量進行合併,只佔用一個空間。

例如 String s1=”abc”; String s2=”abs”;那麼當進行s1==s2時,返回的是true,因爲在內存中s1和s2引用的是同一個副本。

此外,String類的intern()方法是直接與常量池交互的。即當調用intern()方法時,如果常量池中已經包含該字符串,則無需創建直接返回;否則再往常量池中增添此String對象。

(2)    String對象的創建。首先JAVA中任何一個字符串常量或者字符串文字都是一個String對象,即在JAVA中,使用雙引號本質上就是創建了一個JAVA對象。那麼,String s=new String(“abc”)其實是創建了兩個String對象,一個在常量池中,一個在Heap中。如果再加上String s2=new String(“abc”),那麼一共創建了三個JAVA對象。

(3)    JAVA中String類是非可變性的(immutable)。因爲從原理上講JAVA中是使用privatefinal char value[]的方式來實現字符串存儲的,因此String對象創建之後,就不能再修改此對象中存儲的字符串內容。由於同一對象的內容不允許修改,因此有效避免了不一致性的產生。例如String s=”a”; s+=”b”;上述寫法是需要避免的,因爲它開闢了兩個內存段,當執行第二句是其實另外創建了一個對象,而原來s指向的對象就成爲了垃圾。爲了解決這個問題,可以使用String的配套類StringBuffer。StringBuffer類對象的內容是可變的,像上面那個例子通過調用其append方法即可:StringBuffer sb=new StringBuffer(“a”); sb.append(“b”);

多態

         多態是面向對象中最重要的特性。

(1)    什麼是多態?首先形象地講,“如果它不是晚綁定,就不是多態”,即多態的本質是動態聯編,在運行時而不是編譯時進行函數綁定。其次講得技術點,多態是允許將子類類型的指針或者引用賦值給基類類型的指針或者引用,賦值之後,父對象就可以根據當前賦值給它的子對象的特性以不同的方式進行運作。

(2)    多態有什麼好處?多態最大的好處就是接口重用。因爲接口往往是一個公司最有價值的資源,接口的設計屬於架構設計,比用具體的類來實現這些接口更耗費時間和人力;此外,就如我說的,多態性的另一個重要作用是將接口與實現分開,改善代碼的組織結構,增強代碼可讀性。

(3)    JAVA與C++多態性的區別:在C++中,多態性是通過在基類中定義虛函數來實現的;在JAVA中,不需要定義虛函數,除了static和final方法外,其他所有方法都是在運行時綁定的,也就是說C++中的虛函數也就對應於JAVA中的普通函數,這也是JAVA解釋執行而不是編譯執行的體現。(注,由於private方法被隱式指定爲final的,因此在JAVA中實現多態時不要定義成private的了)

(4)    Override與Overload:Override是覆蓋,即子類重新定義父類虛函數的方法,用於實現多態;Overload是重載,即允許存在多個同名函數,只是這些函數的參數表不同而已,與多態性無關,在編譯時就可以確定。

(5)    虛函數表

JAVA抽象類

在JAVA中,是通過定義抽象類來實現多態的.如下面的例子,在抽象類中包含一個等着子類覆蓋實現的抽象函數(當然,極端情況下,抽象類也可以不定義抽象函數)

如abstract class base

{        publicabstract void myFunc();

         publicvoid print{“print”};

}

         在C++中,概念稍有不同:C++中沒有對抽象類進行聲明的方法,而是只要在類中定義了虛函數,那麼這個類就是抽象類,不需要顯式聲明。

Class base

{public:

Virtual void myFunc();

Void print(“print”);

}

         JAVA中抽象類與接口的異同:首先相同點是接口可以理解爲一種特殊的抽象類;不同點在於抽象類是用於繼承的,那麼體現出的是一種”is a”的概念;接口是用於實現的,那麼體現出的是一種”like a”的概念。此外,從語法上也有一點區別,在抽象類中還能定義其他非抽象的變量和方法,而在接口中則不能。詳見:http://www.enet.com.cn/article/2007/1126/A20071126923475.shtml

 

編譯執行與解釋執行

         總所周知,JAVA是解釋執行的,而C++是編譯執行的,那麼具體有什麼區別呢?

(1)    JAVA-編譯和解釋型語言   

 一個JAVA文件,首先會由JAVA編譯器(JAVAC)編譯成class(字節碼文件)文件,然後由Java虛擬機(JVM)去解釋。不同的操作系統只要裝有適合不同平臺的JDK,JAVA文件都可以被解釋運行。JAVA是一種編譯和解釋型語言。
       字節碼文件(class)之所以能夠被JAVA虛擬機(JVM)所解釋,最主要的原因就是字節碼文件(class)裏面所包含的內容是可以被JAVA虛擬機(JVM)所解釋的一種高度優化指令。而JAVA文件只需要編譯一次就可以在不同的操作系統上解釋運行,也就是說一次編譯處處運行,這就是JAVA可以跨平臺的原因。

(2)    C++-編譯型語言

       C++沒有虛擬機這種概念,也就是說C++一旦編譯就可以運行,是一種編譯型語言,速度上比JAVA快得多,C++編譯完成後是機器碼(二進制文件)可以直接在操作系統上運行。

(3)    C#-編譯再編譯型語言

       C#與一樣,同樣有虛擬機,但是他的虛擬機是CLR(公共語言運行時)。一個C#文件,首先會由C#編譯器編譯成低級別的中間語言IL,然後由C#虛擬機也就是公共語言運行時(CLR)即時編譯(JIT)編譯成機器代碼,再由CUP去執行它。所以說C#的執行必須通過二次編譯。

 

正則表達式

詳見http://deerchao.net/tutorials/regex/regex.htm

大括號{}用來表示重複的次數;中括號[]用來表示列舉

在JAVA中使用regex時,對於\要再進行一次轉義才行,例如\D就要寫成\\D才能編譯通過。

 

ACSII碼

大寫A的ASCII碼是65,小寫a的ASCII碼是97。

 

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