<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
  <channel>
    <title>joanzq</title>
    <description></description>
    <link>http://joanzq.javaeye.com</link>
    <language>UTF-8</language>
    <copyright>Copyright 2003-2008, JavaEye.com</copyright>
    <docs>http://blogs.law.harvard.edu/tech/rss</docs>
    <generator>JavaEye - 做最棒的软件开发交流社区</generator>
          <item>
        <title>QTP 安装问题小记</title>
        <author>joanzq</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://joanzq.javaeye.com">joanzq</a>&nbsp;
                    链接：<a href="http://joanzq.javaeye.com/blog/242917" style="color:red;">http://joanzq.javaeye.com/blog/242917</a>&nbsp;
          发表时间: 2008年09月16日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>&nbsp;&nbsp;&nbsp;&nbsp; 对于&nbsp;QTP 9.2 安装。运行setup.exe 出现&nbsp;&nbsp;Command line option syntax error. Type Command /? for Help 错误提示框的有效解除方法是将安装程序包放到一个全英文路径下，再重新安装就可以解决。比如：D:\qtp92</p>
          <br/><br/>
          <span style="color:red;">
            <a href="http://joanzq.javaeye.com/blog/242917#comments" style="color:red;">已有 <strong>0</strong> 人发表留言，猛击-&gt;&gt;<strong>这里</strong>&lt;&lt;-参与讨论</a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">Windows7在微软WinHEC 2008上揭开神秘面纱</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 16 Sep 2008 21:51:08 +0800</pubDate>
        <link>http://joanzq.javaeye.com/blog/242917</link>
        <guid>http://joanzq.javaeye.com/blog/242917</guid>
      </item>
          <item>
        <title>欢迎大家加入测试圈圈，探讨软件测试相关</title>
        <author>joanzq</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://joanzq.javaeye.com">joanzq</a>&nbsp;
                    链接：<a href="http://joanzq.javaeye.com/blog/239853" style="color:red;">http://joanzq.javaeye.com/blog/239853</a>&nbsp;
          发表时间: 2008年09月09日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>&nbsp;欢迎大家加入测试圈圈，共同探讨软件测试领域，一起成长吧！<img src="../../images/smiles/icon_biggrin.gif" alt="" /></p>
<div>&nbsp;软件测试方法，工具，Bug缺陷跟踪，配置管理</div>
<div>名字：测试圈圈</div>
<p>&nbsp;地址：<a href="http://test.group.javaeye.com/">http://test.group.javaeye.com/</a></p>
          <br/><br/>
          <span style="color:red;">
            <a href="http://joanzq.javaeye.com/blog/239853#comments" style="color:red;">已有 <strong>0</strong> 人发表留言，猛击-&gt;&gt;<strong>这里</strong>&lt;&lt;-参与讨论</a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">Windows7在微软WinHEC 2008上揭开神秘面纱</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 09 Sep 2008 17:00:30 +0800</pubDate>
        <link>http://joanzq.javaeye.com/blog/239853</link>
        <guid>http://joanzq.javaeye.com/blog/239853</guid>
      </item>
          <item>
        <title>maxQ的使用</title>
        <author>joanzq</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://joanzq.javaeye.com">joanzq</a>&nbsp;
                    链接：<a href="http://joanzq.javaeye.com/blog/237568" style="color:red;">http://joanzq.javaeye.com/blog/237568</a>&nbsp;
          发表时间: 2008年09月05日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <h3>MaxQ的使用</h3>
<div class="blog_content">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MaxQ是一个Web功能测试工具。它包括一个记录测试脚本的HTTP代理，一个用于重放测试的命令行实用程序。代理记录器自动存储提交到表单的变量，那么你无需用手书写它们。<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MaxQ的使用很简单，今天把使用的方法记录，备忘！<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1）运行maxq.bat;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2)设置一个新的录制new-&gt;standard script<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MaxQ的界面如图：<br />&nbsp;&nbsp;&nbsp;&nbsp;<img src="http://www.blogjava.net/images/blogjava_net/joan/maxq.jpg" border="0" height="527" alt="" width="603" /><br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3）选择test-&gt;start recording开始录制<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<img src="http://www.blogjava.net/images/blogjava_net/joan/2.jpg" border="0" height="480" alt="" width="600" /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4)&nbsp;&nbsp; 设置IE的代理，internater--&gt;连接-&gt;局域网设置&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<img src="http://www.blogjava.net/images/blogjava_net/joan/shezhiIE1.jpg" border="0" height="480" alt="" width="457" /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 5）点击IE ，输入：&nbsp;<a href="http://localhost:8091/"><span style="color: #108ac6;">http://localhost:8091/</span></a>&nbsp; 这里我录的是TOMCAT&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;6）录制完后，选择test-&gt;stop recording。贮存脚本file-&gt;save<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 7）选择file-&gt;open(打开脚本)选择test-&gt;run&nbsp; 回放录制的脚本。分析测试结果，在查看测试结果界面,如果成功的话显示Test Ran Successfully <img src="http://www.blogjava.net/CuteSoft_Client/CuteEditor/images/emsmile.gif" border="0" align="absMiddle" alt="" /><br /><img src="http://www.blogjava.net/images/blogjava_net/joan/huifang1.jpg" border="0" height="397" alt="" width="596" /><br /></div>
          <br/><br/>
          <span style="color:red;">
            <a href="http://joanzq.javaeye.com/blog/237568#comments" style="color:red;">已有 <strong>8</strong> 人发表留言，猛击-&gt;&gt;<strong>这里</strong>&lt;&lt;-参与讨论</a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">Windows7在微软WinHEC 2008上揭开神秘面纱</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Fri, 05 Sep 2008 13:57:23 +0800</pubDate>
        <link>http://joanzq.javaeye.com/blog/237568</link>
        <guid>http://joanzq.javaeye.com/blog/237568</guid>
      </item>
          <item>
        <title>我的涂鸦</title>
        <author>joanzq</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://joanzq.javaeye.com">joanzq</a>&nbsp;
                    链接：<a href="http://joanzq.javaeye.com/blog/237561" style="color:red;">http://joanzq.javaeye.com/blog/237561</a>&nbsp;
          发表时间: 2008年08月16日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p><br /><img src="http://www.blogjava.net/images/blogjava_net/joan/1.jpg" height="411" alt="" style="border: 0;" width="546" /><br /><br />我的涂鸦作品，<img src="http://www.blogjava.net/Emoticons/QQ/laf.gif" border="0" height="20" alt="" width="20" /></p>
          <br/><br/>
          <span style="color:red;">
            <a href="http://joanzq.javaeye.com/blog/237561#comments" style="color:red;">已有 <strong>0</strong> 人发表留言，猛击-&gt;&gt;<strong>这里</strong>&lt;&lt;-参与讨论</a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">Windows7在微软WinHEC 2008上揭开神秘面纱</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sat, 16 Aug 2008 00:26:00 +0800</pubDate>
        <link>http://joanzq.javaeye.com/blog/237561</link>
        <guid>http://joanzq.javaeye.com/blog/237561</guid>
      </item>
          <item>
        <title>JavaScript多线程编程</title>
        <author>joanzq</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://joanzq.javaeye.com">joanzq</a>&nbsp;
                    链接：<a href="http://joanzq.javaeye.com/blog/227537" style="color:red;">http://joanzq.javaeye.com/blog/227537</a>&nbsp;
          发表时间: 2008年08月13日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <h3>AJAX 开发中的难题</h3>
