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



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

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

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

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

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

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

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

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

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

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

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

Eclipse 擁有與 Eclipse 平臺 IDE 緊密集成的內(nèi)置 CVS 客戶機,它是作為一個單獨透視圖(CVS Repository Exploring 透視圖)而實現(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 團隊協(xié)作模型中,團隊成員彼此獨立地在他們各自的工作臺上完成自己的所有工作。最后,他們希望共享其工作。他們通過 CVS 資源庫實現(xiàn)這一點。CVS 使用分支(branch)模型來支持彼此獨立而又高度相互依賴的多個工作流程(course of work)。這些分支是開發(fā)團隊用來共享和集成正在進行中的工作的地方。可以認為分支是一個共享的工作臺,當團隊成員對源代碼進行更改時就更新這個工作臺。這個模型允許從事 CVS 團隊項目的每個開發(fā)人員在進行更改時與其他成員共享其工作,以及在項目進展期間訪問其他成員的工作。

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

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

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

圖 3. 使用 CVS 資源庫共享本地項目
共享項目

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

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

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

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

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

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

圖 6. 將更改提交到遠程資源庫
提交更改

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

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

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

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

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

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

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

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

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

參考資料

 

關(guān)于作者
Pawel Leszek 是 Studio B 的一位作家,他是一位專長于 Linux/Win/Mac OS 系統(tǒng)體系結(jié)構(gòu)和管理的獨立軟件顧問和作家。他具有許多操作系統(tǒng)、編程語言和網(wǎng)絡(luò)協(xié)議方面的經(jīng)驗,尤其是 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.aygfsteel.com/forget/archive/2006/06/26/55068.html橘子橘子Mon, 26 Jun 2006 01:42:00 GMThttp://www.aygfsteel.com/forget/archive/2006/06/26/55068.htmlhttp://www.aygfsteel.com/forget/comments/55068.htmlhttp://www.aygfsteel.com/forget/archive/2006/06/26/55068.html#Feedback0http://www.aygfsteel.com/forget/comments/commentRss/55068.htmlhttp://www.aygfsteel.com/forget/services/trackbacks/55068.htmlhttp://www.volitation.net/Article/print.asp?SelectID=7。
何謂“持久化”
持久(Persistence),即把數(shù)據(jù)(如內(nèi)存中的對象)保存到可永久保存的存儲設(shè)備中(如磁盤)。持久化的主要應(yīng)用是將內(nèi)存中的數(shù)據(jù)存儲在關(guān)系型的數(shù)據(jù)庫中,當然也可以存儲在磁盤文件中、XML數(shù)據(jù)文件中等等。

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

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

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


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

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

JDO 模式
Java Data Objects(JDO)是 SUN 公司制定的描述對象持久化語義的標準API。嚴格的說,JDO 并不是對象-關(guān)系映射接口,因為它支持把對象持久化到任意一種存儲系統(tǒng)中,包括 關(guān)系數(shù)據(jù)庫、面向?qū)ο蟮臄?shù)據(jù)庫、基于 XML 的數(shù)據(jù)庫,以及其他專有存儲系統(tǒng)。由于關(guān)系數(shù)據(jù)庫是目前最流行的存儲系統(tǒng),許多 JDO 的實現(xiàn)都包含了對象-關(guān)系映射服務(wù)。

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

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


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

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

簡單來說,按通常的系統(tǒng)設(shè)計,使用 JDBC 操作數(shù)據(jù)庫,業(yè)務(wù)處理邏輯和數(shù)據(jù)存取邏輯是混雜在一起的。
一般基本都是如下幾個步驟:
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ù)邏輯進行計算。
7、根據(jù)計算得到的結(jié)果再組裝更新 SQL 語句。
8、再使用 Connection 對象執(zhí)行更新 SQL 語句,以更新數(shù)據(jù)庫中的數(shù)據(jù)。
7、最后依次關(guān)閉各個 Statement 對象和 Connection 對象。

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

舉例來說,比如要完成一個購物打折促銷的程序,用 ORM 思想將如下實現(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());
??? // 累積客戶總消費額,并保存累計結(jié)果
??? customer.setSumAmount(customer.getSumAmount().add(amount);
??? CustomerManager.save(customer);
??? // 返回打折后的金額
??? return amount.multiply(protomtion.getRatio());
}
這樣代碼就非常清晰了,而且與數(shù)據(jù)存取邏輯完全分離。設(shè)計業(yè)務(wù)邏輯代碼的時候完全不需要考慮數(shù)據(jù)庫JDBC的那些千篇一律的操作,而將它交給 CustomerManager 和 PromotionManager 兩個類去完成。這就是一個簡單的 ORM 設(shè)計,實際的 ORM 實現(xiàn)框架比這個要復(fù)雜的多。


