<?xml version="1.0" encoding="GBK" ?>
<rss version="2.0" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:dcterms="http://purl.org/dc/terms/">
 <channel>
  	  <title><![CDATA[CaCell Blog]]></title>
	  <link>http://zouzhxi.blog.163.com</link>
	  <description><![CDATA[偶只會一些編程的三腳貓功夫。 偶只会一些编程的三脚毛功夫。]]></description>
	  <language>zh-CN</language>
	  <pubDate>Fri, 24 Oct 2008 10:03:55 +0800</pubDate>
	  <lastBuildDate>Fri, 24 Oct 2008 10:03:55 +0800</lastBuildDate>
	  <docs>http://blogs.law.harvard.edu/tech/rss</docs>
	  <generator><![CDATA[NetEase Space]]></generator>
	  <managingEditor><![CDATA[zouzhxi]]></managingEditor>
	  <webMaster><![CDATA[CaCell]]></webMaster>
		  <ttl>120</ttl>
	  <image>
	  	<title><![CDATA[CaCell Blog]]></title>
	  	<url>http://ava.blog.163.com/photo/0Asq5aXbh5kvEzooAfZv8g==/490610884407359221.jpg</url>
	  	<link>http://zouzhxi.blog.163.com</link>
	  </image>
  <item>
  	<title><![CDATA[[转]电脑在“说谎” 进度条不过是一种安慰]]></title>	
    <link>http://zouzhxi.blog.163.com/blog/static/155925120089241037467</link>
    <description><![CDATA[<div><TABLE cellSpacing=12 cellPadding=0 width="98%" align=center border=0>
<TBODY>
<TR>
<TD align=middle>
<P><SPAN 进度条不过是一种安慰></STRONG><FONT size=2></FONT></SPAN><SPAN height="10" src="http://vnews.avl.com.cn/info/digi/images/neiLINE.gif" width="561"></SPAN></P></SPAN></TD></TR>
<TR>
<TD>
<P><FONT size=2>我以前认为，我了解我们与电脑之间的关系。我曾经很信任我的电脑，虽然多少有点不情愿。但现在我明白了，电脑是个说谎大王，是个骗子，这都是“进度条”惹的祸。<BR><BR>　　大家都知道进度条是什么东西，即使你以为自己对此一无所知。当你安装软件、下载文件或打开一个程序时，就会有一个小小的提示窗口弹出来，这就是进度条。<BR><BR>　　它通常看起来像一个油量表，从左到右逐渐被填满。有时，它会提供更多的信息，比如执行这个指令可能会花费多少时间等。它或许看上去没有什么坏处，但事实上进度条早已欺骗、愚弄了我们。<BR><BR>　　进度条并没有在衡量进度<BR><BR>　　我们犯的第一个错误，就是认为进度条确实在衡量进度，能准确显示出你向电脑发出任务指令的执行情况。<BR><BR>　　为了了解进度条名不副实的原因，我们需要回到使用单色屏幕以及ＤＯＳ命令的旧时岁月，那时电脑会在屏幕上显示一连串小点来表示它正在处理某些命令。微软带给我们的是一个不断倾倒的沙漏，和文件从一个文件夹飞向另一个的简单画面。<BR><BR>　　但这看起来也不够。看着文件图标从屏幕的一端飘向另一端，或浏览器中的地球图标在不停地转动，这都不错。但是，它并没有告诉我们还有多少文件要飘过去，地球图标还要转动多少次。因此，进度条就应运而生了。<BR><BR>　　现在，你能看到一个进度表不断被填满，或许还能看到文件的数量、字节、时间以及其他细节。进度条为我们提供了对生产率的新展望，这样我们就可以确切地知道在电脑完成工作之前，我们还有多长时间去洗手间、喝杯咖啡、读份报纸或者结次婚。<BR><BR>　　突然之间，我们能获得详尽的信息了：“这个任务已完成３４．５６％。”“剩余时间１４．５９分钟。”，也会出现一些怪事：过分乐观的进度条在任务明显刚刚开始的时候，却告诉你已经完成了。或正在处理的任务所需时间还剩“约２０２３４０６８１４小时”。或出现微软式的谜语：“进度条可能显示文件下载已经完成，事实上下载仍在进行中。”<BR><BR>　　进度条不过是一种安慰</FONT><FONT size=2><BR>　　电脑内部在同一时间内要处理的任务太多了，以至于它根本无法准确地判断完成所有任务所需的时间。你可能会看到这样的情形：进度条显示某个任务还需要３分钟，然后降到２分钟，之后或保持不变，或跳回３分钟，甚至是４５分钟。这种情况就说明电脑已经混乱了。<BR><BR>　　另一个问题就是我们自己。我们喜欢胡乱摆弄，很容易感到厌倦。我们会开启新的程序。如果看不到程序进展的任何迹象，我们就会不停地点击鼠标。这一切都会为进度条的计算工作增加难度。因此进度条不得不变得更聪明一些——不是在计算方面，而是在了解我们的心理方面。因此，就有了所谓的“不确定进度条”。<BR><BR>　　根据定义，这种进度条不对任何指标进行衡量。你或许已看到过这样的进度条了：进度显示缓缓地向右移动，之后它会重新开始。这不是一个错误。微软的网站上还有相关文件，帮助程序员创造这样的进度条。其中的一个文件的名字是“创建一个不前进的进度条”。这种进度条就像是一部能显示你到达了一个楼层、但拒绝告诉你是哪一层的电梯。<BR><BR>　　它的出现是为了“检验用户能够忍受多久”。程序员查尔斯·米勒估计，如果任何进度条显示超过１５秒钟，用户“就会开始不信任它”。米勒说，这是一个与实际状况没有多少联系，但看起来很现实的进度条，它会在屏幕上不均衡地变化。他把这种进度条称作“安慰型进度条”。</FONT></P>
<P><FONT size=2>　　只用来分散注意力的进度条</FONT><FONT size=2><BR>　　雅虎在这方面更进一步，它提供的新邮件服务下载速度非常缓慢，为了分散用户对这一点的注意，它采用了一个身着紫色上装的动画代言人Ｌｉａｍ。<BR><BR>　　在用户等待下载的过程中，Ｌｉａｍ或跳霹雳舞，或踢足球，或进行拳击练习，或在一个儿童跳跳玩具上蹦来蹦去。看，进度条现在都能为我们提供娱乐了。最终，当电脑在那里漫无边际地运行时，我们或许还能欣赏到短篇电影。<BR><BR>　　通过上面这些情况进行逻辑推理的话，最终的结论将是：要创造一种除了分散注意力，其他什么都干不了的进度条。我很高兴地告诉您，现在已经有这样的进度条了：Ｍａｃ用户使用“虚假进度条”已经有一阵了；居住在英国的程序员詹姆斯·罗伯茨为Ｗｉｎｄｏｗｓ用户推出了一个“虚假进度条”。<BR><BR>　　与现实世界结合得最紧密的恐怕要算埃亚尔·伯斯坦的进度条了，它看起来有点像一盏圆柱形灯，能够衡量“搬家、结婚、到其他国家居住或者做好人”等各种事情的发展进程，时间段最长可达１８年。他说，任何事情都可以，只要它是一个长期的目标、而不是精准的科学。这一点与电脑进度条相差无几。<BR><BR>　　参考资料<BR>　　刻录你２０年光阴的进度条——“光棒”<BR>　　英国人埃亚尔·伯斯坦设计的“进度条”很有诗意，他主要希望藉由一个可看见的实体——光棒，其形状就如同一盏圆柱形灯，来充当计算机运算的进度条。让每个人所定下的目标能被可视化，使用者可以定下５年、１０年、２０年的计划，然后这个“进度条”便会开始计算，你的完成度将以一刻度一刻度的亮度渐渐累积，而使用者可以随时了解自己完成的百分比。<BR><BR>　　该进度条为时间的进度创造了一种情感：日常琐碎事务可能减弱了你的目标、目的以及抱负和其他长期的兴趣，而这个进度条却能让你亲眼看见一周到１００年之间的时间变化过程。时间程序被输入一个简单的棒状转换装置，并通过一种淡淡的荧光反映出来。你只用将这个光棒随意放在旁边，它就是一个不出声的提示者，告诉你要做的事，以及做了多少。你不需要刻意去注意它，另外，因其成本很低，你也不需要花大价钱去维修。　　</FONT></P>
<P align=right><FONT size=2>来源：青年参考</FONT></P></TD></TR></TBODY></TABLE></div>]]></description>
	    <author><![CDATA[CaCell]]></author>
	    <comments>http://zouzhxi.blog.163.com/blog/static/155925120089241037467</comments>
    <slash:comments>0</slash:comments>
    <guid isPermaLink="true">http://zouzhxi.blog.163.com/blog/static/155925120089241037467</guid>
    <pubDate>Fri, 24 Oct 2008 10:03:07 +0800</pubDate>
    <dcterms:modified>2008-10-24T10:03:07+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[Ajax验证用户名是否存在[转载]]]></title>	
    <link>http://zouzhxi.blog.163.com/blog/static/1559251200892295942518</link>
    <description><![CDATA[<div><div><pre>
作者:作者:飘逸online
地址:http://www.ie521.com/blog/article/388.htm
标题:Ajax验证用户名是否存在[转载]
</pre></div>
<p>
</p><p>用Ajax访问163的通行证注册，获取返回的信息。<br>
 
Register.html页面</p>
<pre>
<span style=  "border:1px solid #B8C9D3;border-left:4px solid #B8C9D3;margin:5px 3px;padding: 5px;display:block;background:#F7FAFD;color:#0070A6;font-size:1em;line-height:1.2em;text-align:left;word-wrap:break-word;">
CODE:<br /><br />
&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"&gt;
&lt;html&gt;
    &lt;head&gt;
        &lt;title&gt;&lt;/title&gt;
        &lt;meta name="GENERATOR" content="Microsoft Visual Studio .NET 7.1"&gt;
        &lt;meta name="ProgId" content="VisualStudio.HTML"&gt;
        &lt;meta name="Originator" content="Microsoft Visual Studio .NET 7.1"&gt;
        &lt;script language="javascript" src="CreateXMLRequest.js"&gt;&lt;/script&gt;
        &lt;script language=javascript src=CheckUserName.js&gt;&lt;/script&gt;
    &lt;/head&gt;
    &lt;body&gt;
        &lt;input type="text" id="163id" NAME="163id" /&gt; 
        &lt;input type="button" value="校验" onclick="AjaxCheckUserName('http://reg.163.com/register/checkssn.jsp?username=','163id','')"    ID="Button1" NAME="Button1" /&gt;
        &lt;div id="message"&gt;&lt;/div&gt;
    &lt;/body&gt;
&lt;/html&gt;
</span>
</pre>

<p>CheckUsername.js脚本</p>
<pre>
<span style=  "border:1px solid #B8C9D3;border-left:4px solid #B8C9D3;margin:5px 3px;padding: 5px;display:block;background:#F7FAFD;color:#0070A6;font-size:1em;line-height:1.2em;text-align:left;word-wrap:break-word;">
CODE:<br /><br />
var xmlHttp=false;
function AjaxCheckUserName(url,nameDiv,httpMethod)
{
    if(!httpMethod)
    {
        httpMethod="POST";
    }
    var regUserName=document.getElementById(nameDiv).value;
    url+=regUserName;
    xmlHttp=CreateXmlRequest();
    xmlHttp.onreadystatechange=StateContent;
    xmlHttp.open(httpMethod,url,true);
    xmlHttp.send(null);
}

function StateContent()
{
    if(xmlHttp.readyState==4)
    {
        if(xmlHttp.status==200)
        {
            MakeOperate();
        }
    }
}

function MakeOperate()
{
    document.getElementById('message').innerHTML=xmlHttp.responsetext;
}
</span>
</pre>


<p>CreateXMLRequest.js脚本</p>
<pre>
<span style=  "border:1px solid #B8C9D3;border-left:4px solid #B8C9D3;margin:5px 3px;padding: 5px;display:block;background:#F7FAFD;color:#0070A6;font-size:1em;line-height:1.2em;text-align:left;word-wrap:break-word;">
CODE:<br /><br />
function CreateXmlRequest( )
{    
 var xmlhttp_request = false;    
 try
 {        
  if( window.ActiveXObject ){            
   for( var i = 5; i; i-- ){               
    try{                   
     if( i == 2 ){
      xmlhttp_request = new ActiveXObject("Microsoft.XMLHTTP" );                       
     }else{
      xmlhttp_request = new ActiveXObject("Msxml2.XMLHTTP." + i + ".0" );   
      xmlhttp_request.setRequestHeader("Content-Type","text/xml");
      xmlhttp_request.setRequestHeader("Content-Type","gb2312");    
     }
     break;
    }catch(e){   
     xmlhttp_request = false;              
    }          
   }       
  }else if( window.XMLHttpRequest ){            
   xmlhttp_request = new XMLHttpRequest();           
   if (xmlhttp_request.overrideMimeType){
    xmlhttp_request.overrideMimeType('text/xml');            
   }       
  }   
 }
 catch(e)
 {        
  xmlhttp_request = false;   
 }    
 return xmlhttp_request ;
}
</span>
</pre>

<p>
Reader页面:<br>
输入Ｒｓｓ地址，也就是Ｒｓｓ所对应的ＸＭＬ在网上的位置,比如：http://rss.sina.com.cn/book/newbooks10.xml，从返回来的ＸＭＬ用ＤＯＭ解析显示出来</p>
<pre>
<span style=  "border:1px solid #B8C9D3;border-left:4px solid #B8C9D3;margin:5px 3px;padding: 5px;display:block;background:#F7FAFD;color:#0070A6;font-size:1em;line-height:1.2em;text-align:left;word-wrap:break-word;">
CODE:<br /><br />
&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"&gt;
&lt;html xmlns="http://www.w3.org/1999/xhtml"&gt;
&lt;head&gt;
&lt;title&gt;RSS Reader&lt;/title&gt;
&lt;!--copyright Turkeycock--&gt;
&lt;script type="text/javascript"&gt;
var xmlHttp;

function ShowRSS() {
 var target=document.getElementById("targeturl");
 alert(target.value);
 readRSS(target.value);
}

function createXMLHttpRequest() {
    if (window.ActiveXObject) {
        xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
    } 
    else if (window.XMLHttpRequest) {
        xmlHttp = new XMLHttpRequest();
    }
}
    
function readRSS(url) {
    createXMLHttpRequest();
    xmlHttp.onreadystatechange = handleStateChange;
    xmlHttp.open("GET", url, true);
    xmlHttp.send(null);
}
    
function handleStateChange() {
    if(xmlHttp.readyState == 4) {
        if(xmlHttp.status == 200) {
        //document.write("&lt;pre&gt;"+xmlHttp.responsetext+"&lt;/pre&gt;");
        
            clearPreviousResults();
            parseResults();
        }
    }
}

function clearPreviousResults() {
    var ListBody = document.getElementById("resultsTitle");
    while(ListBody.childNodes.length &gt; 0) {
        ListBody.removeChild(ListBody.childNodes[0]);
    }
}

function parseResults() {
    var results = xmlHttp.responseXML;
    var title = null;
    var content=null;
    var item = null;

    var items = results.getElementsByTagName("item");
    for(var i = 0; i &lt; items.length; i++) {
        item = items[i];
        title = item.getElementsByTagName("title")[0].firstChild.nodeValue;
        content=item.getElementsByTagName("description")[0].firstChild.nodeValue;
        addListRow(title,content);
    }
}


function addListRow(title,content) {
    var row = document.createElement("ul");
    var cell = createCellWithText(title);
    var contentcell=createCellWithContent(content);
    row.appendChild(cell);
    row.appendChild(contentcell);
    
    document.getElementById("resultsTitle").appendChild(row);
}

function createCellWithText(text) {
    var cell = document.createElement("li");
    var textNode = document.createTextNode(text);
    cell.appendChild(textNode);
    return cell;
}

function createCellWithContent(content) {
var cell=document.createElement("h1")
 var textNode = document.createTextNode(content);
    cell.appendChild(textNode);
    return cell;
}

&lt;/script&gt;
&lt;/head&gt;

&lt;body&gt;
  &lt;h2&gt;Blog文章列表&lt;/h2&gt;
   &lt;input type="text" id="targeturl" name="textfield" /&gt;
    &lt;input type="button" value="搜索" onclick="ShowRSS();"/&gt;    
    &lt;div id="resultsTitle"&gt;
    &lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;
</span>
</pre></div>]]></description>
	    <author><![CDATA[CaCell]]></author>
	    <comments>http://zouzhxi.blog.163.com/blog/static/1559251200892295942518</comments>
    <slash:comments>1</slash:comments>
    <guid isPermaLink="true">http://zouzhxi.blog.163.com/blog/static/1559251200892295942518</guid>
    <pubDate>Wed, 22 Oct 2008 09:59:42 +0800</pubDate>
    <dcterms:modified>2008-10-22T09:59:42+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[Session丢失原因与解决方案[总结]]]></title>	
    <link>http://zouzhxi.blog.163.com/blog/static/1559251200892181053743</link>
    <description><![CDATA[<div><div><pre>
作者:飘逸online
地址:http://www.ie521.com/blog/article/363.htm
标题:Session丢失原因与解决方案[总结]
</pre></div>
<p>

</p><p><br />
原因1： <br />
win2003 server下的IIS6默认设置下对每个运行在默认应用池中的工作者进程都会经过20多个小时后自动回收该进程，造成保存在该进程中的session丢失。 <br />
因为Session,Application等数据默认保存在运行该Web应用程序的工作者进程中,如果回收工作者进程，则会造成丢失。 <br />
解决办法： <br />
修改配置，设置为不定时自动回收该工作者进程，比如设置为当超出占用现有物理内存60％后自动回收
该进程。通过使用默认应用程序池，可以确保多个应用程序间互相隔离，保证由于一个应用程序的崩溃不会影响另外的Web应用程序。还可以使一个独立的应用程序运行在一个指定的用户帐号特权之下。<br />
如果使用StateServer方式或者Sql Server数据库方式来保存Session,则不受该设置的影响。
</p><p>
原因2： <br />
系统要运行在负载平衡的 Web 场环境中，而系统配置文件web.config中的Session状态却设置为InProc（即在本地存储会话状态），导至在用户访问量大时，Session常经超时的情况。引起这个现象的原因主要是因为用户通过负载平衡IP来访问WEB应用系统，某段时候在某台服务器保存了Session的会话状态，但在其它的WEB前端服务器中却没有保存Session的会话状态，而随着并发量的增大，负载平衡会当作路由随时访问空闲的服务器，结果空闲的服务器并没有之前保存的Session会话状态。
</p><p>
解决办法： <br />
1.当您在负载平衡的 Web 场环境中运行 ASP.NET Web 应用程序时，一定要使用 SqlServer 或 StateServer 会话状态模式，在项目中我们基于性能考虑并没有选择SqlServer模式来存储Session状态，而是选择一台SessionStateServer 服务器来用户的Session会话状态。我们要在系统配置文件web.config中设置如下： <br />
<sessionState mode="StateServer" cookieless="false" timeout="240" stateConnectionString="tcpip=192.168.0.1:42424" stateNetworkTimeout="14400" /> <br />
还要添加一项 
<machineKey validationKey="78AE3850338BFADCE59D8DDF58C9E4518E7510149C46142D7AAD7F1AD49D95D4" decryptionKey="5FC88DFC24EA123C" validation="SHA1"/>  
</p><p>
2. 我们同时还要在SessionStateServer 服务器中启动ASP.NET State Service服务，具体设置：控制面板>>管理工具>>服务>>ASP.NET State Service，把它设为自动启动即可。
</p><p>  
3. 每台前端WEB服务的Microsoft“Internet 信息服务”(IIS)设置要在 Web 场中的不同 Web 服务器间维护会话状态，Microsoft“Internet 信息服务”(IIS) 配置数据库中 Web 站点的应用程序路径（例如，\LM\W3SVC\2）与 Web 场中所有 Web 服务器必须相同。大小写也必须相同，因为应用程序路径是区分大小写的。在一台 Web 服务器上，承载 ASP.NET 应用程序的 Web 站点的实例 ID 可能是 2（其中应用程序路径是 \LM\W3SVC\2）。在另一台 Web 服务器上，Web 站点的实例 ID 可能是 3（其中应用程序路径是 \LM\W3SVC\3）。因此，Web 场中的 Web 服务器之间的应用程序路径是不同的。我们必须使Web 场Web 站点的实例 ID 相同即可。你可以在IIS中把某一个WEB配置信息保存为一个文件，其他Web 服务器的IIS配置可以来自这一个文件。您如果想知道具体的设置请访问Microsoft Support网站： 
</p>
<div style="border:1px #cccccc solid;">
补充一些相关资料:<br />
PRB: Session Variables Are Lost If You Use FRAMESET in Internet Explorer 6.0<br />
http://support.microsoft.com/kb/323752/EN-US/#<br /><br />

PRB: Session Data Is Lost When You Use ASP.NET InProc Session State Mode<br />
http://support.microsoft.com/?id=324772<br /><br />

PRB：如果您使用 SqlServer 或 StateServer 会话模式 Web 场中会丢失会话状态<br />
http://support.microsoft.com/default.aspx?scid=kb;zh-cn;325056<br /><br />

ASP.NET Session State FAQ<br />
http://www.eggheadcafe.com/articles/20021016.asp
</div>
</div>]]></description>
	    <author><![CDATA[CaCell]]></author>
	    <comments>http://zouzhxi.blog.163.com/blog/static/1559251200892181053743</comments>
    <slash:comments>1</slash:comments>
    <guid isPermaLink="true">http://zouzhxi.blog.163.com/blog/static/1559251200892181053743</guid>
    <pubDate>Tue, 21 Oct 2008 08:10:53 +0800</pubDate>
    <dcterms:modified>2008-10-21T08:10:53+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[[转]调查显示美国民众对中国认知程度低]]></title>	
    <link>http://zouzhxi.blog.163.com/blog/static/1559251200882393626280</link>
    <description><![CDATA[<div><DIV ><FONT >
<P align=left><STRONG><FONT color=#0000ff>来源：<A href="http://news.xinhuanet.com/">http://news.xinhuanet.com/</A></FONT></STRONG>
</P><P align=center><STRONG><FONT color=#0000ff></FONT></STRONG>&nbsp;
</P><P align=center><STRONG><FONT color=#0000ff>“三星、丰田被认为是中国名牌”——调查显示美国民众对中国认知程度低</FONT></STRONG> &nbsp;&nbsp;&nbsp;&nbsp; 
</P><P>&nbsp;&nbsp;&nbsp;&nbsp;新华网北京９月２２日电（记者李惠子）２２日公布的一项民意调查显示，美国民众对中国的认知程度远远低于人们的想象——“新加坡成美国人心目中最著名的中国城市之一”、“三星、丰田被认为是中国名牌”、“炒饭是美国最流行的中国菜”。 
</P><P>&nbsp;&nbsp;&nbsp;&nbsp;这项题为“美国人眼中的中国”的调查是由新近成立的“蓝海国际传播促进会”委托美国“专业调查机构”（ＰＲＩ）刚刚在美国完成的。蓝海国际传播促进会是一个新成立的非盈利性社团组织，目的是促进中国的对外传播，让西方民众更多了解中国。 
</P><P>&nbsp;&nbsp;&nbsp;&nbsp;此次调查针对有关中国的十个方面的问题在全美国范围内展开，被调查的２００万样本人群代表了美国１８岁以上的成年人口，涵盖各个文化和社会阶层，误差在５％以内。 
</P><P>&nbsp;&nbsp;&nbsp;&nbsp;调查显示，６３％的人想更多了解中国，年轻人更感兴趣。４９％的美国受访者认为，长城是他们心目中代表中国的符号，且回答长城的人群中，女性比男性的比例高很多；其他被提及的中国符号包括奥林匹克（３６％），米饭／食品（３４％），龙（３２％）、熊猫（３０％），以及五星红旗、电器、宝塔。受访者还提及“人口众多”、“共产党执政”、“文化、历史”和“红色”是中国符号。 
</P><P>&nbsp;&nbsp;&nbsp;&nbsp;“美国人知道的中国品牌有哪些”这个问题是受访者回答最少的一个。４２％的人想不到任何中国牌子，大部分被提到的品牌不是中国品牌。三星（３３％）、丰田（２５％）、尼桑 
<TABLE border=0 cellPadding=3 align=left>
<TBODY>
<TR>
<TD>
</TD></TR></TBODY></TABLE>（２４％）、耐克（１６％）都被受访者误认为是中国品牌。 
</P><P>&nbsp;&nbsp;&nbsp;&nbsp;“谁是在美国最著名的中国人？”４３％的受访者认为是成龙，其次是李小龙（４０％）、毛泽东（３９％）、孔子（３３％）、李连杰（２９％）、姚明（２９％）、佛（２８％）、刘玉玲（２３％）、成吉思汗（２２％）和周润发（１６％）。 
</P><P>&nbsp;&nbsp;&nbsp;&nbsp;５９％的受访者认为米饭／炒饭是在美国最流行的中国菜，其次是春卷（４４％）、捞面（４４％）、咕咾肉（３３％）、混沌汤（３１％）和蛋花汤（２５％）。在美国中餐厅非常流行的签语饼——和账单一起拿上来并附有祝福话语的小甜点——也位列其中（２８％），但签语饼在中国大陆的餐馆中很少见。只有２５％的受访者提到了北京烤鸭。 
</P><P>&nbsp;&nbsp;&nbsp;&nbsp;提及中国城市或景点，受访者列出了北京（７０％）、长城（５８％）、香港（４６％）、上海（３９％）、鸟巢（２３％）、故宫（２３％）、西藏（２２％）和天安门广场（２１％），２２％的人错误地认为新加坡是中国的城市。 
</P><P>&nbsp;&nbsp;&nbsp;&nbsp;８７％的受访者使用“中国制造”，使用最多的依次是服装、电器、玩具、餐具、鞋、电话／手机、电视机、米饭／食品、ＤＶＤ播放器／录像机和计算机。 
</P><P>&nbsp;&nbsp;&nbsp;&nbsp;３９％的受访美国人当前最关心的中国问题是民权和自由，其次是人口控制（２５％）、污染和环境（２４％）、共产主义与资本主义（２３％）、经济（２１％）、劳工问题（１７％）、血汗工厂（１６％）、产品质量问题（１５％）、美国对中国的金融债务（１３％）、西藏（１２％）、不知道（１６％）。 
</P><P>&nbsp;&nbsp;&nbsp;&nbsp;受访者对此次调查非常配合，很少有人拒绝回答，这说明了他们对中国话题的兴趣，４９％的人希望了解中国的原因是“对中国文化、历史感兴趣”，５３％的受访者想来中国旅游。 
</P><P>&nbsp;&nbsp;&nbsp;&nbsp;据悉，此调查将成为该会一年一次的常规项目，调查范围还将包括其他西方国家。 
</P><P>&nbsp;&nbsp;&nbsp;&nbsp;蓝海国际传播促进会主席由全国人大常委会原副委员长、著名经济学家成思危担任，理事成员由在国际交流与国际传播领域具有影响力的国内外权威人士和专家组成。旗下的蓝海电视（ＢＯＮ　ＴＶ）是在美国落地的英文民间商业电视媒体，面向西方主流社会传播中国内容。</P>
<DIV align=center>（责任编辑: 周光杨 ）</DIV></FONT></DIV></div>]]></description>
	    <author><![CDATA[CaCell]]></author>
	    <comments>http://zouzhxi.blog.163.com/blog/static/1559251200882393626280</comments>
    <slash:comments>0</slash:comments>
    <guid isPermaLink="true">http://zouzhxi.blog.163.com/blog/static/1559251200882393626280</guid>
    <pubDate>Tue, 23 Sep 2008 09:36:26 +0800</pubDate>
    <dcterms:modified>2008-09-23T13:28:05+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[【转摘】新骂人的方式：你喝了三鹿啊？]]></title>	
    <link>http://zouzhxi.blog.163.com/blog/static/1559251200881651919368</link>
    <description><![CDATA[<div><P><FONT face=楷体_GB2312 size=4>作者: <A title=bjsrcat href="http://mcs.szu.edu.cn/user/bjsrcat" target=_blank>bjsrcat</A></FONT></P>
<P><FONT face=楷体_GB2312 size=4>地址：<A href="http://mcs.szu.edu.cn/Forum/43242">http://mcs.szu.edu.cn/Forum/43242</A></FONT></P>
<P><FONT face=楷体_GB2312 size=4>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 最近的三鹿安全事故可谓是有些蹊跷：好端端的“免检产品”竟然出现如此之大的问题？大家注意了：这个问句其实包含了三个疑问。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 一个是“免检”是官方贴的牌，有问题怎末“免检”？如果这个事故没有人爆出来，官方会吊销三鹿的“免检”吗？官方现在“该出手时就出手”，但当时为什么给“贴牌”时不多留点心，尽早“出手”呢？<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;二是三鹿在“大头娃娃”事故时是充当一个“弱者兼慈善家”的角色。怎末说？想当初三鹿说他被假冒，没责任。同时还大送奶粉。那好，圆满大结局——尘埃落定。现在新事故出现了。我想问下：这两个事故是否有联系？必然吗？或仅仅是巧合？<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;三是现在我们能喝什么奶？这个事故让三鹿掉进井底，他的新闻发言人还想拉个人下水，于是就爆出“现在很多奶商都这样做”！“很多”是多少？说白了：不管是多少，你喝了这种“结石奶粉”就会让你花“很多”钱！你看看现在那些“结石婴儿”的家庭有多少是富裕家庭的？孩子痛苦且不说，治疗带来的经济负担对家庭有多大影响？现在国家说免费治疗——那治好后肾脏功能的损耗需要的费用谁负责？除此之外，我们这些平时喝国产牌子的“奶民”们现在喝的牛奶有没问题？之前喝的会不会带来问题？将来我们能不能喝到没问题的牛奶？还有国产奶业现在可不可信？将来呢？<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 现在的问题不是中国的“食品安全”问题，而是国民现在还能吃什么的问题：上面说是“没问题”的现在有问题——连上面说的都不可信，我们这些小市民还能相信谁，还能吃什么？<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 啰啰嗦嗦地论了一大篇，现在我在想：以后我骂人虚伪就不骂“伪君子”啊、“假佬”啊什么的，以后我就骂：“你喝了三鹿啊！喝了多少斤啊？你结不结（石）啊？”——这样的商家还不虚伪啊？<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 这样骂够时尚、够新鲜、够“潮”！</FONT> </P></div>]]></description>
	    <author><![CDATA[CaCell]]></author>
	    <comments>http://zouzhxi.blog.163.com/blog/static/1559251200881651919368</comments>
    <slash:comments>0</slash:comments>
    <guid isPermaLink="true">http://zouzhxi.blog.163.com/blog/static/1559251200881651919368</guid>
    <pubDate>Tue, 16 Sep 2008 17:19:19 +0800</pubDate>
    <dcterms:modified>2008-09-16T17:20:38+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[“非主流”对联雷到网友(图)]]></title>	
    <link>http://zouzhxi.blog.163.com/blog/static/155925120088163211122</link>
    <description><![CDATA[<div><P style="TEXT-INDENT: 2em">据 <A href="http://news.163.com/" target=_blank>网易新闻</A> 报道： <A href="http://news.163.com/08/0916/02/4LU95V0300011229.html" target=_blank>“非主流”对联雷到网友(图)</A></P>
<P>　　核心提示：西安一户人家门口有一副超级雷人的对联，含有18个成语72个字，你能看懂这18个成语组成的字和组成18个成语的72个字吗？<A href="http://news.163.com/08/0916/02/4LU95V0300011229.html" target=_blank>查看全文&gt;&gt;</A></P>
<P><STRONG><IMG src="http://img2.cache.netease.com/cnews/2008/9/16/20080916023608fe07c.jpg"></STRONG></P>
<P style="TEXT-INDENT: 2em">&nbsp;</P></div>]]></description>
	    <author><![CDATA[CaCell]]></author>
	    <comments>http://zouzhxi.blog.163.com/blog/static/155925120088163211122</comments>
    <slash:comments>0</slash:comments>
    <guid isPermaLink="true">http://zouzhxi.blog.163.com/blog/static/155925120088163211122</guid>
    <pubDate>Tue, 16 Sep 2008 15:21:01 +0800</pubDate>
    <dcterms:modified>2008-09-16T15:21:01+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[&quot;神七&quot;六大突破 航天服中国造每套1.6亿]]></title>	
    <link>http://zouzhxi.blog.163.com/blog/static/1559251200886115031642</link>
    <description><![CDATA[<div><P style="TEXT-INDENT: 2em">据 <A href="http://news.163.com/" target=_blank>网易新闻</A> 报道： <A href="http://news.163.com/08/0906/02/4L4HK16J0001124J.html" target=_blank>"神七"六大突破 航天服中国造每套1.6亿</A></P>
<P>　　核心提示：中国自发研制的“飞天”航天服技术“堪比美国”，每套高达1.6亿元人民币。综合美国媒体的看法，“神七”在航天员数量、出舱行走六个方面的突破很值得关注。<A href="http://news.163.com/08/0906/02/4L4HK16J0001124J.html" target=_blank>查看全文&gt;&gt;</A></P>
<P><STRONG></STRONG>&nbsp;</P>
<P style="TEXT-INDENT: 2em">&nbsp;</P></div>]]></description>
	    <author><![CDATA[CaCell]]></author>
	    <comments>http://zouzhxi.blog.163.com/blog/static/1559251200886115031642</comments>
    <slash:comments>0</slash:comments>
    <guid isPermaLink="true">http://zouzhxi.blog.163.com/blog/static/1559251200886115031642</guid>
    <pubDate>Sat, 6 Sep 2008 11:50:31 +0800</pubDate>
    <dcterms:modified>2008-09-06T11:50:31+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[XP无法自动更新补丁-重新注册Wups2.dll文件]]></title>	
    <link>http://zouzhxi.blog.163.com/blog/static/155925120087180412314</link>
    <description><![CDATA[<div><P>　　不知怎么回事，我的<STRONG>Windows XP</STRONG>不能<STRONG>更新</STRONG>任何补丁了，查了好久才找到具体的解决办法——重新注册Wups2.dll文件。</P>
<P>　　以下是操作步骤：</P>
<P>　　1、鼠标右键“我的电脑”，选择“属性”，找到“自动更新”选项卡，选择“关闭自动更新。”，点击“确定”按钮。还有一个命令方法，在CMD下输入“net stop wuauserv”。</P>
<P>　　2、“开始-运行”，输入“CMD”，打开CMD界面。</P>
<P>　　3、输入“regsvr32 %windir%\system32\wups2.dll”，回车。</P>
<P>　　注意：如果你的系统是Windows XP 64位的，那么命令应该是：</P>
<P>　　“regsvr32 %windir%\syswow64\wups2.dll”</P>
<P>　　对话框中都“确定”即可。</P>
<P>　　4、按照第一步的步骤，选择“自动更新”，或者在CMD界面下输入“net start wuauserv”。</P>
<P><STRONG>来源</STRONG>:网页教学网整理&nbsp;</P></div>]]></description>
	    <author><![CDATA[CaCell]]></author>
	    <comments>http://zouzhxi.blog.163.com/blog/static/155925120087180412314</comments>
    <slash:comments>1</slash:comments>
    <guid isPermaLink="true">http://zouzhxi.blog.163.com/blog/static/155925120087180412314</guid>
    <pubDate>Mon, 18 Aug 2008 12:41:23 +0800</pubDate>
    <dcterms:modified>2008-08-18T12:41:23+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[J2EE中SQL语句自动构造方法]]></title>	
    <link>http://zouzhxi.blog.163.com/blog/static/155925120087710719457</link>
    <description><![CDATA[<div><h2>J2EE中SQL语句自动构造方法</h2>
<p style="margin: 5px; line-height: 150%"></p>
<table style="border: 1px solid rgb(255,0,0);" cellspacing="0"  bordercolordark="#ffffff" cellpadding="2" align="center"  bordercolorlight="#000000">
<tbody>
<tr>
<td style="font-size: 9pt" bgcolor="#F0F0F0">
<pre>
INSERT INTO table_name (col_1,col_2,col_3,) VALUES (value_1,value_2,value_3 …)
DELETE FROM table_name
WHERE col_n=value_n

UPDATE table_name
SET col_1=value_1,col_2=value_2,col_3=value_3
WHERE col_x=value_x
</pre></td>
</tr>
</tbody>
</table>
我们知道，借用j2ee中的request.getParameterNames()方法可以读到表单中的所有元素的名称，有了元素名称借用request.getParameter(elementName)方法可以获取该元素的值。假设在开发中我们让页面元素的名称和底层数据库表的字段名一致。那么在这三种语句中col_n
和 value_n 对我们来说就不是未知的，未知的数据就剩下了 table_name,col_x和value_x
。现在如果我们写一个方法，传入request对象，再把table_name,col_x,value_x作为参数传入方法，那么我们可以轻松的自动构造SQL语句了。但这样做还是有欠灵活，因为一方面每一次使用该方法我们都得人工的设置table_name,col_x和value_x；另一方面别忘了sql语句中对于字符串的字段需要加单引号和替换字符串中间的单引号，而整型、浮点型、系统函数(如now(),to_date()等数据库函数)等不需要做单引号的处理，这些如果没有好的解决的话，我们的方法将受到非常大的限制。要达到再进一步分离最好的办法就是在表单元素命名上面做文章，我们可以自己定义一套元素命名规则，对不同规则命名的元素做不同的处理--设我们定义元素命名规格如下：<br>

1.
table_name,col_x,value_x这类元素，为公共元素。我们规定这类元素名以c_k开头（c=common），我们限制table_name的元素名为c_table,col_x=value_x定义到一起，元素名定为c_where.
当然我们别忘了我们还需要一个元素表示构造什么样（INSERT、DELETE、UPDATE）的SQL语句。我们给这个元素命名c_genre，它的值被限制在INSERT、DELETE、UPDATE这三者之中
。<br>
2.
对于表单中对应数据库字符串类型的元素，在SQL构造中需要做单引号的处理。这类元素我们暂且称他们为字符串型元素。字符串型元素我们规定其名为s_+数据库表字段名
（s=String）。<br>
3.
对于不需要做但引号处理的元素（如integer型、float型、数据库系统函数--如now()，to_date()等等）。我们暂且简单的统称这类元素为整型元素。对于整型元素我们限制其命名规则为i_+数据库表字段名(i=Integer)。<br>

基于上面的规格我们可以非常轻松写一个javabean。代码如下：
<p style="margin: 5px; line-height: 150%"></p>
<table style="border: 1px solid rgb(255,0,0);" cellspacing="0"  bordercolordark="#ffffff" cellpadding="2" align="center"  bordercolorlight="#000000">
<tbody>
<tr>
<td style="font-size: 9pt" bgcolor="#F0F0F0">
<pre>
/**
 * @version: 1.1
 * @Time: 2005.03.02
 */
package com.river.page ;
import java.util.*;
import javax.servlet.http.HttpServletRequest;
public class PageUtil {
  private HttpServletRequest request = null ;
  public PageUtil(){
  }
  public void init(HttpServletRequest _request){
    this.request = _request ;
  }
  public void clear(){
    if(this.request != null){
      this.request = null ;
    }
  }
  public String get(String elementName){
    if(request == null || request.getParameter(elementName) == null){
      return "";
    }else{
      return request.getParameter(elementName);
    }
  }
  public String get(HttpServletRequest _request,String elementName){
    init(_request);
    return get(elementName);
  }
  
  public String getSQL(HttpServletRequest _request){
    init(_request);
 return getSQL();
  }
  public String getSQL(){
    String sqlstr = "";
    String c_table = get("c_table");
    String c_genre = get("c_genre");
    String c_where = get("c_where");
    if(c_genre == null || c_genre.equals("")){
      return "the action is null/empty";
    }
    if(c_table == null || c_table.equals("")){
      return "unknow table/empty" ;
    }
    if(c_genre.equalsIgnoreCase("INSERT")){
      java.util.Enumeration arg_names = request.getParameterNames();
      String colstr = "",valstr = "";
      String arg_name,pre_name,end_name ;
      while(arg_names.hasMoreElements()){
        arg_name = String.valueOf(arg_names.nextElement());
        if(arg_name.length() &lt; 2){
          continue;
        }
        pre_name = arg_name.substring(0,2);
        end_name = arg_name.substring(2);
        if(pre_name.equalsIgnoreCase("i_")){
          colstr = colstr+","+end_name;
          if(get(arg_name).equals("")){
            valstr = valstr+",NULL";
          }else{
            valstr = valstr + "," + String.valueOf(get(arg_name));
          }
        }else if(pre_name.equalsIgnoreCase("s_")){
          colstr = colstr+","+end_name;
          if(get(arg_name).equals("")){
            valstr = valstr+",NULL";
          }else{
            valstr = valstr+",'"+get(arg_name).replaceAll("'","''")+"'";
          }
        }
      }
      if(!colstr.equals("")){
        colstr = colstr.substring(1);
        valstr = valstr.substring(1);
      }
      sqlstr = "INSERT INTO "+c_table+" ("+colstr+") VALUES ("+valstr+")";
      return sqlstr;
    }else if(c_genre.equalsIgnoreCase("UPDATE")){
      java.util.Enumeration arg_names = request.getParameterNames();
      String colstr = "";
      String arg_name,pre_name,end_name ;
      while(arg_names.hasMoreElements()){
        arg_name = String.valueOf(arg_names.nextElement()).trim();
        if(arg_name.length() &lt; 2){
          continue;
        }
        pre_name = arg_name.substring(0,2);
        end_name = arg_name.substring(2);
        if(pre_name.equalsIgnoreCase("i_")){
          if(get(arg_name).equals("")){
            colstr += ","+end_name+"=NULL";
          }else{
            colstr += ","+end_name+"="+get(arg_name);
          }
        }else if(pre_name.equalsIgnoreCase("s_")){
          if(get(arg_name).equals("")){
            colstr += ","+end_name+"="+get(arg_name);
          }else{
            colstr += ","+end_name+"='"+get(arg_name).replaceAll("'","''")+"'";
          }
        }
      }
      if(!colstr.equals("")){
        colstr = colstr.substring(1);
      }
      sqlstr = "UPDATE "+c_table+" SET "+colstr;
      if(!c_where.equals("")){
        sqlstr += " WHERE "+c_where;
      }
      return sqlstr;
    }else if(c_genre.equalsIgnoreCase("DELETE")){
      sqlstr = "DELETE FROM "+c_table;
      if(c_where != null &amp;&amp; !c_where.equals("")){
        sqlstr += " WHERE "+c_where;
      }
    }else{
      com.river.debug.Debug.show("unknow action type : "+c_genre);
      return null;
    }
    return sqlstr;
  }
  public String toString(){
    return "version 1.0, date 2005.03.02, author river";
  }
}

</pre></td>
</tr>
</tbody>
</table>
<p>这样我们就可以根据页面元素的命名来指导SQL语句的生成。这样做有很多的明显的好处：<br>
<br>
1.
减少编码工作，对于元素很多表单，用不着我们去写一大堆的代码，不用去担心哪个元素落下了，元素名有没有些错，单引号有没有处理。<br>
<br>
2. 通用、稳定、易于维护，javabean固有的优点，就不用太多的说明了。<br>
<br>
3.
分离表层的表单内容与逻辑层SQL语句的构造。设想一下，如果我们数据库表结构有调整时，那么我们只要修改一下表单就好了，根本就不用理原来写好的逻辑处理。附带着再说一句，设想如果我们再写一个类自动执行SQL，那么对于一些基本的增、删、改操作都可以映射到同一个action里面来处理，且不是很爽？<br>

<br>
当然，这样做的缺点也是有的。那就是有一定的性能损耗。特别是碰到表单元素非常多时。但是我想对于那些不是很"苛刻"的项目这点损耗是值得的。</p>
</div>]]></description>
	    <author><![CDATA[CaCell]]></author>
	    <comments>http://zouzhxi.blog.163.com/blog/static/155925120087710719457</comments>
    <slash:comments>0</slash:comments>
    <guid isPermaLink="true">http://zouzhxi.blog.163.com/blog/static/155925120087710719457</guid>
    <pubDate>Thu, 7 Aug 2008 10:07:19 +0800</pubDate>
    <dcterms:modified>2008-08-07T10:07:19+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[[转载] Java事务处理总结]]></title>	
    <link>http://zouzhxi.blog.163.com/blog/static/15592512008779593588</link>
    <description><![CDATA[<div><p><strong>一、什么是Java事务</strong></p>
通常的观念认为，事务仅与数据库相关。<br>
<p>
事务必须服从ISO/IEC所制定的ACID原则。ACID是原子性（atomicity）、一致性（consistency）、隔离性（isolation）和持久性（durability）的缩写。事务的原子性表示事务
执行过程中的任何失败都将导致事务所做的任何修改失效。一致性表示当事务执行失败时，所有被该事务影响的数据都应该恢复到事务执行前的状态。隔离性表示在事务执行过程
中对数据的修改，在事务提交之前对其他事务不可见。持久性表示已提交的数据在事务执行失败时，数据的状态都应该正确。</p>
<p>
通俗的理解，事务是一组原子操作单元，从数据库角度说，就是一组SQL指令，要么全部执行成功，若因为某个原因其中一条指令执行有错误，则撤销先前执行过的所有指令。更简
答的说就是：要么全部执行成功，要么撤销不执行。</p>
<p>既然事务的概念从数据库而来，那Java事务是什么？之间有什么联系？</p>
<p>
实际上，一个Java应用系统，如果要操作数据库，则通过JDBC来实现的。增加、修改、删除都是通过相应方法间接来实现的，事务的控制也相应转移到Java程序代码中。因此，数
据库操作的事务习惯上就称为Java事务。</p>
<p><strong>二、为什么需要事务</strong></p>
事务是为解决数据安全操作提出的，事务控制实际上就是控制数据的安全访问。具一个简单例子：比如银行转帐业务，账户A要将自己账户上的1000元转到B账户下面，A账户余额首
先要减去1000元，然后B账户要增加1000元。假如在中间网络出现了问题，A账户减去1000元已经结束，B因为网络中断而操作失败，那么整个业务失败，必须做出控制，要求A账户
转帐业务撤销。这才能保证业务的正确性，完成这个操走就需要事务，将A账户资金减少和B账户资金增加方到一个事务里面，要么全部执行成功，要么操作全部撤销，这样就保持
了数据的安全性。
<p><strong>三、Java事务的类型</strong></p>
<p>Java事务的类型有三种：JDBC事务、JTA(Java Transaction API)事务、容器事务。</p>
<p>1、JDBC事务</p>
<p>JDBC 事务是用 Connection 对象控制的。JDBC Connection 接口(
java.sql.Connection )提供了两种事务模式：自动提交和手工提交。 java.sql.Connection
提供了以下控制事 务的方法：</p>
<p>public void setAutoCommit(boolean)<br>
public boolean getAutoCommit()<br>
public void commit()<br>
public void rollback()</p>
<p>使用 JDBC 事务界定时，您可以将多个 SQL 语句结合到一个事务中。JDBC
事务的一个缺点是事务的范围局限于一个数据库连接。一个 JDBC 事务不能跨越多个数据库。</p>
<p>2、JTA(Java Transaction API)事务</p>
<p>JTA是一种高层的，与实现无关的，与协议无关的API，应用程序和应用服务器可以使用JTA来访问事务。</p>
<p>
JTA允许应用程序执行分布式事务处理--在两个或多个网络计算机资源上访问并且更新数据，这些数据可以分布在多个数据库上。JDBC驱动程序的JTA支持极大地增强了数据访问能
力。</p>
<p>如果计划用 JTA 界定事务，那么就需要有一个实现 javax.sql.XADataSource 、
javax.sql.XAConnection 和 javax.sql.XAResource 接口的 JDBC
驱动程序。一个实现了这些接 口的驱动程序将可以参与 JTA 事务。一个 XADataSource 对象就是一个
XAConnection 对象的工厂。 XAConnection s 是参与 JTA 事务的 JDBC 连接。</p>
<p>您将需要用应用服务器的管理工具设置 XADataSource 。从应用服务器和 JDBC
驱动程序的文档中可以了解到相关的指导。</p>
<p>J2EE 应用程序用 JNDI 查询数据源。一旦应用程序找到了数据源对象，它就调用
javax.sql.DataSource.getConnection() 以获得到数据库的连接。</p>
<p>XA 连接与非 XA 连接不同。一定要记住 XA 连接参与了 JTA 事务。这意味着 XA 连接不支持 JDBC
的自动提交功能。同时，应用程序一定不要对 XA 连接调用 java.sql.Connection.commit() 或者
java.sql.Connection.rollback() 。相反，应用程序应该使用
UserTransaction.begin()、 UserTransaction.commit() 和
serTransaction.rollback() 。</p>
<p>3、容器事务</p>
<p>
容器事务主要是J2EE应用服务器提供的，容器事务大多是基于JTA完成，这是一个基于JNDI的，相当复杂的API实现。相对编码实现JTA事务管理，我们可以通过EJB容器提供的容器
事务管理机制（CMT）完成同一个功能，这项功能由J2EE应用服务器提供。这使得我们可以简单的指定将哪个方法加入事务，一旦指定，容器将负责事务管理任务。这是我们土建的
解决方式，因为通过这种方式我们可以将事务代码排除在逻辑编码之外，同时将所有困难交给J2EE容器去解决。使用EJB
CMT的另外一个好处就是程序员无需关心JTA API的编码， 不过，理论上我们必须使用EJB。</p>
<p><strong>四、三种事务差异</strong></p>
<p>1、JDBC事务控制的局限性在一个数据库连接内，但是其使用简单。</p>
<p>2、JTA事务的功能强大，事务可以跨越多个数据库或多个DAO，使用也比较复杂。</p>
<p>3、容器事务，主要指的是J2EE应用服务器提供的事务管理，局限于EJB应用使用。</p>
<p><strong>五、总结</strong></p>
<p>事务控制是构建J2EE应用不可缺少的一部分，合理选择应用何种事务对整个应用系统来说至关重要。一般说来，在单个JDBC
连接连接的情况下可以选择JDBC事务，在跨多个连接或
者数据库情况下，需要选择使用JTA事务，如果用到了EJB，则可以考虑使用EJB容器事务。</p></div>]]></description>
	    <author><![CDATA[CaCell]]></author>
	    <comments>http://zouzhxi.blog.163.com/blog/static/15592512008779593588</comments>
    <slash:comments>2</slash:comments>
    <guid isPermaLink="true">http://zouzhxi.blog.163.com/blog/static/15592512008779593588</guid>
    <pubDate>Thu, 7 Aug 2008 09:59:03 +0800</pubDate>
    <dcterms:modified>2008-08-07T09:59:03+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[手工实现JDBC事务管理]]></title>	
    <link>http://zouzhxi.blog.163.com/blog/static/15592512008779554339</link>
    <description><![CDATA[<div><h2>手工实现JDBC事务管理</h2>
<pre>

來源:http://www.ublog.cn/user1/11/index.html
By: foxty
</pre>
<p>
最近由于项目原因，底层数据库访问都必须使用JDBC来操作，为了能更好的实现事务，而且也便于将来移植到Ibatis上去，在作设计的时候参照Ibatis的Dao模式来设计dao，然
后事务控制就必须得自己手工来实现了。并且一起也实现了事务得嵌套。主要依靠2个类来实现。</p>
<dl>
<dd>1，TransactionUtil类，负责开启事务，提交事务以及关闭事务。</dd>
</dl>
<dl>
<dd>2，Transaction类，用来记录当前事务得状态以及数据库连接。</dd>
</dl>
<p style="margin: 5px; line-height: 150%"></p>
<table style="border: 1px solid rgb(255,0,0);" cellspacing="0"  bordercolordark="#ffffff" cellpadding="2" align="center"  bordercolorlight="#000000">
<tbody>
<tr>
<td style="font-size: 9pt" bgcolor="#F0F0F0"><span color=  "red">TransactionUtil类</span><br>
<pre>
package com.orizone.oa.extra.service;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import net.orizone.oa.common.ConnectionPoolBean;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.orizone.comm.util.BusinessException;

public class TransactionUtil 
{
 private final static ThreadLocal local = new ThreadLocal();
 private static Log log = LogFactory.getLog(TransactionUtil.class);
 
 /**
  * 开启事务
  */
 public static void startTransaction()throws  BusinessException
 {
  Transaction tran = (Transaction)local.get();
  //判断此事务是否属于一个顶层事务。
  if(tran == null)
  {
   tran = new Transaction();
   //设置本地线程的connection
   Connection con = ConnectionPoolBean.getConnection();
   try
   {
    con.setAutoCommit(false);
   }catch(SQLException e)
   {
    e.printStackTrace();
    throw new BusinessException(e, "开启事务失败！");
   }
   tran.setConnection(con);
   tran.setCommitCount(0);
   tran.setTransCount(1);
   tran.setTransDeep(1);
   
   local.set(tran);
  }else
  {
   //事务已经开启，将嵌套层次深度加一，将事务次数加一
   tran.setTransCount(tran.getTransCount() + 1);
   tran.setTransDeep(tran.getTransDeep() + 1);
  }  
 }
 
 /**
  * 提交事务
  *
  */
 public static void commitTransaction()throws  BusinessException
 {
  Transaction tran = (Transaction)local.get();
  //如果事务属于嵌套，则不提交数据，直接将层次数减一。
  if(tran.getTransDeep() &gt; 1)
  {
   tran.setTransDeep(tran.getTransDeep() - 1);
   tran.setCommitCount(tran.getCommitCount() + 1);
   return;
  }
  
  Connection con = tran.getConnection();
  try
  {
   if(tran.hasFullExecute())
   {
    con.commit();   
   }
  }catch(SQLException e)
  {
   log.error(e);   
   throw new BusinessException(e, "提交事务失败!");
  }
 }
 
 /**
  * 结束事务
  *
  */
 public static void endTransaction()throws  BusinessException
 {
  Transaction tran = (Transaction)local.get();
  //如果事务属于嵌套，则不关闭连接，直接将层次数减一。
  if(tran.getTransDeep() &gt; 1)
  {
   tran.setTransDeep(tran.getTransDeep() - 1);
   return;
  }
  
  //当前事务已经结束，清空ThreadLocal变量，防止下一次操作拿到已经关闭的Connection对象。
  local.set(null);
  Connection con = tran.getConnection();
  try
  {
   if(!tran.hasFullExecute())
   {
    con.rollback();
   }
  }catch(SQLException e)
  {
   log.error(e);
   throw new BusinessException(e, "事务回滚失败!");
  }finally
  {
   try
   {
    con.close();
   }catch(SQLException se)
   {
    log.error(se);
    throw new BusinessException(se, "关闭事务失败!");
   }
  }
  
 }
 
 /**
  * 获取当前事务的数据库连接。
  * @return
  */
 public static Connection getConnection()
 {
  Transaction tran = (Transaction)local.get();
  Connection  con = tran.getConnection();
  if(con == null)
  {
   con = ConnectionPoolBean.getConnection();   
  }
  return con;
 }
 
 /**
  * 测试代码
  * @param args
  * @throws Exception
  */
 public static void main(String args[])throws Exception
 {
  test();
  test();
 }
 
 /**
  * 测试代码
  *
  */
 private static void test()
 {
  TransactionUtil.startTransaction();
  try
  {
   Connection con = TransactionUtil.getConnection();
   Statement stmt = con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
   stmt.executeUpdate("INSERT INTO bb(bb) values('bb')");
   stmt.executeUpdate("INSERT INTO aa(aa) values('aa')");
   //if(true) throw new Exception("");
   TransactionUtil.commitTransaction();
  }catch(Exception e)
  {
   e.printStackTrace();
   //throw new BusinessException("");
  }finally
  {
   TransactionUtil.endTransaction();
  }
 }
}
</pre></td>
</tr>
</tbody>
</table>
<p style="margin: 5px; line-height: 150%"></p>
<table style="border: 1px solid rgb(255,0,0);" cellspacing="0"  bordercolordark="#ffffff" cellpadding="2" align="center"  bordercolorlight="#000000">
<tbody>
<tr>
<td style="font-size: 9pt" bgcolor="#F0F0F0">
<pre>
<span color="red">Transaction类</span><br>
package com.orizone.oa.extra.service;

import java.sql.Connection;

public class Transaction 
{
 //数据库连接对象
 private Connection connection;
 //事务次数
 private int transCount;
 //提交次数
 private int commitCount;
 //事务嵌套层次
 private int transDeep;

 int getCommitCount() 
 {
  return commitCount;
 }

 void setCommitCount(int commitCount) 
 {
  this.commitCount = commitCount;
 }

 Connection getConnection() 
 {
  return connection;
 }

 void setConnection(Connection conn) 
 {
  this.connection = conn;
 }

 public int getTransCount() 
 {
  return transCount;
 }

 void setTransCount(int transCount) 
 {
  this.transCount = transCount;
 }

 int getTransDeep() 
 {
  return transDeep;
 }

 void setTransDeep(int transDeep)
 {
  this.transDeep = transDeep;
 }
 
 /**
  * 判断事务是否完全提交。
  * 通过提交次数和事务次数来判断事务是否完全提交。
  * @return
  */
 boolean hasFullExecute()
 {
  return commitCount + 1 == transCount;
 }
}
</pre></td>
</tr>
</tbody>
</table>
<p>
代码中出现的ConnectionPoolBean是用来负责获取数据库连接的类。整个思想就是，将一个Transaction相关信息（数据库连接对象，事务次数，提交次数以及事务深度）放入到当
前线程的ThradLocal当中，后面的操作都是基于这个事务基础的，这样才能保证事务的原子性。在commit的时候会判断当前事务层次深度，如果为顶层，并且提交次数＋1等于事务
次数（说明事务是安全完整的执行了），才真正提交到数据库。如果不完整，则在endTrnasaction的时候会回滚整个事务。</p>
<p>虽然这样能够实现事务操作，但是无法实现跨数据库操作，要实现跨数据库的事务估计只能用JTA了。</p></div>]]></description>
	    <author><![CDATA[CaCell]]></author>
	    <comments>http://zouzhxi.blog.163.com/blog/static/15592512008779554339</comments>
    <slash:comments>0</slash:comments>
    <guid isPermaLink="true">http://zouzhxi.blog.163.com/blog/static/15592512008779554339</guid>
    <pubDate>Thu, 7 Aug 2008 09:55:04 +0800</pubDate>
    <dcterms:modified>2008-08-07T14:09:33+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[审查Java代码的十一种常见错误]]></title>	
    <link>http://zouzhxi.blog.163.com/blog/static/1559251200856111753347</link>
    <description><![CDATA[<div><p></p><h1>审查Java代码的十一种常见错误</h1>

<p></p><pre>
作者：佚名
文章来源：北天JAVA技术网(www.java114.com)
</pre>
<p>
代码审查是消灭Bug最重要的方法之一，这些审查在大多数时候都特别奏效。由于代码审查本身所针对的对象，就是俯瞰整个代码在测试过程中的问题和Bug。并且，代码审查对消除一些特别细节的错误大有裨益，尤其是那些能够容易在阅读代码的时候发现的错误，这些错误往往不容易通过机器上的测试识别出来。本文就常见的Java代码中容易出现的问题提出一些建设性建议，以便您在审查代码的过程中注意到这些常见的细节性错误。 </p><p>
　　通常给别人的工作挑错要比找自己的错容易些。别样视角的存在也解释了为什么作者需要编辑，而运动员需要教练的原因。不仅不应当拒绝别人的批评，我们应该欢迎别人来发现并指出我们的编程工作中的不足之处，我们会受益匪浅的。</p><p>

　正规的代码审查(code inspection)是提高代码质量的最强大的技术之一，代码审查—由同事们寻找代码中的错误—所发现的错误与在测试中所发现的错误不同，因此两者的关系是互补的，而非竞争的。 
 </p><p>
　　如果审查者能够有意识地寻找特定的错误，而不是靠漫无目的的浏览代码来发现错误，那么代码审查的效果会事半功倍。在这篇文章中，我列出了11个Java编程中常见的错误。你可以把这些错误添加到你的代码审查的检查列表(checklist)中，这样在经过代码审查后，你可以确信你的代码中不再存在这类错误了。
</p><p>
　　一、常见错误1# ：多次拷贝字符串</p><p>

　　测试所不能发现的一个错误是生成不可变(immutable)对象的多份拷贝。不可变对象是不可改变的，因此不需要拷贝它。最常用的不可变对象是String。
</p><p>
　　如果你必须改变一个String对象的内容，你应该使用StringBuffer。下面的代码会正常工作： 
</p><p style="margin: 5px; line-height: 150%">
<table style="border: 1px solid rgb(255,0,0);" cellspacing="0" bordercolordark="#ffffff" cellpadding="2" align="center" bordercolorlight="#000000">
<tbody><tr><td style="font-size: 9pt" bgcolor="#f0f0f0">
<pre>
String s = new String ("Text here"); 
</pre>
</td></tr></tbody></table></p><p>
　　但是，这段代码性能差，而且没有必要这么复杂。你还可以用以下的方式来重写上面的代码： 
</p><p style="margin: 5px; line-height: 150%">
<table style="border: 1px solid rgb(255,0,0);" cellspacing="0" bordercolordark="#ffffff" cellpadding="2" align="center" bordercolorlight="#000000">
<tbody><tr><td style="font-size: 9pt" bgcolor="#f0f0f0">
<pre>
String temp = "Text here"; 
String s = new String (temp); 
</pre>
</td></tr></tbody></table></p><p>
　　但是这段代码包含额外的String，并非完全必要。更好的代码为： 
</p><p style="margin: 5px; line-height: 150%">
<table style="border: 1px solid rgb(255,0,0);" cellspacing="0" bordercolordark="#ffffff" cellpadding="2" align="center" bordercolorlight="#000000">
<tbody><tr><td style="font-size: 9pt" bgcolor="#f0f0f0">
<pre>
String s = "Text here"; 
</pre>
</td></tr></tbody></table></p><p>
　　二、常见错误2#： 没有克隆(clone)返回的对象
</p><p>
　　封装(encapsulation)是面向对象编程的重要概念。不幸的是，Java为不小心打破封装提供了方便——Java允许返回私有数据的引用(reference)。下面的代码揭示了这一点： 
</p><p style="margin: 5px; line-height: 150%">
<table style="border: 1px solid rgb(255,0,0);" cellspacing="0" bordercolordark="#ffffff" cellpadding="2" align="center" bordercolorlight="#000000">
<tbody><tr><td style="font-size: 9pt" bgcolor="#f0f0f0">
<pre>
import java.awt.Dimension; 
/***
 *Example class.The x and y values should never
 *be negative.
 */ 
public class Example{ 
　 private Dimension d = new Dimension (0, 0); 
　 public Example (){ } 

　 /***
    * Set height and width. Both height and width must be nonnegative
    * or an exception is thrown.
    */ 
　 public synchronized void setValues (int height,int width) throws IllegalArgumentException{ 
　　 if (height < 0 || width < 0)   　　　 throw new IllegalArgumentException();   　　　 d.height = height;   　　    d.width = width;   　 }    　 public synchronized Dimension getValues(){   　　 // Ooops! Breaks encapsulation   　　 return d;   　 }   }   </pre>
</td></tr></tbody></table></p><p>
　　Example类保证了它所存储的height和width值永远非负数，试图使用setValues()方法来设置负值会触发异常。不幸的是，由于getValues()返回d的引用，而不是d的拷贝，你可以编写如下的破坏性代码： 
</p><p style="margin: 5px; line-height: 150%">
<table style="border: 1px solid rgb(255,0,0);" cellspacing="0" bordercolordark="#ffffff" cellpadding="2" align="center" bordercolorlight="#000000">
<tbody><tr><td style="font-size: 9pt" bgcolor="#f0f0f0">
<pre>
Example ex = new Example(); 
Dimension d = ex.getValues(); 
d.height = -5; 
d.width = -10; 
</pre>
</td></tr></tbody></table></p><p>
　　现在，Example对象拥有负值了！如果getValues() 的调用者永远也不设置返回的Dimension对象的width 和height值，那么仅凭测试是不可能检测到这类的错误。
</p><p>
　　不幸的是，随着时间的推移，客户代码可能会改变返回的Dimension对象的值，这个时候，追寻错误的根源是件枯燥且费时的事情，尤其是在多线程环境中。
</p><p>
　　更好的方式是让getValues()返回拷贝： 
</p><p style="margin: 5px; line-height: 150%">
<table style="border: 1px solid rgb(255,0,0);" cellspacing="0" bordercolordark="#ffffff" cellpadding="2" align="center" bordercolorlight="#000000">
<tbody><tr><td style="font-size: 9pt" bgcolor="#f0f0f0">
<pre>
public synchronized Dimension getValues(){ 
return new Dimension (d.x, d.y); 
} 
</pre>
</td></tr></tbody></table></p><p>
　　现在，Example对象的内部状态就安全了。调用者可以根据需要改变它所得到的拷贝的状态，但是要修改Example对象的内部状态，必须通过setValues()才可以。
</p><p>
　　三、常见错误3#：不必要的克隆
</p><p>
　　我们现在知道了get方法应该返回内部数据对象的拷贝，而不是引用。但是，事情没有绝对： 
</p><p style="margin: 5px; line-height: 150%">
<table style="border: 1px solid rgb(255,0,0);" cellspacing="0" bordercolordark="#ffffff" cellpadding="2" align="center" bordercolorlight="#000000">
<tbody><tr><td style="font-size: 9pt" bgcolor="#f0f0f0">
<pre>
/*** Example class.The value should never
 * be negative.
 */ 
public class Example{ 
　 private Integer i = new Integer (0); 
　 public Example (){ } 

　 /***
    * Set x. x must be nonnegative
    * or an exception will be thrown
    */ 
　 public synchronized void setValues (int x) throws IllegalArgumentException{ 
　　 if (x < 0)   　　　 throw new IllegalArgumentException();   　　　 i = new Integer (x);   　 }    　 public synchronized Integer getValue(){   　　 // We can’t clone Integers so we makea copy this way.   　　 return new Integer (i.intValue());   　 }   }   </pre>
</td></tr></tbody></table></p><p>
　　这段代码是安全的，但是就象在错误1#那样，又作了多余的工作。Integer对象，就象String对象那样，一旦被创建就是不可变的。因此，返回内部Integer对象，而不是它的拷贝，也是安全的。
</p><p>
　　方法getValue()应该被写为： 
</p><p style="margin: 5px; line-height: 150%">
<table style="border: 1px solid rgb(255,0,0);" cellspacing="0" bordercolordark="#ffffff" cellpadding="2" align="center" bordercolorlight="#000000">
<tbody><tr><td style="font-size: 9pt" bgcolor="#f0f0f0">
<pre>
public synchronized Integer getValue(){ 
// ’i’ is immutable, so it is safe to return it instead of a copy. 
return i; 
} 
</pre>
</td></tr></tbody></table></p><p>
　　Java程序比C++程序包含更多的不可变对象。JDK 所提供的若干不可变类包括： 
</p><p style="margin: 5px; line-height: 150%">
<table style="border: 1px solid rgb(255,0,0);" cellspacing="0" bordercolordark="#ffffff" cellpadding="2" align="center" bordercolorlight="#000000">
<tbody><tr><td style="font-size: 9pt" bgcolor="#f0f0f0">
<pre>
　　·Boolean 
　　 ·Byte 
　　 ·Character 
　　 ·Class 
　　 ·Double 
　　 ·Float 
　　 ·Integer 
　　 ·Long 
　　 ·Short 
　　 ·String 
　　 ·大部分的Exception的子类
</pre>
</td></tr></tbody></table></p><p>
　　四、常见错误4# ：自编代码来拷贝数组
</p><p>
　　Java允许你克隆数组，但是开发者通常会错误地编写如下的代码，问题在于如下的循环用三行做的事情，如果采用Object的clone方法用一行就可以完成： 
</p><p style="margin: 5px; line-height: 150%">
<table style="border: 1px solid rgb(255,0,0);" cellspacing="0" bordercolordark="#ffffff" cellpadding="2" align="center" bordercolorlight="#000000">
<tbody><tr><td style="font-size: 9pt" bgcolor="#f0f0f0">
<pre>
public class Example{ 
　 private int[] copy; 
　 /***
    *Save a copy of ’data’. ’data’ cannot be null.
    */ 
　 public void saveCopy (int[] data){ 
　　 copy = new int[data.length]; 
　　 for (int i = 0; i < copy.length; ++i)   　　　 copy[i] = data[i];   　 }   }   </pre>
</td></tr></tbody></table></p><p>
　　这段代码是正确的，但却不必要地复杂。saveCopy()的一个更好的实现是： 
</p><p style="margin: 5px; line-height: 150%">
<table style="border: 1px solid rgb(255,0,0);" cellspacing="0" bordercolordark="#ffffff" cellpadding="2" align="center" bordercolorlight="#000000">
<tbody><tr><td style="font-size: 9pt" bgcolor="#f0f0f0">
<pre>
void saveCopy (int[] data){ 
　 try{ 
　　 copy = (int[])data.clone(); 
　 }catch (CloneNotSupportedException e){ 
　　 // Can’t get here. 
　 } 
} 
</pre>
</td></tr></tbody></table></p><p>
　　如果你经常克隆数组，编写如下的一个工具方法会是个好主意： 
</p><p style="margin: 5px; line-height: 150%">
<table style="border: 1px solid rgb(255,0,0);" cellspacing="0" bordercolordark="#ffffff" cellpadding="2" align="center" bordercolorlight="#000000">
<tbody><tr><td style="font-size: 9pt" bgcolor="#f0f0f0">
<pre>
static int[] cloneArray (int[] data){ 
　 try{ 
　　 return(int[])data.clone(); 
　 }catch(CloneNotSupportedException e){ 
　　 // Can’t get here. 
　 } 
} 
</pre>
</td></tr></tbody></table></p><p>
　　这样的话，我们的saveCopy看起来就更简洁了： 
</p><p style="margin: 5px; line-height: 150%">
<table style="border: 1px solid rgb(255,0,0);" cellspacing="0" bordercolordark="#ffffff" cellpadding="2" align="center" bordercolorlight="#000000">
<tbody><tr><td style="font-size: 9pt" bgcolor="#f0f0f0">
<pre>
void saveCopy (int[] data){ 
　 copy = cloneArray ( data); 
} 
</pre>
</td></tr></tbody></table></p><p>
　　五、常见错误5#：拷贝错误的数据
</p><p>
　　有时候程序员知道必须返回一个拷贝，但是却不小心拷贝了错误的数据。由于仅仅做了部分的数据拷贝工作，下面的代码与程序员的意图有偏差： 
</p><p style="margin: 5px; line-height: 150%">
<table style="border: 1px solid rgb(255,0,0);" cellspacing="0" bordercolordark="#ffffff" cellpadding="2" align="center" bordercolorlight="#000000">
<tbody><tr><td style="font-size: 9pt" bgcolor="#f0f0f0">
<pre>
import java.awt.Dimension; 
/*** Example class. The height and width values should never 
 * be negative.
 */ 
public class Example{ 
　 static final public int TOTAL_VALUES = 10; 
　 private Dimension[] d = new Dimension[TOTAL_VALUES]; 
　 public Example (){ } 

/*** Set height and width. Both height and width must be nonnegative
 * or an exception will be thrown.
 */ 
　 public synchronized void setValues (int index, int height, int width) throws IllegalArgumentException{ 
　　 if (height < 0 || width < 0)   　　　 throw new IllegalArgumentException();   　　　 if (d[index] == null)   　　　　 d[index] = new Dimension();   　　　　 d[index].height = height;   　　　　 d[index].width = width;   　 }  　 public synchronized Dimension[] getValues()   　　 throws CloneNotSupportedException{   　　　 return (Dimension[])d.clone();   　 }   }   </pre>
</td></tr></tbody></table></p><p>
　　这儿的问题在于getValues()方法仅仅克隆了数组，而没有克隆数组中包含的Dimension对象，因此，虽然调用者无法改变内部的数组使其元素指向不同的Dimension对象，但是调用者却可以改变内部的数组元素(也就是Dimension对象)的内容。方法getValues()的更好版本为： 
</p><p style="margin: 5px; line-height: 150%">
<table style="border: 1px solid rgb(255,0,0);" cellspacing="0" bordercolordark="#ffffff" cellpadding="2" align="center" bordercolorlight="#000000">
<tbody><tr><td style="font-size: 9pt" bgcolor="#f0f0f0">
<pre>
public synchronized Dimension[] getValues() throws CloneNotSupportedException{ 
　 Dimension[] copy = (Dimension[])d.clone(); 
　 for (int i = 0; i < copy.length; ++i){   　　 // NOTE: Dimension isn’t cloneable.   　　 if (d != null)   　　　 copy[i] = new Dimension (d[i].height, d[i].width);   　 }  　 return copy;   }   </pre>
</td></tr></tbody></table></p><p>
　　在克隆原子类型数据的多维数组的时候，也会犯类似的错误。原子类型包括int,float等。简单的克隆int型的一维数组是正确的，如下所示： 
</p><p style="margin: 5px; line-height: 150%">
<table style="border: 1px solid rgb(255,0,0);" cellspacing="0" bordercolordark="#ffffff" cellpadding="2" align="center" bordercolorlight="#000000">
<tbody><tr><td style="font-size: 9pt" bgcolor="#f0f0f0">
<pre>
public void store (int[] data) throws CloneNotSupportedException{ 
　 this.data = (int[])data.clone(); 
　 // OK 
} 
</pre>
</td></tr></tbody></table></p><p>
　　拷贝int型的二维数组更复杂些。Java没有int型的二维数组，因此一个int型的二维数组实际上是一个这样的一维数组：它的类型为int[]。简单的克隆int[][]型的数组会犯与上面例子中getValues()方法第一版本同样的错误，因此应该避免这么做。下面的例子演示了在克隆int型二维数组时错误的和正确的做法： 
</p><p style="margin: 5px; line-height: 150%">
<table style="border: 1px solid rgb(255,0,0);" cellspacing="0" bordercolordark="#ffffff" cellpadding="2" align="center" bordercolorlight="#000000">
<tbody><tr><td style="font-size: 9pt" bgcolor="#f0f0f0">
<pre>
public void wrongStore (int[][] data) throws CloneNotSupportedException{ 
　 this.data = (int[][])data.clone(); // Not OK! 
}
public void rightStore (int[][] data){ 
　 // OK! 
　 this.data = (int[][])data.clone(); 
　 for (int i = 0; i < data.length; ++i){   　　 if (data != null)   　　　 this.data[i] = (int[])data[i].clone();   　 }   }   </pre>
</td></tr></tbody></table></p><p>

　　 六、常见错误6#：检查new 操作的结果是否为null 
</p><p>
　　Java编程新手有时候会检查new操作的结果是否为null。可能的检查代码为： 
</p><p style="margin: 5px; line-height: 150%">
<table style="border: 1px solid rgb(255,0,0);" cellspacing="0" bordercolordark="#ffffff" cellpadding="2" align="center" bordercolorlight="#000000">
<tbody><tr><td style="font-size: 9pt" bgcolor="#f0f0f0">
<pre>
Integer i = new Integer (400); 
if (i == null) 
throw new NullPointerException(); 
</pre>
</td></tr></tbody></table></p><p>
　　检查当然没什么错误，但却不必要，if和throw这两行代码完全是浪费，他们的唯一功用是让整个程序更臃肿，运行更慢。
</p><p>
　　C/C++程序员在开始写java程序的时候常常会这么做，这是由于检查C中malloc()的返回结果是必要的，不这样做就可能产生错误。检查C++中new操作的结果可能是一个好的编程行为，这依赖于异常是否被使能(许多编译器允许异常被禁止，在这种情况下new操作失败就会返回null)。在java 中，new 操作不允许返回null，如果真的返回null，很可能是虚拟机崩溃了，这时候即便检查返回结果也无济于事。
</p><p>
　　七、常见错误7#：用== 替代.equals 
</p><p>
　　在Java中，有两种方式检查两个数据是否相等：通过使用==操作符，或者使用所有对象都实现的.equals方法。原子类型(int, flosat, char 等)不是对象，因此他们只能使用==操作符，如下所示： 
</p><p style="margin: 5px; line-height: 150%">
<table style="border: 1px solid rgb(255,0,0);" cellspacing="0" bordercolordark="#ffffff" cellpadding="2" align="center" bordercolorlight="#000000">
<tbody><tr><td style="font-size: 9pt" bgcolor="#f0f0f0">
<pre>
int x = 4; 
int y = 5; 
if (x == y) 
   System.out.println ("Hi"); 
// This ’if’ test won’t compile. 
if (x.equals (y)) 
   System.out.println ("Hi"); 
</pre>
</td></tr></tbody></table></p><p>
　　对象更复杂些，==操作符检查两个引用是否指向同一个对象，而equals方法则实现更专门的相等性检查。
</p><p>
　　更显得混乱的是由java.lang.Object 所提供的缺省的equals方法的实现使用==来简单的判断被比较的两个对象是否为同一个。
</p><p>
　　许多类覆盖了缺省的equals方法以便更有用些，比如String类，它的equals方法检查两个String对象是否包含同样的字符串，而Integer的equals方法检查所包含的int值是否相等。
</p><p>
　　大部分时候，在检查两个对象是否相等的时候你应该使用equals方法，而对于原子类型的数据，你用该使用==操作符。
</p><p>
　　八、常见错误8#： 混淆原子操作和非原子操作 
</p><p>
　　Java保证读和写32位数或者更小的值是原子操作，也就是说可以在一步完成，因而不可能被打断，因此这样的读和写不需要同步。以下的代码是线程安全(thread safe)的： 
</p><p style="margin: 5px; line-height: 150%">
<table style="border: 1px solid rgb(255,0,0);" cellspacing="0" bordercolordark="#ffffff" cellpadding="2" align="center" bordercolorlight="#000000">
<tbody><tr><td style="font-size: 9pt" bgcolor="#f0f0f0">
<pre>
public class Example{ 
　 private int value; // More code here... 
　 public void set (int x){ 
　　 // NOTE: No synchronized keyword 
　　 this.value = x; 
　 } 
} </pre>
</td></tr></tbody></table></p><p>

　　不过，这个保证仅限于读和写，下面的代码不是线程安全的： 
</p><p style="margin: 5px; line-height: 150%">
<table style="border: 1px solid rgb(255,0,0);" cellspacing="0" bordercolordark="#ffffff" cellpadding="2" align="center" bordercolorlight="#000000">
<tbody><tr><td style="font-size: 9pt" bgcolor="#f0f0f0">
<pre>
public void increment (){ 
　 // This is effectively two or three instructions: 
　 // 1) Read current setting of ’value’. 
　 // 2) Increment that setting. 
　 // 3) Write the new setting back. 
　 ++this.value; 
} 
</pre>
</td></tr></tbody></table></p><p>
　　在测试的时候，你可能不会捕获到这个错误。首先，测试与线程有关的错误是很难的，而且很耗时间。其次，在有些机器上，这些代码可能会被翻译成一条指令，因此工作正常，只有当在其它的虚拟机上测试的时候这个错误才可能显现。因此最好在开始的时候就正确地同步代码： 
</p><p style="margin: 5px; line-height: 150%">
<table style="border: 1px solid rgb(255,0,0);" cellspacing="0" bordercolordark="#ffffff" cellpadding="2" align="center" bordercolorlight="#000000">
<tbody><tr><td style="font-size: 9pt" bgcolor="#f0f0f0">
<pre>
public synchronized void increment (){ 
　 ++this.value; 
} 
</pre>
</td></tr></tbody></table></p><p>
　　九、常见错误9#：在catch 块中作清除工作
</p><p>
　　一段在catch块中作清除工作的代码如下所示： 
</p><p style="margin: 5px; line-height: 150%">
<table style="border: 1px solid rgb(255,0,0);" cellspacing="0" bordercolordark="#ffffff" cellpadding="2" align="center" bordercolorlight="#000000">
<tbody><tr><td style="font-size: 9pt" bgcolor="#f0f0f0">
<pre>
OutputStream os = null; 
try{ 
　 os = new OutputStream (); 
　 // Do something with os here. 
　 os.close(); 
}catch (Exception e){ 
　 if (os != null) 
　 os.close(); 
} 
</pre>
</td></tr></tbody></table></p><p>
　　尽管这段代码在几个方面都是有问题的，但是在测试中很容易漏掉这个错误。下面列出了这段代码所存在的三个问题： 
</p><p>
　　1．语句os.close()在两处出现，多此一举，而且会带来维护方面的麻烦。
</p><p>
　　2．上面的代码仅仅处理了Exception，而没有涉及到Error。但是当try块运行出现了Error，流也应该被关闭。
</p><p>
　　3．close()可能会抛出异常。
</p><p>
　　上面代码的一个更优版本为： 
</p><p style="margin: 5px; line-height: 150%">
<table style="border: 1px solid rgb(255,0,0);" cellspacing="0" bordercolordark="#ffffff" cellpadding="2" align="center" bordercolorlight="#000000">
<tbody><tr><td style="font-size: 9pt" bgcolor="#f0f0f0">
<pre>
OutputStream os = null; 
try{ 
　 os = new OutputStream (); 
　 // Do something with os here. 
}finally{ 
　 if (os != null) 
　　 os.close(); 
} 
</pre>
</td></tr></tbody></table></p><p>
　　这个版本消除了上面所提到的两个问题：代码不再重复，Error也可以被正确处理了。但是没有好的方法来处理第三个问题，也许最好的方法是把close()语句单独放在一个try/catch块中。
</p><p>
　　十、常见错误10#： 增加不必要的catch 块
</p><p>
　　一些开发者听到try/catch块这个名字后，就会想当然的以为所有的try块必须要有与之匹配的catch块。
</p><p>
　　C++程序员尤其是会这样想，因为在C++中不存在finally块的概念，而且try块存在的唯一理由只不过是为了与catch块相配对。
</p><p>
　　增加不必要的catch块的代码就象下面的样子，捕获到的异常又立即被抛出： 
</p><p style="margin: 5px; line-height: 150%">
<table style="border: 1px solid rgb(255,0,0);" cellspacing="0" bordercolordark="#ffffff" cellpadding="2" align="center" bordercolorlight="#000000">
<tbody><tr><td style="font-size: 9pt" bgcolor="#f0f0f0">
<pre>
try{ 
　 // Nifty code here 
}catch(Exception e){ 
　 throw e; 
}finally{ 
　 // Cleanup code here 
} 
</pre>
</td></tr></tbody></table></p><p>
　　不必要的catch块被删除后，上面的代码就缩短为： 
</p><p style="margin: 5px; line-height: 150%">
<table style="border: 1px solid rgb(255,0,0);" cellspacing="0" bordercolordark="#ffffff" cellpadding="2" align="center" bordercolorlight="#000000">
<tbody><tr><td style="font-size: 9pt" bgcolor="#f0f0f0">
<pre>
try{ 
　 // Nifty code here 
}finally{ 
　 // Cleanup code here 
} 
</pre>
</td></tr></tbody></table></p><p>
　　常见错误11#；没有正确实现equals，hashCode，或者clone 等方法
</p><p>
　　方法equals，hashCode，和clone 由java.lang.Object提供的缺省实现是正确的。不幸地是，这些缺省实现在大部分时候毫无用处，因此许多类覆盖其中的若干个方法以提供更有用的功能。但是，问题又来了，当继承一个覆盖了若干个这些方法的父类的时候，子类通常也需要覆盖这些方法。在进行代码审查时，应该确保如果父类实现了equals，hashCode，或者clone等方法，那么子类也必须正确。正确的实现equals，hashCode，和clone需要一些技巧。
</p><p>
　　小结
<br><br>
　　我在代码审查的时候至少遇到过一次这些错误，我自己也犯过其中的几个错误。好消息是只要你知道你在找什么错误，那么代码审查就很容易管理，错误也很容易被发现和修改。即便你找不到时间来进行正规的代码审查，以自审的方式把这些错误从你的代码中根除会大大节省你的调试时间。花时间在代码审查上是值得的。</p>
</div>]]></description>
	    <author><![CDATA[CaCell]]></author>
	    <comments>http://zouzhxi.blog.163.com/blog/static/1559251200856111753347</comments>
    <slash:comments>2</slash:comments>
    <guid isPermaLink="true">http://zouzhxi.blog.163.com/blog/static/1559251200856111753347</guid>
    <pubDate>Fri, 6 Jun 2008 11:17:53 +0800</pubDate>
    <dcterms:modified>2008-06-06T11:17:53+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[引用 ASP和PHP在IIS下共存]]></title>	
    <link>http://zouzhxi.blog.163.com/blog/static/1559251200841911249333</link>
    <description><![CDATA[<div><P><EM>引用</EM></P>
<BLOCKQUOTE><A href="http://ykhacker.blog.163.com/" target=_blank>丝文人</A> 的 <A href="http://ykhacker.blog.163.com/blog/static/665878200841145427749" target=_blank>ASP和PHP在IIS下共存</A><BR>
<P>　　我们都知道，微软公司一直提供的web服务器是iis。大名鼎鼎的ASP可以在IIS下运行.而当今网络所流行的不仅仅是ASP，php有着其更文阔的应用空间。一般网友认为php的运行环境较ASP而言相对复杂，其web服务器也比较难架设，实则不然。</P>
<P>　　正常来讲，架设一个php服务器的有效方法是下载并安装：appserv和ultraedit两个软件的任意版本。这是架设php服务器的最单间方法。可遗憾的是，这种方法架设的php服务器不能和ASP共生。</P>
<P>　　那么，想让ASP和PHP共享同一个服务器环境，又应该怎么实现呢？php-5.2.5版的出现，解决了这个问题。其实它的思路也比较简单，由于PHP可以跨web平台和服务器平台，因此，它提示我们，可以让ASP和PHP在IIS下共存。下面具体看一下步骤：</P>
<P>　　<STRONG>一、软件安装</STRONG></P>
<P>　　在Windows操作系统上通过安装IIS服务，可以很简单的建立一个网页服务器，但是IIS只能支持ASP程序的运行，对于网络上丰富的PHP程序资源，该如何才能使用呢？</P>
<P>　　通常，要运行PHP程序，都是使用Apache HTTP服务器+PHP处理程序来架设网页服务器的。但是，Apache无法直接支持ASP程序，而且它也不能和IIS共存，所以如果我们已经有并且习惯了使用IIS，就还是暂时不考虑安装Apache来提供对PHP的支持了。</P>
<P>　　要让IIS能够支持PHP程序，那么PHP处理程序是必需要安装的。5.2版之前的PHP处理程序在安装后都还需要手工再对IIS进行设置，才能够让IIS正确的运行PHP程序，这一点在最新的5.2.5版已经得到了改进。</P>
<P>　　最新版本的PHP 5.2.5安装程序可以从这里（<A href="http://cn2.php.net/distributions/php-5.2.5-win32-installer.msi">http://cn2.php.net/distributions/php-5.2.5-win32-installer.msi</A><BR>）下载到。运行下载好的安装程序，一路点击下一步，直到“Web Server Setup”这一步的时候，选择“IIS ISAPI module”，然后继续一路点击下一步，直至安装完成。</P>
<P>　　要验证PHP安装是否成功同样也非常的简单，将下面这段代码粘贴到记事本中：</P>
<P>　　&lt;?php<BR>　　Phpinfo();<BR>　　?&gt;</P>
<P>　　将其命名为“info.php”并保存到IIS设置的网页目录下（默认为“C:\Inetpub\wwwroot”），然后使用浏览器访问“http://localhost/info.php”或者“http://127.0.0.1/info.php”，如何看到了PHP的版本及信息说明，就证明PHP已经在你的IIS上开始正常运行了。</P>
<P>　　<STRONG>二、故障排除</STRONG></P>
<P><STRONG>　　</STRONG>安装过程一般是很顺利的，但由于IIS的版本不同，在安装后，很可能导致ASP和PHP都运行不了的情况，这就是IIS的Server Application Error错误。错误的表现有很多，这里只列举一个英文错误提示：The server has encountered an error while loading an application during the processing of your request. Please refer to the event log for more detail information. Please contact the server administrator for assistance. </P>
<P>　　这时只要按照如下的办法，一般来讲都能顺利解决：</P>
<P>　　1、右键我的电脑--管理--本地用户和组，给IUSR_机器名和IWAM_机器名两个用户设置密码，要一样。 </P>
<P>　　2、开始--运行--打cmd， <BR>　　然后cd Ｃ:InetpubAdminscripts（系统盘）， <BR>　　然后cscript.exe adsutil.vbs set w3svc/wamuserpass 你的密码， <BR>　　然后cscript.exe adsutil.vbs set w3svc/anonymoususerpass 你的密码 </P>
<P>　　看一下，行了没有？如果还不行，那么 <BR>　　cscript.exe synciwam.vbs -v， <BR>　　然后iisreset。 </P>
<P>　　据说就可以了,但是到最后一部提示8004e00f的错误,此错误是MSDTC服务不正常造成的,解决方法: </P>
<P>　　首先进入组件服务，查看组件服务/计算机/我的电脑/COM+应用程序，结果报错“COM+ 无法与 Microsoft 分布式事务协调程序交谈”，无法查看里面的对象。 <BR>　　2、进入事件查看器，发现msdtc服务没有正常启动。 <BR>　　3、删除注册表中的键：&nbsp;<BR>　　HKEY_LOCAL_MACHINESYSTEMCurrentControlSetServicesMSDTC&nbsp;<BR>　　HKEY_LOCAL_MACHINESOFTWAREMicrosoftMSDTC <BR>　　HKEY_CLASSES_ROOTCID <BR>　　4、停止MSDTC服务：net stop msdtc <BR>　　5、卸载MSDTC服务：msdtc -uninstall <BR>　　6、重新安装MSDTC服务：msdtc -install <BR>　　7、确认在事件查看器中msdtc服务已经正常启动[这步很关键，如果没有，重新启动下电脑看看] <BR>　　8、重新设置IIS的IWAM账号密码。[在计算机管理中的用户管理里] <BR>　　9、同步IIS metabase中IWAM_MYSERVER的密码，在CMD中：c:inetputadminscripts&gt;adsutil set w3svc/wamuserpass "yourpassword" <BR>　　10、同步COM+应用程序所用的IWAM_MYSERVER密码，在CMD中：c:inetputadminscripts&gt;cscript synciwam.vbs -v </P>
<P>　　到这部分网上大部分都说可以了,但是我这里虽然没有8004e00f的错误提示了,但是访问页面Server Application Error 错误依旧,最后终于找到了解决方法如下: </P>
<P>　　解决办法： <BR>　　[1]：检查你的DTC服务（全名：Distributed Transaction Coordinator）是否可以正常启动，如果正常的话请你跳过此步骤；如果出错，无法正常启动，请在开始菜单的运行中 运行：msdtc -resetlog 以创建日志文件。重起机器，检查IIS是否可以正常使用，若不行继续。 </P>
<P>　　[2]：在CMD下执行以下命令： <BR>　　cd %windir%\system32\inetsrv </P>
<P>　　rundll32 wamreg.dll, CreateIISPackage </P>
<P>　　regsvr32 asptxn.dll </P>
<P>　　到这里我就可以用了，不用重启。需要注意的是，上面的命令行如果运行过程中出现报错现象，可以运行多次，或者改换执行顺序，以解决问题。每个环节的错误解决后，一定要重新启动，让设置生效，别怕麻烦，这样其实是节省时间。</P>
<P>&nbsp;</P></BLOCKQUOTE></div>]]></description>
	    <author><![CDATA[CaCell]]></author>
	    <comments>http://zouzhxi.blog.163.com/blog/static/1559251200841911249333</comments>
    <slash:comments>0</slash:comments>
    <guid isPermaLink="true">http://zouzhxi.blog.163.com/blog/static/1559251200841911249333</guid>
    <pubDate>Mon, 19 May 2008 13:12:49 +0800</pubDate>
    <dcterms:modified>2008-05-19T13:12:49+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[国务院公告：5月19日至21日为全国哀悼日]]></title>	
    <link>http://zouzhxi.blog.163.com/blog/static/155925120084191357669</link>
    <description><![CDATA[<div><P style="TEXT-INDENT: 2em">2008-05-18 18:49:29　来源: <A href="http://www.people.com.cn/">人民网</A>(北京)
</P><P style="TEXT-INDENT: 2em">核心提示：国务院18日发布公告宣布，为表达全国各族人民对四川汶川大地震遇难同胞的深切哀悼，国务院决定，2008年5月19日至21日为全国哀悼日。
</P><P style="TEXT-INDENT: 2em">&nbsp;
</P><P style="TEXT-INDENT: 2em"><STRONG>人民网北京5月18日电</STRONG> 据中国政府网报道，国务院今天发布公告宣布，为表达全国各族人民对四川汶川大地震遇难同胞的深切哀悼，国务院决定，2008年5月19日至21日为全国哀悼日。公告全文如下：</P>
<P style="TEXT-INDENT: 2em"><B>国务院公告</B></P>
<P style="TEXT-INDENT: 2em">为表达全国各族人民对四川汶川大地震遇难同胞的深切哀悼，国务院决定，2008年5月19日至21日为全国哀悼日。在此期间，全国和各驻外机构下半旗志哀，停止公共娱乐活动，外交部和我国驻外使领馆设立吊唁簿。5月19日14时28分起，全国人民默哀3分钟，届时汽车、火车、舰船鸣笛，防空警报鸣响。 </P>
<P style="TEXT-INDENT: 2em">&nbsp;</P>
<P style="TEXT-INDENT: 2em"><STRONG>另据环球网5月18日报道</STRONG>&nbsp;&nbsp; 为表达全国各族人民对四川汶川大地震遇难同胞的深切哀悼，国务院18日发布公告，决定2008年5月19日至21日为全国哀悼日。经与国际奥委会协商，北京奥组委决定，在此期间，北京奥运火炬将暂停传递。</P>
<P style="TEXT-INDENT: 2em">为普通百姓设立全国哀悼日在中国极为罕见，外国媒体对此进行了广泛报道，中国人民大学国际关系学院副院长金灿荣称，无论从内政外交上来说，这都是一个值得肯定的决定。复旦大学国际问题研究院常务副院长沈丁立建议，将每年的5月12日定为国家自然灾害日。</P>
<P style="TEXT-INDENT: 2em">国外各大媒体都刊发了哀悼日的报道。美联社的报道题为《中国宣布为地震遇难者哀悼三天》，路透社的报道题为《为3.25万地震死难者哀悼三天》，法新社的报道包括《地震死亡人数上升，中国宣布哀悼》和《奥运火炬为地震哀悼暂停三天》等。</P>
<P style="TEXT-INDENT: 2em">中国人民大学国际关系学院副院长金灿荣回忆说，毛主席和周总理在1976年逝世时，曾经设定过全国哀悼日；另外1999年南联盟使馆被炸，三名驻外人员遇难后，使馆和政府单位也降过半旗，不过这次是为普通百姓设立全国哀悼日。</P>
<P style="TEXT-INDENT: 2em">金灿荣说，为了巨大生命损失而设立哀悼日，对外来说，这是符合国际惯例的做法，表明中国变得越来越正常，更容易被世界接受。对内而言，表明政府更关注民生，体现了“你痛就是我痛”，即老百姓的痛苦也是政府的痛苦，可以凝聚人心，建立了一种中国国民的认同。无论对内对外，为地震遇难者设立全国哀悼日，都是值得肯定的。火炬传递停三天，这也值得肯定。奥运虽然是大事，是人心所向，但在生命损失的惨剧前，奥运应该让路。</P>
<P style="TEXT-INDENT: 2em">复旦大学国际问题研究院常务副院长沈丁立认为，在现代政治中，设立全国哀悼日体现了政府的公共领导能力，显然，中国政府也开始用这种方法引领人民，有利于提高政府在人民心中的可信度。沈丁立建议，应该将每年的5月12日定为国家自然灾害日，每年的这一天进行悼念，并进行地震和其他自然灾害的演习，提高人们的忧患意识，并对在灾害中逝世的人表示悼念。沈丁立欢迎暂停奥运火炬传递的决定，因为“与奥运火炬相比，人们显然更重视生命”。（环球时报记者李宏伟） (本文来源：<A href="http://media.163.com/special/007625CB/rmw.html">人民网</A> )
</P><P style="TEXT-INDENT: 2em"><A href="http://news.163.com/special/00012MS5/sichuan0512.html">http://news.163.com/special/00012MS5/sichuan0512.html</A>
</P><P style="TEXT-INDENT: 2em"><A href="http://news.163.com/special/00012MS5/sichuan0512.html" target=_blank><IMG src="http://cimg20.163.com/cnews/2008/5/12/200805121905434a66e.gif"></A></P></div>]]></description>
	    <author><![CDATA[CaCell]]></author>
	    <comments>http://zouzhxi.blog.163.com/blog/static/155925120084191357669</comments>
    <slash:comments>0</slash:comments>
    <guid isPermaLink="true">http://zouzhxi.blog.163.com/blog/static/155925120084191357669</guid>
    <pubDate>Mon, 19 May 2008 13:03:57 +0800</pubDate>
    <dcterms:modified>2008-05-19T13:03:57+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[引用 广东奥运火炬传递路线揭秘 为什么选择广州、深圳、惠州和汕头？]]></title>	
    <link>http://zouzhxi.blog.163.com/blog/static/15592512008411102747561</link>
    <description><![CDATA[<div><P><EM>引用</EM></P>
<BLOCKQUOTE><A href="http://heky2004.blog.163.com/" target=_blank>欣雨 </A>的 <A href="http://heky2004.blog.163.com/blog/static/4489782008448015645" target=_blank>广东奥运火炬传递路线揭秘 为什么选择广州、深圳、惠州和汕头？</A><BR>
<P align=center><A href="http://img.blog.163.com/photo/wUSqgTl6YfnLjWSu-pi8Rw==/1170935903117000840.jpg" target=_blank><IMG src="http://img.blog.163.com/photo/wUSqgTl6YfnLjWSu-pi8Rw==/1170935903117000840.jpg"></A>&nbsp;</P>
<P>&nbsp;</P>
<P style="TEXT-INDENT: 2em">
<TABLE height=230 cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD vAlign=top scope=col colSpan=2>
<P></P>
<P style="TEXT-INDENT: 2em">奥运圣火将于5月7日来到广东，作为境内传递的第二站，广东选择了广州、深圳、惠州和汕头作为火炬传递城市。而这四个城市，也分别代表了广东的不同特色。</P>
<P style="TEXT-INDENT: 2em">这四个城市结合起来，可以理解为一部简明的广东发展史。奥运圣火穿行广东大地，让世界人民随着火炬与这片历史与现代并存的南粤大地亲密接触。今天，本报深度揭秘奥运火炬在广东四个城市传递的具体路线。</P>
<P style="TEXT-INDENT: 2em">广州炬传递线路充分体现了羊城“云山珠水”的特点</P>
<P style="TEXT-INDENT: 2em">5月7日，奥运火炬将从有“天南第一峰”之称的白云山脚下的白云国际会议中心开始，最后到达天河体育中心。线路全长43公里。出于考虑，火炬手乘船横渡珠江的计划可能取消，取而代之的是火炬手从广州大桥上跑过珠江。</P>
<P style="TEXT-INDENT: 2em">尽管按照时间安排，广州的火炬传递将于5月7日举行，但现在这个时间还是充满变数。</P>
<P style="TEXT-INDENT: 2em">根据国际奥组委的规定，在同一时间内不能有两支火炬同时传递。当火炬在珠峰点燃的时候，并不能有其他火炬同时传递。如果火炬成功在5月7日登顶，当火种灯在珠峰顶上点燃火炬的时刻，正在广州进行传递的火炬会暂停大约半个小时。当珠峰火炬手离开峰顶，广州方面才会继续传递火炬。</P>
<P style="TEXT-INDENT: 2em">&nbsp;</P>
<P style="TEXT-INDENT: 2em"><A href="http://img.blog.163.com/photo/-ENu4TrnjqvNycwdkHym6w==/2865133787938288796.jpg" target=_blank><IMG src="http://img.blog.163.com/photo/-ENu4TrnjqvNycwdkHym6w==/2865133787938288796.jpg"></A></P>
<P style="TEXT-INDENT: 2em">广州站拟定路线</P>
<P style="TEXT-INDENT: 2em">广州白云国际会议中心→云城东路→白云大道→白云山西门→山顶公园→云台花园→麓湖路→广州艺术博物院→环市路→小北路→应元路→吉祥路→中山纪念堂→东风路→解放北路→南越王博物馆→流花路→人民北路→东风西路→康王路→陈家祠→中山六路→中山五路→人民公园→北京路→天字码头→沿江路→海珠广场→海珠桥→南华东路→滨江横路→滨江东路→艺洲路→广州大桥→临江大道→华穗路→金穗路→华夏路→黄埔大道→体育东路→广州天河体育中心东大门→广州天河体育中心南门广场。</P>
<P style="TEXT-INDENT: 2em">深圳的火炬传递路线充分体现了经济特区的特色</P>
<P style="TEXT-INDENT: 2em">圣火在深圳传递的起点是市民中心，终点是深圳市体育场，全长约40公里，火炬将经过深圳的一些地标性建筑、著名的景点及能展现深圳美丽风貌的地方，如深圳改革开放的标志性雕塑拓荒牛、世界之窗、红树林自然保护区、地王大厦、邓小平画像等。曾经，深圳考虑以滑板自行车等方式传递火炬，但基于安全考虑，最后是把跑步传递作为广东省内传递的唯一方式。但5月8日这一天，深圳人还是会为圣火传递营造最佳氛围。在火炬传递的过程中，他们将在沿途设立的四五处欢迎点扭起丰收秧歌、敲响威风锣鼓。</P>
<P style="TEXT-INDENT: 2em">深圳选出的208名火炬手，当中包含了体育教师、环卫工人、小区保安、政府公务员、企业管理者以及在深圳工作的外籍人士等各行业的代表人物。负责第一棒火炬传递的火炬手将是深圳市副市长梁道行，最后一棒火炬手则为深圳市体工队教练员王绮红。</P>
<P style="TEXT-INDENT: 2em">深圳站拟定路线</P>
<P style="TEXT-INDENT: 2em">市民中心广场出发→福中三路→益田路→深南大道→华侨城→南海立交→深圳大学西门→创业路→凯宾斯基酒店→后海大道→滨海大道→滨河路→福田体育公园→宝安立交→宝安南路→深南中路→大剧院广场→上步路→笋岗西路→体育中心西广场。</P>
<P style="TEXT-INDENT: 2em">圣火惠州之旅将凸显惠州“湖中名城”的特色</P>
<P style="TEXT-INDENT: 2em">5月9日，奥运会火炬抵达惠州，传递路线从惠州体育馆广场西门出发，途中将经过西湖，终点是市民乐园。这条凸显惠州“湖中名城”特色的路线，将于近日公布。选择惠州作为广东省内传递的一站，不仅因为惠州是广东的革命老区，是广东下一轮经济腾飞的新热点，也因为惠州有着独特的美景，西湖是国家4A级重点风景名胜旅游区，融自然景观和人文景观为一体，在西湖进行火炬传递可体会到“城中湖，湖中城”的境界。</P>
<P style="TEXT-INDENT: 2em">为了让线路规划尽量做到精益求精，惠州设计了两条线路，两条线路大致相似，只是第一条线路略长了3公里。</P>
<P style="TEXT-INDENT: 2em">惠州站拟定路线（一）</P>
<P style="TEXT-INDENT: 2em">体育馆广场→东江大桥→东江沙公园→水门桥→滨江公园→文笔塔→朝京门→平湖门→花边岭广场→惠州学院→世纪联华→南线立交→红花湖→西湖小北门→慈云亭→惠州大桥→市民乐园。</P>
<P style="TEXT-INDENT: 2em">惠州站拟定路线（二）</P>
<P style="TEXT-INDENT: 2em">体育馆广场→东江大桥→东江沙公园→水门桥→滨江公园→文笔塔→朝京门→平湖门→花边岭广场→惠州学院→红花湖景区大门→西湖小北门→慈云亭→惠州大桥→市民乐园</P>
<P style="TEXT-INDENT: 2em">汕头 五胞胎集体亮相 传递路线以海为特色</P>
<P style="TEXT-INDENT: 2em">5月10日，奥运火炬将在汕头市展开全程约40公里的传递活动。届时，广大市民可在繁华的路段感受火炬传递盛况。当天上午将在龙湖区政府前广场举行起跑仪式。汕头的奥运火炬传递路线将展示汕头市特有的历史文化、自然风光、民族风情和建设成就，凸显改革开放三十年来汕头的巨大变化，向世界展示今日汕头的崭新面貌。</P>
<P style="TEXT-INDENT: 2em">在火炬传递中，汕头还安排了两大亮点。当火炬传递到最后一棒的时候，特别安排了世界跳水名将集体火炬手团体，将由孙淑伟、蔡玉燕、李巧贤、林媛霞、肖燕娟、池美兰六名跳水世界冠军和陈添源、胡恩勇、余卓成三名代表老、中、青三代的跳水教练一起组成集体火炬手，绕人民广场一周并登上广场跳水池的10米跳台上向世人展示火炬。这项安排成为整个圣火传递活动中一个独特的亮点，而作为亮点中的亮点则是其中有两对夫妻，分别是胡恩勇与肖燕娟，孙淑伟与蔡玉燕。</P>
<P style="TEXT-INDENT: 2em">此外，还有一家五胞胎集体亮相。备受社会各界关注的潮阳五胞胎将组成“五娃迎吉祥”，身着专门为他们设计、写有“汕头欢迎您”字样的独特服饰亮相奥运圣火传递现场，成为汕头的“福娃”。这一安排，将是奥运圣火135个城市传递过程中独一无二的精彩亮点。</P>
<P style="TEXT-INDENT: 2em">汕头站拟定路线： 龙湖区政府前广场→迎宾路→金砂东路→衡山路→珠池路→泰山路→火车站广场→海湾大桥→南滨路→市游泳跳水馆→金砂公园→金环路→长平路→时代广场中路→林百欣会展中心广场→华山南路→长平路→嵩山南路，→金砂东路→帝豪酒店→黄山路→长平路→嵩山南路→中山东路→华侨公园门前路→海滨路→石炮台公园→市人大、市政协大院→中国跳水队汕头训练基地露天跳水池→市人民广场</P>
<P style="TEXT-INDENT: 2em" align=center><A href="http://img.blog.163.com/photo/Vq8U52FIoCC2SHIY6sczCg==/569986827839527658.jpg" target=_blank><IMG src="http://img.blog.163.com/photo/Vq8U52FIoCC2SHIY6sczCg==/569986827839527658.jpg"></A></P>
<P style="TEXT-INDENT: 2em" align=center>&nbsp;</P></TD></TR></TBODY></TABLE></P>
<P>&nbsp;</P>
<P>&nbsp;</P></BLOCKQUOTE></div>]]></description>
	    <author><![CDATA[CaCell]]></author>
	    <comments>http://zouzhxi.blog.163.com/blog/static/15592512008411102747561</comments>
    <slash:comments>0</slash:comments>
    <guid isPermaLink="true">http://zouzhxi.blog.163.com/blog/static/15592512008411102747561</guid>
    <pubDate>Sun, 11 May 2008 10:27:47 +0800</pubDate>
    <dcterms:modified>2008-05-11T10:27:47+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[LEFT OUTER JOIN 使用实况 ]]></title>	
    <link>http://zouzhxi.blog.163.com/blog/static/15592512008470214880</link>
    <description><![CDATA[<div><P align=center></P>
<H2>LEFT OUTER JOIN 使用实况 </H2>
<P></P><PRE>作者:<A href="http://www.cnblogs.com/jack-man/"><SPAN style="FONT-SIZE: 14px">Jack.Man</SPAN></A>
来源:http://www.cnblogs.com/jack-man/archive/2008/05/06/1185111.html
</PRE>
<P>定义就不用说了吧！<BR>测试数据　test_table </P><IMG alt=测试数据　test_table src="http://www.cnblogs.com/images/cnblogs_com/jack-man/20080506_01.jpg"><BR>
<P style="MARGIN: 5px; LINE-HEIGHT: 150%"><SPAN><FONT size=+0><CCID_NOBR></CCID_NOBR>
<TABLE style="BORDER-RIGHT: rgb(255,0,0) 1px solid; BORDER-TOP: rgb(255,0,0) 1px solid; BORDER-LEFT: rgb(255,0,0) 1px solid; BORDER-BOTTOM: rgb(255,0,0) 1px solid" cellSpacing=0 borderColorDark=#ffffff cellPadding=2 align=center borderColorLight=#000000>
<TBODY>
<TR>
<TD style="FONT-SIZE: 9pt" bgColor=#f0f0f0><PRE><CCID_CODE></CCID_CODE><P style="MARGIN: 5px; LINE-HEIGHT: 150%">
create table test_table
(u_id int,u_name varchar(20))
insert test_table select 1,'a1'
union all select 2,'b2'
union all select 3,'c3';
</P></PRE></TD></TR></TBODY></TABLE></FONT></SPAN></P>
<P>测试数据　test_table_link</P><IMG alt=测试数据　test_table_link src="http://www.cnblogs.com/images/cnblogs_com/jack-man/20080506_02.jpg"><BR>
<P style="MARGIN: 5px; LINE-HEIGHT: 150%"><SPAN><FONT size=+0><CCID_NOBR></CCID_NOBR>
<TABLE style="BORDER-RIGHT: rgb(255,0,0) 1px solid; BORDER-TOP: rgb(255,0,0) 1px solid; BORDER-LEFT: rgb(255,0,0) 1px solid; BORDER-BOTTOM: rgb(255,0,0) 1px solid" cellSpacing=0 borderColorDark=#ffffff cellPadding=2 align=center borderColorLight=#000000>
<TBODY>
<TR>
<TD style="FONT-SIZE: 9pt" bgColor=#f0f0f0><PRE><CCID_CODE></CCID_CODE><P style="MARGIN: 5px; LINE-HEIGHT: 150%">
create table test_table_link
(u_id int,u_other varchar(50))
insert test_table_link select 1,'each month'
union all select 1,'each day'
union all select 1,'each year'
union all select 55,'each day'
union all select 55,'each year'
union all select 3,'each day'
union all select 3,'each year'
union all select 88,'each day'
union all select 88,'each month';
</P></PRE></TD></TR></TBODY></TABLE></FONT></SPAN></P>
<P>结果</P><IMG alt=结果 src="http://www.cnblogs.com/images/cnblogs_com/jack-man/20080506_03.jpg"><BR>
<P style="MARGIN: 5px; LINE-HEIGHT: 150%"><SPAN><FONT size=+0><CCID_NOBR></CCID_NOBR>
<TABLE style="BORDER-RIGHT: rgb(255,0,0) 1px solid; BORDER-TOP: rgb(255,0,0) 1px solid; BORDER-LEFT: rgb(255,0,0) 1px solid; BORDER-BOTTOM: rgb(255,0,0) 1px solid" cellSpacing=0 borderColorDark=#ffffff cellPadding=2 align=center borderColorLight=#000000>
<TBODY>
<TR>
<TD style="FONT-SIZE: 9pt" bgColor=#f0f0f0><PRE><CCID_CODE></CCID_CODE><P style="MARGIN: 5px; LINE-HEIGHT: 150%">
select a.u_id,a.u_name,b.u_other
from test_table a LEFT OUTER JOIN test_table_link b
ON  a.u_id=b.u_id;
</P></PRE></TD></TR></TBODY></TABLE></FONT></SPAN></P>
<P>测试环境为sql server 2005</P>
<P>原本以为只是显示test_table中的每３条记录，实际上不是这样的(为什么多了记录了呢？)，只要第一个表（test_table）中有，而第二个表与之相关联得上的都会显示的，但是一定要在第一个表（test_table）中存在，如第二个表(test_table_link)中的uid为55,88的不会出现，若第二个表没有找到与第一个表相匹配的那当然为null了！right outer join就与之相反了． </P></div>]]></description>
	    <author><![CDATA[CaCell]]></author>
	    <comments>http://zouzhxi.blog.163.com/blog/static/15592512008470214880</comments>
    <slash:comments>1</slash:comments>
    <guid isPermaLink="true">http://zouzhxi.blog.163.com/blog/static/15592512008470214880</guid>
    <pubDate>Wed, 7 May 2008 12:21:04 +0800</pubDate>
    <dcterms:modified>2008-05-07T12:21:45+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[蛙蛙推荐：多进程多线程访问数据库]]></title>	
    <link>http://zouzhxi.blog.163.com/blog/static/1559251200847114339385</link>
    <description><![CDATA[<div><p></p><h2>蛙蛙推荐：多进程多线程访问数据库 </h2>
<p>
</p><pre>
作者:<a href="http://www.cnblogs.com/onlytiancai/">蛙蛙池塘</a>
来源:http://www.cnblogs.com/onlytiancai/
地址:http://www.cnblogs.com/onlytiancai/archive/2008/04/19/1161748.html
</pre>

<div align="left">
<p>
如何让多进程多线程访问数据库，而不会选择相同的数据，这在设计分布式程序的时候经常用到，多台机器的多个进程，每个进程都有多个线程，每个线程要从数据库里取数据来处理，要实现不能漏取数据，也不能重复取数据，这里给出答案</p><p>

创建一个数据表，如下，一个自增列，一个表示rss链接地址</p>
<p style="margin: 5px; line-height: 150%">
<table style="border: 1px solid rgb(255,0,0);" cellspacing="0" bordercolordark="#ffffff" cellpadding="2" align="center" bordercolorlight="#000000">
<tbody><tr><td style="font-size: 9pt" bgcolor="#f0f0f0">
<pre>
CREATE TABLE [dbo].[Rss_RssSources](
 [SourceId] [int] IDENTITY(1,1) NOT NULL,
 [Link] [varchar](1024) NOT NULL
) ON [PRIMARY] 
</pre>
</td></tr></tbody></table></p>
<p>先放1w条数据</p>
<p style="margin: 5px; line-height: 150%">
<table style="border: 1px solid rgb(255,0,0);" cellspacing="0" bordercolordark="#ffffff" cellpadding="2" align="center" bordercolorlight="#000000">
<tbody><tr><td style="font-size: 9pt" bgcolor="#f0f0f0">
<pre>
declare @i int
set @i = 1
while @i <10000  begin   select @i = @i +1   insert into [Rss_RssSources] values(newid())  end   </pre>
</td></tr></tbody></table></p>
<p>再创建一个锁表，一个字段表示是否已经锁定的资源，另一个表示已经读取的rss源的最大id</p>
<p style="margin: 5px; line-height: 150%">
<table style="border: 1px solid rgb(255,0,0);" cellspacing="0" bordercolordark="#ffffff" cellpadding="2" align="center" bordercolorlight="#000000">
<tbody><tr><td style="font-size: 9pt" bgcolor="#f0f0f0">
<pre>
create table Rss_RssSourceLock
(
  IsLock bit,
  MaxSourceId int
)
</pre>
</td></tr></tbody></table></p>
<p>初始化数据</p>
<p style="margin: 5px; line-height: 150%">
<table style="border: 1px solid rgb(255,0,0);" cellspacing="0" bordercolordark="#ffffff" cellpadding="2" align="center" bordercolorlight="#000000">
<tbody><tr><td style="font-size: 9pt" bgcolor="#f0f0f0">
<pre>
insert into Rss_RssSourceLock values (0,0) 
</pre>
</td></tr></tbody></table></p>
<p>下面我们要设计一个存储过程，让这个存储过程每次返回10个rss源，知道返回所有的rss源，要求无遗漏，无重复返回。如下</p>
<p style="margin: 5px; line-height: 150%">
<table style="border: 1px solid rgb(255,0,0);" cellspacing="0" bordercolordark="#ffffff" cellpadding="2" align="center" bordercolorlight="#000000">
<tbody><tr><td style="font-size: 9pt" bgcolor="#f0f0f0">
<pre>
CREATE PROCEDURE [dbo].[USP_GetRssSources]
AS
BEGIN
if exists(select * from Rss_RssSourceLock with(READPAST) where IsLock = 0)
begin
 declare @select_count int
 begin tran
  update Rss_RssSourceLock set IsLock = 1

  if object_id('tempdb..#t') is not null  
   drop table #t

  select top 10 a.* into #t from [Rss_RssSources] as a
  inner join Rss_RssSourceLock as b
  on a.SourceId > b.MaxSourceId
  order by a.[SourceId]

  select @select_count = count(*) from #t

  update Rss_RssSourceLock set IsLock = 0,MaxSourceId = MaxSourceId + @select_count

  select * from #t
 commit tran
end
END
</pre>
</td></tr></tbody></table></p>
<p>
</p><pre>
1、如果锁表里显示没有进程正在读取rss源（IsLock = 0），那么就返回从最大的rss源id往后的10个rss源，否则返回空。
2、用with(READPAST)表示忽略锁住的行，如果另一个进程正在执行update Rss_RssSourceLock的语句，并且在事务提交前，update语句会锁住这些要更新的行，而Rss_RssSourceLock表就一行数据，这时候select Rss_RssSourceLock表并且忽略被锁的行肯定是没数据的，所以本次存储过程执行会返回空。
3、begin tran和commit tran保证了即使本次存储过程出错，也不会让Rss_RssSourceLock表处于IsLock = 1的脏数据状态，如果处于这种状态，后面的进程执行存储过程就永远也返回不了数据了。
4、因为有时候一次选取的记录可能不够10条，所以这里用了个临时表来暂存记录，再算出来选取的条数，最后更新Rss_RssSourceLock表的MaxSourceId字段。但用临时表肯定会增加数据库的压力，这里不知道用表变量是不是会改善性能，暂时先这样了。
5、应用里调用这个存储过程，如果返回了数据，就进行处理，如果没返回数据，就sleep几秒才执行，直到返回数据。

我测试了一下，应该没问题，俺是数据库菜鸟，有高手的话给指点指点有没有隐患和bug
相关链接：
关于sqlserver锁的一点儿讨论
http://topic.csdn.net/t/20061127/12/5187714.html#
</pre>
</p></div></div>]]></description>
	    <author><![CDATA[CaCell]]></author>
	    <comments>http://zouzhxi.blog.163.com/blog/static/1559251200847114339385</comments>
    <slash:comments>3</slash:comments>
    <guid isPermaLink="true">http://zouzhxi.blog.163.com/blog/static/1559251200847114339385</guid>
    <pubDate>Wed, 7 May 2008 11:43:39 +0800</pubDate>
    <dcterms:modified>2008-05-07T11:45:14+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[高考作文强句]]></title>	
    <link>http://zouzhxi.blog.163.com/blog/static/155925120083199597302</link>
    <description><![CDATA[<div><WBR><FONT style="FONT-SIZE: x-small; LINE-HEIGHT: 1.3em">1、尽管司马迁多次遭受宫刑，但他忍受住一次又一次的痛苦，还是以顽强的毅力写出了伟大的《史记》。<BR>【评论：一次又一次？司马爷爷你那里难道是春风吹又生？】<BR><BR>2、我的爸爸就像亲人一样爱我。<BR>【评论：敢情您老是您爸爸从垃圾箱里捡来的？】<BR><BR>3、太阳离我们越来越近，像一个金黄的油饼。<BR>【评论：这位同学……你是木吃早饭就来考试的是伐？可怜的～～MOMO】<BR><BR>4、周总理的愿望是国家的富强独立，在他心里只有四个大字：为人民服务！<BR>【评论：也许你的语文老师能容忍你，但你的数学老师不会原谅你！】<BR><BR>5、我希望有一条健康的双腿，一个智慧的大脑，……<BR>【评论：同4】<BR><BR>6、有一种自卑叫自信，有一种跌倒叫爬起。<BR>【评论：这位同学是新时代的苏格拉底】<BR><BR>7、没有自尊的脖子，无法支撑自信的头颅。<BR>【评论：我想知道怎样的脖子叫做“有自尊的脖子”！】<BR><BR>8、没有背景，就奔前景。<BR>【评论：乍一看不知道在说什么，仔细一想似乎有点针砭时弊的意思……但再想又不知道他<BR>确切要说什么……难道只是为了押韵？！】<BR><BR>9、眼睛为什么长在两边，因为它是用来向前看的。<BR>【评论：同学你的逻辑是超越我的理性范围之外的……】<BR><BR>10、人生就像一杯白开水，平平淡淡的；但又像一杯加了糖的白开水，甜甜的；也像一杯加了盐的白开水，咸咸的。<BR>【评论：这……还是白开水么？！】<BR><BR>11、马瘦毛长蹄子肥，儿子偷爹不算贼；瞎大爷和瞎大妈过了半辈子，谁也没见过谁。<BR>【评论：同学，您是郭德钢老师的儿子伐？】<BR><BR>12、孟德斯鸠出身贵族世家，虽然从小过着安逸的生活，但他看着天空变化的云，突然做了一个震惊历史的决定，――那就是投身到资产阶级的革命洪流中去。<BR>【评论：原来孟老师夜观天象忽然大彻大悟……】<BR><BR>13、人命诚可贵，爱情价更高；若为生死故，两者皆可抛。<BR>【评论：8HD啊！你不能因为人家裴多菲过了50年的著作权保护期就这样糟尽人家……】<BR><BR>14、俗话说：人有多大胆，地有多大产。土地如此，人何以堪？所以我们更应对未来怀有远大的前景。<BR>【评论：我无语了……这位同学你到底要说什么？！】<BR><BR>15、进入高三，我就过上了“起的比鸡早，睡得比狗晚，吃的比猪差，干得比牛多”的日子。虽然我吃的比猪好多了，但我干的确实比牛还多。此刻，我的愿景就是……<BR>【评论：可怜的孩子……同情的抚摸之，对高玉宝：你看到了伐！周扒皮对你们那其实是很有人文精神的！】<BR><BR>16、我最大的毛病就是有骂人的习惯。虽说五讲四美要遵守，但恐怕只有坐在房顶上骂上三小时不带重样的才能解解我心头的怨气。写到这里，我手心发，因为我怨的是这张考卷，因为它决定了我的未来和前景。就凭这不足半米的考卷和一些墨水，就决断我十二年的求学生涯，我不服。但我犯不着跟分数过不去。<BR>【评论：孩子……你是不是已经准备好出国的后路才来考试玩的？】<BR><BR>17、上帝给了我们七情六欲，我们却把它们变成了色情和暴力。<BR>【评论：深刻！】<BR><BR>18、我的愿望是考上一所好大学，找到一个好工作，这样以后才有能力让我的儿子也考上一所好大学，找到一个好工作。<BR>【评论：为什么我想到了政治书里那个记者采访放羊娃的那段？！】<BR><BR>19、我的很多同学为了能考上军校或警校，不惜把眼睛给做了。<BR>【评论：做？！抖……怎么就给做了？！】<BR><BR>20、周总理站在十里长街对天哀叹：“出师未捷身先死，长使英雄泪满襟。”他对祖国美好未来的愿望使亿万人民为之失声痛哭。<BR>【评论：十里长街……？！诈尸啊啊啊啊啊啊！！！】<BR><BR>21、泰戈尔说：黑夜给了我黑色的眼睛，我却用它来寻找光明。<BR>【评论：你信不信顾城会拿着斧头半夜来找你？】<BR><BR>22、汨罗江边，项羽手持利剑于颈间，他高呼……<BR>【评论：他高呼：屈原小亲亲你怎么那么早就舍下我去了啊！！！】<BR><BR>23、醉翁深知：不应有恨，何时长向别时圆……<BR>【评论：苏轼TO欧阳修：大家熟归熟，你这样我一样告你剽窃！】<BR><BR>24、在桃花源过着田园生活的陶渊明写下了“疏影横斜水清浅，暗香浮动月黄昏”的名句……<BR>【评论：好吧……我承认……其实我也不敢保证林逋老先生就一定不是陶渊明的邻居。】<BR><BR>25、当俞平伯为钟子期摔琴之时，他所寻找的是高山流水，琴声是他的愿景。<BR>【评论：鉴定为BL穿越文！】<BR><BR>26、韩愈跟着刘邦去打仗，一天，……<BR>【评论：又鉴定出一篇为BL穿越文！】<BR><BR>27、居里夫人发明了鱼镭，她的愿望实现了……<BR>【评论：居里夫人您死得真冤枉……谁晓得这鱼雷它竟然也是有辐射的！】<BR><BR>28、司马迁在受到残酷的宫刑之后，忍辱苟活，因为他知道“不孝有三，无后为大”，所以……<BR>【评论：所以……怎么样？！难道找个小攻搞男男生子么？】<BR><BR>29、司马迁在遭受宫刑之后，不得不忍受断腿之苦，……<BR>【评论：我求求你们了！司马爷爷“一次次”的受了宫刑已经够惨的了！你们别再虐他了！】<BR><BR>30、司马迁在被施行腐刑之后，不顾身体的腐烂，写出了千古绝唱《史记》……<BR>【评论：令人发指啊！我已经彻底无语了……】<BR><BR>31、我看到司马迁在遭受宫刑之后的伟大成就和伟大愿望，不由感叹：三百六十行，行行出状元。<BR>【评论：干笑，是啊！敢情太监这行也能出状元！】<BR><BR>32、一代男儿司马迁自愿接受宫刑，就是因为他心中的伟大愿望――那就是大唐还没有一部自己的史书，于是他忍辱负重为大唐完成了《史记》。<BR>【评论：掀桌！司马迁究竟招谁惹谁了？都被折腾成这样了居然你们还不肯让他得到解脱！还一直把他从汉朝折腾到唐朝】</FONT><WBR><BR><BR>来源:http://mcs.szu.edu.cn/Article/37835<BR><A false" href="http://mcs.szu.edu.cn/" target=_blank link="http://mcs.szu.edu.cn">深圳大学荔园空间</A><WBR>-<A false" href="http://mcs.szu.edu.cn/SubListHome/117440512/P1" target=_blank link="http://mcs.szu.edu.cn/SubListHome/117440512/P1">休闲娱乐</A><WBR>-<A false" href="http://mcs.szu.edu.cn/SubListHome/117637120/P1" target=_blank link="http://mcs.szu.edu.cn/SubListHome/117637120/P1">奇趣生活</A><WBR>- 主题:<A false" href="http://mcs.szu.edu.cn/Sub/41" target=_blank link="http://mcs.szu.edu.cn/Sub/41">笑林广记</A><WBR>-<A false" href="http://mcs.szu.edu.cn/Article/37835" target=_blank link="http://mcs.szu.edu.cn/Article/37835">高考作文强句</A></div>]]></description>
	    <author><![CDATA[CaCell]]></author>
	    <comments>http://zouzhxi.blog.163.com/blog/static/155925120083199597302</comments>
    <slash:comments>1</slash:comments>
    <guid isPermaLink="true">http://zouzhxi.blog.163.com/blog/static/155925120083199597302</guid>
    <pubDate>Sat, 19 Apr 2008 09:59:07 +0800</pubDate>
    <dcterms:modified>2008-04-19T09:59:07+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[C#正则表达式整理备忘]]></title>	
    <link>http://zouzhxi.blog.163.com/blog/static/1559251200837104323540</link>
    <description><![CDATA[<div><P></P>
<H1>C#正则表达式整理备忘</H1>
<P></P><PRE>来源:中国IT实验室收集整理
作者:佚名

</PRE>
<P>有一段时间，正则表达式学习很火热很潮流，当时在CSDN一天就能看到好几个正则表达式的帖子，那段时间借助论坛以及Wrox Press出版的《C#字符串和正则表达式参考手册》学习了一些基础的知识，同时也为我在CSDN大概赚了1000分，今天想起来，去找《C#字符串和正则表达式参考手册》时，已经不知所踪了。现在用到正则的时候也比较少，把以前的笔记等整理一下，以志不忘。 </P>
<P>（1）“@”符号符下两ows表研究室的火热，当晨在“@”虽然并非C#正则表达式的“成员”，但是它经常与C#正则表达式出双入对。“@”表示，跟在它后面的字符串是个“逐字字符串”，不是很好理解，举个例子，以下两个声明是等效的：string x="D：\\My Huang\\My Doc"；string y = @"D：\My Huang\My Doc"；事实上，如果按如下声明，C#将会报错，因为“\”在C#中用于实现转义，如“\n”换行：string x = "D：\My Huang\My Doc"； </P>
<P>（2）基本的语法字符。 </P>
<P>\d 0-9的数字\D \d的补集（以所以字符为全集，下同），即所有非数字的字符\w 单词字符，指大小写字母、0-9的数字、下划线\W \w的补集\s 空白字符，包括换行符\n、回车符\r、制表符\t、垂直制表符\v、换页符\f \S \s的补集。 除换行符\n外的任意字符[…] 匹配[]内所列出的所有字符[^…] 匹配非[]内所列出的字符下面提供一些简单的示例：</P>
<P style="MARGIN: 5px; LINE-HEIGHT: 150%"><SPAN><FONT size=+0><CCID_NOBR></CCID_NOBR>
<TABLE style="BORDER-RIGHT: rgb(255,0,0) 1px solid; BORDER-TOP: rgb(255,0,0) 1px solid; BORDER-LEFT: rgb(255,0,0) 1px solid; BORDER-BOTTOM: rgb(255,0,0) 1px solid" cellSpacing=0 borderColorDark=#ffffff cellPadding=2 align=center borderColorLight=#000000>
<TBODY>
<TR>
<TD style="FONT-SIZE: 9pt" bgColor=#f0f0f0><PRE><CCID_CODE></CCID_CODE><P style="MARGIN: 5px; LINE-HEIGHT: 150%">
string i = "\n";
string m = "3";
Regex r = new Regex(@"\D");
//同Regex r = new Regex("\\D");
//r.IsMatch(i)结果：true
//r.IsMatch(m)结果：false

string i = "%";
string m = "3";
Regex r = new Regex("[a-z0-9]");
//匹配小写字母或数字字符
//r.IsMatch(i)结果：false
//r.IsMatch(m)结果：true
</P></PRE></TD></TR></TBODY></TABLE></FONT></SPAN></P>
<P>（3）定位字符“定位字符”所代表的是一个虚的字符，它代表一个位置，你也可以直观地认为“定位字符”所代表的是某个字符与字符间的那个微小间隙。 </P>
<P>^ 表示其后的字符必须位于字符串的开始处$ 表示其前面的字符必须位于字符串的结束处\b 匹配一个单词的边界\B 匹配一个非单词的边界另外，还包括：\A 前面的字符必须位于字符处的开始处，\z 前面的字符必须位于字符串的结束处，\Z 前面的字符必须位于字符串的结束处，或者位于换行符前下面提供一些简单的示例：</P>
<P style="MARGIN: 5px; LINE-HEIGHT: 150%"><SPAN><FONT size=+0><CCID_NOBR></CCID_NOBR>
<TABLE style="BORDER-RIGHT: rgb(255,0,0) 1px solid; BORDER-TOP: rgb(255,0,0) 1px solid; BORDER-LEFT: rgb(255,0,0) 1px solid; BORDER-BOTTOM: rgb(255,0,0) 1px solid" cellSpacing=0 borderColorDark=#ffffff cellPadding=2 align=center borderColorLight=#000000>
<TBODY>
<TR>
<TD style="FONT-SIZE: 9pt" bgColor=#f0f0f0><PRE><CCID_CODE></CCID_CODE><P style="MARGIN: 5px; LINE-HEIGHT: 150%">
 string i = "Live for nothing,die for something";
Regex r1 = new Regex("^Live for nothing,die for something$");
//r1.IsMatch(i) true
Regex r2 = new Regex("^Live for nothing,die for some$");
//r2.IsMatch(i) false
Regex r3 = new Regex("^Live for nothing,die for some");
//r3.IsMatch(i) true

string i = @"Live for nothing,
die for something";//多行
Regex r1 = new Regex("^Live for nothing,die for something$");
Console.WriteLine("r1 match count:" + r1.Matches(i).Count);//0
Regex r2 = new Regex("^Live for nothing,die for something$", RegexOptions.Multiline);
Console.WriteLine("r2 match count:" + r2.Matches(i).Count);//0
Regex r3 = new Regex("^Live for nothing,\r\ndie for something$");
Console.WriteLine("r3 match count:" + r3.Matches(i).Count);//1
Regex r4 = new Regex("^Live for nothing,$");
Console.WriteLine("r4 match count:" + r4.Matches(i).Count);//0
Regex r5 = new Regex("^Live for nothing,$", RegexOptions.Multiline);
Console.WriteLine("r5 match count:" + r5.Matches(i).Count);//0
Regex r6 = new Regex("^Live for nothing,\r\n$");
Console.WriteLine("r6 match count:" + r6.Matches(i).Count);//0
Regex r7 = new Regex("^Live for nothing,\r\n$", RegexOptions.Multiline);
Console.WriteLine("r7 match count:" + r7.Matches(i).Count);//0
Regex r8 = new Regex("^Live for nothing,\r$");
Console.WriteLine("r8 match count:" + r8.Matches(i).Count);//0
Regex r9 = new Regex("^Live for nothing,\r$", RegexOptions.Multiline);
Console.WriteLine("r9 match count:" + r9.Matches(i).Count);//1
Regex r10 = new Regex("^die for something$");
Console.WriteLine("r10 match count:" + r10.Matches(i).Count);//0
Regex r11 = new Regex("^die for something$", RegexOptions.Multiline);
Console.WriteLine("r11 match count:" + r11.Matches(i).Count);//1
Regex r12 = new Regex("^");
Console.WriteLine("r12 match count:" + r12.Matches(i).Count);//1
Regex r13 = new Regex("$");
Console.WriteLine("r13 match count:" + r13.Matches(i).Count);//1
Regex r14 = new Regex("^", RegexOptions.Multiline);
Console.WriteLine("r14 match count:" + r14.Matches(i).Count);//2
Regex r15 = new Regex("$", RegexOptions.Multiline);
Console.WriteLine("r15 match count:" + r15.Matches(i).Count);//2
Regex r16 = new Regex("^Live for nothing,\r$\n^die for something$", RegexOptions.Multiline);
Console.WriteLine("r16 match count:" + r16.Matches(i).Count);//1
//对于一个多行字符串，在设置了Multiline选项之后，^和$将出现多次匹配。

string i = "Live for nothing,die for something";
string m = "Live for nothing,die for some thing";
Regex r1 = new Regex(@"\bthing\b");
Console.WriteLine("r1 match count:" + r1.Matches(i).Count);//0
Regex r2 = new Regex(@"thing\b");
Console.WriteLine("r2 match count:" + r2.Matches(i).Count);//2
Regex r3 = new Regex(@"\bthing\b");
Console.WriteLine("r3 match count:" + r3.Matches(m).Count);//1
Regex r4 = new Regex(@"\bfor something\b");
Console.WriteLine("r4 match count:" + r4.Matches(i).Count);//1
//\b通常用于约束一个完整的单词
</P></PRE></TD></TR></TBODY></TABLE></FONT></SPAN></P>
<P>（4）重复描述字符“重复描述字符”是体现C#正则表达式“很好很强大”的地方之一：{n} 匹配前面的字符n次{n，} 匹配前面的字符n次或多于n次{n，m} 匹配前面的字符n到m次？ 匹配前面的字符0或1次+ 匹配前面的字符1次或多于1次* 匹配前面的字符0次或式于0次以下提供一些简单的示例：</P>
<P style="MARGIN: 5px; LINE-HEIGHT: 150%"><SPAN><FONT size=+0><CCID_NOBR></CCID_NOBR>
<TABLE style="BORDER-RIGHT: rgb(255,0,0) 1px solid; BORDER-TOP: rgb(255,0,0) 1px solid; BORDER-LEFT: rgb(255,0,0) 1px solid; BORDER-BOTTOM: rgb(255,0,0) 1px solid" cellSpacing=0 borderColorDark=#ffffff cellPadding=2 align=center borderColorLight=#000000>
<TBODY>
<TR>
<TD style="FONT-SIZE: 9pt" bgColor=#f0f0f0><PRE><CCID_CODE></CCID_CODE><P style="MARGIN: 5px; LINE-HEIGHT: 150%">
 string x = "1024";
string y = "+1024";
string z = "1,024";
string a = "1";
string b="-1024";
string c = "10000";
Regex r = new Regex(@"^\+?[1-9],?\d{3}$");
Console.WriteLine("x match count:" + r.Matches(x).Count);//1
Console.WriteLine("y match count:" + r.Matches(y).Count);//1
Console.WriteLine("z match count:" + r.Matches(z).Count);//1
Console.WriteLine("a match count:" + r.Matches(a).Count);//0
Console.WriteLine("b match count:" + r.Matches(b).Count);//0
Console.WriteLine("c match count:" + r.Matches(c).Count);//0
//匹配1000到9999的整数。
</P></PRE></TD></TR></TBODY></TABLE></FONT></SPAN></P>
<P>（5）择一匹配C#正则表达式中的 （|）<BR>符号似乎没有一个专门的称谓，姑且称之为“择一匹配”吧。事实上，像[a-z]也是一种择一匹配，只不过它只能匹配单个字符，而（|）则提供了更大的范围，（ab|xy）表示匹配ab或匹配xy.注意“|”与“（）”在此是一个整体。下面提供一些简单的示例：</P>
<P style="MARGIN: 5px; LINE-HEIGHT: 150%"><SPAN><FONT size=+0><CCID_NOBR></CCID_NOBR>
<TABLE style="BORDER-RIGHT: rgb(255,0,0) 1px solid; BORDER-TOP: rgb(255,0,0) 1px solid; BORDER-LEFT: rgb(255,0,0) 1px solid; BORDER-BOTTOM: rgb(255,0,0) 1px solid" cellSpacing=0 borderColorDark=#ffffff cellPadding=2 align=center borderColorLight=#000000>
<TBODY>
<TR>
<TD style="FONT-SIZE: 9pt" bgColor=#f0f0f0><PRE><CCID_CODE></CCID_CODE><P style="MARGIN: 5px; LINE-HEIGHT: 150%">
 string x = "0";
string y = "0.23";
string z = "100";
string a = "100.01";
string b = "9.9";
string c = "99.9";
string d = "99.";
string e = "00.1";
Regex r = new Regex(@"^\+?((100(.0+)*)|([1-9]?[0-9])(\.\d+)*)$");
Console.WriteLine("x match count:" + r.Matches(x).Count);//1
Console.WriteLine("y match count:" + r.Matches(y).Count);//1
Console.WriteLine("z match count:" + r.Matches(z).Count);//1
Console.WriteLine("a match count:" + r.Matches(a).Count);//0
Console.WriteLine("b match count:" + r.Matches(b).Count);//1
Console.WriteLine("c match count:" + r.Matches(c).Count);//1
Console.WriteLine("d match count:" + r.Matches(d).Count);//0
Console.WriteLine("e match count:" + r.Matches(e).Count);//0
//匹配0到100的数。最外层的括号内包含两部分“(100(.0+)*)”，“([1-9]?[0-9])(\.\d+)*”，
//这两部分是“OR”的关系，即正则表达式引擎会先尝试匹配100，如果失败，则尝试匹配后一个表达式（表示[0,100)范围中的数字）。
</P></PRE></TD></TR></TBODY></TABLE></FONT></SPAN></P>
<P>（6）特殊字符的匹配下面提供一些简单的示例：</P>
<P style="MARGIN: 5px; LINE-HEIGHT: 150%"><SPAN><FONT size=+0><CCID_NOBR></CCID_NOBR>
<TABLE style="BORDER-RIGHT: rgb(255,0,0) 1px solid; BORDER-TOP: rgb(255,0,0) 1px solid; BORDER-LEFT: rgb(255,0,0) 1px solid; BORDER-BOTTOM: rgb(255,0,0) 1px solid" cellSpacing=0 borderColorDark=#ffffff cellPadding=2 align=center borderColorLight=#000000>
<TBODY>
<TR>
<TD style="FONT-SIZE: 9pt" bgColor=#f0f0f0><PRE><CCID_CODE></CCID_CODE><P style="MARGIN: 5px; LINE-HEIGHT: 150%">
 string x = "\\";
Regex r1 = new Regex("^\\\\$");
Console.WriteLine("r1 match count:" + r1.Matches(x).Count);//1
Regex r2 = new Regex(@"^\\$");
Console.WriteLine("r2 match count:" + r2.Matches(x).Count);//1
Regex r3 = new Regex("^\\$");
Console.WriteLine("r3 match count:" + r3.Matches(x).Count);//0
//匹配“\”

string x = "\"";
Regex r1 = new Regex("^\"$");
Console.WriteLine("r1 match count:" + r1.Matches(x).Count);//1
Regex r2 = new Regex(@"^""$");
Console.WriteLine("r2 match count:" + r2.Matches(x).Count);//1
//匹配双引号
</P></PRE></TD></TR></TBODY></TABLE></FONT></SPAN></P>
<P>（7）组与非捕获组以下提供一些简单的示例：</P>
<P style="MARGIN: 5px; LINE-HEIGHT: 150%"><SPAN><FONT size=+0><CCID_NOBR></CCID_NOBR>
<TABLE style="BORDER-RIGHT: rgb(255,0,0) 1px solid; BORDER-TOP: rgb(255,0,0) 1px solid; BORDER-LEFT: rgb(255,0,0) 1px solid; BORDER-BOTTOM: rgb(255,0,0) 1px solid" cellSpacing=0 borderColorDark=#ffffff cellPadding=2 align=center borderColorLight=#000000>
<TBODY>
<TR>
<TD style="FONT-SIZE: 9pt" bgColor=#f0f0f0><PRE><CCID_CODE></CCID_CODE><P style="MARGIN: 5px; LINE-HEIGHT: 150%">
string x = "Live for nothing,die for something";
string y = "Live for nothing,die for somebody";
Regex r = new Regex(@"^Live ([a-z]{3}) no([a-z]{5}),die \1 some\2$");
Console.WriteLine("x match count:" + r.Matches(x).Count);//1
Console.WriteLine("y match count:" + r.Matches(y).Count);//0
//正则表达式引擎会记忆“()”中匹配到的内容，作为一个“组”，并且可以通过索引的方式进行引用。
//表达式中的“\1”，用于反向引用表达式中出现的第一个组，即粗体标识的第一个括号内容，“\2”则依此类推。

string x = "Live for nothing,die for something";
Regex r = new Regex(@"^Live for no([a-z]{5}),die for some\1$");
if (r.IsMatch(x))
{
    Console.WriteLine("group1 value:" + r.Match(x).Groups[1].Value);//输出：thing
}
//获取组中的内容。注意，此处是Groups[1]，因为Groups[0]是整个匹配的字符串，即整个变量x的内容。

string x = "Live for nothing,die for something";
Regex r = new Regex(@"^Live for no(?<G1>[a-z]{5}),die for some\1$");
if (r.IsMatch(x))
{
    Console.WriteLine("group1 value:" + r.Match(x).Groups["g1"].Value);//输出：thing
}
//可根据组名进行索引。使用以下格式为标识一个组的名称(?<GROUPNAME>…)。

string x = "Live for nothing nothing";
Regex r = new Regex(@"([a-z]+) \1");
if (r.IsMatch(x))
{
    x = r.Replace(x, "$1");
    Console.WriteLine("var x:" + x);//输出：Live for nothing
}
//删除原字符串中重复出现的“nothing”。
//在表达式之外，使用“$1”来引用第一个组，下面则是通过组名来引用：
string x = "Live for nothing nothing";
Regex r = new Regex(@"(?<G1>[a-z]+) \1");
if (r.IsMatch(x))
{
    x = r.Replace(x, "${g1}");
    Console.WriteLine("var x:" + x);//输出：Live for nothing
}

string x = "Live for nothing";
Regex r = new Regex(@"^Live for no(?:[a-z]{5})$");
if (r.IsMatch(x))
{
    Console.WriteLine("group1 value:" + r.Match(x).Groups[1].Value);//输出：(空)
}
//在组前加上“?:”表示这是个“非捕获组”，即引擎将不保存该组的内容。
</P></PRE></TD></TR></TBODY></TABLE></FONT></SPAN></P>
<P>（8）贪婪与非贪婪<BR>正则表达式的引擎是贪婪，只要模式允许，它将匹配尽可能多的字符。通过在“重复描述字符”（*,+）后面添加“?”，可以将匹配模式改成非贪婪。请看以下示例：</P>
<P style="MARGIN: 5px; LINE-HEIGHT: 150%"><SPAN><FONT size=+0><CCID_NOBR></CCID_NOBR>
<TABLE style="BORDER-RIGHT: rgb(255,0,0) 1px solid; BORDER-TOP: rgb(255,0,0) 1px solid; BORDER-LEFT: rgb(255,0,0) 1px solid; BORDER-BOTTOM: rgb(255,0,0) 1px solid" cellSpacing=0 borderColorDark=#ffffff cellPadding=2 align=center borderColorLight=#000000>
<TBODY>
<TR>
<TD style="FONT-SIZE: 9pt" bgColor=#f0f0f0><PRE><CCID_CODE></CCID_CODE><P style="MARGIN: 5px; LINE-HEIGHT: 150%">
string x = "Live for nothing,die for something";
Regex r1 = new Regex(@".*thing");
if (r1.IsMatch(x))
{
    Console.WriteLine("match:" + r1.Match(x).Value);//输出：Live for nothing,die for something
}
Regex r2 = new Regex(@".*?thing");
if (r2.IsMatch(x))
{
    Console.WriteLine("match:" + r2.Match(x).Value);//输出：Live for nothing
} 
</P></PRE></TD></TR></TBODY></TABLE></FONT></SPAN></P>
<P>（9）回溯与非回溯<BR>使用“(?&gt;…)”方式进行非回溯声明。由于正则表达式引擎的贪婪特性，导致它在某些情况下，将进行回溯以获得匹配，请看下面的示例：</P>
<P style="MARGIN: 5px; LINE-HEIGHT: 150%"><SPAN><FONT size=+0><CCID_NOBR></CCID_NOBR>
<TABLE style="BORDER-RIGHT: rgb(255,0,0) 1px solid; BORDER-TOP: rgb(255,0,0) 1px solid; BORDER-LEFT: rgb(255,0,0) 1px solid; BORDER-BOTTOM: rgb(255,0,0) 1px solid" cellSpacing=0 borderColorDark=#ffffff cellPadding=2 align=center borderColorLight=#000000>
<TBODY>
<TR>
<TD style="FONT-SIZE: 9pt" bgColor=#f0f0f0><PRE><CCID_CODE></CCID_CODE><P style="MARGIN: 5px; LINE-HEIGHT: 150%">
string x = "Live for nothing,die for something";
Regex r1 = new Regex(@".*thing,");
if (r1.IsMatch(x))
{
    Console.WriteLine("match:" + r1.Match(x).Value);//输出：Live for nothing,
}
Regex r2 = new Regex(@"(?&gt;.*)thing,");
if (r2.IsMatch(x))//不匹配
{
    Console.WriteLine("match:" + r2.Match(x).Value);
}
//在r1中，“.*”由于其贪婪特性，将一直匹配到字符串的最后，随后匹配“thing”，
//但在匹配“,”时失败，此时引擎将回溯，并在“thing,”处匹配成功。
//在r2中，由于强制非回溯，所以整个表达式匹配失败。 
</P></PRE></TD></TR></TBODY></TABLE></FONT></SPAN></P>
<P>（10）正向预搜索、反向预搜索<BR>正向预搜索声明格式：正声明 “(?=…)”，负声明 “(?!...)” ，声明本身不作为最终匹配结果的一部分，请看下面的示例：</P>
<P style="MARGIN: 5px; LINE-HEIGHT: 150%"><SPAN><FONT size=+0><CCID_NOBR></CCID_NOBR>
<TABLE style="BORDER-RIGHT: rgb(255,0,0) 1px solid; BORDER-TOP: rgb(255,0,0) 1px solid; BORDER-LEFT: rgb(255,0,0) 1px solid; BORDER-BOTTOM: rgb(255,0,0) 1px solid" cellSpacing=0 borderColorDark=#ffffff cellPadding=2 align=center borderColorLight=#000000>
<TBODY>
<TR>
<TD style="FONT-SIZE: 9pt" bgColor=#f0f0f0><PRE><CCID_CODE></CCID_CODE><P style="MARGIN: 5px; LINE-HEIGHT: 150%">
string x = "1024 used 2048 free";
Regex r1 = new Regex(@"\d{4}(?= used)");
if (r1.Matches(x).Count==1)
{
    Console.WriteLine("r1 match:" + r1.Match(x).Value);//输出：1024
}
Regex r2 = new Regex(@"\d{4}(?! used)");
if (r2.Matches(x).Count==1)
{
    Console.WriteLine("r2 match:" + r2.Match(x).Value); //输出：2048
}
//r1中的正声明表示必须保证在四位数字的后面必须紧跟着“ used”，
//r2中的负声明表示四位数字之后不能跟有“ used”。 
</P></PRE></TD></TR></TBODY></TABLE></FONT></SPAN></P>
<P>反向预搜索声明格式：正声明“(?&lt;=)”，负声明“(?<!)”，声明本身不作为最终匹配结果的一部分，请看下面的示例：></P>
<P style="MARGIN: 5px; LINE-HEIGHT: 150%"><SPAN><FONT size=+0><CCID_NOBR></CCID_NOBR>
<TABLE style="BORDER-RIGHT: rgb(255,0,0) 1px solid; BORDER-TOP: rgb(255,0,0) 1px solid; BORDER-LEFT: rgb(255,0,0) 1px solid; BORDER-BOTTOM: rgb(255,0,0) 1px solid" cellSpacing=0 borderColorDark=#ffffff cellPadding=2 align=center borderColorLight=#000000>
<TBODY>
<TR>
<TD style="FONT-SIZE: 9pt" bgColor=#f0f0f0><PRE><CCID_CODE></CCID_CODE><P style="MARGIN: 5px; LINE-HEIGHT: 150%">
string x = "used:1024 free:2048";
Regex r1 = new Regex(@"(?&lt;=used:)d{4}");  if (r1.Matches(x).Count==1)  {      Console.WriteLine("r1 match:" + r1.Match(x).Value);//输出：1024  }  Regex r2 = new Regex(@"(?<!used:)d{4}");  if (r2.Matches(x).Count==1)  {      Console.WriteLine("r2 match:" + r2.Match(x).Value);//输出：2048  }  //r1中的反向正声明表示在4位数字之前必须紧跟着“used:”，  //r2中的反向负声明表示在4位数字之前必须紧跟着除“used:”之外的字符串。  ></P></PRE></TD></TR></TBODY></TABLE></FONT></SPAN></P>
<P>（11）十六进制字符范围<BR>正则表达式中，可以使用 "\xXX" 和 "\uXXXX" 表示一个字符（"X" 表示一个十六进制数）形式字符范围：<BR>\xXX 编号在 0到255 范围的字符，比如：空格可以使用 "\x20" 表示。<BR>\uXXXX 任何字符可以使用 "\u" 再加上其编号的4位十六进制数表示，比如：汉字可以使用“[\u4e00-\u9fa5]”表示。<BR><BR><BR>（12）对[0,100]的比较完备的匹配<BR>下面是一个比较综合的示例，对于匹配[0,100]，需要特殊考虑的地方包括<BR>*00合法，00.合法，00.00合法，001.100合法<BR>*空字符串不合法，仅小数点不合法，大于100不合法<BR>*数值是可带后缀的，如“1.07f”表示该值为一个float类型（未考虑） </P>
<P style="MARGIN: 5px; LINE-HEIGHT: 150%"><SPAN><FONT size=+0><CCID_NOBR></CCID_NOBR>
<TABLE style="BORDER-RIGHT: rgb(255,0,0) 1px solid; BORDER-TOP: rgb(255,0,0) 1px solid; BORDER-LEFT: rgb(255,0,0) 1px solid; BORDER-BOTTOM: rgb(255,0,0) 1px solid" cellSpacing=0 borderColorDark=#ffffff cellPadding=2 align=center borderColorLight=#000000>
<TBODY>
<TR>
<TD style="FONT-SIZE: 9pt" bgColor=#f0f0f0><PRE><CCID_CODE></CCID_CODE><P style="MARGIN: 5px; LINE-HEIGHT: 150%">
Regex r = new Regex(@"^\+?0*(?:100(\.0*)?|(\d{0,2}(?=\.\d)|\d{1,2}(?=($|\.$)))(\.\d*)?)$");
string x = "";
while (true)
{
    x = Console.ReadLine();
    if (x != "exit")
    {
        if (r.IsMatch(x))
        {
            Console.WriteLine(x + " succeed!");
        }
        else
        {
            Console.WriteLine(x + " failed!");
        }
    }
    else
    {
        break;
    }
}
</P></PRE></TD></TR></TBODY></TABLE></FONT></SPAN></P>
<P>（13）精确匹配有时候是困难的<BR>有些需求要做到精确匹配比较困难，例如：日期、Url、Email地址等，其中一些你甚至需要研究一些专门的文档写出精确完备的表达式，对于这种情况，只能退而求其次，保证比较精确的匹配。例如对于日期，可以基于应用系统的实际情况考虑一段较短的时间，或者对于像Email的匹配，可以只考虑最常见的形式。</P></div>]]></description>
	    <author><![CDATA[CaCell]]></author>
	    <comments>http://zouzhxi.blog.163.com/blog/static/1559251200837104323540</comments>
    <slash:comments>2</slash:comments>
    <guid isPermaLink="true">http://zouzhxi.blog.163.com/blog/static/1559251200837104323540</guid>
    <pubDate>Mon, 7 Apr 2008 10:43:23 +0800</pubDate>
    <dcterms:modified>2008-04-07T10:44:11+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[用户界面设计风格说明]]></title>	
    <link>http://zouzhxi.blog.163.com/blog/static/15592512008259133247</link>
    <description><![CDATA[<div><P><STRONG><FONT color=#ff0000 size=5>中国C++提供的 用户界面设计风格说明</FONT></STRONG></P>
<P>1引言<BR>1.1设计说明<BR>本文档是对系统界面设计风格进行描述，和用户交互的最终界面在《详细设计说明书》中设计和解释。<BR>1.2概念和定义<BR>用户界面：又称人机界面，实现用户与计算机之间得通信，以控制计算机或进行用户和计算机之间得数据传送得系统部件。<BR>GUI：即图形用户界面，一种可视化得用户界面，它使用图形界面代替正文界面。<BR>1.3用户假定<BR>将使用本系统的用户定义为：对应用程序或计算机的一般用法有一定了解，用户希望界面符合WINDOWS9X特别是OFFICE97风格，对易用性、简洁性有比较高的要求，对界面快速交互没有很强的要求（即不希望通过命令方式快速交互）。<BR>2用户界面设计规范<BR>2.1用户界面设计原则<BR>本系统坚持图形用户界面（GUI）设计原则，界面直观、对用户透明：用户接触软件后对界面上对应的功能一目了然、不需要多少培训就可以方便使用本应用系统。<BR>界面设计员应该明白软件中用户是所有处理的核心，不应该有应用程序来决定处理过程，所以用户界面应当由用户来控制应用如何工作、如何响应，而不是由开发者按自己的意愿把操作流程强加给用户。<BR>界面设计必须经过确认才能完成。<BR>2.2界面一致性<BR>在界面设计中应该保持界面的一致性。一致性既包括使用标准的控件,也指使用相同的信息表现方法,如在字体、标签风格、颜色、术语、显示错误信息等方面确保一致。<BR>1）显示信息一致性标准<BR>（1）标签提示:字体为不加重、宋体、黑色、灰底或透明、无边框、右对齐、不带冒号、一般情况为五号（10号）；<BR>（2）日期:正常字体、宋体、白底黑字、3-D lowered；<BR>（3）对齐方法：<BR>l 左对齐:一般文字、单个数字、日期等<BR>l 右对齐:数字、时间、日期加时间。<BR>（4）分辨率为800*600，增强色16色<BR>（5）字体缺省为宋替、五号、黑色<BR>（6）底色缺省采用灰色<BR>这些信息的排列显示风格供参考, 在同一个应用中,这些信息的表现方式不一致,会使得用户分散注意力,影响这一软件的使用，因此开发者应当注意在同一软件中表现形式的一致性。<BR>2）布局合理化原则<BR>应注意在一个窗口内部所有控件的布局和信息组织的艺术性,使得用户界面美观。<BR>在一个窗口中按tab键,移动聚焦的顺序不能杂乱无章,tab 的顺序是先从上至下，再从左至右。一屏中首先应输入的和重要信息的控件在tab顺序中应当靠前,位置也应放在窗口上较醒目的位置。布局力求简洁、有序、易于操作。<BR>3）鼠标与键盘对应原则<BR>应遵循的是可不用鼠标的原则:应用中的功能只用键盘也应当可以完成,即设计的应用中还应加入一些必要的按钮和菜单项。<BR>但是,许多鼠标的操作,如双击、拖动对象等,并不能简单地用键盘来模拟即可实现。例如在一个列表框中用鼠标双击其中一项可以表示选中该项内容。为了用键盘也能实现这一功能,必须在窗口中定义一个表示选中的按钮,以作为实现双击功能的替代（或其它方式）。又如在一个窗口中有两个数据窗口,可以用鼠标从一个数据窗口中将一项拖出然后放到另一个中。如果只用键盘,就应当在菜单中设置拷贝或移动的菜单项。<BR>4）快捷键<BR>在菜单项中使用快捷键可以让使用键盘的用户操作得更快一些,在西文Windows及其应用软件中快捷键的使用大多是一致的。本系统中应用的快捷键在各个配置项上语义必须保持一致。<BR>面向事务的:<BR>l Ctrl-D 删除<BR>l Ctrl-F 寻找<BR>l Ctrl-I 插入<BR>l Ctrl-N 新记录<BR>l Ctrl-S 保存<BR>查询/列表:<BR>l Ctrl-O<BR>l Ctrl-R<BR>其它:<BR>l Ctrl-C 拷贝<BR>l Ctrl-H 帮助<BR>l Ctrl-P 打印<BR>l Ctrl-V 粘贴<BR>l Ctrl-W 关闭<BR>l Ctrl-X 剪切<BR>MS Windows保留键:<BR>l Ctrl-Tab 下一窗口<BR>l Ctrl-Esc 任务列表<BR>l Ctrl-F4 关闭窗口<BR>l Alt-F4 结束应用<BR>l Alt-Tab 下一应用<BR>l Enter 缺省按钮/确认操作<BR>l Esc 取消按钮/取消操作<BR>l Shift-F1 上下文相关帮助<BR>其它快捷键<BR>其它快捷键使用汉语拼音的开头字母，不常用的可以没有快捷键。<BR><BR>2.3向导（WIZARD）使用原则<BR>对于应用中某些部分的处理流程是固定的，用户必须按照指定的顺序输入操作信息，为了使用户操作得到必要的引用应该使用向导，使用户使用功能时比较轻松明了，但是向导必须用在固定处理流程中，并且处理流程应该不少于3个处理步骤。<BR>2.4系统响应时间<BR>系统响应时间包括两个方面：时间长度和时间的易变性。用户响应时间应该适中，系统响应时间过长，用户就会感到不安和沮丧，而响应时间过短有时会造成用户加快操作节奏，从而导致错误。系统响应时间的易变性是指相对于平均响应时间的偏差。即使响应时间比较长，低的响应时间易变性也有助于用户建立稳定的节奏。因此在系统响应时间上坚持如下原则：<BR>响应时间长度 界面设计<BR>0-10 秒 鼠 标 显 示 成 为 沙 漏<BR>10 到18 秒 由微帮助来显示处理进度<BR>18 秒 以 上 显示处理窗口，或显示进度条<BR>一个长时间的处理完成时 应给予完成警告信息<BR><BR>响应时间的易变性 界面设计<BR>用户感觉不到 不考虑<BR>用户稍微感觉到 由微帮助提供易变性说明<BR>容易性大而且时间绝对差别大 显示易变性提示<BR>2.5用户帮助设施<BR>常用的帮助设施有两种：集成的和附加的。集成的帮助设施一开始就是设计在软件中的，它与语境有关，用户可以直接选择与所要执行操作相关的主题。通过集成帮助设施可以缩短用户获得帮助的时间，增加界面的友好性。附加的帮助设施在系统建好以后再加进去的。通常是一种查询能力比较弱的联机帮助。<BR>本系统提供这两种帮助设施，设计和实现时遵循以下原则：<BR>1） 进行系统交互时，提供部分帮助功能，即：提供主要操作的帮助<BR>2） 用户可以通过帮助菜单、F1键和帮助按钮（如果有的话）访问帮助<BR>3） 表示帮助时根据需要提供三种方式的选择：另一个窗体、微帮助和指出参考某个文档<BR>4） 用户如何回到正常交互方式有两种选择：返回键和功能键<BR>5） 帮助信息的构造：采用分层式帮助<BR>6） 微帮助提供：由状态栏提供，或控件上的提示文本<BR>2.6出错信息和警告<BR>出错信息和警告是指出现问题时系统给出的坏消息，本系统对于出错信息和警告应该遵循以下原则：<BR>1） 信息以用户可以理解的术语描述；<BR>2） 信息应提供如何从错误中恢复的建设性意见；<BR>3） 信息应指出错误可能导致那些不量后果，以便用户检查是否出现了这些情况或帮助用户进行改正；<BR>4） 信息应伴随着视觉上的提示，如特殊的图像、颜色或信息闪烁。<BR>5） 信息不能带有判断色彩，即任何情况下不能指责用户<BR>2.7命令交互<BR>由于本系统用户是WINDOWS用户，故本系统不提供命令交互。<BR>2.8一般交互原则<BR>本系统一般交互遵循以下原则：<BR>1） 一致性：菜单选择、数据显示以及其它功能都应使用一致的格式。<BR>2） 提供有意义的反馈<BR>3） 执行有较大破坏性的动作前要求确认<BR>4） 在数据录入上允许取消大多数操作<BR>5） 减少在动作间必须记忆的信息数量<BR>6） 在对话、移动和思考中提高效率<BR>7） 允许用户非恶意错误，系统应保护自己不受致命作物的破坏<BR>8） 按功能对动作分类，并按此排列屏幕布局，设计者应那里提高命令和动作组织的内聚性<BR>9） 提供语境相关的帮助机制<BR>2.9信息显示原则<BR>本系统信息显示遵循以下原则：<BR>1） 只显示与当前用户语境环境有关的信息；<BR>2） 不要用数据将用户包围，使用便于用户迅速吸取信息的方式表现信息；<BR>3） 使用一致的标记、标准缩写和可预测的颜色，显示信息的含义应该非常明确，用户不必再参考其它信息源；<BR>4） 产生有意义的出错信息，见2.6；<BR>5） 使用缩进和文本来辅助理解；<BR>6） 使用窗口分隔控件分隔不同类型的信息；<BR>7） 高效地使用显示器的显示空间。<BR>2.10数据输入原则<BR>本系统数据输入遵循以下原则：<BR>1） 尽量减少用户输入动作的数量；<BR>2） 维护信息显示和数据输入的一致性；<BR>3） 交互应该时灵活的，对键盘和鼠标输入的灵活性提供支持；<BR>4） 在当前动作的语境中使不合适的命令不起作用；<BR>5） 让用户控制交互流，用户可以跳过不必要的动作、改变所需动作的顺序（如果允许的话）以及在不退出系统的情况下从错误状态中恢复；<BR>6） 为所有输入的动作提供帮助，见2.5；<BR>7） 消除冗余输入。可能的话提供缺省值、绝不要让用户提供程序中可以自动获取或计算出来的信息。<BR>3用户界面设计更改和追加说明<BR>3.1更改说明<BR>更改本用户界面设计时应该征得所有开发者的同意，所有开发者应该按更正后的原则修改和设计用户界面。<BR>3.2追加说明<BR>追加本用户界面设计时应该发布给所有开发者，所有开发者应该按追加后的原则修改和设计用户界面。<BR>4其它<BR>无。</P>
<P>&nbsp;</P>
<P>来源：<A href="http://mcs.szu.edu.cn/Forum/33494">http://mcs.szu.edu.cn/Forum/33494</A></P></div>]]></description>
	    <author><![CDATA[CaCell]]></author>
	    <comments>http://zouzhxi.blog.163.com/blog/static/15592512008259133247</comments>
    <slash:comments>6</slash:comments>
    <guid isPermaLink="true">http://zouzhxi.blog.163.com/blog/static/15592512008259133247</guid>
    <pubDate>Wed, 5 Mar 2008 09:01:33 +0800</pubDate>
    <dcterms:modified>2008-03-05T09:01:33+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[相片:  Photo_017]]></title>	
    <link>http://img.blog.163.com/photo/EJw4T7awqQONOZYn-bDe9w==/4255057222935366476.jpg</link>
    <description><![CDATA[<div>
	<a href="http://img.blog.163.com/photo/EJw4T7awqQONOZYn-bDe9w==/4255057222935366476.jpg" target="_blank">
	<img src="http://img.blog.163.com/photo/EJw4T7awqQONOZYn-bDe9w==/4255057222935366476.jpg" border="0" width="180" height="240"/>
	</a><br/><br/>
</div>]]></description>
	    <author><![CDATA[zouzhxi]]></author>
    <guid isPermaLink="false">http://img.blog.163.com/photo/EJw4T7awqQONOZYn-bDe9w==/4255057222935366476.jpg</guid>
    <pubDate>Thu, 1 May 2008 21:28:41 +0800</pubDate>
    <dcterms:modified>2008-05-01T21:28:41+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[相片:  Photo_007]]></title>	
    <link>http://img.blog.163.com/photo/y7qOrkhwARRjN5LlyYS0BQ==/4255057222935366464.jpg</link>
    <description><![CDATA[<d