7月第一周读完了两本程序访谈类书籍《编程人生》《编程大师访谈录》。这两本书34位专家对编程的看法,给了我很大的启发,最大的收获在于重新调整了编程的价值观,调整了一些编程工作中的习性。
《人生》作者更喜欢提实操类的问题,《访谈录》提问更多聚焦于专家所在的工作领域;《人生》接受采访专家更偏向于计算机科学家,大多侃侃而谈,而非《编程访谈录》里那样,更多是工匠大师,对于理论细节不善表露的浅显。
以下几个问题及其回答,我想记在文章里,当做我程序人生价值观的补充。
问题1,优秀程序员的特征;#
有些程序员是面向用户的,有些程序员是解决数学问题。
有些人对数学问题感兴趣,有些人对决定把东西放在屏幕的顶部还是底部感兴趣。
杰出程序员是团队里3%的人,却做了30%的工作。总有少数人可以做普通人工作量六倍之多
——韦恩.莱特莱夫
计算机科学手艺的关键是找出规则。计算机学科中已经发现了主要规则,最优秀的程序员通常是那些知道普遍规则的程序员。
能够平衡多个可选选项的,让各个组件更好的协同工作。许多人会先设计算法,然后围绕算法设计整个系统。
经年累月,
积累的算法数以百计;
牢记所学到的技巧,处理过的缺陷,误入的死胡同。
牢记自己犯过的所有错误,取得的所有成功经验。
最终,你可以信手拈来,做特定任务就像是从菜谱中选定菜目,巧妙搭配食材,排出一席美味佳肴。把程序各个部分组合一起,才是优秀计算机程序员之道。
我和一个人谈他的程序,马上就能知道他是否是个好程序员。如果他是好程序员,每个细节他都会脱口而出。
好程序员和下棋高手一样。如果你是个好棋手,你会很容易记住十盘棋中的每一步,因为你已经置身其中了。
——比尔盖茨 微软创始人
记性要好,这是对的。
能回忆起以前写过的代码。
——joe.Armstrong
我注意优秀程序员和差劲程序员的一个重要区别是,优秀程序员在不同抽象层级之间切换自如,修改时仍能保持各层独立,并且选择合适的一层修改
决定在什么位置修改很有讲究,而且关系很大。第一类位置是在靠近用户上层位置修改,第二类位置是影响底层的大福修改。这些修改要思考我只改小小特例,还是会碰到十几种同类型情形。
——James.zawinski
问题2,你经常读的书;#
《acm通讯》,《程序设计心理学》,算法书好好看看
自己擅长的编程语言的书,参考手册的书,调试和测试流程的书,代码大全之类的
《设计模式》,里面有好的创意任何程序员都要看,
《写作风格要素》,软件工程师很大一部分工作是写文档,书里写作风格也适用于编程
《计算机程序设计艺术》,
《人月神话》,给一个延期的项目加人,会让他延期的更厉害
《韦氏学院词典》,必须能写好变量命名
问题3,优秀程序员的必备技能;#
想象力,在脑海中对目标有极为清晰的把握。
是天赋、气质、动机、努力工作的结合。
成功来自来自于一遍又一遍地做同样的事情,每次学习一点点,下一次都做的更好一点。
——乔纳森.萨奇
崇尚简洁,例如他们认为5是最大的数字。你能拥有的数字不能超过五。
如果你做什么事情,那得从一个简洁的设计开始,不论是打算写一本书,准备写一个软件,还是即将开始需要规划一个项目,都需要一个简洁的设计。
如何简洁的开始,这需要大量的训练。你得亲眼看到错误的简洁做法,才能知道自己如何做到最简洁。
——斯科特.金
好奇心。把东西大卸八块的好奇心。弄明白底层是怎么回事,那是技能之根本。我的经验主要来自源代码和用户手册。
首先确定好奇的对象,实现这个对象我需要弄清楚这对象都能做什么,然后我会随意折腾一下直到做出原型为止
——James.zawinski
第一你必须对某个方向有所了解,并做出来一点成果,
第二把他当成你前进的方向
第三你要能改进它,改进的结果是,我可能理解错了,有些情况考虑的不全
第四是我要把它封装成工具,下次使用更轻松
——Peter.norvig
问题4,对于自学计算机科学的人有什么建议;#
快点出成果,快速让东西运行起来,快速弃之不用坏的东西
从小的地方开始实验,而不是大的目标开始学习。
最好每个月出点成果,这样才能评估,重组,重新开始
——忘了
1,要试着做点更难的东西,超出能力范围的东西
2,要多读代码,记住他们的代码结构
3,对代码的原始版本即代码仓库的第一个版本做修改
你认为对程序员来说什么是最重要的技能?
一次只改变一个东西,试着了解问题本质。
保持耐心,调试不正常的东西,设计复杂东西更应该保持耐心。
减少抱怨见鬼程序又运行不了。应该停下来看看发生了什么。
——brad.fitzpatrick
多读。读好书,读好的源码。学会从低劣代码,劣质书里走出来。
多写。写算法,写数据结构,写文档,写邮件回复,写提交日志
——douglas crockford
第一是,得充满兴趣,有兴趣才会想要提高技能
第二是,怎样发现好的东西,可以拜访经验丰富的前辈,问他什么是好东西
第三是,流连于各大书店的计算机学科书架,每个月都到哪里去一次,翻一翻
——guy.steel
要编写大量的程序。只有编写程序才能真正掌握要领。
设立明确目标,这方面我应该学些什么,为什么我不试着写个小程序体验下呢。这种想法很管用。
编程是门手艺,需要不断锤炼才能完美。普通人花两周调试,优秀程序员只用五分钟。
——bernie.cosell
一,不要以为你知道所有东西。
二,尝试质疑那些假定的东西。
三,经常猜想你可能做错了什么。
四,要有足够的罪恶感,不要太多,否则会害怕做许多事情
五,保持程序美感
六,保持对事物深刻理解,不要因为它运行成功了,就以为没什么需要了解的了
七,试图了解程序是怎样运行工作的
——鲍勃.弗兰克斯顿
问题5,你如何识别优秀人才;#
我喜欢找这类型人。他们会做很多别人没要求他做的事情。不仅仅是学校或者公司要求他做的。
他们对某些事充满激情,有做额外的项目,我会问清楚他们是如何维护的,对它有多上心,是否最后潦草收场。
——brad.fitzpatrick
我采取的手段是代码阅读。我会让应聘者带来他们写过最优秀的代码,并引领我们阅读这些源码。
是不是他们自己写的,他们是否对程序充满激情。
我喜欢多面手,我想找的是有能力学习任何api,而非只精通其中一种。
——douglas crockford
只看他们的激情
问他们最花费心血写过的程序,问他们做过最有趣的程序,然后让他描述该程序和它的算法,
回答过程中他们是否有热情深入分析问题和解决方案
——ken.Thompson unix联合创始人,图灵奖得主
我认为检验编程能力最好的办法是给程序员一本30来页的代码,看看他的阅读和理解速度有多快。
源码理解能力,是重要编程能力一个人说我花好几天看懂他,和另一个人说我把他带回家,一个小时看懂他。这种能力差异是巨大的。
现在的程序员不用对程序进行压缩,他们认为资源总是可用的。过去程序员总会面临资源有限的情况,所以老程序员总会想着对程序进行压缩。
编程需要大量精力,也需要设定目标并坚持投入训练。持之以恒年轻程序员会变得更出色。
——比尔盖茨 微软创始人
问题6,你如何阅读源码;#
编程就像唱歌写作一样,需要反复练习。但是跟唱歌一样,没有好的调音系统,练的再多也是白搭。
当年读一段代码你会如何入手
一是选择方向,从上往下,或者自底向上
二是程序过大情况,函数和控制流程会变得不清晰,我会借助调试工具来读
三从多个角度读这个代码,角度一它是怎么被更高层调用的,角度二系统提供了哪些调用,不同的调用有什么联系和区别,角度三从系统设计和数据结构方面了解设计思想
——brendan.eich-JavaScript发明者
我为了了解内部工作机制,通常会选择一个特定的命令或者交互行为然后追踪下去。
方式一我会在调试器中启动它,单步执行下去,从程序启动,到执行该方法都做了什么事情,它使用了哪些数据结构,缓冲区是怎样设置的
方式二我在源代码中心查看它。
我更关心源码以下几点:
大师级程序员是如何组织数据结构的,如何让代码更易于阅读。
更容易理解某一特效是如何工作的 ——guy.steel
要么先有些直觉,要么先了解一下该领域
直接从中间部分入手探寻程序的核心,绕过细枝末节
——fran.allen 首位女性图灵奖得主
问题7,如何提高编程水平。#
倒着做事情,会将复杂问题简单化。例如解析向前引用可能很难,如果倒着扫描,他们就变成了向后引用,很容易解析。只要从新角度看待程序,原本很难解决的问题也会很容易解决。这就是algol编译器的玄机。
数学训练,逻辑推理训练,如何证明,如何描述抽象要素,建立抽象要素之间的联系
写出好程序依赖什么
准确定义系统和外界间接口,定义系统内部模块间接口,了解系统之间是如何组合到一块的。
计算机语言的发明家西摩.佩伯特seymour papert 认为孩子可以通过摆弄齿轮等机械小玩意变得具有创造性。第二类观点是通过玩耍而学习和练习的技能会转移到其他领域。
——基尔代尔
编程需要大量精力,也需要设定目标并坚持投入训练。持之以恒年轻程序员会变得更出色。
——比尔盖茨 微软创始人加里
不断编程。解决有意思的问题。
我写了一篇 用十年时间自学编程teach yourself programming in ten years
——Peter.norvig
你不去做的事情都很难,做过的事情都很简单。
我强烈推荐,想理解c就写一个c的编译器,想理解lisp,就写一个lisp的编译器或解释器。
我喜欢分析事物的工作原理。一个好的验证工作原理方式是自己实现他们。
编程不仅是在机器中写入代码。目的在于理解。如我要理解小波变换,所以我实现jpeg,我要理解x协议原理,所以我试着给x Windows加了接口。
——joe.Armstrong
编译出正确结果时,我会很开心。值得警惕的是,人们一上来就开始编码,只是为了得到结果,过后发下所有难题都还没有处理。这种现象是非常糟糕的。
为了享受编码并看着运行出来的乐趣,我喜欢等一等,把基础打好。这就像是美食留到最后一刻品尝一样
——比尔盖茨 微软创始人
我推荐严谨的结构,一致的结构。另外,我认为软件应该高度模块化和分层,规范使用接口,用接口分别构建不同组件
——雷.奥奇
问题8,你的编码习惯是什么#
集中精力思考最难的部分,
简单部分用作图替代
写下数据结构,再写代码,数据结构可以适用于每一行代码
——ken.Thompson unix联合创始人,图灵奖得主
我在oopsla做了一个演讲,主题是如何设计一个好的api。
1,最重要的是了解你最终要设计什么,解决什么问题。
需求沟通是一个理解的过程。客户告诉他需要解决方案,需要特性功能,。你需要沟通去真正理解客户需要软件做成什么事情。
2,沟通的结果是用例。有了用例你就可以比较备选方案优劣的基准。
3,根据用例写骨架api,骨架api应该简洁,一页纸足够,无需精确,。纸上应该声明包,类,方法,想不清楚的地方可以放一句话描述。
4,实现骨架api的代码,反思用例设计的缺陷,骨架api的问题,完善或者推导重来
——joshua.bloch-Java collection framework开发者
我喜欢坐下来把整个设计方案想清楚,写完第一遍代码,我会重头到尾重写一遍。
程序最重要的是设计数据结构,第二重要的是分解各个代码块。
在我实现代码块的之前,我已经花了大量时间思考,写的时间问题已经不在于是否能写出来,问题在于能否把性能压缩到4k,写的过程中我会思考,程序速度够快里面吗?性能够好了吗?别人会怎样做的更好?
计算机性能越来越好,内存越来越大,编程越来变得复杂,这会对人们编码产生什么影响吗?
程序要做到顶尖,关键的内部代码是少数几个知道自己在做什么的人编写出来的。
——比尔盖茨 微软创始人
写程序前只需要学习一组为数不多的程序模块。需要用到很多次的程序模块可以积累起来。方便查看和使用。
我会先画数据结构,然后思考数据结构,在写代码之前花时间思考程序流程。
确定数据结构之后,我会开始写一小段代码,不断地完善和调试。
——加里.基尔代尔
想象,在脑海中对目标有极为清晰的把握。
初始阶段,用纸和笔信手涂鸦,画方框和箭头,过程阶段想象有待维护的数据结构,一旦结构想的严谨和明确,便开始写代码,拿纸和笔手写实现。
数据结构最关键,我会提前想好,并在整个编码过程中将他牢记于心。
我得到的一个忠告是推迟编码。程序设计一直保持在脑海中。
目标是通过一个单一通用数据对象,来简化核心设计和程序结构。鲍勃.卡尔
——鲍勃.卡尔
我会坐下来设想程序应该做成什么样子,绘制一副脑海影像。
第二我会聚焦我认为最可能会有问题的地方。想办法将它们弄清楚。并写一个简单的例子验证。
第三是确定程序的数据结构
第四不过是简单的编码和重复的工作
——约翰.佩奇
问题9,计算机是科学吗#
不是。科学是提出假设做实验,在现实世界创建模型。计算机与之不同,他是信息工具,描述世界模型的实现,操纵和控制信息。
最优的算法知识属于科学,数据结构的想象则是艺术。编写代码实现数据结构以及结构转换,是编程的手艺。这需要非常用心并辅之以大量练习才能成就。
技能的成分多一些。训练是编程的必经之路。说到底还是熟能生巧,受过训练的人比没有受过训练的人更具备优势。
——丹.布兰克林
一种说法是科学,第二种说法是艺术,第三种说法是技能或手艺。编程背后有科学理论支持,如信息理论和计算机科学以及数学。编程跟造工具很像,需要像手艺人一样去精雕细琢它。
我认为,只要将科学,艺术,技能这三者拿捏的好,你就能取得引人瞩目的成就。
问题10,写出好程序需要什么能力#
最重要的能力是把问题的解决方案组成容易操作的数据结构,流程结构。
第二重要的是向团队其他人描述这个数据结构,流程结构。