目前有哪些流行的 ORM 產(chǎn)品
目前眾多廠商和開源社區(qū)都提供了持久層框架的實現(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)品,其他均為開源項目。

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


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



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

內(nèi)容摘要:

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

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

/ | \

(版 本 同 步)

/ | \

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




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

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

一個系統(tǒng)20%的功能往往能夠滿足80%的需求,CVS也不例外,以下是CVS最常用的功能,可能還不
到它全部命令選項的20%,作為一般開發(fā)人員平時會用cvs update和cvs commit就夠了,更多的需求在
實際應(yīng)用過程中自然會出現(xiàn),不時回頭看看相關(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

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

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

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

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


CVS的日常使用

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

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

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

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


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

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

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

然后確認修改并注釋
cvs ci -m "write some comments here"

刪除文件
將某個源文件物理刪除后,比如:rm file_name
cvs rm file_name
然后確認修改并注釋
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

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

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

移動文件/文件重命名
cvs里沒有cvs move或cvs rename,因為這兩個操作是可以由先cvs remove old_file_name,然后cvs add new_file_name實現(xiàn)的。

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

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

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

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

cvs tag release_1_0

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

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

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

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

在release_1_0_patch上修正錯誤后,標記一個1.0的錯誤修正版本號
cvs tag release_1_0_patch_1

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

CVS的遠程認證通過SSH遠程訪問CVS

使用cvs本身基于pserver的遠程認證很麻煩,需要定義服務(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)本地帳號認證并通過
SSH傳輸是比較好的辦法,通過在客戶機的 /etc/profile里設(shè)置一下內(nèi)容:
CVSROOT=:ext:$USER@cvs.server.address#port:/path/to/cvsroot CVS_RSH=ssh; export CVSROOT CVS_RSH
所有客戶機所有本地用戶都可以映射到CVS服務(wù)器相應(yīng)同名帳號了。

比如:

CVS服務(wù)器是192.168.0.3,上面CVSROOT路徑是/home/cvsroot,另外一臺開發(fā)客戶機是192.168.0.4,
如果 tom在2臺機器上都有同名的帳號,那么從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進行訪問了(如果有權(quán)限的話)
cvs checkout project_name
cd project_name
cvs update
...
cvs commit

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

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

解決的方法是做一個腳本指定端口轉(zhuǎn)向(不能使用alias,會出找不到文件錯誤):
創(chuàng)建一個/usr/bin/ssh_cvs文件,假設(shè)遠程服務(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)演化出很多功能界面更豐富的版本,這個是我個人感
覺安裝設(shè)置比較方便的:
原先在:http://www.spaghetti-code.de/software/linux/cvsweb/,但目前已經(jīng)刪除,目前仍可以在本站下載CVSWEB,其實最近2年FreeBSD的CVSWeb項目已經(jīng)有了更好的發(fā)展吧,而當初沒有用FreeBSD那個
版本主要就是因為沒有彩色的文件Diff功能。
下載解包:
tar zxf cvsweb.tgz
把配置文件cvsweb.conf放到安全的地方(比如和apache的配置放在同一個目錄下),
修改: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用戶認證:
先生成 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 $ 加在程序文件開頭的注釋里是一個很好
的習慣,cvs能夠自動解釋更新其中的內(nèi)容成:file_name version time user_name 的格式,比如:
cvs_card.txt,v 1.1 2002/04/05 04:24:12 chedong Exp,可以這些信息了解文件的最后修改人和修改時間


幾個常用的缺省文件:
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同時,同時記錄了文件被導(dǎo)出者鎖定。

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

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

在CVS中,標記自動更新功能缺省是打開的,這樣也帶來一個潛在的問題,就是不用-kb方式添加
binary文件的話在cvs自動更新時可能會導(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 $這樣的標記在Virsual SourceSafe中稱之為Keyword Explaination,缺省是關(guān)閉
的,需要通過OPITION打開,并指定需要進行源文件關(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個軟件以后:
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進行cvs操作了,所有操作都會跳出命令行窗口要求你輸入服務(wù)器端的認
證密碼。

當然,如果你覺得這樣很煩的話,還有一個辦法就是生成一個沒有密碼的公鑰/私鑰對,并設(shè)置
CVS使用基于公鑰/私鑰的SSH認證(在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
在對文件進行版本diff時,第一次需要將窗口右下角的use externel diff選上。

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

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

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

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

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

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

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

CVSTrac很好的解決了CVSROOT/passwd的管理問題,而且包含了BUG跟蹤報告系統(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的所有用戶一致,并且必須讓這個這個用戶對/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庫這時候應(yīng)該已經(jīng)是初始化好了,比如:cvs init初始化在/home/cvsroot里),運行一下
    %cvstrac init /home/cvsroot myproj
    運行后,/home/cvsroot里會有一個的myproj.db庫,使用CVSTRAC服務(wù),/home/cvsroot/myproj.db /home/cvsroot/CVSROOT/readers
    /home/cvsroot/CVSROOT/writers /home/cvsroot/CVSROOT/passwd這幾個文件對于web服務(wù)的運行
    用戶應(yīng)該是可寫的,在RedHat8上,缺省就有一個叫 apache用戶和一個apache組,所以在
    httpd.conf文件中設(shè)置了用apache用戶運行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 進入管理界面
    缺省登錄名: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)建新用戶后會同步更新CVSROOT/passwd下的帳號

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

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

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

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

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

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

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

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

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

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

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

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

1.進入命令行方式。

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

輸入"cvs"。你會看到:


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

2.login


正確的login不會有任何輸出,否則會告訴你錯誤原因。


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

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


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


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


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

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

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

				

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



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





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




一個notepad窗口彈出請您輸入注釋。



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

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


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

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

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

7.最后,為了完成這個試驗,請把這個newfile文件刪去。

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



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

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

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

5、打開一個cmd窗口,輸入命令set cvsroot=:pserver:sunxdd@server/Root(sunxdd是剛才建立的用戶名,server是安裝的計算機名稱或者IP,/Root是剛才建立的文件夾別名,每次登陸之前都要這樣告訴系統(tǒng)建立這樣一個環(huán)境變量)
cvs login
密碼為空
這時會登錄成功
改密碼
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.aygfsteel.com/forget/archive/2006/06/17/53462.html橘子橘子Sat, 17 Jun 2006 03:43:00 GMThttp://www.aygfsteel.com/forget/archive/2006/06/17/53462.htmlhttp://www.aygfsteel.com/forget/comments/53462.htmlhttp://www.aygfsteel.com/forget/archive/2006/06/17/53462.html#Feedback1http://www.aygfsteel.com/forget/comments/commentRss/53462.htmlhttp://www.aygfsteel.com/forget/services/trackbacks/53462.html在php中輸出返回上一級的代碼:
echo "<a href=".$_SERVER["HTTP_REFERER"].">點擊這里返回</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="輸入標題">
<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="標題">
<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ā)表評論
]]>
點中復(fù)選框使得復(fù)選框后的文本框內(nèi)容顯示出指定的內(nèi)容http://www.aygfsteel.com/forget/archive/2006/06/09/51764.html橘子橘子Fri, 09 Jun 2006 15:08:00 GMThttp://www.aygfsteel.com/forget/archive/2006/06/09/51764.htmlhttp://www.aygfsteel.com/forget/comments/51764.htmlhttp://www.aygfsteel.com/forget/archive/2006/06/09/51764.html#Feedback0http://www.aygfsteel.com/forget/comments/commentRss/51764.htmlhttp://www.aygfsteel.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">

