Category Archives: IT

The industrial worker in the time of Electronic Computer likes The industrial worker in the time of Steam power?



PCDATA – Parsed Character Data

CDATA – (Unparsed) Character Data

XML Escapse Character

Keywords for search:

XML, Parse, Escape Character

Case Study on HTML <pre> stylish

by Aivboh


所以,如果要在常用的<pre>上用stylish,在里面用<div>, <span> 就可以了。


SQL: JOIN vs IN vs EXISTS – the Logical difference

原来 pre tag 也可以加style。


倒没说 left join 的问题。

SQL Server: JOIN vs IN vs EXISTS – the logical difference

Monday, March 18, 2013 I want some Moore

We’ve all written a CASE expression (yes, it’s an expression and not a statement) or two every now and then. But did you know there are actually 2 formats you can write the CASE expression in? This actually bit me when I was trying to add some new functionality to an old stored procedure. In some rare cases the stored procedure just didn’t work correctly. After a quick look it turned out to be a CASE expression problem when dealing with NULLS.

In the first format we make simple “equals to” comparisons to a value:

WHEN <equals this value> THEN <return this>

WHEN <equals this value> THEN <return this>
-- ... more WHEN's here
ELSE <return this>

Second format is much more flexible since it allows for complex conditions. USE THIS ONE!

WHEN <value> <compared to> <value> THEN <return this>
WHEN <value> <compared to> <value> THEN <return this>
-- ... more WHEN's here
ELSE <return this>

Now that we know both formats and you know which to use (the second one if that hasn’t been clear enough) here’s an example how the first format WILL make your evaluation logic WRONG.

Run the following code for different values of @i. Just comment out any 2 out of 3 “SELECT @i =” statements.

SELECT  @i = -1 -- first result
SELECT  @i = 55 -- second result
SELECT  @i = NULL -- third result

SELECT @i AS OriginalValue,

-- first CASE format. DON'T USE THIS!
WHEN -1 THEN '-1'
ELSE 'We landed in ELSE'
END AS DontUseThisCaseFormatValue,

-- second CASE format. USE THIS!
WHEN @i = -1 THEN '-1'
WHEN @i IS NULL THEN 'We have a NULL!'
ELSE 'We landed in ELSE'
END AS UseThisCaseFormatValue

When the value of @i is –1 everything works as expected, since both formats go into the –1 WHEN branch.


When the value of @i is 55 everything again works as expected, since both formats go into the ELSE branch.


When the value of @i is NULL the problems become evident. The first format doesn’t go into the WHEN NULL branch because it makes an equality comparison between two NULLs.
Because a NULL is an unknown value: NULL = NULL is false. That is why the first format goes into the ELSE Branch but the second format correctly handles the proper IS NULL comparison.


Please use the second more explicit format. Your future self will be very grateful to you when he doesn’t have to discover these kinds of bugs.

How to open a Windows command prompt

In current folder.

1 Ordinary method

Shift + Right Click

Then click

How to open a Windows command prompt[1]

2 Run as administrator

Copy a shortcut of Command prompt. Change the “start in” property.

How to open a Windows command prompt[2]

Copy to any folder you want to run it. With this, you can open a prompt with administrator permission.

Internet Explorer Operation Aborted


Cannot open Internet website, Operation Aborted


Happens in

  • Microsoft Internet Explorer 6.0
  • Windows Internet Explorer 7


Unsupported code syntax.


Upgrade to Internet Explorer 8

Why do I receive an “Operation aborted” error message when I visit a Web page in Internet Explorer?

What Happened to Operation Aborted?

Windows Setup Hangs

最近遇到了一个很古怪的问题。在笔记本上安装Windows 8 时候,安装程序反应极慢。

在网络搜索半天,也没找到能够解决问题的方法。后来,试了几个英文Keywords,找到了来自Windows Support的解答 ——

Windows Setup Hangs When “Setup Is Starting Windows” Screen Appears

根据文章,看来是硬件驱动的问题,建议禁用一部分硬件尝试安装。试了几次,发现拔下插着的SD卡就好了。整个安装过程非常快,原来等一个晚上都不见动弹的 OTL。

