亚洲日韩激情无码一区,亚洲午夜电影在线观看,亚洲宅男天堂在线观看无病毒http://www.tkk7.com/forget/<h2>能吃能睡是福;能忘是大福......</h2>zh-cnSun, 13 Jul 2025 14:05:48 GMTSun, 13 Jul 2025 14:05:48 GMT6061條面向?qū)ο笤O(shè)計(jì)的經(jīng)驗(yàn)原則http://www.tkk7.com/forget/archive/2011/05/12/350101.html橘子橘子Thu, 12 May 2011 08:50:00 GMThttp://www.tkk7.com/forget/archive/2011/05/12/350101.htmlhttp://www.tkk7.com/forget/comments/350101.htmlhttp://www.tkk7.com/forget/archive/2011/05/12/350101.html#Feedback0http://www.tkk7.com/forget/comments/commentRss/350101.htmlhttp://www.tkk7.com/forget/services/trackbacks/350101.html     (1)所有數(shù)據(jù)都應(yīng)該隱藏在所在的類的內(nèi)部。
  
  (2)類的使用者必須依靠類的共有接口,但類不能依靠它的使用者。
  
  (3)盡量減少類的協(xié)議中的消息。
  
  (4)實(shí)現(xiàn)所有類都理解的最基本公有接口[例如,拷貝操作(深拷貝和淺拷貝)、相等性判定、正確輸出內(nèi)容、從ASCII描述解析等等]。
  
  (5)不要把實(shí)現(xiàn)細(xì)節(jié)(例如放置共用代碼的私有函數(shù))放到類的公有接口中。
  
  假如類的兩個(gè)方法有一段公共代碼,那么就可以創(chuàng)建一個(gè)防止這些公共代碼的私有函數(shù)。
  
  (6)不要以用戶無法使用或不感愛好的東西擾亂類的公有接口。
  
  (7)類之間應(yīng)該零耦合,或者只有導(dǎo)出耦合關(guān)系。也即,一個(gè)類要么同另一個(gè)類毫無關(guān)系,要么只使用另一個(gè)類的公有接口中的操作。
  
  (8)類應(yīng)該只表示一個(gè)要害抽象。
  
  包中的所有類對于同一類性質(zhì)的變化應(yīng)該是共同封閉的。一個(gè)變化若對一個(gè)包影響,則將對包中的所有類產(chǎn)生影響,而對其他的包不造成任何影響 。
  
  (9)把相關(guān)的數(shù)據(jù)和行為集中放置。
  
  設(shè)計(jì)者應(yīng)當(dāng)留意那些通過get之類操作從別的對象中獲取數(shù)據(jù)的對象。這種類型的行為暗示著這條經(jīng)驗(yàn)原則被違反了。
  
  (10)把不相關(guān)的信息放在另一個(gè)類中(也即:互不溝通的行為)。
  
  朝著穩(wěn)定的方向進(jìn)行依靠。
  
  (11)確保你為之建模的抽象概念是類,而不只是對象扮演的角色。
  
  (12)在水平方向上盡可能統(tǒng)一地分布系統(tǒng)功能,也即:按照設(shè)計(jì),頂層類應(yīng)當(dāng)統(tǒng)一地共享工作。
  
  (13)在你的系統(tǒng)中不要?jiǎng)?chuàng)建全能類/對象。對名字包含Driver、Manager、System、Susystem的類要非凡多加小心。
  
  規(guī)劃一個(gè)接口而不是實(shí)現(xiàn)一個(gè)接口。
  
  (14)對公共接口中定義了大量訪問方法的類多加小心。大量訪問方法意味著相關(guān)數(shù)據(jù)和行為沒有集中存放。
  
  (15)對包含太多互不溝通的行為的類多加小心。
  
  這個(gè)問題的另一表現(xiàn)是在你的應(yīng)用程序中的類的公有接口中創(chuàng)建了很多的get和set函數(shù)。
  
  (16)在由同用戶界面交互的面向?qū)ο竽P蜆?gòu)成的應(yīng)用程序中,模型不應(yīng)該依靠于界面,界面則應(yīng)當(dāng)依靠于模型。
  
  (17)盡可能地按照現(xiàn)實(shí)世界建模(我們經(jīng)常為了遵守系統(tǒng)功能分布原則、避免全能類原則以及集中放置相關(guān)數(shù)據(jù)和行為的原則而違反這條原則) 。
  
  (18)從你的設(shè)計(jì)中去除不需要的類。
  
  一般來說,我們會(huì)把這個(gè)類降級成一個(gè)屬性。
  
  (19)去除系統(tǒng)外的類。
  
  系統(tǒng)外的類的特點(diǎn)是,抽象地看它們只往系統(tǒng)領(lǐng)域發(fā)送消息但并不接受系統(tǒng)領(lǐng)域內(nèi)其他類發(fā)出的消息。
  
  (20)不要把操作變成類。質(zhì)疑任何名字是動(dòng)詞或者派生自動(dòng)詞的類,非凡是只有一個(gè)有意義行為的類。考慮一下那個(gè)有意義的行為是否應(yīng)當(dāng)遷移到已經(jīng)存在或者尚未發(fā)現(xiàn)的某個(gè)類中。
  
  (21)我們在創(chuàng)建應(yīng)用程序的分析模型時(shí)經(jīng)常引入代理類。在設(shè)計(jì)階段,我們常會(huì)發(fā)現(xiàn)很多代理沒有用的,應(yīng)當(dāng)去除。
  
  (22)盡量減少類的協(xié)作者的數(shù)量。
  
  一個(gè)類用到的其他類的數(shù)目應(yīng)當(dāng)盡量少。
  
  (23)盡量減少類和協(xié)作者之間傳遞的消息的數(shù)量。
  
  (24)盡量減少類和協(xié)作者之間的協(xié)作量,也即:減少類和協(xié)作者之間傳遞的不同消息的數(shù)量。
  
  (25)盡量減少類的扇出,也即:減少類定義的消息數(shù)和發(fā)送的消息數(shù)的乘積。
  
  (26)假如類包含另一個(gè)類的對象,那么包含類應(yīng)當(dāng)給被包含的對象發(fā)送消息。也即:包含關(guān)系總是意味著使用關(guān)系。
  
  (27)類中定義的大多數(shù)方法都應(yīng)當(dāng)在大多數(shù)時(shí)間里使用大多數(shù)數(shù)據(jù)成員。
  
  (28)類包含的對象數(shù)目不應(yīng)當(dāng)超過開發(fā)者短期記憶的容量。這個(gè)數(shù)目經(jīng)常是6。
  
  當(dāng)類包含多于6個(gè)數(shù)據(jù)成員時(shí),可以把邏輯相關(guān)的數(shù)據(jù)成員劃分為一組,然后用一個(gè)新的包含類去包含這一組成員。
  
  (29)讓系統(tǒng)功能在窄而深的繼續(xù)體系中垂直分布。
  
  (30)在實(shí)現(xiàn)語義約束時(shí),最好根據(jù)類定義來實(shí)現(xiàn)。這經(jīng)常會(huì)導(dǎo)致類泛濫成災(zāi),在這種情況下,約束應(yīng)當(dāng)在類的行為中實(shí)現(xiàn),通常是在構(gòu)造函數(shù)中實(shí)現(xiàn),但不是必須如此。
  
  (31)在類的構(gòu)造函數(shù)中實(shí)現(xiàn)語義約束時(shí),把約束測試放在構(gòu)造函數(shù)領(lǐng)域所答應(yīng)的盡量深的包含層次中。
  
  (32)約束所依靠的語義信息假如經(jīng)常改變,那么最好放在一個(gè)集中式的第3方對象中。
  
  (33)約束所依靠的語義信息假如很少改變,那么最好分布在約束所涉及的各個(gè)類中。
  
  (34)類必須知道它包含什么,但是不能知道誰包含它。
  
  (35)共享字面范圍(也就是被同一個(gè)類所包含)的對象相互之間不應(yīng)當(dāng)有使用關(guān)系。
  
  (36)繼續(xù)只應(yīng)被用來為特化層次結(jié)構(gòu)建模。
  
  (37)派生類必須知道基類,基類不應(yīng)該知道關(guān)于它們的派生類的任何信息。
  
  (38)基類中的所有數(shù)據(jù)都應(yīng)當(dāng)是私有的,不要使用保護(hù)數(shù)據(jù)。
  
  類的設(shè)計(jì)者永遠(yuǎn)都不應(yīng)該把類的使用者不需要的東西放在公有接口中。
  
  (39)在理論上,繼續(xù)層次體系應(yīng)當(dāng)深一點(diǎn),越深越好。
  
  (40)在實(shí)踐中,繼續(xù)層次體系的深度不應(yīng)當(dāng)超出一個(gè)普通人的短期記憶能力。一個(gè)廣為接受的深度值是6。
  
  (41)所有的抽象類都應(yīng)當(dāng)是基類。
  
  (42)所有的基類都應(yīng)當(dāng)是抽象類。
  
  (43)把數(shù)據(jù)、行為和/或接口的共性盡可能地放到繼續(xù)層次體系的高端。
  
  (44)假如兩個(gè)或更多個(gè)類共享公共數(shù)據(jù)(但沒有公共行為),那么應(yīng)當(dāng)把公共數(shù)據(jù)放在一個(gè)類中,每個(gè)共享這個(gè)數(shù)據(jù)的類都包含這個(gè)類。
  
  (45)假如兩個(gè)或更多個(gè)類有共同的數(shù)據(jù)和行為(就是方法),那么這些類的每一個(gè)都應(yīng)當(dāng)從一個(gè)表示了這些數(shù)據(jù)和方法的公共基類繼續(xù)。
  
  (46)假如兩個(gè)或更多個(gè)類共享公共接口(指的是消息,而不是方法),那么只有他們需要被多態(tài)地使用時(shí),他們才應(yīng)當(dāng)從一個(gè)公共基類繼續(xù)。
  
  (47)對對象類型的顯示的分情況分析一般是錯(cuò)誤的。在大多數(shù)這樣的情況下,設(shè)計(jì)者應(yīng)當(dāng)使用多態(tài)。
  
  (48)對屬性值的顯示的分情況分析經(jīng)常是錯(cuò)誤的。類應(yīng)當(dāng)解耦合成一個(gè)繼續(xù)層次結(jié)構(gòu),每個(gè)屬性值都被變換成一個(gè)派生類。
  
  (49)不要通過繼續(xù)關(guān)系來為類的動(dòng)態(tài)語義建模。試圖用靜態(tài)語義關(guān)系來為動(dòng)態(tài)語義建模會(huì)導(dǎo)致在運(yùn)行時(shí)切換類型。
  
  (50)不要把類的對象變成派生類。對任何只有一個(gè)實(shí)例的派生類都要多加小心。
  
  (51)假如你覺得需要在運(yùn)行時(shí)刻創(chuàng)建新的類,那么退后一步以認(rèn)清你要?jiǎng)?chuàng)建的是對象。現(xiàn)在,把這些對象概括成一個(gè)類。
  
  (52)在派生類中用空方法(也就是什么也不做的方法)來覆寫基類中的方法應(yīng)當(dāng)是非法的。
  
  (53)不要把可選包含同對繼續(xù)的需要相混淆。把可選包含建模成繼續(xù)會(huì)帶來泛濫成災(zāi)的類。
  
  (54)在創(chuàng)建繼續(xù)層次時(shí),試著創(chuàng)建可復(fù)用的框架,而不是可復(fù)用的組件。
  
  (55)假如你在設(shè)計(jì)中使用了多重繼續(xù),先假設(shè)你犯了錯(cuò)誤。假如沒犯錯(cuò)誤,你需要設(shè)法證實(shí)。
  
  (56)只要在面向?qū)ο笤O(shè)計(jì)中用到了繼續(xù),問自己兩個(gè)問題:(1)派生類是否是它繼續(xù)的那個(gè)東西的一個(gè)非凡類型?(2)基類是不是派生類的一部分?
  
  (57)假如你在一個(gè)面向?qū)ο笤O(shè)計(jì)中發(fā)現(xiàn)了多重繼續(xù)關(guān)系,確保沒有哪個(gè)基類實(shí)際上是另一個(gè)基類的派生類。
  
  (58)在面向?qū)ο笤O(shè)計(jì)中假如你需要在包含關(guān)系和關(guān)聯(lián)關(guān)系間作出選擇,請選擇包含關(guān)系。
  
  (59)不要把全局?jǐn)?shù)據(jù)或全局函數(shù)用于類的對象的薄記工作。應(yīng)當(dāng)使用類變量或類方法。
  
  (60)面向?qū)ο笤O(shè)計(jì)者不應(yīng)當(dāng)讓物理設(shè)計(jì)準(zhǔn)則來破壞他們的邏輯設(shè)計(jì)。但是,在對邏輯設(shè)計(jì)作出決策的過程中我們經(jīng)常用到物理設(shè)計(jì)準(zhǔn)則。
  
  (61)不要繞開公共接口去修改對象的狀態(tài)。



橘子 2011-05-12 16:50 發(fā)表評論
]]>
SVN完整安裝及簡略使用http://www.tkk7.com/forget/archive/2006/08/08/62304.html橘子橘子Tue, 08 Aug 2006 02:33:00 GMThttp://www.tkk7.com/forget/archive/2006/08/08/62304.htmlhttp://www.tkk7.com/forget/comments/62304.htmlhttp://www.tkk7.com/forget/archive/2006/08/08/62304.html#Feedback0http://www.tkk7.com/forget/comments/commentRss/62304.htmlhttp://www.tkk7.com/forget/services/trackbacks/62304.html閱讀全文

橘子 2006-08-08 10:33 發(fā)表評論
]]>
Synchronization state同步狀態(tài)http://www.tkk7.com/forget/archive/2006/07/26/60221.html橘子橘子Wed, 26 Jul 2006 10:01:00 GMThttp://www.tkk7.com/forget/archive/2006/07/26/60221.htmlhttp://www.tkk7.com/forget/comments/60221.htmlhttp://www.tkk7.com/forget/archive/2006/07/26/60221.html#Feedback0http://www.tkk7.com/forget/comments/commentRss/60221.htmlhttp://www.tkk7.com/forget/services/trackbacks/60221.html同步狀態(tài) ?
同步視圖顯示你的本地工作平臺與服務(wù)器存儲(chǔ)庫中資源的同步狀態(tài)。狀態(tài)按圖標(biāo)顯示,你也可以把狀態(tài)顯示配置為資源名稱之后的文字。下表列出圖標(biāo)的描述。 ?
指向左邊的藍(lán)色箭頭包含加號,引入新增——表示一項(xiàng)資源已經(jīng)被加入到服務(wù)器。點(diǎn)更新鍵會(huì)把資源傳遞到本地上。 ?
指向左邊的藍(lán)色箭頭 ?引入變化——表示服務(wù)器中的資源已經(jīng)變化。點(diǎn)更新鍵會(huì)把新文件傳遞到本地。 ?
指向左邊的藍(lán)色箭頭包含減號 ?引入刪除——表示服務(wù)器的資源已被刪除。點(diǎn)更新鍵會(huì)刪除你本地的資源 ? ?
指向右邊的黑色箭頭包含加號 ?輸出增加——表示你本地有新增加的文件,而服務(wù)器中沒有。添加提交鍵會(huì)把新文件傳到服務(wù)器上。 ? ?
指向右邊的黑色箭頭 ?輸出變化——表示本地的文件已經(jīng)改變。提交文件會(huì)把變化傳入服務(wù)器并創(chuàng)建文件的一個(gè)新版本。 ? ?
指向右邊的黑色箭頭包含減號 ?輸出刪除——表示本地文件已經(jīng)刪除。提交這些資源會(huì)刪除遠(yuǎn)程資源。注意:在CVS中目錄不會(huì)從服務(wù)器中真正的刪除。而只是把文件刪除,在你本地除去空文件夾。 ? ?
紅色雙向箭頭包含加號 ?沖突增加——表示本地和遠(yuǎn)程都新增加了資源 ? ?
紅色雙向箭頭 ?沖突變化——表示本地和遠(yuǎn)程都有文件變化。用戶需要手工合并或者自動(dòng)合并。同時(shí),包含有沖突文件的上級視圖也同時(shí)被顯示為沖突,這樣做是為了讓沖突更容易找到。 ? ? ?
紅色雙向箭頭包含減號 ?沖突刪除——表示本地和遠(yuǎn)程的文件都被刪除。????

橘子 2006-07-26 18:01 發(fā)表評論
]]>
使用 Eclipse 平臺共享代碼http://www.tkk7.com/forget/archive/2006/07/26/60220.html橘子橘子Wed, 26 Jul 2006 10:00:00 GMThttp://www.tkk7.com/forget/archive/2006/07/26/60220.htmlhttp://www.tkk7.com/forget/comments/60220.htmlhttp://www.tkk7.com/forget/archive/2006/07/26/60220.html#Feedback0http://www.tkk7.com/forget/comments/commentRss/60220.htmlhttp://www.tkk7.com/forget/services/trackbacks/60220.html 在團(tuán)隊(duì)項(xiàng)目中共享源代碼
現(xiàn)今的大多數(shù)應(yīng)用程序是由多人組成的團(tuán)隊(duì)開發(fā)的。即使只涉及幾個(gè)開發(fā)人員的小項(xiàng)目,也需要對源代碼的更改進(jìn)行嚴(yán)格控制。這就是源代碼管理軟件的任務(wù)。源代碼版本控制軟件必須支持兩個(gè)核心功能:

  • 提供一種方法,能夠協(xié)調(diào)對源代碼的更改,并能集成這些更改
  • 團(tuán)隊(duì)所提交工作的歷史記錄

當(dāng)團(tuán)隊(duì)成員完成新的工作時(shí),通過將這些更改提交到資源庫來共享他們的工作。類似地,當(dāng)他們希望獲得最新可用的工作成果時(shí),就可以根據(jù)資源庫中的更改,更新自己的本地工作空間。這意味著項(xiàng)目資源庫會(huì)因團(tuán)隊(duì)成員提交新工作成果而經(jīng)常發(fā)生更改。換句話說,資源庫應(yīng)該表示項(xiàng)目的當(dāng)前狀態(tài)。任何時(shí)候,團(tuán)隊(duì)成員都要能夠根據(jù)資源庫更新自己的工作空間,并確信它們是最新的。

維護(hù)歷史記錄也很重要,那樣就可以將當(dāng)前工作與先前版本進(jìn)行比較,如有必要,還可以回復(fù)到先前版本。協(xié)調(diào)團(tuán)隊(duì)的工作,以便只存在唯一的當(dāng)前項(xiàng)目狀態(tài)定義,以及包含團(tuán)隊(duì)已集成的工作,這些對于管理版本控制也是十分必要的。這種協(xié)調(diào)有可能是最難實(shí)現(xiàn)的目標(biāo)。

最理想的模型是:團(tuán)隊(duì)的任何成員都可以對自己有權(quán)訪問的任何資源進(jìn)行更改。因?yàn)閮蓚€(gè)團(tuán)隊(duì)成員可以提交對同一資源的更改,所以有可能發(fā)生沖突,必須解決這種沖突。這種模型假定沖突具有唯一性。但遺憾的是,沒有任何源代碼是孤立地存在的;通常它包含與其它資源隱式或顯式的相關(guān)性。源代碼引用了在其它源代碼資源中描述的構(gòu)件。但源代碼管理軟件的工作就到此為止了,因?yàn)樗⒉荒苋〈?xiàng)目管理。項(xiàng)目管理者必須履行其職責(zé):協(xié)調(diào)其它成員的工作以及負(fù)責(zé)進(jìn)度、項(xiàng)目階段和發(fā)布日期。此外,源代碼管理也不能替代開發(fā)人員之間的交流。

Eclipse 平臺如何支持代碼管理
Eclipse 平臺提供了作為團(tuán)隊(duì)在軟件項(xiàng)目中共享代碼和工作的能力。Eclipse 廣泛地支持各種代碼管理解決方案,這要?dú)w功于它的插件體系結(jié)構(gòu)(不過,現(xiàn)已推出了對 CVS 的支持)。Eclipse 平臺體系結(jié)構(gòu)的重點(diǎn)在于工作空間。工作空間維護(hù)構(gòu)建和測試軟件項(xiàng)目所需的一切。它包含對象(源代碼和資源)。它還保存了用于項(xiàng)目、IDE 和插件的配置設(shè)置。工作空間是在開發(fā)人員的機(jī)器上本地進(jìn)行維護(hù)的,而團(tuán)隊(duì)通過外部資源庫進(jìn)行協(xié)作,不同開發(fā)人員的代碼在資源庫進(jìn)行匯集。可以經(jīng)由因特網(wǎng)通過“客戶機(jī)-服務(wù)器”體系結(jié)構(gòu)訪問資源庫。

Eclipse 平臺提供了對于直接從工作空間進(jìn)行團(tuán)隊(duì)開發(fā)操作的支持。這種支持允許開發(fā)人員并發(fā)地與幾個(gè)獨(dú)立的資源庫以及不同版本的代碼或項(xiàng)目進(jìn)行交互。工作空間中的資源允許團(tuán)隊(duì)支持組件處理版本和配置管理問題。當(dāng)然,單個(gè)工作空間可以同時(shí)訪問不同類型的資源庫。Eclipse 平臺并沒有提供它自己的代碼管理解決方案;它總是依靠外部系統(tǒng)。Eclipse 平臺只對一個(gè)(但也是最流行的一個(gè))源代碼管理系統(tǒng)提供內(nèi)置支持:并發(fā)版本控制系統(tǒng)(Concurrent Versions System,CVS)。對第三方代碼管理應(yīng)用程序的支持一節(jié)中描述了使用第三方插件支持其它資源庫。

CVS 是什么?
CVS 誕生于 1986 年,當(dāng)時(shí)作為一組 shell 腳本而出現(xiàn),但它現(xiàn)在已經(jīng)發(fā)展成了最流行的針對軟件開發(fā)人員的源代碼版本管理解決方案。CVS 是用于代碼版本管理的開放源碼的客戶機(jī)/服務(wù)器解決方案,它可用于各種平臺,包括 Linux 和 Windows NT/2000/XP。請參閱本文末尾的參考資料,其中有 CVS 客戶機(jī)、服務(wù)器和源代碼的下載鏈接。

通常,CVS 的主要功能是記錄源文件的歷史。當(dāng)一組開發(fā)人員從事同一個(gè)項(xiàng)目時(shí),CVS 將他們彼此隔離開來。每個(gè)開發(fā)人員都在他/她自己的目錄中獨(dú)立工作,然后使用 CVS 資源庫(不時(shí)地)合并工作結(jié)果。

Eclipse 擁有與 Eclipse 平臺 IDE 緊密集成的內(nèi)置 CVS 客戶機(jī),它是作為一個(gè)單獨(dú)透視圖(CVS Repository Exploring 透視圖)而實(shí)現(xiàn)的,用于與 CVS 的交互。用于 CVS 的通用 Eclipse 設(shè)置(General Eclipse settings for CVS)位于 Window -> Preferences window -> Team 下。在切換到 CVS Repository Exploring 透視圖之后,就可以使用所有 CVS 操作了(轉(zhuǎn)至 Window -> Open Perspective -> Other -> CVS Repository Exploring 菜單 — 請參閱圖 1圖 2)。

圖 1. 切換到 CVS Repository Exploring 透視圖
CVS 資源庫

首先設(shè)置資源庫的位置,它將定義用于選定 CVS 服務(wù)器/資源庫的連接參數(shù)。請確保使用 SSH 隧道(extssh)。

圖 2. 瀏覽 CVS Repository Exploring 透視圖中的 CVS 資源庫
瀏覽 CVS 資源庫

Eclipse/CVS 的源代碼工作流
CVS 團(tuán)隊(duì)協(xié)作模型中,團(tuán)隊(duì)成員彼此獨(dú)立地在他們各自的工作臺上完成自己的所有工作。最后,他們希望共享其工作。他們通過 CVS 資源庫實(shí)現(xiàn)這一點(diǎn)。CVS 使用分支(branch)模型來支持彼此獨(dú)立而又高度相互依賴的多個(gè)工作流程(course of work)。這些分支是開發(fā)團(tuán)隊(duì)用來共享和集成正在進(jìn)行中的工作的地方。可以認(rèn)為分支是一個(gè)共享的工作臺,當(dāng)團(tuán)隊(duì)成員對源代碼進(jìn)行更改時(shí)就更新這個(gè)工作臺。這個(gè)模型允許從事 CVS 團(tuán)隊(duì)項(xiàng)目的每個(gè)開發(fā)人員在進(jìn)行更改時(shí)與其他成員共享其工作,以及在項(xiàng)目進(jìn)展期間訪問其他成員的工作。

