<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" version="2.0">

<channel>
	<title>西 坪</title>
	
	<link>http://blog.xiping.me</link>
	<description>Keep it simple stupid. Less is more.</description>
	<lastBuildDate>Fri, 06 May 2011 14:24:56 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.6</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/feihoo/blog" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="feihoo/blog" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><feedburner:emailServiceId xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">feihoo/blog</feedburner:emailServiceId><feedburner:feedburnerHostname xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">http://feedburner.google.com</feedburner:feedburnerHostname><item>
		<title>2011, 掌握一门新语言：Erlang</title>
		<link>http://blog.xiping.me/2011/04/2011-study-a-multi-core-lang.html</link>
		<comments>http://blog.xiping.me/2011/04/2011-study-a-multi-core-lang.html#comments</comments>
		<pubDate>Sat, 16 Apr 2011 16:24:06 +0000</pubDate>
		<dc:creator>西坪</dc:creator>
				<category><![CDATA[$Programming]]></category>
		<category><![CDATA[concurrency]]></category>
		<category><![CDATA[erlang]]></category>
		<category><![CDATA[golang]]></category>
		<category><![CDATA[scala]]></category>

		<guid isPermaLink="false">http://blog.xiping.me/?p=1179</guid>
		<description><![CDATA[我们已经进入了多核时代。 做了好些年并发编程设计，觉得虽然主流语言如Java、C/C++都不同程度地通过线程的方式对多核提供了支持，但是要真正理解并发，使用自如，绝非易事。对软件开发人员才是瓶颈的软件工业来说，改革底层的编程模型，以简便地支持多核程序设计，是未来的方向。
为并发而生的 Erlang 已经存活了很多年，只是一直不温不火，阳春白雪。而Java平台上的Scala，在这两年迅速进入软件工业界的视野。尽管其Actor模型借鉴自Eralng，运行在JVM之上，不像Erlang那样纯粹、简单， 但得力于Java平台庞大的现有代码、庞大的程序员阵营和各企业组织的大规模现有投资，很多人都认为Scala会更加成功。即使热爱 Erlang 的 Yariv Sadan &#8212; 他在 Facebook 用 Erlang 开发 Facebook Chat ，也在其争论 Erlang 与 Scala 的博文 《Erlang vs. Scala》 的结尾写道：“ Regardless of these differences, though, I think that Scala has a good chance of being the more popular language of the two.&#8221; 这篇文章很精彩，后面的评论也很精彩，值得一读。 有趣的是，作者说有些人认为 Erlang来自外国 (作者应该是美国人，而Erlang来自瑞典) 是其未能成为主流语言的一个原因。(A few times, [...]


Related posts:<ol><li><a href='http://blog.xiping.me/2010/12/oracle-impdpexpdp-parallel-compression.html' rel='bookmark' title='Permanent Link: Impdp/Expdp 之并行(Parallel)和压缩(Compression)'>Impdp/Expdp 之并行(Parallel)和压缩(Compression)</a></li>
<li><a href='http://blog.xiping.me/2009/12/arguments-on-java-c.html' rel='bookmark' title='Permanent Link: Arguments on Java &#038; C++'>Arguments on Java &#038; C++</a></li>
<li><a href='http://blog.xiping.me/2009/01/flex%e4%b8%ad%e7%9a%84%e5%af%b9%e8%b1%a1%e6%af%94%e8%be%83%ef%bc%88%e7%9b%b8%e7%ad%89%e6%80%a7%ef%bc%89.html' rel='bookmark' title='Permanent Link: Flex中的对象比较（相等性）'>Flex中的对象比较（相等性）</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>我们<a href="http://www.infoq.com/news/2007/09/multicore-processor-trend-impact">已经进入了多核时代</a>。 做了好些年并发编程设计，觉得虽然主流语言如Java、C/C++都不同程度地通过线程的方式对多核提供了支持，但是要真正理解并发，使用自如，绝非易事。对软件开发人员才是瓶颈的软件工业来说，改革底层的编程模型，以简便地支持多核程序设计，是未来的方向。</p>
<p>为并发而生的 <a href="http://www.erlang.org/">Erlang</a> 已经存活了很多年，只是一直不温不火，阳春白雪。而Java平台上的Scala，在这两年迅速进入软件工业界的视野。尽管其Actor模型借鉴自Eralng，运行在JVM之上，不像Erlang那样纯粹、简单， 但得力于Java平台庞大的现有代码、庞大的程序员阵营和各企业组织的大规模现有投资，很多人都认为Scala会更加成功。即使热爱 Erlang 的 <a href="http://yarivsblog.blogspot.com/">Yariv Sadan</a> &#8212; 他在 Facebook 用 Erlang 开发 Facebook Chat ，也在其争论 Erlang 与 Scala 的博文 <a href="http://yarivsblog.blogspot.com/2008/05/erlang-vs-scala.html">《Erlang vs. Scala》</a> 的结尾写道：“ Regardless of these differences, though, I think that Scala has a good chance of being the more popular language of the two.&#8221; 这篇文章很精彩，后面的评论也很精彩，值得一读。 有趣的是，作者说有些人认为 Erlang来自外国 (作者应该是美国人，而Erlang来自瑞典) 是其未能成为主流语言的一个原因。(A few times, I&#8217;ve seen the following take on the relative mertis of Scala and Erlang: Erlang is great for concurrent programming and it has a great track record in its niche, but it&#8217;s unlikely to become mainstream because it&#8217;s foreign and it doesn&#8217;t have as many libraries as Java.)</p>
<p>去年跟风了解了 <a href="http://golang.org">Golang</a>，写过几个小程序。Golang的方式略有有些易于C/Java，但总的来说，还是非常像的，上手不难。尤其是喜欢C的人，要选择一门多核时代的语言去学习，Golang 是最合适的了。不过，我还没有弄透Golang对并发的支持为什么优于传统语言，是的，它的并发基于<a href="http://en.wikipedia.org/wiki/Communicating_sequential_processes">消息传递</a>的，但到底是怎么实现的？又为何如此实现呢？</p>
<p><a href="http://erlang.org">Erlang</a> 给我的感受则完全不同，变量竟然是immutable的，= 竟然不是赋值符号，字符串是整形值，一个类型也没有 <img src='http://blog.xiping.me/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> ， 刘姥姥进了大观园，完全是一个惊奇的世界。不过除了惊讶，我便很快喜欢它immutable的变量，也对久仰大名的 <a href="http://en.wikibooks.org/wiki/Erlang_Programming/List_Comprehensions">List Comprehension</a> 感到异常惊喜。List Comprehension 跟 Map/Reduce的区别还是很明显的。 Erlang 真的是太惊艳了,学习它是必须的。毋庸置疑，它肯定会促使我改变思考事情的方式。</p>
<p>对于Scala，扫描了下<a href="http://www.scala-lang.org/node/197">它的文档</a>。不过我更关心的是 <a href="http://en.wikipedia.org/wiki/Actor_model">Actor</a> 和 <a href="http://en.wikipedia.org/wiki/Communicating_sequential_processes">CSP</a> 。Scala 与 Erlang 的并发都源自 Actor模型，有Erlang就可以了解了。对于一个常跟Java打交道的程序员，Scala需要用了将来再现学就行。 </p>
<p>我想要理解的是Erlang/Go与Java/C不同的并发模型，它们的内存模型有哪些异同。也许你会说减少了上下文切换，减少了CPU Cache丢失，减少系统内存开销，减少抢断带来的损失等等，但我想探寻的是它们具体是怎么做的呢？ 多核的变革已经来临，或许改进应该从计算机体系的顺序模型开始，硬件结构与软件模型一起改进（看看 <a href="http://cacm.acm.org/">Comuunications Of ACM</a> 的 <a href="http://cacm.acm.org/magazines/2010/8/96610-memory-models-a-case-for-rethinking-parallel-languages-and-hardware/fulltext">《Memory Models: A Case for Rethinking Parallel Languages and Hardware》</a>)。 何况除了并发，Erlang 还有更多值得发掘的东西。</p>
<p>下面这是相关的几篇值得一读的好文：</p>
<ul>
<li> <a href="http://cacm.acm.org/magazines/2010/8/96610-memory-models-a-case-for-rethinking-parallel-languages-and-hardware/fulltext">Memory Models: A Case for Rethinking Parallel Languages and Hardware</a></li>
<li>
<a href="http://www.inf.puc-rio.br/~roberto/docs/MCC15-04.pdf">Revisiting Coroutines</a></li>
<li>
<a href="http://java.sys-con.com/node/419716?page=0,0">Multi-Core and Massively Parallel Processors</a></li>
</ul>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />
参考：</p>
<ul>
<li><a href="http://www.infoq.com/news/2008/06/scala-vs-erlang">The multicore crises: Scala vs. Erlang</a>
</ul>


<p>Related posts:<ol><li><a href='http://blog.xiping.me/2010/12/oracle-impdpexpdp-parallel-compression.html' rel='bookmark' title='Permanent Link: Impdp/Expdp 之并行(Parallel)和压缩(Compression)'>Impdp/Expdp 之并行(Parallel)和压缩(Compression)</a></li>
<li><a href='http://blog.xiping.me/2009/12/arguments-on-java-c.html' rel='bookmark' title='Permanent Link: Arguments on Java &#038; C++'>Arguments on Java &#038; C++</a></li>
<li><a href='http://blog.xiping.me/2009/01/flex%e4%b8%ad%e7%9a%84%e5%af%b9%e8%b1%a1%e6%af%94%e8%be%83%ef%bc%88%e7%9b%b8%e7%ad%89%e6%80%a7%ef%bc%89.html' rel='bookmark' title='Permanent Link: Flex中的对象比较（相等性）'>Flex中的对象比较（相等性）</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://blog.xiping.me/2011/04/2011-study-a-multi-core-lang.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Memory leak caused by Proxool and the fix</title>
		<link>http://blog.xiping.me/2011/04/memory-leak-caused-by-proxool-and-the-fix.html</link>
		<comments>http://blog.xiping.me/2011/04/memory-leak-caused-by-proxool-and-the-fix.html#comments</comments>
		<pubDate>Mon, 04 Apr 2011 16:00:15 +0000</pubDate>
		<dc:creator>西坪</dc:creator>
				<category><![CDATA[$Performance]]></category>
		<category><![CDATA[jdbc]]></category>
		<category><![CDATA[oom]]></category>
		<category><![CDATA[opensuse]]></category>
		<category><![CDATA[proxool]]></category>

		<guid isPermaLink="false">http://blog.xiping.me/?p=1136</guid>
		<description><![CDATA[Update: Be cautions if you don&#8217;t apply the patch to work with Oracle JDBC. The finalize() method in the WrappedConnection instances is always invoked when they are being finalized; then the finalize() in the physical connection class would be invoked. If the JDBC driver places some code there, it could destroy the pooled connections.  [...]


Related posts:<ol><li><a href='http://blog.xiping.me/2011/04/proxool-memory-leak.html' rel='bookmark' title='Permanent Link: Proxool导致的内存泄漏'>Proxool导致的内存泄漏</a></li>
<li><a href='http://blog.xiping.me/2010/11/jdbc-ibatis-datetimes.html' rel='bookmark' title='Permanent Link: JDBC和Ibatis中的Date,Time,Timestamp处理'>JDBC和Ibatis中的Date,Time,Timestamp处理</a></li>
<li><a href='http://blog.xiping.me/2010/01/file-lock-and-jvm-mutex.html' rel='bookmark' title='Permanent Link: 文件锁与进程互斥'>文件锁与进程互斥</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p><strong>Update: Be cautions if you don&#8217;t apply the patch to work with Oracle JDBC.</strong> The finalize() method in the <a href="http://proxool.cvs.sourceforge.net/viewvc/proxool/proxool/src/java/org/logicalcobwebs/proxool/WrappedConnection.java?revision=1.6&#038;view=markup">WrappedConnection</a> instances is always invoked when they are being finalized; then the finalize() in the physical connection class would be invoked. If the JDBC driver places some code there, it could destroy the pooled connections.  (Apr 10th, 2011)<br />
============================</p>
<p>Someone has reported a possible memory leak related with <a href="http://proxool.sourceforge.net/">Proxool connection pool</a>. And we addressed the bug recently in our applications, which are Java backend applications that work with Oracle 11g through Oracle JDBC5 on IBM JDK 5 platform. </p>
<p>The finalize() method of the proxied OracleConnection instances are the root cause. <a href="http://download.oracle.com/docs/cd/E11882_01/appdev.112/e13995/oracle/jdbc/OracleConnection.html">OracleConnection</a> classes have no explict finalize() method, but each proxied object has one generated by cglib. When such a proxied connection instance is being finalized, the stack should be as the figure shows.  You can see  Connection#isClosed() method is invoked, which is SYNCHRONIZED (the monitor is the connection object itself).  Then the finalizer thread and the worker thread using the physical connection could block each other. Finally, the proxied connection objects in finalizing queue and all referenced objects couldn&#8217;t be garbage-collected. Sometimes Connections aren&#8217;t so busy &#8211; you are lucky &#8211; the heap could suspend or even decrease; but OOM is waiting for you at the end usually.</p>
<p><img src="http://blog.xiping.me/wp-content/uploads/2011/04/thread_blocked_2.PNG" alt="thread_blocked_2" title="thread_blocked_2" /></p>
<p>I gave a fix that avoid invoking Connection#isClosed() while finalizing. Actually, I changed the line 114 of <a href="http://proxool.cvs.sourceforge.net/viewvc/proxool/proxool/src/java/org/logicalcobwebs/proxool/WrappedConnection.java?revision=1.6&#038;view=markup">WrappedConnection</a> from</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>proxyConnection <span style="color: #339933;">!=</span> <span style="color: #000066; font-weight: bold;">null</span> <span style="color: #339933;">&amp;&amp;</span> proxyConnection.<span style="color: #006633;">isReallyClosed</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></pre></div></div>

<p>to</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>proxyConnection <span style="color: #339933;">!=</span> <span style="color: #000066; font-weight: bold;">null</span> <span style="color: #339933;">&amp;&amp;</span> <span style="color: #339933;">!</span>concreteMethod.<span style="color: #006633;">getName</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">equals</span><span style="color: #009900;">&#40;</span>FINALIZE_METHOD<span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;&amp;</span> proxyConnection.<span style="color: #006633;">isReallyClosed</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></pre></div></div>

<p>The fix is proved to be effective in our serveral systems in production .</p>
<p>You can download the patch in the <a href="http://sourceforge.net/tracker/?func=detail&#038;aid=3267640&#038;group_id=53958&#038;atid=472195">bug page in proxool bugtrack site</a>.</p>
<p>Or you can download a compiled version of <a href="http://blog.xiping.me/wp-content/uploads/2011/04/proxool-0.9.1.zip">proxool-0.9.1.jar</a>(WITHOUT WARRANT). (It&#8217;s comipled from <a href="http://prdownloads.sourceforge.net/proxool/proxool-0.9.1-source.zip?download">proxool-0.9.1-source.zip</a>) </p>
<p>Any questions please let me know by giving a comment.</p>


<p>Related posts:<ol><li><a href='http://blog.xiping.me/2011/04/proxool-memory-leak.html' rel='bookmark' title='Permanent Link: Proxool导致的内存泄漏'>Proxool导致的内存泄漏</a></li>
<li><a href='http://blog.xiping.me/2010/11/jdbc-ibatis-datetimes.html' rel='bookmark' title='Permanent Link: JDBC和Ibatis中的Date,Time,Timestamp处理'>JDBC和Ibatis中的Date,Time,Timestamp处理</a></li>
<li><a href='http://blog.xiping.me/2010/01/file-lock-and-jvm-mutex.html' rel='bookmark' title='Permanent Link: 文件锁与进程互斥'>文件锁与进程互斥</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://blog.xiping.me/2011/04/memory-leak-caused-by-proxool-and-the-fix.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Proxool导致的内存泄漏</title>
		<link>http://blog.xiping.me/2011/04/proxool-memory-leak.html</link>
		<comments>http://blog.xiping.me/2011/04/proxool-memory-leak.html#comments</comments>
		<pubDate>Fri, 01 Apr 2011 15:51:52 +0000</pubDate>
		<dc:creator>西坪</dc:creator>
				<category><![CDATA[$Performance]]></category>
		<category><![CDATA[concurrency]]></category>
		<category><![CDATA[连接池]]></category>
		<category><![CDATA[jdbc]]></category>
		<category><![CDATA[JVM]]></category>
		<category><![CDATA[oom]]></category>
		<category><![CDATA[opensource]]></category>
		<category><![CDATA[proxool]]></category>

		<guid isPermaLink="false">http://blog.xiping.me/?p=1106</guid>
		<description><![CDATA[Proxool是一个很优秀的开源连接池。我曾经比较过dbcp, c3p0 和 proxool 这三个连接池，阅读和分析它们的代码。相比之下，proxool 用了cglib，其源码显得相当简洁优雅。 但是很不幸，在这一次，内存泄漏的帐要算在它头上。 我们使用的是proxool 的0.9.1的版本,环境是Oracle JDBC5 + IBM JDK5。
0.9.1版本是proxool 的最新版本。我们有一个应用据称运行以来，就一直处于内存溢出的阴霾之中。追赶数据时的某些巨忙的系统可能会一天内死好些次，甚至达十几次。不得不采用一些监控脚本定时重启。去年12月我接手以来，也被这个问题困扰，最糟糕的时候甚至某些硬件设施很好的部署实例的多达50+GB的堆也能在一天之内吃光。
出错的原因很简单，proxool使用了cglib，它用WrappedConnection代理实际的Conneciton。在运行WrappedConnection的方法时，包括其finalize方法，都会调用Conneciton.isClosed()方法去判断是否真的需要执行某些操作。不幸的是Oracle JDBC中的这个方法是同步的，锁是连接对象本身。于是， Finalizer线程回收刚执行过的WrappedConnection对象时就总会与还在使用Connection的各个工作线程争用锁。
贴一张简单的图，你就懂了：

解决方案是在WrappedConnection.java的第114行，做一点小小的改动，在调用的方法为finalize方法时，不要去掉isClosed()方法。事实上，WrappedConnection#finalize()方法的调用与Connection根本没啥关系。Oracle JDBC本身没有实现finalize()方法，是cglib代理的对象自己生成了一个finalize()方法而已。
修改前的114行：

if &#40;proxyConnection != null &#38;&#38; proxyConnection.isReallyClosed&#40;&#41;&#41; &#123;

修改后的114行：

if &#40;proxyConnection != null &#38;&#38; !concreteMethod.getName&#40;&#41;.equals&#40;FINALIZE_METHOD&#41; &#38;&#38; proxyConnection.isReallyClosed&#40;&#41;&#41; &#123;

点此查看sourceforge上的完整的WrappedConnection.java。
效果是很明显的。一方面，内存消耗明显降低。之前，所有的部署实例都会隔段时间就当掉，某些部署实例的52G的堆都会溢出！现在，系统再忙其堆大小也基本上在原来那个设得老大的Xms参数之下。 第二方面，吞吐量忽然提高了许多，没有烦人的回收线程（其优先级要高点）的干扰，当然应该要跑得更快些。
感兴趣的朋友可以下载我这里提供的jar包(-target 1.5)，(源码是直接从官网下的proxool-0.9.1-source.zip）。这个jar包也解决了ProxoolDataSource在Spring中作为bean配置时有三个属性(maximumConnectionLifetime,houseKeepingSleepTime,overloadWithoutRefusalLifetime)不能注入的问题。详细请看这篇博文。
下载 proxool-0.9.1
也可以应用patch自己编译一个。patch我上传到Bug页面了，请去那下载。


Related posts:Memory leak caused by Proxool and the fix
J2EE/Oracle性能调优实录
文件锁与进程互斥



Related posts:<ol><li><a href='http://blog.xiping.me/2011/04/memory-leak-caused-by-proxool-and-the-fix.html' rel='bookmark' title='Permanent Link: Memory leak caused by Proxool and the fix'>Memory leak caused by Proxool and the fix</a></li>
<li><a href='http://blog.xiping.me/2011/02/optimizing-actions.html' rel='bookmark' title='Permanent Link: J2EE/Oracle性能调优实录'>J2EE/Oracle性能调优实录</a></li>
<li><a href='http://blog.xiping.me/2010/01/file-lock-and-jvm-mutex.html' rel='bookmark' title='Permanent Link: 文件锁与进程互斥'>文件锁与进程互斥</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p><a href="http://proxool.sourceforge.net/">Proxool</a>是一个很优秀的开源连接池。我曾经比较过<a href="http://commons.apache.org/dbcp/">dbcp</a>, <a href="http://www.mchange.com/projects/c3p0/index.html">c3p0</a> 和 <a href="http://proxool.sourceforge.net/">proxool</a> 这三个连接池，阅读和分析它们的代码。相比之下，<a href="http://proxool.sourceforge.net/">proxool</a> 用了cglib，其源码显得相当简洁优雅。 但是很不幸，在这一次，内存泄漏的帐要算在它头上。 我们使用的是<a href="http://proxool.sourceforge.net/">proxool</a> 的0.9.1的版本,环境是Oracle JDBC5 + IBM JDK5。</p>
<p>0.9.1版本是<a href="http://proxool.sourceforge.net/">proxool</a> 的最新版本。我们有一个应用据称运行以来，就一直处于内存溢出的阴霾之中。追赶数据时的某些巨忙的系统可能会一天内死好些次，甚至达十几次。不得不采用一些监控脚本定时重启。去年12月我接手以来，也被这个问题困扰，最糟糕的时候甚至某些硬件设施很好的部署实例的多达50+GB的堆也能在一天之内吃光。</p>
<p>出错的原因很简单，proxool使用了cglib，它用<a href="http://proxool.cvs.sourceforge.net/viewvc/proxool/proxool/src/java/org/logicalcobwebs/proxool/WrappedConnection.java?revision=1.6&#038;view=markup">WrappedConnection</a>代理实际的Conneciton。在运行<a href="http://proxool.cvs.sourceforge.net/viewvc/proxool/proxool/src/java/org/logicalcobwebs/proxool/WrappedConnection.java?revision=1.6&#038;view=markup">WrappedConnection</a>的方法时，包括其finalize方法，都会调用Conneciton.isClosed()方法去判断是否真的需要执行某些操作。不幸的是Oracle JDBC中的这个方法是同步的，锁是连接对象本身。于是， Finalizer线程回收刚执行过的<a href="http://proxool.cvs.sourceforge.net/viewvc/proxool/proxool/src/java/org/logicalcobwebs/proxool/WrappedConnection.java?revision=1.6&#038;view=markup">WrappedConnection</a>对象时就总会与还在使用Connection的各个工作线程争用锁。</p>
<p>贴一张简单的图，你就懂了：<br />
<a href="http://blog.xiping.me/wp-content/uploads/2011/04/thread_blocked_2.PNG"><img src="http://blog.xiping.me/wp-content/uploads/2011/04/thread_blocked_2.PNG" alt="thread_blocked_2" title="thread_blocked_2" /></a></p>
<p>解决方案是在WrappedConnection.java的第114行，做一点小小的改动，在调用的方法为finalize方法时，不要去掉isClosed()方法。事实上，WrappedConnection#finalize()方法的调用与Connection根本没啥关系。Oracle JDBC本身没有实现finalize()方法，是cglib代理的对象自己生成了一个finalize()方法而已。<br />
修改前的114行：</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>proxyConnection <span style="color: #339933;">!=</span> <span style="color: #000066; font-weight: bold;">null</span> <span style="color: #339933;">&amp;&amp;</span> proxyConnection.<span style="color: #006633;">isReallyClosed</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></pre></div></div>

<p>修改后的114行：</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>proxyConnection <span style="color: #339933;">!=</span> <span style="color: #000066; font-weight: bold;">null</span> <span style="color: #339933;">&amp;&amp;</span> <span style="color: #339933;">!</span>concreteMethod.<span style="color: #006633;">getName</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">equals</span><span style="color: #009900;">&#40;</span>FINALIZE_METHOD<span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;&amp;</span> proxyConnection.<span style="color: #006633;">isReallyClosed</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></pre></div></div>

<p>点此查看sourceforge上的完整的<a href="http://proxool.cvs.sourceforge.net/viewvc/proxool/proxool/src/java/org/logicalcobwebs/proxool/WrappedConnection.java?revision=1.6&#038;view=markup">WrappedConnection.java</a>。</p>
<p>效果是很明显的。一方面，内存消耗明显降低。之前，所有的部署实例都会隔段时间就当掉，某些部署实例的52G的堆都会溢出！现在，系统再忙其堆大小也基本上在原来那个设得老大的Xms参数之下。 第二方面，吞吐量忽然提高了许多，没有烦人的回收线程（其优先级要高点）的干扰，当然应该要跑得更快些。</p>
<p>感兴趣的朋友可以下载我这里提供的jar包(-target 1.5)，(源码是直接从官网下的<a href="http://prdownloads.sourceforge.net/proxool/proxool-0.9.1-source.zip?download">proxool-0.9.1-source.zip</a>）。这个jar包也解决了ProxoolDataSource在Spring中作为bean配置时有三个属性(maximumConnectionLifetime,houseKeepingSleepTime,overloadWithoutRefusalLifetime)不能注入的问题。详细请看这篇<a href="http://windows9834.blog.163.com/blog/static/273450042009102463712870/">博文</a>。</p>
<p><a href='http://blog.xiping.me/wp-content/uploads/2011/04/proxool-0.9.1.zip'>下载 proxool-0.9.1</a></p>
<p>也可以应用patch自己编译一个。patch我上传到<a href="https://sourceforge.net/tracker/?func=detail&#038;aid=3267640&#038;group_id=53958&#038;atid=472195">Bug页面</a>了，请去那下载。</p>


<p>Related posts:<ol><li><a href='http://blog.xiping.me/2011/04/memory-leak-caused-by-proxool-and-the-fix.html' rel='bookmark' title='Permanent Link: Memory leak caused by Proxool and the fix'>Memory leak caused by Proxool and the fix</a></li>
<li><a href='http://blog.xiping.me/2011/02/optimizing-actions.html' rel='bookmark' title='Permanent Link: J2EE/Oracle性能调优实录'>J2EE/Oracle性能调优实录</a></li>
<li><a href='http://blog.xiping.me/2010/01/file-lock-and-jvm-mutex.html' rel='bookmark' title='Permanent Link: 文件锁与进程互斥'>文件锁与进程互斥</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://blog.xiping.me/2011/04/proxool-memory-leak.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>拍拍我这几年买的书</title>
		<link>http://blog.xiping.me/2011/03/my-books-bought-in-5-years.html</link>
		<comments>http://blog.xiping.me/2011/03/my-books-bought-in-5-years.html#comments</comments>
		<pubDate>Thu, 31 Mar 2011 14:59:49 +0000</pubDate>
		<dc:creator>西坪</dc:creator>
				<category><![CDATA[@生活]]></category>

		<guid isPermaLink="false">http://blog.xiping.me/?p=1087</guid>
		<description><![CDATA[虽然很多都没有好好地读，但是这几年确实攒了不少书。书都搁不下了，房子太小，两个书架都满了，好好归置了一下，在电视柜边再放了两摞。
房东的四层书架

自己又买了一个

放不下了，在电视柜旁堆了两摞
用《Communications of ACM》挡住了一些杂七杂八的东西。



No related posts.


No related posts.]]></description>
			<content:encoded><![CDATA[<p>虽然很多都没有好好地读，但是这几年确实攒了不少书。书都搁不下了，房子太小，两个书架都满了，好好归置了一下，在电视柜边再放了两摞。</p>
<h5>房东的四层书架</h5>
<p><img src="http://blog.xiping.me/wp-content/uploads/2011/04/IMG_21802-300x225.jpg" alt="IMG_2180" title="IMG_2180" width="300" height="225" /></p>
<h5>自己又买了一个</h5>
<p><img src="http://blog.xiping.me/wp-content/uploads/2011/04/IMG_2181-225x300.jpg" alt="IMG_2181" title="IMG_2181" width="225" height="300" /></p>
<h5>放不下了，在电视柜旁堆了两摞</h5>
<p>用《Communications of ACM》挡住了一些杂七杂八的东西。</p>
<p><img src="http://blog.xiping.me/wp-content/uploads/2011/04/IMG_2182-300x225.jpg" alt="IMG_2182" title="IMG_2182" width="300" height="225" /></p>


<p>No related posts.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.xiping.me/2011/03/my-books-bought-in-5-years.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>解决Java序列化的版本冲突</title>
		<link>http://blog.xiping.me/2011/03/java-serialize-and-reflection.html</link>
		<comments>http://blog.xiping.me/2011/03/java-serialize-and-reflection.html#comments</comments>
		<pubDate>Sat, 19 Mar 2011 11:18:17 +0000</pubDate>
		<dc:creator>西坪</dc:creator>
				<category><![CDATA[$Programming]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[memcached]]></category>
		<category><![CDATA[reflection]]></category>
		<category><![CDATA[serialize]]></category>
		<category><![CDATA[序列化]]></category>

		<guid isPermaLink="false">http://blog.xiping.me/?p=1038</guid>
		<description><![CDATA[序列化机制有很多种，Java原生的序列化机制是最方便、简单、直接的序列化方法之一。尽管这种机制有很多缺点，但还是有不少项目使用。我们有一个项目，将部分对象序列化后存储在Memcached中，后来程序出了升级版本。不幸的是，序列化对象对应的类有了一些变化，新版本的程序不能反序列化之前的数据。在协助升级Memcached中的数据的过程中才发现这个问题，这时便需提前将Memcached中的数据针对新版本程序做转换。 Memcached的导出机制我已经在前面的博文中作过介绍。
什么时候Java序列化会发生冲突
Java的序列化，实际上序列化的是对象的内容，也即只包括域（含父类的域）。因此类中方法的变化不会对序列化造成影响，只有类的体系和属性会对序列化造成影响。主要的导致版本冲突的变化包括：

删除域
改变类继承体系，讲一个实例域修改为静态或将非瞬时（transient）域修改为瞬时域
修改域类型
修writeObject/readObject导致不兼容的修改
以及其他更多&#8230;.

详细请参见官方文档。
我们的程序修改了一个属性的类型，导致新版本程序不能反序列化之前的数据。
使用Reflection解决版本冲突
最早我尝试使用动态类加载和反射(Reflection)，将旧版本的classes加入到类路径中，使用旧版本的classes将数据反序列化，再通过Reflection将值设置到新版本class的实例上，再将新版本的实例反序列化回Memcached中。伪代码如下：

//Add old classes to classpath and 
import ***.stat.***.service.impl.AAAContext;
 //return: new Instance of AAAContext;
 //param: serialized data of old instance AAAContext
 private byte&#91;&#93; getNewInstance&#40;byte&#91;&#93; serializedData&#41; throws Exception &#123;
&#160;
   //get the old instance by deserializing data 
   AAAContext oldObje = deserialize&#40;serializedData&#41;;
&#160;
   //load new classes from external jar files
   [...]


Related posts:<ol><li><a href='http://blog.xiping.me/2010/12/java-volatile-is-not-so-evil.html' rel='bookmark' title='Permanent Link: Java中的Volatile关键字'>Java中的Volatile关键字</a></li>
<li><a href='http://blog.xiping.me/2009/10/understand_java_additon.html' rel='bookmark' title='Permanent Link: 理解Java虚拟机的加法运算'>理解Java虚拟机的加法运算</a></li>
<li><a href='http://blog.xiping.me/2010/01/file-lock-and-jvm-mutex.html' rel='bookmark' title='Permanent Link: 文件锁与进程互斥'>文件锁与进程互斥</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>序列化机制有很多种，Java原生的序列化机制是最方便、简单、直接的序列化方法之一。尽管这种机制有很多缺点，但还是有不少项目使用。我们有一个项目，将部分对象序列化后存储在Memcached中，后来程序出了升级版本。不幸的是，序列化对象对应的类有了一些变化，新版本的程序不能反序列化之前的数据。在协助升级Memcached中的数据的过程中才发现这个问题，这时便需提前将Memcached中的数据针对新版本程序做转换。 Memcached的导出机制我已经在<a href="http://blog.xiping.me/2010/04/dump_memcached.html">前面的博文</a>中作过介绍。</p>
<h3>什么时候Java序列化会发生冲突</h3>
<p>Java的序列化，实际上序列化的是对象的内容，也即只包括域（含父类的域）。因此类中方法的变化不会对序列化造成影响，只有类的体系和属性会对序列化造成影响。主要的导致版本冲突的变化包括：</p>
<ul>
<li>删除域</li>
<li>改变类继承体系，讲一个实例域修改为静态或将非瞬时（transient）域修改为瞬时域</li>
<li>修改域类型</li>
<li>修writeObject/readObject导致不兼容的修改</li>
<li>以及其他更多&#8230;.</li>
</ul>
<p>详细请参见<a href="http://download.oracle.com/javase/6/docs/platform/serialization/spec/version.html#6678">官方文档</a>。</p>
<p>我们的程序修改了一个属性的类型，导致新版本程序不能反序列化之前的数据。</p>
<h3>使用Reflection解决版本冲突</h3>
<p>最早我尝试使用动态类加载和反射(Reflection)，将旧版本的classes加入到类路径中，使用旧版本的classes将数据反序列化，再通过Reflection将值设置到新版本class的实例上，再将新版本的实例反序列化回Memcached中。伪代码如下：</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">//Add old classes to classpath and </span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #339933;">***</span>.<span style="color: #006633;">stat</span>.<span style="color: #339933;">***</span>.<span style="color: #006633;">service</span>.<span style="color: #006633;">impl</span>.<span style="color: #006633;">AAAContext</span><span style="color: #339933;">;</span>
 <span style="color: #666666; font-style: italic;">//return: new Instance of AAAContext;</span>
 <span style="color: #666666; font-style: italic;">//param: serialized data of old instance AAAContext</span>
 <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> getNewInstance<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> serializedData<span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">throws</span> <span style="color: #003399;">Exception</span> <span style="color: #009900;">&#123;</span>
&nbsp;
   <span style="color: #666666; font-style: italic;">//get the old instance by deserializing data </span>
   AAAContext oldObje <span style="color: #339933;">=</span> deserialize<span style="color: #009900;">&#40;</span>serializedData<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
   <span style="color: #666666; font-style: italic;">//load new classes from external jar files</span>
   <span style="color: #003399;">URLClassLoader</span> clazzLoader <span style="color: #339933;">;</span>
   <span style="color: #000000; font-weight: bold;">Class</span> aaaContextClazz<span style="color: #339933;">;</span>
   <span style="color: #003399;">URL</span> jarfile <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">URL</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;jar&quot;</span>, <span style="color: #0000ff;">&quot;&quot;</span>,<span style="color: #0000ff;">&quot;file:E:<span style="color: #000099; font-weight: bold;">\\</span>workshop<span style="color: #000099; font-weight: bold;">\\</span>new-lib.jar!/&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   <span style="color: #003399;">URL</span> jarfile1 <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">URL</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;jar&quot;</span>, <span style="color: #0000ff;">&quot;&quot;</span>,<span style="color: #0000ff;">&quot;file:E:<span style="color: #000099; font-weight: bold;">\\</span>workshop<span style="color: #000099; font-weight: bold;">\\</span>dependencies.jar!/&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   clazzLoader <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">URLClassLoader</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">URL</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#123;</span> jarfile, jarfile1<span style="color: #009900;">&#125;</span>, <span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   aaaContextClazz <span style="color: #339933;">=</span> clazzLoader.<span style="color: #006633;">loadClass</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;***.stat.***.service.impl.AAAContext&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   <span style="color: #003399;">Object</span> oldins <span style="color: #339933;">=</span> aaaContextClazz.<span style="color: #006633;">newInstance</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
   <span style="color: #666666; font-style: italic;">//get setters on the new clazz, MUST find every setter method by hand coding</span>
   <span style="color: #003399;">Method</span> m<span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> aaaContextClazz.<span style="color: #006633;">getDeclaredMethods</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
   m<span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span>.<span style="color: #006633;">invoke</span><span style="color: #009900;">&#40;</span>ins, oldObject.<span style="color: #006633;">getProp1</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   m<span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span>.<span style="color: #006633;">invoke</span><span style="color: #009900;">&#40;</span>ins, oldObject.<span style="color: #006633;">getProp2</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   .... ....
&nbsp;
   <span style="color: #666666; font-style: italic;">//return the serialized data of new instance</span>
   <span style="color: #000000; font-weight: bold;">return</span> serializeObj<span style="color: #009900;">&#40;</span>ins<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>其中比较特殊的是 &#8220;clazzLoader = new URLClassLoader(new URL[]{ jarfile, jarfile1}, null);&#8221; 这一行代码，因为Java类加载体系的继承方式，必须指定new URLClassLoader()的第二个参数为null，去掉parent加载器。在不指定该参数时，会使用当前类加载器作为parent加载器，于是则会先从当前的类加载器体系中去寻找，只能得到类路径（classpath）下的同名类。</p>
<p>这种方法因为要序列化的字段太多，实现起来不易，且需要老版本的各依赖包，工程人员实施起来麻烦，故转而采取了下面的方法。</p>
<h3>使用内置的序列化措施解决冲突</h3>
<p>花了点时间研究Java的序列化机制后，发现有更好的方法支持序列化数据的版本变化。其中最简单的就是添加readObject/writeObject方法，自定义实现序列化，完成新旧版本间的转换。主要有下面三步要做。</p>
<h5>第一步：自定义要更新的字段</h5>
<p>Java序列化机制容许我们指定哪些字段要序列化（<a href="http://download.oracle.com/javase/1.5.0/docs/guide/serialization/spec/serial-arch.html#6250">官方文档</a>）。将类型变化了的属性的序列化类型指定为旧版本中的类型(Long.class，新类型为String.class)，以兼容老版本的序列化信息。定义如下：</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">  <span style="color: #666666; font-style: italic;">//定义的序列化版本ID必须与新/旧的class一致</span>
  <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000000; font-weight: bold;">final</span> <span style="color: #000066; font-weight: bold;">long</span> serialVersionUID <span style="color: #339933;">=</span> 3495267477129405823L<span style="color: #339933;">;</span>
  <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000000; font-weight: bold;">final</span>
  <span style="color: #003399;">ObjectStreamField</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> serialPersistentFields <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">ObjectStreamField</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;id&quot;</span>, <span style="color: #003399;">Long</span>.<span style="color: #000000; font-weight: bold;">class</span><span style="color: #009900;">&#41;</span>,
	<span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">ObjectStreamField</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;aaa_BeginTime&quot;</span>, <span style="color: #003399;">Date</span>.<span style="color: #000000; font-weight: bold;">class</span><span style="color: #009900;">&#41;</span>,
	<span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">ObjectStreamField</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;flag&quot;</span>, <span style="color: #003399;">Integer</span>.<span style="color: #000000; font-weight: bold;">class</span><span style="color: #009900;">&#41;</span>,
              <span style="color: #666666; font-style: italic;">//略去几十个</span>
&nbsp;
              <span style="color: #666666; font-style: italic;">//将类型变化了的属性的序列化类型为旧版本中的类型</span>
              <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">ObjectStreamField</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;sess_parameter&quot;</span>, <span style="color: #003399;">Long</span>.<span style="color: #000000; font-weight: bold;">class</span><span style="color: #009900;">&#41;</span>
 <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span></pre></div></div>

<h5>第二步：定义readObject方法</h5>
<p>定义readObject方法，读取老版本的数据，并做新旧类型转换:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000066; font-weight: bold;">void</span> readObject<span style="color: #009900;">&#40;</span><span style="color: #003399;">ObjectInputStream</span> ois<span style="color: #009900;">&#41;</span>
    <span style="color: #000000; font-weight: bold;">throws</span> <span style="color: #003399;">ClassNotFoundException</span>, <span style="color: #003399;">IOException</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #666666; font-style: italic;">// Read version one types</span>
  <span style="color: #003399;">ObjectInputStream.<span style="color: #006633;">GetField</span></span> fields <span style="color: #339933;">=</span>  ois.<span style="color: #006633;">readFields</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">id</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #003399;">Long</span><span style="color: #009900;">&#41;</span>fields.<span style="color: #006633;">get</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;id&quot;</span>, <span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">aaa_BeginTime</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #003399;">Date</span><span style="color: #009900;">&#41;</span>fields.<span style="color: #006633;">get</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;aaa_BeginTime&quot;</span>, <span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">flag</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #003399;">Integer</span><span style="color: #009900;">&#41;</span>fields.<span style="color: #006633;">get</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;flag&quot;</span>, <span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #666666; font-style: italic;">//略去几十个</span>
&nbsp;
  <span style="color: #666666; font-style: italic;">//按旧版本读取，在转化为新版本的类型</span>
  <span style="color: #003399;">Long</span> old_param <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #003399;">Long</span><span style="color: #009900;">&#41;</span>fields.<span style="color: #006633;">get</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;sess_parameter&quot;</span>, <span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">sess_parameter</span> <span style="color: #339933;">=</span> <span style="color: #003399;">String</span>.<span style="color: #006633;">valueOf</span><span style="color: #009900;">&#40;</span>old_param<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<h5>第三步，定义writeObject方法 </h5>
<p>定义writeObject方法，以新版本class的序列化格式得到新的序列化数据：</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000066; font-weight: bold;">void</span> writeObject<span style="color: #009900;">&#40;</span><span style="color: #003399;">ObjectOutputStream</span> oos<span style="color: #009900;">&#41;</span>
    <span style="color: #000000; font-weight: bold;">throws</span> <span style="color: #003399;">IOException</span> <span style="color: #009900;">&#123;</span>
   PutField fields <span style="color: #339933;">=</span> oos.<span style="color: #006633;">putFields</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  fields.<span style="color: #006633;">put</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;id&quot;</span>, <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">id</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	fields.<span style="color: #006633;">put</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;aaa_BeginTime&quot;</span>, <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">aaa_BeginTime</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	fields.<span style="color: #006633;">put</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;RoamFlag&quot;</span>, <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">RoamFlag</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #666666; font-style: italic;">//按新版本方式写入</span>
  fields.<span style="color: #006633;">put</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;sess_parameter&quot;</span>, <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">sess_parameter</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  oos.<span style="color: #006633;">writeFields</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>以这种方式，只需要新增一个类就完成了转化工作。 这个类不是新版本程序中的类，实际上只是用于中间转化操作的临时代码，它以旧版本class的序列化方式读取数据，再按新版本class的序列化方式输出数据。</p>
<h3>教训</h3>
<p>使用默认的Java序列化机制，会使得具体的类成为数据的schema，持久化的数据受限于类的实现细节。这带来了多方面的约束。所以，如果你用Java的原生序列化，起码应该制定一个合适的Schema，并清楚类的实现细节变化可能导致数据需要特别的迁移处理。我建议选择一种别的与类的实现细节无关的序列化方案。</p>
<h3>参考资料</h3>
<ol>
<li><a href="http://download.oracle.com/javase/1.5.0/docs/guide/serialization/spec/serialTOC.html">Java Serialization Specification (1.5)</a></li>
<li>T<a href="http://download.oracle.com/javase/6/docs/platform/serialization/spec/version.html#6678">ype Changes Affecting Serialization</a></li>
<li><a href="http://longdick.javaeye.com/blog/458557">Java序列化算法透析</a>: 国人写的一篇Java序列化算法的分析，解析很透彻</li>
<li><a href="http://www.javaworld.com/community/node/2915">The Java serialization algorithm revealed</a> : 一篇英文的有关序列化机制的分析文章，与前一篇参考很接近。 </li>
<li><a href="http://www.javapractices.com/topic/TopicAction.do?Id=45">Implementing Serializable</a> : 简明扼要的概述了序列化机制</li>
<li><a href="http://java.sun.com/developer/technicalArticles/ALT/serialization/">Advanced Serialization</a></li>
<li><a href="http://java.sun.com/developer/technicalArticles/Programming/serialization/">Discover the secrets of the Java Serialization API</a></li>
<li><a href="http://tutorials.jenkov.com/java-reflection/dynamic-class-loading-reloading.html">Dynamic Class Loading and Reloading in Java</a><br />


<p>Related posts:<ol><li><a href='http://blog.xiping.me/2010/12/java-volatile-is-not-so-evil.html' rel='bookmark' title='Permanent Link: Java中的Volatile关键字'>Java中的Volatile关键字</a></li>
<li><a href='http://blog.xiping.me/2009/10/understand_java_additon.html' rel='bookmark' title='Permanent Link: 理解Java虚拟机的加法运算'>理解Java虚拟机的加法运算</a></li>
<li><a href='http://blog.xiping.me/2010/01/file-lock-and-jvm-mutex.html' rel='bookmark' title='Permanent Link: 文件锁与进程互斥'>文件锁与进程互斥</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://blog.xiping.me/2011/03/java-serialize-and-reflection.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>在Android上走出天朝局域网</title>
		<link>http://blog.xiping.me/2011/03/break-gfw-on-android.html</link>
		<comments>http://blog.xiping.me/2011/03/break-gfw-on-android.html#comments</comments>
		<pubDate>Tue, 08 Mar 2011 04:00:36 +0000</pubDate>
		<dc:creator>西坪</dc:creator>
				<category><![CDATA[Tools & Tips]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[opensource]]></category>
		<category><![CDATA[proxy]]></category>
		<category><![CDATA[sshtunnel]]></category>

		<guid isPermaLink="false">http://blog.xiping.me/?p=1019</guid>
		<description><![CDATA[天朝的防火长城越来越牛逼了，我常用的一些网站如 Gmail, Goolgle Search，Google Docs 都很难访问。买了Android手机以后，一直在考虑如何访问这些网站。经过一番苦战，终于搞定，把相关经验写下来分享。
文章比较长，比较有价值的内容包括：

第二部分介绍Opera mini，除了能实现访问抽疯的国外网站外，还能提高访问速度。
第三部分主要介绍SSH Tunnel，能解决DNS污染的问题，并可实现浏览器以及其他非浏览器应用的翻墙访问。

我的手机是Huawei C8500, firmware：2.1-update1, kernel： 2.6.29-perf。
第一阶段：不给力的http_proxy和VPN
最早，我尝试用Android自身的HTTP代理方式。网上有不少帖子读在讨论给Android的一个系统设置表增加http_proxy记录来实现http代理，主要方式包括通过手动使用sqlite3修改data/data/com.google.android.providers.settings/databases/settings.db表，增加http_proxy代理记录（详细参考此文：Tips: Howto Connect Android Emulator behind proxy），如下所示：

./adb shell sqlite3 /DATA/DATA/com.google.android.providers.settings/DATABASES/settings.db
 “\”INSERT INTO system VALUES&#40;99,’http_proxy’,’ &#91;host_or_IP&#93;:&#91;port&#93;‘&#41;;\”&#34;

但经过验证，至少在我的机器上是不行的。
然后又照着这篇文章（[Android] How to set proxy for android browser），写了一个插件直接设置浏览器代理。这个方法试了试，偶尔能行，偶尔不能行。
后来再尝试VPN，试验了几个VPN供应商提供的试用账户，都没有成功。
 第二阶段：翻墙麻利、访问提速的Opera mini 
 Opera mini 是老资历的翻墙工具了，但自从前段时间出了Opera中国版的事情以后，官方版本不支持翻墙了，必须自己破解，并搭建一个IP位于国外的中转服务器。中转服务器其实很简单，只是接收请求，然后用CURL去Opera官方服务器去获取实际内容，再将内容发回。虽然弄一个使用自己的中转服务器的破解版Opera mini比较麻烦，但是搭建起来以后觉得速度相当快。尤其是访问国外几个大站如Google, facebook 和 twitter的移动版，那是相当流畅，远比 Andriod 自带的浏览器流畅。从服务器端Squid代理的日志来看，使用Opera mini访问同一个网页，貌似最终只有一个HTTP请求，图片和JS，CSS等都不用再单独请求了。从日志看，请求数明显减少，网页体积也缩小很多，流量也省不少。
详细参考：

opera mini 翻墙大法 ：此文提供了现成的文件下载，详细指南。
修改Android版Opera Mini的服务器实现翻墙：此文主要讲如何制作使用自己的中转服务器的版本。

搭建php版的中转服务器十分简单，就一个PHP文件，内容如下（文件内容参考自opera mini 翻墙大法提供的文件）：

if &#40;$_SERVER&#91;'REQUEST_METHOD'&#93; == 'GET'&#41; [...]


Related posts:<ol><li><a href='http://blog.xiping.me/2009/03/linux-command-shell-tips-1.html' rel='bookmark' title='Permanent Link: Linux Command &#038; Shell Tips (1)'>Linux Command &#038; Shell Tips (1)</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>天朝的防火长城越来越牛逼了，我常用的一些网站如 Gmail, Goolgle Search，Google Docs 都很难访问。买了Android手机以后，一直在考虑如何访问这些网站。经过一番苦战，终于搞定，把相关经验写下来分享。</p>
<p>文章比较长，比较有价值的内容包括：</p>
<ul>
<li>第二部分介绍Opera mini，除了能实现访问抽疯的国外网站外，还能提高访问速度。</li>
<li>第三部分主要介绍SSH Tunnel，能解决DNS污染的问题，并可实现浏览器以及其他非浏览器应用的翻墙访问。</li>
</ul>
<p>我的手机是Huawei C8500, firmware：2.1-update1, kernel： 2.6.29-perf。</p>
<h3>第一阶段：不给力的http_proxy和VPN</h3>
<p>最早，我尝试用Android自身的HTTP代理方式。网上有不少帖子读在讨论给Android的一个系统设置表增加http_proxy记录来实现http代理，主要方式包括通过手动使用sqlite3修改data/data/com.google.android.providers.settings/databases/settings.db表，增加http_proxy代理记录（详细参考<a href="http://openhandsetmagazine.com/2007/11/tips-howto-connect-android-emulator-behind-proxy/">此文：Tips: Howto Connect Android Emulator behind proxy）</a>，如下所示：</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #66cc66;">./</span>adb shell sqlite3 <span style="color: #66cc66;">/</span><span style="color: #993333; font-weight: bold;">DATA</span><span style="color: #66cc66;">/</span><span style="color: #993333; font-weight: bold;">DATA</span><span style="color: #66cc66;">/</span>com<span style="color: #66cc66;">.</span>google<span style="color: #66cc66;">.</span>android<span style="color: #66cc66;">.</span>providers<span style="color: #66cc66;">.</span>settings<span style="color: #66cc66;">/</span><span style="color: #993333; font-weight: bold;">DATABASES</span><span style="color: #66cc66;">/</span>settings<span style="color: #66cc66;">.</span>db
 “\”<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> system <span style="color: #993333; font-weight: bold;">VALUES</span><span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">99</span><span style="color: #66cc66;">,</span>’http_proxy’<span style="color: #66cc66;">,</span>’ <span style="color: #66cc66;">&#91;</span>host_or_IP<span style="color: #66cc66;">&#93;</span>:<span style="color: #66cc66;">&#91;</span>port<span style="color: #66cc66;">&#93;</span>‘<span style="color: #66cc66;">&#41;</span>;\”<span style="color: #ff0000;">&quot;</span></pre></div></div>

<p>但经过验证，至少在我的机器上是不行的。</p>
<p>然后又照着这篇文章（<a href="http://alexmogurenko.com/blog/programming/android-how-to-set-proxy-for-android-browser/">[Android] How to set proxy for android browser</a>），写了一个插件直接设置浏览器代理。这个方法试了试，偶尔能行，偶尔不能行。</p>
<p>后来再尝试VPN，试验了几个VPN供应商提供的试用账户，都没有成功。</p>
<h3> 第二阶段：翻墙麻利、访问提速的Opera mini </h3>
<p><a href="http://www.opera.com/mobile/"> Opera mini </a>是老资历的翻墙工具了，但自从前段时间出了Opera中国版的事情以后，官方版本不支持翻墙了，必须自己破解，并搭建一个IP位于国外的中转服务器。中转服务器其实很简单，只是接收请求，然后用CURL去Opera官方服务器去获取实际内容，再将内容发回。虽然弄一个使用自己的中转服务器的破解版Opera mini比较麻烦，但是搭建起来以后觉得速度相当快。尤其是访问国外几个大站如Google, facebook 和 twitter的移动版，那是相当流畅，远比 Andriod 自带的浏览器流畅。从服务器端Squid代理的日志来看，使用Opera mini访问同一个网页，貌似最终只有一个HTTP请求，图片和JS，CSS等都不用再单独请求了。从日志看，请求数明显减少，网页体积也缩小很多，流量也省不少。</p>
<p>详细参考：</p>
<ul>
<li><a href="http://zoomao.info/2010/05/05/opera-mini-over-gfw.html">opera mini 翻墙大法</a> ：此文提供了现成的文件下载，详细指南。</li>
<li><a href="http://www.p4cpu.net/2010/08/25/android-opm-modify-server/">修改Android版Opera Mini的服务器实现翻墙</a>：此文主要讲如何制作使用自己的中转服务器的版本。
</ul>
<p>搭建php版的中转服务器十分简单，就一个PHP文件，内容如下（文件内容参考自<a href="http://zoomao.info/2010/05/05/opera-mini-over-gfw.html">opera mini 翻墙大法</a>提供的文件）：</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$_SERVER</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'REQUEST_METHOD'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">==</span> <span style="color: #0000ff;">'GET'</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
       <span style="color: #666666; font-style: italic;">//......</span>
<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$curlInterface</span> <span style="color: #339933;">=</span> <span style="color: #990000;">curl_init</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$headers</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'Connection: Keep-Alive'</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$headers</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'content-type: application/xml'</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$headers</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'User-Agent: Java0'</span><span style="color: #339933;">;</span>
        <span style="color: #990000;">curl_setopt_array</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$curlInterface</span><span style="color: #339933;">,</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
                CURLOPT_URL <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'http://server4.operamini.com'</span><span style="color: #339933;">,</span>
                CURLOPT_HTTPHEADER <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$headers</span><span style="color: #339933;">,</span>
                CURLOPT_POST <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">,</span>
                CURLOPT_POSTFIELDS <span style="color: #339933;">=&gt;</span> <span style="color: #339933;">@</span><span style="color: #990000;">file_get_contents</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'php://input'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$result</span> <span style="color: #339933;">=</span> <span style="color: #990000;">curl_exec</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$curlInterface</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #990000;">curl_close</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$curlInterface</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #990000;">header</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Content-Type: application/octet-stream'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #990000;">header</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Cache-Control: priavte, no-cache'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #b1b100;">echo</span> <span style="color: #000088;">$result</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>顺带提一句，在你翻墙以后（前提是使用第三部分介绍的方式或者其他方式实现443/80端口翻墙以后），你可以使用最新的<a href="https://market.android.com/details?id=com.opera.browser">Opera Mobile 10</a>翻墙。Opera Mobile 10支持手动设置代理，可直接使用国外IP的代理服务器。 Opera Mobile 10 有Android的原生版本，并且不经过Opera的中间服务器代理，你不需要担心安全问题。不过相比较经过中间服务器的Opera mini版本而言，速度慢了不少，且体积庞大，安装完成后有二十几兆大。 </p>
<p>有关<a href="https://market.android.com/details?id=com.opera.browser">Opera Mobile 10</a>的代理设置参考<a href="http://bbs.uc.cn/archiver/?tid-722523.html">这里</a>。</p>
<h3>第三阶段：使用SSH Tunnel为所有80/443端口的访问翻墙</h3>
<p>    但还有一个问题，就是GMS里的一部分应用被墙了，如Gmail，这必须使用能全局代理的代理软件才行。在桌面系统上，有很多工具实现全局代理。其中让系统以socks5代理协议通过SSH隧道就是一种常用方式。SSH隧道在本地服务器与SSH服务器之间建立起一个加密信道，本地系统数据经过这条隧道传递给目标服务器。 这种代理方式所有的内容都经过了加密，并会对流量进行适度压缩。其需要的资源也比较少，只要拥有一个ssh账户就可以实现。<a href="http://www.bitvise.com/port-forwarding">这篇文章 (A short guide to SSH port forwarding) </a>对通过SSH做端口转发做了详细介绍。</p>
<p>    不过在Android系统上，因为系统本身不支持代理设置，尤其像Huawei C8500这样的手机，在Wifi/3G网络的设置中都不能设置代理，必须要有一种方式将本地数据包转发到SSH隧道的本地端口。因为Android是基于Linux的，通常我们可以用iptables来实现数据包的转发。有关iptables的内容，可以参阅一下<a href="http://man.chinaunix.net/network/iptables-tutorial-cn-1.1.19.html">这篇中文指南</a>，了解一些基本知识。</p>
<p>    除此以外，使用端口转发的方式，还需要在服务器端建立一个http代理服务器监听SSH隧道的另一端，接收请求并将请求转给目标服务器，并将处理结果再通过隧道传回给手机。常用的http代理服务器有 <a href="http://www.squid-cache.org/">squid</a>, <a href="http://nginx.org/">nigix</a> 等。</p>
<p>   一开始我找到的是<a href="http://forum.xda-developers.com/showthread.php?t=766569">TransparentProxy</a>， 但这个软件需要手机除了需要支持 iptables外， 内核还需支持 iptables 的 REDIRECT 表。我的手机不支持 redirect，只好作罢。</p>
<p>    然后试了试 <a href="http://code.google.com/p/sshtunnel">SSHTunnel</a>，结果没报告错误，但就是访问不了。 因为这个项目是开源的，翻开代码一看，跟TransparentProxy一样，需要 iptables 的 redirect 支持。 </p>
<p>    尝试了用<a href="http://code.google.com/p/connectbot/"> connectBot</a> 做动态代理，然后再写了个软件将所有端口的内容转发到这个connectBot。转发通过 <a href="http://www.netfilter.org/">iptables</a> 的 DNAT 来实现。不过这样操作起来还是比较麻烦，要开启这两个软件，而且 connectbot 耗电太厉害了，开了一段时间以后，手机发热。</p>
<p>    最后，签出 <a href="http://code.google.com/p/sshtunnel">SSHTunnel</a> 的代码，修改成在内核不支持 redirect 的手机上，自动使用 DNAT 实现转发。问题终于搞定。</p>
<p>    完成后，向该项目提交了这个patch，该项目已经接受<a href="http://code.google.com/p/sshtunnel/issues/detail?id=17">此patch</a>，现在<a href="http://code.google.com/p/sshtunnel">SSHTunnel</a>支持更多的与华为C8500的固件类似的手机了。</p>
<p>     SSH Tunnel 项目主页：<a href="http://code.google.com/p/sshtunnel"><img alt="" src="http://code.google.com/p/sshtunnel/logo?cct=1299552875" title="SSH Tunnel" class="alignnone" width="55" height="55" /></a> 详细使用介绍请去<a href="http://code.google.com/p/sshtunnel/wiki/README">该项目的帮助页面</a>。</p>


<p>Related posts:<ol><li><a href='http://blog.xiping.me/2009/03/linux-command-shell-tips-1.html' rel='bookmark' title='Permanent Link: Linux Command &#038; Shell Tips (1)'>Linux Command &#038; Shell Tips (1)</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://blog.xiping.me/2011/03/break-gfw-on-android.html/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>J2EE/Oracle性能调优实录</title>
		<link>http://blog.xiping.me/2011/02/optimizing-actions.html</link>
		<comments>http://blog.xiping.me/2011/02/optimizing-actions.html#comments</comments>
		<pubDate>Fri, 18 Feb 2011 15:32:32 +0000</pubDate>
		<dc:creator>西坪</dc:creator>
				<category><![CDATA[$Performance]]></category>
		<category><![CDATA[concurrency]]></category>
		<category><![CDATA[io]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[jdbc]]></category>
		<category><![CDATA[lock]]></category>
		<category><![CDATA[oracle]]></category>

		<guid isPermaLink="false">http://blog.xiping.me/?p=1011</guid>
		<description><![CDATA[这两天，有一个新接手的项目性能表现较差，不能满足要求。这个项目在这之前已经写完很久了，但是一些关键部署点一直没有跟上进度。此系统是用Java编写的多线程程序的，主要是从Oracle中读取数据，然后根据业务进行统计运行，在将计算结果放回Oracle中。
这个系统的性能的直观指标，就是每天能处理多少数据量。这个指标很不理想，速度很慢，拖后与现场数据生成的速度。调优的标准，就是每日处理量。
第一次优化: 提高JDBC的fetchSize
首先，分析系统各个环节的时间消耗，弄清瓶颈在哪里。
在进行了一些综合分析后，得出主要时间耗费在数据库的查询上。而从v$session_wait中查询，发现有很多 SQL*Net message from client 事件的等待，时间很长，有数百秒之多。 显然是客户端慢了。但是因为应用端是有连接池的，是不是空闲连接导致的呢？ 有一些怀疑。
接下来，在数据库上用 sqlplus 执行了相同的SQL，测量其时间其实是很快的，远远小于应用消耗在数据获取的时间。联系其上面提到的等待事件，事情变逐渐明朗： 网络传输慢了。 
于是检查了代码，发现大批量的数据查询竟然没有提升fetchSize属性。在调整该属性为500以后，很快收到了正面反馈。处理速度提升了将近一倍。
回去在检查Oracle中的等待事件，发现已经降到200名以外了（是与其他应用共用数据库的）。
有关 sqlnet message from client 事件的分析，可以参考 Asktom 上的文章。 AskTom上的另一篇文章，则描述了类似于连接池等待，或者是在sqlplus中打开会话不操作也会导致该事件。所以在见到这个事件时还是需要仔细甄别一下的。
结论： 适当调整 FetchSize是很有必要的。Oracle JDBC默认的fetchSize为10。FetchSize的提升，一方面是减少了客户端与服务器之间的来回交互次数；另一方面，也会有效减少数据库服务器逻辑读的数量（记得是《Troubleshooting Oracle Performance》中有讲到）。
修改完成后，除了观测到  sqlnet message from client 事件消失外，发现 sys cpu 也有小幅增加。
第二次优化：减小锁定(lock)范围
但是，接下来的观测，证明这个速度还是不合意，达不到要求。于是继续分析。
仍然是分析其主要的时间消耗在什么地方。这次发现时间主要是消耗在程序对数据的处理过程中。数据的处理大部分都是在Java进程中的运算，处理过程中还可能调用到Memcached。是不是网络速度比较慢呢？尝试测试了一下网速，千兆网络的吞吐率在应用并发时还能挤出三分之一左右用来做测试文件的传输，用ping发现其latency也不算高。
在此前的观测中，发现应用服务器上的 user cpu 比较好，在30%～70%之间，主要是被JVM进程消耗了，系统负载在5.0左右。觉得有些奇怪的，因为一般这样的应用瓶颈都出在IO上。于是做了一次代码复查，很快发现有一个在方法签名上的synchronize 关键字。这个类是一个服务bean， 在spring中管理的。这时问题变得清晰起来，所有的处理任务线程都要在这里排队。这样正好符合了此前观测到的cpu现象。
改掉这个关键字，缩小锁定范围，速度又上升了将近一倍。user cpu很快降下来，系统负载也下来了，稍稍大于1。 
此时，速度虽能勉强应付，但还是不够快。此时更多的时间消耗在数据的写回上面。处理速度提升了，写回阶段的压力便也迅速提升，每单位数据的写回时间有20%左右的上浮。于是，需要第三次优化，在数据写回方面提升速度。
第三次优化
(Update Apr 6th):
没心思再仔细写过程了，简略如下：
1) Oracle是多个系统共享的，数据写入成为瓶颈。在内存问题解决后，在本地内存中缓存结果，最后再集中提交，减少更新次数。数度大增2.5倍左右。
2) 将从数据库中的查询和在内存中的处理划分为两个线程并发处理，速度提高50-70%。
3) 然后，Memcached集群成为瓶颈，内网延迟成为问题。但此时速度已经足够快了，因此暂时搁置下一步优化。如果要继续提速，则可能在本地建立一个Memcached实例，或者在程序中使用一个足够大的LRU缓存以减少与Memcached交互的次数。
至此，数据后台处理速度完全达到并超过预期。


Related posts:文件锁与进程互斥
JDBC和Ibatis中的Date,Time,Timestamp处理
Memory leak caused by Proxool and the fix



Related posts:<ol><li><a href='http://blog.xiping.me/2010/01/file-lock-and-jvm-mutex.html' rel='bookmark' title='Permanent Link: 文件锁与进程互斥'>文件锁与进程互斥</a></li>
<li><a href='http://blog.xiping.me/2010/11/jdbc-ibatis-datetimes.html' rel='bookmark' title='Permanent Link: JDBC和Ibatis中的Date,Time,Timestamp处理'>JDBC和Ibatis中的Date,Time,Timestamp处理</a></li>
<li><a href='http://blog.xiping.me/2011/04/memory-leak-caused-by-proxool-and-the-fix.html' rel='bookmark' title='Permanent Link: Memory leak caused by Proxool and the fix'>Memory leak caused by Proxool and the fix</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>这两天，有一个新接手的项目性能表现较差，不能满足要求。这个项目在这之前已经写完很久了，但是一些关键部署点一直没有跟上进度。此系统是用Java编写的多线程程序的，主要是从Oracle中读取数据，然后根据业务进行统计运行，在将计算结果放回Oracle中。</p>
<p>这个系统的性能的直观指标，就是每天能处理多少数据量。这个指标很不理想，速度很慢，拖后与现场数据生成的速度。调优的标准，就是每日处理量。</p>
<h3>第一次优化: 提高JDBC的fetchSize</h3>
<p>首先，分析系统各个环节的时间消耗，弄清瓶颈在哪里。</p>
<p>在进行了一些综合分析后，得出主要时间耗费在数据库的查询上。而从v$session_wait中查询，发现有很多 SQL*Net message from client 事件的等待，时间很长，有数百秒之多。 显然是客户端慢了。但是因为应用端是有连接池的，是不是空闲连接导致的呢？ 有一些怀疑。</p>
<p>接下来，在数据库上用 sqlplus 执行了相同的SQL，测量其时间其实是很快的，远远小于应用消耗在数据获取的时间。联系其上面提到的等待事件，事情变逐渐明朗： 网络传输慢了。 </p>
<p>于是检查了代码，发现大批量的数据查询竟然没有提升fetchSize属性。在调整该属性为500以后，很快收到了正面反馈。处理速度提升了将近一倍。</p>
<p>回去在检查Oracle中的等待事件，发现已经降到200名以外了（是与其他应用共用数据库的）。</p>
<p>有关 sqlnet message from client 事件的分析，可以<a href="http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:366220900346090415">参考 Asktom 上的文章</a>。<a href="http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:223615100346656787"> AskTom上的另一篇文章</a>，则描述了类似于连接池等待，或者是在sqlplus中打开会话不操作也会导致该事件。所以在见到这个事件时还是需要仔细甄别一下的。</p>
<p>结论： 适当调整 FetchSize是很有必要的。Oracle JDBC默认的fetchSize为10。FetchSize的提升，一方面是减少了客户端与服务器之间的来回交互次数；另一方面，也会有效减少数据库服务器逻辑读的数量（记得是<a href="http://www.amazon.com/Troubleshooting-Oracle-Performance-Christian-Antognini/dp/1590599179">《Troubleshooting Oracle Performance》</a>中有讲到）。</p>
<p>修改完成后，除了观测到  sqlnet message from client 事件消失外，发现 sys cpu 也有小幅增加。</p>
<h3>第二次优化：减小锁定(lock)范围</h3>
<p>但是，接下来的观测，证明这个速度还是不合意，达不到要求。于是继续分析。</p>
<p>仍然是分析其主要的时间消耗在什么地方。这次发现时间主要是消耗在程序对数据的处理过程中。数据的处理大部分都是在Java进程中的运算，处理过程中还可能调用到Memcached。是不是网络速度比较慢呢？尝试测试了一下网速，千兆网络的吞吐率在应用并发时还能挤出三分之一左右用来做测试文件的传输，用ping发现其latency也不算高。</p>
<p>在此前的观测中，发现应用服务器上的 user cpu 比较好，在30%～70%之间，主要是被JVM进程消耗了，系统负载在5.0左右。觉得有些奇怪的，因为一般这样的应用瓶颈都出在IO上。于是做了一次代码复查，很快发现有一个在方法签名上的synchronize 关键字。这个类是一个服务bean， 在spring中管理的。这时问题变得清晰起来，所有的处理任务线程都要在这里排队。这样正好符合了此前观测到的cpu现象。</p>
<p>改掉这个关键字，缩小锁定范围，速度又上升了将近一倍。user cpu很快降下来，系统负载也下来了，稍稍大于1。 </p>
<p>此时，速度虽能勉强应付，但还是不够快。此时更多的时间消耗在数据的写回上面。处理速度提升了，写回阶段的压力便也迅速提升，每单位数据的写回时间有20%左右的上浮。于是，需要第三次优化，在数据写回方面提升速度。</p>
<h3>第三次优化</h3>
<p>(Update Apr 6th):<br />
没心思再仔细写过程了，简略如下：<br />
1) Oracle是多个系统共享的，数据写入成为瓶颈。在内存问题解决后，在本地内存中缓存结果，最后再集中提交，减少更新次数。数度大增2.5倍左右。<br />
2) 将从数据库中的查询和在内存中的处理划分为两个线程并发处理，速度提高50-70%。<br />
3) 然后，Memcached集群成为瓶颈，内网延迟成为问题。但此时速度已经足够快了，因此暂时搁置下一步优化。如果要继续提速，则可能在本地建立一个Memcached实例，或者在程序中使用一个足够大的LRU缓存以减少与Memcached交互的次数。</p>
<p>至此，数据后台处理速度完全达到并超过预期。</p>


<p>Related posts:<ol><li><a href='http://blog.xiping.me/2010/01/file-lock-and-jvm-mutex.html' rel='bookmark' title='Permanent Link: 文件锁与进程互斥'>文件锁与进程互斥</a></li>
<li><a href='http://blog.xiping.me/2010/11/jdbc-ibatis-datetimes.html' rel='bookmark' title='Permanent Link: JDBC和Ibatis中的Date,Time,Timestamp处理'>JDBC和Ibatis中的Date,Time,Timestamp处理</a></li>
<li><a href='http://blog.xiping.me/2011/04/memory-leak-caused-by-proxool-and-the-fix.html' rel='bookmark' title='Permanent Link: Memory leak caused by Proxool and the fix'>Memory leak caused by Proxool and the fix</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://blog.xiping.me/2011/02/optimizing-actions.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[译]Chubby — 用于松耦合分布式系统的锁服务</title>
		<link>http://blog.xiping.me/2010/12/google-chubby-in-chinese.html</link>
		<comments>http://blog.xiping.me/2010/12/google-chubby-in-chinese.html#comments</comments>
		<pubDate>Fri, 31 Dec 2010 15:30:55 +0000</pubDate>
		<dc:creator>西坪</dc:creator>
				<category><![CDATA[$算法与计算原理]]></category>
		<category><![CDATA[@Translation]]></category>
		<category><![CDATA[chubby]]></category>
		<category><![CDATA[distributedsystems]]></category>
		<category><![CDATA[nosql]]></category>

		<guid isPermaLink="false">http://blog.feihoo.com/?p=854</guid>
		<description><![CDATA[本文翻译自Google的[The Chubby lock service for loosely-coupled distributed systems]。翻译此文旨在传播更多信息。翻译水平有限，时间少且文章太长了，质量一般。完整版本请阅读原文。如果转载请完整转载，并包含本申明。

摘要
1 简介
2 设计
&#160;&#160;2.1 基础依据(Rationale)
&#160;&#160;2.2 系统结构
&#160;&#160;2.4 锁和序号
&#160;&#160;2.5 事件
&#160;&#160;2.7 缓存
&#160;&#160;2.8 会话 和 KeepAlives
&#160;&#160;2.9 故障切换
&#160;&#160;2.12 镜像 (mirroring) 
3 扩展机制 
4 实际应用，意外和设计错误 
&#160;&#160;4.1 实际应用和表现 
&#160;&#160;4.4 故障切换的问题 
&#160;&#160;4.5 攻击性的客户端 
&#160;&#160;4.6 Lessons learned
5 与相关工作的比较 (Comparison with related work) 
6 总结
7 致谢
参考文献

==========================================================
用于松耦合分布式系统的锁服务Chubby

摘要
我们描述了我们在Chubby锁服务方面的经历。Chubby的目标是为松散耦合的分布式系统，提供粗粒度的锁定、可靠的存储（尽管容量不大）。Chubby提供了一个很像带有意向锁的分布式文件系统的接口（interface)，不过它的设计重点是可用性和可靠性，而不是高性能。许多Chubby服务实例已经使用了超过一年，其中的几个实例每个都同时处理着数万台客户端。本文描述了最初的设计和预期使用，将之与实际的使用相比较，并解释了设计是怎样修改以适应这些差别的。


1. 简介
本文介绍了一种锁服务： Chubby。它被计划用在由适度规模的大量小型计算机通过高速网络互联构成的的松散耦合的分布式系统中。例如，一个Chubby实例（也叫Chubby单元(Cell))可能服务于通过1Gbit/s网络互联的一万台4核计算机。大部分Chubby单元限于一个数据中心或者机房，不过我们运行着至少一个各个副本(replica)之间相隔数千公里的Chubby单元。
锁服务的目的是允许它的客户应用们(clients)同步它们的活动，并对它们所处环境的基本信息取得一致。主要的目标包括在适度大规模的客户应用群时的可靠性、可用性，以及易于理解的语义；吞吐量和存储容量被认为是次要的。Chubby的客户端接口很像这样一个简单的文件系统：能执行整文件的读和写，另外还有意向锁和和多种诸如文件改动等事件的通知。
我们预期Chubby帮助开发者处理他们的系统中的粗粒度同步，特别是处理从一组各方面相当的服务器中选举领导者。例如Google文件系统（Google File System）[7]使用一个Chubby锁来选择GFS Master 服务器，Bigtable[3]以数种方式使用Chbbuy：选择领导者；使得Master可以发现它控制的服务器；使得客户应用(client)可以找到Master。此外，GFS和Bigtable都用Chubby作为众所周知的、可访问的存储小部分元数据(meta-data)的位置；实际上它们用Chubby作为它们的分布式数据结构的根。一些服务使用锁在多个服务器间（在粗粒度级别上）拆分工作。
在Chubby发布之前，Google的大部分分布式系统使用必需的、未提前规划的(ad hoc)方法做主从选举(primary election)（在工作可能被重复单无害时），或者需要人工干预（在正确性至关重要时）。对于前一种情况，Chubby可以节省一些计算能力。对于后一种情况，它使得系统在失败时不再需要人工干预，显著改进了可用性。
熟悉分布式计算的读者会意识到在多个相同体(peer)间primay选举是分布式协同(distributed consensus)问题的一个特例，同时意识到我们需要一种异步（asynchronous）通信的解决方案。异步（asynchronous）这个术语描述了绝大多数真实网络（real networks）如以太网或因特网的行为：它们容许数据包丢失、延时和重排序。（专家们一般应该了解（真实网络的）协议集建立在对环境做了很强假设的模型之上。） 异步一致性由Paxos协议[12, 13]解决了。同样的协议被Oki和Liskov（见于他们有关Viewstamped replication的论文[19, [...]


No related posts.]]></description>
			<content:encoded><![CDATA[

<p>No related posts.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.xiping.me/2010/12/google-chubby-in-chinese.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[译]Redis的事务</title>
		<link>http://blog.xiping.me/2010/12/transaction-in-redis.html</link>
		<comments>http://blog.xiping.me/2010/12/transaction-in-redis.html#comments</comments>
		<pubDate>Tue, 14 Dec 2010 23:47:32 +0000</pubDate>
		<dc:creator>西坪</dc:creator>
				<category><![CDATA[@Translation]]></category>
		<category><![CDATA[nosql]]></category>
		<category><![CDATA[redis]]></category>

		<guid isPermaLink="false">http://blog.xiping.me/?p=910</guid>
		<description><![CDATA[Redis相比于她的一些竞争对手如Memcached,  Tokyo Tyrant等，有一个实在是太吸引人的特性，就是事务。尽管它的事务支持不那么完美，但还是很难得。打算介绍一点使用心得，本想先写个简单介绍，不过觉得官方的文档写得相当不错，我索性做个翻译好了。
声明：本文翻译自Redis官方的MULTI/EXEC命令文档。翻译本文旨在传播更多信息，原著版权为Redis所有。转载请包含此声明。
&#160;

WATCH key1 key2 ... keyN &#40;Redis &#62;= 2.1.0&#41;
UNWATCH
MULTI
COMMAND_1 ...
COMMAND_2 ...
COMMAND_N ...
EXEC or DISCARD

MULTI, EXEC, DISCARD 和 WATCH 命令是Redis事务的基石。一个Redis事务允许一组Redis命令单步执行，并提供下面两个重要保证：

一个事务中的所有命令串行执行。在事务的执行过程中不会为另一个客户端发起的请求提供服务。这保证了事务中的命令以原子操作的方式被执行。
要么全部命令要么没有任何命令被处理。Exec命令触发事务中的所有命令的执行，所以如果一个在事务上下文中的客户端在调用MULTI（译注:貌似应该是EXEC，原文为MULTI）之前丢失了到服务器的链接，没有任何操作会被执行，而如果EXEC命令被调用了，所有的操作都会执行。一个例外是当AOF开启的时候：每个属于某个Redis事务的命令只要操作完成了的话就会记录在AOF中，所以如果Redis服务器崩溃或者被系统管理员以一种粗暴的方式杀死，可能只有部分操作被登记在AOF中。

从Redis 2.1.0开始，以类似于CAS（比较并设置）操作的乐观地锁定一组key的形式，在上面两种保证之外提供更进一步的保证也是可行的。这将在后文中详细阐述。
用法
通过MULTI命令进入一个事务。MULTI总是返回OK。然后用户可以发起多个命令。Redis将这些命令排队，而不是执行它们。一旦EXEC被调用，所有的命令都被执行。
调用DISCARD则将清空队列并退出事务。
下面是一个使用Ruby客户端的例子：

?&#62; r.multi
=&#62; &#34;OK&#34;
&#62;&#62; r.incr &#34;foo&#34;
=&#62; &#34;QUEUED&#34;
&#62;&#62; r.incr &#34;bar&#34;
=&#62; &#34;QUEUED&#34;
&#62;&#62; r.incr &#34;bar&#34;
=&#62; &#34;QUEUED&#34;
&#62;&#62; r.exec
=&#62; &#91;1, 1, 2&#93;

正如从上面的会话能看出来的那样，MULTI返回一个回复&#8221;数组&#8221;，每个元素都是事务中的某一个命令的回复，以命令排队时的顺序排列。
当一个Redis连接处于MULTI请求的上下文中时，所有的命令将用一个简单的字符串“QUEUED”回复，如果它们的语法和参数个数都正确的话。某些命令甚至被允许可在执行期间失败。
在协议层面上这更易于理解；在下面的例子中一个命令将在执行时失败，尽管它的语法是正确的：

Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
MULTI
+OK
SET a 3 
abc
+QUEUED
LPOP a
+QUEUED
EXEC
*2
+OK
-ERR Operation against a key holding the wrong kind [...]


No related posts.]]></description>
			<content:encoded><![CDATA[<p><em>Redis相比于她的一些竞争对手如Memcached,  Tokyo Tyrant等，有一个实在是太吸引人的特性，就是事务。尽管它的事务支持不那么完美，但还是很难得。打算介绍一点使用心得，本想先写个简单介绍，不过觉得<a href="http://code.google.com/p/redis/wiki/MultiExecCommand">官方的文档</a>写得相当不错，我索性做个翻译好了。</em></p>
<p>声明：本文翻译自<a href="http://code.google.com/p/redis">Redis</a>官方的<a href="http://code.google.com/p/redis/wiki/MultiExecCommand">MULTI/EXEC命令文档</a>。翻译本文旨在传播更多信息，原著版权为<a href="http://code.google.com/p/redis">Redis</a>所有。转载请包含此声明。</p>
<p>&nbsp;</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">WATCH key1 key2 ... <span style="color:#9900CC;">keyN</span> <span style="color:#006600; font-weight:bold;">&#40;</span>Redis <span style="color:#006600; font-weight:bold;">&gt;</span>= 2.1.0<span style="color:#006600; font-weight:bold;">&#41;</span>
UNWATCH
MULTI
COMMAND_1 ...
<span style="color:#9900CC;">COMMAND_2</span> ...
<span style="color:#9900CC;">COMMAND_N</span> ...
<span style="color:#CC0066; font-weight:bold;">EXEC</span> <span style="color:#9966CC; font-weight:bold;">or</span> DISCARD</pre></div></div>

<p>MULTI, EXEC, DISCARD 和 WATCH 命令是Redis事务的基石。一个Redis事务允许一组Redis命令单步执行，并提供下面两个重要保证：</p>
<ol>
<li>一个事务中的所有命令串行执行。在事务的执行过程中不会为另一个客户端发起的请求提供服务。这保证了事务中的命令以原子操作的方式被执行。</li>
<li>要么全部命令要么没有任何命令被处理。Exec命令触发事务中的所有命令的执行，所以如果一个在事务上下文中的客户端在调用MULTI（译注:貌似应该是EXEC，原文为MULTI）之前丢失了到服务器的链接，没有任何操作会被执行，而如果EXEC命令被调用了，所有的操作都会执行。一个例外是当AOF开启的时候：每个属于某个Redis事务的命令只要操作完成了的话就会记录在AOF中，所以如果Redis服务器崩溃或者被系统管理员以一种粗暴的方式杀死，可能只有部分操作被登记在AOF中。</li>
</ol>
<p>从Redis 2.1.0开始，以类似于CAS（比较并设置）操作的乐观地锁定一组key的形式，在上面两种保证之外提供更进一步的保证也是可行的。这将在后文中详细阐述。</p>
<h3>用法</h3>
<p>通过MULTI命令进入一个事务。MULTI总是返回OK。然后用户可以发起多个命令。Redis将这些命令排队，而不是执行它们。一旦EXEC被调用，所有的命令都被执行。</p>
<p>调用DISCARD则将清空队列并退出事务。</p>
<p>下面是一个使用Ruby客户端的例子：</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">?<span style="color:#006600; font-weight:bold;">&gt;</span> r.<span style="color:#9900CC;">multi</span>
<span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;OK&quot;</span>
<span style="color:#006600; font-weight:bold;">&gt;&gt;</span> r.<span style="color:#9900CC;">incr</span> <span style="color:#996600;">&quot;foo&quot;</span>
<span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;QUEUED&quot;</span>
<span style="color:#006600; font-weight:bold;">&gt;&gt;</span> r.<span style="color:#9900CC;">incr</span> <span style="color:#996600;">&quot;bar&quot;</span>
<span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;QUEUED&quot;</span>
<span style="color:#006600; font-weight:bold;">&gt;&gt;</span> r.<span style="color:#9900CC;">incr</span> <span style="color:#996600;">&quot;bar&quot;</span>
<span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;QUEUED&quot;</span>
<span style="color:#006600; font-weight:bold;">&gt;&gt;</span> r.<span style="color:#CC0066; font-weight:bold;">exec</span>
<span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">1</span>, <span style="color:#006666;">1</span>, <span style="color:#006666;">2</span><span style="color:#006600; font-weight:bold;">&#93;</span></pre></div></div>

<p>正如从上面的会话能看出来的那样，MULTI返回一个回复&#8221;数组&#8221;，每个元素都是事务中的某一个命令的回复，以命令排队时的顺序排列。</p>
<p>当一个Redis连接处于MULTI请求的上下文中时，所有的命令将用一个简单的字符串“QUEUED”回复，如果它们的语法和参数个数都正确的话。某些命令甚至被允许可在执行期间失败。</p>
<p>在协议层面上这更易于理解；在下面的例子中一个命令将在执行时失败，尽管它的语法是正确的：</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">Trying 127.0.0.1...
<span style="color:#9900CC;">Connected</span> to localhost.
<span style="color:#9900CC;">Escape</span> character is <span style="color:#996600;">'^]'</span>.
<span style="color:#9900CC;">MULTI</span>
<span style="color:#006600; font-weight:bold;">+</span>OK
SET a <span style="color:#006666;">3</span> 
abc
<span style="color:#006600; font-weight:bold;">+</span>QUEUED
LPOP a
<span style="color:#006600; font-weight:bold;">+</span>QUEUED
<span style="color:#CC0066; font-weight:bold;">EXEC</span>
<span style="color:#006600; font-weight:bold;">*</span><span style="color:#006666;">2</span>
<span style="color:#006600; font-weight:bold;">+</span>OK
<span style="color:#006600; font-weight:bold;">-</span>ERR Operation against a key holding the wrong kind of value</pre></div></div>

<p>MULTI 返回一个两个元素的组合回复(bulk reply)，其中一个是 +OK码，另一个是 -ERR回复。这中情况下将由客户端库来选择一种合理的方式将错误提供给用户。</p>
<blockquote><p>重要提示：即使在一个命令将会抛出错误时，队列中的所有其他的命令仍将被处理。在发现错误时，Redis不会停止命令的处理。</p></blockquote>
<p>这是另一个例子，仍旧使用telnet的写协议，展示了语法错误会被尽可能快地报告：</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">MULTI
+OK
INCR a b c
<span style="color: #660033;">-ERR</span> wrong number of arguments <span style="color: #000000; font-weight: bold;">for</span> <span style="color: #ff0000;">'incr'</span> <span style="color: #7a0874; font-weight: bold;">command</span></pre></div></div>

<p>这次由于语法错误，有问题的INCR命令根本不会被排队。</p>
<h3> DISCARD </h3>
<p>DISCARD用于放弃一个事务。没有命令将被执行，客户端的状态重新变回正常，在事务之外。这是个使用Ruby客户端的例子：</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">?<span style="color:#006600; font-weight:bold;">&gt;</span> r.<span style="color:#9900CC;">set</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;foo&quot;</span>,<span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#41;</span>
<span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0000FF; font-weight:bold;">true</span>
<span style="color:#006600; font-weight:bold;">&gt;&gt;</span> r.<span style="color:#9900CC;">multi</span>
<span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;OK&quot;</span>
<span style="color:#006600; font-weight:bold;">&gt;&gt;</span> r.<span style="color:#9900CC;">incr</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;foo&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
<span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;QUEUED&quot;</span>
<span style="color:#006600; font-weight:bold;">&gt;&gt;</span> r.<span style="color:#9900CC;">discard</span>
<span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;OK&quot;</span>
<span style="color:#006600; font-weight:bold;">&gt;&gt;</span> r.<span style="color:#9900CC;">get</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;foo&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
<span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;1&quot;</span></pre></div></div>

<h3>基于WATCH的比较并设置(CAS)事务</h3>
<p>WATCH(观察)用于给Redis事务提供CAS(比较并操作）行为。</p>
<p>调用了WATCH命令(WATCHed)的键将被监视以侦测针对键的修改。如果至少有一个监视的键在EXEC调用之前被修改，整个事务将被放弃，EXEC调用将会返回一个空对象(nil object)(一个Null Multi Bulk回复)来通知客户端事务失败了。</p>
<p>例如想象我们需要给一个键的值原子增一（我知道有INCR，让我们假设我们没有它）。</p>
<p>首先我们可能会像这样尝试:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">val = GET mykey
val = val <span style="color:#006600; font-weight:bold;">+</span> <span style="color:#006666;">1</span>
SET mykey <span style="color:#ff6633; font-weight:bold;">$val</span></pre></div></div>

<p>这只在一个给定时间内只有一个客户端做这个操作时可靠地工作。如果多个客户端将在大约同一时间内递增这个键，将会出现竞争条件(race condition)。例如客户端A和B将读到旧值，例如10。这个值将被这两个客户端递增到11，并最终设置这个键的值。于是最后的值将是11，而不是12。</p>
<p>多亏了WATCH，我们能够很好地解决这个问题：</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">WATCH mykey
val = GET mykey
val = val <span style="color:#006600; font-weight:bold;">+</span> <span style="color:#006666;">1</span>
MULTI
SET mykey <span style="color:#ff6633; font-weight:bold;">$val</span>
<span style="color:#CC0066; font-weight:bold;">EXEC</span></pre></div></div>

<p>使用上面的代码，如果存在竞争条件并且另一个客户端在我们调用WATCH和EXEC之间修改了val的结果，事务将会失败。</p>
<p>我们只需要重复这个操作，寄希望于这次没有新的竞争。这种锁定形式叫做乐观锁定，并且在面对许多有多个客户端同时访问数目庞大的键的问题时，是一种十分强大的锁定形式，这种情况下冲突的可能性是很小的：通常操作不需要执行很多次。</p>
<h3>WATCH的解释</h3>
<p>那WATCH到底是什么呢？它是一个将使得EXEC受到约束的命令：我们要求Redis只在没有别的客户端修改任何一个被监视的键时执行事务。否则，根本就不会开始事务。（注意如果你监视(WATCH)一个瞬时的键，然后Redis在你监视了这个键后，将这个键过期(expire)了，EXEC仍将继续生效。<a href="http://code.google.com/p/redis/issues/detail?id=270">更多信息</a>）</p>
<p>WATCH可以被调用很多次。很简单地，所有的WATCH调用都将从调用时开始监视修改，直到EXEC被调用那一刻。</p>
<p>当EXEC被调用时，不管它是成功还是失败，所有的键都不再被监视。同样当一个客户连接被关闭时，所有的key不再被监视。</p>
<p>也可使用UNWATCH命令（没有参数）来清除被监视的键。有时这是有用的：因为可能我们需要执行一个事务来修改一些键，我们乐观锁定了这些键，但是在读取了这些键的当前内容后我们不想继续修改这些键了。这是我们只需要调用UNWATCH，于是这个连接就能够自由地用于新事务了。</p>
<h3>WATCH用于实现ZPOP</h3>
<p>一个很好的展示WATCH可被用于创建Redis不直接支持的新原子操作的例子是实现ZPOP，这是一个从有序集合(sorted set)中以原子方式弹出(pop)分数权值(score)较低的元素的命令。下面这是最简单的实现：</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">WATCH zset
ele = ZRANGE zset <span style="color:#006666;">0</span> <span style="color:#006666;">0</span>
MULTI
ZREM zset ele
<span style="color:#CC0066; font-weight:bold;">EXEC</span></pre></div></div>

<p>如果EXEC失败了(返回一个nil值)，我们只需要重复上面的操作。</p>
<h3>返回值</h3>
<p>多组合(Multi bulk)回复, 特别地:</p>
<p>一个MULTI/EXEC命令的返回值是一个多组合回复(multi bulk reply)，其中的每个元素是原子事务中的每个命令的返回值。</p>
<p>如果一个MULTI/EXEC事务因为监视命令(WATCH)检测到有键被修改了，返回一个空多组合回复(Null Multi Bulk reply)。</p>


<p>No related posts.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.xiping.me/2010/12/transaction-in-redis.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Java中的Volatile关键字</title>
		<link>http://blog.xiping.me/2010/12/java-volatile-is-not-so-evil.html</link>
		<comments>http://blog.xiping.me/2010/12/java-volatile-is-not-so-evil.html#comments</comments>
		<pubDate>Mon, 13 Dec 2010 04:12:09 +0000</pubDate>
		<dc:creator>西坪</dc:creator>
				<category><![CDATA[$Performance]]></category>
		<category><![CDATA[concurrency]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[volatile]]></category>

		<guid isPermaLink="false">http://blog.feihoo.com/?p=193</guid>
		<description><![CDATA[前两天，并行实验室发表了一篇有关volatile关键字的文章[1]，而该文参考文献中的Sayonara volatile[2]则更直接地要与volatile再见。两篇文章不谋而合，从c/c++到Java/.net，将这几门语言中的volatile过了一遍。列举出各种乱象，看上去volatile是如此不堪。
确实，volatile的语义不是那么常见。不是锁，但是它又拥有锁的部分特性（可见性，Java 5以后还有顺序保证）。如果不能正确理解，确实是个容易出错的地方。但是如果理解了用对了，仅就Java 5以及以后的版本而言，在目前阶段，volatile对性能上的提升还是有帮助的。
Volatile在Java中的语义以及历史
在维基百科上，对Java中的Volatile给了一个准确的定义[6]：

(In all versions of Java) There is a global ordering on the reads and writes to a volatile variable. This implies that every thread accessing a volatile field will read its current value before continuing, instead of (potentially) using a cached value. (However, there is no guarantee about the relative ordering of [...]


Related posts:<ol><li><a href='http://blog.xiping.me/2011/03/java-serialize-and-reflection.html' rel='bookmark' title='Permanent Link: 解决Java序列化的版本冲突'>解决Java序列化的版本冲突</a></li>
<li><a href='http://blog.xiping.me/2009/10/dynamic-programming-problem-1.html' rel='bookmark' title='Permanent Link: 动态规划练习（一）: 求数列中连续数字之和的最大值'>动态规划练习（一）: 求数列中连续数字之和的最大值</a></li>
<li><a href='http://blog.xiping.me/2009/10/%e7%bb%86%e8%8a%82%e8%83%8c%e5%90%8e%ef%bc%9a%e4%b8%ba%e4%bb%80%e4%b9%88%e7%ba%bf%e7%a8%8b%e5%8d%8f%e4%bd%9c%e4%b9%8b%e5%89%8d%e5%bf%85%e9%a1%bb%e5%85%88%e8%8e%b7%e5%be%97%e9%94%81.html' rel='bookmark' title='Permanent Link: 细节背后：为什么线程协作之前必须先获得锁?'>细节背后：为什么线程协作之前必须先获得锁?</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>前两天，<a href="http://www.parallellabs.com">并行实验室</a>发表了一篇有关volatile关键字的<a href="http://www.parallellabs.com/2010/12/04/why-should-we-be-care-of-volatile-keyword-in-multithreaded-applications/">文章</a><sup>[1]</sup>，而该文参考文献中的<a href="http://www.bluebytesoftware.com/blog/PermaLink,guid,a0484627-c752-45f6-a2ac-414130cb3d2f.aspx">Sayonara volatile</a><sup>[2]</sup>则更直接地要与volatile再见。两篇文章不谋而合，从c/c++到Java/.net，将这几门语言中的volatile过了一遍。列举出各种乱象，看上去volatile是如此不堪。</p>
<p>确实，volatile的语义不是那么常见。不是锁，但是它又拥有锁的部分特性（可见性，Java 5以后还有顺序保证）。如果不能正确理解，确实是个容易出错的地方。但是如果理解了用对了，仅就Java 5以及以后的版本而言，在目前阶段，volatile对性能上的提升还是有帮助的。</p>
<h3>Volatile在Java中的语义以及历史</h3>
<p>在<a href="http://en.wikipedia.org/wiki/Volatile_variable#In_Java">维基百科上，对Java中的Volatile给了一个准确的定义</a><sup>[6]</sup>：</p>
<ul>
<li>(In all versions of Java) There is a global ordering on the reads and writes to a volatile variable. This implies that every thread accessing a volatile field will read its current value before continuing, instead of (potentially) using a cached value. (However, there is no guarantee about the relative ordering of volatile reads and writes with regular reads and writes, meaning that it&#8217;s generally not a useful threading construct.)</li>
<li>
(In Java 5 or later) Volatile reads and writes establish a happens-before relationship, much like acquiring and releasing a mutex.</li>
</ul>
<p>翻译过来就是：</p>
<ul>
<li>(在所有的Java版本中)对volatile变量上的读和写有一个全局排序。这暗示着每个线程访问一个volatile域时在往下运行之前将读到当前的值，而不是(有可能)使用一个缓存值。(然而，在volatie变量的读写与常规的读写之间的排序没有保证，意味着volatile通常不是一个有用的线程化的构造)</li>
<li>(在Java5及之后版本中) Volatile读和写建立了一种happens-before关系，就像获取和释放一个互斥体。</li>
</ul>
<p>在Java中，要正确地并发，必须在原子性、可见性和顺序性三个方面做出保证。在Java 5以前的版本中，volatile就已经实现了可见性，但是因为不能保证与普通变量读写之间的顺序，故而经常是没有用的。在Java 5以后的版本中，则额外保证了其与普通变量读写的顺序性。这里不是特别好懂，我们将javamx上的例子<sup>[3] [4]</sup>改造一下：</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> MyBrokenFactory <span style="color: #009900;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000000; font-weight: bold;">volatile</span> MyFactory instance<span style="color: #339933;">;</span>
  <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000066; font-weight: bold;">int</span> field1, field2 ...
&nbsp;
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> MyBrokenFactory getFactory<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">// This is incorrect: don't do it at home, kids!</span>
    <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>instance <span style="color: #339933;">==</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #000000; font-weight: bold;">synchronized</span> <span style="color: #009900;">&#40;</span>MyBrokenFactory.<span style="color: #000000; font-weight: bold;">class</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>instance <span style="color: #339933;">==</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span>
          instance <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> MyBrokenFactory<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #000000; font-weight: bold;">return</span> instance<span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">private</span> MyBrokenFactory<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    field1 <span style="color: #339933;">=</span> ...
    <span style="color: #006633;">field2</span> <span style="color: #339933;">=</span> ...
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>上面的代码，在Java5以前，这个例子是不能正确工作的，因为volatile不保证对field1,field2的初始化（常规读写）一定在对volatile变量instance的写之前完成。但双检查锁本身并非volatile导致的，反而是Java 1.5的volatile让双检查锁能正确工作了。<a href="http://www.parallellabs.com">并行实验室</a>将双检查锁不正确算在volatile的头上，有点冤了。</p>
<p>正是因为volatile在Java 5以前没有得到正确实现，更添加了不少复杂性。在Java 5之前，volatile基本没用处。</p>
<h3>Volatile的实现机制分析</h3>
<p>在Hotspot JVM中，<br />
a) 在JVM层次，对volatile变量在线程本地工作区中不做缓存，对volatile的读写总是指向堆中的引用。可以视作在一个assign指令后总是跟着一个store指令<sup>[5]</sup>。<br />
b) 在机器码执行层次，通过内存屏障指令等迫使CPU不重排序，清除缓存，详细请参考《<a href="http://www.infoq.com/articles/memory_barriers_jvm_concurrency">Memory Barriers and JVM Concurrency</a>》的分析。</p>
<p>这与synchronized是有明显不同的，synchronized通常需要原子锁定，在SMP上要通过锁定总线等方式来实现，其代价在大多数平台上通常要比volatile高得多。</p>
<h3>Performance</h3>
<p><img alt="图一运行100万次" src="http://chart.apis.google.com/chart?cht=lc&#038;chtt=Total+time+for+1000000+times&#038;chs=500x300&#038;chxt=y&#038;chxr=0,0,1131&#038;chds=0,1131&#038;chd=t:72,68,85,61,66,126,70,59,49,54|800,1131,845,770,781,861,928,858,866,907|107,112,94,129,121,103,102,107,120,92&#038;chdl=V1(volatile)|V2(Synchronized)|V3(AtomicLong)&#038;chco=FF0000,00FF00,0000FF" title="图一运行100万次" class="alignright" width="500" height="300" /><br />
引入Volatile的主要目的，就是为了性能。我分下面几个方面来谈谈volatile在目前的Java平台中的作用。</p>
<h4>直接性能比较</h4>
<p>简单写了一个测试来比较一下volatile以及它的两种替代品  &#8212; 原子类型(atomic)和锁(此处指synchronized)。例子的代码改编自<a href="http://www.blogjava.net/killme2008">庄周梦蝶</a>的<a href="http://www.blogjava.net/killme2008/archive/2010/11/22/338420.html">slides《Java NIO trick and trap》</a>中的SystemTimer（部分代码省略，完整源码在<a href="https://github.com/Jeffliu/misc/tree/master/java-volatile-test">Github</a>上）。这个测试只是一个例子，但其实在网络库里都要做定时，原理也大抵如此。</p>
<p>第一个版本如下：</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">package</span> <span style="color: #006699;">me.xiping.volitileverify</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> SystemTimerV1 <span style="color: #009900;">&#123;</span>
	<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">final</span> <span style="color: #000000; font-weight: bold;">static</span> ScheduledExecutorService executor <span style="color: #339933;">=</span> Executors.<span style="color: #006633;">newSingleThreadScheduledExecutor</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000000; font-weight: bold;">final</span> <span style="color: #000066; font-weight: bold;">long</span> tickUnit <span style="color: #339933;">=</span> <span style="color: #003399;">Long</span>.<span style="color: #006633;">parseLong</span><span style="color: #009900;">&#40;</span><span style="color: #003399;">System</span>.<span style="color: #006633;">getProperty</span><span style="color: #009900;">&#40;</span>
			<span style="color: #0000ff;">&quot;notify.systimer.tick&quot;</span>, <span style="color: #0000ff;">&quot;50&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000000; font-weight: bold;">volatile</span> <span style="color: #000066; font-weight: bold;">long</span> time <span style="color: #339933;">=</span> <span style="color: #003399;">System</span>.<span style="color: #006633;">currentTimeMillis</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000000; font-weight: bold;">class</span> TimerTicker <span style="color: #000000; font-weight: bold;">implements</span> <span style="color: #003399;">Runnable</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> run<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			time <span style="color: #339933;">=</span> <span style="color: #003399;">System</span>.<span style="color: #006633;">currentTimeMillis</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000066; font-weight: bold;">long</span> currentTimeMillis<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000000; font-weight: bold;">return</span> time<span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">static</span> <span style="color: #009900;">&#123;</span>
		executor.<span style="color: #006633;">scheduleAtFixedRate</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> TimerTicker<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>, tickUnit, tickUnit,
				TimeUnit.<span style="color: #006633;">MILLISECONDS</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #003399;">Runtime</span>.<span style="color: #006633;">getRuntime</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">addShutdownHook</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">Thread</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			@Override
			<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> run<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
				executor.<span style="color: #006633;">shutdown</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			<span style="color: #009900;">&#125;</span>
		<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>代码的重点在于volatile修饰的time域。time是一个只有一个线程写，其他线程都是读的域，没有并发修改，这里要解决的就是可见性。这正是volatile最适合的场合。</p>
<p>第二个版本使用synchronize关键字，与版本V1的不同如下：</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">package</span> <span style="color: #006699;">me.xiping.volitileverify</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> SystemTimerV2 <span style="color: #009900;">&#123;</span>
	....
	<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000066; font-weight: bold;">long</span> time <span style="color: #339933;">=</span> <span style="color: #003399;">System</span>.<span style="color: #006633;">currentTimeMillis</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000000; font-weight: bold;">class</span> TimerTicker <span style="color: #000000; font-weight: bold;">implements</span> <span style="color: #003399;">Runnable</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> run<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			<span style="color: #000000; font-weight: bold;">synchronized</span> <span style="color: #009900;">&#40;</span>SystemTimerV2.<span style="color: #000000; font-weight: bold;">class</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
				time <span style="color: #339933;">=</span> <span style="color: #003399;">System</span>.<span style="color: #006633;">currentTimeMillis</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			<span style="color: #009900;">&#125;</span>
		<span style="color: #009900;">&#125;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000000; font-weight: bold;">synchronized</span> <span style="color: #000066; font-weight: bold;">long</span> currentTimeMillis<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000000; font-weight: bold;">return</span> time<span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
	....
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>第二个版本使用Java的内部锁来同步，既保证了原子性，也保证了可见性。第三个版本则是使用AtomicLong来实现的，如下：</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">package</span> <span style="color: #006699;">me.xiping.volitileverify</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> SystemTimerV3 <span style="color: #009900;">&#123;</span>
	......
	<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">static</span> AtomicLong time <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> AtomicLong<span style="color: #009900;">&#40;</span><span style="color: #003399;">System</span>.<span style="color: #006633;">currentTimeMillis</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000000; font-weight: bold;">class</span> TimerTicker <span style="color: #000000; font-weight: bold;">implements</span> <span style="color: #003399;">Runnable</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> run<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			time.<span style="color: #006633;">set</span><span style="color: #009900;">&#40;</span><span style="color: #003399;">System</span>.<span style="color: #006633;">currentTimeMillis</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000066; font-weight: bold;">long</span> currentTimeMillis<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000000; font-weight: bold;">return</span> time.<span style="color: #006633;">get</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
	.....
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>在我的本上(cpu: 2core; OS: win7/cygwin; java:1.6.0_13)运行100万次，其性能如上面右图一所示(单位:ms)。<br />
<img alt="图二运行1千万次" src="http://chart.apis.google.com/chart?cht=lc&#038;chtt=Total+time+for+10000000+times&#038;chs=500x300&#038;chxt=y&#038;chxr=0,0,9909&#038;chds=0,4000&#038;chd=t:175,216,192,137,129,160,201,136,140,146|3656,3768,3999,3411,3377,3634,3426,3471,3617,3251|409,437,290,317,334,282,349,310,365,299&#038;chdl=V1(volatile)|V2(Synchronized)|V3(AtomicLong)&#038;chco=FF0000,00FF00,0000FF" title="图二运行1千万次" class="alignright"  width="500" height="300" /><br />
运行1000万次性能如图二所示(注意纵坐标的值与图一不一样)。</p>
<p>结论：性能上的优越性是显而易见的。volatile比AtomicLong明细要快，相比于synchronized则有几倍几十倍的提高了。<br />
（欢迎在不同平台下测试并在评论中给一个反馈，反馈时请包括处理器信息（平台，core数），OS和Java版本。源代码在<a href="https://github.com/Jeffliu/misc/tree/master/java_volitile_test/">这里</a>。编译和运行需要Ant，具体指南请参考<a href="https://github.com/Jeffliu/misc/blob/master/java-volatile-test/README">这里</a>。）</p>
<p>[<strong>Update, Dec15th</strong>： 图片是用<a href="http://chart.apis.google.com">Google Chart API</a> 生成的，在<a href="https://github.com/Jeffliu/misc/tree/master/java_volitile_test/">源代码</a>中包含着两个自动执行测试并生成图片URL的脚本。脚本需运行在Bash环境下，Windows上需在<a href="http://www.cygwin.com">Cygwin</a>下运行。]</p>
<h4>Mina/netty对volatile的利用</h4>
<p>写博文时顺便统计了下volatile在一些性能比较重要的程序中的情况，我顺手统计了手边有的mina和netty两个项目的核心代码，数据如下：</p>
<table>
<tr>
<th>Project</th>
<th>sources path</th>
<th>synchronized occurrence</th>
<th>volatile occurrence</th>
</tr>
<tr>
<td>netty</td>
<td>src/main/java</td>
<td>150</td>
<td>177</td>
</tr>
<tr>
<td>mina</td>
<td>src/main/java</td>
<td>216</td>
<td>55</td>
</tr>
</table>
<p>其中，mina是2009-3-31日Subversion的trunk，如下：</p>

<div class="wp_syntax"><div class="code"><pre class="sh" style="font-family:monospace;">$svn info
Path: .
URL: http://svn.apache.org/repos/asf/mina/trunk
Repository Root: http://svn.apache.org/repos/asf
Repository UUID: 13f79535-47bb-0310-9956-ffa450edef68
Revision: 761900
Node Kind: directory
Schedule: normal
Last Changed Author: jvermillard
Last Changed Rev: 760493
Last Changed Date: 2009-03-31 23:49:15 +0800 (Tue, 31 Mar 2009)</pre></div></div>

<p>netty的版本信息是：</p>

<div class="wp_syntax"><div class="code"><pre class="sh" style="font-family:monospace;">$git log
commit 1ffb1aea75c36def56b709bd0892b19df78d9249
Author: Trustin Lee &lt;trustin@gmail.com&gt;
Date:   Fri Nov 12 10:20:03 2010 +0900</pre></div></div>

<p>从侧面证明了volatile其实是很重要的，在性能很重要的场合，应用还是比较多的。</p>
<h3>结论</h3>
<p>总而言之，相比与Atomic和synchronized，volatile在性能上还是有显著的优势。</p>
<p>不过，正如文章中开头讨论的那样，volatile的缺点也显而易见，需要开发者对volatile的应用需要对内存模型的理解，否则容易误解而造成错误。在并发程序中，其仅可用于JVM支持的几个基本类型(int,short,long,double,reference, etc.)，而这几个基本类型皆有对应的完整并发特性的包装原子类型(java.util.concurrent.atomic.*)，虽然其性能与volatile有些差距，但大部分情形下也可代替volatile（<strong>但用synchronized来代替volatile是很不划算的</strong>）。</p>
<ol>
<li><a href="http://www.parallellabs.com/2010/12/04/why-should-we-be-care-of-volatile-keyword-in-multithreaded-applications/">为什么在多核多线程程序中要慎用volatile关键字？</a></li>
<li><a href="http://www.bluebytesoftware.com/blog/PermaLink,guid,a0484627-c752-45f6-a2ac-414130cb3d2f.aspx">Sayonara volatile</a></li>
<li><a href="http://www.javamex.com/tutorials/double_checked_locking.shtml">Double-checked Locking (DCL) and how to fix it</a></li>
<li><a href="http://www.javamex.com/tutorials/double_checked_locking_fixing.shtml">Double-checked Locking (DCL) and how to fix it (ctd)</a></li>
<li><a href="http://java.sun.com/docs/books/jvms/second_edition/html/Threads.doc.html">JVM specification#Threads and Locks</a></li>
<li><a href="http://en.wikipedia.org/wiki/Volatile_variable#In_Java">Volatile variable#Java</a></li>
<li>http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html</li>
<li><a href="http://www.infoq.com/articles/memory_barriers_jvm_concurrency">Memory Barriers and JVM Concurrency</a></li>
</ol>


<p>Related posts:<ol><li><a href='http://blog.xiping.me/2011/03/java-serialize-and-reflection.html' rel='bookmark' title='Permanent Link: 解决Java序列化的版本冲突'>解决Java序列化的版本冲突</a></li>
<li><a href='http://blog.xiping.me/2009/10/dynamic-programming-problem-1.html' rel='bookmark' title='Permanent Link: 动态规划练习（一）: 求数列中连续数字之和的最大值'>动态规划练习（一）: 求数列中连续数字之和的最大值</a></li>
<li><a href='http://blog.xiping.me/2009/10/%e7%bb%86%e8%8a%82%e8%83%8c%e5%90%8e%ef%bc%9a%e4%b8%ba%e4%bb%80%e4%b9%88%e7%ba%bf%e7%a8%8b%e5%8d%8f%e4%bd%9c%e4%b9%8b%e5%89%8d%e5%bf%85%e9%a1%bb%e5%85%88%e8%8e%b7%e5%be%97%e9%94%81.html' rel='bookmark' title='Permanent Link: 细节背后：为什么线程协作之前必须先获得锁?'>细节背后：为什么线程协作之前必须先获得锁?</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://blog.xiping.me/2010/12/java-volatile-is-not-so-evil.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Impdp/Expdp 之并行(Parallel)和压缩(Compression)</title>
		<link>http://blog.xiping.me/2010/12/oracle-impdpexpdp-parallel-compression.html</link>
		<comments>http://blog.xiping.me/2010/12/oracle-impdpexpdp-parallel-compression.html#comments</comments>
		<pubDate>Thu, 09 Dec 2010 04:33:10 +0000</pubDate>
		<dc:creator>西坪</dc:creator>
				<category><![CDATA[$Programming]]></category>
		<category><![CDATA[datadump]]></category>
		<category><![CDATA[oracle]]></category>

		<guid isPermaLink="false">http://blog.xiping.me/?p=873</guid>
		<description><![CDATA[需要从远程数据库上导数据过来，但数据量不小，传输起来估计要花不少时间。看了下手册，Oracle 11g的expdp有下面几个比较符合这种情况的特性：

Query: 使用Query过滤巨大表中要导出的数据。要注意的是指定query的语法，尤其是在shell下特殊字符的转义问题。
Compression: 压缩数据。在11g中，有个compression选项，可以选择压缩 {ALL &#124; DATA_ONLY &#124; METADATA_ONLY &#124; NONE}。在Oracle 11g中，不能像exp一样使用pipe给gzip的方式压缩了，要用gzip的话必须手动gzip。
Parallel: 并行选项，在启用压缩时感觉效率有所提升。

下面是一个例子，使用 BLOCKS 方法的总估计: 2.159 GB，实际压缩后仅仅剩下 28M左右（因某些数据我通过Query限制了，压缩前实际大小可能在300M左右，且数据比较特殊）。 更具普遍性的压缩效果可参考这篇文章（需翻墙）。该文也比较了使用gzip与使用compression参数的压缩效果。
一个实际的例子，导出：

expdp dbaname/dbapwd DUMPFILE=expdumps%u.dmp DIRECTORY=DPUMP_DIR  TABLES='(T1,T2,T3)' 
\QUERY=T1:\&#34;where mod\(ID,10\)=0\&#34;,T2:\&#34;where mod\(ID,5\)=0\&#34; PARALLEL=4 COMPRESSION=ALL

导入：

impdp dbaname/dbapwd DIRECTORY=dpump_dir1 DUMPFILE=expdumps%U.dmp

详细信息参考Oracle手册相关内容。


Related posts:2011, 掌握一门新语言：Erlang



Related posts:<ol><li><a href='http://blog.xiping.me/2011/04/2011-study-a-multi-core-lang.html' rel='bookmark' title='Permanent Link: 2011, 掌握一门新语言：Erlang'>2011, 掌握一门新语言：Erlang</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>需要从远程数据库上导数据过来，但数据量不小，传输起来估计要花不少时间。看了下手册，Oracle 11g的expdp有下面几个比较符合这种情况的特性：</p>
<ul>
<li>Query: 使用Query过滤巨大表中要导出的数据。要注意的是指定query的语法，尤其是在shell下特殊字符的转义问题。</li>
<li>Compression: 压缩数据。在11g中，有个compression选项，可以选择压缩 {ALL | DATA_ONLY | METADATA_ONLY | NONE}。在Oracle 11g中，不能像exp一样使用pipe给gzip的方式压缩了，要用gzip的话必须手动gzip。</li>
<li>Parallel: 并行选项，在启用压缩时感觉效率有所提升。</li>
</ul>
<p>下面是一个例子，使用 BLOCKS 方法的总估计: 2.159 GB，实际压缩后仅仅剩下 28M左右（因某些数据我通过Query限制了，压缩前实际大小可能在300M左右，且数据比较特殊）。 更具普遍性的压缩效果可参考<a href="http://boomslaang.wordpress.com/2010/05/26/compression-with-11g-expdp/">这篇文章</a>（需翻墙）。该文也比较了使用gzip与使用compression参数的压缩效果。</p>
<p>一个实际的例子，导出：</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;">expdp dbaname<span style="color: #66cc66;">/</span>dbapwd DUMPFILE<span style="color: #66cc66;">=</span>expdumps%u<span style="color: #66cc66;">.</span>dmp DIRECTORY<span style="color: #66cc66;">=</span>DPUMP_DIR  <span style="color: #993333; font-weight: bold;">TABLES</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">'(T1,T2,T3)'</span> 
\QUERY<span style="color: #66cc66;">=</span>T1:\<span style="color: #ff0000;">&quot;where mod<span style="color: #000099; font-weight: bold;">\(</span>ID,10<span style="color: #000099; font-weight: bold;">\)</span>=0<span style="color: #000099; font-weight: bold;">\&quot;</span>,T2:<span style="color: #000099; font-weight: bold;">\&quot;</span>where mod<span style="color: #000099; font-weight: bold;">\(</span>ID,5<span style="color: #000099; font-weight: bold;">\)</span>=0<span style="color: #000099; font-weight: bold;">\&quot;</span> PARALLEL=4 COMPRESSION=ALL</span></pre></div></div>

<p>导入：</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;">impdp dbaname<span style="color: #66cc66;">/</span>dbapwd DIRECTORY<span style="color: #66cc66;">=</span>dpump_dir1 DUMPFILE<span style="color: #66cc66;">=</span>expdumps%U<span style="color: #66cc66;">.</span>dmp</pre></div></div>

<p>详细信息参考<a href="http://download.oracle.com/docs/cd/E11882_01/server.112/e16536/dp_export.htm#i1006293">Oracle手册相关内容</a>。</p>


<p>Related posts:<ol><li><a href='http://blog.xiping.me/2011/04/2011-study-a-multi-core-lang.html' rel='bookmark' title='Permanent Link: 2011, 掌握一门新语言：Erlang'>2011, 掌握一门新语言：Erlang</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://blog.xiping.me/2010/12/oracle-impdpexpdp-parallel-compression.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>JDBC和Ibatis中的Date,Time,Timestamp处理</title>
		<link>http://blog.xiping.me/2010/11/jdbc-ibatis-datetimes.html</link>
		<comments>http://blog.xiping.me/2010/11/jdbc-ibatis-datetimes.html#comments</comments>
		<pubDate>Thu, 25 Nov 2010 10:00:04 +0000</pubDate>
		<dc:creator>西坪</dc:creator>
				<category><![CDATA[$Programming]]></category>
		<category><![CDATA[ibatis]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[jdbc]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[oracle]]></category>

		<guid isPermaLink="false">http://blog.feihoo.com/?p=749</guid>
		<description><![CDATA[在此前，遇到过使用Ibatis操作Oracle时时间精度丢失的问题，昨天又遇到JDBC操作MySQL时间字段的问题，从网上看到各种式样的解释这些问题的博文/帖子，但多是雾里看花，不得要领。

理解JDBC中的时间类型
MySQL与JDBC之间的类型映射
Oracle与JDBC之间的类型映射
Ibatis是怎么处理日期时间类型的
注释
参考资料

理解JDBC中的时间类型

java.sql包中包括三个类，Date, Time, 和 Timestamp，分别用来表示日期（无时间信息，eg: YYYY-MM-DD），时间（只处理时间，无日期部分, eg: HH:MM:SS）和时间戳（精确到纳秒级别）。在 它们都继承自java.util.Date。java.sql.Date和java.sql.Time都存有一个时间域，该时间域是精确到秒级别的，但是，他们只处理日期或者时间部分。在MySQL Connector/J(v5.1.13)的实现中可以看到，PrepareStatement#setDate 时会将时间重新format成&#8221;yyyy-MM-dd&#8221;格式。
因为历史遗留以及各种数据库本身的不同，各种JDBC实现中留下了格式各样的花招, 某些特殊场景下不遵照此情况可能也能工作，但不推荐这样做。
 你必须根据你的实际需要来选择不同的类型，通常应该选用精确度与相应的数据库字段类型相比相同或者更高的JDBC类型。
除此以外，还可以使用java.uitl.Date类型来处理时间。java.util.Date类型是上面各个类型的父类型，JDBC的API大都可以使用。

除此以外，在JDK1.6之前版本的构造java.sql.{Date&#124;Time&#124;TimeStamp}对象时存在性能问题，尤其是在多线程环境下更严重。这个Bug在这里。其原因是java.util.Date的相关方法调用了TimeZone.getDefaultRef()，而此方法是同步方法注1。
MySQL的JDBC类型映射



DATE
 java.sql.Date


DATETIME
java.sql.Timestamp


TIMESTAMP[(M)]
 java.sql.Timestamp

TIME
java.sql.Time


YEAR[(2&#124;4)]
If yearIsDateType configuration property is set to false, then
                               the returned object [...]


Related posts:<ol><li><a href='http://blog.xiping.me/2011/03/java-serialize-and-reflection.html' rel='bookmark' title='Permanent Link: 解决Java序列化的版本冲突'>解决Java序列化的版本冲突</a></li>
<li><a href='http://blog.xiping.me/2010/01/dbcp_principle.html' rel='bookmark' title='Permanent Link: DBCP连接池(一)：原理与基本配置'>DBCP连接池(一)：原理与基本配置</a></li>
<li><a href='http://blog.xiping.me/2011/02/optimizing-actions.html' rel='bookmark' title='Permanent Link: J2EE/Oracle性能调优实录'>J2EE/Oracle性能调优实录</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>在此前，遇到过使用Ibatis操作Oracle时时间精度丢失的问题，昨天又遇到JDBC操作MySQL时间字段的<a href="#mysql_zero_bug">问题</a>，从网上看到各种式样的解释这些问题的博文/帖子，但多是雾里看花，不得要领。</p>
<ol>
<li><a href="#part1">理解JDBC中的时间类型</a></li>
<li><a href="#part2">MySQL与JDBC之间的类型映射</a></li>
<li><a href="#part3">Oracle与JDBC之间的类型映射</a></li>
<li><a href="#part4">Ibatis是怎么处理日期时间类型的</a></li>
<li><a href="#part5">注释</a></li>
<li><a href="#part6">参考资料</a></li>
</ol>
<h3>理解JDBC中的时间类型</h3>
<p><a name="part1"></a></p>
<p>java.sql包中包括三个类，<a href="http://download.oracle.com/javase/6/docs/api/java/sql/Date.html">Date</a>, <a href="http://download.oracle.com/javase/6/docs/api/java/sql/Time.html">Time</a>, 和 <a href="http://download.oracle.com/javase/6/docs/api/java/sql/Timestamp.html">Timestamp</a>，分别用来表示日期（无时间信息，eg: YYYY-MM-DD），时间（只处理时间，无日期部分, eg: HH:MM:SS）和时间戳（精确到纳秒级别）。在 它们都继承自<a href="http://download.oracle.com/javase/6/docs/api/java/util/Date.html">java.util.Date</a>。java.sql.Date和java.sql.Time都存有一个时间域，该时间域是精确到秒级别的，但是，他们只处理日期或者时间部分。在MySQL Connector/J(v5.1.13)的实现中可以看到，PrepareStatement#setDate 时会将时间重新format成&#8221;yyyy-MM-dd&#8221;格式。</p>
<p>因为历史遗留以及各种数据库本身的不同，各种JDBC实现中留下了格式各样的花招, 某些特殊场景下不遵照此情况可能也能工作，但不推荐这样做。</p>
<p> 你必须根据你的实际需要来选择不同的类型，通常应该<b>选用精确度与相应的数据库字段类型相比相同或者更高的JDBC类型</b>。</p>
<p>除此以外，还可以使用java.uitl.Date类型来处理时间。java.util.Date类型是上面各个类型的父类型，JDBC的API大都可以使用。<br />
<a name="no_java_sql_classes"></a><br />
除此以外，在JDK1.6之前版本的构造java.sql.{Date|Time|TimeStamp}对象时存在性能问题，尤其是在多线程环境下更严重。这个Bug在<a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6483402">这里</a>。其原因是java.util.Date的相关方法调用了TimeZone.getDefaultRef()，而此方法是同步方法<a href="#sub1"><sup>注1</sup></a>。</p>
<h3>MySQL的JDBC类型映射</h3>
<p><a name="part2"></a></p>
<table>
<tr>
<td>DATE</td>
<td> java.sql.Date</td>
</tr>
<tr>
<td>DATETIME</td>
<td>java.sql.Timestamp</td>
</tr>
<tr>
<td>TIMESTAMP[(M)]</td>
<td> java.sql.Timestamp</td>
<tr>
<td>TIME</td>
<td>java.sql.Time</td>
</tr>
<tr>
<td>YEAR[(2|4)]</td>
<td>If yearIsDateType configuration property is set to false, then<br />
                               the returned object type is java.sql.Short. If set to true (the<br />
                               default) then an object of type java.sql.Date (with the date<br />
                               set to January 1st, at midnight).</td>
</tr>
</table>
<p>MySQL的DATETIME、TIMESTAMP两种字段类型的显著区别在于TIMESTAMP的取值在&#8217;1970-01-01 00:00:01&#8242; UTC 和 &#8216;2038-01-19 03:14:07&#8242; UTC之间。<br />
<a name="mysql_zero_bug"></a><br />
MySQL在时间处理方面也有一个问题，当Datetimes类型的字段的值为0000-00-00时取值方法会得到下面的异常：</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">Cannot convert value <span style="color: #0000ff;">'0000-00-00 00:00:00'</span> from column xx to TIMESTAMP</pre></div></div>

<p>这个问题的原因在于，MySQL中默认使用0000-00-00等来表示时间的特殊值（<a href="http://dev.mysql.com/doc/refman/5.4/en/date-and-time-types.html">参见文档</a>）。而在Java中，并没有一个合适的方式来表示这个时间(因为Java中时间轴上0是1970-01-01 00:00:00），早于这个时间的用负数表示，这个最小的负数在时间轴上是表示不出来的。Connector/J提供了一个属性zeroDateTimeBehavior来解决此问题。</p>
<ul>
<li>exception (the default), which throws an SQLException with an SQLState of S1009.（默认行为）</li>
<li>convertToNull, which returns NULL instead of the date.</li>
<li>round, which rounds the date to the nearest closest value which is 0001-01-01.</li>
</ul>
<p>如下所示的jdbc连接将指定该行为转化为null值。</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">jdbc<span style="color: #339933;">:</span>mysql<span style="color: #339933;">:</span><span style="color: #666666; font-style: italic;">//localhost/myDatabase?zeroDateTimeBehavior=convertToNull</span></pre></div></div>

<h3>Oracle与JDBC之间的类型映射</h3>
<p><a name="part3"></a></p>
<table>
<tr>
<td>DATE</td>
<td> java.sql.Date</td>
</tr>
<tr>
<td>DATE</td>
<td>java.sql.Time</td>
</tr>
<tr>
<td>TIMESTAMP</td>
<td> java.sql.Timestamp</td>
</table>
<p>Oracle数据库字段类型主要有DATE、TIMESTAMP。</p>
<p>在9i以后、11g以前的Oracle JDBC驱动中存在一个会丢失DATE类型字段的时间信息的bug，原因是其JDBC驱动将Oracle的Date类型处理为java.sql.Date类型，这就丢失了时间部分（看来对java.sql包下三种时间类型认识不足的问题还很普遍的）。关于这个问题，这篇帖子<a href="http://old.nabble.com/Re%3A-Oracle-SQL-DATE-conversion-problem-using-iBATIS-via-Java-JDBC-p21112960.html">给出了不错的解释</a>（墙外），此文中的方法适用于11g JDBC以前的各版本驱动。在11g JDBC驱动中，此问题已经解决了，Oracle 11g JDBC驱动的手册中也给出了解释<a href="#sub2"><sup>注2</sup></a>。</p>
<p>事实上，如果是使用Ibatis，pojo属性的类型设置为java.util.Date，确保 jdbcType不为 DATE或者TIME，则避免了这个bug。因为此时Ibatis会以java.sql.Timestamp来处理该字段。我专门对此做了验证，<a href="https://github.com/Jeffliu/misc/tree/master/orcl_date_test/">点此看测试项目源码</a>。</p>
<h3>Ibatis是怎么处理日期类型的</h3>
<p><a name="part4"></a></p>
<p><em>注意：本文皆基于ibatis 2.3.4.726源码分析。不过根据我初略观察，Ibatis3也适用，但请遇到问题时有所留意。</em></p>
<p>在此前工作中碰到Oracle中的Date字段会只剩下日期部分的数据，丢失了，Google发现一些人的解决方法是将JDBCType指定为datetime。有人甚至自己编写一个自定义的TypeHandler来解决这个问题。其实这完全是瞎猫撞上死耗子，那个datetime根本没意义，却歪打正着。一般的错误都是如下的配置（或者是pojo的属性为java.sql.Date类型）：</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;sqlMap</span> <span style="color: #000066;">namespace</span>=<span style="color: #ff0000;">&quot;Info&quot;</span> <span style="color: #000000; font-weight: bold;">&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;resultMap</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;Info&quot;</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&quot;pojo.Info&quot;</span> <span style="color: #000000; font-weight: bold;">&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;result</span> <span style="color: #000066;">column</span>=<span style="color: #ff0000;">&quot;INFO_BEGINTIME&quot;</span> <span style="color: #000066;">property</span>=<span style="color: #ff0000;">&quot;begin&quot;</span> <span style="color: #000066;">jdbcType</span>=<span style="color: #ff0000;">&quot;DATE&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;result</span> <span style="color: #000066;">column</span>=<span style="color: #ff0000;">&quot;INFO_ENDTIME&quot;</span> <span style="color: #000066;">property</span>=<span style="color: #ff0000;">&quot;end&quot;</span> <span style="color: #000066;">jdbcType</span>=<span style="color: #ff0000;">&quot;DATE&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/resultMap<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>此时不论你pojo.Info中的字段类型（或者<result>的javaType属性）是java.util.Date还是java.sql.Date，最终都会丢失数据。实际上，在pojo.Info中的字段类型(或者javaType属性）为java.util.Date时，如果指定jdbcType为DATE或TIME（区分大小写），则将分别得到DateOnlyTypeHandler或TimeOnlyTypeHandler。如果你不指定jdbcType，或者指定一个错误的值，例如datetime，或者xxxx等，都会得到DateTypeHandler（日期时间都会处理）。 </p>
<p>如果pojo.Info中的属性类型（或者配置中的javaType属性）是java.sql.Date，则选择处理handler类时不会使用jdbcType，而是根据属性类型得到SqlDateTypeHandler（只包含日期）。</p>
<p>在Ibatis的手册中，指出来jdbcType一般情况下是不用于判断处理方式的<a href="sub3"><sup>注3</sup></a>。大部分情况下是依据javaType或者pojo属性类型来判断处理方式，在少部分无法根据pojo属性类型判断的情况下才使用。如果你用java.util.Date对应到MySQL，则就是这种少数情况之一。因为MySQL可以将多个数据库字段类型映射到java.util.Date，所以需要指定是DATE还是TIME（必须是大写），如果不指定则默认是完整的日期时间（此时按JDBC的timestamp操作）。</p>
<p>针对ibatis对时间的处理，我写了个测试，<a href="https://github.com/Jeffliu/misc/tree/master/orcl_date_test/">点此看测试代码。</a></p>
<p>对于Ibatis操作Date/Time/DateTime，总结如下：</p>
<ul>
<li>将pojo的属性类型设置为java.sql.Date（或java.sql.Time, java.sql.Timestamp），此时会严格遵循这三种类型的语义。但此方法因存在<a href="#no_java_sql_classes">前文中提到的性能问题</a>，在JDK1.6以前的JDK版本中能少使用就少使用。</li>
<li>如果你想在pojo中使用java.util.Date， 则要注意：
<ul>
<li>完整的日期时间，要确保jdbcType为空，或为DATE,TIME以外的值
<li>只需要时间，要指定jdbcType=&#8221;TIME&#8221;</li>
<li>只需要日期，要指定jdbcType=&#8221;DATE&#8221;</li>
</ul>
</li>
</ul>
<hr/>
<a name="part5"></a></p>
<h3>注释</h3>
<p><a name="sub1"></a></p>
<p>注释1：<span stype="padding-left:20px">Use oracle.sql.DATE or oracle.sql.TIMESTAMP rather than<br />
java.sql.Date or java.sql.Timestamp if you are using JDK 1.5 or earlier versions or require maximum performance. You may also use the oracle.sql data type if you want to read many date values or compute or display only a small percentage. Due to a bug in all versions of Java prior to JDK 1.6, construction of java.lang.Date and java.lang.Timestamp objects is slow, especially in multithreaded environments. This bug is fixed in JDK 1.6.</span></p>
<p><a name="sub2" ></a></p>
<p>注释2：<span stype="padding-left:20px">Mapping SQL DATE Data type to Java Oracle Database 8i and earlier versions did not support TIMESTAMP data, but Oracle DATE data used to have a time component as an extension to the SQL standard. So, Oracle Database 8i and earlier versions of JDBC drivers mapped oracle.sql.DATE to java.sql.Timestamp to preserve the time component. Starting with Oracle Database 9.0.1, TIMESTAMP support was included and 9i JDBC drivers started mapping oracle.sql.DATE to java.sql.Date. This mapping was incorrect as it truncated the time component of Oracle DATE data. To overcome this problem, Oracle Database 11.1 introduces a new flag mapDateToTimestamp. The default value of this flag is true, which means that by default the drivers will correctly map oracle.sql.DATE to java.sql.Timestamp, retaining the time information. If you still want the incorrect but 10g compatible oracle.sql.DATE to java.sql.Date mapping, then you can get it by setting the value of mapDateToTimestamp flag to false.</span></p>
<p><a name="sub3" ></a></p>
<p>注释3：<span stype="padding-left:20px">Ibatis 2的手册中给出的jdbcType属性的解释：属性jdbcType用于显式地指定给本属性（property）赋值的数据库字段的数据类型。对于某些特定的操作，如果不指定字段的数据类型，某些JDBC Driver无法识别字段的数据类型。一个很好的例子是PreparedStatement.setNull(int parameterIndex, int sqlType)方法，要求指定数据类型。如果不指定数据类型，某些Driver可能指定为Types.Other或Types.Null。但是，不能保证所有的Driver都表现一致。对于这种情况，SQL Map API允许使用parameterMap子元素parameter的jdbcType属性指定数据类型。<br />
正常情况下，只有当字段可以为NULL时才需要jdbcType属性。另一需要指定jdbcType属性的情况是字段类型为日期时间类型的情况。因为Java只有一个Date类型（java.util.Date），而大多数SQL数据库有多个－通常至少有3种。因此，需要指定字段类型是DATE还是DATETIME。<br />
属性jdbcType可以是JDBC Types类中定义的任意参数的字符串值。虽然如此，还是有某些类型不支持（即BLOB）。本节的稍后部分会说明架构支持的数据类型。<br />
注意！大多数JDBC Driver只有在字段可以为NULL时需要指定jdbcType属性。因此，对于这些Driver，只是在字段可以为NULL时才需要指定type属性。<br />
注意！当使用Oracle Driver时，如果没有给可以为NULL的字段指定jdbcType属性，当试图给这些字段赋值NULL时，会出现“Invalid column type”错误。<span></p>
<h3>参考资料</h3>
<p><a name="part6"></a></p>
<ul>
<li><a href="http://jcp.org/aboutJava/communityprocess/final/jsr221/index.html">JSR-000221 JDBC 4.0</a></li>
<li> <a href="http://ibatis.apache.org/docs/java/pdf/iBATIS-SqlMaps-2_en.pdf">Ibatis Developer Guide</a></li>
<li><a href="http://downloads.mysql.com/docs/connector-j-en.pdf">MySQL Connector/J</a></li>
</ul>


<p>Related posts:<ol><li><a href='http://blog.xiping.me/2011/03/java-serialize-and-reflection.html' rel='bookmark' title='Permanent Link: 解决Java序列化的版本冲突'>解决Java序列化的版本冲突</a></li>
<li><a href='http://blog.xiping.me/2010/01/dbcp_principle.html' rel='bookmark' title='Permanent Link: DBCP连接池(一)：原理与基本配置'>DBCP连接池(一)：原理与基本配置</a></li>
<li><a href='http://blog.xiping.me/2011/02/optimizing-actions.html' rel='bookmark' title='Permanent Link: J2EE/Oracle性能调优实录'>J2EE/Oracle性能调优实录</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://blog.xiping.me/2010/11/jdbc-ibatis-datetimes.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Google Apache modpagespeed 测试</title>
		<link>http://blog.xiping.me/2010/11/google-apache-modpagespeed-tests.html</link>
		<comments>http://blog.xiping.me/2010/11/google-apache-modpagespeed-tests.html#comments</comments>
		<pubDate>Tue, 09 Nov 2010 05:17:44 +0000</pubDate>
		<dc:creator>西坪</dc:creator>
				<category><![CDATA[server & system]]></category>
		<category><![CDATA[lamp]]></category>
		<category><![CDATA[ubuntu]]></category>

		<guid isPermaLink="false">http://blog.feihoo.com/?p=704</guid>
		<description><![CDATA[昨日尝新测试Google Pagespeed Mod。今天重新测试了一下，服务器为OpenVZ vps/amd64bit/512M。Web服务器为 Apache 2.2.11。机器的性能是比较差的，所有数据仅供参考。
从客户端看速度有不错提升
未启用之前在Google Chrome中打开 本页，页面各部分内容的大小如下图：

请求速度如下图：

开启mod_pagespeed以后，页面各部分内容的大小如下图：

css减少约1K，js减少1.5K，图片没有太大变化。总体减少约2K。
请求速度如下图：

页面加载时间变化明显，document加载减少了480ms，css减少了6ms(提升比为25%)，图片减少了24ms(提升比为18%)，js脚本减少了6ms(提升比为25%)，整体加载时间减少了460ms(提升比为21%)。
从服务端看
用ab在本机测试服务器的性能，可能是因为机器资源有限，ab本身要消耗一些资源，而本机测试时传输阶段的性能提升可以不计，故整体提升作用不明显。另外，ab不会去获取外部连接的文件也会错过mod_pagespeed在css/js/jpg方面的许多优化工作。尽管如此，处理速度还是有一些提升。开启前，50%的请求需要609ms，开启后降到599ms；66%的请求需要641ms，开启后降到621ms。所有请求的处理时间的中位数从609ms降到599ms。
启用前数据如下：

blog@feihoo:~$ ab -n 1000 -c 3 blog.feihoo.com/
This is ApacheBench, Version 2.3 &#60;$Revision: 655654 $&#62;
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
&#160;
Document Path:          /
Document Length:        114025 bytes
&#160;
Concurrency [...]


Related posts:<ol><li><a href='http://blog.xiping.me/2008/10/%e5%9c%a8-vista-%e4%b8%8a%e5%ae%89%e8%a3%85-apache-22-php-526.html' rel='bookmark' title='Permanent Link: 在 Vista 上安装 Apache 2.2, PHP 5.2.6'>在 Vista 上安装 Apache 2.2, PHP 5.2.6</a></li>
<li><a href='http://blog.xiping.me/2008/10/ubuntu-%e4%b8%8a%e5%ae%89%e8%a3%85buildix%ef%bc%8cphp5%ef%bc%8c-apache2-%e7%9a%84%e7%83%a6%e6%81%bc.html' rel='bookmark' title='Permanent Link: Ubuntu 上安装buildix，PHP5， Apache2'>Ubuntu 上安装buildix，PHP5， Apache2</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>昨日尝新测试<a href="http://code.google.com/speed/page-speed/docs/overview.html">Google Pagespeed Mod</a>。今天重新测试了一下，服务器为OpenVZ vps/amd64bit/512M。Web服务器为 Apache 2.2.11。机器的性能是比较差的，所有数据仅供参考。</p>
<h3>从客户端看速度有不错提升</h3>
<p>未启用之前在Google Chrome中打开 <a href="http://blog.feihoo.com/">本页</a>，页面各部分内容的大小如下图：</p>
<p><img src="http://blog.feihoo.com/wp-content/uploads/2010/11/a2b.jpg" alt="a2b" title="a2b" width="520" height="94" class="size-full wp-image-708" /></p>
<p>请求速度如下图：</p>
<p><img src="http://blog.feihoo.com/wp-content/uploads/2010/11/a1b.jpg" alt="a1b" title="a1b" width="515" height="94" class="size-full wp-image-706" /></p>
<p>开启mod_pagespeed以后，页面各部分内容的大小如下图：<br />
<img src="http://blog.feihoo.com/wp-content/uploads/2010/11/a2.jpg" alt="a2" title="a2" width="487" height="90" class="size-full wp-image-707" /></p>
<p>css减少约1K，js减少1.5K，图片没有太大变化。总体减少约2K。</p>
<p>请求速度如下图：</p>
<p><img src="http://blog.feihoo.com/wp-content/uploads/2010/11/a1.jpg" alt="a1" title="a1" width="473" height="91" class="size-full wp-image-705" /></p>
<p>页面加载时间变化明显，document加载减少了480ms，css减少了6ms(提升比为25%)，图片减少了24ms(提升比为18%)，js脚本减少了6ms(提升比为25%)，整体加载时间减少了460ms(提升比为21%)。</p>
<h3>从服务端看</h3>
<p>用ab在本机测试服务器的性能，可能是因为机器资源有限，ab本身要消耗一些资源，而本机测试时传输阶段的性能提升可以不计，故整体提升作用不明显。另外，ab不会去获取外部连接的文件也会错过mod_pagespeed在css/js/jpg方面的许多优化工作。尽管如此，处理速度还是有一些提升。开启前，50%的请求需要609ms，开启后降到599ms；66%的请求需要641ms，开启后降到621ms。所有请求的处理时间的中位数从609ms降到599ms。</p>
<p>启用前数据如下：</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">blog@feihoo:~$ ab -n 1000 -c 3 blog.feihoo.com/
This is ApacheBench, Version 2.3 &lt;$Revision: 655654 $&gt;
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
&nbsp;
Document Path:          /
Document Length:        114025 bytes
&nbsp;
Concurrency Level:      3
Time taken for tests:   209.315 seconds
Complete requests:      1000
Failed requests:        0
Write errors:           0
Total transferred:      114394000 bytes
HTML transferred:       114025000 bytes
Requests per second:    4.78 [#/sec] (mean)
Time per request:       627.946 [ms] (mean)
Time per request:       209.315 [ms] (mean, across all concurrent requests)
Transfer rate:          533.71 [Kbytes/sec] received
&nbsp;
Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.0      0       0
Processing:   484  628 108.2    609    1763
Waiting:      224  288  57.5    284    1035
Total:        485  628 108.2    609    1763
&nbsp;
Percentage of the requests served within a certain time (ms)
  50%    609
  66%    641
  75%    657
  80%    670
  90%    735
  95%    825
  98%    895
  99%    988
 100%   1763 (longest request)</pre></div></div>

<p>启用后测试结果如下：</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">blog@feihoo:~$ ab -n 1000 -c 3 blog.feihoo.com/
This is ApacheBench, Version 2.3 &lt;$Revision: 655654 $&gt;
&nbsp;
Server Software:        Apache/2.2.11
Document Path:          /
Document Length:        114356 bytes
&nbsp;
Concurrency Level:      3
Time taken for tests:   209.686 seconds
Complete requests:      1000
Failed requests:        0
Write errors:           0
Total transferred:      114755000 bytes
HTML transferred:       114356000 bytes
Requests per second:    4.77 [#/sec] (mean)
Time per request:       629.057 [ms] (mean)
Time per request:       209.686 [ms] (mean, across all concurrent requests)
Transfer rate:          534.44 [Kbytes/sec] received
&nbsp;
Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.2      0       6
Processing:   511  628 216.0    599    3660
Waiting:      233  294 157.4    277    2984
Total:        511  628 216.0    599    3660
&nbsp;
Percentage of the requests served within a certain time (ms)
  50%    599
  66%    621
  75%    635
  80%    643
  90%    664
  95%    694
  98%   1075
  99%   1641
 100%   3660 (longest request)</pre></div></div>



<p>Related posts:<ol><li><a href='http://blog.xiping.me/2008/10/%e5%9c%a8-vista-%e4%b8%8a%e5%ae%89%e8%a3%85-apache-22-php-526.html' rel='bookmark' title='Permanent Link: 在 Vista 上安装 Apache 2.2, PHP 5.2.6'>在 Vista 上安装 Apache 2.2, PHP 5.2.6</a></li>
<li><a href='http://blog.xiping.me/2008/10/ubuntu-%e4%b8%8a%e5%ae%89%e8%a3%85buildix%ef%bc%8cphp5%ef%bc%8c-apache2-%e7%9a%84%e7%83%a6%e6%81%bc.html' rel='bookmark' title='Permanent Link: Ubuntu 上安装buildix，PHP5， Apache2'>Ubuntu 上安装buildix，PHP5， Apache2</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://blog.xiping.me/2010/11/google-apache-modpagespeed-tests.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>位图存储优化</title>
		<link>http://blog.xiping.me/2010/10/bitmap-compression.html</link>
		<comments>http://blog.xiping.me/2010/10/bitmap-compression.html#comments</comments>
		<pubDate>Fri, 01 Oct 2010 16:00:56 +0000</pubDate>
		<dc:creator>西坪</dc:creator>
				<category><![CDATA[$Performance]]></category>
		<category><![CDATA[$算法与计算原理]]></category>
		<category><![CDATA[algorithm]]></category>
		<category><![CDATA[bitvector]]></category>
		<category><![CDATA[d-gap]]></category>
		<category><![CDATA[datastructure]]></category>

		<guid isPermaLink="false">http://blog.feihoo.com/?p=676</guid>
		<description><![CDATA[位图作为一种简高效使用内存的数据结构，在很多场合都能够用最省的内存表达大量的数据。我对位图最早的印象来自于《编程珠玑》中用位图结构来存储电话号码。感叹其简单、方便。本质上，位图是一个存储单个位的数组，每一个位表示一个数组元素。例如如果我们需要标记100万用户的在线状态，则可以将每个用户对应到一个位，只需要100万个位（约0.125M内存)的位图就可以表示了。如下图所示，在线的用户标记为绿色。其存储则可表示为 {01010011 0011&#8230;}。

但是对于某些比较稀疏的位图，其存储效率也会有一些问题。如果100万用户平均只有100个人在线，那另外的999,900个位就浪费掉了。例如在第1位有一个用户，第1,000,000位有个用户，需要1M个位来保存。既浪费了存储空间，也带来大量无用的运算。在前不久我们的应用中就有这种问题。未经压缩的位图保存到数据库中，结果大量的IO操作对数据库的性能造成较大影响。
因为稀疏的位图比较多，比较直接地就想去掉中间的这些空白位，于是就想这样表示：存储第一个位的值（0或1），接着将接下来的所有值相同的位的数目保存为一个整数，再保存接下来另的一类连续位的数目，依此类推。如：{0000 0000 1000 0000 0000 1100 0001 0000 &#8230;&#8230; } 保存为 0,7,1,11,2,5&#8230;。 如果是一百万个位，只有第一个和最后一个是1{10000 &#8230;. &#8230;. 1}，则保存为{1,999998,1}只需要三个整数就可以了！（注：实际上，早有人完整地将这种方法实现了，参考D-Gap Compression）
于是对比较稀疏的位图应用这种方法，由于大部分位图都是比较稀疏，90%以上的位图的体积最终缩小了10倍。在测试过程中，发现最终存储的是大量的小整数（小于1000）。这些小整数其实可以用更短的类型来表示，于是应用变长编码来处理。其原理是每一个字节的高位做标识，其余7位存储值。1标识从这个字节开始是一个新的整数，0表示是上一个字节的延续。则区间[1, 2^7 )中的整数占用一个字节，[2^7, 2^14)中的整数占用两个字节，依次类推。
最终，90%以上的位图体积压缩了30倍以上。 


Related posts:Impdp/Expdp 之并行(Parallel)和压缩(Compression)



Related posts:<ol><li><a href='http://blog.xiping.me/2010/12/oracle-impdpexpdp-parallel-compression.html' rel='bookmark' title='Permanent Link: Impdp/Expdp 之并行(Parallel)和压缩(Compression)'>Impdp/Expdp 之并行(Parallel)和压缩(Compression)</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p><a href="http://en.wikipedia.org/wiki/Bit_vector">位图</a>作为一种简高效使用内存的数据结构，在很多场合都能够用最省的内存表达大量的数据。我对位图最早的印象来自于《编程珠玑》中用位图结构来存储电话号码。感叹其简单、方便。本质上，位图是一个存储单个位的数组，每一个位表示一个数组元素。例如如果我们需要标记100万用户的在线状态，则可以将每个用户对应到一个位，只需要100万个位（约0.125M内存)的位图就可以表示了。如下图所示，在线的用户标记为绿色。其存储则可表示为 {01010011 0011&#8230;}。</p>
<p><img src="http://blog.feihoo.com/wp-content/uploads/2010/11/bitvector.PNG" alt="位图" title="bitvector" width="475" height="20" class="size-full wp-image-732" align="center" /></p>
<p>但是对于某些比较稀疏的位图，其存储效率也会有一些问题。如果100万用户平均只有100个人在线，那另外的999,900个位就浪费掉了。例如在第1位有一个用户，第1,000,000位有个用户，需要1M个位来保存。既浪费了存储空间，也带来大量无用的运算。在前不久我们的应用中就有这种问题。未经压缩的位图保存到数据库中，结果大量的IO操作对数据库的性能造成较大影响。</p>
<p>因为稀疏的位图比较多，比较直接地就想去掉中间的这些空白位，于是就想这样表示：存储第一个位的值（0或1），接着将接下来的所有值相同的位的数目保存为一个整数，再保存接下来另的一类连续位的数目，依此类推。如：{0000 0000 1000 0000 0000 1100 0001 0000 &#8230;&#8230; } 保存为 0,7,1,11,2,5&#8230;。 如果是一百万个位，只有第一个和最后一个是1{10000 &#8230;. &#8230;. 1}，则保存为{1,999998,1}只需要三个整数就可以了！（注：实际上，早有人完整地将这种方法实现了，参考<a href="http://bmagic.sourceforge.net/dGap.html">D-Gap Compression</a>）</p>
<p>于是对比较稀疏的位图应用这种方法，由于大部分位图都是比较稀疏，90%以上的位图的体积最终缩小了10倍。在测试过程中，发现最终存储的是大量的小整数（小于1000）。这些小整数其实可以用更短的类型来表示，于是应用<a href="http://en.wikipedia.org/wiki/Variable-width_encoding">变长编码</a>来处理。其原理是每一个字节的高位做标识，其余7位存储值。1标识从这个字节开始是一个新的整数，0表示是上一个字节的延续。则区间[1, 2^7 )中的整数占用一个字节，[2^7, 2^14)中的整数占用两个字节，依次类推。</p>
<p>最终，90%以上的位图体积压缩了30倍以上。 </p>


<p>Related posts:<ol><li><a href='http://blog.xiping.me/2010/12/oracle-impdpexpdp-parallel-compression.html' rel='bookmark' title='Permanent Link: Impdp/Expdp 之并行(Parallel)和压缩(Compression)'>Impdp/Expdp 之并行(Parallel)和压缩(Compression)</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://blog.xiping.me/2010/10/bitmap-compression.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Java平台上的XML处理梳理</title>
		<link>http://blog.xiping.me/2010/09/xml-names-and-jars.html</link>
		<comments>http://blog.xiping.me/2010/09/xml-names-and-jars.html#comments</comments>
		<pubDate>Thu, 30 Sep 2010 14:39:51 +0000</pubDate>
		<dc:creator>西坪</dc:creator>
				<category><![CDATA[$Programming]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[xml]]></category>

		<guid isPermaLink="false">http://blog.feihoo.com/?p=826</guid>
		<description><![CDATA[做了几年Java了，也经常用XML，但是鉴于Java平台对于XML处理相关的API和实现十分混乱，一直没有完全理清其关系。而又有如此多的名词跟XML沾亲带故，尤其是Java平台里名词满天飞。你应该见过这些名字吧：SAX，DOM，JAXP，JDOM，DOM4J， JAXB ,  JAXM ,  JAXR , XLST，XPATH， JAX-RPC， XML-RPC，XForms，你都知道吗？在维基百科XML页面上还有这么一句话：&#8221;As of 2009， hundreds of XML-based languages have been developed&#8221;（截止到2009年，有数百基于XML的语言被开发出来），可能也不只Java平台上XML处理这么复杂。
基础技术
XML
XML，全称可扩展标记语言（Extensible Markup Language (XML) ）是在W3C制定的几个文档中定义的，用于将内容编码为机器可读的格式。
XML我们经常接触或者使用，其支持Unicode编码、严格完整的标记和错误处理等等，大家都知道。XML最早使用DTD来对XML的内容和格式进行定义和校验，后来W3C开发了新的模式语言XML Schema来取代DTD。于是，现在我们经常见到用来规范XML格式和内容的Xsd文档，DTD 已经逐渐淡出了。
XML的编程接口
XML作为一种数据格式，其设计目标中就包括了能够轻易地为各种编程语言提供接口。概括起来主要是下面这四个类型。

 面向流的API，例如 SAX 和 StAX。
 树遍历的API， 例如 DOM。
 XML数据绑定，支持在程序语言的对象与XML文档之间自动转换。（JAXB）
 声明式转换语言，例如 XSLT 和 XQuery。

Sun公司给Java语言定义了一个将上面这数种编程接口（DOM/SAX/StAX）统一的API，JAXP（Java API for XML Processing），其目的是在Java平台上统一处理XML的接口。
Java平台中怎么处理XML
DOM和SAX
DOM的全称 Document Object Model（文档对象模型），是将XML在内存中组织为一个树形结构，并按照树形结构遍历和访问。不论是使用Dom4j，或者是Javascript里，经常看到Node/Element/Attribute这些东西，这就是使用DOM操作XML/XHTML等。DOM操作的最大缺点就是要将所有东西装到内存中，方便频繁查询、修改。一般的配置文件都比较小，使用DOM问题都不大。但是数据量很大的情况下，或者要处理的XML很多，那最好不用它。
SAX的全称是 Simple API for XML， 是基于流的方式来访问XML的。CSDN的这篇博文解释道：&#8221;SAX 解析器采用了基于事件的模型，它在解析 XML 文档的时候可以触发一系列的事件，当发现给定的tag的时候，它可以激活一个回调方法，告诉该方法制定的标签已经找到。SAX 对内存的要求通常会比较低，因为它让开发人员自己来决定所要处理的tag。特别是当开发人员只需要处理文档中所包含的部分数据时，SAX [...]


Related posts:<ol><li><a href='http://blog.xiping.me/2010/01/dbcp_principle.html' rel='bookmark' title='Permanent Link: DBCP连接池(一)：原理与基本配置'>DBCP连接池(一)：原理与基本配置</a></li>
<li><a href='http://blog.xiping.me/2011/03/java-serialize-and-reflection.html' rel='bookmark' title='Permanent Link: 解决Java序列化的版本冲突'>解决Java序列化的版本冲突</a></li>
<li><a href='http://blog.xiping.me/2009/10/understand_java_additon.html' rel='bookmark' title='Permanent Link: 理解Java虚拟机的加法运算'>理解Java虚拟机的加法运算</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>做了几年Java了，也经常用XML，但是鉴于Java平台对于XML处理相关的API和实现十分混乱，一直没有完全理清其关系。而又有如此多的名词跟XML沾亲带故，尤其是Java平台里名词满天飞。你应该见过这些名字吧：SAX，DOM，JAXP，JDOM，DOM4J， JAXB ,  JAXM ,  JAXR , XLST，XPATH， JAX-RPC， XML-RPC，XForms，你都知道吗？在维基百科<a href="http://en.wikipedia.org/wiki/XML">XML</a>页面上还有这么一句话：&#8221;As of 2009， hundreds of XML-based languages have been developed&#8221;（截止到2009年，有数百基于XML的语言被开发出来），可能也不只Java平台上XML处理这么复杂。</p>
<h3>基础技术</h3>
<h4>XML</h4>
<p><a href="http://en.wikipedia.org/wiki/XML">XML，全称可扩展标记语言</a>（Extensible Markup Language (XML) ）是在W3C制定的几个文档中定义的，用于将内容编码为机器可读的格式。</p>
<p>XML我们经常接触或者使用，其支持Unicode编码、严格完整的标记和错误处理等等，大家都知道。XML最早使用DTD来对XML的内容和格式进行定义和校验，后来W3C开发了新的模式语言<a href="http://en.wikipedia.org/wiki/XML_Schema_(W3C)">XML Schema</a>来取代DTD。于是，现在我们经常见到用来规范XML格式和内容的Xsd文档，DTD 已经逐渐淡出了。</p>
<h3>XML的编程接口</h3>
<p>XML作为一种数据格式，其设计目标中就包括了能够轻易地为各种编程语言提供接口。概括起来主要是下面这四个类型。</p>
<ol>
<li> 面向流的API，例如 SAX 和 StAX。</li>
<li> 树遍历的API， 例如 DOM。</li>
<li> XML数据绑定，支持在程序语言的对象与XML文档之间自动转换。（JAXB）</li>
<li> 声明式转换语言，例如 XSLT 和 XQuery。</li>
</ol>
<p>Sun公司给Java语言定义了一个将上面这数种编程接口（DOM/SAX/StAX）统一的API，<a href="http://jaxp.java.net/">JAXP（Java API for XML Processing）</a>，其目的是在Java平台上统一处理XML的接口。</p>
<h3>Java平台中怎么处理XML</h3>
<h4>DOM和SAX</h4>
<p>DOM的全称 Document Object Model（文档对象模型），是将XML在内存中组织为一个树形结构，并按照树形结构遍历和访问。不论是使用Dom4j，或者是Javascript里，经常看到Node/Element/Attribute这些东西，这就是使用DOM操作XML/XHTML等。DOM操作的最大缺点就是要将所有东西装到内存中，方便频繁查询、修改。一般的配置文件都比较小，使用DOM问题都不大。但是数据量很大的情况下，或者要处理的XML很多，那最好不用它。</p>
<p>SAX的全称是 Simple API for XML， 是基于流的方式来访问XML的。<a href="http://blog.csdn.net/raindew1985/archive/2007/08/10/1736353.aspx">CSDN的这篇博文</a>解释道：&#8221;SAX 解析器采用了基于事件的模型，它在解析 XML 文档的时候可以触发一系列的事件，当发现给定的tag的时候，它可以激活一个回调方法，告诉该方法制定的标签已经找到。SAX 对内存的要求通常会比较低，因为它让开发人员自己来决定所要处理的tag。特别是当开发人员只需要处理文档中所包含的部分数据时，SAX 这种扩展能力得到了更好的体现。但用 SAX 解析器的时候编码工作会比较困难，而且很难同时访问同一个文档中的多处不同数据。&#8221;（该博文有转字样，不知道其出处是哪，没搜到）。</p>
<p>对于SAX/DOM相关的论述， 上面提到的CSDN的博文<a href="http://blog.csdn.net/raindew1985/archive/2007/08/10/1736353.aspx">关于SAX，DOM，JAXP，JDOM，DOM4J的一些理解</a> 有比较精彩的论述。</p>
<p>有关DOM/SAX两种处理接口在处理大量XML数据时的性能，<a href="http://tiny4.org/">Tinyfool</a>的<a href="http://tiny4.org/prog/diary/2007/12/javaxmldomsax.html">博文</a>提供了一组数据为证。</p>
<h4>Java平台这两种API的实现</h4>
<p>在Java的类库中，<a href="http://dom4j.sf.net/">Dom4j</a>最早就是以DOM方式解析XML的。现在dom4j也支持其他方式解析XML，完整实现了DOM, SAX 和 JAXP。如果你使用Dom4j，在JDK5之前的JDK版本中则需要从<a href="http://jaxp.java.net/">JAXP的主页</a>上下载相关的API包。</p>
<p><a href="http://www.jdom.org/">JDOM</a>是另一个基于DOM模型处理XML的类库，但似乎已经不那么流行了。</p>
<p>Apache的<a href="http://xerces.apache.org/ ">xerces</a>项目下有C++/Java/Perl三种语言的XML解析器。<a href="http://xerces.apache.org/xerces-j/">Apache Xerces2 Java</a> 是Java语言的XML解析器。使用Apache xerces-J需要两个jar包，第一个是xml-apis.jar，其中包含了sax dom jaxp等接口的定义，另一个jar包是 xercesImpl.jar，包含各个接口的实现。以前的Xercers包中还包括一个xerces.jar，现在已经废弃了（参考<a href="http://xerces.apache.org/xerces2-j/install.html">这里</a>）。</p>
<h4>XML数据绑定</h4>
<p><a href="https://jaxb.dev.java.net/">JAXB</a>，全称是<a href="https://jaxb.dev.java.net/">Java Architecture for XML Binding</a>，是Java EE平台中处理XML与Java对象之间数据绑定的API。名如 jaxb1-impl.jar, jaxb1-impl-2.0.jar等的包，就是这个接口的相关产物。这个API也是JAXP的一部分，Xecers-j和dom4j都提供了实现。</p>
<p><a href="http://xmlbeans.apache.org/">Apache Xmlbeans</a> 也提供了处理XML与Java对象间数据绑定的功能。</p>
<h4>Java平台中的声明式转换语言</h4>
<p>XSLT， 可扩展样式转换语言，常用于将信息内容与展现分离。在《企业应用架构模式》中将之作为表现层的一种模式做了介绍。使用XSLT，同一份内容，能够转换成HTML，文本文件，PDF，Postscript等等。处理XML的声明式转换语言还有从XML中查找节点的<a href="http://www.w3.org/TR/xpath/">XPATH</a>，用于从XML集合中查询数据的<a href="http://en.wikipedia.org/wiki/XQuery">XQuery</a>等。此前在Flex平台的项目中用过XPATH来处理界面，还是很方便的。</p>
<p>你可能看到过xalan.jar，有的项目里还必须有这个库。其实这是Apache的<a href="http://xml.apache.org/xalan-j/">Xalan-Java</a>的库，是一个XSLT处理库，实现了 JAXP中的javax.xml.transform接口。Xalan可将XML文档转换为HTML，文本文档或者其他XML格式。这个包依赖实现了SAX接口的相关包，所以必须与实现SAX接口的包一起使用。Xalan官方推荐的是Xercers（<a href="http://xml.apache.org/xalan-j/getstarted.html">参考这里</a>）。</p>
<p>另一个可以实现了XML的声明式转换相关接口的类库是<a href="http://saxon.sourceforge.net/">Saxon项目</a>的Java子项目。</p>
<h3>结语</h3>
<p>有关Java中这些XML处理方式，Apache这里有个<a href="http://people.apache.org/~edwingo/jaxp-faq.html">FAQ</a>可以参考一下，这个FAQ尝试回答为什么Java里有这么多XML处理的实现，接口和jar包。</p>
<p>总结这些东西好累，Java平台上处理XML实在是太累了。这大概也与XML被用得如此宽广有关。XML作为一种严格规范化的描述能力很强的数据格式，确实无处不在。虽然XML有时很臃肿，但基于XML的技术如<a href="http://www.w3.org/MarkUp/Forms/">XForm</a>，<a href="http://java.sun.com/webservices/jaxrpc/overview.html">Java API for XML-Based RPC (JAX-RPC)</a>，<a href="http://www.xmlrpc.com/">XML-RPC</a>等，很多很多。</p>
<p>（本文涉及内容较多较杂，我只是尝试做一个整理，如有谬误请不吝赐教）</p>


<p>Related posts:<ol><li><a href='http://blog.xiping.me/2010/01/dbcp_principle.html' rel='bookmark' title='Permanent Link: DBCP连接池(一)：原理与基本配置'>DBCP连接池(一)：原理与基本配置</a></li>
<li><a href='http://blog.xiping.me/2011/03/java-serialize-and-reflection.html' rel='bookmark' title='Permanent Link: 解决Java序列化的版本冲突'>解决Java序列化的版本冲突</a></li>
<li><a href='http://blog.xiping.me/2009/10/understand_java_additon.html' rel='bookmark' title='Permanent Link: 理解Java虚拟机的加法运算'>理解Java虚拟机的加法运算</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://blog.xiping.me/2010/09/xml-names-and-jars.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>15%技术，75%思维和性格？</title>
		<link>http://blog.xiping.me/2010/07/15%e6%8a%80%e6%9c%af%ef%bc%8c75%e6%80%9d%e7%bb%b4%e5%92%8c%e6%80%a7%e6%a0%bc.html</link>
		<comments>http://blog.xiping.me/2010/07/15%e6%8a%80%e6%9c%af%ef%bc%8c75%e6%80%9d%e7%bb%b4%e5%92%8c%e6%80%a7%e6%a0%bc.html#comments</comments>
		<pubDate>Tue, 13 Jul 2010 06:28:06 +0000</pubDate>
		<dc:creator>西坪</dc:creator>
				<category><![CDATA[@生活]]></category>

		<guid isPermaLink="false">http://blog.feihoo.com/?p=650</guid>
		<description><![CDATA[有感于下面这句话（来自AgileChina论坛有关程序员职业规划的讨论（Jacky Huang)）。
一个人的成功，15%来自他的专业技术，75%来自于他的思维和性格，10%来自于机遇。
虽然下面Jeff Xiong做了一些批驳，但是某些情况下我大致同意上面这句话。一方面上面所指的成功因素的比例跟时间分配上的比例完全是不可比的，另一方面，专业技术的发展与性格和思维根本就是分不开的。但其实另外那75%里的思维和性格，同样决定了技术上是否能有所成绩。每个人的目标和志向不同，性格和习惯也不同，不是一句话能概括得了的。(Updated at Nov 30th)


No related posts.


No related posts.]]></description>
			<content:encoded><![CDATA[<p>有感于下面这句话（来自<a href="http://groups.google.com/group/agilechina/browse_thread/thread/bf2b754de80d104f/87fdf3bcb87b78e4?lnk=gst&#038;q=%E4%B8%93%E4%B8%9A#87fdf3bcb87b78e4">AgileChina论坛有关程序员职业规划的讨论（Jacky Huang)</a>）。</p>
<blockquote><p>一个人的成功，15%来自他的专业技术，75%来自于他的思维和性格，10%来自于机遇。</p></blockquote>
<p>虽然下面<a href="http://groups.google.com/groups/profile?enc_user=YW5jlxMAAAB93sZziShE5jMv1MkXsps6WMj6vob75xS36mXc24h6ww">Jeff Xiong</a>做了一些批驳，但是某些情况下我大致同意上面这句话。一方面上面所指的成功因素的比例跟时间分配上的比例完全是不可比的，另一方面，专业技术的发展与性格和思维根本就是分不开的。但其实另外那75%里的思维和性格，同样决定了技术上是否能有所成绩。每个人的目标和志向不同，性格和习惯也不同，不是一句话能概括得了的。(Updated at Nov 30th)</p>


<p>No related posts.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.xiping.me/2010/07/15%e6%8a%80%e6%9c%af%ef%bc%8c75%e6%80%9d%e7%bb%b4%e5%92%8c%e6%80%a7%e6%a0%bc.html/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>[译] Orx教程：1. object</title>
		<link>http://blog.xiping.me/2010/07/orx_tutorial_cn_object.html</link>
		<comments>http://blog.xiping.me/2010/07/orx_tutorial_cn_object.html#comments</comments>
		<pubDate>Mon, 05 Jul 2010 02:22:06 +0000</pubDate>
		<dc:creator>西坪</dc:creator>
				<category><![CDATA[@Translation]]></category>
		<category><![CDATA[orx]]></category>

		<guid isPermaLink="false">http://blog.feihoo.com/?p=641</guid>
		<description><![CDATA[本文译自 orx tutorials 的对象(object)。phpxer 译，九天雁翎 （博客）修订。最新版本见Orx官方中文Wiki。
Object （对象）教程
总结
由于orx是数据驱动的，我们只需要两行代码创建一个viewport（视口）和一个object。它们的所有属性都定义在配置文件（01_Object.ini）中。
Viewport关联到一个按照配置文件中的信息隐含创建的camera(摄像头)。在配置文件里，你还可以设置它们的大小，坐标，对象的颜色，缩放，旋转，动画，物理属性等等。你甚至无需增加一行代码就可以让任何的配置获得随机值。
在后面的一个示例中我们将看到如何使用一行代码生成复杂的object体系甚至整个 scene（场景）（所有的背景对象和普通对象）。
现在，你可以尝试取消01_Object.ini中某些行的注释，自己尝试一下，然后再继续学习这个教程。完整的选项列表请查看CreationTemplate.ini。
详细说明
创建一个object是相当简单的。不过，我们首先需确保已经加载了定义了所有object(对象)的属性的配置文件。我们还要通过viewport/camera组合显示创建好的object(对象)。
不要慌张！所有这些都很容易。
在这篇教程中，我们将加载一个位于父目录中的配置文件。正如你可能想到的，在所有的可执行程序都根据其构建类别（mingw, msvs2005, msvs2008, 等）位于各自的子目录的情况下，我们不打算在每个地方重复同样的配置文件。1)
在我们的例子中，加载配置文件使用类似下面这行代码的方式实现：
    orxConfig_Load(&#8221;../01_Object.ini&#8221;);
然后我们创建viewport(视口)。注意 camera的创建是按照为这个viewport预置的配置信息自动完成的。
    orxViewport_CreateFromConfig(&#8221;Viewport&#8221;);
我们差不多完成了。现在我们只需要创建 object！
    orxObject_CreateFromConfig(&#8221;Object&#8221;);
就这样了！object(对象)已经创建，并且由于在camera的视觉平截体（frustum）内，将会被显示出来。
现在，因为我们使用Orx默认的启动器，我们需要申明我们的插件入口点（这里是我们的Init函数）。这可以使用一个宏很容易地实现。

orxSTATUS Init&#40;&#41;&#123;...&#125;
orxPLUGIN_DECLARE_ENTRY_POINT&#40;Init&#41;;

因为orx是数据驱动的，我们不需要手动加载任何数据，例如一个sprite（精灵）。一切都由数据管理器为我们搞定，它会确保sprites不在内存中重复并在其不再使用时自动释放的
如果你查看配置文件，在[Object]这一节，你将看到你可以设定所有的对象属性，例如 graphic (sprite)，锚点，颜色，透明度，物理属性，坐标，旋转，缩放，tiling(平铺)（重复），动画，视觉特效，等等。
不要担心，这一切都将在后面的教程中讲到。
现在我们拥有了一个object（对象），我们需要学习如何与之交互。这将我们带入第二个教程：clock.
资源


源代码: 01_Object.c
配置文件: 01_Object.ini


1) 不过，如果你的配置文件名字与可执行文件匹配并且在同一个文件夹下，它将被自动加载。


No related posts.


No related posts.]]></description>
			<content:encoded><![CDATA[<p>本文译自<a href="http://orx-project.org/wiki/en/orx/tutorials/main"> orx tutorials </a>的<a href="http://orx-project.org/wiki/en/orx/tutorials/object">对象(object)</a>。<a href="http://blog.feihoo.com">phpxer</a> 译，九天雁翎 （<a href="http://blog.csdn.net/vagrxie">博客</a>）修订。最新版本见<a href="http://orx-project.org/wiki/cn/orx/main">Orx官方中文Wiki</a>。</p>
<h3>Object （对象）教程</h3>
<h4>总结</h4>
<p>由于orx是数据驱动的，我们只需要两行代码创建一个viewport（视口）和一个object。它们的所有属性都定义在配置文件（01_Object.ini）中。</p>
<p>Viewport关联到一个按照配置文件中的信息隐含创建的camera(摄像头)。在配置文件里，你还可以设置它们的大小，坐标，对象的颜色，缩放，旋转，动画，物理属性等等。你甚至无需增加一行代码就可以让任何的配置获得随机值。</p>
<p>在后面的一个示例中我们将看到如何使用一行代码生成复杂的object体系甚至整个 scene（场景）（所有的背景对象和普通对象）。</p>
<p>现在，你可以尝试取消01_Object.ini中某些行的注释，自己尝试一下，然后再继续学习这个教程。完整的选项列表请查看CreationTemplate.ini。</p>
<h4>详细说明</h4>
<p>创建一个object是相当简单的。不过，我们首先需确保已经加载了定义了所有object(对象)的属性的配置文件。我们还要通过viewport/camera组合显示创建好的object(对象)。</p>
<p>不要慌张！所有这些都很容易。</p>
<p>在这篇教程中，我们将加载一个位于父目录中的配置文件。正如你可能想到的，在所有的可执行程序都根据其构建类别（mingw, msvs2005, msvs2008, 等）位于各自的子目录的情况下，我们不打算在每个地方重复同样的配置文件。1)</p>
<p>在我们的例子中，加载配置文件使用类似下面这行代码的方式实现：<br />
    orxConfig_Load(&#8221;../01_Object.ini&#8221;);</p>
<p>然后我们创建viewport(视口)。注意 camera的创建是按照为这个viewport预置的配置信息自动完成的。<br />
    orxViewport_CreateFromConfig(&#8221;Viewport&#8221;);</p>
<p>我们差不多完成了。现在我们只需要创建 object！<br />
    orxObject_CreateFromConfig(&#8221;Object&#8221;);</p>
<p>就这样了！object(对象)已经创建，并且由于在camera的视觉平截体（frustum）内，将会被显示出来。<br />
现在，因为我们使用Orx默认的启动器，我们需要申明我们的插件入口点（这里是我们的Init函数）。这可以使用一个宏很容易地实现。</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;">orxSTATUS Init<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>...<span style="color: #009900;">&#125;</span>
orxPLUGIN_DECLARE_ENTRY_POINT<span style="color: #009900;">&#40;</span>Init<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>因为orx是数据驱动的，我们不需要手动加载任何数据，例如一个sprite（精灵）。一切都由数据管理器为我们搞定，它会确保sprites不在内存中重复并在其不再使用时自动释放的<br />
如果你查看配置文件，在[Object]这一节，你将看到你可以设定所有的对象属性，例如 graphic (sprite)，锚点，颜色，透明度，物理属性，坐标，旋转，缩放，tiling(平铺)（重复），动画，视觉特效，等等。<br />
不要担心，这一切都将在后面的教程中讲到。</p>
<p>现在我们拥有了一个object（对象），我们需要学习如何与之交互。这将我们带入第二个教程：clock.</p>
<h4>资源</h4>
<ul>
<li>
源代码: 01_Object.c</li>
<li>配置文件: 01_Object.ini</li>
</ul>
<hr/>
1) 不过，如果你的配置文件名字与可执行文件匹配并且在同一个文件夹下，它将被自动加载。</p>


<p>No related posts.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.xiping.me/2010/07/orx_tutorial_cn_object.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[译] Orx教程：0.Basic</title>
		<link>http://blog.xiping.me/2010/07/orx_tutorial_cn_basic.html</link>
		<comments>http://blog.xiping.me/2010/07/orx_tutorial_cn_basic.html#comments</comments>
		<pubDate>Mon, 05 Jul 2010 02:05:19 +0000</pubDate>
		<dc:creator>西坪</dc:creator>
				<category><![CDATA[@Translation]]></category>
		<category><![CDATA[orx]]></category>

		<guid isPermaLink="false">http://blog.feihoo.com/?p=633</guid>
		<description><![CDATA[本文译自 orx tutorials 的首页(main)。phpxer 译，九天雁翎 （博客）修订。最新版本见Orx官方Wiki中文教程。
教程
本教程主要包含Orx的基础和高级教程。Orx 是一个开源、跨平台、轻量级、数据驱动的2D游戏引擎。
安装
这些教程演示了如何设置不同的编程环境(IDE)来运行orx1)。

Microsoft Visual  Studio (C++) for Windows: Tutorial / Download (Express version)
CodeLite for Windows,  Linux and Mac OS X: Tutorial / Download
XCode for Mac OS X: Tutorial / Download

基础
本节将要介绍orx的基础知识。
你可以从这里下载Windows(mingw,  msvs2005 &#38; msvs2008). Linux 和 MacOS X下的可执行文件（包括项目文件，数据和源码）。
前九个基础教程（#1 &#8211;  #9）使用默认的orx启动程序为基础(underlying  layer)，这样易于快速测试/制作原型2。
它们被编译成运行时加载（在命令行3) 上  或配置文件中指定它们的名字）的动态连接库。
此外，下面的内容 4) 解释了哪些行为是由默认的orx.exe/orx 启动程序提供的。
这是一个基础的C教程。
由于我们在本教程中使用默认的可执行文件，下面的代码将以插件的方式加载和执行。
另外，一些基础设施有主执行文件为我们处理。
首先，它会加载所有可用的插件和模块。如果你只 [...]


Related posts:<ol><li><a href='http://blog.xiping.me/2010/07/orx_tutorial_cn_object.html' rel='bookmark' title='Permanent Link: [译] Orx教程：1. object'>[译] Orx教程：1. object</a></li>
<li><a href='http://blog.xiping.me/2010/04/virtual-machine-guest-host-share-file.html' rel='bookmark' title='Permanent Link: 虚拟机中Host与Guest文件共享'>虚拟机中Host与Guest文件共享</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>本文译自<a href="http://orx-project.org/wiki/en/orx/tutorials/main"> orx tutorials </a>的<a href="http://orx-project.org/wiki/en/orx/tutorials/main">首页(main)</a>。<a href="http://blog.feihoo.com">phpxer</a> 译，九天雁翎 （<a href="http://blog.csdn.net/vagrxie">博客</a>）修订。最新版本见<a href="http://orx-project.org/wiki/cn/orx/main">Orx官方Wiki中文教程</a>。</p>
<h1 id="internal-source-marker_0.1506159657689189"><span style="font-size: 24pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: bold; font-style: normal; text-decoration: none; vertical-align: baseline;">教程</span></h1>
<p><span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">本教程主要包含Orx的基础和高级教程。Orx 是一个开源、跨平台、轻量级、数据驱动的2D游戏引擎。</span></p>
<h2><span style="font-size: 18pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: bold; font-style: normal; text-decoration: none; vertical-align: baseline;">安装</span></h2>
<p><span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">这些教程演示了如何设置不同的编程环境(IDE)</span><span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; vertical-align: baseline; text-decoration: underline;">来运行</span><a href="https://docs.google.com/document/edit?id=1UGLudR9zxbNw8tNoAqoRX4y45JoBKvjd4OzubCHQJ3E&amp;hl=en&amp;authkey=CMza34sF"><span style="font-size: 11pt; font-family: Arial; color: #000099; background-color: transparent; font-weight: normal; font-style: normal; vertical-align: baseline; text-decoration: underline;">orx</span></a><span style="font-size: 6.6pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: super;">1)</span><span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">。</span></p>
<ul>
<li style="list-style-type: disc; font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"><span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">Microsoft Visual  Studio (C++) for Windows:</span><a href="http://orx-project.org/wiki/en/orx/tutorials/setup_msvs"><span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"> </span><span style="font-size: 11pt; font-family: Arial; color: #000099; background-color: transparent; font-weight: normal; font-style: normal; vertical-align: baseline; text-decoration: underline;">Tutorial</span></a><span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"> /</span><a href="http://www.microsoft.com/Express/VC/"><span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"> </span><span style="font-size: 11pt; font-family: Arial; color: #000099; background-color: transparent; font-weight: normal; font-style: normal; vertical-align: baseline; text-decoration: underline;">Download (Express version)</span></a></li>
<li style="list-style-type: disc; font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"><span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">CodeLite for Windows,  Linux and Mac OS X:</span><a href="http://orx-project.org/wiki/en/orx/tutorials/setup_codelite"><span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"> </span><span style="font-size: 11pt; font-family: Arial; color: #000099; background-color: transparent; font-weight: normal; font-style: normal; vertical-align: baseline; text-decoration: underline;">Tutorial</span></a><span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"> /</span><a href="http://www.codelite.org/"><span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"> </span><span style="font-size: 11pt; font-family: Arial; color: #000099; background-color: transparent; font-weight: normal; font-style: normal; vertical-align: baseline; text-decoration: underline;">Download</span></a></li>
<li style="list-style-type: disc; font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"><span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">XCode for Mac OS X:</span><a href="http://orx-project.org/wiki/en/orx/tutorials/setup_xcode"><span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"> </span><span style="font-size: 11pt; font-family: Arial; color: #000099; background-color: transparent; font-weight: normal; font-style: normal; vertical-align: baseline; text-decoration: underline;">Tutorial</span></a><span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"> /</span><a href="http://developer.apple.com/technology/Xcode.html" class="broken_link" ><span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"> </span><span style="font-size: 11pt; font-family: Arial; color: #000099; background-color: transparent; font-weight: normal; font-style: normal; vertical-align: baseline; text-decoration: underline;">Download</span></a></li>
</ul>
<h2><a href="http://developer.apple.com/technology/Xcode.html" class="broken_link" ><span style="font-size: 18pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: bold; font-style: normal; text-decoration: none; vertical-align: baseline;">基础</span></a></h2>
<p><span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">本节将要介绍orx的基础知识。</span></p>
<p><span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">你可以从</span><a href="https://sourceforge.net/projects/orx/files"><span style="font-size: 11pt; font-family: Arial; color: #000099; background-color: transparent; font-weight: normal; font-style: normal; vertical-align: baseline; text-decoration: underline;">这里</span></a><span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">下载Windows(mingw,  msvs2005 &amp; msvs2008). Linux 和 MacOS X下的</span><span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; vertical-align: baseline; text-decoration: underline;">可执行文件</span><span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">（包括项目文件，数据和源码）。</span></p>
<p><span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">前九个基础教程（#1 &#8211;  #9）使用默认的orx启动程序为</span><span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; vertical-align: baseline; text-decoration: underline;">基础</span><span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">(underlying  layer)，这样易于快速测试/制作原型</span><span style="font-size: 6.6pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: super;">2</span><span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">。</span></p>
<p><span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">它们被编译成运行时加载（在命令行</span><span style="font-size: 6.6pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: super;">3)</span><span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"> 上  或配置文件中指定它们的名字）的动态连接库。</span></p>
<p><span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">此外，下面的内容</span><span style="font-size: 6.6pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: super;"> </span><a href="http://orx-project.org/wiki/en/orx/tutorials/main#fn__4"><span style="font-size: 6.6pt; font-family: Arial; color: #000099; background-color: transparent; font-weight: normal; font-style: normal; vertical-align: super; text-decoration: underline;">4)</span></a><span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"> 解释了哪些行为是由默认的orx.exe/orx 启动程序提供的。</span></p>
<p><span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">这是一个基础的C教程。</span><br />
<span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">由于我们在本教程中使用默认的可执行文件，下面的代码将以插件的方式加载和执行。</span></p>
<p><span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">另外，一些</span><span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; vertical-align: baseline; text-decoration: underline;">基础设施</span><span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">有</span><span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; vertical-align: baseline; text-decoration: underline;">主执行文件</span><span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">为我们处理。</span><br />
<span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">首先，它会加载所有可用的插件和模块。如果你只 需要其中的一些，最好编写你自己的</span><span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; vertical-align: baseline; text-decoration: underline;">可执行文件</span><span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">而不是插件。这部分包含在</span><a href="http://orx-project.org/wiki/en/orx/tutorials/standalone"><span style="font-size: 11pt; font-family: Arial; color: #000099; background-color: transparent; font-weight: normal; font-style: normal; vertical-align: baseline; text-decoration: underline;">后面的教程</span></a><span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">中。</span></p>
<p><span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">主执行文件还处理下面这些</span><span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; vertical-align: baseline; text-decoration: underline;">键盘输入</span><span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">：</span></p>
<p><span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">* F11 是</span><span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; vertical-align: baseline; text-decoration: underline;">纵向对齐切换</span><br />
<span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">* Escape 退出</span><br />
<span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">* F12 截屏</span><br />
<span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">* 退格键(Backspace)  重新载入全部配置文件</span></p>
<p><span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">如果有 orxSYSTEM_EVENT_CLOSE事件发生，程序也会退出。</span></p>
<p><span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">不过，如果使用  orx作为传统库构建你自己的可执行文件当然也是可以的（也很容易做到）。在</span><a href="http://orx-project.org/wiki/en/orx/tutorials/standalone"><span style="font-size: 11pt; font-family: Arial; color: #000099; background-color: transparent; font-weight: normal; font-style: normal; vertical-align: baseline; text-decoration: underline;">教程 #10</span></a><span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">(使用C++编写) 和 </span><a href="http://orx-project.org/wiki/en/orx/tutorials/spawner"><span style="font-size: 11pt; font-family: Arial; color: #000099; background-color: transparent; font-weight: normal; font-style: normal; vertical-align: baseline; text-decoration: underline;">教程 #11</span></a><span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"> (使用 C编写)。</span><a href="http://orx-project.org/wiki/en/orx/tutorials/standalone"><span style="font-size: 11pt; font-family: Arial; color: #000099; background-color: transparent; font-weight: normal; font-style: normal; vertical-align: baseline; text-decoration: underline;">教程 #10</span></a><span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"> 还演示了如何使用orx编写C++代码</span><span style="font-size: 6.6pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: super;">5)</span><span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">。  同样地，你可以用任何可与C连接的语言编写程序。</span></p>
<p><span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">在将来的发布中将会为某些常见语言提供封装。如果你想编写这种封装库，为orx做贡献，请通过</span><a href="http://forum.orx-project.org/"><span style="font-size: 11pt; font-family: Arial; color: #000099; background-color: transparent; font-weight: normal; font-style: normal; vertical-align: baseline; text-decoration: underline;">论坛</span></a><span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">联系我们。</span></p>
<p><span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">当前提供的基础教程列表：</span></p>
<ol>
<li style="list-style-type: decimal; font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"><span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">[C]</span><a href="http://orx-project.org/wiki/en/orx/tutorials/object"><span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"> </span><span style="font-size: 11pt; font-family: Arial; color: #000099; background-color: transparent; font-weight: normal; font-style: normal; vertical-align: baseline; text-decoration: underline;">object</span></a></li>
<li style="list-style-type: decimal; font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"><span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">[C]</span><a href="http://orx-project.org/wiki/en/orx/tutorials/clock"><span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"> </span><span style="font-size: 11pt; font-family: Arial; color: #000099; background-color: transparent; font-weight: normal; font-style: normal; vertical-align: baseline; text-decoration: underline;">clock</span></a></li>
<li style="list-style-type: decimal; font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"><span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">[C]</span><a href="http://orx-project.org/wiki/en/orx/tutorials/frame"><span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"> </span><span style="font-size: 11pt; font-family: Arial; color: #000099; background-color: transparent; font-weight: normal; font-style: normal; vertical-align: baseline; text-decoration: underline;">frame</span></a></li>
<li style="list-style-type: decimal; font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"><span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">[C]</span><a href="http://orx-project.org/wiki/en/orx/tutorials/anim"><span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"> </span><span style="font-size: 11pt; font-family: Arial; color: #000099; background-color: transparent; font-weight: normal; font-style: normal; vertical-align: baseline; text-decoration: underline;">animation</span></a></li>
<li style="list-style-type: decimal; font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"><span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">[C]</span><a href="http://orx-project.org/wiki/en/orx/tutorials/viewport"><span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"> </span><span style="font-size: 11pt; font-family: Arial; color: #000099; background-color: transparent; font-weight: normal; font-style: normal; vertical-align: baseline; text-decoration: underline;">viewport &amp;  camera</span></a></li>
<li style="list-style-type: decimal; font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"><span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">[C]</span><a href="http://orx-project.org/wiki/en/orx/tutorials/sound"><span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"> </span><span style="font-size: 11pt; font-family: Arial; color: #000099; background-color: transparent; font-weight: normal; font-style: normal; vertical-align: baseline; text-decoration: underline;">sound &amp; music</span></a></li>
<li style="list-style-type: decimal; font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"><span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">[C]</span><a href="http://orx-project.org/wiki/en/orx/tutorials/fx"><span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"> </span><span style="font-size: 11pt; font-family: Arial; color: #000099; background-color: transparent; font-weight: normal; font-style: normal; vertical-align: baseline; text-decoration: underline;">fx</span></a></li>
<li style="list-style-type: decimal; font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"><span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">[C]</span><a href="http://orx-project.org/wiki/en/orx/tutorials/physics"><span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"> </span><span style="font-size: 11pt; font-family: Arial; color: #000099; background-color: transparent; font-weight: normal; font-style: normal; vertical-align: baseline; text-decoration: underline;">physics</span></a></li>
<li style="list-style-type: decimal; font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"><span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">[C]</span><a href="http://orx-project.org/wiki/en/orx/tutorials/scrolling"><span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"> </span><span style="font-size: 11pt; font-family: Arial; color: #000099; background-color: transparent; font-weight: normal; font-style: normal; vertical-align: baseline; text-decoration: underline;">scrolling</span></a></li>
<li style="list-style-type: decimal; font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"><span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">[C++]</span><a href="http://orx-project.org/wiki/en/orx/tutorials/standalone"><span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"> </span><span style="font-size: 11pt; font-family: Arial; color: #000099; background-color: transparent; font-weight: normal; font-style: normal; vertical-align: baseline; text-decoration: underline;">stand alone &amp;  localization</span></a></li>
<li style="list-style-type: decimal; font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"><span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">[C]</span><a href="http://orx-project.org/wiki/en/orx/tutorials/spawner"><span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"> </span><span style="font-size: 11pt; font-family: Arial; color: #000099; background-color: transparent; font-weight: normal; font-style: normal; vertical-align: baseline; text-decoration: underline;">spawner &amp;  shader</span></a></li>
</ol>
<h2><a href="http://orx-project.org/wiki/en/orx/tutorials/spawner"><span style="font-size: 18pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: bold; font-style: normal; text-decoration: none; vertical-align: baseline;">社区</span></a></h2>
<p><span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">下面这些教程由社区创建，它们是了解如何使用 orx的不错的资源，可以在这里寻找到对一些简单问题的解答。</span></p>
<ul>
<li style="list-style-type: disc; font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"><a href="http://orx-project.org/wiki/en/orx/tutorials/community/grey"><span style="font-size: 11pt; font-family: Arial; color: #000099; background-color: transparent; font-weight: normal; font-style: normal; vertical-align: baseline; text-decoration: underline;">Grey&#8217;s tutorials</span></a><span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">（英文版）</span></li>
</ul>
<p><a href="http://orx-project.org/wiki/en/orx/tutorials/community/grey"></a><br />
<a href="http://orx-project.org/wiki/en/orx/tutorials/main#fnt__1"><span style="font-size: 11pt; font-family: Arial; color: #000099; background-color: transparent; font-weight: normal; font-style: normal; vertical-align: baseline; text-decoration: underline;">1)</span></a><span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"> 所有的IDE都是免费可以从英特网上下载的。</span><br />
<a href="http://orx-project.org/wiki/en/orx/tutorials/main#fnt__2"><span style="font-size: 11pt; font-family: Arial; color: #000099; background-color: transparent; font-weight: normal; font-style: normal; vertical-align: baseline; text-decoration: underline;">2)</span></a><span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"> one line for the  whole initialization, no main function to write, no loop to handle</span><br />
<span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">用一行代码完成初始化，不需要写main函数， 没有</span><span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; vertical-align: baseline; text-decoration: underline;">循环</span><span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">要处理</span><br />
<a href="http://orx-project.org/wiki/en/orx/tutorials/main#fnt__3"><span style="font-size: 11pt; font-family: Arial; color: #000099; background-color: transparent; font-weight: normal; font-style: normal; vertical-align: baseline; text-decoration: underline;">3)</span></a><span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"> 另提供了 .bat/.sh  脚本方便启动所有示例</span><br />
<a href="http://orx-project.org/wiki/en/orx/tutorials/main#fnt__4"><span style="font-size: 11pt; font-family: Arial; color: #000099; background-color: transparent; font-weight: normal; font-style: normal; vertical-align: baseline; text-decoration: underline;">4)</span></a><span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"> 你将在在所有教程的源文件的开始处看到这些内容</span><br />
<a href="http://orx-project.org/wiki/en/orx/tutorials/main#fnt__5"><span style="font-size: 11pt; font-family: Arial; color: #000099; background-color: transparent; font-weight: normal; font-style: normal; vertical-align: baseline; text-decoration: underline;">5)</span></a><span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;"> Orx本身使用C编写</span></p>


<p>Related posts:<ol><li><a href='http://blog.xiping.me/2010/07/orx_tutorial_cn_object.html' rel='bookmark' title='Permanent Link: [译] Orx教程：1. object'>[译] Orx教程：1. object</a></li>
<li><a href='http://blog.xiping.me/2010/04/virtual-machine-guest-host-share-file.html' rel='bookmark' title='Permanent Link: 虚拟机中Host与Guest文件共享'>虚拟机中Host与Guest文件共享</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://blog.xiping.me/2010/07/orx_tutorial_cn_basic.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>程序员提高工作效率的方法</title>
		<link>http://blog.xiping.me/2010/04/work-effcient-thoughts.html</link>
		<comments>http://blog.xiping.me/2010/04/work-effcient-thoughts.html#comments</comments>
		<pubDate>Thu, 29 Apr 2010 14:56:30 +0000</pubDate>
		<dc:creator>西坪</dc:creator>
				<category><![CDATA[$Architecture & design]]></category>
		<category><![CDATA[$软件工程与管理]]></category>
		<category><![CDATA[effcient]]></category>
		<category><![CDATA[systemdesign]]></category>

		<guid isPermaLink="false">http://blog.feihoo.com/?p=619</guid>
		<description><![CDATA[最近一段时间以来，效率相当地高。 纵观前些年的工作效率中，少有这么利落快速而且不加班的。 回顾这几年，我工作效率的提高主要有下面的几个方面。
一、集中目标
专注目标。凡是工作效率高的时间段里，工作目标都很明确。每天一上班，心里就想明白了今天要干什么，每天下班时，想想今天都实现了什么，有什么目标还没有实现。尽管每天早上来了先看看股票新闻，中午饭后看看股票新闻，偶尔下午还打个盹什么的，但工作的时候确实格外专注，丝毫也不会走神。

分离与当前无关的任务/问题。专注目标不是那么容易做到的。印象中以前工作中经常会碰到的问题是工作中遇到的问题。一方面可能得益于基本功的增强，最近虽然也遇到了一些问题，但是都能够通过简单阅读或查找文档，或浏览问题相关的库的源码解决； 另一方面，遇到的问题我总是避繁就简，首先倾向于寻找简单可用可靠的方案，并将心中的疑虑记录下来，集中成一个列表，工作之外翻翻书，系统思考和学习，而不会因为这个问题而叉开思路对相关的内容研究一番。总之，专注当前的任务，把新问题记录下来，回头再专心攻克。
例如我第一次用ibatis，遇到了一些表可以用集合和映射来加强Pojo的OO功能，但是我并不熟悉ibatis的这些特性，并且使用简单的方案也是可行的，于是就直接使用简便方案(在我看来，ibatis主要是将SQL集中起来管理、简化SQL操纵，对OO不感冒)。
工作列表。不论是开发还是设计，一个文本格式的位于源代码存储系统下的待办工作列表与IDE中的TODO项一起构成了专注目标的重要工具。工作目标分解是基本工作步骤，记录工作中产生的新的问题（任务），这样，子问题越来越多，项目中要干的事情越来越丰富。经常性地调整当前工作任务列表，根据重要性对这些任务进行划分。每天都干掉一些问题，经常想着那些最重要的问题。
简单但有迹可寻的设计材料。在思考和工作的过程中，一方面，项目的过程通常比较长，另一方面经验相对丰富的人手头总是有多个事情在并行进行。当时间太长记不清出了或者是切换任务时，经常要查看此前的代码和设计，易于修改以及有历史记录的设计材料对于保持设计思路的完整十分有意义。（设计材料还应该包括重要的图）
正式准确可以依靠的需求文档。这一条无论怎么说都不过分，遇到需求不确定的地方，就去查需求文档。如果没有，就请能够回答的人来回答，委托给他，先去做别的。细想在上一家公司，经常要承担多种角色，甚至连需求也经常没人给一个最终决策，设计开发的时候在模棱两可的需求之间做决定，很烦心。对于一个设计/开发人员而言，需求人员在需求问题方面就是绝对的权威。如果有些建议，可以建议，但一切均以需求/产品人员为准。
单元测试。另一有助于集中精力编码的就是单元测试。单元测试让我集中精力实现当前的功能，需要依赖的其他功能，我总是先生成一个接口，让当前的功能通过测试后再专心去实现该接口。一天下来，一个一个的测试点亮了绿色，一个一个的接口被实现，整天都是十分惬意的。单元测试的另外一个收益就是放心地去重构吧，放心地去做新的特性吧。
二、简化问题的能力
无论是在广义的工作方法/工作态度上，还是在针对具体问题的设计/实现上，我认为最重要的个人能力就是化繁为简了。化繁为简是所有工作方法/软件设计的核心。将那些可以砍掉的工作砍掉（最多做个记录），做到尽可能地经济，尽可能地简单。
从工作方法和态度上来讲，真正需要去做的工作才值得去做，大力砍掉那些不应该在当前工作中处理的事情。例如不必要的优化，不必要的扩展性，不必要的性能，不必要的功能，可以不要的技术，不必要的流程，不必要的文档，统统砍掉，一切可以没有的全都不能有。
工作中也可能遇到非关键的难题，通常绕过它们，使用更简单的方案就是了。纠缠于这些不重要的难题，最容易浪费时间。例如，eclipse忽然坏掉了，最好的方法是重装一个; 又如以前我经常自己建一个持续集成服务器，现在我直接养成每次写完代码手工跑一遍的习惯（前提是够用）。简化你的工作！简化！
从设计/实现来讲，最好的方案就是最简单直接、一眼就能看懂的方案。记得刚到一个新的环境，有一个统计任务，既要用到数据库也要用缓存，我做了精细的设计来保证最终一致性，状态流程都很完整，并且使用线程池来并发运行分批处理，最后再合并。虽然控制得很完美很精细，但是流程和结构都很复杂。上头根据此前的项目经验给出了一个更简单的例子，直接将各个任务划分为多个线程，分开存储，到了该统计的时候，冻结数据在所有的分区上做统计。状态砍掉一半，流程缩减一半。
事实上，作为简单直接的一个附带效应，最简单直接的方式，通常性能也最好。
简化问题的能力，是一个人的核心能力。
三、基本功
基本功的内容十分复杂。首先，对整个计算机体系的理解，对操作系统/虚拟机/数据库本质的理解，对语言基础类和库的理解，我觉得是核心基本功。
第二项基本功，就是学习能力。 通过快速阅读核心文档理解核心思想，然后其他的东西总是能从文档中查到就行。细枝末节的东西，即学即用，学过就忘可也。
第三项基本功，就是文档、资料的搜索和收集。
要想在工作中如行云流水，另外一个方面就是避开暂时还不熟悉的技术和工具，不熟悉的东西很难用好，更难用顺畅。尤其是那些纠结复杂、华而不实的技术，不要去碰。这属于简化能力的范畴。
四、工具
选择工具的核心标准，就是简单朴素可信赖。
文本格式的设计，加上易于修改的图。 我喜欢用一个简单的文本格式来记录设计，随时修改，随时查阅。而附上几幅简单直接的图，经常能够更简单直接地表达更多的内容。
简单的可信赖的工具。我曾经将很长的时间用来构建Maven的环境上，用Maven管理依赖，尤其是跟Eclipse协作时，经常出现诡异。现在我用ant，或者只用Maven，maven不与eclipse纠缠在一起。如果一个工具出几次诡异现象，那就干脆丢掉它。
版本管理工具。 不仅仅源码要由版本管理，整个项目过程的所有知识，全部用版本管理系统管理起来，集中存放。现在我用subversion和git。


Related posts:设计与开发的五条原则



Related posts:<ol><li><a href='http://blog.xiping.me/2009/12/software-design-devolopment-pricinples.html' rel='bookmark' title='Permanent Link: 设计与开发的五条原则'>设计与开发的五条原则</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>最近一段时间以来，效率相当地高。 纵观前些年的工作效率中，少有这么利落快速而且不加班的。 回顾这几年，我工作效率的提高主要有下面的几个方面。</p>
<h3>一、集中目标</h3>
<p><strong>专注目标。</strong>凡是工作效率高的时间段里，工作目标都很明确。每天一上班，心里就想明白了今天要干什么，每天下班时，想想今天都实现了什么，有什么目标还没有实现。尽管每天早上来了先看看股票新闻，中午饭后看看股票新闻，偶尔下午还打个盹什么的，但工作的时候确实格外专注，丝毫也不会走神。<br />
<strong><br />
分离与当前无关的任务/问题。</strong>专注目标不是那么容易做到的。印象中以前工作中经常会碰到的问题是工作中遇到的问题。一方面可能得益于基本功的增强，最近虽然也遇到了一些问题，但是都能够通过简单阅读或查找文档，或浏览问题相关的库的源码解决； 另一方面，遇到的问题我总是避繁就简，首先倾向于寻找简单可用可靠的方案，并将心中的疑虑记录下来，集中成一个列表，工作之外翻翻书，系统思考和学习，而不会因为这个问题而叉开思路对相关的内容研究一番。总之，专注当前的任务，把新问题记录下来，回头再专心攻克。</p>
<p>例如我第一次用ibatis，遇到了一些表可以用集合和映射来加强Pojo的OO功能，但是我并不熟悉ibatis的这些特性，并且使用简单的方案也是可行的，于是就直接使用简便方案(在我看来，ibatis主要是将SQL集中起来管理、简化SQL操纵，对OO不感冒)。</p>
<p><strong>工作列表。</strong>不论是开发还是设计，一个文本格式的位于源代码存储系统下的待办工作列表与IDE中的TODO项一起构成了专注目标的重要工具。工作目标分解是基本工作步骤，记录工作中产生的新的问题（任务），这样，子问题越来越多，项目中要干的事情越来越丰富。经常性地调整当前工作任务列表，根据重要性对这些任务进行划分。每天都干掉一些问题，经常想着那些最重要的问题。</p>
<p><strong>简单但有迹可寻的设计材料。</strong>在思考和工作的过程中，一方面，项目的过程通常比较长，另一方面经验相对丰富的人手头总是有多个事情在并行进行。当时间太长记不清出了或者是切换任务时，经常要查看此前的代码和设计，易于修改以及有历史记录的设计材料对于保持设计思路的完整十分有意义。（设计材料还应该包括重要的图）</p>
<p><strong>正式准确可以依靠的需求文档。</strong>这一条无论怎么说都不过分，遇到需求不确定的地方，就去查需求文档。如果没有，就请能够回答的人来回答，委托给他，先去做别的。细想在上一家公司，经常要承担多种角色，甚至连需求也经常没人给一个最终决策，设计开发的时候在模棱两可的需求之间做决定，很烦心。对于一个设计/开发人员而言，需求人员在需求问题方面就是绝对的权威。如果有些建议，可以建议，但一切均以需求/产品人员为准。</p>
<p><strong>单元测试。</strong>另一有助于集中精力编码的就是单元测试。单元测试让我集中精力实现当前的功能，需要依赖的其他功能，我总是先生成一个接口，让当前的功能通过测试后再专心去实现该接口。一天下来，一个一个的测试点亮了绿色，一个一个的接口被实现，整天都是十分惬意的。单元测试的另外一个收益就是放心地去重构吧，放心地去做新的特性吧。</p>
<h3>二、简化问题的能力</h3>
<p>无论是在广义的工作方法/工作态度上，还是在针对具体问题的设计/实现上，我认为最重要的个人能力就是化繁为简了。化繁为简是所有工作方法/软件设计的核心。将那些可以砍掉的工作砍掉（最多做个记录），做到尽可能地经济，尽可能地简单。</p>
<p>从工作方法和态度上来讲，真正需要去做的工作才值得去做，大力砍掉那些不应该在当前工作中处理的事情。例如不必要的优化，不必要的扩展性，不必要的性能，不必要的功能，可以不要的技术，不必要的流程，不必要的文档，统统砍掉，<strong>一切可以没有的全都不能有</strong>。</p>
<p>工作中也可能遇到非关键的难题，通常绕过它们，使用更简单的方案就是了。纠缠于这些不重要的难题，最容易浪费时间。例如，eclipse忽然坏掉了，最好的方法是重装一个; 又如以前我经常自己建一个持续集成服务器，现在我直接养成每次写完代码手工跑一遍的习惯（前提是够用）。简化你的工作！简化！</p>
<p>从设计/实现来讲，最好的方案就是最简单直接、一眼就能看懂的方案。记得刚到一个新的环境，有一个统计任务，既要用到数据库也要用缓存，我做了精细的设计来保证最终一致性，状态流程都很完整，并且使用线程池来并发运行分批处理，最后再合并。虽然控制得很完美很精细，但是流程和结构都很复杂。上头根据此前的项目经验给出了一个更简单的例子，直接将各个任务划分为多个线程，分开存储，到了该统计的时候，冻结数据在所有的分区上做统计。状态砍掉一半，流程缩减一半。</p>
<p>事实上，作为简单直接的一个附带效应，最简单直接的方式，通常性能也最好。</p>
<p><strong>简化问题的能力，是一个人的核心能力。</strong></p>
<h3>三、基本功</h3>
<p>基本功的内容十分复杂。首先，对整个计算机体系的理解，对操作系统/虚拟机/数据库本质的理解，对语言基础类和库的理解，我觉得是<strong>核心基本功</strong>。</p>
<p>第二项基本功，就是<strong>学习能力</strong>。 通过快速阅读核心文档理解核心思想，然后其他的东西总是能从文档中查到就行。细枝末节的东西，即学即用，学过就忘可也。</p>
<p>第三项基本功，就是<strong>文档、资料的搜索和收集</strong>。</p>
<p>要想在工作中如行云流水，另外一个方面就是避开暂时还不熟悉的技术和工具，不熟悉的东西很难用好，更难用顺畅。尤其是那些纠结复杂、华而不实的技术，不要去碰。这属于简化能力的范畴。</p>
<h3>四、工具</h3>
<p>选择工具的核心标准，就是<strong>简单朴素可信赖</strong>。</p>
<p>文本格式的设计，加上易于修改的图。 我喜欢用一个简单的文本格式来记录设计，随时修改，随时查阅。而附上几幅简单直接的图，经常能够更简单直接地表达更多的内容。</p>
<p>简单的可信赖的工具。我曾经将很长的时间用来构建Maven的环境上，用Maven管理依赖，尤其是跟Eclipse协作时，经常出现诡异。现在我用ant，或者只用Maven，maven不与eclipse纠缠在一起。如果一个工具出几次诡异现象，那就干脆丢掉它。</p>
<p>版本管理工具。 不仅仅源码要由版本管理，整个项目过程的所有知识，全部用版本管理系统管理起来，集中存放。现在我用subversion和git。</p>


<p>Related posts:<ol><li><a href='http://blog.xiping.me/2009/12/software-design-devolopment-pricinples.html' rel='bookmark' title='Permanent Link: 设计与开发的五条原则'>设计与开发的五条原则</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://blog.xiping.me/2010/04/work-effcient-thoughts.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>虚拟机中Host与Guest文件共享</title>
		<link>http://blog.xiping.me/2010/04/virtual-machine-guest-host-share-file.html</link>
		<comments>http://blog.xiping.me/2010/04/virtual-machine-guest-host-share-file.html#comments</comments>
		<pubDate>Tue, 13 Apr 2010 09:09:50 +0000</pubDate>
		<dc:creator>西坪</dc:creator>
				<category><![CDATA[server & system]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[opensuse]]></category>
		<category><![CDATA[vmware]]></category>

		<guid isPermaLink="false">http://blog.feihoo.com/?p=609</guid>
		<description><![CDATA[   最近很多工作在Linux下做，但是因为整个公司的环境是Windows，很多事情也经常要在Windows下处理。于是在Windows XP上用VMware搭建了OpenSUSE，同时使用这两种系统。经过这段时间的使用，觉得OpenSUSE的桌面支持确实是做得不错的，似乎比Ubuntu更加方便简单。但是Ubuntu更流行，很多简单的设置问题，网络上随处可见Ubuntu的解决方案，而SUSE的方案却难觅踪影。 
   例如，我经常使用VMWare的共享文件夹特性来在Host与Guest之间交换数据，共享文件。 但是在OpenSUSE下，却没有找到合适的方法。最终，不得不求助于Samba。 Samba在OpenSUSE上的安装是很方便的，基本上遵照 How To Samba With openSuse 10.3 And Windows XP 的指导，三两步就完成了。 完毕以后，在Windows XP 下映射一个盘符到 \\GUEST_HOSTNAME\users 就完成了。我完全关闭了Guest上的防火墙，有防火墙反而可能招致麻烦。
而在OpenSUSE上访问Windows XP也很简单，基本上遵照 SDB:Access to Windows Shares 的 Manual Procedure 部分，将Windows XP共享目录加入到 /etc/fstab 中：

  1 /dev/sda1            swap   [...]


Related posts:<ol><li><a href='http://blog.xiping.me/2010/03/my_vps_experience.html' rel='bookmark' title='Permanent Link: 我的VPS使用经验'>我的VPS使用经验</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>   最近很多工作在Linux下做，但是因为整个公司的环境是Windows，很多事情也经常要在Windows下处理。于是在Windows XP上用VMware搭建了OpenSUSE，同时使用这两种系统。经过这段时间的使用，觉得OpenSUSE的桌面支持确实是做得不错的，似乎比Ubuntu更加方便简单。但是Ubuntu更流行，很多简单的设置问题，网络上随处可见Ubuntu的解决方案，而SUSE的方案却难觅踪影。 </p>
<p>   例如，我经常使用VMWare的共享文件夹特性来在Host与Guest之间交换数据，共享文件。 但是在OpenSUSE下，却没有找到合适的方法。最终，不得不求助于Samba。 Samba在OpenSUSE上的安装是很方便的，基本上遵照 <a href="http://www.tweakhound.com/linux/samba/page_1.htm">How To Samba With openSuse 10.3 And Windows XP</a> 的指导，三两步就完成了。 完毕以后，在Windows XP 下映射一个盘符到 \\GUEST_HOSTNAME\users 就完成了。我完全关闭了Guest上的防火墙，有防火墙反而可能招致麻烦。</p>
<p>而在OpenSUSE上访问Windows XP也很简单，基本上遵照 <a href="http://en.opensuse.org/SDB:Access_to_Windows_Shares" class="broken_link" >SDB:Access to Windows Shares</a> 的 Manual Procedure 部分，将Windows XP共享目录加入到 /etc/fstab 中：</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">  <span style="color: #000000;">1</span> <span style="color: #000000; font-weight: bold;">/</span>dev<span style="color: #000000; font-weight: bold;">/</span>sda1            swap                 swap       defaults              <span style="color: #000000;">0</span> <span style="color: #000000;">0</span>
  <span style="color: #000000;">2</span> <span style="color: #000000; font-weight: bold;">/</span>dev<span style="color: #000000; font-weight: bold;">/</span>sda2            <span style="color: #000000; font-weight: bold;">/</span>                    ext4       acl,user_xattr        <span style="color: #000000;">1</span> <span style="color: #000000;">1</span>
  <span style="color: #000000;">3</span> <span style="color: #000000; font-weight: bold;">/</span>dev<span style="color: #000000; font-weight: bold;">/</span>sda3            <span style="color: #000000; font-weight: bold;">/</span>home                ext4       acl,user_xattr        <span style="color: #000000;">1</span> <span style="color: #000000;">2</span>
  <span style="color: #000000;">4</span> proc                 <span style="color: #000000; font-weight: bold;">/</span>proc                proc       defaults              <span style="color: #000000;">0</span> <span style="color: #000000;">0</span>
  <span style="color: #000000;">5</span> sysfs                <span style="color: #000000; font-weight: bold;">/</span>sys                 sysfs      noauto                <span style="color: #000000;">0</span> <span style="color: #000000;">0</span>
  <span style="color: #000000;">6</span> debugfs              <span style="color: #000000; font-weight: bold;">/</span>sys<span style="color: #000000; font-weight: bold;">/</span>kernel<span style="color: #000000; font-weight: bold;">/</span>debug    debugfs    noauto                <span style="color: #000000;">0</span> <span style="color: #000000;">0</span>
  <span style="color: #000000;">7</span> usbfs                <span style="color: #000000; font-weight: bold;">/</span>proc<span style="color: #000000; font-weight: bold;">/</span>bus<span style="color: #000000; font-weight: bold;">/</span>usb        usbfs      noauto                <span style="color: #000000;">0</span> <span style="color: #000000;">0</span>
  <span style="color: #000000;">8</span> devpts               <span style="color: #000000; font-weight: bold;">/</span>dev<span style="color: #000000; font-weight: bold;">/</span>pts             devpts     <span style="color: #007800;">mode</span>=0620,<span style="color: #007800;">gid</span>=<span style="color: #000000;">5</span>       <span style="color: #000000;">0</span> <span style="color: #000000;">0</span>
  <span style="color: #000000;">9</span> <span style="color: #000000; font-weight: bold;">//</span>x.x.x.x<span style="color: #000000; font-weight: bold;">/</span>work   <span style="color: #000000; font-weight: bold;">/</span>mnt<span style="color: #000000; font-weight: bold;">/</span>windows    cifs  auto,<span style="color: #007800;">uid</span>=liuz,<span style="color: #007800;">gid</span>=<span style="color: #c20cb9; font-weight: bold;">users</span>,<span style="color: #007800;"><span style="color: #7a0874; font-weight: bold;">umask</span></span>=0002,<span style="color: #007800;">iocharset</span>=utf8,<span style="color: #007800;">credentials</span>=<span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>winpasswd <span style="color: #000000;">0</span> <span style="color: #000000;">0</span></pre></div></div>

<p>别忘了保护你的密码文件：</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">chmod</span> <span style="color: #000000;">600</span> <span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>winpassword</pre></div></div>

<p>特殊之处，是指定了一个 uid=liuz， 将文件的所有者指定为liuz这个用户，方便增删改等操作。有关 uid,gid,umask等的解释如下： (<a href="http://forum.ubuntu.org.cn/viewtopic.php?f=50&#038;t=138806" class="broken_link" >来源</a>)</p>
<blockquote><p>
uid与gid<br />
uid即user identifer，gid即group identifer。设置所有文件的所有者和群组。gid=64，即权限为所有者可读、写，不能执行，群组用户可读、不能写、执行。<br />
umask<br />
umask即user mask，即用户屏蔽。umask=007，即所有文件的权限中，屏蔽其它使用者的读、写、执行权限。 </p></blockquote>
<h5>总结</h5>
<p>总结一下我使用的这三种方法：</p>
<ul>
<li>1) 使用VMware提供的共享文件夹功能。</li>
<li>2) 使用Samba为Windows Host OS 共享Linux Guest OS文件系统。</li>
<li>3) 在Linux Guest OS中mount Host OS （Windows系统）的共享文件夹。 </li>
</ul>


<p>Related posts:<ol><li><a href='http://blog.xiping.me/2010/03/my_vps_experience.html' rel='bookmark' title='Permanent Link: 我的VPS使用经验'>我的VPS使用经验</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://blog.xiping.me/2010/04/virtual-machine-guest-host-share-file.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>导出Memcached中的全部数据</title>
		<link>http://blog.xiping.me/2010/04/dump_memcached.html</link>
		<comments>http://blog.xiping.me/2010/04/dump_memcached.html#comments</comments>
		<pubDate>Mon, 05 Apr 2010 08:34:13 +0000</pubDate>
		<dc:creator>西坪</dc:creator>
				<category><![CDATA[$Programming]]></category>
		<category><![CDATA[server & system]]></category>
		<category><![CDATA[memcached]]></category>
		<category><![CDATA[nosql]]></category>
		<category><![CDATA[导出]]></category>

		<guid isPermaLink="false">http://blog.feihoo.com/?p=564</guid>
		<description><![CDATA[Update(Mar 18th, 2011) 最近，我们针对数十个Memcached集群（数据从几G到几十G）进行了数据转换工作，虽是不得已而为之，但是整个过程还算顺利。编写导出脚本需注意的是cachedump得到的很多key其实已经过期了，这部分过期的key要通过get()操作，将之从Memcached中清除，使之不再出现在下次的cachedump中。
================================================================
因为特别的原因，需要从Memcached中导出所有的数据。因为Memcached对数据的遍历是明确不支持的，所以必须想歪门邪道的方法。
现在网络上主要有两种思路，一种是通过Memcached提供的stats cachedump命令导出，例如下面这些网址：

dump all keys from memcached
Dumping MemcacheD Content (Keys) with PHP
Robbin的文章

以上文章都利用这个命令导出了部分数据。但事实上，cachedump的输出会限制在 2*1024*1024=2M 字节的长度内（Memecahed source: items.c, func: do_item_cachedump），其导出的格式如下所示：

ITEM key990017 [1 b; 1270394155 s]
ITEM key990016 [1 b; 1270394155 s]
ITEM key990015 [1 b; 1270394155 s]
ITEM key990014 [1 b; 1270394155 s]

即使不计算key的长度，每一条数据至少要占掉近三十个字节，2M最多到几万项数据。对于Item数量很大的情况下，这种方法并不能导出全部数据。
下面的地址佐证了这些观点。

官方邮件列表上的解释
上面提到的文章 memcache dump and load 的读者也在评论中进行了分析

第二种思路来自 Twitter infrastructure team 的 Evan Weaver 的 peeping into memcached [...]


Related posts:<ol><li><a href='http://blog.xiping.me/2009/01/flex%e4%b8%ad%e7%9a%84%e5%af%b9%e8%b1%a1%e6%af%94%e8%be%83%ef%bc%88%e7%9b%b8%e7%ad%89%e6%80%a7%ef%bc%89.html' rel='bookmark' title='Permanent Link: Flex中的对象比较（相等性）'>Flex中的对象比较（相等性）</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p><strong>Update(Mar 18th, 2011)</strong> 最近，我们针对数十个Memcached集群（数据从几G到几十G）进行了数据转换工作，虽是不得已而为之，但是整个过程还算顺利。编写导出脚本需注意的是cachedump得到的很多key其实已经过期了，这部分过期的key要通过get()操作，将之从Memcached中清除，使之不再出现在下次的cachedump中。<br />
================================================================</p>
<p>因为特别的原因，需要从<a href="http://memcached.org">Memcached</a>中导出所有的数据。因为<a href="http://code.google.com/p/memcached/wiki/FAQ#Can_I_iterate_the_items_of_the_memcached_server?">Memcached对数据的遍历是明确不支持</a>的，所以必须想歪门邪道的方法。</p>
<p>现在网络上主要有两种思路，一种是通过Memcached提供的stats cachedump命令导出，例如下面这些网址：</p>
<ul>
<li><a href="http://groups.google.com/group/memcached/browse_thread/thread/d8f3637b84cca7b7?pli=1">dump all keys from memcached</a></li>
<li><a href="http://100days.de/serendipity/archives/55-Dumping-MemcacheD-Content-Keys-with-PHP.html">Dumping MemcacheD Content (Keys) with PHP</a></li>
<li><a href="http://robbin.javaeye.com/blog/252345">Robbin的文章</a></li>
</ul>
<p>以上文章都利用这个命令导出了部分数据。但事实上，cachedump的输出会限制在 2*1024*1024=2M 字节的长度内（<a href="http://github.com/memcached/memcached/blob/master/items.c#L357">Memecahed source: items.c, func: do_item_cachedump</a>），其导出的格式如下所示：</p>

<div class="wp_syntax"><div class="code"><pre class="sh" style="font-family:monospace;">ITEM key990017 [1 b; 1270394155 s]
ITEM key990016 [1 b; 1270394155 s]
ITEM key990015 [1 b; 1270394155 s]
ITEM key990014 [1 b; 1270394155 s]</pre></div></div>

<p>即使不计算key的长度，每一条数据至少要占掉近三十个字节，2M最多到几万项数据。对于Item数量很大的情况下，这种方法并不能导出全部数据。</p>
<p>下面的地址佐证了这些观点。</p>
<ul>
<li><a href="http://lists.danga.com/pipermail/memcached/2007-April/003906.html">官方邮件列表上的解释</a></li>
<li>上面提到的文章 <a href="http://100days.de/serendipity/archives/55-Dumping-MemcacheD-Content-Keys-with-PHP.html">memcache dump and load</a> 的读者也在评论中进行了分析</li>
</ul>
<p>第二种思路来自 Twitter infrastructure team 的 <a href="http://blog.evanweaver.com/about/">Evan Weaver</a> 的 <a href="http://blog.evanweaver.com/articles/2009/04/20/peeping-into-memcached/">peeping into memcached</a> , 利用 linux 的 ptrace 系统调用导出memcached进程中数据，分析这些数据得到memcached的所有Key。</p>
<p>但是这种方式有其限制的，一方面，编译Memcached时必须编译入调试信息 （参见<a href="http://blog.evanweaver.com/files/doc/fauna/peep/files/README.html" class="broken_link" >link</a>）； 另一方面，在分析时对内存消耗太大。我们对一个只使用了64M内存、含有76万左右数据项的Memcached进程进行分析，在完成23万左右数据项时，分析进程占用内存的达到1040M，导致虚拟机内存用满，关闭了该进程。</p>
<p>因为我们现在运行的memcached是不带编译符号的，所以放弃了第二种方式。 第一种方式，则只能考虑怎么将slabs中的数据分批导出来。 Memcached 支持一个可选的 slabs reassign <src slab> <dest slab> 命令，可以将一个slab内的数据项移动到其他slab。但这个命令必须在编译 memcached 时加入该特性。</p>
<p>最后，还是利用了第一种方法，每一次导出一批数据以后就从memcached中删除这一批数据，直到全部导出为止。 虽然这种办法很土，但是还是能够应付一次性数据迁移。 当然这是不得以而为之，明智的做法还是在一开始就不要将需要持久化的数据持久化到其他服务中，而不是只存放于memcached中。</p>


<p>Related posts:<ol><li><a href='http://blog.xiping.me/2009/01/flex%e4%b8%ad%e7%9a%84%e5%af%b9%e8%b1%a1%e6%af%94%e8%be%83%ef%bc%88%e7%9b%b8%e7%ad%89%e6%80%a7%ef%bc%89.html' rel='bookmark' title='Permanent Link: Flex中的对象比较（相等性）'>Flex中的对象比较（相等性）</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://blog.xiping.me/2010/04/dump_memcached.html/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>我的VPS使用经验</title>
		<link>http://blog.xiping.me/2010/03/my_vps_experience.html</link>
		<comments>http://blog.xiping.me/2010/03/my_vps_experience.html#comments</comments>
		<pubDate>Sun, 28 Mar 2010 08:48:02 +0000</pubDate>
		<dc:creator>西坪</dc:creator>
				<category><![CDATA[server & system]]></category>
		<category><![CDATA[aws]]></category>
		<category><![CDATA[fsckvps]]></category>
		<category><![CDATA[linode]]></category>
		<category><![CDATA[vpslink]]></category>

		<guid isPermaLink="false">http://blog.feihoo.com/?p=573</guid>
		<description><![CDATA[VPSlink/Tetonic/fsckvps
约一年多前开始使用 vpslink 的 Xen VPS，前不久因为实在是没什么事情做，只放了一个博客，觉得有点不值得，就搬到了 Tektonic 上的 OpenVZ VPS。Tektonic的OpenVZ性能也还可以，但很快就发现网速实在是不行。于是试用了一下fsckvps，速度还不错的，可惜服务不好，尤其是上次事故以后，客服响应很差。另外，发现OpenVZ的虚拟机运行java基本是不可行的，甚至 ant/maven 编译个程序都不行。只能将某些能够修改JVM参数的程序手工做好设置（-Xmx480M）才能运行。
Linode
于是开始试用在中国颇为有名的 linode，我比较穷，选择了最便宜的 Linode 360，$19.95/M。 听 blogkid 的 博文 选择了 Fremont 的机房。输入信用卡，vps 很快开通。但是ssh一上去，感觉上很卡，测试了一下速度，速度才 几 K/S。受不了了，在本地测试了一下，发现blogkid 推荐的两个机房（Fremont, Newark）的速度都不行。倒是 Dellas 机房的速度很快，北京联通1M宽带能到140K左右。
于是发了个ticket给linode，很快就回信了，让我重新登录控制面板。果然，控制面板上有了自动迁移机房的按钮。于是开始迁移，速度很慢。第二天早上起来发现迁移完了。试用了一下，速度确实不错。不过很快又遇到了问题，做一个hive的测试，因为内存太少，数据一大进程一多，实在是受不了啊&#8230;&#8230;
于是退了 Linode，申请退款。 
Fsckvps + AWS
最后决定采用Fsckvps+AWS的方案。fsckvps 的价格很便宜，虽然fsckvps最近刚刚出过事情，但是我只有一个博客，数据是每天自动备份的。何况 fsckvps 的网速实在是快（北京联通1M能到180K/S，性价比相当不错，我不到 $10/M（年付）就能拿到 512M （burst 1024M)的内存。 Fsckvps的vps的网速实在是不错，在Google Webmaster Tools中，显示我这个博客的速度faster than %92 of sites：
On average, pages in your site take 1.1 seconds to [...]


Related posts:<ol><li><a href='http://blog.xiping.me/2010/04/virtual-machine-guest-host-share-file.html' rel='bookmark' title='Permanent Link: 虚拟机中Host与Guest文件共享'>虚拟机中Host与Guest文件共享</a></li>
<li><a href='http://blog.xiping.me/2008/10/ubuntu-%e4%b8%8a%e5%ae%89%e8%a3%85buildix%ef%bc%8cphp5%ef%bc%8c-apache2-%e7%9a%84%e7%83%a6%e6%81%bc.html' rel='bookmark' title='Permanent Link: Ubuntu 上安装buildix，PHP5， Apache2'>Ubuntu 上安装buildix，PHP5， Apache2</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<h5>VPSlink/Tetonic/fsckvps</h5>
<p>约一年多前开始使用 <a href="http://www.vpslink.com">vpslink</a> 的 Xen VPS，前不久因为实在是没什么事情做，只放了一个博客，觉得有点不值得，就搬到了 <a href="http://www.tektonic.net/">Tektonic</a> 上的 OpenVZ VPS。Tektonic的OpenVZ性能也还可以，但很快就发现网速实在是不行。于是试用了一下fsckvps，速度还不错的，可惜服务不好，尤其是上次事故以后，客服响应很差。另外，发现OpenVZ的虚拟机运行java基本是不可行的，甚至 ant/maven 编译个程序都不行。只能将某些能够修改JVM参数的程序手工做好设置（-Xmx480M）才能运行。</p>
<h5>Linode</h5>
<p>于是开始试用在中国颇为有名的 <a href="http://www.linode.com">linode</a>，我比较穷，选择了最便宜的 Linode 360，$19.95/M。 听 <a href="http://www.blogkid.net/linode">blogkid 的 博文</a> 选择了 Fremont 的机房。输入信用卡，vps 很快开通。但是ssh一上去，感觉上很卡，测试了一下速度，速度才 几 K/S。受不了了，在本地测试了一下，发现<a href="http://www.blogkid.net/linode">blogkid 推荐</a>的两个机房（Fremont, Newark）的速度都不行。倒是 Dellas 机房的速度很快，北京联通1M宽带能到140K左右。</p>
<p>于是发了个ticket给linode，很快就回信了，让我重新登录控制面板。果然，控制面板上有了自动迁移机房的按钮。于是开始迁移，速度很慢。第二天早上起来发现迁移完了。试用了一下，速度确实不错。不过很快又遇到了问题，做一个hive的测试，因为内存太少，数据一大进程一多，实在是受不了啊&#8230;&#8230;</p>
<p>于是退了 Linode，申请退款。 </p>
<h5>Fsckvps + AWS</h5>
<p>最后决定采用Fsckvps+AWS的方案。<a href="http://www.fsckvps.com">fsckvps</a> 的价格很便宜，虽然fsckvps最近刚刚出过事情，但是我只有一个博客，数据是每天自动备份的。何况 fsckvps 的网速实在是快（北京联通1M能到180K/S，性价比相当不错，我不到 $10/M（年付）就能拿到 512M （burst 1024M)的内存。 Fsckvps的vps的网速实在是不错，在<a href="http://www.google.com/webmasters/tools">Google Webmaster Tools</a>中，显示我这个博客的速度faster than %92 of sites：</p>
<blockquote><p>On average, pages in your site take 1.1 seconds to load (updated on Mar 15, 2010). This is faster than 92% of sites.</p></blockquote>
<p>但是<strong> fsckvps 的虚拟机是 OpenVZ的，你不能用swap，所以基本上不要指望运行吃内存太猛的程序了，在64位平台上，1024M内存的vps连java &#8211;version都跑不了</strong>。要在这样的内存比较少的VPS上跑Java，必须对堆内存的大小予以限制，因为默认情况下会根据物理内存去申请一定比例的内存，这很可能超出vps的限制（虽然物理机器的内存可能不小，但是每一个vps内存是有配额的）。</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #7a0874; font-weight: bold;">export</span> <span style="color: #007800;">EC2_JVM_ARGS</span>=<span style="color: #ff0000;">&quot;-Xms128m -Xmx128m&quot;</span>
<span style="color: #7a0874; font-weight: bold;">export</span> <span style="color: #007800;">ANT_OPTS</span>=<span style="color: #ff0000;">&quot;-Xms128m -Xmx256m&quot;</span>
<span style="color: #7a0874; font-weight: bold;">export</span> <span style="color: #007800;">MAVEN_OPTS</span>=<span style="color: #ff0000;">&quot;-Xms128m -Xmx256m&quot;</span></pre></div></div>

<p>事实上，给Maven和Ant限制这么小的内存，导致它们基本失去作用。大部分Java程序的编译都会因为内存超出限额而编译失败。对于基于OpenVZ的VPS，其内存配额在/proc/user_beancounters中，可以用下面的脚本来计算你能用多少内存</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">for</span> v <span style="color: #000000; font-weight: bold;">in</span> vmguarpages privvmpages; <span style="color: #000000; font-weight: bold;">do</span> <span style="color: #c20cb9; font-weight: bold;">expr</span> <span style="color: #000000; font-weight: bold;">`</span><span style="color: #c20cb9; font-weight: bold;">cat</span> <span style="color: #000000; font-weight: bold;">/</span>proc<span style="color: #000000; font-weight: bold;">/</span>user_beancounters <span style="color: #000000; font-weight: bold;">|</span><span style="color: #c20cb9; font-weight: bold;">grep</span> <span style="color: #007800;">$v</span> <span style="color: #000000; font-weight: bold;">|</span><span style="color: #c20cb9; font-weight: bold;">awk</span> <span style="color: #660033;">-F</span><span style="color: #ff0000;">' '</span> <span style="color: #ff0000;">'{print $4}'</span><span style="color: #000000; font-weight: bold;">`</span> <span style="color: #000000; font-weight: bold;">/</span> <span style="color: #000000;">256</span>;<span style="color: #000000; font-weight: bold;">done</span></pre></div></div>

<p>于是我将其他不需要在线的应用，挪到<a href="http://aws.amazon.com">AWS</a>去跑了。</p>
<p>我最后的方案就变成了 FsckVps + AWS. 一个月算起来也不到12$，而且AWS的服务器组集群都行，想咋搞就咋搞。从Fsckvps上操控AWS，实在是太爽了。</p>
<h5>总结：</h5>
<ul>
<li>1) Linode 的网速，以我家（北京网通1M）来看，Dellas 的网速是最快的。 1M 能够保持在120K以上，平均在 140K 左右。 其他三个中心的速度并不快。当然网速的问题，不同的时间，不同的宽带差别可能很大。Linode的服务相当不错，控制面板相当智能化，退款也爽快</li>
<li>2）fsckvps 性价比最高，网速最快（在Atlanta机房，达到140~180K/S，相当稳定）。</li>
<li>3）最终的策略是 fsckvps + AWS, 没有多少在线应用的穷人的选择。</li>
</ul>


<p>Related posts:<ol><li><a href='http://blog.xiping.me/2010/04/virtual-machine-guest-host-share-file.html' rel='bookmark' title='Permanent Link: 虚拟机中Host与Guest文件共享'>虚拟机中Host与Guest文件共享</a></li>
<li><a href='http://blog.xiping.me/2008/10/ubuntu-%e4%b8%8a%e5%ae%89%e8%a3%85buildix%ef%bc%8cphp5%ef%bc%8c-apache2-%e7%9a%84%e7%83%a6%e6%81%bc.html' rel='bookmark' title='Permanent Link: Ubuntu 上安装buildix，PHP5， Apache2'>Ubuntu 上安装buildix，PHP5， Apache2</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://blog.xiping.me/2010/03/my_vps_experience.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>DBCP连接池(一)：原理与基本配置</title>
		<link>http://blog.xiping.me/2010/01/dbcp_principle.html</link>
		<comments>http://blog.xiping.me/2010/01/dbcp_principle.html#comments</comments>
		<pubDate>Fri, 29 Jan 2010 06:20:15 +0000</pubDate>
		<dc:creator>西坪</dc:creator>
				<category><![CDATA[$Programming]]></category>
		<category><![CDATA[commons-pool]]></category>
		<category><![CDATA[dbcp]]></category>
		<category><![CDATA[连接池]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[jdbc]]></category>

		<guid isPermaLink="false">http://blog.feihoo.com/?p=51</guid>
		<description><![CDATA[大约在半年前，曾经帮同事解决过一个Commons-dbcp连接池的问题。当时遇到的问题比较诡异，但是其实并不是什么特别复杂的问题，了解DBCP的原理，大部分问题就迎刃而解了。本文主要对连接池的基本原理以及dbcp的实现方式做一个分析，对dbcp的配置参数结合原理做一个简单解释。
连接池扼要
JDBC是一套通用的Java语言与多种数据库（文件）通讯的标准API。大部分针对数据库服务器（例如Oracle, MySQL等等）的JDBC实现都是基于TCP/IP连接的客户端-服务器端通讯方式。
当我们需要执行一个数据库操作时，有下面三步：

客户端与服务器之间建立一个数据库连接
执行某种数据库操作
断开连接

如果每次处理都要走上面的三步，则应用程序与数据库服务器都要将大量的时间和资源消耗在数据连接的断开与建立上。对于某些数据库系统，一个数据库连接就是一个进程，而且数据库连接通常要占用不少资源，如排序区/Join区等等。对于并发较大的系统，建立一次连接然后缓存起来连续使用，直到程序结束等情况下再释放连接，就能够将系统资源集中在对数据库操作的处理上，从而大大提高性能。通常情况下将数据连接的建立和断开委托给一种能够数据库连接池的组件或服务进行管理。而DBCP, C3p0, Proxool等都是常用的开源的连接池组件。
就好像A公司在郊外，他们公司附近没有出租车。如果A公司有人要出去办事，他必须打电话给出租公司订车，用完车后他还要付账报销。 这样每个人出去一趟都必须订车、退车和报销。员工的很多时间白白花费在这上面了。于是A公司跟出租车公司定了一个合同，出租车公司给了他们一个车队。要用车随时去楼下找车队就可以了，用完了也不必结帐，A公司统一跟出租车公司订车和结帐。这个车队就好比连接池，由公司（应用程序）来统一向出租车公司（数据库服务器）订车（建立连接）和退车（关闭连接）。
DBCP的配置参数以及背后的原理
Commons-dbcp连接池的配置参数比较多，也比较复杂，主要分为

Jdbc连接参数（username, password, url, driverClassName, connectionProperties ）
事务处理参数 （defaultAutoCommit, defaultReadOnly, defaultTransactionIsolation, defaultCatalog）
连接池参数（详见下文）
连接池中链接存活性测试参数（详见下文）
预处理查询池化参数（poolPreparedStatements, maxOpenPreparedStatements）
丢弃失效链接相关参数（详见下文）以及一个控制是否可以正常情况下处于访问连接池包装下的底层JDBC链接参数（accessToUnderlyingConnectionAllowed）

其中Jdbc链接参数、事务处理都跟连接池关系不大，另预处理查询池化参数本文不详细叙述。有关commons-dbcp的详细参数配置信息请参考官方文档。 
连接池的配置
再用车队来比喻，出租车公司每提供一辆车给A公司，A公司肯定要付出一定费用。这时候维持车队的大小就很重要了，在项目少用车少的时候，车队肯定要减少，不然很多空闲车辆也要付出成本；在项目多用车多的时候，肯定要扩大车队，不然车不够用，车队忙不过来。A公司可以简单地设地两个阀值来动态调节车队中空闲的车辆数目以满足动态需求，一个是最小空闲车辆数(最小空空闲连接数（minIdle），当剩余的空车数目小于该数目时，A公司就向出租车公司请求加入新车。 一个是最大空闲车辆数（maxIdle），当剩余的车大于该数目时，就将刚刚用用完的车还给出租车公司从而减少车队数量。 
另外，这家出租车公司可能要为多个客户服务，要考虑能够提供给A公司的最大的车数量，不能超过某个数量(maxActive)。所以A公司想出租车申请新车时首先要看下当前正在用的车辆数目是否超过了这个最大数目，如果没有超过那就直接申请新车，否则可以让申请者（应用程序中执行请求的线程）等待 (maxWait0 当等待时间超过 maxWait时，失败）。
在连接池中，这几个参数是十分重要的，官方的说明如下，是我们调节系统性能时需要认真考虑的值。


Parameter
Default
Description


initialSize
0

      The initial number of connections that are created when the pool is started.Since: 1.2线程池启动时初始化的连接数
   


maxActive
8

      The maximum number of active connections that [...]


Related posts:<ol><li><a href='http://blog.xiping.me/2008/06/%e6%9c%89%e5%85%b3-sum%e4%b8%8elimit%e7%bb%84%e5%90%88%e4%bd%bf%e7%94%a8%e6%97%b6%e7%9a%84%e9%97%ae%e9%a2%98.html' rel='bookmark' title='Permanent Link: 有关 sum与limit组合使用时的问题'>有关 sum与limit组合使用时的问题</a></li>
<li><a href='http://blog.xiping.me/2009/10/%e7%bb%86%e8%8a%82%e8%83%8c%e5%90%8e%ef%bc%9a%e4%b8%ba%e4%bb%80%e4%b9%88%e7%ba%bf%e7%a8%8b%e5%8d%8f%e4%bd%9c%e4%b9%8b%e5%89%8d%e5%bf%85%e9%a1%bb%e5%85%88%e8%8e%b7%e5%be%97%e9%94%81.html' rel='bookmark' title='Permanent Link: 细节背后：为什么线程协作之前必须先获得锁?'>细节背后：为什么线程协作之前必须先获得锁?</a></li>
<li><a href='http://blog.xiping.me/2010/11/jdbc-ibatis-datetimes.html' rel='bookmark' title='Permanent Link: JDBC和Ibatis中的Date,Time,Timestamp处理'>JDBC和Ibatis中的Date,Time,Timestamp处理</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>大约在半年前，曾经帮同事解决过一个Commons-dbcp连接池的问题。当时遇到的问题比较诡异，但是其实并不是什么特别复杂的问题，了解DBCP的原理，大部分问题就迎刃而解了。本文主要对连接池的基本原理以及dbcp的实现方式做一个分析，对dbcp的配置参数结合原理做一个简单解释。</p>
<h5>连接池扼要</h5>
<p><a href="http://java.sun.com/javase/technologies/database/">JDBC</a>是一套通用的Java语言与多种数据库（文件）通讯的标准API。大部分针对数据库服务器（例如Oracle, MySQL等等）的JDBC实现都是基于TCP/IP连接的客户端-服务器端通讯方式。</p>
<p>当我们需要执行一个数据库操作时，有下面三步：</p>
<ol>
<li>客户端与服务器之间建立一个数据库连接</li>
<li>执行某种数据库操作</li>
<li>断开连接</li>
</ol>
<p>如果每次处理都要走上面的三步，则应用程序与数据库服务器都要将大量的时间和资源消耗在数据连接的断开与建立上。对于某些数据库系统，一个数据库连接就是一个进程，而且数据库连接通常要占用不少资源，如排序区/Join区等等。对于并发较大的系统，建立一次连接然后缓存起来连续使用，直到程序结束等情况下再释放连接，就能够将系统资源集中在对数据库操作的处理上，从而大大提高性能。通常情况下将数据连接的建立和断开委托给一种能够数据库连接池的组件或服务进行管理。而DBCP, C3p0, Proxool等都是常用的开源的连接池组件。</p>
<p>就好像A公司在郊外，他们公司附近没有出租车。如果A公司有人要出去办事，他必须打电话给出租公司订车，用完车后他还要付账报销。 这样每个人出去一趟都必须订车、退车和报销。员工的很多时间白白花费在这上面了。于是A公司跟出租车公司定了一个合同，出租车公司给了他们一个车队。要用车随时去楼下找车队就可以了，用完了也不必结帐，A公司统一跟出租车公司订车和结帐。这个车队就好比连接池，由公司（应用程序）来统一向出租车公司（数据库服务器）订车（建立连接）和退车（关闭连接）。</p>
<h5>DBCP的配置参数以及背后的原理</h5>
<p>Commons-dbcp连接池的配置参数比较多，也比较复杂，主要分为</p>
<ul>
<li>Jdbc连接参数（username, password, url, driverClassName, connectionProperties ）</li>
<li>事务处理参数 （defaultAutoCommit, defaultReadOnly, defaultTransactionIsolation, defaultCatalog）</li>
<li>连接池参数（详见下文）</li>
<li>连接池中链接存活性测试参数（详见下文）</li>
<li>预处理查询池化参数（poolPreparedStatements, maxOpenPreparedStatements）</li>
<li>丢弃失效链接相关参数（详见下文）以及一个控制是否可以正常情况下处于访问连接池包装下的底层JDBC链接参数（accessToUnderlyingConnectionAllowed）</li>
</ul>
<p>其中Jdbc链接参数、事务处理都跟连接池关系不大，另预处理查询池化参数本文不详细叙述。有关commons-dbcp的详细参数配置信息请参考<a href="http://commons.apache.org/dbcp/configuration.html">官方文档</a>。 </p>
<h5>连接池的配置</h5>
<p>再用车队来比喻，出租车公司每提供一辆车给A公司，A公司肯定要付出一定费用。这时候维持车队的大小就很重要了，在项目少用车少的时候，车队肯定要减少，不然很多空闲车辆也要付出成本；在项目多用车多的时候，肯定要扩大车队，不然车不够用，车队忙不过来。A公司可以简单地设地两个阀值来动态调节车队中空闲的车辆数目以满足动态需求，一个是最小空闲车辆数(最小空空闲连接数（minIdle），当剩余的空车数目小于该数目时，A公司就向出租车公司请求加入新车。 一个是最大空闲车辆数（maxIdle），当剩余的车大于该数目时，就将刚刚用用完的车还给出租车公司从而减少车队数量。 </p>
<p>另外，这家出租车公司可能要为多个客户服务，要考虑能够提供给A公司的最大的车数量，不能超过某个数量(maxActive)。所以A公司想出租车申请新车时首先要看下当前正在用的车辆数目是否超过了这个最大数目，如果没有超过那就直接申请新车，否则可以让申请者（应用程序中执行请求的线程）等待 (maxWait<=0, 无限等待; maxWait>0 当等待时间超过 maxWait时，失败）。</p>
<p>在连接池中，这几个参数是十分重要的，官方的说明如下，是我们调节系统性能时需要认真考虑的值。</p>
<table>
<hr />
<th>Parameter</th>
<th>Default</th>
<th>Description</th>
</hr>
<tr class="a">
<td>initialSize</td>
<td>0</td>
<td>
      The initial number of connections that are created when the pool is started.<br /></br>Since: 1.2<br />线程池启动时初始化的连接数
   </td>
</tr>
<tr class="b">
<td>maxActive</td>
<td>8</td>
<td>
      The maximum number of active connections that can be allocated from this pool at the same time, or non-positive for no limit.<br/>最大活动连接数，如果非正整数，则不做限制。
   </td>
</tr>
<tr class="a">
<td>maxIdle</td>
<td>8</td>
<td>
      The maximum number of connections that can remain idle in the pool, without extra ones being released, or negative for no limit.<br />最大空闲连接数。
   </td>
</tr>
<tr class="b">
<td>minIdle</td>
<td>0</td>
<td>The minimum number of connections that can remain idle in the pool, without extra ones being created, or zero to create none.<br />最小空闲连接数。
   </td>
</tr>
<tr class="a">
<td>maxWait</td>
<td>indefinitely</td>
<td>
      The maximum number of milliseconds that the pool will wait (when there are no available connections) for a connection to be returned before throwing an exception, or -1 to wait indefinitely.<br />（在没有连接可用时）连接池等待一个数据连接可用时的以毫秒计的最大等待时间，超时以后抛出异常， -1 则将无限等待
</td>
</tr>
</table>
<p>实际上，Dbcp 依赖于 commons-pool 来存储连接对象。 <a href="http://commons.apache.org/dbcp/api-1.2.2/org/apache/commons/dbcp/BasicDataSource.html">BasicDataSource</a>默认使用<a href="http://commons.apache.org/pool/api-1.5.4/org/apache/commons/pool/impl/GenericObjectPool.html" class="broken_link" >GenericObjectPool</a>来管理连接对象。除了请求的线程会在请求和返回连接过程中影响池中连接实例外，另有一个跑着GenericObjectPool.Evictor类型 (implements Runnable) 的实例的线程，也会影响池中的数据库连接。</p>
<p>请继续阅读下一篇：<a href="http://blog.feihoo.com/archives/542" class="broken_link" >《DBCP连接池（二）：Commons-pool的设计》</a></p>


<p>Related posts:<ol><li><a href='http://blog.xiping.me/2008/06/%e6%9c%89%e5%85%b3-sum%e4%b8%8elimit%e7%bb%84%e5%90%88%e4%bd%bf%e7%94%a8%e6%97%b6%e7%9a%84%e9%97%ae%e9%a2%98.html' rel='bookmark' title='Permanent Link: 有关 sum与limit组合使用时的问题'>有关 sum与limit组合使用时的问题</a></li>
<li><a href='http://blog.xiping.me/2009/10/%e7%bb%86%e8%8a%82%e8%83%8c%e5%90%8e%ef%bc%9a%e4%b8%ba%e4%bb%80%e4%b9%88%e7%ba%bf%e7%a8%8b%e5%8d%8f%e4%bd%9c%e4%b9%8b%e5%89%8d%e5%bf%85%e9%a1%bb%e5%85%88%e8%8e%b7%e5%be%97%e9%94%81.html' rel='bookmark' title='Permanent Link: 细节背后：为什么线程协作之前必须先获得锁?'>细节背后：为什么线程协作之前必须先获得锁?</a></li>
<li><a href='http://blog.xiping.me/2010/11/jdbc-ibatis-datetimes.html' rel='bookmark' title='Permanent Link: JDBC和Ibatis中的Date,Time,Timestamp处理'>JDBC和Ibatis中的Date,Time,Timestamp处理</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://blog.xiping.me/2010/01/dbcp_principle.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>推荐：（袁伟时）现代化与中国的历史教科书问题</title>
		<link>http://blog.xiping.me/2010/01/%e6%8e%a8%e8%8d%90%ef%bc%9a%ef%bc%88%e8%a2%81%e4%bc%9f%e6%97%b6%ef%bc%89%e7%8e%b0%e4%bb%a3%e5%8c%96%e4%b8%8e%e4%b8%ad%e5%9b%bd%e7%9a%84%e5%8e%86%e5%8f%b2%e6%95%99%e7%a7%91%e4%b9%a6%e9%97%ae%e9%a2%98.html</link>
		<comments>http://blog.xiping.me/2010/01/%e6%8e%a8%e8%8d%90%ef%bc%9a%ef%bc%88%e8%a2%81%e4%bc%9f%e6%97%b6%ef%bc%89%e7%8e%b0%e4%bb%a3%e5%8c%96%e4%b8%8e%e4%b8%ad%e5%9b%bd%e7%9a%84%e5%8e%86%e5%8f%b2%e6%95%99%e7%a7%91%e4%b9%a6%e9%97%ae%e9%a2%98.html#comments</comments>
		<pubDate>Thu, 28 Jan 2010 01:56:55 +0000</pubDate>
		<dc:creator>西坪</dc:creator>
				<category><![CDATA[@迷思]]></category>
		<category><![CDATA[history]]></category>

		<guid isPermaLink="false">http://blog.feihoo.com/?p=499</guid>
		<description><![CDATA[    以前只知道日本右翼历史教科书是怎么篡改历史的，最近读到袁伟时先生的这篇文章，我深受震动，原来我们的历史教科书也有问题。 我们自小接受的历史教育里竟然也有对历史的裁剪、修改，给我们对中国近代历史的认识造成了太严重的影响。影响有多严重，列个提纲各位看官就知道了：

火烧圆明园是无法避免的？ （看过这个问题你会明白第二次鸦片战争中中方对于战争的起因、过程和结果都负有重要责任）
(义和团)是爱国壮举还是摧残文明和反人道的罪行 （看过这个问题，你会明白义和团的罪恶和八国联军侵占北京不只是对方的责任。 两国交战不杀来使在中国历史上早已认知，要是随意杀死对方的民众就更不应该了，这一段历史教科书里对史实的篡改实在是太糟糕了。在我们记恨南京屠杀时，也想想我们的清政府和义和团所犯下的杀戮。）

    我们的心中积累了太多的仇恨和屈辱，认真对待这一百多年的近代历史，对我们的世界观异常重要。毫无疑问，帝国主义在中国领土上犯下了罪行，但是正确地认知这一进程中的真相，认识到我们的国家在这个转变过程中所经历的曲折、所犯下的错误和之所以这样的原因，或许我们能原谅清朝当政者为何犯下愚昧的错误，理解义和团先民为何会去破坏铁路、会去杀无辜的教民，明白为何赞叹夏宫的英法要烧毁圆明园、为何八国联军杀进北京最后却用庚子赔款做一些有益于中国民族进步的事情，还原一个真实的历史，才能让我们有一个正常的、自信的、健全的世界观。 
再引一段吧：
 19、20世纪中国人干了不少“无法无天”的事，义和团事件是其中的典型。值得重视的是不但至今有人把野蛮的行为说成是“革命”，而且到了20世纪90年代，有人竟把主张遵守现行国际条约的观点视为应该严加批判的卖国投降观点！
  这篇文章或许是因为其真实而对国人的思想产生强大的震撼，直接导致了刊登该文的杂志主编被撤职，杂志停刊。
2006年1月11日“中国青年报”的《冰点》周刊因刊出袁伟时文章《现代化与历史教科书》[2]，因而导致暂时停刊，并引致主编李大同及副主编卢跃刚撤职。3月1日《冰点》复刊，刊登张海鹏的《反帝反封建是近代中国历史的主题》文章批驳上文，并拒刊袁伟时《为何、何时、如何反帝反封建》文章。（来源：维基百科）
也许有的读者会质疑袁伟时的观点，那太好了，希望有人出来反驳一下，真理越辩越明。
   下面给出两个版本的链接，内容大致是一样的，只是青年报的版本用语可能更谨慎些。同时放在这里是为了降低因墙影响不能阅读的概率。
文章链接：

现代化与中国的历史教科书问题（版本一，中国青年报）
现代化与中国的历史教科书问题 （ 五柳村 ） 



No related posts.


No related posts.]]></description>
			<content:encoded><![CDATA[<p>    以前只知道日本右翼历史教科书是怎么篡改历史的，最近读到袁伟时先生的这篇文章，我深受震动，原来我们的历史教科书也有问题。 我们自小接受的历史教育里竟然也有对历史的裁剪、修改，给我们对中国近代历史的认识造成了太严重的影响。影响有多严重，列个提纲各位看官就知道了：</p>
<ul>
<li><strong>火烧圆明园是无法避免的？</strong> （看过这个问题你会明白第二次鸦片战争中中方对于战争的起因、过程和结果都负有重要责任）</li>
<li>(义和团)<strong>是爱国壮举还是摧残文明和反人道的罪行</strong> （看过这个问题，你会明白义和团的罪恶和八国联军侵占北京不只是对方的责任。 两国交战不杀来使在中国历史上早已认知，要是随意杀死对方的民众就更不应该了，这一段历史教科书里对史实的篡改实在是太糟糕了。在我们记恨南京屠杀时，也想想我们的清政府和义和团所犯下的杀戮。）</li>
</ul>
<p><div id="attachment_507" class="wp-caption aligncenter" style="width: 310px"><img src="http://blog.feihoo.com/wp-content/uploads/2010/01/chuzhonglishi.jpg" alt="初中历史教科书图片" title="初中历史教科书图片" width="300" height="300" class="size-full wp-image-507" /><p class="wp-caption-text">初中历史教科书图片(本图片不代表袁伟时文章中批判的教材,袁文可能指的是别的版本）</p></div><br />
    我们的心中积累了太多的仇恨和屈辱，认真对待这一百多年的近代历史，对我们的世界观异常重要。毫无疑问，帝国主义在中国领土上犯下了罪行，但是正确地认知这一进程中的真相，认识到我们的国家在这个转变过程中所经历的曲折、所犯下的错误和之所以这样的原因，或许我们能原谅清朝当政者为何犯下愚昧的错误，理解义和团先民为何会去破坏铁路、会去杀无辜的教民，明白为何赞叹夏宫的英法要烧毁圆明园、为何八国联军杀进北京最后却用庚子赔款做一些有益于中国民族进步的事情，还原一个真实的历史，才能让我们有一个正常的、自信的、健全的世界观。 </p>
<p>再引一段吧：</p>
<blockquote><p> 19、20世纪中国人干了不少“无法无天”的事，义和团事件是其中的典型。值得重视的是不但至今有人把野蛮的行为说成是“革命”，而且到了20世纪90年代，有人竟把主张遵守现行国际条约的观点视为应该严加批判的卖国投降观点！</p></blockquote>
<p>  这篇文章或许是因为其真实而对国人的思想产生强大的震撼，直接导致了刊登该文的杂志主编被撤职，杂志停刊。</p>
<blockquote><p>2006年1月11日“中国青年报”的《冰点》周刊因刊出袁伟时文章《现代化与历史教科书》[2]，因而导致暂时停刊，并引致主编李大同及副主编卢跃刚撤职。3月1日《冰点》复刊，刊登张海鹏的《反帝反封建是近代中国历史的主题》文章批驳上文，并拒刊袁伟时《为何、何时、如何反帝反封建》文章。（来源：<a href="http://zh.wikipedia.org/zh-cn/%E8%A2%81%E4%BC%9F%E6%97%B6">维基百科</a>）</p></blockquote>
<p>也许有的读者会质疑袁伟时的观点，那太好了，希望有人出来反驳一下，真理越辩越明。</p>
<p>   下面给出两个版本的链接，内容大致是一样的，只是青年报的版本用语可能更谨慎些。同时放在这里是为了降低因墙影响不能阅读的概率。</p>
<p>文章链接：</p>
<ul>
<li><a href="http://zqb.cyol.com/gb/zqb/2006-01/11/content_118530.htm">现代化与中国的历史教科书问题</a>（版本一，中国青年报）</li>
<li><a href="http://www.taosl.net/cn019.htm">现代化与中国的历史教科书问题</a> （ 五柳村 ） </li>
</ul>


<p>No related posts.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.xiping.me/2010/01/%e6%8e%a8%e8%8d%90%ef%bc%9a%ef%bc%88%e8%a2%81%e4%bc%9f%e6%97%b6%ef%bc%89%e7%8e%b0%e4%bb%a3%e5%8c%96%e4%b8%8e%e4%b8%ad%e5%9b%bd%e7%9a%84%e5%8e%86%e5%8f%b2%e6%95%99%e7%a7%91%e4%b9%a6%e9%97%ae%e9%a2%98.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>十多年后再见到卓依婷</title>
		<link>http://blog.xiping.me/2010/01/%e5%8d%81%e5%a4%9a%e5%b9%b4%e5%90%8e%e5%86%8d%e8%a7%81%e5%88%b0%e5%8d%93%e4%be%9d%e5%a9%b7.html</link>
		<comments>http://blog.xiping.me/2010/01/%e5%8d%81%e5%a4%9a%e5%b9%b4%e5%90%8e%e5%86%8d%e8%a7%81%e5%88%b0%e5%8d%93%e4%be%9d%e5%a9%b7.html#comments</comments>
		<pubDate>Sun, 10 Jan 2010 16:44:07 +0000</pubDate>
		<dc:creator>西坪</dc:creator>
				<category><![CDATA[@生活]]></category>

		<guid isPermaLink="false">http://blog.feihoo.com/?p=494</guid>
		<description><![CDATA[上初中的时候，因为舅舅、叔叔他们都特别喜欢卓依婷，我听得最多的歌声差不多也是卓依婷的，于是渐渐喜欢上了她的歌声。初高中的时候就听舅舅说她已经因为车祸离世了，感到十分惋惜。
后来我把我们家人对于卓依婷的热爱，以及她已经离世等等都告诉了老婆。才知道她也是喜欢卓依婷的歌的。不过这两天听了三四个人演唱的《小城故事》，觉得都和原唱有一定的差距。而卓依婷估计唱这个歌的时候年纪还很小，歌声有些区别也是可以理解的。
于是我顺便Google了一下有关卓依婷的资料，没想到发现搜索提示框里排名第二的是”卓依婷之死“，于是搜索进去，结果大吃一惊，原来她并没有去世。各种消息都是以讹传讹吧。老婆说，他应该把这个消息告诉我舅舅和叔叔，他们也应该会感到高兴的，因为可以买新专辑了  。
她只是中间休息了两年（她81年出生，我想休息一下学学东西也是好的），但是2001年复出后没有很特别的成果，加上个人低调等原因，有关她的消息不是特别多。可能这些年努力也不容易，她之前给人民的主要印象还是年少时的作品，如今好些年了，要转变也不是一个容易的事情。祝她顺利。
顺便去看了看她的博客，觉得很平易近人，有一种很亲切的感觉。
另外，她现在签约优格音乐文化有限公司，暂时不知道该公司的更多资料。她还开通了官方网站。


No related posts.


No related posts.]]></description>
			<content:encoded><![CDATA[<p>上初中的时候，因为舅舅、叔叔他们都特别喜欢<a href="http://blog.sina.com.cn/timizhuo">卓依婷</a>，我听得最多的歌声差不多也是<a href="http://blog.sina.com.cn/timizhuo">卓依婷</a>的，于是渐渐喜欢上了她的歌声。初高中的时候就听舅舅说她已经因为车祸离世了，感到十分惋惜。</p>
<p>后来我把我们家人对于卓依婷的热爱，以及她已经离世等等都告诉了老婆。才知道她也是喜欢卓依婷的歌的。不过这两天听了三四个人演唱的《小城故事》，觉得都和原唱有一定的差距。而卓依婷估计唱这个歌的时候年纪还很小，歌声有些区别也是可以理解的。</p>
<p>于是我顺便Google了一下有关卓依婷的资料，没想到发现搜索提示框里排名第二的是”卓依婷之死“，于是搜索进去，结果大吃一惊，原来她并没有去世。各种消息都是以讹传讹吧。老婆说，他应该把这个消息告诉我舅舅和叔叔，他们也应该会感到高兴的，因为可以买新专辑了 <img src='http://blog.xiping.me/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> 。</p>
<p>她只是中间休息了两年（她81年出生，我想休息一下学学东西也是好的），但是2001年复出后没有很特别的成果，加上个人低调等原因，有关她的消息不是特别多。可能这些年努力也不容易，她之前给人民的主要印象还是年少时的作品，如今好些年了，要转变也不是一个容易的事情。祝她顺利。</p>
<p>顺便去看了看<a href="http://blog.sina.com.cn/timizhuo">她的博客</a>，觉得很平易近人，有一种很亲切的感觉。</p>
<p>另外，她现在签约优格音乐文化有限公司，暂时不知道该公司的更多资料。她还开通了<a href="http://www.timitimi.com/">官方网站</a>。</p>


<p>No related posts.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.xiping.me/2010/01/%e5%8d%81%e5%a4%9a%e5%b9%b4%e5%90%8e%e5%86%8d%e8%a7%81%e5%88%b0%e5%8d%93%e4%be%9d%e5%a9%b7.html/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>文件锁与进程互斥</title>
		<link>http://blog.xiping.me/2010/01/file-lock-and-jvm-mutex.html</link>
		<comments>http://blog.xiping.me/2010/01/file-lock-and-jvm-mutex.html#comments</comments>
		<pubDate>Fri, 08 Jan 2010 01:54:46 +0000</pubDate>
		<dc:creator>西坪</dc:creator>
				<category><![CDATA[$Programming]]></category>
		<category><![CDATA[concurrency]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[lock]]></category>

		<guid isPermaLink="false">http://blog.feihoo.com/?p=698</guid>
		<description><![CDATA[有的情况下需要在进程之间实现互斥，这对于普通Java程序来说，因为是运行在虚拟机里的原因，手段远不如原生程序方便，但是也有一些简单的方法可以做到。第一个就是使用Socket监听某个端口，第二种方法是使用文件锁定。
使用Socket实现进程互斥
因为Java服务器套接字都是基于系统的socket接口实现的，而socket接口会保证一个套接字端点在整个系统中是唯一的，所以只需要在应用启动时监听一个端口，就可以让系统不同时启动。虽然方法比较土，但是也能用。

try &#123;
	ServerSocket ss = new ServerSocket&#40;3030&#41;;
&#125;catch &#40;Exception e&#41; &#123;
	logger.error&#40;&#34;Cannot start&#34;, e.printStackTrace&#40;&#41;&#41;;
	System.exit&#40;&#41;;
&#125;

使用文件锁在进程间同步
另一个实现Java进程间互斥的方法，就是文件锁。不过与上面使用套接字不同，使用文件锁还可以实现更高级的互斥/协作。完全可以用文件锁来实现不同Java进程之间的同步，基本思路与在线程之间使用读写锁同步相似。
JDK本身直接支持文件锁，在FileChannel下有几个与文件锁有关的方法，可以打开一个FileLock对象。当调用FileLock#release()方法，或者Channel关闭，或者JVM退出时都会释放该锁。文件锁是JVM全局的，与Java内部的锁/线程等无关，是进程之间的竞争关系。如果你不想发生意外你的程序挂起，那就应该用FileChannel#trylock，而不是直接使用FileChannel#lock()，这样在不能加锁时可以休眠一段时间再等等，或者超时退出。
文件锁像读写锁一样，可以是加共享锁，也可以加独占锁，还可以给锁定限制范围。这是操作系统本身提供的功能，JDK在操作系统层面上做了封装。在Linux下，其实就是调用fcntl来设置相关的状态。如下面的代码，会给文件加独占锁，如果再起新的进程，进程就会打开文件失败退出。

     char* lockfile;
      int lockfd;
      struct flock lock;
      time_t t;   
&#160;
      if &#40;&#40;lockfd = open&#40;lockfile, O_RDWR&#41;&#41; == -1&#41; &#123;
 [...]


Related posts:<ol><li><a href='http://blog.xiping.me/2011/02/optimizing-actions.html' rel='bookmark' title='Permanent Link: J2EE/Oracle性能调优实录'>J2EE/Oracle性能调优实录</a></li>
<li><a href='http://blog.xiping.me/2011/03/java-serialize-and-reflection.html' rel='bookmark' title='Permanent Link: 解决Java序列化的版本冲突'>解决Java序列化的版本冲突</a></li>
<li><a href='http://blog.xiping.me/2009/10/%e7%bb%86%e8%8a%82%e8%83%8c%e5%90%8e%ef%bc%9a%e4%b8%ba%e4%bb%80%e4%b9%88%e7%ba%bf%e7%a8%8b%e5%8d%8f%e4%bd%9c%e4%b9%8b%e5%89%8d%e5%bf%85%e9%a1%bb%e5%85%88%e8%8e%b7%e5%be%97%e9%94%81.html' rel='bookmark' title='Permanent Link: 细节背后：为什么线程协作之前必须先获得锁?'>细节背后：为什么线程协作之前必须先获得锁?</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>有的情况下需要在进程之间实现互斥，这对于普通Java程序来说，因为是运行在虚拟机里的原因，手段远不如原生程序方便，但是也有一些简单的方法可以做到。第一个就是使用Socket监听某个端口，第二种方法是使用文件锁定。</p>
<h3>使用Socket实现进程互斥</h3>
<p>因为Java服务器套接字都是基于系统的socket接口实现的，而socket接口会保证一个套接字端点在整个系统中是唯一的，所以只需要在应用启动时监听一个端口，就可以让系统不同时启动。虽然方法比较土，但是也能用。</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">try</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #003399;">ServerSocket</span> ss <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">ServerSocket</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">3030</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #000000; font-weight: bold;">catch</span> <span style="color: #009900;">&#40;</span><span style="color: #003399;">Exception</span> e<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	logger.<span style="color: #006633;">error</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Cannot start&quot;</span>, e.<span style="color: #006633;">printStackTrace</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #003399;">System</span>.<span style="color: #006633;">exit</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<h3>使用文件锁在进程间同步</h3>
<p>另一个实现Java进程间互斥的方法，就是文件锁。不过与上面使用套接字不同，使用文件锁还可以实现更高级的互斥/协作。完全可以用文件锁来实现不同Java进程之间的同步，基本思路与在线程之间使用读写锁同步相似。</p>
<p>JDK本身直接支持文件锁，在<a href="http://download.oracle.com/javase/6/docs/api/java/nio/channels/FileChannel.html">FileChannel</a>下有几个与文件锁有关的方法，可以打开一个<a href="http://download.oracle.com/javase/6/docs/api/java/nio/channels/FileLock.html">FileLock</a>对象。当调用FileLock#release()方法，或者Channel关闭，或者JVM退出时都会释放该锁。文件锁是JVM全局的，与Java内部的锁/线程等无关，是进程之间的竞争关系。如果你不想发生意外你的程序挂起，那就应该用<a href="http://download.oracle.com/javase/6/docs/api/java/nio/channels/FileChannel.html#tryLock()">FileChannel#trylock</a>，而不是直接使用FileChannel#lock()，这样在不能加锁时可以休眠一段时间再等等，或者超时退出。</p>
<p>文件锁像读写锁一样，可以是加共享锁，也可以加独占锁，还可以给锁定限制范围。这是操作系统本身提供的功能，JDK在操作系统层面上做了封装。在Linux下，其实就是调用fcntl来设置相关的状态。如下面的代码，会给文件加独占锁，如果再起新的进程，进程就会打开文件失败退出。</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;">     <span style="color: #993333;">char</span><span style="color: #339933;">*</span> lockfile<span style="color: #339933;">;</span>
      <span style="color: #993333;">int</span> lockfd<span style="color: #339933;">;</span>
      <span style="color: #993333;">struct</span> flock lock<span style="color: #339933;">;</span>
      time_t t<span style="color: #339933;">;</span>   
&nbsp;
      <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>lockfd <span style="color: #339933;">=</span> open<span style="color: #009900;">&#40;</span>lockfile<span style="color: #339933;">,</span> O_RDWR<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">==</span> <span style="color: #339933;">-</span><span style="color: #0000dd;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
          fprintf<span style="color: #009900;">&#40;</span>stdout<span style="color: #339933;">,</span> <span style="color: #ff0000;">&quot;open file %s fail: %s <span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">,</span> lockfile<span style="color: #339933;">,</span> strerror<span style="color: #009900;">&#40;</span>errno<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
          exit<span style="color: #009900;">&#40;</span><span style="color: #0000dd;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #009900;">&#125;</span>
&nbsp;
      t <span style="color: #339933;">=</span> time<span style="color: #009900;">&#40;</span>NULL<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
      lock.<span style="color: #202020;">l_type</span> <span style="color: #339933;">=</span> F_WRLCK<span style="color: #339933;">;</span>
      lock.<span style="color: #202020;">l_start</span> <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
      lock.<span style="color: #202020;">l_len</span> <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
      lock.<span style="color: #202020;">l_whence</span> <span style="color: #339933;">=</span> SEEK_SET<span style="color: #339933;">;</span>
      <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>fcntl<span style="color: #009900;">&#40;</span>lockfd<span style="color: #339933;">,</span> F_SETLKW<span style="color: #339933;">,</span> <span style="color: #339933;">&amp;</span>lock<span style="color: #009900;">&#41;</span> <span style="color: #339933;">==</span> <span style="color: #339933;">-</span><span style="color: #0000dd;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
          fprintf<span style="color: #009900;">&#40;</span>stdout<span style="color: #339933;">,</span> <span style="color: #ff0000;">&quot;lock file %s fail: %s <span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">,</span> lockfile<span style="color: #339933;">,</span> strerror<span style="color: #009900;">&#40;</span>errno<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #009900;">&#125;</span>
      fprintf<span style="color: #009900;">&#40;</span>stdout<span style="color: #339933;">,</span> <span style="color: #ff0000;">&quot;lock file %s success(%d): %ld <span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">,</span> lockfile<span style="color: #339933;">,</span> <span style="color: #009900;">&#40;</span><span style="color: #993333;">int</span><span style="color: #009900;">&#41;</span>getpid<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> time<span style="color: #009900;">&#40;</span>NULL<span style="color: #009900;">&#41;</span><span style="color: #339933;">-</span>t<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      sleep<span style="color: #009900;">&#40;</span><span style="color: #0000dd;">30</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>



<p>Related posts:<ol><li><a href='http://blog.xiping.me/2011/02/optimizing-actions.html' rel='bookmark' title='Permanent Link: J2EE/Oracle性能调优实录'>J2EE/Oracle性能调优实录</a></li>
<li><a href='http://blog.xiping.me/2011/03/java-serialize-and-reflection.html' rel='bookmark' title='Permanent Link: 解决Java序列化的版本冲突'>解决Java序列化的版本冲突</a></li>
<li><a href='http://blog.xiping.me/2009/10/%e7%bb%86%e8%8a%82%e8%83%8c%e5%90%8e%ef%bc%9a%e4%b8%ba%e4%bb%80%e4%b9%88%e7%ba%bf%e7%a8%8b%e5%8d%8f%e4%bd%9c%e4%b9%8b%e5%89%8d%e5%bf%85%e9%a1%bb%e5%85%88%e8%8e%b7%e5%be%97%e9%94%81.html' rel='bookmark' title='Permanent Link: 细节背后：为什么线程协作之前必须先获得锁?'>细节背后：为什么线程协作之前必须先获得锁?</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://blog.xiping.me/2010/01/file-lock-and-jvm-mutex.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>请资助小怡帆</title>
		<link>http://blog.xiping.me/2010/01/help-yifan.html</link>
		<comments>http://blog.xiping.me/2010/01/help-yifan.html#comments</comments>
		<pubDate>Wed, 06 Jan 2010 07:46:30 +0000</pubDate>
		<dc:creator>西坪</dc:creator>
				<category><![CDATA[@生活]]></category>

		<guid isPermaLink="false">http://blog.feihoo.com/?p=480</guid>
		<description><![CDATA[
Update(2010-12-01):爱是永不止息。祈愿她能度过难关求得新生。另，不久前我家小女儿出生了，我也做了爸爸。补一张出生两天多时的照片。爱是永不止息。
Update(2010-3-18): 小怡凡在各界爱心人士的帮助下终于踏上了去往美国医疗的路程。详情在拯救小怡凡主页上。 还要担心手术会怎样，真心祈愿她早日康复！
从小怡凡的主页上了解到：第一，如果要孩子一定要让自己身体健康、强壮；第二，如果孩子有不好，要提早治疗，找几家医院或许能相互参考。
 2010年1月19日亚历山大医生带回来怡帆的血样检测及影像分析结果，排除了由DNA变异导致的先天性肺疾病， 确切的病症是&#8221;肺细胞代谢缺陷&#8221;，肺间质形成脂肪蛋白阻碍氧气进入血液交换，这正是肺部影像一直呈现毛玻璃状的真正原因， 由此导致左心室向肺部加速血液输送，形成“肺动脉高压”。北京市儿童医院2006年对怡帆实施过两次“肺灌洗”， 灌洗液培养结果未见蛋白成分，后归结于“肺纤维化”。几年来，未能及时对症治疗和控制肺间质的脂肪蛋白生长， 错过了治疗及手术修复的最佳时机，目前必须通过全肺移植来救治。
由于我的工作性质以及之前努力工作却忽视了身体，我有些担心我家小宝贝，祈祷他/她在妈妈肚子里健康孕育、成长！
===============================================================================
下面是一个患病需要高昂费用去救助的孩子，他的爸爸妈妈只有一年多点的时间来筹集500,000$，人民币是350万。病情越来越严重了，时间快到了，可是却还不一定能够攒足这笔费用。我老婆看了小孩的照片和故事，心疼不已。我看着也心疼。只可惜我经济状况也不好，只能提供一点捐款。在这里贴下小怡帆的照片，希望过往的人们看到，伸出援助之手。在为小怡帆祈祷的同时，也祈愿天下的小孩子都健康活泼。 

很感谢您能抽时间了解怡帆的事情，怡帆是我四岁的女儿，患有肺动脉高压，需要二十四小时吸氧来维持呼吸， 北京儿童医院诊断为肺纤维化，国内无法医治。在和睦家医院亚历山大医生的全力帮助下， 怡帆有机会去美国德州儿童医院接受心肺移植手术，费用十分昂贵，作为孩子的父母， 我们没有足够的时间来积累这笔费用，为此，和睦家基金会帮助我们建立了怡帆基金，寻求社会的帮助， 请您抽出少量的时间浏览www.yifanfund.com和 www.help-yifan.org， 同时将这个网站告诉您周围的朋友，并恳请提供一些帮助来挽救这个孩子。谢谢！
上面的话来自怡帆的父亲，我们的朋友潘俊廷。
详细请去救助小怡帆的主页。


No related posts.


No related posts.]]></description>
			<content:encoded><![CDATA[<p><img src="http://blog.feihoo.com/wp-content/uploads/2010/01/IMG_1682-WEB.JPG" alt="我家宝贝两天多照" title="我家宝贝两天多照" width="448" height="336" class="alignright size-full wp-image-850" /><br />
<strong>Update(2010-12-01):</strong><a href="http://www.help-yifan.org/situation.html">爱是永不止息</a>。祈愿她能度过难关求得新生。另，不久前我家小女儿出生了，我也做了爸爸。补一张出生两天多时的照片。爱是永不止息。</p>
<p><strong>Update(2010-3-18):</strong> 小怡凡在各界爱心人士的帮助下终于踏上了去往美国医疗的路程。详情在<a href="http://www.help-yifan.org/situation.html">拯救小怡凡主页</a>上。 还要担心手术会怎样，真心祈愿她早日康复！</p>
<p>从小怡凡的主页上了解到：第一，如果要孩子一定要让自己身体健康、强壮；第二，如果孩子有不好，要提早治疗，找几家医院或许能相互参考。</p>
<blockquote><p> 2010年1月19日亚历山大医生带回来怡帆的血样检测及影像分析结果，排除了由DNA变异导致的先天性肺疾病， 确切的病症是&#8221;肺细胞代谢缺陷&#8221;，肺间质形成脂肪蛋白阻碍氧气进入血液交换，这正是肺部影像一直呈现毛玻璃状的真正原因， 由此导致左心室向肺部加速血液输送，形成“肺动脉高压”。北京市儿童医院2006年对怡帆实施过两次“肺灌洗”， 灌洗液培养结果未见蛋白成分，后归结于“肺纤维化”。几年来，未能及时对症治疗和控制肺间质的脂肪蛋白生长， 错过了治疗及手术修复的最佳时机，目前必须通过全肺移植来救治。</p></blockquote>
<p>由于我的工作性质以及之前努力工作却忽视了身体，我有些担心我家小宝贝，祈祷他/她在妈妈肚子里健康孕育、成长！<br />
===============================================================================</p>
<p>下面是一个患病需要高昂费用去救助的孩子，他的爸爸妈妈只有一年多点的时间来筹集500,000$，人民币是350万。病情越来越严重了，时间快到了，可是却还不一定能够攒足这笔费用。我老婆看了小孩的照片和故事，心疼不已。我看着也心疼。只可惜我经济状况也不好，只能提供一点捐款。在这里贴下小怡帆的照片，希望过往的人们看到，伸出援助之手。在为小怡帆祈祷的同时，也祈愿天下的小孩子都健康活泼。 </p>
<p><img src="http://blog.feihoo.com/wp-content/uploads/2010/01/a.jpg" alt="a" title="a" width="389" height="389" class="aligncenter size-full wp-image-518" /></p>
<blockquote><p>很感谢您能抽时间了解怡帆的事情，怡帆是我四岁的女儿，患有肺动脉高压，需要二十四小时吸氧来维持呼吸， 北京儿童医院诊断为肺纤维化，国内无法医治。在和睦家医院亚历山大医生的全力帮助下， 怡帆有机会去美国德州儿童医院接受心肺移植手术，费用十分昂贵，作为孩子的父母， 我们没有足够的时间来积累这笔费用，为此，和睦家基金会帮助我们建立了怡帆基金，寻求社会的帮助， 请您抽出少量的时间浏览<a href="http://www.yifanfund.com">www.yifanfund.com</a>和 <a href="http://www.help-yifan.org">www.help-yifan.org</a>， 同时将这个网站告诉您周围的朋友，并恳请提供一些帮助来挽救这个孩子。谢谢！</p>
<p>上面的话来自怡帆的父亲，我们的朋友潘俊廷。</p></blockquote>
<p>详细请去救助小怡帆的<a href="http://www.help-yifan.org">主页</a>。</p>


<p>No related posts.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.xiping.me/2010/01/help-yifan.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>My Vimrc File</title>
		<link>http://blog.xiping.me/2009/12/my-vimrc-file.html</link>
		<comments>http://blog.xiping.me/2009/12/my-vimrc-file.html#comments</comments>
		<pubDate>Wed, 23 Dec 2009 16:48:37 +0000</pubDate>
		<dc:creator>西坪</dc:creator>
				<category><![CDATA[Tools & Tips]]></category>
		<category><![CDATA[vim]]></category>

		<guid isPermaLink="false">http://blog.feihoo.com/?p=433</guid>
		<description><![CDATA[Apply the recommend vimrc file:

cp /usr/share/vim/vimcurrent/vimrc_example.vim  /usr/share/vim/vimrc

~/.vimrc: Keep it simple!

&#34; 设置文件编码检测类型及支持格式
 set fencs=utf-8,ucs-bom,gb18030,gbk,gb2312,cp936
&#160;
 &#34;显示行号
 set nu!
&#160;
 &#34; 中文帮助
 if version &#62; 603
 set helplang=cn
 endi
&#160;
 &#34; 设置代码自动缩进
 :set cindent
&#160;
 &#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;
 &#34; cscope setting (from http://easwy.com/blog/archives/advanced-vim-skills-cscope/)
 &#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;&#34;
 if has(&#34;cscope&#34;)
   set csprg=/usr/bin/cscope
   set csto=1
   set cst
   set nocsverb
 [...]


Related posts:<ol><li><a href='http://blog.xiping.me/2009/05/vim-usage.html' rel='bookmark' title='Permanent Link: Vim 快捷键'>Vim 快捷键</a></li>
<li><a href='http://blog.xiping.me/2009/12/my-ubuntu-installation-log.html' rel='bookmark' title='Permanent Link: My Ubuntu Installation log'>My Ubuntu Installation log</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>Apply the recommend vimrc file:</p>

<div class="wp_syntax"><div class="code"><pre class="sh" style="font-family:monospace;">cp /usr/share/vim/vimcurrent/vimrc_example.vim  /usr/share/vim/vimrc</pre></div></div>

<p>~/.vimrc: Keep it simple!</p>

<div class="wp_syntax"><div class="code"><pre class="sh" style="font-family:monospace;">&quot; 设置文件编码检测类型及支持格式
 set fencs=utf-8,ucs-bom,gb18030,gbk,gb2312,cp936
&nbsp;
 &quot;显示行号
 set nu!
&nbsp;
 &quot; 中文帮助
 if version &gt; 603
 set helplang=cn
 endi
&nbsp;
 &quot; 设置代码自动缩进
 :set cindent
&nbsp;
 &quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;
 &quot; cscope setting (from http://easwy.com/blog/archives/advanced-vim-skills-cscope/)
 &quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;
 if has(&quot;cscope&quot;)
   set csprg=/usr/bin/cscope
   set csto=1
   set cst
   set nocsverb
   &quot; add any database in current directory
   if filereadable(&quot;cscope.out&quot;)
       cs add cscope.out
   endif
   set csverb
 endif
&nbsp;
 nmap &lt;C-@&gt;s :cs find s &lt;C-R&gt;=expand(&quot;&lt;cword&gt;&quot;)&lt;CR&gt;&lt;CR&gt;
 nmap &lt;C-@&gt;g :cs find g &lt;C-R&gt;=expand(&quot;&lt;cword&gt;&quot;)&lt;CR&gt;&lt;CR&gt;
 nmap &lt;C-@&gt;c :cs find c &lt;C-R&gt;=expand(&quot;&lt;cword&gt;&quot;)&lt;CR&gt;&lt;CR&gt;
 nmap &lt;C-@&gt;t :cs find t &lt;C-R&gt;=expand(&quot;&lt;cword&gt;&quot;)&lt;CR&gt;&lt;CR&gt;
 nmap &lt;C-@&gt;e :cs find e &lt;C-R&gt;=expand(&quot;&lt;cword&gt;&quot;)&lt;CR&gt;&lt;CR&gt;
 nmap &lt;C-@&gt;f :cs find f &lt;C-R&gt;=expand(&quot;&lt;cfile&gt;&quot;)&lt;CR&gt;&lt;CR&gt;
 nmap &lt;C-@&gt;i :cs find i ^&lt;C-R&gt;=expand(&quot;&lt;cfile&gt;&quot;)&lt;CR&gt;$&lt;CR&gt;
 nmap &lt;C-@&gt;d :cs find d &lt;C-R&gt;=expand(&quot;&lt;cword&gt;&quot;)&lt;CR&gt;&lt;CR&gt;</pre></div></div>



<p>Related posts:<ol><li><a href='http://blog.xiping.me/2009/05/vim-usage.html' rel='bookmark' title='Permanent Link: Vim 快捷键'>Vim 快捷键</a></li>
<li><a href='http://blog.xiping.me/2009/12/my-ubuntu-installation-log.html' rel='bookmark' title='Permanent Link: My Ubuntu Installation log'>My Ubuntu Installation log</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://blog.xiping.me/2009/12/my-vimrc-file.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Arguments on Java &amp; C++</title>
		<link>http://blog.xiping.me/2009/12/arguments-on-java-c.html</link>
		<comments>http://blog.xiping.me/2009/12/arguments-on-java-c.html#comments</comments>
		<pubDate>Wed, 23 Dec 2009 10:11:14 +0000</pubDate>
		<dc:creator>西坪</dc:creator>
				<category><![CDATA[$Programming]]></category>
		<category><![CDATA[c/cpp]]></category>
		<category><![CDATA[java]]></category>

		<guid isPermaLink="false">http://blog.feihoo.com/?p=423</guid>
		<description><![CDATA[The Hypertable Team claimed they choose C++ to be Hypertable implement language for performance issues. They gave two points about that, Hypertable is memory (malloc) intensive and and CPU intensive. They also say:
(Hadoop)There are some places where Java is sub-optimal. In particular, at scale, there will be considerable memory pressure in the Namenode of the [...]


Related posts:<ol><li><a href='http://blog.xiping.me/2011/04/memory-leak-caused-by-proxool-and-the-fix.html' rel='bookmark' title='Permanent Link: Memory leak caused by Proxool and the fix'>Memory leak caused by Proxool and the fix</a></li>
<li><a href='http://blog.xiping.me/2009/09/reliability-availability-and-scalability.html' rel='bookmark' title='Permanent Link: Reliability, Availability, and Scalability'>Reliability, Availability, and Scalability</a></li>
<li><a href='http://blog.xiping.me/2010/11/jdbc-ibatis-datetimes.html' rel='bookmark' title='Permanent Link: JDBC和Ibatis中的Date,Time,Timestamp处理'>JDBC和Ibatis中的Date,Time,Timestamp处理</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>The <a href="http://www.hypertable.org">Hypertable</a> Team <a href="http://code.google.com/p/hypertable/wiki/WhyWeChoseCppOverJava">claimed they choose C++ to be Hypertable implement language</a> for performance issues. They gave two points about that, Hypertable is memory (malloc) intensive and and CPU intensive. They also say:</p>
<blockquote><p>(<em>Hadoop</em>)There are some places where Java is sub-optimal. In particular, at scale, there will be considerable memory pressure in the Namenode of the DFS. Java is a poor choice for this type of memory hungry application. Another place where the use of Java is sub-optimal is the post-map sorting in preparation for the reduce phase. This is CPU-intensive and involves the type of CPU work that Java is not good at.</p></blockquote>
<p>There are a bunch comments on the Wiki Page. Someone gave another views. A guy gave two links to support Java is not so bad.</p>
<blockquote><p>Some interesting comparative articles.<br />
<a href=" http://www.ddj.com/cpp/184401976?pgno=1"><br />
http://www.ddj.com/cpp/184401976?pgno=1</a><br />
<a href=" http://www.ddj.com/cpp/184401976?pgno=1">http://www.idiom.com/~zilla/Computer/javaCbenchmark.html </a></p></blockquote>


<p>Related posts:<ol><li><a href='http://blog.xiping.me/2011/04/memory-leak-caused-by-proxool-and-the-fix.html' rel='bookmark' title='Permanent Link: Memory leak caused by Proxool and the fix'>Memory leak caused by Proxool and the fix</a></li>
<li><a href='http://blog.xiping.me/2009/09/reliability-availability-and-scalability.html' rel='bookmark' title='Permanent Link: Reliability, Availability, and Scalability'>Reliability, Availability, and Scalability</a></li>
<li><a href='http://blog.xiping.me/2010/11/jdbc-ibatis-datetimes.html' rel='bookmark' title='Permanent Link: JDBC和Ibatis中的Date,Time,Timestamp处理'>JDBC和Ibatis中的Date,Time,Timestamp处理</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://blog.xiping.me/2009/12/arguments-on-java-c.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>My Ubuntu Installation log</title>
		<link>http://blog.xiping.me/2009/12/my-ubuntu-installation-log.html</link>
		<comments>http://blog.xiping.me/2009/12/my-ubuntu-installation-log.html#comments</comments>
		<pubDate>Fri, 18 Dec 2009 08:11:44 +0000</pubDate>
		<dc:creator>西坪</dc:creator>
				<category><![CDATA[Tools & Tips]]></category>
		<category><![CDATA[ubuntu]]></category>

		<guid isPermaLink="false">http://blog.feihoo.com/?p=406</guid>
		<description><![CDATA[业余使用Ubuntu好些年了，装了删删了装的，为了以后方便，把这次的新版本的安装配置过程都记录下来。
第一步，从官方下载 Ubuntu-desktop。
第二步，在VMWare上安装，并安装VMWare-tools。 在ubuntu-desktop-9.10上，不像以前需要手工安装一些包，安装linux头文件，这次一路回车就搞定了。
到这里系统就算安装完毕，发现已经用去了8G硬盘的 37%。


 (update 2009-12-28): 事后发现根本没有装好，再次尝试安装，基本上各个模块编译时都会出现error日志，并报告模块没有成功编译。而原来在 ubuntu 8.10下是工作正常的。 为什么升级到 ubuntu 9.10就出错了呢？一开始在网络上搜索，看过 VMware workstation fails after 9.0.4 upgrade to 9.10， 根据该帖建议去打补丁， 但是都没有解决。
后来，去Vmware官方找了下是否有更新，结果发现 VMware Workstationfor Windows 出了新的6.5.3版本， 在 Release Notes 中发现 Ubuntu 9.04 is fully supported. 猜测也许是需要新版本。 尝试下载新版本安装后，重新安装和配置 vmware-tools， 一切顺利！

第三步，安装我需要的各种软件。
0. 设置source.list，我使用 mirrors.163.com.
   设置网卡：

auto lo
iface lo inet loopback

auto eth0
iface eth0 inet static
address 192.168.1.126
netmask 255.255.255.0
gateway 192.168.1.1

#auto [...]


Related posts:<ol><li><a href='http://blog.xiping.me/2008/10/ubuntu-%e4%b8%8a%e5%ae%89%e8%a3%85buildix%ef%bc%8cphp5%ef%bc%8c-apache2-%e7%9a%84%e7%83%a6%e6%81%bc.html' rel='bookmark' title='Permanent Link: Ubuntu 上安装buildix，PHP5， Apache2'>Ubuntu 上安装buildix，PHP5， Apache2</a></li>
<li><a href='http://blog.xiping.me/2009/11/%e9%98%bf%e9%87%8c%e5%b7%b4%e5%b7%b4%e6%94%b6%e8%b4%ad%e4%b8%87%e7%bd%91%e4%b8%8evmware%e6%94%b6%e8%b4%adspringsource-%e5%b8%83%e5%b1%80%e4%ba%91%e8%ae%a1%e7%ae%97.html' rel='bookmark' title='Permanent Link: 阿里巴巴收购万网与Vmware收购SpringSource: 布局云计算'>阿里巴巴收购万网与Vmware收购SpringSource: 布局云计算</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>业余使用Ubuntu好些年了，装了删删了装的，为了以后方便，把这次的新版本的安装配置过程都记录下来。</p>
<p>第一步，从官方下载 Ubuntu-desktop。</p>
<p>第二步，在VMWare上安装，并安装VMWare-tools。 在ubuntu-desktop-9.10上，不像以前需要手工安装一些包，安装linux头文件，这次一路回车就搞定了。</p>
<p>到这里系统就算安装完毕，发现已经用去了8G硬盘的 37%。</p>
<div style="padding-left:10px">
<p>
<strong> (update 2009-12-28):</strong> 事后发现根本没有装好，再次尝试安装，基本上各个模块编译时都会出现error日志，并报告模块没有成功编译。而原来在 ubuntu 8.10下是工作正常的。 为什么升级到 ubuntu 9.10就出错了呢？一开始在网络上搜索，看过 <a href="http://newyork.ubuntuforums.org/showthread.php?p=8289474">VMware workstation fails after 9.0.4 upgrade to 9.10</a>， 根据该帖建议去打<a href="http://communities.vmware.com/thread/208219?start=0&amp;tstart=0">补丁</a>， 但是都没有解决。</p>
<p>后来，去Vmware官方找了下是否有更新，结果发现 VMware Workstationfor Windows 出了新的<a href="http://downloads.vmware.com/d/details/workstation_6_5_3_for_windows/dHdiZHdodGJAJXQ=">6.5.3版本</a>， 在 <a href="http://www.vmware.com/support/ws65/doc/releasenotes_ws653.html">Release Notes</a> 中发现 Ubuntu 9.04 is fully supported. 猜测也许是需要新版本。 尝试下载新版本安装后，重新安装和配置 vmware-tools， 一切顺利！</p>
</div>
<p>第三步，安装我需要的各种软件。</p>
<p>0. 设置source.list，我使用 mirrors.163.com.<br />
   设置网卡：</p>
<pre>
auto lo
iface lo inet loopback

auto eth0
iface eth0 inet static
address 192.168.1.126
netmask 255.255.255.0
gateway 192.168.1.1

#auto eth0
#iface eth0 inet dhcp
</pre>
<p>1. 安装 vim/ctags/cscope, 设置颜色，缩进等。 The details are noted at <a href="http://blog.feihoo.com/archives/433" class="broken_link" >Here</a>.</p>
<ul>
<li>install: sudo apt-get install vim</li>
<li>Install Chinese vim help: download from http://vimcdoc.sourceforge.net/, tar and enter the directory, execute
<li>

<div class="wp_syntax"><div class="code"><pre class="sh" style="font-family:monospace;">sudo ./vimcdoc.sh -i</pre></div></div>

<li>sudo apt-get install exuberant-ctags cscope</li>
</ul>
<p>2. 安装 JDK/C++工具: </p>
<pre>
sudo apt-get install sun-java6-jdk sun-java6-source
sudo apt-get install build-essential
</pre>
<p>3. 安装manuals:</p>
<div style="padding-left:20px;padding-top:5px;">
开发用的手册页：</p>

<div class="wp_syntax"><div class="code"><pre class="sh" style="font-family:monospace;">sudo apt-get install manpages-dev</pre></div></div>

<p>安装 Posix 相关的手册页。pthread 库相关的手册页就在这里面，而不在 Dev manual pages 中。</p>

<div class="wp_syntax"><div class="code"><pre class="sh" style="font-family:monospace;">sudo apt-get install manpages-posix manpages-posix-dev</pre></div></div>

<p>安装 STL library man pages:</p>

<div class="wp_syntax"><div class="code"><pre class="sh" style="font-family:monospace;">sudo apt-get install libstdc++6-4.2-doc</pre></div></div>

</div>
<p>4. 安装版本工具 Subversion 和 Git:</p>

<div class="wp_syntax"><div class="code"><pre class="sh" style="font-family:monospace;">sudo apt-get install subversion subversion-tools git-doc git-core</pre></div></div>

<p>5. Configure SSH server:</p>

<div class="wp_syntax"><div class="code"><pre class="sh" style="font-family:monospace;">sudo apt-get install openssh-server</pre></div></div>

<p>.<br />
6. Install LAMP server by tasksel, and configure;<br />
7. 中文支持。我安装系统时用的是英文，因此 LANG=&#8217;en_US.UTF-8&#8242;。中文输入遵循下面三步骤即可：</p>
<div style="padding-left:20px;padding-top:5px;">
<ol>
<li>Install Simple Chinese Language support.</li>
<li>install: sudo apt-get install scim scim-pinyin</li>
<li>System->Administration->Language Support->Input Method, select scim. </li>
<ol>Reboot system, 此时就可以使用智能拼音了。</ol>
</ol>
<p>Resource: <a href="https://wiki.ubuntu.com/InputMethods/SCIM/Setup">SCIM Setup</a>, <a href="https://help.ubuntu.com/community/SCIM">SCIM Usage</a></p>
<p>中文问题的解决没有这么简单，还存在下面的问题：</p>
<ul>
<li>gedit不能打开中文文件： 这个文件主要是gedit猜测编码的机制造成的，略加修改就可以。具体参考<a href="http://www.byvoid.com/blog/gedit-encoding/">这里</a>。</li>
<li>vim不能打开中文文件：<a href="http://blog.feihoo.com/archives/433" class="broken_link" >Here</a> </li>
<li>pdf不能阅读某些中文文件： 问题的症状是能够阅读某些中文pdf，但是还有一些pdf则表现为乱码。问题的原因不太清楚，但是Google后安装了一个新包 <a href="http://poppler.freedesktop.org/">poppler-data</a>，就解决了。(sudo apt-get install poppler-data)</li>
</ul>
</div>
<p>8. 安装 CHM 格式文档查看工具 kchmviewer.</p>
<pre>sudo apt-get install kchmviewer</pre>
<p> 但是 kchmviewer 在查看 boost中文文档页时出现了编码错误。当然这不一定就是kchmviewer有问题，也可能是boost中文文档本身的兼容性等。于是另外安装了chmsee， chmsee的另外一个优点就是安装时体积很小，下载过程中才下了几百K。当然也可能是因为我提前把其他需要的库都已经装上了&#8230;<br />
9. ruby gems: </p>
<pre>sudo apt-get install rubygems1.9.1</pre>
<p>10. 声音问题的解决：<a href="http://hi.baidu.com/tony_chen2009/blog/item/3281fe51677d53858d54304e.html">这里</a> </p>


<p>Related posts:<ol><li><a href='http://blog.xiping.me/2008/10/ubuntu-%e4%b8%8a%e5%ae%89%e8%a3%85buildix%ef%bc%8cphp5%ef%bc%8c-apache2-%e7%9a%84%e7%83%a6%e6%81%bc.html' rel='bookmark' title='Permanent Link: Ubuntu 上安装buildix，PHP5， Apache2'>Ubuntu 上安装buildix，PHP5， Apache2</a></li>
<li><a href='http://blog.xiping.me/2009/11/%e9%98%bf%e9%87%8c%e5%b7%b4%e5%b7%b4%e6%94%b6%e8%b4%ad%e4%b8%87%e7%bd%91%e4%b8%8evmware%e6%94%b6%e8%b4%adspringsource-%e5%b8%83%e5%b1%80%e4%ba%91%e8%ae%a1%e7%ae%97.html' rel='bookmark' title='Permanent Link: 阿里巴巴收购万网与Vmware收购SpringSource: 布局云计算'>阿里巴巴收购万网与Vmware收购SpringSource: 布局云计算</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://blog.xiping.me/2009/12/my-ubuntu-installation-log.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>设计与开发的五条原则</title>
		<link>http://blog.xiping.me/2009/12/software-design-devolopment-pricinples.html</link>
		<comments>http://blog.xiping.me/2009/12/software-design-devolopment-pricinples.html#comments</comments>
		<pubDate>Tue, 15 Dec 2009 15:23:55 +0000</pubDate>
		<dc:creator>西坪</dc:creator>
				<category><![CDATA[$Architecture & design]]></category>
		<category><![CDATA[$软件工程与管理]]></category>
		<category><![CDATA[effcient]]></category>
		<category><![CDATA[systemdesign]]></category>

		<guid isPermaLink="false">http://blog.feihoo.com/?p=388</guid>
		<description><![CDATA[从2004年初（大学二年级第二学期）加入学校就业信息网站，靠写代码获得第一笔收入，迄今已经将近六年。
第一条原则，首先弄清你的问题是什么。这一条规则无论怎么强调都不过分。
在《Programming Pearls》第二版的开篇，Jon Bentley 讲的就是，首先弄清你的问题是什么！ 在你没有详细、明确地定义好你的问题之前，你所做的大部分工作只产出废物。这些年，最头疼的事情，就是经常搞了一大堆东西，累死累活，甚至加班加点，最后总才发现很多事情偏离了目标。但这样的事情，总是在周围一遍一遍地发生。
一个工程师，如果在接到一个问题时首先不是尽可能挖到细致的资料，定义问题，并向了解问题的人去反馈，详细讨论问题的定义。虽然问题定义不是那么容易，但不首先定义好问题，那就是不合格的工程师。
还有很多原则，大抵都是这个原则的派生品。
第二条规则， 弄清你要干什么，以及哪些先干，哪些后干，哪些根本就不需要干。
说白了，就是把问题分解，列个表，排个先后顺序。这是大部分程序员最蹩脚的部分。高效的本质不是捧着ThoughtWorks那本《卓有成效的程序员》，而是我这条原则。我对Joel的书里印象最深刻的就是有关用Excel列任务列表的部分。
这条仍然是如此重要，以致于著名的YAGNI, (You ain&#8217;t gonna need it ）仅仅是一条推论而已。
当然，区分的标准是什么？It depends. 但是最重要的参照是，怎么做你能获得最大产出？也许你会在所谓的扩展性、适应需求变化与可工作的代码，用户的需求之间抉择。 最重要的还是可工作的代码，能够按时 ship the beta! 
记住，先列出来要干什么；然后分清先后顺序，然后淘汰那些可以不干的。
第三条规则，KISS。 Keep It Simple Stupid。
用郭靖和杨过来比喻，代码要像郭靖一样用最简单直接的方式强壮地工作，不需要太多的波折。你的程序要是像杨过的人生那么复杂、聪明，早死翘翘了。 你的程序要简单强壮地干活，思想越简单越好，功能和特性越少越好。
这一条对于设计是至关重要的，浮躁的程序员们经常要在架构设计中引入模式、分层，又或者是绚丽的Ajax效果之类，完全是无知下的自虐。我也是好些年后才明白这条道理，直到后来开始使用Unix下的那些让无数人着迷的工具，才真真地看到了这条规则的巨大威力。
要特别澄清一下，KISS 与你的程序是否好用，是否易于复用，不但不矛盾，而且是相辅相成的。你要知道的只是你的程序应该做什么，然后努力做好。借用《Programming Pearls》开篇里法国作家兼飞机设计师的话：“设计者确定其设计已经达到了完美的标准不是不能再增加任何东西,而是不能再减少任何东西”。又如Chuck Yeager将军（第一个超音速飞行的人）赞扬一架飞机的机械系统时的用词是“结构简单、部件很少、易于维护、非常坚固”。
第四条规则，一键集成和适当的自动化测试。
这条不多说了，在有条件的情况下做会受益非浅。
其他还有一些很有名的原则，例如 DRY （Don&#8217;t Repeat Yourself)， 也许是因为一开始我就懂得了这个道理（尤记得大学的时候把ASP代码提取函数，封装Head和Foot，将写HTML Table的封装成方法来根据不同的数据集打印，好傻。），感触没那么深。 
六年了，好快。
(Update 2009-12-23)
第五条： 一定需要且只需要数页简单明了的设计说明书。
这个设计说明最好不用word，最好是放在源代码下的html或者txt格式。简单粗线条的UML最适宜用在这种地方。当然设计文档也可以放在别的地方。
P.S.
用原则这个词，是为了强调重要性。遣词或有问题，慎自斟酌之。


Related posts:程序员提高工作效率的方法



Related posts:<ol><li><a href='http://blog.xiping.me/2010/04/work-effcient-thoughts.html' rel='bookmark' title='Permanent Link: 程序员提高工作效率的方法'>程序员提高工作效率的方法</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>从2004年初（大学二年级第二学期）加入学校就业信息网站，靠写代码获得第一笔收入，迄今已经将近六年。</p>
<p><strong>第一条原则，首先弄清你的问题是什么。这一条规则无论怎么强调都不过分。</strong></p>
<p>在<a href="http://www.china-pub.com/209243">《Programming Pearls》</a>第二版的开篇，<a href="http://en.wikipedia.org/wiki/Jon_Bentley">Jon Bentley</a> 讲的就是，首先弄清你的问题是什么！ 在你没有详细、明确地定义好你的问题之前，你所做的大部分工作只产出废物。这些年，最头疼的事情，就是经常搞了一大堆东西，累死累活，甚至加班加点，最后总才发现很多事情偏离了目标。但这样的事情，总是在周围一遍一遍地发生。</p>
<p>一个工程师，如果在接到一个问题时首先不是尽可能挖到细致的资料，定义问题，并向了解问题的人去反馈，详细讨论问题的定义。虽然问题定义不是那么容易，但不首先定义好问题，那就是不合格的工程师。</p>
<p>还有很多原则，大抵都是这个原则的派生品。</p>
<p><strong>第二条规则， 弄清你要干什么，以及哪些先干，哪些后干，哪些根本就不需要干。</strong></p>
<p>说白了，就是把问题分解，列个表，排个先后顺序。这是大部分程序员最蹩脚的部分。高效的本质不是捧着ThoughtWorks那本《卓有成效的程序员》，而是我这条原则。我对Joel的书里印象最深刻的就是有关用Excel列任务列表的部分。</p>
<p>这条仍然是如此重要，以致于著名的YAGNI, (<a href="http://en.wikipedia.org/wiki/You_ain%27t_gonna_need_it">You ain&#8217;t gonna need it</a> ）仅仅是一条推论而已。</p>
<p>当然，区分的标准是什么？It depends. 但是最重要的参照是，怎么做你能获得最大产出？也许你会在所谓的扩展性、适应需求变化与可工作的代码，用户的需求之间抉择。 最重要的还是可工作的代码，能够按时 ship the beta! </p>
<p>记住，先列出来要干什么；然后分清先后顺序，然后淘汰那些可以不干的。</p>
<p><strong>第三条规则，KISS。 Keep It Simple Stupid。</strong><br />
用郭靖和杨过来比喻，代码要像郭靖一样用最简单直接的方式强壮地工作，不需要太多的波折。你的程序要是像杨过的人生那么复杂、聪明，早死翘翘了。 你的程序要简单强壮地干活，思想越简单越好，功能和特性越少越好。</p>
<p>这一条对于设计是至关重要的，浮躁的程序员们经常要在架构设计中引入模式、分层，又或者是绚丽的Ajax效果之类，完全是无知下的自虐。我也是好些年后才明白这条道理，直到后来开始使用Unix下的那些让无数人着迷的工具，才真真地看到了这条规则的巨大威力。</p>
<p>要特别澄清一下，KISS 与你的程序是否好用，是否易于复用，不但不矛盾，而且是相辅相成的。你要知道的只是你的程序应该做什么，然后努力做好。借用《Programming Pearls》开篇里法国作家兼飞机设计师的话：“设计者确定其设计已经达到了完美的标准不是不能再增加任何东西,而是不能再减少任何东西”。又如Chuck Yeager将军（第一个超音速飞行的人）赞扬一架飞机的机械系统时的用词是“结构简单、部件很少、易于维护、非常坚固”。</p>
<p><strong>第四条规则，一键集成和适当的自动化测试。</strong></p>
<p>这条不多说了，在有条件的情况下做会受益非浅。</p>
<p>其他还有一些很有名的原则，例如 DRY （<a href="http://en.wikipedia.org/wiki/Don%27t_repeat_yourself">Don&#8217;t Repeat Yourself</a>)， 也许是因为一开始我就懂得了这个道理（尤记得大学的时候把ASP代码提取函数，封装Head和Foot，将写HTML Table的封装成方法来根据不同的数据集打印，好傻。），感触没那么深。 </p>
<p>六年了，好快。</p>
<p><strong>(Update 2009-12-23)</strong><br />
<strong>第五条： 一定需要且只需要数页简单明了的设计说明书。</strong></p>
<p>这个设计说明最好不用word，最好是放在源代码下的html或者txt格式。简单粗线条的UML最适宜用在这种地方。当然设计文档也可以放在别的地方。</p>
<p>P.S.<br />
用原则这个词，是为了强调重要性。遣词或有问题，慎自斟酌之。</p>


<p>Related posts:<ol><li><a href='http://blog.xiping.me/2010/04/work-effcient-thoughts.html' rel='bookmark' title='Permanent Link: 程序员提高工作效率的方法'>程序员提高工作效率的方法</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://blog.xiping.me/2009/12/software-design-devolopment-pricinples.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Cygwin下使用公钥登录SSH</title>
		<link>http://blog.xiping.me/2009/12/cygwin-ssh-keys.html</link>
		<comments>http://blog.xiping.me/2009/12/cygwin-ssh-keys.html#comments</comments>
		<pubDate>Wed, 02 Dec 2009 07:02:12 +0000</pubDate>
		<dc:creator>西坪</dc:creator>
				<category><![CDATA[server & system]]></category>
		<category><![CDATA[ssh]]></category>

		<guid isPermaLink="false">http://blog.feihoo.com/?p=351</guid>
		<description><![CDATA[为了直接使用公钥登录SSH，而不使用密码登录Cygwin，费了老大劲，很长时间以来一直没有成功。此前，一直是按照网络上流传的方法，主要是生成key，然后设置到 authorized_keys中。遵照官方的命令，修改sshd_config, ssh_config, 但是一直没有奏效(不过遵照这些方法，在Ubuntu等系统上配置成功)。
昨天偶然在这个页面上看到 ssh-user-config 命令，试了试，就成功了！各位设置不成功的同学，考虑使用下这个命令，然后一路回车确认即可。
另一篇重要的参考文章：这里。
顺便记录下在探索 SSH使用公钥登录过程中学到的几个sshd相关的命令：

# debug more information 
ssh  -vvv  localhost
&#160;
#start services
net start sshd
#or
cygrunsrv  --start  sshd
&#160;
#login command for user name that has space
ssh  Mickey\  mouse@127.0.0.1
&#160;
#copy publickey to remote host ( 或使用 ssh-copy-id, e.g ssh-copy-id -i ~/.ssh/id_dsa.pub user@host ）
king@king:~$ cat .ssh/id_dsa.pub &#124; ssh master &#34;cat - &#62;&#62; ~/.ssh/authorized_keys&#34;
#copy [...]


Related posts:<ol><li><a href='http://blog.xiping.me/2011/03/break-gfw-on-android.html' rel='bookmark' title='Permanent Link: 在Android上走出天朝局域网'>在Android上走出天朝局域网</a></li>
<li><a href='http://blog.xiping.me/2009/10/maybe-another-choice-for-qq.html' rel='bookmark' title='Permanent Link: Maybe Another Choice for QQ?'>Maybe Another Choice for QQ?</a></li>
<li><a href='http://blog.xiping.me/2008/10/ubuntu-%e4%b8%8a%e5%ae%89%e8%a3%85buildix%ef%bc%8cphp5%ef%bc%8c-apache2-%e7%9a%84%e7%83%a6%e6%81%bc.html' rel='bookmark' title='Permanent Link: Ubuntu 上安装buildix，PHP5， Apache2'>Ubuntu 上安装buildix，PHP5， Apache2</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>为了直接使用公钥登录SSH，而不使用密码登录Cygwin，费了老大劲，很长时间以来一直没有成功。此前，一直是按照网络上流传的方法，主要是生成key，然后设置到 authorized_keys中。遵照官方的命令，修改sshd_config, ssh_config, 但是一直没有奏效(不过遵照这些方法，在Ubuntu等系统上配置成功)。</p>
<p>昨天偶然在<a href="http://chinese-watercolor.com/LRP/printsrv/cygwin-sshd.html">这个页面</a>上看到 ssh-user-config 命令，试了试，就成功了！各位设置不成功的同学，考虑使用下这个命令，然后一路回车确认即可。</p>
<p>另一篇重要的参考文章：<a href="http://ist.uwaterloo.ca/~kscully/CygwinSSHD_W2K3.html">这里</a>。</p>
<p>顺便记录下在探索 SSH使用公钥登录过程中学到的几个sshd相关的命令：</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;"># debug more information </span>
<span style="color: #c20cb9; font-weight: bold;">ssh</span>  <span style="color: #660033;">-vvv</span>  localhost
&nbsp;
<span style="color: #666666; font-style: italic;">#start services</span>
net start sshd
<span style="color: #666666; font-style: italic;">#or</span>
cygrunsrv  <span style="color: #660033;">--start</span>  sshd
&nbsp;
<span style="color: #666666; font-style: italic;">#login command for user name that has space</span>
<span style="color: #c20cb9; font-weight: bold;">ssh</span>  Mickey\  mouse<span style="color: #000000; font-weight: bold;">@</span>127.0.0.1
&nbsp;
<span style="color: #666666; font-style: italic;">#copy publickey to remote host ( 或使用 ssh-copy-id, e.g ssh-copy-id -i ~/.ssh/id_dsa.pub user@host ）</span>
king<span style="color: #000000; font-weight: bold;">@</span>king:~$ <span style="color: #c20cb9; font-weight: bold;">cat</span> .ssh<span style="color: #000000; font-weight: bold;">/</span>id_dsa.pub <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">ssh</span> master <span style="color: #ff0000;">&quot;cat - &gt;&gt; ~/.ssh/authorized_keys&quot;</span>
<span style="color: #666666; font-style: italic;">#copy publickey from remote host</span>
king<span style="color: #000000; font-weight: bold;">@</span>king:~$  <span style="color: #c20cb9; font-weight: bold;">ssh</span> master <span style="color: #ff0000;">&quot;cat .ssh/id_dsa.pub&quot;</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">cat</span> - <span style="color: #000000; font-weight: bold;">&gt;&gt;</span> ~<span style="color: #000000; font-weight: bold;">/</span>.ssh<span style="color: #000000; font-weight: bold;">/</span>authorized_keys<span style="color: #ff0000;">&quot;</span></pre></div></div>

<p>在某些情况下，必须使用代理登录SSH服务器。<a href="http://bent.latency.net/bent/git/goto-san-connect-1.85/src/connect.html">connect.c</a> is the simple relaying command to make network connection via SOCKS and https proxy. It is mainly intended to be used as proxy command of OpenSSH. You can make SSH session beyond the firewall with this command. </p>
<p>在Windows下，只需要下载<a href=" http://www.taiyo.co.jp/~gotoh/ssh/connect.exe">connect.exe</a>到c:/windows，然后在  ~/.ssh/config中添加如下配置：</p>

<div class="wp_syntax"><div class="code"><pre class="sh" style="font-family:monospace;">ProxyCommand connect -S x.x.x.x:x %h %p</pre></div></div>

<p>connect.c 还支持 https 代理，真不赖。</p>


<p>Related posts:<ol><li><a href='http://blog.xiping.me/2011/03/break-gfw-on-android.html' rel='bookmark' title='Permanent Link: 在Android上走出天朝局域网'>在Android上走出天朝局域网</a></li>
<li><a href='http://blog.xiping.me/2009/10/maybe-another-choice-for-qq.html' rel='bookmark' title='Permanent Link: Maybe Another Choice for QQ?'>Maybe Another Choice for QQ?</a></li>
<li><a href='http://blog.xiping.me/2008/10/ubuntu-%e4%b8%8a%e5%ae%89%e8%a3%85buildix%ef%bc%8cphp5%ef%bc%8c-apache2-%e7%9a%84%e7%83%a6%e6%81%bc.html' rel='bookmark' title='Permanent Link: Ubuntu 上安装buildix，PHP5， Apache2'>Ubuntu 上安装buildix，PHP5， Apache2</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://blog.xiping.me/2009/12/cygwin-ssh-keys.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>益智思考题以及分析</title>
		<link>http://blog.xiping.me/2009/11/puzzs.html</link>
		<comments>http://blog.xiping.me/2009/11/puzzs.html#comments</comments>
		<pubDate>Sun, 22 Nov 2009 15:10:24 +0000</pubDate>
		<dc:creator>西坪</dc:creator>
				<category><![CDATA[$算法与计算原理]]></category>
		<category><![CDATA[puzzle]]></category>

		<guid isPermaLink="false">http://blog.feihoo.com/?p=266</guid>
		<description><![CDATA[问题虽然很朴素，但是却能够起到活跃脑筋的作用，有些问题的分析还能够有有利于我们对数学知识（例如概率）的运用，所以把这些益智题都列出来如下。
1. 有一家人父亲、母亲和儿子、女儿，当父亲和女儿独处或者母亲和儿子独处时，父亲（母亲）就会骂女儿（儿子）。现在他们要过一条河，河上有一条船，船一次只能容纳两人,并只能由大人驾船。问他们应该怎么过河才能保证女儿和儿子都不会被骂。
完全是推理分析能力，采用试错法。答案有两种，其中一种是母亲先送女儿过河，然后目前回来接父亲过河，然后父亲回去接儿子过河。
2. 我三个筐子，一个装苹果，一个装橙子，一个装苹果和橙子。你看不到筐子里的东东，而标签都贴错了，你只能任选一个筐子，拿一个水果出来，然后把标签都改正过来，怎么拿?
根据条件要一次确定最多的结果，肯定应该去挑选标签为苹果和橙子的框，选出的水果就决定了这个框的真实标签，然后决定了另外一个标签称是该水果的框里的是混合物，剩余一个自然清楚了。
3. 屋子里有三盏灯，屋外有三个开关，屋外看不到屋里。你在屋外可以任意设置三个开关，然后进屋一次，就要说出哪个开关控制哪盏灯。
? 题目似乎不太清楚。
4. 12个小球，其中有一个是坏球。有一架天平。需要你用最少的称次数来确定哪个小球是坏的并且它到底是轻还是重。
答案是3次。这是一个涉及到概率的问题，需要用概率的方法来选择。详细请参考 刘未鹏的博客 。
对于类似于此种问题， 有其特殊的规律。

第一，是天平有三种输出的可能，所以应该让最终的结果均分称三等分。分得越严格，最有利于最终结果。
第二，分组时，还应该要保证天平输出三种结果的几率是均等的。

这种方式通过构造最佳决策树来解决问题。在刘未鹏的文章中，还提到有人用信息论的方式来讨论此问题。



No related posts.


No related posts.]]></description>
			<content:encoded><![CDATA[<p>问题虽然很朴素，但是却能够起到活跃脑筋的作用，有些问题的分析还能够有有利于我们对数学知识（例如概率）的运用，所以把这些益智题都列出来如下。</p>
<p>1. 有一家人父亲、母亲和儿子、女儿，当父亲和女儿独处或者母亲和儿子独处时，父亲（母亲）就会骂女儿（儿子）。现在他们要过一条河，河上有一条船，船一次只能容纳两人,并只能由大人驾船。问他们应该怎么过河才能保证女儿和儿子都不会被骂。</p>
<blockquote><p>完全是推理分析能力，采用试错法。答案有两种，其中一种是母亲先送女儿过河，然后目前回来接父亲过河，然后父亲回去接儿子过河。</p></blockquote>
<p>2. 我三个筐子，一个装苹果，一个装橙子，一个装苹果和橙子。你看不到筐子里的东东，而标签都贴错了，你只能任选一个筐子，拿一个水果出来，然后把标签都改正过来，怎么拿?</p>
<blockquote><p>根据条件要一次确定最多的结果，肯定应该去挑选标签为苹果和橙子的框，选出的水果就决定了这个框的真实标签，然后决定了另外一个标签称是该水果的框里的是混合物，剩余一个自然清楚了。</p></blockquote>
<p>3. 屋子里有三盏灯，屋外有三个开关，屋外看不到屋里。你在屋外可以任意设置三个开关，然后进屋一次，就要说出哪个开关控制哪盏灯。</p>
<blockquote><p>? 题目似乎不太清楚。</p></blockquote>
<p>4. 12个小球，其中有一个是坏球。有一架天平。需要你用最少的称次数来确定哪个小球是坏的并且它到底是轻还是重。</p>
<blockquote><p>答案是3次。这是一个涉及到概率的问题，需要用概率的方法来选择。详细请参考 <a href="http://blog.csdn.net/pongba/archive/2008/06/13/2544933.aspx">刘未鹏的博客</a> 。<br />
对于类似于此种问题， 有其特殊的规律。</p>
<ul>
<li>第一，是天平有三种输出的可能，所以应该让最终的结果均分称三等分。分得越严格，最有利于最终结果。</li>
<li>第二，分组时，还应该要保证天平输出三种结果的几率是均等的。</li>
</ul>
<p>这种方式通过构造最佳决策树来解决问题。在刘未鹏的文章中，还提到有人用信息论的方式来讨论此问题。
</p></blockquote>


<p>No related posts.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.xiping.me/2009/11/puzzs.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>钗头凤</title>
		<link>http://blog.xiping.me/2009/11/%e9%92%97%e5%a4%b4%e5%87%a4.html</link>
		<comments>http://blog.xiping.me/2009/11/%e9%92%97%e5%a4%b4%e5%87%a4.html#comments</comments>
		<pubDate>Sat, 07 Nov 2009 06:22:17 +0000</pubDate>
		<dc:creator>西坪</dc:creator>
				<category><![CDATA[@迷思]]></category>
		<category><![CDATA[love]]></category>
		<category><![CDATA[古诗]]></category>

		<guid isPermaLink="false">http://blog.feihoo.com/?p=105</guid>
		<description><![CDATA[南宋词人陆游(1125-1209)，在1144年娶了表妹唐琬。次年，唐琬被逐出家门。依古人的说法乃因「不当母夫人意」「二亲恐其惰於学，数谴妇，放翁不敢逆尊者意，与妇诀」。（但依陆游晚年诗作（《剑南诗稿》卷十四），是因唐琬不孕，而遭公婆逐出。） 后陆游另娶，唐婉改嫁皇族赵士程。
十年后一春日绍兴城外沈园中，陆游来此赏春，偶遇唐婉与赵士程也来此春游。 虽遇然不得诉怀，唐婉派人送来一些酒菜，以示默默关怀，然后与夫离去。陆游伤心之余，在园墙上题下《钗头凤》：


红酥手，黄藤酒，满城春色宫墙柳。
东风恶，欢情薄，一怀愁绪，几年离索。
错！错！错！
春如旧，人空瘦，泪痕红邑鲛绡透。
桃花落，闲池阁。山盟虽在，锦书难托。
莫！莫！莫！ 

唐婉后以另一首《钗头凤》作答：


世情薄，人情恶，雨送黄昏花易落。
晓风干，泪痕残，欲笺心事，独语斜阑。
难！难！难！
人成各，今非昨，病魂常似秋千索。
角声寒，夜阑珊。怕人寻问，咽泪装欢。
瞒！瞒！瞒！ 

而后不久，唐婉忧郁而辞世。史载：「未几，怏怏而卒」。
陆游去世前一年，再来沈园，又题下：
「沈家园里花如锦，半是当年识放翁；也信美人终作土，不堪幽梦太匆匆」
好一个「也信美人终作土，不堪幽梦太匆匆」，其中何等苦辛！
参考：

百度知道：谁能够提供陆游及唐婉的，《钗头凤》这两首词？
沈园
钗头凤 陆游与唐婉



Related posts:孔雀东南飞，五里一徘徊



Related posts:<ol><li><a href='http://blog.xiping.me/2009/11/%e5%ad%94%e9%9b%80%e4%b8%9c%e5%8d%97%e9%a3%9e%ef%bc%8c%e4%ba%94%e9%87%8c%e4%b8%80%e5%be%98%e5%be%8a.html' rel='bookmark' title='Permanent Link: 孔雀东南飞，五里一徘徊'>孔雀东南飞，五里一徘徊</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>南宋词人陆游(1125-1209)，在1144年娶了表妹唐琬。次年，唐琬被逐出家门。依古人的说法乃因「不当母夫人意」「二亲恐其惰於学，数谴妇，放翁不敢逆尊者意，与妇诀」。（但依陆游晚年诗作（《剑南诗稿》卷十四），是因唐琬不孕，而遭公婆逐出。） 后陆游另娶，唐婉改嫁皇族赵士程。</p>
<p>十年后一春日绍兴城外沈园中，陆游来此赏春，偶遇唐婉与赵士程也来此春游。 虽遇然不得诉怀，唐婉派人送来一些酒菜，以示默默关怀，然后与夫离去。陆游伤心之余，在园墙上题下《钗头凤》：</p>
<ul style="padding-left:20px">
<ol>
红酥手，黄藤酒，满城春色宫墙柳。<br />
东风恶，欢情薄，一怀愁绪，几年离索。<br />
错！错！错！<br />
春如旧，人空瘦，泪痕红邑鲛绡透。<br />
桃花落，闲池阁。山盟虽在，锦书难托。<br />
莫！莫！莫！ </ol>
</ul>
<p>唐婉后以另一首《钗头凤》作答：</p>
<ul style="padding-left:20px">
<ol>
世情薄，人情恶，雨送黄昏花易落。<br />
晓风干，泪痕残，欲笺心事，独语斜阑。<br />
难！难！难！<br />
人成各，今非昨，病魂常似秋千索。<br />
角声寒，夜阑珊。怕人寻问，咽泪装欢。<br />
瞒！瞒！瞒！ </ol>
</ul>
<p>而后不久，唐婉忧郁而辞世。史载：「未几，怏怏而卒」。</p>
<p>陆游去世前一年，再来沈园，又题下：<br />
「沈家园里花如锦，半是当年识放翁；也信美人终作土，不堪幽梦太匆匆」</p>
<p>好一个「也信美人终作土，不堪幽梦太匆匆」，其中何等苦辛！</p>
<p>参考：</p>
<ul style="padding-left:20px">
<a href="http://zhidao.baidu.com/question/24861604.html">百度知道：谁能够提供陆游及唐婉的，《钗头凤》这两首词？</a><br />
<a href="http://baike.baidu.com/view/23627.htm">沈园</a><br />
<a href="http://www.jsdj.com/luyou/lyzy/zjshaoxing5.htm">钗头凤 陆游与唐婉</a>
</ul>


<p>Related posts:<ol><li><a href='http://blog.xiping.me/2009/11/%e5%ad%94%e9%9b%80%e4%b8%9c%e5%8d%97%e9%a3%9e%ef%bc%8c%e4%ba%94%e9%87%8c%e4%b8%80%e5%be%98%e5%be%8a.html' rel='bookmark' title='Permanent Link: 孔雀东南飞，五里一徘徊'>孔雀东南飞，五里一徘徊</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://blog.xiping.me/2009/11/%e9%92%97%e5%a4%b4%e5%87%a4.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>孔雀东南飞，五里一徘徊</title>
		<link>http://blog.xiping.me/2009/11/%e5%ad%94%e9%9b%80%e4%b8%9c%e5%8d%97%e9%a3%9e%ef%bc%8c%e4%ba%94%e9%87%8c%e4%b8%80%e5%be%98%e5%be%8a.html</link>
		<comments>http://blog.xiping.me/2009/11/%e5%ad%94%e9%9b%80%e4%b8%9c%e5%8d%97%e9%a3%9e%ef%bc%8c%e4%ba%94%e9%87%8c%e4%b8%80%e5%be%98%e5%be%8a.html#comments</comments>
		<pubDate>Fri, 06 Nov 2009 15:01:42 +0000</pubDate>
		<dc:creator>西坪</dc:creator>
				<category><![CDATA[@迷思]]></category>
		<category><![CDATA[love]]></category>
		<category><![CDATA[古诗]]></category>
		<category><![CDATA[古文]]></category>

		<guid isPermaLink="false">http://blog.feihoo.com/?p=79</guid>
		<description><![CDATA[今夜观央视《孔雀东南飞》，恰逢“鸡鸣入机织，夜夜不得息。三日断五匹，大人故嫌迟”，思及二人即将“黄泉下相见”，心有戚戚焉。复寻此诗如下。另有百度百科中节选精妙评述，引述如后。又精彩剧评：随看随写，孔雀东南飞，只为你徘徊。
序曰：汉末建安中，庐江府小吏焦仲卿妻刘氏，为仲卿母所遣，自誓不嫁。其家逼之，乃投水而死。仲卿闻之，亦自缢于庭树。时人伤之，为诗云尔。
孔雀东南飞，五里一徘徊。
　　“十三能织素，十四学裁衣。十五弹箜篌，十六诵诗书。十七为君妇，心中常苦悲。君既为府吏，守节情不移。贱妾留空房，相见常日稀。鸡鸣入机织，夜夜不得息。三日断五匹，大人故嫌迟。非为织作迟，君家妇难为！妾不堪驱使，徒留无所施。便可白公姥，及时相遣归。”
　　府吏得闻之，堂上启阿母：“儿已薄禄相，幸复得此妇。结发同枕席，黄泉共为友。共事二三年，始尔未为久。女行无偏斜，何意致不厚。”
　　阿母谓府吏：“何乃太区区！此妇无礼节，举动自专由。吾意久怀忿，汝岂得自由！东家有贤女，自名秦罗敷。可怜体无比，阿母为汝求。便可速遣之，遣去慎莫留！”
　　府吏长跪告：“伏惟启阿母。今若遣此妇，终老不复取！”
　　阿母得闻之，槌床便大怒：“小子无所畏，何敢助妇语！吾已失恩义，会不相从许！”
　　府吏默无声，再拜还入户。举言谓新妇，哽咽不能语：“我自不驱卿，逼迫有阿母。卿但暂还家，吾今且报府。不久当归还，还必相迎取。以此下心意，慎勿违吾语。”
　　新妇谓府吏：“勿复重纷纭。往昔初阳岁，谢家来贵门。奉事循公姥，进止敢自专？昼夜勤作息，伶俜萦苦辛。谓言无罪过，供养卒大恩；仍更被驱遣，何言复来还！妾有绣腰襦，葳蕤自生光；红罗复斗帐，四角垂香囊；箱帘六七十，绿碧青丝绳，物物各自异，种种在其中。人贱物亦鄙，不足迎后人，留待作遗施，于今无会因。时时为安慰，久久莫相忘！”
　　鸡鸣外欲曙，新妇起严妆。著我绣夹裙，事事四五通。足下蹑丝履，头上玳瑁光。腰若流纨素，耳著明月珰。指如削葱根，口如含朱丹。纤纤作细步，精妙世无双。
　　上堂拜阿母，阿母怒不止。“昔作女儿时，生小出野里。本自无教训，兼愧贵家子。受母钱帛多，不堪母驱使。今日还家去，念母劳家里。”却与小姑别，泪落连珠子。“新妇初来时，小姑始扶床；今日被驱遣，小姑如我长。勤心养公姥，好自相扶将。初七及下九，嬉戏莫相忘。”出门登车去，涕落百余行。
　　府吏马在前，新妇车在后。隐隐何甸甸，俱会大道口。下马入车中，低头共耳语：“誓不相隔卿，且暂还家去。吾今且赴府，不久当还归。誓天不相负！”
　　新妇谓府吏：“感君区区怀！君既若见录，不久望君来。君当作磐石，妾当作蒲苇。蒲苇纫如丝，磐石无转移。我有亲父兄，性行暴如雷，恐不任我意，逆以煎我怀。”举手长劳劳，二情同依依 。
　　入门上家堂，进退无颜仪。阿母大拊掌，不图子自归：“十三教汝织，十四能裁衣，十五弹箜篌，十六知礼仪，十七遣汝嫁，谓言无誓违。汝今何罪过，不迎而自归？”兰芝惭阿母：“儿实无罪过。”阿母大悲摧。
　　还家十余日，县令遣媒来。云有第三郎，窈窕世无双。年始十八九，便言多令才。
　　阿母谓阿女：“汝可去应之。”
　　阿女含泪答：“兰芝初还时，府吏见丁宁，结誓不别离。今日违情义，恐此事非奇。自可断来信，徐徐更谓之。”
　　阿母白媒人：“贫贱有此女，始适还家门。不堪吏人妇，岂合令郎君？幸可广问讯，不得便相许。”
　　媒人去数日，寻遣丞请还，说有兰家女，承籍有宦官。云有第五郎，娇逸未有婚。遣丞为媒人，主簿通语言。直说太守家，有此令郎君，既欲结大义，故遣来贵门。
　　阿母谢媒人：“女子先有誓，老姥岂敢言！”
　　阿兄得闻之，怅然心中烦。举言谓阿妹：“作计何不量！先嫁得府吏，后嫁得郎君。否泰如天地，足以荣汝身。不嫁义郎体，其往欲何云？”
　　兰芝仰头答：“理实如兄言。谢家事夫婿，中道还兄门。处分适兄意，那得自任专！虽与府吏要，渠会永无缘。登即相许和，便可作婚姻。”
　　媒人下床去。诺诺复尔尔。还部白府君：“下官奉使命，言谈大有缘。”府君得闻之，心中大欢喜。视历复开书，便利此月内，六合正相应。良吉三十日，今已二十七，卿可去成婚。交语速装束，络绎如浮云。青雀白鹄舫，四角龙子幡。婀娜随风转，金车玉作轮。踯躅青骢马，流苏金镂鞍。赍钱三百万，皆用青丝穿。杂彩三百匹，交广市鲑珍。从人四五百，郁郁登郡门。
　　阿母谓阿女：“适得府君书，明日来迎汝。何不作衣裳？莫令事不举！”
　　阿女默无声，手巾掩口啼，泪落便如泻。移我琉璃榻，出置前窗下。左手持刀尺，右手执绫罗。朝成绣夹裙，晚成单罗衫。晻晻日欲暝，愁思出门啼。
　　府吏闻此变，因求假暂归。未至二三里，摧藏马悲哀。新妇识马声，蹑履相逢迎。怅然遥相望，知是故人来。举手拍马鞍，嗟叹使心伤：“自君别我后，人事不可量。果不如先愿，又非君所详。我有亲父母，逼迫兼弟兄。以我应他人，君还何所望！”
　　府吏谓新妇：“贺卿得高迁！磐石方且厚，可以卒千年；蒲苇一时纫，便作旦夕间。卿当日胜贵，吾独向黄泉！”
　　新妇谓府吏：“何意出此言！同是被逼迫，君尔妾亦然。黄泉下相见，勿违今日言！”执手分道去，各各还家门。生人作死别，恨恨那可论？念与世间辞，千万不复全！
　　府吏还家去，上堂拜阿母：“今日大风寒，寒风摧树木，严霜结庭兰。儿今日冥冥，令母在后单。故作不良计，勿复怨鬼神！命如南山石，四体康且直！”
　　阿母得闻之，零泪应声落：“汝是大家子，仕宦于台阁。慎勿为妇死，贵贱情何薄！东家有贤女，窈窕艳城郭，阿母为汝求，便复在旦夕。”
　　府吏再拜还，长叹空房中，作计乃尔立。转头向户里，渐见愁煎迫。
　　其日牛马嘶，新妇入青庐。奄奄黄昏后，寂寂人定初。我命绝今日，魂去尸长留！揽裙脱丝履，举身赴清池。
　　府吏闻此事，心知长别离。徘徊庭树下，自挂东南枝。
　　两家求合葬，合葬华山傍。东西植松柏，左右种梧桐。枝枝相覆盖，叶叶相交通。中有双飞鸟，自名为鸳鸯。仰头相向鸣，夜夜达五更。行人驻足听，寡妇起彷徨。多谢后世人，戒之慎勿忘。


下面为来自百度百科上的部分精妙评述，引录如下。更多精妙请参考：百度百科》孔雀东南飞
     全诗“共一千七百八十五字，古今第一首长诗也。淋淋漓漓，反反复复，杂述十数人口中语，而各肖其声音面目，岂非化工之笔”（《古诗源》卷四，沈德潜按语）。在贯穿全篇的对话中，可以看到，刘兰芝对仲卿、对焦母、对小姑、对自己的哥哥和母亲讲话时的态度与语气各不相同，正是在这种不同中可以感受到她那勤劳、善良、备受压迫而又富于反抗精神的外柔内刚的个性。同样的，在焦仲卿各种不同场合的话语中，也可以感受到他那忠于爱情、明辨是非但又迫于母亲威逼的诚正而软弱、但又有发展的性格。
     诗中写到兰芝与仲卿死前，兰芝假意同意再嫁，仲卿见兰芝后回家与母亲诀别，他俩这时的话语，非常切合各自的身份与处境。陈祚明《采菽堂古诗选》曾作过这样细致的分析：“兰芝不白母而府吏白母者，女之于母，子之于母，情固不同。女从夫者也，又恐母防之，且母有兄在，可死也。子之与妻，孰与母重？且子死母何依，能无白乎？同死者，情也。彼此不负，女以死偿，安得不以死？彼此时，母即悔而迎女，犹可两俱无死也。然度母终不肯迎女，死终不可以已，故白母之言亦有异者，儿今冥冥四语明言之矣，今日风寒命如山石，又不甚了了，亦恐母觉而防我也。府吏白母而母不防者，女之去久矣。他日不死而今日何为独死？不过谓此怨怼之言，未必实耳。故漫以东家女答之，且用相慰。然府吏白母，不言女将改适，不言女亦欲死，盖度母之性，必不肯改而迎女，而徒露真情，则防我不得死故也。”试想，兰芝如果直说要死，这个弱女子势必会遭到暴力的约束，被强迫成婚。而仲卿的情况自然与兰芝不同，诚如上述引文的分析。又如：“吾意久怀忿，汝岂得自由”、“小子无所畏，何敢助妇语”，于此可立见焦母的蛮横：“作计何不量！先嫁得府吏，后嫁得郎君。否泰如天地，足以荣汝身。不嫁义郎体，其往欲何云？”由此可见刘兄的势利。
     即使次要人物如媒人、府君的简短对话，也各各符合其人的身份、特点。
     诗中，简洁的人物行动刻划，有助于形象的鲜明；精炼的抒情性穿插，增强了行文的情韵。“鸡鸣外欲曙，新妇起严妆。著我绣夹裙，事事四五通”，写出了刘兰芝离开焦家时的矛盾心情。欲曙即起，表示她不愿在焦家生活的决心，严妆辞婆是她对焦母的抗议与示威。打扮时的事事四五通，表示了她对焦仲卿的爱，欲去又不忍遽去的微妙心理。“却与小姑别，泪落连珠子”，姑嫂关系不易相处，兰芝与小姑关系融洽，正表现了她的懂礼仪、易相处。这同焦母的不容恰成对照。另外，辞焦母不落泪，而辞小姑落泪，也可见兰芝的倔强。
     焦仲卿的形象刻划也是如此，他送兰芝到大道口，“下马入车中，低头共耳语”，表现了一片真情。闻知兰芝要成婚，“未至二三里，摧藏马悲哀”，诗篇用马悲渲染衬托他内心的强烈痛苦。临死前“长叹空房中”、“转头向户里”，对母亲还有所顾念，这里愈见他的诚正与善良。
     在整篇诗中，类似上述的动作刻划还有一些，笔墨虽不多，却极精粹。兰芝死时，一无反顾，“揽裙脱丝履，举身赴清池”；仲卿死时，顾念老母，“徘徊庭树下，自挂东南枝”，这些不同的动作细节，都切合各自的性格与处境。同样是母亲，焦母“捶床便大怒”的泼辣，刘母见兰芝回家时惊异而“大拊掌”的温和，对性格的描绘来说寥寥几笔已极传神。抒情性穿插较之动作刻划更少，但也是成功之笔“举手长劳劳，二情同依依”，兰芝和仲卿第一次分手时，作者情不自禁的感叹，增添了悲剧气氛。“生人作死别，恨恨那可论”，这画龙点睛的穿插，更激起了人们对焦、刘遭遇的同情。即使那教训式的全诗结尾，也带有浓重的抒情意味，充满了作者的同情与期望。


Related posts:钗头凤



Related posts:<ol><li><a href='http://blog.xiping.me/2009/11/%e9%92%97%e5%a4%b4%e5%87%a4.html' rel='bookmark' title='Permanent Link: 钗头凤'>钗头凤</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>今夜观央视《孔雀东南飞》，恰逢“鸡鸣入机织，夜夜不得息。三日断五匹，大人故嫌迟”，思及二人即将“黄泉下相见”，心有戚戚焉。复寻此诗如下。另有百度百科中节选精妙评述，引述如后。又精彩剧评：<a href="http://hi.baidu.com/%B9%C2%D3%B0%BE%AA%BA%E8/blog/item/09fcf603dde920e608fa93f9.html">随看随写，孔雀东南飞，只为你徘徊</a>。</p>
<p style="text-align: left; padding-left:20px"><em>序曰：汉末建安中，庐江府小吏焦仲卿妻刘氏，为仲卿母所遣，自誓不嫁。其家逼之，乃投水而死。仲卿闻之，亦自缢于庭树。时人伤之，为诗云尔。</em><br />
孔雀东南飞，五里一徘徊。<br />
　　“十三能织素，十四学裁衣。十五弹箜篌，十六诵诗书。十七为君妇，心中常苦悲。君既为府吏，守节情不移。贱妾留空房，相见常日稀。鸡鸣入机织，夜夜不得息。三日断五匹，大人故嫌迟。非为织作迟，君家妇难为！妾不堪驱使，徒留无所施。便可白公姥，及时相遣归。”<br />
　　府吏得闻之，堂上启阿母：“儿已薄禄相，幸复得此妇。结发同枕席，黄泉共为友。共事二三年，始尔未为久。女行无偏斜，何意致不厚。”<br />
　　阿母谓府吏：“何乃太区区！此妇无礼节，举动自专由。吾意久怀忿，汝岂得自由！东家有贤女，自名秦罗敷。可怜体无比，阿母为汝求。便可速遣之，遣去慎莫留！”<br />
　　府吏长跪告：“伏惟启阿母。今若遣此妇，终老不复取！”<br />
　　阿母得闻之，槌床便大怒：“小子无所畏，何敢助妇语！吾已失恩义，会不相从许！”<br />
　　府吏默无声，再拜还入户。举言谓新妇，哽咽不能语：“我自不驱卿，逼迫有阿母。卿但暂还家，吾今且报府。不久当归还，还必相迎取。以此下心意，慎勿违吾语。”<br />
　　新妇谓府吏：“勿复重纷纭。往昔初阳岁，谢家来贵门。奉事循公姥，进止敢自专？昼夜勤作息，伶俜萦苦辛。谓言无罪过，供养卒大恩；仍更被驱遣，何言复来还！妾有绣腰襦，葳蕤自生光；红罗复斗帐，四角垂香囊；箱帘六七十，绿碧青丝绳，物物各自异，种种在其中。人贱物亦鄙，不足迎后人，留待作遗施，于今无会因。时时为安慰，久久莫相忘！”<br />
　　鸡鸣外欲曙，新妇起严妆。著我绣夹裙，事事四五通。足下蹑丝履，头上玳瑁光。腰若流纨素，耳著明月珰。指如削葱根，口如含朱丹。纤纤作细步，精妙世无双。<br />
　　上堂拜阿母，阿母怒不止。“昔作女儿时，生小出野里。本自无教训，兼愧贵家子。受母钱帛多，不堪母驱使。今日还家去，念母劳家里。”却与小姑别，泪落连珠子。“新妇初来时，小姑始扶床；今日被驱遣，小姑如我长。勤心养公姥，好自相扶将。初七及下九，嬉戏莫相忘。”出门登车去，涕落百余行。<br />
　　府吏马在前，新妇车在后。隐隐何甸甸，俱会大道口。下马入车中，低头共耳语：“誓不相隔卿，且暂还家去。吾今且赴府，不久当还归。誓天不相负！”<br />
　　新妇谓府吏：“感君区区怀！君既若见录，不久望君来。君当作磐石，妾当作蒲苇。蒲苇纫如丝，磐石无转移。我有亲父兄，性行暴如雷，恐不任我意，逆以煎我怀。”举手长劳劳，二情同依依 。<br />
　　入门上家堂，进退无颜仪。阿母大拊掌，不图子自归：“十三教汝织，十四能裁衣，十五弹箜篌，十六知礼仪，十七遣汝嫁，谓言无誓违。汝今何罪过，不迎而自归？”兰芝惭阿母：“儿实无罪过。”阿母大悲摧。<br />
　　还家十余日，县令遣媒来。云有第三郎，窈窕世无双。年始十八九，便言多令才。<br />
　　阿母谓阿女：“汝可去应之。”<br />
　　阿女含泪答：“兰芝初还时，府吏见丁宁，结誓不别离。今日违情义，恐此事非奇。自可断来信，徐徐更谓之。”<br />
　　阿母白媒人：“贫贱有此女，始适还家门。不堪吏人妇，岂合令郎君？幸可广问讯，不得便相许。”<br />
　　媒人去数日，寻遣丞请还，说有兰家女，承籍有宦官。云有第五郎，娇逸未有婚。遣丞为媒人，主簿通语言。直说太守家，有此令郎君，既欲结大义，故遣来贵门。<br />
　　阿母谢媒人：“女子先有誓，老姥岂敢言！”<br />
　　阿兄得闻之，怅然心中烦。举言谓阿妹：“作计何不量！先嫁得府吏，后嫁得郎君。否泰如天地，足以荣汝身。不嫁义郎体，其往欲何云？”<br />
　　兰芝仰头答：“理实如兄言。谢家事夫婿，中道还兄门。处分适兄意，那得自任专！虽与府吏要，渠会永无缘。登即相许和，便可作婚姻。”<br />
　　媒人下床去。诺诺复尔尔。还部白府君：“下官奉使命，言谈大有缘。”府君得闻之，心中大欢喜。视历复开书，便利此月内，六合正相应。良吉三十日，今已二十七，卿可去成婚。交语速装束，络绎如浮云。青雀白鹄舫，四角龙子幡。婀娜随风转，金车玉作轮。踯躅青骢马，流苏金镂鞍。赍钱三百万，皆用青丝穿。杂彩三百匹，交广市鲑珍。从人四五百，郁郁登郡门。<br />
　　阿母谓阿女：“适得府君书，明日来迎汝。何不作衣裳？莫令事不举！”<br />
　　阿女默无声，手巾掩口啼，泪落便如泻。移我琉璃榻，出置前窗下。左手持刀尺，右手执绫罗。朝成绣夹裙，晚成单罗衫。晻晻日欲暝，愁思出门啼。<br />
　　府吏闻此变，因求假暂归。未至二三里，摧藏马悲哀。新妇识马声，蹑履相逢迎。怅然遥相望，知是故人来。举手拍马鞍，嗟叹使心伤：“自君别我后，人事不可量。果不如先愿，又非君所详。我有亲父母，逼迫兼弟兄。以我应他人，君还何所望！”<br />
　　府吏谓新妇：“贺卿得高迁！磐石方且厚，可以卒千年；蒲苇一时纫，便作旦夕间。卿当日胜贵，吾独向黄泉！”<br />
　　新妇谓府吏：“何意出此言！同是被逼迫，君尔妾亦然。黄泉下相见，勿违今日言！”执手分道去，各各还家门。生人作死别，恨恨那可论？念与世间辞，千万不复全！<br />
　　府吏还家去，上堂拜阿母：“今日大风寒，寒风摧树木，严霜结庭兰。儿今日冥冥，令母在后单。故作不良计，勿复怨鬼神！命如南山石，四体康且直！”<br />
　　阿母得闻之，零泪应声落：“汝是大家子，仕宦于台阁。慎勿为妇死，贵贱情何薄！东家有贤女，窈窕艳城郭，阿母为汝求，便复在旦夕。”<br />
　　府吏再拜还，长叹空房中，作计乃尔立。转头向户里，渐见愁煎迫。<br />
　　其日牛马嘶，新妇入青庐。奄奄黄昏后，寂寂人定初。我命绝今日，魂去尸长留！揽裙脱丝履，举身赴清池。<br />
　　府吏闻此事，心知长别离。徘徊庭树下，自挂东南枝。<br />
　　两家求合葬，合葬华山傍。东西植松柏，左右种梧桐。枝枝相覆盖，叶叶相交通。中有双飞鸟，自名为鸳鸯。仰头相向鸣，夜夜达五更。行人驻足听，寡妇起彷徨。多谢后世人，戒之慎勿忘。</p>
<p><br/></p>
<hr/>
<p>下面为来自百度百科上的部分精妙评述，引录如下。更多精妙请参考：<a href="http://baike.baidu.com/view/26343.htm?fr=ala0#1">百度百科》孔雀东南飞</a></p>
<p><code>     全诗“共一千七百八十五字，古今第一首长诗也。淋淋漓漓，反反复复，杂述十数人口中语，而各肖其声音面目，岂非化工之笔”（《古诗源》卷四，沈德潜按语）。在贯穿全篇的对话中，可以看到，刘兰芝对仲卿、对焦母、对小姑、对自己的哥哥和母亲讲话时的态度与语气各不相同，正是在这种不同中可以感受到她那勤劳、善良、备受压迫而又富于反抗精神的外柔内刚的个性。同样的，在焦仲卿各种不同场合的话语中，也可以感受到他那忠于爱情、明辨是非但又迫于母亲威逼的诚正而软弱、但又有发展的性格。</p>
<p>     诗中写到兰芝与仲卿死前，兰芝假意同意再嫁，仲卿见兰芝后回家与母亲诀别，他俩这时的话语，非常切合各自的身份与处境。陈祚明《采菽堂古诗选》曾作过这样细致的分析：“兰芝不白母而府吏白母者，女之于母，子之于母，情固不同。女从夫者也，又恐母防之，且母有兄在，可死也。子之与妻，孰与母重？且子死母何依，能无白乎？同死者，情也。彼此不负，女以死偿，安得不以死？彼此时，母即悔而迎女，犹可两俱无死也。然度母终不肯迎女，死终不可以已，故白母之言亦有异者，儿今冥冥四语明言之矣，今日风寒命如山石，又不甚了了，亦恐母觉而防我也。府吏白母而母不防者，女之去久矣。他日不死而今日何为独死？不过谓此怨怼之言，未必实耳。故漫以东家女答之，且用相慰。然府吏白母，不言女将改适，不言女亦欲死，盖度母之性，必不肯改而迎女，而徒露真情，则防我不得死故也。”试想，兰芝如果直说要死，这个弱女子势必会遭到暴力的约束，被强迫成婚。而仲卿的情况自然与兰芝不同，诚如上述引文的分析。又如：“吾意久怀忿，汝岂得自由”、“小子无所畏，何敢助妇语”，于此可立见焦母的蛮横：“作计何不量！先嫁得府吏，后嫁得郎君。否泰如天地，足以荣汝身。不嫁义郎体，其往欲何云？”由此可见刘兄的势利。</p>
<p>     即使次要人物如媒人、府君的简短对话，也各各符合其人的身份、特点。</p>
<p>     诗中，简洁的人物行动刻划，有助于形象的鲜明；精炼的抒情性穿插，增强了行文的情韵。“鸡鸣外欲曙，新妇起严妆。著我绣夹裙，事事四五通”，写出了刘兰芝离开焦家时的矛盾心情。欲曙即起，表示她不愿在焦家生活的决心，严妆辞婆是她对焦母的抗议与示威。打扮时的事事四五通，表示了她对焦仲卿的爱，欲去又不忍遽去的微妙心理。“却与小姑别，泪落连珠子”，姑嫂关系不易相处，兰芝与小姑关系融洽，正表现了她的懂礼仪、易相处。这同焦母的不容恰成对照。另外，辞焦母不落泪，而辞小姑落泪，也可见兰芝的倔强。</p>
<p>     焦仲卿的形象刻划也是如此，他送兰芝到大道口，“下马入车中，低头共耳语”，表现了一片真情。闻知兰芝要成婚，“未至二三里，摧藏马悲哀”，诗篇用马悲渲染衬托他内心的强烈痛苦。临死前“长叹空房中”、“转头向户里”，对母亲还有所顾念，这里愈见他的诚正与善良。</p>
<p>     在整篇诗中，类似上述的动作刻划还有一些，笔墨虽不多，却极精粹。兰芝死时，一无反顾，“揽裙脱丝履，举身赴清池”；仲卿死时，顾念老母，“徘徊庭树下，自挂东南枝”，这些不同的动作细节，都切合各自的性格与处境。同样是母亲，焦母“捶床便大怒”的泼辣，刘母见兰芝回家时惊异而“大拊掌”的温和，对性格的描绘来说寥寥几笔已极传神。抒情性穿插较之动作刻划更少，但也是成功之笔“举手长劳劳，二情同依依”，兰芝和仲卿第一次分手时，作者情不自禁的感叹，增添了悲剧气氛。“生人作死别，恨恨那可论”，这画龙点睛的穿插，更激起了人们对焦、刘遭遇的同情。即使那教训式的全诗结尾，也带有浓重的抒情意味，充满了作者的同情与期望。</code></p>


<p>Related posts:<ol><li><a href='http://blog.xiping.me/2009/11/%e9%92%97%e5%a4%b4%e5%87%a4.html' rel='bookmark' title='Permanent Link: 钗头凤'>钗头凤</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://blog.xiping.me/2009/11/%e5%ad%94%e9%9b%80%e4%b8%9c%e5%8d%97%e9%a3%9e%ef%bc%8c%e4%ba%94%e9%87%8c%e4%b8%80%e5%be%98%e5%be%8a.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>算法解题思考过程[总结]</title>
		<link>http://blog.xiping.me/2009/11/%e7%ae%97%e6%b3%95%e8%a7%a3%e9%a2%98%e6%80%9d%e8%80%83%e8%bf%87%e7%a8%8b.html</link>
		<comments>http://blog.xiping.me/2009/11/%e7%ae%97%e6%b3%95%e8%a7%a3%e9%a2%98%e6%80%9d%e8%80%83%e8%bf%87%e7%a8%8b.html#comments</comments>
		<pubDate>Wed, 04 Nov 2009 14:39:14 +0000</pubDate>
		<dc:creator>西坪</dc:creator>
				<category><![CDATA[$算法与计算原理]]></category>
		<category><![CDATA[algorithm]]></category>
		<category><![CDATA[Fibonacci]]></category>

		<guid isPermaLink="false">http://blog.feihoo.com/archives/58</guid>
		<description><![CDATA[今天又做了个斐波那契数列相关的题目：上台阶，每次可走一台阶和两台阶，问上10个台阶有多少种走法。 （出处：阅微堂. EMC笔试 ， 89种) 。 上次的农夫养牛问题也是个斐波那契问题。
对于斐波那契这一类问题，因为特征过于鲜明，可以一看题目就套上，用的联想的思维方式就解决了。不过如果是在不熟悉此类问题时，首先是根据题目估计可用演绎推理来解决，然后尝试 f(1), f(2), f(3) = f(2)+f(1) 之类的推理。 演绎/推理确实是一项十分重要的解题方法，尤其是在对问题领域不熟悉的时候。
延伸阅读：

刘未鹏：知其所以然地学习（以算法为例）



Related posts:农夫养牛问题



Related posts:<ol><li><a href='http://blog.xiping.me/2009/11/farmer-cow-problem.html' rel='bookmark' title='Permanent Link: 农夫养牛问题'>农夫养牛问题</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>今天又做了个斐波那契数列相关的题目：<span class="Apple-style-span" style="font-family: Verdana,Arial,Helvetica,sans-serif; font-size: 15px; line-height: 23px">上台阶，每次可走一台阶和两台阶，问上10个台阶有多少种走法。 （出处：<a href="http://yueweitang.org/blog/posts/emc-2008-10-writing-test.html">阅微堂. EMC笔试</a> ， 89种) 。 上次的<a href="http://blog.feihoo.com/archives/53" class="broken_link" >农夫养牛问题</a>也是个斐波那契问题。</span></p>
<p>对于斐波那契这一类问题，因为特征过于鲜明，可以一看题目就套上，用的<strong>联想</strong>的思维方式就解决了。不过如果是在不熟悉此类问题时，首先是根据题目估计可用演绎推理来解决，然后尝试 f(1), f(2), f(3) = f(2)+f(1) 之类的推理。 <strong>演绎/推理</strong>确实是一项十分重要的解题方法，尤其是在对问题领域不熟悉的时候。</p>
<p>延伸阅读：</p>
<ol>
<li><a href="http://blog.csdn.net/pongba/archive/2008/07/07/2622713.aspx">刘未鹏：知其所以然地学习（以算法为例）</a></li>
</ol>


<p>Related posts:<ol><li><a href='http://blog.xiping.me/2009/11/farmer-cow-problem.html' rel='bookmark' title='Permanent Link: 农夫养牛问题'>农夫养牛问题</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://blog.xiping.me/2009/11/%e7%ae%97%e6%b3%95%e8%a7%a3%e9%a2%98%e6%80%9d%e8%80%83%e8%bf%87%e7%a8%8b.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>25匹马五条赛道决出前五匹马的最少场次[未解决]</title>
		<link>http://blog.xiping.me/2009/11/25%e5%8c%b9%e9%a9%ac%e4%ba%94%e6%9d%a1%e8%b5%9b%e9%81%93%e5%86%b3%e5%87%ba%e5%89%8d%e4%ba%94%e5%8c%b9%e9%a9%ac%e7%9a%84%e6%9c%80%e5%b0%91%e5%9c%ba%e6%ac%a1%e6%9c%aa%e8%a7%a3%e5%86%b3.html</link>
		<comments>http://blog.xiping.me/2009/11/25%e5%8c%b9%e9%a9%ac%e4%ba%94%e6%9d%a1%e8%b5%9b%e9%81%93%e5%86%b3%e5%87%ba%e5%89%8d%e4%ba%94%e5%8c%b9%e9%a9%ac%e7%9a%84%e6%9c%80%e5%b0%91%e5%9c%ba%e6%ac%a1%e6%9c%aa%e8%a7%a3%e5%86%b3.html#comments</comments>
		<pubDate>Wed, 04 Nov 2009 09:18:38 +0000</pubDate>
		<dc:creator>西坪</dc:creator>
				<category><![CDATA[$算法与计算原理]]></category>
		<category><![CDATA[algorithm]]></category>

		<guid isPermaLink="false">http://blog.feihoo.com/archives/57</guid>
		<description><![CDATA[有关25马问题，目前有很多讨论，但是还没有看到真正解决问题的讨论。
TopLanguage 上我的发言：我的发言是8次，应该是正确的，但是还没有找出数学上的理由。
TopLanguage上一个较早的讨论：这个讨论是相对比较意义的，有人说：
其实这个就是kth smallest element的算法，MIT 的 Introduction to Algorithms 里有详细的分析。

参见：http://videolectures.net/mit6046jf05_demaine_lec06/
还有人说：
这个问题应该是磁盘排序的问题的变种吧    在不能计时的情况下   我觉得n * n 匹马 m 条跑道起码需要  
两个Blog文章：http://fayaa.com/tiku/view/91/  （有篇评论值得研究，说到是8场）
http://blog.solrex.cn/articles/25-horses-problem.html#comment-1738 （我对他的做法做了评论）


Related posts:算法解题思考过程[总结]



Related posts:<ol><li><a href='http://blog.xiping.me/2009/11/%e7%ae%97%e6%b3%95%e8%a7%a3%e9%a2%98%e6%80%9d%e8%80%83%e8%bf%87%e7%a8%8b.html' rel='bookmark' title='Permanent Link: 算法解题思考过程[总结]'>算法解题思考过程[总结]</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>有关25马问题，目前有很多讨论，但是还没有看到真正解决问题的讨论。</p>
<p><a href="http://groups.google.com/group/pongba/browse_thread/thread/7c59e6519919d240/9a97f2c56b02ef09?lnk=gst&amp;q=%E9%A9%AC#9a97f2c56b02ef09">TopLanguage 上我的发言</a>：我的发言是8次，应该是正确的，但是还没有找出数学上的理由。</p>
<p><a href="http://groups.google.com/group/pongba/browse_thread/thread/700ebb5d00e72299/84cf7bea74ff51c4?lnk=raot">TopLanguage上一个较早的讨论</a>：这个讨论是相对比较意义的，有人说：</p>
<blockquote><p><em>其实这个就是kth smallest element的算法，MIT 的 Introduction to Algorithms 里有详细的分析。<br />
</em></p></blockquote>
<blockquote><p><em>参见：<a href="http://videolectures.net/mit6046jf05_demaine_lec06/" target="_blank" rel="nofollow">http://videolectures.net/mit6046jf05_demaine_lec06/</a></em></p></blockquote>
<p>还有人说：</p>
<blockquote><p><em>这个问题应该是磁盘排序的问题的变种吧    在不能计时的情况下   我觉得n * n 匹马 m 条跑道起码需要  </em></p></blockquote>
<p>两个Blog文章：http://fayaa.com/tiku/view/91/  （有篇评论值得研究，说到是8场）</p>
<p>http://blog.solrex.cn/articles/25-horses-problem.html#comment-1738 （我对他的做法做了评论）</p>


<p>Related posts:<ol><li><a href='http://blog.xiping.me/2009/11/%e7%ae%97%e6%b3%95%e8%a7%a3%e9%a2%98%e6%80%9d%e8%80%83%e8%bf%87%e7%a8%8b.html' rel='bookmark' title='Permanent Link: 算法解题思考过程[总结]'>算法解题思考过程[总结]</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://blog.xiping.me/2009/11/25%e5%8c%b9%e9%a9%ac%e4%ba%94%e6%9d%a1%e8%b5%9b%e9%81%93%e5%86%b3%e5%87%ba%e5%89%8d%e4%ba%94%e5%8c%b9%e9%a9%ac%e7%9a%84%e6%9c%80%e5%b0%91%e5%9c%ba%e6%ac%a1%e6%9c%aa%e8%a7%a3%e5%86%b3.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>算法：无序实数列V[N]中大小相邻实数的最大差（线性空间和线性时间）</title>
		<link>http://blog.xiping.me/2009/11/%e7%ae%97%e6%b3%95%ef%bc%9a%e6%97%a0%e5%ba%8f%e5%ae%9e%e6%95%b0%e5%88%97vn%e4%b8%ad%e5%a4%a7%e5%b0%8f%e7%9b%b8%e9%82%bb%e5%ae%9e%e6%95%b0%e7%9a%84%e6%9c%80%e5%a4%a7%e5%b7%ae%e7%ba%bf%ef%bc%88.html</link>
		<comments>http://blog.xiping.me/2009/11/%e7%ae%97%e6%b3%95%ef%bc%9a%e6%97%a0%e5%ba%8f%e5%ae%9e%e6%95%b0%e5%88%97vn%e4%b8%ad%e5%a4%a7%e5%b0%8f%e7%9b%b8%e9%82%bb%e5%ae%9e%e6%95%b0%e7%9a%84%e6%9c%80%e5%a4%a7%e5%b7%ae%e7%ba%bf%ef%bc%88.html#comments</comments>
		<pubDate>Tue, 03 Nov 2009 15:21:51 +0000</pubDate>
		<dc:creator>西坪</dc:creator>
				<category><![CDATA[$算法与计算原理]]></category>
		<category><![CDATA[algorithm]]></category>
		<category><![CDATA[buck-sort]]></category>

		<guid isPermaLink="false">http://blog.feihoo.com/archives/56</guid>
		<description><![CDATA[题： 有无序的实数列V[N]，要求求里面大小相邻的实数的差的最大值，关键是要求线性空间和线性时间
题目来自CSDN论坛里的讨论，很多网友给出了他们的意见。
其实这个问题要求线性时间条件下，通常会让我们想到桶排序；接着关键是考虑怎么减少桶排序中对桶中各数的排序即可想到解决方法。我的算法如下：

主要是先找出最大的数与最小的数，然后构造一个n个桶，桶的下标与数的关系为： index =  (v[i]-min)/(max-min/n).
遍历数列，将数值插入到对应的桶中。每个桶最多保留最小和最大的两个元素，不需要多余的数。
遍历所有的桶，记录每个桶之间有多少个空桶到数据flags中，并求出最大连续空桶数 maxGap。
最后遍历flags数组，对于空桶数 &#62;= maxGap -1 的元素，计算从前面的最近的不为空的桶中的大元素与当前桶中的最小元素的差，最终找出最大差。

主算法：

max,min ← GetMaxAndMin &#40;v&#41;
&#160;
bucks&#91;n&#93;;
&#160;
for i = 0 to n-1
     buckNo ← get buck no:  &#40;v&#91;i&#93;-min&#41; / &#40;max-min/n&#41;  //计算桶下标（如果不为整数，取较小的数的绝对值）
     if buck&#91; buckNo &#93; is empty: insert v&#91;i&#93;
     if buck&#91;buckNo&#93;.length == 1 : [...]


Related posts:<ol><li><a href='http://blog.xiping.me/2009/10/dynamic-programming-problem-1.html' rel='bookmark' title='Permanent Link: 动态规划练习（一）: 求数列中连续数字之和的最大值'>动态规划练习（一）: 求数列中连续数字之和的最大值</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>题： 有无序的实数列V[N]，要求求里面大小相邻的实数的差的最大值，关键是要求线性空间和线性时间</p>
<p>题目来自<a href="http://topic.csdn.net/u/20091024/12/989417AA-60E9-45D1-A96F-A623695FC6D7.html">CSDN论坛里的讨论</a>，很多网友给出了他们的意见。</p>
<p>其实这个问题要求线性时间条件下，通常会让我们想到桶排序；接着关键是考虑怎么减少桶排序中对桶中各数的排序即可想到解决方法。我的算法如下：</p>
<ol>
<li>主要是先找出最大的数与最小的数，然后构造一个n个桶，桶的下标与数的关系为： index =  (v[i]-min)/(max-min/n).</li>
<li>遍历数列，将数值插入到对应的桶中。每个桶最多保留最小和最大的两个元素，不需要多余的数。</li>
<li>遍历所有的桶，记录每个桶之间有多少个空桶到数据flags中，并求出最大连续空桶数 maxGap。</li>
<li>最后遍历flags数组，对于空桶数 &gt;= maxGap -1 的元素，计算从前面的最近的不为空的桶中的大元素与当前桶中的最小元素的差，最终找出最大差。</li>
</ol>
<p>主算法：</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;">max<span style="color: #339933;">,</span>min ← GetMaxAndMin <span style="color: #009900;">&#40;</span>v<span style="color: #009900;">&#41;</span>
&nbsp;
bucks<span style="color: #009900;">&#91;</span>n<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">for</span> i <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span> to n<span style="color: #339933;">-</span><span style="color: #0000dd;">1</span>
     buckNo ← get buck no<span style="color: #339933;">:</span>  <span style="color: #009900;">&#40;</span>v<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #339933;">-</span>min<span style="color: #009900;">&#41;</span> <span style="color: #339933;">/</span> <span style="color: #009900;">&#40;</span>max<span style="color: #339933;">-</span>min<span style="color: #339933;">/</span>n<span style="color: #009900;">&#41;</span>  <span style="color: #666666; font-style: italic;">//计算桶下标（如果不为整数，取较小的数的绝对值）</span>
     <span style="color: #b1b100;">if</span> buck<span style="color: #009900;">&#91;</span> buckNo <span style="color: #009900;">&#93;</span> is empty<span style="color: #339933;">:</span> insert v<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span>
     <span style="color: #b1b100;">if</span> buck<span style="color: #009900;">&#91;</span>buckNo<span style="color: #009900;">&#93;</span>.<span style="color: #202020;">length</span> <span style="color: #339933;">==</span> <span style="color: #0000dd;">1</span> <span style="color: #339933;">:</span> <span style="color: #666666; font-style: italic;">//insert v[i] 与原来的数构成正序关系</span>
     <span style="color: #b1b100;">if</span> buck<span style="color: #009900;">&#91;</span>buckNo<span style="color: #009900;">&#93;</span>.<span style="color: #202020;">length</span> <span style="color: #339933;">==</span> <span style="color: #0000dd;">2</span> <span style="color: #339933;">:</span> <span style="color: #666666; font-style: italic;">//与原来的2元素按正序关系排列，去掉中间的数，仍然是2个元素</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// 标记每个不为空的桶元素之前有多少个空桶</span>
flags<span style="color: #009900;">&#91;</span>n<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">//记录每个桶之前的空桶数目</span>
maxgaps <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
tempgaps <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">for</span> i ← FindFirstNotEmptyBuck <span style="color: #009900;">&#40;</span>bucks<span style="color: #009900;">&#41;</span> to n<span style="color: #339933;">-</span><span style="color: #0000dd;">1</span>
         <span style="color: #b1b100;">if</span> buck<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span> is empty then
              tempgaps <span style="color: #339933;">++</span>
         <span style="color: #b1b100;">else</span>
             flags<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span> ← tempgaps<span style="color: #339933;">;</span>
             maxgaps ← GetMax <span style="color: #009900;">&#40;</span>tempgaps<span style="color: #339933;">,</span> maxgaps<span style="color: #009900;">&#41;</span>
             tempgaps <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
<span style="color: #666666; font-style: italic;">// 计算最大的相邻的最大值</span>
maxNeighbor <span style="color: #339933;">==</span> <span style="color: #000000; font-weight: bold;">null</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">for</span> i ← <span style="color: #0000dd;">0</span> to n<span style="color: #339933;">-</span><span style="color: #0000dd;">1</span>
    <span style="color: #b1b100;">if</span> maxgaps <span style="color: #339933;">-</span> flag<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span> <span style="color: #339933;">&amp;</span>lt<span style="color: #339933;">;</span> <span style="color: #0000dd;">2</span> then
       maxNeighbor ← GetMax<span style="color: #009900;">&#40;</span>COMPUTE_MAX<span style="color: #009900;">&#40;</span>bucks<span style="color: #339933;">,</span>i<span style="color: #339933;">,</span>flag<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> maxNeighbor<span style="color: #009900;">&#41;</span>
<span style="color: #b1b100;">return</span> maxNeighbor</pre></div></div>


<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;">COMPUTE_MAX<span style="color: #009900;">&#40;</span>bucks<span style="color: #339933;">,</span>i<span style="color: #339933;">,</span>gap<span style="color: #009900;">&#41;</span> <span style="color: #339933;">:</span>
    <span style="color: #666666; font-style: italic;">//常数级别，取头或取尾</span>
    <span style="color: #b1b100;">return</span> GetMinEle<span style="color: #009900;">&#40;</span>bucks<span style="color: #339933;">,</span> i<span style="color: #009900;">&#41;</span> <span style="color: #339933;">-</span> getMaxEle<span style="color: #009900;">&#40;</span>bucks<span style="color: #339933;">,</span> i <span style="color: #339933;">-</span> gap <span style="color: #339933;">-</span><span style="color: #0000dd;">1</span><span style="color: #009900;">&#41;</span>
<span style="color: #339933;">&lt;</span>pre lang<span style="color: #339933;">=</span><span style="color: #ff0000;">&quot;c&quot;</span><span style="color: #339933;">&gt;</span>GetMaxAndMin <span style="color: #009900;">&#40;</span>v<span style="color: #009900;">&#41;</span><span style="color: #339933;">:</span>
max<span style="color: #339933;">,</span> min<span style="color: #339933;">,</span> i
n ← v.<span style="color: #202020;">length</span>
<span style="color: #b1b100;">if</span> n<span style="color: #339933;">%</span><span style="color:#800080;">2</span> <span style="color: #339933;">==</span> <span style="color: #0000dd;">0</span> then
     <span style="color: #b1b100;">if</span> V<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">1</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">&amp;</span>gt<span style="color: #339933;">;</span> V<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">0</span><span style="color: #009900;">&#93;</span> then
          max ← V<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span> min ← V<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
     <span style="color: #b1b100;">else</span>
          max ← V<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span> min ← V<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
     i <span style="color: #339933;">=</span> <span style="color: #0000dd;">2</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">else</span>
     max <span style="color: #339933;">=</span> min <span style="color: #339933;">=</span> V<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
     i <span style="color: #339933;">=</span> <span style="color: #0000dd;">1</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">for</span> i to n<span style="color: #339933;">-</span><span style="color: #0000dd;">2</span>
    <span style="color: #b1b100;">if</span> v<span style="color: #009900;">&#91;</span>i<span style="color: #339933;">+</span><span style="color: #0000dd;">1</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">&amp;</span>gt<span style="color: #339933;">;</span> v<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span> then
        min ←GetMin<span style="color: #009900;">&#40;</span>min<span style="color: #339933;">,</span> v<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        max ← GetMax<span style="color: #009900;">&#40;</span>max<span style="color: #339933;">,</span> v<span style="color: #009900;">&#91;</span>i<span style="color: #339933;">+</span><span style="color: #0000dd;">1</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span>
   <span style="color: #b1b100;">else</span>
        min ←GetMin<span style="color: #009900;">&#40;</span>min<span style="color: #339933;">,</span> v<span style="color: #009900;">&#91;</span>i<span style="color: #339933;">+</span><span style="color: #0000dd;">1</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        max ← GetMax<span style="color: #009900;">&#40;</span>max<span style="color: #339933;">,</span> v<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span>
   i<span style="color: #339933;">++;</span> <span style="color: #666666; font-style: italic;">//每次取两个数</span>
&nbsp;
<span style="color: #b1b100;">return</span> <span style="color: #009900;">&#40;</span>max<span style="color: #339933;">,</span>min<span style="color: #009900;">&#41;</span></pre></div></div>


<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;">FindFirstNotEmptyBuck <span style="color: #009900;">&#40;</span>bucks<span style="color: #009900;">&#41;</span>
<span style="color: #b1b100;">for</span> i ← <span style="color: #0000dd;">0</span> to n<span style="color: #339933;">-</span><span style="color: #0000dd;">1</span>
     <span style="color: #b1b100;">if</span> tempgapstart <span style="color: #339933;">==</span> <span style="color: #339933;">-</span><span style="color: #0000dd;">1</span> then
         <span style="color: #b1b100;">if</span> buck<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span> is empty then
             <span style="color: #000000; font-weight: bold;">break</span>
         <span style="color: #b1b100;">else</span>
              <span style="color: #b1b100;">continue</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">return</span> i<span style="color: #339933;">;</span></pre></div></div>

</pre>


<p>Related posts:<ol><li><a href='http://blog.xiping.me/2009/10/dynamic-programming-problem-1.html' rel='bookmark' title='Permanent Link: 动态规划练习（一）: 求数列中连续数字之和的最大值'>动态规划练习（一）: 求数列中连续数字之和的最大值</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://blog.xiping.me/2009/11/%e7%ae%97%e6%b3%95%ef%bc%9a%e6%97%a0%e5%ba%8f%e5%ae%9e%e6%95%b0%e5%88%97vn%e4%b8%ad%e5%a4%a7%e5%b0%8f%e7%9b%b8%e9%82%bb%e5%ae%9e%e6%95%b0%e7%9a%84%e6%9c%80%e5%a4%a7%e5%b7%ae%e7%ba%bf%ef%bc%88.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>农夫养牛问题</title>
		<link>http://blog.xiping.me/2009/11/farmer-cow-problem.html</link>
		<comments>http://blog.xiping.me/2009/11/farmer-cow-problem.html#comments</comments>
		<pubDate>Sun, 01 Nov 2009 11:02:08 +0000</pubDate>
		<dc:creator>西坪</dc:creator>
				<category><![CDATA[$算法与计算原理]]></category>
		<category><![CDATA[algorithm]]></category>
		<category><![CDATA[Fibonacci]]></category>

		<guid isPermaLink="false">http://blog.feihoo.com/archives/53</guid>
		<description><![CDATA[算法题来自 CSDN ：http://topic.csdn.net/u/20091001/15/40BF4993-8ED7-45CC-968F-97C524DAE3C4.html
问题： 一个农夫养了一头牛，三年后，这头牛每年会生出1头牛，生出来的牛三年后，又可以每年生出一头牛……问农夫10年后有多少头牛?n年呢？
这个问题的数学模型是类似于斐波那契（Fibonacci）数列，其计算式为：
F(n) = 1 , n&#60;3
或
F(n) = F(n-3) + F(n-1) , n &#62;=3
十年后是28头牛。实现算法时该贴提到了两种实现方式，一种是用过程的方法实现该数列，另一种是面向对象的方法实现。第二种方法确实更好一些，但是原帖实现似乎并不理想。


Related posts:算法解题思考过程[总结]



Related posts:<ol><li><a href='http://blog.xiping.me/2009/11/%e7%ae%97%e6%b3%95%e8%a7%a3%e9%a2%98%e6%80%9d%e8%80%83%e8%bf%87%e7%a8%8b.html' rel='bookmark' title='Permanent Link: 算法解题思考过程[总结]'>算法解题思考过程[总结]</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>算法题来自 CSDN ：http://topic.csdn.net/u/20091001/15/40BF4993-8ED7-45CC-968F-97C524DAE3C4.html</p>
<p>问题： 一个农夫养了一头牛，三年后，这头牛每年会生出1头牛，生出来的牛三年后，又可以每年生出一头牛……问农夫10年后有多少头牛?n年呢？</p>
<p>这个问题的数学模型是类似于斐波那契（Fibonacci）数列，其计算式为：</p>
<p>F(n) = 1 , n&lt;3</p>
<p>或</p>
<p>F(n) = F(n-3) + F(n-1) , n &gt;=3</p>
<p>十年后是28头牛。实现算法时该贴提到了两种实现方式，一种是用过程的方法实现该数列，另一种是面向对象的方法实现。第二种方法确实更好一些，但是原帖实现似乎并不理想。</p>


<p>Related posts:<ol><li><a href='http://blog.xiping.me/2009/11/%e7%ae%97%e6%b3%95%e8%a7%a3%e9%a2%98%e6%80%9d%e8%80%83%e8%bf%87%e7%a8%8b.html' rel='bookmark' title='Permanent Link: 算法解题思考过程[总结]'>算法解题思考过程[总结]</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://blog.xiping.me/2009/11/farmer-cow-problem.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>阿里巴巴收购万网与Vmware收购SpringSource: 布局云计算</title>
		<link>http://blog.xiping.me/2009/11/%e9%98%bf%e9%87%8c%e5%b7%b4%e5%b7%b4%e6%94%b6%e8%b4%ad%e4%b8%87%e7%bd%91%e4%b8%8evmware%e6%94%b6%e8%b4%adspringsource-%e5%b8%83%e5%b1%80%e4%ba%91%e8%ae%a1%e7%ae%97.html</link>
		<comments>http://blog.xiping.me/2009/11/%e9%98%bf%e9%87%8c%e5%b7%b4%e5%b7%b4%e6%94%b6%e8%b4%ad%e4%b8%87%e7%bd%91%e4%b8%8evmware%e6%94%b6%e8%b4%adspringsource-%e5%b8%83%e5%b1%80%e4%ba%91%e8%ae%a1%e7%ae%97.html#comments</comments>
		<pubDate>Sun, 01 Nov 2009 07:29:25 +0000</pubDate>
		<dc:creator>西坪</dc:creator>
				<category><![CDATA[$IT Thoughts]]></category>

		<guid isPermaLink="false">http://blog.feihoo.com/archives/52</guid>
		<description><![CDATA[2009年8月，Vmware 收购了 SpringSource，详情请看这里。
2009年9月28日，阿里巴巴收购了万网。
这两则消息的背后的秘密，不言而喻，都是为了布局云计算，没有其他秘密。
SpringSource是一家从事企业应用服务基础技术服务的公司，其 Spring Framework 在全世界Java EE应用中举足轻重,其 Spring DM Server 是一款模块化Java EE应用服务器。Vmware的这笔收购，目的是为了整合SpringSource 在企业服务方面的资源，结合自己在 IAAS方面的优势，组建PAAS云计算服务平台。
万网是中国内地一家领先的互联网应用服务提供商，在主机服务、域名服务方面具有强大优势。其在互联网基础设施方面的市场和技术实力都是阿里巴巴布局云计算所急需的。 阿里巴巴在2009年9月9日刚刚宣布成立一家新的子公司——阿里巴巴云计算子公司。阿里巴巴在云计算方面的工作开始正式启航。阿里巴巴是迄今为止中国内地第一家真正进入云计算行业的公司。


No related posts.


No related posts.]]></description>
			<content:encoded><![CDATA[<p>2009年8月，<a href="http://www.vmware.com">Vmware</a> 收购了 <a href="http://www.springsource.com">SpringSource</a>，详情请看<a href="http://www.theserverside.com/news/thread.tss?thread_id=55430">这里</a>。</p>
<p>2009年9月28日，<a href="http://tech.163.com/09/0928/18/5KAM6G5V000915BF.html">阿里巴巴收购了万网</a>。</p>
<p>这两则消息的背后的秘密，不言而喻，都是为了布局云计算，没有其他秘密。</p>
<p>SpringSource是一家从事企业应用服务基础技术服务的公司，其 <a href="http://www.springframework.org">Spring Framework</a> 在全世界Java EE应用中举足轻重,其 <a href="http://www.springsource.org/dmserver">Spring DM Server</a> 是一款模块化Java EE应用服务器。Vmware的这笔收购，目的是为了整合SpringSource 在企业服务方面的资源，结合自己在 IAAS方面的优势，组建PAAS云计算服务平台。</p>
<p><a href="http://www.net.cn" title="www.net.cn">万网</a>是中国内地一家领先的互联网应用服务提供商，在主机服务、域名服务方面具有强大优势。其在互联网基础设施方面的市场和技术实力都是<a href="http://www.alibaba.com/">阿里巴巴</a>布局云计算所急需的。 阿里巴巴在<a href="http://tech.qq.com/a/20090910/000278.htm">2009年9月9日刚刚宣布成立一家新的子公司</a>——<a href="http://www.alibabalabs.com/" class="broken_link" >阿里巴巴云计算子公司</a>。阿里巴巴在云计算方面的工作开始正式启航。阿里巴巴是迄今为止中国内地第一家真正进入云计算行业的公司。</p>


<p>No related posts.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.xiping.me/2009/11/%e9%98%bf%e9%87%8c%e5%b7%b4%e5%b7%b4%e6%94%b6%e8%b4%ad%e4%b8%87%e7%bd%91%e4%b8%8evmware%e6%94%b6%e8%b4%adspringsource-%e5%b8%83%e5%b1%80%e4%ba%91%e8%ae%a1%e7%ae%97.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Maybe Another Choice for QQ?</title>
		<link>http://blog.xiping.me/2009/10/maybe-another-choice-for-qq.html</link>
		<comments>http://blog.xiping.me/2009/10/maybe-another-choice-for-qq.html#comments</comments>
		<pubDate>Tue, 27 Oct 2009 16:43:07 +0000</pubDate>
		<dc:creator>西坪</dc:creator>
				<category><![CDATA[$IT Thoughts]]></category>

		<guid isPermaLink="false">http://blog.feihoo.com/archives/50</guid>
		<description><![CDATA[QQ is the only choice to communicate with friends for most Chinese. And now, it&#8217;s a cash cow for Tencent Inc. They control everything, ask your money all the time. Some money for service is reasonable, but they even demand your money when you want more privacy. For an example, when you want to remove [...]


Related posts:<ol><li><a href='http://blog.xiping.me/2008/10/%e5%9c%a8-vista-%e4%b8%8a%e5%ae%89%e8%a3%85-apache-22-php-526.html' rel='bookmark' title='Permanent Link: 在 Vista 上安装 Apache 2.2, PHP 5.2.6'>在 Vista 上安装 Apache 2.2, PHP 5.2.6</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>QQ is the only choice to communicate with friends for most Chinese. And now, it&#8217;s a cash cow for Tencent Inc. They control everything, ask your money all the time. Some money for service is reasonable, but they even demand your money when you want more privacy. For an example, when you want to remove which blog you have visited, you must become their paid user.</p>
<p>How to build another simple, strong, easy to control by user himself/herself, no money-accquired function and cheap system to give another choice? As my imagine,</p>
<p>1st, <strong>Openness</strong>. Everyone can build new function for himself and who likes the function. Users  build the system by themselves.<br />
2nd, <strong>Users make decision</strong>. Everything is controlled by the users community. Even if whether the project should continue or stop.<br />
3rd, <strong>No business goal</strong>. The main system may supported by users&#8217; denotation.<br />
4th, <strong>Distributed and reliable</strong>. Maybe it would like tor, eMule? Most computation is executed on the volunteers&#8217; machine. The center server may serve a index.<br />
5th, <strong>Secured and spam-free</strong>.</p>
<p>To build that system, the road map may like below:</p>
<p>1st, a few architects build the start-up system and open it to more developers.<br />
2nd, many volunteers compose of a support community, and it broadcast by itself.</p>
<p>It must be the source that everything is controlled by users, made by users.</p>


<p>Related posts:<ol><li><a href='http://blog.xiping.me/2008/10/%e5%9c%a8-vista-%e4%b8%8a%e5%ae%89%e8%a3%85-apache-22-php-526.html' rel='bookmark' title='Permanent Link: 在 Vista 上安装 Apache 2.2, PHP 5.2.6'>在 Vista 上安装 Apache 2.2, PHP 5.2.6</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://blog.xiping.me/2009/10/maybe-another-choice-for-qq.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>动态规划练习（一）: 求数列中连续数字之和的最大值</title>
		<link>http://blog.xiping.me/2009/10/dynamic-programming-problem-1.html</link>
		<comments>http://blog.xiping.me/2009/10/dynamic-programming-problem-1.html#comments</comments>
		<pubDate>Fri, 23 Oct 2009 13:36:46 +0000</pubDate>
		<dc:creator>西坪</dc:creator>
				<category><![CDATA[$算法与计算原理]]></category>
		<category><![CDATA[algorithm]]></category>
		<category><![CDATA[dynamic programming]]></category>

		<guid isPermaLink="false">http://blog.feihoo.com/?p=273</guid>
		<description><![CDATA[问题：
给你n个数a[1], a[2], &#8230;, a[n]，(0


No related posts.]]></description>
			<content:encoded><![CDATA[<p>问题：</p>
<blockquote><p>给你n个数a[1], a[2], &#8230;, a[n]，(0<n<=16,000, -1,000<=a[i]<=1,000)和0<L1<=L2<=n 求长度在[L1,L2]的连续若干个数a[i], a[i+1], ..., a[j], (即L1<=j+1-i<=L2) 使得a[i]+a[i+1]+...+a[j]取到最大值, 你只需要输出那个最大值即可<sub>[<a href="#ref1">1</a>]</sub>。</p></blockquote>
<p>这个题目看上去与动态规划很类似，在于其解的特点。设数列的前 n 个数的最大值为 F(n)，则：</p>
<p><img src="http://blog.feihoo.com/wp-content/uploads/2009/11/dp_num_seqs1.gif" alt="dp_num_seqs_larger" title="dp_num_seqs_larger" width="596" height="60" class="alignnone size-full wp-image-286" /></p>
<p>证明从略。</p>
<p>代码如下：</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">package</span> <span style="color: #006699;">com.feihoo.test</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> MaxSequenceValue <span style="color: #009900;">&#123;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000066; font-weight: bold;">int</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> nums <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span> <span style="color: #cc66cc;">2</span>, <span style="color: #cc66cc;">4</span>, <span style="color: #339933;">-</span><span style="color: #cc66cc;">3</span>, <span style="color: #cc66cc;">9</span>, <span style="color: #cc66cc;">30</span>, <span style="color: #339933;">-</span><span style="color: #cc66cc;">30</span>, <span style="color: #cc66cc;">20</span>, <span style="color: #cc66cc;">0</span>, <span style="color: #cc66cc;">34</span>, <span style="color: #339933;">-</span><span style="color: #cc66cc;">2</span>, <span style="color: #339933;">-</span><span style="color: #cc66cc;">45</span>, <span style="color: #cc66cc;">12</span>, <span style="color: #339933;">-</span><span style="color: #cc66cc;">8</span>, <span style="color: #cc66cc;">11</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000066; font-weight: bold;">void</span> main<span style="color: #009900;">&#40;</span><span style="color: #003399;">String</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> args<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000066; font-weight: bold;">int</span> minLen <span style="color: #339933;">=</span> <span style="color: #cc66cc;">2</span><span style="color: #339933;">;</span>
		<span style="color: #000066; font-weight: bold;">int</span> maxLen <span style="color: #339933;">=</span> <span style="color: #cc66cc;">4</span><span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #000066; font-weight: bold;">int</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> m <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #000066; font-weight: bold;">int</span><span style="color: #009900;">&#91;</span>nums.<span style="color: #006633;">length</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
		m<span style="color: #009900;">&#91;</span>minLen <span style="color: #339933;">-</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #000000; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">int</span> i <span style="color: #339933;">=</span> minLen<span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> nums.<span style="color: #006633;">length</span><span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span>
			compute<span style="color: #009900;">&#40;</span>i, m, minLen, maxLen<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #000066; font-weight: bold;">int</span> largest <span style="color: #339933;">=</span> m<span style="color: #009900;">&#91;</span>minLen<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
		<span style="color: #000000; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">int</span> i <span style="color: #339933;">=</span> minLen <span style="color: #339933;">+</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> nums.<span style="color: #006633;">length</span><span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span>
			<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>largest <span style="color: #339933;">&lt;</span> m<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span>
				largest <span style="color: #339933;">=</span> m<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #003399;">System</span>.<span style="color: #006633;">out</span>.<span style="color: #006633;">println</span><span style="color: #009900;">&#40;</span>largest<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000066; font-weight: bold;">void</span> compute<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">int</span> n, <span style="color: #000066; font-weight: bold;">int</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> m, <span style="color: #000066; font-weight: bold;">int</span> minLen, <span style="color: #000066; font-weight: bold;">int</span> maxLen<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		m<span style="color: #009900;">&#91;</span>n<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> m<span style="color: #009900;">&#91;</span>n <span style="color: #339933;">-</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
		<span style="color: #000000; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">int</span> len <span style="color: #339933;">=</span> minLen<span style="color: #339933;">;</span> len <span style="color: #339933;">&lt;</span> maxLen <span style="color: #339933;">&amp;&amp;</span> n <span style="color: #339933;">-</span> len <span style="color: #339933;">&gt;=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span> len<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			<span style="color: #000066; font-weight: bold;">int</span> re <span style="color: #339933;">=</span> nums<span style="color: #009900;">&#91;</span>n<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
			<span style="color: #000000; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">int</span> i <span style="color: #339933;">=</span> n <span style="color: #339933;">-</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&gt;</span> n <span style="color: #339933;">-</span> len<span style="color: #339933;">;</span> i<span style="color: #339933;">--</span><span style="color: #009900;">&#41;</span>
				re <span style="color: #339933;">+=</span> nums<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
			<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>m<span style="color: #009900;">&#91;</span>n<span style="color: #009900;">&#93;</span> <span style="color: #339933;">&lt;</span> re<span style="color: #009900;">&#41;</span>
				m<span style="color: #009900;">&#91;</span>n<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> re<span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
	<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>参考：<br />
<a name="ref1"></a><br />
1. 来源： <a href="http://blog.pfan.cn/argol/16648.html">动态规划习题 </a></p>


<p>No related posts.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.xiping.me/2009/10/dynamic-programming-problem-1.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>理解Java虚拟机的加法运算</title>
		<link>http://blog.xiping.me/2009/10/understand_java_additon.html</link>
		<comments>http://blog.xiping.me/2009/10/understand_java_additon.html#comments</comments>
		<pubDate>Fri, 16 Oct 2009 10:22:12 +0000</pubDate>
		<dc:creator>西坪</dc:creator>
				<category><![CDATA[$Programming]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[JVM]]></category>

		<guid isPermaLink="false">http://blog.feihoo.com/?p=348</guid>
		<description><![CDATA[在CSDN博客诗剑书生的专栏，作者提到了short类型的+操作和++操作的区别，竟然没有一个正确答案。其实这个问题没那么复杂，关键是要了解Java计算的最小单位和理解类型的自动转型。
原问题是：
short tmp = 0;
为什么tmp = tmp +1;错误但 tmp ++;却正确.
理解这个问题，先要理解实现计算的基本原理。Java虚拟机是一种进程虚拟机，它负责解释和执行字节码，跟直接运行在硬件上运行汇编指令是有区别的。普通的机器语言可以直接操作寄存器完成计算，寄存器能够表示的最小单位是字节。而Java的计算是基于栈的，并规定其基本操作单位是一个字。字的实际大小是有虚拟机的设计者来决定的，虚拟机规范只是规定一个字长要能够放下一个 byte、short、 int、 char、float等类型。所以byte、short、char的运算都像 int 一样是在以字为单位来计算的，尽管它本身比字还要小。
此时我们不难理解，tmp+1会得到一个int。根据Java的类型语义，可以向上转型，不会自动向下转型。所以 tmp = tmp+1语法错误， 关键在 = 符号这里。那为什么 tmp++就是正确的呢？ 因为++ 只有一个操作数，不涉及转型的问题， 不像 = 符号。简单比对下二者生成的字节码。

	short a = 2;
	a++;

生成的字节码如下，其中的第5行指令执行了自动转型，i2s指定是int类型的数据转换为short类型的数据。

  0:   iconst_2
  1:   istore_1
  2:   iload_1
  3:   iconst_1
  4:   iadd
  [...]


No related posts.]]></description>
			<content:encoded><![CDATA[<p>在CSDN博客<a href="http://blog.csdn.net/axman">诗剑书生的专栏</a>，作者提到了<a href="http://blog.csdn.net/axman/archive/2007/03/23/1538300.aspx">short类型的+操作和++操作的区别，竟然没有一个正确答案</a>。其实这个问题没那么复杂，关键是要了解Java计算的最小单位和理解类型的自动转型。<br />
原问题是：</p>
<blockquote><p>short tmp = 0;<br />
为什么tmp = tmp +1;错误但 tmp ++;却正确.</p></blockquote>
<p>理解这个问题，先要理解实现计算的基本原理。Java虚拟机是一种进程虚拟机，它负责解释和执行字节码，跟直接运行在硬件上运行汇编指令是有区别的。普通的机器语言可以直接操作寄存器完成计算，寄存器能够表示的最小单位是字节。而Java的计算是基于栈的，并规定其基本操作单位是一个字。字的实际大小是有虚拟机的设计者来决定的，虚拟机规范只是规定一个字长要能够放下一个 byte、short、 int、 char、float等类型。所以byte、short、char的运算都像 int 一样是在以字为单位来计算的，尽管它本身比字还要小。</p>
<p>此时我们不难理解，tmp+1会得到一个int。根据Java的类型语义，可以向上转型，不会自动向下转型。所以 tmp = tmp+1语法错误， 关键在 = 符号这里。那为什么 tmp++就是正确的呢？ 因为++ 只有一个操作数，不涉及转型的问题， 不像 = 符号。简单比对下二者生成的字节码。</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">	<span style="color: #000066; font-weight: bold;">short</span> a <span style="color: #339933;">=</span> <span style="color: #cc66cc;">2</span><span style="color: #339933;">;</span>
	a<span style="color: #339933;">++;</span></pre></div></div>

<p>生成的字节码如下，其中的第5行指令执行了自动转型，i2s指定是int类型的数据转换为short类型的数据。</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">  <span style="color: #cc66cc;">0</span><span style="color: #339933;">:</span>   iconst_2
  <span style="color: #cc66cc;">1</span><span style="color: #339933;">:</span>   istore_1
  <span style="color: #cc66cc;">2</span><span style="color: #339933;">:</span>   iload_1
  <span style="color: #cc66cc;">3</span><span style="color: #339933;">:</span>   iconst_1
  <span style="color: #cc66cc;">4</span><span style="color: #339933;">:</span>   iadd
  <span style="color: #cc66cc;">5</span><span style="color: #339933;">:</span>   i2s
  <span style="color: #cc66cc;">6</span><span style="color: #339933;">:</span>   istore_1
  <span style="color: #cc66cc;">7</span><span style="color: #339933;">:</span>   <span style="color: #000000; font-weight: bold;">return</span></pre></div></div>

<p>我们在看看 int c = a+b 生成的字节码：</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">	<span style="color: #000066; font-weight: bold;">short</span> a <span style="color: #339933;">=</span> <span style="color: #cc66cc;">2</span><span style="color: #339933;">;</span>
	<span style="color: #000066; font-weight: bold;">short</span> b <span style="color: #339933;">=</span> <span style="color: #cc66cc;">111</span><span style="color: #339933;">;</span>
	<span style="color: #000066; font-weight: bold;">int</span> c <span style="color: #339933;">=</span> a <span style="color: #339933;">+</span> b<span style="color: #339933;">;</span></pre></div></div>

<p>生成字节码如下：</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">   <span style="color: #cc66cc;">0</span><span style="color: #339933;">:</span>   iconst_2
   <span style="color: #cc66cc;">1</span><span style="color: #339933;">:</span>   istore_1
   <span style="color: #cc66cc;">2</span><span style="color: #339933;">:</span>   bipush  <span style="color: #cc66cc;">111</span> #压栈<span style="color: #cc66cc;">111</span>
   <span style="color: #cc66cc;">4</span><span style="color: #339933;">:</span>   istore_2
   <span style="color: #cc66cc;">5</span><span style="color: #339933;">:</span>   iload_1  #加载a到栈
   <span style="color: #cc66cc;">6</span><span style="color: #339933;">:</span>   iload_2  #加载b到栈
   <span style="color: #cc66cc;">7</span><span style="color: #339933;">:</span>   iadd  
   <span style="color: #cc66cc;">8</span><span style="color: #339933;">:</span>   istore_3  #将计算结果存到局部变量c中
   <span style="color: #cc66cc;">9</span><span style="color: #339933;">:</span>   <span style="color: #000000; font-weight: bold;">return</span></pre></div></div>

<p>该文中提到的另一个错误：</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000066; font-weight: bold;">short</span> c <span style="color: #339933;">=</span> a <span style="color: #339933;">+</span> b</pre></div></div>

<p>其实是一个原理，尽管a,b,c 都是short， 但是 a+b 实际上得到了是int， 于是不能自动转型为 short 给 c。</p>


<p>No related posts.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.xiping.me/2009/10/understand_java_additon.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>细节背后：为什么线程协作之前必须先获得锁?</title>
		<link>http://blog.xiping.me/2009/10/%e7%bb%86%e8%8a%82%e8%83%8c%e5%90%8e%ef%bc%9a%e4%b8%ba%e4%bb%80%e4%b9%88%e7%ba%bf%e7%a8%8b%e5%8d%8f%e4%bd%9c%e4%b9%8b%e5%89%8d%e5%bf%85%e9%a1%bb%e5%85%88%e8%8e%b7%e5%be%97%e9%94%81.html</link>
		<comments>http://blog.xiping.me/2009/10/%e7%bb%86%e8%8a%82%e8%83%8c%e5%90%8e%ef%bc%9a%e4%b8%ba%e4%bb%80%e4%b9%88%e7%ba%bf%e7%a8%8b%e5%8d%8f%e4%bd%9c%e4%b9%8b%e5%89%8d%e5%bf%85%e9%a1%bb%e5%85%88%e8%8e%b7%e5%be%97%e9%94%81.html#comments</comments>
		<pubDate>Sat, 03 Oct 2009 08:24:17 +0000</pubDate>
		<dc:creator>西坪</dc:creator>
				<category><![CDATA[$Programming]]></category>
		<category><![CDATA[concurrency]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[lock]]></category>

		<guid isPermaLink="false">http://blog.feihoo.com/?p=204</guid>
		<description><![CDATA[为什么Object.wait()/notify()/notifyAll() 之前必须获得锁？ 这是JLS的规定。Wait-notify机制是围绕监控器锁进行的，获得锁是很自然的前提，自身没有拿到锁之前，怎么能够尝试去操作靠锁来调控的线程呢？不过今天偶尔有时间，就看下Sun Hotspot是怎么实现这一机制的。
当我们执行下面的代码时，线程会抛出异常java.lang.IllegalMonitorStateException: current thread not owner。

public class WaitNotifyCompilerCode &#123;
	private String aString = &#34;Hello World!&#34;;
&#160;
	public static void main&#40;String&#91;&#93; args&#41; &#123;
		System.out.println&#40;&#34;Execute start ....&#34;&#41;;
		final WaitNotifyCompilerCode w = new WaitNotifyCompilerCode&#40;&#41;;
		w.wait1SecAndPrintString&#40;&#41;;
		System.out.println&#40;&#34;Execute end ....&#34;&#41;;
	&#125;
&#160;
	public void wait1SecAndPrintString&#40;&#41; &#123;
		try &#123;
			this.wait&#40;1000&#41;;
		&#125; catch &#40;InterruptedException e&#41; &#123;
			e.printStackTrace&#40;&#41;;
		&#125;
		System.out.println&#40;aString&#41;;
	&#125;
&#160;
&#125;

异常栈的信息如下：

Exception in thread &#34;main&#34; java.lang.IllegalMonitorStateException: current thread not owner
	at java.lang.Object.wait&#40;Native Method&#41;
	at com.feihoo.test.waitnotify.WaitNotifyCompilerCode.wait1SecAndPrintString&#40;WaitNotifyCompilerCode.java:35&#41;
	at com.feihoo.test.waitnotify.WaitNotifyCompilerCode.main&#40;WaitNotifyCompilerCode.java:27&#41;

深入查看 OpenJDK的源码，找到 Object.wait() 函数本地代码：

JVM_ENTRY&#40;void, JVM_MonitorWait&#40;JNIEnv* env, [...]


Related posts:<ol><li><a href='http://blog.xiping.me/2009/10/dynamic-programming-problem-1.html' rel='bookmark' title='Permanent Link: 动态规划练习（一）: 求数列中连续数字之和的最大值'>动态规划练习（一）: 求数列中连续数字之和的最大值</a></li>
<li><a href='http://blog.xiping.me/2010/12/java-volatile-is-not-so-evil.html' rel='bookmark' title='Permanent Link: Java中的Volatile关键字'>Java中的Volatile关键字</a></li>
<li><a href='http://blog.xiping.me/2010/01/file-lock-and-jvm-mutex.html' rel='bookmark' title='Permanent Link: 文件锁与进程互斥'>文件锁与进程互斥</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>为什么Object.wait()/notify()/notifyAll() 之前必须获得锁？ 这是JLS的规定。Wait-notify机制是围绕监控器锁进行的，获得锁是很自然的前提，自身没有拿到锁之前，怎么能够尝试去操作靠锁来调控的线程呢？不过今天偶尔有时间，就看下Sun Hotspot是怎么实现这一机制的。</p>
<p>当我们执行下面的代码时，线程会抛出异常java.lang.IllegalMonitorStateException: current thread not owner。</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> WaitNotifyCompilerCode <span style="color: #009900;">&#123;</span>
	<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #003399;">String</span> aString <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;Hello World!&quot;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000066; font-weight: bold;">void</span> main<span style="color: #009900;">&#40;</span><span style="color: #003399;">String</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> args<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #003399;">System</span>.<span style="color: #006633;">out</span>.<span style="color: #006633;">println</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Execute start ....&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #000000; font-weight: bold;">final</span> WaitNotifyCompilerCode w <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> WaitNotifyCompilerCode<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		w.<span style="color: #006633;">wait1SecAndPrintString</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #003399;">System</span>.<span style="color: #006633;">out</span>.<span style="color: #006633;">println</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Execute end ....&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> wait1SecAndPrintString<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000000; font-weight: bold;">try</span> <span style="color: #009900;">&#123;</span>
			<span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">wait</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">1000</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">catch</span> <span style="color: #009900;">&#40;</span><span style="color: #003399;">InterruptedException</span> e<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			e.<span style="color: #006633;">printStackTrace</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
		<span style="color: #003399;">System</span>.<span style="color: #006633;">out</span>.<span style="color: #006633;">println</span><span style="color: #009900;">&#40;</span>aString<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>异常栈的信息如下：</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #003399;">Exception</span> in thread <span style="color: #0000ff;">&quot;main&quot;</span> java.<span style="color: #006633;">lang</span>.<span style="color: #003399;">IllegalMonitorStateException</span><span style="color: #339933;">:</span> current thread not owner
	at java.<span style="color: #006633;">lang</span>.<span style="color: #003399;">Object</span>.<span style="color: #006633;">wait</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">Native</span> <span style="color: #003399;">Method</span><span style="color: #009900;">&#41;</span>
	at com.<span style="color: #006633;">feihoo</span>.<span style="color: #006633;">test</span>.<span style="color: #006633;">waitnotify</span>.<span style="color: #006633;">WaitNotifyCompilerCode</span>.<span style="color: #006633;">wait1SecAndPrintString</span><span style="color: #009900;">&#40;</span>WaitNotifyCompilerCode.<span style="color: #006633;">java</span><span style="color: #339933;">:</span><span style="color: #cc66cc;">35</span><span style="color: #009900;">&#41;</span>
	at com.<span style="color: #006633;">feihoo</span>.<span style="color: #006633;">test</span>.<span style="color: #006633;">waitnotify</span>.<span style="color: #006633;">WaitNotifyCompilerCode</span>.<span style="color: #006633;">main</span><span style="color: #009900;">&#40;</span>WaitNotifyCompilerCode.<span style="color: #006633;">java</span><span style="color: #339933;">:</span><span style="color: #cc66cc;">27</span><span style="color: #009900;">&#41;</span></pre></div></div>

<p>深入查看 OpenJDK的源码，找到 Object.wait() 函数本地代码：</p>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;">JVM_ENTRY<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">void</span>, JVM_MonitorWait<span style="color: #008000;">&#40;</span>JNIEnv<span style="color: #000040;">*</span> env, jobject handle, jlong ms<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span>
  JVMWrapper<span style="color: #008000;">&#40;</span><span style="color: #FF0000;">&quot;JVM_MonitorWait&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
  Handle obj<span style="color: #008000;">&#40;</span>THREAD, JNIHandles<span style="color: #008080;">::</span><span style="color: #007788;">resolve_non_null</span><span style="color: #008000;">&#40;</span>handle<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
  <span style="color: #0000dd;">assert</span><span style="color: #008000;">&#40;</span>obj<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>is_instance<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span> <span style="color: #000040;">||</span> obj<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>is_array<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, <span style="color: #FF0000;">&quot;JVM_MonitorWait must apply to an object&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
  JavaThreadInObjectWaitState jtiows<span style="color: #008000;">&#40;</span>thread, ms <span style="color: #000040;">!</span><span style="color: #000080;">=</span> <span style="color: #0000dd;">0</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
  <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span>JvmtiExport<span style="color: #008080;">::</span><span style="color: #007788;">should_post_monitor_wait</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
    JvmtiExport<span style="color: #008080;">::</span><span style="color: #007788;">post_monitor_wait</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#40;</span>JavaThread <span style="color: #000040;">*</span><span style="color: #008000;">&#41;</span>THREAD, <span style="color: #008000;">&#40;</span>oop<span style="color: #008000;">&#41;</span>obj<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, ms<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
  <span style="color: #008000;">&#125;</span>
  ObjectSynchronizer<span style="color: #008080;">::</span><span style="color: #007788;">wait</span><span style="color: #008000;">&#40;</span>obj, ms, CHECK<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
JVM_END</pre></div></div>

<p>重点看倒数第二行，调用的函数如下面的代码：</p>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #666666;">// NOTE: must use heavy weight monitor to handle wait()</span>
<span style="color: #0000ff;">void</span> ObjectSynchronizer<span style="color: #008080;">::</span><span style="color: #007788;">wait</span><span style="color: #008000;">&#40;</span>Handle obj, jlong millis, TRAPS<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
  <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span>UseBiasedLocking<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
    BiasedLocking<span style="color: #008080;">::</span><span style="color: #007788;">revoke_and_rebias</span><span style="color: #008000;">&#40;</span>obj, <span style="color: #0000ff;">false</span>, THREAD<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000dd;">assert</span><span style="color: #008000;">&#40;</span><span style="color: #000040;">!</span>obj<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>mark<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>has_bias_pattern<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, <span style="color: #FF0000;">&quot;biases should be revoked by now&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
  <span style="color: #008000;">&#125;</span>
  <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span>millis <span style="color: #000080;">&lt;</span> <span style="color: #0000dd;">0</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
    TEVENT <span style="color: #008000;">&#40;</span>wait <span style="color: #000040;">-</span> <span style="color: #0000ff;">throw</span> IAX<span style="color: #008000;">&#41;</span> <span style="color: #008080;">;</span>
    THROW_MSG<span style="color: #008000;">&#40;</span>vmSymbols<span style="color: #008080;">::</span><span style="color: #007788;">java_lang_IllegalArgumentException</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, <span style="color: #FF0000;">&quot;timeout value is negative&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
  <span style="color: #008000;">&#125;</span>
  ObjectMonitor<span style="color: #000040;">*</span> monitor <span style="color: #000080;">=</span> ObjectSynchronizer<span style="color: #008080;">::</span><span style="color: #007788;">inflate</span><span style="color: #008000;">&#40;</span>THREAD, obj<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
  DTRACE_MONITOR_WAIT_PROBE<span style="color: #008000;">&#40;</span>monitor, obj<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, THREAD, millis<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
  monitor<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>wait<span style="color: #008000;">&#40;</span>millis, <span style="color: #0000ff;">true</span>, THREAD<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span></pre></div></div>

<p>而上面的代码中最后一行的函数里，在做实际操作之前调用了下面的宏：</p>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #666666;">// A macro is used below because there may already be a pending</span>
<span style="color: #666666;">// exception which should not abort the execution of the routines</span>
<span style="color: #666666;">// which use this (which is why we don't put this into check_slow and</span>
<span style="color: #666666;">// call it with a CHECK argument).</span>
&nbsp;
<span style="color: #339900;">#define CHECK_OWNER()                                                             \
  do {                                                                            \
    if (THREAD != _owner) {                                                       \
      if (THREAD-&gt;is_lock_owned((address) _owner)) {                              \
        _owner = THREAD ;  /* Convert from basiclock addr to Thread addr */       \
        _recursions = 0;                                                          \
        OwnerIsThread = 1 ;                                                       \
      } else {                                                                    \
        TEVENT (Throw IMSX) ;                                                     \
        THROW(vmSymbols::java_lang_IllegalMonitorStateException());               \
      }                                                                           \
    }                                                                             \
  } while (false)</span></pre></div></div>



<p>Related posts:<ol><li><a href='http://blog.xiping.me/2009/10/dynamic-programming-problem-1.html' rel='bookmark' title='Permanent Link: 动态规划练习（一）: 求数列中连续数字之和的最大值'>动态规划练习（一）: 求数列中连续数字之和的最大值</a></li>
<li><a href='http://blog.xiping.me/2010/12/java-volatile-is-not-so-evil.html' rel='bookmark' title='Permanent Link: Java中的Volatile关键字'>Java中的Volatile关键字</a></li>
<li><a href='http://blog.xiping.me/2010/01/file-lock-and-jvm-mutex.html' rel='bookmark' title='Permanent Link: 文件锁与进程互斥'>文件锁与进程互斥</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://blog.xiping.me/2009/10/%e7%bb%86%e8%8a%82%e8%83%8c%e5%90%8e%ef%bc%9a%e4%b8%ba%e4%bb%80%e4%b9%88%e7%ba%bf%e7%a8%8b%e5%8d%8f%e4%bd%9c%e4%b9%8b%e5%89%8d%e5%bf%85%e9%a1%bb%e5%85%88%e8%8e%b7%e5%be%97%e9%94%81.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Reliability, Availability, and Scalability</title>
		<link>http://blog.xiping.me/2009/09/reliability-availability-and-scalability.html</link>
		<comments>http://blog.xiping.me/2009/09/reliability-availability-and-scalability.html#comments</comments>
		<pubDate>Wed, 30 Sep 2009 05:51:54 +0000</pubDate>
		<dc:creator>西坪</dc:creator>
				<category><![CDATA[$Architecture & design]]></category>

		<guid isPermaLink="false">http://blog.feihoo.com/?p=316</guid>
		<description><![CDATA[Reliability, according the Wikipedia:
In general, reliability (systemic def.) is the ability of a person or system to perform and maintain its functions in routine circumstances, as well as hostile or unexpected circumstances.
The IEEE defines it as &#8220;. . . the ability of a system or component to perform its required functions under stated conditions for [...]


Related posts:<ol><li><a href='http://blog.xiping.me/2009/12/software-design-devolopment-pricinples.html' rel='bookmark' title='Permanent Link: 设计与开发的五条原则'>设计与开发的五条原则</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p><em><strong>Reliability</strong></em>, according the <a href="http://en.wikipedia.org/wiki/Reliability">Wikipedia</a>:</p>
<blockquote><p>In general, <strong>reliability</strong> (systemic def.) is the ability of a person or system to perform and maintain its functions in routine circumstances, as well as hostile or unexpected circumstances.</p>
<p>The IEEE defines it as &#8220;. . . the ability of a system or component to perform its required functions under stated conditions for a specified period of time.&#8221;</p></blockquote>
<p>On the page, it also tells:</p>
<blockquote><p><strong>Reliability</strong> may refer to:<br />
Data reliability, a property of some <em>disk arrays</em> in computer storage</p></blockquote>
<p><em><strong>Availability</strong></em>, according to <a href="http://en.wikipedia.org/wiki/Availability">Wikipedia</a>:</p>
<blockquote><p>In telecommunications and reliability theory, the term availability has the following meanings:</p>
<p>1. The degree to which a system, subsystem, or equipment is operable and in a committable state at the start of a mission, when the mission is called for at an unknown, i.e., a random, time. Simply put, <strong>availability</strong> is <strong>the proportion of time a system is in a functioning condition</strong>.</p>
<p>Note 1: The conditions determining operability and committability must be specified.</p>
<p>Note 2: Expressed mathematically, availability is 1 minus the unavailability.</p>
<p>2. <strong>The ratio of (a) the total time a functional unit is capable of being used during a given interval to (b) the length of the interval.</strong></p>
<p>Note 1: An example of availability is 100/168 if the unit is capable of being used for 100 hours in a week.</p>
<p>Note 2: Typical availability objectives are specified either in decimal fractions, such as 0.9998, or sometimes in a logarithmic unit called nines, which corresponds roughly to a number of nines following the decimal point, such as &#8220;five nines&#8221; for 0.99999 reliability.</p></blockquote>
<p>There is another page about <a href="http://en.wikipedia.org/wiki/High_availability">High Avaliability</a> on Wikipedia:</p>
<blockquote><p><strong>High availability</strong> is a system design protocol and associated implementation that ensures a certain degree of operational continuity during a given measurement period.</p>
<p>Users want their systems, for example wrist watches, hospitals, airplanes or computers, to be ready to serve them at all times. Availability refers to the ability of the user community to access the system, whether to submit new work, update or alter existing work, or collect the results of previous work. If a user cannot access the system, it is said to be <em>unavailable</em>.  Generally, the term <em>downtime</em> is used to refer to periods when a system is unavailable.</p></blockquote>
<p><em><strong>Scalability</strong></em>, according to <a href="http://en.wikipedia.org/wiki/Scalability">Wikipedia</a>:</p>
<blockquote><p>In <em>telecommunications</em> and <em>software engineering</em>, <strong>scalability</strong> is a desirable property of a system, a network, or a process, which indicates its ability to either handle growing amounts of work in a graceful manner or to be readily enlarged.</p></blockquote>
<p>Methods of adding more resources for a particular application fall into two broad categories: Scale Up (Vertically) and Scale Out (Horizontally). Scale Out could be the better choices  in many larger situations.</p>
<p>References:</p>
<ol>
<li><a href="http://www.eventhelix.com/RealtimeMantra/FaultHandling/system_reliability_availability.htm">System Reliability and Availability</a></li>
<li><a href="http://www.eventhelix.com/RealtimeMantra/FaultHandling/reliability_availability_basics.htm">Reliability and Availability Basics</a></li>
</ol>


<p>Related posts:<ol><li><a href='http://blog.xiping.me/2009/12/software-design-devolopment-pricinples.html' rel='bookmark' title='Permanent Link: 设计与开发的五条原则'>设计与开发的五条原则</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://blog.xiping.me/2009/09/reliability-availability-and-scalability.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>面向对象的几个原则</title>
		<link>http://blog.xiping.me/2009/06/%e9%9d%a2%e5%90%91%e5%af%b9%e8%b1%a1%e7%9a%84%e5%87%a0%e4%b8%aa%e5%8e%9f%e5%88%99.html</link>
		<comments>http://blog.xiping.me/2009/06/%e9%9d%a2%e5%90%91%e5%af%b9%e8%b1%a1%e7%9a%84%e5%87%a0%e4%b8%aa%e5%8e%9f%e5%88%99.html#comments</comments>
		<pubDate>Wed, 24 Jun 2009 13:29:33 +0000</pubDate>
		<dc:creator>西坪</dc:creator>
				<category><![CDATA[$Architecture & design]]></category>

		<guid isPermaLink="false">http://blog.feihoo.com/archives/42</guid>
		<description><![CDATA[来源：http://snowolf.javaeye.com/blog/403184

“开-闭”原则（Open-Closed Principle，或者OCP）：Software entities should be open for extension,but closed for modification.
里氏代换原则（Liskov Subsitution Principle，或者LSP）    任何基类出现的地方，子类一定可以出现。
依赖倒转原则（Dependency Inversion Principle，或者DIP）    要依赖于抽象，不要依赖于实现。
接口隔离原则（Interface Segregation Principle，或者ISP）    应当为客户端提供尽可能小的单独的接口，而不要提供大的总接口。
组合/聚合复用原则（Composition/Aggregation Principle，或者CARP）    要尽量使用合成/聚合，而不是继承关系达到复用的目的。
迪米特法则（Law of Demeter，或者LoD）    一个软件实体应当与尽可能少的其他实体发生相互作用。
单一职责原则（Single Responsibility Principle，或者SRP）  要使每一个软件实体只负责一种职责的实现。



Related posts:Flex中的对象比较（相等性）



Related posts:<ol><li><a href='http://blog.xiping.me/2009/01/flex%e4%b8%ad%e7%9a%84%e5%af%b9%e8%b1%a1%e6%af%94%e8%be%83%ef%bc%88%e7%9b%b8%e7%ad%89%e6%80%a7%ef%bc%89.html' rel='bookmark' title='Permanent Link: Flex中的对象比较（相等性）'>Flex中的对象比较（相等性）</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>来源：<a href="http://snowolf.javaeye.com/blog/403184">http://snowolf.javaeye.com/blog/403184</a></p>
<ol>
<li>“开-闭”原则（Open-Closed Principle，或者OCP）：Software entities should be open for extension,but closed for modification.</li>
<li>里氏代换原则（Liskov Subsitution Principle，或者LSP）    任何基类出现的地方，子类一定可以出现。</li>
<li>依赖倒转原则（Dependency Inversion Principle，或者DIP）    要依赖于抽象，不要依赖于实现。</li>
<li>接口隔离原则（Interface Segregation Principle，或者ISP）    应当为客户端提供尽可能小的单独的接口，而不要提供大的总接口。</li>
<li>组合/聚合复用原则（Composition/Aggregation Principle，或者CARP）    要尽量使用合成/聚合，而不是继承关系达到复用的目的。</li>
<li>迪米特法则（Law of Demeter，或者LoD）    一个软件实体应当与尽可能少的其他实体发生相互作用。</li>
<li>单一职责原则（Single Responsibility Principle，或者SRP）  要使每一个软件实体只负责一种职责的实现。</li>
</ol>


<p>Related posts:<ol><li><a href='http://blog.xiping.me/2009/01/flex%e4%b8%ad%e7%9a%84%e5%af%b9%e8%b1%a1%e6%af%94%e8%be%83%ef%bc%88%e7%9b%b8%e7%ad%89%e6%80%a7%ef%bc%89.html' rel='bookmark' title='Permanent Link: Flex中的对象比较（相等性）'>Flex中的对象比较（相等性）</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://blog.xiping.me/2009/06/%e9%9d%a2%e5%90%91%e5%af%b9%e8%b1%a1%e7%9a%84%e5%87%a0%e4%b8%aa%e5%8e%9f%e5%88%99.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Weblogic 81Sp3</title>
		<link>http://blog.xiping.me/2009/05/weblogic-81sp3.html</link>
		<comments>http://blog.xiping.me/2009/05/weblogic-81sp3.html#comments</comments>
		<pubDate>Thu, 14 May 2009 10:17:12 +0000</pubDate>
		<dc:creator>西坪</dc:creator>
				<category><![CDATA[server & system]]></category>
		<category><![CDATA[weblogic]]></category>

		<guid isPermaLink="false">http://blog.feihoo.com/archives/38</guid>
		<description><![CDATA[Weblogic 81Sp3 发布时遇到如下错误：

&#38;lt;2009-5-14 下午05时29分20秒 CST&#38;gt; &#38;lt;Warning&#38;gt; &#38;lt;Deployer&#38;gt; &#38;lt;BEA-149004&#38;gt; &#38;lt;Failures were detected while initiating Deploy task for application receive.&#38;gt;
&#38;lt;2009-5-14 下午05时29分20秒 CST&#38;gt; &#38;lt;Error&#38;gt; &#38;lt;Deployer&#38;gt; &#38;lt;BEA-149201&#38;gt; &#38;lt;Failed to complete the deployment task with ID 0 for the application receive.
weblogic.management.ApplicationException:
Exception:weblogic.management.ApplicationException: prepare failed for receive
Module: receive Error: Could not load receive: java.lang.StringIndexOutOfBoundsException: String index out of range: -1
&#160;
at weblogic.management.deploy.slave.SlaveDeployer$ActivateTask.createContainer&#40;SlaveDeployer.java:2398&#41;
at weblogic.management.deploy.slave.SlaveDeployer$ActivateTask.prepare&#40;SlaveDeployer.java:2310&#41;
at weblogic.management.deploy.slave.SlaveDeployer.processPrepareTask&#40;SlaveDeployer.java:866&#41;
at [...]


Related posts:<ol><li><a href='http://blog.xiping.me/2008/10/%e5%9c%a8-vista-%e4%b8%8a%e5%ae%89%e8%a3%85-apache-22-php-526.html' rel='bookmark' title='Permanent Link: 在 Vista 上安装 Apache 2.2, PHP 5.2.6'>在 Vista 上安装 Apache 2.2, PHP 5.2.6</a></li>
<li><a href='http://blog.xiping.me/2009/10/%e7%bb%86%e8%8a%82%e8%83%8c%e5%90%8e%ef%bc%9a%e4%b8%ba%e4%bb%80%e4%b9%88%e7%ba%bf%e7%a8%8b%e5%8d%8f%e4%bd%9c%e4%b9%8b%e5%89%8d%e5%bf%85%e9%a1%bb%e5%85%88%e8%8e%b7%e5%be%97%e9%94%81.html' rel='bookmark' title='Permanent Link: 细节背后：为什么线程协作之前必须先获得锁?'>细节背后：为什么线程协作之前必须先获得锁?</a></li>
<li><a href='http://blog.xiping.me/2008/10/ubuntu-%e4%b8%8a%e5%ae%89%e8%a3%85buildix%ef%bc%8cphp5%ef%bc%8c-apache2-%e7%9a%84%e7%83%a6%e6%81%bc.html' rel='bookmark' title='Permanent Link: Ubuntu 上安装buildix，PHP5， Apache2'>Ubuntu 上安装buildix，PHP5， Apache2</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>Weblogic 81Sp3 发布时遇到如下错误：</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #339933;">&amp;</span>lt<span style="color: #339933;">;</span><span style="color: #cc66cc;">2009</span><span style="color: #339933;">-</span><span style="color: #cc66cc;">5</span><span style="color: #339933;">-</span><span style="color: #cc66cc;">14</span> 下午05时<span style="color: #cc66cc;">29</span>分<span style="color: #cc66cc;">20</span>秒 CST<span style="color: #339933;">&amp;</span>gt<span style="color: #339933;">;</span> <span style="color: #339933;">&amp;</span>lt<span style="color: #339933;">;</span>Warning<span style="color: #339933;">&amp;</span>gt<span style="color: #339933;">;</span> <span style="color: #339933;">&amp;</span>lt<span style="color: #339933;">;</span>Deployer<span style="color: #339933;">&amp;</span>gt<span style="color: #339933;">;</span> <span style="color: #339933;">&amp;</span>lt<span style="color: #339933;">;</span>BEA<span style="color: #339933;">-</span><span style="color: #cc66cc;">149004</span><span style="color: #339933;">&amp;</span>gt<span style="color: #339933;">;</span> <span style="color: #339933;">&amp;</span>lt<span style="color: #339933;">;</span>Failures were detected <span style="color: #000000; font-weight: bold;">while</span> initiating Deploy task <span style="color: #000000; font-weight: bold;">for</span> application receive.<span style="color: #339933;">&amp;</span>gt<span style="color: #339933;">;</span>
<span style="color: #339933;">&amp;</span>lt<span style="color: #339933;">;</span><span style="color: #cc66cc;">2009</span><span style="color: #339933;">-</span><span style="color: #cc66cc;">5</span><span style="color: #339933;">-</span><span style="color: #cc66cc;">14</span> 下午05时<span style="color: #cc66cc;">29</span>分<span style="color: #cc66cc;">20</span>秒 CST<span style="color: #339933;">&amp;</span>gt<span style="color: #339933;">;</span> <span style="color: #339933;">&amp;</span>lt<span style="color: #339933;">;</span>Error<span style="color: #339933;">&amp;</span>gt<span style="color: #339933;">;</span> <span style="color: #339933;">&amp;</span>lt<span style="color: #339933;">;</span>Deployer<span style="color: #339933;">&amp;</span>gt<span style="color: #339933;">;</span> <span style="color: #339933;">&amp;</span>lt<span style="color: #339933;">;</span>BEA<span style="color: #339933;">-</span><span style="color: #cc66cc;">149201</span><span style="color: #339933;">&amp;</span>gt<span style="color: #339933;">;</span> <span style="color: #339933;">&amp;</span>lt<span style="color: #339933;">;</span>Failed to complete the deployment task with ID <span style="color: #cc66cc;">0</span> <span style="color: #000000; font-weight: bold;">for</span> the application receive.
<span style="color: #006633;">weblogic</span>.<span style="color: #006633;">management</span>.<span style="color: #003399;">ApplicationException</span><span style="color: #339933;">:</span>
<span style="color: #003399;">Exception</span><span style="color: #339933;">:</span>weblogic.<span style="color: #006633;">management</span>.<span style="color: #003399;">ApplicationException</span><span style="color: #339933;">:</span> prepare failed <span style="color: #000000; font-weight: bold;">for</span> receive
Module<span style="color: #339933;">:</span> receive <span style="color: #003399;">Error</span><span style="color: #339933;">:</span> Could not load receive<span style="color: #339933;">:</span> java.<span style="color: #006633;">lang</span>.<span style="color: #003399;">StringIndexOutOfBoundsException</span><span style="color: #339933;">:</span> <span style="color: #003399;">String</span> index out of range<span style="color: #339933;">:</span> <span style="color: #339933;">-</span><span style="color: #cc66cc;">1</span>
&nbsp;
at weblogic.<span style="color: #006633;">management</span>.<span style="color: #006633;">deploy</span>.<span style="color: #006633;">slave</span>.<span style="color: #006633;">SlaveDeployer</span>$ActivateTask.<span style="color: #006633;">createContainer</span><span style="color: #009900;">&#40;</span>SlaveDeployer.<span style="color: #006633;">java</span><span style="color: #339933;">:</span><span style="color: #cc66cc;">2398</span><span style="color: #009900;">&#41;</span>
at weblogic.<span style="color: #006633;">management</span>.<span style="color: #006633;">deploy</span>.<span style="color: #006633;">slave</span>.<span style="color: #006633;">SlaveDeployer</span>$ActivateTask.<span style="color: #006633;">prepare</span><span style="color: #009900;">&#40;</span>SlaveDeployer.<span style="color: #006633;">java</span><span style="color: #339933;">:</span><span style="color: #cc66cc;">2310</span><span style="color: #009900;">&#41;</span>
at weblogic.<span style="color: #006633;">management</span>.<span style="color: #006633;">deploy</span>.<span style="color: #006633;">slave</span>.<span style="color: #006633;">SlaveDeployer</span>.<span style="color: #006633;">processPrepareTask</span><span style="color: #009900;">&#40;</span>SlaveDeployer.<span style="color: #006633;">java</span><span style="color: #339933;">:</span><span style="color: #cc66cc;">866</span><span style="color: #009900;">&#41;</span>
at weblogic.<span style="color: #006633;">management</span>.<span style="color: #006633;">deploy</span>.<span style="color: #006633;">slave</span>.<span style="color: #006633;">SlaveDeployer</span>.<span style="color: #006633;">prepareDelta</span><span style="color: #009900;">&#40;</span>SlaveDeployer.<span style="color: #006633;">java</span><span style="color: #339933;">:</span><span style="color: #cc66cc;">594</span><span style="color: #009900;">&#41;</span>
at weblogic.<span style="color: #006633;">management</span>.<span style="color: #006633;">deploy</span>.<span style="color: #006633;">slave</span>.<span style="color: #006633;">SlaveDeployer</span>.<span style="color: #006633;">prepareUpdate</span><span style="color: #009900;">&#40;</span>SlaveDeployer.<span style="color: #006633;">java</span><span style="color: #339933;">:</span><span style="color: #cc66cc;">508</span><span style="color: #009900;">&#41;</span>
at weblogic.<span style="color: #006633;">drs</span>.<span style="color: #006633;">internal</span>.<span style="color: #006633;">SlaveCallbackHandler</span>$1.<span style="color: #006633;">execute</span><span style="color: #009900;">&#40;</span>SlaveCallbackHandler.<span style="color: #006633;">java</span><span style="color: #339933;">:</span><span style="color: #cc66cc;">25</span><span style="color: #009900;">&#41;</span>
at weblogic.<span style="color: #006633;">kernel</span>.<span style="color: #006633;">ExecuteThread</span>.<span style="color: #006633;">execute</span><span style="color: #009900;">&#40;</span>ExecuteThread.<span style="color: #006633;">java</span><span style="color: #339933;">:</span><span style="color: #cc66cc;">219</span><span style="color: #009900;">&#41;</span>
at weblogic.<span style="color: #006633;">kernel</span>.<span style="color: #006633;">ExecuteThread</span>.<span style="color: #006633;">run</span><span style="color: #009900;">&#40;</span>ExecuteThread.<span style="color: #006633;">java</span><span style="color: #339933;">:</span><span style="color: #cc66cc;">178</span><span style="color: #009900;">&#41;</span>
<span style="color: #339933;">---------------</span> nested within<span style="color: #339933;">:</span> <span style="color: #339933;">------------------</span>
weblogic.<span style="color: #006633;">management</span>.<span style="color: #006633;">ManagementException</span><span style="color: #339933;">:</span>  <span style="color: #339933;">-</span> with nested exception<span style="color: #339933;">:</span>
<span style="color: #009900;">&#91;</span>weblogic.<span style="color: #006633;">management</span>.<span style="color: #003399;">ApplicationException</span><span style="color: #339933;">:</span>
<span style="color: #003399;">Exception</span><span style="color: #339933;">:</span>weblogic.<span style="color: #006633;">management</span>.<span style="color: #003399;">ApplicationException</span><span style="color: #339933;">:</span> prepare failed <span style="color: #000000; font-weight: bold;">for</span> receive
Module<span style="color: #339933;">:</span> receive <span style="color: #003399;">Error</span><span style="color: #339933;">:</span> Could not load receive<span style="color: #339933;">:</span> java.<span style="color: #006633;">lang</span>.<span style="color: #003399;">StringIndexOutOfBoundsException</span><span style="color: #339933;">:</span> <span style="color: #003399;">String</span> index out of range<span style="color: #339933;">:</span> <span style="color: #339933;">-</span><span style="color: #cc66cc;">1</span>
<span style="color: #009900;">&#93;</span>
at weblogic.<span style="color: #006633;">management</span>.<span style="color: #006633;">deploy</span>.<span style="color: #006633;">slave</span>.<span style="color: #006633;">SlaveDeployer</span>$ActivateTask.<span style="color: #006633;">prepare</span><span style="color: #009900;">&#40;</span>SlaveDeployer.<span style="color: #006633;">java</span><span style="color: #339933;">:</span><span style="color: #cc66cc;">2327</span><span style="color: #009900;">&#41;</span>
at weblogic.<span style="color: #006633;">management</span>.<span style="color: #006633;">deploy</span>.<span style="color: #006633;">slave</span>.<span style="color: #006633;">SlaveDeployer</span>.<span style="color: #006633;">processPrepareTask</span><span style="color: #009900;">&#40;</span>SlaveDeployer.<span style="color: #006633;">java</span><span style="color: #339933;">:</span><span style="color: #cc66cc;">866</span><span style="color: #009900;">&#41;</span>
at weblogic.<span style="color: #006633;">management</span>.<span style="color: #006633;">deploy</span>.<span style="color: #006633;">slave</span>.<span style="color: #006633;">SlaveDeployer</span>.<span style="color: #006633;">prepareDelta</span><span style="color: #009900;">&#40;</span>SlaveDeployer.<span style="color: #006633;">java</span><span style="color: #339933;">:</span><span style="color: #cc66cc;">594</span><span style="color: #009900;">&#41;</span>
at weblogic.<span style="color: #006633;">management</span>.<span style="color: #006633;">deploy</span>.<span style="color: #006633;">slave</span>.<span style="color: #006633;">SlaveDeployer</span>.<span style="color: #006633;">prepareUpdate</span><span style="color: #009900;">&#40;</span>SlaveDeployer.<span style="color: #006633;">java</span><span style="color: #339933;">:</span><span style="color: #cc66cc;">508</span><span style="color: #009900;">&#41;</span>
at weblogic.<span style="color: #006633;">drs</span>.<span style="color: #006633;">internal</span>.<span style="color: #006633;">SlaveCallbackHandler</span>$1.<span style="color: #006633;">execute</span><span style="color: #009900;">&#40;</span>SlaveCallbackHandler.<span style="color: #006633;">java</span><span style="color: #339933;">:</span><span style="color: #cc66cc;">25</span><span style="color: #009900;">&#41;</span>
at weblogic.<span style="color: #006633;">kernel</span>.<span style="color: #006633;">ExecuteThread</span>.<span style="color: #006633;">execute</span><span style="color: #009900;">&#40;</span>ExecuteThread.<span style="color: #006633;">java</span><span style="color: #339933;">:</span><span style="color: #cc66cc;">219</span><span style="color: #009900;">&#41;</span>
at weblogic.<span style="color: #006633;">kernel</span>.<span style="color: #006633;">ExecuteThread</span>.<span style="color: #006633;">run</span><span style="color: #009900;">&#40;</span>ExecuteThread.<span style="color: #006633;">java</span><span style="color: #339933;">:</span><span style="color: #cc66cc;">178</span><span style="color: #009900;">&#41;</span></pre></div></div>

<p>错误原因是Spring 2.5.5 与Weblogic 81之间不兼容造成的。<br />
详细看这里<br/><br />
<a href="http://jira.springframework.org/browse/SPR-4904">Doc: Deployment error on Weblogic 8.1 SP1/SP2 due to manifest issues &#8211; upgrade to SP6 required</a></p>


<p>Related posts:<ol><li><a href='http://blog.xiping.me/2008/10/%e5%9c%a8-vista-%e4%b8%8a%e5%ae%89%e8%a3%85-apache-22-php-526.html' rel='bookmark' title='Permanent Link: 在 Vista 上安装 Apache 2.2, PHP 5.2.6'>在 Vista 上安装 Apache 2.2, PHP 5.2.6</a></li>
<li><a href='http://blog.xiping.me/2009/10/%e7%bb%86%e8%8a%82%e8%83%8c%e5%90%8e%ef%bc%9a%e4%b8%ba%e4%bb%80%e4%b9%88%e7%ba%bf%e7%a8%8b%e5%8d%8f%e4%bd%9c%e4%b9%8b%e5%89%8d%e5%bf%85%e9%a1%bb%e5%85%88%e8%8e%b7%e5%be%97%e9%94%81.html' rel='bookmark' title='Permanent Link: 细节背后：为什么线程协作之前必须先获得锁?'>细节背后：为什么线程协作之前必须先获得锁?</a></li>
<li><a href='http://blog.xiping.me/2008/10/ubuntu-%e4%b8%8a%e5%ae%89%e8%a3%85buildix%ef%bc%8cphp5%ef%bc%8c-apache2-%e7%9a%84%e7%83%a6%e6%81%bc.html' rel='bookmark' title='Permanent Link: Ubuntu 上安装buildix，PHP5， Apache2'>Ubuntu 上安装buildix，PHP5， Apache2</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://blog.xiping.me/2009/05/weblogic-81sp3.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Vim 快捷键</title>
		<link>http://blog.xiping.me/2009/05/vim-usage.html</link>
		<comments>http://blog.xiping.me/2009/05/vim-usage.html#comments</comments>
		<pubDate>Sun, 10 May 2009 12:56:31 +0000</pubDate>
		<dc:creator>西坪</dc:creator>
				<category><![CDATA[Tools & Tips]]></category>
		<category><![CDATA[vim]]></category>

		<guid isPermaLink="false">http://blog.feihoo.com/archives/35</guid>
		<description><![CDATA[All these stuff can be found in the manual. Put them here together to give me random review chance.
Some best resource about vim usage:

Bram Moolenaar:Seven habits of effective text editing: Good guide not just for vim usage. Some tips are copied from this.

General tips

Ctrl-N: auto completion
Position the cursor on the name of the function in [...]


Related posts:<ol><li><a href='http://blog.xiping.me/2009/12/my-vimrc-file.html' rel='bookmark' title='Permanent Link: My Vimrc File'>My Vimrc File</a></li>
<li><a href='http://blog.xiping.me/2009/03/linux-command-shell-tips-1.html' rel='bookmark' title='Permanent Link: Linux Command &#038; Shell Tips (1)'>Linux Command &#038; Shell Tips (1)</a></li>
<li><a href='http://blog.xiping.me/2009/12/my-ubuntu-installation-log.html' rel='bookmark' title='Permanent Link: My Ubuntu Installation log'>My Ubuntu Installation log</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>All these stuff can be found in the manual. Put them here together to give me random review chance.</p>
<h5>Some best resource about vim usage:</h5>
<ul>
<li><a href="http://www.moolenaar.net/habits.html">Bram Moolenaar:<strong>Seven habits of effective text editing</strong></a>: Good guide not just for vim usage. Some tips are copied from this.</li>
</ul>
<h5>General tips</h5>
<ul>
<li><strong>Ctrl-N</strong>: auto completion</li>
<li>Position the cursor on the name of the function in your file and type <strong>[I:</strong> Vim will show a list of all matches for the function name in included files. </li>
</ul>
<h5>Search &#038; Replace</h5>
<blockquote><p><font face="Verdana" size="2">这里有篇介绍文章：<a href="http://blog.feihoo.com/wp-admin/post/43/" class="broken_link" >VIM下,在文件及目录中查找字符串的方法</a> 。例如： vimgrep /登录/g **/*.html </font></p>
<p><font face="Verdana" size="2"><font face="Verdana" size="2">查找的结果会显示在 QuickList 列表中。对于Quicklist 的操纵，参考下面的文章 <a href="http://rickey-nctu.blogspot.com/2009/02/vim-quickfix.html">打造自己的VIM: QuickFix 編譯視窗</a></font><font face="Verdana" size="2"> 。 这篇文章还介绍了打造快捷键，因为我的Vim使用的版本比较多，而且直接切换到Qucik List然后使用行移动也很方便的，所以就不配置这些快捷键。 更详细的参考见官方手册 <a href="http://vimdoc.sourceforge.net/htmldoc/quickfix.html">Quickfix</a> 或者 :help quickfix</font></font></p></blockquote>
<h2><font face="Verdana" size="2">替换 </font></h2>
<blockquote><p><font face="Verdana" size="2"><font face="Verdana" size="2">可以在</font> vim 中查看帮助 :help argdo</font></p>
<p><font face="Verdana" size="2">示例：</font></p>
<p><font face="Verdana" size="2">:args **/*.htm</font></p>
<p><font face="Verdana" size="2">:argdo %s/旧/新/ge  |  update</font></p></blockquote>
<h5>Move around quickly</h5>
<ul>
<li>    Use <strong>%</strong> to jump from an open brace to its matching closing brace. Or from a "#if" to the matching "#endif". Actually, <strong>%</strong> can jump to many different matching items. It is very useful to check if () and {} constructs are balanced properly.</li>
<li> Use <strong>[{</strong> to jump back to the "{" at the start of the current code block.</li>
<li>Use <strong>gd</strong> to jump from the use of a variable to its local declaration.</li>
<li><strong>*</strong> command to search for other places</li>
<li><strong>CTRL-]</strong>, <strong>CTRL-t</strong> with ctags/cscope</li>
</ul>
<p>整页翻页 ctrl-f ctrl-b<br />
f就是forword b就是backward</p>
<p>翻半页<br />
ctrl-d ctlr-u<br />
d=down u=up</p>
<p>滚一行<br />
ctrl-e ctrl-y</p>
<p>zz 让光标所杂的行居屏幕中央<br />
zt 让光标所杂的行居屏幕最上一行 t=top<br />
zb 让光标所杂的行居屏幕最下一行 b=bottom</p>
<p>Highlight and increment search set:<br />
set hls is</p>
<h5>Block Operation (Delete a column):</h5>
<ul>
<li> start mode with Ctrl-v</li>
<li>specify a motion, e.g. G (to the end of the file), or use up / down keys</li>
<li>for the selected block specify an action, e.g. &#8216;d&#8217; for delete</li>
</ul>
<h5>Split Window</h5>
<p>set splitright &#8220;put the new split window in the right)</p>
<p>(some content cited from <a href="http://cscope.sourceforge.net/cscope_vim_tutorial.html">The Vim/Cscope tutorial</a>)</p>
<ul>
<li>move between windows via &#8216;CTRL-W w&#8217; (or CTRL-W arrow key, or CTRL-W h/j/k/l for left/up/down/right), </li>
<li>close a window via &#8216;CTRL-W c&#8217; (or good old &#8216;:q&#8217;), </li>
<li>make the current window the only one via &#8216;CTRL-W o&#8217;, </li>
<li>split a window into two via &#8216;CTRL-W s&#8217; (or &#8216;CTRL-W v&#8217; for a vertical split), </li>
<li>open a file in a new window via &#8216;:spl[it] filename&#8217;,</li>
<li>close a window &#8216;CTRL-W c&#8217;</li>
</ul>
<h5> cscope &#038; ctags </h5>
<p>The most completed tutorial I got from Internet:<br />
<a href="http://cscope.sourceforge.net/cscope_vim_tutorial.html">The Vim/Cscope tutorial</a></p>
<p>We can use ctags to navigate the java code by placing the cursor on a class or method and hitting CTRL-]. To jump back and forwards just use CTRL-O and CTRL-I. Type :jumps command to view the jump lists.</p>
<p>Cscope also can works well with other languages likes Java and C++. All we need to do is explicit specify the special file lists in the cscope.files or the command line.</p>


<p>Related posts:<ol><li><a href='http://blog.xiping.me/2009/12/my-vimrc-file.html' rel='bookmark' title='Permanent Link: My Vimrc File'>My Vimrc File</a></li>
<li><a href='http://blog.xiping.me/2009/03/linux-command-shell-tips-1.html' rel='bookmark' title='Permanent Link: Linux Command &#038; Shell Tips (1)'>Linux Command &#038; Shell Tips (1)</a></li>
<li><a href='http://blog.xiping.me/2009/12/my-ubuntu-installation-log.html' rel='bookmark' title='Permanent Link: My Ubuntu Installation log'>My Ubuntu Installation log</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://blog.xiping.me/2009/05/vim-usage.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Linux Command &amp; Shell Tips (1)</title>
		<link>http://blog.xiping.me/2009/03/linux-command-shell-tips-1.html</link>
		<comments>http://blog.xiping.me/2009/03/linux-command-shell-tips-1.html#comments</comments>
		<pubDate>Sun, 22 Mar 2009 06:30:43 +0000</pubDate>
		<dc:creator>西坪</dc:creator>
				<category><![CDATA[Tools & Tips]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[shell]]></category>

		<guid isPermaLink="false">http://blog.feihoo.com/?p=411</guid>
		<description><![CDATA[此文用于记录使用 Linux 过程中的与 shell 和 commands 有关的有意思的小知识。
1. The problem of ftp url:
  在写一个自动备份的脚本时发现，如果 username 中有 @ 符号时，使用 curl ftp://username:password@host/file 是不行的。这可能是 ftp url 地址格式的一个瑕疵。具体参考 Google Group上的一个讨论 （对于该讨论的正确性本人没有特别考证， 根据作者的观点，在整个URL中出现 &#8220;:&#8221;、&#8221;/&#8221;、&#8221;@&#8221; 都是不可行的。如果您发现此论断有问题请留言）。 还好 curl 可以使用 -n 指定使用 ~/.netrc 中的登录标识。
2. 直接使用 sed 命令批量替换文件中的内容

sed -i 's/\/var\/svn/d:\/data\/svn/g' `grep /var/svn -rl ./*/conf/trac.ini`

sed 命令还有很多用法，可惜平时用得不多，经常忘记了要查资料。
3. 使用 find 命令批量操作 Trac 项目同步SVN

find -maxdepth 1 -mindepth [...]


Related posts:<ol><li><a href='http://blog.xiping.me/2010/11/jdbc-ibatis-datetimes.html' rel='bookmark' title='Permanent Link: JDBC和Ibatis中的Date,Time,Timestamp处理'>JDBC和Ibatis中的Date,Time,Timestamp处理</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>此文用于记录使用 Linux 过程中的与 shell 和 commands 有关的有意思的小知识。</p>
<p>1. The problem of ftp url:<br />
  在写一个自动备份的脚本时发现，如果 username 中有 @ 符号时，使用 curl ftp://username:password@host/file 是不行的。这可能是 ftp url 地址格式的一个瑕疵。具体参考 <a href="http://groups.google.com/group/microsoft.public.inetserver.iis.ftp/msg/033ed2bff0c2d8bf">Google Group上的一个讨论</a> （对于该讨论的正确性本人没有特别考证， 根据作者的观点，在整个URL中出现 &#8220;:&#8221;、&#8221;/&#8221;、&#8221;@&#8221; 都是不可行的。如果您发现此论断有问题请留言）。 还好 curl 可以使用 -n 指定使用 ~/.netrc 中的登录标识。</p>
<p>2. 直接使用 sed 命令批量替换文件中的内容</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">sed</span> <span style="color: #660033;">-i</span> <span style="color: #ff0000;">'s/\/var\/svn/d:\/data\/svn/g'</span> <span style="color: #000000; font-weight: bold;">`</span><span style="color: #c20cb9; font-weight: bold;">grep</span> <span style="color: #000000; font-weight: bold;">/</span>var<span style="color: #000000; font-weight: bold;">/</span><span style="color: #c20cb9; font-weight: bold;">svn</span> <span style="color: #660033;">-rl</span> .<span style="color: #000000; font-weight: bold;">/*/</span>conf<span style="color: #000000; font-weight: bold;">/</span>trac.ini<span style="color: #000000; font-weight: bold;">`</span></pre></div></div>

<p>sed 命令还有很多用法，可惜平时用得不多，经常忘记了要查资料。</p>
<p>3. 使用 find 命令批量操作 Trac 项目同步SVN</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">find</span> <span style="color: #660033;">-maxdepth</span> <span style="color: #000000;">1</span> <span style="color: #660033;">-mindepth</span> <span style="color: #000000;">1</span>  <span style="color: #660033;">-type</span> d <span style="color: #660033;">-print</span> <span style="color: #660033;">-exec</span> trac-admin <span style="color: #7a0874; font-weight: bold;">&#123;</span><span style="color: #7a0874; font-weight: bold;">&#125;</span> resync \;</pre></div></div>

<p>对仅仅处理当前目录下的子目录的限定方法比较笨，也许有更好的方法。</p>
<p>find命令是最难用的，再提供一个统计代码行总数的例子。</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">find</span> stat5.1projects<span style="color: #000000; font-weight: bold;">/</span> <span style="color: #000000; font-weight: bold;">!</span> <span style="color: #660033;">-path</span> <span style="color: #ff0000;">'*.common/*'</span> <span style="color: #660033;">-a</span> <span style="color: #000000; font-weight: bold;">!</span> <span style="color: #660033;">-path</span> <span style="color: #ff0000;">'*bin*'</span> <span style="color: #660033;">-a</span> <span style="color: #000000; font-weight: bold;">!</span> <span style="color: #660033;">-path</span> <span style="color: #ff0000;">'*st
at.statuser*'</span> <span style="color: #660033;">-a</span> \<span style="color: #7a0874; font-weight: bold;">&#40;</span> <span style="color: #660033;">-name</span> <span style="color: #000000; font-weight: bold;">*</span>.java <span style="color: #660033;">-or</span> <span style="color: #660033;">-name</span> <span style="color: #000000; font-weight: bold;">*</span>.sql <span style="color: #660033;">-or</span> <span style="color: #660033;">-name</span> <span style="color: #000000; font-weight: bold;">*</span>.xml \<span style="color: #7a0874; font-weight: bold;">&#41;</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">xargs</span> <span style="color: #c20cb9; font-weight: bold;">wc</span>
<span style="color: #660033;">-l</span>
<span style="color: #000000; font-weight: bold;">&lt;/</span>pre <span style="color: #007800;">lang</span>=<span style="color: #ff0000;">&quot;bash&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span>
然后直接通过Shell计算出平均每天的代码行：
<span style="color: #000000; font-weight: bold;">&lt;</span>pre <span style="color: #007800;">lang</span>=<span style="color: #ff0000;">&quot;bash&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span>
<span style="color: #7a0874; font-weight: bold;">echo</span> $<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #000000;">8888</span><span style="color: #000000; font-weight: bold;">/</span><span style="color: #000000;">22</span><span style="color: #7a0874; font-weight: bold;">&#41;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span></pre></div></div>

<p>4. tar error message. </p>
<blockquote><p>Removing leading `/&#8217; from member names</p></blockquote>
<p>It&#8217;s really annoying when it present in a crontab script. That is why (refer from <a href="http://www.linuxquestions.org/questions/linux-general-1/bintar-removing-leading-from-member-names-269508/#post1366021">here</a>):</p>
<blockquote><p>what do you want suggestions about? tar archives don&#8217;t contain absolute paths, only relative ones. this is correct behaviour, as the alternative is really nasty and illogical. this is the same way that other compression programs like winzip work. when you untar somethign you provide an destination directory, which implicity is &#8216;/&#8217; in your case&#8230; but it should be explicit for logical operation</p></blockquote>
<p>The resolution is using relative path. e.g.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #7a0874; font-weight: bold;">cd</span> <span style="color: #000000; font-weight: bold;">/</span>var<span style="color: #000000; font-weight: bold;">/</span>www
<span style="color: #c20cb9; font-weight: bold;">tar</span> <span style="color: #660033;">-cf</span> <span style="color: #000000; font-weight: bold;">/</span>home<span style="color: #000000; font-weight: bold;">/</span>user<span style="color: #000000; font-weight: bold;">/</span>backup<span style="color: #000000; font-weight: bold;">/</span>wp-backup.tar web
<span style="color: #666666; font-style: italic;"># NOT below</span>
<span style="color: #666666; font-style: italic;"># cd /home/user/backup</span>
<span style="color: #666666; font-style: italic;"># tar -cf wp-backup.tar /var/www/web</span></pre></div></div>

<p>5. svn: Delete unversioned files</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">svn</span> status <span style="color: #660033;">--no-ignore</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">grep</span> <span style="color: #ff0000;">'^[I?]'</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">sed</span> <span style="color: #ff0000;">'s/^[I?]//'</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">xargs</span> <span style="color: #c20cb9; font-weight: bold;">rm</span> <span style="color: #660033;">-rf</span></pre></div></div>

<p><a href="http://subversion.tigris.org/faq.html">Here</a> are more frequent ask questions on subversion.</p>
<p>6. 防火墙后面的git通过代理访问：<br />
  设置GIT_PROXY_COMMAND系统变量即可。具体参考：<a href="http://www.patthoyts.tk/blog/using-git-with-socks-proxy.html">Using Git with a SOCKS proxy</a></p>
<p>7. Ubuntu添加sudo用户:<br />
Edit file /etc/sudoers, add line:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">bob  <span style="color: #007800;">ALL</span>=<span style="color: #7a0874; font-weight: bold;">&#40;</span>ALL<span style="color: #7a0874; font-weight: bold;">&#41;</span> ALL</pre></div></div>

<p> 参考：http://www.linuxhomenetworking.com/wiki/index.php/Quick_HOWTO_:_Ch09_:_Linux_Users_and_Sudo</p>
<p>8. Unix timestamp 与 readable date 之间的转换：<br />
shell:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">date</span> <span style="color: #660033;">-d</span> <span style="color: #000000; font-weight: bold;">@</span><span style="color: #000000;">1232144092</span> <span style="color: #666666; font-style: italic;">#timestamp to date</span></pre></div></div>


<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">date</span> –<span style="color: #007800;"><span style="color: #c20cb9; font-weight: bold;">date</span></span>=’<span style="color: #000000;">1970</span>-01-01 <span style="color: #000000;">1000000000</span> sec GMT’</pre></div></div>


<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">date</span> <span style="color: #660033;">-d</span> today +<span style="color: #000000; font-weight: bold;">%</span>s <span style="color: #666666; font-style: italic;">#date to stamp</span></pre></div></div>

<p>Perl:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">date</span> <span style="color: #660033;">-d</span> today +<span style="color: #000000; font-weight: bold;">%</span>s <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">perl</span> <span style="color: #660033;">-e</span> <span style="color: #ff0000;">'print localtime(&lt;&gt;).&quot;\n&quot;'</span> <span style="color: #666666; font-style: italic;"># to readable time</span></pre></div></div>

<p>gawk:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">date</span> <span style="color: #660033;">-d</span> today +<span style="color: #000000; font-weight: bold;">%</span>s <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">gawk</span> <span style="color: #ff0000;">'END{print strftime(&quot;%c&quot;,$1)}'</span> <span style="color: #666666; font-style: italic;"># to readable time</span></pre></div></div>

<p>9. AWK调用shell命令做一些计算</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">cat</span> <span style="color: #007800;">$f</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">awk</span> <span style="color: #ff0000;">'! /^NAI/ {cmd=&quot;date +%k%M -d @&quot;$3; cmd | getline d; close(cmd); if (d&gt;2357)print d}'</span></pre></div></div>

<p>多行时可循环读取：</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #007800;">cmd_</span>= <span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #ff0000;">&quot;cat &quot;</span>naiIdMappingFile<span style="color: #7a0874; font-weight: bold;">&#41;</span>;
<span style="color: #000000; font-weight: bold;">while</span> <span style="color: #7a0874; font-weight: bold;">&#40;</span>cmd_ <span style="color: #000000; font-weight: bold;">|</span> getline d <span style="color: #7a0874; font-weight: bold;">&#41;</span> <span style="color: #7a0874; font-weight: bold;">&#123;</span>
        <span style="color: #c20cb9; font-weight: bold;">split</span><span style="color: #7a0874; font-weight: bold;">&#40;</span>d, naiIds,<span style="color: #ff0000;">&quot; &quot;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>;
        naiIdMaps<span style="color: #7a0874; font-weight: bold;">&#91;</span>naiIds<span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #000000;">1</span><span style="color: #7a0874; font-weight: bold;">&#93;</span><span style="color: #ff0000;">&quot; &quot;</span><span style="color: #7a0874; font-weight: bold;">&#93;</span>=naiIds<span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #000000;">2</span><span style="color: #7a0874; font-weight: bold;">&#93;</span>;
<span style="color: #7a0874; font-weight: bold;">&#125;</span>
close<span style="color: #7a0874; font-weight: bold;">&#40;</span>cmd_<span style="color: #7a0874; font-weight: bold;">&#41;</span></pre></div></div>

<p>其中要提醒一下的是，一定要记得 close() 的调用，不然很快会耗光文件描述符。</p>
<p>10. Perl 跟bash脚本配合，逐行对文件执行某些操作：</p>

<div class="wp_syntax"><div class="code"><pre class="perl" style="font-family:monospace;">cat <span style="color: #0000ff;">$f</span> <span style="color: #339933;">|</span> perl <span style="color: #339933;">-</span>ane <span style="color: #ff0000;">'$F[1] =~ s/\D+(\d+)\D+(\d+)\D+(\d+)/$1 $2/g; @cols = split(&quot; &quot;,$F[1]); $F[2] =~ s/\D+(\d+)\D+(\d+)\D+(\d+)/$3/g;print &quot; @F &quot;. scalar($F[2]-$cols[1]) .&quot; \n&quot;;'</span><span style="color: #339933;">;</span></pre></div></div>



<p>Related posts:<ol><li><a href='http://blog.xiping.me/2010/11/jdbc-ibatis-datetimes.html' rel='bookmark' title='Permanent Link: JDBC和Ibatis中的Date,Time,Timestamp处理'>JDBC和Ibatis中的Date,Time,Timestamp处理</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://blog.xiping.me/2009/03/linux-command-shell-tips-1.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>只有创造和使用才能学会英文</title>
		<link>http://blog.xiping.me/2009/02/%e9%98%85%e8%af%bb%e5%92%8c%e8%83%8c%e8%af%b5%e6%97%a0%e6%b3%95%e4%bd%bf%e4%bd%a0%e5%ad%a6%e4%bc%9a%e8%8b%b1%e6%96%87%e6%80%9d%e7%bb%b4%ef%bc%8c%e5%8f%aa%e6%9c%89%e9%80%9a%e8%bf%87%e8%87%aa%e5%b7%b1.html</link>
		<comments>http://blog.xiping.me/2009/02/%e9%98%85%e8%af%bb%e5%92%8c%e8%83%8c%e8%af%b5%e6%97%a0%e6%b3%95%e4%bd%bf%e4%bd%a0%e5%ad%a6%e4%bc%9a%e8%8b%b1%e6%96%87%e6%80%9d%e7%bb%b4%ef%bc%8c%e5%8f%aa%e6%9c%89%e9%80%9a%e8%bf%87%e8%87%aa%e5%b7%b1.html#comments</comments>
		<pubDate>Mon, 09 Feb 2009 14:34:15 +0000</pubDate>
		<dc:creator>西坪</dc:creator>
				<category><![CDATA[@生活]]></category>
		<category><![CDATA[@English]]></category>

		<guid isPermaLink="false">http://blog.feihoo.com/archives/30</guid>
		<description><![CDATA[这是华尔街英语作业的 Student Manual Guide 上的一句话，至理名言。我最喜欢的华尔街英语上的课程，就是电脑给出上句，自己说出下句的练习。
阅读和背诵无法使你学会英文思维，只有创造和使用才能学会！
华尔街的作业好多。有的作业难度也不小。 我最重要的是完成 Student Manual，尤其是 Listen exercise 。


No related posts.


No related posts.]]></description>
			<content:encoded><![CDATA[<p>这是华尔街英语作业的 Student Manual Guide 上的一句话，至理名言。我最喜欢的华尔街英语上的课程，就是电脑给出上句，自己说出下句的练习。</p>
<p>阅读和背诵无法使你学会英文思维，只有创造和使用才能学会！</p>
<p>华尔街的作业好多。有的作业难度也不小。 我最重要的是完成 Student Manual，尤其是 Listen exercise 。</p>


<p>No related posts.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.xiping.me/2009/02/%e9%98%85%e8%af%bb%e5%92%8c%e8%83%8c%e8%af%b5%e6%97%a0%e6%b3%95%e4%bd%bf%e4%bd%a0%e5%ad%a6%e4%bc%9a%e8%8b%b1%e6%96%87%e6%80%9d%e7%bb%b4%ef%bc%8c%e5%8f%aa%e6%9c%89%e9%80%9a%e8%bf%87%e8%87%aa%e5%b7%b1.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Flex中的对象比较（相等性）</title>
		<link>http://blog.xiping.me/2009/01/flex%e4%b8%ad%e7%9a%84%e5%af%b9%e8%b1%a1%e6%af%94%e8%be%83%ef%bc%88%e7%9b%b8%e7%ad%89%e6%80%a7%ef%bc%89.html</link>
		<comments>http://blog.xiping.me/2009/01/flex%e4%b8%ad%e7%9a%84%e5%af%b9%e8%b1%a1%e6%af%94%e8%be%83%ef%bc%88%e7%9b%b8%e7%ad%89%e6%80%a7%ef%bc%89.html#comments</comments>
		<pubDate>Mon, 05 Jan 2009 02:52:31 +0000</pubDate>
		<dc:creator>西坪</dc:creator>
				<category><![CDATA[$Programming]]></category>
		<category><![CDATA[flex]]></category>

		<guid isPermaLink="false">http://blog.feihoo.com/archives/29</guid>
		<description><![CDATA[Flex中的对象相等性是什么样的呢？国外有篇文章讨论了这一问题：Architectural Atrocities, part 8: is there no equality? 
下面是我从Flex的参考手册中找出来的一些东西。
Equality operators
The equality operators take two operands, compare their values, and return a  Boolean value. All the equality operators, as listed in the following table,  have equal precedence:


Operator
Operation performed


== 
Equality


!= 
Inequality


=== 
Strict equality


!== 
Strict inequality


IUID


Package
mx.core


Interface
public interface IUID


The IUID interface defines the interface for objects that [...]


Related posts:<ol><li><a href='http://blog.xiping.me/2010/04/dump_memcached.html' rel='bookmark' title='Permanent Link: 导出Memcached中的全部数据'>导出Memcached中的全部数据</a></li>
<li><a href='http://blog.xiping.me/2010/11/jdbc-ibatis-datetimes.html' rel='bookmark' title='Permanent Link: JDBC和Ibatis中的Date,Time,Timestamp处理'>JDBC和Ibatis中的Date,Time,Timestamp处理</a></li>
<li><a href='http://blog.xiping.me/2011/03/java-serialize-and-reflection.html' rel='bookmark' title='Permanent Link: 解决Java序列化的版本冲突'>解决Java序列化的版本冲突</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>Flex中的对象相等性是什么样的呢？国外有篇文章讨论了这一问题：<a href="http://blog.iconara.net/2007/11/25/architectural-atrocities-part-8-is-there-no-equality/">Architectural Atrocities, part 8: is there no equality? </a></p>
<p>下面是我从Flex的参考手册中找出来的一些东西。</p>
<h2 class="h2nobreak"><a title="129993" id="129993" name="129993"></a>Equality operators</h2>
<p><a title="129993" id="129993" name="129993"></a>The equality operators take two operands, compare their values, and return a  Boolean value. All the equality operators, as listed in the following table,  have equal precedence:</p>
<table border="0" cellpadding="0" cellspacing="0" height="80" width="280">
<tr>
<th nowrap="nowrap">Operator</th>
<th nowrap="nowrap">Operation performed</th>
</tr>
<tr>
<td><samp class="codeph">== </samp></td>
<td>Equality</td>
</tr>
<tr>
<td><samp class="codeph">!= </samp></td>
<td>Inequality</td>
</tr>
<tr>
<td><samp class="codeph">=== </samp></td>
<td>Strict equality</td>
</tr>
<tr>
<td><samp class="codeph">!== </samp></td>
<td>Strict inequality</td>
</tr>
</table>
<hr />IUID</p>
<table class="classHeaderTable" cellpadding="0" cellspacing="0">
<tr>
<td class="classHeaderTableLabel">Package</td>
<td>mx.core</td>
</tr>
<tr>
<td class="classHeaderTableLabel">Interface</td>
<td class="classSignature">public interface IUID</td>
</tr>
</table>
<p>The IUID interface defines the interface for objects that must have  Unique Identifiers (UIDs) to uniquely identify the object. UIDs do not need to  be universally unique for most uses in Flex. One exception is for messages send  by data services.</p>
<hr />
<h1>Data providers and the uid property</h1>
<p><!--googleoff: index--><!-- END PAGE TITLE --><!-- BEGIN CONTENT WRAPPER --></p>
<p id="content_wrapper"><!--googleon: index-->Flex data provider controls use a unique identifier (UID) to track data  items. Flex can automatically create and manage UIDs. However, there are  circumstances when you must supply your own <samp class="codeph">uid</samp>  property by implementing the IUID  interface, and there are circumstances when supplying your own <samp class="codeph">uid</samp> property improves processing efficiency.</p>
<p>Because the Object and Array classes are dynamic, you normally do not do  anything special for data objects whose items belong to these classes. However,  you should consider implementing the IUID if your data object items belong to  custom classes that you define.</p>
<p class="note"><span class="notetitle">Note: </span>When Flex creates a UID for  an object, such as an item in an ArrayCollection, it adds the UID as an <samp class="codeph">mx_internal_uid</samp> property of the item. Flex creates <samp class="codeph">mx_internal_uid</samp> properties for any objects that are dynamic  and do not have bindable properties. To avoid having Flex create <samp class="codeph">mx_internal_uid</samp> properties, the object class should do any  of the following things: have at least one property with a <samp class="codeph">[Bindable]</samp> metadata tag; implement the IUID interface; or  have a <samp class="codeph">uid</samp><em> property with a value.</em></p>
<p>If Flex must consider two or more different objects to be identical, the  objects must implement the IUID interface so that you can assign the same <samp class="codeph">uid</samp> value to multiple objects. A typical case where you must  implement the IUID interface is an application that uses paged collections. As  the cursor moves through the collection, a particular item might be pulled down  from the server and released from memory repeatedly. Every time the item is  pulled into memory, a new object is created to represent the item. If you need  to compare items for equality, Flex should consider all objects that represent  the same item to be the same &#8220;thing.&#8221;</p>
<p>More common than the case where you must implement the IUID interface is the  case where you can improve processing efficiency by doing so. As a general rule,  you do not implement the IUID interface if the data provider elements are  members of dynamic classes. Flex can automatically create a <samp class="codeph">uid</samp> property for these classes. There is still some  inefficiency, however, so you might consider implementing the IUID interface if  processing efficiency is particularly important.</p>
<p>In all other cases, Flex uses the Dictionary mechanism to manage the <samp class="codeph">uid</samp>, which might not be as efficient as supplying your own  UID.</p>


<p>Related posts:<ol><li><a href='http://blog.xiping.me/2010/04/dump_memcached.html' rel='bookmark' title='Permanent Link: 导出Memcached中的全部数据'>导出Memcached中的全部数据</a></li>
<li><a href='http://blog.xiping.me/2010/11/jdbc-ibatis-datetimes.html' rel='bookmark' title='Permanent Link: JDBC和Ibatis中的Date,Time,Timestamp处理'>JDBC和Ibatis中的Date,Time,Timestamp处理</a></li>
<li><a href='http://blog.xiping.me/2011/03/java-serialize-and-reflection.html' rel='bookmark' title='Permanent Link: 解决Java序列化的版本冲突'>解决Java序列化的版本冲突</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://blog.xiping.me/2009/01/flex%e4%b8%ad%e7%9a%84%e5%af%b9%e8%b1%a1%e6%af%94%e8%be%83%ef%bc%88%e7%9b%b8%e7%ad%89%e6%80%a7%ef%bc%89.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>加班文化</title>
		<link>http://blog.xiping.me/2008/12/opinions-in-overtime-work.html</link>
		<comments>http://blog.xiping.me/2008/12/opinions-in-overtime-work.html#comments</comments>
		<pubDate>Sat, 13 Dec 2008 15:05:59 +0000</pubDate>
		<dc:creator>西坪</dc:creator>
				<category><![CDATA[$软件工程与管理]]></category>
		<category><![CDATA[projectmanagement]]></category>
		<category><![CDATA[team]]></category>

		<guid isPermaLink="false">http://blog.feihoo.com/archives/26</guid>
		<description><![CDATA[Update 2010 Dec: 两年后再看到这篇帖子，有了一些不同的想法。很多事情并不那么简单，虽然那时我也担当项目开发负责之类的工作，但现在有更多的看法。待有时间再写一篇跟管理有关的文字。
和同事在一起吃晚饭的时候，聊起了公司里的加班现象。该同事是刚到公司三个月，他说自从来了以后，每天如果能够在七点下班那就要高兴不已。在这短短的时间里，明显的感觉到身体有了一些的变化，感受到身体上的损害和痛苦。基本上，每天都是紧张的去做事，但还是做不完，还是要加班。不仅工作日的晚上要加班，连周末也经常不得不去公司&#8211;如果想正常完成各项工作的话。
除了加不完的班，另外就是经常有突发性的任务忽然需要去处理。他说有一天六点多，要下班的时候，忽然PM告知他明天要去演示，要求他立即搭建演示环境，因为他明天要去见客户，要给客户演示。这下，搞得他不得不忙到很晚，快十一点时，拖着疲惫的身体回家。这样的事情，真的不少。
仔细观察我们公司的加班文化，发现同是在一个公司的研发部门，有的组加班相对要少一些，有的组加班相对要多一些。第一个原因，我想可能跟领导的风格有关系。有的部门领导自己是个工作狂，所以开发计划也比较紧密。有点部门领导比较重视生活点，正常平衡工作与生活，所以相对来说员工也会轻松一些。第二个原因，可能确实是不同的组，其任务量、效率都有不同。任务较重或者效率较低的组自然要加班了。
加班文化的重要原因肯定跟项目经理有关。人都是需要生活的，不只是需要工作。如果长期工作，而忽视了生活，员工怎么能够在公司里愉快的工作呢？ 不能愉快的工作，对公司有怨言（即使嘴上不说） ，怎么能够好好的工作呢？怎么心甘情愿地做忠诚负责的员工呢？ 我想有能力的员工，又想要平衡好生活与工作的关系的员工，肯定会对领导的强制或者是项目计划的强制产生内心的逆反（即使没有强烈到激化冲突），并进而去选择一个更好的工作环境。所以，我觉得好的项目经理的一项重要素质就是在重视工作的同时，也应该努力帮助员工愉快地工作。
然而，话说回来，项目经理也有自己的难处。
需求多变就是一个关键的难题，但是解决这个问题的方法，有时候也不是项目经理就能够解决的。不过我建议项目经理不应该因为需求多变就把这种多变的需求直接传导到员工头上去。这样，无非是多让员工做一些无意义的事情，最终带来项目成本的增加，还要求员工付出身心牺牲，最终却没有任何意义。管理和控制需求作为降低项目成本提高项目收益的重要内容，我觉得是项目经理的重要工作之一，绝对不应该因为客户比较刁蛮就丢弃了这部分工作内容。
工作过多而资源紧缺也是一个常见的问题。因此经常导致了在制定计划时不能够客观。有的情况下是忽略了一些在计划中需要处理的潜在工作，有的情况下是尽最大限度地去缩减对任务的资源支出。无论哪种方式，这个计划都没有尽可能地去贴近实际情况，这个项目计划的执行过程怎么能够不出问题呢？项目的计划怎么能够执行呢？掩耳盗铃的方式，并不可取。我觉得正确的方法，应该是制定计划时定时不过多超额定量，或者争取更多的资源。
突发事件是项目经理的另一个要经常面对的难题。例如上问提到的忽然要求搭建演示环境的事情。这完全是在项目经理的工作表里面没有的事情，忽然跑出来，如无必要那徒然疲劳下属。 如果当这项工作确实是需要的，那么项目经理应该要提前通知，让手下有所准备，或者确实处于突然，则应该给一定的时间，这样做出来的东西也有保证。如果感觉这项工作内容较多，需要手下去突击完成，从而采取这种突发事件让手下加班的方法，那更不应该。如果确实内容较多，那么要考虑下是不是值得去做这些任务，是不是可以将这项内容适当删减。即使让手下是加班时间突击完成了这件事情，但这些确实已经是项目中的成本。员工的加班尽管不付钱，但是确实是项目成本。员工付出了时间和健康。尽管PM没有付钱，但是却一定付出了威信和下属的信任。项目经理应该努力让所有的事情都是可控的，对于不可控的事情，也要努力去削弱项目中突发事件的影响。
做一个好的项目经理，要尊重、爱惜自己的手下。 在某一个项目里，PM最需要负责的也许不是手下，但是在很多项目构成的长期工作中，PM最需要负责的正是手下的员工。没有他们，PM什么都成不了。


No related posts.


No related posts.]]></description>
			<content:encoded><![CDATA[<p><strong>Update 2010 Dec</strong>: 两年后再看到这篇帖子，有了一些不同的想法。很多事情并不那么简单，虽然那时我也担当项目开发负责之类的工作，但现在有更多的看法。待有时间再写一篇跟管理有关的文字。</p>
<p>和同事在一起吃晚饭的时候，聊起了公司里的加班现象。该同事是刚到公司三个月，他说自从来了以后，每天如果能够在七点下班那就要高兴不已。在这短短的时间里，明显的感觉到身体有了一些的变化，感受到身体上的损害和痛苦。基本上，每天都是紧张的去做事，但还是做不完，还是要加班。不仅工作日的晚上要加班，连周末也经常不得不去公司&#8211;如果想正常完成各项工作的话。</p>
<p>除了加不完的班，另外就是经常有突发性的任务忽然需要去处理。他说有一天六点多，要下班的时候，忽然PM告知他明天要去演示，要求他立即搭建演示环境，因为他明天要去见客户，要给客户演示。这下，搞得他不得不忙到很晚，快十一点时，拖着疲惫的身体回家。这样的事情，真的不少。</p>
<p>仔细观察我们公司的加班文化，发现同是在一个公司的研发部门，有的组加班相对要少一些，有的组加班相对要多一些。第一个原因，我想可能跟领导的风格有关系。有的部门领导自己是个工作狂，所以开发计划也比较紧密。有点部门领导比较重视生活点，正常平衡工作与生活，所以相对来说员工也会轻松一些。第二个原因，可能确实是不同的组，其任务量、效率都有不同。任务较重或者效率较低的组自然要加班了。</p>
<p>加班文化的重要原因肯定跟项目经理有关。人都是需要生活的，不只是需要工作。如果长期工作，而忽视了生活，员工怎么能够在公司里愉快的工作呢？ 不能愉快的工作，对公司有怨言（即使嘴上不说） ，怎么能够好好的工作呢？怎么心甘情愿地做忠诚负责的员工呢？ 我想有能力的员工，又想要平衡好生活与工作的关系的员工，肯定会对领导的强制或者是项目计划的强制产生内心的逆反（即使没有强烈到激化冲突），并进而去选择一个更好的工作环境。所以，我觉得好的项目经理的<strong>一项重要素质就是在重视工作的同时，也应该努力帮助员工愉快地工作</strong>。</p>
<p>然而，话说回来，项目经理也有自己的难处。</p>
<p><strong>需求多变</strong>就是一个关键的难题，但是解决这个问题的方法，有时候也不是项目经理就能够解决的。不过我建议项目经理不应该因为需求多变就把这种多变的需求直接传导到员工头上去。这样，无非是多让员工做一些无意义的事情，最终带来项目成本的增加，还要求员工付出身心牺牲，最终却没有任何意义。管理和控制需求作为降低项目成本提高项目收益的重要内容，我觉得是项目经理的重要工作之一，绝对不应该因为客户比较刁蛮就丢弃了这部分工作内容。</p>
<p>工作过多而资源紧缺也是一个常见的问题。因此经常导致了在制定计划时不能够客观。有的情况下是忽略了一些在计划中需要处理的潜在工作，有的情况下是尽最大限度地去缩减对任务的资源支出。无论哪种方式，这个计划都没有尽可能地去贴近实际情况，这个项目计划的执行过程怎么能够不出问题呢？项目的计划怎么能够执行呢？掩耳盗铃的方式，并不可取。我觉得正确的方法，应该是制定计划时定时不过多超额定量，或者争取更多的资源。</p>
<p><strong>突发事件</strong>是项目经理的另一个要经常面对的难题。例如上问提到的忽然要求搭建演示环境的事情。这完全是在项目经理的工作表里面没有的事情，忽然跑出来，如无必要那徒然疲劳下属。 如果当这项工作确实是需要的，那么项目经理应该要提前通知，让手下有所准备，或者确实处于突然，则应该给一定的时间，这样做出来的东西也有保证。如果感觉这项工作内容较多，需要手下去突击完成，从而采取这种突发事件让手下加班的方法，那更不应该。如果确实内容较多，那么要考虑下是不是值得去做这些任务，是不是可以将这项内容适当删减。即使让手下是加班时间突击完成了这件事情，但这些确实已经是项目中的成本。员工的加班尽管不付钱，但是确实是项目成本。员工付出了时间和健康。尽管PM没有付钱，但是却一定付出了威信和下属的信任。项目经理应该努力让所有的事情都是可控的，对于不可控的事情，也要努力去削弱项目中突发事件的影响。</p>
<p><strong>做一个好的项目经理，要尊重、爱惜自己的手下</strong>。 在某一个项目里，PM最需要负责的也许不是手下，但是在很多项目构成的长期工作中，PM最需要负责的正是手下的员工。没有他们，PM什么都成不了。</p>


<p>No related posts.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.xiping.me/2008/12/opinions-in-overtime-work.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>在 Vista 上安装 Apache 2.2, PHP 5.2.6</title>
		<link>http://blog.xiping.me/2008/10/%e5%9c%a8-vista-%e4%b8%8a%e5%ae%89%e8%a3%85-apache-22-php-526.html</link>
		<comments>http://blog.xiping.me/2008/10/%e5%9c%a8-vista-%e4%b8%8a%e5%ae%89%e8%a3%85-apache-22-php-526.html#comments</comments>
		<pubDate>Sun, 12 Oct 2008 14:58:29 +0000</pubDate>
		<dc:creator>西坪</dc:creator>
				<category><![CDATA[server & system]]></category>

		<guid isPermaLink="false">http://www.feihoo.com/archives/25</guid>
		<description><![CDATA[今天，在Vista上安装了 Apache 2.2， PHP 5.2.6，花费了三四个小时。 Apache 和 PHP 的新版本，在相互兼容性方面似乎是越来越差了！
Apache 2.2  下载完后安装，倒是很顺利，最后 http://localhost, 显示 It works.
一开始，打算以 Module 形式安装 PHP，安装后显示 缺少不少库，并且不能显示 phpinfo.php。
于是改成以 CGI 形式重新安装，配置如下：
ScriptAlias /php/ "D:/software/PHP/"
AddType application/x-httpd-php .php
# For PHP 5
Action application/x-httpd-php "/php/php-cgi.exe"

打开网址，什么也访问不了：
You don&#8217;t have permission to access / on this server.
通过如下设置解决：
DocumentRoot &#8220;D:/programdata/Apachehtdocs&#8221;

Options FollowSymLinks
AllowOverride All
Order Allow,Deny
Allow from all
Satisfy all

然后就一直显示：
You don&#8217;t have permission to access /php/php-cgi.exe/phpinfo.php on this [...]


Related posts:<ol><li><a href='http://blog.xiping.me/2008/10/ubuntu-%e4%b8%8a%e5%ae%89%e8%a3%85buildix%ef%bc%8cphp5%ef%bc%8c-apache2-%e7%9a%84%e7%83%a6%e6%81%bc.html' rel='bookmark' title='Permanent Link: Ubuntu 上安装buildix，PHP5， Apache2'>Ubuntu 上安装buildix，PHP5， Apache2</a></li>
<li><a href='http://blog.xiping.me/2010/11/google-apache-modpagespeed-tests.html' rel='bookmark' title='Permanent Link: Google Apache modpagespeed 测试'>Google Apache modpagespeed 测试</a></li>
<li><a href='http://blog.xiping.me/2009/05/weblogic-81sp3.html' rel='bookmark' title='Permanent Link: Weblogic 81Sp3'>Weblogic 81Sp3</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>今天，在Vista上安装了 Apache 2.2， PHP 5.2.6，花费了三四个小时。 Apache 和 PHP 的新版本，在相互兼容性方面似乎是越来越差了！</p>
<p><a href="http://apache.mirror.phpchina.com/httpd/binaries/win32/apache_2.2.9-win32-x86-openssl-0.9.8h-r2.msi">Apache 2.2 </a> 下载完后安装，倒是很顺利，最后 http://localhost, 显示 It works.</p>
<p>一开始，打算以 Module 形式安装 PHP，安装后显示 缺少不少库，并且不能显示 phpinfo.php。</p>
<p>于是改成以 CGI 形式重新安装，配置如下：<code><br />
ScriptAlias /php/ "D:/software/PHP/"<br />
AddType application/x-httpd-php .php<br />
# For PHP 5<br />
Action application/x-httpd-php "/php/php-cgi.exe"<br />
</code></p>
<p>打开网址，什么也访问不了：<br />
You don&#8217;t have permission to access / on this server.<br />
通过如下设置解决：<br />
DocumentRoot &#8220;D:/programdata/Apachehtdocs&#8221;<br />
<directory><br />
Options FollowSymLinks<br />
AllowOverride All<br />
Order Allow,Deny<br />
Allow from all<br />
Satisfy all<br />
</directory></p>
<p>然后就一直显示：<br />
You don&#8217;t have permission to access /php/php-cgi.exe/phpinfo.php on this server.<br />
在后台 error.log:<br />
[error] [client 127.0.0.1] client denied by server configuration: D:/software/PHP/php-cgi.exe</p>
<p>最后，增加如下设置，解决了问题：<br />
<directory><br />
Options Indexes FollowSymLinks<br />
AllowOverride None<br />
Order allow,deny<br />
Allow from all<br />
</directory></p>
<p>解决了问题。但是，后台又出现了一个问题：<br />
[Sun Oct 12 22:36:57 2008] [error] [client 127.0.0.1] PHP Fatal error:  require_once() [function.require]: Failed opening required &#8216;SAM/php_sam.php&#8217; (include_path=&#8217;.;C:\\php5\\pear&#8217;) in sam_factory on line 1</p>
<p>这个问题的解决，参考 <a href="http://www.phpbuilder.com/board/showthread.php?t=10339966"><strong>[RESOLVED] PHP Install Problem &#8211; SAM Error</strong></a>   我只是简单地安装PHP时，只选择 MySQL扩展。</p>


<p>Related posts:<ol><li><a href='http://blog.xiping.me/2008/10/ubuntu-%e4%b8%8a%e5%ae%89%e8%a3%85buildix%ef%bc%8cphp5%ef%bc%8c-apache2-%e7%9a%84%e7%83%a6%e6%81%bc.html' rel='bookmark' title='Permanent Link: Ubuntu 上安装buildix，PHP5， Apache2'>Ubuntu 上安装buildix，PHP5， Apache2</a></li>
<li><a href='http://blog.xiping.me/2010/11/google-apache-modpagespeed-tests.html' rel='bookmark' title='Permanent Link: Google Apache modpagespeed 测试'>Google Apache modpagespeed 测试</a></li>
<li><a href='http://blog.xiping.me/2009/05/weblogic-81sp3.html' rel='bookmark' title='Permanent Link: Weblogic 81Sp3'>Weblogic 81Sp3</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://blog.xiping.me/2008/10/%e5%9c%a8-vista-%e4%b8%8a%e5%ae%89%e8%a3%85-apache-22-php-526.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ubuntu 上安装buildix，PHP5， Apache2</title>
		<link>http://blog.xiping.me/2008/10/ubuntu-%e4%b8%8a%e5%ae%89%e8%a3%85buildix%ef%bc%8cphp5%ef%bc%8c-apache2-%e7%9a%84%e7%83%a6%e6%81%bc.html</link>
		<comments>http://blog.xiping.me/2008/10/ubuntu-%e4%b8%8a%e5%ae%89%e8%a3%85buildix%ef%bc%8cphp5%ef%bc%8c-apache2-%e7%9a%84%e7%83%a6%e6%81%bc.html#comments</comments>
		<pubDate>Sun, 12 Oct 2008 09:28:48 +0000</pubDate>
		<dc:creator>西坪</dc:creator>
				<category><![CDATA[server & system]]></category>
		<category><![CDATA[buildix]]></category>
		<category><![CDATA[lamp]]></category>
		<category><![CDATA[ubuntu]]></category>

		<guid isPermaLink="false">http://www.feihoo.com/archives/24</guid>
		<description><![CDATA[一开始，我在计算机上安装了buildix，发现 Buildix的各项功能也能正确运行。但是，一旦我安装并启用了 php5和mod-php5，就会导致buildix被卸载。如下：

liuzhr@suowan-master:/etc/apache2/sites-enabled$ sudo apt-get install php5 libapache2-mod-php5
Reading package lists... Done
Building dependency tree
Reading state information... Done
php5 is already the newest version.
The following packages were automatically installed and are no longer required:
python-libxslt1 libapache2-svn libapache2-mod-python sun-java5-jdk python-libxml2 python-svn libapache2-mod-fastcgi cruisecontrol sun-java5-demo
Use 'apt-get autoremove' to remove them.
The following extra packages will be installed:
apache2-mpm-prefork
The following packages will be REMOVED:
apache2-mpm-worker [...]


Related posts:<ol><li><a href='http://blog.xiping.me/2008/10/%e5%9c%a8-vista-%e4%b8%8a%e5%ae%89%e8%a3%85-apache-22-php-526.html' rel='bookmark' title='Permanent Link: 在 Vista 上安装 Apache 2.2, PHP 5.2.6'>在 Vista 上安装 Apache 2.2, PHP 5.2.6</a></li>
<li><a href='http://blog.xiping.me/2009/12/my-ubuntu-installation-log.html' rel='bookmark' title='Permanent Link: My Ubuntu Installation log'>My Ubuntu Installation log</a></li>
<li><a href='http://blog.xiping.me/2010/11/google-apache-modpagespeed-tests.html' rel='bookmark' title='Permanent Link: Google Apache modpagespeed 测试'>Google Apache modpagespeed 测试</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>一开始，我在计算机上安装了buildix，发现 Buildix的各项功能也能正确运行。但是，一旦我安装并启用了 php5和mod-php5，就会导致buildix被卸载。如下：<br />
<code><br />
liuzhr@suowan-master:/etc/apache2/sites-enabled$ sudo apt-get install php5 libapache2-mod-php5<br />
Reading package lists... Done<br />
Building dependency tree<br />
Reading state information... Done<br />
php5 is already the newest version.<br />
The following packages were automatically installed and are no longer required:<br />
python-libxslt1 libapache2-svn libapache2-mod-python sun-java5-jdk python-libxml2 python-svn libapache2-mod-fastcgi cruisecontrol sun-java5-demo<br />
Use 'apt-get autoremove' to remove them.<br />
The following extra packages will be installed:<br />
apache2-mpm-prefork<br />
The following packages will be REMOVED:<br />
apache2-mpm-worker buildix<br />
The following NEW packages will be installed:<br />
apache2-mpm-prefork libapache2-mod-php5<br />
0 upgraded, 2 newly installed, 2 to remove and 60 not upgraded.<br />
Need to get 0B/2978kB of archives.<br />
After unpacking 5747kB of additional disk space will be used.<br />
Do you want to continue [Y/n]?<br />
</code></p>
<p>如果选择继续，安装了php5和libapache2-mod-php5，则会导致buildix卸载，如果重新安装 buildix，安装过程中会出现下面的错误，原因大概是libapache-mod-php5被buildix自动卸载了。<br />
<code><br />
liuzhr@suowan-master:/etc/apache2/sites-enabled$ sudo /etc/init.d/apache2 restart<br />
* Restarting web server apache2<br />
* We failed to correctly shutdown apache, so we're now killing all running apache processes. This is almost certainly suboptimal, so please make sure your system is working as you'd expect now!<br />
apache2: Syntax error on line 183 of /etc/apache2/apache2.conf: Syntax error on line 1 of /etc/apache2/mods-enabled/php5.load: Cannot load /usr/lib/apache2/modules/libphp5.so into server: /usr/lib/apache2/modules/libphp5.so: cannot open shared object file: No such file or directory。<br />
</code></p>
<p>原因应该是 buildix 依赖于   apache2-mpm-worker, 而目前的 php5只能运行单线程的apache2，这样就必须使用  apache2-mpm-prefork。<br />
使用  apt-cache show buildix 一看，果然buildix依赖于 apache2-mpm-worker。看来必须放弃将 buildix与目前的 php5(Module方式) 在一起安装的方法。</p>
<p>于是只能选择使用 cgi 的方式来安装。参考这篇文章：<a href="http://ivan.gudangbaca.com/installing_apache2_and_php5_using_mod_fcgid">Installing Apache2 and PHP5 using mod_fcgid </a>。配置的过程中发生了一些错误（you don&#8217;t have permission to access &#8216;/index.php&#8217;），似乎是因为下面的配置中，AllowOverride ，FCGIWrapper ，AddHandler 或者 Options +ExecCGI 的顺序导致的。没有时间仔细研究这个问题，高手看到请指教。<br />
<code><br />
&lt;directory&gt;<br />
Options Indexes FollowSymLinks MultiViews<br />
AllowOverride All<br />
FCGIWrapper /usr/lib/cgi-bin/php5 .php<br />
AddHandler fcgid-script .php<br />
Options +ExecCGI<br />
Order allow,deny<br />
allow from all<br />
# This directive allows us to have apache2's default start page<br />
# in /apache2-default/, but still have / go to the right place<br />
#RedirectMatch ^/$ /apache2-default/<br />
&lt;/directory&gt;<br />
</code></p>
<p>php5 目前不能使用 apache2-mpm-worker 模块是因为不支持多线程的apache2。 PHP如此说：<a href="http://au.php.net/manual/en/faq.installation.php#faq.installation.apache2">Why shouldn&#8217;t I use Apache2 with a threaded MPM in a production environment?            </a></p>
<p>有关 apt-get 的命令，参考这里：<a href="https://help.ubuntu.com/community/AptGet/Howto">https://help.ubuntu.com/community/AptGet/Howto </a></p>
<p>有关 Ubuntu上的LAMP，参考：<a href="https://help.ubuntu.com/community/ApacheMySQLPHP" rel="nofollow">ApacheMySQLPHP</a></p>


<p>Related posts:<ol><li><a href='http://blog.xiping.me/2008/10/%e5%9c%a8-vista-%e4%b8%8a%e5%ae%89%e8%a3%85-apache-22-php-526.html' rel='bookmark' title='Permanent Link: 在 Vista 上安装 Apache 2.2, PHP 5.2.6'>在 Vista 上安装 Apache 2.2, PHP 5.2.6</a></li>
<li><a href='http://blog.xiping.me/2009/12/my-ubuntu-installation-log.html' rel='bookmark' title='Permanent Link: My Ubuntu Installation log'>My Ubuntu Installation log</a></li>
<li><a href='http://blog.xiping.me/2010/11/google-apache-modpagespeed-tests.html' rel='bookmark' title='Permanent Link: Google Apache modpagespeed 测试'>Google Apache modpagespeed 测试</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://blog.xiping.me/2008/10/ubuntu-%e4%b8%8a%e5%ae%89%e8%a3%85buildix%ef%bc%8cphp5%ef%bc%8c-apache2-%e7%9a%84%e7%83%a6%e6%81%bc.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>有关 sum与limit组合使用时的问题</title>
		<link>http://blog.xiping.me/2008/06/%e6%9c%89%e5%85%b3-sum%e4%b8%8elimit%e7%bb%84%e5%90%88%e4%bd%bf%e7%94%a8%e6%97%b6%e7%9a%84%e9%97%ae%e9%a2%98.html</link>
		<comments>http://blog.xiping.me/2008/06/%e6%9c%89%e5%85%b3-sum%e4%b8%8elimit%e7%bb%84%e5%90%88%e4%bd%bf%e7%94%a8%e6%97%b6%e7%9a%84%e9%97%ae%e9%a2%98.html#comments</comments>
		<pubDate>Wed, 25 Jun 2008 14:03:51 +0000</pubDate>
		<dc:creator>西坪</dc:creator>
				<category><![CDATA[$Programming]]></category>
		<category><![CDATA[mysql]]></category>

		<guid isPermaLink="false">http://www.feihoo.com/archives/18</guid>
		<description><![CDATA[
BODY { FONT-FAMILY:Verdana; FONT-SIZE:10pt } P { FONT-FAMILY:Verdana; FONT-SIZE:10pt } DIV { FONT-FAMILY:Verdana; FONT-SIZE:10pt } TD { FONT-FAMILY:Verdana; FONT-SIZE:10pt } 
select sum(a) from test_table order by b desc limit 1,2
这个句子，在MySQL 和 Sqlite3下，如此 sum得到的是 Empty Set
而 select sum(a) from test_table order by b desc limit 0,2 则返回全部记录的a字段的合计，limit不起作用。
但是去掉sum函数的话， select a from test_table order by b desc limit [...]


Related posts:<ol><li><a href='http://blog.xiping.me/2010/07/orx_tutorial_cn_basic.html' rel='bookmark' title='Permanent Link: [译] Orx教程：0.Basic'>[译] Orx教程：0.Basic</a></li>
<li><a href='http://blog.xiping.me/2009/11/%e7%ae%97%e6%b3%95%e8%a7%a3%e9%a2%98%e6%80%9d%e8%80%83%e8%bf%87%e7%a8%8b.html' rel='bookmark' title='Permanent Link: 算法解题思考过程[总结]'>算法解题思考过程[总结]</a></li>
<li><a href='http://blog.xiping.me/2009/05/vim-usage.html' rel='bookmark' title='Permanent Link: Vim 快捷键'>Vim 快捷键</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><meta name="GENERATOR" content="BLOCKNOTE.NET" /><title></title></p>
<style>BODY { FONT-FAMILY:Verdana; FONT-SIZE:10pt } P { FONT-FAMILY:Verdana; FONT-SIZE:10pt } DIV { FONT-FAMILY:Verdana; FONT-SIZE:10pt } TD { FONT-FAMILY:Verdana; FONT-SIZE:10pt } </style>
<p><basefont face="Verdana" size="2"></basefont>select sum(a) from test_table order by b desc limit 1,2</p>
<p>这个句子，在MySQL 和 Sqlite3下，如此 sum得到的是 Empty Set</p>
<p>而 select sum(a) from test_table order by b desc limit 0,2 则返回全部记录的a字段的合计，limit不起作用。</p>
<p>但是去掉sum函数的话， select a from test_table order by b desc limit 1,2 能够选择出需要的行。</p>
<p>为什么？ 来自 MySQL 官方站点论坛的解释：</p>
<blockquote><p>The LIMIT clause affects only the number of rows returned, and this query in fact only returns one row. You might want to try something like this:</p></blockquote>
<blockquote>
<blockquote><p><font face="monospace"> SELECT sum(quantity)</font><br />
<font face="monospace"> FROM (SELECT quantity</font><br />
<font face="monospace"> FROM stock_card</font><br />
<font face="monospace"> LIMIT 0,2</font><br />
<font face="monospace"> ) AS subquery;</font></p></blockquote>
</blockquote>


<p>Related posts:<ol><li><a href='http://blog.xiping.me/2010/07/orx_tutorial_cn_basic.html' rel='bookmark' title='Permanent Link: [译] Orx教程：0.Basic'>[译] Orx教程：0.Basic</a></li>
<li><a href='http://blog.xiping.me/2009/11/%e7%ae%97%e6%b3%95%e8%a7%a3%e9%a2%98%e6%80%9d%e8%80%83%e8%bf%87%e7%a8%8b.html' rel='bookmark' title='Permanent Link: 算法解题思考过程[总结]'>算法解题思考过程[总结]</a></li>
<li><a href='http://blog.xiping.me/2009/05/vim-usage.html' rel='bookmark' title='Permanent Link: Vim 快捷键'>Vim 快捷键</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://blog.xiping.me/2008/06/%e6%9c%89%e5%85%b3-sum%e4%b8%8elimit%e7%bb%84%e5%90%88%e4%bd%bf%e7%94%a8%e6%97%b6%e7%9a%84%e9%97%ae%e9%a2%98.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>闻网友晒见父母的次数有感</title>
		<link>http://blog.xiping.me/2007/11/%e9%97%bb%e7%bd%91%e5%8f%8b%e6%99%92%e8%a7%81%e7%88%b6%e6%af%8d%e7%9a%84%e6%ac%a1%e6%95%b0%e6%9c%89%e6%84%9f.html</link>
		<comments>http://blog.xiping.me/2007/11/%e9%97%bb%e7%bd%91%e5%8f%8b%e6%99%92%e8%a7%81%e7%88%b6%e6%af%8d%e7%9a%84%e6%ac%a1%e6%95%b0%e6%9c%89%e6%84%9f.html#comments</comments>
		<pubDate>Tue, 06 Nov 2007 00:45:45 +0000</pubDate>
		<dc:creator>西坪</dc:creator>
				<category><![CDATA[@生活]]></category>

		<guid isPermaLink="false">http://www.feihoo.com/archives/12</guid>
		<description><![CDATA[在公司内网看到一篇文章，讨论网友晒见父母的次数。阅后，心里戚戚然。
我回复道：
        我早算过了，如果不能把爸爸妈妈接到北京来，我基本上一年见父母一次吧。就像我爸爸说的，他由于打工待遇微薄，春节时人潮太多，工厂放假又少，以前一般要两年才能回家见爷爷一次。现在爷爷八十多了，还是只能一年见一次。想起这些怎么不心里戚戚然。
啊，咱们公司的年假，是最好的一项福利待遇了。我喜欢。
原文如下：
 				近日，一些网友在一起聊自己的父母。有网友表示：以前总觉得孝敬爸妈的机会还很多，可仔细一算，爸妈能再活二十年，我每年平均回去一两次，跟他们在一起最多就30来次；假若他们只能再活十年，跟他们见面的机会就只有十多次了。
我们曾经对网上的“晒客”们有过非议，认为他们很无聊。“晒工资”自己的工资也涨不了，“晒隐私”你没有那些明星多。可当我看到“父母年迈我们还能见多少面”的帖子时，竟然被深深地打动了。
这是一个令人感到心酸的话题。“父母年迈我们还能见多少面”就像是一根针插进我们感情的胸口，触动我们那麻木的神经，每个人都会感到沉重和自 责。当我们用“多少”这个词儿来标注与父母见面的次数时，才发现这份感情原来是那么的宝贵，而我们却无情的挥霍。“多少”不是多而是少，我们与父母见面的 次数实在是太少了。
面对年迈的父母，我们或许还没有来得及去想这样一个沉重的话题。因为我们一直以为自己还是个孩子。我们的内心深处是不希望父母老去的，希望他们永远年轻，而人生百年又有谁能避免呢？
曾几何时，我们自以为自己已经长大，不再需要父母的呵护；曾几何时，我们厌倦了父母的唠叨，听不进老人的规劝；曾几何时，我们来去匆匆，把家 当作了客栈。而只有当我们静下心来，认真地思考“我们还能见年迈的父母多少面”这样的问题时，才发现自己依然是年幼无知。虽然我们已然是别人的父亲或母 亲。
古代说“父母在，不远游。”可现代社会又有几人能与父母长相厮守，床前尽孝呢？对于在远方的游子，一年也许就有在春节时，才能回家见上父母一 面。即使生活在一个城市，真正与父母在一起的时间又有多少呢？我们嘴上喊着“忙，没时间，加班……”，可宁愿在家上网聊天，出门与朋友喝酒。我们有几个人 还记得父母的生日，会记得上次回家是几月几号，我们多久没和父母聊天了？而还有一些自诩为“月光一族”的朋友，竟然还跟年迈的父母伸手要钱。
不要责怪这位网友的残酷，他用自己的冷静告诉了我们这样一个现实的问题。珍惜和父母在一起的时间吧，不要嫌弃父母的唠叨，多同他们聊聊天；不要嫌弃父母的土气，常回家看看；不要忘了父母的养育，让他们有一个祥和的晚年。
与那些“晒工资”、“晒隐私”、“晒家庭”的晒客相比，我们真应该为这位网友叫好，因为他教会了我们如何珍惜，如何不丢弃孝敬老人这样的传统美德。


No related posts.


No related posts.]]></description>
			<content:encoded><![CDATA[<p>在公司内网看到一篇文章，讨论网友晒见父母的次数。阅后，心里戚戚然。</p>
<p>我回复道：</p>
<blockquote><p>        我早算过了，如果不能把爸爸妈妈接到北京来，我基本上一年见父母一次吧。就像我爸爸说的，他由于打工待遇微薄，春节时人潮太多，工厂放假又少，以前一般要两年才能回家见爷爷一次。现在爷爷八十多了，还是只能一年见一次。想起这些怎么不心里戚戚然。<br />
啊，咱们公司的年假，是最好的一项福利待遇了。我喜欢。</p></blockquote>
<p>原文如下：</p>
<blockquote><p> 				近日，一些网友在一起聊自己的父母。有网友表示：以前总觉得孝敬爸妈的机会还很多，可仔细一算，爸妈能再活二十年，我每年平均回去一两次，跟他们在一起最多就30来次；假若他们只能再活十年，跟他们见面的机会就只有十多次了。</p>
<p>我们曾经对网上的“晒客”们有过非议，认为他们很无聊。“晒工资”自己的工资也涨不了，“晒隐私”你没有那些明星多。可当我看到“父母年迈我们还能见多少面”的帖子时，竟然被深深地打动了。</p>
<p>这是一个令人感到心酸的话题。“父母年迈我们还能见多少面”就像是一根针插进我们感情的胸口，触动我们那麻木的神经，每个人都会感到沉重和自 责。当我们用“多少”这个词儿来标注与父母见面的次数时，才发现这份感情原来是那么的宝贵，而我们却无情的挥霍。“多少”不是多而是少，我们与父母见面的 次数实在是太少了。</p>
<p>面对年迈的父母，我们或许还没有来得及去想这样一个沉重的话题。因为我们一直以为自己还是个孩子。我们的内心深处是不希望父母老去的，希望他们永远年轻，而人生百年又有谁能避免呢？</p>
<p>曾几何时，我们自以为自己已经长大，不再需要父母的呵护；曾几何时，我们厌倦了父母的唠叨，听不进老人的规劝；曾几何时，我们来去匆匆，把家 当作了客栈。而只有当我们静下心来，认真地思考“我们还能见年迈的父母多少面”这样的问题时，才发现自己依然是年幼无知。虽然我们已然是别人的父亲或母 亲。</p>
<p>古代说“父母在，不远游。”可现代社会又有几人能与父母长相厮守，床前尽孝呢？对于在远方的游子，一年也许就有在春节时，才能回家见上父母一 面。即使生活在一个城市，真正与父母在一起的时间又有多少呢？我们嘴上喊着“忙，没时间，加班……”，可宁愿在家上网聊天，出门与朋友喝酒。我们有几个人 还记得父母的生日，会记得上次回家是几月几号，我们多久没和父母聊天了？而还有一些自诩为“月光一族”的朋友，竟然还跟年迈的父母伸手要钱。</p>
<p>不要责怪这位网友的残酷，他用自己的冷静告诉了我们这样一个现实的问题。珍惜和父母在一起的时间吧，不要嫌弃父母的唠叨，多同他们聊聊天；不要嫌弃父母的土气，常回家看看；不要忘了父母的养育，让他们有一个祥和的晚年。</p>
<p>与那些“晒工资”、“晒隐私”、“晒家庭”的晒客相比，我们真应该为这位网友叫好，因为他教会了我们如何珍惜，如何不丢弃孝敬老人这样的传统美德。</p></blockquote>


<p>No related posts.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.xiping.me/2007/11/%e9%97%bb%e7%bd%91%e5%8f%8b%e6%99%92%e8%a7%81%e7%88%b6%e6%af%8d%e7%9a%84%e6%ac%a1%e6%95%b0%e6%9c%89%e6%84%9f.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Sun科技日归来</title>
		<link>http://blog.xiping.me/2007/11/sun%e7%a7%91%e6%8a%80%e6%97%a5%e5%bd%92%e6%9d%a5.html</link>
		<comments>http://blog.xiping.me/2007/11/sun%e7%a7%91%e6%8a%80%e6%97%a5%e5%bd%92%e6%9d%a5.html#comments</comments>
		<pubDate>Thu, 01 Nov 2007 15:55:07 +0000</pubDate>
		<dc:creator>西坪</dc:creator>
				<category><![CDATA[@生活]]></category>

		<guid isPermaLink="false">http://www.feihoo.com/archives/9</guid>
		<description><![CDATA[ 
今天参加了Sun的2007北京科技日。这是我第一次参加类似的会议，感觉很有意思。


No related posts.


No related posts.]]></description>
			<content:encoded><![CDATA[<p> <a href="http://blog.feihoo.com/wp-content/uploads/2007/11/std08_web_header.jpg" title="std08_web_header.jpg"><img src="http://blog.feihoo.com/wp-content/uploads/2007/11/std08_web_header.jpg" alt="std08_web_header.jpg" /></a></p>
<p>今天参加了Sun的2007北京科技日。这是我第一次参加类似的会议，感觉很有意思。</p>


<p>No related posts.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.xiping.me/2007/11/sun%e7%a7%91%e6%8a%80%e6%97%a5%e5%bd%92%e6%9d%a5.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

