2010年9月29日 星期三

Eclipse Web Service Setting



參考以下:
http://www.eclipse.org/webtools/community/tutorials/BottomUpAxis2WebService/bu_tutorial.html


<

AxisAdminServlet Class not found exception occurs as deploying the web service.

問題簡述:
Eclipse Java EE IDE for Web Developers. (Build id: 20090621-0832)
建立 web service後, 啟動 Tomcat 5.5 顯示錯誤訊息
java.lang.NoClassDefFoundError: org/apache/http/HttpResponseFactory

解決方法:
從 Apache Axis2 官網中下載 axis2-1.5-bin.zip, 從zip檔案的lib目錄中複製httpcore-4.0.jar 至
該專案的 WEB-INF/lib 目錄中







2010年9月28日 星期二

Interview 建議的題目(09/27)

1. Describe Java's exception handling:
Exception handling is the technique of catching the exceptions that might be thrown some time in the future during runtime. Java offers robust exception handling solutions with the try-catch-finally construct. One of the most remarkable exception is when, during program execution, the time comes for a division by zero. This cannot be done and, therefore, Java throws an exception, specifically the ArithmeticException.

2. What's the purpose of the finally clause of a try-catch-finally statement?
A finally clause can be added to force the exception of statements that perform necessary cleanup.

3. Tell me about a case that finally cluase will be not executed?
There is none.

4. Name some OO design patterns you have used and how/why you used them?
TO-DO
Singleton? Abstract Factory?
Hibernate SessionFactory is singleton??
Spring framework is Proxy??

5. What is a Singleton?
a. It proposes that at any time, there can only be one instance of a singleton (object) created by the JVM.
b. The class's default constructor is made private, which prevents the direct instantiation of the object by other classes. At static modifier is applied to the instance method that returns the object as it then makes this method a class level method that can be accessed without creating an object.
c. Singletons can be used to create a Connection Pool. If programmers create a new connection object in every class that requires it, then it's clearly waste of resources. In this scenario by using a singleton connection class we can maintain a single connection object which can be used throughout the application,

6. What is a transient variable and why would you use one?
A variable that may not be serialized. (Temporary state of the object which need not be saved, something like process ID, or Time information)

7. What is serialization?
Serialization is a mechanism for persisting and retrieving an object, including its state to/from the persistant storage.
(http://619lucky.blogspot.com/2010/09/java-serializable-string-object-is.html)
String object also implements Serializable interface. Serializable interface doesn't have any mothed.

8. What are the components of JDBC?
Connection pool, data sources, statement, ResultSets.

9. What is a bind variable (for JDBC) and why should they, or should they not, be used?
A placeholder for a variable in a query.... should almost always be used to reduce the number of query parses executed by the database.

10. When do you use a Statement vx. a CallableStatement vs. a PreparedStatement?
CallableStatement for procedures.
PrepatedStatemnt for queries using bind variables.
Statement for non bound (no bind variable) queries.

11. What is a DataSource?
Interface javax.sql.DataSource
DataSource is a factory for connections to the physical data source that DataSource factory represents.
DataSource is the preferred means of getting a connection.
An object that implements DataSource will usually be registered with a naming service based on the JNDI (Java Naming and Directory API)
(http://download.oracle.com/javase/1.4.2/docs/api/javax/sql/DataSource.html)

12. What is connection pool?
When use a SQL ot other similar tool to connect to that database and act on the data, "getting the connection" and "logging in" is the part that takes the most of the time.

Cached connections are kept in a runtime object pool and can be used and reused as needed by the application. One way to implement the object pool is to make a simple hashtable of connection objects. However, a more flexible way to do it is to write a wrapper JDBC Driver that is an intermediary between the client application and database.
(http://java.sun.com/developer/onlineTraining/Programming/JDCBook/conpool.html)
.....

13. What's a reasonable limit on connection pool size for an average single application server?
I don't know.... 20?
....

14. Can that many connections cause problems for a database?
Yes(?) If the connection is persistent...?
(http://blog.powercam.cc/xms/doc/724)
(http://www.coderanch.com/t/216774/ORM/java/Too-many-Connections-Exception)

15. Is there a maximun number of connections limit defined in the database?
How do you change it?
( I don't know )

16. What is the Connections API and what are the advantange of using it?
The Connections framework provides a well-designed set for sorting and manipulating a group of data (a collection).
(http://www.allapplabs.com/java/java_collection_framework.htm)
a. The collection interface is a group of objects, which duplicates allowed.
b. Set extends Collection but NOT allow duplicates.
c. List extends Collection also, it allows duplicates and introduces positioning indexing.
d. Map extends neither Set nor Collection.
Interface
Implementation
Historical
Set
HashSet

TreeSet


List

ArrayList

LinkedList
Vector
Stack
Map
HashMap

Treemap

Hashtable
Properties

ArrayList是List(列表),数据是有序的,可以有重复元素 HashSet是Set(集合),数据没有顺序,没有重复元素,元素搜索速度快 
17. Is Iterator inthe Collections API a class or an interface?
interface

18. What's the difference between a HashSet and an ArrayList?
HashSet can't have duplicate key/value, ArrayList can.

19. What's the difference between a HashSet and a HashMap?
a. HashSet doesn't allow duplcate, it maintains a unique list.
b. HashMap allows null for both keys and value, it's unsynchronized.
A HashMap provides fast access to a mapping from a unique key to a value. Keys are unordered which makes it faster than the TreeMap where the keys are ordered.
A HashSet is fast access to unique value only (there are no keys because it is not a mapping it's just the values). HashSet values are unordered which makes it faster than the TreeSet where the values are ordered.

20. Give an example of when you would use a HashMap?
If you may have null value in the collection, and the keys are unique but not in order...

21. What object do you use to determine if a user posesses a J2EE Role?
HttpRequest

22. What's the difference between an Integer and an int?
Object/Primitive
Object is using memory in Heap, Primitive is using memory in Stack.
(Check out Heap/Stack http://619lucky.blogspot.com/2010/09/java-stack-and-heap.html)

23. What methods are available on an int?
none.

23. What class do you use to convert between Integers, ints and Strings?
Integer

24. Are the methods you use to convert between Integers and ints class methods or instance methods?
Class method.

25. What does it mean for a method to be static?
Static methods use no instance variables of any object of the class. if you define a method to be static, you will be given a rude message by the compiler if you try to access any instance variables. You can access static variables, but except for constants.
Static methods typically take all the data from parameters and compute something from those parameters (with no reference to variables).
Static method is typical of methods which do some kind of generic calculation. A good example of this are the many uility methods in the predefined Math class.

宣告 method 時,如果前面加上 static 的修飾字,就會使得此 method 變成是 class method。對 class method 而言,永遠只佔用一塊記憶體,而且此記憶體空間是在此 class 一被載入進記憶體之後就立刻配置的,就如同此 method 是與該 class 本身相關,而不是與該 class 的 instance 相關。


26. What class do you use to manipulate Date objects in Java?
Calendar

27. What class do you use to format Date objects in Java?
DateFormat(abstract class) or SimpleDateFormat -subclass of DateFormat.


28. What is the difference between SAX based and DOM based XML parsing?
SAX is event based. DOM is tree navigation based.

29. When would you use one over the other?
SAX for XML based event processing. Large documents or memory constrained System.
DOM for XML document editing.

30. Tell about any XML binding tools you've used, or any other parsing techniques.
JAXB (Marschalling and UnMarshalling, Factory)....(?)

31. Schema and DTD
?????

32. What must a class do to implement an interface?
It must provide all of the methods in the interface and identify the interface in its implements clause.

33. What is an interface and what are they used for?
a. Capturing similarities among unrelated classes without arficially forcing a class relationship.
b. Declaring methods that one or more classes are expected to implement.
c. Revealing an object's programming interface without revealing its class.

34. Let's make up a system where we need to track electricity usage in a building. We have some objects that consume electricity (Monitor and Printer). We want to add an interface to the system that will define a method for determining the monitor or printer's electrical consumption.

Question: What should be a good name for this interface?
Answer: (通常是形容詞)something like Powerable, PluggedIn, ElectricityConsumer
Question: What would be a good name for a method in this interface and what would the method do?
Answer: (通常是動詞)getConsumption() returns the amount of power consumed.
Question: Let's create an Exception that will be thrown by the getConsumption method when the object is not plugged in. What's good name for that exception?
Answer: NotPluggedInException. PlugInFailException.

35.

2010年9月27日 星期一

HashMap, HashSet, HashTable 等等的 Hash Collection

Hashtable類
Hashtable繼承Map接口,實現一個key-value映射的哈希表。任何非空(non-null)的對象都可作為key或者value
添加數據使用put(key, value),取出數據使用get(key),這兩個基本操作的時間開銷為常數。
Hashtable通過initial capacity和load factor兩個參數調整性能。通常缺省的load factor 0.75較好地實現了時間和空間的均衡。增大load factor可以節省空間但相應的查找時間將增大,這會影響像get和put這樣的操作。
使用Hashtable的簡單示例如下,將1,2,3放到Hashtable中,他們的key分別是”one”,”two”,”three”:
Hashtable numbers = new Hashtable();
numbers.put(“one”, new Integer(1));
numbers.put(“two”, new Integer(2));
numbers.put(“three”, new Integer(3));
要取出一個數,比如2,用相應的key:
Integer n = (Integer)numbers.get(“two”);
System.out.println(“two = ” + n);
由於作為key的對象將通過計算其散列函數來確定與之對應的value的位置,因此任何作為key的對象都必須實現hashCode和equals方 法。hashCode和equals方法繼承自根類Object,如果你用自定義的類當作key的話,要相當小心,按照散列函數的定義,如果兩個對象相 同,即obj1.equals(obj2)=true,則它們的hashCode必須相同,但如果兩個對象不同,則它們的hashCode不一定不同,如 果兩個不同對象的hashCode相同,這種現象稱為沖突,沖突會導致操作哈希表的時間開銷增大,所以盡量定義好的hashCode()方法,能加快哈希 表的操作。
如果相同的對象有不同的hashCode,對哈希表的操作會出現意想不到的結果(期待的get方法返回null),要避免這種問題,只需要牢記一條:要同時複寫equals方法和hashCode方法,而不要只寫其中一個。
Hashtable是同步的。

HashMap類
HashMap和Hashtable類似,不同之處在於HashMap是非同步的,並且允許null,即null value和null key。但是將HashMap視為Collection時(values()方法可返回Collection),其叠代子操作時間開銷和HashMap 的容量成比例。因此,如果叠代操作的性能相當重要的話,不要將HashMap的初始化容量設得過高,或者load factor過低。

WeakHashMap類
WeakHashMap是一種改進的HashMap,它對key實行“弱引用”,如果一個key不再被外部所引用,那麽該key可以被GC回收。



HashSet請參考對Set的描述

Set是一種不包含重複的元素的Collection,即任意的兩個元素e1和e2都有e1.equals(e2)=false,Set最多有一個null元素。
Set的構造函數有一個約束條件,傳入的Collection參數不能包含重複的元素。  
請註意:必須小心操作可變對象(Mutable Object)。如果一個Set中的可變元素改變了自身狀態導致Object.equals(Object)=true將導致一些問題。
兩個通用Set實現是HashSet 和TreeSet。要決定用哪一個,那是非常簡單明了的。 HashSet 要快得多 (對大多數操作是常數時間之於對數時間(constant time vs. log time)), 但不提供排序保證。如果你需要使用 SortedSet 中的操作,或者按順序叠代對你來說是重要的,那麽請使用 TreeSet。 否則,使用 HashSet。 在大多數時間都不使用 HashSet ,對你來說是個公平的賭博。

關於 HashSet,有一件事應該牢記,即就條目數和容量之和來講,叠代是線性的。因此,如果叠代性能很重要,那就應該慎重選擇一個適當的初始容量。容量選得 太大,既浪費空間,也浪費時間。 默認的初試容量是101, 一般來講,它比你所需要的要多。可以使用 int 構造函數來指定初始容量。要分配 HashSet 的初始容量為17:

Set s= new HashSet(17);

HashSets 另有一個稱作 裝載因數(load factor) 的"調整參數(tuning parameter)" 。如果你非常在乎你的 HashSet 的空間的使用,請閱讀 HashSet 文本以獲取詳細信息。否則,就使用默認值吧。如果你接受默認裝載因數,但你確實又想指定初始容量,那麽,選一個大約是你期望你的 Set 將增長到的容量的兩倍的數。如果你的猜測不著邊,它也可以增長,或只是浪費一點空間。但都沒有大問題。如果你知道有關正確尺寸的一個最佳值,用它吧;如果 不知道,那就使用一個舊的值,或使用一個偶數值。它真的不是非常重要。這些事情只能使 HashSet 稍稍變好一點點。

TreeSet 沒有調整參數。除 clone 之外,HashSet 和 TreeSet 都僅有那些由它們各自的接口所要求的操作 (Set 和 TreeSet),而沒有任何別的操作。



******************************* 我 是 分 隔 線 *******************************

http://www.pakzilla.com/2009/08/24/hashmap-vs-hashtable-vs-hashset/

Hashtable

Hashtable is basically a datastructure to retain values of key-value pair.

  • It didn’t allow null for both key and value. You will get NullPointerException if you add null value.
  • It is synchronized. So it comes with its cost. Only one thread can access in one time
Hashtable;
cityTable = new Hashtable();
cityTable.put(1, "Lahore");
cityTable.put(2, "Karachi");
cityTable.put(3, null); /* NullPointerEcxeption at runtime*/

System.out.println(cityTable.get(1));
System.out.println(cityTable.get(2));
System.out.println(cityTable.get(3));

HashMap

Like Hashtable it also accepts key value pair.

  • It allows null for both key and value
  • It is unsynchronized. So come up with better performance
HashMap productMap = new HashMap();
productMap.put(1, "Keys");
productMap.put(2, null);

HashSet

HashSet does not allow duplicate values. It provides add method rather put method. You also use its contain method to check whether the object is already available in HashSet. HashSet can be used where you want to maintain a unique list.

HashSet stateSet = new HashSet();
stateSet.add ("CA");
stateSet.add ("WI");
stateSet.add ("NY");

if (stateSet.contains("PB")) /* if CA, it will not add but shows following message*/
System.out.println("Already found");
else
stateSet.add("PB");

2010年9月26日 星期日

Java Serializable (String object is serialized)

Java中,什麽時候不能用Serializable?

舉個例子,你編寫了一款遊戲,保存記錄時把所有狀態一一保存非常麻煩,這時就可以使用Serializable(序列化接口),它的作用是可以將一個對象實例序列化,序列化後你可以選擇將它保存在你需要的位置。相對的,讀取後生成的對象所有屬性(除了設置為瞬時值的屬性)將和原對象的屬性相同(只是內存地址不同)。這樣可以方便的將一個java對象寫入到磁盤中,保存該對象的所有狀態!值得註意的是序列化的對象中包含的屬性和其他對象都需要實現序列化接口,不然無法正常序列化!在hibernate裡,並非所有的實體類必須實現序列化接口,因為在hibernate中我們通常是將基本類型的數值映射為數據庫中的字段。而基礎類型都實現了序列化接口(String也實現了)。所以,只有在想將一個對象完整存進數據庫(存儲為二進制碼),而不是將對象的屬性分別存進數據庫,讀取時再重新構建的話,就可以不用實現序列化接口。

2010年9月25日 星期六

Java Boxing(裝箱) and Unboxing(拆箱) (繼堆積堆疊之後)

Boxing(裝箱)跟Unboxing(拆箱)的關係在講之前還要再提一個萬物之母的類別 "Object"
Object是一種參考型別,也是所以類別的源頭。因此Object可以指向任何的參考型別。
但是當Object指向數值型別時,那會怎麼樣?

int
數值 = 100 ;
object o = 數值 ;

參考型別是擺在堆積裡,數值型別是擺在堆疊裡。那...Object指向數值型別到底該擺哪?

這個時候,就會將100從堆疊中複製一份到堆積中的盒子裡,然後o這個物件參考指向這個盒子。這種將堆疊中的值複製到堆積中的行為,就叫Boxing(裝箱)。反過來說,將堆積中的值,複製到堆疊中的行為,就叫Unboxing(拆箱)

int 值 = (int) o ; // 將o拆箱


Java Stack(堆疊, 棧) and Heap(堆積, 堆)

stack 和 heep 都是內存的一部分
stack 空間小,速度比較快, 用來放對象的引用
heep 大,一般所有創建的對象都放在這里。

堆疊(stack)可以想像成一個一個疊起來的盒子,數值型別的變數就一個一個放在盒子內。當變數生命周期結束時,盒子就會被移走。

堆積(heap)就像一個空地內亂七八糟的擺了一堆盒子,然後盒子上有標明這個盒子目前是屬於誰在使用的(可以很多人使用同一個盒子)。每當new 出一個物件,例如: Customer c = new Customer(); 物件參照 c 就擺放在堆疊中的盒子裡,而new出來的物件Customer()就在堆積中找一個沒人用的空盒子來擺。當c的生命周期結束,也就是Customer()沒人使用時,堆積中的盒子就會被註明為沒人使用,系統會不定時的把沒人使用的盒子清空。

棧(stack): 是一個先進後出的數據結構,通常用於保存方法(函數)中的參數,局部變量.
在java中,所有基本類型和引用類型都在棧中存儲.棧中數據的生存空間一般在當前scopes內(就是由{...}括起來的區域).
堆(heap):是一個可動態申請的內存空間(其記錄空閑內存空間的鏈表由操作系統維護),C中的malloc語句所產生的內存空間就在堆中.
在java中,所有使用new xxx()構造出來的對象都在堆中存儲,當垃圾回收器檢測到某對象未被引用,則自動銷毀該對象.所以,理論上說java中對象的生存空間是沒有限制的,只要有引用類型指向它,則它就可以在任意地方被使用.

差別:
1. 棧(stack)與堆(heap)都是Java用來在Ram中存放數據的地方。與C++不同,Java自動管理棧和堆,程序員不能直接地設置棧或堆。
2. 棧的優勢是,存取速度比堆要快,僅次於直接位於CPU中的寄存器。但缺點是,存在棧中的數據大小與生存期必須是確定的,缺乏靈活性。另外,棧數據可以共享,詳見第3點。堆的優勢是可以動態地分配內存大小,生存期也不必事先告訴編譯器,Java的垃圾收集器會自動收走這些不再使用的數據。但缺點是,由於要在運行時動態分配內存,存取速度較慢。
3. Java中的數據類型有兩種。
一種是基本類型(primitive types), 共有8種,即int, short, long, byte, float, double, boolean, char(註意,並沒有string的基本類型)。這種類型的定義是通過諸如int a = 3; long b = 255L;的形式來定義的,稱為自動變量。值得註意的是,自動變量存的是字面值,不是類的實例,即不是類的引用,這里並沒有類的存在。如int a = 3; 這里的a是一個指向int類型的引用,指向3這個字面值。這些字面值的數據,由於大小可知,生存期可知(這些字面值固定定義在某個程序塊里面,程序塊退出後,字段值就消失了),出於追求速度的原因,就存在於棧中
另外,棧有一個很重要的特殊性,就是存在棧中的數據可以共享。假設我們同時定義:
int a = 3;
int b = 3;
編譯器先處理int a = 3;首先它會在棧中創建一個變量為a的引用,然後查找有沒有字面值為3的地址,沒找到,就開辟一個存放3這個字面值的地址,然後將a指向3的地址。接著處理int b = 3;在創建完b的引用變量後,由於在棧中已經有3這個字面值,便將b直接指向3的地址。
這樣,就出現了a與b同時均指向3的情況。特別註意的是,這種字面值的引用與類對象的引用不同。
假定兩個類對象的引用同時指向一個對象,如果一個對象引用變量修改了這個對象的內部狀態,那麽另一個對象引用變量也即刻反映出這個變化。
相反,通過字面值的引用來修改其值,不會導致另一個指向此字面值的引用的值也跟著改變的情況。
如上例,我們定義完a與b的值後,再令a=4;那麽,b不會等於4,還是等於3。在編譯器內部,遇到a=4;時,它就會重新搜索棧中是否有4的字面值,如果沒有,重新開辟地址存放4的值;如果已經有了,則直接將a指向這個地址。因此a值的改變不會影響到b的值。
另一種是包裝類數據,如Integer, String, Double等將相應的基本數據類型包裝起來的類。這些類數據全部存在於堆中,Java用new()語句來顯示地告訴編譯器,在運行時才根據需要動態創建,因此比較靈活,但缺點是要占用更多的時間。
4.String是一個特殊的包裝類數據。即可以用String str = new String("abc");的形式來創建,也可以用String str = "abc";的形式來創建(作為對比,在JDK 5.0之前,你從未見過Integer i = 3;的表達式,因為類與字面值是不能通用的,除了String。而在JDK 5.0中,這種表達式是可以的!因為編譯器在後臺進行Integer i = new Integer(3)的轉換!)。
前者是規範的類的創建過程,即在Java中,一切都是對象,而對象是類的實例,全部通過new()的形式來創建。Java中的有些類,如DateFormat類,可以通過該類的 getInstance()方法來返回一個新創建的類,似乎違反了此原則。其實不然。該類運用了單例模式來返回類的實例,只不過這個實例是在該類內部通過 new()來創建的,而getInstance()向外部隱藏了此細節。那為什麽在String str = "abc";中,並沒有通過new()來創建實例,是不是違反了上述原則?其實沒有。

# public class Test {
# public static void main(String[] args) {
# String str1 = "abc";
# String str2 = "abc";
# String str3 = new String("abc");
# String str4 = new String("abc");
# //str1 str2
# if(str1 == str2) {
# System.out.println("str1 and str2 is stored as stack");
# }
# else {
# System.out.println("str1 and str2 is stored as heap");
# }
# //str3 str4
# if(str3 == str4) {
# System.out.println("str3 and str4 is stored as stack");
# }
# else {
# System.out.println("str3 and str4 stored as heap");
# }
# }
# }



运行结果如下:
str1 and str2 is stored as stack
str3 and str4 stored as heap

產生這種結果的原因:
1.編譯器在處理String str1="abc"時,會首先在棧中創建一個變量"abc",然後用str1指向"abc",然後處理String str2="abc",編譯器查找棧中已經存在了變量"abc",直接將str2指向已經存在的"abc"變量,所以str1==str2執行結果為 true;
2.編譯器在處理String str3=new String("abc")時,在堆中創建一個新的"abc"對象,然後用str3指向這個對象,然後處理String str4=new String("abc"),在堆中再次創建一個新的"abc"對象,然後用str4指向這個對象,所以str3和str4分別為不同對象的引用,執行 str3==str4為false;

Thread-Safe的理解與分析

⓪原創: 蕭沖
http://aftcast.pixnet.net/blog/post/23786004

何謂thread-safe? 這個問題我看過許多論壇都有討論過,都總讓人覺得不很滿意。在此,筆者想要用更logical的方式來把議題說清楚。首先,我要了解它的定義! 定義若都不明白就難以判別安不安全了!

thread是什麼呢? 可能也有人不太了解。就從這裡開始… 當cpu處理一段(區塊)的程式碼時,從開始的第一行程式碼來跑就算是thead的開始,直到區塊的最後一行程式結束,就算是thread的結束。所謂的「主thread」,在dos (或dos like)程式裡,就是指main( )這個函式的開始到結束的一個thread。而主thread以外的一個子thread則是指程式人員自行在主thread裡再定義一個「程式區塊」,並請cpu同步的去執行那個區塊。

由上面的thread的定義來看,我們可以進而推論所謂的multithread這個字其實是有三種情形的,哪三種呢?
1/ 相同的一個程式區塊,請cpu"分出多身"來執行它!
2/ 不同的程式區塊,請cpu各別分時的去執行每個區塊
3/ 混合以上二種情形

所以,當我們在討論多緒/多線程(multithread)的問題時,我們要先去了解問題是上面三類的哪一類。許多的情形下,都是指第一類!

我們再把「程式區塊」給解析一下。它可以是一個function,或是一個class,或是上述二者的混合體。因為function或是class都會使用到變數,於是多緒時變數的共享就成了一個很大的問題。這就是為什麼會有thread-safe的這個議題了!

到此為止,我們可以想像若一個程序(process / 主thread)裡,有大於等於一個子thread在跑,就會產生thread-safe的問題。以最簡單的情形來說,mainthread+user自定的一個thread。假設Button元件按下後會寫入一個item至memo元件裡,而同時間的一個thread則會取用memo裡的item。假想當thread在取用item做分析的時候,user不知情的按下button,那麼thread是否有可能會取到不正確的item? 若不經過特別的安全設定,肯定「取用」時時而會出問題!

因此,到底安全或不安全的根源就在那執行的區塊程式碼上了(以上例就是取用的過程)。我要補充一個重要的事,其實每一個thread都有自己的一個專屬stack,所以auto級(local)的區域變數是不會有共享的問題,因為它們都是存放在thread各自的記憶體空間內,彼此不甘擾。也就是說,若你的程式區塊中,所有使用到的變數都是local(auto)變數,那你這個區塊,或說這個thread,就算是thread-safe! 相反的,若你的區塊中有用到全域的變數,那麼你的這個thread就有可能是不安全。請注意看,是有可能,並非一定是。

如何把含有全域變數的thread分析出安全或不安全?其實這是很直覺的。比如說某全域變數int g被thread使用到,但整個thread裡只參考到一次,那算安全嗎? 答案是…安全。因為單一基本變數的一次存取cpu處理極快,不太會有衝突。又,若是某全域變數 struct tag 被參考到一次,那算安全嗎? 答案是…不太安全,因為一個結構體的存取可能涉及到多個微指令。進一步的用上面的例子來說,若int g被參考到2次(含)以上,那就肯定不安全了。比如說第一次是把g設成k,第二次把g再設給某變數i,若thread1正在處理第二次參考,而thread2在處理第一次參考。那thread1可能會得到意外的答案!

如何讓不安全的thread變成安全的?? 其實主要的方法有二類。


1/
存取共用全域變數時加上lock的機制,而這lock的機制在windows上可以使用mutex、criticalsection、event、semaphore等物件配合WaitForSingleObject或WaitForMultipleObject二個api來控制。其原理就是當某thread在取用資料時,其他的通通都停止並等待,直到該thread取用完。

2/ 把存取全域變數的動作通通交給某一個thread全全處理。比如說你有thread1,thread2,thread3。當要存取全域的struct變數時,thread2就把工作交給thread1做,然後自己停住等thread1完成,thread3也把工作交給thread1做,並等待… 。這原理應該容易理解,因為不安全的工作全都交給"單一"的thread來處理時,那份工作就安全了呀!當然,這也不禁讓我們覺得,這樣效能非常的差! 通通都在等thread1。 不過還好的是,若少少的用還ok,若許多的工作都交給某一thread順序來處理,那就真的沒意義了!而這種方式其實就是bcb或delphi裡的synchronize這個方法的處理方式!

後註: class 其實也像是一種function,所以class本身也是存在著安全與否的問題。倘若該class裡的menthod有用到全域的變數時,該class也算是不安全的! 而許多的VCL就是這類的class!

註2:
若什麼是auto變數、stack都還不清楚,請先自行google或查程式語言的書,這是很基本且重要但易被忽略的章節。

local variable vs instance variable (跟 Multi-thread 有關)

class A{       

}

class B{
/*
* B declare 'a' ---is Instance Variable and its Reference Type is A,
*
*/

A a;

public
void setLocalVariable(int i){
int a=0;//a is Local Variables
a=i;
System.out.println(a);//印出來會是i的值不是null
}


}


2010年9月23日 星期四

Hibernate in Eclipse

如何於Eclipse使用Hibernate Tools --- Eclipse 匯入Hibernate Tools 步驟

1. eclipse 版本: Eclipse IDE for Java EE Developers [Ganymede Packages (based on Eclipse 3.4)]

2. 下載 eclipse 後安裝完成後,開啟 Help ->
Software Updates and Add-ones -> Available Software

3.新增 Hibernate Tools plugins Update site : 點選 Add Site -> 輸入下列URL http://download.jboss.org/jbosstools/updates/stable/ -> 點選 OK
完成後會於 update site 清單中新增一筆被選取的資料

4. 開啟 http://download.jboss.org/jbosstools/updates/stable/ 的 Tree ,勾選 JBossTools Stable Release: 2.2.2.GA
點選 Install the selected items
出現安裝清單 -> 點選 Next -> 點選接收 License 聲明 -> 點選 Finish ->即刻開始下載安裝

5. 安裝完成後 eclipse 會提示重開,點選確定,待重開完成後即可使用

6.於 File -> New -> Others 看到以下選項,則確認成功


7. 也可以使用 Eclipse IDE for Java Developers 這個版本的eclipse ,但須多下載很多相依的 plugins ,比較花時間

2010年9月20日 星期一

Java Diagrams

Example 1:

The School System provides the following functions:
· Create course by teacher
· Enroll course for student
· Cancel course by teacher
· Register for user
· Modify the personal information
· View the Course information (number of students enrolled and teacher information of the course)








































Example 2:
Online test data flow diagram~

2010年9月15日 星期三

SQL (Join)

BASIC 概念

在我們介紹連接(join)的概念。要瞭解連接,我們需要用到許多我們之前已介紹過的指令。 我們先假設我們有以下的兩個表格,

Store_Information 表格

store_name Sales Date
Los Angeles $1500 Jan-05-1999
San Diego $250 Jan-07-1999
Los Angeles $300 Jan-08-1999
Boston $700 Jan-08-1999

Geography 表格
region_name store_name
East Boston
East New York
West Los Angeles
West San Diego

而我們要知道每一區 (region_name) 的營業額 (sales)。 Geography 這個表格 告訴我們每一區有哪些店,而 Store_Information 告訴我們每一個店的營業額。 若我們要知道每一區的營業額,我們需要將這兩個不同表格中的資料串聯起來。當我們仔細瞭解這兩個 表格後,我們會發現它們可經由一個相同的欄位,store_name,連接起來。我們先將 SQL 句列出, 之後再討論每一個子句的意義:

SELECT A1.region_name REGION, SUM(A2.Sales) SALES
FROM Geography A1, Store_Information A2
WHERE A1.store_name = A2.store_name
GROUP BY A1.region_name

結果:

REGIONSALES
East$700
West$2050

在第一行中,我們告訴 SQL 去選出兩個欄位:第一個欄位是 Geography 表格中的 region_name 欄位 (我們取了一個別名叫做 REGION);第二個欄位是 Store_Information 表格 中的 sales 欄位 (別名為 SALES)。請注意在這裡我們有用到表格別名:Geography 表格的 別名是 A1,Store_Information 表格的別名是 A2。若我們沒有用表格別名的話, 第一行就會變成

SELECT Geography.region_name REGION, SUM(Store_Information.Sales) SALES

很明顯地,這就複雜多了。在這裡我們可以看到表格別名的功用:它能讓 SQL 句容易被瞭解, 尤其是這個 SQL 句含蓋好幾個不同的表格時。

接下來我們看第三行,就是 WHERE 子句。 這是我們闡述連接條件的地方。在這裡,我們要確認 Geography 表格中 store_name 欄位的值與 Store_Information 表格中 store_name 欄位的值是相等的。 這個 WHERE 子句是一個連接的靈魂人物,因為它的角色是確定兩個 表格之間的連接是正確的。如果 WHERE 子句是錯誤的, 我們就極可能得到一個笛卡兒連接 (Cartesian join)。笛卡兒連接會造成我們得到所有兩個表格 每兩行之間所有可能的組合。在這個例子中,笛卡兒連接會讓我們得到 4 x 4 = 16 行的結果。


Outer Join

前我們看到的左連接 (left join),又稱內部連接 (inner join)。在這個情況下,要 兩個表格內都有同樣的值,那一筆資料才會被選出。那如果我們想要列出一個表格中每一筆的資料, 無論它的值在另一個表格中有沒有出現,那該怎麼辦呢?在這個時候,我們就需要用到 SQL OUTER JOIN (外部連接) 的指令。

外部連接的語法是依資料庫的不同而有所不同的。舉例來說,在 Oracle 上, 我們會在 WHERE 子句中要選出所有資料的那個表格之後加上一個 "(+)" 來代表說這個表格中的所有資料我們都要。

假設我們有以下的兩個表格:

Store_Information 表格

store_name Sales Date
Los Angeles $1500 Jan-05-1999
San Diego $250 Jan-07-1999
Los Angeles $300 Jan-08-1999
Boston $700 Jan-08-1999

Geography 表格
region_name store_name
East Boston
East New York
West Los Angeles
West San Diego

我們需要知道每一間店的營業額。如果我們用一個普通的連接,我們將會漏失掉 'New York'這個店,因為它並不存在於 Store_Information 這個表格。 所以,在這個情況下,我們需要用外部連接來串聯這兩個表格:

SELECT A1.store_name, SUM(A2.Sales) SALES
FROM Georgraphy A1, Store_Information A2
WHERE A1.store_name = A2.store_name
(+)
GROUP BY A1.store_name

我們在這裡是使用了 Oracle 的外部連接語法。

結果:

store_nameSALES
Boston$700
New York
Los Angeles$1800
San Diego$250

請注意: 當第二個表格沒有相對的資料時, SQL 會傳回 NULL 值。在這一個例子中, 'New York' 並不存在於 Store_Information 表格,所以它的 "SALES" 欄位是 NULL.

SQL (Union 和 Union All)

http://www.1keydata.com/tw/sql/sqlunionall.html

UNION
指令的目的是將兩個 SQL 語句的結果合併起來。 從這個角度來看, UNIONJOIN 有些許類似,因為這兩個指令都可以 由多個表格中擷取資料。 UNION 的一個限制是兩個 SQL 語句所產生 的欄位需要是同樣的資料種類。另外,當我們用 UNION 這個指令 時,我們只會看到不同的資料值 (類似 SELECT DISTINCT)。

UNION 的語法如下:

[SQL 語句 1]
UNION
[SQL 語句 2]


假設我們有以下的兩個表格,

Store_Information 表格

store_name Sales Date
Los Angeles $1500 Jan-05-1999
San Diego $250 Jan-07-1999
Los Angeles $300 Jan-08-1999
Boston $700 Jan-08-1999

Internet_Sales 表格

Date Sales
Jan-07-1999 $250
Jan-10-1999 $535
Jan-11-1999 $320
Jan-12-1999 $750

而我們要找出來所有有營業額 (sales) 的日子。要達到這個目的,我們用以下的 SQL 語句:

SELECT Date FROM Store_Information
UNION
SELECT Date FROM Internet_Sales

結果:

Date
Jan-05-1999
Jan-07-1999
Jan-08-1999
Jan-10-1999
Jan-11-1999
Jan-12-1999

有一點值得注意的是,如果我們在任何一個 SQL 語句 (或是兩句都一起) 用 "SELECT DISTINCT Date" 的話,那我們會得到完全一樣的結果。

*************************************************************************************

UNION ALL 這個指令的目的也是要將兩個 SQL 語句的結果 合併在一起。 UNION ALLUNION 不同 之處在於 UNION ALL 會將每一筆符合條件的資料都列出來,無論資料值 有無重複。

UNION ALL 的語法如下:

[SQL 語句 1]
UNION ALL
[SQL 語句 2]

我們用和上一頁同樣的例子來顯示出 UNION ALLUNION 的不同。同樣假設我們有以下兩個表格,

Store_Information 表格

store_name Sales Date
Los Angeles $1500 Jan-05-1999
San Diego $250 Jan-07-1999
Los Angeles $300 Jan-08-1999
Boston $700 Jan-08-1999

Internet_Sales 表格

Date Sales
Jan-07-1999 $250
Jan-10-1999 $535
Jan-11-1999 $320
Jan-12-1999 $750

而我們要找出有店面營業額以及網路營業額的日子。要達到這個目的,我們用以下的 SQL 語句:

SELECT Date FROM Store_Information
UNION ALL
SELECT Date FROM Internet_Sales

結果:

Date
Jan-05-1999
Jan-07-1999
Jan-08-1999
Jan-08-1999
Jan-07-1999
Jan-10-1999
Jan-11-1999
Jan-12-1999

Static Method/Field 的意義與實作方式 (蔡學鏞)

http://www.oreilly.com.tw/column_sleepless.php?id=j021

「將某 class 產生出一個 instance 之後,此 class 所有的 instance field 都會新增一份,那麼所有的 instance method 是否也會新增一份?」我常常看到網路上有人在討論此問題,所以寫了這篇文章,以為解釋。

Member 的種類
類別(class)的內部組成統稱為成員(member),如果依據成員是「資料」還是「程式」來區分,可以分成:
  • 資料,被稱為 field
  • 程式,被稱為 method
如果再依據有無使用 static 修飾而細分,則成員可細分成四種:
  • class field:有用 static 修飾的 field
  • class method:有用 static 修飾的 method
  • instance field:沒有用 static 修飾的 field
  • instance method:沒有用 static 修飾的 method
顧名思義,class field/method 和 class 本身有密切的關係,而 instance field/method 則與 instance(也就是物件)有密切的關係。請看下面的範例程式。

public class Class1 {
public static int classField;
public static void classMethod1() {
// ...
}
public static void classMethod2() {
// ...
}
public int instanceField;
public void instanceMethod1() {
// ...
}
public void instanceMethod2() {
// ...
}
}
public class Class2 {
public static void classMethod () {
// ...
}
public void instanceMethod() {
// ...
}
}

Field
宣告 field 時,如果前面加上 static 的修飾字,就會使得此 field 變成是 class field。一個 class field 永遠只佔用一塊記憶體,而且此記憶體空間是在此 class 一被載入(load)記憶體之後就立刻配置的(allocate),感覺就如同此 field 與該 class 本身相關,而不是與該 class 的 instance 相關。class field 可以被同一個 class 的 class method 內部所直接使用,舉例來說,上述的 classMethod1() 內部可以出現 classField。如果 Class1 的 class method 或 instance method 欲使用到 Class2 的 class field,就必須在前面冠上 Class2,例如:Class2.classField。

宣告field時,如果前面「不」加上 static 的修飾字,就會使得此 field 變成是 instance field。對 instance field 而言,每產生一個instance(物件)就多一塊 instance field 的記憶體,每少一個 instance 就少一塊 instance field 的記憶體。instance field 可以被同一個 instanc e的 instance method 內部所直接使用,舉例來說,上述的 instanceMethod1() 內部可以出現 instanceField。如果某 class 的class method 或 instance method 欲使用到某 instance 的 instance field,就必須在前面冠上 instance 名稱,例如:obj.classField。

Method
宣告 method 時,如果前面加上 static 的修飾字,就會使得此 method 變成是 class method。對 class method 而言,永遠只佔用一塊記憶體,而且此記憶體空間是在此 class 一被載入進記憶體之後就立刻配置的,就如同此 method 是與該 class 本身相關,而不是與該 class 的 instance 相關。class method 可以被同一個 class 的任何 class method 內部所直接使用,舉例來說,上述的classMethod1() 內部可以出現 classMethod2()。如果 Class1 的 class method 或 instance method 欲使用到 Class2 的 classMethod(),就必須在前面冠上 Class2,也就是 Class2.classMethod()。

宣告 method 時,如果前面「不」加上 static 的修飾字,就會使得此 method 變成是 instance method。對 instance method 而言,每產生一個 instance「並不會」多一塊 instance method 的記憶體。同一個 method 不管被調用(invoke)幾次,也不管被調用時的instance 是何者,每次的程式碼完全都一樣,差別只在每次執行時資料不同,而資料是存放在 call stack 中,所以不會混淆。在 instance method 內,資料的來源包括了參數和 instance field。參數被傳進來變成 call stack 內的 entry,所以不會混淆,這很容易理解,但是 instance field 是如何區隔開來的(前面剛提過:instance field 會隨著 instance 數目增加而增加),這是透過隱匿(implicit)的 this 參數來達到了,稍後會有說明。instance method 可以被同一個 instance 的 instance method 內部所直接使用,舉例來說,上述的 instanceMethod1() 內部可以出現 instanceMethod2()。如果某 class 的 class method 或 instance method 欲使用到某 instance 的某 instance method,就必須在前面冠上此 instance 名稱,例如:obj.classMethod()。

隱匿的 this 參數
綜合上面的敘述來看:
  • class field:共用一塊記憶體
  • class method:共用一塊記憶體
  • instance field:隨著每個 instance 各有一塊記憶體
  • instance method:共用一塊記憶體
instance method 為什麼不是隨著每個 instance 佔有一塊記憶體,反倒是共用一塊記憶體?其實,讓每個 instance method 如同instance field 一樣,隨著每個 instance 佔有一塊記憶體,這麼做當然是可以的,只是 Java 編譯器和 JVM 都不這麼做,因為太浪費記憶體空間了。一個 field 少則佔用一個 byte,多則佔用數百 Byte,但是 method 少則數個 byte,多則數百 Kilo Byte。Mehtod耗費的記憶體是 field 的數百倍,甚至數千倍,當然是能共用就盡量共用,比較不會消耗記憶體。既然 JVM 讓一個 class 的所有instance 共用相同的 instance method,下面兩行程式碼在 instanceMethod() 內部時,如何區分是 instance1 或 instance2?

instance1.instanceMethod();
instance2.instanceMethod();

因為編譯器會幫我們在把 instance1 和 instance2 個別傳入 instanceMethod() 中當作第一個參數。也就是說,任何 instance method 參數的實際個數都會比表面上多一個,這個多出來的參數是由 Java 編譯器幫我們加上去的,用來代表對應的 instance。此參數的變數名稱為 this,也是 Java 的一個關鍵字(keyword)。

當調用某個 instance method 或使用某個 instance field 時,你必須在前面加上該 instance 的名稱,如果該 instance method/field 相關的 instance 和當時程式碼所在的 instance method 的 instance 指的是同一個 instance 時,該 instance 的名稱就是 this,這種情況下,你也可以選擇不在前面加上「this.」。

然而,在某些狀況下,非得在前面加上「this.」不可。例如,當method中的參數或區域變數和 instance field 名稱完全相同時,如果不在前面冠上「this.」,那麼指的是參數或區域變數;如果在前面冠上「this.」,那麼指的才是 instance field。


本文作者:蔡學鏞
張貼日期:09/09/2002

2010年9月14日 星期二

多型 (polymorphism), 多緒 (multithreading),回呼 (call-back)...etc


一旦函數可以被傳遞、被紀錄,這開啓了許多可能性,産生許多有趣的應用,特別是下列三者:

* 多型 (polymorphism):稍後再說明。
* 多緒 (multithreading):將函數指標傳進負責建立多緒的 API 中:例如 Win32 的 CreateThread(...pF...)。
* 回呼 (call-back):所謂的回呼機制就是:「當發生某事件時,自動呼叫某段程式碼」,Charles Petzold 稱此爲「Don’t Call Me, I'll Call You」。事件驅動 (event-driven) 的系統經常透過函數指標來實現回呼機制,例如 Win32 的 WinProc 其實就是一種回呼,用來處理視窗的訊息。

函數指標的致命缺點是:無法對參數 (parameter) 和返回值 (return value) 的型態進行檢查,因為函數已經退化成指標,指標是不帶有這些型態資訊的。少了型態檢查,當參數或返回值不一致時,會造成嚴重的錯誤。編譯器和虛擬機器 (VM) 並不會幫我們找出函數指標這樣的致命錯誤。所以,許多新的程式語言不支援函數指標,而改用其他方式。

多型 (polymorphism)

多型的實現方式很複雜,大致上是編譯器或 VM 在資料結構內加入一個資料指標,此指標通常稱爲 vptr,是 Virtual Table Pointer 的意思。vptr 指向一個 Virtual Table,此 Virtual Table 是一個陣列 (array),由許多函數指標所組成,每個函數指標各自指向一個函數的地址。如圖 1 所示。

對 1

不管是 C++ 編譯器、或是 Java VM、或是 .NET CLR,內部都是以此方式來實現多型。儘管如此,這只能算是 black magic,對於 C++、Java 與 .NET 語言來說,函數指標「並未因此」和語言本身有直接相關。換句話說,C++ 和 Java 與 .NET 語言,就算語法本身不支援函數指標,照樣也能實現多型。事實上,C++ 固然支援函數指標,但不是爲了多型的關係,而是爲了和 C 相容 (畢竟 C++ 是 C 的 superset);IL Asm (.NET 上的組合語言) 固然支援函數指標,但由於安全的理由,使用上受到相當大的限制,且不是爲了多型的關係。至於 Java 與 C# 則都不支援函數指標。

沒 錯,Java 與 C# 都不支援函數指標。雖然剛剛解釋過,這不會影響對於多型的支援,但是這會不會影響對於多緒 (multithreading) 與回呼 (call-back) 機制的支援呢?答案是:不會!因為 Java 可以利用多型或反映 (reflection) 來實現多緒與回呼,而 C#可 以利用多型或反映或委託 (delegate) 來實現多緒與回呼。


反映(reflection)

顧名思義,反映 (reflection) 機制就像是在吳承恩所著的西遊記中所提及的「照妖鏡」,可以讓類別或物件 (object) 在執行時期「現出原形」。我們可以利用反映機制來深入瞭解某類別 (class) 的建構子 (constructor)、方法 (method)、欄位 (field),甚至可以改變欄位的值、呼叫方法、建立新的物件。有了反映機制,程式員即使對所欲使用的類別所知不多,也能照樣寫程式。反映機制能夠用來 呼叫方法,這正是反映機制能夠取代函數指標的原因。

以 Java 來說,java.lang.reflect.Method (以下簡稱 Method) 類別是用來表示某類別的某方法。我們可以透過 java.lang.Class (以下簡稱 Class) 類別的許多方法來取得 Method 物件。Method 類別提供 invoke() 方法,透過 invoke(),此 Method 物件所表示的方法可以被呼叫,所有的參數則是被組織成一個陣列,以方便傳入 invoke()。

舉個例子,下面是一個名為 Invoke 的程式,它會將命令列的 Java 類別名稱和要呼叫的方法名稱作為參數。為了簡單起見,我假定此方法是靜態的,且沒有參數:

=======================================
import java.lang.reflect.*;

class Invoke {
public static void main(String[] args ) {
try {
Class c = Class.forName( args[0] );
Method m = c.getMethod( args[1], new Class [] { } );
Object ret = m.invoke( null, null );
System.out.println(args[0] + "." + args[1] +"() = " + ret );
} catch ( ClassNotFoundException ex ) {
System.out.println("找不到此類別");
} catch (NoSuchMethodException ex ) {
System.out.println("此方法不存在");
} catch (IllegalAccessException ex ) {
System.out.println("沒有權限調用此方法");
} catch (InvocationTargetException ex ) {
System.out.println("調用此方法時發生下列例外:\n" +
ex.getTargetException() );
}
}

}
=======================================

我們可以執行 Invoke 來取得系統的時間:
java Invoke java.lang.System CurrentTimeMillis

執行的結果如下所示:
java.lang.System.currentTimeMillis() = 1049551169474

我們的第一步就是用名稱去尋找指定的 Class。我們用類別名稱 (命令列的第一個參數) 去呼叫 forName() 方法,然後用方法名稱 (命令列的第二個參數) 去取得方法。getMethod() 方法有兩個參數:第一個是方法名稱 (命令列的第二個參數),第二個是 Class 物件的陣列,這個陣例指明了方法的 signature (任何方法都可能會被多載,所以必須指定 signature 來分辨。) 因為我們的簡單程式只呼叫沒有參數的方法,我們建立一個 Class 物件的匿名空陣列。如果我們想要呼叫有參數的方法,我們可以傳遞一個類別陣列,陣列的內容是各個類別的型態,依順序排列。

一旦我們有了 Method 物件,就呼叫它的 invoke() 方法,這會造成我們的目標方法被調用,並且將結果以 Object 物件傳回。如果要對此物件做其他額外的事,你必須將它轉型為更精確的型態。

invoke() 方法的第一個參數就是我們想要呼叫目標方法的物件,如果該方法是靜態的,就沒有物件,所以我們把第一個參數設為 null,這就是我們範例中的情形。第二個參數是要傳給目標方法作為參數的物件陣列,它們的型態要符合呼叫 getMethod() 方法中所指定的型態。因為我們呼叫的方法沒有參數,所以我們傳遞 null 作為 invoke() 的第二個參數。

以上是 Java 的例子,事實上,.NET 的反映機制也相去不遠,不再贅述。反映機制是最動態的機制,比多型的功能更強大。然而,反映的速度比多型慢許多 (而且多型又比函數指標稍慢),所以若非必要,應該少用反映機制。事實上,不管是 Java API 或 .NET Framework,都不使用反映機制來實現回呼與多緒。

多緒 (multithreading)

Java沒有函數指標(為了系統安全),也不用反映機制來處理多緒(一方面為了效率,二方面反映機制是在JDK1.1才開始支援),而是使用多型的機制來處理多緒,作法如下:(另一種作法是實作java.lang.Runnable介面,與下面的作法雷同,不另說明。)

將執行緒的程式寫在下面的run()方法中:

class MyThread extends java.lang.Thread {
public void run() {
// ...
}

}

再利用下面的方式來啟動此執行緒:

MyThread thread = new MyThread();
thread.start();

start() 方法定義在 java.lang.Thread 類別內,start() 方法會請作業系統建立一個執行緒,再呼叫
run(),此時調用的並非在 java.lang.Thread 內定義的 run() (它是空的),而是利用多型機制,調用到 MyThread
內定義的 run()。

Java的回呼(Call Back)

通常回呼機制都是使用 publisher/subscriber (出版者/訂閱者) 的方式,必須先向系統註冊:

  • 何事件:我對何種事件感興趣
  • 何函數:當事件發生時,請呼叫我的函數,以爲通知。此函數即爲回呼函數 (call-back function)。

Java 也是使用類似的作法,差別在於 Java 無法利用函式指標,且採用物件導向的作法。Java 將出版者 (publisher) 稱爲事件來源 (event source),將訂閱者 (subscriber) 稱爲事件傾聽者 (event listener)。大致的作法如下:

  • 向事件來源註冊 (registry) 事件傾聽者
  • 該事件發生時,事件來源通知 (notify) 事件傾聽者

事件來源提供名爲 addXxxListener() 的方法來讓事件傾聽者註冊之用,此方法需要傳入事件傾聽者當參數。至於是何種事件,則由 Xxx 以爲識別。例如:addMouseListener() 表示註冊「滑鼠事件」的事件傾聽者。

利用 addXxxListener(),事件來源就可以將事件傾聽者記錄在欄位 (field) 中。當事件發生時,事件來源就可以從欄位中知道該通知和物件。可是應該呼叫該物件的那個方法呢?如果該物件沒有提供該方法呢?

想要解決此問題,事件來源就必須過濾註冊的對象,addXxxListener() 所需要的參數不可以是籠統的 java.lang.Object,而必須是一個實作 XxxListener 介面 (interface) 的物件。只要在 XxxListener 介面內宣告一個比方說 XxxEventHappened(),那麽任何實作 XxxListener 的物件,都必定有實現 XxxEventHappened(),所以事件來源就可以在事件發生時,呼叫事件傾聽者的 XxxEventHappened()。這正是依靠多型機制才能達成。

事件來源通知事件傾聽者時,往往需要夾帶一些額外的訊息,例如:事件來源是誰、事件發生於何時、事件發生的原因為何…。這些訊息被封裝成事件物件,當作參數傳給 XxxEventHappened()。

例如,我要向一個名為 jButton1 的 javax.swing.JButton 物件註冊,成為它的事件傾聽者,那麼就必須實作 java.awt.event.ActionListener 介面,提供 actionPerformed() 方法,如下所示:

class MyActionListener implements ActionListener {
public void actionPerformed(ActionEvent evt) {
// ...
}
}

註冊的方式如下:
MyActionListener mal = new MyActionListener();
jButton1.addActionListener(mal);

使用多型的機制來實現多緒和回呼,不但麻煩 (必須繼承),也不能使用靜態方法,因為靜態方法本來就沒有多型的機制 (static 一定是 non-virtual)。順便一提,前面所提到的反映機制,可以支援靜態方法 (static method)。


********************** 我 是 分 隔 線 *************************
更多關於Polymorphsim
http://www.inote.tw/2008/02/java-polymorphism.html
Polymorphism又稱為多型,他的討論要在類別間有繼承關係才有意義,而他的定義很少發現有人能一次說得很清楚,所以海芋就以幾句話來帶過他。

簡單來說,多型是指子類別繼承父類別時,同時改寫父類別的函式或變數,而我們可以宣告一個屬於父類別的變數,去存取子類別中改寫自父類別的函式或變數,這我們稱之為多型。

舉個生活一點的例子,若有一個父類別是動物,那麼有一個子類別鳥繼承自動物這個類別,當我們看到鳥的時侯,可以說牠是一隻鳥,也可以說牠是一隻動物。同樣的東西,卻有不同的表示型態。
而舉個程式碼而言:

而在此例子中,animal是宣告給父類別,所以他只能認識父類別擁有的函式或變數,所以他能存取「getLegs()」這個函式。
而另一個要記的重點是,父類別若轉成子類別需要靠強迫轉型,子類別轉成父類別則是屬於自動轉型,而兄弟類別之類亦可以使用強迫的方式來轉型喔!


2010年9月13日 星期一

Static Method (Java Notes)

Static/Class methods

There are two types of methods.

  • Instance methods are associated with an object and use the instance variables of that object. This is the default.
  • Static methods use no instance variables of any object of the class they are defined in. If you define a method to be static, you will be given a rude message by the compiler if you try to access any instance variables. You can access static variables, but except for constants, this is unusual. Static methods typically take all they data from parameters and compute something from those parameters, with no reference to variables. This is typical of methods which do some kind of generic calculation. A good example of this are the many utility methods in the predefined Math class.

Qualifying a static call

From outside the defining class, an instance method is called by prefixing it with an object, which is then passed as an implicit parameter to the instance method, eg, inputTF.setText("");

A static method is called by prefixing it with a class name, eg, Math.max(i,j);. Curiously, it can also be qualified with an object, which will be ignored, but the class of the object will be used.


Example

Here is a typical static method.

class MyUtils {
. . .
//================================================= mean
public static double mean(int[] p) {
int sum = 0; // sum of all the elements
for (int i=0; i

The only data this method uses or changes is from parameters (or local variables of course).


Why declare a method static

The above mean() method would work just as well if it wasn't declared static, as long as it was called from within the same class. If called from outside the class and it wasn't declared static, it would have to be qualified (uselessly) with an object. Even when used within the class, there are good reasons to define a method as static when it could be.

  • Documentation. Anyone seeing that a method is static will know how to call it (see below). Similarly, any programmer looking at the code will know that a static method can't interact with instance variables, which makes reading and debugging easier.
  • Efficiency. A compiler will usually produce slightly more efficient code because no implicit object parameter has to be passed to the method.

Calling static methods

There are two cases.

Called from within the same class
Just write the static method name. Eg,
// Called from inside the MyUtils class
double avgAtt = mean(attendance);
Called from outside the class
If a method (static or instance) is called from another class, something must be given before the method name to specify the class where the method is defined. For instance methods, this is the object that the method will access. For static methods, the class name should be specified. Eg,
// Called from outside the MyUtils class.
double avgAtt = MyUtils.mean(attendance);
If an object is specified before it, the object value will be ignored and the the class of the object will be used.

Accessing static variables

Altho a static method can't access instance variables, it can access static variables. A common use of static variables is to define "constants". Examples from the Java library are Math.PI or Color.RED. They are qualified with the class name, so you know they are static. Any method, static or not, can access static variables. Instance variables can be accessed only by instance methods.


Alternate call

What's a little peculiar, and not recommended, is that an object of a class may be used instead of the class name to access static methods. This is bad because it creates the impression that some instance variables in the object are used, but this isn't the case.


From Java Notes:(http://leepoint.net/notes-java/flow/methods/50static-methods.html)

Web Service~Java2WSDL or WSDL2Java?

Java2WSDL vs WSDL2Java its a long debate.

Theory: People say, it is better to have contract first and develop XSD. later generate code.

Reality:
1. Working on XML tools and generating XSD is painful process.
2. We never use simple data types in real projects
3. Dont have much time to do small POCs, when depending on WSDL2Java (Proof of Concepts)
4. Difficult to handle frequent changes

Reality: Do your work using Java coding. Develop all business objects, ..etc.
Once you are confident and ready to interface with other applications go with Java2WSDL.

Java2WSDL wins and saves time for developers.

Here is the Maven Java2WSDL plugin (cxf-java2ws-plugin) for your reference.

cxf-java2ws-plugin : http://cwiki.apache.org/CXF20DOC/maven-java2ws-plugin.html
WSDL Document Structure: http://www.w3schools.com/WSDL/wsdl_documents.asp


(from blog http://polimetla.com/2009/09/16/java2wsdl-vs-wsdl2java/)


2010年9月12日 星期日

JAVA-CORE 面試題

Question: How could Java classes direct program messages to the system console, but error messages, say to a file?

Answer: The class System has a variable out that represents the standard output, and the variable err that represents the standard error device. By default, they both point at the system console. This how the standard output could be re-directed:

Stream st = new Stream(new FileOutputStream("output.txt")); System.setErr(st); System.setOut(st);

Question: Why would you use a synchronized block vs. synchronized method?

Answer: Synchronized blocks place locks for shorter periods than synchronized methods.

Question: Explain the usage of the keyword transient?

Answer: This keyword indicates that the value of this member variable does not have to be serialized with the object. When the class will be de-serialized, this variable will be initialized with a default value of its data type (i.e. zero for integers).

Question: How can you force garbage collection?

Answer: You can't force GC, but could request it by calling System.gc(). JVM does not guarantee that GC will be started immediately.

Question: What's the difference between the methods sleep() and wait()

Answer: The code sleep(1000); puts thread aside for exactly one second. The code wait(1000), causes a wait of up to one second. A thread could stop waiting earlier if it receives the notify() or notifyAll() call. The method wait() is defined in the class Object and the method sleep() is defined in the class Thread.

Question: Can you call one constructor from another if a class has multiple constructors

Answer: Yes. Use this() syntax.

Question: How would you make a copy of an entire Java object with its state?

Answer: Have this class implement Cloneable interface and call its method clone().

clone() 預設是 重新配置一塊記憶體,並予以 copy ,
所以內容與原來的是一模一樣, 但是分屬不同的空間
所以 x.clone() 當然不等於 x


Inner Class 和 Nested Class

  1. What is nested class? - If all the methods of a inner class is static then it is a nested class.
  2. What is inner class? - If the methods of the inner class can only be accessed via the instance of the inner class, then it is called inner class.

Inner Classes 與 Nested Classes
[class-modifiers] class OuterClassName {
  ‥‥
  [inner-class-modifiers] class InnerClassName {
    ‥‥
  }
  [nested-class-modifiers] static class StaticClassName {
    ‥‥
  }
  ‥‥
}


Inner Class
Java 將 Inner Class 分為下列 3 類
‧ 一般的 Inner Class
指的是將 class 宣告在 class 內
[語法]
[class-modifiers] class EnclosingClass {
  [inner-class-modifiers] class InnerClass {
    // Write Codes Here
  }
}
 inner-class-modifiers 可以是 public、protected、private、final、strictfp、abstract、static(會變成static nested class)

1. 若在 enclosing class 之外建立 inner class 的 instance,必須先建立 enclosing class 的 instance。
 [範例]
 EnclosingClass.InnerClass obj = new EnclosingClass( ).new InnerClass( );
 或是
 EnclosingClass objX = new EnclosingClass( );
 EnclosingClass.InnerClass objY = objX.new InnerClass( );

2. 所有的 inner class 會隱性參考(reference) 其 enclosing class,其型式為 "EnclosingClass.this"
 [範例]
 public class MyEnclosingClass {
   private String someMember = "Some Member";
   private class MyInnerClass {
     private String someMember = "Inner Member";
     public void doIt( ) {
       System.out.println(someMember);  // 印出 Inner Member
       System.out.println( MyEnclosingClass.this.someMember );  // 印出 Some Member
     }
   }

   public static void main(String[ ] args) {
     new MyEnclosingClass( ).new MyInnerClass( ).doIt( );
   }
 }

3. non-static inner class 可存取包含該 inner class 的所有的 members。
4. inner class 內不能宣告 static members,inner class 內所有 members 必須是 instance members,但是 inner classes 可
 存取 enclosing class 的 static members。
 唯一的例外是,inner classes 內可宣告 static 和 final 的 fields(compile-time constant)。

[範例]
class HasStatic {
static int j = 100;
}
class Outer {
class Inner extends HasStatic {
static final int x = 3; // ok - compile-time constant
static int y = 4; // compile-time error, an inner class
}
static class NestedButNotInner {
static int z = 5; // ok, not an inner class
}
interface NeverInner { } // interfaces are never inner
}


‧ Method local Inner Class
1. local class 為定義在 method 內的 class,其 scope 在該 method 內
2. 當 inner class 定義在 method 內,則該 class 只可以存取 enclosing class 宣告為 final 的 variables(或稱為 automatic 或 local variables)

[範例]
public class MyInnerClass {
static String msg = "Hello";

public static void main(String[ ] av) {
class Inner {
public void doSomeWork( ) { // print member of enclosing class
System.out.println(msg);
}
}
Inner p = new Inner( );
p.doSomeWork( );
}
}


‧ Anonymous Inner Class
1. anonymous nested class 必須實作某個 interface 或是繼承某個 class,但是不使用 implements 或 extends 關鍵字做宣告。
2. anonymous class 內不能宣告 constructor,可宣告 instance initializer 做初值設定
[註] anonymous class 的類別名稱可用 this.getClass( ).getName( ) 觀察

[範例]
return new SomeClass( ) {  /*body of the anonymous class goes here*/  };

[範例]
someMethod(new SomeClass( ) {  /*body of the anonymous class goes here*/  } );

Nested Class
Nested Classes 也是 inner class 的一種型式,但是 Java 將宣告為 static 的 inner class 稱為 Nested Class
‧ Static Nested Classes
1. nested classes 即為所謂的 static inner classes
 nested classes 有點像似 top-level classes,enclosing class 提供這種類型的 class 一個 package-like 的架構,nested classes 可
 存取 enclosing class 所有的 members。但是 nested class 比 inner class 有更多的限制。
2. static nested class 可以合用修飾字 abstract。
 [註] 注意,一般而言,在 class 內你不能宣告 static methods 為 abstract。
3. 可直接建立 nested class 的 instance,不需先建立 enclosing class 的 instance。
 EnclosingClass.NestedClass obj = new EnclosingClass.NestedClass( );
4. nested class 只能存取 enclosing class 的 static members(private 權限的 members 亦可)
 
[範例]
public class MyEnclosingClass {
  private static String staticMember = "Static Member";
  private String someMember = "Some Member";
  static class MyNestedClass {
    public void doIt( ) {
      System.out.println(staticMember);
    }
  }

  public static void main(String[ ] args) {
    new MyNestedClass( ).doIt( );
    // new MyInnerClass( ); // ERROR
  }

  class MyInnerClass {
    // static String InnerStaticMember = "Inner Static Member"; // Error:inner classes cannot have static declarations
    public void doIt( ) {
      System.out.println(staticMember + ", " +myStaticFinalConstant);
    }
    static final int myStaticFinalConstant = 0; // OK
  }
}


※ inner interface 與 inner class 混用
1. interface 內的 inner interface 預設為 public static,class 內的 inner interface 預設為 static,存取權限可以為 private/protected/public/default
2. class 的 inner class 內不能再有 inner interface,否則會出現編譯錯誤:inner classes cannot have static declarations
3. Interface 的 Inner Class 內可以有 Inner Interface
4. Interface 內可以有 Inner class
5. Inner Interface 可以繼承 Outer Intreface
6. Inner Class 可以繼承 Outer Class 或 implments Outer Interface

[範例]
public class X {
  class Y {
    private void f( ) { }
  }
  class Z extends Y {
    { // initializer
      f( );    // 編譯錯誤
      this.f( );  // 編譯錯誤
      ((Y)this).f( ); // 可過編譯
      super.f( ); // 可過編譯
    } //end initializer
  }
} // end class X

2010年9月11日 星期六

java 面試題 (2) English

Q:

What is the difference between an Interface and an Abstract class?

A: An abstract class can have instance methods that implement a default behavior. An Interface can only declare constants and instance methods, but cannot implement default behavior and all methods are implicitly abstract. An interface has all public members and no implementation. An abstract class is a class which may have the usual flavors of class members (private, protected, etc.), but has some abstract methods.

Q:

What is the purpose of garbage collection in Java, and when is it used?

A: The purpose of garbage collection is to identify and discard objects that are no longer needed by a program so that their resources can be reclaimed and reused. A Java object is subject to garbage collection when it becomes unreachable to the program in which it is used.

Q:

Describe synchronization in respect to multithreading.

A: With respect to multithreading, synchronization is the capability to control the access of multiple threads to shared resources. Without synchonization, it is possible for one thread to modify a shared variable while another thread is in the process of using or updating same shared variable. This usually leads to significant errors.

Q:

Explain different way of using thread?

A: The thread could be implemented by using runnable interface or by inheriting from the Thread class. The former is more advantageous, 'cause when you are going for multiple inheritance..the only interface can help.

Q:

What are pass by reference and passby value?

A: Interface Pass By Reference means the passing the address itself rather than passing the value. Pass By Value means passing a copy of the value to be passed.

Q:

What is HashMap and Map?

A: Map is Interface and Hashmap is class that implements that.

Q:

Difference between HashMap and HashTable?

A: The HashMap class is roughly equivalent to Hashtable, except that it is unsynchronized and permits nulls. (HashMap allows null values as key and value whereas Hashtable doesnt allow). HashMap does not guarantee that the order of the map will remain constant over time. HashMap is unsynchronized and Hashtable is synchronized.

Q:

Difference between Vector and ArrayList?

A: Vector is synchronized whereas arraylist is not.

Q:

Difference between Swing and Awt?

A: AWT are heavy-weight componenets. Swings are light-weight components. Hence swing works faster than AWT.

Q:

What is the difference between a constructor and a method?

A: A constructor is a member function of a class that is used to create objects of that class. It has the same name as the class itself, has no return type, and is invoked using the new operator.
A method is an ordinary member function of a class. It has its own name, a return type (which may be void), and is invoked using the dot operator.
Q:

What is an Iterator?

A: Some of the collection classes provide traversal of their contents via a java.util.Iterator interface. This interface allows you to walk through a collection of objects, operating on each object in turn. Remember when using Iterators that they contain a snapshot of the collection at the time the Iterator was obtained; generally it is not advisable to modify the collection itself while traversing an Iterator.

Q:

State the significance of public, private, protected, default modifiers both singly and in combination and state the effect of package relationships on declared items qualified by these modifiers.

A: public : Public class is visible in other packages, field is visible everywhere (class must be public too)
private : Private variables or methods may be used only by an instance of the same class that declares the variable or method, A private feature may only be accessed by the class that owns the feature.
protected : Is available to all classes in the same package and also available to all subclasses of the class that owns the protected feature.This access is provided even to subclasses that reside in a different package from the class that owns the protected feature.
default :What you get by default ie, without any access modifier (ie, public private or protected).It means that it is visible to all within a particular package
.

Q:

What is an abstract class?

A: Abstract class must be extended/subclassed (to be useful). It serves as a template. A class that is abstract may not be instantiated (ie, you may not call its constructor), abstract class may contain static data. Any class with an abstract method is automatically abstract itself, and must be declared as such.
A class may be declared abstract even if it has no abstract methods. This prevents it from being instantiated.

Q:

What is static in java?

A: Static means one per class, not one for each object no matter how many instance of a class might exist. This means that you can use them without creating an instance of a class.Static methods are implicitly final, because overriding is done based on the type of the object, and static methods are attached to a class, not an object. A static method in a superclass can be shadowed by another static method in a subclass, as long as the original method was not declared final. However, you can't override a static method with a nonstatic method. In other words, you can't change a static method into an instance method in a subclass.

例子:
底下程式看起來像是可以用一般的override來看待,其實不然
如果overridemethodstatic,實際執行的method會是宣告型別的method而不是實際型別的method

程式:

class Question30Super{

public static void printSomething(){

System.out.println("In Question30Super");

}

}

public class Question30 extends Question30Super {

public static void main(String[] args){

Question30Super q30 = new Question30();

q30.printSomething();

}

public static void printSomething(){

System.out.println("In Question30");

}

}

執行結果:

In Question30Super

Q:

What is final? (Immutable?)

A: A final class can't be extended ie., final class may not be subclassed. A final method can't be overridden when its class is inherited. You can't change value of a final variable (is a constant).