qileilove

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

          性能調(diào)優(yōu)之我見(jiàn)

          談到軟件產(chǎn)品的性能調(diào)優(yōu),我認(rèn)為可以從狹義和廣義兩個(gè)范圍來(lái)理解。從狹義的范疇來(lái)看,性能調(diào)優(yōu)主要是指通過(guò)修改軟件程序邏輯、結(jié)構(gòu)等技術(shù)手段提升軟件產(chǎn)品的各項(xiàng)性能指標(biāo),如響應(yīng)時(shí)間等等;而從廣義的層面來(lái)看,就不僅限于程序內(nèi)部了,因?yàn)樵斐上到y(tǒng)性能問(wèn)題的瓶頸很可能來(lái)源于方方面面,而這種情況往往是性能調(diào)優(yōu)很普遍的情況,下面就從廣義的范圍細(xì)分成幾個(gè)角度來(lái)進(jìn)行闡述。

            一、軟件層面

            a)首先要談到的肯定是我們自己提供的軟件產(chǎn)品,因?yàn)樗膬?nèi)部設(shè)計(jì)是我們最清楚的,用戶在應(yīng)用時(shí)遇到性能問(wèn)題首先要質(zhì)疑的也是我們的產(chǎn)品,因此這個(gè)層面的調(diào)優(yōu)肯定是我們軟件供應(yīng)者的重中之重!舉例來(lái)說(shuō):比較復(fù)雜的業(yè)務(wù),通常會(huì)在程序中輸出一些關(guān)鍵操作的執(zhí)行時(shí)間,然后再分析哪些操作比較耗時(shí),之后再找原因。具體分析原因就比較多了,比如多次循環(huán)查詢數(shù)據(jù)庫(kù),復(fù)雜耗時(shí)的SQL語(yǔ)句,頻繁的遠(yuǎn)程調(diào)用,復(fù)雜算法,等等。

            b)數(shù)據(jù)庫(kù)層面:設(shè)計(jì)數(shù)據(jù)庫(kù)時(shí)應(yīng)考慮到在少訪問(wèn)和簡(jiǎn)化、優(yōu)化訪問(wèn)的前提下實(shí)現(xiàn)產(chǎn)品功能,多用存儲(chǔ)過(guò)程代替完整SQL,盡量用連接池使用戶和服務(wù)的連接實(shí)現(xiàn)可復(fù)用,盡量不使用游標(biāo)結(jié)構(gòu)等,對(duì)基本表的設(shè)計(jì)進(jìn)行優(yōu)化如第三范式、引入“中間表”的技術(shù)思路,控制用戶實(shí)際數(shù)據(jù)量的增長(zhǎng);對(duì)數(shù)據(jù)庫(kù)進(jìn)行索引優(yōu)化,避免整表掃描;對(duì)數(shù)據(jù)庫(kù)的事務(wù)處理進(jìn)行調(diào)優(yōu)(去除不必要的鎖、將事務(wù)切分成小的粒度、適當(dāng)降低隔離級(jí)別、減少訪問(wèn)熱點(diǎn)等);SQL語(yǔ)句調(diào)優(yōu)(盡量?jī)?yōu)化那些無(wú)意義的、拙劣的、復(fù)雜的SQL)等等。這方面主要就是本著一個(gè)通過(guò)盡可能少的磁盤(pán)訪問(wèn)而獲得所需要的數(shù)據(jù)這么一個(gè)基本原則。

            c)中間件軟件:某些軟件產(chǎn)品為數(shù)據(jù)庫(kù)、中間件、客戶端的三層架構(gòu)設(shè)計(jì),此時(shí)為系統(tǒng)運(yùn)行提供服務(wù)的中間件軟件也將成為制約性能的一個(gè)瓶頸。因此在這個(gè)層面上也是有很大調(diào)優(yōu)空間的,比如各種相關(guān)參數(shù)的設(shè)置優(yōu)化,使用性能包、性能監(jiān)控分析工具等,避免競(jìng)爭(zhēng)線程資源,批處理,堆大小的設(shè)置,為溢出條件設(shè)置執(zhí)行隊(duì)列,后備緩沖,減少非重要應(yīng)用的資源占用,使用集群等。舉個(gè)簡(jiǎn)單的實(shí)例,我曾經(jīng)遇到一個(gè)產(chǎn)品的性能問(wèn)題,當(dāng)查詢數(shù)據(jù)大到一定程度時(shí),系統(tǒng)一直灰屏死機(jī)狀態(tài),結(jié)果只是通過(guò)把JVM內(nèi)存參數(shù)設(shè)置從默認(rèn)值的128調(diào)為256就輕松解決了,只是參數(shù)值的一個(gè)小變動(dòng),反映到具體的用戶面前就是出的來(lái)和出不來(lái)數(shù)據(jù)的本質(zhì)差別!

            d)操作系統(tǒng):無(wú)論是服務(wù)器還是用戶終端,都脫離不了操作系統(tǒng)這個(gè)基礎(chǔ)的應(yīng)用平臺(tái)的支持,因此這個(gè)層面的性能調(diào)優(yōu)工作也千萬(wàn)不能遺漏。例如同廠商的不同版本(如WINDOWS各系列)、不同廠商(MS/HP/SUN等)不同的操作系統(tǒng)(WINDOWS/LINUX/UNIX等),這些操作系統(tǒng)的性能表現(xiàn)本身就有所差異,如內(nèi)存的分配、虛擬內(nèi)存的處理、數(shù)據(jù)的讀寫(xiě)交換、兼容穩(wěn)定抗壓性等等方面,利用相應(yīng)的調(diào)優(yōu)方法和工具,可以對(duì)此環(huán)節(jié)進(jìn)行優(yōu)化。

            二、硬件層面

            a)CPU:中央處理器,決定數(shù)據(jù)處理速度的核心部件,與性能表現(xiàn)的相關(guān)度可想而知,硬件方面具體調(diào)優(yōu)方法及工具本文中不再贅述,下同!

            b)內(nèi)存、緩存:數(shù)據(jù)交換的臨時(shí)存儲(chǔ)空間,它的大小形象的說(shuō)就像是火車(chē)站候車(chē)室的面積,與性能的關(guān)系可想而知。比如有些程序設(shè)計(jì)的操作對(duì)內(nèi)存回收設(shè)計(jì)有漏洞,導(dǎo)致頻繁操作時(shí)內(nèi)存泄漏越來(lái)越多,系統(tǒng)就會(huì)越來(lái)越慢。

            c)硬盤(pán)、I/O:數(shù)據(jù)存儲(chǔ)、調(diào)用的載體,如果存儲(chǔ)器像候車(chē)室,那這些就像是車(chē)箱的大小與節(jié)數(shù)等。

            d)網(wǎng)絡(luò):如果還是用坐火車(chē)為例,網(wǎng)絡(luò)的差別就像是普通、快速、動(dòng)車(chē)、磁浮等各種等級(jí)的差別,如果一個(gè)“系統(tǒng)”頻繁需要通過(guò)火運(yùn)完成,那它的性能表現(xiàn)和網(wǎng)絡(luò)的相關(guān)性就不言而喻了。比如某些軟件功能設(shè)計(jì)時(shí)沒(méi)有考慮網(wǎng)絡(luò)流量方面的風(fēng)險(xiǎn),導(dǎo)致每次操作時(shí)網(wǎng)絡(luò)連接次數(shù)很多,頻繁調(diào)用或是數(shù)據(jù)包過(guò)大,這些都會(huì)導(dǎo)致在一定網(wǎng)絡(luò)條件下產(chǎn)生性能問(wèn)題。

            e)顯卡等特殊硬件:不同軟件產(chǎn)品應(yīng)用的業(yè)務(wù)可能用到不同的專(zhuān)用硬件或外設(shè),比如一個(gè)很炫的游戲?qū)︼@卡的要求就會(huì)很高,當(dāng)顯示成為短板時(shí)死機(jī)、跳幀等異常;一個(gè)收款臺(tái)的掃描、信用卡POS機(jī)如果質(zhì)量或兼容性、穩(wěn)定性不佳時(shí),也可能會(huì)造成性能表現(xiàn)的不理想,等待諸如此類(lèi)問(wèn)題。

            三、業(yè)務(wù)層面

            a)業(yè)務(wù)流程重組:項(xiàng)目甲方在購(gòu)買(mǎi)軟件產(chǎn)品或系統(tǒng)服務(wù)前,一般會(huì)找相關(guān)專(zhuān)家、售前人員作一些相關(guān)的評(píng)估或“體檢”,找出現(xiàn)有運(yùn)作模式下的一些存在優(yōu)化空間的錯(cuò)誤環(huán)節(jié)或繁冗流程、制度體系等。因此在這個(gè)階段是否對(duì)項(xiàng)目應(yīng)用方作了足夠的優(yōu)化,也對(duì)未來(lái)產(chǎn)品上線后的應(yīng)用性能表現(xiàn)在宏觀上起著決定作用。取例來(lái)說(shuō):如果一個(gè)系統(tǒng)設(shè)計(jì)前沒(méi)有作過(guò)這方面的優(yōu)化,最后應(yīng)用時(shí)需要100人操作10個(gè)步驟才能完成,通過(guò)流程重組后,從業(yè)務(wù)上只需要40個(gè)人干5個(gè)步驟就搞定了,那么沒(méi)上軟件前我們就能從理論上把性能表現(xiàn)優(yōu)化80%!

            b)需求定位:與上一條闡述的類(lèi)似,只是介入的階段和角色有所區(qū)別。需求人員有時(shí)是從項(xiàng)目乙方發(fā)起的,主動(dòng)地、有策略性的去選擇一些有代表性的單位去調(diào)研軟件產(chǎn)品的概要或詳細(xì)需求,為后續(xù)的產(chǎn)品開(kāi)發(fā)設(shè)計(jì)提供依據(jù)。在這一階段是否有效的考慮了未來(lái)產(chǎn)品的性能表現(xiàn),對(duì)其提出相關(guān)的設(shè)計(jì)目標(biāo),也對(duì)后續(xù)的性能表現(xiàn)有一定的影響。

            c)實(shí)施方案:一般當(dāng)大型一些的項(xiàng)目合同簽訂完畢后,就會(huì)分期安排實(shí)施人員負(fù)現(xiàn)場(chǎng)牽頭并組織雙方成立實(shí)施小組團(tuán)隊(duì),共同制訂系統(tǒng)的上線、操作培訓(xùn)、應(yīng)用方案等,并執(zhí)行方案直至系統(tǒng)正常上線運(yùn)行,項(xiàng)目交付。因此,這個(gè)方案制定的是否精簡(jiǎn)、高效,也直接關(guān)系了用戶應(yīng)用系統(tǒng)的性能表現(xiàn)。


           四、意識(shí)層面

            當(dāng)今社會(huì)萬(wàn)事講求以人為本,如果從軟件應(yīng)用系統(tǒng)涉及的各級(jí)人員角色的內(nèi)心沒(méi)有把性能表現(xiàn)當(dāng)回事,那么一切調(diào)優(yōu)最多也都是亡羊補(bǔ)牢而已。比如:

            a)產(chǎn)品經(jīng)理:項(xiàng)目乙方產(chǎn)品總負(fù)責(zé)人,產(chǎn)品目標(biāo)、市場(chǎng)定位、基本框架的制定者。

            b)一線人員:售前咨詢、實(shí)施顧問(wèn)等。

            c)需求設(shè)計(jì):對(duì)產(chǎn)品具體功能設(shè)計(jì)提出明確要求的角色。

            d)代碼實(shí)現(xiàn):按需求定義進(jìn)行產(chǎn)品的具體實(shí)現(xiàn)的角色。

            e)測(cè)試人員:對(duì)產(chǎn)品質(zhì)量進(jìn)行檢測(cè)、對(duì)開(kāi)發(fā)過(guò)程進(jìn)行監(jiān)管的角色。

            f)最終用戶:系統(tǒng)最終的使用者、應(yīng)用效果的影響者。

            對(duì)于一個(gè)軟件產(chǎn)品來(lái)講,只有以上這些環(huán)節(jié)的角色人等在各自的工作崗位上,真正的在意識(shí)層面上提高優(yōu)化系統(tǒng)性能的地位,而不是把它作為功能優(yōu)先實(shí)現(xiàn)之外的附屬品,才能把系統(tǒng)性能優(yōu)化的工作最大程度的作在前面、作的全面、作得到位!

            綜上所述,我們看到了各類(lèi)導(dǎo)致性能瓶頸的可能原因(也可以說(shuō)是性能調(diào)優(yōu)的入手點(diǎn)),下面我們用一個(gè)比較常用的魚(yú)骨圖分析法來(lái)展示一下,可能會(huì)更為清晰:

            然后我們?cè)侔堰@些原因按一定的規(guī)則進(jìn)行分門(mén)別類(lèi),一般采用如下的二維矩陣分析的方法,按可推行的難易度和收效的影響度高低來(lái)形成四個(gè)象限,把這些問(wèn)題按具體情況分布在這四個(gè)象限中,看到這些問(wèn)題中哪些是我們要優(yōu)先解決的,哪些是可以暫時(shí)放一放的,調(diào)優(yōu)時(shí)可以借鑒這個(gè)順序來(lái)進(jìn)行。

            當(dāng)然在不同的企業(yè)這四個(gè)象限中的原因分布是會(huì)相互轉(zhuǎn)化的,比如在一個(gè)預(yù)算有限的私企中可能額外的硬件投資對(duì)其來(lái)說(shuō)就是應(yīng)該放入暫時(shí)擱置的象限,而對(duì)于財(cái)大氣粗的單位中可能費(fèi)用預(yù)算不是問(wèn)題但是想改變他的辦事流程和組織架構(gòu)將是非常困難的,這時(shí)解決的優(yōu)先次序也就要相應(yīng)調(diào)整了。

          posted @ 2011-11-25 18:07 順其自然EVO 閱讀(179) | 評(píng)論 (0)編輯 收藏

          軟件測(cè)試講義(上)

               摘要: 在一個(gè)軟件團(tuán)隊(duì)里,不同的人有不同的投入,不同的人還要在團(tuán)隊(duì)中擔(dān)負(fù)不同的任務(wù),我們也要講一下。  團(tuán)隊(duì)中的 PM 負(fù)責(zé)分析市場(chǎng),設(shè)想功能,定義用戶到底要什么 – Why & What.  團(tuán)隊(duì)中的 Dev 負(fù)責(zé)實(shí)現(xiàn)功能,搞清楚怎么才能滿足用戶的需求 – How.  團(tuán)隊(duì)中的測(cè)試人員搞清楚我們的軟件是否滿足了用戶的需求 – Whether.  最后所有成員一...  閱讀全文

          posted @ 2011-11-25 18:06 順其自然EVO 閱讀(411) | 評(píng)論 (0)編輯 收藏

          打造高效的技術(shù)團(tuán)隊(duì),我會(huì)關(guān)注的7個(gè)點(diǎn)

          1、使用分布式的版本管理系統(tǒng)

            如果你覺(jué)得不需要使用版本管理系統(tǒng),那我們溝通會(huì)有代溝,如果你是cvs、svn的粉絲,或者由于某種原因沒(méi)有使用過(guò)分布式版本管理系統(tǒng),比如git,那強(qiáng)烈建議你去看一下“why git is better than x”。

            2、一鍵式發(fā)布

            這里發(fā)布的目標(biāo)位置,既可以是開(kāi)發(fā)機(jī),做本地測(cè)試;也可以是測(cè)試機(jī),為QA準(zhǔn)備好捉蟲(chóng)游戲的森林;還可以是生產(chǎn)環(huán)境(或者beta環(huán)境),供用戶直接訪問(wèn)。

            如深度xp一鍵恢復(fù)系統(tǒng)一樣,一鍵式發(fā)布需要自動(dòng)完成很多工作:代碼自動(dòng)化測(cè)試(開(kāi)發(fā)階段),打包壓縮,編譯(測(cè)試階段),數(shù)據(jù)同步(外網(wǎng))。也許還有很多工作要加入進(jìn)來(lái),但核心是是否能通過(guò)一個(gè)腳本的執(zhí)行就全部完成所有流程,這點(diǎn)至關(guān)重要。如果中間多出幾個(gè)環(huán)境,那將來(lái)一定會(huì)引入發(fā)布的災(zāi)難。

            3、TDD / BDD 請(qǐng)對(duì)你自己寫(xiě)的代碼負(fù)責(zé)

            不要為了TDD/BDD而TDD/BDD,只要能及時(shí)獲得自己寫(xiě)的代碼運(yùn)行情況的反饋就行,也無(wú)需一次把test case都覆蓋全。對(duì)于沒(méi)有任何單元測(cè)試的代碼,將來(lái)想引入單位測(cè)試,將舉步維艱!如果,你認(rèn)為測(cè)試完全是QA的事情,那你就花大筆的錢(qián)去招聘一個(gè)規(guī)模龐大的QA集團(tuán)吧,期望他們能讓你偷懶。

            4、使用靠譜的bug記錄工具

            人腦的潛力雖然無(wú)限,但大腦皮層只會(huì)對(duì)進(jìn)入緩存區(qū)的數(shù)據(jù)做高效的反應(yīng)。記憶再好的開(kāi)發(fā),也可能被各種牛魔鬼怪折磨的忘記了昨日的痛(曾經(jīng)產(chǎn)生的bug)。所以,從團(tuán)隊(duì)第一次提測(cè),就應(yīng)該使用靠譜的bug記錄工作。所謂好記性不如爛筆頭就是這個(gè)道理。

            那一個(gè)靠譜的bug記錄工具應(yīng)該要記錄這些數(shù)據(jù):

            ● bug復(fù)現(xiàn)的整個(gè)操作流程
            ● 產(chǎn)品需求中的正常情況
            ● 出現(xiàn)bug后,變成為什么情況
            ● 誰(shuí)將負(fù)責(zé)修復(fù)這個(gè)bug
            ● bug最后修復(fù)沒(méi)有

            至于怎么修復(fù)的bug,是重新設(shè)計(jì)還是漏提交了代碼,我覺(jué)得無(wú)關(guān)緊要。如果一個(gè)bug修復(fù)的經(jīng)驗(yàn)值得分享,可以單獨(dú)做一次團(tuán)隊(duì)的技術(shù)分享,而這往往是由于對(duì)現(xiàn)有產(chǎn)品的(技術(shù)或者其他的)信息獲取不夠?qū)е碌摹?/p>

            5、盡快修復(fù)bug

            我的開(kāi)發(fā)經(jīng)驗(yàn)告訴我,一個(gè)bug越晚修復(fù),被修復(fù)的可能性越小,將來(lái)產(chǎn)生危害的可能性越大。試想,你剛提測(cè)或者發(fā)布的代碼,出現(xiàn)的bug,往往你能最快得到解決它需求的時(shí)間,而時(shí)間在項(xiàng)目管理上是非常重要的。反之,如果積累了很多bug,且有一定時(shí)間了,那修復(fù)它就需要對(duì)所有相關(guān)的系統(tǒng)進(jìn)行了解,這將花費(fèi)大量你可以用來(lái)度假,娛樂(lè)的美好時(shí)光。所以,從團(tuán)隊(duì)一開(kāi)始就貫徹這點(diǎn),可以釋放成員修復(fù)bug的壓力。

            6、給團(tuán)隊(duì)成員一個(gè)安靜的環(huán)境

            最近很多同學(xué)告訴我,白天基本上沒(méi)有什么效率,總是受到各種騷擾。我們做一個(gè)假設(shè):假如A同學(xué)進(jìn)入最佳狀態(tài)需要30分鐘,那么如果他比較慘,在30分鐘間隔內(nèi),他總是被打斷,那么他一天都無(wú)法最高效的工作。又或者同學(xué)B google查詢一個(gè)技術(shù)問(wèn),花費(fèi)2分鐘可以解決,但問(wèn)同學(xué)A只要20秒鐘(好吧,同學(xué)A表達(dá)很清晰)。這樣同學(xué)B節(jié)省了100秒鐘,而同學(xué)A至少損失了30分鐘。

            從這個(gè)假設(shè),我們不難發(fā)現(xiàn),如果能避免團(tuán)隊(duì)成員受到外來(lái)信息的騷擾,他就有可能更加高效的工作,從而寫(xiě)出更好的產(chǎn)品。而常識(shí)告訴我們,人不可能一直高效的工作,所以,我們應(yīng)該利用好無(wú)法集中精力的時(shí)間去進(jìn)行一些溝通。但分出這個(gè)界限顯然十分困難,所以我覺(jué)得不妨這樣:規(guī)定每天的安靜時(shí)間段,在這個(gè)時(shí)間段,其他人都不能來(lái)打擾這位同學(xué),而在非安靜時(shí)間段,可以隨意訪問(wèn),從而讓這位同學(xué)形成一個(gè)新的生物鐘(人體的自我調(diào)節(jié)能力是非常強(qiáng)悍的)。

            7、給員工最好的工具

            做同樣一件事情,如果使用工具A,消耗的時(shí)間為5分鐘,而使用工具B,消耗的時(shí)間為1分鐘,那我一定給員工提供B工具,即使B工具的價(jià)格是A工具的5倍。因?yàn)椋偃缛嗽谶B續(xù)高效工作中的抵抗干擾時(shí)間為1分鐘,那么意味著B(niǎo)工具能保證高效工作的時(shí)間連續(xù),而A將可能分散了用戶精力,導(dǎo)致需要更多的時(shí)間才進(jìn)入最佳狀態(tài)。事實(shí)上,之所以要更好的cpu,更大的內(nèi)存,更好的編譯器,更好的編輯器,多顯示器,都是讓程序員盡快能回到核心業(yè)務(wù)上來(lái),而在等待上花費(fèi)更少的時(shí)間。

            同時(shí),別忘了,一把好的椅子也是維持更長(zhǎng)高效工作時(shí)間的保證,所以,別吝嗇,給員工更好的椅子吧,他們會(huì)感到你的溫懷。

          posted @ 2011-11-25 18:06 順其自然EVO 閱讀(170) | 評(píng)論 (0)編輯 收藏

          如何應(yīng)對(duì)沒(méi)有需求的測(cè)試

          軟件測(cè)試時(shí)候發(fā)現(xiàn)根本沒(méi)有需求,一問(wèn)開(kāi)發(fā)和需求,發(fā)現(xiàn)原來(lái)是我們的項(xiàng)目經(jīng)理口口相傳,告訴開(kāi)發(fā)要怎么怎么做。

            可想而之,這個(gè)過(guò)程是沒(méi)有設(shè)計(jì)的,開(kāi)發(fā)過(guò)程當(dāng)中遇到問(wèn)題,就會(huì)問(wèn),項(xiàng)目經(jīng)理即時(shí)馬上給出答復(fù)。

            而到了測(cè)試,測(cè)試人員在完全不了解狀況的時(shí)候,在界面上點(diǎn)了點(diǎn),也不知道要點(diǎn)多少東西,反正一會(huì)告訴我說(shuō)版本測(cè)試完了。我心里沒(méi)底,想著版本上提到改了這么多東西,怎么馬上就測(cè)試完了呢?

            于是我抱著懷疑的態(tài)度去做測(cè)試,結(jié)果一看發(fā)現(xiàn)我們的系統(tǒng)已經(jīng)大變樣了。以前一個(gè)流程的三種狀態(tài)變成了現(xiàn)在的未知種數(shù)。我傻眼了,這樣怎么可能做測(cè)試呢?沒(méi)有需求,無(wú)法預(yù)估到測(cè)試場(chǎng)景。怎樣才是測(cè)試完成了?更可恨地是部門(mén)經(jīng)理說(shuō)測(cè)試完了沒(méi)問(wèn)題就上線,我的問(wèn)題是怎樣是測(cè)試完了,怎樣是沒(méi)問(wèn)題呢?

            我告訴部門(mén)經(jīng)理,我無(wú)法決定是否上線,因?yàn)槲也恢廊绾卧O(shè)計(jì)測(cè)試場(chǎng)景了,而通過(guò)我的測(cè)試,我發(fā)現(xiàn)了一些開(kāi)發(fā)人員也無(wú)法回答的問(wèn)題,于是我把所有我知道范圍之內(nèi)的可能造成狀態(tài)不同的條件全部列出來(lái)了,要求項(xiàng)目經(jīng)理可我填寫(xiě),如果是這樣的輸入條件,輸出是怎樣的?經(jīng)我這么發(fā)問(wèn),項(xiàng)目經(jīng)理也無(wú)法填寫(xiě)我的結(jié)果,又推給需求去確認(rèn)。當(dāng)然事情暫時(shí)沒(méi)有結(jié)論,現(xiàn)在的狀態(tài)是版本暫時(shí)沒(méi)有上線,我的測(cè)試我認(rèn)為是沒(méi)有做完的。

            針對(duì)以上的問(wèn)題,我覺(jué)得好險(xiǎn)。測(cè)試是項(xiàng)目最后的一道關(guān),如果我不能發(fā)現(xiàn)這些問(wèn)題,上線后,客戶發(fā)現(xiàn)了,我們?nèi)绾谓忉屇兀覀兊捻?xiàng)目經(jīng)理會(huì)挺身而出幫你說(shuō)話,說(shuō)是因?yàn)闆](méi)有需求嗎?

            如果出了問(wèn)題,我對(duì)項(xiàng)目經(jīng)理沒(méi)有這樣的信心。但是我越發(fā)覺(jué)得測(cè)試是多么的重要了,每次上線都是對(duì)我個(gè)人能力的考驗(yàn)。而這種混亂狀態(tài)下,如果我不能夠發(fā)問(wèn),我這個(gè)測(cè)試組的地位只會(huì)越來(lái)越低,成為別人推卸責(zé)任的那個(gè)背著黑鍋的家伙。

            這次我也發(fā)現(xiàn)自己在進(jìn)入這個(gè)部門(mén)兩個(gè)月以后的第一次反抗,前期由于不了解項(xiàng)目的情況,所以出這種問(wèn)題也是無(wú)法察覺(jué)的。需求和開(kāi)發(fā)沒(méi)有文檔,需求分析和設(shè)計(jì)沒(méi)有做好,我的測(cè)試也只能定位比較低。但是通過(guò)這次的考驗(yàn),我自己越來(lái)越多的相信,我能夠做好項(xiàng)目的測(cè)試管理,我的測(cè)試組能夠在項(xiàng)目過(guò)程中充當(dāng)著不可或缺的角色。

            沒(méi)有需求的測(cè)試,很危險(xiǎn),但是我絕不是每次都要用這種方法來(lái)對(duì)付這個(gè)問(wèn)題,我要告訴部門(mén),你們前期的需求分析是否可以做得更全面一點(diǎn),開(kāi)發(fā)設(shè)計(jì)可以多考慮一些,不要每次把問(wèn)題丟給測(cè)試,提高項(xiàng)目的間接成本。

          posted @ 2011-11-25 18:06 順其自然EVO 閱讀(198) | 評(píng)論 (0)編輯 收藏

          深入分析SQL字符串限制長(zhǎng)度漏洞

           MySQL字符串的限制長(zhǎng)度看似重要性不要,其實(shí)和整個(gè)MySQL數(shù)據(jù)庫(kù)的安全性是息息相關(guān)的,很值得我們?nèi)ド钊胙芯糠治觥?/p>

            SQL注入攻擊一直都在被廣泛的討論,然而人們卻忽略了今天我將要介紹的這兩個(gè)安全隱患,那就是超長(zhǎng)SQL查詢和單列SQL字符長(zhǎng)度限制可能會(huì)帶來(lái)的問(wèn)題。

            首先我們來(lái)談?wù)撘幌鲁L(zhǎng)SQL查詢

            max_packet_size

            這個(gè)東西是用來(lái)限制mysql客戶端和服務(wù)器通信數(shù)據(jù)包的長(zhǎng)度的,比如一個(gè)查詢?yōu)?#8220;select * from user where 1”,那么這個(gè)長(zhǎng)度僅僅幾十個(gè)字節(jié),所以不會(huì)超標(biāo)。在絕大多情況下,我們很難會(huì)超過(guò)mysql的默認(rèn)限制1M(可以想象一下,1M的SQL語(yǔ)句還是很長(zhǎng)的)。這里插一句,看到這篇文章之后,我終于清楚我當(dāng)初用PEAR DB 的INSERT插入數(shù)據(jù)失敗的原因了,很可能就是數(shù)據(jù)長(zhǎng)度超標(biāo)。對(duì)于MySQL來(lái)說(shuō),如果查詢MySQL字符串的大小超過(guò)了這個(gè)限制,mysql將不會(huì)執(zhí)行任何查詢操作

            如果訪問(wèn)者有可能控制你的sql長(zhǎng)度,那么你的程序可能會(huì)受到攻擊。哪些情況訪問(wèn)者可能控制sql的長(zhǎng)度呢,比如不限制關(guān)鍵字長(zhǎng)度的搜索。還有可能就是你的程序如果要將用戶的登錄作為日志啟用,總之凡是涉及到超長(zhǎng)sql查詢的地方,一定得小心檢查自己的sql,防止超長(zhǎng)而查詢失效。不過(guò)說(shuō)實(shí)在的,本人認(rèn)為這個(gè)問(wèn)題倒不是多大,數(shù)據(jù)庫(kù)管理員也可以自行設(shè)置MySQL的max_packet_size的長(zhǎng)度,或者在處理可能超長(zhǎng)的SQL查詢的時(shí)候做一個(gè)長(zhǎng)度判斷。

            MySQL列長(zhǎng)度限制

            這個(gè)是本文的重點(diǎn)。MySQL對(duì)于插入的字符串,如果長(zhǎng)度超過(guò)了數(shù)據(jù)表限制的長(zhǎng)度,MySQL將會(huì)截取前面部分MySQL字符串插入數(shù)據(jù)庫(kù)中,而不會(huì)將錯(cuò)誤報(bào)給web程序。對(duì)于粗心的程序員,這個(gè)問(wèn)題可能會(huì)導(dǎo)致程序的漏洞,其實(shí)目前的wordpress有很多限制,通過(guò)這個(gè)漏洞攻擊應(yīng)該沒(méi)有任何作用。下面是原作者的幾個(gè)假設(shè),如果同時(shí)滿足這幾個(gè)條件,獲取一個(gè)站點(diǎn)的用戶名是相當(dāng)容易的事情,幸運(yùn)的是目前的wordpress并不太可能會(huì)同時(shí)滿足下面的條件:

            該web應(yīng)用允許用戶注冊(cè)(開(kāi)放注冊(cè)的wordpress滿足此條件);

            超級(jí)管理員的用戶名已知的,比如admin,這樣方便攻擊者尋找目標(biāo)(可憐wordpress也滿足)

            MySQL使用的是默認(rèn)的配置(估計(jì)大多數(shù)都滿足)

            注冊(cè)新用戶的時(shí)候,程序沒(méi)有對(duì)用戶名的長(zhǎng)度給予限制(我測(cè)試過(guò),wordpress也滿足)

            用戶名被限制在16個(gè)字符(這個(gè)和上面的沒(méi)有關(guān)系,僅僅是方便舉例)

            下面我們來(lái)看看攻擊者是怎么攻擊的:

            首先攻擊者用已知的超級(jí)管理員id如admin注冊(cè),那么這個(gè)時(shí)候程序就會(huì)用

          以下是代碼片段:
              (show/hide)plain text
            SELECT * FROM user WHERE username='admin '

            來(lái)檢查該ID是否已經(jīng)存在,如果存在,這不允許注冊(cè),當(dāng)然,攻擊者嘗試注冊(cè)admin肯定會(huì)失敗;

            但是如果攻擊者用 admin X(admin和x之間有11個(gè)或以上的空格)來(lái)注冊(cè)呢,按照上面的判斷,由于admin x不存在數(shù)據(jù)庫(kù)中,所以當(dāng)然就能注冊(cè)成功了,事實(shí)上wordpress2.6.1之前的版本確實(shí)可以這樣,由于列長(zhǎng)度的限制在16個(gè)字符內(nèi),所以末尾的x就被截掉了,那么現(xiàn)在數(shù)據(jù)庫(kù)中就存在兩個(gè)一模一樣的用戶admin了。(旁白:糟糕,那我的程序不是都要去修改。其實(shí)沒(méi)有必要,你只要把ID設(shè)置為UNIQUE就可以了,于是乎,下面的問(wèn)題就和你沒(méi)有關(guān)系了)

            攻擊者繼續(xù),這個(gè)時(shí)候攻擊者就順利的注冊(cè)了admin這個(gè)用戶名,然后攻擊者用admin和自己的密碼登錄進(jìn)入賬戶管理(wordpress即使注冊(cè)了也無(wú)法登陸),由于真正的admin的帳號(hào)先于攻擊者admin注冊(cè),所以在賬戶信息頁(yè)面,顯示的信息非常有可能就是真正admin的信息,包括密碼提示和email等,這個(gè)時(shí)候攻擊者就可以對(duì)admin的信息進(jìn)行任意修改,包括密碼和密碼找回。

            所以,寫(xiě)web程序的你,是不是該去檢查一下自己的程序是否有此類(lèi)的漏洞呢。

          posted @ 2011-11-25 17:43 順其自然EVO 閱讀(643) | 評(píng)論 (0)編輯 收藏

          OpenStack詳細(xì)解讀:定義,好處與使用實(shí)例

               摘要: OpenStack是一個(gè)旨在為公共及私有云的建設(shè)與管理提供軟件的開(kāi)源項(xiàng)目。它的社區(qū)擁有超過(guò)130家企業(yè)及1350位開(kāi)發(fā)者,這些機(jī)構(gòu)與個(gè)人都將OpenStack作為基礎(chǔ)設(shè)施即服務(wù)(簡(jiǎn)稱(chēng)IaaS)資源的通用前端。OpenStack項(xiàng)目的首要任務(wù)是簡(jiǎn)化云的部署過(guò)程并為其帶來(lái)良好的可擴(kuò)展性。本文希望通過(guò)提供必要的指導(dǎo)信息,幫助大家利用OpenStack前端來(lái)設(shè)置及管理自己的公共云或私有云。  內(nèi)容詳解  ...  閱讀全文

          posted @ 2011-11-25 17:40 順其自然EVO 閱讀(1406) | 評(píng)論 (0)編輯 收藏

          Equinox加載Bundle Class的實(shí)現(xiàn)

           Equinox在創(chuàng)建Bundle的ClassLoader時(shí),首先獲取bundle的classpath,然后執(zhí)行createBCLPrevileged方法,此方法最后轉(zhuǎn)交由BaseData來(lái)創(chuàng)建ClassLoader。

            BaseDate創(chuàng)建ClassLoader的關(guān)鍵代碼片段為:

        1. ClassLoadingHook[] hooks = adaptor.getHookRegistry().getClassLoadingHooks(); 
        2.     ClassLoader parent = adaptor.getBundleClassLoaderParent(); 
        3.     BaseClassLoader cl = null
        4.     for (int i = 0; i < hooks.length && cl == null; i++) 
        5.        cl = hooks[i].createClassLoader(parent, delegate, domain, this, bundleclasspath); 
        6.     if (cl == null
        7.        cl = new DefaultClassLoader(parent, delegate, domain, this, bundleclasspath); 
        8.     return cl;
        9.   在Equinox中,默認(rèn)的情況下adaptor.getBundleClassLoaderParent返回的為bootstrap classloader,可通過(guò)修改啟動(dòng)的osgi.parentClassLoader 來(lái)改變這個(gè)parent classloader,

            osgi.parentClassLoader 的可選值有四個(gè),分別是:

            ● boot:默認(rèn)

            ● app:SystemClassLoader

            ● ext:SystemClassLoader的parent

            ● fwk:?jiǎn)?dòng)Equinox的ClassLoader

            ClassLoadingHook在createClassLoader的時(shí)候都沒(méi)有做動(dòng)作,因此最后ClassLoader都是通過(guò)創(chuàng)建DefaultClassLoader對(duì)象來(lái)構(gòu)建的,其中parent參數(shù)為null,delegate參數(shù)為BundleLoader實(shí)例,bundleclasspath參數(shù)為bundle的classpath。

            經(jīng)過(guò)以上步驟后,完成了ClassLoader的創(chuàng)建,可以開(kāi)始加載class了,根據(jù)上面上述,Bundle的Class就由DefaultClassLoader來(lái)完成了。

            查看DefaultClassLoader的loadClass代碼,發(fā)現(xiàn)真正的加載class的過(guò)程是轉(zhuǎn)為調(diào)用了delegate 的findClass來(lái)完成的,delegate參數(shù)對(duì)應(yīng)的為BundleLoader實(shí)例,轉(zhuǎn)為跟蹤BundleLoader的findClass方法。

            BundleLoader的findClass方法的代碼片段:

        10. if (checkParent && parentCL != null && name.startsWith(JAVA_PACKAGE)) 
        11.    return parentCL.loadClass(name);
        12.   從以上這個(gè)代碼片段,可以看到,Equinox將java.開(kāi)頭的類(lèi)轉(zhuǎn)交給了parent classloader去加載,這也意味著沒(méi)必要在系統(tǒng)中提供對(duì)外export java.開(kāi)頭的package。

            如果不是java.開(kāi)頭的類(lèi),則交由findClassInternal方法來(lái)完成加載。

            findClassInternal方法遵循的為OSGi規(guī)范中定義的Class的加載順序,不過(guò)仍然稍有改動(dòng):

            1)判斷是否交由parent classloader去完成加載

            在啟動(dòng)Equinox時(shí),Equinox會(huì)讀取org.osgi.framework.bootdelegation屬性,該屬性對(duì)應(yīng)配置的為需要從parent classloader中加載的package,如值配置的為*,說(shuō)明所有的都從parent classloader中加載 ,如值配置的為具體的package,那么則放入bootDelegation集合;如配置的為帶通配符的package,那么則放入bootDelegationStems集合。

            判斷時(shí)Equinox首先判斷是否所有的都從parent classloader中加載,如是則從parent classloader中加載;

            如需要加載的類(lèi)的package位于bootDelegation或bootDelegationStems集合中,那么同樣從parent classloader中加載。

            如不從parent classloader中加載,則進(jìn)入下面的步驟。

           2)嘗試調(diào)用Equinox提供的ClassLoaderDelegateHook的擴(kuò)展來(lái)加載

            Equinox對(duì)外提供了ClassLoaderDelegateHook的接口擴(kuò)展,可編寫(xiě)ClassLoaderDelegateHook的實(shí)現(xiàn),注冊(cè)到Framework中,那么當(dāng)有Class需要加載等動(dòng)作時(shí)都會(huì)得到通知。

            在默認(rèn)情況下,Equinox中沒(méi)有ClassLoaderDelegateHook的實(shí)現(xiàn),因此繼續(xù)下面的步驟。

            3)判斷是否在import-package中,如在則交由相應(yīng)的PackageSource去加載

            根據(jù)Bundle配置的import-package,判斷目前需要加載的類(lèi)是否在import-package中,如在則交由對(duì)應(yīng)的PackageSource進(jìn)行加載,PackageSource在加載時(shí)即直接交由對(duì)應(yīng)的Bundle的classloader去加載,如加載的類(lèi)的package在import-package中,但加載后仍然沒(méi)有找到Class,則直接拋出ClassNotFoundException,如加載到,則直接返回。

            如所需要加載的類(lèi)的package不在import-package中,則繼續(xù)下面的步驟。

            4)嘗試從require-bundle中加載

            嘗試使用require-bundle來(lái)加載,如加載到,則直接返回,如加載不到,則繼續(xù)下面的步驟。

            5)嘗試從當(dāng)前Bundle中加載

            直到經(jīng)過(guò)以上步驟的嘗試,才嘗試由當(dāng)前Bundle中加載,當(dāng)前Bundle加載的方法即從Bundle-Classpath或當(dāng)前Bundle的Fragment中查找相應(yīng)名稱(chēng)的class文件,并讀取該文件進(jìn)行加載,如class文件已加載,則進(jìn)行緩存,再次加載時(shí)則不需要查找和解析class文件。

            如從當(dāng)前Bundle中仍然未找到所需的類(lèi),則繼續(xù)下面的步驟。

            6)嘗試從DynamicImport-Package中加載

            判斷需要找的類(lèi)的package是否在DynamicImport-Package中,如果在,則交由相應(yīng)的PackageSource進(jìn)行加載,如PackageSource中加載不到,則拋出ClassNotFoundException;如不在DynamicImport-Package中,則繼續(xù)下面的步驟。

            7)再次嘗試調(diào)用Equinox提供的ClassLoaderDelegateHook的擴(kuò)展來(lái)加載

            這步和第2)步相同,因此在默認(rèn)情況下繼續(xù)下面的步驟。

            8)嘗試使用eclipse的buddy機(jī)制來(lái)加載

            Buddy機(jī)制是Eclipse的擴(kuò)展,并不符合OSGi規(guī)范,因此在此不做深入分析。

            9)判斷一定的條件,如符合則從parent classloader中加載

            判斷的條件為:parent classloader不為null、不從parent classloader中加載、Equinox的向后兼容屬性(osgi.compatibility.bootdelegation)為true以及jvm的bug class,如滿足以上條件,則嘗試從parent classloader中加載。

            如經(jīng)過(guò)以上所有步驟后,仍然未找到需要加載的class,則拋出ClassNotFoundException。

            從上面的代碼分析中,在Equinox中可以通過(guò)osgi.parentClassLoader、org.osgi.framework.bootdelegation來(lái)控制從Bundle ClassLoader外來(lái)加載Class,這對(duì)于集成Equinox其他容器而言,非常有用,另外,還可以通過(guò)實(shí)現(xiàn)ClassLoaderDelegateHook來(lái)改變Class的加載。

          posted @ 2011-11-25 17:21 順其自然EVO 閱讀(213) | 評(píng)論 (0)編輯 收藏

          Tomcat部署多個(gè)應(yīng)用站點(diǎn)的方法

          Tomcat部署多個(gè)應(yīng)用站點(diǎn)的方法

          分類(lèi): 服務(wù)器相關(guān)類(lèi)2010-11-02 11:30 360人閱讀 評(píng)論(0) 收藏 舉報(bào)

          前些天用Tomcat的時(shí)候遇到一個(gè)問(wèn)題,那就是如何在一個(gè)服務(wù)下部署兩個(gè)應(yīng)用,通俗說(shuō)就是一個(gè)web server,下面有兩個(gè)網(wǎng)站,對(duì)應(yīng)不同的二級(jí)域名,兩者指向的是同一IP地址。如何做才能分別訪問(wèn)而不受干擾呢?為此,g了一下,找到了相關(guān)解決辦法。祥見(jiàn)Tomcat建立多個(gè)應(yīng)用(Web Server),多個(gè)主機(jī),多個(gè)站點(diǎn)的方法,粗略了研究了一下,恍然大悟。原來(lái)只消把Tomcat下的server.xml修改一下即可,現(xiàn)把我的配置貼出來(lái),僅供參考。

              <service name="Catalina">
            <connector port="8080" protocol="HTTP/1.1" maxHttpHeaderSize="8192" maxThreads="800" minSpareThreads="10" maxSpareThreads="100" enableLookups="false" redirectPort="8443" acceptCount="200" connectionTimeout="20000" disableUploadTimeout="true">
            </connector>
            <connector port="8009" protocol="AJP/1.3" redirectPort="8443"></connector>  
            <engine name="Catalina" defaultHost="localhost">
             <realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase">
             </realm>
             <host name="qss.pmlove.com.cn" appBase="webapps" unpackWARs="true" autoDeploy="true" xmlValidation="false" xmlNamespaceAware="false">
              <alias>qss.pmlove.com.cn</alias>
              <context path="" docBase="D:/apache-tomcat-6.0.18/webapps/qss" debug="0" reloadable="true"></context>
             </host>
             <host name="vp.pmlove.com.cn" appBase="webapps" unpackWARs="true" autoDeploy="true" xmlValidation="false" xmlNamespaceAware="false">
                       <alias>vp.pmlove.com.cn</alias>
                       <context path="" docBase="D:/apache-tomcat-6.0.18/webapps/vp" debug="0" reloadable="true"></context>
                      </host>
            </engine>
           </service>
          以上代碼是server.xml的一部分,只要對(duì)應(yīng)拷貝即可實(shí)現(xiàn),本人已測(cè)試成功。

          posted @ 2011-11-25 17:15 順其自然EVO 閱讀(22866) | 評(píng)論 (0)編輯 收藏

          頁(yè)面性能測(cè)試

            一、頁(yè)面性能測(cè)試概述

            頁(yè)面性能測(cè)試則是針對(duì)于頁(yè)面性能優(yōu)化而開(kāi)展的一種性能測(cè)試,目的是對(duì)Web系統(tǒng)的頁(yè)面進(jìn)行測(cè)試以確認(rèn)系統(tǒng)頁(yè)面是否會(huì)影響系統(tǒng)的性能并為頁(yè)面的優(yōu)化提供依據(jù)與建議,最終提升系統(tǒng)的整體性能表現(xiàn),提高用戶體驗(yàn)滿意度。可見(jiàn),Web系統(tǒng)頁(yè)面性能測(cè)試是相對(duì)Web系統(tǒng)后臺(tái)測(cè)試的另外一種性能測(cè)試,是Web系統(tǒng)性能測(cè)試的一個(gè)重要部分。

            二、頁(yè)面性能測(cè)試必要性

            相對(duì)于C/S架構(gòu)的應(yīng)用系統(tǒng),Web應(yīng)用系統(tǒng)所有數(shù)據(jù)都需要從服務(wù)器端下載,雖然瀏覽器有緩存機(jī)制,但客戶每次訪問(wèn)仍然需要下載大量的數(shù)據(jù)。特別是用戶對(duì)系統(tǒng)要求越來(lái)越高,除了要求功能完備,對(duì)界面的美觀、易用性也提出了更高的要求,越炫的頁(yè)面也就意味著頁(yè)面中要包含更多的腳本、樣式表、圖片和Flash,頁(yè)面的數(shù)據(jù)量也就越大,這對(duì)Web系統(tǒng)的性能提出了極大的挑戰(zhàn)。

            曾經(jīng)有個(gè)在線打印服務(wù)的應(yīng)用提供商說(shuō)他們的系統(tǒng)不需要關(guān)注系統(tǒng)性能問(wèn)題,沒(méi)有必要進(jìn)行性能測(cè)試,因?yàn)樗麄兛梢再?gòu)買(mǎi)足夠多的服務(wù)器來(lái)支撐系統(tǒng);不少業(yè)界同行也認(rèn)為只要有足夠多的服務(wù)器資源,性能就不會(huì)存在問(wèn)題。其實(shí)不然,他們都只關(guān)注到了應(yīng)用系統(tǒng)的后臺(tái)性能表現(xiàn),而忽略了頁(yè)面對(duì)系統(tǒng)整體性能的影響。舉個(gè)例子,當(dāng)一個(gè)頁(yè)面中包含幾百個(gè)請(qǐng)求,頁(yè)面中沒(méi)有經(jīng)過(guò)優(yōu)化的javaScript文件、CSS 文件與圖片件大小達(dá)到10MB,即使當(dāng)前只有一個(gè)用戶在訪問(wèn)該系統(tǒng),頁(yè)面的訪問(wèn)速度也會(huì)慢得驚人,縱使增加再多的服務(wù)器也不見(jiàn)得會(huì)有明顯的性能提升。

            可見(jiàn),對(duì)Web應(yīng)用系統(tǒng)的頁(yè)面進(jìn)行性能測(cè)試和優(yōu)化是非常有必要的。只有通過(guò)對(duì)頁(yè)面的性能測(cè)試,發(fā)現(xiàn)頁(yè)面存在的性能問(wèn)題并根據(jù)性能測(cè)試結(jié)果進(jìn)行頁(yè)面優(yōu)化以提升頁(yè)面的加載性能,從而提升系統(tǒng)的整體性能。在應(yīng)用系統(tǒng)高并發(fā)訪問(wèn)時(shí),更能體現(xiàn)出Web頁(yè)面優(yōu)化后所帶來(lái)的系統(tǒng)整體性能提升效果。

            2種方式來(lái)提升你的web 應(yīng)用程序的速度:

            ● 減少請(qǐng)求和響應(yīng)的往返次數(shù)

            ● 減少請(qǐng)求和響應(yīng)的往返字節(jié)大小。

            減少請(qǐng)求和響應(yīng)的往返次數(shù):

            HTTP緩存是最好的減少客戶端服務(wù)器端往返次數(shù)的辦法。緩存提供了提供一種機(jī)制來(lái)保證客戶端或者代理能夠存儲(chǔ)一些東西,而這些東西將會(huì)在稍后的HTTP 響應(yīng)中用到的。(即第一次請(qǐng)求了,到了客戶端,緩存起來(lái),下次如果頁(yè)面還要這個(gè)JS文件或者CSS文件啥的,就不要到服務(wù)器端去取下來(lái)了,但是還是要去服務(wù)器上去訪問(wèn)一次,因?yàn)檎?qǐng)求要對(duì)比ETAG值,關(guān)于這個(gè)值,我將會(huì)在下次翻譯中介紹其作用)這樣,就不用讓文件再次跨越整個(gè)網(wǎng)絡(luò)了。

            緩存相關(guān)的請(qǐng)求頭

            為了提高性能,微軟的IE和其他的web客戶端總是想盡辦法來(lái)維持從遠(yuǎn)程服務(wù)器上下載下來(lái)的本地的緩存。

            當(dāng)客戶端需要一個(gè)資源(html,css.js…),他們有3種可能的動(dòng)作:

            1、發(fā)送一個(gè)一般的HTTP請(qǐng)求到遠(yuǎn)程服務(wù)器端,請(qǐng)求這個(gè)資源。

            2、發(fā)送一個(gè)有條件的HTTP請(qǐng)求到服務(wù)器,條件就是如果它不同于本地的緩存版本。

            3、如果緩存的拷貝可用,就使用本地的緩存資源。

            當(dāng)發(fā)送一個(gè)請(qǐng)求,客戶也許會(huì)使用如下的幾個(gè)HEADER

            減少請(qǐng)求肯響應(yīng)往返的字節(jié)大小:

            1、使用更少的圖畫(huà)

            2、將所有的CSS濃縮到一個(gè)CSS文件中

            3、將所有的腳本濃縮到一個(gè)JS文件中

            4、簡(jiǎn)化你的頁(yè)時(shí)間

            5、使用HTTP壓縮

            三、頁(yè)面性能測(cè)試工具介紹

            第一種是通過(guò)HTTP代理的方式來(lái)截取客戶與服務(wù)器之間的通訊。

            此類(lèi)的工具非常的多,如:

            charles是一個(gè)HTTP代理/ HTTP監(jiān)視器/使開(kāi)發(fā)人員可以查看所有的計(jì)算機(jī)和互聯(lián)網(wǎng)之間的HTTP和SSL/ HTTPS流量的反向代理。這包括請(qǐng)求,響應(yīng)和HTTP標(biāo)頭(其中包含的cookies和緩存信息)。

            charles界面清爽,采用中國(guó)的瓷器為logo,給人的感覺(jué)簡(jiǎn)潔高雅。而且使用也非常簡(jiǎn)單。進(jìn)入下載頁(yè)面,選擇你適合你的版本,安裝也非常簡(jiǎn)單,一路“next”就OK了。

            點(diǎn)擊工具欄上的“紅色”按鈕,就自動(dòng)的記錄你瀏覽器訪問(wèn)的所有網(wǎng)站。

            Fiddler是一個(gè)Web調(diào)試代理,記錄所有的HTTP(S)之間的計(jì)算機(jī)和互聯(lián)網(wǎng)的交通。提琴手允許您檢查交通,設(shè)置斷點(diǎn),和“搗鼓”傳入或傳出數(shù)據(jù)。菲德勒包括一個(gè)強(qiáng)大的基于事件的腳本子系統(tǒng),并可以使用任何。NET語(yǔ)言擴(kuò)展。

            Fiddler是免費(fèi)軟件,可以調(diào)試,從幾乎任何應(yīng)用程序,支持代理,包括IE瀏覽器,谷歌Chrome,蘋(píng)果Safari,Mozilla Firefox中,歌劇,還有數(shù)千交通。您也可以像Windows電話,iPod/ iPad和其他流行的設(shè)備調(diào)試的交通。

            Fiddler2相比Charles功能要更強(qiáng)大一些。當(dāng)然了,如果單單把他們理解成頁(yè)面性能測(cè)試工具有此片面,尤其Fiddlers2功能強(qiáng)大,當(dāng)然了,我也沒(méi)有深究,在此就不過(guò)多評(píng)論了。


          posted @ 2011-11-24 18:08 順其自然EVO 閱讀(353) | 評(píng)論 (0)編輯 收藏

          軟件測(cè)試管理的一點(diǎn)經(jīng)驗(yàn)

            測(cè)試工作頭緒較多,專(zhuān)業(yè)性強(qiáng),如何做好測(cè)試管理工作,特別是量化管理,提高測(cè)試效率、督促測(cè)試人員完成好測(cè)試工作,是很重要的。

            我負(fù)責(zé)三位XXX測(cè)試人員對(duì)XXX進(jìn)行測(cè)試。測(cè)試規(guī)程主要是按協(xié)議的各個(gè)要求編寫(xiě)的,測(cè)試規(guī)程的通過(guò)準(zhǔn)則是測(cè)試人員根據(jù)對(duì)協(xié)議的理解、對(duì)系統(tǒng)的理解編寫(xiě)的。三位測(cè)試人員根據(jù)測(cè)試規(guī)程進(jìn)行分工,分別編寫(xiě)、測(cè)試不同的規(guī)程。測(cè)試的平臺(tái)是測(cè)試部自已開(kāi)發(fā)的專(zhuān)用XXX測(cè)試環(huán)境。

            前一段時(shí)間,對(duì)XXX測(cè)試如何進(jìn)行管理沒(méi)有一個(gè)頭緒,使得XXX測(cè)試計(jì)劃一再推遲,并且對(duì)實(shí)際的進(jìn)展、測(cè)試的質(zhì)量都不太清楚。為了加強(qiáng)對(duì)XXX測(cè)試的管理,并爭(zhēng)取做到量化,進(jìn)行一些嘗試,并取得一定的成功。現(xiàn)在每天可以看到實(shí)際的測(cè)試進(jìn)展,并能發(fā)現(xiàn)每位測(cè)試人員的進(jìn)度、質(zhì)量,也可以看到XXX測(cè)試結(jié)果的情況。

            以下是我近期對(duì)測(cè)試管理的經(jīng)驗(yàn)。

            做好每日匯報(bào)工作

            每日匯報(bào)工作可以與項(xiàng)目、部門(mén)的一些具體要求結(jié)合起來(lái)。比如,項(xiàng)目要求每天的測(cè)試應(yīng)當(dāng)有一份測(cè)試日?qǐng)?bào)。測(cè)試部要求測(cè)試規(guī)程、測(cè)試結(jié)果要入到測(cè)試中心。還要求故障及時(shí)提交,并導(dǎo)入CQ。

            除此之外,為了做好統(tǒng)計(jì)工作,我在CC上建立了一個(gè)execl的匯總文件,輸入了所有的測(cè)試規(guī)程、通過(guò)準(zhǔn)則。每天,測(cè)試人員有新增加的測(cè)試規(guī)程、通過(guò)準(zhǔn)則,要加到該文件中;每天的測(cè)試結(jié)果,要填到該文件中。要填的內(nèi)容,如果是測(cè)試規(guī)程、通過(guò)準(zhǔn)則,是與測(cè)試中心的是一致的。測(cè)試結(jié)果只是一個(gè)通過(guò)或不通過(guò),加上一個(gè)當(dāng)天日期。這是一個(gè)非常簡(jiǎn)單的填表,并不會(huì)增加太多的工作量。

            采用CC,可以保證匯總文件的一致性,還可以檢查測(cè)試人員填寫(xiě)的情況,可以提取不同版本的匯總文件。這充分利用了CC的優(yōu)點(diǎn)。

            以下是匯總文件中的一部分:

          posted @ 2011-11-24 17:43 順其自然EVO 閱讀(167) | 評(píng)論 (0)編輯 收藏

          僅列出標(biāo)題
          共394頁(yè): First 上一頁(yè) 357 358 359 360 361 362 363 364 365 下一頁(yè) Last 
          <2025年7月>
          293012345
          6789101112
          13141516171819
          20212223242526
          272829303112
          3456789

          導(dǎo)航

          統(tǒng)計(jì)

          常用鏈接

          留言簿(55)

          隨筆分類(lèi)

          隨筆檔案

          文章分類(lèi)

          文章檔案

          搜索

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

          主站蜘蛛池模板: 罗源县| 平塘县| 大埔区| 牡丹江市| 襄垣县| 伊通| 平远县| 黄冈市| 澎湖县| 长宁区| 河南省| 思茅市| 天津市| 铅山县| 张家界市| 嘉义县| 额敏县| 黄浦区| 赫章县| 商城县| 什邡市| 微山县| 扶风县| 彰化市| 疏勒县| 六安市| 大悟县| 广汉市| 龙门县| 泸定县| 弋阳县| 工布江达县| 闸北区| 五峰| 枞阳县| 青海省| 龙江县| 寿宁县| 马公市| 曲沃县| 揭东县|