出差出差!

wang0zc5

生平第一次出差,目的地是台南成大,南國的母校啊,真是令人懷念!雖然科技新貴已經是上個世紀的事了,但很多還是會把資訊系跟有錢畫上等號,殊不知成大資工系其實是個年輕到了不行的科系,沒有畢業校友的金錢挹注,換來的是古色古香的系館,儘管對這棟系館發出讚嘆的永遠外系的人多過在裡頭唸過的人…

有種圍城的感覺:裡頭的人拼了命想外跑,外頭的人擠破頭想進來!好像選公司也是一樣的,永遠是還沒去過的公司最好!想起了跟 D.N.A 學弟講的話。

Keiko:人家都學歷顯赫,個個都留美學歷!
D.N.A:可是你留台啊!開口粥,留台多年,菁英份子!

哈哈,或許人就是這樣,對未知的東西不是充滿恐懼就是抱有美好幻想!忘了是哪位實驗室學長說過的話,還是我說得呢?

外國人絕對不會比較厲害,狗屁倒灶的事絕對比我們多又扯,只是我們只看到好的一面!

現在想想,我真應該在「工商服務時間」把這點提出來講一下!這就是所謂:門的另一端,真實的世界。突然想起上個禮拜請假到台南玩,星期一去了七股鹽田,在鹽山之前看到一對情侶朝我走來,男生是背對著我,手裡拿著相機,鏡頭當然對著心愛的女友,天空藍藍的,海風不強,輕輕拂過女孩的長髮,三千髮絲搖曳著,雖然只看到男生的背影,不過已經可以想像他是多麼小心翼翼想會這針對的一刻留下永恆的紀念,他一定小心翼翼地想捕捉女生最美的瞬間,傳說中甜蜜的青春也不過如此吧!

可是呢?這當然是我的幻想啊,從來沒有女生讓我這樣拍過,我也沒有有錢到請 model 來讓我幻想一下,更何況我手中只有 Sony W7 這種傻到不行的相機!那現實可能是怎樣呢?

  1. 可能是男孩倒退著走,然後一個重心不穩,跌個狗吃屎。
  2. 也可能男生其實跟我一樣,得了一種「相機帕金森式症」,這是一種拿到相機才會發作,症狀是手晃不止的病。結果就是把女朋友拍得很醜,晚上回到飯店可能遭到一頓痛毆。

image

天啊,我話好多,讓我想起這幾天看的獵人漫畫 280 話的拿酷戮,短短擦身而過,原來我也想了這麼多字!

its_Cold

出差很累,比上班還累,早上六點半就起床,因為家住台北知名的塞車之地,天空下著小雨,冷到我都想偷我弟的羽戎衣來穿!為什麼公司發的宣傳衣是短袖,為什麼我明明是興高采烈的想去說明會,卻是這樣的天氣歡迎我,知道嗎?這就回到剛剛講的:門的另一端,真實的世界…

儘管如此,這世間還是有不變的美好!要我舉例來說嗎?

  1. 嗯嗯,那就像我印象中的台南永遠都是有陽光的,高鐵只要一過曾文溪就會看到太陽。
  2. 李強老師永遠不記得我的名字,卻永遠記得我這個學生,記得我修過他什麼課、幹過什麼壞事,這次到是不忘跟我要名片!
  3. 黃宗立老師跟我打招呼的速度一定比我跟他打招呼快!
  4. 黃崇明老師一直記得我在蘇小鈺手下打雜!
  5. 每次要找朱治平老師,他永遠不在辦公室!!
  6. 永遠以為楊中平老師跟我一樣菜 -_-||
  7. 老師的女兒德恩不管看過我們幾次,每次的印象卻都像是要砍掉重練,從零開始、再出發!
  8. 老師辦公室的唱片還是很多,不時還會有陣陣木頭香!
  9. showmin, 文森, D.N.A 永遠很捧場,buffett 一定要坐在角落,aaa 一定要遲到。
  10. 冠廷一定要提早會消失(哪怕我們有革命情感),bbb 一定要耍龜毛!
  11. 老師一定會問我:我的 P2P player 呢?我的黑膠呢?
  12. 最後,在回台北的高鐵上,計畫著下次什麼時候再來?(這樣會不會被發現我是敗家子,都坐高鐵來回 -_-)

回到正題,出差是為了宣傳騰雲駕霧程式競賽,雖然來的人不多,不過也讓我體驗到什麼是一字之差的 mindset:

Royce:會來的就是會來!
Keiko:該來的就是會來!

不過還是有感動的事,遇到三個電通所的學弟,雖然不知道他們是從哪看來的網宣,可能是系學會幫的忙,不過從他們堅定的眼神看得出來他們會參加!

最後,也是最重要的一點,說明會前遇到了系主任,在他大力支持下, 4/17 (五)下午 2:00 開始的 seminar 我們又可以再去一次了!天啊,意義非凡,因為星期五下去,表示可以星期 X 才回台北!

Domain-Specific Language (DSL)

前言

過去幾年蠻熱門的話題(?),原本還想來學院派式的追本溯源一下,不過凡事起頭難,手邊資料不多,很多論文又不能下載,就作罷了,當閒聊了,又不是要寫論文 XD

