posts - 495,  comments - 11,  trackbacks - 0
           

          先說(shuō)下CVSNT的用戶(hù)驗(yàn)證方式,CVSNT的用戶(hù)驗(yàn)證方式分兩種:Windows系統(tǒng)用戶(hù)與CVSNT用戶(hù)共存的混合驗(yàn)證方式,及CVSNT用戶(hù) 單一驗(yàn)證方式,默認(rèn)工作在混合驗(yàn)證方式下,當(dāng)然使用單一驗(yàn)證方式對(duì)用戶(hù)的管理肯定比較方便一點(diǎn),因此下面的配置就是圍繞該方式進(jìn)行的。各個(gè)資源庫(kù)所使用的 驗(yàn)證方式及用戶(hù)配置由其目錄下CVSROOT里的配置文件決定,其中有幾個(gè)比較重要的文件。


          1、config文件

          控制CVSNT的驗(yàn)證工作方式的就是config文件,注意該文件最前面的兩行:

          #Set this to `no" if pserver shouldn"t check system users/passwords
          #SystemAuth=yes

          第二行就是我們要修改的內(nèi)容,默認(rèn)狀態(tài)是被注釋掉的,SystemAuth有兩個(gè)值yes和no:

          yes:pserver將使用Windows系統(tǒng)用戶(hù)和CVSNT用戶(hù)來(lái)共同驗(yàn)證(若CVSNT用戶(hù)未定義,則用Windows系統(tǒng)用戶(hù)來(lái)進(jìn)行驗(yàn)證),默認(rèn)為yes,CVSNT用戶(hù)在后面將要介紹的passwd文件中定義。

          no:只使用CVSNT用戶(hù)來(lái)進(jìn)行驗(yàn)證。

          該文件可以在客戶(hù)端進(jìn)行修改,因此我們可以將其checkout出來(lái)將第二行改為SystemAuth=no,并commit到CVSNT上就可以啟用單一驗(yàn)證方式了,注意啟用單一驗(yàn)證方式后原來(lái)的Windows系統(tǒng)用戶(hù)將變?yōu)闊o(wú)效,因此要注意執(zhí)行該步驟的時(shí)機(jī)。

          2、 admin文件

          該文件保存CVSNT管理員用戶(hù)列表,內(nèi)容很簡(jiǎn)單,形式如下:
          User1
          User2
          User3
          每一行定義一個(gè)管理 員用戶(hù),默認(rèn)時(shí)沒(méi)有該文件,但你可以在客戶(hù)端自己添加并add上去,再commit到CVSNT上,但是光有這個(gè)文件還是不會(huì)生效的,還要將其添加到 checklist文件中,使CVSNT能夠讀取該文件的內(nèi)容,在checklist中添加文件列表的格式為:

          [空格]文件名 出錯(cuò)信息

          其中文件名前的空格必須要有的,不然會(huì)出錯(cuò)。
          我們可以先添加admin文件到CVSNT中,再修改checklist文件commit,就可以使admin文件生效了。

          3、passwd文件

          服務(wù)器工作在CVSNT用戶(hù)單一驗(yàn)證方式下的時(shí)候,這個(gè)文件定義了CVSNT的用戶(hù)信息,這里面保存著用戶(hù)名,用戶(hù)密碼,以及別名信息。默認(rèn)狀態(tài)下 沒(méi)有該文件,但是我們可以在CVSNT還工作在混合驗(yàn)證方式下時(shí),用系統(tǒng)管理員登錄,通過(guò)添加用戶(hù)命令來(lái)讓CVSNT自動(dòng)建立一個(gè)passwd文件。

          添加用戶(hù)的命令的示例:

          cvs passwd –r administrator –a cvsadmin

          之后系統(tǒng)提示輸入密碼,輸入后服務(wù)器會(huì)新建一個(gè)passwd文件。

          該文件的內(nèi)容很簡(jiǎn)單,形式如下:

          cvsadmin:fqr1fS4gDghrt:administrator
          kid:aTXRfS31Bm6JA
          mystique:Yna4QcXz9dEqd

          以第一行為例:cvsadmin為用戶(hù)名,fqr1fS4gDghrt為CVS使用UNIX標(biāo)準(zhǔn)加密函數(shù)對(duì)密碼進(jìn)行加密后的結(jié)果,administrator為該用戶(hù)的別名,當(dāng)使用混合驗(yàn)證方式時(shí)對(duì)應(yīng)Windows系統(tǒng)用戶(hù)名。

          注意:這個(gè)文件是不能在客戶(hù)端進(jìn)行修改的,不能checkout出來(lái)。

          4、group文件

          該文件定義CVSNT中組信息,同組里的用戶(hù)擁有一樣的權(quán)限,對(duì)組權(quán)限的修改和對(duì)用戶(hù)權(quán)限的修改一樣。

          group文件的內(nèi)容為

          administrators:cvsadmin kid mystique
          users:User1 User2 User3

          可以看到該文件的內(nèi)容也很簡(jiǎn)單,組名:用戶(hù)名,多個(gè)用戶(hù)名之間用空格隔開(kāi)。

          Group文件可以在客戶(hù)端修改,不用修改checkoutlist這個(gè)文件,系統(tǒng)會(huì)自動(dòng)使其生效。

          作為組里面的特定成員可以賦給特定的權(quán)限。

          了解了以上內(nèi)容,下面我說(shuō)一下我自己的配置步驟,我沒(méi)有使用WinCVS進(jìn)行操作,是直接使用命令行進(jìn)行修改的,覺(jué)得這樣思路比較清晰:

          1、添加系統(tǒng)變量CVSROOT=E:/CVSNT/Repository,并把E:CVSNT加入到系統(tǒng)Path路徑。

          2、進(jìn)入命令提示符,因?yàn)榇藭r(shí)為混合驗(yàn)證模式,可以不用不用登陸直接進(jìn)行checkout。可以建立一個(gè)工作目錄,在該目錄下進(jìn)行操作,我這里為E:/CVSNT/Works。

          檢出CVSROOT目錄:

          cvs co CVSROOT

          3、添加CVSNT系統(tǒng)管理員用戶(hù),此時(shí)會(huì)提示設(shè)置用戶(hù)密碼:

          cvs passwd –r administrator –a cvsadmin

          4、修改CVSROOT訪問(wèn)權(quán)限:

          cd CVSROOT
          cvs chown cvsadmin //更改所有者為cvsadmin
          cvs chacl default:n //默認(rèn)權(quán)限為n
          cvs chacl cvsadmin:rwc //添加cvsadmin

          5、修改config文件,按上面的方法修改后commit:

          cvs ci

          6、此時(shí)單一驗(yàn)證方式已經(jīng)啟用了,也就是只能使用剛才添加的cvsadmin進(jìn)行登錄,此時(shí)可以把CVSNT控制面板上的Use local users for pserver authentication instead of domain users關(guān)掉。登錄前還要改一下系統(tǒng)變量CVSROOT,關(guān)閉命令提示符窗口,修改CVSROOT為:

          :pserver:cvsadmin@192.168.0.1:4021/CVSNT/Repository

          這里的192.168.0.1是服務(wù)器的IP地址,/CVSNT/Repository就是前面設(shè)置Repository時(shí)設(shè)置的Name,可以改為你機(jī)器上的配置。修改系統(tǒng)變量之后以下的步驟在任何與服務(wù)器相連的機(jī)器上進(jìn)行,當(dāng)然該機(jī)器上應(yīng)該有CVSNT的可執(zhí)行文件。

          7、如果為了避免出現(xiàn)錯(cuò)誤,先重啟一下CVSNT服務(wù)器,再啟動(dòng)命令提示符來(lái)到E:/CVSNT/Works,因?yàn)橐呀?jīng)啟用單一驗(yàn)證方式,先要進(jìn)行登錄。

          cvs login

          輸入密碼,此時(shí)就是以cvsadmin登錄了。

          8、添加admin文件,首先將CVSROOT檢出,在CVSROOT下新建admin文件,內(nèi)容為

          cvsadmin

          執(zhí)行命令:

          cvs add admin
          cvs ci

          9、修改checklist文件,在該文件末尾添加一行:

          [空格]admin error message

          注意:admin前的空格不能少。

          執(zhí)行命令:

          cvs ci

          經(jīng)過(guò)以上步驟,可以說(shuō)用戶(hù)配置已經(jīng)基本完成了,CVSNT可以很好的工作在單一驗(yàn)證方式下。進(jìn)一步的管理可使用以下命令:

          添加用戶(hù): cvs passwd -a username,使用時(shí)不必理會(huì)需要添加別名的提示。

          修改用戶(hù)權(quán)限:cvs chacl username:r|w|c|n,(r:Read w:write c:control n:none)

          要添加組管理,只需同添加admin步驟一樣,按照格式要求新建group文件即可。

          如果還有不清楚的可以看看自帶的文檔,說(shuō)得還是比較詳細(xì)的。

          posted @ 2007-12-01 13:27 jadmin 閱讀(41) | 評(píng)論 (0)編輯 收藏
          CVS

          一、什么是CVS?

          CVS――Concurrent Versions System并行版本系統(tǒng);
          是一個(gè)標(biāo)準(zhǔn)的版本控制系統(tǒng);
          對(duì)代碼進(jìn)行集中管理;
          記錄代碼所有的更改歷史;
          提供協(xié)作開(kāi)發(fā)的功能;
          支持多人同時(shí)CheckOut與合并。
          以客戶(hù)端/服務(wù)器模式工作,所有的用戶(hù)都在客戶(hù)端進(jìn)行CVS操作,而所有命令的執(zhí)行都在CVS服務(wù)器端進(jìn)行。

          二、CVS基本概念

          1. CVS倉(cāng)庫(kù):又稱(chēng)主拷貝,是CVS系統(tǒng)保存軟件資源的地方。所有項(xiàng)目的所有文件的所有版本都保存在這個(gè)倉(cāng)庫(kù)中。
          2. 版本:開(kāi)發(fā)人員每次向CVS提交所做的修改就形成了一個(gè)新版本。
          3. 工作拷貝:從CVS服務(wù)器端取出的,保存在我們正在使用的客戶(hù)端計(jì)算機(jī)上的代碼拷貝。每個(gè)人員都有一個(gè)屬于自己的工作拷貝。
          4. 檢出代碼(創(chuàng)建工作拷貝check out):從服務(wù)器取出代碼,就是創(chuàng)建工作拷貝的過(guò)程。
          5. 提交代碼(commit):將代碼送到服務(wù)器保存,commit又叫作check in。
          6. 導(dǎo)入代碼(import):將未被CVS進(jìn)行版本管理的代碼引入CVS系統(tǒng)中,由CVS開(kāi)始對(duì)它進(jìn)行版本管理。
          7. CVS日志:CVS用來(lái)記錄每次操作的內(nèi)容的信息。日志信息可以用cvs log命令來(lái)查看。
          8. 更新(update):在協(xié)同開(kāi)發(fā)環(huán)境下,將其他人所作的最新修改從CVS倉(cāng)庫(kù)中取到你的工作拷貝中,從而使得你得工作拷貝與倉(cāng)庫(kù)中得最新版本保持一致。使用update是同步各個(gè)工作拷貝的手段。
          9. 沖突(conflict):在協(xié)同開(kāi)發(fā)的環(huán)境下,當(dāng)兩個(gè)開(kāi)發(fā)人員對(duì)同一個(gè)文件進(jìn)行修改,并且依次提交CVS倉(cāng)庫(kù)時(shí)就發(fā)生了沖突。這種沖突需要開(kāi)發(fā)人員手工消除,并提交到CVS倉(cāng)庫(kù)中形成解除沖突之后的新版本。

          三、CVS命令:

          1.設(shè)置環(huán)境變量。

          set CVSROOT=:pserver:xxx@192.168.0.226:e:/cvsroot
          
          set CVSROOT=:pserver:xxx@ansi.3322.org:e:/cvsroot

          2.簽出工作版本到工作目錄。
          $cd
          
          $cvs??  co??  account/src/common
          該命令只將account/src/common目錄結(jié)構(gòu)簽出到本地。若使用
          $cvs co account
          則將account下所有目錄結(jié)構(gòu)簽出來(lái)。

          3.提交修改的文件到CVS版本庫(kù)中:

          $cvs??  ci??  <filename>
          注意若提交多個(gè)文件可以輸入多個(gè)文件名,并以空格分開(kāi)。若將該目錄下所有文件都提交,那么只需
          $cvs??  ci <回車(chē)>
          即可。

          4.提交新增加的目錄或文件到CVS版本庫(kù)中:

          $cvs??  add??  <dirname>
          
          $cvs??  ci??  <dirname>
          
          $cvs??  add??  <filename>
          
          $cvs??  ci??  <filename>

          5.刪除目錄及文件,需先刪除目錄下的文件

          $rm??  <filename>
          
          $cvs??  remove??  <filename>
          
          $cvs??  ci??  <filename>

          再執(zhí)行
          $cd ..
          $cvs up –P

          則將該空目錄刪除(只是刪除本地工作拷貝的空目錄)。

          6.查看文件狀態(tài)

          $cvs status <filename>

          例如:
          $ cvs st ffun.c
          
          =================================================================
          
          File: ffun.c????????????  Status: Up-to-date
          
          ???  Working revision:????  1.1?????  Wed Nov??  6 11:29:04 2002
          
          ???  Repository revision: 1.1?????  /szunicom/dev/billing/src/preproc/CDMA/ffun.c,v
          
          ???  Sticky Tag:??????????  (none)
          
          ???  Sticky Date:?????????  (none)
          
          ???  Sticky Options:??????  (none)

          注意:最重要的是Status欄,可以有以下幾種狀態(tài):

          Up-to-date

          :表明你的工作拷貝是最新的.
          Locally Modified:表明你曾經(jīng)修改過(guò)該文件,但還沒(méi)有提交,你的版本比倉(cāng)庫(kù)里的新.
          Needing Patch:表明有人已經(jīng)修改過(guò)該文件并且已經(jīng)提交了!你沒(méi)有修改但你的工作拷貝的版本比倉(cāng)庫(kù)里的舊.
          Needs Merge:表明你修改了該文件但沒(méi)有提交,而有人也修改了這個(gè)文件,并且提交給倉(cāng)庫(kù)了。

          Locally added

          :表明使用了"add"命令增加了該文件,但還沒(méi)有"commit"

          Locally Removed

          :表明你使用了"remove"命令,但還沒(méi)有"commit"

          Unkown

          :CVS不知道關(guān)于這個(gè)文件的情況.例如,你創(chuàng)建了一個(gè)新文件,而沒(méi)有使用"add"命令
          解決辦法:
          若狀態(tài)為L(zhǎng)ocally Modified,則需執(zhí)行$cvs ci <filename>
          若狀態(tài)為Needing Patch或Needing Merge,則需執(zhí)行$cvs up <filename>
          將版本庫(kù)里的文件與工作拷貝合并后,再提交給版本庫(kù),使用命令:

          $cvs ci <filename>


          若狀態(tài)為:Locallyadded,則需執(zhí)行$cvs ci <filename>
          若狀態(tài)為:Removed,則需執(zhí)行$cvs ci <filename>
          若狀態(tài)為:Unkown,則需執(zhí)行$cvs add <filename>,$cvs ci <filename>。

          7.查看工作拷貝和倉(cāng)庫(kù)中最后版本之間的修改

          $ cvs diff src.c

          8.查看指定的兩個(gè)版本之間的修改

          $ cvs diff -r 1.1 -r 1.2 <filename>

          9.版本回退(取出以前的某個(gè)版本)
          有兩種方式:
          一是只把某一版本的文件輸出到標(biāo)準(zhǔn)輸出上:

          $cvs up –p –r <版本號(hào)> <filename>

          “-p”選項(xiàng)讓CVS命令的結(jié)果只輸出到標(biāo)準(zhǔn)輸出,而不寫(xiě)入到結(jié)果文件中。

          另一種是將輸出到標(biāo)準(zhǔn)輸出的結(jié)果重定向到文件中:
          $cvs up –p –r <版本號(hào)> <filename> > <filename>

          如:目前abc.c文件的版本號(hào)為1.5,要取出1.2的版本,那么執(zhí)行
          $cvs up –p –r 1.2 abc.c > abc.c

          若沒(méi)有使用“-p”選項(xiàng)進(jìn)行回退,而是使用了$cvs up –r 1.2 abc.c命令,之后若對(duì)1.2版本進(jìn)行修改后再提交到CVS時(shí),會(huì)出現(xiàn)如下提示信息:
          cvs ci
          
          cvs commit: Examining .
          
          cvs commit: sticky tag `1.2' for file `abc.c' is not a branch
          
          cvs [commit aborted]: correct above errors first!

          解決辦法兩種方式:

          1、修改CVS/Entries文件,將以下黃色標(biāo)記部分刪除即可。

          $cd CVS
          
          $ vi E*
          
          /abc.c/1.2/Tue Dec 17 13:33:06 2002//T1.2
          
          
          2、使用$cvs up –A abc.c命令來(lái)消除附著標(biāo)簽,但是該命令是將1.2版本與最新版本進(jìn)行了合并,還需對(duì)abc.c進(jìn)行修改再重新提交。

          10.如何恢復(fù)已經(jīng)刪除的文件或目錄:
          1. 在執(zhí)行了【Remove】命令之后恢復(fù)文件。 ◇ 【Ctrl+L】直接輸入命令cvs add xxxxx,或執(zhí)行【Add Selection】界面操作。 ◇ 這樣就可以直接恢復(fù)還未提交的刪除文件。
          2. 在執(zhí)行了【Commit】命令之后恢復(fù)文件。 ◇ 只能用【Ctrl+L】直接輸入命令cvs add xxxxx,這時(shí)會(huì)得到一個(gè)空的文件。 ◇ 選中這個(gè)空文件,執(zhí)行【Update】操作,得到這個(gè)文件的實(shí)體。 ◇ 再次選中這個(gè)文件,執(zhí)行【Commit】操作,得到這個(gè)文件最新版本。
          3. 由于CVS系統(tǒng)中本質(zhì)上不會(huì)刪除任何目錄,因此,談不上對(duì)目錄的恢復(fù),但是CVS系統(tǒng)默認(rèn)情況下是要在用戶(hù)本機(jī)上(如:YCW2000)要?jiǎng)h除空目錄,因此,可以用如下方法得到已被刪除的空目錄:cvs checkout -p xxx,也可以在Admin=>Preference的【Globals】頁(yè)面進(jìn)行設(shè)置。

          =============================================================================

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

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

          / | \ (版 本 同 步)

          / | \

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

          CVS(Concurrent Version System)版本控制系統(tǒng)是一種GNU軟件包,主要用于在多人開(kāi)發(fā)環(huán)境下的源碼的維護(hù)。實(shí)際上CVS可以維護(hù)任意文檔的開(kāi)發(fā)和使用,例如共享文件的編輯修改,而不僅僅局限于程序設(shè)計(jì)。CVS維護(hù)的文件類(lèi)型可以是文本類(lèi)型也可以是二進(jìn)制類(lèi)型。CVS用Copy-Modify-Merge(拷貝、修改、合并)變化表支持對(duì)文件的同時(shí)訪問(wèn)和修改。它明確地將源文件的存儲(chǔ)和用戶(hù)的工作空間獨(dú)立開(kāi)來(lái),并使其并行操作。CVS基于客戶(hù)端/服務(wù)器的行為使其可容納多個(gè)用戶(hù),構(gòu)成網(wǎng)絡(luò)也很方便。這一特性使得CVS成為位于不同地點(diǎn)的人同時(shí)處理數(shù)據(jù)文件(特別是程序的源代碼)時(shí)的首選。

          所有重要的免費(fèi)軟件項(xiàng)目都使用CVS作為其程序員之間的中心點(diǎn),以便能夠綜合各程序員的改進(jìn)和更改。這些項(xiàng)目包括GNOME、KDE、THE GIMP和Wine等。

          CVS的基本工作思路是這樣的:在一臺(tái)服務(wù)器上建立一個(gè)源代碼庫(kù),庫(kù)里可以存放許多不同項(xiàng)目的源程序。由源代碼庫(kù)管理員統(tǒng)一管理這些源程序。每個(gè)用戶(hù)在使用源代碼庫(kù)之前,首先要把源代碼庫(kù)里的項(xiàng)目文件下載到本地,然后用戶(hù)可以在本地任意修改,最后用CVS命令進(jìn)行提交,由CVS源代碼庫(kù)統(tǒng)一管理修改。這樣,就好象只有一個(gè)人在修改文件一樣,既避免了沖突,又可以做到跟蹤文件變化等。

          CVS是并發(fā)版本系統(tǒng)(Concurrent Versions System)的意思,主流的開(kāi)放源碼網(wǎng)絡(luò)透明的版本控制系統(tǒng)。CVS對(duì)于從個(gè)人開(kāi)發(fā)者到大型,分布團(tuán)隊(duì)都是有用的:

          它的客戶(hù)機(jī)/服務(wù)器存取方法使得開(kāi)發(fā)者可以從任何因特網(wǎng)的接入點(diǎn)存取最 新的代碼。它的無(wú)限制的版本管理檢出(check out:注1)的模式避免了通常的因?yàn)榕潘?檢出模式而引起的人工沖突。 它的客戶(hù)端工具可以在絕大多數(shù)的平臺(tái)上使用。

          CVS被應(yīng)用于流行的開(kāi)放源碼工程中,象Mozilla,GIMP,XEmacs,KDE,和GNOME等。 那么它到底怎么樣?

          你可能會(huì)說(shuō),它非常棒,但是對(duì)于 "我"來(lái)說(shuō)它能做什么?首先,基本的 :一個(gè)版本控制系統(tǒng)保持了對(duì)一系列文件所作改變的歷史記錄。對(duì)于一個(gè)開(kāi)發(fā)者來(lái)說(shuō),那就意味著在你對(duì)一個(gè)程 序所進(jìn)行開(kāi)發(fā)的整個(gè)期間,能夠跟蹤對(duì)其所作的所有改動(dòng)的痕跡。對(duì)你來(lái)說(shuō),有沒(méi)有出現(xiàn)過(guò)由于在令行上 按錯(cuò)鍵而導(dǎo)致一天的工作都白費(fèi)的情況呢?版本控制系統(tǒng)給了你一個(gè)安全的網(wǎng)絡(luò)。

          版本控制系統(tǒng)對(duì)任何人都有用,真的。(畢竟,誰(shuí)不愿意使用一個(gè)安全的 網(wǎng)絡(luò)呢?)但是它們經(jīng)常被軟件開(kāi)發(fā)團(tuán)隊(duì)使用。在團(tuán)隊(duì)中工作的開(kāi)發(fā)者需要能夠調(diào)整他們的各自的修改;一個(gè)集 中式版本控制系統(tǒng)允許那樣做。
          代碼集中的配置

          個(gè)人開(kāi)發(fā)者希望一個(gè)版本控制系統(tǒng)的安全網(wǎng)絡(luò)能夠運(yùn)行在他們的本地的 一臺(tái)機(jī)器上。然而,開(kāi)發(fā)團(tuán)隊(duì)需要一個(gè)集中的服務(wù)器,所有的成員可以將服務(wù)器作為倉(cāng)庫(kù)來(lái)訪問(wèn)他們的代碼。在 一個(gè)辦公室中,沒(méi)有問(wèn)題 --只是將倉(cāng)庫(kù)連到本地網(wǎng)絡(luò)上的一臺(tái)服務(wù)器上就行了。對(duì)于開(kāi)放源碼項(xiàng)目...噢, 還是沒(méi)有問(wèn)題,這要感謝因特網(wǎng)。CVS內(nèi)建了客戶(hù)機(jī)/服務(wù)器存取方法,所以任何一個(gè)可以連到因特網(wǎng)上的開(kāi)發(fā) 者都可以存取在一臺(tái)CVS服務(wù)器上的文件。

          調(diào)整代碼

          在傳統(tǒng)的版本控制系統(tǒng)中,一個(gè)開(kāi)發(fā)者檢出一個(gè)文件,修改它,然后將 其登記回去。檢出文件的開(kāi)發(fā)者擁有對(duì)這個(gè)文件修改的排它權(quán)。沒(méi)有其它的開(kāi)發(fā)者可以檢出這個(gè)文件 -- 并且只 有檢出那個(gè)文件的開(kāi)發(fā)者可以登記(check in:注2)所做的修改。(當(dāng)然對(duì)于管理員有很多方法可以超越這個(gè) 限制。)

          想一下排它的檢出可能會(huì)如何工作:Bob的兄弟檢出 foo.java以便加入 注釋?zhuān)瑢?xiě)好代碼后他什么也沒(méi)做。然后他去吃午飯了。Bob吃完午飯后,發(fā)現(xiàn)他的老板所指給他的一個(gè)bug在 foo.java里。他試圖檢出 foo.java ... 但是版本控制系統(tǒng)不允許他這樣做,因?yàn)樗男值芤呀?jīng)把它檢出了。Bob不 得不等著他的兄弟吃完午飯回來(lái)(在這個(gè) "好"日子用了兩個(gè)小時(shí)),他才可以修正bug。

          在一個(gè)大型的開(kāi)放源碼工程中,因?yàn)殚_(kāi)發(fā)者可能在任意的時(shí)區(qū)工作得很 晚,給予一個(gè)開(kāi)發(fā)者阻止任意地方的其它開(kāi)發(fā)者繼續(xù)處理任意文件的能力很明顯示無(wú)法運(yùn)轉(zhuǎn)。他們最終將因?yàn)椴?能夠在他們想要的時(shí)候開(kāi)展項(xiàng)目而感到厭煩。

          CVS通過(guò)它的無(wú)限制的檢出模式解決了這個(gè)問(wèn)題。檢出一個(gè)文件并不給定 開(kāi)發(fā)者對(duì)那個(gè)文件的排它權(quán)。其它的開(kāi)發(fā)者也可以對(duì)其檢出,進(jìn)行他們自己的修改,并且將其登記回去。

          "等一下!"你可能會(huì)說(shuō)。"但是后面的登記不是會(huì)覆蓋前面的嗎?"回答 是不會(huì)。詳細(xì)地回答就是當(dāng)多個(gè)開(kāi)發(fā)者對(duì)同一個(gè)文件作了修改CVS會(huì)檢測(cè),并且自動(dòng)合并那些改變。

          哇噢。自動(dòng)的?不用擔(dān)心 -- CVS 會(huì)很小心,并且將會(huì)自動(dòng)合并那些只 要不是對(duì)代碼的同一行所作的改動(dòng)。如果CVS不能安全的處理這些改動(dòng),開(kāi)發(fā)者將不得不手工合并它們。 從此去往何處?

          到現(xiàn)在為止,你已經(jīng)毫不猶豫地著迷于CVS 的潛力,并且急不可待地想 開(kāi)始。第一步就是去得到 適合你的平臺(tái)的CVS軟件。安裝CVS通常就是將其從你下載的壓縮包中解開(kāi)這么一件 事。配置CVS 可能要小心一些,它非常依賴(lài)于你使用的平臺(tái)和你的CVS代碼倉(cāng)庫(kù)的存放地。CVShome.org存放了大 量的CVS 文檔:
          《Introduction to CVS》 Jim Blandy所寫(xiě)的一篇很棒地在線介紹。我也推薦《 Open Source Development with CVS》 Karl Fogel寫(xiě)的。你可以讀一下我寫(xiě)的關(guān) 于它的評(píng)論在OpenAvenue VOX上。Karl已 經(jīng)將書(shū)中關(guān)于CVS的部分置于GPL許可證之下;這篇文檔在Karl的站點(diǎn)上以多種文檔格式提供。

          《The Cederqvist》 -- 由Per Cederqvist所編寫(xiě)的CVS手冊(cè) -- 是一個(gè)關(guān)于CVS信息的全面資料。

          有大量的可用在許多平臺(tái)上CVS 附加工具,它們給 CVS增加了功能或使得CVS更容易使用。

          posted @ 2007-11-27 20:33 jadmin 閱讀(63) | 評(píng)論 (0)編輯 收藏
          SWT

          ?????? SWT-"Standard Widget Toolkit",它是一個(gè)Java平臺(tái)下開(kāi)放源碼的Native GUI組件庫(kù),也是Eclipse平臺(tái)的UI組件之一。從功能上來(lái)說(shuō),SWT與AWT/SWING是基本等價(jià)的。SWT以方便有效的方式提供了便攜式的(即Write Once,Run Away)帶有本地操作系統(tǒng)觀感的UI組件。
          ?????? 由于widget系統(tǒng)的固有復(fù)雜性以及平臺(tái)之間微妙的差異,即使在理想情況下,能夠達(dá)到工業(yè)標(biāo)準(zhǔn)的跨平臺(tái)的widget類(lèi)庫(kù)也是很難編寫(xiě)和維護(hù)的。最早的AWT組件現(xiàn)在被認(rèn)為是樣貌丑陋的,而且存在很多問(wèn)題;SWING組件雖然也是缺點(diǎn)多多,但是隨著JDK版本的不斷升高,它仍在不斷進(jìn)行著改進(jìn)。我認(rèn)為,SWT在功能上與AWT/SWING不相伯仲,但是組件更為豐富,平臺(tái)表現(xiàn)穩(wěn)定,BUG也相對(duì)較少。如果你的應(yīng)用程序真的需要在多個(gè)平臺(tái)上運(yùn)行,需要更為美觀的界面,又不那么依賴(lài)于其他基于AWT/SWING的圖形庫(kù),那么SWT或許是一個(gè)比AWT/SWING更好的選擇。

          =========================================

          為什么要使用SWT?

            SWT是一個(gè)IBM開(kāi)發(fā)的跨平臺(tái)GUI開(kāi)發(fā)工具包。至于IBM費(fèi)勁自己另起爐灶開(kāi)發(fā)一個(gè)GUI工具包,而不是使用Sun現(xiàn)有的由AWT, Swing, Java 2D, Java 3D等構(gòu)成的Java GUI框架,那就說(shuō)來(lái)話長(zhǎng)了。(得在一個(gè)BBS讀過(guò)一個(gè)關(guān)SWT起源的調(diào)類(lèi)的帖子)。

            在SWT之前,Sun經(jīng)提供了一個(gè)跨平臺(tái)GUI開(kāi)發(fā)工具包AWT (Abstract Windowing Toolkit)AWT框架也使用的是原生窗口部件(native widgets),但是它一直未能突破LCD問(wèn)題LCD問(wèn)題導(dǎo)致了一些主要平臺(tái)特征的失。如果你不明白的(其實(shí)我也沒(méi)明白),話說(shuō),如果平臺(tái)A有窗口部件(widgets1–40,而平臺(tái)B有窗口部件(widgets20–25,那跨平臺(tái)的AWT框架只能提供兩個(gè)窗口部件集的交集。

            解決個(gè)問(wèn)題Sun創(chuàng)建了一個(gè)新的框架。個(gè)框架不再使用原生窗口部件,而是使用仿真窗口部件(emulated widgets)。個(gè)方法然解決了LCD問(wèn)題,并且提供了豐富的窗口部件集,但是它也來(lái)了新的問(wèn)題。例如,Swing應(yīng)用程序的界面外不再和原生應(yīng)用程序的外相似。 然在JVMSwing應(yīng)用程序已經(jīng)得到了最大程度的性能改善,但是它們還是存在著其原生對(duì)應(yīng)物所不具有的性能問(wèn)題。并且,Swing應(yīng)用程序消耗太多的內(nèi)存,這樣Swing不適于一些小設(shè)備,如PDA和移動(dòng)電話等。

            IBM進(jìn)行了嘗試底解決AWTSwing框架來(lái)的上述問(wèn)題。最IBM創(chuàng)建了一個(gè)新的GUI庫(kù)就是SWTSWT框架通過(guò)JNI來(lái)訪問(wèn)原生窗口部件。如果在宿主(host)平臺(tái)上無(wú)法找到一個(gè)窗口部件,SWT就會(huì)自動(dòng)地模它。

          =====================================

          Tags:java,rcp,jface,swt,ibm,eclipse,ui,gui

          posted @ 2007-11-27 15:04 jadmin 閱讀(86) | 評(píng)論 (0)編輯 收藏

          在JDK環(huán)境配置好的情況下,進(jìn)行如下操作:

          1.先下載最新版Derby數(shù)據(jù)庫(kù)
          下載地址:http://db.apache.org/derby/
          本人下載的是:db-derby-10.3.1.4-bin.zip

          2.將db-derby-10.3.1.4-bin.zip解壓到一目錄下,我這里是才C:\Derby\db-derby-10.3.1.4-bin

          3.查看“系統(tǒng)屬性”——“高級(jí)”——“環(huán)境變量”,在“系統(tǒng)變量”下面新建變量“DERBY_INSTALL”,值為第2步的路徑值C:\Derby\db-derby-10.3.1.4-bin

          4.在CLASSPATH里增加“%DERBY_INSTALL%\lib\derby.jar;%DERBY_INSTALL%\lib\derbytools.jar;”內(nèi)容

          5.進(jìn)入Derby安裝目錄“%DERBY_INSTALL%\frameworks\embedded\bin”,雙擊運(yùn)行文件setEmbeddedCP.bat

          6.測(cè)試Derby數(shù)據(jù)庫(kù)環(huán)境是否配置成功,打開(kāi)命令提示符窗口,輸入信息“java org.apache.derby.tools.sysinfo”,如出現(xiàn)諸如下面的信息:

          C:\Documents and Settings\Administrator>java org.apache.derby.tools.sysinfo
          ------------------ Java 信息 ------------------
          Java 版本:??????? 1.5.0_12
          Java 供應(yīng)商:????? Sun Microsystems Inc.
          Java 主目錄:????? C:\Program Files\Java\jdk1.5.0_12\jre
          Java 類(lèi)路徑:????? .;C:\Program Files\Java\jdk1.5.0_12\lib;C:\Program Files\Java
          \jdk1.5.0_12\lib\dt.jar;C:\Program Files\Java\jdk1.5.0_12\lib\tools.jar;C:\Derby
          \db-derby-10.3.1.4-bin\lib\derby.jar;C:\Derby\db-derby-10.3.1.4-bin\lib\derbytoo
          ls.jar;C:\Program Files\Microsoft SQL Server 2000 Driver for JDBC\lib\msbase.jar
          ;C:\Program Files\Microsoft SQL Server 2000 Driver for JDBC\lib\mssqlserver.jar;
          C:\Program Files\Microsoft SQL Server 2000 Driver for JDBC\lib\msutil.jar;C:\Pro
          gram Files\MySQL\mysql-connector-java-5.0.7-bin.jar;C:\Program Files\Apache Soft
          ware Foundation\Tomcat 5.5\common\lib\servlet-api.jar;C:\Program Files\Libs\dom4
          j-1.6.1.jar
          OS 名:??????????? Windows XP
          OS 體系結(jié)構(gòu):????? x86
          OS 版本:????????? 5.1
          Java 用戶(hù)名:????? Administrator
          Java 用戶(hù)主目錄:C:\Documents and Settings\Administrator
          Java 用戶(hù)目錄:??? C:\Documents and Settings\Administrator
          java.specification.name: Java Platform API Specification
          java.specification.version: 1.5
          --------- Derby 信息 --------
          JRE - JDBC: J2SE 5.0 - JDBC 3.0
          [C:\Derby\db-derby-10.3.1.4-bin\lib\derby.jar] 10.3.1.4 - (561794)
          [C:\Derby\db-derby-10.3.1.4-bin\lib\derbytools.jar] 10.3.1.4 - (561794)
          ------------------------------------------------------
          ----------------- 語(yǔ)言環(huán)境信息 -----------------
          當(dāng)前語(yǔ)言環(huán)境: [中文/中國(guó) [zh_CN]]
          找到支持的語(yǔ)言環(huán)境:[cs]
          ???????? 版本:10.3.1.4 - (561794)
          找到支持的語(yǔ)言環(huán)境:[de_DE]
          ???????? 版本:10.3.1.4 - (561794)
          找到支持的語(yǔ)言環(huán)境:[es]
          ???????? 版本:10.3.1.4 - (561794)
          找到支持的語(yǔ)言環(huán)境:[fr]
          ???????? 版本:10.3.1.4 - (561794)
          找到支持的語(yǔ)言環(huán)境:[hu]
          ???????? 版本:10.3.1.4 - (561794)
          找到支持的語(yǔ)言環(huán)境:[it]
          ???????? 版本:10.3.1.4 - (561794)
          找到支持的語(yǔ)言環(huán)境:[ja_JP]
          ???????? 版本:10.3.1.4 - (561794)
          找到支持的語(yǔ)言環(huán)境:[ko_KR]
          ???????? 版本:10.3.1.4 - (561794)
          找到支持的語(yǔ)言環(huán)境:[pl]
          ???????? 版本:10.3.1.4 - (561794)
          找到支持的語(yǔ)言環(huán)境:[pt_BR]
          ???????? 版本:10.3.1.4 - (561794)
          找到支持的語(yǔ)言環(huán)境:[ru]
          ???????? 版本:10.3.1.4 - (561794)
          找到支持的語(yǔ)言環(huán)境:[zh_CN]
          ???????? 版本:10.3.1.4 - (561794)
          找到支持的語(yǔ)言環(huán)境:[zh_TW]
          ???????? 版本:10.3.1.4 - (561794)
          ------------------------------------------------------
          Derby數(shù)據(jù)庫(kù)環(huán)境已經(jīng)基本配置好了

          本文作者:曦勤

          http://hi.baidu.com/jadmin

          posted @ 2007-11-27 10:24 jadmin 閱讀(130) | 評(píng)論 (0)編輯 收藏

          要用開(kāi)源數(shù)據(jù)庫(kù)Derby了,下面先轉(zhuǎn)篇入門(mén)級(jí)的文章,學(xué)習(xí)學(xué)習(xí)!

          數(shù)據(jù)庫(kù)做為數(shù)據(jù)持久化存儲(chǔ)的重要手段怎么強(qiáng)度都不過(guò)分,但傳統(tǒng)的數(shù)據(jù)庫(kù)都比較龐大,需要安裝配置等,對(duì)于一些比較輕量級(jí)的應(yīng)用來(lái)說(shuō)有點(diǎn)象殺雞用牛刀一樣.

          Derby做為一個(gè)開(kāi)源的、純Java數(shù)據(jù)庫(kù)引起了越來(lái)越多的關(guān)注,它源自IBM的CloudScape,現(xiàn)在成了大名鼎鼎的Apache基金會(huì)的開(kāi)源項(xiàng)目。Apache一項(xiàng)是開(kāi)源項(xiàng)目的領(lǐng)導(dǎo)者,從他們手里出去的東西都很不錯(cuò),在此感謝一下這些無(wú)私奉獻(xiàn)的人們。

          Derby做為嵌入式數(shù)據(jù)庫(kù)的一個(gè)方便之處就是對(duì)數(shù)據(jù)庫(kù)的一切操控都可以在Java程序代碼中實(shí)現(xiàn),并且它非常的小,幾個(gè)jar文件總共才2M多,非常輕巧,非常便于我們程序的移植。下面說(shuō)一步步的來(lái)說(shuō)明一下怎樣使用。

          首先,從http://db.apache.org/derby/下載Derby的最新版本,直接解壓到本地,然后設(shè)置程序運(yùn)行的環(huán)境變量。

          在win2000/xp中“我的電腦”--》右鍵--》屬性--》環(huán)境變量--》變量--》添加

          1.設(shè)置JAVA_HOME

          2.設(shè)置DERBY_INSTALL(一定要是這個(gè)名字,否則可能無(wú)法正常運(yùn)行),值為解壓的目錄

          環(huán)境變量設(shè)置好了之后,我們就可以著手寫(xiě)第一個(gè)測(cè)試程序了。

          和使用其它的數(shù)據(jù)庫(kù)一樣,首先加載數(shù)據(jù)庫(kù)驅(qū)動(dòng):

          Class.forName("org.apachy.derby.jdbc.EmbeddedDriver");

          然后我們創(chuàng)建一個(gè)數(shù)據(jù)庫(kù):

          Connection conn=DriverManager.getConnection("jdbc.derby.derbyDB;create=true","user","pwd");

          在上面的Url中指定create=true,則創(chuàng)建一個(gè)新的數(shù)據(jù)庫(kù)。

          得到連接之后,我們就可以象訪問(wèn)其它數(shù)據(jù)庫(kù)一樣,進(jìn)行相關(guān)操作了。

          Statement st=conn.createStatement();

          st.execute("create table test1(id int,name varchar(20));

          st.execute("insert into test1 values(1,'sinboy')");

          st.execute("inert into test1 values(2,'Tom')");

          ResultSet rs=st.executeQuery("select * from test1");

          while(rs.next){

          ?? System.out.println("id:"+rs.getInt(1)+" name:"+rs.getString(2));

          }

          rs.close();

          st.close();

          conn.commit();

          conn.close();

          Derby的最大好處應(yīng)該還是小巧、純Java、好移植,比較適全小量的數(shù)據(jù)存儲(chǔ)。

          posted @ 2007-11-25 20:21 jadmin 閱讀(455) | 評(píng)論 (0)編輯 收藏

          做項(xiàng)目時(shí),經(jīng)常遇到要把數(shù)據(jù)庫(kù)的內(nèi)容放到j(luò)avascript里。不管是單個(gè)字符串(String),還是集合(array)。javascript不能直接從數(shù)據(jù)庫(kù)拿東西。所以只得借助一些其他條件。比如在頁(yè)面上的標(biāo)簽里放id,name 之類(lèi)的標(biāo)志。

          假如:

          1,獲取字符串:

          user.getName() 是一條單個(gè)的記錄。

          <div id=a><%=user.getName() %></div>

          那么javascript很容易獲取 : var jsa=???? document.getElementById("a").innerText; (注:innerHTML也可以獲取。)

          2,獲取集合,數(shù)組:

          <form name="form1">
          ?????? <table>
          ????????????????? <%
          ???? Mgr mgr=new Mgr();
          ???? ArrayList list=mgr.getonebbs();
          ???? for(int i=0;i<list.size();i++)
          ???? {
          ?????? Ext role=(Ext)list.get(i);
          ????? %>
          ?????????????? <tr>
          ?????????????? <td id="cid<%=i %>"><%=role.getId()%></td>
          ?????????????? <td id="cname<%=i %>"><%=role.getName()%></td>
          ?????????????? <td id="cpass<%=i %>"><%=role.getPass()%></td>
          ?????????????? <td id="ctel<%=i %>"><%=role.getTel()%></td>
          ?????????????? </tr>
          ??????????? <%
          ????? }%>
          ???? <input type="hidden" value="<%=list.size() %>" name="hid" >
          ????? </table>
          </form>

          javascript獲取:
          ???????? var cc = document.getElementById("hid").value; //首先獲取長(zhǎng)度,下面循環(huán)輸出
          ????????? var a=new Array();
          ??????????? var b=new Array();
          ????????????? var c=new Array();
          ??????????????? var d=new Array();
          ????????? var myData=new Array();
          ??????? for(var j=0;j<cc;j++)
          ??????? {
          ????????? a[j]= document.getElementById("cid"+j).innerText;
          ????????? b[j]= document.getElementById("cname"+j).innerText;
          ????????? c[j]= document.getElementById("cpass"+j).innerText;
          ????????? d[j]= document.getElementById("ctel"+j).innerText;
          ?????????????????? //????? alert(a+" "+b+" "+c+" "+d+" ");???? //測(cè)試
          ?????????????????? myData[j] =???? [a[j],b[j],c[j],d[j]] ;???
          ??????? }

          這樣就把數(shù)組放到myData中去了。

          3,總結(jié):
          先把輸出放到j(luò)sp頁(yè)面上,?????????????? //也就是把數(shù)據(jù)查詢(xún)出來(lái)
          然后在js里面獲取jsp上的數(shù)據(jù),???? //通過(guò)document.獲取。 單個(gè),循環(huán)。
          然后放到string 或者 array里面。//OK

          反正感覺(jué)多做了2步似的,繞了個(gè)圈,不過(guò)沒(méi)辦法,人家都是這樣做的。。。

          js數(shù)組的寫(xiě)法:
          ArrI=new Array();
          ArrI[0] = new Array("username1","0","609");
          ArrI[1] = new Array("username2","609","610");
          ArrI[2] = new Array("username3","609","611");

          ArrII=new Array(
          new Array("username1","0","609"),
          new Array("username2","609","610"),
          new Array("username3","609","611")
          );

          ArrIII=[];
          ArrIII[0] = new Array("username1","0","609");
          ArrIII[1] = new Array("username2","609","610");
          ArrIII[2] = new Array("username3","609","611");

          ArrIIII=[
          ["username1","0","609"],
          ["username2","609","610"],
          ["username3","609","611"]
          ];
          一般最后一種..
          posted @ 2007-11-10 20:02 jadmin 閱讀(100) | 評(píng)論 (0)編輯 收藏

          How to clone:

          1. Implement the Cloneable interface, and

          2. Redefine the clone method with the public access modifier.


          Cloneable:

          The Cloneable interface is one of a handful of tagging interfaces that Java provides.A tagging interface has no methods; its only purpose is to allow the use of instanceof in a type inquiry:
          if (obj instanceof Cloneable) . . .
          We recommend that you do not use this technique in your own programs.


          Shallow copy:

          Even if the default (shallow copy) implementation of clone is adequate, you still need to implement the Cloneable interface, redefine clone to be public, and call super.clone(). Here is an example:

          class Employee implements Cloneable
          {
          ?? // raise visibility level to public, change return type
          ?? public Employee clone() throws CloneNotSupportedException
          ?? {
          ????? return super.clone();
          ?? }
          ?? . . .
          }


          Deep copy:

          class Employee implements Cloneable
          {
          ?? . . .
          ?? public Object clone() throws CloneNotSupportedException
          ?? {
          ????? // call Object.clone()
          ????? Employee cloned = (Employee) super.clone();

          ????? // clone mutable fields
          ????? cloned.hireDay = (Date) hireDay.clone()

          ????? return cloned;
          ?? }
          }

          1 The clone method of the Object class threatens to throw a CloneNotSupportedException—it does that whenever clone is invoked on an object whose class does not implement the Cloneable interface. Of course, the Employee and Date class implements the Cloneable interface, so the exception won't be thrown.

          2
          public Employee clone()
          {
          ?? try
          ?? {
          ????? return super.clone();
          ?? }
          ?? catch (CloneNotSupportedException e) { return null; }
          ?? // this won't happen, since we are Cloneable
          }

          This is appropriate for final classes. Otherwise, it is a good idea to leave the tHRows specifier in place. That gives subclasses the option of throwing a CloneNotSupportedException if they can't support cloning.


          Use clone:

          public static void main(String[] args) {
          ???? try {
          ??????? Employee original = new Employee("John Q. Public", 50000);
          ??????? original.setHireDay(2000, 1, 1);
          ??????? Employee copy = original.clone();
          ??????? copy.raiseSalary(10);
          ??????? copy.setHireDay(2002, 12, 31);
          ??????? System.out.println("original=" + original);
          ??????? System.out.println("copy=" + copy);
          ??? }
          ??? catch (CloneNotSupportedException e) {
          ??????? e.printStackTrace();
          ??? }
          }

          posted @ 2007-11-10 10:39 jadmin 閱讀(79) | 評(píng)論 (0)編輯 收藏

          1。list方法。?? 將 Enumeration 類(lèi)型轉(zhuǎn)換成list類(lèi)型

          2。swap方法。方便的調(diào)換一個(gè)list中的兩個(gè)元素的位置。

          3。lastIndexOfSubList方法。從一個(gè)list中從后面開(kāi)始查找另外一個(gè)list第一次出現(xiàn)的位置。

          4。rotate方法。在一個(gè)list中,順序移動(dòng)每一個(gè)元素的位置到指定的位置。

          5。replaceAll方法。用指定的元素替換一個(gè)list中所用匹配的元素。

          6。indexOfSubList方法。從一個(gè)list中從前面開(kāi)始查找另外一個(gè)list第一次出現(xiàn)的位置。

          示例程序:

          import java.util.*;

          class TestCollections {

          public static void main(String[] args) {
          TestCollections t = new TestCollections();
          t.testList();
          }
          public void testList() {
          Vector v = new Vector();
          v.add("a");
          v.add("b");
          Enumeration e = v.elements() ;
          List l = Collections.list(e);
          System.out.println(l);
          }

          public void testSwap() {
          List l = new ArrayList();
          l.add("t");
          l.add("a");
          l.add("n");
          l.add("k");
          l.add("s");
          System.out.println(l);
          Collections.swap(l,1,3);
          System.out.println(l);
          }

          public void testLastIndexOfSubList() {
          List l = new ArrayList();
          l.add("a");
          l.add("b");
          l.add("c");
          l.add("d");
          l.add("e");
          l.add("a");
          l.add("b");
          l.add("c");
          l.add("d");
          l.add("e");
          List l2 = new ArrayList();
          l2.add("b");
          l2.add("c");
          l2.add("d");
          int result = Collections.lastIndexOfSubList(l,l2);
          if(result != -1) {
          ?? System.out.println("!!! " + result + ". Found from " + l + " with " + l2);
          } else {
          ?? System.out.println("!!! Not found from " + l + " with " + l2);
          }
          List l3 = new ArrayList();
          l3.add("b");
          l3.add("d");
          l3.add("d");
          result = Collections.lastIndexOfSubList(l,l3);
          if(result != -1) {
          ?? System.out.println("!!! " + result + ". Found from " + l + " with " + l3);
          } else {
          ?? System.out.println("!!! Not found from " + l + " with " + l3);
          }
          }
          public void testRotate() {
          List l = new ArrayList();
          l.add("t");
          l.add("a");
          l.add("n");
          l.add("k");
          l.add("s");
          System.out.println(l);
          Collections.rotate(l,1);
          System.out.println(l);

          //
          ?? l = new ArrayList();
          l.add("t");
          l.add("a");
          l.add("n");
          l.add("k");
          l.add("s");
          System.out.println(l);
          Collections.rotate(l,-4);
          System.out.println(l);

          ?? l = new ArrayList();
          l.add("a");
          l.add("b");
          l.add("c");
          l.add("d");
          l.add("e");
          System.out.println(l);
          Collections.rotate(l.subList(1, 4), -1);
          System.out.println(l);


          }

          public void testReplaceAll() {
          List l = new ArrayList();
          l.add("t");
          l.add("a");
          l.add("n");
          l.add("a");
          l.add("s");
          System.out.println(l);
          boolean b = Collections.replaceAll(l,"a","hello");
          System.out.println(l);
          System.out.println(b);

          // not found
          b = Collections.replaceAll(l,"a","hello");
          System.out.println(b);

          }

          public void testIndexOfSubList() {
          List l = new ArrayList();
          l.add("a");
          l.add("b");
          l.add("c");
          l.add("d");
          l.add("e");
          List l2 = new ArrayList();
          l2.add("b");
          l2.add("c");
          l2.add("d");
          int result = Collections.indexOfSubList(l,l2);
          if(result != -1) {
          ?? System.out.println("!!! " + result + ". Found from " + l + " with " + l2);
          } else {
          ?? System.out.println("!!! Not found from " + l + " with " + l2);
          }
          List l3 = new ArrayList();
          l3.add("b");
          l3.add("d");
          l3.add("d");
          result = Collections.indexOfSubList(l,l3);
          if(result != -1) {
          ?? System.out.println("!!! " + result + ". Found from " + l + " with " + l3);
          } else {
          ?? System.out.println("!!! Not found from " + l + " with " + l3);
          }
          }
          }

          posted @ 2007-11-08 07:37 jadmin 閱讀(75) | 評(píng)論 (0)編輯 收藏
          1.在一些字符串?dāng)?shù)組中,常會(huì)有重復(fù)的記錄,比如手機(jī)號(hào)碼,我們可以通過(guò)Hashtable來(lái)對(duì)其進(jìn)行過(guò)濾
          public String[] checkArray(String[] str)...{
          ??????? Hashtable<String, String> hash=new Hashtable<String, String>();

          ??????? for(int i=0;i<str.length;i++)...{
          ??????????? if(!hash.containsKey(str[i]))
          ??????????????? hash.put(str[i], str[i]);
          ??????? }

          ??????? Enumeration enumeration=hash.keys();
          ??????? String[] str_new=new String[hash.size()];
          ??????? int i=0;

          ??????? while(enumeration.hasMoreElements())...{
          ??????????? str_new[i]=enumeration.nextElement().toString();
          ??????????? i++;
          ??????? }
          ??????? return str_new;
          ??? }

          示例:
          ??????? String[] mobile={"13811071500","13811071500","13811071501","13811071503","13811071501"};
          ??????? mobile=checkArray(mobile);
          ??????? for(int i=0;i<mobile.length;i++)
          ??????????? System.out.println(mobile[i]);
          ?????? 輸出結(jié)果為:
          ??????? 13811071503
          ??????? 13811071501
          ??????? 13811071500
          2.A,B均為字符串?dāng)?shù)組,找出在A中存在,而在B中不存在的字符串
          ??? public String[] compareArray(String[] A,String[] B){
          ??????? Hashtable<String, String> hash=new Hashtable<String, String>();
          ??????? Hashtable<String, String> hash_new=new Hashtable<String, String>();

          ??????? for(int i=0;i<B.length;i++)
          ??????????? hash.put(B[i], B[i]);

          ??????? for(int i=0;i<A.length;i++){
          ??????????? if(!hash.containsKey(A[i]))
          ??????????????? hash_new.put(A[i], A[i]);
          ??????? }

          ??????? String[] C=new String[hash_new.size()];
          ??????? int i=0;
          ??????? Enumeration enumeration=hash_new.keys();

          ??????? while(enumeration.hasMoreElements()){
          ??????????? C[i]=enumeration.nextElement().toString();
          ??????????? i++;
          ??????? }
          ??????? return C;
          ??? }
          示例:
          ??????? String[] mobile1={"13811071500","13811071501","13811071502","13811071503","13811071504"};
          ??????? String[] mobile2={"13811071500","13811071505","13811071502","13811071506","13811071504"};
          ??????? String[] mobile3=compareArray(mobile1,mobile2);
          ??????? for(int i=0;i<mobile3.length;i++)
          ??????????? System.out.println(mobile[i]);
          輸出結(jié)果:
          ??? 13811071503
          ??? 13811071501
          存在的問(wèn)題:
          每次都是倒序,可以再對(duì)程序稍加改動(dòng),變成正序。

          3.將一個(gè)字符串?dāng)?shù)組中某一個(gè)特定的字符串過(guò)濾掉
          /** *//**檢驗(yàn)一個(gè)字符串?dāng)?shù)組,若包含某一特定的字符串,則將該字符串從數(shù)組中刪
          除,返回剩余的字符串?dāng)?shù)組
          ???? * @param str_array 字符串?dāng)?shù)組
          ???? * @param str_remove 待刪除的字符串
          ???? * @return 過(guò)濾后的字符串
          ???? */
          ??? public String[] removeStrFromArray(String[] str_array,String
          str_remove)...{
          ??????? Hashtable<String, String> hash=new Hashtable<String, String>();
          ??????? for(int i=0;i<str_array.length;i++)...{
          ??????????? if(!str_array[i].equals(str_remove))
          ??????????????? hash.put(str_array[i], str_array[i]);
          ??????? }
          ??????? //生成一個(gè)新的數(shù)組
          ??????? String[] str_new=new String[hash.size()];
          ??????? int i=0;
          ??????? Enumeration enumeration=hash.keys();
          ??????? while(enumeration.hasMoreElements())...{
          ??????????? str_new[i]=enumeration.nextElement().toString();
          ??????????? i++;
          ??????? }
          ??????? return str_new;
          ??? }
          posted @ 2007-11-06 21:07 jadmin 閱讀(97) | 評(píng)論 (0)編輯 收藏

          如果你的很多時(shí)間是用來(lái)敲純文本,寫(xiě)程序或HTML,那么有效地使用一個(gè)好的編輯器能節(jié)省你不少時(shí)間。這篇文章里的指導(dǎo)和提示將有助于你更快工作,更少犯錯(cuò)誤。

          文中采用開(kāi)源文本編輯器Vim(Vi IMproved)說(shuō)明有效編輯的思想,但這些思想也適用于其他編輯器。擇合適的編輯器只是有效編輯的第一步,對(duì)于哪個(gè)編輯器更好的討論將占很大地方,這里就不提了。如果你不知道該用哪個(gè)編輯器,或者對(duì)現(xiàn)在所使用的不太滿意,不妨試試Vim;你是不會(huì)失望的。

          第一部分:編輯一個(gè)文件

          快速定位

          編輯中大部分時(shí)間是花費(fèi)在閱讀、查錯(cuò)和尋找應(yīng)該進(jìn)行編輯的地方上,而不是插入新文字或進(jìn)行修改。在文件中不斷定位(navigate)是經(jīng)常要做的,所以最好學(xué)會(huì)如何快速地進(jìn)行。

          你常會(huì)搜尋文檔中的一些文字。或者找出包含特定詞或詞組的行。你當(dāng)然可以使用搜尋命令 /pattern,不過(guò)還有更聰明的方法:

          * 如果你看到一個(gè)特定詞,想看看其他地方是不是出現(xiàn)過(guò)同樣的詞,可以使用* 命令。它將對(duì)光標(biāo)所指的詞進(jìn)行搜尋。
          * 如果設(shè)置了 ' incsearch' 選項(xiàng),Vim將在你正在輸入搜尋模式的時(shí)候就顯示搜尋的結(jié)果(而不是等到你敲了回車(chē)之后)。這能夠使你更快地找出拼寫(xiě)錯(cuò)誤。
          * 如果設(shè)置了 ' hlsearch' 選項(xiàng),Vim將使用黃色背景對(duì)搜尋結(jié)果進(jìn)行高亮顯示。你可以對(duì)搜尋的結(jié)果一目了然。應(yīng)用在程序代碼中可以顯示變量的所有引用。你甚至不需要移動(dòng)鼠標(biāo)就能看到所有的搜尋結(jié)果。

          對(duì)于結(jié)構(gòu)化的文檔,快速定位的辦法就更多了。Vim提供專(zhuān)門(mén)針對(duì)C程序(以及C++、Java等等)的特殊命令:

          * 使用 %可以從開(kāi)始括號(hào)跳到對(duì)應(yīng)的關(guān)閉括號(hào)。或者從 ``#if'' 跳到對(duì)應(yīng)的 ``#endif''。事實(shí)上, % 可以完成許多對(duì)應(yīng)項(xiàng)之間的跳轉(zhuǎn)。可以用來(lái)檢查if()和{}結(jié)構(gòu)是否平衡。
          * 使用 [{可以在代碼段(block)中跳回到段起始的 ``{``。
          * 使用 gb 可以從引用某個(gè)變量的地方跳轉(zhuǎn)到它的局部聲明。

          定位的方法當(dāng)然不止這些。關(guān)鍵是你需要知道有這些命令。你也許會(huì)說(shuō)不可能學(xué)會(huì)所有命令 — Vim里有成百個(gè)定位命令,有的很簡(jiǎn)單,有的很聰明 — 這需要幾星期的學(xué)習(xí)。不過(guò),你不必如此;你只需要了解自己的編輯特點(diǎn),然后掌握相關(guān)的定位命令就可以了。

          可以采取三個(gè)基本步驟:

          1. 在你進(jìn)行編輯的時(shí)候,注意那些重復(fù)進(jìn)行的操作。
          2. 找出能快速進(jìn)行這些操作的編輯命令。閱讀文檔,問(wèn)問(wèn)朋友,或者看看其他人是如何做的。
          3. 進(jìn)行練習(xí),知道熟練為止。

          讓我們通過(guò)以下這個(gè)例子說(shuō)明一下:

          1. 你發(fā)現(xiàn)在寫(xiě)C程序時(shí),經(jīng)常要查找函數(shù)定義。你目前使用 * 命令對(duì)函數(shù)名進(jìn)行搜尋,但得到的往往是函數(shù)的引用而不是函數(shù)定義。你覺(jué)得一定會(huì)有更好的辦法。
          2. 讀過(guò)一篇快速參考以后,你發(fā)現(xiàn)關(guān)于定位標(biāo)記的說(shuō)明,里面說(shuō)明了如何定位函數(shù)定義,這正是你要找的!
          3. 你試著生成了一個(gè)標(biāo)記文件,使用Vim自帶的ctags程序。你學(xué)會(huì)了使用CTRL-] 命令,發(fā)現(xiàn)這省了不少事。為了更方便,你在 Makefile 里加入了幾行以自動(dòng)生成標(biāo)記文件。

          當(dāng)你使用以上三個(gè)步驟時(shí),有幾點(diǎn)需要注意的地方:

          * ``我只想完成任務(wù),不想去讀那些文檔來(lái)找新的命令。''。如果你真的是這么想的,那么你將永遠(yuǎn)停留在計(jì)算的石器時(shí)代。有些人編寫(xiě)什么都用Notepad,卻總不明白為什么其他人總能用他一半的時(shí)間成任務(wù)。
          * 不要過(guò)分。如果你總為一點(diǎn)小事也要去找完美的命令,你就沒(méi)法集中精力到你本要完成的任務(wù)上了。只要找出那些耗費(fèi)過(guò)多時(shí)間的操作,然后使用相關(guān)的命令直到熟練就可以了。這以后你就能集中精力到自己的文檔上了。

          下面這些章節(jié)給出了大多數(shù)人遇到的操作。你仿照它們?cè)趯?shí)際工作中使用

          三個(gè)基本步驟

          不要敲兩次

          我們所使用的字詞集合是有限的。既使是詞組和句子也不過(guò)是有限的幾個(gè)。對(duì)于程序來(lái)說(shuō)更是如此。很明顯,你不想把同樣的東西敲上兩遍。

          你經(jīng)常會(huì)想把一個(gè)詞替換成另一個(gè)。如果是全文件替換,你可以使用:s (substitute)命令。如果只是幾個(gè)位置需要被替換,一個(gè)快速辦法是使用 * 命令找出下一個(gè)詞,使用 cw 來(lái)進(jìn)行替換。然后敲n 找到下個(gè)詞,再用 . 重復(fù) cw 命令。

          . 命令重復(fù)上一個(gè)改變。這里的改變是插入、刪除或替換操作。能夠重復(fù)進(jìn)行操作是個(gè)極為強(qiáng)大的機(jī)制。如果好好使用它,那么你大部分的編輯工作可能只不過(guò)是敲幾下 . 的事。小心不要在兩次重復(fù)之間做其他修改,因?yàn)檫@將改變你要重復(fù)的操作。如果確實(shí)需要如此,可以使用 m 命令記住要修改的位置,等重復(fù)操作進(jìn)行完畢之后再回過(guò)頭來(lái)修改它。

          有些函數(shù)名和變量名可能很難敲。你能準(zhǔn)確無(wú)誤地輸入``XpmCreatePixmapFromData''么?Vim的自動(dòng)補(bǔ)齊機(jī)制能給你省不少事。它查看你正在編輯的文件以及#include文件,你可以只敲入``XpmCr'',然后使用CTRL-N 命令讓Vim把它補(bǔ)齊為``XpmCreatePixmapFromData''。這不但節(jié)省了輸入時(shí)間,而且減少了輸入的錯(cuò)誤。

          如果你有同樣的詞組或句子需要輸入多次,還有個(gè)更簡(jiǎn)單的辦法。Vim可以進(jìn)行錄制宏。使用 qa 命令開(kāi)始在'a'寄存器里錄制宏。然后正常地輸入編輯命令,最后用 q 退出錄制狀態(tài)。如果你想重復(fù)所錄制的命令,只需執(zhí)行 @a 命令。Vim總共提供26個(gè)這樣的宏寄存器。

          使用宏錄制功能可以記錄各種操作,不只限于插入操作。如果你想重復(fù)一些東西,不妨一試。

          需要注意的是記錄的命令會(huì)被原封不動(dòng)地重復(fù)執(zhí)行。在進(jìn)行定位時(shí)簡(jiǎn)單的重復(fù)宏操作可能不是你想要的結(jié)果。比如對(duì)于一個(gè)詞這里可能需要左移4個(gè)字符,在下個(gè)地方可能就要左移5個(gè)字符。所以必須定位到合適的位置再重復(fù)進(jìn)行宏操作。

          如果你要重復(fù)的命令很復(fù)雜,把它們一次敲進(jìn)去會(huì)很困難。這時(shí)你可以寫(xiě)一個(gè)腳本或宏。這常被用于建立代碼模板;比如,一個(gè)函數(shù)頭。你想做得多聰明就可以做得多聰明。

          知錯(cuò)就改

          編輯時(shí)經(jīng)常會(huì)出錯(cuò)。無(wú)人能免。關(guān)鍵是快速發(fā)現(xiàn)并進(jìn)行改正。編輯器應(yīng)該提供這方面的支持,不過(guò)你必須告訴它什么是對(duì)什么是錯(cuò)。

          你可能常常會(huì)重復(fù)同樣的錯(cuò)誤,你的手指所做的并非是你要它做的。可以使用縮寫(xiě)(abbreviation)進(jìn)行修正。下面是一些例子:


          * :abbr Lunix Linux
          * :abbr accross across
          * :abbr hte the


          這些詞會(huì)在編輯時(shí)被自動(dòng)改正。

          同樣的機(jī)制也可以用于對(duì)很長(zhǎng)的詞語(yǔ)進(jìn)行縮寫(xiě)。特別適用于輸入那些你覺(jué)得很難敲的詞,它可以避免出錯(cuò)。比如:

          * :abbr pn pinguin
          * :abbr MS Mandrake Software

          但有時(shí)候你想要的正是那些縮寫(xiě),比如想插入``MS''。所以縮寫(xiě)中最好使用那些不會(huì)出現(xiàn)在文中的詞。

          Vim提供了一個(gè)很聰明的高亮機(jī)制,一般用于程序的語(yǔ)法高亮,不過(guò)也可以用來(lái)查錯(cuò)。

          語(yǔ)法高亮?xí)褂妙伾@示注釋。這聽(tīng)上去不是什么特別重要的功能,不過(guò)一旦用起來(lái)就會(huì)發(fā)現(xiàn)這其實(shí)很有用。你能夠快速地發(fā)現(xiàn)那些沒(méi)有高亮卻本應(yīng)作為注釋的文字(可能是因?yàn)橥饲米⑨尫R部梢园l(fā)現(xiàn)一些被錯(cuò)誤當(dāng)成注釋的代碼(可能是因?yàn)橥饲胉`*/'')。這些錯(cuò)誤在黑白方式下是很難被發(fā)現(xiàn)的,浪費(fèi)了不少調(diào)試時(shí)間。

          語(yǔ)法高亮也可以用來(lái)查找不匹配的括號(hào)。一個(gè)未被匹配的``)''會(huì)被亮紅色背景加以標(biāo)識(shí)。你可以使用 % 命令他們是被如何匹配的,然后把``(''或``)''插入到合適的位置。

          另一類(lèi)常犯的錯(cuò)誤也很容易發(fā)現(xiàn),比如把 ``#include <stdio.h>''敲成了``#included <stdio.h>''。在黑白方式下這是很難發(fā)現(xiàn)的,但在語(yǔ)法高亮下則能很快發(fā)現(xiàn)``include''能被高亮而``included''沒(méi)有。

          再看一個(gè)更復(fù)雜的例子:對(duì)于英文文本你可以定義一個(gè)所要使用的詞的長(zhǎng)列表。所有未在表中出現(xiàn)的詞都可能是錯(cuò)誤,并進(jìn)行高亮顯示。可以定義幾個(gè)用于編輯詞表的宏。這正是字處理器的拼寫(xiě)檢查功能。Vim中是靠一些腳本來(lái)實(shí)現(xiàn)的,你也可以對(duì)它進(jìn)行定制:比如,只對(duì)注釋中的文字進(jìn)行拼寫(xiě)檢查。

          第二部分:編輯多個(gè)文件

          文件總是成幫結(jié)伙

          人們很少只編輯一個(gè)文件。一般需要順序或同時(shí)編輯一些相關(guān)的文件。你應(yīng)該利用編輯器使多文件編輯工作更為高效地。

          上面提到的標(biāo)識(shí)(tag)機(jī)制也支持跨文件搜尋。一般做法是為項(xiàng)目的所有文件生成標(biāo)識(shí)文件,然后在項(xiàng)目的所有文件中搜尋函數(shù)、結(jié)構(gòu)、類(lèi)型(typedef)等的定義。這比手工搜尋要快捷的多;我瀏覽一個(gè)程序要做的第一件事便是建立標(biāo)識(shí)文件。

          另一個(gè)強(qiáng)大的功能是使用 :grep 命令對(duì)一組文件進(jìn)行模式搜尋。Vim把搜尋結(jié)果做成一個(gè)列表,然后跳到第一個(gè)結(jié)果。使用 :cn 命令跳到下一個(gè)結(jié)果。如果你想改變一個(gè)函數(shù)調(diào)用的、參數(shù)個(gè)數(shù),那么這個(gè)功能會(huì)很有用。

          頭文件里有很多有用的信息。然而要知道一個(gè)聲明出現(xiàn)在哪個(gè)頭文件中卻需要花不少時(shí)間。Vim能夠理解頭文件,能夠從中找到你需要的東西。把光標(biāo)移動(dòng)到函數(shù)名下,然后敲 [I:Vim就會(huì)顯示出一個(gè)頭文件中該函數(shù)名的所有匹配。
          如果你想得到更詳細(xì)的結(jié)果,可以直接跳到聲明中。一個(gè)類(lèi)似的命令可以用于檢查你所使用的頭文件是否正確。

          你可以把Vim的編輯區(qū)域進(jìn)行分隔,用來(lái)編輯不同的文件。你可以對(duì)兩個(gè)或多個(gè)文件進(jìn)行比較,或者進(jìn)行拷貝/粘貼。有許多命令用于打開(kāi)關(guān)閉窗口,文件間跳轉(zhuǎn),暫時(shí)隱藏文件等等。可以再使用上面提到的三個(gè)基本步驟選擇合適的命令進(jìn)行學(xué)習(xí)。

          多窗口還有更多的用法。預(yù)覽標(biāo)識(shí)(preview-tag)就是個(gè)很好的例子。它打開(kāi)一個(gè)特殊的預(yù)覽窗口,光標(biāo)還保留在你正在編輯的文件中。預(yù)覽窗口中可以是光標(biāo)所指函數(shù)的聲明。如果你移動(dòng)光標(biāo)到另一個(gè)名字下,停留一兩秒,預(yù)覽窗口中就會(huì)顯示那個(gè)名字的定義。名字還可以是頭文件中聲明的結(jié)構(gòu)或函數(shù)。

          讓我們一起來(lái)工作

          編輯器可以編輯文件。e-mail程序可以收發(fā)消息。操作系統(tǒng)可以運(yùn)行程序。每個(gè)程序都有它自己的任務(wù),而且應(yīng)該做好。如果能讓程序一同工作,那么就會(huì)實(shí)現(xiàn)很強(qiáng)大的功能。

          舉個(gè)簡(jiǎn)單的例子:選擇一個(gè)列表中的結(jié)構(gòu)化的文字,并對(duì)它進(jìn)行排序:!sort。這將使用外部命令``sort''來(lái)過(guò)濾文件。容易吧?排序功能是可以添加到編譯器中的。不過(guò)看一下``man sort''就知道它有很多選項(xiàng)。它可能用了一個(gè)極為精巧的排序算法。你還打算把它加到編輯器中么?更何況還有其他不少過(guò)濾程序。編輯器可能會(huì)變得很大。

          Unix精神的一個(gè)體現(xiàn)就是提供獨(dú)立的程序,各自做好自己的任務(wù),然后組合起來(lái)完成更大的任務(wù)。不幸的是,許多編輯器不能很好地和其他程序一起工作,比如,你不能包Netscape的郵件編輯器換成其他編輯器。這樣你只能使用那個(gè)不順手的程序。另一個(gè)趨勢(shì)是在編輯器里提供所有的功能,Emacs就是個(gè)代表(有人說(shuō)Emacs其實(shí)是個(gè)操作系統(tǒng),只是可以用來(lái)編輯文件)。

          Vim盡力和其他程序集成,但這需要經(jīng)過(guò)斗爭(zhēng)。目前Vim已經(jīng)可以作為MS-Developer Studio和Sniff的編輯器。一些e-mail程序(比如Mutt)也支持外部編輯器。和Sun Workshop的集成工作正在進(jìn)行中。總的來(lái)說(shuō)這個(gè)領(lǐng)域還有待提高。將來(lái)我們會(huì)有一個(gè)大于其各部分總和的系統(tǒng)。

          文本結(jié)構(gòu)化

          你可能經(jīng)常會(huì)遇到有一些結(jié)構(gòu)的文本,這些結(jié)構(gòu)可能同于那些現(xiàn)有命令所支持的結(jié)構(gòu)。這樣你不得不利用那些底層的``磚頭''創(chuàng)建你自己的宏和腳本。這里說(shuō)明的就是這類(lèi)更復(fù)雜的東西。

          有個(gè)簡(jiǎn)單的辦法可以加速編輯-編譯-修改這個(gè)循環(huán)。Vim提供 :make 命令,用于進(jìn)行編譯,并且獲取錯(cuò)誤輸出,把你帶到發(fā)生錯(cuò)誤的地方進(jìn)行修正。如果你使用了另一個(gè)編譯器,那么錯(cuò)誤就無(wú)法被Vim獲得。如果不想自己動(dòng)手,可以修改' errorformat'選項(xiàng)。告訴Vim錯(cuò)誤是什么樣子,以及如何從中獲得文件名和行號(hào)。它支持復(fù)雜的gcc錯(cuò)誤信息,所以應(yīng)該也能支持其他編譯器。

          有時(shí)處理一個(gè)新的文件類(lèi)型只需要設(shè)置幾個(gè)選項(xiàng)或?qū)懸恍┖辍1热纾瑸榱嗽趍an手冊(cè)中進(jìn)行跳轉(zhuǎn),你可以寫(xiě)一個(gè)宏獲取光標(biāo)下的詞,清除緩沖區(qū),然后讀入新的man手冊(cè)。這是簡(jiǎn)單而高效的參照(cross-reference)方法。

          使用三個(gè)基本步驟,你可以更有效地處理各種結(jié)構(gòu)化文件。只需要想想你想對(duì)文件采取的操作,然后找到相應(yīng)的命令去用就是了。就這么簡(jiǎn)單,你只要去做就成了。

          第三部分:磨刀

          養(yǎng)成習(xí)慣

          要學(xué)會(huì)開(kāi)車(chē)必須下功夫。這是不是你只騎自行車(chē)的原因么?當(dāng)然不是,你會(huì)發(fā)現(xiàn)你必須花時(shí)間來(lái)獲得所需的技術(shù)。文本編輯也不例外。你需要學(xué)習(xí)新的命令,并使用它直至成為習(xí)慣。

          另一方面,你不應(yīng)該試圖學(xué)習(xí)編輯器提供的每個(gè)命令。這是徹底的浪費(fèi)時(shí)間。大多數(shù)人只需要學(xué)習(xí)10%到20%的命令就足夠工作了。但是每個(gè)人所需要的命令都各不相同。你需要不斷學(xué)習(xí),找出那些可以自動(dòng)完成的重復(fù)操作。如果你只做一次操作,而且以后也不會(huì)再去做,那么就不需要進(jìn)行優(yōu)化。是如果你發(fā)現(xiàn)你在過(guò)去的一小時(shí)中重復(fù)了好幾遍同樣的操作,那么就有必要查看一下手冊(cè),看看能否更快速地完成。或者寫(xiě)一個(gè)宏來(lái)做。如果是是個(gè)不小的任務(wù),比如對(duì)一類(lèi)文本進(jìn)行對(duì)齊,你需要閱讀一下新聞組或看看Internet上是不是有人已經(jīng)解決了同樣的問(wèn)題。

          最根本的步驟是最后的那一個(gè)。你可能能夠找到一個(gè)重復(fù)性的任務(wù),找到一個(gè)不錯(cuò)的作法,可過(guò)了一個(gè)周末就徹底忘了自己是怎么做的了。這不成。你必須重復(fù)你的作法直到爛熟于胸。只有這時(shí)你才真正獲得了你需要的高效。一次不要學(xué)得太多。一次只試一些工作得很好的方法。對(duì)于那些不常用的技巧,你可能只需要把它記下來(lái),留待以后查閱。總之,如果抱著這樣的目標(biāo),你的編輯技能就會(huì)更加有效。

          最后需要指出的是,如果人們忽略了以上幾點(diǎn)會(huì)發(fā)生什么:我仍然可以看到有人盯著屏幕看上半天,用兩個(gè)指頭敲幾下,然后繼續(xù)抬頭看著屏幕,還抱怨自己太累.. 把十個(gè)指頭都用上!這不光更快,還不累。每天抽出一個(gè)小時(shí)練習(xí)一下指法,只要幾星期就足夠了。

          后記

          書(shū)名得益于Stephen R. Covey所著的那本暢銷(xiāo)書(shū)《高效人的七種習(xí)慣》(``The 7 habits of highly effective people'')。

          關(guān)于作者

          Bram Moolenaar是Vim的主要作者。他編寫(xiě)了Vim核心功能,并采納了許多開(kāi)發(fā)者提供的代碼。他的e-mail地址是:Bram@Moolenaar.net

          posted @ 2007-11-06 11:14 jadmin 閱讀(60) | 評(píng)論 (0)編輯 收藏
          僅列出標(biāo)題
          共50頁(yè): First 上一頁(yè) 20 21 22 23 24 25 26 27 28 下一頁(yè) Last 
          主站蜘蛛池模板: 苏州市| 工布江达县| 青川县| 正定县| 乌拉特中旗| 微博| 华池县| 保康县| 屯留县| 周宁县| 宜宾市| 弋阳县| 富顺县| 巴林右旗| 南部县| 元谋县| 苍南县| 广昌县| 郧西县| 眉山市| 偃师市| 武隆县| 庆云县| 蛟河市| 正蓝旗| 吴堡县| 信阳市| 徐州市| 吐鲁番市| 蒙山县| 太仆寺旗| 桂平市| 密云县| 美姑县| 灵丘县| 宁阳县| 榆林市| 固安县| 龙井市| 神农架林区| 西乌珠穆沁旗|