精心收集java基礎106條

Java基礎java

1、一個".java"源文件中是否能夠包括多個類(不是內部類)?有什麼限制?ios

一個Java源文件中能夠定義多個類,但最多隻能定義一個public的類,而且publicc++

類的類名必須與源文件名一致。一個文件中能夠只有非public類,並且這些類的類名能夠跟Java源文件名不一樣。例如一個Java源文件名中只定義了一個非publicMyClass,而源文件名爲Other.java,編譯後只會生成一個MyClass.class文件,不會生成Other.class文件。git

2Java有沒有goto?程序員

java中的保留字,如今沒有在java中使用。web

3、說說&&&的區別。 面試

&&&均可以用做邏輯與的運算符,&&爲短路與運算,&不是短路與運算。另外&能夠作爲整數的位運算符的與運算。例1:對於if(str != null && !str.equals(「」))表達式,當strnull時,後面的表達式不會執行,因此不會出現NullPointerException。若是將&&改成&,則會拋出NullPointerException異常。固然不建議這樣的寫法,應該寫爲if(str != null && ! 「」.equals(str)),例2If(x==33 &++y>0) y會增加,if(x==33 && ++y>0)不會增加正則表達式

4、在JAVA中如何跳出當前的多重嵌套循環?算法

1. Break + 標籤spring

2. 直接使用Break

3. 使用方法的return

Java中,要想跳出多重循環,能夠在外面的循環語句前定義一個標號,而後在裏

層循環體的代碼中使用帶有標號的break語句,便可跳出外層循環。例如,

ok: for (int i = 0; i < 10; i++) {

for (int j = 0; j < 10; j++) {

System.out.println("i=" + i + ",j=" + j);

if (j == 5)

break ok;

}

}

另外,可讓外層的循環條件表達式的結果能夠受到裏層循環體代碼的控制,例如,要在二維數組中查找到某個數字。

int arr[][] ={{1,2,3},{4,5,6,7},{9}};

boolean found = false;

for(int i=0;i<arr.length&& !found;i++) {

for(int j=0;j<arr[i].length;j++){

System.out.println("i=" + i + ",j=" + j);

if(arr[i][j]  ==5) {

found = true;

break;

}

}

}

第三種,使用方法的return

public static int test() {

int count = 0;

for (int i = 0; i < 10; i++) {

for (int j = 0; j < 10; j++) {

count++;

System.out.println("i=" + i + ",j=" + j);

if (j == 5) {

return count;

}

}

}

return 0;

}

5switch語句可否做用在byte上,可否做用在long上,可否做用在String?

做用在byteshortcharint,這四種基本類型的封裝類對象和枚舉,其它基本數據類型及引用數據類型都不能作爲case的條件。基本數據類型能夠這樣簡單記憶,能自動加寬到int類型的簡單類型和封裝類,再加一個enum類型。在JDK 7之後,String類型也能夠作爲switchcase條件。

6short s1 = 1; s1 = s1 + 1; 有什麼錯? short s1 = 1; s1 += 1; 有什麼錯?

對於short s1 = 1; s1 = s1 + 1; 因爲s1+1運算時會自動提高表達式的類型,由於s1short類型,1int類型,因此結果自動提高爲int型,再賦值給short類型s1時,編譯器將報告須要強制轉換類型的錯誤。對於short s1 = 1; s1 += 1; 由於 += java語言的內置的運算符,是一種特殊的運算,不會有編譯錯誤,不會出錯。

7char型變量中能不能存貯一箇中文漢字?爲何?

char型變量是用來存儲Unicode編碼的字符的,Unicode編碼字符集中包含了漢字。

補充說明:Unicode編碼佔用兩個字節,所以Javachar類型的變量也是佔用兩個字節。

其它補充:

基本類型 長度(字節) 範圍

Byte 1 -128 ~ 127

Short 2 -32768 ~ 32767

Int 4 -2147483648 ~ 2147483647

Long 8 -9223372036854775808 ~ 9223372036854775807

Float 4 -3.4E38 ~ 3.4E38 

Double 8 -1.7E308~1.7E308

Char 2 0~65535

boolean 1 true, false

8、用最有效率的方法算出2乘以8等於幾?

2 << 3。由於2 * 8 = 2 * 2 ^ 3 = 2 << 3,採用位運算能夠提升計算機的運行效率,一個數乘以2n次方,就能夠使用移位運算左移n位。同時若是一個數除以2n次方,就能夠使用移位運算向可移動n位。位運算是CPU直接支持的,效率很是高。

9、請設計一個一百億的計算器

設計一個百億計算器,是一件很是麻煩的事情,由於百億已經超出了int類型的最大值(2147483647,即21.5億),long值會出現科學計算法的表示,也不太適合直接作這個計算器,須要使用把數字切分紅多段,分別進行計算和加合,段與段之間的運算可能會出現越界,須要進行特殊處理,加減法運算相對容易,乘除法就很是困

難了,再加上浮點數運算,更是難上加難。

10、使用final關鍵字修飾一個變量時,是引用不能變,仍是引用的對象不能變?

引用變量不能從新賦值,可是引用指向的對象的內容能夠改變

1

final StringBuffer a=new StringBuffer("test");

a=new StringBuffer("  ");

有編譯錯

2

final StringBuffer a=new StringBuffer("test");

a.append(123);

正確

3

有些人想要在傳參時,防止參數值發生變化,如下作法是錯誤的:

public void test(final StringBuffer buffer) {  }

可是這是作不到的,由於buffer的值是能夠改變的,方法體中能夠使用 buffer.append(test)

11"=="equals方法究竟有什麼區別?

他們的區別主要存在在引用數據類型上==’爲比較兩側的對象是否同一對象,是用內存地址來比較的‘equals’是對象的方法,默認是用內存地址比較,重寫後,主要是用來比較兩側的對象的值是否相同,和equals方法中的實現有關==是運算符,能夠兩側都爲null,但equals左側的引用指向的對象不能空,否則有NullPointerException除非須要比較兩個引用指向的對象是同一對象,通常都使用equals方法進行比較。尤爲是String之類的值對象,另外,常量儘可能放在比較的左側

12、靜態變量和實例變量的區別?

在語法定義上的區別:靜態變量前要加static關鍵字,而實例變量前則不加。

在程序運行時的區別:實例變量屬於某個對象的屬性,必須建立了實例對象,其中的實例變量纔會被分配空間,才能使用這個實例變量。靜態變量不屬於某個實例對象,而是屬於類,因此也稱爲類變量,只要程序加載了類的字節碼,不用建立任何實例對象,靜態變量就會被分配空間,靜態變量就能夠被使用了。總之,實例變量必須建立對象後才能夠經過這個對象來使用,靜態變量則能夠直接使用類名來引用。

13、是否能夠從一個static方法內部發出對非static方法的調用?

不能夠。非static方法即實例對象方法,是屬於某個對象的,必須在對象被建立後才能被調用,成員方法的內部其實隱藏着一個this引用;而static方法是屬於類對象的,不屬於實例對象,所以static方法在執行時,不能得到當前對象的this引用,從而不能直接調用實例對象的方法。

14Integerint的區別

intjava提供的8種原始數據類型之一,佔用4個字節,直接存值;Integer是引用數據類型,是int的封裝類。

1. 默認值:int的默認值爲0Integer的默認值爲null。例如考試成績爲0,表示參加了考試,但成績爲0分,但null意味未參加考試。

2. JSP開發中,Integer的默認值爲null, EL表達式時,文本框顯示的值爲空白;若是使用int默認值爲0,文本框顯示的值是0int不適合在展現層使用。

3. Hibernate中,若是將自增ID字段設置成Integer類型,若是值爲null,則表示臨時對象,保存時,會自動升成ID值。而使用int類型,則須要在hbm映射文件中,設置unsaved-value屬性的值爲0

4. Integer提供了許多跟整數運算相關的操做方法,例如與字符串的轉換,還定了一些整數的最大值和最小值的轉換。

15Math.round(11.5)等於多少? Math.round(-11.5)等於多少?

Math.round(11.5)的結果爲12Math.round(-11.5)的結果爲-11

Math類提供了三個與取整有關的方法:ceilfloorround

方法名 英文意思 功能           示例

ceil     天花板   向上取整 ceil(11.5)=12; ceil(-11.5)=-11

floor     地板   向下取整 floor(11.5)=11; cell(-11.5)=-12

round 圓形   四捨五入 Round(11.5)=12; round(-11.5)=-11

16、下面的代碼有什麼不妥之處?

  1. if(username.equals(xyz){}

 username可能爲null,會報空指針錯誤;改成"xyz".equals(username)

  2. int x = 1;

 return x==1?true:false;  這個改爲return x==1;就能夠!

17、請說出做用域publicprivateprotected,以及不寫時的區別

不寫修飾符也是一種特殊的修飾符,在java中叫作默認修飾符、default修飾符或friendly修飾符,只是說法不一樣。

修飾符的做用範圍:

        private  default  protected    public

同一個類中      能夠  能夠   能夠    能夠

同一個包的類中      能夠     能夠    能夠

不一樣包的子類中           能夠      能夠

不一樣包的類中                能夠

從以上表中數據能夠看出,訪問權限的範圍自下向上依次增大。特別強調一點,protected修飾符,在同一包內,即便兩個類沒有繼承關係,依然能夠互相訪問其protected成員屬性和成員方法。

18OverloadOverride的區別。Overloaded的方法是否能夠改變返回值的類型?

Overload是重載的意思,Override是覆蓋的意思,也就是重寫。

OverloadOverride有共同之處,兩個方法的方法名都必須相同,若是不一樣,既不構成Overload,也不構成Override

1.Override必須發生在父子類之間,Overload能夠不在父子類之間

2.Override的特色:

a)參數列表徹底相同:個數相同、類型相同、順序相同

b)子類的返回值不能比父類的返回值範圍大

c)子類方法拋出的異常不能比父類方法拋出的異常範圍大

d)修飾符只能爲publicprotectedfriendly,不能爲private

e)父子類方法不能使用static修飾

3.重載發生在同一個類或父子類之間,重載中參數列表至少知足個數不一樣、類型不一樣、順序不一樣中的一個條件,不包含父子類之間的static方法

19、構造器Constructor是否可被override?

構造器不能被重寫Override,但能夠被重載Overload。若是類沒有顯示定義構造器,此類也會有一個系統默認的無參構造器,只是方法體是空的。

20、接口是否可繼承接口?抽象類是否可實現(implements)接口?抽象類是否可繼承具體類(concrete class)?抽象類中是否能夠有靜態的main方法?抽象類是否可有之內部類?接口是否能夠有內部類?

接口能夠繼承接口;抽象類能夠實現(implements)接口;抽象類能夠繼承具體類;抽象類中能夠有靜態的main方法;抽象類可有之內部類;接口能夠有內部類,但必須是static內部類,但不必定是final的。

抽象類與普通類的區別有如下兩點:

1. 不能建立實例對象

2. 容許有abstract方法

抽象類再補充幾點:

1. 抽象類能夠沒有抽象方法

2. 抽象類能夠只有私有構造器

3. 抽象類的修飾符不能使用final

接口補充幾點:

1. 能夠沒有任何抽象方法

2. 接口能夠有屬性,但必須是public static final類型的

3. 接口中能夠定義內部類,但內部類必須是public static類型的(能夠是抽象類,

不要求是final類型的)

4. 接口類定義不能使用final修飾符

5. 接口類都是abstract的,即便定義類時,沒有顯示聲明

21、寫clone()方法時,一般都有一行代碼(不是必須有),是什麼?

答案:super.clone()

super.clone()是淺度克隆,只是把原對象的對象屬性的引用複製一份,基本數據類型的屬性是徹底複製的。

要想深度clone,就須要把對象中的引用類型的屬性遞歸複製。

22、面向對象的特徵有哪些方面

1. 封裝,隱藏內部實現,只暴露公共行爲

2. 繼承,提升代碼的重用性

3. 多態,體現現實生活中類似對象的差別性

4. 抽象,抽取現實世界中類似對象的共同點

23java中實現多態的機制是什麼?

Java中經過繼承父類或實現接口,實現多態的機機制。

繼承指子類繼承父類的全部屬性、方法、內部類。對於屬性而言,若是子類的屬性名和父類的屬性名相同,則子類會把父類的屬性隱藏。屬性根據引用來調用,方法根據對象來調用; Java中只有單繼承,一個子類只能直接繼承一個父類。實現指某類能夠實現接口中的部分或全部方法,並能繼承接口中的全部的屬性和內部類。接口中的屬性都爲public static final類型,方法都爲public類型,內部類都爲public static類型。接口能夠繼承多個接口,實現類能夠實現多個接口。

24abstract classinterface有什麼區別?

使用abstract修飾符的class爲抽象類,abstract類不能建立的實例對象。

接口(interface)是一種特殊的類,使用interface關鍵字進行修飾。

下面比較一下二者的語法區別:

1. 抽象類能夠有構造方法,接口中不能有構造方法;

2. 抽象類中能夠有普通成員屬性,接口中沒有普通成員屬性;

3. 抽象類中能夠包含非抽象的普通方法,接口中的全部方法必須都是抽象的,不能

有非抽象的普通方法;

4. 抽象類中的抽象方法的訪問類型能夠是publicprotected和默認類型,但接口中的抽象方法只能是public類型的,而且默認即爲public abstract類型;

5. 抽象類中能夠包含靜態方法,接口中不能包含靜態方法;

6. 抽象類和接口中均可以包含靜態成員變量,抽象類中的靜態成員變量的訪問類型能夠任意,但接口中定義的變量只能是public static final類型,而且默認即爲public static final類型;

7. 一個類能夠實現多個接口,但只能繼承一個抽象類;

8. 在應用上也有區別,接口更多的是在系統架構設計方法發揮做用,主要用於定義模塊之間的通訊契約;而抽象類在代碼實現方面發揮做用,能夠實現代碼的重用

25abstractmethod是否可同時是static,是否可同時是native,是否可同時是synchronized,是否可同時是final?

1. abstractmethod不能夠同時是static的,由於abstract方法是抽象的方法,不能有方法體,是要被子類實現的,而static方法必須有方法體,二者不能在方法上共用。

2. abstractmethod不能夠同時是native的,native方法表示該方法要用另一種依賴平臺的編程語言實現的,實際上是有實現的,只是否是Java代碼實現的,因此,它也不能是抽象的,不能與abstract混用。另外native方法能夠被子類重寫,例如hashCode方法。

3. abstractmethod不能夠同時是synchronized的,abstract方法只能存在於抽象類或接口中,它不能直接產生對象,而默認synchronized方法對當前對象加鎖,而abstract方法只能被子類繼承,synchronized不能被繼承,抽象方法使用synchronized,沒有意思,所以Java不容許抽象方法使用synchronized修飾;synchronized 能夠修飾構造器,但一個對象的構造器不可能同時被多個線程調用,這個也是多餘的,可是Java不報錯,應該是一個BUG

4. abstractmethod不能夠同時是final的,由於抽象方法目的是讓子類實現,而final方法是不讓子類重寫,再者從根本上是衝突的,不能夠共用。

26、什麼是內部類?Static Nested ClassInner Class的不一樣。

內部類就是在一個類的內部定義的類。內部能夠定義在除參數位置上的任意位置。

1. 靜態內部類須要使用static修飾,而普通內部類不能使用static修飾

2. 靜態內部類只能定義在和屬性同級,普通內部類能夠定義在除參數位置之外的任意位置

3. 靜態內部類必需有名稱,而普通內部類能夠是匿名的

4. 靜態內部類沒有this引用,只此只能訪問外部類的靜態成員,而普通內部類能夠訪問外部類的所有成員

5. 靜態內部類訪問外部類的同名函數時,使用「外部類名.方法名」便可,而普通內部類須要使用「外部類名.this.外部方法」

6. 靜態內部類能夠定義靜態方法,而普通內部類不能定義靜態方法,但能定義簡單數據類型的靜態屬性,不能定義引用類型的靜態屬性。

7. 建立靜態內部類的對象的時候,能夠直接new 靜態內部類名;建立普通內部類的時候,須要先建立外部類的對象,再使用外部類的對象名.new 內部類的類名,例如:object.new MyClass()

27、內部類能夠引用它的包含類的成員嗎?有沒有什麼限制?

1. 若是內部類爲靜態內部類,只能調用外部類的靜態成員;若是有重名成員,須要用「外部類名.成員名」訪問;不能調用外部類的對象成員。

2. 若是內部類爲非靜態內部類,則能夠調用外部類的全部成員;若是有重名成員,須要使用「外部類名.this.成員名」

28Anonymous Inner Class (匿名內部類)是否能夠extends(繼承)其它類,是否能夠implements(實現)interface(接口)?

匿名內部類能夠繼承其它類,也能夠實現接口,但不能顯示使用extendsimplements關鍵字。例如:

繼承其它類的:

Thread thread = new Thread() {

   public void run() {

   }

};

實現接口的:

Runnable runnable = new Runnable() {

   public void run() {

   }

};

29super.getClass()方法和this.getClass()方法返回對象是否相同?

返回的Class對象是同一對象,都是子類的對象。final方法,不容許重寫。想得一個對象的父類對象的引用能夠使用object.getClass().getSuperClass()方法。

30String是最基本的數據類型嗎?

基本數據類型包括byteintcharlongfloatdoublebooleanshort

String是引用數據類型,它的類全名是:java.lang.String,是final類型,且這個類是不可變類,對象被建立後,只能讀取不能改寫,是線程安全的。字符串的拼接運算能夠使用「+」,但結果是新字符串。爲了提升字符串的拼接運算效率,咱們經常使用StringBufferStringBuilder類。

31String s = "Hello";s = s + " world!";這兩行代碼執行後,原始的String對象中的內容到底變了沒有?

沒有,String類爲不可變量,對象被建立後,只能讀,不改修改,s = s+ " world!"是裝引用s指向了一個新的字符串"Hello world!"

s = s+ " world!"JDK1.5之前版本至關於:s = new StringBuffer(String.valueOf(s)).append(" world!").toString();

s = s+ " world!"JDK1.5及之後版本至關於:s = new StringBuilder(String.valueOf(s)).append(" world!").toString();

32、是否能夠繼承String?

String類是final類故不能夠繼承,並且String爲不可變量,只能讀不能修改。

補充:

經常使用的值類大都爲final類,例如:ByteCharacterShortIntegerLongFloatDoubleBooleanStringStringBufferStringBuilder,但DateBigIntegerBigDecimal都是非final類,但原則上儘可能不繼承這些類。

33String s = new String("xyz");建立了幾個String Object?兩者之間有什麼區別?

兩個對象。一個是"xyz",爲緩衝區對象。另外一個是new出來的String對象。這兩個對象的值相同,但不是同一個對象。

補充,新建對象有幾種方式?

1. 使用new關鍵字

2. 使用反射,調用newInstance

3. 使用clone方法

4. 使用序列化與反序列化

5. 動態代理(Proxy類和CGLIB)

補充例題1

String aaa = "aaa";

String bbb = "bbb";

String aaabbb = "aaabbb";

System.out.println("aaa"+"bbb"=="aaabbb"); // true

System.out.println("aaa"+"bbb"==aaa+bbb); // false

System.out.println("aaa"+"bbb"==aaabbb); // true

System.out.println("aaa"+bbb=="aaabbb"); // false

System.out.println("aaa"+bbb==aaabbb); // false

System.out.println(aaa+bbb=="aaabbb"); // false

System.out.println(aaa+bbb==aaabbb); // false

System.out.println("aaa"+"bbb"==aaabbb.intern()); // true

補充例題2

final String aaa = "aaa";

final String bbb = "bbb";

String aaabbb = "aaabbb";

System.out.println("aaa"+"bbb"=="aaabbb"); // true

System.out.println("aaa"+"bbb"==aaa+bbb); // true

System.out.println("aaa"+"bbb"==aaabbb); // true

System.out.println("aaa"+bbb=="aaabbb"); // true

System.out.println("aaa"+bbb==aaabbb); // true

System.out.println(aaa+bbb=="aaabbb"); // true

System.out.println(aaa+bbb==aaabbb); // true

System.out.println("aaa"+"bbb"==aaabbb.intern()); // true

這兩個例子顯示了字符串相加產生多少個對象的結果,緣由是JVM對字符串相加進行了特殊的優化處理。在第一個例子中:"aaa"+"bbb"+號兩側的值都是字符串常量,所以結果也必然是字符串常量,所以編譯時能夠優化爲"aaabbb",和=號右側的字符串相同,結果都放在了字符串的常量池,是同一對象。在第一個例子中,aaabbb兩個變量不是final類型,所以當"aaa"+bbbJVM編譯時,不能肯定bbb的值是否在運行時沒有被改變過,所以不能進行優化,在運行到此句時,會產生一個新的"aaabbb"字符串對象,而不是池中的字符串對象,獲得false。在第二個例子中,aaabbb兩個變量都是final類型,所以當"aaa"+bbbJVM編譯時,能肯定bbb的值,所以能夠在編譯期進行優化,獲得池中的字符串"aaabbb",所以結果爲true

34StringStringBuffer的區別

這兩個類都實現了CharSequence接口。

1. 類型不一樣,由於不是一個類,也沒有繼承關係,作參數時不能共用

2. String對象是不可變對象,不能修改值。而StringBuffer是可變對象,能修改值。

3. 拼接字符串時,String會產生新對象,而StringBuffer只是增長新字符,不產生新對象,所以效率高。

4. String覆蓋了equals方法和hashCode方法,而StringBuffer沒有覆蓋equals方法和hashCode方法,因此,將StringBuffer對象存儲進Java集合類中時會出現問題。

34.1StringBufferStringBuilder的區別

相同之處,這兩類都是可變長的字符串存儲類,都實現了CharSequence接口

1. 類型不一樣,由於不是一個類,也沒有繼承關係,作參數時不能共用

2. StringBuffer爲線程安全類,StringBuilder爲線程非安全類

3. StringBuffer性能低,StringBuilder性能高,若是在局部優先使用StringBuilder

4. JDK1.5以前,字符串相加使用StringBuffer對象,在1.5以後使用StringBuilder對象

35、如何把一段逗號分割的字符串轉換成一個數組?

1.用正則表達式,代碼大概爲:String [] result = orgStr.split(,, -1);

2.StingTokenizer ,代碼爲:

StringTokenizer tokener = new StringTokenizer(s, ",");

String[] result = new String[tokener.countTokens()];

Integer i = 0;

while (tokener.hasMoreTokens()) {

result[i++] = tokener.nextToken();

}

3.最笨的辦法,用String.indexOf()

int index = -1;

int oldIndex = 0;

List<String> ss = new ArrayList<String>();

while ((index = s.indexOf(',', index + 1)) != -1) {

ss.add(s.substring(oldIndex, index));

oldIndex = index + 1;

}

if (s.charAt(s.length() - 1) == ',') {

ss.add("");

}

String[] array = ss.toArray(new String[ss.size()]);

System.out.println(Arrays.toString(array));

36、數組有沒有length()這個方法? String有沒有length()這個方法?JS的數組有沒有length()方法?JS的字符串有沒有length()方法?

數組沒有length()這個方法,有length的屬性。String有有length()這個方法。JS中只有length屬性,沒有length方法。

37、下面這條語句一共建立了多少個對象:String s="a"+"b"+"c"+"d";

答:產生了一個對象,即"abcd"

對於以下代碼:

String s1 = "a";

String s2 = s1 + "b";

String s3 = "a" + "b";

System.out.println(s2 == "ab"); // false

System.out.println(s3 == "ab"); // true

String s = "a" + "b" + "c" + "d";

System.out.println(s == "abcd"); // true s被優化爲」abcd

38try {}裏有一個return語句,那麼緊跟在這個try後的finally {}裏的code會不會被執行,何時被執行,在return前仍是後?

也許你的答案是在return以前,但往更細地說,個人答案是在return中間執行,請看下面程序代碼的運行結果:

public class Test {

public static void main(String[] args) {

System.out.println(test());

}

 

static int test() {

       int x = 1;

       try {

           return x;

       }

       finally {

           ++x;

       }

    }

}

 ---------執行結果 ---------

1

運行結果是1,爲何呢?主函數調用子函數並獲得結果的過程,比如主函數準備一個空罐子,當子函數要返回結果時,先把結果放在罐子裏,而後再將程序邏輯返回到主函數。所謂返回,就是子函數說,我不運行了,你主函數繼續運行吧,這沒什麼結果可言,結果是在說這話以前放進罐子裏的。

39、下面的程序代碼輸出的結果是多少?

public class SmallT {

public static void main(String args[]) {

SmallT t = new SmallT();

int b = t.get();

System.out.println(b);

}

public int get() {

try {

return 1;

} finally {

return 2;

}

}

}

返回的結果是2

我能夠經過下面一個例子程序來幫助我解釋這個答案,從下面例子的運行結果中可

以發現,try中的return語句調用的函數先於finally中調用的函數執行,也就是說return語句先執行,finally語句後執行,因此,返回的結果是2Return並非讓函數立刻返回,而是return語句執行後,將把返回結果放置進函數棧中,此時函數並非立刻返回,它要執行finally語句後才真正開始返回。

在講解答案時能夠用下面的程序來幫助分析:

public class Test {

 

public static void main(String[] args) {

System.out.println(newTest().test());

}

 

int test() {

try {

return func1();

} finally {

return func2();

}

}

 

int func1() {

System.out.println("func1");

return 1;

}

 

int func2() {

System.out.println("func2");

return 2;

}

}

-----------執行結果-----------------

func1

func2

2

結論:finally中的代碼比returnbreak語句後執行

40final, finally, finalize的區別。

final 用於聲明屬性,方法和類,分別表示屬性不可變,方法不可覆蓋,類不可繼承。

內部類要訪問局部變量,局部變量必須定義成final類型

final int[] number = { 20 };

new Thread() {

@Override

public void run() {

for (int k = 0; k < 20; k++) {

number[0]++;

}

}

}.start();

Thread.sleep(10);

System.out.println(number[0]);

finally是異常處理語句結構的一部分,表示老是執行,用來釋放資源。finalizeObject類的一個方法,在垃圾收集器執行的時候會調用被回收對象的此方法,能夠覆蓋此方法提供垃圾收集時的其餘資源回收,例如關閉文件等。JVM不保證此方法總被調用.

41、運行時異常(Runtime)與檢查異常(Checked)有何異同?

異常表示程序運行過程當中可能出現的非正常狀態,運行時異常表示虛擬機的一般操做中可能遇到的異常,是一種常見運行錯誤。java編譯器要求方法必須聲明拋出可能發生的非運行時異常,可是並不要求必須聲明拋出未被捕獲的運行時異常。運行時異常爲編程時的異常,應該在生產環境正常運行狀態下不會發生的異常檢查異常一般爲一種設計模式,表示某處執行時可能由於條件不足而出現異常,程序必須對此進行處理,JVM會提示編程人員捕獲或從新拋出異常

42errorexception有什麼區別?

error 表示恢復不是不可能但很困難的狀況下的一種嚴重問題。好比說內存溢出,不可能期望程序能處理這樣的狀況。exception表示一種設計或實現問題,也就是說,它表示若是程序運行正常,正常狀況下從不會發生的狀況。

43Java中的異常處理機制的簡單原理和應用。

異常是指java程序運行時(非編譯)所發生的非正常狀況或錯誤。

Java使用面向對象的方式來處理異常,它把程序中發生的每一個異常也都分別封裝到一個對象中,該對象中包含有異常的信息。

Java能夠自定義異常類,全部異常的根類爲java.lang.ThrowableThrowable下面又派生了兩個子類:ErrorException

1.Error表示應用程序自己沒法克服和恢復的一種嚴重問題,程序只有退的份了,例如說內存溢出和線程死鎖等系統問題。

2.Exception表示程序還可以克服和恢復的問題,其中又分爲運行時異常和檢查異常,運行時異常是軟件自己缺陷所致使的問題,也就是軟件開發人員考慮不周所致使的問題,軟件使用者沒法克服和恢復這種問題,但在這種問題下還可讓軟件系統繼續運行或者讓軟件死掉。例如,數組越界(ArrayIndexOutOfBoundsException),空指針異常(NullPointerException)、類轉換異常(ClassCastException);檢查異常是運行環境的變化或異常所致使的問題,是用戶可以克服的問題,例如,網絡斷線,硬盤空間不夠,發生這樣的異常後,程序不該該死掉。

Java爲運行時異常和檢查異常提供了不一樣的解決方案,編譯器強制檢查異常必須try..catch處理或用throws聲明繼續拋給上層調用方法處理,因此檢查異常也稱爲checked異常,而運行異常能夠處理也能夠不處理,因此編譯器不強制用try..catch處理或用throws聲明,因此運行異常也稱爲Runtime異常。

44、請寫出你最多見到的5RuntimeException

NullPointerExceptionArrayIndexOutOfBoundsExceptionClassCastExceptionIllegelArgumentExceptionSecurityException

45Java語言如何進行異常處理,關鍵字:throws,throw,try,catch,finally分別表明什麼意義?在try塊中能夠拋出異常嗎?

1.Java語言如何進行異常處理見43

2.throws爲向上拋異常,當前方法沒法處理此異常,須要上層方法進行處理throw程序出錯時,手工拋出異常,最好能把異常進行堆棧式拋出try嘗試執行,裏面的語句可能出現異常,如出現異常須要處理catch處理try中出現的異常finallytry後執行清理操做,用於釋放資源

3.try中能夠拋出異常

46Java中有幾種方法能夠實現一個線程?用什麼關鍵字修飾同步方法? stop()suspend()方法爲什麼不推薦使用?

java5之前,有以下兩種:

第一種:

new Thread(){}.start();這表示調用Thread子類對象的run方法,new Thread(){}表示一個Thread的匿名子類的實例對象,子類加上run方法後的代碼以下:

new Thread() {

public void run() {

}

}.start();

第二種:

new Thread(new Runnable(){}).start();這表示調用Thread對象接受的Runnable對象的run方法,new Runnable(){}表示一個Runnable的匿名子類的實例對象,runnable的子類加上run方法後的代碼以下:

new Thread(new Runnable() {

public void run() {

}

}).start();

Java5開始,還有以下一些線程池建立多線程的方式:

ExecutorService pool = Executors.newFixedThreadPool(3);

for (int i = 0; i < 10; i++) {

pool.execute(new Runable() {

public void run() {

}

});

}