我想是因為自己很晚才接觸資訊這個領域,加上上個世紀,網路、社群並非如此盛行,總有種錯覺:這幾年許多新語言的出現不再宣稱自己能解決所有的問題、可以被應用在所有領域,而是將焦點專注於特定問題、領域(domain)的,當然,這不是個新概念,但 Domain-specific language 卻是這幾年才流行起來的。

Generative Programming

Generative Programming 一書是這麼描述 DSL 的:

A domain-specific language (DSL) is a specialized, problem-oriented language. …(略) ... Domain-specific languages can be textural (e.g. SQL) or graphical (e.g. the graphical specification of a GUI in a GUI builder).

哈,基本上這是個很寬鬆的描述,會被 reviewer 打槍的那種,不過不難想像到 DSL 概念的成品已經充斥著我們生活周遭,像是:

  1. lex & yacc:大學 compiler 課用會到!
  2. SQL
  3. 曾經 SLIM 想用的 XUL ,到後來自己設計的 component script
  4. SMP 的 SREAM script
  5. ChucK (那有沒有 SCREAM 呢!)
  6. 微軟 .Net 新一代的 GUI 平台用到的 XAML(很多 open source GUI framework 也有類似的概念)
  7. UML 中的 OCL

這幾年 VM 這種結合 compiler, interpreter 特性的平台語言很是盛行,透過重複利用 VM 的中間碼可以讓原本設計一個 programming langauge 需要的繁雜後端工作得到部份減輕。所以許多研究、實驗性質的 DSL 會考慮建構在 VM 之上。舉例來說,就有許多語言建構在 JVM 之上,參考這邊

優點

那到底 DSL 的好處是什麼呢?wikiDomain-Specific Language: An Annotated Bibliography 做了很好的條列和解釋,不過我還是想再說一遍:( -_-||唉,我想我個性不太好)

  1. Expressive:我想這是最重要一點,人類的思考會受到語言、符號、圖像的限制。因此 DSL 在描述問題、解決問題時都會比 general purpose language (暫用 GPL 代表)更能貼近核心。最顯而易見的例子就是 GUI 的設計,用 WYSIWYG 的方式刻繪介面會比純文字好、BNF  form 比一堆 if, else, loop 湊出來的 FSM 更能表達語言結構、SQL 語法比用 procedural 清晰。此外,好的表達力可以讓維護程式碼時,一目了然,不需太多註解、文件相輔,一行 DSL 程式碼表達的運算可能需要數行 GPL 才能完成,這種精簡效果是很可觀的!
  2. 語法支持:這個部份我最想挑出來說的是 domain-specific error report/checking 和 constraint enforcement。好的語言不僅給予程式設計師自由的空間去發會,還要能適時給予程式設計師提醒與限制。 enforcement 是我進公司後才體驗到的一個 term ,這裡或許反映出一個個人喜好,我不喜歡把錯誤推遲到執行時期發現。不同的應用中常會帶來不同的限制或者說是規範,最糟糕的情況是無法透過 GPL 既有元素去表達的,或是僅能在執行時期偵測、或是以間接、隱晦的方式去表現。
  3. 其他,如可以做到更好的最佳化、程式碼內嵌 domain knowledge、易於測試等。(哈,我用其他來帶過,其實就代表我個人認為前兩項是最重要的好處)

為了避免空口說白話,這邊以 C++ 實做一個矩陣為例子來說明 GPL 可能做不好的地方:

class MyMatrix {
public:
    MyMatrix();
    MyMatrix( int row, int col );

    int operator ()( int row, int col );
    vector<int>& operator []( int row );
    template <typename T>
    MyMatrix& operator =( const T& );

private:
    int     row_;
    int     col_;
    vector< vector<int> >   data_;
};

使用時很簡單,就像下面一樣,精練、不失矩陣的意含(我想是這樣沒錯):

    MyMatrix m1( 10, 10 );

第一步看起來不錯,但是很明顯的當我們想初始化矩陣時,無論我們怎麼努力,卻很難只靠 C++ 本身(先不討論 Preprocessor)做到像下面的效果:

    MyMatrix m2 = { { 0, 0 }, { 0, 0 } };

最多我們只能靠著 operator overloading 做到:

    for ( int i = 0; i < 10; ++i ) {
        for ( int j = 0; j < 10; ++j ) {
            m1[ i ][ j ] = i + j;
        }
    }

或是提供 MyMatrixRow, MyMatrixCol 之類的 Proxy class 去一次設定多個元素;但無論如何,當元素間沒有規則時,一個一個指定矩陣元素的步驟就跑不了,此時若是有個 Matrix 相關的 DSL 輔助,我們可以寫出更精練、具可讀性的程式。下一個我們會面臨的問題可能發生在矩陣運算上,以加法為例,兩個相加的矩陣必須具有同樣的維度,但這個限制(或說規範)在 MyMatrix 是無法直接表達的(請先不要考慮到 C++ template,首先是因為這不是每個語言都有的 feature,其次是之後會有個段論詳細解釋這部份),所以我們可能得在

MyMatrix operator +( const MyMatrix& lhs, const MyMatrix& rhs );

