網頁

顯示具有 Java 標籤的文章。 顯示所有文章
顯示具有 Java 標籤的文章。 顯示所有文章

2010年8月11日 星期三

[雜談] 程式設計師之夢 從無到有建構世界的「純粹」

程式設計,最讓我著迷的是那種從無到有的那種「純粹」。我用這目前所擁有的所有知識與經驗,賦予了這個孩子為人所不能的優點,同時也賦予了一些不可為的缺憾,但我卻可以在我靈光乍現的時刻,將缺憾從程式的生命中抽離,這種種「純粹」,是一種程式設計師自身生命的體現。

程式設計的過程,就因為有了這種可全然由人掌控的「純粹」,才能撫慰了人生旅程無常無定的不完美。程式設計如此,文字創作如此,音樂藝術等創作亦是如此。或者我們可以直接這樣說,程式設計即為藝術。

更精確來說,程式設計是一種文字創作的體現,即使大家都擁有著相同的詞彙可以使用,但在不同的語法結構之下,就有著不同的生命。而雖然「重用」是程式設計很重要的課題,但以大多數狀況來看「重用」的理由,卻往往是以「不會寫」為出發點,這就像是申論題可以用各種方面去闡釋自己的回答,但卻提不出自己的主張一般。

2010年5月30日 星期日

[MySQL] Using XML to simulate field changeable data

資料欄位的不確定性一向是資料庫設計時的痛,但也是在評估架構大小時極為有趣的部份。雖然軟體界的先驅,孜孜不倦地要求著我們一定要先做好需求分析,之後再進行架構設計與程式的實作,然而我們永遠都避免不了程式上線後,使用者提出新增或調整輸入內容的需求,而且更糟的是,使用者甚至願意捧著一大筆錢請你實踐這個功能,讓你老闆無法為公司拒絕這樣誘人的條件。

或者試想這樣的情況,你現在正在設計一個API提供使用者上傳資料,雖然第一版API提供了一種型態三個變數用以上傳,但是經過半個月之後,你發現必須要開發第二版API,多新增一個型態含四個變數做處理,而原本的變數,因為前端UI功能增加,必須多增添兩個變數以滿足要求。

一般說來,最直觀的作法,就是將第一版API對應的資料表新增兩個欄位供新功能使用,而過去的所有已輸入資料通通設定為null;而第二版API則另開一個新資料表做儲存,幾乎等於重新開發一個API專屬另一個型態來使用。

但隨著需求的擴增,你的資料表開得越來越多,若開發時只設計一個API入口,那後端程式就必須相對的去維護多個資料庫,又若資料庫程式很先進的使用了O/R Mapping進行實作,那你就會看到堆有著相似性目的,卻只是組成不同的資料庫物件在你的程式裡頭。

為了處理這樣的窘境,我們可以將這類的狀況統整成一個單一資料表,將之間差異的型態以及變數,以XML進行儲存,把ROW×COL的資料表格式,成為不確定COL大小的模式。

建構的資料表範例如下:
-- ----------------------------
--  Table structure for `sample`
-- ----------------------------
CREATE TABLE `sample` (
  `alias` int(10) unsigned NOT NULL auto_increment COMMENT '主鍵',
  `type` varchar(255) NOT NULL default '' COMMENT '資料分類',
  `xml` text NOT NULL COMMENT '動態XML資料',
  PRIMARY KEY  (`alias`)
) ENGINE=MyISAM AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;


-- ----------------------------
--  Records of `sample`
-- ----------------------------
INSERT INTO  VALUES ( '1', 'HT', '<bio><sys>140</sys><dias>100</dias></bio>' ) , ( '2', 'GLU', '<bio><glu>100</glu></bio>' ) , ( '3', 'HT', '<bio><sys>139</sys><dias>85</dias></bio>' ) ;


2009年4月14日 星期二

Strus2 json plugin + jquery.getJSON()

Struts2其中之一的優點,是可以直接擴充別人寫好的plugin,簡化自己動手做的步驟。以下是簡單的範例。

Step 1:
請將基本strtus2環境架設完畢。

Step 2:
下載strus2 json plugin,放置於 %WEBROOT%/WEB-INF/lib/ 中
連結:http://cwiki.apache.org/S2PLUGINS/json-plugin.html
(官網有很詳盡的說明,建議有空看看)

Step 3:
編輯struts.xml,加入以下資訊...
<result-types>
 <result-type name="json" class="com.googlecode.jsonplugin.JSONResult">
 </result-type>
</result-types>

