一、《高效程序员的45个习惯》
1.态度决定一切
(1)做事,把矛头对准问题的解决办法,而不是人,这是真正有用处的正面效应
(2)欲速则不达,要投入时间和精力保持代码的整洁、敞亮
(3)对事不对人,让我们骄傲的应该是解决了问题,而不是比较出谁的主意更好
(4)排除万难,奋勇前进,要诚实有勇气去说出实情,有时候这样做很困难,所以我们需要有足够的勇气
2.学无止境
(5)跟踪变化,不需要精通所有技术,但需要清楚知道行业的动向,从而规划你的项目和职业生涯
(6)对团队投资,通过午餐会议可以增进每个人的知识和技能,并帮助大家聚集在一起进行沟通交流。唤起人们对技术和技巧的激情,将会对项目大有裨益。
(7)懂得丢弃,在学习一门新技术的时候,要丢去会阻止你前进的旧习惯。毕竟,汽车要比马车强得多。
(8)打破沙锅问到底,不能只满足与别人告诉你的表面现象。要不停地提问直到你明白问题的根源。
(9)把握开发节奏,保持时间之间稳定重复的间隔,更容易解决常见的重复任务
3.交付用户想要的软件
(10)让客户做决定,开发者、经理或者业务分析师不应该做业务方面的决定。用业务负责人能够理解的语言,向他们详细解释遇到的问题,并让他们做决定。
(11)让设计指导而不是操纵开发,设计指引你向正确的方向前进,它不是殖民地,它不应该标识具体的路线。你不要被设计(或者设计师)操控。
(12)合理地实用技术,首先决定什么是你需要的,接着为这些具体的问题评估使用技术,对任何要使用的技术,多问一些挑剔的问题,并真实地作出回答。新技术就应该像是新的工具,可以帮助你更好地工作,她自己不应该是成为你的工作。
(13)保持可以发布,保证你的系统随时可以编译、运行、测试并立即部署。
(14)提早集成,频繁集成,代码集成式主要的风险来源。要想规避这个风险,只有提早集成,持续而有规律地进行集成。
(15)提早实现自动化部署,使用部署系统安装你的应用,在不同的机器上用不同的配置文件测试依赖问题。质量保证人员要像测试应用一样测试部署。
(16)使用演示获得频繁反馈,在开发的时候,要保持应用可见(而且客户心中也要了解)。每隔一周或者两周,邀请所有客户,给他们演示最新完成的功能,积极获得他们的反馈。
(17)使用短迭代,增量发布,发布带有最小却可用功能块的产品。每个增量开发中,使用1~4周左右的迭代周期。
(18)固定的价格就意味着背叛承诺,让团队和客户一起,真正地在当前项目中工作,做具体实际的评估。由客户控制他们要的功能和预算。
4.敏捷反馈
(19)守护天使,好的单元测试能够为你的代码问题提供及时的警报。如果没有到位的单元测试,不要进行任何的设计和代码修改。
(20)先用它再实现它,使用测试驱动开发作为设计工具,它会为你带来更简单更实效的设计。
(21)不同环境,就有不同问题,使用持续集成工具。在每一种支持的平台和环境中运行单元测试。要积极地寻找问题,为不是等问题来找你。
(22)自动验收测试,为核心的业务逻辑创建测试,让你的客户单独验证这些测试,要让它们像一般的测试一样可以自动运行。
(23)度量真实的进度,不要用不恰当的度量来欺骗自己或者团队。要评估那些需要完成的待办事项。
(24)倾听用户的声音,每一个抱怨的背后都隐藏了一个事实,找出真相,修复真正的问题。
5.敏捷编码
(25)代码要清晰地表达意图,向代码阅读者明确表明你的意图。可读性差的代码一点也不聪明。
(26)用代码沟通,使用细心选择的、有意义的命名。用注释描述代码意图和约束。注释不能替代优秀的代码。
(27)动态评估取舍,考虑性能、便利性、生产力、成本和上市时间。如果性能表现足够了,就将注意力放在其他因素上。不要为了感觉上的性能提升或者设计的优雅,而将设计复杂化。
(28)增量式编程,在很短的编辑/构建/测试循环中编写代码,这要比花费长时间仅仅做编写代码的工作好得多。可以创建更加清晰、简单、易于维护的代码。
(29)保持简单,除非有不可辩驳的原因,否则不要使用模式、原则和高难度技术之类的东西。
(30)编写内聚的代码,让类的功能尽量集中,让组件尽量小。要避免创建很大的类或组件,也不要创建无所不包的大杂烩类。
(31)告知,不要询问,不要抢别的对象或者是组件的工作。告诉它做什么,然后盯着你自己的指责就好了。
(32)根据契约进行替换,通过替换遵循接口契约的类,来添加并改进功能特性。要使用更多的委托而不是继承。
6.敏捷调试
(33)记录问题解决日志,保留解决方案是修复问题过程的一部分,以后发生相同或类似问题时,就可以很快找到并使用了。
(34)警告就是错误,签入带有警告的代码,就跟签入有错误或者没有通过测试的代码一样,都是极差的做法。签入构建工具中的代码不应该产生任何警告信息。
(35)对问题各个击破,在解决问题时,要将问题域与周边隔离开。特别是在大型应用中。
(36)报告所有的异常,不要将它们压制不管,就算是临时这样做也不行,在写代码时要估计到会发生的问题。
(37)提供有用的错误信息,提供更多易于查找错误细节的方式,发生问题时,要展示出尽量多的支持细节,不过别让用户陷入其中。
7.敏捷协作
(38)定期安排会面时间。使用立会(站着开的会议)可以让团队达成共识。保证会议短小精悍不跑题。
(39)架构师必须写代码。优秀的设计从积极的程序员那里开始演化。积极的编程可以带来深入的理解。不要使用不愿意编程的架构师——不知道系统的真实情况。是无法展开设计的。
(40)实行代码集体所有制。让开发人员轮换完成系统不同领域中不同模块的不同任务。
(41)成为指导者。分享自己的知识很有趣——付出的同时便有收获。还可以激励别人获得更好的成果,而且提升了整个团队的实力。
(42)允许大家自己想办法。指给他们正确的方向,而不是直接提供解决方案。每个人都能从中学到不少东西。
(43)准备好后再共享代码。绝对不要提交尚未完成的代码。故意签入编译未通过或是没有通过单元测试的代码,对项目来说,应该被视作为玩忽职守的犯罪行为。
(44)做代码复查。对于提升代码质量和降低错误率来说,代码复查是无价之宝。如果以正确的方式进行,复查可以产生非常实用而高效的成果。要让不同的开发人员在每个任务完成后复查代码。
(45)及时通报进展与问题。发布进展状况,新的想法和目前正在关注的主题。不要等着别人来问项目状态如何。
1. 只做需要做的工作
- 使用敏捷方法;
- 全心全意做UX设计;
- 沟通第一;
- 编码也许不是解决问题的办法;
- 过早的优化是一切罪恶的根源;
- 选择最简单的解决方案。
2. 站在巨人的肩膀上
- 使用开源框架;
- 使用简洁语言;
- 不要做重复的事情(不要重新发明轮子);
- 利用包管理器来进行公共和私有代码分配;
- 不要任凭巨头(如微软)的摆布而修复库中的一个Bug;
- 不要让你的雇主逼你学习;
- 自主学习并为自己设定新的目标。
3. 了解数据结构和算法
如果你不知道什么时候应该使用快速排序、不懂辨认O(n2)程序、不会写递归函数,你将无法成为10倍效率的开发者。使用多种语言你才能清楚不同的框架是如何解决相同问题的。尽可能去了解底层命令(plumbing),以便能够作出明智的决定(Web框架是怎么存储session状态的?Cookie到底是什么?)。
4. 不要怕买工具,它可以节省你的时间
Ben说:“昨天我花50美元买了一个位图字体工具,它帮我节省的时间成本绝对超过200美元。”
5. 集中注意力
不要整天开着你的电子邮件、Twitter、Facebook等,在工作时将它们最小化或关掉它们,戴上耳机。Tiny hack说:“即使不听音乐我也戴着耳机工作,这样便不会有人打扰到我。”
6. 尽早并且经常性地进行代码重构
有时,你不得不放弃漂亮的代码转而去寻找真正对项目有用的代码,但没关系,如果你的现有项目中有这样的代码,最好的方式便是不要看它,并重构。
7. 只管去做
将你的业余项目分享到Startup Weekend中。在我开始转到Unix和Ruby on Rails上之前,我买了一台Mac,使用Windows虚拟机花了一年时间做.NET项目。
8. 挑选一个编辑器,并掌握它
高效开发者喜欢用文本编辑器胜过IDE编辑器,因为这样可以学到更多东西。无论什么情况,尽量使用键盘快捷键,因为熟练使用一件工具的前提是熟悉它。
在选择编辑器时,认真考虑并挑选最好的(Emacs或Vim),因为它们是通用的。其次,挑选你的首选平台最支持的。使用宏,不断地写代码;使用Mac上的TextExpander为整个段落创建快捷方式;使用Visual Studio或SublimeText的自动补齐功能;使用支持按行/列分割窗口的编辑器,这样你便能同时看到单元测试和代码(或模型、视图)。
一定要想清楚后再写代码。Adam说,“我有朋友在一个大项目组里工作,他们组里最高效的程序员是一个高位截瘫用嘴叼着棍子敲代码的人,他总是在写代码之前想得很仔细且很少出错。”
9. 整洁的代码胜过巧妙的代码
要想让其他人能够读懂你的代码,尽量使用最少的代码来完成任务。遵循DRY(Don’t repeat yourself)的原则,使用明确定义的对象和库,将任务分解成小而简单的代码段。
10. 潜意识是强大的工具
离开10分钟往往就可以解决一个问题。控制编程时间,给自己一个多姿多彩的生活,劳逸结合能让你在工作时更高效、更愉悦。当然,即便是上了年纪的程序员也知道,以最少的时间完成最高效的工作是成为10倍效率开发者的必要条件。
作为一个程序员,我觉得在职业生涯中最好的一件事儿就是从电脑前站起来,去拜访那些在某一领域有所建树的人们。
11. 推动自身和团队进步
重视批评,以包容的态度接受批评并提升自己是非常重要的事情。没有这个基础,你不可能成为一个高效的开发者。一位智者曾经说过:“聪明的人善于从自己的错误中学习,而智慧的人善于从别人的错误中学习。”
优秀程序员必备的23条好习惯
世间少有天才,所谓天才,只不过是把别人喝咖啡的功夫都用在工作上了。所以,对于绝大多数还称不上天才的程序员而言,以下这些编程的好习惯都是无数前人智慧的结晶,具有相当意义的参考价值。
(1)估算解决问题所需要的时间。为自己定一个时间限制,如果在这期间未能解决问题,那就去寻求帮助,或到网上找答案,而不是尝试去做“超级堆码员”,因为很多问题,你很少会是这个世界上唯一一个遇到的人。站在别人的肩膀上,会让你的形象变得高大、伟岸。
(2) 理解编程语言的原理。三流的人才懂应用,二流的人才懂开发,一流的人才懂原理,要想学好一门编程语言,掌握语言的原理是必不可少的。各种语言之间存在相似之处,你所选择的语言,你应该觉得“舒服”,并且能够写出有效(而且简洁)的代码。最重要的,让语言去适应项目,反之亦然。
(3) 重视,但不过于注重程序的设计模式。在大中型系统中,引入设计模式,往往能极大地提高系统研发的效率。但设计模式并非万金油,有时候,写一个简单的算法,要比引入某种模式更容易。如果一个100行就能写完的脚本,最终却使用了8个类,10个接口,外加一大堆范式和标记符,结果导致97%的代码不做任何事情,这种优化又有什么意义?在多数情况下,程序代码应是简单易懂,而不应该是老太婆的裹脚布—又臭又长。
(4) 做好版本控制,并及时备份代码。编码时,最痛苦的事情不是有多少bug没解决,而是突然停电了,一天的工作却没有保存。版本控制时,最好使用版本控制软件。无论什么时候改变自己的程序,它们都会将其保存为.bak文件。
(5) 对项目文件归类保存。可以把项目文件放到SOURCE、HEADERS、MAKE、EXES等不同的文件夹中。如果工程包含多个源文件,则可以建立一个README文件,注明每个源文件、数据文件、临时文件以及日志文件(如果有的话)的作用。还可以注明编译和运行步骤。
(6)动手编码之前,先做好分析和设计。项目开始之初,不要急于编码,而应该做好详细的需求与设计。做需求确实很难,不然也不会有程序员发出这样的牢骚:需求无非两种,一种是“你妹的,这还用做?”,另一种是“你妹的,这也能做?”不仅如此,实践和分析设计过程也可存在很大的矛盾,但是好的分析会避免过早走向一个错误的方向,好的设计可以避免混乱,否则,很有可能忙活了很久,最后发现方向错了或是架构错了,需要不断的监测、修改与调试,甚至是完全推翻以前的工作,重新设计,工作的成果看起来更像一个三岁小孩的涂鸦,而不是意见艺术作品,“捡了芝麻却丢了西瓜”。永远不要在没有任何设计的前提下就开始编码,除非所编代码不重要。
(7)多向其他优秀程序员学习。你有一个苹果,我也有一个苹果,我们交换苹果,你我还是有一个苹果;你有一种思想,我也有一种思想,我们交换思想,你我就有了两种思想。其实,一个人能走多远,要看他与谁同行;一个人有多优秀,要看他有谁指点;一个人有多成功,要看他有谁相伴,更何况“一山总比一山高”。休息放松固然重要,但需要适可而止,生命不息,奋斗不止,尤其是年轻的时候,更是如此。时间的强大是不可逆转,再繁华的都会归于尘土,与其把大把大把的时间浪费在打dota、玩三国杀或是无聊发呆上,还不如与其他优秀程序员坐在一起边喝咖啡边交流或是研究他们编写的代码,吸收他们的经验转化为自己所用。在与这些人的沟通中,学习他们解决和自己相同的任务时所使用的方法,在此过程中所学知识可能会帮你省下几个星期的时间。我们不赞成与臭棋佬下棋,棋会越下越臭的观点,但不可否认这样一个事实:和什么样的人在一起,就会有什么样的人生,和勤奋的人在一起,你不会懒惰;和积极的人在一起,你不会消沉;与智者同行,你会不同凡响;与高人为伍,你能登上巅峰。
(8)优化代码。优雅的代码非常的易读,所以如果时间允许,应该尽可能地优化代码,对时间和空间进行合理分配与使用。之前声明的一些变量,现在可能没用了。同样,并不依赖循环的一些声明可以移到循环模块之外去。否则后续开发或是技术提供会比较困难。但也需要注意,优化后的代码并不是越简短越好,用的语法越偏僻越好,因为晦涩的代码,维护成本会非常高,而且好的代码不但要实现功能,更要好维护,最好是A写的代码让B能很轻易的理解和修改。
(9)加强测试。测试的重要性并不亚于开发,所以要非常注重程序自测试。测试时,一般使用工具为主,人工为辅的策略,工具包括用单元测试,assert语句,代码测试容器,人工指用 print 和debugger 一行一行跟踪。
(10)使用输出日志。打印输出函数可以跟踪变量的执行,但频繁地插入打印会使得屏幕的输出很乱,而写一个日志函数,可以保证 Debug 的时候的输出以一种统一的,可管理的方式出现,这样在最后发布稳定版本的时候,只需要简单的几行命令就可以从代码中剔除所有的日志打印行。
(11)检查代码。代码要经常检查(包括自查和其他同事检查)。在提交代码前,找个同事一起坐下来,向他解释代码做了哪些修改。这样做的过程中通常能够发现代码中的错误,而不需要同事说一句话。这比自己审查自己的代码要有效的多。将代码的bug发现的越早,成本越低。
(12)回顾代码。在看到自己以前的代码时,通常会有两种矛盾不同的想法:第一种:我怎么写了这么烂的代码;第二种,我写的代码还是挺有成就感的。其实,经常回顾以前的代码,往往会触发新的想法,以及对以前编码更深层次的思考。
(13)编码不能想当然,任何时候都要严谨。一个简单的项目,表面上看可能可以轻松完成,其实不然,一个使用Microsoft Access的、只有3个页面的网站,最后很有可能会变成一个有30个页面并使用SQL Server作为数据库的网站。所以除非有一个类、组件或者一段已经写好的代码,并且在现有的项目已经测试通过,否则,切不可掉以轻心。
(14)任何软件都会有BUG。BUG像幽灵一样,它是永远也改不完的,所以关键是要修复严重的、影响业务的、显眼的Bug。一个软件项目,参与的人数越多,并不代表软件可靠性越好,相反,“人多手杂”,而且需求越变更,潜在的Bug会越来越多,很多时候,也许只是修改了一行代码,其很有可能影响到很多关键流程的执行。
(15) 养成耐心、冷静的好习惯。作为一名程序员,不能像普通人一样被计算机掌控,而应该作为计算机的主人,去掌控计算机。所以,一定要有足够的耐心,当程序运行不正确时,要冷静下来,站在计算机的角度去看问题、分析问题。
(16) 遵循编程规范。例如“==”与“=”的区别;合理使用缩进;使用循环和条件语句时,先把左右括号对应起来,然后再在里面写其他语句;避免使用幻数(magic numbers);使用有意义的变量和函数名称,例如,使用‘radius’来代替圆的半径,而不是用‘r’来表示。
(17)了解底层知识。优秀的程序员不会只关注程序如何实现,而会深层次地剖析其实现机理,所以,程序员要对自己的操作系统和硬件要有足够的了解,从CPU的执行方法,到操作系统的运转,到程序的编译链接,到代码的加载与运行,到程序的调试,最后到实现的功能这一整套的内容,只有做到这样,才能真正提高。
(18)要聪明但不要“小聪明”。不反对走捷径,但是一定要论证充分,否则,可能会产生很多潜在的bug。编码中走捷径也许能够提高程序的可读性以及效率,但是如果论证不充分,不能把所有的潜在问题考虑周全,很有可能犯了丢了西瓜拣了芝麻的错误。最好的论证方法是多和他人商量,请别人检查自己的工作,将问题提早暴露。所以,不要为了做成某件事却忽略过程的连带效应,也许有一天你会为你当初的“小聪明”买单。
(19)要有创新的想法。对于大型企业而言,离开了创新,就等于失去了生命力,对于程序员个人而言,离开了创新,就等于停止了进步的脚步。虽然说天下学术全是抄,俨然一副“君不见创新项目一大堆,都被抄死化成灰”架势,但是不能因此而放弃创新,因为大地不可以因为有畜牲吃草而不复生机,山泉也不会因为有王八偷水而不冒活水。所以,无论工作有多忙,生活有多艰辛,都要尽可能地保持有一颗生机灵动的心。因为这个东西是别人偷不走的,也是最大的财富。即使暂时不具备这个东西,也要在生活中用心经营、好好培养。创新不一定要是改变全世界的大举,也不一定非得是世界上第一个做这件事的人,任何一种能改善生活的行为都可以认为是一种创新。例如写一个脚本去改变重复劳动或是采用什么方式解放自己。
(20) 对待知识要刨根问底,要有“打破沙锅问到底”的决心。“知识就像内裤,看不见却很重要”,在工作中,不能只知其然,不知其所以然,要不懈追求对细节一丝不苟的实干作风与敬业精神,而不是浮于表面,满足于填鸭,满足于考试交差或随便应付,请记住,这个世界牛逼的人少,装逼的人多,要从深层次去想其背后的思想和原理是什么。任何行业都有核心技术,掌握某一项核心技术,就可以让你进入这个行业并在其中生存,反之仅仅浅尝辄止,就会让你遭遇失败,抱怨不公。例如学会了C++面向对象程序设计,就应该弄清楚一个对象在编译后,在汇编代码中是如何被初始化的;就应该弄清楚这个对象的各个成员在内存中是如何存放的;就应该弄清楚当一个成员函数被调用时,编译器在汇编代码中加入了哪些额外的动作;就应该弄清楚虚函数的调用是如何实现的,而这些东西没有人强迫你去弄懂,只有你自己。想得多了,自己的层次才有可能提高,如果只是停留在被动的接受,那很难有所提高。
(21)尽可能复用成熟代码。如果有现成的允许使用的经过测试的代码或程序库,并且有人维护或维护成本可以接受,程序员应该尽量使用现有代码和库来节省时间和开发测试成本。
(22)多一份追求完美的执着。人是不完美的,但人们都在追求完美,程序也一样,所以程序员要去追求完美。追求完美的人更容易出色、更具责任心,做事往往也显得更专业。
(23)不要心存侥幸,可能出错的地方一定会出错,偶尔发生偶尔不发生的问题就是大问题。所以,对于一些常见的问题,一定做到防微杜渐:每个变量都做初始化;每个函数都做声明;引用每个参数都会做有效性检查;在可能出错的每个地方都会做边界条件检查等等。这样开发出来的程序一定会稳固很多,就是出错也会很容易修改。而一些没经过正规培训或是半路出家的所谓的高手,一般开发速度很快,三下两除二的就开发完成了,结果很可能出现“功能大体实现,bug总是在变”的情况,最后花费很长的时间来修改代码中的bug,总时间甚至会大大延期。而真正的高手,追求的境界是零缺陷代码。
每个人的路都在自己的脚下,自己过得怎么样,也只有自己心里明白。要想让自己的编程变得快乐有趣,还是应该努力培养一些好的习惯。也许上面的这些好习惯,要想都能在实际生活中落实并不是一件容易的事情,恐怕只有“大牛”们才能完全做到了,但只要你不断地朝着那个方向努力,相信你也会在这个努力的过程中得到长足的进步。