溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Java開發(fā)中的面試題有哪些

發(fā)布時(shí)間:2022-01-06 18:09:51 來源:億速云 閱讀:83 作者:iii 欄目:編程語言

本篇內(nèi)容主要講解“Java開發(fā)中的面試題有哪些”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實(shí)用性強(qiáng)。下面就讓小編來帶大家學(xué)習(xí)“Java開發(fā)中的面試題有哪些”吧!

一、super() 方法的用法及作用?

有如下Java類:

public class Bird{ private String name; public Bird() { } public Bird(String name){ this.name = name; } public void walk() { System.out.println(“走路”); } public String getName(){ return name; } public void setName(String name){ this.name = name; } }

另有一個(gè)類Chicken繼承上邊的Bird類;

public class Chicken extends Bird{ private String crest; public Chicken(){ super(); } public Chicken(String name,String crest) { super(name); this.name = name; } …………. }

在第二個(gè)自定義的類Chicken中,super()方法一共出現(xiàn)了兩次,分別是super()和super(name),請(qǐng)問super() 是什么含義,放在這里又作何解釋?

參考答案:

1.子類的構(gòu)造過程中必須調(diào)用父類的構(gòu)造方法。

2.子類可在自己的構(gòu)造方法中使用super()來調(diào)用父類的構(gòu)造方法。

(1)使用this來調(diào)用本類的另外的構(gòu)造方法。

(2)如果調(diào)用super必須寫在子類構(gòu)造方法的***行。

3.如果子類的構(gòu)造方法中沒有顯示的調(diào)用父類的構(gòu)造方法,則系統(tǒng)默認(rèn)的調(diào)用父類的無參的構(gòu)造方法。

4.如果子類的構(gòu)造方法中既沒有顯示調(diào)用父類的構(gòu)造方法,而父類中又沒有無參的構(gòu)造方法,則編譯出錯(cuò)。

那你這里***個(gè)super()無參的就是調(diào)用了上面Bird類的Bird() 方法!

super(name)這個(gè)有參數(shù)就是調(diào)用public Bird(String name){

this.name = name; 這個(gè)方法!super() 是調(diào)用父類的構(gòu)造函數(shù),你例子中有Bird()和Bird(String name)兩個(gè)方法,super()是調(diào)用Bird()構(gòu)造函數(shù),而super(name)是調(diào)用Birth(String name)構(gòu)造函數(shù)。注意super() 調(diào)用的是對(duì)應(yīng)參數(shù)個(gè)數(shù)和類型相同的父類構(gòu)造函數(shù)。 public Chicken(String name,String crest) { super(name); this.name = name; } 應(yīng)該重復(fù)了吧,super(name)應(yīng)該就是this.name = name。

二、Java 語言中的 volatile 和synchronized有什么區(qū)別?

Java 語言中的 volatile 變量可以被看作是一種 “程度較輕的 synchronized”;與 synchronized 塊相比,volatile 變量所需的編碼較少,并且運(yùn)行時(shí)開銷也較少,但是它所能實(shí)現(xiàn)的功能也僅是 synchronized 的一部分。

我們知道,在Java中設(shè)置變量值的操作,除了long和double類型的變量外都是原子操作,也就是說,對(duì)于變量值的簡單讀寫操作沒有必要進(jìn)行同步。

這在JVM 1.2之前,Java的內(nèi)存模型實(shí)現(xiàn)總是從主存讀取變量,是不需要進(jìn)行特別的注意的。而隨著JVM的成熟和優(yōu)化,現(xiàn)在在多線程環(huán)境下volatile關(guān)鍵字的使用變得非常重要。

在當(dāng)前的Java內(nèi)存模型下,線程可以把變量保存在本地內(nèi)存(比如機(jī)器的寄存器)中,而不是直接在主存中進(jìn)行讀寫。這就可能造成一個(gè)線程在主存中修改了一個(gè)變量的值,而另外一個(gè)線程還繼續(xù)使用它在寄存器中的變量值的拷貝,造成數(shù)據(jù)的不一致。

要解決這個(gè)問題,只需要像在本程序中的這樣,把該變量聲明為volatile(不穩(wěn)定的)即可,這就指示JVM,這個(gè)變量是不穩(wěn)定的,每次使用它都到主存中進(jìn)行讀取。一般說來,多任務(wù)環(huán)境下各任務(wù)間共享的標(biāo)志都應(yīng)該加volatile修飾。

Volatile修飾的成員變量在每次被線程訪問時(shí),都強(qiáng)迫從共享內(nèi)存中重讀該成員變量的值。而且,當(dāng)成員變量發(fā)生變化時(shí),強(qiáng)迫線程將變化值回寫到共享內(nèi)存。這樣在任何時(shí)刻,兩個(gè)不同的線程總是看到某個(gè)成員變量的同一個(gè)值。

Java語言規(guī)范中指出:為了獲得***速度,允許線程保存共享成員變量的私有拷貝,而且只當(dāng)線程進(jìn)入或者離開同步代碼塊時(shí)才與共享成員變量的原始值對(duì)比。

這樣當(dāng)多個(gè)線程同時(shí)與某個(gè)對(duì)象交互時(shí),就必須要注意到要讓線程及時(shí)的得到共享成員變量的變化。

而volatile關(guān)鍵字就是提示VM:對(duì)于這個(gè)成員變量不能保存它的私有拷貝,而應(yīng)直接與共享成員變量交互。

使用建議:在兩個(gè)或者更多的線程訪問的成員變量上使用volatile。當(dāng)要訪問的變量已在synchronized代碼塊中,或者為常量時(shí),不必使用。

由于使用屏蔽掉了VM中必要的代碼優(yōu)化,所以在效率上比較低,因此一定在必要時(shí)才使用此關(guān)鍵字。

注意:聲明為volatile的簡單變量如果當(dāng)前值由該變量以前的值相關(guān),那么volatile關(guān)鍵字不起作用,也就是說如下的表達(dá)式都不是原子操作:

n = n + 1; n++;

如果要想使這種情況變成原子操作,需要使用synchronized關(guān)鍵字,如上的代碼可以改成如下的形式:

public static synchronized void inc() { n++; }

將n=n+1改成了inc(),其中inc方法使用了synchronized關(guān)鍵字進(jìn)行方法同步。因此,在使用volatile關(guān)鍵字時(shí)要慎重,并不是只要簡單類型變量使用volatile修飾,對(duì)這個(gè)變量的所有操作都是原來操作,當(dāng)變量的值由自身的上一個(gè)決定時(shí),如n=n+1、n++等,volatile關(guān)鍵字將失效,只有當(dāng)變量的值和自身上一個(gè)值無關(guān)時(shí)對(duì)該變量的操作才是原子級(jí)別的,如n = m + 1,這個(gè)就是原級(jí)別的。所以在使用volatile關(guān)鍵時(shí)一定要謹(jǐn)慎,如果自己沒有把握,可以使用synchronized來代替volatile。

三、什么是互斥鎖?使用互斥鎖都有哪些注意事項(xiàng)?

1.男孩和女孩例子,每個(gè)女孩是一個(gè)對(duì)象,每個(gè)男孩是個(gè)線程。每個(gè)女孩都有自己的鎖池。每個(gè)男孩可能在鎖池里等待。

Class Girl{ Public void hand(){ } Public syncronized void kiss(){ } } Class Boy extends Thread{ Public void run(){ } }

鎖標(biāo)記如果過多,就會(huì)出現(xiàn)線程等待其他線程釋放鎖標(biāo)記,而又都不釋放自己的鎖標(biāo)記供其他線程運(yùn)行的狀況。就是死鎖。

死鎖的兩種處理方法:統(tǒng)一排列鎖順序(解決不同方法中對(duì)多個(gè)共享資源的訪問)。

對(duì)象1的方法

synchronized(a)
synchronized(b)

對(duì)象2的方法

synchronized(a) synchronized(b)

2.線程間通信(也就是線程間的相互協(xié)調(diào))

線程間通信使用的空間稱之為對(duì)象的等待池(wait pool),該隊(duì)列也是屬于對(duì)象的空間的。

進(jìn)入等待池

使用Object類中wait()的方法,在運(yùn)行狀態(tài)中,線程調(diào)用wait(),此時(shí)表示線程將釋放自己所有的鎖標(biāo)記和CPU的占用,同時(shí)進(jìn)入這個(gè)對(duì)象的等待池。等待池的狀態(tài)也是阻塞狀態(tài),只不過線程釋放自己的鎖標(biāo)記。

退出等待池進(jìn)入鎖池

notify():將從對(duì)象的等待池中移走一個(gè)任意的線程,并放到鎖池中,那里的對(duì)象一直在等待,直到可以獲得對(duì)象的鎖標(biāo)記。

notifyAll():將從等待池中移走所有等待那個(gè)對(duì)象的線程并放到鎖池中,只有鎖池中的線程能獲取對(duì)象的鎖標(biāo)記,鎖標(biāo)記允許線程從上次因調(diào)用wait()而中斷的地方開始繼續(xù)運(yùn)行。

注意:只能對(duì)加鎖的資源進(jìn)行wait()和notify()。

1) wait():交出鎖和CPU的占用;

