<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    隨筆 - 59, 文章 - 4, 評論 - 184, 引用 - 7
    數據加載中……

    2005年11月15日

    一切都在變

    blog也搬遷了:http://blog.sina.com.cn/liuwendao

    來武漢快三年了,留在北京的最后一件物件-電吉它,也被我拿到武漢來了

    我們這么混,能成功嗎?
    立帖為證

    posted @ 2007-09-16 23:21 fisher 閱讀(1463) | 評論 (0)編輯 收藏

    來自蘇聯的笑話

      軍事演習區,一位婦女駕車在大橋前被一名軍官攔住:“對不起,公民,您現在不能過去。”“為什么?”“這座橋在一小時前被炸毀了。”“您能告訴我這究竟是怎么回事嗎?”“很抱歉,不行。我本人已于2小時前陣亡。”
      
      
      伊萬看電視,是勃在演講。伊萬覺得無聊,換了一個,還是勃在演講,又換一個,還是他。伊萬一連撥了幾十個臺,最后累了,準備關電視。這時候電視畫面變成一個KGB,怒氣沖沖地叫:“你再敢換?再敢換?再換判你10年大牢!”
      
      
      某日蘇聯舉行國慶**,沿著大街開來了炮兵、機械化步兵、坦克、自行火炮、戰術導彈、戰略核導彈,破壞力一個比一個大;隊列末尾卻是兩個帶公文包的矮子。在看臺上勃列日涅夫驚訝地說:“這兩個人破壞力比核導彈還大!他們是什么人?”
      KGB頭子說:“不是我的人。”
      國防部長說:“沒見過他們。”
      蘇聯總理說:“他們是國家計委的...”
      
      
      戈爾巴喬夫視察農場,看到豬兒乖乖,一時興起站在豬中間照了張像。
      待到報紙準備發表時,編輯為照片的標題犯了難??
      “戈爾巴喬夫同志和豬在一起”不好。
      “豬和戈爾巴喬夫同志在一起”也不好。
      報紙出版后,照片下的說明文字是??
      “左起第三位是戈爾巴喬夫同志”
      
      
      勃列日涅夫和美國總統卡特在瑞士開會,休息時間兩個人很無聊,就開始比誰的保膘更忠誠。卡特先來,他把自己的報膘叫進來,推開窗(外面是20層樓)說:“約翰,從這里跳下去!”
      約翰哭著說:“你著么能這樣呢,總統先生,我還有老婆孩子吶。”
      卡特被感動了,流著淚說是自己不對,叫約翰走了,然后掄到勃列日涅夫,他也大聲叫自己的保膘伊萬。
      “伊萬,從這里跳下去!”
      伊萬二話不說就要往下跳,卡特一把抱住他說:“你瘋了?跳下去會死的!”
      伊萬一邊掙扎著要跳下去一邊說:“放開我,混蛋,我還有老婆孩子吶。”
      
      
      早年莫斯科修地鐵,工程師將方案上報斯大林審批。不久,方案發下來,上面有斯大林的簽字。
      細心的工程師發現圖紙上多了一個圓型的茶杯印,于是莫斯科地鐵就多了一條環形線。
      
      
      斯大林肅反時期的蘇聯。一位內務人民委員部審判員結束一天的審判工作,回到辦公室,突然一個人大笑起來。對面辦公桌的同事奇怪的問道:“有什么好笑的事嗎?”“是啊,”審判員用手帕擦著笑出來的眼淚:“一個很好笑的笑話……”“哦?說來聽聽?”“你瘋了嗎?!我剛判了說這笑話的家伙五年苦役!”
      
      
      蘇聯30年代肅反擴大化時期。內務人民委員部的一間牢房里關了三個人,彼此間談起坐牢的原因。
      第一個人說,我因為反對了黨書記彼得羅夫;
      第二個人說,我因為支持了彼得羅夫;
      第三個人說,我就是彼得羅夫。
      
      
      戈爾巴喬夫和他的司機開著車在路上,戈爾巴喬夫突發異想,說:讓開!我來開。一個老警察和一個新警察在路上值勤,見一輛車歪歪扭扭的開得瘋快,老警察就對新警察說:去!好好收拾一下。新警察將車攔住之后,又沒趣沒趣地回來了。老警察問:怎么?里面是誰?新警察回答說:我也不知道里面是誰,反正給他開車的是戈爾巴喬夫。
      
      
      美國外交代表團到蘇聯訪問,蘇聯接待官員陪他們參觀“建設的偉大成就”,并且得意的說:“到了下一個五年計劃,每個蘇聯家庭都可以擁有一架私人飛機!”美國人驚訝的問:“ 他們要飛機干什么呢?”蘇聯官員說:“當然有用啊……譬如你在莫斯科聽說列寧格勒開始供應面包了,你可以馬上開著飛機趕去排上隊。”
      
      
      一位公民打電話到基輔電臺問主持人:“共產主義到底是藝術還是科學?” 主持人說:“我也不清楚,但我肯定不是科學” “為什么?” “如果是科學的話,他們應該拿狗做試驗。”
      
      
      斯大林在大會上引經據典地說:“馬克思和列寧說1+1=2,而托洛茨基和布哈林說1+1不等于3。是托洛茨基和布哈林說的對呢?還是馬克思和列寧說得對呢?”下面聽眾一臉疑惑,“毫無疑問,是馬克思和列寧說的對!”底下熱烈鼓掌,“托洛茨基和布哈林是帝國主義派來的間諜,說1+1不等于3的人罪不容赦……”
      
      
      列寧快去世了,叫趕快把繼承人斯大林召進克里姆林宮來,臨終有幾句話要囑托。“不瞞你說,我還有一個隱憂啊,斯大林。”“說吧,親愛的伊里奇。”斯大林專心地聽著。“那就是,人們會跟你走嗎?不知你想過了沒有?”“他們一定會跟我走的。”斯大林強調說,“一定會!” “但愿如此。”列寧說,“我只是擔心,萬一他們不跟你走,你怎么辦?”“沒問題!”斯大林答道:“那他們就得跟你走!”
      
      
      集體農莊莊員伊萬在河里捉到一條大魚,高興的回到家里和老婆說:“看,我們有炸魚吃了!”
      “沒有油啊。”
      “那就煮!”
      “沒鍋。”
      “烤魚!”
      “沒柴。”
      伊萬氣死了,走到河邊把魚扔了回去。那魚在水里劃了一個半圓,上身出水,舉起右鰭激動地高呼:“斯大林萬歲!”
      
      
      “瑞典能否建立共產主義”?
      “不能。”
      “為何?”
      “列寧同志說了:共產主義不在山那邊。”
      
      
      一個蘇聯KGB特工和一個美國CIA特工互相吹噓各自的機構是如何的杰出。
      那個KGB特工首先發言說,“我們擁有你們美國過去15年里所有導彈發射的詳細數據。”
      CIA特工說:“這不算什么。我們CIA掌握著你們蘇聯未來15年里所有當選的中央委員名單。”
      
      
      一艘航行在大海上的輪船快要沉了,船長叫乘客趕緊跳海,但他喊了半天沒有一個人跳,一個社會學家說我來喊,他去喊過之后所有的人都跳下海去了。船長覺得奇怪,問他是怎么喊的,社會學家回答說:我對法國人說這樣跳下去很浪漫,我對西班牙人說這樣跳下去很瀟灑,我對英國人說這樣跳下去是一種體育運動,我對美國人說這樣跳下去有利可圖,我對蘇聯人說這樣跳下去是革命行動。
      
      
      在蘇聯的一趟公交車,一個男的非常謙恭地問站在他身旁的另一個男的:“同志,請問您是克格勃嗎?”
      那人答道:“不是。”
      又問:“那您有沒有親戚或朋友是克格勃呢?”
      答:“沒有。”
      還問:“那您是否跟克格勃有些交往或聯系?”
      答:“沒有,你要干嘛啊!”
      該男生氣地說:“干嘛,他媽的,你踩著我的腳了!”
      
      
      赫魯曉夫作報告,批判斯大林。忽然,有人從臺下遞了個紙條,寫道:當他做壞事的時候,你在哪里?赫魯曉夫一看這個條子,大聲怒喝道:“是誰寫的,給我站出來。”臺下雅雀無聲,沒有人站出來。赫魯曉夫接著說道:“同志們,我當時就和你們現在一樣,你們知道我當時為什么不敢站出來了吧”
      
      
      勃列日涅夫:同志們,美國人登上了月球,我們不能再等了,黨決定讓你們上太陽。
      宇航員:總書記同志,我們會被燒死的。
      勃列日涅夫:沒關系,同志們,黨都替你們想好了,你們晚上去。
      
      
      電影《這里的黎明靜悄悄》試映時,由于其中有部分裸體鏡頭,因此主管電影審核的官員曾試圖把這部電影禁演,幸虧勃列日涅夫內部觀看時感動得熱淚盈眶,這部優秀的電影才有幸與觀眾見面,成為世界電影史上不朽的篇章。而另一部電影由于其中有主人公走到教堂時跪地痛哭的鏡頭,被電影審核官員認為是宣揚宗教而準備勒令裁掉這部分內容,恰恰勃列日涅夫看到這里時動了感情,因此這個鏡頭得以幸存下來。
      
      
      當年的捷克斯洛伐克政府中,設立了一個“海軍部”,結果,蘇聯老大哥就對捷克人說:你們是內陸國家,設什么海軍部?
      捷克人回答說:那你們不是也設了文化部嗎?

    posted @ 2007-01-20 15:15 fisher 閱讀(2198) | 評論 (0)編輯 收藏

    [調查]國內有多少人使用MINA?

    最近看到越來越多的人使用mina,甚至在線下也碰到合作公司的庫中使用MINA,出于好奇,嘗試一下用自己的blog做一下調查,訪問本blog的兄弟,如果您使用MINA作為自己的通訊基礎件,請留言介紹一下自己

    posted @ 2006-12-27 13:00 fisher 閱讀(4515) | 評論 (20)編輯 收藏

    隨想

    軟件開發的世界里充滿了不理解,客戶不理解軟件是怎樣開發的、經理不理解開發人員、開發人員不理解指揮者。

    問題在于軟件開發驚人的困難,造成很少有開發人員能夠說出軟件自始至終是怎樣開發的,并能夠對這個過程中會遇到的不同選擇所隱含的結果表現出適度的理解。

    在軟件開發人員還很年輕的時候(十幾歲或二十出頭),他們通常集中精力學習和使用技術,稱自己為perl程序員、Linux專家、EJB開發人員、.NET開發人員等。對他們來說技術是最重要的事情。因為技術在不斷的變化,年輕的程序員傾向于大致學習一個技術,在一到兩個項目中使用,然后重新開始學習新技術或者是學習以前使用過的技術的最新發展。這里的問題是,他們一遍又一遍的重復的學習的不過是同樣的低層次基本技能的不同風味。

    幸運的是,很多開發人員在經過了幾輪技術學習之后逐漸意識到:一旦用COBOLJavaC#等語言為事務控制編寫過代碼,就會開始認識到基本的、本質的東西是不變的。不同環境下的數據庫訪問、用戶界面設計等領域也是同樣的情況。不久以后,開發人員逐漸認識到無論具體的技術怎樣,很多基礎性的東西是保持不變的,這些基礎性的東西有的在學校里講過,有的沒有。
    這種認識經常發生在開發人員接近三十歲或剛過三十歲的時候,通常是人們開始穩定下來,結婚、買房的時候。這是比較幸運的情況,因為上面提到的這些新的個人需求意味著他們不可能再投入大量的時間去學習新的技術,他們需要用這些時間和家庭成員在一起。突然的,高層次的角色如項目負責人、項目經理、(非敏捷的)建模人員等對他們變得非常有吸引力,因為這些角色不需要持續花費大量的時間和精力去學習新技術。于是,等到開發人員開始真正學到技藝的時候,他們已經處于離開開發人員角色的轉變過程中了。所幸的是,新的“小年輕”不斷的跟上來,這個過程在不斷的循環重復。最終的結果是:大部分最活躍的正在開發軟件的人通常不是最稱職的做這件事的人,而他們自己甚至還不知道。

    posted @ 2006-07-24 11:31 fisher 閱讀(2249) | 評論 (6)編輯 收藏

    今天學會一個新名詞 - Troll

    來自pythoncn的maillist,呵呵,挺有意思
    -------------
    像Chris Qie <longroad1999@gmail.com>這樣的在公共論壇用侮辱性言語挑起罵戰并從中獲取某種不知名快感的人,在Usenet文化中有一個名稱:

    • Troll

    • Troll作動詞是釣魚的意思,指那些人發表某種言論后等待別人的攻擊性回復,從而獲得快感。Troll還有一個意思是斯堪的納維亞神話中一種長相丑陋、愛惡作 劇、令人討厭的巨人,和那些找罵的人有相似之處,因此也被引申過來形容那些 人,做名詞使用。回troll的貼則被稱為feed the trolls,即給trolls喂食。
    • Trolls有很多種,像Chris Qie只是其中一種,即使用種族歧視性語言激怒別人,好讓別人回帖罵他。comp.lang.python上著名的troll: Xah Lee則是長年在各個 script語言討論組上交叉張貼無關內容或用錯誤百出的話語對某種語言或者文化進 行攻擊。但無論那種troll,他們的目的都是一樣的:想通過怪誕的舉動引起別人 的注意。這是一種病態心理,是一種未成熟,類似小孩“人來瘋”似的舉動。
    • Trolls的存在對公共空間是破壞性的。它們的post會引起很多人回帖,甚至會有情緒激動者采用謾罵的方式回敬,這些人被稱為trollhunter。這些行為正中trolls 的下懷,使他們獲得被罵的快樂,從而更加積極的trolling。而且即使 trollhunter的動機是好的,也會給論壇帶來不好影響,使其他用戶接收到大量無 關信息和攻擊性信息,成為受害者。公共空間的和諧性被破壞。
    • Trolls最愿意看到別人回他的貼,無論是正兒八經指出他的錯誤還是義憤填膺的對他謾罵。對一個troll來說,最能讓他感到沮喪的則是沒有人理他。而我們,正是 應該讓他們沮喪,失去trolling的動力。
    • 對待trolls的方法,一方面要靠大家自覺,克制自己回帖的沖動,不給他們喂食。

    另一方面,在郵件列表這種有管理員的公共空間,可以向管理員提出封禁trolls的 提案。

    • 下圖是我從c.l.python上Keith Thompson對Xah Lee的trolling行為提醒公眾的帖子中拷貝過來的圖片(請使用等寬字體觀看)
            +-------------------+             .:\:\:/:/:.
           |   PLEASE DO NOT   |            :.:\:\:/:/:.:
           |  FEED THE TROLLS  |           :=.' -   - '.=:
           |                   |           '=(\ 9   9 /)='
           |   Thank you,      |              (  (_)  )
           |       Management  |              /`-vvv-'\
           +-------------------+             /         \
                   |  |        @@@          / /|,,,,,|\ \
                   |  |        @@@         /_//  /^\  \\_\
     @x@@x@        |  |         |/         WW(  (   )  )WW
     \||||/        |  |        \|           __\,,\ /,,/__
      \||/         |  |         |      jgs (______Y______)
    /\/\/\/\/\/\/\/\//\/\\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
    
    • 歷年python-cn 各種列表著名 Troll 案例:

      1. 051106-RE:python的無奈

        唉,沒想到這里鄉下賤農(的賤崽)還真不少,
        說城市人酒囊飯袋是農村人聊以自慰的一點點資本,
        就象美國黑人在奧運會奪得金牌時獲得的快樂一樣,
        我就是酒囊飯袋怎么樣?
        可惜就是你爸在田間地頭為我流汗流淚的勞作養活的我,
        哈哈?心理不平衡了?誰讓你爹是農民!
        還"龍村",真夠惡心的,一輩子你都是低賤的鄉下人 ,
        低賤!哈哈!就是血染你家老母老爹,然后發跡的,你能怎樣?HOHO~
        
        -- 是標準的運用城市差異來挑起回復的實例,在中國這樣的發展中國家尤其奏效
    • 060112-RE:Web開發有必要選Python(或者是ruby)么?????????

    • ???????????? -- 開始,僅僅是比較典型的"是否最優"探討,后來立即轉向人身攻擊,是經典的通過技術爭論引發回復的實例

    posted @ 2006-06-13 10:27 fisher 閱讀(13591) | 評論 (9)編輯 收藏

    程序員的進化——從學生到首席執行官(轉)


    /*-------------------------------------------

    ? 程序員的進化——從學生到首席執行官

    翻譯 2002 王詠剛
    http://www.contextfree.net/
    轉譯自 Omri's Computer Humor Page
    http://www.cs.bgu.ac.il/~omri/Humor/
    -------------------------------------------*/


    --------------------------------------------------------------------------------
    中學階段

    ? ? ? 10 PRINT "HELLO WORLD"
    ? ? ? 20 END
    --------------------------------------------------------------------------------
    大學一年級

    ? ? ? program Hello(input, output)
    ? ? ? ? begin
    ? ? ? ? writeln('Hello World')
    ? ? ? ? end.
    --------------------------------------------------------------------------------
    大學高年級

    ? ? ? (defun hello
    ? ? ? ? (print
    ? ? ? ? (cons 'Hello (list 'World))))
    --------------------------------------------------------------------------------
    初級程序員

    ? ? ? #include <stdio.h>
    ? ? ? void main(void)
    ? ? ? {
    ? ? ? ? char *message[] = {"Hello ", "World"};
    ? ? ? ? int i;

    ? ? ? ? for(i = 0; i < 2; ++i)
    ? ? ? ? printf("%s", message
    );
    ? ? ? ? printf("\n");
    ? ? ? }
    --------------------------------------------------------------------------------
    編程老鳥

    ? ? ? #include <iostream.h>
    ? ? ? #include <string.h>

    ? ? ? class string
    ? ? ? {
    ? ? ? private:
    ? ? ? ? int size;
    ? ? ? ? char *ptr;

    ? ? ? public:
    ? ? ? ? string() : size(0), ptr(new char('\0')) {}

    ? ? ? ? string(const string &s) : size(s.size)
    ? ? ? ? {
    ? ? ? ? ptr = new char[size + 1];
    ? ? ? ? strcpy(ptr, s.ptr);
    ? ? ? ? }

    ? ? ? ? ~string()
    ? ? ? ? {
    ? ? ? ? delete [] ptr;
    ? ? ? ? }

    ? ? ? ? friend ostream &operator <<(ostream &, const string &);
    ? ? ? ? string &operator=(const char *);
    ? ? ? };

    ? ? ? ostream &operator<<(ostream &stream, const string &s)
    ? ? ? {
    ? ? ? ? return(stream << s.ptr);
    ? ? ? }

    ? ? ? string &string::operator=(const char *chrs)
    ? ? ? {
    ? ? ? ? if (this != &chrs)
    ? ? ? ? {
    ? ? ? ? delete [] ptr;
    ? ? ? ? size = strlen(chrs);
    ? ? ? ? ptr = new char[size + 1];
    ? ? ? ? strcpy(ptr, chrs);
    ? ? ? ? }
    ? ? ? ? return(*this);
    ? ? ? }

    ? ? ? int main()
    ? ? ? {
    ? ? ? ? string str;

    ? ? ? ? str = "Hello World";
    ? ? ? ? cout << str << end

    ? ? ? ? return(0);
    ? ? ? }
    --------------------------------------------------------------------------------
    編程高手

    ? ? ? [
    ? ? ? uuid(2573F8F4-CFEE-101A-9A9F-00AA00342820)
    ? ? ? ]
    ? ? ? library LHello
    ? ? ? {
    ? ? ? ? // bring in the master library
    ? ? ? ? importlib("actimp.tlb");
    ? ? ? ? importlib("actexp.tlb");

    ? ? ? ? // bring in my interfaces
    ? ? ? ? #include "pshlo.idl"

    ? ? ? ? [
    ? ? ? ? uuid(2573F8F5-CFEE-101A-9A9F-00AA00342820)
    ? ? ? ? ]
    ? ? ? ? cotype THello
    ? ? ? {
    ? ? ? interface IHello;
    ? ? ? interface IPersistFile;
    ? ? ? };
    ? ? ? };

    ? ? ? [
    ? ? ? exe,
    ? ? ? uuid(2573F890-CFEE-101A-9A9F-00AA00342820)
    ? ? ? ]
    ? ? ? module CHelloLib
    ? ? ? {

    ? ? ? ? // some code related header files
    ? ? ? ? importheader(<windows.h>);
    ? ? ? ? importheader(<ole2.h>);
    ? ? ? ? importheader(<except.hxx>);
    ? ? ? ? importheader("pshlo.h");
    ? ? ? ? importheader("shlo.hxx");
    ? ? ? ? importheader("mycls.hxx");

    ? ? ? ? // needed typelibs
    ? ? ? ? importlib("actimp.tlb");
    ? ? ? ? importlib("actexp.tlb");
    ? ? ? ? importlib("thlo.tlb");

    ? ? ? ? [
    ? ? ? ? uuid(2573F891-CFEE-101A-9A9F-00AA00342820),
    ? ? ? ? aggregatable
    ? ? ? ? ]
    ? ? ? ? coclass CHello
    ? ? ? {
    ? ? ? cotype THello;
    ? ? ? };
    ? ? ? };

    ? ? ? #include "ipfix.hxx"

    ? ? ? extern HANDLE hEvent;

    ? ? ? class CHello : public CHelloBase
    ? ? ? {
    ? ? ? public:
    ? ? ? ? IPFIX(CLSID_CHello);

    ? ? ? ? CHello(IUnknown *pUnk);
    ? ? ? ? ~CHello();

    ? ? ? ? HRESULT __stdcall PrintSz(LPWSTR pwszString);

    ? ? ? private:
    ? ? ? ? static int cObjRef;
    ? ? ? };

    ? ? ? #include <windows.h>
    ? ? ? #include <ole2.h>
    ? ? ? #include <stdio.h>
    ? ? ? #include <stdlib.h>
    ? ? ? #include "thlo.h"
    ? ? ? #include "pshlo.h"
    ? ? ? #include "shlo.hxx"
    ? ? ? #include "mycls.hxx"

    ? ? ? int CHello::cObjRef = 0;

    ? ? ? CHello::CHello(IUnknown *pUnk) : CHelloBase(pUnk)
    ? ? ? {
    ? ? ? ? cObjRef++;
    ? ? ? ? return;
    ? ? ? }

    ? ? ? HRESULT __stdcall CHello::PrintSz(LPWSTR pwszString)
    ? ? ? {
    ? ? ? ? printf("%ws\n", pwszString);
    ? ? ? ? return(ResultFromScode(S_OK));
    ? ? ? }

    ? ? ? CHello::~CHello(void)
    ? ? ? {

    ? ? ? // when the object count goes to zero, stop the server
    ? ? ? cObjRef--;
    ? ? ? if( cObjRef == 0 )
    ? ? ? ? PulseEvent(hEvent);

    ? ? ? return;
    ? ? ? }

    ? ? ? #include <windows.h>
    ? ? ? #include <ole2.h>
    ? ? ? #include "pshlo.h"
    ? ? ? #include "shlo.hxx"
    ? ? ? #include "mycls.hxx"

    ? ? ? HANDLE hEvent;

    ? ? ? int _cdecl main(
    ? ? ? int argc,
    ? ? ? char * argv[]
    ? ? ? ) {
    ? ? ? ULONG ulRef;
    ? ? ? DWORD dwRegistration;
    ? ? ? CHelloCF *pCF = new CHelloCF();

    ? ? ? hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);

    ? ? ? // Initialize the OLE libraries
    ? ? ? CoInitializeEx(NULL, COINIT_MULTITHREADED);

    ? ? ? CoRegisterClassObject(CLSID_CHello, pCF, CLSCTX_LOCAL_SERVER,
    ? ? ? ? REGCLS_MULTIPLEUSE, &dwRegistration);

    ? ? ? // wait on an event to stop
    ? ? ? WaitForSingleObject(hEvent, INFINITE);

    ? ? ? // revoke and release the class object
    ? ? ? CoRevokeClassObject(dwRegistration);
    ? ? ? ulRef = pCF->Release();

    ? ? ? // Tell OLE we are going away.
    ? ? ? CoUninitialize();

    ? ? ? return(0);
    ? ? ? }

    ? ? ? extern CLSID CLSID_CHello;
    ? ? ? extern UUID LIBID_CHelloLib;

    ? ? ? CLSID CLSID_CHello = { /* 2573F891-CFEE-101A-9A9F-00AA00342820 */
    ? ? ? ? 0x2573F891,
    ? ? ? ? 0xCFEE,
    ? ? ? ? 0x101A,
    ? ? ? ? { 0x9A, 0x9F, 0x00, 0xAA, 0x00, 0x34, 0x28, 0x20 }
    ? ? ? };

    ? ? ? UUID LIBID_CHelloLib = { /* 2573F890-CFEE-101A-9A9F-00AA00342820 */
    ? ? ? ? 0x2573F890,
    ? ? ? ? 0xCFEE,
    ? ? ? ? 0x101A,
    ? ? ? ? { 0x9A, 0x9F, 0x00, 0xAA, 0x00, 0x34, 0x28, 0x20 }
    ? ? ? };

    ? ? ? #include <windows.h>
    ? ? ? #include <ole2.h>
    ? ? ? #include <stdlib.h>
    ? ? ? #include <string.h>
    ? ? ? #include <stdio.h>
    ? ? ? #include "pshlo.h"
    ? ? ? #include "shlo.hxx"
    ? ? ? #include "clsid.h"

    ? ? ? int _cdecl main(
    ? ? ? int argc,
    ? ? ? char * argv[]
    ? ? ? ) {
    ? ? ? HRESULT hRslt;
    ? ? ? IHello ? ? *pHello;
    ? ? ? ULONG ulCnt;
    ? ? ? IMoniker * pmk;
    ? ? ? WCHAR wcsT[_MAX_PATH];
    ? ? ? WCHAR wcsPath[2 * _MAX_PATH];

    ? ? ? // get object path
    ? ? ? wcsPath[0] = '\0';
    ? ? ? wcsT[0] = '\0';
    ? ? ? if( argc > 1) {
    ? ? ? ? mbstowcs(wcsPath, argv[1], strlen(argv[1]) + 1);
    ? ? ? ? wcsupr(wcsPath);
    ? ? ? ? }
    ? ? ? else {
    ? ? ? ? fprintf(stderr, "Object path must be specified\n");
    ? ? ? ? return(1);
    ? ? ? ? }

    ? ? ? // get print string
    ? ? ? if(argc > 2)
    ? ? ? ? mbstowcs(wcsT, argv[2], strlen(argv[2]) + 1);
    ? ? ? else
    ? ? ? ? wcscpy(wcsT, L"Hello World");

    ? ? ? printf("Linking to object %ws\n", wcsPath);
    ? ? ? printf("Text String %ws\n", wcsT);

    ? ? ? // Initialize the OLE libraries
    ? ? ? hRslt = CoInitializeEx(NULL, COINIT_MULTITHREADED);

    ? ? ? if(SUCCEEDED(hRslt)) {

    ? ? ? ? hRslt = CreateFileMoniker(wcsPath, &pmk);
    ? ? ? ? if(SUCCEEDED(hRslt))
    ? ? ? hRslt = BindMoniker(pmk, 0, IID_IHello, (void **)&pHello);

    ? ? ? ? if(SUCCEEDED(hRslt)) {

    ? ? ? // print a string out
    ? ? ? pHello->PrintSz(wcsT);

    ? ? ? Sleep(2000);
    ? ? ? ulCnt = pHello->Release();
    ? ? ? }
    ? ? ? ? else
    ? ? ? printf("Failure to connect, status: %lx", hRslt);

    ? ? ? ? // Tell OLE we are going away.
    ? ? ? ? CoUninitialize();
    ? ? ? ? }

    ? ? ? return(0);
    ? ? ? }
    --------------------------------------------------------------------------------
    黑客初階

    ? ? ? #!/usr/local/bin/perl
    ? ? ? $msg="Hello, world.\n";
    ? ? ? if ($#ARGV >= 0) {
    ? ? ? ? while(defined($arg=shift(@ARGV))) {
    ? ? ? ? $outfilename = $arg;
    ? ? ? ? open(FILE, ">" . $outfilename) || die "Can't write $arg: $!\n";
    ? ? ? ? print (FILE $msg);
    ? ? ? ? close(FILE) || die "Can't close $arg: $!\n";
    ? ? ? ? }
    ? ? ? } else {
    ? ? ? ? print ($msg);
    ? ? ? }
    ? ? ? 1;
    --------------------------------------------------------------------------------
    黑客有成

    ? ? ? #include <stdio.h>
    ? ? ? #define S "Hello, World\n"
    ? ? ? main(){exit(printf(S) == strlen(S) ? 0 : 1);}
    --------------------------------------------------------------------------------
    黑客高手

    ? ? ? % cc -o a.out ~/src/misc/hw/hw.c
    ? ? ? % a.out
    --------------------------------------------------------------------------------
    黑客大蝦

    ? ? ? % cat
    ? ? ? Hello, world.
    ? ? ? ^D
    --------------------------------------------------------------------------------
    初級經理

    ? ? ? 10 PRINT "HELLO WORLD"
    ? ? ? 20 END
    --------------------------------------------------------------------------------
    中級經理

    ? ? ? mail -s "Hello, world." bob@b12
    ? ? ? Bob, could you please write me a program that prints "Hello, world."?
    ? ? ? I need it by tomorrow.
    ? ? ? ^D
    --------------------------------------------------------------------------------
    高級經理

    ? ? ? % zmail jim
    ? ? ? I need a "Hello, world." program by this afternoon.
    --------------------------------------------------------------------------------
    首席執行官

    ? ? ? % letter
    ? ? ? letter: Command not found.
    ? ? ? % mail
    ? ? ? To: ^X ^F ^C
    ? ? ? % help mail
    ? ? ? help: Command not found.
    ? ? ? % damn!
    ? ? ? !: Event unrecognized
    ? ? ? % logout
    --------------------------------------------------------------------------------

    posted @ 2006-05-18 17:14 fisher 閱讀(1058) | 評論 (0)編輯 收藏

    Hello World的196種寫法

    還記得孔乙己說:茴香豆的‘茴’字有四種寫法嗎?現在我們的知識份子已經進步了,看看Hello World的196種寫法:)

    http://man.lupaworld.com/content/develop/hello/HelloWorld.shtml

    posted @ 2006-05-18 16:58 fisher 閱讀(874) | 評論 (0)編輯 收藏

    趴在窗戶上看長江

    下午寫完設計,趴在武漢辦公室的窗戶上看風景,天氣好的時候,左面長江右邊東湖都可以看到,其實想想在武漢出差也挺不錯的,呵呵

    posted @ 2006-05-17 18:03 fisher 閱讀(588) | 評論 (0)編輯 收藏

    關于人.....

    彼得·德魯克在他的《卓有成效的管理者?》當中,闡述了知識工作者管理的秘訣,那就是知識工作者的工作效率來自于對其工作的有效性以及他的工作是否有所成就。這本1966年出版的管理學書籍經過近50年的時間,反而越發顯得適應潮流。
    而卓有成效的知識工作管理者現在顯得比過去任何時候都要短缺,也比現時任何人才都要短缺。在現時這個信息爆炸,案例豐富的年代,戰略眼光與部署格局對于一個企業人才不再如此重要,對于企業戰略,任何有管理常識、了解企業實情的人大都可以分析得很到位,關鍵是要找到合適的人去實施。知道什么樣的人合適,以及找到這個合適的人,成為企業家最需要做的事情。而成為那個合適的人,則成為草根階層走入舞臺中央的必備能力。

    附一篇來自經濟觀察報劉軍的《笨蛋,最重要的是人!
    ---------------------------------

    ????? 2005年10月8日管理大師彼得·德魯克曾經講過一個他和《時代》《財富》等雜志的出版人亨利·魯斯交往的故事。魯斯有個很好的新雜志方案——試圖創辦“從美國人思考角度出發”的高格調文化雜志,他去向德魯克求教。德魯克分析了一番說,“這份企劃案很棒,不過晚了50年。”接著,他對魯斯說出了最重要的話:“此外,《時代》的人也無法勝任。我猜,你想鼓勵一些外面的作家來為這本雜志執筆,并以一般大眾為讀者群。但是你的專長卻是叫自己手下人搞定,因此大有不同。”?
    ????? 魯斯回答說,“我來向你請教,正因為我猜想你會這么說。”他因而放棄了這個計劃,因為他深知人的重要性。經過十多年的西方管理教育和知識傳播,中國企業管理者已經熟知戰略的理性分析,與重視人比起來更重視事,另外先建立制度、而不是依靠人的觀念也被廣泛接受。不過,我卻逐漸感覺到,在這些問題上我們可能有點矯枉過正,對于知識型工作、對于管理,或許人更重要,是應該優先考慮的。?
    ????? 9月底,索尼新任CEO、美國人霍華德·斯特林格(Howard?Stringer)宣布索尼的戰略調整計劃:全球裁員一萬人,縮減工廠數目,出售1200億日元的不動產與股票等非核心資產,對消費電子業務進行架構調整、將權力集中到這一業務的最高主管手中。在過去五年中,索尼逐漸失去消費電子霸主地位,業績很不理想,這背后的根本原因正是這些戰略調整所觸及的問題。對于這一點,大概稍微有點管理常識的人都知道,我想索尼前CEO出井伸之自然了然于心,他之下的索尼高管也清楚。不過,大概只有霍華德·斯特林格、索尼歷史上第一個外國人CEO、這個日本文化的局外人才能推行上述改革。?
    ???? 戰略,有管理常識、了解企業實情的人大都可以分析得很到位,但真正去做,就需要“合適的人”。我一直相信,選擇霍華德·斯特林格作為繼任者,是出井伸之的最重要的決策,體現這個亞洲最優秀的商業領袖的領導才能。卡洛斯·戈恩已經因成功在日產汽車(Nissan)實現大逆轉而成為全球最知名的管理者之一,他當初所做的關閉工廠與裁員、破除日本式企業聯盟等措施,都是眾所周知的弊端,但惟有他這個合適的人才能推動變革。斯特林格和戈恩都是在這種情境下最合適的人,只是恰巧他們都是外國人。?
    ????? Google、微軟和李開復之間的紛爭一直沒有停息的跡象。在這個過程中李開復把自己再次塑造成了最優秀的技術專家形象,但如果相信這一點,我們就錯誤理解了Google的智慧。如果要一流的中文搜索研發人才,Google的最佳人選絕對不是李開復,而可能是李彥宏。如果它的戰略訴求點是這個,它可以百度買下,從而得到李彥宏。但是,Google在中國,需要的哪里是什么技術專家、研發中心?現在Google中國戰略要的合適的人是據稱是“技術專家”的李開復,但他在公眾心目中的號召力和政府公關能力才是Google所看重的。?
    ????? 我們也可以循同樣的視角來看待雅虎和阿里巴巴之間的聯姻。這一次是把雅虎中國的業務交道馬云手中去讓他照料,因為對于誰了解中國市場和能夠幫助雅虎發現中國市場潛力這個問題,馬云是最佳答案。雅虎在中國的最近兩次戰略行動目標都首先是為了“人”。上一次是雅虎在中國收購3721,反而讓其老板周鴻一擔任中國區總裁,從而讓雅虎中國從跨國公司在華分支機構這樣的角色變成勇猛的中國本土企業。但在經歷一段發展時期之后,雅虎中國就需要更合適的人。我們可以認為,這是雅虎、阿里巴巴聯姻的主要原因之一。?
    ????? 先建立制度、體系,而不是“因人設事”這樣的觀點被廣泛接受,可是,我們忘記了這個觀念背后的工業化背景:所有人的都被當成了可替換的零件,所以制度體系最重要。但是,對于知識型工作來說,特別是非重復的創造性工作,每個人的工作方式、結果都截然不同。?
    ????? 我們所設計的制度體系,在當前的人員安排下也似乎運轉正常。但是,由于這些人是無法替換的,人走了,看似精妙的體系也就出現出現問題了。這個時候,是去做不可能完成的任務:尋找適合制度體系的一摸一樣的人?還是更改體系?或者看得更遠點,在現在的情境下,我們根本就不該把制度體系的重要性神話到這種程度?針對知識型工作的討論,和上文對最高管理者的討論并非沒有聯系,因為在我看來,管理工作是最重要的、最具創造性的知識工作。?
    ????? 吉姆·柯林斯在《從優秀到卓越》說卓越公司是“先人后事”:這些公司的主管不是先確定目的地(先有方向、愿景、戰略),然后才把人們引向那里;他們首先讓合適的人上車(不合適的人自然請下車),然后才決定去向何處。他所說的雖是方向、遠景,但大體上和制度是同一類型的事物。我們都應該了解,合適的人更重要,那些看似嚴密的戰略分析和完善的制度體系有時候會變成令人難以忍受的障礙,因為它們和“合適的人”可能是完全矛盾的,這些人通常都難以放到一個既定的模子中去。?

    posted @ 2006-04-25 23:19 fisher 閱讀(1047) | 評論 (0)編輯 收藏

    webwork2.2.2的dtd解析問題(感謝飛云小俠)

    今天將webwork2.2.1更換成webwork2.2.2,出現了一個奇怪的異常,每次啟動后,都會報出:
    org.xml.sax.SAXParseException:?Element?type?"global-exception-mappings"?must?be?declared.
    com.opensymphony.xwork.config.ConfigurationException:?Caught?exception?
    while?loading?file?xwork.xml
    ????with?nested?exception?
    org.xml.sax.SAXParseException:?Element?type?
    "global-exception-mappings"?must?be?declared.
    如果將xwork.xml中的global-exception-mappings注釋掉便好

    頭疼了幾個小時解決不了,不得不求助飛云小俠
    飛云小俠一出手果然不同,馬上定位了問題所在
    就是這句:
    <!DOCTYPE?xwork?PUBLIC?"-//OpenSymphony?Group//XWork?1.1.1//EN"?"http://www.opensymphony.com/xwork/xwork-1.1.1.dtd">

    原來雖然幾次升級webwork.jar,但是xwork.xml的DTD解析還是用的原來的DTD,頂多就是改了DTD的地址,也就是將這句
    ?"http://www.opensymphony.com/xwork/xwork-1.1.dtd">
    改為這樣
    ?"http://www.opensymphony.com/xwork/xwork-1.1.1.dtd">

    而實際上解析DTD是靠的前面那句
    <!DOCTYPE?xwork?PUBLIC?"-//OpenSymphony?Group//XWork?1.1.1//EN"?>
    原來一直是
    <!DOCTYPE?xwork?PUBLIC?"-//OpenSymphony?Group//XWork?1.0//EN"?>
    于是就出現了上面的問題
    多謝飛云小俠的幫助^_^

    posted @ 2006-04-21 15:07 fisher 閱讀(1274) | 評論 (0)編輯 收藏

    重讀溫博格

    自工作以來,我就養成了睡前讀書的習慣,這一年在武漢,實在買不到一些好書,每次回北京總要帶很多書過來,最近再次面臨回京購書的局面,在回京之前總不能閑著,于是從去年看過的書中亂翻,以第一感覺來決定自己最想重讀那本書,結果選中了溫博格的《成為技術領導者-解決問題的有機方法》
    兩年前,當一位同窗好友集齊全套的溫博格系列的時候,我曾很不屑的說他:一個人寫那么多書,質量顯然沒保證,買他作甚?現在看來,當時確是井底之蛙了,溫博格的書中少有瑕疵,尤其是后期作品,讀來總是讓人意猶未盡。
    過去的幾年里,我看過很多書,無論是早期GOF的設計模式,Martin Fowler的企業架構系列,還是Rod的J2EE開發厚厚的兩卷本,甚至我最喜歡的POSA系列,雖然都會給人技術方面成長的感覺,但最好情況下也只是讓我感覺到技藝的變化。
    而管理方面的書籍,則大多走入兩個極端,要么是學院式的分析解構,要么是江湖術士式的技巧集合。就像過去我曾很喜歡DEBORAH G. ANCONA的那本組織行為學和曾士強的中國式管理,但現在看來,DEBORAH關注組織多過于關注團隊,而曾士強則過于強調中國人的心理情結,實用歸實用,但可能不太適合技術人員的口味,讀他的書讓人感覺有些厚黑,讓我常常想到一句俗語:人老精,鬼老靈。

    而溫博格的寫作方式,如同Ken在英文版序中所說,會引起大量的思考,對溫博格的文字的思考,思考對溫博格文字的思考,以及對自身思考的思考....通過溫博格的書,讓我體會到的事是,讀書,有時候是為了實用,而的有時候,則純粹是為了過癮。
    本書中溫博格的MOI模型,實際上不是一個行為指導手冊,而是帶來了更加宏觀和可思考的空間,讓你對自己在團隊中的行為更加有目的性,也更加有效。我仍然記得兩年前,上述同窗好友在某技術論壇發表的一篇名為《任務分解和任務分配》的帖子,現在看來,在該貼中提出的Effective Communication仍然太過于關注技術視角了,而現在,我則更加注重人文關懷,包括對技術架構。這一點,在本書第十章得到了精彩的闡述。

    下面的內容,來自于本書第三章摘錄

    各種各樣的想法是解決問題的核心,沒有想法就不可能找到解決方案,但想法太多又會雜亂無章,領導者需要對想法的交流進行有效的管理。以下是領導者常用的12種典型的管理想法交流的方法以及點評。
    ??? >? 為團隊提供一個聰明的想法。盡管這是最顯而易見的領導者行為,而且有時新的想法的確會起到關鍵性作用,但事實上真正全新的想法是非常罕見的。比發掘一個新的聰明想法更重要的是創建一個合適的環境,是能夠解決問題的想法一旦提出就能被大家意識到。
    ??? >? 鼓勵和借鑒有用的舊想法。盡管有些領導者不愿意承認,但他們實際上是根深蒂固的模仿者。最優秀的領導者不僅承認這一點,而且將其視為一門藝術而精心培育。
    ??? >? 認真完善團隊成員提出的想法。大部分解決問題型領導者在完善一個想法上花費的時間比提出這個想法多上百倍的精力。
    ??? >? 放棄自己的想法并支持團隊采納的想法,但只有當每個成員都充分了解你的想法時才予以放棄。放棄或保留你的想法是相當簡單的,難的是要做到理智和公正。
    ??? >? 盡管時間壓力很大,仍然不要吝嗇花時間聽其他人解釋他們的想法。迫于時間壓力,大部分想法沒有經過充分理解就被否決了,事實上,其中一些想法可以為我們節省的時間是花在了解錯誤想法上時間的上百倍。
    ??? >? 檢驗別人提出的想法。在任何給定的環境中,絕大部分的想法都是沒用的,但到底哪些才是有用的呢?領導者要做的就是分析和檢驗這些想法。
    ??? >? 為了保持想法的交流,不要輕易否定團隊成員的想法。盡管檢驗這些想法是非常重要的,但幾乎沒有什么想法會危險到使我們來不及重新考慮一下我們的第一反應,就必須立刻否定。
    ??? >? 如果你不得不否定一個想法,那么一定要明確,你所否定的只是這個想法,而不是提出這個想法的人。解決問題型領導者一直清楚地知道,并不是所有的想法對每個問題都有幫助,但他們更知道,團隊中的每一個成員都是有用的。
    ??? >? 在給出你的想法之前要先對它進行檢驗。沒有人可以聰明到提出所有建設性的想法,而一個喋喋不休地發表自己未經仔細考慮的想法的人卻能有效地阻止其他人給出自己的想法。
    ??? >? 當時間和人力吃緊時,不要再考慮新的想法而應該專注于現有的想法。
    ??? >? 鼓勵團隊成員放棄以前曾經成功過,但并不適用于現在情況的想法。
    ??? >? 如果一個已被否定的想法對問題的其他部分有價值,就應該重新采納它。其實沒有絕對不好的想法,之所以“不好”只是因為它們出現在不適當的地點或時間。

    posted @ 2006-03-18 06:44 fisher 閱讀(1344) | 評論 (1)編輯 收藏

    歡迎加入“osgi觀察者”googlegroup

    去年年底,osgi R4發布,eclipse建立equinox項目,標志著以osgi為核心的組件管理模型正式進入使用階段,鑒于今年年初jsr291的推出,osgi正式走向java世界的前端,遂建立osgi觀察者group,希望能同所有關心和喜愛osgi的國內技術人員共同進步。

    加入osgi觀察者:

    Google Groups Subscribe to osgi觀察者
    Email:
    Browse Archives at groups.google.com

    posted @ 2006-03-06 13:37 fisher 閱讀(1021) | 評論 (1)編輯 收藏

    善待自己每一天

    最近的忙碌加上精神壓力,讓我患上了胃病,每天吃完飯都會難受好一陣子,給自己學醫的兒時好友打電話,被勸之:“人生苦短,要學會善待自己每一天”。遂發此文為戒。

    附一篇BJUG中Tin發的文章《白天紐約黑夜巴黎》
    -------------------------------
    白天紐約黑夜巴黎
    -------------------------------
    【王文華/文】

    我在趕些什么?我耗盡青春用盡全力,拼命追求身外之物,結果我真的比別人有錢、有名嗎?更重要的,我真的因此而快樂嗎?遠方有廣闊的地平線,為何我還在原地搖過時的呼拉圈?

    紐約和巴黎,代表了我人生的兩個面向。紐約是白天,巴黎是黑夜。紐約是前半生,巴黎是下半場。

    三十五歲之前,我認定紐約是世上最棒的城市。我在加州念研究所,畢業后迫不及待地去紐約工作。一做五年,快樂似神仙。我愛紐約的原因跟很多人一樣:她是二十世紀以來世界文化的中心。豐富、方便。靠著地鐵和出租車,你可以穿越時間,前后各跑數百年。人類最新和最舊、最好和最壞的東西,紐約都看得見。

    所以在紐約時,我把握每分每秒去體會。白天,我在金融機構做事,一天十小時。晚上下了班,去NYU學電影,一坐四小時。在那二十多歲的年紀,忙碌是唯一有意義的生活方式。活著,就是要把自己榨干,把自己居住的城市,內外翻轉過來。

    這種想法并不是到紐約才有的。其實從小開始,臺灣人就過著紐約生活。紐約生活,充滿新教徒的打拚精神和資本主義的求勝意志。相信人要借著不斷努力,克服萬難、打敗競爭。活著的目的,是更大、更多、更富裕、更有名。權力與財富,是紐約人的兩個上帝。而能幫你走進天堂的鞋,就是事業、事業、事業。

    在這種弱肉強食的生活方式,為了保持領先,每個人都在趕時間、搶資源。進了電梯,明明已經按了樓層的鈕,那燈也亮了,偏偏還要再按幾下,彷佛這樣就可以快一點。出了公司,明明已經下班了,卻還要不停講手機,搖控每一個環節。在紐約,為達目的,可以不擇手段,甚至趕盡殺絕。在紐約,沒有壞人,只有失敗者。

    臺灣,是不是也變成這樣?

    每一件事,都變成工作。上班當然是工作,下班后的應酬也是工作。有人談戀愛是在工作,甚至到酒店喝酒、KTV狂歡,臉上都殺氣騰騰,準備拚個你死我活。

    我曾熱烈擁抱這種生活,并著迷于這種因為燒烤成功而冒出的焦慮。這種焦慮讓我坐在椅子邊緣,以便迅速地跳起來閃躲明槍暗箭。這種警覺性讓我練就了酒量和膽量、抗壓性和厚臉皮。但也養成了偏執和倔強、優越感和勢利眼。在紐約時我深信:能在這里活下來的,都是可敬的對手。黯然離開的,統統是輸家。人生任何事,絕對要堅持到底。半途而廢的,必定有隱疾。在這不睡的城市,每天我醒來,帶著人定勝天的活力,跟著法蘭克辛納屈唱〈紐約?紐約〉:「如果你能在紐約成功,你可以在任何地方成功!」是的,在紐約,現代的羅馬競技場,我要和別人,以及自己,比出高低。

    這套想法,在我三十五歲以后,慢慢改變。

    第一件動搖我想法的,是父親的過世。我父親一生奉公守法、與人為善。毫無不良嗜好,身體健康地像城堡。七十二歲時,他得了癌癥、引發中風,經歷了所有的痛苦和羞辱。他一生辛勤工作、努力存錢、堅信現在的苦可以換得更好的明天。我們也相信一分耕耘、一分收獲,用在紐約拚事業的精神照顧他。但兩年的治療兵敗如山倒,最后他還是走了。父親逝世的那天,我的價值系統崩潰了。我一路走來引以為傲的「紐約精神」,沒想到這么脆弱。

    不止在病床,也在職場。當我在企業越爬越高,才發現「資本主義」在職場中也未必靈驗。上過班的都知道,很少公司真的是「開放市場」、「公平競爭」。大部分的同事都覺得你不是朋友、就是敵人。職場上偉大的,未必會成功。成功的,有時很渺小。很多人一輩子為公司鞠躬盡瘁,最后得到一支紀念筆。那些卷款潛逃的,反而變成傳奇。

    慢慢的,我體會到:世上有一種比「善有善報、惡有惡報」更高、更復雜的公平。人生有另一種比「功成名就」更幽微、更持久的樂趣。那是沖沖沖的美式資本主義,所無法解釋的。

    我能在哪里找到那種公平和樂趣呢?我想過西藏、不丹、非洲、紐西蘭。然后,我注意到法國。

    住紐約時,法國是嘲諷的對象。身為經濟、科技、和軍事強權的美國,談起法國總是忍不住調侃一番。法國是沒落的貴族,值得崇拜的人都已作古。法國人傲慢,高稅率讓每個人都很慵懶。動不動就罷工,連酒莊主人都要走上街頭。

    搬回臺灣后,普羅旺斯、托斯卡尼突然流行。我看了弗朗西斯?梅思的《美麗的托斯卡尼》,其中一句話打動了我:「在加州,時間像呼拉圈。我扭個不停,卻停在原地。在托斯卡尼,我可以在地中海的陽光下,提著一籃李子,逍遙地走一整天。」

    是啊!我在趕些什么?我耗盡青春用盡全力,拚命追求身外之物,結果我真的比別人有錢、有名嗎?更重要的,我真的因此而快樂嗎?遠方有廣闊的地平線,為何我還在原地搖過時的呼拉圈?

    當我重新學習法國,我發現法國和美國代表兩種截然不同的生活方式。美國人追求人定勝天,凡事要逆流而上。法國人講究和平共存,凡事順勢而為。紐約有很多一百層的摩天大樓,巴黎的房子都是三百年的古跡。紐約不斷創新,巴黎永遠有懷舊的氣息。巴黎人在咖啡廳聊天,紐約人在咖啡廳用計算機。紐約有人潮,巴黎有味道。紐約有鈔票,巴黎有蛋糕。

    不論是政府或個人,法國人都把精神投注在食、衣、住、行等「身內之物」。就讓美國去做老大哥吧。要征服太空、要打伊拉克、要調高利率、要發明新科技,都隨他去。法國人甘愿偏安大西洋,抽煙、喝酒、看足球、搞時尚。當美國人忙出了胃潰瘍,法國人又吃了一罐鵝肝醬。

    講到吃,法國有三百種起司、光是波爾多就有五十七個酒的產區。晚上六點朝咖啡廳門口一坐,一杯紅酒就可以聊三個小時。九點再去吃晚餐,一直吃到隔天凌晨。他們在吃上所花的時間,跟我們上班時數一樣。但諷刺的是:他們沒有「All
    You Can Eat」。

    吃很重要,但也要會挑時間,朋友介紹我去試一家法國餐廳,提醒我他們禮拜二、四晚上休息。「為什么?」我問。他說:「因為主廚要回家看足球。」

    聰明的主廚懂法律。法國法律規定一周工作最多三十五小時,大部分的人一年有五周的假期。而美國人把加班當作自己有價值的表示,度假時還拿著手機回E-mail。法國人比美國人會玩。每年六月的巴黎音樂節,從午后到深夜,幾百場露天音樂會在各處同時舉行,人多到地鐵都暫停收費。每年十月的「白夜」,平日入夜就打烊的店面,徹夜營業到清晨七點。每年夏天,巴黎市政府在塞納-馬恩省河右岸布置了三段、總長一.八公里的人工海灘。細砂、吊床、躺椅、棕櫚樹,自然海灘有的景致這里都有,讓沒有錢去海邊度假的民眾,也可以享受到海灘風光。

    當然,法國這么深厚的文化,不可能只從吃喝玩樂而來。美國人讀書,為了考證照。法國人讀書,為了搞情調。每年十月的讀書節,大城市的火車站內,民眾輪流上臺朗誦詩句。書店營業到天明,整晚有現場演奏的樂曲。「美食書展」選在銅臭味最重的證券交易所舉辦。小鎮書展的書直接「長」在樹上,讀者必須爬到樹上,把書摘下來品嘗。

    一直跟著美國走的臺灣人,會心動嗎?

    我心動了。十一月我到巴黎,一位法國朋友來接待我。臨走前我問他:「明天你要干嘛?」

    「我要去銀行。」

    「然后呢?」我問。

    「我不懂你的意思......」

    對我來說,「去銀行」是吃完午飯后跑去辦的小事。對法國人來說,這是他一天全部的行程。法國人總是專心而緩慢的,每天把一件小事做好。

    這樣的生活,對美國或臺灣人來說,實在是太頹廢了。的確也是。法國失業率接近10%,高稅率讓雇主寧愿打烊休息,免得幫員工繳稅。巴黎鬧區紙醉金迷,但郊區的少數民族卻沒有工作機會。這些都是黑暗面,但對于每日被強光烤焦的臺灣人,陰暗也許提供了喘息空間。生命的終點都一樣,有錢人的喪禮只是比較多人上香。不斷的追趕只是提前沖向謝幕,為什么不把時間花在慢慢為生命暖場?你不需要一輩子鞠躬盡瘁、死而后已。你可以偶爾伸伸懶腰、安步當車。

    我從巴黎回來,臺北并沒有改變。關了兩周的手機再度響起,一通電話找不到我的人會連續狂call十通。和朋友見面,他很關心地問我:「好了,你現在工作也辭了、歐洲也去了,接下來有什么projects?」

    「Projects」?多么紐約的字眼。

    我真想說:「好好生活,不就是人生最大的project?」但我知道在熙來攘往的臺北街頭,在不到四十歲的年紀,這樣說太矯情了。況且,我今天之所以有錢有閑享受法式生活,不也正因為我曾在美式生活中得到很多利益?我仍熱愛工作、熱愛紐約,但已不用像二十歲時一樣亦步亦趨、寸步不離。

    所以我說:「我還是會早起,白天努力寫作。但到了晚上,我想關掉手機。」

    世界少了我,其實無所謂。但我少了我,還剩什么?

    他笑一笑:「你這是用紐約來過白天,用巴黎來過黑夜。」

    唉,他講得真好!這應該是一個完美的妥協吧。也許有一天,我能創造自己的「白夜」,讓白天和黑夜融合在一起。但我還沒到那個境界。

    「明天星期一,你要干嘛?」他問。

    「我要去銀行。」

    「然后呢?」

    我張大眼睛,停頓了一下。

    「然后呢?」他追問。

    「然后我會摩拳擦掌,認真地寫一篇文章。」


    我們是不是也應該學一學法國人呢?提高些生活質量,注意身體。

    posted @ 2006-02-28 11:04 fisher 閱讀(1017) | 評論 (4)編輯 收藏

    MINA vs. QuickServer

    很久沒更新blog了,實在太忙,今天看到有朋友在我去年的blog《MINA is a good framwork 》中回復提到比較一下MNA和QuickServer,遂寫一篇小文:

    First for all, QuickServer is licensed as LGPL, and MINA as ASL

    從我個人角度而言,去年看過QuickServer的源碼,我在項目中采用的每一個框架或類庫都會做綜合評價,通常不會是一個原因導致我采用或沒有采用某個庫或框架,具體最后沒有采用QuickServer的原因忘記了,但是當時給我的總體感覺是,QuickServer雖然很方便,但不會讓我在架構上得到新的好處。而它最大的優點則是,支持JDK1.3(如果沒記錯的話),另外就是License的問題

    下面看一看來自TrusinLee的評論:

    Thank for the information about another network application framework.  I found a few differences:

    * QuickServer supports blocking mode.  (MINA supports only non-blocking mode, but you can make your operation block at your will.)
    * QuickServer provides GUI-based admin.  (MINA doesn't have one yet, but will have full JMX support soon, which is a standard.)
    * QuickServer uses java.util.logging.  (MINA uses SLF4J, which is a safe replacement of commons-logging.)
    * QuickServer uses its own XML settings.  (MINA provides Spring framework integration instead.)
    * QuickServer can specify maximum number of clients allowed.  (MINA can do this using a filter, but not implemented by default.  Of course, this will be implemented as an overload prevention filter.)
    * QuickServer team has one crew.  (MINA has three crews.)
    * QuickServer project started in 2003.  (MINA started in 2005.)
    * QuickServer has a difference event handler interface from MINA.  (You'll have to compare it by yourself.  IMHO, MINA has one simple enough handler which covers all QuickServer provides.)
    * QuickServer doesn't support UDP at all.  (MINA does)
    * QuickServer doesn't support client-side API at all.  (MINA does)
    * QuickServer integrated authentication and text protocol in its core.  (MINA didn't and they are considered as a cross-cutting concern that a filter should take care of.  IMHO, MINA is more extensible here.)


    至于對MINA更詳細的介紹,可以看看我去年翻譯的MINA的Tutorial

    MinaTutorialInChinese

    MINA的應用,在MINA的Testimonials中有兩個項目:
    開源Flash server:red5
    http://ludonet.leonardo.it/的game server
    還有,就是MINA所在的項目,Apache的LDAP

    posted @ 2006-02-24 21:58 fisher 閱讀(6234) | 評論 (18)編輯 收藏

    一個SWT Application如何轉職成為RCP Appliactioin

    昨天david問到如何將舊的swt應用轉成一個RCP應用,昨晚胃疼難忍,于是草草說了一下,就早早上床休息了,早上起來又想起這件事情,遂在這里說一下思路
    下面說一下我的思路
    (注:以下觀點未經證實,請自行斟酌使用)

    一個舊的SWT應用,應該都是有一個main函數里初始化一些UI組件,然后run一個事件循環

    在RCP中,由于是基于Eclipse的插件體系,也就是說,使用我前面那篇文章發布的RCP Application,是可以直接發布成Eclipse插件的
    所以,對于UI組件的控制也要遵循Eclipse的插件體系的代碼要求,看看Hello RCP模板中的幾個類:ApplicationActionBarAdvisor、ApplicationWorkbenchAdvisor、ApplicationWorkbenchWindowAdvisor以及RCPPlugin,想起了什么?對,OSGI

    我們只要將原swt的main函數中初始化的ui組件,放入到這幾個Advisor中進行初始化

    將下拉菜單項的ui組件的初始化工作放入到ApplicationActionBarAdvisor的如下方法:

        protected void makeActions(IWorkbenchWindow window) {
        }



        
    protected void fillMenuBar(IMenuManager menuBar) {
        }


    將其他UI組件初始化工作放入到ApplicationWorkbenchWindowAdvisor的如下方法:

        public void preWindowOpen() {

            IWorkbenchWindowConfigurer configurer 
    = getWindowConfigurer();

            configurer.setInitialSize(
    new Point(400300));

            configurer.setShowCoolBar(
    false);

            configurer.setShowStatusLine(
    false);

            configurer.setTitle(
    "Hello RCP");

        }


    至于ApplicationWorkbenchAdvisor這個類,我想你一定想起了Eclipse中的Workbench概念
    在這里,可以定義當這個RCP作為plugin的時候的Worbench的透視圖的一些屬性。

    -----------------------------------

    最后,基于Eclipse3.1的product方式的RCP程序將獲得同Eclipse相同的插件體系支持
    也就是說:你的應用本身就是基于Eclipse Platform的,這樣,你的程序也可以接受插件插入了(如果你設計的好的話^_^)
    另外,還有其他很多好處,比如在線升級功能的自動綁定啊,幫助功能的使用啊等等
    想一想,你的程序將既能作為單獨的程序運行,又能作為Eclipse的插件運行,而且還跨平臺,think about it...
    So....try it now, you will get more

    posted @ 2006-01-17 11:02 fisher 閱讀(1748) | 評論 (0)編輯 收藏

    使用Eclipse3.1的新特性方便的發布你的RCP Product

         摘要: Eclipse3.1剛剛release的時候,它的RCP發布功能就很吸引我,當時正好有個小東西要做,就用了這個功能發布了一個小程序,似乎很多人推薦用NSIS,但是我覺得Eclipse的這個功能似乎更方便,幾乎不用擔心任何部署的問題。
      閱讀全文

    posted @ 2006-01-16 23:16 fisher 閱讀(3719) | 評論 (4)編輯 收藏

    N久沒有更新了-大雜燴-blogjava年終看點

    Blog有一個多月沒有更新了,今年8個月的忙碌生活,以及最后兩個月的突擊使我徹底失去了熱情,無論是工作還是寫blog,目前只想每天休息休息,看看書。
    12月底回了一趟北京,然后又順路回大連家中辦了點事情,待了三天,又飛回武漢著手招人和培訓的工作,為明年的工作做準備,技術上有些事情還得自己動手,不知道這忙碌的生活什么時候可以停歇.....

    在妖精群里還跟非魚說要寫一篇關于架構師職責的Blog,暫時還是沒心情寫,不過自從那次在群里討論過架構師的職責之后,似乎已經有很多人寫了這方面的文章,在blogjava中就有很多了,架構師之家的文章數目也一下激增起來。

    近期blogjava也是好戲連臺,雖然不寫,看著也是過足癮了。

    canonical是個很好的寫手,學理論物理出身的思維縝密果然不同凡響,關于架構師的職責那篇,已經把能寫的都寫盡了。江南白衣 搞的springside.org.cn看起來也很吸引人,有理想的好青年的典范。非魚的幾篇關于架構的文章也寫的很扎實,預備役架構師是有些謙虛了,呵呵。Jerry在經過一段時間的忙碌之后,似乎又再次復活了,以每天一到兩篇的速度持續更新blog,讓我著實佩服他的精力,幾篇blog的涉獵范圍so廣,足見積累之深。老莊最近似乎也是瑣事纏身,除了在上月底被Rx反敲喪鐘的時候露了幾次臉,就沒怎么出現過,看來年底了哪里都是忙碌的時候。Raimundox近期多次出手,除了對老莊的《喪鐘》系列的再次釋疑之外,還為我們貢獻了Smalltalk的入門手冊,實為近期技術blog中風頭最勁的一個了。飛云小俠也更新漸少了,除了今天預告了WebWork2.2的發布,已經10天沒更新了。近期weide技術架構評估也是頗為扎眼,算是近期最全面完整的一篇技術文章了,顯然是花了精力了,難怪達到14709的訪問量 :)

    2005年讓我感覺到人的精力畢竟有限,以及,一個純技術人員能發揮的能量實在太小了,雖然不情愿,但這可能促使我更早的脫離純技術崗位,真是凌亂的一年......

    posted @ 2006-01-11 00:36 fisher 閱讀(729) | 評論 (4)編輯 收藏

    【ESB專題】之六 - System Management及其相關模式

     

    開發一個基于消息的解決方案是不容易的事情,在生產中操作這樣一個產品同樣也是一個挑戰:一個基于消息的集成解決方案一天可以產生、路由和轉換成千上萬的消息。我們不得不處理異常、效率瓶頸或改變合作系統。而為了使事情變得更加有挑戰性,組件經常被分布在不同的平臺和機器上,甚至位于不同的地理位置。

     

    System Management包含以下幾種模式

    l         Control Bus

    l         Detour

    l         Wire Tap

    l         Message History

    l         Message Store      

    l         Smart Proxy

    l         Test Message

    l         Channel Purger

     

     

    除了與生據來的復雜性、分布式集成的規模以及個性化的應用之外,低耦合的架構使得測試和debug變得更加困難。Martin Fowler將這個癥狀稱為“架構師的夢想,開發者的夢魘”。低耦合的架構原則以及間接的依賴于外部系統提供了靈活性。然而,測試一個消息生產者不了解消息消費者的系統可能會是一個挑戰。另外異步的和時間相關的消息使得事情變的更加復雜。舉例來說,消息方案可能被設計沒有被成消息生產者者必須從接受者那里得到一個回應。同樣的消息基礎設施通常保證傳輸消息,但不能保證傳輸時間。這是的開發基于消息傳送結果的測試用例變得困難。

     

    當監控一個消息解決方案,我們可以在兩個抽象層面上跟蹤消息流。一個典型的系統管理方案監控多少消息被發送或者它多長時間得到一個被處理的消息。這些監控方案不檢查消息數據,除了可能會檢查消息頭中的幾個字段(比如消息標識或者消息歷史)。與之相對的,BAMbusiness activity monitoring)方案聚焦于包含在消息中的有效數據,舉例來說,發生在過去一小時的所有訂單的金額。System Management中的很多模式都足夠通用并可以用在以上兩個目的中(監控消息頭或者消息內容)。然而,由于BAM本身就是一個新領域,并且需要從數據倉庫中獲得很多數據(有些我們根本就沒有涉及到),我們決定在系統管理的內容中討論這些模式。

     

    系統管理模式被設計用于為保持一個基于消息的復雜系統的運轉所提出的需求并提供工具。System Management的模式涉及三個種類:監控和控制,觀察和分析消息流量,測試和調試

     

    監控和控制

     

    一個Control Bus提供一個單獨的控制點來對一個分布式方案進行監控和管理。它將多個組件連接到一個中心管理控制臺,這里可以顯示每個組件的狀態并且監控通過每個組件的消息流量。控制臺同時也可以用于發送控制命令給組件,比如,轉變消息流。

    我們可能想要在路由消息時添加附加的步驟,比如驗證或者日志。由于這些步驟可能使效率降低,所以我們可以通過Control Bus來控制他們開關。一個Detour為我們提供這種能力。

     

    觀察和分析消息流量

     

    有時我們想要在不影響主要消息流的情況下觀察消息的內容。一個Wire Tap允許我們接入到消息流中。

    當我們調試一個基于消息的系統,知道一個特定的消息在哪使很有幫助的。Message History保留一個消息訪問過的所有組件的日志,而不需要增加組件間的依賴。

    然而Message History依賴于單獨的消息,一個中心的Message Store可以提供一個穿越系統的每個消息的完整記錄。結合Message HistoryMessage Store可以分析所有消息穿過系統的可能路徑。

    Wire Tap, Message History, Message Store幫助我們分析異步的消息流。為了跟蹤發送到請求-應答service的消息,我們需要在消息流中插入一個Smart Proxy

     

    測試和調試

     

    在部署前測試一個消息系統是一個非常好的注意。但是測試不應該停止在部署前。你應該有能力驗證正在運行的消息系統運行持續的運行正常。你可以周期性的發送一個Test Message到系統中并驗證結果。

    當一個組件失敗或者運行不正常,它可以簡單的終止,并放棄一個channel中的剩余消息。在測試期間這是很有用的。一個Channel Purger可以為我們做這些。

     

    posted @ 2005-11-23 20:20 fisher 閱讀(1651) | 評論 (7)編輯 收藏

    【過勞死】27個危險信號,在你身上發生幾個了? (zt)

    最近身體不太好,轉貼一則文章,提醒自己多多休息和鍛煉。

    ------------------------

     只要踏入在我們IT這個行業, 過不了幾年身體就是亞健康狀態,過渡的話就可能會“過勞死”,要想防止“過勞死”,就必須了解身體為我們發出的“過勞死”信號。

        研究者認為:在這27項癥狀和因素中占有7項以上,即是有過度疲勞危險者,占10項以上就可能在任何時候發生“過勞死”。同時,在第1項到第9項中占兩項以上或者在第10項到18項中占3項以上者也要特別注意,這27項癥狀和因素分別是:

      1.經常感到疲倦,忘性大;

      2.酒量突然下降,即使飲酒也不感到有滋味;

      3.突然覺得有衰老感;

      
    4.肩部和頸部發木發僵;

      
    5.因為疲勞和苦悶失眠;

      
    6.有一點小事也煩躁和生氣;

      7.經常頭痛和胸悶;

      8.發生高血壓、糖尿病,心電圖測試結果不正常;

      9.體重突然變化大,出現“將軍肚”;

      10.幾乎每天晚上聚餐飲酒;

      11.一天喝5杯以上咖啡;

      12.經常不吃早飯或吃飯時間不固定;

      13.喜歡吃油炸食品;

      14.一天吸煙30支以上;

      15.晚上10時也不回家或者12時以后回家占一半以上;

      16.上下班單程占2小時以上;

      17.最近幾年運動也不流汗;

      18.自我感覺身體良好而不看病;

      19.一天工作10小時以上;

      20.星期天也上班;

      21.經常出差,每周只在家住兩三天;

      22.夜班多,工作時間不規則;

      23.最近有工作調動或工作變化;

      24.升職或者工作量增多;

      25.最近以來加班時間突然增加;

      26.人際關系突然變壞;

      27.最近工作失誤或者發生不和。

      針對如何擺脫過度疲勞,何永成博士開出如下處方:

      消除腦力疲勞法:適當參加體育鍛煉和文娛活動,積極休息。如果是心理疲勞,千萬不要濫用鎮靜劑、安眠藥等,應找出引起感情憂郁的原因,并求得解脫。病理性疲勞,應及時找醫生檢查和治療。

      飲食補充法:注意飲食營養的搭配。多吃含蛋白質、脂肪和豐富的B族維生素食物,如豆腐、牛奶、魚肉類,多吃水果、蔬菜,適量飲水。

      休息恢復法:每天都要留出一定的休息時間。聽音樂、繪畫、散步等有助解除生理疲勞。

      科學健身方法:一是有氧運動,如跑步、打球、打拳、騎車、爬山等;二是腹式呼吸,全身放松后深呼吸,鼓足腹部,憋一會兒再慢慢呼出;三是做保健操;四是點穴按摩。

        哥們, 上面27條在你身上出現幾條癥狀了?  怕怕吧? 

      建議哥們們每天早上和傍晚各抽出一小時鍛煉身體,畢竟身體是革命的本錢!

    轉自: 電子商務論壇 http://bbs.eczn.com/

    上面下劃線的是我有的問題,你都有哪些?

    posted @ 2005-11-23 13:38 fisher 閱讀(707) | 評論 (0)編輯 收藏

    WTP1.0已經到達M9

    經過這半年的使用,WTP在我們組內已經從只用于開發Web Service的工具變成web開發的首選插件
    雖然只是0.7版,但WTP的設計確實很好,目前WTP1.0已經release到了M9,還有20幾天就到達release date了,熱烈期待中....

    posted @ 2005-11-23 13:29 fisher 閱讀(634) | 評論 (0)編輯 收藏

    【ESB專題】之五 - Message Endpoint及其相關模式


    ESB中另外一個重要的課題就是Message Endpoint,這是關于一個應用程序如何連接到一個消息系統,并通過它來發送和接收消息。如果你在面向一個消息API編程,則你就正在開發一個endpoint代碼。商業中間件通常都提供了這些工具。

     

    l         Messaging Gateway

    l         Messaging Mapper

    l         Transactional Client

    l         Polling Consumer

    l         Event-Driven Consumer

    l         Competing Consumers

    l         Message Dispatcher

    l         Selective Consumer

    l         Durable Subscriber

    l         Idempotent Receiver

    l         Service Activator

     

    發送和接收模式

     

    有些endpoint模式既可以使用在發送方也可以使用在接受方。它們描述一個應用連接一個消息系統的一般情況。

     

    包裝消息代碼 一個應用不應該意識到正在使用消息同另外一個應用程序通訊,大多數應用代碼應該在不知道message的情況下被編寫。在應用集成的地方,應該有一個薄薄的一層代碼來執行應用的集成部分。當集成是由消息實現的,這層將應用連接到消息系統的代碼稱為一個Message Gateway

     

    數據轉換 當發送者和接受者使用不同的數據格式,或者不同的消息格式(支持不同的發送和接收者),在這種情況下,使用一個Message Mapper來在應用格式和消息格式之間轉換數據。

     

    外部控制的事務 消息系統在內部和外部使用事務,默認的,每個發送和接收方法在他們自己的事務中運行。Message生產者和消費者應可選的使用一個Transactional Client來控制事務,當你需要將幾個消息一起發送伙通過其他事務服務整理消息時是很有用的。

     

    消息消費者模式

     

    其他endpoint模式只適用于消息消費者,發送消息是簡單的。棘手的問題是決定一個消息應該何時發送,它應包含什么,以及怎樣將它送到接受者 這是為什么我們有很多消息結構模式 但是一旦消息被構建,發送它是很容易的。另一方面,接收消息 很麻煩。因此許多endpoint模式是關于接收消息的。

     

    接收消息的一個最重要的主題就是流量控制:一個應用控制,或者調節它消費消息的速度。一個潛在的問題是任何server都面臨著大量的客戶端請求會使其超載。通過遠程過程調用(RPI),server幾乎受到客戶端調用的支配。同樣的,通過消息,server不能控制客戶端發送請求的速度 但是server可是控制它處理這些請求的速度。應用不必像消息系統傳送消息那么快的接收并處理消息;使用一個Message Channel可以使它在一個可接收的速率上處理消息。然而,當消息積累太多,而server還有資源可以處理的更快,它可以使用同步message消費者來加快速度。所以使用這些消息消費者模式可以讓你的應用將速度控制在它可以承受的范圍。

     

    許多消息消費者模式都是成對出現的,你可以任選一個使用。

     

    同步或異步接受者 可以使用輪詢消費者或一個事件驅動消費者。輪詢提供最好的流量控制,因為如果server忙,則它不再繼續輪詢消息,所以message將阻塞在隊列。事件驅動的消費者傾向于消息到達便觸發處理,所以有可能會使server超載,但是每個消費者每次只處理一個消息,所以限制消費者的數量可以有效的控制消費速度。

     

    消息分派 vs 消息獲取 另外一個二選一的模式是一堆消費者如何處理一堆消息。如果每個消費者獲得一個消息,他們可以并行的處理消息。最簡單的方法是Competing Consumers,也就是一個點對點的channel有多個消費者。每個都可能獲得任何消息;消息系統的實現決定那個消費者獲得消息。如果你想控制消息到消費者的匹配過程,使用Message Dispatcher這時只有一個消費者接收消息,但是將委派消息到一個執行者去處理。一個應用程序可以通過限制消費者或執行者的數量來控制流量。當然,分派者Message Dispatcher也可以實現一個流量控制行為。

     

    接收所有消息或者過濾 默認的,任何到達一個Message Channel的消息對于監聽著這個channelMessage Endpoint都是可用的。然而有些消費者并不打算處理channel上的任何消息,而是希望只處理其中幾種。這樣一個識別的消費者可以使用一個Selective Consumer來描述它將接收什么類型的消息。然后消息系統將只將匹配的消息對該接受者描述為可用。

     

    當斷開連接的時候訂閱消息 Publish-Subscribe Channels帶來的問題是,如果一個消費者感興趣一個channel,但是現在網絡是斷開的怎么辦?是不是一個未連接的應用將錯過發布的消息,即使它已經訂閱過該消息?默認的,是的,訂閱只對連接的訂閱者有效,為了使應用不會因為連接而錯過訂閱的消息,要使用Durable Subscriber

     

    等冪 有時一個消息可能被傳輸不只一次,可能因為消息系統不確定該消息是否已經被成功的傳遞過,或者可能因為Message ChannelQoS被設置較低來提高效率。另一面的,消息接受者認為每個消息只會被傳輸一次,并且當它們重復處理相同的消息,它們會出錯。一個Idempotent Receiver可以優雅的處理重復的消息,并且阻止它們引起接收者應用的發生錯誤。

     

    同步或異步服務 另外一個選擇是一個應用應該暴露它的service為同步(RPI)還是異步的(Messaging)。不同的客戶端可能喜歡不同的方式;不同的環境可能需要不同的方式。既然很難選擇,就一起使用。一個Service Activator連接一個Message Channel到一個應用的同步服務以便當一個消息被接收,service就被調用。同步客戶端可以簡單的直接調用service;異步客戶端可以通過發送消息調用service

     

    Message Endpoint的相關主題

     

    Message Endpoint的另外一個重要主題是很難同其他模式共同應用Transactional ClientEvent-Driven Consumer通常不能適當的在外部控制事務,Message Dispatcher也必須小心的設計這個問題,Competing Consumers的事務也是個重大問題。最安全的使用Transactional Client是使用一個單獨的Polling Consumer,但是這不會是一個令人滿意的解決方案。

     

    這里特別要提到應該會保證成功的JMS風格的MDBEJB的一種。一個MDB是一個消息消費者,它即使一個Event-Driven Consumer又是一個支持J2EE分布式事務的Transactional Client,并且它可以作為Competing Consumers動態的池化,甚至作為一個Publish-Subscribe Channel。這是在一個自由的應用中實現這些是一個困難且乏味的組合,但是這個功能作為一個EJB容器的內建的功能被提供。(MDB框架如何實現的?本質上,容器通過一個動態改變大小的可重用的執行者的線程池來實現了一個Message Dispatcher,在那里每個執行者自己使用自己的session和事務來消費消息。)

     

    最后,緊記一個單獨的Message Endpoint可以很好結合幾個不同的模式。一組Competing Consumers可以被作為Polling Consumers實現,同時也可以是一個Selective Consumers并且可以作為一個Service Activator調用一個應用的service

    一個Message Dispatcher可以是一個Event-Driven Consumer和一個使用Messaging Mapper的一個Durable Subscriber。無論一個endpoint實現什么模式,它總是一個Messaging Gateway。所以,不要考慮使用哪種模式 而要考慮如何結合他們。這是使用模式解決問題的魅力所在。

     

    要實現一個Message Endpoint有很多選擇。Message Endpoint模式用于解釋這些選擇是什么以及如何最好的使用它們。

     

     

    posted @ 2005-11-22 21:40 fisher 閱讀(2090) | 評論 (2)編輯 收藏

    【ESB專題】之四 - Message Transformation及其相關模式

     

     

     

    通常,通過消息系統集成的應用很少有同樣的消息格式。比如說,一個帳務系統同一個CRM系統對客戶對象是有著不同的概念的。基于這個,一個系統可能將消息存儲在關系表中,另一個可能存儲在文件中。集成已存在的系統通常意味著我們沒有修改系統以便使他們更好的一起工作的自由。然而,集成方案不得不協調和解決各種系統之間的不同。Message Translator模式提供了一個通用的解決方案。這里解釋幾種特定的Message Translator

     

    Message Transformation包含以下幾種模式:

    l         Envelope Wrapper

    l         Content Enricher

    l         Content Filter

    l         Claim Check

    l         Normalizer

    l         Canonical Data Model

     

    大多數消息系統放置特定的需求在消息頭的格式和內容中。我們包裝有效數據到一個Envelope Wrapper中以適應消息基礎設施的需求。如果消息需要穿過不同的消息基礎設施,可以結合多個Envelope Wrapper

    如果原始系統不能提供目標系統需要的數據域,可以使用一個Content Enricher。它可以查找缺少的信息并從已有數據中計算出它。Content Filter正好相反,它從消息中刪除不需要的數據。Claim Check也從消息中刪除數據,但是它將存儲他們以便以后取回。Normalizer將多個不同格式的消息翻譯成統一格式。

     

    消除依賴

     

    消息轉換在集成中是一個很深的話題。Message ChannelsMessage Routers可以通過消除應用必須知道另外一個應用的位置的需求從而解除應用間的基本依賴。

    一個應用可以發送一個消息到Message Channel而不必擔心誰來取出消息。然而消息格式增加了另外一種依賴。如果一個應用不得不將消息格式化成另外一個應用的數據格式,通過Message Channel解耦的說法就像一個幻想。接收系統的任何改變或切換到另外一個接收系統都需要對發送應用進行改變。Message Translators可以幫助除去這種依賴。

     

    元數據管理

     

    將消息從一個消息格式轉換到另一個格式需要操作元數據 描述數據格式的數據。

    元數據在兩個并行系統之間的集成中扮演著非常重要的角色。一個處理實際的消息數據,另外一個處理元數據。許多用于處理消息數據的模式也同樣可以管理元數據。比如說,Channel Adapter不僅可以從一個系統中移進和移出消息,還可以從一個外部應用中獲取元數據,并將其加載到一個元數據倉庫中。使用這個倉庫,集成開發者可以定義應用元數據與Canonical Data Model.之間的轉換。

     

     

    元數據集成

     

    o_MT1.JPG

    舉例來說,上面的圖描述了兩個需要交換客戶信息的應用的集成。每個系統的客戶數據的定義稍有不同。從
    AB的消息需要轉換一下才能被B接收。如果Channel Adapters可以抽取元數據的話,創建一個轉換將非常簡單。然后這個元數據可以被放入一個倉庫,大大的簡化了Message Translator的配置和驗證。元數據可以被存儲成不同的格式。通常XML消息使用XSD格式。其他EAI工具實現所有元數據格式,但是允許管理員導入或導出到其他格式。

     

    消息系統外的數據轉換

     

    這些轉換模式組成的很多原則可以被應用于非消息集成。比如說,File Transfer可以執行系統間的轉換工作。類似的,Remote Procedure Invocation必須使請求使用要調用的service的格式,即使應用本身的格式可能不同。典型的,需要調用程序來執行轉換。一些最成熟的轉換引擎組成了ETL工具,比如Informatica或者DataMirror。這些工具一般都一次轉換大量的數據,而不是轉換單個消息。

    Message System應專注于幾種基本的Message Translator模式。而不應該關心實體間結構轉換的細節(不同的數據模型之間的轉換,比如ER模型不支持多對多關系而其他的支持這種)。關于這個主題最老也使最相關的書是Kent的《Data and Reality》。

     

    posted @ 2005-11-21 21:40 fisher 閱讀(1614) | 評論 (1)編輯 收藏

    【ESB專題】之三 - Message Construction及其相關模式


    在前面的關鍵組件中我們提到了Messages。當兩個應用想要交換數據,他們將數據包裝在一個message中。但是一個Message Channel不能傳輸原始數據,它只能傳輸包含在一個message中的數據(即傳輸特定格式的數據)。

     

    Message在消息系統中處于信息載體的位置,而在ESB中,還消息識別、序列以及生存周期等職責。

     

    Message的結構涉及以下幾個模式:

    l         Command Message      

    l         Document Message      

    l         Event Message

    l         Request-Reply

    l         Return Address

    l         Correlation Identifier

    l         Message Sequence

    l         Message Expiration

    l         Format Indicator

     

    創建和發送一個Message產生以下幾個問題:

     

    消息意圖 Message最終是為了運送一些數據,但是發送者可能有其他目的,比如它希望接受者使用消息做些事情。它可以發送一個Command Message,指定它希望調用的接受者上的函數或方法。發送者告訴接受者運行那些代碼。發送者可以發送一個Document Message來傳送它的數據結構到接受者。發送者發送數據到接受者,但是不指定接受者應該做什么。

    或者它可以發送一個Event Message,通知接受者發送者那里有一個改變。發送者不應告訴接受者應該怎樣適應這個改變,而只應提供通知。

     

    返回一個應答 當一個應用發送一個消息,它通常期望得到一個回應來確定消息被處理并提供一個結果。這是一個Request-Reply場景。Request通常是一個Command Message,而應答是一個包含返回值或異常的Document Message。請求者應該在請求中指定一個Return Address來告訴應答者使用哪個通道來傳回應答。請求者可能在一個處理過程中發送多個請求,所以應答應該包含一個Correlation Identifier來指出這個應答對應哪個請求。

    有兩個Request-Reply場景需要注意;它們都包含了一個Command Message請求和一個對應的Document Message應答。在第一個場景中,Message RPC,請求不但要調用應答者的函數,而且期望一個返回值。這是RPC。另一個場景中,Message Query,請求者執行一個查詢;應答者執行查詢并在應答中返回結果。這是遠程查詢。

     

    大量的數據 有時應用想要傳送大量的數據結構,放入一個單獨的message里面不是很合適。在這種情況下,將他們分解成可管理的消息塊并將他們作為Message Sequence發送。這些消息必須按順序發送,以便接受者能夠充足原始數據結構。

     

    慢速消息 消息系統的一個問題是發送者通常不知道接受者要多久才能接受到消息。然而,消息的內容可能是時間敏感的,所以如果消息在某一時間內沒有被接受,它將被忽略并取消。在這種情況下,sender應該使用Message Expiration來指定一個到期時間。如果消息系統在規定時間內無法傳輸一個消息,應該將它取消并刪除到Dead Letter Channel中。同樣的一個receiver接受到一個超出該時間點的消息,也要取消該消息。

     

    總之,只選擇使用消息是不夠的。使一個消息工作的其他決定性因素來自于消息所要完成的任務。

     

    posted @ 2005-11-19 20:31 fisher 閱讀(1415) | 評論 (6)編輯 收藏

    【ESB專題】之二 - Message Channel及其相關模式

     

     

    在前面一個專題中,我們列出了一個ESB系統所需要關心的所有方面的關鍵組件,這里介紹其中的Message Channels所關注的問題及相關的模式。

     

    Message Channel主題之下包含以下模式,分別用于解決channel中不同方面的問題:

     

    l         Point-to-Point Channel  

    l         Publish-Subscribe Channel   

    l         Datatype Channel  

    l         Invalid Message Channel      

    l         Dead Letter Channel     

    l         Guaranteed Delivery     

    l         Channel Adapter    

    l         Messaging Bridge  

    l         Message Bus  

     

     

    當兩個應用需要交換數據,它們通過連接兩端的channel來發送數據。發送的應用可能不知道哪個應用將接受數據。然而,通過選擇特定的channel來發送,發送者知道接受者將是守候在channel另一端等待數據的應用之一。通過這種方式,生產數據的應用有了一個同數據消費者通訊的途徑。

     

    Message Channels面對的各個主要問題:

     

    如果一個應用要傳輸或接受數據,它一定會用到一個channel。問題是你的應用要知道要使用什么樣的channel,以及用它來做什么。

     

    固定的channel集合 Channel中討論的一個主題是,一個應用可用的Message Channel集合一般是固定的。設計一個應用時,一個開發者必須知道將某種類型的數據放到哪里可以同其他應用共享該數據,以及從什么地方可以找到其他應用的特定數據。這些通訊路徑不會在運行期動態的創建和發現;它們需要在設計期間就確定下來,以便應用知道它的數據從哪里來以及數據將去哪里。( 雖然大多數channel必須被靜態定義使正確的,但是也有例外,有些情況下動態channel是很好用的。一個例外就是Request-Reply模式中的reply channel。請求者可以創建或者獲得一個應答者不知道的新的channel,并在請求消息中指定該channelReturn Address,應答者就可以使用它。另外一個例外是支持集成channels的消息系統實現。一個接受者可以訂閱一個集成體系的根channel,然后發送者可以發布消息到一個子channel,而接受者不需要知道子channel,仍然會收到消息。這些都是不常見的情況,channel通常仍然是在部署之前被定義,并且應用被設計連接到一個已知的channel集合 )。

     

    決定channel的集合 一個相關的主題是,誰決定那些Message Channel是可用的 message系統還是應用程序?換句話說,是由消息系統確定一些channel,然后要求應用程序使用它們?還是應用決定它們需要什么channel,然后要求消息系統提供它們?這個問題沒有一個簡單的答案,設計必須的channel集合是迭代的。首先,應用要決定消息系統提供哪些channel。然后應用將圍繞這些channel設計它們的通訊,但是如果這樣是不可行的,它們將需要添加額外的channel。當一些應用已經使用了一個確定的channel集合,當加入新的應用,它們將使用已存在的channel。當為應用添加新的功能,它們需要新的channel

     

    單向channel 另外一個經常引起混淆的是一個Message channel是單向的還是雙向的。技術上來說,兩者都不是,一個channel更像是一個桶,一個應用放入數據,另外一個應用從中取出數據。但是由于數據是放在消息中從一個應用傳到另一個,這使得channel具有方向性,使它變成單向的。如果一個channel是雙向的,應用將從中發送和接受數據,雖然技術上是可行的,但是會有小小的問題,應用將有可能持續的取出自己放進去的希望發送給其他應用的消息。所以,為了實踐性的目的,channel是單向的。作為結論,兩個應用如果有雙向通訊,它們需要兩個channel,每個方向一個

     

    如何使用Message channels

     

    現在我們來討論以下如何使用channel

     

    一對一或者一對多 當你的應用共享一些數據,你希望只將它共享給一個應用還是對它感興趣的所有應用?要傳送數據到一個單獨的應用,使用Point-to-Point Channel。這并不意味著發送到這個channel的每個數據都發送給同樣的接受者,因為一個channel可能有多個接受者。它意味著,實際上,保證每個數據都被同一個應用接收。如果你想讓所有接收應用都能接收數據,使用Publish-Subscribe Channel。當你通過這種方式發送數據,channel將高效的復制數據到每一個接收者。

     

    什么類型的數據 任何內存中的數據都有一個類型。另一方面,所有數據都是一些bytes集合。消息系統工作同這類似,消息內容必須符合某些類型以便接受者了解數據的結構。Datatype Channel認為在一個channel中的數據必須擁有同樣的類型。這也是為什么消息系統需要很多channel的主要原因(每個channel一種格式)。如果數據可以是任意的格式,那么消息系統在兩個應用之間只需要兩條channel

     

    無效的和過期的消息 消息系統可以確定消息被正確的傳輸,但是它不能保證接受者知道如何處理它。接收者對數據格式和意義存在期望。當它接收到一個不符合期望的消息,它什么也不能做。它們能作的,就是將這個陌生的消息放入到一個特別設計的Invalid Message Channel并希望某些監控這個channel的工具能夠取出這個消息,并指出該如何處置它們。許多消息系統有一個類似的內建特征,一個Dead Letter Channel,用來存放成功送出但卻無法成功投遞的消息。另外,一個系統管理工具應該監視Dead Letter Channel并且決定如何處置這些無法投遞的消息。

     

    故障檢測 如果一個消息系統發生故障或停機維護,它的消息會怎樣?當它重啟并重新運行,它的消息能否還在它的channel中?默認的:不會;channel將消息存儲在內存中。然而,Guaranteed Deliverychannel持久化以便將它們的消息存儲到硬盤上。這會影響效率,但會使消息更加可靠,即使消息系統是不可靠的。

     

    非消息客戶端 如果一個應用不能連接到一個消息系統但是仍然想要參與消息怎么辦?通常它只能自認倒霉了,但是如果消息系統可以通過某種方式連接到應用系統 通過它的用戶界面,它的service API,它的數據庫,或者一個TCP/IPHTTP這樣的網絡連接 那么消息系統可以使用一個Channel Adapter。這允許你連接到一個或多個連接到應用的channel而不必改變應用或者可能也不需要一個同應用運行在同一個機器上的消息客戶端。有時‘非消息客戶端’真的是一個消息客戶端,但是只有連接的是其他消息系統的時候。

     

    通訊中樞 隨著越來越多的企業應用系統連接到消息系統以便通過消息暴露他們的功能,消息系統變成了企業中一站式功能的集散地。一個應用只需簡單的知道用哪個channel來請求功能,以及從哪個監聽結果。消息系統本質上變成一個消息總線,一個提供所有企業應用甚至變化中的應用和功能的中樞。你可以更快速的集成。

     

    如你所見,使用消息構建應用不僅僅是將他們連接到消息系統并發送消息。消息必須使用Message Channel來發送。Channel必須被設計為某個目的服務,比如基于被共享的數據類型,共享數據的應用類型,和接收數據的應用。

     

    posted @ 2005-11-17 22:56 fisher 閱讀(1295) | 評論 (1)編輯 收藏

    【ESB專題】-面向消息的EAI的關鍵組件

     

    企業集成有很多種模式,隨著技術的發展,實時的、面向消息的企業集成越來越成為主流,面向消息的企業集成的穩定性和兼容性要求其基礎件,也就是message系統必須提供足夠強壯和可擴展的設計,下面幾種是作為面向消息的企業集成的基礎件所必須提供的幾個關鍵性組件。

     

    消息集成使得message系統負責轉換兩個應用之間的數據格式,從而使得應用可以專注于他們需要共享什么數據而不是如何共享它們。

     

    以下這些組件,在著名的ESB系統Mule中都可以見到,有興趣的同學可以去看看Mule的源代碼,雖然Mule對ESB的實現有很多不成熟的地方,以至于讓我不敢在生產系統中使用(唉...可恨的Mule),但是畢竟是一個大而全的系統,值得借鑒一下。
     

    Channels — Messaging應用通過一個Message Channel傳送數據,一個senderreceiver的虛擬管道。一個新安裝的消息系統默認不包含任何channel;你必須知道你的應用需要怎樣通訊,然后才能建立channel來完成它。

     

    Messages — Message是在channel上傳輸的不可分割的包。因此,為了傳輸數據,應用必須將數據打包成一個或多個packets,將每個packet包裝成一個message,然后將其傳輸到一個channel。同樣的,一個receiver應用在接受到message后必須從message中提取出數據才能使用。Message系統應該能重復的傳輸message,直到它成功為止。

     

    Pipes and Filters 最簡單的情況下,message系統將一個消息直接從sender計算機傳送到receiver計算機。然而,通常在消息從sender中發出后,receiver接受到之前,有一些動作需要對message執行。舉例來說,message也許需要驗證或者轉換。Pipes and Filters架構使用channel將多個處理步驟連接起來。

     

    Routing 在一個大型的、擁有許多不同的應用和channel連接的企業應用中,一個message可能需要穿過多個channel才能到達最終目的地。Message的路由如此復雜以至于最初的發送者無法知道那些channel能將message傳送給最終的receiver。因此,最初的發送者將message發送給一個Message Router,一個以Pipes and Filters架構中的filter形式存在的應用組件。Router將決定如何將message發送到最終receiver或者至少是下一個Router

     

    Transformation 不同的應用的數據格式可能不同。為了調節senderreceiver之間的數據格式不同的問題,message必須經過一個中介的filter,一個Message Translator,它將message從一個格式轉換成另外一個格式,或轉換成一個公共的格式。

     

    Endpoints 大多數的應用程序沒有內建的能力來同一個message系統交互。因此他們必須包含一個中間層,它知道應用系統如何工作,也知道message系統如何工作,并橋接兩個系統。這個系統是一組并列的Message Endpoints,它能夠使得應用發送和接受message

     

    System manager 作為一個大型的消息集成系統,其面向消息的、異步、低耦合的本質使得系統更加難以調試,運行期的狀態也難以跟蹤,所以,我們必須有強有力的手段進行系統的運行期管理和監控,同時最好能夠在運行進行動態更新,以保障系統的強壯性。


    企業應用集成是一個巨大而復雜的系統,作為其基礎件ESB系統,必須能夠提供對其完全的支撐以及足夠強壯的系統,這正是ESB系統建設的難度所在。

    posted @ 2005-11-16 20:56 fisher 閱讀(2333) | 評論 (6)編輯 收藏

    在webwork中使用自定義的Result生成動態驗證圖片

    這個動態圖片的實現原理是在servlet的response中寫入一個ImageOutputStream,并由servlet容器將其轉成圖片,在非webwork的實現中,可以直接操作response,但是在webwork中,要想直接操作response的output則必須使用不需要對response操作的result類型

    實現一個
    Result

     

    不可以用普通的dispatcherResultresponseoutputStream中寫入東西,否則將覆蓋所有的dispatcherjsp頁面

    上次的代碼忘記加上response的設置不緩存了,這樣即使使用IE的回退也會刷新圖片 

        private HttpSession            session;

        
    /**
         * 
    @see com.opensymphony.webwork.dispatcher.WebWorkResultSupport#doExecute(java.lang.String,
         *      com.opensymphony.xwork.ActionInvocation)
         
    */
        @Override
        
    protected void doExecute(String finalLocation, ActionInvocation invocation) throws Exception
        {
            HttpServletRequest request 
    = (HttpServletRequest) invocation.getInvocationContext().get(
                    ServletActionContext.HTTP_REQUEST);
            HttpServletResponse response 
    = (HttpServletResponse) invocation.getInvocationContext().get(
                    ServletActionContext.HTTP_RESPONSE);
            response.setHeader(
    "Pragma""No-cache");
            response.setHeader(
    "Cache-Control""no-cache");
            response.setDateHeader(
    "Expires"0);
            VerifyImage verify 
    = new VerifyImage();
            OutputStream os 
    = response.getOutputStream();
            String str 
    = verify.GetImage(os);
            session 
    = request.getSession(true);
            session.setAttribute(
    "rand", str);
        }


     

    xwork.xml中配置result-type

            <result-types>

                <result-type name="image"

                  class="com.bnt.afp.action.verify.ImageResult"/>

            </result-types>

     

    添加一個生成圖片的action

            <action name="imageAction"

    class="com.bnt.afp.action.verify.ImageAction">

                <result name="success" type="image"/>

            </action>

     

    在需要生成驗證圖片的地方這樣調用:

    <img border=0 src="imageAction.action">


     ImageAction里只要簡單的返回SUCCESS就可以了

        public String execute() throws IOException
        {
            
    return SUCCESS;
        }



    VerifyImage中生成圖片的方法:(來自網上一個JSP生成動態驗證圖片的實例)

           //獲取生成的圖片,返回生成的驗證碼,并將ImageOutputStream寫入

           
    public String GetImage(OutputStream outputStream){

                  

                  
    int width=60, height=20;

                  BufferedImage image 
    = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);

                  Graphics g 
    = image.getGraphics();

                  Random random 
    = new Random();

                  g.setColor(getRandColor(
    200,250));

                  g.fillRect(
    00, width, height);

                  g.setFont(
    new Font("Times New Roman",Font.PLAIN,18));

                  

                  g.setColor(getRandColor(
    160,200));

                  
    for (int i=0;i<155;i++)

                  {

                         
    int x = random.nextInt(width);

                         
    int y = random.nextInt(height);

                         
    int xl = random.nextInt(12);

                         
    int yl = random.nextInt(12);

                         g.drawLine(x,y,x
    +xl,y+yl);

                  }

                  String sRand
    ="";

                  
    for (int i=0;i<4;i++){

                      String rand
    =String.valueOf(random.nextInt(10));

                      sRand
    +=rand;

                      g.setColor(
    new Color(20+random.nextInt(110),20+random.nextInt(110),20+random.nextInt(110)));

    g.drawString(rand,
    13*i+6,16);

                  }

                  g.dispose();

                  
    try {

                         ImageIO.write(image, 
    "JPEG", outputStream);

                         outputStream.flush();

                         
    return sRand;

                  } 
    catch (IOException e) {

                         e.printStackTrace();

                         
    return "fail";

                  }

           }

     

           
    public Color getRandColor(int fc,int bc){

                  Random random 
    = new Random();

            
    if(fc>255) fc=255;

            
    if(bc>255) bc=255;

            
    int r=fc+random.nextInt(bc-fc);

            
    int g=fc+random.nextInt(bc-fc);

            
    int b=fc+random.nextInt(bc-fc);

            
    return new Color(r,g,b);

           }


                                                                                                                                     轉載請注明作者和來源. 

    posted @ 2005-11-15 21:14 fisher 閱讀(1663) | 評論 (2)編輯 收藏

    主站蜘蛛池模板: 亚洲av乱码一区二区三区 | 最近的中文字幕大全免费8| 亚洲精品麻豆av| 亚洲日韩在线中文字幕综合| 在线不卡免费视频| 亚洲AV无码AV吞精久久| 免费欧洲美女牲交视频| 天堂亚洲免费视频| 亚洲色大成网站WWW久久九九| jizz免费观看视频| 亚洲日韩v无码中文字幕| 你懂的免费在线观看网站| 久久亚洲春色中文字幕久久久| 国产一卡二卡四卡免费| 亚洲精品第一综合99久久| 国产三级电影免费观看| 中文字幕在线免费视频| 亚洲第一视频网站| 无码人妻久久一区二区三区免费丨 | 免费国产在线视频| 亚洲第一精品电影网| 成人性生交大片免费看无遮挡| 亚洲AV永久无码天堂影院| 免费jlzzjlzz在线播放视频| 中文在线观看永久免费| 亚洲专区先锋影音| 日韩高清免费在线观看| jizz免费在线影视观看网站| 亚洲精品中文字幕无乱码| 午夜免费福利在线观看| 三年片免费高清版| 亚洲人成图片网站| 亚洲综合区小说区激情区| 91麻豆国产免费观看| 亚洲国产无线乱码在线观看| 亚洲精品乱码久久久久久自慰| 四虎永久在线观看免费网站网址 | 色欲aⅴ亚洲情无码AV蜜桃| 国产午夜亚洲不卡| 久久天天躁狠狠躁夜夜免费观看| 羞羞网站免费观看|