隨筆-31  評論-2  文章-0  trackbacks-0
           

          基本語法

          聲明

          #set ($var=XXX)
          左邊可以是以下的內容:
          • Variable reference
          • String literal
          • Property reference
          • Method reference
          • Number literal #set ($i=1)
          • ArrayList #set ($arr=["yt1","t2"])
          • 算術運算符
          • References 引用的類型

          注釋

          單行:

          ## this is a comment

          多行:

          #* this line
          and this line
          and this line, are comments...*#

          變量 Variables

          以 "$" 開頭,第一個字符必須為字母。character followed by a VTL Identifier. (a .. z or A .. Z).
          變量可以包含的字符有以下內容:
          • alphabetic (a .. z, A .. Z)
          • numeric (0 .. 9)
          • hyphen ("-")
          • underscore ("_")

          Properties

          $Identifier.Identifier
          $user.name
          hashtable user中的的name值.類似:user.get("name")

          h2、Methods

          object user.getName() = $user.getName()

          h2、Formal Reference Notation

          用{}把變量名跟字符串分開。如

          #set ($user="csy"}
          ${user}name

          返回csyname

          $與$!的區別

          當找不到username的時候,$username返回字符串"$username",而$!username返回空字符串""

          雙引號 與 引號

          #set ($var="helo")

          則 test"$var" 返回testhello,test'$var' 返回test'$var'。
          可以通過設置 stringliterals.interpolate=false改變默認處理方式

          條件語句

          #if( $foo )
          <strong>Velocity!</strong>
          #end
          #if($foo)
          #elseif()
          #else
          #end

          當$foo為null或為Boolean對象的false值執行.

          邏輯運算符:

          == && || !

          循環語句

          #foreach($var in $arrays ) // 集合包含下面三種Vector, a Hashtable or an Array
          #end

          #foreach( $product in $allProducts )
          <li>$product</li>
          #end

          #foreach( $key in $allProducts.keySet() )
          <li>Key: $key -> Value: $allProducts.get($key)</li>
          #end

          #foreach( $customer in $customerList )
          <tr><td>$velocityCount</td><td>$customer.Name</td></tr>
          #end

          velocityCount變量在配置文件中定義

          1. Default name of the loop counter
          2. variable reference.
            directive.foreach.counter.name = velocityCount
          3. Default starting value of the loop
          4. counter variable reference.
            directive.foreach.counter.initial.value = 1

          包含文件

          #include( "one.gif","two.txt","three.htm" )

          Parse導入腳本

          #parse("me.vm" )

          #stop 停止執行并返回

          定義宏

          Velocimacros, 相當于函數支持包含功能:

          #macro( d )
          <tr><td></td></tr>
          #end
          調用
          #d()

          帶參數的宏

          #macro( tablerows $color $somelist )
          #foreach( $something in $somelist )
          <tr><td bgcolor=$color>$something</td></tr>
          #end
          #end

          Range Operator

          #foreach( $foo in [1..5] )

          與struts2的整合

          模板裝載位置(按順序依次搜索)

          • Web application 應用程序路徑,會覆蓋掉類路徑下的同名配置文件;
          • Class path 類路徑,一般為缺省模板的配置,公共模板位置;

          數據來源(按順序依次搜索)

          • The value stack
          • The action context
          • Built-in variables

          Struts2-Velocity集成的一些隱含變量

          • stack - ValueStack自身。調用方式:${stack.findString('ognl expr')}
          • action - 最新操作的action
          • reponse
          • request
          • session
          • applicaion - 獲得servlet的環境
          • base - 請求環境的路徑

          Velocity Result 輸出模板

          模擬jsp執行環境,使用velocity的模板直接顯示到servelet的輸出流。

          location - 模板位置,沒有其它參數時的缺省配置。
          parse - 默認true ,false將不解析Ognl expressions.

          配置范例:

          <result name="success" type="velocity">
          <param name="location">foo.vm</param>
          </result>

          等價于以下的配置方式:

          <result name="success" type="velocity">
          foo.vm
          </result>

          Velocity語法

          http://blog.csdn.net/alexwan/archive/2007/10/29/1853285.aspx

          Struts 與 Velocity 的集成

          http://www.ibm.com/developerworks/cn/java/j-sr1.html

          posted @ 2009-07-02 09:38 xiaoxinchen 閱讀(164) | 評論 (0)編輯 收藏
          cdn

          介紹

          CDN 的全稱是Content Delivery Network,即內容分發網絡。其目的是通過在現有的Internet中增加一層新的網絡架構, 將網站的內容發布到最接近用戶的網絡"邊緣", 使用戶可以就近取得所需的內容, 解決Internet網絡擁擠的狀況, 提高用戶訪問網站的響應速度。從技術上全面解決由于網絡帶寬小, 用戶訪問量大, 網點分布不均等原因所造成的用戶訪問網站響應速度慢的問題。

          CDN互聯網內容發布網絡(Content Delivery Network)

          CDN 技術是近年來在美國首先興起并迅速發展起來的一種解決互聯網性能不佳問題的有效手段。其基本思路就是盡可能避開互聯網上有可能影響數據傳輸速度和穩定性的 瓶頸和環節,使內容傳輸的更快、更穩。通過在網絡各處放置節點服務器所構成的在現有的互聯網基礎之上的一層智能虛擬網絡,cdn系統能夠實時地根據網絡流 量和各節點的連接、負載狀況以及到用戶的距離和響應時間等綜合信息將用戶的請求重新導向離用戶最近的服務節點上。

          實際上,內容分發 布網絡(CDN)是一種新型的網絡構建方式,它是為能在傳統的IP網發布寬帶豐富媒體而特別優化的網絡覆蓋層;而從廣義的角度,CDN代表了一種基于質量 與秩序的網絡服務模式。簡單地說,內容發布網(CDN)是一個經策略性部署的整體系統,包括分布式存儲、負載均衡、網絡請求的重定向和內容管理4個要件, 而內容管理和全局的網絡流量管理(Traffic Management)是CDN的核心所在。通過用戶就近性和服務器負載的判斷,CDN確保內容以一種極為高效的方式為用戶的請求提供服務。總的來說,內 容服務基于緩存服務器,也稱作代理緩存(Surrogate),它位于網絡的邊緣,距用戶僅有"一跳"(Single Hop)之遙。同時,代理緩存是內容提供商源服務器(通常位于CDN服務提供商的數據中心)的一個透明鏡像。這樣的架構使得CDN服務提供商能夠代表他們 客戶,即內容供應商,向最終用戶提供盡可能好的體驗,而這些用戶是不能容忍請求響應時間有任何延遲的。據統計,采用CDN技術,能處理整個網站頁面的 70%~95%的內容訪問量,減輕服務器的壓力,提升了網站的性能和可擴展性。

          與目前現有的內容發布模式相比較,CDN強調了網絡 在內容發布中的重要性。通過引入主動的內容管理層的和全局負載均衡,CDN從根本上區別于傳統的內容發布模式。在傳統的內容發布模式中,內容的發布由 ICP的應用服務器完成,而網絡只表現為一個透明的數據傳輸通道,這種透明性表現在網絡的質量保證僅僅停留在數據包的層面,而不能根據內容對象的不同區分 服務質量。此外,由于IP網的"盡力而為"的特性使得其質量保證是依靠在用戶和應用服務器之間端到端地提供充分的、遠大于實際所需的帶寬通量來實現的。在 這樣的內容發布模式下,不僅大量寶貴的骨干帶寬被占用,同時ICP的應用服務器的負載也變得非常重,而且不可預計。當發生一些熱點事件和出現浪涌流量時, 會產生局部熱點效應,從而使應用服務器過載退出服務。這種基于中心的應用服務器的內容發布模式的另外一個缺陷在于個性化服務的缺失和對寬帶服務價值鏈的扭 曲,內容提供商承擔了他們不該干也干不好的內容發布服務。

          縱觀整個寬帶服務的價值鏈,內容提供商和用戶位于整個價值鏈的兩端,中間 依靠網絡服務提供商將其串接起來。隨著互聯網工業的成熟和商業模式的變革,在這條價值鏈上的角色越來越多也越來越細分。比如內容/應用的運營商、托管服務 提供商、骨干網絡服務提供商、接入服務提供商等等。在這一條價值鏈上的每一個角色都要分工合作、各司其職才能為客戶提供良好的服務,從而帶來多贏的局面。 從內容與網絡的結合模式上看,內容的發布已經走過了ICP的內容(應用)服務器和IDC這兩個階段。IDC的熱潮也催生了托管服務提供商這一角色。但 是,IDC并不能解決內容的有效發布問題。內容位于網絡的中心并不能解決骨干帶寬的占用和建立IP網絡上的流量秩序。因此將內容推到網絡的邊緣,為用戶提 供就近性的邊緣服務,從而保證服務的質量和整個網絡上的訪問秩序就成了一種顯而易見的選擇。而這就是內容發布網(CDN)服務模式。CDN的建立解決了困 擾內容運營商的內容"集中與分散"的兩難選擇,無疑對于構建良好的互聯網價值鏈是有價值的,也是不可或缺的最優網站加速服務。

          目前,國內訪問量較高的大型網站如新浪、網易等,均使用CDN網絡加速技術,雖然網站的訪問巨大,但無論在什么地方訪問都會感覺速度很快。而一般的網站如果服務器在網通,電信用戶訪問很慢,如果服務器在電信,網通用戶訪問又很慢。

          它 采取了分布式網絡緩存結構(即國際上流行的web cache技術),通過在現有的Internet中增加一層新的網絡架構,將網站的內容發布到最接近用戶的cache服務器內,通過DNS負載均衡的技 術,判斷用戶來源就近訪問cache服務器取得所需的內容,解決Internet網絡擁塞狀況,提高用戶訪問網站的響應速度,如同提供了多個分布在各地的 加速器,以達到快速、可冗余的為多個網站加速的目的。

          CDN的特點

          1. 本地Cache加速 提高了企業站點(尤其含有大量圖片和靜態頁面站點)的訪問速度,并大大提高以上性質站點的穩定性
          2. 鏡像服務 消除了不同運營商之間互聯的瓶頸造成的影響,實現了跨運營商的網絡加速,保證不同網絡中的用戶都能得到良好的訪問質量。
          3. 遠程加速 遠程訪問用戶根據DNS負載均衡技術 智能自動選擇Cache服務器,選擇最快的Cache服務器,加快遠程訪問的速度
          4. 帶寬優化 自動生成服務器的遠程Mirror(鏡像)cache服務器,遠程用戶訪問時從cache服務器上讀取數據,減少遠程訪問的帶寬、分擔網絡流量、減輕原站點WEB服務器負載等功能。
          5. 集群抗攻擊 廣泛分布的CDN節點加上節點之間的智能冗于機制,可以有效地預防黑客入侵以及降低各種D.D.o.S攻擊對網站的影響,同時保證較好的服務質量 。

          關鍵技術

          1. 內容發布:它借助于建立索引、緩存、流分裂、組播(Multicast)等技術,將內容發布或投遞到距離用戶最近的遠程服務點(POP)處;
          2. 內容路由:它是整體性的網絡負載均衡技術,通過內容路由器中的重定向(DNS)機制,在多個遠程POP上均衡用戶的請求,以使用戶請求得到最近內容源的響應;
          3. 內容交換:它根據內容的可用性、服務器的可用性以及用戶的背景,在POP的緩存服務器上,利用應用層交換、流分裂、重定向(ICP、WCCP)等技術,智能地平衡負載流量;
          4. 性能管理:它通過內部和外部監控系統,獲取網絡部件的狀況信息,測量內容發布的端到端性能(如包丟失、延時、平均帶寬、啟動時間、幀速率等),保證網絡處于最佳的運行狀態。

          P4P與傳統CDN、P2P的對比

          7 月30日消息:德國一個名為iPoque的研究機構在2007年研究了一百多萬網民將近 3TB的匿名數據流量,調查地區包括澳大利亞、東歐、德國、中東和南歐地區。調查發現,目前網絡帶寬“消費大戶”是P2P文件共享,在中東占據了49%, 東歐地區占據了84%。從全球來看,晚上時段的網絡帶寬有95%被P2P占據。據國內權威部門統計,當前P2P流量已經占整個互聯網流量的約70%,并且 正在以每年350%的速度增長。P2P流量消耗了巨大的網絡帶寬,尤其是國際帶寬,使網絡基礎設施不堪重負,運營商苦不堪言。

          問題 的癥結不在于P2P,而在于交換的機制。P2P過于強調“對等”,每個節點之間的交換完全是無序的。一個北京的用戶,既可能和廣州的用戶進行文件片段的交 換,也可能和遠在美國的某用戶進行交換。顯然,無序的交換導致了無謂的跨地區甚至是跨國的 “流量旅行”,這耗費了寶貴的國內和國際帶寬資源,代價巨大。

          如 果正好用戶都在同一個地區,那么,本地化的交換的成本就會大大降低。這也正是P4P的簡單原理——讓P2P也玩“同城”。 P4P全稱是“Proactive network Provider Participation for P2P(電信運營商主動參與P2P網絡)”。與P2P隨機挑選Peer(對等機)不同,P4P協議可以協調網絡拓撲數據,能夠有效選擇節點,從而提高網絡 路由效率。仍以上述例子來說,北京的用戶就可以優先和北京同城的用戶來實現文件片段的交換,再擴展至較遠的地區,有十分的必要時,才會出國進行文件片段交 換。當然,P4P的運行機制,要遠遠超過“同城交換”的概念,它還會根據用戶的上行、下載帶寬進行綜合判斷,以進行最有效選擇,最大化整體交換的效率。

          舉 幾個例子可以說明CDN的普遍作用。例如2008年,北京奧運會之前,關于門票網絡出售,很多國內的朋友都去登陸,而大家的登錄的時刻幾乎千篇一律,導致 中國政府的網站服務器支撐不了這么大的請求,誰都進去不了,都被堵死在門外。這中現象在國內許多網站都出現過,比如高考時期,學生上網填申請,大家都說是 自己網絡原因,其實不然,這都跟被請求的服務器有關,來自四面八方的請求去請求他一個網站,他自然接受不了這么大的帶寬,給人一種印象,就是互聯網太慢, 落后了。這樣的例子很多,我們就不紛紛介紹了。不過互聯網,網聚全球人的智慧。解決方法很多,美國作為世界的互聯網中心,提供了CDN技術,內容網絡分 發。美國很多軍方工程都是采用該技術。我國國內的香港海洋科技集團的GTONE產品,專業為我國國內大型公司提供海外服務,在全球都有很廣的資源。國內很 多很有實力的公司都和他們合作了。

          新建文件

          posted @ 2009-07-02 09:37 xiaoxinchen 閱讀(125) | 評論 (0)編輯 收藏
          1. 基本命令
          1. 常見文件操作
                  建立目錄:mkdir 目錄名
          刪除空目錄:rmdir 目錄名
          無條件刪除子目錄: rm -rf 目錄名
          改變當前目錄:cd 目錄名 (進入用戶home目錄:cd ~;進入上一級目錄:cd -)
          查看自己所在目錄:pwd
          查看當前目錄大小:du
          顯示目錄文件列表:ls -l (-a:增加顯示隱含目錄)
          其中:藍:目錄;綠:可執行文件;紅:壓縮文件;淺藍:鏈接文件;灰:其他文件;紅底白字:錯誤的鏈接文件
          瀏覽文件:more 文件名.txt;less 文件名.txt
          復制文件: cp 源文件 目標文件 (-r:包含目錄)
          查找文件:(1)find (2)locate 命令名
          鏈接:(1)建立hard鏈接:ln 來源文件 鏈接文件(-d:創建目錄鏈接);(2)建立符號鏈接:ln -s 來源文件 鏈接文件
          文本編碼轉換工具iconv:iconv -f gb2312 -t utf-8 -o new.txt old.txt
          輸入/輸出格式規范
          -f, --from-code=NAME 原始文本編碼,
          -t,--to-code=NAME 輸出編碼,信息
          -l, --list 列出所有已知編碼字符集

          輸出控制:

          -c 忽略輸出中的無效字符
          -o, --output=FILE 輸出文件
          -s, --silent suppress warnings
          # 進程管理
                  列出當前進程ID:ps -auxw
          終止進程:(1)終止單一進程:kill 進程ID號
          終止該程序所有進程:killall 程序名
          終止X-Window程序:xkill
          查看資源占用情況:(1)top (2)free (3)dmesg
          查看環境變量值:env
          重啟:(1)reboot (2)Ctrl Alt Del (3)init 6
          關機:(1)shutdown -h now (2)halt (3)init 0
          # 網絡管理
                  顯示網絡接口參數:ifconfig
          聯機狀況:ping xxx.xxx.xxx.xxx
          顯示網絡狀況:netstat ,其中:options:-a==所有sockets;-l==包含網絡設備;-n==數字IP;-o==其他信息;-r==路由表;-t==只列TCP sockets;-u==只列UDP sockets;-w==只列raw sockets;
          -x==只列Unix Domain sockets

          # 權限設定
                  (1)chmod -a|u|g|o |-|=r|w|x 文件/目錄名
          其中:a--所有用戶(all);u--本用戶(user);g--用戶組(group);o--其他用戶(other users)
          --增加權限;---刪除權限;=--設置權限
          文件:r--只讀權限(read);w--寫權限(write);x--執行權限(execute)
          目錄:r--允許列目錄下文件和子目錄;w--允許生成和刪除目錄下文件;x--允許訪問該目錄
          (2)chmod xxx 文件/目錄名
          其中:execute=1;write=2;read=4
          x取值:0--沒有任何權限(常用);1--只能執行(不常見);2--只能寫(不常見);3--只能寫和執行(不常見);4--只讀(常見);5--只讀和執行(常見);6--讀和寫(常見);7--讀.寫和執行
          # vim 常見命令
                  進入后為命令模式:(1)插入i;(2)打開0;(3)修改c;(4)取代r;(5)替換s
          經(1)后進入全屏幕編輯模式。
          命令模式-->編輯模式(a/i);編輯模式-->命令模式(Esc);命令模式-->末行模式(:)。
          :w/w newfile保存
          :q/q!退出iv;:wq保存退出
          http://vimcdoc.sourceforge.net/doc/help.html

          #ln命令

          ln 命令

          用途 : 鏈接文件。

          語法

          1>將某個文件鏈接到一個文件上 ln [ -f | -n] [ -s ] SourceFile [ TargetFile ]

          2>將一個或多個文件鏈接到一個目錄上 ln [ -f | -n] [ -s ] SourceFile ... TargetDirectory

          描述 ln 命令將在 SourceFile 參數中指定的文件鏈接到在 TargetFile 參數中指定的文件,或將其鏈接到在 TargetDirectory 參數中指定的另一個目錄中的文件。

          在缺省情況下,ln 命令會創建硬鏈接。如果需要使用 ln 命令來創建符號鏈接,請指明 -s 標志。

          符號鏈接是指向文件的一個間接指針;它的目錄項中包含了它所鏈接的文件名。符號鏈接可能會跨越文件系統,可能指向目錄。

          如果正在將某個文件鏈接到新的名字,那么只能列出一個文件。如果鏈接到一個目錄,那么可以列出多個文件。

          TargetFile 參數是可選的。

          如果不指定目標文件,ln 命令會在當前的目錄中創建一個新的文件。新的文件繼承了指定在 SourceFile 參數中的文件名。

          注意: 如果不使用 -s 標志,就不能在文件系統之間鏈接文件。 如果 TargetDirectory 已經是鏈接到目錄上的一個符號鏈接,那么 ln 命令將現有的目標視為文件。 這意味著,類似于 ln -fs somepath/lname symdir 的命令不會遵循現有的 symdir 符號鏈接,作為代替,它會創建一個從 somepath/lname 到 symdir 的新的符號鏈接。

          參數

          -f 促使 ln 命令替換掉任何已經存在的目的路徑。如果目的路徑已經存在,而沒有指定 -f 標志,ln 命令不會創建新的鏈接,而是向標準錯誤寫一條診斷消息并繼續鏈接剩下的 SourceFiles。

          -n 指定,如果鏈接是一個現有的文件,那么不要覆蓋文件的內容。 -f 標志重設了這個標志。這是缺省的行為。

          -s 促使 ln 命令創建符號鏈接。符號鏈接中包含了它所鏈接的文件的名字。當對鏈接執行打開操作的時候,會使用到引用文件。對符號鏈接的 stat 調用會返回鏈接的目標文件;必須完成lstat 調用來獲取鏈接的信息。可以使用 readlink 調用來讀取符號鏈接的內容。符號鏈接可能跨越文件系統,指向目錄。

          注意:當為 -s 標志指定 SourceFile 參數的時候,必須使用絕對路徑。如果沒有指明絕對路徑,那么當 SourceFile 和 TargetFile 參數位于不同的目錄中的時候,可能會發生意外的結果。在創建符號鏈接之前,不需要存在源文件。

          退出狀態 此命令返回以下的退出值:

          0 所有指定的文件都成功鏈接上了。

          0 出現一次錯誤。

          示例

          1>為了創建到一個文件的另一個鏈接(別名),請輸入:

          ln -f file1 file2 這會將 file1 鏈接到新的名稱, file2。如果 file2 不存在,那么會創建該文件名。如果 file2 已經存在了,那么這個文件會被替換為指向 file1的一個鏈接。然后 file1 和 file2 文件名會指向同一個文件。對其中任何一個的更改都會出現在另一個中。如果一個文件名被 rm 命令刪除,那么該文件并沒有完全被刪除,因為它仍然以其它的名字存在。

          2>為了將文件鏈接為另一個目錄中的相同名字,請輸入:

          ln index dir1 這會將 index 鏈接到新的名稱,dir1/index。

          注意:在示例 1 中的 file2 是一個文件的名稱;在示例 2 中的 dir1 是一個已經存在的目錄。

          3>為了將幾個文件鏈接為另一個目錄中的名稱,請輸入:

          ln file2 dir2/file3 /home/dir1 這會將 file2 鏈接到新的名稱 /home/dir1/file2;將 dir2/file3 鏈接到新的名稱 /home/dir1/file3。

          4>如果想要在 ln 命令中使用模式匹配字符,請輸入:

          ln dir1/* . 這會將 dir1 目錄中的所有文件鏈接到當前目錄中, . (點),給他們在 dir1 目錄中同樣的名稱。

          注意: 必須在星號和句點之間輸入一個空格。

          5>為了創建一個符號鏈接,輸入:

          ln -s /tmp/test test

          這會在當前的目錄中創建符號鏈接 test。 test 文件指向 /tmp/test 文件。如果 /tmp/test 文件已經存在了,那么 cat test 命令可以列出其內容。

          6>如果想要在不指明 TargetFile 參數的情況下得到相同的結果,請輸入:

          ln -s /tmp/test

          文件

          /usr/bin/ln 包含了 ln 命令。

          1. 常見配置文件
          posted @ 2009-07-02 09:37 xiaoxinchen 閱讀(129) | 評論 (0)編輯 收藏

          介紹

          入門

          安裝

          不用安裝,直接解壓即可。如果進行JEE開發,可以用eclipse-jee-ganymede-SR2文件,而PHP的話可以直接用PDT。Python可以用基于Apanta的PyDev。

          基本操作

          選項:Windows -> Preference。
          安裝新特性/插件:Help -> SoftwareUpdates

          常用快捷鍵

          快捷鍵的設置和修改在Windows -> Preference ->General -> Keys;

          我最常用的:
          Ctrl+Space 代碼助手完成一些代碼的插入(但一般和輸入法有沖突,可以Alt+/來代替,在keys里找到command 為Content Assist的,把其Binding改為Alt+/) 這個是我最喜歡的功能,你可以把變量命名的很長,下次引用時只要打首個字母,再打Alt+/,就能寫出變量。
          Ctrl+Q 定位到最后編輯的地方
          Ctrl+Shift+R 全局 打開資源
          Ctrl+E 快速顯示當前Editer的下拉列表(如果當前頁面沒有顯示的用黑體表示)
          Java編輯器 組織導入 Ctrl+Shift+O
          Java編輯器 添加導入 Ctrl+Shift+M
          Alt+← 前一個編輯的頁面
          Alt+→ 下一個編輯的頁面(當然是針對上面那條來說了)
          Ctrl+1 快速修復
          Ctrl+/ 注釋當前行,再按則取消注釋
          Ctrl+D: 刪除當前行
          Java編輯器 格式化 Ctrl+Shift+F
          Alt+↓ 當前行和下面一行交互位置(特別實用,可以省去先剪切,再粘貼了)
          Alt+↑ 當前行和上面一行交互位置(同上)
          Ctrl+L 定位在某行 (對于程序超過100的人就有福音了)
          Alt+Shift+R 重命名 (是我自己最愛用的一個了,尤其是變量和類的Rename,比手工方法能節省很多勞動力)
          Alt+Shift+Z 使用try/catch塊來包圍

          下面是網上轉過來
          Eclipse快捷鍵大全(轉載)
          Ctrl+1 快速修復(最經典的快捷鍵,就不用多說了)
          Ctrl+D: 刪除當前行
          Ctrl+Alt+↓ 復制當前行到下一行(復制增加)
          Ctrl+Alt+↑ 復制當前行到上一行(復制增加)
          Alt+↓ 當前行和下面一行交互位置(特別實用,可以省去先剪切,再粘貼了)
          Alt+↑ 當前行和上面一行交互位置(同上)
          Alt+← 前一個編輯的頁面
          Alt+→ 下一個編輯的頁面(當然是針對上面那條來說了)
          Alt+Enter 顯示當前選擇資源(工程,or 文件 or文件)的屬性
          Shift+Enter 在當前行的下一行插入空行(這時鼠標可以在當前行的任一位置,不一定是最后)
          Shift+Ctrl+Enter 在當前行插入空行(原理同上條)
          Ctrl+Q 定位到最后編輯的地方
          Ctrl+L 定位在某行 (對于程序超過100的人就有福音了)
          Ctrl+M 最大化當前的Edit或View (再按則反之)
          Ctrl+/ 注釋當前行,再按則取消注釋
          Ctrl+O 快速顯示 OutLine
          Ctrl+T 快速顯示當前類的繼承結構
          Ctrl+W 關閉當前Editer
          Ctrl+K 參照選中的Word快速定位到下一個
          Ctrl+E 快速顯示當前Editer的下拉列表(如果當前頁面沒有顯示的用黑體表示)
          Ctrl+/(小鍵盤) 折疊當前類中的所有代碼
          Ctrl+×(小鍵盤) 展開當前類中的所有代碼
          Ctrl+Space 代碼助手完成一些代碼的插入(但一般和輸入法有沖突,可以修改輸入法的熱鍵,也可以暫用Alt+/來代替)
          Ctrl+Shift+E 顯示管理當前打開的所有的View的管理器(可以選擇關閉,激活等操作)
          Ctrl+J 正向增量查找(按下Ctrl+J后,你所輸入的每個字母編輯器都提供快速匹配定位到某個單詞,如果沒有,則在stutes line中顯示沒有找到了,查一個單詞時,特別實用,這個功能Idea兩年前就有了)
          Ctrl+Shift+J 反向增量查找(和上條相同,只不過是從后往前查)
          Ctrl+Shift+F4 關閉所有打開的Editer
          Ctrl+Shift+X 把當前選中的文本全部變味小寫
          Ctrl+Shift+Y 把當前選中的文本全部變為小寫
          Ctrl+Shift+F 格式化當前代碼
          Ctrl+Shift+P 定位到對于的匹配符(譬如{}) (從前面定位后面時,光標要在匹配符里面,后面到前面,則反之)

          下面的快捷鍵是重構里面常用的,本人就自己喜歡且常用的整理一下(注:一般重構的快捷鍵都是Alt+Shift開頭的了)
          Alt+Shift+R 重命名 (是我自己最愛用的一個了,尤其是變量和類的Rename,比手工方法能節省很多勞動力)
          Alt+Shift+M 抽取方法 (這是重構里面最常用的方法之一了,尤其是對一大堆泥團代碼有用)
          Alt+Shift+C 修改函數結構(比較實用,有N個函數調用了這個方法,修改一次搞定)
          Alt+Shift+L 抽取本地變量( 可以直接把一些魔法數字和字符串抽取成一個變量,尤其是多處調用的時候)
          Alt+Shift+F 把Class中的local變量變為field變量 (比較實用的功能)
          Alt+Shift+I 合并變量(可能這樣說有點不妥Inline)
          Alt+Shift+V 移動函數和變量(不怎么常用)
          Alt+Shift+Z 重構的后悔藥(Undo)

          編輯
          作用域 功能 快捷鍵
          全局 查找并替換 Ctrl+F
          文本編輯器 查找上一個 Ctrl+Shift+K
          文本編輯器 查找下一個 Ctrl+K
          全局 撤銷 Ctrl+Z
          全局 復制 Ctrl+C
          全局 恢復上一個選擇 Alt+Shift+↓
          全局 剪切 Ctrl+X
          全局 快速修正 Ctrl1+1
          全局 內容輔助 Alt+/
          全局 全部選中 Ctrl+A
          全局 刪除 Delete
          全局 上下文信息 Alt+?
          Alt+Shift+?
          Ctrl+Shift+Space
          Java編輯器 顯示工具提示描述 F2
          Java編輯器 選擇封裝元素 Alt+Shift+↑
          Java編輯器 選擇上一個元素 Alt+Shift+←
          Java編輯器 選擇下一個元素 Alt+Shift+→
          文本編輯器 增量查找 Ctrl+J
          文本編輯器 增量逆向查找 Ctrl+Shift+J
          全局 粘貼 Ctrl+V
          全局 重做 Ctrl+Y

          查看
          作用域 功能 快捷鍵
          全局 放大 Ctrl+=
          全局 縮小 Ctrl+-

          窗口
          作用域 功能 快捷鍵
          全局 激活編輯器 F12
          全局 切換編輯器 Ctrl+Shift+W
          全局 上一個編輯器 Ctrl+Shift+F6
          全局 上一個視圖 Ctrl+Shift+F7
          全局 上一個透視圖 Ctrl+Shift+F8
          全局 下一個編輯器 Ctrl+F6
          全局 下一個視圖 Ctrl+F7
          全局 下一個透視圖 Ctrl+F8
          文本編輯器 顯示標尺上下文菜單 Ctrl+W
          全局 顯示視圖菜單 Ctrl+F10
          全局 顯示系統菜單 Alt+-

          導航
          作用域 功能 快捷鍵
          Java編輯器 打開結構 Ctrl+F3
          全局 打開類型 Ctrl+Shift+T
          全局 打開類型層次結構 F4
          全局 打開聲明 F3
          全局 打開外部javadoc Shift+F2
          全局 打開資源 Ctrl+Shift+R
          全局 后退歷史記錄 Alt+←
          全局 前進歷史記錄 Alt+→
          全局 上一個 Ctrl+,
          全局 下一個 Ctrl+.
          Java編輯器 顯示大綱 Ctrl+O
          全局 在層次結構中打開類型 Ctrl+Shift+H
          全局 轉至匹配的括號 Ctrl+Shift+P
          全局 轉至上一個編輯位置 Ctrl+Q
          Java編輯器 轉至上一個成員 Ctrl+Shift+↑
          Java編輯器 轉至下一個成員 Ctrl+Shift+↓
          文本編輯器 轉至行 Ctrl+L

          搜索
          作用域 功能 快捷鍵
          全局 出現在文件中 Ctrl+Shift+U
          全局 打開搜索對話框 Ctrl+H
          全局 工作區中的聲明 Ctrl+G
          全局 工作區中的引用 Ctrl+Shift+G

          文本編輯
          作用域 功能 快捷鍵
          文本編輯器 改寫切換 Insert
          文本編輯器 上滾行 Ctrl+↑
          文本編輯器 下滾行 Ctrl+↓

          文件
          作用域 功能 快捷鍵
          全局 保存 Ctrl+X
          Ctrl+S
          全局 打印 Ctrl+P
          全局 關閉 Ctrl+F4
          全局 全部保存 Ctrl+Shift+S
          全局 全部關閉 Ctrl+Shift+F4
          全局 屬性 Alt+Enter
          全局 新建 Ctrl+N

          項目
          作用域 功能 快捷鍵
          全局 全部構建 Ctrl+B

          源代碼
          作用域 功能 快捷鍵
          Java編輯器 格式化 Ctrl+Shift+F
          Java編輯器 取消注釋 Ctrl+\
          Java編輯器 注釋 Ctrl+/
          Java編輯器 添加導入 Ctrl+Shift+M
          Java編輯器 組織導入 Ctrl+Shift+O
          Java編輯器 使用try/catch塊來包圍 未設置,太常用了,所以在這里列出,建議自己設置。
          也可以使用Ctrl+1自動修正。

          運行
          作用域 功能 快捷鍵
          全局 單步返回 F7
          全局 單步跳過 F6
          全局 單步跳入 F5
          全局 單步跳入選擇 Ctrl+F5
          全局 調試上次啟動 F11
          全局 繼續 F8
          全局 使用過濾器單步執行 Shift+F5
          全局 添加/去除斷點 Ctrl+Shift+B
          全局 顯示 Ctrl+D
          全局 運行上次啟動 Ctrl+F11
          全局 運行至行 Ctrl+R
          全局 執行 Ctrl+U

          重構
          作用域 功能 快捷鍵
          全局 撤銷重構 Alt+Shift+Z
          全局 抽取方法 Alt+Shift+M
          全局 抽取局部變量 Alt+Shift+L
          全局 內聯 Alt+Shift+I
          全局 移動 Alt+Shift+V
          全局 重命名 Alt+Shift+R
          全局 重做 Alt+Shift+Y

          檢出項目

          首先安裝SVN插件(subversive或者subclipse),然后新建Project,從SVN檢出項目。需要特別注意的是,要在general / workspace選項中正確設置字符編碼,否則可能會出現編譯錯誤。

          用Maven構建項目

          安裝IAM之后,在項目的context菜單中選“Maven 2 / Use Maven Dependency Management”,然后就可以管理依賴。

          查看數據庫

          打開 Database Perspective 即可。注意要先選擇驅動程序,即mysql的java connector的jar,然后才是配置各個連接的jdbc地址。

          關于插件

          插件安裝方法(zz)

          英文教程:http://www.venukb.com/2006/08/20/install-eclipse-plugins-the-easy-way/

          有關插件安裝問題,四種常用的方法在此特別注明:

          #“幫助”->“軟件更新”->“查找并安裝”->“搜索要安裝的新功能部件”->“新建遠程站點”(此種方式用于在線更新)
          #“幫助”->“軟件更新”->“查找并安裝”->“搜索要安裝的新功能部件”->“新建本地站點”(如果插件已經下載到了本地,請不要用第一種方法)
          1. 直接拷貝plugins和features兩個目錄下的內容置于$Eclipse_Home$/對應的plugins和features下面
          2. 用link外鏈接與外部插件關聯

          最菜的,一般用第一種方法,而大部分生手一般選擇第二或者第三種方法,用得習慣的一般選擇最后一種方式。此四類方法優劣勢對比如下:
          前三種方法都會將插件文件拷貝至相$Eclipse_Home$/對應的plugins和features目錄下,從本質上看,沒多大區別,并且插件只能 安裝和禁用,不能卸載(當然,如果你對插件對應的目錄和文件都很熟悉的話,可以通過直接刪除拷進去的文件來達到卸載插件的目的),但方法一和方法二在安裝 插件的時候很容易出錯或者是產生沖突,特別是當你用了Myeclipse插件、中文包的同時,又想安裝HibernateSynchronizer、 Jode Compiler(Class反編譯工具)、Visual Editor等插件時,及有可能導致Myeclipse插件和中文包失效。

          所以,如果插件已經下載到了本地,請直接拷貝至$Eclipse_Home$/對應的plugins和features目錄下,也就是用方法三,這樣能避免沖突。

          方 法四是將所有的插件用一個外部目錄存放起來,假如是D:\plug-in,將上面所示的插件目錄文件全部拷貝到該目錄下,比如Tomcat插件,此時的文 件路徑就是D:\plug-in\tomcat_plug\eclipse\plugins \com.sysdeo.eclipse.tomcat_3.1.0.beta(請注意,方法四一定要嚴格這樣的目錄路徑放置文件)。然后 在$Eclipse_Home$下新建一個links目錄,并在links目錄下建立關聯文件,假如是tomcat.link,在建立的關聯文件中加入如 下語句:

          path=D:/plug-in/tomcat_plug

          還可以寫成相對路徑的形式。剩下的事情,不用我說你肯定都知道了,就是重啟Eclipse,在Dos窗口下進入Eclipse安 裝目錄,鍵入命令eclipse -clean,回車,或者進入$Eclipse_Home$/configuration目錄,刪除org.eclipse.update后再重新啟動 Eclipse。

          QA相關插件

          參考:http://www.ibm.com/developerworks/cn/java/j-ap01117/

          CheckStyle http://eclipse-cs.sourceforge.net/update/
          Coverlipse http://coverlipse.sf.net/update
          PMD http://pmd.sourceforge.net/eclipse/
          JDepend http://andrei.gmxhome.de/eclipse/
          Metrics http://metrics.sourceforge.net/update
          FindBugs http://findbugs.cs.umd.edu/eclipse

          參考資源

          http://www.ibm.com/developerworks/cn/eclipse/resources.html
          http://www.eclipseplugincentral.com/

          posted @ 2009-07-02 09:36 xiaoxinchen 閱讀(279) | 評論 (0)編輯 收藏

          Web標準

          我理解的Web標準
          web標準就是瀏覽器的開發廠商和界面開發人員共同遵循的標準。由萬維網聯盟W3C(World Wide Web Consortium)組織制定。
          Web標準化無異于工業標準化,就好像改錐和螺絲一樣,他們都遵循同樣的標準,易用,有效,甚至能贏得戰爭(注1)。
          遵循Web標準的好處
          • 高效率。開發人員可以更容易地理解彼此的編碼,web開發的團隊協作將得到簡化。
          • 易用性。大家都遵循標準,未來也許就不存在跨瀏覽器問題,也可以跨平臺(比如移動電話),另外,標準也可以使殘疾人士更容易地使用web。
          • 利于訪問。更易被搜索引擎訪問,也更易被準確地索引。

          注1:德國的工業非常發達,二戰時德國設計的武器都是標準件,即使一輛趟克被炸爛,其中的零件都還可以再利用,甚至可以應用到槍支或其他武器上。

          Acid3

          測試瀏覽器支持Acid3的程度:http://acid3.acidtests.org/

          為什么要使用Web標準(zz)?

          英文版:http://www.webstandards.org/learn/faq/
          中文版:http://www.webstandards.org/learn/faq/faq_zh-simplified/

          posted @ 2009-07-02 09:35 xiaoxinchen 閱讀(111) | 評論 (0)編輯 收藏

          快速入門

          歡迎使用BeanShell.這是一個速成課程。我們將省去一些重要的選項和細節。要學習更多的內容請看本User's Guide的其它部分。

          下載和運行BeanShell

          請到http://www.beanshell.org下載最新的JAR文件。你可以用圖形桌面模式和命令行模式起動BeanShell。
          如果你只是要玩一玩BeanShell,你可以在BeanShell的jar文件上雙擊來起動BeanShell的桌面。但不管怎樣,如果你要讓BeanShell與你的類與應用程序一起工作就必須將BeanShell的jar文件加到classpath中。
          你可以將BeanShell的jar文件拖到JAVA_HOME的ext目錄也可以直接加到classpath中。

          • windows用戶請將bsh.jar放在JAVA_HOME/jre/lib/ext文件夾,OSX用戶可以放在/Library/Java/Extensions.
            或者增加BeanShell到你的classpath目錄,如:
            unix: export CLASSPATH=$CLASSPATH:bsh-xx.jar
            windows:set classpath %classpath%;bsh-xx.jar

          然后你就可以運行BeanShell在GUI或命令行模式:

          •  java bsh.Console       // run the graphical desktop
            or
                 java bsh.Interpreter   // run as text-only on the command line
            or
                 java bsh.Interpreter filename [ args ] // run script file

          可以在你的應用程序內部來運行,也可以作為debug及servlet的遠程服務器模式,或一個Applet內部來運行BeanShell。請參考"BeanShell Modes of Operation"獲得更多詳情。

          BeanShell GUI

          用GUI模式啟動BeanShell后,將打開一個桌面視窗。用鼠標右擊在桌面的背景上,你可以打開另一個控制臺視窗及其它的工具如一個簡單的類游覽器。
          每一個控制臺視窗運行一個獨立的BeanShell解釋器。這個圖形化的控制臺支持基本的歷史命令,行編輯,剪切和粘貼,甚至類和變量名的自動完成功能。從控制臺你能開啟一個簡單的編輯視窗。在它里面,你可以編寫腳本和使用‘eval’選項求表達式的值。

          Java語句和表達式

          BeanShell能理解標準的JAVA語句,表達式,和方法宣告。語句和表達式的內容可以是:變量,宣告,賦值,方法調用,循環,條件等。
          在 Java程序中你必須嚴格的使用它們,但在BeanShell中,你可以用“寬松類型”(loosely typed)的方式來使用它們。也就是說,你可以在寫腳本時偷懶,不進行變量類型的宣告(在原始數據類型和對象都可以)。如果你試著用錯變量類 型,BeanShell將會給出一個錯誤。
          這里有一些例子:

          • foo = "Foo";   
            four = (2 + 2)*2/2;
            print( foo + " = " + four );  // print() is a BeanShell command
            // Do a loop
            for (i=0; i<5; i++)
                print(i);  
            // Pop up a frame with a button in it
            button = new JButton( "My Button" );
            frame = new JFrame( "My Frame" );
            frame.getContentPane().add( button, "Center" );
            frame.pack();
            frame.setVisible(true);

          有用的BeanShell命令

          在 剛才那個例子中我們用了一個內建在BeanShell中的一個方便的命令print(),來顯示變量的值。print()跟ava的 System.out.println()非常的相像,除非它能保證輸出總是命令行。print()也可以顯示一些對象的類型(如數組),但比Java的 更詳細。另一個相關的命令是show(),用來開啟與關閉顯示你輸入的每一行的結果。
          這兒是一些其它的BeanShell的命令:
          source(), run() - 將一個bsh腳本讀到解釋器或運行在另一個解釋器。
          frame() - 顯示一個Frame或JFrame的GUI組件.
          load(), save() - 載入和保存一個序列化的對象到一個文件.
          cd(), cat(), dir(), pwd(), etc. - 類unix的shell命令。
          exec() - 運行一個本地的程序。
          javap() - 打印一個對象的方法和字段,類似于Java的javap命令。
          setAccessibility() - 開啟無限制的存取private 和protected的組件。
          要獲得更多的信息請查看BeanShell命令的詳細清單。

          提示:
          BeanShell命令并不是真的"內建"其中的,而是作為腳本方法自動從classpath載入的. 你可以擴展基本命令集并加到classpath中作為自訂義的腳本來使用。

          腳本方法

          你可以在bsh中宣告和使用方法,就像在java的類中一樣。

          • int addTwoNumbers( int a, int b ) {
                return a + b;
            }
            sum = addTwoNumbers( 5, 7 );  // 12

          bsh的方法可以有動態的(寬松的)參數和返回類型。

          • add( a, b ) {
                return a + b;
            }
            foo = add(1, 2);            // 3
            foo = add("Oh", " baby");   // "Oh baby"

          實現Interface

          注意:如果要BeanShell能實現任意的Interface,必須有jdk1.3及以上支持。
          你可以在腳本中用標準的Java內部類的語法來實現Interface.例如:

          • ActionListener scriptedListener = new ActionListener() {
                actionPerformed( event ) { ... }
            }

          你 可以不用實現Interface的所有方法,而只用實現你需要的方法。如果代碼中調用了未被實現的方法,將丟出異常。如果你想重載大量的方法的行為--例 如為日志生成一個"啞"適配器--你可以在腳本對象中實現一個特殊的方法:invoke(name,args)。invoke()方法用來處理任何未被定 義的方法的調用:

          • ml = new MouseListener() {
                mousePressed( event ) { ... }
                // handle the rest
                invoke( name, args ) { print("Method: "+name+" invoked!");
            }

          腳本對象

          在 BeanShell中,和在JavaScript與Perl中一樣,腳本對象是用封閉的方法體一構成的。通過在方法未尾返回一個特殊值"this",你就 可以像使用方法一樣調用這個對象了。在這個方法調用時,你可以給與它任何的值。通常對象內部需要包括方法,所以BeanShell的腳本方法在一定程度上 可再包含一些方法以構成腳本對象。例如:

          • foo() {
                print("foo");
                x=5;
                bar() {
                    print("bar");
                }
                return this;
            }
            myfoo = foo();    // prints "foo"
            print( myfoo.x ); // prints "5"
            myfoo.bar();      // prints "bar"

          如果這些代碼對你來說很陌生,別急,請用戶手冊可得到更透徹的解釋。

          在 你的腳本中,BeanShell腳本對象(也就是先前例子中的"this"參照)能自動實現任何JAVA介面類型。當JAVA代碼調用相應與之通訊的腳本 方法內的方法。當你試著將腳本對象作為參數傳給Java方法時,BeanShell會自動將它造型(cast)為相應的類型。如要傳遞BeanShell 外部的對象時,你可以在需要時顯式的進行造型(cast).請看用戶手冊中的詳細內容。

          從你的應用程序調用BeanShell

          通過建立一個BeanShell解釋器,使用eval()或source()命令,你可以在你的應用程序中求文本表達式的值和運行腳本。如果你希望在你的腳本內部使用一個對象,可以用set()方法傳遞對象的變量參照給BeanShell,并通過get()方法取得結果。

          • import bsh.Interpreter;
            Interpreter i = new Interpreter();  // Construct an interpreter
            i.set("foo", 5);                    // Set variables
            i.set("date", new Date() );
            Date date = (Date)i.get("date");    // retrieve a variable
            // Eval a statement and get the result
            i.eval("bar = foo*10");            
            System.out.println( i.get("bar") );
            // Source an external script file
            i.source("somefile.bsh");

           

          BeanShell將成為Java平臺上的第三種編程語言
          2005-06-08  點擊:8  來源:CSDN  作者:CSDN
          JCP接納了一個新的技術規范進入標準化進程,這個編號為JSR-274的技術規范將把BeanShell引入為Java平臺上支持的又一種編程語言。

          JSR- 274(http://jcp.org/en/jsr/detail?id=274)是由 Patrick Niemeyer提交的技術規范,其目標是將BeanShell腳本語言(http://www.beanshell.org/)規范化為Java虛擬機 平臺上支持的第三種編程語言。除了Java之外,Java虛擬機還支持Groovy腳本語言。Doug Lea、Apache和Google三個JCP執委會成員對此規范表示了支持。

          按照Java最初的設計思路,有很多語言都可以在JVM上 運行(詳細列表參見http://en.wikipedia.org/wiki/List_of_Java_scripting_languages), 但這些語言大多沒有流行起來。直到2004年為止,Java平臺事實上只有一種編程語言,也就是Java。2004年3月,Groovy(JSR- 241)成為了Java平臺上的第二種編程語言。

          消息全文請看:http://rmh.blogs.com/weblog/2005/05/beanshell_the_3.html

          http://www.cn-java.com/target/news.php?news_id=2450

          簡介:
          BeanShell是一種腳本語言,一種完全符合java語法的java腳本語言,并且又擁有自己的一些語法和方法,beanShell是一種松散類型的腳本語言(這點和JS類似)。
          下載地址:http://www.beanshell.org

          設置環境
          l 把;bsh-xx.jar放到$JAVA_HOME/jre/lib/ext文件夾下
          l unix: export CLASSPATH=$CLASSPATH:bsh-xx.jar
          l windows: set classpath %classpath%;bsh-xx.jar

          運行方式:
          l 界面UI方式 :java bsh.Console
          l 命令行方式 :java bsh.Interpreter
          l 運行腳本文件:java bsh.Interpreter filename [ args ]



          簡單舉例:
          在classpath中設置好環境變量,打開dos窗口,鍵入:java bsh.Console命令
          出現BeanShell圖片代表設置成功,beanshell開始運行





          測試內容:
          設置變量
          foo = "Foo";
          four = (2 + 2)*2/2;
          打印變量
          print( foo + " = " + four );
          循環
          for (i=0; i<5; i++)
          print(i);
          在窗口中打印按鈕
          button = new JButton( "My Button" );
          frame = new JFrame( "My Frame" );
          frame.getContentPane().add( button, "Center" );
          frame.pack();
          frame.setVisible(true);

          完整代碼:
          foo = "Foo";
          four = (2 + 2)*2/2;
          print( foo + " = " + four );

          for (i=0; i<5; i++)
          print(i);

          button = new JButton( "My Button" );
          frame = new JFrame( "My Frame" );
          frame.getContentPane().add( button, "Center" );
          frame.pack();
          frame.setVisible(true);


          在窗口中輸入上面的代碼

          敲回車執行,運行結果如圖


          說明:
          因為beanshell是松散類型的腳本語言因此可以直接寫
          foo = "Foo";
          four = (2 + 2)*2/2;

          print是beanshell提供一種簡單的打印命令相當于java中的System.out.println()





          其他的beanshell腳本命令
          · source(), run() – 讀取,或者運行一個腳本文件
          · frame() – 顯示一個窗口
          · load(), save() – 讀取或者保存一個腳本對象到文件
          · cd(), cat(), dir(), pwd(), etc. 使用Unix下面的命令
          · exec() – 運行一個本地的方法
          · javap() –使用javap命令.
          · setAccessibility() – 設置可以接收private和protected類型的變量
          BeanShell命令不一定都是內置的腳本命令,腳本方法會自動從classpath中取方法使用,因此你可以添加你自己的腳本到classpath中來擴充基本的命令






          腳本方法
          一般的方法:
          int addTwoNumbers( int a, int b ) {
          return a + b;
          }

          sum = addTwoNumbers( 5, 7 ); // 12
          也可以使用動態的變量類型(無狀態)方法
          add( a, b ) {
          return a + b;
          }
          foo = add(1, 2); // 3
          foo = add(1, “2”); //”12” 只要有一個為字符串全部按照字符串處理,系統不會根據1是數字在前把“2”轉換成數字處理(特別注意)
          foo = add("Oh", " baby"); // "Oh baby"




          實現接口
          實現任何接口需要java1.3或者更高
          可以使用缺省的java匿名類的語法實現一個接口類,例如:
          ActionListener scriptedListener = new ActionListener() {
          actionPerformed( event ) { ... }
          }
          不需要實現接口的所有的方法,只需要實現你使用的方法即可,如果使用你沒有實現的方法,beanshell將拋出一個錯誤,
          ml = new MouseListener() {
          mousePressed( event ) { ... }
          // handle the rest
          invoke( name, args ) { print("Method: "+name+" invoked!");
          }








          腳本對象
          使用特殊的關鍵字this可以創建一個對象(根JS類似)
          foo() {
          print("foo");
          x=5;

          bar() {
          print("bar");
          }

          return this;
          }

          myfoo = foo(); // prints "foo"
          print( myfoo.x ); // prints "5"
          myfoo.bar(); // prints "bar"

          從應用程序中調用BeanShell
          創建一個BeanShell的解釋器(interpreter)用eval()和source()命令可以對一個字符串求值和運行一個腳本文件
          使用set()方法可以給一個對象傳入一個變量的參考
          使用get()方法可以重新得到一個變量的結果


          完整代碼:
          package cn.com.sparknet.util;

          import bsh.*;
          import java.util.*;

          public class BeanShell {
          public static void main(String[] args) {
          try {
          Interpreter interpreter = new Interpreter(); // 構造一個解釋器
          interpreter.set("foo", 5); // 設置變量
          interpreter.set("date", new Date()); //設置一個時間對象
          Date date = (Date) interpreter.get("date"); // 重新得到時間變量
          interpreter.println(date.toString()); //打印時間變量
          interpreter.eval("bar = foo*10"); // 對一段腳本求值,并得到結果
          System.out.println(interpreter.get("bar")); //打印變量
          interpreter.source("d:\\helloWorld.bsh"); // 導入并執行一個腳本文件
          }
          catch (Exception e) {
          //如果發生異常,寫入日志文件
          Log.error(new BeanShell(), "main", FormatDate.getCurrDate(), e.getMessage());
          }
          }
          }






          BeanShell語法
          BeanShell是一種最原始的java解釋器。
          標準的java語法
          /*
          Standard Java syntax
          */

          // Use a hashtable
          Hashtable hashtable = new Hashtable();
          Date date = new Date();
          hashtable.put( "today", date );

          // Print the current clock value
          print( System.currentTimeMillis() );

          // Loop
          for (int i=0; i<5; i++)
          print(i);

          // Pop up a frame with a button in it
          JButton button = new JButton( "My Button" );
          JFrame frame = new JFrame( "My Frame" );
          frame.getContentPane().add( button, "Center" );
          frame.pack();
          frame.setVisible(true);
          松散類型的java語法
          /*
          Loosely Typed Java syntax
          */

          // Use a hashtable
          hashtable = new Hashtable();
          date = new Date();
          hashtable.put( "today", date );

          // Print the current clock value
          print( System.currentTimeMillis() );

          // Loop
          for (i=0; i<5; i++)
          print(i);

          // Pop up a frame with a button in it
          button = new JButton( "My Button" );
          frame = new JFrame( "My Frame" );
          frame.getContentPane().add( button, "Center" );
          frame.pack();
          frame.setVisible(true);
          異常處理
          標準的java異常
          try {
          int i = 1/0;
          } catch ( ArithmeticException e ) {
          print( e );
          }
          松散的異常處理(類似JS)
          try {
          ...
          } catch ( e ) {
          ...
          }
          松散類型變量的作用范圍
          標 準的java程序的變量作用范圍是在一個模塊中的(在模塊中聲明的變量),而在松散類型的語言中如果在一個模塊中沒有指定一個變量的類型,則認為是一個全 局變量(只有它以后的代碼可以使用該變量,系統在調用該變量的時候自動生成一個全局變量,也就為什么在調用模塊之前不能使用該變量的原因)
          // Arbitrary code block
          {
          y = 2; // Untyped variable assigned
          int x = 1; // Typed variable assigned
          }
          print( y ); // 2
          print( x ); // Error! x is undefined.

          // Same with any block statement: if, while, try/catch, etc.
          if ( true ) {
          y = 2; // Untyped variable assigned
          int x = 1; // Typed variable assigned
          }
          print( y ); // 2
          print( x ); // Error! x is undefined.

          同樣也使用于for-loop, if-else等循環語句
          for( int i=0; i<10; i++ ) { // typed for-init variable
          j=42;
          }
          print( i ); // Error! 'i' is undefined.
          print( j ); // 42

          for( z=0; z<10; z++ ) { } // untyped for-init variable
          print( z ); // 10









          方便靈活的語法
          標準的java語法
          java.awt.Button button = new java.awt.Button();
          button.setLabel(“javaButton”);
          松散的語法
          button = new java.awt.Button();
          button.label = "my button";
          你也可以使用{}來對一個對象設置屬性
          b = new java.awt.Button();
          b{"label"} = "my button"; // Equivalent to: b.setLabel("my button");

          h = new Hashtable();
          h{"foo"} = "bar"; // Equivalent to: h.put("foo", "bar");




          包裝和未包裝(box和unbox)
          BeanShell自動轉為簡單類型
          i=5;
          iw=new Integer(5);
          print( i * iw ); // 25
          導入類和包
          import javax.xml.parsers.*;
          import mypackage.MyClass;
          超級導入法:
          import *;
          BeanShell默認導入下面的包
          · java.lang
          · java.io
          · java.util
          · java.net
          · java.awt
          · java.awt.event
          · javax.swing
          · javax.swing.event
          友好文檔實體
          BeanShell支持特殊的文檔操作類型內容
          @gt > @lt <
          @lteq <= @gteq >=
          @or || @and &&
          @bitwise_and & @bitwise_or |
          @left_shift << @right_shift >>
          @right_unsigned_shift >>> @and_assign &=
          @or_assign |= @left_shift_assign <<=
          @right_shift_assign >>= @right_unsigned_shift_assign >>>=
          腳本方法
          你可以定義方法象java中的定義方法一樣
          int addTwoNumbers( int a, int b ) {
          return a + b;
          }
          你可以使用內餡的BeanShell方法使用他們
          sum = addTwoNumbers( 5, 7 );
          只有BeanShell變量可以被動態定義為動態類型,方法可以有動態的參數以及返回類型
          add( a, b ) {
          return a + b;
          }
          在這個方法中,BeanShell將動態的決定類型當這個方法被調用時并且能夠準確的計算出你想要的結果
          foo = add(1, 2);
          print( foo ); // 3

          foo = add("Oh", " baby");
          print( foo ); // Oh baby
          在第一個例子中BeanShell將把參數定義為數字型,并返回數字型
          在第二個例子中BeanShell將把參數定義為字符型,并返回字符對象
          變量和方法的可見范圍
          就像您所預期的那樣,在方法內您可以參考到上下文中上面的變量和方法
          a = 42;
          someMethod() { ... }

          foo() {
          print( a );
          someMethod(); // invoke someMethod()
          }

          // invoke foo()
          foo(); // prints 42
          如果一個變量只有在方法內使用請定義成局部變量,即加上類型,如果是全局變量請在方法外定義
          var = "global";
          foo() {
          print(var);
          String var = "local";
          print(var);
          }
          foo();
          print(var);
          將打印出
          global
          local
          global
          方法內的var(第四行)變量屬于局部變量,不會覆蓋全局變量var(第一行)的因此改變var(第四行)變量不會影響到全局變量var(第一行)
          范圍參考:super
          使用super關鍵字可以在局部參考到全局變量
          var = "global";
          foo() {
          String var = "local";
          print(var);
          print(super.var);
          }
          foo();
          將輸出
          local
          global







          腳本對象
          this對象
          在java標準語言中可以使用this返回一個類的一個實例
          // MyClass.java
          MyClass {
          Object getObject() {
          return this; // return a reference to our object
          }
          }
          在這個例子中getObject() 方法是返回MyClass類的一個實例
          在BeanShell中對象中的變量只是局部的變量在對象內可以使用,在對象外是不可以使用(不同于前面for-loop,if-else中的使用);
          // Define the foo() method:
          foo() {
          bar = 42;
          print( bar );
          }

          // Invoke the foo() method:
          foo(); // prints 42

          print( bar ); // Error, bar is undefined here
          可以使用this返回對象,使用對象加上“.”運算符參考屬性(類似JS)
          foo() {
          bar = 42;
          return this;
          }

          fooObj = foo();
          print( fooObj.bar ); // prints 42!
          同樣對象中也可以定義一些方法
          foo() {
          bar() {
          ...
          }
          }
          例如
          foo() {
          int a = 42;
          bar() {
          print("The bar is open!");
          }

          bar();
          return this;
          }

          // Construct the foo object
          fooObj = foo(); // prints "the bar is open!"
          // Print a variable of the foo object
          print ( fooObj.a ) // 42
          // Invoke a method on the foo object
          fooObj.bar(); // prints "the bar is open!"
          也可以把bar()和foo也可以代參數
          foo() {
          return this;
          }
          bar(int a) {
          print("The bar is open!" + a);
          }
          foo().bar(1);
          也可以把bar()方法定義到對象外面

          foo() {
          bar(int a) {
          print("The bar is open!" + a);
          }
          return this;
          }
          foo().bar(1);
          BeanShell一種松散的腳本語言,有很多中聲明的方法可以使用
          This super global
          This是參考當前對象
          Super是參考父親對象
          Global是參考最上層對象
          super.super.super...foo = 42; // Chain super. to reach the top
          global.foo = 42;








          簡單例子:
          文本拖動:

          dragText() {
          f = new Frame("Drag in the box");
          f.setFont( new Font("Serif", Font.BOLD, 24) );
          f.setSize(300, 300);
          f.show();
          gc = f.getGraphics();
          gc.setColor(Color.cyan);
          mouseDragged( e ) {
          gc.drawString("Drag Me!", e.getX(), e.getY());
          }
          mouseMoved( e ) { }
          f.addMouseMotionListener( this );
          }
          簡單畫圖

          import bsh.util.BshCanvas; // BshCanvas simply buffers graphics

          graph( int width, int height ) {
          canvas=new BshCanvas();
          canvas.setSize( width, height );
          frame=frame( canvas );
          graphics=canvas.getBufferedGraphics();
          // draw axis
          graphics.setColor( Color.red );
          graphics.drawLine( 0, height/2, width, height/2 );
          graphics.drawLine( width/2, 0, width/2, height );
          graphics.setColor( Color.black );

          plot(int x, int y) {
          graphics.fillOval( (x+width/2-1), (y+height/2-1), 3, 3);
          canvas.repaint();
          }

          return this;
          }

          drawSin( graph ) {
          for (int x=-100; x<100; x++ ) {
          y=(int)(50*Math.sin( x/10.0 ));
          graph.plot( x, y );
          }
          }
          簡單web瀏覽器

          import javax.swing.*;
          import javax.swing.event.*;
          import javax.swing.text.*;
          import java.awt.event.*;
          import java.awt.*;

          JFrame browser( startingUrl ) {
          invoke( method, args ) {}

          windowClosing(WindowEvent we) {
          we.getWindow().setVisible(false);
          }

          setPage( url ) {
          try {
          pane.setPage( url );
          } catch(Exception e) {
          statusBar.setText("Error opening page: "+url);
          }
          }

          hyperlinkUpdate( HyperlinkEvent he ) {
          type = he.getEventType();
          if (type == HyperlinkEvent.EventType.ENTERED) {
          pane.setCursor(
          Cursor.getPredefinedCursor( Cursor.HAND_CURSOR) );
          statusBar.setText(he.getURL().toString());
          } else
          if (type == HyperlinkEvent.EventType.EXITED) {
          pane.setCursor( Cursor.getDefaultCursor() );
          statusBar.setText(" ");
          } else {
          setPage( he.getURL() );
          if (urlField != null)
          urlField.setText(he.getURL().toString());
          }
          }

          frame = new JFrame("Browser");
          frame.setSize(400,300);
          frame.addWindowListener( this );

          urlPanel = new JPanel();
          urlPanel.setLayout(new BorderLayout());
          urlField = new JTextField(startingUrl);
          urlPanel.add(new JLabel("Site: "), BorderLayout.WEST);
          urlPanel.add(urlField, BorderLayout.CENTER);

          statusBar = new JLabel(" ");
          pane = new JEditorPane();
          pane.setEditable(false);
          setPage( startingUrl );
          jsp = new JScrollPane(pane);

          frame.getContentPane().add(jsp, BorderLayout.CENTER);
          frame.getContentPane().add(urlPanel, BorderLayout.SOUTH);
          frame.getContentPane().add(statusBar, BorderLayout.NORTH);

          // This is the equivalent of an inner class in bsh.
          urlTextHandler() {
          actionPerformed(ActionEvent ae) {
          setPage( ae.getActionCommand() );
          }
          return this;
          }

          urlField.addActionListener( urlTextHandler() );
          pane.addHyperlinkListener( (HyperlinkListener)this );

          return frame;
          }
          browser = browser("http://java.sun.com/");
          browser.show();




          更多的文檔參考BeanShell網站

          http://www.beanshell.org
          posted @ 2008-10-08 14:34 xiaoxinchen 閱讀(2477) | 評論 (0)編輯 收藏

          在處理一個大數據量數據庫的時候
          突然發現mysql對于count(*)的不同處理會造成不同的結果

          比如執行
          SELECT count(*) FROM tablename
          即使對于千萬級別的數據mysql也能非常迅速的返回結果
          而對于
          SELECT count(*) FROM tablename WHERE…..
          mysql的查詢時間開始攀升

          仔細查閱累下手冊,發現當沒有WHERE語句對于整個mysql的表進行count運算的時候
          MyISAM類型的表中保存有總的行數,而當添加有WHERE限定語句的時候Mysql需要對整個表進行檢索
          從而得出count的數值

          突然又想起來看到的不少新興的php程序對于count的處理并沒有很好的意思到這點
          記錄下

          順便提下mysql的DISTINCT的關鍵字有很多你想不到的用處
          1.在count 不重復的記錄的時候能用到
          比如SELECT COUNT( DISTINCT id ) FROM tablename;
          就是計算talbebname表中id不同的記錄有多少條

          2,在需要返回記錄不同的id的具體值的時候可以用
          比如SELECT DISTINCT id FROM tablename;
          返回talbebname表中不同的id的具體的值

          3.上面的情況2對于需要返回mysql表中2列以上的結果時會有歧義
          比如SELECT DISTINCT id, type FROM tablename;
          實際上返回的是 id與type同時不相同的結果,也就是DISTINCT同時作用了兩個字段,必須得id與tyoe都相同的才被排除了,與我們期望的結果不一樣

          4.這時候可以考慮使用group_concat函數來進行排除,不過這個mysql函數是在mysql4.1以上才支持的

          5.其實還有另外一種解決方式,就是使用
          SELECT id, type, count(DISTINCT id) FROM tablename
          雖然這樣的返回結果多了一列無用的count數據(或許你就需要這個我說的無用數據)
          返回的結果是 只有id不同的所有結果和上面的4類型可以互補使用,就是看你需要什么樣的數據了


          posted @ 2008-10-07 14:46 xiaoxinchen 閱讀(253) | 評論 (0)編輯 收藏
          Lucene,作為一種全文搜索的輔助工具,為我們進行條件搜索,無論是像Google,Baidu之類的搜索引擎,還是論壇中的搜索功能,還是其它 C/S架構的搜索,都帶來了極大的便利和比較高的效率。本文主要是利用Lucene對MS Sql Server 2000進行建立索引,然后進行全文索引。至于數據庫的內容,可以是網頁的內容,還是其它的。本文中數據庫的內容是圖書館管理系統中的某個作者表 -Authors表。

            因為考慮到篇幅的問題,所以該文不會講的很詳細,也不可能講的很深。

            本文以這樣的結構進行:

            1.介紹數據庫中Authors表的結構

            2.為數據庫建立索引

            3.為數據庫建立查詢功能

            4.在web界面下進行查詢并顯示結果

            1.介紹數據庫中Authors表的結構

          字段名稱         字段類型         字段含義

          Au_id                Varchar(11)    作者號
          Au_name        Varchar(60)     作者名
          Phone             Char(12)           電話號碼
          Address          Varchar(40)      地址
          City                   Varchar(20)     城市
          State                Char(2)             省份
          Zip                    Char(5)             郵編
          contract            Bit(1)                外鍵(關系不大)


          表中的部分內容:
           

            2.為數據庫建立索引

            首先建立一個類TestLucene.java。這個類就是對數據庫進行建立索引,編寫查詢條件等。

            當然,最開始就是建立數據庫連接。連接代碼這里就省略了。^_^

            接著,新建一個方法getResutl(String),它返回的是數據庫表Authors的內容。具體代碼如下:


              public ResultSet getResult(String sql){
                try{
                  Statement stmt = conn.createStatement();
                  ResultSet rs = stmt.executeQuery(sql);
                  return rs;
                }
                catch(SQLException e){
                  System.out.println(e);
                }
                return null;
              }
           


          然后,為數據庫建立索引。

            首先要定義一個IndexWriter(),它是將索引寫進Lucene自己的數據庫中,它存放的位置是有你自己定義的。在定義 IndexWriter是需要指定它的分析器。Lucene自己自帶有幾個分析器,例 如:StandarAnalyzer(),SimpleAnalyzer(),StopAnalyzer()等。它作用是對文本進行分析,判斷如何進行切 詞。
          接著,要定義一個Document。Document相當于二維表中一行數據一樣。Document里包含的是Field字段,Field相當于數據庫中一列,也就是一個屬性,一個字段。
          最后應該對IndexWriter進行優化,方法很簡單,就是writer.optimize().
          具體代碼如下:


            public void Index(ResultSet rs){
                try{
                  IndexWriter writer = new IndexWriter("d:/index/", getAnalyzer(), true);
                  while(rs.next()){
                      Document doc=new Document();
                      doc.add(Field.Keyword("id",rs.getString("au_id")));
                      doc.add(Field.Text("name",rs.getString("au_name")));
                      doc.add(Field.UnIndexed("address",rs.getString("address")));
                      doc.add(Field.UnIndexed("phone",rs.getString("phone")));
                      doc.add(Field.Text("City",rs.getString("city")));
                      writer.addDocument(doc);
                    }
                  writer.optimize();
                  writer.close();
                }
                catch(IOException e){
                  System.out.println(e);
                }
                catch(SQLException e){
                  System.out.println(e);
                }
              }

              public Analyzer getAnalyzer(){
                return new StandardAnalyzer();
              }

           


          3.為數據庫建立查詢功能

            在類TestLucene中建立一個新的方法searcher(String),它返回的是一個搜索的結構集,相當于數據庫中的ResultSet一樣。它代的參數是你要查詢的內容。這里,我把要查詢的字段寫死了。你可以在添加一個參數表示要查詢的字段。
          這里主要有兩個對象IndexSearcher和Query。IndexSearcher是找到索引數據庫,Query是處理搜索,它包含了三個參數:查詢內容,查詢字段,分析器。
          具體代碼如下:


            public Hits seacher(String queryString){
                Hits hits=null;;
                try{
                  IndexSearcher is = new IndexSearcher("D:/index/");
                  Query query=QueryParser.parse(queryString,"City",getAnalyzer());
                  hits=is.search(query);
                }catch(Exception e){
                  System.out.print(e);
                }
                return hits;
              }
           


          4.在web界面下進行查詢并顯示結果

            這里建立一個Jsp頁面TestLucene.jsp進行搜索。

            在TestLucene.jsp頁面中首先引入類


          <%@ page import="lucenetest.LucentTest"%>
          <%@ page import="org.apache.lucene.search.*,org.apache.lucene.document.*" %>
           


          然后定義一個LuceneTest對象,獲取查詢結果集:


            LucentTest lucent=new LucentTest();
            Hits hits=lucent.seacher(request.getParameter("queryString"));
           


          定義一個Form,建立一個查詢環境:


          <form action="TestLucene.jsp">
            <input  type="text" name="queryString"/>
            <input type="submit" value="搜索"/>
          </form>
           


          顯示查詢結果:


          <table>
            <%if(hits!=null){%>
            <tr>
              <td>作者號</td>
              <td>作者名</td>
              <td>地址</td>
              <td>電話號碼</td>
            </tr>

           <% for(int i=0;i<hits.length();i++){
              Document doc=hits.doc(i);
             %>
              <tr>
              <td><%=doc.get("id") %></td>
              <td><%=doc.get("name") %></td>
              <td><%=doc.get("address") %></td>
              <td><%=doc.get("phone") %></td>
            </tr>
           <% }}%>
          </table>

          posted @ 2008-08-29 13:59 xiaoxinchen 閱讀(215) | 評論 (0)編輯 收藏

          中國有很多精于編碼的人,但是中國軟件行業,尤其是網絡應用開發方面誤區很大,很難形成有規模的軟件開發力量和產品能力,不但比美國差距甚遠,和印 度相比也是頗有不如。這些問題不是在于中國程序員的智商和工作努力狀況,也不是在于國家和民間對開發的投入程度,而是很大程度上,有一些對技術,對程序開 發,對項目設計方面的思想誤區,這些誤區,導致了軟件行業的產品化能力不足,缺乏規模化和大型復用系統研發能力,可以說,改變認識誤區,是解決軟件行業小 作坊模式和個體英雄模式所帶來的局限性的重要工作。


          程序員是一種技術工作,在IT的發展中有相當重要的地位,從底層硬件通訊協議的建立,到數據傳輸層的處理,到操作系統的建設,到數據庫平臺的建設,一直到應用層上各種數據營銷平臺的搭建,程序員在里面都扮演著舉足輕重的角色并為IT事業的發展做出了巨大的貢獻。

          中 國有很多小朋友,他們18,9歲或21,2歲,通過自學也寫了不少代碼,他們有的代碼寫的很漂亮,一些技術細節相當出眾,也很有鉆研精神,但是他們被一些 錯誤的認識和觀點左右,缺乏對系統,對程序的整體理解能力,這些人,一個網上的朋友說得很好,他們實際上只是一些Codingfans,壓根沒有資格稱 為程序員,但是據我所知,不少小網絡公司的CTO就是這樣的codingfans,拿著嚇人的工資,做著嚇人的項目,項目的結局通常也很嚇人。
          程序員基本素質:

          作一個真正合格的程序員,或者說就是可以真正合格完成一些代碼工作的程序員,應該具有的素質。

          1:團隊精神和協作能力
          把 它作為基本素質,并不是不重要,恰恰相反,這是程序員應該具備的最基本的,也是最重要的安身立命之本。把高水平程序員說成獨行俠的都是在囈語,任何個人的 力量都是有限的,即便如linus這樣的天才,也需要通過組成強大的團隊來創造奇跡,那些遍布全球的為linux寫核心的高手們,沒有協作精神是不可想象 的。獨行俠可以作一些賺錢的小軟件發點小財,但是一旦進入一些大系統的研發團隊,進入商業化和產品化的開發任務,缺乏這種素質的人就完全不合格了。

          2:文檔習慣
          說 高水平程序員從來不寫文檔的肯定是乳臭未干的毛孩子,良好的文檔是正規研發流程中非常重要的環節,作為代碼程序員,30%的工作時間寫技術文檔是很正常 的,而作為高級程序員和系統分析員,這個比例還要高很多。缺乏文檔,一個軟件系統就缺乏生命力,在未來的查錯,升級以及模塊的復用時就都會遇到極大的麻 煩。

          3:規范化,標準化的代碼編寫習慣
          作為一些外國知名軟件公司的規矩,代碼的變量命名,代碼內注釋格式,甚至嵌套中行縮進的長度和函數間的空行數字都有明確規定,良好的編寫習慣,不但有助于代碼的移植和糾錯,也有助于不同技術人員之間的協作。
          有些codingfans叫囂高水平程序員寫的代碼旁人從來看不懂,這種叫囂只能證明他們自己壓根不配自稱程序員。代碼具有良好的可讀性,是程序員基本的素質需求。
          再看看整個linux的搭建,沒有規范化和標準化的代碼習慣,全球的研發協作是絕對不可想象的。
          4:需求理解能力
          程 序員需要理解一個模塊的需求,很多小朋友寫程序往往只關注一個功能需求,他們把性能指標全部歸結到硬件,操作系統和開發環境上,而忽視了本身代碼的性能考 慮,有人曾經放言說寫一個廣告交換程序很簡單,這種人從來不知道在百萬甚至千萬數量級的訪問情況下的性能指標是如何實現的,對于這樣的程序員,你給他深藍 那套系統,他也做不出太極鏈的并訪能力。性能需求指標中,穩定性,并訪支撐能力以及安全性都很重要,作為程序員需要評估該模塊在系統運營中所處的環境,將 要受到的負荷壓力以及各種潛在的危險和惡意攻擊的可能性。就這一點,一個成熟的程序員至少需要2到3年的項目研發和跟蹤經驗才有可能有心得。

          5:復用性,模塊化思維能力
          經常可以聽到一些程序員有這樣的抱怨,寫了幾年程序,變成了熟練工,每天都是重復寫一些沒有任何新意的代碼,這其實是中國軟件人才最大浪費的地方,一些重復性工作變成了熟練程序員的主要工作,而這些,其實是完全可以避免的。
          復 用性設計,模塊化思維就是要程序員在完成任何一個功能模塊或函數的時候,要多想一些,不要局限在完成當前任務的簡單思路上,想想看該模塊是否可以脫離這個 系統存在,是否可以通過簡單的修改參數的方式在其他系統和應用環境下直接引用,這樣就能極大避免重復性的開發工作,如果一個軟件研發單位和工作組能夠在每 一次研發過程中都考慮到這些問題,那么程序員就不會在重復性的工作中耽誤太多時間,就會有更多時間和精力投入到創新的代碼工作中去。
          一些好的程序模塊代碼,即便是70年代寫成的,拿到現在放到一些系統里面作為功能模塊都能適合的很好,而現在我看到的是,很多小公司軟件一升級或改進就動輒全部代碼重寫,大部分重復性工作無謂的浪費了時間和精力。

          6:測試習慣
          作 為一些商業化正規化的開發而言,專職的測試工程師是不可少的,但是并不是說有了專職的測試工程師程序員就可以不進行自測;軟件研發作為一項工程而言,一個 很重要的特點就是問題發現的越早,解決的代價就越低,程序員在每段代碼,每個子模塊完成后進行認真的測試,就可以盡量將一些潛在的問題最早的發現和解決, 這樣對整體系統建設的效率和可靠性就有了最大的保證。
          測試工作實際上需要考慮兩方面,一方面是正常調用的測試,也就是看程序是否能在正常調用 下完成基本功能,這是最基本的測試職責,可惜在很多公司這成了唯一的測試任務,實際上還差的遠那;第二方面就是異常調用的測試,比如高壓力負荷下的穩定性 測試,用戶潛在的異常輸入情況下的測試,整體系統局部故障情況下該模塊受影響狀況的測試,頻發的異常請求阻塞資源時的模塊穩定測試等等。當然并不是程序員 要對自己的每段代碼都需要進行這種完整測試,但是程序員必須清醒認識自己的代碼任務在整體項目中的地位和各種性能需求,有針對性的進行相關測試,并盡早發 現和解決問題,當然這需要上面提到的需求理解能力。

          7:學習和總結的能力
          程序員是人才很容易被淘汰,很容易落伍的職業,因為一種技術可能僅僅在三兩年內具有領先性,程序員如果想安身立命,就必須不斷跟進新的技術,學習新的技能。
          善 于學習,對于任何職業而言,都是前進所必需的動力,對于程序員,這種要求就更加高了。但是學習也要找對目標,一些小codingfans們,他們也津津 樂道于他們的學習能力,一會學會了asp,一會兒學會了php,一會兒學會了jsp,他們把這個作為炫耀的資本,盲目的追逐一些膚淺的,表面的東西和名 詞,做網絡程序不懂通訊傳輸協議,做應用程序不懂中斷向量處理,這樣的技術人員,不管掌握了多少所謂的新語言,永遠不會有質的提高。
          善于總結,也是學習能力的一種體現,每次完成一個研發任務,完成一段代碼,都應當有目的的跟蹤該程序的應用狀況和用戶反饋,隨時總結,找到自己的不足,這樣逐步提高,一個程序員才可能成長起來。
          一個不具備成長性的程序員,即便眼前看是個高手,建議也不要選用,因為他落伍的時候馬上就到了。
          具備以上全部素質的人,應當說是夠格的程序員了,請注意以上的各種素質都不是由IQ決定的,也不是大學某些課本里可以學習到的,需要的僅僅是程序員對自己工作的認識,是一種意識上的問題。
          posted @ 2008-08-29 10:57 xiaoxinchen 閱讀(151) | 評論 (0)編輯 收藏
          Lucene是一個高性能的java全文檢索工具包,它使用的是倒排文件索引結構。該結構及相應的生成算法如下:

          0)設有兩篇文章1和2
          文章1的內容為:Tom lives in Guangzhou,I live in Guangzhou too.
          文章2的內容為:He once lived in Shanghai.

          1)由于lucene是基于關鍵詞索引和查詢的,首先我們要取得這兩篇文章的關鍵詞,通常我們需要如下處理措施
          a.我們現在有的是文章內容,即一個字符串,我們先要找出字符串中的所有單詞,即分詞。英文單詞由于用空格分隔,比較好處理。中文單詞間是連在一起的需要特殊的分詞處理。
          b.文章中的”in”, “once” “too”等詞沒有什么實際意義,中文中的“的”“是”等字通常也無具體含義,這些不代表概念的詞可以過濾掉
          c.用戶通常希望查“He”時能把含“he”,“HE”的文章也找出來,所以所有單詞需要統一大小寫。
          d.用戶通常希望查“live”時能把含“lives”,“lived”的文章也找出來,所以需要把“lives”,“lived”還原成“live”
          e.文章中的標點符號通常不表示某種概念,也可以過濾掉
          在lucene中以上措施由Analyzer類完成

          經過上面處理后
          文章1的所有關鍵詞為:[tom] [live] [guangzhou] [i] [live] [guangzhou]
          文章2的所有關鍵詞為:[he] [live] [shanghai]

          2) 有了關鍵詞后,我們就可以建立倒排索引了。上面的對應關系是:“文章號”對“文章中所有關鍵詞”。倒排索引把這個關系倒過來,變成:“關鍵詞”對“擁有該關鍵詞的所有文章號”。文章1,2經過倒排后變成
          關鍵詞 文章號
          guangzhou 1
          he 2
          i 1
          live 1,2
          shanghai 2
          tom 1

          通常僅知道關鍵詞在哪些文章中出現還不夠,我們還需要知道關鍵詞在文章中出現次數和出現的位置,通常有兩種位置:a)字符位置,即記錄該詞是文章 中第幾個字符(優點是關鍵詞亮顯時定位快);b)關鍵詞位置,即記錄該詞是文章中第幾個關鍵詞(優點是節約索引空間、詞組(phase)查詢 快),lucene中記錄的就是這種位置。

          加上“出現頻率”和“出現位置”信息后,我們的索引結構變為:
          關鍵詞 文章號[出現頻率] 出現位置
          guangzhou 1[2] 3,6
          he 2[1] 1
          i 1[1] 4
          live 1[2],2[1] 2,5,2
          shanghai 2[1] 3
          tom 1[1] 1

          以live 這行為例我們說明一下該結構:live在文章1中出現了2次,文章2中出現了一次,它的出現位置為“2,5,2”這表示什么呢?我們需要結合文章號和出現 頻率來分析,文章1中出現了2次,那么“2,5”就表示live在文章1中出現的兩個位置,文章2中出現了一次,剩下的“2”就表示live是文章2中第 2個關鍵字。

          以上就是lucene索引結構中最核心的部分。我們注意到關鍵字是按字符順序排列的(lucene沒有使用B樹結構),因此lucene可以用二元搜索算法快速定位關鍵詞。

          實現時 lucene將上面三列分別作為詞典文件(Term Dictionary)、頻率文件(frequencies)、位置文件 (positions)保存。其中詞典文件不僅保存有每個關鍵詞,還保留了指向頻率文件和位置文件的指針,通過指針可以找到該關鍵字的頻率信息和位置信 息。

          Lucene中使用了field的概念,用于表達信息所在位置(如標題中,文章中,url中),在建索引中,該field信息也記錄在詞典文件中,每個關鍵詞都有一個field信息(因為每個關鍵字一定屬于一個或多個field)。

          為了減小索引文件的大小,Lucene對索引還使用了壓縮技術。首先,對詞典文件中的關鍵詞進行了壓縮,關鍵詞壓縮為<前綴長度,后綴>,例 如:當前詞為“阿拉伯語”,上一個詞為“阿拉伯”,那么“阿拉伯語”壓縮為<3,語>。其次大量用到的是對數字的壓縮,數字只保存與上一個值 的差值(這樣可以減小數字的長度,進而減少保存該數字需要的字節數)。例如當前文章號是16389(不壓縮要用3個字節保存),上一文章號是16382, 壓縮后保存7(只用一個字節)。

          下面我們可以通過對該索引的查詢來解釋一下為什么要建立索引。
          假設要查詢單詞 “live”,lucene先對詞典二元查找、找到該詞,通過指向頻率文件的指針讀出所有文章號,然后返回結果。詞典通常非常小,因而,整個過程的時間是毫秒級的。
          而用普通的順序匹配算法,不建索引,而是對所有文章的內容進行字符串匹配,這個過程將會相當緩慢,當文章數目很大時,時間往往是無法忍受的。
          參考資料:http://blog.csdn.net/ladofwind/archive/2005/01/10/247403.aspx
          posted @ 2008-08-21 13:24 xiaoxinchen 閱讀(150) | 評論 (0)編輯 收藏
          僅列出標題
          共4頁: 上一頁 1 2 3 4 下一頁 
          主站蜘蛛池模板: 西充县| 汉中市| 铜梁县| 诏安县| 蒲江县| 涞源县| 双桥区| 堆龙德庆县| 林周县| 仲巴县| 克拉玛依市| 玛纳斯县| 肃北| 岚皋县| 名山县| 许昌市| 柳州市| 安徽省| 三都| 长子县| 桓仁| 长沙市| 瑞昌市| 厦门市| 朔州市| 汉中市| 洞头县| 扎鲁特旗| 秀山| 桦南县| 桃源县| 林西县| 华容县| 临夏县| 洪泽县| 衡南县| 宁远县| 若尔盖县| 读书| 富川| 吉木乃县|