12/20/2013
2:21:00 PM 0

使用 PC 在 Facebook 打卡

1. 安裝  Chrome 瀏覽器

2. 到 Chrome 線上應用程式商店安裝  Manual Geolocation

安裝完成後再網址列右方會多了一個圖示,按下圖示開始設定位置
3. 設定 Manual Geolocation
  • 按下 enable, 打開定位功能

  • 輸入打卡地點

4. 接著到行動版的 Facebook 打卡就行囉, 行動版網址 http://m.facebook.com
12/18/2013

Configuring Apache 2.0 as a Forward Proxy Server

Edit the Apache httpd.conf Configuration File

1.設定 Port
Listen 8080
2.設定 Module
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_connect_module modules/mod_proxy_connect.so
LoadModule proxy_http_module modules/mod_proxy_http.so
LoadModule proxy_ftp_module modules/mod_proxy_ftp.so
前三項為必要Module, 後面可依需求增減

3.設定 VirtualHost
<VirtualHost *:8080>
 ProxyRequests On
 ProxyVia On
 <Proxy *>
  Order deny,allow
  Deny from all
  Allow from 192.168.0.0/16
 </Proxy>
</VirtualHost>
4.重新啟動 server 即設定完成


Windows 版本的 Chrome Browser 獨自設定 Proxy Server 的方式如下
Chrome.exe --proxy-server=192.168.0.1:8080
12/04/2013
3:43:00 PM 0

Java Enum Singleton

Java 在 1.5 版本之後開始支援 Enumerated type,Enum 的用法可參考下面連結

http://www.ajaxonomy.com/2007/java/making-the-most-of-java-50-enum-tricks
http://javarevisited.blogspot.tw/2011/08/enum-in-java-example-tutorial.html
http://docs.oracle.com/javase/1.5.0/docs/guide/language/enums.html

使用 enum 實作 singleton,是一個不錯的方式,因 enum instance 預設狀態下就是 thread safe 的,所以使用 enum 來實作 singleton 是相當簡便的

範例
public enum Singleton {
    INSTANCE;
    public void someOperation() { .. }
}
參考
http://www.informit.com/articles/article.aspx?p=1216151&seqNum=3
12/03/2013

Initialization-on-demand holder idiom

實做 Singleton 的方法有很多種,Java 1.5 以上可以使用 Double-checked locking,但使用鎖會影響程式效率,如何不用鎖又能達到 Singleton 呢?  Initialization-on-demand holder 就是一種常見的程式技巧,以下列出 Eager initialization, Static block initialization 與 Initialization-on-demand holder 做比較
public class EagerInitialization {

    public static final EagerInitialization INSTANCE =  new EagerInitialization(); 
    public static final String TEST = "test";
 
    private EagerInitialization() {
        System.out.println("constructor");
    }
 
    public static EagerInitialization getInstance() {
        System.out.println("getInstance");
        return INSTANCE;
    }
}
public class StaticBlockInitialization {

    public static StaticBlockInitialization instance; 
    public static final String TEST = "test";
 
    private StaticBlockInitialization() {
        System.out.println("constructor");
    }
 
    static {
        try {
            instance = new StaticBlockInitialization();
        } 
        catch (Exception e) {
            e.printStackTrace();
        }
    }
   
    public static StaticBlockInitialization getInstance() {
        System.out.println("getInstance");
        return instance;
    }

}
public class InitializationOnDemandHolder {

    public static final String TEST = "test";
 
    private InitializationOnDemandHolder() {
        System.out.println("constructor");
    }

    private static class SingletonHolder {
        public static final InitializationOnDemandHolder INSTANCE = new InitializationOnDemandHolder();    
    }
 
    public static InitializationOnDemandHolder getInstance() {
        System.out.println("getInstance");
        return SingletonHolder.INSTANCE;
    }
}
import org.junit.Test;

public class TestRun {
    @Test
    public void testEagerInitialization() {
        System.out.println("testEagerInitialization start");
        System.out.println(EagerInitialization.TEST);
        EagerInitialization.getInstance();
        System.out.println("testEagerInitialization end");
        System.out.println("------------------------------------");
    }

    @Test
    public void testStaticBlockInitialization() {
        System.out.println("testStaticBlockInitialization start");
        System.out.println(StaticBlockInitialization.TEST);
        StaticBlockInitialization.getInstance();
        System.out.println("testStaticBlockInitialization end");
        System.out.println("------------------------------------");
    }

    @Test
    public void testInitializationOnDemandHolder() {
        System.out.println("testInitializationOnDemandHolder start");
        System.out.println(InitializationOnDemandHolder.TEST);
        InitializationOnDemandHolder.getInstance();
        System.out.println("testInitializationOnDemandHolder end");
        System.out.println("------------------------------------");
    }
}
output

testEagerInitialization start
test
constructor
getInstance
testEagerInitialization end
------------------------------------
testStaticBlockInitialization start
test
constructor
getInstance
testStaticBlockInitialization end
------------------------------------
testInitializationOnDemandHolder start
test
getInstance
constructor
testInitializationOnDemandHolder end
------------------------------------

由此可看出 Initialization-on-demand holder 的 lazy initialization 效果是三種方法中最好的
如果我們把上面程式裡的 TEST 變數 關鍵字 final 拿掉
public static final String TEST = "test";
修改成
public static String TEST = "test";
除了 testInitializationOnDemandHolder 輸出結果一樣之外, 其他兩個的輸出次序會改變, 進而影響到 lazy initialization 的結果,以下是拿掉 final 關鍵字的輸出結果

testEagerInitialization start
constructor
test
getInstance
testEagerInitialization end
------------------------------------
testStaticBlockInitialization start
constructor
test
getInstance
testStaticBlockInitialization end
------------------------------------
testInitializationOnDemandHolder start
test
getInstance
constructor
testInitializationOnDemandHolder end
------------------------------------

當存取到非 final 的 static 變數時, JVM 會立刻初始化其他 static 變數,因此使用 Eager initialization, Static block initialization 必須要注意到這個問題,相形之下 Initialization-on-demand holder 的好處就顯現出來了,就算其他程式設計師在程式中添加其他變數也不會影響到程式輸出結果

參考
http://en.wikipedia.org/wiki/Singleton_pattern
12/02/2013

Java Double-check locking idiom for lazy initialization of fields

注意 : Java 1.5 以上版本才可使用 雙檢鎖, 並要搭配 volatile 關鍵字
private static final Object LOCK = new Object();
private static volatile Singleton instance;

public static Singleton getInstance() {

    Singleton result = instance;
    if (result == null) {
        synchronized (LOCK) {
            result = instance;
            if (result == null) {
                instance = result = new Singleton();
            }
        }
    }
    return result;
}
區域變數 result 看起來是不必要的,但在某些版本的JVM,可以提升執行效率

參考
http://en.wikipedia.org/wiki/Double-checked_locking
http://zh.wikipedia.org/wiki/%E5%8F%8C%E9%87%8D%E6%A3%80%E6%9F%A5%E9%94%81%E5%AE%9A%E6%A8%A1%E5%BC%8F
https://github.com/resteasy/Resteasy/blob/master/jaxrs/jaxrs-api/src/main/java/javax/ws/rs/ext/RuntimeDelegate.java