曾经有个说法,程序=数据结构+算法。这在面向过程的编程语言流行的年代是很受推崇的。
然而,随着时代的发展,各种编程语言的出现,各种编程模式的发明,面向对象、设计模式、框架、模型等各种概念早已淹没了当年那个简单的提法。
那么,在这个多样化的年代,如果想立志做编程开发,还有没有必要学好数据结构和算法呢?
我的回答是,非但有必要,更应该学好、学博、学精。
第一,数据结构与算法是程序的灵魂,是朴素的基础,学好它有有助于理解各种上层抽象。
在没有充分学习和理解数据结构与算法的基础上去学习面向对象、设计模式,是无法真正体会这些上层抽象的真正意义的,最终可能会导致学之泛泛,用之泛泛。
在工作中,见识了太多开口设计模式,闭口面向对象的人,在某个具体的问题上,问他为什么要用面向对象,为什么要用这样的设计模式,得到的回答相当空泛,有时候甚至是为了对象而对象,为了设计而设计。这样的人,做出来的设计,往往过度设计,似是而非,导致做出来的东西混乱不堪。
遇到的真正设计高手,还没有一个是对数据结构与算法是不精通的。让他讲为什么这样设计,为什么这样架构,他往往能深入浅出,将面向对象的思想、设计模式的考虑,与基础的数据结构和对应的算法结合起来,贴合问题的实际情况,给出良好的结论。
有人可能会抬杠:照你这么说,是基础就要学,那是不是还要把CPU的物理原理学透了才能写程序?
我的回答:你说的还真对,一个对CPU的运行原理不清楚的人,是不可能真正理解现在流行的SMP架构、MPP架构的,也不可能写出高质量的并发程序。这其中当然有个量的问题,但没有质的差异。
从编程的角度来看,数据结构与算法几乎是最朴素的基础知识了,这是关,是每一个立志当好程序员的必经之路,不管你是想学C还是想学JAVA,不管你是想学面向过程,还是面向对象,不管你是想当架构师,还是想当DBA(一个没有良好算法底子的DBA差不多算是半个残废)。
第二,在编程实践中,数据结构和算法随处可见,影响重大。
有人说在工作中没用到数据结构和算法,这是一种误解。并非让你去实现一个链表才叫使用了链表。这可能与大学里教条的教学有关,一味地讲这些数据结构是怎么编程实现的,一味地讲这些算法是怎么证明的,却忽视了学习这些的主要目的是为了在编程实践中去应用它,而不是去重造轮子再发明一次(当然也有少数在算法领域继续深造作出新贡献的人,这里就排除不讲了)。
见过不少对链表的基本属性都不了解的人,在程序里一味使用数组,内存能开多大就多大;也见过太多根本不知道HASH原理的人,对Hash表随意使用,造成KEY值严重重复、效率极为低下、失去了选用HASH的初衷。
即使不是算法密集型的程序里,哪怕是面向业务的编程工作中,能够适当地应用数据结构,选择恰当的算法,也是能极大地提高程序的开发效率、运行效率和运行稳定性的。更不要说面向业务和工作流的基础平台,本身就含有大量的数据结构与算法理论,想利用好这些平台,没有一个好的底子,那会事倍功半的。
第三,现在的软件工程充斥着大量的过度设计、资源浪费,实际上已经到了硬件承受不了的地步了。学好数据结构和算法,能够从根本上去避免这些问题。
从我这里的5年经验来看,J2EE就是最佳代表。一个WAS应用,能够承受的并发用户数,竟然只有区区的100!!花费百万元的投资,去买几十个CPU、上百G内存,花费十倍甚至几十倍的代价,却只能提升百分之几十的效率。这还是一个产品级的应用,是一个大型银行核心的数据服务之一。那就更不用提在水平更低的项目组中那些可笑的效率问题了。
这是J2EE、JAVA的错吗?我不觉得,我同样见到了设计良好的J2EE产品,效率一流,稳定性极佳。主要原因,还是开发者自身的水平,对算法无知到了极点,对数据结构忽视到了极点。
第四,当今流行的WEB新时代,各种云概念,海量数据,百万用户并发(从以前著名的C10K问题,到现在的C1000K甚至更高问题),最终都是数据结构与算法的比拼。这一切,较量才刚刚开始。
这里我就不展开了,虽然我这5年来做的主要工作就是这方面的(其中一点)。但它离初学者的层面还是太远了,每一点展开都是工程实践大部头论述。
最后,说说对于初学者来说,该怎么去学数据结构与算法。
1、常备参考书。即使不能通读,也要时时备查
2、已有的数据结构与算法,怎么实现是末节,能理解原理、明白适用场合才是重点。
3、不必过度追求怪异算法,适用的就是最好的,简单的才是最佳的。
4、多读开源作品,看看他们是怎么熟练应用那些基本的数据结构与算法的。
5、希望你能在融会贯通的基础上,举一反三,来教教我怎么继续深入学习。因为我目前也卡在更高深的算法泥潭中不能自拔