這樣一來 如果想輸入某個確定的值時就不用那么辛辛苦苦的復(fù)制了,點擊就自動選擇!

橘子 2006-06-09 23:08 發(fā)表評論
]]>
php上傳多個文件http://www.aygfsteel.com/forget/archive/2006/06/08/51520.html橘子橘子Thu, 08 Jun 2006 14:31:00 GMThttp://www.aygfsteel.com/forget/archive/2006/06/08/51520.htmlhttp://www.aygfsteel.com/forget/comments/51520.htmlhttp://www.aygfsteel.com/forget/archive/2006/06/08/51520.html#Feedback1http://www.aygfsteel.com/forget/comments/commentRss/51520.htmlhttp://www.aygfsteel.com/forget/services/trackbacks/51520.html前面提到了上傳單個文件的方法,上傳多個文件的思想類似
1、在表單頁面動態(tài)生成多個文件提交框,這里注意一下,多個文件提交框的名字要設(shè)置為數(shù)組,否則只有一個文件會上傳。
此時在$_FILES數(shù)組構(gòu)造方式是這樣:$_FILES["files"][xxxxfileProperty][xxxcount]; 比如說我要知道第一個文件的error值:$_FILES["userfiles"]["error"][0] ,第一個文件客戶端名字:$_FILES["userfiles"]["name"][0]等等。
2、接收端接收,操作和單個的是一樣,只是需要做個循環(huán),有多少個文件做多少次循環(huán),以便所有的文件都能正確發(fā)送。
示例代碼:
表單頁面
<form enctype="multipart/form-data" action="post.php" method="post">
&nbsp;&nbsp;文章標題:&nbsp;&nbsp;<input name="title" type="text"/>&nbsp;標題不能為空!
<br />&nbsp;&nbsp;淘吧名字:&nbsp;&nbsp;<input name="bar_name" type="text"/>
<?php
echo "請選擇一個!\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 "標題或內(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()從標記開始前字節(jié)個數(shù)(不算標記),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ù)生成臨時文件名,并按照 $_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 "上傳錯誤!? 以下是上傳的信息:\n";
????print_r($_FILES);
???}
??}
??else{
???echo "{$FILES_NAME}\n不是允許上傳的文件類型!";
???exit;
??}
?}
}

