什么?程序竟然等于数据结构 + 算法?
这个公式是大师 Niklaus Wirth 在 1976 年提出来的,40 多年过去了,这个公式还成立吗?
对于做 Java 开发的朋友,可能会更加的赞同这个公式:
程序 = 框架 + SQL
今天,我们就来说说这些公式,我们先从 CRUD 开始说起
做 Java 开发的朋友,大部分都知道 CRUD,也就是 Create、Retrieve、Update、Delete 四个英文单词头字母的缩写,翻译成中文就是【增删改查】的意思
也有很多人称我们 Java 开发人员为【CRUD Boy】,因为我们的工作内容一般就是面向数据库的增删改查,有的时候,有些人甚至还会带着轻蔑的语气说,你只会 CRUD 吧
我想说的是,我只会 CRUD 怎么了?软件开发的本质不就是 CRUD 吗?
不信你来看下大神 Josh Bloch (JDK 源码作者之一) 写的代码,你可以打开 JDK 的源码,来看两个类的源码:
java.util.ArrayList
java.util.LinkedList
这两个类都包含常用的 add、remove、set、get 等 CRUD 的方法
以上我们只看了大神 Josh Bloch 写的两个类,你看,大神写的代码也是离不开 CRUD 的
你可以打开任何一个类,类的方法绝大部分是逃不过 CRUD 这四种操作
软件开发属于信息技术,信息技术本质就是对数据的处理,既然要处理数据,那么首先要解决数据存储的问题,也就是将数据 add 到某个地方,按照某种规则存储起来
当要用数据的时候,就去存储数据的地方,按照一定的规则查询指定的数据,有的时候还需要删除不用的,或者要更新已经存在的数据,说白了,不就是数据的 CRUD 吗?
说到数据的存储,我们都知道,数据是存储在磁盘中的,但是为了能快速的查询操作数据,我们会将数据组织成符合查询要求的结构,比如线性结构、树结构甚至图结构等,这就是我们所熟知的数据结构
作为 Java 开发,我们一般处理关系型数据的时候,都会把数据存储在 MySQL 这种关系型数据库中,为了提升数据库的 CRUD 效率,关系型数据库一般会将数据组织成像 B 树或者 B+ 树这种树结构
有了 MySQL 后,Java 业务开发就变简单了,我们只需要根据业务写 SQL 了,这些 SQL 本质上就是对数据库,或者说是对 B 树这种数据结构的 CRUD 了。
从这里我们看出,MySQL 中的数据都是组织成 B 树这种数据结构,然后,我们写的每个 SQL ,本质上就是对 B 树这种数据结构的 CRUD,这些 CRUD 操作就是基于 B 树这种数据结构的算法,看到这里,你是不是会认同程序 = 数据结构 + 算法这个公式呢?
上面我们是站在 SQL 的角度来分析的,你可能还会问,那框架代码呢?有了框架,我们只要简单的使用框架给的 API 就可以了,这里也可以说程序 = 数据结构 + 算法?
如果我们脱去框架的华丽外衣,看看它的本质,你的眼界会得到开阔
我们以大家熟悉的 Spring 框架来举例,Spring 中的核心功能是 IOC,说白了就是维护对象与对象之间的引用关系,在这里,你可以将每个对象看作一个顶点,对象与对象之间的引用看成一条边
而且边是有方向的,比如对象 A 持有对象 B 的引用,那么顶点 A 到顶点 B 的边的方向就是 A --> B 了,表示对象 A 依赖于对象 B
在一个系统中,会有很多的对象,对象与对象之间有依赖关系,这样,不就形成了一个有向图吗?
也就是说 Spring 管理的对象之间的关系,本质上就是一个有向图结构,那么 Spring 中所有的功能其实就是基于有向图这种数据结构之上的 CRUD 来实现的
可以看出,对于框架,如果脱去华丽的外衣的话,本质上也是数据结构 + 算法
以上,我们是站在整个框架的层面上来看数据结构与算法的
实际上,对于每一个有成员变量的类来说,都是一个数据结构,数据存储在类中的成员变量中,类中方法基本都是对成员变量中的数据进行 CRUD,也就是说类中每个方法其实就是一个算法了
但是,要实现像 Spring 这种大型的框架,需要成千上万个类,这些类怎么组织起来呢?这就要用到设计模式来组织成千上万个类了
所以,在面向对象的世界里,这样说可能会更加的合适:
程序 = 数据结构 + 算法 + 设计模式
一个做 Java 开发的,做了一段时间后,如果只会:
做面向数据库的 CRUD 的工作
调用框架提供的 API
那么,你很容易被以下两种人所替代:
刚毕业的应届生,他们要求的薪资比较低,还喜欢干活
刚培训转行 Java 的人,他们刚转行,一开始要求也低
我们 Java 开发只会 CRUD ,这是没错的,而且是好事,但是如果你只会面向某种数据库 CRUD 的话呢,你就很容易达到瓶颈
其实,很多人带着轻蔑的语气说你只会 CRUD,很多时候他说的就是你只会面向数据库的 CRUD
这个时候,你会想着怎么提升?
重点来了,其实提升需要做到两个方面:横向提升 和 纵向提升
1. 横向提升
对于如何横向提升的话,我们向 JDK 源码大师 Josh Bloch 学习就可以了。
我们 Java 开发为什么容易达到瓶颈,其实本质上就是因为我们只懂面向数据库的 CRUD,或者说我们只懂面向 B 树这一种数据结构的 CRUD,也就是说技能太单一
你看 JDK 源码大师 Josh Bloch,他之所以厉害,是因为他不单单懂 B 树的 CRUD,他还精通 ArrayList、LinkedList、HashMap、TreeMap 等各种各样的数据结构的 CRUD
当然,你想提升的话,也不要求你对所有的数据结构的 CRUD 都精通,这也没必要,至少你需要对一些常用的数据结构精通,比如:数组、链表、栈和队列、二叉树、二叉查找树、AVL 树、红黑树、B 树、哈希表、堆和优先队列、跳表、字典树、图结构等
所以说,你如果真想提升的话,你首先要做的就是:掌握各种各样的常用的数据结构的 CRUD,这样你的视野会变得很开阔,编程能力也能得到非常大的提高,你被取代的概率就少了很多,这就是横向提升
掌握各种各样的比较基础的数据结构的 CRUD?这谈何容易,很多人会这么认为的,当然可能也包括你,就是觉得一个字:难
但是,如果把每一个数据结构的每个操作,拆解好了,然后再来学,你还觉得难吗?你可以体验下下面的两个例子
第一个例子:删除双向链表中指定索引的节点
第二个例子:平衡二叉树 - AVL 树中增加元素时的右旋转操作
除了数据结构,算法也是一个非常重要的部分,可以这么说:数据结构与算法就是程序的灵魂了,同时也是一个 Java 程序员安身立命的核心竞争力所在
对于算法的话,我们一定要培养自己的算法思维,对于程序一步一步的选择合适的数据结构,然后达到优化程序的目的,我们来看一个算法问题
这个算法问题是 leetcode 里面的第 1 号算法题:两数之和
题目描述:
给定一个整数数组 nums 和一个目标值 target
请在数组中找出和为目标值的两个元素,并返回它们的数组下标
注意:数组中同一个元素不能使用两次
示例如下:
输入:nums = [2,7,11,15], target = 9
输出:[0,1]
解释:因为 nums[0] + nums[1] == 9 ,
返回 [0, 1] 。
如果上面的题目描述你没看懂的话,可以看下面视频解释,如果题目你已经懂了,下面的视频可以跳过呢
当面对一个算法问题时,先尝试使用最简单、最暴力的解法来解决,这道算法题的暴力解法就是线性查找,看下面的视频讲解:
当暴力解法的时间复杂度很高的时候,我们可以尝试对暴力解法进行不断的优化,请先看使用二分查找来优化算法:
二分查找虽然可以优化降低时间复杂度,但是还有一个时间复杂度更低的哈希查找,接下来我们来看看怎么使用哈希查找,进一步降低时间复杂度:
接下来就是追求算法的极致性能,只有这样,才能培养你的算法思维,提高你的编程水平,看下面对这个算法的进一步优化:
你看,对于算法,就应该这样去不断的训练,训练多了,你还怕算法和数据结构吗?你还怕写代码吗?
如果,这样学习数据结构,这样刻意练习算法的话,相信,在很短的时间内,你的编程能力会提高好多个档次的
因为篇幅的原因,这里我也只能放一个算法的讲解,更多的数据结构与算法的学习和练习,请长按下面的二维码,然后可以查看:
说完横向提升,接下来,我们再来讨论同等重要的纵向提升
2. 纵向提升
所谓纵向提升,就是针对每个常用的技术,往深处学习,比如 Spring、MySQL 等技术
不管你怎么学习这些技术,你永远绕不开每个技术对应的底层数据结构的话题
比如你想学习 MySQL 的话,你就得搞懂 B 树或者 B+ 树这种数据结构,对基于 B 树或者 B+ 树之上的算法也是需要搞懂的
比如你想深入学习 Spring,甚至说你想看 Spring 的源码,那么你就需要对图结构及其算法搞懂
我们有很多人尝试去看 Spring 源码,但是很多人都放弃了,因为觉得看不懂,甚至去网上看一些老师讲源码的视频,但是也很难看懂,其根本的原因就是你、甚至讲源码的老师都不懂图这种数据结构及其算法
可以看出,不管是横向提升还是纵向提升,你都绕不开一个很重要的话题,那就是【数据结构与算法】
那么,数据结构与算法这么重要,为什么很多人会不知道呢?
这是一个事实
数据结构与算法在实际工作中的确很少会用到,这是一个事实,在平时的业务开发中,用到数据结构与算法的地方比较少。
虽然不得不承认,懂数据结构与算法是很牛逼的一件事,但是,即使你不懂,也可以解决 80% 的问题。
不利于求职
面试中 70% 的题目与数据结构与算法有关,这也是一个事实
随着时间的推移,企业面试越来越重视数据结构与算法了,大厂的第一关便是算法,很多中小企业,也会问上一两道算法编程题,如果,你不会的话,基本就和工作无缘了。
那为什么数据结构与算法在工作中明明用不到,却在面试中频频提到呢?
首先,数据结构与算法在面试中比较好考察,相对来说也比较公平,还可以看出这个人码代码的功力
其次,解决数据结构与算法问题的能力,同时可以反应出一个人的思维能力,也能间接看出这个人在日后工作中,解决问题的能力、学习能力和成长潜力
职业高度受限
在软件开发行业,从来都是算法先行,次基础,技术为末。这也是程序员从业者金字塔的层级关系分布
在数据结构与算法知识匮乏的情况下,工作三五年之后,大约可以达到中级水平,但是很难达到高级程序员水平,导致你的事业发展遇到瓶颈,升不上去,这也是一个事实
最不能接受的是,35 岁以后,你的编码能力一定下降的,你写代码绝对不如 25 岁的程序员快,效率高
这时候,如果你对于各种算法和数据结构的认知还是处于入门级或者中级阶段的话,最终结果就是,随着年龄的变大而不得不面对所谓的程序员中年危机了
其实,很多人觉得数据结构与算法很难学,觉得非常遥远,但是如果你跟着老汤学习的话,那么这些知识并不难的,也不遥远的:
如果你不想只会业务开发的话,你要做的就是跟着老汤学习数据结构与算法:
如果你能从大学毕业,那说明,你并不比任何人差,为什么别人能学好数据结构与算法,而你却学不好呢?并不是因为难学,最重要的原因是你没有碰到好的老师
来,长按扫码,跟着老汤一步一步走,只要你是从大专及以上毕业的,你就可以学会数据结构与算法的:
???? 点「阅读原文」跟老汤一起拿下数据结构与算法,就今天。