<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<?xml-stylesheet type="text/xsl" href="css/rss.xslt"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>MacGoo</title><link>http://www.macgoo.com/myblog/</link><description>梦想开始的地方</description><generator>RainbowSoft Studio Z-Blog 1.8 Arwen Build 90619</generator><language>zh-CN</language><copyright>Powered By Z-Blog Copyright 2006-2009 Macgoo.com Some Rights Reserved.Theme Design By Design Disease | Transplant by Nobird湘ICP备07001810号var gaJsHost = ((&amp;quot;https:&amp;quot; == document.location.protocol) ? &amp;quot;https://ssl.&amp;quot; : &amp;quot;http://www.&amp;quot;);document.write(unescape(&amp;quot;%3Cscript src='&amp;quot; + gaJsHost + &amp;quot;google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E&amp;quot;));try {var pageTracker = _gat._getTracker(&amp;quot;UA-5293693-2&amp;quot;);pageTracker._trackPageview();} catch(err) {}</copyright><pubDate>Tue, 09 Feb 2010 23:00:30 +0800</pubDate><item><title>!+&amp;quot;\v1&amp;quot; 和 !+[1,] 和 !&amp;quot;1&amp;quot;[0] 和 window.attachEvent 和 document.all 比比谁更快</title><author>soddyque@gmail.com (米落)</author><link>http://www.macgoo.com/myblog/archives/144/</link><pubDate>Tue, 02 Feb 2010 00:38:14 +0800</pubDate><guid>http://www.macgoo.com/myblog/archives/144/</guid><description><![CDATA[<p>
<link href="http://www.macgoo.com/myblog/PLUGIN/Codelight/SyntaxHighlighter/Styles/shCore.css" rel="stylesheet" type="text/css" />
<link href="http://www.macgoo.com/myblog/PLUGIN/Codelight/SyntaxHighlighter/Styles/shThemeDefault.css" rel="stylesheet" type="text/css" /><script language="javascript" src="http://www.macgoo.com/myblog/PLUGIN/Codelight/SyntaxHighlighter/Scripts/shCore.js"></script><script language="javascript" src="http://www.macgoo.com/myblog/PLUGIN/Codelight/SyntaxHighlighter/Scripts/shBrushJScript.js"></script></p>
<p>&nbsp;&nbsp;&nbsp; 下面所做的可能有点鸡蛋里跳骨头的味道,但却也十分有趣,希望各位能够在看了之后能够有所收获.</p>
<p>&nbsp;&nbsp;&nbsp; 总所周知,浏览器兼容问题一直困扰着开发者们,勤劳的开发者们也想到了各式各样的小技巧来区分各个派系的浏览器.</p>
<p>&nbsp;&nbsp;&nbsp; !+&quot;\v1&quot;<br />
&nbsp;&nbsp;&nbsp; 这是在园子里的司徒正美童鞋那看到的,第一眼就被震惊了,原来判断可以这样的精悍.<br />
&nbsp;&nbsp;&nbsp; 以下是个人的理解,出处文尾<sup>连接1</sup>.<br />
&nbsp;&nbsp;&nbsp; 这是一个JavaScript类型转换的技巧,按照优先级,这里是从右往左(+ 取正&gt; ! 逻辑求负).也就是将字符串&quot;\v1&quot;转换为数字后再求反.数字求反很好理解,只要不是0的都是true,然后 + 取正对字符串进行了转换,转换为数字.然后IE在这里就出现了歧义,错误的理解了转义符&quot;\v&quot;,垂直制表符,关于制表符在文尾<sup>连接2</sup>有更多的解释.在其他浏览器中能够正确解释这个制表符,IE则将这个制表符解释成了字母&quot;v&quot;,这个当然无法转换成数字,自然转换NaN,按照逻辑操作符的转换规则,转换为了false,再一个求反,则变成了true,趾高气昂的说,&quot;我是IE,没错,TRUE!&quot;.<br />
&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp; !+[1,]<br />
&nbsp;&nbsp;&nbsp; 同样是在司徒童鞋那看到的,天天逛园子的收货果然不少啊,关于这个判断语句的解释请移步<a href="http://www.cnblogs.com/rubylouvre/archive/2010/01/28/1658006.html">司徒正美--全 世界最短的IE判定</a> .<br />
&nbsp;&nbsp;&nbsp; 不过在接下来的测试中,你会发现,这条最短的语句不一定是最快的.</p>
<p>&nbsp;&nbsp;&nbsp; <strike>!&quot;1&quot;[0]&nbsp;</strike>&nbsp;&nbsp; <span style="color: rgb(255, 0, 0);"><strong>此方法失效: 详见:</strong></span><a href="http://www.cnblogs.com/dreampuf/archive/2010/02/02/1661444.html#1758968" target="_blank">http://www.cnblogs.com/dreampuf/archive/2010/02/02/1661444.html#1758968<br />
</a> &nbsp;&nbsp;&nbsp; 这个是我翻看Ext源代码时发现的,在Ext.toArray的注释里作者告诉了IE无法使用数组下标访问字符串,这不就又可以分辨了么.<br />
&nbsp;&nbsp;&nbsp; 就是这个方法,IE中无法以数组下标的方式访问字符串,在Ext的注释中提示可以使用&quot;abc&quot;.match(/./g)的方式,我就纳闷了怎么直接使用原生的split方法,&quot;abc&quot;.split(&quot;&quot;),很明显的更直观,而且免去了一个正则的构造.<br />
&nbsp;&nbsp;&nbsp; 这个方法在FF下的效率已经超过了IE.</p>
<p>&nbsp;&nbsp;&nbsp; 至于其他的方法,都是老生长谈的访问某个特殊属性,这里就不多解释了.不过在IE以及FF下访问不存在的属性相差可真大啊.</p>
<table cellspacing="1" cellpadding="1" border="1" align="left" style="width: 600px; height: 366px;">
    <tbody>
        <tr>
            <td colspan="5">IE8</td>
        </tr>
        <tr>
            <td bgcolor="#3399cc"><strong>判断语句</strong></td>
            <td colspan="3"><strong>三次测试</strong></td>
            <td bgcolor="#990033"><strong>平均值</strong></td>
        </tr>
        <tr>
            <td bgcolor="#3399cc">!+&quot;\v1&quot;</td>
            <td>3776</td>
            <td>3682</td>
            <td>3681</td>
            <td bgcolor="#996633">3713</td>
        </tr>
        <tr>
            <td bgcolor="#3399cc">!+[1,]</td>
            <td>58422</td>
            <td>56519</td>
            <td>56581</td>
            <td bgcolor="#996633">57174</td>
        </tr>
        <tr>
            <td bgcolor="#3399cc">!&quot;1&quot;[0]</td>
            <td>5445</td>
            <td>5554</td>
            <td>5507</td>
            <td bgcolor="#996633">5502</td>
        </tr>
        <tr>
            <td bgcolor="#3399cc">!window.addEventListener</td>
            <td>23045</td>
            <td>22825</td>
            <td>22908</td>
            <td bgcolor="#996633">&nbsp;22926</td>
        </tr>
        <tr>
            <td bgcolor="#3399cc">window.attachEvent</td>
            <td>29419</td>
            <td>29450</td>
            <td>29556</td>
            <td bgcolor="#996633">&nbsp;29475</td>
        </tr>
        <tr>
            <td bgcolor="#3399cc">document.all</td>
            <td>44553</td>
            <td>44647</td>
            <td>44835</td>
            <td bgcolor="#996633">&nbsp;44678</td>
        </tr>
        <tr>
            <td colspan="5">&nbsp;</td>
        </tr>
        <tr>
            <td colspan="5">FireFox3.6</td>
        </tr>
        <tr>
            <td bgcolor="#3399cc">!+&quot;\v1&quot;</td>
            <td>&nbsp;1425</td>
            <td>1428</td>
            <td>1425</td>
            <td bgcolor="#996633">&nbsp;1426</td>
        </tr>
        <tr>
            <td bgcolor="#3399cc">!+[1,]</td>
            <td>&nbsp;12627</td>
            <td>12478</td>
            <td>12560</td>
            <td bgcolor="#996633">&nbsp;12555</td>
        </tr>
        <tr>
            <td bgcolor="#3399cc">!&quot;1&quot;[0]</td>
            <td>&nbsp;125</td>
            <td>140</td>
            <td>126</td>
            <td bgcolor="#996633">&nbsp;130</td>
        </tr>
        <tr>
            <td bgcolor="#3399cc">!window.addEventListener</td>
            <td>&nbsp;27236</td>
            <td>25530</td>
            <td>25556</td>
            <td bgcolor="#996633">&nbsp;26107</td>
        </tr>
        <tr>
            <td bgcolor="#3399cc">window.attachEvent</td>
            <td>&nbsp;77590</td>
            <td>79494</td>
            <td>77347</td>
            <td bgcolor="#996633">&nbsp;78143</td>
        </tr>
        <tr>
            <td bgcolor="#3399cc">document.all</td>
            <td>&nbsp;22877</td>
            <td>22984</td>
            <td>22978</td>
            <td bgcolor="#996633">&nbsp;22946</td>
        </tr>
    </tbody>
</table>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp; 测试环境 CPU : E2180(2.0GHz),RAM 2G.OS : Win7</p>
<pre class="brush:javascript;mouse-over:#ff9" name="CodeLight_code" height="400" style="background-color: rgb(240, 240, 240); border: thin ridge rgb(204, 204, 204);">
    var i = 0, total = 10000000, btimespan, p1timespan, p2timespan;
    var Bstart = new Date();
    for(;i &lt; total; i++) {
        if(/*测试语句*/) ;
    }
    btimespan = new Date().getTime() - Bstart.getTime();
    
    i = 0;
    var P1start = new Date();
    for(; i &lt; total; i++) {
        if(/*测试语句*/) ;
    }
    p1timespan = new Date().getTime() - P1start.getTime();</pre>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp; 连接1: 32 bytes, ehr ... 9, ehr ... 7!!! to know if your browser is IE -- <a target="_blank" href="http://webreflection.blogspot.com/2009/01/32-bytes-to-know-if-your-browser-is-ie.html">http://webreflection.blogspot.com/2009/01/32-bytes-to-know-if-your-browser-is-ie.html</a>&nbsp; (需翻墙)<br />