一個(gè)稱為 HEAD 的特殊分支用來表示資源庫中的主要工作流程(HEAD 通常被稱為主干)。當(dāng)團(tuán)隊(duì)成員將資源提交給該分支時(shí),會(huì)影響這些相關(guān)性。確保相關(guān)性的完整性是很重要的,因?yàn)樵摲种П硎玖水?dāng)前項(xiàng)目的狀態(tài)。當(dāng)然,任何時(shí)候,團(tuán)隊(duì)成員都可以使用該分支的內(nèi)容作為新工作的基礎(chǔ)。

那些規(guī)則不僅適用于 CVS:無論使用哪種版本控制軟件,團(tuán)隊(duì)項(xiàng)目中都有一些用于源代碼管理的常見步驟。下面是一個(gè)使用 Eclipse 內(nèi)置的 CVS 支持的示例工作流:

1. 啟動(dòng)新的團(tuán)隊(duì)項(xiàng)目
每個(gè)新的空 Eclipse 項(xiàng)目都可以通過 CVS(或受支持的任何其它源代碼管理系統(tǒng))進(jìn)行共享。開發(fā)人員也可以通過將其現(xiàn)有的代碼遷移到資源庫來共享它。要進(jìn)行共享,單擊項(xiàng)目主文件夾,在顯示的上下文菜單中使用 Team -> Share Project 選項(xiàng),如圖 3 所示。

圖 3. 使用 CVS 資源庫共享本地項(xiàng)目
共享項(xiàng)目

另一個(gè)選項(xiàng)是通過從選定的 CVS 資源庫分支導(dǎo)入代碼來創(chuàng)建新的工作臺項(xiàng)目。只要選擇適當(dāng)分支(或 HEAD),然后選擇從 CVS Repository Exploring 透視圖中的上下文菜單中選擇“Checkout As Project”選項(xiàng),如圖 4 所示。

圖 4. 從現(xiàn)有的 CVS 資源庫創(chuàng)建新項(xiàng)目
新建項(xiàng)目

2. 使用代碼并進(jìn)行更改
開發(fā)人員通過 Eclipse 工作臺在本地使用代碼,包括的工作有創(chuàng)建新資源、修改現(xiàn)有資源、編寫注釋,并在他們使用后在本地保存這些內(nèi)容。

3. 使本地更改與 CVS 資源庫同步
如果一個(gè)項(xiàng)目開發(fā)人員準(zhǔn)備提交他/她的工作,那么首先要執(zhí)行更新操作。這會(huì)針對引入的更改核對資源庫,并將這些更改添加到該開發(fā)人員的本地工作臺。這樣確保了開發(fā)人員知道這些更改可能會(huì)影響他/她將要提交的工作的完整性。使用項(xiàng)目上下文菜單中的 Compare With... 選項(xiàng)將本地版本與資源庫中存儲(chǔ)的代碼進(jìn)行比較(請參閱圖 5)。

圖 5. 比較本地版本與資源庫中的版本
本地版本

下一步是解決最后出現(xiàn)的任何沖突,并設(shè)法再次編譯代碼。如果一切正常,那么從項(xiàng)目上下文菜單使用 Team -> Commit... 選項(xiàng)執(zhí)行提交操作,如圖 6 所示。這會(huì)使所有更改都集成到資源庫中。

圖 6. 將更改提交到遠(yuǎn)程資源庫
提交更改

4. 管理資源庫
CVS 允許開發(fā)人員將更改隔離在開發(fā)的某些獨(dú)立路徑之內(nèi),這些路徑稱為分支。當(dāng)一個(gè)開發(fā)人員更改某個(gè)分支上的文件時(shí),這種更改不會(huì)出現(xiàn)在主干或其它分支上。那些分支被命名為子版本(subversion)代碼分叉(code fork)。稍后,由合并操作將更改從一個(gè)分支遷移到另一個(gè)分支(或主干)。然后提交這些修訂。這樣就有效地將更改復(fù)制到了另一個(gè)分支上。使用項(xiàng)目上下文菜單的 Team -> Branch... 選項(xiàng),Eclipse 使開發(fā)分支之間的遷移變得容易。

當(dāng)然,當(dāng)開發(fā)團(tuán)隊(duì)維護(hù)大型資源庫時(shí),有必要控制項(xiàng)目內(nèi)的提交和合并操作。Eclipse/CVS 集成提供了一種特殊的視圖:CVS Repository History(請參閱圖 7)。它給出了關(guān)于團(tuán)隊(duì)成員在資源庫中所執(zhí)行更改的快速預(yù)覽。

圖 7. 在 CVS Resource History 窗口中查看帶注釋的修訂歷史記錄
修訂歷史記錄

Eclipse 平臺提供了幾個(gè)支持代碼管理的實(shí)用程序。最有用的是補(bǔ)丁功能。它將出自兩個(gè)來源(譬如本地工作臺和資源庫)的代碼進(jìn)行比較,然后創(chuàng)建一個(gè)包含代碼差異的類似 UNIX 的補(bǔ)丁文件(請參閱圖 8)。可以將該文件發(fā)送給開發(fā)人員以將源代碼升級到最新版本。

圖 8. 創(chuàng)建用于源代碼分發(fā)的補(bǔ)丁
源代碼分發(fā)

5. 斷開項(xiàng)目與 CVS 的連接
當(dāng)項(xiàng)目開發(fā)已經(jīng)結(jié)束,并且團(tuán)隊(duì)希望凍結(jié)源代碼時(shí),可以從 HEAD 資源庫刪除該項(xiàng)目的最終版本。斷開項(xiàng)目與 CVS 的連接將在該項(xiàng)目及其資源上禁用資源庫操作,并刪除與該項(xiàng)目相關(guān)聯(lián)的 CVS 信息(這一操作是可選的)。

可以通過項(xiàng)目上下文菜單中的 Team -> Disconnect 選項(xiàng)執(zhí)行斷開連接操作。通過選擇這個(gè)選項(xiàng),會(huì)打開 Confirm Disconnect from CVS 對話框。在將該項(xiàng)目與資源庫的連接斷開之后,該團(tuán)隊(duì)必須確定如何處理 CVS 信息。第一個(gè)選項(xiàng)是“Delete the CVS meta information”;它將禁用 CVS 團(tuán)隊(duì)菜單操作并從文件系統(tǒng)中刪除CVS 文件夾及其內(nèi)容。第二個(gè)選項(xiàng)是“Do not delete the CVS meta information”;它將禁用 CVS 團(tuán)隊(duì)菜單操作,但保留 CVS 元信息。

對第三方代碼管理應(yīng)用程序的支持
CVS 有幾個(gè)重要的限制:它不能確定單個(gè)文件或整個(gè)文件集范圍內(nèi)同時(shí)進(jìn)行的更改,它也不能檢測文件之間的邏輯沖突。其沖突概念純粹是文本意義上的,當(dāng)對于同一基本文件的兩個(gè)更改時(shí)間上非常非常接近,從而使合并命令受到干擾時(shí),就會(huì)發(fā)生沖突。CVS 也不能提供任何類似于消息傳遞這樣的交互式協(xié)作工具。幸運(yùn)的是,CVS 并不是 Eclipse 平臺所支持的唯一的源代碼管理軟件。開發(fā)人員可以通過插件擴(kuò)展 Eclipse 平臺的功能,而且目前(到 2003 年 3 月 4 日為止)已有 16 個(gè)可用于團(tuán)隊(duì)開發(fā)軟件的插件。所有插件都是由 Eclipse 社區(qū)或商業(yè)軟件供應(yīng)商創(chuàng)建的。這些插件中的大多數(shù)添加了對第三方、商業(yè)源代碼管理系統(tǒng)的支持。最有價(jià)值的插件是那些支持流行的企業(yè)代碼管理系統(tǒng)(如 Merant PVCS 和 Rational ClearCase)的插件。例如,CVS-SSH2 插件允許通過 SSH2 會(huì)話訪問 CVS,而 Microsoft Visual SourceSafe(VSS)團(tuán)隊(duì)提供程序插件添加了對 MS VSS 產(chǎn)品的支持(也可以在諸如 Linux 這樣的非 Windows 平臺上使用)。

但是,我本人所偏愛的插件是 Koi(請參閱參考資料以獲取鏈接)。盡管它并非嚴(yán)格用于源代碼控制,但這個(gè)創(chuàng)新的工具給協(xié)作開發(fā)注入了許多新的活力。其當(dāng)前版本支持工作臺到工作臺的消息傳遞、共享標(biāo)記、沖突更改通知、共享日歷和事件通知。Koi 將 XML-RPC 用作其客戶機(jī)-服務(wù)器體系結(jié)構(gòu)中的通信模型。客戶機(jī)是與“協(xié)作服務(wù)器”通信的單個(gè) Eclipse 平臺實(shí)例,而協(xié)作服務(wù)器也是一個(gè) Eclipse 插件。Koi 使用以 JDBC 訪問的關(guān)系數(shù)據(jù)庫作為數(shù)據(jù)存儲(chǔ)。可在參考資料中找到指向完整的、經(jīng)過分類的 Eclipse 插件注冊表的鏈接。

參考資料

 

關(guān)于作者
Pawel Leszek 是 Studio B 的一位作家,他是一位專長于 Linux/Win/Mac OS 系統(tǒng)體系結(jié)構(gòu)和管理的獨(dú)立軟件顧問和作家。他具有許多操作系統(tǒng)、編程語言和網(wǎng)絡(luò)協(xié)議方面的經(jīng)驗(yàn),尤其是 Lotus Domino 和 DB2 方面。Pawel 還在 LinuxWorld 上發(fā)表過一系列文章,他是 PC World 波蘭版的 Linux 專欄作家。Pawel 和他的妻子以及可愛的小女兒住在華沙。歡迎提問并提出意見;您可以通過 pawel.leszek@ipgate.pl 與 Pawel 聯(lián)系。


橘子 2006-07-26 18:00 發(fā)表評論
]]>
什么是持久化和對象關(guān)系映射ORM技術(shù)http://www.tkk7.com/forget/archive/2006/06/26/55068.html橘子橘子Mon, 26 Jun 2006 01:42:00 GMThttp://www.tkk7.com/forget/archive/2006/06/26/55068.htmlhttp://www.tkk7.com/forget/comments/55068.htmlhttp://www.tkk7.com/forget/archive/2006/06/26/55068.html#Feedback0http://www.tkk7.com/forget/comments/commentRss/55068.htmlhttp://www.tkk7.com/forget/services/trackbacks/55068.htmlhttp://www.volitation.net/Article/print.asp?SelectID=7。
何謂“持久化”
持久(Persistence),即把數(shù)據(jù)(如內(nèi)存中的對象)保存到可永久保存的存儲(chǔ)設(shè)備中(如磁盤)。持久化的主要應(yīng)用是將內(nèi)存中的數(shù)據(jù)存儲(chǔ)在關(guān)系型的數(shù)據(jù)庫中,當(dāng)然也可以存儲(chǔ)在磁盤文件中、XML數(shù)據(jù)文件中等等。

何謂“持久層”
持久層(Persistence Layer),即專注于實(shí)現(xiàn)數(shù)據(jù)持久化應(yīng)用領(lǐng)域的某個(gè)特定系統(tǒng)的一個(gè)邏輯層面,將數(shù)據(jù)使用者和數(shù)據(jù)實(shí)體相關(guān)聯(lián)。

何謂“對象數(shù)據(jù)映射(ORM)”
ORM-Object/Relational Mapper,即“對象-關(guān)系型數(shù)據(jù)映射組件”。對于O/R,即 Object(對象)和 Relational(關(guān)系型數(shù)據(jù)),表示必須同時(shí)使用面向?qū)ο蠛完P(guān)系型數(shù)據(jù)進(jìn)行開發(fā)。

備注:建模領(lǐng)域中的 ORM 為 Object/Role Modeling(對象角色建模)。另外這里是“O/R Mapper”而非“O/R Mapping”。相對來講,O/R Mapping 描述的是一種設(shè)計(jì)思想或者實(shí)現(xiàn)機(jī)制,而 O/R Mapper指以O(shè)/R原理設(shè)計(jì)的持久化框架(Framework),包括 O/R機(jī)制還有 SQL自生成,事務(wù)處理,Cache管理等。


除了 ORM 技術(shù),還有以下幾種持久化技術(shù)

主動(dòng)域?qū)ο竽J?br />它是在實(shí)現(xiàn)中封裝了關(guān)系數(shù)據(jù)模型和數(shù)據(jù)訪問細(xì)節(jié)的一種形式。在 J2EE 架構(gòu)中,EJB 組件分為會(huì)話 EJB 和實(shí)體 EJB。會(huì)話 EJB 通常實(shí)現(xiàn)業(yè)務(wù)邏輯,而實(shí)體 EJB 表示業(yè)務(wù)實(shí)體。實(shí)體 EJB 又分為兩種:由 EJB 本身管理持久化,即 BMP(Bean-Managed Persistence);有 EJB 容器管理持久化,即 CMP(Container-Managed Persistence)。BM P就是主動(dòng)域?qū)ο竽J降囊粋€(gè)例子,BMP 表示由實(shí)體 EJB 自身管理數(shù)據(jù)訪問細(xì)節(jié)。
主動(dòng)域?qū)ο蟊旧砦挥跇I(yè)務(wù)邏輯層,因此采用主動(dòng)域?qū)ο竽J綍r(shí),整個(gè)應(yīng)用仍然是三層應(yīng)用結(jié)構(gòu),并沒有從業(yè)務(wù)邏輯層分離出獨(dú)立的持久化層。

JDO 模式
Java Data Objects(JDO)是 SUN 公司制定的描述對象持久化語義的標(biāo)準(zhǔn)API。嚴(yán)格的說,JDO 并不是對象-關(guān)系映射接口,因?yàn)樗С职褜ο蟪志没饺我庖环N存儲(chǔ)系統(tǒng)中,包括 關(guān)系數(shù)據(jù)庫、面向?qū)ο蟮臄?shù)據(jù)庫、基于 XML 的數(shù)據(jù)庫,以及其他專有存儲(chǔ)系統(tǒng)。由于關(guān)系數(shù)據(jù)庫是目前最流行的存儲(chǔ)系統(tǒng),許多 JDO 的實(shí)現(xiàn)都包含了對象-關(guān)系映射服務(wù)。

CMP 模式
在 J2EE 架構(gòu)中,CMP(Container-Managed Persistence)表示由 EJB 容器來管理實(shí)體 EJB 的持久化,EJB 容器封裝了對象-關(guān)系的映射及數(shù)據(jù)訪問細(xì)節(jié)。CMP 和 ORM 的相似之處在于,兩者都提供對象-關(guān)系映射服務(wù),都把對象持久化的任務(wù)從業(yè)務(wù)邏輯中分離出來。區(qū)別在于 CMP 負(fù)責(zé)持久化實(shí)體 EJB 組件,而 ORM 負(fù)責(zé)持久化 POJO,它是普通的基于 Java Bean 形式的實(shí)體域?qū)ο蟆?/p>

一般把基于 Java Bean 形式的實(shí)體域?qū)ο蠓Q為 POJO(Plain Old Java Object),意為又普通又古老的 Java 對象的意思。隨著各種 ORM 映射工具的日趨成熟和流行,POJO有重現(xiàn)光彩,它和基于 CMP 的實(shí)體 EJB 相比,即簡單又具有很高的可移植性,因此聯(lián)合使用 ORM 映射工具和 POJO,已經(jīng)成為一種越來越受歡迎的且用來取代 CMP 的持久化方案。POJO 的缺點(diǎn)就是無法做遠(yuǎn)程調(diào)用,不支持分布式計(jì)算。


為什么要做持久化和ORM設(shè)計(jì)

在目前的企業(yè)應(yīng)用系統(tǒng)設(shè)計(jì)中,MVC,即 Model(模型)- View(視圖)- Control(控制)為主要的系統(tǒng)架構(gòu)模式。MVC 中的 Model 包含了復(fù)雜的業(yè)務(wù)邏輯和數(shù)據(jù)邏輯,以及數(shù)據(jù)存取機(jī)制(如 JDBC的連接、SQL生成和Statement創(chuàng)建、還有ResultSet結(jié)果集的讀取等)等。將這些復(fù)雜的業(yè)務(wù)邏輯和數(shù)據(jù)邏輯分離,以將系統(tǒng)的緊耦合關(guān)系轉(zhuǎn)化為松耦合關(guān)系(即解耦合),是降低系統(tǒng)耦合度迫切要做的,也是持久化要做的工作。MVC 模式實(shí)現(xiàn)了架構(gòu)上將表現(xiàn)層(即View)和數(shù)據(jù)處理層(即Model)分離的解耦合,而持久化的設(shè)計(jì)則實(shí)現(xiàn)了數(shù)據(jù)處理層內(nèi)部的業(yè)務(wù)邏輯和數(shù)據(jù)邏輯分離的解耦合。而 ORM 作為持久化設(shè)計(jì)中的最重要也最復(fù)雜的技術(shù),也是目前業(yè)界熱點(diǎn)技術(shù)。

簡單來說,按通常的系統(tǒng)設(shè)計(jì),使用 JDBC 操作數(shù)據(jù)庫,業(yè)務(wù)處理邏輯和數(shù)據(jù)存取邏輯是混雜在一起的。
一般基本都是如下幾個(gè)步驟:
1、建立數(shù)據(jù)庫連接,獲得 Connection 對象。
2、根據(jù)用戶的輸入組裝查詢 SQL 語句。
3、根據(jù) SQL 語句建立 Statement 對象 或者 PreparedStatement 對象。
4、用 Connection 對象執(zhí)行 SQL語句,獲得結(jié)果集 ResultSet 對象。
5、然后一條一條讀取結(jié)果集 ResultSet 對象中的數(shù)據(jù)。
6、根據(jù)讀取到的數(shù)據(jù),按特定的業(yè)務(wù)邏輯進(jìn)行計(jì)算。
7、根據(jù)計(jì)算得到的結(jié)果再組裝更新 SQL 語句。
8、再使用 Connection 對象執(zhí)行更新 SQL 語句,以更新數(shù)據(jù)庫中的數(shù)據(jù)。
7、最后依次關(guān)閉各個(gè) Statement 對象和 Connection 對象。

由上可看出代碼邏輯非常復(fù)雜,這還不包括某條語句執(zhí)行失敗的處理邏輯。其中的業(yè)務(wù)處理邏輯和數(shù)據(jù)存取邏輯完全混雜在一塊。而一個(gè)完整的系統(tǒng)要包含成千上萬個(gè)這樣重復(fù)的而又混雜的處理過程,假如要對其中某些業(yè)務(wù)邏輯或者一些相關(guān)聯(lián)的業(yè)務(wù)流程做修改,要改動(dòng)的代碼量將不可想象。另一方面,假如要換數(shù)據(jù)庫產(chǎn)品或者運(yùn)行環(huán)境也可能是個(gè)不可能完成的任務(wù)。而用戶的運(yùn)行環(huán)境和要求卻千差萬別,我們不可能為每一個(gè)用戶每一種運(yùn)行環(huán)境設(shè)計(jì)一套一樣的系統(tǒng)。
所以就要將一樣的處理代碼即業(yè)務(wù)邏輯和可能不一樣的處理即數(shù)據(jù)存取邏輯分離開來,另一方面,關(guān)系型數(shù)據(jù)庫中的數(shù)據(jù)基本都是以一行行的數(shù)據(jù)進(jìn)行存取的,而程序運(yùn)行卻是一個(gè)個(gè)對象進(jìn)行處理,而目前大部分?jǐn)?shù)據(jù)庫驅(qū)動(dòng)技術(shù)(如ADO.NET、JDBC、ODBC等等)均是以行集的結(jié)果集一條條進(jìn)行處理的。所以為解決這一困難,就出現(xiàn) ORM 這一個(gè)對象和數(shù)據(jù)之間映射技術(shù)。

