Skip to content

Instantly share code, notes, and snippets.

@fanfeilong
Last active May 11, 2024 05:49
Show Gist options
  • Save fanfeilong/fbea5c4683d91e587176 to your computer and use it in GitHub Desktop.
Save fanfeilong/fbea5c4683d91e587176 to your computer and use it in GitHub Desktop.
《编程格调》读书笔记

备注:笔记类帖子只是在看书过程中的结构化树形缓存,以及少量评注,只做以后整理的素材之用。

  • 格调妙语

    • 无论哪种情况,要点在于使代码的意图不会被误解,而非炫技。
    • 分支和分支不要纠缠在一起,把关系检测表达式调个方向,程序就更容易理解了。
    • 分支与分支纠缠在一起,在任何语言中都会引发困扰。
    • 语言细节虽然各不相同,但编程格调的原理是一致的。
    • 问题在于,一个小问题也许不会造成大的破坏,但是多处引发困扰语句形成的积累效应,就会使程序十分费解了。
    • 好的程序应该返回错误信息或诊断信息。
    • 在计算机程序中非必要的跳转,已经被证明是错误的一大来源,并且通常这表明程序员没能很好地掌控代码走向。
    • 批判性的阅读不要止于发现一个键入错误,甚至不良的整体思想。
    • 如何表达每一个语句很大程度上决定了程序本身是否易于理解,语句的完美表达是任何注释、格式规范或补充文档都无法替代的。
    • 所有人都知道调试程序是写程序难度的两倍。所以如果你写程序的时候尽可能的“精明”,那么将来如何调试它?
    • 生僻的表达通常是为了尝试编写“高效”的代码。
    • 就当前来说,一般而言我们观察到程序通常要读个几遍才能对其进行调试。
    • 程序中某个片段的意图越难把握,那么这个程序变成可以运作所花的时间就越长。
    • 尝试比编译器更高明,往往适得其反。
    • 在经过了这么多年之后,由于对“效率”错误的认识,我们还要被迫用二进制思考,这绝对是一个羞耻。
    • 我们要对这些重复样式引起警觉并寻找疏漏,为什么程序员不让计算机去处理这样的重复?
    • 如果通过电话大声朗读,其他人就能理解你的代码,这说明代码写的足够清楚。
    • 那么我们改进了什么?原则上说是可读性、局部性和程序结构的简单性。
    • 计算机程序是数据的表示和控制流的语句所塑造的。
    • 最简单的结构就是语句组--总是放在一起并按顺序处理的一组操作。
    • 当有两个不同的且互斥的操作都依赖于一个判断条件时,我们才应该使用ELSE。
    • 程序应该尽量这么写,用控制流的结构引导读者快速且直接地理解程序的意图
    • 术语“结构化编程”有时候说的就是把这些基本的结构合理组合起来的编程过程
    • 用日常语言构思代码
    • 任何语言写一个复杂的程序,都有一个有用的方法,这就是先用一个方便的、富于表达的伪语言来编写代码, 等到代码看起来正确的时候,再将代码翻译成要用的语言。
    • 伪代码不仅易读、精确,并且非常像常用的编程语言,我们同样可以对伪代码在编程格调上做规范,就像它能够被执行一样。
    • 如果一个程序有好的结构,那么它的布局会是清晰的。
    • 注释的数量并不能挽救代码的失败。
    • 一旦做了判断,就要去做对应操作,而不要做其他操作和判断。
    • 通常程序形式不好或者难以使用都是由于数据的表示形式与所做的工作不匹配造成的
    • 程序的缺陷往往是一个线索,意味着还有更多问题隐藏着
    • 与其试图修补这些错误,不如我们重新审视一下数据结构
    • 子例程、函数和过程都是“模块”,或者说是构建大程序的积木
    • 重复同样的判断,但是没有明显的组织形式,警示我们这是一个潜在的结构上的弱点
    • 把代码合理的划分到模块之中是编写程序很重要的一个方面
    • 输入输出常常是变化的,要将输入输出放到独立的模块中
    • 当程序开始变的庞大,模块化就是最重要的事情
    • 我们基于可读性的原则来组织程序的结构,不要花很大力气就能理解她
    • 把大的任务分解成合适的小块通常被称为“结构设计(Structured Design)”,有时也称为“合成设计(Composite Design)”
    • 不要信任任何数据
    • 程序设计的困难之处,就在于控制复杂度--将各个成分解耦、分别处理、而不要同时处理所有问题。
    • 一个编程编程关心的重点是确保程序能抵抗坏的数据,但是即使是应对正确的数据,都不能确保程序允许无误
    • 最严重的是逻辑上的错误
    • 寻找初始化错误的是困难和费时的
    • 我们阐述的多数例子讲的都是“边界条件”错误,错误出现在关键的数据值或者决策区域上。
    • 与人工想必,机器越来越便宜
    • “效率”就是要降低总成本,不仅仅是程序在整个生命周期里所耗费的机器时间,而应该把程序员和用户所花费的时间也计算在内
    • 代码写的易读,不一定就要以牺牲效率为前提,相反,编写可读的代码往往是保证程序运行有效率,以及方便程序维护和修改的唯一方法
    • 杂乱无章的程序常常出错
    • 性能的根本改进,往往是通过改变算法,而非微调代码来实现
    • 投入到选择好算法上的时间,比投入在精修差算法实现上的时间要更有回报
    • 对于任何给定的算法,在已经基本上稳定、简洁的实现上再画蛇添足,未必能收获什么重大改进,极有可能会适得其反
    • 计算机程序最好的文档是代码清晰的结构
    • 计算机唯一可靠的文档是代码本身
    • 如果代码存在错误,优雅的流程图和详尽的注释都是没有用处的。
    • 程序员确切懂得程序的唯一途径是阅读代码
    • 这并不是说程序员不要写文档
    • 具有可读性的文档是十分关键的
    • 对于注释、布局之类的问题,我们所要求的格调规则并不是绝对一致的
  • 格调规则

    • 撰写简洁的程序--不要耍小聪明
    • 简单并直接的表达你要说的意思
    • 使用库函数
    • 避免使用临时变量
    • 代码要清晰,不要为了“效率”牺牲可读性
    • 让机器干脏活。
    • 用函数代替重复的表达式
    • 加括号来避免歧义
    • 使用不会被混淆的变量名
    • 避免不必要的分支
    • 使用语言好的特性,避免使用不好的特性
    • 不要使用条件分支来代替一个逻辑表达式
    • 用“电话测试”来检查可读性
    • 使用DO-END和缩进来界定语句组
    • 用IF-ELSE强调两个操作中只有一个被执行
    • 用DO和DO-WHILE来强调循环的存在
    • 确保你的程序是自顶向下阅读的
    • 使用IF-ELSE IF-ELSE IF-ELSE来实现多路分支
    • 使用基本的控制流结构
    • 先用易于理解的伪语言编写代码,然后再翻译成你需要使用的语言
    • 避免使用THEN-IF和空ELSE
    • 避免使用ELSE-GOTO和ELSE-RETURN
    • 判断要尽可能紧挨着与之相关的操作
    • 使用数组来避免重复的控制流
    • 选择可以简化程序的数据表示方法
    • 不要止步于第一遍的代码草稿
    • 模块化,使用子例程
    • 让模块之间的耦合,变得可见
    • 每一个模块都应该做好一件事
    • 确保每个模块都隐藏好一些东西
    • 以数据为导向来构建程序的结构
    • 不要修补烂代码--重写它
    • 分块编写和测试大的程序
    • 对于递归定义的数据结构使用递归过程
    • 校验输入的合法性和合理性
    • 利用文件结束符号或结束标志来终止输入,不要让用户去计数
    • 识别出非法输入数据,如果可能则纠正之
    • 使用统一的形式出入文件结束条件
    • 让输入数据易于准备,并让输出数据意义不言自明
    • 使用统一的输入格式
    • 让输入数据易于校对
    • 仅可能选择自由格式输入
    • 使用含义自明的输入,指定默认值,将以上二者都输出
    • 将输入与输出局限在子例程中
    • 确保所有的变量在使用之前被初始化
    • 不要停留在一个BUG上
    • 使用调试编译器
    • 用DATA语句或INITAL属性初始化常理,用可执行语句初始化变量
    • 小心“差一”错误
    • 要注意对不等式进行正确的分支
    • 避免循环有多个出口
    • 确保你的代码巧妙地“不做事情”
    • 在边界上测试程序
    • 预防性编程
    • 10.0乘以0.1不等于1.0
    • 不要比较浮点数是否相等
    • 先做对,再做快
    • 在提高程序运行速度时,要保持其正确性
    • 先把程序改得简洁,再提高其运行速度
    • 不要为了“效率”上的蝇头小利而牺牲程序的简洁性
    • 让编译器执行平凡优化
    • 不要勉强地复用代码,应该进行改遍
    • 保证特殊情况真的有特殊性
    • 保持简单性,反而会更快
    • 不要为了提高速度而画蛇添足--去寻找更好的算法
    • 在程序中放置测试语句,“增效”之前先执行测算
    • 确保注释和代码一致
    • 不要用注释复述代码做的事情,每个注释都要有实际意义
    • 不要注释糟糕的代码--重写它
    • 使用含有意义的变量名
    • 使用含有意义的语句标签
    • 程序的格式要有助于读者的理解
    • 用缩进来体现程序的逻辑结构
    • 记录你的数据规划
    • 不要过度注释
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment