<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    qileilove

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

    Oracle11G在linux環境下的卸載操作

     1.使用SQL*PLUS停止數據庫
      [oracle@OracleTest oracle]$ sqlplus log
      SQL> connect / as sysdba
      SQL> shutdown [immediate]
      SQL> exit
      2.停止Listener
      [oracle@OracleTest oracle]$ lsnrctl stop
      3.停止HTTP服務
      [root@OracleTest /root]# service httpd stop
      4.用su或者重新登錄到root(如想重新安裝可以保留oracle用戶,省得輸入環境變量了)
      5.將安裝目錄刪除
      [root@OracleTest /root]# rm -rf /u01/oracle/
      [root@OracleTest /root]# rm -rf /u01/oraInventory/
      6.將/usr/bin下的文件刪除
      [root@OracleTest /root]# rm /usr/local/bin/dbhome
      [root@OracleTest /root]# rm /usr/local/bin/oraenv
      [root@OracleTest /root]# rm /usr/local/bin/coraenv
      7.將/etc/oratab刪除
      [root@OracleTest /root]# rm /etc/oratab
      8.將/etc/oraInst.loc刪除
      [root@OracleTest /root]# rm /etc/oraInst.loc
      9.將oracle用戶刪除(若要重新安裝,可以不刪除)
      [root@OracleTest /root]# userdel –r oracle
      10.將用戶組刪除(若要重新安裝,可以不刪除)
      [root@OracleTest /root]# groupdel oinstall
      [root@OracleTest /root]# groupdel dba
      11.將啟動服務刪除
      [root@OracleTest /root]# chkconfig --del dbora
      到此為止重啟后,你的Linux系統下的Oracle數據庫已完全刪除了?。?!
      以上是CentOS5.4+Oracle 11g的環境。
      如果要再次安裝, 最好先做一些備份工作
      包括用戶的登錄腳本,數據庫自動啟動關閉的腳本,和Listener自動啟動的腳本。
      要是有可能連創建數據庫的腳本也保存下來。

    posted @ 2014-06-16 10:22 順其自然EVO 閱讀(1365) | 評論 (0)編輯 收藏

    重新配置OpenFire數據庫

     1.停止oepnfire服務
      [root@openfire.clvn.com.cn ~]# su - openfire
      -bash-4.1$ cd /usr/local/openfire/bin
      -bash-4.1$ ./openfire stop
      2.找到openfire配置文件
      [root@openfire.clvn.com.cn ~]# cd /usr/local/openfire/conf/
      [root@openfire.clvn.com.cn conf]# ls
      available-plugins.xml  crowd.properties  openfire.xml  security.xml  server-update.xml
      [root@openfire.clvn.com.cn conf]# vim openfire.xml
      找到
      <setup>true</setup>
      將其刪除
      3.重新啟動openfire
      [root@openfire.clvn.com.cn ~]# su - openfire
      -bash-4.1$ cd /usr/local/openfire/bin
      -bash-4.1$ ./openfire start
      Starting openfire

    posted @ 2014-06-16 10:21 順其自然EVO 閱讀(3957) | 評論 (0)編輯 收藏

    再論Java虛擬機XMS與XMX設置

      1.1 背景
      某銀行的自助設備前置機系統為核心系統,故對系統可用性和性能有著極高的要求,運維管理面臨很大挑戰。但是在3月份,出現了100會話并發時,系統CPU使用為100%,大量交易回滾,無法提供正常的ATM終端服務,為此需要對故障進行分析,對系統進行優化,優化系統性能以大幅提高處理能力
      1.2 應用環境
      WebLogic應用服務器、Oracle數據庫
      單實例WebLogic環境,JVM配置為-Xms=1g  -Xmx 2g
      AIX 5.3服務器。
      自助設備前置機系統,包括信用卡消費和跨行取款等交易。
      1.3 實施收益
      1.3.1 -Xms=1g  -Xmx 2g
      通過在該行開發中心UAT環境進行壓力測試,通過監控軟件進行分析系統性能,在采用JVM 堆大小-Xms=1g  -Xmx 2g,并發會話數為100情況下:
      關鍵事務性能
      關鍵事務平均處理時間為53.933sec
      GC停頓時間
      最長GC停頓時間達到1.4sec
      JVM使用百分比
      JVM使用在57%左右,最高到850M
      1.3.2 -Xms=256M  -Xmx 512M
      在采用JVM 堆大小-Xms=256M  -Xmx 512M,并發會話數為100情況下:
    關鍵事務性能
      關鍵事務平均處理時間為10.420sec
      GC停頓時間
      最長GC停頓時間為0.625sec
      JVM使用百分比
      JVM使用在65%左右,最高到324M。
      1.3.3 結論
      綜上,我們可以發現當采用-Xms=256M  -Xmx 512M,系統性能約提高了4倍,原因在于系統用于GC的停頓時間為原來的一半,這也大大減少了CPU使用。同時內存的利用效率也獲得了比較大的提高,在選擇較大的內存時,會顯著提高每次Full GC的時間。這帶來的大量的CPU開銷,對于對實時性要求較高的事務更意味著性能災難。
      所有JVM設置及調優都圍繞著2個方面:減少GC次數與停頓時間,但是2者本身就存在著根本的矛盾,具體取舍要按照不同的業務類型,在本例中,銀行的取款等交易屬于很短的、實時性要求高的交易,故最終的調優在減少停頓時間方面做了傾斜。
      通過第3方監控軟件(如HP SiteScope\Diagnostics)可以對事務的性能,GC停頓時間以及JVM內存使用的分析,可以幫助我們獲得最優的JVM調優,幫助客戶選擇最優的JVM設置。

    posted @ 2014-06-16 10:20 順其自然EVO 閱讀(729) | 評論 (0)編輯 收藏

    Selenium支持高版本的FireFox

     今天寫個自動刷新頁面的腳本,發現在啟動firefox的時候,出現一個類似如下的錯誤:
    請在文本框輸入文字15:22:12.031 WARN - GET /selenium-server/driver/?cmd=getNewBrowserSession&1=*fir
    efox&2=http://www.google.com HTTP/1.1
    java.lang.RuntimeException: Firefox refused shutdown while preparing a profile
    at org.openqa.selenium.server.browserlaunchers.FirefoxCustomProfileLaunc
    her.waitForFullProfileToBeCreated(FirefoxCustomProfileLauncher.java:277)
      后來查了google發現問題是selenium不支持高版本firefox, 解決方案如下:
      1、用winrar打開selenium-server.jar;
      2、查找兩個目錄:customProfileDirCUSTFFCHROME和customProfileDirCUSTFF;
      3、搜索每個目錄,對每個文件install.rdf,編輯如下行:
      修改
    <!-- Firefox -->
    <em:targetApplication>
    <Description>
    <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
    <em:minVersion>1.4.1</em:minVersion>
    <em:maxVersion>3.5.*</em:maxVersion>
    </Description>
    </em:targetApplication>
    <!-- Firefox -->
    <em:targetApplication>
    <Description>
    <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
    <em:minVersion>1.4.1</em:minVersion>
    <em:maxVersion>3.6.*</em:maxVersion>
    </Description>
    </em:targetApplication>
      還可以改得更加大,那么就可以支持4.0 的firefox了

    posted @ 2014-06-16 10:19 順其自然EVO 閱讀(3368) | 評論 (0)編輯 收藏

    LoadRunner中Action的迭代次數的設置和運行場景中設置

     LoadRunner是怎么重復迭代和怎么增加并發運行的呢?
      另外,在參數化時,對于一次壓力測試中均只能用一次的資源應該怎么參數化呢?就是說這些資源用了一次就不能在用了的。
     ?。瓍祷瘯r,在select  next row選擇unique,update value on選擇 each occurence,
      1. 迭代跟虛擬用戶數沒什么必然聯系
      迭代是這樣的:
      迭代1次   迭代2次  迭代3次
      用戶1     X1           X2             X3
      用戶2     Y1           X2             Y3
      其中的X1-3 Y1-3是參數,參數規則就是二樓說的
      這么兩個用戶是根據你的rump up 上來的,比如5秒上兩個用戶,那么用戶1和2就在5秒之內加載進來的,不知道說清楚了沒。
      第二個問題就簡單了,只能用一次的參數,首先確保你的參數足夠,另外規則選擇的時候,注意選擇唯一
      迭代次數只是對你設置了迭代次數的action進行迭代,而用戶數可以理解為對整個錄制過程的迭代(只是各個用戶不同) 而且增加并發量可以通過增加用戶來達到 還可以設置集合點來增加某個操作的并發量
      假如一個腳本,設置最大并發量為10,每5秒中增加2個并發用戶,而Action設置的迭代為10次:
      當開始至2秒時,加載了2個用戶,這2個用戶分別開始運行,并都運行10次,不管這個2個用戶運行10次是否結束,當下一個2兩秒到來時,即開始至第4秒時又加載了2個用戶,這2個又運行10次;就這樣一直加載到10個并發用戶,然后當每個用戶都運行完10次時就結束。
      這樣中間最大并發是10個,但不一定能達到10個,因為在加載最后幾個時,前面的有可能已經運行結束,所以如果要真正達到最大并發10就必須設置集合點來完成
      不過也不一定非要設置集合點才能實現同時處在running的狀態有10個用戶。
      設置duration也是可以的。不過那就不只每個用戶運行10次了。
      如果想實現用戶迭代10次,并且想同時running為10個用戶,就應該設置集合點。
      迭代(Iterate)設計,或者我們稱之為增量(Incremental)設計的思想和XP提倡的Evolutionary Design有異曲同工之妙。
      注意:1、 參數類型:在創建參數的時候,我選擇了參數類型為File。參數類型共有9 種,現在來簡單介紹一下所有的參數類型以及意義。
      1.1、   DateTime:在需要輸入日期/時間的地方,可以用 DateTime 類型來替代。其屬性設置也很簡單,選擇一種格式即可。當然也可以定制格式。
      1.2、   Group Name:很少用到。在實際運行中,LoadRunner 使用該虛擬用戶所在的Vuser Group 來代替。但是在 VuGen 中運行時,Group Name將會是None。
      1.3、   Load Generator Name :在實際運行中, LoadRunner   使用該虛擬用戶所 在LoadGenerator   的機器名來代替。
      1.4、   Iteration Number :在實際運行中,LoadRunner 使用該測試腳本當前循環的次數來代替。
      1.5、   Random Number:隨機數。很簡單。在屬性設置中可以設置產生隨機數的范圍。
      1.6、   Unique Number:唯一的數。在屬性設置中可以設置第一個數以及遞增的數的大小。
      注意:使用該參數類型必須注意可以接受的最大數。例如:某個文本框能接受的最大數為99。當使用該參數類型時,設置第一個數為 1,遞增的數為1,但100個虛擬用戶同時運行時,第100 個虛擬用戶輸入的將是 100,這樣腳本運行將會出錯。這里說的遞增意思是各個用戶取第一個值的遞增數,每個用戶相鄰的兩次循環之間的差值為 1。舉例說明:假如起始數為 1,遞增為 5,那么第一個用戶第一次循環取值 1,第二次循環取值 2;第二個用戶第一次循環取值為 6,第二次為 7;依次類推。
     1.7、   Vuser ID:設置比較簡單。在實際運行中,LoadRunner 使用該虛擬用戶的 ID   來代替,該 ID   是由 Controller 來控制的。但是在 VuGen 中運行時,Vuser ID   將會是 –1。
      1.8、   File:需要在屬性設置中編輯文件,添加內容,也可以從現成的數據庫中取數據
      1.9、   User Defined Function:從用戶開發的 dll 文件提取數據。
      用HTTP協議錄制了一個包含登錄、瀏覽、退出過程的腳本,錄制時都放到Action部分,這時腳本設置了迭代后可以多次重復運行,但是出于處理邏輯,一旦將登錄腳本放到Init部分后,就無法正常進行迭代運行了。今天專門找個時間做了嘗試,發現可能出現這兩種錯誤。
      1、這是我犯的一個低級錯誤。在我將登錄腳本移到Init部分時,將登錄腳本之后的瀏覽操作前面的web_reg_find腳本也一起移了過去,結果運行完Init部分腳本就出錯了。錯誤提示:
      Error -27259: Pending web_reg_save_param/reg_find/create_html_param[_ex] request(s) detected and reset at the end of the Init section
      這種錯誤的現象是沒有進行迭代已經出錯了,錯誤提示也很明確。這時只要把web_reg_find放回Action部分的正確的位置即可。
      2、單次運行正確,但是多次迭代運行時出錯,錯誤提示:
      Error -27985: There is no context for HTML-based functions. A previous function may not have used "Mode=HTML" or downloaded only non-HTML page(s), or the context has been reset (e.g., due to a GUI-based function)
      這種錯誤可能比較常見,原因是在Runtime Settings的Browse Emulation中設置了Simulate a new user on each iteration引起的。由于這個設置導致每次迭代時都會模擬一個新的用戶,此時這個新的用戶并沒有執行init操作而失敗了,也即是錯誤提示中的There is no context。
      這里涉及到一個知識點就是在Rumtime Settings的迭代設置中,迭代運行次數只對Action部分有效,而Init部分和End部分還是只運行一次的。這時如果設置了“Simulate a new user on each iteration”,將出現上面的第2種錯誤。

    posted @ 2014-06-16 10:18 順其自然EVO 閱讀(7854) | 評論 (0)編輯 收藏

    利用Hudson實現自動化測試的分布式執行

     一、概述
      目前,持續集成已成為當前許多軟件開發團隊在整個軟件開發生命周期內側重于保證代碼質量的常見做法。隨著測試的自動化率逐步提高,每天要需要自動執行的測試用例也就越來越多了,當我們發現,跑一次完整的測試需要幾個小時,測試的速度已遠遠跟不上編譯的速度的時候,我們自然要考慮如何加快測試的速度了——分布式執行測試用例,顯然是一個不錯的辦法,本文正是講述如何利用Hudson來實現自動化測試的分布式執行。
      二、基本概念
      1.什么是持續集成
      簡而言之,持續集成(Continuous Integration)是一種軟件開發實踐,即團隊開發成員經常集成它們的工作,通常每個成員每天至少集成一次,也就意味著每天可能會發生多次集成。每次集成都通過自動化的構建(包括編譯,發布,自動化測試)來驗證,從而盡快地發現集成錯誤。
      持續集成可以幫助我們做到:
      1. 軟件構建自動化
      2. 持續自動的構建檢查
      3. 持續自動的構建測試
      4. 構件生成后續過程的自動化
      關于持續集成的更多概念和知識,本文不做深入闡述,有興趣的讀者可以參考以下鏈接:
      互聯網行業應用持續集成實踐
      2.關于Hudson
      沒錯,Hudson正是一個能幫助我們實現持續集成的平臺。確切來說,Hudson是一個可擴展的持續集成引擎。 主要用于:
      1. 持續、自動地構建/測試軟件項目
      2. 監控一些定時執行的任務
      更多關于Hudson的介紹和說明,請參考以下鏈接:
      持續集成工具Hudson
      三、分布式測試
      1.串行執行測試
      一般,我們會在Hudson上配置三個任務,分別是編譯任務、快速測試任務、慢速(完整)測試任務。這三個任務一般是順序串行執行的,上一個任務執行完畢了之后,下一個任務才能開始執行。
      2.化整為零
      串行執行測試,當需要運行的自動化測試用例較多時,任務執行的速度顯然不會讓我們滿意,尤其是完整測試任務。如何加快執行速度呢 我們首先會想到的是,可以化整為零,把slowtest任務(完整測試任務)分成多個小任務,這樣,就可以在多臺機器上同時執行,從而加快執行速度了。
      然而,這樣的做法,缺點也很明顯——測試結果也被拆分,而且維護成本較高:
      ①slowtest的測試結果被拆分到各個小任務里,測試結果不方便統一顯示和分析。
      ②為達到最大速度,需要我們人工來把slowtest任務拆分成跟已有測試機器數量相等的測試任務,如果測試機器的數量新增或減少了,就需要我們再次人工調整任務。
      ③需要我們人工來指定不同的測試用例,平均分給各個測試任務,如果測試用例數量發生變化,也需要我們再次調整設置。 3.分布式執行!
      一般的任務,是不能并發調度執行的,有多個構建請求時,即使有多個測試機器是空閑的,也必須按時間順序,一個接一個運行,典型的情況如下圖所示。
      因此,上述化整為零的做法把slowtest任務拆分為多個子任務,從而達到多個任務同時可以同時執行的效果。
      實際上,要加快自動化測試的速度,不一定需要多個任務同時執行——我們只需要多個構建同時執行。Hudson任務設置里有一個選項
      可以設置任務是否可以多個構建同時執行。我們把這個選項勾選上后,當同時有多個構建請求時,只要有N個測試機器是空閑的,那就可以有N個構建同時執行!
      4.遠程控制
      Hudson可以設置一個任務構建完成后自動觸發另外的任務構建。這樣,編譯任務、快速測試任務、完整測試任務可以自動地有序執行。然而,這樣的自動觸發任務構建,上游任務只能對每個下游任務觸發一次。那么,當我們的quicktest任務構建完畢后,如何觸發多個slowtest任務構建呢 難道只能手工在網頁頁面上點擊“立即構建”嗎
      當然不是。在Hudson任務設置里,如下圖,有這樣的一個設置,勾選并填寫”Authentication Token”上之后,我們就可以使用這個Token編寫腳本或程序來隨時觸發一個任務的構建了。
      例如,用類似以下的Python代碼,就可以觸發一次”Your_Job”任務的一次構建。
      如果”Your_Job”任務是帶參數(見后文)的,可以用類似以下的代碼觸發一次構建。
      5.測試用例分配
      為了讓slowtest任務的每一次構建能執行不同的自動化測試用例,我們需要指定該任務為帶參數的任務,在任務設置中勾選
      并指定相應的參數。例如,我們指定一個字符串參數名為suite,用于指定某一次構建是運行哪一個suite里的case。這樣,在具體的某一次構建中,suite會以環境變量的方式存在。當然,如果構建的時候沒有指定suite參數,那么suite就會默認為None。
      這樣,在一個任務的每次構建中,就可以根據環境變量suite的值去取不同的測試用例來運行了。
      6.測試結果回收
      當分布式測試執行完畢后,slowtest的測試結果仍然被拆分到了多個構建之中,如何把這些測試結果統一收集起來呢
      例如,我們很可能需要把所有測試用例的運行生成的JUnit格式的測試結果報表合并在一起,即我們需要收集slowtest任務每一次構建所產生的xml測試結果文件。
      解決辦法是,我們在slowtest任務里設置Hudson把我們需要的一些文件在構建完成后打包存檔起來。例如下圖這樣設置,則Hudson在每一次構建完成后,會將test_report文件夾下的所有xml文件上傳至服務器保存下來。
      這樣,我們也就可以自己編寫腳本或程序去獲取這些文件了。例如,類似如下Python代碼,可以獲得test-slowtest任務第67次構建所生成的所有文件,打包保存為tmp.zip。
    7.萬事俱備
      至此,分布式執行自動化測試用例所需要的條件都已具備。一個具體的可行自動化測試分布式執行方案如下。
      1) test-build-only
      o 編譯任務,可以設置Hudson輪詢SCM,每當提交代碼至服務器后,此任務會自動觸發。
      2) test-quicktest
      o 快速測試任務,在編譯任務成功完成后,自動觸發,快速執行一些最基本的自動化測試用例,確保新提交代碼后,程序產品的基本功能沒有問題。
      3) test-slowtest-dispatch
      o 此任務在test-quicktest執行成功后自動觸發,它所做的工作是把所有需要執行的自動化測試用例分配為多個suite,并為每個suite觸發一次test-slowtest-distributed任務的構建。
      4) test-slowtest-distributed
      o 分布式執行的主要任務,可以多個構建同時執行,根據任務參數不同來執行不同的自動化測試用例。
      5) test-slowtest-report
      o 分布式測試匯總任務,當test-slowtest-distributed任務在一次分布式執行中的所有構建執行完畢后,此任務負責將這些構建產生的測試結果收集在一起。
      8.分布式方案
      如下圖。
     四、FAQ & Tips
      在什么時候,怎樣觸發report任務呢
      o 可以為distributed任務再設定一個end參數,默認為空,在dispatch任務執行的腳本或程序里,觸發最后一個distributed任務的構建時,才指定該構建的end為True。在distributed任務執行的時候,如果end為True,再去觸發report任務,觸發方式當然也是用腳本或程序觸發。
      report任務如何知道該收集distributed任務的哪幾次構建的測試結果呢
      o 可以由distributed任務通過傳遞參數的方式告訴report應該收集哪幾次構建的測試結果。到底該如何確定是哪幾次構建呢 Hudson定義了一些環境變量,我們在任務執行的shell或批處理中可以使用到。例如,可以在最后一次構建的時候,讀取環境變量BUILD_NUMBER,再設法確定本次分布式執行共有多少次構建,即可以知道哪些構建是report應該收集測試結果文件的了~
      report任務收集到的測試結果文件,由于不對,Hudson不承認怎么辦呢
      o 實際上,只需要一個批處理命令即可以修改文件的創建時間:copy *.xml+,,
      report任務構建時,怎樣知道distributed任務所有的構建都已完成呢
      o 打開Hudson網頁,試試在網址后面加上“api”,如http://HUDSON/job/test/63/api,然后刷新一下頁面,你將知道更多如何遠程操作Hudson的方法。
      在環境變量中添加WinRAR的安裝路徑,即可以在批處理中使用WinRAR命令來解壓archive
      Hudson會通過等待的方式來保證BUILD_NUMBER較小的構建會先完成。因此,妥善安排suite的順序和suite包含的自動化測試用例數可以提高測試速度哦~
      可以限制一個任務只能在某些機器上運行,也可以限制它只能在具有某些Label的機器上執行~
      點擊我可以查看關于Hudson預設的環境變量。

    posted @ 2014-06-16 10:17 順其自然EVO 閱讀(210) | 評論 (0)編輯 收藏

    PHP幾個防SQL注入攻擊自帶函數區別

     SQL注入攻擊是黑客攻擊網站最常用的手段。如果你的站點沒有使用嚴格的用戶輸入檢驗,那么常容易遭到SQL注入攻擊。SQL注入攻擊通常通過給站點數據庫提交不良的數據或查詢語句來實現,很可能使數據庫中的紀錄遭到暴露,更改或被刪除。
      為了防止SQL注入攻擊,PHP自帶一個功能可以對輸入的字符串進行處理,可以在較底層對輸入進行安全上的初步處理,也即Magic Quotes。(php.ini magic_quotes_gpc)。如果magic_quotes_gpc選項啟用,那么輸入的字符串中的單引號,雙引號和其它一些字符前將會被自動加 上反斜杠\。
      但Magic Quotes并不是一個很通用的解決方案,沒能屏蔽所有有潛在危險的字符,并且在許多服務器上Magic Quotes并沒有被啟用。所以,我們還需要使用其它多種方法來防止SQL注入。
      許多數據庫本身就提供這種輸入數據處理功能。例如PHP的MySQL操作函數中有addslashes()、 mysql_real_escape_string()、mysql_escape_string()等函數,可將特殊字符和可能引起數據庫操作出錯的字 符轉義。那么這三個功能函數之間有什么卻別呢?下面我們就來詳細講述下。
      雖然國內很多PHP程序員仍在依靠addslashes防止SQL注入,還是建議大家加強中文防止SQL注入的檢查。addslashes的問題在 于黑客 可以用0xbf27來代替單引號,而addslashes只是將0xbf27修改為0xbf5c27,成為一個有效的多字節字符,其中的0xbf5c仍會 被看作是單引號,所以addslashes無法成功攔截。
      當然addslashes也不是毫無用處,它是用于單字節字符串的處理,多字節字符還是用mysql_real_escape_string吧。
      另外對于php手冊中get_magic_quotes_gpc的舉例:
    if (!get_magic_quotes_gpc()) {
    $lastname = addslashes($_POST[‘lastname’]);
    } else {
    $lastname = $_POST[‘lastname’];
    }
      最好對magic_quotes_gpc已經開放的情況下,還是對$_POST[’lastname’]進行檢查一下。
      再說下mysql_real_escape_string和mysql_escape_string這2個函數的區別:
      mysql_real_escape_string 必須在(PHP 4 >= 4.3.0, PHP 5)的情況下才能使用。否則只能用 mysql_escape_string ,兩者的區別是:mysql_real_escape_string 考慮到連接的當前字符集,而mysql_escape_string 不考慮。
      總結一下:
      * addslashes() 是強行加\;
      * mysql_real_escape_string() 會判斷字符集,但是對PHP版本有要求;
      * mysql_escape_string不考慮連接的當前字符集。
      dz中的防止sql注入就是用addslashes這個函數,同時在dthmlspecialchars這個函數中有進行一些替換$string = preg_replace('/&((#(\d{3,5}|x[a-fA-F0-9]{4}));)/', '&\\1',這個替換解決了注入的問題,同時也解決了中文亂碼的一些問題

    posted @ 2014-06-16 10:11 順其自然EVO 閱讀(217) | 評論 (0)編輯 收藏

    ORACLE-SQL微妙之處

     本文總結一下平時經常使用的SQL語句以及一些ORACLE函數的微妙之處。歡迎大家多多補充平時最常用的SQL語句,供大家學習參考。
    SQL> select * from temp2;
    NAME            SORCE
    ---------- ----------
    1                  43
    2                  23
    3                  42
    4                  87
    5                  12
    <span style="font-size: 14px;"><strong><span style="color: #ff0000;">1、數據累加</span></strong></span>
    SQL> SELECT NAME, sum(sorce) OVER(ORDER BY NAME)
    2    FROM temp2
    3   ORDER BY NAME;
    NAME       SUM(SORCE)OVER(ORDERBYNAME)
    ---------- ---------------------------
    1                                   43
    2                                   66
    3                                  108
    4                                  195
    5                                  207
    <span style="font-size: 14px;"><strong><span style="color: #ff0000;">2、去掉最大值和最小值</span></strong></span>
    SQL> SELECT NAME,
    2         sorce,
    3         LAG(sorce) over(order by sorce)  Lag_List,
    4         LEAD(sorce) over(order by sorce)  Lead_List
    5    FROM temp2;
    NAME            SORCE        Lag       Lead
    ---------- ---------- ---------- ----------
    5                  12                    23
    2                  23         12         42
    3                  42         23         43
    1                  43         42         87
    4                  87         43
      1、著名分析函數--排序
    SQL> SELECT name,
    2         value,
    3         RANK() OVER(order by value) RANK_SORT,
    4         DENSE_RANK() OVER(order by value) DENSE_SORT,
    5         ROW_NUMBER() OVER(order by value) ROW_SORT
    6    FROM sorce;
    NAME       VALUE       RANK_SORT DENSE_SORT ROW_SORT
    ---------- ------ ---------- ---------- ----------
    wu          21          1          1          1
    zhang       60          2          2          2
    Li          70          3          3          3
    xue         119         5          5          5
    <span style="color: #ff0000;">wang        130         6          6          6
    chen        130         6          6          7
    sun         175         8          7          8</span>
    zhao        285         9          8          9
    su          359         10         9          10
    Li          480         11         10         11<br>
    可見三者的區別:<br>RANK()OVER():如果值相同,則兩者順序號相同,隨機一個在另外一個的上邊,而且順序號會有間斷,不是連續的;<br>DENSE_RANK():如果值相同,則兩者順序號相同,隨機一個在另外一個的上邊,而且順序號仍然是連續的,不存在斷層的現象;<br>ROW_NUMBER():如果值相同,則兩種順序號不同,安裝順序號依次排開,而且順序號是連續的。
      2、TRANSLATE()函數
      translate函數與replace類似,但是又與replace不同,translate指定字符串string中出現的from_str,將from_str中各個字符替換成to_str中位置順序與其相同的to_str中的字符。
      SQL Reference中給的例子:SELECT TRANSLATE('SQL*Plus User''s Guide', ' */''', '___') FROM DUAL;
      巧用:
     ?。?)判斷一個字符串是數字
      SELECT TRANSLATE('ABC123','#1234567890.','#') FROM DUAL;
     ?。?)統計字符E出現的次數
      SELECT LENGTHB(TRANSLATE('ABCDEFGEFGDBE','E'||'ABCDEFGEFGDBE','E')) FROM DUAL;
      3、ROUND()函數
      我們平時用得最多的是第一種,用ROUND()函數作為數據四舍五入運算,其實ROUND函數還有第二種形式,對日期進行格式化操作,與TRUNC()函數類似。
      如:SELECT ROUND(SYSDATE,'yyyy') FROM DUAL;
      SELECT ROUND(SYSDATE,'MM') FROM DUAL;
      SELECT ROUND(SYSDATE,'HH24') FROM DUAL;
      4、NVL相關函數
      NVL相關的函數有:NVL(expr1,expr2),NVL2(expr1,expr2,expr3),NULLIF(expr1,expr2),DECODE(expr1,expr2,value1,expr3,value2...,default)
      (1) NVL(expr1,expr2) :如果expr1為空,則用expr2來替換。
      (2) NVL2(expr1,expr2,expr3) :如果expr1非空,則返回expr2,否則返回expr3。
      (3) NULLIF(expr1,expr2):將expr1和expr2做比較,如果想等,則返回null,否則返回expr1。
      (3) DECODE(expr1,expr2,value1,expr3,value2...,default):如果expr1與expr2相等,則返回value1,如果expr1與expr3相等,則返回value2,...否則,返回default。
      5、收集表的統計信息
      收集表的統計信息方法有很多種: (1) ANALYZE  (2) DBMS_STATS
      看起來很繁瑣,其實用起來挺簡單的。
      如對某張表進行分析:
      ANALYZE TABLE TABLE_NAME COMPUTE STATISTICS;
      目前,ORACLE官方推薦第二種方法。在DBMS_STATS包里有很多過程和方法,對SCHEMA、TABLE和INDEX進行收集統計信息相關的操作。
      EXEC DBMS_STATS.GATHER_TABLE_STATS(OWNNAME=>'SCOTT',TABNAME=>'EMP',DEGREE=>4,CASCADE=>'TRUE');

    posted @ 2014-06-13 10:10 順其自然EVO 閱讀(171) | 評論 (0)編輯 收藏

    Java中JSON的簡單使用與前端解析

      一、JSON
      JSON(JavaScript Object Notation) 是一種輕量級的數據交換格式。 JSON采用完全獨立于語言的文本格式。這些特性使JSON成為理想的數據交換語言。易于人閱讀和編寫,同時也易于機器解析和生成。
      JSON與XML的對比(引用自:sanpintian的CSDN博客):
      1、可讀性:JSON和XML的可讀性可謂不相上下,一邊是建議的語法,一邊是規范的標簽形式,很難分出勝負。
      2、可擴展性:XML天生有很好的擴展性,JSON當然也有,沒有什么是XML能擴展,JSON不能的。
      3、編碼難度:XML有豐富的編碼工具,比如Dom4j、JDom等,JSON也有json.org提供的工具,但是JSON的編碼明顯比XML容易許多,即使不借助工具也能寫出JSON的代碼,可是要寫好XML就不太容易了。
      4、解碼難度:XML的解析得考慮子節點父節點,讓人頭昏眼花,而JSON的解析難度幾乎為0。這一點XML輸的真是沒話說。
      5、流行度:XML已經被業界廣泛的使用,而JSON才剛剛開始,但是在Ajax這個特定的領域,未來的發展一定是XML讓位于JSON。到時Ajax應該變成Ajaj(Asynchronous Javascript and JSON)了。
      二、導包
      使用JSON需要導入以下包:
      commons-beanutils.jar
      commons-logging.jar
      commons-lang.jar
      commons-collection.jar
      ezmorph.jar
      json-lib.jar
      三、實現
      Book類的實現:
    1  public class Book {
    2     private String name;
    3     private double price;
    4
    5     public String getName() {
    6         return name;
    7     }
    8
    9     public void setName(String name) {
    10         this.name = name;
    11     }
    12
    13     public double getPrice() {
    14         return price;
    15     }
    16
    17     public void setPrice(double price) {
    18         this.price = price;
    19     }
    20
    21     @Override
    22     public String toString() {
    23         return name+" "+price;
    24     }
    25 }
    1 /**
    2  * @author ZWQ
    3  * **/
    4 public class JsonTest {
    5     public static void main(String[] args) {
    6         //***********************************************************************
    7         // json基本測試
    8         {
    9             //新建一個JSON數組
    10             JSONArray jsonArray = new JSONArray();
    11             //新建一個JSON對象
    12             JSONObject json1 = new JSONObject();
    13             json1.put("id", "1");
    14             json1.put("name", "張三");
    15             json1.put("password", "123456");
    16             //將JSON對象添加到JSON數組中去
    17             jsonArray.add(json1);
    18
    19             JSONObject json2 = new JSONObject();
    20             json2.put("id", "2");
    21             json2.put("name", "李四");
    22             json2.put("password", "654321");
    23             jsonArray.add(json2);
    24             System.out.println("json數組基本測試:" + jsonArray);
    25
    26             //結果:
    27             //[{"id":"1","name":"張三","password":"123456"},{"id":"2","name":"李四","password":"654321"}]
    28         }
    29
    30         //***********************************************************************
    31         //將對象轉成JSON字符串
    32         {
    33             Book book = new Book();
    34             book.setName("Java入門教程");
    35             book.setPrice(52.3);
    36             //將Java對象轉成JSON對象
    37             JSONObject jsonObject = JSONObject.fromObject(book);
    38             System.out.println("從Object到JSONObject:" + jsonObject.toString());
    39
    40             //結果:
    41             //從Object到JSONObject:{"name":"Java入門教程","price":52.3}
    42         }
    43
    44         //***********************************************************************
    45         //將對象集合轉成JSON字符串
    46         {
    47             List<Book> list = new ArrayList<Book>();
    48             Book book1 = new Book();
    49             book1.setName("高等數學I");
    50             book1.setPrice(34.1);
    51             Book book2 = new Book();
    52             book2.setName("線性代數");
    53             book2.setPrice(12.7);
    54             list.add(book1);
    55             list.add(book2);
    56             //將List集合轉為JSON數組
    57             JSONArray jsonArray= JSONArray.fromObject(list);
    58             System.out.println("從Object集合到JSONArray:" + jsonArray.toString());
    59
    60             //結果:
    61             //從Object集合到JSONArray:[{"name":"高等數學I","price":34.1},{"name":"線性代數","price":12.7}]
    62         }
    63
    64         //***********************************************************************
    65         // 將JSON字符串轉為Java對象
    66         {
    67             String jsonString = "{name:'數據結構',price:52.3}";
    68             JSONObject jsonObject = JSONObject.fromObject(jsonString);
    69             //將JSON對象轉為Java對象
    70             Book book = (Book) JSONObject.toBean(jsonObject, Book.class);
    71             System.out.println(book.toString());
    72
    73             //結果:
    74             //數據結構 52.3
    75         }
    76
    77         //***********************************************************************
    78         //將JSON字符串轉為Java對象數組
    79         {
    80             // (2).Bean的數組
    81             String jsonsString = "[{name:'數據庫基礎',price:52.3},{name:'Oracle 11g精華',price:42.3}]";
    82             JSONArray jsonArray = JSONArray.fromObject(jsonsString);
    83             //將JSON數組轉為Java對象數組
    84             Book[] books = (Book[]) JSONArray.toArray(jsonArray, Book.class);
    85             for (Book b : books) {
    86                 System.out.println(b.toString());
    87             }
    88
    89             //結果:
    90             //數據庫基礎 52.3
    91             //Oracle 11g精華 42.3
    92         }
    93     }
    94 }
      四、前端解析
    1 //Jquery提供的獲取json的方法
    2 //使用前先導入Jquery
    3
    4 $('#button').click(function(){
    5     //url:請求的地址
    6     $.getJSON('url', {
    7         //id是需要傳的參數
    8         id: 1
    9         }, function(data) {//成功后data即為獲取的json字符串
    10             //例如data:[{"name":"高等數學I","price":34.1},{"name":"線性代數","price":12.7}]
    11             alert("第二本書是:"+data[1].name+"  價格是:"+data[1].price);
    12         });
    13 });

    posted @ 2014-06-13 10:09 順其自然EVO 閱讀(1689) | 評論 (0)編輯 收藏

    Fitnesse集成TestLink

     TestLink作為開源測試管理工具,可以進行測試工程、測試計劃以及執行計劃的管理,而且TestLink團隊提供了XML-PRC的接口供第三方工具調用,接口支持程度也比較好。
      Fitnesse作為開源驗收測試框架,本身可以做到測試集、測試用例的執行,有較為優秀的測試執行行為的管理以及測試結果的收集。
      由于Testlink大部分場合下是用于手工測試用例的管理,為了能夠是Testlink對于測試用例管理的優點也用于Fitnesse上自動化測試用例的管理,也為了能夠讓手工測試用例和自動化回歸測試用例mapping起來,方便測試管理者能夠清晰知道自動化測試用例在測試項目中的比例,也為了測試管理者可以較好的管理回歸測試流程,考慮將Fitnesse和Testlink進行集成。
      兩個平臺集成的基本思路是: 1. 將Testlink上的用例和Fitnesse上的用例一一mapping. 2. 將Fitnesse上用例的執行結果能夠實時反饋給Testlink上用例的執行結果。
      Testlink Java api client提供了一個非常好的接口,
      reportTestCaseResult(projectName,testPlanName,testCaseNameOrVisiableID,buildName,execNotes,testResultStatus)
      該接口有6個參數,其中
      projectName: Testlink上對應的測試工程名稱
      testPlanName:Testlink上測試工程對應的測試計劃
      testCaseNameOrVisiableID: Testlink上測試用例的名稱或ID,這里的ID是指測試項目前綴加上'-'在加上阿拉伯數字
      buildName:Testlink上對應測試計劃的構建執行計劃
      execNotes:是指每個case執行后的備注,可以為null
      testResultStatus:是指測試用例執行結果,'p'或者'f'
      通過調用給接口,我們可以完成測試用例執行結果的傳遞。
      接下去我們要解析Fitnesse執行結果的分析:
      在這里我通過一個代理proxy來完成該任務,該代理需要完成Fitnesse測試執行結果的解析,測試用例ID的解析,然后完成TestLink接口的調用
      如下圖所示總體架構:
    當然我的proxy還做了其他的事情,可以完成和Jenkins之間集成和調用。下圖是最終完成的事列
      上圖備注是測試用例在fitnesse上的具體執行結果,可以點擊查看失敗用例的原因。
      通過這個方法可以完成自動化測試用例和手工測試用例之間的mapping,也可以讓測試人員了解哪些用例是可以通過自動化實現的。
      總之使用Testlink java client api可以實現不同測試平臺之間的集成,方便工具和用例的統一管理。
      關于proxy代碼有興趣的話,可以上我的git hub主頁獲取。

    posted @ 2014-06-13 10:02 順其自然EVO 閱讀(272) | 評論 (0)編輯 收藏

    僅列出標題
    共394頁: First 上一頁 100 101 102 103 104 105 106 107 108 下一頁 Last 
    <2025年5月>
    27282930123
    45678910
    11121314151617
    18192021222324
    25262728293031
    1234567

    導航

    統計

    常用鏈接

    留言簿(55)

    隨筆分類

    隨筆檔案

    文章分類

    文章檔案

    搜索

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 亚洲午夜在线一区| jjizz全部免费看片| 亚洲AV日韩综合一区尤物| 国产性爱在线观看亚洲黄色一级片 | 亚洲成aⅴ人片在线观| 国产午夜亚洲不卡| 一本久久综合亚洲鲁鲁五月天| 131美女爱做免费毛片| 伊人久久大香线蕉免费视频| 国产成人无码a区在线观看视频免费| 香蕉成人免费看片视频app下载| 一级一看免费完整版毛片| 香蕉蕉亚亚洲aav综合| 亚洲精品老司机在线观看| 我要看免费的毛片| 成视频年人黄网站免费视频| 免费精品国自产拍在线播放 | fc2成年免费共享视频18| 精品国产亚洲第一区二区三区 | 久久电影网午夜鲁丝片免费| 久久久久av无码免费网| 色欲国产麻豆一精品一AV一免费| 久久免费视频一区| 国产高清视频免费在线观看| 免费激情网站国产高清第一页| 国产亚洲精品美女| 国产91成人精品亚洲精品| 亚洲AV成人无码网站| 亚洲欧美熟妇综合久久久久| 日韩亚洲不卡在线视频中文字幕在线观看 | 亚洲国产精品线观看不卡| 亚洲一区二区三区电影| 免费看一级做a爰片久久| 99国产精品视频免费观看| 野花香在线视频免费观看大全| 亚洲av无码一区二区三区人妖| 亚洲xxxx视频| 亚洲乱色熟女一区二区三区蜜臀| 久久亚洲精品国产精品婷婷| 在线精品亚洲一区二区| 亚洲欧洲日韩在线电影|