&nbsp;&nbsp;&nbsp; 连接2: 转义字符_百度百科 -- <a target="_blank" href="http://baike.baidu.com/view/73.html">http://baike.baidu.com/view/73.html</a><br />
&nbsp;&nbsp;&nbsp; 连接3: JavaScript类型转换 --<a target="_blank" href="http://www.macgoo.com/lib/doc/Javascript_Type_Conversion/Javascript-Type-Conversion.htm"> http://www.macgoo.com/lib/doc/Javascript_Type_Conversion/Javascript-Type-Conversion.htm</a></p>
<script language="javascript">SyntaxHighlighter.config.clipboardSwf = 'http://www.macgoo.com/myblog/PLUGIN/Codelight/SyntaxHighlighter/Scripts/clipboard.swf';SyntaxHighlighter.all();</script>]]></description><category>Programer</category><comments>http://www.macgoo.com/myblog/archives/144/#comment</comments><wfw:comment>http://www.macgoo.com/myblog/</wfw:comment><wfw:commentRss>http://www.macgoo.com/myblog/feed.asp?cmt=144</wfw:commentRss><trackback:ping>http://www.macgoo.com/myblog/cmd.asp?act=tb&amp;id=144&amp;key=1068f486</trackback:ping></item><item><title>我的七个建议</title><author>soddyque@gmail.com (米落)</author><link>http://www.macgoo.com/myblog/archives/143/</link><pubDate>Sat, 30 Jan 2010 01:11:54 +0800</pubDate><guid>http://www.macgoo.com/myblog/archives/143/</guid><description><![CDATA[<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 24pt"><span style="font-weight: normal; font-size: 10.5pt; font-family: '宋体'">作者</span><span style="font-weight: normal; font-size: 12pt; font-family: '宋体'">：</span><span style="font-size: 10.5pt; font-family: 'Times New Roman'">Joel&nbsp;Spolsky</span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 21pt"><span style="font-size: 10.5pt; font-style: italic; font-family: 'Times New Roman'">[<span style="font-family: 宋体">编者按</span><span style="font-family: Times New Roman">]</span><span style="font-family: 宋体">由于</span><span style="font-family: Times New Roman">Joel&nbsp;Spolsky</span><span style="font-family: 宋体">的双重身份（昔日耶鲁大学计算机系学长，今日</span><span style="font-family: Times New Roman">Fog&nbsp;Creek</span><span style="font-family: 宋体">软件公司的</span><span style="font-family: Times New Roman">CEO</span><span style="font-family: 宋体">），所以听听他的建议，对于当今无数困扰于就业压力的中国高校计算机专业学子来说，是大有裨益的。你们会发现，大多数建议，都在强调</span><span style="font-family: Times New Roman">&ldquo;</span><span style="font-family: 宋体">软实力</span><span style="font-family: Times New Roman">&rdquo;</span><span style="font-family: 宋体">的价值。本文转载自《软件随想录》</span><span style="font-family: Times New Roman">(</span><span style="font-family: 宋体">作者：</span><span style="font-family: Times New Roman">Joel&nbsp;Spolsky </span><span style="font-family: 宋体">，译者</span><span style="font-family: Times New Roman">: </span><span style="font-family: 宋体">阮一峰，</span><span style="font-family: Times New Roman">2009</span><span style="font-family: 宋体">年</span><span style="font-family: Times New Roman">12</span><span style="font-family: 宋体">月出版</span><span style="font-family: Times New Roman">)</span><span style="font-family: 宋体">，感谢北京图灵文化发展有限公司的支持。</span></span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 21pt"><span style="font-size: 10.5pt; font-family: 'Times New Roman'">如果你喜欢编程，那么你真是受到了上天的眷顾。你是非常幸运的少数人之一，能够以自己喜欢的事谋生。大多数人没有这么幸运。你认为理所当然的观念<span style="font-family: Times New Roman">&ldquo;</span><span style="font-family: 宋体">热爱你的工作</span><span style="font-family: Times New Roman">&rdquo;</span><span style="font-family: 宋体">，其实是一个很现代的概念。通常的看法是，工作是一种让人很不开心的事，你为了拿工资才不得不去上班。你工作的目的是为了攒下钱去干那些自己真正喜欢干的事，但是前提是你得等到</span><span style="font-family: Times New Roman">65</span><span style="font-family: 宋体">岁退休之后才行，而且还有不少条件。条件一，你的积蓄必须足够多；条件二，你没有老到走不动，你还有体力去干那些事情；条件三，你喜欢的事情不需要用到脆弱的膝盖、昏花的视力，也不要求你走上一里地不喘气，等等。</span></span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 21pt"><span style="font-size: 10.5pt; font-family: 'Times New Roman'">我刚才说到哪里了？对了，我要提建议。</span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 21pt"><span style="font-weight: bold; font-size: 10.5pt; font-family: 'Times New Roman'">毕业前练好写作</span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 21pt"><span style="font-size: 10.5pt; font-family: 'Times New Roman'">如果不是<span style="font-family: Times New Roman">Linus&nbsp;Torvalds</span><span style="font-family: 宋体">不断地散布福音，请问</span><span style="font-family: Times New Roman">Linux</span><span style="font-family: 宋体">操作系统会成功吗？虽然他是一个非常聪明的计算机天才，但是</span><span style="font-family: Times New Roman">Linux</span><span style="font-family: 宋体">吸引来全世界一大批志愿者的真正原因却是</span><span style="font-family: Times New Roman">Linus&nbsp;Torvalds</span><span style="font-family: 宋体">的表达能力。他通过电子邮件和邮件列表用书面形式传播自己的想法，最终引起了所有人的注意。</span></span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 21pt"><span style="font-size: 10.5pt; font-family: 'Times New Roman'">你听说过现在风靡一时的<span style="font-family: Times New Roman">&ldquo;</span><span style="font-family: 宋体">极限编程</span><span style="font-family: Times New Roman">[&nbsp;]&nbsp;&rdquo;</span><span style="font-family: 宋体">（</span><span style="font-family: Times New Roman">Extreme&nbsp;Programming</span><span style="font-family: 宋体">）吗？我在这个地方不谈我对极限编程的看法，我只说如果你听过这个词，那么原因就是它的倡导者都是一些非常有才华的作家和演说家。</span></span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 21pt"><span style="font-size: 10.5pt; font-family: 'Times New Roman'">即使我们缩小范围，将目光局限在任何一个软件开发团体中，你也会发现该团体中最有权势和影响力的程序员正是那些表达能力强的程序员，他们无论是做书面表达还是做口头表达，都能够清晰、自如、具有说服力地传达观点。此外，长得高也有助于提升影响力，不过这个不取决于你。</span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 21pt"><span style="font-size: 10.5pt; font-family: 'Times New Roman'">一个普通程序员与一个优秀程序员的区别，不在于他们懂得的编程语言谁多谁少，也不在于他们喜欢用<span style="font-family: Times New Roman">Python</span><span style="font-family: 宋体">语言还是喜欢用</span><span style="font-family: Times New Roman">Java</span><span style="font-family: 宋体">语 言，而在于他们能否与他人交流思想。如果你能说服其他人，你的力量就可以得到放大。如果你能写出清晰的注释和技术规格说明书，其他程序员就能够理解你的代 码，因此他们就能在自己的代码中使用，而不必重写。如果你做不到这一点，你的代码对其他人就没有价值。如果你能为最终用户写出清晰的使用手册，其他人就能 明白你的代码是用来干什么的，这是唯一让别人明白你的代码有何价值的方法</span></span><span style="font-size: 10.5pt; font-family: '宋体'">。</span><span style="font-size: 10.5pt; font-family: 'Times New Roman'">SourceForge[&nbsp;]<span style="font-family: 宋体">上有许多优美的、有用的代码，但是它们都像被埋葬了一样，根本没人来用，原因就是它们的作者没有写好使用说明（或者压根就没写）。这样一来就没有人知道他们的成果，他们杰出的代码就衰亡了。</span></span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 21pt"><span style="font-size: 10.5pt; font-family: 'Times New Roman'">如果一个程序员不会用英语写作、没有良好的写作能力，我就不会雇他。如果你能写，不管你去哪家公司工作，你很快就会发现写作技术文档的任务会落到你头上，这意味着你已经开始在放大自己的影响力了，管理层正在注意到你。</span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 21pt"><span style="font-size: 10.5pt; font-family: 'Times New Roman'">大学里有些课程被公认为<span style="font-family: Times New Roman">&ldquo;</span><span style="font-family: 宋体">写作密集型</span><span style="font-family: Times New Roman">&rdquo;</span><span style="font-family: 宋体">（</span><span style="font-family: Times New Roman">writing&nbsp;intensive</span><span style="font-family: 宋体">）课程，这就是说为了拿到学分，你必须写作多得可怕的文字。一定要去上这样的课程！不要管学科，只要这门课每周甚至每天都要你写东西，你就去上。</span></span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 21pt"><span style="font-size: 10.5pt; font-family: 'Times New Roman'">你还可以动手写日记或者网志。你写得越多，写作就会变得越容易。写起来越容易，你就会写得越多。这是一个良性循环。</span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 21pt"><span style="font-weight: bold; font-size: 10.5pt; font-family: 'Times New Roman'">毕业前学好<span style="font-family: Times New Roman">C</span><span style="font-family: 宋体">语言</span></span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 21pt"><span style="font-size: 10.5pt; font-family: 'Times New Roman'">第二点我要讲的是<span style="font-family: Times New Roman">C</span><span style="font-family: 宋体">语言。请注意，我说的是</span><span style="font-family: Times New Roman">C</span><span style="font-family: 宋体">语言，而不是</span><span style="font-family: Times New Roman">C++</span><span style="font-family: 宋体">。虽然在实际使用中</span><span style="font-family: Times New Roman">C</span><span style="font-family: 宋体">语言已经越来越罕见，但是它仍然是当前程序员的共同语言。</span><span style="font-family: Times New Roman">C</span><span style="font-family: 宋体">语言让程序员互相沟通，更重要的是，它比你在大学中学到的</span><span style="font-family: Times New Roman">&ldquo;</span><span style="font-family: 宋体">现代语言</span><span style="font-family: Times New Roman">&rdquo;</span><span style="font-family: 宋体">（比如</span><span style="font-family: Times New Roman">ML</span><span style="font-family: 宋体">语言、</span><span style="font-family: Times New Roman">Java</span><span style="font-family: 宋体">语言、</span><span style="font-family: Times New Roman">Python</span><span style="font-family: 宋体">语 言或者其它正在教授的流行垃圾语言）都更接近机器。你至少需要花一个学期来了解机器原理，否则你永远不可能在高级语言的层次写出高效的代码。你也永远无法 开发编译器和操作系统，而它们恰恰属于目前程序员能够得到的最佳工作之列。别人也永远不会放心将大型项目的架构设计交给你。我不管你懂多少延续（</span><span style="font-family: Times New Roman">continuation</span><span style="font-family: 宋体">）、闭包（</span><span style="font-family: Times New Roman">closure</span><span style="font-family: 宋体">）、异常处理（</span><span style="font-family: Times New Roman">exception&nbsp;handling</span><span style="font-family: 宋体">），只要你不能解释为什么</span><span style="font-family: Times New Roman">while&nbsp;(*s++&nbsp;=&nbsp;*t++)</span><span style="font-family: 宋体">；这句代码的作用是复制字符串，或者不觉得这是世界上对你来说再自然不过的事情，那么你就是在盲目无知的情况下编程。在我看来，这就好像一个医生不懂得最基本的解剖学就在开处方，他看病的根据完全是因为那些娃娃脸的医药厂商销售代表说这种药有用。</span></span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 21pt"><span style="font-weight: bold; font-size: 10.5pt; font-family: 'Times New Roman'">毕业前学好微观经济学</span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 21pt"><span style="font-size: 10.5pt; font-family: 'Times New Roman'">如 果你没有上过任何经济学课程，那么我首先来做一个超短的评论：经济学是这样的学科之一，刚开始学的时候轰轰烈烈，有许多有用的、言之有理的理论和可以在真 实世界中得到证明的事实，等等；但是，再学下去就每况愈下，有用的东西就不多了。经济学一开始那个有用的部分正是微观经济学，它是商业领域所有重要理论的 基础。跟在微观经济学后面的东西就不行了。你接下来学的是宏观经济学，如果你愿意，尽管跳过去，也不会有什么损失。宏观经济学开头的部分是利息理论，内容 比方说是利率与失业之间的关系，但是怎么说呢，看上去这部分里面还没有被证实的东西多于已经被证实的东西。学完这部分，后面的内容越来越糟糕，许多经济学 专业的学生实际上都变成在搞物理学，因为这样才能在华尔街上找到更好的工作。但是不管怎样，你一定要去学微观经济学，因为你必须搞懂供给和需求，你必须明 白竞争优势，你必须理解什么是净现值（<span style="font-family: Times New Roman">NPV</span><span style="font-family: 宋体">），什么是贴现，什么是边际效用。只有这样，你才会懂得为什么生意是现在这种做法。</span></span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 21pt"><span style="font-size: 10.5pt; font-family: 'Times New Roman'">为 什么计算机系的学生也应该学经济学？因为，从经营一家公司的角度来看，比起那些不懂的程序员，一个理解基本商业规则的程序员将会更有价值。就是这么简单。 我无法告诉你有多少次我是那样地充满挫折感，因为我看到了太多的提出一些疯狂的想法的程序员，这些想法在代码上也许可行，但在资本主义世界中毫无意义。如 果你懂得商业规则，你就是一个更有价值的程序员，你会因此得到回报的，但是前提是你要去学习微观经济学。</span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 21pt"><span style="font-size: 10.5pt; font-family: 'Times New Roman'">不要因为枯燥就不选修非计算机专业的课程。</span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 21pt"><span style="font-size: 10.5pt; font-family: 'Times New Roman'">想提高<span style="font-family: Times New Roman">GPA</span><span style="font-family: 宋体">绩点的一个好方法就是多选修非计算机系的课程。请千万不要低估你的</span><span style="font-family: Times New Roman">GPA</span><span style="font-family: 宋体">的重大意义。千千万万的人事经理和招聘人员在拿到一份简历的时候，第一眼就会去看</span><span style="font-family: Times New Roman">GPA</span><span style="font-family: 宋体">，包括我也是这样。我们不会为这种做法道歉。为什么？因为</span><span style="font-family: Times New Roman">GPA</span><span style="font-family: 宋体">不反映单个的成绩，而是代表了许多个教授在一段很长的时间中，在不同的情况下，对你的表现的一个总的评估。</span><span style="font-family: Times New Roman">SAT</span><span style="font-family: 宋体">成绩难道不够吗？哈，那只不过是一场几个小时的测试罢了。</span><span style="font-family: Times New Roman">GPA</span><span style="font-family: 宋体">中包括了四年大学期间你的小论文、期中考试和课堂表现，总数有几百次之多。当然，</span><span style="font-family: Times New Roman">GPA</span><span style="font-family: 宋体">也有自己的问题，不是百分之百准确。比如，这些年来，老师对学生的打分越来越宽松，学习成绩有通货膨胀的趋势。再比如，</span><span style="font-family: Times New Roman">GPA</span><span style="font-family: 宋体">无法反映课程的难度，没人能够看出你的</span><span style="font-family: Times New Roman">GPA</span><span style="font-family: 宋体">是来自无名社区大学家政系的轻松课程还是来自加州理工学院针对研究生的量子力学课程。渐渐地，我形成了一套自己的做法，首先我会过滤掉所有来自社区大学、</span><span style="font-family: Times New Roman">GPA</span><span style="font-family: 宋体">低于</span><span style="font-family: Times New Roman">2.5</span><span style="font-family: 宋体">的简历，然后我会要求剩下的人给我寄成绩单和推荐信。我再从中发现那些成绩一贯优秀的人，而不是那些仅仅在计算机系课程中得到高分的人。</span></span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 21pt"><span style="font-size: 10.5pt; font-family: 'Times New Roman'">为什么我要关心某人的<span style="font-family: Times New Roman">&ldquo;</span><span style="font-family: 宋体">欧洲历史</span><span style="font-family: Times New Roman">&rdquo;</span><span style="font-family: 宋体">课 程成绩呢，毕竟作为雇主我要找的应该是程序员啊？何况，历史是那么枯燥，不得高分很正常。哦，这么说来，你的意思是我应该雇用你，而不用考虑一旦工作变得 枯燥你会不会努力工作？别忘了，在编程工作中也有很枯燥的东西。每一项工作都有枯燥难耐的时刻。我不想雇用那些只想干有趣事情的人。</span></span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 21pt"><span style="font-weight: bold; font-size: 10.5pt; font-family: 'Times New Roman'">选修有大量编程实践的课程</span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 21pt"><span style="font-size: 10.5pt; font-family: 'Times New Roman'">我依然清楚记得我发誓绝不读研究生的那一刻。那是在一门叫做<span style="font-family: Times New Roman">&ldquo;</span><span style="font-family: 宋体">动态逻辑</span><span style="font-family: Times New Roman">&rdquo;</span><span style="font-family: 宋体">的课程上，教师是活力十足的耶鲁大学教授</span><span style="font-family: Times New Roman">Lenore&nbsp;Zuck</span><span style="font-family: 宋体">，她是计算机系那些聪明的老师中最聪明的人之一。</span></span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 21pt"><span style="font-size: 10.5pt; font-family: 'Times New Roman'">如今，&nbsp;由于记忆力糟糕，&nbsp;我已经差不多把这门课的内容忘光了，但是不管怎么说，在这里我还是想要对付着说一下。大致上，形式逻辑的意思是说，如果条件成立，你就能证明结论也成立。比如，根据形式逻辑，已知<span style="font-family: Times New Roman">&ldquo;</span><span style="font-family: 宋体">只要成绩好，就能被雇用</span><span style="font-family: Times New Roman">&rdquo;</span><span style="font-family: 宋体">，然后假定</span><span style="font-family: Times New Roman">&ldquo;Johnny</span><span style="font-family: 宋体">的成绩好</span><span style="font-family: Times New Roman">&rdquo;</span><span style="font-family: 宋体">，你就可以得到一个崭新的结论</span><span style="font-family: Times New Roman">&ldquo;Johnny</span><span style="font-family: 宋体">会被雇用</span><span style="font-family: Times New Roman">&rdquo;</span><span style="font-family: 宋体">。这完全是经典方法。但是，一个解构主义者（</span><span style="font-family: Times New Roman">deconstructionist</span><span style="font-family: 宋体">）只需要</span><span style="font-family: Times New Roman">10</span><span style="font-family: 宋体">秒钟就能破坏形式逻辑中所有有用的东西。这样一来，留给你的只是一些趣味性，而不是实用性。</span></span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 21pt"><span style="font-size: 10.5pt; font-family: 'Times New Roman'">现在再来说动态逻辑。它与形式逻辑其实是一回事，但是必须再多考虑时间因素。比如，<span style="font-family: Times New Roman">&ldquo;</span><span style="font-family: 宋体">你打开灯之后，就能看见自己的鞋子</span><span style="font-family: Times New Roman">&rdquo;</span><span style="font-family: 宋体">，已知</span><span style="font-family: Times New Roman">&ldquo;</span><span style="font-family: 宋体">灯以前是亮的</span><span style="font-family: Times New Roman">&rdquo;</span><span style="font-family: 宋体">，那么这就意味着</span><span style="font-family: Times New Roman">&ldquo;</span><span style="font-family: 宋体">你看见了自己的鞋子</span><span style="font-family: Times New Roman">&rdquo;</span><span style="font-family: 宋体">。</span></span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 21pt"><span style="font-size: 10.5pt; font-family: 'Times New Roman'">对于像<span style="font-family: Times New Roman">Zuck</span><span style="font-family: 宋体">教授那样聪明的理论家，动态逻辑充满了吸引力，因为它看上去很有希望让你在形式上证明一些计算机程序的相关理论问题。这样做说不定很有用。比如，你可以用它在形式上证明，火星漫游车的闪存卡不会发生溢出（</span><span style="font-family: Times New Roman">overflow</span><span style="font-family: 宋体">）问题，不会因而整天一遍又一遍地重启，耽误了它在那颗赤红色的星球上漫游寻找火星人马文（</span><span style="font-family: Times New Roman">Marvin&nbsp;the</span></span> <span style="font-size: 10.5pt; font-family: 'Times New Roman'">Martian<span style="font-family: 宋体">）。</span></span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 21pt"><span style="font-size: 10.5pt; font-family: 'Times New Roman'">在第一堂课上，<span style="font-family: Times New Roman">Zuck</span><span style="font-family: 宋体">博士写满了整整两面黑板，甚至黑板旁边的墙上都写上了很多证明步骤。需要证明的问题是，有一个控制灯泡的开关，现在灯泡没有亮，这时你打开了开关，请证明灯泡将会点亮。</span></span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 21pt"><span style="font-size: 10.5pt; font-family: 'Times New Roman'">整 个证明过程复杂得不可思议，处处都是陷阱，必须十分小心。保证这个证明不出错太困难了，还不如直接相信打开开关灯就会亮。真的，虽然证明过程写满了许多块 黑板，但是还是有许多中间步骤被省略了，因为如果要从形式逻辑上完整证明所有步骤，那就琐碎得无法形容了。许多步骤是用各种经典的逻辑证明方法推导得到 的，包括归纳法、反证法等，甚至有些部分还是由旁听的研究生证明的。</span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 21pt"><span style="font-size: 10.5pt; font-family: 'Times New Roman'">留给我们的课后作业是证明逆命题：如果灯原来是关着的，现在却亮了，那么请证明开关的状态一定同原来相反。</span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 21pt"><span style="font-size: 10.5pt; font-family: 'Times New Roman'">我动手开始证明，我真的去证明了。</span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 21pt"><span style="font-size: 10.5pt; font-family: 'Times New Roman'">我在图书馆里待了很长时间。</span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 21pt"><span style="font-size: 10.5pt; font-family: 'Times New Roman'">我对照着<span style="font-family: Times New Roman">Zuck</span><span style="font-family: 宋体">博士的原始证明想依样画葫芦。研究了几个小时之后，我在其中发现了一个错误。可能我抄写的时候抄错了，但是这使得我想通了一件事。如果花费</span><span style="font-family: Times New Roman">3</span><span style="font-family: 宋体">个小时，写满了一块又一块的黑板，每一秒钟都可能出错，最后能够证明的却只是一个很琐碎的结论，那么这种方式有多大的实用性呢？在活生生、充满趣味的现实世界中，你永远都不会有机会使用它。</span></span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 21pt"><span style="font-size: 10.5pt; font-family: 'Times New Roman'">但是，动态逻辑的理论家们对这一点不感兴趣。他们看上它不是因为它有用，而是因为它可以为他们带来终身教职。</span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 21pt"><span style="font-size: 10.5pt; font-family: 'Times New Roman'">我放弃了这门课，并且发誓绝不会去读计算机科学的研究生。</span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 21pt"><span style="font-size: 10.5pt; font-family: 'Times New Roman'">这 个故事告诉我们，计算机科学与软件开发不是一回事。如果你真的非常幸运，你的学校可能会开设很像样的软件开发课程。但是另一种可能是，你的学校根本不教你 在现实中如何编程，因为精英学校都觉得，教授工作技能最好留给职业技术学校、犯人重返社会的培训项目去做。你到处都能学怎么写代码。别忘了，我们是耶鲁大 学，我们的使命是培养未来的世界领袖。你交了<span style="font-family: Times New Roman">16</span><span style="font-family: 宋体">万美元的学费，却在学循环语句的写法，这怎么可以？你以为这是什么地方，难道是机场沿途的酒店里临时拼凑起来不靠谱的</span><span style="font-family: Times New Roman">Java</span><span style="font-family: 宋体">语言培训班？哼哼。</span></span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 21pt"><span style="font-size: 10.5pt; font-family: 'Times New Roman'">麻烦在于我们没有一种真正教授软件开发的专门学校。你如果想成为一个程序员，你可能只能选择计算机科学专业。这是一个不错的专业，但是它同软件开发不是一回事。在那些<span style="font-family: Times New Roman">400</span><span style="font-family: 宋体">等级的课程代号中，去寻找名称中带有</span><span style="font-family: Times New Roman">&ldquo;Practicum&rdquo;</span><span style="font-family: 宋体">这个词的课程吧（编者注：指供人实习的课程）。不要被这个拉丁语单词吓倒，这些都是有用的课程，之所以起这种名字，只是为了让那些文绉绉、装腔作势、满嘴胡说八道的公司经理们觉得高深莫测。</span></span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 21pt"><span style="font-weight: bold; font-size: 10.5pt; font-family: 'Times New Roman'">别担心所有工作都被印度人抢走</span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 21pt"><span style="font-size: 10.5pt; font-family: 'Times New Roman'">我首先要说的是，如果你本身就已经在印度了，或者你就是印度人，那么你真的毫无必要去想这件事，根本不用琢磨所有的工作机会是不是都跑到了印度。那些都是非常好的工作，好好地享受吧，祝你身体健康。</span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 21pt"><span style="font-size: 10.5pt; font-family: 'Times New Roman'">但是，我不断听说计算机系的入学人数下降得很厉害，已经到了危险的程度。根据我听到的说法，其中的一个原因是<span style="font-family: Times New Roman">&ldquo;</span><span style="font-family: 宋体">学生们不愿去学一个工作机会都流向印度的专业</span><span style="font-family: Times New Roman">&rdquo;</span><span style="font-family: 宋体">。这种担心大错特错，有很多理由可以反驳。首先，根据一时性的商业潮流决定个人的职业选择，这是愚蠢的。其次，即使编程工作无一幸存地都流向了印度和中国，但是学习编程本身依然是一种第一流的素质训练，可以为各种超级有趣的工作打下基础，比如业务流程工程（</span><span style="font-family: Times New Roman">business&nbsp;process&nbsp;engineering</span><span style="font-family: 宋体">）。再次，不管是在美国还是在印度，真正优秀的程序员依然是非常非常短缺的，这一点请相信我。不错，确实有相当一批失业的</span><span style="font-family: Times New Roman">IT</span><span style="font-family: 宋体">从 业者在那里鼓噪，抱怨他们长时间找不到工作，但是你知道吗？即使冒着触怒这些人的风险，我还是要说，真正优秀的程序员根本不会失业。最后，你还能找到更好 的专业吗？你觉得什么专业好？主修历史学？如果那样，你毕业的时候就会发现，根本没有其他选择，只能去法学院。不过我倒是知道一件事：</span><span style="font-family: Times New Roman">99%</span><span style="font-family: 宋体">的律师都痛恨他们的工作，痛恨他们当律师的每一分钟。可是，律师每周的工作时间偏偏长达</span><span style="font-family: Times New Roman">90</span><span style="font-family: 宋体">小时。就像我前面说过的：如果你喜欢编程，那么你真是受到了上天的眷顾。你是非常幸运的少数人之一，能够以自己喜欢的事谋生。</span></span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 21pt"><span style="font-size: 10.5pt; font-family: 'Times New Roman'">不 过说实话，我不觉得学生们真的有上面的想法。近年来，计算机系入学人数的下降只是回到了历史上的正常水平，因为前些年的互联网狂热使得入学人数出现了大泡 沫，抬高了基数。由于这种泡沫，许多并不真的喜欢编程的人也来读计算机系。他们心里想的是，只要进了计算机系，将来就能找到诱人的高薪工作，就能获得<span style="font-family: Times New Roman">24</span><span style="font-family: 宋体">岁当上</span><span style="font-family: Times New Roman">CEO</span><span style="font-family: 宋体">、进行</span><span style="font-family: Times New Roman">IPO</span><span style="font-family: 宋体">的机会。谢天谢地，这些人现在都离计算机系远远的了。</span></span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 21pt"><span style="font-weight: bold; font-size: 10.5pt; font-family: 'Times New Roman'">找一份好的暑期实习工作</span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 21pt"><span style="font-size: 10.5pt; font-family: 'Times New Roman'">精明的招聘负责人都知道，喜欢编程的人高中时就将牙医的信息输入了数据库，进入大学前就去过三次电脑夏令营，为校报做过内容管理系统，有过软件公司的夏季实习经历。招聘负责人就是要在你的简历上找这些东西。</span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 21pt"><span style="font-size: 10.5pt; font-family: 'Times New Roman'">如果你喜欢编程，&nbsp;就不要随便什么工作都答应，否则你会犯下最大的错误。不管是暑期工作，还是兼职或者其他性质的工作，只要与编程无关，就不要轻易接受。我知道，其他<span style="font-family: Times New Roman">19</span><span style="font-family: 宋体">岁的孩子都想去购物中心里打工，在那里折叠衬衫。但是你与他们不同，你</span><span style="font-family: Times New Roman">19</span><span style="font-family: 宋体">岁时就已经掌握了一门非常有价值的技能。将时间浪费在折叠衬衫上是很愚蠢的，等到毕业的时候，你的简历上本应该写满了一大堆与编程相关的经历。就让那些财经类的毕业生去租车公司</span><span style="font-family: Times New Roman">&ldquo;</span><span style="font-family: 宋体">帮助人们满足他们租车的需要</span><span style="font-family: Times New Roman">&rdquo;</span><span style="font-family: 宋体">吧，你要干的是别的事（在电视中扮演超人的</span><span style="font-family: Times New Roman">Tom</span></span> <span style="font-size: 10.5pt; font-family: 'Times New Roman'">Welling<span style="font-family: 宋体">注</span><span style="font-family: Times New Roman">1</span><span style="font-family: 宋体">除外）。</span></span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 21pt"><span style="font-size: 10.5pt; font-family: 'Times New Roman'">为了让你的生活变得更容易一些，也为了强调这整篇文章完全是为了满足我的个人目的，我要告诉你，我的公司<span style="font-family: Times New Roman">&mdash;&mdash;Fog&nbsp;Creek</span><span style="font-family: 宋体">软件公司</span><span style="font-family: Times New Roman">&mdash;&mdash;</span><span style="font-family: 宋体">提供软件开发方面的暑期实习机会。我们非常看重简历。</span><span style="font-family: Times New Roman">&ldquo;</span><span style="font-family: 宋体">比起其他公司的实习工作，你在</span><span style="font-family: Times New Roman">Fog&nbsp;Creek</span><span style="font-family: 宋体">最有可能学到更多的编写代码、软件开发、商业运作方面的知识。</span><span style="font-family: Times New Roman">&rdquo;</span><span style="font-family: 宋体">这是去年夏天我们的一个实习生</span><span style="font-family: Times New Roman">Ben</span><span style="font-family: 宋体">说的。他会这样说，并不完全是因为我派了人到他的宿舍让他这样说。我们接受实习申请的截止日期是</span><span style="font-family: Times New Roman">2</span><span style="font-family: 宋体">月</span><span style="font-family: Times New Roman">1</span><span style="font-family: 宋体">日。一起来吧。</span></span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt"><span style="font-size: 10.5pt; font-family: 'Times New Roman'">如果你听从了我的建议，你还是有可能落得一个悲惨的下场，比如很早就卖掉了微软公司的股票，再比如拒绝了谷歌公司的工作机会，原因是你想要一间自己的可以关上门的独立办公室，或者做出了其他生命中愚蠢的决定。但是，这些可不是我的错。我一开始就告诉过你，不要听我的话。</span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt"><span style="font-size: 9pt; font-family: 'Times New Roman'">(注<span style="font-family: Times New Roman">1 </span><span style="font-family: 宋体">： </span><span style="font-family: Times New Roman">T&nbsp;o&nbsp;m&nbsp;W&nbsp;e&nbsp;l&nbsp;l&nbsp;i&nbsp;n&nbsp;g</span><span style="font-family: 宋体">是一个美国演员，&nbsp;在电视剧《超人前传》（</span><span style="font-family: Times New Roman">Smallville</span><span style="font-family: 宋体">）中扮演超人。该电视剧讲述还没有成长为后来超人的克拉克</span><span style="font-family: Times New Roman">&middot;</span><span style="font-family: 宋体">肯特少年时代的故事。)<br />
</span></span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 21pt">&nbsp;</p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 21pt"><span style="font-size: 10.5pt; font-family: 'Times New Roman'">作者简介：</span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt; text-indent: 21pt"><span style="font-size: 10.5pt; font-family: 'Times New Roman'">Joel&nbsp;Spolsky<span style="font-family: 宋体">，世界最具影响的程序员网志</span><span style="font-family: Times New Roman">Joel&nbsp;on</span></span> <span style="font-size: 10.5pt; font-family: 'Times New Roman'">Software<span style="font-family: 宋体">的主人，软件业一位旗帜鲜明的思想者，一位传统软件管理理念的挑战者。他创办的这个网站被程序员誉为</span><span style="font-family: Times New Roman">&ldquo;</span><span style="font-family: 宋体">反呆伯特宣言书</span><span style="font-family: Times New Roman">&rdquo;</span><span style="font-family: 宋体">，并被翻译为三十多种语言。</span><span style="font-family: Times New Roman">Joel</span><span style="font-family: 宋体">毕业于耶鲁大学，随后即进入微软公司工作，曾任微软公司</span><span style="font-family: Times New Roman">E&nbsp;x&nbsp;c&nbsp;e&nbsp;l </span><span style="font-family: 宋体">开发小组项目经理。现在他在自己创办的</span><span style="font-family: Times New Roman">Fog&nbsp;Creek</span><span style="font-family: 宋体">软件公司任</span><span style="font-family: Times New Roman">CEO</span><span style="font-family: 宋体">。此外，他与人合办的</span><span style="font-family: Times New Roman">Stack&nbsp;Overflow</span><span style="font-family: 宋体">已经成为如今最热门的技术网站。</span></span></p>
<p style="margin-top: 0pt; margin-bottom: 0pt"><span style="font-size: 10.5pt; font-family: '宋体'">（本文来自《程序员》杂志2010年1月刊）</span></p>]]></description><category>Booooer.</category><comments>http://www.macgoo.com/myblog/archives/143/#comment</comments><wfw:comment>http://www.macgoo.com/myblog/</wfw:comment><wfw:commentRss>http://www.macgoo.com/myblog/feed.asp?cmt=143</wfw:commentRss><trackback:ping>http://www.macgoo.com/myblog/cmd.asp?act=tb&amp;id=143&amp;key=ad2e9e55</trackback:ping></item><item><title>在线聊天框界面实现以及控制脚本(不包含与服务端交互)</title><author>soddyque@gmail.com (米落)</author><link>http://www.macgoo.com/myblog/archives/141/</link><pubDate>Wed, 13 Jan 2010 09:23:23 +0800</pubDate><guid>http://www.macgoo.com/myblog/archives/141/</guid><description><![CDATA[<link type="text/css" rel="stylesheet" href="http://www.macgoo.com/myblog/PLUGIN/Codelight/SyntaxHighlighter/Styles/shCore.css" />
<link type="text/css" rel="stylesheet" href="http://www.macgoo.com/myblog/PLUGIN/Codelight/SyntaxHighlighter/Styles/shThemeDefault.css" /><script language="javascript" src="http://www.macgoo.com/myblog/PLUGIN/Codelight/SyntaxHighlighter/Scripts/shCore.js"></script><script language="javascript" src="http://www.macgoo.com/myblog/PLUGIN/Codelight/SyntaxHighlighter/Scripts/shBrushCss.js"></script><script language="javascript" src="http://www.macgoo.com/myblog/PLUGIN/Codelight/SyntaxHighlighter/Scripts/shBrushJScript.js"></script>
<p>&nbsp;&nbsp;&nbsp; 在项目中需要一个在线帮助功能,于是临时设计了一个固定浮动的帮助按钮,在触发后能够弹出一个聊天窗口,确保能在任何页面中都能找到帮助.<br />
&nbsp;&nbsp;&nbsp; 由于需要使用弹出一个聊天窗口,而且站点自身使用了jQuery,于是考虑使用jQuery UI,介于加上了它后的页面变大许多,于是做了一些处理,以便形成惰性加载的效果(只在需要的时候加载页面样式表以及脚本).<br />
&nbsp;&nbsp;&nbsp; 在下面的代码中已经提供了详细的注释,使用时只需要引入这个脚本,和指定的CSS样式表即可.</p>
<p>&nbsp;</p>
<p style="text-align: center;"><img title="" alt="" src="../../attachments/2010/1/201001130938198371.jpg" onload="ResizeImage(this,520)" /><br />
界面如上</p>
<p>&nbsp;</p>
<p>JavaScript 代码:</p>
<pre style="border: thin ridge rgb(204, 204, 204); background-color: rgb(240, 240, 240);" height="400" name="CodeLight_code" class="brush:javascript;mouse-over:#ff9">
var chattingWindow;
(function(){
    var inputContext, showContent, floatDiv;
    chattingWindow = {
        SetUp : function() {
            $(document).ready(function(){
                var cssSrc = &quot;&lt;link rel='stylesheet' type='text/css' href='/css/excite-bike/jquery-ui-1.7.2.custom.css'/&gt;&quot;;    /* CSS样式表 */
                var javascriptSrc = &quot;&lt;script type='text/javascript' src='/javascript/jquery-ui-1.7.2.custom.min.js'&gt;&lt;/script&gt;&quot;;   /* jQuery UI dialog 功能脚本 */
                /* 聊天触发浮动按钮,以及聊天界面HTML */
                var chattingContent = &quot;&lt;div id='chattingWindow'&gt;&lt;img src='images/elementsImages/page_pdf.png' alt='在线咨询' title='在线咨询' /&gt;&lt;/div&gt;&lt;div id='chattingWindowDialog'&gt;&lt;div id='dialogcontent'&gt;&lt;div class='ctitle'&gt;聊天记录&lt;/div&gt;&lt;div id='dialogrender'&gt;&lt;/div&gt;&lt;/div&gt;&lt;div id='dialogintro'&gt;&lt;div class='ctitle'&gt;平安门窗&lt;/div&gt;&lt;p&gt;这里是简介&lt;/p&gt;&lt;/div&gt;&lt;div id='dialoginputs'&gt;&lt;textarea id='dialoginputText' &gt;&lt;/textarea&gt;	&lt;button value='发送' &gt;&lt;img src='/images/global/send_cn.gif' /&gt;&lt;/button&gt;&lt;/div&gt;&lt;div id='dialoglogo'&gt;&lt;/div&gt;&lt;/div&gt;&quot;;
                var inited = false; /* 是否已载入 */
                $(document.body).append(chattingContent);  /* 加入到BODY文档流中去 */
                var floatDiv = $(&quot;#chattingWindow&quot;);     /* 获取引用 */ 
                inputContext = $(&quot;#dialoginputs &gt; textarea&quot;);
                showContent = $(&quot;#dialogrender&quot;);
                showContent.height(250);
                floatDiv.click(function(){  /* 触发弹出窗口页面 */
                    if(!inited) {  /* 第一次使用时的配置工作 */
                        inited = true;
                        $(cssSrc).appendTo(document.body);  /* 引入jQuery UI 样式表,不能删除了,否则后面无法正常显示,可见样式表设置并不会临时保存 */
                        $(javascriptSrc).appendTo(document.body).remove();  /* 引入jQuery UI 脚本,可以删除,因为已经保存在内存中了 */
                        /* diaolog配置 */
                        $(&quot;#chattingWindowDialog&quot;).dialog({autoOpen:false, modal: true, title: &quot;在线客服&quot;, width: 620, height: 470, show: true, hide: true});
                        inputContext.keydown(function(event){  /* 回车按钮事件 */
                        var keycode = event.keyCode || event.which || event.charCode;
                        if(keycode == 13) {
                            chattingWindow.SendMsg(inputContext.val());
                            inputContext.val(&quot;&quot;);
                            return false;
                        }
                    });
                    }
                    $(&quot;#chattingWindowDialog&quot;).dialog(&quot;open&quot;);  /* 打开对话框 */
                });
                $(&quot;#dialoginputs &gt; button&quot;).click(function(){  /* 发送按钮事件 */
                    chattingWindow.SendMsg(inputContext.val());
                    inputContext.val(&quot;&quot;);
                });
                
            });
        },
        SendMsg : function(content) {
            var d = new Date();
            showContent.append(&quot;&lt;div class='send-msg-name'&gt;我 &quot; + (d.getHours() + &quot;:&quot; + d.getMinutes() + &quot;:&quot; + d.getSeconds()) + &quot;&lt;/div&gt;&quot;);
            showContent.append(&quot;&lt;p class='send-msg-content'&gt;&quot; + content + &quot;&lt;/p&gt;&quot;);
            showContent.scrollTop(showContent[0].scrollHeight);
        }
    }
})();
chattingWindow.SetUp();</pre>
<p>&nbsp;</p>
<p>CSS 样式表:</p>
<pre style="border: thin ridge rgb(204, 204, 204); background-color: rgb(240, 240, 240);" height="400" name="CodeLight_code" class="brush:css;mouse-over:#ff9">
#chattingWindow {
	position: fixed;
	bottom: 10px;
	right: 10px;
	
}
#chattingWindow:hover, #chattingWindow a:hover {
	cursor: help;
}
#chattingWindowDialog {
	display: none;
	width: 700px;
	overflow: hidden;
	white-space: normal;
}
div.ctitle {
	background: #06F url(/css/excite-bike/images/ui-bg_diagonals-thick_26_2293f7_40x40.png) repeat left top;
	width: auto;
	height: 24px;
	border: 1px solid #09F;
	overflow: hidden;
}
#dialogcontent {
	width: 450px;
	height: 280px;
	float: left;
	border: 1px solid #09F;
	margin: 2px;
	position: relative;
	overflow: hidden;
}
#dialogrender {
	position: absolute;
	margin-bottom: 5px;
	width: 450px;
	overflow-y: scroll;
	word-break:break-all;
	height: inherit;
}
#dialoginputs {
	width: 450px;
	height: 115px;
	float: left;
	border: 1px solid #09F;
	margin: 2px;
	text-indent:inherit;
}
#dialoginputs textarea {
	float: left;
	border: 0px;
	width: 340px;
	height: 113px;
}
#dialoginputs button {
	float: left;
	border: 0 none;
	background: #FFF;
	margin: 4px;
	width: 100px;
	height: 100px;
}