請注意,若你的struts.xml已經新增了其他的result-type,那麼請直接將內的xml加入你的result-types中即可。

step 4:
宣告欲使用json result的action於strtus.xml中..
<action name="JsonAction" class="tw.foo.JsonAction">
 <result name="success" type="json">
  <param name="contentType">text/html</param>
 </result>
</action>

(設定contentType為text/html,可以讓你利用瀏覽器進行debug)

step 5:
撰寫action...
package tw.foo;

import java.util.*;
import com.opensymphony.xwork2.ActionSupport;

public class JsonAction extends ActionSupport{
 private List<map<string,string>> li = null;
 public String execute() throws Exception{
  li = new ArrayList<map<string, string>>();
  Map<string, string> map = new Hashtable<string, string>();
  map.put("name", "Jay");
  map.put("age", "28");
  li.add(map);
  map = new Hashtable<string, string="">();
  map.put("name", "Jolin");
  map.put("age", "27");
  map.put("skill", "dance");
  li.add(map);
  return SUCCESS;
 }

 public List<map<string, string>> getMyList(){
  return li;
 }
}



Step 6:
現在,你可以在瀏覽器打開action測試,會出現如下json資訊...

{"myList":[{"age":"28","name":"Jay"},{"skill":"dance","age":"27","name":"Jolin"}]}


Step 7:
現在開始用jquery對json資訊進行處理,jsp範例如下:
<%@ page language="java" pageEncoding="UTF-8" contentType="text/html; charset=UTF-8"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
 <head>
  <script type="text/javascript" src="js/jquery-1.3.2.js"></script>
  <script type="text/javascript">
  $(document).ready(function(){
    $.getJSON("JsonAction.action", function(json){
    var table = "<table border='1' cellpedding='1'>";
      table+="<thead><tr><th>name</th><th>age</th><th>skill</th></tr></thead>";
      table += "<tbody>";
      for(i = 0; i < json.myList.length; i++){
        table += "<tr>";
        table += "<td>" + json.myList[i].name + "</td>";
        table += "<td>" + json.myList[i].age + "</td>";
        table += "<td>" + json.myList[i].skill + "</td>";
        table += "</tr>";
      }
      table += "</tbody></table>";
      $('#jsonresult').html(table);
    });
  });
  </script>
 </head>
 <body>
   <div id="jsonresult">test</div>
 </body>
</html>



Step 8:
恭喜完成!看看你的頁面是不是如下所示:

nameageskill
Jay28undefined
Jolin27dance

2008年12月15日 星期一

[筆記] Java crypto & How to restore the key object

單純做個筆記...

import javax.crypto.KeyGenerator;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

public class AES {
  public static void main(String[] args) throws Exception{
    KeyGenerator kg = KeyGenerator.getInstance("AES");
    kg.init(128); //初始化
    SecretKey key = kg.generateKey(); //生成key
    //取得encoded key
    byte[] keyRaw = key.getEncoded();

    Cipher cp = Cipher.getInstance("AES");
    // 初始化為加密模式
    cp.init(Cipher.ENCRYPT_MODE, key);
    String str = "天譴寶寶吃肉... ";

    byte [] pText = str.getBytes(); // 可指定文字編碼
    byte [] cText = cp.doFinal(pText); //加密
    // 加密過後的String
    System.out.println(new String(cText));

    // 由encoded key,轉為key Object
    SecretKeySpec keySpec = new SecretKeySpec(keyRaw, "AES");
     // 重新初始化為解密模式
    cp.init(Cipher.DECRYPT_MODE, keySpec);
    pText = cp.doFinal(cText); // 解密
     // 需配合加密端指定文字編碼,沒有就聽天由命
    String str2 = new String(pText);
    System.out.println(str2);
  }
}


參考資料:
1. blog.csdn.net/xjtuse_mal/archive/2007/11/08/1874869.aspx
2. forums.sun.com/thread.jspa?threadID=760082

2007年12月26日 星期三

該選個好的OS還是好的執行環境(xRE)?

又一陣子沒更新了,最近為了Java ME的Optional API搞得焦頭爛額,譬如JSR75、JSR82... 這些還沒完全搞定,今天又多了JSR226。也因為team一個月都在忙這些東西,以及開始要跨過Mobile軟體設計的門檻,弄得其他人看我們似乎沒有什麼生產力。也就是因為如此,才在內部產生了如同標題的爭論。

昨天是挪雞鴨手機開發論壇,一位始終對我們當初選擇Java手機開發抱持懷疑態度的同事跑去參加之後(還抽到手機耶!),回來之後便開始遊說我們,是否該主攻50%市場的Symbian程式開發,而別再走Java這條需要一堆Optional API的路。