的實做時,去檢查矩陣的維度,當兩者不符合時丟出一個 excption。當然不是說 exception 不好,而是若是能越早發現錯誤會更好,尤其是這種維度的指定與推導是可以靜態完成的,實在沒有必要留待動態時期去偵測。此時若是有個 Matrix 相關的 DSL 可以在撰寫時給予這方面的限制,可以省去不少麻煩、也能提高程式效能。

缺點

說完 DSL 的優點,聽起來是如此好用,讓我也一度著迷,想做些 DSL 出來用,不過現實世界當然不會如此美好!DSL 最大的問題在於:

  1. 草創期
    實做一個 DSL 需要許多人力投入在設計、實做上,先期的 domain/problem 分析、研究更是花費人工。這階段最惱人的應該是穩定度吧?!
  2. 初期
    當語言實做完成後,下一個面臨的問題就是配套與使用者心理。即使語言再簡單,都還是有自己的中心哲學,對於使用者來說:他們是不是快速的學習、語言的 Learning curve 是不是適當呢?甚至使用者可能排斥再學一個新語言?接著實際開發時,是不是相關的 tool chain 都能搭配上,是不是能有好用的 editor、IDE 來輔助開發、吸引開發者目光。而其中最為麻煩的,我想是錯誤資訊(像是 compiler error、failed to code gen …)與 debug 的環境,該如何讓使用者快速 trouble shooting 是很重要的。即使今天我們提供的 DSL 只是做 transformation,把 MyMatrix DSL 轉成 C++ 而已,錯誤資訊的轉換是恨重要的,有用過 lex/yacc 的人可以回憶一下,在寫錯 lex/yacc 的程式時,lex/yacc 的 codegen 程式有時不會知道,它們只能根據預先的條件去轉換成 C 語言,當送給 C compiler 時才會 compile errors,此時使用者該如何從這樣的錯誤對應回 lex/yacc 的錯誤呢?當然最好的方式是,使用者不必以 codegen 後的角度去找尋錯誤,而是直接面對他們寫的 DSL 程式去找錯(像是 lex, yacc 程式碼、MyMatrix),同樣地,debug 也是面臨同樣問題,lex/yacc 雖然在code generation 時會把對應的行號、檔名寫到產生出來的 .c 檔中,但用 C debugger 回頭看到的卻是 FSM 和 LALR 的程式,個人認為使用者是很容易迷路的!
  3. 中期
    維護,像是文件、社群資源等都是需要長時間投入的。
  4. 長期
    想必該是面對改版相容性問題時候了!

DSL 的形式