#dialogintro {
	width: 120px;
	height: 280px;
	border: 1px solid #09F;
	float: left;
	margin: 2px;
}
#dialoglogo {
	width: 120px;
	height: 115px;
	border: 1px solid #09F;
	float: left;
	margin: 2px;
}
.send-msg-name	  {font-family:arial,宋体;font-size:13px;color:#666;font-weight:normal;margin-top:6px}
.send-msg-content {color:#000; }
.recv-msg-content {color:#00f; }</pre>
<p>&nbsp;</p>
<script language="javascript">SyntaxHighlighter.config.clipboardSwf = 'http://www.macgoo.com/myblog/PLUGIN/Codelight/SyntaxHighlighter/Scripts/clipboard.swf';SyntaxHighlighter.all();</script>]]></description><category>Programer</category><comments>http://www.macgoo.com/myblog/archives/141/#comment</comments><wfw:comment>http://www.macgoo.com/myblog/</wfw:comment><wfw:commentRss>http://www.macgoo.com/myblog/feed.asp?cmt=141</wfw:commentRss><trackback:ping>http://www.macgoo.com/myblog/cmd.asp?act=tb&amp;id=141&amp;key=f1828a14</trackback:ping></item><item><title>新年.总结.展望</title><author>soddyque@gmail.com (米落)</author><link>http://www.macgoo.com/myblog/archives/140/</link><pubDate>Thu, 31 Dec 2009 17:23:03 +0800</pubDate><guid>http://www.macgoo.com/myblog/archives/140/</guid><description><![CDATA[<p>&nbsp;&nbsp;&nbsp; 零九年结束了,迎来崭新的一零年.虎年.<br />
&nbsp;&nbsp;&nbsp; 正如上次年末总结一样,今天同样如此,在上次的展望中,仅仅只有Asp.net/C# 在不贬值的情况下偶有练习,其他的却频露疲样.数数自己零九年做了哪些鸡毛蒜皮.</p>
<ul>
    <li>&nbsp;IT活动周上,展示了一个多月功夫打造的pyhton + django ,依托 Google engine app ,从此喜欢上了 GEA.虽然网站最后没能假设在云上,但好歹体会到了python 的精美.特别是脚本语言和强大精炼的语法,让我顿时知道了什么叫做效率,听说Ruby更好,但谁交GEA只支持,我学习python 可以完全是因为GEA支持,能够放到云上去,这才是根本动力,只有在接触了python 后才知道脚本语言能有这么大的威力,虽然目前没能假设一个东西在上面,不过好马迟早会有好鞍安在上面的不是么~</li>
    <li>两次系篮球赛,我是跑龙套的.</li>
    <li>暑假打工,头一回正儿八经的站在了服务人员队列中,要知道以前可都是被服务的.还头一次误人子弟的做了一回家教.</li>
    <li>迎新接待+带班,认识了可爱的学弟学妹们,也意识到自己在不断的老去,还有学生会拜拜~</li>
    <li>ACM,林华学长还有谢玉成学长,虽然一题未AC,但起码也让我意识到了算法的重要性,而且加强的数据结构的复习.</li>
    <li>运动会上,400米,第二.我的运动员生涯啊.</li>
    <li>冬季技能大赛,虽然结果有点遗憾,没能一举AC,而且题目本身并不是很难,算是自己大意了.复习了数据结构.</li>
    <li>项目组,由于算法比赛并不能够使用C#/JavaScript/ActionScript,只支持C/C++/Pascal/Java 所以只能跳到Java上去.而且项目组出于成本的考虑,也选择了Java阵营的一些产品,我也跳到了Java这边鼓捣struts2,hibernate.当然更重要的并不是技术上的提高,而是意识到了团队的重要性,要知道一个人生产力是有限的,但是多几个人就不同了,而中国就是不缺人.</li>
</ul>
<p>&nbsp;&nbsp;&nbsp; 总结零九年就是: 下学期里找到方向了.</p>
<p>&nbsp;&nbsp;&nbsp; 人这个东西,不鼓捣点东西就不罢休的,可是不能总是盲目的乱做对不,所以要来点目标:</p>
<ul>
    <li>Google Engine App for Java</li>
    <li>Windows Azure</li>
    <li>多点东西(人文书籍50本),多写点东西(博客常更新)</li>
    <li>自考</li>
    <li>高级程序员</li>
    <li>计算机等级二级(为了自考的计算机那科)</li>
    <li>项目悉数(我也无法承诺是些啥,太随性了)</li>
    <li>ACM比赛上AC几题.</li>
</ul>
<p>&nbsp;&nbsp;&nbsp; 还活着,还能乱蹦乱跳,还能大步走~真好.</p>]]></description><category>Booooer.</category><comments>http://www.macgoo.com/myblog/archives/140/#comment</comments><wfw:comment>http://www.macgoo.com/myblog/</wfw:comment><wfw:commentRss>http://www.macgoo.com/myblog/feed.asp?cmt=140</wfw:commentRss><trackback:ping>http://www.macgoo.com/myblog/cmd.asp?act=tb&amp;id=140&amp;key=3c5b7c64</trackback:ping></item><item><title>使用JavaScript 对Cookie 操作的封装</title><author>soddyque@gmail.com (米落)</author><link>http://www.macgoo.com/myblog/archives/139/</link><pubDate>Thu, 31 Dec 2009 17:12:04 +0800</pubDate><guid>http://www.macgoo.com/myblog/archives/139/</guid><description><![CDATA[<div id="dictaudio">&nbsp;通过本篇,您能了解到:</div>
<ul>
    <li>匿名函数</li>
    <li>闭包的产生</li>
    <li>JavaScript实现private 以及 public 访问权限</li>
    <li>document.cookie 的操作</li>
