7/12/2013
2:36:00 PM 0

Javascript Wrapper Object

Javascript 有五個基本型別(primitive types)

string
number
boolean
null
undefined

除了這五個之外, 其他都是物件(object)
去掉 null 及 undefined, 其他三個各有對應的 wrapper 物件

string --> String
number --> Number
boolean --> Boolean

Javascript 在執行過程中可以彈性化的轉換基本型別到相對應的 wrapper 物件
var a = "123";
console.log(typeof a);
a.test = "456";
console.log(a.test);
output
--------------------------------------------
string
undefined
因為是基本型別無法賦予屬性, 所以 a.test 會顯示 undefined

自動轉型成 String 物件
var b = "456";
console.log(b.length);
output
--------------------------------------------
3

如果要自訂屬性則必須使用 wrapper 物件
var obj = new String("test");
obj.test1 = "test wrapper object";
console.log(obj.test1);
console.log(typeof obj);
output
--------------------------------------------
test wrapper object
object

模擬 String 物件內部的操作方式
var obj = {
  "0" : "t"
  "1" : "e"
  "2" : "s"
  "3" : "t"
  length: 4
  test1: "test wrapper object"
}

再來看看 Number 物件
var x = 99;
var y = new Number(99);
console.log(typeof x);
console.log(typeof y); 
console.log(x == y); 
console.log(x === y);
output
--------------------------------------------
number
object
true
false

比較 x == y 時,會呼叫 valueOf() 取得回傳值,並做比較的動作
var s1 = new String("abc");
var n1 = new Number(111);
var b1 = new Boolean(true);
console.log(s1 == "abc");
console.log(n1 == 111);
console.log(b1 == true);
String.prototype.valueOf = function() { return "xyz";}
Number.prototype.valueOf = function() { return 999;}
Boolean.prototype.valueOf = function() { return false;}
console.log(s1 == "abc");
console.log(n1 == 111);
console.log(b1 == true);
console.log(s1.toString());
console.log(n1.toString());
console.log(b1.toString());
output
--------------------------------------------
true
true
true
false
false
false
abc
111
true
7/07/2013
8:57:00 PM 0

Javascript loop

  1. for
    var myArray = [1,2,3];
    for (var i = 0; i < myArray.length; i++) 
    {
        alert(myArray[i]);
    }
    
    output
    --------------------------------------------
    1
    2
    3

  2. for in
    var obj = 
    {
        a : 1,
        b : 2
    };
    
    for(var key in obj) 
    {
       alert(key);
    }
    
    output
    --------------------------------------------
    a
    b

  3. forEach (IE9 之後才支援)
    forEach 是從 Array.prototype.forEach 來的, 因此只要是 Array 物件就擁有 forEach 方法
    function alertElements(element, index, array) 
    {
        alert(element);
    }
    [1,2,3].forEach(alertElements);
    
    output
    --------------------------------------------
    1
    2
    3

    在 ECMAScript 5, 也可使用 forEach 取得物件屬性名稱
    var obj = 
    {
        a : 1,
        b : 2
    };
    
    Object.keys(obj).forEach(function(key) 
    {
        alert(key);
    });
    
    output
    --------------------------------------------
    a
    b

  4. while
    var i=0;
    var myArray = [1,2,3];
    
    while(myArray[i])
    {
        alert(myArray[i]);
        i++;
    }
    
    output
    --------------------------------------------
    1
    2
    3

  5. do while
    var i = 1;
    var sum = 0;
         
    do 
    {
        sum += i;
        i++;
    } 
    while (i <= 100);
    
    alert(sum);
    
    output
    --------------------------------------------
    5050
7/03/2013

Hash Collision DoS

oCERT Advisories ==> http://www.ocert.org/advisories/ocert-2011-003.html

Hashtable 在 Java 中是很常被使用的 class 之一, Hashtable 的原理是利用 hash code 的方式, 算出陣列的索引, 來加速資料搜尋, 最佳狀況下, hash code 是不會重覆的, 因此可以達到快速搜尋的效果

Wikipedia 對 Hash table 的說明 ==>  http://en.wikipedia.org/wiki/Hash_table

hash code 的運算方式有很多種, 但不管使用哪一種方式, 都難免發生兩種不同的 Key, 算出同樣 hash code 的狀況, 稱之為碰撞(collision)

我們來看 Java HashMap 如何去處理 collision
public V put(K key, V value) {
    if (key == null)
        return putForNullKey(value);
    int hash = hash(key.hashCode());
    int i = indexFor(hash, table.length);
    for (Entry<k> e = table[i]; e != null; e = e.next) {
        Object k;
        if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
            V oldValue = e.value;
            e.value = value;
            e.recordAccess(this);
            return oldValue;
        }
    }

    modCount++;
    addEntry(hash, key, value, i);
    return null;
}

public V get(Object key) {
    if (key == null)
        return getForNullKey();
    int hash = hash(key.hashCode());
    for (Entry<k> e = table[indexFor(hash, table.length)];
         e != null;
         e = e.next) {
        Object k;
        if (e.hash == hash && ((k = e.key) == key || key.equals(k)))
            return e.value;
    }
    return null;
}

未發生 collision 的狀況下資料結構應該是長這樣

 

當發生 collision 時, Hashtable 變形為 single linked list

在一個線性串列中,如果資料量很大,花費在搜尋上的時間成本也就隨之增加,
有心人士可利用這個特性來對 Java 撰寫的 Web 做攻擊
6/20/2013
5:31:00 PM 0

JavaScript 變數宣告(使用 var 與不使用 var 的區別)

JavaScript 變數使用 var 來宣告, 如果不使用 var, 則屬於 global object
a = 1; //global

function init() {
    b = 2; //global
    var c = 3; //local
}

function test1() {
    init();
 
    console.log(a); 
    console.log(b); 
    console.log(c); 
}

test1();
output
--------------------------------------------
1
2
exception : ReferenceError: c is not defined

變數宣告後在作用範圍內都有效
function test2() {
    console.log(a);
    var a = 1;
    console.log(a);
}

test2();
output
--------------------------------------------
undefined
1

注意 :
第一次 alert 時並未發生 exception, 而是輸出 undefined, 因 a 的作用範圍在 function test2 裡都有效果, a 尚未出始化, 所以輸出 undefined, 這行為稱之為提昇(Hoisting)

我們可以使用 delete 來刪除物件上的特性, 當不使用 var 宣告的變數, 就屬於 global object 中的一個特性, 相當於我們使用 delete 來刪除變數
var a = 1;
b = 2;
console.log(a);
console.log(b);
console.log(delete a);
console.log(delete b);
console.log(a);
console.log(b)
output
--------------------------------------------
1
2
false (false 表示無法刪除)
true (true 表示特性刪除成功)
1
ReferenceError: b is not defined

JavaScript 有幾個內建的 Data Types, 都可使用 var 來宣告
  1. Primary Data Types
    • String
    • Number
    • Boolean
  2. Composite Data Types
    • Object
      • Function
      • Array
      • Date
      • RegExp
    • Array
  3. Special Data Types
    • Null
    • Undefined
example :
var a;//a is undefined
var b = "test";//b is String
var c = 1;//c is a Number
var d = new Array();//d is Array
6/07/2013
3:03:00 PM 0

Service Locator Pattern

將取得服務的方法進行封裝, 可降低程式碼間的耦合度

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

public final class ServiceLocator {

 private static ServiceLocator sl = new ServiceLocator();
 private Context c;
 private Map m;

 private ServiceLocator() {
  try {
   c = new InitialContext();
   m = Collections.synchronizedMap(new HashMap());
  } catch (Exception ex) {
   throw new ExceptionInInitializerError(ex);
  }
 }

 public static ServiceLocator getInstance() {
  return sl;
 }

 public DataSource getDataSource(String name) throws NamingException {
  DataSource ds = null;

  if (m.containsKey(name)) {
   ds = (DataSource) m.get(name);
  } else {
   ds = (DataSource) c.lookup(name);
   m.put(name, ds);
  }

  return ds;
 }
}
11/05/2011
9:08:00 AM 0

解決 windows 2003 升級 sp2 後 RDP(遠端桌面) 無法使用的方法

1. 尋找 %WINDOWS%\Driver Cache\i386\sp2.cab 這個檔案
2. 解壓縮 sp2.cab 取出 termdd.sys
3. Copy termdd.sys to %windows%\system32\drivers
4. 重新啟動 Terminal Services