舉例來說,比如要完成一個(gè)購物打折促銷的程序,用 ORM 思想將如下實(shí)現(xiàn)(引自《深入淺出Hibernate》):
業(yè)務(wù)邏輯如下:
public Double calcAmount(String customerid, double amount)
{
??? // 根據(jù)客戶ID獲得客戶記錄
??? Customer customer = CustomerManager.getCustomer(custmerid);
??? // 根據(jù)客戶等級獲得打折規(guī)則
??? Promotion promotion = PromotionManager.getPromotion(customer.getLevel());
??? // 累積客戶總消費(fèi)額,并保存累計(jì)結(jié)果
??? customer.setSumAmount(customer.getSumAmount().add(amount);
??? CustomerManager.save(customer);
??? // 返回打折后的金額
??? return amount.multiply(protomtion.getRatio());
}
這樣代碼就非常清晰了,而且與數(shù)據(jù)存取邏輯完全分離。設(shè)計(jì)業(yè)務(wù)邏輯代碼的時(shí)候完全不需要考慮數(shù)據(jù)庫JDBC的那些千篇一律的操作,而將它交給 CustomerManager 和 PromotionManager 兩個(gè)類去完成。這就是一個(gè)簡單的 ORM 設(shè)計(jì),實(shí)際的 ORM 實(shí)現(xiàn)框架比這個(gè)要復(fù)雜的多。


目前有哪些流行的 ORM 產(chǎn)品
目前眾多廠商和開源社區(qū)都提供了持久層框架的實(shí)現(xiàn),常見的有
Apache OJB (http://db.apache.org/ojb/
Cayenne (http://objectstyle.org/cayenne/
Jaxor (http://jaxor.sourceforge.net
Hibernate (http://www.hibernate.org
iBatis (http://www.ibatis.com
jRelationalFramework (http://ijf.sourceforge.net
mirage (http://itor.cq2.org/en/oss/mirage/toon
SMYLE (http://www.drjava.de/smyle
TopLink (http://otn.oracle.com/products/ias/toplink/index.html
其中 TopLink 是 Oracle 的商業(yè)產(chǎn)品,其他均為開源項(xiàng)目。

其中 Hibernate 的輕量級 ORM 模型逐步確立了在 Java ORM 架構(gòu)中領(lǐng)導(dǎo)地位,甚至取代復(fù)雜而又繁瑣的 EJB 模型而成為事實(shí)上的 Java ORM 工業(yè)標(biāo)準(zhǔn)。而且其中的許多設(shè)計(jì)均被 J2EE 標(biāo)準(zhǔn)組織吸納而成為最新 EJB 3.0 規(guī)范的標(biāo)準(zhǔn),這也是開源項(xiàng)目影響工業(yè)領(lǐng)域標(biāo)準(zhǔn)的有力見證。


參考文獻(xiàn):1、《深入淺出Hibernate》
???????? 2、《精通Hibernate:Java對象持久化技術(shù)詳解》



橘子 2006-06-26 09:42 發(fā)表評論
]]>
CVS命令篇(二)http://www.tkk7.com/forget/archive/2006/06/22/54416.html橘子橘子Thu, 22 Jun 2006 01:29:00 GMThttp://www.tkk7.com/forget/archive/2006/06/22/54416.htmlhttp://www.tkk7.com/forget/comments/54416.htmlhttp://www.tkk7.com/forget/archive/2006/06/22/54416.html#Feedback0http://www.tkk7.com/forget/comments/commentRss/54416.htmlhttp://www.tkk7.com/forget/services/trackbacks/54416.html關(guān)鍵詞:CVS CVSWeb CVSTrac WinCVS CVSROOT

內(nèi)容摘要:

CVS是一個(gè)C/S系統(tǒng),多個(gè)開發(fā)人員通過一個(gè)中心版本控制系統(tǒng)來記錄文件版本,從而達(dá)到保證
文件同步的目的。工作模式如下:

       CVS服務(wù)器(文件版本庫)

/ | \

(版 本 同 步)

/ | \

開發(fā)者1 開發(fā)者2 開發(fā)者3




作為一般開發(fā)人員挑選2,6看就可以了,CVS的管理員則更需要懂的更多一些,最后還簡單介紹了
一些Windows下的cvs客戶端使用,CVS遠(yuǎn)程用戶認(rèn)證的選擇及與BUG跟蹤系統(tǒng)等開發(fā)環(huán)境的集成
問題。

  1. CVS環(huán)境初始化 :CVS環(huán)境的搭建 管理員
  2. CVS的日常使用 :日常開發(fā)中最常用的CVS命令, 開發(fā)人員 管理員
  3. CVS的分支開發(fā) :項(xiàng)目按照不同進(jìn)度和目標(biāo)并發(fā)進(jìn)行 管理員
  4. CVS的用戶認(rèn)證 :通過SSH的遠(yuǎn)程用戶認(rèn)證,安全,簡單 管理員
  5. CVSWEB :CVS的WEB訪問界面大大提高代碼版本比較的效率 管理員
  6. CVS TAG :將$Id$ 加入代碼注釋中,方便開發(fā)過程的跟蹤開發(fā)人員
  7. CVS vs VSS : CVS和Virsual SourceSafe的比較 開發(fā)人員 管理員
  8. WinCVS: 通過SSH認(rèn)證的WinCVS認(rèn)證設(shè)置
  9. 基于CVSTrac的小組開發(fā)環(huán)境搭建 :通過CVSTrac實(shí)現(xiàn)web界面的CVS
    用戶管理,集成的BUG跟蹤和WIKI交流
  10. CVS中的用戶權(quán)限管理 :基于系統(tǒng)用戶的CVS權(quán)限管理和基于CVSROOT/passwd
    的虛擬用戶管理

一個(gè)系統(tǒng)20%的功能往往能夠滿足80%的需求,CVS也不例外,以下是CVS最常用的功能,可能還不
到它全部命令選項(xiàng)的20%,作為一般開發(fā)人員平時(shí)會(huì)用cvs update和cvs commit就夠了,更多的需求在
實(shí)際應(yīng)用過程中自然會(huì)出現(xiàn),不時(shí)回頭看看相關(guān)文檔經(jīng)常有意外的收獲。


CVS環(huán)境初始化

環(huán)境設(shè)置:指定CVS庫的路徑CVSROOT

tcsh
setenv CVSROOT /path/to/cvsroot
bash
CVSROOT=/path/to/cvsroot ; export CVSROOT

后面還提到遠(yuǎn)程CVS服務(wù)器的設(shè)置:
CVSROOT=:ext:$USER@test.server.address#port:/path/to/cvsroot CVS_RSH=ssh;
export CVSROOT CVS_RSH

初始化:CVS版本庫的初始化。
cvs init

一個(gè)項(xiàng)目的首次導(dǎo)入
cvs import -m "write some comments here" project_name vendor_tag release_tag
執(zhí)行后:會(huì)將所有源文件及目錄導(dǎo)入到/path/to/cvsroot/project_name目錄下
vender_tag: 開發(fā)商標(biāo)記
release_tag: 版本發(fā)布標(biāo)記

項(xiàng)目導(dǎo)出:將代碼從CVS庫里導(dǎo)出
cvs checkout project_name
cvs 將創(chuàng)建project_name目錄,并將最新版本的源代碼導(dǎo)出到相應(yīng)目錄中。這個(gè)checkout和Virvual SourceSafe中的check out不是一個(gè)概念,相對于Virvual SourceSafe的check out是cvs update,
check in是cvs commit。


CVS的日常使用

注意:第一次導(dǎo)出以后,就不是通過cvs checkout來同步文件了,而是要進(jìn)入剛才cvs checkout
project_name導(dǎo)出的project_name目錄下進(jìn)行具體文件的版本同步(添加,修改,刪除)操作。

將文件同步到最新的版本
cvs update
不制定文件名,cvs將同步所有子目錄下的文件,也可以制定某個(gè)文件名/目錄進(jìn)行同步
cvs update file_name
最好每天開始工作前或?qū)⒆约旱墓ぷ鲗?dǎo)入到CVS庫里前都要做一次,并養(yǎng)成“先同步 后修改”的習(xí)
慣,和Virvual SourceSafe不同,CVS里沒有文件鎖定的概念,所有的沖突是在commit之前解決,如果
你修改過程中,有其他人修改并commit到了CVS 庫中,CVS會(huì)通知你文件沖突,并自動(dòng)將沖突部分用
>>>>>>
content on cvs server
<<<<<<
content in your file
>>>>>>
標(biāo)記出來,由你確認(rèn)沖突內(nèi)容的取舍。
版本沖突一般是在多個(gè)人修改一個(gè)文件造成的,但這種項(xiàng)目管理上的問題不應(yīng)該指望由CVS來解決。

確認(rèn)修改寫入到CVS庫里
cvs commit -m "write some comments here" file_name

注意:CVS的很多動(dòng)作都是通過cvs commit進(jìn)行最后確認(rèn)并修改的,最好每次只修改一個(gè)文件。在確認(rèn)
的前,還需要用戶填寫修改注釋,以幫助其他開發(fā)人員了解修改的原因。如果不用寫-m "comments"而
直接確認(rèn)`cvs commit file_name` 的話,cvs會(huì)自動(dòng)調(diào)用系統(tǒng)缺省的文字編輯器(一般是vi)要求你寫入注釋。
注釋的質(zhì)量很重要:所以不僅必須要寫,而且必須寫一些比較有意義的內(nèi)容:以方便其他開發(fā)人員能
夠很好的理解不好的注釋,很難讓其他的開發(fā)人員快速的理解:比如: -m "bug fixed" 甚至 -m ""
好的注釋,甚至可以用中文: -m "在用戶注冊過程中加入了Email地址校驗(yàn)"


修改某個(gè)版本注釋:每次只確認(rèn)一個(gè)文件到CVS庫里是一個(gè)很好的習(xí)慣,但難免有時(shí)候忘了指定文件
名,把多個(gè)文件以同樣注釋commit到CVS庫里了,以下命令可以允許你修改某個(gè)文件某個(gè)版本的注釋:
cvs admin -m 1.3:"write some comments here" file_name

添加文件
創(chuàng)建好新文件后,比如:touch new_file
cvs add new_file
注意:對于圖片,Word文檔等非純文本的項(xiàng)目,需要使用cvs add -kb選項(xiàng)按2進(jìn)制文件方式導(dǎo)入(k表示
擴(kuò)展選項(xiàng),b表示binary),否則有可能出現(xiàn)文件被破壞的情況
比如:
cvs add -kb new_file.gif
cvs add -kb readme.doc

如果關(guān)鍵詞替換屬性在首次導(dǎo)入時(shí)設(shè)置錯(cuò)了怎么辦?
cvs admin -kkv new_file.css

然后確認(rèn)修改并注釋
cvs ci -m "write some comments here"

刪除文件
將某個(gè)源文件物理刪除后,比如:rm file_name
cvs rm file_name
然后確認(rèn)修改并注釋
cvs ci -m "write some comments here"
以上面前2步合并的方法為:
cvs rm -f file_name
cvs ci -m "why delete file"
注意:很多cvs命令都有縮寫形式:commit=>ci; update=>up; checkout=>co/get; remove=>rm;

添加目錄
cvs add dir_name

查看修改歷史
cvs log file_name
cvs history file_name

查看當(dāng)前文件不同版本的區(qū)別
cvs diff -r1.3 -r1.5 file_name
查看當(dāng)前文件(可能已經(jīng)修改了)和庫中相應(yīng)文件的區(qū)別
cvs diff file_name
cvs的web界面提供了更方便的定位文件修改和比較版本區(qū)別的方法,具體安裝設(shè)置請看后面的cvsweb
使用

正確的通過CVS恢復(fù)舊版本的方法
如果用cvs update -r1.2 file.name
這個(gè)命令是給file.name加一個(gè)STICK TAG: "1.2" ,雖然你的本意只是想將它恢復(fù)到1.2版本
正確的恢復(fù)版本的方法是:cvs update -p -r1.2 file_name >file_name
如果不小心已經(jīng)加成STICK TAG的話:用cvs update -A 解決

移動(dòng)文件/文件重命名
cvs里沒有cvs move或cvs rename,因?yàn)檫@兩個(gè)操作是可以由先cvs remove old_file_name,然后cvs add new_file_name實(shí)現(xiàn)的。

刪除/移動(dòng)目錄
最方便的方法是讓管理員直接移動(dòng),刪除CVSROOT里相應(yīng)目錄(因?yàn)镃VS一個(gè)項(xiàng)目下的子目錄都是
獨(dú)立的,移動(dòng)到$CVSROOT目錄下都可以作為新的獨(dú)立項(xiàng)目:好比一顆樹,其實(shí)砍下任意一枝都能獨(dú)
立存活),對目錄進(jìn)行了修改后,要求其開發(fā)人員重新導(dǎo)出項(xiàng)目cvs checkout project_name 或者用
cvs update -dP同步。

項(xiàng)目發(fā)布導(dǎo)出不帶CVS目錄的源文件
做開發(fā)的時(shí)候你可能注意到了,每個(gè)開發(fā)目錄下,CVS都創(chuàng)建了一個(gè)CVS/目錄。里面有文件用于記錄
當(dāng)前目錄和CVS庫之間的對應(yīng)信息。但項(xiàng)目發(fā)布的時(shí)候你一般不希望把文件目錄還帶著含有CVS信息
的CVS目錄吧,這個(gè)一次性的導(dǎo)出過程使用cvs export命令,不過export只能針對一個(gè)TAG或者日期導(dǎo)出,比如:
cvs export -r release1 project_name
cvs export -D 20021023 project_name
cvs export -D now project_name

CVS Branch:項(xiàng)目多分支同步開發(fā)

確認(rèn)版本里程碑:多個(gè)文件各自版本號不一樣,項(xiàng)目到一定階段,可以給所有文件統(tǒng)一指定一個(gè)階段
里程碑版本號,方便以后按照這個(gè)階段里程碑版本號導(dǎo)出項(xiàng)目,同時(shí)也是項(xiàng)目的多個(gè)分支開發(fā)的基礎(chǔ)。

cvs tag release_1_0

開始一個(gè)新的里程碑
cvs commit -r 2 標(biāo)記所有文件開始進(jìn)入2.x的開發(fā)

注意:CVS里的revsion和軟件包的發(fā)布版本可以沒有直接的關(guān)系。但所有文件使用和發(fā)布版本一致的
版本號比較有助于維護(hù)。

版本分支的建立
在開發(fā)項(xiàng)目的2.x版本的時(shí)候發(fā)現(xiàn)1.x有問題,但2.x又不敢用,則從先前標(biāo)記的里程碑:release_1_0導(dǎo)出
一個(gè)分支 release_1_0_patch
cvs rtag -b -r release_1_0 release_1_0_patch proj_dir

一些人先在另外一個(gè)目錄下導(dǎo)出release_1_0_patch這個(gè)分支:解決1.0中的緊急問題,
cvs checkout -r release_1_0_patch
而其他人員仍舊在項(xiàng)目的主干分支2.x上開發(fā)

在release_1_0_patch上修正錯(cuò)誤后,標(biāo)記一個(gè)1.0的錯(cuò)誤修正版本號
cvs tag release_1_0_patch_1

如果2.0認(rèn)為這些錯(cuò)誤修改在2.0里也需要,也可以在2.0的開發(fā)目錄下合并release_1_0_patch_1中的修改到
當(dāng)前代碼中:
cvs update -j release_1_0_patch_1

CVS的遠(yuǎn)程認(rèn)證通過SSH遠(yuǎn)程訪問CVS

使用cvs本身基于pserver的遠(yuǎn)程認(rèn)證很麻煩,需要定義服務(wù)器和用戶組,用戶名,設(shè)置密碼等,

常見的登陸格式如下:
cvs -d :pserver:cvs_user_name@cvs.server.address:/path/to/cvsroot login
例子:
cvs -d :pserver:cvs@samba.org:/cvsroot login

不是很安全,因此一般是作為匿名只讀CVS訪問的方式。從安全考慮,通過系統(tǒng)本地帳號認(rèn)證并通過
SSH傳輸是比較好的辦法,通過在客戶機(jī)的 /etc/profile里設(shè)置一下內(nèi)容:
CVSROOT=:ext:$USER@cvs.server.address#port:/path/to/cvsroot CVS_RSH=ssh; export CVSROOT CVS_RSH
所有客戶機(jī)所有本地用戶都可以映射到CVS服務(wù)器相應(yīng)同名帳號了。

比如:

CVS服務(wù)器是192.168.0.3,上面CVSROOT路徑是/home/cvsroot,另外一臺開發(fā)客戶機(jī)是192.168.0.4,
如果 tom在2臺機(jī)器上都有同名的帳號,那么從192.168.0.4上設(shè)置了:
export CVSROOT=:ext:tom@192.168.0.3:/home/cvsroot
export CVS_RSH=ssh
tom就可以直接在192.168.0.4上對192.168.0.3的cvsroot進(jìn)行訪問了(如果有權(quán)限的話)
cvs checkout project_name
cd project_name
cvs update
...
cvs commit

如果CVS所在服務(wù)器的SSH端口不在缺省的22,或者和客戶端與CVS服務(wù)器端SSH缺省端口不一致,
有時(shí)候設(shè)置了:
:ext:$USER@test.server.address#port:/path/to/cvsroot

仍然不行,比如有以下錯(cuò)誤信息:
ssh: test.server.address#port: Name or service not known
cvs [checkout aborted]: end of file from server (consult above messages if any)

解決的方法是做一個(gè)腳本指定端口轉(zhuǎn)向(不能使用alias,會(huì)出找不到文件錯(cuò)誤):
創(chuàng)建一個(gè)/usr/bin/ssh_cvs文件,假設(shè)遠(yuǎn)程服務(wù)器的SSH端口是非缺省端口:34567
#!/bin/sh
/usr/bin/ssh -p 34567 "$@"
然后:chmod +x /usr/bin/ssh_cvs
并CVS_RSH=ssh_cvs; export CVS_RSH

注意:port是指相應(yīng)服務(wù)器SSH的端口,不是指cvs專用的pserver的端口

CVSWEB:提高文件瀏覽效率

CVSWEB就是CVS的WEB界面,可以大大提高程序員定位修改的效率:

使用的樣例可以看:http://www.freebsd.org/cgi/cvsweb.cgi

CVSWEB的下載:CVSWEB從最初的版本已經(jīng)演化出很多功能界面更豐富的版本,這個(gè)是我個(gè)人感
覺安裝設(shè)置比較方便的:
原先在:http://www.spaghetti-code.de/software/linux/cvsweb/,但目前已經(jīng)刪除,目前仍可以在本站下載CVSWEB,其實(shí)最近2年FreeBSD的CVSWeb項(xiàng)目已經(jīng)有了更好的發(fā)展吧,而當(dāng)初沒有用FreeBSD那個(gè)
版本主要就是因?yàn)闆]有彩色的文件Diff功能。
下載解包:
tar zxf cvsweb.tgz
把配置文件cvsweb.conf放到安全的地方(比如和apache的配置放在同一個(gè)目錄下),
修改:cvsweb.cgi讓CGI找到配置文件:
$config = $ENV{'CVSWEB_CONFIG'} || '/path/to/apache/conf/cvsweb.conf';

轉(zhuǎn)到/path/to/apache/conf下并修改cvsweb.conf:

  1. 修改CVSROOT路徑設(shè)置:
    %CVSROOT = (
    'Development' => '/path/to/cvsroot', #<==修改指向本地的CVSROOT
    );
  2. 缺省不顯示已經(jīng)刪除的文檔:
    "hideattic" => "1",#<==缺省不顯示已經(jīng)刪除的文檔
  3. 在配置文件cvsweb.conf中還可以定制頁頭的描述信息,你可以修改$long_intro成你需要的文字

CVSWEB可不能隨便開放給所有用戶,因此需要使用WEB用戶認(rèn)證:
先生成 passwd:
/path/to/apache/bin/htpasswd -c cvsweb.passwd user

修改httpd.conf: 增加
<Directory "/path/to/apache/cgi-bin/cvsweb/">
AuthName "CVS Authorization"
AuthType Basic
AuthUserFile /path/to/cvsweb.passwd
require valid-user
</Directory>

CVS TAGS: $Id: cvs_card.html,v 1.5 2003/03/09 08:41:46

chedong Exp $

將$Id: cvs_card.html,v 1.9 2003/11/09 07:57:11 chedong Exp $ 加在程序文件開頭的注釋里是一個(gè)很好
的習(xí)慣,cvs能夠自動(dòng)解釋更新其中的內(nèi)容成:file_name version time user_name 的格式,比如:
cvs_card.txt,v 1.1 2002/04/05 04:24:12 chedong Exp,可以這些信息了解文件的最后修改人和修改時(shí)間


幾個(gè)常用的缺省文件:
default.php
<?php
/*
* Copyright (c) 2002 Company Name.
* $Header: /home/cvsroot/tech/cvs_card.html,v 1.9 2003/11/09 07:57:11
chedong Exp $

*/

?>
====================================
Default.java: 注意文件頭一般注釋用 /* 開始 JAVADOC注釋用 /** 開始的區(qū)別
/*
* Copyright (c) 2002 MyCompany Name.
* $Header: /home/cvsroot/tech/cvs_card.html,v 1.9 2003/11/09 07:57:11
chedong Exp $

*/

package com.mycompany;

import java.;

/**
* comments here
*/
public class Default {
/**
* Comments here
* @param
* @return
*/
public toString() {

}
}
====================================
default.pl:
#!/usr/bin/perl -w
# Copyright (c) 2002 Company Name.
# $Header: /home/cvsroot/tech/cvs_card.html,v 1.9 2003/11/09 07:57:11
chedong Exp $


# file comments here

use strict;

CVS vs VSS

CVS沒有文件鎖定模式,VSS在check out同時(shí),同時(shí)記錄了文件被導(dǎo)出者鎖定。

CVS的update和commit, VSS是get_lastest_version和check in

對應(yīng)VSS的check out/undo check out的CVS里是edit和unedit

在CVS中,標(biāo)記自動(dòng)更新功能缺省是打開的,這樣也帶來一個(gè)潛在的問題,就是不用-kb方式添加
binary文件的話在cvs自動(dòng)更新時(shí)可能會(huì)導(dǎo)致文件失效。

$Header: /home/cvsroot/tech/cvs_card.html,v 1.5 2003/03/09 08:41:46 chedong Exp $ $Date: 2003/11/09
07:57:11 $這樣的標(biāo)記在Virsual SourceSafe中稱之為Keyword Explaination,缺省是關(guān)閉
的,需要通過OPITION打開,并指定需要進(jìn)行源文件關(guān)鍵詞掃描的文件類型:*.txt,*.java, *.html...

對于Virsual SourceSafe和CVS都通用的TAG有:
$Header: /home/cvsroot/tech/cvs_card.html,v 1.5 2003/03/09 08:41:46 chedong Exp $
$Author: chedong $
$Date: 2003/11/09 07:57:11 $
$Revision: 1.9 $

我建議盡量使用通用的關(guān)鍵詞保證代碼在CVS和VSS都能方便的跟蹤。

WinCVS

下載:

cvs Windows客戶端:目前穩(wěn)定版本為1.2
http://cvsgui.sourceforge.net
ssh Windows客戶端
http://www.networksimplicity.com/openssh/

安裝好以上2個(gè)軟件以后:
WinCVS客戶端的admin==>preference設(shè)置
1 在general選單里
設(shè)置CVSROOT: username@192.168.0.123:/home/cvsroot
設(shè)置Authorization: 選擇SSH server

2 Port選單里
鉤上:check for alternate rsh name
并設(shè)置ssh.exe的路徑,缺省是裝在 C:\Program Files\NetworkSimplicity\ssh\ssh.exe

然后就可以使用WinCVS進(jìn)行cvs操作了,所有操作都會(huì)跳出命令行窗口要求你輸入服務(wù)器端的認(rèn)
證密碼。

當(dāng)然,如果你覺得這樣很煩的話,還有一個(gè)辦法就是生成一個(gè)沒有密碼的公鑰/私鑰對,并設(shè)置
CVS使用基于公鑰/私鑰的SSH認(rèn)證(在general 選單里)。

可以選擇的diff工具:examdiff
下載:
http://www.prestosoft.com/examdiff/examdiff.htm
還是在WinCVS菜單admin==>preference的WinCVS選單里
選上:Externel diff program
并設(shè)置diff工具的路徑,比如:C:\Program Files\ed16i\ExamDiff.exe
在對文件進(jìn)行版本diff時(shí),第一次需要將窗口右下角的use externel diff選上。

基于CVSTrac的小組開發(fā)環(huán)境搭建

作為一個(gè)小組級的開發(fā)環(huán)境,版本控制系統(tǒng)和BUG跟蹤系統(tǒng)等都涉及到用戶認(rèn)證部分。如何方便的
將這些系統(tǒng)集成起來是一個(gè)非常困難的事情,畢竟我們不能指望 Linux下有像Source Offsite那樣集成
度很高的版本控制/BUG跟蹤集成系統(tǒng)。

我個(gè)人是很反對使用pserver模式的遠(yuǎn)程用戶認(rèn)證的,但如果大部分組員使用WINDOWS客戶端進(jìn)行
開發(fā)的話,總體來說使用 CVSROOT/passwd認(rèn)證還是很難避免的,但CVS本身用戶的管理比較麻煩
本來我打算自己用perl寫一個(gè)管理界面的,直到我發(fā)現(xiàn)了 CVSTrac:一個(gè)基于WEB界面的BUG跟蹤
系統(tǒng),它外掛在CVS系統(tǒng)上的BUG跟蹤系統(tǒng),其中就包括了WEB界面的CVSROOT/passwd文件的管
理,甚至還集成了WIKI討論組功能。

這里首先說一下CVS的pserver模式下的用戶認(rèn)證,CVS的用戶認(rèn)證服務(wù)是基于inetd中的:
cvspserver stream tcp nowait apache /usr/bin/cvs cvs --allow-root=/home/cvsroot pserver
一般在2401端口(這個(gè)端口號很好記:49的平方)

CVS用戶數(shù)據(jù)庫是基于CVSROOT/passwd文件,文件格式:
[username]:[crypt_password]:[mapping_system_user]
由于密碼都用的是UNIX標(biāo)準(zhǔn)的CRYPT加密,這個(gè)passwd文件的格式基本上是apache的htpasswd格式
的擴(kuò)展(比APACHE的 PASSWD文件多一個(gè)系統(tǒng)用戶映射字段),所以這個(gè)文件最簡單的方法可
以用
apache/bin/htpasswd -b myname mypassword
創(chuàng)建。注意:通過htpasswd創(chuàng)建出來的文件會(huì)沒有映射系統(tǒng)用戶的字段
例如:
new:geBvosup/zKl2
setup:aISQuNAAoY3qw
test:hwEpz/BX.rEDU

映射系統(tǒng)用戶的目的在于:你可以創(chuàng)建一個(gè)專門的CVS服務(wù)帳號,比如用apache的運(yùn)行用戶apache,
并將/home/cvsroot目錄下的所有權(quán)限賦予這個(gè)用戶,然后在passwd文件里創(chuàng)建不同的開發(fā)用戶帳號,
但開發(fā)用戶帳號最后的文件讀寫權(quán)限都映射為apache用戶,在SSH模式下多個(gè)系統(tǒng)開發(fā)用戶需要在
同一個(gè)組中才可以相互讀寫CVS庫中的文件。

進(jìn)一步的,你可以將用戶分別映射到apache這個(gè)系統(tǒng)用戶上。
new:geBvosup/zKl2:apache
setup:aISQuNAAoY3qw:apache
test:hwEpz/BX.rEDU:apache

CVSTrac很好的解決了CVSROOT/passwd的管理問題,而且包含了BUG跟蹤報(bào)告系統(tǒng)和集成WIKI交

功能等,使用的 CGI方式的安裝,并且基于GNU Public License

在inetd里加入cvspserver服務(wù):
cvspserver stream tcp nowait apache /usr/bin/cvs cvs --allow-root=/home/cvsroot pserver

xietd的配置文件:%cat cvspserver
service cvspserver
{
disable = no
socket_type = stream
wait = no
user = apache
server = /usr/bin/cvs
server_args = -f --allow-root=/home/cvsroot pserver
log_on_failure += USERID
}

注意:這里的用戶設(shè)置成apache目的是和/home/cvsroot的所有用戶一致,并且必須讓這個(gè)這個(gè)用戶對/home/cvsroot/下的 CVSROOT/passwd和cvstrac初始化生成的myproj.db有讀取權(quán)限。

安裝過程

  1. 下載:可以從http://www.cvstrac.org 下載
    我用的是已經(jīng)在Linux上編譯好的應(yīng)用程序包:cvstrac-1.1.2.bin.gz,
    %gzip -d cvstrac-1.1.2.bin.gz
    %chmod +x cvstrac-1.1.2.bin
    #mv cvstarc-1.1.1.bin /usr/bin/cvstrac
    如果是從源代碼編譯:
    從 http://www.sqlite.org/download.html 下載SQLITE的rpm包:
    rpm -i sqlite-devel-2.8.6-1.i386.rpm
    從 ftp://ftp.cvstrac.org/cvstrac/ 下載軟件包
    解包,假設(shè)解包到/home/chedong/cvstrac-1.1.2下,并規(guī)劃將cvstrac安裝到/usr/local/bin目錄下, cd /home/chedong/cvstrac-1.1.2 編輯linux-gcc.mk:
    修改:
    SRCDIR = /home/chedong/cvstrac-1.1.2
    INSTALLDIR = /usr/local/bin
    然后
    mv linux-gcc.mk Makefile
    make
    #make install

  2. 初始化cvstrac數(shù)據(jù)庫:假設(shè)數(shù)據(jù)庫名是 myproj
    在已經(jīng)裝好的CVS服務(wù)器上(CVS庫這時(shí)候應(yīng)該已經(jīng)是初始化好了,比如:cvs init初始化在/home/cvsroot里),運(yùn)行一下
    %cvstrac init /home/cvsroot myproj
    運(yùn)行后,/home/cvsroot里會(huì)有一個(gè)的myproj.db庫,使用CVSTRAC服務(wù),/home/cvsroot/myproj.db /home/cvsroot/CVSROOT/readers
    /home/cvsroot/CVSROOT/writers /home/cvsroot/CVSROOT/passwd這幾個(gè)文件對于web服務(wù)的運(yùn)行
    用戶應(yīng)該是可寫的,在RedHat8上,缺省就有一個(gè)叫 apache用戶和一個(gè)apache組,所以在
    httpd.conf文件中設(shè)置了用apache用戶運(yùn)行web服務(wù):
    User apache
    Group apache,
    然后設(shè)置屬于apache用戶和apache組
    #chown -R apache:apache /home/cvsroot
    -rw-r--r-- 1 apache apache 55296 Jan 5 19:40 myproj.db
    drwxrwxr-x 3 apache apache 4096 Oct 24 13:04 CVSROOT/
    drwxrwxr-x 2 apache apache 4096 Aug 30 19:47 some_proj/
    此外還在/home/cvsroot/CVSROOT中設(shè)置了:
    chmod 664 readers writers passwd
  3. 在apche/cgi-bin目錄中創(chuàng)建腳本cvstrac:
    #!/bin/sh
    /usr/bin/cvstrac cgi /home/cvsroot
    設(shè)置腳本可執(zhí)行:
    chmod +x /home/apache/cgi-bin/cvstrac
  4. 從 http://cvs.server.address/cgi-bin/cvstrac/myproj 進(jìn)入管理界面
    缺省登錄名:setup 密碼 setup
    對于一般用戶可以從:
    http://cvs.server.address/cgi-bin/cvstrac/myproj
  5. 在setup中重新設(shè)置了CVSROOT的路徑后,/home/cvsroot
    如果是初次使用需要在/home/cvsroot/CVSROOT下創(chuàng)建passwd, readers, writers文件
    touch passwd readers writers
    然后設(shè)置屬于apache用戶,
    chown apache.apache passwd readers writers
    這樣使用setup用戶創(chuàng)建新用戶后會(huì)同步更新CVSROOT/passwd下的帳號

修改登錄密碼,進(jìn)行BUG報(bào)告等,
更多使用細(xì)節(jié)可以在使用中慢慢了解。

對于前面提到的WinCVS在perference里設(shè)置:
CVSROOT欄輸入:username@ip.address.of.cvs:/home/cvsroot
Authenitication選擇:use passwd file on server side
就可以了從服務(wù)器上進(jìn)行CVS操作了。

CVS的用戶權(quán)限管理

CVS的權(quán)限管理分2種策略:

  • 基于系統(tǒng)文件權(quán)限的系統(tǒng)用戶管理:適合多個(gè)在Linux上使用系統(tǒng)帳號的開發(fā)人員進(jìn)行開發(fā)。
  • 基于CVSROOT/passwd的虛擬用戶管理:適合多個(gè)在Windows平臺上的開發(fā)人員將帳號映射
    成系統(tǒng)帳號使用。
為什么使用apache/apache用戶?首先RedHat8中缺省就有了,而且使用這個(gè)用戶可以方便通過cvstrac
進(jìn)行WEB管理。
chown -R apache.apache /home/cvsroot
chmod 775 /home/cvsroot

Linux上通過ssh連接CVS服務(wù)器的多個(gè)開發(fā)人員:通過都屬于apache組實(shí)現(xiàn)文件的共享讀寫開發(fā)人員
有開發(fā)服務(wù)器上的系統(tǒng)帳號:sysuser1 sysuser2,設(shè)置讓他們都屬于apache組,因?yàn)橥ㄟ^cvs新導(dǎo)入的
項(xiàng)目都是對組開放的:664權(quán)限的,這樣無論那個(gè)系統(tǒng)用戶導(dǎo)入的項(xiàng)目文件,只要文件的組宿主是apache,所有其他同組系統(tǒng)開發(fā)用戶就都可以讀寫;基于ssh遠(yuǎn)程認(rèn)證的也是一樣。

? ?apache(system group)
/ ? ? ? ? ? ?| ? ? ? ? ? \
sysuser1 ? sysuser2 ? ? sysuser3

Windows上通過cvspserver連接CVS服務(wù)器的多個(gè)開發(fā)人員:通過在passwd文件種映射成 apache用戶
實(shí)現(xiàn)文件的共享讀寫
他們的帳號通過CVSROOT/passwd和readers writers這幾個(gè)文件管理;通過cvstrac設(shè)置所有
虛擬用戶都映射到apache用戶上即可。

? ?apache(system user)
/ ? ? ? ? ? ?| ? ? ? ? ? ?\
windev1 ? ? windev2 ? ? ?windev3? ? ? ? ? ? ?

利用CVS WinCVS/CVSWeb/CVSTrac 構(gòu)成了一個(gè)相對完善的跨平臺工作組開發(fā)版本控制環(huán)境。

相關(guān)資源:

CVS HOME:
http://www.cvshome.org

CVS FAQ:
http://www.loria.fr/~molli/cvs-index.html

相關(guān)網(wǎng)站:
http://directory.google.com/Top/Computers/Software/Configuration_Management/Tools/Concurrent_
Versions_System/

CVS--并行版本系統(tǒng)
http://www.soforge.com/cvsdoc/zh_CN/book1.html

CVS 免費(fèi)書:
http://cvsbook.red-bean.com/

CVS命令的速查卡片 refcards.com/refcards/cvs/

WinCVS:
http://cvsgui.sourceforge.net/

CVSTrac: A Web-Based Bug And Patch-Set Tracking System For CVS
http://www.cvstrac.org

StatCVS:基于CVS的代碼統(tǒng)計(jì)工具:按代碼量,按開發(fā)者的統(tǒng)計(jì)表等
http://sourceforge.net/projects/statcvs

如何在WEB開發(fā)中規(guī)劃CVS上:在Google上查 "cvs web development"
http://ccm.redhat.com/bboard-archive/cvs_for_web_development/index.html
轉(zhuǎn)載:作者: 車東 Email: chedongATbigfoot.com/chedongATchedong.com
http://flysun163.spaces.msn.com/blog/

橘子 2006-06-22 09:29 發(fā)表評論
]]>
CVSNT用戶管理方案篇http://www.tkk7.com/forget/archive/2006/06/22/54393.html橘子橘子Wed, 21 Jun 2006 17:28:00 GMThttp://www.tkk7.com/forget/archive/2006/06/22/54393.htmlhttp://www.tkk7.com/forget/comments/54393.htmlhttp://www.tkk7.com/forget/archive/2006/06/22/54393.html#Feedback0http://www.tkk7.com/forget/comments/commentRss/54393.htmlhttp://www.tkk7.com/forget/services/trackbacks/54393.html1、 CVSNT的用戶驗(yàn)證方式
我們這里所討論的是工作在pserver方式下。
在CVSNT的文檔中給出了兩種驗(yàn)證方式,我總結(jié)了一下,可以這樣稱呼:Window和CVSNT混合驗(yàn)證方式,CVSNT獨(dú)立驗(yàn)證方式。在前面的文章中,我們沒有詳細(xì)的給出這兩種方式的內(nèi)容,所講述的啟示就是混合驗(yàn)證方式。
決定CVSNT工作于何種驗(yàn)證方式是由CVS的管理文件來決定的,這些管理文件處在庫的目錄下的CVSROOT目錄中,這里可以得出結(jié)論,對于不同的庫,可以給不同的驗(yàn)證方式。所以,在每個(gè)庫建立的時(shí)候要首先設(shè)定好這些前提。
下面的操作如果沒有特殊指出則都是在客戶端來進(jìn)行管理的,下面首先是對一些控制原理和相關(guān)的文件做一些說明,如果你正在進(jìn)行相關(guān)的模擬操作,請停下來暫時(shí)停止你的操作,因?yàn)檫@些操作的步驟是有先后的,如果你順序不對,那么你可能就權(quán)限失效,進(jìn)行不了下面的操作了。
1.1 config文件
在庫建立好了以后,你還沒有對控制文件進(jìn)行修改之前,CVSNT是工作在混合驗(yàn)證方式之下的,這個(gè)時(shí)候,CVS服務(wù)器的管理員就是CVSNT的管理員,你以一個(gè)管理員身份登陸,檢出你要操作的庫的CVSROOT模塊,看一下文件列表,控制CVSNT的驗(yàn)證工作方式的是config文件,你可以在文件列表中找到它,雙擊看看其中的內(nèi)容,這里對我們最重要的就是第一個(gè)設(shè)置內(nèi)容,你會(huì)看到下面的內(nèi)容:
# Set this to `no' if pserver shouldn't check system users/passwords
#SystemAuth=yes
第二行就是我們要修改的內(nèi)容,默認(rèn)狀態(tài)是被注釋掉的,SystemAuth有兩個(gè)值yes和no
yes:pserver將使用系統(tǒng)用戶數(shù)據(jù)庫和passwd文件(這個(gè)文件后面會(huì)詳細(xì)講述)來共同驗(yàn)證(若passwd文件不存在或者文件中沒有相應(yīng)的資料,則用系統(tǒng)用戶來進(jìn)行驗(yàn)證)默認(rèn)為yes
no:所有的用戶必須在passwd中存在,根據(jù)passwd的內(nèi)容來進(jìn)行用戶的驗(yàn)證。
我這里所闡述的方案就是工作在no的下面的,修改完之后提交到服務(wù)器,提交完畢服務(wù)器就處在CVSNT的獨(dú)立驗(yàn)證模式下了。在這個(gè)工作方式下,NT本地的用戶和CVSNT用戶沒有任何本質(zhì)的聯(lián)系和影響(僅僅是要建立一個(gè)別名)。
1.2 passwd文件
在講述上面的時(shí)候提到了這個(gè)文件,在服務(wù)器工作在CVSNT驗(yàn)證模式下的時(shí)候,這個(gè)文件就可以稱之為CVSNT的用戶數(shù)據(jù)庫,這個(gè)里面存儲(chǔ)著用戶列表,用戶的密碼,以及別名的一些信息。默認(rèn)狀態(tài)下這個(gè)文件是不存在的,所以,如果我們要在CVSNT驗(yàn)證模式下工作,必須建立這個(gè)文件。注意:這個(gè)文件是不能夠在客戶端進(jìn)行修改的。這個(gè)文件的內(nèi)容是相當(dāng)簡單的,就像下面:
bach:ULtgRLXo7NRxs
spwang:1sOp854gDF3DY
melissa:tGX1fS8sun6rY:pubcvs
qproj:XR4EZcEs0szik:pubcvs
這里分別拿第一個(gè)用戶bach和第三個(gè)用戶melissa來進(jìn)行說明,每一行代表一個(gè)用戶,總共有三部分信息,用戶名、密碼、本地用戶三部分之間使用冒號“:”來進(jìn)行分割。
用戶名:就是登陸CVS的用戶名
密 碼:用戶的密碼,這里是經(jīng)過加密的,如果為空,那么就是空密碼
本地用戶:CVS用戶這個(gè)別名對應(yīng)的本地用戶,(跟本地用戶沒有任何其他關(guān)系,僅僅是別名的關(guān)系)
如果在本地系統(tǒng)中存在一個(gè)用戶名bash,那么要在CVS建立一個(gè)bach這樣的用戶就不需要在后面指出對應(yīng)的系統(tǒng)用戶,melissa后面的pubcvs就是系統(tǒng)用戶,在本地系統(tǒng)上面存在的用戶。對于要用命令增加這兩種用戶的格式如下:
cvspasswd –a bach
cvspasswd –r pubcvs –a melissa
在庫建立的時(shí)候可以在服務(wù)器上建立一個(gè)簡單的passwd初始化文件,加一行
cvsadmin:
這樣,就給出了一個(gè)cvsadmin這個(gè)空密碼用戶(本地系統(tǒng)中有這樣的用戶,就可以不加到后面去),然后在客戶端來進(jìn)行修改和以后的用戶增加工作。注意:在客戶端進(jìn)行其他之前請先首先修改這個(gè)密碼,以防止別人進(jìn)行破壞。
在服務(wù)器端建立了這個(gè)文件以后,就不用再手動(dòng)進(jìn)行修改了,當(dāng)你在客戶端進(jìn)行密碼或者用戶的增加刪除的時(shí)候,系統(tǒng)會(huì)自動(dòng)進(jìn)行這個(gè)文件的更新。這個(gè)文件是管理著CVSNT系統(tǒng)中的所有的用戶,所以,要特別重視,不了解這個(gè)文件格式的,不要去隨便修改,更加不要嘗試在客戶端進(jìn)行修改!
1.3 admin文件
這個(gè)文件是指定CVSNT的管理員列表的文件,CVSNT會(huì)根據(jù)這個(gè)文件中的內(nèi)容來判斷一個(gè)用戶是否是管理員。這個(gè)文件的內(nèi)容很簡單,是一個(gè)用戶列表。類似下面
user1
user2
user3
這些代表user1,user2,user3都是管理員,當(dāng)然,這些用戶必須要存在才能夠正確登陸系統(tǒng)來執(zhí)行管理。
這個(gè)文件默認(rèn)狀態(tài)下是沒有的,但是,可以在客戶端進(jìn)行添加,在你的客戶端進(jìn)行新建這個(gè)文件然后add上去再commit一下,這個(gè)文件就可以上傳到服務(wù)器,但是這個(gè)時(shí)候還沒有生效,請修改checkoutlist這個(gè)文件,加入admin這一行,checkoutlist也可以在客戶端進(jìn)行修改再提交,這個(gè)時(shí)候admin就可以被系統(tǒng)自動(dòng)的build了。
Checkoutlist是維護(hù)的一個(gè)文件列表,可以放入系統(tǒng)自動(dòng)build的用戶自定義的系統(tǒng)文件列表,注意:對passwd沒有用!!
1.4 group文件
這個(gè)文件是定義系統(tǒng)的組,我們可以將同樣性質(zhì)的用戶歸入一個(gè)組,然后用給用戶賦權(quán)限的方式給組賦權(quán)限,這樣,一個(gè)組的用戶就會(huì)具有同樣的權(quán)限。Group的內(nèi)容如下:
group1:user1 user2 user3
group2:me you he
group3:tom honey
有上面可以看出來,這個(gè)文件的內(nèi)容也是相當(dāng)?shù)暮唵危紫仁墙M的名稱然后是冒號,接著是用戶名,多個(gè)用戶名之間用空格來進(jìn)行分割。
Group文件可以在客戶端進(jìn)行新建和修改,不用修改checkoutlist這個(gè)文件,系統(tǒng)會(huì)自動(dòng)build這個(gè)文件并且使之生效。
作為組里面的特定成員還可以賦給特定的權(quán)限,權(quán)限分為兩類c,w,r和n,否定權(quán)限是有高的優(yōu)先級的。
好,上面已經(jīng)介紹了本方案所涉及到的幾個(gè)重要的文件以及修改方式。這里再強(qiáng)調(diào)一下,passwd只能夠再服務(wù)器端進(jìn)行建立和修改,不能夠在客戶端進(jìn)行操作!
現(xiàn)在根據(jù)上面介紹的內(nèi)容,可以開始你的操作了,下面給出修改順序,庫剛剛建立起來的時(shí)候,使用一個(gè)服務(wù)器上的本地管理員用戶進(jìn)行登陸檢出CVSROOT模塊。
1、 現(xiàn)在服務(wù)器端加上passwd文件,給一個(gè)初始的用戶,比如cvsadmin:
2、 在客戶端增加admin,將cvsadmin加入admin文件,作為出是管理員,并提交加入到庫中。
3、 在修改checkoutlist文件,加入admin,使其能夠自動(dòng)build。
4、 最后修改config文件的SystemAuth=no,在提交之前要確認(rèn)一下你上面的修改是否正確,如果提交了這個(gè)文件,CVSNT驗(yàn)證模式就開始生效了!
5、 好,現(xiàn)在請修改你的參數(shù)再重新進(jìn)行的登陸吧。因?yàn)槟愕南到y(tǒng)已經(jīng)切換了工作模式,你當(dāng)前的用戶已經(jīng)失效了。
完成了上面的步驟,整個(gè)服務(wù)器就會(huì)有效的工作在CVSNT驗(yàn)證模式下了。而group文件在你需要的任何時(shí)候可以加入。
在上面的文章關(guān)于CVSNT的用戶的管理方案的,在這里做一點(diǎn)補(bǔ)充,在后面的操作中全部是針對在客戶端使用WinCVS來進(jìn)行的(出了增加passwd)文件,其實(shí),在我的實(shí)踐當(dāng)中config,passwd,admin,checkoutlist,這些文件的起始修改(初始化)都可以在新建了庫以后一起完成,然后再讓相應(yīng)的庫的管理員來進(jìn)行相關(guān)的操作。
轉(zhuǎn)載至:http://www.51cmm.com/casepanel/CM/No051.htm

