qileilove

          blog已經轉移至github,大家請訪問 http://qaseven.github.io/

          Sybase系統維護經驗談

           Sybase數據庫系統作為C/S構架的主流產品在我國有著廣泛的應用,因此,對Sybase系統的維護也顯得至關重要。筆者在對Sybase系統維護工作中,總結了一些技巧和經驗,現介紹給大家。

            1、實現開機時自動裝載Sybase數據庫

            原先要使Sybase SQL Server啟動,一般需要先以sybase用戶登錄,然后運行$SYBASE/install目錄下

            的startserver命令啟動SYBASE_XXXX服務進程和SYB_BACKUP_XXXX備份服務進程。

            要實現Unix系統啟動時就能在后臺裝載Sybase的功能,我們可在/etc/rc2.d/目錄下新建一文件S99sybase,

            內容如下:

          以下是代碼片段:
              SYBASE=/usr/sybase
            PATH=$PATH:$SYBASE/bin
            export $SYBASE $PATH
            $SYBASE/install/startserver -f $SYBASE/install/RUN_SYBASE_XXXX > /dev/null
            $SYBASE/install/startserver -f $SYBASE/install/RUN_SYB_BACKUP_XXX >/dev/null

            然后修改Sybase的權限,重啟系統即可。

            2、實現關機時自動卸載Sybase數據庫

            為保證Sybase系統的正常運行,每次在關閉Unix系統時要先結束Sybase SQL Server 的服務進程,從減輕

            系統管理人員操作的角度出發建立一用戶halt,修改/etc/passwd文件,將halt用戶的uid改為0(或其他可運行

            shutdown的用戶id),在/usr/halt/.profile中添加以下語句:

          以下是代碼片段:
              SYBASE=/usr/sybase
            DSQUERY=SYBASE_XXXX
            PATH=$PATH:$SYBASE/bin
            export SYBASE DSQUERY PATH
            isql -Usa -Pabcabc -ihalt.sql > /dev/null
            shutdown -y -g0

            其中“abcabc”為sa用戶的口令,halt.sql是一簡單的文本文件,內容如下:

          以下是代碼片段:
              shutdown
            go

            這樣每次只要以halt用戶登錄,就實現了自動卸下Sybase數據庫,然后關閉Unix系統。

            3、Sybase庫備份技巧

            一般對Sybase庫進行備份都用磁帶作介質進行,但還有一更好的方法,即先備份到硬盤上然后經壓縮,

            拷貝到磁帶上,這樣便于恢復,多了一個備份拷貝,同時也節省了備份時間。具體實現步驟如下:

            (1)建立磁盤備份設備

            運行isql,以sa進入Sybase系統,運行如下內容:

          以下是代碼片段:
              sp_addumpdevice "disk",disk_bkupdevice ,/tmp/dumpdb ,2
            go

            這樣就在Sybase中建立了一個名為“disk_bkupdevice”的備份設備,它對應Unix系統下的/tmp/dumpdb文件。

            (2)創建備份用戶

            以root身份進入Unix系統,新建用戶backupdb,并歸屬于sybase組。

            (3)修改相關文件

            在/usr/backupdb/.profile中添加以下語句:

          以下是代碼片段:
              SYBASE=/usr/sybase
            DSQUERY=SYBASE_XXXX
            PATH=$PATH:$SYBASE/bin
            export SYBASE DSQUERY PATH
            rm /tmp/backupdb.Z
            echo"開始備份SYBASE數據庫…"
            isql -Usa -Pabcabc -ibackup.sql > /tmp/dbbackup.log
            echo"硬盤備份完成,正在壓縮備份的數據文件…"
            compress /tmp/backupdb
            echo "正在將備份的壓縮數據拷入磁帶…"
            tar c8v /tmp/backupdb.Z
            echo "備份完成!"

            其中"abcabc"為sa用戶的口令,backup.sql是一簡單的文本文件,內容如下:

          以下是代碼片段:
              dump database db_main to disk_bkupdevice
            go

            備份的執行日志被記錄在/tmp/dbbackup.log中,當然系統管理員也可通過查看$SYBASE/install/backup.log獲知備份日志。

            這種備份方法要求硬盤空間足夠大,這點請系統管理員在為Unix建分區時特別注意。

            在SCO Open Server 5.0.4、Sybase 11.0.3平臺上,以上幾個小技巧已應用成功,為筆者的日常維護節省了許多時間,取得了非常好的效果。

          posted @ 2011-12-05 13:35 順其自然EVO 閱讀(139) | 評論 (0)編輯 收藏

          精解Java中代理模式的實現

            簡介摘要: 代理模式是GOF設計模式中的一種,常用于權限模塊的架構設計,其根本的原理是通過將一個代理對象交給調用者,使得調用者不能直接使用相應的功能模塊,所 有的調用被傳遞給代理對象,代理對象負責對真實模塊完成調用,在調用者與被調用者之間建立了一個隔離帶,我們可以使 代理模式是GOF設計模式中的一種,常用于權限模塊的架構設計,其根本的原理是通過將一個代理對象交給調用者,使得調用者不能直接使用相應的功能模塊,所有的調用被傳遞給代理對象,代理對象負責對真實模塊完成調用,在調用者與被調用者[bei tiao yong zhe]之間建立了一個隔離帶,我們可以使用這個隔離帶進行權限檢查、對象的延遲[yan chi] 加載等功能的實現。這里不對這個設計模式的具體原理多加解釋[jie shi],我們直接通過一個實例的編寫來完成對代理模式的應用[ying yong],在理解了代理模式之后,我們將繼續介紹 java中提供的一種動態[dong tai]代理技術與其實現。

            這里我們假設有一個用戶管理模塊,這個模塊提供了添加用戶、刪除用戶的功能。我們現在要使用代理模式來檢查權限該如何實現呢?首先我們需要具有一個類叫User用來表示一個用戶的信息[xin xi],代碼如下:

        1. public class User { 
        2.        private String username; 
        3.        private String password; 
        4.        public User() { 
        5.        } 
        6.        public User(String username, String password) { 
        7.                this.username = username; 
        8.                this.password = password; 
        9.        } 
        10.  }
        11.   為了提供功能模塊,并且希望能夠隔離模塊,我們需要設計一個接口來定義用戶管理模塊的接口,這里我們定義IUserFace接口,代碼如下:

        12. public interface IUserFace { 
        13.        public void addUser(User user); 
        14.        public void removeUser(User user); 
        15. }
        16.   接下來為這個接口編寫一個真正實現具體功能的類出來,定義為UserFaceImpl,代碼如下:

        17. public class UserFaceImpl implements IUserFace { 
        18.        public void addUser(User user) { 
        19.                //這里處理相關的添加用戶的代碼任務 
        20.                //比如說連接數據庫,執行相關的SQL語句 
        21.                System.out.println("Add User Successfully"); 
        22.        } 
        23.        public void removeUser(User user) { 
        24.                //這里處理相關的刪除用戶的代碼任務 
        25.                //比如說連接數據庫,執行相關的SQL語句 
        26.                System.out.println("Remove User Successfully"); 
        27.        } 
        28. }
        29.   好了,現在我們對外提供的功能具備了,那么使用者該如何使用這個功能的實現類呢?為了讓外界對具體功能類的使用透明化,我們實現一個工廠類來負責創造具體功能模塊的對象,并以接口的形式提供外界使用,這樣將來更換相關模塊的使用將會比較方便。具體工廠類(FaceFactory)代碼如下:

        30. public class FaceFactory { 
        31.        private static FaceFactory instance; 
        32.        private FaceFactory() { 
        33.        } 
        34.        public static FaceFactory getInstance() { 
        35.                if(instance == null) { 
        36.                        instance = new FaceFactory(); 
        37.                } 
        38.                return instance; 
        39.        } 
        40.        public IUserFace createUserFace() { 
        41.                return new UserFaceImpl(); 
        42.        } 
        43. }

        44.  完成了工廠類的代碼,我們可以使用具體模塊,這里我們編寫一個App.java來使用以下具體功能模塊,代碼如下:

        45. public class App { 
        46.        public static void main(String args[]) { 
        47.                User u = new User(); 
        48.                IUserFace uf = FaceFactory.getInstance().createUserFace(); 
        49.                uf.addUser(u); 
        50.        } 
        51. }
        52.   從上面代碼我們可以看到,代碼中并沒有提及UserFaceImpl這個類,這保證了將來如果需要跟換UserFaceImpl這個類的使用,調用者的代碼將不需要做任何的修改。好了,現在我們要來研究一下權限的問題,在這個例子中,我們可能需要在添加用戶或者刪除用戶的時候進行權限檢查,符合權限的才能執行相關動作,否則不能執行,那么該如何修改代碼才能更加貼切,而且在實際的編寫過程中,雖然我們需要權限模塊,但有時候為了更好地快速測試,我們常常希望暫時關閉權限模塊,如何才能讓這樣的臨時需求變得更加容易處理呢?我們現在使用代理模式來完成這樣的任務,現在繼續編寫一個類叫 UserFaceProxy,讓它也實現IUserFace接口,也許你會說,不是已經有一個類實現了這個接口了嗎?為什么還要寫一個?不要著急,看完這個代碼,你就會了解其中的道理了。

        53. public class UserFaceProxy implements IUserFace { 
        54.        private IUserFace userFace; 
        55.        public UserFaceProxy(IUserFace userFace) { 
        56.                this.userFace = userFace; 
        57.        } 
        58.        public void addUser(User user) { 
        59.                //在這里檢查權限,如果權限不合法則拋出異常
        60.                userFace.addUser(user); 
        61.        } 
        62.        public void removeUser(User user) { 
        63.                //在這里檢查權限,如果權限不合法則拋出異常
        64.                //如果權限通過則完成下面的工作 
        65.                userFace.removeUser(user); 
        66.        } 
        67. }
        68.   在代碼中你可以看到,這個代理類在構造對象的時候需要傳入一個實現了IUserFace接口的類的對象,當代理類對象的方法被調用的時候,首先檢查權限,如果權限檢查不通過,那么則拋出異常,通過的話則調用構造時傳入對象的相應方法]來完成真是的工作。這樣的話,我們需要繼續修改工廠類的代碼如下:

        69. public class FaceFactory { 
        70.        private static FaceFactory instance; 
        71.        private FaceFactory() { 
        72.        } 
        73.        public static FaceFactory getInstance() { 
        74.                if(instance == null) { 
        75.                        instance = new FaceFactory(); 
        76.                } 
        77.                return instance; 
        78.        } 
        79.        public IUserFace createUserFace() { 
        80.                IUserFace userFace = new UserFaceImpl(); 
        81.                IUserFace proxy = new UserFaceProxy(userFace); 
        82.                return proxy; 
        83.        } 
        84. }
        85.   好了,到這里你是不是已經明白了?通過這樣的代理模式我們完成了權限檢查的隔離處理,當需要臨時關閉權限檢查的時候,我們只需要在如上的代碼中return userFace;就可以了。這就是代理模式在實際中的應用步驟。


          posted @ 2011-12-05 13:32 順其自然EVO 閱讀(141) | 評論 (0)編輯 收藏

          軟件質量保證管理辦法

          本文檔的目的是為特定產品、項目或合同的質保工作提供指導,幫助項目組其他成員了解質量保證要素,明確質量保證活動,確定質量保證范圍。本文檔將規定項目質量管理員的職責和權利,資源要求,活動安排,進度,要求質量保證活動中必須生成的文檔,反饋問題的方法和頻度等。
            一、管理組織
            本公司的軟件質量保證活動統一由質量管理員進行管理、檢查與匯報,公司相關部門經理及項目中的項目經理、程序經理、開發經理、測試經理、產品經理、測試經理、用戶教育經理是質量保證活動中的第一責任人。
            二、軟件開發過程
            本公司的軟件開發過程分為以下8個階段:項目策劃階段、需求分析階段、設計階段、開發階段、測試階段、實施階段、驗收階段、維護階段,每個階段的主要活動分別為:業務啟動和項目規劃、需求分析、邏輯設計和物理設計、軟件開發、軟件測試、系統實施及用戶培訓、用戶試用及驗收、維護,里程碑分別為:策劃完成、需求明確、設計完成、開發完成、測試通過、系統上線、驗收通過、合同結束。每階段結束后,必須對相應的里程碑進行檢查,方式為評審或批準。
            三、項目文檔
            項目文檔分為兩種:管理類文檔與技術類文檔,所有文檔必須保存于知識庫及相應的VSS庫中。文檔共有三種狀態:編制完成、審核通過、批準通過。其中管理類文檔只有編制和批準兩種狀態,技術類文檔擁有所有三種狀態。所有文檔必須明確說明當前文檔版本號。
            管理類文檔包含以下類型:計劃、總結、報告、會議紀要、備忘錄、申請等。技術類文檔包含:設計文檔、需求文檔、測試設計文檔、界面原型軟件、使用手冊、安裝手冊、技術白皮書、培訓資料、源代碼、軟件產品等。除VSS庫中的文檔以外,放入知識庫中的文檔由部門助理統一放入,文檔必須批準通過。
            文檔的編制、審核、批準可在文檔中直接寫明,也可使用單獨的審批文檔進行說明。
            每個項目在不同階段必須產生的文檔如下,但不限于此:
            1、項目開始前:
            合同、技術方案、市場立項表。以上文檔存放于知識庫。
            2、項目策劃階段:
            業務啟動表(EXCEL格式)、項目規劃(WORD格式)、項目進度(PROJECT格式)等。必須使用規定模板編寫。以上文檔存放于知識庫。
            3、需求分析階段:
            需求模型(EA格式)、軟件需求規格說明書(WORD格式)、單據報表格式(EXCEL格式)、需求分析評審表(WORD格式)、需求分析計劃(WORD格式和PROJECT兩種格式)。必須使用規定模板編寫。以上文檔存放于知識庫。
            4、設計階段
            軟件開發計劃(PROJECT格式)、邏輯設計(EA格式)、物理設計(VS.NET格式)、設計評審表(WORD格式),必須使用規定模板編寫。物理設計存放于VSS庫,其它文檔存放于知識庫。
            5、開發階段
            源代碼、可安裝的軟件、安裝手冊、評審表(WORD格式)。源代碼、可安裝的軟件存放于VSS庫,其它文檔存放于知識庫。
            6、測試階段
            測試用例設計、軟件BUG、測試計劃(WORD格式和PROJECT兩種格式)、測試報告(WORD格式)、開發的測試工具源代碼及軟件、測試通過的軟件產品、軟件評審表(WORD格式)。開發的測試工具源代碼及軟件、測試通過的軟件產品存放于VSS庫,其它文檔存放于知識庫。軟件BUG存于TD中。

           7、實施階段
            實施計劃(WORD格式和PROJECT兩種格式)、實施報告(WORD格式)、用戶使用手冊、用戶培訓資料、用戶培訓記錄、軟件問題反饋表(EXCEL格式)、上線報告(書面、電子掃描件)等。必須使用規定模板編寫。以上文檔存放于知識庫。
            8、驗收階段
            驗收材料、驗收報告(書面、電子掃描件)。以上文檔存放于知識庫。
            9、維護階段
            維護報告(WORD格式),以上文檔存放于知識庫。
            四、檢查和審查
            本公司的項目關鍵檢查點有以下8個,采取評審和批準的方式,由質量管理員進行跟蹤。
            1、策劃完成里程碑
            以總經理批準通過業務啟動表為標志,質量管理員檢查業務啟動表、項目規劃、項目風險控制計劃、項目進度、技術方案文檔是否進入知識庫。負責人為項目經理。
            2、需求明確里程碑
            以軟件需求評審通過為標志,評審通過后由配置管理員建立軟件功能基線。項目由用戶代表、公司代表、同行、下游人員(程序經理、開發經理、測試經理、用戶教育經理)進行評審,評審記錄上必須有以上幾類角色的人員進行簽名。質量管理員檢查需求規格說明書、需求模型、需求評審表是否進入知識庫。負責人為產品經理。
            3、設計完成里程碑
            以邏輯設計和物理設計通過評審為標志,它包含兩個部分:邏輯設計與物理設計。邏輯設計評審通過后由配置管理員建立指派基線1,物理設計評審通過后由配置管理員建立指派基線2。邏輯設計評審參與人員必須包括:公司代表、產品經理、開發經理、測試經理、同行。物理設計評審參與人員必須包括:公司代表、程序經理、測試經理、同行。質量管理員檢查邏輯設計、物理設計、設計評審表是否進入知識庫或VSS庫。邏輯設計負責人為程序經理、物理設計負責人為開發經理。
            4、開發完成里程碑
            以軟件所有功能開發完成,并通過評審為標志,它的評審必須包括:公司代表、產品經理、程序經理、測試經理。質量管理員檢查評審表是否進入知識庫。負責人為開發經理。
            5、測試通過里程碑
            以軟件評審通過作為標志,評審通過后將建立產品基線。評審參與人員必須包括:公司代表、產品經理、開發經理、實施經理、用戶教育經理。質量管理員檢查測試報告、軟件評審表是否進入知識庫。負責人為測試經理。
            6、系統上線里程碑
            以用戶簽署通過上線報告為標志,評審參與人員必須包括:用戶代表、公司代表、項目經理。質量管理員檢查上線報告、實施計劃、培訓材料等文檔是否進入知識庫。如上線報告為紙質文檔,則掃描后入庫。負責人為實施經理。
            7、驗收通過里程碑
            以用戶簽署通過驗收報告為準,評審參與人員必須包括:用戶代表、公司代表、項目經理。質量管理員檢查驗收報告文檔是否進入知識庫,如上線報告為紙質文檔,則掃描后入庫。負責人為項目經理。
            8、合同結束里程碑
            合同結束,項目跟蹤完成。負責人為軟件業務部技術服務組長。

            五、測試
            本公司的軟件必須通過測試。測試工作由開發部測試組負責,所有測試出來的BUG必須統一存放,由測試組負責管理。在測試活動進行前必須有測試計劃,測試完成后必須編寫測試報告。測試報告由測試經理負責編寫,測試組長批準。
            六、配置管理
            軟件開發過程中的配置管理工作由配置管理員負責,配置管理工作詳細要求依據《配置管理規范》進行。
            七、媒體控制
            在軟件開發過程中產生的正式文檔必須存入于知識庫中或VSS庫中,由公司系統管理員負責每天進行物理備份。在項目進行過程中的備份采用移動硬盤進行,已結項的項目使用刻錄光盤存檔備份。
            八、質量記錄
            質量記錄主要包括各種評審記錄和審批記錄,形式有評審表、簽名文件、會議紀要、質量報告等。所有的質量記錄由質量管理員統一管理,紙質的保存在指定的文件柜中,電子的保存在知識庫中。質量記錄的保存期限是3年。
            九、風險和應急
            公司所有的項目必須有獨立的風險控制計劃,風險控制計劃由項目經理負責編寫并跟蹤,風險控制計劃由項目管理部門批準。風險計劃中必須包括風險列表、風險度、應急方案、緩解方案、責任人、風險狀態。風險度由風險發生可能性和風險造成的危害程度相乘得到。
            十、質量報告
            項目的質量管理員必須在每周五12:00以前制作當前的項目質量報告,報告公司當前正在進行的項目的質量狀態。主要包括:項目文檔的審核情況、存放情況、完備情況;各里程碑的評審執行情況;各種計劃的跟蹤情況,責任人是否及時更新計劃;各項規范的符合程度;等等。質量報告屬于項目狀態報告的一部分,與其一同填寫。具體格式參見《項目狀態報告》。
            十一、質量會議
            質量會議與公司的項目月例會合并召開,開會時必須提交質量報告。參會人員必須包括軟件業務部部門經理、產品組組長、實施組組長和開發部部門經理、開發組組長、技術支持組組長、測試組組長、各項目經理。如遇特殊情況,質量管理員可臨時針對某類問題發起會議,會議結束時必須有會議紀要并存檔。
            十二、工具及技術
            在進行質量保證活動中,主要使用兩種工具軟件:知識管理系統和MS Visual SourceSafe。前者用來存放項目產生的各種文檔,后者主要用于存放源碼。公司在所有正式場合中所使用的項目文檔均以這兩個系統中的數據為準。在使用工具軟件的過程中,各項目成員的權限統一由公司文檔管理員進行分配。
            十三、變更控制委員會
            公司所有在建項目必須成立變更控制委員會,該委員會最小要包括以下人員:用戶代表、市場代表、軟件業務代表、開發代表、項目經理,但不限于此。一般情況下,產品經理、程序經理、開發經理、測試經理、實施經理、用戶教育經理也可包括在該組織中。對于維護性項目,變更控制委員會由營銷中心主任、軟件業務部經理、開發部經理組成。

          posted @ 2011-12-05 09:41 順其自然EVO 閱讀(267) | 評論 (0)編輯 收藏

          測試用例及時更新的可實施性

            1、案例描述

            測試團隊目前面臨一個非常嚴峻的問題:測試用例得不到有效執行的問題。

            導致此問題的主要原因在于當前的測試用例可用性較差,針對系統原有功能的測試用例主要存在以下三個問題:

            第一,存在較多冗余的測試用例,在測試執行過程中執行此類用例浪費時間而且沒有價值;

            第二,存在較多與當前系統實現不一致的用例,此類用例嚴重誤導測試執行人員,并容易造成新加入項目的測試人員對系統理解的混亂;

            第三,存在一些重復的測試用例,此類用例的反復執行雖然可能可以確保某一功能實現的正確性,但確可能造成嚴重的資源浪費,特別是當此類功能并非系統的主要功能時這樣的時間浪費在項目時間非常緊迫的情況下是非常不值得的。

            雖然一再要求測試人員及時更新測試用例,一再強調測試用例的重要性,但仍存在大量的測試用例未能得到有效的維護。

            2、案例分析

            相信每一個做測試的都清楚的知道測試用例對于測試工作的重要性,但是由于主觀或客觀的種種因素導致很多測試人員或測試組對測試用例的編寫/維護不夠重視,那么為了讓我們的測試用例能夠真正的發揮其作用,我們就在此再次重申一下測試用例編寫及維護的意義,以及測試用例維護需要注意的問題。

            我們先說一下測試用例編寫及維護的意義。

            首先,在測試過程中測試用例可以幫你理清頭緒,從而讓你能夠進行比較系統的測試,避免在測試過程中產生遺漏;

            其次,便于bug的記錄及重現,從而方便與開發人員的溝通交流;

            第三,確保對系統功能的全覆蓋測試,同時方便將系統使用過程中或測試執行過程偶然遇到的一些問題添加到測試用例中,從而避免以后同樣的問題再次發生;

            第四,在測試時間緊迫的情況下,測試用例可以幫你分清重點(前提當然是測試用例中有標注重要程度和優先級),以確保在緊急情況對重點功能的保障;

            最后,測試用例執行情況的記錄可以方便測試經理或項目經理及時了解測試進度,以及方便對測試人員的工作效率進行考核。

            基于測試用例的上述作用那就要求測試用例必須與產品功能/特性保持一致,而由于我們的產品在不斷地升級/完善,為了確保測試用例與產品的功能/特性的變化保持一致,那就需要我們的測試用例也要不斷地更新完善,只有及時進行測試用例的維護才能確保測試用例的完整性和有效性。

            如果不能及時對測試用例進行維護,那將會使其成為一堆廢紙,而由于系統需求與設計的不斷變更,將導致新加入的測試工程師或對系統不是很了解的測試人員在執行測試用例時不知所措,開發人員在多次被無效的缺陷打擾后,進而導致開發人員對測試人員的信任度嚴重降低,這對于系統測試工作的推進及合作是非常不利的。

            測試用例的維護是一個不間斷的過程,維護的主要內容包括以下幾個方面:

            (1)刪除過時的測試用例因為需求的改變等原因可能會使一個基線測試用例不再適合被測試系統,這些測試用例就會過時。例如,某個功能被取消了,原來針對此功能的測試就無法完成對新功能的測試。所以,在軟件的每次修改后都應進行相應的過時測試用例的刪除。

            (2)改進不受控制的測試用例隨著軟件項目的進展,測試用例庫中的用例會不斷增加,其中會出現一些對輸入或運行狀態十分敏感的測試用例。這些測試不容易重復且結果難以控制,會影響回歸測試的效率,需要進行改進,使其達到可重復和可控制的要求。

            (3)刪除冗余的測試用例如果存在兩個或者更多個測試用例針對一組相同的輸入和輸出進行測試,那么這些測試用例是冗余的。冗余測試用例的存在降低了回歸測試的效率。所以需要定期的整理測試用例庫,并將冗余的用例刪除掉。

            (4)增添新的測試用例如果某個程序段、構件或關鍵的接口在現有的測試中沒有被測試,那么應該開發新測試用例重新對其進行測試。并將新開發的測試用例合并到基線測試包中。

            (5)測試用例需要經常的按其邏輯性對其順序進行整理,雜亂無章也不利于測試人員的執行,帶有一定的邏輯性順序,可方便測試人員的執行,極大地提高了工作效率。

            3、解決過程

            通過上述分析我們可以看到及時有效地維護測試用例可以最大限度的實現測試用例的重復使用,同時可以最大可能確保測試用例的完整性和有效性。而一份完整、有效地測試用例可以很好的發揮其測試指導的功能,實現其幫助新加入項目人員快速學習了解系統使用的功能,同時還可以縮短用例的編寫時間,從而有效提高測試工作的效率。

            基于上述因素的考慮,以及測試組目前已積累了不少測試用例,但長期無人維護,因此現在我們正嘗試著在每一個項目的測試計劃中安排用例的編寫及更新的時間,在每一個項目的測試過程中完成新增功能的用例編寫同時,逐步完成早期被復用的用例的更新完善,要求做到被復用的用例至少與當前項目的規格是保持一致的;而對于早期用例與早期版本的相關性則嘗試通過技術支持組在做外部技術支持的過程中逐步進行更新完善;當然為了能較好的執行用例的及時更新完善還需要以下配套措施:

            (1)為每個項目組成員指定負責更新完善的某一模塊的測試用例,用例的更新完善做為工作內容安排進工作計劃,各LTM在制定周計劃時考慮用例完善的時間(可以利用固定加班時間完成用例的編寫),盡量避免由于時間不夠導致的用例更新完善的時間被延后,同時鑒于測試用例編寫的工作是可以進行基本的預估的,因此用例編寫及維護工作完成的及時性將作為個人工作績效考核的參考依據;

            (2)要求每個項目組成員在執行用例的過程中發現當前用例與實際實現/規格不一致時,要主動進行確認,若確認后發現確實是用例的問題,可進行用例的修改,修改完成后要求填上自己的大名,同時郵件通知組內其他人員,以便LTM進行用例更新完善有效性的統計,此統計數據將會作為個人工作績效考核的參考依據;(注:此處的用例有效性包括:所修改的用例修改是否正確、新增的用例是否有助于覆蓋當前業務功能的所有邏輯、新增用例是否有助于發現當前系統中的更多bug)

            (3)為了使測試用例盡可能全面覆蓋其對應的系統規格及系統實現,無論是新增的測試用例還是維護的測試用例都需要經過組內人員的共同討論評審。一個人對整個系統/某個功能的理解及經驗始終是有限的。測試用例的評審的主要目的就是集眾人的經驗及認識于一體,對測試用例進行查漏補缺,使得測試用例的有效性進一步提升。因此就要求所有參與評審的人員都要貢獻出自己的智慧、積極主動的參與到評審中。同樣為了使用例評審能真正發揮其作用,用例的編寫/維護人員就需要提前至少一天將需要評審的內容以郵件的形式發送給評審會議相關人員。并注明詳審時間、地點及參與人員,而參與評審的人員在評審之前至少簡讀一遍用例,在會議進行中,會議主持者/會議記錄人需記錄評審過程中每一個建議/問題以及建議/問題的提出人,而每一個建議/問題都應該有相應的解決方案,只有這樣才能真正提高測試用例的有效性。通過用例評審會議的會議紀要考核每一個參與人員對用例評審的積極性,同時此類數據可作為個人工作績效考核的參考依據;

            (4)為了確保測試用例的正確性及完整性,無論是新增的測試用例還是更新完善的測試用例都需要經過組內資深人員參與的評審,而作為用例編寫者/用例的更新人需要負責發起用例的評審,對于當前進行中的項目,用例在完成組內評審后還需進行項目組內的評審,只有經過評審的并且所有參與評審人員達成共識的測試用例才是有效的可用的用例,才是可以指導測試工作順利進行的測試用例,因此對于當前進行中的項目的測試用例的評審可以利用常規的工作時間進行,從而確保用例的及時評審測試工作的及時進行,而對于一些早期維護用例的評審建議安排常規加班時間進行,從而確保當前測試工作的正常進行,盡可能減少用例評審對當前測試工作的沖擊。

            4、解決結果

            希望通過上述努力能使我們的測試用例逐步完善,同時測試人員養成及時更新維護用例的習慣,從而有效地改善我們測試用例的可用性,實現其指導測試的作用,并幫助新人快速學習了解系統的應用,從而有效地提高測試人員的工作效率,同時盡可能通過用例的有效復用縮短項目的測試周期,并提供項目的測試質量。

          posted @ 2011-12-05 09:39 順其自然EVO 閱讀(442) | 評論 (0)編輯 收藏

          邊界測試——讓BUG現形

            題目:寫一個函數,輸入一行字符,將此字符串中最長的單詞輸出。

          #include <stdio.h>

          #include <string.h>

          int main()

          {int alphabetic(char);

          int longest(char []);

          int i;

          char line[100];

          printf("input one line:\n");

          gets(line);

          printf("The longest word is:");

          for(i=longest(line);alphabetic(line[i]);i++)

          printf("%c",line[i]);

          printf("\n");

          return 0;

          }



          int alphabetic(char c)

          {

          if((c>='a'&&c<='z')||(c>='A'&&c<='z'))

          return(1);

          else

          return(0);

          }



          int longest(char string[])

          {int len=0,i,length=0,flag=1,place=0,point;

          for(i=0;i<=strlen(string);i++)

          if(alphabetic(string[i]))

          if(flag)

          {point=i;

          flag=0;

          }

          else

          len++;

          else

          {flag=1;

          if(len>=length)

          {length=len;

          place=point;

          len=0;

          }

          }

          return(place);

          }

            運行結果:

            input a line:             
            I am a student.           
            The longest word is : student

            題目要求“寫一個函數,輸入一行字符,將此字符串中最長的單詞輸出”,可是無論alphabetic()還是longest()函數都沒有實現“輸入一行字符,將此字符串中最長的單詞輸出”這個功能要求。疑惑很久,發現實現這個功能的函數居然是main()。這就難免讓人貽笑大方了。因為按照常規的慣例,要求寫一個函數實現某個功能,從來不是要求寫main(),盡管不能說main()不是“一個函數”。然而如果是要求main()完成的事情,通常是作為一個完整的問題提出的,不會提出“寫一個函數”這樣的要求。如果硬要狡辯“寫一個函數”也不排除是寫main(),就牽強的近乎強詞奪理了。不過設若真的有人如此嘴硬,你還真拿他沒什么辦法。

            既然是不見棺材不掉淚,那就不妨繼續往下看。

            在代碼中一眼瞄見了flag這個變量。經驗表明,凡是有這個flag變量的代碼,80%以上都是垃圾代碼。道理很簡單:首先,多數問題根本不需要設置這個別別扭扭標志變量,只有那些善于把自己的思維扭曲得如同爛麻花一樣的人才喜歡時不時地祭出flag這個破爛的法寶。其次,即使需要設置標準變量,優秀的代碼作者也不會使用這個含義模糊不清的名字作為標志變量名,而會用一個更貼切、意義更明確恰當更適合描述問題的名字。所以,一般來說,flag往往反映了代碼的垃圾度。


            對于垃圾代碼,沒必要進行過于細致的分析,只要指出錯誤即可。不要試圖了解這種代碼的思路,因為這種代碼的思路本來就是錯亂不堪的,就如同不要試圖理解瘋子的胡言亂語一樣。不要試圖修繕一座胡亂搭建起來的破爛不堪的危房,推倒重來才是明智的選擇。

            然而,找出程序的漏洞或錯誤,往往比完成程序要難得多。而且越是垃圾的代碼越難查錯,因為垃圾代碼往往也不具備良好的可測試性。

            但是對付這種可測試性極差的垃圾代碼,有一些簡單的辦法往往非常容易奏效,比如邊界檢查。訓練有素的程序員通常都特別注意邊界,無論是寫代碼時還是檢查代碼時。因為他們知道這里非常容易出錯,而且往往失之毫厘謬之千里。但垃圾代碼的作者,由于代碼是東拼西補、胡亂拼湊而成的,所以往往顧不上或考慮不到這些,因此垃圾代碼很容易被“邊界檢查”這把小刀輕而易舉地戳破。以alphabetic()函數為例,只要簡單地考察一下其中if語句所要求的表達式——(c>='a'&&c<='z')||(c>='A'&&c<='z'),就不難發現c<='z'這個子表達式是c<='Z'之誤。這樣就充分說明原代碼中存在著BUG。

            順便說一下,alphabetic()函數中的if-else語句用得非常愚蠢,因為(c>='a'&&c<='z') || (c>='A'&&c<='Z')這個表達式的值本身就只能為0或1,所以直接返回這個表達式的值就可以了。壓根用不著脫褲子放屁地寫一個if-else語句。

          int alphabetic(char c)
          {
             return   (c>='a'&&c<='z'
                  ||  (c>='A'&&c<='Z');
          }

            或許,有人會認為這是一個簡單的筆誤或印刷錯誤,修正了這個錯誤原來的代碼是正確的。那么好吧,下面改正這個錯誤后再來運用一次簡單的邊界測試。

            由于問題要求輸出一行字符中最長的單詞,而一行字符中可能有0個單詞、1個單詞、2個單詞……。注意,這里0個單詞的情況就是一種邊界情況,運行這個程序并輸入0個單詞(輸入一行不含任何字母的字符,因為代碼作者把連續的若干字母字符作為一個單詞),后果居然是——運行時程序崩潰了。這個結果絕對可以充分說明原來的代碼是錯誤的。

            這個結果是如何產生的呢?只要在紙上走查一遍,就不難發現,輸入一行不含任何字母的字符時,longest()函數中嵌套在for語句內部的if語句將毫無意義地反復執行

              {flag=1;
          if(len>=length)
          {length=len;
          place=point;
          len=0;
          }
          }

            部分,而其中的賦值給place的point卻居然是一個不確定的垃圾值。

            應該如何正確地給出這個問題的代碼呢?正確解決問題的前提是正確地提出問題。原來問題的提法本身就有很多不正確或不嚴謹的地方。例如,“將此字符串中最長的單詞輸出”,這個要求本身就是似是而非很不明確的。比如,字符串中有兩個單詞長度相同且都長于其他單詞,究竟應該輸出這兩個單詞中的任何一個還是需要同時輸出這兩個單詞?再有,要求函數“輸入一行字符”也非常無聊。為了能正確地解決問題,有必要對原問題的錯誤要求進行如下更正:

            寫一個函數,輸出字符串中的任一長度最長的單詞。這里所謂的單詞,是指不含空白字符的連續字符序列。

          #include <stdio.h>  
             
          void print_a_longestword ( const char [] ) ;  
          int  be_white  ( const char )  ;  
          int  find_begin( char const [] , unsigned ) ;  
          int  find_end  ( char const [] , unsigned ) ;  
          void output    ( char const [] , unsigned , unsigned ) ;  
             
          int main( void )  
          {  
             printf("%s中一最長單詞為:","");            //測試""   
             print_a_longestword("");  
                
             printf("%s中一最長單詞為:"," \n\t ");      //測試" \n\t "  
             print_a_longestword(" \n\t ");  
             
             printf("%s中一最長單詞為:"," abc ");       //測試" abc "  
             print_a_longestword(" abc ");  
             
             printf("%s中一最長單詞為:"," abc \tabcd  "); //測試" abc \tabcd  "  
             print_a_longestword(" abc \tabcd  ");  
                   
             return 0;  
          }  
             
          void output( char const str[] , unsigned from , unsigned to )  
          {  
             while(from < to)  
                putchar(str[from ++]);  
             putchar('\n');     
          }  
             
          int find_end (  const char str[] , unsigned from )  
          {  
                while( str[from]!='\0' && ! be_white( str[from] ) )  
                   from ++ ;  
                return from ;     
          }  
             
          int find_begin (  const char str[] , unsigned from )  
          {  
                while( be_white( str[from] ) )  
                   from ++ ;  
                return from ;     
          }  
             
          int be_white( const char c )  
          {  
             return       c == ' '    ||  
                       c == '\t'  ||  
                       c == '\n'  ;  
          }  
             
          void print_a_longestword ( char const line[] )  
          {  
             unsigned site = 0U ;     
             unsigned begin_longest , end_longest ;  
             begin_longest = end_longest = site    ;  
                
             do{  
                int this_begin , this_end  ;  
                   
                site = this_begin = find_begin ( line , site )    ;//單詞開頭   
                site = this_end  = find_end   ( line , site )     ;//單詞結尾        
             
                if(   ( this_end    - this_begin )   
                    > ( end_longest - begin_longest ) ){  
                   begin_longest = this_begin ;  
                   end_longest   = this_end   ;       
                }       
             
             }while( line[ site ] != '\0') ;     
             
             output( line , begin_longest , end_longest );  
          }

          posted @ 2011-12-05 09:38 順其自然EVO 閱讀(139) | 評論 (0)編輯 收藏

          如何在面試時選擇合適的測試人員?

           各位,大家好!今天分享一下我在面試測試人員時常問的一些問題及為什么,僅供各位參考,謝謝!

            1、你最近3-5年的職業規劃是什么?

            重點考察測試人員的職業發展方向是否與當前職位招聘相符? 從其中可以側面看出來其員工穩定性。

            2、一個項目測試結束,有沒什么經驗總結?如果有,具體是如何開展的?

            重點考察測試人員對自己能力提升方面,有沒有提高總結的地方,從項目中吸取的經驗與教訓。從中可以看出來,測試人員是否屬行自我驅動型人才!

            3、為什么會選擇做測試這份工作

            重點考察測試人員對待測試工作的態度及是否有發展潛力?面試過很多測試人員,經常見到的回答,自己是女孩子,做測試細心,各位你認為這樣回答你會滿意嗎?其碼不是我想要的答案!

            4、請說出一個你以前參與項目,對你測試經驗提升很高的,具體是哪方面?

            重點考察測試人員在以往的測試工作中能力提升方面,有哪些?然后重點詢問此部分內容,是否測試經驗增長,具備一定的深度?

            5、通常做測試時會碰到,提交的某個bug開發人員不認同你的觀點?這時你如何辦?

            重點考察測試人員是否堅持自已的價值觀?是否具備協調溝通處理問題能力?

            6、有沒有看過什么測試書,具體是哪本?帶給你的收獲是?

            重點考察測試人員是否為測試這個職業肯付出多少?從中也可以看出這個測試人員是否上進心?是否有求知心?我的定義是如果哪個應聘者來面試時,都沒系統的看過一本測試書籍,基本上不會錄取!

            7、如果安排一項測試技術研究工作,你如何應對?

            重點考察測試人員是否具體測試技術專研精神?是否喜歡接受挑戰?是否屬于以后培養骨干對象?

            8、某個項目上線后,出現問題,恰巧你是負責的,你如何應對這突如其來的事件?

            重點考察測試人員應對問題的壓力,責任感,及如何處理項目上線后的技術問題及應對解決能力。

            9、周末放假有什么業余愛好?

            重點考察面試測試人員性格特質,測試工作本身就是復雜且富有技術性的工作,而且不同的職位所需要的測試人員性格品質差異性很大。

            10、公司產品,具體應用什么編程技術?具體的架構是?具體的應用場景有哪些?

            重點考察測試人員對以往的工作所負責的產品測試,是否具備一定的深度!通常我都是讓面試者自己講述或是在紙上畫出具體系統架構的圖!

            11、公司測試團隊的規模如何,具體你所處的角色是什么?

            重點考察測試人員在以往的公司測試團隊中,具體的工作職責,評判其工作是否與當要求職位是否符合?是否有哪些優缺點?

            12、特定測試技術考察:性能測試,安全性測試,自動化測試等以前有開展過沒?如果有,具體是如何實施的?

            重點考察測試人員技術能力,是否在各方面都有所涉及?或是在各方面技術上都有一定深度?當然從中也能看出一個測試人員是否屬于是技術路線發展方向!

            13、你自己所期待加入的測試團隊是什么樣的?

            重點考察測試人員在以前測試團隊中有哪些不協調?當然最重要的是也能提供給你一些信息,這個員工以后如何更好的管理與溝通!

          posted @ 2011-12-05 09:37 順其自然EVO 閱讀(156) | 評論 (0)編輯 收藏

          從項目、產品、運營型看發展

           序言:自己身處通信界一段時間,偶然網上看到一些公司的正積極的轉型,突然將公司的發展對照著個人的發展以及自己自動化測試工作的進展,深有感悟,也許:一個怎樣的公司能持續發展,漸漸在市場上占有一席之地;一個怎樣的個人才能持續進步,漸漸的在人群稍有突顯;一個怎么的自動化測試策略才能持續提高,漸漸在軟件中真正起到至關重要的角色。這都是需要思考的吧。現在就說說自己一點認知吧。
            一、從項目、產品、運營看公司的發展
            首先聲明,這些都是我聽到的、查閱的再加自己的一點感悟,因為視野局限性,不一定適用,但卻是值得去感悟一下;
            在通信業界,公司分為三類,項目型公司、產品型公司以及運營型公司;
            1、項目型公司,項目型公司指那些業務是以項目運作方式為主的公司,其針對不同的客戶需求提供不同的項目,排除公司規模性的方面,據說這種公司盈利很辛苦,因為其針對每一個的需求就需要對應一個項目,這就是一個開發成本;然后需要對開發過的每一個項目進行維護,這就是一個維護成本。所以,每一個項目都會耗費大量的成本,成本越高,盈利越少。
            這種項目型公司需要的是將其項目的技術或者框架進行抽象,使得其項目間能夠共享、甚至可以將其滿足一定需求的項目拓展成產品。
            2、產品型公司,即擁有一定產品型組織結構,針對一定市場有專門的產品線支撐。在通信界。很多設備提供商都屬于這類,而產品型公司的追求向服務型公司轉型,其服務型公司是以顧客的需求為中心、以產品為載體、為顧客提供端到端的完整服務,其利潤總額,提供服務所創造的利潤將占很大一部分;例如:看看大家總說的IBM,其Rational的軟件產品,你會發現其主要介紹產品的方式是從能夠提供的服務方向來介紹的,而其主要服務理念是為其打造一條完整的軟件交付平臺。
            3、運營型公司,在通信業界,其三大運行商就是屬于運營型公司,其需要從網絡角度知道網絡運行狀況,還需要從服務角度知道網絡運行狀況。此外,他們需要在提供多媒體服務和應用時有效利用網絡資源。在通信業界,因為其特殊性,其運營型體制無可替代。但與通信界不同,互聯網的特殊性又決定了一個個大型的運營型公司的興起,他們以互聯網資源為優勢,打造了一系列的運營平臺,提供給廣大客戶一個享受服務的通道。
            二、從項目、產品、運營看個人的發展
            也許很多人都有過的疑慮,我在這個公司所學的知識出了公司之后是否還能使用?到底如何建立我的核心競爭力?
            1、 項目型個人,即只針對當前公司的狀況而獲得的技能,而等到了出了這個公司,還需要去學習新的技能。例如:做手工測試,只會對當前公司的產品進行黑盒測試,也許你可以針對這個產品的特性測試的很好,可以出了這個公司,這個技能就不一定適合與另外一個公司了。
            2、產品型個人,即擁有針對一定范圍的行業或者公司而擁有的技能,例如:編程的技能、撰寫測試用例的技能、性能測試的技能。為什么有一些知識面很廣的人卻沒有競爭力,那是因為就如一個公司,他把市場鋪的太大,他也無法去顧及其主要市場,所以一個人不斷學習,然后針對其公司和行業需求,抽象出自己的核心競爭力即可。而什么樣的核心競爭力,就需要自己對其需求的把握了。
            3、運營型個人,個人認為,此人是一個整合型的人才,也許很多人有疑問,為什么有的人不懂技術,卻能位于很高的位置,那是因為他能利用好人力的資源,就像互聯網中能利用好互聯網資源一樣,將其各人的優勢進行整合,打造了一個運轉的平臺。
            三、從項目、產品、運營看自動化測試的發展
            從以后可以聯系一下,自動化測試的發展
            1、項目型自動化測試;即腳本開發式,測試開發人員負責給不同測試的測試需求開發不同的腳本,這樣就導致了測試開發人員總需要幫助測試人員維護腳本,而且由于開發效率不高,導致自動化測試效果緩慢。
            2、產品型自動化測試,即開發了一系列的自動化測試框架與自動化測試工具,測試人員可以應用這些框架和工具去自己進行自動化測試,測試開發人員只對這些框架與工具負責。
            3、運營型自動化測試,即一個整體的自動化測試平臺,這需要與軟件產品流程相結合,利用軟件開發的資源,把握住軟件開發的每一個過程,例如:現在流程的每日構建感覺就是這么一個概念吧。
            總結:以上只是我的個人一些看法,同意或者不同意的都可以一起探討,我覺得對與不對,都值得思考,思想碰撞才能提高自身的一些眼界吧。

          posted @ 2011-12-05 09:36 順其自然EVO 閱讀(271) | 評論 (0)編輯 收藏

          DB2數據庫應用系統性能優化深入探究

            DB2是一種高性能的大型關系數據庫管理系統,廣泛的應用在客戶/服務器體系結構中。評價系統性能優化的標準有:吞吐量、響應時間、并行能力等。
            設計數據庫
            1、熟悉業務系統
            對業務系統的熟悉程度對整個數據庫系統的性能有很大影響,一個對業務不熟悉的設計人員,盡管有豐富的數據庫知識,也很難設計出性能最佳的數據庫應用系統。
            2、規范化與非規范化
            數據庫被規范化后,減少了數據冗余,數據量變小,數據行變窄。這樣DB2的每一頁可以包括更多行,那么每一區里的數據量更多,從而加速表的掃描,改進了單個表的查詢性能。但是,當查詢涉及多個表的時候,需要用很多連接操作把信息從各個表中組合在一起,導致更高的CPU和I/O花銷。那么,有很多時候需要在規范化和非規范化之間保持平衡,用適當的冗余信息來減少系統開銷,用空間代價來換取時間代價。有訂單信息表OrderDetail,它里面記錄了投遞員信息,收款員信息,物品信息,價格策略,客戶信息…..這些信息分別在投遞員信息表、收款員信息表、物品信息表、價格策略表、客戶信息表中存放。如果按照規范化的要求,OrderDetail查詢時就必須要與這么多個表進行連接或者嵌套查詢。如果OrderDetail表中的數據量是在百萬級的,那么一次查詢所需要的時間可能會達到好幾個小時。事實上,只要在設計時保證數據的邏輯有效性,很多信息都可以直接冗余在OrderDetail表中,這些冗余的數據能夠極大的提高查詢的效率,從而減少CPU和I/O操作。
            3、數據條帶化
            如果一個表的記錄條數超過一定的規模,那么最基本的查詢操作也會受到影響,需要將該表根據日期水平劃分,把最近、最經常用的數據和歷史的、不經常用的數據劃分開來,或是根據地理位置、部門等等進行劃分。還有一種劃分方式――垂直劃分,即把一個屬性列很多的表分割成好幾個小表,比如把經常用到的屬性放在一個表里,不經常用到的屬性放在另一個表里,這樣可以加快表的掃描,提高效率。
            4、選擇數據類型
            對每一屬性選擇什么樣的數據類型很大程度上依據表的要求,但是在不違背表要求的前提下,選擇適當的數據類型可以提高系統性能。比如有text列存放一本書的信息,用BLOB而不是character(1024),BLOB存放的是指針或者文件參照變量,真正的文本信息可以放在數據庫之外,從而減少數據庫存儲空間,使得程序運行的速度提高。DB2提供了UDT(User Defined Datatypes)功能,用戶可以根據自己的需要定義自己的數據類型。
            5、選擇索引
            索引是數據庫中重要的數據結構,它的根本目的就是為了提高查詢效率。現在大多數的數據庫產品都采用IBM最先提出的ISAM索引結構。使用索引可以快速、直接、有序的存取數據。索引的建立雖然加快了查詢,另一方面卻將低了數據更新的速度,因為新數據不僅要增加到表中,也要增加到索引中。另外,索引還需要額外的磁盤空間和維護開銷。因此,要合理使用索引:
            在經常進行連接,但是沒有指定為外鍵的屬性列上建立索引。
            在頻繁進行排序或分組(即進行group by或order by操作)的列上建立索引。按索引來排序或分組,可以提高效率。
            在條件表達式中經常用到的不同值較多的列上建立檢索,在不同值少的列上不要建立索引。
            如果待排序的列有多個,可以在這些列上建立復合索引(compound index),即索引由多個字段復合而成。
            查詢優化
            現在的數據庫產品在系統查詢優化方面已經做得越來越好,但由于用戶提交的SQL語句是系統優化的基礎,很難設想一個原本糟糕的查詢計劃經過系統的優化之后會變得高效,因此用戶所寫語句的優劣至關重要。下面重點說明改善用戶查詢計劃的解決方案。
            1、排序
            在很多時候,應當簡化或避免對大型表進行重復的排序。當能夠利用索引自動以適當的次序產生輸出時,可以避免排序的步驟,當以下的情況發生時,排序就不能省略:
            索引中不包括一個或幾個待排序的列;
            group by或order by子句中列的次序與索引的次序不一樣;
            排序的列來自不同的表。
            為了避免不必要的排序,就要正確地增建索引,合理地合并數據庫表,盡管有時可能影響表的規范化,但相對于效率的提高是值得的。如果排序不可避免,那么應當試圖簡化它,如縮小排序列的范圍等。

            2、主鍵
            主鍵用整型會極大的提高查詢效率,而字符型的比較開銷要比整型的比較開銷大很多,用字符型數據作主鍵會使數據插入、更新與查詢的效率降低。數據量小的時候這點降低可能不會被注意,可是當數據量大的時候,小的改進也能夠提高系統的響應速度。
            3、嵌套查詢
            在SQL語言中,一個查詢塊可以作為另一個查詢塊中謂詞的一個操作數。因此,SQL查詢可以層層嵌套。例如在一個大型分布式數據庫系統中,有訂單表Order、訂單信息表OrderDetail,如果需要兩表關聯查詢:
          以下是代碼片段:
              SELECT CreateUser 
            FROM Order 
            WHERE OrderNo IN 
            ( SELECT OrderNo 
            FROM OrderDetail 
            WHERE Price=0.5)
            在這個查詢中,找出報紙單價為0.5元的收訂員名單。下層查詢返回一組值給上層查詢,然后由上層查詢塊再根據下層塊提供的值繼續查詢。在這種嵌套查詢中,對上層查詢的每一個值OrderNo,下層查詢都要對表OrderDetail進行全部掃描,執行效率顯然不會高。在該查詢中,有2層嵌套,如果每層都查詢1000行,那么這個查詢就要查詢100萬行數據。在系統開銷中,對表Order的掃描占82%,對表OrderDetail的搜索占16%。如果我們用連接來代替,即:
          以下是代碼片段:
              SELECT CreateUser 
            FROM Order,OrderDetail 
            WHERE Order.OrderNo=OrderDetail.OrderNo AND Praice=0.5
            那么對表Order的掃描占74%,對表OrderDetail的搜索占14%。
            而且,一個列的標簽同時在主查詢和where子句中的查詢中出現,那么很可能當主查詢中的列值改變之后,子查詢必須重新查詢一次。查詢嵌套層次越多,效率越低,因此應當盡量避免子查詢。如果子查詢不可避免,那么要在子查詢中過濾掉盡可能多的行。
            4、通配符
            在SQL語句中,LIKE關鍵字支持通配符匹配,但這種匹配特別耗費時間。例如:SELECT * FROM Order WHERE CreateUser LIKE ‘M_ _ _’ 。即使在CreateUser字段上建立了索引,在這種情況下也還是采用順序掃描的方式,Order表中有1000條記錄,就需要比較1000次。如果把語句改為SELECT * FROM Order WHERE CreateUser >’M’ AND CreateUser <’N’,在執行查詢時就會利用索引來查詢,顯然會大大提高速度。
            5、distinct
            使用distinct是為了保證在結果集中不出現重復值,但是distinct會產生一張工作表,并進行排序來刪除重復記錄,這會大大增加查詢和I/O的操作次數。因此應當避免使用distinct關鍵字。
            6、負邏輯
            負邏輯如!=、<>、not in等,都會導致DB2用表掃描來完成查詢。當表較大時,會嚴重影響系統性能,可以用別的操作來代替。
            7、臨時表
            使用臨時表時數據庫會在磁盤中建立相應的數據結構,因為內存的訪問速度遠遠大于外部存儲器的訪問速度,在復雜查詢中使用臨時表時,中間結果會被導入到臨時表中,這種磁盤操作會大大降低查詢效率。另外,在分布式系統中,臨時表的使用還會帶來多個查詢進程之間的同步問題。所以,在進行復雜查詢時最好不要使用臨時表。
            8、存儲過程
            DB2中的Stored Procedure Builder可以產生存儲過程,運行并測試存儲過程。存儲過程可以包含巨大而復雜的查詢或SQL操作,經過編譯后存儲在DB2數據庫中。用戶在多次使用同樣的SQL操作時,可以先把這些SQL操作做成存儲過程,在需要用到的地方直接引用其名字進行調用。存儲過程在第一次執行時建立優化的查詢方案,DB2將查詢方案保存在高速緩存里,以后調用運行時可以直接從高速緩存執行,省去了優化和編譯的階段,節省了執行時間,從而提高效率和系統利用率。
            最優的查詢方案按照某些標準選擇往往不可行,要根據實際的要求和具體情況,通過比較進行選擇。DB2提供的Query Patroller可以對不同的查詢方案的查詢代價進行比較,通過追蹤查詢語句,返回查詢不同階段的系統開銷,從而作出最佳選擇。DB2提供的Performance Monitor也對整個數據庫系統的性能進行監控,包括I/O時間、查詢次數、排序時間、同步讀寫時間等等。
            數據庫系統的并發控制也能影響系統性能。多個用戶的同時操作可能導致數據的不一致性,DB2為了防止同時修改造成數據丟失和訪問未被提交的數據,以及數據的保護讀,采用Lock機制來實現控制。
            DB2中可以對表空間、表、表列和索引加鎖。鎖的粒度越大,鎖越簡單,開銷小,并發度低;粒度小,鎖機制復雜,開銷大,并發度高。大型系統在并發處理中如果遇到所要分配的資源處于鎖定狀態,系統會把進程掛起等待。如果一個很耗時的查詢操作工作于一個經常使用的表上,此時使用表一級鎖,意味著整個系統都要等待你的查詢結束以后才能夠繼續運行。所以在復雜查詢中,盡量避免使用表一級鎖。如果有這一類的需要該怎么辦呢?可以利用視圖來解決這一類問題。視圖避免了對表的直接操作,同時有能夠保證數據庫的高效運轉。

          posted @ 2011-12-05 09:34 順其自然EVO 閱讀(140) | 評論 (0)編輯 收藏

          性能測試報告(實例)

            上一篇博文主要通過兩個例子讓測試新手了解一下測試思想,和在做測試之前應該了解人幾點,那么我們在如何完成一次完整的性能測試呢?

            測試報告是一次完整性能測試的體現,所以,這里我給出一個完整的性能測試報告,相信通過這個報告,我們會整性能測試有個整體的了解,知道我們在以后做性能測試時需要做哪些工作

            注明:1)性能測試報告模板很多,這不是一個空洞的模板,是一個完整的測試報告。

            2)由于商業原因,關于項目明,用XXX代替

            3)我一直覺得,關于性能工具重要,但不是很重要,要學習性能測試,需要了解的知識面很多,工具只是工具,是為我們服務的,會用性能測試工具并不代表你就會做性能測試了

            ----//性能測試報告(某網站用戶登陸性能測試)

            1、概述

            1.1 目的

            本測試報告為XXXX網站的性能測試報告,目的在于總結測試階段的測試以及分析測試結果,描述網站是否符合需求。

            1.2 背景

            XXXX網站,XXXXXX科技有限公司目前正在進行性能測試。考慮到用戶數量及數據的增多給服務器造成壓力不可估計,因此計劃對XXXX網站負載性能測試,在系統配置不變的情況下,在一定時間內,服務器在高負載情況下的性能行為表現,便于對系統環境進行正確的分析及評估。

            1.3 范圍

            本次測試主要是XXXX網站系統的性能測試。

            1.1 引用文檔

            下表列出了執行測試過程所引用的文檔:

          文檔名稱 

          版本號 

          作者 

          備注 

          XXX系統壓力測試方案 

           

          蟲師 

           
              
              
              

            2、測試概要

            2.1 測試環境

            下圖描述測試該項目所需要的硬件環境:

          客戶機 Intel(R) Xeon(TM) CUP 3.06GHz 四核至強處理器、內存:4GB RAM 
          NAS服務器 

          PowerVault(TM) NAS1950,

          四核至強處理器 E5430, 2.66GHz, 2x6M緩存,1333MHz前端總線,80W 數量1

          8GB(2x4G),DDR-2 667MHz ECC 4R Memory

          1TB 3.5-inch 5.4K RPM SATA II Hard Drive with interposer 數量12 

          數據庫服務器 Intel(R) Quad Core E5504  Xeon(R) CPU,  2.0GHz,  4M Cache,  4.86GT/s QPI 數量2
          500GB 7.2K RPM  Near Line SAS 3.5” Hot Plug H ard Drive 數量2 RAID
          8GB Memory(4x2GB),1066MHz, Dual Ranked RDI MMs for 1 Processor 

            下圖描述測試網絡的拓撲結構:

                              客戶機測試環境                 服務器測試環境

            測試機與被測服務器在同一局域網進行,排除了網速限制及網速度不穩定性。

            系統采用B/S架構模式,客戶端通過中間件訪問數據庫,中間件和數據庫分別部署在兩臺服務器上。

            2.2 人力資源

            下表列出了所有參與此項目的測試人員:

          角色 資源數量/具體人員 
          測試員 XXXX科技有限公司:蟲師 

            2.1 測試工作量

          任務 開始時間 結束時間 總計(天數) 總計(人時) 
          計劃 2011-11-19 2011-11-19  
          實際 2011-11-19 2011-11-19  

            3、測試內容及方法

            3.1 測試需求/目標

            在大用戶量、數據量的超負荷下,獲得服務器運行時的相關數據,從而進行分析,找出系統瓶頸,提高系統的穩定性。

            3.2 測試內容

            本次測試主要是對寶寶足跡網站“首頁登錄”、后臺“成長記錄”及網站信息頁面訪問操作在大負荷情況下處理數據的能力及承受能力。

            測試方法:

          場景 并發用戶數量 運行場景設置 測試點 
          登錄 200 40分鐘 服務器穩定性及操作響應時間 

            注釋:所有用戶登陸、沒有權限限制。

            3.3 測試工具

            主要測試工具為:LoadRunner性能測試工具

            輔助軟件:截圖工具,Word

            4、測試結果及分析

            4.1 寶寶足跡處理性能評估

            這次測試屬于局域網環境進行,排除了外網的網速限制及不穩定性。

            并發登錄用戶測試

            測試內容:

            這次測試屬于模擬真實環境,加入思考時間(think time);用戶輸入網址登錄首頁,加入1~5秒思考時間,輸入用戶名密碼,點擊登錄按鈕。



          說明:用戶的整個執行流程都錄制在Action(循環)部分,所以Vuser_int (開始)和Vuser_end(結束)部分為空。Action_Transaction部分的時間為運行整個Action腳本所需的時間。

            整個Action的平均響應時間為:3.945秒;登錄操作的平均響應時間為:1.185秒。

            說明:所有響應事務數為:8720次(個)

            服務器平均每秒響應事件:6.664次/秒;其中登錄的平均每秒響應事件為:3.257次/秒

            結果分析:

            此次測試用戶操作流程簡單,所以并未對服務器造成高度負載,從NAS服務器服務器曲線圖來看,0到70%區間浮動,運行相當平穩。從模擬環境來看,加入1到5的思考時間,更符合真實用戶的操作。

            從設置200人的壓力分析,響應速度很快,完全在用戶的感覺快速響應時間內,從整個Action腳本分析,把整個Action時間減去登錄時間為:2.76秒,首頁的訪問時間相比較長,首頁部分圖片和動畫較多,如果用戶量訪問量繼續加大,必定會影響系統性能。

           

           

          posted @ 2011-12-05 09:32 順其自然EVO 閱讀(650) | 評論 (0)編輯 收藏

          java實現后臺自動發郵件功能

               摘要: java實現后臺自動發郵件功能www.diybl.com    時間 : 2008-09-13  作者:佚名   編輯:本站 點擊:  1390 [ 評論 ]web.xml文件 <?xml version="1.0" encoding...  閱讀全文

          posted @ 2011-12-01 17:47 順其自然EVO 閱讀(4910) | 評論 (6)編輯 收藏

          僅列出標題
          共394頁: First 上一頁 353 354 355 356 357 358 359 360 361 下一頁 Last 
          <2025年7月>
          293012345
          6789101112
          13141516171819
          20212223242526
          272829303112
          3456789

          導航

          統計

          常用鏈接

          留言簿(55)

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 内江市| 霍山县| 大埔县| 山东省| 临澧县| 安吉县| 成都市| 石景山区| 汝阳县| 泰州市| 新宁县| 红原县| 油尖旺区| 洛宁县| 福建省| 莱阳市| 大余县| 如东县| 文化| 苗栗市| 峨山| 金川县| 武汉市| 胶州市| 北辰区| 元朗区| 登封市| 尚志市| 甘肃省| 修水县| 武功县| 新丰县| 临城县| 张家界市| 山西省| 民县| 赤水市| 大荔县| 墨脱县| 崇礼县| 辽源市|