Executors.newCachedThreadPool().execute(new Runable() {

public void run() {

}

});

Executors.newSingleThreadExecutor().execute(new Runable() {

public void run() {

}

});

有兩種實現方法,分別使用new Thread()new Thread(runnable)形式,第一種直接調用threadrun方法,因此,咱們每每使用Thread子類,即new SubThread()。第二種調用runnablerun方法。

1.有兩種實現方法,分別是繼承Thread類與實現Runnable接口。能夠的話使用線程池

2.synchronized關鍵字修飾同步方法

3.反對使用stop(),是由於它不安全。它會解除由線程獲取的全部鎖定,並且若是對象處於一種不連貫狀態,那麼其餘線程能在那種狀態下檢查和修改它們。結果很難檢查出真正的問題所在。suspend()方法容易發生死鎖。調用suspend()的時候,目標線程會停下來,但卻仍然持有在這以前得到的鎖定。此時,其餘任何線程都不能訪問鎖定的資源,除非被"掛起"的線程恢復運行。對任何線程來講,若是它們想恢復目標線程,同時又試圖使用任何一個鎖定的資源,就會形成死鎖。因此不該該使用suspend(),而應在本身的Thread類中置入一個標誌,指出線程應該活動仍是掛起。若標誌指出線程應該掛起,便用wait()命其進入等待狀態。若標誌指出線程應當恢復,則用一個notify()從新啓動線程。

47sleep()wait()有什麼區別?

1. sleep是在Thread類定義的,wait是在Object類定義的

2. sleep有兩個重載方法,wait有三個重載方法

3. sleep能自動喚醒,wait有參數的方法能自動喚醒,但無參數的重載方法不能自動喚醒,須要使用notify/notifyAll進行手動喚醒

4. sleep掛起時,不釋放鎖資源,wait掛起時,會釋放鎖資源

5. sleep調用時,不須要放在synchronized內,wait須要放在synchronized

6. sleep通常不會產生死鎖,可是wait可能會產生死鎖

48、同步和異步有何異同,在什麼狀況下分別使用他們?舉例說明。

同步是指全部操做串行化執行,順序不能改變,前一操做未完成,後個操做不執行。

異步是指全部操做能夠並行執行,順序無關。

例如寄信

同步:若是沒有寄完,不能吃飯,郵遞員10天后送到,發送人被餓死

異步:寄出後能夠當即吃飯,郵遞員送完後,通知發送人送信結果。

若是強調執行順序的話,用同步。若是順序無關,則能夠用異步。

異步執行效率比同步高。該用同步時,若是用了異步,結果可能會出現不一致。

49、多線程有幾種實現方法?同步有幾種實現方法?

多線程有兩種實現方法,分別是繼承Thread類與實現Runnable接口

同步的實現方面有五種,分別是synchronizedwaitnotifysleepsuspendjoinsynchronized: 一直持有鎖,直至執行結束

wait():使一個線程處於等待狀態,而且釋放所持有的對象的lock,需捕獲異常。

sleep():使一個正在運行的線程處於睡眠狀態,是一個靜態方法,需捕獲異常,不釋放鎖。

notify():喚醒一個處於等待狀態的線程,注意的是在調用此方法的時候,並不能確切的喚醒某一個等待狀態的線程,而是由JVM肯定喚醒哪一個線程,並且不是按優先級。

notityAll():喚醒全部處入等待狀態的線程,注意並非給全部喚醒線程一個對象的鎖,而是讓它們競爭。

50、啓動一個線程是用run()仍是start()?

啓動一個線程是調用start()方法,使線程就緒狀態,之後能夠被調度爲運行狀態,一個線程必須關聯一些具體的執行代碼,run()方法是該線程所關聯的執行代碼。

51、當一個線程進入一個對象的一個synchronized方法後,其它線程是否可進入此對象的其它方法?

若是其它方法中使用當前對象做爲鎖對象,則不能;

若是其它方法中沒有使用當前對象做爲鎖對象,則能。

52、線程的基本概念、線程的基本狀態以及狀態之間的關係

在多任務操做系統中,爲了提升CPU的利用率,能夠使用多進程編程。但對進程通訊比較困難,進程間數據不能共享,所以能夠使用多線程編程。一個進程至少包含一個主入口線程。單個CPU,在同一時間只能處理一個線程的數據,可是操做系統的任務調度很是快,人眼沒法識別,感受上是多個線程同時執行。有的線程能夠已經用完CPU,正在做磁盤操做,此時並不使用CPU,可讓出CPU資源給其它線程使用,提升效率。線程有生命週期及相關關係和對應方法見46題。

54、簡述synchronizedjava.util.concurrent.locks.Lock的異同?

主要相同點:Lock能完成synchronized所實現的全部功能

主要不一樣點:

1.更好的語義

2.更高性能

3.synchronized自動釋放鎖,Lock手動釋放,而且必須在finally從句中釋放。

4.功能強大,能夠用tryLock方法能夠非阻塞方式去拿鎖

舉例說明(對下面的題用lock進行了改寫):

package com.huawei.interview;

 

import java.util.concurrent.locks.Lock;

import java.util.concurrent.locks.ReentrantLock;

 

public class ThreadTest {

 

private int j;

private Lock lock = newReentrantLock();

 

public static void main(String[] args) {

ThreadTest tt = new ThreadTest();

for (int i = 0; i < 2; i++) {

new Thread(tt.new Adder()).start();

new Thread(tt.new Subtractor()).start();

}

}

 

private class Subtractor implements Runnable {

 

@Override

public void run() {

while (true) {

lock.lock();

try {

System.out.println("j--=" + j--);

} finally {

lock.unlock();

}

}

}

 

}

 

private class Adder implements Runnable {

 

@Override

public void run() {

while (true) {

lock.lock();

try {

System.out.println("j++=" + j++);

} finally {

lock.unlock();

}

}

}

}

}

55、設計4個線程,其中兩個線程每次對j增長1,另外兩個線程對j每次減小1。寫出程序。

如下程序使用內部類實現線程,對j增減的時候沒有考慮順序問題。