橘子 2006-06-22 01:28 發(fā)表評論
]]>
CVSNT命令篇http://www.tkk7.com/forget/archive/2006/06/22/54392.html橘子橘子Wed, 21 Jun 2006 17:26:00 GMThttp://www.tkk7.com/forget/archive/2006/06/22/54392.htmlhttp://www.tkk7.com/forget/comments/54392.htmlhttp://www.tkk7.com/forget/archive/2006/06/22/54392.html#Feedback0http://www.tkk7.com/forget/comments/commentRss/54392.htmlhttp://www.tkk7.com/forget/services/trackbacks/54392.html在得到CVSROOT和你的口令之后,你就可以試著登陸了。

首先,由于其他所有的GUI工具都是基于CVS基本協(xié)議的,而且他們可能會(huì)提供CVS的命令行或者等價(jià)形
式作為顯示的一部分,所以你應(yīng)該對命令行操作有所了解。如果你還沒有一個(gè)cvs。exe的命令行程序,從
www.cvsnt.org你可以得到一個(gè)cvsnt的下載連接,其中就包含了一個(gè)命令行的cvs.exe程序。我們先從它開始
(為了作為一個(gè)client使用,你不需要安裝cvsnt的server組件)。CVSNT的cvs.exe是專門為windows編寫的,你
需要把cvs.exe放在你的path里面。

1.進(jìn)入命令行方式。

和VSS一樣,你也需要在本地有一個(gè)工作目錄對應(yīng)于一個(gè)repository。假設(shè)這個(gè)目錄是'd:\works\sandbox'。
請切換到這個(gè)目錄。

輸入"cvs"。你會(huì)看到:


這些提示信息告訴您關(guān)于cvs的基本語法。cvs后面跟著的是全局參數(shù),然后是命令,最后是命令的參數(shù)。

2.login


正確的login不會(huì)有任何輸出,否則會(huì)告訴你錯(cuò)誤原因。


如果login失敗,則可以先嘗試命令:set cvsroot=:pserver:cao@IP或者計(jì)算機(jī)名字/CVSRoot

3.下面我們看看這個(gè)CVS server中有哪些module。


4.假設(shè)現(xiàn)在我們工作的項(xiàng)目是projectX,下面我們需要得到它下面的全部文件。


現(xiàn)在讓我們看一下我們得到了什么。


在d:/works/sandbox目錄下,你可以看到有一個(gè)projectX目錄。這就是你得到的所有文件。

這個(gè)目錄下你會(huì)發(fā)現(xiàn)一個(gè)叫做 CVS的目錄。危險(xiǎn)!請不要?jiǎng)h除這個(gè)目錄,或者改名,或者改動(dòng)其中的
任何文件,除非你知道你在做什么。這個(gè)目錄是CVS的控制目錄。如果你用過source safe,你一定很熟悉。scc這個(gè)文件,CVS目錄的作用就和這個(gè)控制文件一樣,都是用來記錄你訪問服務(wù)器的參數(shù)。

這里我們需要解釋一下cvs和VSS的名詞差別。在VSS中,checkout意味著你將獲得一個(gè)文件的修改權(quán),而
cvs中checkout的這個(gè)含義取消了,僅僅指取得文件的新版本。很多cvs server會(huì)有一個(gè)anonymous用戶,他
只有checkout權(quán)限,也就意味著它只讀。???

				

5.讓我們試著加入一個(gè)文件:
在d:/works/sandbox/projectX下,新建一個(gè)文件newfile.txt,



然后,在這個(gè)目錄下執(zhí)行:





你需要commit它才能被sever接受。




一個(gè)notepad窗口彈出請您輸入注釋。



這是commit完成的結(jié)果。現(xiàn)在的版本號是1.1。

6.好了,現(xiàn)在假設(shè)您需要改一下這個(gè)文件的內(nèi)容。


CVS可以幫助您比較現(xiàn)在您的版本和repository中的版本有什么不同。

好了,現(xiàn)在您可以提交您的新文件。

CVS會(huì)幫您保留您的各個(gè)版本。在commit之后,現(xiàn)在我們來看一看各個(gè)版本的history。

7.最后,為了完成這個(gè)試驗(yàn),請把這個(gè)newfile文件刪去。

我們現(xiàn)在認(rèn)識了一些最基本的CVS入門級指令。
其實(shí)CVS是非常強(qiáng)大的,我們并沒有用到一些更復(fù)雜的功能,請參閱cvs的手冊來得到更為詳盡的幫助。
轉(zhuǎn)載至:http://www.redsaga.com/CVS_newbie_win32/



橘子 2006-06-22 01:26 發(fā)表評論
]]>
CVS相關(guān)配置使用http://www.tkk7.com/forget/archive/2006/06/21/54112.html橘子橘子Wed, 21 Jun 2006 01:15:00 GMThttp://www.tkk7.com/forget/archive/2006/06/21/54112.htmlhttp://www.tkk7.com/forget/comments/54112.htmlhttp://www.tkk7.com/forget/archive/2006/06/21/54112.html#Feedback0http://www.tkk7.com/forget/comments/commentRss/54112.htmlhttp://www.tkk7.com/forget/services/trackbacks/54112.html1、下載CVSNT一路默認(rèn)安裝,在選擇安裝類型時(shí),應(yīng)該選擇完全安裝。一路裝好ok,重啟動(dòng)系統(tǒng),在控制面板多了個(gè)東東。并且可以在服務(wù)控制器中發(fā)現(xiàn)多了2個(gè)服務(wù):cvsnt與cvslocking,雙擊Service Control Panel快捷方式,在Service Status頁面,會(huì)看見cvs server 和 cvs lock server2個(gè)服務(wù)正常和穩(wěn)定運(yùn)行

2、切換到Advanced,先在Use local users for pserver authentication instead of domain users和Pretend to be a Unix CVS version鉤上,這是讓CVSNT使用本地賬戶作為pserver認(rèn)證方式以及讓CVSNT服務(wù)器模擬為Unix CVS服務(wù)器,如圖:

3、選擇Repository頁面,點(diǎn)按Add按鈕,選擇已經(jīng)準(zhǔn)備好的F:\Root這個(gè)目錄,確認(rèn),OK,Yes,這時(shí)會(huì)在F:\Root下面建立一個(gè)CVSRoot目錄,這是CVS默認(rèn)的管理目錄(默認(rèn)模塊)。如果報(bào)錯(cuò),那是系統(tǒng)Path路徑未設(shè)置正確。
?
4、CVSNT的用戶驗(yàn)證方式:我會(huì)專門找一篇寫得全的另外寫。

5、打開一個(gè)cmd窗口,輸入命令set cvsroot=:pserver:sunxdd@server/Root(sunxdd是剛才建立的用戶名,server是安裝的計(jì)算機(jī)名稱或者IP,/Root是剛才建立的文件夾別名,每次登陸之前都要這樣告訴系統(tǒng)建立這樣一個(gè)環(huán)境變量)
cvs login
密碼為空
這時(shí)會(huì)登錄成功
改密碼
cvs passwd

到這里CVSNT服務(wù)器基本上搞定了。


有用的資源:
http://edu.tmn.cn/html/5/47/185/2005210/104247.htm
http://www.redsaga.com/CVS_newbie_win32/#tortoisecvs
http://sunxdd.blogchina.com/2338489.html



橘子 2006-06-21 09:15 發(fā)表評論
]]>
php開發(fā)wap常用技巧http://www.tkk7.com/forget/archive/2006/06/17/53462.html橘子橘子Sat, 17 Jun 2006 03:43:00 GMThttp://www.tkk7.com/forget/archive/2006/06/17/53462.htmlhttp://www.tkk7.com/forget/comments/53462.htmlhttp://www.tkk7.com/forget/archive/2006/06/17/53462.html#Feedback1http://www.tkk7.com/forget/comments/commentRss/53462.htmlhttp://www.tkk7.com/forget/services/trackbacks/53462.html在php中輸出返回上一級的代碼:
echo "<a href=".$_SERVER["HTTP_REFERER"].">點(diǎn)擊這里返回</a>";
在wap中的代碼是:
<?php
@header("Content-Type:text/vnd.wap.wml");
?>
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.3//EN" "<wml>
<head>
<meta http-equiv="expires" content="0" />
</head>
<card title="輸入標(biāo)題">
<do type="prev" label="返回上頁">
<prev/>
<!--provide a button you can clink to back a step-->
</do><br/>
<!--<anchor>
<prev/>后退
</anchor>-->?
</card>
</wml>
在wap中打電話的代碼:
<?php
?@header("Content-Type:text/vnd.wap.wml");
?>
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.3//EN" "
<wml>
<head>
<meta http-equiv="expires" content="0" />
</head>
<card title="標(biāo)題">
<p>
<input name="phone_no" format="*m" value="13"/>
<do type="option" >
<go href="wtai://wp/mc;$(phone_no)"/>
</do><br/>
或者
<a href="wtai://wp/mc;13333333333">撥打電話</a>
<br />
</p>
</card>
</wml>