</ul>
<p>&nbsp;</p>
<p>&nbsp; &nbsp; Javascript 没有 private , public 访问权限设置的关键字,但是可以通过一定的技巧来模拟出相同的结果.<br />
&nbsp;&nbsp;&nbsp; 首先我们来看下面一行代码:</p>
<div class="cnblogs_code">
<div><!--<br/ />
<br/ />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ />
http://www.CodeHighlighter.com/<br/ />
<br/ />
--><span style="color: rgb(0, 0, 255);">var</span><span style="color: rgb(0, 0, 0);">&nbsp;i&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;(</span><span style="color: rgb(0, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">,&nbsp;</span><span style="color: rgb(0, 0, 0);">2</span><span style="color: rgb(0, 0, 0);">,&nbsp;</span><span style="color: rgb(0, 0, 0);">3</span><span style="color: rgb(0, 0, 0);">,&nbsp;</span><span style="color: rgb(0, 0, 0);">4</span><span style="color: rgb(0, 0, 0);">,&nbsp;</span><span style="color: rgb(0, 0, 0);">5</span><span style="color: rgb(0, 0, 0);">);</span></div>
</div>
<p>&nbsp;&nbsp;&nbsp; 变量 i 最后的结果为 5.<br />
&nbsp;&nbsp;&nbsp; 这是逗号操作符的结果,也就是说返回最后的一个值,小括号改变了这行代码的优先级,否则 var i = 1, 2, 3, 4, 5; 会报错缺少标识符.</p>
<div class="cnblogs_code">
<div><!--<br/ />
<br/ />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ />
http://www.CodeHighlighter.com/<br/ />
<br/ />
--><span style="color: rgb(0, 0, 255);">var</span><span style="color: rgb(0, 0, 0);">&nbsp;i&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;(</span><span style="color: rgb(0, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">,&nbsp;</span><span style="color: rgb(0, 0, 0);">2</span><span style="color: rgb(0, 0, 0);">,&nbsp;</span><span style="color: rgb(0, 0, 0);">3</span><span style="color: rgb(0, 0, 0);">,&nbsp;</span><span style="color: rgb(0, 0, 0);">4</span><span style="color: rgb(0, 0, 0);">,&nbsp;</span><span style="color: rgb(0, 0, 255);">function</span><span style="color: rgb(0, 0, 0);">(){&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">5</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">5</span><span style="color: rgb(0, 0, 0);">;});</span></div>
</div>
<p>&nbsp;&nbsp;&nbsp; 变量 i 最后的结果为 一个函数, 返回结果 25.<br />
&nbsp;&nbsp;&nbsp; 这就是Javascript 的灵活之处,能够赋值任意类型而不必提前声明.现在我们完全可以进行如下调用:</p>
<div class="cnblogs_code">
<div><!--<br/ />
<br/ />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ />
http://www.CodeHighlighter.com/<br/ />
<br/ />
--><span style="color: rgb(0, 0, 0);">i();</span> <br />
alert( i() );</div>
</div>
<p>&nbsp;&nbsp;&nbsp; 来获得返回25的一次方法调用.</p>
<p>&nbsp;</p>
<p>&nbsp; &nbsp; 我们继续, 变量 i 是通过赋值符来获取函数的引用的, 也就是说在等号右边的小括号运算完后返回的最后一个结果的引用还在,虽然我们无法显示调用,但它确实存在,如果要不通过变量的引用而调用呢?</p>
<div class="cnblogs_code">
<div><!--<br/ />
<br/ />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ />
http://www.CodeHighlighter.com/<br/ />
<br/ />
--><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">,&nbsp;</span><span style="color: rgb(0, 0, 0);">2</span><span style="color: rgb(0, 0, 0);">,&nbsp;</span><span style="color: rgb(0, 0, 0);">3</span><span style="color: rgb(0, 0, 0);">,&nbsp;</span><span style="color: rgb(0, 0, 0);">4</span><span style="color: rgb(0, 0, 0);">,&nbsp;</span><span style="color: rgb(0, 0, 255);">function</span><span style="color: rgb(0, 0, 0);">(){&nbsp;&nbsp;&nbsp;&nbsp;alert(</span><span style="color: rgb(0, 0, 0);">5</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">5</span><span style="color: rgb(0, 0, 0);">);})()</span></div>
</div>
<p>&nbsp;&nbsp;&nbsp; 上面的代码执行后,弹出一个消息框,显示25.<br />
&nbsp;&nbsp;&nbsp; 为了显示方便,我将上个例子的函数改为弹出消息框了.<br />
&nbsp;&nbsp;&nbsp; 两对小括号 () (); 前面一对表示返回一个结果,如果该结果为一个函数,由第二对小括号发生调用.<br />
&nbsp;&nbsp;&nbsp; 也就是通过前面一对括号发生匿名函数的引用,以便在下面进行引用.这就是对匿名函数的调用.<br />
&nbsp;&nbsp;&nbsp; 关于更多匿名函数的使用可以参考文尾的引用连接.</p>
<p>&nbsp;</p>
<p>&nbsp; &nbsp; 闭包产生的原因是因为作用域的不同,子作用域引用了父作用域的变量,而返回子作用域,父作用域按理来说执行完毕后该销毁掉了,只是子作用域一直存在,且一直握有父作用域的引用,所以才一直保留.<br />
&nbsp;&nbsp;&nbsp; 来看下面的代码</p>
<pre class="brush:javascript;mouse-over:#ff9" name="CodeLight_code" height="400" style="border: thin ridge rgb(204, 204, 204); background-color: rgb(240, 240, 240);">
function parent() {
    var a = 1;
    function child(){
        var b = 2;
        alert(a);
        alert(b);
    }
}</pre>
<p>&nbsp;&nbsp;&nbsp; 父函数 parent 中包含了一个 child 子函数,在子函数中有一个对父函数中 a 变量的引用(输出其值).<br />
&nbsp;&nbsp;&nbsp; 我们来让父函数执行完后返回其声明的子函数</p>
<pre style="border: thin ridge rgb(204, 204, 204); background-color: rgb(240, 240, 240);" height="400" name="CodeLight_code" class="brush:javascript;mouse-over:#ff9">
function parent() {
    var a = 1;
    function child(){
        var b = 2;
        alert(a);
        alert(b);
    }
    return child;
}
var t = parent();
t();</pre>
<p>&nbsp;&nbsp;&nbsp; 在10行中, 我们执行了parent 函数,返回了在函数内部声明的函数 child,这时变量 t 持有该返回对象(此时是一个可以执行的函数)的引用,在11行代码中我们调用了它.结果分别输出了 1 和 2.<br />
&nbsp;&nbsp;&nbsp; 注意,输出 2, 是因为我们在子函数体内声明了一个变量,而输出 1, 我们在该函数体内并没有相应的定义变量 a ,而是发生了对父函数里的变量的引用,也就是说引用了父作用域的变量.<br />
&nbsp;&nbsp;&nbsp; 而此时又能能够完成输出的,也就是说变量 a 还存在.可是我们无法直接对其引用 (比如 parent.a),因为函数已经执行完毕,没有了其相应的引用,我们只能通过所返回的子函数的引用来进行访问.<br />
&nbsp;&nbsp;&nbsp; 假如我又在父函数中声明了其他的变量呢? 结果是一样的,子函数能够访问,而如果子函数并不返回相应的引用的话,我们根本无法从外部访问到.这就形成了闭包.</p>
<p>&nbsp;</p>
<p>&nbsp; &nbsp; 闭包能够干些什么呢?如果你有一个不想让外部随意修改的变量该怎么做?那就去使用闭包.</p>
<pre style="border: thin ridge rgb(204, 204, 204); background-color: rgb(240, 240, 240);" height="400" name="CodeLight_code" class="brush:javascript;mouse-over:#ff9">
myObj = {};   //声明一个全局变量,它是一个window对象的属性(window.myObj)
(function(){
    var i = 4;
    myObj = {    //引用全局变量,对其进行赋值
        getI : function() {    //get方法,一个函数
            return i;
        },
        setI : function(val) {    //set方法,限制值的设定
            if(val &gt; 100) {
                alert(&quot;i connt &gt; 100&quot;);
                return;
            }
            i = val;
        }
    }
})();    //匿名函数的调用,由于也是一个函数,所以作为一个子作用域,在执行完之后销毁,避免代码污染
myObj.setI(5);  //成功
myObj.setI(101);  //失败
alert(myObj.getI());
alert(myObj.i);  //错误,没有该属性
</pre>
<p>&nbsp; &nbsp; 至此我们简单的实现了public 访问权限以及 private 访问权限 (也就给你想给你的,不给你不想给你的)&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp; 在页面中,我们通常使用 document.cookie 属性来访问,对其赋新值就会创建一个新的Cookie,一个Cookie通常具有五个属性:value (存储的值), date (UTC格式的时间,代表什么时间过期, domain (域,Cookie的所有者), Path (子目录).</p>
<p>&nbsp;&nbsp;&nbsp; 而在平常的开发中,如果仅仅使用 document.cookie 属性进行访问,会很麻烦,因为只能向其赋值字符串,并且在读取后还要进行字符串切割,才能获取指定变量名称的值.document.cookie 读取时,返回的是所有赋值的值,而不包括过期时间,域之类的信息,只能再次独设置.</p>
<p>&nbsp; &nbsp; 下面就附上代码,全部封装到Cookie全局对象中,暴露出几个方法.</p>
<p>&nbsp; &nbsp; Get : 返回指定所有cookie字符串.<br />
&nbsp;&nbsp;&nbsp; Set : 设置cookie 字符串.<br />
&nbsp;&nbsp;&nbsp; Clear : 清除所有cookie对象.<br />
&nbsp;&nbsp;&nbsp; GetDayTime : 获取指定距今val天的Date对象.<br />
&nbsp;&nbsp;&nbsp; Write : 写cookie.已重载.详见代码.<br />
&nbsp;&nbsp;&nbsp; Query : 查询cookie. 已重载.详见代码.<br />
&nbsp;&nbsp;&nbsp; Update : 修改cookie.<br />
&nbsp;&nbsp;&nbsp; Delete : 删除cookie.</p>
<p><pre style="border: thin ridge rgb(204, 204, 204); background-color: rgb(240, 240, 240);" height="400" name="CodeLight_code" class="brush:javascript;mouse-over:#ff9;collapse:true">
Cookie = {};
/*
*   练习总结:
*       Date对象的setTime方法是设置距离1970-01-01以来的毫秒数,设置到对象里去,返回的是据那以后的毫秒数而不是原对象.
*       如果Cookie 不设置 expires 属性,或者expires 时间比本地时间少,那么将会在下一次浏览时过期.
*       document.cookie 对象返回的是所有值的字符串形式,不包含 expires 或者其他.
*
*/
(function() {
    var nDay = 24 * 60 * 60 * 1000;
    var isString = function(v) {
        return typeof v === &quot;string&quot;;
    }
    var isArray = function(v) {
        return Object.prototype.toString.apply(v) == &quot;[object Array]&quot;;
    }
    var isObject = function(v) {
        return v &amp;&amp; typeof v == &quot;object&quot;;
    }
    var isDate = function(v) {
        return Object.prototype.toString.apply(v) == &quot;[object Date]&quot;;
    }
    var getTime = function() {
        return new Date().getTime();
    }
    var trim = function(val) {
        return (val || &quot;&quot;).replace(/^\s+|\s+$/g, &quot;&quot;);
    }
    var tryEval = function(val) {
        var Obj, e;
        try {
            Obj = eval(val);
        } catch (e) {
            Obj = val;
        }
        return Obj;
    }
    var ObjectToString = function(o) {
        var tstr = &quot;{&quot;;
        for (var v in o) {
            if (isArray(o[v])) {
                tstr += v + &quot;:&quot; + ArrayToString(o[v]) + &quot;,&quot;;
            } else if (isObject(o[v])) {
                tstr += v + &quot;:&quot; + ObjectToString(o[v]) + &quot;,&quot;;
            } else if (isString(o[v])) {
                tstr += v + &quot;:\&quot;&quot; + o[v].toString() + &quot;\&quot;,&quot;;
            } else {
                tstr += v + &quot;:&quot; + o[v].toString() + &quot;,&quot;;
            }
        }
        return tstr.slice(0, -1) + &quot;}&quot;;
    }
    var ArrayToString = function(o) {
        var tstr = &quot;[&quot;;
        for (var v in o) {
            if (isArray(o[v])) {
                tstr += ArrayToString(o[v]) + &quot;,&quot;;
            } else if (isObject(o[v])) {
                tstr += ObjectToString(o[v]) + &quot;,&quot;;
            } else {
                tstr += o[v].toString() + &quot;,&quot;;
            }
        }
        return tstr.slice(0, -1) + &quot;]&quot;; ;
    }
    Cookie = {
        Get: function() {
            return document.cookie;
        },
        Set: function(val) {
            document.cookie = val;
        },
        Clear: function() {
            var temp = this.Query();
            var o;
            for (o in temp) {
                this.Delete(o);
            }
        },
        GetDayTime: function(val) {
            var texpires = new Date();
            texpires.setTime(texpires.getTime() + val * nDay);
            return texpires;
        },
        Write: function() {
            /*
            *   Cookie.Write(Object); 写入对象,名称为main;
            *   Cookie.Write(varname, Object); varname:变量名, Object:写入对象;
            *   Cookie.Write(Object, Date); Object:写入对象, Date:过期时间;
            *   Cookie.Write(varname, Object, Date); varname:变量名, Object:写入对象, Date:过期时间;
            *   Cookie.Write(varname, Object, Date, Domain, Path); varname:变量名, Object:写入对象, Date:过期时间, Domain:域, Path: 子目录;
            */
            if (arguments.length == 1) {
                var tvalue = arguments[0];
                var tstr = &quot;&quot;;
                var texpires = new Date(); texpires.setTime(texpires.getTime() + 1 * nDay);
                if (isArray(tvalue)) {
                    tstr = ArrayToString(tvalue);
                } else if (isObject(tvalue)) {
                    tstr = ObjectToString(tvalue);
                } else {
                    tstr = tvalue.toString();
                }
                tstr = &quot;main=&quot; + escape(tstr) + &quot;;expires=&quot; + texpires.toGMTString() + &quot;;&quot;;
            } else if (arguments.length == 2) {
                var tname, tvalue, texpires, tstr = &quot;&quot;;
                if (isDate(arguments[1])) {
                    tname = &quot;main&quot;;
                    tvalue = arguments[0];
                    texpires = arguments[1];
                } else {
                    tname = arguments[0];
                    tvalue = arguments[1];
                    texpires = new Date(); texpires.setTime(texpires.getTime() + 1 * nDay);
                }

                if (isArray(tvalue)) {
                    tstr += ArrayToString(tvalue);
                } else if (isObject(tvalue)) {
                    tstr += ObjectToString(tvalue);
                } else {
                    tstr = tvalue.toString();
                }
                tstr = tname + &quot;=&quot; + escape(tvalue) + &quot;;expires=&quot; + texpires.toGMTString() + &quot;;&quot;;

            } else if (arguments.length == 3) {
                var tname = arguments[0], tvalue = arguments[1], texpires = arguments[2], tstr = &quot;&quot;;
                if (isArray(tvalue)) {
                    tstr = ArrayToString(tvalue);
                } else if (isObject(tvalue)) {
                    tstr = ObjectToString(tvalue);
                } else {
                    tstr = tvalue.toString();
                }
                tstr = tname + &quot;=&quot; + escape(tvalue) + &quot;;expires=&quot; + texpires.toGMTString() + &quot;;&quot;;
            } else if (arguments.length == 5) {
                var tname = arguments[0], tvalue = arguments[1], texpires = arguments[2], tdomain = arguments[3], tpath = arguments[4], tstr = &quot;&quot;;
                if (isArray(tvalue)) {
                    tstr = ArrayToString(tvalue);
                } else if (isObject(tvalue)) {
                    tstr = ObjectToString(tvalue);
                } else {
                    tstr = tvalue.toString();
                }
                tstr = tname + &quot;=&quot; + escape(tvalue) + &quot;;expires=&quot; + texpires.toGMTString() + &quot;;domain=&quot; + tdomain + &quot;;path=&quot; + tpath + &quot;;&quot;;
            }
            alert(tstr);
            this.Set(tstr);
        },
        Query: function() {
            /*
            *   Cookie.Query(); 返回所有Cookie值组成的Object;
            *   Cookie.Query(string); 返回指定名称的Object; 失败则返回 undefined;
            *   Cookie.Query(string, Object); 为指定对象写入指定名称的Object,并返回; 失败则返回 undefined;
            */
            var tname = tvalue = &quot;&quot;, tright = -1;
            var tstr = this.Get();
            var tObj = {};
            if (arguments.length == 0) {
                var i = 0;
                do {
                    tname = trim(tstr.slice(i, tstr.indexOf(&quot;=&quot;, i)));
                    tright = tstr.indexOf(&quot;;&quot;, i);
                    if (tright == -1) {
                        tvalue = unescape(tstr.slice(tstr.indexOf(&quot;=&quot;, i) + 1, tstr.length));
                    } else {
                        tvalue = unescape(tstr.slice(tstr.indexOf(&quot;=&quot;, i) + 1, tright));
                    }
                    tObj[tname] = tryEval(tvalue);
                    i = tstr.indexOf(&quot;;&quot;, i) == -1 ? -1 : tstr.indexOf(&quot;;&quot;, i) + 1;
                } while (i != -1);

            } else {
                tname = arguments[0];
                if (tstr.indexOf(tname) == -1) return undefined;
                var i = tstr.indexOf(tname);
                tname = trim(tstr.slice(i, tstr.indexOf(&quot;=&quot;, i)));
                tright = tstr.indexOf(&quot;;&quot;, tstr.indexOf(tname)) == -1 ? tstr.length : tstr.indexOf(&quot;;&quot;, tstr.indexOf(tname));
                tvalue = unescape(tstr.slice(tstr.indexOf(tname) + tname.length + 1, tright));

                if (arguments.length == 1) {
                    tObj = tryEval(tvalue);
                } else if (arguments.length == 2) {
                    tObj = arguments[1];
                    tObj[tname] = tryEval(tvalue);
                }
            }
            return tObj;
        },
        Update: function() {
            return this.Write.apply(this, arguments);
        },
        Delete: function() {
            if (arguments.length == 1) {
                var varname = arguments[0];
                if (this.Query(varname)) {
                    this.Update(varname, &quot;&quot;, new Date(1970, 01, 01));
                }
            }
        }
    }
})();
//alert(isString(&quot;asd&quot;));
//Cookie.Write([1,{t:1, p:&quot;asdasd&quot;, ary:[1,2,3,45]},3,4,5,6,7,8,9]);
//Cookie.Write(&quot;myvar&quot;, {t:1, p:&quot;asdasd&quot;});
//Cookie.Write(&quot;myvar&quot;, {t:1, p:&quot;asdasd&quot;}, new Date(2009, 12, 31));
//alert(Cookie.Query(&quot;myvar&quot;));
//Cookie.Write(&quot;myvar&quot;, {t:1, p:&quot;asdasd&quot;}, new Date(2009, 12, 31));
//Cookie.Update(&quot;myvar&quot;, {t:1, p:&quot;asdasd&quot;}, new Date(2009, 12, 31));
//Cookie.Write(&quot;myvar&quot;, {t:1, p:&quot;aasdasd&quot;}, Cookie.GetDayTime(5));
//Cookie.Delete(&quot;myvar&quot;);
//alert(Cookie.Query(&quot;main&quot;));</pre></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; 其中有一个从字符串eval 成对象的执行,以及从Object 或者 Array 对象获得对应字符串形式的功能函数,模拟了一些JSON的操作.当然,并不能存储所有的JavaScript 对象,仅仅满足一部分,我已经感觉够用了.</p>
<p>&nbsp;</p>
<p>&nbsp; &nbsp; 个人理解有限,请各位多多指教.</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; <a target="_blank" href="http://www.cnblogs.com/Files/dreampuf/Cookie.zip" title="Cookie.js.zip">源代码下载 : Cookie.js.zip</a></p>
<p>&nbsp;</p>
<p>Javascript的匿名函数 : <a target="_blank" href="http://dancewithnet.com/2008/05/07/javascript-anonymous-function/">http://dancewithnet.com/2008/05/07/javascript-anonymous-function/ </a> <br />
Javascript 的闭包 : <a target="_blank" href="http://www.cn-cuckoo.com/wordpress/wp-content/uploads/2007/08/JavaScriptClosures.html">http://www.cn-cuckoo.com/wordpress/wp-content/uploads/2007/08/JavaScriptClosures.html</a><br />
Cookie 文件的格式 : <a target="_blank" href="http://www.cnblogs.com/sephil/archive/2008/05/06/cookiefmt.html">http://www.cnblogs.com/sephil/archive/2008/05/06/cookiefmt.html</a></p>]]></description><category>Programer</category><comments>http://www.macgoo.com/myblog/archives/139/#comment</comments><wfw:comment>http://www.macgoo.com/myblog/</wfw:comment><wfw:commentRss>http://www.macgoo.com/myblog/feed.asp?cmt=139</wfw:commentRss><trackback:ping>http://www.macgoo.com/myblog/cmd.asp?act=tb&amp;id=139&amp;key=0972e604</trackback:ping></item><item><title>Visual Studio 2010 beta2 尝鲜</title><author>soddyque@gmail.com (米落)</author><link>http://www.macgoo.com/myblog/archives/138/</link><pubDate>Sat, 26 Dec 2009 19:16:21 +0800</pubDate><guid>http://www.macgoo.com/myblog/archives/138/</guid><description><![CDATA[<p>&nbsp;&nbsp;&nbsp; 微软的Visual Studio 2010 已经发布了 beta2 版了,下载来看试了下味道~</p>
<p>&nbsp;</p>
<p style="text-align: center;"><img style="width: 482px; height: 355px;" onload="ResizeImage(this,520)" src="http://www.macgoo.com/myblog/attachments/2009/12/200912261918433620.jpg" alt="" title="" /><br />
&nbsp;</p>
<p style="text-align: center;">&nbsp;</p>
<p>&nbsp;</p>
<p style="text-align: center;"><img style="width: 482px; height: 287px;" onload="ResizeImage(this,520)" src="http://www.macgoo.com/myblog/attachments/2009/12/200912261919006217.jpg" alt="" title="" /></p>
<p>&nbsp;</p>
<p style="text-align: center;"><img style="width: 564px; height: 388px;" onload="ResizeImage(this,520)" src="http://www.macgoo.com/myblog/attachments/2009/12/200912261919514540.jpg" alt="" title="" /></p>
<p>&nbsp;&nbsp;&nbsp; 新建项目里面相比vs2008多了许多模版,其中比较吸引我的就是MVC,还有Cloud Service .<br />
&nbsp;&nbsp;&nbsp; 由于最近在鼓捣Java , Struts2, Hibernate, 所以自然会拿出来和.Net 这边的比较比较.<br />
&nbsp;&nbsp;&nbsp; Asp.net Mvc 中 Routing 主要起将URL请求转换到指定Control中去,并且通过URL捕获传参,Struts2中是通过 Filter 来启用某个Action.<br />
&nbsp;&nbsp;&nbsp; Asp.net Mvc 中 Control 如其名字一样,控制器,负责将实体模型填充到ViewData或者TempData中去,然后在每个public方法中返回指定视图,并且能够指定名称或者传参.Struts2中 Action 起控制器的作用,Struts2 中获取参数很直接的就在Action的属性里面,传参的话直接添加到request里去就可以了,也很是方便,返回的视图是通过预先约定的name定义好的.<br />
&nbsp;&nbsp;&nbsp; 当然也有一些不同,Struts的每个Action对应的就是一个提交过来的表单,这和Asp.net Mvc里的Control 完全不同,Control 是写在public下的方法中的,两个框架的颗粒度不同,基本上Asp.net Mvc只需要几个Control ,然后根据不同的URL请求来判断该使用那种方法,而可能在一个页面中就有很多个表单提交,这就需要不同的Action 来完成相应的业务.</p>
<p>&nbsp;&nbsp;&nbsp; 还有微软的云 Azure, 虽然还没能写个demo,不过看帮助也能得知个大概,不过貌似相比Google Engine App, Azure需要的配置文件也真的算是多,不知道是不是在Visual Studio舒适的环境待惯了,还是怎么的,都不喜欢那么动辄几个文件的配置了.</p>
<p>&nbsp;&nbsp;&nbsp; 多写代码少说话~</p>]]></description><category>Programer</category><comments>http://www.macgoo.com/myblog/archives/138/#comment</comments><wfw:comment>http://www.macgoo.com/myblog/</wfw:comment><wfw:commentRss>http://www.macgoo.com/myblog/feed.asp?cmt=138</wfw:commentRss><trackback:ping>http://www.macgoo.com/myblog/cmd.asp?act=tb&amp;id=138&amp;key=2dbb1f4e</trackback:ping></item><item><title>Java Servlet &amp;amp; MySQL &amp;amp; ExtJS 练习总结</title><author>soddyque@gmail.com (米落)</author><link>http://www.macgoo.com/myblog/archives/137/</link><pubDate>Sun, 06 Dec 2009 21:22:51 +0800</pubDate><guid>http://www.macgoo.com/myblog/archives/137/</guid><description><![CDATA[<p>&nbsp;&nbsp;&nbsp; 由于项目需要,所以转到了Java 平台,这是个习作,用于Java 上web 开发的练习.打算要实现一个简单的购物车模型的,只是时间不够马上又有别的任务了,于是就此作罢,拿出来,做个笔记.</p>
<p>&nbsp;&nbsp;&nbsp; 环境是 : Win 7, Mysql 5.1 , MyEclipse 8 GA.</p>
<p>&nbsp;</p>
<p style="text-align: center;"><img title="" alt="" src="../../../attachments/2009/12/200912062133191763.png" onload="ResizeImage(this,520)" /><br />
数据库设计</p>
<p>&nbsp;</p>
<p style="text-align: center;"><img title="" alt="" src="http://www.macgoo.com/myblog/attachments/2009/12/200912062129143703.png" onload="ResizeImage(this,520)" /><br />
这是整个项目的文件层次</p>
<p style="text-align: left;">&nbsp;&nbsp;&nbsp; 首先构建一些实体类,他们对应数据库中的每一张表.<br />
&nbsp;&nbsp;&nbsp; 然后为每个实体类写他们的数据库访问类也就是以DAO结尾的类,他们都继承于AbstractDAO抽象类,他是一个泛型类,提供了简单的增删改查方法,构造参数为数据库连接地址,用户名和密码,三个字符串参数.其他DAO都继承这个类然后实现这些方法即可.<br />
&nbsp;&nbsp;&nbsp; 接下来是BLL层,因为发现要跳转到Struts2框架上了,所以就放弃继续写下去的念头了,虽然三层还是可以这样摆,但是一些业务逻辑应该可以放到别的地方.现在只是简单的实现了一些登录,注册逻辑,其他的都没实现.<br />
&nbsp;&nbsp;&nbsp; 最后是前台的搭建,由于使用的是ExtJS,找了很多资料,原来也鼓捣过一次HelloWorld 的练习,不过和这次显然不能同日而语.由于只实现了登录和注册,两个Window嵌套两个Form,最后ajax提交,没有什么特别的.中间交互使用的是JSON,在Java端还犯难了,最后找了Json-lib 这一组建来帮忙,简陋的登录系统实现了.</p>
<p style="text-align: left;">&nbsp;&nbsp;&nbsp; 总体上和 .net 比较就是开发不那么舒服了,毕竟离开了维修死丢丢那么舒服的开发环境,尤其是代码自动完成,Eclipse似乎很迟钝.<br />
&nbsp;&nbsp;&nbsp; 这一趟下来学到了不少东西,再接再厉.</p>]]></description><category>Programer</category><comments>http://www.macgoo.com/myblog/archives/137/#comment</comments><wfw:comment>http://www.macgoo.com/myblog/</wfw:comment><wfw:commentRss>http://www.macgoo.com/myblog/feed.asp?cmt=137</wfw:commentRss><trackback:ping>http://www.macgoo.com/myblog/cmd.asp?act=tb&amp;id=137&amp;key=eddc763f</trackback:ping></item><item><title>记湖南 09届 冬季技能大赛</title><author>soddyque@gmail.com (米落)</author><link>http://www.macgoo.com/myblog/archives/136/</link><pubDate>Sun, 29 Nov 2009 20:18:49 +0800</pubDate><guid>http://www.macgoo.com/myblog/archives/136/</guid><description><![CDATA[<p>&nbsp;&nbsp;&nbsp; 大赛9月28日开幕,一共举行了两天,今日(29日闭幕),在湖南民政学院举行.<br />
&nbsp;&nbsp;&nbsp; 我们是27日去的,上午十一点到达,发现我们算是比较积极的,由于住宿问题,主办单位未能准备妥当,我们只能找周边酒店下榻,不过环境也还不错,起码比起学校寝室方便,下午参观了赛场,晚上进行了抽签仪式,由于我们(应用程序设计,其实也就是做算法题)组一共就四间考场,而每个学院只能有三名选手,所以就自觉的抽取不同考场的机号.<br />
&nbsp;&nbsp;&nbsp; 28日上午八点开始开幕式,人挺多的,据说到了八百多人,有很多组,应用程序的也就一百来号人吧.开幕式过后就进考场进行比赛了.</p>
<p>&nbsp;&nbsp;&nbsp; 应用程序设计,四小时,五道基本算法题,单人完成.<br />
&nbsp;&nbsp;&nbsp; 我选择的是 Java, 环境是 Jdk 1.42 , Eclipse 3.1.不像上次ACM 的 Jdk 1.6,这次是正儿八经的 Jdk 1.42,所以心里算是比较稳定的.<br />
&nbsp;&nbsp;&nbsp; 一开始是把Eclipse 的首选项进行修改, 自动提示的触发所有字符都进行了触发,而不是原来的只有 &quot;.&quot; 才有,并且设置响应速度为0, 而不是原来的200ms.<br />
&nbsp;&nbsp;&nbsp; 第一题是道水题,N个观众给M个选手投票的问题,第一行分别给出了这两个数据,第二行为观众所投的选手号(从1开始),思路很清晰,2分钟不到就提交了,报错,检查一遍,发现有个如果最大票数大于一人,要按编号从小到大输出,更正后提交,还是报错,就搁浅到这了.<br />
&nbsp;&nbsp;&nbsp; 第二题是求从1900年1月1日到 19~N -1 年 12月31日的每个月的13号,所占的星期几各是多少次,两个数组,分别装入闰年每个月份的天数以及平年的每个月份的天数,然后判断闰年还是平年,for 循环累加天数,在每个月头计算总天数的星期几加上5取模7,+5 是因为13%7=6,而我们存放13号占星期几的数组的下标是从0开始的,所以减去一.循环过后输出,样列测试是过了,但一直提交不成功,而且一直到比赛结束.<br />
&nbsp;&nbsp;&nbsp; 第三题,狡兔三窟,我就不说故事的描述了,给定N,也就是产生从1开始一直到N的序列,从N出发,K=0,每次跳过K++个单位进行访问,求最后哪几个单位是没有被访问过的,这道题起初也困扰着我,一直不知道该循环跳多少次才是正确的,最后龙龙跑过来激动的问我AC了多少道题时直接告诉了我要爆破,循环10万,就YES了.我顿悟,修改后马上提交,成功.囧rz.<br />
&nbsp;&nbsp;&nbsp; 第四题,生分证从15位升至18位的算法,按照说明照写下来即可,没难度,当然你连最基本的序列和都不理解那就该补补课了.一次提交YES.我做了两个多小时,前面的三道题一直困扰着我,在这道题上终于返回了YES,真是让我内流满面.<br />
&nbsp;&nbsp;&nbsp; 第五题,哈夫曼编码,基本的基本,书上的例题,构造一颗哈夫曼树即可.没做的童鞋可以面壁了.构造树后对每个叶子节点访问并求出其高度,然后除法运算即可.</p>
<p>&nbsp;&nbsp;&nbsp; 本次应用程序设计大赛的难度还是很简单的,起码没有前面ACM的变态,大多数童鞋都能完成三道以上,米落童鞋基础知识不牢固,以及极其低的人品导致最后只AC了三道题,算是正常发挥了,以后还得多多加强,争取AC所有题目.<br />
&nbsp;&nbsp;&nbsp; 最后感谢各位主任以及老师一路陪同,各位指导老师的诲人不倦,各位同僚们的并肩作战,让我们在这次比赛中收获了应收获的,只是没能夺魁始终有些遗憾,再接再厉吧!</p>]]></description><category>Booooer.</category><comments>http://www.macgoo.com/myblog/archives/136/#comment</comments><wfw:comment>http://www.macgoo.com/myblog/</wfw:comment><wfw:commentRss>http://www.macgoo.com/myblog/feed.asp?cmt=136</wfw:commentRss><trackback:ping>http://www.macgoo.com/myblog/cmd.asp?act=tb&amp;id=136&amp;key=41807c57</trackback:ping></item><item><title>思想汇报</title><author>soddyque@gmail.com (米落)</author><link>http://www.macgoo.com/myblog/archives/135/</link><pubDate>Sat, 14 Nov 2009 14:24:22 +0800</pubDate><guid>http://www.macgoo.com/myblog/archives/135/</guid><description><![CDATA[<p>&nbsp;&nbsp;&nbsp; 我就是一闲不住的主儿,还真的佩服自己挺能折腾的.<br />
&nbsp;&nbsp;&nbsp; 学期伊始迎新结束,带完班后马上就投入了算法的较量之中,虽然都是纯时间性质的,对于理论还是停留在一个很浅的层次,但起码意识到了各门语言的强大,也一口气投入了Java的怀抱.然后参加了某个项目,至今都不确定这个项目是否会流产,虽然童鞋们的学习进度很快,比得上改革开放时的深圳了,但是光有热情是明显不够的,后面的效率,以及核心功能的设计,最后投入市场,这些我也不保准,要知道万一前台的SQL Inject 导致安全出错,强插了后台,那我们就玩完了,而且运行之后的维护,还有代码文档的维护,全新的体验是不错,但是你突然就让我们几个搞作坊生产的来流水线上一条龙服务就有点霸蛮了.</p>
<p>&nbsp;&nbsp;&nbsp; 发扬湖南人传统吧,霸得蛮,吃得苦.</p>
<p>&nbsp;&nbsp;&nbsp; 我自己是感觉挺刺激的,上半年鼓捣了Python,下半年又鼓捣了Java (达人别笑,这是真的鼓捣,就停留在Hello World 的层次),两个都是Google Engine App 上面支持的,于是乎自然而然的想搭些东西在那上面,虽然完全无法商用的Google Engine App 的稳定性实在无法控制,但好歹是个 Free 的,不用白不用呢.下面汇报一些近期所发现的资源,希望能对您起哪怕一点点的作用.^_^</p>
<ul>
    <li>Google 发布了新语言Go, 就有<a href="http://sunxiunan.com/?p=1463" target="_blank">达人发布试用教程了</a>,Go 官方地址:<a href="http://golang.org/" target="_blank">http://golang.org/</a></li>
    <li>PinyShop 0.2 发布,让您在windows环境下轻松搭建 nginx+php+mysql+memcache 环境&nbsp; <a href="http://pinyshop.nginxhome.com/" target="_blank">http://pinyshop.nginxhome.com/</a></li>
    <li><a href="http://wave.google.com/wave" target="_blank">Google Wave</a> 测试,前些天邮件过来了测试帐号的通知,进去看了一下,我的理解Wave是一个网上协作平台,因为还是测试状态,所以插件不是很多,但是依照这个态势发展下去,很有可能替代一些传统的工具.</li>
    <li><a href="http://www.army8735.org/2009/11/02/236.html" target="_blank">走进 Jssc 的世界</a>, Army 达人写的前端加亮实现的系列文章,对词法分析感兴趣的童鞋可以进去学习学习.(Jssc 一款前端的加亮实现,<a href="http://www.macgoo.com/myblog/archives/102/" target="_blank">CodeLight for Zblog</a> 就是基于这个版本库之上所建立的.</li>
</ul>]]></description><category>Booooer.</category><comments>http://www.macgoo.com/myblog/archives/135/#comment</comments><wfw:comment>http://www.macgoo.com/myblog/</wfw:comment><wfw:commentRss>http://www.macgoo.com/myblog/feed.asp?cmt=135</wfw:commentRss><trackback:ping>http://www.macgoo.com/myblog/cmd.asp?act=tb&amp;id=135&amp;key=7d03573f</trackback:ping></item><item><title>约瑟夫环问题</title><author>soddyque@gmail.com (米落)</author><link>http://www.macgoo.com/myblog/archives/134/</link><pubDate>Thu, 29 Oct 2009 19:32:30 +0800</pubDate><guid>http://www.macgoo.com/myblog/archives/134/</guid><description><![CDATA[<p>
<link type="text/css" rel="stylesheet" href="http://www.macgoo.com/myblog/PLUGIN/Codelight/SyntaxHighlighter/Styles/shCore.css" />
<link type="text/css" rel="stylesheet" href="http://www.macgoo.com/myblog/PLUGIN/Codelight/SyntaxHighlighter/Styles/shThemeDefault.css" /><script language="javascript" src="http://www.macgoo.com/myblog/PLUGIN/Codelight/SyntaxHighlighter/Scripts/shCore.js"></script><script language="javascript" src="http://www.macgoo.com/myblog/PLUGIN/Codelight/SyntaxHighlighter/Scripts/shBrushJScript.js"></script><script language="javascript" src="http://www.macgoo.com/myblog/PLUGIN/Codelight/SyntaxHighlighter/Scripts/shBrushXml.js"></script></p>
<p>问题描述: n个人围成一圈,并依次编号1～n。从编号为1的人开始，按顺时针方向每隔一人选出一个，剩下的人重新围成一圈，如此循环直到剩下两人，这剩下的两人就是幸运儿。如果你想成为最后两个幸运儿，请问开始时应该站在什么位置？（设3&lt;=n&lt;=50）<br />
输入：开始时的人数n<br />
输出：第1行是选出顺序，第2行是两名幸运儿的开始位置（按升序排列），位置编号之间用一个空格分开。<br />
示例<br />
输入：<br />
12<br />
输出：<br />
2 4 6 8 10 12 3 7 11 5<br />
1 9</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 这个问题，基本上属于每次比赛的热身难度，也就是语法复习，可自己偏偏还是想了很久，果然是缺乏练习的问题。求解思路是用数组来模拟队列删除，也就有一个已访问对象的问题，很好解决直接赋值-1即可，用JavaScript 实现如下:</p>
<pre class="brush:javascript;mouse-over:#ff9;html-script:true;toolbar:false" name="CodeLight_code" height="400" style="border: thin ridge rgb(204, 204, 204); background-color: rgb(240, 240, 240);">
&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Transitional//EN&quot; &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&quot;&gt;
&lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot; &gt;
&lt;head&gt;
    &lt;title&gt;yoself&lt;/title&gt;
    &lt;script type=&quot;text/javascript&quot;&gt;
    function yoself()
    {
        var total = 12; /* 十二名 */
        var cur = 0; /* 已剔除数 */
        var io = 1; /* 当前数组下标 */
        var list = []; /* 编号数组 */
        for(var i = 0; i &lt; total; i++) /* 数组初始化 */
            list.push(i+1);
        
        while(cur != -1)
        {
            io %= total; /* 防止越界 */
            document.write(list[io] + &quot; &quot;);
            list[io] = -1; /* 已访问标记 */
            cur++; 
            io = nextInts(list, io, 2); /* 下下个未访问的元素 */
            
            /* 获取结果 */
            if(cur &gt;= total - 2)
            {
                var a,c,n;
                n = nextInts(list, -1, 1);
                a = list[n];
                c = list[nextInts(list, n, 1)];
                document.write(&quot;&lt;br /&gt;&quot; + a + &quot; &quot; + c);
                cur = -1;
            }
        }
    }
    /*
    * 将list数组以start为起始下标开始的第n个不为-1的元素下标返回
    */
    function nextInts(list, start, n)
    {
        while(n &gt; 0)
            if(list[++start % list.length] != -1)
                n--;
        return start % list.length;
    }
    window.onload = yoself;
    &lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;/body&gt;