他立論的觀點,是著眼於未來我們若需要什麼新的Java API功能,則必須遷就於廠商是否有實做,這樣會導致開發以及手機的選擇性層層受限。我承認,若以目前的時間點而言,手機的可選擇性當然受限於API是否有實作,我也認為,S60的確是一款成熟的手機OS;然而,選擇了S60,真的就可以避免了層層的限制嗎?

首先,先談安全性方面,S60程式與Java程式同樣需要憑證才可使用被限制的API,而目前手機三大廠除了Motorola之外,憑證申請應該都還算方便,快的話幾天就可以下來。至於S60,據同事說,是要靠Nokia來核發,至於程序複雜與否,我沒申請過不敢妄言。

再來,關於程式移植性的問題,Java的移植性就不用談了,雖然Optional API跑在每家手機時多少會有些微妙的差異,頁面呈現的感覺也有些不同,但經過適合該廠KVM微調之後,通常都可以達到理想的效果。(譬如:JSR75各家容許存取的檔案位置有所不同等等... )至於S60,編出來的程式是否能在80或是90上面跑?憑證是否要重新申請?這些都是值得質疑的。

最後,就是API功能的問題。JavaME至今仍在不斷的進步,各家廠商也不斷地將Optional API實做上去,雖然有人說手機廠商會因為差別定價將部份Optional API功能拿掉,如果向S60投誠就沒有這種問題。但差別定價的問題我想原因其實不在於KVM,而是在於手機本身就缺乏了相關的硬體規格,那麼更遑論將功能實做上去了。因此我認為將API拿掉這種走回頭路的模式,應該不再考量的問題當中。至於S60會不會出現新機種卻不提供私人開發程式控制的狀況呢?他人的立論基礎是不會,我也相信由於開發環境夠低階,這狀況應會比較少,但仍然是無法保證。

基於上面這些的理由,我實在是找不到限定S60手機用較低階語言開發(C/C++)開發優勢在哪裡?選擇Java開發,等待手機市場各大廠KVM更成熟,支援所需功能的手機更多樣化,對一個預計一年後才會進入市場的產品而言,似乎是個較佳的選擇,我是這樣期盼的。

而至於為什麼不考慮Windows Mobile系統,那又是另一個故事了...

2007年12月21日 星期五

為什麼要用Java開發緊急通報系統?

這幾年來,其他人對於開發遠距醫療的伺服器系統端的眾多問題之一,就是「為什麼要用Java開發」?

算算自己碰過的網頁程式語言,如了Java外,大概還有ASP NET、PHP以及CGI吧!CGI寫作曠日廢時,先忽略不談,最後僅剩下ASP.NET、大家都愛用的PHP,以及受到信賴的Java。

在大學時期,同學們都喜歡玩PHP,因為C是資工學生的基本技能,所以用起PHP得心應手,看起來似乎是個不錯的選擇。然而,當微軟將.NET Framework推至一般人的眼前,蔡大帶槍投靠C#,Java社群也隨著有東西比較而日漸壯大,而我也在當初不甚成熟的.NET Framwork 1.0環境體會到微軟的「用心」,玩了一陣子的dotText之後,陣營便開始在C#與Java之間搖晃。 (心酸地看著書架上的原版Visual Studio 2003紙盒)

而最後為何要用Java建置呢?以我的觀點,簡單來說,要建置一個簡單的資料同步、資料轉換、資料轉送,以及擁有足夠恢復能力的遠距醫療緊急通報系統,概念那些都不是問題,對於醫療,問題應該是來自於要如何能夠完全掌控並調整這些細微的步驟、同步機制與傳輸效能的瓶頸。
.NET因受限於平台與封閉程式庫,對於這點稍嫌不足。而PHP對於系統的負擔,會造成無法滿足穩定處理後端穩定的需要。因此再三考量之下,採用了企業與銀行一般來說偏好採用的Java系統。憑藉著Java VM的穩定性、例外處理以及記憶體回收機制,在測試期間拯救了我無數次程式失誤所造成的在其他伺服器環境下,可能會導致系統完全失敗的情況。

完成之後,一年多過去,問題大多發生在居家端機器的品質以及內部缺乏整體規劃的程式,自己所設計的後端系統,在病患發出緊急通報之後,約在●●●(消音)內可讓被通報者在移動環境中收到訊息,更進一步的評估,若捨棄目前依賴●●●(消音)機制,改由自行設計的●●●(消音),時間應可進一步壓縮至●●●(消音)秒內。