加入WAP書簽

<?xml version="1.0"?>
<!DOCTYPE CHARACTERISTIC-LIST SYSTEM "/DTD/characteristic_list.xml">
<CHARACTERISTIC-LIST>
<CHARACTERISTIC TYPE="ADDRESS">
<PARM NAME="BEARER" VALUE="GPRS"/>
<PARM NAME="PROXY" VALUE="10.0.0.172"/>
<PARM NAME="PORT" VALUE="9201"/>
<PARM NAME="GPRS_ACCESSPOINTNAME" VALUE="wap.02826.com"/>
<PARM NAME="PPP_AUTHTYPE" VALUE="PAP"/>
</CHARACTERISTIC>
<CHARACTERISTIC TYPE="NAME">
<PARM NAME="NAME" VALUE="wmzsoft GPRS"/>
</CHARACTERISTIC>
<CHARACTERISTIC TYPE="BOOKMARK"/>
<PARM NAME="NAME" VALUE="02826"/>
<PARM NAME="URL" VALUE="
http://wap.02826.com "/>
</CHARACTERISTIC>
</CHARACTERISTIC-LIST>


橘子 2006-06-17 11:43 發(fā)表評論
]]>
點(diǎn)中復(fù)選框使得復(fù)選框后的文本框內(nèi)容顯示出指定的內(nèi)容http://www.tkk7.com/forget/archive/2006/06/09/51764.html橘子橘子Fri, 09 Jun 2006 15:08:00 GMThttp://www.tkk7.com/forget/archive/2006/06/09/51764.htmlhttp://www.tkk7.com/forget/comments/51764.htmlhttp://www.tkk7.com/forget/archive/2006/06/09/51764.html#Feedback0http://www.tkk7.com/forget/comments/commentRss/51764.htmlhttp://www.tkk7.com/forget/services/trackbacks/51764.html<!--
function test(obj) {
??? if (obj.checked) {document.all(obj.name+'_t').value=obj.value}
??? else {document.all(obj.name+'_t').value=''}
}
//-->
</script>
<input type="checkbox" name="cb1" value="aaaa" onClick="test(this)">aaaa
<input type="text" name="cb1_t">
<br>
<input type="checkbox" name="cb2" value="bbbb" onClick="test(this)">bbbb
<input type="text" name="cb2_t">
<br>
<input type="checkbox" name="cb3" value="cccc" onClick="test(this)">cccc
<input type="text" name="cb3_t">
<br>
<input type="checkbox" name="cb4" value="dddd" onClick="test(this)">dddd
<input type="text" name="cb4_t">

這樣一來 如果想輸入某個(gè)確定的值時(shí)就不用那么辛辛苦苦的復(fù)制了,點(diǎn)擊就自動(dòng)選擇!

橘子 2006-06-09 23:08 發(fā)表評論
]]>
php上傳多個(gè)文件http://www.tkk7.com/forget/archive/2006/06/08/51520.html橘子橘子Thu, 08 Jun 2006 14:31:00 GMThttp://www.tkk7.com/forget/archive/2006/06/08/51520.htmlhttp://www.tkk7.com/forget/comments/51520.htmlhttp://www.tkk7.com/forget/archive/2006/06/08/51520.html#Feedback1http://www.tkk7.com/forget/comments/commentRss/51520.htmlhttp://www.tkk7.com/forget/services/trackbacks/51520.html前面提到了上傳單個(gè)文件的方法,上傳多個(gè)文件的思想類似
1、在表單頁面動(dòng)態(tài)生成多個(gè)文件提交框,這里注意一下,多個(gè)文件提交框的名字要設(shè)置為數(shù)組,否則只有一個(gè)文件會(huì)上傳。
此時(shí)在$_FILES數(shù)組構(gòu)造方式是這樣:$_FILES["files"][xxxxfileProperty][xxxcount]; 比如說我要知道第一個(gè)文件的error值:$_FILES["userfiles"]["error"][0] ,第一個(gè)文件客戶端名字:$_FILES["userfiles"]["name"][0]等等。
2、接收端接收,操作和單個(gè)的是一樣,只是需要做個(gè)循環(huán),有多少個(gè)文件做多少次循環(huán),以便所有的文件都能正確發(fā)送。
示例代碼:
表單頁面
<form enctype="multipart/form-data" action="post.php" method="post">
&nbsp;&nbsp;文章標(biāo)題:&nbsp;&nbsp;<input name="title" type="text"/>&nbsp;標(biāo)題不能為空!
<br />&nbsp;&nbsp;淘吧名字:&nbsp;&nbsp;<input name="bar_name" type="text"/>
<?php
echo "請選擇一個(gè)!\t(";
for ($i=0; $i<count($name); $i++ ){
?echo mb_convert_encoding($name[$i]["name"],"UTF-8","GB2312");
?echo "? ";
}
echo ")";
?>
<br />
<textarea name="text" cols="90" rows="20"></textarea>
<?php
for ($i=0;$i<3;$i++){
?echo "<input name=\"userfile[]\" type=\"file\"/>";
}
echo "<input name=\"i\" type=\"hidden\" value=\"$i\" />";
?>
</td></tr>
</table>
<table align="center" cellpadding="0" cellspacing="0"><tr><td>
<input name="submit" type="submit" value="確定提交"/>&nbsp;&nbsp;
<input name="reset" type="reset" value="重新來過"/>
</form>
處理頁面
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "<html xmlns="<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>提交</title>
</head>

<body>
<?php
$title=$_POST["title"];
$text=$_POST["text"];
$name=$_POST["name"];
$count=$_POST["i"];
include_once("數(shù)據(jù)庫連接文件");
if (empty($title)||empty($text)||empty($bar_name)){
?echo "標(biāo)題或內(nèi)容不能空
?die("<br /><a href=\"index.php\">重新來過</a>");
}

/*這里是數(shù)據(jù)查詢語言取出要用的數(shù)據(jù)*/

if(in_array("0", $_FILES['userfile']['error'])){//上傳文件開始
?$uploaddir= 'attfile/';//設(shè)置上傳的文件夾地址
?$FILES_EXT=array('.gif','.jpg','.mp3','.3gp');//設(shè)置允許上傳文件的類型
?$MAX_SIZE = 20000000;//設(shè)置文件上傳限制20000000byte=2M
?for ($i=0;$i<$count;$i++){
??$FILES_NAME=$_FILES['userfile']['name'][$i];//客戶端文件名
??//取出文件后綴名,strrpos()從標(biāo)記開始前字節(jié)個(gè)數(shù)(不算標(biāo)記),substr()顯示從第strrpos()之后的字符
??$file_ext=substr($FILES_NAME,strrpos($FILES_NAME,"."));
??//檢查文件大小
??if($_FILES['userfile']['size'][$i]>$MAX_SIZE){
???echo "文件大小超程序允許范圍!";
???exit;
??}
??//檢查文件類型
??if(in_array($file_ext, $FILES_EXT)){
???$_FILES['userfile']['name'][$i]=date("YmdHis").rand(10000,1000000).$file_ext;
???//echo $_FILES['userfile']['name'][$i];
???$uploadfile = $uploaddir.$_FILES['userfile']['name'][$i];//上傳后文件的路徑及文件名
???//echo $uploadfile;
???//用move函數(shù)生成臨時(shí)文件名,并按照 $_FILES['userfile']['name']上傳到$uploaddir下
???if (move_uploaded_file($_FILES['userfile']['tmp_name'][$i], $uploadfile)) {
????//將上傳后的路徑寫入到數(shù)據(jù)庫中
????$post_id=(int)$post_id;
????$uploadfile="attfile/".$_FILES['userfile']['name'][$i];
????$sql=插入語句
????$stmt=$db->prepare($sql);
????$stmt->execute();
????print "<br />文件\n{$FILES_NAME}\n上傳成功!";
???} else {
????print "上傳錯(cuò)誤!? 以下是上傳的信息:\n";
????print_r($_FILES);
???}
??}
??else{
???echo "{$FILES_NAME}\n不是允許上傳的文件類型!";
???exit;
??}
?}
}

?>
</body>
</html>



橘子 2006-06-08 22:31 發(fā)表評論
]]>
php上傳單個(gè)文件http://www.tkk7.com/forget/archive/2006/06/08/51506.html橘子橘子Thu, 08 Jun 2006 14:09:00 GMThttp://www.tkk7.com/forget/archive/2006/06/08/51506.htmlhttp://www.tkk7.com/forget/comments/51506.htmlhttp://www.tkk7.com/forget/archive/2006/06/08/51506.html#Feedback0http://www.tkk7.com/forget/comments/commentRss/51506.htmlhttp://www.tkk7.com/forget/services/trackbacks/51506.html ??? PHP上傳文件的問題:
一:1、上傳單個(gè)文件的時(shí)候。在表單頁面設(shè)置文件輸入域,<input name="userfile" type="file" />然后表單要加入<form enctype="multipart/form-data" action="post.php" method="post">這個(gè)屬性,這是告訴瀏覽器我要上傳文件的屬性,一定要加上。
??? 2、設(shè)置好了表單,接下來的事就是讀取表單的變量,如果你還定義了其他的變量,那么php使用$_POST來讀出,如:$uservar=$_POST["uservar"],然而文件是存在$_FILES中,具體見下面:
?
? * $_FILES['userfile']['name'] 客戶端機(jī)器文件的原名稱。
? ?* $_FILES['userfile']['type'] 文件的 MIME 類型,需要瀏覽器提供該信息的支持,例如“image/gif”。
? ?* $_FILES['userfile']['size'] 已上傳文件的大小,單位為字節(jié)。
? ?* $_FILES['userfile']['tmp_name'] 文件被上傳后在服務(wù)端儲(chǔ)存的臨時(shí)文件名。
? ?* $_FILES['userfile']['error'] 和該文件上傳相關(guān)的錯(cuò)誤代碼

? 1. 值:0; 沒有錯(cuò)誤發(fā)生,文件上傳成功。
? 2. 值:1; 上傳的文件超過了 php.ini 中 upload_max_filesize 選項(xiàng)限制的值。
? 3. 值:2; 上傳文件的大小超過了 HTML 表單中 MAX_FILE_SIZE 選項(xiàng)指定的值。
? 4. 值:3; 文件只有部分被上傳。
? 5. 值:4; 沒有文件被上傳。
3、完成上傳過程。示例代碼:
(1)
<?php
$upload_file=$_FILES['userfile']['tmp_name'];
$upload_file_name=$_FILES['userfile']['name'];
if($upload_file){
?$file_size_max = 20000000;// 1M限制文件上傳最大容量(bytes)
?$store_dir = "attfile/";// 上傳文件的儲(chǔ)存位置
?$accept_overwrite = 1;//是否允許覆蓋相同文件
?// 檢查文件大小
?if ($upload_file_size > $file_size_max) {
??echo "對不起,你的文件容量大于規(guī)定";
??exit;
?}
?// 檢查讀寫文件
?if (file_exists($store_dir . $upload_file_name) && !$accept_overwrite) {
??echo?? "存在相同文件名的文件";
??exit;
?}
?//復(fù)制文件到指定目錄
?if (!move_uploaded_file($upload_file,$store_dir.$upload_file_name)) {
??echo "復(fù)制文件失敗";
??exit;
?}
}
echo?? "<p>你上傳了文件:";
echo $_FILES['userfile']['name'];
echo "<br>";
//客戶端機(jī)器文件的原名稱。
Echo?? "文件的 MIME 類型為:";
echo $_FILES['userfile']['type'];
//文件的 MIME 類型,需要瀏覽器提供該信息的支持,例如“image/gif”。
echo "<br>";

Echo?? "上傳文件大小:";
echo $_FILES['userfile']['size'];
//已上傳文件的大小,單位為字節(jié)。
echo "<br>";

Echo?? "文件上傳后被臨時(shí)儲(chǔ)存為:";
echo $_FILES['userfile']['tmp_name'];
//文件被上傳后在服務(wù)端儲(chǔ)存的臨時(shí)文件名。
echo "<br>";

$Erroe=$_FILES['userfile']['error'];
switch($Erroe){
?case 0:
?Echo?? "上傳成功"; break;
?case 1:
?Echo?? "上傳的文件超過了 php.ini 中 upload_max_filesize 選項(xiàng)限制的值."; break;
?case 2:
?Echo?? "上傳文件的大小超過了 HTML 表單中 MAX_FILE_SIZE 選項(xiàng)指定的值。";?? break;
?case 3:
?Echo?? "文件只有部分被上傳";break;
?case 4:
?Echo?? "沒有文件被上傳";break;
}
?>
(2)<?php
$uploaddir= '../attfile/';//設(shè)置上傳的文件夾地址
$FILES_EXT=array('.gif','.jpg','.bmp');//設(shè)置允許上傳文件的類型
$MAX_SIZE = 20000000;//設(shè)置文件上傳限制20000000byte=2M
for ($i=0;$i<count($userfile);$i++){
?$FILES_NAME=$_FILES['userfile']['name'][$i];//客戶端文件名
}
//echo $FILES_NAME;
//取出文件后綴名,strrpos()從標(biāo)記開始前字節(jié)個(gè)數(shù)(不算標(biāo)記),substr()顯示從第strrpos()之后的字符
$file_ext=substr($FILES_NAME,strrpos($FILES_NAME,"."));
//echo $file_ext;
//檢查文件大小
if($_FILES['userfile']['size']>$MAX_SIZE){
?echo "文件大小超程序允許范圍!";
?exit;
}
//檢查文件類型
if(in_array($file_ext, $FILES_EXT)){
?$_FILES['userfile']['name']=date("YmdHis").rand().$file_ext;
?$uploadfile = $uploaddir.$_FILES['userfile']['name'];//上傳后文件的路徑及文件名
?//將上傳后的路徑寫入到數(shù)據(jù)庫中

?//用move函數(shù)生成臨時(shí)文件名,并按照 $_FILES['userfile']['name']上傳到$uploaddir下
?if (move_uploaded_file($_FILES['userfile']['tmp_name'], $uploadfile)) {
??print "\n上傳成功!";
?} else {
??print "上傳錯(cuò)誤!? 以下是上傳的信息:\n";
??print_r($_FILES);
?}
}
else{
?echo "{$file_ext}不是允許上傳的文件類型!";
?exit;
}
?>



小技巧>>1、當(dāng)在提交時(shí),希望確認(rèn)是否要提交可以在<form>里如這樣加入:<form onsubmit="return confirm('你真的要提交嗎?')">
2、在php里希望返回時(shí)所有在文本框里的東西都保留可以這樣:<a href=javascript:history.back(1)>重新來過</a>。



橘子 2006-06-08 22:09 發(fā)表評論
]]>
JAVA相關(guān)基礎(chǔ)知識http://www.tkk7.com/forget/archive/2006/05/19/47089.html橘子橘子Fri, 19 May 2006 09:38:00 GMThttp://www.tkk7.com/forget/archive/2006/05/19/47089.htmlhttp://www.tkk7.com/forget/comments/47089.htmlhttp://www.tkk7.com/forget/archive/2006/05/19/47089.html#Feedback0http://www.tkk7.com/forget/comments/commentRss/47089.htmlhttp://www.tkk7.com/forget/services/trackbacks/47089.html
JAVA相關(guān)基礎(chǔ)知識
1、面向?qū)ο蟮奶卣饔心男┓矫??
1.抽象:
抽象就是忽略一個(gè)主題中與當(dāng)前目標(biāo)無關(guān)的那些方面,以便更充分地注意與當(dāng)前目標(biāo)有關(guān)的方面。抽象并不打算了解全部問題,而只是選擇其中的一部分,暫時(shí)不用部分細(xì)節(jié)。抽象包括兩個(gè)方面,一是過程抽象,二是數(shù)據(jù)抽象。
2.繼承:
繼 承是一種聯(lián)結(jié)類的層次模型,并且允許和鼓勵(lì)類的重用,它提供了一種明確表述共性的方法。對象的一個(gè)新類可以從現(xiàn)有的類中派生,這個(gè)過程稱為類繼承。新類繼 承了原始類的特性,新類稱為原始類的派生類(子類),而原始類稱為新類的基類(父類)。派生類可以從它的基類那里繼承方法和實(shí)例變量,并且類可以修改或增 加新的方法使之更適合特殊的需要。
3.封裝:
封裝是把過程和數(shù)據(jù)包圍起來,對數(shù)據(jù)的訪問只能通過已定義的界面。面向?qū)ο笥?jì)算始于這個(gè)基本概念,即現(xiàn)實(shí)世界可以被描繪成一系列完全自治、封裝的對象,這些對象通過一個(gè)受保護(hù)的接口訪問其他對象。
4. 多態(tài)性:
多態(tài)性是指允許不同類的對象對同一消息作出響應(yīng)。多態(tài)性包括參數(shù)化多態(tài)性和包含多態(tài)性。多態(tài)性語言具有靈活、抽象、行為共享、代碼共享的優(yōu)勢,很好的解決了應(yīng)用程序函數(shù)同名問題。
2、String是最基本的數(shù)據(jù)類型嗎?
基本數(shù)據(jù)類型包括byte、int、char、long、float、double、boolean和short。
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í)所指定的缺省值。對象引用實(shí)例變量的缺省值為 null,而原始類型實(shí)例變量的缺省值與它們的類型有關(guān)。
4、String 和StringBuffer的區(qū)別
JAVA平臺提供了兩個(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方法,請求到達(dá)時(shí)運(yùn)行其service方法,service方法自動(dòng)派遣運(yùn)行與請求對應(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è)請求,并且其實(shí)例一般不會(huì)銷毀,而CGI對每個(gè)請求都產(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ù)以便增加和插入元素,它們都允許直接按序號索引元素,但是插入元素要涉及數(shù)組元 素移動(dòng)等內(nèi)存操作,所以索引數(shù)據(jù)快而插入數(shù)據(jù)慢,Vector由于使用了synchronized方法(線程安全),通常性能上較ArrayList差, 而LinkedList使用雙向鏈表實(shí)現(xiàn)存儲(chǔ),按序號索引數(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ù)。
對于客戶機(jī),SessionBean是一種非持久性對象,它實(shí)現(xiàn)某些在服務(wù)器上運(yùn)行的業(yè)務(wù)邏輯。
對于客戶機(jī),EntityBean是一種持久性對象,它代表一個(gè)存儲(chǔ)在持久性存儲(chǔ)器中的實(shí)體的對象視圖,或是一個(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è)相對應(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)勢卻在于他可以維持使用者的狀態(tài)。
9、Collection 和 Collections的區(qū)別。
  Collection是集合類的上級接口,繼承與他的接口主要有Set 和List.
Collections是針對集合類的一個(gè)幫助類,他提供一系列靜態(tài)方法實(shí)現(xiàn)對各種集合的搜索、排序、線程安全化等操作。
10、&和&&的區(qū)別。
??? &是位運(yùn)算符,表示按位與運(yùn)算,&&是邏輯運(yùn)算符,表示邏輯與(and)。
11、HashMap和Hashtable的區(qū)別。
??? HashMap是Hashtable的輕量級實(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)用被回收對象的此方法,可以覆蓋此方法提供垃圾收集時(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ì)釋放對象鎖。
wait是Object類的方法,對此對象調(diào)用wait方法導(dǎo)致本線程放棄對象鎖,進(jìn)入等待此對象的等待鎖定池,只有針對此對象發(fā)出notify方法(或notifyAll)后本線程才進(jìn)入對象鎖定池準(zhǔn)備獲得對象鎖進(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)。子類的對象使用這個(gè)方法時(shí),將調(diào)用子類中的定義,對它而言,父類中的定義如同被"屏蔽"了。如果在一個(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)用程序在對象上調(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)了該接口的類的任何對象上調(diào)用接口的方法。由于有抽象類,它允許使用接口名作為引用變量的類型。通常的動(dòng)態(tài)聯(lián)編將生效。引用可以轉(zhuǎn)換到 接口類型或從接口類型轉(zhuǎn)換,instanceof 運(yùn)算符可以用來決定某對象的類是否實(shí)現(xiàn)了接口。
18、heap和stack有什么區(qū)別。
棧是一種線形集合,其添加和刪除元素的操作應(yīng)在同一段完成。棧按照后進(jìn)先出的方式進(jìn)行處理。
堆是棧的一個(gè)組成元素
19、forward 和redirect的區(qū)別
forward是服務(wù)器請求資源,服務(wù)器直接訪問目標(biāo)地址的URL,把那個(gè)URL的響應(yīng)內(nèi)容讀取過來,然后把這些內(nèi)容再發(fā)給瀏覽器,瀏覽器根本不知道服務(wù)器發(fā)送的內(nèi)容是從哪兒來的,所以它的地址欄中還是原來的地址。
??? redirect就是服務(wù)端根據(jù)邏輯,發(fā)送一個(gè)狀態(tài)碼,告訴瀏覽器重新去請求那個(gè)地址,一般來說瀏覽器會(huì)用剛才請求的所有參數(shù)重新請求,所以session,request參數(shù)都可以獲取。
20、EJB與JAVA BEAN的區(qū)別?
Java Bean 是可復(fù)用的組件,對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組件。
21、Static Nested Class 和 Inner Class的不同。
??? Static Nested Class是被聲明為靜態(tài)(static)的內(nèi)部類,它可以不依賴于外部類實(shí)例被實(shí)例化。而通常的內(nèi)部類需要在外部類實(shí)例化后才能實(shí)例化。
22、JSP中動(dòng)態(tài)INCLUDE與靜態(tài)INCLUDE的區(qū)別?
動(dòng)態(tài)INCLUDE用jsp:include動(dòng)作實(shí)現(xiàn) <jsp:include page="included.jsp" flush="true" />它總是會(huì)檢查所含文件中的變化,適合用于包含動(dòng)態(tài)頁面,并且可以帶參數(shù)。
靜態(tài)INCLUDE用include偽碼實(shí)現(xiàn),定不會(huì)檢查所含文件的變化,適用于包含靜態(tài)頁面<%@ include file="included.htm" %>
23、什么時(shí)候用assert。
??? assertion(斷言)在軟件開發(fā)中是一種常用的調(diào)試方式,很多開發(fā)語言中都支持這種機(jī)制。在實(shí)現(xiàn)中,assertion就是在程序中的一條語句,它 對一個(gè)boolean表達(dá)式進(jìn)行檢查,一個(gè)正確程序必須保證這個(gè)boolean表達(dá)式的值為true;如果該值為false,說明程序已經(jīng)處于不正確的狀 態(tài)下,系統(tǒng)將給出警告或退出。一般來說,assertion用于保證程序最基本、關(guān)鍵的正確性。assertion檢查通常在開發(fā)和測試時(shí)開啟。為了提高 性能,在軟件發(fā)布后,assertion檢查通常是關(guān)閉的。
24、GC是什么? 為什么要有GC?
  GC是垃圾收集的意思 (Gabage Collection),內(nèi)存處理是編程人員容易出現(xiàn)問題的地方,忘記或者錯(cuò)誤的內(nèi)存回收會(huì)導(dǎo)致程序或系統(tǒng)的不穩(wěn)定甚至崩潰,Java提供的GC功能可以 自動(dòng)監(jiān)測對象是否超過作用域從而達(dá)到自動(dòng)回收內(nèi)存的目的,Java語言沒有提供釋放已分配內(nèi)存的顯示操作方法。
25、short s1 = 1; s1 = s1 + 1;有什么錯(cuò)? short s1 = 1; s1 += 1;有什么錯(cuò)?
??? short s1 = 1; s1 = s1 + 1; (s1+1運(yùn)算結(jié)果是int型,需要強(qiáng)制轉(zhuǎn)換類型)
short s1 = 1; s1 += 1;(可以正確編譯)
26、Math.round(11.5)等於多少? Math.round(-11.5)等於多少?
??? Math.round(11.5)==12
Math.round(-11.5)==-11
round方法返回與參數(shù)最接近的長整數(shù),參數(shù)加1/2后求其floor.
27、String s = new String("xyz");創(chuàng)建了幾個(gè)String Object?
??? 兩個(gè)
28、設(shè)計(jì)4個(gè)線程,其中兩個(gè)線程每次對j增加1,另外兩個(gè)線程對j每次減少1。寫出程序。
以下程序使用內(nèi)部類實(shí)現(xiàn)線程,對j增減的時(shí)候沒有考慮順序問題。
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();
}
?}
? }
}
29、Java有沒有g(shù)oto?
java中的保留字,現(xiàn)在沒有在java中使用。
30、啟動(dòng)一個(gè)線程是用run()還是start()?
啟動(dòng)一個(gè)線程是調(diào)用start()方法,使線程所代表的虛擬處理機(jī)處于可運(yùn)行狀態(tài),這意味著它可以由JVM調(diào)度并執(zhí)行。這并不意味著線程就會(huì)立即運(yùn)行。run()方法可以產(chǎn)生必須退出的標(biāo)志來停止一個(gè)線程。
?

