Java程序員面試分類真題7_第1頁
Java程序員面試分類真題7_第2頁
Java程序員面試分類真題7_第3頁
Java程序員面試分類真題7_第4頁
Java程序員面試分類真題7_第5頁
已閱讀5頁,還剩32頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認(rèn)領(lǐng)

文檔簡介

Java程序員面試分類真題7(總分:100.00,做題時間:120分鐘)一、單項選擇題(總題數(shù):30,分?jǐn)?shù):60.00)1.

以下可以對對象加互斥鎖的關(guān)鍵字是______。

(分?jǐn)?shù):2.00)

A.synchronized

B.serialize

C.volatile

D.static解析:對于選項A,synchronized(同步的)是Java語言的關(guān)鍵字,主要用來給對象和方法或者代碼塊加鎖,當(dāng)它鎖定一個方法或者一個代碼塊的時候,同一時刻最多只有一個線程執(zhí)行這段代碼。當(dāng)兩個并發(fā)線程訪問同一個對象中的這個加鎖同步代碼塊時,同一時間只能有一個線程執(zhí)行。所以,選項A正確。

對于選項B,serialize是序列化的意思,所謂對象的序列化指的是把對象轉(zhuǎn)換為字節(jié)序列的過程,所謂對象的反序列化指的是把字節(jié)序列恢復(fù)為對象的過程。通常,對象的序列化主要有以下兩種用途:①把對象的字節(jié)序列永久地保存到硬盤上,通常存放在一個文件中;②在網(wǎng)絡(luò)上傳送對象的字節(jié)序列。在Java語言中,序列化通過Serializable接口來實現(xiàn)。所以,選項B不正確。

對于選項C,在由Java語言編寫的程序中,有時候為了提高程序的運行效率,編譯器會做一些優(yōu)化操作,把經(jīng)常被訪問的變量緩存起來,程序在讀取這個變量的時候有可能會直接從寄存器中來讀取這個值,而不會去內(nèi)存中讀取。這樣做的一個好處是提高了程序的運行效率,但當(dāng)遇到多線程編程時,變量的值可能被其他線程改變了,而該緩存的值不會做相應(yīng)的改變,從而造成應(yīng)用程序讀取的值和實際的變量值不一致。關(guān)鍵字volatile正好能夠解決這一問題,被關(guān)鍵字volatile修飾的變量編譯器不會做優(yōu)化,每次都會從內(nèi)存中讀取。所以,選項C不正確。

對于選項D,關(guān)鍵字static主要有以下兩種作用:第一,為某特定數(shù)據(jù)類型或?qū)ο蠓峙鋯我坏拇鎯臻g,而與創(chuàng)建對象的個數(shù)無關(guān);第二,希望某個方法或?qū)傩耘c類而不是對象關(guān)聯(lián)在一起,也就是說,在不創(chuàng)建對象的情況下就可以通過類來直接調(diào)用方法或使用類的屬性??傊?,被static修飾的屬性(方法)是類的屬性(方法),不屬于任何對象。所以,選項D不正確。2.

JavaTbread中的方法resume()負(fù)責(zé)恢復(fù)哪些線程的執(zhí)行?______

(分?jǐn)?shù):2.00)

A.通過調(diào)用wait()方法而停止運行的線程

B.通過調(diào)用sleep()方法而停止運行的線程

C.通過調(diào)用stop()方法而停止運行的線程

D.通過調(diào)用suspend()方法而停止運行的線程

√解析:對于選項A,wait()方法是一種使線程暫停執(zhí)行的方法,例如,當(dāng)線程交互時,如果線程對一個同步對象發(fā)出了一個wait()調(diào)用請求,那么該線程會暫停執(zhí)行,被調(diào)對象進入等待狀態(tài),直到被喚醒(通常使用notify方法喚醒)或等待時間超時。所以,選項A錯誤。

對于選項B,sleep()方法的作用是使當(dāng)前運行的線程休眠指定的時間。所以,選項B錯誤。

對于選項C,可以使用stop()方法來終止線程的執(zhí)行。當(dāng)使用Tbread.stop()方法來終止線程時,它會釋放已經(jīng)鎖定的所有的監(jiān)視資源。如果當(dāng)前任何一個受這些監(jiān)視資源保護的對象處于一個不一致的狀態(tài),其他的線程將會看到這個不一致的狀態(tài),這可能會導(dǎo)致程序執(zhí)行的不確定性,并且這種問題很難被定位。因此,不推薦使用。所以,選項C錯誤。

對于選項D,suspend()方法就是將一個線程掛起(暫停),并且不會自動恢復(fù),必須通過調(diào)用對應(yīng)的resume()方法,才能使得線程重新進入可執(zhí)行狀態(tài)。所以,選項D正確。3.

在一個線程中,sleep(100)方法將使得該線程在______后獲得對CPU的控制(假設(shè)睡眠過程中不會有其他事件喚醒該線程)。

(分?jǐn)?shù):2.00)

A.正好100ms

B.100ms不到

C.≥100ms

D.不一定解析:Tbread.sleep(longmillis)和Tbread.sleep(longmillis,intnanos)靜態(tài)方法強制當(dāng)前正在執(zhí)行的線程休眠(即暫停執(zhí)行),當(dāng)線程睡眠時,它睡在某個地方,在蘇醒之前不會返回到可運行狀態(tài)。當(dāng)睡眠時間到期,則返回到可運行狀態(tài)。所以,sleep()方法指定的時間為線程不會運行的最短時間。當(dāng)線程休眠時間結(jié)束后,會返回到可運行狀態(tài),注意不是運行狀態(tài),如果要到運行狀態(tài)還需要等待CPU調(diào)度執(zhí)行。因此,sleep()方法不能保證該線程睡眠到期后就開始執(zhí)行。所以,選項C正確。

引申:sleep與wait有什么區(qū)別?

sleep()是使線程暫停執(zhí)行一段時間的方法。wait()也是一種使線程暫停執(zhí)行的方法,例如,當(dāng)線程交互時,如果線程對一個同步對象x發(fā)出一個wait()調(diào)用請求,那么該線程會暫停執(zhí)行,被調(diào)對象進入等待狀態(tài),直到被喚醒或等待時間超時。

具體而言,sleep與wait的區(qū)別主要表現(xiàn)在以下幾個方面:

1)原理不同。sleep是Thread類的靜態(tài)方法,是線程用來控制自身流程的,它會使此線程暫停執(zhí)行指定時間,而把執(zhí)行機會讓給其他線程,等到計時時間到時,此線程會自動蘇醒。例如,當(dāng)線程執(zhí)行報時功能時,每一秒鐘打印出一個時間,那么此時就需要在打印方法前面加上一個sleep方法,以便讓自己每隔一秒執(zhí)行一次,該過程如同鬧鐘一樣。而wait是Object類的方法,用于線程間的通信,這個方法會使當(dāng)前擁有該對象鎖的進程等待,直到其他線程調(diào)用notify方法(或notifyAll方法)時才醒來,不過開發(fā)人員也可以給它指定一個時間,自動醒來。與wait配套的方法還有notify和notifyAll。

2)對鎖的處理機制不同。由于sleep方法的主要作用是讓線程休眠指定的一段時間,在時間到時自動恢復(fù),不涉及線程間的通信,因此,調(diào)用sleep方法并不會釋放鎖。而wait方法則不同,當(dāng)調(diào)用wait方法后,線程會釋放掉它所占用的鎖,從而使線程所在對象中的其他synchronized數(shù)據(jù)可被其他線程使用。舉個簡單例子,在小明拿遙控器期間,他可以用自己的sleep方法每隔十分鐘調(diào)一次電視臺,而在他調(diào)臺休息的十分鐘期問,遙控器還在他的手上。

3)使用區(qū)域不同。由于wait方法的特殊意義,所以,它必須放在同步控制方法或者同步語句塊中使用,而sleep方法則可以放在任何地方使用。

4)sleep方法必須捕獲異常,而wait、notify以及notifyall不需要捕獲異常。在sleep的過程中,有可能被其他對象調(diào)用它的interrupt(),產(chǎn)生InterruptedException異常。

由于sleep不會釋放“鎖標(biāo)志”,容易導(dǎo)致死鎖問題的發(fā)生,所以,一般情況下,不推薦使用sleep方法,而推薦使用wait方法。4.

下面不是mead類的方法是______。

(分?jǐn)?shù):2.00)

A.run!()

B.start()

C.exit()

D.stop()解析:在Java語言中,Tharead類位于java.lang命名空間下。Thread類主要用于創(chuàng)建并控制線程、設(shè)置線程優(yōu)先級并獲取其狀態(tài)。

本題中,對于選項A,要實現(xiàn)多線程,在繼承了Thread類后必須實現(xiàn)run()方法,也就是說,線程的核心邏輯都存在于run()方法中。這個方法被start()方法調(diào)用來實現(xiàn)多線程的功能,如果直接調(diào)用run()方法,那么就與調(diào)用普通的方法類似。所以,選項A錯誤。

對于選項B,Tbread類提供了一個start()方法,該方法的功能是讓這個線程開始執(zhí)行,當(dāng)開始執(zhí)行后,JVM將會調(diào)用這個線程的run()方法來執(zhí)行這個線程的任務(wù)。所以,選項B錯誤。

對于選項C,Tbread類沒有exit()這個方法。所以,選項C正確。

對于選項D,Thread類的stop()方法是用來停止一個線程的,但是由于這個方法不是線程安全的,因此,通常不推薦使用。所以,選項D錯誤。5.

有如下代碼:

publicstaticvoidmain(Stringargs[])

{

Threadt=DewThread()

{

publicvoidrun()

{

world();

}

};

t.run();

System.out.print("hello");

}

staticvoidworld()

{

System.out.print("world");

}

上面程序的運行結(jié)果是______。

(分?jǐn)?shù):2.00)

A.helloworld

B.worldhello

C.A和B都有可能

D.都不輸出解析:Thread類提供了一個start()方法,這個方法的功能是讓這個線程開始執(zhí)行,當(dāng)開始執(zhí)行后,JVM將會調(diào)用這個線程的run()方法來執(zhí)行這個線程的任務(wù)。如果直接調(diào)用run()方法就與調(diào)用普通的方法類似。

對于本題而言,首先調(diào)用t.run()方法,輸出“world”,等調(diào)用結(jié)束后才會執(zhí)行System.out.print("hello")語句,輸出“hello”。所以,選項B正確。

如果把t.run()改成t.start(),在調(diào)用t.start()方法后不需要等這個線程結(jié)束,這個方法就會立即返回,然后執(zhí)行語句System.out.print("Hllo"),在這種情況下,這兩個輸出語句的執(zhí)行順序是無法保證的,任何一個語句都有可能先執(zhí)行,因此,答案就是選項C。6.

有如下代碼:

publicclassTestextendsThread

{

publicstaticvoidmain(Stringargv[])

{

Testb=newTest();

b.run();

}

publicvoidstart()

{

for(inti=0;i<10;i++)

{

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

}

}

}

當(dāng)編譯并運行上面程序時,輸出結(jié)果是______。

(分?jǐn)?shù):2.00)

A.編譯錯誤,指明run方法沒有定義

B.運行錯誤,指明run方法沒有定義

C.編譯通過并輸出0到9

D.編譯通過但無輸出

√解析:在Java語言中,可以采用以下兩種方法來創(chuàng)建線程:繼承Thread類與實現(xiàn)Runnable接口。其中,在使用Runnable接口時,需要建立一個Thread實例。所以,無論是通過Thread類創(chuàng)建線程還是通過Runnable接口創(chuàng)建線程,都必須建立Thread類或它的子類的實例。

Thread類提供了一個start()方法,該方法的功能是讓這個線程開始執(zhí)行,當(dāng)這個線程開始執(zhí)行后,JVM將會調(diào)用這個線程的run()方法來執(zhí)行這個線程的任務(wù)。在實現(xiàn)多線程時,在繼承了Thread類后必須實現(xiàn)run()方法,也就是說,線程的核心邏輯都存在于run()方法中,這個方法被start()方法調(diào)用來實現(xiàn)多線程的功能,如果直接調(diào)用run()方法,就與調(diào)用普通的方法類似。

對于本題而言,Test類繼承了Thread類,但是沒有重寫Thread類的run()方法,因此,b.run()實際上調(diào)用的是Tbread類的run()方法,而Thread類的run()方法的方法體為空,故這個程序能編譯通過,但是沒有輸出結(jié)果。所以,選項D正確。7.

以下可以啟動一個線程的方法是______。

(分?jǐn)?shù):2.00)

A.start()

B.ran()

C.begin()

D.notify()解析:Thread類提供了一個start方法,這個方法的功能是讓這個線程開始執(zhí)行,開始執(zhí)行后,JVM將會調(diào)用這個線程的run方法來執(zhí)行這個線程的任務(wù)。在實現(xiàn)多線程的時候,在繼承了Thread方法后必須實現(xiàn)run方法,也就是說,線程的核心邏輯都存在于run方法中。這個方法被start方法調(diào)用來實現(xiàn)多線程的功能,如果直接調(diào)用run方法就與調(diào)用普通的方法類似。所以,選項A正確,選項B錯誤。

對于選項C,在Java語言中,線程是沒有begin方法的。所以,選項C錯誤。

對于選項D,notify方法是用來喚醒一個線程的,而不是啟動一個線程。所以,選項D錯誤。8.

對于Java語言中的Daemon線程,setDaemon設(shè)置必須要______。

(分?jǐn)?shù):2.00)

A.在start之后

B.在start之前

C.前后都可以

D.前后都不可以解析:Java語言提供了兩種線程:守護線程(DaemonThread)與用戶線程。守護線程又稱為“服務(wù)進程”“精靈線程”或“后臺線程”,是指當(dāng)程序運行的時候,在后臺提供一種通用服務(wù)的線程,這種線程并不屬于程序中不可或缺的部分。通俗點講,任何一個守護線程都是整個JVM中所有非守護線程的保姆。

用戶線程和守護線程幾乎一樣,唯一的不同之處就在于:如果用戶線程已經(jīng)全部退出運行,只剩下守護線程存在,JVM也就退出了。因為當(dāng)所有的非守護線程結(jié)束時,沒有了被守護者,守護線程也就沒有工作可做,也就沒有繼續(xù)運行程序的必要了,程序也就終止,同時會殺死所有守護線程。也就是說,只要有任何非守護線程還在運行,程序就不會終止。

在Java語言中,守護線程一般具有較低的優(yōu)先級,它并非只由JVM內(nèi)部提供,用戶在編寫程序時也可以自己設(shè)置守護線程。例如,將一個用戶線程設(shè)置為守護線程的方法就是在調(diào)用start啟動線程之前調(diào)用對象的setDaemon(true)方法,如果將以上參數(shù)設(shè)置為false,則表示的是用戶進程模式。需要注意的是,當(dāng)在一個守護線程中產(chǎn)生了其他線程,那么這些新產(chǎn)生的線程默認(rèn)還是守護線程,用戶線程也是如此。所以,選項B正確。9.

當(dāng)線程1使用某個對象,而此對象又需要線程2修改后才能符合線程1的需要,這時線程1就要等待線程2完成修改工作,這種現(xiàn)象稱為______。

(分?jǐn)?shù):2.00)

A.線程的同步

B.線程的調(diào)度

C.線程的就緒

D.線程的互斥解析:對于選項A,同步就是協(xié)同步調(diào),按預(yù)定的先后次序進行運行。例如你說完,我再說。該定義正好與題目描述一致。所以,選項A正確。

對于選項B,假設(shè)計算機的CPU在任意時刻都只能執(zhí)行一條機器指令,線程只有獲得CPU的使用權(quán)才能執(zhí)行對應(yīng)的操作,多線程的并發(fā)運行原理為:各個線程輪流獲得CPU的使用權(quán),來執(zhí)行對應(yīng)的操作。線程調(diào)度是指按照特定機制為多個線程分配CPU的使用權(quán)。所以,選項B錯誤。

對于選項C,線程有多個狀態(tài),就緒是指這個線程已經(jīng)有了除CPU外所有的資源,在等待獲取CPU,一旦獲取到CPU的控制權(quán)就可以立即執(zhí)行。所以,選項C錯誤。

對于選項D,線程互斥是指某一資源同時只允許一個訪問者對其進行訪問,具有唯一性和排它性。但互斥無法限制訪問者對資源的訪問順序,即訪問是無序的。所以,選項D錯誤。10.

有如下代碼:

publicclassXextendsThreadimplementsRunable

{

publicvoidrun()

{

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

}

publicstaticvoidmain(Stringargs[])

{

Threadt=newThread(newX());

t.start();

}

}

程序的運行結(jié)果為______。

(分?jǐn)?shù):2.00)

A.第一行會產(chǎn)生編譯錯誤

B.第六行會產(chǎn)生編譯錯誤

C.第六行會產(chǎn)生運行錯誤

D.程序會運行和啟動

√解析:11.

可以對對象加互斥鎖的關(guān)鍵字是______。

(分?jǐn)?shù):2.00)

A.transient

B.synchronized

C.serialize

D.static解析:12.

下列可以終止當(dāng)前線程的運行的是______。

(分?jǐn)?shù):2.00)

A.當(dāng)拋出一個異常時

B.當(dāng)該線程調(diào)用sleep()方法時

C.當(dāng)創(chuàng)建一個新線程時

D.當(dāng)一個優(yōu)先級高的線程進入就緒狀態(tài)時解析:13.

GC線程______守護線程。

(分?jǐn)?shù):2.00)

A.是

B.不是

C.不確定解析:Java語言提供了兩種線程:守護線程與用戶線程。守護線程又被稱為“服務(wù)進程”“精靈線程”或“后臺線程”,是指當(dāng)程序運行時,在后臺提供一種通用服務(wù)的線程,這種線程并不屬于程序中不可或缺的部分。通俗點講,任何一個守護線程都是整個JVM中所有非守護線程的保姆。

用戶線程和守護線程幾乎一樣,唯一的不同之處就在于如果用戶線程已經(jīng)全部退出運行,只剩下守護線程存在,Java虛擬機也就退出了。因為當(dāng)所有的非守護線程結(jié)束時,沒有了被守護者,守護線程也就沒有工作可做,也就沒有繼續(xù)運行程序的必要了,程序也就終止,同時會殺死所有守護線程。也就是說,只要有任何非守護線程還在運行,程序就不會終止。

在Java語言中,守護線程一般具有較低的優(yōu)先級,它并非只由JVM內(nèi)部提供,用戶在編寫程序時,也可以自己設(shè)置守護線程。例如,將一個用戶線程設(shè)置為守護線程的方法就是在調(diào)用start方法啟動線程之前調(diào)用對象的setDaemon(true)方法,如果將以上參數(shù)設(shè)置為false,則表示的是用戶進程模式。需要注意的是,當(dāng)在一個守護線程中產(chǎn)生了其他線程,那么這些新產(chǎn)生的線程默認(rèn)還是守護線程,用戶線程也是如此。

守護線程的一個典型的例子就是垃圾回收器。只要JVM啟動,它就始終在運行,實時監(jiān)控和管理系統(tǒng)中可以被回收的資源。

所以,選項A正確。14.

事務(wù)隔離級別是由______實現(xiàn)的。

(分?jǐn)?shù):2.00)

A.Hibernate

B.Java應(yīng)用程序

C.數(shù)據(jù)庫系統(tǒng)

D.JDBC驅(qū)動程序解析:對于選項A,Hibemate是一個開放源代碼的對象關(guān)系映射框架,它對JDBC進行了非常輕量級的對象封裝,使得Java程序員可以隨心所欲地使用對象編程思維來操縱數(shù)據(jù)庫。所以,選項A不正確。

對于選項B,Java應(yīng)用程序可以通過JDBC或Hiberhate對數(shù)據(jù)庫系統(tǒng)進行訪問。雖然JDBC和Hibernate都提供了事務(wù)控制的接口,但這些接口只是把事務(wù)控制相關(guān)的命令發(fā)送給數(shù)據(jù)庫系統(tǒng),由數(shù)據(jù)庫系統(tǒng)來控制事務(wù)的隔離級別。所以,選項B不正確。

對于選項C,數(shù)據(jù)庫系統(tǒng)是為適應(yīng)數(shù)據(jù)處理的需要而發(fā)展起來的一種較為理想的數(shù)據(jù)處理系統(tǒng),也是一個為實際可運行的存儲、維護和應(yīng)用系統(tǒng)提供數(shù)據(jù)的軟件系統(tǒng),是存儲介質(zhì)、處理對象和管理系統(tǒng)的集合體。在數(shù)據(jù)庫操作中,為了保證在并發(fā)情況下數(shù)據(jù)讀寫的正確性,提出了事務(wù)隔離級別。在標(biāo)準(zhǔn)SQL規(guī)范中,定義了4個事務(wù)隔離級別,分別為未授權(quán)讀取,也稱為讀未提交(ReadUncommitted);授權(quán)讀取,也稱為讀提交(ReadCommitted);可重復(fù)讀取(RepeatableRead);序列化(Seiializable)。所以,事務(wù)隔離級別是由數(shù)據(jù)庫系統(tǒng)實現(xiàn)的。所以,選項C正確。

對于選項D,JDBC驅(qū)動程序是一種用于執(zhí)行SQL語句的JavaAPI,可以為多種關(guān)系數(shù)據(jù)庫提供統(tǒng)一訪問。所以,選項D不正確。15.

下列選項中,提供了Java存取數(shù)據(jù)庫能力的包是______。

(分?jǐn)?shù):2.00)

A.java.sql

B.java.swing

C.java.io

D.java.awt解析:包(package)是Java語言提供的一種區(qū)別類的命名空間的機制,它是類的組織方式,是一組相關(guān)類和接口的集合,提供了訪問權(quán)限和命名的管理機制。

在Java語言中,包的作用主要體現(xiàn)在以下三個方面:

1)方便查找與使用。將功能相近的類放在同一個包中,可以方便查找與使用。

2)避免命名沖突。由于在不同包中可以存在同名類,所以,使用包的好處是在一定程度上可以避免命名沖突。

3)訪問權(quán)限設(shè)定。某次訪問權(quán)限是以包為單位的。

本題中,對于選項A,java.sql包中主要包含一些訪問數(shù)據(jù)庫相關(guān)的接口。所以,選項A正確。

對于選項B,java.swing是一個用于開發(fā)Java應(yīng)用程序用戶界面的開發(fā)工具包。所以,選項B錯誤。

對于選項C,java.io提供了流處理的相關(guān)接口。所以,選項C錯誤。

對于選項D,java.awt包含用于創(chuàng)建用戶界面和繪制圖形圖像的所有類。所以,選項D錯誤。16.

在JDBC中,用于表示數(shù)據(jù)庫連接的對象是______。

(分?jǐn)?shù):2.00)

A.Statement

B.Connection

C.PreparedStatement

D.DriverManager解析:JDBC(JavaDataBaseConnectivity,Java數(shù)據(jù)庫連接)用于在Java程序中實現(xiàn)數(shù)據(jù)庫操作功能,它提供了執(zhí)行SQL語句、訪問各種數(shù)據(jù)庫的方法,并為各種不同的數(shù)據(jù)庫提供統(tǒng)一的操作接口,java.sql包中包含了JDBC操作數(shù)據(jù)庫的所有類。通過JDBC訪問數(shù)據(jù)庫一般有如下幾個步驟:

1)加載JDBC驅(qū)動器。將數(shù)據(jù)庫的JDBC驅(qū)動加載到classpath中,在基于JavaEE的Web應(yīng)用開發(fā)過程中,通常要把目標(biāo)數(shù)據(jù)庫產(chǎn)品的JDBC驅(qū)動復(fù)制到WEB-INF/lib下。

2)加載JDBC驅(qū)動,并將其注冊到DriverManager中。一般使用反射Class.forName(StringdriveNamel。

3)建立數(shù)據(jù)庫連接,取得Connection對象。一般通過DriverManager.getConnection(url,username,passwd)方式實現(xiàn),其中,url表示連接數(shù)據(jù)庫的字符串,username表示連接數(shù)據(jù)庫的用戶名,passwd表示連接數(shù)據(jù)庫的密碼。

4)建立Statement對象或者PreparedStatement對象。

5)通過Statement或PreparedStatement對象執(zhí)行SQL語句。

6)訪問結(jié)果集ResultSet對象。

7)依次將ResultSet、Statement、PreparedStatement、Connection等對象關(guān)閉,釋放掉所占用的資源。

通過上述分析可知,選項B正確。17.

在Java語言中,用于調(diào)用存儲過程的對象是______。

(分?jǐn)?shù):2.00)

A.DriverManager

B.ResultSet

C.CallableStatemet

D.PreparedStatement解析:存儲過程(StoredProcedure)是在大型數(shù)據(jù)庫系統(tǒng)中,一組為了完成特定功能的SQL語句集,存儲在數(shù)據(jù)庫中經(jīng)過第一次編譯后再次調(diào)用不需要再次編譯,用戶通過指定存儲過程的名字并給出參數(shù)(如果該存儲過程帶有參數(shù))來執(zhí)行它。存儲過程是數(shù)據(jù)庫中的一個重要對象,任何一個設(shè)計良好的數(shù)據(jù)庫應(yīng)用程序都應(yīng)該用到存儲過程。

本題中,對于選項A,DriverManager是JDBC的管理層,它作用于用戶和驅(qū)動程序之間,管理一組JDBC驅(qū)動程序的基本服務(wù),提供用來建立數(shù)據(jù)庫連接的一系列方法。除此以外,DriverManager還處理諸如驅(qū)動程序登錄時間限制以及登錄與跟蹤消息的顯示等事務(wù)。因此,選項A錯誤。

對于選項B,ResultSet表示查詢的結(jié)果集,通常通過執(zhí)行查詢數(shù)據(jù)庫的語句生成。ResultSet對象具有指向其當(dāng)前數(shù)據(jù)行的光標(biāo)。最初,光標(biāo)被置于第一行之前,next方法將光標(biāo)移動到下一行,因為該方法在ResultSet對象沒有下一行時返回false,所以,可以在while循環(huán)中使用它來迭代結(jié)果集。因此,選項B錯誤。

對于選項C,CallableStatement提供了用來調(diào)用數(shù)據(jù)庫中存儲過程的接口,如果有輸出參數(shù)要注冊,說明是輸出參數(shù)。因此,選項C正確。

對于選項D,PreparedStatement表示預(yù)編譯的SQL語句的對象,用于執(zhí)行帶參數(shù)的預(yù)編譯SQL語句。因此,選項D錯誤。18.

下面不是標(biāo)準(zhǔn)的Statement類的是______。

(分?jǐn)?shù):2.00)

A.Statement

B.CallableStatement

C.PreparedStatement

D.BatchedStatement

√解析:本題中,對于選項A,Statement是Java語言執(zhí)行數(shù)據(jù)庫操作的一個重要方法,用于在已經(jīng)建立數(shù)據(jù)庫連接的基礎(chǔ)上,向數(shù)據(jù)庫發(fā)送要執(zhí)行的SQL語句,并返回它所生成結(jié)果的對象,每次執(zhí)行SQL語句時,數(shù)據(jù)庫都要編譯該SQL語句。以下是一個最簡單的SQL語句:

Statementstmt=conn.getStatement();

stmt.executeUpdate("insertintoclientvalues('aa','aaaa')");

所以,選項A錯誤。

對于選項B,CallableStatement提供了用來調(diào)用數(shù)據(jù)庫中存儲過程的接口。所以,選項B錯誤。

對于選項C,PreparedStatement表示預(yù)編譯的SQL語句的對象,用于執(zhí)行帶參數(shù)的預(yù)編譯SQL語句。所以,選項C錯誤。

對于選項D,不存在BatchedStatement方法。所以,選項D正確。19.

以下獲取ResutlSet對象rst的第一行數(shù)據(jù)的方法中,正確的是______。

(分?jǐn)?shù):2.00)

A.rst.hashNext();

B.rst.next();

C.rst.first();

D.rst.nextRow();解析:ResultSet(結(jié)果集)是數(shù)據(jù)中查詢結(jié)果返回的一種對象,通常通過執(zhí)行查詢數(shù)據(jù)庫的語句生成。ResultSet對象不僅具有存儲功能,還具有操縱數(shù)據(jù)的功能。

ResultSet對象具有指向其當(dāng)前數(shù)據(jù)行的指針,它包含了符合SQL語句查詢結(jié)果的所有行,提供了一套get方法(訪問當(dāng)前行的不同列)用于對這些行中數(shù)據(jù)進行訪問。ResultSet的next方法用于移動到ResultSet中的下一行,使下一行成為當(dāng)前行。因此,對于剛獲取到的ResultSet對象,第一次調(diào)用next方法就會得到第一行的數(shù)據(jù)。所以,選項B正確。

所以,本題的答案為B。20.

為了讓瀏覽器以UTF-8編碼顯示JSP頁面,下列JSP代碼正確的是______。

(分?jǐn)?shù):2.00)

A.<%pagecontentType=

B.<metahttp-equiv=

C.把所有的輸出內(nèi)容重新編碼:newSTRing(content.getBytes())

D.response.setContentType()

√解析:選項A設(shè)置的是服務(wù)器端編碼,選項B設(shè)置的是客戶端編碼,選項C設(shè)置的是某個字符串的編碼。只有選項D滿足題意。21.

Servlet處理請求的方式為______。

(分?jǐn)?shù):2.00)

A.以程序的方式

B.以進程的方式

C.以線程的方式

D.以響應(yīng)的方式解析:SeiMet是采用Java語言編寫的服務(wù)器端程序,運行于Web服務(wù)器的Servlet容器中,其主要功能是提供請求/響應(yīng)的Web服務(wù)模式,可以生成動態(tài)的Web內(nèi)容,工作原理如圖所示。

Servlet工作原理

Servlet處理客戶端請求通常有如下幾個步驟:

1)用戶通過單擊一個鏈接來向Servlet發(fā)起請求。

2)Web服務(wù)器接收到該請求后,會把該請求提交給相應(yīng)的容器來處理,當(dāng)容器發(fā)現(xiàn)這是對Servlet發(fā)起的請求后,容器此時會創(chuàng)建兩個對象:HttpServletResponse和HttpServletRequest。

3)容器可以根據(jù)請求消息中的URL消息找到對應(yīng)的Servlet,然后針對該請求創(chuàng)建一個單獨的線程,同時把第2)步中創(chuàng)建的兩個對象以參數(shù)的形式傳遞到新創(chuàng)建的線程中。

4)容器調(diào)用Servlel的service()方法來完成對用戶請求的響應(yīng),service()方法會調(diào)用doPost()方法或doGet()方法來完成具體的響應(yīng)任務(wù),同時把生成的動態(tài)頁面返回給容器。

5)容器把響應(yīng)消息組裝成HTTP格式返回給客戶端。此時,這個線程運行結(jié)束,同時刪除第2)步創(chuàng)建的兩個對象.HttpServletResponse和HttpServletRequest。

容器會針對每次請求創(chuàng)建一個新的線程進行處理,同時,會針對每次請求創(chuàng)建HttpServletResponse和HttpServletRequest兩個對象,處理完成后,線程也就退出了。所以,選項C正確。22.

按照MVC設(shè)計模式,JSP用于實現(xiàn)______。

(分?jǐn)?shù):2.00)

A.Controller(控制器)

B.View(視圖)

C.Model(模型)

D.Database(數(shù)據(jù)庫)解析:使用JSP與Servlet實現(xiàn)的MVC模型如圖所示。

MVC模型

在這個MVC模型中,視圖模塊采用JSP來實現(xiàn),主要負(fù)責(zé)數(shù)據(jù)的展現(xiàn),視圖可以從控制器上獲取模型的狀態(tài),當(dāng)然不是直接從控制器上獲取到的,而是控制器把模型的數(shù)據(jù)放到一個視圖可以訪問的地方,通過這種間接的方式來訪問模型的數(shù)據(jù)。

控制器使用Servlet來實現(xiàn),客戶端的所有請求都發(fā)送給Servlet,它接受請求,并根據(jù)請求消息把它們分發(fā)給對應(yīng)的JSP頁面來響應(yīng),同時根據(jù)需求生成JavaBean實例供JSP來使用。

模型采用JavaBean來實現(xiàn)的,這個模塊實現(xiàn)了實際的業(yè)務(wù)邏輯。

從以上分析可知,選項B正確。23.

在JSP葉旨令中,isELIgnored="boolean"的意思是______。

(分?jǐn)?shù):2.00)

A.決定該頁面是否是一個錯誤處理頁面

B.決定是否實現(xiàn)setvlet的單線程模式

C.決定是否支持EL表示

D.沒有具體的含義解析:isELIgnored屬性用來指定該JSP文件是否支持EL(ExpressionLanguage,表達式語言)表達式。如果值為true,那么對于類似于${..}這樣的內(nèi)容,直接會原樣輸出,而不會進行EL表達式運算;如果值為false,那么表示EL表達式不會被忽略,該EL表達式將會被執(zhí)行。其屬性配置語法格式如下:<%@pageisELIgnored="true|false"%>。所以,選項C正確。24.

在WEB-INF目錄下,必須存放的文件為______。

(分?jǐn)?shù):2.00)

A.class文件

B.web.xml

C.html文件

D.jar文件解析:WEB-INF是Web應(yīng)用的安全目錄。所謂安全目錄就是客戶端無法訪問,只有服務(wù)端可以訪問的目錄。如果想在頁面中直接訪問其中的文件,必須通過web.xml文件對要訪問的文件進行相應(yīng)的映射才行。WEB-INF文件夾下除了web.xml外,還存在一個classes文件夾,用以放置*.class文件,這些*.class文件是設(shè)計人員編寫的類庫,實現(xiàn)了JSP頁面前臺與后臺服務(wù)的分離,使得網(wǎng)站的維護非常方便。web.xml文件為網(wǎng)站部署描述XML文件,它對網(wǎng)站的部署非常重要。因此,web.xml是必不可少的文件。所以,選項B正確。25.

在JavaScript中,以下驗證一個數(shù)據(jù)是否是數(shù)字的描述中,正確的是______。

(分?jǐn)?shù):2.00)

A.imtI=value若報錯就不是數(shù)字

B.如果用Integer.parseInt(yalue)有誤就不是數(shù)字

C.沒有方法驗證

D.利用isNaN(value)返回的boolean進行判斷

√解析:對于選項A,JavaScript是弱類型語言(也稱為弱類型定義語言,與強類型定義相反。弱類型語言允許將一塊內(nèi)存看作多種類型,比如直接將整型變量與字符變量相加。C/C++是靜態(tài)語言,是強類型語言;Perl與PHP是動態(tài)語言,但也是弱類型語言),只有一種類型var。所以,選項A錯誤。

對于選項B,Integer.parseInt(value)是Java語言中的方法,而不是JavaScript的方法。所以,選項B錯誤。

對于選項C,JavaScript中驗證一個數(shù)據(jù)是否是數(shù)字是存在方法的,可以使用isNaN()函數(shù)判斷,也可以使用正則表達式判斷。所以,選項C錯誤。

對于選項D,JavaScript提供了一個isNaN()函數(shù)用于檢查其參數(shù)是否是非數(shù)字值。所以,選項D正確。26.

以下不能作JSP的服務(wù)器的是______。

(分?jǐn)?shù):2.00)

A.JBoss

B.BEAWebLogic

C.Tomcat

D.PWS

√解析:Web服務(wù)器指的是提供Web功能的服務(wù)器,主要就是HTTP服務(wù)器,包括圖片的下載等一系列和文本相關(guān)的資源。Web服務(wù)器支持以HTTP協(xié)議的方式來訪問,當(dāng)Web服務(wù)器接收到一個HTTP請求時,它同樣會以HTTP協(xié)議格式返回一個響應(yīng),這個響應(yīng)可以是一個靜態(tài)的HTML頁面,也可以是結(jié)果處理的一個動態(tài)的頁面,還可以是音頻、視頻等信息。為了處理一個請求,Web服務(wù)器可以做出一個響應(yīng),并進行頁面跳轉(zhuǎn),或者把動態(tài)響應(yīng)的產(chǎn)生委托給一些其他的程序,例如CGl腳本、JSP、Servlet或者一些其他的服務(wù)器端程序。Web服務(wù)器一般都使用了一些特有的機制(例如容錯機制)來保證Web服務(wù)器有較好的擴展性和不問斷地提供服務(wù)。常見的Web服務(wù)器有IIS和Apache。

應(yīng)用服務(wù)器提供訪問業(yè)務(wù)邏輯的途徑以供客戶端應(yīng)用程序使用。具體而言,它通過HTTP、TCP/IP、IIOP(InternetInter-ORBProtocol,互聯(lián)網(wǎng)內(nèi)部對象請求代理協(xié)議)或JRMP(JavaRemoteMethodProtocol,Java遠程方法協(xié)議)等來提供業(yè)務(wù)邏輯接口。為了系統(tǒng)的可靠性,同樣使用了一些可擴展性和容錯機制。除此之外,它還為應(yīng)用的開發(fā)提供了許多服務(wù),例如事務(wù)管理、安全管理和對象生命周期管理等。常見的應(yīng)用服務(wù)器有BEAWebLogicServer、IBMWebSphereApplicationServer、IPlanetApplicationServer、Oracle9iApplicationServer、JBoss和Tomcat等。

Web服務(wù)器一般是通用的,而應(yīng)用服務(wù)器一般是專用的,例如Tomcat只處理Java應(yīng)用程序而不能處理ASPX或PHP。需要注意的是,Web服務(wù)器與應(yīng)用服務(wù)器是并列關(guān)系,二者不存在相互包容關(guān)系。在使用的時候,如果訪問的頁面只有HTML,用Web服務(wù)器就足夠了,但是如果是JSP,此時就需要應(yīng)用服務(wù)器,因為只有應(yīng)用服務(wù)器才能解析JSP里的Java代碼,并將解析結(jié)果以HTML的格式返回給用戶。

從上面的分析可以看出,選項A、選項B和選項C都可以作為JSP的服務(wù)器。

對于選項D,PWS(PersonalWebSetwer,個人Web服務(wù)器)是微軟開發(fā)的個人網(wǎng)站服務(wù)器,主要應(yīng)用于解決個人信息共享和Web開發(fā)。它是一個桌面形的Web服務(wù)器,使用它可以自動創(chuàng)建個性化主頁,以拖放的方式發(fā)布文檔,在它的幫助下,用戶可以快速簡便地進行Web站點設(shè)置。由于它只是一個Web服務(wù)器,因此,它無法作為JSP的服務(wù)器。所以,選項D正確。27.

以下不是JSP操作指令的是______。

(分?jǐn)?shù):2.00)

A.setProperty

B.include

C.forward

D.import

√解析:JSP總共有6個操作指令:jsp:include、jsp:useBean、jsp:setProperty、jsp:getProperty、jsp:forward與jsp:plugin。以下將分別對這幾種指令進行介紹。

jsp:include:用來在頁面被請求的時候引入一個文件。使用示例如下:

<jsp:includepage="test.jsp"flush="true">

<jsp:paramname="name"value="value"/>

</jsp:include>

以上代碼表示在當(dāng)前文件中可以引入test.jsp文件。

jsp:useBean:用來尋找或者實例化一個JavaBean。它使得開發(fā)人員既可以發(fā)揮Java組件重用的優(yōu)勢,同時也避免了損失JSP區(qū)別于Servlet的方便性。使用示例如下:

<jsp:useBean

id="car"scope="session"class="com.Car">

以上代碼表示實例化了一個com.Car類的實例。

jsp:setProperty:用來設(shè)置已經(jīng)實例化的Bean對象的屬性。使用示例如下:

<jsp:setPropertyname="car"property="colour"value="red"/>

以上代碼用來設(shè)置名字為car的實例的colour屬性為red。

jsp:getProperty:用來獲取某個JavaBean的屬性。使用示例如下:

Colom=<jsp:getPropertyname="car"property="colour"></jsp:getProperty>

以上代碼用來獲取名字為car的實例的colour屬性。

jsp:foward:用來把請求轉(zhuǎn)到一個新頁面。使用示例如下:

<jsp:forwardpage="/Servlet/login"/>

以上代碼把當(dāng)前頁面重定向到/Servlet/login來處理。

jsp:plugin:用于在瀏覽器中播放或顯示一個對象。使用這個動作能插入所需的特定瀏覽器的OBJECT或EMBED元素來指定瀏覽器運行一個JAVAApplet所需的插件。使用示例如下:

<jsp:plugintype="applet"codebase="/ch5"code="Hello.class"height="40"width="320">

以上代碼用來在瀏覽器中運行一個applet插件。

由此可見,選項D中的import不是JSP的操作指令。所以,選項D正確。28.

在配置tomcat虛擬目錄時,需要打開的文件是______。

(分?jǐn)?shù):2.00)

A.A.web.xml

B.B.index.jsp

C.C.server.xml

D.D.以上都不是

E.解析:一般情況下,配置虛擬目錄的方法為:

在tomcat\conf下server.xml中找到<Hostname="localhost"appBase="webapps"unpackWARs="true"autoDeploy="true"xmlValidation="false"xmlNamespaceAware="false"></Host>,在其中添加:<Contextpath=""docBase="自定義目錄"reloadable="true"></Context>。因此,選項C正確。

對于選項A,web.xml可以被看作是JSP的一個配置文件,其中一個重要的作用是用來配置Servlet的路徑。所以,選項A錯誤。

對于選項B,index.jsp一般是一個網(wǎng)站的首頁,不包含與tomcat相關(guān)的配置信息。所以,選項B錯誤。29.

下面不是表單標(biāo)記的是______。

(分?jǐn)?shù):2.00)

A.RADIO

B.INPUT

C.CHECKBOX

D.TR

√解析:本題中,對于選項A,RADIO為單選按鈕控件標(biāo)簽,是表單標(biāo)記。所以,選項A錯誤。

對于選項B,INPUT表示Form表單中的一種輸入對象,其又隨Type類型的不同而分為文本輸入框、密碼輸入框、單選/復(fù)選框及提交/重置按鈕等,是表單標(biāo)記。所以,選項B錯誤。

對于選項C,CHECKBOX為多選復(fù)選框標(biāo)簽,是表單標(biāo)記。所以,選項C錯誤。

對于選項D,TR是表中的行標(biāo)簽,不屬于表單標(biāo)記。所以,選項D正確。30.

下面不是response對象的方法的是______。

(分?jǐn)?shù):2.00)

A.addCookie(Cookiecookie)

B.setHeader(Stringheademarne,Stringheadervalue)

C.getParameter(Stringstr)

D.sendError(interrorcode)解析:response對象所提供的方法有如下幾類:

(1)設(shè)定響應(yīng)頭的方法

voidaddCookie(Cookiecookie)

新增cookie

voidaddDateHeader(Stringname,longdate)

新增long類型的值到name響應(yīng)頭

voidaddHeader(Stringname,Stringvalue)

新增String類型的值到name響應(yīng)頭

voidaddIntHeader(Stringname,intvahe)

新增int類型的值到name響應(yīng)頭

voidsetDateHeader(Stringname,longdate)

指定long類型的值到name響應(yīng)頭

voidsetHeader(Stringname,Stringvalue)

指定String類型的值到name響應(yīng)頭

voidsetIntHeader(Stringname,intvalue)

指定int類型的值到name響應(yīng)頭

booleancontainsHeader

判斷指定名字的HTTP文件頭是否已經(jīng)存在,然

后返回真假部爾值

(2)設(shè)定響應(yīng)狀態(tài)碼的方法

voidsendError(intsc)

傳送狀態(tài)碼(StatusCode)

voidsendError(intsc,Stringmsg)

傳送狀態(tài)碼和錯誤信息

voidsetStatus(intsc)

設(shè)定狀態(tài)碼

(3)用來URL重寫(Rewriting)的方法

StringencodeRedirectURL(Stringurl)

對使用sendRedirect()方法的URL予以編碼

(4)設(shè)置重定向

sendRedirect()

設(shè)置重定向頁面

(5)設(shè)置不同瀏覽器對應(yīng)的數(shù)據(jù)

setContentType(StringcontentTypestr):使客戶端瀏覽器,區(qū)分不同種類的數(shù)據(jù),并根據(jù)不同的MIME(MultipurposeInternetMailExtensions,多用途互聯(lián)網(wǎng)郵件擴展類型)調(diào)用瀏覽器內(nèi)不同的程序嵌入模塊來處理相應(yīng)的數(shù)據(jù)。

所以,選項C正確。二、多項選擇題(總題數(shù):6,分?jǐn)?shù):12.00)1.

以下布局管理器中,使用的是組件的最佳尺寸(PreferredSize)的是______。

(分?jǐn)?shù):2.00)

A.FlowLayout

B.BorderLayout

C.GridLayout

D.CardLayout

E.GridBagLayout

√解析:2.

以下關(guān)于線程的描述中,錯誤的是______。

(分?jǐn)?shù):2.00)

A.sleep方法必須寫在同步方法或同步塊中

B.wait方法執(zhí)行時會釋放對象鎖

C.sleep方法執(zhí)行時會釋放對象鎖

D.wait方法必須寫在同步方法或同步塊中解析:3.

Tbread類中本身的方法(不包括繼承)有______。

(分?jǐn)?shù):2.00)

A.start()

B.sleep(longmi)

C.notify()

D.wait()解析:對于選項A,start方法是Thread類中比較重要的方法,JVM通過調(diào)用這個方法啟動一個線程。所以,選項A正確。

對于選項B,sleep是使線程暫停執(zhí)行一段時間的方法。所以,選項B正確。

對于選項C和選項D,wait和notify都是從Object類繼承的方法。所以,選項C和選項D錯誤。4.

在Java語言中,如果需要編寫一個多線程程序,可以使用的方法是______。

(分?jǐn)?shù):2.00)

A.實現(xiàn)Runnable接口

B.擴展類Thread

C.擴展類Runnable

D.實現(xiàn)接口Thread解析:Java多線程實現(xiàn)常用的有兩種方法:繼承Thread類與實現(xiàn)Runnable接口。所以,選項A與選項B正確。5.

下列可用于創(chuàng)建一個可運行的類的方法有______。

(分?jǐn)?shù):2.00)

A.publicclassXimplementsRunnable{publicvoidrun(){}}

B.publicclassXimplementsThread{publicvoidrun(){}}

C.publicclassXimplementsRunnable{publicintrun(){}}

D.publicclassXimplementsRunnable{protectedvoidrun(){}}

E.publicclassXimplementsThread{publicvoidrun(){}}解析:6.

下面可以在任何時候被任何線程調(diào)用的方法有______。

(分?jǐn)?shù):2.00)

A.notify()

B.wait()

C.notifyall()

D.sleep()

E.yield()

F.synchronized(this)

√解析:三、論述題(總題數(shù):13,分?jǐn)?shù):28.00)1.

實現(xiàn)多線程的方法有哪幾種?

(分?jǐn)?shù):4.00)__________________________________________________________________________________________

正確答案:(Java虛擬機(JavaVirtualMachine,JVM,是運行所有Java程序的抽象計算機,是Java語言的運行環(huán)境)允許應(yīng)用程序并發(fā)地運行多個線程。在Java語言中,多線程的實現(xiàn)一般有以下三種方法:

1)實現(xiàn)Runnable接口,并實現(xiàn)該接口的run()方法。以下是主要步驟:

①自定義類并實現(xiàn)Runnable接口,實現(xiàn)run()方法。

②創(chuàng)建Thread對象,用實現(xiàn)Runnable接口的對象作為參數(shù)實例化該Thread對象。

③調(diào)用Thread的start()方法。

classMyThreadimplementsRunnable

{//創(chuàng)建線程類

publicvoidrun()

{

System.out.println("Threadbody");

}

}

publicclassTest

{

publicstaticvoidmain(String[]args)

{

MyThreadthread=newMyThread();

Threadt=newThread(thread);

t.start();

//開啟線程

}

2)繼承Thread類,重寫run方法。Thread本質(zhì)上也是實現(xiàn)了Runnable接口的一個實例,它代表一個線程的實例,并且,啟動線程的唯一方法就是通過Thread類的start()方法。start()方法是一個native(本地)方法,它將啟動一個新線程,并執(zhí)行run()方法(Thread中提供的run()方法是一個空方法)。這種方式通過自定義類直接extendsThread,并重寫run()方法,就可以啟動新線程并執(zhí)行自己定義的run()方法。需要注意的是,當(dāng)start()方法調(diào)用后并不是立即執(zhí)行多線程代碼,而是使得該線程變?yōu)榭蛇\行態(tài)(Runnable),什么時候運行多線程代碼是由操作系統(tǒng)決定的。

下例給出了Thread的使用方法。

classMyThreadextendsThread

{//創(chuàng)建線程類

publicvoidrun()

{

System.out.println("Threadbody");

//線程的方法體

}

}

publicclassTest

{

publicstaticvoidmain(String[]args)

{

MyThreadthread=newMyThread();

thread.start();

//開啟線程

}

3)實現(xiàn)Callable接口,重寫call()方法。Callable對象實際是屬于Executor框架中的功能類,Callable接口與Runnable接口類似,但是提供了比Runnable更強大的功能,主要表現(xiàn)為以下三點:

①Callable可以在任務(wù)結(jié)束后提供一個返回值,Runnable無法提供這個功能。

②Callable中的call()方法可以拋出異常,而Runnable的run()方法不能拋出異常。

③運行Callable可以拿到一個Future對象,F(xiàn)uture對象表示異步計算的結(jié)果。它提供了檢查計算是否完成的方法。由于線程屬于異步計算模型,所以無法從其他線程中得到方法的返回值,在這種情況下,就可以使用Future來監(jiān)視目標(biāo)線程調(diào)用call()方法的情況,當(dāng)調(diào)用Future的get()方法以獲取結(jié)果時,當(dāng)前線程就會阻塞,直到call()方法結(jié)束返回結(jié)果。

示例代碼如下:

importjava.util.concurrent.*;

publicclassCallableAndFuture

{

//創(chuàng)建線程類

publicstaticclassCallableTestimplementsCallable<String>

{

publicStringcall()throwsException

{

return"HelloWorld!";

}

}

publicstaticvoidmain(String[]args)

{

ExecutorServicethreadPool=Executors.newSingleThreadExecutor();

//啟動線程

Future<String>future=threadPool.submit(newCallableTest());

try

{

System.out.println("waitingthreadtofinish");

System.out.println(future.get());//等待線程結(jié)束,并獲取返回結(jié)果

}

catch(Exceptione)

{

e.printStackTrace();

}

}

}

上述程序的運行結(jié)果為:

waitingthreadtofinish

HelloWorid!

在以上三種方式中,前兩種方式線程執(zhí)行完后都沒有返回值,只有最后一種是帶返回值的。當(dāng)需要實現(xiàn)多線程時,一般推薦實現(xiàn)Runnable接口的方式,原因如下:首先,Thread類定義了多種方法可以被派生類使用或重寫,但是只有run方法是必須被重寫的,在run方法中實現(xiàn)這個線程的主要功能。這當(dāng)然是實現(xiàn)Runnable接口所需的同樣的方法。而且,很多Java開發(fā)人員認(rèn)為,一個類僅在它們需要被加強或修改時才會被繼承。因此,如果沒有必要重寫Thread類中的其他方法,那么通過繼承Thread的實現(xiàn)方式與實現(xiàn)Runnable接口的效果相同,在這種情況下最好通過實現(xiàn)Runnable接口的方式來創(chuàng)建線程。)解析:2.

多線程同步有幾種實現(xiàn)方法?

(分?jǐn)?shù):2.00)__________________________________________________________________________________________

正確答案:(當(dāng)使用多線程訪問同一個資源時,非常容易出現(xiàn)線程安全的問題(例如,當(dāng)多個線程同時對一個數(shù)據(jù)進行修改時,會導(dǎo)致某些線程對數(shù)據(jù)的修改丟失)。因此,需要采用同步機制來解決這種問題。Java主要提供了三種實現(xiàn)同步機制的方法:

(1)synchronized關(guān)鍵字

在Java語言中,每個對象都有一個對象鎖與之相關(guān)聯(lián),該鎖表明對象在任何時候只允許被一個線程所擁有,當(dāng)一個線程調(diào)用對象的一段synchronized代碼時,首先需要獲取這個鎖,然后去執(zhí)行相應(yīng)的代碼,執(zhí)行結(jié)束后,釋放鎖。

synchronized關(guān)鍵字主要有兩種用法(synchronized方法和synchronized塊),此外該關(guān)鍵字還可以作用于靜態(tài)方法、類或某個實例,但這都對程序的效率有很大的影響。

1)synchronized方法。在方法的聲明前加入synchronized關(guān)鍵字。例如:

publicsynchronizedvoidmutiThreadAccess();

只要把多個線程訪問的資源的操作放到mutiThreadAccess方法中,就能夠保證這個方法在同一時刻只能被一個線程訪問,從而保證了多線程訪問的安全性。然而,當(dāng)一個方法的方法體規(guī)模非常大時,把該方法聲明為synchronized會大大影響程序的執(zhí)行效率。為了提高程序的執(zhí)行效率,Java語言提供了synchronized塊。

2)synchronized塊??梢园讶我獾拇a段聲明為synchronized,也可以指定上鎖的對象,有非常高的靈活性。用法如下:

synchronized(syncObject){

//訪問syncObject的代碼

}

(2)wait與notify

當(dāng)使用synchronized來修飾某個共享資源的時候,如果線程A1在執(zhí)行synchronized代碼,另外一個線程A2也要同時執(zhí)行同一對象的同一synchronized代碼時,線程A2將要等到線程A1執(zhí)行完成后,才能繼續(xù)執(zhí)行。在這種情況下,可以使用wait方法和notify方法。

在synchronized代碼被執(zhí)行期間,線程可以調(diào)用對象的wait方法,釋放對象鎖,進入等待狀態(tài),并且可以調(diào)用notify方法或notifyAll方法通知正在等待的其他線程,notify方法僅喚醒一個線程(等待隊列中的第一個線程),并允許它去獲得鎖,而notifyAll方法喚醒所有等待這個對象的線程,并允許它們?nèi)カ@得鎖(并不是讓所有喚醒線程都獲取到鎖,而是讓它們?nèi)ジ偁?。

(3)Lock

JDK5新增加了Lock接口以及它的一個實現(xiàn)類ReentrantLock(重入鎖),Lock也可以用來實現(xiàn)多線程的同步,具體而言,它提供了如下的一些方法來實現(xiàn)多線程的同步:

1)lock()。以阻塞的方式來獲取鎖,也就是說,如果獲取到了鎖,則立即返回,如果其他線程持有鎖,當(dāng)前線程等待,直到獲取鎖后返回。

2)tryLock()。以非阻塞的方式獲取鎖。只是嘗試性地去獲取一下鎖,如果獲取到鎖,則立即返回true,否則,立即返回false。

3)tryLock(longtimeout,TimeUnitunit)。如果獲取了鎖,立即返回true,否則,會等待參數(shù)給定的時間單元,在等待的過程中,如果獲取了鎖,就返回true,如果等待超時,則返回false。

4)lockInterruptibly()。如果獲取了鎖,則立即返回,如果沒有獲取鎖,則當(dāng)前線程處于休眠狀態(tài),直到獲得鎖,或者當(dāng)前線程被其他線程中斷(會收到InterruptedException異常)。它與lock()方法最大的區(qū)別在于:如果lock()方法獲取不到鎖,則會一直處于阻塞狀態(tài),且會忽略interrupt()方法。如下例所示:

importjava.util.concurrent.locks.Lock;

importjava.util.concurrent.locks.ReentrantLock;

publicclassTest{

publicstaticvoidmain(String[]args)throwsInterruptedException{

finalLocklock=newReentrantLock();

lock.lock();

Threadt1=newThread(newRunnable(){

publicvoidrun(){

try{

lock.lockInterruptibly();

//lock.lock();編譯器報錯

}catch(InterruptedExceptione){

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

}

}

});

t1.start();

errupt();

Thread.sleep(1);

}

}

程序的運行結(jié)果為:

interrupted.

如果把lock.lockInterruptibly()替換為lock.lock(),編譯器將會提示lock.lock()catch代碼塊無效,因為lock.lock()不會拋出異常,由此可見,lock()方法會忽略interrupt()引發(fā)的異常。)解析:3.

在多線程編程的時候有哪些注意事項?

(分?jǐn)?shù):2.00)__________________________________________________________________________________________

正確答案:(多線程編程是一項非常重要的技能。如何能避免死鎖,如何提高多線程并發(fā)情況下的性能是非常重要的,下面列出一些在多線程編程情況下的指導(dǎo)原則:

1)如果能用volatile代替synchronized,盡可能用volatile。因為被synchronized修飾的方法或代碼塊在同一時間只允許一個線程訪問,而volatile卻沒有這個限制,因此使用synchronized會降低并發(fā)量。由于volatile無法保證原子操作,因此在多線程的情況下,只有對變量的操作為原子操作的情況下才可以使用volatile。

2)盡可能減少synchronized塊內(nèi)的代碼,只把臨界區(qū)的代碼放到synchronized塊中,盡量避免用synchronized來修飾整個方法。

3)盡可能給每個線程都定義一個線程的名字,不要使用匿名線程,這樣有利于調(diào)試。

4)盡可能用concurrent容器(ConcurrentHashMap)來代替synchronized容器(Hashtable)。因為synchronized容器使用synchronized關(guān)鍵字通過對整個容器加鎖來實現(xiàn)多線程安全,性能比較低。而ConcurrentHashMap采用了更加細(xì)粒度的鎖,因此可以支持更高的并發(fā)量。

5)使用線程池來控制多線程的執(zhí)行。)解析:4.

一個文件中有10000個數(shù),用Java語言實現(xiàn)一個多線程程序,將這10000個數(shù)輸出到5個不同文件中(不要求輸出到每個文件中的數(shù)量相同)。要求啟動10個線程,兩兩一組,分為5組。每組兩個線程分別將文件中的奇數(shù)和偶數(shù)輸出到該組對應(yīng)的一個文件中,需要偶數(shù)線程每打印10個偶數(shù)以后,就將奇數(shù)線程打印10個奇數(shù),如此交替進行。同時需要記錄輸出進度,每完成1000個數(shù)就在控制臺中打印當(dāng)前完成數(shù)量,并在所有線程結(jié)束后,在控制臺輸出“Done”。

(分?jǐn)?shù):2.00)__________________________________________________________________________________________

正確答案:(本題考查的是對多線程編程的理解。為了便于理解,首先用隨機函數(shù)隨機生成10000個數(shù)放到文件中,以供測試使用。一次把這10000條記錄讀到內(nèi)存中,平均分配給5組線程并行處理,因此,本題的難點是如何控制打印偶數(shù)的線程和打印奇數(shù)的線程輪流運行。

本題通過Java提供的Condition來實現(xiàn)線程的同步。Condition是在Java1.5中才出現(xiàn)的,它用來替代傳統(tǒng)的Object類的wait()、notify()方法,以實現(xiàn)線程間的協(xié)作,相比使用Object類的wait()、nofify()方法,使用Condition的await()、signal()這種方式實現(xiàn)線程間協(xié)作,更加安全和高效。它主要有如下特點:

1)Condition最常用的方法為await()和signal(),其中,await()對應(yīng)Object類的wait()方法,signal()對應(yīng)Object類的notify()方法。

2)Condition依賴于Lock接口,生成一個Condition的代碼為lock.newCondition()。

3)調(diào)用Condition的await()和signal()方法必須在lock保護之內(nèi)。

對于本題而言,定義兩個Condition(oddLock和evenLock),首先打印奇數(shù)的線程開始運行,通過調(diào)用evenLock.await()來等待打印偶數(shù)的線程執(zhí)行。接著打印偶數(shù)的線程開始運行,當(dāng)輸出10個偶數(shù)或者沒有偶數(shù)輸出后,調(diào)用evenLock.signal()來通知打印奇數(shù)的線程開始運行,然后調(diào)用oddLock.wait方法來等待打印奇數(shù)的線程運行完成。通過這種方法來控制奇數(shù)線程與偶數(shù)線程的運行順序,實現(xiàn)代碼如下:

importjava.io.*;

importjava.util.Random;

importjava.util.concurrent.locks.Condition;

importjava.util.concurrent.locks.Lock;

importjava.util.concurrent.locks.ReentrantLock;

publicclassTest

{

privatestaticfinalintcount=10000;

privatestaticfinalintthreadGruopCount=5;

privatestaticfinalStringinputFile="testInput.txt";

publicstaticvoidgenerateTestFile()throwsIOException

{

//用隨機數(shù)生成10000個測試數(shù)據(jù)放到文件中

PrintWriterpw=newPrintWriter(newFileWriter(newFile(inputFile)),true);

Randomrandom=newRandom();

for(inti=0;i<count;i++)

{

pw.write(Math.abs(random.nextInt())%count+",");

}

pw.flush();

pw.close();

}

publicstaticvoidmain(String[]args)

{

try

{

generateTestFile();

BufferedReaderreader=newBufferedReader(newFileReader(inputFile));

Stringstr=reader.readLine();

reader.close();

String[]strs=str.split(",");

intindex=0;

//為了簡單,每個文件輸出數(shù)字的個數(shù)相同

int

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論