從 DSL 的實做方式以及它怎麼跟其他語言合作,我們可以大致上分成下面幾種,並且從設計、實做與使用上來討論一下:

  1. Fixed, separate DSLs
    這是最常見的一種形式,DSL 擁有自行一套的 tool chain 甚至執行環境,例如 SQL 。這種形式的 DSL 最大的問題是很難跟其他語言進行良好的整合,可能是語言特性(static vs. dynamic)、執行方式(compiler vs. interpreter)、執行環境的差異、tool chain 等因素造成。即使是可以透過一定的手法把 separate DSLs 轉為 embedded DSLs,但仍不是很方便。而 DSL 實做上呢?從頭到尾打造一個 DSL 是很曠日費時,而且成本極高的一件事,更不要談說相關的開發環境。簡單的說, DSL 和他要合作的語言間太鬆綁了(loose coupling),loose coupling 有時不是件好事。
  2. Embedded DSLs
    另一種方式是我們可以在 GPL 中定義相關的類別、函式去包裝 DSL ,讓開發過程中,DSL 與 GPL 是緊緊地包在一起的,這聽起來比 separate DSLs 好,但是根據實做出的合作方式,卻可能比 separate DSLs 好不到哪裡去,舉個例子來說,很多 database 都會有不同語言的 interface library 供開發者使用,PostgreSQL 有一個 C++ 介面的函式,叫做 libpgxx ,它與 PostgreSQL 連接的方式是:
    int playWithDb() {
        connection Conn( "dbname=test" );
        {
            work Xaction( Conn, "DemoTransaction" );
            result r = Xaction.exec( "DELETE FROM " + Table + " WHERE ID=" + ID );
    
            for ( result::size_type i = 0; i != R.size(); ++i ) {
                Process(R[i]["lastname"]);
            }
        }
    }
    或是看個 C++ 與 TCL 的整合:
    void hello()
    {
         cout << "Hello C++/Tcl!" << endl;
    }
    
    int main()
    {
         interpreter i;
         i.def("hello", hello);
    
         string script = "for {set i 0} {$i != 4} {incr i} { hello }";
    
         i.eval(script);
    }
    不難發現這種倚賴參數、字串來執行 DSL 的方式讓我們失去了機會去做一些事情:
    1. express domain-specific optimization
    2. domain-specific error report:  syntax error 和 debug 是我認為尤其重要的,像是 compile time 的 error/constraint enforcement !
    3. domain-specific syntax
    不過幸運的是,有另外一種方式可以讓我們從 GPL 中衍生 DSL ,那就是 metaprogramming ,雖然不是每種語言都有這種特性,也不是擁有這種特性後就能一切完美。以 C++ 來說,我們可以透過 template metaprogramming 做到 code generation 和 code optimization ,甚至透過 C++ 型別去做部份的 error report/checking。但大部分時候仍是補強而已,很多 domain-specific 的事還是得推延到 run time。這邊想示範一個簡單的 C++ metaprogramming 利用型別實做 constraint enforcement 的概念,那就再次請出 Matrix 來當例子,這次我想針對維度做出 constraint enforcement ,那我們可以把原本的實做改成像下面這樣:
    template <int RowT, int ColT>
    class MyMatrix {
    public:
        friend MyMatrix operator +( const MyMatrix& lhs, const MyMatrix& rhs );
    
        MyMatrix();
    
        int operator ()( int row, int col );
        vector<int>& operator []( int row );
        template <typename T>
        MyMatrix& operator =( const T& );
    
        static const int RowDimension = RowT;
        static const int ColDimension = ColT;
    
    private:
        vector< vector<int> >   data_;
    };
    注意到沒有,我們把維度的概念帶入型別之中,那麼下面的程式碼, 
     
        MyMatrix<10, 10> m1;
        MyMatrix<2, 2>   m2;
    
        cout << m1 + m2 << endl;
    便可以在 compile time 丟出錯誤,下面是 VC 2005 的錯誤訊息:

    error C2679: binary '+' : no operator found which takes a right-hand operand of type 'MyMatrix' (or there is no acceptable conversion)

    但是細心的你注意到了嗎?即使我們把錯誤拉前了,但這樣的錯誤訊息並不是跟矩陣有太大關係,如果能丟出

    incompatible dimensions

    是不是更好呢?在 GPL 中,我們有時是很難做到完整的 domain-specific error report/checking 的 。再者,並不是每種 constraint 都適合以型別的方式表達,一來可能造成 template parameter 數量爆增,這可能增加 compile 時間,二來也暴露太多細節在 client code 中,這會讓程式碼難以擴充維護。
    雖然用了 C++ template 當例子,不過值得提一下, template haskell 似乎也很有趣,許多 functional language 都可以一些語言擴充!
  3. Modularly composable DSLs
    腦子很小的我,只想出前面兩種,這第三種形式是 Generative Programming 一書提出的,它強調的是在語言的基礎建設(infrastructure)完善皆備的情況下,去開發語言的 plug-in ,說來神奇,其實不會, C/C++ 的 preprocessor 或是更古老的 Smalltalk 和 CLOS 都是這種概念的雛型。只是它們未能在 domain-specific 的需求上達到更好的精細度。或許看到這裡,你會有跟我一樣的一個疑問:那 Modularly composable DSLs 與 Embedded DSLs 有什麼不同呢?聽起來都是建構在既有語言之上,其實這中間有個隱微的差異,可以細細體驗一下:

    Embedded DSLs 的根基是現有語言的 syntax,而 Modularly composable DSLs 則是做 syntax extensions。

    這句話代表的是,Embedded DSLs 的使用是類似於使用 GPL 的 library 或是 framework 的,其 syntax/semantic 跟原本 GPL 是一樣的。但 Modularly composable DSLs 是構造在 GPL infrastructure 之上,除了既有的 syntax/semantic 外,我們還可以增加 domain-specific 的 syntax/semantic ,甚至是刪去、捨棄既有的。若是想更細部條列兩者的差異,或許可以參考 Generative Programming 所條列的,Modularly composable DSLs 可以比 Embedded DSLs 做到:
    1. Syntax extensions
    2. Semantic extensions or modifications of language constructs
    3. Domain-specific optimizations
    4. Domain-specific type systems
    5. Domain-specific error checking and reporting
    再回到 language infrastructure 上, 我們有什麼辦法可以操作 language infrastructure 呢?有幾種可能性:
    1. Preprocessor
    2. Metaprogramming
    3. Modularly Extendible Compilers and Modularly Extendible Programming Environments
    前兩者在許多語言上已經可以做到,正如前面提到的 C/C++, Smalltalk, Haskell 和 CLOS 都行,只是做的不夠好。因為這不只是語言本身支援的問題,還牽扯到 tool chain 與環境。至於第三種,則可以參考 Charles Simonyi (是的,就是微軟的那位大師,匈牙利命名法、WYSIWYG document 發明者、 Word 之父)的研究 – Intentional Programming 。大師在 Microsoft Research 以及後來開設的 Intentional Software 公司都可以找到這方面的發表與研究成果,研究開始得很早,約莫在上個世紀的 90 年代初,未來有時間,希望能玩玩看再來跟大家分享一下!

結語

這篇文章真是超長,內容又很空洞,可是我打了兩天,大概是我在低潮吧…不過還是想跟大家分享一下幾點:

  1. Compiler is your friend!
  2. Constraint enforcement is your friend!
  3. Compile-time error report/checking is your friend!
  4. The last but most important point, C++ is your friend!

歐萊禮書籍特價,三本以上 75 折

image

學弟的版看到了,趕快來廣告一下,雖然都是中文書,不過掛著 O’Reilly 至少不會太差唷,是不是要開團了!

http://www.books.com.tw/exep/activity/activity.php?id=0000017976&sid=0000017976&page=291