31、EJB包括(SessionBean,EntityBean)說出他們的生命周期,及如何管理事務(wù)的?
SessionBean: Stateless Session Bean 的生命周期是由容器決定的,當(dāng)客戶機(jī)發(fā)出請求要建立一個(gè)Bean的實(shí)例時(shí),EJB容器不一定要?jiǎng)?chuàng)建一個(gè)新的Bean的實(shí)例供客戶機(jī)調(diào)用,而是隨便找一個(gè)現(xiàn) 有的實(shí)例提供給客戶機(jī)。當(dāng)客戶機(jī)第一次調(diào)用一個(gè)Stateful Session Bean 時(shí),容器必須立即在服務(wù)器中創(chuàng)建一個(gè)新的Bean實(shí)例,并關(guān)聯(lián)到客戶機(jī)上,以后此客戶機(jī)調(diào)用Stateful Session Bean 的方法時(shí)容器會(huì)把調(diào)用分派到與此客戶機(jī)相關(guān)聯(lián)的Bean實(shí)例。
EntityBean:Entity Beans能存活相對較長的時(shí)間,并且狀態(tài)是持續(xù)的。只要數(shù)據(jù)庫中的數(shù)據(jù)存在,Entity beans就一直存活。而不是按照應(yīng)用程序或者服務(wù)進(jìn)程來說的。即使EJB容器崩潰了,Entity beans也是存活的。Entity Beans生命周期能夠被容器或者 Beans自己管理。
EJB通過以下技術(shù)管理實(shí)務(wù):對象管理組織(OMG)的對象實(shí)務(wù)服務(wù)(OTS),Sun Microsystems的Transaction Service(JTS)、Java Transaction API(JTA),開發(fā)組(X/Open)的XA接口。
32、應(yīng)用服務(wù)器有那些?
BEA WebLogic Server,IBM WebSphere Application Server,Oracle9i Application Server,jBoss,Tomcat
33、給我一個(gè)你最常見到的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、接口是否可繼承接口? 抽象類是否可實(shí)現(xiàn)(implements)接口? 抽象類是否可繼承實(shí)體類(concrete class)?
接口可以繼承接口。抽象類可以實(shí)現(xiàn)(implements)接口,抽象類是否可繼承實(shí)體類,但前提是實(shí)體類必須有明確的構(gòu)造函數(shù)。
35、List, Set, Map是否繼承自Collection接口?
??? List,Set是,Map不是
36、說出數(shù)據(jù)連接池的工作機(jī)制是什么?
J2EE 服務(wù)器啟動(dòng)時(shí)會(huì)建立一定數(shù)量的池連接,并一直維持不少于此數(shù)目的池連接。客戶端程序需要連接時(shí),池驅(qū)動(dòng)程序會(huì)返回一個(gè)未使用的池連接并將其表記為忙。如果 當(dāng)前沒有空閑連接,池驅(qū)動(dòng)程序就新建一定數(shù)量的連接,新建連接的數(shù)量有配置參數(shù)決定。當(dāng)使用的池連接調(diào)用完成后,池驅(qū)動(dòng)程序?qū)⒋诉B接表記為空閑,其他調(diào)用 就可以使用這個(gè)連接。
37、abstract的method是否可同時(shí)是static,是否可同時(shí)是native,是否可同時(shí)是synchronized?
??? 都不能
38、數(shù)組有沒有l(wèi)ength()這個(gè)方法? String有沒有l(wèi)ength()這個(gè)方法?
數(shù)組沒有l(wèi)ength()這個(gè)方法,有l(wèi)ength的屬性。String有有l(wèi)ength()這個(gè)方法。
39、Set里的元素是不能重復(fù)的,那么用什么方法來區(qū)分重復(fù)與否呢? 是用==還是equals()? 它們有何區(qū)別?
Set里的元素是不能重復(fù)的,那么用iterator()方法來區(qū)分重復(fù)與否。equals()是判讀兩個(gè)Set是否相等。
??? equals()和==方法決定引用值是否指向同一對象equals()在類中被覆蓋,為的是當(dāng)兩個(gè)分離的對象的內(nèi)容和類型相配的話,返回真值。
40、構(gòu)造器Constructor是否可被override?
構(gòu)造器Constructor不能被繼承,因此不能重寫Overriding,但可以被重載Overloading。
41、是否可以繼承String類?
String類是final類故不可以繼承。
42、swtich是否能作用在byte上,是否能作用在long上,是否能作用在String上?
switch(expr1)中,expr1是一個(gè)整數(shù)表達(dá)式。因此傳遞給 switch 和 case 語句的參數(shù)應(yīng)該是 int、 short、 char 或者 byte。long,string 都不能作用于swtich。
43、try {}里有一個(gè)return語句,那么緊跟在這個(gè)try后的finally {}里的code會(huì)不會(huì)被執(zhí)行,什么時(shí)候被執(zhí)行,在return前還是后?
會(huì)執(zhí)行,在return前執(zhí)行。
44、編程題: 用最有效率的方法算出2乘以8等於幾?
2 << 3
45、兩個(gè)對象值相同(x.equals(y) == true),但卻可有不同的hash code,這句話對不對?
不對,有相同的hash code。
46、當(dāng)一個(gè)對象被當(dāng)作參數(shù)傳遞到一個(gè)方法后,此方法可改變這個(gè)對象的屬性,并可返回變化后的結(jié)果,那么這里到底是值傳遞還是引用傳遞?
是值傳遞。Java 編程語言只有值傳遞參數(shù)。當(dāng)一個(gè)對象實(shí)例作為一個(gè)參數(shù)被傳遞到方法中時(shí),參數(shù)的值就是對該對象的引用。對象的內(nèi)容可以在被調(diào)用的方法中改變,但對象的引用是永遠(yuǎn)不會(huì)改變的。
47、當(dāng)一個(gè)線程進(jìn)入一個(gè)對象的一個(gè)synchronized方法后,其它線程是否可進(jìn)入此對象的其它方法?
不能,一個(gè)對象的一個(gè)synchronized方法只能由一個(gè)線程訪問。
48、編程題: 寫一個(gè)Singleton出來。
Singleton模式主要作用是保證在Java應(yīng)用程序中,一個(gè)類Class只有一個(gè)實(shí)例存在。
一般Singleton模式通常有幾種種形式:
第一種形式: 定義一個(gè)類,它的構(gòu)造函數(shù)為private的,它有一個(gè)static的private的該類變量,在類初始化時(shí)實(shí)例話,通過一個(gè)public的getInstance方法獲取對它的引用,繼而調(diào)用其中的方法。
public class Singleton {
private Singleton(){}
  ??? //在自己內(nèi)部定義自己一個(gè)實(shí)例,是不是很奇怪?
  ??? //注意這是private 只供內(nèi)部調(diào)用
  ??? private static Singleton instance = new Singleton();
  ??? //這里提供了一個(gè)供外部訪問本class的靜態(tài)方法,可以直接訪問  
  ??? public static Singleton getInstance() {
    ??? return instance;   
  ??? }
??? }
??? 第二種形式:
public class Singleton {
  private static Singleton instance = null;
  public static synchronized Singleton getInstance() {
  //這個(gè)方法比上面有所改進(jìn),不用每次都進(jìn)行生成對象,只是第一次     
  //使用時(shí)生成實(shí)例,提高了效率!
  if (instance==null)
    instance=new Singleton();
return instance;   }
}
其他形式:
定義一個(gè)類,它的構(gòu)造函數(shù)為private的,所有方法為static的。
一般認(rèn)為第一種形式要更加安全些
49、Java的接口和C++的虛類的相同和不同處。
由 于Java不支持多繼承,而有可能某個(gè)類或?qū)ο笠褂梅謩e在幾個(gè)類或?qū)ο罄锩娴姆椒ɑ驅(qū)傩裕F(xiàn)有的單繼承機(jī)制就不能滿足要求。與繼承相比,接口有更高的靈 活性,因?yàn)榻涌谥袥]有任何實(shí)現(xiàn)代碼。當(dāng)一個(gè)類實(shí)現(xiàn)了接口以后,該類要實(shí)現(xiàn)接口里面所有的方法和屬性,并且接口里面的屬性在默認(rèn)狀態(tài)下面都是public static,所有方法默認(rèn)情況下是public.一個(gè)類可以實(shí)現(xiàn)多個(gè)接口。
50、Java中的異常處理機(jī)制的簡單原理和應(yīng)用。
當(dāng)JAVA 程序違反了JAVA的語義規(guī)則時(shí),JAVA虛擬機(jī)就會(huì)將發(fā)生的錯(cuò)誤表示為一個(gè)異常。違反語義規(guī)則包括2種情況。一種是JAVA類庫內(nèi)置的語義檢查。例如數(shù) 組下標(biāo)越界,會(huì)引發(fā)IndexOutOfBoundsException;訪問null的對象時(shí)會(huì)引發(fā)NullPointerException。另一種 情況就是JAVA允許程序員擴(kuò)展這種語義檢查,程序員可以創(chuàng)建自己的異常,并自由選擇在何時(shí)用throw關(guān)鍵字引發(fā)異常。所有的異常都是 java.lang.Thowable的子類。
51、垃圾回收的優(yōu)點(diǎn)和原理。并考慮2種回收機(jī)制。
Java語言中一個(gè)顯著的特點(diǎn)就是引入 了垃圾回收機(jī)制,使c++程序員最頭疼的內(nèi)存管理的問題迎刃而解,它使得Java程序員在編寫程序的時(shí)候不再需要考慮內(nèi)存管理。由于有個(gè)垃圾回收機(jī)制, Java中的對象不再有"作用域"的概念,只有對象的引用才有"作用域"。垃圾回收可以有效的防止內(nèi)存泄露,有效的使用可以使用的內(nèi)存。垃圾回收器通常是 作為一個(gè)單獨(dú)的低級別的線程運(yùn)行,不可預(yù)知的情況下對內(nèi)存堆中已經(jīng)死亡的或者長時(shí)間沒有使用的對象進(jìn)行清楚和回收,程序員不能實(shí)時(shí)的調(diào)用垃圾回收器對某個(gè) 對象或所有對象進(jìn)行垃圾回收。回收機(jī)制有分代復(fù)制垃圾回收和標(biāo)記垃圾回收,增量垃圾回收。
52、請說出你所知道的線程同步的方法。
wait():使一個(gè)線程處于等待狀態(tài),并且釋放所持有的對象的lock。
sleep():使一個(gè)正在運(yùn)行的線程處于睡眠狀態(tài),是一個(gè)靜態(tài)方法,調(diào)用此方法要捕捉InterruptedException異常。
notify():喚醒一個(gè)處于等待狀態(tài)的線程,注意的是在調(diào)用此方法的時(shí)候,并不能確切的喚醒某一個(gè)等待狀態(tài)的線程,而是由JVM確定喚醒哪個(gè)線程,而且不是按優(yōu)先級。
Allnotity():喚醒所有處入等待狀態(tài)的線程,注意并不是給所有喚醒線程一個(gè)對象的鎖,而是讓它們競爭。
53、你所知道的集合類都有哪些?主要方法?
最常用的集合類是 List 和 Map。 List 的具體實(shí)現(xiàn)包括 ArrayList 和 Vector,它們是可變大小的列表,比較適合構(gòu)建、存儲(chǔ)和操作任何類型對象的元素列表。 List 適用于按數(shù)值索引訪問元素的情形。
Map 提供了一個(gè)更通用的元素存儲(chǔ)方法。 Map 集合類用于存儲(chǔ)元素對(稱作"鍵"和"值"),其中每個(gè)鍵映射到一個(gè)值。
54、描述一下JVM加載class文件的原理機(jī)制?
JVM中類的裝載是由ClassLoader和它的子類來實(shí)現(xiàn)的,Java ClassLoader 是一個(gè)重要的Java運(yùn)行時(shí)系統(tǒng)組件。它負(fù)責(zé)在運(yùn)行時(shí)查找和裝入類文件的類。
55、char型變量中能不能存貯一個(gè)中文漢字?為什么?
能夠定義成為一個(gè)中文的,因?yàn)閖ava中以unicode編碼,一個(gè)char占16個(gè)字節(jié),所以放一個(gè)中文是沒問題的
56、多線程有幾種實(shí)現(xiàn)方法,都是什么?同步有幾種實(shí)現(xiàn)方法,都是什么?
多線程有兩種實(shí)現(xiàn)方法,分別是繼承Thread類與實(shí)現(xiàn)Runnable接口
同步的實(shí)現(xiàn)方面有兩種,分別是synchronized,wait與notify
57、JSP的內(nèi)置對象及方法。
request表示HttpServletRequest對象。它包含了有關(guān)瀏覽器請求的信息,并且提供了幾個(gè)用于獲取cookie, header, 和session數(shù)據(jù)的有用的方法。
??? response表示HttpServletResponse對象,并提供了幾個(gè)用于設(shè)置送回 瀏覽器的響應(yīng)的方法(如cookies,頭信息等)
??? out對象是javax.jsp.JspWriter的一個(gè)實(shí)例,并提供了幾個(gè)方法使你能用于向?yàn)g覽器回送輸出結(jié)果。
??? pageContext表示一個(gè)javax.servlet.jsp.PageContext對象。它是用于方便存取各種范圍的名字空間、servlet相關(guān)的對象的API,并且包裝了通用的servlet相關(guān)功能的方法。
??? session表示一個(gè)請求的javax.servlet.http.HttpSession對象。Session可以存貯用戶的狀態(tài)信息
??? applicaton 表示一個(gè)javax.servle.ServletContext對象。這有助于查找有關(guān)servlet引擎和servlet環(huán)境的信息
??? config表示一個(gè)javax.servlet.ServletConfig對象。該對象用于存取servlet實(shí)例的初始化參數(shù)。
??? page表示從該頁面產(chǎn)生的一個(gè)servlet實(shí)例
58、線程的基本概念、線程的基本狀態(tài)以及狀態(tài)之間的關(guān)系
線程指在程序執(zhí)行過程中,能夠執(zhí)行程序代碼的一個(gè)執(zhí)行單位,每個(gè)程序至少都有一個(gè)線程,也就是程序本身。
Java中的線程有四種狀態(tài)分別是:運(yùn)行、就緒、掛起、結(jié)束。
59、JSP的常用指令
<%@page language="java" contenType="text/html;charset=gb2312" session="true" buffer="64kb" autoFlush="true" isThreadSafe="true" info="text" errorPage="error.jsp" isErrorPage="true" isELIgnored="true" pageEncoding="gb2312" import="java.sql.*"%>
isErrorPage(是否能使用Exception對象),isELIgnored(是否忽略表達(dá)式)
<%@include file="filename"%>
<%@taglib prefix="c"uri="http://......"%>
60、什么情況下調(diào)用doGet()和doPost()?
Jsp頁面中的form標(biāo)簽里的method屬性為get時(shí)調(diào)用doGet(),為post時(shí)調(diào)用doPost()。
61、servlet的生命周期
web容器加載servlet,生命周期開始。通過調(diào)用servlet的init()方法進(jìn)行servlet的初始化。通過調(diào)用service()方法實(shí)現(xiàn),根據(jù)請求的不同調(diào)用不同的do***()方法。結(jié)束服務(wù),web容器調(diào)用servlet的destroy()方法。
62、如何現(xiàn)實(shí)servlet的單線程模式
<%@ page isThreadSafe="false"%>
63、頁面間對象傳遞的方法
request,session,application,cookie等
64、JSP和Servlet有哪些相同點(diǎn)和不同點(diǎn),他們之間的聯(lián)系是什么?
JSP 是Servlet技術(shù)的擴(kuò)展,本質(zhì)上是Servlet的簡易方式,更強(qiáng)調(diào)應(yīng)用的外表表達(dá)。JSP編譯后是"類servlet"。Servlet和JSP最 主要的不同點(diǎn)在于,Servlet的應(yīng)用邏輯是在Java文件中,并且完全從表示層中的HTML里分離開來。而JSP的情況是Java和HTML可以組合 成一個(gè)擴(kuò)展名為.jsp的文件。JSP側(cè)重于視圖,Servlet主要用于控制邏輯。
65、四種會(huì)話跟蹤技術(shù)
會(huì)話作用域ServletsJSP 頁面描述
page否是代表與一個(gè)頁面相關(guān)的對象和屬性。一個(gè)頁面由一個(gè)編譯好的 Java servlet 類(可以帶有任何的 include 指令,但是沒有 include 動(dòng)作)表示。這既包括 servlet 又包括被編譯成 servlet 的 JSP 頁面
request是是代表與 Web 客戶機(jī)發(fā)出的一個(gè)請求相關(guān)的對象和屬性。一個(gè)請求可能跨越多個(gè)頁面,涉及多個(gè) Web 組件(由于 forward 指令和 include 動(dòng)作的關(guān)系)
session是是代表與用于某個(gè) Web 客戶機(jī)的一個(gè)用戶體驗(yàn)相關(guān)的對象和屬性。一個(gè) Web 會(huì)話可以也經(jīng)常會(huì)跨越多個(gè)客戶機(jī)請求
application是是代表與整個(gè) Web 應(yīng)用程序相關(guān)的對象和屬性。這實(shí)質(zhì)上是跨越整個(gè) Web 應(yīng)用程序,包括多個(gè)頁面、請求和會(huì)話的一個(gè)全局作用域
66、Request對象的主要方法:
setAttribute(String name,Object):設(shè)置名字為name的request的參數(shù)值
getAttribute(String name):返回由name指定的屬性值
getAttributeNames():返回request對象所有屬性的名字集合,結(jié)果是一個(gè)枚舉的實(shí)例
getCookies():返回客戶端的所有Cookie對象,結(jié)果是一個(gè)Cookie數(shù)組
getCharacterEncoding():返回請求中的字符編碼方式
getContentLength():返回請求的Body的長度
getHeader(String name):獲得HTTP協(xié)議定義的文件頭信息
getHeaders(String name):返回指定名字的request Header的所有值,結(jié)果是一個(gè)枚舉的實(shí)例
getHeaderNames():返回所以request Header的名字,結(jié)果是一個(gè)枚舉的實(shí)例
getInputStream():返回請求的輸入流,用于獲得請求中的數(shù)據(jù)
getMethod():獲得客戶端向服務(wù)器端傳送數(shù)據(jù)的方法
getParameter(String name):獲得客戶端傳送給服務(wù)器端的有name指定的參數(shù)值
getParameterNames():獲得客戶端傳送給服務(wù)器端的所有參數(shù)的名字,結(jié)果是一個(gè)枚舉的實(shí)例
getParameterValues(String name):獲得有name指定的參數(shù)的所有值
getProtocol():獲取客戶端向服務(wù)器端傳送數(shù)據(jù)所依據(jù)的協(xié)議名稱
getQueryString():獲得查詢字符串
getRequestURI():獲取發(fā)出請求字符串的客戶端地址
getRemoteAddr():獲取客戶端的IP地址
getRemoteHost():獲取客戶端的名字
getSession([Boolean create]):返回和請求相關(guān)Session
getServerName():獲取服務(wù)器的名字
getServletPath():獲取客戶端所請求的腳本文件的路徑
getServerPort():獲取服務(wù)器的端口號
removeAttribute(String name):刪除請求中的一個(gè)屬性
67、J2EE是技術(shù)還是平臺還是框架?
??? J2EE本身是一個(gè)標(biāo)準(zhǔn),一個(gè)為企業(yè)分布式應(yīng)用的開發(fā)提供的標(biāo)準(zhǔn)平臺。
??? J2EE也是一個(gè)框架,包括JDBC、JNDI、RMI、JMS、EJB、JTA等技術(shù)。
68、我們在web應(yīng)用開發(fā)過程中經(jīng)常遇到輸出某種編碼的字符,如iso8859-1等,如何輸出一個(gè)某種編碼的字符串?
? 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、簡述邏輯操作(&,|,^)與條件操作(&&,||)的區(qū)別。
區(qū)別主要答兩點(diǎn):a.條件操作只能操作布爾型的,而邏輯操作不僅可以操作布爾型,而且可以操作數(shù)值型
b.邏輯操作不會(huì)產(chǎn)生短路
70、XML文檔定義有幾種形式?它們之間有何本質(zhì)區(qū)別?解析XML文檔有哪幾種方式?
a: 兩種形式 dtd? schema,b: 本質(zhì)區(qū)別:schema本身是xml的,可以被XML解析器解析(這也是從DTD上發(fā)展schema的根本目的),c:有DOM,SAX,STAX等
??? DOM:處理大型文件時(shí)其性能下降的非常厲害。這個(gè)問題是由DOM的樹結(jié)構(gòu)所造成的,這種結(jié)構(gòu)占用的內(nèi)存較多,而且DOM必須在解析文件之前把整個(gè)文檔裝入內(nèi)存,適合對XML的隨機(jī)訪問
SAX:不現(xiàn)于DOM,SAX是事件驅(qū)動(dòng)型的XML解析方式。它順序讀取XML文件,不需要一次全部裝載整個(gè)文件。當(dāng)遇到像文件開頭,文檔結(jié)束,或者標(biāo)簽開頭與標(biāo)簽結(jié)束時(shí),它會(huì)觸發(fā)一個(gè)事件,用戶通過在其回調(diào)事件中寫入處理代碼來處理XML文件,適合對XML的順序訪問
??? STAX:Streaming API for XML (StAX)
71、簡述synchronized和java.util.concurrent.locks.Lock的異同 ?
主要相同點(diǎn):Lock能完成synchronized所實(shí)現(xiàn)的所有功能
主要不同點(diǎn):Lock有比synchronized更精確的線程語義和更好的性能。synchronized會(huì)自動(dòng)釋放鎖,而Lock一定要求程序員手工釋放,并且必須在finally從句中釋放。
72、EJB的角色和三個(gè)對象
一 個(gè)完整的基于EJB的分布式計(jì)算結(jié)構(gòu)由六個(gè)角色組成,這六個(gè)角色可以由不同的開發(fā)商提供,每個(gè)角色所作的工作必須遵循Sun公司提供的EJB規(guī)范,以保證 彼此之間的兼容性。這六個(gè)角色分別是EJB組件開發(fā)者(Enterprise Bean Provider) 、應(yīng)用組合者(Application Assembler)、部署者(Deployer)、EJB 服務(wù)器提供者(EJB Server Provider)、EJB 容器提供者(EJB Container Provider)、系統(tǒng)管理員(System Administrator)
三個(gè)對象是Remote(Local)接口、Home(LocalHome)接口,Bean類
73、EJB容器提供的服務(wù)
主要提供聲明周期管理、代碼產(chǎn)生、持續(xù)性管理、安全、事務(wù)管理、鎖和并發(fā)行管理等服務(wù)。
74、EJB規(guī)范規(guī)定EJB中禁止的操作有哪些?
??? 1.不能操作線程和線程API(線程API指非線程對象的方法如notify,wait等),2.不能操作awt,3.不能實(shí)現(xiàn)服務(wù)器功能,4.不能對靜 態(tài)屬生存取,5.不能使用IO操作直接存取文件系統(tǒng),6.不能加載本地庫.,7.不能將this作為變量和返回,8.不能循環(huán)調(diào)用。
75、remote接口和home接口主要作用
remote接口定義了業(yè)務(wù)方法,用于EJB客戶端調(diào)用業(yè)務(wù)方法。
home接口是EJB工廠用于創(chuàng)建和移除查找EJB實(shí)例
76、bean 實(shí)例的生命周期
對 于Stateless Session Bean、Entity Bean、Message Driven Bean一般存在緩沖池管理,而對于Entity Bean和Statefull Session Bean存在Cache管理,通常包含創(chuàng)建實(shí)例,設(shè)置上下文、創(chuàng)建EJB Object(create)、業(yè)務(wù)方法調(diào)用、remove等過程,對于存在緩沖池管理的Bean,在create之后實(shí)例并不從內(nèi)存清除,而是采用緩沖 池調(diào)度機(jī)制不斷重用實(shí)例,而對于存在Cache管理的Bean則通過激活和去激活機(jī)制保持Bean的狀態(tài)并限制內(nèi)存中實(shí)例數(shù)量。
77、EJB的激活機(jī)制
以Stateful Session Bean 為例:其Cache大小決定了內(nèi)存中可以同時(shí)存在的Bean實(shí)例的數(shù)量,根據(jù)MRU或NRU算法,實(shí)例在激活和去激活狀態(tài)之間遷移,激活機(jī)制是當(dāng)客戶端調(diào) 用某個(gè)EJB實(shí)例業(yè)務(wù)方法時(shí),如果對應(yīng)EJB Object發(fā)現(xiàn)自己沒有綁定對應(yīng)的Bean實(shí)例則從其去激活Bean存儲(chǔ)中(通過序列化機(jī)制存儲(chǔ)實(shí)例)回復(fù)(激活)此實(shí)例。狀態(tài)變遷前會(huì)調(diào)用對應(yīng)的 ejbActive和ejbPassivate方法。
78、EJB的幾種類型
會(huì)話(Session)Bean ,實(shí)體(Entity)Bean 消息驅(qū)動(dòng)的(Message Driven)Bean
會(huì)話Bean又可分為有狀態(tài)(Stateful)和無狀態(tài)(Stateless)兩種
實(shí)體Bean可分為Bean管理的持續(xù)性(BMP)和容器管理的持續(xù)性(CMP)兩種
79、客服端調(diào)用EJB對象的幾個(gè)基本步驟
設(shè)置JNDI服務(wù)工廠以及JNDI服務(wù)地址系統(tǒng)屬性,查找Home接口,從Home接口調(diào)用Create方法創(chuàng)建Remote接口,通過Remote接口調(diào)用其業(yè)務(wù)方法。
80、如何給weblogic指定大小的內(nèi)存?
在啟動(dòng)Weblogic的腳本中(位于所在Domian對應(yīng)服務(wù)器目錄下的startServerName),增加set MEM_ARGS=-Xms32m -Xmx200m,可以調(diào)整最小內(nèi)存為32M,最大200M
81、如何設(shè)定的weblogic的熱啟動(dòng)模式(開發(fā)模式)與產(chǎn)品發(fā)布模式?
可以在管理控制臺中修改對應(yīng)服務(wù)器的啟動(dòng)模式為開發(fā)或產(chǎn)品模式之一。或者修改服務(wù)的啟動(dòng)文件或者commenv文件,增加set PRODUCTION_MODE=true。
82、如何啟動(dòng)時(shí)不需輸入用戶名與密碼?
修改服務(wù)啟動(dòng)文件,增加 WLS_USER和WLS_PW項(xiàng)。也可以在boot.properties文件中增加加密過的用戶名和密碼.
83、在weblogic管理制臺中對一個(gè)應(yīng)用域(或者說是一個(gè)網(wǎng)站,Domain)進(jìn)行jms及ejb或連接池等相關(guān)信息進(jìn)行配置后,實(shí)際保存在什么文件中?
保存在此Domain的config.xml文件中,它是服務(wù)器的核心配置文件。
84、 說說weblogic中一個(gè)Domain的缺省目錄結(jié)構(gòu)?比如要將一個(gè)簡單的helloWorld.jsp放入何目錄下,然的在瀏覽器上就可打入 http://主機(jī):端口號//helloword.jsp就可以看到運(yùn)行結(jié)果了? 又比如這其中用到了一個(gè)自己寫的javaBean該如何辦?
Domain 目錄服務(wù)器目錄applications,將應(yīng)用目錄放在此目錄下將可以作為應(yīng)用訪問,如果是Web應(yīng)用,應(yīng)用目錄需要滿足Web應(yīng)用目錄要求,jsp文 件可以直接放在應(yīng)用目錄中,Javabean需要放在應(yīng)用目錄的WEB-INF目錄的classes目錄中,設(shè)置服務(wù)器的缺省應(yīng)用將可以實(shí)現(xiàn)在瀏覽器上無 需輸入應(yīng)用名。
85、在weblogic中發(fā)布ejb需涉及到哪些配置文件
不同類型的EJB涉及的配置文件不同,都涉及到的配置文件包括ejb-jar.xml,weblogic-ejb-jar.xmlCMP實(shí)體Bean一般還需要weblogic-cmp-rdbms-jar.xml
86、如何在weblogic中進(jìn)行ssl配置與客戶端的認(rèn)證配置或說說j2ee(標(biāo)準(zhǔn))進(jìn)行ssl的配置
缺 省安裝中使用DemoIdentity.jks和DemoTrust.jks? KeyStore實(shí)現(xiàn)SSL,需要配置服務(wù)器使用Enable SSL,配置其端口,在產(chǎn)品模式下需要從CA獲取私有密鑰和數(shù)字證書,創(chuàng)建identity和trust keystore,裝載獲得的密鑰和數(shù)字證書。可以配置此SSL連接是單向還是雙向的。
87、如何查看在weblogic中已經(jīng)發(fā)布的EJB?
可以使用管理控制臺,在它的Deployment中可以查看所有已發(fā)布的EJB
88、CORBA是什么?用途是什么?
CORBA 標(biāo)準(zhǔn)是公共對象請求代理結(jié)構(gòu)(Common Object Request Broker Architecture),由對象管理組織 (Object Management Group,縮寫為 OMG)標(biāo)準(zhǔn)化。它的組成是接口定義語言(IDL), 語言綁定(binding:也譯為聯(lián)編)和允許應(yīng)用程序間互操作的協(xié)議。其目的為:用不同的程序設(shè)計(jì)語言書寫在不同的進(jìn)程中運(yùn)行,為不同的操作系統(tǒng)開發(fā)。
89、說說你所熟悉或聽說過的j2ee中的幾種常用模式?及對設(shè)計(jì)模式的一些看法
? Session Facade Pattern:使用SessionBean訪問EntityBean
Message Facade Pattern:實(shí)現(xiàn)異步調(diào)用
EJB Command Pattern:使用Command JavaBeans取代SessionBean,實(shí)現(xiàn)輕量級訪問
Data Transfer Object Factory:通過DTO Factory簡化EntityBean數(shù)據(jù)提供特性
Generic Attribute Access:通過AttibuteAccess接口簡化EntityBean數(shù)據(jù)提供特性
Business Interface:通過遠(yuǎn)程(本地)接口和Bean類實(shí)現(xiàn)相同接口規(guī)范業(yè)務(wù)邏輯一致性
EJB架構(gòu)的設(shè)計(jì)好壞將直接影響系統(tǒng)的性能、可擴(kuò)展性、可維護(hù)性、組件可重用性及開發(fā)效率。項(xiàng)目越復(fù)雜,項(xiàng)目隊(duì)伍越龐大則越能體現(xiàn)良好設(shè)計(jì)的重要性。
90、說說在weblogic中開發(fā)消息Bean時(shí)的persistent與non-persisten的差別
persistent方式的MDB可以保證消息傳遞的可靠性,也就是如果EJB容器出現(xiàn)問題而JMS服務(wù)器依然會(huì)將消息在此MDB可用的時(shí)候發(fā)送過來,而non-persistent方式的消息將被丟棄。
91、Servlet執(zhí)行時(shí)一般實(shí)現(xiàn)哪幾個(gè)方法?
public void init(ServletConfig config)
public ServletConfig getServletConfig()
public String getServletInfo()
public void service(ServletRequest request,ServletResponse response)
public void destroy()
92、j2ee常用的設(shè)計(jì)模式?說明工廠模式。
??? Java中的23種設(shè)計(jì)模式:
Factory(工廠模式),????? Builder(建造模式),?????? Factory Method(工廠方法模式),
Prototype(原始模型模式),Singleton(單例模式),??? Facade(門面模式),
Adapter(適配器模式),??? Bridge(橋梁模式),??????? Composite(合成模式),
Decorator(裝飾模式),??? Flyweight(享元模式),???? Proxy(代理模式),
Command(命令模式),????? Interpreter(解釋器模式), Visitor(訪問者模式),
Iterator(迭代子模式),?? Mediator(調(diào)停者模式),??? Memento(備忘錄模式),
Observer(觀察者模式),?? State(狀態(tài)模式),???????? Strategy(策略模式),
Template Method(模板方法模式), Chain Of Responsibleity(責(zé)任鏈模式)
工 廠模式:工廠模式是一種經(jīng)常被使用到的模式,根據(jù)工廠模式實(shí)現(xiàn)的類可以根據(jù)提供的數(shù)據(jù)生成一組類中某一個(gè)類的實(shí)例,通常這一組類有一個(gè)公共的抽象父類并且 實(shí)現(xiàn)了相同的方法,但是這些方法針對不同的數(shù)據(jù)進(jìn)行了不同的操作。首先需要定義一個(gè)基類,該類的子類通過不同的方法實(shí)現(xiàn)了基類中的方法。然后需要定義一個(gè) 工廠類,工廠類可以根據(jù)條件生成不同的子類實(shí)例。當(dāng)?shù)玫阶宇惖膶?shí)例后,開發(fā)人員可以調(diào)用基類中的方法而不必考慮到底返回的是哪一個(gè)子類的實(shí)例。
93、EJB需直接實(shí)現(xiàn)它的業(yè)務(wù)接口或Home接口嗎,請簡述理由。
遠(yuǎn)程接口和Home接口不需要直接實(shí)現(xiàn),他們的實(shí)現(xiàn)代碼是由服務(wù)器產(chǎn)生的,程序運(yùn)行中對應(yīng)實(shí)現(xiàn)類會(huì)作為對應(yīng)接口類型的實(shí)例被使用。
94、排序都有哪幾種方法?請列舉。用JAVA實(shí)現(xiàn)一個(gè)快速排序。
??? 排序的方法有:插入排序(直接插入排序、希爾排序),交換排序(冒泡排序、快速排序),選擇排序(直接選擇排序、堆排序),歸并排序,分配排序(箱排序、基數(shù)排序)
快速排序的偽代碼。
/ /使用快速排序方法對a[ 0 :n- 1 ]排序
從a[ 0 :n- 1 ]中選擇一個(gè)元素作為m i d d l e,該元素為支點(diǎn)
把余下的元素分割為兩段left 和r i g h t,使得l e f t中的元素都小于等于支點(diǎn),而right 中的元素都大于等于支點(diǎn)
遞歸地使用快速排序方法對left 進(jìn)行排序
遞歸地使用快速排序方法對right 進(jìn)行排序
所得結(jié)果為l e f t + m i d d l e + r i g h t
95、請對以下在J2EE中常用的名詞進(jìn)行解釋(或簡單描述)
web 容器:給處于其中的應(yīng)用程序組件(JSP,SERVLET)提供一個(gè)環(huán)境,使JSP,SERVLET直接更容器中的環(huán)境變量接口交互,不必關(guān)注其它系統(tǒng)問 題。主要有WEB服務(wù)器來實(shí)現(xiàn)。例如:TOMCAT,WEBLOGIC,WEBSPHERE等。該容器提供的接口嚴(yán)格遵守J2EE規(guī)范中的WEB APPLICATION 標(biāo)準(zhǔn)。我們把遵守以上標(biāo)準(zhǔn)的WEB服務(wù)器就叫做J2EE中的WEB容器。
EJB容器:Enterprise java bean 容器。更具有行業(yè)領(lǐng)域特色。他提供給運(yùn)行在其中的組件EJB各種管理功能。只要滿足J2EE規(guī)范的EJB放入該容器,馬上就會(huì)被容器進(jìn)行高效率的管理。并 且可以通過現(xiàn)成的接口來獲得系統(tǒng)級別的服務(wù)。例如郵件服務(wù)、事務(wù)管理。
JNDI:(Java Naming & Directory Interface)JAVA命名目錄服務(wù)。主要提供的功能是:提供一個(gè)目錄系統(tǒng),讓其它各地的應(yīng)用程序在其上面留下自己的索引,從而滿足快速查找和定位分布式應(yīng)用程序的功能。
JMS:(Java Message Service)JAVA消息服務(wù)。主要實(shí)現(xiàn)各個(gè)應(yīng)用程序之間的通訊。包括點(diǎn)對點(diǎn)和廣播。
JTA:(Java Transaction API)JAVA事務(wù)服務(wù)。提供各種分布式事務(wù)服務(wù)。應(yīng)用程序只需調(diào)用其提供的接口即可。
JAF:(Java Action FrameWork)JAVA安全認(rèn)證框架。提供一些安全控制方面的框架。讓開發(fā)者通過各種部署和自定義實(shí)現(xiàn)自己的個(gè)性安全控制策略。
RMI/IIOP: (Remote Method Invocation /internet對象請求中介協(xié)議)他們主要用于通過遠(yuǎn)程調(diào)用服務(wù)。例如,遠(yuǎn)程有一臺計(jì)算機(jī)上運(yùn)行一個(gè)程序,它提供股票分析服務(wù),我們可以在本地計(jì)算機(jī) 上實(shí)現(xiàn)對其直接調(diào)用。當(dāng)然這是要通過一定的規(guī)范才能在異構(gòu)的系統(tǒng)之間進(jìn)行通信。RMI是JAVA特有的。
96、JAVA語言如何進(jìn)行異常處理,關(guān)鍵字:throws,throw,try,catch,finally分別代表什么意義?在try塊中可以拋出異常嗎?
Java 通過面向?qū)ο蟮姆椒ㄟM(jìn)行異常處理,把各種不同的異常進(jìn)行分類,并提供了良好的接口。在Java中,每個(gè)異常都是一個(gè)對象,它是Throwable類或其它 子類的實(shí)例。當(dāng)一個(gè)方法出現(xiàn)異常后便拋出一個(gè)異常對象,該對象中包含有異常信息,調(diào)用這個(gè)對象的方法可以捕獲到這個(gè)異常并進(jìn)行處理。Java的異常處理是 通過5個(gè)關(guān)鍵詞來實(shí)現(xiàn)的:try、catch、throw、throws和finally。一般情況下是用try來執(zhí)行一段程序,如果出現(xiàn)異常,系統(tǒng)會(huì)拋 出(throws)一個(gè)異常,這時(shí)候你可以通過它的類型來捕捉(catch)它,或最后(finally)由缺省處理器來處理。
用try來指定一塊預(yù)防所有"異常"的程序。緊跟在try程序后面,應(yīng)包含一個(gè)catch子句來指定你想要捕捉的"異常"的類型。
throw語句用來明確地拋出一個(gè)"異常"。
throws用來標(biāo)明一個(gè)成員函數(shù)可能拋出的各種"異常"。
Finally為確保一段代碼不管發(fā)生什么"異常"都被執(zhí)行一段代碼。
可 以在一個(gè)成員函數(shù)調(diào)用的外面寫一個(gè)try語句,在這個(gè)成員函數(shù)內(nèi)部寫另一個(gè)try語句保護(hù)其他代碼。每當(dāng)遇到一個(gè)try語句,"異常"的框架就放到堆棧上 面,直到所有的try語句都完成。如果下一級的try語句沒有對某種"異常"進(jìn)行處理,堆棧就會(huì)展開,直到遇到有處理這種"異常"的try語句。
97、一個(gè)".java"源文件中是否可以包括多個(gè)類(不是內(nèi)部類)?有什么限制?
可以。必須只有一個(gè)類名與文件名相同。
98、MVC的各個(gè)部分都有那些技術(shù)來實(shí)現(xiàn)?如何實(shí)現(xiàn)?
MVC 是Model-View-Controller的簡寫。"Model" 代表的是應(yīng)用的業(yè)務(wù)邏輯(通過JavaBean,EJB組件實(shí)現(xiàn)), "View" 是應(yīng)用的表示面(由JSP頁面產(chǎn)生),"Controller" 是提供應(yīng)用的處理過程控制(一般是一個(gè)Servlet),通過這種設(shè)計(jì)模型把應(yīng)用邏輯,處理過程和顯示邏輯分成不同的組件實(shí)現(xiàn)。這些組件可以進(jìn)行交互和重 用。
99、java中有幾種方法可以實(shí)現(xiàn)一個(gè)線程?用什么關(guān)鍵字修飾同步方法? stop()和suspend()方法為何不推薦使用?
有兩種實(shí)現(xiàn)方法,分別是繼承Thread類與實(shí)現(xiàn)Runnable接口
用synchronized關(guān)鍵字修飾同步方法
反 對使用stop(),是因?yàn)樗话踩K鼤?huì)解除由線程獲取的所有鎖定,而且如果對象處于一種不連貫狀態(tài),那么其他線程能在那種狀態(tài)下檢查和修改它們。結(jié)果 很難檢查出真正的問題所在。suspend()方法容易發(fā)生死鎖。調(diào)用suspend()的時(shí)候,目標(biāo)線程會(huì)停下來,但卻仍然持有在這之前獲得的鎖定。此 時(shí),其他任何線程都不能訪問鎖定的資源,除非被"掛起"的線程恢復(fù)運(yùn)行。對任何線程來說,如果它們想恢復(fù)目標(biāo)線程,同時(shí)又試圖使用任何一個(gè)鎖定的資源,就 會(huì)造成死鎖。所以不應(yīng)該使用suspend(),而應(yīng)在自己的Thread類中置入一個(gè)標(biāo)志,指出線程應(yīng)該活動(dòng)還是掛起。若標(biāo)志指出線程應(yīng)該掛起,便用 wait()命其進(jìn)入等待狀態(tài)。若標(biāo)志指出線程應(yīng)當(dāng)恢復(fù),則用一個(gè)notify()重新啟動(dòng)線程。
100、java中有幾種類型的流?JDK為每種類型的流提供了一些抽象類以供繼承,請說出他們分別是哪些類?
字節(jié)流,字符流。字節(jié)流繼承于InputStream OutputStream,字符流繼承于InputStreamReader OutputStreamWriter。在java.io包中還有許多其他的流,主要是為了提高性能和使用方便。
101、java中會(huì)存在內(nèi)存泄漏嗎,請簡單描述。
會(huì)。如:int i,i2;? return (i-i2);?? //when i為足夠大的正數(shù),i2為足夠大的負(fù)數(shù)。結(jié)果會(huì)造成溢位,導(dǎo)致錯(cuò)誤。
102、java中實(shí)現(xiàn)多態(tài)的機(jī)制是什么?
方法的重寫Overriding和重載Overloading是Java多態(tài)性的不同表現(xiàn)。重寫Overriding是父類與子類之間多態(tài)性的一種表現(xiàn),重載Overloading是一個(gè)類中多態(tài)性的一種表現(xiàn)。
103、垃圾回收器的基本原理是什么?垃圾回收器可以馬上回收內(nèi)存嗎?有什么辦法主動(dòng)通知虛擬機(jī)進(jìn)行垃圾回收?
對 于GC來說,當(dāng)程序員創(chuàng)建對象時(shí),GC就開始監(jiān)控這個(gè)對象的地址、大小以及使用情況。通常,GC采用有向圖的方式記錄和管理堆(heap)中的所有對象。 通過這種方式確定哪些對象是"可達(dá)的",哪些對象是"不可達(dá)的"。當(dāng)GC確定一些對象為"不可達(dá)"時(shí),GC就有責(zé)任回收這些內(nèi)存空間。可以。程序員可以手 動(dòng)執(zhí)行System.gc(),通知GC運(yùn)行,但是Java語言規(guī)范并不保證GC一定會(huì)執(zhí)行。
104、靜態(tài)變量和實(shí)例變量的區(qū)別?
static i = 10; //常量
?? class A a;? a.i =10;//可變
105、什么是java序列化,如何實(shí)現(xiàn)java序列化?
序列化就是一種用來處理對象流的機(jī)制,所謂對象流也就是將對象的內(nèi)容進(jìn)行流化。可以對流化后的對象進(jìn)行讀寫操作,也可將流化后的對象傳輸于網(wǎng)絡(luò)之間。序列化是為了解決在對對象流進(jìn)行讀寫操作時(shí)所引發(fā)的問題。
序 列化的實(shí)現(xiàn):將需要被序列化的類實(shí)現(xiàn)Serializable接口,該接口沒有需要實(shí)現(xiàn)的方法,implements Serializable只是為了標(biāo)注該對象是可被序列化的,然后使用一個(gè)輸出流(如:FileOutputStream)來構(gòu)造一個(gè) ObjectOutputStream(對象流)對象,接著,使用ObjectOutputStream對象的writeObject(Object obj)方法就可以將參數(shù)為obj的對象寫出(即保存其狀態(tài)),要恢復(fù)的話則用輸入流。
106、是否可以從一個(gè)static方法內(nèi)部發(fā)出對非static方法的調(diào)用?
不可以,如果其中包含對象的method();不能保證對象初始化.
107、寫clone()方法時(shí),通常都有一行代碼,是什么?
Clone 有缺省行為,super.clone();他負(fù)責(zé)產(chǎn)生正確大小的空間,并逐位復(fù)制。
108、在JAVA中,如何跳出當(dāng)前的多重嵌套循環(huán)?
用break; return 方法。
109、List、Map、Set三個(gè)接口,存取元素時(shí),各有什么特點(diǎn)?
List 以特定次序來持有元素,可有重復(fù)元素。Set 無法擁有重復(fù)元素,內(nèi)部排序。Map 保存key-value值,value可多值。
110、J2EE是什么?
J2EE 是Sun公司提出的多層(multi-diered),分布式(distributed),基于組件(component-base)的企業(yè)級應(yīng)用模型 (enterpriese application model).在這樣的一個(gè)應(yīng)用系統(tǒng)中,可按照功能劃分為不同的組件,這些組件又可在不同計(jì)算機(jī)上,并且處于相應(yīng)的層次(tier)中。所屬層次包括客戶 層(clietn tier)組件,web層和組件,Business層和組件,企業(yè)信息系統(tǒng)(EIS)層。
111、UML方面
標(biāo)準(zhǔn)建模語言UML。用例圖,靜態(tài)圖(包括類圖、對象圖和包圖),行為圖,交互圖(順序圖,合作圖),實(shí)現(xiàn)圖。
112、說出一些常用的類,包,接口,請各舉5個(gè)
常用的類:BufferedReader? BufferedWriter? FileReader? FileWirter? String? Integer
常用的包:java.lang? java.awt? java.io? java.util? java.sql
常用的接口:Remote? List? Map? Document? NodeList
113、開發(fā)中都用到了那些設(shè)計(jì)模式?用在什么場合?
每個(gè)模式都描述了一個(gè)在我們的環(huán)境中不斷出現(xiàn)的問題,然后描述了該問題的解決方案的核心。通過這種方式,你可以無數(shù)次地使用那些已有的解決方案,無需在重復(fù)相同的工作。主要用到了MVC的設(shè)計(jì)模式。用來開發(fā)JSP/Servlet或者J2EE的相關(guān)應(yīng)用。簡單工廠模式等。
114、jsp有哪些動(dòng)作?作用分別是什么?
JSP 共有以下6種基本動(dòng)作 jsp:include:在頁面被請求的時(shí)候引入一個(gè)文件。 jsp:useBean:尋找或者實(shí)例化一個(gè)JavaBean。 jsp:setProperty:設(shè)置JavaBean的屬性。 jsp:getProperty:輸出某個(gè)JavaBean的屬性。 jsp:forward:把請求轉(zhuǎn)到一個(gè)新的頁面。 jsp:plugin:根據(jù)瀏覽器類型為Java插件生成OBJECT或EMBED標(biāo)記。
115、Anonymous Inner Class (匿名內(nèi)部類) 是否可以extends(繼承)其它類,是否可以implements(實(shí)現(xiàn))interface(接口)?
可以繼承其他類或完成其他接口,在swing編程中常用此方式。
116、應(yīng)用服務(wù)器與WEB SERVER的區(qū)別?
應(yīng)用服務(wù)器:Weblogic、Tomcat、Jboss
WEB SERVER:IIS、 Apache
117、BS與CS的聯(lián)系與區(qū)別。
C/S是Client/Server的縮寫。服務(wù)器通常采用高性能的PC、工作站或小型機(jī),并采用大型數(shù)據(jù)庫系統(tǒng),如Oracle、Sybase、Informix或 SQL Server。客戶端需要安裝專用的客戶端軟件。
B/S 是Brower/Server的縮寫,客戶機(jī)上只要安裝一個(gè)瀏覽器(Browser),如Netscape Navigator或Internet Explorer,服務(wù)器安裝Oracle、Sybase、Informix或 SQL Server等數(shù)據(jù)庫。在這種結(jié)構(gòu)下,用戶界面完全通過WWW瀏覽器實(shí)現(xiàn),一部分事務(wù)邏輯在前端實(shí)現(xiàn),但是主要事務(wù)邏輯在服務(wù)器端實(shí)現(xiàn)。瀏覽器通過Web Server 同數(shù)據(jù)庫進(jìn)行數(shù)據(jù)交互。
C/S 與 B/S 區(qū)別:
1.硬件環(huán)境不同:
  C/S 一般建立在專用的網(wǎng)絡(luò)上, 小范圍里的網(wǎng)絡(luò)環(huán)境, 局域網(wǎng)之間再通過專門服務(wù)器提供連接和數(shù)據(jù)交換服務(wù).
  B/S 建立在廣域網(wǎng)之上的, 不必是專門的網(wǎng)絡(luò)硬件環(huán)境,例與電話上網(wǎng), 租用設(shè)備. 信息自己管理. 有比C/S更強(qiáng)的適應(yīng)范圍, 一般只要有操作系統(tǒng)和瀏覽器就行
