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 ^^^^^^^^^^^^^^^^^^^^^^^^^ 如果只是调用库里的东西,如果不能自己写库, 那编程还有什么意思呢? 如今的编程更像是组合别人写好的库和工具, 然后得到一些有趣的结果。 这种结果跟不断创新获得的快感是完全不同的。 能够深入到别人的思维方式之中,并对他们使用的词汇和符号进行解码, 这是非常重要的。 你阅读别人的材料越多,未来开拓创新的能力就越强。