&lt;/html&gt;
</pre>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 然后又闲着用链表结构实现了次，当然了，JavaScript 的链表实现和 C 还有 Java 的实现是有点小区别的，C 用结构体，Java 就用 LinkedList 也行。在下面的列子中 getLen函数主要是用于获取链表长度，其实完全可以用一个整形变量来保存弹出多少个了，然后判断和总数相差小于2 就跳出 while循环。JavaScript 实现如下:</p>
<pre class="brush:javascript;mouse-over:#ff9;html-script:true;toolbar:false" name="CodeLight_code" height="400" style="border: thin ridge rgb(204, 204, 204); background-color: rgb(240, 240, 240);">
&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Transitional//EN&quot; &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&quot;&gt;
&lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot; &gt;
&lt;head&gt;
    &lt;title&gt;yoself&lt;/title&gt;
    &lt;script type=&quot;text/javascript&quot;&gt;
    function yoself()
    {
        var total ,head ,cur, end;
        total = 12; /* 总数 */
        head = {}; /* 头结点,不存储数据 */
        cur = head; /* 当前节点 */
        for(var i=0; i &lt; total; i++) /* 初始化,创建链表结构 */
        {
            cur.next = { value: i+1, next:null};
            cur = cur.next;
        }
        end = cur; /* 终点 */
        end.next = head.next; /* 终点连接到起始点,head只是作为一个引子,本身不储存数据,形成环形结构 */
        
        cur = head.next; /*  */
        while(getLen(cur) &gt; 2)
        {
            drop(cur);
            cur = cur.next;
        }
        document.writeln(&quot;&lt;br /&gt;&quot;);
        drop(head);
        drop(head);
    }
    function getLen(obj)
    {
        var c = obj;
        var i = 1;
        obj = obj.next;
        while(obj != null &amp;&amp; obj != c)
        {
            i++;
            obj = obj.next;
        }
        return i;
    }
    function drop(obj)
    {
        var bedrop = obj.next;
        document.write(bedrop.value + &quot; &quot;);
        obj.next = obj.next.next;
        bedrop = null;
    }
    window.onload = yoself;
    &lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;/body&gt;
&lt;/html&gt;
</pre>
<script language="javascript">SyntaxHighlighter.config.clipboardSwf = 'http://www.macgoo.com/myblog/PLUGIN/Codelight/SyntaxHighlighter/Scripts/clipboard.swf';SyntaxHighlighter.all();</script>]]></description><category>Programer</category><comments>http://www.macgoo.com/myblog/archives/134/#comment</comments><wfw:comment>http://www.macgoo.com/myblog/</wfw:comment><wfw:commentRss>http://www.macgoo.com/myblog/feed.asp?cmt=134</wfw:commentRss><trackback:ping>http://www.macgoo.com/myblog/cmd.asp?act=tb&amp;id=134&amp;key=7fc02eea</trackback:ping></item></channel></rss>
