<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom"><title type="text">博客园_飞林沙</title><subtitle type="text"/><id>http://feed.cnblogs.com/blog/u/39564/rss</id><updated>2012-05-13T16:28:29Z</updated><author><name>飞林沙</name><uri>http://www.cnblogs.com/kym/</uri></author><generator>feed.cnblogs.com</generator><link rel="alternate" type="text/html" href="http://www.cnblogs.com/kym/"/><link rel="self" type="application/atom+xml" href="http://feed.cnblogs.com/blog/u/39564/rss"/><entry><id>http://www.cnblogs.com/kym/archive/2012/05/14/2498728.html</id><title type="text">说说Python程序的执行过程</title><summary type="text">1. Python是一门解释型语言？ 我初学Python时，听到的关于Python的第一句话就是，Python是一门解释性语言，我就这样一直相信下去，直到发现了*.pyc文件的存在。如果是解释型语言，那么生成的*.pyc文件是什么呢？c应该是compiled的缩写才对啊！ 为了防止其他学习Python的人也被这句话误解，那么我们就在文中来澄清下这个问题，并且把一些基础概念给理清。 2. 解释型语言和编译型语言 计算机是不能够识别高级语言的，所以当我们运行一个高级语言程序的时候，就需要一个“翻译机”来从事把高级语言转变成计算机能读懂的机器语言的过程。这个过程分成两类，第一...</summary><published>2012-05-13T16:28:00Z</published><updated>2012-05-13T16:28:00Z</updated><author><name>飞林沙</name><uri>http://www.cnblogs.com/kym/</uri></author><link rel="alternate" href="http://www.cnblogs.com/kym/archive/2012/05/14/2498728.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/kym/archive/2012/05/14/2498728.html"/><content type="html">&lt;p&gt;&lt;strong&gt;&lt;span style="font-family: 'Hiragino Sans GB', Helvetica; font-size: 14px; line-height: 16px;"&gt;1. Python是一门解释型语言？&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&lt;div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 5px; padding-top: 5px; padding-right: 5px; padding-bottom: 5px; padding-left: 5px; background-color: #FFFFFF; color: #000000; font: 12px/1.5 'sans serif', tahoma, verdana, helvetica; font-size: 14px; line-height: 1.2; font-family: 'Hiragino Sans GB', Helvetica;"&gt;  &lt;p&gt;我初学Python时，听到的关于Python的第一句话就是，Python是一门解释性语言，我就这样一直相信下去，直到发现了*.pyc文件的存在。如果是解释型语言，那么生成的*.pyc文件是什么呢？c应该是compiled的缩写才对啊！&lt;/p&gt;  &lt;p&gt;为了防止其他学习Python的人也被这句话误解，那么我们就在文中来澄清下这个问题，并且把一些基础概念给理清。&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;br /&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;2. 解释型语言和编译型语言&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;br /&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;计算机是不能够识别高级语言的，所以当我们运行一个高级语言程序的时候，就需要一个&amp;#8220;翻译机&amp;#8221;来从事把高级语言转变成计算机能读懂的机器语言的过程。这个过程分成两类，第一种是编译，第二种是解释。&lt;/p&gt;  &lt;p&gt;编译型语言在程序执行之前，先会通过编译器对程序执行一个编译的过程，把程序转变成机器语言。运行时就不需要翻译，而直接执行就可以了。最典型的例子就是C语言。&lt;/p&gt;  &lt;p&gt;解释型语言就没有这个编译的过程，而是在程序运行的时候，通过解释器对程序逐行作出解释，然后直接运行，最典型的例子是Ruby。&lt;/p&gt;  &lt;p&gt;通过以上的例子，我们可以来总结一下解释型语言和编译型语言的优缺点，因为编译型语言在程序运行之前就已经对程序做出了&amp;#8220;翻译&amp;#8221;，所以在运行时就少掉了&amp;#8220;翻译&amp;#8221;的过程，所以效率比较高。但是我们也不能一概而论，一些解释型语言也可以通过解释器的优化来在对程序做出翻译时对整个程序做出优化，从而在效率上超过编译型语言。&lt;/p&gt;  &lt;p&gt;此外，随着Java等基于虚拟机的语言的兴起，我们又不能把语言纯粹地分成解释型和编译型这两种。&lt;/p&gt;  &lt;p&gt;用Java来举例，Java首先是通过编译器编译成字节码文件，然后在运行时通过解释器给解释成机器文件。所以我们说Java是一种先编译后解释的语言。&lt;/p&gt;  &lt;p&gt;再换成C#，C#首先是通过编译器将C#文件编译成IL文件，然后在通过CLR将IL文件编译成机器文件。所以我们说C#是一门纯编译语言，但是C#是一门需要二次编译的语言。同理也可等效运用到基于.NET平台上的其他语言。&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;br /&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;3. Python到底是什么&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;br /&gt;&lt;/p&gt;  &lt;p&gt;其实Python和Java/C#一样，也是一门基于虚拟机的语言，我们先来从表面上简单地了解一下Python程序的运行过程吧。&lt;/p&gt;  &lt;p&gt;当我们在命令行中输入python hello.py时，其实是激活了Python的&amp;#8220;解释器&amp;#8221;，告诉&amp;#8220;解释器&amp;#8221;：你要开始工作了。可是在&amp;#8220;解释&amp;#8221;之前，其实执行的第一项工作和Java一样，是编译。&lt;/p&gt;  &lt;p&gt;熟悉Java的同学可以想一下我们在命令行中如何执行一个Java的程序：&lt;/p&gt;  &lt;p&gt;javac hello.java&lt;/p&gt;  &lt;p&gt;java hello&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;只是我们在用Eclipse之类的IDE时，将这两部给融合成了一部而已。其实Python也一样，当我们执行python hello.py时，他也一样执行了这么一个过程，所以我们应该这样来描述Python，Python是一门先编译后解释的语言。&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;br /&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;4. 简述Python的运行过程&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;br /&gt;&lt;/p&gt;  &lt;p&gt;在说这个问题之前，我们先来说两个概念，PyCodeObject和pyc文件。&lt;/p&gt;  &lt;p&gt;我们在硬盘上看到的pyc自然不必多说，而其实PyCodeObject则是Python编译器真正编译成的结果。我们先简单知道就可以了，继续向下看。&lt;/p&gt;  &lt;p&gt;当python程序运行时，编译的结果则是保存在位于内存中的PyCodeObject中，当Python程序运行结束时，Python解释器则将PyCodeObject写回到pyc文件中。&lt;/p&gt;  &lt;p&gt;当python程序第二次运行时，首先程序会在硬盘中寻找pyc文件，如果找到，则直接载入，否则就重复上面的过程。&lt;/p&gt;  &lt;p&gt;所以我们应该这样来定位PyCodeObject和pyc文件，我们说pyc文件其实是PyCodeObject的一种持久化保存方式。&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;br /&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;5. 运行一段Python程序&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;br /&gt;&lt;/p&gt;  &lt;p&gt;我们来写一段程序实际运行一下：&lt;/p&gt;  &lt;p&gt;&lt;img src="http://files.note.sdo.com/pqo2g~jWXCOiwE0gA00ejt" width="0" height="0" style="max-width: 100%;"  alt="" /&gt;&lt;img src="http://images.cnblogs.com/cnblogs_com/kym/201205/201205140026509494.jpg" width="371" height="125" alt="201205140014.jpg" /&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;程序本身毫无意义。我们继续看：&lt;/p&gt;  &lt;p&gt;&lt;br /&gt;  &lt;img src="http://images.cnblogs.com/cnblogs_com/kym/201205/201205140026464906.jpg" width="407" height="173" alt="201205140015.jpg" /&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;然而我们在程序中并没有看到pyc文件，仍然是test.py孤零零地呆在那！&lt;/p&gt;  &lt;p&gt;那么我们换一种写法，我们把print_str方法换到另外的一个python模块中：&lt;/p&gt;  &lt;p&gt;&lt;br /&gt;  &lt;img src="http://images.cnblogs.com/cnblogs_com/kym/201205/201205140026477773.jpg" width="346" height="136" alt="201205140015.jpg" /&gt;&lt;/p&gt;  &lt;p&gt;&lt;br /&gt;  &lt;img src="http://images.cnblogs.com/cnblogs_com/kym/201205/201205140026582506.jpg" width="361" height="146" alt="201205140016.jpg" /&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;然后运行程序：&lt;/p&gt;  &lt;p&gt;&lt;br /&gt;  &lt;img src="http://images.cnblogs.com/cnblogs_com/kym/201205/201205140026541507.jpg" width="388" height="105" alt="201205140016.jpg" /&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;这个时候pyc文件出现了，其实认真思考一下不难得到原因，我们考虑一下实际的业务情况。&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;br /&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;6. pyc的目的是重用&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;br /&gt;&lt;/p&gt;  &lt;p&gt;回想本文的第二段在解释编译型语言和解释型语言的优缺点时，我说编译型语言的优点在于，我们可以在程序运行时不用解释，而直接利用已经&amp;#8220;翻译&amp;#8221;过的文件。也就是说，我们之所以要把py文件编译成pyc文件，最大的优点在于我们在运行程序时，不需要重新对该模块进行重新的解释。&lt;/p&gt;  &lt;p&gt;所以，我们需要编译成pyc文件的应该是那些可以重用的模块，这于我们在设计软件类时是一样的目的。所以Python的解释器认为：只有import进来的模块，才是需要被重用的模块。&lt;/p&gt;  &lt;p&gt;这个时候也许有人会说，不对啊！你的这个问题没有被解释通啊，我的test.py不是也需要运行么，虽然不是一个模块，但是以后我每次运行也可以节省时间啊！&lt;/p&gt;  &lt;p&gt;OK，我们从实际情况出发，思考下我们在什么时候才可能运行python xxx.py文件：&lt;/p&gt;  &lt;p&gt;A. 执行测试时。&lt;/p&gt;  &lt;p&gt;B. 开启一个Web进程时。&lt;/p&gt;  &lt;p&gt;C. 执行一个程序脚本。&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;我们逐个来说，第一种情况我们就不用多说了，这个时候哪怕所有的文件都没有pyc文件都是无所谓的。&lt;/p&gt;  &lt;p&gt;第二种情况，我们试想一个webpy的程序把，我们通常这样执行：&lt;/p&gt;  &lt;p&gt;&lt;br /&gt;  &lt;img src="http://images.cnblogs.com/cnblogs_com/kym/201205/201205140026588112.jpg" width="480" height="106" alt="201205140016.jpg" /&gt;&lt;/p&gt;  &lt;p&gt;抑或者：&lt;/p&gt;  &lt;p&gt;&lt;br /&gt;  &lt;img src="http://images.cnblogs.com/cnblogs_com/kym/201205/201205140026436599.jpg" width="480" height="212" alt="201205140017.jpg" /&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;然后这个程序就类似于一个守护进程一样一直监视着8181/9002端口，而一旦中断，只可能是程序被杀死，或者其他的意外情况，那么你需要恢复要做的是把整个的Web服务重启。那么既然一直监视着，把PyCodeObject一直放在内存中就足够了，完全没必要持久化到硬盘上。&lt;/p&gt;  &lt;p&gt;最后一个情况，执行一个程序脚本，一个程序的主入口其实很类似于Web程序中的Controller，也就是说，他负责的应该是Model之间的调度，而不包含任何的主逻辑在内，如我在&lt;a href="http://www.cnblogs.com/kym/archive/2010/07/19/1780407.html"&gt;http://www.cnblogs.com/kym/archive/2010/07/19/1780407.html&lt;/a&gt;中所提到，Controller应该就是一个Facade，无任何的细节逻辑，只是把参数转来转去而已，那么如果做算法的同学可以知道，在一段算法脚本中，最容易改变的就是算法的各个参数，那么这个时候给持久化成pyc文件就未免有些画蛇添足了。&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;所以我们可以这样理解Python解释器的意图，Python解释器只把我们可能重用到的模块持久化成pyc文件。&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;br /&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;7. pyc的过期时间&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;br /&gt;&lt;/p&gt;  &lt;p&gt;说完了pyc文件，可能有人会想到，每次Python的解释器都把模块给持久化成了pyc文件，那么当我的模块发生了改变的时候，是不是都要手动地把以前的pyc文件remove掉呢？&lt;/p&gt;  &lt;p&gt;当然Python的设计者是不会犯这么白痴的错误的。而这个过程其实就取决于PyCodeObject是如何写入pyc文件中的。&lt;/p&gt;  &lt;p&gt;我们来看一下import过程的源码吧：&lt;/p&gt;  &lt;p&gt;&lt;br /&gt;  &lt;img src="http://images.cnblogs.com/cnblogs_com/kym/201205/201205140026542445.jpg" width="477" height="480" alt="201205140024.jpg" /&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;这段代码比较长，我们只来看我标注了的代码，其实他在写入pyc文件的时候，写了一个Long型变量，变量的内容则是文件的最近修改日期，同理，我们再看下载入pyc的代码：&lt;/p&gt;  &lt;p&gt;&lt;br /&gt;  &lt;img src="http://images.cnblogs.com/cnblogs_com/kym/201205/201205140026564373.jpg" width="479" height="480" alt="201205140025.jpg" /&gt;&lt;/p&gt;  &lt;p&gt;&lt;br /&gt;  &lt;img src="http://images.cnblogs.com/cnblogs_com/kym/201205/20120514002657653.jpg" width="480" height="393" alt="201205140026.jpg" /&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;不用仔细看代码，我们可以很清楚地看到原理，其实每次在载入之前都会先检查一下py文件和pyc文件保存的最后修改日期，如果不一致则重新生成一份pyc文件。&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;br /&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;8. 写在最后的&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;br /&gt;&lt;/p&gt;  &lt;p&gt;其实了解Python程序的执行过程对于大部分程序员，包括Python程序员来说意义都是不大的，那么真正有意义的是，我们可以从Python的解释器的做法上学到什么，我认为有这样的几点：&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;A. 其实Python是否保存成pyc文件和我们在设计缓存系统时是一样的，我们可以仔细想想，到底什么是值得扔在缓存里的，什么是不值得扔在缓存里的。&lt;/p&gt;  &lt;p&gt;B. 在跑一个耗时的Python脚本时，我们如何能够稍微压榨一些程序的运行时间，就是将模块从主模块分开。（虽然往往这都不是瓶颈）&lt;/p&gt;  &lt;p&gt;C. 在设计一个软件系统时，重用和非重用的东西是不是也应该分开来对待，这是软件设计原则的重要部分。&lt;/p&gt;  &lt;p&gt;D. 在设计缓存系统（或者其他系统）时，我们如何来避免程序的过期，其实Python的解释器也为我们提供了一个特别常见而且有效的解决方案。&lt;/p&gt;&lt;/div&gt;&lt;img src="http://www.cnblogs.com/kym/aggbug/2498728.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/kym/archive/2012/05/14/2498728.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/kym/archive/2012/05/11/2495297.html</id><title type="text">关于排行榜的算法经验谈</title><summary type="text">好久不来博客园了，前几天更新个人状态时，也把“技术博客”四个字改成了“荒废已久的博客”。好久不总结自己的工作和学习了，怎么说也过不去，就来这写一篇浅显的文章，没什么新鲜的内容，算是一篇经验的汇总把。1. 关于排行榜各大网站一般来说都少不了排行榜这个东西，一者是提供给商业合作方的数据排行榜，另一者是提供给用户的榜单。例如豆瓣的新书榜：2. 打造一个最简单的排行榜我们先用豆瓣的新书榜为例，看看我们如何来一步步完善我们的榜单。其实最初的版本很简单，既然是新书，那么我们只需要先得到最近出版的读书，例如：select * from book where create_datetime &gt; xxxx</summary><published>2012-05-10T20:06:00Z</published><updated>2012-05-10T20:06:00Z</updated><author><name>飞林沙</name><uri>http://www.cnblogs.com/kym/</uri></author><link rel="alternate" href="http://www.cnblogs.com/kym/archive/2012/05/11/2495297.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/kym/archive/2012/05/11/2495297.html"/><content type="html">&lt;p&gt;好久不来博客园了，前几天更新个人状态时，也把&amp;#8220;技术博客&amp;#8221;四个字改成了&amp;#8220;荒废已久的博客&amp;#8221;。&lt;/p&gt;&lt;p&gt;好久不总结自己的工作和学习了，怎么说也过不去，就来这写一篇浅显的文章，没什么新鲜的内容，算是一篇经验的汇总把。&lt;/p&gt;&lt;p&gt;1. 关于排行榜&lt;/p&gt;&lt;p&gt;各大网站一般来说都少不了排行榜这个东西，一者是提供给商业合作方的数据排行榜，另一者是提供给用户的榜单。&lt;/p&gt;&lt;p&gt;例如豆瓣的新书榜：&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;img src="http://images.cnblogs.com/cnblogs_com/kym/201205/201205110405573363.jpg" width="480" height="309" alt="201205110223.jpg" /&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;2. 打造一个最简单的排行榜&lt;/p&gt;&lt;p&gt;我们先用豆瓣的新书榜为例，看看我们如何来一步步完善我们的榜单。&lt;/p&gt;&lt;p&gt;其实最初的版本很简单，既然是新书，那么我们只需要先得到最近出版的读书，例如：&lt;/p&gt;&lt;p&gt;select * from book where create_datetime &amp;gt; xxxx limit 0,10;&lt;/p&gt;&lt;p&gt;这样其实我们的排行榜就是可用的了。&lt;/p&gt;&lt;p&gt;3. 排行榜的演化&lt;/p&gt;&lt;p&gt;这个榜单我们应该很快就可以发现一些问题：&lt;/p&gt;&lt;p&gt;A. 有很多书其实质量很低，包括《21天精通ASP.NET》这样的书都能够上榜。&lt;/p&gt;&lt;p&gt;B. 一些书得到的关注很少，那么其实它就不值得推出来。&lt;/p&gt;&lt;p&gt;综上所述，我们应该在排行榜中增加两个元素：分数和收藏人数。这个时候解决方案仍然很简单：&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;img src="http://images.cnblogs.com/cnblogs_com/kym/201205/201205110405565414.jpg" width="547" height="150" alt="201205110233.jpg" /&gt;&lt;/p&gt;&lt;p&gt;我们其实只是加了两层过滤而已。&lt;/p&gt;&lt;p&gt;但是我们仍然发现了很多问题，对于一本刚刚出版的书来说，很少有人关注，一本书的&amp;#8220;绽放期&amp;#8221;应该在他出版的两三个月左右，那么这个时候我们就不能这样暴力地利用时间来排序了，此外我们依然需要书条目的Rank问题，现在我们的Rank完全是依赖于时间。&lt;/p&gt;&lt;p&gt;4. 半衰期的引入&lt;/p&gt;&lt;p&gt;我们来重新设计一下整个排行榜的算法，首先，我们整理一下思路，既然是新书榜，无疑我们需要要把时间的概念放大化，但是我们却不能让时间占据过大的因素，而只应该让他成为各种因素的一部分，分配给其较大的权重。&lt;/p&gt;&lt;p&gt;另外一点，我们并非认为昨天和今天出版的书有什么差别，而是涉及到一个逐渐衰减的过程。那么我们第一个想到的应该是高中物理一个基本的概念：半衰期。让我们来复习一下下半衰期的公式：&lt;/p&gt;&lt;p&gt;m = M * (1/2) ^ (t/T)&lt;/p&gt;&lt;p&gt;我们来解释下该公式的含义：M 为初始值，m为反应后的值，t为反应的时间，T为半衰期。&lt;/p&gt;&lt;p&gt;我们把该公式作用于出版时间上，以天作为单位，以一周作为半衰期，从而得到这样的一条函数曲线：&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;img src="http://images.cnblogs.com/cnblogs_com/kym/201205/201205110405534872.jpg" width="423" height="356" alt="201205110249.jpg" /&gt;&lt;/p&gt;&lt;p&gt;接下来我们考虑分数的因素，其实有两种方案可选择，第一是把分数的因素和之前得到的分数相乘，第二是采用指数的方式。可是由于之前的时间标准&amp;lt;1，函数是一个递减的曲线，所以如果我们需要让分数的评价正作用于之前的函数曲线，我们则需要将分数取反。由于之前我们过滤掉了3分以下的图书，所以我们将分数的参数也归一。（这里我采用第二种，全凭拍脑袋的喜好）从而会这样定义我们的算法：&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src="http://images.cnblogs.com/cnblogs_com/kym/201205/201205110405559658.jpg" width="480" height="369" alt="201205110320.jpg" /&gt;&lt;/p&gt;&lt;p&gt;最后一个因素是收藏人数的因素，我们只是归一然后简单相乘即可。&lt;/p&gt;&lt;p&gt;这样我们便出来了一个相对完善排行榜。&lt;/p&gt;&lt;p&gt;5. 排行榜面临的主要问题&lt;/p&gt;&lt;p&gt;其实排行榜更多的是业务问题，而不是算法问题，当我们面对着一个排行榜需求时，我们需要的是先来整理，这个排行榜，我们需要综合哪些因素，这些因素在整个排行榜的Rank中究竟占据多大的比重。然后，我们只需要一个简单的乘法，或者对数即可解决大多数的问题。&lt;/p&gt;&lt;p&gt;那么对于大多数网站的排行榜来说，无外乎这样几个因素，条目的质量，条目的点击率，条目的收藏率等等。而条目的排行榜又往往出现在网站的首页，例如百度听：&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;img src="http://images.cnblogs.com/cnblogs_com/kym/201205/201205110405549233.jpg" width="480" height="335" alt="201205110335.jpg" /&gt;&lt;/p&gt;&lt;p&gt;如果我们不做任何的优化，则会出现排行榜面临的最大的问题：马太效应。&lt;/p&gt;&lt;p&gt;6. 马太效应&lt;/p&gt;&lt;p&gt;什么是马太效应，我们可以先来看下网上的解释：&lt;/p&gt;&lt;p&gt;马太效应(Matthew Effect)，指强者愈强，弱者愈弱的现象，广泛应用于社会心里学，教育，金融等领域。&lt;/p&gt;&lt;p&gt;那么换到我们的排行榜上也就是，越放到排行榜上，他的收听就越多，收听越多，他就越在排行榜上，这样的一个循环。&lt;/p&gt;&lt;p&gt;对于解决马太效应，工程界提出了很多算法，最著名的包括Reddit，Hacker News的Ranking算法，以及我之前提出过的半衰期算法。&lt;/p&gt;&lt;p&gt;我们接下来来逐个介绍一下，并且比较他们的优缺点。&lt;/p&gt;&lt;p&gt;7. Reddit算法&lt;/p&gt;&lt;p&gt;我们先来看下Reddit算法的公式：&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;img src="http://images.cnblogs.com/cnblogs_com/kym/201205/201205110405566003.jpg" width="454" height="480" alt="201205110342.jpg" /&gt;&lt;/p&gt;&lt;p&gt;其实Reddit的原理很简单，用发表时间减去固定时间来表示某帖子的新鲜程度，x则表示某帖子的受欢迎程序，然后讲这个参数取对数则是因为该参数的受热度影响较大，产生的值会和另外的时间结果不在同一个数量级上。&lt;/p&gt;&lt;p&gt;而至于10和45000，则属于一个trial-and-error，是算法工程师最头疼的地方，因为该参数并说不出太多的理论道理，只能根据人眼的结果来微调。&lt;/p&gt;&lt;p&gt;8. Hacker New的Ranking算法&lt;/p&gt;&lt;p&gt;这个算法就更为简单：&lt;/p&gt;&lt;p&gt;&lt;span style="color: #000000; font-family: Georgia, 'Times New Roman', Times, serif; font-size: 13px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 19px; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; display: inline !important; float: none;"&gt;(p &amp;#8211; 1) / (t + 2)^1.5&lt;/span&gt;&lt;/p&gt;&lt;p&gt;p来代表这个帖子被推荐的次数，-1则是去掉作者自己的推荐，然后除以时间的一个指数。其中的2和1.5也是一个trial-and-error。&lt;br /&gt;&lt;/p&gt;&lt;p&gt;9. 以上算法的优劣&lt;/p&gt;&lt;p&gt;首先是Hacker News的算法，我们从公式即可看出，这个算法的设计是比较简陋的，时间占据了很大的因素，即便是推荐较多的文章，也会被很快的沉没：&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;img src="http://images.cnblogs.com/cnblogs_com/kym/201205/201205110405542755.jpg" width="480" height="446" alt="201205110354.jpg" /&gt;&lt;/p&gt;&lt;p&gt;相对来说：Reddit的算法设计较为巧妙，但是Reddit的局限性是对负反馈的要求也比较高，在之前的一个项目中，我尝试过使用Reddit的算法，但是发现如果没有了负反馈，其实消减的效果也比较差。&lt;/p&gt;&lt;p&gt;最后是半衰期的算法，半衰期的算法是我最为推崇的算法，他不依赖于负反馈，而且它的职责很单一，他很专一地来解决时间衰减的问题，然后我们则可以把其他的因素来用单独的方式来计算。最重要的一点是，他的参数是可解释的，Half-life的值，我们是可以根据业务逻辑来解释，比如我们认为一部电影的热门期就应该是一个星期，那么我们则可以把半衰期设置为7，7天后，这个电影的分值则会发生一个较大程度的衰减。这一点是之前的两个算法所无法比拟的。&lt;/p&gt;&lt;p&gt;作为算法工程师，&amp;nbsp;trial-and-error是需要极力避免的，也就是说我们可以从学术界中去得到算法的框架，但是我们要竭力来保持参数的可解释性。&lt;/p&gt;&lt;p&gt;10. 综述&lt;/p&gt;&lt;p&gt;排行榜是一个重业务而轻算法的需求，而且是一个几乎所有网站都会通用的需求，这个需求说简单也简单，说复杂更复杂。&lt;/p&gt;&lt;p&gt;例如应用汇：&lt;a href="http://www.appchina.com/soft_rank.html"&gt;http://www.appchina.com/soft_rank.html&lt;/a&gt; 这种千年不变的排行榜，就完全不需要动脑子。&lt;/p&gt;&lt;p&gt;也有例如近日很火爆的AppStore，也包括豆瓣电影等很多Spammer来刷排名的现象，这就不仅仅需要考虑到马太效应，也包括Anti-spammer的领域。&lt;/p&gt;&lt;p&gt;如果我们把推荐系统这个领域给分成个性化推荐和非个性化推荐，那么排行榜一定是非个性化推荐中最重要的一部分了。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/kym/aggbug/2495297.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/kym/archive/2012/05/11/2495297.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/kym/archive/2011/12/29/2306428.html</id><title type="text">virtualenv搭建虚拟环境</title><summary type="text">Python的背后有着庞大的开源社区支持，但是有一个缺点就是每个包的质量都参差不齐，如果我们在工作服务器上去测试安装每个包，就会造成整个的服务器形成庞大复杂的第三方包依赖。 virtualenv就是为了解决这个问题而生，他可以在我们的目录上生成若干个独立的虚拟环境，这些虚拟环境和正式环境一样。 安装virtualenv非常简单： 首先安装virtualenv： 然后我们就可以创建一个虚拟的环境了： mytest就是我们所创建的虚拟环境目录了，我们可以发现，该目录中已经安装了和我们本机相同的python版本： 我们接下来需要激活这个虚拟环境： 我们就可以看到在命令...</summary><published>2011-12-29T09:11:00Z</published><updated>2011-12-29T09:11:00Z</updated><author><name>飞林沙</name><uri>http://www.cnblogs.com/kym/</uri></author><link rel="alternate" href="http://www.cnblogs.com/kym/archive/2011/12/29/2306428.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/kym/archive/2011/12/29/2306428.html"/><content type="html">&lt;div&gt;        &lt;p&gt;Python的背后有着庞大的开源社区支持，但是有一个缺点就是每个包的质量都参差不齐，如果我们在工作服务器上去测试安装每个包，就会造成整个的服务器形成庞大复杂的第三方包依赖。&lt;/p&gt; &lt;p&gt;&lt;br /&gt;&lt;/p&gt; &lt;p&gt;virtualenv就是为了解决这个问题而生，他可以在我们的目录上生成若干个独立的虚拟环境，这些虚拟环境和正式环境一样。&lt;/p&gt; &lt;p&gt;&lt;br /&gt;&lt;/p&gt; &lt;p&gt;安装virtualenv非常简单：&lt;/p&gt; &lt;p&gt;首先安装virtualenv：&lt;/p&gt; &lt;p&gt;&lt;img src="http://images.cnblogs.com/cnblogs_com/kym/1.jpeg" border="0" alt="" width="692" height="331" /&gt;&lt;br /&gt;&lt;/p&gt; &lt;p&gt;&lt;br /&gt;&lt;/p&gt; &lt;p&gt;然后我们就可以创建一个虚拟的环境了：&lt;/p&gt; &lt;p&gt;&lt;img src="http://images.cnblogs.com/cnblogs_com/kym/2.jpeg" border="0" alt="" width="336" height="111" /&gt;&lt;br /&gt;&lt;/p&gt; &lt;p&gt;mytest就是我们所创建的虚拟环境目录了，我们可以发现，该目录中已经安装了和我们本机相同的python版本：&lt;/p&gt; &lt;p&gt;&lt;img src="http://images.cnblogs.com/cnblogs_com/kym/3.jpeg" border="0" alt="" width="587" height="108" /&gt;&lt;br /&gt;&lt;/p&gt; &lt;p&gt;我们接下来需要激活这个虚拟环境：&lt;/p&gt; &lt;p&gt;&lt;img src="http://images.cnblogs.com/cnblogs_com/kym/4.jpeg" border="0" alt="" width="370" height="41" /&gt;&lt;br /&gt;&lt;/p&gt; &lt;p&gt;&lt;br /&gt;&lt;/p&gt; &lt;p&gt;我们就可以看到在命令行的前面已经加上了&amp;#8220;mytest&amp;#8221;，这个时候我们看看python所指向的路径：&lt;/p&gt;&lt;p&gt;&lt;img src="http://images.cnblogs.com/cnblogs_com/kym/5.jpeg" border="0" alt="" width="401" height="60" /&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;br /&gt;&lt;/p&gt; &lt;p&gt;OK ，这个时候我们就可以在这个虚拟环境中安装我们所需要的包了：&lt;/p&gt;&lt;p&gt;&lt;img src="http://images.cnblogs.com/cnblogs_com/kym/6.jpeg" border="0" alt="" width="648" height="194" /&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;img src="http://images.cnblogs.com/cnblogs_com/kym/7.jpeg" border="0" alt="" width="707" height="191" /&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;br /&gt;&lt;/p&gt; &lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;/div&gt;&lt;img src="http://www.cnblogs.com/kym/aggbug/2306428.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/kym/archive/2011/12/29/2306428.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/kym/archive/2011/11/10/2244764.html</id><title type="text">《浪潮之巅》读书笔记汇总</title><summary type="text">其实我是没有做读书笔记的习惯的，但是这本书只是借来看的，而且这种杂谈性的书，也比较容易扯开去，就随便写了一些东西，大多是自己的一些乱七八糟的想法。现在给汇总一下发出来把。。1. 第一章AT&amp;T的兴起感谢于美国的反垄断法不断地强迫公司做着技术革新，帮助公司修枝剪叶以删除掉那些无用的业务，而衰败同样是由于反垄断法使公司不得不做着不理智的拆分从而使一个巨型帝国迅速的滑落。当一个公司到后期被投行以及他人所大量持股，而创始人逐渐丧失公司的决策权时，公司就必将不在有着理智的长远的发展眼光，而越来越侧重短线投资和大量套现，从而使公司走向灭亡。2. 第二章从IBM看腾讯，IBM的成功之道在于保守，他不</summary><published>2011-11-10T09:51:00Z</published><updated>2011-11-10T09:51:00Z</updated><author><name>飞林沙</name><uri>http://www.cnblogs.com/kym/</uri></author><link rel="alternate" href="http://www.cnblogs.com/kym/archive/2011/11/10/2244764.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/kym/archive/2011/11/10/2244764.html"/><content type="html">&lt;div&gt;&lt;div&gt;&lt;p&gt;其实我是没有做读书笔记的习惯的，但是这本书只是借来看的，而且这种杂谈性的书，也比较容易扯开去，就随便写了一些东西，大多是自己的一些乱七八糟的想法。现在给汇总一下发出来把。。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;1. 第一章&lt;/p&gt;AT&amp;amp;T的兴起感谢于美国的反垄断法不断地强迫公司做着技术革新，帮助公司修枝剪叶以删除掉那些无用的业务，而衰败同样是由于反垄断法使公司不得不做着不理智的拆分从而使一个巨型帝国迅速的滑落。当一个公司到后期被投行以及他人所大量持股，而创始人逐渐丧失公司的决策权时，公司就必将不在有着理智的长远的发展眼光，而越来越侧重短线投资和大量套现，从而使公司走向灭亡。2. 第二章&lt;div&gt;&lt;pre style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; font: normal normal normal 12px/162% Arial, Helvetica, sans-serif; white-space: pre-wrap; word-wrap: break-word; color: #111111; line-height: 19px; background-color: #ffffff; "&gt;从IBM看腾讯，IBM的成功之道在于保守，他不会盲目地对技术做大步的革新，因为任何一个失败都可能会影响到公司的股价，发展，战略等。所以很多大公司，比如IBM该做的不是盲目的创新，而是在其他公司创新后做出快速反映即使跟进。&lt;div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 1em; padding-left: 0px; "&gt;&lt;/div&gt;而小公司，比如曾经的苹果，一直没有被IBM所击败，而现在太多的中国公司纷纷职责腾讯在抄袭，是因为苹果公司不是满足于当前的用户群体，而是即使地把握到用户的更大的需求和动态，从而持续创新，用反映速度来摆脱大公司的纠缠，然后让自己步入一个灵活变动的大公司的行列。&lt;div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 1em; padding-left: 0px; "&gt;&lt;/div&gt;另外一点让我感触最深的是，IBM在金融危机前后，并没有受到特别大的打击，与他的公司定位&amp;#8220;服务型公司&amp;#8221;是密切相关的。所以我对XaaS这种概念炒作一直嗤之以鼻，却很赞成&amp;#8220;软件即服务&amp;#8221;这种理念，在我看来，无论是行业软件，还是互联网，都是一种变相的服务行业，只有遵循了这一点，才能让一个公司，或者一个网站一直立于不败之地。&lt;div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 1em; padding-left: 0px; "&gt;&lt;/div&gt;然后，多说一句，豆瓣的改版，显然不是以服务为核心导向的，所以我TM也想注销了。&lt;br /&gt;3. 第三章&lt;div&gt;&lt;pre style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; font: normal normal normal 12px/162% Arial, Helvetica, sans-serif; white-space: pre-wrap; word-wrap: break-word; "&gt;水果公司的成功在于始终把任何一个产品做到完美，做到极致。他们和大多数互联网公司不一样，很多互联网为了扩大用户群体，一直信仰的一点是，我们要把用户当成傻子去看待，但是水果公司是把每个他的用户都当成艺术家，然后让这部分人再带动更多的人.....其实也不失一个好战略。&lt;div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 1em; padding-left: 0px; "&gt;&lt;/div&gt;此外，很多PM在苹果兴起后，在做很多产品时都多了一个冠冕堂皇的理由，&amp;#8220;用户不知道自己要什么&amp;#8221;，需要我们来引领，可是不要忘记：&lt;div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 1em; padding-left: 0px; "&gt;&lt;/div&gt;1. 苹果本身是第一个创造出"Windows"的，这本就为他们积累了不少的用户口碑&lt;div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 1em; padding-left: 0px; "&gt;&lt;/div&gt;2. 苹果所说的不知道用户要什么，只是说&amp;#8220;用户想象不到原来还有如此美妙的展现方式&amp;#8221;，而并非&amp;#8220;用户不知道自己想要他已知的A还是B&amp;#8221;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/pre&gt;&lt;br /&gt;4. 第四章&lt;div&gt;&lt;pre style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; font: normal normal normal 12px/162% Arial, Helvetica, sans-serif; white-space: pre-wrap; word-wrap: break-word; color: #111111; line-height: 19px; background-color: #ffffff; "&gt;1. 摩尔定律是有实效期的，摩尔原本认为实效期是10年，可是只今已经过去了近50年，随着技术的发展遇到瓶颈，集成度不可能再像原来一样指数型的提高，我们目前能期待的只是纳米技术的飞速发展来让整个计算机世界发生一个质的飞跃，而如今，摩尔定律的失效只能让我们越来越多地寄望于多核程序设计了。&lt;div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 1em; padding-left: 0px; "&gt;&lt;/div&gt;2. 反摩尔定律：一个IT公司如果今天和18个月前卖出同样多的，同样的产品，那么他的营业额就要降一半。&lt;div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 1em; padding-left: 0px; "&gt;&lt;/div&gt;这个翻译成反摩尔定律好奇怪....其实这个应该说是摩尔定律的一个推论更合适一些。于是这就强迫着IT公司进行技术革新.....&lt;br /&gt;5. 第五章&lt;div&gt;&lt;pre style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; font: normal normal normal 12px/162% Arial, Helvetica, sans-serif; white-space: pre-wrap; word-wrap: break-word; "&gt;在PC时代，Intel的统治地位无须多说，他彻底击垮了Moto，然后为了反垄断留下了一个不足以成为竞争对手的AMD。&lt;div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 1em; padding-left: 0px; "&gt;&lt;/div&gt;但是Intel已经占据了PC市场的之后，从外界看来却有些忽略了移动端的市场，所以未来若干年的发展，如果不及时凭借自己的规模口碑和影响力去抢占这一块，前景堪忧...&lt;br /&gt;6. 第六章&lt;div&gt;&lt;pre style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; font: normal normal normal 12px/162% Arial, Helvetica, sans-serif; white-space: pre-wrap; word-wrap: break-word; "&gt;MSRA是我一直的梦想，所以我把所有的用户名后都加上了ms的后缀，对微软的历史已经再熟悉不过了。&lt;div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 1em; padding-left: 0px; "&gt;&lt;/div&gt;从微软利用MS-DOS起家，到雇佣阿尔钦和卡特勒研发Windows(《观止》)，再到之后的x-box。一直关注着C#的我，更是深刻体会到.NET的强大和微软一统天下的野心。&lt;div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 1em; padding-left: 0px; "&gt;&lt;/div&gt;只是微软在互联网的表现一直让人失望，无论是Bing，还是微软之前力推的Silverlight，在我看来，微软不是由于过于庞大而丧失灵活性，当然，这也是其中的一个原因。而是微软的基因中从来都缺少创新的灵魂，一直都是靠着Windows打天下，而再互联网行业，微软便没有了Windows的优势可利用，而追在别人后面，只能说是别人的市场已经成熟了，微软就很难侵占了。&lt;div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 1em; padding-left: 0px; "&gt;&lt;/div&gt;在这个问题上，我认为吴军博士的分析可能还是有些不到位把......&lt;br /&gt;&lt;br /&gt;7. 第八章&lt;div&gt;&lt;pre style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; font: normal normal normal 12px/162% Arial, Helvetica, sans-serif; white-space: pre-wrap; word-wrap: break-word; "&gt;Yahoo最大的贡献应该在于他开创了一种免费，开源的互联网商业模式。而Yahoo也相当于一手创造了当年的互联网泡沫。&lt;div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 1em; padding-left: 0px; "&gt;&lt;/div&gt;Yahoo最大的失败一点：&lt;div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 1em; padding-left: 0px; "&gt;&lt;/div&gt;Yahoo在我看来一直都是一个人力密集型公司，而不是一个技术型公司，因为他的排名，乃至聚类都是人来完成。而在互联网行业，这样的模式是很容易被复制的。&lt;br /&gt;但是这也怪不得Yahoo，因为Yahoo一直都是以一个传统媒体的思路来经营互联网，甚至包括之后的几位CEO，这就决定了在互联网的浪潮中，对Google战斗的完败。&lt;br /&gt;8. 第九章，第十章&lt;div&gt;&lt;pre style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; font: normal normal normal 12px/162% Arial, Helvetica, sans-serif; white-space: pre-wrap; word-wrap: break-word; "&gt;惠普和Moto一样，都是属于一个以硬件为主要盈利模式的公司，也包括如今的Dell。&lt;div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 1em; padding-left: 0px; "&gt;&lt;/div&gt;但是从目前来看，随着硬件的价格越来越低，也包括无数的&amp;#8220;中国制造&amp;#8221;的冲击，硬件的利润已经越来越小。&lt;div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 1em; padding-left: 0px; "&gt;&lt;/div&gt;惠普越来越多的市场都是投在了打印机上，丰富打印机的生产线，但是从长远角度来看这个仍然很难维持惠普一个大公司的兴起。而Moto作为无线通信的主要生产商，也已经成为了没落的贵族。&lt;div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 1em; padding-left: 0px; "&gt;&lt;/div&gt;如今看来，如果这两个公司，甚至包括其他的硬件厂商，如果不及时地扩展业务模式，或者是与软件，与服务相结合，必然衰败甚至倒闭。&lt;br /&gt;9. 第十一章&lt;div&gt;&lt;pre style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; font: normal normal normal 12px/162% Arial, Helvetica, sans-serif; white-space: pre-wrap; word-wrap: break-word; "&gt;创业几乎是每个IT人的梦想，至少我身边的人都是这样，没有人甘心为人打工一辈子。&lt;div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 1em; padding-left: 0px; "&gt;&lt;/div&gt;但是每当他们跟我说出想法时，我给他们的打击总是多于鼓励和支持，他们给我的理由无外乎某某人做了一个什么什么样的东西，然后这个人就成功了。我往往都会说，那是因为剩下99%没有成功的人你不知道而已。&lt;div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 1em; padding-left: 0px; "&gt;&lt;/div&gt;书上给出了一个小公司想成功的理由： 1. 创始人不仅仅是梦想家，而要是一个实干家。 2. 仅仅有一个好的团队和技术远远不够，更重要的是商业头脑，以及可以找到盈利的商业模型。此外除了领导力，判断力之外，也许更重要的是运气了。我读过茅侃侃的关于创业的一本书，虽然书写的不怎么样，但是有的观点我还是很认同，创业的路是异常坚信的，很多人都看到了成功的结果，而忽略了成功的过程。硅谷每天上千的公司成立，但是同时也有上千的公司关门，血本无归。&lt;div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 1em; padding-left: 0px; "&gt;&lt;/div&gt;此外，我身边的好多人除了创业之外，更多的就是和我说，你看谁谁谁每个月多少多少钱，你看看哪个哪个方向（比如移动开发）每个月多少多少钱，你看某某行业（最多的是金融和销售）每个月多少多少钱。 &lt;div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 1em; padding-left: 0px; "&gt;&lt;/div&gt;我总是说的观点有几个，每个公司都不是傻子（当然我现在越来越感觉傻子还真不少），能给他比你多的工资，必然有他的辛劳之处，太多人看到百度的人工资翻着番的数，可是我更多看到的是百度人日益稀少的头发和大量的情侣分手数。&lt;div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 1em; padding-left: 0px; "&gt;&lt;/div&gt;某个方向的工资很高，无外乎几个可能，第一，这个方向门槛很高，第二，这个方向是个泡沫。比如web开发，世纪初随便会写个html都能拿到高额的年薪，而现在web开发却成为了低端的代名词，以至于前公司大家见面都会说，&amp;#8220;靠，你丫的是套页面的把？&amp;#8221;&amp;#8220;滚！你们去安全家都是套页面的！&amp;#8221; 。 而这种现状完全可以应用于当今的移动（Android和IOS开发），泡沫而已，何必耗费心思呢。&lt;div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 1em; padding-left: 0px; "&gt;&lt;/div&gt;某个行业工资很高，我能说的只是，那是你看到出来炫耀的都是成功人士，殊不知那些每个月只有几百块底薪的销售，和&amp;#8220;四大&amp;#8221;公司里每天累得快吐血的白领人士呢.......&lt;div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 1em; padding-left: 0px; "&gt;&lt;/div&gt;硅谷的&amp;#8220;硅&amp;#8221;&amp;#8212;&amp;#8212;半导体制造业已经随着时代的发展越来越少，取而代之的是生物科技和高新技术，而这些终有一天也会随着时代而消亡，而硅谷之所以长盛不衰，留下的，只有他的创新精神，而这个，正是中国没有硅谷的最大原因之所在把。&lt;br /&gt;10. 第十八章&lt;div&gt;&lt;pre style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; font: normal normal normal 12px/162% Arial, Helvetica, sans-serif; white-space: pre-wrap; word-wrap: break-word; "&gt;如果说微软一直是我的梦想的话，那么Google从来都是我可望不可及的一个神圣的地方。&lt;div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 1em; padding-left: 0px; "&gt;&lt;/div&gt;1. Google至于Yahoo等公司固然有技术上的巨大优势，而从财政上讲，他的成功很大一部分是因为他们没有着急上市，也在融资时注意自己手中的股份，避免被过度稀释，这样就保证了公司创始人的决策权，而不是受华尔街影响。&lt;div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 1em; padding-left: 0px; "&gt;&lt;/div&gt;2. Google和微软之争好多人评价说是技术的胜利，或者决策的胜利等等，可是在我看来，更大因素还是因为微软没找到一个合理的办法把操作系统和互联网捆绑这个关键因素，否则Google的失败也是无可避免。&lt;div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 1em; padding-left: 0px; "&gt;&lt;/div&gt;3. Google的人才政策，Google信仰个人英雄主义。那天吃饭我问女朋友说，你说历史是人民创造的，还是英雄创造的。成绩优异的她果不其然地说人民。可是我却对于尖端行业的&amp;#8220;团队主义&amp;#8221;一直抱有质疑，举个最粗俗的例子，一万个女人生一个孩子一样需要十个月。那么说如果是装配行业，外包行业，10000个人的产量大于10个人没问题。可是对于一些技术性行业来说，我却从来都对&amp;#8220;三个臭皮匠，赛过诸葛亮&amp;#8221;的说法嗤之以鼻。在我看来，与其让我和三个&amp;#8220;臭皮匠&amp;#8221;工作，还不如让我一个人安安心心地工作来得更合适，所以我喜欢精英主义的公司，而对某些大规模不分青红皂白扩招的公司躲得远远的，宁缺勿滥是我一向的格言。所以每次和别人聊天谈起某某公司多少多少人的时候，我都说，三个人足够了把......&lt;div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 1em; padding-left: 0px; "&gt;&lt;/div&gt;4. 关于研究部门。我一直觉得把研究部门和开发部门分开是不太合理的，比如传说中的MSRA不写代码，每天负责的只是研究，结果导致的是很难让研究部门真正开发出真正的产品，如果我组建一个公司，研究部门可以研究某一个具体方向，但是研究区间不得超过一个月，而一个月后他需要的是，进行研究报告，然后如果通过接下来需要申请一个工程团队将这个研究迅速转变成产品，哪怕是实验室项目.....这样才能不会让研究成为单纯的研究。&lt;div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 1em; padding-left: 0px; "&gt;&lt;/div&gt;5. &amp;#8220;杀鸡也用牛刀&amp;#8221;，这个在我看来是一把双刃剑。一方面，这样会损耗掉大量的人才，也会让大量的人才逐渐趋于平庸，而且牛刀杀鸡是不是更好还有待考证。另外，这样非常不利于控制公司的成本。&lt;div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 1em; padding-left: 0px; "&gt;&lt;/div&gt;6. Android。Android无非是近年来智能手机的一个创举，超过多年的老品牌Symbian，更是将IOS和WP远远甩在身后，但是在我看来，如果Android不解决以下几个问题，必然成为迅速陨落的流星。&lt;div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 1em; padding-left: 0px; "&gt;&lt;/div&gt;A. 版本更新过快的问题。十天的时间，九天都在讨论要不要刷系统明显是个很不成熟的情况。&lt;div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 1em; padding-left: 0px; "&gt;&lt;/div&gt;B. 亟需一个行业约定标准。这个是Android和IOS最大的差距之所在。Google一向的做事风格就是联合各大厂商然后来狙击一个巨头，以前是联合电脑制作商，互联网公司来狙击微软，今天是联合各大手机制造商来狙击Apple，但是这一套明显在手机操作系统时代行不通。各大手机都有着不同的硬件标准，这样每个公司都需要对Android做一个定制，而各大n公司的水平更是参差不平，这就导致了整个系统的混乱，尤其是对手机应用开发者更是痛苦，缺乏了应用的智能手机更是鸡肋了。&lt;div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 1em; padding-left: 0px; "&gt;&lt;/div&gt;C. 效率问题。太多Android粉都辩解着Android的手机不慢，可是从技术的角度说，Android这种基于虚拟机的效率低于IOS是毋容置疑的，而打开性能监视器更是可以看到GC回收个没完没了.....&lt;div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 1em; padding-left: 0px; "&gt;&lt;/div&gt;7. Google的商业竞争这句话我最喜欢，进攻就是最好的防守，不要怕失败，努力地去向那些所谓的权威质疑把！&lt;br /&gt;11. 第二十章&lt;div&gt;&lt;pre style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; font: normal normal normal 12px/162% Arial, Helvetica, sans-serif; white-space: pre-wrap; word-wrap: break-word; "&gt;1. 在我看来，web2.0应该是无干涉的，公司只需要打造一个平台任由用户自由发挥，从这个意义来说，由于天朝独有的审核制度，使国内不存在真正意义上的web2.0。作者在书中给出了这样几个web2.0必备的特征。&lt;div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 1em; padding-left: 0px; "&gt;&lt;/div&gt;A. 必须有平台可以接受并管理用户的内容，并且这些内容是网站的主体。&lt;div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 1em; padding-left: 0px; "&gt;&lt;/div&gt;B. 这个必须是个平台，允许用户开发自己的程序。&lt;div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 1em; padding-left: 0px; "&gt;&lt;/div&gt;C. 交互性。交互通信和信息共享。&lt;div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 1em; padding-left: 0px; "&gt;&lt;/div&gt;D. 非竞争性和自足性。&lt;div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 1em; padding-left: 0px; "&gt;&lt;/div&gt;2. 关于web2.0的盈利。我一直对web2.0不足够看好，如果说web1.0是单对多，web2.0是多对多，那我更愿意相信web3.0是一种基于语义，基于上下文等等的完全个性化定制，那么如果从这个意义上来说，web2.0只是web3.0的一个过度，就如Vista一样，只是一个过度产品而已。&lt;div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 1em; padding-left: 0px; "&gt;&lt;/div&gt;评价一个网站，一个公司的好坏只有一个标准，是否盈利，财务报表是否足够漂亮，那么web2.0明显是雷声大雨点小的，我曾经帮别人修改一个商业计划书里写，这个网站我只能制定一个最终的目标，但是不能确定其产品表现形式，我更不会为了做社区而去做社区，因为在我看来，包括Facebook和Twitter在内，都是一个失败的产品，因为他们直到现在都没有找到足够好的盈利模式，尤其是Twitter。&lt;div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 1em; padding-left: 0px; "&gt;&lt;/div&gt;曾经有人问我新浪微博怎么样，我的回答是，微博这样的产品代表了当今社会的浮躁，在宣扬一种快餐文化，但是微博直到现在都没有办法找到一个成熟的盈利模式，唯一可能进行的也不过是一些热门账号的软广告，以及广告精准投放而已，而我们知道，靠广告生存的公司的空间越来越小。 所以我对国内各大互联网公司盲目追随Twitter, 投资微博感觉非常不理解，更对点点这类还宣扬&amp;#8220;轻微博&amp;#8221;的网站感到好笑，由此也是对开复老师创新工厂的投资眼光表示质疑。 而新浪微博的前景，我更愿意相信这只是新浪想用来拆分上市然后大佬一笔的中间产品而已。&lt;div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 1em; padding-left: 0px; "&gt;&lt;/div&gt;如果说web2.0的盈利渠道，只能个性化，再个性化，然后通过个性化进一步做广告精准投放以及商品推荐，以及打造一个更加开放的平台，然后收取中间费用（在这一点上人人做的应该是很好的）。但是这个已经是偏向于web3.0的概念了。&lt;div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 1em; padding-left: 0px; "&gt;&lt;/div&gt;此外，好多人跟我聊天时候说创业的点子，我说，从前，我们做网站是努力把线下生活搬到互联网上，让人们能在网上真实模拟日常生活，造成这个的原因是互联网行业的不成熟。而随着互联网的日益成熟，我们该想的是，如何把线上生活搬到线下，打造这样一个实体店，让用户在日常生活中像在网上一样。如此往复循环，线上线下彼此促进，才是未来互联网的趋势。&lt;div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 1em; padding-left: 0px; "&gt;&lt;/div&gt;曾经的年代线下依赖于线上的广告，那么在下一个年代，让线上的网站基于线下的实体体验，是不是也可以看成未来web3.0乃至web4.0的一个卖点所在呢....&lt;br /&gt;&lt;br /&gt;最后，顺路给自己豆瓣打个广告把，http://www.douban.com/people/lovekym/。&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;img src="http://www.cnblogs.com/kym/aggbug/2244764.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/kym/archive/2011/11/10/2244764.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/kym/archive/2011/09/26/2191501.html</id><title type="text">R对MongoDB的性能测试——RMongo</title><summary type="text">在九月初的时候，RMongoDB正式发布了修订版本，这也就意味着，从事数值计算的语言也可以于Nosql产品相接轨了，但是鉴于我身边并没有公司真的在使用R和MongoDB的结合，所以在效率问题上，我们也不敢掉以轻心，所以就做了一个这样的测试。测试环境是8核，64位机。 用于测试的库是一个未经Sharding，大概30G左右的Collection。用于存储用户的喜好信息，标签信息等数据。 1library(rmongodb)23mongo&lt;-mongo.create()45if(mongo.is.connected(mongo))6{7ns&lt;-'rivendell.user&amp;#</summary><published>2011-09-26T03:35:00Z</published><updated>2011-09-26T03:35:00Z</updated><author><name>飞林沙</name><uri>http://www.cnblogs.com/kym/</uri></author><link rel="alternate" href="http://www.cnblogs.com/kym/archive/2011/09/26/2191501.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/kym/archive/2011/09/26/2191501.html"/><content type="html">&lt;p&gt;在九月初的时候，RMongoDB正式发布了修订版本，这也就意味着，从事数值计算的语言也可以于Nosql产品相接轨了，但是鉴于我身边并没有公司真的在使用R和MongoDB的结合，所以在效率问题上，我们也不敢掉以轻心，所以就做了一个这样的测试。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;测试环境是8核，64位机。 用于测试的库是一个未经Sharding，大概30G左右的Collection。用于存储用户的喜好信息，标签信息等数据。&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div&gt;&lt;div&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;font class="Apple-style-span" face="Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif"&gt;&amp;nbsp; &amp;nbsp;&lt;/font&gt;&lt;span style="color: #008080;"&gt;1&lt;/span&gt;&amp;nbsp;library(rmongodb)&lt;span style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; font-size: 13px; line-height: 19px; "&gt;&lt;/span&gt;&lt;div&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;2&lt;/span&gt;&amp;nbsp;&lt;br /&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;3&lt;/span&gt;&amp;nbsp;mongo&amp;nbsp;&amp;lt;-&amp;nbsp;mongo.create()&lt;br /&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;4&lt;/span&gt;&amp;nbsp;&lt;br /&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;5&lt;/span&gt;&amp;nbsp;&lt;span style="color: #0000FF;"&gt;if&lt;/span&gt;(mongo.&lt;span style="color: #0000FF;"&gt;is&lt;/span&gt;.connected(mongo))&lt;br /&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;6&lt;/span&gt;&amp;nbsp;{&lt;br /&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;7&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ns&amp;nbsp;&amp;lt;-&amp;nbsp;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;rivendell.user&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;8&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #0000FF;"&gt;print&lt;/span&gt;(&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;查询一个没有索引的字段，查询一条&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;)&lt;br /&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;9&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #0000FF;"&gt;print&lt;/span&gt;(system.time(p&amp;nbsp;&amp;lt;-&amp;nbsp;mongo.find.one(mongo,ns,list(Friend=600))))&lt;br /&gt;&lt;span style="color: #008080;"&gt;10&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #0000FF;"&gt;print&lt;/span&gt;(&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;查询一个没有索引的字段，多条,without&amp;nbsp;buffer&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;)&lt;br /&gt;&lt;span style="color: #008080;"&gt;11&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #0000FF;"&gt;print&lt;/span&gt;(system.time(p&amp;nbsp;&amp;lt;-&amp;nbsp;mongo.find(mongo,ns,list(Friend=600))))&lt;br /&gt;&lt;span style="color: #008080;"&gt;12&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #0000FF;"&gt;print&lt;/span&gt;(&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;看看是否有缓存策略&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;)&lt;br /&gt;&lt;span style="color: #008080;"&gt;13&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #0000FF;"&gt;print&lt;/span&gt;(system.time(p&amp;nbsp;&amp;lt;-&amp;nbsp;mongo.find(mongo,ns,list(Friend=600))))&lt;br /&gt;&lt;span style="color: #008080;"&gt;14&lt;/span&gt;&amp;nbsp;&lt;br /&gt;&lt;span style="color: #008080;"&gt;15&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #0000FF;"&gt;print&lt;/span&gt;(&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;查询一个没有索引的字段，多条,has&amp;nbsp;buffer&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;)&lt;br /&gt;&lt;span style="color: #008080;"&gt;16&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;buf&amp;nbsp;&amp;lt;-&amp;nbsp;mongo.bson.buffer.create()&lt;br /&gt;&lt;span style="color: #008080;"&gt;17&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;mongo.bson.buffer.append(buf,&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;Friend&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;,600L)&lt;br /&gt;&lt;span style="color: #008080;"&gt;18&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;query&amp;nbsp;&amp;lt;-&amp;nbsp;mongo.bson.&lt;span style="color: #0000FF;"&gt;from&lt;/span&gt;.buffer(buf)&lt;br /&gt;&lt;span style="color: #008080;"&gt;19&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #0000FF;"&gt;print&lt;/span&gt;(system.time(p&amp;nbsp;&amp;lt;-&amp;nbsp;mongo.find(mongo,ns,query)))&lt;br /&gt;&lt;span style="color: #008080;"&gt;20&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #0000FF;"&gt;print&lt;/span&gt;(&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;看看是否有缓存策略&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;)&lt;br /&gt;&lt;span style="color: #008080;"&gt;21&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;buf&amp;nbsp;&amp;lt;-&amp;nbsp;mongo.bson.buffer.create()&lt;br /&gt;&lt;span style="color: #008080;"&gt;22&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;mongo.bson.buffer.append(buf,&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;Friend&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;,600L)&lt;br /&gt;&lt;span style="color: #008080;"&gt;23&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;query&amp;nbsp;&amp;lt;-&amp;nbsp;mongo.bson.&lt;span style="color: #0000FF;"&gt;from&lt;/span&gt;.buffer(buf)&lt;br /&gt;&lt;span style="color: #008080;"&gt;24&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #0000FF;"&gt;print&lt;/span&gt;(system.time(p&amp;nbsp;&amp;lt;-&amp;nbsp;mongo.find(mongo,ns,query)))&lt;br /&gt;&lt;span style="color: #008080;"&gt;25&lt;/span&gt;&amp;nbsp;&lt;br /&gt;&lt;span style="color: #008080;"&gt;26&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #0000FF;"&gt;print&lt;/span&gt;(&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;大于的查询，查询一条记录&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;)&lt;br /&gt;&lt;span style="color: #008080;"&gt;27&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #0000FF;"&gt;print&lt;/span&gt;(system.time(p&amp;nbsp;&amp;lt;-&amp;nbsp;mongo.find.one(mongo,ns,list(Friend=list(&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;$gt&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;=600L)))))&lt;br /&gt;&lt;span style="color: #008080;"&gt;28&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #0000FF;"&gt;print&lt;/span&gt;(&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;大于的记录，查询多条记录&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;)&lt;br /&gt;&lt;span style="color: #008080;"&gt;29&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #0000FF;"&gt;print&lt;/span&gt;(system.time(cursor&amp;nbsp;&amp;lt;-&amp;nbsp;mongo.find(mongo,ns,list(Friend=list(&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;$gt&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;=600L)))))&lt;br /&gt;&lt;span style="color: #008080;"&gt;30&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;mongo.cursor.destroy(cursor)&lt;br /&gt;&lt;span style="color: #008080;"&gt;31&lt;/span&gt;&amp;nbsp;&lt;br /&gt;&lt;span style="color: #008080;"&gt;32&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #0000FF;"&gt;print&lt;/span&gt;(&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;查询一条有索引的记录&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;)&lt;br /&gt;&lt;span style="color: #008080;"&gt;33&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #0000FF;"&gt;print&lt;/span&gt;(system.time(p&amp;nbsp;&amp;lt;-&amp;nbsp;mongo.find.one(mongo,ns,list(&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;_id&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;=3831809L))))&lt;br /&gt;&lt;span style="color: #008080;"&gt;34&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #0000FF;"&gt;print&lt;/span&gt;(&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;查询索引的记录&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;)&lt;br /&gt;&lt;span style="color: #008080;"&gt;35&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #0000FF;"&gt;print&lt;/span&gt;(system.time(p&amp;nbsp;&amp;lt;-&amp;nbsp;mongo.find(mongo,ns,list(&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;_id&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;=3831809L))))&lt;br /&gt;&lt;span style="color: #008080;"&gt;36&lt;/span&gt;&amp;nbsp;&lt;br /&gt;&lt;span style="color: #008080;"&gt;37&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #0000FF;"&gt;print&lt;/span&gt;(&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;插入一条记录&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;)&lt;br /&gt;&lt;span style="color: #008080;"&gt;38&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;buf&amp;nbsp;&amp;lt;-&amp;nbsp;mongo.bson.buffer.create()&lt;br /&gt;&lt;span style="color: #008080;"&gt;39&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;mongo.bson.buffer.append(buf,&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;name&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;huangxin&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;)&lt;br /&gt;&lt;span style="color: #008080;"&gt;40&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;mongo.bson.buffer.append(buf,&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;age&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;,22L)&lt;br /&gt;&lt;span style="color: #008080;"&gt;41&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;p&amp;nbsp;&amp;lt;-&amp;nbsp;mongo.bson.&lt;span style="color: #0000FF;"&gt;from&lt;/span&gt;.buffer(buf)&lt;br /&gt;&lt;span style="color: #008080;"&gt;42&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #0000FF;"&gt;print&lt;/span&gt;(system.time(mongo.insert(mongo,ns,p)))&lt;br /&gt;&lt;span style="color: #008080;"&gt;43&lt;/span&gt;&amp;nbsp;&lt;br /&gt;&lt;span style="color: #008080;"&gt;44&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #0000FF;"&gt;print&lt;/span&gt;(&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;找到刚刚插入的记录&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;)&lt;br /&gt;&lt;span style="color: #008080;"&gt;45&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #0000FF;"&gt;print&lt;/span&gt;(system.time(p&amp;nbsp;&amp;lt;-&amp;nbsp;mongo.find.one(mongo,ns,list(&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;name&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;=&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;huangxin&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;))))&lt;br /&gt;&lt;span style="color: #008080;"&gt;46&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #0000FF;"&gt;if&lt;/span&gt;(!&lt;span style="color: #0000FF;"&gt;is&lt;/span&gt;.null(p))&lt;br /&gt;&lt;span style="color: #008080;"&gt;47&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&lt;span style="color: #008080;"&gt;48&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #0000FF;"&gt;print&lt;/span&gt;(&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;success&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;)&lt;br /&gt;&lt;span style="color: #008080;"&gt;49&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&lt;span style="color: #008080;"&gt;50&lt;/span&gt;&amp;nbsp;&lt;br /&gt;&lt;span style="color: #008080;"&gt;51&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #0000FF;"&gt;print&lt;/span&gt;(&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;批量插入&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;)&lt;br /&gt;&lt;span style="color: #008080;"&gt;52&lt;/span&gt;&amp;nbsp;&lt;br /&gt;&lt;span style="color: #008080;"&gt;53&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;buf&amp;nbsp;&amp;lt;-&amp;nbsp;mongo.bson.buffer.create()&lt;br /&gt;&lt;span style="color: #008080;"&gt;54&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;mongo.bson.buffer.append(buf,&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;name&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;,&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;huangxin&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;)&lt;br /&gt;&lt;span style="color: #008080;"&gt;55&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;mongo.bson.buffer.append(buf,&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;age&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;,22L)&lt;br /&gt;&lt;span style="color: #008080;"&gt;56&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;p1&amp;nbsp;&amp;lt;-&amp;nbsp;mongo.bson.&lt;span style="color: #0000FF;"&gt;from&lt;/span&gt;.buffer(buf)&lt;br /&gt;&lt;span style="color: #008080;"&gt;57&lt;/span&gt;&amp;nbsp;&lt;br /&gt;&lt;span style="color: #008080;"&gt;58&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;buf&amp;nbsp;&amp;lt;-&amp;nbsp;mongo.bson.buffer.create()&lt;br /&gt;&lt;span style="color: #008080;"&gt;59&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;mongo.bson.buffer.append(buf,&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;name&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;,&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;huangxin&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;)&lt;br /&gt;&lt;span style="color: #008080;"&gt;60&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;mongo.bson.buffer.append(buf,&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;age&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;,22L)&lt;br /&gt;&lt;span style="color: #008080;"&gt;61&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;p2&amp;nbsp;&amp;lt;-&amp;nbsp;mongo.bson.&lt;span style="color: #0000FF;"&gt;from&lt;/span&gt;.buffer(buf)&lt;br /&gt;&lt;span style="color: #008080;"&gt;62&lt;/span&gt;&amp;nbsp;&lt;br /&gt;&lt;span style="color: #008080;"&gt;63&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;buf&amp;nbsp;&amp;lt;-&amp;nbsp;mongo.bson.buffer.create()&lt;br /&gt;&lt;span style="color: #008080;"&gt;64&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;mongo.bson.buffer.append(buf,&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;name&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;,&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;huangxin&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;)&lt;br /&gt;&lt;span style="color: #008080;"&gt;65&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;mongo.bson.buffer.append(buf,&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;age&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;,22L)&lt;br /&gt;&lt;span style="color: #008080;"&gt;66&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;p3&amp;nbsp;&amp;lt;-&amp;nbsp;mongo.bson.&lt;span style="color: #0000FF;"&gt;from&lt;/span&gt;.buffer(buf)&lt;br /&gt;&lt;span style="color: #008080;"&gt;67&lt;/span&gt;&amp;nbsp;&lt;br /&gt;&lt;span style="color: #008080;"&gt;68&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #0000FF;"&gt;print&lt;/span&gt;(system.time(mongo.insert.batch(mongo,ns,list(p1,p2,p3))))&lt;br /&gt;&lt;span style="color: #008080;"&gt;69&lt;/span&gt;&amp;nbsp;&lt;br /&gt;&lt;span style="color: #008080;"&gt;70&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #0000FF;"&gt;print&lt;/span&gt;(&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;找到刚刚批量插入的记录&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;)&lt;br /&gt;&lt;span style="color: #008080;"&gt;71&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #0000FF;"&gt;print&lt;/span&gt;(system.time(cursor&amp;nbsp;&amp;lt;-&amp;nbsp;mongo.find(mongo,ns,list(&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;name&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;=&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;huangxin&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;))))&lt;br /&gt;&lt;span style="color: #008080;"&gt;72&lt;/span&gt;&amp;nbsp;&lt;br /&gt;&lt;span style="color: #008080;"&gt;73&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;i&amp;nbsp;&amp;lt;-&amp;nbsp;0&lt;br /&gt;&lt;span style="color: #008080;"&gt;74&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #0000FF;"&gt;while&lt;/span&gt;(mongo.cursor.next(cursor))&lt;br /&gt;&lt;span style="color: #008080;"&gt;75&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&lt;span style="color: #008080;"&gt;76&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;i&amp;nbsp;&amp;lt;-&amp;nbsp;i&amp;nbsp;+&amp;nbsp;1&lt;br /&gt;&lt;span style="color: #008080;"&gt;77&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&lt;span style="color: #008080;"&gt;78&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #0000FF;"&gt;print&lt;/span&gt;(i)&lt;br /&gt;&lt;span style="color: #008080;"&gt;79&lt;/span&gt;&amp;nbsp;&lt;br /&gt;&lt;span style="color: #008080;"&gt;80&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #0000FF;"&gt;print&lt;/span&gt;(&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;批量更新&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;)&lt;br /&gt;&lt;span style="color: #008080;"&gt;81&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #0000FF;"&gt;print&lt;/span&gt;(system.time(mongo.update(mongo,ns,list(name=&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;huangxin&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;),list(&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;name&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;=&amp;nbsp;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;kym&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;))))&lt;br /&gt;&lt;span style="color: #008080;"&gt;82&lt;/span&gt;&amp;nbsp;&lt;br /&gt;&lt;span style="color: #008080;"&gt;83&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #0000FF;"&gt;print&lt;/span&gt;(&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;查看更新是否成功&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;)&lt;br /&gt;&lt;span style="color: #008080;"&gt;84&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #0000FF;"&gt;print&lt;/span&gt;(system.time(p&amp;nbsp;&amp;lt;-&amp;nbsp;mongo.find.one(mongo,ns,list(&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;name&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;=&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;kym&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;))))&lt;br /&gt;&lt;span style="color: #008080;"&gt;85&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #0000FF;"&gt;if&lt;/span&gt;(!&lt;span style="color: #0000FF;"&gt;is&lt;/span&gt;.null(p))&lt;br /&gt;&lt;span style="color: #008080;"&gt;86&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&lt;span style="color: #008080;"&gt;87&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #0000FF;"&gt;print&lt;/span&gt;(&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;success&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;)&lt;br /&gt;&lt;span style="color: #008080;"&gt;88&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&lt;span style="color: #008080;"&gt;89&lt;/span&gt;&amp;nbsp;&lt;br /&gt;&lt;span style="color: #008080;"&gt;90&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #0000FF;"&gt;print&lt;/span&gt;(&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;批量删除&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;)&lt;br /&gt;&lt;span style="color: #008080;"&gt;91&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #0000FF;"&gt;print&lt;/span&gt;(system.time(mongo.remove(mongo,ns,list(name=&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;kym&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;))))&lt;br /&gt;&lt;span style="color: #008080;"&gt;92&lt;/span&gt;&amp;nbsp;}&lt;br /&gt;&lt;span style="color: #008080;"&gt;93&lt;/span&gt;&amp;nbsp;&lt;br /&gt;&lt;span style="color: #008080;"&gt;94&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #0000FF;"&gt;print&lt;/span&gt;(system.time(p&amp;nbsp;&amp;lt;-&amp;nbsp;mongo.find.one(mongo,ns,list(&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;name&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;=&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;kym&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;))))&lt;br /&gt;&lt;span style="color: #008080;"&gt;95&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #0000FF;"&gt;if&lt;/span&gt;(!&lt;span style="color: #0000FF;"&gt;is&lt;/span&gt;.null(p))&lt;br /&gt;&lt;span style="color: #008080;"&gt;96&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&lt;span style="color: #008080;"&gt;97&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #0000FF;"&gt;print&lt;/span&gt;(&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;success&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;)&lt;br /&gt;&lt;span style="color: #008080;"&gt;98&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;[1]&amp;nbsp;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;查询一个没有索引的字段，查询一条&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;br /&gt;user&amp;nbsp;system&amp;nbsp;elapsed&lt;br /&gt;0.000&amp;nbsp;0.000&amp;nbsp;0.115&lt;br /&gt;[1]&amp;nbsp;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;查询一个没有索引的字段，多条,without&amp;nbsp;buffer&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;br /&gt;user&amp;nbsp;system&amp;nbsp;elapsed&lt;br /&gt;0.000&amp;nbsp;0.000&amp;nbsp;32.513&lt;br /&gt;[1]&amp;nbsp;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;看看是否有缓存策略&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;br /&gt;user&amp;nbsp;system&amp;nbsp;elapsed&lt;br /&gt;0.000&amp;nbsp;0.000&amp;nbsp;32.528&lt;br /&gt;[1]&amp;nbsp;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;查询一个没有索引的字段，多条,has&amp;nbsp;buffer&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;br /&gt;user&amp;nbsp;system&amp;nbsp;elapsed&lt;br /&gt;0.000&amp;nbsp;0.000&amp;nbsp;32.685&lt;br /&gt;[1]&amp;nbsp;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;看看是否有缓存策略&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;br /&gt;user&amp;nbsp;system&amp;nbsp;elapsed&lt;br /&gt;0.000&amp;nbsp;0.000&amp;nbsp;33.172&lt;br /&gt;[1]&amp;nbsp;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;大于的查询，查询一条记录&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;br /&gt;user&amp;nbsp;system&amp;nbsp;elapsed&lt;br /&gt;0.000&amp;nbsp;0.000&amp;nbsp;0.001&lt;br /&gt;[1]&amp;nbsp;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;大于的记录，查询多条记录&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;br /&gt;user&amp;nbsp;system&amp;nbsp;elapsed&lt;br /&gt;0.000&amp;nbsp;0.000&amp;nbsp;0.014&lt;br /&gt;[1]&amp;nbsp;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;查询一条有索引的记录&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;br /&gt;user&amp;nbsp;system&amp;nbsp;elapsed&lt;br /&gt;0&amp;nbsp;0&amp;nbsp;0&lt;br /&gt;[1]&amp;nbsp;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;查询索引的记录&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;br /&gt;user&amp;nbsp;system&amp;nbsp;elapsed&lt;br /&gt;0&amp;nbsp;0&amp;nbsp;0&lt;br /&gt;[1]&amp;nbsp;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;插入一条记录&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;br /&gt;user&amp;nbsp;system&amp;nbsp;elapsed&lt;br /&gt;0&amp;nbsp;0&amp;nbsp;0&lt;br /&gt;[1]&amp;nbsp;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;找到刚刚插入的记录&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;br /&gt;user&amp;nbsp;system&amp;nbsp;elapsed&lt;br /&gt;0.00&amp;nbsp;0.00&amp;nbsp;35.42&lt;br /&gt;[1]&amp;nbsp;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;success&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;br /&gt;[1]&amp;nbsp;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;批量插入&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;br /&gt;user&amp;nbsp;system&amp;nbsp;elapsed&lt;br /&gt;0&amp;nbsp;0&amp;nbsp;0&lt;br /&gt;[1]&amp;nbsp;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;找到刚刚批量插入的记录&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;br /&gt;user&amp;nbsp;system&amp;nbsp;elapsed&lt;br /&gt;0.004&amp;nbsp;0.000&amp;nbsp;35.934&lt;br /&gt;[1]&amp;nbsp;7&lt;br /&gt;[1]&amp;nbsp;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;批量更新&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;br /&gt;user&amp;nbsp;system&amp;nbsp;elapsed&lt;br /&gt;0.000&amp;nbsp;0.004&amp;nbsp;0.000&lt;br /&gt;[1]&amp;nbsp;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;查看更新是否成功&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;br /&gt;user&amp;nbsp;system&amp;nbsp;elapsed&lt;br /&gt;0.000&amp;nbsp;0.000&amp;nbsp;67.773&lt;br /&gt;[1]&amp;nbsp;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;success&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;br /&gt;[1]&amp;nbsp;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;批量删除&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;br /&gt;user&amp;nbsp;system&amp;nbsp;elapsed&lt;br /&gt;0&amp;nbsp;0&amp;nbsp;0&lt;br /&gt;user&amp;nbsp;system&amp;nbsp;elapsed&lt;br /&gt;0.000&amp;nbsp;0.000&amp;nbsp;91.396&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; font-size: 13px; line-height: 19px; "&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;之前我一直不太理解的就是为什么大于和等于，差距会差这么多。后来当我在用Python去做同样的测试的时候发现，Python两者的效率其实是相同的，所以这就证明了这个不是MongoDB的问题，而我不相信在数据库层面，一个语言的Driver会有这么大的差别。&lt;/p&gt;&lt;p&gt;后来我发现了Python和R的关于MongoDB Driver的一个区别。首先，Python find的时候，不是将查询到的数据集整体拉回，而是返回一个cursor，也就是说，他在执行find命令的时候并不消耗时间，而如果加上while cursor.next()的时候，才会真正地去执行这个查询。&lt;/p&gt;&lt;p&gt;但是R不一样，R会首先考虑数据集的大小（或者其他情况），然后视情况而定地返回cursor还是将整个数据集整体拉回。如果我们将之前的while mongo.cursor.next(cursor)也算在计算时间的时候，那么我们就会发现，其实大于和等于的操作，效率相差并不明显了.......&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;在实际操作中，批量插入是一个非常常见的应用场景，但是对于R或者Matlab语言来说，循环的效率一直是硬伤，所以接下来，我会尝试着用apply系列来解决R语言的循环问题，如果实际操作发现可行，那么接下来使用mutilab等R的并行计算库来充分发挥多核的效率也值得尝试了！&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/kym/aggbug/2191501.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/kym/archive/2011/09/26/2191501.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/kym/archive/2011/07/31/2123308.html</id><title type="text">Euler第三题</title><summary type="text">帮同学做道题....其实真没什么好的做法....1defgetList(n):2result=[]3count=34max=n5whilemax%2==0:6max/=27result.append(2)89whilecount&lt;=max:10ifmax%count==0:11result.append(count)12max/=count13else:14count+=215returnresult1617printgetList(600851475143)</summary><published>2011-07-31T15:55:00Z</published><updated>2011-07-31T15:55:00Z</updated><author><name>飞林沙</name><uri>http://www.cnblogs.com/kym/</uri></author><link rel="alternate" href="http://www.cnblogs.com/kym/archive/2011/07/31/2123308.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/kym/archive/2011/07/31/2123308.html"/><content type="html">&lt;p&gt;帮同学做道题....其实真没什么好的做法....&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;1&lt;/span&gt;&amp;nbsp;&lt;span style="color: #0000FF;"&gt;def&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;getList(n):&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;2&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;result&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;[]&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;3&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;count&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;3&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;4&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;max&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;n&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;5&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;while&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;max&lt;/span&gt;&lt;span style="color: #000000;"&gt;%&lt;/span&gt;&lt;span style="color: #000000;"&gt;2&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;==&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;0:&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;6&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;max&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;/=&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;2&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;7&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;result.append(&lt;/span&gt;&lt;span style="color: #000000;"&gt;2&lt;/span&gt;&lt;span style="color: #000000;"&gt;)&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;8&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;&amp;nbsp;9&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;while&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;count&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;max:&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;10&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;max&lt;/span&gt;&lt;span style="color: #000000;"&gt;%&lt;/span&gt;&lt;span style="color: #000000;"&gt;count&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;==&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;0:&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;11&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;result.append(count)&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;12&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;max&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;/=&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;count&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;13&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;else&lt;/span&gt;&lt;span style="color: #000000;"&gt;:&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;14&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;count&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;+=&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000;"&gt;2&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;15&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;result&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;16&lt;/span&gt;&amp;nbsp;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New'; font-size: 13px; line-height: 19px; background-color: #f5f5f5; "&gt;&lt;span style="color: #008080;"&gt;17&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;print&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;getList(&lt;/span&gt;&lt;span style="color: #000000;"&gt;600851475143&lt;/span&gt;&lt;span style="color: #000000;"&gt;)&lt;/span&gt;&lt;/span&gt;&amp;nbsp;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/kym/aggbug/2123308.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/kym/archive/2011/07/31/2123308.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/kym/archive/2011/06/01/2065327.html</id><title type="text">谈谈开放平台</title><summary type="text">不知道从什么时候起，开放平台越来越多地走近了我们的视线，从最初的开心开放平台，人人开放平台，新浪开放平台，再到即将发布的飞信开放平台，腾讯Q+开放平台，似乎在这么一瞬间，开放平台成了各个互联网的一个标配。如果你没有这么一个开放平台，你都不好意思说我是一个互联网公司。 那么这里，我们就来谈谈这个所谓的开放平台。 1. 什么是开放平台 首先，让我们来了解下什么是开放平台。 也许对于程序员来说，...</summary><published>2011-05-31T18:56:00Z</published><updated>2011-05-31T18:56:00Z</updated><author><name>飞林沙</name><uri>http://www.cnblogs.com/kym/</uri></author><link rel="alternate" href="http://www.cnblogs.com/kym/archive/2011/06/01/2065327.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/kym/archive/2011/06/01/2065327.html"/><content type="html">&lt;p&gt;不知道从什么时候起，开放平台越来越多地走近了我们的视线，从最初的开心开放平台，人人开放平台，新浪开放平台，再到即将发布的飞信开放平台，腾讯Q+开放平台，似乎在这么一瞬间，开放平台成了各个互联网的一个标配。如果你没有这么一个开放平台，你都不好意思说我是一个互联网公司。&lt;/p&gt;  &lt;p&gt;那么这里，我们就来谈谈这个所谓的开放平台。&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;font color="#0000ff"&gt;1. 什么是开放平台&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;首先，让我们来了解下什么是开放平台。&lt;/p&gt;  &lt;p&gt;也许对于程序员来说，有一个概念一定不陌生，Open API，对，就是开放的应用程序接口。那么开放平台呢？我们不要把他想的那么神秘，简单来说就是Open API + Platform，那么什么是Platform，简单来说，就是一个系统，让别的系统可以接进来。&lt;/p&gt;  &lt;p&gt;那让我来总结一下什么是开放平台？我个人认为&lt;font color="#ff0000"&gt;&lt;strong&gt;就是一个软件系统（互联网）开放自己内部的API，允许外部的程序通过调用自己的API接入自己的系统，从而来靠第三方的资源来增加自己软件系统的功能。&lt;/strong&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;那么这么一说也许就很简单了？开放平台这个概念其实很早就有了？是什么呢？操作系统！开放自己的API，然后为用户提供各种各样的功能。我们今天所说的开放平台，其实不过类似于操作系统的内核，而第三方的系统类似于其他的应用程序开发商，只此而已。&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;font color="#0000ff"&gt;2. 开放平台和内容聚合&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;其实在之前，我一直没有弄清楚开放平台和内容聚合一直有什么区别？&lt;/p&gt;  &lt;p&gt;最初我问同事，开放台到底是个什么东西？他能为我带来什么？&lt;/p&gt;  &lt;p&gt;同事告诉我，你有腾讯微博，新浪微博，饭否，Twitter，那么你只需要登陆开放平台，就可以看到这四个微博的最新动态了！&lt;/p&gt;  &lt;p&gt;我说，那么，这和市面上已有的微博聚合工具有什么区别呢？不就是验证一下，然后调用几个API而已么？&lt;/p&gt;  &lt;p&gt;然后同事也说不出个所以然来了。&lt;/p&gt;  &lt;p&gt;再到之后我看过了开放平台的一些资料和定义，大致明白了他们之间的区别。&lt;font color="#ff0000"&gt;&lt;strong&gt;从技术上说，开放平台是推的过程，是从内容产生处向开放平台来推送。而聚合是一个拉的过程，是从内容聚合软件（网站）去内容产生处来抓取&lt;/strong&gt;&lt;/font&gt;。&lt;/p&gt;  &lt;p&gt;那为什么同事没办法说出个所以然来，是因为，&lt;font color="#ff0000"&gt;&lt;strong&gt;站在用户的角度来说，内容聚合和开放平台并无本质区别&lt;/strong&gt;&lt;/font&gt;，对他们来说，都是一个聚合的过程。那么我们抛开技术，开放平台和聚合软件的差别究竟在哪儿？&lt;font color="#ff0000"&gt;&lt;strong&gt;在于第三方应用厂商的利益&lt;/strong&gt;&lt;/font&gt;。&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;font color="#0000ff"&gt;3. 开放平台的商业价值&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;越来越多的互联网公司都逐渐地走向了开放平台这一条路。网易，百度，人人，腾讯，飞信，他们为什么要开放？他们都是商业公司，相信每个人都不会相信他们所说的希望来通过自己的开放来改变中国的互联网这样的鬼话。做任何事情，无外乎就一个目的，盈利！&lt;/p&gt;  &lt;p&gt;网易，新浪已经不满足于传统的Web1.0所带来的广告收益。而&lt;font color="#ff0000"&gt;&lt;strong&gt;人人，开心也深刻地理解SNS本身其实是没有盈利价值的，而他们能做的只是通过SNS这个平台保证用户粘度，然后向其他的方向去发展赚钱渠道，于是开放平台应运而生&lt;/strong&gt;&lt;/font&gt;。&lt;/p&gt;  &lt;p&gt;如果人人网变成一个收费的SNS网站，你还会去么？我想不会，这样人人网必然会失去很多用户，无论是新用户还是老用户。那么既然不能从用户这来赚钱，好把！那我就从第三方厂商处赚钱，利用我的平台为你带来流量，然后我来收取分红。&lt;/p&gt;  &lt;p&gt;&lt;font color="#ff0000"&gt;&lt;strong&gt;其实这种商业模式并不新鲜，就是一个高级的广告位罢了&lt;/strong&gt;&lt;/font&gt;。只不过最初的广告是图片，然后接下来换成了会动的Flash，再到今天换成了能和用户对话的应用程序。&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;font color="#0000ff"&gt;4. 开放平台仍然是互联网&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;无论我们给开放平台起怎样一个冠冕堂皇的词，我们都必须要承认一个事实，开放平台还是一个互联网，是一个上面挂着各种各样高级广告的互联网。既然是互联网，那么有一个核心就永远都不会改变——&amp;#8220;用户至上&amp;#8221;。&lt;/p&gt;  &lt;p&gt;做互联网企业，不说这么大，做一个网站，永远需要想到的第一点都是，我们能给用户带来什么？这一点不想清楚，我们就不要动手。某产品经理的一句话对我影响很大，做一个网站，产品形态可以不断调整，但是最终目标一定不能变。其实这句话再延伸一下，&lt;font color="#ff0000"&gt;&lt;strong&gt;一个公司产品形态可以不断改变，而战略形态必须要明确，什么是战略形态，就是给用户带来的最终价值一定不能改变&lt;/strong&gt;&lt;/font&gt;。&lt;/p&gt;  &lt;p&gt;那么我们就站在用户的角度来考虑这个问题？用户为什么来我们费尽心思所搭建的开放平台？&lt;/p&gt;  &lt;p&gt;如果如之前同事所说，为了在同一个地方看到不同地方的微博，那我们不用费这么大的力气搭建开放平台，花上2人天做个内容聚合软件就可以满足用户的需求！&lt;/p&gt;  &lt;p&gt;如果是为了让用户来你这玩游戏？那更没必要了&amp;#8230;&amp;#8230;用户干吗费这么大的劲儿先登陆你的网站，然后再添加应用，然后看着一个IFrame在屏幕上闪来闪去？我直接登陆那个官网去玩游戏好不好！&lt;/p&gt;  &lt;p&gt;还有什么？还有什么？反正我是想不到了！你能想到么？我也可以找到一个取代的产品来代替开放平台！为什么这样？还是之前我说的，&lt;font color="#ff0000"&gt;&lt;strong&gt;开放平台就是高级广告位，对用户来说没有丝毫的价值&lt;/strong&gt;&lt;/font&gt;！&lt;/p&gt;  &lt;p&gt;&lt;font color="#0000ff"&gt;&lt;strong&gt;5. 开放平台健康的发展模式&lt;/strong&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;我们都不能免俗，没有公司是为了服务世界而不考虑赚钱的，那么对于当前的SNS站点来说，说更宽一点来说，对于社会化网络媒体来说，开放平台是个很好的盈利途径，甚至说，任何想赚钱的网站都会有&amp;#8220;开放平台&amp;#8221;这么个东西。但是何时开放，这才是问题的关键。&lt;/p&gt;  &lt;p&gt;我们来考虑这样几个问题：&lt;/p&gt;  &lt;p&gt;A. 第三方厂商为什么要用额外的人力来接入开放平台？是因为他们希望能够利用开放平台的影响力为他们带来流量，带来利益。为什么好多游戏厂商只做Windows下的软件，而不会去做Linux下的？道理很简单，因为Windows下的用户多，这样的投入回报比是值得的。那么道理一样，如果你的开放平台本身就没有用户，那么我们自然就没有必要去为这个开放平台来浪费我的人力资源。&lt;/p&gt;  &lt;p&gt;B. 用户为何来开放平台？这个问题又回到了上一节，不多做解释。&lt;/p&gt;  &lt;p&gt;问题到底出在哪？这么一来，开放平台没用户，没用户就没接入，没接入这个开放平台就真的只剩一个平台了。&lt;font color="#ff0000"&gt;&lt;strong&gt;这个就是我在全文想表达的一个中心，真正的开放平台，不是孤立存在的，而应该是作为一个成熟软件系统的盈利附属品而存在。&lt;/strong&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;用户为什么来开放平台？&lt;strong&gt;&lt;font color="#ff0000"&gt;因为用户不是想来开放平台，用户是想来新浪微博，是想来腾讯微博，是想来百度搜索，只是既然都来了，旁边还有应用，有游戏，我就顺带着玩了！用户不是为了广告而来到某一个网站，而是因为我喜欢这个网站的内容，而这个网站上有某个广告正好也是我感兴趣的，那么我就顺带着点一下，道理是相同的&lt;/font&gt;&lt;/strong&gt;。&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;font color="#0000ff"&gt;6. 开放平台何时开&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;一个打算长期发展的网站什么时候挂广告？建站之初么？不是。这个时候第一，广告商不会在你这打广告；第二，用户会因为满屏的广告而对网站产生方案。开放平台也是一样。&lt;/p&gt;  &lt;p&gt;既然在前一节已经说过，开放平台只是附属品，那么附属品存在的前提条件是，主要的网站已经做的很好了，用户有很好的忠诚度了，这个时候，嗯，该盈利了！当然，开放平台不会像广告一样惹人厌烦，但是一个公司的人力成本是有限的，何必不把有限的精力放在更应该去做的事儿上去呢？&lt;/p&gt;  &lt;p&gt;在这个开放成风的年代，那些呼吁开放的高层领导是不是盲目的跟风意识呢？那些跟着叫好的中层领导是不是想要通过这个开放平台来给自己的人生增加一次跳槽的光辉履历呢？&lt;/p&gt;  &lt;p&gt;在这个开放成风的年代，除了腾讯，人人等一些有着扎实用户基础的网站，其余的开放平台是不是也会随着热潮的过去而被人渐渐淡忘，成了一个从未被应用过的产品呢？&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;font color="#0000ff"&gt;7. 开放平台的未来&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;个性化，已经成为Web2.0中后期最重要的概念了，个性化推荐，个性化布局，个性化服务，把以人为本的精神发挥到了极致。&lt;/p&gt;  &lt;p&gt;那么一个成熟的开放平台也必然会走向这样的道路，对不同的内容源产生的Feed流做进一步的过滤，为用户推荐个性化的内容。看到这里也许有人会说，我们的开放平台也支持这个功能，我只能说，这是一个个性化的广告，挖掘用户的喜好，给用户推荐他可能感兴趣的广告而已，但是这仍然是个广告。&lt;/p&gt;  &lt;p&gt;再往后，第三方的应用厂商不再需要自己部署服务器，不再需要考虑性能问题，分布式问题，而都是将这些接入到开放平台上，而这一天，开放平台这个概念就显得太小了，我们还是说这是一个&amp;#8220;云操作系统&amp;#8221;好了。&lt;/p&gt; &lt;img src="http://www.cnblogs.com/kym/aggbug/2065327.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/kym/archive/2011/06/01/2065327.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/kym/archive/2011/04/26/2029093.html</id><title type="text">参数对象究竟要不要？</title><summary type="text">首先，这篇文章只是我临时写的，之前没有给文章个整体思路，所以文章可能思路会显得有些乱，连我到现在都不知道我要写到什么时候终止。这篇文章的产生是因为看过了横刀天笑的这篇文章，在这篇文章中，作者给出了一个很好的关于代码重构的步骤，以及我们要如何重构代码，提高抽象层次，但是我对其中一点，是对Martin Fowler在《重构》一书中所提出的关于参数对象的观点一直抱有质疑。先别急着反对，也别急着回复，先继续向下看。1. 先想想Python , F#之类的函数式语言让我们先想想Python , F#之类的函数式语言（让我们暂时先把Python称之为函数式语言吧），这些函数式语言，也包括C#(从4.0开始</summary><published>2011-04-26T03:18:00Z</published><updated>2011-04-26T03:18:00Z</updated><author><name>飞林沙</name><uri>http://www.cnblogs.com/kym/</uri></author><link rel="alternate" href="http://www.cnblogs.com/kym/archive/2011/04/26/2029093.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/kym/archive/2011/04/26/2029093.html"/><content type="html">&lt;p&gt;&lt;font style="background-color: #c0c0c0"&gt;首先，这篇文章只是我临时写的，之前没有给文章个整体思路，所以文章可能思路会显得有些乱，连我到现在都不知道我要写到什么时候终止。&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;font style="background-color: #c0c0c0"&gt;&lt;/font&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;font style="background-color: #c0c0c0"&gt;这篇文章的产生是因为看过了横刀天笑的&lt;a title="面向对象实践之路-提升抽象层次 &amp;#13;&amp;#10;" href="http://www.cnblogs.com/yuyijq/archive/2011/04/26/2028789.html"&gt;这篇文章&lt;/a&gt;，在这篇文章中，作者给出了一个很好的关于代码重构的步骤，以及我们要如何重构代码，提高抽象层次，但是我对其中一点，是对Martin Fowler在&lt;a href="http://book.douban.com/subject/4262627/"&gt;《重构》&lt;/a&gt;一书中所提出的关于参数对象的观点一直抱有质疑。先别急着反对，也别急着回复，先继续向下看。&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;font style="background-color: #c0c0c0"&gt;&lt;strong style="color: #3366ff"&gt;1. 先想想Python , F#之类的函数式语言&lt;/strong&gt;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;font style="background-color: #c0c0c0"&gt;让我们先想想Python , F#之类的函数式语言（让我们暂时先把Python称之为函数式语言吧），这些函数式语言，也包括C#(从4.0开始)，都有一个概念叫做Tuple，我们看看Python如何来声明一个Tuple。&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;font style="background-color: #c0c0c0"&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;span style="color: #008080"&gt;1&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000"&gt;t&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;(&lt;/span&gt;&lt;span style="color: #800000"&gt;"&lt;/span&gt;&lt;span style="color: #800000"&gt;kym&lt;/span&gt;&lt;span style="color: #800000"&gt;"&lt;/span&gt;&lt;span style="color: #000000"&gt;,&lt;/span&gt;&lt;span style="color: #000000"&gt;22&lt;/span&gt;&lt;span style="color: #000000"&gt;,&lt;/span&gt;&lt;span style="color: #800000"&gt;"&lt;/span&gt;&lt;span style="color: #800000"&gt;developer&lt;/span&gt;&lt;span style="color: #800000"&gt;"&lt;/span&gt;&lt;span style="color: #000000"&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;不知道您看到这段代码是不是感到眼熟呢？我们来写一个方法，就是横刀天笑在文章中用到的一段近似的代码：&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;span style="color: #008080"&gt;1&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000"&gt;private&amp;nbsp;bool&amp;nbsp;Validate(string&amp;nbsp;userName,int&amp;nbsp;age,string&amp;nbsp;email)&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080"&gt;2&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000"&gt;{&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080"&gt;3&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;//&lt;/span&gt;&lt;span style="color: #000000"&gt;....Validate&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080"&gt;4&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;return&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;true;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080"&gt;5&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;恩，那我们怎么来调用这个方法：&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;span style="color: #008080"&gt;1&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000"&gt;public&amp;nbsp;static&amp;nbsp;void&amp;nbsp;Main(string[]&amp;nbsp;args)&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080"&gt;2&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000"&gt;{&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080"&gt;3&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;bool&amp;nbsp;isValid&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;Validate(&lt;/span&gt;&lt;span style="color: #800000"&gt;"&lt;/span&gt;&lt;span style="color: #800000"&gt;kym&lt;/span&gt;&lt;span style="color: #800000"&gt;"&lt;/span&gt;&lt;span style="color: #000000"&gt;,&lt;/span&gt;&lt;span style="color: #000000"&gt;22&lt;/span&gt;&lt;span style="color: #000000"&gt;,&lt;/span&gt;&lt;span style="color: #800000"&gt;"&lt;/span&gt;&lt;span style="color: #800000"&gt;developer&lt;/span&gt;&lt;span style="color: #800000"&gt;"&lt;/span&gt;&lt;span style="color: #000000"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080"&gt;4&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;if&lt;/span&gt;&lt;span style="color: #000000"&gt;(isValid)&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080"&gt;5&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Console.WriteLine(&lt;/span&gt;&lt;span style="color: #800000"&gt;"&lt;/span&gt;&lt;span style="color: #800000"&gt;Success&lt;/span&gt;&lt;span style="color: #800000"&gt;"&lt;/span&gt;&lt;span style="color: #000000"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080"&gt;6&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;else&lt;/span&gt;&lt;span style="color: #000000"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080"&gt;7&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Console.WriteLine(&lt;/span&gt;&lt;span style="color: #800000"&gt;"&lt;/span&gt;&lt;span style="color: #800000"&gt;Failure&lt;/span&gt;&lt;span style="color: #800000"&gt;"&lt;/span&gt;&lt;span style="color: #000000"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080"&gt;8&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;其实方法的参数调用是不是和Tuple很类似呢？想想我们把方法改成这样的形式：&lt;/p&gt;&lt;p&gt;&lt;/font&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;span style="color: #008080"&gt;1&lt;/span&gt;&amp;nbsp;&lt;span style="color: #0000ff"&gt;def&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;Validate(userInfo):&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080"&gt;2&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;bool&amp;nbsp;nameIsValid&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;userInfo[0]&lt;/span&gt;&lt;span style="color: #000000"&gt;==&lt;/span&gt;&lt;span style="color: #800000"&gt;''&lt;/span&gt;&lt;span style="color: #000000"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080"&gt;3&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;//&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;and&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;so&amp;nbsp;on&amp;nbsp;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080"&gt;4&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;return&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;isValid&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;然后我们就可以把最之前的Tuple传入了：&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;span style="color: #008080"&gt;1&lt;/span&gt;&amp;nbsp;&lt;span style="color: #0000ff"&gt;if&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #800080"&gt;__name__&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;==&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #800000"&gt;'&lt;/span&gt;&lt;span style="color: #800000"&gt;__main__&lt;/span&gt;&lt;span style="color: #800000"&gt;'&lt;/span&gt;&lt;span style="color: #000000"&gt;:&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080"&gt;2&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;print&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;Validate(t)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;相信这个时候，也许很多人知道我想表达什么概念了。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;span style="color: #3366ff"&gt;&lt;strong&gt;2. Tuple and Class&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: Comic Sans MS"&gt;&lt;span style="font-family: Comic Sans MS"&gt;&lt;span style="font-family: Comic Sans MS"&gt;&lt;span style="font-family: Comic Sans MS"&gt;&lt;span style="font-family: Comic Sans MS"&gt;&lt;span style="font-family: Comic Sans MS"&gt;&lt;span style="font-family: Comic Sans MS"&gt;是的，其实我想表达的就是方法参数从本质上来说就一个Tuple而已，那么接下来让我们想想Tuple和Class的区别所在吧？&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: Comic Sans MS"&gt;&lt;span style="font-family: Comic Sans MS"&gt;&lt;span style="font-family: Comic Sans MS"&gt;&lt;span style="font-family: Comic Sans MS"&gt;&lt;span style="font-family: Comic Sans MS"&gt;&lt;span style="font-family: Comic Sans MS"&gt;&lt;span style="font-family: Comic Sans MS"&gt;从语法分类上来讲，Tuple我们把他叫做序列，和List被划分到同一分类下。而Class即使在那些弱面向对象（让我们暂且这么叫吧），比如Javascript来说，也充其量与Dictionary , Hashtable划分到同一类下，完全不同。&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: Comic Sans MS"&gt;&lt;span style="font-family: Comic Sans MS"&gt;&lt;span style="font-family: Comic Sans MS"&gt;&lt;span style="font-family: Comic Sans MS"&gt;&lt;span style="font-family: Comic Sans MS"&gt;&lt;span style="font-family: Comic Sans MS"&gt;&lt;span style="font-family: Comic Sans MS"&gt;一个Tuple，如果不考虑思维意义的话，我们也完全可以将之用List取代。&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: Comic Sans MS"&gt;&lt;span style="font-family: Comic Sans MS"&gt;&lt;span style="font-family: Comic Sans MS"&gt;&lt;span style="font-family: Comic Sans MS"&gt;&lt;span style="font-family: Comic Sans MS"&gt;&lt;span style="font-family: Comic Sans MS"&gt;&lt;span style="font-family: Comic Sans MS"&gt;t = ('kym',22,'developer') 和 l = ['kym',22,'developer'] 在使用上是没有什么区别的。而同样，我们将之封装成一个User对象也无可厚非：&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: Comic Sans MS"&gt;&lt;span style="font-family: Comic Sans MS"&gt;&lt;span style="font-family: Comic Sans MS"&gt;&lt;span style="font-family: Comic Sans MS"&gt;&lt;span style="font-family: Comic Sans MS"&gt;&lt;span style="font-family: Comic Sans MS"&gt;&lt;span style="font-family: Comic Sans MS"&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;span style="color: #008080"&gt;1&lt;/span&gt;&amp;nbsp;&lt;span style="color: #0000ff"&gt;class&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;User(Object):&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080"&gt;2&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;def&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #800080"&gt;__init__&lt;/span&gt;&lt;span style="color: #000000"&gt;(name,age,work):&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080"&gt;3&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.name&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;name&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080"&gt;4&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.age&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;age&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080"&gt;5&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.work&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;work&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;但是从思维意义上来说，这几者是完全不同的：&lt;/p&gt;&lt;p&gt;其实在C#之类的强类型语言来说表现的更明显，List&amp;lt;T&amp;gt;只能用来用来容纳同一类型的元素，换句话说，List&amp;lt;T&amp;gt;只能用来容纳同一种意义的元素，我们可以称之为兄弟元素。&lt;/p&gt;&lt;p&gt;而Tuple和Class的区别则取决于元素之间的关系如何，让我们想想单一职责原则(SRP), 一个类下应该只有一个能够引起他变化的原因，也就是说，这些元素高内聚的关系，我们才能够把他们塞到一起。而Tuple相对来说，则是更弱的内聚关系。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;span style="color: #3366ff"&gt;&lt;strong&gt;3. 要不要重构&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;看完了上面的内容，那就让我们想想，究竟要不要重构。或者说要不要参数对象究竟取决于什么？&lt;/p&gt;&lt;p&gt;我们首先，不要把方法参数当成方法参数，而要把他们当成一个Tuple，也就是说我们把要不要重构的问题转换成了是Tuple还是Class的问题。&lt;/p&gt;&lt;p&gt;那么Tuple还是Class取决于什么，不是取决于参数的个数，而是完全取决于参数之间的内聚关系。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;span style="color: #3366ff"&gt;&lt;strong&gt;4. 一些小引申&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;相信很多人都见过这样的代码：&lt;/p&gt;&lt;p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;span style="color: #008080"&gt;&amp;nbsp;1&lt;/span&gt;&amp;nbsp;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;void&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;Insert(&lt;/span&gt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;userName,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;password,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;bool&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;isValid)&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080"&gt;&amp;nbsp;2&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000"&gt;{&amp;nbsp;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080"&gt;&amp;nbsp;3&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt;是否需要验证&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080"&gt;&amp;nbsp;4&lt;/span&gt;&amp;nbsp;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;if&lt;/span&gt;&lt;span style="color: #000000"&gt;(isValid)&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080"&gt;&amp;nbsp;5&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&amp;nbsp;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080"&gt;&amp;nbsp;6&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;bool&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;userNameValid&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;userName&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;!=&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #800000"&gt;''&lt;/span&gt;&lt;span style="color: #000000"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080"&gt;&amp;nbsp;7&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;bool&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;passwordValid&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;IsStrongPassword(password);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080"&gt;&amp;nbsp;8&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;if&lt;/span&gt;&lt;span style="color: #000000"&gt;(userNameValid&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;passwordValid)&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080"&gt;&amp;nbsp;9&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080"&gt;10&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;&lt;span style="color: #000000"&gt;.StoreIntoDatabase(username,password);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080"&gt;11&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080"&gt;12&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080"&gt;13&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;else&lt;/span&gt;&lt;span style="color: #000000"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080"&gt;14&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080"&gt;15&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;&lt;span style="color: #000000"&gt;.StoreIntoDatabase(username,password);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080"&gt;16&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080"&gt;17&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: Comic Sans MS"&gt;&lt;span style="font-family: Comic Sans MS"&gt;&lt;span style="font-family: Comic Sans MS"&gt;&lt;span style="font-family: Comic Sans MS"&gt;&lt;span style="font-family: Comic Sans MS"&gt;&lt;span style="font-family: Comic Sans MS"&gt;&lt;span style="font-family: Comic Sans MS"&gt;&lt;span style="font-family: Comic Sans MS"&gt;&lt;span style="font-family: Comic Sans MS"&gt;&lt;span style="font-family: Comic Sans MS"&gt;&lt;span style="font-family: Comic Sans MS"&gt;&lt;span style="font-family: Comic Sans MS"&gt;&lt;span style="font-family: Comic Sans MS"&gt;&lt;span style="font-family: Comic Sans MS"&gt;&lt;span style="font-family: Comic Sans MS"&gt;先说这个参数是不是很长，如果你觉得还不够长，那么就把什么Address,Job之类通通塞进去吧！够长了吧！可是我们是不是应该把这些参数封装成一个参数对象？如果是？那么这个类要怎么写？&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: Comic Sans MS"&gt;&lt;span style="font-family: Comic Sans MS"&gt;&lt;span style="font-family: Comic Sans MS"&gt;&lt;span style="font-family: Comic Sans MS"&gt;&lt;span style="font-family: Comic Sans MS"&gt;&lt;span style="font-family: Comic Sans MS"&gt;&lt;span style="font-family: Comic Sans MS"&gt;&lt;span style="font-family: Comic Sans MS"&gt;&lt;span style="font-family: Comic Sans MS"&gt;&lt;span style="font-family: Comic Sans MS"&gt;&lt;span style="font-family: Comic Sans MS"&gt;&lt;span style="font-family: Comic Sans MS"&gt;&lt;span style="font-family: Comic Sans MS"&gt;&lt;span style="font-family: Comic Sans MS"&gt;&lt;span style="font-family: Comic Sans MS"&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;div&gt;&lt;span style="color: #008080"&gt;1&lt;/span&gt;&amp;nbsp;&lt;span style="color: #0000ff"&gt;class&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;UserArgsForValidation&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080"&gt;2&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000"&gt;{&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080"&gt;3&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;userName;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080"&gt;4&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;password;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080"&gt;5&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;bool&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;isValid;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080"&gt;6&lt;/span&gt;&amp;nbsp;&lt;span style="color: #000000"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;这样真的就面向对象了么？明显不是，可是这个问题到底出在哪？是方法重载的过分滥用。&lt;/p&gt;&lt;p&gt;如果我没有记错，Martin Fowler在书中提到过这一点，如果在方法中出现了对参数的if判断或者switch等条件选择语句，那么就让我们把这个方法拆成InsertWithValid(string userName , string password)和InsertWithoutValid(string userName, string password)这两个方法吧。&lt;/p&gt;&lt;p&gt;所以，在大多数情况下，如果一个方法带有了很多的参数，其实在一般的意义上，这些参数一定是有一个相对高的内聚性，如果没有，诸如上面的情况，就先想想是不是该用用其他的重构原则，如果没有，那么就想想是Tuple还是Class，而不是这个参数有四个，还有八个。&lt;/p&gt;&lt;p&gt;其实有个很好的区分原则，记得在设计模式的圈子有这样一个说法，说如果你设计的类名带有了这个模式的名称，比如ProductFactory, AccessAdapter,那么你就是设计模式滥用了，当然这个说法有些极端。但是我们不妨也试试把这个原则迁移到方法重构上，如果你的类名上带有了Args这样的参数，那么你也是重构的滥用了。&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/kym/aggbug/2029093.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/kym/archive/2011/04/26/2029093.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/kym/archive/2011/03/22/1990909.html</id><title type="text">Haskell&amp;mdash;&amp;mdash;模式匹配和Guard的区别</title><summary type="text">sayMe :: (Integral a) =&gt; a -&gt; String sayMe 1 = "One" sayMe 2 = "Two" sayMe 3 = "Three" sayMe 4 = "Four" sayMe x = "Others" sayMe :: (Integral a) =&gt; a -&gt; String sayMe x | x &lt; 3 = "less than 3" | x =...</summary><published>2011-03-21T17:34:00Z</published><updated>2011-03-21T17:34:00Z</updated><author><name>飞林沙</name><uri>http://www.cnblogs.com/kym/</uri></author><link rel="alternate" href="http://www.cnblogs.com/kym/archive/2011/03/22/1990909.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/kym/archive/2011/03/22/1990909.html"/><content type="html">&lt;p&gt;sayMe :: (Integral a) =&amp;gt; a -&amp;gt; String   &lt;br /&gt;sayMe 1 = &amp;quot;One&amp;quot;    &lt;br /&gt;sayMe 2 = &amp;quot;Two&amp;quot;    &lt;br /&gt;sayMe 3 = &amp;quot;Three&amp;quot;    &lt;br /&gt;sayMe 4 = &amp;quot;Four&amp;quot;    &lt;br /&gt;sayMe x = &amp;quot;Others&amp;quot;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/kym/201103/201103220133279403.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/kym/201103/201103220133308516.png" width="474" height="233" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;sayMe :: (Integral a) =&amp;gt; a -&amp;gt; String   &lt;br /&gt;sayMe x    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; | x &amp;lt; 3 = &amp;quot;less than 3&amp;quot;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; | x == 3 = &amp;quot;equals with 3&amp;quot;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; | x &amp;gt; 3 = &amp;quot;larger than 3&amp;quot;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/kym/201103/201103220133315876.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/kym/201103/201103220133344150.png" width="479" height="166" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;区别就在于一个对比的是对象，一个对比的是布尔值。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/kym/aggbug/1990909.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/kym/archive/2011/03/22/1990909.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/kym/archive/2011/03/17/1986643.html</id><title type="text">由扩展方法引申出的编程思维</title><summary type="text">1. Helper大爆炸.NET Framework为我们提供了丰富的类库，但是这并不是万能地，在大部分的时间，我们都需要为我们的项目特殊定制我们的通用类库。常常，我们都可以构造一个类，类里封装一些方法。但是对于很多时候，我们并没有办法提取出这样一个类，举一个小例子，我们在很多时候，需要把url给保存到数据库里，作为一个唯一标识，但是我们知道url所占空间很大，如果用url来建立索引的话是非常耗费...</summary><published>2011-03-16T22:45:00Z</published><updated>2011-03-16T22:45:00Z</updated><author><name>飞林沙</name><uri>http://www.cnblogs.com/kym/</uri></author><link rel="alternate" href="http://www.cnblogs.com/kym/archive/2011/03/17/1986643.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/kym/archive/2011/03/17/1986643.html"/><content type="html">&lt;p&gt;&lt;font color="#0000ff"&gt;&lt;strong&gt;1. Helper大爆炸&lt;/strong&gt;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;.NET Framework为我们提供了丰富的类库，但是这并不是万能地，在大部分的时间，我们都需要为我们的项目特殊定制我们的通用类库。&lt;/p&gt;&lt;p&gt;常常，我们都可以构造一个类，类里封装一些方法。但是对于很多时候，我们并没有办法提取出这样一个类，举一个小例子，我们在很多时候，需要把url给保存到数据库里，作为一个唯一标识，但是我们知道url所占空间很大，如果用url来建立索引的话是非常耗费空间，而且影响效率的，那么我们最常用的办法就是把url做一个Hash来作为索引的替代品。&lt;/p&gt;&lt;p&gt;这个时候，我们根本就没有办法说我们来怎么样提取一个类，然后在类里写这样一个方法，这个时候，我们通常就只能这样：&lt;/p&gt;&lt;p&gt;public static class HashHelper &lt;br /&gt;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public static string GetHashCode(string s) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //GetHashCode........ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return String.Empty &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;br /&gt;}&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;然后我们会这样使用：&lt;/p&gt;&lt;p&gt;public static void Main(string[] args) &lt;br /&gt;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; string url = "www.fandongxi.com" &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; string sql = "insert into Test values('"+HashHelper.GetHashCode(url)+"')" &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; //执行SQL &lt;br /&gt;}&lt;/p&gt;&lt;p&gt;这里，只是一个例子，并不是说我们要这个样子拼接字符串。&lt;/p&gt;&lt;p&gt;很快，肯定又会出现一个情况，说，我们要保存网页的内容，但是网页的内容直接存储到数据库里太大了，那么我们就需要对网页文本做一个Base64的编码然后压缩。//之前这里些的是错的，被很多人挑了错误.....&lt;/p&gt;&lt;p&gt;那么，我们就又得继续写：&lt;/p&gt;&lt;p&gt;public static class Base64Helper &lt;br /&gt;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public static string GetBase64Text(string text) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //Base64........ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return String.Empty &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;br /&gt;}&lt;/p&gt;&lt;p&gt;接下来我们在使用的地方就又多出来一个Base64Helper。那么过几天，还会出现SHA1Helper , MD5Helper等等各种各样的Helper。&lt;/p&gt;&lt;p&gt;渐渐地，我们会不会发现，Helper的数量已经让我们难以忍受了呢？&lt;/p&gt;&lt;p&gt;&lt;font color="#0000ff"&gt;&lt;strong&gt;2. 扩展方法的提出&lt;/strong&gt;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;font color="#000000"&gt;接下来的事情，我们都知道了，在.NET Framework 3.5中，也就是在C#3.0中，引入了扩展方法这个概念。&lt;/font&gt;&lt;/p&gt;&lt;p&gt;那就让我们扩展方法来解决上面的难题。&lt;/p&gt;&lt;p&gt;各位现在一定知道，&lt;font color="#ff0000"&gt;&lt;strong&gt;无论是做UrlHashCode，还是Base64压缩，还是SHA1加密，还是MD5加密，这些都是针对字符串，或者说是一段文本的处理&lt;/strong&gt;&lt;/font&gt;，那么很自然地，我们就需要把这些全部写入String类的扩展方法中。&lt;/p&gt;&lt;p&gt;public static class ExtensionClass &lt;br /&gt;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public static string GetHashCode(this string s) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //........ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public static string GetBase64Text(this string text) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //....... &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;br /&gt;}&lt;/p&gt;&lt;p&gt;public static void Main(string[] args) &lt;br /&gt;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; string url = "www.fandongxi.com" &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; string sql = "insert into Test values('"+url.GetHashCode()+"')" &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //执行SQL &lt;br /&gt;}&lt;/p&gt;&lt;p&gt;在这里，我不想剖析去读扩展方法的实现本质，这里我们只谈编程思维和扩展方法所带来的意义。&lt;/p&gt;&lt;p&gt;&lt;font color="#0000ff"&gt;&lt;strong&gt;3. 扩展方法让C#更加面向对象&lt;/strong&gt;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;从面向对象的角度来看，世间万物皆为对象，所有属性，所有方法都是属于某一个对象的，那么再从这个角度看开去，&lt;strong&gt;&lt;font color="#ff0000"&gt;本就不应该存在静态类，也不应该存在静态方法，所谓的静态，不过是面向对象语言对并不成熟的语法实现的一种屈从罢了。&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;我们要求Base64加密后的文本，其实是文本调用自身的一个方法，之所以我们在之前的方法中需要一个Base64Helper，而不能这样子"&lt;a href="http://www.fandongxi.com%22.replace%28%22com%22,%22cn/"&gt;http://www.fandongxi.com%22.replace(%22com%22,%22cn/&lt;/a&gt;")直接调用，只是因为.NET Framework无法预计到我们所有的业务场景，所以把只能把最通用的方法封装到已有的类库中。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;&lt;font color="#0000ff"&gt;4. 从扩展方法向外谈一些&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;让我们从扩展方法逐渐地向外围来探讨一些关于编码规范，以及一些代码优雅的问题。我们先不妨假设我们并不存在&amp;#8220;+&amp;#8221;运算符，或者说，我们禁止在程序中使用+运算符，那么也就是说，我们需要对&amp;#8220;+&amp;#8221;这个操作来做一个简单的封装，那么我们常规意义上会怎么做？&lt;/p&gt;&lt;p&gt;public int Add(int a,int b) &lt;br /&gt;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return a+b; &lt;br /&gt;}&lt;/p&gt;&lt;p&gt;public static void Main(string[] args) &lt;br /&gt;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; int result = Add(3,4) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine(result) &lt;br /&gt;}&lt;/p&gt;&lt;p&gt;让我们来看这个函数，我们顺着代码的意思向下读，加，3，4。这明显是不符合我们常规的数学思维的，如果用了扩展方法之后，我们一定是应该这样来写。&lt;/p&gt;&lt;p&gt;public static class Extension &lt;br /&gt;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public static int Add(this int a,int b) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return a+b; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;br /&gt;}&lt;/p&gt;&lt;p&gt;public static void Main(string[] args) &lt;br /&gt;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; int a = 3; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; a.Add(b) &lt;br /&gt;}&lt;/p&gt;&lt;p&gt;可是这个"."运算符看上去还是那么有点别扭&amp;#8230;..没办法，至少这样读上去让我们的代码顺畅了很多不是么？像写文章，说话一样写代码一直是我们程序员追求的最高境界，就像这样的代码总是好的。&lt;/p&gt;&lt;p&gt;Good：people.eat(food)&lt;/p&gt;&lt;p&gt;而不是Bad：Eat(people,food)&lt;/p&gt;&lt;p&gt;对把！&lt;/p&gt;&lt;p&gt;&lt;strong&gt;&lt;font color="#0000ff"&gt;5. 前缀，中缀和后缀表达式&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;说到这，就不得不谈谈前缀，中缀和后缀表达式了。&lt;/p&gt;&lt;p&gt;学过数据结构的朋友们，一定都记得在数据结构中，有一道经典的习题，就是利用&amp;#8220;栈&amp;#8221;来实现前缀，中缀和后缀表达式的转换。在考试题中也经常会出现这样的习题。那现在让我们来复习一下，什么是前缀，中缀和后缀表达式。&lt;/p&gt;&lt;blockquote style='border:2px solid #EFEFEF;color:#333333;padding:5px 10px;'&gt;&lt;p&gt;前缀表达式就是不含括号的算术表达式，而且它是将运算符写在前面，操作数写在后面的表达式，也称为&amp;#8220;波兰式&amp;#8221;。&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;大名鼎鼎的Lisp就是前缀表达式的典型，让我们看一个最简单的小例子，还是那个经典的斐波那契数列：&lt;/p&gt;&lt;p&gt;(define (fib n) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; (fib-iter 1 0 n))&lt;/p&gt;&lt;p&gt;(defile (fib-iter a b count) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; (if (= count 0) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; b &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (fib-iter (+ a b) a (- count 1))))&lt;/p&gt;&lt;p&gt;每次写Lisp的时候，都会被密密麻麻的括号所吓到，可是真的没什么太好的解决方案呢！&lt;/p&gt;&lt;p&gt;中缀表达式就很简单了，和我们常规所涉及到的代码是一样的，后缀也是一个道理，在此就不再一一赘述。鉴于后缀的应用不是很大，在此我们也只谈谈前缀和中缀的意义。&lt;/p&gt;&lt;p&gt;那么我们想想，为什么Lisp要采用这么蹩脚的前缀表达式语法呢？&lt;/p&gt;&lt;p&gt;记得在大二第一次学习C语言的时候，老师让我们写一个简单的计算器，当时每个同学都写出了+，-，*，/的操作，但是在当时大多数的我们都没有办法写出更为常用的混合运算，以及（）的操作，当时只有班上某鹤立鸡群的哥们写出了让我们当时完全无法看懂的代码。再直到大三学习数据结构，再反过来想他当时的代码，才恍然大悟。&lt;/p&gt;&lt;p&gt;废话说了一堆，那么其实前缀表达式最大的意义就是他更贴近计算机的思维，他只需要两种操作就能完成运算，就是入栈和出栈。让我们来看一个简单的小例子&lt;/p&gt;&lt;p&gt;3+(1-4)，首先这是一个中缀表达式，把他转换为前缀表达式就是+3 &amp;#8211; 1 4，计算机会从右向左来扫描这个表达式，4入栈，1入栈，然后遇到 - ，1和4出栈，并且完成运算，(-3)入栈，3进栈，+入栈，(-3)和3出栈，完成运算。&lt;/p&gt;&lt;p&gt;也就是说，其实在计算机完成我们所编写的数学操作时，其实往往都是把我们的中缀表达式首先转换为前缀表达式，然后完成计算，而Lisp采用前缀表达式，则是省去了这一个步骤，从而提高解释器的效率。&lt;/p&gt;&lt;p&gt;那我们就来总结下前缀和中缀表达式的意义。&lt;/p&gt;&lt;p&gt;&lt;font color="#ff0000"&gt;&lt;strong&gt;前缀表达式更加贴近计算机思维，方便计算。而中缀表达式更加贴近数学思维，容易被我们所理解。&lt;/strong&gt;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;那回顾下，我们之前写Add的代码，如果说我们去掉.运算符，而且方法不加括号，是否采用扩展方法，把C#的语法和Lisp的语法相结合，其实就成了这样的形式。&lt;/p&gt;&lt;p&gt;public int Add(int a,int b) &lt;br /&gt;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return a+b; &lt;br /&gt;}&lt;/p&gt;&lt;p&gt;public static void Main(string[] args) &lt;br /&gt;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; (set! result (Add a b)) &lt;br /&gt;}&lt;/p&gt;&lt;p&gt;public static class Extension &lt;br /&gt;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public static int Add(this int a,int b) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return a+b; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;br /&gt;}&lt;/p&gt;&lt;p&gt;public static void Main(string[] args) &lt;br /&gt;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; (set! result (a Add b)) &lt;br /&gt;}&lt;/p&gt;&lt;p&gt;还是后者更贴近我们的自然思维一些。&lt;/p&gt;&lt;p&gt;.NET Framework很强大，给我们提供了扩展方法这个概念，那么如果没有了扩展方法，其他语言给出了怎么样的解决方案呢？&lt;/p&gt;&lt;p&gt;那让我们来看看Haskell给出的方案。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;&lt;font color="#0000ff"&gt;5. 看看Haskell的方法&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Haskell是一门函数式的语言，在FP大行其道的今天，Haskell这门久居深宫的语言也渐渐地浮出了水面。&lt;/p&gt;&lt;p&gt;废话不多说，我们只来看看Haskell是如何在没有扩展方法的情况下来解决语法和自然思维不相协调的问题的。&lt;/p&gt;&lt;p&gt;让我们先来编写一个简单的Haskell函数。&lt;/p&gt;&lt;p&gt;add x y = x + y&lt;/p&gt;&lt;p&gt;代码很简单，没什么值得多说，让我们来看看Haskell怎么调用。&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/kym/201103/20110317064511865.png"&gt;&lt;img style="background-image: none; border-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px;" title="image" alt="image" src="http://images.cnblogs.com/cnblogs_com/kym/201103/201103170645141647.png" height="241" width="644" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;这是我们传统的调用方式，可是Haskell为了更贴近我们的自然思维，为参数个数数量为2的方法提供了这样一个便捷的调用：&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/kym/201103/201103170645152072.png"&gt;&lt;img style="background-image: none; border-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px;" title="image" alt="image" src="http://images.cnblogs.com/cnblogs_com/kym/201103/201103170645176857.png" height="169" width="654" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;这就是Haskell为我们提供的&amp;#8220;中缀表达式&amp;#8221;的解决方案。&lt;/p&gt;&lt;p&gt;扩展方法很好，但是当我们的语言中没有扩展方法的时候，Haskell给我们提供了一个优秀的典范。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;&lt;font color="#0000ff"&gt;6. 语言和类库&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;说到这，我就想顺便谈谈关于语言扩展和类库扩展的问题。&lt;/p&gt;&lt;p&gt;在&lt;a href="http://book.douban.com/subject/2258023/" target="_blank"&gt;《Masterminds of Programmming》&lt;/a&gt;一书中，Python语言之父Guido在接受采访时，谈到PEP（Python增强处理）时，顺便说到了关于在编写编程语言时，如何来根据用户的意见来处理语言实现的问题。&lt;/p&gt;&lt;p&gt;他谈到：&lt;/p&gt;&lt;blockquote style='border:2px solid #EFEFEF;color:#333333;padding:5px 10px;'&gt;&lt;p&gt;如果某个用户提出一个新特性，它几乎不会成功。因为用户对实现没有全面的理解，他几乎不可能提出一个合理的新特性。&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;那么在我看来什么是用户？用户就是使用这门语言来完成工作任务的人，他们往往需要的都是增加一个新功能，换句话说，他们需要的仅仅是一个方法而已。&lt;/p&gt;&lt;p&gt;那么什么是增加语言特性，什么是增加类库方法，Guido也给出了比较合理的解释。&lt;/p&gt;&lt;blockquote style='border:2px solid #EFEFEF;color:#333333;padding:5px 10px;'&gt;&lt;p&gt;如果某个特性对于Web来说确实很棒，那么，对于加到语言中来说，就未必是优秀的特性了。如果它确实利于编写更短的函数，或者是有利于编写可维护更强的类，把它添加到语言中可能就是一件好事。&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;其实Guido的意思很简单，是否增加到语言中，关于在于这个特性是否是领域相关的，如果是领域相关的，也许它需要做的仅仅是扩展类库，无论是增加Python的类库，还是用C去扩展Python API，总之无需对语言做出改变。&lt;/p&gt;&lt;p&gt;那么对于C#来说，什么是类库的修改，什么是语言的修改，在我看来，每一个版本的修改都一定有着类库的修改，但是如果说到语言的修改，应该是仅仅当MSIL发生变动的时候，我们才可以说语言发生了修改。//仔细想了一下，这个观点有问题....但是我没找到更合适的语言来做比喻。也许应该说，只有当语法的编译规则发生改变的时候，我们才可以说语言发生了修改。&lt;/p&gt;&lt;p&gt;Python也是一样，增加了方法充其量是类库的修改，而仅仅是语言的解释过程都发生了修改才可以算得上是语言层面的修改，例如从Python 2.x到Python3.x的大版本变动。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;&lt;font color="#0000ff"&gt;7. 总结&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;在本文中，主要是从扩展方法说起，谈到我们该怎么样更好的编写更贴近自然语言的程序。&lt;/p&gt;&lt;p&gt;然后再到一些没有扩展方法语言给出的折衷实现。而对于Python，C等其他语言，我尚且没有找到合适的方法来解决问题。&lt;/p&gt;&lt;p&gt;如果各位有好的办法，尤其是对于Python，毕竟这是我的工作，希望各位补充给出解决方法。&lt;/p&gt;&lt;p&gt;谢谢。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/kym/aggbug/1986643.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/kym/archive/2011/03/17/1986643.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry></feed>
