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

2009年4月11日

感動ㄋㄟ,Google App Engine 支援 Java 啦

appengine_lowres.jpg千呼萬喚始出來,Google App Engine 終於支援 Java 啦~

自從用了 Google App Engine 寫了笨搜網後,就再也沒動力改版或寫新服務了,Python 對我來說簡直是蝌蚪文,不會念也不會寫,現在想想真懷疑當初是怎麼東貼西剪拼湊出來的。想用 Google App Engine 上一堆好用的功能卻卡在最基本的語言不通,硬幹又覺得來綁手綁腳,真兩難。

但在 2009.04.07 後,一切都變得不一樣,Google App Engine 聽得懂我說的話了,開始支援 Java,在我的生活中 Google App Engine 開始從黑白變成彩色的 (太扯)。Java 就像我的母語一樣,寫起來不用大腦,一切都是那麼的自然,Google App Engine 支援 Java 對於我這種只會 Java 的人真是一大福音 (只會 Java 不會 Python 的人應該不多了)。

抱著滿懷希望的心情去下載回來試試,一切的一切都令人超級滿意,大神一出手便知功力高低,Google App Engine 跟 Eclipse 整合的非常好,透過 Eclipse 開發整個過程簡直可以說無痛升級,簡單的點選下一步就可以弄出一個基本的測試網站,扣掉下載的時間,十分鐘不到就完成。

以下以 Eclipse 3.4.2 (Ganymede) Eclipse IDE for Java EE Developers Packages 作範例,首先進到 Help → Software Updates… → Available Software 底下 Add Site…,填入

http://dl.google.com/eclipse/plugin/3.4

2009-04-11_004112.gif

接著找到 Google Plugin for Eclipse 3.4、Google App Engine Java SDK 1.2.0、Google Web Toolkit SDK 1.6.4,勾選後按 Install… 開始下載需要的檔案,這時可以泡個麵、轉開電視,等他下載完重開。
2009-04-11_004156.gif

重開後工具列上多了三個按鈕,分別是 New Web Application Project、GWT Compile Project、 Deploy App Engine Project。
2009-04-11_020736.gif

按下 New Web Application Project 填入 Project name、Package,Finish 後一個最基本的 Project 就完成了,而且還支援 Google Web Tookit 喔。
2009-04-11_020852.gif
2009-04-11_022451.gif

點選 GWT Compile Project 出現 Compile 畫面
2009-04-11_021716.gif
2009-04-11_021809.gif

點選 Deploy App Engine Project 將程式上傳,第一次會遇到 Project 的 application ID 未設定的情況。
2009-04-11_021838.gif

登入自己的 Google App Engine 可以查到 Application ID。
2009-04-11_023115.gif

查到後點選 App Engine project settings 進入設定畫面,填上 Application ID 後返回就可以順利上傳了。
2009-04-11_021901.gif
2009-04-11_021941.gif
2009-04-11_022130.gif

就這樣,最最基本的 Project 設定結束了,連上服務網址就可以看到示範程式,又快又簡單吧!
2009-04-11_023626.gif
2009-04-11_023700.gif

在 Local 測試也只要按下 Eclipse 原有的 Debug 按鈕,透過內建的 Browser 可以馬上測試,比起以往寫 Java 還要 Deploy 上 Web Container 快太多了,這樣才叫寫程式嘛,如果有一天公司的系統也改成這樣開發,整個產能應該會快個十倍吧 (流口水ing)。
2009-04-11_025139.gif

笨搜網,我來替你改版了,等我~

2008年9月5日

[Java] if-else pk switch,誰快?

技術文章又來啦,當沒題材時,技術文章就是最好的工具人。

今天要介紹的是之前在公司 Code Review 探討過的一個問題,if-else 跟 switch 誰快?不囉唆,直接公佈答案:大部分情況 switch 快,但絕少部份 if 快。

switch 判斷的方式類似 HashMap,採用 Binary Tree 的方式,當有 8 個 case 時,最少需要判斷3 次才能找到要執行的區段,因為 2^3=8。這可能因為 Compiler 不同有不同的最佳方式,我用的是 JDK 1.4,推論是這樣。

但 if 就是從頭開始判斷,如果第一個條件就 match 到,那速度就超快的,即使後續有 n 個 if-else 都無所謂了。

所以結論就是如果已經知道非常大部分都會落在某一個選項,採用 if 的方式,把最常發生的選項放在 if 的第一個,保證速度最快。但如果每一個選項都有一定的機率會被判斷到,採用 switch 會是比較保險的選擇。

驗證的程式如下,第一個是 switch。

 1:   public static void caseSwitch(int a) {
 2:    long s = System.currentTimeMillis();
 3:    for (int i = 0; i < 100000000; i++) {
 4:     switch (a) {
 5:      case 3 :
 6:       break;
 7:      case 5 :
 8:       break;
 9:      case 7 :
10:       break;
11:      case 2 :
12:       break;
13:      case 6 :
14:       break;
15:      case 4 :
16:       break;
17:      case 1 :
18:       break;
19:      default :
20:       break;
21:     }
22:    }
23:    long e = System.currentTimeMillis();
24:    System.out.println("Switch Cost: " + (e - s));
25:   }

第二個是 if。


 1:   public static void caseIf(int a) {
 2:    long s = System.currentTimeMillis();
 3:    for (int i = 0; i < 100000000; i++) {
 4:     if (a == 3) {
 5:     } else if (a == 5) {
 6:     } else if (a == 7) {
 7:     } else if (a == 2) {
 8:     } else if (a == 6) {
 9:     } else if (a == 4) {
10:     } else if (a == 1) {
11:     }
12:    }
13:    long e = System.currentTimeMillis();
14:    System.out.println("If Cost: " + (e - s));
15:   }

當傳入的數值落在 if 跟 switch 的最後一個選項時,if 比較慢。

caseSwitch(1); // --> Switch Cost: 328
caseIf(1); // --> If Cost: 532

當傳入的數值落在 if 跟 switch 的第一個選項時,if 變得比較快了。

caseSwitch(3); // --> Switch Cost: 422
caseIf(3); // --> If Cost: 297

實際比較起來,執行一億次差不到半秒鐘,雖然說各有優勢,但優勢實在太小了,等有寫到十億次、一兆次的程式再來考慮就好,平常跑個幾千次的就隨便用了啦,差別實在太小了。


PS:有人會說那換成 char 會不會有所不一樣, 有空的人可以去測測看,我測試的結論是一樣。

2008年7月20日

驗證密碼的 Regular Expression

好久沒寫技術文章了,來寫一下最近遇到的 Case,利用 Regular Expression 驗證密碼,密碼長度在 6-30 字元內,且要包含數字、英文字,網路上查到的 Pattern 如下

^(?=.*\d)(?=.*[a-zA-Z]).{6,30}$

有人說這是罵人的話,哈,看起來真像。

先來驗證一下是否正確,先到 RegEx: online regular expression testing,Regular Expression 輸入上面那一串密文,Test String #1 輸入想驗證的字串,按下 Test 出現驗證結果,這個網站好用的地方在驗證結果會很貼心的把 Java 跟 Regular Expression 有關的 Method 的驗證結果都列出來。

測試沒問題後接著就來了解一下這串外星文在寫些什麼

.:表示任意一個字元,在 Java 中除了 "\r"、"\n" 外都包括。
*:表示前面那個 Pattern 出現 0 或一次以上。
.*:表示非 "\r"、"\n" 字元出現了 0 或一次以上。
\d:表示數字 0-9,也可以寫成 [0-9]。
.*\d:表示非 "\r"、"\n" 字元出現了 0 或一次以上,再跟著一個數字,可以驗證字串中有出現過數字,不管在任何位置。
(?=.*\d):這是 Positive Lookahead,用來判斷右邊緊接著的字元是否符合比對條件,如果符合條件才會繼續比對下去。拿這個實例來說,右邊的字元必須包含一個數字才算符合這個條件。
[a-zA-Z]:表示英文字母,大小寫都包含在內。
.*[a-zA-Z]:表示非 "\r"、"\n" 字元出現了 0 或一次以上,再跟著一個英文字母,可以驗證字串中有出現過英文字母,不管在任何位置。
(?=.*[a-zA-Z]):跟上面出現過得 Positive Lookahead 一樣,這是說右邊的字必須包含一個 a 到 z 或是 A 到 Z 的字元,說穿了就是右邊的字要包含一個英文字的意思。
.{6,30}:表示字串長度要大於等於 6,小於等於 30。
^:表示字首,意思就是說後面的字必須是從字首開始。
$:表示字尾,表示前面的字要是字尾。

解釋完畢,到這裡原本就不懂的人應該還是不懂,原本就懂的人會覺得這是垃圾文,半懂的人應該會有點收穫,但腦海中應該會浮出更多疑惑。

在測試完這神奇的外星文可以正確的達到我想要得效果後,去網路上找了一些資料,發覺 Regular Expression 真強大,一堆看不懂的符號交錯在一起就可以完成驗證的工作,這就像 SQL 一樣,要常寫、常練習才會寫得好、寫得漂亮。因此解釋完有更多疑惑是正常的。

想更了解的可以參考 JavaWorld 上有一篇 Java Regular Expression的學習筆記,寫得算很淺顯易懂。最後放上驗證的程式碼供參考

public boolean isPwValid() {
String pw = getSysUser().getPassword();
String pattern = "^(?=.*[a-zA-Z]+)(?=.*\\d+)[a-zA-Z0-9]{6,16}$";
Pattern p = Pattern.compile(pattern);
Matcher m = p.matcher(pw);
return m.matches();
}

很意外不是用 Jakarta 的 RegExp 套件吧,原來 Java 中藏了這麼好用的 Class。

2008年1月1日

SCMAD 考試心得

上星期四趁著 Voucher 快過期,趕緊去考了 SCMAD,話說 SCMAD 年初就想考了,但是因為沒急迫性(其實是自己懶),就這樣一直拖到年底,眼看 Voucher 要過期才想到今年還有這件事沒完成,迫於不想浪費 $4000 才拿起書本猛 K。Voucher 過期真的是逼自己唸書的好方式,幾乎每一次考證照都是因為 Voucher 快到期的關係,不然還真的沒啥動力考證照,又不會加薪XD。

SCMAD 全名 Sun Certified Mobile Application Developer for the Java 2 Platform, Micro Edition, Version 1.0,考試內容主要為 J2ME,考試編號是 CX-310-110,考試時間 150 分鐘,答對 68 題中的 38 題就算過關,需先具備 SCJP 才能參加。

 

考試內容分為十一部份

第1部分:JTWI (JSR 185)及JTWI-Compliant無線應用程式概觀
第2部分:CLDC 1.0及1.1
第3部分:安全性(CLDC與MIDP)
第4部分:網路
第5部分:應用程式模型、傳遞、生命週期及供應
第6部分:MIDP持續儲存
第7部分:Push Registry
第8部分:MIDP使用者介面(UI) API
第9部分:MIDP Game API
第10部分:使用MIDP 2.0與MMAPI 1.1之媒體
第11部分:無線傳訊API 1.1

 

因為我是抱著志在考過,不在學會的消極心態,所以準備的內容不是很充足,有心學習 J2ME 最好還是認真一點準備,多寫一點練習程式,不然證照就真的只是一張紙而已。

準備考試的教材是Java手機程式設計─邁向SCMAD認證,這應該是市面上唯一一本專門針對 SCMAD 寫的中文認證書。跟一般認證書一樣,書中附了大量的考古題供練習。如果想跟我一樣只想快點考到證照,那這本書是唯一選擇。

但書中的錯誤真的太多了,多到會懷疑這本書是不是寫完就上架開賣,不只內容有誤,考古題答案也有錯。讀的時候如果遇到怪怪的地方,最好抱持懷疑態度,自己去找到答案會比較好。

 

我整個考試的準備時間是一個月。前兩個星期就是猛 K Java手機程式設計─邁向SCMAD認證,能記就記、能背就背,一字不漏的讀完 11 個章節,除非遇到很怪的內容我才會上網找正確答案,否則就先抱持懷疑態度,因為要快,所以在這階段我以相信書為主。

這兩個星期我沒每天看書,平常大概兩天看一章節,六日時間比較多就每天看一個章節。整體來說這兩個星期是很混的。不過只要是開始看書,就很認真的做每個考古題,不是只看題目背答案,是真的去做,然後跟答案比對,做錯了就回去翻前面的內容了解錯在哪裡。這樣下來每一個章節的閱讀時間加上做考古題大概也要花上一個半鐘頭到兩個小時。

 

第三個星期就是再把書拿來 K 一次,從頭到尾再讀一次、考古題再做一次。由於已經讀過一次,這次會快很多。這次閱讀時可以開始畫重點了,但切記不要畫太多,除非你有把握有時間回來看,不然畫很多只是浪費自己的時間。我的重點畫很少,大概十分鐘可以翻完,就是考前十分鐘複習用。(雖說如此,考試當天我還是一下班就去考了,上班時哪有時間看書ㄚ)

因為已經做過一次考古題,第二次做的時候會比較確定哪些是真的有問題的答案,這時不要客氣,Google 下去吧。不然就自己寫練習程式,這真的很重要,因為寫練習程式會比單純看書還記得更牢,我大概寫了五、六個練習程式,特別是在 UI、Game 的部份,這兩個部份書中寫得不清楚,如果不自己實做恐怕很難光靠書就了解意思,背也背不起來。

這個階段我還搭配了 J2ME 相關的 API Doc 來看,Java ME Technology APIs & Docs這是所有 J2ME 相關的 API 文件,但考試內容不是全部,重點在於

重要程度    
★★★ Mobile Information Device Profile 2.0 JSR 118
★★ Connected Limited Device Configuration 1.1 JSR 139
★ Mobile Media API 1.2 JSR 135

只要書中有提到的 Class、Method,請務必翻到對應的 Java Doc 看過一次,什麼 Method Name、Parameter、Return Type、Throws Exception,能背就背,不能背多翻幾次起碼也有印象,這真的超級超級重要。考越多 Java 證照就會越體驗到 Java Doc 的重要。

 

最後一週的時間就是拿來做考古題,網路上可以找到題目不多,大概有這些

 

準備完就殺去考試,考試時按照往例選擇中文考題,原因是中文考題上機考時,考試軟體會多出原文的按鈕,按下可閱讀題目原文。比起單純選擇英文考題多了一份選擇,雖然看英文考題對我來說不是太大的問題,但是看中文還是比看英文快得多,有利於加快作答速度。

但是...不知道從哪時候開始,中文考題竟然沒有原文翻譯,不要以為這沒什麼,中文考題根本不是專業技術人員翻譯的,整個就是看不懂,Push Registry 翻成發送登錄、Application Management Software 翻成軟體管理系統,這絕對會大大影響成績。建議還是乖乖的選擇英文考題來的好,考試時間絕對夠,不用怕看題目花太多時間而做不完考題。

最後 68 題中答對 51 題,以 75% Pass,成績雖然不算太好,但好加在沒浪費 $4000。真的想學 J2ME 的人還是一步一腳印的多做練習,只為了考證照而考證照似乎有點本末倒置。

2007年7月17日

[Java] Synchronized 心得

最近寫程式遇到各個 Thread 之間共用資料保護的問題,做了點功課,寫下一些小筆記。
簡單介紹
Synchronized使用時,需指定一個物件,系統會Lock此物件,當程式進入Synchrnoized區塊或Method時,該物件會被Lock,直到離開Synchronized時才會被釋放。在Lock期間,鎖定同一物件的其他Synchronized區塊,會因為無法取得物件的Lock而等待。待物件Release Lock後,其他的Synchronized區塊會有一個取得該物件的Lock而可以執行。
各種用法
1. Synchronized Method
synchronized public void syncMethod() {
…
}

此種synchronized用法鎖定的物件為Method所屬的物件,只要物件被new出超過一個以上的Instance,就有可能保護不到Method內程式。但如果此物件只會被new出一個Instance,譬如new出來後就放到ServletContext,要用的時候從ServletContext中拿出來執行,就可以避免此情況。
2. Synchronized Static Method
synchronized static public void syncMethod() {
…
}

此種synchronized用法鎖定的物件為Method所屬的物件的Class,不管被new出幾個的Instance,都能夠保證同一個時間只會有一個Thread在執行此Method。
3. Synchronized(this)
public void syncMethod() {
  synchronized(this) {
    …
  }
}

此種synchronized用法與synchronized method用法一樣,都是鎖定Method所屬的物件本身。
4. Synchronized(SomeObject)
public void syncMethod() {
  synchronized(SomeObject) {
    …
  }
}

此種synchronized用法鎖定的是SomeObject,如果SomeObject是同一個Class的兩個不同Instance,那synchronized區塊內就有可能被同時執行。如果每一個Synchronized的SomeObject都是同一個Instance(或者SomeObject本身就是Static),就可以保證區塊內同時間只會有一個Thread執行。
當使用Synchornized(SomeObject)時,SomeObject本身處於被Lock狀態,但此時其他的Thread是可以去更改SomeObject裡面的值,Lock只是同步化的狀態,不表示不能更改資料。
使用時機
Synchronized的使用時機很難定義,比較常見的情況是,當程式中會取出某一個共用的物件且會判斷物件內容值,再更新物件內容,此情況大部分都需要synchronized保護。
Related Posts Plugin for WordPress, Blogger...