<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom"><title type="text">博客园_1-2-3.cnblogs.com</title><subtitle type="text">Think different</subtitle><id>http://feed.cnblogs.com/blog/u/28843/rss</id><updated>2012-01-26T15:25:57Z</updated><author><name>1-2-3</name><uri>http://www.cnblogs.com/1-2-3/</uri></author><generator>CNBlogs BlogServer</generator><link rel="alternate" type="text/html" href="http://www.cnblogs.com/1-2-3/"/><link rel="self" type="application/atom+xml" href="http://feed.cnblogs.com/blog/u/28843/rss"/><entry><id>http://www.cnblogs.com/1-2-3/archive/2012/01/18/intro-pomodoro.html</id><title type="text">[推荐]番茄工作法——专治拖延症、精神涣散、再要五分钟综合症</title><summary type="text">首先向仍然在工作岗位上奋战以及回到家还不忘刷博客园的兄弟们致敬。最近读了一点《The Clean Coder》，一个意外的收获是，知道了原来还有个“番茄工作法”。尝试了几天，觉得很有效，推荐给你。XX工作法，一听这名字你就能猜到，是时间管理，而时间管理又往往等同于成功学，所以如果你看了标题之后习惯性地无视本文的话，我也不怪你。成功学没有效果，是因为每个人的特质、境遇都不相同，成功往往无法复制。相反的，想办法改掉自己的一些坏习惯会更有效果。</summary><published>2012-01-18T01:51:00Z</published><updated>2012-01-18T01:51:00Z</updated><author><name>1-2-3</name><uri>http://www.cnblogs.com/1-2-3/</uri></author><link rel="alternate" href="http://www.cnblogs.com/1-2-3/archive/2012/01/18/intro-pomodoro.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/1-2-3/archive/2012/01/18/intro-pomodoro.html"/><content type="html">&lt;p&gt;&lt;img style="float: right;" src="http://pic002.cnblogs.com/images/2012/25284/2012011717574219.png" alt="" width="178" height="150" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;首先向仍然在工作岗位上奋战以及回到家还不忘刷博客园的兄弟们致敬。&lt;br /&gt;　　最近读了一点《&lt;a href="http://book.douban.com/subject/6114900/" target="_blank"&gt;The Clean Coder&lt;/a&gt;》，一个意外的收获是，知道了原来还有个&amp;ldquo;番茄工作法&amp;rdquo;。尝试了几天，觉得很有效，推荐给你。&lt;br /&gt;　　XX工作法，一听这名字你就能猜到，是时间管理，而时间管理又往往等同于成功学，所以你看了标题之后习惯性地无视本文的话，我也不怪你。成功学没有效果，是因为每个人的特质、境遇都不相同，成功往往无法复制。相反的，想办法改掉自己的一些坏习惯会更有效果。&lt;br /&gt;　　我同时患有严重的拖延症、精神涣散和再要五分钟综合症，用了番茄工作法之后，好转了很多。&lt;br /&gt;　　先说说我的病情。&lt;br /&gt;　　&lt;strong&gt;拖延症&lt;/strong&gt;&amp;mdash;&amp;mdash;一直在心里想着&amp;ldquo;那件事必须得做了&amp;rdquo;，可就是迟迟不能开始。越是困难的、重要的事情，越容易这样。&lt;br /&gt;　　&lt;strong&gt;再要五分钟综合症&lt;/strong&gt;&amp;mdash;&amp;mdash;无论娱乐还是工作，都容易烂尾。想好了娱乐到9点就工作，结果拖拖拉拉到10点还没开始干正经事；下定决心要在11点之前睡觉，但是天天都会磨蹭到11点半，12点还没上床。&lt;br /&gt;　　&lt;strong&gt;精神涣散&lt;/strong&gt;&amp;mdash;&amp;mdash;我们都知道&lt;strong&gt;打断&lt;/strong&gt;的危害。但是仔细想想，被别人打断的次数远没有被自己打断自己的次数多。譬如编译程序的时候，感觉好慢呐，赶快趁机刷下微博或者豆瓣吧，然后看到网友上传了美女图片，呦，韩寒写了新博客啦，完了又想起周报还没写呢&amp;hellip;&amp;hellip;&lt;br /&gt;　　这三种毛病综合发作的结果就是，整天愁眉苦脸、心急火燎，好像忙忙叨叨累的不行，到了该睡觉的时候却发现其实没干多少正经事，越发舍不得睡觉。脸色苍白，目光空洞，神疲气短，恶性循环。&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #008000;"&gt;&lt;strong&gt;番茄工作法&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;　　番茄工作法用一句话来概括就是&amp;mdash;&amp;mdash;&lt;strong&gt;工作25分钟休息5分钟&lt;/strong&gt;。详细条款如下：&lt;br /&gt;　　&lt;strong&gt;0. 准备工作：买一个厨房计时器，或者使用软件计时器也行&lt;/strong&gt;（&lt;a href="http://code.google.com/p/pomodairo/" target="_blank"&gt;pc&lt;/a&gt;，&lt;a href="http://pomodoro.ugolandini.com/" target="_blank"&gt;mac&lt;/a&gt;，&lt;a href="http://pomodoropro.com/" target="_blank"&gt;iphone&lt;/a&gt;，&lt;a href="http://51souapp.com/other/939405.html" target="_blank"&gt;Android&lt;/a&gt;）。&lt;br /&gt;　　&lt;strong&gt;1. 把计时器设定为25分钟，开始工作，直到响铃，算工作了一个番茄时间。然后在你的本子的工作项后面画一个叉叉表示此项工作已经耗费了一个番茄时间（如果使用软件会自动记录，更为方便）。&lt;/strong&gt;&lt;br /&gt;　　　　在一个番茄时间内，不可以被打断。这意味着等待编译的时候也不可以刷微博，也不要去泡咖啡或者吃东西。如果想到周报还没写，在本子上记上&amp;ldquo;需要写周报&amp;rdquo;然后马上回到工作中。如果有同事打扰你或者接到客户的电话，礼貌地请求他等待20分钟，在本子上记上&amp;ldquo;需要给王科长回电话&amp;rdquo;然后马上回到工作中。当然有时人家也会大喊一声&amp;ldquo;我等不了了！&amp;rdquo;，需要你立即紧急处理，那么这个番茄时间就相当于白费了，回到工作中时要重新开始这个番茄时间，就当这个番茄时间从来没有开始过。响铃之后，你就可以看一下你的本子，处理刚刚记下的事情。如果这些零碎的小事很多，可以开启一个番茄时间集中处理它们。&lt;br /&gt;　　　　在一个番茄时间内，只做一件工作。如果工作了20分钟就完成了，也不要开始下一项工作或者去娱乐，可以回顾一下，检查/测试，总结经验，做一些优化或美化。如果工作了5分钟就完成了，而且你觉得它本可以在上一个番茄时间里就完成的，并且再去复查一遍也没什么必要，可以将这个番茄时间作废。&lt;br /&gt;　　&lt;strong&gt;2. 休息5分钟。&lt;/strong&gt;&lt;br /&gt;　　　　响铃之后必须立即停止手中的工作，想象你在考试，时间到，马上停笔。即使你觉得在休息的几分钟里就能完成它，也不能继续工作。而且，脑子里也不要再去想任何有关你工作的事情。这其实挺难做到的，我的建议是&amp;mdash;&amp;mdash;离开你的座位&amp;mdash;&amp;mdash;去做运动，或者跟同事聊聊天。&lt;br /&gt;　　&lt;strong&gt;3. 每4个番茄之后休息15分钟。&lt;br /&gt;　　　　&lt;/strong&gt;如果感到疲劳，也可3个番茄就长休一次。或者把休息时间延长，但是不应超过25分钟。&lt;strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;/strong&gt;　　更为详细的内容可以参考&lt;a href="http://cn.pomodorotechnique.com/" target="_blank"&gt;网站&lt;/a&gt;，电子书&lt;a href="http://cn.pomodorotechnique.com/" target="_blank"&gt;英文版&lt;/a&gt;，&lt;a href="http://www.pomodorotechnique.com/resources/ThePomodoroTechnique-CHN_v1-3.pdf" target="_blank"&gt;中文版&lt;/a&gt;（仅32页，值得一读）。番茄工作法由意大利人Francesco Cirillo(弗朗切斯科&amp;bull;齐立罗)发明于1992年。因发明人最开始使用的是番茄形状的计时器而得名。&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #008000;"&gt;&lt;strong&gt;番茄工作法的好处&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;　　&lt;strong&gt;健康&lt;/strong&gt;。这个世界上有太多好玩的事情让人目不暇接。今晚有NFL季后赛野马vs爱国者耶，另外巴萨的比赛也不能错过，还有NBA快船vs湖人也想看一看。《The Clean Coder》看了一半不能扔下，还想再研究下ios编程&amp;hellip;&amp;hellip;一件接着一件，一直不休息，直到累得实在难受才去床上趴一会儿，要么睡不着要么一睡不起。这种被动的休息方式对健康极为不利。最好的休息方式是在感到累之前就做短暂的休息。&lt;br /&gt;　　&lt;strong&gt;保持大脑的活力&lt;/strong&gt;。由于特定的生化原理，大脑内每个神经元都只能连续工作几分钟，之后就必须休息。连续的娱乐和工作会让大脑处于一种麻木、呆滞的状态。番茄团队经过大量研究发现，为保持大脑的活力和效率最大化，最佳番茄时间为25～35分钟。我们大多数人连续工作的时间都是1小时或2小时，所以直觉上会怀疑25分钟的工作时间是不是短了点？会不会刚刚进入状态就被休息打断了？其实，5分钟的休息并不会中断你的思路，反而可以让大脑里的清洁工有时间打扫战场，给脑细胞做做马杀鸡，之后你会文思泉涌也说不定。&lt;br /&gt;　　&lt;strong&gt;成就感&lt;/strong&gt;。每个番茄代表一个纯的25分钟的工作时间。每天数一下番茄数就知道自己做了多少有用功，对每项工作耗费了多少时间也会有更具体的感觉。你可以知道自己娱乐了几个番茄，看了几个番茄的书，做了几个番茄的练习，对时间更有掌控感。&lt;br /&gt;　　&lt;strong&gt;安全感&lt;/strong&gt;。你可以安全地先娱乐一个番茄，然后再看一个番茄的书，不必担心一娱乐起来就停不下。&lt;br /&gt;　　&lt;strong&gt;专心&lt;/strong&gt;。娱乐的时候想着工作，工作的时候不忘娱乐，这是我们大多数人的工作方式，也是低效和焦虑的根源。稀里糊涂地就到了下午，到了晚上，计划难以完成，好像做了很多额外的事情，却又想不起来都干了些什么了。要想摆脱精神涣散的阴影，必须明确地强迫自己&amp;ldquo;一次只做一件事情，并且必须连续做25分钟&amp;rdquo;。&lt;br /&gt;　　&lt;strong&gt;张弛有度&lt;/strong&gt;。根据我的经验，对于一个严重的&amp;ldquo;再要五分钟综合症&amp;rdquo;患者，只是自己在心里想着&amp;ldquo;到九点就休息&amp;rdquo;是不够的，到时候不是差一点没完成，就是有了新的兴趣点。借助于计时器和&amp;ldquo;铃声响起立即停止&amp;rdquo;条款，才能干净利落地根治此症。&lt;br /&gt;　　&lt;strong&gt;不再拖延&lt;/strong&gt;。拖延症患者大多喜欢追求完美。越是想要做得好，就越容易否定自己，觉得没思路，不够好，信心受挫之下更容易精神涣散。使用番茄法，按下计时器，叮咚，强迫自己没思路也不许干别的，就算干想也要想满25分钟。&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #008000;"&gt;&lt;strong&gt;娱乐也番茄&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;　　书里说空闲的时间就不要用番茄法了。但是我的问题是，因为我觉得刚刚吃饱就工作不太合适，总想先娱乐一会儿。可是一旦娱乐起来就停不下来，所以我想娱乐也可以使用番茄法。比如&amp;ldquo;看一个番茄的电影&amp;rdquo;，或者&amp;ldquo;看一个番茄的比赛&amp;rdquo;，之后休息五分钟。这样既有利于健康，也有机会决定之后是继续娱乐一个番茄，还是工作一个番茄。&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #008000;"&gt;&lt;strong&gt;番茄你的计划&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;　　把番茄法与你的工作计划结合起来也很简单，就是使用番茄数作为工作项的时间单位。首先，你可以通过经验知道你每天平均能做几个番茄的工作。然后，估算每个工作项需要的番茄数，这样你就能知道明天可以完成哪几个工作项了。每天结束的时候，再回顾一下每个工作项实际使用的番茄数。简单实用，是吧？&lt;br /&gt;　　也许你还没有做计划的习惯，番茄法可以给你一个很好的起点。因为在按下计时器的开关之前，必须先想好&amp;ldquo;只能做一件事情呐，这个番茄我要做什么？&amp;rdquo; 这样子，逐渐的升级为&amp;ldquo;上午的3个番茄我要做什么？&amp;rdquo;随着你的技巧越来越娴熟，你会有能力并且愿意做全天的计划，一周的计划&amp;mdash;&amp;mdash;不是随便写写、应付领导的，也不会写完就丢在一边，而是真正切合实际，容易跟踪和度量，通过不断的反馈得到改进的计划。&lt;br /&gt;&lt;strong&gt;贴士&lt;/strong&gt; 一个工作项最多5到7个番茄，如果多于这个数，就认为这个任务太过复杂，最好把它分解为几个小任务。如果一个工作项的估值小于一个番茄，把它与其它的小任务组合成一个大任务。&lt;br /&gt;&lt;strong&gt;小贴士&lt;/strong&gt; 你可以在做计划的时候用空心方框&amp;ldquo;[]&amp;rdquo;表示一个番茄时间，3个番茄时间就是&amp;ldquo;[][][]&amp;rdquo;，把它标记在工作项的后面。实际工作时，每耗费一个番茄时间就在空心方框里打个叉叉，耗费2个番茄时间是就是&amp;ldquo;[x][x][]&amp;rdquo;，耗费4个番茄时间时是&amp;ldquo;[x][x][x]x&amp;rdquo;）。&lt;/p&gt;&#xD;
&lt;p style="text-align: center;"&gt;&lt;img src="http://images.cnblogs.com/cnblogs_com/1-2-3/113933/o_logo2_170_r.png" alt="" width="170" height="66" /&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/1-2-3/aggbug/2324917.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/1-2-3/archive/2012/01/18/intro-pomodoro.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/1-2-3/archive/2011/09/12/impression-of-toshiba.html</id><title type="text">东芝の印象</title><summary type="text">东芝有两个挺气派的厂房。说它气派，主要是因为它有好几个又高又宽，大大的卷帘门——方便用卡车直接把电梯运出去。卷帘门平常是关着的，按规定也不允许人走，我每次只能很委屈地走两侧普普通通的、一比较起来就显得很寒酸的小铁门。“要是卷帘门完全敞开了，直接从那么大的门走进去，哇，不知道有多爽呢。”</summary><published>2011-09-12T12:18:00Z</published><updated>2011-09-12T12:18:00Z</updated><author><name>1-2-3</name><uri>http://www.cnblogs.com/1-2-3/</uri></author><link rel="alternate" href="http://www.cnblogs.com/1-2-3/archive/2011/09/12/impression-of-toshiba.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/1-2-3/archive/2011/09/12/impression-of-toshiba.html"/><content type="html">&lt;p&gt;&lt;strong&gt;1.&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;　　东芝有两个挺气派的厂房。说它气派，主要是因为它有好几个又高又宽，大大的卷帘门&amp;mdash;&amp;mdash;方便用卡车直接把电梯运出去。卷帘门平常是关着的，按规定也不允许人走，我每次只能很委屈地走两侧普普通通的、一比较起来就显得很寒酸的小铁门。&amp;ldquo;要是卷帘门完全敞开了，直接从那么大的门走进去，哇，不知道有多爽呢。&amp;rdquo;每次深吸一口气弓着腰去拽小铁门的时候我都这么想着。功夫不负有心人，机会是给有准备的人的，总之，有一天我发现了一个大敞着的卷帘门，顿时心中一亮，小鹿乱撞，急忙小跑着过去，四下打量了一下没人，&amp;ldquo;咻&amp;rdquo;的一下就穿了过去。可是并没有多爽，反而因为担心挨骂以及头上的卷帘会突然砸下来而提心吊胆的，再说那个过程太快了，也根本来不及爽。唉，想象中美好的东西多半不是那么回事。但是，以后只要发现了敞开着的卷帘门，我还是会四下打量一下然后&amp;ldquo;咻&amp;rdquo;的一下穿过去，因为放着现成的、大大门的不走，非要费劲巴力地拽开小铁门走进去，那是多么的白痴啊。&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;2.&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;　　我喜欢聊天，和美女聊天，自由自在、无拘无束的聊天，我喜欢东芝的聊天文化。当然东芝高管们的字典里可没有这一条，要是他们知道聊天成了企业文化不知道会不会气得翻白眼？那时我刚刚步入职场，业务、人头都不熟，整天干坐着心里空落落地挺不好过，看着别人忙这忙那只能干瞪眼。那时候，桌子还是四张四张拼在一起，我对面正巧坐着宁宁和蓉蓉两位美女。我们一开始就聊得挺开心，每天都能聊上一个多小时。我印象最深的是每次宁宁都会特意把脑袋从大大的显示器后面探出来，这对她来说是很自然的事情，但是我总觉得得到了特别的尊重和关注，每次心里都特别高兴。&lt;br /&gt;　　在东芝，拉家常是一项必备的工作技能。可能因为前身是老国企的缘故，这里到处都洋溢着一股子慵懒&amp;mdash;&amp;mdash;倒不是说大家都很闲&amp;mdash;&amp;mdash;早就不是国企了，大家其实都挺忙，压力也不小，但是就像英国的绅士以不工作为荣，这里每个人见了面都憋着非得拉几句家常不可。每次跟宁宁去别的部门办事，她们都得聊上至少半小时，而我就像被聊得热乎的家长们撇在一边的小孩子，站也不是、坐也不是。&lt;br /&gt;　　我们聊得多了梁部长会感觉很不爽。有一次开会的时候他就拉着脸说让我们注意工作气氛，那以后他在屋里的时候我们就不怎么聊了。过了一段时间，又开会，梁部长说你们全是年轻人怎么一天到晚死气沉沉的，都没人说话的&amp;hellip;&amp;hellip;我们全部晕倒。&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;3.&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;　　我在东芝呆了五年，跟许多日本人打过交道，由于种种原因相处得不太愉快，有时候我甚至气得骂脏话，日本人估计也会说些不好听的，但是我从没听他们说过&amp;ldquo;巴嘎&amp;rdquo;，一次都没有，多奇怪！在动画片里不是也经常出现这个词的么？为什么来中国就不说了呢？我真后悔没直接问他们。是不是来中国前受过培训呢？（要是他们真对我说了这个词不知道我会是什么反应）我知道每个日本人来中国之前都会有短期培训，学一些简单的会话，以及注意事项什么的，这种细致的工作作风挺让人佩服。很多日本人来中国都会主动要求去九一八纪念馆参观，有一次还正好是在9月18号前后，我开玩笑地说他们还真不怕挨打。&lt;br /&gt;　　前年忘年会的时候，梁部长不无感慨地说&amp;ldquo;我跟日本人打了10多年交道，老实说，我不了解日本人。&amp;rdquo;确实，日本人跟中国人长得虽然很像，确是那么不同的一个品种。大事说起来没意思，有一件小事很有趣，我记得很清楚。那天是周六，我们三四个同事还有一个叫星原的日本人一起加班。一个同事带了一袋子油桃，洗了之后分给大家吃。这时候星原进来了，我们想也不能让他看着我们吃呀，于是也分给他一个。星原看着手里的油桃，问&amp;ldquo;这是什么东东？&amp;rdquo;我们告诉他是油桃，他听不懂，我们说&amp;ldquo;是桃子。&amp;rdquo;他很机警地说&amp;ldquo;桃子不是有毛的么？这个怎么没有毛？&amp;rdquo;我们说&amp;ldquo;诶呀，你看我们不是吃的挺香的嘛，让你吃你就放心大胆地吃好了，婆婆妈妈的。&amp;rdquo;星原又端详了半天，突然从兜里掏出一把小刀，把桃子的皮给削了，很得意地嘿嘿了两声，然后才吃了起来。&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;4.&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;　　我辞职的时候，按规定必须拿着一张印着所有部长名字的纸，让每个部长在那上面盖章。我拿着那张纸跑来跑去。在楼上的时候（好像是技术部），部长一边盖章一边说&amp;ldquo;可惜了&amp;rdquo;，挺痛快。在一楼，贺部长拿着他的印章，看着我的那张纸，自己在那儿琢磨，也不知道在琢磨啥，琢磨了半天，然后撇了撇嘴，掂了掂手里的章，又琢磨了一下，才重重地盖了上去，一边对我说&amp;ldquo;可惜了，虽然东芝不是最好的选择。&amp;rdquo;这件事我现在还记得，因为当时想着&amp;ldquo;怪不得人家能当那么大领导，同样一句话，人家说出来就感觉那么真诚，那么有分量。&amp;rdquo;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;5.&lt;/strong&gt;&amp;nbsp;&lt;br /&gt;&lt;br /&gt;　　还有一件挺有意思的小事。那是我们刚刚入职的时候，要统一进行入职培训，其实就是HR给我们讲一讲公司的制度、纪律什么的。讲师是一个50多岁感觉很实在的大叔，我们管他叫赵老师。赵老师说&amp;ldquo;注意上班时的纪律，不允许上网、看报纸，也不要趴在桌子上睡觉&amp;rdquo;，我上学的时候很喜欢趴在桌子上睡觉，所以当时心里很忐忑地想&amp;ldquo;不让趴桌子呐，不知道能不能挺得住。&amp;rdquo;他接着说&amp;ldquo;中午午休一小时，不允许打扑克。&amp;rdquo;，还有&amp;ldquo;我们中午去食堂吃饭，分两拨，第一拨11:50，第二拨12:10分，间隔20分钟。&amp;rdquo;我因为吃饭比较慢所以很担心地问&amp;ldquo;要是20分钟之内吃不完怎么办？&amp;rdquo;他说&amp;ldquo;一般都能吃得完的。&amp;rdquo;我还是很担心地问&amp;ldquo;那万一吃不完怎么办呢？&amp;rdquo;他说&amp;ldquo;怎么会吃不完呢？你上了班就知道了，都着急回去打扑克，没有吃不完的&amp;hellip;&amp;hellip;&amp;rdquo;&amp;ldquo;啊？你刚刚不是说不允许打扑克的吗？&amp;rdquo;我狂晕。&lt;/p&gt;&#xD;
&lt;p style="text-align: center;"&gt;&lt;img src="http://images.cnblogs.com/cnblogs_com/1-2-3/113933/o_logo2_170_r.png" width="170" height="66" /&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/1-2-3/aggbug/2174192.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/1-2-3/archive/2011/09/12/impression-of-toshiba.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/1-2-3/archive/2011/09/05/model-method-part3.html</id><title type="text">建模心法(3) 模型的演进——保持简单和弹性的3个建议</title><summary type="text">对于开发信息系统的程序员来说，最闹心、最上火、最忐忑、最纠结、最不好干、而且肯定会被埋怨的活儿是什么？</summary><published>2011-09-05T01:32:00Z</published><updated>2011-09-05T01:32:00Z</updated><author><name>1-2-3</name><uri>http://www.cnblogs.com/1-2-3/</uri></author><link rel="alternate" href="http://www.cnblogs.com/1-2-3/archive/2011/09/05/model-method-part3.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/1-2-3/archive/2011/09/05/model-method-part3.html"/><content type="html">&lt;p&gt;问：&amp;ldquo;对于开发信息系统的程序员来说，最闹心、最上火、最忐忑、最纠结、最不好干、而且肯定会被埋怨的活儿是什么？&amp;rdquo;&lt;br /&gt;　　答案是&amp;ldquo;建立领域模型&amp;rdquo;。好的（或者说合理的）模型必须基于对业务深刻理解。一个刚刚接触某个陌生领域的程序员，无论他怎么努力，对业务的理解一定是肤浅和片面的。他明知这个时候作出的模型一定是不够合理的，但是又不得不做，可谓明知不可为而为之，怎能不闹心、不上火、不忐忑？随着项目的推进，对业务的理解也在不断深入，需要对模型不断地重构&amp;mdash;&amp;mdash;&lt;a href="http://book.douban.com/subject/1629512/" target="_blank"&gt;《DDD》&lt;/a&gt;也是这么说的嘛，但是它没提重构的成本有多大。讽刺的是，越到项目的最后阶段，甚至是上线一段时间之后，越容易产生&amp;ldquo;啊哈！原来是这么回事！&amp;rdquo;的顿悟。如果你已经完成了100个页面、300张报表，还有几百万条一分钱都不许错的生产数据，这时候，即使把一个字段从一个表转移到另一个表都可能让你闹心好几天。重构还是不重构？你怎能不纠结，不被埋怨？&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;&lt;span style="color: #008000;"&gt;简单&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;　　重构是不可避免的，特别是项目想要产品化，生命周期在5年、10年甚至更久的时候。既然明知道初始的模型肯定是不够合理的&amp;mdash;&amp;mdash;还是咬咬牙承认吧&amp;mdash;&amp;mdash;我们的目标只能（很委屈地）变成&amp;ldquo;构建一个重构成本比较小的模型&amp;rdquo;。&lt;br /&gt;　　那是怎样的模型呢？答案也很普通：&amp;ldquo;简单的模型&amp;rdquo;。&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;建模心法4&lt;/strong&gt;&amp;nbsp; 初始模型一定要简单。&lt;br /&gt;&lt;br /&gt;　　任何事物，总是由小到大、由简单到复杂的，所以你一准儿在心里吐槽说&amp;ldquo;这神马破文章，看了半天原来全是废话。&amp;rdquo;这里的问题是，我们知道领域模型的重构成本很大，对此心有余悸，所以即使想着&amp;ldquo;就目前的状况来看一个员工只有一个所属科室&amp;hellip;&amp;hellip;&amp;rdquo;，但是总有个小恶魔在耳边嘀咕着：&amp;ldquo;就以往的经验和客户的口风，一个员工有多个所属科室是非常可能而且合理的，与其将来重构，不如现在就设计成多对多关系&amp;hellip;&amp;hellip;&amp;rdquo;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img alt="" src="http://pic002.cnblogs.com/images/2011/25284/2011082710400072.png" /&gt;&lt;br /&gt;　　一段时间之后，果然出现了这样的需求：一个医生本来是属于某个住院科室的（例如一病区、二病区&amp;hellip;&amp;hellip;），但是他也要隔三差五地出门诊，他在出门诊时，是属于某个门诊科室的（例如普通门诊、小儿门诊&amp;hellip;&amp;hellip;）。难道我们的前瞻性设计成功了？！再仔细考察一下，就会发现2个问题：1）虽说一个医生可以有多个部门和角色，但是他同一时间不能既是住院医生又是门诊医生；2）当他在住院部工作时，不但所属科室是某个住院科室，而且所需的功能模块也和出门诊时不一样。也就是说，医生有&amp;ldquo;住院医生&amp;rdquo;和&amp;ldquo;门诊医生&amp;rdquo;两个身份，分别对应不同的科室和角色，他在工作时，必须选择一个身份作为他的当前身份。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img alt="" src="http://pic002.cnblogs.com/images/2011/25284/2011082815141378.png" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;在实际实现的时候，考虑到&amp;ldquo;大多数员工都只有一个身份&amp;rdquo;以及&amp;ldquo;员工最多有3个身份&amp;rdquo;这两个实际情况，可以使用更为简单的结构：&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img alt="" src="http://pic002.cnblogs.com/images/2011/25284/2011082816345273.png" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;如果某个员工没有第二部门和第二角色，就空着。如果某个员工有第二部门和第二角色，在登录系统时，需要由用户选择一个部门&amp;amp;角色作为他的当前部门&amp;amp;当前角色。&lt;br /&gt;&lt;strong&gt;小贴士&lt;/strong&gt; 在分析业务的时候要注意区分&amp;ldquo;有限多个&amp;rdquo;和&amp;ldquo;不确定数量的多个&amp;rdquo;，它们往往需要不同的结构。&lt;br /&gt;　　讨论到这里不难得出结论，&lt;strong&gt;把简单模型重构成复杂模型不是件容易的事，但是如果一开始就使用复杂的模型，往往就会需要由一个复杂模型向另一个复杂模型的重构，那可就有点让人望而生畏了&lt;/strong&gt;。&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;&lt;span style="color: #008000;"&gt;概念&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;　　由于模型的重构成本比较大，所以终归还是希望不要动不动就大改。但是新需求是无法预料的，同时由于前面讨论的原因又不想做太多的前瞻性设计，如何增加模型的弹性呢？为什么那些设计得好的模型总能从容应对需求的变化呢？如果硬要说有什么诀窍的话，那就是&amp;mdash;&amp;mdash;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;建模心法5&lt;/strong&gt; 从一开始就关注实物背后的概念&lt;br /&gt;&lt;br /&gt;　　我不想故弄玄虚，玩概念。这里的&lt;strong&gt;概念&lt;/strong&gt;指的是对实物进行一点儿&lt;strong&gt;抽象&lt;/strong&gt;，考虑它的&lt;strong&gt;本质&lt;/strong&gt;。&lt;strong&gt;抽象&lt;/strong&gt;的意思是指把不重要的属性略去不考虑，重点考量它对客户、对系统的价值和存在的意义。&lt;strong&gt;本质&lt;/strong&gt;指的是那些固有的、不容易发生变化的东西。譬如对于人来说性格不容易改变，所以把握住司马懿多疑的性格，就大概可以料到摆个空城计能令他不敢攻城。同样，如果你能把握住业务中每个对象对客户或系统的价值和存在的意义，能看透哪一部分是固有的、不易变化的，那么，在外人看来你大概也有了料敌机先的本事。&lt;br /&gt;　　说起来容易，真要操作起来还有几个难题。1）到底应该从什么时候开始，又从何处入手呢？2）哪些是重要的、什么是本质的，可谓仁者见仁，很难找到评判的依据和标准；3）对一个东西的抽象，可以有无数个方向、无数个层次。就像故事里说的明代那个叫王守仁的大牛，年轻的时候立志要成为圣贤，所以决定实践一下朱大圣人的&amp;ldquo;格物致知&amp;rdquo;，每天在自家后院&amp;ldquo;格&amp;rdquo;竹子，无论风吹雨淋，一直盯着竹子&amp;ldquo;格&amp;rdquo;，后来竹子没格成功，自己先得了感冒。&lt;br /&gt;　　后面两个问题无法可想，它们大概属于&amp;ldquo;艺术&amp;rdquo;的范畴。对于第一个问题倒是有个不错的建议&amp;mdash;&amp;mdash;当遇到&lt;strong&gt;矛盾&lt;/strong&gt;的时候，就是一个很好的契机。&lt;br /&gt;　　看一个具体的例子。如果你去医院看过病，一定对交了费之后拿到的那一大堆收据不陌生。当然，我们一般也不会仔细看它们，都是到了医生那里就把一堆收据全给人家，等人家捡走几张之后再把剩下的揣到自己兜里。所以现在让领域专家给我们讲讲吧。&lt;br /&gt;　　&amp;ldquo;这种收据，一般都是&amp;lsquo;3联&amp;rsquo;，也就是3张大小、格式全都一样的纸叠在一起，纸张之间有复写功能，由针式打印机打印之后3张纸就有了一模一样的内容。这3张纸，第一联叫存根联，由收款员留着；第二联叫通知联，由执行科室（也就是负责执行医嘱的部门，像放射线室、化验室、门诊药局等等）留着，所以这一联也叫执行联；第三联叫报销凭证，由患者留着。&lt;br /&gt;　　&amp;ldquo;每张收据有一个收据号，收据是一张接着一张连续打印的。对于非药医嘱，每个医嘱一张收据；对于药品医嘱，每个处方（一个处方可能包含1～5种药品）一张收据。收据上打印的主要内容是医嘱名称、数量、金额和整张收据的总金额。&lt;br /&gt;　　&amp;ldquo;需要注意的是，上面说的是针对自费患者的规则。如果是医保患者，则变成所有医嘱的总费用打印在第一张收据上，并注明此收据为&amp;lsquo;医保总联收据&amp;rsquo;，专门用于报销；然后再接着打印执行联，其规则是每个非药医嘱一张执行联，每个处方一个执行联。因为执行联也是打印在收据纸上的，所以还要注明&amp;lsquo;这是执行联，不可用于报销&amp;rsquo;的字样&amp;hellip;&amp;hellip;&amp;rdquo;领域专家说完之后有点小得意地瞟了程序员一眼。&lt;br /&gt;　　&amp;ldquo;我艹，这都神马乱七八糟的&amp;hellip;&amp;hellip;&amp;rdquo;程序员听到这儿都快崩溃了，&amp;ldquo;不但非药医嘱和药品医嘱的处理方式不一样，自费患者和医保患者的处理方式相差的更多，这要怎么搞？&amp;rdquo;&lt;br /&gt;　　说实在的，模型变得臃肿和难以理解很大程度上是拜各种&amp;ldquo;其它情况&amp;rdquo;所赐。但是，这些都是每天正在发生着的实际业务。如果说&amp;ldquo;存在就有它的理由&amp;rdquo;的话，要是我们能把这些理由搞明白，这反而可以成为加深理解的好机会。&lt;br /&gt;　　要从哪里开始呢？就从最明显的不一致的地方开始：我们可以发现对于自费患者，收据和执行联是一模一样的（因为是一次打印3联，无论票据号还是内容都完全相同）；对于医保患者，收据和执行联是分开的，且票据号和内容都不一样。这暗示我们收据和执行联可能是2个不同的概念。&lt;br /&gt;　　从价值和存在的意义考虑，收据的作用是1）作为患者已经交了费用的证明；2）报销的依据。执行联的作用是 1）表明患者已经交了费可以执行医嘱；2）指示医院的执行科室应该执行哪些医嘱。&lt;br /&gt;　　再抽象一点从拓扑的角度考虑，可以认为收据和执行联都是对医嘱（所对应的收费项目）的分组，只是分组的方法不一定相同。一个重要的问题是这两种分组方法是否有必然的联系？&lt;br /&gt;　　再回过头来仔细考虑那些规则，看看有多少非本质的因素。当然就像前面所讨论的，是不是本质的很大程度上是主观的、相对的。可以认为，&amp;ldquo;X光检查和验血不应该打印到同一张执行联上&amp;rdquo;是本质的，因为这两项医嘱需要在不同的执行科室执行，如果打在一张执行联上，难不成要把执行联撕成两片吗？但是&amp;ldquo;每个非药医嘱一张执行联&amp;rdquo;分明是因为程序员想偷懒&amp;mdash;&amp;mdash;判断哪些医嘱属于同一个执行科室有点麻烦，还要考虑医嘱太多的话一张小小的票据可能打不下，另外这样做会使退费更容易处理（退费是另一个有点复杂的主题，本文限于篇幅不再讨论）。&amp;ldquo;对于医保患者，所有医嘱的总费用打印在第一张收据上&amp;rdquo;可能是因为医保中心要求这么做，也可能仅仅因为分几组进行医保结算操作技术上很麻烦。&lt;br /&gt;　　经过一些分析之后，不难得出结论。需要把医嘱（所对应的费用明细）分组打印到票据（收据和执行联）上是本质的（当然将来随着医院和全社会无纸化水平越来越高，这些票据也会逐步消失）。生成这两种票据的分组规则可能完全相同，也可能有很大的不同，这取决于技术上的限制或实现上的方便，它们之间没有必然的联系。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img alt="" src="http://pic002.cnblogs.com/images/2011/25284/2011090123270949.png" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;在创建票据的时候，我们给出两种分组算法：GroupMethod1&amp;mdash;&amp;mdash;对于非药医嘱，每个医嘱一组；对于药品医嘱，每个处方一组；GroupMethod2&amp;mdash;&amp;mdash;所有医嘱一组。对于自费患者，使用 GroupMethod1 创建收据和执行联；对于医保患者，使用 GroupMethod2 创建收据，使用 GroupMethod1 创建执行联。打印票据的时候，自费患者只打印收据；医保患者先打印收据，再接着打印执行联。&lt;br /&gt;　　因为收据和执行联的属性几乎一样，所以实际实现的时候也可以把收据和执行联用一个叫&amp;ldquo;票据&amp;rdquo;的实体来表示。另外，由于普通患者的收据和执行联的所有属性值都相同，持久化两条几乎一模一样的数据好像也没什么意思，可以暂且先不创建自费患者的执行联。至于要不要使用子类、弄个 factory 什么的，可以根据实际情况再做决定，本文限于篇幅不再讨论，但是至少应该把那两个分组算法和创建票据的代码封装到函数之中。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img alt="" src="http://pic002.cnblogs.com/images/2011/25284/2011090123403527.png" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;&lt;span style="color: #008000;"&gt;功夫在模型外&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;　　再说一点题外话。当客户要求我们实现很复杂的功能时，一定要小心&amp;mdash;&amp;mdash;那可能只是客户脑袋发热，没有想到可以有更简单明了的解决问题的方法。这时候，即使可以假设开发团队的水平相当高，可以又快又好的把程序搞出来，仍然还要面对两个问题：1）程序太复杂了，想要向客户证明程序是光荣伟大而正确的很困难，客户需要经过很长时间才能信任程序，这预示着更大的培训和维护成本；2）客户可能没有程序员那么聪明，特别是需要多个部门的基础、利益各不相同的众多用户协作的时候&amp;mdash;&amp;mdash;他们用不明白那么复杂、微妙的程序，最后只能使用最简单的那一部分&amp;mdash;&amp;mdash;程序员应该对程序复杂性的边界心中有数，可以感觉到&amp;ldquo;这个要越线了&amp;rdquo;。这时候，如果程序员能给出更简单的方法，客户反而会感谢你，取得双赢的结果。这也可以说是&amp;ldquo;功夫在模型外&amp;rdquo;。相信将来企业管理软件的开发会与管理咨询一同进行，由目前的业务驱动开发逐渐转变为信息化建设促进管理改进。&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;建模心法6&lt;/strong&gt;&amp;nbsp; 帮助客户找到既简单又有效的解决方案。&lt;br /&gt;&lt;br /&gt;　　这一条要求程序员在更高的层面上思考业务的本质。直觉上可能会觉得这已经和程序无关了，或者至少程序员不是最适合干这个的人选，但是我不这么认为。有句话说得好&amp;ldquo;想知道自己是不是真正理解了就用程序去实现它&amp;rdquo;，如果程序员已经成功地创造了一个信息系统来仿真真实业务，他对业务的理解一定比普通的业务人员更深刻、更全面，再加上他又是那么的聪明伶俐，如果他愿意更进一步的话，谁能拦得住？&lt;/p&gt;&#xD;
&lt;p style="text-align: center;"&gt;&lt;img src="http://images.cnblogs.com/cnblogs_com/1-2-3/113933/o_logo2_170_r.png" width="170" height="66" /&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/1-2-3/aggbug/2155353.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/1-2-3/archive/2011/09/05/model-method-part3.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/1-2-3/archive/2011/08/13/diary-2011-08-08.html</id><title type="text">[日记]游长白遇梅花，植物大战僵尸</title><summary type="text">2011年8月6、7、8，和东芝的老朋友们一起去游长白山。</summary><published>2011-08-13T15:22:00Z</published><updated>2011-08-13T15:22:00Z</updated><author><name>1-2-3</name><uri>http://www.cnblogs.com/1-2-3/</uri></author><link rel="alternate" href="http://www.cnblogs.com/1-2-3/archive/2011/08/13/diary-2011-08-08.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/1-2-3/archive/2011/08/13/diary-2011-08-08.html"/><content type="html">&lt;p&gt;&amp;ldquo;旅客朋友们&amp;mdash;&amp;mdash;&amp;rdquo;我因为坐在面包车副驾驶的位置，所以假装自己是导游，&amp;ldquo;您即将经过的景点是&amp;lsquo;董眼镜修车铺&amp;rsquo;，请向车窗的左侧观看&amp;hellip;&amp;hellip;&amp;rdquo;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #008000;"&gt;&lt;strong&gt;董眼镜修车铺&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;img style="float: right;" src="http://images.cnblogs.com/cnblogs_com/1-2-3/316160/o_IMG_0284_40.JPG" alt="" width="384" height="288" /&gt;　　&amp;ldquo;董眼镜修车铺&amp;rdquo;是怎么回事呢？原来，我们昨天经过这附近的时候爆了胎。从长白山西坡到长白县要3个多小时的车程，大段大段的在修路，差不多 2/3 都是土路，坑坑洼洼的，有些地段铺满了碎石子。我们刚刚行进了不到 1/4 的路程，就被小石子扎爆了左后轮。&lt;br /&gt;　　那是我跟东芝的老朋友们出来旅行的第二天。我们刚刚从西坡登上长白山的峰顶，很幸运地看到了天池。下午 4 点钟左右，阳光正灿烂，司机换备胎累得满头大汗，我只能帮忙压了几下千斤顶。备胎不宜使用太长时间，所以还得找修车铺补胎。开着车在附近找到一个村子，转了3家修车铺，都对我们摇了头。他们有的说&amp;ldquo;董眼镜！&amp;rdquo;，有的指着门外说&amp;ldquo;去，董眼镜！&amp;rdquo;。于是&amp;ldquo;董眼镜&amp;rdquo;成了我们心目中一个好似银河抵抗组织基地一般既神秘又好玩的所在。其实董眼镜的修车铺就在公路的旁边，挺破烂的一间瓦房，里面有火炕和一台老式电视机。我们大大咧咧地上了炕（后来想想好像真正算是上了炕的只有宁宁），开着各种好玩的玩笑，比如扎爆了我们轮胎的小石子其实是董眼镜的徒弟们故意扔的等等，很欢乐。补胎需要不少时间，以至于我们可以去附近的村子里上趟厕所，还买了雪糕吃。董眼镜是个 60 来岁剃着平头的小老头，皮肤黑黑的，确实带着副大大的眼镜。&amp;ldquo;我不干这么没技术含量的活儿&amp;rdquo;董眼镜说，&amp;ldquo;平时都是我老婆负责补胎的&amp;rdquo;。也许他没吹牛，过道上摆得满满的车床、电焊机和架子上好几本技术书都是证明。另一间屋子里则摆满了各种汽车的配件，我们都说董眼镜其实是这一片修车行里的老大呢。&lt;br /&gt;　　就像圣埃克絮佩里说的，&amp;ldquo;当你在长长的公路上找到了一间修车铺，度过了本该不怎么愉快的一个小时，留下了欢声笑语，看过了修车师傅的全家福之后，对于你来说，它就不再是一间普通的修车铺，对于它来说，你也不再是一名普通的游客。以后，每当你看到它，都会在心底泛起微笑&amp;rdquo;。&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;&lt;span style="color: #008000;"&gt;夜行&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;img style="float: right;" src="http://images.cnblogs.com/cnblogs_com/1-2-3/316160/o_IMG_0368.JPG" alt="" width="400" height="300" /&gt;　　由于修车耽搁了一个多小时，我们不得不早早地开始走夜路。我是真的喜欢夜路！山路窄窄的，车灯投射在地面上，形成一片小小的淡黄色光芒，周围则渐渐没入黑暗。有时会遇到浓烟和雾气，蜿蜒曲折的山路，好像永远也到不了头似的。路上静悄悄地，很难遇到对头车。黑暗包裹着，你就像一只孤单的萤火虫。有时，飞蛾迎着车头飞过，在车灯的映照下闪着金黄色的光芒，黑夜也平添了一丝绚丽和神秘。如果你的眼神好，偶尔能看见有金色的小东西在地上一跳一跳的，那是蛤蟆想要横过马路，到另一侧的鸭绿江边去。半个月亮很明亮，星空清晰可见。路两旁黑压压的原始森林向你压过来。我心想，要睁大眼睛注意看有没有停在路边还不亮灯的危险车辆&amp;hellip;&amp;hellip;&lt;br /&gt;　　&amp;ldquo;啊呀！好危险！还真有这么无德的车！&amp;rdquo;我们刚转过一个弯角，就看到一辆黑色的轿车停在路边，两个模糊的人影正在后备箱那里忙活着什么。&amp;ldquo;那辆车&amp;hellip;&amp;hellip;&amp;rdquo;司机过了几秒钟才说，&amp;ldquo;八成是干走私的，因为公路那边就是朝鲜，他们有铜和铁，我们用粮食交换，有时也会走私从日本过来的毒品&amp;mdash;&amp;mdash;冰毒一类的。&amp;rdquo;后来，这样的车我们陆陆续续看到了 3 辆。司机是本地人，朝鲜族，32岁，个子不高，瘦瘦的，既开朗又自信。&amp;ldquo;路的左边隔着鸭绿江就是朝鲜。注意看那些像萤火虫似的亮点，那就是村民的房子，灯光有些暗，因为都是二三十瓦的老式灯泡。&amp;rdquo;我们没请导游，全靠热情的司机给我们介绍，&amp;ldquo;再往前开一段就是朝鲜第三大城市惠山，明天我们返程时可以看一下。&amp;rdquo;&lt;br /&gt;　　&amp;ldquo;师傅你这条路很熟吧？&amp;rdquo;开始了下山路的连续弯道，司机居然都不用刹车的，弯来转去的公路像一条大蛇扭动着斑驳的腰身，怎么都觉得像是在玩极品飞车一类的游戏。&amp;ldquo;啊&amp;hellip;&amp;hellip;&amp;rdquo;司机听到我这么问好像有一点惊讶，过了好一会儿才回答我说，&amp;ldquo;是挺熟啊，这条路哪里有坑、哪里有包我全都知道。&amp;rdquo;&lt;br /&gt;　　有那么几个瞬间，我甚至希望永远不要到达终点。我希望&amp;hellip;&amp;hellip;被大雨耽搁在路上；滚石摧毁铁轨；台风阻断一切交通。也许&amp;hellip;&amp;hellip;司机会突然不省人事&amp;mdash;&amp;mdash;就让我们永远迷失在旅途上吧。&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;&lt;span style="color: #008000;"&gt;就算只看到一片乌云，那也是天池上空的乌云啊&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;img style="float: right;" src="http://images.cnblogs.com/cnblogs_com/1-2-3/316160/o_IMG_0307_40.JPG" alt="" width="288" height="384" /&gt;　　我的乌鸦嘴向来有点名气。昨天刚说这次唯一的一点遗憾是新买的旅行专用雨衣和一次性鞋套没用上，早上就下起了小雨，我们披上雨衣穿行在十五道沟（官方名称是望天鹅峡谷）的小桥和木质栈道上。峡谷里有一条挺漂亮的小河，两侧的山上有好几个大大小小的瀑布浇灌着青草和绿树。游客很稀少，实际上，很难遇到别的游客，拍起照来很过瘾。有点可惜的是景点有些少，只用了2个小时就游遍了。门口景区地图上的景点有一半都是灰色的未开放状态，不知道是不是因为它是新开发的景区，还没有完全完工。&lt;br /&gt;　　我们按计划接着赶到长白山南坡，想要再看一次天池，却收到坏消息&amp;mdash;&amp;mdash;受台风&amp;ldquo;梅花&amp;rdquo;的影响，山顶刮起了大风，门票全部停售（据说风力强到把一辆汽车的车门都吹坏了）。我们都暗自庆幸幸亏昨天看到了天池，但是其它刚刚赶到的游客就惨了，有一个旅行团找了景区领导，非要买票进门不可。那边的答复是想进去也可以，但是所有景区全部关闭，门票售出不退。即使这样他们也愿意进山，还有一个女游客悲壮地说&amp;ldquo;就算只看到一片乌云，那也是天池上空的乌云啊&amp;rdquo;。希望和失望的力量多么强大！它们两个加在一起的杀伤力更是超乎想象。&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;&lt;span style="color: #008000;"&gt;绿皮火车&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;　　晚上，回程的火车没有买到卧铺，好在提前买好了票，有座&amp;mdash;&amp;mdash;13 个小时的车程，总好过站票。老雷他们凑了一桌打扑克。宁宁和我因为很悲惨地明早还要上班，早早地眯起眼睛打盹。这是古老的绿皮火车。我想起了周云蓬的《绿皮火车》。我虽然没有他那么多姿多彩的经历，但是也同样从小就喜欢自己坐火车出去玩。那脏兮兮的地面，局促的空间，深绿色的座椅，还有偶尔钻进鼻孔的厕所味道，都隐隐地勾起了一丝熟悉的旅愁。座椅虽然看上去很宽大，但是靠背太直了，想要打个盹还真是不容易，脖子疼的像是要折了。我一个盹下去，脑袋啪嚓一下砸在宁宁的头上，心里很过意不去，于是把脑袋稍稍偏向珊珊这边一点。过了一会儿，不知怎么搞的啪嚓一下又砸在宁宁的脑袋上。后来，早上的时候，我问她，她却什么也不记得了。&lt;br /&gt;　　靠窗的桌子很小，宁宁在上面铺了一件厚衣服，趴在上面貌似睡得挺舒服。我琢磨着桌子还剩 20 厘米的一小块地方，也够我趴在上面了。多亏我上学的时候天天练习趴在桌子上睡觉，这么小的地方也能掌握平衡，还做了一个离奇的梦，梦见章弦和&amp;hellip;&amp;hellip;算了，为了他的性命着想就忍着不说了。&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;&lt;span style="color: #008000;"&gt;植物大战僵尸&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;　　早上醒来，居然有一点神清气爽的感觉。背着旅行包直接赶到医院。同事们见了我都说&amp;ldquo;你这个豌豆射手T恤很漂亮呀&amp;rdquo;。我告诉他们说这次旅行我们每个人都事先在淘宝上买了一件植物大战僵尸T恤&amp;mdash;&amp;mdash;有的是植物，有的是僵尸。小孩子们见了我们都会抢着说&amp;ldquo;这个是豌豆射手，那个是寒冰射手&amp;hellip;&amp;hellip;&amp;rdquo;，等哪天我把合影给你们看看。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/1-2-3/aggbug/2137586.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/1-2-3/archive/2011/08/13/diary-2011-08-08.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/1-2-3/archive/2011/07/31/ExtJs4-SASS-Custom-Theme.html</id><title type="text">ExtJs4 与 SASS 的亲密接触——使用 SASS 自定义主题</title><summary type="text">“Sass makes CSS fun again”，我特别喜欢 SASS 网站上的这个口号。SASS 能不能让 ExtJs 也变得更加有趣呢？</summary><published>2011-07-31T03:48:00Z</published><updated>2011-07-31T03:48:00Z</updated><author><name>1-2-3</name><uri>http://www.cnblogs.com/1-2-3/</uri></author><link rel="alternate" href="http://www.cnblogs.com/1-2-3/archive/2011/07/31/ExtJs4-SASS-Custom-Theme.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/1-2-3/archive/2011/07/31/ExtJs4-SASS-Custom-Theme.html"/><content type="html">&lt;p&gt;SASS 是一个在 Ruby 社区兴起的样式语言，支持嵌套、变量、混入、继承等等语言特性，通过命令行工具或Web框架插件生成标准的 CSS 样式（参加SASS主页&lt;a href="http://sass-lang.com/"&gt;http://sass-lang.com/&lt;/a&gt;）。使用 SASS 定义的样式代码更少、更清晰，更重要的是减少重复代码，符合 DRY 原则。让人高兴的是，ExtJs4 已经转向 SASS，你可以在 ext-4.0.2a\resources\sass\ 找到所有 ExtJs 样式的 SASS 版本。&lt;br /&gt;　　由于 SASS 支持变量，所以修改/覆盖样式变得更加容易。例如，只要把 ExtJs 预定义的一个名为 $base-color 的变量重新赋值为 #a1c148（绿色），所有 Ext 控件的底色就会全都变成绿色了。在 ext-4.0.2a\resources\themes\stylesheets\ext4\default\variables\ 文件夹里可以找到所有预定义的变量。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img alt="" src="http://pic002.cnblogs.com/images/2011/25284/2011073021343525.png" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;下面我们一步一步地演练一下使用 SASS 自定义样式的全过程。&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #008000;"&gt;&lt;strong&gt;准备工作&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Step1&lt;/strong&gt; 下载 ExtJs4. &lt;a href="http://www.sencha.com/products/extjs/download"&gt;http://www.sencha.com/products/extjs/download&lt;/a&gt;&lt;br /&gt;&lt;strong&gt;Step2&lt;/strong&gt; 下载 Ruby。在 &lt;a href="http://www.ruby-lang.org/en/downloads/"&gt;http://www.ruby-lang.org/en/downloads/&lt;/a&gt;&amp;nbsp;页，如果你是 Windows 用户应该下载&amp;ldquo;Ruby on Windows&amp;rdquo; 节下的&amp;ldquo;&lt;a href="http://rubyforge.org/frs/download.php/74298/rubyinstaller-1.9.2-p180.exe" target="_blank"&gt;Ruby 1.9.2-p180 RubyInstaller&lt;/a&gt;&amp;rdquo;。下载后将 Ruby 安装到 D:\Ruby192\。为方便使用Ruby命令行工具，安装时建议勾选&amp;ldquo;Add Ruby executables to your PATH&amp;rdquo;选项。&lt;br /&gt;&lt;strong&gt;Step3&lt;/strong&gt; 安装 Compass/SASS。打开 Windows 命令行，执行&lt;br /&gt;gem install compass&lt;br /&gt;安装后，可使用命令&lt;br /&gt;compass &lt;span &gt;-&lt;/span&gt;v&lt;br /&gt;sass &lt;span &gt;-&lt;/span&gt;v&lt;br /&gt;检验是否已成功安装了 compass 和 sass。&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #008000;"&gt;&lt;strong&gt;创建网站，规划目录&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Step4&lt;/strong&gt; 创建一个 MVC 网站，添加一个名为 MyThemDemoController 的控制器，以及配套的 Views\MyThemDemo\MyThemDemo.aspx 和 Scripts\Demo\MyThemDemo.js。把 Step1 中下载的 ext-4.0.2a 复制到网站的 Scripts 目录下。在 IIS 中创建网站，我把端口设成了 6000，你如果想偷懒的话可以下载我建好的整个 &lt;a href="http://files.cnblogs.com/1-2-3/ExtJsThemeDemo.rar" target="_blank"&gt;Demo 项目&lt;/a&gt;，但是要注意 1）别忘了在IIS中建网站，端口是 6000，2）ext-4.0.2a 一共 128M，我为了节省上传、下载时间没有放进去，3）Demo 页 URL 是 &lt;a href="http://localhost:6000/MyThemDemo/MyThemDemo"&gt;http://localhost:6000/MyThemDemo/MyThemDemo&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Step5&lt;/strong&gt; 把 Scripts\ext-4.0.2a\resources\themes\templates\resources 文件夹复制到 Scripts 文件夹下。把 Scripts\ext-4.0.2a\resources\themes\images\default 文件夹复制到 Scripts\resources 文件夹下，并把它由 &amp;ldquo;default&amp;rdquo;重命名为&amp;ldquo;images&amp;rdquo;。之后你的目录结构应该如下图所示。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img alt="" src="http://pic002.cnblogs.com/images/2011/25284/2011073110511462.png" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;&lt;br /&gt;&lt;span style="color: #008000;"&gt;由 SASS 生成 CSS&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Step6&lt;/strong&gt; 修改 Scripts\resources\sass\config.rb 中的 $ext_path 变量，使其指向 ExtJs 根目录。&lt;br /&gt;$ext_path = ".. /.. /ext-4.0.2a"&lt;br /&gt;注意".."和"/"之间不要有空格，天杀的博客园居然会把 &amp;ldquo;.. /.. /&amp;rdquo;替换为&amp;ldquo;http://www.cnblogs.com&amp;rdquo;，逼得我没办法只好加了个空格进去 囧&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Step7&lt;/strong&gt; 修改 Scripts\ext-4.0.2a\resources\themes\lib\utils.rb 第 62 行，由&lt;br /&gt;images_path = File.join($ext_path, 'resources', 'themes', 'images', theme) &lt;br /&gt;修改为&lt;br /&gt;images_path = relative_path&lt;br /&gt;这样 ExtJs 将使用 Scripts\resources\images 下的图片而不是 Scripts\ext-4.0.2a\resources 下的图片。&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Step8&lt;/strong&gt; 打开 Windows 命令行，进入 Scripts\resources\sass 目录下，执行命令&lt;br /&gt;&amp;gt; compass compile&lt;br /&gt;此命令会在 Scripts\resources\css 文件夹下生成 my-ext-theme.css 文件。&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #008000;"&gt;&lt;strong&gt;修改 $base-color 变量，查看效果&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Step9&lt;/strong&gt;&amp;nbsp;编辑 Scripts\resources\sass\my-ext-theme.scss，在 &lt;a href="mailto:&amp;ldquo;@import"&gt;&amp;ldquo;@import&lt;/a&gt; 'ext4/default/all';&amp;rdquo; 这一行之前插入一行&lt;br /&gt;&amp;nbsp;$base-color: #a1c148;&lt;br /&gt;&lt;strong&gt;注意&lt;/strong&gt; 对变量的重新赋值的语句都应该放在 &lt;a href="mailto:&amp;ldquo;@import"&gt;&amp;ldquo;@import&lt;/a&gt; 'ext4/default/all';&amp;rdquo; 这一行之前。&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Step10&lt;/strong&gt; 再次打开 Windows 命令行，进入 Scripts\resources\sass 目录下，执行命令&lt;br /&gt;&amp;gt; compass compile&lt;br /&gt;重新生成CSS文件。&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Step11&lt;/strong&gt; 编辑 MyThemDemo.aspx，添加对 my-ext-theme.css 等文件的引用。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img alt="" src="http://pic002.cnblogs.com/images/2011/25284/2011073111443597.png" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;Step12&lt;/strong&gt; 编辑 MyThemDemo.js，把 Scripts\ext-4.0.2a\examples\themes\themes.js 里的内容全部复制到 MyThemDemo.js 里面。&lt;br /&gt;&lt;strong&gt;Step13&lt;/strong&gt; 打开浏览器，进入 &lt;a href="http://localhost:6000/MyThemDemo/MyThemDemo"&gt;http://localhost:6000/MyThemDemo/MyThemDemo&lt;/a&gt;&amp;nbsp;即可看到效果了。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;br /&gt;但是如何能够实时更改样式呢？（以便达到&lt;a href="http://www.screencast.com/users/sroussey/folders/Jing/media/abbaafdc-82d6-4431-81b0-832d6729266c" target="_blank"&gt;这个视频&lt;/a&gt;所演示的效果），偶也不知道。你要是知道的话请告诉我！&lt;br /&gt;本文主要内容来自&lt;a href="http://www.sencha.com/learn/theming/"&gt;http://www.sencha.com/learn/theming/&lt;/a&gt;。&lt;/p&gt;&#xD;
&lt;p style="text-align: center;"&gt;&lt;img src="http://images.cnblogs.com/cnblogs_com/1-2-3/113933/o_logo2_170_r.png" width="170" height="66" /&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/1-2-3/aggbug/2120373.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/1-2-3/archive/2011/07/31/ExtJs4-SASS-Custom-Theme.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/1-2-3/archive/2011/07/12/nhibernate-guid-key-performance.html</id><title type="text">[NHibernate] Guid 作主键速度超慢的背后</title><summary type="text">从一个70万条的表里面取一条匹配Id的数据居然需要3.5秒！性能瓶颈到底是 NHibernate 还是 .net？难道真的不能用字符串做主键？问题又该如何解决呢？</summary><published>2011-07-12T14:32:00Z</published><updated>2011-07-12T14:32:00Z</updated><author><name>1-2-3</name><uri>http://www.cnblogs.com/1-2-3/</uri></author><link rel="alternate" href="http://www.cnblogs.com/1-2-3/archive/2011/07/12/nhibernate-guid-key-performance.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/1-2-3/archive/2011/07/12/nhibernate-guid-key-performance.html"/><content type="html">&lt;p&gt;最近遇到了一个让人抓狂的性能问题。生产环境里有一张表的数据量目前达到了 70 万条。结果发现无论是匹配主键的查询还是更新，执行一条语句居然需要 3.5 秒！如果把 NH Prof 中截获的 SQL 语句拿到 PL/SQL Developer 里执行，就只需几十毫秒。一开始还以为是NH的问题，后来发现其实另有隐情。&lt;br /&gt;　　介绍一下环境先。数据库使用 Oracle10g，所有字符类型的字段都是 varchar2 &lt;a href="#r1"&gt;[1]&lt;/a&gt;。所有的主键都使用 Guid，在数据库里是 varchar2(36) 类型，相应的，实体的 Id 属性的类型是 string。ORM 使用的是 NHibernate 2.1.0 和 FluentNHibernate1.1。&lt;br /&gt;　　经过一番排查之后发现，问题的根源是 NH 将 SQL 语句传递给 Oracle 时，所有字符型的参数都是 nvarchar2 类型，而数据库里对应的字段却是 varchar2 类型，这将导致 Oracle 无法使用索引，终于造成全表扫描，所以数据量稍大就慢得不行。&lt;br /&gt;　　第一种解决方法是，把数据库中所有的字符型字段的类型由 varchar2 更改为 nvarchar2，出于种种原因我们不希望这么做。&lt;br /&gt;　　第二种解决方法是，让 NH&amp;nbsp;把 varchar2 作为参数类型传递给 Oracle。&lt;br /&gt;　　事实上，NH 默认把 .net 的 string 映射为 DbType.String &lt;a href="#r2"&gt;[2]&lt;/a&gt;，把 DbType.String 映射为 nvarchar2 &lt;a href="#r3"&gt;[3]&lt;/a&gt;。把 DbType.AnsiString 映射为 varchar2 &lt;a href="#r4"&gt;[4]&lt;/a&gt;。&lt;br /&gt;所以对于查询比较简单，只要把 HQL 的参数类型指定为 AnsiString 就行了。&lt;/p&gt;&#xD;
&lt;div &gt;&#xD;
&lt;pre &gt;var query = Session.CreateQuery(@"select t from Region as t&#xD;
                                   where t.Id = :Id")&#xD;
                     .SetAnsiString("Id", id);&#xD;
&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div &gt;&#xD;
&lt;pre &gt;var query = Session.CreateQuery(@"select t from Region as t&#xD;
                                   where t.Id in (:Ids)")&#xD;
                     .SetParameterList("Ids", ids.ToList(), NHibernateUtil.AnsiString);&#xD;
&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;但是如何设置 Update 和 Delete 语句的参数类型呢？这里有个小小的秘技，把映射文件里的属性类型指定为&amp;ldquo;AnsiString&amp;rdquo;即可。&lt;/p&gt;&#xD;
&lt;div &gt;&#xD;
&lt;pre &gt;public class RegionMap : TreeNodeMap&amp;lt;Region&amp;gt;&#xD;
{&#xD;
    public RegionMap()&#xD;
    {&#xD;
        Table("INFRA_REGION");&#xD;
        Id(t =&amp;gt; t.Id, "REGION_ID").CustomType("AnsiString");&#xD;
        ...&#xD;
    }&#xD;
}&#xD;
&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;&lt;strong&gt;注意&lt;/strong&gt; 一定要使用 CustomType() 而不是 CustomSqlType()。&lt;br /&gt;当然了，要是把每一个配置文件都改一遍实在很烦，好像项目使用了 Fluent&amp;nbsp; NHibernate，只要添加一个 IdConvention 就行了。&lt;/p&gt;&#xD;
&lt;div &gt;&#xD;
&lt;pre &gt;public class IdConvention : FluentNHibernate.Conventions.IIdConvention&#xD;
{&#xD;
    public void Apply(FluentNHibernate.Conventions.Instances.IIdentityInstance instance)&#xD;
    {&#xD;
        instance.CustomType("AnsiString");&#xD;
    }&#xD;
}&#xD;
&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;想要彻底一点的话，可以再加一个 string 类型的 property 的 convention。&lt;/p&gt;&#xD;
&lt;div &gt;&#xD;
&lt;pre &gt;public class StringPropertyConvention : IPropertyConvention, IPropertyConventionAcceptance&#xD;
{&#xD;
    public void Accept(IAcceptanceCriteria&amp;lt;IPropertyInspector&amp;gt; criteria)&#xD;
    {&#xD;
        criteria.Expect(x =&amp;gt; x.Property.PropertyType == typeof(string));&#xD;
    }&#xD;
&#xD;
    public void Apply(IPropertyInstance instance)&#xD;
    {&#xD;
        instance.CustomType("AnsiString");&#xD;
    }&#xD;
}&#xD;
&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;把这两个 Convention 加到配置里面：&lt;/p&gt;&#xD;
&lt;div &gt;&#xD;
&lt;pre &gt;Session["SessionFactory"] = Fluently.Configure()&#xD;
          .Database(OracleClientConfiguration.Oracle10&#xD;
              .Dialect&amp;lt;Oracle10gDialect&amp;gt;()&#xD;
              .ConnectionString("User ID=iBlast;Password=不可说;Data Source=Moki")&#xD;
              .QuerySubstitutions("true 1, false 0, yes 'Y', no 'N'")&#xD;
              .UseOuterJoin()&#xD;
              .ProxyFactoryFactory&amp;lt;ProxyFactoryFactory&amp;gt;()&#xD;
              .AdoNetBatchSize(1000)&#xD;
              .Driver&amp;lt;OracleClientDriver&amp;gt;())&#xD;
          .Mappings(m =&amp;gt; { m.HbmMappings.AddFromAssembly(Assembly.Load("Infrastructure.Repositories")); &#xD;
                           m.FluentMappings.AddFromAssembly(Assembly.Load("Infrastructure.Repositories"))&#xD;
                                           .Conventions.Add&amp;lt;EnumConvention&amp;gt;()&#xD;
                                           .Conventions.Add&amp;lt;HasManyConvention&amp;gt;()&#xD;
                                           .Conventions.Add&amp;lt;HasManyToManyConvention&amp;gt;()&#xD;
                                           .Conventions.Add&amp;lt;StringPropertyConvention&amp;gt;()&#xD;
                                           .Conventions.Add&amp;lt;IdConvention&amp;gt;()&#xD;
                                           .ExportTo(@"F:\temp\"); })&#xD;
          .BuildSessionFactory();&#xD;
&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;注意倒数第二行的 .ExportTo(@"F:\temp\") 是为了测试一下生成的映射文件对不对而把映射文件输出到了 &amp;ldquo;F:\temp\&amp;rdquo;，映射文件应该像这个样子：&amp;nbsp;&lt;/p&gt;&#xD;
&lt;div &gt;&#xD;
&lt;pre &gt;&amp;lt;hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" default-access="property" auto-import="true" default-cascade="none" default-lazy="true"&amp;gt;&#xD;
  &amp;lt;class xmlns="urn:nhibernate-mapping-2.2" dynamic-insert="true" dynamic-update="true" mutable="true" where="IsDelete=0" name="Dawn.HIS.Infrastructure.Core.Data.Region, Infrastructure.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" table="INFRA_REGION"&amp;gt;&#xD;
    &amp;lt;id name="Id" type="AnsiString"&amp;gt;&#xD;
      &amp;lt;column name="REGION_ID" /&amp;gt;&#xD;
      &amp;lt;generator  /&amp;gt;&#xD;
    &amp;lt;/id&amp;gt;&#xD;
    &amp;lt;version name="Version" type="System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"&amp;gt;&#xD;
      &amp;lt;column name="Version" /&amp;gt;&#xD;
    &amp;lt;/version&amp;gt;&#xD;
    &amp;lt;property name="CreateTime" type="System.DateTime, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"&amp;gt;&#xD;
      &amp;lt;column name="CREATETIME" /&amp;gt;&#xD;
    &amp;lt;/property&amp;gt;&#xD;
    &amp;lt;property name="Name" type="AnsiString"&amp;gt;&#xD;
      &amp;lt;column name="NAME" /&amp;gt;&#xD;
    &amp;lt;/property&amp;gt;&#xD;
    ...&#xD;
  &amp;lt;/class&amp;gt;&#xD;
&amp;lt;/hibernate-mapping&amp;gt;&#xD;
&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;&lt;br /&gt;&lt;a name="r1"&gt;&lt;/a&gt;[1] 之所以使用 varchar2 而不是 nvarchar2，除了考虑 varchar2 可以节省空间之外，主要是为了避免 &lt;a href="http://blog.csdn.net/wh62592855/article/details/4896635" target="_blank"&gt;nvarchar2 排序时的性能问题&lt;/a&gt;。&lt;br /&gt;&lt;a name="r2"&gt;&lt;/a&gt;[2] 见 NHibernate-2.1.0.GA-src\src\NHibernate\Type\TypeFactory.cs 第 197 行。&lt;br /&gt;&lt;a name="r3"&gt;&lt;/a&gt;[3] 见&amp;nbsp;NHibernate-2.1.0.GA-src\src\NHibernate\Dialect\Oracle8iDialect.cs 第 92&amp;nbsp;行。&lt;br /&gt;&lt;a name="r4"&gt;&lt;/a&gt;[4] 见&amp;nbsp;NHibernate-2.1.0.GA-src\src\NHibernate\Dialect\Oracle8iDialect.cs 第&amp;nbsp;88&amp;nbsp;行。&lt;/p&gt;&#xD;
&lt;p style="text-align: center;"&gt;&lt;img src="http://images.cnblogs.com/cnblogs_com/1-2-3/113933/o_logo2_170_r.png" width="170" height="66" /&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/1-2-3/aggbug/2102436.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/1-2-3/archive/2011/07/12/nhibernate-guid-key-performance.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/1-2-3/archive/2011/07/04/restart-iis7-apppool.html</id><title type="text">重启 IIS7 应用程序池的批处理</title><summary type="text">重启 IIS7 应用程序池的批处理</summary><published>2011-07-04T15:00:00Z</published><updated>2011-07-04T15:00:00Z</updated><author><name>1-2-3</name><uri>http://www.cnblogs.com/1-2-3/</uri></author><link rel="alternate" href="http://www.cnblogs.com/1-2-3/archive/2011/07/04/restart-iis7-apppool.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/1-2-3/archive/2011/07/04/restart-iis7-apppool.html"/><content type="html">批处理很简单：&lt;br /&gt;c:\windows\system32\inetsrv\AppCmd.exe stop apppool /apppool.name:"ASP.NET v4.0"&lt;br /&gt;c:\windows\system32\inetsrv\AppCmd.exe start apppool /apppool.name:"ASP.NET v4.0"&lt;br /&gt;先Stop再Start就行。&lt;br /&gt;&lt;br /&gt;　　但是以前有过在IIS管理器里面停止应用程序池，然后马上启动，这时可能因为应用程序池还有些操作没完全完成而报错。所以我很害怕批处理里第二个启动应用程序池的命令也会有报错的可能性。所以为了安全起见我希望能先Sleep 1分钟再Start一下。但是批处理里没有Sleep命令，所以就用下面的方法模拟了一下。&lt;br /&gt;c:\windows\system32\inetsrv\AppCmd.exe stop apppool /apppool.name:"ASP.NET v4.0"&lt;br /&gt;c:\windows\system32\inetsrv\AppCmd.exe start apppool /apppool.name:"ASP.NET v4.0"&lt;br /&gt;ping -n 60 -w 1000 192.168.255.255&lt;br /&gt;c:\windows\system32\inetsrv\AppCmd.exe start apppool /apppool.name:"ASP.NET v4.0"&lt;img src="http://www.cnblogs.com/1-2-3/aggbug/2097822.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/1-2-3/archive/2011/07/04/restart-iis7-apppool.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/1-2-3/archive/2011/05/23/generate-permutation-part3.html</id><title type="text">白话算法(7) 生成全排列的几种思路(三) 邻位对换法</title><summary type="text">邻位对换法的规则/邻位对换法的图示/邻位对换法的源码/邻位对换法的原理</summary><published>2011-05-23T01:18:00Z</published><updated>2011-05-23T01:18:00Z</updated><author><name>1-2-3</name><uri>http://www.cnblogs.com/1-2-3/</uri></author><link rel="alternate" href="http://www.cnblogs.com/1-2-3/archive/2011/05/23/generate-permutation-part3.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/1-2-3/archive/2011/05/23/generate-permutation-part3.html"/><content type="html">　　可以直觉地知道，只要把数组任意相邻的两个元素交换位置，就可以得到一个新的排列。例如把数组 [1,2,3,4,5] 的&amp;nbsp;5 和&amp;nbsp;4 交换位置就得到 [1,2,3,5,4]，再把 5 和 3 交换位置就得到[1,2,5,3,4]&amp;hellip;&amp;hellip;这样不停地交换就能得到所有的（不重复的）排列吗？这里有两个问题：&lt;br /&gt;　　1）怎么知道交换相邻的两个元素就能得到所有的排列（还是说有时候也需要交换不相邻的元素）？&lt;br /&gt;　　2）要以何种顺序交换元素才能保证每次都得到新的（不重复）的排列呢？&lt;br /&gt;把5依次与前面的4、3、2、1交换位置其实等于把 5 插入到子数组 [1,2,3,4] 的所有可能的位置上得到新的排列。如果我们事先已经知道子数组 [1,2,3,4] 的所有排列，就可以把 5 插入到这些排列的所有可能的位置上得到数组 [1,2,3,4,5] 的所有排列。那么如何知道子数组 [1,2,3,4] 的所有排列呢？我们同样可以把 [1,2,3,4] 分解为 4 和子数组 [1,2,3]&amp;hellip;&amp;hellip;这样一直分解到子数组只剩一个元素时为止。按照这个思路，我们将得到一个普通的递归生成全排列的算法。不过邻位对换法使用的是另一种思路：为每个元素附加一个移动方向。&lt;br /&gt;&#xD;
&lt;div &gt;&#xD;
&lt;pre &gt;class Item&#xD;
{&#xD;
    public Item(string value, Item[] container, int index)&#xD;
    {&#xD;
        Value = value;&#xD;
        Direction = ItemDirection.Left; // 初始时方向默认指向左边&#xD;
    }&#xD;
    // 元素的值&#xD;
    public string Value { get; set; }&#xD;
&#xD;
    // 元素的移动方向&#xD;
    public ItemDirection Direction { get; set; }&#xD;
}&#xD;
enum ItemDirection&#xD;
{&#xD;
    Left = 0,&#xD;
    Right = 1&#xD;
}&#xD;
&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;br /&gt;有了这个移动方向之后，邻位对换法的规则就变得极其简单了：&lt;br /&gt;　　1）如果一个元素的移动方向所指向的那个邻位比它小，此元素就是可移的；相反，如果一个元素的移动方向所指向的那个邻位比它大，此元素就是不可移的。如果一个元素的移动方向上没有邻位，此元素也是不可移的。&lt;br /&gt;　　2）每次都是先寻找最大的可移元素 max，把它与移动方向所指向的那个邻位交换，然后把所有比 max 大的元素的移动方向反转。&lt;br /&gt;　　3）不断重复(2)，直到所有元素都不可移为止。&lt;br /&gt;下面演示数组 [1,2,3,4,5] 使用邻位对换法生成前 27&amp;nbsp;个排列的过程。&lt;br /&gt;&lt;img src="http://pic002.cnblogs.com/images/2011/25284/2011052213213768.png" /&gt;&lt;br /&gt;源码如下。&lt;br /&gt;&#xD;
&lt;div &gt;&#xD;
&lt;pre &gt;class Program&#xD;
{&#xD;
    static void Main(string[] args)&#xD;
    {&#xD;
        string[] source = new string[] { "1", "2", "3", "4", "5" };&#xD;
        foreach (IList&amp;lt;string&amp;gt; p in SwapPermutation(source))&#xD;
        {&#xD;
            Console.WriteLine(p.Montage(t =&amp;gt; t, " "));&#xD;
        } &#xD;
    }&#xD;
&#xD;
    // 使用邻位对换法生成全排列&#xD;
    static IEnumerable&amp;lt;IList&amp;lt;string&amp;gt;&amp;gt; SwapPermutation(string[] source)&#xD;
    {&#xD;
        yield return source.ToList(); // 第一个排列就是数组的初始顺序&#xD;
&#xD;
        LinkedList&amp;lt;Item&amp;gt; s = Item.Create(source); // 初始化&#xD;
&#xD;
        Item max = null;&#xD;
        while ((max = FindMaxMovableItem(s)) != null) // 寻找最大的可移元素 max&#xD;
        {&#xD;
            max.Move(); // 把 max 与移动方向所指向的那个邻位交换&#xD;
            yield return s.ToList(t =&amp;gt; t.Value); // 交换后产生了一个新的排列&#xD;
&#xD;
            // 把所有比 max 大的元素的移动方向反转&#xD;
            foreach (Item item in s)&#xD;
            {&#xD;
                if (item &amp;gt; max)&#xD;
                    item.ReverseDirection();&#xD;
            }&#xD;
        }&#xD;
    }&#xD;
&#xD;
    // 寻找最大的可移元素，找不到时返回null&#xD;
    static Item FindMaxMovableItem(LinkedList&amp;lt;Item&amp;gt; s)&#xD;
    {&#xD;
        Item max = null;&#xD;
        foreach (Item item in s)&#xD;
        {&#xD;
            if (item.IsMovable() &amp;amp;&amp;amp; (max == null || item &amp;gt; max))&#xD;
                max = item;&#xD;
        }&#xD;
        return max;&#xD;
    } &#xD;
}&#xD;
&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;br /&gt;Item的完整代码如下。&lt;br /&gt;&#xD;
&lt;div &gt;&#xD;
&lt;pre &gt;// 带有方向的元素&#xD;
[DebuggerDisplay("Value = {Value} Direction={Direction} Index = {Index}")]&#xD;
class Item&#xD;
{&#xD;
    public Item(string value)&#xD;
    {&#xD;
        Value = value;&#xD;
        Direction = ItemDirection.Left; // 初始时方向默认指向左边&#xD;
    }&#xD;
    // 元素的值&#xD;
    public string Value { get; set; }&#xD;
&#xD;
    // 元素的移动方向&#xD;
    public ItemDirection Direction { get; set; }&#xD;
&#xD;
    // 在链表中的节点&#xD;
    public LinkedListNode&amp;lt;Item&amp;gt; Node { get; set; }&#xD;
&#xD;
    // 初始创建&#xD;
    public static LinkedList&amp;lt;Item&amp;gt; Create(string[] source)&#xD;
    {&#xD;
        LinkedList&amp;lt;Item&amp;gt; result = new LinkedList&amp;lt;Item&amp;gt;();&#xD;
        for (int i = 0; i &amp;lt; source.Length; i++)&#xD;
        {&#xD;
            Item item = new Item(source[i]);&#xD;
            // 增加对链表中节点的反向引用，以便能够知道前一个和后一个节点是什么&#xD;
            item.Node = result.AddLast(item); &#xD;
        }&#xD;
        return result;&#xD;
    }&#xD;
&#xD;
    // 反转元素的移动方向&#xD;
    public void ReverseDirection()&#xD;
    {&#xD;
        if (Direction == ItemDirection.Left)&#xD;
            Direction = ItemDirection.Right;&#xD;
        else&#xD;
            Direction = ItemDirection.Left;&#xD;
    }&#xD;
&#xD;
    // 返回元素是否可移&#xD;
    public bool IsMovable()&#xD;
    {&#xD;
        // 如果一个元素的移动方向所指向的那个邻位比它小，此元素就是可移的；&#xD;
        // 相反，如果一个元素的移动方向所指向的那个邻位比它大，此元素就是不可移的。&#xD;
        // 如果一个元素的移动方向上没有邻位，此元素也是不可移的。&#xD;
        if (Direction == ItemDirection.Left) // 移动方向向左时&#xD;
        {&#xD;
            if (Node.Previous == null) // 已经是最左侧元素时&#xD;
                return false;&#xD;
            else&#xD;
                return Node.Previous.Value &amp;lt; this;&#xD;
        }&#xD;
        else // 移动方向向右时&#xD;
        {&#xD;
            if (Node.Next == null) // 已经是最右侧元素时&#xD;
                return false;&#xD;
            else&#xD;
                return Node.Next.Value &amp;lt; this;&#xD;
        }&#xD;
    }&#xD;
&#xD;
    // 与移动方向所指向的那个邻位交换&#xD;
    public void Move()&#xD;
    {&#xD;
        if (Direction == ItemDirection.Left) // 移动方向向左时&#xD;
        {&#xD;
            // 与左侧元素交换位置&#xD;
            Item temp = Node.Previous.Value;&#xD;
            Node.Previous.Value = this;&#xD;
            Node.Value = temp;&#xD;
&#xD;
            temp.Node = Node;&#xD;
            Node = Node.Previous;&#xD;
        }&#xD;
        else // 移动方向向右时&#xD;
        {&#xD;
            // 与右侧元素交换位置&#xD;
            Item temp = Node.Next.Value;&#xD;
            Node.Next.Value = this;&#xD;
            Node.Value = temp;&#xD;
&#xD;
            temp.Node = Node;&#xD;
            Node = Node.Next;&#xD;
        }&#xD;
    }&#xD;
&#xD;
    public static bool operator &amp;lt;(Item lhs, Item rhs)&#xD;
    {&#xD;
        if (lhs == null || rhs == null)&#xD;
            return false;&#xD;
        else&#xD;
            return lhs.Value.CompareTo(rhs.Value) &amp;lt; 0;&#xD;
    }&#xD;
    public static bool operator &amp;gt;(Item lhs, Item rhs)&#xD;
    {&#xD;
        if (lhs == null || rhs == null)&#xD;
            return false;&#xD;
        else&#xD;
            return lhs.Value.CompareTo(rhs.Value) &amp;gt; 0;&#xD;
    }&#xD;
}&#xD;
enum ItemDirection&#xD;
{&#xD;
    Left = 0,&#xD;
    Right = 1&#xD;
}&#xD;
&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;br /&gt;辅助函数Montage()和ToList()源码如下。&lt;br /&gt;&#xD;
&lt;div &gt;&#xD;
&lt;pre &gt;public static class EnumerableExtension&#xD;
{&#xD;
    /// &amp;lt;summary&amp;gt;&#xD;
    /// 将列表元素拼接成由splitter分隔的字符串&#xD;
    /// &amp;lt;/summary&amp;gt;&#xD;
    /// &amp;lt;example&amp;gt;&#xD;
    ///     拼接字符串：&#xD;
    ///         &amp;lt;c&amp;gt;new List&amp;lt;string&amp;gt; { "aa", "bb", "cc" }.Montage(p =&amp;gt; p, ","); // 返回："aa,bb,cc"&amp;lt;/c&amp;gt;&#xD;
    ///     拼接对象属性：&#xD;
    ///         &amp;lt;c&amp;gt;new List&amp;lt;string&amp;gt; { "aa", "bbb", "c" }.Montage(p =&amp;gt; p.Length.ToString(), ","); // 返回："2,3,1"&amp;lt;/c&amp;gt;&#xD;
    ///     拼接枚举值：&#xD;
    ///         &amp;lt;c&amp;gt;new List&amp;lt;DomainType&amp;gt; { DomainType.GuanHao, DomainType.YaoJiKe }.Montage(p =&amp;gt; ((int)p).ToString(), ","); // 返回："1,2"&amp;lt;/c&amp;gt;&#xD;
    ///     拼接枚举名：&#xD;
    ///         &amp;lt;c&amp;gt;new List&amp;lt;DomainType&amp;gt; { DomainType.GuanHao, DomainType.YaoJiKe }.Montage(p =&amp;gt; p.ToString(), ","); // 返回："GuanHao,YaoJiKe"&amp;lt;/c&amp;gt;&#xD;
    /// &amp;lt;/example&amp;gt;&#xD;
    /// &amp;lt;typeparam name="T"&amp;gt;&amp;lt;/typeparam&amp;gt;&#xD;
    /// &amp;lt;param name="source"&amp;gt;&amp;lt;/param&amp;gt;&#xD;
    /// &amp;lt;param name="toString"&amp;gt;将列表元素转换为字符串的委托&amp;lt;/param&amp;gt;&#xD;
    /// &amp;lt;param name="splitter"&amp;gt;分隔符（可为空）&amp;lt;/param&amp;gt;&#xD;
    /// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;&#xD;
    public static string Montage&amp;lt;T&amp;gt;(this IEnumerable&amp;lt;T&amp;gt; source, Func&amp;lt;T, string&amp;gt; toString, string splitter)&#xD;
    {&#xD;
        StringBuilder result = new StringBuilder();&#xD;
        splitter = splitter ?? string.Empty;&#xD;
        foreach (T item in source)&#xD;
        {&#xD;
            result.Append(toString(item));&#xD;
            result.Append(splitter);&#xD;
        }&#xD;
        string resultStr = result.ToString();&#xD;
        if (resultStr.EndsWith(splitter))&#xD;
            resultStr = resultStr.Remove(resultStr.Length - splitter.Length, splitter.Length);&#xD;
        return resultStr;&#xD;
    }&#xD;
&#xD;
    /// &amp;lt;summary&amp;gt;&#xD;
    /// 从泛型IEnumerable创建一个泛型List，每个元素由converter进行类型转换。&#xD;
    /// &amp;lt;/summary&amp;gt;&#xD;
    /// &amp;lt;example&amp;gt;&#xD;
    ///     将枚举List转换为Int32 List：&#xD;
    ///         &amp;lt;c&amp;gt;new DomainType[] { DomainType.GuanHao, DomainType.YaoJiKe }.ToList(p =&amp;gt; (int)p); // 返回：List&amp;lt;int&amp;gt;&amp;lt;/c&amp;gt;&#xD;
    /// &amp;lt;/example&amp;gt;&#xD;
    /// &amp;lt;typeparam name="TSource"&amp;gt;&amp;lt;/typeparam&amp;gt;&#xD;
    /// &amp;lt;typeparam name="TResult"&amp;gt;&amp;lt;/typeparam&amp;gt;&#xD;
    /// &amp;lt;param name="source"&amp;gt;&amp;lt;/param&amp;gt;&#xD;
    /// &amp;lt;param name="converter"&amp;gt;&amp;lt;/param&amp;gt;&#xD;
    /// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;&#xD;
    public static List&amp;lt;TResult&amp;gt; ToList&amp;lt;TSource, TResult&amp;gt;(this IEnumerable&amp;lt;TSource&amp;gt; source, Func&amp;lt;TSource, TResult&amp;gt; converter)&#xD;
    {&#xD;
        List&amp;lt;TResult&amp;gt; result = new List&amp;lt;TResult&amp;gt;();&#xD;
        foreach (TSource item in source)&#xD;
        {&#xD;
            result.Add(converter(item));&#xD;
        }&#xD;
        return result;&#xD;
    }&#xD;
}&#xD;
&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;&lt;br /&gt;&lt;strong&gt;注意&lt;/strong&gt;：当最大可移元素是整个数组里最大的那个元素时（本例中是5），可以省略&amp;ldquo;把所有比 max 大的元素的移动方向反转&amp;rdquo;那一步，而且只要5是可移的它就一定是最大可移元素，所以可以一直移动5直到不能移动再调用FindMaxMovableItem()&amp;nbsp;。上面的源码为了简单起见没有做这些工作。&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #008000;"&gt;&lt;strong&gt;邻位对换法的原理&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;　　邻位对换法的规则乍一看既简单又奇妙，其实它与本文开篇所提到的递归生成全排列的算法本质上是相同的。在5从最右侧移动到最左侧之后，一定要先使得子数组[1,2,3,4]变成下一个排列[1,2,4,3]，再让5从最左侧移动到最右侧。对于子数组[1,2,3,4]来说，同样是先把4从子数组[1,2,3]的最右侧移动的最左侧，然后让子数组[1,2,3]变成下一个排列[1,3,2]，再让4从它的最左侧移动到最右侧&amp;hellip;&amp;hellip;只不过如果没有递归时的堆栈来保存每一层进行到哪里了，怎么知道每一步应该移动5还是4抑或是3呢？这里必须要先观察得到2个重要的规律，&lt;br /&gt;　　1）只有元素从子数组的一侧移动到另一侧之后才需要把子数组变换成下一个排列。例如只有当4从子数组[1,2,3]的最右侧移动的最左侧之后，才需要让子数组[1,2,3]变成下一个排列[1,3,2]。&lt;br /&gt;　　2）元素一定比子数组中的任何一个元素都大。例如5比子数组[1,2,3,4]的每一个元素都大；4比子数组[1,2,3]的每一个元素都大。&lt;br /&gt;接着我们列出需要知道的3个信息，&lt;br /&gt;　　1）每个元素下一步的移动方向。&lt;br /&gt;　　2）每个元素是否已经移动到了子数组的最左侧或最右侧。&lt;br /&gt;　　3）每一步应该移动哪个元素。&lt;br /&gt;根据上面的2个规律，我们只要为每一个元素增加一个移动方向属性就可以知道这3个信息。首先，当一个元素的移动方向上的邻位比它大或者没有元素时，说明此元素已经到了边界，它暂时不可移，&amp;ldquo;递归&amp;rdquo;要下降一层。如果下一层的最大元素也到了边界，就再下降一层。当把子数组变换成新的排列时，再从最上层开始移动元素。&amp;ldquo;移动方向&amp;rdquo;属性既保存了移动方向信息，同时也可用于判断元素是否已经移动到了边界。&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;思考题&lt;/strong&gt; 请比较邻位对换法里的&amp;ldquo;递归&amp;rdquo;与真正的递归方法的区别，然后看看能否写出一个不一样的《盗梦空间》出来。&lt;/p&gt;&#xD;
&lt;p style="text-align: center;"&gt;&lt;img height="66" width="170" src="http://images.cnblogs.com/cnblogs_com/1-2-3/113933/o_logo2_170_r.png" /&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/1-2-3/aggbug/2053473.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/1-2-3/archive/2011/05/23/generate-permutation-part3.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/1-2-3/archive/2011/05/15/diary-2011-05-15.html</id><title type="text">[日记]大局观和细节</title><summary type="text">没在细节上下过苦功就想以大局观取胜，这就是3流选手一辈子都是3流选手的原因。</summary><published>2011-05-15T12:58:00Z</published><updated>2011-05-15T12:58:00Z</updated><author><name>1-2-3</name><uri>http://www.cnblogs.com/1-2-3/</uri></author><link rel="alternate" href="http://www.cnblogs.com/1-2-3/archive/2011/05/15/diary-2011-05-15.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/1-2-3/archive/2011/05/15/diary-2011-05-15.html"/><content type="html">&lt;p&gt;最近买了个爱泡的他去死来玩。本来已经很长时间没玩游戏了，还是忍不住下载了一大推很可爱的可以 Touch 的小游戏。这其中有一个很专业的围棋教学游戏 &lt;a target="_blank" href="http://mobile.91.com/Soft/iPhone/smartgo-pro-1.7.1.html"&gt;SmartGo Pro(官方中文版)&lt;/a&gt;，自带20000局职业对局和2000道死活题，入门教程很细致，当然也支持人机对战。想想我也是知道围棋规则的人，还煞有介事地观看过体育频道讲解大师的比赛，什么&amp;ldquo;势&amp;rdquo;啦，&amp;ldquo;棋形&amp;rdquo;啦，&amp;ldquo;手筋&amp;rdquo;啦，听得半懂不懂地，但是感觉很酷。&amp;ldquo;下棋最重要的是什么？当然是大局观啦。着眼于全局，不断积累胜势，在恰当的时候发起攻击，这方面电脑肯定不如我啦。&amp;rdquo;怀着这种想虐虐电脑的兴奋心情，开始新手对局。第一局电脑让我3个子，轻松取胜，一下子从7级升到了10级。第二局电脑让我2个子，我一开始下的像模像样，可是总是失误让电脑提子，结果连输3局，最后降为7级打回原形了。&lt;br /&gt;　　心里很不爽，不仅是因为输给了白痴电脑，还因为想到自己这辈子不管干什么都是3流水平。没在细节上下过苦功就想以大局观取胜，这就是3流选手一辈子都是3流选手的原因。没有对细节的精确把握，拿什么作为决策的依据呢？没有基础的大局观，不过是自欺欺人的撞大运罢了。&lt;br /&gt;　　所谓大师级选手一定是在大局观和细节上都登峰造极的人，这是很显然的。但是容易忽略的一点是，他们是先锻炼的大局观，还是先注意的细节呢？当然是&amp;ldquo;同时&amp;rdquo;&amp;mdash;&amp;mdash;没听说过有哪个大师是小时候一直摆棋谱不对弈的。但是就是这个&amp;ldquo;同时&amp;rdquo;害人。因为对弈的乐趣远大于摆棋谱、做死活题。最后业余选手大多身经百战但是战漏洞百出，而且就算他再有天赋也无法发挥出来&amp;mdash;&amp;mdash;只有把细节技术练成下意识的&amp;ldquo;感觉&amp;rdquo;，才能给大脑留出空间着眼于全局。&lt;br /&gt;　　好吧细节很重要。但是很多时候并不是我们没有意识到细节的重要性，而是掉进了一个心理上的陷阱&amp;mdash;&amp;mdash;我们必须有意识地推迟满足感。比如练字的时候，本来应该先把每个笔画逐个练好。但是在写字的时候，如果把注意力放在每个笔画上，写出来的字就会非常难看，惨不忍睹；如果注意整体结构的话，感觉一下子好看了很多。于是一开始的时候，我们就不知不觉地被这个因素控制住了，到达一定的程度之后，当细节因素成为瓶颈的时候，我们更加不愿倒退到原始阶段，于是停滞不前。所以脸皮一定要厚一点，不要以做基础练习为耻，也不要急于达到普通水平。&lt;br /&gt;　　今天好好反省了一下，一口气做了100道入门练习和400道死活题。但是死活题还有2000多道呐，明天工作一忙起来恐怕今天学的东东全都会忘记了。练习密度也是很重要的。可是如果不是一个很偏执的人，又怎么会坚持每天花大把的时间在一件事情上呢？于是我们的时间在断断续续中浪费掉了，这是个很难解决的问题。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/1-2-3/aggbug/2047085.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/1-2-3/archive/2011/05/15/diary-2011-05-15.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/1-2-3/archive/2011/04/30/diary-2011-04-30.html</id><title type="text">[日记]初中时写的一篇日记</title><summary type="text">在抽屉里翻出来10几张破纸，发现竟然是初中时写的日记。那时候的字和现在不一样，写的什么也早就忘了，好像是在读着另一个人写的东西似的，恍如隔世啊！有一篇还挺有意思的，下面原文抄录。</summary><published>2011-04-30T14:27:00Z</published><updated>2011-04-30T14:27:00Z</updated><author><name>1-2-3</name><uri>http://www.cnblogs.com/1-2-3/</uri></author><link rel="alternate" href="http://www.cnblogs.com/1-2-3/archive/2011/04/30/diary-2011-04-30.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/1-2-3/archive/2011/04/30/diary-2011-04-30.html"/><content type="html">&lt;p&gt;在抽屉里翻出来10几张破纸，竟然是初中时写的日记。那时候的字和现在不一样，写的什么也早就忘了，好像是在读着另一个人写的东西似的，恍如隔世啊！有一篇还挺有意思的，下面原文抄录。&lt;br /&gt;&lt;br /&gt;　　我梦见我似乎是一个很有名气的作家。&lt;br /&gt;　　我坐在一个漂亮的写字台旁，心想，既然是作家，就应该写点什么出来。可是当我拿起笔，望着那厚厚的一叠稿纸，却连一个字也写不出来了。我想：&amp;ldquo;这是不可能的！既然我是一个作家，就一定能写出很好的文章！&amp;rdquo;可是仍然没写出一个字来。&lt;br /&gt;　　我的笔开始抖了起来。于是我就在纸上写：&amp;ldquo;我的笔开始抖起来了。&amp;rdquo;可是接下去该怎么写呢？我的脑子里仍像这纸一样白。&lt;br /&gt;　　我有些害怕了，心想：&amp;ldquo;我这样算是什么作家呢？&amp;rdquo;这时我突然发现，原来我浑身都已被汗水浸透了。我开始懊丧起来了，心想，我这个作家怕是当不成了。&lt;br /&gt;　　&amp;ldquo;我也许是用左手写作的呢！&amp;rdquo;我突然有了一丝希望，马上把笔由右手交到左手，它果然飞快地动起来！我真有一种刑满释放时的感觉，连忙把它放到那句&amp;ldquo;我的笔开始抖起来了。&amp;rdquo;的后面。糟糕，从右往左的字迹把先前的那句话给盖住了，结果两句话都模模糊糊的，不过没关系，它又飞快地接着往下写了。不一会儿，它就写满了一页，我真是高兴的不得了。就这样，我用右手翻页，左手写字，稿纸飞快地向后翻去。我心想，这才是大作家写作时的风度！&lt;br /&gt;　　我的左手又酸又痛，可是心里却像喝了蜜一样甜。是啊，一个作家最幸福的时刻不正是他急书的那一瞬么？&lt;br /&gt;　　终于，我写完了那厚厚的一叠纸，痛快地把笔往窗外一扔，重重地靠在椅背上，长吁一口气。心想，终于又有一篇大作问世了，我的书迷会怎样高兴呢？对了！我不能在这里偷懒，我要马上校订原稿，赶快让它出版！我支撑起来，拿起稿纸，翻到第一页，只见上面除第一句模糊看不清外，通篇都写着：&amp;ldquo;我的名字叫右手，我的名字叫右手&amp;hellip;&amp;hellip;&amp;rdquo;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/1-2-3/aggbug/2033611.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/1-2-3/archive/2011/04/30/diary-2011-04-30.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry></feed>