public class ThreadTest1 {

private int j;

 

public static void main(String args[]) {

ThreadTest1 tt = new ThreadTest1();

Inc inc = tt.new Inc();

Dec dec = tt.new Dec();

for (inti = 0; i < 2; i++) {

Thread t = new Thread(inc);

t.start();

t = new Thread(dec);

t.start();

}

}

 

private synchronized void inc() {

j++;

System.out.println(Thread.currentThread().getName() + "-

 

inc:" + j);

}

 

private synchronized void dec() {

j--;

   System.out.println(Thread.currentThread().getName()+"-

 

dec:"+j);

}

 

class Inc implements Runnable {

public void run() {

for (inti = 0; i < 100; i++) {

inc();

}

}

}

 

class Dec implements Runnable {

public void run() {

for (inti = 0; i < 100; i++) {

dec();

}

}

}

}

56、子線程循環10次,接着主線程循環100,接着又回到子線程循環10次,接着再回到主線程又循環100,如此循環50次,請寫出程序。

public class ThreadTest {

 

public static void main(String[] args) throws Exception {

for (int i = 0; i < 50; i++) {

MainThread main = new MainThread();

main.start();

main.join();

}

}

}

 

class MainThread extends Thread {

 

@Override

public void run() {

SubThread sub = new SubThread();

sub.start();

try {

sub.join();

} catch (InterruptedException e) {

// LOG

}

for (int i = 0; i < 100; i++) {

System.out.println("main: " + i);

}

}

}

 

class SubThread extends Thread {

 

@Override

public void run() {

for (int i = 0; i < 10; i++) {

System.out.println("sub: " + i);

}

}

}

57、介紹Collection框架的結構

Iterable

    Collection

        List

            ArrayList

            LinkedList

            Vector

                Stack

        Set

            HashSet

            SortedSet

TreeSet

Map

SortedMap

TreeMap

    Hashtable

Properties

HashMap

    LinkedHashMap

Collections,不屬於集合,是集合類的工具類

Arrays,不屬於集合類,是數據對象的工具類

58Collection框架中實現比較要實現什麼接口

Comparable/Comparator

59ArrayListVector的區別

1. 線程同步,Vector線程安全,ArrayList線程不安全

2. 效率問題,Vector效率低,ArrayList效率高

3. 增加數量,Vector1.5倍增加,ArrayList2倍增加

60HashMapHashtable的區別

1. 線程同步,Hashtable線程安全,HashMap線程不安全

2. 效率問題,Hashtable效率低,HashMap效率高

3. HashMap能夠使用null做爲keyHashtable不能夠使用nullkey

4. HashMap使用的是新實現,繼承AbstractMap,而Hashtable是繼承Dictionary類,實現比較老

5. Hash算法不一樣,HashMaphash算法比Hashtablehash算法效率高

6. HashMapHashtablecontains方法去掉了,改爲containsValuecontainsKey。由於contains方法容易讓人引發誤解。

7. 取值不一樣,HashMap用的是Iterator接口,而Hashtable中還有使用Enumeration接口

61ListMap區別?

一個是存儲單列數據的集合,另外一個是存儲鍵和值的雙列數據的集合,List中存儲的數據是有順序,而且容許重複;Map中存儲的數據是沒有順序的,其鍵是不能重複的,它的值是能夠有重複的。

1.List有重複值,Map沒有重複key,但能夠有重複值

2.List有序,Map不必定有序

3.List只能存單列值,Map能夠存雙列值

62List, Set, Map是否繼承自Collection接口?

    ListSet是,Map不是

63ListMapSet三個接口,存取元素時,各有什麼特色?

List使用get(index)取值,也能夠使用IteratortoArray取值

Set只能經過IteratortoArray取值

Map取值使用get(key)取值,也能夠使用keySet取鍵值集合,也可以使用values取值集合,entrySet取所有鍵值對映射。

64、說出ArrayList,Vector, LinkedList的存儲性能和特性

1. ArrayListVector使用數組存儲元素;LinkedList使用鏈表存儲元素

2. ArrayListVector插入刪除數據時,須要搬運數據,效率較差;LinkedList使用鏈表,不須要搬運數據,效率高

3. ArrayListVectory查詢時,按數組下標查詢,不須要遍歷,效率高;LinkedList須要遍歷,查詢效率底

4. ArrayListVector的區別見59

65、去掉一個Vector集合中重複的元素

1. 自行遍歷,用另一個Vector來判斷是否有重複

2. Set(TreeSetHashSet)來去重

3. ApacheCollectionUtil工具類去重

Vector newVector = new Vector();

for (int i = 0; i < vector.size(); i++) {

Object obj = vector.get(i);

if (!newVector.contains(obj))

newVector.add(obj);

}

還有一種簡單的方式,HashSet set = new HashSet(vector);

66CollectionCollections的區別。

Collection是集合類的上級接口,繼承與他的接口主要有SetList.

Collections是針對集合類的一個工具類,他提供一系列靜態方法實現對各類集合的搜索、排序、線程安全化等操做。

67Set裏的元素是不能重複的,那麼用什麼方法來區分重複與否呢?是用==仍是equals()?它們有何區別?

Set裏的元素是不能重複的,元素重複與否視具體狀況而定:

1. HashSet使用equals比較

2. TreeSet使用compareTo進行比較

68、你所知道的集合類都有哪些?主要方法?

最經常使用的集合類接口是List Map

List的具體實現包括ArrayListVectorLinkedList,它們是可變大小的列表,比較適合構建、存儲和操做任何類型對象的元素列表。List適用於按數值索引訪問元素的情形。

Set的具體實現包括HashSetTreeSet,它們也是可變大小集合,但不適合用索引取值。

Map 提供了一個更通用的元素存儲方法。Map集合類用於存儲元素對(稱做""""),其中每一個鍵映射到一個值。

ArrayList/VectorLinkedList

HashSet/TreeSet

Properties/HashTable/TreeMap/HashMap

List的主要方法有:

addgetremovesetiteratorcontainsaddAllremoveAllindexOftoArrayclearisEmpty

Set的主要方法有:

addremoveiteratorcontainsaddAllremoveAlltoArrayclearisEmpty

Map的主要方法有:

putgetkeySetvaluesentrySetclearremoveisEmpty

69、兩個對象值相同(x.equals(y) == true),但卻可有不一樣的hash code,這句話對不對?

1. equals等,hashCode同,所以重寫equals方法必須重寫hashCode

2. hashCode等,equals不必定同,但hashCode最好散列化

3. 任何對象equals null都得false

4. 沒有繼承關係的兩個類,equals都得false

5. 重寫equals方法的類最好是值類,即不可變

6. 若是A對象equals B對象,B對象equals C對象,則A對象equals C對象

70TreeSet裏面放對象,若是同時放入了父類和子類的實例對象,那比較時使用的是父類的compareTo方法,仍是使用的子類的compareTo方法,仍是拋異常!

1. 若是子類從新實現了Comparable,且比較時所有使用父類的引用和屬性,則不會出錯

2. 若是子類從新實現了Comparable,且比較時使用了子類的引用和屬性,出異常

3. 子類沒有從新實現Comparable,則不會了出錯。

用哪一個對象比較,則調用哪一個對象的comparaTo方法

71、說出一些經常使用的類,包,接口,請各舉5

要讓人家感受你對JavaEE開發很熟,因此,不能僅僅只列core java中的那些東西,要多列你在作ssh項目中涉及的那些東西。就寫你最近寫的那些程序中涉及的那些類。

經常使用的類:BufferedReaderBufferedWriterFileReaderFileWirterStringIntegerjava.util.DateSystemClassListHashMap

經常使用的包:java.langjava.iojava.utiljava.sqljavax.servletorg.apache.strtuts.actionorg.hibernate, org.springframework

經常使用的接口:ListMapDocumentNodeListServletHttpServletRequestHttpServletResponseHttpSessionAction(Struts)Transaction(Hibernate) Session(Hibernate)ApplicationContext(Spring)FactoryBean(Spring)

72Java中有幾種類型的流?JDK爲每種類型的流提供了一些抽象類以供繼承,請說出他們分別是哪些類?

字節流,字符流。字節流繼承於InputStreamOutputStream,字符流繼承於ReaderWriter。在java.io包中還有許多其餘的流,主要是爲了提升性能和使用方便。ileInputStreamFileReaderByteArrayInputStreamCharArrayReaderBufferedInputStreamBufferedReaderZipInputStreamPrintStreamStringReaderObjectInputStreamRandomAccessFile(不屬於流,但像流)

73、字節流與字符流的區別

字節流是按字節讀取或寫入設備,但字符流是以字符爲單位讀取或寫入設備。

若是是二進制文件,須要用字節流讀取。通常來講,字符流只處理文本文件。在設備中,大多數狀況是以字節形式存儲數據的,所以字符流經過須要傳入字節流當參數。

74、什麼是java序列化,如何實現java序列化?或者請解釋Serializable接口的做用。

序列化是把內存Java對象保存到存儲介質中,反序列化就是把存儲介質中的數據轉化爲Java對象。Java經過ObjectInputStreamObjectOutputStream實現序列化和反序列化。須要進行序列化的對象的類必須實現Serializable接口,一般狀況下須要知足如下條件:

1. 強烈建議手動生成serialVersionUID常量

2. 若是須要加解密的話,須要實現兩個方法readObjectwriteObject方法

3. 若是使用Hibernate二級緩存或其它緩存服務器的話,對象必須是可序列化的

4. 若是須要遠程調用對象或傳值的話,則對像須要序列化

5. 序列化類的可序列化成員必須也是可序列化的,不須要序列化的屬性用transient修飾

75、描述一下JVM加載class文件的原理機制?

1. 查找當前ClassLoader中是否有此class的類對象,有則返回

2. 若沒有的話,向上遞歸全部的父ClassLoader中有無此class類對象,有則返回

3. 若尚未,查找BootstrapClassLoader中有無此class類對象,有則返回

4. 若尚未的話,使用findClassresolveClass加載類對象

a. 讀取class二進制文件

b. 根據字節數組生成Class對象

c. 緩存到當前ClassLoader

JVM加載class對象是懶加載,按需加載

76heapstack有什麼區別。

Java的內存分爲兩類,一類是棧內存,一類是堆內存。

棧中存儲的是當前線程的方法調用、基本數據類型和對象的引用,棧是有序的。

堆中存儲的是對象,堆是無序的。

方法中的局部變量使用final修飾後,放在堆中,而不是棧中。

77GC是什麼?爲何要有GC?

GC是垃圾回收的意思(Gabage Collection),內存處理是編程人員容易出現問題的地方,忘記或者錯誤的內存回收會致使程序或系統的不穩定甚至崩潰,Java提供的GC功能能夠自動監測對象是否超過做用域從而達到自動回收內存的目的,Java語言沒有提供釋放已分配內存的顯示操做方法。線程對象在沒有終止前,即便沒有任何引用,也不會被垃圾回收。只能建議JVM回收內存,不能強制,能夠使用System.gc()建議執行。

GC有三種方式,串行回收、並行回收、混合回收。

78、垃圾回收的優勢和原理。並考慮2種回收機制。

Java語言中一個顯著的特色就是引入了垃圾回收機制,使C++程序員最頭疼的內存管理的問題迎刃而解,它使得Java程序員在編寫程序的時候再也不須要考慮內存管理。因爲有垃圾回收機制,Java中的對象再也不有"做用域"的概念,只有對象的引用纔有"做用域"。垃圾回收能夠有效的防止內存泄露,更有效的使用內存。垃圾回收器一般是做爲一個單獨的低級別的線程運行,對內存堆中已經死亡的或者長時間沒有使用的對象進行清除和回收,程序員不能實時的調用垃圾回收器對某個對象或全部對象進行垃圾回收。回收機制有分代複製垃圾回收和標記垃圾回收,增量垃圾回收。

1.按時間輪詢,把沒有引用的對象進行回收

2.按內存的使用量超不超過報警值進行回收

3.CPU空閒時間進行回收

4.程序建議JVM進行垃圾回收

GC有三種方式,串行回收、並行回收、混合回收。

79、垃圾回收器的基本原理是什麼?垃圾回收器能夠立刻回收內存嗎?有什麼辦法主動通知虛擬機進行垃圾回收?

對於GC來講,當程序員建立對象時,GC就開始監控這個對象的地址、大小以及使用狀況。一般,GC採用有向圖的方式記錄和管理堆(heap)中的全部對象。經過這種方式肯定哪些對象是"可達的",哪些對象是"不可達的"。當GC肯定一些對象爲"不可達"時,GC就有責任回收這些內存空間。能夠。程序員能夠手動執行System.gc(),通知GC運行,可是Java語言規範並不保證GC必定會執行。

80、何時用assert

assertion(斷言)在軟件開發中是一種經常使用的調試方式,不少開發語言中都支持這種機制。在實現中,assertion就是在程序中的一條語句,它對一個boolean表達式進行檢查,一個正確程序必須保證這個boolean表達式的值爲true;若是該值爲false,說明程序已經處於不正確的狀態下,assert將給出警告或退出。通常來講,assertion用於保證程序最基本、關鍵的正確性。assertion檢查一般在開發和測試時開啓。爲了提升性能,在軟件發佈後,assertion檢查一般是關閉的。

81java中會存在內存泄漏嗎,請簡單描述。

會,緣由:

若是對象被集合類引用時,若是隻是添加,而不刪除,會引發內存泄漏,嚴重時會發出內存溢出。Java中的內存泄露的狀況:長生命週期的對象持有短生命週期對象的引用就極可能發生內存泄露 內存泄露的另一種狀況:當一個對象被存儲進HashSetHashMap中之後,就不能修改這個對象中的那些參與計算哈希值的字段了,不然,對象修改後的哈希值與最初存儲進HashSet集合中時的哈希值就不一樣了,在這種狀況下,即便在contains方法使用該對象的當前引用做爲的參數去HashSet集合中檢索對象,也將返回找不到對象的結果,這也會致使沒法從HashSet集合中單獨刪除當前對象,形成內存泄露。

82、能不能本身寫個類,也叫java.lang.String

能夠,若是非要實現java.lang.String,須要自已寫ClassLoader,否則JVM優先加載默認rt.jar中的java.lang.String。能夠,但在應用的時候,須要用本身的類加載器去加載,不然,系統的類加載器永遠只是去加載rt.jar包中的那個java.lang.String。因爲在tomcatweb應用程序中,都是由webapp本身的類加載器先本身加載WEB-INF/classess目錄中的類,而後才委託上級的類加載器加載,若是咱們在tomcatweb應用程序中寫一個java.lang.String,這時候Servlet程序加載的就是咱們本身寫的java.lang.String,可是這麼幹就會出不少潛在的問題,原來全部用了java.lang.String類的都將出現問題。雖然java提供了endorsed技術,能夠覆蓋jdk中的某些類,可是,可以被覆蓋的類是有限制範圍,反正不包括java.lang這樣的包中的類。(下面的例如主要是便於你們學習理解只用,不要做爲答案的一部分,不然,人家懷疑是題目泄露了)例如,運行下面的程序:

package java.lang;

 

public class String {

 

public static void main(String[] args) {

System.out.println("string");

}

}

報告的錯誤以下:

java.lang.NoSuchMethodError:main

Exception inthread "main"

這是由於加載了jre自帶的java.lang.String,而該類中沒有main方法。

83. Java代碼查錯

1.

abstract class Name {

   private String name;

   public abstract boolean isStupidName(String name) {}

}

大俠們,這有何錯誤?

答案: 錯。abstract method必須以分號結尾,且不帶花括號。

2.

public class Something {

void doSomething() {

private String s = "";

int l = s.length();

}

}

有錯嗎?

答案: 錯。局部變量前不能放置任何訪問修飾符 (privatepublic,和protected)final能夠用來修飾局部變(final如同abstractstrictfp,都是非訪問修飾符,strictfp只能修飾classmethod而非variable)

3.

abstract class Something {

private abstract String doSomething();

}

這好像沒什麼錯吧?

答案: 錯。abstractmethods不能以private修飾。abstractmethods就是讓子類

implement(實現)具體細節的,怎麼能夠用privateabstractmethod封鎖起來呢? (同理,abstract method前不能加final)

4.

public class Something {

public int addOne(final int x) {

return ++x;

}

}

這個比較明顯。

答案: 錯。int x被修飾成final,意味着x不能在addOne method中被修改。

5.

public class Something {

public static void main(String[] args) {

Other o = new Other();

new Something().addOne(o);

}

public void addOne(final Other o) {

o.i++;

}

}

class Other {

public int i;

}

和上面的很類似,都是關於final的問題,這有錯嗎?

答案: 正確。在addOne method中,參數o被修飾成final。若是在addOne method

咱們修改了oreference(好比: o = new Other();),那麼如同上例這題也是錯的。但這裏修改的是omember vairable(成員變量),而oreference並無改變。

6.

class Something {

int i;

 

public void doSomething() {

System.out.println("i = " + i);

}

}

有什麼錯呢? 看不出來啊。

答案: 正確。輸出的是"i = 0"int i屬於instant variable (實例變量,或叫成員變量)instant variabledefault valueintdefault value0

7.

class Something {

final int i;

public void doSomething() {

System.out.println("i = " + i);

}

}

和上面一題只有一個地方不一樣,就是多了一個final。這難道就錯了嗎?

答案: 錯。final int i是個finalinstant variable (實例變量,或叫成員變量)finalinstant variable沒有default value,必須在constructor (構造器)結束以前被賦予一個明確的值。能夠修改成"final int i =0;"

8.

public class Something {

public static void main(String[] args) {

Something s = new Something();

System.out.println("s.doSomething() returns " +

doSomething());

}

public String doSomething() {

return "Do something ...";

}

}

 看上去很完美。

答案: 錯。看上去在maincall doSomething沒有什麼問題,畢竟兩個methods都在同一個class裏。但仔細看,mainstatic的。static method不能直接call non-staticmethods。可改爲"System.out.println("s.doSomething()returns " + s.doSomething());"。同理,static method不能訪問non-static instant variable

9.

此處,Something類的文件名叫OtherThing.java

class Something {

private static void main(String[] something_to_do) {

System.out.println("Dosomething ...");

}

}

 這個好像很明顯。

答案: 正確。歷來沒有人說過JavaClass名字必須和其文件名相同。但public class的名字必須和文件名相同,若是main方法是public,則爲程序的入口方法,而爲private只是普通的靜態方法而已。

10

interface A {

int x = 0;

}

class D {

int x = 2;

}

class B extends D {

int x = 1;

}

class C extends B implements A {

public void pX() {

System.out.println(super.x);

}

public static void main(String[] args) {

new C().pX();

}

}

答案:錯誤。在編譯時會發生錯誤(錯誤描述不一樣的JVM有不一樣的信息,意思就是未

明確的x調用,兩個x都匹配(就象在同時import java.utiljava.sql兩個包時直接聲明Date同樣)。對於父類的變量,能夠用super.x來明確,而接口的屬性默認隱含爲 public static final.因此能夠經過A.x來明確。

11.

interface Playable {

void play();

}

interface Bounceable {

void play();

}

interface Rollable extends Playable, Bounceable {

Ball ball = new Ball("PingPang");

}

class Ball implements Rollable {

private String name;

public String getName() {

return name;

}

public Ball(String name) {

this.name = name;

}

public void play() {

ball = new Ball("Football");

System.out.println(ball.getName());

}

}

這個錯誤不容易發現。

答案: 錯。"interfaceRollable extends Playable, Bounceable"沒有問題。interface可繼承多個interfaces,因此這裏沒錯。問題出在interface Rollable裏的"Ball ball =new Ball("PingPang");"。任何在interface裏聲明的interface variable (接口變量,也可稱成員變量),默認爲public static final。也就是說"Ball ball = new Ball("PingPang");"其實是"public staticfinal Ball ball = new Ball("PingPang");"。在Ball類的Play()方法中,"ball = newBall("Football");"改變了ballreference,而這裏的ball來自Rollable interfaceRollable interface裏的ballpublic static final的,finalobject是不能被改變reference的。所以編譯器將在"ball = newBall("Football");"這裏顯示有錯。

 

.算法與編程

1、編寫一個程序,將a.txt文件中的單詞與b.txt文件中的單詞交替合併到c.txt文件中,a.txt文件中的單詞用回車符分隔,b.txt文件中用回車或空格進行分隔。

本題考覈的是使用字符流讀寫文件,並能切分字符串

 

package com.bwie.interview;

 

import java.io.IOException;

import java.io.InputStreamReader;

import java.io.PrintStream;

import java.util.StringTokenizer;

 

public class AnswerB01 {

 

public static void main(String[] args) throws IOException {

StringTokenizer tokenizer1 = getTokenzer("/a.txt");

StringTokenizer tokenizer2 = getTokenzer("/b.txt");

PrintStream out = new PrintStream("C:/c.txt");

while (tokenizer1.hasMoreTokens() &&

 

tokenizer2.hasMoreTokens()) {

out.println(tokenizer1.nextToken());

out.println(tokenizer2.nextToken());

}

out.close();

}

 

private static StringTokenizer getTokenzer(String fileName)

 

throws IOException {

InputStreamReader reader = new InputStreamReader

 

(AnswerB01.class.getResourceAsStream(fileName));

StringBuilder builder = new StringBuilder(1000);

int length = -1;

char[] cs = new char[1024];

while ((length = reader.read(cs)) != -1) {

builder.append(cs, 0, length);

}

reader.close();

return new StringTokenizer(builder.toString());

}

}

2、編寫一個程序,將d:\java目錄下的全部.java文件複製到d:\jad目錄下,並將原來文件的擴展名從.java改成.jad

答:listFiles方法接受一個FileFilter對象,這個FileFilter對象就是過慮的策略對象,不一樣的人提供不一樣的FileFilter實現,即提供了不一樣的過濾策略。

import java.io.File;

import java.io.FileInputStream;

import java.io.FileOutputStream;

import java.io.FilenameFilter;

import java.io.IOException;

 

public class AnswerB02 {

 

public static void main(String[] args) throws IOException {

File sourceFolder = new File("D:/java");

File[] files = sourceFolder.listFiles(new JavaFileFilter

 

());

for (File file : files) {

String absolutePath = file.getName();

String targetFile = "D:/jad/" +

 

absolutePath.substring(0, absolutePath.length() - 5) + ".jad";

copy(file, new File(targetFile));

}

}

 

private static void copy(File source, File target) throws IOException {

FileInputStream input = new FileInputStream(source);

FileOutputStream out = new FileOutputStream(target);

int length = -1;

byte[] bs = new byte[1024];

while ((length = input.read(bs)) != -1) {

out.write(bs, 0, length);

}

input.close();

out.close();

}

 

private static final class JavaFileFilter implements FilenameFilter {

@Override

public boolean accept(File dir, String name) {

return name.endsWith(".java");

}

}

}

3、編寫一個截取字符串的函數,輸入爲一個字符串和字節數,輸出爲按字節截取的字符串,但要保證漢字不被截取半個,如「我ABC」,4,應該截取「我AB」,輸入「我ABCDEF」,6,應該輸出「我ABC」,而不是「我ABC+漢的半個」。

import java.io.IOException;

 

public class AnswerB03 {

public static void main(String[] args) throws IOException {

String s = "ABCDEF";

System.out.println(substring(s, 6));

}

public static String substring(String s, int length) {

char[] cs = s.toCharArray();

StringBuilder builder = new StringBuilder();

int count = 0;

for (char c : cs) {

if (isAsc(c)) {

count++;

} else {

count += 2;

}

if (count > length) {

break;

}

builder.append(c);

}

return builder.toString();

}

public static boolean isAsc(char c) {

return c < 128;

}

}

4、有一個字符串,其中包含中文字符、英文字符和數字字符,請統計和打印出各個字符的個數。

String content = "中文字符english中文字符&&&****$%#abc";

Map<Character, Integer> map = new HashMap<Character, Integer>();

for (int i = 0; i < content.length; i++) {

char c = content.charAt(i);

Integer count = map.get(c);

if (count == null) {

count = 0;

}

count = count + 1;

map.put(c, count);

}

Set<Entry> entries = map.entrySet();

for (Entry entry : entries) {

system.out.println(entry.getkey() + ":" + entry.getValue());

}

若是一串字符如"中文字符english中文字符123456"要分別統計英文字符的數量,中文字符的數量,和數字字符的數量,假設字符中沒有中文字符、英文字符、數字字符以外的其餘特殊字符。

int engishCount;

int chineseCount;

int digitCount;

for (int i = 0; i < str.length; i++) {

char ch = str.charAt(i);

if (ch >= '0' && ch <= '9' || ch == '.') {

digitCount++;

} else if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z'))

 

{

engishCount++;

} else {

chineseCount++;

}

}

6、從相似以下的文本文件中讀取出全部的姓名,並打印出重複的姓名和重複的次數,並按重複次數排序:

1,張三,28

2,李四,35

3,張三,28

4,王五,35

5,張三,28

6,李四,35

7,趙六,28

8,田七,35

 

import java.io.BufferedReader;

import java.io.IOException;

import java.io.InputStreamReader;

import java.util.ArrayList;

import java.util.Collections;

import java.util.HashMap;

import java.util.List;

import java.util.Map;

import java.util.Set;

 

public class AnswerB06 {

 

public static void main(String[] args) throws IOException {

BufferedReader reader = new BufferedReader(new

 

InputStreamReader(new FileInputStream("/person.txt")));

 

Map<String, Integer> nameMap = new HashMap<String,

 

Integer>();

String line = null;

while ((line = reader.readLine()) != null) {

String[] segments = line.split(",", -1);

String name = segments[1];

Integer count = nameMap.get(name);

if (count == null) {

count = 0;

}

count++;

nameMap.put(name, count);

}

reader.close();

 

List<PersonCount> personCounts = new

 

ArrayList<PersonCount>();

Set<String> names = nameMap.keySet();

for (String name : names) {

PersonCount personCount = new PersonCount();

personCount.name = name;

personCount.count = nameMap.get(name);

personCounts.add(personCount);

}

 

Collections.sort(personCounts);

 

for (PersonCount personCount : personCounts) {

System.out.println(personCount.name + "=" +

 

personCount.count);

}

}

 

static class PersonCount implements Comparable<PersonCount> {

public String name;

public int count;

 

@Override

public int compareTo(PersonCount o) {

return count - o.count;

}

}

}

7、寫一個Singleton出來。

第一種:飽漢模式

public class SingleTon {

private SingleTon() {

}

 

// 實例化放在靜態代碼塊裏可提升程序的執行效率,但也可能更佔用空間

private final static SingleTon instance = new SingleTon();

 

public static SingleTon getInstance() {

return instance;

}

}

第二種:飢漢模式

public class SingleTon {

private SingleTon() {

}

 

private static SingleTon instance;

 

public static synchronized SingleTon getInstance() {

if (instance == null) {

instance = new SingleTon();

}

return instance;

}

}

 

第三種:用枚舉

public enum SingleTon {

ONE;

}

 

第四種:雙重校驗

public class SingleTon {

private SingleTon() {

}

 

private static SingleTon instance;

 

public static SingleTon getInstance() {

if (instance == null) {

synchronized(SingleTon.class) {

if (instance == null) {

instance = new SingleTon();

}

}

}

return instance;

}

}

 

第五種:所有靜態方法、定義一個類,它的全部的方法都是靜態方法,且構造器是私有的通常認爲第一種形式要更加安全些

8、遞歸算法題1

一個整數,大於0,不用循環和本地變量,按照n2n4n8n的順序遞增,當值大於5000時,把值按照指定順序輸出來。

例:n=1237

則輸出爲:

1237

2474

4948

9896

9896

4948

2474

1237

public static void doubleNum(int n) {

System.out.println(n);

if (n <= 5000) {

doubleNum(n * 2);

}

System.out.println(n);

}

public static void doubleNum(int n) {

if (n > 5000) {

System.out.println(n);

return;

}

doubleNum(n * 2);

System.out.println(n);

}

9、遞歸算法題2

1我的10歲,第2個比第1我的大2歲,依次遞推,請用遞歸方式計算出第8我的多大?

import java.util.Date;

 

public class RecursionDemo {

 

public static void main(String[] args) {

System.out.println(computeAge(8));

}

 

public static int computeAge(int n) {

if (n == 1) {

return 10;

}

return computeAge(n - 1) + 2;

}

}

10、排序都有哪幾種方法?請列舉。用JAVA實現一個快速排序。

經常使用的排序算法有冒泡排序、選擇排序和快速排序。下面給出冒泡排序和快速排序的例子。

冒泡排序:

private static void bubbleSort(int[] array) {

for (int i = 1; i < array.length; i++) {

for (int j = 0; j < i; j++) {

if (array[i] < array[j]) {

int temp = array[i];

array[i] = array[j];

array[j] = temp;

}

}

}

}

 

快速排序:

public void quickSort(String[] strDate, int left, int right) {

String middle, tempDate;

int i, j;

i = left;

j = right;

middle = strDate[(i + j) / 2];

do {

while (strDate[i].compareTo(middle) < 0 && i < right)

i++; // 找出左邊比中間值大的數

while (strDate[j].compareTo(middle) > 0 && j > left)

j--; // 找出右邊比中間值小的數

if (i <= j) { // 將左邊大的數和右邊小的數進行替換

tempDate = strDate[i];

strDate[i] = strDate[j];

strDate[j] = tempDate;

i++;

j--;

}

} while (i <= j); // 當二者交錯時中止

if (i < right) {

quickSort(strDate, i, right);

}

if (j > left) {

quickSort(strDate, left, j);

}

}

11、有數組a[n],用java代碼將數組元素順序顛倒

public class AnswerB11 {

 

public static void main(String[] args) {

int[] array = { 2, 25, 21, 63, 234, 83 };

reverse(array);

System.out.println(Arrays.toString(array));

}

 

private static void reverse(int[] array) {

for (int i = 0; i < array.length / 2; i++) {

int temp = array[i];

array[i] = array[array.length - 1 - i];

array[array.length - 1 - i] = temp;

}

}

}

12、金額轉換,阿拉伯數字的金額轉換成中國傳統的形式如:(¥1011)->(一千零一拾一元整)輸出。

public class AnswerB12 {

private static final char[] data = {

'', '', '', '', '', '', '', '', '', ''

};

private static final char[] units = {

'', '', '', '', '', '', '', '', ''

};

 

public static void main(String[] args) {

System.out.println(toUpcaseMoney(convert(100215)));

}

 

private static String toUpcaseMoney(String money) {

return new StringBuilder(money).toString()

.replaceAll("[拾佰仟]", "")

.replaceAll("+", "")

.replaceAll("+", "")

.replaceAll("+", "");

}

 

public static String convert(int money) {

StringBuffer sbf = new StringBuffer();

int unit = 0;

while (money != 0) {

sbf.insert(0, units[unit++]);

int number = money % 10;

sbf.insert(0, data[number]);

money /= 10;

}

 

return sbf.toString();

}

}

14、以最快的效率找出一個數組中第二大的數

不能使用排序,而後取第二大數,緣由有兩個,第一個不是最快的效率,第二個是由於題目只是要求找出第二大的數,並無要求破壞數據。通常狀況下儘可能不要破壞原始數據。

public class SecondMaxNumber {

 

public static void main(String[] args) {

int[] nums = {2, 10, 6, 68, 13, 26, 98, 5};

int firstMax = nums[0];

int secondMax = nums[0];

for (int i = 1; i < nums.length; i++) {

int num = nums[i];

if (num < secondMax) {

continue;

}

if (num > firstMax) {

secondMax = firstMax;

firstMax = num;

continue;

}

secondMax = num;

}

System.out.println(secondMax);

}

}

1、JDK經常使用的包

 java.lang: 這個是系統的基礎類,好比StringMathIntegerSystemThread,提供經常使用功能。

 java.io: 這裏面是全部輸入輸出有關的類,好比文件操做等

 java.net: 這裏面是與網絡有關的類,好比URL,URLConnection等。

 java.util : 這個是系統輔助類,特別是集合類Collection,List,Map等。

 java.sql: 這個是數據庫操做的類,Connection, StatememtResultSet

 

3、Java多態的具體體現

面向對象編程有四個特徵:抽象,封裝,繼承,多態。

多態有四種體現形式:

1. 接口和接口的繼承。

2. 類和類的繼承。

3. 重載。

4. 重寫。

其中重載和重寫爲核心。

重載:重載發生在同一個類中,在該類中若是存在多個同名方法,可是方法的參數類型和個數不同,那麼說明該方法被重載了。

重寫:重寫發生在子類繼承父類的關係中,父類中的方法被子類繼承,方法名,返回值類型,參數徹底同樣,可是方法體不同,那麼說明父類中的該方法被子類重寫了。

 

4、StringBuffer StringBuilder String 區別

String       字符串常量   不可變  使用字符串拼接時是不一樣的2個空間

StringBuffer  字符串變量   可變   線程安全    字符串拼接直接在字符串後追加

StringBuilder 字符串變量   可變   非線程安全  字符串拼接直接在字符串後追加

1.StringBuilder執行效率高於StringBuffer高於String.

2String是一個常量,是不可變的,因此對於每一次+=賦值都會建立一個新的對象,StringBufferStringBuilder都是可變的,當進行字符串拼接時採用append方法,在原來的基礎上進行追加,因此性能比String要高,又由於StringBuffer是線程安全的而StringBuilder是線程非安全的,因此StringBuilder的效率高於StringBuffer.

3.對於大數據量的字符串的拼接,採用StringBuffer,StringBuilder.

5、HashtableHashMap的區別

     HashMap不是線程安全的,HashTable是線程安全。

     HashMap容許空(null)的鍵和值(key),HashTable則不容許。

     HashMap性能優於Hashtable

Map

1.Map是一個以鍵值對存儲的接口。Map下有兩個具體的實現,分別是HashMap

HashTable.

2.HashMap是線程非安全的,HashTable是線程安全的,因此HashMap的效率高於HashTable.

3.HashMap容許鍵或值爲空,而HashTable不容許鍵或值爲空.

十4、List,Set,Collection,Collections

1.ListSet都是接口,他們都繼承於接口Collection,List是一個有序的可重複的集合,而Set的無序的不可重複的集合。Collection是集合的頂層接口,Collections是一個封裝了衆多關於集合操做的靜態方法的工具類,由於構造方法是私有的,因此不能實例化。

2.List接口實現類有ArrayList,LinkedList,VectorArrayListVector是基於數組實現的,因此查詢的時候速度快,而在進行增長和刪除的時候速度較慢LinkedList是基於鏈式存儲結構,因此在進行查詢的時候速度較慢但在進行增長和刪除的時候速度較快。又由於Vector是線程安全的,因此他和ArrayList相比而言,查詢效率要低。

十5、java的基本數據類型

數據類型 大小

byte(字節) 1(8)

shot(短整型) 2(16)

int(整型) 4(32)

long(長整型) 8(32)

float(浮點型) 4(32)

double(雙精度) 8(64)

char(字符型) 2(16)

boolean(布爾型) 1

附加:

 String是基本數據類型嗎?(String不是基本數據類型)

 String的長度是多少,有限制?(長度受內存大小的影響)

十8、時間類型轉換

public class DateFormat {

public static void fun() {

SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd

 

");

String newDate;

try {

newDate = sdf.format(new SimpleDateFormat

 

("yyyyMMdd")

.parse("20121115"));

System.out.println(newDate);

} catch (ParseException e) {

e.printStackTrace();

}

}

public static void main(String args[]) {

fun();

}

}

十9、階乘

public class Multiply {

public static int multiply(int num) {

if (num < 0) {

System.out.println("請輸入大於0的數!");

return -1;

} else if (num == 0 || num == 1) {

return 1;

} else {

return multiply(num - 1) * num;

}

}

public static void main(String[] args) {

System.out.println(multiply(10));

}

}

 

jvm的內存結構

Java虛擬機的內存結構分爲堆(heap)和棧(stack),堆裏面存放是對象實例也就是new出來的對象。棧裏面存放的是基本數據類型以及引用數據類型的地址。對於所謂的常量是存儲在方法區的常量池裏面。

java Exception體系結構

java 異常是程序運行過程當中出現的錯誤。Java把異常看成對象來處理,並定義一個基類java.lang.Throwable做爲全部異常的超類。在Java API中定義了許多異常類,分爲兩大類,錯誤Error和異常Exception。其中異常類Exception又分爲運行時異常(RuntimeException)和非運行時異常(runtimeException),也稱之爲不檢查異常Unchecked Exception)和檢查異常(Checked Exception)。

1ErrorException

Error是程序沒法處理的錯誤,好比OutOfMemoryErrorThreadDeath等。

這些異常發生時,Java虛擬機(JVM)通常會選擇線程終止。

Exception是程序自己能夠處理的異常,這種異常分兩大類運行時異常和非運行時異常。程序中應當儘量去處理這些異常。

2、運行時異常和非運行時異常      

運行時異常: 都是RuntimeException類及其子類異常:

IndexOutOfBoundsException 索引越界異常

ArithmeticException:數學計算異常

NullPointerException:空指針異常

ArrayOutOfBoundsException:數組索引越界異常

ClassNotFoundException:類文件未找到異常

ClassCastException:造型異常(類型轉換異常)

這些異常是不檢查異常(Unchecked Exception),程序中能夠選擇捕獲處理,也能夠不處理。這些異常通常是由程序邏輯錯誤引發的。

非運行時異常:RuntimeException之外的異常,類型上都屬於Exception類及其子類。從程序語法角度講是必須進行處理的異常,若是不處理,程序就不能編譯經過。如:

IOException、文件讀寫異常

FileNotFoundException:文件未找到異常

  EOFException:讀寫文件尾異常

MalformedURLExceptionURL格式錯誤異常

SocketExceptionSocket異常

SQLExceptionSQL數據庫異常

字節流與字符流的區別

stream結尾都是字節流,readerwriter結尾都是字符流

二者的區別就是讀寫的時候一個是按字節讀寫,一個是按字符。

實際使用一般差很少。

在讀寫文件須要對內容按行處理,好比比較特定字符,處理某一行數據的時候通常會選擇字符流。

只是讀寫文件,和文件內容無關的,通常選擇字節流。

final,finally,finalize 三者區別

Final是一個修飾符:

final修飾一個變量的時候,變量變成一個常量,它不能被二次賦值

final修飾的變量爲靜態變量(即由static修飾)時,必須在聲明這個變 量的時候給它賦值

final修飾方法時,該方法不能被重寫

final修飾類時,該類不能被繼承

Final不能修飾抽象類,由於抽象類中會有須要子類實現的抽 象方法,(抽象類中能夠有抽象方法,也能夠有普通方法,當一個抽象類中沒有抽象方法時,這個抽象類也就沒有了它存在的必要)

Final不能修飾接口,由於接口中有須要其實現類來實現的方法

Finally

Finally只能與try/catch語句結合使用,finally語句塊中的語句必定會執行,而且會在returncontinuebreak關鍵字以前執行

finalize

Finalize是一個方法,屬於java.lang.Object類,finalize()方法是GCgarbage collector垃圾回收)運行機制的一部分,finalize()方法是在 GC清理它所從屬的對象時被調用的

Io流的層次結構

從流的方向

輸入流   輸出流

 

從流的類型上

字符流    字節流

 

inputstreamoutputstream都是抽象類

 

它們下面的實現包括

 

FileInputStream,BufferedInputStream

 

FileOutputStream,BufferedOutputStream

 

reader writer

 

FileReader,BufferedReader,StringReader

FileWriter,BufferedWriter,StringWriter,PrintWriter

 

 

 

JAVA:

Java是面向對象的,跨平臺的,它經過java虛擬機來進行跨平臺操做,它能夠進行自動垃圾回收的【c語言是經過人工進行垃圾回收】,java還會進行自動分配內存。【c語言是經過指定進行分配內存的】,只須要new一個對象,這個對象佔用了多少空間,不須要咱們來管,java虛擬機負責管這些,用完以後也不須要咱們來釋放,java虛擬機會自動釋放

 

JavaSE JavaEE JavaME區別

是什麼:

Java SE=Java Standard Edition=j2se = java 標準版

Java EE=Java Enterprise Edition=j2ee= java 企業版

Java ME=Java Mobile Edition=j2me = java移動版

特色:

SE主要用於桌面程序(swing,控制檯開發(main程序)

EE企業級開發(JSP,EJB,Spring MVC,Struts,hibernate,ibatis)

用於企業級軟件開發,網絡開發,web開發。

ME嵌入式開發(手機,小家電,PDA)[蘋果的ios,黑莓]

三者之間的關係:

Java SEJava Platform, Standard EditionJava標準版)就是基於JDKJRE的。

Java SEJava EE提供了基礎。

Java EE除了基於咱們這個所謂的Java SE外,還新加了企業應用所需的類庫

JDK  JRE  JVM的區別:

JdkJava Development ToolKit】就是java開發工具箱, JDK是整個JAVA的核內心邊包含了jre,它除了包含jre以外還包含了一些javac的工具類,把java源文件編譯成class文件,java文件是用來運行這個程序的,除此以外,裏邊還包含了java源生的APIjava.lang.integerrtjar包裏邊【能夠在項目中看到】,經過rt這個jar包來調用咱們的這些io流寫入寫出等

JDK有如下三種版本:

J2SEstandard edition,標準版,是咱們一般用的一個版本

J2EEenterpsise edtion,企業版,使用這種JDK開發J2EE應用程序

J2MEmicro edtion,主要用於移動設備、嵌入式設備上的java應用程序

JreJava  Runtime  Enviromental】是java運行時環境,那麼所謂的java運行時環境,就是爲了保證java程序可以運行時,所必備的一基礎環境,也就是它只是保證java程序運行的,不能用來開發,而jdk纔是用來開發的,全部的Java程序都要在JRE下才能運行。包括JVMJAVA核心類庫和支持文件。與JDK相比,它不包含開發工具——編譯器、調試器和其它工具。

Jre裏邊包含jvm

Jvm:【Java Virtual Mechinal】由於jrejava運行時環境,java運行靠什麼運行,而底層就是依賴於jvm,即java虛擬機,java虛擬機用來加載類文件,java中之因此有跨平臺的做用,就是由於咱們的jvm

 

關係:

J2se是基於jdkjre

  JDK是整個JAVA的核內心邊包含了jre

  Jre裏邊包含jvm

 

 

抽象類與接口的區別

1.一個類只能進行單繼承,但能夠實現多個接口。

2.有抽象方法的類必定是抽象類,可是抽象類裏面不必定有抽象方法;

  接口裏面全部的方法的默認修飾符爲public abstract,接口裏的成員變量默認的修飾符爲  pulbic static final

       關係

接口和接口      繼承

接口和抽象類    抽象類實現接口

類和抽象類      類繼承抽象類

類和類          繼承

switch默認接受的幾種數據類型

Short, int, byte, char

 

反射的描述

經過字符串能夠動態建立java對象,而且能夠動態訪問方法,屬性等。

咱們在項目中的時候封裝過數據庫jdbc的持久層,其中就利用反射這項

技術來達到通用和靈活的目的。

 

1.4.HashtableHashMap的區別

HashMap不是線程安全的,HashTable是線程安全。

HashMap容許空(null)的鍵和值(key),HashTable則不容許。

HashMap性能優於Hashtable

 

Map

1.Map是一個以鍵值對存儲的接口。Map下有兩個具體的實現,分別是HashMap

 

HashTable.

2.HashMap是線程非安全的,HashTable是線程安全的,因此HashMap的效率高於

 

HashTable.

3.HashMap容許鍵或值爲空,而HashTable不容許鍵或值爲空.

jvm的類加載機制?  jvm中類的生命週期?

生命週期:加載、鏈接、初始化,使用,卸載

對象基本上都是在jvm的堆區中建立,在建立對象以前,

會觸發類加載(加載、鏈接、初始化),

當類初始化完成後,

根據類信息在堆中實例化類對象,

初始化非靜態變量、非靜態代碼以及默認構造方法,

當對象使用完以後會在合適的時候被jvm垃圾收集器回收。

 

要通過三步:加載(Load),連接(Link),初始化(Initializ)。

其中連接又可分爲校驗(Verify),準備(Prepare),解析(Resolve)三步。

ClassLoader就是用來裝載的。經過指定的className,找到二進制碼,

生成Class實例,放到JVM中。

Collection Collections 的區別?

Collection 是集合類的上級接口,繼承與他的接口主要有 Set List.

Collections 是針對集合類的一個幫助類,他提供一系列靜態方法實現對各類集合的搜索、排序、線程安全化等操做

數組爲何是查詢快?

由於數組的內存空間地址是連續的。ArrayList 底層維護了一個 Object[] 用於存儲對象,(源碼可查)默認數組的長度是 10。 能夠經過 new ArrayList(15)顯式的指定用於存儲對象的數組的長度。當默認的或者指定的容量不夠存儲對象的時候,容量自動增加爲原來的容量的 1.5 倍。因爲 ArrayList 是數組實現,在增和刪的時候會牽扯到數組增容, 以及拷貝元素, 因此慢。 數組是能夠直接按索引查找,因此查找時較快。能夠考慮,假設向數組的 0 角標未知添加元素,那麼原來的角標位置的元素須要總體日後移,而且數組可能還要增容,一旦增容,就須要要將老數組的內容拷貝到新數組中,因此數組的增刪的效率是很低的

Array ArrayList 有何區別?何時更適合用 Array

1. Array 能夠容納基本類型和對象,而 ArrayList 只能容納對象。

2. Array 是指定大小的,而 ArrayList 大小是固定的

ArrayList LinkedList 的存儲查找的優缺點?

1ArrayList 是採用動態數組來存儲元素的,它容許直接用下標號來直接查找對應的元素。可是,可是插入元素要涉及數組元素移動及內存的操做。總結:查找快,增刪慢。

2LinkedList 是採用雙向鏈表實現存儲,按序號索引數據須要進行前向或後向遍歷,可是插入數據時只須要記錄本項的先後項便可,因此插入速度較快。總結:增刪快,查找慢

HashSet 如何檢查重複?

HashSet 會經過元素的 hashcode()和

equals 方法進行判斷元素師否重複。

hashCode()equals()方法有何重要性?

HashMap 使用 Key 對象的 hashCode()equals()方法去決定 key-value

對的索引。當咱們試着從 HashMap 中獲取值的時候,這些方法也會被用到。若是這些方法沒有被正確地實現,在這種狀況下,兩個不一樣 Key 也許會產生相同的 hashCode()equals()輸出,HashMap 將會認爲它們是相同的,而後覆蓋它們,而非把它們存儲到不一樣的地方。一樣的,全部不容許存儲重複數據的集合類都使用 hashCode()equals()去查找重複,因此正確實現它們很是重要。 equals()hashCode()的實現應該遵循如下規則:

1)若是 o1.equals(o2),那麼 o1.hashCode() == o2.hashCode()老是爲

true 的。

2)若是 o1.hashCode() == o2.hashCode(),並不意味着 o1.equals(o2)會爲 true

爲什麼 Map 接口不繼承 Collection 接口?

儘管 Map 接口和它的實現也是集合框架的一部分,但 Map 不是集合,集合也不是 Map。所以,Map 繼承 Collection 毫無心義,反之亦然。若是 Map 繼承 Collection 接口,那麼元素去哪兒?Map 包含 keyvalue 對,它提供抽取 key value 列表集合的方法,可是它不適合「一組對象」規範

什麼是 HashMap?你爲何用到它?

譬如 HashMap 能夠接受 null 鍵值和值,而 Hashtable 則不能;HashMap 是非 synchronizedHashMap 很快;以及 HashMap 儲存的是鍵值對等等。

 

你知道 HashMap 的工做原理嗎?

HashMap 是基於 hashing(散列法)的原理,咱們使用 put(key, value)存儲對象到 HashMap 中,使用 get(key)HashMap 中獲取對象。當咱們給put()方法傳遞鍵和值時,咱們先對鍵調用 hashCode()方法,返回的hashCode 用於找到 bucket 位置來儲存 Entry 對象。 這裏關鍵點在於指出,HashMap 是在 bucket 中儲存鍵對象和值對象,做爲 Map.Entry。當兩個對象的 hashcode 相同會發生什麼?由於 hashcode 相同,因此它們的 bucket 位置相同,‘碰撞’會發生。由於 HashMap 使用鏈表存儲對象,這個 Entry(包含有鍵值對的 Map.Entry 對象)會存儲在鏈表中。」這個答案很是的合理,雖然有不少種處理碰撞的方法,這種方法是最簡單的,也正是 HashMap 的處理方法。若是兩個鍵的 hashcode 相同,你如何獲取值對象?當咱們調用 get()方法,HashMap 會使用鍵對象的 hashcode 找到bucket 位置,而後獲取值對象。 若是有兩個值對象儲存在同一個 bucket,那麼將會遍歷鏈表直到找到值對象。若是 HashMap 的大小超過了負載因子(load factor)定義的容量,怎麼辦?默認的負載因子大小爲 0.75,也就是說,當一個 map 填滿了 75%bucket 時候,和其它集合類(ArrayList)同樣,將會建立原來 HashMap大小的兩倍的 bucket 數組,來從新調整 map 的大小,並將原來的對象放入新的 bucket 數組中。這個過程叫做rehashing,由於它調用 hash 方法找到新的bucket 位置。你瞭解從新調整 HashMap 大小存在什麼問題嗎?當從新調整 HashMap 大小的時候,確實存在條件競爭,由於若是兩個線程都發現 HashMap 須要從新調整大小了,它們會同時試着調整大小。在調整大小的過程當中,存儲在鏈表中的元素的次序會反過來,由於移動到新的 bucket位置的時候,HashMap 並不會將元素放在鏈表的尾部,而是放在頭部,這是爲了不尾部遍歷(tail traversing)。若是條件競爭發生了,那麼就死循環了。這個時候,你能夠質問面試官,爲何這麼奇怪,要在多線程的環境下使用HashMap 呢?

 

Enumeration Iterator 接口的區別?

Enumeration 的速度是 Iterator 的兩倍,也使用更少的內存。

Enumeration 是很是基礎的,也知足了基礎的須要。可是,與 Enumeration相比,Iterator 更加安全,由於當一個集合正在被遍歷的時候,它會阻止其它線程去修改集合。迭代器取代了 Java 集合框架中的 Enumeration。迭代器容許調用者從集合中移除元素,而 Enumeration 不能作到。爲了使它的功能更加清晰,迭代器方法名已經通過改善。

 

Java內存模型:

Java虛擬機規範中將Java運行時數據分爲六種。

1.程序計數器: 是一個數據結構, 用於保存當前正常執行的程序的內存地址。 Java虛擬機的多線程就是經過線程輪流切換並分配處理器時間來實現的,爲了線程切換後能恢復到正確的位置, 每條線程都須要一個獨立的程序計數器, 互不影響, 該區域爲「線程私有」。

2.Java虛擬機棧: 線程私有的, 與線程生命週期相同, 用於存儲局部變量表, 操做棧, 方法返回值。 局部變量表放着基本數據類型, 還有對象的引用。

3.本地方法棧: 跟虛擬機棧很像, 不過它是爲虛擬機使用到的Native方法服務。

4.Java堆: 全部線程共享的一塊內存區域, 對象實例幾乎都在這分配內存。

5.方法區: 各個線程共享的區域, 儲存虛擬機加載的類信息, 常量, 靜態變量, 編譯後的代碼。

6.運行時常量池: 表明運行時每一個class文件中的常量表。 包括幾種常量: 編譯時的數字常量、 方法或者域的引用。

 

java GC是在何時, 對什麼東西, 作了什麼事情? 」

在何時:

1.新生代有一個Eden區和兩個survivor區, 首先將對象放入Eden區, 若是空間不足就向其中的一個survivor區上放, 若是仍然放不下就會引起一次發生

在新生代的minor GC, 將存活的對象放入另外一個survivor區中, 而後清空Eden和以前的那個survivor區的內存。 在某次GC過程當中, 若是發現仍然又放

不下的對象, 就將這些對象放入老年代內存裏去。

2.大對象以及長期存活的對象直接進入老年區。

3.當每次執行minor GC的時候應該對要晉升到老年代的對象進行分析, 若是這些立刻要到老年區的老年對象的大小超過了老年區的剩餘大小, 那麼執

行一次Full GC以儘量地得到老年區的空間。

對什麼東西: GC Roots搜索不到, 並且通過一次標記清理以後仍沒有復活的對象。

作什麼: 新生代: 複製清理; 老年代: 標記-清除和標記-壓縮算法; 永久代: 存放Java中的類和加載類的類加載器自己。

GC Roots都有哪些:

1. 虛擬機棧中的引用的對象

2. 方法區中靜態屬性引用的對象, 常量引用的對象

3. 本地方法棧中JNI(即通常說的Native方法) 引用的對象

 

1Java 中能建立 Volatile 數組嗎?

能, Java 中能夠建立 volatile 類型數組, 不過只是一個指向數組的引用, 而不是整個數組。 個人意思是, 若是改變引用指向的數組, 將會受到 volatile 的保護, 可是若是多個線程同時改變數組的元素, volatile 標示符就不能起到以前的保護做用了。

2volatile 能使得一個非原子操做變成原子操做嗎

一個典型的例子是在類中有一個 long 類型的成員變量。若是你知道該成員變量會被多個線程訪問, 如計數器、 價格等, 你最好是將其設置爲 volatile。 爲何? 由於 Java 中讀取long 類型變量不是原子的, 須要分紅兩步, 若是一個線程正在修改該 long 變量的值, 另外一個線程可能只能看到該值的一半(前 32 位) 。 可是對一個 volatile 型的 long double 變量的讀寫是原子。

3volatile 修飾符的有過什麼實踐?

一種實踐是用 volatile 修飾 long double 變量,使其能按原子類型來讀寫。double long 都是 64 位寬, 所以對這兩種類型的讀是分爲兩部分的, 第一次讀取第一個 32 位, 而後再讀剩下的 32 位, 這個過程不是原子的, 但 Java volatile 型的 long double

變量的讀寫是原子的。 volatile 修復符的另外一個做用是提供內存屏障(memory barrier) ,

例如在分佈式框架中的應用。 簡單的說, 就是當你寫一個 volatile 變量以前, Java 內存模型會插入一個寫屏障(write barrier) , 讀一個 volatile 變量以前, 會插入一個讀屏

障(read barrier) 。 意思就是說, 在你寫一個 volatile 域時, 能保證任何線程都能看到

你寫的值, 同時, 在寫以前, 也能保證任何數值的更新對全部線程是可見的, 由於內存屏障會將其餘全部寫的值更新到緩存。

4volatile 類型變量提供什麼保證? (答案)

volatile 變量提供順序和可見性保證, 例如, JVM 或者 JIT 爲了得到更好的性能會對語句重排序, 可是 volatile 類型變量即便在沒有同步塊的狀況下賦值也不會與其餘語句重排序。 volatile 提供 happens-before 的保證,確保一個線程的修改能對其餘線程是可見的。

某些狀況下, volatile 還能提供原子性, 如讀 64 位數據類型, 像 long double 都不

是原子的, volatile 類型的 double long 就是原子的。

5) 10 個線程和 2 個線程的同步代碼, 哪一個更容易寫?

從寫代碼的角度來講, 二者的複雜度是相同的, 由於同步代碼與線程數量是相互獨立的。 可是同步策略的選擇依賴於線程的數量, 由於越多的線程意味着更大的競爭, 因此你須要利用同步技術, 如鎖分離, 這要求更復雜的代碼和專業知識。

6) 你是如何調用 wait() 方法的? 使用 if 塊仍是循環? 爲何? (答案)

wait() 方法應該在循環調用, 由於當線程獲取到 CPU 開始執行的時候, 其餘條件可能尚未知足, 因此在處理前, 循環檢測條件是否知足會更好。 下面是一段標準的使用 wait notify 方法的代碼:

// The standard idiom for using the wait method

synchronized (obj) {while (condition does not hold)

obj.wait(); // (Releases lock, and reacquires on wakeup)

... // Perform action appropriate to condition

} 參見 Effective Java 69 條, 獲取更多關於爲何應該在循環中來調用 wait 方法的內

容。

7) 什麼是多線程環境下的僞共享(false sharing) ?

僞共享是多線程系統(每一個處理器有本身的局部緩存) 中一個衆所周知的性能問題。 僞共享發生在不一樣處理器的上的線程對變量的修改依賴於相同的緩存行, 以下圖所示:僞共享有經驗程序員的 Java 面試題僞共享問題很難被發現, 由於線程可能訪問徹底不一樣的全局變量, 內存中卻碰巧在很相近的位置上。 如其餘諸多的併發問題, 避免僞共享的最基本方式是仔細審查代碼, 根據緩存行來調整你的數據結構。

8) 什麼是 Busy spin? 咱們爲何要使用它?

Busy spin 是一種在不釋放 CPU 的基礎上等待事件的技術。 它常常用於避免丟失 CPU 緩存中的數據(若是線程先暫停, 以後在其餘 CPU 上運行就會丟失) 。 因此, 若是你的工做要求低延遲, 而且你的線程目前沒有任何順序, 這樣你就能夠經過循環檢測隊列中的新消息來代替調用 sleep() wait() 方法。 它惟一的好處就是你只需等待很短的時間, 如幾微秒或幾 納 秒 。 LMAX 分 布 式 框 架 是 一 個 高 性 能 線 程 間 通 信 的 庫 , 該 庫 有 一 個BusySpinWaitStrategy 類 就 是 基 於 這 個 概 念 實 現 的 , 使 用 busy spin 循 環EventProcessors 等待屏障。

9Java 中怎麼獲取一份線程 dump 文件?

Linux 下, 你能夠經過命令 kill -3 PID Java 進程的進程 ID) 來獲取 Java 應用的dump 文件。 在 Windows 下, 你能夠按下 Ctrl + Break 來獲取。 這樣 JVM 就會將線程的dump 文件打印到標準輸出或錯誤文件中, 它可能打印在控制檯或者日誌文件中, 具體位置依賴應用的配置。 若是你使用 Tomcat

10Swing 是線程安全的? (答案)

不是, Swing 不是線程安全的。 你不能經過任何線程來更新 Swing 組件, 如 JTableJListJPanel, 事實上, 它們只能經過 GUI AWT 線程來更新。 這就是爲何 Swing 提供invokeAndWait() invokeLater() 方法來獲取其餘線程的 GUI 更新請求。這些方法將更新請求放入 AWT 的線程隊列中, 能夠一直等待, 也能夠經過異步更新直接返回結果。 你也能夠在參考答案中查看和學習到更詳細的內容。

11) 什麼是線程局部變量? (答案)

線程局部變量是侷限於線程內部的變量, 屬於線程自身全部, 不在多個線程間共享。 Java 提供 ThreadLocal 類來支持線程局部變量, 是一種實現線程安全的方式。 可是在管理環境下(如 web 服務器) 使用線程局部變量的時候要特別當心, 在這種狀況下, 工做線程的生命週期比任何應用變量的生命週期都要長。 任何線程局部變量一旦在工做完成後沒有釋放,Java 應用就存在內存泄露的風險。

12) 用 wait-notify 寫一段代碼來解決生產者-消費者問題? (答案)

請參考答案中的示例代碼。 只要記住在同步塊中調用 wait() notify()方法, 若是阻塞,經過循環來測試等待條件。

13) Java 寫一個線程安全的單例模式(Singleton (答案)

請參考答案中的示例代碼, 這裏面一步一步教你建立一個線程安全的 Java 單例類。 當咱們說線程安全時, 意思是即便初始化是在多線程環境中, 仍然能保證單個實例。 Java 中, 使用枚舉做爲單例類是最簡單的方式來建立線程安全單例模式的方式。

14Java sleep 方法和 wait 方法的區別? (答案)

雖然二者都是用來暫停當前運行的線程, 可是 sleep() 實際上只是短暫停頓, 由於它不會

釋放鎖, wait() 意味着條件等待, 這就是爲何該方法要釋放鎖, 由於只有這樣, 其餘等待的線程才能在知足條件時獲取到該鎖。

15) 什麼是不可變對象(immutable object) ? Java 中怎麼建立一個不可變對象? (答案)

不可變對象指對象一旦被建立, 狀態就不能再改變。 任何修改都會建立一個新的對象, StringInteger 及其它包裝類。 詳情參見答案, 一步一步指導你在 Java 中建立一個不可變的類。

16) 咱們能建立一個包含可變對象的不可變對象嗎

是的, 咱們是能夠建立一個包含可變對象的不可變對象的, 你只須要謹慎一點, 不要共享可變對象的引用就能夠了, 若是須要變化時, 就返回原對象的一個拷貝。 最多見的例子就是對象中包含一個日期對象的引用。

數據類型和 Java 基礎面試問題

17Java 中應該使用什麼數據類型來表明價格? (答案)

若是不是特別關心內存和性能的話, 使用 BigDecimal, 不然使用預約義精度的 double 類型。

18怎麼將 byte 轉換爲 String (答案)

能夠使用 String 接收 byte[] 參數的構造器來進行轉換, 須要注意的點是要使用的正確的編碼, 不然會使用平臺默認編碼, 這個編碼可能跟原來的編碼相同, 也可能不一樣。

19Java 中怎樣將 bytes 轉換爲 long 類型?

20咱們能將 int 強制轉換爲 byte 類型的變量嗎? 若是該值大於 byte 類型的範圍, 將

會出現什麼現象?

是的, 咱們能夠作強制轉換, 可是 Java int 32 位的, 而 byte 8 位的, 因此,若是強制轉化是, int 類型的高 24 位將會被丟棄, byte 類型的範圍是從 -128 128

21存在兩個類, B 繼承 AC 繼承 B, 咱們能將 B 轉換爲 C 麼?  C = (C) B(answer

答案)

22哪一個類包含 clone 方法? 是 Cloneable 仍是 Object (答案)

java.lang.Cloneable 是一個標示性接口, 不包含任何方法, clone 方法在 object 類中定

義。 而且須要知道 clone() 方法是一個本地方法, 這意味着它是由 c c++ 或 其餘本地語言實現的。

23 Java ++ 操做符是線程安全的嗎? (答案)

不是線程安全的操做。 它涉及到多個指令, 如讀取變量值, 增長, 而後存儲回內存, 這個過程可能會出現多個線程交差。

24a = a + b a += b 的區別(答案)

+= 隱式的將加操做的結果類型強制轉換爲持有結果的類型。若是兩這個整型相加,如 byteshort 或者 int, 首先會將它們提高到 int 類型, 而後在執行加法操做。 若是加法操做的結果比 a 的最大值要大, 則 a+b 會出現編譯錯誤, 可是 a += b 沒問題, 以下:

byte a = 127;

byte b = 127;

b = a + b; // error : cannot convert from int to byte

b += a; // ok

(譯者注:這個地方應該表述的有誤,其實不管 a+b 的值爲多少,編譯器都會報錯,由於 a+b

操做會將 ab 提高爲 int 類型, 因此將 int 類型賦值給 byte 就會編譯出錯)

25我能在不進行強制轉換的狀況下將一個 double 值賦值給 long 類型的變量嗎? (答案)

不行, 你不能在沒有強制類型轉換的前提下將一個 double 值賦值給 long 類型的變量, 由於 double 類型的範圍比 long 類型更廣, 因此必需要進行強制轉換。

263*0.1 == 0.3 將會返回什麼? true 仍是 false(答案)

false, 由於有些浮點數不能徹底精確的表示出來。

27int Integer 哪一個會佔用更多的內存? (答案)

Integer 對象會佔用更多的內存。 Integer 是一個對象, 須要存儲對象的元數據。 可是 int是一個原始類型的數據, 因此佔用的空間更少。

28) 爲何 Java 中的 String 是不可變的(Immutable) ? (answer 答案)

Java 中的 String 不可變是由於 Java 的設計者認爲字符串使用很是頻繁, 將字符串設置爲不可變能夠容許多個客戶端之間共享相同的字符串。 更詳細的內容參見答案。

29咱們能在 Switch 中使用 String 嗎? (answer 答案)

Java 7 開始, 咱們能夠在 switch case 中使用字符串, 但這僅僅是一個語法糖。 內部實如今 switch 中使用字符串的 hash code

30Java 中的構造器鏈是什麼? (answer 答案)

當你從一個構造器中調用另外一個構造器, 就是 Java 中的構造器鏈。 這種狀況只在重載了類的構造器的時候纔會出現。JVM 底層 與 GCGarbage Collection) 的面試問題

31 64 JVM 中, int 的長度是多數?

Java 中, int 類型變量的長度是一個固定值, 與平臺無關, 都是 32 位。 意思就是說, 在 32位 和 64 位 的 Java 虛擬機中, int 類型的長度是相同的。

32Serial Parallel GC 之間的不一樣之處? (答案)

Serial Parallel GC 執行的時候都會引發 stop-the-world。 它們之間主要不一樣serial 收集器是默認的複製收集器, 執行 GC 的時候只有一個線程, 而 parallel 收集器

使用多個 GC 線程來執行。

3332 位和 64 位的 JVMint 類型變量的長度是多數? (答案)

32 位和 64 位的 JVM 中, int 類型變量的長度是相同的, 都是 32 位或者 4 個字節。

34Java WeakReference SoftReference 的區別? (答案)

WeakReference SoftReference 都 有 利 於 提 高 GC 和 內 存 的 效 率 , 但 是WeakReference , 一旦失去最後一個強引用, 就會被 GC 回收, 而軟引用雖然不能阻止被回收, 可是能夠延遲到 JVM 內存不足的時候。

35WeakHashMap 是怎麼工做的? (答案)

WeakHashMap 的工做與正常的 HashMap 相似, 可是使用弱引用做爲 key, 意思就是當 key對象沒有任何引用時, key/value 將會被回收。

36JVM 選項 -XX:+UseCompressedOops 有什麼做用? 爲何要使用? (答案)

當你將你的應用從 32 位的 JVM 遷移到 64 位的 JVM 時, 因爲對象的指針從 32 位增長到了 64 位, 所以堆內存會忽然增長, 差很少要翻倍。 這也會對 CPU 緩存(容量比內存小不少) 的數據產生不利的影響。 由於, 遷移到 64 位的 JVM 主要動機在於能夠指定最大堆大小, 經過壓縮 OOP 能夠節省必定的內存。 經過 -XX:+UseCompressedOops 選項, JVM 會使用 32 位的 OOP, 而不是 64 位的 OOP

37) 怎樣經過 Java 程序來判斷 JVM 32 位 仍是 64 位? (答案)

你能夠檢查某些系統屬性如 sun.arch.data.model os.arch 來獲取該信息。

3832 JVM 64 JVM 的最大堆內存分別是多數? (答案)

理論上說上 32 位的 JVM 堆內存能夠到達 2^32, 即 4GB, 但實際上會比這個小不少。 不一樣操做系統之間不一樣, 如 Windows 系統大約 1.5 GBSolaris 大約 3GB64 JVM 容許指定最大的堆內存, 理論上能夠達到 2^64, 這是一個很是大的數字, 實際上你能夠指定堆內存大小到 100GB。 甚至有的 JVM, 如 Azul, 堆內存到 1000G 都是可能的。

39JREJDKJVM JIT 之間有什麼不一樣? (答案)

JRE 表明 Java 運行時(Java run-time) , 是運行 Java 引用所必須的。 JDK 表明 Java 開發工具(Java development kit) , 是 Java 程序的開發工具, 如 Java 編譯器, 它也包含JREJVM 表明 Java 虛擬機(Java virtual machine) , 它的責任是運行 Java 應用。 JIT

表明即時編譯(Just In Time compilation) , 當代碼執行的次數超過必定的閾值時, 會將

Java 字節碼轉換爲本地代碼, 如, 主要的熱點代碼會被準換爲本地代碼, 這樣有利大幅度提升 Java 應用的性能。

最近 5 133 Java 面試問題列表 ----3 年工做經驗的 Java 面試題

40解釋 Java 堆空間及 GC(答案)

當經過 Java 命令啓動 Java 進程的時候, 會爲它分配內存。內存的一部分用於建立堆空間,當程序中建立對象的時候, 就從對空間中分配內存。 GC JVM 內部的一個進程, 回收無效對象的內存用於未來的分配。

JVM 底層面試題及答案

41你能保證 GC 執行嗎? (答案)

不能, 雖然你能夠調用 System.gc() 或者 Runtime.gc(), 可是沒有辦法保證 GC 的執行。

42怎麼獲取 Java 程序使用的內存? 堆使用的百分比

能夠經過 java.lang.Runtime 類中與內存相關方法來獲取剩餘的內存, 總內存及最大堆內存 。 通 過 這 些 方 法 你 也 可 以 獲 取 到 堆 使 用 的 百 分 比 及 堆 內 存 的 剩 餘 空 間 。Runtime.freeMemory() 方法返回剩餘空間的字節數, Runtime.totalMemory() 方法總內存的字節數, Runtime.maxMemory() 返回最大內存的字節數。

43Java 中堆和棧有什麼區別? (答案)

JVM 中堆和棧屬於不一樣的內存區域, 使用目的也不一樣。 棧經常使用於保存方法幀和局部變量, 而對象老是在堆上分配。 棧一般都比堆小, 也不會在多個線程之間共享, 而堆被整個 JVM 的全部線程共享。

關於內存的的面試問題和答案----Java 基本概念面試題

44) 「a==b」 和」 a.equals(b)」 有什麼區別? (答案)

若是 a b 都是對象, 則 a==b 是比較兩個對象的引用, 只有當 a b 指向的是堆中的同一個對象纔會返回 true, 而 a.equals(b) 是進行邏輯比較, 因此一般須要重寫該方法來提供邏輯一致性的比較。 例如, String 類重寫 equals() 方法, 因此能夠用於兩個不一樣對象, 可是包含的字母相同的比較。

45a.hashCode() 有什麼用? 與 a.equals(b) 有什麼關係? (答案)

hashCode() 方 法 是 相 應 對 象 整 型 的 hash 值 。 它 常 用 於 基 於 hash 的 集 合 類 , 如HashtableHashMapLinkedHashMap 等等。 它與 equals() 方法關係特別緊密。 根據 Java規範, 兩個使用 equal() 方法來判斷相等的對象, 必須具備相同的 hash code

46finalfinalize finally 的不一樣之處? (答案)

final 是一個修飾符, 能夠修飾變量、 方法和類。 若是 final 修飾變量, 意味着該變量的值在初始化後不能被改變。 finalize 方法是在對象被回收以前調用的方法, 給對象本身最後一個復活的機會,可是何時調用 finalize 沒有保證。finally 是一個關鍵字,與 try

catch 一塊兒用於異常的處理。 finally 塊必定會被執行, 不管在 try 塊中是否有發生異

常。

47Java 中的編譯期常量是什麼? 使用它又什麼風險?

公共靜態不可變(public static final )變量也就是咱們所說的編譯期常量, 這裏的 public

可選的。 實際上這些變量在編譯時會被替換掉, 由於編譯器知道這些變量的值, 而且知道這些變量在運行時不能改變。這種方式存在的一個問題是你使用了一個內部的或第三方庫中的公有編譯時常量, 可是這個值後面被其餘人改變了, 可是你的客戶端仍然在使用老的值, 甚至你已經部署了一個新的 jar。 爲了不這種狀況, 當你在更新依賴 JAR 文件時, 確保從新編譯你的程序。

Java 集合框架的面試題----這部分也包含數據結構、 算法及數組的面試問題

48) ListSetMap Queue 之間的區別(答案)

List 是一個有序集合, 容許元素重複。 它的某些實現能夠提供基於下標值的常量訪問時間,可是這不是 List 接口保證的。 Set 是一個無序集合。

49poll() 方法和 remove() 方法的區別?

poll() remove() 都是從隊列中取出一個元素, 可是 poll() 在獲取元素失敗的時候會

返回空, 可是 remove() 失敗的時候會拋出異常。

50Java LinkedHashMap PriorityQueue 的區別是什麼? (答案)

PriorityQueue 保證最高或者最低優先級的的元素老是在隊列頭部, 可是 LinkedHashMap維持的順序是元素插入的順序。 當遍歷一個 PriorityQueue 時, 沒有任何順序保證, 可是LinkedHashMap 課保證遍歷順序是元素插入的順序。

51ArrayList LinkedList 的不區別? (答案)

最明顯的區別是 ArrrayList 底層的數據結構是數組, 支持隨機訪問, 而 LinkedList 的底層數據結構書鏈表, 不支持隨機訪問。 使用下標訪問一個元素, ArrayList 的時間複雜度是O(1), 而 LinkedList O(n)。 更多細節的討論參見答案。

52) 用哪兩種方式來實現集合的排序? (答案)

你能夠使用有序集合, TreeSet TreeMap, 你也能夠使用有順序的的集合, 如 list,而後經過 Collections.sort() 來排序。

53 Java 中怎麼打印數組? (answer 答案)

你能夠使用 Arrays.toString() Arrays.deepToString() 方法來打印數組。因爲數組沒

有實現 toString() 方法, 因此若是將數組傳遞給 System.out.println() 方法, 將沒法打

印出數組的內容, 可是 Arrays.toString() 能夠打印每一個元素。

54Java 中的 LinkedList 是單向鏈表仍是雙向鏈表? (答案)

是雙向鏈表, 你能夠檢查 JDK 的源碼。 在 Eclipse, 你能夠使用快捷鍵 Ctrl + T, 直接在編輯器中打開該類。

55Java 中的 TreeMap 是採用什麼樹實現的? (答案)

Java 中的 TreeMap 是使用紅黑樹實現的。

56) Hashtable HashMap 有什麼不一樣之處? (答案)

這兩個類有許多不一樣的地方, 下面列出了一部分:

a) Hashtable JDK 1 遺留下來的類, 而 HashMap 是後來增長的。

bHashtable 是同步的, 比較慢, 但 HashMap 沒有同步策略, 因此會更快。

cHashtable 不容許有個空的 key, 可是 HashMap 容許出現一個 null key

更多的不一樣之處參見答案。

57 Java 中的 HashSet, 內部是如何工做的? (answer 答案)

HashSet 的內部採用 HashMap 來實現。 因爲 Map 須要 key value, 因此全部 key 的都有一個默認 value。 相似於 HashMapHashSet 不容許重複的 key, 只容許有一個 null key,意思就是 HashSet 中只容許存儲一個 null 對象。

58) 寫一段代碼在遍歷 ArrayList 時移除一個元素? (答案)

該問題的關鍵在於面試者使用的是 ArrayList remove() 仍是 Iterator remove()方法。 這有一段示例代碼, 是使用正確的方式來實如今遍歷的過程當中移除元素, 而不會出現ConcurrentModificationException 異常的示例代碼。

59咱們能本身寫一個容器類, 而後使用 for-each 循環碼?

能夠, 你能夠寫一個本身的容器類。 若是你想使用 Java 中加強的循環來遍歷, 你只須要實現 Iterable 接口。 若是你實現 Collection 接口, 默認就具備該屬性。

60ArrayList HashMap 的默認大小是多數? (答案)

Java 7 中, ArrayList 的默認大小是 10 個元素, HashMap 的默認大小是 16 個元素(必須是 2 的冪) 。 這就是 Java 7 ArrayList HashMap 類的代碼片斷:

// from ArrayList.java JDK 1.7

private static final int DEFAULT_CAPACITY = 10;

//from HashMap.java JDK 7

static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16

61) 有沒有可能兩個不相等的對象有有相同的 hashcode

有可能, 兩個不相等的對象可能會有相同的 hashcode 值, 這就是爲何在 hashmap 中會

有衝突。 相等 hashcode 值的規定只是說若是兩個對象相等, 必須有相同的 hashcode 值,

可是沒有關於不相等對象的任何規定。

62) 兩個相同的對象會有不一樣的的 hash code 嗎?

不能, 根據 hash code 的規定, 這是不可能的。

63) 咱們能夠在 hashcode() 中使用隨機數字嗎? (答案)

不行, 由於對象的 hashcode 值必須是相同的。 參見答案獲取更多關於 Java 中重寫

hashCode() 方法的知識。

64Java 中, Comparator Comparable 有什麼不一樣? (答案)

Comparable 接口用於定義對象的天然順序,而 comparator 一般用於定義用戶定製的順序。

Comparable 老是隻有一個, 可是能夠有多個 comparator 來定義對象的順序。

65) 爲何在重寫 equals 方法的時候須要重寫 hashCode 方法? (答案)

由於有強制的規範指定須要同時重寫 hashcode equal 是方法, 許多容器類, 如

HashMapHashSet 都依賴於 hashcode equals 的規定。

Java IO NIO 的面試題

IO Java 面試中一個很是重要的點。 你應該很好掌握 Java IONIONIO2 以及與操做

系統, 磁盤 IO 相關的基礎知識。 下面是 Java IO 中常常問的問題。

66) 在我 Java 程序中, 我有三個 socket, 我須要多少個線程來處理?

67Java 中怎麼建立 ByteBuffer

ByteBuffer.allocate(250) -- 新建byteBuffer

bb.wrap(new byte[100]) -- 新建byteBuffer

68Java 中, 怎麼讀寫 ByteBuffer

put方法寫 -- 入緩衝區

get方法  -- 讀取緩衝區

69Java 採用的是大端仍是小端?

大端模式,是指數據的高字節保存在內存的低地址中,而數據的低字節保存在內存的高地址中,這樣的存儲模式有點兒相似於把數據看成字符串順序處理:地址由小向大增長,而數據從高位往低位放;

小端模式,是指數據的高字節保存在內存的高地址中,而數據的低字節保存在內存的低地址中,這種存儲模式將地址的高低和數據位權有效地結合起來,高地址部分權值高,低地址部分權值低,和咱們的邏輯方法一致。

存儲量大於1字節,非char類型,如intfloat等,要考慮字節的順序問題了。java因爲虛擬機的關係,屏蔽了大小端問題,須要知道的話可用 ByteOrder.nativeOrder() 查詢。在操做ByteBuffer中,也能夠使用 ByteBuffer.order() 進行設置:

70ByteBuffer 中的字節序是什麼?

字節序分爲兩種:

BIG-ENDIAN----大字節序

LITTLE-ENDIAN----小字節序

BIG-ENDIANLITTLE-ENDIAN與多字節類型的數據有關的好比int,short,long型,而對單字節數據byte卻沒有影響。

BIG-ENDIAN就是最低地址存放最高有效字節。

LITTLE-ENDIAN是最低地址存放最低有效字節。即常說的低位在先,高位在後。

71Java 中, 直接緩衝區與非直接緩衝器有什麼區別? (答案)

BufferedOutputStream與任何一個OutputStream相同,除了用一個另外的flush( ) 方法來保證數據緩衝器被寫入到實際的輸出設備。由於BufferedOutputStream是經過減少系統寫數據的時間而提升性能的,能夠調用flush( )方法生成緩衝器中待寫的數據。

72Java 中的內存映射緩存區是什麼? (answer 答案)

 

73socket 選項 TCP NO DELAY 是指什麼?

在默認狀況下,客戶端向服務器發送數據時,會根據數據包的大小決定是否當即發送。當數據包中的數據不多時,如只有1個字節,而數據包的頭卻有幾十個字節(IP+TCP頭)時,系統會在發送以前先將較小的包合併到軟大的包後,一塊兒將數據發送出去。在發送下一個數據包時,系統會等待服務器對前一個數據包的響應,當收到服務器的響應後,再發送下一個數據包,這就是所謂的Nagle算法;在默認狀況下,Nagle算法是開啓的。

    這種算法雖然能夠有效地改善網絡傳輸的效率,但對於網絡速度比較慢,並且對實現性的要求比較高的狀況下(如遊戲、Telnet等),使用這種方式傳輸數據會使得客戶端有明顯的停頓現象。所以,最好的解決方案就是須要Nagle算法時就使用它,不須要時就關閉它。而使用setTcpToDelay正好能夠知足這個需求。當使用setTcpNoDelaytrue)將Nagle算法關閉後,客戶端每發送一次數據,不管數據包的大小都會將這些數據發送出去。

74TCP 協議與 UDP 協議有什麼區別? (answer 答案)

小結TCPUDP的區別:

1.基於鏈接與無鏈接;

2.對系統資源的要求(TCP較多,UDP少);

3.UDP程序結構較簡單;

4.流模式與數據報模式 ;

5.TCP保證數據正確性,UDP可能丟包,TCP保證數據順序,UDP不保證。

75Java 中, ByteBuffer StringBuffer 有什麼區別? (答案)

Java 最佳實踐的面試問題

包含 Java 中各個部分的最佳實踐, 如集合, 字符串, IO, 多線程, 錯誤和異常處理, 設計模式等等。

76Java 中, 編寫多線程程序的時候你會遵循哪些最佳實踐? (答案)

這是我在寫 Java 併發程序的時候遵循的一些最佳實踐:

a) 給線程命名, 這樣能夠幫助調試。

b) 最小化同步的範圍, 而不是將整個方法同步, 只對關鍵部分作同步。

c) 若是能夠, 更偏向於使用 volatile 而不是 synchronized

d) 使用更高層次的併發工具, 而不是使用 wait() notify() 來實現線程間通訊, 如

BlockingQueueCountDownLatch Semeaphore

e) 優先使用併發集合, 而不是對集合進行同步。 併發集合提供更好的可擴展性。

77) 說出幾點 Java 中使用 Collections 的最佳實踐(答案)

這是我在使用 Java Collectionc 類的一些最佳實踐:

a) 使用正確的集合類, 例如, 若是不須要同步列表, 使用 ArrayList 而不是 Vector

b) 優先使用併發集合, 而不是對集合進行同步。 併發集合提供更好的可擴展性。

c)使用接口表明和訪問集合, 如使用 List 存儲 ArrayList, 使用 Map 存儲 HashMap 等等。

d) 使用迭代器來循環集合。

e) 使用集合的時候使用泛型。

78) 說出至少 5 點在 Java 中使用線程的最佳實踐。 (答案)

這個問題與以前的問題相似, 你能夠使用上面的答案。 對線程來講, 你應該:

a) 對線程命名

b) 將線程和任務分離, 使用線程池執行器來執行 Runnable Callable

c) 使用線程池

79) 說出 5 IO 的最佳實踐(答案)

IO Java 應用的性能很是重要。理想狀況下,你不該該在你應用的關鍵路徑上避免 IO

做。 下面是一些你應該遵循的 Java IO 最佳實踐:

a) 使用有緩衝區的 IO 類, 而不要單獨讀取字節或字符。

b) 使用 NIO NIO2

c) 在 finally 塊中關閉流, 或者使用 try-with-resource 語句。

d) 使用內存映射文件獲取更快的 IO

80) 列出 5 個應該遵循的 JDBC 最佳實踐(答案)

有不少的最佳實踐, 你能夠根據你的喜愛來例舉。 下面是一些更通用的原則:

a) 使用批量的操做來插入和更新數據

b) 使用 PreparedStatement 來避免 SQL 異常, 並提升性能。

c) 使用數據庫鏈接池

d) 經過列名來獲取結果集, 不要使用列的下標來獲取。

81) 說出幾條 Java 中方法重載的最佳實踐? (答案)

下面有幾條能夠遵循的方法重載的最佳實踐來避免形成自動裝箱的混亂。

a) 不要重載這樣的方法: 一個方法接收 int 參數, 而另個方法接收 Integer 參數。

b) 不要重載參數數量一致, 而只是參數順序不一樣的方法。

c) 若是重載的方法參數個數多於 5 個, 採用可變參數。

DateTime Calendar 的面試題

82) 在多線程環境下, SimpleDateFormat 是線程安全的嗎? (答案)

不是, 很是不幸, DateFormat 的全部實現, 包括 SimpleDateFormat 都不是線程安全的,

所以你不該該在多線程序中使用, 除非是在對外線程安全的環境中使用, SimpleDateFormat 限制在 ThreadLocal 中。 若是你不這麼作, 在解析或者格式化日期的時

候, 可能會獲取到一個不正確的結果。 所以, 從日期、 時間處理的全部實踐來講, 我強力推

joda-time 庫。

83Java 中如何格式化一個日期? 如格式化爲 ddMMyyyy 的形式? (答案)

Java 中, 能夠使用 SimpleDateFormat 類或者 joda-time 庫來格式日期。 DateFormat

容許你使用多種流行的格式來格式化日期。 參見答案中的示例代碼, 代碼中演示了將日期格

式化成不一樣的格式, dd-MM-yyyy ddMMyyyy

84Java 中, 怎麼在格式化的日期中顯示時區? (答案)

其實在格式化的加上Z,表示的就是時區!

85Java java.util.Date java.sql.Date 有什麼區別? (答案)

java.util.Date 就是在除了SQL語句的狀況下面使用

java.sql.Date 是針對SQL語句使用的,它只包含日期而沒有時間部分

轉換是

java.sql.Date date = new Java.sql.Date();

java.util.Date sqlDate = new java.util.Date (date.getTime());

直接說就是:java.sql.Date就是與數據庫Date相對應的一個類型,而java.util.Date是純javaDate

87Java 中, 如何將字符串 YYYYMMDD 轉換爲日期? (答案)

單元測試 JUnit 面試題

89) 如何測試靜態方法? (答案)

能夠使用 PowerMock 庫來測試靜態方法。

90) 怎麼利用 JUnit 來測試一個方法的異常? (答案)

91) 你使用過哪一個單元測試庫來測試你的 Java 程序? (答案)

92@Before @BeforeClass 有什麼區別? (答案)

@Before:初始化方法   對於每個測試方法都要執行一次(注意與BeforeClass區別,後者是對於全部方法執行一次)

@After:釋放資源  對於每個測試方法都要執行一次(注意與AfterClass區別,後者是對於全部方法執行一次)

@Test:測試方法,在這裏能夠測試指望異常和超時時間

@Test(expected=ArithmeticException.class)檢查被測方法是否拋出ArithmeticException異常

@Ignore:忽略的測試方法

@BeforeClass:針對全部測試,只執行一次,且必須爲static void

@AfterClass:針對全部測試,只執行一次,且必須爲static void

一個JUnit4的單元測試用例執行順序爲:

@BeforeClass -> @Before -> @Test -> @After -> @AfterClass;

每個測試方法的調用順序爲:

@Before -> @Test -> @After;

編程和代碼相關的面試題

93) 怎麼檢查一個字符串只包含數字? (解決方案)

1、用JAVA自帶的函數

public static boolean isNumeric(String str){

  for (int i = str.length();--i>=0;){   

   if (!Character.isDigit(str.charAt(i))){

       return false;

     }

    }

  return true;

 }

 

94Java 中如何利用泛型寫一個 LRU 緩存? (答案<)

95) 寫一段 Java 程序將 byte 轉換爲 long(答案)

95) 在不使用 StringBuffer 的前提下, 怎麼反轉一個字符串? (解決方案)

97Java 中, 怎麼獲取一個文件中單詞出現的最高頻率? (解決方案)

98) 如何檢查出兩個給定的字符串是反序的? (解決方案)

99Java 中, 怎麼打印出一個字符串的全部排列? (解決方案)

100Java 中, 怎樣才能打印出數組中的重複元素? (解決方案)

101Java 中如何將字符串轉換爲整數? (解決方案)

102) 在沒有使用臨時變量的狀況如何交換兩個整數變量的值? (解決方案)

關於 OOP 和設計模式的面試題

這部分包含 Java 面試過程當中關於 SOLID 的設計原則, OOP 基礎, 如類, 對象, 接口, 繼

承, 多態, 封裝, 抽象以及更高級的一些概念, 如組合、 聚合及關聯。 也包含了 GOF 設計

模式的問題。

103) 接口是什麼? 爲何要使用接口而不是直接使用具體類?

接口用於定義 API。 它定義了類必須得遵循的規則。 同時, 它提供了一種抽象, 由於客戶端

只使用接口, 這樣能夠有多重實現, List 接口, 你能夠使用可隨機訪問的 ArrayList

也能夠使用方便插入和刪除的 LinkedList。 接口中不容許寫代碼, 以此來保證抽象, 可是

Java 8 中你能夠在接口聲明靜態的默認方法, 這種方法是具體的。

104Java 中, 抽象類與接口之間有什麼不一樣? (答案)

Java 中, 抽象類和接口有不少不一樣之處, 可是最重要的一個是 Java 中限制一個類只能繼

承一個類, 可是能夠實現多個接口。 抽象類能夠很好的定義一個家族類的默認行爲, 而接口

能更好的定義類型, 有助於後面實現多態機制。 關於這個問題的討論請查看答案。105) 除了單例模式, 你在生產環境中還用過什麼設計模式?

這須要根據你的經驗來回答。 通常狀況下, 你能夠說依賴注入, 工廠模式, 裝飾模式或者觀

察者模式, 隨意選擇你使用過的一種便可。 不過你要準備回答接下的基於你選擇的模式的問

題。

106) 你能解釋一下里氏替換原則嗎?(答案)

107) 什麼狀況下會違反迪米特法則? 爲何會有這個問題? (答案)

迪米特法則建議「只和朋友說話, 不要陌生人說話」 , 以此來減小類之間的耦合。

108) 適配器模式是什麼? 何時使用?

適配器模式提供對接口的轉換。 若是你的客戶端使用某些接口, 可是你有另一些接口,

就能夠寫一個適配去來鏈接這些接口。

109) 什麼是「依賴注入」 和「控制反轉」 ? 爲何有人使用? (答案)

110) 抽象類是什麼? 它與接口有什麼區別? 你爲何要使用過抽象類? (答案)

111) 構造器注入和 setter 依賴注入, 那種方式更好? (答案)

每種方式都有它的缺點和優勢。 構造器注入保證全部的注入都被初始化, 可是 setter 注入

提供更好的靈活性來設置可選依賴。 若是使用 XML 來描述依賴, Setter 注入的可讀寫會更

強。 經驗法則是強制依賴使用構造器注入, 可選依賴使用 setter 注入。

112) 依賴注入和工程模式之間有什麼不一樣? (答案)

雖然兩種模式都是將對象的建立從應用的邏輯中分離, 可是依賴注入比工程模式更清晰。

過依賴注入, 你的類就是 POJO, 它只知道依賴而不關心它們怎麼獲取。 使用工廠模式, 你

的類須要經過工廠來獲取依賴。 所以, 使用 DI 會比使用工廠模式更容易測試。 關於這個話

題的更詳細討論請參見答案。

113) 適配器模式和裝飾器模式有什麼區別? (答案)

雖然適配器模式和裝飾器模式的結構相似, 可是每種模式的出現意圖不一樣。 適配器模式被用

於橋接兩個接口, 而裝飾模式的目的是在不修改類的狀況下給類增長新的功能。

114) 適配器模式和代理模式以前有什麼不一樣? (答案)

這個問題與前面的相似, 適配器模式和代理模式的區別在於他們的意圖不一樣。 因爲適配器模

式和代理模式都是封裝真正執行動做的類, 所以結構是一致的, 可是適配器模式用於接口之

間的轉換, 而代理模式則是增長一個額外的中間層, 以便支持分配、 控制或智能訪問。

115) 什麼是模板方法模式? (答案)

模板方法提供算法的框架, 你能夠本身去配置或定義步驟。 例如, 你能夠將排序算法看作是

一個模板。 它定義了排序的步驟, 可是具體的比較, 能夠使用 Comparable 或者其語言中類

似東西, 具體策略由你去配置。 列出算法概要的方法就是衆所周知的模板方法。

116) 何時使用訪問者模式? (答案)

訪問者模式用於解決在類的繼承層次上增長操做, 可是不直接與之關聯。 這種模式採用雙派

發的形式來增長中間層。

117) 何時使用組合模式? (答案)

組合模式使用樹結構來展現部分與總體繼承關係。它容許客戶端採用統一的形式來對待單個

對象和對象容器。 當你想要展現對象這種部分與總體的繼承關係時採用組合模式。

118) 繼承和組合之間有什麼不一樣? (答案)

雖然兩種均可以實現代碼複用, 可是組合比繼承共靈活, 由於組合容許你在運行時選擇不一樣

的實現。 用組合實現的代碼也比繼承測試起來更加簡單。

119) 描述 Java 中的重載和重寫? (答案)

重載和重寫都容許你用相同的名稱來實現不一樣的功能, 可是重載是編譯時活動, 而重寫是運

行時活動。 你能夠在同一個類中重載方法, 可是隻能在子類中重寫方法。 重寫必需要有繼承。120Java 中, 嵌套公共靜態類與頂級類有什麼不一樣? (答案)

類的內部能夠有多個嵌套公共靜態類, 可是一個 Java 源文件只能有一個頂級公共類, 而且

頂級公共類的名稱與源文件名稱必須一致。

121) OOP 中的 組合、 聚合和關聯有什麼區別? (答案)

若是兩個對象彼此有關係, 就說他們是彼此相關聯的。 組合和聚合是面向對象中的兩種形式

的關聯。 組合是一種比聚合更強力的關聯。 組合中, 一個對象是另外一個的擁有者, 而聚合則

是指一個對象使用另外一個對象。 若是對象 A 是由對象 B 組合的, 則 A 不存在的話, B

定不存在, 可是若是 A 對象聚合了一個對象 B, 則即便 A 不存在了, B 也能夠單獨存在。

122) 給我一個符合開閉原則的設計模式的例子? (答案)

開閉原則要求你的代碼對擴展開放, 對修改關閉。 這個意思就是說, 若是你想增長一個新的

功能, 你能夠很容易的在不改變已測試過的代碼的前提下增長新的代碼。 有好幾個設計模式

是基於開閉原則的, 如策略模式, 若是你須要一個新的策略, 只須要實現接口, 增長配置,

不須要改變核心邏輯。 一個正在工做的例子是 Collections.sort() 方法, 這就是基於策略

模式, 遵循開閉原則的, 你不需爲新的對象修改 sort() 方法, 你須要作的僅僅是實現你自

己的 Comparator 接口。

123) 抽象工廠模式和原型模式之間的區別? (答案)

124) 何時使用享元模式? (答案)

享元模式經過共享對象來避免建立太多的對象。 爲了使用享元模式, 你須要確保你的對象是

不可變的, 這樣你才能安全的共享。 JDK String 池、 Integer 池以及 Long 池都是很好

的使用了享元模式的例子。

Java 面試中其餘各式各樣的問題

這部分包含 Java 中關於 XML 的面試題, JDBC 面試題, 正則表達式面試題, Java 錯誤和

異常及序列化面試題

125) 嵌套靜態類與頂級類有什麼區別? (答案)

一個公共的頂級類的源文件名稱與類名相同, 而嵌套靜態類沒有這個要求。 一個嵌套類位於

頂級類內部, 須要使用頂級類的名稱來引用嵌套靜態類, HashMap.Entry 是一個嵌套靜

態類, HashMap 是一個頂級類, Entry 是一個嵌套靜態類。

126) 你能寫出一個正則表達式來判斷一個字符串是不是一個數字嗎? (解決方案)

一個數字字符串, 只能包含數字, 0 9 以及 +- 開頭, 經過這個信息, 你能夠下一

個以下的正則表達式來判斷給定的字符串是否是數字。

127Java 中, 受檢查異常 和 不受檢查異常的區別? (答案)

受檢查異常編譯器在編譯期間檢查。 對於這種異常, 方法強制處理或者經過 throws 子句聲

明。 其中一種狀況是 Exception 的子類但不是 RuntimeException 的子類。 非受檢查是

RuntimeException 的子類, 在編譯階段不受編譯器的檢查。

128Java 中, throw throws 有什麼區別? (答案)

throw 用於拋出 java.lang.Throwable 類的一個實例化對象, 意思是說你能夠經過關鍵字

throw 拋出一個 Error 或者 一個 Exception, 如:

throw new IllegalArgumentException(size must be multiple of 2)

throws 的做用是做爲方法聲明和簽名的一部分, 方法被拋出相應的異常以便調用者能處

理。 Java 中, 任何未處理的受檢查異常強制在 throws 子句中聲明。

129Java 中, Serializable Externalizable 的區別? (答案)

Serializable 接口是一個序列化 Java 類的接口, 以便於它們能夠在網絡上傳輸或者能夠

將它們的狀態保存在磁盤上, JVM 內嵌的默認序列化方式, 成本高、 脆弱並且不安全。Externalizable 容許你控制整個序列化過程, 指定特定的二進制格式, 增長安全機制。

130Java 中, DOM SAX 解析器有什麼不一樣? (答案)

DOM 解析器將整個 XML 文檔加載到內存來建立一棵 DOM 模型樹, 這樣能夠更快的查找節點

和修改 XML 結構, 而 SAX 解析器是一個基於事件的解析器, 不會將整個 XML 文檔加載到

內存。 因爲這個緣由, DOM SAX 更快, 也要求更多的內存, 不適合於解析大 XML 文件。

131) 說出 JDK 1.7 中的三個新特性? (答案)

JDK 1.7 不 像 JDK 5 8 一 樣 的 大 版 本 , 但 是 , 還 是 有 很 多 新 的 特 性 , 如

try-with-resource 語句, 這樣你在使用流或者資源的時候, 就不須要手動關閉, Java

自動關閉。 Fork-Join 池某種程度上實現 Java 版的 Map-reduce。 容許 Switch 中有

String 變量和文本。 菱形操做符(<>)用於類型推斷, 再也不須要在變量聲明的右邊申明泛型,

所以能夠寫出可讀寫更強、 更簡潔的代碼。 另外一個值得一提的特性是改善異常處理, 如容許

在同一個 catch 塊中捕獲多個異常。

132) 說出 5 JDK 1.8 引入的新特性? (答案)

Java 8 Java 歷史上是一個開創新的版本, 下面 JDK 8 5 個主要的特性:

Lambda 表達式, 容許像對象同樣傳遞匿名函數

Stream API, 充分利用現代多核 CPU, 能夠寫出很簡潔的代碼

Date Time API, 最終, 有一個穩定、 簡單的日期和時間庫可供你使用

擴展方法, 如今, 接口中能夠有靜態、 默認方法。

重複註解, 如今你能夠將相同的註解在同一類型上使用屢次。

1.靜態變量和實例變量的區別? 

在語法定義上的區別:靜態變量前要加static關鍵字,而實例變量前則不加。
在程序運行時的區別:實例變量屬於某個對象的屬性,必須建立了實例對象,其中的實例變量纔會被分配空間,才能使用這個實例變量。靜態變量不屬於某個實例對象,而是屬於類,因此也稱爲類變量,只要程序加載了類的字節碼,不用建立任何實例對象,靜態變量就會被分配空間,靜態變量就能夠被使用了。總之,實例變量必須建立對象後才能夠經過這個對象來使用,靜態變量則能夠直接使用類名來引用。

 

 

2.是否能夠從一個static方法內部發出對非static方法的調用? 

不能夠。由於非static方法是要與對象關聯在一塊兒的,必須建立一個對象後,才能夠在該對象上進行方法調用,而static方法調用時不須要建立對象,能夠直接調用。也就是說,當一個static方法被調用時,可能尚未建立任何實例對象,若是從一個static方法中發出對非static方法的調用,那個非static方法是關聯到哪一個對象上的呢?這個邏輯沒法成立,因此,一個static方法內部發出對非static方法的調用。

 

3.Integer與int的區別

int是java提供的8種原始數據類型之一。Java爲每一個原始類型提供了封裝類,Integer是java爲int提供的封裝類。int的默認值爲0,而Integer的默認值爲null,即Integer能夠區分出未賦值和值爲0的區別,int則沒法表達出未賦值的狀況,例如,要想表達出沒有參加考試和考試成績爲0的區別,則只能使用Integer。在JSP開發中,Integer的默認爲null,因此用el表達式在文本框中顯示時,值爲空白字符串,而int默認的默認值爲0,因此用el表達式在文本框中顯示時,結果爲0,因此,int不適合做爲web層的表單數據的類型。
Hibernate中,若是將OID定義爲Integer類型,那麼Hibernate就能夠根據其值是否爲null而判斷一個對象是不是臨時的,若是將OID定義爲了int類型,還須要在hbm映射文件中設置其unsaved-value屬性爲0。
另外,Integer提供了多個與整數相關的操做方法,例如,將一個字符串轉換成整數,Integer中還定義了表示整數的最大值和最小值的常量

 

4.Overload和Override的區別。Overloaded的方法是否能夠改變返回值的類型? 

Overload是重載的意思,Override是覆蓋的意思,也就是重寫。
重載Overload表示同一個類中能夠有多個名稱相同的方法,但這些方法的參數列表各不相同(即參數個數或類型不一樣)。
重寫Override表示子類中的方法能夠與父類中的某個方法的名稱和參數徹底相同,經過子類建立的實例對象調用這個方法時,將調用子類中的定義方法,這至關於把父類中定義的那個徹底相同的方法給覆蓋了,這也是面向對象編程的多態性的一種表現。子類覆蓋父類的方法時,只能比父類拋出更少的異常,或者是拋出父類拋出的異常的子異常,由於子類能夠解決父類的一些問題,不能比父類有更多的問題。子類方法的訪問權限只能比父類的更大,不能更小。若是父類的方法是private類型,那麼,子類則不存在覆蓋的限制,至關於子類中增長了一個全新的方法。

 

5.構造器Constructor是否可被override? 

構造器Constructor不能被繼承,所以不能重寫Override,但能夠被重載Overload。 

 

6.接口是否可繼承接口? 抽象類是否可實現(implements)接口? 抽象類是否可繼承具體類(concrete class)? 抽象類中是否能夠有靜態的main方法?

接口能夠繼承接口。抽象類能夠實現(implements)接口,抽象類是否可繼承具體類。抽象類中能夠有靜態的main方法。

 

 

7.面向對象的特徵有哪些方面

面向對象編程就是按現實業務同樣的方式將程序代碼按一個個對象進行組織和編寫,讓計算機系統可以識別和理解用對象方式組織和編寫的程序代碼,這樣就能夠把現實生活中的業務對象映射到計算機系統中。
面向對象的編程語言有封裝、繼承 、抽象、多態等4個主要的特徵。

封裝:
封裝是保證軟件部件具備優良的模塊性的基礎,封裝的目標就是要實現軟件部件的「高內聚、低耦合」,防止程序相互依賴性而帶來的變更影響。在面向對象的編程語言中,對象是封裝的最基本單位,面向對象的封裝比傳統語言的封裝更爲清晰、更爲有力。面向對象的封裝就是把描述一個對象的屬性和行爲的代碼封裝在一個「模塊」中,也就是一個類中,屬性用變量定義,行爲用方法進行定義,方法能夠直接訪問同一個對象中的屬性。一般狀況下,只要記住讓變量和訪問這個變量的方法放在一塊兒,將一個類中的成員變量所有定義成私有的,只有這個類本身的方法才能夠訪問到這些成員變量,這就基本上實現對象的封裝,就很容易找出要分配到這個類上的方法了,就基本上算是會面向對象的編程了。把握一個原則:把對同一事物進行操做的方法和相關的方法放在同一個類中,把方法和它操做的數據放在同一個類中。

抽象:
抽象就是找出一些事物的類似和共性之處,而後將這些事物歸爲一個類,這個類只考慮這些事物的類似和共性之處,而且會忽略與當前主題和目標無關的那些方面,將注意力集中在與當前目標有關的方面。例如,看到一隻螞蟻和大象,你可以想象出它們的相同之處,那就是抽象。抽象包括行爲抽象和狀態抽象兩個方面。

繼承:
在定義和實現一個類的時候,能夠在一個已經存在的類的基礎之上來進行,把這個已經存在的類所定義的內容做爲本身的內容,並能夠加入若干新的內容,或修改原來的方法使之更適合特殊的須要,這就是繼承。繼承是子類自動共享父類數據和方法的機制,這是類之間的一種關係,提升了軟件的可重用性和可擴展性。

多態:
多態是指程序中定義的引用變量所指向的具體類型和經過該引用變量發出的方法調用在編程時並不肯定,而是在程序運行期間才肯定,即一個引用變量倒底會指向哪一個類的實例對象,該引用變量發出的方法調用究竟是哪一個類中實現的方法,必須在由程序運行期間才能決定。由於在程序運行時才肯定具體的類,這樣,不用修改源程序代碼,就可讓引用變量綁定到各類不一樣的類實現上,從而致使該引用調用的具體方法隨之改變,即不修改程序代碼就能夠改變程序運行時所綁定的具體代碼,讓程序能夠選擇多個運行狀態,這就是多態性。多態性加強了軟件的靈活性和擴展性。

 

8.java中實現多態的機制是什麼? 

靠的是父類或接口定義的引用變量能夠指向子類或具體實現類的實例對象,而程序調用的方法在運行期才動態綁定,就是引用變量所指向的具體實例對象的方法,也就是內存里正在運行的那個對象的方法,而不是引用變量的類型中定義的方法。 

 

9.abstract的method是否可同時是static,是否可同時是native,是否可同時是synchronized? 

abstract的method 不能夠是static的,由於抽象的方法是要被子類實現的,而static與子類扯不上關係!
native方法表示該方法要用另一種依賴平臺的編程語言實現的,不存在着被子類實現的問題,因此,它也不能是抽象的,不能與abstract混用。

 

10.什麼是內部類?Static Nested Class 和 Inner Class的不一樣。

內部類就是在一個類的內部定義的類,內部類中不能定義靜態成員(靜態成員不是對象的特性,只是爲了找一個容身之處,因此須要放到一個類中而已,這麼一點小事,你還要把它放到類內部的一個類中,過度了啊!提供內部類,不是爲讓你幹這種事情,無聊,不讓你幹。我想多是既然靜態成員相似c語言的全局變量,而內部類一般是用於建立內部對象用的,因此,把「全局變量」放在內部類中就是毫無心義的事情,既然是毫無心義的事情,就應該被禁止),內部類能夠直接訪問外部類中的成員變量,內部類能夠定義在外部類的方法外面,也能夠定義在外部類的方法體中

在方法體外面定義的內部類的訪問類型能夠是public,protecte,默認的,private等4種類型,這就好像類中定義的成員變量有4種訪問類型同樣,它們決定這個內部類的定義對其餘類是否可見;對於這種狀況,咱們也能夠在外面建立內部類的實例對象,建立內部類的實例對象時,必定要先建立外部類的實例對象,而後用這個外部類的實例對象去建立內部類的實例對象,

在方法內部定義的內部類前面不能有訪問類型修飾符,就好像方法中定義的局部變量同樣,但這種內部類的前面能夠使用final或abstract修飾符。這種內部類對其餘類是不可見的其餘類沒法引用這種內部類,可是這種內部類建立的實例對象能夠傳遞給其餘類訪問。這種內部類必須是先定義,後使用,即內部類的定義代碼必須出如今使用該類以前,這與方法中的局部變量必須先定義後使用的道理也是同樣的。這種內部類能夠訪問方法體中的局部變量,可是,該局部變量前必須加final修飾符。

在方法體內部還能夠採用以下語法來建立一種匿名內部類,即定義某一接口或類的子類的同時,還建立了該子類的實例對象,無需爲該子類定義名稱

最後,在方法外部定義的內部類前面能夠加上static關鍵字,從而成爲Static Nested Class,它再也不具備內部類的特性,全部,從狹義上講,它不是內部類。Static Nested Class與普通類在運行時的行爲和功能上沒有什麼區別,只是在編程引用時的語法上有一些差異,它能夠定義成public、protected、默認的、private等多種類型,而普通類只能定義成public和默認的這兩種類型。在外面引用Static Nested Class類的名稱爲「外部類名.內部類名」。在外面不須要建立外部類的實例對象,就能夠直接建立Static Nested Class,例如,假設Inner是定義在Outer類中的Static Nested Class,那麼能夠使用以下語句建立Inner類:
Outer.Inner inner = new Outer.Inner();
因爲static Nested Class不依賴於外部類的實例對象,因此,static Nested Class能訪問外部類的非static成員變量。當在外部類中訪問Static Nested Class時,能夠直接使用Static Nested Class的名字,而不須要加上外部類的名字了,在Static Nested Class中也能夠直接引用外部類的static的成員變量,不須要加上外部類的名字。
在靜態方法中定義的內部類也是Static Nested Class,這時候不能在類前面加static關鍵字,靜態方法中的Static Nested Class與普通方法中的內部類的應用方式很類似,它除了能夠直接訪問外部類中的static的成員變量,還能夠訪問靜態方法中的局部變量,可是,該局部變量前必須加final修飾符。

 

11.Anonymous Inner Class (匿名內部類) 是否能夠extends(繼承)其它類,是否能夠implements(實現)interface(接口)? 

能夠繼承其餘類或實現其餘接口。不只是能夠,而是必須!

 

12.String是最基本的數據類型嗎? 

基本數據類型包括byte、int、char、long、float、double、boolean和short。 
java.lang.String類是final類型的,所以不能夠繼承這個類、不能修改這個類。爲了提升效率節省空間,咱們應該用StringBuffer類 ,而且string不能夠繼承。

 

13.如何把一段逗號分割的字符串轉換成一個數組?

若是不查jdk api,我很難寫出來!我能夠說說個人思路:
1. 用正則表達式,代碼大概爲:String [] result = orgStr.split(「,」);
2. 用 StingTokenizer ,代碼爲:StringTokenizer  tokener = StringTokenizer(orgStr,」,」);
String [] result = new String[tokener .countTokens()];
Int i=0;
while(tokener.hasNext(){result[i++]=toker.nextToken();}

14.數組有沒有length()這個方法? String有沒有length()這個方法? 

數組沒有length()這個方法,有length的屬性。String有有length()這個方法。

15.final, finally, finalize的區別。 

final 用於聲明屬性,方法和類,分別表示屬性不可變,方法不可覆蓋,類不可繼承。 
內部類要訪問局部變量,局部變量必須定義成final類型,

finally是異常處理語句結構的一部分,表示老是執行。
finalize是Object類的一個方法,在垃圾收集器執行的時候會調用被回收對象的此方法,能夠覆蓋此方法提供垃圾收集時的其餘資源回收,例如關閉文件等。JVM不保證此方法總被調用

 

16. 解釋下java的跨平臺特性?

雖然不知道什麼是跨平臺也能夠使用Java語言進行編程,可是對於一個Java編程員來講,理解跨平臺特性可以更深刻掌握Java語言,因此企業中每每要求應聘者至少理解這個特性。

參考答案:Java的跨平臺特性也被稱爲可移植性、平臺無關性,或者一次編寫到處運行。他的意思就是如果用Java語言編寫一個應用,那麼就能夠在不一樣平臺上運行,而不須要爲不一樣平臺單獨運行開發。之因此能實現跨平臺的特性。主要得益於Java虛擬機(JVM),JVM解釋器在運行Java應用時根據當前平臺進行解釋,解釋成符合當前平臺規範的機器碼,因此能夠實現一樣的應用在不一樣平臺上都能運行。

 

17. 請舉例java語言的主要特色?

解析:瞭解一門語言,每每從熟悉該語言的主要特色開始入手,因此企業也經常經過應聘者對JAVA語言特色的掌握程度而判斷其語言基礎是否紮實。

參考答案:JAVA語言有不少特色,主要包括跨平臺性:一個應用能夠不通過修改直接運行到不一樣的平臺上。   象:J AV      A   語言是一門面向對面的語言,能夠使用對象的屬性和行爲,能夠使用面向對象的思想進行分析設計,並實現整個應用。解釋執行JAVA應用時,JVM中的解釋器將解釋類文件,生成符合當前平臺的字節碼。自動回收:JAVA應用中的垃圾回收是自動進行的,JVM中的後臺線程將監視內存中數據的使用,當內存中的數據再也不被引用時,將被做爲垃圾回收,而不須要程序員動手回收。

 

1、面向對象的特徵有哪些方面? 【基礎】

答:面向對象的特徵主要有如下幾個方面:

1)抽象:抽象就是忽略一個主題中與當前目標無關的那些方面,以便更充分地

注意與當前目標有關的方面。抽象並不打算了解所有問題,而只是選擇其中的一

部分,暫時不用部分細節。抽象包括兩個方面,一是過程抽象,二是數據抽象。

2)繼承:繼承是一種聯結類的層次模型,而且容許和鼓勵類的重用,它提供了

一種明確表述共性的方法。對象的一個新類能夠從現有的類中派生,這個過程稱

爲類繼承。新類繼承了原始類的特性,新類稱爲原始類的派生類(子類),而原

始類稱爲新類的基類(父類)。派生類能夠從它的基類那裏繼承方法和實例變

而且類能夠修改或增長新的方法使之更適合特殊的須要。

3)封裝:封裝是把過程和數據包圍起來,對數據的訪問只能經過已定義的界 面 。

面向對象計算始於這個基本概念,即現實世界能夠被描繪成一系列徹底自治、封

裝的對象,這些對象經過一個受保護的接口訪問其餘對象。

4)多態性:多態性是指容許不一樣類的對象對同一消息做出響應。多態性包括參

數化多態性和包含多態性。多態性語言具備靈活、抽象、行爲共享、代碼共享的

優點,很好的解決了應用程序函數同名問題。

2、做用域 public,private,protected,以及不寫時的區別?【基礎】

答:區別以下:

做用域 當前類 同包 子孫類 其餘

public √ √ √ √

2 頁 共 59

protected √ √ √ ×

default √ √ × ×

private √ × × ×

不寫時默認爲 default

11heap stack 有什麼區別?【基礎】

答:棧是一種線形集合,其添加和刪除元素的操做應在同一段完成,棧按照後進

先出的方式進行處理;堆是棧的一個組成元素。

12Math.round(11.5) 等於多少? Math.round(-11.5)等於多少? 【基礎】

答: Math.round(11.5)==12 Math.round(-11.5)==-11 round 方法返回與參數

最接近的長整數,參數加 1/2 後求其 floor

14、編程題: 用最有效率的方法算出 2 乘以 8 等於幾? 【基礎】

答: 2 << 3

16、在 JAVA 中,如何跳出當前的多重嵌套循環?【基礎】

答:在最外層循環前加 label 標識,而後用 break:label 方法便可跳出多重循環

19、是否能夠繼承 String ? 【基礎】

答:String 類是 final 類,故不能夠繼承

20、如下二條語句返回值爲 true 的有:

A:「beijing==beijing」;

B:「beijing.equalsIgnoreCasenew String(「beijing」 )); 【基礎】

答: A B

21、當一個對象被看成參數傳遞到一個方法後,此方法可改變這個對象的屬性,

並可返回變化後的結果,那麼這裏究竟是值傳遞仍是引用傳遞? 【基礎】

答:是值傳遞。Java 編程語言只有值傳遞參數。當一個對象實例做爲一個參數

被傳遞到方法中時,參數的值就是對該對象的引用。對象的內容能夠在被調用的

方法中改變,但對象的引用是永遠不會改變的

26、定義類 A 和類 B 以下: 【基礎】

class A {

int a=1;

double d=2.0;

void show(){

System.out.println("Class A: a="+a +"\td="+d);

}

}

class B extends A{

5 頁 共 59

float a=3.0f;

String d="Java program.";

void show(){

super.show( );

System.out.println("Class B: a="+a +"\td="+d);

}

}

(1) 若在應用程序的 main 方法中有如下語句:

A a=new A();

a.show();

則輸出的結果如何?

(2) 若在應用程序的 main 方法中定義類 B 的對象 b

A b=new B();

b.show();

則輸出的結果如何?

答:輸出結果爲:

1Class A: a=1 d=2.0

2Class A: a=1 d=2.0

Class B: a=3.0 d=Java program

47、在 java 中一個類被聲明爲 final 類型,表示了什麼意思?【基礎】

答:表示該類不能被繼承,是頂級類。

48、下面哪些類能夠被繼承? 【基礎】

1java.lang.Thread (T)

8 頁 共 59

2java.lang.Number (T)

3java.lang.Double (F)

4java.lang.Math (F)

5java.lang.Void (F)

6java.lang.Class (F)

7java.lang.ClassLoader (T)

答:127 能夠被繼承。

49、指出下面程序的運行結果: 【基礎】

class A{

static{

System.out.print("1");

}

public A(){

System.out.print("2");

}

}

class B extends A{

static{

System.out.print("a");

}

public B(){

System.out.print("b");

}

}

public class Hello{

public static void main(String[] ars){

A ab = new B(); //執行到此處,結果: 1a2b

ab = new B(); //執行到此處,結果: 1a2b2b

}

}

答:輸出結果爲 1a2b2b;類的 static 代碼段,能夠看做是類首次加載(虛擬機加

)執行的代碼,而對於類加載,首先要執行其基類的構造,再執行其自己的構造。

50、繼承時候類的執行順序問題,通常都是選擇題,問你將會打印出什麼?【基 礎 】

父類:

package test;

public class FatherClass {

public FatherClass() {

System.out.println("FatherClass Create");

}

}

子類:

package test;

9 頁 共 59

import test.FatherClass;

public class ChildClass extends FatherClass {

public ChildClass() {

System.out.println("ChildClass Create");

}

public static void main(String[] args) {

FatherClass fc = new FatherClass();

ChildClass cc = new ChildClass();

}

}

答:輸出結果爲:

FatherClass Create

FatherClass Create

ChildClass Create

51、內部類的實現方式? 【基礎】

答:示例代碼以下:

package test;

public class OuterClass {

private class InterClass {

public InterClass() {

System.out.println("InterClass Create");

}

}

public OuterClass() {

InterClass ic = new InterClass();

System.out.println("OuterClass Create");

}

public static void main(String[] args) {

OuterClass oc = new OuterClass();

}

}

輸出結果爲:

InterClass Create

OuterClass Create

52、關於內部類: 【基礎】

public class OuterClass {

private double d1 = 1.0;

//insert code here

}

You need to insert an inner class declaration at line 3Which two

inner class declarations are valid?(Choose two.)

A. class InnerOne{

10 頁 共 59

public static double methoda() {return d1;}

}

B. public class InnerOne{

static double methoda() {return d1;}

}

C. private class InnerOne{

double methoda() {return d1;}

}

D. static class InnerOne{

protected double methoda() {return d1;}

}

E. abstract class InnerOne{

public abstract double methoda();

}

答:答案爲 CE;說明以下:

1)靜態內部類能夠有靜態成員,而非靜態內部類則不能有靜態成員;故 A B

錯;

2)靜態內部類的非靜態成員能夠訪問外部類的靜態變量,而不可訪問外部類

的非靜態變量;故 D 錯;

3)非靜態內部類的非靜態成員能夠訪問外部類的非靜態變量;故 C 正確 。

53、數據類型之間的轉換:

1)如何將數值型字符轉換爲數字?

2)如何將數字轉換爲字符?

3)如何取小數點前兩位並四捨五入? 【基礎】

1)調用數值類型相應包裝類中的方法 parse***(String)valueOf(String)

便可返回相應基本類型或包裝類型數值;

2)將數字與空字符串相加便可得到其所對應的字符串;另外對於基本類型

數字還可調用String 類中的valueOf()方法返回相應字符串,而對於包裝類型

數字則可調用其 toString()方法得到相應字符串;

3)可用該數字構造一 java.math.BigDecimal 對象,再利用其 round()方法

進行四捨五入到保留小數點後兩位,再將其轉換爲字符串截取最後兩位。

54、字符串操做:如何實現字符串的反轉及替換?【基礎】

答:可用字符串構造一 StringBuffer 對象,而後調用 StringBuffer 中的 reverse

方法便可實現字符串的反轉,調用 replace 方法便可實現字符串的替換。

55、編碼轉換:怎樣將 GB2312 編碼的字符串轉換爲 ISO-8859-1 編碼的字符串?

【基礎】

答:示例代碼以下:

String s1 = "你好";

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

56、寫一個函數,要求輸入一個字符串和一個字符長度,對該字符串進行分

隔。 【基礎】

11 頁 共 59

答:函數代碼以下:

public String[] split(String str, int chars){

int n = (str.length()+ chars - 1)/chars;

String ret[] = new String[n];

for(int i=0; i<n; i++){

if(i < n-1){

ret[i] = str.substring(i*chars , (i+1)*chars);

}else{

ret[i] = str.substring(i*chars);

}

}

return ret;

}

57、寫一個函數,2 個參數,1 個字符串,1 個字節數,返回截取的字符串,要

求字符串中的中文不能出現亂碼:如( 「我 ABC 」 , 4 )應該截爲 「我 AB 」 ,輸入 ( 「我

ABC DEF 」 ,6)應該輸出爲「我 ABC」而不是「我 ABC+漢的半個 」 。 【基礎】

答:代碼以下:

public String subString(String str, int subBytes) {

int bytes = 0; // 用來存儲字符串的總字節數

for (int i = 0; i < str.length(); i++) {

if (bytes == subBytes) {

return str.substring(0, i);

}

char c = str.charAt(i);

if (c < 256) {

bytes += 1; // 英文字符的字節數看做 1

} else {

bytes += 2; // 中文字符的字節數看做 2

if(bytes - subBytes == 1){

return str.substring(0, i);

}

}

}

return str;

}

58、日期和時間:

1)如何取得年月日、小時分秒?

2)如何取得從 1970 年到如今的毫秒數?

3)如何取得某個日期是當月的最後一天?

4)如何格式化日期?【基礎】

答: 1)建立 java.util.Calendar 實例(Calendar.getInstance()),調用其 get()

方法傳入不一樣的參數便可得到參數所對應的值,如:

12 頁 共 59

calendar.get(Calendar.YEAR);//得到年

2)如下方法都可得到該毫秒數:

Calendar.getInstance().getTimeInMillis();

System.currentTimeMillis();

3)示例代碼以下:

Calendar time = Calendar.getInstance();

time.set(Calendar.DAY_OF_MONTH,

time.getActualMaximum(Calendar.DAY_OF_MONTH));

4)利用 java.text.DataFormat 類中的 format()方法可將日期格式化。

59Java 編程,打印昨天的當前時刻。【基礎】

答:public class YesterdayCurrent{

public static void main(String[] args){

Calendar cal = Calendar.getInstance();

cal.add(Calendar.DATE, -1);

System.out.println(cal.getTime());

}

}

60java javasciprt 的區別。【基礎】

答: JavaScript Java 是兩個公司開發的不一樣的兩個產品。Java SUN 公司推

出的新一代面向對象的程序設計語言,特別適合於 Internet 應用程序開發;而

JavaScript Netscape 公司的產品,其目的是爲了擴展 Netscape Navigator

功能,而開發的一種能夠嵌入 Web 頁面中的基於對象和事件驅動的解釋性語言,

它的前身是 Live Script;而 Java 的前身是 Oak 語言。下面對兩種語言間的異

同做以下比較:

1)基於對象和麪向對象:

Java 是一種真正的面向對象的語言,即便是開發簡單的程序,必須設計對象 ;

JavaScript 是種腳本語言,它能夠用來製做與網絡無關的,與用戶交互做用

的複雜軟件。它是一種基於對象(Object Based)和事件驅動(Event Driver

的編程語言。於是它自己提供了很是豐富的內部對象供設計人員使用;

2)解釋和編譯:

Java 的源代碼在執行以前,必須通過編譯;

JavaScript 是一種解釋性編程語言,其源代碼不需通過編譯,由瀏覽器解釋

執行;

3)強類型變量和類型弱變量:

Java 採用強類型變量檢查,即全部變量在編譯以前必須做聲明;

JavaScript 中變量聲明,採用其弱類型。即變量在使用前不需做聲明,而是

解釋器在運行時檢查其數據類型;

4)代碼格式不同。

61、何時用 assert?【中等難度】

答:assertion(斷言)在軟件開發中是一種經常使用的調試方式,不少開發語言中都

支持這種機制。通常來講,assertion 用於保證程序最基本、關鍵的正確性。

assertion 檢查一般在開發和測試時開啓。爲了提升性能,在軟件發佈後,

13 頁 共 59

assertion 檢查一般是關閉的。在實現中,斷言是一個包含布爾表達式的語句,

在執行這個語句時假定該表達式爲 true;若是表達式計算爲 false,那麼系統

會報告一個 Assertionerror

斷言用於調試目的:

assert(a > 0); // throws an Assertionerror if a <= 0

斷言能夠有兩種形式:

assert Expression1 ;

assert Expression1 : Expression2 ;

Expression1 應該老是產生一個布爾值。

Expression2 能夠是得出一個值的任意表達式;這個值用於生成顯示更多調

試信息的 String 消息。

斷言在默認狀況下是禁用的,要在編譯時啓用斷言,需使用 source 1.4 標 記 :

javac -source 1.4 Test.java

要在運行時啓用斷言,可以使用 -enableassertions 或者 -ea 標記。

要在運行時選擇禁用斷言,可以使用 -da 或者 -disableassertions 標記。

要在系統類中啓用斷言,可以使用 -esa 或者 -dsa 標記。還能夠在包的基礎上

啓用或者禁用斷言。能夠在預計正常狀況下不會到達的任何位置上放置斷言。斷

言能夠用於驗證傳遞給私有方法的參數。不過,斷言不該該用於驗證傳遞給公有

方法的參數,由於無論是否啓用了斷言,公有方法都必須檢查其參數。不過,既

能夠在公有方法中,也能夠在非公有方法中利用斷言測試後置條件。另外,斷言

不該該以任何方式改變程序的狀態。

65JAVA 語言如何進行異常處理,關鍵字:throws,throw,try,catch,finally

分別表明什麼意義?在 try 塊中能夠拋出異常嗎?【基礎】

答:Java 經過面向對象的方法進行異常處理,把各類不一樣的異常進行分類,並

14 頁 共 59

提供了良好的接口。在 Java 中,每一個異常都是一個對象,它是 Throwable 類或

其它子類的實例。當一個方法出現異常後便拋出一個異常對象,該對象中包含有

異常信息,調用這個對象的方法能夠捕獲到這個異常並進行處理。Java 的異常

處理是經過 5 個關鍵詞來實現的:trycatchthrowthrows finally。一

般狀況下是用 try 來執行一段程序,若是出現異常,系統會拋出(throws)一個

異常,這時候你能夠經過它的類型來捕捉(catch)它,或最後(finally)由缺

省處理器來處理;

try 用來指定一塊預防全部「異常」的程序;

catch 子句緊跟在 try 塊後面,用來指定你想要捕捉的「異常」的類型;

throw 語句用來明確地拋出一個「異常」;

throws 用來標明一個成員函數可能拋出的各類「異常」;

Finally 爲確保一段代碼無論發生什麼「異常」都被執行一段代碼;

能夠在一個成員函數調用的外面寫一個 try 語句,在這個成員函數內部寫另外一

try 語句保護其餘代碼。每當遇到一個 try 語句, 「異常 」 的框架就放到堆棧

上面,直到全部的 try 語句都完成。若是下一級的 try 語句沒有對某種「異常 」

進行處理,堆棧就會展開,直到遇到有處理這種「異常」的 try 語句。

67、給我一個你最多見到的 runtime exception?【基礎】

ArithmeticException, ArrayStoreException, BufferOverflowException,

BufferUnderflowException, CannotRedoException, CannotUndoException,

ClassCastException, CMMException, ConcurrentModificationException,

DOMException, EmptyStackException, IllegalArgumentException,

IllegalMonitorStateException, IllegalPathStateException,

IllegalStateException, ImagingOpException, IndexOutOfBoundsException,

MissingResourceException, NegativeArraySizeException,

NoSuchElementException, NullPointerException, ProfileDataException,

ProviderException, RasterFormatException, SecurityException,

SystemException, UndeclaredThrowableException,

UnmodifiableSetException, UnsupportedOperationException

 

 

 

 

. 1. 什麼是 Java 虛擬機 ? 爲何 Java 被稱做是「 「 平臺無關的編程語言」 」 ?

Java 虛擬機是一個能夠執行 Java 字節碼的虛擬機進程。Java 源文件被編譯成能被 Java 虛擬

機執行的字節碼文件。

Java 被設計成容許應用程序能夠運行在任意的平臺,而不須要程序員爲每個平臺單獨重寫

或者是從新編譯。Java 虛擬機讓這個變爲可能,由於它知道底層硬件平臺的指令長度和其特性。

2. JDK JRE 的區別是什麼 ?

Java 運行時環境(JRE)是將要執行 Java 程序的 Java 虛擬機。它同時也包含了執行 applet 須要 的瀏覽器

插件。

Java 開發工具包(JDK)是完整的 Java 軟件開發包,包含了 JRE,編譯器和其餘的工具(好比:JavaDocJava

調試器),可讓開發者開發、編譯、執行 Java 應用程序

3. 」 」static」 」 關鍵字是什麼意思 ?Java 中是否能夠覆蓋(override) 一個 private 或者是

static 的 方法 ?

static」關鍵字代表一個成員變量或者是成員方法能夠在沒有所屬的類的實例變量的狀況下被訪問。

Java static 方法不能被覆蓋,由於方法覆蓋是基於運行時動態綁定的,而 static 方法是編 譯時靜態綁

定的。static 方法跟類的任何實例都不相關,因此概念上不適用。private 也是不支持覆蓋的,由於私有的

成員外界是看不到的因此也就不存在覆蓋的問題。

. 4. 是否能夠在 static 環境中訪問非 static 變量 ?

static 變量在 Java 中是屬於類的,它在全部的實例中的值是同樣的。當類被 Java 虛擬機載入 的時候,

會對 static 變量進行初始化。若是你的代碼嘗試不用實例來訪問非 static 的變量,編譯器會報錯,因

爲這些變量尚未被建立出來,尚未跟任何實例關聯上。

. 5. Java 支持的數據類型有哪些 ? 什麼是自動拆裝箱 ?

Java 語言支持的 8 中基本數據類型是:

整型:byte short int long

浮點型:float double

布爾型:boolean

字符型:char

自動裝箱是 Java 編譯器在基本數據類型和對應的對象包裝類型之間作的一個轉化。好比:把 int 轉化

Integerdouble 轉化成 double,等等。反之就是自動拆箱。

. 6. Java 中的方法覆蓋(Overriding) 和方法重載(Overloading) 是什麼意思 ?

重寫方法的規則 (方法重寫也稱爲方法覆蓋)

1、參數列表必須徹底與被重寫的方法相同,不然不能稱其爲重寫而是重載。

2、返回的類型必須一直與被重寫的方法的返回類型相同,不然不能稱其爲重寫而是重載。

3、訪問修飾符的限制必定要大於被重寫方法的訪問修飾符(public>protected>default>private

4、重寫方法必定不能拋出新的檢查異常或者比被重寫方法申明更加寬泛的檢查型異常。例如:

父類的一個方法申明瞭一個檢查異常 IOException,在重寫這個方法是就不能拋出 Exception,只能拋出

IOException 的子類異常,能夠拋出非檢查異常。

而重載的規則:

1、必須具備不一樣的參數列表;

2、能夠有不責罵的返回類型,只要參數列表不一樣就能夠了;

3、能夠有不一樣的訪問修飾符;

4、能夠拋出不一樣的異常;

重寫與重載的區別在於:

重寫多態性起做用,對調用被重載過的方法能夠大大減小代碼的輸入量,同一個方法名只要往裏面傳遞不

同的參數就能夠擁有不一樣的功能或返回值。

用好重寫和重載能夠設計一個結構清晰而簡潔的類,能夠說重寫和重載在編寫代碼過程當中的做用非同通常.

7. Java 中, , 什麼是構造函數 ? 什麼是構造函數重載 ? 什麼是複製構造函數 ?

當新對象被建立的時候,構造函數會被調用。每個類都有構造函數。在程序員沒有給類提

供構造函數的狀況下,Java 編譯器會爲這個類建立一個默認的構造函數。

Java 中構造函數重載和方法重載很類似。能夠爲一個類建立多個構造函數。每個構造函數 必須有它自

己惟一的參數列表。

Java 不支持像 C++中那樣的複製構造函數,這個不一樣點是由於若是你不本身寫構造函數的狀況下,Java

會建立默認的複製構造函數。

8. Java 支持多繼承麼 ? 支持多實現嗎?

不支持,Java 不支持多繼承。每一個類都只能繼承一個類,可是能夠實現多個接口。

9. 接口 能夠繼承接口嗎 ? 若是能夠繼承 請 列舉一個案例?

能夠,List 繼承 Collection

10. 接口和抽象類的區別是什麼 ?

接口和抽象類有什麼區別

你選擇使用接口和抽象類的依據是什麼?

接口和抽象類的概念不同。接口是對動做的抽象,抽象類是對根源的抽象。

抽象類表示的是,這個對象是什麼。接口表示的是,這個對象能作什麼。好比, 蘇格蘭摺耳貓 布偶貓 ,這

兩個類(若是是類的話„„),他們的抽象類是貓。說明,他們都是貓。

貓能夠吃東西,耗子也能夠吃東西,你能夠把「吃東西」定義成一個接口,而後讓這些類去實現它.

因此,在高級語言上,一個類只能繼承一個類(抽象類)(正如貓不可能同時是生物和非生物),可是能夠

實現多個接口(吃飯接口、走路接口)

第一點.接口是抽象類的變體,接口中全部的方法都是抽象的。而抽象類是聲明方法的存在而不去實現它

的類。

第二點.接口能夠多繼承,抽象類不行

第三點.接口定義方法,不能實現,而抽象類能夠實現部分方法。

第四點.接口中基本數據類型爲 static 而抽類象不是的。

第五點.Java 接口中聲明的變量默認都是 final 的。抽象類能夠包含非 final 的變量。

第六點.Java 接口中的成員函數默認是 public 的。抽象類的成員函數能夠是 privateprotected 或者

public

當你關注一個事物的本質的時候,用抽象類;當你關注一個操做的時候,用接口。

抽象類的功能要遠超過接口,可是,定義抽象類的代價高。由於高級語言來講(從實際設計上來講也是)

每一個類只能繼承一個類。在這個類中,你必須繼承或編寫出其全部子類的

全部共性。雖然接口在功能上會弱化許多,可是它只是針對一個動做的描述。並且你能夠在一個類中同時實現多個接口。在設計階段會下降難度的。

接口是絕對抽象的,不能夠被實例化。抽象類也不能夠被實例化

11. 什麼是值傳遞和引用傳遞 ?

對象被值傳遞,意味着傳遞了對象的一個副本。所以,就算是改變了對象副本,也不會影響 源對象的值。

對象被引用傳遞,意味着傳遞的並非實際的對象,而是對象的引用。所以,外部對引用對 象所作的改變

會反映到全部的對象上。

12. 進程和線程的區別是什麼 ?

進程是執行着的應用程序,而線程是進程內部的一個執行序列。一個進程能夠有多個線程。

線程又叫作輕量級進程。

13. 建立 線程有幾種不一樣的方式 ? 你喜歡哪種 ? 爲何 ?

有三種方式能夠用來建立線程:

繼承 Thread

實現 Runnable 接口

應用程序能夠使用 Executor 框架來建立線程池

實現 Runnable 接口這種方式更受歡迎,由於這不須要繼承 Thread 類。在應用設計中已經繼承了別的對

象的狀況下,這須要多繼承(而 Java 不支持多繼承),只能實現接口。同時,線程池也是很是高效的,

很容易實現和使用。

14. 歸納的解釋下線程的幾種可用狀態。

線程在執行過程當中,能夠處於下面幾種狀態:

就緒(Runnable):線程準備運行,不必定立馬就能開始執行。

運行中(Running):進程正在執行線程的代碼。

等待中(Waiting):線程處於阻塞的狀態,等待外部的處理結束。 睡眠中

(Sleeping):線程被強制睡眠。

I/O 阻塞(Blocked on I/O):等待 I/O 操做完成。

同步阻塞(Blocked on Synchronization):等待獲取鎖。

死亡(Dead):線程完成了執行

15. 同步方法和同步代碼塊的區別是什麼 ?

Java 語言中,每個對象有一把鎖。線程能夠使用 synchronized 關鍵字來獲取對象上的

鎖。

synchronized 關鍵字可應用在方法級別(粗粒度鎖)或者是代碼塊級別(細粒度鎖)

16. 在監視器(Monitor) 內部, , 是如何作線程同步的 ? 程序應該作哪一種級別的同步 ?

監視器和鎖在 Java 虛擬機中是一塊使用的。監視器監視一塊同步代碼塊,確保一次只有一

個線程執行同步代碼塊。每個監視器都和一個對象引用相關聯。線程在獲取鎖以前不容許

執行同步代碼。

17. 什麼是死鎖(deadlock)

兩個進程都在等待對方執行完畢才能繼續往下執行的時候就發生了死鎖。結果就是兩個進程

都陷入了無限的等待中。

18. 如何確保 N 個線程能夠訪問 N 個資源同時又不致使死鎖 ?

使用多線程的時候,一種很是簡單的避免死鎖的方式就是:指定獲取鎖的順序,並強制線程

按照指定的順序獲取鎖。所以,若是全部的線程都是以一樣的順序加鎖和釋放鎖,就不會出 現死鎖了。

19. Java 集合類框架的基本接口有哪些 ?

Java 集合類提供了一套設計良好的支持對一組對象進行操做的接口和類。Java 集合類裏面最

基本的接口有:

Collection:表明一組對象,每個對象都是它的子元素。

Set:不包含重複元素的 Collection

List:有順序的 collection,而且能夠包含重複元素。

Map:能夠把鍵(key)映射到值(value)的對象,鍵不能重複。

20. 爲何集合類沒有實現 Cloneable 和 和 Serializable 接口?

集合類接口指定了一組叫作元素的對象。集合類接口的每一種具體的實現類均可以選擇以它

本身的方式對元素進行保存和排序。有的集合類容許重複的鍵,有些不容許。

21. 什麼是迭代器(Iterator)

Iterator 接口提供了不少對集合元素進行迭代的方法。每個集合類都包含了能夠返回迭代

器實例的 迭代方法。迭代器能夠在迭代的過程當中刪除底層集合的元素。

克隆(cloning)或者是序列化(serialization)的語義和含義是跟具體的實現相關的。所以,應該由

集合類的具體實現來決定如何被克隆或者是序列化。

22. Iterator 和 和 ListIterator 的區別是什麼?

下面列出了他們的區別:

Iterator 可用來遍歷 Set List 集合,可是 ListIterator 只能用來遍歷 ListIterator 對集合只能是前向遍歷,ListIterator 既能夠前向也能夠後向。

ListIterator 實現了 Iterator 接口,幷包含其餘的功能,好比:增長元素,替換元素,獲取前

一個和後一個元素的索引,等等。

23. 快速失敗(fail-fast) 和安全失敗(fail-safe) 的區別是什麼?

Iterator 的安全失敗是基於對底層集合作拷貝,所以,它不受源集合上修改的影響。java.util

包下面的全部的集合類都是快速失敗的,而 java.util.concurrent 包下面的全部的類都是安全 失

敗的。快速失敗的迭代器會拋出 ConcurrentModificationException 異常,而安全失敗的迭 代

器永遠不會拋出這樣的異常。

24. Java 中的 HashMap 的工做原理是什麼?

Java 中的 HashMap 是以鍵值對(key-value)的形式存儲元素的。HashMap 須要一個 hash

數,它使用 hashCode()equals()方法來向集合/從集合添加和檢索元素。當調用 put()方法的時

候,HashMap 會計算 key hash 值,而後把鍵值對存儲在集合中合適的索引上。若是 key

已經存在了,value 會被更新成新值。HashMap 的一些重要的特性是它的容量(capacity),負 載

因子(load factor)和擴容極限(threshold resizing)

25. hashCode()和 和 equals() 方法的重要性體如今什麼地方?

Java 中的 HashMap 使用 hashCode()equals()方法來肯定鍵值對的索引,當根據鍵獲取值

的時候也會用到這兩個方法。若是沒有正確的實現這兩個方法,兩個不一樣的鍵可能會有相同的

hash 值,所以,可能會被集合認爲是相等的。並且,這兩個方法也用來發現重複元素。所

以這兩個方法的實現對 HashMap 的精確性和正確性是相當重要的。

26. HashMap 和 和 Hashtable 有什麼區別?

HashMap Hashtable 都實現了 Map 接口,所以不少特性很是類似。可是,他們有如下不一樣點:

HashMap 容許鍵和值是 null,而 Hashtable 不容許鍵或者值是 null

Hashtable 是同步的,而 HashMap 不是。所以,HashMap 更適合於單線程環境,而 Hashtable

適合於多線程環境。

HashMap 提供了可供應用迭代的鍵的集合,所以,HashMap 是快速失敗的。另外一方面,

Hashtable 提供了對鍵的列舉(Enumeration)

通常認爲 Hashtable 是一個遺留的類。

27. 數組(Array) 和列表(ArrayList) 有什麼區別?何時應該使用 Array 而不是

ArrayList

下面列出了 Array ArrayList 的不一樣點:

Array 能夠包含基本類型和對象類型,ArrayList 只能包含對象類型。

Array 大小是固定的,ArrayList 的大小是動態變化的。

ArrayList 提供了更多的方法和特性,好比:addAll()removeAll()iterator()等等。

對於基本類型數據,集合使用自動裝箱來減小編碼工做量。可是,當處理固定大小的基本數

據類型的時候,這種方式相對比較慢。

28. ArrayList 和 和 LinkedList 有什麼區別?

ArrayList LinkedList 都實現了 List 接口,他們有如下的不一樣點:

ArrayList 是基於索引的數據接口,它的底層是數組。它能夠以 O(1)時間複雜度對元素進行隨

機訪問。與此對應,LinkedList 是以元素列表的形式存儲它的數據,每個元素都和它

的前 一個和後一個元素連接在一塊兒,在這種狀況下,查找某個元素的時間複雜度是 O(n)

相對於 ArrayList LinkedList 的插入,添加,刪除操做速度更快,由於當元素被添加到集合

意位置的時候,不須要像數組那樣從新計算大小或者是更新索引。

LinkedList ArrayList 更佔內存,由於 LinkedList 爲每個節點存儲了兩個引用,一個指

向前一個元素,一個指向下一個元素。

也能夠參考 ArrayList vs. LinkedList

29. Comparable 和 和 Comparator 接口是幹什麼的?列出它們的區別。

Java 提供了只包含一個 compareTo()方法的 Comparable 接口。這個方法能夠個給兩個對象排

序。具體來講,它返回負數,0,正數來代表輸入對象小於,等於,大於已經存在的對象。

Java 提供了包含 compare()equals()兩個方法的 Comparator 接口。compare()方法用來給兩

個輸入參數排序,返回負數,0,正數代表第一個參數是小於,等於,大於第二個參數。equals()

方法須要一個對象做爲參數,它用來決定輸入參數是否和 comparator 相等。只有當輸入參

數也是一個 comparator 而且輸入參數和當前 comparator 的排序結果是相同的時候,這個方

法才返回 true

30. 什麼是 Java 優先級隊列(Priority Queue)

PriorityQueue 是一個基於優先級堆的無界隊列,它的元素是按照天然順序(natural order)排序

的。在建立的時候,咱們能夠給它提供一個負責給元素排序的比較器。PriorityQueue 不容許

null 值,由於他們沒有天然順序,或者說他們沒有任何的相關聯的比較器。最後,PriorityQueue

不是線程安全的,入隊和出隊的時間複雜度是 O(log(n))

31. 你瞭解大 O 符號(big-O notation) 麼?你能給出不一樣數據結構的例子麼?

O 符號描述了當數據結構裏面的元素增長的時候,算法的規模或者是性能在最壞的場景

下有多麼好。 O 符號也可用來描述其餘的行爲,好比:內存消耗。由於集合類其實是

數據結構,我 們通常使用大 O 符號基於時間,內存和性能來選擇最好的實現。大 O 符號可

以對大量數據的性能給出一個很好的說明。

32. 如何權衡是使用無序的數組仍是有序的數組?

有序數組最大的好處在於查找的時間複雜度是 O(log n),而無序數組是 O(n)。有序數組的缺點是插入操做的時間複雜度是 O(n),由於值大的元素須要日後移動來給新元素騰位置。相反,

無序數組的插入時間複雜度是常量 O(1)

33. Java 集合類框架的最佳實踐有哪些?

根據應用的須要正確選擇要使用的集合的類型對性能很是重要,好比:假如元素的大小是固

定的,並且能事先知道,咱們就應該用 Array 而不是 ArrayList 。有些集合類容許指定初始容

量。所以,若是咱們能估計出存儲的元素的數目,咱們能夠設置

初始容量來避免從新計算 hash 值或者是擴容。爲了類型安全,可讀性和健壯性的緣由老是要

使用泛型。同時,使用泛型還能夠避免運行時的 ClassCastException

使用 JDK 提供的不變類(immutable class)做爲 Map 的鍵能夠避免爲咱們本身的類實現

hashCode()equals()方法。

編程的時候接口優於實現。

底層的集合其實是空的狀況下,返回長度是 0 的集合或者是數組,不要返回 null

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

Enumeration 速度是 Iterator 2 倍,同時佔用更少的內存。可是,Iterator 遠遠比 Enumeration

安全,由於其餘線程不可以修改正在被 iterator 遍歷的集合裏面的對象。同時,Iterator 容許

調用者刪除底層集合裏面的元素,這對 Enumeration 來講是不可能的。

35. HashSet 和 和 TreeSet 有什麼區別?

HashSet 是由一個 hash 表來實現的,所以,它的元素是無序的。add() remove()contains()

方法的時間複雜度是 O(1)

另外一方面,TreeSet 是由一個樹形的結構來實現的,它裏面的元素是有序的。所以,add()

remove()contains()方法的時間複雜度是 O(logn)

36. Java 中垃圾回收有什麼目的?何時進行垃圾回收?

垃圾回收的目的是識別而且丟棄應用再也不使用的對象來釋放和重用資源。

37. System.gc()和 和 Runtime.gc() 會作什麼事情?

這兩個方法用來提示 JVM 要進行垃圾回收。可是,當即開始仍是延遲進行垃圾回收是取決

JVM 的。

38. finalize() 方法何時被調用?析構函數(finalization) 的目的是什麼?

在釋放對象佔用的內存以前,垃圾收集器會調用對象的 finalize()方法。通常建議在該方法中

釋放對象持有的資源。

39. 若是對象的引用被置爲 null ,垃圾收集器是否會當即釋放對象佔用的內存?

不會,在下一個垃圾回收週期中,這個對象將是可被回收的。

40. Java 堆的結構是什麼樣子的?什麼是堆中的永久代(Perm Gen space)?

JVM 的堆是運行時數據區,全部類的實例和數組都是在堆上分配內存。它在 JVM 啓動的時

候被建立。對象所佔的堆內存是由自動內存管理系統也就是垃圾收集器回收。

堆內存是由存活和死亡的對象組成的。存活的對象是應用能夠訪問的,不會被垃圾回收。死

亡的對象是應用不可訪問尚且尚未被垃圾收集器回收掉的對象。一直到垃圾收集器把這些

對象回收掉以前,他們會一直佔據堆內存空間。

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

吞吐量收集器使用並行版本的新生代垃圾收集器,它用於中等規模和大規模數據的應用程

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

42. 在 在 Java 中,對象何時能夠被垃圾回收?

當對象對當前使用這個對象的應用程序變得不可觸及的時候,這個對象就能夠被回收了。

43. JVM 的永久代中會發生垃圾回收麼?

垃圾回收不會發生在永久代,若是永久代滿了或者是超過了臨界值,會觸發徹底垃圾回收 (Full

GC)。若是你仔細查看垃圾收集器的輸出信息,就會發現永久代也是被回收的。這就是

爲何正確的永久代大小對避免 Full GC 是很是重要的緣由。請參考下 Java8 :從永久代到元

數據區

(譯者注:Java8 中已經移除了永久代,新加了一個叫作元數據區的 native 內存區)

43. Java 中的兩種異常類型是什麼 ? 他們有什麼區別 ?

Java 中有兩種異常:受檢查的(checked)異常和不受檢查的(unchecked)異常。不受檢查的異常

不須要在方法或者是構造函數上聲明,就算方法或者是構造函數的執行可能會拋出這樣的異

常,而且不受檢查的異常能夠傳播到方法或者是構造函數的外面。相反,受檢查的異常必須 要用 throws

44. Java Exception Error 有什麼區別 ?

Exception Error 都是 Throwable 的子類。Exception 用於用戶程序能夠捕獲的異常狀況。

Error

定義了不指望被用戶程序捕獲的異常。

45. throw throws 有什麼區 別 ?

throw 關鍵字用來在程序中明確的拋出異常,相反,throws 語句用來代表方法不能處理的異 常。每個方

法都必需要指定哪些異常不能處理,因此方法的調用者纔可以確保處理可能發

生的異常,多個異常是用逗號分隔的。

46. 異常處理的時候, ,finally 代碼塊的重要性是什麼 ?

不管是否拋出異常,finally 代碼塊老是會被執行。就算是沒有 catch 語句同時又拋出異常的

狀況下,finally 代碼塊仍然會被執行。最後要說的是,finally 代碼塊主要用來釋放資源,比

如:I/O 緩衝區,數據庫鏈接。

47. 異常處理完成之後, ,Exception 對象會發生什麼變化 ?

Exception 對象會在下一個垃圾回收過程當中被回收掉。

48. finally 代碼塊和 finalize() 方法有什麼區別 ?

不管是否拋出異常,finally 代碼塊都會執行,它主要是用來釋放應用佔用的資源。finalize()

方法是 Object 類的一個 protected 方法,它是在對象被垃圾回收以前由 Java 虛擬機來調用

的。

73. 什麼是 JDBC

JDBC 是容許用戶在不一樣數據庫之間作選擇的一個抽象層。JDBC 容許開發者用 JAVA 寫數據庫

應用程序,而不須要關心底層特定數據庫的細節。

74. 解釋下驅動(Driver) JDBC 中的角色。

JDBC 驅動提供了特定廠商對 JDBC API 接口類的實現,驅動必需要提供 java.sql 包下面這些類

的實現:Connection, Statement, PreparedStatement,CallableStatement, ResultSet Driver

75. Class.forName() 方法有什麼做用 ?

這個方法用來載入跟數據庫創建鏈接的驅動。

78. 數據庫鏈接池是什麼意思?

像打開關閉數據庫鏈接這種和數據庫的交互多是很費時的,尤爲是當客戶端數量增長的時

候,會消耗大量的資源,成本是很是高的。能夠在應用服務器啓動的時候創建不少個數據庫

鏈接並維護在一個池中。鏈接請求由池中的鏈接提供。在鏈接使用完畢之後,把鏈接歸還到 池中,以用於

知足未來更多的請求。

79. 什麼是 RMI

Java 遠程方法調用(JavaRMI)Java API 對遠程過程調用(RPC)提供的面向對象的等價形式,

支持直接傳輸序列化的 Java 對象和分佈式垃圾回收。遠程方法調用能夠看作是激活遠程正

在運行的對象上的方法的步驟。RMI 對調用者是位置透明的,由於調用者感受方法是執行在

本地運行的對象上的。看下 RMI 的一些注意事項。

80. RMI 體系結構的基本原則是什麼?

RMI 體系結構是基於一個很是重要的行爲定義和行爲實現相分離的原則。RMI 容許定義行爲的代碼和實現

行爲的代碼相分離,而且運行在不一樣的 JVM 上。

 

 

1、面向對象的特徵有哪些方面

(1)抽象:

抽象就是忽略一個主題中與當前目標無關的那些方面,以便更充分地注意與當前目標有關的方面。抽象並不打算了解所有問題,而只

是選擇其中的一部分,暫時不用部分細節。抽象包括兩個方面,一是過程抽象,二是數據抽象。

(2)繼承:

繼承是一種聯結類的層次模型,而且容許和鼓勵類的重用,它提供了一種明確表述共性的方法。對象的一個新類能夠從現有的類中派生,這個過程稱爲類繼承。新類繼承了原始類的特性,新類稱爲原始類的派生類(子類),而原始類稱爲新類的基類(父類)。派生

類能夠從它的基類那裏繼承方法和實例變量,而且類能夠修改或增長新的方法使之更適合特殊的須要。

(3)封裝:

封裝是把過程和數據包圍起來,對數據的訪問只能經過已定義的界面。面向對象計算始於這個基本概念,即現實世界能夠被描繪成一

系列徹底自治、封裝的對象,這些對象經過一個受保護的接口訪問其餘對象。

(4) 多態性:

多態性是指容許不一樣類的對象對同一消息做出響應。多態性包括參數化多態性和包含多態性。多態性語言具備靈活、抽象、行爲共享 、代碼共享的優點,很好的解決了應用程序函數同名問題。

 

2String是最基本的數據類型嗎?

基本數據類型包括byteintcharlongfloatdoublebooleanshort

java.lang.String類是final類型的,所以不能夠繼承這個類、不能修改這個類。爲了提升效率節省空間,咱們應該用StringBuffer

 

3int Integer 有什麼區別

Java 提供兩種不一樣的類型:引用類型和原始類型(或內置類型)。Intjava的原始數據類型,Integerjavaint提供的封裝類。

Java爲每一個原始類型提供了封裝類。

原始類型封裝類

booleanBoolean

charCharacter

byteByte

shortShort

intInteger

longLong

floatFloat

doubleDouble

引用類型和原始類型的行爲徹底不一樣,而且它們具備不一樣的語義。引用類型和原始類型具備不一樣的特徵和用法,它們包括:大小和速

度問題,這種類型以哪一種類型的數據結構存儲,當引用類型和原始類型用做某個類的實例數據時所指定的缺省值。對象引用實例變量

的缺省值爲 null,而原始類型實例變量的缺省值與它們的類型有關。

 

4String StringBuffer的區別

JAVA 平臺提供了兩個類:StringStringBuffer,它們能夠儲存和操做字符串,即包含多個字符的字符數據。這個String類提供了

數值不可改變的字符串。而這個StringBuffer類提供的字符串進行修改。當你知道字符數據要改變的時候你就能夠使用StringBuffer

。典型地,你能夠使用StringBuffers來動態構造字符數據。

 

5、運行時異常與通常異常有何異同?

異常表示程序運行過程當中可能出現的非正常狀態,運行時異常表示虛擬機的一般操做中可能遇到的異常,是一種常見運行錯誤。java

編譯器要求方法必須聲明拋出可能發生的非運行時異常,可是並不要求必須聲明拋出未被捕獲的運行時異常。

6、說出Servlet的生命週期,並說出ServletCGI的區別。

Servlet被服務器實例化後,容器運行其init方法,請求到達時運行其service方法,service方法自動派遣運行與請求對應的doXXX

法(doGetdoPost)等,當服務器決定將實例銷燬的時候調用其destroy方法。

cgi的區別在於servlet處於服務器進程中,它經過多線程方式運行其service方法,一個實例能夠服務於多個請求,而且其實例一

般不會銷燬,而CGI對每一個請求都產生新的進程,服務完成後就銷燬,因此效率上低於servlet

7、說出ArrayList,Vector, LinkedList的存儲性能和特性

ArrayList Vector都是使用數組方式存儲數據,此數組元素數大於實際存儲的數據以便增長和插入元素,它們都容許直接按序號索

引元素,可是插入元素要涉及數組元素移動等內存操做,因此索引數據快而插入數據慢,Vector因爲使用了synchronized方法(線程

安全),一般性能上較ArrayList差,而LinkedList使用雙向鏈表實現存儲,按序號索引數據須要進行前向或後向遍歷,可是插入數

據時只須要記錄本項的先後項便可,因此插入速度較快。

EJB是基於哪些技術實現的?並說出SessionBeanEntityBean的區別,StatefulBeanStatelessBean的區別。

EJB包括Session BeanEntity BeanMessage Driven Bean,基於JNDIRMIJAT等技術實現。

SessionBeanJ2EE應用程序中被用來完成一些服務器端的業務操做,例如訪問數據庫、調用其餘EJB組件。EntityBean被用來表明應

用系統中用到的數據。

對於客戶機,SessionBean是一種非持久性對象,它實現某些在服務器上運行的業務邏輯。

對於客戶機,EntityBean是一種持久性對象,它表明一個存儲在持久性存儲器中的實體的對象視圖,或是一個由現有企業應用程序實

現的實體。

Session Bean 還能夠再細分爲 Stateful Session Bean Stateless Session Bean ,這兩種的 Session Bean均可以將系統邏輯

放在 method之中執行,不一樣的是 Stateful Session Bean 能夠記錄呼叫者的狀態,所以一般來講,一個使用者會有一個相對應的  

Stateful Session Bean 的實體。Stateless Session Bean 雖然也是邏輯組件,可是他卻不負責記錄使用者狀態,也就是說當使用

者呼叫 Stateless Session Bean 的時候,EJB Container 並不會找尋特定的 Stateless Session Bean 的實體來執行這個 method

。換言之,極可能數個使用者在執行某個 Stateless Session Bean methods 時,會是同一個 Bean Instance 在執行。從內

存方面來看, Stateful Session Bean Stateless Session Bean 比較, Stateful Session Bean 會消耗 J2EE Server 較多的

內存,然而 Stateful Session Bean 的優點卻在於他能夠維持使用者的狀態。

9Collection Collections的區別。

  Collection是集合類的上級接口,繼承與他的接口主要有Set List.

Collections是針對集合類的一個幫助類,他提供一系列靜態方法實現對各類集合的搜索、排序、線程安全化等操做。

 

10&&&的區別。

&是位運算符,表示按位與運算,&&是邏輯運算符,表示邏輯與(and

12final, finally, finalize的區別。

final 用於聲明屬性,方法和類,分別表示屬性不可變,方法不可覆蓋,類不可繼承。

finally是異常處理語句結構的一部分,表示老是執行。

finalizeObject類的一個方法,在垃圾收集器執行的時候會調用被回收對象的此方法,能夠覆蓋此方法提供垃圾收集時的其餘資源

回收,例如關閉文件等。

13sleep() wait() 有什麼區別?

sleep是線程類(Thread)的方法,致使此線程暫停執行指定時間,把執行機會給其餘線程,可是監控狀態依然保持,到時後會自動

恢復。調用sleep不會釋放對象鎖。

waitObject類的方法,對此對象調用wait方法致使本線程放棄對象鎖,進入等待此對象的等待鎖定池,只有針對此對象發出notify

方法(或notifyAll)後本線程才進入對象鎖定池準備得到對象鎖進入運行狀態。

14OverloadOverride的區別。Overloaded的方法是否能夠改變返回值的類型?

方法的重寫Overriding和重載OverloadingJava多態性的不一樣表現。重寫Overriding是父類與子類之間多態性的一種表現,重載

Overloading是一個類中多態性的一種表現。若是在子類中定義某方法與其父類有相同的名稱和參數,咱們說該方法被重寫  

(Overriding)。子類的對象使用這個方法時,將調用子類中的定義,對它而言,父類中的定義如同被"屏蔽"了。若是在一個類中定義

了多個同名的方法,它們或有不一樣的參數個數或有不一樣的參數類型,則稱爲方法的重載(Overloading)Overloaded的方法是能夠改

變返回值的類型。

16、同步和異步有何異同,在什麼狀況下分別使用他們?舉例說明。

若是數據將在線程間共享。例如正在寫的數據之後可能被另外一個線程讀到,或者正在讀的數據可能已經被另外一個線程寫過了,那麼這

些數據就是共享數據,必須進行同步存取。

當應用程序在對象上調用了一個須要花費很長時間來執行的方法,而且不但願讓程序等待方法的返回時,就應該使用異步編程,在很

多狀況下采用異步途徑每每更有效率。

17abstract classinterface有什麼區別?

聲明方法的存在而不去實現它的類被叫作抽象類(abstract class),它用於要建立一個體現某些基本行爲的類,併爲該類聲明方法

,但不能在該類中實現該類的狀況。不能建立abstract 類的實例。然而能夠建立一個變量,其類型是一個抽象類,並讓它指向具體

子類的一個實例。不能有抽象構造函數或抽象靜態方法。Abstract 類的子類爲它們父類中的全部抽象方法提供實現,不然它們也是

抽象類爲。取而代之,在子類中實現該方法。知道其行爲的其它類能夠在類中實現這些方法。

接口(interface)是抽象類的變體。在接口中,全部方法都是抽象的。多繼承性可經過實現這樣的接口而得到。接口中的全部方法

都是抽象的,沒有一個有程序體。接口只能夠定義static final成員變量。接口的實現與子類類似,除了該實現類不能從接口定義中

繼承行爲。當類實現特殊接口時,它定義(即將程序體給予)全部這種接口的方法。而後,它能夠在實現了該接口的類的任何對象上

調用接口的方法。因爲有抽象類,它容許使用接口名做爲引用變量的類型。一般的動態聯編將生效。引用能夠轉換到接口類型或從接

口類型轉換,instanceof 運算符能夠用來決定某對象的類是否實現了接口。

18heapstack有什麼區別。

棧是一種線形集合,其添加和刪除元素的操做應在同一段完成。棧按照後進先出的方式進行處理。

堆是棧的一個組成元素

21Static Nested Class Inner Class的不一樣。

Static Nested Class是被聲明爲靜態(static)的內部類,它能夠不依賴於外部類實例被實例化。而一般的內部類須要在外部類實

例化後才能實例化。

26Math.round(11.5)等於多少? Math.round(-11.5)等於多少?

Math.round(11.5)==12

Math.round(-11.5)==-11

round方法返回與參數最接近的長整數,參數加1/2後求其floor.

28、設計4個線程,其中兩個線程每次對j增長1,另外兩個線程對j每次減小1。寫出程序。

如下程序使用內部類實現線程,對j增減的時候沒有考慮順序問題。

public class ThreadTest1{

private int j;

public static void main(String args[]){

ThreadTest1 tt=new ThreadTest1();

Inc inc=tt.new Inc();

Dec dec=tt.new Dec();

for(int i=0;i<2;i++){

Thread t=new Thread(inc);

t.start();

t=new Thread(dec);

t.start();

}

}

private synchronized void inc(){

j++;

System.out.println(Thread.currentThread().getName()+"-inc:"+j);

}

private synchronized void dec(){

j--;

System.out.println(Thread.currentThread().getName()+"-dec:"+j);

}

class Inc implements Runnable{

public void run(){

for(int i=0;i<100;i++){

inc();

}

}

}

class Dec implements Runnable{

public void run(){

for(int i=0;i<100;i++){

dec();

}

}

}

}

 

29Java有沒有goto?

java中的保留字,如今沒有在java中使用。

30、啓動一個線程是用run()仍是start()?

啓動一個線程是調用start()方法,使線程所表明的虛擬處理機處於可運行狀態,這意味着它能夠由JVM調度並執行。這並不意味着線 程就會當即運行。run()方法能夠產生必須退出的標誌來中止一個線程。

 

33、給我一個你最多見到的runtime exception

ArithmeticException, ArrayStoreException, BufferOverflowException, BufferUnderflowException, CannotRedoException,  

CannotUndoException, ClassCastException, CMMException, ConcurrentModificationException, DOMException,  

EmptyStackException, IllegalArgumentException, IllegalMonitorStateException, IllegalPathStateException,  

IllegalStateException, ImagingOpException, IndexOutOfBoundsException, MissingResourceException,  

NegativeArraySizeException, NoSuchElementException, NullPointerException, ProfileDataException, ProviderException,  

RasterFormatException, SecurityException, SystemException, UndeclaredThrowableException, UnmodifiableSetException,  

UnsupportedOperationException

34、接口是否可繼承接口? 抽象類是否可實現(implements)接口? 抽象類是否可繼承實體類(concrete class)?

接口能夠繼承接口。抽象類能夠實現(implements)接口,抽象類是否可繼承實體類,但前提是實體類必須有明確的構造函數。

36、說出數據鏈接池的工做機制是什麼?

J2EE 服務器啓動時會創建必定數量的池鏈接,並一直維持很多於此數目的池鏈接。客戶端程序須要鏈接時,池驅動程序會返回一個

未使用的池鏈接並將其表記爲忙。若是當前沒有空閒鏈接,池驅動程序就新建必定數量的鏈接,新建鏈接的數量由配置參數決定。當

使用的池鏈接調用完成後,池驅動程序將此鏈接表記爲空閒,其餘調用就能夠使用這個鏈接。

38、數組有沒有length()這個方法? String有沒有length()這個方法?

數組沒有length()這個方法,有length的屬性。String有有length()這個方法。

39Set裏的元素是不能重複的,那麼用什麼方法來區分重複與否呢? 是用==仍是equals()? 它們有何區別?

Set裏的元素是不能重複的,那麼用iterator()方法來區分重複與否。equals()是判讀兩個Set是否相等。

equals()==方法決定引用值是否指向同一對象equals()在類中被覆蓋,爲的是當兩個分離的對象的內容和類型相配的話,返回真值

40、構造器Constructor是否可被override?

構造器Constructor不能被繼承,所以不能重寫Overriding,但能夠被重載Overloading

42swtich是否能做用在byte上,是否能做用在long上,是否能做用在String?

switchexpr1)中,expr1是一個整數表達式。所以傳遞給 switch case 語句的參數應該是 intshortchar 或者 byte

long,string 都不能做用於swtich

43try {}裏有一個return語句,那麼緊跟在這個try後的finally {}裏的code會不會被執行,何時被執行,在return前仍是後?

會執行,在return前執行。

8、編程題: 寫一個Singleton出來。

Singleton模式主要做用是保證在Java應用程序中,一個類Class只有一個實例存在。

通常Singleton模式一般有幾種種形式:

第一種形式: 定義一個類,它的構造函數爲private的,它有一個staticprivate的該類變量,在類初始化時實例話,經過一個

publicgetInstance方法獲取對它的引用,繼而調用其中的方法。

public class Singleton {

private Singleton(){}

   //在本身內部定義本身一個實例,是否是很奇怪?

   //注意這是private 只供內部調用

   private static Singleton instance = new Singleton();

   //這裏提供了一個供外部訪問本class的靜態方法,能夠直接訪問  

   public static Singleton getInstance() {

     return instance;   

   }

}

第二種形式:

public class Singleton {

  private static Singleton instance = null;

  public static synchronized Singleton getInstance() {

  //這個方法比上面有所改進,不用每次都進行生成對象,只是第一次    

  //使用時生成實例,提升了效率!

  if (instance==null)

    instancenew Singleton();

return instance;   }

}

其餘形式:

定義一個類,它的構造函數爲private的,全部方法爲static的。

通常認爲第一種形式要更加安全些

45、兩個對象值相同(x.equals(y) == true),但卻可有不一樣的hash code,這句話對不對?

不對,有相同的hash code

46、當一個對象被看成參數傳遞到一個方法後,此方法可改變這個對象的屬性,並可返回變化後的結果,那麼這裏究竟是值傳遞仍是

引用傳遞?

是值傳遞。Java 編程語言只有值傳遞參數。當一個對象實例做爲一個參數被傳遞到方法中時,參數的值就是對該對象的引用。對象

的內容能夠在被調用的方法中改變,但對象的引用是永遠不會改變的。

47、當一個線程進入一個對象的一個synchronized方法後,其它線程是否可進入此對象的其它方法?

不能,一個對象的一個synchronized方法只能由一個線程訪問。

48、編程題: 寫一個Singleton出來。

Singleton模式主要做用是保證在Java應用程序中,一個類Class只有一個實例存在。

通常Singleton模式一般有幾種種形式:

第一種形式: 定義一個類,它的構造函數爲private的,它有一個staticprivate的該類變量,在類初始化時實例話,經過一個

publicgetInstance方法獲取對它的引用,繼而調用其中的方法。

public class Singleton {

private Singleton(){}

   //在本身內部定義本身一個實例,是否是很奇怪?

   //注意這是private 只供內部調用

   private static Singleton instance = new Singleton();

   //這裏提供了一個供外部訪問本class的靜態方法,能夠直接訪問  

   public static Singleton getInstance() {

     return instance;   

   }

}

第二種形式:

public class Singleton {

  private static Singleton instance = null;

  public static synchronized Singleton getInstance() {

  //這個方法比上面有所改進,不用每次都進行生成對象,只是第一次    

  //使用時生成實例,提升了效率!

  if (instance==null)

    instancenew Singleton();

return instance;   }

}

其餘形式:

定義一個類,它的構造函數爲private的,全部方法爲static的。

通常認爲第一種形式要更加安全些

 

49Java的接口和C++的虛類的相同和不一樣處。

因爲Java不支持多繼承,而有可能某個類或對象要使用分別在幾個類或對象裏面的方法或屬性,現有的單繼承機制就不能知足要求。

與繼承相比,接口有更高的靈活性,由於接口中沒有任何實現代碼。當一個類實現了接口之後,該類要實現接口裏面全部的方法和屬

性,而且接口裏面的屬性在默認狀態下面都是public static,全部方法默認狀況下是public.一個類能夠實現多個接口。

50Java中的異常處理機制的簡單原理和應用。

JAVA 程序違反了JAVA的語義規則時,JAVA虛擬機就會將發生的錯誤表示爲一個異常。違反語義規則包括2種狀況。一種是JAVA類庫

內置的語義檢查。例如數組下標越界,會引起IndexOutOfBoundsException;訪問null的對象時會引起NullPointerException。另外一種

狀況就是JAVA容許程序員擴展這種語義檢查,程序員能夠建立本身的異常,並自由選擇在什麼時候用throw關鍵字引起異常。全部的異常

都是 java.lang.Thowable的子類。

 

51、垃圾回收的優勢和原理。並考慮2種回收機制。

Java 語言中一個顯著的特色就是引入了垃圾回收機制,使c++程序員最頭疼的內存管理的問題迎刃而解,它使得Java程序員在編寫程

序的時候再也不須要考慮內存管理。因爲有個垃圾回收機制,Java中的對象再也不有"做用域"的概念,只有對象的引用纔有"做用域"。垃

圾回收能夠有效的防止內存泄露,有效的使用能夠使用的內存。垃圾回收器一般是做爲一個單獨的低級別的線程運行,不可預知的情

況下對內存堆中已經死亡的或者長時間沒有使用的對象進行清楚和回收,程序員不能實時的調用垃圾回收器對某個對象或全部對象進

行垃圾回收。回收機制有分代複製垃圾回收和標記垃圾回收,增量垃圾回收。

 

52、請說出你所知道的線程同步的方法。

wait():使一個線程處於等待狀態,而且釋放所持有的對象的lock

sleep():使一個正在運行的線程處於睡眠狀態,是一個靜態方法,調用此方法要捕捉InterruptedException異常。

notify():喚醒一個處於等待狀態的線程,注意的是在調用此方法的時候,並不能確切的喚醒某一個等待狀態的線程,而是由JVM肯定

喚醒哪一個線程,並且不是按優先級。

Allnotity():喚醒全部處入等待狀態的線程,注意並非給全部喚醒線程一個對象的鎖,而是讓它們競爭。

53、你所知道的集合類都有哪些?主要方法?

最經常使用的集合類是 List MapList 的具體實現包括 ArrayList Vector,它們是可變大小的列表,比較適合構建、存儲和操

做任何類型對象的元素列表。 List 適用於按數值索引訪問元素的情形。

Map 提供了一個更通用的元素存儲方法。 Map 集合類用於存儲元素對(稱做""""),其中每一個鍵映射到一個值。

54、描述一下JVM加載class文件的原理機制?

JVM中類的裝載是由ClassLoader和它的子類來實現的,Java ClassLoader 是一個重要的Java運行時系統組件。它負責在運行時查找和

裝入類文件的類。

 

55char型變量中能不能存貯一箇中文漢字?爲何?

可以定義成爲一箇中文的,由於java中以unicode編碼,一個char2個字節(Byte)16位(bit),因此放一箇中文是沒問題的

57JSP的內置對象及方法。

request表示HttpServletRequest對象。它包含了有關瀏覽器請求的信息,而且提供了幾個用於獲取cookie, header, session數據的有用的方法。

response表示HttpServletResponse對象,並提供了幾個用於設置送回瀏覽器的響應的方法(如cookies,頭信息等)

out對象是javax.jsp.JspWriter的一個實例,並提供了幾個方法使你能用於向瀏覽器回送輸出結果。

pageContext表示一個javax.servlet.jsp.PageContext對象。它是用於方便存取各類範圍的名字空間、servlet相關的對象的API,而且包裝了通用的servlet相關功能的方法。

session表示一個請求的javax.servlet.http.HttpSession對象。Session能夠存貯用戶的狀態信息

applicaton 表示一個javax.servle.ServletContext對象。這有助於查找有關servlet引擎和servlet環境的信息

config表示一個javax.servlet.ServletConfig對象。該對象用於存取servlet實例的初始化參數。

page表示從該頁面產生的一個servlet實例

58、線程的基本概念、線程的基本狀態以及狀態之間的關係

線程指在程序執行過程當中,可以執行程序代碼的一個執行單位,每一個程序至少都有一個線程,也就是程序自己。

Java中的線程有四種狀態分別是:運行、就緒、掛起、結束。

67J2EE是技術仍是平臺仍是框架?

J2EE自己是一個標準,一個爲企業分佈式應用的開發提供的標準平臺。

J2EE也是一個框架,包括JDBCJNDIRMIJMSEJBJTA等技術。

68、咱們在web應用開發過程當中常常遇到輸出某種編碼的字符,如iso8859-1等,如何輸出一個某種編碼的字符串?

Public String translate (String str) {

String tempStr = "";

try {

tempStr = new String(str.getBytes("ISO-8859-1"), "GBK");

tempStr = tempStr.trim();

}

catch (Exception e) {

System.err.println(e.getMessage());

}

return tempStr;

}

69、簡述邏輯操做(&,|,^)與條件操做(&&,||)的區別。

區別主要答兩點:a.條件操做只能操做布爾型的,而邏輯操做不只能夠操做布爾型,並且能夠操做數值型

b.邏輯操做不會產生短路

70XML文檔定義有幾種形式?它們之間有何本質區別?解析XML文檔有哪幾種方式?

a: 兩種形式 dtd schema

b: 本質區別:schema自己是xml的,能夠被XML解析器解析(這也是從DTD上發展schema的根本目的)

c:DOM,SAX,STAX

DOM:處理大型文件時其性能降低的很是厲害。這個問題是由DOM的樹結構所形成的,這種結構佔用的內存較多,並且DOM必須在解析文

件以前把整個文檔裝入內存,適合對XML的隨機訪問

SAX:不現於DOM,SAX是事件驅動型的XML解析方式。它順序讀取XML文件,不須要一次所有裝載整個文件。當遇到像文件開頭,文檔結

束,或者標籤開頭與標籤結束時,它會觸發一個事件,用戶經過在其回調事件中寫入處理代碼來處理XML文件,適合對XML的順序訪問

STAX:Streaming API for XML (StAX)

xml文檔有兩種定義方法:

dtd:數據類型定義(data type definition),用以描述XML文檔的文檔結構,是早期的XML文檔定義形式。

schema:其自己是基於XML語言編寫的,在類型和語法上的限定能力比dtd強,處理也比較方便,由於此正逐漸代替dtd成爲新的模式

定義語言。

 

71、簡述synchronizedjava.util.concurrent.locks.Lock的異同?

主要相同點:Lock能完成synchronized所實現的全部功能

主要不一樣點:Lock有比synchronized更精確的線程語義和更好的性能。synchronized會自動釋放鎖,而Lock必定要求程序員手工釋放

,而且必須在finally從句中釋放。

 

72EJB的角色和三個對象

一個完整的基於EJB的分佈式計算結構由六個角色組成,這六個角色能夠由不一樣的開發商提供,每一個角色所做的工做必須遵循Sun公司

提供的EJB規範,以保證彼此之間的兼容性。這六個角色分別是EJB組件開發者(Enterprise Bean Provider) 、應用組合者

Application Assembler)、部署者(Deployer)、EJB 服務器提供者(EJB Server Provider)、EJB 容器提供者(EJB  

Container Provider)、系統管理員(System Administrator

三個對象是RemoteLocal)接口、HomeLocalHome)接口,Bean

 

73EJB容器提供的服務

主要提供聲明週期管理、代碼產生、持續性管理、安全、事務管理、鎖和併發行管理等服務。

 

74EJB規範規定EJB中禁止的操做有哪些?

1. 不能操做線程和線程API(線程API指非線程對象的方法如notify,wait)2.不能操做awt3.不能實現服務器功能,4.不能對靜

態屬生存取,5.不能使用IO操做直接存取文件系統,6.不能加載本地庫.7.不能將this做爲變量和返回,8.不能循環調用。

 

75remote接口和home接口主要做用

remote接口定義了業務方法,用於EJB客戶端調用業務方法。

home接口是EJB工廠用於建立和移除查找EJB實例

 

76bean 實例的生命週期

對於Stateless Session BeanEntity BeanMessage Driven Bean通常存在緩衝池管理,而對於Entity BeanStatefull Session  

Bean存在Cache管理,一般包含建立實例,設置上下文、建立EJB Objectcreate)、業務方法調用、remove等過程,對於存在緩衝

