我从本书的第五章《高级控制流程》中总结出一下重点内容以及相应的见解:采用递归定义的算法和数据结构经常用递归的函数定义来实现;在推理递归函数时, 要从基准落伍测试开始, 并认证每次递归调用如何逐渐接近非递归基准范例代码;尾递归调用等同于一个回到函数开始处的循环;将throws子句从方法的定义中移除, 然后运行Java编译器对类的源代码进行编译, 就可以容易地找到那些可能隐式地生成异常的方法;工作群并行模型用于在多个处理器间分配工作, 或者创建一个任务池, 然后将大量需要处理标准化的工作进行分配;基于线程的管理者/工人并行模型一般将耗时的或阻塞的操作分配给工人子任务, 从而维护中心任务的响应性;基于进程的管理者/工人并行模型一般用来重用现有的程序, 或用定义良好的接口组织和分离粗粒度的系统模块.;基于流水线的并行处理中, 每个任务都接收到一些输入, 对它们进行一些处理, 并将生成的输出传递给下一个任务, 进行不同的处理;在阅读包含宏的代码时, 要注意, 宏既非函数, 也非语句;do…while(0)块中的宏等同于控制块中的语句;宏可以访问在它的使用点可见的所有局部变量。
第六章《应对大型项目》是对我们今后遇到大型项目的策略和经验的指导。我觉得以下是本章节中比较值得重视的内容的:我们可以通过浏览项目的源代码树—包含项目源代码的层次目录结构, 来分析一个项目的组织方式, 源码树常常能够反映出项目在构架和软件过程上的结构;项目的源代码远不只是编译后可以获得可执行程序的计算机语言指令; 一个项目的源码树一般还包括规格说明|最终用户和开发人员文档|测试脚本|多媒体资源|编译工具|例子|本地化文件|修订历史|安装过程和许可信息;检查大型编译过程的各个步骤时, 可以使用make程序的-n开关进行预演;定制编译工具用在软件开发过程的许多方面, 包括配置|编译过程管理|代码的生成|测试和文档编制;可以用断言来检验算法运作的步骤|函数接收的参数|程序的控制流程|底层硬件的属性和测试用例的结果;可以使用测试用例的输入数据对源代码序列进行预演。
我从第七章《 编码规范和约定》中认识到了:在知道了给定代码库所遵循的文件组织方式后, 就能更有效率地浏览它的源代码;阅读代码时, 首先要确保编辑器或优美打印程序的tab设置, 与代码遵循的风格规范一致;分析代码时, 对标记为XXX, FIXME和TODO的代码序列要格外注意: 错误可能就潜伏在其中;在遵循Java编码规范的程序中, 包名(package name)总是从一个顶级的域名开始(例如, org, com), 类名和接口名由大写字母开始, 方法和变量名由小写字母开始;如果GUI功能都使用相应的编程结构来实现, 则通过代码审查可以轻易地验证给定用户界面的规格说明是否被正确地采用;了解项目编译过程的组织方式与自动化方式之后, 我们就能够快速地阅读与理解对应的编译规则。
从第八章《文档》中我学习到了:系统的规格说明文档:详细描述系统的目标、系统的功能需求、管理和技术上的限制、以及成本和日程等要素;软件需求规格说明:提供对用户需求和系统总体结构的高层描述,并且详细记述系统的功能和非功能性需求,比如数据处理、外部接口、数据库的逻辑模式以及设计上的各种约束;系统的设计规格说明:一般描述系统的构架、数据和代码结构,还有不同模块之间的接口;系统测试规格说明:包括测试计划、具体的测试过程、以及实际的测试结果;用户文档:包括功能描、安装说明、介绍性的引导、参考手册和管理员手册;文档可以快捷地获取系统的概况, 了解提供特定特性的代码,有助于理解复杂的算法和数据结构,能够阐明源代码中标识符的含义,够提供非功能性需求背后的理论基础;文档常常会提供不恰当的信息, 误导我们对源代码的理解. 两种不同类型的歪曲是未记录的特性和理想化表述;总是要以批判的态度来看待文档, 注意非传统的来源, 比如注释|标准|出版物|测试用例|邮件列表|新闻组|修订日志|问题跟踪数据库|营销材料|源代码本身;文档两种类型:二进制文件和文本文件;在应对体积庞大的文档时, 可以使用工具, 或将文本输出到高品质输出设备上, 比如激光打印机, 来提高阅读的效率。