Wednesday, October 10, 2007
Review myself
After I work in PCCW, i never write any new thing.
Using hibernate, write simple Java everyday.
I hope after i change i new job,
i can try again to write some applications.
Thursday, September 27, 2007
Java programmer interview hot questions
第二,Anonymous Inner Class (匿名內部類) 是否可以extends(繼承)其他類,是否可以implements(實現)interface(介面)?
第三,Static Nested Class 和 Inner Class的不同,說得越多越好(面試題有的很籠統)。
第四,&和&&的區別。
第五,HashMap和Hashtable的區別。
第六,Collection 和 Collections的區別。
第七,什麼時候用assert。
第八,GC是什麼? 為什麼要有GC?
第九,String s = new String("xyz");創建了幾個String Object?
第十,Math.round(11.5)等於多少? Math.round(-11.5)等於多少?
第十一,short s1 = 1; s1 = s1 + 1;有什麼錯? short s1 = 1; s1 += 1;有什麼錯?
第十二,sleep() 和 wait() 有什麼區別?
第十三,Java有沒有goto?
第十四,陣列有沒有length()這個方法? String有沒有length()這個方法?
第十五,Overload和Override的區別。Overloaded的方法是否可以改變返回值的類型?
第十六,Set裏的元素是不能重複的,那麼用什麼方法來區分重複與否呢? 是用==還是equals()? 它們有何區別?
第十七,給我一個你最常見到的runtime exception。
第十八,error和exception有什麼區別?
第十九,List, Set, Map是否繼承自Collection介面?
第二十,abstract class和interface有什麼區別?
第二十一,abstract的method是否可同時是static,是否可同時是native,是否可同時是synchronized?
第二十二,介面是否可繼承介面? 抽象類是否可實現(implements)介面? 抽象類是否可繼承實體類(concrete class)?
第二十三,啟動一個線程是用run()還是start()?
第二十四,構造器Constructor是否可被override?
第二十五,是否可以繼承String類?
第二十六,當一個線程進入一個物件的一個synchronized方法後,其他線程是否可進入此物件的其他方法?
第二十七,try {}裏有一個return語句,那麼緊跟在這個try後的finally {}裏的code會不會被執行,什麼時候被執行,在return前還是後?
第二十八,編程題: 用最有效率的方法算出2乘以8等於幾?
第二十九,兩個對象值相同(x.equals(y) == true),但卻可有不同的hash code,這句話對不對?
第三十,當一個物件被當作參數傳遞到一個方法後,此方法可改變這個物件的屬性,並可返回變化後的結果,那麼這裏到底是值傳遞還是引用傳遞?
第三十一,swtich是否能作用在byte上,是否能作用在long上,是否能作用在String上?
第三十二,編程題: 寫一個Singleton出來。
以下是答案
第一,談談final, finally, finalize的區別。
final-修飾符(關鍵字)如果一個類被聲明為final,意味著它不能再派生出新的子類,不能作為父類被繼承。因此一個類不能既被聲明為 abstract的,又被聲明為final的。將變數或方法聲明為final,可以保證它們在使用中不被改變。被聲明為final的變數必須在聲明時給定初值,而在以後的引用中只能讀取,不可修改。被聲明為final的方法也同樣只能使用,不能重載
finally-再異常處理時提供 finally 塊來執行任何清除操作。如果拋出一個異常,那麼相匹配的 catch 子句就會執行,然後控制就會進入 finally 塊(如果有的話)。
finalize-方法名。Java 技術允許使用 finalize() 方法在垃圾收集器將物件從記憶體中清除出去之前做必要的清理工作。這個方法是由垃圾收集器在確定這個物件沒有被引用時對這個物件調用的。它是在 Object 類中定義的,因此所有的類都繼承了它。子類覆蓋 finalize() 方法以整理系統資源或者執行其他清理工作。finalize() 方法是在垃圾收集器刪除物件之前對這個物件調用的。
第二,Anonymous Inner Class (匿名內部類) 是否可以extends(繼承)其他類,是否可以implements(實現)interface(介面)?匿名的內部類是沒有名字的內部類。不能extends(繼承) 其他類,但一個內部類可以作為一個介面,由另一個內部類實現。
第三,Static Nested Class 和 Inner Class的不同,說得越多越好(面試題有的很籠統)。
Nested Class (一般是C++的說法),Inner Class (一般是JAVA的說法)。Java內部類與C++嵌套類最大的不同就在於是否有指向外部的引用上。具體可見http: //www.frontfree.net/articles/services/view.asp?id=704&page=1注: 靜態內部類(Inner Class)意味著1創建一個static內部類的物件,不需要一個外部類物件,2不能從一個static內部類的一個物件訪問一個外部類物件
第四,&和&&的區別。
&是位運算符。&&是布林邏輯運算符。
第五,HashMap和Hashtable的區別。都屬於Map介面的類,實現了將惟一鍵映射到特定的值上。
HashMap 類沒有分類或者排序。它允許一個 null 鍵和多個 null 值。
Hashtable 類似於 HashMap,但是不允許 null 鍵和 null 值。它也比 HashMap 慢,因為它是同步的。
第六,Collection 和 Collections的區別。
Collections是個java.util下的類,它包含有各種有關集合操作的靜態方法。
Collection是個java.util下的介面,它是各種集合結構的父介面。
第七,什麼時候用assert。斷言是一個包含布林運算式的語句,在執行這個語句時假定該運算式為 true。如果運算式計算為 false,那麼系統會報告一個 AssertionError。它用於調試目的:
assert(a > 0); // throws an AssertionError if a <= 0 斷言可以有兩種形式:
assert Expression1 ;
assert Expression1 : Expression2 ;
Expression1 應該總是產生一個布林值。
Expression2 可以是得出一個值的任意運算式。這個值用於生成顯示更多調試資訊的 String 消息。斷言在默認情況下是禁用的。要在編譯時啟用斷言,需要使用 source 1.4 標記:
javac -source 1.4 Test.java要在運行時啟用斷言,可使用 -enableassertions 或者 -ea 標記。 要在運行時選擇禁用斷言,可使用 -da 或者 -disableassertions 標記。 要系統類中啟用斷言,可使用 -esa 或者 -dsa 標記。還可以在包的基礎上啟用或者禁用斷言。 可以在預計正常情況下不會到達的任何位置上放置斷言。斷言可以用於驗證傳遞給私有方法的參數。不過,斷言不應該用於驗證傳遞給公有方法的參數,因為不管是否啟用了斷言,公有方法都必須檢查其參數。不過,既可以在公有方法中,也可以在非公有方法中利用斷言測試後置條件。另外,斷言不應該以任何方式改變程式的狀態。
第八,GC是什麼? 為什麼要有GC? (基礎)。
GC是垃圾收集器。Java 程式師不用擔心記憶體管理,因為垃圾收集器會自動進行管理。要請求垃圾收集,可以調用下面的方法之一:
System.gc()
Runtime.getRuntime().gc()
第九,String s = new String("xyz");創建了幾個String Object?兩個物件,一個是“xyx”,一個是指向“xyx”的引用物件s。
第十,Math.round(11.5)等於多少? Math.round(-11.5)等於多少?
Math.round(11.5)返回(long)12,Math.round(-11.5)返回(long)-11;
第十一,short s1 = 1; s1 = s1 + 1;有什麼錯? short s1 = 1; s1 += 1;有什麼錯?
short s1 = 1; s1 = s1 + 1;有錯,s1是short型,s1+1是int型,不能顯式轉化為short型。可修改為s1 =(short)(s1 + 1) 。short s1 = 1; s1 += 1正確。
第十二,sleep() 和 wait() 有什麼區別? 搞線程的最愛
sleep()方法是使線程停止一段時間的方法。在sleep 時間間隔期滿後,線程不一定立即恢復執行。這是因為在那個時刻,其他線程可能正在運行而且沒有被調度為放棄執行,除非(a)“醒來”的線程具有更高的優先順序
(b)正在運行的線程因為其他原因而阻塞。
wait()是線程交互時,如果線程對一個同步物件x 發出一個wait()調用,該線程會暫停執行,被調物件進入等待狀態,直到被喚醒或等待時間到。
第十三,Java有沒有goto?
Goto-java中的保留字,現在沒有在java中使用。
第十四,陣列有沒有length()這個方法? String有沒有length()這個方法?陣列沒有length()這個方法,有length的屬性。
String有有length()這個方法。
第十五,Overload和Override的區別。Overloaded的方法是否可以改變返回值的類型?方法的重寫Overriding和重載Overloading是Java多態性的不同表現。重寫Overriding是父類與子類之間多態性的一種表現,重載Overloading是一個類中多態性的一種表現。如果在子類中定義某方法與其父類有相同的名稱和參數,我們說該方法被重寫 (Overriding)。子類的物件使用這個方法時,將調用子類中的定義,對它而言,父類中的定義如同被“遮罩”了。如果在一個類中定義了多個同名的方法,它們或有不同的參數個數或有不同的參數類型,則稱為方法的重載(Overloading)。Overloaded的方法是可以改變返回值的類型。
第十六,Set裏的元素是不能重複的,那麼用什麼方法來區分重複與否呢? 是用==還是equals()? 它們有何區別?
Set裏的元素是不能重複的,那麼用iterator()方法來區分重複與否。equals()是判讀兩個Set是否相等。
equals()和==方法決定引用值是否指向同一物件equals()在類中被覆蓋,為的是當兩個分離的物件的內容和類型相配的話,返回真值。
第十七,給我一個你最常見到的runtime exception。
ArithmeticException, ArrayStoreException, BufferOverflowException, BufferUnderflowException, CannotRedoException, CannotUndoException, ClassCastException, CMMException, ConcurrentModificationException, DOMException, EmptyStackException, IllegalArgumentException, IllegalMonitorStateException, IllegalPathStateException, IllegalStateException,
ImagingOpException, IndexOutOfBoundsException, MissingResourceException, NegativeArraySizeException, NoSuchElementException, NullPointerException, ProfileDataException, ProviderException, RasterFormatException, SecurityException, SystemException, UndeclaredThrowableException, UnmodifiableSetException, UnsupportedOperationException
第十八,error和exception有什麼區別?
error 表示恢復不是不可能但很困難的情況下的一種嚴重問題。比如說記憶體溢出。不可能指望程式能處理這樣的情況。
exception 表示一種設計或實現問題。也就是說,它表示如果程式運行正常,從不會發生的情況。
第十九,List, Set, Map是否繼承自Collection介面?
List,Set是
Map不是
第二十,abstract class和interface有什麼區別?聲明方法的存在而不去實現它的類被叫做抽象類(abstract class),它用於要創建一個體現某些基本行為的類,並為該類聲明方法,但不能在該類中實現該類的情況。不能創建abstract 類的實例。然而可以創建一個變數,其類型是一個抽象類,並讓它指向具體子類的一個實例。不能有抽象構造函數或抽象靜態方法。Abstract 類的子類為它們父類中的所有抽象方法提供實現,否則它們也是抽象類為。取而代之,在子類中實現該方法。知道其行為的其他類可以在類中實現這些方法。介面(interface)是抽象類的變體。在介面中,所有方法都是抽象的。多繼承性可通過實現這樣的介面而獲得。介面中的所有方法都是抽象的,沒有一個有程式體。介面只可以定義static final成員變數。介面的實現與子類相似,除了該實現類不能從介面定義中繼承行為。當類實現特殊介面時,它定義(即將程式體給予)所有這種介面的方法。然後,它可以在實現了該介面的類的任何物件上調用介面的方法。由於有抽象類,它允許使用介面名作為引用變數的類型。通常的動態聯編將生效。引用可以轉換到介面類型或從介面類型轉換,instanceof 運算符可以用來決定某物件的類是否實現了介面。
第二十一,abstract的method是否可同時是static,是否可同時是native,是否可同時是synchronized?都不能
第二十二,介面是否可繼承介面? 抽象類是否可實現(implements)介面? 抽象類是否可繼承實體類(concrete class)?介面可以繼承介面。抽象類可以實現(implements)介面,抽象類是否可繼承實體類,但前提是實體類必須有明確的構造函數。
第二十三,啟動一個線程是用run()還是start()?啟動一個線程是調用start()方法,使線程所代表的虛擬處理機處於可運行狀態,這意味著它可以由JVM調度並執行。這並不意味著線程就會立即運行。run()方法可以產生必須退出的標誌來停止一個線程。
第二十四,構造器Constructor是否可被override?構造器Constructor不能被繼承,因此不能重寫Overriding,但可以被重載Overloading。
第二十五,是否可以繼承String類?
String類是final類故不可以繼承。
第二十六,當一個線程進入一個物件的一個synchronized方法後,其他線程是否可進入此物件的其他方法?不能,一個物件的一個synchronized方法只能由一個線程訪問。
第二十七,try {}裏有一個return語句,那麼緊跟在這個try後的finally {}裏的code會不會被執行,什麼時候被執行,在return前還是後?會執行,在return前執行。
第二十八,編程題: 用最有效率的方法算出2乘以8等於幾?有C背景的程式師特別喜歡問這種問題。
2 << 3
第二十九,兩個對象值相同(x.equals(y) == true),但卻可有不同的hash code,這句話對不對?不對,有相同的hash code。
第三十,當一個物件被當作參數傳遞到一個方法後,此方法可改變這個物件的屬性,並可返回變化後的結果,那麼這裏到底是值傳遞還是引用傳遞? 是值傳遞。Java 編程語言只由值傳遞參數。當一個物件實例作為一個參數被傳遞到方法中時,參數的值就是對該物件的引用。物件的內容可以在被調用的方法中改變,但物件的引用是永遠不會改變的。
第三十一,swtich是否能作用在byte上,是否能作用在long上,是否能作用在String上?
switch(expr1)中,expr1是一個整數運算式。因此傳遞給 switch 和 case 語句的參數應該是 int、 short、 char 或者 byte。long,string 都不能作用於swtich。
第三十二,編程題: 寫一個Singleton出來。
Singleton模式主要作用是保證在Java應用程式中,一個類Class只有一個實例存在。一般Singleton模式通常有幾種種形式:第一種形式: 定義一個類,它的構造函數為private的,它有一個static的private的該類變數,在類初始化時實例話,通過一個public的getInstance方法獲取對它的引用,繼而調用其中的方法。
public class Singleton { private Singleton(){} //在自己內部定義自己一個實例,是不是很奇怪? //注意這是private 只供內部調用 private static Singleton instance = new Singleton(); //這裏提供了一個供外部訪問本class的靜態方法,可以直接訪問 public static Singleton getInstance() { return instance; }
} 第二種形式:
public class Singleton { private static Singleton instance = null; public static synchronized Singleton getInstance() { //這個方法比上面有所改進,不用每次都進行生成物件,只是第一次 //使用時生成實例,提高了效率! if (instance==null) instance=new Singleton();
return instance; }
} 其他形式:定義一個類,它的構造函數為private的,所有方法為static的。一般認為第一種形式要更加安全些 第三十三 Hashtable和HashMap
Hashtable繼承自Dictionary類,而HashMap是Java1.2引進的Map interface的一個實現
HashMap允許將null作為一個entry的key或者value,而Hashtable不允許
還有就是,HashMap把Hashtable的contains方法去掉了,改成containsvalue和containsKey。因為contains方法容易讓人引起誤解。
最大的不同是,Hashtable的方法是Synchronize的,而HashMap不是,在 多個線程訪問Hashtable時,不需要自己為它的方法實現同步,而HashMap 就必須為之提供外同步。
Hashtable和HashMap採用的hash/rehash演算法都大概一樣,所以性能不會有很大的差異。
Thursday, May 03, 2007
Improve SQL performance
1. Know your data and business application well.Identical information can often be retrieved from different business data sources. Familiarize yourself with these sources; you must be aware of the data volume and distribution in your database. Your should also have a thorough understanding of your data model--such as the relationships among business entities--before writing your SQL. This understanding will help you write much better queries for retrieving information from multiple tables. CASE tools such as Designer/2000 do a very good job of documenting relations among different business and database objects.
2. Test your queries with realistic data.
Most organizations have three database environments: development, test, and production. Programmers use the development database environment to create and test applications, which are then more rigorously examined in the test environment by programmers and users before they are migrated to the production environment.
When a SQL is being tested in the test environment, make sure the test database contains data that reflects the production database. A SQL statement tested with unrealistic data may behave differently when used in production. To ensure rigorous testing, the data distribution in the test environment must also closely resemble that in the production environment.
3. Write identical SQL statements in your applications.
Take full advantage of bind variables, stored procedures, and packages wherever possible. The benefits of identical SQL statements include reduced memory use on the database server and faster execution, as parsing is unnecessary. For example, these statements are not identical:
select * from employee where empid = 10;4. Use indexes on the tables carefully.
SELECT * FROM EMPLOYEE WHERE EMPID = 10;
select * from employee where empid = 20;
but when using a bind variable named i_empid, the statement would be:
select * from employee where empid = :i_empid;
Be sure to create all the necessary indexes on the tables. However, too many of them can degrade performance. So how do you choose which columns to index?
* Make indexes on columns that are used frequently in the WHERE clause of the application SQL or queries used by end users.
* Index those columns that are used frequently to join tables in SQL statements.
* Use only index columns that have a small percentage of rows with the same value.
* Do not make indexes on those columns that are used only with functions and operators in the WHERE clause of queries.
* Do not index columns that are frequently modified or when the efficiency gained due to index creation results in more efficiency loss due to inserts, updates, and deletes. These operations will slow down due to the need to maintain indexes.
* Unique indexes are better than nonunique indexes because of better selectivity. Use unique indexes on primary key columns and nonunique indexes on foreign keys and columns frequently used in the WHERE clause.
* Create the index so that the columns used in the WHERE clause make up a leading portion of the index.
5. Make an indexed path available.
To take advantage of indexes, write your SQL in such a manner that an indexed path is available to it. The optimizer cannot use an access path that uses an index simply because the index exists; the access path must be made available by the SQL. Using SQL hints is one of the ways to ensure the index is used. See the following tips to select a particular access path.
6. Use Explain Plan and TKPROF where possible.
If your SQL statements are not well-tuned, they may be inefficient even if the Oracle database itself is "well-oiled." Become familiar with Explain Plan and TKPROF tools and use them to your advantage. Explain Plan helps in discovering the access path used by a SQL; TKPROF shows its actual performance statistics. These tools are bundled with Oracle server software and can help you improve SQL performance.
8. Think globally when acting locally.
Always remember: Any changes you make in the database to tune one SQL statement may affect the performance of other statements used by applications and users.
9. The WHERE clause is crucial.
The following WHERE clauses would not use the index access path even if an index is available (COL1 and COL2 are in the same table and the index is created on COL1):
* COL1 > COL2
* COL1 < COL2
* COL1 > = COL2
* COL1 <= COL2
* COL1 IS NULL
* COL1 IS NOT NULL. An index does not store the ROWIDs for columns that have null values. So querying for rows with null values cannot use that index.
* COL1 NOT IN (value1, value2 )
* COL1 != expression
* COL1 LIKE '%pattern'. In this case, the leading edge of the index is suppressed so the index cannot be used. On the other side, COL1 LIKE 'pattern%' or COL1 LIKE 'pattern%pattern%' can use index because they would result in a bounded-range index scan.
* NOT EXISTS subquery
* expression1 = expression2. Any expressions, functions, or calculations involving indexed columns would prohibit usage of the index. In the following example, using the UPPER SQL function would prevent index scan and result in a full table scan.
SELECT DEPT_NAME13. Use ORDER BY for index scan.
FROM DEPARTMENT
WHERE UPPER(DEPT_NAME) like 'SALES%';
10. Use WHERE instead of HAVING for record filtering.
Avoid using the HAVING clause along with GROUP BY on an indexed column.
In this case, the index is not used. Furthermore, exclude rows with
WHERE clause rather than using HAVING. If the EMP table has an index on
column DEPTID, the following query cannot take advantage of it:
SELECT DEPTID,
SUM(SALARY)
FROM EMP
GROUP BY DEPTID
HAVING DEPTID = 100;
However, the same query can be rewritten to exploit the index:
SELECT DEPTID,
SUM(SALARY)
FROM EMP
WHERE DEPTID = 100
GROUP BY DEPTID;
11. Specify the leading index columns in WHERE clauses.
For a composite index, the query would use the index as long as the
leading column of the index is specified in the WHERE clause. The
following query would use the composite index based on the primary key
constraint on the PART_NUM and PRODUCT_ID columns:
SELECT *
FROM PARTS
WHERE PART_NUM = 100;
whereas this query would not use the composite index:
SELECT *
FROM PARTS
WHERE PRODUCT_ID = 5555;
The same request can rewritten to take advantage of the index. In this
query, it is assumed that the PART_NUM column will always have a value
greater than zero:
SELECT *
FROM PARTS
WHERE PART_NUM > 0
AND PRODUCT_ID = 5555;
12. Evaluate index scan vs. full table scan.
If selecting more than 15 percent of the rows from a table, full table
scan is usually faster than an index access path. In such cases, write
your SQLs so that they use full table scans.
The following statements would not use index scans even if an index
is created on the SALARY column. In the first SQL, using the FULL hint
forces Oracle to employ full table scan. When using an index does more
harm than good, you can also use these techniques to suppress the use
of the index.
SELECT * --+FULL
FROM EMP
WHERE SALARY = 50000;
SELECT *
FROM EMP
WHERE SALARY+0 = 50000;
The following statements would not use index scans even if an index is created on the SS# column:
SELECT *
FROM EMP
WHERE SS# || ' ' = '111-22-333';
An index is also not used if Oracle has to perform implicit data
conversion. For the following example, SALARY is a numeric column in
the table EMP and a character value is converted into a numeric value:
SELECT *
FROM EMP
WHERE SALARY = '50000';
When the percentage of table rows accessed is 15 percent or less, an
index scan will work better because it results in multiple logical
reads per row accessed, whereas a full table scan can read all the rows
in a block in one logical read. Thus, the performance of full table
scan is better when accessing a large percentage of rows from a table.
To illustrate this point, say the ANALYZE command is issued against
the EMP table and all its indexes. Oracle generates the following
statistics in the data dictionary table USER_TABLES and USER_INDEXES:
Table Statistics:
NUM_ROWS = 1000
BLOCKS = 100
Index Statistics:
BLEVEL = 2
AVG_LEAF_BLOCKS_PER_KEY = 1
AVG_DATA_BLOCKS_PER_KEY = 1
Based on these statistics, the following would be the logical reads (block accessed) for different types of scans:
Use of index to return one row = 3
(BLEVEL+(AVG_LEAF_BLOCKS_PER_KEY - 1) + AVG_DATA_PER_KEY
Full table scan = 100
(BLOCKS)
Use of index to return all rows = 3000
(NUM_ROWS * Blocks accessed to return one row using index)
Oracle's optimizer will use an index scan if the ORDER BY clause is on an indexed column. The following query illustrates this point. This query would use the index available on EMPID column even though the column is not specified in the WHERE clause. The query would retrieve ROWID for each row from the index and access the table using the ROWID.
SELECT SALARY
FROM EMP
ORDER BY EMPID;
If this query performs poorly, you can try another alternative by rewriting the same query using the FULL hint described earlier (Number 12).
14. Know thy data.
As I've already explained, you have to know your data intimately. For example, say you have a table called BOXER containing two columns--BOXER_NAME and SEX--with a nonunique index on column SEX. If there are an equal number of male and female boxers, the following query will run faster if Oracle performs a full table scan:
SELECT BOXER_NAMEYou can ensure the query performs a full table scan by rewriting it as :
FROM BOXER
WHERE SEX = 'F';
SELECT BOXER_NAME --+ FULLIf the table contains 980 male boxers, this query would be faster because it results in index scan:
FROM BOXER
WHERE SEX = 'F';
SELECT BOXER_NAME --+ INDEX (BOXER BOXER_SEX)
FROM BOXER
WHERE SEX = 'F';
This example illustrates the importance of being familiar with data distribution. SQL performance will vary as the database grows and data distribution changes. Oracle added a HISTOGRAMS function with Oracle7.3 so that the optimizer can be aware of the data distribution in a table and select an appropriate execution plan.
15. Know when to use large-table scans.
When retrieving rows from a very small table or very large table, a full table scan may result in better performance over an index scan. An index scan on a very large table may require scanning of many index and table blocks. When these blocks are brought in the database buffer cache, they are kept as long as possible. These blocks may not be needed by other queries so the database buffer hit ratio may decline and the performance of a multiuser system may suffer. However, the blocks read by a full table scan are removed from the database buffer cache much earlier and the database buffer hit ratio is not affected.
16. Minimize table passes.
Usually, reducing the number of table passes in a SQL query results in better performance. Queries with fewer table passes mean faster queries. Here's an example. The STUDENT table has four columns named NAME, STATUS, PARENT_INCOME, and SELF_INCOME. The name is the primary key. The values of the STATUS column is 0 for independent students and 1 for dependent students.
The following query returns the name and income for dependent as well as independent students. It results in two passes through the STUDENT table, creates a temporary table for processing, and initiates a sort to eliminate duplicates:
SELECT NAME, PARENT_INCOME
FROM STUDENT
WHERE STATUS = 1
UNION
SELECT NAME, SELF_INCOME
FROM STUDENT
WHERE STATUS = 0;
The same request can be fulfilled by this query, which results in only one pass through the table:
SELECT NAME, PARENT_INCOME*STATUS + SELF_INCOME(1-STATUS)17. Join tables in the proper order.
FROM STUDENT;
The order in which tables are joined in a multiple table join is crucial. Overall, fewer rows will be processed if tables are joined in the correct order.
Always perform the most restrictive search first to filter out the maximum number of rows in the early phases of a multiple table join. This way, the optimizer will have to work with fewer rows in the subsequent phases of join, improving performance. You should carry fewer rows to the subsequent phases of a join. Furthermore, make sure that the driving table (the table searched first in the nested loop join) is the table that returns the least number of rows. In a master and detail tables join (i.e., ORDERS and ORDER LINE ITEMS tables), ensure that the master table is connected first; connecting a detail table first will usually result in more rows getting joined.
For the rule-based optimizer, the driving table should be the last table specified in the FROM clause. The rule-based optimizer makes the last table specified in the FROM clause the driving table in the nested loop join. If the join is resulting in nested loop join, consider making index available for the inner table search. Explain Plan and TKPROF output show the join type, table join order, and number of rows processed in every phase of a join.
For the cost-based optimizer, the order in which tables appear in the WHERE clause is irrelevant as the optimizer will try to find the best execution plan on its own. Consider using the ORDERED hint to control the table join order. In the following query, tables would be joined in the order in which they appear in the WHERE clause:
SELECT ORDERS.CUSTID, ORDERS.ORDERNO,18. Use index-only searches when possible.
ORDER_LINE_ITEMS.PRODUCTNO --+ORDERED
FROM ORDERS, ORDER_LINE_ITEMS
WHERE ORDERS.ORDERNO = ORDER_LINE_ITEMS.ORDERNO;
If possible, write queries that use index-only searches. The optimizer will need to search only the index and not the table to satisfy such queries, so performance is better; the optimizer will use an index-only search if all the information to satisfy the SQL can be found in the index itself. If the EMP table has a composite index on LANME and FNAME columns, the following query will result in index-only search:
SELECT FNAME
FROM EMP
WHERE LNAME = 'SMITH';
whereas this query results in an index scan as well as table search by ROWID:
SELECT FNAME , SALARY
FROM EMP
WHERE LNAME = 'SMITH';
Therefore, pay close attention to the column list in the SELECT clause. Include only those columns that you really need.
19. Redundancy is good.
Provide as much information as possible in the WHERE clause. For example, if the WHERE clause is WHERE COL1 = COL2 and COL1 = 10, the optimizer will infer that COL2 =10. But if the WHERE clause is WHERE COL1 = COL2 and COL2 = COL3, then optimizer will not infer that COL1 = COL3.
20. Keep it simple, stupid.
Make your SQL statements as simple as possible. Very complex SQL statements can overwhelm the optimizer; sometimes writing multiple, simpler SQLs will yield better performance than a single complex SQL statement. Oracle's cost-based optimizer is not completely robust. It's in the development stage but getting better with each Oracle release. As a result, you have to keep an eye on the Explain Plan cost estimate. "Cost" is a relative term--nobody seems to know what the cost numeric value means--but the smaller this value, the better the SQL performance. So tune the statement for the lower cost.
It may often be more efficient to use temporary tables and break up a complex SQL join involving many tables. For example, if a join involves eight tables with large amount of data, it might be better to split the SQL into two or three SQLs, each involving at most a four-table join and storing the intermediate results in precreated temporary tables.
21. You can reach the same destination in different ways.
In many cases, more than one SQL statement can get you the same desired results. Each SQL may use a different access path and may perform differently. For example, the MINUS operator can be much faster than using WHERE NOT IN (SELECT ) or WHERE NOT EXISTS.
Let's say we have an index on a STATE column and another index on an AREA_CODE column. Despite the availability of indexes, the following statement will require a full table scan due to the usage of the NOT IN predicate:
SELECT CUSTOMER_IDHowever, if the same query is rewritten as the following, it will result in index scans:
FROM CUSTOMERS
WHERE STATE IN ('VA', 'DC', 'MD')
AND AREA_CODE NOT IN (804, 410);
SELECT CUSTOMER_IDIf a SQL involves OR in the WHERE clause, it can also be rewritten by substituting UNION for OR in the WHERE clause. You must carefully evaluate execution plans of all SQLs before selecting one to satisfy the information request. You can use Explain Plan and TKPROF tools for this process.
FROM CUSTOMERS
WHERE STATE IN ('VA', 'DC', 'MD')
MINUS
SELECT CUSTOMER_ID
FROM CUSTOMERS
WHERE AREA_CODE IN (804, 410);
22. Use the special columns.
Take advantage of ROWID and ROWNUM columns. Remember, the ROWID search is the fastest. Here's an example of UPDATE using ROWID scan:
SELECT ROWID, SALARYA ROWID value is not constant in a database, so don't hard-code a ROWID value in your SQLs and applications.
INTO TEMP_ROWID, TEMP_SALARY
FROM EMPLOYEE;
UPDATE EMPLOYEE
SET SALARY = TEMP_SALARY * 1.5
WHERE ROWID = TEMP_ROWID;
Use ROWNUM column to limit the number of rows returned. If you're not sure how many rows a SELECT statement will return, use ROWNUM to restrict the number of rows returned. The following statement would not return more than 100 rows:
SELECT EMPLOYE.SS#, DEPARTMENT.DEPT_NAME
FROM EMPLOYEE, DEPENDENT
WHERE EMPLOYEE.DEPT_ID = DEPARTMENT.DEPT_ID
AND ROWNUM < 100;
23. Use explicit cursors over implicit cursors.
Implicit cursors result in an extra fetch. Explicit cursors are opened by developers by using DECLARE, OPEN, FETCH and CLOSE cursor statements. Implicit cursors are opened by Oracle for DELETE, UPDATE, INSERT and SELECT statements.
24. Explore and take advantage of the Oracle parallel query option.
Using the parallel query option, you can execute SQL in parallel for faster performance. In Oracle7, only queries based on a full table scan can be processed in parallel. In Oracle8, queries based on indexed range scans can be parallelized if the index is partitioned. Parallel query option should be used only for SMP and MPP systems containing multiple disk drives.
The Oracle server has many features, but the presence of these features alone does not ensure faster performance. You must configure the database for these features and write SQL specifically to take advantage of them. For example, the following SQL would be executed in parallel:
SELECT * --+PARALLEL(ORDERS,6)25. Reduce network traffic and increase throughput.
FROM ORDERS;
Using array processing and PL/SQL blocks can achieve better performance as well as reduce network traffic. Array processing allows a single SQL statement to process multiple rows. For example, using arrays in an INSERT statement can insert 1,000 rows in a table. Significant performance gains can be achieved in client/server and batch systems using this technique.
Multiple SQL statements can cause heavy network traffic. However, if the SQL statements are within a single PL/SQL block, the entire block can be sent to the Oracle server, processed there, and results returned to the application running on the client.
Encrypting DataSource Passwords
1. Encrypt the database password by using SecureIdentityLoginModule in JBoss.
JBoss 3.2.5
$ cd jboss-3.2.5 $ java -cp 'lib/jboss-jmx.jar;lib/jboss-common.jar;server/default/deploy/jboss-jca.sar;server/default/lib/jbosssx.jar' org.jboss.resource.security.SecureIdentityLoginModule password Encoded password: 5dfc52b51bd35553df8592078de921bc
|
JBoss 4.0
$ cd jboss-4.0 $ java -cp "lib/jboss-jmx.jar;lib/jboss-common.jar;server/default/lib/jboss-jca.jar;server/default/lib/jbosssx.jar" org.jboss.resource.security.SecureIdentityLoginModule password Encoded password: 5dfc52b51bd35553df8592078de921bc
|
(P.S. I fail to generate encoded password by JBoss 3.2.5. Thus I use JBoss 4.0 library to generate it instead.)
2. The datasource oracle-ds.xml should then not use the user-name and password settings, and instead specify the security-domain that maps to the login-config.xml entry for the SecureIdentityLoginModule config.
(JBOSS 3.2.5: If oracle-ds.xml doesn’t exist, copy from “%JBOSS_HOME%docsexamplesjca”)
In oracle-ds.xml ( %JBOSS_HOME%serveralldeploy), replace the <user-name> and <password> with <security-domain> as below:
<datasources> <local-tx-datasource> <jndi-name>DefaultDS</jndi-name> <connection-url>jdbc:oracle:thin:@dev-db:1000:abc</connection-url> <driver-class>oracle.jdbc.driver.OracleDriver</driver-class> <blocking-timeout-millis>5000</blocking-timeout-millis> <idle-timeout-minutes>15</idle-timeout-minutes> <max-pool-size>20</max-pool-size> <min-pool-size>10</min-pool-size>
<!-- Use the security domain defined in conf/login-config.xml --> <security-domain>EncryptDBPassword</security-domain>
</local-tx-datasource> </datasources>
|
In login-config.xml (%JBOSS_HOME%serverallconf), add below code with encrypted password:
<policy> <!-- Example usage of the SecureIdentityLoginModule --> <application-policy name = "EncryptDBPassword"> <authentication> <login-module code = "org.jboss.resource.security.SecureIdentityLoginModule" flag = "required"> <module-option name = "username">system</module-option> <module-option name = "password">5dfc52b51bd35553df8592078de921bc</module-option> <module-option name = "managedConnectionFactoryName">jboss.jca:service=LocalTxCM,name=DefaultDS</module-option> </login-module> </authentication> </application-policy>
</policy>
|
Test Example Code in Java
import javax.naming.Context; import javax.naming.InitialContext; import javax.rmi.PortableRemoteObject;
import javax.naming.NamingException; import javax.sql.DataSource; import java.sql.Connection; import java.sql.SQLException;
import java.util.Hashtable; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.ResultSetMetaData;
private String getDSData(){ String a = "Nothing"; try { Object obj = new InitialContext().lookup("java:DefaultDS"); DataSource ds = (DataSource)obj; Connection conn = null; conn = ds.getConnection(); conn.setAutoCommit(true); PreparedStatement pStmt = null;
pStmt = conn.prepareStatement("select * from TABLE1");
ResultSet rs = pStmt.executeQuery();
ResultSetMetaData rsmd = rs.getMetaData(); int numberOfColumns = rsmd.getColumnCount(); String[] columnNames = new String[numberOfColumns]; for (int i=0; i<columnNames.length; i++) { columnNames[i] = rsmd.getColumnName(i+1); }
while (rs.next()) { Hashtable values = new Hashtable(); for (int i=0; i<columnNames.length; i++) { Object value = rs.getObject(columnNames[i]); if (value!=null) values.put(columnNames[i],value); } a = values.toString();
} if (conn!=null) conn.close(); } catch (NamingException ex) { a=ex.toString(); } catch (SQLException ex) { a=ex.toString(); } catch(Exception ex){ a = ex.toString(); } return a; } |
Reference: http://wiki.jboss.org/wiki/Wiki.jsp?page=EncryptingDataSourcePasswords
Friday, April 27, 2007
log4j good logging tool
Reference web page:
http://my.so-net.net.tw/idealist/Java/Log4j.html (chinese)
http://wiki.apache.org/logging-log4j/Log4jXmlFormat
Thursday, April 26, 2007
Quartz Basic structure: (referenece book: Quartz Job Schedule Framework)
Classes:
1. Job - interface class- provide method execute(JobExecutionContext c)
- JobExecutionContext - getJobDetail() to get the JobDetail instance.
- JobDetail contain the job name and JobDataMap instance from getJobDataMap.
- JobDataMap can help pass the data inside the Job.
Sample:
Create JobDetail, JobDataMap and Trigger.JobDetail jobDetail = new JobDetail("ScanDirectory", Scheduler.DEFAULT_GROUP, ScanDirectoryJob.class);
// Configure the directory to scan
jobDetail.getJobDataMap().put("SCAN_DIR", "c:\quartz-book\input");
// Create a trigger that fires every 10 seconds, forever
Trigger trigger = TriggerUtils.makeSecondlyTrigger(10); trigger.setName("scanTrigger");
// Start the trigger firing from now
trigger.setStartTime(new Date());
// Associate the trigger with the job in the scheduler scheduler.scheduleJob(jobDetail, trigger);
For CronTrigger
It could be help to develop a more complex trigger than SimpleTrigger.
Name | Required | Allowed Values | Special Characters |
---|---|---|---|
Seconds | Yes | 059 | , - * / |
Minutes | Yes | 059 | , - * / |
Hours | Yes | 23 | , - * / |
Day of Month | Yes | 131 | , - * ? / L W C |
Month | Yes | 112 or JAN-DEC | , - * / |
Day of Week | Yes | 17 or SUN-SAT | , - * ? / L C # |
Year | No | Blank or 19702099 | , - * / |
The names of months and days of the week are not case sensitive. FRI is the same as fri. |
Understanding the Special Characters
As with UNIX cron, Quartz cron expressions support special characters that can be used to create more complicated execution schedules. However, Quartz supports many more than the standard UNIX cron expression.
The * Character
Using the asterisk (*) in a field indicates that you want to include all legal values for that field. For example, using this character in the month field means to fire the trigger for every month.
Example expression:
0 * 17 * * ?
Meaning: Fire the trigger every minute, every day starting at 5 PM until 5:59 PM. It stops at 5:59 PM because the value 17 is in the hour field, and at 6 PM, the hour becomes 18 and doesn't agree with this trigger until the next day at 5 PM.
Use the * character when you want the trigger to fire for every valid value of the field.
The ? Character
The question mark (?) character can be used only in the dayofmonth and dayofweek fields, but not at the same time. You can think of the ? character as "I don't care what value is in this field." This is different from the asterisk, which indicates every value for the field. The ? character says that no value was specified for this field.
The reasons a value can't be specified for both fields are tough to explain and even tougher to understand. Basically, if a value was specified for each, the meaning would become ambiguous: Consider if an expression had the value 11 in a field for the day of the month and a value of WED in the field for the day of the week. Should that trigger fire only on the 11th of the month if it falls on a Wednesday? Or should it fire on both the 11th and every Wednesday? The ambiguity is removed by not allowing a value in both fields at the same time.
Just remember that if you specify a value in one of the two fields, you must put a ? in the other.
Example expression:
0 10,44 14 ? 3 WED
Meaning: Fire at 2:10 PM and 2:44 PM every Wednesday in the month of March.
The , Character
The comma (,) character is used to specify a list of additional values within a given field. For example, using the value 0,15,30,45 in the second field means to fire the trigger every 15 seconds.
Example expression:
0 0,15,30,45 * * * ?
Meaning: Fire the trigger on every quarter-hour.
The / Character
The slash (/) character is used to schedule increments. We just used the comma to increment every 15 minutes, but we could have also written it like 0/15.
Example expression:
0/15 0/30 * * * ?
Meaning: Fire the trigger every 15 seconds on the hour and half-hour.
You can't increment beyond the fields range. For example, you can't specify 30/20 in the second field and expect the scheduler to fire correctly.
The Character
The hyphen (-) character is used to specify a range. For example, 3-8 in the hour field means "the hours 3, 4, 5, 6, 7, and 8." The fields will not wrap, so values such as 50-10 are not allowed.
Example expression:
0 45 3-8 ? * *
Meaning: Fire the trigger on 45 past the hours 3 AM through 8 AM.
The L Character
The L character represents the last allowed value for the field. It is supported by the dayofmonth and dayofweek fields only. When used in the dayofmonth field, it represents the last day of the month for the value specified in the month field. For example, when the month field has JAN specified, using L in the dayofmonth field would cause the trigger to fire on January 31. If SEP was specified as the month, then L would mean to fire on September 30. In order words, it means to fire the trigger on the last day of whatever month is specified.
The expression 0 0 8 L * ? means to fire the trigger at 8:00 AM the last day of every month. The * character in the month field gives us the "every month" part.
When the L character is used in the dayofweek field, it indicates the last day of the week, which is Saturday (or, numerically, 7). So if you needed to fire the trigger on the last Saturday of every month at 11:59 PM, you could use the expression 0 59 23 ? * L.
When used in the dayofweek field, you can use a numerical value in conjunction with the L character to represent the last X day of the month. For example, the expression 0 0 12 ? * 2L says to fire the trigger on the last Monday of every month.
The W Character
The W character stands for weekday (MonFri) and can be used only in the dayofmonth field. It is used to specify the weekday that is nearest to the given day. Most business processes are based on the work week, so the W character can be very important. For example, a value of 15W in the dayofmonth field means "the nearest weekday to the 15th of the month." If the 15th was on a Saturday, the trigger would fire on Friday the 14th because it's closer to the 15th than Monday, which would be the 17th in this example. The W character can be specified only when the day of the month is a single day, not a range or list of days.
The # Character
The # character can be used only in the dayofweek field. It's used to specify the nth XXX day of the month. For example, if you specified the value 6#3 in the dayofweek field, it would mean the third Friday of the month (6 = Friday and #3 means the third one in the month). Another example of 2#1 means the first Monday of the month (2 = Monday and #1 means the first one of the month). Note that if you specify #5 and there is no 5 of the given day of the week in the month, no firing will occur that month.
Monday, April 23, 2007
Howtoforge
http://www.howtoforge.com/
A very good article for install Internet Explorer on Ubuntau
http://www.howtoforge.com/ubuntu_internet_explorer
Thursday, April 19, 2007
JBoss rules
DRL file is represent one package.
Under DRL file it contains many rule with a identify name with package.
JBoss IDE for JBoss rules (necessary install in Eclipse 3.2.x) . It just add some views and DRL and DSL Editor. (so i think it just good for help you to check the syntax).
the programming steps:
1. PackageBuilder -> Package
2. RunBaseFactory -> RunBase -> add -> Package
3. RunBase -> new -> WorkingMemory
4. WorkingMemory -> assertObject for fireAllRules().
It will use all assertObjects in WorkingMemory to run for all rules except you have add filter for call method of fireAllRules();
DRL sytax:
rule :
rule "name"
while "condition"
then "process"
end
e.g.
rule "Your First Rule"
salience 10
when
$m : Man(age <> 25)
then
System.out.println("first : " + $m.getName());
mans.add($m);
end
rule "Your Second Rule"
salience 5
when
$m : Man(age > 25, $name : name)
then
System.out.println("second : " + $name);
end
note: if miss salience .. then all rule by default salience = 0.
If fireAllRules() "Your Second Rule" execute first and then "Your First Rule"
query:
query "name"
"condition"
end
e.g. DRL
query "test"
$man Man(age > 25);
end
e.g. Java
QueryResults qrs = WorkingMemory.getQueryResults("test");
qrs.size();
It could return all valid the query objects.
Personal comment:
From example most rule only check about the assertObject and update the state of object ... but never return anything ..... such as only true/false.
If you have other thing out of set state, you need to define global object to return.
Wednesday, April 18, 2007
oracle reverse enginee and select sql query with case
http://www.eveandersson.com/writing/data-model-reverse-engineering#columns
use Select sql query with case:
syntax
case when
when
...
else
end
sample:
select sal, case when sal < style="font-family: monospace;">'category 1'
else 'category 4'
end
from emp;
Thursday, April 12, 2007
Open source free Java docking framework and discovery new DB Engine
http://mydoggy.sourceforge.net/
I tried the tutorial. It is a very simple docking framework. It cannot place more than panel on the same dock.
H2 Database Engine. it seems better than hypersonic SQL database
http://www.h2database.com/html/frame.html
Wednesday, April 11, 2007
oracle 10g FlashBack function
http://dbaoracle.itpub.net/post/901/271132
Issue one of the following statements:
ALTER SESSION SET recyclebin = ON/OFF;
SELECT object_name, original_name FROM dba_recyclebinThe recycle bin table name is "dba_recyclebin"
How to purge the recycle bin:
PURGE TABLE BIN$jsleilx392mk2=293$0;
or
PURGE RECYCLEBIN;
Maybe you also can append PURGE after drop table statement.
DROP TABLE ABC PURGE;
then the table will direct delete not add to recycle bin.