目前最希望加強的,則是能夠將靈活運用目前多核心伺服器的效能,如果能克服這點,希望能再進一步改進目前不同邏輯欲同時處理時的時程。

而如今隨著自己主動要求獨立於公司之外,我終於可以從這一年來的束縛中喘息,繼續實現這一年來中斷的理想;至於學業,反而就是隨緣了。

2007年12月20日 星期四

備Java的課真累人

一陣子沒更新了,這兩週每天的工作就是寫範例與做投影片不斷的迴圈,弄得我幾乎只要聽到「投影片」三個字就會想翻桌!

由於老闆接下來兩年的計畫要大量用到J2ME以及J2EE的技術,而目前的人才要不是不會Java,不然就是無法屈就在學校的計畫底下。於是趁著新舊計畫銜接的空檔,安排了Java基礎概念的課程來替計畫打底。說起來也巧,恰好所上有老師需要他的學生短期間能讀懂Java Code,甚至想送學生去補習班上課,在得知了開課的消息之後,也欣然地把學生往這堂課送,加上老闆的學生以及聞風而來其他實驗室學生,第一堂課竟然也能來個十幾人。

我會強調第一堂課,隱含的意思就是之後來上的學生只剩下2/3。想想看,一門早上8:00~12:00,連著四小時,中間休息15分鐘的課程,我自己要教課都有些受不了,何況是學生,而且還是放寒假中的學生,其中還有1/3是被老闆逼來的呢!不過裡面還有頗老實的學生在,因故不能來還會乖乖向我請假,並詢問能不能請同學錄影。雖然個人對錄影的效果有所存疑,但看人家這麼有心,自然也就隨他了。

雖然人數變少了,但還好,剩下的學生對於課程的反應還算不錯,投影片的程式碼,也真的回去重新打過並編譯執行。因此雖然課程進度飛快,我企圖用16個小時上完所有基礎課程,但藉由課堂上即時問答與解惑,他們也仍能跟得上。至於其他因故未能參加的學生們,我也在第一堂課公佈了網路教室,讓他們雖然無法出席,也能藉由上課的投影片有粗淺的了解。

老實說,教程式語言真是一件麻煩的任務。首先必須為了學習目標定下參考的書目,以及適合教學的書目。一般學校都採用D&D的螞蟻書,但老實說,用螞蟻書並無法讓學生了解物件的意含以及Java初學者容易犯下的錯誤,更重要的,是時間只有16小時,必須用有效率的方式推著學生學習。於是我向學生推薦購買Java 2 徹底研究 (Java: The Complete Reference, J2SE, 5/e) 這本書當作課本,但實際教學卻參考SCJP Sun Certified Programmer for Java 5 Study Guide ,目的是希望課堂上帶著他們講解概念以及讀code,他們回家之後,可以拿課本當作工具書,搭配著學習,彌補課堂上範例不足的缺範。

選完了書,再來就是投影片了。很不幸,這兩本書都不是教學用書,沒有投影片。就算有,也不適合拿來上16小時的短期課程。於是只好自己動手做,把一些書中的重點或表格整理之後放進投影片,而每個段落自己則得寫個小程式說明用法以及明確表現出學生可能會發生錯誤的地方以增進學生印象。於是做投影片的過程就不斷地重複寫code、編譯、執行、剪下、貼上、加入動畫這些讓人會發狂的動作。四個小時的課程,我得花上兩個工作天的時間才能弄完投影片。

還好,課程後天就結束了,投影片只剩下內部類別以及執行緒還沒弄,聽說上課都是第一天以及最後一天人最多,說不定週五捧場的人會多一些。(苦笑)

2007年5月7日 星期一

MotoE6 JavaME hack

由於那個用騾拖的 Moto 好不容易給了申請憑證的回音,結果卻只是想更進一步了解我們計畫的內容,跟他們對頭N社的朋友討論無論是 Moto Signed 或是 Symbian Signed 審核過程這麼冗長的原因?朋友開玩笑地回答:「怕手機爆掉啊!」所以,不想在進一步解釋計畫內容的我們,終於在上週三宣告不再等待Moto的開發環境(其實也沒有等)。

星期四晚上,嚷著想去看蜘蛛人的我,因為找不到伴抵擋同事的閃光而回家乖乖寫程式。好死不死的,不知道之前什麼時候,我把資料夾管理的「顯示所有資料夾」選項打開。所以在想把程式 Porting 到 E6 的當刻,看到了一個名為 .System 的隱藏資料夾,而裡頭有個叫做  java 的資料夾。

