bt下載與小說(shuō)520

          bt下載與小說(shuō)520

            BlogJava :: 首頁(yè) :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
            16 隨筆 :: 0 文章 :: 6 評(píng)論 :: 0 Trackbacks

          2008年10月5日 #

          Mozilla Public License

          MPL License,允許免費(fèi)重發(fā)布、免費(fèi)修改,但要求修改后的代碼版權(quán)歸軟件的發(fā)起者。這種授權(quán)維護(hù)了商業(yè)軟件的利益,,它要求基于這種軟件得修改無(wú)償貢獻(xiàn)版權(quán)給該軟件。這樣,圍繞該軟件得所有代碼得版權(quán)都集中在發(fā)起開(kāi)發(fā)人得手中。但MPL是允許修改,無(wú)償使用得。MPL軟件對(duì)鏈接沒(méi)有要求。

          SD開(kāi)源協(xié)議

          BSD開(kāi)源協(xié)議是一個(gè)給于使用者很大自由的協(xié)議。可以自由的使用,修改源代碼,也可以將修改后的代碼作為開(kāi)源或者專有軟件再發(fā)布。 當(dāng)你發(fā)布使用了BSD協(xié)議的代碼,或則以BSD協(xié)議代碼為基礎(chǔ)做二次開(kāi)發(fā)自己的產(chǎn)品時(shí),需要滿足三個(gè)條件:

          1. 如果再發(fā)布的產(chǎn)品中包含源代碼,則在源代碼中必須帶有原來(lái)代碼中的BSD協(xié)議。

          2. 如果再發(fā)布的只是二進(jìn)制類庫(kù)/軟件,則需要在類庫(kù)/軟件的文檔和版權(quán)聲明中包含原來(lái)代碼中的BSD協(xié)議。

          3. 不可以用開(kāi)源代碼的作者/機(jī)構(gòu)名字和原來(lái)產(chǎn)品的名字做市場(chǎng)推廣。

          BSD代碼鼓勵(lì)代碼共享,但需要尊重代碼作者的著作權(quán)。BSD由于允許使用者修改和重新發(fā)布代碼,也允許使用或在BSD代碼上開(kāi)發(fā)商業(yè)軟件發(fā)布和銷售,因此是對(duì)商業(yè)集成很友好的協(xié)議。而很多的公司企業(yè)在選用開(kāi)源產(chǎn)品的時(shí)候都首選BSD協(xié)議,因?yàn)榭梢酝耆刂七@些第三方的代碼,在必要的時(shí)候可以修改或者二次開(kāi)發(fā)。

          Apache Licence 2.0

          Apache Licence是著名的非盈利開(kāi)源組織Apache采用的協(xié)議。該協(xié)議和BSD類似,同樣鼓勵(lì)代碼共享和尊重原作者的著作權(quán),同樣允許代碼修改,再發(fā)布(作為開(kāi)源或商業(yè)軟件)。需要滿足的條件:

          1. 需要給代碼的用戶一份Apache Licence

          2. 如果你修改了代碼,需要再被修改的文件中說(shuō)明。

          3. 在延伸的代碼中(修改和有源代碼衍生的代碼中)需要帶有原來(lái)代碼中的協(xié)議,商標(biāo),專利聲明和其他原來(lái)作者規(guī)定需要包含的說(shuō)明。

          4. 如果再發(fā)布的產(chǎn)品中包含一個(gè)Notice文件,則在Notice文件中需要帶有Apache Licence。你可以在Notice中增加自己的許可,但不可以表現(xiàn)為對(duì)Apache Licence構(gòu)成更改。

          Apache Licence也是對(duì)商業(yè)應(yīng)用友好的許可。使用者也可以在需要的時(shí)候修改代碼來(lái)滿足需要并作為開(kāi)源或商業(yè)產(chǎn)品發(fā)布/銷售。

          GPL

          GPL許可證是自由軟件的應(yīng)用最廣泛的軟件許可證,人們可以修改程式的一個(gè)或幾個(gè)副本或程式的任何部分,以此形成基於這些程式的衍生作品。必須在修改過(guò)的檔案中附有明顯的說(shuō)明:您修改了此一檔案及任何修改的日期。 您必須讓您發(fā)布或出版的作品,包括本程式的全部或一部分,或內(nèi)含本程式的全部或部分所衍生的作品,允許第三方在此許可證條款下使用,并且不得因?yàn)榇隧?xiàng)授權(quán)行為而收費(fèi)。

          LGPL

          Linux就是采用了GPL。GPL協(xié)議和BSD, Apache Licence等鼓勵(lì)代碼重用的許可很不一樣。GPL的出發(fā)點(diǎn)是代碼的開(kāi)源/免費(fèi)使用和引用/修改/衍生代碼的開(kāi)源/免費(fèi)使用,但不允許修改后和衍生的代碼做為閉源的商業(yè)軟件發(fā)布和銷售。這也就是為什么我們能用免費(fèi)的各種linux,包括商業(yè)公司的linux和linux上各種各樣的由個(gè)人,組織,以及商業(yè)軟件公司開(kāi)發(fā)的免費(fèi)軟件了。

          GPL協(xié)議的主要內(nèi)容是只要在一個(gè)軟件中使用(“使用”指類庫(kù)引用,修改后的代碼或者衍生代碼)GPL協(xié)議的產(chǎn)品,則該軟件產(chǎn)品必須也采用GPL協(xié)議,既必須也是開(kāi)源和免費(fèi)。這就是所謂的”傳染性”。GPL協(xié)議的產(chǎn)品作為一個(gè)單獨(dú)的產(chǎn)品使用沒(méi)有任何問(wèn)題,還可以享受免費(fèi)的優(yōu)勢(shì)。

          由于GPL嚴(yán)格要求使用了GPL類庫(kù)的軟件產(chǎn)品必須使用GPL協(xié)議,對(duì)于使用GPL協(xié)議的開(kāi)源代碼,商業(yè)軟件或者對(duì)代碼有保密要求的部門(mén)就不適合集成/采用作為類庫(kù)和二次開(kāi)發(fā)的基礎(chǔ)。

          其它細(xì)節(jié)如再發(fā)布的時(shí)候需要伴隨GPL協(xié)議等和BSD/Apache等類似。

          Public Domain

          公共域授權(quán)。將軟件授權(quán)為公共域,這些軟件包沒(méi)有授權(quán)協(xié)議,任何人都可以隨意使用它。

          Artistic許可

          使作者保持對(duì)進(jìn)一步開(kāi)發(fā)的控制。

          posted @ 2008-12-18 13:55 bt下載| 編輯 收藏

          著第3屆bt論壇的順利結(jié)束的秋風(fēng),我也來(lái)分享一下自己在前端優(yōu)化方面的一些些小經(jīng)驗(yàn),其實(shí)這些經(jīng)驗(yàn)本身都是來(lái)自yahoo的優(yōu)化原則,不過(guò)經(jīng)過(guò)ahuaxuan自身的實(shí)踐和再次的思考,把原來(lái)的原則都進(jìn)行了分組和分析.不過(guò)由于ahuaxuan bt涉及到的東西有限,并沒(méi)有經(jīng)歷過(guò)全部的優(yōu)化點(diǎn),所以只把自己做過(guò)的拿出來(lái)和大家討論討論,其中不免加入自己一些觀點(diǎn),希望大家指正.

          先說(shuō)說(shuō)目標(biāo),前端優(yōu)化的目標(biāo)是什么,一個(gè)字:快.兩個(gè)字:更快.那么下面我們來(lái)看看慢的網(wǎng)頁(yè)將會(huì)給我們帶來(lái)什么:
          1. 慢的頁(yè)面可能會(huì)網(wǎng)站失去更多的用戶.

          2. 慢500ms意味著20%的用戶將放棄訪問(wèn)(google)

          3. 慢100ms意味著1%的用戶將放棄交易(amazon)

          4. 慢 ???ms意味著??%的用戶將放棄xx(your site)

          所以我們的目標(biāo)很明確,就是要網(wǎng)頁(yè)展現(xiàn)的速度更快.
          經(jīng)過(guò)ahuaxuan的實(shí)踐和總結(jié),其實(shí)要讓網(wǎng)頁(yè)展現(xiàn)更快只需要注意幾個(gè)大的方面,下面會(huì)一一描述這幾個(gè)大的方面.


          [size=medium]1減少http請(qǐng)求,我把它排在了第一點(diǎn),為啥要在第一點(diǎn)呢,很簡(jiǎn)單,因?yàn)樗钪匾?



          如何做呢.讓ahuaxuan帶著大家分析一下這個(gè)問(wèn)題.從何處著手呢.ahuaxuan大聲疾呼,我們要從數(shù)據(jù)開(kāi)始.ok,一般來(lái)說(shuō),我們從變化性上把數(shù)據(jù)分成兩種類型,變和不變.那么不變的數(shù)據(jù)可以緩存,變化的數(shù)據(jù)不能緩存,這是一個(gè)常識(shí),也就是說(shuō)要減少我們的http請(qǐng)求次數(shù)這個(gè)目標(biāo)可以轉(zhuǎn)換成把數(shù)據(jù)分為變化和不變化兩個(gè)部分.不變化的數(shù)據(jù)不需要再次請(qǐng)求,這樣http請(qǐng)求的次數(shù)就減少了,下面我們分點(diǎn)來(lái)描述將數(shù)據(jù)分類的途徑.


          1. 合并腳本文件
          包括腳本,樣式和圖片,可以有選擇的把一些Js和css可以合并成一個(gè)文件,一些圖片可以使用css sprites技術(shù).這樣做的原因是什么?做過(guò)web開(kāi)發(fā)的人都知道,js和css基本是不變的,是靜態(tài)文件,圖片亦然.那么不變的文件如果適當(dāng)?shù)暮喜⒃谝黄?會(huì)有什么效果呢?請(qǐng)求的次數(shù)從多次變成了一次.這樣http請(qǐng)求的次數(shù)就減少了.當(dāng)時(shí)合并之后,文件體積變大了,會(huì)影響速度嗎?答:肯定會(huì)啊,不過(guò)這里是需要權(quán)衡的,比如我100份靜態(tài)文件,合并成10份還是合并成1份這就得看你得具體情況了.

          2. 指定Expires或者Cache-Control,
          對(duì)于靜態(tài)內(nèi)容:設(shè)置文件頭過(guò)期時(shí)間Expires的值為“Never expire”(永不過(guò)期)
          動(dòng)態(tài)頁(yè)面,在代碼中添加cache-control,表示多少時(shí)間之后過(guò)期,如:
          response.setHeader("Cache-Control", "max-age=3600");
          如果使用了Expires文件頭,當(dāng)頁(yè)面內(nèi)容改變時(shí)就必須改變內(nèi)容的文件名。通常是在文件內(nèi)容后加版本號(hào)
          這一點(diǎn)是大多數(shù)人都忽略得,之前很多人在壇子上發(fā)布自己得小系統(tǒng),還有demo,ahuaxuan跑過(guò)去一看,my god,一堆又一堆得js,css,既沒(méi)有恰當(dāng)?shù)煤喜?也沒(méi)有設(shè)置過(guò)期時(shí)間.每次刷新頁(yè)面都要重新下載這一堆又一堆的js,css.http請(qǐng)求那叫一個(gè)多啊.無(wú)謂了流量就這樣產(chǎn)生了.

          這一點(diǎn)在企業(yè)應(yīng)用的系統(tǒng)中也時(shí)有發(fā)生.比如我們使用extjs作為前端的技術(shù),400多k啊,每打開(kāi)一個(gè)頁(yè)面都導(dǎo)入,下載這個(gè)js,夠無(wú)聊的.那么童子們可能就要問(wèn)了,靜態(tài)文件為啥不用apache,lighttpd等呢,答,用了又怎么樣,不設(shè)expire或者max-age不是一樣要下載,最好的方法是寫(xiě)一個(gè)filter,再filter中判斷,如果url滿足一定的條件(比如符合配置文件中的正則表達(dá)式),那么就設(shè)置一個(gè)max-age,這樣就ok,太簡(jiǎn)單了,幾行代碼就可以搞定.快哉.

          3. 緩存Ajax請(qǐng)求
          緩存的方法同動(dòng)態(tài)頁(yè)面,ajax請(qǐng)求需要使用get方式,url長(zhǎng)度為2k(ie)限制(post請(qǐng)求有兩個(gè)過(guò)程,1發(fā)送請(qǐng)求headers,2發(fā)送請(qǐng)求數(shù)據(jù),根據(jù)http規(guī)范,get請(qǐng)求只會(huì)發(fā)送一個(gè)tcp包).--------這一段話來(lái)自yahoo,先不管其真假,我們從另外一個(gè)方面來(lái)考慮一下為什么最好使用get方式,講一個(gè)ahuaxuan經(jīng)歷過(guò)的事情,之前有一個(gè)項(xiàng)目的ajax請(qǐng)求使用了post方式,后來(lái)發(fā)現(xiàn)經(jīng)常出錯(cuò),而且拋出了squid的錯(cuò)誤,因?yàn)槲覀兊木W(wǎng)站使用了squid,問(wèn)題就出在這里了,從http協(xié)議上可以了解到,method=post是指把數(shù)據(jù)提交到服務(wù)器上去,那么squid的一個(gè)特性是不會(huì)緩存post請(qǐng)求(事實(shí)上它確實(shí)不應(yīng)該緩存,因?yàn)檫@樣會(huì)違反http協(xié)議中的語(yǔ)義),把a(bǔ)jax請(qǐng)求改成get方式之后,一切恢復(fù)如常.

          4. 移除重復(fù)的js
          重復(fù)的js導(dǎo)入也有可能導(dǎo)致ie重新加載該腳本.沒(méi)啥好說(shuō)的,照做.

          5. 避免重定向
          有一種經(jīng)常被網(wǎng)頁(yè)開(kāi)發(fā)者忽略卻往往十分浪費(fèi)響應(yīng)時(shí)間的跳轉(zhuǎn)現(xiàn)象。這種現(xiàn)象發(fā)生在當(dāng)URL本該有斜杠(/)卻被忽略掉時(shí)。這時(shí)候會(huì)返回一個(gè)301的狀態(tài)碼,然后瀏覽器重新發(fā)起一次請(qǐng)求.在企業(yè)應(yīng)用里,重定向是我們?cè)谄髽I(yè)應(yīng)用中常用的技術(shù),不過(guò)用在網(wǎng)站項(xiàng)目上,您可要小心了,因?yàn)槠胀ǖ闹囟ㄏ蚱鋵?shí)是server在response header中設(shè)置http status=302,瀏覽器收到之后,判斷出是302,會(huì)重新發(fā)送一個(gè)請(qǐng)求,目標(biāo)地址是前一次返回中指定的地址.在網(wǎng)站項(xiàng)目中如果可以不用重定向就別用吧.如果您做企業(yè)應(yīng)用項(xiàng)目,ok,關(guān)系不大,您就放心的”定”吧.

          小節(jié),ahuaxuan把減少http請(qǐng)求次數(shù)分為了以上5個(gè)小點(diǎn),每個(gè)小點(diǎn)之后附加一些實(shí)例,大家可以根據(jù)這些點(diǎn)來(lái)判斷自己的項(xiàng)目是否可以有優(yōu)化的地方.


          使用cdn
          讓內(nèi)容更靠近用戶,這有啥好說(shuō)呢,原理很簡(jiǎn)單,就是根據(jù)用戶瀏覽器所在機(jī)器的ip來(lái)判斷哪些服務(wù)器離用戶最近,瀏覽器會(huì)再次去請(qǐng)求這些最近的機(jī)器.一般的cdn服務(wù)商是通過(guò)開(kāi)發(fā)自己的dns server來(lái)達(dá)到這個(gè)目的的.不過(guò)這個(gè)是通常情況哦,技術(shù)實(shí)力比較高,或者場(chǎng)景比較特殊的公司會(huì)開(kāi)發(fā)自己的cdn.當(dāng)然不管怎么說(shuō),使用cdn肯定可以使頁(yè)面響應(yīng)更快(也包括音頻,視頻,圖片,文本文件,等等等等)

          減小返回?cái)?shù)據(jù)的體積
          1. 使用gzip壓縮返回?cái)?shù)據(jù)
          Gzip壓縮所有可能的文件類型是減少文件體積增加用戶體驗(yàn)的簡(jiǎn)單方法。比如本來(lái)400k的文件,壓縮一下之后只有50k-100k,那么網(wǎng)絡(luò)的流量就立刻下來(lái)了,壓縮的代價(jià)是服務(wù)器端要壓縮文件,需要消耗cpu,瀏覽器需要解壓文件,也需要消耗cpu,不過(guò)對(duì)于現(xiàn)代這么nb的pc,來(lái)說(shuō),瀏覽器解壓一下數(shù)據(jù)帶來(lái)的cpu消耗簡(jiǎn)直不值一提.所以您就壓吧.不過(guò)壓的時(shí)候要小心哦,有的瀏覽器在特定場(chǎng)景下會(huì)出去一些小bug,導(dǎo)致頁(yè)面不正常.比如ie6在跨域的時(shí)候可能會(huì)有些小麻煩,把這部分?jǐn)?shù)據(jù)的gzip去掉就可以了.

          2. 最小化js文件和css文件
          壓縮js可以使用JSMin或者YUI Compressor,后者同時(shí)可以壓縮css,這個(gè)也沒(méi)啥好說(shuō)的,照做吧.

          3. 將css和js獨(dú)立成外部文件
          其實(shí)這一點(diǎn)也可以看成是區(qū)分不變數(shù)據(jù)和變化數(shù)據(jù).很多人喜歡在頁(yè)面商寫(xiě)很多很多的js和css,這些數(shù)據(jù)其實(shí)都是不會(huì)變化的數(shù)據(jù),也就是說(shuō)這些數(shù)據(jù)也是可以緩存在瀏覽器上的,通過(guò)把它們獨(dú)立成外部文件,可以把這些數(shù)據(jù)緩存起來(lái).這樣做看上去是增加的請(qǐng)求的次數(shù),但是由于第一次請(qǐng)求之后該部分?jǐn)?shù)據(jù)已經(jīng)被緩存,所以第二次就無(wú)需再請(qǐng)求后端,減少了網(wǎng)絡(luò)帶寬的開(kāi)銷.

          優(yōu)化Cookie

          1. 減小cookie體積
          能不放就別放吧,為啥呀,cookie就象鑰匙串,只有出門(mén)和回家得時(shí)候才用,但是一整天你都要帶在身上,麻煩不.
          2. 合理設(shè)置Cookie域
          由于二級(jí)域名可以拿到一級(jí)域名得cookie,那么如果,而二級(jí)域名之間確不能相互共享cookie,所以合理得設(shè)置cookie得域名也可以避免無(wú)必要得帶寬浪費(fèi)和響應(yīng)速度得增加.
          3. 設(shè)置合理的cookie過(guò)期時(shí)間
          該過(guò)期就過(guò)期,不要讓不必要的數(shù)據(jù)一直帶在身上走來(lái)走去.
          4. 使用域分離
          為圖片或者其他靜態(tài)資源文件使用子域或者建立新的獨(dú)立域名(申請(qǐng)新的域名),避免無(wú)必要的cookie傳輸,當(dāng)然也是要在有必要得情況下,圖片類網(wǎng)站肯定有必要,javaeye上得圖片并沒(méi)有使用域分離,所以我們得cookie其實(shí)會(huì)帶到壇子得圖片服務(wù)器上去,每次請(qǐng)求圖片都是如此(不過(guò)還好,壇子里沒(méi)有什么圖片,所以這方面的浪費(fèi)不大).

          小結(jié),其實(shí)cookie上得問(wèn)題,單詞請(qǐng)求看上去也不是什么大問(wèn)題,好像是無(wú)所謂得事情,就那么幾十個(gè)byte,至于嗎,不過(guò)大家都聽(tīng)說(shuō)過(guò)水滴石穿,繩鋸木斷的故事.所以該做的,我們還是要做,正所謂,勿以善小而不為,勿以惡小而為之.
          優(yōu)化瀏覽器加載
          1. 將css放在頁(yè)面頂部加載
          把樣式表放在文檔底部的問(wèn)題是在包括Internet Explorer在內(nèi)的很多瀏覽器中這會(huì)中止內(nèi)容的有序呈現(xiàn)。瀏覽器中止呈現(xiàn)是為了避免樣式改變引起的頁(yè)面元素重繪。用戶不得不面對(duì)一個(gè)空白頁(yè)面。
                HTML規(guī)范清 楚指出樣式表要放包含在頁(yè)面的<head />區(qū)域內(nèi):“和<a />不同,<link />只能出現(xiàn)在文檔的<head />區(qū)域內(nèi),盡管它可以多次使用它”。無(wú)論是引起白屏還是出現(xiàn)沒(méi)有樣式化的內(nèi)容都不值得去嘗試。最好的方案就是按照HTML規(guī)范在文 檔<head />內(nèi)加載你的樣式表。

          2. 將js放在頁(yè)面底部加載
          腳本帶來(lái)的問(wèn)題就是它阻止了頁(yè)面的平行下載。HTTP/1.1 規(guī)范建議,瀏覽器每個(gè)主機(jī)名的并行下載內(nèi)容不超過(guò)兩個(gè)。如果你的圖片放在多個(gè)主機(jī)名上,你可以在每個(gè)并行下載中同時(shí)下載2個(gè)以上的文件。但是當(dāng)下載腳本時(shí),瀏覽器就不會(huì)同時(shí)下載其它文件了,即便是主機(jī)名不相同。

          Js放在底部加載其實(shí)并不影響瀏覽器展示頁(yè)面,除非用戶會(huì)在js加載完成之前就調(diào)用某個(gè)js方法,比如說(shuō)頁(yè)面剛展現(xiàn)到一半,但是恰好這一半里有一部分是調(diào)用了還未下載的js,這個(gè)時(shí)候就會(huì)出問(wèn)題了,如果童子們遇到這種情況,可以把這部分js先加載.

              
          總結(jié)一下下:以上這些優(yōu)化點(diǎn)其實(shí)只是前端優(yōu)化的部分內(nèi)容,不過(guò)根據(jù)80/20原則,這些優(yōu)化點(diǎn)已經(jīng)覆蓋了80%的情況了,同時(shí)前端優(yōu)化其實(shí)也不是什么復(fù)雜的東西,原理上是很簡(jiǎn)單的,更多的是需要我們的實(shí)踐,因?yàn)槲覀兛赡軙?huì)碰到各種各樣的問(wèn)題,而很多的這些問(wèn)題其實(shí)一般是預(yù)測(cè)不到的.只有遇到過(guò)才知道.
          說(shuō)的不對(duì)的地方請(qǐng)大家拍磚,或者童子們也可以把自己的經(jīng)驗(yàn)在這里和大家分享一下.代表其他童子表示十分的感謝.

          當(dāng)然,由于ahuaxuan水平有限,文章中難免有不到之處,還望不吝指正,謝謝.
          posted @ 2008-12-04 20:31 bt下載 閱讀(1553) | 評(píng)論 (3)編輯 收藏

          企業(yè)向國(guó)家工商總局申請(qǐng)對(duì)百度濫用市場(chǎng)支配地位進(jìn)行反壟斷調(diào)查,并處1.7億元罰款 bt吧。

            本報(bào)記者 韋文潔

            目前,國(guó)內(nèi)對(duì)百度的競(jìng)價(jià)排名雖然詬病頗多,但在制約手段的建立上處于真空狀態(tài),缺乏相應(yīng)的措施。在業(yè)界評(píng)論家看來(lái),如果國(guó)內(nèi)搜索控制輿論沒(méi)有相關(guān)的法律法規(guī)來(lái)制裁,總有一天,網(wǎng)絡(luò)自由也將會(huì)淪為資本的附屬品 色即是空

            2008年的這個(gè)秋天,對(duì)北京百度網(wǎng)訊科技有限公司(以下簡(jiǎn)稱百度)來(lái)說(shuō),可謂多事之秋。

            10月31日,就在秋末的最后這幾天,受河北唐山人人信息服務(wù)有限公司法定代表人王冠玨的委托,北京市邦道律師事務(wù)所李長(zhǎng)青律師,把一冊(cè)厚達(dá)91頁(yè)16開(kāi)本的《反壟斷調(diào)查申請(qǐng)書(shū)》,送到了國(guó)家工商總局反壟斷處一位官員手中,申請(qǐng)對(duì)百度濫用市場(chǎng)支配地位的反壟斷調(diào)查。據(jù)這位官員告訴他,這是反壟斷法實(shí)施以來(lái),發(fā)生在網(wǎng)絡(luò)領(lǐng)域的第一例。

            而在此之前,9月8日,淘寶網(wǎng)“為杜絕不良商家欺詐”,首次向外界宣布屏蔽百度搜索鏈接,向其公正性公開(kāi)提出抗議;9月12日,百度因被披露涉嫌收取300萬(wàn)元保護(hù)費(fèi)屏蔽三鹿奶粉負(fù)面新聞,被卷入震驚全國(guó)的“三鹿問(wèn)題奶粉”事件之中,成為公眾口誅筆伐的對(duì)象。

            更早一些,在今年的秋初,因質(zhì)疑“競(jìng)價(jià)排名”的貓膩,百度就被深圳律師黃維領(lǐng)告上法院,如果不是百度提出管轄權(quán)異議,此案恐怕已在深圳市福田區(qū)人民法院開(kāi)庭審理。

            “發(fā)難”一場(chǎng)連接一場(chǎng),面對(duì)來(lái)自南北的不斷夾擊,百度這個(gè)“全球最大的中文搜索引擎”,如何將這股訴訟潮化險(xiǎn)為夷,巧渡搜索引擎行業(yè)所面臨的經(jīng)營(yíng)模式之困,化解新技術(shù)帶來(lái)的法律難題,成為業(yè)界關(guān)注的焦點(diǎn)。

            異常變化

            2007年初,曾有10年經(jīng)營(yíng)藥品生意的唐山人王冠玨,在工商局登記注冊(cè)了唐山人人信息服務(wù)有限公司,創(chuàng)辦了一個(gè)普及醫(yī)藥知識(shí)及招商的網(wǎng)站———全民醫(yī)藥網(wǎng)。

            為了提高網(wǎng)站的點(diǎn)擊率,增加客流量,全民醫(yī)藥網(wǎng)和百度河北代理商簽了一個(gè)《競(jìng)價(jià)排名協(xié)議》。

            所謂“競(jìng)價(jià)排名”,就是搜索引擎商推出的一種業(yè)務(wù)。當(dāng)用戶搜索一些常用詞語(yǔ)時(shí),從搜索引擎服務(wù)商購(gòu)買了服務(wù)的廠商的名字就會(huì)排在搜索的前列。每當(dāng)用戶點(diǎn)擊搜索的結(jié)果進(jìn)入廠商的主頁(yè)時(shí),廠商就要向搜索引擎服務(wù)商繳納一次費(fèi)用,也就是搜索引擎的廣告收入。

            全民醫(yī)藥網(wǎng)和百度簽訂的這個(gè)競(jìng)價(jià)排名,參與時(shí)間為2008年3月至9月份,金額8.9萬(wàn)元,排位于第3名,點(diǎn)擊一次最低價(jià)格為0.55元,最高為3.8元。

            參與競(jìng)價(jià)的最初幾個(gè)月,是全民醫(yī)藥網(wǎng)和百度的蜜月期。全民醫(yī)藥網(wǎng)做的全國(guó)廠家招商、招會(huì)員,在百度搜索排第一名。他們網(wǎng)站的客流,高峰時(shí)日瀏覽量達(dá)8000次,每月固定客戶以1000人的比例上漲。

            誰(shuí)知前景開(kāi)始看好的時(shí)候,因?yàn)槿襻t(yī)藥網(wǎng)要改版,6月至8月,全民醫(yī)藥網(wǎng)把競(jìng)價(jià)支付價(jià)格調(diào)到最低時(shí),異常便開(kāi)始出現(xiàn)了。

            7月5日一上班,商務(wù)部經(jīng)理李娟就慌慌張張地跑來(lái)告訴王冠玨,“今天在百度里輸入全民醫(yī)藥網(wǎng)的網(wǎng)址,鏈接一下子突然少了,以前的八萬(wàn)多條信息,只剩下了一個(gè)頁(yè)面4條記錄”。

            身為商人的王冠玨深知,訪問(wèn)量就是網(wǎng)站的生命,新客戶來(lái)不了,老客戶不會(huì)來(lái),做免費(fèi)的廣告,商家也不會(huì)干。從百度來(lái)的訪問(wèn)量一直占全民醫(yī)藥網(wǎng)90%的客流量,如果不及時(shí)改變這種異常變化,全民醫(yī)藥網(wǎng)只能是“坐以待斃。”

            為了解決面臨的“滅頂之災(zāi)”,作為百度的一個(gè)客戶,王冠玨趕緊讓技術(shù)部長(zhǎng)王運(yùn)嶺,給百度總部和百度石家莊代理商發(fā)信和去電,反映這一異常變化。但百度的電話始終打不通。最后好不容易收到了石家莊百度的回信:“通常這種變化是正常的,是完全自動(dòng)的,并不表示會(huì)對(duì)個(gè)別網(wǎng)站進(jìn)行懲罰。”

            可是,讓王冠玨焦慮不已的是,到了7月10日,全民醫(yī)藥網(wǎng)的日訪問(wèn)量驟減,從前一日的2961IP驟減為701IP。而后來(lái)以2008年7月10日為分界點(diǎn)的前后兩個(gè)月對(duì)比,全民醫(yī)藥網(wǎng)的月訪問(wèn)量從前一個(gè)月的88095IP銳減至18340IP,日均訪問(wèn)量從2936IP銳減至611IP,會(huì)員已經(jīng)在網(wǎng)上搜不到全民醫(yī)藥網(wǎng),網(wǎng)站幾乎沒(méi)人來(lái)光顧了。再和百度聯(lián)系,一點(diǎn)音信都沒(méi)有。

            7月14日,焦慮不已的王冠玨不得不再次給百度去信哀求:“就算是你們客服說(shuō)的是因?yàn)橄到y(tǒng)自動(dòng)更新,但更新也不能差距這么大呀?現(xiàn)在幾乎就在百度里找不到帶著全民醫(yī)藥網(wǎng)域名的內(nèi)容了……請(qǐng)幫我們查出原因,速回郵件或致電。”

            但直到現(xiàn)在,他也沒(méi)有等來(lái)百度的郵件或回電。

            “降權(quán)懲罰”

            9月初,王冠玨給全民醫(yī)藥網(wǎng)換了一個(gè)域名,希望百度能夠收錄他們網(wǎng)站,但是一個(gè)月過(guò)去了,一條記錄都沒(méi)有。

            2008年9月25日,王冠玨在查詢谷歌、雅虎對(duì)全民醫(yī)藥網(wǎng)的收錄情況時(shí),結(jié)果分別顯示為6690條及3000多條,而其他的包括有道、搜狗,都比百度多。

            面對(duì)這種異常,王冠玨真是百思不解。經(jīng)過(guò)走訪大量的網(wǎng)站,咨詢行內(nèi)專家,翻閱大量資料后,發(fā)現(xiàn)他們也遭遇過(guò)類似的結(jié)果。

            一些站長(zhǎng)告訴他,之前在百度做了競(jìng)價(jià)排名,如果后來(lái)不做,很容易就被百度屏蔽了。比如:重慶某知名民營(yíng)醫(yī)院在建立自己的網(wǎng)站后,在百度、谷歌、雅虎等搜索引擎上搜索排名一直排第一。但是,從今年8月開(kāi)始,用百度竟然再也搜索不到醫(yī)院網(wǎng)站了,但用谷歌、雅虎卻能夠搜索到,而且還是排位第一。這讓醫(yī)院感到十分疑惑,便以各種方式向百度反映這一情況,但都未得到令人信服的答復(fù)。迫于無(wú)奈,醫(yī)院負(fù)責(zé)人趕緊投錢參加百度的競(jìng)價(jià)排名,很快,醫(yī)院的網(wǎng)站又“神奇地”在百度上出現(xiàn)了。

            2005年10月至2006年4月,365數(shù)碼網(wǎng)曾在百度做競(jìng)價(jià)排名廣告。而當(dāng)他們停止續(xù)費(fèi),不再在百度上投放廣告后,竟然被百度“屏蔽”。

            據(jù)中搜網(wǎng)的技術(shù)專家介紹,所有的搜索結(jié)果都可以進(jìn)行人工干預(yù),所謂屏蔽就是在搜索程序中嵌入針對(duì)特定信息的“黑名單”,從而使機(jī)器自動(dòng)不去抓取指定域名的網(wǎng)頁(yè),從而實(shí)現(xiàn)自己的營(yíng)銷目的。

            王冠玨的一位網(wǎng)友還告訴他,其代理的客戶大部分在行業(yè)中有較強(qiáng)的影響,網(wǎng)站也都具有相當(dāng)?shù)牧髁俊T谫?gòu)買百度關(guān)鍵詞競(jìng)價(jià)之前,在百度搜索頁(yè)左邊的排序中,基本都能排在前幾名,而在購(gòu)買了百度的關(guān)鍵詞競(jìng)價(jià)服務(wù)后,反而在首頁(yè)很難找到。

            “顯然,百度在非付費(fèi)的自然排序中有意下降客戶的排名,目的就是希望這些客戶對(duì)于關(guān)鍵詞競(jìng)價(jià)這種付費(fèi)服務(wù)產(chǎn)生依賴。”王冠玨的網(wǎng)友說(shuō)。

            因此,早在2005年,一些網(wǎng)站站長(zhǎng)甚至結(jié)成了“反百度聯(lián)盟”,并且獲得了信息產(chǎn)業(yè)部備案序號(hào)(豫ICP備05009507)。據(jù)《瞭望》報(bào)道,聯(lián)盟的發(fā)起人郭振東,2004年發(fā)現(xiàn)自己創(chuàng)辦的文學(xué)網(wǎng)站美人魚(yú)社區(qū)被百度屏蔽。此后,他在與百度上海公司員工的接觸中獲悉,只要交6000元就能將被封的網(wǎng)站解禁,并承諾在一年內(nèi)不再屏蔽。因此,他認(rèn)為百度之所以對(duì)網(wǎng)站進(jìn)行屏蔽,是為了推廣百度的競(jìng)價(jià)排名服務(wù),遂發(fā)起“反百度聯(lián)盟”,收集百度公司對(duì)待站長(zhǎng)和網(wǎng)友不公正的證據(jù)。

            “沒(méi)在百度做競(jìng)價(jià)排名廣告前,還可以在百度上搜索到365數(shù)碼網(wǎng),現(xiàn)在卻搜不到了。早知道這樣,還不如一開(kāi)始就不做呢。”該365數(shù)碼網(wǎng)負(fù)責(zé)人認(rèn)為,百度“封殺”365數(shù)碼網(wǎng)的目的,在于迫使其繼續(xù)交錢給百度做競(jìng)價(jià)排名廣告。

            “最令人不服氣的是,用什么評(píng)定中小網(wǎng)站該不該被屏蔽,這一系列的標(biāo)準(zhǔn)都是百度自己在操作,外人無(wú)法知道,更無(wú)法考證和干涉。”一位網(wǎng)友告訴王冠玨。

            看一看他人,比一比自己,王冠玨徹底明白了,因?yàn)樽约旱木W(wǎng)站開(kāi)始有了4000以上的客流量,它一看你的IP這么高,開(kāi)始能賺到錢,為什么還不到我這里來(lái)交錢?便給你的網(wǎng)站來(lái)了個(gè)“降權(quán)懲罰。”

            但百度企業(yè)市場(chǎng)部總監(jiān)舒迅曾對(duì)“屏蔽”一說(shuō)斷然否認(rèn):“百度搜索引擎上是否收錄一個(gè)網(wǎng)站,與這個(gè)網(wǎng)站是否參與百度競(jìng)價(jià)排名推廣沒(méi)有任何關(guān)系。百度收錄的中文網(wǎng)站數(shù)是全球最多的,但并不承諾收錄每一個(gè)網(wǎng)站。”

          百度壟斷

            “百度一下”,幾乎已經(jīng)成為廣大網(wǎng)民最為常見(jiàn)的習(xí)慣性搜索。

            自7月份以來(lái),不斷有客戶問(wèn)王冠玨:“在網(wǎng)上為什么搜不到你們網(wǎng)站?”網(wǎng)民一般都使用百度,他們認(rèn)為在百度搜不到,就是在網(wǎng)上搜不到。

            李長(zhǎng)青律師認(rèn)為,百度的屏蔽行為對(duì)其他網(wǎng)站之所以構(gòu)成封殺是基于其獲得的市場(chǎng)支配地位。

            據(jù)相關(guān)資料表明,2008年第2季度,百度占據(jù)中國(guó)搜索引擎市場(chǎng)份額的64.4%。第3季度,坐擁中國(guó)搜索市場(chǎng)近2/3份額。到今年10月23日,百度網(wǎng)站發(fā)布公司新聞,已經(jīng)在中國(guó)搜索引擎市場(chǎng)穩(wěn)穩(wěn)占據(jù)70%以上市場(chǎng)份額。雖然它不過(guò)是一個(gè)工具,但它現(xiàn)在形成了一個(gè)霸主的地位。將對(duì)手遠(yuǎn)遠(yuǎn)拋在后面。

            《反壟斷法》第19條第一款第一項(xiàng)規(guī)定,有下列情形之一的,可以推定經(jīng)營(yíng)者具有市場(chǎng)支配地位:一個(gè)經(jīng)營(yíng)者在相關(guān)市場(chǎng)的市場(chǎng)份額達(dá)到二分之一的。上述資料表明,百度已經(jīng)完全獲得了中國(guó)搜索引擎市場(chǎng)的支配地位。

            正是因?yàn)榘俣染哂辛诉@樣的市場(chǎng)地位,其屏蔽行為才具有了封殺其他網(wǎng)站的能量和效果。百度也利用此舉,贏得了巨大的收益:2007年,百度年收入為17.444億元人民幣,比2006年增長(zhǎng)108.2%。而其2008年第二季度的財(cái)報(bào)顯示,收入突破一億美元。

            記者一位在北京經(jīng)營(yíng)網(wǎng)站的朋友則認(rèn)為,對(duì)于眾多中小網(wǎng)站來(lái)講,其絕大多數(shù)的流量都來(lái)自于百度搜索引擎這個(gè)“入口”。因?yàn)榻^大多數(shù)網(wǎng)民往往只能記住網(wǎng)站的名稱,然后通過(guò)搜索到達(dá)該網(wǎng)站。因此,擺在眾多網(wǎng)站面前的一個(gè)現(xiàn)實(shí)問(wèn)題是,網(wǎng)站流量的訪問(wèn)入口已經(jīng)被百度這些大搜索巨頭所壟斷,網(wǎng)站的生殺大權(quán)事實(shí)上已經(jīng)被掌握在了別人手中。一旦被搜索引擎“屏蔽”,就很有可能導(dǎo)致網(wǎng)站失去流量。對(duì)于搜索引擎“競(jìng)價(jià)排名”的方式,中小網(wǎng)站雖然不滿,但為了生存,大多數(shù)都敢怒不敢言。

            現(xiàn)在擺在他們面前的只有兩條路:如果想逃避被百度封殺的厄運(yùn),要么屈服于它,參與競(jìng)價(jià)推廣,任其宰割;要么向反壟斷部門(mén)舉報(bào),或到法院起訴,通過(guò)打官司,尋求公正。

            對(duì)王冠玨而言,擺在他面前的這兩條路,沒(méi)有一條坦途。

            “生死之戰(zhàn)”

            就在瀕臨絕望的時(shí)候,8月1日起施行的《反壟斷法》,讓王冠玨瞬間下定了決心:“我看到了希望。只要法律是公正的,哪怕我失敗,也要去摸這個(gè)老虎屁股。否則,你投入再多,由它來(lái)主宰,這種狀況永遠(yuǎn)也無(wú)法改變。”

            10月31日,在送往國(guó)家工商總局反壟斷處的《反壟斷調(diào)查申請(qǐng)書(shū)》中,李長(zhǎng)青律師認(rèn)為,百度對(duì)其他網(wǎng)站的封殺,是濫用市場(chǎng)支配地位的行為,造成兩個(gè)嚴(yán)重的社會(huì)后果:其一、百度的封殺行為在實(shí)際上消滅了許多網(wǎng)絡(luò)經(jīng)濟(jì)中的市場(chǎng)競(jìng)爭(zhēng)主體,從根本上破壞了公平的市場(chǎng)競(jìng)爭(zhēng)秩序,嚴(yán)重?fù)p害了社會(huì)主義市場(chǎng)經(jīng)濟(jì)的活力;其二、出于商業(yè)目的人工干預(yù)搜索結(jié)果的行為損害了社會(huì)大眾的利益,不符合公眾對(duì)于信息公開(kāi)、客觀的要求。其行為與敲詐勒索無(wú)二。這種網(wǎng)絡(luò)霸權(quán)主義,不僅應(yīng)該受到道義上的譴責(zé),而且應(yīng)該受到行政和法律的制裁。

            他建議:執(zhí)法機(jī)構(gòu)對(duì)百度使用的搜索技術(shù)規(guī)則和搜索過(guò)程進(jìn)行調(diào)查;制定搜索技術(shù)規(guī)范和搜索市場(chǎng)服務(wù)規(guī)范,強(qiáng)化對(duì)搜索引擎服務(wù)的管理;責(zé)令百度停止其濫用市場(chǎng)支配地位封殺其他網(wǎng)站的違法行為,并處以1.7444億元人民幣的罰款(《中華人民共和國(guó)反壟斷法》第47條規(guī)定:經(jīng)營(yíng)者違反本法規(guī)定,濫用市場(chǎng)支配地位的,由反壟斷執(zhí)法機(jī)構(gòu)責(zé)令停止違法行為,沒(méi)收違法所得,并處上一年度銷售額百分之一以上百分之十以下的罰款。2007年百度全年?duì)I業(yè)收入為17.444億人民幣,根據(jù)以上規(guī)定,可以對(duì)其處以1.7444億元人民幣的罰款)。

            中國(guó)互聯(lián)網(wǎng)協(xié)會(huì)互聯(lián)網(wǎng)政策與資源工作委員會(huì)學(xué)術(shù)專家胡鋼曾對(duì)媒體表示,搜索引擎的“推廣方式”或“贊助商鏈接”在本質(zhì)上依然屬于廣告。但由于嶄新性,搜索引擎尚處在廣告法的監(jiān)管盲區(qū),這使得搜索引擎服務(wù)商得以明目張膽地大打“擦邊球”。

            中國(guó)政法大學(xué)副教授吳景明則認(rèn)為,我國(guó)《廣告法》第13條早已規(guī)定:廣告應(yīng)當(dāng)具有可識(shí)別性,能夠使消費(fèi)者辨明其為廣告。而搜索行業(yè)的競(jìng)價(jià)排名未能被明確劃歸到廣告范圍,類似搜索引擎這類新技術(shù)應(yīng)用帶來(lái)的問(wèn)題該如何適用法律,目前尚無(wú)定論,“這凸顯我國(guó)相關(guān)立法的滯后”。

            互聯(lián)法網(wǎng)總監(jiān)趙占領(lǐng)也認(rèn)為:“這類事件反映出我國(guó)互聯(lián)網(wǎng)領(lǐng)域還存在很多法律空白或爭(zhēng)議之處。比如廣告法和反不正當(dāng)競(jìng)爭(zhēng)法如何適用于網(wǎng)絡(luò)環(huán)境下?搜索引擎運(yùn)營(yíng)商在用戶沒(méi)有購(gòu)買競(jìng)價(jià)排名的情況下,不收錄用戶的網(wǎng)站究竟該如何定性?是否屬于強(qiáng)制交易行為?這都需要提供證據(jù)來(lái)證明搜索引擎運(yùn)營(yíng)商此舉的初衷是為了達(dá)成交易。”

            目前,國(guó)內(nèi)對(duì)百度的競(jìng)價(jià)排名雖然詬病頗多,但在制約手段的建立上處于真空狀態(tài),缺乏相應(yīng)的措施。在業(yè)界評(píng)論家看來(lái),如果國(guó)內(nèi)搜索控制輿論沒(méi)有相關(guān)的法律法規(guī)來(lái)制裁,總有一天,網(wǎng)絡(luò)自由也將會(huì)淪為資本的附屬品。

            現(xiàn)在,也許是政府部門(mén)著手解決這個(gè)問(wèn)題的最佳時(shí)間。10月31日,李長(zhǎng)青律師送材料到國(guó)家工商總局反壟斷處時(shí),一位官員告訴他:“內(nèi)部也正在開(kāi)會(huì),研討這方面的問(wèn)題呢。”

            在等待行政申請(qǐng)結(jié)果的同時(shí),他正忙著收集證據(jù),準(zhǔn)備一旦時(shí)機(jī)成熟,要與百度對(duì)簿公堂,展開(kāi)一場(chǎng)面對(duì)面的“生死之戰(zhàn)”。而“一旦這個(gè)口子打開(kāi)了,救活的就不僅僅是全民醫(yī)藥網(wǎng)這一家了,而是所有的中小網(wǎng)站和中國(guó)的互聯(lián)網(wǎng)經(jīng)濟(jì)。”李長(zhǎng)青律師說(shuō)。

          posted @ 2008-11-09 22:08 bt下載 閱讀(231) | 評(píng)論 (0)編輯 收藏

          這是 Mashable bt搜集的最新 Web 開(kāi)發(fā)工具箱,包括拖放式 Web 程序創(chuàng)建工具,代碼庫(kù),項(xiàng)目管理,測(cè)試程序,以及支持各種編程語(yǔ)言的框架,從 Ajax 到 Ruby 到 Python。這是第二部分。

            參考與資料


          COfundOS - 一個(gè)討論開(kāi)源軟件,尋找投資的平臺(tái)。 http://www.5a520.cn
          Mac Yenta - 獨(dú)立 Mac 開(kāi)發(fā)者的社會(huì)化網(wǎng)絡(luò)平臺(tái)
          CorkDump - 一個(gè)關(guān)于常用資源(代碼片段,CSS,F(xiàn)lash 等)討論板。
          All Developers Network - 開(kāi)發(fā)者社會(huì)化網(wǎng)絡(luò)
          CodePlex - 來(lái)自微軟的開(kāi)源項(xiàng)目托管站點(diǎn)


          UnmatchList - 開(kāi)發(fā)設(shè)計(jì)者的資源庫(kù)
          developerAnalytics - 社會(huì)媒體評(píng)價(jià)與報(bào)告,幫助你發(fā)現(xiàn)有潛力的社會(huì)媒體應(yīng)用。
          CollabFinder - 一個(gè)供開(kāi)發(fā)設(shè)計(jì)者協(xié)同工作的地方。
          測(cè)試,監(jiān)控,Bug 跟蹤,項(xiàng)目管理



          CloudStatus - 對(duì) Web 上最流行云服務(wù)進(jìn)行觀察

          BetaBitz - 一個(gè)幫助你尋找 Beta 測(cè)試者的地方

          observu - 免費(fèi)的網(wǎng)站與服務(wù)器監(jiān)測(cè)服務(wù)

          UserFix - Bug 報(bào)告與功能請(qǐng)求站點(diǎn)

          OctaGate SiteTimer - 用來(lái)測(cè)試你的站點(diǎn)的訪問(wèn)時(shí)延



          Cuzillion - 簡(jiǎn)單的頁(yè)面測(cè)試與檢查程序

          Mob4Hire - 為你的移動(dòng)應(yīng)用程序需要大量測(cè)試者

          Beanstalk - 一個(gè)托管的服務(wù),用來(lái)瀏覽跟蹤版本控制,包含對(duì)Basecamp 以及 Campfire 等同類服務(wù)的集成。

          BUGtrack - 項(xiàng)目管理,Bug 跟蹤

          UserZoom - 用戶體驗(yàn)測(cè)試平臺(tái)


          devunity - 曾是一個(gè) Beta 版 Bug 跟蹤服務(wù),現(xiàn)已成為社會(huì)化開(kāi)發(fā)平臺(tái)
          BuiltWith - 對(duì)任何站點(diǎn)提供技術(shù)分析與 SEO 信息服務(wù)
          fixx - Bug 跟蹤,包含移動(dòng)設(shè)備界面與協(xié)同功能
          BugWiki - 一個(gè)簡(jiǎn)易的 Bug 跟蹤系統(tǒng)
          litmus - 基于 Web 的測(cè)試程序,在不同瀏覽器上檢查你的設(shè)計(jì)


          Bugtagger - 一個(gè)包含標(biāo)簽機(jī)制的 Bug 跟蹤程序,方便找到每個(gè) Bug 是與什么相關(guān)的
          FEED Validator - 驗(yàn)證你的 Atom, RSS 以及 KML 聚合服務(wù)
          pastebin - Debug 工具允許你協(xié)同工作以找到問(wèn)題所在
          JUnit.org - 一個(gè)測(cè)試框架,編寫(xiě)并執(zhí)行自動(dòng)測(cè)試程序
            Ruby 以及 Ruby on Rails 資源與工具


          Open Source Rails - 一個(gè)用來(lái)展示基于開(kāi)源 Ruby on Rails 站點(diǎn)的地方
          Exceptional - Rails 程序異常跟蹤與管理工具
          TuneUp - 使用 Rails 插件檢查你的程序的性能
          heroku - Ruby on Rails平臺(tái),無(wú)需安裝配置,直接在瀏覽器中寫(xiě)代碼。
          RSpec 1.1.8 - Ruby 的開(kāi)發(fā)框架,包括 Scenario 框架與代碼示例框架



          Lovd By Less - 一個(gè)開(kāi)源的 Ruby on Rails 社會(huì)網(wǎng)絡(luò)平臺(tái)
          Merb - 一個(gè) Ruby 框架,包含廣泛功能
          Camping - 一個(gè) Ruby 微框架
            Ajax, Java & JavaScript 資源與工具


          Javxs - 在線工具,將 HTML 轉(zhuǎn)換為 JavaScript
          frevvo - 一個(gè) Ajax 表單創(chuàng)建工具,包括 XML 支持與拖放式控制
          AjaxDaddy - Ajax 程序演示
          WaveMaker - 可視化,開(kāi)源 Ajax 所見(jiàn)即所得編輯器
          AppJet - JavaScript 程序編寫(xiě)平臺(tái)



          SproutCore - 一個(gè) JavaScript 框架,用來(lái)創(chuàng)建桌面質(zhì)量的 Web 程序
          Bungee Connect - Ajax Web 程序平臺(tái),跨瀏覽器支持
          Spring - 企業(yè) Java 應(yīng)用平臺(tái),旨在提高開(kāi)發(fā)效率與程序質(zhì)量
          jQuery - 一個(gè)用于 Ajax Web 開(kāi)發(fā)的 JavaScript 庫(kù)。
          KSS - 使用該框架,無(wú)需編寫(xiě)任何代碼就可以開(kāi)發(fā)基于 javaScript 的 UI
              PHP 資源與工具


          Flow3 - 一個(gè)最初用于 TYPO3 5.0 的 PHP 框架,但可以獨(dú)立使用
          Prado - 一個(gè)基于組件的 PHP 5 編程框架,面向?qū)ο螅录?qū)動(dòng)
            Perl 資源與工具


          Mason - 基于 Perl 的 網(wǎng)站開(kāi)發(fā)引擎,包含 Debug, 模板等工具
            Flash 資源與工具


          OpenLaszlo - 富 Internet 平臺(tái),結(jié)合 Flash 與 DHTML,但只需一次編寫(xiě)
            Python 資源與工具


          GTK+ - 一個(gè)用于 Python 的 GUI 開(kāi)發(fā)工具套件
          Wing IDE - 專業(yè)的 Python 開(kāi)發(fā)環(huán)境,提供30天試用
          Cheetah - 一個(gè)開(kāi)源的,基于 Python 的模板引擎與代碼生成工具

          posted @ 2008-11-06 19:51 bt下載 閱讀(230) | 評(píng)論 (0)編輯 收藏

          新聞來(lái)源:mashable.com
          這是 Mashable bt搜集的最新 Web 開(kāi)發(fā)工具箱,包括拖放式 Web 程序創(chuàng)建工具,代碼庫(kù),項(xiàng)目管理,測(cè)試程序,以及支持各種編程語(yǔ)言的框架,從 Ajax 到 Ruby 到 Python。這是第一部分。

          Web 程序創(chuàng)建類


          DreamFace - 一個(gè)用來(lái)創(chuàng)建個(gè)性化 Web 程序的框架。

          Organic Incentive - 以拖放式界面創(chuàng)建 Web 飾件 http://www.5a520.cn

          dbFLEX - 商務(wù)程序開(kāi)發(fā)平臺(tái)。

          app2you - 在線創(chuàng)建與定制 Web 程序。

          Qrimp - 一個(gè)便宜的數(shù)據(jù)庫(kù)平臺(tái),基于你周圍的數(shù)據(jù)(如 Excel)創(chuàng)建應(yīng)用程序。





          Lightspoke - 拖放式程序創(chuàng)建工具,動(dòng)態(tài)過(guò)濾,排序,真正的關(guān)系數(shù)據(jù)庫(kù)后臺(tái)。

          Tersus - 可視化程序創(chuàng)建工具,無(wú)需編寫(xiě)代碼。

          Qt - 跨平臺(tái)應(yīng)用程序框架,可以同時(shí)開(kāi)發(fā)應(yīng)用與界面。


          代碼庫(kù)與代碼搜索




          byteMyCode - 代碼搜索

          Snipplr - 幫你存儲(chǔ),管理所有代碼片段。

          ErrorKey - 錯(cuò)誤代碼搜索引擎。

          findJAR.com - JAR 文件搜索

          github - 代碼庫(kù),既支持公共代碼,又支持私人代碼,私人代碼通過(guò) SSH 以及 SSL 訪問(wèn)。



          merobase - 搜索組件。

          Codebase - 代碼庫(kù),技術(shù)支持與安裝部署跟蹤程序。

          CONFiles - 配置文件的在線存儲(chǔ)與分享

          CodeSnippets - 公共代碼庫(kù),也支持私人代碼

          GWT-Ext - 免費(fèi)的,可下載的飾件庫(kù)


          開(kāi)發(fā)環(huán)境,平臺(tái)與框架


          SocialGO - 社會(huì)化網(wǎng)絡(luò)托管平臺(tái),包括消息,視頻聊天,會(huì)員資料,照片分享,博客等
          Pringo - 社會(huì)化網(wǎng)絡(luò)平臺(tái),功能包括視頻,MP3 支持,圖片庫(kù),圈子,podcasting 等。
          slinkset - 一個(gè)用于創(chuàng)建社會(huì)化新聞?wù)军c(diǎn)的在線平臺(tái)
          iWidgets - 社會(huì)化 Syndication 平臺(tái),允許你將你的內(nèi)容聚合到社會(huì)化網(wǎng)絡(luò)
          WackWall - 一個(gè) Hosted 的社會(huì)化網(wǎng)絡(luò)平臺(tái)




          WhiteLabelDating.com - 一個(gè)創(chuàng)建約會(huì),社會(huì)網(wǎng)絡(luò),社區(qū)站點(diǎn)的平臺(tái),允許以自己公司的名義創(chuàng)建。
          ONEsite - 社會(huì)網(wǎng)絡(luò)平臺(tái),包括博客,照片與視頻庫(kù),評(píng)分與標(biāo)簽,消息板,私人消息等
          jinity - 免費(fèi)的社會(huì)網(wǎng)絡(luò)平臺(tái),包括消息板,聊天,圈子,日志,投票,新聞等
          Magnify.net - 網(wǎng)站視頻工具,包括全套媒體工具
          ShoutEm - 微博客與社會(huì)網(wǎng)絡(luò)平臺(tái)



          Soceeo - 社會(huì)網(wǎng)絡(luò)平臺(tái),包含文件分享,新聞,投票等
          Swift - 移動(dòng)站點(diǎn)創(chuàng)建工具,包括多種設(shè)計(jì)選項(xiàng),支持 RSS Feed,多媒體等
          SnappVille - 社會(huì)網(wǎng)絡(luò)平臺(tái),包括組,博客工具,即時(shí)消息等
          Ning - 社會(huì)網(wǎng)絡(luò)平臺(tái),允許使用自己的品牌,包括會(huì)員資料,事件列表,甚至 Facebook 集成。
          mixxt - 社會(huì)網(wǎng)絡(luò)平臺(tái),包括事件,論壇等
          zembly - 一個(gè)用來(lái)創(chuàng)建社會(huì)應(yīng)用的的平臺(tái),目前處于 Beta 版。Yuku - 一個(gè)社區(qū)平臺(tái),可定制,擁有很強(qiáng)大的系統(tǒng)管理工具SocialEngine - 基于 PHP 的社會(huì)網(wǎng)絡(luò)平臺(tái),功能包括 multi-part profiles,子網(wǎng),搜索友好 URL,博客,圈子等。Cappuccino - 一個(gè)用來(lái)創(chuàng)建桌面品質(zhì) Web 程序的開(kāi)源框架Jaws - 一個(gè)用戶友好 CMS 平臺(tái)。   綜合開(kāi)發(fā)工具


          Tabifier - 對(duì)你的代碼進(jìn)行自動(dòng)縮進(jìn)。
          Sms2do - 一個(gè)用來(lái)評(píng)測(cè)和演示 SMS 程序的免費(fèi)工具。
          Pretty Printer - 源代碼格式化工具,支持 PHP, JavaScript, CSS 等
          Jitterbit - 一個(gè)開(kāi)源集成方案,提高可擴(kuò)充性與性能
          Bitizer - 二進(jìn)制,十進(jìn)制,16進(jìn)制,Base 36 以及 ASCII 轉(zhuǎn)換工具



          thmbnl - 顯示你站點(diǎn)中那些鏈接網(wǎng)頁(yè)的縮略圖
          ID Selector - 一個(gè) OpenID 工具
          consoleFISH - 免費(fèi)的,基于 Web 的 SSH 服務(wù)器訪問(wèn)
          form site - 用來(lái)創(chuàng)建自定義表單
          99Polls - 用來(lái)創(chuàng)建投票與調(diào)查



          Warehouse - 一個(gè)非常漂亮的代碼庫(kù)瀏覽服務(wù),支持多代碼庫(kù)以及非常完善的權(quán)限控制
          rendur 2.1 - 一個(gè)沙箱程,讓你一邊寫(xiě)代碼,一邊生成頁(yè)面
          Languify - 翻譯管理系統(tǒng)
          ROR Sitemap Generator - 顧名思義,這是一個(gè) ROR 網(wǎng)站地圖生成工具
          MicroMaps - 用來(lái)生成交互式地圖,放在你的網(wǎng)站



          Newsfeed Maker - 為你的網(wǎng)站或博客創(chuàng)建 News Feed
          WriteMaps - 網(wǎng)站地圖在線生成工具
          Project Kenai - 免費(fèi)的開(kāi)源項(xiàng)目或代碼托管站點(diǎn)
          Launch Splash - 為你還沒(méi)有開(kāi)通的網(wǎng)站免費(fèi)生成一個(gè)歡迎頁(yè)面
          Browser Shell - 基于瀏覽器的 SSH 工具
          foigo - 創(chuàng)建自定義表單,調(diào)查,以及數(shù)據(jù)庫(kù)AggData - Premade lists for your development projects.SnapCasa - 網(wǎng)站縮略圖工具Versionshelf - 代碼庫(kù)安全管理   Mashups 與 APIs


          The Echo Nest - 音樂(lè)相關(guān)的開(kāi)發(fā)服務(wù) API,包括歌手資料,音樂(lè)推薦等功能
          Zeep Mobile - 為你的站點(diǎn)添加基于文本的消息系統(tǒng)
          Clickatell - 一個(gè)短消息網(wǎng)關(guān),讓你的網(wǎng)站通過(guò)多中連接方式發(fā)短消息
          Nonoba - 在線游戲開(kāi)發(fā) API,支持多玩家。
          Zong - 移動(dòng)支付平臺(tái),包含開(kāi)發(fā) API



          Web Shots Pro - 一個(gè) API,開(kāi)發(fā)者可用來(lái)在他們的程序中添加網(wǎng)站縮略圖。
          Pushpin - 一個(gè)簡(jiǎn)單易用的在線地圖 API,支持大量標(biāo)記以及眾多其它功能
          Datamash - Create widgets and mashups for your site with information anywhere on the Web.借助網(wǎng)絡(luò)上的眾多信息為你的站點(diǎn)創(chuàng)建 widgets 與 mashups
          Spicy Pipes - Mashup builder.

          posted @ 2008-11-06 19:50 bt下載 閱讀(261) | 評(píng)論 (0)編輯 收藏

          原文作者:miguelcarrasco
          原文鏈接:Who Wants To Beat-Google?
          翻譯:小豬哥

          誰(shuí)不想打敗Google呢?很宏偉的目標(biāo),但怎樣做到呢?每個(gè)人對(duì)此都有自己的魔幻方法。微軟一度要以440億美元收購(gòu)Yahoo!,還在R&D投資 bt幾十億,縱然財(cái)力如此雄厚,他能做到么?有人認(rèn)為需要更多的網(wǎng)頁(yè)檢索,有人認(rèn)為應(yīng)當(dāng)有更好的界面,這個(gè)問(wèn)題的答案仁者見(jiàn)仁,智者見(jiàn)智。

              而且現(xiàn)在來(lái)做這件事情(打敗Google)再合適不過(guò)。隨著經(jīng)濟(jì)危機(jī)的來(lái)臨,大批大批的web 2.0 公司即將破產(chǎn),那些僅僅依賴互聯(lián)網(wǎng)生存的公司也即將倒閉。即便強(qiáng)如Google也在去年受到了沖擊,其股價(jià)去年700美元每股,而今跌到286(作者發(fā)稿時(shí))。現(xiàn)在看來(lái),互聯(lián)網(wǎng)免費(fèi)的午餐已經(jīng)消失。

              然而微軟卻一直保持著強(qiáng)勁的勢(shì)頭,因?yàn)樗浅6嘣以谝粋€(gè)領(lǐng)域做得實(shí)在太優(yōu)秀了——軟件!他有著難以想象的money,手中有難以置信的全球智慧人群(接近100,000雇員),同時(shí)他還擁有最富有夢(mèng)想的一些領(lǐng)導(dǎo)者在運(yùn)籌帷幄。如果有誰(shuí)能夠做出更好的搜索引擎,那毫無(wú)疑問(wèn)就是微軟。而Google會(huì)退縮么,當(dāng)然也不會(huì)。

          社交圖(Social Graph)


          Facebook經(jīng)常談?wù)?/font>的Social Graph著實(shí)強(qiáng)大,因此Facebook得以很了解你。他知道你的朋友是誰(shuí)、你住在哪里、你在哪兒工作……他有圖片、video以及你感興趣的東西。他甚至知道你在哪個(gè)社交圈、你想?yún)⒓邮裁椿顒?dòng)。因而可以說(shuō)Facebook比你的朋友都了解你。

          搜索怎么了(What’s Wrong With Search Today?)

              當(dāng)我試著用“GAC”一類的來(lái)搜索的時(shí)候,返回的結(jié)果令我感到荒唐——加拿大抵制協(xié)會(huì)(Geological Association of Canada)。我是一個(gè)軟件開(kāi)發(fā)者,F(xiàn)acebook、Twitter和LinkedIn 都知道這一點(diǎn),但是Google對(duì)此一無(wú)所知。所以返回的有效搜索寥寥無(wú)幾。我媽媽搜索一個(gè)關(guān)鍵詞跟我搜索一個(gè)關(guān)鍵詞得到的返回完全相同。但是我媽媽喜愛(ài) 的是手工藝,我喜歡的是軟件開(kāi)發(fā),我們應(yīng)該得到不同的結(jié)果才對(duì)。

              為什么沒(méi)有人利用社交圖的數(shù)據(jù)呢?單純拷貝Google搜索模式、換個(gè)Logo是行不通的,人們更換搜索需要理由。在搜索中添加內(nèi)容才是出路。

              比爾蓋茨在過(guò)去的幾年里一而再再而三地提到:搜索的道路還很長(zhǎng)。幾個(gè)月前我聽(tīng)到的解決方案——新的界面、一直鼠標(biāo)滾動(dòng)的搜索結(jié)果(never ending scrolling),這些顯然不是比爾蓋茨想說(shuō)的。Scrolling endlessly所以你就不用選頁(yè)了?這顯然不是解決方式。

              微軟真正應(yīng)當(dāng)做到的是:當(dāng)用Google和Live Search搜索的時(shí)候,Live Search返回的結(jié)果更好。而且不是好一點(diǎn),要好很多才行。

          微軟能做什么(So What Can Microsoft Do?)

              毫無(wú)疑問(wèn),微軟有業(yè)內(nèi)最優(yōu)秀的開(kāi)發(fā)者、架構(gòu)師和工程師,同樣也有大筆大筆的錢可以投到搜索中(這一點(diǎn)從他購(gòu)買Yahoo! 就能夠看出來(lái))。然而微軟要想贏得搜索戰(zhàn)所缺少的東西也很明了:他們需要?jiǎng)?chuàng)意和行動(dòng)路線,也即“作戰(zhàn)計(jì)劃”。Windows, Internet Explorer和Office,微軟當(dāng)年都不是第一個(gè),但他做出了比其他操作系統(tǒng)更好的操作系統(tǒng),比其他office套件更好的office套件,比其 他瀏覽器更好的IE,而且他還讓所有這些應(yīng)用能夠無(wú)縫地運(yùn)行在一起。所以如果微軟擁有戰(zhàn)略,并且能夠正確實(shí)施,Live Search將會(huì)迅速得到難以想象的市場(chǎng)占有率。

          Live Search 與Facebook關(guān)聯(lián)(Live Search and Facebook Connect)

              微軟應(yīng)當(dāng)充分利用Facebook connect,并將之與Live Search關(guān)聯(lián)。使用Facebook connect,F(xiàn)acebook用戶能夠在Microsoft Live Search中關(guān)聯(lián)到他們資料數(shù)據(jù)和認(rèn)證證書(shū)。通過(guò)關(guān)聯(lián)搜索、結(jié)合用戶的資料數(shù)據(jù),這個(gè)搜索就是“終極搜索引擎”。

          Microformats將是搜索的未來(lái)(Microformats are the future of Search)


              Microformats比其他任何瀏覽器都好,以hCalander, hCard和 hReview開(kāi)始。如果你還從未聽(tīng)過(guò)Microformats,趕緊查查,你就會(huì)知道他為什么這么重要。到目前為止,網(wǎng)絡(luò)上大部分的數(shù)據(jù)都是完全無(wú)序的。舉個(gè)例子你輸入“Contact Miguel Carrasco”搜索,你會(huì)搜到我的博客但僅此而已。但你想要找到的是我的聯(lián)系卡片。下面是我使用hCalander Microformat來(lái)為Winnipeg.net User Group創(chuàng)建一個(gè)事件的實(shí)例。

             1: <div class="vevent" id="hcalendar-Winnipeg-.net-User-Group-September-Event">
             2:     <a class="url" >
             3:     <abbr class="dtstart" title="2008-09-30T06:00-06:0000">September 30, 2008  6</abbr> –
             4:     <abbr class="dtend" title="2008-09-30T08:00-06:00">8am</abbr> : 
             5:     <span class="summary">Winnipeg .net User Group September Event</span> at
             6:     <span class="location">17th Floor - One Lombard Place - Winnipeg, Manitoba, Canada</span></a>

             7:     <div class="description">What could possibly be better than enjoying some free pizza and pop with your peers while be entertained / educated by a presentation on a single .Net topic? Well, how about an open forum that includes some of the hottest topics in software development to date?! To keep the meeting energized, we will be limiting each topic to 20 minutes, and what's more, each topic will have a subject matter expert on hand to facilitate the session.
             8: 
             9:     Come prepared with questions, project stories, and ideas to one of the most unique user group sessions we have ever had.
            10: 
            11:     Topics will include:
            12: 
            13:     What is BizTalk
            14:     A Real World Silverlight Application
            15:     What is NHibernate
            16:     Why Continuous Integration Is Critical
            17:     Open Forum Free-for-All Session</div><div class="tags">Tags:
            18:     <a rel="tag" >winnipeg</a><a rel="tag" > user group</a><a rel="tag" > .net</a><a rel="tag" > microsoft</a></div>
            19: 
            20: </div>

              一個(gè)支持Microformat的搜索引擎可以在搜索結(jié)果中得到正確的信息,并且鏈接到網(wǎng)址來(lái)為事件注冊(cè)

          完美的搜索界面(The Complete Search Interface)

              大家也許都忘記了,Google剛誕生出來(lái)的那會(huì),沒(méi)有blogs,Video也不大,F(xiàn)acebook和其他社交網(wǎng)絡(luò)還在娘胎呢。然而搜索的未來(lái)在于內(nèi)容。人們每月花費(fèi)成百上千個(gè)鐘頭在社交網(wǎng)絡(luò)、新網(wǎng)址和博客。他們持續(xù)地向這些玩意中提供了大量他們的信息:喜歡什么?朋友是誰(shuí)?下周做什么?現(xiàn)在什么心情?未來(lái)三周可能去哪玩……

              我個(gè)人就至少在網(wǎng)絡(luò)上使用至少20種不同的社交服務(wù),所以說(shuō)搜索引擎不能只返給我簡(jiǎn)單的數(shù)據(jù),而應(yīng)當(dāng)利用這些數(shù)據(jù)返給我我想要的內(nèi)容。比如,我已經(jīng)在網(wǎng)上吵了好幾天說(shuō)我下周要去邁阿密。

              在Facebook,我創(chuàng)建了幾個(gè)我將要在邁阿密參加的活動(dòng);在Digg,我dugg了幾個(gè)水中呼吸器的信息;在Last.fm,我創(chuàng)建了幾個(gè)標(biāo)題為“Miami Plane Ride”的音樂(lè)列表。在Facebook我從朋友那兒收到了幾個(gè)回帖稱我不應(yīng)當(dāng)錯(cuò)過(guò)邁阿密的幾個(gè)酒吧和跳舞俱樂(lè)部。其他朋友推薦了那兒的幾處海灘,還給了照片。

              如果我去Google搜索跳舞俱樂(lè)部,最頂上的三個(gè)搜索結(jié)果跟我要找的一點(diǎn)關(guān)系都沒(méi)有。如圖:



          圖片11
              正如我說(shuō)的,沒(méi)有一個(gè)搜索結(jié)果對(duì)我有用,是不是我的搜索條件太為難Google了?于是我又輸入了“Miami”,讓我們?cè)倏纯唇Y(jié)果:


          圖片22

              現(xiàn)在起碼我得到了一些結(jié)果能讓我看到邁阿密的跳舞俱樂(lè)部,但是哪個(gè)是朋友推薦我的呢?為什么我要的結(jié)果不能直接出現(xiàn)在我的面前?為什么沒(méi)有圖片,或者最好再有video?消費(fèi)者的評(píng)論在哪兒呢?

              使用Live Complete Search,,輸入“跳舞俱樂(lè)部”,迅速在我的搜索結(jié)果中出現(xiàn)了內(nèi)容,并且將結(jié)果局限到了邁阿密。并不是因?yàn)?/font>我想去邁阿密,搜索才得到這樣的結(jié)果,而是因?yàn)槲襱witter了我的朋友問(wèn)他們邁阿密最好的跳舞俱樂(lè)部在哪兒,因此,搜索找出了我想要的結(jié)果。



          圖片33

              第一條結(jié)果是Nikki Beach,正是我朋友告訴我的那個(gè)。搜索中還有一張圖片,他們留給我的評(píng)論也能在搜索頁(yè)面中看到,還有電話號(hào)碼也以microformats的形式出現(xiàn) 在網(wǎng)頁(yè)中,我還能夠在這兒使用Twitter, Digg或者 Facebook得到更詳細(xì)的信息。而且,Live Complete Search知道我在Last.FM創(chuàng)建了一個(gè)Miami播放列表,所以還在搜索中加入了一個(gè)鏈接。

              當(dāng)然這只是個(gè)例子,但我想從中你已經(jīng)能夠看到了精髓。

          Building Live Social Profile
              Google已經(jīng)證明你并不需要擁有所有的數(shù)據(jù),因?yàn)橛腥藭?huì)提供而Google只是幫你找到它們,令人感到發(fā)笑的是許多企業(yè)紛紛克隆Google的方法。 微軟有互聯(lián)網(wǎng)上第一位的IM——MSN Messenger,每個(gè)用戶都有一個(gè)Live 賬號(hào),有些人還有Live Spaces的賬號(hào)。我不知道你怎樣,但在我看來(lái)使用Live Spaces的并不多。我點(diǎn)擊了一下我MSN的好友,發(fā)現(xiàn)很多人從未用過(guò)Live Spaces,即使有使用的人,可能使用的幾率也不及Facebook之類的百分之一。

              我的建議是微軟應(yīng)當(dāng)設(shè)法將Live Spaces變成人氣旺盛的(“Live”) Spaces,從而用戶可以通過(guò)互聯(lián)網(wǎng)將他們的社交狀況傳上去,這將創(chuàng)建一個(gè)終極社交檔案(social profile)和終極個(gè)人網(wǎng)頁(yè)(social “my page”)。


          圖片44
          建議界面(The Proposed Interface)

              建議的Live Search的界面非常簡(jiǎn)單。它默認(rèn)提供完整的搜索容量,包含互聯(lián)網(wǎng)上的一切并將搜索結(jié)果放在合適的位置。比如,使用完全搜索,你會(huì)得到一些網(wǎng)頁(yè)、 blog、帖子和一些視頻,也可能有寫(xiě)Digg文章。如果只想搜索自己的社交圖呢?沒(méi)問(wèn)題,只需要點(diǎn)擊“Social”,搜索結(jié)果馬上只呈現(xiàn)出與你有關(guān)的 結(jié)果。

              而且,Live Search的界面中能夠插入許多過(guò)濾器,比如“搜索”和“兒童”。學(xué)校可以管理網(wǎng)絡(luò)從而只允許“搜索”模式,父母可以管好自己的孩子只允許“兒童”模 式。通過(guò)Live Spaces和 Live Profile連接這些系統(tǒng),微軟將創(chuàng)建出比Google PageRank強(qiáng)大許多的搜索,用戶的天平也開(kāi)始擺向了這邊。



          圖片55
          搜索的最終思想(Final Thoughts on Search)

              希望你能夠意識(shí)到,社交內(nèi)容、microformats、和一個(gè)能夠提供整個(gè)網(wǎng)絡(luò)的完美界面將是搜索的下一次飛躍。擁有更加接近社交圖的搜索結(jié)果比PageRank或者PageRank的克隆更容易統(tǒng)計(jì)互聯(lián)網(wǎng)

          posted @ 2008-11-05 21:57 bt下載 閱讀(221) | 評(píng)論 (0)編輯 收藏

          毋庸置疑,對(duì)于所有研究互聯(lián)網(wǎng)新媒體公司的同仁們而言,blogbus是一個(gè)絕佳的案例,他不是BT bsp。

          1,在門(mén)戶BSP大舉進(jìn)攻下,專業(yè)BSP日漸沒(méi)落。blogbus偏安于上海,能發(fā)展的有聲有色,不易。剛看到Jenny發(fā)的blogbus六周年的活動(dòng)。可以說(shuō),blogbus的發(fā)展路線值得所有web2.0公司學(xué)習(xí)。

           編者注:如在百度中搜索 甜性澀愛(ài)色即是空 愛(ài)的色放出現(xiàn)的問(wèn)題說(shuō)知道了。

          2,blogbus能走到現(xiàn)在,跟公司團(tuán)隊(duì)的黃金組合關(guān)系很大。資深的互聯(lián)網(wǎng)人士:橫戈;資深媒體研究專家:魏武揮;資深廣告營(yíng)銷界人士:jenny。我想,國(guó)內(nèi)所有希望通過(guò)互聯(lián)網(wǎng)賺錢的web2.0公司都應(yīng)該參考下這種團(tuán)隊(duì)。不管是思路、見(jiàn)地。還有資源,客戶的說(shuō)教。

          3,blogbus走出的商業(yè)模式,將是未來(lái)很長(zhǎng)一段時(shí)間,不少國(guó)內(nèi)2.0公司必須的一步。原因很簡(jiǎn)單,中國(guó)互聯(lián)網(wǎng)廣告規(guī)模雖然上漲很快,但依然停留在初級(jí)階段,缺乏專業(yè)細(xì)分的廣告網(wǎng)絡(luò)(代理)公司推動(dòng)。加上客戶認(rèn)知度較低,web2.0公司必須肩負(fù)推動(dòng)廣告挖掘的重任。

          4,所以,細(xì)分的廣告網(wǎng)絡(luò)(代理)公司在國(guó)內(nèi)會(huì)越來(lái)越有前景,其中一部分會(huì)來(lái)源于公關(guān)公司的升級(jí),另一部分會(huì)來(lái)自于當(dāng)下大量掌握廣告客戶投放資源的4A公司;再有一個(gè)就是新媒體或者是社會(huì)化媒體公司自身,在這點(diǎn)上blogbus和feedsky都是個(gè)例子。David Wolf說(shuō),“中國(guó)的問(wèn)題在于我們點(diǎn)子的太簡(jiǎn)單”,其實(shí)更準(zhǔn)確點(diǎn)說(shuō)是缺專營(yíng)的廣告營(yíng)銷公司。

          5,所以,有人會(huì)問(wèn):blogbus是廣告公司,還是互聯(lián)網(wǎng)公司?其實(shí),blogbus作為一個(gè)新媒體或者是社會(huì)化媒體平臺(tái),已經(jīng)聚集了百萬(wàn)級(jí)的人群,背靠這些人群挖掘出了不小的商業(yè)價(jià)值,這已經(jīng)說(shuō)明了一切。很多更大用戶量級(jí)的公司,尚不及此。你說(shuō)google是互聯(lián)網(wǎng)公司,還是廣告公司?除了不斷膨脹的互聯(lián)網(wǎng)業(yè)務(wù),google也正在成為更大的廣告代理或分銷商。所以,我說(shuō)過(guò),新媒體要變成廣告公司

          6,blogbus最近推出的幾個(gè)業(yè)務(wù),非常值得把玩。一個(gè)是基于blog平臺(tái)推出的SNS功能,我非常認(rèn)同魏武揮的說(shuō)法,因?yàn)橛脩艉蜖I(yíng)銷需求去增加blog平臺(tái)的互動(dòng)功能,顯然SNS是增加互動(dòng)關(guān)聯(lián)的成熟方式。但絕不是把blog變成一個(gè)SNS平臺(tái)。

          7,另一個(gè)更有意思的則是《城客》,簡(jiǎn)單說(shuō),城客是一個(gè)依托于blogbus平臺(tái)的雜志;它其實(shí)是blogbus線上資源的一個(gè)延伸(內(nèi)容低成本+現(xiàn)有用戶群),這也是我看好它的一個(gè)因素;趕巧的是,同期還有一個(gè)純粹靠整合網(wǎng)上內(nèi)容的印刷雜志《博客天下》。形式相同,思路卻是迥異。

          8,我記得,blogbus下面還有一個(gè)做口碑營(yíng)銷的“吆喝城”。

          9,blogbus會(huì)成為一種現(xiàn)象,尤其是在冬天。

          posted @ 2008-11-03 11:34 bt下載| 編輯 收藏

          TreeMap是紅黑樹(shù)算法的實(shí)現(xiàn),實(shí)現(xiàn)了SortedMap接口,要注意的是它不在使用哈希表,存儲(chǔ)方式是一個(gè)特殊的二叉樹(shù),有關(guān)紅黑樹(shù):
          http://baike.baidu.com/view/133754.htm  http://www.bt285.cn

          這篇文章介紹的不錯(cuò),我之前沒(méi)有聽(tīng)說(shuō)過(guò)二叉樹(shù),我就是看這篇文章加上看一下TreeMap的源代碼才搞懂紅黑樹(shù)算法的.

           

          這里不打算研究TreeMap的源代碼了,因?yàn)橥耆且粋€(gè)算法的實(shí)現(xiàn),如果對(duì)這個(gè)算法不了解,肯定看不懂,我也有很多地方不是沒(méi)有完全看明白,這里就談?wù)凾reeMap的使用吧.

           

           

          TreeMap的聲明:public class TreeMap extends AbstractMap implements SortedMap,Cloneable, java.io.Serializable
          所以我們要知道SortedMap接口:
          SortedMap表示的是一個(gè)排序的Map
          public interface SortedMap extends Map
          增加了幾個(gè)方法的定義
          SortedMap headMap(Object toKey)
          SortedMap tailMap(Object fromKey)
          SortedMap subMap(Object fromKey, Object toKey)
          Object firstKey()
          Object lastKey()

           

           

          既然TreeMap是有序的,自然要求元素是可以比較大小的,如果構(gòu)造函數(shù)指定Comparator的話,就使用這個(gè)Comparator比較大小,如果沒(méi)有指定Comparator的話,就使用自然排序(元素要實(shí)現(xiàn)Comparable接口).如果這兩個(gè)都不可用,就等著出錯(cuò)吧.

          現(xiàn)看一下該接口的定義:
          public interface Comparable{
             public int compareTo(Object o);
          }
          該接口定義類的自然順序,實(shí)現(xiàn)該接口的類就可以按這種方式排序.
          一般要求:
          e1.equals((Object)e2)和e1.compareTo((Object)e2)==0具有相同的值,
          這樣的話我們就稱自然順序就和equals一致.
          這個(gè)接口有什么用呢?
          如果數(shù)據(jù)或者List中的元素實(shí)現(xiàn)了該接口的話,我們就可以調(diào)用Collections.sort或者Arrays方法給他們排序.

          如果自然順序和equals不一致的話,如果出現(xiàn)在Sorted Map和Set里面,
          就會(huì)出現(xiàn)預(yù)想不到的邏輯錯(cuò)誤,可能你調(diào)用add的時(shí)候添加不了,而集合里面確沒(méi)有這個(gè)元素.具體的討論要接口哈希表的應(yīng)用.

           

           

           

          public interface Comparator {
            int compare(Object o1, Object o2);
            boolean equals(Object obj);
          }

          定義了兩個(gè)方法,其實(shí)我們一般都只需要實(shí)現(xiàn)compare方法就行了,因?yàn)轭惗际悄J(rèn)從Object繼承
          所以會(huì)使用Object的equals方法.
          Comparator一般都作為一個(gè)匿名類出現(xiàn),對(duì)于沒(méi)有實(shí)現(xiàn)Comparable的對(duì)象的集合,排序的時(shí)候
          需要指定一個(gè)Comparator.

          這里舉例說(shuō)明
          對(duì)于實(shí)現(xiàn)了Comparable的類我們就用最簡(jiǎn)單的Integer
          List list=new ArrayList();
          list.add(new Integer(3));
          list.add(new Integer(53));
          list.add(new Integer(34));
          Collections.sort(list);

          對(duì)于沒(méi)有實(shí)現(xiàn)Comparable的,我們就用Object,按照hashCode大小來(lái)排序.
          List list= new ArrayList();
          list.add(new Object());
          list.add(new Object());
          list.add(new Object());
          Collections.sort(list,new Comparator(){ public int compare(Object o1, Object o2){
                              return (o1.hashCode()-o2.hashCode());
          })

          因?yàn)槭嵌鏄?shù),所以一般查找時(shí)間復(fù)雜度為 o(lg(n)),這個(gè)效率當(dāng)然沒(méi)有HashMap的效率高.不過(guò)TreeMap比HashMap功能強(qiáng)大,如果不需要排序的話當(dāng)然不會(huì)用TreeMap,如果需要排序的話,HashMap無(wú)法勝任,當(dāng)然要用TreeMap了,它可以求子Map.所以這個(gè)是適用場(chǎng)合問(wèn)題,無(wú)法比較他們.
           
          另外,我們也習(xí)慣了,有Map就會(huì)跟一個(gè)Set,我們都可以猜到TreeSet和通過(guò)TreeMap實(shí)現(xiàn)的一個(gè)SortedSet的實(shí)現(xiàn).不過(guò)我覺(jué)的TreeSet好像比TreeMap用的場(chǎng)合多一些,求子集是很常用的呀!!

          posted @ 2008-10-30 20:59 bt下載 閱讀(3293) | 評(píng)論 (1)編輯 收藏

          以前我一直以為File#renameTo(File)方法與OS下面的 move/mv 命令是相同的,可以達(dá)到改名、移動(dòng)文件的目的。不過(guò)后來(lái)經(jīng)常發(fā)現(xiàn)問(wèn)題,真的很bt,File#renameTo(File)方法會(huì)返回失敗(false),文件沒(méi)有移動(dòng),又查不出原因,再后來(lái)干脆棄用該方法,自己實(shí)現(xiàn)一個(gè)copy方法,問(wèn)題倒是再也沒(méi)有出現(xiàn)過(guò)。

          昨天老板同學(xué)又遇到這個(gè)問(wèn)題,F(xiàn)ile#renameTo(File)方法在windows下面工作的好好的,在linux下偶爾又失靈了。回到家我掃了一遍JDK中File#renameTo(File)方法的源代碼,發(fā)現(xiàn)它調(diào)用的是一個(gè)本地的方法(native method),無(wú)法再跟蹤下去。網(wǎng)上有人說(shuō)該方法在window下是正常的,在linux下面是不正常的。這個(gè)很難說(shuō)通,SUN不可能搞出這種平臺(tái)不一致的代碼出來(lái)啊。

          后面在SUN的官方論壇上看到有人提到這個(gè)問(wèn)題“works on windows, don't work on linux”,后面有人回復(fù)說(shuō)是“file systems”不一樣。究竟怎么不一樣呢?還是沒(méi)有想出來(lái)...

          后面在一個(gè)論壇里面發(fā)現(xiàn)了某人關(guān)于這個(gè)問(wèn)題的闡述:
          In the Unix'esque O/S's you cannot renameTo() across file systems. This behavior is different than the Unix "mv" command. When crossing file systems mv does a copy and delete which is what you'll have to do if this is the case.

          The same thing would happen on Windows if you tried to renameTo a different drive, i.e. C: -> D:
          終于明白咯。

          做個(gè)實(shí)驗(yàn):

        1. File sourceFile = new File("c:/test.txt");   
        2. File targetFile1 = new File("e:/test.txt");   
        3. File targetFile2 = new File("d:/test.txt");   
        4. System.out.println("source file is exist? " + sourceFile.exists()   
        5.     + ", source file => " + sourceFile);   
        6. System.out.println(targetFile1 + " is exist? " + targetFile1.exists());   
        7. System.out.println("rename to " + targetFile1 + " => "  
        8.     + sourceFile.renameTo(targetFile1));   
        9. System.out.println("source file is exist? " + sourceFile.exists()   
        10.     + ", source file => " + sourceFile);   
        11. System.out.println(targetFile2 + " is exist? " + targetFile2.exists());   
        12. System.out.println("rename to " + targetFile2 + " => "  
        13.     + sourceFile.renameTo(targetFile2));  



        14. 注意看結(jié)果,從C盤(pán)到E盤(pán)失敗了,從C盤(pán)到D盤(pán)成功了。因?yàn)槲业碾娔XC、D兩個(gè)盤(pán)是NTFS格式的,而E盤(pán)是FAT32格式的。所以從C到E就是上面文章所說(shuō)的"file systems"不一樣。從C到D由于同是NTFS分區(qū),所以不存在這個(gè)問(wèn)題,當(dāng)然就成功了。

          果然是不能把File#renameTo(File)當(dāng)作move方法使用。

          可以考慮使用apache組織的commons-io包里面的FileUtils#copyFile(File,File)和FileUtils#copyFileToDirectory(File,File)方法實(shí)現(xiàn)copy的效果。至于刪除嘛,我想如果要求不是那么精確,可以調(diào)用File#deleteOnExit()方法,在虛擬機(jī)終止的時(shí)候,刪除掉這個(gè)目錄或文件。

          BTW:File是文件和目錄路徑名的抽象表示形式,所以有可能是目錄,千萬(wàn)小心。
          下面我寫(xiě)的一個(gè)實(shí)現(xiàn)方法

          /**
            * 使用FileChannel拷貝文件
            *
            * @param srcFile
            * @param destFile
            * @throws IOException
            */
           public static void copyUseChannel(File srcFile, File destFile)
             throws IOException {
            if ((!srcFile.exists()) || (srcFile.isDirectory())) {
             return;
            }

            if (!destFile.exists()) {
             createFile(destFile.getAbsolutePath());
            }

            FileChannel out = null;
            FileChannel in = null;
            try {
             out = new FileOutputStream(destFile).getChannel();
             in = new FileInputStream(srcFile).getChannel();
             ByteBuffer buffer = ByteBuffer.allocate(102400);
             int position = 0;
             int length = 0;
             while (true) {
              length = in.read(buffer, position);
              if (length <= 0) {
               break;
              }
              // System.out.println("after read:"+buffer);
              buffer.flip();
              // System.out.println("after flip:"+buffer);
              out.write(buffer, position);
              position += length;
              buffer.clear();
              // System.out.println("after clear:"+buffer);
             }

            } finally {
             if (out != null) {
              out.close();
             }
             if (in != null) {
              in.close();
             }
            }
           }

          posted @ 2008-10-27 10:15 bt下載 閱讀(1679) | 評(píng)論 (2)編輯 收藏

          CSDN首頁(yè)推薦了一篇文章,說(shuō)兩位退休的美國(guó)大學(xué)教授上書(shū)反對(duì)將Java作為編程教學(xué)語(yǔ)言,對(duì)此我表示高度認(rèn)同。對(duì)于Java,我并不反感,而且相信它在工業(yè)應(yīng)用中的地位不可取代,但是,我一直反對(duì)將Java作為主要的編程教學(xué)語(yǔ)言,因?yàn)榻虒W(xué)語(yǔ)言承擔(dān)著與生產(chǎn)語(yǔ)言不同的任務(wù),它必須能夠幫助學(xué)生奠定堅(jiān)實(shí)的技術(shù)基礎(chǔ),塑造核心技術(shù)能力。在這方面,Java不能夠勝任。

          1990年代中期以前,美國(guó)的計(jì)算機(jī)編程入門(mén)教育以Pascal為主。我的一位美國(guó)程序員朋友至今還懷念他與Pascal為伴的高中年代。到了1990年代中后期,由于ANSI C語(yǔ)言“糾正”了早期C語(yǔ)言的一些不適合編程教學(xué)的問(wèn)題,因此成為很多美國(guó)高中和大學(xué)編程入門(mén)課的教學(xué)語(yǔ)言。1998年,美國(guó)指導(dǎo)編程教學(xué)的一個(gè)協(xié)會(huì)推薦將C++作為入門(mén)教學(xué)語(yǔ)言,在當(dāng)時(shí)引起很大的反響,認(rèn)為是編程教育方面的一個(gè)重要進(jìn)步。但遺憾的是,C++非常復(fù)雜,而當(dāng)時(shí)C++語(yǔ)言的教育體系又非常不成熟,因此很多地方的教學(xué)方法不得當(dāng),把學(xué)生迅速拖入無(wú)邊無(wú)際的語(yǔ)言細(xì)節(jié)當(dāng)中,引起了學(xué)生痛苦的抱怨。大約經(jīng)過(guò)兩三年不成功的實(shí)踐之后,在本世紀(jì)初,美國(guó)計(jì)算機(jī)教育界普遍接受Java作為編程入門(mén)語(yǔ)言。此后在很短的時(shí)間里,Java迅速成為美國(guó)高中和大學(xué)里的首選編程教學(xué)語(yǔ)言,老師教得輕松,學(xué)生學(xué)得甜蜜,所以這個(gè)局面一直持續(xù)到現(xiàn)在。

          而在中國(guó),BASIC語(yǔ)言及其變體一直到1990年代中期都還是“算法語(yǔ)言”課程的主要教學(xué)內(nèi)容,充分折射出當(dāng)時(shí)中國(guó)計(jì)算機(jī)教學(xué)與工業(yè)應(yīng)用之間的脫節(jié)。只是到了1990年代后期,C語(yǔ)言才確立了在中國(guó)工科計(jì)算機(jī)編程入門(mén)教育中的主流地位。到現(xiàn)在為止,大部分工科學(xué)生都“必修”“C程序設(shè)計(jì)語(yǔ)言”這門(mén)課程。不過(guò)事實(shí)上,根據(jù)我的了解,這門(mén)課程的總體教學(xué)質(zhì)量相當(dāng)糟糕,大部分學(xué)生可以說(shuō)是滿懷希望而來(lái),兩手空空而去。在這種情況下,中國(guó)高校計(jì)算機(jī)編程入門(mén)教育已經(jīng)開(kāi)始悄悄向Java過(guò)渡了。據(jù)我所知,有一些名校已經(jīng)開(kāi)始將Java設(shè)為編程入門(mén)課程,并且認(rèn)為這是與國(guó)際接軌進(jìn)步標(biāo)志。

          在我的朋友圈子里,大多數(shù)真正的一線開(kāi)發(fā)者和技術(shù)領(lǐng)導(dǎo)者,對(duì)于將Java作為入門(mén)教學(xué)語(yǔ)言的“發(fā)展方向”都持質(zhì)疑態(tài)度。他們中很多人目前主要的工作都集中在Java上,因此這種態(tài)度并非來(lái)自所謂語(yǔ)言宗教情緒,而是來(lái)自他們招聘和實(shí)際工作中的感受。他們發(fā)現(xiàn),只學(xué)習(xí)Java、C#、VB等“現(xiàn)代”編程語(yǔ)言的學(xué)生,精于拿來(lái)主義,長(zhǎng)于整合和快速開(kāi)發(fā),思維活躍,生產(chǎn)效率高,讓他們來(lái)做直截了當(dāng)?shù)摹⒂姓驴裳摹⒎茄芯啃院头莿?chuàng)新性的工作比較合適,但是基礎(chǔ)不扎實(shí),對(duì)計(jì)算機(jī)系統(tǒng)的理解薄弱,處理細(xì)節(jié)和矛盾的能力不足,一旦他們熟悉的套路用不上,則缺少自主分析問(wèn)題、解決問(wèn)題的知識(shí)、能力和經(jīng)驗(yàn)。

          今天看到兩位教授的“上書(shū)”,才知道原來(lái)他們也有同感。只不過(guò)這兩位教授說(shuō)的更直白,直接反對(duì)將Java作為入門(mén)編程語(yǔ)言,而是冒天下之大不韙,公然號(hào)召開(kāi)歷史倒車,要求退回到C、C++、Lisp和Ada去。

          我是支持兩位教授的。我認(rèn)為,Java、C#、VB和其它虛擬機(jī)之上的語(yǔ)言都不適合作為專業(yè)程序員的入門(mén)教學(xué)語(yǔ)言。在中國(guó)還非常缺乏具有創(chuàng)新和獨(dú)立解決問(wèn)題的高水平程序員的局面下,我們應(yīng)該認(rèn)真做好的事情是努力提高C/C++的教學(xué)質(zhì)量,而不是圖快活轉(zhuǎn)向Java。

          教學(xué)語(yǔ)言的選擇是至關(guān)重要的事情。作為大多數(shù)學(xué)生第一種需要認(rèn)真學(xué)習(xí)理解的編程語(yǔ)言,教學(xué)語(yǔ)言將會(huì)成為他們中間很多人的“編程母語(yǔ)”,深深地烙印在學(xué)生的思維方式中。這個(gè)編程母語(yǔ)要幫助學(xué)生破除計(jì)算機(jī)和軟件的神秘感,建立對(duì)于程序的基本認(rèn)識(shí)和對(duì)計(jì)算機(jī)模型的最初理解。在后續(xù)專業(yè)基礎(chǔ)課和專業(yè)課程的學(xué)習(xí)中,這門(mén)編程語(yǔ)言應(yīng)該作為主要工具貫穿始終,幫助學(xué)生認(rèn)識(shí)計(jì)算機(jī)系統(tǒng),掌握算法與數(shù)據(jù)結(jié)構(gòu)技能,熟悉操作系統(tǒng)概念,理解編譯原理知識(shí),理解軟件抽象及軟件設(shè)計(jì)的基本思想,完成一定量的課程及課外項(xiàng)目實(shí)踐,建立正確的軟件開(kāi)發(fā)實(shí)踐習(xí)慣。不但如此,這種教學(xué)語(yǔ)言必須是工業(yè)界的主流語(yǔ)言,否則學(xué)生學(xué)非所用,學(xué)習(xí)動(dòng)力無(wú)法保證。

          按照這個(gè)標(biāo)準(zhǔn)來(lái)衡量,Java適合于作為主要的編程教學(xué)語(yǔ)言嗎?我不這么認(rèn)為。首先,我承認(rèn)Java在教學(xué)上有一些優(yōu)勢(shì),比如其開(kāi)發(fā)環(huán)境和工具支持非常成熟,有助于培養(yǎng)學(xué)生正確的編程習(xí)慣;Java是當(dāng)今第一工業(yè)主流語(yǔ)言,標(biāo)準(zhǔn)類庫(kù)非常全面,可以迅速地開(kāi)發(fā)具有實(shí)際用途的程序,有助于激發(fā)和保持學(xué)生的興趣;而在數(shù)據(jù)結(jié)構(gòu)、算法、編譯原理的教學(xué)方面,Java也毫不落于下風(fēng),在軟件抽象設(shè)計(jì)(面向?qū)ο螅┓矫妫琂ava還有著明顯的優(yōu)勢(shì);特別是在并行編程的教學(xué)方面,Java 1.5 concurrency包提供的優(yōu)勢(shì)是壓倒性的。盡管有如上這些優(yōu)勢(shì),但Java作為教學(xué)語(yǔ)言存在著一個(gè)致命的缺陷,即它是一個(gè)虛擬機(jī)語(yǔ)言,這一點(diǎn)就足以把它從教學(xué)語(yǔ)言的名單上去掉。作為一個(gè)虛擬機(jī)語(yǔ)言,Java對(duì)開(kāi)發(fā)者隔絕了下層的真實(shí)系統(tǒng),從而構(gòu)造了一個(gè)近乎完美的環(huán)境,在這個(gè)環(huán)境里,世界上只有一種機(jī)器,一個(gè)操作系統(tǒng),內(nèi)存是無(wú)限的,所有的機(jī)器都具有相同的字節(jié)順序和一致的類型約定,為了設(shè)計(jì)的優(yōu)美而犧牲速度永遠(yuǎn)是正義行為,從反射到運(yùn)行時(shí)自動(dòng)加載,從完備的容器類到統(tǒng)一字符編碼,一大堆漂亮的功能都可以不費(fèi)吹灰之力唾手而得。要是這個(gè)世界上每臺(tái)計(jì)算機(jī)都是一個(gè)Java機(jī)器,每項(xiàng)編程任務(wù)都可以在這樣一個(gè)近乎完美的環(huán)境中開(kāi)發(fā),那毫無(wú)以為,Java是最合適的編程教學(xué)語(yǔ)言。但是事實(shí)上呢?這樣一個(gè)完美的環(huán)境是Java力量的源泉,但這卻不是真實(shí)的世界。在真實(shí)世界里,我們可能面對(duì)非常原始的環(huán)境,苛刻的運(yùn)行時(shí)限制,復(fù)雜多變的系統(tǒng)環(huán)境,令人窒息的細(xì)節(jié)魔鬼,要對(duì)付這些東西,需要開(kāi)發(fā)者具有在應(yīng)對(duì)復(fù)雜性,自己構(gòu)造環(huán)境,在諸多限制條件下尋找解決方案的能力。而這種能力,被無(wú)數(shù)人無(wú)數(shù)次地證明是軟件開(kāi)發(fā)、特別是軟件創(chuàng)新的核心能力。把Java作為教學(xué)語(yǔ)言,恰恰會(huì)導(dǎo)致這種核心能力的缺失。除此之外,如果耐心觀察的話,不難發(fā)現(xiàn),幾乎在任何軟件領(lǐng)域里的創(chuàng)新性成果都首先是由C/C++語(yǔ)言實(shí)現(xiàn)的,原因很簡(jiǎn)單,Java是站在C/C++基礎(chǔ)之上的,只有C/C++先把大路趟開(kāi),Java才能夠順勢(shì)而上。

          相反,盡管C/C++語(yǔ)言作為教學(xué)語(yǔ)言有很多的不足,比如不同環(huán)境下開(kāi)發(fā)模式差異大,細(xì)節(jié)繁多,開(kāi)發(fā)效率低,容易犯錯(cuò),測(cè)試和調(diào)試?yán)щy,學(xué)習(xí)者難以保持動(dòng)力,等等,但是這些問(wèn)題都可以解決。而C/C++的關(guān)鍵優(yōu)點(diǎn),是能夠讓學(xué)習(xí)者在真實(shí)的計(jì)算機(jī)抽象上、在大量的細(xì)節(jié)和矛盾中學(xué)會(huì)思考,學(xué)會(huì)解決問(wèn)題,學(xué)會(huì)了解真實(shí)的系統(tǒng),知輕重,明生死,從而建立核心能力。掌握了C/C++ bt語(yǔ)言,再去學(xué)習(xí)和理解Java、C#、Python、Ruby和其它語(yǔ)言,就比較容易達(dá)到更高的境界。反之,如果習(xí)慣了舒舒服服躺在完美世界里當(dāng)闊少,那就很難有勇氣面對(duì)真實(shí)的世界。當(dāng)然,很多開(kāi)發(fā)者認(rèn)為,現(xiàn)在更重要的能力是理解業(yè)務(wù)、整合現(xiàn)有資源的能力,而不是處理底層細(xì)節(jié)的技術(shù)。這種說(shuō)法放在個(gè)人身上沒(méi)有問(wèn)題,但是不能成為整個(gè)編程教育的指導(dǎo)思想。我們需要各個(gè)層面上的人才,精通業(yè)務(wù)和設(shè)計(jì)的架構(gòu)師固然很重要,但能夠在底層作出創(chuàng)新成果的編程高手實(shí)際上更為稀缺和珍貴,很多時(shí)候也能夠創(chuàng)造更大的價(jià)值。而且,更重要的是,一個(gè)精通系統(tǒng)知識(shí)的開(kāi)發(fā)者在往上走的時(shí)候不會(huì)遇到大的障礙,而一個(gè)只知道拼裝組合的“高級(jí)設(shè)計(jì)師”,往往連往下看的勇氣都沒(méi)有。

          Java的另外一個(gè)問(wèn)題,是其所倡導(dǎo)的繁瑣設(shè)計(jì)風(fēng)格,一個(gè)對(duì)象套一個(gè)對(duì)象,一個(gè)對(duì)象疊一個(gè)對(duì)象,概念之間彼此橫七豎八地互相依賴,人為制造出一大堆貌似精美、實(shí)則累贅的所謂設(shè)計(jì)。這個(gè)問(wèn)題我已經(jīng)批評(píng)過(guò)多次,并且相信這股歪風(fēng)一定會(huì)最終被人們拋棄,Java最終會(huì)歸于質(zhì)樸。但是在這一天到來(lái)之前,Java對(duì)于初學(xué)者來(lái)說(shuō),很可能蒙住他們的雙眼,使他們看不到軟件設(shè)計(jì)中最可貴的簡(jiǎn)單性和優(yōu)美的統(tǒng)一,體會(huì)不到數(shù)據(jù)和程序的統(tǒng)一。在這一點(diǎn)上,C表現(xiàn)的非常好,而C++如果教學(xué)得體,可以做的更好。

          當(dāng)然,這并不是為現(xiàn)在的C/C++教學(xué)辯護(hù)。恰恰相反,從我了解的情況來(lái)看,目前普通高校的C/C++教學(xué)質(zhì)量非常令人擔(dān)憂。學(xué)生學(xué)不會(huì),而且越學(xué)越?jīng)]有興趣,老師則感到教起來(lái)很棘手,迫于現(xiàn)實(shí)情況往往選擇敷衍了事。反而是教Java,無(wú)論如何學(xué)生還能學(xué)到一點(diǎn)東西,對(duì)就業(yè)也有直接的幫助。至于學(xué)生的核心能力確實(shí),發(fā)展后勁不足等問(wèn)題,就讓他們?cè)诂F(xiàn)實(shí)工作中自己解決吧。坦率地說(shuō),這種想法也很有道理。不過(guò),從教學(xué)角度來(lái)說(shuō),我認(rèn)為老師們還是應(yīng)該積極考慮如何提高C/C++的教學(xué)質(zhì)量。畢竟學(xué)生階段是十分寶貴的,基礎(chǔ)不在這個(gè)時(shí)期夯實(shí),將來(lái)想彌補(bǔ),就算不是完全不可能,也將付出十倍的代價(jià)。本著對(duì)學(xué)生職業(yè)生涯的負(fù)責(zé)態(tài)度,還是應(yīng)該幫助學(xué)生達(dá)到這個(gè)階段應(yīng)該達(dá)到的目標(biāo)。在兩位教授的公開(kāi)信里,也充分表達(dá)出這個(gè)意思。

          我贊成的編程教育過(guò)程,應(yīng)當(dāng)是以C/C++(基本上是C)為主線,貫穿起算法、數(shù)據(jù)結(jié)構(gòu)、系統(tǒng)原理、編譯和數(shù)據(jù)處理、軟件設(shè)計(jì)和組件技術(shù)等關(guān)鍵知識(shí)領(lǐng)域,讓學(xué)生能夠從根本上理解現(xiàn)代軟件系統(tǒng)的原理和構(gòu)造,并通過(guò)有效的練習(xí)建立正確的軟件設(shè)計(jì)觀念和良好的工程實(shí)踐習(xí)慣。在這個(gè)基礎(chǔ)上,無(wú)論將來(lái)是深入學(xué)習(xí)C++,還是進(jìn)入Java的繁榮世界,或者擁抱Python、Ruby,甚至于走向Web開(kāi)發(fā),都會(huì)心領(lǐng)神會(huì),勢(shì)如破竹。

          posted @ 2008-10-14 19:38 bt下載| 編輯 收藏

          第1章基礎(chǔ)知識(shí)

          1.1. 單鑰密碼體制

          單鑰密碼體制是一種傳統(tǒng)的加密算法,是指信息的發(fā)送方和接收方共同使用同一把密鑰進(jìn)行加解密。

          通常,使用的加密算法比較簡(jiǎn)便高效,密鑰簡(jiǎn)短,加解密速度快,破譯極其困難。但是加密的安全性依靠密鑰保管的安全性,在公開(kāi)的計(jì)算機(jī)網(wǎng)絡(luò)上安全地傳送和保管密鑰是一個(gè)嚴(yán)峻的問(wèn)題,并且如果在多用戶的情況下密鑰的保管安全性也是一個(gè)問(wèn)題。

          單鑰密碼體制的代表是美國(guó)的DES

          1.2. 消息摘要

          一個(gè)消息摘要就是一個(gè)數(shù)據(jù)塊的數(shù)字指紋。即對(duì)一個(gè)任意長(zhǎng)度的一個(gè)數(shù)據(jù)塊進(jìn)行計(jì)算,產(chǎn)生一個(gè)唯一指印(對(duì)于SHA1是產(chǎn)生一個(gè)20字節(jié)的二進(jìn)制數(shù)組)。

          消息摘要有兩個(gè)基本屬性:

          • 兩個(gè)不同的報(bào)文難以生成相同的摘要
          • 難以對(duì)指定的摘要生成一個(gè)報(bào)文,而由該報(bào)文反推算出該指定的摘要

          代表:美國(guó)國(guó)家標(biāo)準(zhǔn)技術(shù)研究所的SHA1和麻省理工學(xué)院Ronald Rivest提出的MD5

          1.3. Diffie-Hellman密鑰一致協(xié)議

          密鑰一致協(xié)議是由公開(kāi)密鑰密碼體制的奠基人Diffie和Hellman所提出的一種思想。

          先決條件,允許兩名用戶在公開(kāi)媒體上交換信息以生成"一致"的,可以共享的密鑰

          代表:指數(shù)密鑰一致協(xié)議(Exponential Key Agreement Protocol)

          1.4. 非對(duì)稱算法與公鑰體系

          1976年,Dittie和Hellman為解決密鑰管理問(wèn)題,在他們的奠基性的工作"密碼學(xué)的新方向"一文中,提出一種密鑰交換協(xié)議,允許在不安全的媒體上通過(guò)通訊雙方交換信息,安全地傳送秘密密鑰。在此新思想的基礎(chǔ)上,很快出現(xiàn)了非對(duì)稱密鑰密碼體制,即公鑰密碼體制。在公鑰體制中,加密密鑰不同于解密密鑰,加密密鑰公之于眾,誰(shuí)都可以使用;解密密鑰只有解密人自己知道。它們分別稱為公開(kāi)密鑰(Public key)和秘密密鑰(Private key)。

          迄今為止的所有公鑰密碼體系中,RSA系統(tǒng)是最著名、最多使用的一種。RSA公開(kāi)密鑰密碼系統(tǒng)是由R.Rivest、A.Shamir和L.Adleman俊教授于1977年提出的。RSA的取名就是來(lái)自于這三位發(fā)明者的姓的第一個(gè)字母

          1.5. 數(shù)字簽名

          所謂數(shù)字簽名就是信息發(fā)送者用其私鑰對(duì)從所傳報(bào)文中提取出的特征數(shù)據(jù)(或稱數(shù)字指紋)進(jìn)行RSA算法操作,以保證發(fā)信人無(wú)法抵賴曾發(fā)過(guò)該信息(即不可抵賴性),同時(shí)也確保信息報(bào)文在經(jīng)簽名后末被篡改(即完整性)。當(dāng)信息接收者收到報(bào)文后,就可以用發(fā)送者的公鑰對(duì)數(shù)字簽名進(jìn)行驗(yàn)證。 

          在數(shù)字簽名中有重要作用的數(shù)字指紋是通過(guò)一類特殊的散列函數(shù)(HASH函數(shù))生成的,對(duì)這些HASH函數(shù)的特殊要求是:

          1. 接受的輸入報(bào)文數(shù)據(jù)沒(méi)有長(zhǎng)度限制;
          2. 對(duì)任何輸入報(bào)文數(shù)據(jù)生成固定長(zhǎng)度的摘要(數(shù)字指紋)輸出
          3. 從報(bào)文能方便地算出摘要;
          4. 難以對(duì)指定的摘要生成一個(gè)報(bào)文,而由該報(bào)文反推算出該指定的摘要;
          5. 兩個(gè)不同的報(bào)文難以生成相同的摘要

          代表:DSA





          回頁(yè)首


          第2章在JAVA中的實(shí)現(xiàn)

          2.1. 相關(guān)

          Diffie-Hellman密鑰一致協(xié)議和DES程序需要JCE工具庫(kù)的支持,可以到 http://java.sun.com/security/index.html  或是www.bt285.cn 下載JCE,并進(jìn)行安裝。簡(jiǎn)易安裝把 jce1.2.1\lib 下的所有內(nèi)容復(fù)制到 %java_home%\lib\ext下,如果沒(méi)有ext目錄自行建立,再把jce1_2_1.jar和sunjce_provider.jar添加到CLASSPATH內(nèi),更詳細(xì)說(shuō)明請(qǐng)看相應(yīng)用戶手冊(cè)

          2.2. 消息摘要MD5和SHA的使用

          使用方法:

          首先用生成一個(gè)MessageDigest類,確定計(jì)算方法

          java.security.MessageDigest alga=java.security.MessageDigest.getInstance("SHA-1");

          添加要進(jìn)行計(jì)算摘要的信息

          alga.update(myinfo.getBytes());

          計(jì)算出摘要

          byte[] digesta=alga.digest();

          發(fā)送給其他人你的信息和摘要

          其他人用相同的方法初始化,添加信息,最后進(jìn)行比較摘要是否相同

          algb.isEqual(digesta,algb.digest())

          相關(guān)AIP

          java.security.MessageDigest 類

          static getInstance(String algorithm)

          返回一個(gè)MessageDigest對(duì)象,它實(shí)現(xiàn)指定的算法

          參數(shù):算法名,如 SHA-1 或MD5

          void update (byte input)

          void update (byte[] input)

          void update(byte[] input, int offset, int len)

          添加要進(jìn)行計(jì)算摘要的信息

          byte[] digest()

          完成計(jì)算,返回計(jì)算得到的摘要(對(duì)于MD5是16位,SHA是20位)

          void reset()

          復(fù)位

          static boolean isEqual(byte[] digesta, byte[] digestb)

          比效兩個(gè)摘要是否相同

          代碼:

          import java.security.*;
                      public class myDigest {
                      public static void main(String[] args)  {
                      myDigest my=new myDigest();
                      my.testDigest();
                      }
                      public void testDigest()
                      {
                      try {
                      String myinfo="我的測(cè)試信息";
                      //java.security.MessageDigest alg=java.security.MessageDigest.getInstance("MD5");
                      java.security.MessageDigest alga=java.security.MessageDigest.getInstance("SHA-1");
                      alga.update(myinfo.getBytes());
                      byte[] digesta=alga.digest();
                      System.out.println("本信息摘要是:"+byte2hex(digesta));
                      //通過(guò)某中方式傳給其他人你的信息(myinfo)和摘要(digesta) 對(duì)方可以判斷是否更改或傳輸正常
                      java.security.MessageDigest algb=java.security.MessageDigest.getInstance("SHA-1");
                      algb.update(myinfo.getBytes());
                      if (algb.isEqual(digesta,algb.digest())) {
                      System.out.println("信息檢查正常");
                      }
                      else
                      {
                      System.out.println("摘要不相同");
                      }
                      }
                      catch (java.security.NoSuchAlgorithmException ex) {
                      System.out.println("非法摘要算法");
                      }
                      }
                      public String byte2hex(byte[] b) //二行制轉(zhuǎn)字符串
                      {
                      String hs="";
                      String stmp="";
                      for (int n=0;n<b.length;n++)
                      {
                      stmp=(java.lang.Integer.toHexString(b[n] & 0XFF));
                      if (stmp.length()==1) hs=hs+"0"+stmp;
                      else hs=hs+stmp;
                      if (n<b.length-1)  hs=hs+":";
                      }
                      return hs.toUpperCase();
                      }
                      }

          2.3. 數(shù)字簽名DSA

          1. 對(duì)于一個(gè)用戶來(lái)講首先要生成他的密鑰對(duì),并且分別保存

            生成一個(gè)KeyPairGenerator實(shí)例

               java.security.KeyPairGenerator  keygen=java.security.KeyPairGenerator.getInstance("DSA");
                                如果設(shè)定隨機(jī)產(chǎn)生器就用如相代碼初始化
                            SecureRandom secrand=new SecureRandom();
                            secrand.setSeed("tttt".getBytes()); //初始化隨機(jī)產(chǎn)生器
                            keygen.initialize(512,secrand);     //初始化密鑰生成器
                            否則
                            keygen.initialize(512);
                            生成密鑰公鑰pubkey和私鑰prikey
                            KeyPair keys=keygen.generateKeyPair(); //生成密鑰組
                            PublicKey pubkey=keys.getPublic();
                            PrivateKey prikey=keys.getPrivate();
                            分別保存在myprikey.dat和mypubkey.dat中,以便下次不在生成
                            (生成密鑰對(duì)的時(shí)間比較長(zhǎng)
                            java.io.ObjectOutputStream out=new java.io.ObjectOutputStream(new java.io.FileOutputStream("myprikey.dat"));
                                 out.writeObject(prikey);
                            out.close();
                            out=new java.io.ObjectOutputStream(new java.io.FileOutputStream("mypubkey.dat"));
                                 out.writeObject(pubkey);
                            out.close();
                            


          2. 用他私人密鑰(prikey)對(duì)他所確認(rèn)的信息(info)進(jìn)行數(shù)字簽名產(chǎn)生一個(gè)簽名數(shù)組

            從文件中讀入私人密鑰(prikey)

               java.io.ObjectInputStream in=new java.io.ObjectInputStream(new java.io.FileInputStream("myprikey.dat"));
                                PrivateKey myprikey=(PrivateKey)in.readObject();
                            in.close();
                            初始一個(gè)Signature對(duì)象,并用私鑰對(duì)信息簽名
                            java.security.Signature signet=java.security.Signature.getInstance("DSA");
                            signet.initSign(myprikey);
                            signet.update(myinfo.getBytes());
                            byte[] signed=signet.sign();
                            把信息和簽名保存在一個(gè)文件中(myinfo.dat)
                            java.io.ObjectOutputStream out=new java.io.ObjectOutputStream(new java.io.FileOutputStream("myinfo.dat"));
                                  out.writeObject(myinfo);
                            out.writeObject(signed);
                            out.close();
                            把他的公鑰的信息及簽名發(fā)給其它用戶
                            


          3. 其他用戶用他的公共密鑰(pubkey)和簽名(signed)和信息(info)進(jìn)行驗(yàn)證是否由他簽名的信息

            讀入公鑰
            java.io.ObjectInputStream in=new java.io.ObjectInputStream(new java.io.FileInputStream("mypubkey.dat"));
            PublicKey pubkey=(PublicKey)in.readObject();
            in.close();

            讀入簽名和信息
            in=new java.io.ObjectInputStream(new java.io.FileInputStream("myinfo.dat"));
            String info=(String)in.readObject();
            byte[] signed=(byte[])in.readObject();
            in.close();

            初始一個(gè)Signature對(duì)象,并用公鑰和簽名進(jìn)行驗(yàn)證
            java.security.Signature signetcheck=java.security.Signature.getInstance("DSA");
            signetcheck.initVerify(pubkey);
            signetcheck.update(info.getBytes());
            if (signetcheck.verify(signed)) { System.out.println("簽名正常");}

            對(duì)于密鑰的保存本文是用對(duì)象流的方式保存和傳送的,也可可以用編碼的方式保存.注意要
            import java.security.spec.*
            import java.security.*

            具休說(shuō)明如下

            • public key是用X.509編碼的,例碼如下:
                byte[] bobEncodedPubKey=mypublic.getEncoded(); //生成編碼
                                  //傳送二進(jìn)制編碼
                                  //以下代碼轉(zhuǎn)換編碼為相應(yīng)key對(duì)象
                                  X509EncodedKeySpec bobPubKeySpec = new X509EncodedKeySpec(bobEncodedPubKey);
                                  KeyFactory keyFactory = KeyFactory.getInstance("DSA");
                                  PublicKey bobPubKey = keyFactory.generatePublic(bobPubKeySpec);
                                  


            • 對(duì)于Private key是用PKCS#8編碼,例碼如下:
               byte[] bPKCS=myprikey.getEncoded();
                                  //傳送二進(jìn)制編碼
                                  //以下代碼轉(zhuǎn)換編碼為相應(yīng)key對(duì)象
                                  PKCS8EncodedKeySpec priPKCS8=new PKCS8EncodedKeySpec(bPKCS);
                                  KeyFactory keyf=KeyFactory.getInstance("DSA");
                                  PrivateKey otherprikey=keyf.generatePrivate(priPKCS8);
                                  


          4. 常用API

            java.security.KeyPairGenerator 密鑰生成器類
            public static KeyPairGenerator getInstance(String algorithm) throws NoSuchAlgorithmException
            以指定的算法返回一個(gè)KeyPairGenerator 對(duì)象
            參數(shù): algorithm 算法名.如:"DSA","RSA"

            public void initialize(int keysize)

            以指定的長(zhǎng)度初始化KeyPairGenerator對(duì)象,如果沒(méi)有初始化系統(tǒng)以1024長(zhǎng)度默認(rèn)設(shè)置

            參數(shù):keysize 算法位長(zhǎng).其范圍必須在 512 到 1024 之間,且必須為 64 的倍數(shù)

            public void initialize(int keysize, SecureRandom random)
            以指定的長(zhǎng)度初始化和隨機(jī)發(fā)生器初始化KeyPairGenerator對(duì)象
            參數(shù):keysize 算法位長(zhǎng).其范圍必須在 512 到 1024 之間,且必須為 64 的倍數(shù)
            random 一個(gè)隨機(jī)位的來(lái)源(對(duì)于initialize(int keysize)使用了默認(rèn)隨機(jī)器

            public abstract KeyPair generateKeyPair()
            產(chǎn)生新密鑰對(duì)

            java.security.KeyPair 密鑰對(duì)類
            public PrivateKey getPrivate()
            返回私鑰

            public PublicKey getPublic()
            返回公鑰

            java.security.Signature 簽名類
            public static Signature getInstance(String algorithm) throws NoSuchAlgorithmException
            返回一個(gè)指定算法的Signature對(duì)象
            參數(shù) algorithm 如:"DSA"

            public final void initSign(PrivateKey privateKey)
            throws InvalidKeyException
            用指定的私鑰初始化
            參數(shù):privateKey 所進(jìn)行簽名時(shí)用的私鑰

            public final void update(byte data)
            throws SignatureException
            public final void update(byte[] data)
            throws SignatureException
            public final void update(byte[] data, int off, int len)
            throws SignatureException
            添加要簽名的信息

            public final byte[] sign()
            throws SignatureException
            返回簽名的數(shù)組,前提是initSign和update

            public final void initVerify(PublicKey publicKey)
            throws InvalidKeyException
            用指定的公鑰初始化
            參數(shù):publicKey 驗(yàn)證時(shí)用的公鑰

            public final boolean verify(byte[] signature)
            throws SignatureException
            驗(yàn)證簽名是否有效,前提是已經(jīng)initVerify初始化
            參數(shù): signature 簽名數(shù)組

             */
                            import java.security.*;
                            import java.security.spec.*;
                            public class testdsa {
                            public static void main(String[] args) throws java.security.NoSuchAlgorithmException,java.lang.Exception {
                                    testdsa my=new testdsa();
                            my.run();
                            }
                            public void run()
                            {
                            //數(shù)字簽名生成密鑰
                            //第一步生成密鑰對(duì),如果已經(jīng)生成過(guò),本過(guò)程就可以跳過(guò),對(duì)用戶來(lái)講myprikey.dat要保存在本地
                            //而mypubkey.dat給發(fā)布給其它用戶
                            if ((new java.io.File("myprikey.dat")).exists()==false) {
                            if (generatekey()==false) {
                            System.out.println("生成密鑰對(duì)敗");
                            return;
                            };
                            }
                            //第二步,此用戶
                            //從文件中讀入私鑰,對(duì)一個(gè)字符串進(jìn)行簽名后保存在一個(gè)文件(myinfo.dat)中
                            //并且再把myinfo.dat發(fā)送出去
                            //為了方便數(shù)字簽名也放進(jìn)了myifno.dat文件中,當(dāng)然也可分別發(fā)送
                            try {
                            java.io.ObjectInputStream in=new java.io.ObjectInputStream(new java.io.FileInputStream("myprikey.dat"));
                              PrivateKey myprikey=(PrivateKey)in.readObject();
                            in.close();
                            // java.security.spec.X509EncodedKeySpec pubX509=new java.security.spec.X509EncodedKeySpec(bX509);
                             //java.security.spec.X509EncodedKeySpec pubkeyEncode=java.security.spec.X509EncodedKeySpec
                              String myinfo="這是我的信息";    //要簽名的信息
                            //用私鑰對(duì)信息生成數(shù)字簽名
                            java.security.Signature signet=java.security.Signature.getInstance("DSA");
                            signet.initSign(myprikey);
                            signet.update(myinfo.getBytes());
                            byte[] signed=signet.sign();  //對(duì)信息的數(shù)字簽名
                            System.out.println("signed(簽名內(nèi)容)="+byte2hex(signed));
                            //把信息和數(shù)字簽名保存在一個(gè)文件中
                            java.io.ObjectOutputStream out=new java.io.ObjectOutputStream(new java.io.FileOutputStream("myinfo.dat"));
                              out.writeObject(myinfo);
                            out.writeObject(signed);
                            out.close();
                            System.out.println("簽名并生成文件成功");
                            }
                            catch (java.lang.Exception e) {
                            e.printStackTrace();
                            System.out.println("簽名并生成文件失敗");
                            };
                            //第三步
                            //其他人通過(guò)公共方式得到此戶的公鑰和文件
                            //其他人用此戶的公鑰,對(duì)文件進(jìn)行檢查,如果成功說(shuō)明是此用戶發(fā)布的信息.
                            //
                            try {
                            java.io.ObjectInputStream in=new java.io.ObjectInputStream(new java.io.FileInputStream("mypubkey.dat"));
                               PublicKey pubkey=(PublicKey)in.readObject();
                            in.close();
                            System.out.println(pubkey.getFormat());
                            in=new java.io.ObjectInputStream(new java.io.FileInputStream("myinfo.dat"));
                            String info=(String)in.readObject();
                            byte[] signed=(byte[])in.readObject();
                            in.close();
                            java.security.Signature signetcheck=java.security.Signature.getInstance("DSA");
                            signetcheck.initVerify(pubkey);
                            signetcheck.update(info.getBytes());
                            if (signetcheck.verify(signed)) {
                            System.out.println("info="+info);
                            System.out.println("簽名正常");
                            }
                            else  System.out.println("非簽名正常");
                            }
                            catch (java.lang.Exception e) {e.printStackTrace();};
                            }
                            //生成一對(duì)文件myprikey.dat和mypubkey.dat---私鑰和公鑰,
                            //公鑰要用戶發(fā)送(文件,網(wǎng)絡(luò)等方法)給其它用戶,私鑰保存在本地
                            public boolean generatekey()
                            {
                            try {
                            java.security.KeyPairGenerator  keygen=java.security.KeyPairGenerator.getInstance("DSA");
                             // SecureRandom secrand=new SecureRandom();
                            // secrand.setSeed("tttt".getBytes()); //初始化隨機(jī)產(chǎn)生器
                            // keygen.initialize(576,secrand);     //初始化密鑰生成器
                            keygen.initialize(512);
                            KeyPair keys=keygen.genKeyPair();
                            //  KeyPair keys=keygen.generateKeyPair(); //生成密鑰組
                            PublicKey pubkey=keys.getPublic();
                            PrivateKey prikey=keys.getPrivate();
                            java.io.ObjectOutputStream out=new java.io.ObjectOutputStream(new java.io.FileOutputStream("myprikey.dat"));
                              out.writeObject(prikey);
                            out.close();
                            System.out.println("寫(xiě)入對(duì)象 prikeys ok");
                            out=new java.io.ObjectOutputStream(new java.io.FileOutputStream("mypubkey.dat"));
                            out.writeObject(pubkey);
                            out.close();
                            System.out.println("寫(xiě)入對(duì)象 pubkeys ok");
                            System.out.println("生成密鑰對(duì)成功");
                            return true;
                            }
                            catch (java.lang.Exception e) {
                            e.printStackTrace();
                            System.out.println("生成密鑰對(duì)失敗");
                            return false;
                            };
                            }
                            public String byte2hex(byte[] b)
                            {
                            String hs="";
                            String stmp="";
                            for (int n=0;n<b.length;n++)
                            {
                            stmp=(java.lang.Integer.toHexString(b[n] & 0XFF));
                            if (stmp.length()==1) hs=hs+"0"+stmp;
                            else hs=hs+stmp;
                            if (n<b.length-1)  hs=hs+":";
                            }
                            return hs.toUpperCase();
                            }
                            }


          2.4. DESede/DES對(duì)稱算法

          首先生成密鑰,并保存(這里并沒(méi)的保存的代碼,可參考DSA中的方法)

          KeyGenerator keygen = KeyGenerator.getInstance(Algorithm);

          SecretKey deskey = keygen.generateKey();

          用密鑰加密明文(myinfo),生成密文(cipherByte)

          Cipher c1 = Cipher.getInstance(Algorithm);

          c1.init(Cipher.ENCRYPT_MODE,deskey);

          byte[] cipherByte=c1.doFinal(myinfo.getBytes());

          傳送密文和密鑰,本文沒(méi)有相應(yīng)代碼可參考DSA

          .............

          用密鑰解密密文

          c1 = Cipher.getInstance(Algorithm);

          c1.init(Cipher.DECRYPT_MODE,deskey);

          byte[] clearByte=c1.doFinal(cipherByte);

          相對(duì)來(lái)說(shuō)對(duì)稱密鑰的使用是很簡(jiǎn)單的,對(duì)于JCE來(lái)講支技DES,DESede,Blowfish三種加密術(shù)

          對(duì)于密鑰的保存各傳送可使用對(duì)象流或者用二進(jìn)制編碼,相關(guān)參考代碼如下

             SecretKey deskey = keygen.generateKey();
                      byte[] desEncode=deskey.getEncoded();
                      javax.crypto.spec.SecretKeySpec destmp=new javax.crypto.spec.SecretKeySpec(desEncode,Algorithm);
                         SecretKey mydeskey=destmp;

          相關(guān)API

          KeyGenerator 在DSA中已經(jīng)說(shuō)明,在添加JCE后在instance進(jìn)可以如下參數(shù)

          DES,DESede,Blowfish,HmacMD5,HmacSHA1

          javax.crypto.Cipher 加/解密器

          public static final Cipher getInstance(java.lang.String transformation)
                      throws java.security.NoSuchAlgorithmException,
                      NoSuchPaddingException

          返回一個(gè)指定方法的Cipher對(duì)象

          參數(shù):transformation 方法名(可用 DES,DESede,Blowfish)

          public final void init(int opmode, java.security.Key key)
          throws java.security.InvalidKeyException

          用指定的密鑰和模式初始化Cipher對(duì)象

          參數(shù):opmode 方式(ENCRYPT_MODE, DECRYPT_MODE, WRAP_MODE,UNWRAP_MODE)

          key 密鑰

          public final byte[] doFinal(byte[] input)
                      throws java.lang.IllegalStateException,
                      IllegalBlockSizeException,
                      BadPaddingException
                      

          對(duì)input內(nèi)的串,進(jìn)行編碼處理,返回處理后二進(jìn)制串,是返回解密文還是加解文由init時(shí)的opmode決定

          注意:本方法的執(zhí)行前如果有update,是對(duì)updat和本次input全部處理,否則是本inout的內(nèi)容

          /*
                      安全程序 DESede/DES測(cè)試
                      */
                      import java.security.*;
                      import javax.crypto.*;
                      public class testdes {
                      public static void main(String[] args){
                      testdes my=new testdes();
                      my.run();
                      }
                      public  void run() {
                      //添加新安全算法,如果用JCE就要把它添加進(jìn)去
                      Security.addProvider(new com.sun.crypto.provider.SunJCE());
                      String Algorithm="DES"; //定義 加密算法,可用 DES,DESede,Blowfish
                      String myinfo="要加密的信息";
                      try {
                      //生成密鑰
                      KeyGenerator keygen = KeyGenerator.getInstance(Algorithm);
                      SecretKey deskey = keygen.generateKey();
                      //加密
                      System.out.println("加密前的二進(jìn)串:"+byte2hex(myinfo.getBytes()));
                      System.out.println("加密前的信息:"+myinfo);
                      Cipher c1 = Cipher.getInstance(Algorithm);
                      c1.init(Cipher.ENCRYPT_MODE,deskey);
                      byte[] cipherByte=c1.doFinal(myinfo.getBytes());
                      System.out.println("加密后的二進(jìn)串:"+byte2hex(cipherByte));
                      //解密
                      c1 = Cipher.getInstance(Algorithm);
                      c1.init(Cipher.DECRYPT_MODE,deskey);
                      byte[] clearByte=c1.doFinal(cipherByte);
                      System.out.println("解密后的二進(jìn)串:"+byte2hex(clearByte));
                      System.out.println("解密后的信息:"+(new String(clearByte)));
                      }
                      catch (java.security.NoSuchAlgorithmException e1) {e1.printStackTrace();}
                      catch (javax.crypto.NoSuchPaddingException e2) {e2.printStackTrace();}
                      catch (java.lang.Exception e3) {e3.printStackTrace();}
                      }
                      public String byte2hex(byte[] b) //二行制轉(zhuǎn)字符串
                      {
                      String hs="";
                      String stmp="";
                      for (int n=0;n<b.length;n++)
                      {
                      stmp=(java.lang.Integer.toHexString(b[n] & 0XFF));
                      if (stmp.length()==1) hs=hs+"0"+stmp;
                      else hs=hs+stmp;
                      if (n<b.length-1)  hs=hs+":";
                      }
                      return hs.toUpperCase();
                      }
                      }


          2.5. Diffie-Hellman密鑰一致協(xié)議

          公開(kāi)密鑰密碼體制的奠基人Diffie和Hellman所提出的 "指數(shù)密鑰一致協(xié)議"(Exponential Key Agreement Protocol),該協(xié)議不要求別的安全性先決條件,允許兩名用戶在公開(kāi)媒體上交換信息以生成"一致"的,可以共享的密鑰。在JCE的中實(shí)現(xiàn)用戶alice生成DH類型的密鑰對(duì),如果長(zhǎng)度用1024生成的時(shí)間請(qǐng),推薦第一次生成后保存DHParameterSpec,以便下次使用直接初始化.使其速度加快

          System.out.println("ALICE: 產(chǎn)生 DH 對(duì) ...");
                      KeyPairGenerator aliceKpairGen = KeyPairGenerator.getInstance("DH");
                      aliceKpairGen.initialize(512);
                      KeyPair aliceKpair = aliceKpairGen.generateKeyPair();

          alice生成公鑰發(fā)送組bob

          byte[] alicePubKeyEnc = aliceKpair.getPublic().getEncoded();

          bob從alice發(fā)送來(lái)的公鑰中讀出DH密鑰對(duì)的初始參數(shù)生成bob的DH密鑰對(duì)

          注意這一步一定要做,要保證每個(gè)用戶用相同的初始參數(shù)生成的

             DHParameterSpec dhParamSpec = ((DHPublicKey)alicePubKey).getParams();
                      KeyPairGenerator bobKpairGen = KeyPairGenerator.getInstance("DH");
                      bobKpairGen.initialize(dhParamSpec);
                      KeyPair bobKpair = bobKpairGen.generateKeyPair();

          bob根據(jù)alice的公鑰生成本地的DES密鑰

             KeyAgreement bobKeyAgree = KeyAgreement.getInstance("DH");
                      bobKeyAgree.init(bobKpair.getPrivate());
                      bobKeyAgree.doPhase(alicePubKey, true);
                      SecretKey bobDesKey = bobKeyAgree.generateSecret("DES");

          bob已經(jīng)生成了他的DES密鑰,他現(xiàn)把他的公鑰發(fā)給alice,

                byte[] bobPubKeyEnc = bobKpair.getPublic().getEncoded();

          alice根據(jù)bob的公鑰生成本地的DES密鑰

                 ,,,,,,解碼
                      KeyAgreement aliceKeyAgree = KeyAgreement.getInstance("DH");
                      aliceKeyAgree.init(aliceKpair.getPrivate());
                      aliceKeyAgree.doPhase(bobPubKey, true);
                      SecretKey aliceDesKey = aliceKeyAgree.generateSecret("DES");

          bob和alice能過(guò)這個(gè)過(guò)程就生成了相同的DES密鑰,在這種基礎(chǔ)就可進(jìn)行安全能信

          常用API

          java.security.KeyPairGenerator 密鑰生成器類
          public static KeyPairGenerator getInstance(String algorithm)
          throws NoSuchAlgorithmException
          以指定的算法返回一個(gè)KeyPairGenerator 對(duì)象
          參數(shù): algorithm 算法名.如:原來(lái)是DSA,現(xiàn)在添加了 DiffieHellman(DH)

          public void initialize(int keysize)
          以指定的長(zhǎng)度初始化KeyPairGenerator對(duì)象,如果沒(méi)有初始化系統(tǒng)以1024長(zhǎng)度默認(rèn)設(shè)置
          參數(shù):keysize 算法位長(zhǎng).其范圍必須在 512 到 1024 之間,且必須為 64 的倍數(shù)
          注意:如果用1024生長(zhǎng)的時(shí)間很長(zhǎng),最好生成一次后就保存,下次就不用生成了

          public void initialize(AlgorithmParameterSpec params)
          throws InvalidAlgorithmParameterException
          以指定參數(shù)初始化

          javax.crypto.interfaces.DHPublicKey
          public DHParameterSpec getParams()
          返回
          java.security.KeyFactory

          public static KeyFactory getInstance(String algorithm)
          throws NoSuchAlgorithmException
          以指定的算法返回一個(gè)KeyFactory
          參數(shù): algorithm 算法名:DSH,DH

          public final PublicKey generatePublic(KeySpec keySpec)
          throws InvalidKeySpecException
          根據(jù)指定的key說(shuō)明,返回一個(gè)PublicKey對(duì)象

          java.security.spec.X509EncodedKeySpec
          public X509EncodedKeySpec(byte[] encodedKey)
          根據(jù)指定的二進(jìn)制編碼的字串生成一個(gè)key的說(shuō)明
          參數(shù):encodedKey 二進(jìn)制編碼的字串(一般能過(guò)PublicKey.getEncoded()生成)
          javax.crypto.KeyAgreement 密碼一至類

          public static final KeyAgreement getInstance(java.lang.String algorithm)
          throws java.security.NoSuchAlgorithmException
          返回一個(gè)指定算法的KeyAgreement對(duì)象
          參數(shù):algorithm 算法名,現(xiàn)在只能是DiffieHellman(DH)

          public final void init(java.security.Key key)
          throws java.security.InvalidKeyException
          用指定的私鑰初始化
          參數(shù):key 一個(gè)私鑰

          public final java.security.Key doPhase(java.security.Key key,
          boolean lastPhase)
          throws java.security.InvalidKeyException,
          java.lang.IllegalStateException
          用指定的公鑰進(jìn)行定位,lastPhase確定這是否是最后一個(gè)公鑰,對(duì)于兩個(gè)用戶的
          情況下就可以多次定次,最后確定
          參數(shù):key 公鑰
          lastPhase 是否最后公鑰

          public final SecretKey generateSecret(java.lang.String algorithm)
          throws java.lang.IllegalStateException,
          java.security.NoSuchAlgorithmException,
          java.security.InvalidKeyException
          根據(jù)指定的算法生成密鑰
          參數(shù):algorithm 加密算法(可用 DES,DESede,Blowfish)

          */
                      import java.io.*;
                      import java.math.BigInteger;
                      import java.security.*;
                      import java.security.spec.*;
                      import java.security.interfaces.*;
                      import javax.crypto.*;
                      import javax.crypto.spec.*;
                      import javax.crypto.interfaces.*;
                      import com.sun.crypto.provider.SunJCE;
                      public class testDHKey {
                      public static void main(String argv[]) {
                      try {
                      testDHKey my= new testDHKey();
                      my.run();
                      } catch (Exception e) {
                      System.err.println(e);
                      }
                      }
                      private void run() throws Exception {
                      Security.addProvider(new com.sun.crypto.provider.SunJCE());
                      System.out.println("ALICE: 產(chǎn)生 DH 對(duì) ...");
                      KeyPairGenerator aliceKpairGen = KeyPairGenerator.getInstance("DH");
                      aliceKpairGen.initialize(512);
                      KeyPair aliceKpair = aliceKpairGen.generateKeyPair(); //生成時(shí)間長(zhǎng)
                      // 張三(Alice)生成公共密鑰 alicePubKeyEnc 并發(fā)送給李四(Bob) ,
                      //比如用文件方式,socket.....
                      byte[] alicePubKeyEnc = aliceKpair.getPublic().getEncoded();
                      //bob接收到alice的編碼后的公鑰,將其解碼
                      KeyFactory bobKeyFac = KeyFactory.getInstance("DH");
                      X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec  (alicePubKeyEnc);
                      PublicKey alicePubKey = bobKeyFac.generatePublic(x509KeySpec);
                      System.out.println("alice公鑰bob解碼成功");
                      // bob必須用相同的參數(shù)初始化的他的DH KEY對(duì),所以要從Alice發(fā)給他的公開(kāi)密鑰,
                      //中讀出參數(shù),再用這個(gè)參數(shù)初始化他的 DH key對(duì)
                      //從alicePubKye中取alice初始化時(shí)用的參數(shù)
                      DHParameterSpec dhParamSpec = ((DHPublicKey)alicePubKey).getParams();
                      KeyPairGenerator bobKpairGen = KeyPairGenerator.getInstance("DH");
                      bobKpairGen.initialize(dhParamSpec);
                      KeyPair bobKpair = bobKpairGen.generateKeyPair();
                      System.out.println("BOB: 生成 DH key 對(duì)成功");
                      KeyAgreement bobKeyAgree = KeyAgreement.getInstance("DH");
                      bobKeyAgree.init(bobKpair.getPrivate());
                      System.out.println("BOB: 初始化本地key成功");
                      //李四(bob) 生成本地的密鑰 bobDesKey
                      bobKeyAgree.doPhase(alicePubKey, true);
                      SecretKey bobDesKey = bobKeyAgree.generateSecret("DES");
                      System.out.println("BOB: 用alice的公鑰定位本地key,生成本地DES密鑰成功");
                      // Bob生成公共密鑰 bobPubKeyEnc 并發(fā)送給Alice,
                      //比如用文件方式,socket.....,使其生成本地密鑰
                      byte[] bobPubKeyEnc = bobKpair.getPublic().getEncoded();
                      System.out.println("BOB向ALICE發(fā)送公鑰");
                      // alice接收到 bobPubKeyEnc后生成bobPubKey
                      // 再進(jìn)行定位,使aliceKeyAgree定位在bobPubKey
                      KeyFactory aliceKeyFac = KeyFactory.getInstance("DH");
                      x509KeySpec = new X509EncodedKeySpec(bobPubKeyEnc);
                      PublicKey bobPubKey = aliceKeyFac.generatePublic(x509KeySpec);
                      System.out.println("ALICE接收BOB公鑰并解碼成功");
                      ;
                      KeyAgreement aliceKeyAgree = KeyAgreement.getInstance("DH");
                      aliceKeyAgree.init(aliceKpair.getPrivate());
                      System.out.println("ALICE: 初始化本地key成功");
                      aliceKeyAgree.doPhase(bobPubKey, true);
                      // 張三(alice) 生成本地的密鑰 aliceDesKey
                      SecretKey aliceDesKey = aliceKeyAgree.generateSecret("DES");
                      System.out.println("ALICE: 用bob的公鑰定位本地key,并生成本地DES密鑰");
                      if (aliceDesKey.equals(bobDesKey)) System.out.println("張三和李四的密鑰相同");
                      //現(xiàn)在張三和李四的本地的deskey是相同的所以,完全可以進(jìn)行發(fā)送加密,接收后解密,達(dá)到
                      //安全通道的的目的
                      /*
                      * bob用bobDesKey密鑰加密信息
                      */
                      Cipher bobCipher = Cipher.getInstance("DES");
                      bobCipher.init(Cipher.ENCRYPT_MODE, bobDesKey);
                      String bobinfo= "這是李四的機(jī)密信息";
                      System.out.println("李四加密前原文:"+bobinfo);
                      byte[] cleartext =bobinfo.getBytes();
                      byte[] ciphertext = bobCipher.doFinal(cleartext);
                      /*
                      * alice用aliceDesKey密鑰解密
                      */
                      Cipher aliceCipher = Cipher.getInstance("DES");
                      aliceCipher.init(Cipher.DECRYPT_MODE, aliceDesKey);
                      byte[] recovered = aliceCipher.doFinal(ciphertext);
                      System.out.println("alice解密bob的信息:"+(new String(recovered)));
                      if (!java.util.Arrays.equals(cleartext, recovered))
                      throw new Exception("解密后與原文信息不同");
                      System.out.println("解密后相同");
                      }
                      }
          posted @ 2008-10-13 19:31 bt下載| 編輯 收藏

          關(guān)于應(yīng)用服務(wù)器和web服務(wù)器的整合,有很多的資料了,可是都講的半生不熟的。根據(jù)這幾天整合tomcat 和 iis 的經(jīng)驗(yàn),再次聊聊這個(gè)話題。

          首先我們應(yīng)該對(duì)應(yīng)用服務(wù)器和web服務(wù)器有一個(gè)清晰的概念。所謂的應(yīng)用服務(wù)器,就是提供應(yīng)用的服務(wù)器,這里的應(yīng)用有很多,比如java應(yīng)用,ruby 應(yīng)用,或者 c#應(yīng)用。

          那么什么是web服務(wù)器呢?就是提供了web功能的服務(wù)器,主要就是http服務(wù),包括圖片的下載,等等一系列和web相關(guān)的。

          好吧,你會(huì)問(wèn)為什么我們不能直接使用應(yīng)用服務(wù)器呢?應(yīng)用服務(wù)器也提供了http服務(wù),比如tomcat。

          那么我們從實(shí)際出發(fā)。當(dāng)你瀏覽一個(gè)網(wǎng)頁(yè)的時(shí)候,什么情況下你會(huì)覺(jué)得速度很慢?我們僅僅考慮頁(yè)面本身。那當(dāng)然是圖片越多顯示得越慢。

          好吧,我們至少認(rèn)識(shí)到一點(diǎn),一些靜態(tài)資源,例如圖片,會(huì)嚴(yán)重影響頁(yè)面打開(kāi)的速度。當(dāng)然,這僅僅是一個(gè)方面。

          那么web服務(wù)器有什么用呢?web服務(wù)器一個(gè)優(yōu)點(diǎn)就是在處理靜態(tài)信息上。例如一些靜態(tài)的html,圖片,等等其他靜態(tài)的東西。

          那為什么tomcat不能具備這些優(yōu)點(diǎn)?這個(gè)問(wèn)題我們可以換一個(gè)說(shuō)法:為什么會(huì)計(jì)不能做市場(chǎng)營(yíng)銷呢?

          所以嘛,大家要分工明確,應(yīng)用服務(wù)器就做好它該做的:如何解釋一個(gè)jsp,如何處理java文件等等,做好這一點(diǎn)就足夠了。而web服務(wù)器也做好它該做的:如何快速向?yàn)g覽器傳遞信息,如何快速地讓瀏覽器下載圖片。

          那你又問(wèn)了,那為啥tomcat還提供一個(gè)http服務(wù)?那不是讓你開(kāi)發(fā)方便嘛!千萬(wàn)別把tomcat的http服務(wù)當(dāng)成是一個(gè)web服務(wù)器。

          說(shuō)了這么多,那么我們對(duì)應(yīng)用服務(wù)器和web服務(wù)器的整合也應(yīng)該心里有數(shù)了。就拿tomcat和iis整合來(lái)說(shuō)事吧!

          我們到底想干什么呢?很明顯,我們想讓tomcat 處理對(duì) java應(yīng)用的請(qǐng)求,而iis應(yīng)該處理圖片,css 等等其他靜態(tài)資源的事情。

          具體的細(xì)節(jié)不談了,無(wú)非就是配置 ispai_redirect 這個(gè)東東。因?yàn)槲覀冎饕f(shuō)的分工問(wèn)題,所以還是說(shuō)說(shuō)這個(gè) uriworkermap.properties 文件。

          這個(gè)文件就是處理分工的用的。例如我定義成如下這個(gè)樣子:
          /www.5a520.cn /eshop/*.do=ajp13
          /www.5a520.cn /eshop/dwr/interface/*=ajp13
          /www.5a520.cn /eshop/dwr/*=ajp13
          /www.bt285.cn /eshop/js/*=ajp13

          那么就告訴了 isapi_redirect , 以上4種請(qǐng)求,都交給tomcat處理。
          那么其他的請(qǐng)求呢?當(dāng)然是交給 iis了。

          如果我定義成這個(gè)樣子:
          /* = ajp13

          這下可慘了,iis被你浪費(fèi)了,就好像你招聘了一個(gè)會(huì)計(jì)和一個(gè)推銷的人員,但是讓會(huì)計(jì)干財(cái)務(wù)的活之外,還干了推銷。而推銷人員給閑置了。

          至于 uriworkermap.properties  的詳細(xì)配置,可以參考 tomcat 網(wǎng)站,上面有詳細(xì)的講解。


          兩種服務(wù)器的整合雖然不難,但是如果不明白其中的意義和原理,一旦項(xiàng)目配置有所變化,那就是沒(méi)有葫蘆就畫(huà)不出來(lái)瓢了。
          posted @ 2008-10-08 21:17 bt下載| 編輯 收藏

          mysql slow log 是用來(lái)記錄執(zhí)行時(shí)間較長(zhǎng)(超過(guò)long_query_time秒)的sql的一種日志工具.

          啟用 slow log

          有兩種啟用方式:
          1, 在my.cnf 里 通過(guò) log-slow-queries[=file_name]
          2, 在mysqld進(jìn)程啟動(dòng)時(shí),指定--log-slow-queries[=file_name]選項(xiàng)

          比較的五款常用工具

          mysqldumpslow, mysqlsla, myprofi, mysql-explain-slow-log, mysqllogfilter


          mysqldumpslow, mysql官方提供的慢查詢?nèi)罩痉治龉ぞ? 輸出圖表如下:
          主要功能是, 統(tǒng)計(jì)不同慢sql的
          出現(xiàn)次數(shù)(Count), 
          執(zhí)行最長(zhǎng)時(shí)間(Time), 
          累計(jì)總耗費(fèi)時(shí)間(Time), 
          等待鎖的時(shí)間(Lock), 
          發(fā)送給客戶端的行總數(shù)(Rows), 
          掃描的行總數(shù)(Rows), 
          用戶以及sql語(yǔ)句本身(抽象了一下格式, 比如 limit 1, 20 用 limit N,N 表示).

          mysqlsla, hackmysql.com推出的一款日志分析工具(該網(wǎng)站還維護(hù)了 mysqlreport, mysqlidxchk 等比較實(shí)用的mysql工具)
          整體來(lái)說(shuō), 功能非常強(qiáng)大. 數(shù)據(jù)報(bào)表,非常有利于分析慢查詢的原因, 包括執(zhí)行頻率, 數(shù)據(jù)量, 查詢消耗等.

          格式說(shuō)明如下:
          總查詢次數(shù) (queries total), 去重后的sql數(shù)量 (unique)
          輸出報(bào)表的內(nèi)容排序(sorted by)
          最重大的慢sql統(tǒng)計(jì)信息, 包括 平均執(zhí)行時(shí)間, 等待鎖時(shí)間, 結(jié)果行的總數(shù), 掃描的行總數(shù).

          Count, sql的執(zhí)行次數(shù)及占總的slow log數(shù)量的百分比.
          Time, 執(zhí)行時(shí)間, 包括總時(shí)間, 平均時(shí)間, 最小, 最大時(shí)間, 時(shí)間占到總慢sql時(shí)間的百分比.
          95% of Time, 去除最快和最慢的sql, 覆蓋率占95%的sql的執(zhí)行時(shí)間.
          Lock Time, 等待鎖的時(shí)間.
          95% of Lock , 95%的慢sql等待鎖時(shí)間.
          Rows sent, 結(jié)果行統(tǒng)計(jì)數(shù)量, 包括平均, 最小, 最大數(shù)量.
          Rows examined, 掃描的行數(shù)量.
          Database, 屬于哪個(gè)數(shù)據(jù)庫(kù)
          Users, 哪個(gè)用戶,IP, 占到所有用戶執(zhí)行的sql百分比

          Query abstract, 抽象后的sql語(yǔ)句
          Query sample, sql語(yǔ)句

          除了以上的輸出, 官方還提供了很多定制化參數(shù), 是一款不可多得的好工具.

          mysql-explain-slow-log, 德國(guó)人寫(xiě)的一個(gè)perl腳本.
          http://www.willamowius.de/mysql-tools.html

          功能上有點(diǎn)瑕疵, 不僅把所有的 slow log 打印到屏幕上, 而且統(tǒng)計(jì)也只有數(shù)量而已. 不推薦使用.
          mysql-log-filter, google code上找到的一個(gè)分析工具.提供了 python 和 php 兩種可執(zhí)行的腳本.
          http://code.google.com/p/mysql-log-filter/
          功能上比官方的mysqldumpslow, 多了查詢時(shí)間的統(tǒng)計(jì)信息(平均,最大, 累計(jì)), 其他功能都與 mysqldumpslow類似.
          特色功能除了統(tǒng)計(jì)信息外, 還針對(duì)輸出內(nèi)容做了排版和格式化, 保證整體輸出的簡(jiǎn)潔. 喜歡簡(jiǎn)潔報(bào)表的朋友, 推薦使用一下.
          myprofi, 純php寫(xiě)的一個(gè)開(kāi)源分析工具.項(xiàng)目在 sourceforge 上.
          http://myprofi.sourceforge.net/

          功能上, 列出了總的慢查詢次數(shù)和類型, 去重后的sql語(yǔ)句, 執(zhí)行次數(shù)及其占總的slow log數(shù)量的百分比.
          從整體輸出樣式來(lái)看, 比mysql-log-filter還要簡(jiǎn)潔. 省去了很多不必要的內(nèi)容. 對(duì)于只想看sql語(yǔ)句及執(zhí)行次數(shù)的用戶來(lái)說(shuō), 比較推薦.

          總結(jié)

          工具/功能 一般統(tǒng)計(jì)信息 高級(jí)統(tǒng)計(jì)信息 腳本 優(yōu)勢(shì)
          mysqldumpslow 支持 不支持 perl mysql官方自帶
          mysqlsla 支持 支持 perl 功能強(qiáng)大,數(shù)據(jù)報(bào)表齊全,定制化能力強(qiáng).
          mysql-explain-slow-log 支持 不支持 perl 無(wú)
          mysql-log-filter 支持 部分支持 python or php 不失功能的前提下,保持輸出簡(jiǎn)潔
          myprofi 支持 不支持 php 非常精簡(jiǎn)
          posted @ 2008-10-07 23:33 bt下載| 編輯 收藏

          一、Java編碼是怎么回事?

          對(duì)于使用中文以及其他非拉丁語(yǔ)系語(yǔ)言的開(kāi)發(fā)人員來(lái)說(shuō),經(jīng)常會(huì)遇到字符集編碼問(wèn)題。對(duì)于Java語(yǔ)言來(lái)說(shuō),在其內(nèi)部使用的是UCS2編碼(2個(gè)字節(jié)的Unicode編碼)。這種編碼并不屬于某個(gè)語(yǔ)系的語(yǔ)言編碼,它實(shí)際上是一種編碼格式的世界語(yǔ)。在這個(gè)世界上所有可以在計(jì)算機(jī)中使用的語(yǔ)言都有對(duì)應(yīng)的UCS2編碼

          正是因?yàn)?/span>Java采用了UCS2,因此,在Java中可以使用世界上任何國(guó)家的語(yǔ)言來(lái)為變量名、方法名、類起名,如下面代碼如下:


          class 中國(guó)
          {
              
          public String 雄起()
              {
                   
          return "中國(guó)雄起";
              }
          }

          中國(guó) 祖國(guó) 
          = new 中國(guó)();
          System.out.println(祖國(guó).雄起());

              哈哈,是不是有點(diǎn)象“中文編程”。實(shí)際上,也可以使用其他的語(yǔ)言來(lái)編程,如下面用韓文和日文來(lái)定義個(gè)類:

          class ???
          {
              
          public void スーパーマン() {  }
          }

              實(shí)際上,由于Java內(nèi)部使用的是UCS2編碼格式,因?yàn)椋?/span>Java并不關(guān)心所使用的是哪種語(yǔ)言,而只要這種語(yǔ)言在UCS2中有定義就可以。

              UCS2編碼中為不同國(guó)家的語(yǔ)言進(jìn)行了分頁(yè),這個(gè)分頁(yè)也叫“代碼頁(yè)”或“編碼頁(yè)”。中文根據(jù)包含中文字符的多少,分了很多代碼頁(yè),如cp935cp936等,然而,這些都是在UCS2中的代碼頁(yè)名,而對(duì)于操作系統(tǒng)來(lái)說(shuō),如微軟的windows,一開(kāi)始的中文編碼為GB2312,后來(lái)擴(kuò)展成了GBK。其實(shí)GBKcp936是完全等效的,用它們哪個(gè)都行。

          二、Java編碼轉(zhuǎn)換

             
          上面說(shuō)了這么多,在這一部分我們做一些編碼轉(zhuǎn)換,看看會(huì)發(fā)生什么事情。

              先定義一個(gè)字符串變量:

              String gbk = "
          中國(guó)"; // “中國(guó)”在Java內(nèi)部是以UCS2格式保存的

              用下面的語(yǔ)言輸出一定會(huì)輸出中文:

          System.out.println(gbk);

              實(shí)現(xiàn)上,當(dāng)我們從IDE輸入“中國(guó)”時(shí),用的是java源代碼文件保存的格式,一般是GBK,有時(shí)也可是utf-8,而在Java編譯程序時(shí),會(huì)不由分說(shuō)地將所有的編碼格式轉(zhuǎn)換成utf-8編碼,讀者可以用UltraEdit或其他的二進(jìn)制編輯器打開(kāi)上面的“中國(guó).class”,看看所生成的二進(jìn)制是否有utf-8的編碼(utf-8ucs2之間的轉(zhuǎn)換非常容易,因?yàn)?/span>utf-8ucs2之間是用公式進(jìn)行轉(zhuǎn)換的,而不是到代碼頁(yè)去查,這就相當(dāng)于將二進(jìn)制轉(zhuǎn)成16進(jìn)制一樣,4個(gè)字節(jié)一組)。如“中國(guó)”的utf-8編碼按著GBK解析就是“涓  浗”。如下圖所示。



          如果使用下面的語(yǔ)言可以獲得“中國(guó)”的utf-8字節(jié),結(jié)果是6(一個(gè)漢字由3個(gè)字節(jié)組成)

          System.out.println(gbk.getBytes("utf-8").length);

          下面的代碼將輸出“涓  浗”。

          System.out.println(new String(gbk.getBytes("utf-8"), "gbk"));   

          由于將“中國(guó)“的utf-8編碼格式按著gbk解析,所以會(huì)出現(xiàn)亂碼。

          如果要返回中文的UCS2編碼,可以使用下面的代碼:

          System.out.println(gbk.getBytes("unicode")[2]);

          System.out.println(gbk.getBytes("unicode")[3]);

          前兩個(gè)字節(jié)是標(biāo)識(shí)位,要從第3個(gè)字節(jié)開(kāi)始。還有就是其他的語(yǔ)言使用的編碼的字節(jié)順序可能不同,如在C#中可以使用下面的代碼獲得“中國(guó)“的UCS2編碼:

          String s = "
          ";

          MessageBox.Show(ASCIIEncoding.Unicode.GetBytes(s)[0].ToString());

          MessageBox.Show(ASCIIEncoding.Unicode.GetBytes(s)[1].ToString());

              使用上面的java代碼獲得的“中“的16進(jìn)制UCS2編碼為4E2D,而使用C#獲得的相應(yīng)的ucs2編碼為2D4E,這只是C#Java編碼內(nèi)部使用的問(wèn)題,并沒(méi)有什么關(guān)系。但在C#Java互操作時(shí)要注意這一點(diǎn)。

              如果使用下面的java編碼將獲得16進(jìn)制的“中”的GBK編碼:

          System.out.println(Integer.toHexString(0xff & xyz.getBytes("gbk")[0]));

          System.out.println(Integer.toHexString(0xff & xyz.getBytes("gbk")[1]));

          “中”的ucs2編碼為2D4EGBK編碼為D6D0

              讀者可訪問(wèn)如下的url自行查驗(yàn):

              http://unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP936.TXT

              當(dāng)然,感興趣的讀者也可以試試其他語(yǔ)言的編碼,如“人類”的韓語(yǔ)是“???”,如下面的代碼將輸出“???”的cp949ucs2編碼,其中cp949是韓語(yǔ)的代碼頁(yè)。


          String korean = "???"// 共三個(gè)韓文字符,我們只測(cè)試第一個(gè)“?”

          System.out.println(Integer.toHexString(
          0xff & korean.getBytes("unicode")[2]));

          System.out.println(Integer.toHexString(
          0xff & korean.getBytes("unicode")[3]));

          System.out.println(Integer.toHexString(
          0xff & korean.getBytes("Cp949")[0]));

          System.out.println(Integer.toHexString(
          0xff & korean.getBytes("Cp949")[1]));

           

          上面代碼的輸出結(jié)果如下:

          c7

          78

          c0

          ce

              也就是說(shuō)“?”的ucs2編碼為C778cp949的編碼為C0CE,要注意的是,在cp949中,ucs2編碼也有C0CE,不要弄混了。讀者可以訪問(wèn)下面的url來(lái)驗(yàn)證:

          http://unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP949.TXT

          http://www.bt285.cn/content.php?id=1196863

          Java支持的編碼格式

          三、屬性文件

          Java中的屬性文件只支持iso-8859-1編碼格式,因此,要想在屬性文件中保存中文,就必須使用UCS2編碼格式("uxxxx),因此,出現(xiàn)了很多將這種編碼轉(zhuǎn)換成可視編碼和工具,如Eclipse中的一些屬性文件編輯插件。

          實(shí)際上,"uxxxx編碼格式在javaC#中都可以使用,如下面的語(yǔ)句所示:

          String name= ""u7528"u6237"u540d"u4e0d"u80fd"u4e3a"u7a7a" ;

          System.out.println(name);

              上面代碼將輸出“用戶名不能為空”的信息。將"uxxxx格式顯示成中文非常簡(jiǎn)單,那么如何將中文還原成"uxxxxx格式呢?下面的代碼完成了這個(gè)工作:


          String ss = "用戶名不能為空";
          byte[] uncode = ss.getBytes("Unicode");
          int x = 0xff;
          String result 
          ="";
          for(int i= 2; i < uncode.length; i++)
          {
              
          if(i % 2 == 0) result += "\\u";
              String abc 
          = Integer.toHexString(x & uncode[i]);            
              result 
          += abc.format("%2s", abc).replaceAll(" ""0");               
          }
          System.out.println(result);

           

              上面的代碼將輸出如下結(jié)果:


          \u7528\u6237\u540d\u4e0d\u80fd\u4e3a\u7a7a

              好了,現(xiàn)在可以利用這個(gè)技術(shù)來(lái)實(shí)現(xiàn)一個(gè)屬性文件編輯器了。

          四、Web中的編碼問(wèn)題

              大家碰到最多的編碼問(wèn)題就是在Web應(yīng)用中。先讓我們看看下面的程序:

           

          <!--  main.jsp  -->

            
          <%@ page language="java"  pageEncoding="utf-8"%>

            
          <html>
                
          <head>

                
          </head>

                
          <body>
                    
          <form action="servlet/MyPost" method="post">
                        
          <input type="text" name="user" />
                        
          <p/>
                        
          <input type="submit"  value="提交"/>
                    
          </form>

                
          </body>
            
          </html>


              下面是個(gè)Servlet

            package servlet;

            import java.io.IOException;
            import java.io.PrintWriter;
            import javax.servlet.ServletException;
            import javax.servlet.http.HttpServlet;
            import javax.servlet.http.HttpServletRequest;
            import javax.servlet.http.HttpServletResponse;

            
          public class MyPost extends HttpServlet
            {

                
          public void doPost(HttpServletRequest request, HttpServletResponse response)
                        throws ServletException, IOException
                {
                    String user 
          = request.getParameter("user");
                    System.
          out.println(user);
                }
            }


              如果中main.jsp中輸入中文后,向MyPost提交,在控制臺(tái)中會(huì)輸出“中å?½”,一看就是亂碼。如果將IE的當(dāng)前編碼設(shè)成其他的,如由utf-8改為gbk,仍然會(huì)出現(xiàn)亂碼,只是亂得不一樣而已。這是因?yàn)榭蛻舳颂峤粩?shù)據(jù)時(shí)是根據(jù)瀏覽器當(dāng)前的編碼格式來(lái)提交的,如瀏覽器當(dāng)前為gbk編碼,就以gbk編碼格式來(lái)提交。 這本身是不會(huì)出現(xiàn)亂碼的,問(wèn)題就出在Web服務(wù)器接收數(shù)據(jù)的時(shí)候,HttpServletRequest在將客戶端傳來(lái)的數(shù)據(jù)轉(zhuǎn)成ucs2上出了問(wèn)題。在默認(rèn)情況下,是按著iso-8859-1編碼格式來(lái)轉(zhuǎn)的,而這種編碼格式并不支持中文,所以也就無(wú)法正常顯示中文了,解決這個(gè)問(wèn)題的方法是用和客戶端瀏覽器當(dāng)前編碼格式一致的編碼來(lái)轉(zhuǎn)換,如果是utf-8,則在doPost方法中應(yīng)該用以下的語(yǔ)句來(lái)處理:

              request.setCharacterEncoding("utf-8");

              為了對(duì)每一個(gè)Servlet都起作用,可以將上面的語(yǔ)句加到filter里。

              另外,我們一般使用象MyEclipse一樣的IDE來(lái)編寫(xiě)jsp文件,這樣的工具會(huì)根據(jù)pageEncoding屬性將jsp文件保存成相應(yīng)的編碼格式,但如果要使用象記事本一樣的簡(jiǎn)單的編輯器來(lái)編寫(xiě)jsp文件,如果pageEncodingutf-8,而在默認(rèn)時(shí),記事本會(huì)將文件保存成iso-8859-1ascii)格式,但在myeclipse里,如果文件中有中文,它是不允許我們保存成不支持中文的編碼格式的,但記事本并不認(rèn)識(shí)jsp,因此,這時(shí)在ie中就無(wú)法正確顯示出中文了。除非用記事本將其保存在utf-8格式。如下圖:


           

          http://blog.csdn.net/wangdei/archive/2008/10/07/3030758.aspx
          posted @ 2008-10-07 22:36 bt下載 閱讀(514) | 評(píng)論 (0)編輯 收藏

               摘要: 在沒(méi)有使用Spring提供的Open Session In View情況下,因需要在service(or Dao)層里把session關(guān)閉,所以lazy loading 為true的話,要在應(yīng)用層內(nèi)把關(guān)系集合都初始化,如 company.getEmployees(),否則Hibernate拋session already closed Exception;    Op...  閱讀全文
          posted @ 2008-10-05 15:01 bt下載| 編輯 收藏

          主站蜘蛛池模板: 鹤山市| 郸城县| 临朐县| 江城| 灵璧县| 连山| 嫩江县| 山阳县| 淮滨县| 湟中县| 牙克石市| 泸溪县| 海兴县| 乌海市| 阜阳市| 含山县| 武夷山市| 亳州市| 北流市| 水城县| 鄄城县| 铁力市| 兰州市| 常宁市| 公主岭市| 仪征市| 玛曲县| 铜山县| 南郑县| 镇平县| 托克托县| 盈江县| 昔阳县| 四会市| 沿河| 靖宇县| 垫江县| 阿合奇县| 志丹县| 图木舒克市| 临沭县|