池管理的Bean,在create以後實例並不從內存清除,而是採用緩衝池調度機制不斷重用實例,而對於存在Cache管理的Bean則經過激

活和去激活機制保持Bean的狀態並限制內存中實例數量。

 

77EJB的激活機制

Stateful Session Bean 爲例:其Cache大小決定了內存中能夠同時存在的Bean實例的數量,根據MRUNRU算法,實例在激活和去

激活狀態之間遷移,激活機制是當客戶端調用某個EJB實例業務方法時,若是對應EJB Object發現本身沒有綁定對應的Bean實例則從

其去激活Bean存儲中(經過序列化機制存儲實例)回覆(激活)此實例。狀態變遷前會調用對應的 ejbActiveejbPassivate方法。

 

78EJB的幾種類型

會話(SessionBean ,實體(EntityBean 消息驅動的(Message DrivenBean

會話Bean又可分爲有狀態(Stateful)和無狀態(Stateless)兩種

實體Bean可分爲Bean管理的持續性(BMP)和容器管理的持續性(CMP)兩種

 

79、客服端調用EJB對象的幾個基本步驟

設置JNDI服務工廠以及JNDI服務地址系統屬性,查找Home接口,從Home接口調用Create方法建立Remote接口,經過Remote接口調用其

業務方法。

 

80、如何給weblogic指定大小的內存?

在啓動Weblogic的腳本中(位於所在Domian對應服務器目錄下的startServerName),增長set MEM_ARGS=-Xms32m -Xmx200m,能夠調

整最小內存爲32M,最大200M

 

81、如何設定的weblogic的熱啓動模式(開發模式)與產品發佈模式?

能夠在管理控制檯中修改對應服務器的啓動模式爲開發或產品模式之一。或者修改服務的啓動文件或者commenv文件,增長set  

PRODUCTION_MODE=true

 

82、如何啓動時不需輸入用戶名與密碼?

修改服務啓動文件,增長 WLS_USERWLS_PW項。也能夠在boot.properties文件中增長加密過的用戶名和密碼.

 

83、在weblogic管理制臺中對一個應用域(或者說是一個網站,Domain)進行jmsejb或鏈接池等相關信息進行配置後,實際保存在什麼

文件中?

保存在此Domainconfig.xml文件中,它是服務器的核心配置文件。

 

84、說說weblogic中一個Domain的缺省目錄結構?好比要將一個簡單的helloWorld.jsp放入何目錄下,然的在瀏覽器上就可打入主機:

端口號//helloword.jsp就能夠看到運行結果了? 又好比這其中用到了一個本身寫的javaBean該如何辦?

Domain 目錄服務器目錄applications,將應用目錄放在此目錄下將能夠做爲應用訪問,若是是Web應用,應用目錄須要知足Web應用

目錄要求,jsp文件能夠直接放在應用目錄中,Javabean須要放在應用目錄的WEB-INF目錄的classes目錄中,設置服務器的缺省應用

將能夠實如今瀏覽器上無需輸入應用名。

 

85、在weblogic中發佈ejb需涉及到哪些配置文件

不一樣類型的EJB涉及的配置文件不一樣,都涉及到的配置文件包括ejb-jar.xml,weblogic-ejb-jar.xmlCMP實體Bean通常還須要

weblogic-cmp-rdbms-jar.xml

 

86、如何在weblogic中進行ssl配置與客戶端的認證配置或說說j2ee(標準)進行ssl的配置

缺省安裝中使用DemoIdentity.jksDemoTrust.jks KeyStore實現SSL,須要配置服務器使用Enable SSL,配置其端口,在產品模式

下須要從CA獲取私有密鑰和數字證書,建立identitytrust keystore,裝載得到的密鑰和數字證書。能夠配置此SSL鏈接是單向還

是雙向的。

 

87、如何查看在weblogic中已經發布的EJB?

能夠使用管理控制檯,在它的Deployment中能夠查看全部已發佈的EJB

 

88CORBA是什麼?用途是什麼?

CORBA 標準是公共對象請求代理結構(Common Object Request Broker Architecture),由對象管理組織 (Object Management Group

,縮寫爲 OMG)標準化。它的組成是接口定義語言(IDL), 語言綁定(binding:也譯爲聯編)和容許應用程序間互操做的協議。其目的爲

:用不一樣的程序設計語言書寫在不一樣的進程中運行,爲不一樣的操做系統開發。

 

89、說說你所熟悉或據說過的j2ee中的幾種經常使用模式?及對設計模式的一些見解

Session Facade Pattern:使用SessionBean訪問EntityBean

Message Facade Pattern:實現異步調用

EJB Command Pattern:使用Command JavaBeans取代SessionBean,實現輕量級訪問

Data Transfer Object Factory:經過DTO Factory簡化EntityBean數據提供特性

Generic Attribute Access:經過AttibuteAccess接口簡化EntityBean數據提供特性

Business Interface:經過遠程(本地)接口和Bean類實現相同接口規範業務邏輯一致性

EJB架構的設計好壞將直接影響系統的性能、可擴展性、可維護性、組件可重用性及開發效率。項目越複雜,項目隊伍越龐大則越

能體現良好設計的重要性。

90、說說在weblogic中開發消息Bean時的persistentnon-persisten的差異

persistent方式的MDB能夠保證消息傳遞的可靠性,也就是若是EJB容器出現問題而JMS服務器依然會將消息在此MDB可用的時候發送過

來,而nonpersistent方式的消息將被丟棄。

既然沒有標準答案,就根據本身的所瞭解的,補充修正一下好了

 

91Servlet執行時通常實現哪幾個方法?

public void init(ServletConfig config)

public ServletConfig getServletConfig()

public String getServletInfo()

public void service(ServletRequest request,ServletResponse response)

public void destroy()

init ()方法在servlet的生命週期中僅執行一次,在服務器裝載servlet時執行。缺省的init()方法一般是符合要求的,不過也能夠

根據須要進行 override,好比管理服務器端資源,一次性裝入GIF圖像,初始化數據庫鏈接等,缺省的inti()方法設置了servlet

初始化參數,並用它的ServeltConfig對象參數來啓動配置,因此覆蓋init()方法時,應調用super.init()以確保仍然執行這些任務

service ()方法是servlet的核心,在調用service()方法以前,應確保已完成init()方法。對於HttpServlet,每當客戶請求一個  

HttpServlet對象,該對象的service()方法就要被調用,HttpServlet缺省的service()方法的服務功能就是調用與 HTTP請求的方法

相應的do功能,doPost()doGet(),因此對於HttpServlet,通常都是重寫doPost()doGet() 方法。

destroy()方法在servlet的生命週期中也僅執行一次,即在服務器中止卸載servlet時執行,把servlet做爲服務器進程的一部分關閉

。缺省的destroy()方法一般是符合要求的,但也能夠override,好比在卸載servlet時將統計數字保存在文件中,或是關閉數據庫連

接。

getServletConfig()方法返回一個servletConfig對象,該對象用來返回初始化參數和servletContextservletContext接口提供有

servlet的環境信息。

getServletInfo()方法提供有關servlet的信息,如做者,版本,版權。

 

92j2ee經常使用的設計模式?說明工廠模式。

Java中的23種設計模式:

Factory(工廠模式), Builder(建造模式), Factory Method(工廠方法模式),

Prototype(原始模型模式),Singleton(單例模式), Facade(門面模式),

Adapter(適配器模式), Bridge(橋樑模式), Composite(合成模式),

Decorator(裝飾模式), Flyweight(享元模式), Proxy(代理模式),

Command(命令模式), Interpreter(解釋器模式), Visitor(訪問者模式),

Iterator(迭代子模式), Mediator(調停者模式), Memento(備忘錄模式),

Observer(觀察者模式), State(狀態模式), Strategy(策略模式),

Template Method(模板方法模式), Chain Of Responsibleity(責任鏈模式)

工廠模式:工廠模式是一種常常被使用到的模式,根據工廠模式實現的類能夠根據提供的數據生成一組類中某一個類的實例,一般這

一組類有一個公共的抽象父類而且實現了相同的方法,可是這些方法針對不一樣的數據進行了不一樣的操做。首先須要定義一個基類,該

類的子類經過不一樣的方法實現了基類中的方法。而後須要定義一個工廠類,工廠類能夠根據條件生成不一樣的子類實例。當獲得子類的

實例後,開發人員能夠調用基類中的方法而沒必要考慮到底返回的是哪個子類的實例。

 

93EJB需直接實現它的業務接口或Home接口嗎,請簡述理由。

遠程接口和Home接口不須要直接實現,他們的實現代碼是由服務器產生的,程序運行中對應實現類會做爲對應接口類型的實例被使用

其實一直都不是很明白EJBremote接口,home接口,Bean類到底是如何使用的,或許應該進一步瞭解EJB的原理吧,查到了一個原創

文章,那就說說EJB調用的原理吧。其實在這個問題上,最須要理解的是RMI機制原理。

一個遠程對象至少要包括4class文件:遠程對象、遠程對象接口、實現遠程接口的對象的stub、對象的skeleton

而在EJB中則至少要包括10class:

Bean類,特定App ServerBean實現類

Beanremote接口,特定App Serverremote接口實現類,特定App Serverremote接口的實現類的stub類和skeleton類。

Beanhome接口,特定App Serverhome接口實現類,特定App Serverhome接口的實現類的stub類和skeleton類。

RMI不一樣的是,EJB中這10class真正須要用戶寫的只有3個,Bean類,remote接口,home接口,其它的7個究竟怎麼生成,被打包

在哪裏,是否須要更多的類文件,否根據不一樣的App Server表現出較大的差別。

Weblogic

home接口和remote接口的weblogic的實現類的stub類和skeleton類是在EJB被部署到weblogic的時候,由weblogic動態生成stub類和

skeleton類的字節碼,因此看不到這4個類文件。

對於一次客戶端遠程調用EJB,要通過兩個遠程對象的屢次RMI循環。首先是經過JNDI查找Home接口,得到Home接口的實現類,這個過

程其實至關複雜,首先是找到Home接口的Weblogic實現類,而後建立一個Home接口的Weblogic實現類的stub類的對象實例,將它序列

化傳送給客戶端(注意stub類的實例是在第1RMI循環中,由服務器動態發送給客戶端的,所以不須要客戶端保存Home接口的

Weblogic實現類的stub 類),最後客戶端得到該stub類的對象實例(普通的RMI須要在客戶端保存stub類,而EJB不須要,由於服務

器會把stub類的對象實例發送給客戶端)。

客戶端拿到服務器給它的Home接口的Weblogic實現類的stub類對象實例之後,調用stub類的create方法, (在代碼上就是

home.create(),可是後臺要作不少事情),因而通過第2RMI循環,在服務器端,Home接口的Weblogic實現類的 skeleton類收到stub

類的調用信息後,由它再去調用Home接口的Weblogic實現類的create方法。

在服務端, Home接口的Weblogic實現類的create方法再去調用Bean類的Weblogic實現類的ejbCreate方法,在服務端建立或者分配一

EJB實例,而後將這個EJB實例的遠程接口的Weblogic實現類的stub類對象實例序列化發送給客戶端。

 

客戶端收到 remote接口的Weblogic實現類的stub類的對象實例,對該對象實例的方法調用(在客戶端代碼中實際上就是對remote

口的調用),將傳送給服務器端remote接口的Weblogic實現類的skeleton類對象,而skeleton類對象再調用相應的remote接口的  

Weblogic實現類,而後remote接口的Weblogic實現類再去調用Bean類的Weblogic實現類,如此就完成一次EJB對象的遠程調用。

先拿普通RMI來講,有4class,分別是遠程對象,對象的接口,對象的stub類和skeleton類。而對象自己和對象的stub類同時都實

現了接口類。而咱們在客戶端代碼調用遠程對象的時候,雖然在代碼中操縱接口,實質上是在操縱stub類,例如:

接口類:Hello

遠程對象:Hello_Server

stub類:Hello_Stub

skeleton類:Hello_Skeleton

 

客戶端代碼要這樣寫:

Hello h = new Hello_Stub();

h.getString();

 

咱們不會這些寫:

Hello_Stub h = new Hello_Stub();

h.getString();

 

由於使用接口適用性更廣,就算更換了接口實現類,也不須要更改代碼。所以客戶端須要Hello.classHello_Stub.class這兩個文

件。可是對於EJB來講,就不須要Hello_Stub.class,由於服務器會發送給它,可是Hello.class文件客戶端是省不了的,必須有。表

面上咱們的客戶端代碼在操縱Hello,但別忘記了Hello只是一個接口,抽象的,實質上是在操縱Hello_Stub

Weblogic上的EJB舉例子,10class分別是:

Bean類:HelloBean (用戶編寫)

Bean類的Weblogic實現類:HelloBean_Impl EJBC生成)

 

Home接口:HelloHome (用戶編寫)

Home接口的Weblogic實現類 HelloBean_HomeImplEJBC生成)

Home接口的Weblogic實現類的stubHelloBean_HomeImpl_WLStub(部署的時候動態生成字節碼)

Home接口的Weblogic實現類的skeletonHelloBean_HomeImpl_WLSkeleton(部署的時候動態生成字節碼)

 

Remote接口: Hello (用戶編寫)

Remote接口的Weblogic實現類 HelloBean_EOImplEJBC生成)