在进入Windows 8 之后,发现确实是读卡器驱动的问题。尽管在Lenovo Thinkpad 的官方网站上,查找驱动库里会注明读卡器驱动是使用Windows 8 预打包,但是如果不另行下载Windows 7 驱动安装的话,读卡器是不会正常工作的。

Keywords for search:

Windows setup, Setup is starting windows, no response, stop

Windows 8 安装,不动,没有反应

IntelliJ IDEA Settings

1 Configuration


2 Issues

It was painful when the first time I switched from MyEclipse to IntelliJ IDEA. Well, it was because the source codes were a mess though.

2.1 Move Maven repository location.

I want to manage my profile folder structure, so I have changed the location of many of them. After the IntelliJ IDEA installation, I found there are two directories under my profile folder. One is called “.m2” and the other one is “.IntelliJIdea”.

After many tries, I failed to figure out a way of moving them. Although there are some environment variable settings in the option, none of them work for me.

The location of them seems to be related to the location of your Desktop folder. But this is only my assumption.

I found this after that I installed Windows 8 and redesign the layer of my profile storage. I like the new layer which seems cleaner so I copied them to Windows 7. Then I found this issue was accidently solved – both .m2 and .IntelliJIdea are moved to a location that I liked.

2.2 Cannot display Chinese.

Well, this is the most issues I met. I strongly request Jetbrains the compilation.

At first, I should point out that this almost happens in every IDE. Either you will met them in the application, or in the source codes, or in your compiled program.

2.2.1 Font

The first thing you need to do to choose a correct font which support your language. As the simplified Chinese, many mono-spaced fonts doesn’t have this support. Well, although they seems OK in many Windows application when displaying Chinese, the OS has done a great job for you under the surface.

If you choose a appropriate font, in most cases, your source code should be displayed without malformed text. If it doesn’t work, then check out the below section.

2.2.2 File encoding

The second thing you could do is configuring your application. You could find them in IntelliJ IDEA -> settings -> file encodings.

IntelliJ IDEA Settings[1]

You should keep the properties as default because this is a standard.

IntelliJ IDEA Settings[3]

This will solve the second common error – File encoding.

Besides this, look at the bottom. You will find a way to specify the encoding for a single file.

IntelliJ IDEA Settings[2]

After the above steps, your source code should have been display completely correctly. If it still doesn’t work, I believe it is the problem of this file.

But what you see is not always as same as your get. Not like MyEclipse, the encoding settings for single files not automatically considered in the process of compilation. This is reason why you got malformed text in the program. Then we switch to the next approach.

The best way to solve it is to do it in UTF-8 (without BOM) at the beginning of your work. However, by default, it is in ANSI which is usually GBK for Windows CHS (ANSI is different regarding to your operating system).

To take remedial measures, for MyEclipse, you need to change all your project file encoding setting to GBK or UTF-8 or any other encodings. Just all your files. In MyEclipse, your won’t need to do this though. You just need to turn a switch for this single file.

Well, I strongly request Jetbrains enhance the compilation module to make it more smarter. I processed a chunk of codes and they were wrote in different encodings. It’s fine when in MyEclipse but I have to convert them when in IntelliJ IDEA.

There may by a way to get around with by using Eclipse compiler. But I failed to find a manual to make it work. I found a help from Ecplise (Compiling Java Code) which tells how to add settings for specified files but it didn’t work for me. If anyone knows how to do it, please tell me.

IntelliJ IDEA Settings[4]

2.2.3 Wrong codes

If above doesn’t help get out of the mess, then I believed it is because of your codes. The Internet has examples for this and I am not going to place them in this article since it is not doing with this IDE.


2.3 Module dependency.

Configure project framework supports

Right click. You will see a menu called “add framework”. If you don’t have the libraries of some commonly used such as spring, hibernate, you may try the “add framework” approach. It will download them for you.

Import libraries.

Also under the module dependency tab. You can choose to add user libraries, jars, etc.

2.4 Edit the file

2.4.1 Where is the function list?

Look at the left bottom. There is a structure windows.

