这是一本致力于告诉广大程序员如何生产效率的不错的书. 其实对于一个厌恶重复劳动的程序员都会有一套自己的高效工作秘笈, 但是真正系统, 完善整理成册的却是一个叫Neal Ford的家伙.
书里面的一些做法也是我的做法, 但是没有作者那种广度和深度, 比如作者跨越了mac os x, windows, *nix多个操作系统下的高效做法都有说明, 而java, c#, ruby, groovy等多种语言的联合使用也是信手拈来.
总之一句话, 珍惜生命, 远离重复. 计算机能做的, 绝不人肉, 是每一个程序员的偷懒哲学.
以下是一些笔记摘抄:
机制
加速法则
一个应用程序列表的有用程度与它的长度成反比.
首选键盘而非鼠标
vi编辑器就是一个经典的不需要鼠标的应用. 旁观一个经验丰富的vi用户会使人心生敬畏. 光标看起来就是一个跟随着他们的眼睛. 遗憾的是, 它的学习曲线太陡峭, 大概需要两年坚持使用vi才能达到这种程度.
即使你安装了一个高效的工具, 需要花时间了解它的适用场景, 情况往往是, 安装之后很快就忘记了它的存在. 能识别出某种技巧所适用的场景就成功了一半.
编程是一项基于文本的行为, 所以你应该尽量将手放在键盘上.
学习快捷键的最好时机是你需要执行这个动作的时候. 当你打开菜单时, 留意一下上面的快捷键, 然后先不要选择菜单项, 而是记住快捷键, 在退出菜单, 在键盘上使用快捷键.在使用快捷键的同时大声说出快捷键也会非常有帮助, 因为这会迫使大脑更多部分的接收这个快捷键的信息.
eclipse 快捷键: alt+shift+up箭头 逐级选择
你知道什么可以加速你的工作, 但是你觉得没有时间去运用它们, "我知道这个快捷键可以做这个事情, 但是我赶时间, 所有我代之以使用鼠标, 以后再去找那个快捷键". 这个以后的动作永远不会发生. 因此需要找到一种平衡: 尝试每周掌握一种提高生产率的方式, 将精力集中在那个方法上直到根深蒂固, 然后再尝试一下
每天花一点时间来使每一天都更高效.
寻找一种平衡: 一方面要花时间去学习, 另一方面这些学习会让你变得更高效.
专注法则
作为一个知识工作者, 你的收入来自于创造性的工作.
linux中反引号`中的命令会在其他命令之前被执行.
资源管理器的有根视图:
引用
explorer.exe /e,/root,d:\workspace
有根视图将资源管理器变成了项目管理器.
采用虚拟桌面管理器之后: 所有开发工具在一个桌面上, 文档在另一个桌面上, 第三个桌面用来运行应用程序, 还有一个打开浏览器.
自动化法则
图形化环境是来帮助新手的
不要浪费时间动手去做可以被自动化的事情
一个统计异常的脚本:
引用
#!/bin/bash
for X in $(egrep -o "[A-Z]\w*Exception" log_week.txt | sort | uniq)
do
echo -n -e "processing $X \t"
echo -c "$X" log_week.txt
done
一个用来关闭所有占用超过15MB内存的进程(试了一下, 貌似不对):
引用
ps -el | awk '{if ($6 > (1024*15)){print $3 }}' | grep -V PID | xargs kill
一个关于svn的 脚本
引用
svn st | grep '^\?' | tr '^\?' ' ' | sed 's/[ ]*//' | sed 's/[ ]/\\ /g' | xargs svn add
获取当前目录以及子目录中所有文件的subversion状态, 每个文件一行. 尚未加入版本控制的文件会以问号开头, 随后是一个tab 最后是文件名
手工执行简单重复的任务会让你变傻
注意力是最重要的生成率之源
做简单重复的事是在浪费注意力
以创造性的方式解决问题, 有助于在将来解决类似的问题
项目中会有很多琐事让你想自动化, 这时你应该先拿下列问题来问自己:
- 长期来看, 将其自动化能节省时间吗?
- 这件任务是否容易出错(其中包含很多负责的步骤)? 一旦出错是否浪费大量时间?
- 执行这件任务是否在浪费注意力?(几乎所有任务都会使注意力为之转移, 你必须花些功夫才能再回到全神贯注的状态.)
- 如果手工操作失误会造成什么危害?
原本以为只需要两个小时就能搞定的事儿, 最终用了4天才做完, 要控制这种风险, 最好的办法就是"时间盒": 首先定好一段时间来探索和了解情况, 时间一到, 就客观的评估是否值得去做这件事.
为避免剪牦牛毛(因为做A必须完成B, 要完成B必须搞定C, 搞定C要..), 始终牢记你到底要做什么, 如果情况开始失控就及时抽身而出.
规范性法则
尽早, 尽可能频繁地提交文件到版本控制中鼓励进行小步改动, 如果进行了长时间的改动就会面临合并冲突的问题, 认识到这一点将鼓励你越发经常的提交.
过时的文档比没有文档更糟, 因为它会主动误导你
如果最终需要费劲创建某件东西, 就意味着需要费劲去改变它.
白板+数码相机强过任何case工具.
实践
测试驱动设计
其实, 非常简单的测试并不是为了真正的测试, 它只是帮助你正确地搭建起基础设施. 这个也叫金丝雀测试(金丝雀对煤气非常敏感, 因此矿工把金丝雀带到煤矿井下来进行煤气报警), 如果有一天这个测试失败了, 说明你的代码基础设施出了严重的问题.
一个简单的测试往往揭示了所需要实现的功能, 这样的事情其实经常发生在TDD的过程中, 要实现这些令人望而生畏的大量的功能, 最好的办法是: 先跳出来, 然后想想怎么让这个测试通过.
更多更小的方法是件好事, 当你读到这些方法名时, 会有一种看到很多原子操作的感觉.
在处理一个长方法时, 要找到错误的根源就需要花费更多的时间, 因为在你开始修改之前要对整个方法的上下文理解清楚. 而理解一个只有三行代码的方法要快得多, 几乎不需要花费时间. 所以如果你发现代码中加入了一些注释, 那说明这个方法应该更加精炼. 带有很多注释的长方法, 往往意味着解决方案没有被很好地组织. 通过把注释重构成方法, 就可以清楚这些又臭又长的大方法.
当个好公民
如果你发现自己使用很多静态方法, 你就应该检查一下你的抽象是否正确.
迪米特法则
只跟最紧密的朋友讲话. 任何对象都不需要到与之交互的那些对象的任何内部细节, 在调用方法时永远不要使用一个以上的点, 比如下面的代码:
homer.getJob().setPosition("foo");
应该改写成:
homer.changeJobPositionTo("foo");
当严格遵守迪米特法则时, 你会倾向于为你的类做很多小的包装或者为其编写大量的代理方法, 以防止在调用方法时使用多个点
java中setAccessable的调用把方法的调用权限改成public.
组合方法和SLAP(单一抽象层次原则)
组合方法要求所有的公有方法读起来就像一系列执行步骤的概要, 而这些步骤的真正实现细节是在私有方法里面. 组合方法有助于让代码保持精炼并使之易于复用.
SLAP强调每个方法中的所有代码都处于同一级抽象层次.
即使只有一行代码, 如果有助于使代码更好的遵循SLAP原则, 那也是好的.
把所有的实现细节封装在公共方法之外.
很多时候, 为了让代码更加清晰以及更具可读性所进行的重构, 也要考虑取舍, 这是由于代码本身存在一定的本质复杂性, 所以问题就变成了"复杂性应该分布在哪里? " 我更倾向于保持简单的公有方法, 而把复杂性放到私有方法里面
多语言编程
语言发展趋势:用一种语言(很可能静态类型的语言)作为可靠的基础, 用一种彰显开发效率的语言(很可能是某种动态语言)来完成日常的编程任务, 而用多种领域特定语言(DSL)让我们的代码更贴近业务分析师和最终用户的需求.
附录
grep的意思是在ex里, 进入命令模式, 键入g来做全局搜索, 接下来以/开头和结尾的正则表达式, 最后输入p以打印查找结果., 总的来说就是g/re/p.
一个脚本:
查找所有以Helper.java结尾的文件, 并统计这些文件中继承以Helper结尾的文件的个数.
引用
find . -name *Helper.java -exec grep -l *extends .*Helper* {} \;
另一种写法:
find . -name *Helper.java | xargs grep -l "extends .*Helper"
还有一种写法:
grep -l "extends .*Helper" `find . -name *Helper.java`