2) notify():將從對(duì)象的等待池中移走一個(gè)任意的線程,并放到鎖池中,那里的對(duì)象一直在等待,直到可以獲得對(duì)象的鎖標(biāo)記。

3) notifyAll(): 將從等待池中移走所有等待那個(gè)對(duì)象的線程并放到鎖池中,只有鎖池中的線程能獲取對(duì)象的鎖標(biāo)記,鎖標(biāo)記允許線程從上次因調(diào)用wait()而中斷的地方開始繼續(xù)運(yùn)行。

注:在java.io包中Vector 和 HashTable 之所以是線程安全的,是因?yàn)槊總€(gè)方法都有synchronized修飾。Static 方法可以加 synchronized , 鎖的是類對(duì)象。

但是Vector 是 jdk 1.0 的 ArrayList 是 jdk1.2 所以實(shí)際應(yīng)用還是使用ArrayList

例子:

生產(chǎn)者和消費(fèi)者

一個(gè)柜臺(tái)一定數(shù)量的產(chǎn)品,柜臺(tái)滿時(shí)不能生產(chǎn),空時(shí)不能夠買。

四、Java中流的分類都有哪些?

1)從數(shù)據(jù)類型分為字節(jié)流和字符流

字節(jié)流類:

抽象父類: InputStream,OutputStream

實(shí)現(xiàn)類包括如下幾種:

BufferedInputStream 緩沖流-過慮流
BufferedOutputStream
ByteArrayInputStream 字節(jié)數(shù)組流-節(jié)點(diǎn)流
ByteArrayOutputStream
DataInputStream 處理JAVA標(biāo)準(zhǔn)數(shù)據(jù)流-過慮流
DataOutputStream
FileInputStream 處理文件IO流-節(jié)點(diǎn)流
FileOutputStream
FilterInputStream 實(shí)現(xiàn)過慮流-字節(jié)過慮流父類
FilterOutputStream
PipedInputStream 管道流
PipedOutputStream
PrintStream 包含print() 和 println()
RandomAccessFile 支持隨機(jī)文件

抽象父類:Reader, Writer

實(shí)現(xiàn)類:

BufferedReader
BufferedWriter
PrintWriter
CharArrayReader
CharArrayWriter
FileReader
FileWriter
FilterReader
FilterWriter
InputStreamReader
OutputStreamWriter
PipedReader
PipedWriter
StringReader
StringWriter

2) 從數(shù)據(jù)方向分為輸入流和輸出流

InputXXXXX , OutputXXXXX

3) 從流的功能分為節(jié)點(diǎn)流和過濾流

節(jié)點(diǎn)流用來傳輸數(shù)據(jù)。

過濾流用來封裝節(jié)點(diǎn)流或者其他過濾流,從而給節(jié)點(diǎn)流或其他的過濾流增加一個(gè)功能。

五、Java中父類和子類關(guān)系

父類的非私有化屬性(不同包的子類無法訪問default修飾符)和方法可以默認(rèn)繼承到子類。

Class Son extends Father{ }

而如果父類中的私有方法被子類調(diào)用的話,則編譯報(bào)錯(cuò)。

父類的構(gòu)造方法子類不可以繼承,更不存在覆蓋的問題。

所以子類構(gòu)造方法默認(rèn)調(diào)用父類的無參構(gòu)造方法。(所以養(yǎng)成寫無參構(gòu)造的習(xí)慣)

如果子類訪問父類的有參構(gòu)造方法,必須在子類構(gòu)造方法***行使用super(參數(shù))

當(dāng)構(gòu)造一個(gè)對(duì)象的時(shí)候,系統(tǒng)先構(gòu)造父類對(duì)象,再構(gòu)造子類對(duì)象。

Public class BMWcar extends Car{ Public BMWcar(){ Super(int alength); //顯式的調(diào)用父類的構(gòu)造,默認(rèn)調(diào)用無參構(gòu)造 //所以父類沒有無參構(gòu)造的話,子類如果不加顯示調(diào)用其他構(gòu)造就會(huì)報(bào)錯(cuò)。這里的super是一個(gè)對(duì)父類的引用 } }

六、Java多線程常見面試題

1、定義線程

1)擴(kuò)展java.lang.Thread類。

此類中有個(gè)run()方法,應(yīng)該注意其用法:

public void run()如果該線程是使用獨(dú)立的 Runnable 運(yùn)行對(duì)象構(gòu)造的,則調(diào)用該 Runnable 對(duì)象的 run 方法;否則,該方法不執(zhí)行任何操作并返回。

Thread 的子類應(yīng)該重寫該方法。

2)實(shí)現(xiàn)java.lang.Runnable接口。

void run()

使用實(shí)現(xiàn)接口 Runnable 的對(duì)象創(chuàng)建一個(gè)線程時(shí),啟動(dòng)該線程將導(dǎo)致在獨(dú)立執(zhí)行的線程中調(diào)用對(duì)象的 run 方法。

方法 run 的常規(guī)協(xié)定是,它可能執(zhí)行任何所需的操作。

2、實(shí)例化線程

1)如果是擴(kuò)展java.lang.Thread類的線程,則直接new即可。

2)如果是實(shí)現(xiàn)了java.lang.Runnable接口的類,則用Thread的構(gòu)造方法:

Thread(Runnable target)
Thread(Runnable target, String name)
Thread(ThreadGroup group, Runnable target)
Thread(ThreadGroup group, Runnable target, String name)
Thread(ThreadGroup group, Runnable target, String name, long stackSize)

3、啟動(dòng)線程

在線程的Thread對(duì)象上調(diào)用start()方法,而不是run()或者別的方法。

在調(diào)用start()方法之前:線程處于新狀態(tài)中,新狀態(tài)指有一個(gè)Thread對(duì)象,但還沒有一個(gè)真正的線程。

在調(diào)用start()方法之后:發(fā)生了一系列復(fù)雜的事情

啟動(dòng)新的執(zhí)行線程(具有新的調(diào)用棧);

該線程從新狀態(tài)轉(zhuǎn)移到可運(yùn)行狀態(tài);

當(dāng)該線程獲得機(jī)會(huì)執(zhí)行時(shí),其目標(biāo)run()方法將運(yùn)行。

注意:對(duì)Java來說,run()方法沒有任何特別之處。像main()方法一樣,它只是新線程知道調(diào)用的方法名稱(和簽名)。因此,在Runnable上或者Thread上調(diào)用run方法是合法的。但并不啟動(dòng)新的線程。

4、例子

1)實(shí)現(xiàn)Runnable接口的多線程例子。

/** * 實(shí)現(xiàn)Runnable接口的類 * * @author leizhimin 2008-9-13 18:12:10 */ public class DoSomething implements Runnable { private String name;  public DoSomething(String name) { this.name = name; }  public void run() { for (int i = 0; i < 5; i++) { for (long k = 0; k < 100000000; k++) ; System.out.println(name + “: ” + i); } } }  /** * 測(cè)試Runnable類實(shí)現(xiàn)的多線程程序 * * @author leizhimin 2008-9-13 18:15:02 */ public class TestRunnable { public static void main(String[] args) { DoSomething ds1 = new DoSomething(“阿三”); DoSomething ds2 = new DoSomething(“李四”);  Thread t1 = new Thread(ds1); Thread t2 = new Thread(ds2);  t1.start(); t2.start(); } }

執(zhí)行結(jié)果:

李四: 0
阿三: 0
李四: 1
阿三: 1
李四: 2
李四: 3
阿三: 2
李四: 4
阿三: 3
阿三: 4
Process finished with exit code 0

2)擴(kuò)展Thread類實(shí)現(xiàn)的多線程例子。

/** * 測(cè)試擴(kuò)展Thread類實(shí)現(xiàn)的多線程程序 * * @author leizhimin 2008-9-13 18:22:13 */ public class TestThread extends Thread{ public TestThread(String name) { super(name); }  public void run() { for(int i = 0;i<5;i++){ for(long k= 0; k <100000000;k++); System.out.println(this.getName()+” :”+i); } }  public static void main(String[] args) { Thread t1 = new TestThread(“阿三”); Thread t2 = new TestThread(“李四”); t1.start(); t2.start(); } }

執(zhí)行結(jié)果:

阿三 :0
李四 :0
阿三 :1
李四 :1
阿三 :2
李四 :2
阿三 :3
阿三 :4
李四 :3
李四 :4
Process finished with exit code 0

對(duì)于上面的多線程程序代碼來說,輸出的結(jié)果是不確定的。其中的一條語句for(long k= 0; k <100000000;k++);是用來模擬一個(gè)非常耗時(shí)的操作的。

5、一些常見問題

1)線程的名字,一個(gè)運(yùn)行中的線程總是有名字的,名字有兩個(gè)來源,一個(gè)是虛擬機(jī)自己給的名字,一個(gè)是你自己的定的名字。在沒有指定線程名字的情況下,虛擬機(jī)總會(huì)為線程指定名字,并且主線程的名字總是mian,非主線程的名字不確定。

2)線程都可以設(shè)置名字,也可以獲取線程的名字,連主線程也不例外。

3)獲取當(dāng)前線程的對(duì)象的方法是:Thread.currentThread();

4)在上面的代碼中,只能保證:每個(gè)線程都將啟動(dòng),每個(gè)線程都將運(yùn)行直到完成。一系列線程以某種順序啟動(dòng)并不意味著將按該順序執(zhí)行。對(duì)于任何一組啟動(dòng)的線程來說,調(diào)度程序不能保證其執(zhí)行次序,持續(xù)時(shí)間也無法保證。

5)當(dāng)線程目標(biāo)run()方法結(jié)束時(shí)該線程完成。

6)一旦線程啟動(dòng),它就永遠(yuǎn)不能再重新啟動(dòng)。只有一個(gè)新的線程可以被啟動(dòng),并且只能一次。一個(gè)可運(yùn)行的線程或死線程可以被重新啟動(dòng)。

7)線程的調(diào)度是JVM的一部分,在一個(gè)CPU的機(jī)器上上,實(shí)際上一次只能運(yùn)行一個(gè)線程。一次只有一個(gè)線程棧執(zhí)行。JVM線程調(diào)度程序決定實(shí)際運(yùn)行哪個(gè)處于可運(yùn)行狀態(tài)的線程。眾多可運(yùn)行線程中的某一個(gè)會(huì)被選中做為當(dāng)前線程??蛇\(yùn)行線程被選擇運(yùn)行的順序是沒有保障的。

8)盡管通常采用隊(duì)列形式,但這是沒有保障的。隊(duì)列形式是指當(dāng)一個(gè)線程完成“一輪”時(shí),它移到可運(yùn)行隊(duì)列的尾部等待,直到它最終排隊(duì)到該隊(duì)列的前端為止,它才能被再次選中。事實(shí)上,我們把它稱為可運(yùn)行池而不是一個(gè)可運(yùn)行隊(duì)列,目的是幫助認(rèn)識(shí)線程并不都是以某種有保障的順序排列唱呢個(gè)一個(gè)隊(duì)列的事實(shí)。

9)盡管我們沒有無法控制線程調(diào)度程序,但可以通過別的方式來影響線程調(diào)度的方式。

七、java經(jīng)典面試題

總結(jié)了一下java的一些企業(yè)常面試的面試題,也可以說是堪稱經(jīng)典吧!大部分企業(yè)的面試題,差不多都會(huì)以下我列出的面試題!而且面試題為紅色的題更是企業(yè)經(jīng)常面試的,可以說是屢試不爽,大家如果看到了我的這篇文章,那么請(qǐng)你進(jìn)來看看,會(huì)對(duì)你有不小的收獲的。

Java基礎(chǔ)方面:

1、Static Nested Class 和 Inner Class的不同。

Static Nested Class是被聲明為靜態(tài)(static)的內(nèi)部類,它可以不依賴于外部類實(shí)例被實(shí)例化。而通常的內(nèi)部類需要在外部類實(shí)例化后才能實(shí)例化。

2、java.lang.String類是否能被繼承和修改,為什么?

java.lang.String類是final類型的,因此不可以繼承這個(gè)類、不能修改這個(gè)類。為了提高效率節(jié)省空間,我們應(yīng)該用StringBuffer類

3、int 和 Integer 有什么區(qū)別?

Java 提供兩種不同的類型:引用類型和原始類型(或內(nèi)置類型)。Int是java的原始數(shù)據(jù)類型,Integer是java為int提供的封裝類。Java為每個(gè)原始類型提供了封裝類。

原始類型封裝類

booleanBoolean
charCharacter
byteByte
shortShort
intInteger
longLong
floatFloat
doubleDouble

引 用類型和原始類型的行為完全不同,并且它們具有不同的語義。引用類型和原始類型具有不同的特征和用法,它們包括:大小和速度問題,這種類型以哪種類型的數(shù) 據(jù)結(jié)構(gòu)存儲(chǔ),當(dāng)引用類型和原始類型用作某個(gè)類的實(shí)例數(shù)據(jù)時(shí)所指定的缺省值。對(duì)象引用實(shí)例變量的缺省值為 null,而原始類型實(shí)例變量的缺省值與它們的類型有關(guān)。

4、String 和StringBuffer的區(qū)別。

JAVA 平臺(tái)提供了兩個(gè)類:String和StringBuffer,它們可以儲(chǔ)存和操作字符串,即包含多個(gè)字符的字符數(shù)據(jù)。這個(gè)String類提供了數(shù)值不可改 變的字符串。而這個(gè)StringBuffer類提供的字符串進(jìn)行修改。當(dāng)你知道字符數(shù)據(jù)要改變的時(shí)候你就可以使用StringBuffer。典型地,你可 以使用StringBuffers來動(dòng)態(tài)構(gòu)造字符數(shù)據(jù)。

5、運(yùn)行時(shí)異常與一般異常有何異同?

異常表示程序運(yùn)行過程中可能出現(xiàn)的非正常狀態(tài),運(yùn)行時(shí)異常表示虛擬機(jī)的通常操作中可能遇到的異常,是一種常見運(yùn)行錯(cuò)誤。java編譯器要求方法必須聲明拋出可能發(fā)生的非運(yùn)行時(shí)異常,但是并不要求必須聲明拋出未被捕獲的運(yùn)行時(shí)異常。

6、說出Servlet的生命周期,并說出Servlet和CGI的區(qū)別。

Servlet被服務(wù)器實(shí)例化后,容器運(yùn)行其init方法,請(qǐng)求到達(dá)時(shí)運(yùn)行其service方法,service方法自動(dòng)派遣運(yùn)行與請(qǐng)求對(duì)應(yīng)的doXXX方法(doGet,doPost)等,當(dāng)服務(wù)器決定將實(shí)例銷毀的時(shí)候調(diào)用其destroy方法。

與cgi的區(qū)別在于servlet處于服務(wù)器進(jìn)程中,它通過多線程方式運(yùn)行其service方法,一個(gè)實(shí)例可以服務(wù)于多個(gè)請(qǐng)求,并且其實(shí)例一般不會(huì)銷毀,而CGI對(duì)每個(gè)請(qǐng)求都產(chǎn)生新的進(jìn)程,服務(wù)完成后就銷毀,所以效率上低于servlet。

7、說出ArrayList,Vector, LinkedList的存儲(chǔ)性能和特性。

ArrayList 和Vector都是使用數(shù)組方式存儲(chǔ)數(shù)據(jù),此數(shù)組元素?cái)?shù)大于實(shí)際存儲(chǔ)的數(shù)據(jù)以便增加和插入元素,它們都允許直接按序號(hào)索引元素,但是插入元素要涉及數(shù)組元 素移動(dòng)等內(nèi)存操作,所以索引數(shù)據(jù)快而插入數(shù)據(jù)慢,Vector由于使用了synchronized方法(線程安全),通常性能上較ArrayList差, 而LinkedList使用雙向鏈表實(shí)現(xiàn)存儲(chǔ),按序號(hào)索引數(shù)據(jù)需要進(jìn)行前向或后向遍歷,但是插入數(shù)據(jù)時(shí)只需要記錄本項(xiàng)的前后項(xiàng)即可,所以插入速度較快。

8、EJB是基于哪些技術(shù)實(shí)現(xiàn)的?并說出SessionBean和EntityBean的區(qū)別,StatefulBean和StatelessBean的區(qū)別。

EJB包括Session Bean、Entity Bean、Message Driven Bean,基于JNDI、RMI、JAT等技術(shù)實(shí)現(xiàn)。

SessionBean在J2EE應(yīng)用程序中被用來完成一些服務(wù)器端的業(yè)務(wù)操作,例如訪問數(shù)據(jù)庫、調(diào)用其他EJB組件。EntityBean被用來代表應(yīng)用系統(tǒng)中用到的數(shù)據(jù)。

對(duì)于客戶機(jī),SessionBean是一種非持久性對(duì)象,它實(shí)現(xiàn)某些在服務(wù)器上運(yùn)行的業(yè)務(wù)邏輯。

對(duì)于客戶機(jī),EntityBean是一種持久性對(duì)象,它代表一個(gè)存儲(chǔ)在持久性存儲(chǔ)器中的實(shí)體的對(duì)象視圖,或是一個(gè)由現(xiàn)有企業(yè)應(yīng)用程序?qū)崿F(xiàn)的實(shí)體。

Session Bean 還可以再細(xì)分為 Stateful Session Bean 與 Stateless Session Bean ,這兩種的 Session Bean都可以將系統(tǒng)邏輯放在 method之中執(zhí)行,不同的是 Stateful Session Bean 可以記錄呼叫者的狀態(tài),因此通常來說,一個(gè)使用者會(huì)有一個(gè)相對(duì)應(yīng)的 Stateful Session Bean 的實(shí)體。Stateless Session Bean 雖然也是邏輯組件,但是他卻不負(fù)責(zé)記錄使用者狀態(tài),也就是說當(dāng)使用者呼叫 Stateless Session Bean 的時(shí)候,EJB Container 并不會(huì)找尋特定的 Stateless Session Bean 的實(shí)體來執(zhí)行這個(gè) method。換言之,很可能數(shù)個(gè)使用者在執(zhí)行某個(gè) Stateless Session Bean 的 methods 時(shí),會(huì)是同一個(gè) Bean 的 Instance 在執(zhí)行。從內(nèi)存方面來看, Stateful Session Bean 與 Stateless Session Bean 比較, Stateful Session Bean 會(huì)消耗 J2EE Server 較多的內(nèi)存,然而 Stateful Session Bean 的優(yōu)勢(shì)卻在于他可以維持使用者的狀態(tài)。

9、Collection 和 Collections的區(qū)別。

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

Collections是針對(duì)集合類的一個(gè)幫助類,他提供一系列靜態(tài)方法實(shí)現(xiàn)對(duì)各種集合的搜索、排序、線程安全化等操作。

10、&和&&的區(qū)別。

&是位運(yùn)算符,表示按位與運(yùn)算,&&是邏輯運(yùn)算符,表示邏輯與(and)。

11、HashMap和Hashtable的區(qū)別。

HashMap是Hashtable的輕量級(jí)實(shí)現(xiàn)(非線程安全的實(shí)現(xiàn)),他們都完成了Map接口,主要區(qū)別在于HashMap允許空(null)鍵值(key),由于非線程安全,效率上可能高于Hashtable。

HashMap允許將null作為一個(gè)entry的key或者value,而Hashtable不允許。

HashMap把Hashtable的contains方法去掉了,改成containsvalue和containsKey。因?yàn)閏ontains方法容易讓人引起誤解。

Hashtable繼承自Dictionary類,而HashMap是Java1.2引進(jìn)的Map interface的一個(gè)實(shí)現(xiàn)。

***的不同是,Hashtable的方法是Synchronize的,而HashMap不是,在多個(gè)線程訪問Hashtable時(shí),不需要自己為它的方法實(shí)現(xiàn)同步,而HashMap 就必須為之提供外同步。

Hashtable和HashMap采用的hash/rehash算法都大概一樣,所以性能不會(huì)有很大的差異。

12、final, finally, finalize的區(qū)別。

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

finally是異常處理語句結(jié)構(gòu)的一部分,表示總是執(zhí)行。

finalize是Object類的一個(gè)方法,在垃圾收集器執(zhí)行的時(shí)候會(huì)調(diào)用被回收對(duì)象的此方法,可以覆蓋此方法提供垃圾收集時(shí)的其他資源回收,例如關(guān)閉文件等。

13、sleep() 和 wait() 有什么區(qū)別?

sleep是線程類(Thread)的方法,導(dǎo)致此線程暫停執(zhí)行指定時(shí)間,給執(zhí)行機(jī)會(huì)給其他線程,但是監(jiān)控狀態(tài)依然保持,到時(shí)后會(huì)自動(dòng)恢復(fù)。調(diào)用sleep不會(huì)釋放對(duì)象鎖。

wait是Object類的方法,對(duì)此對(duì)象調(diào)用wait方法導(dǎo)致本線程放棄對(duì)象鎖,進(jìn)入等待此對(duì)象的等待鎖定池,只有針對(duì)此對(duì)象發(fā)出notify方法(或notifyAll)后本線程才進(jìn)入對(duì)象鎖定池準(zhǔn)備獲得對(duì)象鎖進(jìn)入運(yùn)行狀態(tài)。

14、Overload和Override的區(qū)別。Overloaded的方法是否可以改變返回值的類型?

方 法的重寫Overriding和重載Overloading是Java多態(tài)性的不同表現(xiàn)。重寫Overriding是父類與子類之間多態(tài)性的一種表現(xiàn),重 載Overloading是一個(gè)類中多態(tài)性的一種表現(xiàn)。如果在子類中定義某方法與其父類有相同的名稱和參數(shù),我們說該方法被重寫 (Overriding)。子類的對(duì)象使用這個(gè)方法時(shí),將調(diào)用子類中的定義,對(duì)它而言,父類中的定義如同被”屏蔽”了。如果在一個(gè)類中定義了多個(gè)同名的方 法,它們或有不同的參數(shù)個(gè)數(shù)或有不同的參數(shù)類型,則稱為方法的重載(Overloading)。Overloaded的方法是可以改變返回值的類型。

15、error和exception有什么區(qū)別?

error 表示恢復(fù)不是不可能但很困難的情況下的一種嚴(yán)重問題。比如說內(nèi)存溢出。不可能指望程序能處理這樣的情況。

exception 表示一種設(shè)計(jì)或?qū)崿F(xiàn)問題。也就是說,它表示如果程序運(yùn)行正常,從不會(huì)發(fā)生的情況。

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

如果數(shù)據(jù)將在線程間共享。例如正在寫的數(shù)據(jù)以后可能被另一個(gè)線程讀到,或者正在讀的數(shù)據(jù)可能已經(jīng)被另一個(gè)線程寫過了,那么這些數(shù)據(jù)就是共享數(shù)據(jù),必須進(jìn)行同步存取。

當(dāng)應(yīng)用程序在對(duì)象上調(diào)用了一個(gè)需要花費(fèi)很長時(shí)間來執(zhí)行的方法,并且不希望讓程序等待方法的返回時(shí),就應(yīng)該使用異步編程,在很多情況下采用異步途徑往往更有效率。