Remote接口的Weblogic實現類的stubHelloBean_EOImpl_WLStub(部署的時候動態生成字節碼)

Remote接口的Weblogic實現類的skeletonHelloBean_EOImpl_WLSkeleton(部署的時候動態生成字節碼)

 

客戶端只須要Hello.classHelloHome.class這兩個文件。

 

HelloHome home = (Home) PortableRemoteObject.narrow(ctx.lookup("Hello"), HelloHome.class);

 

這一行代碼是從JNDI得到Home接口,可是請記住!接口是抽象的,那麼home這個對象究竟是什麼類的對象實例呢?很簡單,用

toString()輸出看一下就明白了,下面一行是輸出結果:

HelloBean_HomeImpl_WLStub@18c458

這代表home這個經過從服務器的JNDI樹上查找得到的對象其實是HelloBean_HomeImpl_WLStub類的一個實例。

接下來客戶端代碼:

 

Hello h = home.create()

 

一樣Hello只是一個抽象的接口,那麼h對象是什麼東西呢?打印一下:

HelloBean_EOImpl_WLStub@8fa0d1

原來是HelloBean_EOImpl_WLStub的一個對象實例。

 

用這個例子來簡述一遍EJB調用過程:

 

首先客戶端JNDI查詢,服務端JNDI樹上Hello這個名字實際上綁定的對象是HelloBean_HomeImpl_WLStub,因此服務端將建立