I didn’t find it. Yes, I did!! :(

2.5 Search

Ctrl+Shift+N to search file.

Ctrl+Shift+F to search text.

2.7 VCS undo add (or Move versioned files to unversion)

The fist case is that the file you just added was not versioned and it was not in the repository.

To make a undo is doing the revert. There is no second solution.

The second case is that the file has been versioned and you want to be moved to unversion category.

You have to mark them for delete. For SVN, svn rm –keep-local [file]

2.5 Tomcat deployment.

The URL is configured directly in “Run/Debug Configuration”, which is combined with Server page and Deployment page.

There are 5 things you need to do.

First, add a artifact in Project Structure. You can choose the output directory here. By default, it is $PROJECT_DIR$/.out. The IntelliJ IDEA maps the URL of your application to here. You can change it to the ordinary way which is putting the output under webapp folder.

Second, add an application server in Run/Debug Configuration.

Third, select the server you added.

Fourth, select artifact you added in the Deployment tab. You can keep the Application context as the default, which is just a /. You can also change it you any name your want. But I recommend that set it as same as the name of your artifact. For example, if the artifact is EG, then the context is /EG.

Fifth, go back to Server tab. You find the startup page is different from the first time you see it. If your doesn’t have configuration for the start page somewhere. Then you need to append it here. If the URL is …/EG, then you append your page to the URL which becomes …/EG/your page.

2.5.1 Error running Default: Unable to open debugger port: “socket closed”

This error is popped out because there are something wrong with the JVM.

I came across this error because I modified the catalina.bat. I added a JAVA_OPTS configuration in this file. It seems IntelliJ IDEA doesn’t like this approach and perhaps it more prefers configuring it in its settings (After all I see such a space).

After I removed it, this error disappeared.

2.5.2 Tomcat dynamic updates.

Some articles say I need plugins to support this feature. But it seems no. In my situation, when I modified something, the IDE does update the resource and I can see the modification I made from the browser.

But just in case, if you don’t get the dynamically updating, you can select “update classes and sources” option.

Sometimes, you may get to need manual operations when something is wrong. Make the project.

2.5.3 Simultaneously debug multiple application via a single Application server instance.

Won’t be able to do this as what can be done in Eclipse. At least I failed to find it.


Keywords for look up:

IntelliJ IDEA,中文,乱码,Tomcat,设置


IntelliJ IDEA 中文乱码解决办法



Firefox settings

1 Errors

1.1 sec_error_reused_issuer_and_serial

I encountered this error after every GoAgent update and finally this solved my problem.

Copy from

One of the thing I hate about firefox is that when you have internal certificates like those issued by HP Integrated Lights-Out’s (iLO) web page, you have to confirm to download the cert and add it to your cert store. There is no one-click solution to this as yet and neither can I disable this in FireFox even if I only intend to use it in an intranet environment.

More troublesome is when I update the firmware in my iLO and hence a new certificate is generated and when you try to launch the web page for iLO access again you will encounter the following error.

Error code: sec_error_reused_issuer_and_serial

It took me a while to figure it out from googling, and the solution is very simple. Just delete the cert8.db from your FireFox profile, who is usually found in C:\Documents and Settings\\Application Data\Mozilla\Firefox\Profiles\. The easier way is just searching for cert8.db in your computer and delete that file.

2 Add-ons

Personal favorite add-ons. Constantly updates.

Adblock Plus: Deal with ads.

Easy Access: Helpful tools developed by Mozilla CN.

Firebug:  Intercept their websites.:)

HttpFox: Craft Http request. Don’t be evil~ :)

HttpRequester: Monitoring Http traffic.

EPUBReader: Read epub files. Can also help you figure out how to parse them.

Flash Video Downloader: Download valuable videos.

Clearly: Helpful tool delivered by Evernote. The best clip tools ever used.


Source has been invalid. Unable to complete ref notes.


Date here 刘未鹏




  1. 算法本身就很难。也就是说,算法这个东西对于人类的大脑来说本身就是个困难的事儿。
  2. 讲得太烂。