再繼續往下搜尋,裡頭還有個名為 DownloadApps 的資料夾,裡頭有著三個名為 MIDletXXXXX 的資料夾,而E6裡頭也恰好額外裝了三隻 Java 程式,所以想單然爾,這些資料夾應該就是 MIDlet 的安裝位置。

進入了 MIDletXXXXX,裡頭有兩個資料夾以及一個檔案,分別是Files、rms兩個資料夾以及registry.txt這個檔案。Files 裡頭就是我們所安裝的MIDlet檔案,rms自然就是rms(好像是廢話)。而重點就是這隻registry.txt檔案。

部份內容如下:

Suite-Icon:
DRM-Mode: Forbidden
Is-Trusted: 0
Jar-URL:
Description:
Domain: Untrusted
Signer-Name:
Mot-JavaVM-Heapsize: 17
Delete-Notify:
Num-MIDlets: 6


我先將看起來似乎相關的 Is-Trusted: 0 試著由 0 改為 1 ,結果無效。

接著又基於之前開發印象中「MOTOROKR E6 Developer Guide」的一份表格表格,想起了 trust domain 分別有Trusted 3rd Party、untrusted、Manufacturer以及Operator,於是我又將 Domain: Untrusted 更改為 Domain: Manufacturer。

結果神奇的事情發生了!!

長按MIDlet圖示,由跳出的選單進入「管理 -> 許可」之後發現,權限竟然全都變成了「不要詢問」,啟動Apple的Data-IO程式之後,原本的權限錯誤也的確都消失了!所以現在只差找到正確的記憶卡路徑位置,我們就可以在E6這隻強力的手機上面跑我們目前開發完成的程式了!!

看到畫面的一瞬間超感動!當我們不去指望Motorola官方的支援,上天反而偷偷地指引了一扇更寬廣的大門,這就是神恩啊!

2006年9月15日 星期五

由AJAX設計導入來談資料庫資料分頁實作

程式碼說明版請連至 [Java技術論壇]

談到分頁這個問題,其實算是個討論到爛的設計,目前說法大抵可分「一次讀完」,與「建立索引」 這兩派。

一次讀完再慢慢地分,簡單來說就是一口氣將資料庫的屬於該邏輯的所有資料讀到記憶體中,再依使用者所要求的區間來呈現資料表內容。這方法的好處是可以降低平均整體查詢資料庫的時間,也就是降低與資料庫之間存取的頻率。而缺點就是必須提供大量的記憶體來儲存整個資料表內容,而且不能即時反應資料庫的變化。

建立索引的方式則是取得資料庫的資料表內含的索引,再讓使用者依照分頁索引來查詢出資料庫內的資料表該區間的資料。這方法的好處是僅需在記憶體內提供一些位置給使用者做資料表更新與索引表物件,缺點就是對資料庫的存取頻率較高,連結資料庫的動作所消耗的時間較多。

當然,有些額外的手段可以使資料庫查詢的動作簡化,就好比說是Connection Pool,這幾乎可以讓建立連結的時間忽略不計,而只需考慮到資料庫本身處理SQL語法的速度。但仍有些部分是無解(也不能這麼說,因為阿扁言:能用金錢解決的問題就不是問題。),那就是記憶體的使用量。

正因為金錢的來源是大問題,所以實際上要設計分頁還是要回歸使用者的使用習慣和查詢功能。若使用者的查詢習慣是只看前幾筆最新的內容,則一次讀完的方式顯然太浪費記憶體。又若使用者的習慣是將所有每筆資料逐筆查詢做運算,則建立索引的方式就顯得無用武之地。

既然使用者的習慣捉摸不定,那麼設計者就應要在介面上來隱性導引使用者習慣。好比說頁面僅呈現該區間資料的簡略屬性,若需要詳細資料,可再繼續按下按鈕調出詳細的屬性。而要調閱及時反應的最新資料,僅需使用者按下了分頁的第一頁,整批索引便立即更新,即可調閱最新一批資料。這些都是目前各開源的討論區作法的一部份。

而如今,有賴於AJAX的流行,我們更可以將所有資料作更分散式的取得,讓使用者有者近似於「一次讀完」的速度,又可以達到「建立索引」的記憶體節約。



上圖的分頁內容為使用「建立索引」的方式來呈現,搭配了Connection Pool之後,分頁的速度也頗為迅速。由於此服務的使用者習慣為檢閱最新資料以及指定時間區間的資料,因此在資料呈現上提供了最新十筆資料,並在右下角要求使用者一頁頁往前翻查,再不然也可以使用日期輸入器指定日期區間來做查詢。



接著,若按下了事件旁的按鈕,則會啟動AJAX function,將指定的單筆資料撈回做處理。由於不用換頁,因此此分頁的內容無須在重新reload,也無須重新查詢一次整個頁面的事件數。 即使系統忙碌,使用者也可藉由讀取中的小icon來得知目前正在等待事件事件內容資料,而不像目前一般討論區在閱讀文章遇到系統忙碌時,使用者只能看著瀏覽器底下的進度欄緩慢地前進,頁面空白一片,不知所謂。



當然,若要更狠一些,還可以將整個頁面都以JavaScript配合XMLHttpRequest來呈現出來,但我想那已經已經算是「純」Web 2.0 網站(Beta都應該還不算是吧!)的範圍了吧。

註: 「純」web 2.0,我想每個人心中都有一把尺,我認為像是Google ig、start.com、以及Windows Live Mail beta 的純度應該比Yahoo奇摩那些大得多

2006年8月31日 星期四

SCWCD 考試心得

今天是個特殊的日子,8/31,八月的最後一天,明天就是九月,有薪水可以領,但重點不是這個。

話說我在前天book了今天下午兩點的考試時間。那時我就覺得奇怪,怎麼Ti8今天晚上的時間都沒得登記!起初我還以為是恆●他們上課的學員卯起來要今天考試,腦子頓了一會兒才驚覺真正的原因,為什麼一堆人擠著今天來考試。

這故事說來話長,我長話短說,就從一年前的JavaTwo2005說起吧!我想大家應該都知道這個年度盛會,除了最重要的課程研討會與國外專家的精彩演講之外,一樓擺攤要資料的廠商們,到處穿梭的Java美眉們,甚至那些每年擺著不一樣POSE的Duke娃娃都是JAVA大會不可缺少的要素。

是的!故事的起源就是在攤位。

所有攤位都有個目的,那就是收集個人資料。但是有一區比較特殊,他們不是要資料,而是要錢!簡單來說,這個攤位就是賣便宜的準考證。而我,去年一口氣買了兩張…(我其實頗討厭我這種貪小便宜的歐巴桑心態!)

【迷之音】:討厭你還買! <( ‵︿′)╭C<─___-)|||

偏偏參加完活動之後,我就開始忙計畫的事(有一半時間在花在跟PM爭執架構可行度,唉~),所以參加考試這回事就被我擱到腦後去了。當我再有時間準備考試,已經是六月了,於是趁著計劃空檔,我考了SCJP,緊接著又開始忙著實驗室搬遷,以及計畫受測者的問題。但我手裡還有一張准考證要消化啊!〒△〒

眼看著準考證期限將屆…

很好,岔題岔回來了,准考證的期限就是8/31號。在趕著學AJAX並應用到新網頁的時間壓力之下,原本以為到期時間是8/16號而來不及的我,頓時鬆了一口氣,於是當下決定在准考證到期最後一天才去拼拼看。

所以,大家可以知道,台灣資訊界是多麼地忙碌,一堆人忙到已經花了錢報名,卻沒有時間去考試,還真是頗慘的。所以今天考試中心就像是大拜拜一樣,考試人潮絡繹不絕;我關在那個考試小房間裡頭,總不時會聽到外頭小姐講解考試規則的聲音。大家想的都一樣,畢竟一張准考證要價4000大洋,無論能否Pass,至少要考一下才不浪費。

