支付宝前端架构专家梁文森(绝云)与你探讨算法与数据结构

本文是对CSDN专家问答的汇总,原贴见支付宝前端架构专家与你探讨算法与数据结构(第十一期)

这个问答解决了很多我的疑问,要养成每天学习算法和数据结构的习惯,从今天起!

什么是数据结构和算法?

设计一个类不就是在设计一个数据结构吗?实现一个接口就是在写一个自己设计的算法或者应用经典的算法。平时写程序的时候设计的一个类就是一个数据结构啊。java里的set、map这些其实都是封装好的数据结构。array的sort方法之类的就是封装好的算法实现。自己写的程序里,表示流程的(一个函数?)可以看作算法;表示数据的(一个Person类?)就可以看作数据结构。数据结构和算法不是什么高大上的东西,其实都在我们平时写的程序里头了。

其实写程序就是设计算法、实现算法或者应用算法的过程(“程序=数据结构+算法”)。

为什么我感觉没有用到数据结构和算法?

这个和从事的领域、工作性质、技术栈、个人编程习惯各个方面都有关系的。譬如如果不从事游戏界面编程之类的,可能寻找最佳路径等场景都挺难遇得到;譬如如果不需要做AI,那很多数据挖掘相关的算法也不太有机会用得到;譬如如果不需要倒腾巨量数据,那很多索引、压缩、集群、并发相关的算法也没有用武之地了。加上很多大家熟知的“经典算法”可能从编程语言层面就封装好了,所以的确容易有这样的观点。

数据结构和算法在实际中是怎么用的?

我觉得如果按照经典的“程序=数据结构+算法”说法,平时写的程序也可以说是算法+数据结构的结合。并不是说一定要用上动态规划、KMP之类的才算是“用上了算法”。不过知名的算法大多是经过实践检验的、某种场景下接近最优解的算法,所以如果刚好碰上这样的场景,用经典的算法是比较可靠、高效的。举个例子说,Web开发中有可能会遇到在一个大的有序列表(譬如带自增id的聊天记录)中查找某一个纪录(不知道id,但知道大概的创建时间)的问题,这个时候就可以用二分法之类的算法来提升查找效率。

想想还是有不少地方可以用上“经典算法”的,譬如利用搜索相关的算法优化一下信息查询(数据库查询?全文搜索?);譬如在解释XML或者其它什么结构化数据的时候想一想树相关的算法;譬如做某个需求的时候先看看是不是某个经典算法的应用场景。。。

再者,脑子里的“经典算法”并不是要实际实现了才算是发挥作用。如果它的某种思路(动态规划?贪心策略?缓存化?)能帮助你用更好的设计去解决实际问题,那也不失为一种“应用”。

我不是做算法研究的,工作的内容集中在web上(即时通讯服务器/手游服务器/前端),应用场景大多数不涉及到很复杂的算法,遇到的性能瓶颈一般经典的算法也能完美解决,所以并没有什么“算法优化”的内容。

硬要说算法方面的能力,可能也就会根据不同的场景选用或者切换不同的算法而已。这个可能要实际问题实际分析了。譬如如果是一个对性能有严苛要求的场景,可能会用很多极端优化,不过可维护性很差的算法;譬如如果应用运行的环境内存很充分,对性能也有一定的要求,那么可以考虑采用“用空间换时间”的算法;譬如如果项目的维护周期特别长,对性能的要求也不是特别高,那么相比起复杂、优化到极端的算法而言,逻辑简单、易于维护的算法更是首选。

总之,每个算法都有它的优势和局限,都有最适合应用的场景。好好把握当前领域的算法特征,吃透这些适用场景和限制,就能作出相对较好的选择了。

其实写程序就是设计算法、实现算法或者应用算法的过程(“程序=数据结构+算法”)。要知道偏重哪些算法、有哪些经典算法,还是要分领域的。譬如偏数据处理的可能有一堆数据挖掘相关的算法;偏图像处理的也有一堆CG 相关的算法;偏处理流程(譬如设计DSL等)可能涉及图论的一堆算法等。不过无论如何,要写出优雅、结构良好的程序,的确是需要一定的算法功底的

怎么提高自己在数据结构和算法方面的理解力?

1.    怎么学,怎么设定短期目标呢?一定要动手做项目,最好选自己感兴趣、和某个长期目标(学分?职业规划?)相关的项目。在leetcode上刷题也不失为练习的方法啊,在解决具体问题的同时复习编程技巧和算法基础。当然就是有点功利,有点无聊了。学习算法比较重要的一点是一定要结合应用。光是看肯定理解不深,要实际去实现算法,在实际的项目里应用算法,才能对算法的原理、适用范围、优势和局限等方面理解得更深

2.     我觉得学习算法应该尽量去关注和理解它背后的初衷和局限,是解决什么样的问题,怎样解决的,解决得怎么样。这样无论是要应用到适当的地方,还是为解决新的问题做参考,还是要设计更好的算法,都有章可循。

3.     我对学习算法和数据结构最大的感触是:一定要动手多写。要搞清楚递归、尾递归都是怎么回事,就一定要实际写过相关代码,一行一行地调试去确认;要弄明白O(N)和O(logN)的算法有什么区别,也一定要实际动手写、动手跟踪代码。从最简单的算法开始,从最基础的算法概念入手,一遍遍地实践、理解。算法的描述对于很多初学者来说是全新的“语言”,光看是很难掌握的,一定要实际地去“用”起来。攻克一个算法之后,自然就会增加一点经验、一点自信,坚持下去总会形成良性循环的

4.     可以先了解一些基本的概念:什么是算法、怎么衡量一个算法(时间复杂度/空间复杂度)、有哪些经典的算法等,最好学习的过程中动手写写程序,自己实现一些算法、设计一些算法(找些经典的问题譬如八皇后问题、汉诺塔问题、背包问题等)。我觉得对程序员来说,数据结构和算法应该是必备的能力。写程序实际上就是设计算法、实现算法的过程。所以应该无所谓“用算法比较多的项目”。如果要说“经典算法(譬如你提到的排序)”能用在什么场合,我觉得有几个方面:1,平时写程序可以借鉴经典算法的思路,譬如用缓存化提高效率/采用类似动态规划的思路来剪枝等;2. 直接应用经典算法,譬如用hash替代array实现快速查找,用二分法加快搜索过程等

5.    如果单纯从优化算法的角度来看,我可能会推荐一些辅助方法:不是通过训练来提升技艺,而是通过可视化、对比的方式来排错。自己想好的某个优化方向对不对?不同的h(n)在不同的数据集下的表现如何,有哪些是有优化的潜力的?单纯用BFS、单纯用Dijkstra和用A star算法的差异是怎么样的?能不能把寻径过程可视化出来,看看究竟在什么样的场景下损耗的性能比较大,针对这一的场景能不能做特异化的处理?

相信你工作的性质已经可以经常接触算法实现/算法优化了。有时候埋头码代码,对着一堆字符调参数、调函数会很闷,会有恶性循环,会对自己的水准产生怀疑。但通常来讲实现算法的能力上下浮动并不会太大,是不是可以考虑用更直观的方式、代码以外的方式来辅助算法优化呢?每次调参数的时候做了什么,带来的结果是什么,处理时间、结果的精度是怎么变化的,把这些记录下来,用数据,用图表来指导下一步的工作可能也是一种可行的办法。



你可能感兴趣的:(数据结构和算法)