版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
計(jì)算機(jī)類(lèi)面試專(zhuān)業(yè)問(wèn)題
2007-12-1100:01
1、java
因?yàn)槲彝兜穆毼恢饕莏ava相關(guān)的,所以這方面積累的經(jīng)驗(yàn)比較多一下。
這部分考
查的重點(diǎn)主要有:java基本語(yǔ)法,多線程,異常處理,抽象類(lèi),匿名類(lèi),接口,
MVC架構(gòu)
,設(shè)計(jì)模式,Servlet,Struts,Spring,J2EE。以下是我遇見(jiàn)過(guò)的面試問(wèn)題:
1)transient和volatile是java關(guān)鍵字嗎?(瞬聯(lián))
transient:
java有個(gè)特點(diǎn)就是序列化,簡(jiǎn)單地來(lái)說(shuō)就是可以將這個(gè)類(lèi)存儲(chǔ)在物理空間(當(dāng)然還是
以文件的形式存在),那么當(dāng)你從本地還原這個(gè)文件時(shí),你可以將它轉(zhuǎn)換為它本身。這可以
極大地方便網(wǎng)絡(luò)上的一些操作,但同時(shí),因?yàn)樯婕暗桨踩珕?wèn)題,所以并不希望把類(lèi)里面所
有的東西都能存儲(chǔ)(因?yàn)槟菢?,別人可以通過(guò)序列化知道類(lèi)里面的內(nèi)容),那么我們就可
以用上transient這個(gè)關(guān)鍵字,它的意思是臨時(shí)的,即不會(huì)隨類(lèi)一起序列化到本地,所以當(dāng)
還原后,這個(gè)關(guān)健字定義的變量也就不再存在。
volatile:
Volatile修飾的成員變量在每次被線程訪問(wèn)時(shí),都強(qiáng)迫從共享內(nèi)存中重讀該成員變量
的值。而且,當(dāng)成員變量發(fā)生變化時(shí),強(qiáng)迫線程將變化值回寫(xiě)到共享內(nèi)存。這樣在任何時(shí)刻,
兩個(gè)不同的線程總是看到某個(gè)成員變量的同一個(gè)值。
2)抽象類(lèi)和接口有什么區(qū)別?(瞬聯(lián))
1>飛機(jī)會(huì)飛,鳥(niǎo)會(huì)飛,他們都繼承了同一個(gè)接口“飛”;但是F22屬于飛機(jī)抽象類(lèi),鴿子
屬于鳥(niǎo)抽象類(lèi)。
2>就像鐵門(mén)木門(mén)都是門(mén)(抽象類(lèi)),你想要個(gè)門(mén)我給不了(不能實(shí)例化),但我可以給
你個(gè)具體的鐵門(mén)或木門(mén)(多態(tài));而且只能是門(mén),你不能說(shuō)它是窗(單繼承);一個(gè)門(mén)可以
有鎖(接口)也可以有門(mén)鈴(多實(shí)現(xiàn))。門(mén)(抽象類(lèi))定義了你是什么,接口(鎖)規(guī)定了
你能做什么(一個(gè)接口最好只能做一件事,你不能要求鎖也能發(fā)出聲音吧(接口污染))。
抽象類(lèi)和接口有什么區(qū)別?
簡(jiǎn)單來(lái)說(shuō),
接口是公會(huì)的,里面不能有私有的方法或變量,是用于讓別人使用的,而抽象類(lèi)是可以有私
有方法或私有變量的.
另外,實(shí)現(xiàn)接口的-?定要實(shí)現(xiàn)接口里定義的所有方法,而實(shí)現(xiàn)抽象類(lèi)可以有選擇地重寫(xiě)需要
用到的方法,一般的應(yīng)用里,最頂級(jí)的是接口,然后是抽象類(lèi)實(shí)現(xiàn)接口,最后才到具體類(lèi)實(shí)
現(xiàn)。
還有,接口可以實(shí)現(xiàn)多重繼承,而一個(gè)類(lèi)只能繼承一個(gè)超類(lèi),但可以通過(guò)繼承多個(gè)接U實(shí)現(xiàn)
多重繼承,接口還有標(biāo)識(shí)(里面沒(méi)有任何方法,如Remote接口)和數(shù)據(jù)共享(里面的變量
全是常量)的作用.
接口和抽象類(lèi)的區(qū)別,我覺(jué)得主要是兩點(diǎn),一個(gè)是抽象類(lèi)里還可以有非抽象的方法,雖然抽
象類(lèi)仍無(wú)法實(shí)例化,但是其子類(lèi)可以,也就是說(shuō)這些非抽象函數(shù)仍可以被多態(tài)調(diào)用,這也是
抽象類(lèi)為什么沒(méi)有完全被接口取代的原因。接口就是相反了,不過(guò)接口也有一個(gè)優(yōu)勢(shì)是抽象
類(lèi)無(wú)法比擬,就是類(lèi)可以繼承多個(gè)接口,而抽象類(lèi)和普通類(lèi)一樣,只能繼承一個(gè),所以接口
可以解決多重繼承問(wèn)題。
抽象類(lèi)可以只實(shí)現(xiàn)部分方法,接口則必須實(shí)現(xiàn)其全部方法;抽象類(lèi)的方法可以有抽象方法,
也可以有普通方法,接口里的方法必須是抽象方法;抽象類(lèi)的方法的訪問(wèn)權(quán)限可以多種,接
口的方法的訪問(wèn)權(quán)限只能是public;抽象類(lèi)的子類(lèi)只能繼承一個(gè)抽象類(lèi),而實(shí)現(xiàn)接口的類(lèi)
可以同時(shí)實(shí)現(xiàn)多個(gè)接口.
籠統(tǒng)點(diǎn)說(shuō):
接口=定義了要做的所有事情,但自己啥也不干
抽象類(lèi)=做了部分共做,剩下的他不干了,等后來(lái)人繼續(xù)完成
這就是區(qū)別!
抽象類(lèi)的成員可以具有訪問(wèn)級(jí)別,而接口的成員全部public級(jí)別
抽象類(lèi)可以包含字段,而接口不可以,
抽象類(lèi)可以繼承接口,而接口不能繼承抽象類(lèi)
抽象類(lèi)的成員可以具有具體實(shí)現(xiàn),而接口不行
抽象的子類(lèi)可以選擇性實(shí)現(xiàn)其基類(lèi)的抽象方法,而接口的子類(lèi)必須全部實(shí)現(xiàn)
2)能說(shuō)一下java的反射機(jī)制嗎?(瞬聯(lián))
JAVA反射機(jī)制是在運(yùn)行狀態(tài)中,對(duì)于任意一個(gè)類(lèi),都能夠知道這個(gè)類(lèi)的所有屬性和方法;
對(duì)于任意一個(gè)對(duì)象,都能夠調(diào)用它的任意?個(gè)方法:這種動(dòng)態(tài)獲取的信息以及動(dòng)態(tài)調(diào)用對(duì)象
的方法的功能稱(chēng)為java語(yǔ)言的反射機(jī)制。
Java反射機(jī)制主要提供了以卜功能:在運(yùn)行時(shí)判斷任意一個(gè)對(duì)象所屬的類(lèi);在運(yùn)行時(shí)
構(gòu)造任意一個(gè)類(lèi)的對(duì)象;在運(yùn)行時(shí)判斷任意一個(gè)類(lèi)所具有的成員變量和方法;在運(yùn)行時(shí)調(diào)用
任意一個(gè)對(duì)象的方法;生成動(dòng)態(tài)代理。
4)在java中怎樣實(shí)現(xiàn)多線程?(瞬聯(lián))
5)你用過(guò)哪種設(shè)計(jì)模式?(瞬聯(lián),IBM,aspenTech)
6)請(qǐng)說(shuō)一下MVC架構(gòu)(瞬聯(lián),IBM,aspenTech)
7)如果類(lèi)a繼承類(lèi)b,實(shí)現(xiàn)接口c,而類(lèi)b和接口c中定義了同名變量,請(qǐng)問(wèn)會(huì)
出現(xiàn)什么問(wèn)題?(瞬聯(lián))
8)請(qǐng)說(shuō)一下java中為什么要引入內(nèi)部類(lèi)?還有匿名內(nèi)部類(lèi)?(瞬聯(lián),IBM)
9)請(qǐng)說(shuō)一下final,finally和finalize的區(qū)別?(瞬聯(lián))
10)請(qǐng)說(shuō)一下HTTP請(qǐng)示的基本過(guò)程(IBM)
11)java中存在內(nèi)存泄漏問(wèn)題嗎?請(qǐng)舉例說(shuō)明?(IBM)
12)請(qǐng)說(shuō)一下java中的內(nèi)存回收機(jī)制所采用的算法(IBM,瞬聯(lián))
13)請(qǐng)說(shuō)一下System.gc()函數(shù)的作用。什么什么時(shí)候可以調(diào)用垃圾回收器?(瞬
聯(lián))
14)你做過(guò)的項(xiàng)目中采用了什么安全認(rèn)證機(jī)制?(IBM)
15)Math,round。什么作用?
2、C
C語(yǔ)言考查的重點(diǎn)一般是:指針、結(jié)構(gòu)體、條件編譯、全局變量/局部變量。
以下是
我遇見(jiàn)過(guò)的面試問(wèn)題:
1)請(qǐng)說(shuō)一下extemC的作用(漢略)
2)請(qǐng)說(shuō)一下#ifdef...的作用(漢略)
3)C語(yǔ)言里,哪些變量是存放在堆里,哪些是存放在棧里?(普天)
4)C語(yǔ)言里的static關(guān)鍵詞是什么含義?(普天)
5)進(jìn)程和線程有什么區(qū)別?(普天)
3、C++
C++語(yǔ)言考查的重點(diǎn)主要有:多繼承,抽象類(lèi),虛函數(shù),拷貝構(gòu)造函數(shù),析
構(gòu)函數(shù),
動(dòng)態(tài)聯(lián)編,多態(tài),const,static0以下是我面試中遇到的問(wèn)題:
1)你聽(tīng)說(shuō)過(guò)拷貝構(gòu)造函數(shù)嗎?能具體說(shuō)一下它的作用嗎?(漢略)
2)析構(gòu)函數(shù)必須是虛函數(shù)嗎?為什么?(漢略)
3)你聽(tīng)說(shuō)過(guò)鉆石結(jié)構(gòu)嗎?請(qǐng)具體說(shuō)一下(aspenTech)
4)什么是深拷貝?什么是淺拷貝?他們有什么區(qū)別?(aspenTech)
5)什么是虛函數(shù),什么是純虛函數(shù)?為什么引入虛函數(shù)和純虛函數(shù)?(漢略,
aspenTe
ch,普天)
6)請(qǐng)說(shuō)一下面向?qū)ο蟮幕咎匦?。(aspenTech)
7)C++中的const關(guān)鍵定代表什么含義?跟C語(yǔ)言中的const有什么區(qū)別?
(aspenTech)
8)C++中的static關(guān)鍵定代表什么含義?跟C語(yǔ)言、Java中的static有什么
區(qū)別?(普天
)
4、數(shù)據(jù)結(jié)構(gòu)
這是面試中兒乎必考的部分。考查的重點(diǎn)有:鏈表,二叉樹(shù)前序、中序、后
序遍歷
(遞歸,非遞歸),二叉樹(shù)結(jié)點(diǎn)、層次的計(jì)算,樹(shù)轉(zhuǎn)二叉樹(shù),各種排序算法(冒
泡排序
,快速排序,堆排序是重點(diǎn))。以下是我在面試中遇到過(guò)的問(wèn)題:
1)請(qǐng)編寫(xiě)程序,將一個(gè)鏈表倒置。(聯(lián)發(fā))
2)請(qǐng)編寫(xiě)二叉樹(shù)的中序遍歷非遞歸算法。(新華社)
3)請(qǐng)編寫(xiě)一個(gè)程序,實(shí)現(xiàn)將樹(shù)轉(zhuǎn)化成二叉樹(shù)。(華為)
4)一棵滿二叉樹(shù)有x個(gè)結(jié)點(diǎn),請(qǐng)問(wèn)整棵二叉樹(shù)有多少結(jié)點(diǎn)?(新華社,中國(guó)信
保)
5)請(qǐng)編程實(shí)現(xiàn)一個(gè)堆排序算法/快速排序算法。(漢略)
5、數(shù)據(jù)庫(kù)
這也是面試重點(diǎn)內(nèi)容。主要考查點(diǎn)有:范式,1、2、3范式,事務(wù),內(nèi)連接,
外連接
,關(guān)系代數(shù),數(shù)據(jù)庫(kù)設(shè)計(jì)。以下是我遇到過(guò)的面試問(wèn)題:
1)什么是范式、1范式、2范式、3范式?(百度,中航信,新華社,中國(guó)信保)
2)事務(wù)具有哪些特性?(中航信)
3)請(qǐng)說(shuō)說(shuō)什么是外連接、左外連接、右外連接?(aspenTech)
4)請(qǐng)說(shuō)說(shuō)關(guān)系代表中的兒種基本運(yùn)算?(中航信)
5)請(qǐng)對(duì)一個(gè)論壇進(jìn)行數(shù)據(jù)庫(kù)設(shè)計(jì),并說(shuō)說(shuō)你設(shè)計(jì)的數(shù)據(jù)庫(kù)滿足哪個(gè)范式(百度)
6)給你一個(gè)數(shù)據(jù)庫(kù)需求,請(qǐng)對(duì)數(shù)據(jù)庫(kù)進(jìn)行設(shè)計(jì),并根據(jù)要求寫(xiě)出查詢語(yǔ)句(中
國(guó)信保)
6、網(wǎng)絡(luò)
這也是??嫉牟糠帧V饕疾辄c(diǎn)有:OSI參考模型,TCP/IP參考模型。以下
是我遇到
過(guò)的具體面試問(wèn)題:
1)請(qǐng)解釋一下OSI參考模型。(中國(guó)信保)
2)請(qǐng)解釋一下TCP/IP參考模型。(中國(guó)信保)
3)為什么現(xiàn)在的網(wǎng)絡(luò)最后采用了TCP/IP參考模型而沒(méi)用0SI參考模型?(中國(guó)
信保)
Java
1)transient和volatile是java關(guān)鍵字嗎
不常用到的關(guān)鍵字有:const,goto,native,strictfp,transient,volatile0
const和goto為java中的保留字。
1.native
native是方法修飾符。Native方法是由另外一種語(yǔ)言(如c/c++,FORTRAN,匯編)實(shí)現(xiàn)的
本地方法。因?yàn)樵谕獠繉?shí)現(xiàn)了方法,所以在java代碼中,就不需要聲明了,有點(diǎn)類(lèi)似于借
口方法。Native可以和其他一些修飾符連用,但是abstract方法和Interface方法不能用native
來(lái)修飾。
Example:代碼
publicinterfaceTestinterface{
voiddoMethod();
}
publicclassTestimplementsTestinterface{
publicnativevoiddoMethod();
privatenativeintdoMethodB();
publicnativesynchronizedStringdoMcthodC();
staticnativevoiddoMethodD();
)
render_code();
為什么需要使用nativemethod?請(qǐng)參考:
/topic/72543javaNativeMethod初涉
2.strictfp
修飾類(lèi)和方法,意思是FP-strict,精確浮點(diǎn),符合IEEE-754規(guī)范的。當(dāng)一個(gè)class或interface
用strictfp聲明,內(nèi)部所有的float和double表達(dá)式都會(huì)成為strictfp的。Interfacemethod不
能被聲明為strictfp的,class的可以。
Example:
代碼
strictfpinterfaceFPTest{
voidmethodA();
}
classFPClassimplementsFPTest{
publicvoidmethodA(){
publicvoidmcthodB(){
}
publicstrictfpvoidmethodC(){
}
}
classFPClassB{
strictfpvoidmethodA(){
}
}
render_code();
3.transient
變量修飾符。標(biāo)記為transient的變量,在對(duì)象存儲(chǔ)時(shí),這些變量狀態(tài)不會(huì)被持久化。當(dāng)對(duì)象
序列化的保存在存儲(chǔ)器上時(shí),不希望有些字段數(shù)據(jù)被保存,為了保證安全性,可以把這些字
段聲明為transiento
4.volatile
volatile修飾變量。在每次被線程訪問(wèn)時(shí),都強(qiáng)迫從共享內(nèi)存中重讀該成員變量的值。而且,
當(dāng)成員變量發(fā)生變化時(shí),強(qiáng)迫線程將變化值回寫(xiě)到共享內(nèi)存。這樣在任何時(shí)刻,兩個(gè)不同的
線程總是看到某個(gè)成員變量的同一個(gè)值。
看看JavaLanguageSpecification中的例子。
條件:一個(gè)線程不停的調(diào)用方法。ne(),一個(gè)線程不停的調(diào)用方法two()。我測(cè)試過(guò)多次,這
種情況好像一直沒(méi)有現(xiàn)。
抽象類(lèi)和接口有什么區(qū)別?(瞬聯(lián))
聲明方法的存在而不去實(shí)現(xiàn)它的類(lèi)被叫做抽象類(lèi)(abstractclass),它用于要?jiǎng)?chuàng)建一個(gè)體現(xiàn)某
些基本行為的類(lèi),并為該類(lèi)聲明方法,但不能在該類(lèi)中實(shí)現(xiàn)該類(lèi)的情況。不能創(chuàng)建abstract類(lèi)
的實(shí)例。然而可以創(chuàng)建一個(gè)變量,其類(lèi)型是一個(gè)抽象類(lèi),并讓它指向具體子類(lèi)的一個(gè)實(shí)例。
不能有抽象構(gòu)造函數(shù)或抽象靜態(tài)方法。Abstract類(lèi)的子類(lèi)為它們父類(lèi)中的所有抽象方法提供
實(shí)現(xiàn),否則它們也是抽象類(lèi)為。取而代之,在子類(lèi)中實(shí)現(xiàn)該方法。知道其行為的其它類(lèi)可以
在類(lèi)中實(shí)現(xiàn)這些方法。
接口(interface)是抽象類(lèi)的變體。在接口中,所有方法都是抽象的。多繼承性可通過(guò)
實(shí)現(xiàn)這樣的接口而獲得。接口中的所有方法都是抽象的,沒(méi)有一個(gè)有程序體。接口只可以定
義staticfinal成員變量。接口的實(shí)現(xiàn)與子類(lèi)相似,除了該實(shí)現(xiàn)類(lèi)不能從接口定義中繼承行為。
當(dāng)類(lèi)實(shí)現(xiàn)特殊接口時(shí),它定義(即將程序體給予)所有這種接U的方法。然后,它可以在實(shí)
現(xiàn)了該接口的類(lèi)的任何對(duì)象卜.調(diào)用接口的方法。由于有抽象類(lèi),它允許使用接口名作為引用
變量的類(lèi)型。通常的動(dòng)態(tài)聯(lián)編將生效。引用可以轉(zhuǎn)換到接口類(lèi)型或從接口類(lèi)型轉(zhuǎn)換,
instanceof運(yùn)算符可以用來(lái)決定某對(duì)象的類(lèi)是否實(shí)現(xiàn)了接口。
3)能說(shuō)一下java的反射機(jī)制嗎?(瞬聯(lián))
JAVA反射機(jī)制是在運(yùn)行狀態(tài)中,對(duì)于任意一個(gè)類(lèi),都能夠知道這個(gè)類(lèi)的所有屬性和方法;
對(duì)于任意一個(gè)對(duì)象,都能夠調(diào)用它的任意一個(gè)方法;這種動(dòng)態(tài)獲取的信息以及動(dòng)態(tài)調(diào)用對(duì)象
的方法的功能稱(chēng)為java語(yǔ)言的反射機(jī)制。
Java反射機(jī)制主要提供了以下功能:在運(yùn)行時(shí)判斷任意一個(gè)對(duì)象所屬的類(lèi);在運(yùn)行時(shí)構(gòu)造
任意一個(gè)類(lèi)的對(duì)象;在運(yùn)行時(shí)判斷任意一個(gè)類(lèi)所具有的成員變量和方法;在運(yùn)行時(shí)調(diào)用任意
一個(gè)對(duì)象的方法;生成動(dòng)態(tài)代理。
1.得到某個(gè)對(duì)象的屬性
1publicObjectgetProperty(Objectowner,StringfieldName)throwsException{
2ClassownerClass=owner.getClass();
3
4Fieldfield=ownerClass.getField(fieldName);
5
6Objectproperty=field.get(owner);
7
8returnproperty;
9)
ClassownerClass=owner.getClass():得到該對(duì)象的Classo
Fieldfield=ownerClass.getField(fieldName):通過(guò)Class得到類(lèi)聲明的屬性。
Objectproperty=field.get(owner):通過(guò)對(duì)象得到該屬性的實(shí)例,如果這個(gè)屬性是非公有的,
這里會(huì)報(bào)HlegalAccessException。
2.得到某個(gè)類(lèi)的靜態(tài)屬性
1publicObjectgetStaticProperty(StringclassName,StringfieldName)
2throwsException{
3ClassownerClass=Class.forName(className);
4
5Fieldfield=ownerClass.getField(fieldName);
6
7Objectproperty=field.get(ownerClass);
8
9returnproperty;
10)
ClassownerClass=Class.fbrName(className):首先得到這個(gè)類(lèi)的Classo
Fieldfield=ownerClass.getField(fieldName):和上面一樣,通過(guò)Class得到類(lèi)聲明的屬性。
Objectproperty=field.get(ownerClass):這里和上面有些不同,因?yàn)樵搶傩允庆o態(tài)的,所以
直接從類(lèi)的Class里取。
3.執(zhí)行某對(duì)象的方法
1publicObjectinvokeMethod(Objectowner,StringmethodName,Object[]args)throwsExcepti
on{
2
3ClassownerClass=owner.getClass();
4
5Classf]argsClass=newClass[args.length];
6
7for(inti=0,j=args.length;i<j;i-H-){
8argsClass[i]=args[i].getClass();
9}
10
11Methodmethod=ownerClass.getMethod(methodName,argsClass);
12
13returnmethod.invoke(owner,args);
14)
Classownerclass=owner.getClass():首先還是必須得到這個(gè)對(duì)象的Class0
5?9行:配置參數(shù)的Class數(shù)組,作為尋找Method的條件。
Methodmethod=ownerClass.getMethod(methodName,argsClass):通過(guò)Method名和參數(shù)的
Class數(shù)組得到要執(zhí)行的Methodo
method.invoke(owner,args):執(zhí)行該Method,invoke方法的參數(shù)是執(zhí)行這個(gè)方法的對(duì)象,和
參數(shù)數(shù)組。返回值是Object,也既是該方法的返回值。
4.執(zhí)行某個(gè)類(lèi)的靜態(tài)方法
1publicObjectinvokeStaticMethod(StringclassName,StringmethodName,
2Object[]args)throwsException{
3ClassownerClass=Class.fbrName(className);
4
5Classf]argsClass=newClass[args.length];
6
7for(inti=0,j=args.length;i<j;i-H-){
8argsClass[i]=args[i].getClass();
9)
10
11Methodmethod=ownerClass.getMethod(methodName,argsClass);
12
13returnmethod.invoke(null,args);
14}
基本的原理和實(shí)例3相同,不同點(diǎn)是最后一行,invoke的一個(gè)參數(shù)是null,因?yàn)檫@是靜態(tài)方
法,不需要借助實(shí)例運(yùn)行。
5.新建實(shí)例
1
2publicObjectnewInstance(StringclassName,Object[]args)throwsException{
3ClassnewoneClass=Class.fbrName(className);
4
5Class[]argsClass=newClass[args.length];
6
7for(inti=0,j=args.length;i<j;i++){
8argsClass[i]=args[i].getClass();
9}
10
11Constructorcons=newoneClass.getConstructor(argsClass);
12
13returncons.newlnstance(args);
14
15)
這里說(shuō)的方法是執(zhí)行帶參數(shù)的構(gòu)造函數(shù)來(lái)新建實(shí)例的方法。如果不需要參數(shù),可以直接使用
newoneClass.newInstance()來(lái)實(shí)現(xiàn)。
ClassnewoneClass=Class.fbrName(className):第一步,得到要構(gòu)造的實(shí)例的Classo
第5?第9行:得到參數(shù)的Class數(shù)組。
Constructorcons=newoneClass.getConstructor(argsClass):得到構(gòu)造子。
cons.newlnstance(args):新建實(shí)例。
6.判斷是否為某個(gè)類(lèi)的實(shí)例
1publicbooleanisInstance(Objectobj,Classcis){
2returncls.islnstance(obj);
3)
7.得到數(shù)組中的某個(gè)元素
1publicObjectgetByArray(Objectarray,intindex){
2returnArray.get(array,index);
3)
4)在java中怎樣實(shí)現(xiàn)多線程?(瞬聯(lián))
與其他語(yǔ)言不一樣的是,線程的觀念在java是語(yǔ)言中是重要的,根深蒂固的,因?yàn)樵趈ava
語(yǔ)言中的線程系統(tǒng)是java語(yǔ)言自建的,java中有專(zhuān)門(mén)的支持多線程的API庫(kù),所以你可以
以最快的速度寫(xiě)一個(gè)支持線程的程序。在使用java創(chuàng)建線程的時(shí)候,你可以生成一個(gè)Thread
類(lèi)或者他的子類(lèi)對(duì)象,并給這個(gè)對(duì)象發(fā)送start。消息(程序可以向任何個(gè)派生自Runnable
接口的類(lèi)對(duì)象發(fā)送start()消息的),這樣一來(lái)程序會(huì)一直執(zhí)行,直到run返回為止,此時(shí)該
線程就死掉了。
在java語(yǔ)言中,線程有如下特點(diǎn):
§在一個(gè)程序中而言,主線程的執(zhí)行位置就是main。而其他線程執(zhí)行的位置,程序員
是可以自定義的。值得注意的是對(duì)Applet也是一樣。
§每個(gè)線程執(zhí)行其代碼的方式都是一次順序執(zhí)行的。
§一個(gè)線程執(zhí)行其代碼是與其他線程獨(dú)立開(kāi)來(lái)的。如果諸線程之間又相互協(xié)作的話,就
必須采用一定的交互機(jī)制。
§前面已經(jīng)說(shuō)過(guò),線程是共享地址空間的,如果控制不當(dāng),這里很有可能出現(xiàn)死鎖。
各線程之間是相互獨(dú)立的,那么本地變量對(duì)一個(gè)線程而言就是完全獨(dú)立,私有的。所以
呢,線程執(zhí)行時(shí),每個(gè)線程都有各自的本地變量拷貝。對(duì)象變量(instancevariable)在線程之
間是可以共享的,這也就是為什么在java中共享數(shù)據(jù)對(duì)象是如此的好用,但是java線程不
能夠武斷地訪問(wèn)對(duì)象變量:他們是需要訪問(wèn)數(shù)據(jù)對(duì)象的權(quán)限的。
二、準(zhǔn)備知識(shí)
在分析這個(gè)例子之前,然我們先看看關(guān)于線程的幾個(gè)概念,上鎖,信號(hào)量,和java所
提供的API。
上鎖
對(duì)于大多數(shù)的程序而言,他們都需要線程之間相互的通訊來(lái)完成整個(gè)線程的生命周期,
二實(shí)現(xiàn)線程之間同步的最簡(jiǎn)單的辦法就是上鎖。為了防止相互關(guān)聯(lián)的兩個(gè)線程之間錯(cuò)誤地訪
間共享資源,線程需要在訪問(wèn)資源的時(shí)候上鎖和解鎖,對(duì)于鎖而言,有讀鎖,寫(xiě)鎖和讀寫(xiě)鎖
等不同的同步策略。在java中,所有的對(duì)象都有鎖:線程只需要使用synchronized關(guān)鍵字就
可以獲得鎖。在任時(shí)刻對(duì)于給定的類(lèi)的實(shí)例,方法或同步的代碼塊只能被一個(gè)線程執(zhí)行。
這是因?yàn)榇a在執(zhí)行之前要求獲得對(duì)象的鎖。
/士旦啟-
1萬(wàn)節(jié)里
通常情況下,多個(gè)線程所訪問(wèn)為數(shù)不多的資源,那怎么控制呢?一個(gè)比較非常經(jīng)典而起
非常簡(jiǎn)單的辦法就是采用信號(hào)量機(jī)制。信號(hào)量機(jī)制的含義就是定義一個(gè)信號(hào)量,也就是說(shuō)能
夠提供的連接數(shù);當(dāng)有一個(gè)線程占用了一個(gè)連接時(shí),信號(hào)量就減一;當(dāng)一個(gè)線程是放了連接
時(shí),信號(hào)量就加一。采用這種方法就可以簡(jiǎn)單有效地控制線程的同步問(wèn)題,而且實(shí)現(xiàn)起來(lái)也
特別方便。看下面的代碼:
classSemaphore{
privateintcount;
publicSemaphore(intcount){
this.count=count;
}
publicsynchronizedvoidacquire(){
while(count==0){
trycatch(InterruptedExceptione){
//keeptrying
}
count—;
}
publicsynchronizedvoidrelease(){
count++;
notify();//alertathreadthat'sblockingonthissemaphore
}
)
java中提供了哪些api以編寫(xiě)多線程程序
這里只列出幾個(gè)常用的方法和屬性值。
屬性值,有三個(gè)MAX_PRIORITY,MINPRIORITY,NORMPRIORITY
方法:
Thread。;〃建立一個(gè)線程
voidrun();〃對(duì)于--個(gè)繼承了Runnable接口的class而言,
〃他運(yùn)行一個(gè)線程,否著他什么都不做
voidsctPriority(intnewPriority);//設(shè)置優(yōu)先級(jí)
voidstart。;//運(yùn)行一個(gè)程序
voidsleep(longmillis);〃線程睡眠millis毫秒
staticvoidyield。;//臨時(shí)pause一個(gè)程序以便起他線程運(yùn)行
:程序示例
例一、
讓我們看看下面的例子。取錢(qián)的流程是輸入密碼,然后確定要取得金額,如果所取的金
額小于或等于可以取出的金額,WITHDRAW則返回TRUE,然后ATM機(jī)出錢(qián),然后打印
清單;否則返回FALSE,然后打印清單。如下圖:
publicclassAutomatedTellerMachineextendsTeller{
publicvoidwithdraw(floatamount){
Accounta=getAccount();
if(a.deduct(amount))
dispense(amount);
printReceipt();
)
publicclassAccount{
privatefloattotal;
publicbooleandeduct(floatt){
if(t<=total){
total-=t;
returntrue;
)
returnfalse;
)
}
就這個(gè)例子而言,假設(shè)有這種情況,對(duì)同一個(gè)賬號(hào)可以在不同的地方取錢(qián),在同一時(shí)間,
不同地點(diǎn),妻子和丈夫取錢(qián),妻子輸入了賬號(hào)上的最大金額,丈夫也是一樣,假如妻子輸入
后已經(jīng)得到true的返回值,但是丈夫的線程所得到的值還沒(méi)有更新,這樣丈夫也能夠得到
true的返回值,這樣就出現(xiàn)了問(wèn)題!這個(gè)問(wèn)題怎么解決呢?在java里面提供了控制機(jī)制以保
證deduct操作時(shí)的原子性,那就是關(guān)鍵字synchronizedo
在Account的deduct方法加入synchronized就可以解決這個(gè)問(wèn)題。
例二、
在這里我們用多線程中最典型的例子,生產(chǎn)者與消費(fèi)者問(wèn)題。在這個(gè)例子里面我們定義
了生產(chǎn)者Producer,消費(fèi)者Consumer和倉(cāng)庫(kù)Warehouse?:個(gè)類(lèi),在整個(gè)程序的生命周期里,
生產(chǎn)者隨機(jī)地制造出產(chǎn)品放到倉(cāng)庫(kù)中,消費(fèi)者也是隨即地從倉(cāng)庫(kù)中取出產(chǎn)品。
importexception.ProducerConsumerException;
*Consumer.java
*Consumer
*By:Jiabo
*Date:Mar21,2004
*Time:2:47:58PM
*/
publicclassConsumerextendsThread{
privateWarehousewarehouse;
privateStringid;
publicConsumer(Warehousewarehouse,Stringid){
this.warehouse=warehouse;
this.id=id;
}
publicvoidrun(){
inttmp=(int)Math.random()*10;
try(
warehouse.get(tmp);
System.out.println(nConsumer#"+this.id+”get"+tmp);
}catch(ProducerConsumerExceptione)
try(
sleep((int)(Math.random()*100));
}catch(InterruptedExceptione)
)
}
在這個(gè)類(lèi)中,值得注意的?點(diǎn)是run方法中必須使用try-catch,因?yàn)?,消費(fèi)者從倉(cāng)庫(kù)中
取東西時(shí)有可能諸如倉(cāng)庫(kù)中的儲(chǔ)量不夠得異常,在消費(fèi)者里面也是一樣,只不過(guò)異常變?yōu)閭}(cāng)
庫(kù)已滿。
importexception.*;
/**
*Producer.]ava
*Producer
*By:Jiabo
*Date:Mar21,2004
*Time:2:47:45PM
*/
publicclassProducerextendsThread{
privateWarehousewarehouse;
privateStringid;
publicProducer(Warehousewarehouse,Stringid){
this.warehouse=warehouse;
this.id=id;
}
publicvoidrun(){
inttmp=(int)Math.random()*10;
if(tmp!=0){
try{
warehouse.put(tmp);
System.out.println(,,Consumer#"+this.id+“put"+tmp);
}catch(ProducerConsumerExceptione)
)
try{
sleep((int)(Math.random()*100));
}catch(InterruptedExceptione)
最重要的一部分在Warehouse類(lèi),如上所說(shuō)為了保證get何set的原子性,在這里使用了synchronized關(guān)鍵字,
并且在操作時(shí)拋出了可能跑出的異常。
5)你用過(guò)哪種設(shè)計(jì)模式?(瞬聯(lián),舊M,aspenTech)
MVC模式,靜態(tài)工廠模式,適配器模式,門(mén)面模式,DAO模式,單例模式,Template模式.
command模式
在網(wǎng)上看見(jiàn)了這篇文章,作者以輕松的語(yǔ)言比喻了java的23種模式,有很好的啟發(fā)作用。
創(chuàng)建型模式
1、FACTORY—追MM少不了請(qǐng)吃飯了,麥當(dāng)勞的雞翅和肯德基的雞翅都是MM愛(ài)吃的東
西,雖然口味有所不同,但不管你帶MM去麥當(dāng)勞或肯德基,只管向服務(wù)員說(shuō)“來(lái)四個(gè)雞翅”就
行了。麥當(dāng)勞和肯德基就是生產(chǎn)雞翅的Factory
工廠模式:客戶類(lèi)和工廠類(lèi)分開(kāi)。消費(fèi)者任何時(shí)候需要某種產(chǎn)品,只需向工廠請(qǐng)求即可。消
費(fèi)者無(wú)須修改就可以接納新產(chǎn)品。缺點(diǎn)是當(dāng)產(chǎn)品修改時(shí),工廠類(lèi)也要做相應(yīng)的修改。如:如何創(chuàng)
建及如何向客戶端提供。
2、BUILDER—MM最?lèi)?ài)聽(tīng)的就是“我愛(ài)你”這句話了,見(jiàn)到不同地方的MM,要能夠用她們
的方言跟她說(shuō)這句話哦,我有一個(gè)多種語(yǔ)言翻譯機(jī),上面每種語(yǔ)言都有一個(gè)按鍵,見(jiàn)到MM我
只要按對(duì)應(yīng)的鍵,它就能夠用相應(yīng)的語(yǔ)言說(shuō)出“我愛(ài)你”這句話了,國(guó)外的MM也可以輕松搞掂,
這就是我的“我愛(ài)你"builder,(這一定比美軍在伊拉克用的翻譯機(jī)好賣(mài))
建造模式:將產(chǎn)品的內(nèi)部表象和產(chǎn)品的生成過(guò)程分割開(kāi)來(lái),從而使一個(gè)建造過(guò)程生成具有不
同的內(nèi)部表象的產(chǎn)品對(duì)象。建造模式使得產(chǎn)品內(nèi)部表象可以獨(dú)立的變化,客戶不必知道產(chǎn)品內(nèi)部
組成的細(xì)節(jié)。建造模式可以強(qiáng)制實(shí)行一種分步驟進(jìn)行的建造過(guò)程。
3、FACTORYMETHOD—請(qǐng)MM去麥當(dāng)勞吃漢堡,不同的MM有不同的口味,要每個(gè)都
記住是一件煩人的事情,我一般采用FactoryMethod模式,帶著MM到服務(wù)員那兒,說(shuō)“要?
個(gè)漢堡”,具體要什么樣的漢堡呢,讓MM直接跟服務(wù)員說(shuō)就行了。
工廠方法模式:核心工廠類(lèi)不再負(fù)責(zé)所有產(chǎn)品的創(chuàng)建,而是將具體創(chuàng)建的工作交給子類(lèi)去做,
成為一個(gè)抽象工廠角色,僅負(fù)責(zé)給出具體工廠類(lèi)必須實(shí)現(xiàn)的接口,而不接觸哪一個(gè)產(chǎn)品類(lèi)應(yīng)當(dāng)被
實(shí)例化這種細(xì)節(jié)。
4、PROTOTYPE一跟MM用QQ聊天,一定要說(shuō)些深情的話語(yǔ)了,我搜集了好多肉麻的情
話,需要時(shí)只要copy出來(lái)放到QQ里面就行了,這就是我的情話prototype了。(100塊錢(qián)-
份,你要不要)
原始模型模式:通過(guò)給出一個(gè)原型對(duì)象來(lái)指明所要?jiǎng)?chuàng)建的對(duì)象的類(lèi)型,然后用復(fù)制這個(gè)原型
對(duì)象的方法創(chuàng)建出更多同類(lèi)型的對(duì)象。原始模型模式允許動(dòng)態(tài)的增加或減少產(chǎn)品類(lèi),產(chǎn)品類(lèi)不需
要非得有任何事先確定的等級(jí)結(jié)構(gòu),原始模型模式適用于任何的等級(jí)結(jié)構(gòu)。缺點(diǎn)是每一個(gè)類(lèi)都必
須配備一個(gè)克隆方法。
5、SINGLETON—俺有6個(gè)漂亮的老婆,她們的老公都是我,我就是我們家里的老公
Sigleton,她們只要說(shuō)道“老公”,都是指的同一個(gè)人,那就是我(剛才做了個(gè)夢(mèng)啦,哪有這么好
的事)
單例模式:?jiǎn)卫J酱_保某一個(gè)類(lèi)只有一個(gè)實(shí)例,而且自行實(shí)例化并向整個(gè)系統(tǒng)提供這個(gè)實(shí)
例單例模式。單例模式只應(yīng)在有真正的“單一實(shí)例”的需求時(shí)才可使用。
結(jié)構(gòu)型模式
6、ADAPTER—在朋友聚會(huì)上碰到了一個(gè)美女Sarah,從香港來(lái)的,可我不會(huì)說(shuō)粵語(yǔ),她
不會(huì)說(shuō)普通話,只好求助于我的朋友kent了,他作為我和Sarah之間的Adapter,讓我和Sarah
可以相互交談了(也不知道他會(huì)不會(huì)耍我)
適配器(變木器)模式:把一個(gè)類(lèi)的接口變換成客戶端所期待的另一種接口,從而使原本因
接口原因不匹配而無(wú)法一起工作的兩個(gè)類(lèi)能夠一起工作。適配類(lèi)可以根據(jù)參數(shù)返還一個(gè)合適的實(shí)
例給客戶端。
7、BRIDGE—早上碰到MM,要說(shuō)早上好,晚上碰到MM,要說(shuō)晚上好;碰到MM穿了件
新衣服,要說(shuō)你的衣服好漂亮哦,碰到MM新做的發(fā)型,要說(shuō)你的頭發(fā)好漂亮哦。不要問(wèn)我“早
上碰到MM新做了個(gè)發(fā)型怎么說(shuō)”這種問(wèn)題,自己用BRIDGE組合一下不就行了
橋梁模式:將抽象化與實(shí)現(xiàn)化脫耦,使得二者可以獨(dú)立的變化,也就是說(shuō)將他們之間的強(qiáng)關(guān)
聯(lián)變成弱關(guān)聯(lián),也就是指在一個(gè)軟件系統(tǒng)的抽象化和實(shí)現(xiàn)化之間使用組合/聚合關(guān)系而不是繼承
關(guān)系,從而使兩者可以獨(dú)立的變化。
8、COMPOSITE—Mary今天過(guò)生日?!拔疫^(guò)生日,你要送我?件禮物?!薄班牛冒?,去商
店,你自己挑?!薄斑@件T恤挺漂亮,買(mǎi),這條裙子好看,買(mǎi),這個(gè)包也不錯(cuò),買(mǎi)。”“喂,買(mǎi)了三
件了呀,我只答應(yīng)送一件禮物的哦。”“什么呀,T恤加裙子加包包,正好配成一套呀,小姐,麻
煩你包起來(lái)。":',MM都會(huì)用Composite模式了,你會(huì)了沒(méi)有?
合成模式:合成模式將對(duì)象組織到樹(shù)結(jié)構(gòu)中,可以用來(lái)描述整體與部分的關(guān)系。合成模式就
是一個(gè)處理對(duì)象的樹(shù)結(jié)構(gòu)的模式。合成模式把部分與整體的關(guān)系用樹(shù)結(jié)構(gòu)表示出來(lái)。合成模式使
得客戶端把一個(gè)個(gè)單獨(dú)的成分對(duì)象和由他們復(fù)合而成的合成對(duì)象同等看待。
9、DECORATOR—Mary過(guò)完輪到Sarly過(guò)生日,還是不要叫她自己挑了,不然這個(gè)月伙
食費(fèi)肯定玩完,拿出我去年在華山頂上照的照片,在背面寫(xiě)上“最好的的禮物,就是愛(ài)你的Fita",
再到街上禮品店買(mǎi)了個(gè)像框(賣(mài)禮品的MM也很漂亮哦),再找隔壁搞美術(shù)設(shè)計(jì)的Mike設(shè)計(jì)了
一個(gè)漂亮的盒子裝起來(lái)……,我們都是Decorator,最終都在修飾我這個(gè)人呀,怎么樣,看懂了
嗎?
裝飾模式:裝飾模式以對(duì)客戶端透明的方式擴(kuò)展對(duì)象的功能,是繼承關(guān)系的一個(gè)替代方案,
提供比繼承更多的靈活性。動(dòng)態(tài)給一個(gè)對(duì)象增加功能,這些功能可以再動(dòng)態(tài)的撤消。增加由一些
基本功能的排列組合而產(chǎn)生的非常大量的功能。
10、FACADE—我有一個(gè)專(zhuān)業(yè)的Nikon相機(jī),我就喜歡自己手動(dòng)調(diào)光圈、快門(mén),這樣照出
來(lái)的照片才專(zhuān)業(yè),但MM可不懂這些,教了半天也不會(huì)。幸好相機(jī)有Facade設(shè)計(jì)模式,把相
機(jī)調(diào)整到自動(dòng)檔,只要對(duì)準(zhǔn)目標(biāo)按快門(mén)就行了,一切由相機(jī)自動(dòng)調(diào)整,這樣MM也可以用這個(gè)
相機(jī)給我拍張照片了。
門(mén)面模式:外部與一個(gè)子系統(tǒng)的通信必須通過(guò)一個(gè)統(tǒng)一的門(mén)面對(duì)象進(jìn)行。門(mén)面模式提供一個(gè)
高層次的接口,使得子系統(tǒng)更易于使用。每一個(gè)子系統(tǒng)只有一個(gè)門(mén)面類(lèi),而且此門(mén)面類(lèi)只有一個(gè)
實(shí)例,也就是說(shuō)它是個(gè)單例模式。但整個(gè)系統(tǒng)可以有多個(gè)門(mén)面類(lèi)。
11、FLYW日GHJ每天跟MM發(fā)短信,手指都累死了,最近買(mǎi)了個(gè)新手機(jī),可以把一些
常用的句子存在手機(jī)里,要用的時(shí)候,直接拿出來(lái),在前面加上MM的名字就可以發(fā)送了,冉
不用一個(gè)字一個(gè)字敲了。共享的句子就是Flyweight,MM的名字就是提取出來(lái)的外部特征,根
據(jù)上下文情況使用。
享元模式:FLYW曰GHT在拳擊比賽中指最輕量級(jí)。享元模式以共享的方式高效的支持大
量的細(xì)粒度對(duì)象。享元模式能做到共享的關(guān)鍵是區(qū)分內(nèi)蘊(yùn)狀態(tài)和外蘊(yùn)狀態(tài)。內(nèi)蘊(yùn)狀態(tài)存儲(chǔ)在享元
內(nèi)部,不會(huì)隨環(huán)境的改變而有所不同。外蘊(yùn)狀態(tài)是隨環(huán)境的改變而改變的。外蘊(yùn)狀態(tài)不能影響內(nèi)
蘊(yùn)狀態(tài),它們是相互獨(dú)立的。將可以共享的狀態(tài)和不可以共享的狀態(tài)從常規(guī)類(lèi)中區(qū)分開(kāi)來(lái),將不
可以共享的狀態(tài)從類(lèi)里剔除出去??蛻舳瞬豢梢灾苯觿?chuàng)建被共享的對(duì)象,而應(yīng)當(dāng)使用一個(gè)工廠對(duì)
象負(fù)責(zé)創(chuàng)建被共享的對(duì)象。享元模式大幅度的降低內(nèi)存中對(duì)象的數(shù)量。
6)請(qǐng)說(shuō)一下MVC架構(gòu)(瞬聯(lián),IBM,aspenTech)
MVC指的是Model,View,Controller嘀罩來(lái)-Model是負(fù)責(zé)資料眉,:ft責(zé)輿資料需1接:View
是負(fù)責(zé)資料的呈垣方式,可以是^真,統(tǒng)吉十1園等;Controller是^^系統(tǒng)的流程及決定如何呈現(xiàn)
資料
1解釋■/article/52/52575.shtm
模型一視圖一控制器(MVC)是XeroxPARC在八十年代為編程語(yǔ)言Smalltalk-80發(fā)明的一種軟件
設(shè)計(jì)模式,至今已被廣泛使用。最近幾年被推薦為Sun公司J2EE平臺(tái)的設(shè)計(jì)模式,并且受到越來(lái)越多的
使用ColdFusion和PHP的開(kāi)發(fā)者的歡迎。模型一視圖一控制器模式是一個(gè)有用的工具箱,它有很多好
處,但也有一些缺點(diǎn)。
MVC如何工作
MVC是一個(gè)設(shè)計(jì)模式,它強(qiáng)制性的使應(yīng)用程序的輸入、處理和輸出分開(kāi)。使用MVC應(yīng)用程序被分成:個(gè)
核心部件:模型、視圖、控制器.它們各自處理自己的任務(wù)。
視圖
視圖是用戶看到并與之交互的界面。對(duì)老式的Web應(yīng)用程序來(lái)說(shuō),視圖就是由HTML元素組成的界面,
在新式的Web應(yīng)用程序中,HTML依舊在視圖中扮演著重要的角色,但?些新的技術(shù)已層出不窮,它們
包括MacromediaFlash和象XHTML,XML/XSL,WML等一些標(biāo)識(shí)語(yǔ)言和Webservices.
如何處理應(yīng)用程序的界面變得越來(lái)越有挑戰(zhàn)性。MVC一個(gè)大的好處是它能為你的應(yīng)用程序處理很多不同的
視圖。在視圖中其實(shí)沒(méi)有真正的處理發(fā)生,不管這些數(shù)據(jù)是聯(lián)機(jī)存儲(chǔ)的還是一個(gè)雇員列表,作為視圖來(lái)講,
它只是作為一種輸出數(shù)據(jù)并允許用戶操縱的方式。
模型
模型表示企業(yè)數(shù)據(jù)和業(yè)務(wù)規(guī)則。在MVC的三個(gè)部件中,模型擁有最多的處理任務(wù)。例如它可能用象EJBs
和ColdFusionComponents這樣的構(gòu)件對(duì)象來(lái)處理數(shù)據(jù)庫(kù)。被模型返回的數(shù)據(jù)是中立的,就是說(shuō)模型
與數(shù)據(jù)格式無(wú)關(guān),這樣一個(gè)模型能為多個(gè)視圖提供數(shù)據(jù)。由于應(yīng)用于模型的代碼只需寫(xiě)一次就可以被多個(gè)
視圖重用,所以減少了代碼的重復(fù)性。
控制器
控制器接受用戶的輸入并調(diào)用模型和視圖去完成用戶的需求。所以當(dāng)單擊Web頁(yè)面中的超鏈接和發(fā)送
HTML表單時(shí),控制器本身不輸出任何東西和做任何處理。它只是接收請(qǐng)求并決定調(diào)用哪個(gè)模型構(gòu)件去處
理請(qǐng)求,然后用確定用哪個(gè)視圖來(lái)顯示模型處理返回的數(shù)據(jù)。
現(xiàn)在我們總結(jié)MVC的處理過(guò)程,首先控制器接收用戶的請(qǐng)求,并決定應(yīng)該調(diào)用哪個(gè)模型來(lái)進(jìn)行處理,然后
模型用業(yè)務(wù)邏輯來(lái)處理用戶的請(qǐng)求并返回?cái)?shù)據(jù),最后控制器用相應(yīng)的視圖格式化模型返回的數(shù)據(jù),并通過(guò)
表示層呈現(xiàn)給用戶。
為什么要使用MVC
大部分Web應(yīng)用程序都是用像ASP,PHP,或者CFML這樣的過(guò)程化語(yǔ)言來(lái)創(chuàng)建的。它們將像數(shù)據(jù)庫(kù)查
詢語(yǔ)句這樣的數(shù)據(jù)層代碼和像HTML這樣的表示層代碼混在一起。經(jīng)驗(yàn)比較豐富的開(kāi)發(fā)者會(huì)將數(shù)據(jù)從表示
層分離開(kāi)來(lái),但這通常不是很容易做到的,它需要精心的計(jì)劃和不斷的嘗試。MVC從根本上強(qiáng)制性的將它
們分開(kāi).盡管構(gòu)造MVC應(yīng)用程序需要一些額外的工作,但是它給我們帶來(lái)的好處是無(wú)庸質(zhì)疑的。
首先,最重要的一點(diǎn)是多個(gè)視圖能共享一個(gè)模型,正如我所提及的,現(xiàn)在需要用越來(lái)越多的方式來(lái)訪問(wèn)你
的應(yīng)用程序。對(duì)此,其中一個(gè)解決之道是使用MVC,無(wú)論你的用戶想要Flash界面或是WAP界面;用
?個(gè)模型就能處理它們。由于你已經(jīng)將數(shù)據(jù)和業(yè)務(wù)規(guī)則從表示層分開(kāi),所以你可以最大化的重用你的代碼
了。
由于模型返回的數(shù)據(jù)沒(méi)有進(jìn)行格式化,所以同樣的構(gòu)件能被不同界面使用。例如,很多數(shù)據(jù)可能用HTML
來(lái)表示,但是它們也有可能要用MacromediaFlash和WAP來(lái)表示。模型也有狀態(tài)管理和數(shù)據(jù)持久性處
理的功能,例如,基于會(huì)話的購(gòu)物車(chē)和電子商務(wù)過(guò)程也能被Flash網(wǎng)站或者無(wú)線聯(lián)網(wǎng)的應(yīng)用程序所重用。
因?yàn)槟P褪亲园模⑶遗c控制器和視圖相分離,所以很容易改變你的應(yīng)用程序的數(shù)據(jù)層和業(yè)務(wù)規(guī)則。
如果你想把你的數(shù)據(jù)庫(kù)從MySQL移植到Oracle,或者改變你的基于RDBMS數(shù)據(jù)源到LDAP,只需改變
你的模型即可。一旦你正確的實(shí)現(xiàn)了模型,不管你的數(shù)據(jù)來(lái)自數(shù)據(jù)庫(kù)或是LDAP服務(wù)器,視圖將會(huì)正確的
顯示它們。由于運(yùn)用MVC的應(yīng)用程序的三個(gè)部件是相互對(duì)立,改變其中一個(gè)不會(huì)影響其它兩個(gè),所以依
據(jù)這種設(shè)計(jì)思想你能構(gòu)造良好的松偶合的構(gòu)件
對(duì)我來(lái)說(shuō),控制器的也提供了一個(gè)好處,就是可以使用控制器來(lái)聯(lián)接不同的模型和視圖去完成用戶的需求,
這樣控制器可以為構(gòu)造應(yīng)用程序提供強(qiáng)有力的手段。給定一些可重用的模型和視圖,控制器可以根據(jù)用戶
的需求選擇模型進(jìn)行處理,然后選擇視圖將處理結(jié)果顯示給用戶。
MVC的缺點(diǎn)
MVC的缺點(diǎn)是由于它沒(méi)有明確的定義,所以完全理解MVC并不是很容易。使用MVC需要精心的計(jì)劃,
由于它的內(nèi)部原理比較復(fù)雜,所以需要花費(fèi)?些時(shí)間去思考。
你將不得不花費(fèi)相當(dāng)可觀的時(shí)間去考慮如何將MVC運(yùn)用到你的應(yīng)用程序,同時(shí)由于模型和視圖要嚴(yán)格的
分離,這樣也給調(diào)試應(yīng)用程序到來(lái)了一定的困難。每個(gè)構(gòu)件在使用之前都需要經(jīng)過(guò)徹底的測(cè)試。一旦你的
構(gòu)件經(jīng)過(guò)了測(cè)試,你就可以毫無(wú)顧忌的重用它們了。
根據(jù)我個(gè)人經(jīng)驗(yàn),由于我們將?個(gè)應(yīng)用程序分成了三個(gè)部件,所以使用MVC同時(shí)也意味著你將要管理比
以前更多的文件,這一點(diǎn)是顯而易見(jiàn)的。這樣好像我們的工作量增加了,但是請(qǐng)記住這比起它所能帶給我
們的好處是不值?提。
MVC并不適介小吧其至中等規(guī)模的應(yīng)用程序,花費(fèi)大量時(shí)間將MVC應(yīng)用到規(guī)模并不是很大的應(yīng)用程序通
常會(huì)得不償失。
MVC是一條創(chuàng)建軟件的好途徑
MVC設(shè)計(jì)模式是?個(gè)很好創(chuàng)建軟件的途徑,它所提倡的?些原則,像內(nèi)容和顯示互相分離可能比較好理解。
但是如果你要隔離模型、視圖和控制器的構(gòu)件,你可能需要重新思考你的應(yīng)用程序,尤其是應(yīng)用程序的構(gòu)
架方面。如果你肯接受MVC,并且有能力應(yīng)付它所帶來(lái)的額外的工作和復(fù)雜性,MVC將會(huì)使你的軟件在
健壯性,代碼重用和結(jié)構(gòu)方面上一個(gè)新的臺(tái)階。
2解釋二http://www.ask321.com/ask8/ask151598.htm
Model-View-Controller
a.問(wèn)題
如果開(kāi)發(fā)?個(gè)企業(yè)級(jí)應(yīng)用,只需要?種客戶端的話,那么?切都非常容易解決。但真實(shí)情況是,我們必須
面對(duì)運(yùn)行在各種設(shè)備上客戶端,象PDA,WAP瀏覽器以及運(yùn)行在桌面上的瀏覽器,我們不得不開(kāi)發(fā)不同
的應(yīng)用程序來(lái)處理來(lái)自不同客戶端的請(qǐng)求。數(shù)據(jù)訪問(wèn)與現(xiàn)實(shí)將混淆在?起,可能會(huì)出現(xiàn)重復(fù)的數(shù)據(jù)訪問(wèn),
導(dǎo)致整個(gè)開(kāi)發(fā)周期沒(méi)有必要的延長(zhǎng)。
b.建議的解決方法
Model-View-Controller(MVC)開(kāi)發(fā)模式被證明是有效的處理方法之-?它可以分離數(shù)據(jù)訪問(wèn)和數(shù)據(jù)表
現(xiàn)。你可以開(kāi)發(fā)一個(gè)有伸縮性的,便于擴(kuò)展的控制器,來(lái)維護(hù)整個(gè)流程。如圖1所示為整個(gè)模式的結(jié)構(gòu)。
MVC模式可以被映射到多層企業(yè)級(jí)的J2EE應(yīng)用上。
§所有的企業(yè)數(shù)據(jù)以及商業(yè)邏輯可以作為模式。
§視圖可以通過(guò)模式訪問(wèn)數(shù)據(jù),并根據(jù)客戶端的要求來(lái)技示數(shù)據(jù)。視圖必須保證當(dāng)模式改變的時(shí)候,
數(shù)據(jù)顯示也必須同時(shí)改變。
§控制器用來(lái)結(jié)合模式和視圖,把客戶端來(lái)的請(qǐng)求轉(zhuǎn)換成模式能夠理解并執(zhí)行的請(qǐng)求,并且根據(jù)請(qǐng)
求以及執(zhí)行結(jié)果來(lái)決定下?次顯示那?個(gè)視圖。
根據(jù)以上的邏輯,你可以象這樣建立個(gè)應(yīng)用:
§應(yīng)用的商業(yè)邏輯由MVC中的模式也就是EJB來(lái)表現(xiàn)。模式必須處理由控制器傳遞過(guò)來(lái)的對(duì)數(shù)據(jù)
的訪問(wèn)請(qǐng)求。
§多個(gè)頁(yè)面組成了MVC中的視圖,這些視圖必須隨模式一起更新。
§控制器是一系列接收用戶動(dòng)作的對(duì)象,他們把用戶的請(qǐng)求轉(zhuǎn)換成模式可理解的請(qǐng)求,并決定顯示
那個(gè)頁(yè)面當(dāng)模式處理完請(qǐng)求后。
圖1
c.要點(diǎn)
§MVC結(jié)構(gòu)適用于那些多用戶的,可擴(kuò)展的,可維護(hù)的,具有很高交互性的系統(tǒng)。
§MVC可以很好的表達(dá)用戶的交互和系統(tǒng)模式。
§很方便的用多個(gè)視圖來(lái)顯示多套數(shù)據(jù),是系統(tǒng)很方便的支持其他新的客戶端類(lèi)型。
§代碼重復(fù)達(dá)到最低。
§由于分離了模式中的流控制和數(shù)據(jù)表現(xiàn),可以分清開(kāi)發(fā)者的責(zé)任,另外,也可以加快產(chǎn)品推向市
場(chǎng)的時(shí)間
3解釋三/bbsjhZ14/1135.html
[轉(zhuǎn)帖]了解MVC架構(gòu)對(duì)于用Struts構(gòu)建的強(qiáng)大的Web應(yīng)用程序很重要
作者:cine發(fā)表時(shí)間:2002/12/0308:48am
了解MVC架構(gòu)對(duì)于用Struts構(gòu)建的強(qiáng)大的Web應(yīng)用程序很重要
Struts是雅加達(dá)的,個(gè)項(xiàng)目,它提供了一個(gè)方法,可以在?,個(gè)Web應(yīng)用程序中一起使用JavaServer
Pages(JSP)和servlets。它的目的是要解決完全由JSP或完全由servlet實(shí)現(xiàn)的應(yīng)用程序中的固有的
問(wèn)
題。例如,servelts可以生成HTML頁(yè)面,但這么做很麻煩。另一方面,JSP可以很容易地用于傳統(tǒng)的
HTML頁(yè)面,但JSP頁(yè)面有其它的缺點(diǎn)。特別是,用JSP很難將內(nèi)容同內(nèi)容的顯示分開(kāi)。很容易將Java
代
碼同HTML混在一起,結(jié)果做出的東西又慢乂難以維護(hù)。
然而,因?yàn)镴SP頁(yè)面容易使用,所以它們成為用Java構(gòu)建動(dòng)態(tài)的Web應(yīng)用程序的首選方法。除了容易編
程
外,JSP頁(yè)面也被改進(jìn)了,所以現(xiàn)在它們克服了以前的某些局限性。JavaBeans和標(biāo)記庫(kù)只是在基礎(chǔ)的
JSP技術(shù)上的幾個(gè)改進(jìn)。這種類(lèi)型的方法一JSP頁(yè)面單獨(dú)負(fù)責(zé)處理輸入的請(qǐng)求和回復(fù)客戶端一被稱(chēng)為
Model1架構(gòu)。
JavaServerPages是servlets的特殊情況,所以兩者可以「?起工作以彌補(bǔ)每個(gè)的不足,這似乎是合乎邏
輯的。這種類(lèi)型的方法一你的Web架構(gòu)包含截然不同的但又互聯(lián)的處理數(shù)據(jù)模式、顯示代碼和程序控
制邏輯的JSP和servlet組件——被稱(chēng)為Model2架構(gòu),或Model-View-Controller(MVC)架構(gòu)。
為了使用Struts架構(gòu)以及用JSP和servlets有效地編程,對(duì)MVC架構(gòu)的了解是很必要的。Model1和
MVC架
構(gòu)的主要不同就是請(qǐng)求是在哪里處理的。在Model1架構(gòu)中,請(qǐng)求通過(guò)JSP接收,主要通過(guò)JSP處理。
如
果JSP頁(yè)面需要來(lái)自任何其它應(yīng)用程序組件的服務(wù),如一個(gè)數(shù)據(jù)庫(kù),那么你就從頁(yè)面做適當(dāng)?shù)恼{(diào)用,把
數(shù)據(jù)返回到頁(yè)面,安排數(shù)據(jù)的格式并顯示出來(lái)。你可以把一些代碼放到一個(gè)或多個(gè)JavaBean中,但是這
么做本身沒(méi)有將邏輯同顯示完全分離。
MVC方法采用了JSP和servlet方法的最佳特性,使這兩種技術(shù)可以協(xié)同工作。明確的是,servlet是處
理
層(控制器)。Servlet接收請(qǐng)求,很像Model1架構(gòu)中JSP頁(yè)面所做的那樣,并確定如何滿足那些請(qǐng)
求。這就意味著,servlet控制輸入的請(qǐng)求和輸出的回應(yīng)。
商業(yè)邏輯體現(xiàn)了MVC架構(gòu)中的模式。商業(yè)邏輯代碼為頁(yè)面做處理。如果進(jìn)入servlet的請(qǐng)求是一個(gè)數(shù)據(jù)庫(kù)
查詢,servlet就將這個(gè)請(qǐng)求傳送到個(gè)SQL調(diào)用或類(lèi)似的數(shù)據(jù)庫(kù)代碼。如果請(qǐng)求是一個(gè)包括輸入信用卡
號(hào)的購(gòu)買(mǎi)請(qǐng)求,那么事物處理代碼就接管了。在某種意義上,架構(gòu)的模式部分是讓?xiě)?yīng)用程序處于領(lǐng)先地
位的全部原因。
JSP頁(yè)面是顯示層(視圖),是用戶與應(yīng)用程序交互的地方。它提供輸入并顯示結(jié)果。頁(yè)面不應(yīng)該包括
任何腳本。它只是將數(shù)據(jù)傳送到servlet,并接收和顯示返回的數(shù)據(jù)。
該架構(gòu)的優(yōu)勢(shì)應(yīng)該是很明顯的。首先,它將計(jì)算和顯示清楚地分開(kāi)了。結(jié)果很理想,在JSP頁(yè)面上沒(méi)有
出現(xiàn)處理過(guò)程,在servlet或商業(yè)邏輯中沒(méi)有數(shù)據(jù)格式。這種分離的另?個(gè)好處是Java程序員可以專(zhuān)注
于servlet代碼,HTML編寫(xiě)者可以專(zhuān)注于JSP。第二點(diǎn),控制器servlet做頁(yè)面上的所有的決定。在
你
的頁(yè)面和邏輯中不會(huì)出現(xiàn)任何決策。這就提高了一個(gè)應(yīng)用程序的性能和可擴(kuò)展性,因?yàn)檎?qǐng)求可以被導(dǎo)向
架構(gòu)的不同的組件,甚至是不同的服務(wù)器。
運(yùn)用MVC架構(gòu)
MVC架構(gòu)沒(méi)有必要成為用于所有Java應(yīng)用程序的最佳方法。如你想象的那樣,它在準(zhǔn)備和編碼時(shí)往往
很
復(fù)雜一這對(duì)簡(jiǎn)單的應(yīng)用程序來(lái)說(shuō)是沒(méi)必要的。當(dāng)頁(yè)面導(dǎo)航相對(duì)來(lái)說(shuō)比較簡(jiǎn)單和固定,而且應(yīng)用程序中
的頁(yè)面結(jié)構(gòu)可以由一個(gè)簡(jiǎn)單的目錄結(jié)構(gòu)管理時(shí),Model1架構(gòu)仍然是最好的方法。這些應(yīng)用程序往往將
頁(yè)面流動(dòng)信息嵌入到頁(yè)面間的鏈接中。(JSP中出現(xiàn)forward。就告訴你,在該頁(yè)中有嵌入的邏輯,讓你
對(duì)顯示下一頁(yè)作出決定。)對(duì)于對(duì)流量或可擴(kuò)展性需求有限的靜態(tài)的應(yīng)用程序來(lái)說(shuō),標(biāo)準(zhǔn)的JSP模式仍
然是一個(gè)可行的選擇方案。
在一些情況下,你可能想把一個(gè)JSP應(yīng)用程序移植到MVC架構(gòu)中。例如,你可能開(kāi)始時(shí)用的是Model1,
簡(jiǎn)單的JSP架構(gòu),隨著你的需求的增加,你會(huì)發(fā)現(xiàn)維護(hù)起來(lái)太復(fù)雜或太難了。如果你花很長(zhǎng)的時(shí)間對(duì)應(yīng)
用程序做相對(duì)來(lái)說(shuō)較簡(jiǎn)單的修改,或者如果你經(jīng)常在你的代碼中發(fā)現(xiàn)bug,那么你的JSP導(dǎo)向的應(yīng)用程序
也許就不再是合適的方法了。
隨著應(yīng)用程序的發(fā)展和變化,頁(yè)面的流動(dòng)和商業(yè)邏輯也增加了。應(yīng)用程序變得難以維護(hù),因?yàn)轫?yè)面流動(dòng)
邏輯跨多個(gè)頁(yè)面分布,而且商業(yè)邏輯可能開(kāi)始存在于未計(jì)劃的地方。從Model1轉(zhuǎn)到MVC的最佳時(shí)機(jī)就
是
當(dāng)這些類(lèi)型的維護(hù)問(wèn)題出現(xiàn)的時(shí)候。
你也可以預(yù)先計(jì)劃將你的應(yīng)用程序從一個(gè)架構(gòu)移植到另一個(gè)架構(gòu)。當(dāng)你的應(yīng)用程序中的JSP頁(yè)面包含腳
本元素,定制標(biāo)記或JavaScript來(lái)執(zhí)行?個(gè)forward。操作時(shí),你可能想調(diào)整你最初的設(shè)計(jì),變成一種
用MVC架構(gòu)的設(shè)計(jì)。
Refactoring用在這兒是個(gè)不錯(cuò)的術(shù)語(yǔ)。它指的是以一種高度嚴(yán)謹(jǐn)?shù)姆绞街亟ùa結(jié)構(gòu)的一種技術(shù)。當(dāng)
你的代碼變得難以理解、修改和調(diào)試時(shí),你通常就開(kāi)始考慮調(diào)整了。你可以用兒種方式來(lái)調(diào)整代碼:你
可以簡(jiǎn)單地重新命名變量和方法,或者將部分代碼移植到不同類(lèi)型的執(zhí)行模式中。更多的關(guān)于調(diào)整及其
技術(shù)方面的信息,請(qǐng)?jiān)L問(wèn)MartinFowler的網(wǎng)站或者閱讀他寫(xiě)的書(shū)
Refactoring:ImprovingtheDesignofExistingCode。
在許多情況下,一開(kāi)始就選擇MVC架構(gòu)是很有意義的,例如你的應(yīng)用程序是為廣泛的企業(yè)應(yīng)用而設(shè)計(jì)
的,或者在幾年內(nèi),你的應(yīng)用程序可能擴(kuò)展到一個(gè)相當(dāng)高的流量。設(shè)計(jì)一個(gè)MVC架構(gòu)需要有深謀遠(yuǎn)慮。
大多數(shù)程序員發(fā)現(xiàn)寫(xiě)邏輯腳本或JavaBeans,以及用HTML顯示很容易。當(dāng)你設(shè)計(jì)一個(gè)MVC架構(gòu)時(shí),你
必須
首先進(jìn)行一個(gè)完整的設(shè)計(jì)。這就意味著,分析需要處理的請(qǐng)求的類(lèi)型,確定哪些組件(JavaBean.數(shù)據(jù)
庫(kù)或其它servlets)將處理這些請(qǐng)求,以及對(duì)那些請(qǐng)求的回應(yīng)是如何顯示給用戶的。該設(shè)計(jì)的關(guān)鍵就
是請(qǐng)求和數(shù)據(jù)的流動(dòng)性。為MVC架構(gòu)設(shè)計(jì)應(yīng)用程序組件只是對(duì)你現(xiàn)在用JSP和servlets所做工作的擴(kuò)
展。
面臨的挑戰(zhàn)就是構(gòu)建一個(gè)servlet,它接收請(qǐng)求并把那些請(qǐng)求分到應(yīng)用程序的不同的組件。將一個(gè)數(shù)據(jù)
庫(kù)請(qǐng)求傳送到?個(gè)數(shù)據(jù)庫(kù),或?qū)?個(gè)處理請(qǐng)求傳送到個(gè)JavaBean是很容易的,但是如果?個(gè)請(qǐng)求包含
這兩種元素,會(huì)怎樣呢?或者如果請(qǐng)求的性質(zhì)在一些處理出現(xiàn)前不能確定,又怎樣呢?
Struts構(gòu)架
該挑戰(zhàn)使我們乂回到Struts構(gòu)架。Struts提供了?個(gè)實(shí)現(xiàn)MVC架構(gòu)的高度自動(dòng)化的方式。它的結(jié)構(gòu)實(shí)現(xiàn)
了MVC,并包括一個(gè)控制器servlet、一組JSP頁(yè)面和應(yīng)用程序的商業(yè)邏輯??刂破鲗⒂脩粽?qǐng)求打包,并
把它們導(dǎo)向架構(gòu)中的其他對(duì)象。
Struts構(gòu)架是圍繞?個(gè)ActionMapping結(jié)構(gòu)的。控制器用ActionMapping把HTTP消息形式的用戶
請(qǐng)求
轉(zhuǎn)換成應(yīng)用程序的動(dòng)作。ActionMapping指定請(qǐng)求的路徑、計(jì)劃處理請(qǐng)求的對(duì)象以及任何服務(wù)該請(qǐng)求需
要的其它信息。ActionMa
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- GB/T 44951-2024防彈材料及產(chǎn)品V50試驗(yàn)方法
- 2021年華夏航空分析報(bào)告48
- 人力資源管理(管理科學(xué)研究所課件)
- 羊水污染的健康宣教
- 同型胱氨酸尿癥的臨床護(hù)理
- 上頜竇癌的健康宣教
- 《數(shù)學(xué)應(yīng)用問(wèn)題專(zhuān)題》課件
- 《第一章》課件-第七章第三節(jié):大數(shù)據(jù)技術(shù)與應(yīng)用-大數(shù)據(jù)相關(guān)知識(shí)
- 胎動(dòng)的健康宣教
- 孕期呼吸道過(guò)敏的健康宣教
- 【MOOC】信號(hào)與系統(tǒng)-南京郵電大學(xué) 中國(guó)大學(xué)慕課MOOC答案
- 大學(xué)美育(同濟(jì)大學(xué)版)學(xué)習(xí)通超星期末考試答案章節(jié)答案2024年
- 中國(guó)重癥患者腸外營(yíng)養(yǎng)治療臨床實(shí)踐專(zhuān)家共識(shí)(2024)解讀
- 足三陰經(jīng)周康梅
- MOOC 跨文化交際通識(shí)通論-揚(yáng)州大學(xué) 中國(guó)大學(xué)慕課答案
- 10000中國(guó)普通人名大全
- 吊籃安裝合同范文
- 【甲乳外科-甲狀腺-課件-幻燈】超聲引導(dǎo)下甲旁亢熱消融治療
- 軟件開(kāi)發(fā)項(xiàng)目的監(jiān)理規(guī)劃
- 小區(qū)會(huì)所經(jīng)營(yíng)方案(開(kāi)業(yè)投資分析)
- 加氣混凝土砌塊施工方法
評(píng)論
0/150
提交評(píng)論