HelloBean_HomeImpl_WLStub的一個對象實例,序列化返回給客戶端。

 

因而客戶端獲得home對象,表面上是獲得HelloHome接口的實例,其實是進行了一次遠程調用獲得了 HelloBean_HomeImpl_WLStub

類的對象實例,別忘記了HelloBean_HomeImpl_WLStub也實現了 HelloHome接口。

 

而後home.create()實質上就是 HelloBean_HomeImpl_WLStub.create(),該方法將發送信息給 HelloBean_HomeImpl_WLSkeleton,而

HelloBean_HomeImpl_WLSkeleton接受到信息後,再去調用 HelloBean_HomeImplcreate方法,至此完成第1次完整的RMI循環。

 

注意在此次RMI循環過程當中,遠程對象是HelloBean_HomeImpl,遠程對象的接口是HelloHome,對象的stub

HelloBean_HomeImpl_WLStub,對象的skeletonHelloBean_HomeImpl_WLSkeleton

 

而後HelloBean_HomeImpl 再去調用HelloBean_ImplejbCreate方法,而HelloBean_ImplejbCreate方法將負責建立或者分配一個  

Bean實例,而且建立一個HelloBean_EOImpl_WLStub的對象實例。

 

這一步比較有趣的是,在前一步RMI循環中,遠程對象HelloBean_HomeImpl在客戶端有一個代理類HelloBean_HomeImpl_WLStub,但在

這一步, HelloBean_HomeImpl本身卻充當了HelloBean_Impl的代理類,只不過HelloBean_HomeImpl不在客戶端,而是在服務端,因

此不進行RMI

 

而後HelloBean_EOImpl_WLStub的對象實例序列化返回給客戶端,這一步也頗有趣,上次RMI過程,主角是HelloBean_HomeImpl和它的

代理類HelloBean_HomeImpl_WLStub,但這這一次換成了 HelloBean_EOImpl和它的代理類HelloBean_EOImpl_WLStub來玩了。

 

 

Hello h = home.create();h.helloWorld();

 

假設Hello接口有一個helloWorld遠程方法,那麼表面上是在調用Hello接口的helloWorld方法,其實是在調用

HelloBean_EOImpl_WLStubhelloWorld方法。

 

而後HelloBean_EOImpl_WLStubhelloWorld方法將發送信息給服務器上的 HelloBean_EOImpl_WLSkeleton,而

HelloBean_EOImpl_WLSkeleton收到信息之後,再去調用 HelloBean_EOImplhelloWorld方法。至此,完成第2次完整的RMI循環過程

 

在剛纔 HelloBean_EOImpl是做爲遠程對象被調用的,它的代理類是HelloBean_EOImpl_WLStub,但如今 HelloBean_EOImpl要做爲