?>
</body>
</html>



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

? 1. 值:0; 沒有錯誤發(fā)生,文件上傳成功。
? 2. 值:1; 上傳的文件超過了 php.ini 中 upload_max_filesize 選項限制的值。
? 3. 值:2; 上傳文件的大小超過了 HTML 表單中 MAX_FILE_SIZE 選項指定的值。
? 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/";// 上傳文件的儲存位置
?$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>";
//客戶端機器文件的原名稱。
Echo?? "文件的 MIME 類型為:";
echo $_FILES['userfile']['type'];
//文件的 MIME 類型,需要瀏覽器提供該信息的支持,例如“image/gif”。
echo "<br>";

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

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

$Erroe=$_FILES['userfile']['error'];
switch($Erroe){
?case 0:
?Echo?? "上傳成功"; break;
?case 1:
?Echo?? "上傳的文件超過了 php.ini 中 upload_max_filesize 選項限制的值."; break;
?case 2:
?Echo?? "上傳文件的大小超過了 HTML 表單中 MAX_FILE_SIZE 選項指定的值。";?? 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()從標記開始前字節(jié)個數(shù)(不算標記),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ù)生成臨時文件名,并按照 $_FILES['userfile']['name']上傳到$uploaddir下
?if (move_uploaded_file($_FILES['userfile']['tmp_name'], $uploadfile)) {
??print "\n上傳成功!";
?} else {
??print "上傳錯誤!? 以下是上傳的信息:\n";
??print_r($_FILES);
?}
}
else{
?echo "{$file_ext}不是允許上傳的文件類型!";
?exit;
}
?>



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