必须说明的是,没有哪位作者是故意这样做的,但任何人在讲解一个自己已经理解了的东西的时候,往往会无意识地对自己的讲解进行“线性化”,例如证明题,如果你回忆一下高中做平面几何证明题的经历,就会意识到,其实证明的过程是一个充满了试错,联想,反推,特例,修改问题条件,穷举等等一干“非线性” 思维的,混乱不堪的过程,而并不像写在课本上那样——引理1,引理2,定理1,定理2,一口气直到最终结论。这样的证明过程也许容易理解,但绝对不容易记忆。过几天你就会忘记其中一个或几个引理,其中的一步或几步关键的手法,然后当你想要回过头来自己试着去证明的时候,就会发现卡在某个关键的地方,为什么会这样?因为证明当中并没有告诉你为什么作者当时会想到证明算法需要那么一个引理或手法,所以,虽说看完证明之后,对算法这个结论而言你是知其所以然了,但对于算法的证明过程你却还没知其所以然。在我们大脑的记忆系统当中,新的知识必须要和既有的知识建立联系,才容易被回忆起来(《如何有效地学习与记忆》),联系越多,越容易回忆,而一个天外飞仙似地引理,和我们既有的知识没有半毛钱联系,没娘的孩子没人疼,自然容易被遗忘。(为什么还原思维过程如此困难呢?我曾经在知其所以然(一)里详述)



如果说以上提到的算法难度(讲解和记忆的难度)属于Accidental Complexity的话,算法的另一个难处便是Essential Complexity了:算法设计。还是拿数学证明来类比(如果你看过《Introduction to Algorithms:A Creative Approach》就知道算法和数学证明是多么类似。),与单单只需证明相比,设计算法的难处在于,定理和证明都需要你去探索,尤其是前者——你需要去自行发现关键的那(几)个定理,跟证明已知结论相比(已经确定知道结论是正确的了,你只需要用逻辑来连接结论和条件),这件事情的复杂度往往又难上一个数量级。


  1. 一劳永逸:程序员都知道“一次编写到处运行”的好处,多省事啊。学了就忘,忘了又得学,翻来覆去浪费生命。为什么不能看了一遍就再也不会忘掉呢?到底是教的不好,还是学得不好?
  2. 事半功倍:事实上,程序员不仅讲究一次编写到处运行,更讲究“一次编写到处使用”(也就是俗称的“复用”)。如果学一个算法所得到的经验可以到处使用,学一当十,推而广之,时间的利用效率便会大大提高。究竟怎样学习,才能够使得经验的外推(extrapolate)效率达到最大呢?





首先它给出了一棵编码树的cost function:

cost of tree = Σ freq(i) * depth(i)

这个cost function很直白,就是把编码的定义复述了一遍。但是接下来就说了:

There is another way to write this cost function that is very helpful. Although we are only given frequencies for the leaves, we can define the frequency of any internal node to be the sum of the frequencies of its descendant leaves; this is, after all, the number of times the internal node is visited during encoding or decoding…

接着就按照这个思路把cost function转换了一下:

The cost of a tree is the sum of the frequencies of all leaves and internal nodes, except the root.


The first formulation of the cost function tells us that the two symbols with the smallest frequencies must be at the bottom of the optimal tree, as children of the lowest internal node (this internal node has two children since the tree is full). Otherwise, swapping these two symbols with whatever is lowest in the tree would improve the encoding.

This suggests that we start constructing the tree greedily: find the two symbols with the smallest frequencies, say i and j, and make them children of a new node, which then has frequency fi + fj. To keep the notation simple, let’s just assume these are f1 and f2. By the second formulation of the cost function, any tree in which f1 and f2 are sibling-leaves has cost f1 + f2 plus the cost for a tree with n – 1 leaves of frequencies (f1 + f2), f3, f4, .., fn. The latter problem is just a smaller version of the one we started with.


  1. 觉得理所当然。
  2. 觉得恍然大悟。


如果看完霍夫曼编码这样一个简短证明你觉得顺理成章,一切都挺显然,那就坏了,即便是看上去最基本的性质也往往实际上没那么显然。“逢山开路,遇水架桥”在我们今天看来是无比显然的事实,但是试想在没有桥的远古时代,一个原始人走到一条湍急的河流前,他会怎么想,他又能有什么法子呢?这是个他从来没有遇见过的问题。如果后来有一天,他路过另外一条小溪,看到小溪上有一截被闪电劈断的枯树,于是他踏着树干走过了小溪,并意识到“树横过河面”可以达到“过河”这个目的,这就将条件和目的建立了直接的联系(事实上,是自然界展示了这个联系,我们的原始人只是记住了这个联系)。后来他又路过那条河流,他寻思如何达到“过河”这个目的的时候,忽然意识到在他的记忆中已经遇到过需要达成同样目的的时候了,那个时候的条件是“树横过河面”,于是问题便归结为如何满足这个“树横过河面”的条件,而后一个问题就简单多了。(事实上波利亚在他的著作《How to Solve it》中举的正是这么个例子)



  1. 作者轻飘飘地就给出了cost function的另外一种关键的描述,而对于如何发现这种描述却只是一语带过:”There is another way to write this cost function that is very helpful.. we can define the frequency of any internal node to be the sum of the frequencies of its descendant leaves“这其实就是我常常痛恨的“我们考虑…”,这里作者其实就是在说”让我们考虑下面这样一种奇妙的转换“,可是怎么来的却不说。但必须承认,《Algorithms》的作者还是算厚道的,因为后面他又稍微解释了一下:“this is, after all, the number of times the internal node is visited during encoding or decoding…”这个解释就有点让人恍然大悟了,但是千万别忘了,这种恍然大悟是一种错觉,你还是没明白为什么他会想到这一点。这就像是作者对你说“仔细观察问题条件,我们容易发现这样一种奇妙的性质..”,怎么个“仔细”法?凭什么我自己“观察”半天就是发现不了呢?霍夫曼本人难道也是死死盯着问题“观察”了一学期然后就“发现”了么?我们有理由相信霍夫曼肯定尝试了各种各样的方法,作出了各种各样的努力,否则当年Shannon都没搞定的这个问题花了他一学期,难道他在这个学期里面大脑就一片空白(或者所有的尝试全都是完全不相干的徒劳),然后到学期末尾忽然“灵光一现”吗?
  2. 如果“仔细观察”:),我们会发现两个cost function表达中frequency的概念有微妙的差异,在第一个cost function中,只有叶子节点有frequency,而这个frequency必须和叶子节点的深度相乘。而在第二个cost function中,内部节点也具有了frequency,可是所有节点的“frequency”忽然全都不跟深度相乘了。frequency的不同含义令人困惑。

作者提到:第一个cost function告诉我们频率最低的两个节点必然处于最优编码树的底端,作为最低内部节点的两个子节点。这是一个不严谨的说法,从前文给出的条件和性质,只能推导出频率最低的两个节点必然处于编码树的最底层,但未必一定要是兄弟节点,如果树的最底层不止能容纳两个节点的话它们就可以有不同的父节点。“我们不妨考虑”这样一个例子:对A,B,C,D四个字母进行编码,假设它们的频率分别是1, 1, 2, 2。这个时候我们可以构造如下图所示的两棵树,两棵树的cost都是12,都是最优的。但其中一棵树中,两个频率最低的节点并非兄弟。







回到霍夫曼编码问题,按照这个原则,我们会去假设已经得到了最优编码树,那么我们能够发现关于它的什么性质呢?这里又要提到另一个适用于很多最优化问题的原则(前面提到的原则适用于一般性搜索问题),所谓最优解,就是说比其他所有解都要更好,虽然这句话听上去像是废话,但是它的一个直接推论——比与它邻近的所有候选解都要好—— 就是一个非常有用的,不是废话的性质了。学过微积分的都知道,光滑函数的最值点必然是大(小)于其邻域内的所有点的,然后再根据这个就自然推出该点的一阶导数(切线斜率)必然为0的性质,这个性质(必要条件)让我们直接省掉了去整个区间内搜索的麻烦,从而可以直接锁定有限几个候选解。那么,既然我们说最优霍夫曼树一定比它“附近”的树更好,我们就想看看,怎么来找到它附近的树。我们知道要从一个点到它附近,往往是对这个点进行一些调整,例如N+1是到达附近的另一个整数。霍夫曼树是一棵树,所以对这棵树的所有的一次“改动”(或“折腾”)都能够到达与它的“改动”距离为1的点(是不是想起“编辑距离”这个概念),怎么改动呢?最符合直觉的(虽然并不是唯一的)改动便是把叶子节点进行互换。


  • 在最优霍夫曼树中,无论互换哪两个叶子节点,得到的树都变得更“差”。(严格来说是不会变得更“好”,因为最优树未必唯一)


上面这个性质究竟意味着什么呢?如果你假设这两个叶子节点的频率为f1和f2,深度为d1和d2,互换它们的时候,其他叶子节点的cost保持不变,令为常量 C,那么互换前总cost为C+f1d1+f2d2,互换后为C+f1d2+f2d1,既然互换之后的树一定更”差“那么就是说 f1d1+f2d2 < f1d2 + f2d1,简单变换一下就得到结论:f1(d1-d2)<f2(d1-d2),也就是说如果d1<d2,那么f1必然>f2,如果 d1>d2,那么f1必然<f2。换言之就是叶子节点的深度越高,频率必须越低,否则就不可能是最优霍夫曼树。那么,之前我们觉得不那么显然的结论便呼之欲出了:频率最低的叶子节点必然位于树的最底层,频率最高的叶子节点必然位于树的最高层。










  • 在最优霍夫曼树中,无论互换哪两个节点,得到的树都变得更“差”(交换内部节点则是连同该内部节点作为局部根的子树一同带走)




回到刚才我们的推论:在最优霍夫曼树中,无论互换哪两个节点,得到的树都变得更“差”(交换内部节点则是连同该内部节点作为局部根的子树一同带走) 。依葫芦画瓢我们容易计算出,在最优霍夫曼树当中,两个内部节点n1和n2,如果n1比n2更深,那么n1下面的所有叶子的频率之和必然要小于n2下面所有叶子的频率之和。如果交换的是一个内部节点和一个叶子节点,则道理是类似的。这个性质的证明和上面的类似,就不赘述了。

这个性质暗示了一个重要的推广结论:如果我们把每个内部节点的所有叶子的频率之和标在它旁边,那么整棵树的每个节点便都有了一个数值,这个数值遵循统一的规律:即越往深层越小。这就意味着,我们刚才的二选一困境有办法了!当我们将最小的两个叶子f1和f2合并的时候,生成了一个新的节点M,这个节点有一个数字(为两个叶子的频率之和f1+f2),根据上面的推论,这个数字f1+f2跟所有频率一同,遵循最小的在最底层的原则,所以我们下一步必须在剩下的那些互相之间关系待确定的节点(叶子节点和内部节点)之中,即{(f1 + f2), f3, f4}里面选择最小的两个数字结合成兄弟(由于f1和f2这两个节点已经铁板钉钉结为整体了,所以从集合里面可以看做移除)。到这里,我们就发现递归已经出现了,接下去的过程对于绝大多数人应该就真的很显然了。



还有,其实以上只是试图给出最优霍夫曼树的证明的一个更自然的过程,而当年霍夫曼面临这个问题的时候根本还没有人想到要用二叉树呢!更不要说在二叉树的前提之下进行证明了。根据wikipedia的介绍,霍夫曼同学(当年还在读Ph.D,所以的确是“同学”,而这个问题是坑爹的导师Robert M. Fano给他们作为大作业的,Fano自己和Shannon合作给出了一个suboptimal的编码方案,为得不到optimal的方案而寝食难安,情急之下便死马当活马医扔给他的学生们了)当年为这个问题憔悴了一个学期,最后就快到deadline的时候“忽然”想到二叉树这个等价模型,然后在这个模型下三下五除二就搞定了一篇流芳千古的论文,超越了其导师。


