Coders At Work

几个经典的问题及我的回答

如何开始一个新的项目,设计好然后编码,最后发现问题重构吗?

先设计号原型,然后根据对于需求的理解调整功能,不断完善。

最奇怪的Bug是什么?

一般是关于并发的,还有关于硬件的比较难调试。

如何调试? 使用调试器还是print语句?

如果是大型的项目,可以使用调试器的情况下还是使用调试器。 有时为了加深对代码的理解,可以使用调试器来查看调用关系。

如何识别优秀的程序员?

对编程有热情,有责任心,有好奇心,想弄明白事情是怎么一回事。 同时勤奋好学也必不可少的。

哪些推荐的书?

这个就先略过。

对程序员的建议

多读代码,多写代码,勤加练习,学习一些新的东西(语言、技术等)。

《计算机程序设计艺术》以及数学对一个程序员的影响?

数学还是蛮重要的,可以锻炼一个人的严谨的思维, 虽说现在还没有看过《计算机程序设计艺术》, 但以后一定会看的。

同时,这套书里面有很多作者收集的很有意思的问题, 都可以做一做。

还有很多计算机领域需要一定的数学基础, 这些数学也是必学的。

对于文学编程的看法?

有时间一定要看看Tex的源代码,才2万行而已。

如何保证程序的正确性?断言,契约,形式化证明,不动点?

加断言是一个好的方法。

至于形式化的证明,觉得有点过于数学化了。

通过不动点可以更好地理解代码。

如何阅读别人的代码?

先积累一些领域知识,然后开始理清代码的结构, 然后开始关注细节。所以仍然是自顶向下的方式。 如果,只是单纯的想了解某一个特定的实现, 那么可以自底向上。

很重要的一点是要有选择地忽略一些细节, 要知道目前的重点是什么, 不要被细节所干扰。

可以借助调试器,单元测试来加深理解。

什么代码是好代码,可读性,效率,紧凑?

可读的代码是好代码。

为了可读性可以牺牲一点效率。 如果是为了效率牺牲可读性一定要通过注视说明为什么要这么做。

代码如何管理,每个人对各自代码负责还是拥有全部代码?

每一个人对自己写过的代码负责,同时几个人共同维护一些代码, 进行code review什么的。

编程是年轻人的专利吗?

不这么认为,年轻人或许精力更好, 但是经验很不足。编程不是一项体力劳动。

一些共同的看法

使用C/C++这种带指针的语言会带来很多问题, 同时没有边界检查。至于C++,有点过于复杂了。 是不是也可以像Javascript一样, 出一个C++: The Good Parts, 使用C++中的一些精华部分,感觉Modern C++正在朝着这个方向走。

对于《设计模式》这本书没有很好的评价。尽管只有少数几个采访提到, 都认为这本书不是一本能够带来很大帮助的书(除了Bloch),不能什么问题都往设计模式上面去套。 设计模式不是解决问题的银弹。

新知道的观点

第二系统综合征

在重写一个系统时,往往会过于目标远大, 然后导致这个系统会放进太多的功能,显得更加杂乱, 甚至还不如第一个系统。

Worse is better

更差就是更好。投入90%的精力改进10%是否值得。 软件质量并不和功能多少成正比, 功能少的软件更加实用。

单个人物总结

1. Jamie Zawinski

Lisp黑客,XEmacs,屏保程序,NetScape Unix版本开发。

喜欢lisp,不喜欢C/C++,相对来说更喜欢Java。

如果某个人是C++模板的忠实拥趸,那就离他远点。

不知道某件东西并不代表你笨,只是你暂时不知道罢了。

2. Brad Fitzpatrick

Memcached作者,LiveJournal的创始人。现在在Google开发了Memcached的C++版本和go版本(groupcache)。

经历过网站扩张时的扩展性挑战,在如何应对高并发方面有很多经验。

主要的编程语言是Perl,C,目前来说对于C++和Go也很了解。

解决的思路会被局限在自己的知识范围内。因此多学习一些编程语言, 学会用不同的编程语言来思考。这样,学习新的编程语言或者接手新的项目也更容易:

不用它写一些大的、复杂的系统,就不能算是学会了一门编程语言。

不要迷信库和框架,那些看起来很美的库实现也很糟糕。 不要害怕修改一个库,相信自己有实现一个库的能力。 很多的库为了照顾通用性实现得并不是很好。

崇拜某个程序员,去读读他写的代码,也许你会发现他也是凡人。

优秀程序员的特征:会做很多别人没要求他做的事情。

好的工具:strace(dtrace), Valgrind。

在机器多的时候,程序员的时间可能没有机器的时间重要。

学习Perl的书:《High Order Perl》。

3. Douglas Crockford

Json, JavaScript: The Good Parts, JsLint的作者。 反对ECMAScript 4。

为什么反对ECMA 4,因为现在的主要问题是脚本的安全性, 而不是语言的特性不够。使用JavaScript目前的精华就能写出好的程序。 修正标准时要考虑标准增加的价值足够抵消它带来的代价(原来的程序不能用)。

主张使用代码代码阅读来解决代码中的问题。

偏爱K&R风格,因为这在JS里面是必须的。

使用第七个周期来清理代码。

使用JavaScript将使重构更加容易,为什么??现在还不是很理解。

阅读和写作的重要性。

4. Brendan Eich

JavaScript语言发明者,在编译器领域比较突出。

JavaScript受影响的语言:Self, Scheme, Smalltalk。

在语言用户,开发者和研究程序语言的学者之间还存在一定隔阂。 不过关于这一点,在对Simon Peyton Jones的采访中, 他提到学术界是编程的语言的先行者, 学术界的研究成果会被应用到新的语言设计中, 比如Hindley-Milner类型推导就是。

5. Joshua Bloch

Java架构师,著有《Effective Java》,《Java 解惑》, 《Java并发编程实战》。

试图不复制任何程序。

推荐《设计模式》, 《Elements of Style》,《Hacker’s Delight》,《人月神话》。

优化正确的代码比改正优化过的代码容易多了。 所以一开始把可读性放在首位。

具有感同身受的基因,站在用户的角度去考虑整个问题。

6. Joe Armstrong

Erlang语言发明者。

在编程之间先思考清楚。画一些图形帮助理解。通过向别人解释加深理解。

编程的目的在于理解。为了理解一个事物的工作原理可以自己尝试着去实现它。

Erlang风格的消息传递机制不是解决并发编程问题的银弹。

7. Simon Peyton Jones

微软剑桥研究院研究员。主要研究方向是Haskell,是GHC的架构师和开发者。

“不惜一切代价避免成功”,太成功的项目在发展的时候就会遭遇太多的阻碍。

动手去做,不管这件事有多么不起眼。

S-K组合子,有时间可以研究一下。

Why Functional Programming Matters,这篇论文也应该读一下。

使用惰性求职,能够很好地将生成器和使用者隔开。

STM完全胜过锁和条件变量。但是可能会有饥饿的问题。

Purely Functional Data Structures。

A Discipline of Programming。

8. Peter Norvig

Teach youself programming in ten years。 要经过十年左右的磨练,才能成长为编程大师。

9. Guy Steele

像讲故事那样去表达想法,通过这样的方式来写代码。

如何评价接口的好坏?通用性和正交性。

如果有什么东西值得告诉程序员,那么它也值得告诉编译器。

编程是一项高度不自然的活动。

同样的错误绝不止一个。

10. Dan Ingalls

Smalltalk的实现者。

一定的无知也自有优势,它为创造力留下了一些空间。

11. L Peter Deutsch

Ghostscript作者。

一套程序设计语言就像是一个三脚架,三只脚分别是语言本身,库和工具。

12. Ken Thompson

Unix之父。

不要过度设计,一开始就想做得特别好根本就是在浪费时间。

更倾向于简单的代码和简单的算法。

13. Fran Allen

Fortran编译器开发。SSA发明者。

设计是在编码中逐渐完善的。

C语言等的出现对于自动并行造成了不好的影响, 不理解这个观点。

14. Bernie Cosell

IMP系统开发者之一。

支持设计评审。

相信没什么真正难的程序。

程序是写给人看的。

优秀程序员的特征:刨根问底、勤学好问、一丝不苟、 有天分、学习快速、爱好广泛。

15. Donald Knuth

如果只是调用库里的东西,如果不能自己写库, 那编程还有什么意思呢?

如今的编程更像是组合别人写好的库和工具, 然后得到一些有趣的结果。 这种结果跟不断创新获得的快感是完全不同的。

能够深入到别人的思维方式之中,并对他们使用的词汇和符号进行解码, 这是非常重要的。

你阅读别人的材料越多,未来开拓创新的能力就越强。