17、abstract class和interface有什么區(qū)別?

聲 明方法的存在而不去實(shí)現(xiàn)它的類被叫做抽象類(abstract class),它用于要?jiǎng)?chuàng)建一個(gè)體現(xiàn)某些基本行為的類,并為該類聲明方法,但不能在該類中實(shí)現(xiàn)該類的情況。不能創(chuàng)建abstract 類的實(shí)例。然而可以創(chuàng)建一個(gè)變量,其類型是一個(gè)抽象類,并讓它指向具體子類的一個(gè)實(shí)例。不能有抽象構(gòu)造函數(shù)或抽象靜態(tài)方法。Abstract 類的子類為它們父類中的所有抽象方法提供實(shí)現(xiàn),否則它們也是抽象類為。取而代之,在子類中實(shí)現(xiàn)該方法。知道其行為的其它類可以在類中實(shí)現(xiàn)這些方法。

接 口(interface)是抽象類的變體。在接口中,所有方法都是抽象的。多繼承性可通過實(shí)現(xiàn)這樣的接口而獲得。接口中的所有方法都是抽象的,沒有一個(gè)有 程序體。接口只可以定義static final成員變量。接口的實(shí)現(xiàn)與子類相似,除了該實(shí)現(xiàn)類不能從接口定義中繼承行為。當(dāng)類實(shí)現(xiàn)特殊接口時(shí),它定義(即將程序體給予)所有這種接口的方法。 然后,它可以在實(shí)現(xiàn)了該接口的類的任何對(duì)象上調(diào)用接口的方法。由于有抽象類,它允許使用接口名作為引用變量的類型。通常的動(dòng)態(tài)聯(lián)編將生效。引用可以轉(zhuǎn)換到 接口類型或從接口類型轉(zhuǎn)換,instanceof 運(yùn)算符可以用來決定某對(duì)象的類是否實(shí)現(xiàn)了接口。

18、heap和stack有什么區(qū)別。

棧是一種線形集合,其添加和刪除元素的操作應(yīng)在同一段完成。棧按照后進(jìn)先出的方式進(jìn)行處理。

堆是棧的一個(gè)組成元素

19、forward 和redirect的區(qū)別

forward是服務(wù)器請(qǐng)求資源,服務(wù)器直接訪問目標(biāo)地址的URL,把那個(gè)URL的響應(yīng)內(nèi)容讀取過來,然后把這些內(nèi)容再發(fā)給瀏覽器,瀏覽器根本不知道服務(wù)器發(fā)送的內(nèi)容是從哪兒來的,所以它的地址欄中還是原來的地址。
redirect就是服務(wù)端根據(jù)邏輯,發(fā)送一個(gè)狀態(tài)碼,告訴瀏覽器重新去請(qǐng)求那個(gè)地址,一般來說瀏覽器會(huì)用剛才請(qǐng)求的所有參數(shù)重新請(qǐng)求,所以session,request參數(shù)都可以獲取。

20、EJB與JAVA BEAN的區(qū)別?
Java Bean 是可復(fù)用的組件,對(duì)Java Bean并沒有嚴(yán)格的規(guī)范,理論上講,任何一個(gè)Java類都可以是一個(gè)Bean。但通常情況下,由于Java Bean是被容器所創(chuàng)建(如Tomcat)的,所以Java Bean應(yīng)具有一個(gè)無參的構(gòu)造器,另外,通常Java Bean還要實(shí)現(xiàn)Serializable接口用于實(shí)現(xiàn)Bean的持久性。Java Bean實(shí)際上相當(dāng)于微軟COM模型中的本地進(jìn)程內(nèi)COM組件,它是不能被跨進(jìn)程訪問的。Enterprise Java Bean 相當(dāng)于DCOM,即分布式組件。它是基于Java的遠(yuǎn)程方法調(diào)用(RMI)技術(shù)的,所以EJB可以被遠(yuǎn)程訪問(跨進(jìn)程、跨計(jì)算機(jī))。但EJB必須被布署在 諸如Webspere、WebLogic這樣的容器中,EJB客戶從不直接訪問真正的EJB組件,而是通過其容器訪問。EJB容器是EJB組件的代理, EJB組件由容器所創(chuàng)建和管理??蛻敉ㄟ^容器來訪問真正的EJB組件。

八、戴爾公司電話面試Java

接到了dell公司項(xiàng)目經(jīng)理的電話面試,我們從java 的接口,abstract函數(shù),談的c++的虛函數(shù),然后談到j(luò)ava native interface。談到動(dòng)態(tài)庫,談到靜態(tài)庫,然后談到了進(jìn)程間通訊,操作系統(tǒng)是如何管理進(jìn)程的,已經(jīng)操作系統(tǒng)原理。談到了android的framework的部分原理,談到了aidl接口。

九、一朋友面試失敗后得到的一個(gè)回復(fù)信 你被涮后有過回復(fù)信嗎?

尊敬的應(yīng)聘者xxx,

非常感謝您到敝公司來面試。經(jīng)過我們對(duì)您的表現(xiàn)的認(rèn)真評(píng)估,認(rèn)為您目前還不適合敝公司的職位。如果您想在Java開發(fā)方面有好的發(fā)展,我們對(duì)您有以下建議:

1. 要注重基礎(chǔ)知識(shí)的學(xué)習(xí),不要只會(huì)SSH框架。

2. 多學(xué)習(xí)一些Linux方面的知識(shí)。

3. 推薦您看看Java核心技術(shù),Think in java這兩本書。

4. 建議您閑時(shí)上一些技術(shù)論壇看看,同大家多交流交流技術(shù)。

十、什么是觀察者模式(Observer)?

觀察者模式定義了一種一對(duì)多的依賴關(guān)系,讓多個(gè)觀察者對(duì)象同時(shí)監(jiān)聽某一個(gè)主題對(duì)象。這個(gè)主題對(duì)象在狀態(tài)上發(fā)生變化時(shí),會(huì)通知所有觀察者對(duì)象,讓他們能夠自動(dòng)更新自己

觀察者模式的組成

抽象主題角色:把所有對(duì)觀察者對(duì)象的引用保存在一個(gè)集合中,每個(gè)抽象主題角色都可以有任意數(shù)量的觀察者。抽象主題提供一個(gè)接口,可以增加和刪除觀察者角色。一般用一個(gè)抽象類或接口來實(shí)現(xiàn)。

抽象觀察者角色:為所有具體的觀察者定義一個(gè)接口,在得到主題的通知時(shí)更新自己。

從AWT1.1開始圖形系統(tǒng)的事件模型采用觀察者模式,因此觀察者模式在Java語言中的地位極其重要。

在xml解析中的SAX也采用了觀察者模式來實(shí)現(xiàn)。

Java也提供了對(duì)觀察者模式的內(nèi)置支持。

Observable類用于創(chuàng)建可以觀測(cè)到你的程序中其他部分的子類。當(dāng)這種子類的對(duì)象發(fā)生變化時(shí),觀測(cè)類被通知。觀測(cè)類必須實(shí)現(xiàn)定義了update( )方法的Observer接口。當(dāng)一個(gè)觀測(cè)程序被通知到一個(gè)被觀測(cè)對(duì)象的改變時(shí),update( )方法被調(diào)用。

一個(gè)被觀測(cè)的對(duì)象必須服從下面的兩個(gè)簡單規(guī)則。***,如果它被改變了,它必須調(diào)用setChanged( )方法。第二,當(dāng)它準(zhǔn)備通知觀測(cè)程序它的改變時(shí),它必須調(diào)用notifyObservers( )方法。這導(dǎo)致了在觀測(cè)對(duì)象中對(duì)update( )方法的調(diào)用。注意&mdash;&mdash;當(dāng)對(duì)象在調(diào)用notifyObservers( )方法之前,沒有調(diào)用setChanged( )方法,就不會(huì)有什么動(dòng)作發(fā)生。在update( )被調(diào)用之前,被觀測(cè)對(duì)象必須調(diào)用setChanged( )和notifyObservers( )兩種方法。

注意notifyObservers()有兩種形式:一種帶有參數(shù)而另一種沒有。當(dāng)用參數(shù)調(diào)用notifyObservers( )方法時(shí),該對(duì)象被傳給觀測(cè)程序的update( )方法作為其第二個(gè)參數(shù)。否則,將給update( )方法傳遞一個(gè)null??梢允褂玫诙€(gè)參數(shù)傳遞適合于你的應(yīng)用程序的任何類型的對(duì)象。

為了觀測(cè)一個(gè)可觀測(cè)的對(duì)象,必須實(shí)現(xiàn)Observer接口。這個(gè)接口僅僅定義了如下所示的一個(gè)方法。

void update(Observable observOb, Object arg)

這里,observOb是被觀測(cè)的對(duì)象,而arg是由notifyObservers( )方法傳遞的值。當(dāng)被觀測(cè)對(duì)象發(fā)生了改變,調(diào)用update( )方法。

十一、JavaEE N層架構(gòu)的好處都有哪些?

JavaEE帶來的好處是雙向的,對(duì)于開發(fā)應(yīng)用的公司和使用它的客戶,優(yōu)點(diǎn)主要在于4個(gè)方面。

1、簡化了體系和開發(fā)。相對(duì)于傳統(tǒng)的應(yīng)用開發(fā),JavaEE提供了簡單的、基于組件的開發(fā)模型。這個(gè)模型提供了WORA(Write Once, Run Anywhere)的可移植性,只要符合JavaEE規(guī)范的服務(wù)器,就可以運(yùn)行應(yīng)用。同時(shí),基于組件的開發(fā)模型也大大提高了生產(chǎn)力。

2、集成現(xiàn)有的企業(yè)信息系統(tǒng)。JavaEE平臺(tái),與JavaSE平臺(tái)一樣,提供訪問現(xiàn)有的企業(yè)信息系統(tǒng)的一些工業(yè)標(biāo)準(zhǔn)API;

3、提供可擴(kuò)展性。當(dāng)前JavaEE容器向組件提供事務(wù)支持、數(shù)據(jù)庫連接、生命周期管理和影響性能的其它特性,從而提供可擴(kuò)展性(scalability)。

4、安全機(jī)制。JavaEE支持豐富的跨越整個(gè)體系的一致的安全措施。

十二、四種操作xml的方式:SAX, DOM, JDOM , DOM4J的比較

1、DOM(JAXP Crimson解析器)

DOM是用與平臺(tái)和語言無關(guān)的方式表示XML文檔的官方W3C標(biāo)準(zhǔn)。DOM是以層次結(jié)構(gòu)組織的節(jié)點(diǎn)或信息片斷的集合。

這個(gè)層次結(jié)構(gòu)允許開發(fā)人員在樹中尋找特定信息。分析該結(jié)構(gòu)通常需要加載整個(gè)文檔和構(gòu)造層次結(jié)構(gòu),然后才能做任何工作。

由于它是基于信息層次的,因而DOM被認(rèn)為是基于樹或基于對(duì)象的。DOM以及廣義的基于樹的處理具有幾個(gè)優(yōu)點(diǎn)。

首先,由于樹在內(nèi)存中是持久的,因此可以修改它以便應(yīng)用程序能對(duì)數(shù)據(jù)和結(jié)構(gòu)作出更改。

它還可以在任何時(shí)候在樹中上下導(dǎo)航,而不是像SAX那樣是一次性的處理。DOM使用起來也要簡單得多。

2、SAX

SAX處理的優(yōu)點(diǎn)非常類似于流媒體的優(yōu)點(diǎn)。分析能夠立即開始,而不是等待所有的數(shù)據(jù)被處理。而且,由于應(yīng)用程序只是在讀取數(shù)據(jù)時(shí)檢查數(shù)據(jù),因此不需要將數(shù)據(jù)存儲(chǔ)在內(nèi)存中。這對(duì)于大型文檔來說是個(gè)巨大的優(yōu)點(diǎn)。事實(shí)上,應(yīng)用程序甚至不必解析整個(gè)文檔;它可以在某個(gè)條件得到滿足時(shí)停止解析。一般來說,SAX還比它的替代者DOM快許多。 選擇DOM還是選擇SAX? 對(duì)于需要自己編寫代碼來處理XML文檔的開發(fā)人員來說,選擇DOM還是SAX解析模型是一個(gè)非常重要的設(shè)計(jì)決策。 DOM采用建立樹形結(jié)構(gòu)的方式訪問XML文檔,而SAX采用的事件模型。

DOM解析器把XML文檔轉(zhuǎn)化為一個(gè)包含其內(nèi)容的樹,并可以對(duì)樹進(jìn)行遍歷。用DOM解析模型的優(yōu)點(diǎn)是編程容易,開發(fā)人員只需要調(diào)用建樹的指令,然后利用navigation APIs訪問所需的樹節(jié)點(diǎn)來完成任務(wù)??梢院苋菀椎奶砑雍托薷臉渲械脑亍H欢捎谑褂肈OM解析器的時(shí)候需要處理整個(gè)XML文檔,所以對(duì)性能和內(nèi)存的要求比較高,尤其是遇到很大的XML文件的時(shí)候。由于它的遍歷能力,DOM解析器常用于XML文檔需要頻繁的改變的服務(wù)中。