2.對安全要求不同
  C/S 一般面向相對固定的用戶群, 對信息安全的控制能力很強(qiáng). 一般高度機(jī)密的信息系統(tǒng)采用C/S 結(jié)構(gòu)適宜. 可以通過B/S發(fā)布部分可公開信息.
  B/S 建立在廣域網(wǎng)之上, 對安全的控制能力相對弱, 可能面向不可知的用戶。
3.對程序架構(gòu)不同
  C/S 程序可以更加注重流程, 可以對權(quán)限多層次校驗(yàn), 對系統(tǒng)運(yùn)行速度可以較少考慮.
   B/S 對安全以及訪問速度的多重的考慮, 建立在需要更加優(yōu)化的基礎(chǔ)之上. 比C/S有更高的要求 B/S結(jié)構(gòu)的程序架構(gòu)是發(fā)展的趨勢, 從MS的.Net系列的BizTalk 2000 Exchange 2000等, 全面支持網(wǎng)絡(luò)的構(gòu)件搭建的系統(tǒng). SUN 和IBM推的JavaBean 構(gòu)件技術(shù)等,使 B/S更加成熟.
4.軟件重用不同
  C/S 程序可以不可避免的整體性考慮, 構(gòu)件的重用性不如在B/S要求下的構(gòu)件的重用性好.
  B/S 對的多重結(jié)構(gòu),要求構(gòu)件相對獨(dú)立的功能. 能夠相對較好的重用.就入買來的餐桌可以再利用,而不是做在墻上的石頭桌子
