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

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

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

    qileilove

    blog已經(jīng)轉(zhuǎn)移至github,大家請(qǐng)?jiān)L問 http://qaseven.github.io/

    Java list三種遍歷方法性能比較

      從c/c++語言轉(zhuǎn)向java開發(fā),學(xué)習(xí)java語言list遍歷的三種方法,順便測(cè)試各種遍歷方法的性能,測(cè)試方法為在ArrayList中插入1千萬條記錄,然后遍歷ArrayList,發(fā)現(xiàn)了一個(gè)奇怪的現(xiàn)象,測(cè)試代碼例如以下:
    package com.hisense.tiger.list;
    import java.util.ArrayList;
    import java.util.Iterator;
    import java.util.List;
    public class ListTest {
    public static void main(String[] args)
    {
    List<String> list = new ArrayList<String>();
    long t1,t2;
    for(int j = 0; j < 10000000; j++)
    {
    list.add("aaaaaa" + j);
    }
    System.out.println("List first visit method:");
    t1=System.currentTimeMillis();
    for(String tmp:list)
    {
    //System.out.println(tmp);
    }
    t2=System.currentTimeMillis();
    System.out.println("Run Time:" + (t2 -t1) + "(ms)");
    System.out.println("List second visit method:");
    t1=System.currentTimeMillis();
    for(int i = 0; i < list.size(); i++)
    {
    list.get(i);
    //System.out.println(list.get(i));
    }
    t2=System.currentTimeMillis();
    System.out.println("Run Time:" + (t2 -t1) + "(ms)");
    System.out.println("List Third visit method:");
    Iterator<String> iter = list.iterator();
    t1=System.currentTimeMillis();
    while(iter.hasNext())
    {
    iter.next();
    //System.out.println(iter.next());
    }
    t2=System.currentTimeMillis();
    System.out.println("Run Time:" + (t2 -t1) + "(ms)");
    System.out.println("Finished!!!!!!!!");
    }
    }
      測(cè)試結(jié)果例如以下:
      List first visit method:
      Run Time:170(ms)
      List second visit method:
      Run Time:10(ms)
      List Third visit method:
      Run Time:34(ms)
      Finished!!!!!!!!
      測(cè)試的結(jié)論非常奇怪,第一種方法是java語言支持的新語法,代碼最簡(jiǎn)潔,可是在三種方法中,性能確是最差的,取size進(jìn)行遍歷性能是最高的,求牛人解釋?

    posted @ 2014-11-24 10:01 順其自然EVO 閱讀(201) | 評(píng)論 (0)編輯 收藏

    通過配置實(shí)現(xiàn)多種需求下的地圖展示

    1.背景
      對(duì)于一般性的地圖顯示需求,我們只需要知道地圖的一個(gè)固定URL,然后知道要顯示的范圍和要顯示的級(jí)別以及每個(gè)級(jí)別的scale等即可。
      但是如果我們遇到下面幾種情況時(shí),又該如何。
      (1)需要顯示的圖層的不同級(jí)別來自于不同的服務(wù)器(URL不同):如前幾個(gè)級(jí)別由一個(gè)固定URL提供,后幾個(gè)級(jí)別由另外一個(gè)URL提供。
      (2)需要同時(shí)疊加幾張圖層:如需要疊加地形圖和注記圖,且圖層的顯示有層級(jí)之分。
      (3)需要同時(shí)疊加幾張圖層,并且每個(gè)圖層初始顯示級(jí)別不一樣。
      (4)需要同時(shí)疊加幾張圖層,圖層的URL的請(qǐng)求方式均有不同:如其中一個(gè)圖層由AGS提供,一個(gè)圖層是天地圖服務(wù)提供,還有一個(gè)圖層是當(dāng)?shù)爻枪芫痔峁詈筮€有一個(gè)圖層是由本地未發(fā)布的緩存瓦片提供。
      諸如類似于以上的地圖顯示需求還有很多,如果我們單純的對(duì)每一種情況進(jìn)行一個(gè)代碼上的分支當(dāng)然也是能解決的。但是這并不是最好的一種解決方法,每次新的需求提出時(shí),都需要對(duì)代碼修改,這不符合設(shè)計(jì)模式中的開放封閉原則。雖然我們可以用簡(jiǎn)單工廠等模式來努力改善這種情況,不過如果有更好的方式,不需要修改任何代碼,不需要用設(shè)計(jì)模式,就能解決以上的問題是否更好?
      下面我將給出一種通過數(shù)據(jù)庫(kù)配置來實(shí)現(xiàn)上面所有問題的解決方案。此方案在多個(gè)項(xiàng)目中已經(jīng)開始使用。
      2.配置(表)的設(shè)計(jì)
      2.1原理
      首先我們必須對(duì)以上多種地圖顯示的需求進(jìn)行一個(gè)分析,提出他們的共同點(diǎn)。
      (1)對(duì)圖層開始顯示的級(jí)別有需求(startLevel)。
      (2)多張圖層疊加,并且圖層疊加有從上自下的順序(layerDisplayOrder)。
      (3)圖層可能的URL不同(ServiceURL)
      (4)每個(gè)圖層的URL格式可以不一樣,比如URL可能天地圖的WMTS格式,可能是AGS發(fā)布的請(qǐng)求方式(level\row\col),也有可能是Geoserver發(fā)布的WMS格式。并且有的服務(wù)提供商還需要token字段來判斷是否有權(quán)限得到服務(wù),或者不同的服務(wù)商提供的WMTS格式中對(duì)col和row以及l(fā)evel的表述字段名稱不一樣(通過這個(gè)分析,可以提煉出Xfield、Yfield、LevelFieldName、Token字段來對(duì)不同的需求進(jìn)行配置)。
      (5)所有的圖層,如果要疊加,需要用同一個(gè)空間參考,同一個(gè)瓦片大小,同一個(gè)地圖起始原點(diǎn),以及同一套地圖比例尺。
      (6)變化的只是URL,其核心瓦片行列號(hào)和地圖級(jí)別是每種瓦片請(qǐng)求URL均需要的。
      2.2設(shè)計(jì)
      2.2.1圖層列表(tcMaplayerList)的設(shè)計(jì)
      首先我給出圖層列表設(shè)計(jì)的截圖:
      (1)每一個(gè)圖層均有一個(gè)圖層名
      (2)每一個(gè)圖層均有自己的圖層類型,比如AGS類型的、WMTS類型的等。這是為了程序中對(duì)不同的類型的URL進(jìn)行解析。
      (3)每一個(gè)圖層有其自己的顯示順序,為了正確的疊加圖層之用。
      (4)每一個(gè)圖層也有自己開始顯示的級(jí)別。如有的圖層想第一級(jí)別開始顯示,有的圖層希望地圖放大到第二級(jí)別時(shí)才開始顯示。
      2.2.2圖層詳細(xì)內(nèi)容列表(tcgismapservicedetail)的設(shè)計(jì)
      同樣,這里先給出表的截圖:
      (1)ItemID為每個(gè)記錄的主碼。
      (2)layerName與tcMaplayerList中的圖層名是對(duì)應(yīng)的。
      (3)圖層級(jí)別表示的是該圖層在此級(jí)別時(shí)的信息。
      (4)圖層在該級(jí)別的URL有一個(gè)固定的部分,比如WMTS請(qǐng)求中,變化的只是行列號(hào),而前面的部分均是不定的。
      (5)Token、XFieldName、YFieldName、LevelFieldName均是為擴(kuò)展之用,當(dāng)URL需要給行列號(hào)以及級(jí)別一個(gè)固定的名稱時(shí)等,則配置。否則不用。
      3.工作流程
      3.1流程圖
      3.2流程詳解
      3.2.1得到需要顯示的圖層列表
      在顯示地圖之前,需要先向后臺(tái)發(fā)出請(qǐng)求,此請(qǐng)求的參數(shù)主要是layerType,后臺(tái)根據(jù)layerType將tcMapLayerList表中符合需求的內(nèi)容讀出返回。
      3.2.2 解析當(dāng)前地圖級(jí)別下的各個(gè)圖層信息,并順序顯示
      在解析了需要顯示的圖層列表后,每個(gè)圖層均會(huì)給后臺(tái)發(fā)出自己的信息,信息中包括了此時(shí)地圖的級(jí)別,以及需要得到的瓦片行列號(hào)和自己的圖層名。
      但是此時(shí)的地圖級(jí)別并不是圖層發(fā)給后臺(tái)的級(jí)別參數(shù),真是的地圖級(jí)別是:
      factLayerLevel=layerLevel+startLayerLevel。
      根據(jù)factlayerLevel和layerName,在tcgismapservicedetail中找到對(duì)應(yīng)的信息,如果有信息,則表示該圖層在此真實(shí)級(jí)別下是需要顯示的,然后根據(jù)該圖層的layerType將此時(shí)的URL拼接出來,下載瓦片然后返回此瓦片。
      如果沒有查到數(shù)據(jù)則不顯示此地圖級(jí)別下的該圖層。
      4.成果展示
      4.1測(cè)繪局地圖+本地瓦片
      4.2 天地圖地形圖層+天地圖注記圖層+Geoserver發(fā)布的行政區(qū)劃圖層
      4.3測(cè)繪局提供的管線WMTS圖層+本地AGS發(fā)布的地形圖層
      5.總結(jié)
      通過此配置基本可以實(shí)現(xiàn)項(xiàng)目中遇到的絕大部分地圖需求。改進(jìn)后,雖然不再需要對(duì)各種需求進(jìn)行大規(guī)模的代碼編寫,但是針對(duì)不同的瓦片類型的URL獲取依然是要走分支的,這里可以通過策略模式來讓代碼更加規(guī)范。
      斷了一個(gè)多月沒寫博,WebGIS的原理系列會(huì)繼續(xù)寫下去的,希望大家持續(xù)關(guān)注。

    posted @ 2014-11-24 10:00 順其自然EVO 閱讀(186) | 評(píng)論 (0)編輯 收藏

    BurpSuite實(shí)例教程講解

     很久以前就看到了Burp suite這個(gè)工具了,當(dāng)時(shí)感覺好NB,但全英文的用起來很是蛋疼,網(wǎng)上也沒找到什么教程,就把這事給忘了。今天準(zhǔn)備開始好好學(xué)習(xí)這個(gè)滲透神器,也正好給大家分享下。(注:內(nèi)容大部分是百度的,我只是分享下自已的學(xué)習(xí)過程)
      什么是BurpSuite
      Burp Suite 是用于攻擊web 應(yīng)用程序的集成平臺(tái)。它包含了許多工具,并為這些工具設(shè)計(jì)了許多接口,以促進(jìn)加快攻擊應(yīng)用程序的過程。所有的工具都共享一個(gè)能處理并顯示HTTP 消息,持久性,認(rèn)證,代理,日志,警報(bào)的一個(gè)強(qiáng)大的可擴(kuò)展的框架。
      Burp Suite 能高效率地與單個(gè)工具一起工作,例如:
      一個(gè)中心站點(diǎn)地圖是用于匯總收集到的目標(biāo)應(yīng)用程序信息,并通過確定的范圍來指導(dǎo)單個(gè)程序工作。
      在一個(gè)工具處理HTTP 請(qǐng)求和響應(yīng)時(shí),它可以選擇調(diào)用其他任意的Burp工具。例如:
      代理記錄的請(qǐng)求可被Intruder 用來構(gòu)造一個(gè)自定義的自動(dòng)攻擊的準(zhǔn)則,也可被Repeater 用來手動(dòng)攻擊,也可被Scanner 用來分析漏洞,或者被Spider(網(wǎng)絡(luò)爬蟲)用來自動(dòng)搜索內(nèi)容。應(yīng)用程序可以是“被動(dòng)地”運(yùn)行,而不是產(chǎn)生大量的自動(dòng)請(qǐng)求。Burp Proxy 把所有通過的請(qǐng)求和響應(yīng)解析為連接和形式,同時(shí)站點(diǎn)地圖也相應(yīng)地更新。由于完全的控制了每一個(gè)請(qǐng)求,你就可以以一種非入侵的方式來探測(cè)敏感的應(yīng)用程序。
      當(dāng)你瀏覽網(wǎng)頁(這取決于定義的目標(biāo)范圍)時(shí),通過自動(dòng)掃描經(jīng)過代理的請(qǐng)求就能發(fā)現(xiàn)安全漏洞。
      IburpExtender 是用來擴(kuò)展Burp Suite 和單個(gè)工具的功能。一個(gè)工具處理的數(shù)據(jù)結(jié)果,可以被其他工具隨意的使用,并產(chǎn)生相應(yīng)的結(jié)果。
      BurpSuite工具箱
      Proxy——是一個(gè)攔截HTTP/S的代理服務(wù)器,作為一個(gè)在瀏覽器和目標(biāo)應(yīng)用程序之間的中間人,允許你攔截,查看,修改在兩個(gè)方向上的原始數(shù)據(jù)流。
      Spider——是一個(gè)應(yīng)用智能感應(yīng)的網(wǎng)絡(luò)爬蟲,它能完整的枚舉應(yīng)用程序的內(nèi)容和功能。
      Scanner[僅限專業(yè)版]——是一個(gè)高級(jí)的工具,執(zhí)行后,它能自動(dòng)地發(fā)現(xiàn)web 應(yīng)用程序的安全漏洞。
      Intruder——是一個(gè)定制的高度可配置的工具,對(duì)web應(yīng)用程序進(jìn)行自動(dòng)化攻擊,如:枚舉標(biāo)識(shí)符,收集有用的數(shù)據(jù),以及使用fuzzing 技術(shù)探測(cè)常規(guī)漏洞。
      Repeater——是一個(gè)靠手動(dòng)操作來補(bǔ)發(fā)單獨(dú)的HTTP 請(qǐng)求,并分析應(yīng)用程序響應(yīng)的工具。
      Sequencer——是一個(gè)用來分析那些不可預(yù)知的應(yīng)用程序會(huì)話令牌和重要數(shù)據(jù)項(xiàng)的隨機(jī)性的工具。
      Decoder——是一個(gè)進(jìn)行手動(dòng)執(zhí)行或?qū)?yīng)用程序數(shù)據(jù)者智能解碼編碼的工具。
      Comparer——是一個(gè)實(shí)用的工具,通常是通過一些相關(guān)的請(qǐng)求和響應(yīng)得到兩項(xiàng)數(shù)據(jù)的一個(gè)可視化的“差異”。
      BurpSuite的使用
      當(dāng)Burp Suite 運(yùn)行后,Burp Proxy 開起默認(rèn)的8080 端口作為本地代理接口。通過置一個(gè)web 瀏覽器使用其代理服務(wù)器,所有的網(wǎng)站流量可以被攔截,查看和修改。默認(rèn)情況下,對(duì)非媒體資源的請(qǐng)求將被攔截并顯示(可以通過Burp Proxy 選項(xiàng)里的options 選項(xiàng)修改默認(rèn)值)。對(duì)所有通過Burp Proxy 網(wǎng)站流量使用預(yù)設(shè)的方案進(jìn)行分析,然后納入到目標(biāo)站點(diǎn)地圖中,來勾勒出一張包含訪問的應(yīng)用程序的內(nèi)容和功能的畫面。在Burp Suite 專業(yè)版中,默認(rèn)情況下,Burp Scanner是被動(dòng)地分析所有的請(qǐng)求來確定一系列的安全漏洞。
      在你開始認(rèn)真的工作之前,你最好為指定工作范圍。最簡(jiǎn)單的方法就是瀏覽訪問目標(biāo)應(yīng)用程序,然后找到相關(guān)主機(jī)或目錄的站點(diǎn)地圖,并使用上下菜單添加URL 路徑范圍。通過配置的這個(gè)中心范圍,能以任意方式控制單個(gè)Burp 工具的運(yùn)行。
      當(dāng)你瀏覽目標(biāo)應(yīng)用程序時(shí),你可以手動(dòng)編輯代理截獲的請(qǐng)求和響應(yīng),或者把攔截完全關(guān)閉。在攔截關(guān)閉后,每一個(gè)請(qǐng)求,響應(yīng)和內(nèi)容的歷史記錄仍能再站點(diǎn)地圖中積累下來。
      和修改代理內(nèi)截獲的消息一樣,你可以把這些消息發(fā)送到其他Burp 工具執(zhí)行一些操作:
      你可以把請(qǐng)求發(fā)送到Repeater,手動(dòng)微調(diào)這些對(duì)應(yīng)用程序的攻擊,并重新發(fā)送多次的單獨(dú)請(qǐng)求。
      [專業(yè)版]你可以把請(qǐng)求發(fā)送到Scanner,執(zhí)行主動(dòng)或被動(dòng)的漏洞掃描。
      你可以把請(qǐng)求發(fā)送到Intruer,加載一個(gè)自定義的自動(dòng)攻擊方案,進(jìn)行確定一些常規(guī)漏洞。
      如果你看到一個(gè)響應(yīng),包含不可預(yù)知內(nèi)容的會(huì)話令牌或其他標(biāo)識(shí)符,你可以把它發(fā)送到Sequencer 來測(cè)試它的隨機(jī)性。
      當(dāng)請(qǐng)求或響應(yīng)中包含不透明數(shù)據(jù)時(shí),可以把它發(fā)送到Decoder 進(jìn)行智能解碼和識(shí)別一些隱藏的信息。
      [專業(yè)版]你可使用一些engagement 工具使你的工作更快更有效。
      你在代理歷史記錄的項(xiàng)目,單個(gè)主機(jī),站點(diǎn)地圖里目錄和文件,或者請(qǐng)求響應(yīng)上顯示可以使用工具的任意地方上執(zhí)行任意以上的操作。
      可以通過一個(gè)中央日志記錄的功能,來記錄所單個(gè)工具或整個(gè)套件發(fā)出的請(qǐng)求和響應(yīng)。
      這些工具可以運(yùn)行在一個(gè)單一的選項(xiàng)卡窗口或者一個(gè)被分離的單個(gè)窗口。所有的工具和套件的配置信息是可選為通過程序持久性的加載。在Burp Suite 專業(yè)版中,你可以保存整個(gè)組件工具的設(shè)置狀態(tài),在下次加載過來恢復(fù)你的工具。
      burpsuite專業(yè)版的個(gè)人感受
      不知不覺使用burpsuite也有點(diǎn)年頭了。它在我日常進(jìn)行安全評(píng)估,它已經(jīng)變得日益重要。
      現(xiàn)在已經(jīng)變成我在日常滲透測(cè)試中不可缺少的工具之一。burpsuite官方現(xiàn)在已經(jīng)更新到1.5,與之前的一點(diǎn)1.4相比。界面做了比較大的變化。而且還增加了自定義快捷鍵功能。burpsuite1.5缺點(diǎn)是對(duì)中文字符一如既往的亂碼。burpsuite入門的難點(diǎn)是:入門很難,參數(shù)復(fù)雜,但是一旦掌握它的使用方法,在日常工作中肯定會(huì)如虎添翼。
      網(wǎng)上有破解版的下載,請(qǐng)自行百度。
      一 快速入門(Burpsuite的安裝使用與改包上傳)
      BlAck.Eagle
      Burp suite 是一個(gè)安全測(cè)試框架,它整合了很多的安全工具,對(duì)于滲透的朋友來說,是不可多得的一款囊中工具包,今天筆者帶領(lǐng)大家來解讀如何通過該工具迅速處理“截?cái)嗌蟼?#8221;的漏洞。如果對(duì)該漏洞還不熟悉,就該讀下以前的黑客X檔案補(bǔ)習(xí)下了。
      由于該工具是通過Java寫的,所以需要安裝 JDK,關(guān)于 JDK 的安裝,筆者簡(jiǎn)單介紹 下。基本是傻瓜化安裝,安裝完成后需要簡(jiǎn)單配置下環(huán)境變量,右鍵 ”我的電腦”->”屬 性”->”高級(jí)”->”環(huán)境變量”,在系統(tǒng)變量中查找 Path,然后點(diǎn)擊編輯,把 JDK 的 bin 目 錄寫在 path 的最后即可。如圖 1
      
    圖 1
      通過 CMD 執(zhí)行下 javac 看是否成功安裝。安裝配置成功則會(huì)顯示下圖信息。如圖 2
      圖 2 這里的測(cè)試網(wǎng)址是筆者幫朋友測(cè)試某站點(diǎn)時(shí)獲取的,登陸后臺(tái)后可以發(fā)表新聞,但是只能上 傳圖片。然后發(fā)現(xiàn)新聞的圖片目錄在 upload/newsimg 下。如圖 3
      
    圖 3
      后臺(tái)有個(gè)” 網(wǎng)站資料設(shè)置”的功能,可以自行定義新聞圖片的路徑,但是當(dāng)嘗試把新聞圖片
      路徑改為”upload/newsimg.asp/”時(shí),上傳圖片竟然上傳失敗了,所以這種方法失效。 如圖 4、
      
    圖 4
      接下來我們嘗試上傳截?cái)嗦┒矗赡艽蠹医?jīng)常用的是通過 WSockExpert 抓包,修改后通過 nc 來提交獲取 shell,但是大家會(huì)發(fā)現(xiàn)那樣有點(diǎn)繁瑣,我們看看今天的方法是多么高效: 首先允許 burpsuite.jar,然后點(diǎn)擊”proxy” 標(biāo)簽,會(huì)發(fā)現(xiàn) burp suite 默認(rèn)的代理監(jiān)聽端 口為  8080,如果怕跟自己電腦上的某個(gè)端口沖突的話,可以點(diǎn)擊”edit”進(jìn)行編輯。筆者 使用默認(rèn)端口。如圖 5
      
    圖 5
      然后打開本地瀏覽器的代理設(shè)置的地方,IE  一般為”工具”->”Internet 選項(xiàng)” –>”連 接”->”局域網(wǎng)設(shè)置”,其他瀏覽器大致相同。如圖 6
      
    圖 6
      設(shè)置代理之后,我們到后臺(tái)的某個(gè)上傳新聞圖片的地方上傳一個(gè)圖片木馬,我這里的圖片木 馬為asp 一句話。如圖 7
      
    圖 7
      點(diǎn)擊上傳之后,我們到 proxy 的”history”選項(xiàng),會(huì)發(fā)現(xiàn)該網(wǎng)站的某個(gè) POST 提交請(qǐng)求, 我們選中該鏈接后,右鍵選擇”send to repeater”,如圖 8
      
    圖 8
      我們會(huì)發(fā)現(xiàn)剛才提交的請(qǐng)求的數(shù)據(jù)包,那么我們看一下,有一項(xiàng)是上傳路徑的地方,我們以
      前 進(jìn) 行 截 斷 上 傳 的 時(shí) 候 經(jīng) 常 修 改 這 個(gè) 地 方 , 這 次 也 不 例 外 , 我 們 把 上 傳 路 徑 改 為”upload/shell.asp ”后面有一個(gè)空格,如圖 9
     
     然后選擇”hex”進(jìn)入 16 進(jìn)制編輯模塊,將空格的 16 進(jìn)制 20 改為 00,即 null。如圖 10
      然后點(diǎn)擊上方的”go”即可進(jìn)行數(shù)據(jù)包的提交,提交成功后會(huì)返回提交的路徑,如圖 11
      
    圖 10
      
    圖 11
      筆者通過菜刀就直接連接到一句話后門了。如圖 12,大家進(jìn)行測(cè)試吧!
      
    圖 12

    posted @ 2014-11-24 09:58 順其自然EVO 閱讀(608) | 評(píng)論 (0)編輯 收藏

    淺談測(cè)試rhel7新功能時(shí)的感受

    半夜起來看世界杯,沒啥激情,但是又怕錯(cuò)誤意大利和英格蘭的比賽,就看了rhel7
      相關(guān)新功能的介紹。
      安裝還算順利,安裝的界面比以前簡(jiǎn)潔的多,很清爽,分類很是明確。
      有些奇怪的是,我安裝的時(shí)候,怕有些基礎(chǔ)的包沒有裝上去,所以選定了mini和Web的類型,結(jié)果還是有些基礎(chǔ)的包沒有安裝,比如 ifconfig 。
      虛擬機(jī)的網(wǎng)卡,被識(shí)別為ens,有意思。
      
      yum groupinstall Base
      這樣的話,就可以把一些基礎(chǔ)的包打上。可以正常的時(shí)候ifconfig lsof  。
      這里需要說明的是,redhat7的測(cè)試的repo源貌似不能用,我跟著地址看了下。壓根就沒有,我想應(yīng)該還是測(cè)試版的原因吧。 直接mount /dev/cdrom /mnt用的。
      [rhel-iso]
      name=Red Hat Enterprise Linux 7
      baseurl=file:///mnt/
      enabled=1
      系統(tǒng)的分區(qū)默認(rèn)是xfs格式,當(dāng)然你還是可以用ext3,ext4的
      [root@localhost ~]# df -T
      文件系統(tǒng)              類型     1K-blocks    已用     可用 已用% 掛載點(diǎn)
      /dev/mapper/rhel-root xfs       39262208 3591304 35670904   10% /
      devtmpfs              devtmpfs    500772       0   500772    0% /dev
      tmpfs                 tmpfs       507508       0   507508    0% /dev/shm
      tmpfs                 tmpfs       507508    2604   504904    1% /run
      tmpfs                 tmpfs       507508       0   507508    0% /sys/fs/cgroup
      /dev/sda1             xfs         494940   95444   399496   20% /boot
      發(fā)現(xiàn)rhel7的開發(fā)軟件版本不低。
      python 是2.7.5的了,和ubuntu一樣。  java默認(rèn)也給你裝上了。perl在centos6應(yīng)該是5.10的 ,現(xiàn)在更新到了5.16.3 。 至于為什么更新到perl6,估計(jì)和python3一樣吧。
      [root@localhost ~]#
      [root@localhost ~]#
      [root@localhost ~]# python -V
      Python 2.7.5
      [root@localhost ~]# java -version
      java version "1.7.0_45"
      OpenJDK Runtime Environment (rhel-2.4.3.4.el7-x86_64 u45-b15)
      OpenJDK 64-Bit Server VM (build 24.45-b08, mixed mode)
      [root@localhost ~]#
      [root@localhost ~]#
      [root@localhost ~]# perl -v
      This is perl 5, version 16, subversion 3 (v5.16.3) built for x86_64-linux-thread-multi
      (with 24 registered patches, see perl -V for more detail)
      想安裝pip但是iso沒有python-pip這個(gè)包。rhel7的官方源又打不開,郁悶。本來打算用epel6試試,用不了,到epel官網(wǎng)一瞅。epel居然已經(jīng)有對(duì)于rhel7的源了。
      
     簡(jiǎn)單測(cè)試下rhel7的openlmi,什么是openlmi,我看了下一些文檔,他是一個(gè)類似func、但又不屬于puppet這類的集群接口工具。
      安裝    yum install openlmi
      安裝    yum -y install openlmi-scripts*
      scp root@10.10.10.71:/etc/Pegasus/client.pem /etc/pki/ca-trust/source/anchors/managed-machine-cert.pem
      [root@localhost ~]# lmi -h 10.10.10.71
      lmi> hwinfo
      username: pegasus
      password:
      error   : Failed to make a connection to "10.10.10.71": (0, 'Socket error: [Errno 113] No route to host')
      error   : No successful connection made.
      lmi>
      lmi>
      lmi>
      原因不詳,我看了下官網(wǎng)對(duì)于openlmi的一些介紹,使用方面也是相當(dāng)?shù)暮?jiǎn)練。
      lmi -h ${hostname}
      lmi> help
      ...
      lmi> sw search django
      ...
      lmi> sw install python-django
      ...
      lmi> exit
      rhel7 用systemd替換了咱們熟悉的sysv ,說是這東西很強(qiáng)大,說實(shí)話,資料還是少,這里就簡(jiǎn)單講解下systemd的用法。
    # CentOS 6.4
    service httpd (start|stop)
    # rhel7
    systemctl (start|stop) httpd.service
    # CentOS 6.4
    chkconfig httpd (on|off)
    # rhel7
    systemctl (enable|disable) httpd.service
    $ cat /usr/lib/systemd/system/httpd.service
    [Unit]
    Description=The Apache HTTP Server
    After=network.target remote-fs.target nss-lookup.target
    [Service]
    Type=notify
    EnvironmentFile=/etc/sysconfig/httpd
    ExecStart=/usr/sbin/httpd $OPTIONS -DFOREGROUND
    ExecReload=/usr/sbin/httpd $OPTIONS -k graceful
    ExecStop=/usr/sbin/httpd $OPTIONS -k graceful-stop
    # We want systemd to give httpd some time to finish gracefully, but still want
    # it to kill httpd after TimeoutStopSec if something went wrong during the
    # graceful stop. Normally, Systemd sends SIGTERM signal right after the
    # ExecStop, which would kill httpd. We are sending useless SIGCONT here to give
    # httpd time to finish.
    KillSignal=SIGCONT
    PrivateTmp=true
    [Install]
    WantedBy=multi-user.target
      會(huì)發(fā)現(xiàn)其實(shí),用systemd參數(shù)更加的清晰,在sysv下,啟動(dòng)start、關(guān)閉stop、重啟restart都是用$1來傳遞參數(shù),但是在systemctl下,更直白點(diǎn)。很是像supervisord這個(gè)daemon程序。
      [root@localhost ~]# chkconfig --list|grep samba
      注意:該輸出結(jié)果只顯示 SysV 服務(wù),并不包含原生 systemd 服務(wù)。SysV 配置數(shù)據(jù)可能被原生 systemd 配置覆蓋。
      如果您想列出 systemd 服務(wù),請(qǐng)執(zhí)行 'systemctl list-unit-files'。
      欲查看對(duì)特定 target 啟用的服務(wù)請(qǐng)執(zhí)行
      'systemctl list-dependencies [target]'。
      [root@localhost ~]#
      [root@localhost ~]#
      [root@localhost ~]# systemctl list-dependencies samba
      samba.service
      [root@localhost ~]#
      數(shù)據(jù)庫(kù)方面真的是轉(zhuǎn)向到mariadb,當(dāng)我去安裝mysql的時(shí)候,他會(huì)直接去安裝mariadb ,看來mariadb大勢(shì)所趨呀。
      [root@localhost ~]# 原文:http://rfyiamcool.blog.51cto.com/1030776/1426550
      [root@localhost ~]# yum -y install mysql
      已加載插件:langpacks, product-id, subscription-manager
      This system is not registered to Red Hat Subscription Management. You can use subscription-manager to register.
      file:///mnt/repodata/repomd.xml: [Errno 14] curl#37 - "Couldn't open file /mnt/repodata/repomd.xml"
      正在嘗試其它鏡像。
      軟件包 1:mariadb-5.5.33a-3.el7.x86_64 已安裝并且是最新版本
      無須任何處理
      [root@localhost ~]#
      [root@localhost ~]#
      [root@localhost ~]# yum -y install mysql-server
      已加載插件:langpacks, product-id, subscription-manager
      This system is not registered to Red Hat Subscription Management. You can use subscription-manager to register.
      file:///mnt/repodata/repomd.xml: [Errno 14] curl#37 - "Couldn't open file /mnt/repodata/repomd.xml"
      正在嘗試其它鏡像。
      正在解決依賴關(guān)系
      --> 正在檢查事務(wù)
      ---> 軟件包 mariadb-galera-server.x86_64.1.5.5.37-2.el7 將被 安裝
      --> 正在處理依賴關(guān)系 mariadb-galera-common(x86-64) = 1:5.5.37-2.el7,它被軟件包 1:mariadb-galera-server-5.5.37-2.el7.x86_64 需要
      --> 正在處理依賴關(guān)系 galera >= 25.3.3,它被軟件包 1:mariadb-galera-server-5.5.37-2.el7.x86_64 需要
      --> 正在處理依賴關(guān)系 perl-DBI,它被軟件包 1:mariadb-galera-server-5.5.37-2.el7.x86_64 需要
      --> 正在處理依賴關(guān)系 perl-DBD-MySQL,它被軟件包 1:mariadb-galera-server-5.5.37-2.el7.x86_64 需要
      --> 正在處理依賴關(guān)系 perl(DBI),它被軟件包 1:mariadb-galera-server-5.5.37-2.el7.x86_64 需要
      --> 正在檢查事務(wù)
      ---> 軟件包 galera.x86_64.0.25.3.5-5.el7 將被 安裝
      --> 正在處理依賴關(guān)系 nmap-ncat,它被軟件包 galera-25.3.5-5.el7.x86_64 需要
      ---> 軟件包 mariadb-galera-common.x86_64.1.5.5.37-2.el7 將被 安裝
      ---> 軟件包 perl-DBD-MySQL.x86_64.0.4.023-2.el7 將被 安裝
      ---> 軟件包 perl-DBI.x86_64.0.1.627-1.el7 將被 安裝
      --> 正在處理依賴關(guān)系 perl(RPC::PlClient) >= 0.2000,它被軟件包 perl-DBI-1.627-1.el7.x86_64 需要
      --> 正在處理依賴關(guān)系 perl(RPC::PlServer) >= 0.2001,它被軟件包 perl-DBI-1.627-1.el7.x86_64 需要
      --> 正在檢查事務(wù)
      ---> 軟件包 nmap-ncat.x86_64.2.6.40-2.el7 將被 安裝
      ---> 軟件包 perl-PlRPC.noarch.0.0.2020-12.el7 將被 安裝
      --> 正在處理依賴關(guān)系 perl(Net::Daemon) >= 0.13,它被軟件包 perl-PlRPC-0.2020-12.el7.noarch 需要
      --> 正在處理依賴關(guān)系 perl(Net::Daemon::Log),它被軟件包 perl-PlRPC-0.2020-12.el7.noarch 需要
      --> 正在處理依賴關(guān)系 perl(Net::Daemon::Test),它被軟件包 perl-PlRPC-0.2020-12.el7.noarch 需要
      --> 正在檢查事務(wù)
      ---> 軟件包 perl-Net-Daemon.noarch.0.0.48-4.el7 將被 安裝
      --> 解決依賴關(guān)系完成
      依賴關(guān)系解決
      ======================================================================================================================================
      Package                                 架構(gòu)                     版本                               源                          大小
      ======================================================================================================================================
      正在安裝:
      mariadb-galera-server                   x86_64                   1:5.5.37-2.el7                     epel                        11 M
      為依賴而安裝:
      galera                                  x86_64                   25.3.5-5.el7                       epel                       1.1 M
      mariadb-galera-common                   x86_64                   1:5.5.37-2.el7                     epel                       212 k
      nmap-ncat                               x86_64                   2:6.40-2.el7                       rhel-iso                   198 k
      perl-DBD-MySQL                          x86_64                   4.023-2.el7                        rhel-iso                   140 k
      perl-DBI                                x86_64                   1.627-1.el7                        rhel-iso                   801 k
      perl-Net-Daemon                         noarch                   0.48-4.el7                         rhel-iso                    51 k
      perl-PlRPC                              noarch                   0.2020-12.el7
      期待centos7的到來,用rhel7,總是覺得不順手,心里別扭。 先這樣,有時(shí)間再搞。

    posted @ 2014-11-24 09:23 順其自然EVO 閱讀(1582) | 評(píng)論 (0)編輯 收藏

    記一次性能測(cè)試實(shí)踐

     1.測(cè)試對(duì)象
      這次測(cè)了一些http接口和幾個(gè)網(wǎng)頁。
      2.測(cè)試策略
      2.1 基準(zhǔn)測(cè)試:?jiǎn)蝹€(gè)調(diào)用各接口循環(huán)100次計(jì)算平均響應(yīng)時(shí)間
      2.2 性能測(cè)試:?jiǎn)蝹€(gè)接口調(diào)用以50并發(fā)用戶數(shù)為單位,逐步加壓直到預(yù)估的實(shí)際負(fù)載300并發(fā)用戶,觀察測(cè)試指標(biāo)變化
      2.3 壓力測(cè)試:?jiǎn)蝹€(gè)接口調(diào)用以50并發(fā)用戶數(shù)為單位,逐步加壓直到錯(cuò)誤率過高或服務(wù)器資源使用率過高,觀察測(cè)試指標(biāo)變化
      2.4 負(fù)載測(cè)試:預(yù)估實(shí)際負(fù)載為300并發(fā)用戶數(shù),在此基礎(chǔ)上持續(xù)測(cè)試5分鐘左右,觀察測(cè)試指標(biāo)是否達(dá)標(biāo)
      2.5 穩(wěn)定性測(cè)試:預(yù)估實(shí)際負(fù)載為300并發(fā)用戶數(shù),在此基礎(chǔ)上持續(xù)測(cè)試60分鐘左右,觀察測(cè)試指標(biāo)是否達(dá)標(biāo),重點(diǎn)觀察錯(cuò)誤率
      2.6 疲勞性測(cè)試:預(yù)估實(shí)際負(fù)載為300并發(fā)用戶數(shù),在此基礎(chǔ)上持續(xù)測(cè)試240分鐘左右,觀察測(cè)試指標(biāo)是否達(dá)標(biāo),重點(diǎn)觀察錯(cuò)誤率
      2.7 組合測(cè)試:對(duì)2.2-2.5的測(cè)試采用不同接口同時(shí)調(diào)用(即系統(tǒng)不同模塊同時(shí)測(cè)試)
      2.8 其他:以不同ip地址加壓,測(cè)試服務(wù)器負(fù)載均衡效果。
      以上,本次只做了2.2、2.3、2.4、2.8
      3.測(cè)試指標(biāo)
      測(cè)響應(yīng)時(shí)間、錯(cuò)誤率;同時(shí)專人監(jiān)控服務(wù)器硬件資源使用狀況、監(jiān)控tomcat應(yīng)用服務(wù)器等。
      計(jì)算和監(jiān)控吞吐量(測(cè)試工具自動(dòng)計(jì)算測(cè)試執(zhí)行過程中的吞吐量(每秒鐘處理請(qǐng)求數(shù)),同時(shí)服務(wù)器監(jiān)控軟件業(yè)監(jiān)控到了測(cè)試執(zhí)行時(shí)服務(wù)器的吞吐量)
      本次實(shí)際測(cè)試得到吞吐量距離預(yù)估有較大差距;錯(cuò)誤率超出預(yù)期;且測(cè)試數(shù)據(jù)準(zhǔn)備有一定問題。
      4.測(cè)試工具
      本次選用Jmeter,因?yàn)楸阋饲异`活。
      需設(shè)置語言為英文,默認(rèn)中文翻譯不完整。
      5.測(cè)試腳本編寫、調(diào)試
      5.1 提前對(duì)接口、網(wǎng)頁進(jìn)行錄制。每個(gè)待測(cè)接口、網(wǎng)頁需要加斷言。 斷言多采用JQuery斷言和Regular Expression斷言
      5.2 重點(diǎn)在測(cè)試數(shù)據(jù)的準(zhǔn)備。
      5.3 采用了本地web應(yīng)用提供數(shù)據(jù),jmeter獲取這些數(shù)據(jù),再發(fā)送給服務(wù)器的方法(這次發(fā)現(xiàn)這個(gè)本地應(yīng)用生成的數(shù)據(jù)在較高并發(fā)時(shí)有重復(fù),導(dǎo)致了不必要的錯(cuò)誤率)
      5.4 測(cè)試結(jié)果監(jiān)聽器: assertion results, summary report, aggregate report, result tree, result table
      5.5 測(cè)試接口調(diào)用時(shí),可用網(wǎng)頁、數(shù)據(jù)庫(kù)等其他方法確認(rèn)接口調(diào)用成功。觀察接口調(diào)用是否生效,是否和網(wǎng)頁同樣效果。
      6.測(cè)試執(zhí)行
      6.1 一臺(tái)電腦加壓300-600并發(fā)用戶。如果需要更多則需要增加電腦。
      6.2 以不同ip地址加壓,測(cè)試服務(wù)器負(fù)載均衡效果。
      6.3 機(jī)房測(cè)試,排除internet網(wǎng)絡(luò)延遲問題
      6.4 數(shù)據(jù)備份和還原,排除性能測(cè)試對(duì)數(shù)據(jù)的改變
      6.5 生產(chǎn)環(huán)境測(cè)試(系統(tǒng)未上線),排除測(cè)試環(huán)境的影響
      7.測(cè)試報(bào)告
      7.1 截取了jmeter監(jiān)聽器的結(jié)果,可以截取服務(wù)器監(jiān)控的截圖
      8.調(diào)優(yōu)
      本次測(cè)試結(jié)果不理想,服務(wù)器因硬件強(qiáng)大,幾乎無負(fù)載,但應(yīng)用本身有java出錯(cuò)。并發(fā)現(xiàn)接口調(diào)用結(jié)果未正確影響網(wǎng)頁的bug。
      后續(xù)需要等開發(fā)修復(fù)、優(yōu)化之后再次測(cè)試

    posted @ 2014-11-24 09:23 順其自然EVO 閱讀(951) | 評(píng)論 (0)編輯 收藏

    iOS開發(fā)系列-ARC淺解

     一、什么是 ARC ?
      所謂ARC就是Automatic Reference Counting , 即自動(dòng)引用計(jì)數(shù)。ARC是自iOS5引入的。ARC機(jī)制的引入是為了簡(jiǎn)化開發(fā)過程的內(nèi)存管理的。相對(duì)于之前的MRC (Manual Reference Counting) , ARC機(jī)制顯得更加自動(dòng)化。在使用ARC開發(fā)過程中,開發(fā)者只需考慮strong / weak 的使用,不再需要考慮對(duì)象何時(shí)要retain,release/autorealease。使用ARC一般不會(huì)降低程序的效率。
      二、ARC的工作原理
      ARC一個(gè)很重要的原則是:只要某個(gè)對(duì)象被任一strong指針指向,那么它將不會(huì)被銷毀。如果對(duì)象沒有被任何strong指針指向,那么就將被銷毀。
      ARC是基于引用計(jì)數(shù)的,當(dāng)某個(gè)對(duì)象被一個(gè)strong指針指向時(shí),它的計(jì)數(shù)+1。當(dāng)沒有strong指針指向時(shí),其計(jì)數(shù)為0,此時(shí)對(duì)象會(huì)被銷毀。只要一個(gè)對(duì)象有至少一個(gè)strong指針指向時(shí),它就不會(huì)被銷毀。但ARC容易造成一個(gè) Strong Reference Cycle 的問題,這樣即使AddBook 和 Entry 這兩個(gè)對(duì)象都不再使用了,但是由于ARC機(jī)制,這兩個(gè)對(duì)象都互相有strong指針指向,所以這兩個(gè)對(duì)象都不會(huì)被回收,從而造成內(nèi)存無法被釋放。
      針對(duì)上面的情況,有一種解決方法:在其中一個(gè)對(duì)象中引入weak,替換其strong
      引入weak后,當(dāng)entry使用完后,由于指向AddrBook沒有strong指針,所以AddrBook會(huì)首先被釋放,然后由于AddrBook被釋放,指向Entry的Strong指針也會(huì)銷毀,此時(shí)沒有指向Entry的strong指針,所以Entry也會(huì)被釋放。這樣就不會(huì)出現(xiàn)內(nèi)存無法被釋放的情況。
      這里就有一個(gè)問題了,什么時(shí)候應(yīng)該用strong,什么時(shí)候應(yīng)該用weak呢?看以下解析:
      如圖所示,ViewController直接持有View,所以ViewController應(yīng)該要有一個(gè)strong指向view。同理,view直接持有subviews,所以也應(yīng)該要有strong指向subviews。由于viewcontroller要使用subviews對(duì)象,但又不想直接持有subviews,所以只好通過weak指向subviews。這樣的話,可以在viewcontroller中不改變view的持有關(guān)系,就可以使用subviews對(duì)象。從圖中可以得出一個(gè)通用的規(guī)律:對(duì)于有直接持有的關(guān)系,持有者要通過strong指向被持有者。對(duì)于有間接持有關(guān)系的,間接持有者需通過weak指向間接被持有者。

    posted @ 2014-11-21 10:57 順其自然EVO 閱讀(194) | 評(píng)論 (0)編輯 收藏

    Java學(xué)習(xí)之路-RMI學(xué)習(xí)

     Java遠(yuǎn)程方法調(diào)用,即Java RMI(Java Remote Method Invocation)是Java編程語言里,一種用于實(shí)現(xiàn)遠(yuǎn)程過程調(diào)用的應(yīng)用程序編程接口。它使客戶機(jī)上運(yùn)行的程序可以調(diào)用遠(yuǎn)程服務(wù)器上的對(duì)象。遠(yuǎn)程方法調(diào)用特性使Java編程人員能夠在網(wǎng)絡(luò)環(huán)境中分布操作。RMI全部的宗旨就是盡可能簡(jiǎn)化遠(yuǎn)程接口對(duì)象的使用。
      一、創(chuàng)建RMI程序的4個(gè)步驟
      1、定義一個(gè)遠(yuǎn)程接口的接口,該接口中的每一個(gè)方法必須聲明它將產(chǎn)生一個(gè)RemoteException異常。
      2、定義一個(gè)實(shí)現(xiàn)該接口的類。
      3、創(chuàng)建一個(gè)服務(wù),用于發(fā)布2中定義的類。
      4、創(chuàng)建一個(gè)客戶程序進(jìn)行RMI調(diào)用。
      二、程序的詳細(xì)實(shí)現(xiàn)
      1.首先我們先創(chuàng)建一個(gè)實(shí)體類,這個(gè)類需要實(shí)現(xiàn)Serializable接口,用于信息的傳輸。
    1 import java.io.Serializable;
    3 public class Student implements Serializable {
    5   private String name;
    7   private int age;
    9   public String getName() {
    11       return name;
    13   }
    15   public void setName(String name) {
    17       this.name = name;
    19   }
    21   public int getAge() {
    23       return age;
    25   }
    27   public void setAge(int age) {
    29       this.age = age;
    31   }
    33 }
      2.定義一個(gè)接口,這個(gè)接口需要繼承Remote接口,這個(gè)接口中的方法必須聲明RemoteException異常。
      1 import java.rmi.Remote;
      3 import java.rmi.RemoteException;
      5 import java.util.List;
      6 public interface StudentService extends Remote {
      12   List<Student> getList() throws RemoteException;
      14 }
      3.創(chuàng)建一個(gè)類,并實(shí)現(xiàn)步驟2中的接口,但還需要繼承UnicastRemoteObject類和顯示寫出無參的構(gòu)造函數(shù)。
    1 import java.rmi.RemoteException;
    3 import java.rmi.server.UnicastRemoteObject;
    5 import java.util.ArrayList;
    7 import java.util.List;
    11 public class StudentServiceImpl extends UnicastRemoteObject implements
    13       StudentService {
    15   public StudentServiceImpl() throws RemoteException {
    17   }
    21   public List<Student> getList() throws RemoteException {
    23       List<Student> list=new ArrayList<Student>();
    25       Student s1=new Student();
    27       s1.setName("張三");
    29       s1.setAge(15);
    31       Student s2=new Student();
    33       s2.setName("李四");
    35       s2.setAge(20);
    37       list.add(s1);
    39       list.add(s2);
    41       return list;
    43   }
    45 }
     4.創(chuàng)建服務(wù)并啟動(dòng)服務(wù)
    1 import java.rmi.Naming;
    2 import java.rmi.registry.LocateRegistry;
    4 public class SetService {
    6     public static void main(String[] args) {
    8         try {
    10             StudentService studentService=new StudentServiceImpl();
    12             LocateRegistry.createRegistry(5008);//定義端口號(hào)
    14             Naming.rebind("rmi://127.0.0.1:5008/StudentService", studentService);
    16             System.out.println("服務(wù)已啟動(dòng)");
    18         } catch (Exception e) {
    20             e.printStackTrace();
    22         }
    24     }
    26 }
      5. 創(chuàng)建一個(gè)客戶程序進(jìn)行RMI調(diào)用。
    1 import java.rmi.Naming;
    3 import java.util.List;
    5 public class GetService {
    9   public static void main(String[] args) {
    11       try {
    13           StudentService studentService=(StudentService) Naming.lookup("rmi://127.0.0.1:5008/StudentService");
    15           List<Student> list = studentService.getList();
    17           for (Student s : list) {
    19               System.out.println("姓名:"+s.getName()+",年齡:"+s.getAge());
    21           }
    23       } catch (Exception e) {
    25           e.printStackTrace();
    27       }
    29   }
    33 }
      6.控制臺(tái)顯示結(jié)果
      =============控制臺(tái)============
      姓名:張三,年齡:15
      姓名:李四,年齡:20
      ===============================
      在Spring中配置Rmi服務(wù)
      將Rmi和Spring結(jié)合起來用的話,比上面實(shí)現(xiàn)Rmi服務(wù)要方便的多。
      1.首先我們定義接口,此時(shí)定義的接口不需要繼承其他接口,只是一個(gè)普通的接口
      1 package service;
      3 import java.util.List;
      5 public interface StudentService {
      7      List<Student> getList();
      9 }
      2.定義一個(gè)類,實(shí)現(xiàn)這個(gè)接口,這個(gè)類也只需實(shí)現(xiàn)步驟一定義的接口,不需要額外的操作
    1 package service;
    4 import java.util.ArrayList;
    6 import java.util.List;
    9 public class StudentServiceImpl implements StudentService {
    11  public List<Student> getList() {
    13   List<Student> list=new ArrayList<Student>();
    15   Student s1=new Student();
    17   s1.setName("張三");
    19   s1.setAge(15);
    21   Student s2=new Student();
    23   s2.setName("李四");
    25   s2.setAge(20);
    27   list.add(s1);
    29   list.add(s2);
    31   return list;
    33  }
    35 }
     3.接一下來在applicationContext.xml配置需要的信息
      a.首先定義服務(wù)bean
      <bean id="studentService" class="service.StudentServiceImpl"></bean>
      b.定義導(dǎo)出服務(wù)
      <bean class="org.springframework.remoting.rmi.RmiServiceExporter"
      p:service-ref="studentService"
      p:serviceInterface="service.StudentService"
      p:serviceName="StudentService"
      p:registryPort="5008"
      />
      也可以增加p:registryHost屬性設(shè)置主機(jī)
      c.在客戶端的applicationContext.xml中定義得到服務(wù)的bean(這里的例子是把導(dǎo)出服務(wù)bean和客戶端的bean放在一個(gè)applicationContext.xml中的)
      <bean id="getStudentService"
      class="org.springframework.remoting.rmi.RmiProxyFactoryBean"
      p:serviceUrl="rmi://127.0.0.1:5008/StudentService"
      p:serviceInterface="service.StudentService"
      />
      d.配置的東西就這么多,是不是比上面的現(xiàn)實(shí)要方便的多呀!現(xiàn)在我們來測(cè)試一下
    1 package service;
    2 import java.util.List;
    3 import org.springframework.context.ApplicationContext;
    4 import org.springframework.context.support.ClassPathXmlApplicationContext;
    5 public class Test {
    6 public static void main(String[] args) {
    7   ApplicationContext ctx=new ClassPathXmlApplicationContext("applicationContext.xml");
    8   StudentService studentService=(StudentService) ctx.getBean("getStudentService");
    9   List<Student> list = studentService.getList();
    10   for (Student s : list) {
    11    System.out.println("姓名:"+s.getName()+",年齡:"+s.getAge());
    12   }
    13  }
    14 }
      =============控制臺(tái)============
      姓名:張三,年齡:15
      姓名:李四,年齡:20
      =============================
      上面的mian方法運(yùn)行可能會(huì)報(bào)錯(cuò),應(yīng)該是spring的jar少了,自己注意添加。

    posted @ 2014-11-21 10:56 順其自然EVO 閱讀(255) | 評(píng)論 (0)編輯 收藏

    提高代碼質(zhì)量系列之一—盡可能少寫注釋

    關(guān)于<<提高代碼質(zhì)量系列>>
      這是我新開的一個(gè)系列,旨在記錄我對(duì)整個(gè)編碼規(guī)范,代碼風(fēng)格,語法習(xí)慣,架構(gòu)設(shè)計(jì)的一些思考,感悟和總結(jié).
      前言
      不知道大家會(huì)不會(huì)覺得我的標(biāo)題很噱頭,不是一般應(yīng)該提倡寫注釋的么?首先我得解釋下,我這句話有兩個(gè)意思!
      1,絕非提倡不寫注釋,而是不要寫不必要的注釋.
      2,命名規(guī)范的作用大于注釋
      好吧,這么一說,其實(shí)還是有點(diǎn)噱頭的感覺的,因?yàn)槲疫@篇文其實(shí)重心更放在強(qiáng)調(diào)命名規(guī)范和設(shè)計(jì)規(guī)范上面,良好的規(guī)范,讓你的代碼有自釋性,省去了注釋的步驟.
      還要強(qiáng)調(diào)下的是:這個(gè)觀點(diǎn)絕非我自己主觀臆斷,憑空瞎想出來的. 而是實(shí)實(shí)在在由項(xiàng)目開發(fā)里面總結(jié)出來的.
      為什么我有這個(gè)想法呢?請(qǐng)繼續(xù)看我的蛋疼經(jīng)歷.
      正文
      先上段奇葩代碼
    /// <summary>
    ///     根據(jù)產(chǎn)品ID獲取產(chǎn)品列表
    /// </summary>
    /// <param name="columnID">關(guān)鍵字</param>
    public DataTable GetColumnInfoByColumnID(int columnID)
    {
    return DALColumn.GetColumnInfoByColumnID(columnID);
    }
    /// <summary>
    ///     根據(jù)產(chǎn)品名稱獲取產(chǎn)品列表
    /// </summary>
    /// <param name="columnID">關(guān)鍵字</param>
    public DataTable GetColumnInfoByColumnID(string columnName)
    {
    return DALColumn.GetColumnInfoByColumnID(columnName);
    }
      這是我現(xiàn)在維護(hù)的一個(gè)老項(xiàng)目了,經(jīng)手的人比較多,代碼寫的比較垃圾,我們先不吐槽這種純粹是脫褲子放屁的所謂三層和明明返回的是dataTable又扯什么info,就說這兩個(gè)函數(shù),tm功能應(yīng)該是不一樣的吧,為啥名字一模一樣?這是在鬧哪樣?
      其實(shí),造成這種情況的原因,我們都知道,就是某類程序員的ctrl c+v大法,這兩個(gè)函數(shù)底層邏輯比較相似,懶得重構(gòu),直接copy了改改多快!copy就copy吧,好歹名字改一下啊!也許這位前輩會(huì)說,我不是寫了注釋了嗎,看到注釋,不就知道這個(gè)函數(shù)是干嘛的了?但問題是,其他調(diào)用的人,首先看到的,肯定是函數(shù)名啊,GetColumnInfoByColumnID,多直觀 通過id來查找唄.雖然這里有兩個(gè)比較違和的地方,一是參數(shù)默認(rèn)名字是columnName,二是參數(shù)類型不是int而是string,但反正這項(xiàng)目的代碼不規(guī)范,如果調(diào)用的人也夠粗心,那么,一個(gè)隱晦的bug,就這么產(chǎn)生了.
      如果改下名字,叫 GetTableByColumnName,這種錯(cuò)誤發(fā)生的概率無疑會(huì)減少很多了,
      Ps:其實(shí)現(xiàn)在ide功能這么強(qiáng)大,只要你確定沒有反射調(diào)用這個(gè)函數(shù)的地方,完全可以使用全局重命名的方法,一步到位.
      看到這里讀者朋友們可能會(huì)說,這是命名不規(guī)范嘛,和寫不寫注釋有什么關(guān)系呢?
      我們可以假想一種這樣的情況,同樣是拷貝代碼,拷貝者改了函數(shù)名,這個(gè)名字語義清晰,表意清楚, 但他卻忘記改注釋了,結(jié)果函數(shù)是新的函數(shù)簽名,函數(shù)的注釋卻是其他一段莫名其妙的注釋.
      或者再假想一種情況.
      原來的一個(gè)函數(shù),名字和注釋是對(duì)應(yīng)的,隨便舉個(gè)例子,叫GetTypeByColumnId吧,注釋為"通過產(chǎn)品id取得產(chǎn)品類型"
      一切ok,是吧! 但是現(xiàn)在邏輯變了,比如說Type和產(chǎn)品無關(guān)了,需要通過生產(chǎn)批次來確定,于是一個(gè)代碼維護(hù)者,將函數(shù)重寫了一下功能ok,滿足新需求!!同時(shí)他比上個(gè)人好一點(diǎn),他記得改函數(shù)名,然后他改為了GetTypeBySerialId,這名字也很ok,一切也都看起來很好.但偏偏他漏掉了注釋,但代碼仍然運(yùn)行的很ok,畢竟注釋可不受.net的元數(shù)據(jù)的支持,ide也不可能知道你這里犯了這么一個(gè)錯(cuò)誤是吧!
      然后,接下來的場(chǎng)景大家很容易就可以聯(lián)想到,
      如果是細(xì)心的調(diào)用者:
      尼瑪!函數(shù)注釋讓我傳"產(chǎn)品id",但函數(shù)名和參數(shù)默認(rèn)名字又是"SerialId"(流水號(hào)),這尼瑪鬧哪樣?
      如果是粗心的調(diào)用者呢?兩種情況唄:
      1.看了函數(shù)名字和默認(rèn)參數(shù)名字 ,沒注意到注釋,ok,算這個(gè)粗心的小伙伴幸運(yùn),
      2.看了注釋,然后這小伙伴不認(rèn)識(shí)SerialId這個(gè)單詞的意思. 然后,一個(gè)悲傷的故事就這么發(fā)生了!!
      其實(shí)我以上舉例的一些函數(shù),都是功能比較具體,業(yè)務(wù)比較單純,也容易用幾個(gè)單詞描述.對(duì)于這些函數(shù),我個(gè)人的意見是,完全不需要去寫注釋,
    有以下幾個(gè)原因:
      1.浪費(fèi)精力去寫,
      2.調(diào)用的人需要把一段話讀兩遍(函數(shù)名和注釋)
      3.寫了還需要人去維護(hù),(改了代碼,得同步去改注釋)
      4.如果強(qiáng)類型的參數(shù)傳遞不匹配,ide或者resharper插件會(huì)馬上指出你的錯(cuò)誤,但如果注釋和代碼不匹配,則除了通過人力CodeReview,沒有其他任何辦法去找出這種錯(cuò)誤.
      其中尤其是4,完全就是埋在項(xiàng)目中的地雷,除非你踩到了,不然很難排查.
      當(dāng)然,如果是反之,邏輯復(fù)雜,甚至有調(diào)用的前置約束,那肯定該寫注釋還是得寫了.
      同時(shí),這里還提一個(gè)觀點(diǎn),注釋比代碼更有價(jià)值,因?yàn)榇a畢竟大部分還是在講怎么做(how do),而注釋是講做什么(do what)?抽象程度更高,對(duì)于比較復(fù)雜的代碼,如果有注釋,調(diào)用者一般都會(huì)優(yōu)先去閱讀注釋,而不是去閱讀代碼,所以:輕易不寫注釋,但如果你寫了,請(qǐng)一定要對(duì)你的注釋負(fù)責(zé),它比代碼更需要你的細(xì)心呵護(hù)!!
      好吧,我會(huì)說這篇文最大的作用,其實(shí)是可以讓我吐槽發(fā)泄一下么?
      我感覺自己現(xiàn)在就是在這種地雷坑里,天天過著提醒吊膽的日子.
      以上例子皆非我刻意編造,來源于工作中的真實(shí)經(jīng)歷,只是稍作修飾,隱去了和業(yè)務(wù)有關(guān)的信息.
      根據(jù)回復(fù)的補(bǔ)充:
      相信很多博友有這樣的經(jīng)歷,這個(gè)函數(shù)好復(fù)雜呀!我必須寫注釋啊,不然一段時(shí)間之后,我自己都看不明白了,
      有些時(shí)候是確實(shí)很復(fù)雜,但也有時(shí)候是設(shè)計(jì)的問題,這時(shí)候,寫注釋其實(shí)是一種逃避了.逃避你需要繼續(xù)深入思考這個(gè)函數(shù)的業(yè)務(wù)和功能的設(shè)計(jì)是否合理.
      其實(shí)我這標(biāo)題還有第三個(gè)意思:
      在盡可能少寫注釋的前提下,如果一個(gè)函數(shù)的注釋仍然超過了2處,那么我認(rèn)為這個(gè)函數(shù)的設(shè)計(jì)是有問題的.
      這個(gè)函數(shù)是否太大,是否是反模式里面提到的萬應(yīng)靈或屠龍術(shù)?
      所以有時(shí)候說的 "因?yàn)闃I(yè)務(wù)復(fù)雜,很難用幾個(gè)單詞去描述,所以很難命名",就是如此.
      你的業(yè)務(wù)抽象粒度是否太大?導(dǎo)致一個(gè)業(yè)務(wù)模塊承擔(dān)了過多的業(yè)務(wù).
      你是否把幾個(gè)流程放在了一個(gè)節(jié)點(diǎn)上?導(dǎo)致引入了額外的邏輯判斷甚至是多余的邏輯分支.
      如果是這樣,你想用幾個(gè)單詞來描述這么復(fù)雜的邏輯,當(dāng)然是不可能了.
      這點(diǎn)我會(huì)在后續(xù)的重構(gòu)系列里面談?wù)勎易约旱睦斫?
      補(bǔ)充下自己的理解.
      我始終認(rèn)為好的設(shè)計(jì),大部分情況下,函數(shù)名就足以解釋它的功能,如果你遇到了兩三個(gè)單詞不能解釋函數(shù)功能的情況----說明你該分解函數(shù)了!
      比如一個(gè)大函數(shù),OutPutMetaData,輸入是源數(shù)據(jù)路徑,使用的模板 返回解析之后的元數(shù)據(jù)
      流程大概是 采集數(shù)據(jù)->分析數(shù)據(jù)->匹配模板->生成MetaData
      代碼是大約1-2k行,如果寫在一個(gè)函數(shù)里面,當(dāng)然也似可以的,但你想用注釋解釋清楚,必須在每個(gè)流程的關(guān)鍵節(jié)點(diǎn)寫注釋,遇到數(shù)據(jù)有前后關(guān)聯(lián)關(guān)系的,還得思維反復(fù)跳來跳去.
      但如果寫成下面這種模式的代碼,基本就像是閱讀英文說明(注釋),一樣閱讀代碼了
    public MetaData OutPutMetaData(string sourcePath, MetaTemplate template)
    {
    var metaDataFactory = new MetaDataFactory();
    if (!metaDataFactory.CheckInput(sourcePath))
    {
    throw new ErrorSourceException();
    }
    if (!metaDataFactory.TransformSourceData(template))
    {
    throw new ErrorFormatException();
    }
    return metaDataFactory.CreateMetaData();
    }
      這樣寫雖然多了很多的類和方法,還要額外定義一些中間數(shù)據(jù)的實(shí)體類型和自定義異常,但是經(jīng)過合理的封裝和命名之后,整個(gè)結(jié)構(gòu)非常清晰,定位錯(cuò)誤和修改流程也方便.
      代碼閱讀速度基本和描述語句(注釋)的閱讀速度相當(dāng), 這就是代碼即注釋.
      最后總結(jié):
      其實(shí)我認(rèn)為最關(guān)鍵是要形成自己的編碼規(guī)范,這個(gè)"規(guī)范"不僅僅指的是狹義的命名規(guī)則和代碼格式,縮進(jìn),文件組織結(jié)構(gòu)等.更關(guān)鍵的是,要形成一套有邏輯性,能自洽,有良性導(dǎo)向的一套思維模式,并時(shí)刻堅(jiān)持遵守它,思考它,改進(jìn)它.
      這套思維模式你可以自由的去擴(kuò)展,只要不偏離它的中心思想.比如我給自己擴(kuò)展的一些要求:
      1.函數(shù)一律使用動(dòng)賓結(jié)構(gòu),如InitFactory,而不用FactoryInit,其實(shí)這兩者沒什么優(yōu)劣,僅僅只是讓自己習(xí)慣,以后思考和閱讀自己代碼的時(shí)候,能更快的帶入過去的自己的思維,更快的理解自己的代碼,同時(shí)找api也能節(jié)約一點(diǎn)時(shí)間.
      2.html標(biāo)簽樣式id小寫開頭,class大寫開頭,同理,其實(shí)也沒啥原因,就是個(gè)習(xí)慣.
      3.描述一個(gè)事物的時(shí)候要區(qū)分是what it is(名詞,形容詞)還是what it can do(動(dòng)詞,動(dòng)名詞,動(dòng)賓短語)比如doClose, 是某個(gè)事物的動(dòng)作,closing,和 closed則代表它的狀態(tài)
      再就是結(jié)構(gòu)設(shè)計(jì)上的一些感覺了,這個(gè)比較抽象,不好用文字很準(zhǔn)確的描述,大致意思就是我會(huì)從一些緯度對(duì)功能進(jìn)行切分,access business viewModel show interaction 等,不一定都能分的非常清楚,也不強(qiáng)求一個(gè)區(qū)分度很高的邊際,但至少要有個(gè)模糊的定位.
      如果能長(zhǎng)期堅(jiān)持下來,以后閱讀自己的代碼是非常容易的,即使是沒有(少量)注釋.
      Ps:錘煉自己的這套思維模式的方法也很簡(jiǎn)單,也就三點(diǎn)
      多看優(yōu)秀代碼,自己動(dòng)手多寫,多思考總結(jié).

    posted @ 2014-11-21 10:55 順其自然EVO 閱讀(258) | 評(píng)論 (0)編輯 收藏

    Linux網(wǎng)站壓力測(cè)試工具webbench

      一、Webbench簡(jiǎn)單介紹
      在一個(gè)網(wǎng)站上線前, 通常我們應(yīng)該做一些相關(guān)的壓力測(cè)試, 以便了解當(dāng)前Web服務(wù)器在高并發(fā)高負(fù)載情況下的響應(yīng)狀況和速度,方便對(duì)Web服務(wù)器進(jìn)行優(yōu)化和重構(gòu)。目前有很多免費(fèi)的web壓力測(cè)試工具可以幫助我們完成測(cè)試, 例如: 十個(gè)免費(fèi)的Web壓力測(cè)試工具h(yuǎn)ttp://coolshell.cn/articles/2589.html,但在真實(shí)項(xiàng)目中使用Apache ab和Webbench來完成壓力測(cè)試。Apache的優(yōu)點(diǎn):Apache的ab使用非常簡(jiǎn)單, 而且只要是安裝了Apache了,就會(huì)自帶其ab工具,缺點(diǎn):就是不能模擬高并發(fā)狀態(tài)下的測(cè)試, 好像最多可以模擬100-200次/秒的并發(fā). 如果需要模擬更高負(fù)載的壓力測(cè)試, 就需要使用Webbench。
      Webbench是有名的網(wǎng)站壓力測(cè)試工具,它是由 Lionbridge公司(http://www.lionbridge.com)開發(fā)。Webbech能測(cè)試處在相同硬件上,不同服務(wù)的性能以及不同硬件上同一個(gè)服務(wù)的運(yùn)行狀況。webBech的標(biāo)準(zhǔn)測(cè)試可以向我們展示服務(wù)器的兩項(xiàng) 內(nèi)容:每秒鐘相應(yīng)請(qǐng)求數(shù)和每秒鐘傳輸數(shù)據(jù)量。webbench不但能具有便準(zhǔn)靜態(tài)頁面的測(cè)試能力,還能對(duì)動(dòng)態(tài)頁面(ASP,PHP,JAVA,CGI)進(jìn)行測(cè)試的能力。還有就是他支持對(duì)含有SSL的安全網(wǎng)站例如電子商務(wù)網(wǎng)站進(jìn)行靜態(tài)或動(dòng)態(tài)的性能測(cè)試,webbench最多可以模擬3萬個(gè)并發(fā)連接去測(cè)試網(wǎng)站的負(fù)載能力。缺點(diǎn)測(cè)試的結(jié)果太簡(jiǎn)單了。
      二、安裝Webbench
      注意點(diǎn):為了測(cè)試準(zhǔn)確,請(qǐng)將 webbench 安裝在別的linux服務(wù)器上,(因?yàn)閣ebbench 做壓力測(cè)試時(shí),自身也會(huì)消耗CPU和內(nèi)存資源, 否則很可能把自己服務(wù)器搞掛掉)
      目前Webbench最新的版本為webbench-1.5.tar.gz下載地址 http://home.tiscali.cz/~cz210552/distfiles/webbench-1.5.tar.gz
      1.先安裝依賴包:yum install ctags
      2.安裝Webbench:
      tar zxvfwebbench-1.5.tar.gz
      cd webbench-1.5
      make &&make install
      如果出現(xiàn)以下報(bào)錯(cuò)信息:
    ctags *.c
    /bin/sh: ctags: command not found
    make: [tags] Error 127 (ignored)
    install -s webbench /usr/local/bin
    install -m 644 webbench.1 /usr/local/man/man1
    install: cannot create regular file `/usr/local/man/man1': No such file ordirectory
    make: *** [install] Error 1
      解決方法:
      mkdir -p /usr/local/man
      chmod 644 /usr/local/man
      再次執(zhí)行make && make install
      看到如下界面,說明安裝成功
    make: Nothing to be done for `all'.
    install -s webbench /usr/local/bin
    install -m 644 webbench.1/usr/local/man/man1
    install -d /usr/local/share/doc/webbench
    install -m 644 debian/copyright/usr/local/share/doc/webbench
    install -m 644 debian/changelog/usr/local/share/doc/webbench
      三、使用
    [root@centos ~]# webbench -c 400 -t 20 http://10.43.2.192/
    Webbench - Simple Web Benchmark 1.5
    Copyright (c) Radim Kolar 1997-2004, GPL Open Source Software.
    Benchmarking: GET http://10.43.2.192/
    400 clients, running 20 sec.
    Speed=392676 pages/min, 1603427 bytes/sec.
    Requests: 130892 susceed, 0 failed.
      參數(shù)說明:-c表示并發(fā)數(shù),-t表示時(shí)間(秒)
      每秒鐘傳輸數(shù)據(jù)量:1603427 bytes/sec每秒鐘相應(yīng)請(qǐng)求數(shù):392676/60= 6544 pages/sec
      這里有一個(gè)特別要注意的點(diǎn):10.43.2.192/后面的“/”一定不要忘記

    posted @ 2014-11-21 10:54 順其自然EVO 閱讀(327) | 評(píng)論 (0)編輯 收藏

    利用Selenium自動(dòng)化WEB測(cè)試

         摘要: 簡(jiǎn)介  Selenium 是一個(gè)健壯的工具集合,跨很多平臺(tái)支持針對(duì)基于 web 的應(yīng)用程序的測(cè)試自動(dòng)化的敏捷開發(fā)。它是一個(gè)開源的、輕量級(jí)的自動(dòng)化工具,很容易集成到各種項(xiàng)目中,支持多種編程語言,比如 .NET、Perl、Python、Ruby 和 Java? 編程語言。  利用 Selenium 測(cè)試 Ajax 應(yīng)用程序  Asynchronous JavaS...  閱讀全文

    posted @ 2014-11-21 10:52 順其自然EVO 閱讀(1280) | 評(píng)論 (0)編輯 收藏

    僅列出標(biāo)題
    共394頁: First 上一頁 12 13 14 15 16 17 18 19 20 下一頁 Last 
    <2025年5月>
    27282930123
    45678910
    11121314151617
    18192021222324
    25262728293031
    1234567

    導(dǎo)航

    統(tǒng)計(jì)

    常用鏈接

    留言簿(55)

    隨筆分類

    隨筆檔案

    文章分類

    文章檔案

    搜索

    最新評(píng)論

    閱讀排行榜

    評(píng)論排行榜

    主站蜘蛛池模板: 亚洲精品V天堂中文字幕| 日韩中文无码有码免费视频| 综合亚洲伊人午夜网 | 99久久人妻精品免费二区| 久久亚洲国产伦理| 免费国产叼嘿视频大全网站| 伊人亚洲综合青草青草久热| 一级做a免费视频观看网站| 亚洲视频在线一区二区| 一级做a爰性色毛片免费| 亚洲线精品一区二区三区| GOGOGO免费观看国语| 久久精品国产亚洲香蕉| 久久一区二区三区免费播放| 亚洲网站在线观看| 青苹果乐园免费高清在线| 亚洲av日韩av永久在线观看| 亚洲AV无码乱码在线观看| 中文字幕视频免费在线观看| 亚洲国产精品成人精品无码区| 无码免费一区二区三区免费播放| 亚洲精品韩国美女在线| 成年性生交大片免费看| 西西人体大胆免费视频| 亚洲精品你懂的在线观看| 久久精品毛片免费观看| 亚洲国产精品日韩av不卡在线 | 曰批全过程免费视频免费看| 亚洲色偷拍区另类无码专区| 青青青国产手机频在线免费观看| 亚洲小说图片视频| 四虎国产精品免费久久影院| 国产自国产自愉自愉免费24区| 亚洲第一二三四区| 亚洲成人高清在线| 亚洲黄色免费观看| 成人福利在线观看免费视频| 久久精品亚洲一区二区三区浴池| 午夜毛片不卡高清免费| 国产做国产爱免费视频| 精品丝袜国产自在线拍亚洲|