<p>让我们通过一个简单的例子来认识这个问题。假设你要建立一个树形结构的公告栏系统(BBS)，它可以根据用户请求与服务器进行交互，动态加载每篇文章的信息，而不是一次性从服务器载入所有文章信息。每篇文章有四个相关属性：系统中可以作为唯一标识的ID、发贴人姓名、文章内容以及包含其所有子文章ID的数组信息。首先假定有一个名为getArticle()的函数可以加载一篇文章信息。该函数接收的参数是要加载文章的ID，通过它可从服务器获取文章信息。它返回的对象包含与文章相关的四条属性：id，name，content和children。例程如下：</p>
<pre>function ( id ) {
     var a = getArticle(id);
     document.writeln(a.name + "
" + a.content);
 } </pre>
<p>然而你也许会注意到，重复用同一个文章ID调用此函数，需要与服务器之间进行反复且无益的通信。想要解决这个问题，可以考虑使用函数 getArticleWithCache()，它相当于一个带有缓存能力的getArticle()。在这个例子中，getArticle()返回的数据只是作为一个全局变量被保存下来：</p>
<pre>var cache = {};
 function getArticleWithCache ( id ) {
     if ( !cache[id] ) {
         cache[id] = getArticle(id);
     }
     return cache[id];
 } </pre>
<p>现在已将读入的文章缓存起来，让我们再来考虑一下函数backgroundLoad()，它应用我们上面提到的缓存机制加载所有文章信息。其用途是，当读者在阅读某篇文章时，从后台预加载它所有子文章。因为文章数据是树状结构的，所以很容易写一个递归的算法来遍历树并且加载所有的文章：</p>
<pre>function backgroundLoad ( ids ) {
     for ( var i=0; i &lt; ids.length; i++ ) {
         var a = getArticleWithCache(ids[i]);
         backgroundLoad(a.children);
     }
 } </pre>
<p>backgroundLoad ()函数接收一个ID数组作为参数，然后通过每个ID调用前面定义过的getArticldWithCache()方法，这样就把每个ID对应的文章缓存起来。之后再通过已加载文章的子文章ID数组递归调用backgroundLoad()方法，如此整个文章树就被缓存起来。</p>
<p>到目前为止，一切似乎看起来都很完美。然而，只要你有过开发AJAX应用的经验，你就应该知晓这种幼稚的实现方法根本不会成功，这个例子成立的基础是默认 getArticle()用的是同步通信。可是，作为一条基本原则，JavaScript要求在与服务器进行交互时要用异步通信，因为它是单线程的。就简单性而言，把每一件事情（包括GUI事件和渲染）都放在一个线程里来处理是一个很好的程序模型，因为这样就无需再考虑线程同步这些复杂问题。另一方面，他也暴露了应用开发中的一个严重问题，单线程环境看起来对用户请求响应迅速，但是当线程忙于处理其它事情时(比如说调用getArticle())，就不能对用户的鼠标点击和键盘操作做出响应。 </p>
<p>如果在这个单线程环境里进行同步通信会发生什么事情呢？同步通信会中断浏览器的执行直至获得通信结果。在等待通信结果的过程中，由于服务器的调用还没有完成，线程会停止响应用户并保持锁定状态直到调用返回。因为这个原因，当浏览器在等待服务器响应时它不能对用户行为作出响应，所以看起来像是冻结了。当执行 getArticleWithCache()和backgroundLoad()会有同样的问题，因为它们都是基于getArticle()函数的。由于下载所有的文章可能会耗费很可观的一段时间，因此对于backgroundLoad()函数来说，浏览器在此段时间内的冻结就是一个很严重的问题&mdash;&mdash;既然浏览器都已经冻结，当用户正在阅读文章时就不可能首先去执行后台预加载数据，如果这样做连当前的文章都没办法读。</p>
<p>如上所述，既然同步通信在使用中会造成如此严重的问题，JavaScript就把异步通信作为一条基本原则。因此，我们可以基于异步通信改写上面的程序。 JavaScript要求以一种事件驱动的程序设计方式来写异步通信程序。在很多场合中，你都必须指定一个回调程序，一旦收到通信响应，这个函数就会被调用。例如，上面定义的getArticleWithCache()可以写成这样：</p>
<pre>var cache = {};
 function getArticleWithCache ( id, callback ) {
     if ( !cache[id] ) {
         callback(cache[id]);
     } else {
         getArticle(id, function( a ){
             cache[id] = a;
             callback(a);
         });
     }
 } </pre>
<p>这个程序也在内部调用了getArticle()函数。然而需要注意的是，为异步通信设计的这版getArticle()函数要接收一个函数作为第二个参数。当调用这个getArticle()函数时，与从前一样要给服务器发送一个请求，不同的是，现在函数会迅速返回而非等待服务器的响应。这意味着，当执行权交回给调用程序时，还没有得到服务器的响应。如此一来，线程就可以去执行其它任务直至获得服务器响应，并在此时调用回调函数。一旦得到服务器响应， getArticle()的第二个参数作为预先定义的回调函数就要被调用，服务器的返回值即为其参数。同样的，getArticleWithCache ()也要做些改变，定义一个回调参数作为其第二个参数。这个回调函数将在被传给getArticle()的回调函数中调用，因而它可以在服务器通信结束后被执行。</p>
<p>单是上面这些改动你可能已经认为相当复杂了，但是对backgroundLoad()函数做得改动将会更复杂，它也要被改写成可以处理回调函数的形式：</p>
<pre>function backgroundLoad ( ids, callback ) {
     var i = 0;
     function l ( ) {
         if ( i &lt; ids.length ) {
             getArticleWithCache(ids[i++], function( a ){
                 backgroundLoad(a.children, l);
             });
         } else {
             callback();
         }
     }
     l();
 } </pre>
<p>改动后的backgroundLoad()函数看上去和我们以前的那个函数已经相去甚远，不过他们所实现的功能并无二致。这意味着这两个函数都接受ID数组作为参数，对于数组里的每个元素都要调用getArticleWithCache()，再应用已经获得子文章ID递归调用backgroundLoad ()。不过同样是对数组的循环访问，新函数中的就不太好辨认了，以前的程序中是用一个for循环语句完成的。为什么实现同样功能的两套函数是如此的大相径庭呢？</p>
<p>这个差异源于一个事实：任何函数在遇到有需要同服务器进行通信情况后，都必须立刻返回，例如getArticleWithCache()。除非原来的函数不在执行当中，否则应当接受服务器响应的回调函数都不能被调用。对于JavaScript，在循环过程中中断程序并在稍后从这个断点继续开始执行程序是不可能的，例如一个for语句。因此，本例利用递归传递回调函数实现循环结构而非一个传统循环语句。对那些熟悉连续传送风格(CPS)的人来说，这就是一个 CPS的手动实现，因为不能使用循环语法，所以即便如前面提到的遍历树那么简单的程序也得写得很复杂。与事件驱动程序设计相关的问题是<a href="http://www.cis.upenn.edu/~stevez/papers/LZ04a.pdf">控制流问题</a>：循环和其它控制流表达式可能比较难理解。</p>
<p>这里还有另外一个问题：如果你把一个没有应用异步通信的函数转换为一个使用异步通信的函数，那么重写的函数将需要一个回调函数作为新增参数，这为已经存在的APIs造成了很大问题，因为内在的改变没有把影响限于内部，而是导致整体混乱的APIs以及API的其它使用者的改变。</p>
<p>造成这些问题目的根本原因是什么呢？没错，正是JavaScript单线程机制导致了这些问题。在单线程里执行异步通信需要事件驱动程序设计和复杂的语句。如果当程序在等待服务器的响应时，有另外一个线程可以来处理用户请求，那么上述复杂技术就不需要了。</p>
<h3>试试多线程编程</h3>
<p>让我来介绍一下Concurrent.Thread，它是一个允许JavaScript进行多线程编程的库，应用它可以大大缓解上文提及的在AJAX开发中与异步通信相关的困难。这是一个用JavaScript写成的免费的软件库，使用它的前提是遵守Mozilla Public License和GNU General Public License这两个协议。你可以从<a href="http://jsthread.sourceforge.net/">他们的网站 </a>下载源代码。</p>
<p>马上来下载和使用源码吧！假定你已经将下载的源码保存到一个名为Concurrent.Thread.js的文件夹里，在进行任何操作之前，先运行如下程序，这是一个很简单的功能实现：</p>
<pre><code>&lt;script type="text/javascript" src="Concurrent.Thread.js"&gt;&lt;/script&gt;
 &lt;script type="text/javascript"&gt;
     Concurrent.Thread.create(function(){
         var i = 0;
         while ( 1 ) {
             document.body.innerHTML += i++ + "&lt;br&gt;";
         }
     });
 &lt;/script&gt;</code></pre>
<p>执行这个程序将会顺序显示从0开始的数字，它们一个接一个出现，你可以滚屏来看它。现在让我们来仔细研究一下代码，他应用while(1)条件制造了一个不会中止的循环，通常情况下，象这样不断使用一个并且是唯一一个线程的JavaScript程序会导致浏览器看起来象冻结了一样，自然也就不会允许你滚屏。那么为什么上面的这段程序允许你这么做呢？关键之处在于while(1)上面的那条Concurrent.Thread.create()语句，这是这个库提供的一个方法，它可以创建一个新线程。被当做参数传入的函数在这个新线程里执行，让我们对程序做如下微调：</p>
<pre><code>&lt;script type="text/javascript" src="Concurrent.Thread.js"&gt;&lt;/script&gt;
 &lt;script type="text/javascript"&gt;
     function f ( i ){
         while ( 1 ) {
             document.body.innerHTML += i++ + "&lt;br&gt;";
         }
     }
     Concurrent.Thread.create(f, 0);
     Concurrent.Thread.create(f, 100000);
 &lt;/script&gt; </code></pre>
<p><span style="font-family: monospace;">在这个程序里有个新函数f()可以重复显示数字，它是在程序段起始定义的，接着以f()为参数调用了两次create()方法，传给create()方法的第二个参数将会不加修改地传给f()。执行这个程序，先会看到一些从0开始的小数，接着是一些从100,000开始的大数，然后又是接着前面小数顺序的数字。你可以观察到程序在交替显示小数和大数，这说明两个线程在同时运行。</span></p>
<p>让我来展示Concurrent.Thread的另外一个用法。上面的例子调用create()方法来创建新线程。不调用库里的任何APIs也有可能实现这个目的。例如，前面那个例子可以这样写：</p>
<pre><code>&lt;script type="text/javascript" src="Concurrent.Thread.js"&gt;&lt;/script&gt;
 &lt;script type="text/x-script.multithreaded-js"&gt;
     var i = 1;
     while ( 1 ) {
         document.body.innerHTML += i++ + "&lt;br&gt;";
     }
 &lt;/script&gt; </code></pre>
<p><span style="font-family: monospace;">在script 标签内，很简单地用JavaScript写了一个无穷循环。你应该注意到标签内的type属性，那里是一个很陌生的值(text/x- script.multithreaded-js)，如果这个属性被放在script标签内，那么Concurrent.Thread就会在一个新的线程内执行标签之间的程序。你应当记住一点，在本例一样，必须将Concurrent.Thread库包含进来。</span></p>
<p>有了Concurrent.Thread，就有可能自如的将执行环境在线程之间进行切换，即使你的程序很长、连续性很强。我们可以简要地讨论下如何执行这种操作。简言之，需要进行代码转换。粗略地讲，首先要把传递给create()的函数转换成一个字符串，接着改写直至它可以被分批分次执行。然后这些程序可以依照调度程序逐步执行。调度程序负责协调多线程，换句话说，它可以在适当的时候做出调整以便每一个修改后的函数都会得到同等机会运行。 Concurrent.Thread实际上并没有创建新的线程，仅仅是在原本单线程的基础上模拟了一个多线程环境。</p>
<p>虽然转换后的函数看起来是运行在不同的线程内，但是实际上只有一个线程在做这所有的事情。在转换后的函数内执行同步通信仍然会造成浏览器冻结，你也许会认为以前的那些问题根本就没有解决。不过你不必耽心，Concurrent.Thread提供了一个应用JavaScript 的异步通信方式实现的定制通信库，它被设计成当一个线程在等待服务器的响应时允许其它线程运行。这个通信库存于 Concurrent.Thread.Http下。它的用法如下所示：</p>
<pre><code>&lt;script type="text/javascript" src="Concurrent.Thread.js"&gt;&lt;/script&gt;
 &lt;script type="text/x-script.multithreaded-js"&gt;
     var req = Concurrent.Thread.Http.get(url, ["Accept", "*"]);
     if (req.status == 200) {
         alert(req.responseText);
     } else {
         alert(req.statusText);
     }
 &lt;/script&gt; </code></pre>
<p>get()方法，就像它的名字暗示的那样，可以通过HTTP的GET方法获得指定URL的内容，它将目标URL作为第一个参数，将一个代表HTTP请求头的数组作为可选的第二个参数。get()方法与服务器交互，当得到服务器的响应后就返回一个XMLHttpRequest对象作为返回值。当get()方法返回时，已经收到了服务器响应，所以就没必要再用回调函数接收结果。自然，也不必再耽心当程序等待服务器的响应时浏览器冻结的情况了。另外，还有一个 post()方法可以用来发送数据到服务器：</p>
<pre><code>&lt;script type="text/javascript" src="Concurrent.Thread.js"&gt;&lt;/script&gt;
 &lt;script type="text/x-script.multithreaded-js"&gt;
     var req = Concurrent.Thread.Http.post(url, "key1=val1&amp;key2=val2");
     alert(req.statusText);
 &lt;/script&gt;</code> </pre>
<p>post()方法将目的URL作为第一个参数，要发送的内容作为第二个参数。像get()方法那样，你也可以将请求头作为可选的第三个参数。</p>
<p>如果你用这个通信库实现了第一个例子当中的getArticle()方法，那么你很快就能应用文章开头示例的那种简单的方法写出getArticleWithCache(),backgroundLoad ()以及其它调用了getArticle()方法的函数了。即使是那版backgroundLoad()正在读文章数据，照例还有另外一个线程可以对用户请求做出响应，浏览器因此也不会冻结。现在，你能理解在JavaScript中应用多线程有多实用了？</p>
<h3>想了解更多</h3>
<p>我向你介绍了一个可以在JavaScript中应用多线程的库：Concurrent.Thread。这篇文章的内容只是很初级的东西，如果你想更深入的了解，我推荐您去看<a href="http://jsthread.sourceforge.net/cgi-bin/wiki/wiki.cgi?page=A+Tutorial">the tutorial</a>。它提供有关Concurrent.Thread用法的更多内容，并列出了可供高级用户使用的文档，是最适合起步的材料。访问<a href="http://jsthread.sourceforge.net/">他们的网站</a>也不错，那里提供更多信息。</p>
          <br/><br/>
          <span style="color:red;">
            <a href="http://joanzq.javaeye.com/blog/227537#comments" style="color:red;">已有 <strong>3</strong> 人发表留言，猛击-&gt;&gt;<strong>这里</strong>&lt;&lt;-参与讨论</a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">Windows7在微软WinHEC 2008上揭开神秘面纱</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 13 Aug 2008 14:10:02 +0800</pubDate>
        <link>http://joanzq.javaeye.com/blog/227537</link>
        <guid>http://joanzq.javaeye.com/blog/227537</guid>
      </item>
          <item>
        <title>QTP相关资料下载（收集）</title>
        <author>joanzq</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://joanzq.javaeye.com">joanzq</a>&nbsp;
                    链接：<a href="http://joanzq.javaeye.com/blog/213691" style="color:red;">http://joanzq.javaeye.com/blog/213691</a>&nbsp;
          发表时间: 2008年07月10日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>QTP相关资料下载&nbsp;</p>
<div class="t_msgfont" id="postmessage_6390">VBScript 常用函数集 <a href="http://www.3atesting.com/bbs/viewthread.php?tid=918&amp;extra=page%3D3" target="_blank">http://www.3atesting.com/bbs/vie ... &amp;extra=page%3D3</a> XML基础教程下载 <a href="http://www.3atesting.com/bbs/viewthread.php?tid=838&amp;extra=page%3D3" target="_blank">http://www.3atesting.com/bbs/vie ... &amp;extra=page%3D3</a> 正则表达式学习文档　下载 <a href="http://www.3atesting.com/bbs/viewthread.php?tid=707&amp;extra=page%3D3" target="_blank">http://www.3atesting.com/bbs/vie ... &amp;extra=page%3D3</a> 一份QTP脚本供大家学习 <a href="http://www.3atesting.com/bbs/viewthread.php?tid=826&amp;extra=page%3D3" target="_blank">http://www.3atesting.com/bbs/vie ... &amp;extra=page%3D3</a> HTML教程下载 <a href="http://www.3atesting.com/bbs/vie ... &amp;extra=page%3D4" target="_blank">http://www.3atesting.com/bbs/vie ... &amp;extra=page%3D4</a></div>
<div class="t_msgfont">
<div class="t_msgfont" id="postmessage_6390">VBScript 常用函数集 <a href="http://www.3atesting.com/bbs/viewthread.php?tid=918&amp;extra=page%3D3" target="_blank">http://www.3atesting.com/bbs/vie ... &amp;extra=page%3D3</a> XML基础教程下载 <a href="http://www.3atesting.com/bbs/viewthread.php?tid=838&amp;extra=page%3D3" target="_blank">http://www.3atesting.com/bbs/vie ... &amp;extra=page%3D3</a> 正则表达式学习文档　下载 <a href="http://www.3atesting.com/bbs/viewthread.php?tid=707&amp;extra=page%3D3" target="_blank">http://www.3atesting.com/bbs/vie ... &amp;extra=page%3D3</a> 一份QTP脚本供大家学习 <a href="http://www.3atesting.com/bbs/viewthread.php?tid=826&amp;extra=page%3D3" target="_blank">http://www.3atesting.com/bbs/vie ... &amp;extra=page%3D3</a> HTML教程下载 <a href="http://www.3atesting.com/bbs/viewthread.php?tid=836&amp;extra=page%3D4" target="_blank">http://www.3atesting.com/bbs/vie ... &amp;extra=page%3D4</a></div>
</div>
          <br/><br/>
          <span style="color:red;">
            <a href="http://joanzq.javaeye.com/blog/213691#comments" style="color:red;">已有 <strong>0</strong> 人发表留言，猛击-&gt;&gt;<strong>这里</strong>&lt;&lt;-参与讨论</a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">Windows7在微软WinHEC 2008上揭开神秘面纱</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Thu, 10 Jul 2008 21:17:03 +0800</pubDate>
        <link>http://joanzq.javaeye.com/blog/213691</link>
        <guid>http://joanzq.javaeye.com/blog/213691</guid>
      </item>
          <item>
        <title>MyEclipse “Error initializing endpoint” resolvent </title>
        <author>joanzq</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://joanzq.javaeye.com">joanzq</a>&nbsp;
                    链接：<a href="http://joanzq.javaeye.com/blog/207082" style="color:red;">http://joanzq.javaeye.com/blog/207082</a>&nbsp;
          发表时间: 2008年06月23日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 在家写程序时发现当QQlive开着的，MyEclipse 出现 &ldquo; Error initializing endpoint &rdquo;，Tomcat无法使用。浏览器进度条显示为0% 。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 关闭QQlive即正常使用，担心QQlive是不是占用了tomcat端口，&nbsp;把tomcat端口改了，重启问题依旧。在使用QQlive的同时仍然无法使用tomcat 。不知道有没有人遇到过这个问题，可以怎样解决！</p>
          <br/><br/>
          <span style="color:red;">
            <a href="http://joanzq.javaeye.com/blog/207082#comments" style="color:red;">已有 <strong>1</strong> 人发表留言，猛击-&gt;&gt;<strong>这里</strong>&lt;&lt;-参与讨论</a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">Windows7在微软WinHEC 2008上揭开神秘面纱</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 23 Jun 2008 13:31:32 +0800</pubDate>
        <link>http://joanzq.javaeye.com/blog/207082</link>
        <guid>http://joanzq.javaeye.com/blog/207082</guid>
      </item>
          <item>
        <title>童年零食总汇</title>
        <author>joanzq</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://joanzq.javaeye.com">joanzq</a>&nbsp;
                    链接：<a href="http://joanzq.javaeye.com/blog/195263" style="color:red;">http://joanzq.javaeye.com/blog/195263</a>&nbsp;
          发表时间: 2008年05月21日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p><span style="font-size: medium; font-family: 宋体;">跳跳糖。小时候还算是比较奢侈的零食，一点点倒进嘴里，跳跳！ <br /><br /></span></p>
<p><span style="font-family: 宋体;"><span style="font-size: medium;"></span></span></p>
<p><a href="http://pop.pcpop.com/p080120/0004718431.html" onclick="showLinkBubble(this);return false" target="_blank"></a><a href="http://img3.pcpop.com/upimg3/2008/1/20/0004718431.jpg" target="_blank"><span style="font-size: medium; font-family: 宋体;"><img src="http://img3.pcpop.com/upimg3/2008/1/20/0004718431.jpg" border="0" height="400" alt="" style="vertical-align: baseline! important;" width="300" /></span></a><a href="http://pop.pcpop.com/p080120/0004718432.html" onclick="showLinkBubble(this);return false" target="_blank"></a><a href="http://img3.pcpop.com/upimg3/2008/1/20/0004718432.jpg" target="_blank"><span style="font-size: medium; font-family: 宋体;"><img src="http://img3.pcpop.com/upimg3/2008/1/20/0004718432.jpg" border="0" height="400" alt="" style="vertical-align: baseline! important;" width="300" /></span></a><a href="http://pop.pcpop.com/p080120/0004718433.html" onclick="showLinkBubble(this);return false" target="_blank"></a><a href="http://img3.pcpop.com/upimg3/2008/1/20/0004718433.jpg" target="_blank"><span style="font-size: medium; font-family: 宋体;"><img src="http://img3.pcpop.com/upimg3/2008/1/20/0004718433.jpg" border="0" height="426" alt="" style="vertical-align: baseline! important;" width="282" /></span></a></p>
<p><span style="font-size: medium; font-family: 宋体;"> </span></p>
<p><span style="font-size: medium; font-family: 宋体;">&nbsp;</span></p>
<p><span><br /></span></p>
<p><span style="font-size: medium; font-family: 宋体;">&nbsp;</span></p>
<p><span style="font-family: 宋体;"><span style="font-size: medium;"></span></span></p>
<p><span style="font-family: 宋体;"><span style="font-size: medium;"><span style="line-height: 1.3em;"><span style="line-height: 1.3em;">蜜桃精。这是我们那的叫法，味道现在已经记不太清楚了，但还记得那些藏在袋子里的小勺子，很个性 </span><br /></span><span style="line-height: 1.3em;"><a href="http://img3.pcpop.com/upimg3/2008/1/20/0004718437.jpg" target="_blank"><img src="http://img3.pcpop.com/upimg3/2008/1/20/0004718437.jpg" border="0" height="354" alt="" style="vertical-align: baseline! important;" width="500" /></a></span><br /></span></span><span style="line-height: 1.3em;"><span style="font-family: 宋体;"><span style="font-size: medium;"><span style="line-height: 1.3em;">棉花糖。其实也没多好吃，但足以满足小朋友的童心，现在也有而且还改良了，但已经没以前的那种味道了 </span><br /></span></span></span><a href="http://pop.pcpop.com/p080120/0004718438.html" onclick="showLinkBubble(this);return false" target="_blank"></a><a href="http://img3.pcpop.com/upimg3/2008/1/20/0004718438.jpg" target="_blank"><span style="font-size: medium; font-family: 宋体;"><img src="http://img3.pcpop.com/upimg3/2008/1/20/0004718438.jpg" border="0" height="375" alt="" style="vertical-align: baseline! important;" width="500" /></span></a><br /><span style="line-height: 1.3em;"><span style="font-family: 宋体;"><span style="font-size: medium;"><span style="line-height: 1.3em;">无花果。记得见过的第一个可以任意封的小袋子就是这种无花果，是一种酸酸的干丝 </span><br /></span></span></span><a href="http://pop.pcpop.com/p080120/0004718450.html" onclick="showLinkBubble(this);return false" target="_blank"></a><a href="http://img3.pcpop.com/upimg3/2008/1/20/0004718450.jpg" target="_blank"><span style="font-size: medium; font-family: 宋体;"><img src="http://img3.pcpop.com/upimg3/2008/1/20/0004718450.jpg" border="0" height="396" alt="" style="vertical-align: baseline! important;" width="491" /></span></a><br /><span style="line-height: 1.3em;"><span style="font-family: 宋体;"><span style="font-size: medium;"><span style="line-height: 1.3em;">果丹皮。</span><br /></span></span></span><a href="http://pop.pcpop.com/p080120/0004718458.html" onclick="showLinkBubble(this);return false" target="_blank"></a><a href="http://img3.pcpop.com/upimg3/2008/1/20/0004718458.jpg" target="_blank"><span style="font-size: medium; font-family: 宋体;"><img src="http://img3.pcpop.com/upimg3/2008/1/20/0004718458.jpg" border="0" height="240" alt="" style="vertical-align: baseline! important;" width="188" /></span></a><br /><span style="line-height: 1.3em;"><span style="font-family: 宋体;"><span style="font-size: medium;"><span style="line-height: 1.3em;">太阳锅巴。还记得那个电视上的广告，还有那个味道，那时候觉得真好吃 </span><br /></span></span></span><a href="http://pop.pcpop.com/p080120/0004718467.html" onclick="showLinkBubble(this);return false" target="_blank"></a><a href="http://img3.pcpop.com/upimg3/2008/1/20/0004718467.jpg" target="_blank"><span style="font-size: medium; font-family: 宋体;"><img src="http://img3.pcpop.com/upimg3/2008/1/20/0004718467.jpg" border="0" height="210" alt="" style="vertical-align: baseline! important;" width="280" /></span></a><br /><span style="line-height: 1.3em;"><span style="font-family: 宋体;"><span style="font-size: medium;"><span style="line-height: 1.3em;">小果冻。隐约记得那个味道很淡，喜欢它的形状和颜色。 </span><br /></span></span></span><a href="http://pop.pcpop.com/p080120/0004718468.html" onclick="showLinkBubble(this);return false" target="_blank"></a><a href="http://img3.pcpop.com/upimg3/2008/1/20/0004718468.jpg" target="_blank"><span style="font-size: medium; font-family: 宋体;"><img src="http://img3.pcpop.com/upimg3/2008/1/20/0004718468.jpg" border="0" height="234" alt="" style="vertical-align: baseline! important;" width="280" /></span></a><br /><span style="line-height: 1.3em;"><span style="font-family: 宋体;"><span style="font-size: medium;"><span style="line-height: 1.3em;">浇糖稀。很甜，那时候觉得浇糖艺人好厉害，不买也要在那看上大半天 </span><br /></span></span></span><a href="http://pop.pcpop.com/p080120/0004718473.html" onclick="showLinkBubble(this);return false" target="_blank"></a><a href="http://img3.pcpop.com/upimg3/2008/1/20/0004718473.jpg" target="_blank"><span style="font-size: medium; font-family: 宋体;"><img src="http://img3.pcpop.com/upimg3/2008/1/20/0004718473.jpg" border="0" height="272" alt="" style="vertical-align: baseline! important;" width="450" /></span></a><br /><span style="line-height: 1.3em;"><span style="font-family: 宋体;"><span style="font-size: medium;"><span style="line-height: 1.3em;">麦丽素，现在也觉得很好吃。入口即化，好吃 </span><br /></span></span></span><a href="http://pop.pcpop.com/p080120/0004718476.html" onclick="showLinkBubble(this);return false" target="_blank"></a><a href="http://img3.pcpop.com/upimg3/2008/1/20/0004718476.jpg" target="_blank"><span style="font-size: medium; font-family: 宋体;"><img src="http://img3.pcpop.com/upimg3/2008/1/20/0004718476.jpg" border="0" height="300" alt="" style="vertical-align: baseline! important;" width="400" /></span></a><br /><span style="line-height: 1.3em;"><span style="font-family: 宋体;"><span style="font-size: medium;"><span style="line-height: 1.3em;">雪人冰棍，那时候最爱吃的冰棍 </span><br /></span></span></span><a href="http://pop.pcpop.com/p080120/0004718480.html" onclick="showLinkBubble(this);return false" target="_blank"></a><a href="http://img3.pcpop.com/upimg3/2008/1/20/0004718480.jpg" target="_blank"><span style="font-size: medium; font-family: 宋体;"><img src="http://img3.pcpop.com/upimg3/2008/1/20/0004718480.jpg" border="0" height="371" alt="" style="vertical-align: baseline! important;" width="350" /></span></a><br /><span style="line-height: 1.3em;"><span style="font-size: medium; line-height: 1.3em; font-family: 宋体;">健力宝 </span><a href="http://pop.pcpop.com/p080120/0004718488.html" onclick="showLinkBubble(this);return false" target="_blank"><span style="font-size: medium; line-height: 1.3em; font-family: 宋体;"><a href="http://img3.pcpop.com/upimg3/2008/1/20/0004718488.jpg" target="_blank"><img src="http://img3.pcpop.com/upimg3/2008/1/20/0004718488.jpg" border="0" height="95" alt="" style="vertical-align: baseline! important;" width="140" /></a></span></a></span><span style="line-height: 1.3em;"><span style="font-size: medium; line-height: 1.3em; font-family: 宋体;">喔喔佳佳奶糖 </span><a href="http://pop.pcpop.com/p080120/0004718497.html" onclick="showLinkBubble(this);return false" target="_blank"><span style="font-size: medium; line-height: 1.3em; font-family: 宋体;"><a href="http://img3.pcpop.com/upimg3/2008/1/20/0004718497.jpg" target="_blank"><img src="http://img3.pcpop.com/upimg3/2008/1/20/0004718497.jpg" border="0" height="139" alt="" style="vertical-align: baseline! important;" width="125" /></a></span></a><a href="http://pop.pcpop.com/p080120/0004718496.html" onclick="showLinkBubble(this);return false" target="_blank"><span style="font-size: medium; line-height: 1.3em; font-family: 宋体;"><a href="http://img3.pcpop.com/upimg3/2008/1/20/0004718496.jpg" target="_blank"><img src="http://img3.pcpop.com/upimg3/2008/1/20/0004718496.jpg" border="0" height="139" alt="" style="vertical-align: baseline! important;" width="139" /></a></span></a></span><span style="line-height: 1.3em;"><span style="font-family: 宋体;"><span style="font-size: medium;"><span style="line-height: 1.3em;">大街小巷的爆米花 </span><br /></span></span></span><a href="http://pop.pcpop.com/p080120/0004718505.html" onclick="showLinkBubble(this);return false" target="_blank"></a><a href="http://img3.pcpop.com/upimg3/2008/1/20/0004718505.jpg" target="_blank"><span style="font-size: medium; font-family: 宋体;"><img src="http://img3.pcpop.com/upimg3/2008/1/20/0004718505.jpg" border="0" height="334" alt="" style="vertical-align: baseline! important;" width="500" /></span></a><br /><span style="line-height: 1.3em;"><span style="font-family: 宋体;"><span style="font-size: medium;"><span style="line-height: 1.3em;">小浣熊干脆面，里面还有小卡片，可是现在各类干脆面的始祖了 </span><br /></span></span></span><a href="http://pop.pcpop.com/p080120/0004718516.html" onclick="showLinkBubble(this);return false" target="_blank"></a><a href="http://img3.pcpop.com/upimg3/2008/1/20/0004718516.jpg" target="_blank"><span style="font-size: medium; font-family: 宋体;"><img src="http://img3.pcpop.com/upimg3/2008/1/20/0004718516.jpg" border="0" height="211" alt="" style="vertical-align: baseline! important;" width="240" /></span></a><br /><span style="line-height: 1.3em;"><span style="font-family: 宋体;"><span style="font-size: medium;"><span style="line-height: 1.3em;">华华丹有的地方叫老鼠屎，有一股中药味，很怀念那个小盒子 </span><br /></span></span></span><a href="http://pop.pcpop.com/p080120/0004718520.html" onclick="showLinkBubble(this);return false" target="_blank"></a><a href="http://img3.pcpop.com/upimg3/2008/1/20/0004718520.jpg" target="_blank"><span style="font-size: medium; font-family: 宋体;"><img src="http://img3.pcpop.com/upimg3/2008/1/20/0004718520.jpg" border="0" height="300" alt="" style="vertical-align: baseline! important;" width="300" /></span></a><br /><span style="line-height: 1.3em;"><span style="font-family: 宋体;"><span style="font-size: medium;"><span style="line-height: 1.3em;">大白兔奶糖，经典经典 </span><br /></span></span></span><a href="http://pop.pcpop.com/p080120/0004718526.html" onclick="showLinkBubble(this);return false" target="_blank"></a><a href="http://img3.pcpop.com/upimg3/2008/1/20/0004718526.jpg" target="_blank"><span style="font-size: medium; font-family: 宋体;"><img src="http://img3.pcpop.com/upimg3/2008/1/20/0004718526.jpg" border="0" height="667" alt="" style="vertical-align: baseline! important;" width="500" /></span></a><br /><span style="line-height: 1.3em;"><span style="font-family: 宋体;"><span style="font-size: medium;"><span style="line-height: 1.3em;">桔子糖水罐头，当时佳节馈赠亲友的佳品，也是小朋友的最爱 </span><br /></span></span></span><a href="http://pop.pcpop.com/p080120/0004718536.html" onclick="showLinkBubble(this);return false" target="_blank"></a><a href="http://img.pcpop.com/upimg3/2008/1/20/0004718536.jpg" target="_blank"><span style="font-size: medium; font-family: 宋体;"><img src="http://img.pcpop.com/upimg3/2008/1/20/0004718536.jpg" border="0" height="500" alt="" style="vertical-align: baseline! important;" width="500" /></span></a><br /><span style="line-height: 1.3em;"><span style="font-size: medium; line-height: 1.3em; font-family: 宋体;">亲亲虾条，吃了凑字还可以中奖 </span><a href="http://pop.pcpop.com/p080120/0004718537.html" onclick="showLinkBubble(this);return false" target="_blank"><span style="font-size: medium; line-height: 1.3em; font-family: 宋体;"><a href="http://img.pcpop.com/upimg3/2008/1/20/0004718537.jpg" target="_blank"><img src="http://img.pcpop.com/upimg3/2008/1/20/0004718537.jpg" border="0" height="500" alt="" style="vertical-align: baseline! important;" width="500" /></a></span></a></span><span style="line-height: 1.3em;"><span style="font-family: 宋体;"><span style="font-size: medium;"><span style="line-height: 1.3em;">大块糖！东北叫灶糖，呵呵 吃着很粘牙，冷的时候很硬很脆，暖和了就会变软 </span><br /></span></span></span><a href="http://pop.pcpop.com/p080120/0004718539.html" onclick="showLinkBubble(this);return false" target="_blank"></a><a href="http://img.pcpop.com/upimg3/2008/1/20/0004718539.jpg" target="_blank"><span style="font-size: medium; font-family: 宋体;"><img src="http://img.pcpop.com/upimg3/2008/1/20/0004718539.jpg" border="0" height="449" alt="" style="vertical-align: baseline! important;" width="350" /></span></a><br /><span style="line-height: 1.3em;"><span style="font-family: 宋体;"><span style="font-size: medium;"><span style="line-height: 1.3em;">经典的糖葫芦，地球人都知道 </span><br /></span></span></span><a href="http://pop.pcpop.com/p080120/0004718541.html" onclick="showLinkBubble(this);return false" target="_blank"></a><a href="http://img.pcpop.com/upimg3/2008/1/20/0004718541.jpg" target="_blank"><span style="font-size: medium; font-family: 宋体;"><img src="http://img.pcpop.com/upimg3/2008/1/20/0004718541.jpg" border="0" height="469" alt="" style="vertical-align: baseline! important;" width="500" /></span></a><br /><span style="line-height: 1.3em;"><span style="font-family: 宋体;"><span style="font-size: medium;"><span style="line-height: 1.3em;">找来找去也没找到张彩色的，是玉米用象蹦蹦车一样的机器弄出来的。有的叫姜酥糖或者就是脆香酥 </span><br /></span></span></span><a href="http://pop.pcpop.com/p080120/0004718549.html" onclick="showLinkBubble(this);return false" target="_blank"></a><a href="http://img.pcpop.com/upimg3/2008/1/20/0004718549.jpg" target="_blank"><span style="font-size: medium; font-family: 宋体;"><img src="http://img.pcpop.com/upimg3/2008/1/20/0004718549.jpg" border="0" height="600" alt="" style="vertical-align: baseline! important;" width="368" /></span></a><br /><br /><span style="line-height: 1.3em;"><span style="font-family: 宋体;"><span style="font-size: medium;"><span style="line-height: 1.3em;">再发个去包装纸的喔喔佳佳奶糖 </span><br /></span></span></span><a href="http://pop.pcpop.com/p080120/0004718557.html" onclick="showLinkBubble(this);return false" target="_blank"></a><a href="http://img.pcpop.com/upimg3/2008/1/20/0004718557.jpg" target="_blank"><span style="font-size: medium; font-family: 宋体;"><img src="http://img.pcpop.com/upimg3/2008/1/20/0004718557.jpg" border="0" height="250" alt="" style="vertical-align: baseline! important;" width="200" /></span></a><a href="http://pop.pcpop.com/p080120/0004718556.html" onclick="showLinkBubble(this);return false" target="_blank"></a><a href="http://img.pcpop.com/upimg3/2008/1/20/0004718556.jpg" target="_blank"><span style="font-size: medium; font-family: 宋体;"><img src="http://img.pcpop.com/upimg3/2008/1/20/0004718556.jpg" border="0" height="250" alt="" style="vertical-align: baseline! important;" width="200" /></span></a><br /><span style="line-height: 1.3em;"><span style="font-size: medium; line-height: 1.3em; font-family: 宋体;">小时候每家都有的麦乳精和麦乳精的瓶子 </span><a href="http://pop.pcpop.com/p080120/0004718565.html" onclick="showLinkBubble(this);return false" target="_blank"><span style="font-size: medium; line-height: 1.3em; font-family: 宋体;"><a href="http://img.pcpop.com/upimg3/2008/1/20/0004718565.jpg" target="_blank"><img src="http://img.pcpop.com/upimg3/2008/1/20/0004718565.jpg" border="0" height="405" alt="" style="vertical-align: baseline! important;" width="204" /></a></span></a></span><br /><br /><span style="line-height: 1.3em;"><span style="font-size: medium; line-height: 1.3em; font-family: 宋体;">酒心巧克力。原哈尔滨秋林的最正宗了，现在怎样不清楚了 </span><a href="http://pop.pcpop.com/p080120/0004718570.html" onclick="showLinkBubble(this);return false" target="_blank"><span style="font-size: medium; line-height: 1.3em; font-family: 宋体;"><a href="http://img.pcpop.com/upimg3/2008/1/20/0004718570.jpg" target="_blank"><img src="http://img.pcpop.com/upimg3/2008/1/20/0004718570.jpg" border="0" height="506" alt="" style="vertical-align: baseline! important;" width="400" /></a></span></a></span><span style="line-height: 1.3em;"><span style="font-family: 宋体;"><span style="font-size: medium;"><span style="line-height: 1.3em;">大沙果，不仅仅小孩，大人也喜欢，不仅仅以前，现在也喜欢 </span><br /></span></span><a href="http://pop.pcpop.com/p080120/0004718574.html" onclick="showLinkBubble(this);return false" target="_blank"><span style="font-size: medium; line-height: 1.3em; font-family: 宋体;"><a href="http://img.pcpop.com/upimg3/2008/1/20/0004718574.jpg" target="_blank"><img src="http://img.pcpop.com/upimg3/2008/1/20/0004718574.jpg" border="0" height="333" alt="" style="vertical-align: baseline! important;" width="500" /></a></span></a></span><br /><span style="line-height: 1.3em;"><span style="font-family: 宋体;"><span style="font-size: medium;"><span style="line-height: 1.3em;">黑悠悠儿也叫黑星星，太怀念摘一大缸子然后倒在嘴里的感觉了 </span><br /></span></span><a href="http://pop.pcpop.com/p080120/0004718581.html" onclick="showLinkBubble(this);return false" target="_blank"><span style="font-size: medium; line-height: 1.3em; font-family: 宋体;"><a href="http://img.pcpop.com/upimg3/2008/1/20/0004718581.jpg" target="_blank"><img src="http://img.pcpop.com/upimg3/2008/1/20/0004718581.jpg" border="0" height="517" alt="" style="vertical-align: baseline! important;" width="400" /></a></span></a></span><br /><span style="line-height: 1.3em;"><span style="font-family: 宋体;"><span style="font-size: medium;"><span style="line-height: 1.3em;">姑鸟儿，东北叫法，广东叫红果娘子，很甜，没成熟的还可以挖空放在嘴里压出响来，是吃的也是玩具 </span><br /></span></span></span><a href="http://pop.pcpop.com/p080120/0004718585.html" onclick="showLinkBubble(this);return false" target="_blank"></a><a href="http://img.pcpop.com/upimg3/2008/1/20/0004718585.jpg" target="_blank"><span style="font-size: medium; font-family: 宋体;"><img src="http://img.pcpop.com/upimg3/2008/1/20/0004718585.jpg" border="0" height="453" alt="" style="vertical-align: baseline! important;" width="465" /></span></a><br /><span style="line-height: 1.3em;"><span style="font-family: 宋体;"><span style="font-size: medium;"><span style="line-height: 1.3em;">菱角，好像是出自水里的，里面的瓤是面的 </span><br /></span></span></span><a href="http://pop.pcpop.com/p080120/0004718593.html" onclick="showLinkBubble(this);return false" target="_blank"></a><a href="http://img.pcpop.com/upimg3/2008/1/20/0004718593.jpg" target="_blank"><span style="font-size: medium; font-family: 宋体;"><img src="http://img.pcpop.com/upimg3/2008/1/20/0004718593.jpg" border="0" height="377" alt="" style="vertical-align: baseline! important;" width="500" /></span></a><br /><span style="line-height: 1.3em;"><span style="font-family: 宋体;"><span style="font-size: medium;"><span style="line-height: 1.3em;">烤地瓜，香喷喷 </span><br /></span></span></span><a href="http://pop.pcpop.com/p080120/0004718595.html" onclick="showLinkBubble(this);return false" target="_blank"></a><a href="http://img.pcpop.com/upimg3/2008/1/20/0004718595.jpg" target="_blank"><span style="font-size: medium; font-family: 宋体;"><img src="http://img.pcpop.com/upimg3/2008/1/20/0004718595.jpg" border="0" height="237" alt="" style="vertical-align: baseline! important;" width="494" /></span></a><br /><br /><span style="line-height: 1.3em;"><span style="font-family: 宋体;"><span style="font-size: medium;"><span style="line-height: 1.3em;">烤土豆，更香喷喷 </span><br /></span></span></span><a href="http://pop.pcpop.com/p080120/0004718596.html" onclick="showLinkBubble(this);return false" target="_blank"></a><a href="http://img.pcpop.com/upimg3/2008/1/20/0004718596.jpg" target="_blank"><span style="font-size: medium; font-family: 宋体;"><img src="http://img.pcpop.com/upimg3/2008/1/20/0004718596.jpg" border="0" height="375" alt="" style="vertical-align: baseline! important;" width="500" /></span></a><br /><span style="font-family: 宋体;"><span style="font-size: medium;"><span style="line-height: 1.3em;"><span style="line-height: 1.3em;">烤玉米，单纯的放在火上烤，不是象现在加那些调味料，干干的很香，如果用甜苞米一定更好 </span></span><span style="line-height: 1.3em;"><a href="http://pop.pcpop.com/p080120/0004718602.html" onclick="showLinkBubble(this);return false" target="_blank"></a><a href="http://img.pcpop.com/upimg3/2008/1/20/0004718602.jpg" target="_blank"><img src="http://img.pcpop.com/upimg3/2008/1/20/0004718602.jpg" border="0" height="375" alt="" style="vertical-align: baseline! important;" width="500" /></a></span><br /></span></span><span style="line-height: 1.3em;"><span style="font-family: 宋体;"><span style="font-size: medium;"><span style="line-height: 1.3em;">以前一种出去吃饭就要喝的饮料：粒粒橙: </span><br /></span></span></span><a href="http://pop.pcpop.com/p080120/0004718603.html" onclick="showLinkBubble(this);return false" target="_blank"></a><a href="http://img.pcpop.com/upimg3/2008/1/20/0004718603.jpg" target="_blank"><span style="font-size: medium; font-family: 宋体;"><img src="http://img.pcpop.com/upimg3/2008/1/20/0004718603.jpg" border="0" height="427" alt="" style="vertical-align: baseline! important;" width="500" /></span></a><br /><span style="line-height: 1.3em;"><span style="font-size: medium; line-height: 1.3em; font-family: 宋体;">冬天一定要吃的冻柿子 </span><a href="http://pop.pcpop.com/p080120/0004718610.html" onclick="showLinkBubble(this);return false" target="_blank"><span style="font-size: medium; line-height: 1.3em; font-family: 宋体;"><a href="http://img.pcpop.com/upimg3/2008/1/20/0004718610.jpg" target="_blank"><img src="http://img.pcpop.com/upimg3/2008/1/20/0004718610.jpg" border="0" height="336" alt="" style="vertical-align: baseline! important;" width="448" /></a></span></a></span><br /><span style="line-height: 1.3em;"><span style="font-family: 宋体;"><span style="font-size: medium;"><span style="line-height: 1.3em;">还有冻梨、冻梨 </span><br /></span></span><a href="http://pop.pcpop.com/p080120/0004718613.html" onclick="showLinkBubble(this);return false" target="_blank"><span style="font-size: medium; line-height: 1.3em; font-family: 宋体;"><a href="http://img.pcpop.com/upimg3/2008/1/20/0004718613.jpg" target="_blank"><img src="http://img.pcpop.com/upimg3/2008/1/20/0004718613.jpg" border="0" height="213" alt="" style="vertical-align: baseline! important;" width="283" /></a></span></a></span><br /><span style="line-height: 1.3em;"><span style="font-family: 宋体;"><span style="font-size: medium;"><span style="line-height: 1.3em;">嘿嘿，这就是相声里的江米条了 </span><br /></span></span><a href="http://pop.pcpop.com/p080120/0004718615.html" onclick="showLinkBubble(this);return false" target="_blank"><span style="font-size: medium; line-height: 1.3em; font-family: 宋体;"><a href="http://img.pcpop.com/upimg3/2008/1/20/0004718615.jpg" target="_blank"><img src="http://img.pcpop.com/upimg3/2008/1/20/0004718615.jpg" border="0" height="389" alt="" style="vertical-align: baseline! important;" width="400" /></a></span></a></span><br /><span style="line-height: 1.3em;"><span style="font-family: 宋体;"><span style="font-size: medium;"><span style="line-height: 1.3em;">江米条的妹妹江米球 </span><br /></span></span><a href="http://pop.pcpop.com/p080120/0004718618.html" onclick="showLinkBubble(this);return false" target="_blank"><span style="font-size: medium; line-height: 1.3em; font-family: 宋体;"><a href="http://img.pcpop.com/upimg3/2008/1/20/0004718618.jpg" target="_blank"><img src="http://img.pcpop.com/upimg3/2008/1/20/0004718618.jpg" border="0" height="453" alt="" style="vertical-align: baseline! important;" width="400" /></a></span></a></span><br /><span style="line-height: 1.3em;"><span style="font-family: 宋体;"><span style="font-size: medium;"><span style="line-height: 1.3em;">麻团 </span><br /></span></span><a href="http://pop.pcpop.com/p080120/0004718622.html" onclick="showLinkBubble(this);return false" target="_blank"><span style="font-size: medium; line-height: 1.3em; font-family: 宋体;"><a href="http://img.pcpop.com/upimg3/2008/1/20/0004718622.jpg" target="_blank"><img src="http://img.pcpop.com/upimg3/2008/1/20/0004718622.jpg" border="0" height="640" alt="" style="vertical-align: baseline! important;" width="480" /></a></span></a></span></p>
          <br/><br/>
          <span style="color:red;">
            <a href="http://joanzq.javaeye.com/blog/195263#comments" style="color:red;">已有 <strong>11</strong> 人发表留言，猛击-&gt;&gt;<strong>这里</strong>&lt;&lt;-参与讨论</a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">Windows7在微软WinHEC 2008上揭开神秘面纱</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 21 May 2008 14:27:28 +0800</pubDate>
        <link>http://joanzq.javaeye.com/blog/195263</link>
        <guid>http://joanzq.javaeye.com/blog/195263</guid>
      </item>
          <item>
        <title>打扑克到软件开发的方式</title>
        <author>joanzq</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://joanzq.javaeye.com">joanzq</a>&nbsp;
                    链接：<a href="http://joanzq.javaeye.com/blog/195247" style="color:red;">http://joanzq.javaeye.com/blog/195247</a>&nbsp;
          发表时间: 2008年05月21日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 学习打扑克和学习软件开发的方式是一样的：尽可能多读书。我用两年的时间，读完了所能找到的每一本有关扑克的书。最后竟至39本之多。编程亦如是。此刻，我面前仍然摆着接下来要读的5本书；而在过去三年ThoughtWorks的工作中，我放火烧掉的书亦不在少数。 <br />我认为，无论编程还是玩牌，阅读书籍、博客与杂志都是要想有所成就的必备条件；而若要以二者为谋生之业，仅靠读书却是远远不够的。也许你可以把书本上的一切知识都装入脑中，但知道在何时应用何种规则，这才是真正高手的标志。 <br />诚然，开卷有益。但总要走过万里路，方能对应用特定技术的具体环境烂熟于心。书本不可能把所有情况都囊括一空，只有通过亲身体会得来的经验，才能让你在某些状况下为自己或是雇主做出快速而正确的决策，而这些决策可能价值几千乃至数百万美元。 <br />经验之宝贵，世间无物可代。 <br />艺术的巅峰你可以设计出击败普通扑克玩家的计算机程序。遵守一些基本规则，自然就可获胜。但迄今为止，还没有任何程序可以击败最好的扑克玩家。因为扑克技能达到巅峰时，也就成了一门艺术。软件开发亦如是。要想成为一个还不错的开发者，只要遵循一系列最佳实践即可。如果按照经典参考指南一类的书籍行事，开发出还不错的应用程序应该不成问题，而且效果会胜过其他最常见的做法。有了这么多失败的项目作为前车之鉴，我相信，还不错的应用就足以令大多数管理层甘心掏腰包了。 <br />当然，有些经理有更高的标准。在银行、创业公司、医疗系统等领域，标准则更为严苛。&ldquo;还不错&rdquo;自是远远不够。那些经理会很乐意为最佳选择买单，他们期待的是远超常人的技能。但问题在于，专家级程序员的技能与普通程序员不同。普通程序员知道做事的方式；专家知道做事的目的。普通程序员会僵化跟随模式书籍中的指示，就如遵守参考指南一般；专家则明白对模式的创新可能会带来指数级的性能改善。 <br />他们看到的绝非同一个世界，所以普通程序员很难跟专家对面交流。做艺术评论家易，做优秀的艺术评论家难。 <br />决策技能 在扑克和编程中有一条绝对真理：几乎没人能像他自我感觉的那么良好。有自知之明是不错的开始，但人们依然很难知道自己与专家之间的差距。程序员接触专家的机会并不多，也就无法公正评判自己的技能。在牌桌上，每个人都是为了锦标而来，可大多数人都会过高评价自己的牌技，这总是让我惊讶不已。 <br />程序员之间亦是如此，而且大多数人可以获得的信息更少得可怜。一个从不参加任何大会的技术领导人，只能跟自己的团队成员一比高下。当然，他可能已经很优秀了，否则也不会成为技术领导。但如果与整个行业中最出类拔萃的人相比，他又处于什么位置？如果觉得在自己的圈子里已经一览众山小了，那碰到不同意见时，他又会作何反应？有些人会视之为学习的契机并为此感到兴奋，但绝大多数都会对不同意见嗤之以鼻。 <br />团队协作 乍看上去，扑克是一种彼此对抗的游戏。但事实很少如是。即使在赌注最小的牌桌上，通常也至少会有几个人常打交道。他们不会达成条件一致对付牌桌上的其他人&mdash;&mdash;他们也不必如此。大家都明白一条道理：你不是要去跟牌玩得好的人对着干，赢他们的钱，而是要从水平低的人身上赚钱。专业牌手甚至会像一个团队一样协同工作。有些人彼此利益相关，故而一人得利则众人均有收益。他们不仅互相了解，而且认识很多人。如果出现一局精彩牌局，楼层经理会跟他们打招呼；侍者会为他们的对手调制酒精度高的饮品；荷官会故意&ldquo;犯错&rdquo;以影响某人心情（很少有人在心情不好的时候能够打好牌）。每个人都在协同工作，确保大家都能挣到钱。 <br />颇为有趣的是，程序员的情况也与之相似。很多人都坐在格子里，完全依赖自己解决问题。他们往往工作在代码个人独有制模式之下。我曾亲眼目睹，在这种程序员交付的应用中，集成问题一直都是大家的心病。而更为不幸的是，集成之痛还只是最小的问题。假设IT部门把业务需求锁定为500页的需求文档。如果公司决定改变业务方向，随之而来的系统变更需求将令人痛不欲生。数以百万计的金钱付诸东流，因为程序员开发的特性已不再具备业务价值，而IT部门还没有找到更好的方式来应对业务变化。 <br />当然，情况并非总是如此。专家懂得协作。他们会跟其他专家协作，但也不排斥与经理、客户、业务部门、分析师、质保人员，以及所有可以为成功贡献力量的人协作。他们胸怀大局：只有协作，才能让每个人有所收获。 <br />度量 雄心勃勃的牌手常常讨论他们赢了多少手牌，又输了多少手。他们讨论最多的还是本该赢但却输掉的那几手牌。有时人们会犯错误输钱，但他们一般都不会记得这几手是怎么输掉的。相反的是，如果有些牌局只是因为手气不好而输掉，他们就会记得那一局中的每一处细节，他们还会在故事中透露对手必然获胜的几率，来证明自己根本没有胜出的机会。真正的牌手知道他们输掉过多少手牌，以及失败的大概几率。他们懂得度量。而且专业牌手会专注于重要的度量标准。你赢了多少手，输了多少手，这无关紧要；重要的是你赢了多少钱，输了多少钱。而且，为你的狗屎运（<strong>译者注</strong>：bad beat，即开局时输家比赢家牌好，赢的几率更大，但关键时刻赢家却来了更好的牌。碰到狗屎运&mdash;&mdash;take a bad beat&mdash;&mdash;用来形容输家，来了狗屎运&mdash;&mdash;lay a bad beat&mdash;&mdash;用来形容赢家）苦恼实际上等于替你对手的牌运犯愁。既然你的收入来自于对手的错误，那你就是在抱怨为什么对手把钱给了你。 <br />有度量标准是好事，不过专业人士懂得哪些标准重要，哪些只会分散注意力，哪些介于二者之间。 <br />软件开发也有很多度量标准，而且有很多标准身上的光环已经远远超出了它们所应有的范围。例如，知道代码行数几乎不能带来任何价值。复杂应用需要相当多的代码，但这个&ldquo;相当&rdquo;到底是多少？它得依赖于语言、工具及其他因素。 <br />修复的bug数量也是个很有趣的话题，只是略逊于前一个。为什么人们会在乎修复了多少个bug？Bug数量也许有其价值，但是修复的bug数目并不能为我们带来多少有用信息。 <br />特性完成率是我自己最喜欢把玩的一个标准。除非我们使用特性来评估工作量，否则知道完成了多少特性又有何用？而且，如果已经对工作量做出了评估，那为什么不把剩余工作与已完成工作相比较，从而得到工作进度呢？我很难从特性完成率中看到价值所在。 <br />代码覆盖率让我想起了记录狗屎运。这项度量是有意义的，但很多人都没抓住重点。代码覆盖率低意味着可能有问题存在，但是代码覆盖率高只能表示你有一个很大的代码覆盖率数值。高代码覆盖率与高质量之间没有必然联系。 <br />注意人，而不是逻辑 如果看过有玩牌镜头出现的电影，你大概听过这样一句话：你不是在与扑克玩，而是与人玩。此言极是。牌手无疑都是心理学家。有时你确实需要某些牌，但拿一手好牌只是赚钱的一部分而已。一旦有了好牌，你就需要知道怎样利用好它们。你是应该加注，还是先让牌然后加注，还是彻底让牌，还是跟进？这些做法依赖于很多因素，但关键还是要了解牌桌上的对手。当你得到一手好牌，首要目标就是尽可能多地从对手那里赢钱，而达到这种目的的唯一方式则是想办法让对手给你更多的钱。了解逻辑可以帮助你赢得几手牌，了解人则可以帮助你赢钱。 <br />在交付软件时，人处于同样重要的地位。如果软件只是让一切工作起来，那只要把它变成自动化的工作，事情就容易得多了。但软件却远非功能组合这么简单。在一场高尔夫球比赛中，人们会卖出软件包；在全家到迪斯尼免费旅游时，人们会签下软件服务合同；为了避免法律纠纷，人们会履行合同去构建已经毫无用处的软件；为了超越竞争对手，人们会使用软件来加快业务响应速度。 <br />人们使用软件、开发软件、维护软件，或是在某种程度上依赖软件。软件开发与这个世界有着千丝万缕的联系，要把洋洋洒洒的变量组合成简单方程，生产出高质量的软件，又与登天何异？但是，软件开发高手需要考虑每个人引入的所有已知与未知的变量，做出他们力所能及的推测。知道应该做什么会让你受益，而知道必须做什么所带来的价值却是难以衡量。了解逻辑可以帮助你交付应用，了解人则可以帮助你交付价值。 <br />在残缺的信息下工作 有关这点，刚开始打牌的人处理的非常好：打好每一手牌，老老实实押注，从不虚张声势。这便是了，新手就应该只做该做的事情，除非你的钱多得没地方花了。难点在于如何从初学者的水平提升。大量信息霎那间纷至沓来，你需要注意牌桌上每个人的每一处细节：他们怎样交流，你从前跟他们每个人打过什么交道，他们所钟爱的玩牌方式，谁在赢，谁在输，凡此种种不一而足。而且，你也不可能知道对手手里的牌是什么，下一张牌又是什么。你所拥有的信息已超出所能处理的极限，而且这远非全部。 <br />编程亦如是。领域专家无所不知，但把一切都向你倾囊相授却毫无意义。何况，你也不一定需要所有的领域知识。你需要熟悉团队，但同事总有些事情是你永远无法知晓，或者不能完全理解的。不过，编程高手能够把必要的领域知识融会贯通，掌握团队的动态，并始终提供技术上的真知灼见。他们知道他们永远无法成为百晓生，他们知道什么事情值得思考，哪些应该置之不理。纵使面前汹涌澎湃的信息仍是残缺不全，他们也总能做出正确的决定。 <br />即时反馈 普通牌手在反馈信息少的游戏中表现最好。因为牌手是根据信息而赢钱的。在5张牌梭哈中只有一轮押注的机会。各位玩家只有一次机会来分析你给出的信息，而你也只有一次机会犯错。专家级牌手更喜欢多轮的游戏。游戏中的回合数越多，他们就有越多机会从低水平的对手身上捞到好处。他们喜欢即时反馈，并根据反馈做出调整。在有多个回合的游戏中，每一个回合都可以得到反馈，专业玩家就会根据当前局势调整打法。 <br />编程高手同样喜欢即时反馈。从业务人员即时反馈回来的信息，可以避免你在构建业务应用时走上弯路。从另一个程序员即时反馈回来的信息，可以在软件产品化之前发现bug。持续集成服务器可以提供即时的集成反馈，从而避免集成之痛。喜欢敏捷的人能马上说出迭代是一个有着显著成效的实践，因为它可以让程序员和业务人员得到即时反馈。不过，作为一个编程高手，纵使他不喜欢敏捷，他也能够意识到即时反馈的价值；即使在非敏捷的环境中，他也会争取得到更多的反馈，从而避免浪费时间精力。即时反馈可以让你了解前行的方向正确与否，每一个专家都会珍视这些信息。 <br />上下文为王 无论扑克还是编程，没有绝对正确或是绝对错误的选择。如果你有一对K，那么在翻牌之前你该不跟么？也许吧。这要看你是在打比赛还是赌钱、有上限还是没上限、你坐在哪个位置上、你是否已经不跟过一次还是已经封顶了等等。我在扑克中学到了一点，那就是在给出答案之前，一定要综合考虑所有的因素。 <br />在编程中沉浸的时间愈久，同样的体会在我心里就愈加深刻。Java在有些时候是不错的选择，但它并非万能。所有的编程语言均如此。工具亦然。Hibernate很不错，但它不适用的地方还有IBatis，当IBatis也不适用的地方还会出现或自己创造新的解决方案。几乎没有一款解决方案能够绝对有效，它只有在恰当的形势下才会发挥应有的作用。在错误的环境中，它也许会成为毒药。 <br />所以，面对一门新的语言或者工具，无论是你是打算弃若敝履，或是爱不释手推而广之，不妨先想想它的适用环境，尽量做到对症下药，量体裁衣。<img src="http://imgcache.qq.com/ac/qzone_v4/b.gif" id="paperPicArea1" alt="" style="display: none; position: relative;" /></p>
<p>&nbsp;</p>
<p>&nbsp;(转载 <strong>查看英文原文</strong>：<a href="http://www.infoq.com/articles/fields-it-depends" onclick="showLinkBubble(this);return false" target="_blank">Software Development Lessons Learned from Poker</a>)</p>
          <br/><br/>
          <span style="color:red;">
            <a href="http://joanzq.javaeye.com/blog/195247#comments" style="color:red;">已有 <strong>0</strong> 人发表留言，猛击-&gt;&gt;<strong>这里</strong>&lt;&lt;-参与讨论</a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">Windows7在微软WinHEC 2008上揭开神秘面纱</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 21 May 2008 14:05:09 +0800</pubDate>
        <link>http://joanzq.javaeye.com/blog/195247</link>
        <guid>http://joanzq.javaeye.com/blog/195247</guid>
      </item>
          <item>
        <title>cannnot find the Word template : WordToRqm.dot</title>
        <author>joanzq</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://joanzq.javaeye.com">joanzq</a>&nbsp;
                    链接：<a href="http://joanzq.javaeye.com/blog/195203" style="color:red;">http://joanzq.javaeye.com/blog/195203</a>&nbsp;
          发表时间: 2008年05月21日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;出现这种情况的原因好像是安裝了power designer 12的原因。 使用word时发生了这种情况 ：<strong>cannnot find the Word template : <em>WordToRqm.dot</em></strong><br />运行regedit.exe 打开注册表编辑器，定位到：HKEY_CURRENT_USER\Software\Microsoft\Office\Word\Addins\WordToRQM12.Connect 键，双击右边的&ldquo;LoadBehavior&rdquo;，在弹出的修改值对话框中将其值从3改为2，然后关闭注册表编辑器，重新启动Word。</p>
          <br/><br/>
          <span style="color:red;">
            <a href="http://joanzq.javaeye.com/blog/195203#comments" style="color:red;">已有 <strong>0</strong> 人发表留言，猛击-&gt;&gt;<strong>这里</strong>&lt;&lt;-参与讨论</a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">Windows7在微软WinHEC 2008上揭开神秘面纱</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 21 May 2008 12:52:54 +0800</pubDate>
        <link>http://joanzq.javaeye.com/blog/195203</link>
        <guid>http://joanzq.javaeye.com/blog/195203</guid>
      </item>
          <item>
        <title>CSS 推荐样式 换行</title>
        <author>joanzq</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://joanzq.javaeye.com">joanzq</a>&nbsp;
                    链接：<a href="http://joanzq.javaeye.com/blog/191455" style="color:red;">http://joanzq.javaeye.com/blog/191455</a>&nbsp;
          发表时间: 2008年05月09日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>&nbsp;在项目实际应用中出现了表格的内容不会换行，本文列举了兼容 IE 和 FF 的换行 CSS 推荐样式，详细介绍了word-wrap和word-break的区别。 </p>
<p>&nbsp;</p>
<p>兼容 IE 和 FF 的换行 CSS 推荐样式 最好的方式是 </p>
<p>&nbsp;</p>
<p>word-wrap:break-word; overflow:hidden;</p>
<p>而不是 </p>
<p>&nbsp;</p>
<p>word-wrap:break-word; word-break:break-all;</p>
<p>也不是 </p>
<p>&nbsp;</p>
<p>word-wrap:break-word; overflow:auto;</p>
<p>在 IE 下没有任何问题，在 FF 下，长串英文会被遮住超出的内容。 </p>
<p>&nbsp;</p>
<p>word-wrap同word-break的区别</p>
<p>
<table cellspacing="0" border="0" align="center" width="95%" cellpadding="6" style="table-layout: fixed; border: #cccccc 1px dotted;">
<tbody>
<tr>
<td bgcolor="#fdfddf" style="word-wrap: break-word;"><span style="color: #ff0000;">以下为引用的内容：</span><br />
<p>word-wrap:<br />normal&nbsp;&nbsp; Default. Content exceeds the boundaries of its container. <br />break-word Content wraps to next line, and a word-break occurs when necessary. 必要时会触发word-break。</p>
<p>word-break:<br />normal&nbsp;&nbsp; Default. Allows line breaking within words. 好像是只对Asian text起作用。<br />break-all Behaves the same as normal for Asian text, yet allows the line to break arbitrarily for non-Asian text. This value is suited to Asian text that contains some excerpts of non-Asian text. <br />keep-all Does not allow word breaking for Chinese, Japanese, and Korean. Functions the same way as normal for all non-Asian languages. This value is optimized for text that includes small amounts of Chinese, Japanese, or Korean. </p>
</td>
</tr>
</tbody>
</table>
</p>
<p>总结如下： </p>
<p>&nbsp;</p>
<p>word-wrap是控制换行的。 </p>
<p>&nbsp;</p>
<p>使用break-word时，是将强制换行。中文没有任何问题，英文语句也没问题。但是对于长串的英文，就不起作用。</p>
<p>break-word是控制是否断词的。 </p>
<p>&nbsp;</p>
<p>normal是默认情况，英文单词不被拆开。</p>
<p>break-all，是断开单词。在单词到边界时，下个字母自动到下一行。主要解决了长串英文的问题。 </p>
<p>keep-all，是指Chinese, Japanese, and Korean不断词。即只用此时，不用word-wrap，中文就不会换行了。（英文语句正常。）<span style="color: #f5fafe;">力</span> </p>
<p>ie下：</p>
<p>使用word-wrap:break-word;所有的都正常。</p>
<p>ff下： </p>
<p>&nbsp;</p>
<p>如这2个都不用的话，中文不会出任何问题。英文语句也不会出问题。但是，长串英文会出问题。</p>
<p>为了解决长串英文，一般用word-wrap:break-word;word-break:break-all;。但是，此方式会导致，普通的英文语句中的单词会被断开（ie下也是）。目前主要的问题存在于 长串英文 和 英文单词被断开。其实长串英文就是一个比较长的单词而已。 </p>
<p>&nbsp;</p>
<p>即英文单词应不应该被断开那？那问题很明显了，显然不应该被断开了。 </p>
<p>&nbsp;</p>
<p>对于长串英文，就是恶意的东西，自然不用去管了。但是，也要想些办法，不让它把容器撑大。</p>
<p>用：overflow:auto; ie下，长串会自动折行。ff下，长串会被遮盖。</p>
<p>所以，综上，最好的方式是word-wrap:break-word;overflow:hidden;而不是word-wrap:break-word;word-break:break-all;。 </p>
<p>&nbsp;</p>
<p>word-wrap:break-word;overflow:auto;在ie下没有任何问题。在ff下，长串会被遮住部分内容。</p>
<p>另，测试代码如下： </p>
<p>
<table cellspacing="0" border="0" align="center" width="95%" cellpadding="6" style="table-layout: fixed; border: #cccccc 1px dotted;">
<tbody>
<tr>
<td bgcolor="#fdfddf" style="word-wrap: break-word;"><span style="color: #ff0000;">以下为引用的内容：</span><br />
<p>1.htm============</p>
<p>&nbsp;</p>
<p>&lt;style&gt;<br />.c1{ width:300px;&nbsp;&nbsp; border:1px solid red}<br />.c2{ width:300px;word-wrap:break-word;&nbsp;&nbsp; border:1px solid yellow}<br />.c3{ width:300px;word-wrap:break-word;word-break:break-all;&nbsp;&nbsp; border:1px solid green}<br />.c4{ width:300px;word-wrap:break-word;word-break:keep-all; border:1px solid blue}<br />.c5{ width:300px;word-break:break-all;&nbsp;&nbsp; border:1px solid black}<br />.c6{ width:300px;word-break:keep-all;&nbsp;&nbsp; border:1px solid red}<br />.c7{ width:300px;word-wrap:break-word;overflow:auto;&nbsp;&nbsp; border:1px solid yellow}<br />&lt;/style&gt; </p>
<p>.c1{ width:300px;&nbsp;&nbsp; border:1px solid red}<br />&lt;div class="c1"&gt;<br />safjaskflasjfklsajfklasjflksajflksjflkasjfksafj<br />&lt;/div&gt;<br />&lt;div class=c1&gt;<br />This is all English. This is all English. This is all English.<br />&lt;/div&gt;<br />&lt;div class=c1&gt;<br />全是中文的情况。全是中文的情况。全是中文的情况。<br />&lt;/div&gt;<br />&lt;div class=c1&gt;<br />中英文混排的情况。Chinese and English. 中英文混排的情况。Chinese and English. <br />&lt;/div&gt; </p>
<p>&nbsp;</p>
<p>&lt;br&gt;<br />.c2{ width:300px;word-wrap:break-word; border:1px solid yellow}<br />&lt;div class="c2"&gt;<br />safjaskflasjfklsajfklasjflksajflksjflkasjfksafj<br />&lt;/div&gt;<br />&lt;div class=c2&gt;<br />This is all English. This is all English. This is all English.<br />&lt;/div&gt;<br />&lt;div class=c2&gt;<br />全是中文的情况。全是中文的情况。全是中文的情况。<br />&lt;/div&gt;<br />&lt;div class=c2&gt;<br />中英文混排的情况。Chinese and English. 中英文混排的情况。Chinese and English. <br />&lt;/div&gt;</p>
<p>&lt;br&gt;<br />.c3{ width:300px;word-wrap:break-word;word-break:break-all;&nbsp;&nbsp; border:1px solid green}<br />&lt;div class="c3"&gt;<br />safjaskflasjfklsajfklasjflksajflksjflkasjfksafj<br />&lt;/div&gt;<br />&lt;div class=c3&gt;<br />This is all English. This is all English. This is all English.<br />&lt;/div&gt;<br />&lt;div class=c3&gt;<br />全是中文的情况。全是中文的情况。全是中文的情况。<br />&lt;/div&gt;<br />&lt;div class=c3&gt;<br />中英文混排的情况。Chinese and English. 中英文混排的情况。Chinese and English. <br />&lt;/div&gt; </p>
<p>&nbsp;</p>
<p>&lt;br&gt;<br />.c4{ width:300px;word-wrap:break-word;word-break:keep-all; border:1px solid blue}<br />&lt;div class="c4"&gt;<br />safjaskflasjfklsajfklasjflksajflksjflkasjfksafj<br />&lt;/div&gt;<br />&lt;div class=c4&gt;<br />This is all English. This is all English. This is all English.<br />&lt;/div&gt;<br />&lt;div class=c4&gt;<br />全是中文的情况。全是中文的情况。全是中文的情况。<br />&lt;/div&gt;<br />&lt;div class=c4&gt;<br />中英文混排的情况。Chinese and English. 中英文混排的情况。Chinese and English. <br />&lt;/div&gt;</p>
<p>&lt;br&gt;<br />.c5{ width:300px;word-break:break-all;&nbsp;&nbsp; border:1px solid black}<br />&lt;div class="c5"&gt;<br />safjaskflasjfklsajfklasjflksajflksjflkasjfksafj<br />&lt;/div&gt;<br />&lt;div class=c5&gt;<br />This is all English. This is all English. This is all English.<br />&lt;/div&gt;<br />&lt;div class=c5&gt;<br />全是中文的情况。全是中文的情况。全是中文的情况。<br />&lt;/div&gt;<br />&lt;div class=c5&gt;<br />中英文混排的情况。Chinese and English. 中英文混排的情况。Chinese and English. <br />&lt;/div&gt;</p>
<p>&lt;br&gt;<br />.c6{ width:300px;word-break:keep-all;&nbsp;&nbsp; border:1px solid red}<br />&lt;div class="c6"&gt;<br />safjaskflasjfklsajfklasjflksajflksjflkasjfksafj<br />&lt;/div&gt;<br />&lt;div class=c6&gt;<br />This is all English. This is all English. This is all English.<br />&lt;/div&gt;<br />&lt;div class=c6&gt;<br />全是中文的情况。全是中文的情况。全是中文的情况。<br />&lt;/div&gt;<br />&lt;div class=c6&gt;<br />中英文混排的情况。Chinese and English. 中英文混排的情况。Chinese and English. <br />&lt;/div&gt;</p>
<p>&lt;br&gt;<br />.c7{ width:300px;word-wrap:break-word;overflow:auto;&nbsp;&nbsp; border:1px solid yellow}<br />&lt;div class="c7"&gt;<br />safjaskflasjfklsajfklasjflksajflksjflkasjfksafj<br />&lt;/div&gt;<br />&lt;div class=c7&gt;<br />This is all English. This is all English. This is all English.<br />&lt;/div&gt;<br />&lt;div class=c7&gt;<br />全是中文的情况。全是中文的情况。全是中文的情况。<br />&lt;/div&gt;<br />&lt;div class=c7&gt;<br />中英文混排的情况。Chinese and English. 中英文混排的情况。Chinese and English. <br />&lt;/div&gt;</p>
</td>
</tr>
</tbody>
</table>
</p>
          <br/><br/>
          <span style="color:red;">
            <a href="http://joanzq.javaeye.com/blog/191455#comments" style="color:red;">已有 <strong>0</strong> 人发表留言，猛击-&gt;&gt;<strong>这里</strong>&lt;&lt;-参与讨论</a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">Windows7在微软WinHEC 2008上揭开神秘面纱</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Fri, 09 May 2008 15:32:57 +0800</pubDate>
        <link>http://joanzq.javaeye.com/blog/191455</link>
        <guid>http://joanzq.javaeye.com/blog/191455</guid>
      </item>
          <item>
        <title> Exploded location overlaps an existing deployment</title>
        <author>joanzq</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://joanzq.javaeye.com">joanzq</a>&nbsp;
                    链接：<a href="http://joanzq.javaeye.com/blog/189167" style="color:red;">http://joanzq.javaeye.com/blog/189167</a>&nbsp;
          发表时间: 2008年05月04日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; tomcat 使用时加载部署项目出现 &ldquo;Exploded location overlaps an existing deployment&rdquo; 的解决方法。&nbsp;&nbsp;tomcat 因为有着开源，免费等的优点得到广大的使用群就不说了。如果你在使用 tomcat 时也出现 &ldquo;Exploded location overlaps an existing deployment&rdquo;&nbsp;并且它的三个按钮都是灰色不可用状态。&nbsp;不妨试一下看看可否解决问题。</p>
<p>1 .找到你的tomcat 的部署地址如 &nbsp; C:\Program Files\Apache Software Foundation\Tomcat 6.0\webapps和 C:\Program Files\Apache Software Foundation\Tomcat 6.0\work\Catalina\localhost&nbsp;&nbsp;&nbsp; 看下是否有你现在要发布的项目。如果没有请新建一个 文件夹 更名为你要部署的项目的名称 </p>
<p>2 回到你的myeclipse&nbsp; ，点击部署delopy J2EE projects to server ....&nbsp;&nbsp; </p>
<p>相信这样应该可以解决&ldquo;Exploded location overlaps an existing deployment&rdquo; 这个问题了。 我是这样解决这个问题的。</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
          <br/><br/>
          <span style="color:red;">
            <a href="http://joanzq.javaeye.com/blog/189167#comments" style="color:red;">已有 <strong>1</strong> 人发表留言，猛击-&gt;&gt;<strong>这里</strong>&lt;&lt;-参与讨论</a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">Windows7在微软WinHEC 2008上揭开神秘面纱</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sun, 04 May 2008 09:18:06 +0800</pubDate>
        <link>http://joanzq.javaeye.com/blog/189167</link>
        <guid>http://joanzq.javaeye.com/blog/189167</guid>
      </item>
          <item>
        <title>ＪＳ正则表达式</title>
        <author>joanzq</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://joanzq.javaeye.com">joanzq</a>&nbsp;
                    链接：<a href="http://joanzq.javaeye.com/blog/176318" style="color:red;">http://joanzq.javaeye.com/blog/176318</a>&nbsp;
          发表时间: 2008年03月26日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>正则表达式用于字符串处理，表单验证等场合，实用高效，但用到时总是不太把握，以致往往要上网查一番。我将一些常用的表达式收藏在这里，作备忘之用。本贴随时会更新。</p>
<p><span style="color: #800080;">匹配中文字符的正则表达式： [\u4e00-\u9fa5]</span></p>
<p><span style="color: #000080;">匹配双字节字符(包括汉字在内)：[^\x00-\xff]</span></p>
<p><span style="color: #000080;">应用：计算字符串的长度（一个双字节字符长度计2，ASCII字符计1）</span></p>
<p><span style="color: #000080;">String.prototype.len=function(){return this.replace([^\x00-\xff]/g,"aa").length;}</span></p>
<p><span style="color: #800080;">匹配空行的正则表达式：\n[\s| ]*\r</span></p>
<p><span style="color: #000080;">匹配HTML标记的正则表达式：/&lt;(.*)&gt;.*&lt;\/\1&gt;|&lt;(.*) \/&gt;/</span><span style="color: #000000;"> </span></p>
<p><span style="color: #000080;">
<p><span style="color: #800080;">匹配首尾空格的正则表达式：(^\s*)|(\s*$)</span></p>
<p><span style="color: #800080;">应用：javascript中没有像vbscript那样的trim函数，我们就可以利用这个表达式来实现，如下：</span></p>
</span></p>
<p><span style="color: #800080;">String.prototype.trim = function()<br />{<br />&nbsp;&nbsp;&nbsp; return this.replace(/(^\s*)|(\s*$)/g, "");<br />}</span></p>
<p><span style="color: #000080;">利用正则表达式分解和转换IP地址：</span></p>
<p><span style="color: #000080;">下面是利用正则表达式匹配IP地址，并将IP地址转换成对应数值的Javascript程序：</span></p>
<p><span style="color: #000080;">function IP2V(ip)<br />{<br />&nbsp;re=/(\d+)\.(\d+)\.(\d+)\.(\d+)/g&nbsp; //匹配IP地址的正则表达式<br />if(re.test(ip))<br />{<br />return RegExp.$1*Math.pow(255,3))+RegExp.$2*Math.pow(255,2))+RegExp.$3*255+RegExp.$4*1<br />}<br />else<br />{<br />&nbsp;throw new Error("Not a valid IP address!")<br />}<br />}</span></p>
<p><span style="color: #000080;">不过上面的程序如果不用正则表达式，而直接用split函数来分解可能更简单，程序如下：</span></p>
<p><span style="color: #000080;">var ip="10.100.20.168"<br />ip=ip.split(".")<br />alert("IP值是："+(ip[0]*255*255*255+ip[1]*255*255+ip[2]*255+ip[3]*1))</span></p>
<p><span style="color: #800080;">匹配Email地址的正则表达式：\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*</span></p>
<p><span style="color: #000080;">匹配网址URL的正则表达式：http://([\w-]+\.)+[\w-]+(/[\w- ./?%&amp;=]*)?</span></p>
<p><span style="color: #800080;"><span style="text-decoration: line-through;">利用正则表达式去除字串中重复的字符的算法程序</span>：[注：此程序不正确，原因见本贴回复]</span></p>
<p><span style="color: #800080;">var s="abacabefgeeii"<br />var s1=s.replace(/(.).*\1/g,"$1")<br />var re=new RegExp("["+s1+"]","g")<br />var s2=s.replace(re,"") <br />alert(s1+s2)&nbsp; //结果为：abcefgi<br /></span><span style="color: #800080;"><br />我原来在CSDN上发贴寻求一个表达式来实现去除重复字符的方法，最终没有找到，这是我能想到的最简单的实现方法。思路是使用后向引用取出包括重复的字符，再以重复的字符建立第二个表达式，取到不重复的字符，两者串连。这个方法对于字符顺序有要求的字符串可能不适用。</span></p>
<p><span style="color: #000080;">得用正则表达式从URL地址中提取文件名的javascript程序，如下结果为page1</span></p>
<p><span style="color: #800080;"><span style="color: #000080;">s="http://www.9499.net/page1.htm"<br />s=s.replace(/(.*\/){0,}([^\.]+).*/ig,"$2")<br />alert(s)</span></span></p>
<p><span style="color: #800080;">利用正则表达式限制网页表单里的文本框输入内容：</span></p>
<p><span style="color: #800080;">用正则表达式限制只能输入中文：onkeyup="value=value.replace(/[^\u4E00-\u9FA5]/g,'')" onbeforepaste="clipboardData.setData('text',clipboardData.getData('text').replace(/[^\u4E00-\u9FA5]/g,''))"</span></p>
<p><span style="color: #800080;">用正则表达式限制只能输入全角字符：</span><span style="color: #800080;">&nbsp;onkeyup="value=value.replace(/[^\uFF00-\uFFFF]/g,'')" onbeforepaste="clipboardData.setData('text',clipboardData.getData('text').replace(/[^\uFF00-\uFFFF]/g,''))"</span></p>
<p><span style="color: #800080;">用正则表达式限制只能输入数字：onkeyup="value=value.replace(/[^\d]/g,'') "onbeforepaste="clipboardData.setData('text',clipboardData.getData('text').replace(/[^\d]/g,''))"</span></p>
<p><span style="color: #800080;">用正则表达式限制只能输入数字和英文：onkeyup="value=value.replace(/[\W]/g,'') "onbeforepaste="clipboardData.setData('text',clipboardData.getData('text').replace(/[^\d]/g,''))"</span></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p class="postfoot"><a name="feedback"></a>正则表达式，相关链接 <br /><a href="http://blog.csdn.net/laily/category/19548.aspx" target="_new">http://blog.csdn.net/laily/category/19548.aspx</a> <br /><a href="http://blog.csdn.net/laily/archive/2004/06/30/30525.aspx" target="_new">http://blog.csdn.net/laily/archive/2004/06/30/30525.aspx</a> 微软的正则表达式教程（五）：选择/编组和后向引用 <br /><br /><a href="http://blog.csdn.net/laily/archive/2004/06/30/30522.aspx" target="_new">http://blog.csdn.net/laily/archive/2004/06/30/30522.aspx</a> 微软的正则表达式教程（四）：限定符和定位符 <br /><br /><a href="http://blog.csdn.net/laily/archive/2004/06/30/30517.aspx" target="_new">http://blog.csdn.net/laily/archive/2004/06/30/30517.aspx</a> 微软的正则表达式教程（三）：字符匹配 <br /><br /><a href="http://blog.csdn.net/laily/archive/2004/06/30/30514.aspx" target="_new">http://blog.csdn.net/laily/archive/2004/06/30/30514.aspx</a> 微软的正则表达式教程（二）：正则表达式语法和优先权顺序 <br /><br /><a href="http://blog.csdn.net/laily/archive/2004/06/30/30511.aspx" target="_new">http://blog.csdn.net/laily/archive/2004/06/30/30511.aspx</a> 微软的正则表达式教程（一）：正则表达式简介 <br /><br /><a href="http://blog.csdn.net/laily/archive/2004/06/30/30360.aspx" target="_new">http://blog.csdn.net/laily/archive/2004/06/30/30360.aspx</a> 小程序大作为：高级查找/替换、正则表达式练习器、Javascript脚本程序调试器 <br /><br /><a href="http://blog.csdn.net/laily/archive/2004/06/24/25872.aspx" target="_new">http://blog.csdn.net/laily/archive/2004/06/24/25872.aspx</a> 经典正则表达式 <br /><br />正则表达式，正规表达式，正则表达式匹配，正则表达式语法，模式匹配，正规表达式匹配 javascript正则表达式 ASP正则表达式 ASP.NET正则表达式 C#正则表达式 JSP正则表达式 PHP正则表达式 VB.NET正则表达式 VBSCript正则表达式编程 delphi正则表达式 jscript <a href="javascript:__doPostBack('Comments.ascx$CommentList$_ctl0$EditLink','')" id="Comments.ascx_CommentList__ctl0_EditLink"></a></p>
<p>正则表达式 regular expression <br />正则表达式 RegExp <br />模式 pattern <br />匹配 Match <br />.NET命名空间： System.Text.RegularExpression <br /><br /><a href="javascript:__doPostBack('Comments.ascx$CommentList$_ctl1$EditLink','')" id="Comments.ascx_CommentList__ctl1_EditLink"></a></p>
<p>补充： <br />^\d+$　　//匹配非负整数（正整数 + 0） <br />^[0-9]*[1-9][0-9]*$　　//匹配正整数 <br />^((-\d+)|(0+))$　　//匹配非正整数（负整数 + 0） <br />^-[0-9]*[1-9][0-9]*$　　//匹配负整数 <br />^-?\d+$　　　　//匹配整数 <br />^\d+(\.\d+)?$　　//匹配非负浮点数（正浮点数 + 0） <br />^(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*))$　　//匹配正浮点数 <br />^((-\d+(\.\d+)?)|(0+(\.0+)?))$　　//匹配非正浮点数（负浮点数 + 0） <br />^(-(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*)))$　　//匹配负浮点数 <br />^(-?\d+)(\.\d+)?$　　//匹配浮点数 <br />^[A-Za-z]+$　　//匹配由26个英文字母组成的字符串 <br />^[A-Z]+$　　//匹配由26个英文字母的大写组成的字符串 <br />^[a-z]+$　　//匹配由26个英文字母的小写组成的字符串 <br />^[A-Za-z0-9]+$　　//匹配由数字和26个英文字母组成的字符串 <br />^\w+$　　//匹配由数字、26个英文字母或者下划线组成的字符串 <br />^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$　　　　//匹配email地址 <br />^[a-zA-z]+://匹配(\w+(-\w+)*)(\.(\w+(-\w+)*))*(\?\S*)?$　　//匹配url <a href="javascript:__doPostBack('Comments.ascx$CommentList$_ctl2$EditLink','')" id="Comments.ascx_CommentList__ctl2_EditLink"></a></p>
<p>利用正则表达式去除字串中重复的字符的算法程序： <br /><br />var s="abacabefgeeii" <br />var s1=s.replace(/(.).*\1/g,"$1") <br />var re=new RegExp("["+s1+"]","g") <br />var s2=s.replace(re,"") <br />alert(s1+s2) //结果为：abcefgi <br />=============================== <br />如果var s = "abacabefggeeii" <br />结果就不对了，结果为：abeicfgg <br />正则表达式的能力有限 <a href="javascript:__doPostBack('Comments.ascx$CommentList$_ctl3$EditLink','')" id="Comments.ascx_CommentList__ctl3_EditLink"></a></p>
<p>RE: totoro <br />谢谢你的指点，这个javascript正则表达式程序算法确实有问题，我会试着找更好的办法!!! <a href="javascript:__doPostBack('Comments.ascx$CommentList$_ctl4$EditLink','')" id="Comments.ascx_CommentList__ctl4_EditLink"></a></p>
<p>1.确认有效电子邮件格式 <br />下面的代码示例使用静态 Regex.IsMatch 方法验证一个字符串是否为有效电子邮件格式。如果字符串包含一个有效的电子邮件地址，则 IsValidEmail 方法返回 true，否则返回 false，但不采取其他任何操作。您可以使用 IsValidEmail，在应用程序将地址存储在数据库中或显示在 ASP.NET 页中之前，筛选出包含无效字符的电子邮件地址。 <br /><br />[Visual Basic] <br />Function IsValidEmail(strIn As String) As Boolean <br />' Return true if strIn is in valid e-mail format. <br />Return Regex.IsMatch(strIn, ("^([\w-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([\w-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$") <br />End Function <br />[C#] <br />bool IsValidEmail(string strIn) <br />{ <br />// Return true if strIn is in valid e-mail format. <br />return Regex.IsMatch(strIn, @"^([\w-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([\w-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$"); <br />} <br /><br /><br />2.清理输入字符串 <br />下面的代码示例使用静态 Regex.Replace 方法从字符串中抽出无效字符。您可以使用这里定义的 CleanInput 方法，清除掉在接受用户输入的窗体的文本字段中输入的可能有害的字符。CleanInput 在清除掉除 @、-（连字符）和 .（句点）以外的所有非字母数字字符后返回一个字符串。 <br /><br />[Visual Basic] <br />Function CleanInput(strIn As String) As String <br />' Replace invalid characters with empty strings. <br />Return Regex.Replace(strIn, "[^\w\.@-]", "") <br />End Function <br />[C#] <br />String CleanInput(string strIn) <br />{ <br />// Replace invalid characters with empty strings. <br />return Regex.Replace(strIn, @"[^\w\.@-]", ""); <br />} <br /><br /><br />3.更改日期格式 <br />以下代码示例使用 Regex.Replace 方法来用 dd-mm-yy 的日期形式代替 mm/dd/yy 的日期形式。 <br /><br />[Visual Basic] <br />Function MDYToDMY(input As String) As String <br />Return Regex.Replace(input, _ <br />"\b(?&lt;month&gt;\d{1,2})/(?&lt;day&gt;\d{1,2})/(?&lt;year&gt;\d{2,4})\b", _ <br />"${day}-${month}-${year}") <br />End Function <br />[C#] <br />String MDYToDMY(String input) <br />{ <br />return Regex.Replace(input, <br />"\\b(?&lt;month&gt;\\d{1,2})/(?&lt;day&gt;\\d{1,2})/(?&lt;year&gt;\\d{2,4})\\b", <br />"${day}-${month}-${year}"); <br />} <br />Regex 替换模式 <br />本示例说明如何在 Regex.Replace 的替换模式中使用命名的反向引用。其中，替换表达式 ${day} 插入由 (?&lt;day&gt;...) 组捕获的子字符串。 <br /><br />有几种静态函数使您可以在使用正则表达式操作时无需创建显式正则表达式对象，而 Regex.Replace 函数正是其中之一。如果您不想保留编译的正则表达式，这将给您带来方便 <br /><br /><br />4.提取 URL 信息 <br />以下代码示例使用 Match.Result 来从 URL 提取协议和端口号。例如，&ldquo;http://www.contoso.com:8080/letters/readme.html&rdquo;将返回&ldquo;http:8080&rdquo;。 <br /><br />[Visual Basic] <br />Function Extension(url As String) As String <br />Dim r As New Regex("^(?&lt;proto&gt;\w+)://[^/]+?(?&lt;port&gt;:\d+)?/", _ <br />RegexOptions.Compiled) <br />Return r.Match(url).Result("${proto}${port}") <br />End Function <br />[C#] <br />String Extension(String url) <br />{ <br />Regex r = new Regex(@"^(?&lt;proto&gt;\w+)://[^/]+?(?&lt;port&gt;:\d+)?/", <br />RegexOptions.Compiled); <br />return r.Match(url).Result("${proto}${port}"); <br />} <br /><br /><a href="javascript:__doPostBack('Comments.ascx$CommentList$_ctl5$EditLink','')" id="Comments.ascx_CommentList__ctl5_EditLink"></a></p>
<p>5.如何用正则表达式表示要么是数字要么是字母 是字母的话只能是一个字母 数字则无所谓<br /><br />^[a-zA-Z]$|^\d+$ </p>
<p><a href="javascript:__doPostBack('Comments.ascx$CommentList$_ctl6$EditLink','')" id="Comments.ascx_CommentList__ctl6_EditLink"></a></p>
          <br/><br/>
          <span style="color:red;">
            <a href="http://joanzq.javaeye.com/blog/176318#comments" style="color:red;">已有 <strong>1</strong> 人发表留言，猛击-&gt;&gt;<strong>这里</strong>&lt;&lt;-参与讨论</a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">Windows7在微软WinHEC 2008上揭开神秘面纱</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 26 Mar 2008 14:33:46 +0800</pubDate>
        <link>http://joanzq.javaeye.com/blog/176318</link>
        <guid>http://joanzq.javaeye.com/blog/176318</guid>
      </item>
          <item>
        <title>如何用JNI技术提高Java的性能详解 </title>
        <author>joanzq</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://joanzq.javaeye.com">joanzq</a>&nbsp;
                    链接：<a href="http://joanzq.javaeye.com/blog/161152" style="color:red;">http://joanzq.javaeye.com/blog/161152</a>&nbsp;
          发表时间: 2008年02月02日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <h3 align="center">如何用JNI技术提高Java的性能详解 </h3><p align="center">&nbsp;</p><p>阻碍Java获得广泛应用的一个主要因素是Java程序的运行效率。Java是介于解释型和编译型之间的一种语言，同样的程序，如果用编译型语言C来实现，其运行速度一般要比Java快一倍以上。Java具有平台无关性，这使人们在开发企业级应用的时候总是把它作为主要候选方案之一，但是性能方面的因素又大大削弱了它的竞争力。为此，提高Java的性能就显得十分重要。&nbsp;&nbsp; </p><p><br /><br />&nbsp;</p><p class="a14">&nbsp;<strong>问题的提出</strong> </p><p class="a14">Sun公司及Java的支持者们为提高Java的运行速度已经做出了许多努力，其中大多数集中在程序设计的方法和模式选择方面。由于算法和设计模式的优化是通用的，对Java有效的优化算法和设计模式，对其他编译语言也基本同样适用，因此不能从根本上改变Java程序与编译型语言在执行效率方面的差异。 </p><p class="a14">JIT(Just In Time，及时编译)技术是个比较好的思想。它的基本原理是：首先通过Java编译器把Java源代码编译成平台无关的二进制字节码。然后在Java程序真正执行之前，系统通过JIT编译器把Java的字节码编译为本地化机器码。最后，系统执行本地化机器码，节省了对字节码进行解释的时间。这样做的优点是大大提高了Java程序的性能，缩短了加载程序的时间；同时，由于编译的结果并不在程序运行间保存，因此也节约了存储空间。缺点是由于JIT编译器对所有的代码都想优化，因此同样也占用了很多时间。 </p><p class="a14">动态优化技术是提高Java性能的另一个尝试。该技术试图通过把Java源程序直接编译成机器码，以充分利用Java动态编译和静态编译技术来提高Java的性能。该方法把输入的Java源码或字节码转换为经过高度优化的可执行代码和动态库 (Windows中的. dll文件或Unix中的. so文件)。该技术能大大提高程序的性能，但却破坏了Java的可移植性。 </p><p class="a14"><strong>JNI技术</strong> </p><p class="a14">实际上，有一种通常为我们忽视的技术可以在很大程度上解决这个难题，那就是JNI(Java Native Interface, Java本地化方法)。主张采用纯Java的人们通常反对本地化代码的使用，他们认为在Java程序执行的过程中调用C/C++程序会影响程序的可移植性和安全性。还有一些人认为JNI只是对过去混合编程技术的简单扩展，其实际目的是为了充分利用大量原有的C程序库。 </p><p class="a14">其实，我们不必拘泥于严格的平台独立性限制，因为采用JNI技术只是针对一些严重影响Java性能的代码段，该部分可能只占源程序的极少部分，所以几乎可以不考虑该部分代码在主流平台之间移植的工作量。同时，也不必过分担心类型匹配问题，我们完全可以控制代码不出现这种错误。此外，也不必担心安全控制问题，因为Java安全模型已扩展为允许非系统类加载和调用本地方法。根据Java规范，从JDK 1. 2开始，FindClass将设法找到与当前的本地方法关联的类加载器。如果平台相关代码属于一个系统类，则无需涉及任何类加载器; 否则，将调用适当的类加载器来加载和链接已命名的类。换句话说，如果在Java程序中直接调用C/C++语言产生的机器码，该部分代码的安全性就由Java虚拟机控制。 </p><p class="a14"><strong>JNI实现步骤</strong> </p><p class="a14">编写JNI代码的大致流程如下图所示： </p><p align="center"><img src="http://java.ccidnet.com/col/attachment/2006/2/596881.jpg" alt="" style="border: black 1px solid" /> </p><p class="a14">JNI实现流程图 </p><p class="a14">1. 首先编写需要JNI功能的Java类源文件。其中，需要JNI实现的方法应当用native关键字声明。在该类中，用System. loadLibrary()方法加载需要的动态链接库。关键代码如下： </p><p class="a14">//Compute.java </p><p class="a14">&hellip;&hellip; </p><p class="a14">public class Compute { </p><p class="a14">public native double comp (double [] params); </p><p class="a14">&hellip;&hellip; </p><p class="a14">static { </p><p class="a14">// 调用动态链接库 </p><p class="a14">System. loadLibrary(&ldquo;mathlib&rdquo;); </p><p class="a14">} </p><p class="a14">&hellip;&hellip; </p><p class="a14">} </p><p class="a14">2. 将该类源文件用Java类编译器编译成二进制字节码文件。由于采用了native关键字声明，编译器会忽视没有代码体的JNI方法部分。 </p><p class="a14">3. 利用javah -jni *.class 生成相关JNI方法的头文件。我们可以手工生成该文件，但是由于Java虚拟机是根据一定的命名规范完成对JNI方法的调用，所以手工编写头文件需要特别小心。 </p><p class="a14">上述文件产生的头文件部分代码如下： </p><p class="a14">//Compute. h </p><p class="a14">&hellip;&hellip; </p><p class="a14">extern &ldquo;C&rdquo; { </p><p class="a14">JNIEXPORT jdouble JNICALL Java_Compute_comp (JNIEnv *, jobject, jdoubleArray); </p><p class="a14">} </p><p class="a14">&hellip;&hellip; </p><p class="a14">可以看出，JNI函数名称分为三部分：首先是Java关键字，供Java虚拟机识别；然后是调用者类名称（全限定的类名，其中用下划线代替名称分隔符）；最后是对应的方法名称，各段名称之间用下划线分割。 </p><p class="a14">JNI函数的参数也由三部分组成: 首先是JNIEnv *，是一个指向JNI运行环境的指针；第二个参数随本地方法是静态还是非静态而有所不同&mdash;&mdash;非静态本地方法的第二个参数是对对象的引用，而静态本地方法的第二个参数是对其 Java 类的引用; 其余的参数对应通常 Java 方法的参数，参数类型需要根据一定规则进行映射。 </p><p class="a14">4. 根据头文件编写相应方法的实现代码。由于篇幅所限，具体的实现部分在此不再赘述。在编码过程中，需要注意变量的长度问题，例如Java的整型变量长度为32位，而C语言为16位，所以要仔细核对变量类型映射表，防止在传值过程中出现问题。 </p><p class="a14">5. 利用C/C++编译器将JNI实现代码编译成动态链接库。调用者类中需要显式调用该链接库。 </p><p class="a14">在Win32环境下，可以利用Visual C ++或其他能产生DLL文件的C/C++编译器将实现代码编译成动态链接库。笔者利用的是Microsoft.NET Framework的编译器。编译指令如下，其中%Java_HOME%是笔者的jdk安装目录变量： </p><p class="a14">cl -I%Java_HOME%\include </p><p class="a14">-I%Java_HOME%\include\win32 </p><p class="a14">-LD jnicomp. c -Femathlib. dll </p><p class="a14">在Sun Soloaris下，相应指令为： </p><p class="a14">cc -G -I/usr/local/java/include -I/usr/local/java/include/solaris jnicomp. c \ </p><p class="a14">-o mathlib. so </p><p class="a14">注意，编译的时候需要用I指令包含必要的库文件路径。 </p><p class="a14">经过上述处理，就基本上完成了一个包含本地化方法的Java类的开发。 </p><p class="a14"><strong>JNI技术的应用</strong> </p><p class="a14">一些主要的Java技术，如JDBC和RMI，大部分都采用JNI方式实现。但是，采用JNI确实会影响程序的平台无关性，所以只能在特别需要的地方才能使用。通常来说，如果遇到下面的情况，我们可以考虑JNI: </p><p class="a14">● 需要直接操作物理设备，而没有相关的驱动程序，这时候我们可能需要用C甚至汇编语言来编写该设备的驱动，然后通过JNI调用； </p><p class="a14">● 涉及大量数学运算的部分，用Java会带来些效率上的损失； </p><p class="a14">● 用Java会产生系统难以支付的开销，如需要大量网络链接的场合； </p><p class="a14">● 存在大量可重用的C/C++代码，通过JNI可以减少开发工作量，避免重复开发。 </p><p class="a14">另外，在利用JNI技术的时候要注意以下几点： </p><p class="a14">● 由于Java安全机制的限制，不要试图通过Jar文件的方式发布包含本地化方法的Applet到客户端； </p><p class="a14">● 注意内存管理问题，虽然在本地方法返回 Java 后将自动释放局部引用，但过多的局部引用将使虚拟机在执行本地方法时耗尽内存； </p><p class="a14">● JNI技术不仅可以让Java程序调用C/C++代码，也可以让C/C++代码调用Java代码。 </p>
          <br/><br/>
          <span style="color:red;">
            <a href="http://joanzq.javaeye.com/blog/161152#comments" style="color:red;">已有 <strong>2</strong> 人发表留言，猛击-&gt;&gt;<strong>这里</strong>&lt;&lt;-参与讨论</a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">Windows7在微软WinHEC 2008上揭开神秘面纱</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sat, 02 Feb 2008 12:20:36 +0800</pubDate>
        <link>http://joanzq.javaeye.com/blog/161152</link>
        <guid>http://joanzq.javaeye.com/blog/161152</guid>
      </item>
          <item>
        <title>请问该如何运用JAVA 来实现发送语音验证请求，语音验证服务？</title>
        <author>joanzq</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://joanzq.javaeye.com">joanzq</a>&nbsp;
                    链接：<a href="http://joanzq.javaeye.com/blog/158933" style="color:red;">http://joanzq.javaeye.com/blog/158933</a>&nbsp;
          发表时间: 2008年01月24日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          我从来没有接触过用 JAVA 来发送短信，过去做得项目都只是增，删，查，改。<br /><br />请问该如何运用JAVA 来实现发送语音验证请求，语音验证服务？请问前辈们怎样做呀？ 谢谢！
          <br/><br/>
          <span style="color:red;">
            <a href="http://joanzq.javaeye.com/blog/158933#comments" style="color:red;">已有 <strong>1</strong> 人发表留言，猛击-&gt;&gt;<strong>这里</strong>&lt;&lt;-参与讨论</a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">Windows7在微软WinHEC 2008上揭开神秘面纱</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Thu, 24 Jan 2008 09:59:31 +0800</pubDate>
        <link>http://joanzq.javaeye.com/blog/158933</link>
        <guid>http://joanzq.javaeye.com/blog/158933</guid>
      </item>
          <item>
        <title>基于struts+spring+ibatis的轻量级J2EE开发</title>
        <author>joanzq</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://joanzq.javaeye.com">joanzq</a>&nbsp;
                    链接：<a href="http://joanzq.javaeye.com/blog/158066" style="color:red;">http://joanzq.javaeye.com/blog/158066</a>&nbsp;
          发表时间: 2008年01月21日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          大多数IT 组织都必须解决三个主要问题：1．帮助组织减少成本 2．增加并且保持客户 3．加快业务效率。完成这些问题一般都需要实现对多个业务系统的数据和业务逻辑的无缝访问，也就是说，要实施系统集成工程，以便联结业务流程、实现数据的访问与共享。<br />JpetStore 4.0是ibatis的最新示例程序，基于Struts MVC框架（注：非传统Struts开发模式），以ibatis作为持久化层。该示例程序设计优雅，层次清晰，可以学习以及作为一个高效率的编程模型参考。本文是在其基础上，采用Spring对其中间层（业务层）进行改造。使开发量进一步减少，同时又拥有了Spring的一些好处…<br /><br />1. 前言<br /><br />&nbsp;&nbsp;&nbsp; JpetStore 4.0是ibatis的最新示例程序。ibatis是开源的持久层产品，包含SQL Maps 2.0 和 Data Access Objects 2.0 框架。JpetStore示例程序很好的展示了如何利用ibatis来开发一个典型的J2EE web应用程序。JpetStore有如下特点：<br /><br />ibatis数据层 <br />POJO业务层 <br />POJO领域类 <br />Struts MVC <br />JSP 表示层 <br />&nbsp;&nbsp;&nbsp; 以下是本文用到的关键技术介绍，本文假设您已经对Struts，SpringFramewok，ibatis有一定的了解，如果不是，请首先查阅附录中的参考资料。<br /><br />&nbsp;&nbsp;&nbsp; Struts 是目前Java Web MVC框架中不争的王者。经过长达五年的发展，Struts已经逐渐成长为一个稳定、成熟的框架，并且占有了MVC框架中最大的市场份额。但是Struts某些技术特性上已经落后于新兴的MVC框架。面对Spring MVC、Webwork2 这些设计更精密，扩展性更强的框架，Struts受到了前所未有的挑战。但站在产品开发的角度而言，Struts仍然是最稳妥的选择。本文的原型例子JpetStore 4.0就是基于Struts开发的，但是不拘泥于Struts的传统固定用法，例如只用了一个自定义Action类，并且在form bean类的定义上也是开创性的，令人耳目一新，稍后将具体剖析一下。 <br />Spring Framework 实际上是Expert One-on-One J2EE Design and Development 一书中所阐述的设计思想的具体实现。Spring Framework的功能非常多。包含AOP、ORM、DAO、Context、Web、MVC等几个部分组成。Web、MVC暂不用考虑，JpetStore 4.0用的是更成熟的Struts和JSP；DAO由于目前Hibernate、JDO、ibatis的流行，也不考虑，JpetStore 4.0用的就是ibatis。因此最需要用的是AOP、ORM、Context。Context中，最重要的是Beanfactory，它能将接口与实现分开，非常强大。目前AOP应用最成熟的还是在事务管理上。 <br />ibatis 是一个功能强大实用的SQL Map工具，不同于其他ORM工具（如hibernate），它是将SQL语句映射成Java对象，而对于ORM工具，它的SQL语句是根据映射定义生成的。ibatis 以SQL开发的工作量和数据库移植性上的让步，为系统设计提供了更大的自由空间。有ibatis代码生成的工具，可以根据DDL自动生成ibatis代码，能减少很多工作量。 <br /><br /><br /><br /><br />2. JpetStore简述<br /><br />2.1. 背景<br /><br />&nbsp;&nbsp;&nbsp;&nbsp; 最初是Sun公司的J2EE petstore，其最主要目的是用于学习J2EE，但是其缺点也很明显，就是过度设计了。接着Oracle用J2EE petstore来比较各应用服务器的性能。微软推出了基于.Net平台的 Pet shop，用于竞争J2EE petstore。而JpetStore则是经过改良的基于struts的轻便框架J2EE web应用程序，相比来说，JpetStore设计和架构更优良，各层定义清晰，使用了很多最佳实践和模式，避免了很多"反模式"，如使用存储过程，在java代码中嵌入SQL语句，把HTML存储在数据库中等等。最新版本是JpetStore 4.0。<br /><br />2.2. JpetStore开发运行环境的建立<br /><br />1、开发环境<br /><br />Java SDK 1.4.2 <br />Apache Tomcat 4.1.31 <br />Eclipse-SDK-3.0.1-win32 <br />HSQLDB 1.7.2 <br />2、Eclipse插件<br /><br />EMF SDK 2.0.1：Eclipse建模框架，lomboz插件需要，可以使用runtime版本。 <br />lomboz 3.0：J2EE插件，用来在Eclipse中开发J2EE应用程序 <br />Spring IDE 1.0.3：Spring Bean配置管理插件 <br />xmlbuddy_2.0.10：编辑XML，用免费版功能即可 <br />tomcatPluginV3：tomcat管理插件 <br />Properties Editor：编辑java的属性文件,并可以预览以及自动存盘为Unicode格式。免去了手工或者ANT调用native2ascii的麻烦。 <br />3、示例源程序<br /><br />ibatis示例程序JpetStore 4.0 http://www.ibatis.com/jpetstore/jpetstore.html <br />改造后的源程序（+spring）（源码链接） <br />2.3. 架构<br /><br /><br />图1 JpetStore架构图<br /> <br /><br />&nbsp;&nbsp;&nbsp;&nbsp; 图1 是JPetStore架构图，更详细的内容请参见JPetStore的白皮书。参照这个架构图，让我们稍微剖析一下源代码，得出JpetStore 4.0的具体实现图（见图2），思路一下子就豁然开朗了。前言中提到的非传统的struts开发模式，关键就在struts Action类和form bean类上。<br /><br />&nbsp;&nbsp;&nbsp; struts Action类只有一个：BeanAction。没错，确实是一个！与传统的struts编程方式很不同。再仔细研究BeanAction类，发现它其实是一个通用类，利用反射原理，根据URL来决定调用formbean的哪个方法。BeanAction大大简化了struts的编程模式，降低了对struts的依赖（与struts以及WEB容器有关的几个类都放在com.ibatis.struts包下，其它的类都可以直接复用）。利用这种模式，我们会很容易的把它移植到新的框架如JSF，spring。<br /><br />&nbsp;&nbsp;&nbsp; 这样重心就转移到form bean上了，它已经不是普通意义上的form bean了。查看源代码，可以看到它不仅仅有数据和校验/重置方法，而且已经具有了行为，从这个意义上来说，它更像一个BO(Business Object)。这就是前文讲到的，BeanAction类利用反射原理，根据URL来决定调用form bean的哪个方法（行为）。form bean的这些方法的签名很简单，例如：<br /><br /><br /> public String myActionMethod() {<br />&nbsp;&nbsp; //..work<br />&nbsp;&nbsp; return "success";<br /> }<br />&nbsp; <br /><br /><br />&nbsp;&nbsp;&nbsp; 方法的返回值直接就是字符串，对应的是forward的名称，而不再是ActionForward对象，创建ActionForward对象的任务已经由BeanAction类代劳了。<br /><br />&nbsp;&nbsp;&nbsp;&nbsp; 另外，程序还提供了ActionContext工具类，该工具类封装了request 、response、form parameters、request attributes、session attributes和 application attributes中的数据存取操作，简单而线程安全，form bean类使用该工具类可以进一步从表现层框架解耦。<br /><br />在这里需要特别指出的是，BeanAction类是对struts扩展的一个有益尝试，虽然提供了非常好的应用开发模式，但是它还非常新，一直在发展中。<br /><br /><br />图2 JpetStore 4.0具体实现<br /> <br /><br />2.4. 代码剖析<br /><br />&nbsp;&nbsp; 下面就让我们开始进一步分析JpetStore4.0的源代码，为下面的改造铺路。<br /><br />BeanAction.java是唯一一个Struts action类，位于com.ibatis.struts包下。正如上文所言，它是一个通用的控制类，利用反射机制，把控制转移到form bean的某个方法来处理。详细处理过程参考其源代码，简单明晰。 <br />Form bean类位于com.ibatis.jpetstore.presentation包下，命名规则为***Bean。Form bean类全部继承于BaseBean类，而BaseBean类实际继承于ActionForm，因此，Form bean类就是Struts的 ActionForm，Form bean类的属性数据就由struts框架自动填充。而实际上，JpetStore4.0扩展了struts中ActionForm的应用： Form bean类还具有行为，更像一个BO,其行为（方法）由BeanAction根据配置（struts-config.xml）的URL来调用。虽然如此，我们还是把Form bean类定位于表现层。<br /><br />Struts-config.xml的配置里有3种映射方式，来告诉BeanAction把控制转到哪个form bean对象的哪个方法来处理。<br /><br />以这个请求连接为例http://localhost/jpetstore4/shop/viewOrder.do<br /><br />1. URL Pattern<br /><br />&nbsp;&nbsp;&nbsp; &lt;action path="/shop/viewOrder" type="com.ibatis.struts.BeanAction"<br />&nbsp;&nbsp;&nbsp; name="orderBean" scope="session"<br />&nbsp;&nbsp;&nbsp; validate="false"><br />&nbsp;&nbsp;&nbsp; &lt;forward name="success" path="/order/ViewOrder.jsp"/><br />&nbsp; &lt;/action><br />&nbsp;&nbsp; <br /><br /><br />此种方式表示，控制将被转发到"orderBean"这个form bean对象 的"viewOrder"方法（行为）来处理。方法名取"path"参数的以"/"分隔的最后一部分。<br /><br />2. Method Parameter<br /><br />&nbsp;&nbsp;&nbsp; &lt;action path="/shop/viewOrder" type="com.ibatis.struts.BeanAction"<br />&nbsp;&nbsp;&nbsp; name="orderBean" parameter="viewOrder" scope="session"<br />&nbsp;&nbsp;&nbsp; validate="false"><br />&nbsp;&nbsp;&nbsp; &lt;forward name="success" path="/order/ViewOrder.jsp"/><br />&nbsp; &lt;/action><br />&nbsp;&nbsp; <br /><br /><br />此种方式表示，控制将被转发到"orderBean"这个form bean对象的"viewOrder"方法（行为）来处理。配置中的"parameter"参数表示form bean类上的方法。"parameter"参数优先于"path"参数。<br /><br />3. No Method call<br /><br />&nbsp;&nbsp;&nbsp; &lt;action path="/shop/viewOrder" type="com.ibatis.struts.BeanAction"<br />&nbsp;&nbsp;&nbsp; name="orderBean" parameter="*" scope="session"<br />&nbsp;&nbsp;&nbsp; validate="false"><br />&nbsp;&nbsp;&nbsp; &lt;forward name="success" path="/order/ViewOrder.jsp"/><br />&nbsp; &lt;/action><br />&nbsp;&nbsp; <br /><br /><br />此种方式表示，form bean上没有任何方法被调用。如果存在"name"属性，则struts把表单参数等数据填充到form bean对象后，把控制转发到"success"。否则，如果name为空，则直接转发控制到"success"。<br /><br />这就相当于struts内置的org.apache.struts.actions.ForwardAction的功能<br /><br /> &lt;action path="/shop/viewOrder" type="org.apache.struts.actions.ForwardAction"<br />&nbsp;&nbsp;&nbsp; parameter="/order/ViewOrder.jsp " scope="session" validate="false"><br /> &lt;/action><br />&nbsp; <br /><br /><br />&nbsp;&nbsp;&nbsp; Service类位于com.ibatis.jpetstore.service包下，属于业务层。这些类封装了业务以及相应的事务控制。Service类由form bean类来调用。 <br />com.ibatis.jpetstore.persistence.iface包下的类是DAO接口，属于业务层，其屏蔽了底层的数据库操作，供具体的Service类来调用。DaoConfig类是工具类（DAO工厂类），Service类通过DaoConfig类来获得相应的DAO接口，而不用关心底层的具体数据库操作，实现了如图2中{耦合2}的解耦。 <br />com.ibatis.jpetstore.persistence.sqlmapdao包下的类是对应DAO接口的具体实现，在JpetStore4.0中采用了ibatis来实现ORM。这些实现类继承BaseSqlMapDao类，而BaseSqlMapDao类则继承ibatis DAO 框架中的SqlMapDaoTemplate类。ibatis的配置文件