5.系統(tǒng)維護(hù)不同?
  C/S 程序由于整體性, 必須整體考察, 處理出現(xiàn)的問題以及系統(tǒng)升級. 升級難. 可能是再做一個(gè)全新的系統(tǒng)
  B/S 構(gòu)件組成,方面構(gòu)件個(gè)別的更換,實(shí)現(xiàn)系統(tǒng)的無縫升級. 系統(tǒng)維護(hù)開銷減到最小.用戶從網(wǎng)上自己下載安裝就可以實(shí)現(xiàn)升級.
6.處理問題不同
  C/S 程序可以處理用戶面固定, 并且在相同區(qū)域, 安全要求高需求, 與操作系統(tǒng)相關(guān). 應(yīng)該都是相同的系統(tǒng)
  B/S 建立在廣域網(wǎng)上, 面向不同的用戶群, 分散地域, 這是C/S無法作到的. 與操作系統(tǒng)平臺關(guān)系最小.
7.用戶接口不同
  C/S 多是建立的Window平臺上,表現(xiàn)方法有限,對程序員普遍要求較高
  B/S 建立在瀏覽器上, 有更加豐富和生動(dòng)的表現(xiàn)方式與用戶交流. 并且大部分難度減低,減低開發(fā)成本.
8.信息流不同
  C/S 程序一般是典型的中央集權(quán)的機(jī)械式處理, 交互性相對低
  B/S 信息流向可變化, B-B B-C B-G等信息、流向的變化, 更像交易中心。
118、LINUX下線程,GDI類的解釋。
LINUX實(shí)現(xiàn)的就是基于核心輕量級進(jìn)程的"一對一"線程模型,一個(gè)線程實(shí)體對應(yīng)一個(gè)核心輕量級進(jìn)程,而線程之間的管理在核外函數(shù)庫中實(shí)現(xiàn)。
GDI類為圖像設(shè)備編程接口類庫。
119、STRUTS的應(yīng)用(如STRUTS架構(gòu))
Struts 是采用Java Servlet/JavaServer Pages技術(shù),開發(fā)Web應(yīng)用程序的開放源碼的framework。采用Struts能開發(fā)出基于MVC(Model-View- Controller)設(shè)計(jì)模式的應(yīng)用構(gòu)架。 Struts有如下的主要功能:一.包含一個(gè)controller servlet,能將用戶的請求發(fā)送到相應(yīng)的Action對象。二.JSP自由tag庫,并且在controller servlet中提供關(guān)聯(lián)支持,幫助開發(fā)員創(chuàng)建交互式表單應(yīng)用。三.提供了一系列實(shí)用對象:XML處理、通過Java reflection APIs自動(dòng)處理JavaBeans屬性、國際化的提示和消息。
120、Jdo是什么?
JDO 是Java對象持久化的新的規(guī)范,為java data object的簡稱,也是一個(gè)用于存取某種數(shù)據(jù)倉庫中的對象的標(biāo)準(zhǔn)化API。JDO提供了透明的對象存儲(chǔ),因此對開發(fā)人員來說,存儲(chǔ)數(shù)據(jù)對象完全不需要額 外的代碼(如JDBC API的使用)。這些繁瑣的例行工作已經(jīng)轉(zhuǎn)移到JDO產(chǎn)品提供商身上,使開發(fā)人員解脫出來,從而集中時(shí)間和精力在業(yè)務(wù)邏輯上。另外,JDO很靈活,因?yàn)樗?可以在任何數(shù)據(jù)底層上運(yùn)行。JDBC只是面向關(guān)系數(shù)據(jù)庫(RDBMS)JDO更通用,提供到任何數(shù)據(jù)底層的存儲(chǔ)功能,比如關(guān)系數(shù)據(jù)庫、文件、XML以及對 象數(shù)據(jù)庫(ODBMS)等等,使得應(yīng)用可移植性更強(qiáng)。
121、內(nèi)部類可以引用他包含類的成員嗎?有沒有什么限制?
一個(gè)內(nèi)部類對象可以訪問創(chuàng)建它的外部類對象的內(nèi)容
122、WEB SERVICE名詞解釋。JSWDL開發(fā)包的介紹。JAXP、JAXM的解釋。SOAP、UDDI,WSDL解釋。
Web ServiceWeb Service是基于網(wǎng)絡(luò)的、分布式的模塊化組件,它執(zhí)行特定的任務(wù),遵守具體的技術(shù)規(guī)范,這些規(guī)范使得Web Service能與其他兼容的組件進(jìn)行互操作。
JAXP(Java API for XML Parsing) 定義了在Java中使用DOM, SAX, XSLT的通用的接口。這樣在你的程序中你只要使用這些通用的接口,當(dāng)你需要改變具體的實(shí)現(xiàn)時(shí)候也不需要修改代碼。
JAXM(Java API for XML Messaging) 是為SOAP通信提供訪問方法和傳輸機(jī)制的API。
WSDL是一種 XML 格式,用于將網(wǎng)絡(luò)服務(wù)描述為一組端點(diǎn),這些端點(diǎn)對包含面向文檔信息或面向過程信息的消息進(jìn)行操作。這種格式首先對操作和消息進(jìn)行抽象描述,然后將其綁定到具體的網(wǎng)絡(luò)協(xié)議和消息格式上以定義端點(diǎn)。相關(guān)的具體端點(diǎn)即組合成為抽象端點(diǎn)(服務(wù))。
SOAP即簡單對象訪問協(xié)議(Simple Object Access Protocol),它是用于交換XML編碼信息的輕量級協(xié)議。
UDDI 的目的是為電子商務(wù)建立標(biāo)準(zhǔn);UDDI是一套基于Web的、分布式的、為Web Service提供的、信息注冊中心的實(shí)現(xiàn)標(biāo)準(zhǔn)規(guī)范,同時(shí)也包含一組使企業(yè)能將自身提供的Web Service注冊,以使別的企業(yè)能夠發(fā)現(xiàn)的訪問協(xié)議的實(shí)現(xiàn)標(biāo)準(zhǔn)。

JAVA代碼查錯(cuò)
1.
abstract class Name {
?? private String name;
?? public abstract boolean isStupidName(String name) {}
}
大俠們,這有何錯(cuò)誤?
答案: 錯(cuò)。abstract method必須以分號結(jié)尾,且不帶花括號。
2.
public class Something {
?? void doSomething () {
?????? private String s = "";
?????? int l = s.length();
?? }
}
有錯(cuò)嗎?
答案: 錯(cuò)。局部變量前不能放置任何訪問修飾符 (private,public,和protected)。final可以用來修飾局部變量
(final如同abstract和strictfp,都是非訪問修飾符,strictfp只能修飾class和method而非variable)。
3.
abstract class Something {
?? private abstract String doSomething ();
}
這好像沒什么錯(cuò)吧?
答案: 錯(cuò)。abstract的methods不能以private修飾。abstract的methods就是讓子類implement(實(shí)現(xiàn))具體細(xì)節(jié)的,怎么可以用private把a(bǔ)bstract
method封鎖起來呢? (同理,abstract method前不能加final)。
4.
public class Something {
?? public int addOne(final int x) {
?????? return ++x;
?? }
}
這個(gè)比較明顯。
答案: 錯(cuò)。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;
}
和上面的很相似,都是關(guān)于final的問題,這有錯(cuò)嗎?
答案: 正確。在addOne method中,參數(shù)o被修飾成final。如果在addOne method里我們修改了o的reference
(比如: o = new Other();),那么如同上例這題也是錯(cuò)的。但這里修改的是o的member vairable
(成員變量),而o的reference并沒有改變。
6.
class Something {
??? int i;
??? public void doSomething() {
??????? System.out.println("i = " + i);
??? }
}
有什么錯(cuò)呢? 看不出來啊。
答案: 正確。輸出的是"i = 0"。int i屬於instant variable (實(shí)例變量,或叫成員變量)。instant variable有default value。int的default value是0。
7.
class Something {
??? final int i;
??? public void doSomething() {
??????? System.out.println("i = " + i);
??? }
}
和上面一題只有一個(gè)地方不同,就是多了一個(gè)final。這難道就錯(cuò)了嗎?
答 案: 錯(cuò)。final int i是個(gè)final的instant variable (實(shí)例變量,或叫成員變量)。final的instant variable沒有default value,必須在constructor (構(gòu)造器)結(jié)束之前被賦予一個(gè)明確的值。可以修改為"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 ...";
??? }
}
?看上去很完美。
答 案: 錯(cuò)。看上去在main里call doSomething沒有什么問題,畢竟兩個(gè)methods都在同一個(gè)class里。但仔細(xì)看,main是static的。static method不能直接call non-static methods。可改成"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("Do something ...");
??? }
}
?這個(gè)好像很明顯。
答案: 正確。從來沒有人說過Java的Class名字必須和其文件名相同。但public class的名字必須和文件名相同。
10.
interface? A{
?? int x = 0;
}
class B{
?? int x =1;
}
class C extends B implements A {
?? public void pX(){
????? System.out.println(x);
?? }
?? public static void main(String[] args) {
????? new C().pX();
?? }
}
答 案:錯(cuò)誤。在編譯時(shí)會(huì)發(fā)生錯(cuò)誤(錯(cuò)誤描述不同的JVM有不同的信息,意思就是未明確的x調(diào)用,兩個(gè)x都匹配(就象在同時(shí)import java.util和java.sql兩個(gè)包時(shí)直接聲明Date一樣)。對于父類的變量,可以用super.x來明確,而接口的屬性默認(rèn)隱含為 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());
??? }
}
這個(gè)錯(cuò)誤不容易發(fā)現(xiàn)。
答 案: 錯(cuò)。"interface Rollable extends Playable, Bounceable"沒有問題。interface可繼承多個(gè)interfaces,所以這里沒錯(cuò)。問題出在interface Rollable里的"Ball ball = new Ball("PingPang");"。任何在interface里聲明的interface variable (接口變量,也可稱成員變量),默認(rèn)為public static final。也就是說"Ball ball = new Ball("PingPang");"實(shí)際上是"public static final Ball ball = new Ball("PingPang");"。在Ball類的Play()方法中,"ball = new Ball("Football");"改變了ball的reference,而這里的ball來自Rollable interface,Rollable interface里的ball是public static final的,final的object是不能被改變r(jià)eference的。因此編譯器將在"ball = new Ball("Football");"這里顯示有錯(cuò)。


橘子 2006-05-19 17:38 發(fā)表評論
]]>
關(guān)于JAVA的中文問題http://www.tkk7.com/forget/archive/2006/04/09/40064.html橘子橘子Sun, 09 Apr 2006 03:13:00 GMThttp://www.tkk7.com/forget/archive/2006/04/09/40064.htmlhttp://www.tkk7.com/forget/comments/40064.htmlhttp://www.tkk7.com/forget/archive/2006/04/09/40064.html#Feedback0http://www.tkk7.com/forget/comments/commentRss/40064.htmlhttp://www.tkk7.com/forget/services/trackbacks/40064.htmlJAVA的中文問題比較突出,主要表現(xiàn)在控制面板輸出,JSP頁面輸出和數(shù)據(jù)庫訪問上。本文盡量避開字體問題,而只談編碼。通過本文,你可以了解JAVA中文問題的由來,問題的解決方法,其中提了一下用JDBC訪問數(shù)據(jù)庫的方法。

二、問題描述:
1)在中文W2000中文窗口編譯和運(yùn)行,用的是國際版的JDK,連接的是中文W2000下的Cp936編碼的SQL SERVER數(shù)據(jù)庫:

J:\exercise\demo\encode\HelloWorld>make
Created by XCompiler. PhiloSoft All Rights Reserved.
Wed May 30 02:54:45 CST 2001

J:\exercise\demo\encode\HelloWorld>run
Created by XRunner. PhiloSoft All Rights Reserved.
Wed May 30 02:51:33 CST 2001
中文
[B@7bc8b569
[B@7b08b569
[B@7860b569
中文
中文
????
中文
中文
????
??
??
??

2)如果在中文W2000的西文窗口(編碼為437)下編譯,用JAVA運(yùn)行則由于無字體而無法正常顯示,如果象上面一樣在中文W2000的中文窗口運(yùn)行,輸出為:

J:\exercise\demo\encode\HelloWorld>run
Created by XRunner. PhiloSoft All Rights Reserved.
Wed May 30 02:51:33 CST 2001
????
[B@7bc0b66a
[B@7b04b66a
[B@7818b66a
????
????
????
????
????
????
中文
中文
????

三)分析

1)出現(xiàn)有亂碼(也就是?)。由于只出現(xiàn)?而沒出現(xiàn)小方框,說明只是編碼有問題,而不是字體問題。 在編碼中,如果從一種字符集轉(zhuǎn)換到別一種字符集,比較典型的是從GB2312轉(zhuǎn)換到ISO8859_1(即ASCII),那么很多漢字(半個(gè)漢字)是無法映射到西文字符中去的,在這種情形下,系統(tǒng)就把這些字符用?代替。同樣,也存在小字符集無法到大字符集的情況,具體原因這里就不詳談了。

2)出現(xiàn)了中文環(huán)境編譯,中文環(huán)境運(yùn)行時(shí)漢字顯示有正確也有不正確的地方,同樣,在西文環(huán)境下編譯,在中文環(huán)境下運(yùn)行時(shí)也出現(xiàn)類似情況。這是由于自動(dòng)(默認(rèn))或手工(也就new String(bytes[,encode])和bytes getBytes([encode]))轉(zhuǎn)碼的結(jié)果。

2.1)在JAVA源文件-->JAVAC-->Class-->Java-->getBytes()-->new String()-->顯示的過程中,每一步都有編碼的轉(zhuǎn)換過程,這個(gè)過程總是存在的,只是有的時(shí)候用默認(rèn)的參數(shù)進(jìn)行。下面我們一步一步分析為什么出現(xiàn)上面的情形。

2.2)這里是源代碼:

HelloWorld.java:
------------------------
public class HelloWorld
{
public static void main(String[] argv){
try{
System.out.println("中文");//1
System.out.println("中文".getBytes());//2
System.out.println("中文".getBytes("GB2312"));//3
System.out.println("中文".getBytes("ISO8859_1"));//4

System.out.println(new String("中文".getBytes()));//5
System.out.println(new String("中文".getBytes(),"GB2312"));//6
System.out.println(new String("中文".getBytes(),"ISO8859_1"));//7

System.out.println(new String("中文".getBytes("GB2312")));//8
System.out.println(new String("中文".getBytes("GB2312"),"GB2312"));//9
System.out.println(new

String("中文".getBytes("GB2312"),"ISO8859_1"));//10

System.out.println(new String("中文".getBytes("ISO8859_1")));//11
System.out.println(new

String("中文".getBytes("ISO8859_1"),"GB2312"));//12
System.out.println(new

String("中文".getBytes("ISO8859_1"),"ISO8859_1"));//13
}
catch(Exception e){
e.printStackTrace();
}
}
}

為了方便起見,在每個(gè)轉(zhuǎn)換的后面加了操作序號,分別為1,2,...,13。

2.3)需要說明的是,JAVAC是以系統(tǒng)默認(rèn)編碼讀入源文件,然后按UNICODE進(jìn)行編碼的。在JAVA運(yùn)行的時(shí)候,JAVA也是采用UNICODE編碼的,并且默認(rèn)輸入和輸出的都是操作系統(tǒng)的默認(rèn)編碼,也就是說在new String(bytes[,encode])中,系統(tǒng)認(rèn)為輸入的是編碼為encode的字節(jié)流,換句話說,如果按encode來翻譯bytes才能得到正確的結(jié)果,這個(gè)結(jié)果最后要在JAVA中保存,它還是要從這個(gè)encode轉(zhuǎn)換成Unicode,也就是說有bytes-->encode字符-->Unicode字符的轉(zhuǎn)換;而在String.getBytes([encode])中,系統(tǒng)要做一個(gè)Unicode字符-->encode字符-->bytes的轉(zhuǎn)換。

在這個(gè)例子中,除那個(gè)英文窗口編碼的時(shí)候除外,其實(shí)情形下默認(rèn)編碼都是GBK(在本例中,我們暫且把GBK和GB2312等同看待)。

2.4)由于在未指明在上面的兩個(gè)用代碼實(shí)現(xiàn)的轉(zhuǎn)換中,如果未指定encode,系統(tǒng)將采用默認(rèn)的編碼(這里為GBK),我們認(rèn)為上面的5,6,7和8,9,10是一樣的,8和9、11和12也是一樣的,所以我們在討論中將只討論1,9,10,12,13。其中的2,3,4只是用于測試,不在我們的討論范圍之內(nèi)。

2.5)下面我們來跟蹤程序中的“中”字的轉(zhuǎn)換歷程,我們先說在中文窗口下作的編譯和運(yùn)行過程,注意在下面的字母下標(biāo)中,我有意識地使用了一些數(shù)字,以表示相同,相異還是相關(guān)2.5.1)我們先以上面的13個(gè)代碼段中的的代碼9為例:

步驟 內(nèi)容 地點(diǎn) 說明
01: C1 HelloWorld.java C1泛指一個(gè)GBK字符
02: U1 JAVAC讀取 U1泛指一個(gè)Unicode字符
03: C1 getBytes()第一步 JAVA先和操作系統(tǒng)交流
04: B1,B2 getBytes()第二步 然后返回字節(jié)數(shù)組
05: C1 new String()第一步 JAVA先和操作系統(tǒng)交流
06: U1 new String()第二步 然后返回字符
07: C1 println(String) 能顯示“中”字,內(nèi)容和原來的相同

2.5.2)然后再以代碼段10為例,我們注意到只是:

步驟 內(nèi)容 地點(diǎn) 說明
01: C1 HelloWorld.java C1泛指一個(gè)GBK字符
02: U1 JAVAC讀取 U1泛指一個(gè)Unicode字符
03: C1 getBytes()第一步 JAVA先和操作系統(tǒng)交流
04: B1,B2 getBytes()第二步 然后返回字節(jié)數(shù)組
05: C3,C4 new String()第一步 JAVA先和操作系統(tǒng)交流,這時(shí)解析錯(cuò)誤
06: U5,U6 new String()第二步 然后返回字符
07: C3,C4 println(String) 由于中字給分成了兩半,在ISO8859_1中剛好也沒有字符

能映射上,所以顯示為“??”。在上面的示例中,
“中文”兩個(gè)字就顯示為“????”
2.5.3)在完全中文模式下的其它情形類似,我就不多說了

2.6)我們接著看為什么在西文DOS窗口下編譯出來的類在中文窗口下也出現(xiàn)類似情形,特別是為什么居然有的情形下還能正確顯示漢字。

2.6.1)我們還是先以代碼段9為例:

步驟 內(nèi)容 地點(diǎn) 說明
01: C1C2 HelloWorld.java C1C2分別泛指一個(gè)ISO8859_1字符,“中”字被拆開
02: U3U4 JAVAC讀取 U1U2泛指一個(gè)Unicode字符
03: C5C6 getBytes()第一步 JAVA先和操作系統(tǒng)交流,這時(shí)解析錯(cuò)誤
04: B5B6B7B8 getBytes()第二步 然后返回字節(jié)數(shù)組
05: C5C6 new String()第一步 JAVA先和操作系統(tǒng)交流
06: U3U4 new String()第二步 然后返回字符
07: C5C6 println(String) 雖然同是兩個(gè)字符,但已不是最初的“兩個(gè)ISO8859_1字

符”,而是“兩個(gè)BGK字符”,“中”顯示成了“??”
而“中文”就顯示成了“????”

2.6.2)下面我們以代碼段12為例,因?yàn)樗苷_顯示漢字

步驟 內(nèi)容 地點(diǎn) 說明

01: C1C2 HelloWorld.java C1C2分別泛指一個(gè)ISO8859_1字符,“中”字被拆開
02: U3U4 JAVAC讀取 U1U2泛指一個(gè)Unicode字符
03: C1C2 getBytes()第一步 JAVA先和操作系統(tǒng)交流(注意還是正確的哦!)
04: B5B6 getBytes()第二步 然后返回字節(jié)數(shù)組(這是很關(guān)鍵的一步!)
05: C12 new String()第一步 JAVA先和操作系統(tǒng)交流(這是更關(guān)鍵的一步,JAVA已經(jīng)知道B5B6要解析成一個(gè)漢字!)
06: U7 new String()第二步 然后返回字符(真是一個(gè)項(xiàng)兩!U7包含了U3U4的信息)
07: C12 println(String) 這就原來的“中”字,很委屈被JAVAC冤枉了一回,不過被程序員撥亂反正了一下!當(dāng)然,“中文”兩個(gè)字都能正確顯示了!

3)那為什么有的時(shí)候用JDBC的
new String(Recordset.getBytes(int)[,encode])
Recordset.getSting(int)
Recordset.setBytes(String.getBytes([encode]))

Recordset.setString(String)
的時(shí)候會(huì)出現(xiàn)亂碼了呢?

其實(shí)問題就出現(xiàn)在編寫JDBC的的也考慮了編碼問題,它從數(shù)據(jù)庫讀取數(shù)據(jù)后,可能自作主張做了一個(gè)從GB2312(默認(rèn)編碼)到Unicode的轉(zhuǎn)換,我的這個(gè)WebLogic For SQL Server的JDBC Driver就是這樣的,當(dāng)我讀字串的時(shí)候,發(fā)出讀到的不是正確的漢字,可恨的是我卻可以直接寫漢字字串,這讓人多少有點(diǎn)難以接受!
也就是說,我們不得不在讀或?qū)懙臅r(shí)候進(jìn)行轉(zhuǎn)碼,盡管這個(gè)轉(zhuǎn)碼有的時(shí)候不是那么明顯,這是因?yàn)槲覀兪褂昧四J(rèn)的編碼進(jìn)行轉(zhuǎn)碼。JDBC Driver所做的操作,我們只有進(jìn)入到源代碼內(nèi)部才能清楚,不是嗎?

橘子 2006-04-09 11:13 發(fā)表評論
]]>
主站蜘蛛池模板: 久久久久免费看黄A片APP| 91精品免费久久久久久久久| 亚洲国产精品无码观看久久| 亚洲天堂一区二区三区四区| 久久精品国产亚洲网站| 伊人亚洲综合青草青草久热| 全黄性性激高免费视频| 日本成人免费在线| 在线精品免费视频无码的| 巨胸喷奶水视频www网免费| 18国产精品白浆在线观看免费 | 久久免费线看线看| 91精品国产免费久久国语麻豆| 国产免费黄色无码视频| **一级毛片免费完整视| 亚洲毛片网址在线观看中文字幕| 国产无遮挡色视频免费视频| 四虎免费久久影院| 亚洲avav天堂av在线不卡 | 亚洲激情中文字幕| 国产成人精品亚洲2020| 国产成人自产拍免费视频| 亚洲国产精品免费视频| 亚洲伦乱亚洲h视频| 亚洲国产日韩精品| 最近2018中文字幕免费视频| 精品久久免费视频| 亚洲短视频男人的影院| 亚洲av无码成人精品国产 | 国产亚洲精aa成人网站| 亚洲一本综合久久| 国产亚洲精品美女久久久久久下载| 深夜A级毛片视频免费| 久久aⅴ免费观看| 四虎www成人影院免费观看| 亚洲午夜无码久久久久| 亚洲视频无码高清在线| 99久久精品毛片免费播放| 国产一卡2卡3卡4卡2021免费观看 国产一卡2卡3卡4卡无卡免费视频 | 亚洲线精品一区二区三区影音先锋| 国产AV无码专区亚洲AV蜜芽|