不過,還好,我幸運地Pass了!所以現在才有膽寫這篇心得! ╮(﹀_﹀")╭

好! 以上是廢話,接下來才是考試心得。

先說一下我平常網頁設計的習慣,我是MVC的愛用者,雖然想進化到Front Controller,Struts的書我也買了兩本做參考,在實作做了幾個簡單的頁面後,就沒時間再深入了。眼看著那個Spring似乎開始熱了起來,真擔心這兩本書我可能會看不完。

學歷上面,大學背景是電機轉資工(其實跟考試沒啥關係,純給各位做參考);正式拿Java來賺錢是從去年年初開始。至於其他技術,什麼都碰一些,但什麼都不強,我恨死了JavaScript,恨死了CSS,恨死了調web版面,恨死了用Photoshop設計圖片!!為什麼這麼恨?因為要用到啊!

由於我MVC弄得頗「徹底」,JSP的各種技巧都只有碰了一些些,每個JSP頁面多是單純的VIEW,所以考試單元成績出來,一開始的項目都拿到8X%,但到了tag那些部分就開始慘不忍睹。能過真的是老天爺眷顧我!考試內容整體來看,參考書中幾乎都提到了考試重點,如果自己曾經實作過裡面的技術,考起來是算是頗得心應手的。

說到參考書,我其實只有一本圖畫書。就是「Head First Servlet & JSP」,第一次翻它是為了學習Servlet & JSP的技術(頗好用,我也要要求實驗室小朋友買了一本當課本),好不容易在昨天看完了第二遍。記得第一次看這本書,可說是霧裡看花,但如今自己有了足夠的設計經驗之後,第二次再看,閱讀的感覺可說是完全不同。(雖然有些還是很模糊)

直到今天早上,我才把每章後面的模擬試題以及附錄的「終極模擬試題」第一次看了一遍。(嗯..嗯..對,是看過,因為時間不夠,所以直接看解答與註解。)別看輕了模擬試題,它的好處,可不是讓你填鴨式的死記,而是利用簡單的例題,讓你快速釐清觀念可能模糊的所在,並依此加強自己較弱部份。所以在當你準備好要出發考試前,快速瀏覽一下模擬試題會是不錯的暖身操。

最後,就是生活準備啦!我考試態度是屬於大考大玩,小考小玩那種,昨天不好好看書,還很無腦的弄了一大篇「好人&壞人」的Java灌水文。考前保持心情的愉快是很重要的。而飲食上,考試當天盡量吃清淡些,要進入考場前,請讓自己保持要餓不餓的狀態,只要你沒有血糖不耐症,那麼考試的兩個多小時內,你的頭腦將會保持在最清醒的狀態。(如果你有感冒或慢性疾病須服藥,也請估個時間暫時停一下,考完再服用。)

總之,只要腳踏實地動手做,遇到問題第一個先懷疑自己是否缺乏什麼必須的能力,然後去克服它,基於玩Java的都是好人的理由!相信什麼認證都難不倒各位的!!

PS1. 你,就是你!別再問我人是不是只分好人或壞人了!<(‵︿′)@m
PS2. 基本上,每個人學習曲線各有不同,不過我大學副修教育學程,還當過補習班教師,真心希望這裡提供的準備考試技巧,能給各位一些幫助。

2006年8月30日 星期三

人的特色只有好人與坏人嗎?

有位仁兄在Java版的回應中問了我這樣一個問題,這問題是多麼富有哲學性,但既然在Java板出現了,就一定要認真地用Java的方式來回答。

話說,人類是萬物之靈,所以人類也是物件的一種。然而要具體形容一個人,除了外觀,當然還有道德、職業、學經歷、聲望這些因素等等…這些要素,在還沒有能夠具體形容這
些要素前,我們能做的,就是暫時將人類塑造為一個簡陋的抽象類別。

package universe.earth;

public abstract class Human {
protected boolean isNormal;
protected boolean isGoodGuy;
protected String sex;
protected double weight;
protected double height;
protected double BMI;
public Human(){}
public abstract boolean IsNormal(boolean eyebrow);
public abstract boolean IsGoodGuy(String skill);
public abstract void setBMI(double weight, double height); }

基本上,人類又可分為帶把與沒帶把的!所以我們接下來就要實做男人類別(帶把的),這個類別繼承自Human這個抽象類別。

package universe.earth;

public class Male extends Human{

// Of course, this a male class
public Male(){
sex = "male";
this.isNormal = true;
this.isGoodGuy = false; // 人心險惡,先認為不是好人吧!
}

// Is his look normal?
public boolean IsNormal(boolean eyebrow){
if(eyebrow){
this.isNormal = true;
}else{
this.isNormal = false;
}
return isNormal;
}

// Is he a good guy?
public boolean IsGoodGuy(String skill){
if(skill == null || skill.equalsIgnoreCase("java")){
this.isGoodGuy = true;
}else{
this.isGoodGuy = false; // Are you a C# user?;
}
return isGoodGuy;
}

// Check his body is strong, weak, or normal.
public void setBMI(double weight, double height){
this.weight = weight;
this.height = height;
BMI = 10000*weight/Math.pow(height, 2);
}

// overridden toString()
public String toString(){
String description = "He is a " + sex +".\n";
if(isNormal && isGoodGuy && BMI >0){
description += "Good! You should make friend with him.";
}else if(!isNormal && isGoodGuy && BMI >0){
description += "He might be a good friend, but don't laught at his eyebow.";
}else if(!isNormal && !isGoodGuy && BMI >0){
description += "Please, he's just with no eyebrow!";
}else if(BMI <> 0){
description += "You might win at this fight!";
}else if(BMI > 24.9){
description += "Run! Frost! Run!";
}else {
description += "It's a even fight!";
}
return description+"\n";
}
}

好!我們做到這,我們已經可以基於一個人有沒有眉毛、專長、以及BMI決定這個人好不好相處。為了簡單測試,所以我們開始將這個male類別實例化。

package universe.earth;

public class JudgeHuman {
public final static void main(String[] args){
Male thisGuy = new Male();
// 路上兩人相見,不熟悉!
System.out.println("You haven't analyze who he is...");
System.out.println(thisGuy.toString());
// 然後你推測他的身高體重,算出他的BMI...
thisGuy.setBMI(100,183);
System.out.println("After you know his BMI...");
System.out.println(thisGuy.toString());
// 然後你又看了一下他的臉,發現他沒有眉毛!
thisGuy.IsNormal(false);
System.out.println("After you analyze his face...");
System.out.println(thisGuy.toString());
// 最後他告訴你,他原來是個java程式設計師!
thisGuy.IsGoodGuy("java");
System.out.println("After you know his skills...");
System.out.println(thisGuy.toString());
}
}

將這個Java application執行後的結果如下:

You haven't analyze who he is...
He is a male.
It's a even fight!

After you know his BMI...
He is a male.
Run! Frost! Run!

After you analyze his face...
He is a male.
Please, he's just with no eyebrow!

After you know his skills...
He is a male.
He might be a good friend, but don't laught at his eyebow.


所以,最後要回答的結論就是…「人的特色當然不是只有好人或壞人囉!」

2006年6月12日 星期一

放棄吧!日子還很長!

今天在網路上被一個小朋友挖起來問問題。原來他是看到我曾在Java版上有PO過文,才來找我問問題。我一向歡迎小朋友來問我問題,只要他是有心學程式,一切都好辦。

他很直接,把習題拿出來問,我也不以為意,因為如何建立一個class這是個基本的問題,但沒有好好解釋,也算是卡住的關鍵,於是我就一邊跟他解釋物件的概念,一邊寫Code實做給他看。

習題有三小題,講完了第一小題的物件建立,第二小題就是關於物件繼承。原本想讓他自己做做看,但在他表示還是不太了解的狀況下,又寫了一次給他看。

接著,他陸陸續續丟出了幾份作業題目過來,分別是物件宣告、IO、以及在JSP中使用Database。

這讓我很驚訝得下巴掉了下來,這儼然是回顧整學期的作業啊!接著更讓我驚訝的,是他們老師給他的期限是晚間11點要寄出code,而他的觀念竟然弱成這樣。但基於同情心,還是指點他每題實做的方向,但我明白,除了我給他的那兩個class之外,他大概準備接受事實了。

就在我處於震驚中時,他又對我說,這些程式沒交出去,他會很難過,希望我能幫他完成一部份。此時我腦中丟出了一個想法:「你是指心情難過?還是這科會很難過?」不過無論如何,基於我一貫的立場,對於作業乞丐一向唾棄的立場,我拒絕了。接著藉著洗澡先暫離,而回來後,他也下線了。

之前跟中學生相處久了,所以處事來說,我這個人一向好說話,一開始不會太嚴格對人。尤其是對有熱忱的人。就算是裝得很有熱忱也罷,我都願意協助他進步。但我更相信,可憐之人必有可恨之處,在弄成無可挽回的情況前,一定有做了些什麼動作讓所有事情演變成這樣。換言之,種了什麼因,自然就會得什麼果。只要被我知道了有不單純的動機,那我也不會讓學習的過程草草的結束。

如今這位小朋友的因就是他誤選了他系的程式語言課程,而又認不清自己的能力,把程式作業留到最後一天才急忙找槍手代筆,所以才造成了他作業交不出來的苦果。

而對他最好的方式,很簡單,就是重修。既然他在這門課上沒有什麼斬獲,那怎可就這樣不好好再學一次呢?除非,他想放棄,既然要放棄,那就更不用去思考這門課的學分拿不拿得到了,不是嗎?

所以,放棄吧!小朋友,日子還很長,下回多花點心力讀書吧!

也許哪天會有人說,那我拿錢給你幫我寫,可以嗎?

也許吧!也許哪天我會遇上,但是,一般人能有免費的好人可以找,誰會要去找收錢的?這也算是一種程式工作者的悲哀吧。

總之,我只是想說,我不是好人。