编程珠玑

一、绪论

  编程珠玑是一本很有影响力的书籍。它是作者对自己在长期的计算机程序设计实践中积累下来的宝贵经验的总结。行文生动形象,可读性高。在美国,它被作为低年级数据结构与算法的教材,同时,也作为高年级的算法辅助教材。它涵盖了算法课程和数据结构课程的大部分内容。不同于其他教材,他不强调单纯的从数学上分析,而是强调结合实际问题进行分析、应用和实现。话不多说,开卷有益。

二、概述

  这是第二次翻开本书。虽然被很多人推荐,但阅读一遍后,我并没有抓到什么重点。这次边读边记录,希望能够做到讲本书融会贯通。主要是记录为主,可能每一段都没有核心,也可能上下文没有逻辑性,强迫症或者性情暴躁者,慎读。

准确的问题描述

  在程序员的日常工作中,更多的工作更像是通过程序解决问题的过程。所以更好的描述问题,或者说是自己能够对需求更准确的转化成为问题,会对后续的程序设计帮助十足。将复杂的问题简单化,模块化。同时,能否准确的描述问题,也决定这你是否将要解决一个“正确”的问题。
  一般情况下,对问题的描述可以概括为三个方面:

准确的输入  

准确的输出  

准确的约束条件

算法,灵机一动

  先进的算法有时候对软件系统影响很大——减少开发时间,同时使得执行效率更快。在算法中所谓的灵机一动,看似是“看起来很困难的问题也可以有一个简单的、意想不到的答案”。算法的灵机一动,并非只有大量的研究以后才能出现,需要的是编程之前、之中和之后进行认真的思考。伴随着这种思考,往往就能捕获到这灵机一动。

数据决定数据结构

  恰当的数据视图实际上决定了程序的结构。通过重新组织内部数据是程序变得更好。在我们工作中,很多时候是可以用小程序完成任务的情况下,程序员往往最终写出了又大又纯的程序。其主要原因就是惰性:不去尝试思考,而急于完成最初的想法。
  程序员在节省空间方面无计可施时,将自己从代码中解脱出来,退回起点并集中心机去研究数据,常常会有奇效。数据的表示形式是程序设计的根本。退回起点的原则:

  1. 使用数组代替重复的代码
  2. 封装复杂结构
  3. 尽可能使用高级工具
  4. 从数据得出程序结构

编写正确的程序

  必须引起注意的是,编程技巧仅仅是编写正确程序的很小一部分,大部分内容还是:问题定义、算法设计和数据结构的选择。遵循这几点的话,编写正常的程序通常是很容易的。除此之外,要记得使用测试用例和断言等去验证程序的正确性。

让编写的程序真正可用

  程序员都是乐观主义者,他们总是认为讲编写完的程序,插入系统中就可以正常运行。在大部分时间是可行的,但是有的时候确实灾难性的存在,我们不得不需要在庞大的系统中,去寻找这个错误的小小的程序。
  良好的使用断言,可以知道程序的开发,同时也可以用来判断程序的正确性。这里作者提到了一个对于断言使用的一个小嘲讽:在测试时使用断言,而产品发布时将断言关闭的程序员,就好比在岸上操练时穿着救生衣,而下海时将救生衣脱下的水手。
  为了程序的可用性,往往自动测试和时间计数也显得至关重要。具有完整且完善边界测试用例能够保证程序的准确性,而且可以提高测试效率。同时,时间计数可以直观的观察程序的运行时间复杂度。

来聊聊性能

  一个简单而又功能强大的程序,往往令用户欣喜而不令开发者烦恼,这是程序的终极目标。而其中一个重要的元素就是效率。低效率的程序往往令用户沮丧。等待的时间越长,也就意味着越高的概率会失去用户。而如何提高效率我们往往考虑以下途径:

  1. 通过积累经验,选择恰当的方法
  2. 粗略估算运行时间
  3. 算法设计
  4. 代码调优

性能分析

  而在真正进行效率优化的时候,从计算机系统的层面我们应该从以下方面进行:

  1. 问题定义
  2. 系统结构:模块化;性能分析在系统设计阶段至关重要
  3. 算法和数据结构:快速的模块是基于其良好的表示的数据结构和操纵这些数据结构的算法
  4. 代码调优
  5. 系统软件
  6. 硬件

粗略评估

  任何事都应尽量简单,但不易于过于简单 —— 爱因斯坦

  我们知道简单的计算并不简单,因为我们为了补偿估算参数时的错误和对问题的了解不足,我们往往会选定和包含安全系数。

算法设计技术

  几个重要的算法设计技术

  1. 保存状态,避免重复计算
  2. 将信息预处理至数据结构中
  3. 分治算法
  4. 扫描算法
  5. 累加算法
  6. 下界

代码调优

  代码调优很重要的一点是把握调优的尺度。有些程序猿过于关注程序的效率,由于太在乎细小的“优化”,它们编写出的程序过于精妙,难以维护。而一些程序员很少关注程序的效率,它们编写的程序有着清晰漂亮的结构,但效率极低以至于毫无用处。往往获取更多的可用内存空间,需要在程序的性能、功能或者可维护性上做出牺牲,所以优化的前提永远是正确的决策。
  代码调优是一个在程序中需要做整体考虑的工作项目,但其根本目的是解决程序中开销过大的部分,对其进行少量修改,以提高运行效率。所谓开销包括CPU时间和程序存储空间。
  作者在文中给出了代码调优的原理:

代码调优的最重要远离就是尽量少用它  

  1. 效率的角色: 没有坏的话就不要修
  2. 设计层面: 只有确定没有更好的解决方案时,才考虑进行代码调优
  3. 双刃剑

节省空间

  努力的考虑一下空间紧凑的程序是很有意义的。在节省空间的同时,我们往往会得到运行时间上产生的副作用:程序小意味着加载更快,也更容易填入高速缓存中,操作的数据变少意味着操作时间变少等等。
  简单性可以衍生出功能性、健壮性以及速度和空间。
  这里列出一些较少程序所需数据的存储空间的技术:

  1. 不存储、重新计算
  2. 稀疏数据结构
  3. 数据压缩
  4. 分配策略
  5. 垃圾回收

排序

  将一些列记录排成有序的,最后也是最容易的办法就是使用排序函数库。但是并非总是有效的,这时我们别无选择,只能编写自己的排序函数。

  采用堆排序不会超过O(nlogn),并且只需要几个额外的字节。


写到最后

  读者用实践和经验去讲述程序中的问题,其实也是对我们工作和学习方法的一种提示。勿要死读书,读死书,要结合实际灵活运用。

------ 本文结束 ------
扫二维码
扫一扫,用手机访问本站

扫一扫,用手机访问本站

发送邮件