SAX解析器采用了基于事件的模型,它在解析XML文檔的時(shí)候可以觸發(fā)一系列的事件,當(dāng)發(fā)現(xiàn)給定的tag的時(shí)候,它可以激活一個(gè)回調(diào)方法,
告訴該方法制定的標(biāo)簽已經(jīng)找到。SAX對(duì)內(nèi)存的要求通常會(huì)比較低,因?yàn)樗岄_發(fā)人員自己來決定所要處理的tag。
特別是當(dāng)開發(fā)人員只需要處理文檔中所包含的部分?jǐn)?shù)據(jù)時(shí),SAX這種擴(kuò)展能力得到了更好的體現(xiàn)。但用SAX解析器的時(shí)候編碼工作會(huì)比較困難,
而且很難同時(shí)訪問同一個(gè)文檔中的多處不同數(shù)據(jù)。

3、JDOM

JDOM的目的是成為Java特定文檔模型,它簡化與XML的交互并且比使用DOM實(shí)現(xiàn)更快。由于是***個(gè)Java特定模型,JDOM一直得到大力推廣和促進(jìn)。

正在考慮通過“Java規(guī)范請(qǐng)求JSR-102”將它最終用作“Java標(biāo)準(zhǔn)擴(kuò)展”。從2000年初就已經(jīng)開始了JDOM開發(fā)。

JDOM與DOM主要有兩方面不同。首先,JDOM僅使用具體類而不使用接口。這在某些方面簡化了API,但是也限制了靈活性。

第二,API大量使用了Collections類,簡化了那些已經(jīng)熟悉這些類的Java開發(fā)者的使用。

JDOM文檔聲明其目的是“使用20%(或更少)的精力解決80%(或更多)Java/XML問題”(根據(jù)學(xué)習(xí)曲線假定為20%)。JDOM對(duì)于大多數(shù)Java/XML應(yīng)用程序來說當(dāng)然是有用的,并且大多數(shù)開發(fā)者發(fā)現(xiàn)API比DOM容易理解得多。JDOM還包括對(duì)程序行為的相當(dāng)廣泛檢查以防止用戶做任何在XML中無意義的事。

然而,它仍需要您充分理解XML以便做一些超出基本的工作(或者甚至理解某些情況下的錯(cuò)誤)。這也許是比學(xué)習(xí)DOM或JDOM接口都更有意義的工作。

JDOM自身不包含解析器。它通常使用SAX2解析器來解析和驗(yàn)證輸入XML文檔(盡管它還可以將以前構(gòu)造的DOM表示作為輸入)。

它包含一些轉(zhuǎn)換器以將JDOM表示輸出成SAX2事件流、DOM模型或XML文本文檔。JDOM是在Apache許可證變體下發(fā)布的開放源碼。

4、DOM4J

雖然DOM4J代表了完全獨(dú)立的開發(fā)結(jié)果,但最初,它是JDOM的一種智能分支。它合并了許多超出基本XML文檔表示的功能,包括集成的XPath支持、XML Schema支持以及用于大文檔或流化文檔的基于事件的處理。它還提供了構(gòu)建文檔表示的選項(xiàng),它通過DOM4J API和標(biāo)準(zhǔn)DOM接口具有并行訪問功能。從2000下半年開始,它就一直處于開發(fā)之中。

為支持所有這些功能,DOM4J使用接口和抽象基本類方法。DOM4J大量使用了API中的Collections類,但是在許多情況下,它還提供一些替代方法以允許更好的性能或更直接的編碼方法。直接好處是,雖然DOM4J付出了更復(fù)雜的API的代價(jià),但是它提供了比JDOM大得多的靈活性。在添加靈活性、XPath集成和對(duì)大文檔處理的目標(biāo)時(shí),DOM4J的目標(biāo)與JDOM是一樣的:針對(duì)Java開發(fā)者的易用性和直觀操作。它還致力于成為比JDOM更完整的解決方案,實(shí)現(xiàn)在本質(zhì)上處理所有Java/XML問題的目標(biāo)。在完成該目標(biāo)時(shí),它比JDOM更少強(qiáng)調(diào)防止不正確的應(yīng)用程序行為。

DOM4J是一個(gè)非常非常優(yōu)秀的Java XML API,具有性能優(yōu)異、功能強(qiáng)大和極端易用使用的特點(diǎn),同時(shí)它也是一個(gè)開放源代碼的軟件。如今你可以看到越來越多的Java軟件都在使用DOM4J來讀寫XML,特別值得一提的是連Sun的JAXM也在用DOM4J。

比較

1、DOM4J性能***,連Sun的JAXM也在用DOM4J。目前許多開源項(xiàng)目中大量采用DOM4J,例如大名鼎鼎的Hibernate也用DOM4J來讀取XML配置文件。如果不考慮可移植性,那就采用DOM4J。

2、JDOM和DOM在性能測(cè)試時(shí)表現(xiàn)不佳,在測(cè)試10M文檔時(shí)內(nèi)存溢出。在小文檔情況下還值得考慮使用DOM和JDOM。雖然JDOM的開發(fā)者已經(jīng)說明他們期望在正式發(fā)行版前專注性能問題,但是從性能觀點(diǎn)來看,它確實(shí)沒有值得推薦之處。另外,DOM仍是一個(gè)非常好的選擇。DOM實(shí)現(xiàn)廣泛應(yīng)用于多種編程語言。它還是許多其它與XML相關(guān)的標(biāo)準(zhǔn)的基礎(chǔ),因?yàn)樗将@得W3C推薦(與基于非標(biāo)準(zhǔn)的Java模型相對(duì)),所以在某些類型的項(xiàng)目中可能也需要它(如在JavaScript中使用DOM)。

3、SAX表現(xiàn)較好,這要依賴于它特定的解析方式-事件驅(qū)動(dòng)。一個(gè)SAX檢測(cè)即將到來的XML流,但并沒有載入到內(nèi)存(當(dāng)然當(dāng)XML流被讀入時(shí),會(huì)有部分文檔暫時(shí)隱藏在內(nèi)存中)

到此,相信大家對(duì)“Java開發(fā)中的面試題有哪些”有了更深的了解,不妨來實(shí)際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI