Jackei 的測試生活與人文社會讀本
posted @ 2007-02-12 09:19 dennis 閱讀(356) | 評論 (1) | 編輯 收藏
|
|||||||||||||||||||||||||||||||||
安裝了JProfiler和LoadRunner,最近對軟件性能測試產生很大興趣,發現一個很棒的blog,做下推薦:
Jackei 的測試生活與人文社會讀本posted @ 2007-02-12 09:19 dennis 閱讀(356) | 評論 (1) | 編輯 收藏
The Java automatic garbage collection process typically operates as a low-priority thread that constantly searches memory for unreachable
objects, objects not referenced by any other object reachable by a live
thread. Different JVMs use different algorithms to determine how to
collect garbage most efficiently.
In the JVM, memory is allocated in two regions:
Causes of memory leaks in Java
Detection of memory leaks
Causes of memory leaks in enterprise Java applications
First, I executed the application with the
Figure 1 is a heap usage chart provided by JProbe. It gives a runtime summary of the heap memory in use over time as the Java EE application runs. The green area indicates the heap usage. The vertical line indicates a heap usage checkpoint has been set at that time. After setting the checkpoint, the query occurs and the heap memory usage shoots up as objects are created. Once the operation completes, the objects no longer referenced will be garbage collected by the JVM, so the memory usage decreases. Ideally at this time, all new objects should be released and garbage collected, and the heap usage should return to the value before the checkpoint was set. In this case, some new objects continue to occupy memory space, reflecting an increase in heap usage by 166.308 KB. When queried 10 times, the heap memory usage increases by 175.512 KB, as illustrated in Figure 2.
When queried 50 times, the heap memory usage increases by 194.128 KB, as shown in Figure 3.
The observed increase in memory was traced to the connection objects stored in the pool for subsequent reuse. Scenario 2
When queried 10 times, the heap memory usage increases by 217.016 KB.
When queried 50 times, the heap memory usage increases by 425.404 KB
The difference in memory usage after 50 queries with open
Figure 7 clearly shows that 50 objects of
From the referrer tree of
A collection with no policy for removing data causes a memory leak, known as the Leak Collection anti-pattern (read J2EE Design Patterns, for more information on anti-patterns). Recommendation
Example code for the Singleton pattern follows:
The
Once the
After completing 10 query-and-save operations, the increase in memory usage is 175.512 KB.
After performing 50 query-and-save operations, the increase in memory usage is 194.128 KB.
Scenario 2
After 10 query-and-save operations, the increase in memory usage is 178.46 KB.
After 50 query-and-save operations, the increase in memory usage is 216.552 KB.
When the data is stored in
Conclusion
posted @ 2007-02-12 08:49 dennis 閱讀(418) | 評論 (0) | 編輯 收藏 場景:常見的領導關系樹結構,知道某一節點ID,要查出此節點的所有下級(直接下級和間接下級),此時需要使用SQL遞歸語句。
oracle中的遞歸語句:? ![]() ![]() ![]() ![]() 例子: ?pid? id ? a ? b ? ? a ? c ? ? ? a ? e ? ? b ? b1 ? ? b ? b2 ? ? c ? c1 ? ? e ? e1 ? ? e ? e3 ? ? d ? d1 ? ? ? ? 指定pid=a,選出 ? ? a ? b ? ? a ? c ? ? ? a ? e ? ? b ? b1 ? ? b ? b2 ? ? c ? c1 ? ? e ? e1 ? ? e ? e3? SQL語句: ![]() ![]() posted @ 2007-02-11 20:02 dennis 閱讀(1566) | 評論 (1) | 編輯 收藏 為了合并多個select語句的查詢結果,可以使用集合操作符UNION,UNION ALL,INTERSECT和MINUS.語法如下: ? ![]() ? 使用集合操作符有以下一些限制: .對于LOB,VARRAY,嵌套表類來說,集合操作符無效 .對于LONG型,UNION ALL,INTERSECT和MINUS無效 .如果選擇列表包含了表達式,必須指定別名 1。UNION,用于獲取兩個結果集的并集,會自動去掉結果集中的重復行,并會以第一列的結果進行排序,例: ? ![]() ? 2。UNION ALL,與UNION相似,不同的是UNION ALL不會自動去處重復行,也不會以任何列排序 ? ![]() ? 3。INTERSECT,用于獲取兩個結果集的交集,并且以第一列排序,如: ? ![]() ? 4。MINUS,用于獲取結果集的差集(或者說補集),顯示第一個結果集存在的,第2個結果集不存在的數據: ? ![]() ? 注意事項: 1。兩個選擇列表必須完全一致 2。可以連續使用集合操作符,這些操作符擁有相同優先級,多個操作符存在時,從左向右執行,如: ? ![]() ![]() ![]() ![]() ![]() ![]() ![]()
posted @ 2007-02-11 20:01 dennis 閱讀(4739) | 評論 (0) | 編輯 收藏 編寫控制結構:順序結構,條件結構,循環結構 一。條件語句: 1。與delphi或者java,或者其他任何語言的條件語句基本一樣咯: 單條件: IF condition THEN ? ...... END IF; 雙條件: IF condition THEN ? ...... ELSE ? ... END IF; 多條件: IF condition THEN ?? ... ELSEIF conditon THEN ?? .... ELSEIF conditon THEN ?? .... ELSE ?? .... END IF; ? 舉例:
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]()
各種語言的switch ...case語句相同,只不過沒有switch關鍵字。 1。使用單一選擇符進行比較: ? ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ? END CASE; 2。多種條件比較: ? ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() END CASE; ![]() ![]() ![]() ? ? (三)循環語句: 3種循環: 1。基本循環,至少執行一次: LOOP ?? statement1; ???... ?? EXIT WHEN 退出循環條件; END LOOP1; 例如: ? ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ? 2。while循環: WHILE conditon1 LOOP ?? statement1; ?? ... END LOOP; 比如上面的例子改寫為: ? ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ? 3。FOR循環,類似于ruby的FOR循環: FOR counter IN [REVERSE] 下限..上限 LOOP ? statement1; ??... END LOOP; REVERSE參數可選,有的話表示從上限往下限遞減。 ? (四)順序控制語句 PL/SQL也提供了GOTO和NULL語句用于控制語句執行順序,GOTO語句與JAVA的機制相似,通過label來實現跳轉,盡量不要使用。NULL語句不會執行任何操作,它的存在主要是為了提高程序的可讀性。? posted @ 2007-02-11 19:59 dennis 閱讀(924) | 評論 (0) | 編輯 收藏 這部分主要講述在PL/SQL中如何訪問oracle (一)檢索單行數據 在PL/SQL嵌入select語句,使用方法: SELECT select_list INTO variable_name1,variable_name2,variable_name3... FROM TABLE WHRE condition 例: ? ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ? 需要注意事項: 1.不僅可以使用普通標量接受數據,也可以使用Record接受數據 2.使用的SELECT語句必須返回一條記錄,并且只能返回一條記錄,否則會觸發PL/SQL異常,或者顯示錯誤信息 (1)NO_DATA_FOUND異常,當沒有數據返回時拋出此異常 (2)TOO_MANY_ROWS異常,返回多條數據時拋出此異常 (3)在WHERE子句中使用變量時必須注意,變量名不能字段名相同,否則會觸發TOO_MANY_ROWS異常 (二)使用DML語句 1.在PL/SQL中使用DML語句(insert,update,delete)語句與直接在sqlplus使用沒什么不同,只不過可以使用變量代替具體的值,不再舉例 2.SQL游標: (1)在執行SELECT,INSERT,UPDATE,DELETE語句時,Oracle Server會為這些SQL語句分配相應的Context Area,并且Oracle使用此Context Area解析并執行相應的SQL語句,而游標就是指向Context Area的指針。在oracle中,游標又分為顯式和隱式兩種,其中隱式游標又被成為SQL游標,專門用于處理SELECT INTO,INSERT,DELETE,UPDATE語句。而顯式游標多用于處理多行的SELECT語句。 (2)SQL游標的四種屬性: (A) SQL%ISOPEN 用于確定SQL游標是否打開。因為oracle在執行SELECT INTO,INSERT,UPDATE,DELETE語句時會隱含著打開游標,并在執行結束后關閉。所以此值對于開發人員來說一直是false,實際開發中不需要此屬性 (B) SQL%FOUND 用于確定SQL語句是否執行成功,當SQL語句有作用行時,它為TRUE,否則為FALSE,如:
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]()
(D)SQL%ROWCOUNT ,用于返回SQL語句作用的行數 (三)事務控制語句 在PL/SQL中同樣可以使用COMMIT,ROLLBACK,SAVEPOINT等事務控制語句,與直接使用沒有什么不同。 posted @ 2007-02-11 19:57 dennis 閱讀(1067) | 評論 (0) | 編輯 收藏 養成良好的代碼編寫習慣,PL/SQL代碼編寫規則: 1.標識符命名規則 1)定義變量時以v_作為前綴,如v_sal 2)定義常量時以c_作為前綴,如c_rate 3)定義游標時,建議使用_cursor作為后綴,如emp_cursor 4)定義異常時,以e_作為前綴,如e_integrity_error 5)定義PL/SQL表類型時,使用_table_type作為后綴,如sal_table_type. 6)定義表變量時,以_table作為后綴,如sal_table 7)同樣,定義PL/SQL記錄型時以_record_type作為后綴 8)定義PL/SQL記錄變量時以_record作為后綴 ? 2.大小寫規則: 1)SQL關鍵字采用大寫,比如SELECT,DELETE等 2)PL/SQL關鍵字也用大寫,比如DECLARE,BEGIN,END等 3)數據類型也采用大寫,比如VARCHA2 4)標識符和參數采用小寫,如v_sal 5)數據庫對象和列以及別名也才用小寫 3.合適的代碼縮進風格 posted @ 2007-02-11 19:56 dennis 閱讀(1150) | 評論 (0) | 編輯 收藏 定義并使用變量 PL/SQL有四種類型:標量類型,復合類型,引用類型(reference),LOB(Large Obejct)類型 一.標量類型 最常用的就是標量類型,是指只能存放單個數值的變量,包括數字類型、字符類型、日期類型和布爾類型,每種類型又包含相應的子類型。 常量標量類型如下: ? ![]() ? 定義標量: identifier [CONSTANT] datatype [NOT NULL] [:=| DEFAULT expr] 使用標量需要注意的是=號被:=取代,與delphi一樣的賦值符號@_@ 例子: ? ![]() ![]() ![]() ![]() ? 為了防止定義的變量類型與表中的字段類型不一致,可以使用%TYPE來定義: ? ![]() ? 如上面所示,v_name的類型就與表employee中的name字段類型一樣!! 二。復合變量: 用于存放多個值的變量稱為復合變量,包括PL/SQL記錄,PL/SQL表,嵌套表和VARRAY四種類型 1。PL/SQL記錄 類似于C/C++中的結構概念: ? ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ? 2。PL/SQL表,類似于數組概念,不同的是PL/SQL表允許負值下標,而且沒有上下限,如: ? ![]() ![]() ![]() ![]() ![]() ![]() ![]() ? 3。嵌套表,與PL/SQL表相似,不同的是嵌套表可以做表列的數據類型,而PL/SQL表不能,使用嵌套表作為表列時,必須為其指定專門的存儲表,如: ? ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ? 4。VARRAY(變長數組),與嵌套表相似,也可以做為表列的數據類型,但是嵌套表沒有個數限制,而VARRAY有個數限制,如: CREATE TYPE TEST_ARRAY IS VARRAY(20) OF emp_type; 三。引用變量(reference) 類似于C++中的指針或者JAVA中引用的概念,用于存放數值指針的變量,使用此變量,可以使得應用程序共享相同對象,降低占用空間。此類有兩種類型:游標(REF CURSOR)和對象類型(REF OBJECT) 1。REF CURSOR,定義時同時指定SELECT語句的游標稱為顯式或者靜態游標,在打開時才指定SELECT語句的游標稱為動態游標,如: ? ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ?? 2。REF OBJECT,與JAVA的引用概念相同,存儲的是指向對象的指針 ? 四。LOB類型 LOB類型是指用于存儲大批量數據的變量,包括內部的3種(CLOB,BLOB,NCLOB)和外部LOB(BFILE)。 CLOB,NCLOB用于存儲大量的字符數據。 BLOB用于存儲大批量二進制數據(如圖象)。 BFILE則存儲指向OS文件的指針。 posted @ 2007-02-11 19:55 dennis 閱讀(1615) | 評論 (0) | 編輯 收藏 斷斷續續學過,這次系統地來讀讀。 (一) PL/SQL是oracle在標準SQL語言上的過程性擴展,它不僅允許嵌入SQL語句,而且允許定義變量和常量,允許過程語言結構(條件語句和循環語句),允許使用異常處理oracle錯誤等。通過使用PL/SQL,可以在一個PL/SQL塊中包含多條SQL語句和PL/SQL語句。PL/SQL具有以下優點: 1。提高應用系統的運行性能。 通過使用PL/SQL塊包含多條SQL語句,從而減少了SQL語句的發送次數,降低了網絡開銷,提高了應用程序性能 2。提供模塊化的程序設計功能。 將企業規則和商業邏輯集成到PL/SQL子程序當中,提供給客戶端調用,簡化了客戶端應用程序的開發和維護工作,降低了耦合度 3。允許定義標識符,允許定義變量、常量、游標和異常等標識符 4。具有過程語言控制結構,允許使用條件分支語句和循環語句 5。具有良好的兼容性,在允許運行oracle的任何平臺上執行,不僅在數據庫服務端執行,也可以在oracle提供的工具中開發PL/SQL 6。處理運行錯誤,使用PL/SQL提供的EXCEPTION,開發人員可以集中處理各種oracle錯誤和PL/SQL錯誤,簡化了錯誤處理。 (二) PL/SQL塊的概念: Block是PL/SQL的基本單元,編寫PL/SQL本質上就是編寫PL/SQL塊,塊的嵌套層次沒有限制。 1。塊的結構:塊由3部分組成 ? ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ? 其中只有執行部分是必須的! 2。分類: 1)匿名塊,匿名塊是指沒有名稱的PL/SQL塊,可以內嵌到應用程序中,如:
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]()
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]()
A。過程用于執行特定操作,當建立過程時既可以指定輸入參數,也可以指定輸出參數,從而在應用環境和程序間傳遞數據,使用CREATE PROCEDURE語句,如:
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]()
? ![]() ![]() ![]() ![]() ![]() ![]() ![]() ? C)包,類似JAVA包的概念,包含兩部分,包規范和包體,包規范相當于C++中的頭文件聲明子程序,而包體包含這些子程序的具體實現。調用包中的子程序時,需要 ‘包名.子程序名’ 這樣的形式調用 4。觸發器是指隱含執行的存儲過程,定義觸發器需要指定觸發事件和觸發操作,常見觸發事件如insert,update,delete等,使用CREATE?TRIGGER命令建立 posted @ 2007-02-11 19:52 dennis 閱讀(1015) | 評論 (0) | 編輯 收藏 ??? 網上到處充斥這c#與java對比的文章,看了看,還是覺的MSDN上的一篇文章很全面和客觀。《針對JAVA開發人員的C#編程語言》。
??? 我的第一天C#學習,總體感覺C#在語言層面上保留了更多C++/C的特點,比如virtual,override關鍵字的使用,比如結構(值類型,存儲在棧上),比如delegate(類似函數指針)。比較感興趣的也就是delegate、事件和attribute方面。C#某種意義上講比java稍微復雜,比C++簡單。 ??? 參照語言規范寫的例子,抽象類、繼承的例子,可以擴展成一個簡單計算器: using?System; using?System.Collections; namespace?VirtualDemo { ????public?abstract?class?Expression ????{ ????????public?abstract?double?Evaluate(Hashtable?vars); ???????? ????} ????public?class?Constant?:?Expression ????{ ????????double?value; ????????public?Constant(double?value) ????????{ ????????????this.value?=?value; ????????} ????????public?override?double?Evaluate(Hashtable?vars) ????????{ ????????????return?value; ????????} ????} ????public?class?VariableReference?:?Expression ????{ ????????string?name; ????????public?VariableReference(string?name) ????????{ ????????????this.name?=?name; ????????} ????????public?override?double?Evaluate(Hashtable?vars) ????????{ ????????????object?value?=?vars[name]; ????????????if?(value?==?null) ????????????{ ????????????????throw?new?Exception("Unknown?variable:?"?+?name); ????????????} ????????????return?Convert.ToDouble(value); ????????} ????} ????public?class?Operation?:?Expression ????{ ????????Expression?left; ????????char?op; ????????Expression?right; ????????public?Operation(Expression?left,?char?op,?Expression?right) ????????{ ????????????this.left?=?left; ????????????this.op?=?op; ????????????this.right?=?right; ????????} ????????public?override?double?Evaluate(Hashtable?vars) ????????{ ????????????double?x?=?left.Evaluate(vars); ????????????double?y?=?right.Evaluate(vars); ????????????switch?(op) ????????????{ ????????????????case?'+':?return?x?+?y; ????????????????case?'-':?return?x?-?y; ????????????????case?'*':?return?x?*?y; ????????????????case?'/':?return?x?/?y; ????????????} ????????????throw?new?Exception("Unknown?operator"); ????????} ????} ????public?class?Test ????{ ????????public?static?void?Main(string?[]args) ????????{ ????????????Expression?e?=?new?Operation( ????????????new?VariableReference("x"), ????????????'*', ????????????new?Operation( ????????????????new?VariableReference("y"), ????????????????'+', ????????????????new?Constant(2) ????????????) ????????); ????????Hashtable?vars?=?new?Hashtable(); ????????vars["x"]?=?3; ????????vars["y"]?=?5; ????????Console.WriteLine(e.Evaluate(vars));????????//?Outputs?"21" ????????vars["x"]?=?1.5; ????????vars["y"]?=?9; ????????Console.WriteLine(e.Evaluate(vars));????????//?Outputs?"16.5" ????????} ????} } 再來一個委托的例子,函數作為變量的傳遞和使用,對有C++經驗或者動態語言經驗的人來說不會奇怪: using?System; namespace?DelegateDemo { ????delegate?double?Function(double?x); ????class?Multiplier ????{ ????????double?factor; ????????public?Multiplier(double?factor) ????????{ ????????????this.factor?=?factor; ????????} ????????public?double?Multiply(double?x) ????????{ ????????????return?x?*?factor; ????????} ????} ????class?Test ????{ ????????static?double?Square(double?x) ????????{ ????????????return?x?*?x; ????????} ????????static?double[]?Apply(double[]?a,?Function?f) ????????{ ????????????double[]?result?=?new?double[a.Length]; ??????????? //直接通過f()調用 ????????????for?(int?i?=?0;?i?<?a.Length;?i++)?result[i]?=?f(a[i]); ????????????return?result; ????????} ????????static?void?Main() ????????{ ????????????double[]?a?=?{?0.0,?0.5,?1.0?}; ??????????? //delegate Function分別賦予了不同的方法 ????????????double[]?squares?=?Apply(a,?new?Function(Square)); ????????????double[]?sines?=?Apply(a,?new?Function(Math.Sin)); ????????????Multiplier?m?=?new?Multiplier(2.0); ????????????double[]?doubles?=?Apply(a,?new?Function(m.Multiply)); ????????????foreach?(double?b?in?doubles) ????????????{ ????????????????Console.WriteLine(b); ????????????} ????????} ????} } posted @ 2007-02-10 17:39 dennis 閱讀(691) | 評論 (0) | 編輯 收藏 |
|||||||||||||||||||||||||||||||||