﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>语源科技BlogJava-rosial</title><link>http://www.blogjava.net/rosial/</link><description>lost memory</description><language>zh-cn</language><lastBuildDate>Tue, 12 May 2026 08:55:27 GMT</lastBuildDate><pubDate>Tue, 12 May 2026 08:55:27 GMT</pubDate><ttl>60</ttl><item><title>安装j2ee找不到jre的解决办法</title><link>http://www.blogjava.net/rosial/archive/2012/07/07/382478.html</link><dc:creator>rosial</dc:creator><author>rosial</author><pubDate>Sat, 07 Jul 2012 14:07:00 GMT</pubDate><guid>http://www.blogjava.net/rosial/archive/2012/07/07/382478.html</guid><wfw:comment>http://www.blogjava.net/rosial/comments/382478.html</wfw:comment><comments>http://www.blogjava.net/rosial/archive/2012/07/07/382478.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/rosial/comments/commentRss/382478.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/rosial/services/trackbacks/382478.html</trackback:ping><description><![CDATA[换了新本，又想趁机换个新的IDE，结果悲剧出来了&#8230;&#8230;<br />居然死活装不了J2EE，说找不到JRE= =<br /><br />解决方案：<br />1. 装了jdkjre之后，设好参数，你的javahome假设是：D:\Java\jre7;<br />2. 把下载好的j2ee放在某个地方如d盘下；<br />3. 在d盘下toDos，键入：j2ee安装文件名带点exe -j "D:\Java\jre7" 回车<br /><br />这样就可以成功安装了。<img src ="http://www.blogjava.net/rosial/aggbug/382478.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/rosial/" target="_blank">rosial</a> 2012-07-07 22:07 <a href="http://www.blogjava.net/rosial/archive/2012/07/07/382478.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>zz - JDK 环境变量如何设置</title><link>http://www.blogjava.net/rosial/articles/382475.html</link><dc:creator>rosial</dc:creator><author>rosial</author><pubDate>Sat, 07 Jul 2012 12:17:00 GMT</pubDate><guid>http://www.blogjava.net/rosial/articles/382475.html</guid><wfw:comment>http://www.blogjava.net/rosial/comments/382475.html</wfw:comment><comments>http://www.blogjava.net/rosial/articles/382475.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/rosial/comments/commentRss/382475.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/rosial/services/trackbacks/382475.html</trackback:ping><description><![CDATA[<strong style="font-size: 18pt; color: #0000ff;">JDK 环境变量如何设置</strong><p>&nbsp;</p><p>原文地址：</p><div>http://www.cnblogs.com/pricks/archive/2009/05/28/1491346.html</div><p>&nbsp;</p><p>这是讲基础配置最清楚的一篇，适合拿来发给新新手看，不用再多花一秒钟教啦~<br /></p><pre><span style="color: #008000;">　　</span><span style="font-size: 12pt; color: #008000;">首先右键点我的电脑。打开属性。然后选择&#8220;高级&#8221;里面的&#8220;环境变量&#8221;，在新的打开界面中的系统变量里需要设置</span><br /><span style="font-size: 12pt; color: #008000;">三个属性&#8220;java_home&#8221;、&#8220;path&#8221;、&#8220;classpath&#8221;,其中在没安装过jdk的环境下，path属性是本来存在的。而</span><br /><span style="font-size: 12pt; color: #008000;">java_home和classpath是不存在的。</span><br /><span style="font-size: 12pt; color: #008000;">    首先点&#8220;新建&#8221;，然后在变量名写上java_home，顾名其意该变量的含义就是java的安装路径，呵呵，</span><br /><span style="font-size: 12pt; color: #008000;">然后在变量值写入刚才安装的路径&#8220;E:\Java\jdk1.6.0_02&#8221;；</span><br /><span style="font-size: 12pt; color: #008000;">    其次在系统变量里面找到path，然后点编辑，path变量的含义就是系统在任何路径下都可以识别java命令，则变量值为</span><br /><span style="font-size: 12pt; color: #008000;">&#8220;%java_home%\bin;%java_home%\jre\bin&#8221;，(其中&#8220;%java_home%&#8221;的意思为刚才设置java_home的值），也可以直接写</span><br /><span style="font-size: 12pt; color: #008000;">上&#8220;E:\Java\jdk1.6.0_02&#8221;；</span><br /><span style="font-size: 12pt; color: #008000;">    最后再点&#8220;新建&#8221;，然后在变量名上写classpath,该变量的含义是为java加载类(class or lib)路径，只有类</span><br /><span style="font-size: 12pt; color: #008000;">在classpath中，java命令才能识别。其值为&#8220;.;%java_home%\lib;%java_home%\lib\tools.jar (要加.表示当前路径)&#8221;，</span><br /><span style="font-size: 12pt; color: #008000;">与&#8220;%java_home%有相同意思&#8221;</span><br /><br /><span style="font-size: 12pt; color: #008000;">    以上三个变量设置完毕，则按&#8220;确定&#8221;直至属性窗口消失，下来是验证看看安装是否成功。先打开&#8220;开始&#8221;-&gt;&#8220;运行&#8221;，</span><br /><span style="font-size: 12pt; color: #008000;">打入&#8220;cmd&#8221;，进入dos系统界面。然后打&#8220;java -version&#8221;，如果安装成功。系统会显示java的版本信息。</span><br /><br /><span style="font-size: 12pt; color: #008000;">　　另外安装java时，安装jdk 和 jre要有两个目录，安装时都选择在同一目录会出现bin和lib文件覆盖现象，从而出现</span><br /><span style="font-size: 12pt; color: #008000;">无lib\tools.jar文件的现象，到时即使正确设置了环境变量后javac也不可用！！因此安装jdk后一定要看下在jdk\lib下是</span><br /><span style="font-size: 12pt; color: #008000;">否有tools.jar文件，有的话按照上面的方法设置环境变量就ok了 <br /><br /><br /><div>1。 <a href="http://wenwen.soso.com/z/Search.e?sp=S%E5%8F%98%E9%87%8F&amp;ch=w.search.yjjlink&amp;cid=w.search.yjjlink" target="_blank">变量</a>名为JAVA_HOME，内容为"这里面写你的jdk的安装后的绝对路径" <br />2。 变量名为CLASS，内容为".;%JAVA_HOME%\jib\tools.jar" 注意：内容里面的那个是分号，不是冒号；它前面的是点。 <br />3。  变量名为Path， 内容为";%JAVA_HOME%\bin"  注意：内容里面的那个是分号；还有这个变量名已经存在，你只需在内容的最后面添加即刻（也就是说，这个环境你只需编辑，而不用像前面那样新增）；并且这个 变量你一定不要改动里面原先存在的内容，动了的话，有可能系统启动不了，也有可能你的某个软件不能启动了</div><div>http://www.cnblogs.com/chenzhao/articles/2090322.html</div><br /><br /><div>所谓环境变量可以这样理解，把操作系统理解为一个平常的系统，它当调用一个api接口的时候，需要输入参数，就像我们写java代码一样。<br /><br />但我们也知道，一个功能不可能只有一种方法。除了设置环境变量来传递参数之外，还可以有其他的办法，Jdk5及以后的版本就采取了其它的做法。<br /><br />当然，你不是安装的JDK,而是拷贝的别人已安装好的，就需要配置环境变量了。<br /><br />如果你平时都是用eclipse等IDE来写代码，而不是文本文件，就只需要在eclipse里面配置就行了。<br /><br />再说说JDK与JRE的却别，很多人都不知道。<br /><br />JDK是用来编译是用来调用的库，比如java.lang,java.util等都在JDK里面的<br />JRE是用来解释的调用的。如果你是一个用户，你只需要安装JRE就行了<br />如果你是开发者，你只需要安装JDK。<br />JDK里面包含了jre,你可以去JDK的目录下面看看，不是有个JRE吗？<br /><br />那你说，你配置环境变量是编译的时候用，还是用来解释的时候用的？</div><br /></span></pre><img src ="http://www.blogjava.net/rosial/aggbug/382475.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/rosial/" target="_blank">rosial</a> 2012-07-07 20:17 <a href="http://www.blogjava.net/rosial/articles/382475.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>zz - 4用戶端安全:4-3偵測方法與工具:分析方法:webscarab介紹</title><link>http://www.blogjava.net/rosial/articles/381628.html</link><dc:creator>rosial</dc:creator><author>rosial</author><pubDate>Wed, 27 Jun 2012 08:39:00 GMT</pubDate><guid>http://www.blogjava.net/rosial/articles/381628.html</guid><wfw:comment>http://www.blogjava.net/rosial/comments/381628.html</wfw:comment><comments>http://www.blogjava.net/rosial/articles/381628.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/rosial/comments/commentRss/381628.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/rosial/services/trackbacks/381628.html</trackback:ping><description><![CDATA[<h1><a name="webscarab" id="webscarab" style="padding: 0px; margin: 0px; display: block; "><span style="padding: 0px; margin: 0px; background-color: #ffff99; "><br /></span><span style="padding: 0px; margin: 0px; background-color: #ffff99; font-size: 12pt; color: #000000; "><span style="font-weight: normal; background-color: #ffffff; ">原文地址：</span><a href="http://knowledge.twisc.ntust.edu.tw/doku.php?id=4%E7%94%A8%E6%88%B6%E7%AB%AF%E5%AE%89%E5%85%A8:4-3%E5%81%B5%E6%B8%AC%E6%96%B9%E6%B3%95%E8%88%87%E5%B7%A5%E5%85%B7:%E5%88%86%E6%9E%90%E6%96%B9%E6%B3%95:webscarab%E4%BB%8B%E7%B4%B9"><span style="font-size: 12pt; color: #000000; font-weight: normal; background-color: #ffffff; ">http://knowledge.twisc.ntust.edu.tw/doku.php?id=4%E7%94%A8%E6%88%B6%E7%AB%AF%E5%AE%89%E5%85%A8:4-3%E5%81%B5%E6%B8%AC%E6%96%B9%E6%B3%95%E8%88%87%E5%B7%A5%E5%85%B7:%E5%88%86%E6%9E%90%E6%96%B9%E6%B3%</span><span style="background-color: #ffffff; ">95:webscarab%E4%BB%8B%E7%B4%B9</span></a><br /><br />WebScarab</span></a></h1><div style="margin: 0px 0px 0px 3px; color: #333333; font-family: Verdana, 'Lucida Grande', Lucida, Helvetica, Arial, sans-serif; font-size: 13px; line-height: 19px; text-align: justify; background-color: #ffffff; "><ul style="padding: 0px; margin: 0em 1em 2em 3em; line-height: 1.5em; list-style-type: square; list-style-image: none; "><li style="padding: 0px; margin: 0px 0px 0.5em; "><div style="margin: 0px; "><strong style="padding: 0px; margin: 0px; ">對象：</strong>&nbsp;程式設計師/資訊安全人員</div></li><li style="padding: 0px; margin: 0px 0px 0.5em; "><div style="margin: 0px; "><strong style="padding: 0px; margin: 0px; ">難易度：</strong>&nbsp;&#9733;&#9733;&#9733;&#9734;&#9734;</div></li><li style="padding: 0px; margin: 0px 0px 0.5em; "><div style="margin: 0px; "><strong style="padding: 0px; margin: 0px; ">技術新舊：</strong>&nbsp;2010年</div></li><li style="padding: 0px; margin: 0px 0px 0.5em; "><div style="margin: 0px; "><strong style="padding: 0px; margin: 0px; ">閱讀時間：</strong>&nbsp;30分鐘</div></li></ul></div><h2><a name="預備知識" id="預備知識" style="padding: 0px; margin: 0px; ">預備知識</a></h2><div style="margin: 0px 0px 0px 23px; color: #333333; font-family: Verdana, 'Lucida Grande', Lucida, Helvetica, Arial, sans-serif; font-size: 13px; line-height: 19px; text-align: justify; background-color: #ffffff; "><ul style="padding: 0px; margin: 0em 1em 2em 3em; line-height: 1.5em; list-style-type: square; list-style-image: none; "><li style="padding: 0px; margin: 0px 0px 0.5em; "><div style="margin: 0px; ">HTTP通訊協定</div></li></ul></div><h2><a name="簡介" id="簡介" style="padding: 0px; margin: 0px; ">簡介</a></h2><div style="margin: 0px 0px 0px 23px; color: #333333; font-family: Verdana, 'Lucida Grande', Lucida, Helvetica, Arial, sans-serif; font-size: 13px; line-height: 19px; text-align: justify; background-color: #ffffff; "><p style="padding: 0px; margin: 0px 0px 1em; ">　　<span style="padding: 0px; margin: 0px; background-color: #ffff99; ">WebScarab</span>是個分析使用HTTP和HTTPS通訊協定的應用程式。允許使用者檢查和修改瀏覽器發送(Request)給Server的請求和Server回傳(Responses)給瀏覽器的訊息。</p></div><h2><a name="說明" id="說明" style="padding: 0px; margin: 0px; ">說明</a></h2><div style="margin: 0px 0px 0px 23px; color: #333333; font-family: Verdana, 'Lucida Grande', Lucida, Helvetica, Arial, sans-serif; font-size: 13px; line-height: 19px; text-align: justify; background-color: #ffffff; "><p style="padding: 0px; margin: 0px 0px 1em; ">　　<span style="padding: 0px; margin: 0px; background-color: #ffff99; ">WebScarab</span>有許多的功能，先簡單介紹<span style="padding: 0px; margin: 0px; background-color: #ffff99; ">WebScarab</span>如何攔截和修改經由HTTP/S所發送的Requests和Response。&nbsp;<a href="http://knowledge.twisc.ntust.edu.tw/lib/exe/detail.php?id=4%E7%94%A8%E6%88%B6%E7%AB%AF%E5%AE%89%E5%85%A8%3A4-3%E5%81%B5%E6%B8%AC%E6%96%B9%E6%B3%95%E8%88%87%E5%B7%A5%E5%85%B7%3A%E5%88%86%E6%9E%90%E6%96%B9%E6%B3%95%3Awebscarab%E4%BB%8B%E7%B4%B9&amp;media=4%E7%94%A8%E6%88%B6%E7%AB%AF%E5%AE%89%E5%85%A8:4-3%E5%81%B5%E6%B8%AC%E6%96%B9%E6%B3%95%E8%88%87%E5%B7%A5%E5%85%B7:%E5%88%86%E6%9E%90%E6%96%B9%E6%B3%95:webscarab1.png" title="4用戶端安全:4-3偵測方法與工具:分析方法:webscarab1.png" style="padding: 0px; margin: 0px; color: #342d7e; text-decoration: none; "><img src="http://knowledge.twisc.ntust.edu.tw/lib/exe/fetch.php?media=4%E7%94%A8%E6%88%B6%E7%AB%AF%E5%AE%89%E5%85%A8:4-3%E5%81%B5%E6%B8%AC%E6%96%B9%E6%B3%95%E8%88%87%E5%B7%A5%E5%85%B7:%E5%88%86%E6%9E%90%E6%96%B9%E6%B3%95:webscarab1.png" alt="" style="padding: 0px; margin: 3px; border: 0px; " /></a><br style="padding: 0px; margin: 0px; " />(圖一)<br style="padding: 0px; margin: 0px; " /></p><p style="padding: 0px; margin: 0px 0px 1em; ">　　上圖為<span style="padding: 0px; margin: 0px; background-color: #ffff99; ">WebScarab</span>開啟後的畫面，首先介紹Summary。Summary分成兩個部分，上半部份會以樹狀顯示訪問的站點有哪些。下半部份是以表格呈現通過<span style="padding: 0px; margin: 0px; background-color: #ffff99; ">WebScarab</span>所有的會話內容，通常以ID遞減排列，所以靠近表格頂部的是最近的會話。<br style="padding: 0px; margin: 0px; " />　　為了要使用<span style="padding: 0px; margin: 0px; background-color: #ffff99; ">WebScarab</span>，需要到IE的網際網路選項，去修改Proxy的設定。點選「網際網路選項」&#8594;「連線」&#8594;「區域網路設定」，勾選使用Proxy伺服器，在位址輸入&#8220;localhost&#8221;，連接埠輸入&#8220;8008&#8221;。<span style="padding: 0px; margin: 0px; background-color: #ffff99; ">WebScarab</span>預設使用localhost的8008port做為其Proxy，此設定會讓IE將requests傳送到<span style="padding: 0px; margin: 0px; background-color: #ffff99; ">WebScarab</span>。<br style="padding: 0px; margin: 0px; " />　　接著回到IE瀏覽器，並開啟<span style="padding: 0px; margin: 0px; background-color: #ffff99; ">WebScarab</span>，連接到任一網站，就可看到圖一的畫面。你可以看到URL樹，以顯示曾經過<span style="padding: 0px; margin: 0px; background-color: #ffff99; ">WebScarab</span>的所有會話。點擊下方窗口資料表的任一行，會彈出一個視窗，顯示此會話詳細的資料。<br style="padding: 0px; margin: 0px; " /></p><p style="padding: 0px; margin: 0px 0px 1em; "><a href="http://knowledge.twisc.ntust.edu.tw/lib/exe/detail.php?id=4%E7%94%A8%E6%88%B6%E7%AB%AF%E5%AE%89%E5%85%A8%3A4-3%E5%81%B5%E6%B8%AC%E6%96%B9%E6%B3%95%E8%88%87%E5%B7%A5%E5%85%B7%3A%E5%88%86%E6%9E%90%E6%96%B9%E6%B3%95%3Awebscarab%E4%BB%8B%E7%B4%B9&amp;media=4%E7%94%A8%E6%88%B6%E7%AB%AF%E5%AE%89%E5%85%A8:4-3%E5%81%B5%E6%B8%AC%E6%96%B9%E6%B3%95%E8%88%87%E5%B7%A5%E5%85%B7:%E5%88%86%E6%9E%90%E6%96%B9%E6%B3%95:webscarab2.png" title="4用戶端安全:4-3偵測方法與工具:分析方法:webscarab2.png" style="padding: 0px; margin: 0px; color: #342d7e; text-decoration: none; "><img src="http://knowledge.twisc.ntust.edu.tw/lib/exe/fetch.php?media=4%E7%94%A8%E6%88%B6%E7%AB%AF%E5%AE%89%E5%85%A8:4-3%E5%81%B5%E6%B8%AC%E6%96%B9%E6%B3%95%E8%88%87%E5%B7%A5%E5%85%B7:%E5%88%86%E6%9E%90%E6%96%B9%E6%B3%95:webscarab2.png" alt="" style="padding: 0px; margin: 3px; border: 0px; " /></a><br style="padding: 0px; margin: 0px; " /></p><p style="padding: 0px; margin: 0px 0px 1em; ">(圖二)</p><p style="padding: 0px; margin: 0px 0px 1em; ">　　接下來介紹<span style="padding: 0px; margin: 0px; background-color: #ffff99; ">WebScarab</span>如例攔截請求並在它們發送給Server前對其進行修改。<br style="padding: 0px; margin: 0px; " />　　點選<span style="padding: 0px; margin: 0px; background-color: #ffff99; ">WebScarab</span>上Proxy頁面，選擇Manual Edit頁面，勾選「Intercept Requests」，然後選擇要攔截的項目，先以&#8220;POST&#8221;做為範例。<br style="padding: 0px; margin: 0px; " /><a href="http://knowledge.twisc.ntust.edu.tw/lib/exe/detail.php?id=4%E7%94%A8%E6%88%B6%E7%AB%AF%E5%AE%89%E5%85%A8%3A4-3%E5%81%B5%E6%B8%AC%E6%96%B9%E6%B3%95%E8%88%87%E5%B7%A5%E5%85%B7%3A%E5%88%86%E6%9E%90%E6%96%B9%E6%B3%95%3Awebscarab%E4%BB%8B%E7%B4%B9&amp;media=4%E7%94%A8%E6%88%B6%E7%AB%AF%E5%AE%89%E5%85%A8:4-3%E5%81%B5%E6%B8%AC%E6%96%B9%E6%B3%95%E8%88%87%E5%B7%A5%E5%85%B7:%E5%88%86%E6%9E%90%E6%96%B9%E6%B3%95:webscarab3.png" title="4用戶端安全:4-3偵測方法與工具:分析方法:webscarab3.png" style="padding: 0px; margin: 0px; color: #342d7e; text-decoration: none; "><img src="http://knowledge.twisc.ntust.edu.tw/lib/exe/fetch.php?media=4%E7%94%A8%E6%88%B6%E7%AB%AF%E5%AE%89%E5%85%A8:4-3%E5%81%B5%E6%B8%AC%E6%96%B9%E6%B3%95%E8%88%87%E5%B7%A5%E5%85%B7:%E5%88%86%E6%9E%90%E6%96%B9%E6%B3%95:webscarab3.png" alt="" style="padding: 0px; margin: 3px; border: 0px; " /></a><br style="padding: 0px; margin: 0px; " />(圖三)</p><p style="padding: 0px; margin: 0px 0px 1em; ">　　然後回到瀏覽器，隨便點擊任一按鍵，例如在Gmail的登入畫面按登入。這時就可以看到<span style="padding: 0px; margin: 0px; background-color: #ffff99; ">WebScarab</span>在工作列閃爍，顯示有新視窗產生。點選新視窗就會看到以下畫面。&nbsp;<a href="http://knowledge.twisc.ntust.edu.tw/lib/exe/detail.php?id=4%E7%94%A8%E6%88%B6%E7%AB%AF%E5%AE%89%E5%85%A8%3A4-3%E5%81%B5%E6%B8%AC%E6%96%B9%E6%B3%95%E8%88%87%E5%B7%A5%E5%85%B7%3A%E5%88%86%E6%9E%90%E6%96%B9%E6%B3%95%3Awebscarab%E4%BB%8B%E7%B4%B9&amp;media=4%E7%94%A8%E6%88%B6%E7%AB%AF%E5%AE%89%E5%85%A8:4-3%E5%81%B5%E6%B8%AC%E6%96%B9%E6%B3%95%E8%88%87%E5%B7%A5%E5%85%B7:%E5%88%86%E6%9E%90%E6%96%B9%E6%B3%95:webscarab4.png" title="4用戶端安全:4-3偵測方法與工具:分析方法:webscarab4.png" style="padding: 0px; margin: 0px; color: #342d7e; text-decoration: none; "><img src="http://knowledge.twisc.ntust.edu.tw/lib/exe/fetch.php?media=4%E7%94%A8%E6%88%B6%E7%AB%AF%E5%AE%89%E5%85%A8:4-3%E5%81%B5%E6%B8%AC%E6%96%B9%E6%B3%95%E8%88%87%E5%B7%A5%E5%85%B7:%E5%88%86%E6%9E%90%E6%96%B9%E6%B3%95:webscarab4.png" alt="" style="padding: 0px; margin: 3px; border: 0px; " /></a><br style="padding: 0px; margin: 0px; " /></p><p style="padding: 0px; margin: 0px 0px 1em; ">(圖四)</p><p style="padding: 0px; margin: 0px 0px 1em; ">　　你可以看到剛才輸入的使用者名稱及密碼，接著，就可以在此視窗編輯此Request的任何部份了。編輯完畢後，點擊&#8220;Accept changes&#8221;就會將修改後的Request傳送到Server。若是希望取消此次編輯，就點擊&#8220;Cancel changes&#8221;。若是不想傳送此一Request到Server，就點擊&#8220;Abort request&#8221;。或是想一次將全部的攔截視窗都關閉，可選擇&#8220;Cancel All intercepts&#8221;。<br style="padding: 0px; margin: 0px; " />　　<span style="padding: 0px; margin: 0px; background-color: #ffff99; ">WebScarab</span>會一直攔截所有符合指定方式的Request，直到取消「Intercept Requests」。<br style="padding: 0px; margin: 0px; " /></p></div><h2><a name="作者" id="作者" style="padding: 0px; margin: 0px; ">作者</a></h2><div style="margin: 0px 0px 0px 23px; color: #333333; font-family: Verdana, 'Lucida Grande', Lucida, Helvetica, Arial, sans-serif; font-size: 13px; line-height: 19px; text-align: justify; background-color: #ffffff; "><p style="padding: 0px; margin: 0px 0px 1em; ">2011/03/014 江漣真 整理&nbsp;<br style="padding: 0px; margin: 0px; " /></p></div><h2><a name="參考資料" id="參考資料" style="padding: 0px; margin: 0px; ">參考資料</a></h2><div style="margin: 0px 0px 0px 23px; color: #333333; font-family: Verdana, 'Lucida Grande', Lucida, Helvetica, Arial, sans-serif; font-size: 13px; line-height: 19px; text-align: justify; background-color: #ffffff; "><ol style="padding: 0px; margin: 0em 1em 1em 3em; line-height: 1.5em; list-style-image: none; "><li style="padding: 0px; margin: 0px 0px 0.5em; "><div style="margin: 0px; "><a href="http://www.owasp.org/index.php/Category:OWASP_WebScarab_Project" title="http://www.owasp.org/index.php/Category:OWASP_WebScarab_Project" rel="nofollow" style="padding: 1px 0px 1px 18px; margin: 0px; color: purple; text-decoration: none; background-image: url(http://knowledge.twisc.ntust.edu.tw/lib/tpl/arctic/images/urlextern.png); background-color: transparent; background-position: 0px 1px; background-repeat: no-repeat no-repeat; ">http://www.owasp.org/index.php/Category:OWASP_<span style="padding: 0px; margin: 0px; color: #333333; background-color: #ffff99; ">WebScarab</span>_Project</a></div></li></ol></div><img src ="http://www.blogjava.net/rosial/aggbug/381628.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/rosial/" target="_blank">rosial</a> 2012-06-27 16:39 <a href="http://www.blogjava.net/rosial/articles/381628.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>zz - 六种异常处理的陋习</title><link>http://www.blogjava.net/rosial/articles/371337.html</link><dc:creator>rosial</dc:creator><author>rosial</author><pubDate>Tue, 06 Mar 2012 06:51:00 GMT</pubDate><guid>http://www.blogjava.net/rosial/articles/371337.html</guid><wfw:comment>http://www.blogjava.net/rosial/comments/371337.html</wfw:comment><comments>http://www.blogjava.net/rosial/articles/371337.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/rosial/comments/commentRss/371337.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/rosial/services/trackbacks/371337.html</trackback:ping><description><![CDATA[<div><p style="margin-top: 0px; margin-right: 0px; margin-left: 0px; margin-bottom: 14px; color: #000000; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 19px; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; background-color: #ffffff; "><br /></p><p style="margin-top: 0px; margin-right: 0px; margin-left: 0px; margin-bottom: 14px; color: #000000; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 19px; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; background-color: #ffffff; ">你觉得自己是一个Java专家吗？是否肯定自己已经全面掌握了Java的异常处理机制？在下面这段代码中，你能够迅速找出异常处理的六个问题吗？&nbsp;<br /><br /></p><table style="font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; background-color: #ffffff; " align="center" bgcolor="#dadacf" border="1" width="90%"><tbody><tr><td style="font-size: 12px; ">1 OutputStreamWriter out = ...&nbsp;<br />2 java.sql.Connection conn = ...&nbsp;<br />3 try { // &#9336;&nbsp;<br />4 　Statement stat = conn.createStatement();&nbsp;<br />5 　ResultSet rs = stat.executeQuery(&nbsp;<br />6 　　"select uid, name from user");&nbsp;<br />7 　while (rs.next())&nbsp;<br />8 　{&nbsp;<br />9 　　out.println("ID：" + rs.getString("uid") // &#9337;&nbsp;<br />10 　　　"，姓名：" + rs.getString("name"));&nbsp;<br />11 　}&nbsp;<br />12 　conn.close(); // &#9334;&nbsp;<br />13 　out.close();&nbsp;<br />14 }&nbsp;<br />15 catch(Exception ex) // &#9333;&nbsp;<br />16 {&nbsp;<br />17 　ex.printStackTrace(); //&#9332;，&#9335;&nbsp;<br />18 }</td></tr></tbody></table><p style="margin-top: 0px; margin-right: 0px; margin-left: 0px; margin-bottom: 14px; color: #000000; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 19px; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; background-color: #ffffff; "><br />　　作为一个Java程序员，你至少应该能够找出两个问题。但是，如果你不能找出全部六个问题，请继续阅读本文。&nbsp;<br /><br />　　本文讨论的不是Java异常处理的一般性原则，因为这些原则已经被大多数人熟知。我们要做的是分析各种可称为&#8220;反例&#8221;（anti-pattern）的违背优秀编码规范的常见坏习惯，帮助读者熟悉这些典型的反面例子，从而能够在实际工作中敏锐地察觉和避免这些问题。&nbsp;<br /><br />　　<strong>反例之一：丢弃异常&nbsp;</strong><br /><br />　　代码：15行-18行。&nbsp;<br /><br />　　这段代码捕获了异常却不作任何处理，可以算得上Java编程中的杀手。从问题出现的频繁程度和祸害程度来看，它也许可以和C/C++程序的一个恶名远播的问题相提并论??不检查缓冲区是否已满。如果你看到了这种丢弃（而不是抛出）异常的情况，可以百分之九十九地肯定代码存在问题（在极少数情况下，这段代码有存在的理由，但最好加上完整的注释，以免引起别人误解）。&nbsp;<br /><br />　　这段代码的错误在于，异常（几乎）总是意味着某些事情不对劲了，或者说至少发生了某些不寻常的事情，我们不应该对程序发出的求救信号保持沉默和无动于衷。调用一下printStackTrace算不上&#8220;处理异常&#8221;。不错，调用printStackTrace对调试程序有帮助，但程序调试阶段结束之后，printStackTrace就不应再在异常处理模块中担负主要责任了。&nbsp;<br /><br />　　丢弃异常的情形非常普遍。打开JDK的ThreadDeath类的文档，可以看到下面这段说明：&#8220;特别地，虽然出现ThreadDeath是一种&#8216;正常的情形&#8217;，但ThreadDeath类是Error而不是Exception的子类，因为许多应用会捕获所有的Exception然后丢弃它不再理睬。&#8221;这段话的意思是，虽然ThreadDeath代表的是一种普通的问题，但鉴于许多应用会试图捕获所有异常然后不予以适当的处理，所以JDK把ThreadDeath定义成了Error的子类，因为Error类代表的是一般的应用不应该去捕获的严重问题。可见，丢弃异常这一坏习惯是如此常见，它甚至已经影响到了Java本身的设计。&nbsp;<br /><br />　　那么，应该怎样改正呢？主要有四个选择：&nbsp;<br /><br />　　1、处理异常。针对该异常采取一些行动，例如修正问题、提醒某个人或进行其他一些处理，要根据具体的情形确定应该采取的动作。再次说明，调用printStackTrace算不上已经&#8220;处理好了异常&#8221;。&nbsp;<br /><br />　　2、重新抛出异常。处理异常的代码在分析异常之后，认为自己不能处理它，重新抛出异常也不失为一种选择。&nbsp;<br /><br />　　3、把该异常转换成另一种异常。大多数情况下，这是指把一个低级的异常转换成应用级的异常（其含义更容易被用户了解的异常）。&nbsp;<br /><br />　　4、不要捕获异常。&nbsp;<br /><br />　　结论一：既然捕获了异常，就要对它进行适当的处理。不要捕获异常之后又把它丢弃，不予理睬。&nbsp;<br /><br />　　<strong>反例之二：不指定具体的异常&nbsp;</strong><br /><br />　　代码：15行。&nbsp;<br /><br />　　许多时候人们会被这样一种&#8220;美妙的&#8221;想法吸引：用一个catch语句捕获所有的异常。最常见的情形就是使用catch(Exception ex)语句。但实际上，在绝大多数情况下，这种做法不值得提倡。为什么呢？&nbsp;<br /><br />　　要理解其原因，我们必须回顾一下catch语句的用途。catch语句表示我们预期会出现某种异常，而且希望能够处理该异常。异常类的作用就是告诉Java编译器我们想要处理的是哪一种异常。由于绝大多数异常都直接或间接从java.lang.Exception派生，catch(Exception ex)就相当于说我们想要处理几乎所有的异常。&nbsp;<br /><br />　　再来看看前面的代码例子。我们真正想要捕获的异常是什么呢？最明显的一个是SQLException，这是JDBC操作中常见的异常。另一个可能的异常是IOException，因为它要操作OutputStreamWriter。显然，在同一个catch块中处理这两种截然不同的异常是不合适的。如果用两个catch块分别捕获SQLException和IOException就要好多了。这就是说，catch语句应当尽量指定具体的异常类型，而不应该指定涵盖范围太广的Exception类。&nbsp;<br /><br />　　另一方面，除了这两个特定的异常，还有其他许多异常也可能出现。例如，如果由于某种原因，executeQuery返回了null，该怎么办？答案是让它们继续抛出，即不必捕获也不必处理。实际上，我们不能也不应该去捕获可能出现的所有异常，程序的其他地方还有捕获异常的机会??直至最后由JVM处理。&nbsp;<br /><br />　　结论二：在catch语句中尽可能指定具体的异常类型，必要时使用多个catch。不要试图处理所有可能出现的异常。&nbsp;<br /><br />　　<strong>反例之三：占用资源不释放&nbsp;</strong><br /><br />　　代码：3行-14行。&nbsp;<br /><br />　　异常改变了程序正常的执行流程。这个道理虽然简单，却常常被人们忽视。如果程序用到了文件、Socket、JDBC连接之类的资源，即使遇到了异常，也要正确释放占用的资源。为此，Java提供了一个简化这类操作的关键词finally。&nbsp;<br /><br />　　finally是样好东西：不管是否出现了异常，Finally保证在try/catch/finally块结束之前，执行清理任务的代码总是有机会执行。遗憾的是有些人却不习惯使用finally。&nbsp;<br /><br />　　当然，编写finally块应当多加小心，特别是要注意在finally块之内抛出的异常??这是执行清理任务的最后机会，尽量不要再有难以处理的错误。&nbsp;<br /><br />　　结论三：保证所有资源都被正确释放。充分运用finally关键词。</p><p style="margin-top: 0px; margin-right: 0px; margin-left: 0px; margin-bottom: 14px; color: #000000; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 19px; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; background-color: #ffffff; "><strong>反例之四：不说明异常的详细信息&nbsp;<br /><br /></strong>　　代码：3行-18行。&nbsp;<br /><br />　　仔细观察这段代码：如果循环内部出现了异常，会发生什么事情？我们可以得到足够的信息判断循环内部出错的原因吗？不能。我们只能知道当前正在处理的类发生了某种错误，但却不能获得任何信息判断导致当前错误的原因。&nbsp;<br /><br />　　printStackTrace的堆栈跟踪功能显示出程序运行到当前类的执行流程，但只提供了一些最基本的信息，未能说明实际导致错误的原因，同时也不易解读。&nbsp;<br /><br />　　因此，在出现异常时，最好能够提供一些文字信息，例如当前正在执行的类、方法和其他状态信息，包括以一种更适合阅读的方式整理和组织printStackTrace提供的信息。&nbsp;<br /><br />　　结论四：在异常处理模块中提供适量的错误原因信息，组织错误信息使其易于理解和阅读。&nbsp;<br /><br />　　<strong>反例之五：过于庞大的try块&nbsp;</strong><br /><br />　　代码：3行-14行。&nbsp;<br /><br />　　经常可以看到有人把大量的代码放入单个try块，实际上这不是好习惯。这种现象之所以常见，原因就在于有些人图省事，不愿花时间分析一大块代码中哪几行代码会抛出异常、异常的具体类型是什么。把大量的语句装入单个巨大的try块就象是出门旅游时把所有日常用品塞入一个大箱子，虽然东西是带上了，但要找出来可不容易。&nbsp;<br /><br />　　一些新手常常把大量的代码放入单个try块，然后再在catch语句中声明Exception，而不是分离各个可能出现异常的段落并分别捕获其异常。这种做法为分析程序抛出异常的原因带来了困难，因为一大段代码中有太多的地方可能抛出Exception。&nbsp;<br /><br />　　结论五：尽量减小try块的体积。&nbsp;<br /><br />　　<strong>反例之六：输出数据不完整</strong>&nbsp;<br /><br />　　代码：7行-11行。&nbsp;<br /><br />　　不完整的数据是Java程序的隐形杀手。仔细观察这段代码，考虑一下如果循环的中间抛出了异常，会发生什么事情。循环的执行当然是要被打断的，其次，catch块会执行??就这些，再也没有其他动作了。已经输出的数据怎么办？使用这些数据的人或设备将收到一份不完整的（因而也是错误的）数据，却得不到任何有关这份数据是否完整的提示。对于有些系统来说，数据不完整可能比系统停止运行带来更大的损失。&nbsp;<br /><br />　　较为理想的处置办法是向输出设备写一些信息，声明数据的不完整性；另一种可能有效的办法是，先缓冲要输出的数据，准备好全部数据之后再一次性输出。&nbsp;<br /><br />　　结论六：全面考虑可能出现的异常以及这些异常对执行流程的影响。&nbsp;<br /><br />　　<strong>改写后的代码</strong>&nbsp;<br /><br />　　根据上面的讨论，下面给出改写后的代码。也许有人会说它稍微有点?嗦，但是它有了比较完备的异常处理机制。&nbsp;<br /><br /></p><table align="center" bgcolor="#dadacf" border="1" width="90%"><tbody><tr><td style="font-size: 12px; ">OutputStreamWriter out = ...&nbsp;<br />java.sql.Connection conn = ...&nbsp;<br />try {&nbsp;<br />　Statement stat = conn.createStatement();&nbsp;<br />　ResultSet rs = stat.executeQuery(&nbsp;<br />　　"select uid, name from user");&nbsp;<br />　while (rs.next())&nbsp;<br />　{&nbsp;<br />　　out.println("ID：" + rs.getString("uid") + "，姓名: " + rs.getString("name"));&nbsp;<br />　}&nbsp;<br />}&nbsp;<br />catch(SQLException sqlex)&nbsp;<br />{&nbsp;<br />　out.println("警告：数据不完整");&nbsp;<br />　throw new ApplicationException("读取数据时出现SQL错误", sqlex);&nbsp;<br />}&nbsp;<br />catch(IOException ioex)&nbsp;<br />{&nbsp;<br />　throw new ApplicationException("写入数据时出现IO错误", ioex);&nbsp;<br />}&nbsp;<br />finally&nbsp;<br />{&nbsp;<br />　if (conn != null) {&nbsp;<br />　　try {&nbsp;<br />　　　conn.close();&nbsp;<br />　　}&nbsp;<br />　　catch(SQLException sqlex2)&nbsp;<br />　　{&nbsp;<br />　　　System.err(this.getClass().getName() + ".mymethod - 不能关闭数据库连接: " + sqlex2.toString());&nbsp;<br />　　}&nbsp;<br />　}&nbsp;<br /><br />　if (out != null) {&nbsp;<br />　　try {&nbsp;<br />　　　out.close();&nbsp;<br />　　}&nbsp;<br />　　catch(IOException ioex2)&nbsp;<br />　　{&nbsp;<br />　　　System.err(this.getClass().getName() + ".mymethod - 不能关闭输出文件" + ioex2.toString());&nbsp;<br />　　}&nbsp;<br />　}&nbsp;<br />}</td></tr></tbody></table><br />　　本文的结论不是放之四海皆准的教条，有时常识和经验才是最好的老师。如果你对自己的做法没有百分之百的信心，务必加上详细、全面的注释。&nbsp;<br /><br />　　另一方面，不要笑话这些错误，不妨问问你自己是否真地彻底摆脱了这些坏习惯。即使最有经验的程序员偶尔也会误入歧途，原因很简单，因为它们确确实实带来了&#8220;方便&#8221;。所有这些反例都可以看作Java编程世界的恶魔，它们美丽动人，无孔不入，时刻诱惑着你。也许有人会认为这些都属于鸡皮蒜毛的小事，不足挂齿，但请记住：勿以恶小而为之，勿以善小而不为。<p><br /></p></div><img src ="http://www.blogjava.net/rosial/aggbug/371337.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/rosial/" target="_blank">rosial</a> 2012-03-06 14:51 <a href="http://www.blogjava.net/rosial/articles/371337.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>zz - Java 流（Stream）简介：1、基本的输入流和输出流</title><link>http://www.blogjava.net/rosial/articles/371154.html</link><dc:creator>rosial</dc:creator><author>rosial</author><pubDate>Fri, 02 Mar 2012 12:20:00 GMT</pubDate><guid>http://www.blogjava.net/rosial/articles/371154.html</guid><wfw:comment>http://www.blogjava.net/rosial/comments/371154.html</wfw:comment><comments>http://www.blogjava.net/rosial/articles/371154.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/rosial/comments/commentRss/371154.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/rosial/services/trackbacks/371154.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 原作者为csdn上的 YidingHehttp://blog.csdn.net/YidingHe本人打算写几篇文章，介绍一下流。本文是针对初学者的，加上本人水平有限，所以不敢说写得很高深。如果你是初学者，而且对流这个东西很头疼，你就应该看看这个。&nbsp;本文发表在：http://blog.csdn.net/YidingHe，转载请保留出处。&nbsp;&nbsp;&nbsp;流是 Java 中...&nbsp;&nbsp;<a href='http://www.blogjava.net/rosial/articles/371154.html'>阅读全文</a><img src ="http://www.blogjava.net/rosial/aggbug/371154.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/rosial/" target="_blank">rosial</a> 2012-03-02 20:20 <a href="http://www.blogjava.net/rosial/articles/371154.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>zz - 谈自动化测试与CI中一些常见的谬见</title><link>http://www.blogjava.net/rosial/articles/371078.html</link><dc:creator>rosial</dc:creator><author>rosial</author><pubDate>Thu, 01 Mar 2012 06:38:00 GMT</pubDate><guid>http://www.blogjava.net/rosial/articles/371078.html</guid><wfw:comment>http://www.blogjava.net/rosial/comments/371078.html</wfw:comment><comments>http://www.blogjava.net/rosial/articles/371078.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/rosial/comments/commentRss/371078.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/rosial/services/trackbacks/371078.html</trackback:ping><description><![CDATA[作者：<div><strong id="ownernick" style="color: #909090; font-family: 宋体; font-size: 14px; font-style: normal; font-variant: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: center; text-indent: 0px; text-transform: none; white-space: nowrap; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; background-color: #d5e7b7; ">flybird88</strong></div>转自：<div><a href="http://blog.sina.com.cn/s/blog_5399c78401011kft.html">http://blog.sina.com.cn/s/blog_5399c78401011kft.html</a></div><br /><div><div style="color: #555555; font-family: simsun; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 21px; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; background-color: #d5e7b7; "><span style="word-wrap: normal; word-break: normal; line-height: 18px; font-size: 12px; ">现在对于自动化测试与CI往往有一些很常见的谬见，包括一些专门从事相关工作的人都未必清楚。在实际的工作中感触颇深，所以想撰文讨论一下。</span></div><div style="color: #555555; font-family: simsun; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 21px; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; background-color: #d5e7b7; "><span style="word-wrap: normal; word-break: normal; line-height: 18px; font-size: 12px; ">第一，自动化测试就是给CI服务的，或者自动化测试不太能发现问题。</span></div><div style="color: #555555; font-family: simsun; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 21px; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; background-color: #d5e7b7; "><span style="word-wrap: normal; word-break: normal; line-height: 18px; font-size: 12px; ">持有这种观点的人，建议他们去看看Google或者Microsoft的相关测试研究的文章，或者GTAC（ Google Test Automation Conference),也许可以拓宽我们考虑这个问题的思路。</span></div><div style="color: #555555; font-family: simsun; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 21px; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; background-color: #d5e7b7; "><span style="word-wrap: normal; word-break: normal; line-height: 18px; font-size: 12px; ">他们的测试对象是搜索引擎，海量的数据库信息，或者提供的各种服务，比如Google Map，Navigation。他们研究的是搜索引擎对于海量的数据库处理起来是否有效，搜索结果是否准确 。</span></div><div style="color: #555555; font-family: simsun; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 21px; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; background-color: #d5e7b7; "><span style="word-wrap: normal; word-break: normal; line-height: 18px; font-size: 12px; "><br /></span></div><div style="color: #555555; font-family: simsun; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 21px; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; background-color: #d5e7b7; "><span style="word-wrap: normal; word-break: normal; line-height: 18px; font-size: 12px; ">下面举几个例子：</span></div><div style="color: #555555; font-family: simsun; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 21px; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; background-color: #d5e7b7; "><span style="word-wrap: normal; word-break: normal; line-height: 18px; font-size: 12px; ">比如Google会提供一种 &#8216;Auto Completion'的功能，你只要在搜索框里敲入一个词，google会根据与这个词的相关性大小，以及该关键词被搜索的热度，自动补全一些关键词，并提示给你。这样，你就可以参考或者直接用别人的搜索条件。那大家有没有考虑过，这种功能应该如何测试呢？</span></div><div style="color: #555555; font-family: simsun; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 21px; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; background-color: #d5e7b7; "><span style="word-wrap: normal; word-break: normal; line-height: 18px; font-size: 12px; ">还有导航系统，怎么确保从A点到B点找出来的路径都是正确的呢？而不是说你要找一个当地的餐馆，导航却告诉你要来一次跨国旅行呢？</span></div><div style="color: #555555; font-family: simsun; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 21px; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; background-color: #d5e7b7; "><span style="word-wrap: normal; word-break: normal; line-height: 18px; font-size: 12px; "><br /></span></div><div style="color: #555555; font-family: simsun; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 21px; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; background-color: #d5e7b7; "><span style="word-wrap: normal; word-break: normal; line-height: 18px; font-size: 12px; ">面对这些海量的测试数据，并且基本上也无法预先给不同的测试数据定义好期望的测试结果。所以他们无法采用我们这样的静态的自动化测试，而且通常Manual Testing也无法帮助他们解决问题， 他们必须采用动态的大规模的自动化测试，或者叫计算计辅助测试。</span></div><div style="color: #555555; font-family: simsun; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 21px; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; background-color: #d5e7b7; "><span style="word-wrap: normal; word-break: normal; line-height: 18px; font-size: 12px; "><br /></span></div><div style="color: #555555; font-family: simsun; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 21px; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; background-color: #d5e7b7; "><span style="word-wrap: normal; word-break: normal; line-height: 18px; font-size: 12px; "><br /></span></div><div style="color: #555555; font-family: simsun; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 21px; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; background-color: #d5e7b7; "><span style="word-wrap: normal; word-break: normal; line-height: 18px; font-size: 12px; ">他们的做法就是采取一种叫HBT( Heuristics Based Testing）的技术，测试工程师找出一些测试是否成功的判断法则，而不是像传统的自动化测试一定要明确规定静态的期望结果，并把这种判断规则用代码实现。</span></div><div style="color: #555555; font-family: simsun; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 21px; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; background-color: #d5e7b7; "><span style="word-wrap: normal; word-break: normal; line-height: 18px; font-size: 12px; ">通过这种方法，再加上一些并行的测试技术，他们也许一天可测上千万个case，并且在一种判断法则已经不太能有效地发现问题的时候，可以随时调整或者寻找新的判断成功与否的法则。</span></div><div style="color: #555555; font-family: simsun; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 21px; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; background-color: #d5e7b7; "><span style="word-wrap: normal; word-break: normal; line-height: 18px; font-size: 12px; ">而寻找 &#8220;测试是否成功的判断法则&#8221;，也就是常说的Test Oracle的时候,则很类似传统手工测试做manual exploratory testing的过程。测试人员做手工测试的时候，不是重复地去敲键盘，点鼠标，而是寻找系统的失效模型，然后利用自动化测试技术实现，并把这个失效模型放大到尽可能大的范围。 这部分工作，往往是测试工作中最有意思，最有创造性，往往也是最考测试人员功力的。</span></div><div style="color: #555555; font-family: simsun; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 21px; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; background-color: #d5e7b7; "><span style="word-wrap: normal; word-break: normal; line-height: 18px; font-size: 12px; ">我曾经看过一个他们的例子，Microsoft 的Principal Test Engineer写的，他们用这种方法，一天执行了2200万个测试用例，发现了20多个可能的问题，然后和相关stakeholder讨论。</span></div><div style="color: #555555; font-family: simsun; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 21px; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; background-color: #d5e7b7; "><span style="word-wrap: normal; word-break: normal; line-height: 18px; font-size: 12px; ">从上面的例子可以看到，Test Automation其实完全不受限于CI这种模式的下的测试，完全可以借助自动化测试的手段来做Exploratory Testing.</span></div><div style="color: #555555; font-family: simsun; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 21px; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; background-color: #d5e7b7; "><span style="word-wrap: normal; word-break: normal; line-height: 18px; font-size: 12px; ">第二：CI中的测试一定要保证测试的全覆盖。</span></div><div style="color: #555555; font-family: simsun; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 21px; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; background-color: #d5e7b7; "><span style="word-wrap: normal; word-break: normal; line-height: 18px; font-size: 12px; ">&nbsp;<wbr>&nbsp;首先，测试的全覆盖本来就是一个伪命题，从来也没有一种测试可以做到全覆盖。测试人员要解决的是在测试设备有限，测试人员有限，测试时间也有限的情况下，如何能够让组织在测试的投入上，达到最高的ROI。</span></div><div style="color: #555555; font-family: simsun; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 21px; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; background-color: #d5e7b7; "><span style="word-wrap: normal; word-break: normal; line-height: 18px; font-size: 12px; ">&nbsp;<wbr>&nbsp;然后回到CI，我们来看一下CI的目的到底是什么。</span></div><div style="color: #555555; font-family: simsun; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 21px; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; background-color: #d5e7b7; "><span style="word-wrap: normal; word-break: normal; line-height: 18px; font-size: 12px; ">在传统的开发模式下，软件组织在Integration的时候往往会发现模块的接口定义或者理解有不一致，然后需要返工，甚至因此要改模块的内部设计。在各个模块都各自完成以后，想让他们在一起能工作，给客户提供一个完整的功能，往往还要等待很长的时间</span></div><div style="color: #555555; font-family: simsun; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 21px; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; background-color: #d5e7b7; "><span style="word-wrap: normal; word-break: normal; line-height: 18px; font-size: 12px; ">既然集成这么麻烦，那我们就提倡尽早集成,尽快测试，以期待尽快发现问题。同时开发人员在实现代码的时候，如果能够尽快给他们的实现提供反馈，这对他们避免在后来的开发中犯同样的错误，也是非常重要的。如果这种反馈的成本比较低，那我们就可以让这种反馈尽可能频繁。</span></div><div style="color: #555555; font-family: simsun; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 21px; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; background-color: #d5e7b7; "><span style="word-wrap: normal; word-break: normal; line-height: 18px; font-size: 12px; ">具体来说，如果让尽可能多的测试都自动化了，那我们在降低反馈的成本上就走出了第一步，也是非常重要的一步。</span></div><div style="color: #555555; font-family: simsun; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 21px; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; background-color: #d5e7b7; "><span style="word-wrap: normal; word-break: normal; line-height: 18px; font-size: 12px; ">但是大家要思考一下，反馈的速度，频率和反馈的价值是不是完全等同？</span></div><div style="color: #555555; font-family: simsun; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 21px; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; background-color: #d5e7b7; "><span style="word-wrap: normal; word-break: normal; line-height: 18px; font-size: 12px; ">开发人员的开发过程其实就是一个不断犯错误，又不断纠正的过程。</span></div><div style="color: #555555; font-family: simsun; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 21px; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; background-color: #d5e7b7; "><span style="word-wrap: normal; word-break: normal; line-height: 18px; font-size: 12px; ">比如说IDE会频繁告诉他们的一些语法错误，然后在编译链接的时候又会发现一些问题，然后在执行UT的时候又会发现一些问题，然后在后面的Smoke Testing，Function Testing，System Testing又会得到一些反馈，然后从最终的客户那里会得到更进一步的反馈。</span></div><div style="color: #555555; font-family: simsun; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 21px; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; background-color: #d5e7b7; "><span style="word-wrap: normal; word-break: normal; line-height: 18px; font-size: 12px; ">随着软件技术的发展，比如更好的IDE，更好的UT，更好的自动化测试，开发人员在不断地降低得到反馈的成本，提高反馈的效率。但是，我们可以问问周边的开发人员，特别是那些资深的开发人员，在他们的开发生涯中，让他们印象最深的一个Bug，是怎么发现的？</span></div><div style="color: #555555; font-family: simsun; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 21px; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; background-color: #d5e7b7; "><span style="word-wrap: normal; word-break: normal; line-height: 18px; font-size: 12px; ">我会怀疑让开发人员得到的一个印象很深的Bug，一个真正有价值的反馈，往往是一个好的测试人员给他的。</span></div><div style="color: #555555; font-family: simsun; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 21px; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; background-color: #d5e7b7; "><span style="word-wrap: normal; word-break: normal; line-height: 18px; font-size: 12px; ">在我们的组织里，一个好的测试人员是很受开发人员尊重的，因为他不光光是发现产品Bug那么简单，他还不断地给开发人员提供有价值的反馈，不断地让开发人员以该更加周全思路来考虑问题，也促使开发人员不断地成长。</span></div><div style="color: #555555; font-family: simsun; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 21px; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; background-color: #d5e7b7; "><span style="word-wrap: normal; word-break: normal; line-height: 18px; font-size: 12px; "><br /></span></div><div style="color: #555555; font-family: simsun; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 21px; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; background-color: #d5e7b7; "><span style="word-wrap: normal; word-break: normal; line-height: 18px; font-size: 12px; ">但是CI模式下完全依赖机器的执行，不强调人的介入的自动化测试，会是给开发人员提供反馈的唯一途径吗？</span></div><div style="color: #555555; font-family: simsun; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 21px; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; background-color: #d5e7b7; "><span style="word-wrap: normal; word-break: normal; line-height: 18px; font-size: 12px; ">通过我们的经验来看：</span></div><div style="color: #555555; font-family: simsun; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 21px; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; background-color: #d5e7b7; "><span style="word-wrap: normal; word-break: normal; line-height: 18px; font-size: 12px; ">1. 有些team抱怨这种模式的测试，我们也叫CRT( Continuous Regression Test)基本发现不了软件问题。</span></div><div style="color: #555555; font-family: simsun; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 21px; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; background-color: #d5e7b7; "><span style="word-wrap: normal; word-break: normal; line-height: 18px; font-size: 12px; ">2. 个别Team的经验是CRT可以帮助他们发现很多问题，但估计和模块工作的领域有关，比如该模块本身就是问题比较多的模块。</span></div><div style="color: #555555; font-family: simsun; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 21px; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; background-color: #d5e7b7; "><span style="word-wrap: normal; word-break: normal; line-height: 18px; font-size: 12px; ">3.即便是上述第2种情况的模块，也发现许多软件深层次的问题，比如一些设计上考虑不太周到的地方，往往也是一些Senior Tester才能发现的。</span></div><div style="color: #555555; font-family: simsun; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 21px; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; background-color: #d5e7b7; "><span style="word-wrap: normal; word-break: normal; line-height: 18px; font-size: 12px; ">4.往往一个测试中发现的问题，在另外一些测试用例里面会被重复发现。意味着我们的测试用例发现问题的能力往往是有冗余的。</span></div><div style="color: #555555; font-family: simsun; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 21px; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; background-color: #d5e7b7; "><span style="word-wrap: normal; word-break: normal; line-height: 18px; font-size: 12px; "><br /></span></div><div style="color: #555555; font-family: simsun; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 21px; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; background-color: #d5e7b7; "><span style="word-wrap: normal; word-break: normal; line-height: 18px; font-size: 12px; "><br /></span></div><div style="color: #555555; font-family: simsun; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 21px; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; background-color: #d5e7b7; "><span style="word-wrap: normal; word-break: normal; line-height: 18px; font-size: 12px; ">在这种情况下，再强调在CI的模式下要保证测试的全覆盖，我们来看一下会给我们带来什么。</span></div><div style="color: #555555; font-family: simsun; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 21px; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; background-color: #d5e7b7; "><span style="word-wrap: normal; word-break: normal; line-height: 18px; font-size: 12px; ">首先，你的测试用例越加越多，你的测试周期势必越来越长，也就无法给他们提供及时的反馈。而CI的精华之一就是强调给开发人员提供及时的反馈。</span></div><div style="color: #555555; font-family: simsun; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 21px; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; background-color: #d5e7b7; "><span style="word-wrap: normal; word-break: normal; line-height: 18px; font-size: 12px; ">其二, 如果你考虑并行测试的话，势必要增大测试设备的投入。在电信领域，测试设备往往是很贵的，往往比请几个测试人员还贵。当你的自动化测试不能持续给开发人员提供有价值和有深度的反馈，你还不断要求管理层给你加大测试的投入，往往也是不现实的。根据我们的经验，很多采用静态测试技术的自动化项目，往往都会碰到类似的问题。</span></div><div style="color: #555555; font-family: simsun; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 21px; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; background-color: #d5e7b7; "><span style="word-wrap: normal; word-break: normal; line-height: 18px; font-size: 12px; "><br /></span></div><div style="color: #555555; font-family: simsun; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 21px; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; background-color: #d5e7b7; "><span style="word-wrap: normal; word-break: normal; line-height: 18px; font-size: 12px; ">所以CI天生是用来解决Integration的问题的，因为Integration给软件开发带来了很多的问题，是开发工作中很大的一个bottleneck，所以采取了Continuous Integration的方式去做。而Test Coverage则是测试中另外一个很难解决的问题，意指在测试阶段尽可能保证全面的测试覆盖，以避免软件Deploy到客户现场，被客户发现问题。CI作为一种很好的Practice，应该被我们很好地应用，但是如果片面追求CI的Test Coverage，反而有可能会丧失掉CI本身的优势。</span></div></div><img src ="http://www.blogjava.net/rosial/aggbug/371078.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/rosial/" target="_blank">rosial</a> 2012-03-01 14:38 <a href="http://www.blogjava.net/rosial/articles/371078.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Violations(多数内容来自他人blog与论坛讨论)</title><link>http://www.blogjava.net/rosial/archive/2012/02/27/370865.html</link><dc:creator>rosial</dc:creator><author>rosial</author><pubDate>Mon, 27 Feb 2012 10:43:00 GMT</pubDate><guid>http://www.blogjava.net/rosial/archive/2012/02/27/370865.html</guid><wfw:comment>http://www.blogjava.net/rosial/comments/370865.html</wfw:comment><comments>http://www.blogjava.net/rosial/archive/2012/02/27/370865.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/rosial/comments/commentRss/370865.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/rosial/services/trackbacks/370865.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: Critical!1. Findbugs&#8212;&#8212;Dodgy - Dead store to local variable&nbsp;例如：String abc = "abc";&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String xyz = new String();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; xyz = abc;编译肯定...&nbsp;&nbsp;<a href='http://www.blogjava.net/rosial/archive/2012/02/27/370865.html'>阅读全文</a><img src ="http://www.blogjava.net/rosial/aggbug/370865.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/rosial/" target="_blank">rosial</a> 2012-02-27 18:43 <a href="http://www.blogjava.net/rosial/archive/2012/02/27/370865.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>maven的一些问题</title><link>http://www.blogjava.net/rosial/archive/2012/02/22/370536.html</link><dc:creator>rosial</dc:creator><author>rosial</author><pubDate>Wed, 22 Feb 2012 10:39:00 GMT</pubDate><guid>http://www.blogjava.net/rosial/archive/2012/02/22/370536.html</guid><wfw:comment>http://www.blogjava.net/rosial/comments/370536.html</wfw:comment><comments>http://www.blogjava.net/rosial/archive/2012/02/22/370536.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/rosial/comments/commentRss/370536.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/rosial/services/trackbacks/370536.html</trackback:ping><description><![CDATA[<div>.m2\repository\com\公司项目</div>清除以上文件夹的内容，再重新打包，可以解决大部分莫名其妙的包找不到的问题。<br /><br />在eclipse里导入项目，enable maven有时会不管用，仍然找不到dependency。需要在项目pom同级的directory下找到&#8220;.classpath&#8221;文件，手动加入maven如&#8220;&lt;classpathentry kind="con" path="org.maven.ide.eclipse.MAVEN2_CLASSPATH_CONTAINER"/&gt;&#8221;。这是由于eclipse的bug导致的。<img src ="http://www.blogjava.net/rosial/aggbug/370536.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/rosial/" target="_blank">rosial</a> 2012-02-22 18:39 <a href="http://www.blogjava.net/rosial/archive/2012/02/22/370536.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>sonar 在maven project下的安装与运行</title><link>http://www.blogjava.net/rosial/archive/2012/01/16/368609.html</link><dc:creator>rosial</dc:creator><author>rosial</author><pubDate>Mon, 16 Jan 2012 11:59:00 GMT</pubDate><guid>http://www.blogjava.net/rosial/archive/2012/01/16/368609.html</guid><wfw:comment>http://www.blogjava.net/rosial/comments/368609.html</wfw:comment><comments>http://www.blogjava.net/rosial/archive/2012/01/16/368609.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/rosial/comments/commentRss/368609.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/rosial/services/trackbacks/368609.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 1. 下载sonar：http://www.sonarsource.org/downloads/2. 随便放到一个地方，解压即可。做为winXP32的用户，直接进sonar-2.12\bin\windows-x86-32文件夹，run&nbsp;StartSonar.bat 。电脑情况像我一样悲催的用户多等一会儿，不要急于下一步，有可能导致出错。3. 确保你的project是maven的（ant等...&nbsp;&nbsp;<a href='http://www.blogjava.net/rosial/archive/2012/01/16/368609.html'>阅读全文</a><img src ="http://www.blogjava.net/rosial/aggbug/368609.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/rosial/" target="_blank">rosial</a> 2012-01-16 19:59 <a href="http://www.blogjava.net/rosial/archive/2012/01/16/368609.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>zz - JAVA SSH 框架介绍</title><link>http://www.blogjava.net/rosial/articles/365509.html</link><dc:creator>rosial</dc:creator><author>rosial</author><pubDate>Sun, 04 Dec 2011 09:34:00 GMT</pubDate><guid>http://www.blogjava.net/rosial/articles/365509.html</guid><wfw:comment>http://www.blogjava.net/rosial/comments/365509.html</wfw:comment><comments>http://www.blogjava.net/rosial/articles/365509.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/rosial/comments/commentRss/365509.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/rosial/services/trackbacks/365509.html</trackback:ping><description><![CDATA[<div><span style="font-family: Arial; line-height: 18px; font-size: 10px; color: #333333; "><table style="table-layout: fixed; width: 970px; "><tbody><tr><td style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: 18px; "><div id="blog_text" style="font-family: Arial; word-wrap: break-word; word-break: normal; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 14px; line-height: 20px; color: #625b49; overflow-x: hidden; overflow-y: hidden; position: static; ">原帖地址：<span class="Apple-style-span" style="font-size: 12.5px; "><a href="http://hi.baidu.com/hahalgj/blog/item/5d773647067846056a63e556.html">http://hi.baidu.com/hahalgj/blog/item/5d773647067846056a63e556.html</a></span><br /><br /><br />JAVA SSH框架在Struts + Spring + Hibernate的组合框架模式中，三者各自的特点都是什么？&nbsp;<br style="line-height: normal; " /><br style="line-height: normal; " />Struts 的MVC设计模式可以使我们的逻辑变得很清晰。&nbsp;<br style="line-height: normal; " />Spring 的IOC和AOP可以使我们的产品在最大限度上解藕。&nbsp;<br style="line-height: normal; " />hibernate的当然就是实体对象的持久化了&nbsp;<br style="line-height: normal; " /><br style="line-height: normal; " />典型的J2EE三层结构，分为表现层、中间层（业务逻辑层）和数据服务层。三层体系将业务规则、数据访问及合法性校验等工作放在中间层处理。客户端不直接与数据库交互，而是通过组件与中间层建立连接，再由中间层与数据库交互。&nbsp;<br style="line-height: normal; " /><br style="line-height: normal; " />表现层是传统的JSP技术，自1999年问世以来，经过多年的发展，其广泛的应用和稳定的表现，为其作为表现层技术打下了坚实的基础。&nbsp;<br style="line-height: normal; " /><br style="line-height: normal; " />中间层采用的是流行的Spring+Hibernate，为了将控制层与业务逻辑层分离，又细分为以下几种。&nbsp;<br style="line-height: normal; " /><br style="line-height: normal; " />Web层，就是MVC模式里面的&#8220;C&#8221;（controller），负责控制业务逻辑层与表现层的交互，调用业务逻辑层，并将业务数据返回给表现层作组织表现，该系统的MVC框架采用Struts。&nbsp;<br style="line-height: normal; " /><br style="line-height: normal; " />Service层（就是业务逻辑层），负责实现业务逻辑。业务逻辑层以DAO层为基础，通过对DAO组件的正面模式包装，完成系统所要求的业务逻辑。&nbsp;<br style="line-height: normal; " /><br style="line-height: normal; " />DAO层，负责与持久化对象交互。该层封装了数据的增、删、查、改的操作。&nbsp;<br style="line-height: normal; " /><br style="line-height: normal; " />PO，持久化对象。通过实体关系映射工具将关系型数据库的数据映射成对象，很方便地实现以面向对象方式操作数据库，该系统采用Hibernate作为ORM框架。&nbsp;<br style="line-height: normal; " /><br style="line-height: normal; " />Spring的作用贯穿了整个中间层，将Web层、Service层、DAO层及PO无缝整合，其数据服务层用来存放数据。&nbsp;<br style="line-height: normal; " /><br style="line-height: normal; " />一个良好的框架可以让开发人员减轻重新建立解决复杂问题方案的负担和精力;它可以被扩展以进行内部的定制化;并且有强大的用户社区来支持它。框架通常能很好的解决一个问题。然而，你的应用是分层的，可能每一个层都需要各自的框架。仅仅解决UI问题并不意味着你能够很好的将业务逻辑和持久性逻辑和UI 组件很好的耦合。&nbsp;<br style="line-height: normal; " /><br style="line-height: normal; " /><br style="line-height: normal; " /><br style="line-height: normal; " />不可否认，对于简单的应用，采用ASP或者PHP的开发效率比采用J2EE框架的开发效率要高。甚至有人会觉得：这种分层的结构，比一般采用JSP + Servlet的系统开发效率还要低。&nbsp;<br style="line-height: normal; " /><br style="line-height: normal; " />笔者从一下几个角度来阐述这个问题。&nbsp;<br style="line-height: normal; " /><br style="line-height: normal; " />&#8212; 开发效率：软件工程是个特殊的行业，不同于传统的工业，例如电器、建筑及汽车等行业。这些行业的产品一旦开发出来，交付用户使用后将很少需要后续的维护。但软件行业不同，软件产品的后期运行维护是个巨大的工程，单纯从前期开发时间上考虑其开发效率是不理智的，也是不公平的。众所周知，对于传统的ASP和 PHP等脚本站点技术，将整个站点的业务逻辑和表现逻辑都混杂在ASP或PHP页面里，从而导致页面的可读性相当差，可维护性非常低。即使需要简单改变页面的按钮，也不得不打开页面文件，冒着破坏系统的风险。但采用严格分层J2EE架构，则可完全避免这个问题。对表现层的修改即使发生错误，也绝对不会将错误扩展到业务逻辑层，更不会影响持久层。因此，采用J2EE分层架构，即使前期的开发效率稍微低一点，但也是值得的。&nbsp;<br style="line-height: normal; " /><br style="line-height: normal; " />&#8212; 需求的变更：以笔者多年的开发经验来看，很少有软件产品的需求从一开始就完全是固定的。客户对软件需求，是随着软件开发过程的深入，不断明晰起来的。因此，常常遇到软件开发到一定程度时，由于客户对软件需求发生了变化，使得软件的实现不得不随之改变。当软件实现需要改变时，是否可以尽可能多地保留软件的部分，尽可能少地改变软件的实现，从而满足客户需求的变更？答案是&#8212;&#8212;采用优秀的解耦架构。这种架构就是J2EE的分层架构，在优秀的分层架构里，控制层依赖于业务逻辑层，但绝不与任何具体的业务逻辑组件耦合，只与接口耦合;同样，业务逻辑层依赖于DAO层，也不会与任何具体的DAO组件耦合，而是面向接口编程。采用这种方式的软件实现，即使软件的部分发生改变，其他部分也尽可能不要改变。&nbsp;<br style="line-height: normal; " /><br style="line-height: normal; " />注意：即使在传统的硬件行业，也有大量的接口规范。例如PCI接口、显卡或者网卡，只要其遵守PCI的规范，就可以插入主板，与主板通信。至于这块卡内部的实现，不是主板所关心的，这也正是面向接口编程的好处。假如需要提高电脑的性能，需要更新显卡，只要更换另一块PCI接口的显卡，而不是将整台电脑抛弃。如果一台电脑不是采用各种接口组合在一起，而是做成整块，那将意味着即使只需要更新网卡，也要放弃整台电脑。同样，对于软件中的一个个组件，当一个组件需要重构时，尽量不会影响到其他组件。实际上，这是最理想的情况，即使采用目前最优秀的架构，也会有或多或少的影响，这也是软件工程需要努力提高的地方。&nbsp;<br style="line-height: normal; " /><br style="line-height: normal; " />技术的更新，系统重构：软件行业的技术更新很快，虽然软件行业的发展不快，但小范围的技术更新特别快。一旦由于客观环境的变化，不得不更换技术时，如何保证系统的改变最小呢？答案还是选择优秀的架构。&nbsp;<br style="line-height: normal; " /><br style="line-height: normal; " />在传统的Model 1的程序结构中，只要有一点小的需求发生改变，将意味着放弃整个页面。或者改写。虽然前期的开发速度快，除非可以保证以后永远不会改变应用的结构，否则不要采用Model 1的结构。&nbsp;<br style="line-height: normal; " /><br style="line-height: normal; " />采用Hibernate作为持久层技术的最大的好处在于：可以完全以面向对象的方式进行系统分析、系统设计。&nbsp;<br style="line-height: normal; " /><br style="line-height: normal; " />DAO模式需要为每个DAO组件编写DAO接口，同时至少提供一个实现类，根据不同需要，可能有多个实现类。用Spring容器代替DAO工厂&nbsp;<br style="line-height: normal; " /><br style="line-height: normal; " />通常情况下，引入接口就不可避免需要引入工厂来负责DAO组件的生成。Spring实现了两种基本模式：单态模式和工厂模式。而使用Spring可以完全避免使用工厂模式，因为Spring就是个功能非常强大的工厂。因此，完全可以让Spring充当DAO工厂。&nbsp;<br style="line-height: normal; " /><br style="line-height: normal; " />由Spring充当DAO工厂时，无须程序员自己实现工厂模式，只需要将DAO组件配置在Spring容器中，由ApplicationContext负责管理DAO组件的创建即可。借助于Spring提供的依赖注入，其他组件甚至不用访问工厂，一样可以直接使用DAO实例。&nbsp;<br style="line-height: normal; " /><br style="line-height: normal; " />优点：&nbsp;<br style="line-height: normal; " />Struts跟Tomcat、Turbine等诸多Apache项目一样，是开源软件，这是它的一大优点。使开发者能更深入的了解其内部实现机制。&nbsp;<br style="line-height: normal; " />除此之外，Struts的优点主要集中体现在两个方面：Taglib和页面导航。Taglib是Struts的标记库，灵活动用，能大大提高开发效率。另外，就目前国内的JSP开发者而言，除了使用JSP自带的常用标记外，很少开发自己的标记，或许Struts是一个很好的起点。&nbsp;<br style="line-height: normal; " />关于页面导航，我认为那将是今后的一个发展方向，事实上，这样做，使系统的脉络更加清晰。通过一个配置文件，即可把握整个系统各部分之间的联系，这对于后期的维护有着莫大的好处。尤其是当另一批开发者接手这个项目时，这种优势体现得更加明显。&nbsp;<br style="line-height: normal; " />缺点：&nbsp;<br style="line-height: normal; " />Taglib是Struts的一大优势，但对于初学者而言，却需要一个持续学习的过程，甚至还会打乱你网页编写的习惯，但是，当你习惯了它时，你会觉得它真的很棒。&nbsp;<br style="line-height: normal; " />Struts将MVC的Controller一分为三，在获得结构更加清晰的同时，也增加了系统的复杂度。&nbsp;<br style="line-height: normal; " />Struts从产生到现在还不到半年，但已逐步越来越多运用于商业软件。虽然它现在还有不少缺点，但它是一种非常优秀的J2EE MVC实现方式，如果你的系统准备采用J2EE MVC架构，那么，不妨考虑一下Struts。&nbsp;</div><div></div></td></tr></tbody></table></span></div><img src ="http://www.blogjava.net/rosial/aggbug/365509.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/rosial/" target="_blank">rosial</a> 2011-12-04 17:34 <a href="http://www.blogjava.net/rosial/articles/365509.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>