如果你熟悉動態語言,你大概會嘗試使用 Java 的反射(reflection)來重構程式碼。我個人提供一個重構經驗,告訴你使用 Java 的反射時,你可能會感到失望。
這是一段透過 Hibernate 進行的資料更新動作。我從使用者端取得要更新的資料項,接著先向 Hibernate 查詢要更新的資料項目是否存在,存在的話再把新的資料內容更新進去。
...繼續閱讀如果你熟悉動態語言,你大概會嘗試使用 Java 的反射(reflection)來重構程式碼。我個人提供一個重構經驗,告訴你使用 Java 的反射時,你可能會感到失望。
這是一段透過 Hibernate 進行的資料更新動作。我從使用者端取得要更新的資料項,接著先向 Hibernate 查詢要更新的資料項目是否存在,存在的話再把新的資料內容更新進去。
...繼續閱讀公司這個月開始一件專案,我分配到用 Java 開發 web service 那一塊。 於是我親身體驗到一本書說的故事。
找一個很聰明,但是沒有 Java 經驗的開發者,讓他去學學 Java web 企業應用的那一堆技術,然後再問問他的想法。問題是兩方面的,首先,它很難;再者,失敗的後果很悲慘。
對我來說,或許這意味者程式碼應該在較高等級的抽象中,而我們無法在 Java 中做到這一點。
《超越 Java》(Beyond Java),Bruce Tate,O'Reilly出版
我不算聰明的開發者,但十幾年基本功練下來,功底還算紥實。OOP, ORM, Design pattern 這些概念都懂。Web 架構更是熟悉。儘管如此,當我試圖使用 Spring, Hibernate 等框架時,我完全無法理解為什麼 Java 語言可以把一件簡單的事搞成這麼複雜。這件事促成我寫出《不同程式語言的中介編程與反射能力系列文章》。
...繼續閱讀我來說個關於函數指標(在 C 語言中,function 就是一個 function pointer)與函數個體(function object)的小故事。這個故事還有一個 Java 版的,在本文的最後一節。只對 Java 語言有興趣的,可以先看後面的 Java 版,再回頭看前面。
有一天,"偉大的"架構設計師交代甲和乙兩位程序員共同負責撰寫一個小程式。這個程式配置了兩個陣列,一個是傳統的整數陣列,一個是整數vector。這個程式要將這兩個陣列的內容傾印出來。
在 libmapi 中,主要的封包結構是 mapi_object_t。使用 mapi_object_init() 建構內容。
主要的函數回傳值是 enum MAPISTATUS,並以 MAPI_E_SUCCESS 表示成功執行。
通常在呼叫 libmapi API 後使用 if (retval != MAPI_E_SUCCESS) return false; 判斷程式流程。
就設計架構而言, libmapi 運作時會管理記憶體資源。使用 MAPIFreeBuffer(), mapi_object_release() 便可釋放閒置的記憶體空間。
但就我實測結果顯示,它目前存有 memory lack 問題。以擷取連絡人清單為例,在擁有 256MB 實際記憶體與 384MB Swap 空間的 GNU/Linux 系統上,
大約在擷取200筆訊息後,就會因為記憶體不足而被系統中止程序。
openchangeclient -p rock --fetch-items=contact
這是目前使用 libmapi 開發大型客戶軟體時必須注意之處。其他Bug可以參考 Openchange開發工具補遺。
...繼續閱讀日前有一項工作,需要從 Microsoft Exchange Server 中轉出行事曆、連絡人等等資料。我嘗試使用 Openchage 這套工具來處理。它透過 Exchange 預設的 SMB 封包協定交換資訊。應用軟體開發人員可使用其 libmapi 函數庫設計一般用戶程式。
OpenChange aims to provide a portable Open Source implementation of Microsoft Exchange Server and Exchange protocols.
Openchange
不過 Openchange 仍未臻成熟,在使用前必須修正不少地方。本文說明 header 檔路徑修正、常數定義修正與中日韓語系修正的內容。
...繼續閱讀bbslib::pool 是一個簡單的記憶體配置功能 (源碼: bbslib-20010331.tar.gz/strexp/pool.c)。乍看之下,像是一個動態長度字串,但實際上,卻是簡單的動態記憶體管理模組。bbslib::pool 當初在設計時,是有多種考量的,例如安全性。當它要複製或銜接一個字串時,如果原先的空間不足,就會自動重配置夠大的空間去儲存,如此可避免 buffer ovewflow 的問題。而在使用效率上, bbslib::pool 是用 page 為單位向系統要求配置記憶體空間。
...繼續閱讀簡單地說, MD5 是一種單向雜湊(hashing)演算法,可將你所給予的任何長度字串,藉由 MD5 雜湊演算得出一個長度為 128 位元 (術語稱之為 "digest code")的計算結果。後述以鍵值稱呼 digest code。MD5 演算法,是由 RSA Data Security, Inc 公司所提出的。演算原理參閱 MD5 - Wikipedia。
...繼續閱讀我以前維護學校的 Firebird BBS 系統時,寫了一套 library ,其中字串處理部份包含了 Regex library 的使用函數。源碼可於此下載: bbslib2 sources tarball。接下來的 Regex library 說明內容,都取自其中的源碼,不另行列出。
Regex 於其他程式語言中之應用現狀,可見《Regular Expression (RegExp) in JavaScript》、《PHP Manual:Regular Expression Functions (POSIX Extended)》等。
...繼續閱讀最近在練習使用 C++ STL 中的 Container 功能。嗯,寫著寫著,覺得很不順手啊。例如不能用 Vector/Set/Map 直接建表。Stack 的 pop() 方法沒有回傳值;我用 C 寫的 stack 功能, pop() 是會推一個值出來的。
挑了兩個 STL Container 的練習程式碼,再用 Ruby 寫一段相同的。兩相比較,也算在吐槽吧。
...繼續閱讀
前一陣子,為了說明《程式語言中的介面》,我把大約八、九年前寫的 C 語言程式碼翻了出來。編譯的時候出現錯誤訊息,顯示我用了不被允許的轉型動作,即 (void*)。雖然心裡嘀咕了一下,不過還是很快地改成完整的轉型語法 (也更冗長),將之用於文章範例。
這幾天抽空檢視了一下那些舊程式碼,才發現不是程式碼的問題,而是我用錯編譯器了。我的編輯器 PSPad 設定 C/C++ 文件呼叫的編譯器是 g++ (C++ compiler) ,而不是 gcc (C compiler)。而 C++ 不允許將 void* 轉型為其他型態指標。這點與 C 不同。我又測了一下舊有程式碼的 C/C++ 規範相容性。