基本語法¶
#set ($var=XXX)
左邊可以是以下的內(nèi)容:
- Variable reference
- String literal
- Property reference
- Method reference
- Number literal #set ($i=1)
- ArrayList #set ($arr=["yt1","t2"])
- 算術(shù)運(yùn)算符
- References 引用的類型
單行:
## this is a comment
多行:
#* this line
and this line
and this line, are comments...*#
變量 Variables¶
以 "$" 開頭,第一個(gè)字符必須為字母。character followed by a VTL Identifier. (a .. z or A .. Z).
變量可以包含的字符有以下內(nèi)容:
- 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
$與$!的區(qū)別¶
當(dāng)找不到username的時(shí)候,$username返回字符串"$username",而$!username返回空字符串""
雙引號(hào) 與 引號(hào)¶
#set ($var="helo")
則 test"$var" 返回testhello,test'$var' 返回test'$var'。
可以通過設(shè)置 stringliterals.interpolate=false改變默認(rèn)處理方式
條件語句¶
#if( $foo )
<strong>Velocity!</strong>
#end
#if($foo)
#elseif()
#else
#end
當(dāng)$foo為null或?yàn)锽oolean對(duì)象的false值執(zhí)行.
邏輯運(yùn)算符:¶
== && || !
循環(huán)語句¶
#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變量在配置文件中定義¶
- Default name of the loop counter
- variable reference.
directive.foreach.counter.name = velocityCount
- Default starting value of the loop
- counter variable reference.
directive.foreach.counter.initial.value = 1
包含文件¶
#include( "one.gif","two.txt","three.htm" )
Parse導(dǎo)入腳本¶
#parse("me.vm" )
#stop 停止執(zhí)行并返回¶
定義宏¶
Velocimacros, 相當(dāng)于函數(shù)支持包含功能:
#macro( d )
<tr><td></td></tr>
#end
調(diào)用
#d()
帶參數(shù)的宏¶
#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 應(yīng)用程序路徑,會(huì)覆蓋掉類路徑下的同名配置文件;
- Class path 類路徑,一般為缺省模板的配置,公共模板位置;
數(shù)據(jù)來源(按順序依次搜索)¶
- The value stack
- The action context
- Built-in variables
Struts2-Velocity集成的一些隱含變量¶
- stack - ValueStack自身。調(diào)用方式:${stack.findString('ognl expr')}
- action - 最新操作的action
- reponse
- request
- session
- applicaion - 獲得servlet的環(huán)境
- base - 請(qǐng)求環(huán)境的路徑
Velocity Result 輸出模板¶
模擬jsp執(zhí)行環(huán)境,使用velocity的模板直接顯示到servelet的輸出流。
location - 模板位置,沒有其它參數(shù)時(shí)的缺省配置。
parse - 默認(rèn)true ,false將不解析Ognl expressions.
配置范例:
<result name="success" type="velocity">
<param name="location">foo.vm</param>
</result>
等價(jià)于以下的配置方式:
<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 閱讀(161) |
評(píng)論 (0) |
編輯 收藏
CDN
的全稱是Content Delivery Network,即內(nèi)容分發(fā)網(wǎng)絡(luò)。其目的是通過在現(xiàn)有的Internet中增加一層新的網(wǎng)絡(luò)架構(gòu),
將網(wǎng)站的內(nèi)容發(fā)布到最接近用戶的網(wǎng)絡(luò)"邊緣", 使用戶可以就近取得所需的內(nèi)容, 解決Internet網(wǎng)絡(luò)擁擠的狀況,
提高用戶訪問網(wǎng)站的響應(yīng)速度。從技術(shù)上全面解決由于網(wǎng)絡(luò)帶寬小, 用戶訪問量大, 網(wǎng)點(diǎn)分布不均等原因所造成的用戶訪問網(wǎng)站響應(yīng)速度慢的問題。
CDN互聯(lián)網(wǎng)內(nèi)容發(fā)布網(wǎng)絡(luò)(Content Delivery Network)¶
CDN
技術(shù)是近年來在美國首先興起并迅速發(fā)展起來的一種解決互聯(lián)網(wǎng)性能不佳問題的有效手段。其基本思路就是盡可能避開互聯(lián)網(wǎng)上有可能影響數(shù)據(jù)傳輸速度和穩(wěn)定性的
瓶頸和環(huán)節(jié),使內(nèi)容傳輸?shù)母臁⒏€(wěn)。通過在網(wǎng)絡(luò)各處放置節(jié)點(diǎn)服務(wù)器所構(gòu)成的在現(xiàn)有的互聯(lián)網(wǎng)基礎(chǔ)之上的一層智能虛擬網(wǎng)絡(luò),cdn系統(tǒng)能夠?qū)崟r(shí)地根據(jù)網(wǎng)絡(luò)流
量和各節(jié)點(diǎn)的連接、負(fù)載狀況以及到用戶的距離和響應(yīng)時(shí)間等綜合信息將用戶的請(qǐng)求重新導(dǎo)向離用戶最近的服務(wù)節(jié)點(diǎn)上。
實(shí)際上,內(nèi)容分發(fā)
布網(wǎng)絡(luò)(CDN)是一種新型的網(wǎng)絡(luò)構(gòu)建方式,它是為能在傳統(tǒng)的IP網(wǎng)發(fā)布寬帶豐富媒體而特別優(yōu)化的網(wǎng)絡(luò)覆蓋層;而從廣義的角度,CDN代表了一種基于質(zhì)量
與秩序的網(wǎng)絡(luò)服務(wù)模式。簡單地說,內(nèi)容發(fā)布網(wǎng)(CDN)是一個(gè)經(jīng)策略性部署的整體系統(tǒng),包括分布式存儲(chǔ)、負(fù)載均衡、網(wǎng)絡(luò)請(qǐng)求的重定向和內(nèi)容管理4個(gè)要件,
而內(nèi)容管理和全局的網(wǎng)絡(luò)流量管理(Traffic
Management)是CDN的核心所在。通過用戶就近性和服務(wù)器負(fù)載的判斷,CDN確保內(nèi)容以一種極為高效的方式為用戶的請(qǐng)求提供服務(wù)。總的來說,內(nèi)
容服務(wù)基于緩存服務(wù)器,也稱作代理緩存(Surrogate),它位于網(wǎng)絡(luò)的邊緣,距用戶僅有"一跳"(Single
Hop)之遙。同時(shí),代理緩存是內(nèi)容提供商源服務(wù)器(通常位于CDN服務(wù)提供商的數(shù)據(jù)中心)的一個(gè)透明鏡像。這樣的架構(gòu)使得CDN服務(wù)提供商能夠代表他們
客戶,即內(nèi)容供應(yīng)商,向最終用戶提供盡可能好的體驗(yàn),而這些用戶是不能容忍請(qǐng)求響應(yīng)時(shí)間有任何延遲的。據(jù)統(tǒng)計(jì),采用CDN技術(shù),能處理整個(gè)網(wǎng)站頁面的
70%~95%的內(nèi)容訪問量,減輕服務(wù)器的壓力,提升了網(wǎng)站的性能和可擴(kuò)展性。
與目前現(xiàn)有的內(nèi)容發(fā)布模式相比較,CDN強(qiáng)調(diào)了網(wǎng)絡(luò)
在內(nèi)容發(fā)布中的重要性。通過引入主動(dòng)的內(nèi)容管理層的和全局負(fù)載均衡,CDN從根本上區(qū)別于傳統(tǒng)的內(nèi)容發(fā)布模式。在傳統(tǒng)的內(nèi)容發(fā)布模式中,內(nèi)容的發(fā)布由
ICP的應(yīng)用服務(wù)器完成,而網(wǎng)絡(luò)只表現(xiàn)為一個(gè)透明的數(shù)據(jù)傳輸通道,這種透明性表現(xiàn)在網(wǎng)絡(luò)的質(zhì)量保證僅僅停留在數(shù)據(jù)包的層面,而不能根據(jù)內(nèi)容對(duì)象的不同區(qū)分
服務(wù)質(zhì)量。此外,由于IP網(wǎng)的"盡力而為"的特性使得其質(zhì)量保證是依靠在用戶和應(yīng)用服務(wù)器之間端到端地提供充分的、遠(yuǎn)大于實(shí)際所需的帶寬通量來實(shí)現(xiàn)的。在
這樣的內(nèi)容發(fā)布模式下,不僅大量寶貴的骨干帶寬被占用,同時(shí)ICP的應(yīng)用服務(wù)器的負(fù)載也變得非常重,而且不可預(yù)計(jì)。當(dāng)發(fā)生一些熱點(diǎn)事件和出現(xiàn)浪涌流量時(shí),
會(huì)產(chǎn)生局部熱點(diǎn)效應(yīng),從而使應(yīng)用服務(wù)器過載退出服務(wù)。這種基于中心的應(yīng)用服務(wù)器的內(nèi)容發(fā)布模式的另外一個(gè)缺陷在于個(gè)性化服務(wù)的缺失和對(duì)寬帶服務(wù)價(jià)值鏈的扭
曲,內(nèi)容提供商承擔(dān)了他們不該干也干不好的內(nèi)容發(fā)布服務(wù)。
縱觀整個(gè)寬帶服務(wù)的價(jià)值鏈,內(nèi)容提供商和用戶位于整個(gè)價(jià)值鏈的兩端,中間
依靠網(wǎng)絡(luò)服務(wù)提供商將其串接起來。隨著互聯(lián)網(wǎng)工業(yè)的成熟和商業(yè)模式的變革,在這條價(jià)值鏈上的角色越來越多也越來越細(xì)分。比如內(nèi)容/應(yīng)用的運(yùn)營商、托管服務(wù)
提供商、骨干網(wǎng)絡(luò)服務(wù)提供商、接入服務(wù)提供商等等。在這一條價(jià)值鏈上的每一個(gè)角色都要分工合作、各司其職才能為客戶提供良好的服務(wù),從而帶來多贏的局面。
從內(nèi)容與網(wǎng)絡(luò)的結(jié)合模式上看,內(nèi)容的發(fā)布已經(jīng)走過了ICP的內(nèi)容(應(yīng)用)服務(wù)器和IDC這兩個(gè)階段。IDC的熱潮也催生了托管服務(wù)提供商這一角色。但
是,IDC并不能解決內(nèi)容的有效發(fā)布問題。內(nèi)容位于網(wǎng)絡(luò)的中心并不能解決骨干帶寬的占用和建立IP網(wǎng)絡(luò)上的流量秩序。因此將內(nèi)容推到網(wǎng)絡(luò)的邊緣,為用戶提
供就近性的邊緣服務(wù),從而保證服務(wù)的質(zhì)量和整個(gè)網(wǎng)絡(luò)上的訪問秩序就成了一種顯而易見的選擇。而這就是內(nèi)容發(fā)布網(wǎng)(CDN)服務(wù)模式。CDN的建立解決了困
擾內(nèi)容運(yùn)營商的內(nèi)容"集中與分散"的兩難選擇,無疑對(duì)于構(gòu)建良好的互聯(lián)網(wǎng)價(jià)值鏈?zhǔn)怯袃r(jià)值的,也是不可或缺的最優(yōu)網(wǎng)站加速服務(wù)。
目前,國內(nèi)訪問量較高的大型網(wǎng)站如新浪、網(wǎng)易等,均使用CDN網(wǎng)絡(luò)加速技術(shù),雖然網(wǎng)站的訪問巨大,但無論在什么地方訪問都會(huì)感覺速度很快。而一般的網(wǎng)站如果服務(wù)器在網(wǎng)通,電信用戶訪問很慢,如果服務(wù)器在電信,網(wǎng)通用戶訪問又很慢。
它
采取了分布式網(wǎng)絡(luò)緩存結(jié)構(gòu)(即國際上流行的web
cache技術(shù)),通過在現(xiàn)有的Internet中增加一層新的網(wǎng)絡(luò)架構(gòu),將網(wǎng)站的內(nèi)容發(fā)布到最接近用戶的cache服務(wù)器內(nèi),通過DNS負(fù)載均衡的技
術(shù),判斷用戶來源就近訪問cache服務(wù)器取得所需的內(nèi)容,解決Internet網(wǎng)絡(luò)擁塞狀況,提高用戶訪問網(wǎng)站的響應(yīng)速度,如同提供了多個(gè)分布在各地的
加速器,以達(dá)到快速、可冗余的為多個(gè)網(wǎng)站加速的目的。
CDN的特點(diǎn)¶
- 本地Cache加速 提高了企業(yè)站點(diǎn)(尤其含有大量圖片和靜態(tài)頁面站點(diǎn))的訪問速度,并大大提高以上性質(zhì)站點(diǎn)的穩(wěn)定性
- 鏡像服務(wù) 消除了不同運(yùn)營商之間互聯(lián)的瓶頸造成的影響,實(shí)現(xiàn)了跨運(yùn)營商的網(wǎng)絡(luò)加速,保證不同網(wǎng)絡(luò)中的用戶都能得到良好的訪問質(zhì)量。
- 遠(yuǎn)程加速 遠(yuǎn)程訪問用戶根據(jù)DNS負(fù)載均衡技術(shù) 智能自動(dòng)選擇Cache服務(wù)器,選擇最快的Cache服務(wù)器,加快遠(yuǎn)程訪問的速度
- 帶寬優(yōu)化 自動(dòng)生成服務(wù)器的遠(yuǎn)程Mirror(鏡像)cache服務(wù)器,遠(yuǎn)程用戶訪問時(shí)從cache服務(wù)器上讀取數(shù)據(jù),減少遠(yuǎn)程訪問的帶寬、分擔(dān)網(wǎng)絡(luò)流量、減輕原站點(diǎn)WEB服務(wù)器負(fù)載等功能。
- 集群抗攻擊 廣泛分布的CDN節(jié)點(diǎn)加上節(jié)點(diǎn)之間的智能冗于機(jī)制,可以有效地預(yù)防黑客入侵以及降低各種D.D.o.S攻擊對(duì)網(wǎng)站的影響,同時(shí)保證較好的服務(wù)質(zhì)量 。
關(guān)鍵技術(shù)¶
- 內(nèi)容發(fā)布:它借助于建立索引、緩存、流分裂、組播(Multicast)等技術(shù),將內(nèi)容發(fā)布或投遞到距離用戶最近的遠(yuǎn)程服務(wù)點(diǎn)(POP)處;
- 內(nèi)容路由:它是整體性的網(wǎng)絡(luò)負(fù)載均衡技術(shù),通過內(nèi)容路由器中的重定向(DNS)機(jī)制,在多個(gè)遠(yuǎn)程POP上均衡用戶的請(qǐng)求,以使用戶請(qǐng)求得到最近內(nèi)容源的響應(yīng);
- 內(nèi)容交換:它根據(jù)內(nèi)容的可用性、服務(wù)器的可用性以及用戶的背景,在POP的緩存服務(wù)器上,利用應(yīng)用層交換、流分裂、重定向(ICP、WCCP)等技術(shù),智能地平衡負(fù)載流量;
- 性能管理:它通過內(nèi)部和外部監(jiān)控系統(tǒng),獲取網(wǎng)絡(luò)部件的狀況信息,測(cè)量內(nèi)容發(fā)布的端到端性能(如包丟失、延時(shí)、平均帶寬、啟動(dòng)時(shí)間、幀速率等),保證網(wǎng)絡(luò)處于最佳的運(yùn)行狀態(tài)。
P4P與傳統(tǒng)CDN、P2P的對(duì)比¶
7
月30日消息:德國一個(gè)名為iPoque的研究機(jī)構(gòu)在2007年研究了一百多萬網(wǎng)民將近
3TB的匿名數(shù)據(jù)流量,調(diào)查地區(qū)包括澳大利亞、東歐、德國、中東和南歐地區(qū)。調(diào)查發(fā)現(xiàn),目前網(wǎng)絡(luò)帶寬“消費(fèi)大戶”是P2P文件共享,在中東占據(jù)了49%,
東歐地區(qū)占據(jù)了84%。從全球來看,晚上時(shí)段的網(wǎng)絡(luò)帶寬有95%被P2P占據(jù)。據(jù)國內(nèi)權(quán)威部門統(tǒng)計(jì),當(dāng)前P2P流量已經(jīng)占整個(gè)互聯(lián)網(wǎng)流量的約70%,并且
正在以每年350%的速度增長。P2P流量消耗了巨大的網(wǎng)絡(luò)帶寬,尤其是國際帶寬,使網(wǎng)絡(luò)基礎(chǔ)設(shè)施不堪重負(fù),運(yùn)營商苦不堪言。
問題
的癥結(jié)不在于P2P,而在于交換的機(jī)制。P2P過于強(qiáng)調(diào)“對(duì)等”,每個(gè)節(jié)點(diǎn)之間的交換完全是無序的。一個(gè)北京的用戶,既可能和廣州的用戶進(jìn)行文件片段的交
換,也可能和遠(yuǎn)在美國的某用戶進(jìn)行交換。顯然,無序的交換導(dǎo)致了無謂的跨地區(qū)甚至是跨國的 “流量旅行”,這耗費(fèi)了寶貴的國內(nèi)和國際帶寬資源,代價(jià)巨大。
如
果正好用戶都在同一個(gè)地區(qū),那么,本地化的交換的成本就會(huì)大大降低。這也正是P4P的簡單原理——讓P2P也玩“同城”。
P4P全稱是“Proactive network Provider Participation for
P2P(電信運(yùn)營商主動(dòng)參與P2P網(wǎng)絡(luò))”。與P2P隨機(jī)挑選Peer(對(duì)等機(jī))不同,P4P協(xié)議可以協(xié)調(diào)網(wǎng)絡(luò)拓?fù)鋽?shù)據(jù),能夠有效選擇節(jié)點(diǎn),從而提高網(wǎng)絡(luò)
路由效率。仍以上述例子來說,北京的用戶就可以優(yōu)先和北京同城的用戶來實(shí)現(xiàn)文件片段的交換,再擴(kuò)展至較遠(yuǎn)的地區(qū),有十分的必要時(shí),才會(huì)出國進(jìn)行文件片段交
換。當(dāng)然,P4P的運(yùn)行機(jī)制,要遠(yuǎn)遠(yuǎn)超過“同城交換”的概念,它還會(huì)根據(jù)用戶的上行、下載帶寬進(jìn)行綜合判斷,以進(jìn)行最有效選擇,最大化整體交換的效率。
舉
幾個(gè)例子可以說明CDN的普遍作用。例如2008年,北京奧運(yùn)會(huì)之前,關(guān)于門票網(wǎng)絡(luò)出售,很多國內(nèi)的朋友都去登陸,而大家的登錄的時(shí)刻幾乎千篇一律,導(dǎo)致
中國政府的網(wǎng)站服務(wù)器支撐不了這么大的請(qǐng)求,誰都進(jìn)去不了,都被堵死在門外。這中現(xiàn)象在國內(nèi)許多網(wǎng)站都出現(xiàn)過,比如高考時(shí)期,學(xué)生上網(wǎng)填申請(qǐng),大家都說是
自己網(wǎng)絡(luò)原因,其實(shí)不然,這都跟被請(qǐng)求的服務(wù)器有關(guān),來自四面八方的請(qǐng)求去請(qǐng)求他一個(gè)網(wǎng)站,他自然接受不了這么大的帶寬,給人一種印象,就是互聯(lián)網(wǎng)太慢,
落后了。這樣的例子很多,我們就不紛紛介紹了。不過互聯(lián)網(wǎng),網(wǎng)聚全球人的智慧。解決方法很多,美國作為世界的互聯(lián)網(wǎng)中心,提供了CDN技術(shù),內(nèi)容網(wǎng)絡(luò)分
發(fā)。美國很多軍方工程都是采用該技術(shù)。我國國內(nèi)的香港海洋科技集團(tuán)的GTONE產(chǎn)品,專業(yè)為我國國內(nèi)大型公司提供海外服務(wù),在全球都有很廣的資源。國內(nèi)很
多很有實(shí)力的公司都和他們合作了。
新建文件
posted @
2009-07-02 09:37 xiaoxinchen 閱讀(119) |
評(píng)論 (0) |
編輯 收藏
- 基本命令
- 常見文件操作
建立目錄:mkdir 目錄名
刪除空目錄:rmdir 目錄名
無條件刪除子目錄: rm -rf 目錄名
改變當(dāng)前目錄:cd 目錄名 (進(jìn)入用戶home目錄:cd ~;進(jìn)入上一級(jí)目錄:cd -)
查看自己所在目錄:pwd
查看當(dāng)前目錄大小:du
顯示目錄文件列表:ls -l (-a:增加顯示隱含目錄)
其中:藍(lán):目錄;綠:可執(zhí)行文件;紅:壓縮文件;淺藍(lán):鏈接文件;灰:其他文件;紅底白字:錯(cuò)誤的鏈接文件
瀏覽文件:more 文件名.txt;less 文件名.txt
復(fù)制文件: cp 源文件 目標(biāo)文件 (-r:包含目錄)
查找文件:(1)find (2)locate 命令名
鏈接:(1)建立hard鏈接:ln 來源文件 鏈接文件(-d:創(chuàng)建目錄鏈接);(2)建立符號(hào)鏈接:ln -s 來源文件 鏈接文件
文本編碼轉(zhuǎn)換工具iconv:iconv -f gb2312 -t utf-8 -o new.txt old.txt
輸入/輸出格式規(guī)范
-f, --from-code=NAME 原始文本編碼,
-t,--to-code=NAME 輸出編碼,信息
-l, --list 列出所有已知編碼字符集
輸出控制:
-c 忽略輸出中的無效字符
-o, --output=FILE 輸出文件
-s, --silent suppress warnings
# 進(jìn)程管理
列出當(dāng)前進(jìn)程ID:ps -auxw
終止進(jìn)程:(1)終止單一進(jìn)程:kill 進(jìn)程ID號(hào)
終止該程序所有進(jìn)程:killall 程序名
終止X-Window程序:xkill
查看資源占用情況:(1)top (2)free (3)dmesg
查看環(huán)境變量值:env
重啟:(1)reboot (2)Ctrl Alt Del (3)init 6
關(guān)機(jī):(1)shutdown -h now (2)halt (3)init 0
# 網(wǎng)絡(luò)管理
顯示網(wǎng)絡(luò)接口參數(shù):ifconfig
聯(lián)機(jī)狀況:ping xxx.xxx.xxx.xxx
顯示網(wǎng)絡(luò)狀況:netstat ,其中:options:-a==所有sockets;-l==包含網(wǎng)絡(luò)設(shè)備;-n==數(shù)字IP;-o==其他信息;-r==路由表;-t==只列TCP sockets;-u==只列UDP sockets;-w==只列raw sockets;
-x==只列Unix Domain sockets
# 權(quán)限設(shè)定
(1)chmod -a|u|g|o |-|=r|w|x 文件/目錄名
其中:a--所有用戶(all);u--本用戶(user);g--用戶組(group);o--其他用戶(other users)
--增加權(quán)限;---刪除權(quán)限;=--設(shè)置權(quán)限
文件:r--只讀權(quán)限(read);w--寫權(quán)限(write);x--執(zhí)行權(quán)限(execute)
目錄:r--允許列目錄下文件和子目錄;w--允許生成和刪除目錄下文件;x--允許訪問該目錄
(2)chmod xxx 文件/目錄名
其中:execute=1;write=2;read=4
x取值:0--沒有任何權(quán)限(常用);1--只能執(zhí)行(不常見);2--只能寫(不常見);3--只能寫和執(zhí)行(不常見);4--只讀(常見);5--只讀和執(zhí)行(常見);6--讀和寫(常見);7--讀.寫和執(zhí)行
# vim 常見命令
進(jìn)入后為命令模式:(1)插入i;(2)打開0;(3)修改c;(4)取代r;(5)替換s
經(jīng)(1)后進(jìn)入全屏幕編輯模式。
命令模式-->編輯模式(a/i);編輯模式-->命令模式(Esc);命令模式-->末行模式(:)。
:w/w newfile保存
:q/q!退出iv;:wq保存退出
http://vimcdoc.sourceforge.net/doc/help.html
#ln命令
ln 命令
用途 : 鏈接文件。
語法
1>將某個(gè)文件鏈接到一個(gè)文件上
ln [ -f | -n] [ -s ] SourceFile [ TargetFile ]
2>將一個(gè)或多個(gè)文件鏈接到一個(gè)目錄上
ln [ -f | -n] [ -s ] SourceFile ... TargetDirectory
描述
ln 命令將在 SourceFile 參數(shù)中指定的文件鏈接到在 TargetFile 參數(shù)中指定的文件,或?qū)⑵滏溄拥皆?TargetDirectory 參數(shù)中指定的另一個(gè)目錄中的文件。
在缺省情況下,ln 命令會(huì)創(chuàng)建硬鏈接。如果需要使用 ln 命令來創(chuàng)建符號(hào)鏈接,請(qǐng)指明 -s 標(biāo)志。
符號(hào)鏈接是指向文件的一個(gè)間接指針;它的目錄項(xiàng)中包含了它所鏈接的文件名。符號(hào)鏈接可能會(huì)跨越文件系統(tǒng),可能指向目錄。
如果正在將某個(gè)文件鏈接到新的名字,那么只能列出一個(gè)文件。如果鏈接到一個(gè)目錄,那么可以列出多個(gè)文件。
TargetFile 參數(shù)是可選的。
如果不指定目標(biāo)文件,ln 命令會(huì)在當(dāng)前的目錄中創(chuàng)建一個(gè)新的文件。新的文件繼承了指定在 SourceFile 參數(shù)中的文件名。
注意:
如果不使用 -s 標(biāo)志,就不能在文件系統(tǒng)之間鏈接文件。
如果 TargetDirectory 已經(jīng)是鏈接到目錄上的一個(gè)符號(hào)鏈接,那么 ln 命令將現(xiàn)有的目標(biāo)視為文件。
這意味著,類似于 ln -fs somepath/lname symdir 的命令不會(huì)遵循現(xiàn)有的 symdir 符號(hào)鏈接,作為代替,它會(huì)創(chuàng)建一個(gè)從 somepath/lname 到 symdir 的新的符號(hào)鏈接。
參數(shù)
-f 促使 ln 命令替換掉任何已經(jīng)存在的目的路徑。如果目的路徑已經(jīng)存在,而沒有指定 -f 標(biāo)志,ln 命令不會(huì)創(chuàng)建新的鏈接,而是向標(biāo)準(zhǔn)錯(cuò)誤寫一條診斷消息并繼續(xù)鏈接剩下的 SourceFiles。
-n 指定,如果鏈接是一個(gè)現(xiàn)有的文件,那么不要覆蓋文件的內(nèi)容。 -f 標(biāo)志重設(shè)了這個(gè)標(biāo)志。這是缺省的行為。
-s
促使 ln 命令創(chuàng)建符號(hào)鏈接。符號(hào)鏈接中包含了它所鏈接的文件的名字。當(dāng)對(duì)鏈接執(zhí)行打開操作的時(shí)候,會(huì)使用到引用文件。對(duì)符號(hào)鏈接的 stat
調(diào)用會(huì)返回鏈接的目標(biāo)文件;必須完成lstat 調(diào)用來獲取鏈接的信息。可以使用 readlink
調(diào)用來讀取符號(hào)鏈接的內(nèi)容。符號(hào)鏈接可能跨越文件系統(tǒng),指向目錄。
注意:當(dāng)為 -s 標(biāo)志指定 SourceFile 參數(shù)的時(shí)候,必須使用絕對(duì)路徑。如果沒有指明絕對(duì)路徑,那么當(dāng) SourceFile 和 TargetFile 參數(shù)位于不同的目錄中的時(shí)候,可能會(huì)發(fā)生意外的結(jié)果。在創(chuàng)建符號(hào)鏈接之前,不需要存在源文件。
退出狀態(tài)
此命令返回以下的退出值:
0 所有指定的文件都成功鏈接上了。
0 出現(xiàn)一次錯(cuò)誤。
示例
1>為了創(chuàng)建到一個(gè)文件的另一個(gè)鏈接(別名),請(qǐng)輸入:
ln
-f file1 file2
這會(huì)將 file1 鏈接到新的名稱, file2。如果 file2 不存在,那么會(huì)創(chuàng)建該文件名。如果 file2
已經(jīng)存在了,那么這個(gè)文件會(huì)被替換為指向 file1的一個(gè)鏈接。然后 file1 和 file2
文件名會(huì)指向同一個(gè)文件。對(duì)其中任何一個(gè)的更改都會(huì)出現(xiàn)在另一個(gè)中。如果一個(gè)文件名被 rm
命令刪除,那么該文件并沒有完全被刪除,因?yàn)樗匀灰云渌拿执嬖凇?/p>
2>為了將文件鏈接為另一個(gè)目錄中的相同名字,請(qǐng)輸入:
ln index dir1
這會(huì)將 index 鏈接到新的名稱,dir1/index。
注意:在示例 1 中的 file2 是一個(gè)文件的名稱;在示例 2 中的 dir1 是一個(gè)已經(jīng)存在的目錄。
3>為了將幾個(gè)文件鏈接為另一個(gè)目錄中的名稱,請(qǐng)輸入:
ln file2 dir2/file3 /home/dir1
這會(huì)將 file2 鏈接到新的名稱 /home/dir1/file2;將 dir2/file3 鏈接到新的名稱 /home/dir1/file3。
4>如果想要在 ln 命令中使用模式匹配字符,請(qǐng)輸入:
ln dir1/* .
這會(huì)將 dir1 目錄中的所有文件鏈接到當(dāng)前目錄中, . (點(diǎn)),給他們?cè)?dir1 目錄中同樣的名稱。
注意: 必須在星號(hào)和句點(diǎn)之間輸入一個(gè)空格。
5>為了創(chuàng)建一個(gè)符號(hào)鏈接,輸入:
ln -s /tmp/test test
這會(huì)在當(dāng)前的目錄中創(chuàng)建符號(hào)鏈接 test。 test 文件指向 /tmp/test 文件。如果 /tmp/test 文件已經(jīng)存在了,那么 cat test 命令可以列出其內(nèi)容。
6>如果想要在不指明 TargetFile 參數(shù)的情況下得到相同的結(jié)果,請(qǐng)輸入:
ln -s /tmp/test
文件
/usr/bin/ln 包含了 ln 命令。
- 常見配置文件
posted @
2009-07-02 09:37 xiaoxinchen 閱讀(126) |
評(píng)論 (0) |
編輯 收藏
不用安裝,直接解壓即可。如果進(jìn)行JEE開發(fā),可以用eclipse-jee-ganymede-SR2文件,而PHP的話可以直接用PDT。Python可以用基于Apanta的PyDev。
基本操作¶
選項(xiàng):Windows -> Preference。
安裝新特性/插件:Help -> SoftwareUpdates
常用快捷鍵¶
快捷鍵的設(shè)置和修改在Windows -> Preference ->General -> Keys;
我最常用的:
Ctrl+Space 代碼助手完成一些代碼的插入(但一般和輸入法有沖突,可以Alt+/來代替,在keys里找到command 為Content
Assist的,把其Binding改為Alt+/)
這個(gè)是我最喜歡的功能,你可以把變量命名的很長,下次引用時(shí)只要打首個(gè)字母,再打Alt+/,就能寫出變量。
Ctrl+Q 定位到最后編輯的地方
Ctrl+Shift+R 全局 打開資源
Ctrl+E 快速顯示當(dāng)前Editer的下拉列表(如果當(dāng)前頁面沒有顯示的用黑體表示)
Java編輯器 組織導(dǎo)入 Ctrl+Shift+O
Java編輯器 添加導(dǎo)入 Ctrl+Shift+M
Alt+← 前一個(gè)編輯的頁面
Alt+→ 下一個(gè)編輯的頁面(當(dāng)然是針對(duì)上面那條來說了)
Ctrl+1 快速修復(fù)
Ctrl+/ 注釋當(dāng)前行,再按則取消注釋
Ctrl+D: 刪除當(dāng)前行
Java編輯器 格式化 Ctrl+Shift+F
Alt+↓ 當(dāng)前行和下面一行交互位置(特別實(shí)用,可以省去先剪切,再粘貼了)
Alt+↑ 當(dāng)前行和上面一行交互位置(同上)
Ctrl+L 定位在某行 (對(duì)于程序超過100的人就有福音了)
Alt+Shift+R 重命名 (是我自己最愛用的一個(gè)了,尤其是變量和類的Rename,比手工方法能節(jié)省很多勞動(dòng)力)
Alt+Shift+Z 使用try/catch塊來包圍
下面是網(wǎng)上轉(zhuǎn)過來
Eclipse快捷鍵大全(轉(zhuǎn)載)
Ctrl+1 快速修復(fù)(最經(jīng)典的快捷鍵,就不用多說了)
Ctrl+D: 刪除當(dāng)前行
Ctrl+Alt+↓ 復(fù)制當(dāng)前行到下一行(復(fù)制增加)
Ctrl+Alt+↑ 復(fù)制當(dāng)前行到上一行(復(fù)制增加)
Alt+↓ 當(dāng)前行和下面一行交互位置(特別實(shí)用,可以省去先剪切,再粘貼了)
Alt+↑ 當(dāng)前行和上面一行交互位置(同上)
Alt+← 前一個(gè)編輯的頁面
Alt+→ 下一個(gè)編輯的頁面(當(dāng)然是針對(duì)上面那條來說了)
Alt+Enter 顯示當(dāng)前選擇資源(工程,or 文件 or文件)的屬性
Shift+Enter 在當(dāng)前行的下一行插入空行(這時(shí)鼠標(biāo)可以在當(dāng)前行的任一位置,不一定是最后)
Shift+Ctrl+Enter 在當(dāng)前行插入空行(原理同上條)
Ctrl+Q 定位到最后編輯的地方
Ctrl+L 定位在某行 (對(duì)于程序超過100的人就有福音了)
Ctrl+M 最大化當(dāng)前的Edit或View (再按則反之)
Ctrl+/ 注釋當(dāng)前行,再按則取消注釋
Ctrl+O 快速顯示 OutLine
Ctrl+T 快速顯示當(dāng)前類的繼承結(jié)構(gòu)
Ctrl+W 關(guān)閉當(dāng)前Editer
Ctrl+K 參照選中的Word快速定位到下一個(gè)
Ctrl+E 快速顯示當(dāng)前Editer的下拉列表(如果當(dāng)前頁面沒有顯示的用黑體表示)
Ctrl+/(小鍵盤) 折疊當(dāng)前類中的所有代碼
Ctrl+×(小鍵盤) 展開當(dāng)前類中的所有代碼
Ctrl+Space 代碼助手完成一些代碼的插入(但一般和輸入法有沖突,可以修改輸入法的熱鍵,也可以暫用Alt+/來代替)
Ctrl+Shift+E 顯示管理當(dāng)前打開的所有的View的管理器(可以選擇關(guān)閉,激活等操作)
Ctrl+J 正向增量查找(按下Ctrl+J后,你所輸入的每個(gè)字母編輯器都提供快速匹配定位到某個(gè)單詞,如果沒有,則在stutes line中顯示沒有找到了,查一個(gè)單詞時(shí),特別實(shí)用,這個(gè)功能Idea兩年前就有了)
Ctrl+Shift+J 反向增量查找(和上條相同,只不過是從后往前查)
Ctrl+Shift+F4 關(guān)閉所有打開的Editer
Ctrl+Shift+X 把當(dāng)前選中的文本全部變味小寫
Ctrl+Shift+Y 把當(dāng)前選中的文本全部變?yōu)樾?br />
Ctrl+Shift+F 格式化當(dāng)前代碼
Ctrl+Shift+P 定位到對(duì)于的匹配符(譬如{}) (從前面定位后面時(shí),光標(biāo)要在匹配符里面,后面到前面,則反之)
下面的快捷鍵是重構(gòu)里面常用的,本人就自己喜歡且常用的整理一下(注:一般重構(gòu)的快捷鍵都是Alt+Shift開頭的了)
Alt+Shift+R 重命名 (是我自己最愛用的一個(gè)了,尤其是變量和類的Rename,比手工方法能節(jié)省很多勞動(dòng)力)
Alt+Shift+M 抽取方法 (這是重構(gòu)里面最常用的方法之一了,尤其是對(duì)一大堆泥團(tuán)代碼有用)
Alt+Shift+C 修改函數(shù)結(jié)構(gòu)(比較實(shí)用,有N個(gè)函數(shù)調(diào)用了這個(gè)方法,修改一次搞定)
Alt+Shift+L 抽取本地變量( 可以直接把一些魔法數(shù)字和字符串抽取成一個(gè)變量,尤其是多處調(diào)用的時(shí)候)
Alt+Shift+F 把Class中的local變量變?yōu)閒ield變量 (比較實(shí)用的功能)
Alt+Shift+I 合并變量(可能這樣說有點(diǎn)不妥Inline)
Alt+Shift+V 移動(dòng)函數(shù)和變量(不怎么常用)
Alt+Shift+Z 重構(gòu)的后悔藥(Undo)
編輯
作用域 功能 快捷鍵
全局 查找并替換 Ctrl+F
文本編輯器 查找上一個(gè) Ctrl+Shift+K
文本編輯器 查找下一個(gè) Ctrl+K
全局 撤銷 Ctrl+Z
全局 復(fù)制 Ctrl+C
全局 恢復(fù)上一個(gè)選擇 Alt+Shift+↓
全局 剪切 Ctrl+X
全局 快速修正 Ctrl1+1
全局 內(nèi)容輔助 Alt+/
全局 全部選中 Ctrl+A
全局 刪除 Delete
全局 上下文信息 Alt+?
Alt+Shift+?
Ctrl+Shift+Space
Java編輯器 顯示工具提示描述 F2
Java編輯器 選擇封裝元素 Alt+Shift+↑
Java編輯器 選擇上一個(gè)元素 Alt+Shift+←
Java編輯器 選擇下一個(gè)元素 Alt+Shift+→
文本編輯器 增量查找 Ctrl+J
文本編輯器 增量逆向查找 Ctrl+Shift+J
全局 粘貼 Ctrl+V
全局 重做 Ctrl+Y
查看
作用域 功能 快捷鍵
全局 放大 Ctrl+=
全局 縮小 Ctrl+-
窗口
作用域 功能 快捷鍵
全局 激活編輯器 F12
全局 切換編輯器 Ctrl+Shift+W
全局 上一個(gè)編輯器 Ctrl+Shift+F6
全局 上一個(gè)視圖 Ctrl+Shift+F7
全局 上一個(gè)透視圖 Ctrl+Shift+F8
全局 下一個(gè)編輯器 Ctrl+F6
全局 下一個(gè)視圖 Ctrl+F7
全局 下一個(gè)透視圖 Ctrl+F8
文本編輯器 顯示標(biāo)尺上下文菜單 Ctrl+W
全局 顯示視圖菜單 Ctrl+F10
全局 顯示系統(tǒng)菜單 Alt+-
導(dǎo)航
作用域 功能 快捷鍵
Java編輯器 打開結(jié)構(gòu) Ctrl+F3
全局 打開類型 Ctrl+Shift+T
全局 打開類型層次結(jié)構(gòu) F4
全局 打開聲明 F3
全局 打開外部javadoc Shift+F2
全局 打開資源 Ctrl+Shift+R
全局 后退歷史記錄 Alt+←
全局 前進(jìn)歷史記錄 Alt+→
全局 上一個(gè) Ctrl+,
全局 下一個(gè) Ctrl+.
Java編輯器 顯示大綱 Ctrl+O
全局 在層次結(jié)構(gòu)中打開類型 Ctrl+Shift+H
全局 轉(zhuǎn)至匹配的括號(hào) Ctrl+Shift+P
全局 轉(zhuǎn)至上一個(gè)編輯位置 Ctrl+Q
Java編輯器 轉(zhuǎn)至上一個(gè)成員 Ctrl+Shift+↑
Java編輯器 轉(zhuǎn)至下一個(gè)成員 Ctrl+Shift+↓
文本編輯器 轉(zhuǎn)至行 Ctrl+L
搜索
作用域 功能 快捷鍵
全局 出現(xiàn)在文件中 Ctrl+Shift+U
全局 打開搜索對(duì)話框 Ctrl+H
全局 工作區(qū)中的聲明 Ctrl+G
全局 工作區(qū)中的引用 Ctrl+Shift+G
文本編輯
作用域 功能 快捷鍵
文本編輯器 改寫切換 Insert
文本編輯器 上滾行 Ctrl+↑
文本編輯器 下滾行 Ctrl+↓
文件
作用域 功能 快捷鍵
全局 保存 Ctrl+X
Ctrl+S
全局 打印 Ctrl+P
全局 關(guān)閉 Ctrl+F4
全局 全部保存 Ctrl+Shift+S
全局 全部關(guān)閉 Ctrl+Shift+F4
全局 屬性 Alt+Enter
全局 新建 Ctrl+N
項(xiàng)目
作用域 功能 快捷鍵
全局 全部構(gòu)建 Ctrl+B
源代碼
作用域 功能 快捷鍵
Java編輯器 格式化 Ctrl+Shift+F
Java編輯器 取消注釋 Ctrl+\
Java編輯器 注釋 Ctrl+/
Java編輯器 添加導(dǎo)入 Ctrl+Shift+M
Java編輯器 組織導(dǎo)入 Ctrl+Shift+O
Java編輯器 使用try/catch塊來包圍 未設(shè)置,太常用了,所以在這里列出,建議自己設(shè)置。
也可以使用Ctrl+1自動(dòng)修正。
運(yùn)行
作用域 功能 快捷鍵
全局 單步返回 F7
全局 單步跳過 F6
全局 單步跳入 F5
全局 單步跳入選擇 Ctrl+F5
全局 調(diào)試上次啟動(dòng) F11
全局 繼續(xù) F8
全局 使用過濾器單步執(zhí)行 Shift+F5
全局 添加/去除斷點(diǎn) Ctrl+Shift+B
全局 顯示 Ctrl+D
全局 運(yùn)行上次啟動(dòng) Ctrl+F11
全局 運(yùn)行至行 Ctrl+R
全局 執(zhí)行 Ctrl+U
重構(gòu)
作用域 功能 快捷鍵
全局 撤銷重構(gòu) Alt+Shift+Z
全局 抽取方法 Alt+Shift+M
全局 抽取局部變量 Alt+Shift+L
全局 內(nèi)聯(lián) Alt+Shift+I
全局 移動(dòng) Alt+Shift+V
全局 重命名 Alt+Shift+R
全局 重做 Alt+Shift+Y
檢出項(xiàng)目¶
首先安裝SVN插件(subversive或者subclipse),然后新建Project,從SVN檢出項(xiàng)目。需要特別注意的是,要在general / workspace選項(xiàng)中正確設(shè)置字符編碼,否則可能會(huì)出現(xiàn)編譯錯(cuò)誤。
用Maven構(gòu)建項(xiàng)目¶
安裝IAM之后,在項(xiàng)目的context菜單中選“Maven 2 / Use Maven Dependency Management”,然后就可以管理依賴。
查看數(shù)據(jù)庫¶
打開 Database Perspective 即可。注意要先選擇驅(qū)動(dòng)程序,即mysql的java connector的jar,然后才是配置各個(gè)連接的jdbc地址。
關(guān)于插件¶
插件安裝方法(zz)¶
英文教程:http://www.venukb.com/2006/08/20/install-eclipse-plugins-the-easy-way/
有關(guān)插件安裝問題,四種常用的方法在此特別注明:
#“幫助”->“軟件更新”->“查找并安裝”->“搜索要安裝的新功能部件”->“新建遠(yuǎn)程站點(diǎn)”(此種方式用于在線更新)
#“幫助”->“軟件更新”->“查找并安裝”->“搜索要安裝的新功能部件”->“新建本地站點(diǎn)”(如果插件已經(jīng)下載到了本地,請(qǐng)不要用第一種方法)
- 直接拷貝plugins和features兩個(gè)目錄下的內(nèi)容置于$Eclipse_Home$/對(duì)應(yīng)的plugins和features下面
- 用link外鏈接與外部插件關(guān)聯(lián)
最菜的,一般用第一種方法,而大部分生手一般選擇第二或者第三種方法,用得習(xí)慣的一般選擇最后一種方式。此四類方法優(yōu)劣勢(shì)對(duì)比如下:
前三種方法都會(huì)將插件文件拷貝至相$Eclipse_Home$/對(duì)應(yīng)的plugins和features目錄下,從本質(zhì)上看,沒多大區(qū)別,并且插件只能
安裝和禁用,不能卸載(當(dāng)然,如果你對(duì)插件對(duì)應(yīng)的目錄和文件都很熟悉的話,可以通過直接刪除拷進(jìn)去的文件來達(dá)到卸載插件的目的),但方法一和方法二在安裝
插件的時(shí)候很容易出錯(cuò)或者是產(chǎn)生沖突,特別是當(dāng)你用了Myeclipse插件、中文包的同時(shí),又想安裝HibernateSynchronizer、
Jode Compiler(Class反編譯工具)、Visual Editor等插件時(shí),及有可能導(dǎo)致Myeclipse插件和中文包失效。
所以,如果插件已經(jīng)下載到了本地,請(qǐng)直接拷貝至$Eclipse_Home$/對(duì)應(yīng)的plugins和features目錄下,也就是用方法三,這樣能避免沖突。
方
法四是將所有的插件用一個(gè)外部目錄存放起來,假如是D:\plug-in,將上面所示的插件目錄文件全部拷貝到該目錄下,比如Tomcat插件,此時(shí)的文
件路徑就是D:\plug-in\tomcat_plug\eclipse\plugins
\com.sysdeo.eclipse.tomcat_3.1.0.beta(請(qǐng)注意,方法四一定要嚴(yán)格這樣的目錄路徑放置文件)。然后
在$Eclipse_Home$下新建一個(gè)links目錄,并在links目錄下建立關(guān)聯(lián)文件,假如是tomcat.link,在建立的關(guān)聯(lián)文件中加入如
下語句:
path=D:/plug-in/tomcat_plug
還可以寫成相對(duì)路徑的形式。剩下的事情,不用我說你肯定都知道了,就是重啟Eclipse,在Dos窗口下進(jìn)入Eclipse安
裝目錄,鍵入命令eclipse
-clean,回車,或者進(jìn)入$Eclipse_Home$/configuration目錄,刪除org.eclipse.update后再重新啟動(dòng)
Eclipse。
QA相關(guān)插件¶
參考: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 閱讀(269) |
評(píng)論 (0) |
編輯 收藏
Web標(biāo)準(zhǔn)¶
我理解的Web標(biāo)準(zhǔn)
web標(biāo)準(zhǔn)就是瀏覽器的開發(fā)廠商和界面開發(fā)人員共同遵循的標(biāo)準(zhǔn)。由萬維網(wǎng)聯(lián)盟W3C(World Wide Web Consortium)組織制定。
Web標(biāo)準(zhǔn)化無異于工業(yè)標(biāo)準(zhǔn)化,就好像改錐和螺絲一樣,他們都遵循同樣的標(biāo)準(zhǔn),易用,有效,甚至能贏得戰(zhàn)爭(注1)。
遵循Web標(biāo)準(zhǔn)的好處
- 高效率。開發(fā)人員可以更容易地理解彼此的編碼,web開發(fā)的團(tuán)隊(duì)協(xié)作將得到簡化。
- 易用性。大家都遵循標(biāo)準(zhǔn),未來也許就不存在跨瀏覽器問題,也可以跨平臺(tái)(比如移動(dòng)電話),另外,標(biāo)準(zhǔn)也可以使殘疾人士更容易地使用web。
- 利于訪問。更易被搜索引擎訪問,也更易被準(zhǔn)確地索引。
注1:德國的工業(yè)非常發(fā)達(dá),二戰(zhàn)時(shí)德國設(shè)計(jì)的武器都是標(biāo)準(zhǔn)件,即使一輛趟克被炸爛,其中的零件都還可以再利用,甚至可以應(yīng)用到槍支或其他武器上。
Acid3¶
測(cè)試瀏覽器支持Acid3的程度:http://acid3.acidtests.org/
為什么要使用Web標(biāo)準(zhǔn)(zz)?¶
英文版:http://www.webstandards.org/learn/faq/
中文版:http://www.webstandards.org/learn/faq/faq_zh-simplified/
posted @
2009-07-02 09:35 xiaoxinchen 閱讀(109) |
評(píng)論 (0) |
編輯 收藏
快速入門
歡迎使用BeanShell.這是一個(gè)速成課程。我們將省去一些重要的選項(xiàng)和細(xì)節(jié)。要學(xué)習(xí)更多的內(nèi)容請(qǐng)看本User's Guide的其它部分。
下載和運(yùn)行BeanShell
請(qǐng)到http://www.beanshell.org下載最新的JAR文件。你可以用圖形桌面模式和命令行模式起動(dòng)BeanShell。
如果你只是要玩一玩BeanShell,你可以在BeanShell的jar文件上雙擊來起動(dòng)BeanShell的桌面。但不管怎樣,如果你要讓BeanShell與你的類與應(yīng)用程序一起工作就必須將BeanShell的jar文件加到classpath中。
你可以將BeanShell的jar文件拖到JAVA_HOME的ext目錄也可以直接加到classpath中。
- windows用戶請(qǐng)將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
然后你就可以運(yùn)行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
可以在你的應(yīng)用程序內(nèi)部來運(yùn)行,也可以作為debug及servlet的遠(yuǎn)程服務(wù)器模式,或一個(gè)Applet內(nèi)部來運(yùn)行BeanShell。請(qǐng)參考"BeanShell Modes of Operation"獲得更多詳情。
BeanShell GUI
用GUI模式啟動(dòng)BeanShell后,將打開一個(gè)桌面視窗。用鼠標(biāo)右擊在桌面的背景上,你可以打開另一個(gè)控制臺(tái)視窗及其它的工具如一個(gè)簡單的類游覽器。
每一個(gè)控制臺(tái)視窗運(yùn)行一個(gè)獨(dú)立的BeanShell解釋器。這個(gè)圖形化的控制臺(tái)支持基本的歷史命令,行編輯,剪切和粘貼,甚至類和變量名的自動(dòng)完成功能。從控制臺(tái)你能開啟一個(gè)簡單的編輯視窗。在它里面,你可以編寫腳本和使用‘eval’選項(xiàng)求表達(dá)式的值。
Java語句和表達(dá)式
BeanShell能理解標(biāo)準(zhǔn)的JAVA語句,表達(dá)式,和方法宣告。語句和表達(dá)式的內(nèi)容可以是:變量,宣告,賦值,方法調(diào)用,循環(huán),條件等。
在
Java程序中你必須嚴(yán)格的使用它們,但在BeanShell中,你可以用“寬松類型”(loosely
typed)的方式來使用它們。也就是說,你可以在寫腳本時(shí)偷懶,不進(jìn)行變量類型的宣告(在原始數(shù)據(jù)類型和對(duì)象都可以)。如果你試著用錯(cuò)變量類
型,BeanShell將會(huì)給出一個(gè)錯(cuò)誤。
這里有一些例子:
- 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命令
在
剛才那個(gè)例子中我們用了一個(gè)內(nèi)建在BeanShell中的一個(gè)方便的命令print(),來顯示變量的值。print()跟ava的
System.out.println()非常的相像,除非它能保證輸出總是命令行。print()也可以顯示一些對(duì)象的類型(如數(shù)組),但比Java的
更詳細(xì)。另一個(gè)相關(guān)的命令是show(),用來開啟與關(guān)閉顯示你輸入的每一行的結(jié)果。
這兒是一些其它的BeanShell的命令:
source(), run() - 將一個(gè)bsh腳本讀到解釋器或運(yùn)行在另一個(gè)解釋器。
frame() - 顯示一個(gè)Frame或JFrame的GUI組件.
load(), save() - 載入和保存一個(gè)序列化的對(duì)象到一個(gè)文件.
cd(), cat(), dir(), pwd(), etc. - 類unix的shell命令。
exec() - 運(yùn)行一個(gè)本地的程序。
javap() - 打印一個(gè)對(duì)象的方法和字段,類似于Java的javap命令。
setAccessibility() - 開啟無限制的存取private 和protected的組件。
要獲得更多的信息請(qǐng)查看BeanShell命令的詳細(xì)清單。
提示:
BeanShell命令并不是真的"內(nèi)建"其中的,而是作為腳本方法自動(dòng)從classpath載入的. 你可以擴(kuò)展基本命令集并加到classpath中作為自訂義的腳本來使用。
腳本方法
你可以在bsh中宣告和使用方法,就像在java的類中一樣。
- int addTwoNumbers( int a, int b ) {
return a + b;
}
sum = addTwoNumbers( 5, 7 ); // 12
bsh的方法可以有動(dòng)態(tài)的(寬松的)參數(shù)和返回類型。
- add( a, b ) {
return a + b;
}
foo = add(1, 2); // 3
foo = add("Oh", " baby"); // "Oh baby"
實(shí)現(xiàn)Interface
注意:如果要BeanShell能實(shí)現(xiàn)任意的Interface,必須有jdk1.3及以上支持。
你可以在腳本中用標(biāo)準(zhǔn)的Java內(nèi)部類的語法來實(shí)現(xiàn)Interface.例如:
- ActionListener scriptedListener = new ActionListener() {
actionPerformed( event ) { ... }
}
你
可以不用實(shí)現(xiàn)Interface的所有方法,而只用實(shí)現(xiàn)你需要的方法。如果代碼中調(diào)用了未被實(shí)現(xiàn)的方法,將丟出異常。如果你想重載大量的方法的行為--例
如為日志生成一個(gè)"啞"適配器--你可以在腳本對(duì)象中實(shí)現(xiàn)一個(gè)特殊的方法:invoke(name,args)。invoke()方法用來處理任何未被定
義的方法的調(diào)用:
- ml = new MouseListener() {
mousePressed( event ) { ... }
// handle the rest
invoke( name, args ) { print("Method: "+name+" invoked!");
}
腳本對(duì)象
在
BeanShell中,和在JavaScript與Perl中一樣,腳本對(duì)象是用封閉的方法體一構(gòu)成的。通過在方法未尾返回一個(gè)特殊值"this",你就
可以像使用方法一樣調(diào)用這個(gè)對(duì)象了。在這個(gè)方法調(diào)用時(shí),你可以給與它任何的值。通常對(duì)象內(nèi)部需要包括方法,所以BeanShell的腳本方法在一定程度上
可再包含一些方法以構(gòu)成腳本對(duì)象。例如:
- foo() {
print("foo");
x=5;
bar() {
print("bar");
}
return this;
}
myfoo = foo(); // prints "foo"
print( myfoo.x ); // prints "5"
myfoo.bar(); // prints "bar"
如果這些代碼對(duì)你來說很陌生,別急,請(qǐng)用戶手冊(cè)可得到更透徹的解釋。
在
你的腳本中,BeanShell腳本對(duì)象(也就是先前例子中的"this"參照)能自動(dòng)實(shí)現(xiàn)任何JAVA介面類型。當(dāng)JAVA代碼調(diào)用相應(yīng)與之通訊的腳本
方法內(nèi)的方法。當(dāng)你試著將腳本對(duì)象作為參數(shù)傳給Java方法時(shí),BeanShell會(huì)自動(dòng)將它造型(cast)為相應(yīng)的類型。如要傳遞BeanShell
外部的對(duì)象時(shí),你可以在需要時(shí)顯式的進(jìn)行造型(cast).請(qǐng)看用戶手冊(cè)中的詳細(xì)內(nèi)容。
從你的應(yīng)用程序調(diào)用BeanShell
通過建立一個(gè)BeanShell解釋器,使用eval()或source()命令,你可以在你的應(yīng)用程序中求文本表達(dá)式的值和運(yùn)行腳本。如果你希望在你的腳本內(nèi)部使用一個(gè)對(duì)象,可以用set()方法傳遞對(duì)象的變量參照給BeanShell,并通過get()方法取得結(jié)果。
- 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平臺(tái)上的第三種編程語言
|
2005-06-08 點(diǎn)擊:8 來源:CSDN 作者:CSDN |
JCP接納了一個(gè)新的技術(shù)規(guī)范進(jìn)入標(biāo)準(zhǔn)化進(jìn)程,這個(gè)編號(hào)為JSR-274的技術(shù)規(guī)范將把BeanShell引入為Java平臺(tái)上支持的又一種編程語言。
JSR-
274(http://jcp.org/en/jsr/detail?id=274)是由 Patrick
Niemeyer提交的技術(shù)規(guī)范,其目標(biāo)是將BeanShell腳本語言(http://www.beanshell.org/)規(guī)范化為Java虛擬機(jī)
平臺(tái)上支持的第三種編程語言。除了Java之外,Java虛擬機(jī)還支持Groovy腳本語言。Doug
Lea、Apache和Google三個(gè)JCP執(zhí)委會(huì)成員對(duì)此規(guī)范表示了支持。
按照J(rèn)ava最初的設(shè)計(jì)思路,有很多語言都可以在JVM上
運(yùn)行(詳細(xì)列表參見http://en.wikipedia.org/wiki/List_of_Java_scripting_languages),
但這些語言大多沒有流行起來。直到2004年為止,Java平臺(tái)事實(shí)上只有一種編程語言,也就是Java。2004年3月,Groovy(JSR-
241)成為了Java平臺(tái)上的第二種編程語言。
消息全文請(qǐng)看: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是一種松散類型的腳本語言(這點(diǎn)和JS類似)。
下載地址:http://www.beanshell.org
設(shè)置環(huán)境
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
運(yùn)行方式:
l 界面UI方式 :java bsh.Console
l 命令行方式 :java bsh.Interpreter
l 運(yùn)行腳本文件:java bsh.Interpreter filename [ args ]
簡單舉例:
在classpath中設(shè)置好環(huán)境變量,打開dos窗口,鍵入:java bsh.Console命令
出現(xiàn)BeanShell圖片代表設(shè)置成功,beanshell開始運(yùn)行
測(cè)試內(nèi)容:
設(shè)置變量
foo = "Foo";
four = (2 + 2)*2/2;
打印變量
print( foo + " = " + four );
循環(huán)
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);
在窗口中輸入上面的代碼
敲回車執(zhí)行,運(yùn)行結(jié)果如圖
說明:
因?yàn)閎eanshell是松散類型的腳本語言因此可以直接寫
foo = "Foo";
four = (2 + 2)*2/2;
print是beanshell提供一種簡單的打印命令相當(dāng)于java中的System.out.println()
其他的beanshell腳本命令
· source(), run() – 讀取,或者運(yùn)行一個(gè)腳本文件
· frame() – 顯示一個(gè)窗口
· load(), save() – 讀取或者保存一個(gè)腳本對(duì)象到文件
· cd(), cat(), dir(), pwd(), etc. 使用Unix下面的命令
· exec() – 運(yùn)行一個(gè)本地的方法
· javap() –使用javap命令.
· setAccessibility() – 設(shè)置可以接收private和protected類型的變量
BeanShell命令不一定都是內(nèi)置的腳本命令,腳本方法會(huì)自動(dòng)從classpath中取方法使用,因此你可以添加你自己的腳本到classpath中來擴(kuò)充基本的命令
腳本方法
一般的方法:
int addTwoNumbers( int a, int b ) {
return a + b;
}
sum = addTwoNumbers( 5, 7 ); // 12
也可以使用動(dòng)態(tài)的變量類型(無狀態(tài))方法
add( a, b ) {
return a + b;
}
foo = add(1, 2); // 3
foo = add(1, “2”); //”12” 只要有一個(gè)為字符串全部按照字符串處理,系統(tǒng)不會(huì)根據(jù)1是數(shù)字在前把“2”轉(zhuǎn)換成數(shù)字處理(特別注意)
foo = add("Oh", " baby"); // "Oh baby"
實(shí)現(xiàn)接口
實(shí)現(xiàn)任何接口需要java1.3或者更高
可以使用缺省的java匿名類的語法實(shí)現(xiàn)一個(gè)接口類,例如:
ActionListener scriptedListener = new ActionListener() {
actionPerformed( event ) { ... }
}
不需要實(shí)現(xiàn)接口的所有的方法,只需要實(shí)現(xiàn)你使用的方法即可,如果使用你沒有實(shí)現(xiàn)的方法,beanshell將拋出一個(gè)錯(cuò)誤,
ml = new MouseListener() {
mousePressed( event ) { ... }
// handle the rest
invoke( name, args ) { print("Method: "+name+" invoked!");
}
腳本對(duì)象
使用特殊的關(guān)鍵字this可以創(chuàng)建一個(gè)對(duì)象(根JS類似)
foo() {
print("foo");
x=5;
bar() {
print("bar");
}
return this;
}
myfoo = foo(); // prints "foo"
print( myfoo.x ); // prints "5"
myfoo.bar(); // prints "bar"
從應(yīng)用程序中調(diào)用BeanShell
創(chuàng)建一個(gè)BeanShell的解釋器(interpreter)用eval()和source()命令可以對(duì)一個(gè)字符串求值和運(yùn)行一個(gè)腳本文件
使用set()方法可以給一個(gè)對(duì)象傳入一個(gè)變量的參考
使用get()方法可以重新得到一個(gè)變量的結(jié)果
完整代碼:
package cn.com.sparknet.util;
import bsh.*;
import java.util.*;
public class BeanShell {
public static void main(String[] args) {
try {
Interpreter interpreter = new Interpreter(); // 構(gòu)造一個(gè)解釋器
interpreter.set("foo", 5); // 設(shè)置變量
interpreter.set("date", new Date()); //設(shè)置一個(gè)時(shí)間對(duì)象
Date date = (Date) interpreter.get("date"); // 重新得到時(shí)間變量
interpreter.println(date.toString()); //打印時(shí)間變量
interpreter.eval("bar = foo*10"); // 對(duì)一段腳本求值,并得到結(jié)果
System.out.println(interpreter.get("bar")); //打印變量
interpreter.source("d:\\helloWorld.bsh"); // 導(dǎo)入并執(zhí)行一個(gè)腳本文件
}
catch (Exception e) {
//如果發(fā)生異常,寫入日志文件
Log.error(new BeanShell(), "main", FormatDate.getCurrDate(), e.getMessage());
}
}
}
BeanShell語法
BeanShell是一種最原始的java解釋器。
標(biāo)準(zhǔn)的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);
異常處理
標(biāo)準(zhǔn)的java異常
try {
int i = 1/0;
} catch ( ArithmeticException e ) {
print( e );
}
松散的異常處理(類似JS)
try {
...
} catch ( e ) {
...
}
松散類型變量的作用范圍
標(biāo)
準(zhǔn)的java程序的變量作用范圍是在一個(gè)模塊中的(在模塊中聲明的變量),而在松散類型的語言中如果在一個(gè)模塊中沒有指定一個(gè)變量的類型,則認(rèn)為是一個(gè)全
局變量(只有它以后的代碼可以使用該變量,系統(tǒng)在調(diào)用該變量的時(shí)候自動(dòng)生成一個(gè)全局變量,也就為什么在調(diào)用模塊之前不能使用該變量的原因)
// 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等循環(huán)語句
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
方便靈活的語法
標(biāo)準(zhǔn)的java語法
java.awt.Button button = new java.awt.Button();
button.setLabel(“javaButton”);
松散的語法
button = new java.awt.Button();
button.label = "my button";
你也可以使用{}來對(duì)一個(gè)對(duì)象設(shè)置屬性
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自動(dòng)轉(zhuǎn)為簡單類型
i=5;
iw=new Integer(5);
print( i * iw ); // 25
導(dǎo)入類和包
import javax.xml.parsers.*;
import mypackage.MyClass;
超級(jí)導(dǎo)入法:
import *;
BeanShell默認(rèn)導(dǎo)入下面的包
· java.lang
· java.io
· java.util
· java.net
· java.awt
· java.awt.event
· javax.swing
· javax.swing.event
友好文檔實(shí)體
BeanShell支持特殊的文檔操作類型內(nèi)容
@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;
}
你可以使用內(nèi)餡的BeanShell方法使用他們
sum = addTwoNumbers( 5, 7 );
只有BeanShell變量可以被動(dòng)態(tài)定義為動(dòng)態(tài)類型,方法可以有動(dòng)態(tài)的參數(shù)以及返回類型
add( a, b ) {
return a + b;
}
在這個(gè)方法中,BeanShell將動(dòng)態(tài)的決定類型當(dāng)這個(gè)方法被調(diào)用時(shí)并且能夠準(zhǔn)確的計(jì)算出你想要的結(jié)果
foo = add(1, 2);
print( foo ); // 3
foo = add("Oh", " baby");
print( foo ); // Oh baby
在第一個(gè)例子中BeanShell將把參數(shù)定義為數(shù)字型,并返回?cái)?shù)字型
在第二個(gè)例子中BeanShell將把參數(shù)定義為字符型,并返回字符對(duì)象
變量和方法的可見范圍
就像您所預(yù)期的那樣,在方法內(nèi)您可以參考到上下文中上面的變量和方法
a = 42;
someMethod() { ... }
foo() {
print( a );
someMethod(); // invoke someMethod()
}
// invoke foo()
foo(); // prints 42
如果一個(gè)變量只有在方法內(nèi)使用請(qǐng)定義成局部變量,即加上類型,如果是全局變量請(qǐng)?jiān)诜椒ㄍ舛x
var = "global";
foo() {
print(var);
String var = "local";
print(var);
}
foo();
print(var);
將打印出
global
local
global
方法內(nèi)的var(第四行)變量屬于局部變量,不會(huì)覆蓋全局變量var(第一行)的因此改變var(第四行)變量不會(huì)影響到全局變量var(第一行)
范圍參考:super
使用super關(guān)鍵字可以在局部參考到全局變量
var = "global";
foo() {
String var = "local";
print(var);
print(super.var);
}
foo();
將輸出
local
global
腳本對(duì)象
this對(duì)象
在java標(biāo)準(zhǔn)語言中可以使用this返回一個(gè)類的一個(gè)實(shí)例
// MyClass.java
MyClass {
Object getObject() {
return this; // return a reference to our object
}
}
在這個(gè)例子中g(shù)etObject() 方法是返回MyClass類的一個(gè)實(shí)例
在BeanShell中對(duì)象中的變量只是局部的變量在對(duì)象內(nèi)可以使用,在對(duì)象外是不可以使用(不同于前面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返回對(duì)象,使用對(duì)象加上“.”運(yùn)算符參考屬性(類似JS)
foo() {
bar = 42;
return this;
}
fooObj = foo();
print( fooObj.bar ); // prints 42!
同樣對(duì)象中也可以定義一些方法
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也可以代參數(shù)
foo() {
return this;
}
bar(int a) {
print("The bar is open!" + a);
}
foo().bar(1);
也可以把bar()方法定義到對(duì)象外面
foo() {
bar(int a) {
print("The bar is open!" + a);
}
return this;
}
foo().bar(1);
BeanShell一種松散的腳本語言,有很多中聲明的方法可以使用
This super global
This是參考當(dāng)前對(duì)象
Super是參考父親對(duì)象
Global是參考最上層對(duì)象
super.super.super...foo = 42; // Chain super. to reach the top
global.foo = 42;
簡單例子:
文本拖動(dòng):
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網(wǎng)站
http://www.beanshell.org
posted @
2008-10-08 14:34 xiaoxinchen 閱讀(2472) |
評(píng)論 (0) |
編輯 收藏
在處理一個(gè)大數(shù)據(jù)量數(shù)據(jù)庫的時(shí)候
突然發(fā)現(xiàn)mysql對(duì)于count(*)的不同處理會(huì)造成不同的結(jié)果
比如執(zhí)行
SELECT count(*) FROM tablename
即使對(duì)于千萬級(jí)別的數(shù)據(jù)mysql也能非常迅速的返回結(jié)果
而對(duì)于
SELECT count(*) FROM tablename WHERE…..
mysql的查詢時(shí)間開始攀升
仔細(xì)查閱累下手冊(cè),發(fā)現(xiàn)當(dāng)沒有WHERE語句對(duì)于整個(gè)mysql的表進(jìn)行count運(yùn)算的時(shí)候
MyISAM類型的表中保存有總的行數(shù),而當(dāng)添加有WHERE限定語句的時(shí)候Mysql需要對(duì)整個(gè)表進(jìn)行檢索
從而得出count的數(shù)值
突然又想起來看到的不少新興的php程序?qū)τ赾ount的處理并沒有很好的意思到這點(diǎn)
記錄下
順便提下mysql的DISTINCT的關(guān)鍵字有很多你想不到的用處
1.在count 不重復(fù)的記錄的時(shí)候能用到
比如SELECT COUNT( DISTINCT id ) FROM tablename;
就是計(jì)算talbebname表中id不同的記錄有多少條
2,在需要返回記錄不同的id的具體值的時(shí)候可以用
比如SELECT DISTINCT id FROM tablename;
返回talbebname表中不同的id的具體的值
3.上面的情況2對(duì)于需要返回mysql表中2列以上的結(jié)果時(shí)會(huì)有歧義
比如SELECT DISTINCT id, type FROM tablename;
實(shí)際上返回的是 id與type同時(shí)不相同的結(jié)果,也就是DISTINCT同時(shí)作用了兩個(gè)字段,必須得id與tyoe都相同的才被排除了,與我們期望的結(jié)果不一樣
4.這時(shí)候可以考慮使用group_concat函數(shù)來進(jìn)行排除,不過這個(gè)mysql函數(shù)是在mysql4.1以上才支持的
5.其實(shí)還有另外一種解決方式,就是使用
SELECT id, type, count(DISTINCT id) FROM tablename
雖然這樣的返回結(jié)果多了一列無用的count數(shù)據(jù)(或許你就需要這個(gè)我說的無用數(shù)據(jù))
返回的結(jié)果是 只有id不同的所有結(jié)果和上面的4類型可以互補(bǔ)使用,就是看你需要什么樣的數(shù)據(jù)了
posted @
2008-10-07 14:46 xiaoxinchen 閱讀(251) |
評(píng)論 (0) |
編輯 收藏
Lucene,作為一種全文搜索的輔助工具,為我們進(jìn)行條件搜索,無論是像Google,Baidu之類的搜索引擎,還是論壇中的搜索功能,還是其它
C/S架構(gòu)的搜索,都帶來了極大的便利和比較高的效率。本文主要是利用Lucene對(duì)MS Sql Server
2000進(jìn)行建立索引,然后進(jìn)行全文索引。至于數(shù)據(jù)庫的內(nèi)容,可以是網(wǎng)頁的內(nèi)容,還是其它的。本文中數(shù)據(jù)庫的內(nèi)容是圖書館管理系統(tǒng)中的某個(gè)作者表
-Authors表。
因?yàn)榭紤]到篇幅的問題,所以該文不會(huì)講的很詳細(xì),也不可能講的很深。
本文以這樣的結(jié)構(gòu)進(jìn)行:
1.介紹數(shù)據(jù)庫中Authors表的結(jié)構(gòu)
2.為數(shù)據(jù)庫建立索引
3.為數(shù)據(jù)庫建立查詢功能
4.在web界面下進(jìn)行查詢并顯示結(jié)果
1.介紹數(shù)據(jù)庫中Authors表的結(jié)構(gòu)
字段名稱 字段類型 字段含義
Au_id Varchar(11) 作者號(hào)
Au_name Varchar(60) 作者名
Phone Char(12) 電話號(hào)碼
Address Varchar(40) 地址
City Varchar(20) 城市
State Char(2) 省份
Zip Char(5) 郵編
contract Bit(1) 外鍵(關(guān)系不大)
表中的部分內(nèi)容:
2.為數(shù)據(jù)庫建立索引
首先建立一個(gè)類TestLucene.java。這個(gè)類就是對(duì)數(shù)據(jù)庫進(jìn)行建立索引,編寫查詢條件等。
當(dāng)然,最開始就是建立數(shù)據(jù)庫連接。連接代碼這里就省略了。^_^
接著,新建一個(gè)方法getResutl(String),它返回的是數(shù)據(jù)庫表Authors的內(nèi)容。具體代碼如下:
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;
}
然后,為數(shù)據(jù)庫建立索引。
首先要定義一個(gè)IndexWriter(),它是將索引寫進(jìn)Lucene自己的數(shù)據(jù)庫中,它存放的位置是有你自己定義的。在定義
IndexWriter是需要指定它的分析器。Lucene自己自帶有幾個(gè)分析器,例
如:StandarAnalyzer(),SimpleAnalyzer(),StopAnalyzer()等。它作用是對(duì)文本進(jìn)行分析,判斷如何進(jìn)行切
詞。
接著,要定義一個(gè)Document。Document相當(dāng)于二維表中一行數(shù)據(jù)一樣。Document里包含的是Field字段,F(xiàn)ield相當(dāng)于數(shù)據(jù)庫中一列,也就是一個(gè)屬性,一個(gè)字段。
最后應(yīng)該對(duì)IndexWriter進(jìn)行優(yōu)化,方法很簡單,就是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.為數(shù)據(jù)庫建立查詢功能
在類TestLucene中建立一個(gè)新的方法searcher(String),它返回的是一個(gè)搜索的結(jié)構(gòu)集,相當(dāng)于數(shù)據(jù)庫中的ResultSet一樣。它代的參數(shù)是你要查詢的內(nèi)容。這里,我把要查詢的字段寫死了。你可以在添加一個(gè)參數(shù)表示要查詢的字段。
這里主要有兩個(gè)對(duì)象IndexSearcher和Query。IndexSearcher是找到索引數(shù)據(jù)庫,Query是處理搜索,它包含了三個(gè)參數(shù):查詢內(nèi)容,查詢字段,分析器。
具體代碼如下:
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界面下進(jìn)行查詢并顯示結(jié)果
這里建立一個(gè)Jsp頁面TestLucene.jsp進(jìn)行搜索。
在TestLucene.jsp頁面中首先引入類
<%@ page import="lucenetest.LucentTest"%>
<%@ page import="org.apache.lucene.search.*,org.apache.lucene.document.*" %>
然后定義一個(gè)LuceneTest對(duì)象,獲取查詢結(jié)果集:
LucentTest lucent=new LucentTest();
Hits hits=lucent.seacher(request.getParameter("queryString"));
定義一個(gè)Form,建立一個(gè)查詢環(huán)境:
<form action="TestLucene.jsp">
<input type="text" name="queryString"/>
<input type="submit" value="搜索"/>
</form>
顯示查詢結(jié)果:
<table>
<%if(hits!=null){%>
<tr>
<td>作者號(hào)</td>
<td>作者名</td>
<td>地址</td>
<td>電話號(hào)碼</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 閱讀(212) |
評(píng)論 (0) |
編輯 收藏
中國有很多精于編碼的人,但是中國軟件行業(yè),尤其是網(wǎng)絡(luò)應(yīng)用開發(fā)方面誤區(qū)很大,很難形成有規(guī)模的軟件開發(fā)力量和產(chǎn)品能力,不但比美國差距甚遠(yuǎn),和印
度相比也是頗有不如。這些問題不是在于中國程序員的智商和工作努力狀況,也不是在于國家和民間對(duì)開發(fā)的投入程度,而是很大程度上,有一些對(duì)技術(shù),對(duì)程序開
發(fā),對(duì)項(xiàng)目設(shè)計(jì)方面的思想誤區(qū),這些誤區(qū),導(dǎo)致了軟件行業(yè)的產(chǎn)品化能力不足,缺乏規(guī)模化和大型復(fù)用系統(tǒng)研發(fā)能力,可以說,改變認(rèn)識(shí)誤區(qū),是解決軟件行業(yè)小
作坊模式和個(gè)體英雄模式所帶來的局限性的重要工作。
程序員是一種技術(shù)工作,在IT的發(fā)展中有相當(dāng)重要的地位,從底層硬件通訊協(xié)議的建立,到數(shù)據(jù)傳輸層的處理,到操作系統(tǒng)的建設(shè),到數(shù)據(jù)庫平臺(tái)的建設(shè),一直到應(yīng)用層上各種數(shù)據(jù)營銷平臺(tái)的搭建,程序員在里面都扮演著舉足輕重的角色并為IT事業(yè)的發(fā)展做出了巨大的貢獻(xiàn)。
中
國有很多小朋友,他們18,9歲或21,2歲,通過自學(xué)也寫了不少代碼,他們有的代碼寫的很漂亮,一些技術(shù)細(xì)節(jié)相當(dāng)出眾,也很有鉆研精神,但是他們被一些
錯(cuò)誤的認(rèn)識(shí)和觀點(diǎn)左右,缺乏對(duì)系統(tǒng),對(duì)程序的整體理解能力,這些人,一個(gè)網(wǎng)上的朋友說得很好,他們實(shí)際上只是一些Codingfans,壓根沒有資格稱
為程序員,但是據(jù)我所知,不少小網(wǎng)絡(luò)公司的CTO就是這樣的codingfans,拿著嚇人的工資,做著嚇人的項(xiàng)目,項(xiàng)目的結(jié)局通常也很嚇人。
程序員基本素質(zhì):
作一個(gè)真正合格的程序員,或者說就是可以真正合格完成一些代碼工作的程序員,應(yīng)該具有的素質(zhì)。
1:團(tuán)隊(duì)精神和協(xié)作能力
把
它作為基本素質(zhì),并不是不重要,恰恰相反,這是程序員應(yīng)該具備的最基本的,也是最重要的安身立命之本。把高水平程序員說成獨(dú)行俠的都是在囈語,任何個(gè)人的
力量都是有限的,即便如linus這樣的天才,也需要通過組成強(qiáng)大的團(tuán)隊(duì)來創(chuàng)造奇跡,那些遍布全球的為linux寫核心的高手們,沒有協(xié)作精神是不可想象
的。獨(dú)行俠可以作一些賺錢的小軟件發(fā)點(diǎn)小財(cái),但是一旦進(jìn)入一些大系統(tǒng)的研發(fā)團(tuán)隊(duì),進(jìn)入商業(yè)化和產(chǎn)品化的開發(fā)任務(wù),缺乏這種素質(zhì)的人就完全不合格了。
2:文檔習(xí)慣
說
高水平程序員從來不寫文檔的肯定是乳臭未干的毛孩子,良好的文檔是正規(guī)研發(fā)流程中非常重要的環(huán)節(jié),作為代碼程序員,30%的工作時(shí)間寫技術(shù)文檔是很正常
的,而作為高級(jí)程序員和系統(tǒng)分析員,這個(gè)比例還要高很多。缺乏文檔,一個(gè)軟件系統(tǒng)就缺乏生命力,在未來的查錯(cuò),升級(jí)以及模塊的復(fù)用時(shí)就都會(huì)遇到極大的麻
煩。
3:規(guī)范化,標(biāo)準(zhǔn)化的代碼編寫習(xí)慣
作為一些外國知名軟件公司的規(guī)矩,代碼的變量命名,代碼內(nèi)注釋格式,甚至嵌套中行縮進(jìn)的長度和函數(shù)間的空行數(shù)字都有明確規(guī)定,良好的編寫習(xí)慣,不但有助于代碼的移植和糾錯(cuò),也有助于不同技術(shù)人員之間的協(xié)作。
有些codingfans叫囂高水平程序員寫的代碼旁人從來看不懂,這種叫囂只能證明他們自己壓根不配自稱程序員。代碼具有良好的可讀性,是程序員基本的素質(zhì)需求。
再看看整個(gè)linux的搭建,沒有規(guī)范化和標(biāo)準(zhǔn)化的代碼習(xí)慣,全球的研發(fā)協(xié)作是絕對(duì)不可想象的。
4:需求理解能力
程
序員需要理解一個(gè)模塊的需求,很多小朋友寫程序往往只關(guān)注一個(gè)功能需求,他們把性能指標(biāo)全部歸結(jié)到硬件,操作系統(tǒng)和開發(fā)環(huán)境上,而忽視了本身代碼的性能考
慮,有人曾經(jīng)放言說寫一個(gè)廣告交換程序很簡單,這種人從來不知道在百萬甚至千萬數(shù)量級(jí)的訪問情況下的性能指標(biāo)是如何實(shí)現(xiàn)的,對(duì)于這樣的程序員,你給他深藍(lán)
那套系統(tǒng),他也做不出太極鏈的并訪能力。性能需求指標(biāo)中,穩(wěn)定性,并訪支撐能力以及安全性都很重要,作為程序員需要評(píng)估該模塊在系統(tǒng)運(yùn)營中所處的環(huán)境,將
要受到的負(fù)荷壓力以及各種潛在的危險(xiǎn)和惡意攻擊的可能性。就這一點(diǎn),一個(gè)成熟的程序員至少需要2到3年的項(xiàng)目研發(fā)和跟蹤經(jīng)驗(yàn)才有可能有心得。
5:復(fù)用性,模塊化思維能力
經(jīng)常可以聽到一些程序員有這樣的抱怨,寫了幾年程序,變成了熟練工,每天都是重復(fù)寫一些沒有任何新意的代碼,這其實(shí)是中國軟件人才最大浪費(fèi)的地方,一些重復(fù)性工作變成了熟練程序員的主要工作,而這些,其實(shí)是完全可以避免的。
復(fù)
用性設(shè)計(jì),模塊化思維就是要程序員在完成任何一個(gè)功能模塊或函數(shù)的時(shí)候,要多想一些,不要局限在完成當(dāng)前任務(wù)的簡單思路上,想想看該模塊是否可以脫離這個(gè)
系統(tǒng)存在,是否可以通過簡單的修改參數(shù)的方式在其他系統(tǒng)和應(yīng)用環(huán)境下直接引用,這樣就能極大避免重復(fù)性的開發(fā)工作,如果一個(gè)軟件研發(fā)單位和工作組能夠在每
一次研發(fā)過程中都考慮到這些問題,那么程序員就不會(huì)在重復(fù)性的工作中耽誤太多時(shí)間,就會(huì)有更多時(shí)間和精力投入到創(chuàng)新的代碼工作中去。
一些好的程序模塊代碼,即便是70年代寫成的,拿到現(xiàn)在放到一些系統(tǒng)里面作為功能模塊都能適合的很好,而現(xiàn)在我看到的是,很多小公司軟件一升級(jí)或改進(jìn)就動(dòng)輒全部代碼重寫,大部分重復(fù)性工作無謂的浪費(fèi)了時(shí)間和精力。
6:測(cè)試習(xí)慣
作
為一些商業(yè)化正規(guī)化的開發(fā)而言,專職的測(cè)試工程師是不可少的,但是并不是說有了專職的測(cè)試工程師程序員就可以不進(jìn)行自測(cè);軟件研發(fā)作為一項(xiàng)工程而言,一個(gè)
很重要的特點(diǎn)就是問題發(fā)現(xiàn)的越早,解決的代價(jià)就越低,程序員在每段代碼,每個(gè)子模塊完成后進(jìn)行認(rèn)真的測(cè)試,就可以盡量將一些潛在的問題最早的發(fā)現(xiàn)和解決,
這樣對(duì)整體系統(tǒng)建設(shè)的效率和可靠性就有了最大的保證。
測(cè)試工作實(shí)際上需要考慮兩方面,一方面是正常調(diào)用的測(cè)試,也就是看程序是否能在正常調(diào)用
下完成基本功能,這是最基本的測(cè)試職責(zé),可惜在很多公司這成了唯一的測(cè)試任務(wù),實(shí)際上還差的遠(yuǎn)那;第二方面就是異常調(diào)用的測(cè)試,比如高壓力負(fù)荷下的穩(wěn)定性
測(cè)試,用戶潛在的異常輸入情況下的測(cè)試,整體系統(tǒng)局部故障情況下該模塊受影響狀況的測(cè)試,頻發(fā)的異常請(qǐng)求阻塞資源時(shí)的模塊穩(wěn)定測(cè)試等等。當(dāng)然并不是程序員
要對(duì)自己的每段代碼都需要進(jìn)行這種完整測(cè)試,但是程序員必須清醒認(rèn)識(shí)自己的代碼任務(wù)在整體項(xiàng)目中的地位和各種性能需求,有針對(duì)性的進(jìn)行相關(guān)測(cè)試,并盡早發(fā)
現(xiàn)和解決問題,當(dāng)然這需要上面提到的需求理解能力。
7:學(xué)習(xí)和總結(jié)的能力
程序員是人才很容易被淘汰,很容易落伍的職業(yè),因?yàn)橐环N技術(shù)可能僅僅在三兩年內(nèi)具有領(lǐng)先性,程序員如果想安身立命,就必須不斷跟進(jìn)新的技術(shù),學(xué)習(xí)新的技能。
善
于學(xué)習(xí),對(duì)于任何職業(yè)而言,都是前進(jìn)所必需的動(dòng)力,對(duì)于程序員,這種要求就更加高了。但是學(xué)習(xí)也要找對(duì)目標(biāo),一些小codingfans們,他們也津津
樂道于他們的學(xué)習(xí)能力,一會(huì)學(xué)會(huì)了asp,一會(huì)兒學(xué)會(huì)了php,一會(huì)兒學(xué)會(huì)了jsp,他們把這個(gè)作為炫耀的資本,盲目的追逐一些膚淺的,表面的東西和名
詞,做網(wǎng)絡(luò)程序不懂通訊傳輸協(xié)議,做應(yīng)用程序不懂中斷向量處理,這樣的技術(shù)人員,不管掌握了多少所謂的新語言,永遠(yuǎn)不會(huì)有質(zhì)的提高。
善于總結(jié),也是學(xué)習(xí)能力的一種體現(xiàn),每次完成一個(gè)研發(fā)任務(wù),完成一段代碼,都應(yīng)當(dāng)有目的的跟蹤該程序的應(yīng)用狀況和用戶反饋,隨時(shí)總結(jié),找到自己的不足,這樣逐步提高,一個(gè)程序員才可能成長起來。
一個(gè)不具備成長性的程序員,即便眼前看是個(gè)高手,建議也不要選用,因?yàn)樗湮榈臅r(shí)候馬上就到了。
具備以上全部素質(zhì)的人,應(yīng)當(dāng)說是夠格的程序員了,請(qǐng)注意以上的各種素質(zhì)都不是由IQ決定的,也不是大學(xué)某些課本里可以學(xué)習(xí)到的,需要的僅僅是程序員對(duì)自己工作的認(rèn)識(shí),是一種意識(shí)上的問題。
posted @
2008-08-29 10:57 xiaoxinchen 閱讀(149) |
評(píng)論 (0) |
編輯 收藏
Lucene是一個(gè)高性能的java全文檢索工具包,它使用的是倒排文件索引結(jié)構(gòu)。該結(jié)構(gòu)及相應(yīng)的生成算法如下:
0)設(shè)有兩篇文章1和2
文章1的內(nèi)容為:Tom lives in Guangzhou,I live in Guangzhou too.
文章2的內(nèi)容為:He once lived in Shanghai.
1)由于lucene是基于關(guān)鍵詞索引和查詢的,首先我們要取得這兩篇文章的關(guān)鍵詞,通常我們需要如下處理措施
a.我們現(xiàn)在有的是文章內(nèi)容,即一個(gè)字符串,我們先要找出字符串中的所有單詞,即分詞。英文單詞由于用空格分隔,比較好處理。中文單詞間是連在一起的需要特殊的分詞處理。
b.文章中的”in”, “once” “too”等詞沒有什么實(shí)際意義,中文中的“的”“是”等字通常也無具體含義,這些不代表概念的詞可以過濾掉
c.用戶通常希望查“He”時(shí)能把含“he”,“HE”的文章也找出來,所以所有單詞需要統(tǒng)一大小寫。
d.用戶通常希望查“live”時(shí)能把含“lives”,“lived”的文章也找出來,所以需要把“lives”,“lived”還原成“live”
e.文章中的標(biāo)點(diǎn)符號(hào)通常不表示某種概念,也可以過濾掉
在lucene中以上措施由Analyzer類完成
經(jīng)過上面處理后
文章1的所有關(guān)鍵詞為:[tom] [live] [guangzhou] [i] [live] [guangzhou]
文章2的所有關(guān)鍵詞為:[he] [live] [shanghai]
2) 有了關(guān)鍵詞后,我們就可以建立倒排索引了。上面的對(duì)應(yīng)關(guān)系是:“文章號(hào)”對(duì)“文章中所有關(guān)鍵詞”。倒排索引把這個(gè)關(guān)系倒過來,變成:“關(guān)鍵詞”對(duì)“擁有該關(guān)鍵詞的所有文章號(hào)”。文章1,2經(jīng)過倒排后變成
關(guān)鍵詞 文章號(hào)
guangzhou 1
he 2
i 1
live 1,2
shanghai 2
tom 1
通常僅知道關(guān)鍵詞在哪些文章中出現(xiàn)還不夠,我們還需要知道關(guān)鍵詞在文章中出現(xiàn)次數(shù)和出現(xiàn)的位置,通常有兩種位置:a)字符位置,即記錄該詞是文章
中第幾個(gè)字符(優(yōu)點(diǎn)是關(guān)鍵詞亮顯時(shí)定位快);b)關(guān)鍵詞位置,即記錄該詞是文章中第幾個(gè)關(guān)鍵詞(優(yōu)點(diǎn)是節(jié)約索引空間、詞組(phase)查詢
快),lucene中記錄的就是這種位置。
加上“出現(xiàn)頻率”和“出現(xiàn)位置”信息后,我們的索引結(jié)構(gòu)變?yōu)椋?
關(guān)鍵詞 文章號(hào)[出現(xiàn)頻率] 出現(xiàn)位置
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
這行為例我們說明一下該結(jié)構(gòu):live在文章1中出現(xiàn)了2次,文章2中出現(xiàn)了一次,它的出現(xiàn)位置為“2,5,2”這表示什么呢?我們需要結(jié)合文章號(hào)和出現(xiàn)
頻率來分析,文章1中出現(xiàn)了2次,那么“2,5”就表示live在文章1中出現(xiàn)的兩個(gè)位置,文章2中出現(xiàn)了一次,剩下的“2”就表示live是文章2中第
2個(gè)關(guān)鍵字。
以上就是lucene索引結(jié)構(gòu)中最核心的部分。我們注意到關(guān)鍵字是按字符順序排列的(lucene沒有使用B樹結(jié)構(gòu)),因此lucene可以用二元搜索算法快速定位關(guān)鍵詞。
實(shí)現(xiàn)時(shí) lucene將上面三列分別作為詞典文件(Term Dictionary)、頻率文件(frequencies)、位置文件
(positions)保存。其中詞典文件不僅保存有每個(gè)關(guān)鍵詞,還保留了指向頻率文件和位置文件的指針,通過指針可以找到該關(guān)鍵字的頻率信息和位置信
息。
Lucene中使用了field的概念,用于表達(dá)信息所在位置(如標(biāo)題中,文章中,url中),在建索引中,該field信息也記錄在詞典文件中,每個(gè)關(guān)鍵詞都有一個(gè)field信息(因?yàn)槊總€(gè)關(guān)鍵字一定屬于一個(gè)或多個(gè)field)。
為了減小索引文件的大小,Lucene對(duì)索引還使用了壓縮技術(shù)。首先,對(duì)詞典文件中的關(guān)鍵詞進(jìn)行了壓縮,關(guān)鍵詞壓縮為<前綴長度,后綴>,例
如:當(dāng)前詞為“阿拉伯語”,上一個(gè)詞為“阿拉伯”,那么“阿拉伯語”壓縮為<3,語>。其次大量用到的是對(duì)數(shù)字的壓縮,數(shù)字只保存與上一個(gè)值
的差值(這樣可以減小數(shù)字的長度,進(jìn)而減少保存該數(shù)字需要的字節(jié)數(shù))。例如當(dāng)前文章號(hào)是16389(不壓縮要用3個(gè)字節(jié)保存),上一文章號(hào)是16382,
壓縮后保存7(只用一個(gè)字節(jié))。
下面我們可以通過對(duì)該索引的查詢來解釋一下為什么要建立索引。
假設(shè)要查詢單詞 “live”,lucene先對(duì)詞典二元查找、找到該詞,通過指向頻率文件的指針讀出所有文章號(hào),然后返回結(jié)果。詞典通常非常小,因而,整個(gè)過程的時(shí)間是毫秒級(jí)的。
而用普通的順序匹配算法,不建索引,而是對(duì)所有文章的內(nèi)容進(jìn)行字符串匹配,這個(gè)過程將會(huì)相當(dāng)緩慢,當(dāng)文章數(shù)目很大時(shí),時(shí)間往往是無法忍受的。
參考資料:
http://blog.csdn.net/ladofwind/archive/2005/01/10/247403.aspx
posted @
2008-08-21 13:24 xiaoxinchen 閱讀(147) |
評(píng)論 (0) |
編輯 收藏