HelloBean_Impl的代理類了。如今HelloBean_EOImpl去調用 HelloBean_ImplhelloWorld方法。注意!HelloBean_Impl繼承了

HelloBean,而HelloBean中的 helloWorld方法是咱們親自編寫的代碼,如今終於調用到了咱們編寫的代碼了!

 

至此,一次EJB調用過程終於完成。在整個過程當中,服務端主要要調用的類是HelloBean_ImplHelloBean_HomeImpl

HelloBean_HomeImpl_WLSkeletonHelloBean_EOImplHelloBean_EOImpl_WLSkeleton。客戶端主要調用的類是

HelloBean_HomeImpl_WLStubHelloBean_EOImpl_WLStub,這兩個類在客戶端代碼中並不會直接出現,出如今代碼中的類是他們的

接口HelloHomeHello,所以客戶端須要這兩個接口文件,而Stub是服務器傳送給他們的。

http://www.pbase.com/nobo123/image/27229257

http://forum.javaeye.com/viewtop ... der=asc&start=0

 

94、排序都有哪幾種方法?請列舉。用JAVA實現一個快速排序。

排序的方法有:插入排序(直接插入排序、希爾排序),交換排序(冒泡排序、快速排序),選擇排序(直接選擇排序、堆排序),

歸併排序,分配排序(箱排序、基數排序)

快速排序的僞代碼。

/ /使用快速排序方法對a[ 0 :n- 1 ]排序

a[ 0 :n- 1 ]中選擇一個元素做爲m i d d l e,該元素爲支點

把餘下的元素分割爲兩段left r i g h t,使得l e f t中的元素都小於等於支點,而right 中的元素都大於等於支點

遞歸地使用快速排序方法對left 進行排序

遞歸地使用快速排序方法對right 進行排序

所得結果爲l e f t + m i d d l e + r i g h t

 

95、請對如下在J2EE中經常使用的名詞進行解釋(或簡單描述)

web 容器:給處於其中的應用程序組件(JSPSERVLET)提供一個環境,使JSP,SERVLET直接和容器中的環境變量接接口互,沒必要關

注其它系統問題。主要有WEB服務器來實現。例如:TOMCAT,WEBLOGIC,WEBSPHERE等。該容器提供的接口嚴格遵照J2EE規範中的WEB  

APPLICATION 標準。咱們把遵照以上標準的WEB服務器就叫作J2EE中的WEB容器。

Web container:實現J2EE體系結構中Web組件協議的容器。這個協議規定了一個Web組件運行時的環境,包括安全,一致性,生命周

期管理,事務,配置和其它的服務。一個提供和JSPJ2EE平臺APIs界面相同服務的容器。一個Web container Web服務器或者J2EE

服務器提供。

EJB容器:Enterprise java bean 容器。更具備行業領域特點。他提供給運行在其中的組件EJB各類管理功能。只要知足J2EE規範的

EJB放入該容器,立刻就會被容器進行高效率的管理。而且能夠經過現成的接口來得到系統級別的服務。例如郵件服務、事務管理。

一個實現了J2EE體系結構中EJB組件規範的容器。

這個規範指定了一個Enterprise bean的運行時環境,包括安全,一致性,生命週期,事務,

配置,和其餘的服務。

JNDI:(Java Naming & Directory InterfaceJAVA命名目錄服務。主要提供的功能是:提供一個目錄系統,讓其它各地的應用程

序在其上面留下本身的索引,從而知足快速查找和定位分佈式應用程序的功能。

JMS:(Java Message ServiceJAVA消息服務。主要實現各個應用程序之間的通信。包括點對點和廣播。

JTA:(Java Transaction APIJAVA事務服務。提供各類分佈式事務服務。應用程序只需調用其提供的接口便可。

JAF:(Java Action FrameWorkJAVA安全認證框架。提供一些安全控制方面的框架。讓開發者經過各類部署和自定義實現本身的個

性安全控制策略。

RMI/IIOP: Remote Method Invocation /internet對象請求中介協議)他們主要用於經過遠程調用服務。例如,遠程有一臺計算機

上運行一個程序,它提供股票分析服務,咱們能夠在本地計算機上實現對其直接調用。固然這是要經過必定的規範才能在異構的系統

之間進行通訊。RMIJAVA特有的。

RMI-IIOP出現之前,只有RMICORBA兩種選擇來進行分佈式程序設計。RMI-IIOP綜合了RMICORBA的優勢,克服了他們的缺點,使

得程序員能更方便的編寫分佈式程序設計,實現分佈式計算。首先,RMI-IIOP綜合了RMI的簡單性和CORBA的多語言性(兼容性),其

RMI-IIOP克服了RMI只能用於Java 的缺點和CORBA的複雜性(能夠不用掌握IDL)。

 

96JAVA語言如何進行異常處理,關鍵字:throws,throw,try,catch,finally分別表明什麼意義?在try塊中能夠拋出異常嗎?

Java 經過面向對象的方法進行異常處理,把各類不一樣的異常進行分類,並提供了良好的接口。在Java中,每一個異常都是一個對象,

它是Throwable類或其它子類的實例。當一個方法出現異常後便拋出一個異常對象,該對象中包含有異常信息,調用這個對象的方法

能夠捕獲到這個異常並進行處理。Java的異常處理是經過5個關鍵詞來實現的:trycatchthrowthrowsfinally。通常狀況下

是用try來執行一段程序,若是出現異常,系統會拋出(throws)一個異常,這時候你能夠經過它的類型來捕捉(catch)它,或最後

finally)由缺省處理器來處理。

try來指定一塊預防全部"異常"的程序。緊跟在try程序後面,應包含一個catch子句來指定你想要捕捉的"異常"的類型。

throw語句用來明確地拋出一個"異常"

throws用來標明一個成員函數可能拋出的各類"異常"

Finally爲確保一段代碼無論發生什麼"異常"都被執行一段代碼。

能夠在一個成員函數調用的外面寫一個try語句,在這個成員函數內部寫另外一個try語句保護其餘代碼。每當遇到一個try語句,"異常

"的框架就放到堆棧上面,直到全部的try語句都完成。若是下一級的try語句沒有對某種"異常"進行處理,堆棧就會展開,直到遇到

有處理這種"異常"try語句。

http://www.programfan.com/article/showarticle.asp?id=2731

 

97、一個".java"源文件中是否能夠包括多個類(不是內部類)?有什麼限制?

能夠。必須只有一個類名與文件名相同。

 

98MVC的各個部分都有那些技術來實現?如何實現?

MVC ModelViewController的簡寫。"Model" 表明的是應用的業務邏輯(經過JavaBeanEJB組件實現), "View" 是應用的表

示面,用於與用戶的交互(由JSP頁面產生),"Controller" 是提供應用的處理過程控制(通常是一個Servlet),經過這種設計模

型把應用邏輯,處理過程和顯示邏輯分紅不一樣的組件實現。這些組件能夠進行交互和重用。

model層實現系統中的業務邏輯,view層用於與用戶的交互,controller層是modelview之間溝通的橋樑,能夠分派用戶的請求並選

擇恰當的視圖以用於顯示,同時它也能夠解釋用戶的輸入並將它們映射爲模型層可執行的操做。

 

99java中有幾種方法能夠實現一個線程?用什麼關鍵字修飾同步方法? stop()suspend()方法爲什麼不推薦使用?

有兩種實現方法,分別是繼承Thread類與實現Runnable接口

synchronized關鍵字修飾同步方法

反對使用stop(),是由於它不安全。它會解除由線程獲取的全部鎖定,並且若是對象處於一種不連貫狀態,那麼其餘線程能在那種狀

態下檢查和修改它們。結果很難檢查出真正的問題所在。suspend()方法容易發生死鎖。調用suspend()的時候,目標線程會停下來,

但卻仍然持有在這以前得到的鎖定。此時,其餘任何線程都不能訪問鎖定的資源,除非被"掛起"的線程恢復運行。對任何線程來講,

若是它們想恢復目標線程,同時又試圖使用任何一個鎖定的資源,就會形成死鎖。因此不該該使用suspend(),而應在本身的Thread

類中置入一個標誌,指出線程應該活動仍是掛起。若標誌指出線程應該掛起,便用 wait()命其進入等待狀態。若標誌指出線程應當恢復,則用一個notify()從新啓動線程。

00java中有幾種類型的流?JDK爲每種類型的流提供了一些抽象類以供繼承,請說出他們分別是哪些類?

字節流,字符流。字節流繼承於InputStream OutputStream,字符流繼承於InputStreamReader OutputStreamWriter。在java.io

中還有許多其餘的流,主要是爲了提升性能和使用方便。

101java中會存在內存泄漏嗎,請簡單描述。

的確存在Java的內存泄漏, 而且事態能夠變得至關嚴重

 

Java garbage collector自動釋放哪些內存裏面程序不在須要的對象, 以此避免大多數的其餘程序上下文的內存泄漏. 可是Java應用

程序依舊會有至關的內存泄漏. 查找緣由會十分困難.

有兩類主要的Java內存泄漏:

* 再也不須要的對象引用

* 未釋放的系統資源

2.2 非必要的對象引用

Java代碼經常保留對於再也不須要的對象引用, 而且這組織了內存的垃圾收集器的工做. Java對象一般被其餘對象包含引用, 爲此一個

單一對象能夠保持整個對象樹在內存中, 因而致使了以下問題:

* 在向數組添加對象之後遺漏了對於他們的處理

* 直到你再次使用對象的時候都不釋放引用. 好比一個菜單指令能夠插件一個對象實例引用而且不釋放便於之後再次調用的時候使用

, 可是也許永遠不會發生.

* 在其餘引用依然須要舊有狀態的時候貿然修改對象狀態. 好比當你爲了在一個文本文件裏面保存一些屬性而使用一個數組, 諸如"

字符個數"等字段在再也不須要的時候依然保留在內存當中.

* 容許一個長久執行的線程所引用的對象. 設置引用爲NULL也無濟於事, 在線程退出和空閒以前, 對象不會被收集釋放

2.3 未釋放的系統資源

Java方法能夠定位Java實例意外的堆內存, 諸如針對視窗和位圖的內存資源. Java經常經過JNI(Java Native Interface)調用C/C++

子程序定位這些資源.

102java中實現多態的機制是什麼?

方法的重寫Overriding和重載OverloadingJava多態性的不一樣表現。重寫Overriding是父類與子類之間多態性的一種表現,重載

Overloading是一個類中多態性的一種表現

103、垃圾回收器的基本原理是什麼?垃圾回收器能夠立刻回收內存嗎?有什麼辦法主動通知虛擬機進行垃圾回收?

對於GC來講,當程序員建立對象時,GC就開始監控這個對象的地址、大小以及使用狀況。一般,GC採用有向圖的方式記錄和管理堆

(heap)中的全部對象。經過這種方式肯定哪些對象是"可達的",哪些對象是"不可達的"。當GC肯定一些對象爲"不可達"時,GC就有責

任回收這些內存空間。能夠。程序員能夠手動執行System.gc(),通知GC運行,可是Java語言規範並不保證GC必定會執行。

104、靜態變量和實例變量的區別?

static i = 10; //常量

class A a; a.i =10;//可變

105、什麼是java序列化,如何實現java序列化?

序列化就是一種用來處理對象流的機制,所謂對象流也就是將對象的內容進行流化。能夠對流化後的對象進行讀寫操做,也可將流化

後的對象傳輸於網絡之間。序列化是爲了解決在對對象流進行讀寫操做時所引起的問題。

序列化的實現:將須要被序列化的類實現Serializable接口,該接口沒有須要實現的方法,implements Serializable只是爲了標註

該對象是可被序列化的,而後使用一個輸出流(如:FileOutputStream)來構造一個 ObjectOutputStream(對象流)對象,接着,使用

ObjectOutputStream對象的writeObject(Object ob

j)方法就能夠將參數爲obj的對象寫出(即保存其狀態),要恢復的話則用輸入流。

106、是否能夠從一個static方法內部發出對非static方法的調用?

不能夠,若是其中包含對象的method();不能保證對象初始化.

相關文章
相關標籤/搜索