目前看上了:

  1. 深入淺出物件導向分析與設計
  2. Linux 核心詳解
  3. Linux 驅動程式(這有電子版

聽說還不錯的:

  1. 讓事情發生--專案管理之美學,第二版
  2. 軟體預先架構之美學
  3. 程式設計師提升生產力秘笈
  4. 操作介面設計模式

推薦的:

  1. UML 2.0學習手冊
    不知道有沒有特別有名,沒有特別針對哪種軟體工程方法論做介紹,單純講 UML diagrams ,感覺很清爽易讀!
  2. 深入淺出-設計模式
    很經典的書,不過看久了覺得很囉唆,唉,我真是難伺候!
  3. 深入資料庫之美學
    有點深,害我都放在書架上!

入門的、可當工具書的:

  1. 建構嵌入式Linux系統
  2. Python 學習手冊
  3. 精通CVS
  4. 防駭超級工具
  5. 防駭戰士
  6. GNU Make 專案開發工具

觀望中:

  1. 美麗程式:頂尖程式設計師的思考方式
    在成大圖書部翻過,覺得都是淺嘗則止的帶過一些東西。
  2. Linux 系統程式設計
    看了目錄,感覺有更好的選擇!
  3. 輕快的好 Java
    在成大圖書部翻過,不過內容已經忘了,沒有什麼印象,但好像有提過一些觀念 -_-||
  4. Java I/O 技術
    有點舊!
  5. 超越Java:探討程式語言的未來
    蠻有趣的書,不過論點似乎有點 ooxx ,是本可以戰起來的書!

考慮去書店翻翻的或是有人要借我翻閱嗎?

  1. Java 效能調校技巧
  2. Java Data Object 深度探討
  3. Java 虛擬機器
  4. Java Threads

在 blog 上貼 YouTube

網友 Alvin 最近詢問怎麼在 blog 上嵌入 YouTube 一類的元件,所以就來跟大家介紹一下,順便騙騙文章數,掩飾一下自己江郎才盡了…

步驟一

YouTube 之類的服務都有提供物件語法給大家複製到自己的網頁上,參考下圖可以看到網頁有一區標示著嵌入

ScreenHunter_01 Mar. 18 21.28

步驟二

滑鼠移過去,還會發現有自訂的功能。使用者可以根據自己的需求調整,調整後,就是把 <object> …開頭的語法複製起來。image

步驟三

開啟自己 blog 文章編輯的 html 模式,以 WLW 為例,就是切換到程式碼模式。 接著就勇敢的貼上吧!

ScreenHunter_04 Mar. 18 21.55

成果

最後,就可以看到成果了!

其他

其他像是 mp3, quicktime 等格式的多媒體資料,基本上只要 host 有提供 object 來嵌入,都可以在網頁上產生美美的元件。

結語

ㄜ,感覺教學最後就要來個結語,那就: Yes, We Can!

長尾效應(The Long Tail)

為了為裝成統計達人,上上一篇文章用了長尾效應,不過馬上就被 Royce 大戳破,解釋得零零落落,還好 Wesley 馬上挺身救愛徒6TRYWO4km 12DJLfVSRV2OcUpK4=

不過還是來解釋一下什麼是長尾效應,我想最常聽到的例子就是 Amazon 吧?!有人研究了 Amazon 賣的書和銷售排名關係後,發現銷售排名低的書即使不熱門但為數眾多,累積起來的銷售額還大於熱門書籍!

或是更簡單、更流行的說法就是:

BeatTen

舉個例子來說:

Keiko 只有 Royce 萬分之一的戰鬥力!可是我有千千萬萬個 Keiko ,然後 Keikos 就打贏了 Royce…

不是小兵立大功,是小兵們立大功!所以注意到沒,Keiko 要用複數型!

接著就開始很多人用這個詞了,像我這種常上網的阿宅,每天在一堆的 Web 2.0 應用或是趨勢研究中都會看到它,有時候看到的次數比我當天寫出來的 bug 還多…


唉,不過我是那種很難相處又反社會的人,這種詞看多了就會有股莫名的火燒上心頭!然後我就開始幻想一種對話:

猩仙人:前輩,為什麼你都這麼早開始對程式最佳化?
偽前輩 Keiko:你不知道嗎?80-20 落伍了,長尾正夯!在 80% 的 code 做最佳化搞不好會比你在 20% 的程式做最佳化來的有用唷!
猩仙人:又學到一招了,前輩,我好崇拜你唷!(筆記、筆記)
Royce:<囧>
mobo:Keiko 毀人不倦!

心存歹念,會有報應!

今天幫友 team 的客戶跑 beta 程式,馬上就遇到一個問題,我不是那種很會找 bug 的人,事實上也還在等對方驗證是不是 bug ,可我腦海中就想到一句話:

當你看到一隻蟑螂,表示還有一百隻;
當你看到一隻bug,表示…

然後,回家報應就來了…

DSC05499


有 dump 耶,我應該看嗎?

螢幕解析度統計

最近換了新版型,發現文章區的版面大小竟然跟油價一樣是浮動的,讓我在小黑的 1024 x 768 螢幕上看到很多圖都被截掉了,這就表示很多看我 blog 的人(其實沒有很多人看,科科…)都會有同樣的狀況,原本還想發個文問問大家的意見,沒想到 google analytics 竟然幫我統計好了!

ScreenHunter_02 Mar. 03 23.26

然後又很無聊的看了一下,原來我的 blog :

  • “CreateProcess” 最熱門啊!那李組長眉頭一皺,揪竟,地球一天會產生多少 process 呢?
  • “我要變胖”用 google 去 search 排名還是 8,看來 google 不太準唷 –_-||
  • “黑暗之路”,這真是什麼鬼,我的文章好像沒出現過這段字,難道是黑暗騎士被斷詞找到了?

image

科科,接下來就是拜 ubuntu 和 mysql 兩套 open source 之賜了,對了,還要感謝 Alvin 老師讓我管實驗室主機、mobo 決定用 ubuntu + mysql!果然痛過就是要留下痕跡,這樣人家才不會再痛一次 >_<

image 

最後感謝各位的流量貢獻,我的 blog 流量四分之一來自你們的網站!(從我退伍開始 10/13 ~)

image

天啊,小路學長後勢看漲唷!(最近一個月)

image


Kane 哥,加油,好嗎?

Windows Debugging – Kernel Debugging with WinDbg and VMWare

看到 Royce 大師開始把 Nt Insider 的精華實用文章分享給大家,讓向來只有三分鐘熱度的我,也想硬著頭皮寫點東西,不過我是初學者,就從最最入門的、簡單的開始寫起吧,啊啊,希望不要變成富奸

前言

mini_wininternals

Windows Internals 這本書是許多人進入 Windows 的第一本完整教科書,目前出到第四版,不過我一直懷疑大師 Mark E. Russinovich & David A. Solomon 被富奸上身,因為第五版已經推延了好幾次,目前看來會在 2009/05/20 上市,這次希望是真的。

Windows Internals 第一章介紹了許多工具包來幫助我們瞭解 Windows Kernel ,其中 Debugging Tools for Windows 中的 WinDbg 尤其重要。透過它,我們可以去逐行執行、trace 、反組譯 Windows Kernel。

Debug Windows Kernel 可以是 live (debug 自己)或是 remote (需要兩台 Windows),不過還是 remote debugging 提供了比較多的功能和彈性,傳統上,remote debugging 需要兩台電腦透過

  1. null-modem cable: 也就是 serial port ,一般電腦的 COM port。
  2. 1394
  3. USB 2.0

啊,不管怎麼看兩台電腦總是很麻煩,不過幸好現在有 VMware 可以用了。把 VMware 上跑的 guest OS 當作 debugging target,在上面開啟它的 debugging port ,而提供 VMware 的 host os 則執行 WinDbg 。

VMware 設定

  1. 安裝完後,開啟 guest OS 的設定。 
    ScreenHunter_02 Mar. 01 12.24
  2. 新增一個 Serial Port 的硬體裝置。 
    ScreenHunter_03 Mar. 01 12.26  ScreenHunter_04 Mar. 01 12.27
  3. 使用 Named Pipe 去模擬 Serial Port 裝置。
     ScreenHunter_05 Mar. 01 12.29
  4. 替這個 Pipe 命名,這個名字稍後會被 WinDbg 用來作為連線的名稱。
     ScreenHunter_06 Mar. 01 12.31

  5. 最後別忘了把 Yield CPU on Poll 選項勾起。
     ScreenHunter_07 Mar. 01 12.33

Windows Boot 設定

設定完 VMware 後,接著要設定 debugging target 也就是 guest OS 的開機選項。也就是 boot.ini 檔。修改前請先備份一下!boot.ini 是系統的隱藏檔,要看到它,要到資料夾選項中把下面兩個選項關掉:

  1. 隱藏保護的作業系統檔案
  2. 顯示所有檔案和資料夾

路大師補充:boot.ini 有可能是唯讀檔,若遇到不能修改的情況,請記得把唯讀的屬性拿掉!

ScreenHunter_08 Mar. 01 12.39

看到 boot.ini 後,在 operating systems 的選項多加一個:

multi(0)disk(0)rdisk(0)partition(1)\WINDOWS="Microsoft Windows XP Professional - Debug" /fastdetect /debugport=com1 /baudrate=115200

要注意的是:

  1. debugport 的名字要跟你在設定 VMware Serial Port 時給的名字一樣才行。
  2. baudrate 可以任意調整成你想要的速度。

ScreenHunter_10 Mar. 01 12.45

重開機讓 boot.ini 生效。這時會發現開機多了一個選項(如下圖),這就表示成功了。

image 

使用

最後,在使用 WinDbg 時,可以在 cmd 下這個指令:

windbg -b -k com:pipe,port=\\.\pipe\com_1,resets=0

這樣 WinDbg 就會嘗試連透過 com_1 這個 debugport 去連上 debugging target 。成功的話,應該會看到像下面的圖:

image

 

參考資料

  1. Debugging Tools for Windows
  2. Driver Debugging with WinDbg and VMWare

更新

  1. 2009/03/01 13:02 原文
  2. 2009/03/01 22:28 加上小路學長補充的 boot.ini 檔唯讀的設定。

Keep hacking, and enjoy it!

在 blog 貼程式碼使用 Syntaxhighlighter + PreCode

前言

在上一篇教學後,我們已經可以使用 Syntaxhighlighter 來幫我們排版、美化程式碼了,不過很快地我們就發現單靠 <pre> 去排版還是會遇到問題,當初我覺得可以靠 WLW plugin 解決,沒想到馬上就找到了一個不錯的與 Syntaxhighlighter 整合的 plugin ,不過可惜的是,目前它支援的語法是 Syntaxhighlighter 1.5 的,不過好在有一些間接的 solution 。

這個 plugin 叫做 PreCode ,有趣的是官網稱 PreCode 是 Code Snippet With Syntaxhighlighter Support for Windows Live Writer,而 PreCode 這名字只出現在 binary 中,啊,題外話。

安裝 PreCode

PreCode 的官方網站, 在這裡可以找到安裝檔,安裝很方便,安裝完後可以看到 WLW 視窗右方的工具列多出了一個 PreCode 的選項:

ScreenHunter_02 Mar. 01 00.54 使用 PreCode

PreCode 的使用相當直覺,點下 PreCode 後,就會跳出一個對話方塊:

ScreenHunter_06 Mar. 01 00.58 對話方塊已經有 Content 區塊可以貼上程式碼,Format 則建議選擇 pre,Syntax Highlighting 的地方就根據需求設定吧!

跟 Syntaxhighlighter 2.0 共存

第一種方式是手動修改 HTML code ,如果把 PreCode 的產生的 HTML code 打開來看,你會看到:

<pre class="cpp" name="code">#include &lt;iostream&gt;
using namespace std;

int main()
{
    cout &lt;&lt; "Hello World\n";
    return 0;
}</pre>

pre tag 的 class 的地方使用的是舊的 Syntaxhighlighter 語法,所以手動改成 “brush: cpp” 是一種方式。

第二種方式是開啟 Syntaxhighlighter 的向下相容性,這個方法得修改 blog 的 template 檔,跟上一個教學一樣,只是得多加一行來啟動向下相容!

<script type="text/javascript">
    SyntaxHighlighter.config.clipboardSwf = 'http://alexgorbatchev.com/pub/sh/2.0.287/scripts/clipboard.swf';
    SyntaxHighlighter.all();
    dp.SyntaxHighlighter.HighlightAll('code'); // Add this!!!
</script>

參考

在 blog 貼程式碼使用 Syntaxhighlighter

在 blog 貼程式碼使用 Syntaxhighlighter

前言

謠言都說 Web App 的時代來了,可是在 blog 上貼個好看的程式碼片段還是不太容易,以我自己的理解,一來是排版問題、 二來是語言有些符號和 HTML tag 相衝突,例如:C/C++ 的 < > 同時也用在 HTML tag 上,所以當我們寫下:

#include <iostream>

往往會導致 editor 把 iostream 當作HTML tag ,而導致發佈文章後,只看到:

#include

這是因為對於不認識的 tag ,解讀時是可以略過的,所以有些 editor 會在發佈時就清掉這些 tag。此外,為了美觀、可讀性,若是還能讓程式碼貼出後自動支援 syntax highlight 那就更好了!所以這邊就來介紹一個不錯顯示程式碼的好工具—— SyntaxHighlighter。

簡介

Syntaxhighlighter 是好心人 Alex Gorbatchev 利用 JavaScript 搭配 CSS、Flash 開發出來,使用上並不需要 blog host 在 server 端提供支援。不過需要另外的網路空間來存放 *.js, *.swf, *.css, *.png 檔,以前大家流行放在 Google Page 這個免費空間上,不過這個服務去年八月就被 Google 收了,看似能取代 Google Page 的 Google Site 並不讓使用者上傳 js 檔。不過 Alex Gorbatchev 大概是好人作到底吧,他還提供了免費 host 的服務,至於頻寬問題怎樣,我就沒有細究了!

Syntaxhighlighter 支援的語言很多,有十六種:

  1. Bash/shell
  2. C#
  3. C/C++
  4. CSS
  5. Delphi
  6. Diff
  7. Groovy
  8. JavaScript
  9. Java
  10. PHP
  11. Plain Test
  12. Python
  13. Ruby
  14. SQL
  15. VB
  16. XML

而且支援六種顏色模式,可以點這裡看到預覽:

  1. Default:白色為主。
  2. Django
  3. Emacs
  4. FadeToGrey
  5. Midnight
  6. RDark

另外,值得注意的是,沈寂了兩年,Syntaxhighlighter 才在今年二月初出了 2.0 版,不過與它相關的 plugin 似乎都還沒跟上腳步,所以想安裝 1.5 的人同樣可以參考這篇文章,方法是一樣的。

正文

  1. Syntaxhighlighter 可以在它 Google Code Syntaxhighlighter Project 或是 Alex Gorbatchev 的網站上找到。不過 2.0 目前只能在 Alex Gorbatchev 的網站下載到。(目前 2.0.287 是最新版)
  2. 下載完,解壓縮可以看到幾個檔案和資料夾:
    ScreenHunter_01 Feb. 28 23.44
    1. scripts 資料夾下放著支援的程式語言相關的 JavaScript code。另外有個 clipboard.swf ,是 flash 元件,用來顯示程式碼、支援列印、複製等友善功能。
    2. styles:css 檔。
    3. src:不會用到。
    4. test.html :Syntaxhighlighter  範例。
  3. 請找個網頁空間,上傳 Scripts、Styles裡頭的檔案。Scripts 裡頭的語言種類不一定要全放,選擇想要用的就可以了。找不到網路空間,可以去用 Syntaxhighlighter  作者自己提供的。
  4. 修改 blog 的 template ,這步驟會根據你的 blogger host 而異。以 blogger 為例,請先登入再去範本 -> 修改 HTML,將下列程式片段貼到 </body> </html> 前。為免意外,請先備份原始 template 的程式唷。
    <SCRIPT src="http://alexgorbatchev.com/pub/sh/2.0.287/scripts/shCore.js" type="text/javascript"></SCRIPT>
    <SCRIPT src="http://alexgorbatchev.com/pub/sh/2.0.287/scripts/shLegacy.js" type="text/javascript"></SCRIPT>
    <SCRIPT src="http://alexgorbatchev.com/pub/sh/2.0.287/scripts/shBrushBash.js" type="text/javascript"></SCRIPT>
    <SCRIPT src="http://alexgorbatchev.com/pub/sh/2.0.287/scripts/shBrushCpp.js" type="text/javascript"></SCRIPT>
    <SCRIPT src="http://alexgorbatchev.com/pub/sh/2.0.287/shBrushCSharp.js" type="text/javascript"></SCRIPT>
    <SCRIPT src="http://alexgorbatchev.com/pub/sh/2.0.287/scripts/shBrushCss.js" type="text/javascript"></SCRIPT>
    <SCRIPT src="http://alexgorbatchev.com/pub/sh/2.0.287/scripts/shBrushDelphi.js" type="text/javascript"></SCRIPT>
    <SCRIPT src="http://alexgorbatchev.com/pub/sh/2.0.287/scripts/shBrushDiff.js" type="text/javascript"></SCRIPT>
    <SCRIPT src="http://alexgorbatchev.com/pub/sh/2.0.287/scripts/shBrushGroovy.js" type="text/javascript"></SCRIPT>
    <SCRIPT src="http://alexgorbatchev.com/pub/sh/2.0.287/scripts/shBrushJava.js" type="text/javascript"></SCRIPT>
    <SCRIPT src="http://alexgorbatchev.com/pub/sh/2.0.287/scripts/shBrushJScript.js" type="text/javascript"></SCRIPT>
    <SCRIPT src="http://alexgorbatchev.com/pub/sh/2.0.287/scripts/shBrushPhp.js" type="text/javascript"></SCRIPT>
    <SCRIPT src="http://alexgorbatchev.com/pub/sh/2.0.287/scripts/shBrushPlain.js" type="text/javascript"></SCRIPT>
    <SCRIPT src="http://alexgorbatchev.com/pub/sh/2.0.287/scripts/shBrushPython.js" type="text/javascript"></SCRIPT>
    <SCRIPT src="http://alexgorbatchev.com/pub/sh/2.0.287/scripts/shBrushRuby.js" type="text/javascript"></SCRIPT>
    <SCRIPT src="http://alexgorbatchev.com/pub/sh/2.0.287/scripts/shBrushScala.js" type="text/javascript"></SCRIPT>
    <SCRIPT src="http://alexgorbatchev.com/pub/sh/2.0.287/scripts/shBrushSql.js" type="text/javascript"></SCRIPT>
    <SCRIPT src="http://alexgorbatchev.com/pub/sh/2.0.287/scripts/shBrushVb.js" type="text/javascript"></SCRIPT>
    <SCRIPT src="http://alexgorbatchev.com/pub/sh/2.0.287/scripts/shBrushXml.js" type="text/javascript"></SCRIPT>
    <LINK href="http://alexgorbatchev.com/pub/sh/2.0.287/styles/shCore.css" type="text/css" rel="stylesheet" />
    <LINK href="http://alexgorbatchev.com/pub/sh/2.0.287/styles/shThemeDefault.css" type="text/css" rel="styleshee" />
    <SCRIPT type=text/javascript>
        SyntaxHighlighter.config.clipboardSwf = 'http://alexgorbatchev.com/pub/sh/2.0.287/scripts/clipboard.swf';
        SyntaxHighlighter.all();
    </SCRIPT>
  5. 之後當你要貼上程式碼時,只要切換到 HTML 模式,然後用<pre></pre>框起程式碼的方式就可以了!
    <pre class="brush: your_language">
    你的程式碼
    </pre>
  6. 最後是一個跟 WLW 有關的提醒,當我們切換到 WLW 的模式時,我們輸入的 <, >, & 等符號都不會自動轉換為對應的 &lt;, &gt;, &amp ,因此對於像是 C/C++ 這類語言來說,使用 SyntaxHighlighter 還是無法完全解決貼程式碼的問題,我想這點就必須倚賴 plug-in 來幫忙了! 可參考在 blog 貼程式碼使用 Syntaxhighlighter + PreCode 這篇文章!

參考文章

在 blog 貼程式碼使用 Syntaxhighlighter + PreCode

Windows + Visual Studio + VSCode + CMake 的疑難雜症

Environment Windows 10 Visual Studio 2019 CMake 3.27.7 VSCode VSCode CMake Tools 1. CMAKE_BUILD_TYPE 是空的 參考一下 這篇 的處理。 大致上因為 Visual...