最适合将一个东西讲给别人听的时候并不是等懂了很多年以后,而是刚刚弄懂的时候,这个时候从不懂到懂的差别记忆还非常鲜明,能够清清楚楚地记得到底是哪些关键的地方是最折磨人的,也最能够站在不懂者的角度来思考问题。像波利亚这样,成了大师还能够站在不懂者角度去换位思考的,可以说是凤毛麟角。所以说前Amazon CAO(首席算法官)的《Introduction to Algorithms: a Creative Approach》绝对是本罕见的好算法书)




  1. 不要觉得每个步骤都很显然,每个nontrivial的算法背后都有一段艰辛的探索经历,觉得显然的话必然是一种幻觉。Stay foolish,才能发现某些环节其实并不是那么显然的。
  2. 检验是否真正理解的最佳方法就是过一段时间之后,自己试着证明一次。如果真正理解了的话,你的证明便会比较顺畅。如果当时没有真正理解,那么凡是那些你当时觉得显然但其实不显然的地方,都会成为你证明里面缺失的环节。
  3. 对于一个算法,多寻找各种来源的资料,也许能够找到一个讲的比较深刻的。我在《数学之美番外篇:快排为什么那么快》和《知其所以然(一)》里面都举到了这样的例子。
  4. 多试着去抽象背后的一般性法则,即便后来发现抽象得是错的,也比不去抽象要好。抽象是推广的基础。只有抽象出更深层的法则,才能让你事半功倍,触类旁通,否则一个萝卜永远是一个坑。(注意,其实我们的下意识是会进行一定程度的抽象的,例如前面提到的原始人的例子,小溪和小河(或者小沟)细节上是不同的,但本质上是一样的,我们的大脑会自动进行这种简单抽象,提出事物的共性。正因此,即便你不去有意识地总结一般规律,只要你看的足够多,练的足够多,必然就会越来越谙熟。)



[1] 《逃出你的肖申克》和《BetterExplained》是我喜欢的两个系列,还会继续写,我有很多问题,也在Evernote里面记了不少零碎的思考和资料,但只有当我觉得理解的足够深入,系统,以及手头有足够的有意思和有说服力的例子的时候,我才会把整条线串起来成文,所以这事慢慢来不着急,反正这个博客也不会关掉。

[2] 工作之后可用业余时间急剧减少,已经陆续基本把GReader砍掉了,时间再往前推,砍掉邮件列表,再往前是Twitter,再往前是BBS。现在基本就只剩邮件了。越来越发现当时间有限的时候,看书比看网要有效得多,也不会那么信息焦虑,网络上的那些消息当中真正重要的会自己来找你,不用每天去刷屏。不过有个例外,我过一阵子就会去逛一下Amazon的个性化推荐项目。如果你已经工作,苦于时间有限,我建议你这么做。最近看过的几本值得好好推荐的书有:《Number Sense》,《Reading in the Brain》,《The Vision Revolution》,《The Tell-Tale Brain》,《Kluge》。

[3] 顺便吐槽国内出版社引进Pop Science类书籍的效率和质量,就我观察,台湾引进Pop Science类书籍需要延迟两年左右,大陆则从三四年到无限期不等(某种程度上,一个国家的出版方的认识水平,决定了这个国家大众的认识水平。你去看下我在豆瓣的书单就知道有多少好书与国内读者失之交臂了),例如《Number Sense》这本好书,到现在还没有引进,99年出版的书啊。《Kluge》更是译为《乱乱脑》这种坑爹的书名,封面搞得跟少儿读物一样。《Reading in the Brain》引入的算较快的,但也延迟了一年半了,而且翻译质量也不是很上乘(算是不功不过吧),说到这里要赞中信出版社,最近一年引入了很多给力的 Pop Science畅销书,眼光还算不错。最近在Amazon上搜一些好的发展心理学的书,通过Amazon的推荐引擎看到了《Pink Brain,Blue Brain》,这本受到因研究大脑记忆的分子机制而获诺奖的Eric Kandel盛赞的科普09年就出了,到现在国内影子都见不着,还好在卓越上买到了原版。虽然基本还没开始看,但可以郑重推荐给初为父母的同学们:)

Software Development Is Bad For Your Health (And What You Can Do About It)

中枪了=。= 学习之。


Embedded Keywords for searching: 坐姿,脊椎,久坐

Software Development Is Bad For Your Health (And What You Can Do About It)

February 24, 2013 alexmedearis

Software Development Is Bad For Your Health_1

Slouched Sitting Posture

If you’re like most computer programmers, this is probably what you look like for a large portion of the day, hunched over your desk at a computer for hours on end.  It sucks.  I know because I’ve been there.

The head is forward (1), shoulders are slouched (2), back is arched (3) and your hips form an angle of less than 90 degrees (4).  The evidence is overwhelming that sitting this way is really bad for you. Slouching can cause problems with headaches and jaw pain , gastrointestinal problems , give you a beer gut , even cause you to perform poorly at your job and wreak havoc on your perceived confidence.  In order to avoid these problems, a number of experts advise improving your sitting posture.

