子龙
对
代码大全
的书评
发表时间:2016-04-02 01:04:49
详细的笔记也同时放在了我的博客里:《代码大全(第2版)》笔记
---
title: 《代码大全(第2版)》笔记
date: 2016-08-28 21:05:43
tags:
- 代码大全
- 读书笔记
---
### 记
按照阅读顺序来记录吧。并没有按照书页顺序来读,而是听从了译序里的“这本书适合谁看,该怎么看”的建议。先看了18章(初级程序员)、11章(低年级学生)、第8章(防御式编程)、第7章(自学
编程的人)、第13章(喜欢参与网上争论的人)。看完这几章之后,就开始顺序看了。
总体感觉,这本书是属于“软件工程”范畴的。译序里提到:“这本书讲的正是为了到达‘编码完成’这一重要里程碑所必需的软件构件技术,确切地说,就是如何编写高质量的代码。作者认为,应该首先为人编写代码,其次才是为机器”。这差不多就总结了这本书的主旨。
这个笔记最初是在豆瓣上面一点点记录的,顺便还发现豆瓣上面这本书的一个特点:目前其书评大概是隔2个月会有人写一篇;本书出版10年,共计90篇书评,平均每年9篇。相对于那些畅销书,这样的评论增幅的确较慢,估计也是因为本书非常厚重、比较偏技术类的缘故了。
即使那么多年过去了,程序员在工作时的常见心理表现似乎没什么大变化。程序员普遍自负,例如23.4节说的,“就算是已经看到了一个缺陷,你的自负还是会让你觉得自己的代码完美无缺”。~~
<!-- more -->
### 第3章 三思而后行:前期准备
> 【49页】
> 错误处理已被证实为现代计算机科学中最棘手的问题之一,你不能武断地处理它。有人估计程序中高达 90% 的代码是用来处理异常情况、进行错误处理、或做簿记工作,意味着只有 10% 的代码是用来处理常规的情况。
> ……最好在架构层次上对待它。
### 第4章 关键的“构建”决策
> 一套好的符号系统能把大脑从所有非必要的工作中解放出来,集中精力去对付更高级的问题,从功效上看,能够有效地提高人类的智力。
以及:
>【4.3】
> 在我的职业生涯中,我看到了PC之星的升起和大型机之星的陨落,我看到图形用户界面程序代替了字符界面程序,我还看到了Web的崛起和Windows的衰落。(2004年)
### 第5章 软件构建中的设计
这一章提到了本书的核心理念:
> 管理复杂度是软件开发中最为重要的技术话题。在我看来,软件的首要技术使命便是管理复杂度,它实在是太重要了。
以及,程序员的基本职业操守就是:
> 要写出既让自己容易理解,也能让别人容易看懂,而且很少有错误的程序代码。
>【第90页】:
> 封装帮助你管理复杂度的方法是不让你看到那些复杂度。
### 第11章 变量名的力量
> 临时变量,这个名词很奇怪,因为真的是“无论从那种角度看,你程序中的大多数变量都是临时性的。把其中几个称为临时的,可能表明你还没有弄清它们的实际用途。
【275页】给出了CPP/Java的非正式变量命命名规则。然而似乎没有见过针对JavaScript的呢。。。(待调研)
为变量命名这个事情,也挺考验程序员的英语词汇量的。
### 第12章 基本数据类型
>【第292页】
> 避免使用“神秘数值” 神秘数值是在程序中出现的、没有经过解释的数值文字量。如果你编程用的语言支持具名常量,那么就用它来代替神秘数值。
> 即使你确信某个数值在代码中永远也不会改变,使用具名常量也会有助于提高可读性。
> 一条很好的经验法则是,程序主体中仅能出现的(数字)字面量就是 0 和 1 。
### 第15章 使用条件语句
> 【第363页】
> 利用 default 子句来检测错误
> 如果一条 case 语句中默认子句既没有用来做其他的处理,按照正常执行顺序也不太可能会发生,那么就向里面加入一条诊断消息。
的确,很多时候编辑器的 Lint 工具会提示我们一定要加上一个 default 子句,然而有时候真的不知道该在里面写什么。上面的建议很不错。
### 第16章 控制循环
> 【第382页】
> 在嵌套循环中使用有意义的变量名来提高其可读性
### 第18章 表驱动法
表驱动法就讲了三类方法:① 直接访问;② 索引访问;③ 阶梯访问。
### 第20章
> 虽然开发一个高质量产品的最好方法似乎就是专注于产品本身,但就软件质量保证而言,你还需要关注软件开发的过程。
要尽可能多地找出缺陷,靠一种技术肯定是远远不够的,需要多种技术联合使用。例如,进行功能检查,单元测试,代码阅读。这三个就是最基本的了。而我目前的措施,顶多只有功能检查和代码阅读。非常缺少单元测试。
### 第21章 协同构建
对于协同构建技术的一个相关思想比较有趣而且也非常符合在实践中的感受:
> ……那就是在工作中,开发人员总会对某些错误点视而不见,而其他人不会有相同的盲点,所以开发人员让其他人来检查自己的工作是很有好处的……攻击这些盲点就成为了有效构建的关键。
> 正如 Karl Wiegers 所指出的那样:“由人进行的复查能够发现不明显的错误信息、不恰当的注释、硬编码的变量值,以及重复出现的需要进行统一的代码模式,这些是测试发现不了的。”
想到一个话题,“经验丰富的程序员的价值究竟体现在哪里”,窃以为,其人工执行代码检查从而发现潜在问题、漏洞、缺陷的能力,可以弥补测试的不足、减少上线后的BUG率,从而为整个项目节约成本。这便是其价值体现之一。
> 【第482页】
> 一个采用正式检查的团队报告称,复查可以快速地讲所有开发者的水平提升到最优秀的开发者的高度(Tackett and Van Doren 1999)。
### 第22章 开发者测试
> 有些程序员会将术语“测试(testing)”和“调试(debugging)”混用,但是严谨的程序员会区分这两种活动。测试是一种检查错误的方法,而调试意味着错误已经被发现,要做的是诊断错误并消灭造成这些错误的根本原因。
在最近的开发体验中(说白了,就是指工作啦),深感开发者如果能够进行充分的自测,那么其交付的软件质量,将会更高,对代码质量(可维护性、可靠性、容错能力等)也都会有相应的(以及间接的)帮助。然而:
> 测试对于绝大多数开发人员来说都是一种煎熬……
>
> 开发者测试应该占整个项目时间的8%~25%
519页有一条很有趣,而且自己也遇到这样的事情:
> 让人惊奇的是,笔误(拼写错误)是一个常见的问题根源……我的一位同事仅仅借助一个拼写检查工具对可执行文件中的所有字符串进行检查,就在我写的一个程序里发现了许多的错误。
说真的,编码过程中,还是应该尽量使用拼写正确的英文单词~~
**测试数据生成器(test-data generators)**是用于产生对自己的代码进行测试用的数据的类或工具,作者在【524 页】提到了自己的一个经历,总结认为:
> 比起手工构造测试数据,随机数据生成器可以更加彻底地对程序进行测试。
这个概念目前我们也正在试用,对于线下无数据的情形比较有帮助。
### 第23章 调试
程序员背锅誓言:
> **要知道,如果你写的程序出了问题,那就是你的原因,不是计算机的,也不是编译器的。程序不会每次都产生不同的结果。它不是自己写出来的,是你写的,所以,请对它负责。**
有种编程方式叫做迷信式编程(programming by superstition),迷信式编程的同学大概是这样子的:
> 每个团队里也许都有这样一个程序员,他总会遇到无穷的问题:不听话的机器,奇怪的编译器错误,月圆时才会出现的编程语言的隐藏缺陷,失效的数据,忘记做的重要改动,一个不能正常保存程序的疯狂的编辑器……
以及新手程序员常犯错误:
> 因此,如果你从一开始就假设错误是你引发的,就能避免陷入这样的尴尬境地:在公众面前先指责别人犯了错,最终却发现错误其实由你而生。
550页:
> 当你的编译器输出了一大堆的错误信息时,如果无法迅速找出第二条或第三条错误信息的源头,不要担心。先把第一条处理了,再重新编译。
### 第33章 个人性格
这一章的主题,像是对程序员的职业发展、学习方法给出合理中肯的建议。
要保持谦逊的品质。
> 在成长为高手的过程中,对技术事物的求知欲具有压倒一切的重要性。
> 技术环境的特定特征每5到10年就变化一番,如果没有足够的求知欲来跟上这些变化,你就面临落伍的威胁。
> 学习编程的一个特别好的途径是研究高手的程序。
> 如果每两月能看一本计算机好书,大约每周35页,过不了多久,你就能把握本行业的脉搏,并脱颖而出。(824页)
> 当初学者或中级程序员不是错,当熟练级程序员而非技术带头人也无可厚非。但如果知道自己该如何改进后,还总是在初学者或者中级程序员阶段徘徊,就是你的不对了。
> 比尔·盖茨说,任何日后出色的程序员前几年就做得很好。从那以后,程序员好坏就定型了(Lammers,1986)。