SVN Checksum Error

前陣子在寫程式的時候,發現了這個錯誤,當我想要commit一個檔案到SVN Server上時,他會告訴我【SVN Checksum Error】的訊息,結果就無法commit檔案上去了。

網路上找到的方法:
但是我是了還是不行,囧。我自己的解決方法很簡單,順序是這樣:

(1) 除了有checksum error的檔案之外,先commit所有其他的檔案
(2) 把無法commit上去的檔案先複製一份到別的資料夾
(3) 刪除有問題的檔案
(4) 重新把剛剛複製到別的資料夾的檔案copy過來,重新commit,這樣就解決了

打完收工!

Minimalist Gmail - 好用的Chrome套件,讓你的GMail更強大

Minimalist Gmail是一個相當強大的Google Chrome瀏覽器套件,他可以讓你自己打造相當客製化的GMail介面,看到Minimalist你可能會覺得這個套件只是讓介面更簡潔,但是除了簡化介面之外,他還可以讓你增加許多原本沒有的功能,讓我們來安裝玩玩看吧!
安裝好之後,會跳出這樣的設定畫面,裡面包羅萬象,可以設定的項目可多著呢:


比如說,在General的選項裡面,你可以去更改按鈕的顏色:


此外,我覺得最方便的是,當你的滑鼠移動到該項目上面時,他會show出一張圖讓你可以清楚的了解到目前所更改的部分是對應到GMail的哪個部位,如此一來,你就不用憑空猜想勾選這個選項後會有什麼改變了,我覺得這真的是一個很好的設計概念。比如說,下面的圖是我把滑鼠游標移動到【Enable custom buttons】選單上所顯示的圖:


還有選項是可以在標籤上顯示目前未讀的郵件:


這個是讓你自訂GMail上方的連結,不喜歡都是Google產品連結的話,就自己改個喜歡的吧!


其他還有許多不同的功能,大家不妨使用看看,把GMail的介面調整成自己最喜歡的樣式吧!

Do Nothing for 2 Minutes - 兩分鐘內什麼都不要作,休息一下吧!

我們每天都在網路上接收大量的訊息,不管是來是RSS訂閱、Plurk、Facebook、Twitter上面的朋友分享連結或是各式各樣的網路新聞,其實都是在進行【ADD】資訊的動作,你有沒有曾經覺得資訊多到腦袋已經不勝負荷了呢?

其實,一直不斷的給腦袋作資訊轟炸,某些層面上並不是件好事情,每天撥一點時間來放空或放鬆,對於創造力、生產力來說,都是一件好事情。這個時候,不妨打開這個叫做【Do Nothing for 2 Minutes】的網站來幫助你放鬆兩分鐘吧!

  • Do Nothing for 2 Minutes:http://www.donothingfor2minutes.com/

顧名思義,這個網站相當相當簡單,你只需要什麼都不作,聽著海浪的聲音放空兩分鐘就對了,在放鬆的過程中,會有倒數計時器幫助你了解目前進行的時間:


如果你動了滑鼠或鍵盤,那就會出現FAIL的字眼並且重新開始倒數:


成功的話當然也會秀出一些訊息囉:


累了嗎?來休息兩分鐘吧!

Google短網址服務 - 有了專屬網站還有API

Google在去年九月的時候給自己的短網址服務【goo.gl】一個專屬的網站,網址在此:

根據pingdom的這篇文章-【Is Goo.gl really the fastest URL shortener? (chart)】顯示,goo.gl是目前最快速、最穩定的短網址服務:


Google自己在也在Blog中提到,目前的短網址服務這麼多,為什麼Google還要跳進來參與呢?因為goo.gl是強調要做就要做最好的,他們提供了穩定度、安全性和速度的三大保證,目前看起來似乎是有這麼一回事:
  • Stability: We've had near 100% uptime since our initial launch, and we've worked behind the scenes to make goo.gl even stabler and more robust.
  • Security: We've added automatic spam detection based on the same type of filtering technology we use in Gmail.
  • Speed: We've more than doubled our speed in just over nine months.

而goo.gl這個短網址服務也很有趣,他所提供的網站裡面保存著你過去的紀錄,你可以追溯每個被縮短網址的點擊情況:


點選detail進去可以看到比較詳細的統計情形,包括是從哪個網站連進來的、國家、使用的瀏覽器和作業系統等等:


甚至還提供了QR Code呢:


現在,goo.gl還有對外的API可以使用了,網址在此:

Google短網址API:http://code.google.com/intl/zh-TW/apis/urlshortener/overview.html

有興趣的人可以自己寫程式來存取短網址服務囉。

[設計模式] Strategy Pattern(策略模式) Part 1

策略模式在Head First Design Pattern這本書中,是最先被介紹到的設計模式,可見得他應該是很重要且很基本的模式之一。以下就讓我們來記錄學習的心得並且分享筆記給大家。策略模式的基本定義如下:

Define a family of algorithms, encapsulate each one, and make them interchangeable. [The] Strategy [pattern] lets the algorithm vary independently from clients that use it.

【中文版】策略模式在於觀察程式中變動的部分,並且將他們抽離出來封裝成可互相抽換的演算法家族。這個模式讓你即使任意更換實作的演算法,也不會變動到去使用者他們的客戶端程式。

在這篇文章中,我們先看看如果不使用策略模式時,撰寫出來的程式是如何,接著在下一篇文章中進行一個對比。

讓我們考量一個情境(此情境延伸自Head First Design Pattern的練習),假設我們需要設計一組遊戲角色,我們可能會先定義一個角色類別,每一個遊戲角色都可以攻擊(fight)、行動(action)和交談(chat):


public abstract class Character {
    public abstract void fight();
    public abstract void action();
    public abstract void char();
}

這是一個很簡單的角色類別,加上abstract修飾子,讓繼承Character的class必須強迫去實作fight、walk和talk這三個方法。接著就可以真正創造我們的角色,假設我們有國王(King)、皇后(Queen)和騎士(Knight)這三個角色,那我們會這樣定義三個類別:

public class King extends Character {

     @Override
     public void action() {
         System.out.println("King walk");
     }

     @Override
     public void chat() {
         System.out.println("King chat");
     }

     @Override
     public void fight() {
          System.out.println("King fight by hand");
     }
}



public class Queen extends Character {

     @Override
     public void action() {
         System.out.println("Queen walk");
     }

     @Override
     public void chat() {
         System.out.println("Queen chat");
     }

     @Override
     public void fight() {
          System.out.println("Queen fight by hand");
}



public class Knight extends Character {

     @Override
     public void action() {
         System.out.println("Knight walk");
     }

     @Override
     public void chat() {
         System.out.println("Knight chat");
     }

     @Override
     public void fight() {
          System.out.println("Knight fight by hand");
}

角色都創建好了,看起來好像都沒有問題,但假設某天我們的遊戲改版了,使用者可以購買武器來殺敵,我們需要擴充程式來滿足這樣的需求。所以老闆說需要增加【寶劍】、【斧頭】、【匕首】等三種不同的新的攻擊模式,慘了,我們需要在角色類別裡面增加三個方法:


public abstract void fightBySword();
public abstract void fightByKnife();
public abstract void fightByAxe();


但是,問題來了,所有繼承角色這個類別的子類別都必須要實作這三個方法,但是假設皇后不能用斧頭只能用匕首、國王只能用寶劍...,這樣一來就很麻煩,我們必須要在個別角色裡面新增這三個方法,然後有些方法是空的...,多麼不好的寫法!

所以,利用繼承是會有缺點的,改變父類別的內容會連帶的更動到所有繼承他的子類別。在下一篇中我們來看看Strategy Pattern可以帶來什麼改變。

隨時提醒自己保持專注的三款倒數計時器(Keep Focus、Focus Booster、Timer)

最近和同事聊天談到時間管理的話題,主要是希望能夠有一個可以倒數計時的時鐘在桌面上提醒自己,印象中之前就有看過類似的工具和介紹文章,研究了一下,目前有幾個工具可以介紹。

Keep Focus

下載:
Keep Focus是用來實踐Pomodoro工作法的小工具,主要的進行步驟如下:
  1. 從Tasks List中挑選一個工作出來
  2. 設定25分鐘的Pomodoro工作時間
  3. 開始進行工作直到25分鐘結束(不論該工作結束與否,都要稍微停止並且做記錄)
  4. 休息5分鐘
  5. 每4個Pmodoro工作時間做一次較長時間的休息
上面的方法有沒有效是因人而異,不過裡面用到了Keep Focus這個小工具來實踐Pomodoro工作法。這個小軟體功能很簡單,就是一個小小的倒數計時器:
紅色叉叉關閉、白色按鈕會暫停計時並且重新開啟一段25分鐘區塊、最左邊的灰色按鈕可以進行拖拉。Keep Focus會把你實踐的結果存成文字檔,你可以隨時進行檢視。

  • 優點:小巧不占空間,功能單純。
  • 缺點:時間區塊不能自訂,只有25分鐘的設定。

Focus Booster

下載:
Focus Booster是一款base on Adobe AIR的軟體,功能也是用來倒數計時。這個軟體就頗美觀,同時也可以設定一個工作區塊的長度和休息時間。比較有趣的是,Focus Booster可以在倒數的時候發出滴答滴答聲音(不過還蠻吵的,所以預設是關閉的),結束了可以設定鬧鐘聲音。





    • 優點:可自訂工作時間長度。
    • 缺點:必須要先安裝Adobe AIR。


    Timer

    下載:
    Timer也是一個用來倒數計時的軟體,下載安裝之後,會在常駐區出現這樣的到數計時器:


    在icon上面點右鍵選擇Settings可以進行細部設定:


    可以設定的項目包括了是否要顯示在最上層、是否要開啟鬧鈴、鬧鈴的音樂...等等。


    比較特別的是Timer的設定時間方式,產生一個新的倒數計時工作的格式是:
    時間   時間種類   顯示訊息
    比如說我輸入【30 出門】代表30分鐘後出門,就會產生下面的倒數計時器。如果時間種類不輸入預設就是分鐘,小時則要輸入【hours】、秒的話是【sec】









    • 優點:功能最強大。
    • 缺點:時間設定功能較不直覺。

    介紹了三種倒數計時的工具,大家可以挑選自己喜歡的來使用,不過記得不要一次全部都用,這樣只會更複雜喔。

    【相關閱讀】
    Timer 免費免安裝的桌面小鬧鐘軟體,幫你倒數計時重要約會
    Keep Focused 保持25分鐘專注力的Pomodoro 工作法小工具| 電腦玩物
    Focus Booster 善用桌面電子番茄鐘,讓工作專注力加速| 電腦玩物

    [設計模式] Singleton Pattern (單例模式) Part2 (解決多執行緒問題) - Update Volatile關鍵字

    [2011-1-1補充] volatile關鍵字


    感謝馮大哥留言,在運用Double-Checked locking的作法時,在Java 5.0之後必須要加上volatile的修飾子在物件的變數宣告上,也就是變成:
    •  private volatile static Singleton instance;
    這樣子的寫法。原因在於,如果不加上volatile這個關鍵字時,在Java中由"順序"的問題,還是有可能會發生問題。最顯而易見的錯誤在於,當A執行緒進入getInstance()方法後,並且得到if(instance==null)為true的結果,進入到同步區,要執行Singleton()建構子內的敘述,但還沒有執行完時,執行緒B就進入getInstance()方法中,並且得到instance不是null的結果(因為在記憶體空間中已經配置的位置給instance了),如此一來就會造成執行緒B的物件內容並沒有成功的被指派,A和B之間就會有不同步的情形了。

    詳細的過程可以參考這篇文章:Double-checked Locking (DCL) and how to fix it

    我覺得寫的還蠻清楚的,另外我也加了相關閱讀在最下方,歡迎大家參考,這幾篇對於Double Check Locking的機制都寫得蠻清楚的,值得一看囉。
    ==

    在Singleton Pattern (單例模式) Part1中的【Lazy Instantization】方法可以說是最基礎的方式,但是在多執行緒的程式當中,這樣的寫法還是有可能會產生不同的實體,也就是這樣的寫法並不是一個thread-safe的方式,我們可以寫一個小程式來檢查看看:


    public class SingletonTest extends Thread {

        String threadName = "";

        public SingletonTest(String name) {
            threadName = name;
        }

        public void run() {
            for(int i=0 ; i<10 ; i++) {
                try {
                    Thread.sleep((int)500);
                    Singleton instance1 = Singleton.getInstance();
                    System.out.println(threadName + " ==> " + instance1.hashCode());

                } catch (InterruptedException e) {
                    e.printStackTrace();
            }
        }
    }

        public static void main(String [] a) {
            Thread t1 = new SingletonTest("thread-1");
            Thread t2 = new SingletonTest("thread-2");

            t1.start();
            t2.start();
        }
    }


    兩個threads可能會產生相同的實體(相同的hashCode)或是不同的實體(但不一定每次都會發生),原因在於兩個threads可能同時呼叫Singleton.getInstance()時,在進行if(instance==null)判斷時,結果都可能會是true,以至於都產生一個新的實體,這樣就會違背Singleton Pattern的宗旨了,所以我們必須進一步的修改這個模式。

    修改的想法是,當A、B兩個執行緒同時呼叫Singleton.getInstance()這個方法來取得物件的實體時,必須要先等對方結束之後才呼叫,才不會造成問題。換句話說,getInstance()這個方法在Java中只要加上Synchronized這個修飾子就可以解決了,如此一來,整個getInstance()方法就變成一個同步等待區,可以避免多執行緒造成重複實體的問題。

    public class Singleton {

        private static Singleton instance;

        private Singleton () { }

        public static Synchronized Singleton getInstance() {
            if(instance==null)
                instance = new Singleton();
            return instance;
        }
    }


    上面提到,某個執行緒必須等到另外一個執行緒離開之後才能存取getInstance()這個method,當執行緒一多的時候,可以想像的會造成效率的低落。所以又有進一步的改良寫法,那就是採用雙重上鎖(Double-Checked locking)的方式。

    雙重上鎖的概念是,一開始先檢查instance這個變數是不是null,如果不是null代表之前已經實體化了,直接回傳就好,如果沒有實體化時,才會進入同步等待區域。實際撰寫上只要將上面的getInstance()方法改寫成以下的形式就可以了:


    public class Singleton {

        private volatile static Singleton instance;

        private Singleton () { }

        public static Singleton getInstance() {
            if(instance==null) {
                Synchronized(Singleton.class) {
                    instance = new Singleton();
                }
            }
            return instance;
        }
    }


    如此一來就可以解決多執行緒效率的問題囉!歡迎大家一起留言討論:)

    【相關閱讀】
    Double-checked locking and the Singleton pattern
    Double-checked Locking (DCL) and how to fix it
    The "Double-Checked Locking is Broken" Declaration