简介
本文主要从业务程序猿的角度来阐述问题。
2019.2.26 补充:为什么做搜索的公司技术都很牛?为什么要学数据结构与算法?为什么业务程序猿感觉数据结构与算法没用?剖析搜索引擎背后的经典数据结构和算法 光一个最最简单的搜索引擎涉及的数据结构和算法就有:图、散列表、Trie 树、布隆过滤器、单模式字符串匹配算法、AC 自动机、广度优先遍历、归并排序等。
首先,我们先回答一个孪生问题,再从“业务发展阶段” 及 “X/Y问题”视角来论证一下。
业务程序猿为什么要学习数据结构与算法
首先,笔者针对这个问题问了好几个大牛, 汇总如下
- 这不是大学基础专业课吗?基础的东西,也是it行业都必须要掌握的,不要问为什么要学,这是软技能,必须掌握
- 具体的数据结构是次要的,对目标问题的可利用的属性、数学模型的特殊属性、以及运行系统的物理属性保持高度敏感才是关键。数据结构课程不厌其烦讲解那么多例子就是让你建立这种“机敏”的世界观
- 数据结构基本就干两件事:对特定问题的有效存储,以方便更有效的检索。
- 不同的公司、不同的人做rpc框架,架构设计思路都差不多,最后实现的功能也差不多。但有的人做出来的框架 bug很多、性能一般、扩展性也不好,只是内部使用,而有的人可以被apache收录。高手之间的竞争其实就在细节,细节在技术上往往就是数据结构和算法。
- 数据结构不是最用不上的,数据结构是最普遍的,就像你可能认为数学是最用不上的时候,其实它无处不在
- 技术会有几个终极目标,比如最好的性能(包括最少时间和最少空间占用),还有最快交付结果。第一个和数据结构算法关系密切。虽然多数人并不需要自己写算法,只需要crud,但走到高级技术时,就要自己直面难题,不了解底下原理的话,就不容易做出合适的选择以及出深刻问题时如何排查。
- 数据结构,算法,作为编程基础,很有用,但未必有针对性的有用。很多日常工作可能根本不会直接用到。比如,高等数学有用吗?肯定有用,对你实际工作有很大帮助吗?未必,在实际逻辑开发中可能作用还不如一个简单的设计模式有用。我觉得你要看针对性,比如我是前一两年开始研究深度学习的时候,才去复习线性代数的一些算法比如梯度下降。如果关注架构,领域建模等层面,不太需要对数据结构和算法随时保持新鲜的记忆,有一点点“肌肉记忆”即可,如果你要做偏底层的开发,比如Southgate这种,才那可能会直接用到算法。
- 我觉得数据结构和算法属于提升层次的一个东西,具体点,对数据结构和算法敏感通常代码审美能力比较好,知道什么代码是好的,什么代码是低效的,数据结构最大的作用就是简化代码的复杂度和提高代码的维护性,典型的例子就是比如你用个前缀树啥的做搜索你可以很清楚时间复杂度和空间复杂度是多少,如果没这种数据结构的概念就容易写出低效的代码了。再补充一点,开源方案非常多,我们选择一些方案,进行技术选型的时候肯定会去稍微看看代码,美的代码会促进你使用,而评价美与丑就是看里面一些数据结构和小的算法的使用
笔者自己在交流中的一些体会
- 很多时候,是不学导致用不到,学到自然会找办法用到。就好比学英语,英语不好的程序猿不看英文文档,自然也体会不到英文的用处。
- 跟业务领域有关系,比如你在一家做地图的公司上班,对“图”相关的算法是一定要了解的。
业务发展阶段
有时候单说问题本身,是说不出所以然的,要place it in context,本文将context 定位为 公司的发展阶段。
一个互联网公司的发展通常有以下阶段:
- 业务为重,因为要生存
- 业务与技术并重,生存是第一的,但量级增大导致技术拖了后腿
-
技术驱动业务,最明显的体现在两个地方
- 大公司做一个app的成本极其低廉
- 最近流行的 为用户、主播、商家“赋能”
具体的说
- 互联网公司早期业务的本质是信息化,信息化体现在技术上就是crud,也就有了很多crud boy
- 早期用户、数据量不大
- “业务为重”体现在技术上 就是尽快的交付,无暇顾及数据结构与算法
- 后续,用户、数据量增大本身 对技术构成挑战
- 竞品的出现,以及用户需求的提高,不能止步于信息化,需要个性化、智能化
大部分公司 处在前两个阶段,所以业务程序猿 面对的事情更多是信息化和快速交付,因此对数据结构 与算法的 必要性感受不深。
一个很直观的例子, 大家谁能说的清楚自己的项目扛得住多大的QPS?有没有试过单机最大扛多少QPS?有没有体验过 最大QPS 下代码会出现哪些问题?很少。为何很多业务程序猿很少考虑这个问题呢?因为出了问题哪有时间想这些,代码逻辑没错就行,性能不够就加机器啊。
X/Y 问题
X/Y 问题说的是:你让我干Y,但其实为什么需要Y呢,是因为X,而实现X的方法 不是只有Y。说的是 做事情、看问题 要寻找本源。针对本文的问题可以衍射出两个问题
- 当我在说“数据结构与算法”的时候,我在说什么
- 数据结构与算法是Y,那么X是什么?
对数据结构的认识问题
大部分人在说 数据结构 和算法的时候,其实说的是大学学的《数据结构》那本书,再具体一点就是清华大学出版社的那本。那本书 定义了 我们看到 数据结构 这四个字时的条件反射,即线性表、树、图、排序算法等。
所以,我们说学习数据结构与算法有什么用?对大部分人来说,可以转换为:学习“线性表、树、图、排序算法” 有什么用? 就这个具体问题而言,除了代码里必不可少的数组/List 之外,其它的确实用的少。再者,笔者确实没碰到业务场景说 一定要将ArrayList 替换为LinkedList 。
对应前文中大牛提到的观点:数据结构基本就干两件事:对特定问题的有效存储,以方便更有效的检索。 所以数据结构不只是线性表、树和图,业务数据的结构化都可以归类到数据结构问题,进而考量数据有哪些检索场景?是否高效?
真的是为了数据结构本身么?
我们学习数据结构 与算法 是为了“更优的数据结构和算法” 本身么?不是,性能不高 加机器就好了呀。
我们学习数据结构与算法, 不是为了死记硬背几个知识点,是为了不断提高自己的意识
- 从无到有写代码的时候,培养对空间、时间浪费的罪恶感
- 从有到更好。出了问题,你的应对手段多一个思维方向,而不是只有“加机器”/“求助” 两条路
结合笔者的工作经历提一个问题:netty最牛的地方在哪里?用了nio?用了主从线程模型?内存零拷贝?数据处理pipeline?使用arena 接管内存分配和释放? 都对也都不对,是netty 在不断迭代的过程中,不断地对自己提要求,不断地挖掘问题点以支持更高的性能。
netty 的版本一直在迭代,业务当前很稳定,自然没有必要升netty的版本。类似的,如果你没有这样的意识,学数据结构与算法 也毫无必要。
如何学习数据结构与算法——有度的学习
数据结构 在技术中的 整体地位
做偏中间件开发的人,对算法和偏底层的比如网络的运用是比较多的,一般数据结构和算法能力都比较好,但他们对“工程”架构的东西关注不足。
因此凡事都可以一体两面的去看,技术能力可以分为
- 基础能力,包括但不限于语言、计算机组成原理、操作系统、数据结构与算法等
- 工程能力,如何应用基础能力,以及需求分析、项目设计、测试、维护和文档等
- 技术管理,人员项目协调、进度把控、技术氛围等
数据结构、计算机组成原理、操作系统等 经过文章、博客、课本的普及,成为一种“显学”。而“工程/架构”、”技术管理“等 因为模糊 提的少, 被归类为软技能。软技能在做他人/自我评估时,便容易被漏掉,一些工程能力/管理能力还不错的同学 也容易因为数据结构 不好而觉得不自信。
结合上文公司的发展阶段也可以看到,业务从无到有的过程 对工程能力和技术管理比较看重,业务从有到更好阶段 则更为看重基础能力。
有理有利有节
记忆有以下几种
- 有随时“新鲜”的记忆
- 不常用但是了解原理的“常识“记忆
- “肌肉”记忆,跟直觉一样
工作内容尽量要覆盖在新鲜记忆上。结合公司的发展阶段 以及自己的兴趣 爱好 和 定位 来把控自己的学习节奏,要不要学?学到什么程度? 很多时候,学不到位会误事,太超前了则容易受挫,进而打击积极性。此外,要随着项目、阶段的变化调整自己的策略,有些事要提前布局,有些事被动跟进就可以了。
个人微信订阅号