Software Development Is Bad For Your Health_2

Proper Sitting Posture

This what the textbook “correct” sitting posture looks like.  The monitor is positioned at or just below eye level so that the head is straight (1).  The shoulders are back and the back is slightly arched (2).  The elbows form a 90-degree angle (3) so that the forearms are level.

It’s true that sitting properly may improve your overall posture, but it’s only part of the story.  For me, the improvement was marginal at best.  I still walked around with slouched shoulders and with my head forward.  About a year ago, I made a concerted effort to change that.

The Beginning

I’ve always struggled with posture.  It doesn’t help that I’m tall and lanky, which seems to exacerbate the issue.  So, last April, when I was offered a free personal training session as part of my new gym membership, I took it as an opportunity to learn more about posture and training.

At the first session, the trainer puts you through a series of exercises to try and determine overall fitness and if there might be any areas which need improvement.  Even though I would consider myself a relatively fit individual, I had trouble with exercises focusing on the abs and glutes.  Why?

The Kinetic Chain

In physical therapy, there is a concept known as a kinetic chain .  Essentially, the idea is that no joint can be evaluated in isolation.  The body tends to compensate for injuries or muscle imbalances in one area by propagating the imbalance to other muscles and joints.  An imbalance in the hip will propagate to the back and shoulders, for instance.

Software Development Is Bad For Your Health_3

Kinetic Chain Ripple Effect

In my case, I believe I developed a muscle imbalance in the hip resulting from hours sitting at a computer.  When you are sitting, your abdominal muscles are not being engaged .  Furthermore, the hip flexor muscles are contracted which can shorten them over time .

With shortened hip flexors and weak abs and glues, the result is an excessive anterior pelvic tilt, meaning that the hips are excessively tilted forward. Some amount of anterior tilt is normal, and the back naturally has some degree of arch, between 4-7 degrees in men and about 7-10 degrees in women.  Mine was closer to 15 degrees.  The anterior pelvic tilt propagates up the kinetic chain, resulting an excessive back arch.  The excessive back arch means that the shoulders and head must come forward to compensate.

Software Development Is Bad For Your Health_4

Anterior Pelvic Tilt

Regardless of whether you are sitting with proper posture or slouching, you will still run into these problems.  Of course, sitting properly will help, but it may not be a solution in itself – at least, it wasn’t enough for me.

My Results

The solution for an anterior pelvic tilt is actually fairly straightforward in theory – strengthen the abs and glutes and stretch the opposing muscles, the erector spinae and hip flexors.  In practice, it’s a little more complicated.

I continued to do roughly the same workout routine I’ve done for years, but I modified it to focus on those goals.  I added planks and hip abductor exercises to my weight training routine.  I added stretches for the erector spinae and hip flexors.  I also started doing pull ups with a reverse grip so as to focus on the deltoids (delts) to try to pull my shoulders back.

I also recently switched to a standing desk, which appears to be a trend among developers these days.  I definitely like my standing desk, but I don’t believe it is a solution in itself.  In fact, a standing desk can actually cause injury for individuals that have been sitting for years if the switch is abrupt.  Standing tends to put more stress on the lower back if you previously had problems with weak abs or glutes.  When I first switched, I definitely felt pain in my back, so I dialed it back and gave my body time to adjust.

It’s been almost a year since I decided to focus explicitly on posture.  My posture has improved dramatically, though it still isn’t quite where I’d like it to be.  In other areas, however, I’ve noticed very clear benefits.  Since my shoulders are farther back, I’ve noticed that I have much greater mobility on exercises like the bench press.  It’s easier for me to lift things off of the ground and my butt actually has some curvature to it, which I’m told might help with the ladies, though I can’t provide any scientific data to support that assertion.  A problem I had previously with shoulder impingement is essentially gone.  I can stand for longer periods of time without feeling fatigue.  So, in short, I am making progress.

Posture is probably something I will struggle with for the foreseeable future.  However, I have found ways to improve my posture gradually.  The bottom line is that our profession is inherently unnatural in that it requires a great deal of time to be spent in a stationary position.  To the extent that we can break up that pattern by taking breaks, stretching, working out and remaining mobile, we can be better, healthier, longer-living. more productive and sane developers.