橘子 2006-06-08 22:09 發(fā)表評論
]]>
JAVA相關(guān)基礎(chǔ)知識http://www.aygfsteel.com/forget/archive/2006/05/19/47089.html橘子橘子Fri, 19 May 2006 09:38:00 GMThttp://www.aygfsteel.com/forget/archive/2006/05/19/47089.htmlhttp://www.aygfsteel.com/forget/comments/47089.htmlhttp://www.aygfsteel.com/forget/archive/2006/05/19/47089.html#Feedback0http://www.aygfsteel.com/forget/comments/commentRss/47089.htmlhttp://www.aygfsteel.com/forget/services/trackbacks/47089.html
JAVA相關(guān)基礎(chǔ)知識
1、面向?qū)ο蟮奶卣饔心男┓矫??
1.抽象:
抽象就是忽略一個主題中與當前目標無關(guān)的那些方面,以便更充分地注意與當前目標有關(guān)的方面。抽象并不打算了解全部問題,而只是選擇其中的一部分,暫時不用部分細節(jié)。抽象包括兩個方面,一是過程抽象,二是數(shù)據(jù)抽象。
2.繼承:
繼 承是一種聯(lián)結(jié)類的層次模型,并且允許和鼓勵類的重用,它提供了一種明確表述共性的方法。對象的一個新類可以從現(xiàn)有的類中派生,這個過程稱為類繼承。新類繼 承了原始類的特性,新類稱為原始類的派生類(子類),而原始類稱為新類的基類(父類)。派生類可以從它的基類那里繼承方法和實例變量,并且類可以修改或增 加新的方法使之更適合特殊的需要。
3.封裝:
封裝是把過程和數(shù)據(jù)包圍起來,對數(shù)據(jù)的訪問只能通過已定義的界面。面向?qū)ο笥嬎闶加谶@個基本概念,即現(xiàn)實世界可以被描繪成一系列完全自治、封裝的對象,這些對象通過一個受保護的接口訪問其他對象。
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類型的,因此不可以繼承這個類、不能修改這個類。為了提高效率節(jié)省空間,我們應(yīng)該用StringBuffer類
3、int 和 Integer 有什么區(qū)別
Java 提供兩種不同的類型:引用類型和原始類型(或內(nèi)置類型)。Int是java的原始數(shù)據(jù)類型,Integer是java為int提供的封裝類。Java為每個原始類型提供了封裝類。
原始類型封裝類
booleanBoolean
charCharacter
byteByte
shortShort
intInteger
longLong
floatFloat
doubleDouble
引 用類型和原始類型的行為完全不同,并且它們具有不同的語義。引用類型和原始類型具有不同的特征和用法,它們包括:大小和速度問題,這種類型以哪種類型的數(shù) 據(jù)結(jié)構(gòu)存儲,當引用類型和原始類型用作某個類的實例數(shù)據(jù)時所指定的缺省值。對象引用實例變量的缺省值為 null,而原始類型實例變量的缺省值與它們的類型有關(guān)。
4、String 和StringBuffer的區(qū)別
JAVA平臺提供了兩個 類:String和StringBuffer,它們可以儲存和操作字符串,即包含多個字符的字符數(shù)據(jù)。這個String類提供了數(shù)值不可改變的字符串。而 這個StringBuffer類提供的字符串進行修改。當你知道字符數(shù)據(jù)要改變的時候你就可以使用StringBuffer。典型地,你可以使用 StringBuffers來動態(tài)構(gòu)造字符數(shù)據(jù)。
5、運行時異常與一般異常有何異同?
異常表示程序運行過程中可能出現(xiàn)的非正常狀態(tài),運行時異常表示虛擬機的通常操作中可能遇到的異常,是一種常見運行錯誤。java編譯器要求方法必須聲明拋出可能發(fā)生的非運行時異常,但是并不要求必須聲明拋出未被捕獲的運行時異常。
6、說出Servlet的生命周期,并說出Servlet和CGI的區(qū)別。
Servlet被服務(wù)器實例化后,容器運行其init方法,請求到達時運行其service方法,service方法自動派遣運行與請求對應(yīng)的doXXX方法(doGet,doPost)等,當服務(wù)器決定將實例銷毀的時候調(diào)用其destroy方法。
與cgi的區(qū)別在于servlet處于服務(wù)器進程中,它通過多線程方式運行其service方法,一個實例可以服務(wù)于多個請求,并且其實例一般不會銷毀,而CGI對每個請求都產(chǎn)生新的進程,服務(wù)完成后就銷毀,所以效率上低于servlet。
7、說出ArrayList,Vector, LinkedList的存儲性能和特性
ArrayList 和Vector都是使用數(shù)組方式存儲數(shù)據(jù),此數(shù)組元素數(shù)大于實際存儲的數(shù)據(jù)以便增加和插入元素,它們都允許直接按序號索引元素,但是插入元素要涉及數(shù)組元 素移動等內(nèi)存操作,所以索引數(shù)據(jù)快而插入數(shù)據(jù)慢,Vector由于使用了synchronized方法(線程安全),通常性能上較ArrayList差, 而LinkedList使用雙向鏈表實現(xiàn)存儲,按序號索引數(shù)據(jù)需要進行前向或后向遍歷,但是插入數(shù)據(jù)時只需要記錄本項的前后項即可,所以插入速度較快。
8、EJB是基于哪些技術(shù)實現(xiàn)的?并說出SessionBean和EntityBean的區(qū)別,StatefulBean和StatelessBean的區(qū)別。
??? EJB包括Session Bean、Entity Bean、Message Driven Bean,基于JNDI、RMI、JAT等技術(shù)實現(xiàn)。
SessionBean在J2EE應(yīng)用程序中被用來完成一些服務(wù)器端的業(yè)務(wù)操作,例如訪問數(shù)據(jù)庫、調(diào)用其他EJB組件。EntityBean被用來代表應(yīng)用系統(tǒng)中用到的數(shù)據(jù)。
對于客戶機,SessionBean是一種非持久性對象,它實現(xiàn)某些在服務(wù)器上運行的業(yè)務(wù)邏輯。
對于客戶機,EntityBean是一種持久性對象,它代表一個存儲在持久性存儲器中的實體的對象視圖,或是一個由現(xiàn)有企業(yè)應(yīng)用程序?qū)崿F(xiàn)的實體。
Session Bean 還可以再細分為 Stateful Session Bean 與 Stateless Session Bean ,這兩種的 Session Bean都可以將系統(tǒng)邏輯放在 method之中執(zhí)行,不同的是 Stateful Session Bean 可以記錄呼叫者的狀態(tài),因此通常來說,一個使用者會有一個相對應(yīng)的 Stateful Session Bean 的實體。Stateless Session Bean 雖然也是邏輯組件,但是他卻不負責記錄使用者狀態(tài),也就是說當使用者呼叫 Stateless Session Bean 的時候,EJB Container 并不會找尋特定的 Stateless Session Bean 的實體來執(zhí)行這個 method。換言之,很可能數(shù)個使用者在執(zhí)行某個 Stateless Session Bean 的 methods 時,會是同一個 Bean 的 Instance 在執(zhí)行。從內(nèi)存方面來看, Stateful Session Bean 與 Stateless Session Bean 比較, Stateful Session Bean 會消耗 J2EE Server 較多的內(nèi)存,然而 Stateful Session Bean 的優(yōu)勢卻在于他可以維持使用者的狀態(tài)。
9、Collection 和 Collections的區(qū)別。
  Collection是集合類的上級接口,繼承與他的接口主要有Set 和List.
