<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	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/"
	>

<channel>
	<title>Sipo Blog</title>
	<atom:link href="http://www.dc9.cn/feed" rel="self" type="application/rss+xml" />
	<link>http://www.dc9.cn</link>
	<description>尺蠖居</description>
	<lastBuildDate>Wed, 16 May 2012 09:23:31 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>爆痘研究</title>
		<link>http://www.dc9.cn/post/658.html</link>
		<comments>http://www.dc9.cn/post/658.html#comments</comments>
		<pubDate>Wed, 16 May 2012 09:23:31 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[未分类]]></category>

		<guid isPermaLink="false">http://www.dc9.cn/?p=658</guid>
		<description><![CDATA[最近脸上长包。毁容了。虽然本来就没容。 于是做了一些深入研究。 痘痘和血睾酮的关系就是，血睾酮大量分泌，然后导致皮脂腺分泌，然后就长痘了。看到一篇文章。说的是运动与血睾酮的关系。 &#8212;&#8212;&#8212;-持续更新&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; 众多研究表明，长时间运动训练或力竭性运动会使血睾酮水平降低，但是引起这种变化的机制还不十分清楚。其可能的原因是多方面的： (1) 长期激烈运动使骨骼肌增加了睾酮的肝外消耗。 (2) 训练使得机体在应急情况下睾丸大量分泌睾酮，应激后睾丸暂时处于 “耗竭状态”，也可能是睾丸本身的功能障碍导致睾酮分泌、合成减少。 (3) 血睾酮浓度与其降解率有关。 (4) 睾酮分泌水平变化在很大程度上受垂体分泌的黄体生成紊(LH)影响。 (5) 长期运动训练后游离睾酮下降幅度超过了总血皋酮下降的幅度，而血液中只有游离睾酮才具有直接生物活性作用，提示游离睾酮大幅度降低对运动性低血睾酮更具有直接意义 (6) 血睾酮下降由排泄引起。 (7) 缺硒引起血清睾酮和睾丸睾酮下降。 (8) 缺锌引起血清睾酮和睾丸睾酮含量降低。]]></description>
			<content:encoded><![CDATA[<p>最近脸上长包。毁容了。虽然本来就没容。</p>
<p>于是做了一些深入研究。</p>
<p>痘痘和血睾酮的关系就是，血睾酮大量分泌，然后导致皮脂腺分泌，然后就长痘了。看到一篇文章。说的是运动与血睾酮的关系。</p>
<p>&#8212;&#8212;&#8212;-持续更新&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;</p>
<p>众多研究表明，长时间运动训练或力竭性运动会使血睾酮水平降低，但是引起这种变化的机制还不十分清楚。其可能的原因是多方面的：</p>
<p>(1) 长期激烈运动使骨骼肌增加了睾酮的肝外消耗。</p>
<p>(2) 训练使得机体在应急情况下睾丸大量分泌睾酮，应激后睾丸暂时处于 “耗竭状态”，也可能是睾丸本身的功能障碍导致睾酮分泌、合成减少。</p>
<p>(3) 血睾酮浓度与其降解率有关。</p>
<p>(4) 睾酮分泌水平变化在很大程度上受垂体分泌的黄体生成紊(LH)影响。</p>
<p>(5) 长期运动训练后游离睾酮下降幅度超过了总血皋酮下降的幅度，而血液中只有游离睾酮才具有直接生物活性作用，提示游离睾酮大幅度降低对运动性低血睾酮更具有直接意义</p>
<p>(6) 血睾酮下降由排泄引起。</p>
<p>(7) 缺硒引起血清睾酮和睾丸睾酮下降。</p>
<p>(8) 缺锌引起血清睾酮和睾丸睾酮含量降低。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dc9.cn/post/658.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>时光小偷</title>
		<link>http://www.dc9.cn/post/655.html</link>
		<comments>http://www.dc9.cn/post/655.html#comments</comments>
		<pubDate>Wed, 16 May 2012 08:14:53 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[未分类]]></category>

		<guid isPermaLink="false">http://www.dc9.cn/?p=655</guid>
		<description><![CDATA[过去像一滴汗 静静地蒸发在马路上 偶尔当心很烦 我总是爱穿过捷运站 看着世界变换 时光像小偷拿走眼泪 从不同的地方 也许吧 泪滴在琴上 所以我有了歌能唱 回忆很美 未来很慢 我的故事因此写到一半 风吹着 我跑向远方 我知道爱也甜也酸 人要学会 停止流浪 我也一样 过去像一滴汗 静静地蒸发在马路上 偶尔当心很烦 我总是爱穿过捷运站 看着世界变幻 时光像小偷拿走眼泪 从不同的地方 也许吧 泪滴在琴上 所以我有了歌能唱 回忆很美 未来很慢 我的故事因此写到一半 风吹着 我跑向远方 我知道爱也甜也酸 人要学会 停止流浪 我也一样 天空从黑到白 继续地转换 &#8230; <a href="http://www.dc9.cn/post/655.html">继续阅读 <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>过去像一滴汗 静静地蒸发在马路上</p>
<div></div>
<p>偶尔当心很烦 我总是爱穿过捷运站</p>
<div></div>
<p>看着世界变换 时光像小偷拿走眼泪</p>
<div></div>
<p>从不同的地方</p>
<div></div>
<p>也许吧 泪滴在琴上 所以我有了歌能唱</p>
<div></div>
<p>回忆很美 未来很慢</p>
<div></div>
<p>我的故事因此写到一半</p>
<div></div>
<p>风吹着 我跑向远方 我知道爱也甜也酸</p>
<div></div>
<p>人要学会 停止流浪 我也一样</p>
<div></div>
<p>过去像一滴汗 静静地蒸发在马路上</p>
<div></div>
<p>偶尔当心很烦 我总是爱穿过捷运站</p>
<div></div>
<p>看着世界变幻 时光像小偷拿走眼泪</p>
<div></div>
<p>从不同的地方</p>
<div></div>
<p>也许吧 泪滴在琴上 所以我有了歌能唱</p>
<div></div>
<p>回忆很美 未来很慢</p>
<div></div>
<p>我的故事因此写到一半</p>
<div></div>
<p>风吹着 我跑向远方 我知道爱也甜也酸</p>
<div></div>
<p>人要学会 停止流浪 我也一样</p>
<div></div>
<p>天空从黑到白 继续地转换</p>
<div></div>
<p>热闹后的孤单 让人更加了解珍惜平凡</p>
<div></div>
<p>泪滴在琴上 有了歌能唱</p>
<div></div>
<p>回忆很美 未来很慢</p>
<div></div>
<p>我的故事因此写到一半</p>
<div></div>
<p>风吹着 我跑向远方 我知道爱也甜也酸</p>
<div></div>
<p>人要学会 停止流浪 我也一样</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dc9.cn/post/655.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>JS的Trim实现（多种）</title>
		<link>http://www.dc9.cn/post/646.html</link>
		<comments>http://www.dc9.cn/post/646.html#comments</comments>
		<pubDate>Sun, 13 May 2012 13:37:09 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[未分类]]></category>

		<guid isPermaLink="false">http://www.dc9.cn/?p=646</guid>
		<description><![CDATA[The analysis Although there are 11 rows in the table above, they are only the most notable (for various reasons) of about 20 versions I wrote and benchmarked against various types of strings. The following analysis is based on testing &#8230; <a href="http://www.dc9.cn/post/646.html">继续阅读 <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>The analysis<br />
Although there are 11 rows in the table above, they are only the most notable (for various reasons) of about 20 versions I wrote and benchmarked against various types of strings. The following analysis is based on testing in Firefox 2.0.0.4, although I have noted where there are major differences in IE6.</p>
<p>1.<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />
return str.replace(/^\s\s*/, ”).replace(/\s\s*$/, ”);<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br />
All things considered, this is probably the best all-around approach. Its speed advantage is most notable with long strings — when efficiency matters. The speed is largely due to a number of optimizations internal to JavaScript regex interpreters which the two discrete regexes here trigger. Specifically, the pre-check of required character and start of string anchor optimizations, possibly among others.</p>
<p>2.<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br />
return str.replace(/^\s+/, ”).replace(/\s+$/, ”);<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br />
Very similar to trim1 (above), but a little slower since it doesn&#8217;t trigger all of the same optimizations.</p>
<p>3.<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br />
return str.substring(Math.max(str.search(/\S/), 0), str.search(/\S\s*$/) + 1);<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br />
This is often faster than the following methods, but slower than the above two. Its speed comes from its use of simple, character-index lookups.</p>
<p>4.<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br />
return str.replace(/^\s+|\s+$/g, ”);<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br />
This commonly thought up approach is easily the most frequently used in JavaScript libraries today. It is generally the fastest implementation of the bunch only when working with short strings which don&#8217;t include leading or trailing whitespace. This minor advantage is due in part to the initial-character discrimination optimization it triggers. While this is a relatively decent performer, it&#8217;s slower than the three methods above when working with longer strings, because the top-level alternation prevents a number of optimizations which could otherwise kick in.</p>
<p>5.<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br />
str = str.match(/\S+(?:\s+\S+)*/);<br />
return str ? str[0] : ”;<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br />
This is generally the fastest method when working with empty or whitespace-only strings, due to the pre-check of required character optimization it triggers. Note: In IE6, this can be quite slow when working with longer strings.</p>
<p>6.<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br />
return str.replace(/^\s*(\S*(\s+\S+)*)\s*$/, &#8216;$1&#8242;);<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br />
This is a relatively common approach, popularized in part by some leading JavaScripters. It&#8217;s similar in approach (but inferior) to trim8. There&#8217;s no good reason to use this in JavaScript, especially since it can be very slow in IE6.</p>
<p>7.<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br />
return str.replace(/^\s*(\S*(?:\s+\S+)*)\s*$/, &#8216;$1&#8242;);<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br />
The same as trim6, but a bit faster due to the use of a non-capturing group (which doesn&#8217;t work in IE 5.0 and lower). Again, this can be slow in IE6.</p>
<p>8.<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br />
return str.replace(/^\s*((?:[\S\s]*\S)?)\s*$/, &#8216;$1&#8242;);<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br />
This uses a simple, single-pass, greedy approach. In IE6, this is crazy fast! The performance difference indicates that IE has superior optimization for quantification of “any character” tokens.</p>
<p>9.<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br />
return str.replace(/^\s*([\S\s]*?)\s*$/, &#8216;$1&#8242;);<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br />
This is generally the fastest with very short strings which contain both non-space characters and edge whitespace. This minor advantage is due to the simple, single-pass, lazy approach it uses. Like trim8, this is significantly faster in IE6 than Firefox 2.<br />
Since I&#8217;ve seen the following additional implementation in one library, I&#8217;ll include it here as a warning:<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br />
return str.replace(/^\s*([\S\s]*)\b\s*$/, &#8216;$1&#8242;);<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br />
Although the above is sometimes the fastest method when working with short strings which contain both non-space characters and edge whitespace, it performs very poorly with long strings which contain numerous word boundaries, and it&#8217;s terrible (!) with long strings comprised of nothing but whitespace, since that triggers an exponentially increasing amount of backtracking. Do not use.</p>
<p>A different endgame<br />
There are two methods in the table at the top of this post which haven&#8217;t been covered yet. For those, I&#8217;ve used a non-regex and hybrid approach.</p>
<p>After comparing and analyzing all of the above, I wondered how an implementation which used no regular expressions would perform. Here&#8217;s what I tried:</p>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br />
function trim10 (str) {<br />
	var whitespace = &#8216; \n\r\t\f\x0b\xa0\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u2028\u2029\u3000&#8242;;<br />
	for (var i = 0; i < str.length; i++) {<br />
		if (whitespace.indexOf(str.charAt(i)) === -1) {<br />
			str = str.substring(i);<br />
			break;<br />
		}<br />
	}<br />
	for (i = str.length - 1; i >= 0; i&#8211;) {<br />
		if (whitespace.indexOf(str.charAt(i)) === -1) {<br />
			str = str.substring(0, i + 1);<br />
			break;<br />
		}<br />
	}<br />
	return whitespace.indexOf(str.charAt(0)) === -1 ? str : ”;<br />
}<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br />
How does that perform? Well, with long strings which do not contain excessive leading or trailing whitespace, it blows away the competition (except against trim1/2/8 in IE, which are already insanely fast there).</p>
<p>Does that mean regular expressions are slow in Firefox? No, not at all. The issue here is that although regexes are very well suited for trimming leading whitespace, apart from the .NET library (which offers a somewhat-mysterious “backwards matching” mode), they don&#8217;t really provide a method to jump to the end of a string without even considering previous characters. However, the non-regex-reliant trim10 function does just that, with the second loop working backwards from the end of the string until it finds a non-whitespace character.</p>
<p>Knowing that, what if we created a hybrid implementation which combined a regex&#8217;s universal efficiency at trimming leading whitespace with the alternative method&#8217;s speed at removing trailing characters?</p>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br />
function trim11 (str) {<br />
	str = str.replace(/^\s+/, ”);<br />
	for (var i = str.length &#8211; 1; i >= 0; i&#8211;) {<br />
		if (/\S/.test(str.charAt(i))) {<br />
			str = str.substring(0, i + 1);<br />
			break;<br />
		}<br />
	}<br />
	return str;<br />
}<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br />
Although the above is a bit slower than trim10 with some strings, it uses significantly less code and is still lightning fast. Plus, with strings which contain a lot of leading whitespace (which includes strings comprised of nothing but whitespace), it&#8217;s much faster than trim10.</p>
<p>In conclusion…<br />
Since the differences between the implementations cross-browser and when used with different data are both complex and nuanced (none of them are faster than all the others with any data you can throw at it), here are my general recommendations for a trim method:</p>
<p>Use trim1 if you want a general-purpose implementation which is fast cross-browser.<br />
Use trim11 if you want to handle long strings exceptionally fast in all browsers.<br />
To test all of the above implementations for yourself, try my very rudimentary benchmarking page. Background processing can cause the results to be severely skewed, so run the test a number of times (regardless of how many iterations you specify) and only consider the fastest results (since averaging the cost of background interference is not very enlightening).</p>
<p>As a final note, although some people like to cache regular expressions (e.g. using global variables) so they can be used repeatedly without recompilation, IMO this does not make much sense for a trim method. All of the above regexes are so simple that they typically take no more than a nanosecond to compile. Additionally, some browsers automatically cache the most recently used regexes, so a typical loop which uses trim and doesn&#8217;t contain a bunch of other regexes might not encounter recompilation anyway.</p>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;</p>
<p>Edit (2008-02-04): Shortly after posting this I realized trim10/11 could be better written. Several people have also posted improved versions in the comments. Here&#8217;s what I use now, which takes the trim11-style hybrid approach:<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br />
function trim12 (str) {<br />
	var	str = str.replace(/^\s\s*/, ”),<br />
		ws = /\s/,<br />
		i = str.length;<br />
	while (ws.test(str.charAt(&#8211;i)));<br />
	return str.slice(0, i + 1);<br />
}<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dc9.cn/post/646.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>碎碎念</title>
		<link>http://www.dc9.cn/post/648.html</link>
		<comments>http://www.dc9.cn/post/648.html#comments</comments>
		<pubDate>Sun, 13 May 2012 03:39:24 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[未分类]]></category>

		<guid isPermaLink="false">http://www.dc9.cn/?p=648</guid>
		<description><![CDATA[生命就像 一条大河 时而宁静 时而疯狂 现实就像 一把枷锁 把我捆住 无法挣脱 这谜样的生活锋利如刀 一次次将我重伤 我知道我要的那种幸福 就在那片更高的天空 我要飞得更高 飞得更高 狂风一样舞蹈 挣脱怀抱 我要飞得更高 飞得更高 翅膀卷起风暴 心生呼啸 飞得更高 一直在飞 一直在找 可我发现 无法找到 若真想要 是一次解放 要先剪碎 这有过的往 我要的一种生命更灿烂 我要的一片天空更蔚蓝 我知道我要的那种幸福 就在那片更高的天空]]></description>
			<content:encoded><![CDATA[<p>生命就像 一条大河<br />
时而宁静 时而疯狂<br />
现实就像 一把枷锁<br />
把我捆住 无法挣脱<br />
这谜样的生活锋利如刀<br />
一次次将我重伤<br />
我知道我要的那种幸福<br />
就在那片更高的天空</p>
<p>我要飞得更高<br />
飞得更高<br />
狂风一样舞蹈<br />
挣脱怀抱<br />
我要飞得更高<br />
飞得更高<br />
翅膀卷起风暴<br />
心生呼啸<br />
飞得更高</p>
<p>一直在飞 一直在找<br />
可我发现 无法找到<br />
若真想要 是一次解放<br />
要先剪碎 这有过的往<br />
我要的一种生命更灿烂<br />
我要的一片天空更蔚蓝<br />
我知道我要的那种幸福<br />
就在那片更高的天空</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dc9.cn/post/648.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ext.XTemplate</title>
		<link>http://www.dc9.cn/post/643.html</link>
		<comments>http://www.dc9.cn/post/643.html#comments</comments>
		<pubDate>Thu, 10 May 2012 14:35:42 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[未分类]]></category>

		<guid isPermaLink="false">http://www.dc9.cn/?p=643</guid>
		<description><![CDATA[Sample Data This is the data object used for reference in each code example: var data = { name: 'Tommy Maintz', title: 'Lead Developer', company: 'Sencha Inc.', email: 'tommy@sencha.com', address: '5 Cups Drive', city: 'Palo Alto', state: 'CA', zip: '44102', &#8230; <a href="http://www.dc9.cn/post/643.html">继续阅读 <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<ul>
<li id="ext-gen1175"><strong><span id="ext-gen1167" style="text-decoration: underline;">Sample Data</span></strong>
<div id="ext-gen1168">
<p id="ext-gen1097">This is the data object used for reference in each code example:</p>
<pre id="ext-gen1098"><code>var data = {
name: 'Tommy Maintz',
title: 'Lead Developer',
company: 'Sencha Inc.',
email: 'tommy@sencha.com',
address: '5 Cups Drive',
city: 'Palo Alto',
state: 'CA',
zip: '44102',
drinks: ['Coffee', 'Soda', 'Water'],
kids: [{
        name: 'Joshua',
        age:3
    },{
        name: 'Matthew',
        age:2
    },{
        name: 'Solomon',
        age:0
}]
};
 </code></pre>
</div>
</li>
<li><strong><span style="text-decoration: underline;">Auto filling of arrays</span></strong>
<div id="ext-gen1164">
<p>The <strong><tt>tpl</tt></strong> tag and the <strong><tt>for</tt></strong> operator are used to process the provided data object:</p>
<ul>
<li>If the value specified in <tt>for</tt> is an array, it will auto-fill, repeating the template block inside the <tt>tpl</tt> tag for each item in the array.</li>
<li>If <tt>for="."</tt> is specified, the data object provided is examined.</li>
<li>While processing an array, the special variable <tt>{#}</tt> will provide the current array index + 1 (starts at 1, not 0).</li>
</ul>
<pre><code>&lt;tpl <strong>for</strong>="."&gt;...&lt;/tpl&gt;       // loop through array at root node
&lt;tpl <strong>for</strong>="foo"&gt;...&lt;/tpl&gt;     // loop through array at foo node
&lt;tpl <strong>for</strong>="foo.bar"&gt;...&lt;/tpl&gt; // loop through array at foo.bar node
 </code></pre>
<p>Using the sample data above:</p>
<pre id="ext-gen1100"><code>var tpl = new Ext.XTemplate(
    '&lt;p&gt;Kids: ',
    '&lt;tpl <strong>for</strong>="."&gt;',       // process the data.kids node
        '&lt;p&gt;{#}. {name}&lt;/p&gt;',  // use current array index to autonumber
    '&lt;/tpl&gt;&lt;/p&gt;'
);
tpl.overwrite(panel.body, data.kids); // pass the kids property of the data object
 </code></pre>
<p>An example illustrating how the <strong><tt>for</tt></strong> property can be leveraged to access specified members of the provided data object to populate the template:</p>
<pre id="ext-gen1102"><code>var tpl = new Ext.XTemplate(
    '&lt;p&gt;Name: {name}&lt;/p&gt;',
    '&lt;p&gt;Title: {title}&lt;/p&gt;',
    '&lt;p&gt;Company: {company}&lt;/p&gt;',
    '&lt;p&gt;Kids: ',
    '&lt;tpl <strong>for="kids"</strong>&gt;',     // interrogate the kids property within the data
        '&lt;p&gt;{name}&lt;/p&gt;',
    '&lt;/tpl&gt;&lt;/p&gt;'
);
tpl.overwrite(panel.body, data);  // pass the root node of the data object
 </code></pre>
<p>Flat arrays that contain values (and not objects) can be auto-rendered using the special <strong><tt>{.}</tt></strong> variable inside a loop. This variable will represent the value of the array at the current index:</p>
<pre id="ext-gen1103"><code>var tpl = new Ext.XTemplate(
    '&lt;p&gt;{name}\'s favorite beverages:&lt;/p&gt;',
    '&lt;tpl for="drinks"&gt;',
        '&lt;div&gt; - {.}&lt;/div&gt;',
    '&lt;/tpl&gt;'
);
tpl.overwrite(panel.body, data);
 </code></pre>
<p>When processing a sub-template, for example while looping through a child array, you can access the parent object&#8217;s members via the <strong><tt>parent</tt></strong> object:</p>
<pre id="ext-gen1104"><code>var tpl = new Ext.XTemplate(
    '&lt;p&gt;Name: {name}&lt;/p&gt;',
    '&lt;p&gt;Kids: ',
    '&lt;tpl for="kids"&gt;',
        '&lt;tpl if="age &amp;gt; 1"&gt;',
            '&lt;p&gt;{name}&lt;/p&gt;',
            '&lt;p&gt;Dad: {<strong>parent</strong>.name}&lt;/p&gt;',
        '&lt;/tpl&gt;',
    '&lt;/tpl&gt;&lt;/p&gt;'
);
tpl.overwrite(panel.body, data);
 </code></pre>
</div>
</li>
<li><strong><span style="text-decoration: underline;">Conditional processing with basic comparison operators</span></strong>
<div>
<p>The <strong><tt>tpl</tt></strong> tag and the <strong><tt>if</tt></strong> operator are used to provide conditional checks for deciding whether or not to render specific parts of the template. Notes:</p>
<div>
<ul>
<li id="ext-gen1161">Double quotes must be encoded if used within the conditional</li>
<li>There is no <tt>else</tt> operator — if needed, two opposite <tt>if</tt> statements should be used.</li>
</ul>
</div>
<pre id="ext-gen1113"><code>&lt;tpl if="age &gt; 1 &amp;&amp; age &lt; 10"&gt;Child&lt;/tpl&gt;
&lt;tpl if="age &gt;= 10 &amp;&amp; age &lt; 18"&gt;Teenager&lt;/tpl&gt;
&lt;tpl <strong>if</strong>="this.isGirl(name)"&gt;...&lt;/tpl&gt;
&lt;tpl <strong>if</strong>="id==\'download\'"&gt;...&lt;/tpl&gt;
&lt;tpl <strong>if</strong>="needsIcon"&gt;&lt;img src="{icon}" class="{iconCls}"/&gt;&lt;/tpl&gt;
// no good:
&lt;tpl if="name == "Tommy""&gt;Hello&lt;/tpl&gt;
// encode " if it is part of the condition, e.g.
&lt;tpl if="name == &amp;quot;Tommy&amp;quot;"&gt;Hello&lt;/tpl&gt;
</code></pre>
<p>Using the sample data above:</p>
<pre id="ext-gen1140"><code>var tpl = new Ext.XTemplate(
    '&lt;p&gt;Name: {name}&lt;/p&gt;',
    '&lt;p&gt;Kids: ',
    '&lt;tpl for="kids"&gt;',
        '&lt;tpl if="age &amp;gt; 1"&gt;',
            '&lt;p&gt;{name}&lt;/p&gt;',
        '&lt;/tpl&gt;',
    '&lt;/tpl&gt;&lt;/p&gt;'
);
tpl.overwrite(panel.body, data);
 </code></pre>
</div>
</li>
<li><strong><span style="text-decoration: underline;">Basic math support</span></strong>
<div id="ext-gen1141">
<p>The following basic math operators may be applied directly on numeric data values:</p>
<pre>+ - * /</pre>
<p>For example:</p>
<pre id="ext-gen1142"><code>var tpl = new Ext.XTemplate(
    '&lt;p&gt;Name: {name}&lt;/p&gt;',
    '&lt;p&gt;Kids: ',
    '&lt;tpl for="kids"&gt;',
        '&lt;tpl if="age &amp;gt; 1"&gt;',  // &lt;-- Note that the &gt; is encoded
            '&lt;p&gt;{#}: {name}&lt;/p&gt;',  // &lt;-- Auto-number each item
            '&lt;p&gt;In 5 Years: {age+5}&lt;/p&gt;',  // &lt;-- Basic math
            '&lt;p&gt;Dad: {parent.name}&lt;/p&gt;',
        '&lt;/tpl&gt;',
    '&lt;/tpl&gt;&lt;/p&gt;'
);
tpl.overwrite(panel.body, data);
 </code></pre>
</div>
</li>
<li><strong><span style="text-decoration: underline;">Execute arbitrary inline code with special built-in template variables</span></strong>
<div>
<p>Anything between <code>{[ ... ]}</code> is considered code to be executed in the scope of the template. There are some special variables available in that code:</p>
<ul>
<li id="ext-gen1158"><strong><tt>values</tt></strong>: The values in the current scope. If you are using scope changing sub-templates, you can change what <tt>values</tt> is.</li>
<li><strong><tt>parent</tt></strong>: The scope (values) of the ancestor template.</li>
<li><strong><tt>xindex</tt></strong>: If you are in a looping template, the index of the loop you are in (1-based).</li>
<li><strong><tt>xcount</tt></strong>: If you are in a looping template, the total length of the array you are looping.</li>
</ul>
<p>This example demonstrates basic row striping using an inline code block and the <tt>xindex</tt>variable:</p>
<pre id="ext-gen1144"><code>var tpl = new Ext.XTemplate(
    '&lt;p&gt;Name: {name}&lt;/p&gt;',
    '&lt;p&gt;Company: {[values.company.toUpperCase() + ", " + values.title]}&lt;/p&gt;',
    '&lt;p&gt;Kids: ',
    '&lt;tpl for="kids"&gt;',
        '&lt;diveven" : "odd"]}"&gt;',
        '{name}',
        '&lt;/div&gt;',
    '&lt;/tpl&gt;&lt;/p&gt;'
 );
tpl.overwrite(panel.body, data);
 </code></pre>
</div>
</li>
<li><strong><span style="text-decoration: underline;">Template member functions</span></strong>
<div>
<p id="ext-gen1157">One or more member functions can be specified in a configuration object passed into the XTemplate constructor for more complex processing:</p>
<pre id="ext-gen1145"><code>var tpl = new Ext.XTemplate(
    '&lt;p&gt;Name: {name}&lt;/p&gt;',
    '&lt;p&gt;Kids: ',
    '&lt;tpl for="kids"&gt;',
        '&lt;tpl if="this.isGirl(name)"&gt;',
            '&lt;p&gt;Girl: {name} - {age}&lt;/p&gt;',
        '&lt;/tpl&gt;',
         // use opposite if statement to simulate 'else' processing:
        '&lt;tpl if="this.isGirl(name) == false"&gt;',
            '&lt;p&gt;Boy: {name} - {age}&lt;/p&gt;',
        '&lt;/tpl&gt;',
        '&lt;tpl if="this.isBaby(age)"&gt;',
            '&lt;p&gt;{name} is a baby!&lt;/p&gt;',
        '&lt;/tpl&gt;',
    '&lt;/tpl&gt;&lt;/p&gt;',
    {
        // XTemplate configuration:
        compiled: true,
        // member functions:
        isGirl: function(name){
           return name == 'Sara Grace';
        },
        isBaby: function(age){
           return age &lt; 1;
        }
    }
);
tpl.overwrite(panel.body, data)</code></pre>
</div>
</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.dc9.cn/post/643.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>突然回忆起最爱的大话西游……</title>
		<link>http://www.dc9.cn/post/641.html</link>
		<comments>http://www.dc9.cn/post/641.html#comments</comments>
		<pubDate>Thu, 10 May 2012 09:58:27 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[未分类]]></category>

		<guid isPermaLink="false">http://www.dc9.cn/?p=641</guid>
		<description><![CDATA[       至尊宝：干什么？ 　　紫霞：我的心跳得好厉害！ 　　至尊宝：那怎么办？ 　　紫霞：来！ 　　至尊宝：干什么嘛？ 　　紫霞：我的意中人就在附近。 　　至尊宝：你看到他了？ 　　紫霞：没有，因为我的紫青宝剑发出“嘟－嘟－”的讯号。 　　至尊宝：哪儿来的嘟嘟声？ 　　紫霞：嘟－嘟－嘟－！对不对？ 　　至尊宝：你嘟的，宝剑没嘟。 　　紫霞：哎呀我知道你听不见我才“嘟”给你听的嘛！完了，我好害怕，我不骗你，我真的好害怕！ 　　至尊宝：你怕什么？ 　　紫霞：这段姻缘是上天安排的，你说我怕不怕？ 　　至尊宝：又来了…… 　　紫霞：是啊！我的心在跳，我的宝剑在“嘟”，怎么办？怎么跟他说？怎么跟他说？ 　　至尊宝：那你就跟他说是上天安排了这么一段姻缘。 　　紫霞：他不喜欢我怎么办？他有老婆怎么办？ 　　至尊宝：你管他那么多，上天安排的最大嘛！ 　　紫霞：真的？ 　　至尊宝：上天安排的，还不够你臭屁的啊？ 　　紫霞：对对对对对！（等了一会儿）他来了。 　　至尊宝：不会是我吧？ 　　紫霞：哎呀，就是你啊！你怎么知道的？就是你啊！你知不知道我刚才都不知道怎么跟你说，你真聪明！ 　　至尊宝：可是我有老婆了…… 　　紫霞：我知道啊！可是我也没办法，这段姻缘是上天安排的最大嘛！你现在呢就只有马上甩掉你那个老婆，然后跟我一起走。 　　至尊宝：也好啊。 　　紫霞：好啊？ 　　至尊宝：是很好啊。 　　紫霞：那我们大家立刻开始这段感情吧！ 　　至尊宝：好，就立刻开始！ 　　紫霞：你先亲我一下！]]></description>
			<content:encoded><![CDATA[<p>       至尊宝：干什么？<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>
]]></content:encoded>
			<wfw:commentRss>http://www.dc9.cn/post/641.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>sql server 更新 随机数</title>
		<link>http://www.dc9.cn/post/638.html</link>
		<comments>http://www.dc9.cn/post/638.html#comments</comments>
		<pubDate>Wed, 09 May 2012 15:02:51 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[未分类]]></category>

		<guid isPermaLink="false">http://www.dc9.cn/?p=638</guid>
		<description><![CDATA[update pxtest2.dbo.ContentLists SET Price = CONVERT(smallint, 70 + RAND(CHECKSUM(NEWID())) * 95)]]></description>
			<content:encoded><![CDATA[<p>update pxtest2.dbo.ContentLists SET Price = CONVERT(smallint, 70 + RAND(CHECKSUM(NEWID())) * 95)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dc9.cn/post/638.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>sqlserver 2008 geography</title>
		<link>http://www.dc9.cn/post/636.html</link>
		<comments>http://www.dc9.cn/post/636.html#comments</comments>
		<pubDate>Tue, 08 May 2012 06:04:49 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[未分类]]></category>

		<guid isPermaLink="false">http://www.dc9.cn/?p=636</guid>
		<description><![CDATA[Update [pxtest2].[dbo].[ContentLists] set Location = geography::STGeomFromText(&#8216;POINT(&#8216; + CAST([Longitude] AS VARCHAR(20)) + &#8216; &#8216; + CAST([Latitude] AS VARCHAR(20)) + &#8216;)&#8217;, 4326)]]></description>
			<content:encoded><![CDATA[<p>Update [pxtest2].[dbo].[ContentLists] set Location = geography::STGeomFromText(&#8216;POINT(&#8216; + CAST([Longitude] AS VARCHAR(20)) + &#8216; &#8216; +<br />
                    CAST([Latitude] AS VARCHAR(20)) + &#8216;)&#8217;, 4326)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dc9.cn/post/636.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[zz]不懂技术的人不要对懂技术的人说这很容易实现</title>
		<link>http://www.dc9.cn/post/634.html</link>
		<comments>http://www.dc9.cn/post/634.html#comments</comments>
		<pubDate>Tue, 08 May 2012 04:58:25 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[未分类]]></category>

		<guid isPermaLink="false">http://www.dc9.cn/?p=634</guid>
		<description><![CDATA[“这个网站相当简单，所有你需要做的就是完成X，Y，Z。你看起来应该是技术很好，所以，我相信，你不需要花费太多时间就能把它搭建起来。” 我时不时的就会收到这样的Email。写这些邮件的人几乎都是跟技术不沾边的人，或正在研究他们的第一个产品。起初，当听到人们这样的话，我总是十分的恼怒。他们在跟谁辩论软件开发所需要的时间？但后来我意识到，即使我自己对自己的项目预测要花去多少开发时间,我也是一筹莫展。如果连我自己都做不好，我何必对那些人恼怒呢？ 真正让我郁闷的不是他们预估的错误。问题在于他们竟然认为自己可以做出正确的估计。作为开发人员，我们经常会发现，在软件开发的问题上，一个外行人会很自然的把复杂的事情估计的很简单。 这并不是为我们的愤怒找借口。但这引起了另外一个有趣的问题：为什么我们天生的预测复杂性的能力在遇到编程问题时会失灵？ 为了回答这个问题，让我们来认识一下我们的大脑如何估计事情的。有些事情对于一些没有经验的人也很容易预估正确，但有些事情则不然。 我们来想想观看一个人弹吉他。即使你从来没有弹过吉他，在观看了一场弹奏《玛丽有只小羊羔(Mary had a Little Lamb)》的吉他表演后，你也能大概推测出这很简单，一个人不需要太高的技术就能演奏出来。同样，当观看了有人演奏D大调的《卡农(Pachabel’s Canon)》后，你也很容易推测出，这很复杂，需要很长时间的练习才能演奏的出来。 为什么我们能够很迅速准确的预估这两首曲子的复杂性呢？这是跟我们用来判断一个事情简单和还是复杂的方法有关的。我们的大脑有一些现成的模式来完成这些事情，首先一个就是根据速度。这种情况下，大脑会辨别每秒钟演奏的东西。根据每秒钟演奏了多少东西，我们很容易有一个直观的判断曲子的复杂度。因为用吉他演奏一首歌是一种物理过程，一种感官上的活动，我们的大脑很容易依此来推测速度，继而转换成复杂度。 我们还有另外一个天生的推测依据：体积。想想把一个帐篷和一栋公寓放在一起对比。即使一个人从来没有学过建筑学，他也能告诉你通常设计和建造一个帐篷会比设计和建造一栋公寓要简单。为什么？因为我们天生的会使用物理体积作为事物复杂性的一个指标。 当然。上面说的这两种逻辑分析并不是总是100%的有效。但大多数情况下，人们就是这样干，而且很成功。大多数情况中，我们在对物理过程评估时，我们的大脑会对物理事物进行有效的关联，不需要依赖之前的经验。 现在让我们来谈谈软件。当一个不懂技术的人试图对软件开发时间进行评估时，有两个很基本的直观指标在辅助他们：以体积为指标的复杂度和以速度为指标的复杂度。但他们没有意识到，软件跟他们想象的不一样。软件本质上不是有形物质。没有体积和速度。它的极小的组成部分可能会时不时的在电脑屏幕上闪现。正因为如此，当面对开发一个web应用时(或任何类型的软件)，我们的基本直观感觉失效了。 这第一点，速度，很显然根本不可能被外行人拿来对软件进行评估。于是很自然的，他们倾向于使用体积指标进行评估。要么是根据描述文档的页数，要么是根据软件的功能用例数或特征数。 有时候，这种评估手段确实有效！当面对一个静态网站，没有特别的设计要求，外行人很容易用这种方法估计出开发时间。但是，通常情况下，对于软件开发，体积并不能真实有效的反映复杂度。 不幸的是，对于软件的复杂度，唯一有效的推测方法是依据经验。而且还不是时时都好用。作为一个程序员，我知道，根据我之前开发过的相似的功能特征，我可以估计出现在的这些功能特征各自要多少开发时间。然后，我把总时间加起来，这就得到了完成整个项目需要的大致时间。然而，事实情况中，每个项目在开发过程中都遇到二、三个瓶颈。这些瓶颈会肆意的消耗程序员的大量时间，你在遇到它们之前根本不会有所预见。它们会拖住整个项目，致使工期延后数周甚至数月。 这些是没有经验的人在评估复杂度时不会理解的。他们不明白在其他事情上都很灵的方法，为什么放到软件开发上就不灵了。所以，下一次当你听到有人说“我想你几天时间就能把它开发出来”时，不管是谁说的，都不要懊恼。深呼吸一下，告诉他这篇文章的地址，自己该干什么还干什么。 [本文英文原文链接：I'm Sure It Will Only Take You A Few Days To Code ] [ZZ:http://www.aqee.net/im-sure-it-will-only-take-you-a-few-days-to-code/]]]></description>
			<content:encoded><![CDATA[<p>“这个网站相当简单，所有你需要做的就是完成X，Y，Z。你看起来应该是技术很好，所以，我相信，你不需要花费太多时间就能把它搭建起来。”</p>
<p>我时不时的就会收到这样的Email。写这些邮件的人几乎都是跟技术不沾边的人，或正在研究他们的第一个产品。起初，当听到人们这样的话，我总是十分的恼怒。他们在跟谁辩论软件开发所需要的时间？但后来我意识到，即使<em>我自己</em>对<em>自己的</em>项目预测要花去多少开发时间,我也是一筹莫展。如果连我自己都做不好，我何必对那些人恼怒呢？</p>
<p>真正让我郁闷的不是他们预估的错误。问题在于他们竟然认为自己可以做出正确的估计。作为开发人员，我们经常会发现，在软件开发的问题上，一个外行人会很自然的把复杂的事情估计的很简单。</p>
<p>这并不是为我们的愤怒找借口。但这引起了另外一个有趣的问题：<em>为什么</em>我们天生的预测复杂性的能力在遇到编程问题时会失灵？</p>
<p>为了回答这个问题，让我们来认识一下我们的大脑如何估计事情的。有些事情对于一些没有经验的人也很容易预估正确，但有些事情则不然。</p>
<p>我们来想想观看一个人弹吉他。即使你从来没有弹过吉他，在观看了一场弹奏《玛丽有只小羊羔(Mary had a Little Lamb)》的吉他表演后，你也能大概推测出这很简单，一个人不需要太高的技术就能演奏出来。同样，当观看了有人演奏D大调的《卡农(Pachabel’s Canon)》后，你也很容易推测出，这很复杂，需要很长时间的练习才能演奏的出来。</p>
<p>为什么我们能够很迅速准确的预估这两首曲子的复杂性呢？这是跟我们用来判断一个事情简单和还是复杂的方法有关的。我们的大脑有一些现成的模式来完成这些事情，首先一个就是根据速度。这种情况下，大脑会辨别每秒钟演奏的东西。根据每秒钟演奏了多少东西，我们很容易有一个直观的判断曲子的复杂度。因为用吉他演奏一首歌是一种物理过程，一种感官上的活动，我们的大脑很容易依此来推测速度，继而转换成复杂度。</p>
<p>我们还有另外一个天生的推测依据：体积。想想把一个帐篷和一栋公寓放在一起对比。即使一个人从来没有学过建筑学，他也能告诉你通常设计和建造一个帐篷会比设计和建造一栋公寓要简单。为什么？因为我们天生的会使用物理体积作为事物复杂性的一个指标。</p>
<p>当然。上面说的这两种逻辑分析并不是总是100%的有效。但大多数情况下，人们就是这样干，而且很成功。大多数情况中，我们在对物理过程评估时，我们的大脑会对物理事物进行有效的关联，不需要依赖之前的经验。</p>
<p>现在让我们来谈谈软件。当一个不懂技术的人试图对软件开发时间进行评估时，有两个很基本的直观指标在辅助他们：以体积为指标的复杂度和以速度为指标的复杂度。但他们没有意识到，软件跟他们想象的不一样。软件本质上不是有形物质。没有体积和速度。它的极小的组成部分可能会时不时的在电脑屏幕上闪现。正因为如此，当面对开发一个web应用时(或任何类型的软件)，我们的基本直观感觉失效了。</p>
<p>这第一点，速度，很显然根本不可能被外行人拿来对软件进行评估。于是很自然的，他们倾向于使用体积指标进行评估。要么是根据描述文档的页数，要么是根据软件的功能用例数或特征数。</p>
<p>有时候，这种评估手段确实有效！当面对一个静态网站，没有特别的设计要求，外行人很容易用这种方法估计出开发时间。但是，通常情况下，对于软件开发，体积并不能真实有效的反映复杂度。</p>
<p>不幸的是，对于软件的复杂度，唯一有效的推测方法是依据<em>经验</em>。而且还不是时时都好用。作为一个程序员，我知道，根据我之前开发过的相似的功能特征，我可以估计出现在的这些功能特征各自要多少开发时间。然后，我把总时间加起来，这就得到了完成整个项目需要的大致时间。然而，事实情况中，每个项目在开发过程中都遇到二、三个瓶颈。这些瓶颈会肆意的消耗程序员的大量时间，你在遇到它们之前根本不会有所预见。它们会拖住整个项目，致使工期延后数周甚至数月。</p>
<p>这些是没有经验的人在评估复杂度时不会理解的。他们不明白在其他事情上都很灵的方法，为什么放到软件开发上就不灵了。所以，下一次当你听到有人说“我想你几天时间就能把它开发出来”时，不管是谁说的，都不要懊恼。深呼吸一下，告诉他这篇文章的地址，自己该干什么还干什么。</p>
<p id="page-note">[本文英文原文链接：<a href="http://danshipper.com/non-technical-people-cant-estimate-developmen">I'm Sure It Will Only Take You A Few Days To Code</a> ]</p>
<p>[ZZ:<a href="http://www.aqee.net/im-sure-it-will-only-take-you-a-few-days-to-code/">http://www.aqee.net/im-sure-it-will-only-take-you-a-few-days-to-code/</a>]</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dc9.cn/post/634.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Sql Server 去除重复</title>
		<link>http://www.dc9.cn/post/627.html</link>
		<comments>http://www.dc9.cn/post/627.html#comments</comments>
		<pubDate>Sun, 29 Apr 2012 06:04:36 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[未分类]]></category>

		<guid isPermaLink="false">http://www.dc9.cn/?p=627</guid>
		<description><![CDATA[delete t2 from [pxtest].[dbo].[PXContent] t1 join [pxtest].[dbo].[PXContent] t2 on t1.ContentListId = t2.ContentListId where t1.Id &#60; t2.Id]]></description>
			<content:encoded><![CDATA[<p>delete t2<br />
from [pxtest].[dbo].[PXContent] t1<br />
join [pxtest].[dbo].[PXContent] t2<br />
on t1.ContentListId = t2.ContentListId<br />
where t1.Id &lt; t2.Id</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dc9.cn/post/627.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

