我不是天才,但我相信,通过有效的方法和训练,以及持之以恒地积累,完全是可以成为一名出色的开发者的。那么,到目前为止,掌握了多少思想、方法和技术可以用于开发程序、处理软件开发过程中所遇到的问题呢?不妨作下总结,以备后用。
1、抽象
萃取出主要特征,而摒弃次要不相关的特征;无需了解物质的内部结构而基于其提供的抽象来构造其应用;声明与实现相分离。计算机科学中的抽象俯拾即是,比如汇编语言是对机器硬件的抽象,编译器是对高级程序语言的抽象,进程是对程序一次执行的抽象,线程是对任务单元的抽象等。
2、分层
将系统分解为多个层次,精确定义每层所提供的服务及层次之间提供的服务接口;处于某个层次的层依赖于下一层提供的服务,并为上一层提供服务;各层之间无需知道彼此的细节。典型例子是网络协议栈及操作系统虚拟机的概念。
3、模式
在《水平思考的力量》一书中谈到,大脑的运作机制主要是模式机制,即通过模式存储、识别、连接和提取来实现思考。生活中无时不刻使用着模式,模式提高了人们的适应能力和反应能力。设计模式是模式思想在软件设计中的运用。
4、缓存
将一部分已求解值存储起来以备后用;或者将一次性存储一部分数据(包括但不仅含有当前所需数据),以便之后紧随着访问。动态规划法是使用缓存技术的典型例子。
存储器高速缓存是缓存技术的又一典型例子,与程序局部性原理密切相关。要想达到更好的程序性能,则必须采用一定手段,使得访问数据的顺序与数据在存储器中的存储顺序保持一致,这样才能提高命中率,防止大量的缺页中断带来的低效。
5、科学原理和性质
深刻理解科学原理和性质,往往能够催生非常简洁高效的算法和技术,这可能就是计算机科学家与开发者之间的一大区别吧。比如上述异或的妙用,就是基于对异或性质的深刻理解上。还有向量的旋转问题,将ab转换为ba, 也是基于对逆置性质的深刻理解上。R(R(a)R(b)) = ba
6、二分搜索技术
用于在有序数组(连续物理存储块)中查找给定关键字,时间复杂度为O(logn)。
例子: 在有序数组里找出给定关键字出现的次数;在不重复的若干整数中找出不存在的整数; 程序调试技巧;
7、分区技术
给定一个列表,从中选定一个主轴元素,将它置于某个位置,并将列表中的元素分为两个部分:使前半部分的所有元素都不大于该元素,后半部分的元素都不小于该元素。
例子:快速排序,找出第k大的元素(顺序统计量),请参阅算法相关书籍。
8、分治技术
将一个任务分解为多个子任务,然后分别求出这些子任务的解,最后综合这些子任务的解,得到总任务的解。时间复杂度是T(n) = aT(n/b) + G(n),主要因素取决于a, b , G(n)。
例子: 最近对问题,归并排序。
9、递归技术
一个规模为N的问题的解可以由规模为S(S<=N)的同样性质的问题的解来构
造。T(N) = T(S) + G(N). 递归技术是一种非常有效的程序设计技术。
例子: 汉诺塔,二叉树操作
10、时空权衡技术
通过额外操作以时间换空间,或者额外空间存储以空间换时间。在PC机上,通常是以空间换时间,例如,哈希表就是一个典型例子。
以时间换空间的例子,比如说在内存不足的情形下进行海量数据处理,可以采用k 趟遍历,每趟遍历解决一部分数据,得到一些子结果,最后将子结果合并。这样在I/O读写上可能耗费较大量的时间。当k比较小时,采取k趟排序是一个较好的选择。