Collections是針對集合類的一個幫助類,他提供一系列靜態(tài)方法實現(xiàn)對各種集合的搜索、排序、線程安全化等操作。
10、&和&&的區(qū)別。
??? &是位運算符,表示按位與運算,&&是邏輯運算符,表示邏輯與(and)。
11、HashMap和Hashtable的區(qū)別。
??? HashMap是Hashtable的輕量級實現(xiàn)(非線程安全的實現(xiàn)),他們都完成了Map接口,主要區(qū)別在于HashMap允許空(null)鍵值(key),由于非線程安全,效率上可能高于Hashtable。
HashMap允許將null作為一個entry的key或者value,而Hashtable不允許。
HashMap把Hashtable的contains方法去掉了,改成containsvalue和containsKey。因為contains方法容易讓人引起誤解。
Hashtable繼承自Dictionary類,而HashMap是Java1.2引進的Map interface的一個實現(xiàn)。
最大的不同是,Hashtable的方法是Synchronize的,而HashMap不是,在多個線程訪問Hashtable時,不需要自己為它的方法實現(xiàn)同步,而HashMap 就必須為之提供外同步。
Hashtable和HashMap采用的hash/rehash算法都大概一樣,所以性能不會有很大的差異。
12、final, finally, finalize的區(qū)別。
  final 用于聲明屬性,方法和類,分別表示屬性不可變,方法不可覆蓋,類不可繼承。
finally是異常處理語句結(jié)構(gòu)的一部分,表示總是執(zhí)行。
finalize是Object類的一個方法,在垃圾收集器執(zhí)行的時候會調(diào)用被回收對象的此方法,可以覆蓋此方法提供垃圾收集時的其他資源回收,例如關(guān)閉文件等。
13、sleep() 和 wait() 有什么區(qū)別?
??? sleep是線程類(Thread)的方法,導(dǎo)致此線程暫停執(zhí)行指定時間,給執(zhí)行機會給其他線程,但是監(jiān)控狀態(tài)依然保持,到時后會自動恢復(fù)。調(diào)用sleep不會釋放對象鎖。
wait是Object類的方法,對此對象調(diào)用wait方法導(dǎo)致本線程放棄對象鎖,進入等待此對象的等待鎖定池,只有針對此對象發(fā)出notify方法(或notifyAll)后本線程才進入對象鎖定池準備獲得對象鎖進入運行狀態(tài)。
14、Overload和Override的區(qū)別。Overloaded的方法是否可以改變返回值的類型?
方 法的重寫Overriding和重載Overloading是Java多態(tài)性的不同表現(xiàn)。重寫Overriding是父類與子類之間多態(tài)性的一種表現(xiàn),重 載Overloading是一個類中多態(tài)性的一種表現(xiàn)。如果在子類中定義某方法與其父類有相同的名稱和參數(shù),我們說該方法被重寫 (Overriding)。子類的對象使用這個方法時,將調(diào)用子類中的定義,對它而言,父類中的定義如同被"屏蔽"了。如果在一個類中定義了多個同名的方 法,它們或有不同的參數(shù)個數(shù)或有不同的參數(shù)類型,則稱為方法的重載(Overloading)。Overloaded的方法是可以改變返回值的類型。
15、error和exception有什么區(qū)別?
error 表示恢復(fù)不是不可能但很困難的情況下的一種嚴重問題。比如說內(nèi)存溢出。不可能指望程序能處理這樣的情況。
??? exception 表示一種設(shè)計或?qū)崿F(xiàn)問題。也就是說,它表示如果程序運行正常,從不會發(fā)生的情況。
16、同步和異步有何異同,在什么情況下分別使用他們?舉例說明。
如果數(shù)據(jù)將在線程間共享。例如正在寫的數(shù)據(jù)以后可能被另一個線程讀到,或者正在讀的數(shù)據(jù)可能已經(jīng)被另一個線程寫過了,那么這些數(shù)據(jù)就是共享數(shù)據(jù),必須進行同步存取。
當應(yīng)用程序在對象上調(diào)用了一個需要花費很長時間來執(zhí)行的方法,并且不希望讓程序等待方法的返回時,就應(yīng)該使用異步編程,在很多情況下采用異步途徑往往更有效率。
17、abstract class和interface有什么區(qū)別?
聲 明方法的存在而不去實現(xiàn)它的類被叫做抽象類(abstract class),它用于要創(chuàng)建一個體現(xiàn)某些基本行為的類,并為該類聲明方法,但不能在該類中實現(xiàn)該類的情況。不能創(chuàng)建abstract 類的實例。然而可以創(chuàng)建一個變量,其類型是一個抽象類,并讓它指向具體子類的一個實例。不能有抽象構(gòu)造函數(shù)或抽象靜態(tài)方法。Abstract 類的子類為它們父類中的所有抽象方法提供實現(xiàn),否則它們也是抽象類為。取而代之,在子類中實現(xiàn)該方法。知道其行為的其它類可以在類中實現(xiàn)這些方法。
接 口(interface)是抽象類的變體。在接口中,所有方法都是抽象的。多繼承性可通過實現(xiàn)這樣的接口而獲得。接口中的所有方法都是抽象的,沒有一個有 程序體。接口只可以定義static final成員變量。接口的實現(xiàn)與子類相似,除了該實現(xiàn)類不能從接口定義中繼承行為。當類實現(xiàn)特殊接口時,它定義(即將程序體給予)所有這種接口的方法。 然后,它可以在實現(xiàn)了該接口的類的任何對象上調(diào)用接口的方法。由于有抽象類,它允許使用接口名作為引用變量的類型。通常的動態(tài)聯(lián)編將生效。引用可以轉(zhuǎn)換到 接口類型或從接口類型轉(zhuǎn)換,instanceof 運算符可以用來決定某對象的類是否實現(xiàn)了接口。
18、heap和stack有什么區(qū)別。
棧是一種線形集合,其添加和刪除元素的操作應(yīng)在同一段完成。棧按照后進先出的方式進行處理。
堆是棧的一個組成元素
19、forward 和redirect的區(qū)別
forward是服務(wù)器請求資源,服務(wù)器直接訪問目標地址的URL,把那個URL的響應(yīng)內(nèi)容讀取過來,然后把這些內(nèi)容再發(fā)給瀏覽器,瀏覽器根本不知道服務(wù)器發(fā)送的內(nèi)容是從哪兒來的,所以它的地址欄中還是原來的地址。
??? redirect就是服務(wù)端根據(jù)邏輯,發(fā)送一個狀態(tài)碼,告訴瀏覽器重新去請求那個地址,一般來說瀏覽器會用剛才請求的所有參數(shù)重新請求,所以session,request參數(shù)都可以獲取。
20、EJB與JAVA BEAN的區(qū)別?
Java Bean 是可復(fù)用的組件,對Java Bean并沒有嚴格的規(guī)范,理論上講,任何一個Java類都可以是一個Bean。但通常情況下,由于Java Bean是被容器所創(chuàng)建(如Tomcat)的,所以Java Bean應(yīng)具有一個無參的構(gòu)造器,另外,通常Java Bean還要實現(xiàn)Serializable接口用于實現(xiàn)Bean的持久性。Java Bean實際上相當于微軟COM模型中的本地進程內(nèi)COM組件,它是不能被跨進程訪問的。Enterprise Java Bean 相當于DCOM,即分布式組件。它是基于Java的遠程方法調(diào)用(RMI)技術(shù)的,所以EJB可以被遠程訪問(跨進程、跨計算機)。但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)部類,它可以不依賴于外部類實例被實例化。而通常的內(nèi)部類需要在外部類實例化后才能實例化。
22、JSP中動態(tài)INCLUDE與靜態(tài)INCLUDE的區(qū)別?
動態(tài)INCLUDE用jsp:include動作實現(xiàn) <jsp:include page="included.jsp" flush="true" />它總是會檢查所含文件中的變化,適合用于包含動態(tài)頁面,并且可以帶參數(shù)。
靜態(tài)INCLUDE用include偽碼實現(xiàn),定不會檢查所含文件的變化,適用于包含靜態(tài)頁面<%@ include file="included.htm" %>
23、什么時候用assert。
??? assertion(斷言)在軟件開發(fā)中是一種常用的調(diào)試方式,很多開發(fā)語言中都支持這種機制。在實現(xiàn)中,assertion就是在程序中的一條語句,它 對一個boolean表達式進行檢查,一個正確程序必須保證這個boolean表達式的值為true;如果該值為false,說明程序已經(jīng)處于不正確的狀 態(tài)下,系統(tǒng)將給出警告或退出。一般來說,assertion用于保證程序最基本、關(guān)鍵的正確性。assertion檢查通常在開發(fā)和測試時開啟。為了提高 性能,在軟件發(fā)布后,assertion檢查通常是關(guān)閉的。
24、GC是什么? 為什么要有GC?
  GC是垃圾收集的意思 (Gabage Collection),內(nèi)存處理是編程人員容易出現(xiàn)問題的地方,忘記或者錯誤的內(nèi)存回收會導(dǎo)致程序或系統(tǒng)的不穩(wěn)定甚至崩潰,Java提供的GC功能可以 自動監(jiān)測對象是否超過作用域從而達到自動回收內(nèi)存的目的,Java語言沒有提供釋放已分配內(nèi)存的顯示操作方法。
