<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>刘未鹏 &#124; Mind Hacks &#187; 编程</title>
	<atom:link href="http://mindhacks.cn/tags/%e7%bc%96%e7%a8%8b/feed/" rel="self" type="application/rss+xml" />
	<link>http://mindhacks.cn</link>
	<description>思维改变生活</description>
	<lastBuildDate>Sun, 21 Mar 2010 08:00:41 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>编程的首要原则(s)是什么？</title>
		<link>http://mindhacks.cn/2009/03/09/first-principles-of-programming/</link>
		<comments>http://mindhacks.cn/2009/03/09/first-principles-of-programming/#comments</comments>
		<pubDate>Mon, 09 Mar 2009 07:12:00 +0000</pubDate>
		<dc:creator>刘未鹏</dc:creator>
				<category><![CDATA[编程]]></category>

		<guid isPermaLink="false">http://mindhacks.cn/2009/03/09/first-principles-of-programming/</guid>
		<description><![CDATA[半年前，JoelOnSoftware和CodingHorror合搞的stackoverflow.com刚上线不久，我兴冲冲地跑过去扔了一个问题：

你们认为编程的首要原则是什么？ 

作为我的学习原则的一个实践： 

8. 学习一项知识，必须问自己三个重要问题：1. 它的本质是什么。2. 它的第一原则是什么。3. 它的知识结构是怎样的。

5个月过去了，这个问题到现在还有人回复，我得到了一大堆有意思的答案，忍不住翻译过来与大家分享：]]></description>
			<content:encoded><![CDATA[<p>半年前，JoelOnSoftware和CodingHorror合搞的stackoverflow.com刚上线不久，我兴冲冲地跑过去扔了一个问题：</p>
<p><strong>你们认为编程的首要原则是什么？ </strong></p>
<p>作为我的<a href="http://mindhacks.cn/2008/07/08/learning-habits-part1/">学习原则</a>的一个实践：<a href="http://mindhacks.cn/wp-content/uploads/2009/03/important.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; margin-left: 0px; border-left-width: 0px; margin-right: 0px" title="important" border="0" alt="important" align="right" src="http://mindhacks.cn/wp-content/uploads/2009/03/important-thumb.png" width="160" height="183" /></a> </p>
<blockquote><p>8. 学习一项知识，必须问自己三个重要问题：1. 它的本质是什么。2. 它的第一原则是什么。3. 它的知识结构是怎样的。</p>
</blockquote>
<p>5个月过去了，这个问题到现在还有人回复，我得到了一大堆有意思的答案，忍不住翻译过来与大家分享：</p>
<p>1. 获得<strong>最多认同的答案</strong>：</p>
<blockquote><p><strong>KISS &#8211; Keep It Simple Stupid </strong></p>
<p><strong>DRY &#8211; Don&#8217;t Repeat Yourself </strong></p>
</blockquote>
<p>一点不感到意外吧？ </p>
<p>注：DRY原则倒是比较好理解和实践的。但KISS原则则是看上去直白，其实实践起来不那么容易的一个原则，因为simple和stupid的定义并不是每个人、在每个场景下都是一致且明显的，一个人的simple可能是另一个人的stupid，一个人的stupid可能是另一个人的unnecessary。一旦一个标准取决于具体场景，事情就不那么简单了。所以我们经常要说“<a href="http://c2.com/cgi/wiki?ItDepends">It depends</a>”。 </p>
<p>2. 获得<strong>第二认同的答案</strong>： </p>
<blockquote><p><strong>写代码时时刻设想你就是将来要来维护这坨代码的人。 </strong></p>
</blockquote>
<p>在这个答案后面有人添加到：</p>
<blockquote><p>最好设想你的代码会被一个挥着斧头的精神病来维护。</p>
</blockquote>
<p>有人接着又YY道：</p>
<blockquote><p>而且这个挥着斧头的精神病还知道你住在哪儿。<sup>1</sup></p>
</blockquote>
<p>注：其实这个原则在设计API时也有用：</p>
<blockquote><p><strong>写API时时刻设想你就是要去使用这坨API的人。</strong></p>
</blockquote>
<p>3. <strong>一些众所不一定周知的答案</strong>：</p>
<blockquote><p><strong>先弄清你的问题是什么！</strong></p>
</blockquote>
<p><a href="http://www.douban.com/subject/1135754/">弄清问题</a>永远是问题解决过程中的第一步和最重要的一步。</p>
<blockquote><p><strong>代码只是工具，不是手段。</strong></p>
</blockquote>
<p>不知道怎么最好地解决你手头的问题（注：需求、架构、算法，技术选型，etc..），写上一万坨代码也是浪费比特。</p>
<blockquote><p><strong>知道什么时候不该编码</strong>。</p>
</blockquote>
<p>（类似条目：YAGNI——“你并不需要编写这坨代码！”，针对你的需求编码，“写你所需”，别做“聪明事”，为一个不确定的未来编码。同时也注意模块化设计，以便能在未来新增需求时无痛扩充系统）</p>
<blockquote><p><strong>永远不要假定你已经了解一切了！</strong></p>
</blockquote>
<blockquote><p><strong>不作没有证据的推论。</strong></p>
</blockquote>
<blockquote><p><strong>想清楚了再编写</strong>。类似条目：<strong>如果方案在你脑子里面或者纸上不能工作，写成代码还是不能工作。</strong></p>
</blockquote>
<p>4. 一些众所很可能周知的答案：</p>
<blockquote><p>越懒越好。</p>
<p>过早优化是一切罪恶的根源。</p>
<p>不要重新发明轮子。</p>
<p>测试通过前说什么“它可以工作”都是纯扯淡。</p>
<p>了解你的工具。</p>
<p>一切以用户需求为导向。</p>
<p>利用分治、抽象，解开子问题之间的耦合。</p>
</blockquote>
<p>5. <strong>最幽默的答案</strong>：</p>
<blockquote><p><strong>咖啡进，代码出</strong>。（Coffee in, Code out）<sup>2</sup></p>
</blockquote>
<p>最后，整个问题的 thread 在<a href="http://stackoverflow.com/questions/159176">这里</a>。</p>
Footnotes:<ol class="footnotes"><li id="footnote_0_180" class="footnote"> 事实上后面有人指出这是 Martin Golding 的一句名言 </li><li id="footnote_1_180" class="footnote"> 参见 <a href="http://en.wikipedia.org/wiki/Garbage_in,_garbage_out">Garbage in, Garbage out</a>. </li></ol><h3  class="related_post_title">你可能也会喜欢以下文章</h3><ul class="related_post"><li><a href="http://mindhacks.cn/2008/10/29/methodology-for-programmers/" title="方法论、方法论&mdash;&mdash;程序员的阿喀琉斯之踵">方法论、方法论&mdash;&mdash;程序员的阿喀琉斯之踵</a> (10)</li><li><a href="http://mindhacks.cn/2008/03/03/failing-to-see-the-big-picture/" title="Failing To See the Big Picture &#8211; Mistakes we make when learning programming">Failing To See the Big Picture &#8211; Mistakes we make when learning programming</a> (1)</li></ul><hr />
<h3>订阅 Mind Hacks</h3>
<a title="用Google Reader订阅" href="http://fusion.google.com/add?feedurl=http://mindhacks.cn/feed/"><img src="http://mindhacks.cn/wp-content/uploads/2009/02/feed_google.gif" style="border:0" alt="订阅到 | Google" /></a> 
<a title="用鲜果订阅" href="http://www.xianguo.com/subscribe.php?url=http://mindhacks.cn/feed/"><img src="http://mindhacks.cn/wp-content/uploads/2009/02/feed_xianguo.gif" style="border:0" alt="订阅到 | 鲜果" /></a>
<br/> 
<a title="用抓虾订阅" href="http://www.zhuaxia.com/add_channel.php?url=http://mindhacks.cn/feed/"><img src="http://mindhacks.cn/wp-content/uploads/2009/02/feed_zhuaxia.gif" style="border:0" alt="订阅到 | 抓虾" /></a> 
<a title="用有道订阅" href="http://reader.youdao.com/b.do?keyfrom=mindhacks&url=http://mindhacks.cn/feed/"><img src="http://mindhacks.cn/wp-content/uploads/2009/02/feed_yodao1.gif" style="border:0" alt="订阅到 | 有道" /></a> 
<hr />
<h3>我是你的信息过滤器</h3>
想了解作者最近在关注什么，欢迎 Follow <a href="https://twitter.com/pongba">pongba@Twitter</a>
<br/>
程序员朋友请到作者发起的 <a href="https://groups.google.com/group/pongba">TopLanguage</a> (<a href="http://mindhacks.cn/about-toplanguage/">about</a>) 社群逛逛，定有收获 :)
<br/>
想了解作者在阅读哪些书，请到 <a href="http://www.douban.com/people/pongba/">pongba@豆瓣</a>，或者直接访问以下四个豆列：<a href="http://www.douban.com/doulist/46003/">[只读经典]思维改变生活</a> | <a href="http://www.douban.com/doulist/127649/">[只读经典]思考的技术与艺术</a> | <a href="http://www.douban.com/doulist/197706/">决策与判断</a> | <a href="http://www.douban.com/doulist/176513/">机器学习与人工智能书籍资源导引</a> 。
<br/>
想了解作者平时在互联网上的阅读，请订阅 <a href="http://delicious.com/pongba/shared-reading">pongba-shared-reading@delicious</a> 。
<hr />
<p><small>
本文由 刘未鹏 发布在 <a href="http://mindhacks.cn">刘未鹏 | Mind Hacks</a>, 2009. | <a href="http://mindhacks.cn/2009/03/09/first-principles-of-programming/#commenting">32 条评论</a> | 标签: <a href="http://mindhacks.cn/tags/%e7%bc%96%e7%a8%8b/" rel="tag">编程</a>
<br/>
转载请注明作者，出处，以及<a href="http://mindhacks.cn/2009/03/09/first-principles-of-programming/">原始超链接</a>: http://mindhacks.cn/2009/03/09/first-principles-of-programming/
</small></p>]]></content:encoded>
			<wfw:commentRss>http://mindhacks.cn/2009/03/09/first-principles-of-programming/feed/</wfw:commentRss>
		<slash:comments>32</slash:comments>
		</item>
		<item>
		<title>方法论、方法论&#8212;&#8212;程序员的阿喀琉斯之踵</title>
		<link>http://mindhacks.cn/2008/10/29/methodology-for-programmers/</link>
		<comments>http://mindhacks.cn/2008/10/29/methodology-for-programmers/#comments</comments>
		<pubDate>Wed, 29 Oct 2008 13:09:00 +0000</pubDate>
		<dc:creator>刘未鹏</dc:creator>
				<category><![CDATA[学习方法]]></category>
		<category><![CDATA[思维改变生活]]></category>
		<category><![CDATA[编程]]></category>

		<guid isPermaLink="false">http://mindhacks.cn/2008/10/29/methodology-for-programmers/</guid>
		<description><![CDATA[以前，我认为一个事物对我没有直接用途的时候就不会去理会它，心理学上说我们都戴着自己的认知偏见的有色眼镜去有选择性地看待这个世界，纷繁的信息经过我们的认知图式过滤之后便成为少量有序的事件，所以我们都在有强烈选择性地关注一些事物和忽视另一些事物，然而，这样可能会导致丧失一些很有价值的信息，而总是将知识面停留在自己的小世界中——当然这倒也不是说看到什么都要凑上去学一学。如何在这两者中间取得折中，我觉得一个好的办法是先简略地想一下这是个什么东东，他的本质是什么，出现是为了满足什么需求，等等比较“高层”的问题（即“What”和“Why”而不是“How”），这些问题应该是可以通过简单的调研和思考得出结论的，至于背后的技术细节，如果你打算入行，就可以去学，如果不打算的话则可以免了，至少前面的思考和简单的调研能够一定程度上保证当有价值的信息或机会摆在你面前的时候你不会把眼睛蒙上走开，并且多做做这类思考对于思维的广度也很有价值。最近我开始认为，最佳的学习方法就是先广度优先遍历（先弄清What和Why），然后择最合适的分支深入（How）（算法牛人DD同学在TopLang上的一个帖子里面也提到类似的想法，刚进大学就能够如此清晰地看清前方道路的走法，我对DD很佩服）。]]></description>
			<content:encoded><![CDATA[<p>以前，我认为一个事物对我没有直接用途的时候就不会去理会它，心理学上说我们都戴着自己的<a href="http://en.wikipedia.org/wiki/Cognitive_bias">认知偏见</a>的有色眼镜去<a href="http://en.wikipedia.org/wiki/Selective_attention">有选择性地看待</a>这个世界，纷繁的信息经过我们的<a href="http://en.wikipedia.org/wiki/Schema_(psychology)">认知图式</a>过滤之后便成为少量有序的事件，所以我们都在有强烈选择性地关注一些事物和忽视另一些事物，然而，这样可能会导致丧失一些很有价值的信息，而总是将知识面停留在自己的小世界中——当然这倒也不是说看到什么都要凑上去学一学。如何在这两者中间取得折中，我觉得一个好的办法是先简略地想一下这是个什么东东，他的本质是什么，出现是为了满足什么需求，等等比较“高层”的问题（即“What”和“Why”而不是“How”），这些问题应该是可以通过简单的调研和思考得出结论的，至于背后的技术细节，如果你打算入行，就可以去学，如果不打算的话则可以免了，至少前面的思考和简单的调研能够一定程度上保证当有价值的信息或机会摆在你面前的时候你不会把眼睛蒙上走开，并且多做做这类思考对于思维的广度也很有价值。最近我开始认为，最佳的学习方法就是先广度优先遍历（先弄清What和Why），然后择最合适的分支深入（How）（算法牛人<a href="http://cuitianyi.com/blog/">DD同学</a>在TopLang上的一个帖子里面也提到<a href="https://groups.google.com/group/pongba/browse_frm/thread/19feb2efbeef7d5a/">类似的想法</a>，刚进大学就能够如此清晰地看清前方道路的走法，我对DD很佩服）。 </p>
<p>方法论看似是个很抽象的东西，并且的确有一些方法论是抽象到 over-generalized （泛化过度）的地步，然而说实话<strong>在实践当中我总是发现（正确的）方法论是再现实不过的东西</strong>，比如一个大家都明白的道理是：如果方向走错了，那么做的功就基本全白费了（还有比如“如果方法对头，就能事半功倍，反之可能多走很多弯路”）——然而现实中有多少人能够真正实践这个方法呢？绝大多数人都是只顾解决眼前问题，抓了这头丢了那头，更多人是不知道问题是什么，只管把头脑中能联想到的一个以前类似情况下的类似方案套用上来。以前我总是觉得一个公司里面，CEO/CTO 这样的角色是基本摆设，但我现在不这样想了。在 How 层面把事情做好，做成一个精钻的程序员，那顶多就是能把钳子使好，这样的事情很多人都能做到，熟能生巧嘛。换句话说<strong>程序员基本上是去解决一个定义好的问题，去实施一个定义好的方案</strong>。然而决策问题就不一样了，决策问题是需要去定义问题是什么，以及权衡最佳方案是什么，不管是决策技术架构还是决策商业策略，都是非常复杂的思维过程，需要<strong>综合和权衡大量的信息</strong>，这种能力<strong>就不是简单楞着头搞下去能练出来的了，很多时候需要抬起头来看，免得只见树木不见森林</strong>。（以上也是为什么我在讨论组里面一篇帖子（<a href="https://groups.google.com/group/pongba/browse_frm/thread/f70e1e9cbbd0ff74">什么是算法？为什么学习算法？以及学到什么程度？</a>）中提到我觉得<a href="https://groups.google.com/group/pongba/msg/2638bc0a319bce32">学数学学到精通未必就会思考日常决策问题的原因</a>——数学几乎总是去解决一个定义好的问题，用的也都是定义好的严密的逻辑推导。然而现实中的问题是一个复杂系统，诸多变量互相影响，如何权衡最佳方案实际上是一个复杂的统筹规划。更重要的是，你往往甚至都不知道问题是什么，能够从纷繁的信息中抽象出问题，是一种极大的能力。这里推荐<a href="http://www.douban.com/subject/1135754/"><strong>《你的灯亮着吗？》</strong></a><strong>和</strong><a href="http://www.douban.com/subject/1001737/"><strong>《失败的逻辑》</strong></a>） </p>
<p>当然，我自己还没能到这个层面，尚需要不断实践和总结，所以只能稍微的谈一点感受，再往下扯只怕就会流于空泛了。这一点上我还是举一个程序员们喜闻乐见的例子吧，在程序员眼睛里面，做一个项目，也许首先想到的是用什么语言，什么框架，什么库，在这个方向上那就是什么看上去牛B用什么，恨不能都用 haskell、lisp 来写才爽，用 Java？那多没意思啊，Java 那坨弱智语法我小学的弟弟都能掌握，也没啥牛B的语言特性，忒没成就感（只可惜<strong>真正判别弱智与否的并非用什么语言技术，而是做出什么产品满足什么需求</strong>）。这就是属于只考虑单个孤立因素的简单（或者说 Naive 的）决策，这个因素就是——只要让我自己感觉爽——只可惜<strong>并不是让自己感觉爽的做法就是真正解决问题的做法</strong>，始终要弄清问题是什么，在后者意义上，一些对于技术型程序员往往没有吸引力的话题其实有着极其重大的价值——比如什么时候设计，什么时候重构，什么时候集成，再往上一层其实这些又都是次级问题，首要的问题还是这个产品满足什么需求，有什么市场（即这件事情值不值得做），有一句话想必很多人常听说，<strong>如果不知道要做什么，套上十二层架构也无济于事</strong>，方法永远不是因，而是果（我在以前的另一篇文章“<a href="http://blog.csdn.net/pongba/archive/2008/03/03/2143245.aspx">Failing to see the Big Picture – Mistakes we make when learning programming</a>”中也阐述了类似的观点）。</p>
<p>再举个例子，如果我想给我的网站做一个 feature ，我认为这个 feature 技术上很牛很强大，而且刚好有机会使用一下我最近修炼的某某 framework 和某某语言，而且这玩意很有挑战性，还不是一般人能够做得了的，综合以上三点，我立时觉得心痒难耐摩拳擦掌。然而实际上这个问题应该怎样分析呢？首先，考虑到以上三点，这将会是一个投入相当大的项目，那么其收益就必须要对得起这个投入，技术上很牛不代表商业上就牛，再牛再难做的 feature 如果不能带来商业价值那就是负收益。总而言之，</p>
<p><strong>1. </strong><strong>一件事情</strong><em><b>仅仅</b></em><strong>让你感觉挺牛不代表这件事情就是值得做的； </strong><b>     <br /><strong>2. </strong><strong>一件事情</strong><em>仅仅</em><strong>让你感到很有兴趣并不代表这件事情就是值得做的。</strong></b></p>
<p>这两句话和我们日常的认识并不冲突，其实<strong>我们几乎总可以找到既有价值、又有趣、又有足够挑战性的工作</strong>。举个例子，本科数学学得精纯无比的同学有没有偶尔也会觉得盲目呢？做这些题目到底有什么实际用途呢？这就像是你总是在磨一把刀，磨得闪闪发光锋利无比，你可以向别人炫耀自己的刀很牛B，但是刀是为了冲锋陷阵血溅五步的，你也不想让它折戟沉沙吧，不管是将数学用在数学物理上还是用在人工智能、机器学习、密码学、通信上，都是既让人有成就感，同时又有意义和价值的事情。对我们程序员来说，你把一门语言玩得很精通，不仅知晓它所有的语法细节，陷阱和缺陷，还了解它的底层实现模型是如何。你觉得很牛很有成就感——的确，我们都会为一件自己做到了别人做不到的事情而感到自豪，然而反问一句，除了情绪价值之外，这样的事情在本身的价值上有没有你感觉到的那么牛呢？<strong>如果你只是在削铅笔，那么何必磨一把倚天屠龙剑来？反之，如果你做的是一个本身功能很牛很创新很有价值的软件，那么语言技术其实完全是次要的</strong>，并不是看上去越眩越好，关键是选择各个方面综合考虑起来最合适的工具即可，瑞士军刀也许很丑，但对于丛林冒险很实用就行。<strong>拿着一把屠龙宝刀去野外生存，同样也不靠谱。</strong></p>
<p>编程语言是为了实现软件的，软件是为了服务于人的。诚然，了解一门语言的方方面面能够使你更有效地使用它，然而另一方面，如果结果发现这门语言并不何时来解决你手头的问题呢？受到投入的<a href="http://en.wikipedia.org/wiki/Sunk_cost">沉没成本</a>的影响你一定觉得很不甘心吧？同理，由于你对一门工具投入了很多的精力，<strong>这门工具已经和你的情感挂上了钩，于是如果让你来决策用什么工具来完成一个任务的时候，你几乎会毫无疑问地想到使用你最熟悉而喜爱的那个</strong>，这就是“当你手头拿的是一个锤子，任何东西看上去都像钉子”这句话的一个解释。<strong>原先的问题是使用一门技术使得能够性价比最高地实现要完成地产品，然而到你那里问题就悄悄地变成了“使用一门技术让我感觉最爽”，问题的所有其他需要综合考虑的因素都被选择性忽略掉了</strong>，所以<strong>如果你是一个语言技术 fans ，那么几乎毫无疑问你会成为一个糟糕的决策者</strong>。最近，在学习和研究的方法论上我已经听到不止一个人（参见《失败的逻辑》和<a href="http://www.bullog.cn/blogs/siyi/archives/194207.aspx">这里</a>——一位诺贝尔奖得主的忠告（引言如下））忠告我们，不要为了工具而工具，忘记了工具的目的是什么。</p>
<blockquote><p>…我们前面提过的显微摄影专家，擅长于拍矽藻的照片，动物学家着迷于昆虫贝壳跟有美丽羽毛的鸟类。我们的爱书狂最高兴的事情，就是读最新书和专论，他认为这些东西很重要，而且很能够刺激头脑，可是别人没办法，找到另外一本同样的书。我们博学的模范，经过这种策略，让他的朋友惊奇，让他的朋友佩服…</p>
</blockquote>
<p>…没有效率的科学家中，有一小类就是所谓的崇拜研究仪器的狂人，他们对金属的闪烁非常着迷，就像是夜鹰对它在镜里的反影着迷一样。他们非常仔细照顾所崇拜的东西，把仪器拭擦得雪亮，可以当镜子使用，而且把它摆饰在最崇高的地方，就好像在教堂里面的圣坛…</p>
<p><a href="http://www.codinghorror.com/blog/">CodingHorror</a> 的作者最近在博客里面跟着 <a href="http://steve-yegge.blogspot.com/">Steve Yegge</a> 同学宣称，如果有一件事情是他想教给程序员同学们的，那就是 Marketing 。无独有偶，有一次吃饭的时候<a href="http://wesleybao.spaces.live.com/">鲍志云</a>同学也提到： Marketing Sense 是很重要的。其实也就是不要总想着写牛代码，用牛语言技术，不要落入为技术而技术的怪圈，而是首先想明白做的事情有什么价值，先弄清做什么，为什么做，再去想怎么做，这样后面的功夫才花的有价值。</p>
<blockquote><p>You won&#8217;t&#8211; you <i>cannot</i>&#8211; become a better programmer through sheer force of programming alone. You can only complement and enhance your existing programming skills by branching out. Learn about your users. Learn about the industry. Learn about your business. </p>
</blockquote>
<p>当然，最后必须声明的是，不要矫枉过正，误会以上的观点，以上观点<strong>并不是说学生时代做的基本功是不需要的</strong>，一些非常基本的功夫（如计算机体系结构、数据结构和算法、两个主要流派（命令式和声明式）的编程语言都使用了哪些主要的编程范式、对主流语言的优缺点和适用场合的了解等等）是有必要掌握牢靠的，因为一方面我们并不是都能去做判断与决策，码农总是一个可靠的职业。另一方面对技术大方向的把握也是决策的基础知识，只是不要掉进无尽的技术漩涡，成为技术追星族。此外也许还有一个小小的好处就是如果被老板逼着用一门不熟悉的语言时不会很不痛快，因为<strong>真正重要的事情是你完成的产品，而不是用的语言</strong>。</p>
<p><strong>一个有趣的附录</strong></p>
<p>我们的思维有很多很多的弱点，前文讲的其实就是这样的弱点，更多更系统一点总结可以看下<a href="https://groups.google.com/group/pongba/browse_frm/thread/3a88afe2d0fcbcdc/">这里</a>，和<a href="http://www.douban.com/doulist/127649/">这里</a>。我一向认为，正确的思维方式，是一切高效学习的基础。比如参见如下2个例子，错误的思维方式得到的结论有大得多的可能性是谬误。</p>
<p>[1] 人总喜欢沿袭以往习得的经验，并通过类比来进行外推。我第一次在一个地铁终点站坐地铁的时候，看着从远方开来的地铁，我心生疑惑——“这车每节车厢都这么长，待会怎么调头呢（我心说没看到铁轨终点有一个大大的供调头的U形弯啊）？”，当车开始开的时候我终于意识到原来车是可以往两头方向开的。 </p>
<p>[2] 人喜欢从关联当中寻找因果，有一次我我老婆去银行取款，到了 ATM 室的自动门口，我开玩笑地拿着手头的饭卡去刷了一下，然后——门居然开了。我顿时来了劲，立即得出一个结论：这个刷卡装置不安全，至少不是能够专门识别银联的卡的。我甚至飞快地泛化出了一个更具一般性的理论来解释这个现象：即可能所有带有磁性的卡都可以用来开门。老婆看我得意洋洋，就泼过来一盘冷水：不一定是你的卡刷开的啊，你不刷卡试试看。我不信，说怎么可能呢，心想我刷卡，门就开了，还有比这更明显的因果关系嘛。但出乎我意料的是，我走出门，这次没刷卡，门也开了——原来是感应门——原先这个 ATM 室的确是刷卡门，但后来改成了感应门，刷卡的那个装置只不过没拆掉残留在那里而已。</p>
<p>[3] 《失败的逻辑》里面从认知心理学的角度系统介绍了我们在复杂情况下的判断与决策是如何出错的，非常值得一读。</p>
<h3  class="related_post_title">你可能也会喜欢以下文章</h3><ul class="related_post"><li><a href="http://mindhacks.cn/2009/03/28/effective-learning-and-memorization/" title="[BetterExplained]如何有效地记忆与学习">[BetterExplained]如何有效地记忆与学习</a> (74)</li><li><a href="http://mindhacks.cn/2009/02/15/why-you-should-start-blogging-now/" title="[BetterExplained]为什么你应该（从现在开始就）写博客">[BetterExplained]为什么你应该（从现在开始就）写博客</a> (94)</li><li><a href="http://mindhacks.cn/2009/02/09/writing-is-better-thinking/" title="[BetterExplained]书写是为了更好的思考">[BetterExplained]书写是为了更好的思考</a> (34)</li><li><a href="http://mindhacks.cn/2008/07/20/learning-habits-part2/" title="一直以来伴随我的一些学习习惯(二)：时间管理">一直以来伴随我的一些学习习惯(二)：时间管理</a> (6)</li><li><a href="http://mindhacks.cn/2008/07/08/learning-habits-part1/" title="一直以来伴随我的一些学习习惯(一)：学习与思考">一直以来伴随我的一些学习习惯(一)：学习与思考</a> (14)</li><li><a href="http://mindhacks.cn/2008/06/05/how-memory-works/" title="学习与记忆">学习与记忆</a> (1)</li><li><a href="http://mindhacks.cn/2008/03/03/failing-to-see-the-big-picture/" title="Failing To See the Big Picture &#8211; Mistakes we make when learning programming">Failing To See the Big Picture &#8211; Mistakes we make when learning programming</a> (1)</li><li><a href="http://mindhacks.cn/2007/05/24/learn-to-focus/" title="学习密度与专注力">学习密度与专注力</a> (17)</li><li><a href="http://mindhacks.cn/2010/03/18/escape-from-your-shawshank-part3/" title="逃出你的肖申克（三）：遇见20万年前的自己">逃出你的肖申克（三）：遇见20万年前的自己</a> (86)</li><li><a href="http://mindhacks.cn/2009/12/20/dark-time/" title="暗时间">暗时间</a> (97)</li></ul><hr />
<h3>订阅 Mind Hacks</h3>
<a title="用Google Reader订阅" href="http://fusion.google.com/add?feedurl=http://mindhacks.cn/feed/"><img src="http://mindhacks.cn/wp-content/uploads/2009/02/feed_google.gif" style="border:0" alt="订阅到 | Google" /></a> 
<a title="用鲜果订阅" href="http://www.xianguo.com/subscribe.php?url=http://mindhacks.cn/feed/"><img src="http://mindhacks.cn/wp-content/uploads/2009/02/feed_xianguo.gif" style="border:0" alt="订阅到 | 鲜果" /></a>
<br/> 
<a title="用抓虾订阅" href="http://www.zhuaxia.com/add_channel.php?url=http://mindhacks.cn/feed/"><img src="http://mindhacks.cn/wp-content/uploads/2009/02/feed_zhuaxia.gif" style="border:0" alt="订阅到 | 抓虾" /></a> 
<a title="用有道订阅" href="http://reader.youdao.com/b.do?keyfrom=mindhacks&url=http://mindhacks.cn/feed/"><img src="http://mindhacks.cn/wp-content/uploads/2009/02/feed_yodao1.gif" style="border:0" alt="订阅到 | 有道" /></a> 
<hr />
<h3>我是你的信息过滤器</h3>
想了解作者最近在关注什么，欢迎 Follow <a href="https://twitter.com/pongba">pongba@Twitter</a>
<br/>
程序员朋友请到作者发起的 <a href="https://groups.google.com/group/pongba">TopLanguage</a> (<a href="http://mindhacks.cn/about-toplanguage/">about</a>) 社群逛逛，定有收获 :)
<br/>
想了解作者在阅读哪些书，请到 <a href="http://www.douban.com/people/pongba/">pongba@豆瓣</a>，或者直接访问以下四个豆列：<a href="http://www.douban.com/doulist/46003/">[只读经典]思维改变生活</a> | <a href="http://www.douban.com/doulist/127649/">[只读经典]思考的技术与艺术</a> | <a href="http://www.douban.com/doulist/197706/">决策与判断</a> | <a href="http://www.douban.com/doulist/176513/">机器学习与人工智能书籍资源导引</a> 。
<br/>
想了解作者平时在互联网上的阅读，请订阅 <a href="http://delicious.com/pongba/shared-reading">pongba-shared-reading@delicious</a> 。
<hr />
<p><small>
本文由 刘未鹏 发布在 <a href="http://mindhacks.cn">刘未鹏 | Mind Hacks</a>, 2008. | <a href="http://mindhacks.cn/2008/10/29/methodology-for-programmers/#commenting">10 条评论</a> | 标签: <a href="http://mindhacks.cn/tags/%e5%ad%a6%e4%b9%a0%e6%96%b9%e6%b3%95/" rel="tag">学习方法</a>, <a href="http://mindhacks.cn/tags/%e6%80%9d%e7%bb%b4%e6%94%b9%e5%8f%98%e7%94%9f%e6%b4%bb/" rel="tag">思维改变生活</a>, <a href="http://mindhacks.cn/tags/%e7%bc%96%e7%a8%8b/" rel="tag">编程</a>
<br/>
转载请注明作者，出处，以及<a href="http://mindhacks.cn/2008/10/29/methodology-for-programmers/">原始超链接</a>: http://mindhacks.cn/2008/10/29/methodology-for-programmers/
</small></p>]]></content:encoded>
			<wfw:commentRss>http://mindhacks.cn/2008/10/29/methodology-for-programmers/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Failing To See the Big Picture &#8211; Mistakes we make when learning programming</title>
		<link>http://mindhacks.cn/2008/03/03/failing-to-see-the-big-picture/</link>
		<comments>http://mindhacks.cn/2008/03/03/failing-to-see-the-big-picture/#comments</comments>
		<pubDate>Mon, 03 Mar 2008 07:42:00 +0000</pubDate>
		<dc:creator>刘未鹏</dc:creator>
				<category><![CDATA[学习方法]]></category>
		<category><![CDATA[编程]]></category>

		<guid isPermaLink="false">http://mindhacks.cn/2008/03/03/failing-to-see-the-big-picture/</guid>
		<description><![CDATA[Let’s start with an obvious fact: 

The Inconvenient Human Nature, #1
People are inherently more easily attracted by “interesting” (as opposed to “mundane”) things. (We will define “interesting” in the later parts)

What can we derive from this simple axiom? 

A lot of things. But since we’re talking about learning programming, we shall focus mainly on the implications it has for how we learn programming. 

Programming, the interesting and the mundane]]></description>
			<content:encoded><![CDATA[<p><font size="2">Let’s start with an obvious fact: </font></p>
<blockquote><p><font size="2"><b>The Inconvenient Human Nature, #1         <br /></b><i>People are inherently more easily attracted by “interesting” (as opposed to “mundane”) things. (We will define “interesting” in the later parts)</i></font></p>
</blockquote>
<p><font size="2">What can we derive from this simple axiom? </font></p>
<p><font size="2">A lot of things. But since we’re talking about learning programming, we shall focus mainly on the implications it has for how we learn programming. </font></p>
<p><font size="2"><b>Programming, the interesting and the mundane</b> </font></p>
<p><font size="2"><b>The Interesting</b> </font></p>
<p><font size="2">What was the first thing that struck you when you first learned how to program? Wasn’t it the simple fact that you could order a computer to do stuff by simply typing a bunch of characters (thinking of the “hello world” program that we all have written)? But what happened then? You (hopefully) would learn the things that happened under the hood and drove your programs, which leads us to the first point: </font></p>
<blockquote><p><i><font size="2">If it’s something under the hood, it’s interesting (therefore attracts people).</font></i></p>
</blockquote>
<p><font size="2">People are always curious about the forces behind the phenomenons in nature since the dawn of human civilization. There’s a need for people to seek the reason why something happened. We call it the desire to understand. </font></p>
<p><font size="2">After you’ve learned how to hack up a program, and the reason why your program works all the way down to the bit level. What, then, would be the next thing you do? You write programs, and in so doing discover more and more features of your programming language, which means you get more and more familiar with your language and you start to notice the sorts of things it can do conveniently and those it can’t. That when language tricks step into the picture. Language tricks are interesting in that they enable you to do something you usually can’t do. Human beings are born problem solvers, we like solving problems just as much as we like seek out the deep reasons why stuff works. But sadly we’re also adept problem creators. </font></p>
<p><font size="2">In program language sense, the problems of which we seek for solutions are also the ones created by us. For example, there has recently been a remarked theory suggesting that design patterns are missing language features. First we create a language that &#8211; of course &#8211; has some drawbacks which we then use language tricks (such as design patterns) to overcome, but as time goes by, we would get to a point where all those kinds of patterns aren’t wealth anymore but instead turn into pure burdens, which is when we build them into the language. However, by solving the problems created by the previous language, we often create our own new problems. For example, there’s always this “DSL &amp; GPL” (where GPL means general-purpose language) debate. On the one hand, building domain specific features into a language has the obvious advantage that it would be a lot more convenient for programmers to use when faced with domain-specific programming tasks, but on the other hand it would also limit the usage of the language, thus making the whole set of runtime system only accessable by itself (yeah, of course I know there’s inter-language operation, but that’s still another additional step don’t you think?). As to GPLs, the main advantage of them is to use a single runtime system to serve theoretically unlimited application areas. This isn’t without compromises, either. The main compromise is that when faced with domain-specific problems, a GPL only makes for a second-class language. That’s why Microsoft “invented” the CLR system; that’s also why Martin Fowler started advocating the so-called </font><a href="http://www.martinfowler.com/articles/languageWorkbench.html"><font size="2">Language-Oriented Programming</font></a><font size="2">. </font></p>
<p><font size="2">So, to sum up, we created all kinds of language abstractions to make programming easier. But, as it always has been, by solving one problem (programming convenience) we create other ones. Our language will no doubt have many drawbacks, that is, ones that make certain programming tasks harder to do. That’s where language tricks step in and </font><a href="http://www.codinghorror.com/blog/archives/001011.html"><font size="2">steal our focuses</font></a><font size="2"> (I guess you all have a huge stack of language “techniques” books, right?). If you don’t understand what I’m saying, please take a look at any suggested “classic C++ books” list. </font></p>
<p><font size="2">However, why on earth do we have to learn those tricks? We don’t, actually. But we tend to. Because: </font></p>
<blockquote><p><i><font size="2">We’re born problem solvers, we like solving problems; problems are interesting, even if they’re created by ourselves. </font></i></p>
</blockquote>
<p><font size="2">So, what happens after that? We learn new “techniques”. By “techniques”, I mean literally dozens of libraries, frameworks, APIs, and several new languages dubbed “the next big thing” (whether or not they say that explicitly). Again, why do we have to learn these? We don’t, really. We can learn them on an as-needed basis. One of the main reasons we’re attracted to them is because: </font></p>
<blockquote><p><i><font size="2">We like new stuff. If it’s new, it’s interesting.</font></i></p>
</blockquote>
<p><font size="2">Another reason is that we like to <b>jump on the bandwagon</b>. </font></p>
<blockquote><p><font size="2"><b>The Inconvenient Human Nature, #2         <br /><i>Jumping-on-the-bandwagon</i></b><i>: If everyone is doing it, so should I.</i><b></b></font></p>
</blockquote>
<p><font size="2">Not only do corporations use this strategy to induce us, we do it ourselves, that is, we create our own bandwagon. When some new language or technique comes out, we often get so excited that we blind ourselves to the problems it has; we’re blinded by the halo created by its featured features. We often, as a result, regard it as a panacea. We start eagerly to learn it. Programmers are smart animals, probably too smart. They always yearn for new stuff (check out what’s been discussed on the major programming forums and you will know what I’m saying), just like beasts hungering for blood. You walk around on the programming forums, you see thousands and thousands of technical details; it’s an endless job learning all those, but programmers love that.</font><a href="http://www.douban.com/subject/1417047/" target="_blank"><font size="2"><img align="right" src="http://lobelia.douban.com/mpic/s2652990.jpg" /></font></a><font size="2"> </font></p>
<p><font size="2"><b>The Mundane</b> </font></p>
<p><font size="2">On the other hand, what do (most) programmers not love? Principles, be it coding principles in the small (e.g. “always give variables meaningful names”) or development principles in the large (e.g. “write&#160; tests before you write the actual code”). They’re just dull. They’re not tricky; they’re not weird; they’re not challenging. We can’t show the world how smart we are by complying with some silly rules. What we do love is writing some insanely tricky code or</font><a href="http://www.douban.com/subject/1432042/" target="_blank"><font size="2"><img align="right" src="http://lobelia.douban.com/mpic/s1445893.jpg" /></font></a><font size="2"> using some dazzling patterns that nobody else has a clue what we’re doing (or everybody knows what we’re doing). </font></p>
<p><font size="2">Right? </font></p>
<p><font size="2"><b>The Self-handicapped Programmers</b> </font></p>
<p><font size="2">On the one hand, programmers are learning too fast, and learning too much (see above). On the other hand, there’re always times when we need to learn new things. </font><a href="http://www.douban.com/subject/1451622/" target="_blank"><font size="2"><img align="right" src="http://lobelia.douban.com/mpic/s1463770.jpg" /></font></a><font size="2"> </font></p>
<p><font size="2">There actually are several kinds of human natures that can hinder one from learning new things. The&#160; one related to what we’re getting at is: </font></p>
<blockquote><p><font size="2"><b>The Inconvenient Human Nature, #3          <br /><i>Self-serving bias</i></b><i>: We love what we’re doing, or who we’re; we dislike all the things that counter it.</i></font></p>
</blockquote>
<p><font size="2">Admit it or not, we’ve all been through this. After we get familiar enough with some language or </font><a href="http://www.douban.com/subject/1229948/" target="_blank"><font size="2"><img align="right" src="http://lobelia.douban.com/mpic/s2547828.jpg" /></font></a><font size="2">platform, the self-serving bias will start to affect what we like (and learn) and what we dislike (and won’t learn). Language debates are all too common in programming community. By blinding ourselves to the disadvantages of our languages or platforms and to the advantages of other languages or platforms, we limit our access to new techniques and ideas. In a sense, we limit our potentials. </font></p>
<p><font size="2"><b>Conclusion</b> </font></p>
<p><font size="2">Most of the times, we’re learning just a little too much. We’re attracted to interesting stuff like a </font><a href="http://www.douban.com/subject/1419359/" target="_blank"><font size="2"><img align="right" src="http://lobelia.douban.com/mpic/s2595001.jpg" /></font></a><font size="2">moth to a flame. Or oftentimes we just learn what everybody else around us is learning or what we’re&#160; told to learn, not know why we should learn it. Fact is, however, after we’ve grasped the essential knowledge, other stuff can just be learned on an as-needed basis. Don’t fall into technical details unless they’re essential or needed right away. There’s just unlimited number of details to follow in this area; you can put your time to something more useful (learning the essentials, learning the ideas, or even just another language). </font></p>
<p><font size="2">On the other hand, however, we’re learning too little. We blind ourselves to the really important </font><a href="http://www.douban.com/subject/1771049/" target="_blank"><font size="2"><img align="right" src="http://lobelia.douban.com/mpic/s1642259.jpg" /></font></a><font size="2">subjects just because they look dull. Tests? That’s like wearing condoms before having sex. Refactoring? Why do we have to do something that’s not going to generate new functionalities and not&#160; shinny at all? Defensive Programming? No thanks, I know what I’m doing here. API Design? Oh-Man, it’s just too darn hard to consider how somebody else would be using my code when I’m writing the splendid implementations. New Languages? What… R U saying that mine is not good enough? Did U NOT see how I can bend the language to do whatever the heck I want it to do?</font></p>
<p><font size="2"></font></p>
<h3  class="related_post_title">你可能也会喜欢以下文章</h3><ul class="related_post"><li><a href="http://mindhacks.cn/2008/10/29/methodology-for-programmers/" title="方法论、方法论&mdash;&mdash;程序员的阿喀琉斯之踵">方法论、方法论&mdash;&mdash;程序员的阿喀琉斯之踵</a> (10)</li><li><a href="http://mindhacks.cn/2009/12/20/dark-time/" title="暗时间">暗时间</a> (97)</li><li><a href="http://mindhacks.cn/2009/10/05/im-a-tiny-bird-book-review/" title="不是书评 ：《我是一只IT小小鸟》">不是书评 ：《我是一只IT小小鸟》</a> (37)</li><li><a href="http://mindhacks.cn/2009/07/06/why-you-should-do-it-yourself/" title="[BetterExplained]遇到问题为什么应该自己动手">[BetterExplained]遇到问题为什么应该自己动手</a> (48)</li><li><a href="http://mindhacks.cn/2009/05/17/seven-years-in-nju/" title="我在南大的七年">我在南大的七年</a> (91)</li><li><a href="http://mindhacks.cn/2009/03/28/effective-learning-and-memorization/" title="[BetterExplained]如何有效地记忆与学习">[BetterExplained]如何有效地记忆与学习</a> (74)</li><li><a href="http://mindhacks.cn/2009/03/09/first-principles-of-programming/" title="编程的首要原则(s)是什么？">编程的首要原则(s)是什么？</a> (32)</li><li><a href="http://mindhacks.cn/2009/02/15/why-you-should-start-blogging-now/" title="[BetterExplained]为什么你应该（从现在开始就）写博客">[BetterExplained]为什么你应该（从现在开始就）写博客</a> (94)</li><li><a href="http://mindhacks.cn/2009/02/09/writing-is-better-thinking/" title="[BetterExplained]书写是为了更好的思考">[BetterExplained]书写是为了更好的思考</a> (34)</li><li><a href="http://mindhacks.cn/2009/01/14/make-yourself-irreplacable/" title="什么才是你的不可替代性和核心竞争力">什么才是你的不可替代性和核心竞争力</a> (18)</li></ul><hr />
<h3>订阅 Mind Hacks</h3>
<a title="用Google Reader订阅" href="http://fusion.google.com/add?feedurl=http://mindhacks.cn/feed/"><img src="http://mindhacks.cn/wp-content/uploads/2009/02/feed_google.gif" style="border:0" alt="订阅到 | Google" /></a> 
<a title="用鲜果订阅" href="http://www.xianguo.com/subscribe.php?url=http://mindhacks.cn/feed/"><img src="http://mindhacks.cn/wp-content/uploads/2009/02/feed_xianguo.gif" style="border:0" alt="订阅到 | 鲜果" /></a>
<br/> 
<a title="用抓虾订阅" href="http://www.zhuaxia.com/add_channel.php?url=http://mindhacks.cn/feed/"><img src="http://mindhacks.cn/wp-content/uploads/2009/02/feed_zhuaxia.gif" style="border:0" alt="订阅到 | 抓虾" /></a> 
<a title="用有道订阅" href="http://reader.youdao.com/b.do?keyfrom=mindhacks&url=http://mindhacks.cn/feed/"><img src="http://mindhacks.cn/wp-content/uploads/2009/02/feed_yodao1.gif" style="border:0" alt="订阅到 | 有道" /></a> 
<hr />
<h3>我是你的信息过滤器</h3>
想了解作者最近在关注什么，欢迎 Follow <a href="https://twitter.com/pongba">pongba@Twitter</a>
<br/>
程序员朋友请到作者发起的 <a href="https://groups.google.com/group/pongba">TopLanguage</a> (<a href="http://mindhacks.cn/about-toplanguage/">about</a>) 社群逛逛，定有收获 :)
<br/>
想了解作者在阅读哪些书，请到 <a href="http://www.douban.com/people/pongba/">pongba@豆瓣</a>，或者直接访问以下四个豆列：<a href="http://www.douban.com/doulist/46003/">[只读经典]思维改变生活</a> | <a href="http://www.douban.com/doulist/127649/">[只读经典]思考的技术与艺术</a> | <a href="http://www.douban.com/doulist/197706/">决策与判断</a> | <a href="http://www.douban.com/doulist/176513/">机器学习与人工智能书籍资源导引</a> 。
<br/>
想了解作者平时在互联网上的阅读，请订阅 <a href="http://delicious.com/pongba/shared-reading">pongba-shared-reading@delicious</a> 。
<hr />
<p><small>
本文由 刘未鹏 发布在 <a href="http://mindhacks.cn">刘未鹏 | Mind Hacks</a>, 2008. | <a href="http://mindhacks.cn/2008/03/03/failing-to-see-the-big-picture/#commenting">一条评论</a> | 标签: <a href="http://mindhacks.cn/tags/%e5%ad%a6%e4%b9%a0%e6%96%b9%e6%b3%95/" rel="tag">学习方法</a>, <a href="http://mindhacks.cn/tags/%e7%bc%96%e7%a8%8b/" rel="tag">编程</a>
<br/>
转载请注明作者，出处，以及<a href="http://mindhacks.cn/2008/03/03/failing-to-see-the-big-picture/">原始超链接</a>: http://mindhacks.cn/2008/03/03/failing-to-see-the-big-picture/
</small></p>]]></content:encoded>
			<wfw:commentRss>http://mindhacks.cn/2008/03/03/failing-to-see-the-big-picture/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