25、short s1 = 1; s1 = s1 + 1;有什么錯? short s1 = 1; s1 += 1;有什么錯?
??? short s1 = 1; s1 = s1 + 1; (s1+1運算結(jié)果是int型,需要強制轉(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)建了幾個String Object?
??? 兩個
28、設(shè)計4個線程,其中兩個線程每次對j增加1,另外兩個線程對j每次減少1。寫出程序。
以下程序使用內(nèi)部類實現(xiàn)線程,對j增減的時候沒有考慮順序問題。
public class ThreadTest1{
? private int j;
? public static void main(String args[]){
ThreadTest1 tt=new ThreadTest1();
Inc inc=tt.new Inc();
Dec dec=tt.new Dec();
for(int i=0;i<2;i++){
Thread t=new Thread(inc);
t.start();
t=new Thread(dec);
t.start();
}
}
? private synchronized void inc(){
j++;
System.out.println(Thread.currentThread().getName()+"-inc:"+j);
? }
? private synchronized void dec(){
j--;
System.out.println(Thread.currentThread().getName()+"-dec:"+j);
? }
? class Inc implements Runnable{
public void run(){
for(int i=0;i<100;i++){
inc();
}
}
? }
? class Dec implements Runnable{
public void run(){
for(int i=0;i<100;i++){
dec();
}
?}
? }
}
29、Java有沒有g(shù)oto?
java中的保留字,現(xiàn)在沒有在java中使用。
30、啟動一個線程是用run()還是start()?
啟動一個線程是調(diào)用start()方法,使線程所代表的虛擬處理機處于可運行狀態(tài),這意味著它可以由JVM調(diào)度并執(zhí)行。這并不意味著線程就會立即運行。run()方法可以產(chǎn)生必須退出的標志來停止一個線程。
?

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

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


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

二、問題描述:
1)在中文W2000中文窗口編譯和運行,用的是國際版的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運行則由于無字體而無法正常顯示,如果象上面一樣在中文W2000的中文窗口運行,輸出為:

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),那么很多漢字(半個漢字)是無法映射到西文字符中去的,在這種情形下,系統(tǒng)就把這些字符用?代替。同樣,也存在小字符集無法到大字符集的情況,具體原因這里就不詳談了。

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

2.1)在JAVA源文件-->JAVAC-->Class-->Java-->getBytes()-->new String()-->顯示的過程中,每一步都有編碼的轉(zhuǎn)換過程,這個過程總是存在的,只是有的時候用默認的參數(shù)進行。下面我們一步一步分析為什么出現(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();
}
}
}

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

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

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

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

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

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

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

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

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

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

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

2.6.2)下面我們以代碼段12為例,因為它能正確顯示漢字

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

01: C1C2 HelloWorld.java C1C2分別泛指一個ISO8859_1字符,“中”字被拆開
02: U3U4 JAVAC讀取 U1U2泛指一個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要解析成一個漢字!)
06: U7 new String()第二步 然后返回字符(真是一個項兩!U7包含了U3U4的信息)
07: C12 println(String) 這就原來的“中”字,很委屈被JAVAC冤枉了一回,不過被程序員撥亂反正了一下!當然,“中文”兩個字都能正確顯示了!

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

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

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

橘子 2006-04-09 11:13 發(fā)表評論
]]>
主站蜘蛛池模板: 昆山市| 沙雅县| 闻喜县| 舟曲县| 巩义市| 安吉县| 观塘区| 济源市| 泽普县| 忻城县| 南和县| 嵊泗县| 蛟河市| 宜川县| 临湘市| 页游| SHOW| 栾川县| 濉溪县| 宾川县| 新余市| 夏邑县| 万盛区| 耿马| 兴化市| 旺苍县| 都昌县| 七台河市| 宜宾市| 体育| 铅山县| 云阳县| 娄底市| 鄂伦春自治旗| 长泰县| 峡江县| 额尔古纳市| 杭州市| 电白县| 栾城县| 舒城县|