典型的错误观点
- 基础 = 底层
- 基础 = 源码
- 基础 = 不变
- 我有个同事花了 6 个月时间去研究编译原理,感觉没什么收获,然后找我来讨论原因。
- 我也有位朋友花了大量的时间来看 Linux 内核源码,看完好像知道了一些源码,但线上出了问题之后,连 Linux 定位工具都不会用。
- 也有很多技术人员用了很多时间来背算法和数据结构的源码,但在实际工作中,要么不知道什么时候用什么算法,要么就滥用算法,明明一个很简单的逻辑也要硬套一个算法。
核心就是工作相关
我的观点是“基础能力是指工作任务相关的基础能力,不是整个计算机技术的基础能力”,核心就是“工作相关”,千万不要单纯照搬别人口中的基础能力。
- 基础!= 底层
- 如果底层技术和当前的工作内容没有关系,那就不是工作要求的基础能力。
- 基础!= 源码
- 如果当前的工作并不需要我们去修改其源码或者理解其源码细节,那就不是工作要求的基础能力。
- 基础!= 不变
- 不变的东西确实应用很广,但是随着技术的发展,不变的东西越来越稳定,封装也越来越抽象,基本上就可以认为不再需要关注它了。
- 这就像电一样,我们天天用,电学的原理,你只要上过中学基本都知道。但是我相信,现在没有人在使用电器的时候,还要去翻一翻物理课本吧。
麻省理工大学以前有一门非常火的课程,叫“计算机程序的构造和解释”(SICP,Structure and Interpretation of Computer Programs),但后来他们停止了这门课,给出的原因如下(Why MIT stopped teaching SICP):
They felt that the SICP curriculum no longer prepared engineers for what engineering is like today.Sussman said that in the 80s and 90s, engineers built complex systems by combining simple and well-understood parts. The goal of SICP was to provide the abstraction language for reasoning about such systems.Today, this is no longer the case. Sussman pointed out that engineers now routinely write code for complicated hardware that they don’t fully understand (and often can’t understand because of trade secrecy.)The same is true at the software level, since programming environments consist of gigantic libraries with enormous functionality.
简单来说,就是 SICP 课程不是为今天的程序员准备的,而是为 20 世纪 80~90 年代的程序员准备的。
这是因为那个时候的程序员是通过组合简单和深刻理解的部件(其实就是指从底层开始构建)来构建复杂系统,而现在的程序员在复杂的商业硬件和大型的开发库上面来构建复杂系统,就算程序员想了解这些底层硬件和开发库,也可能因为商业秘密等原因无法做到。
举例说明
Java 业务开发 vs AJDK 开发
Android 业务开发 vs Android 动态化框架
细化基础范围:技能图谱
明确了“工作相关”这个原则之后,提升基础的第一步,就是使用技能图谱的方式,从以下 4 个维度来细化基础能力的范围。
- 工具:工作中常用的工具,比如 IDE、编程语言、问题定位工具和版本管理工具等。
- 生态:系统或者产品运行时依赖的所有组件或者系统,比如第三方库、中间件、数据库、文件系统和游戏引擎等。
- 容器:系统或者产品在哪里运行,比如 Android、iOS、Linux、浏览器和云服务器等。
- 原理:需要掌握的原理知识,常见的有计算机网络和数据结构等。
以前端开发为例,基础能力的范围如下图所示:
提升技术的技巧
常见学习误区
- 既然是基础技术,那肯定是掌握得越深越好
以数据结构和算法为例,很多人学习的时候都采用了背代码的方式,认为只有自己能手写这些代码,才算是真正的掌握。
而且,有些面试官在面试的时候喜欢让应聘者写简单的算法代码,进一步强化了这样的认知。
- 要完全掌握基础,一定要掌握源码
这个观点更加容易导致你投入大量时间却没什么收获。尤其是 Linux 内核源码、JVM 虚拟机源码和 MySQL 源码这些,如果你不具备深厚的 C/C++ 的开发功力,基本上连看都看不懂,更不用说考虑代码规模和复杂度了。
因为一个成熟的开源项目,都是几十个人用了很多年的时间慢慢积累的,你一个人想一下子就全部搞懂所有代码,这是不现实的。而如果你把时间浪费在这个地方,用来提升其他更有用的技术的时间就没有了。
如何判断学习深度?
核心的原则还是之前提到的“工作相关”,根据工作内容来决定基础技术的学习深度。
举几个常见的例子来说明:
数据结构和算法
- 对于绝大部分开发人员来说,主要是熟悉数据结构和算法的原理、优缺点与应用场景,还有自己所用的编程语言提供的算法和数据结构。
- 而对于中间件开发的技术人员来说,在做极致的性能优化的时候,Java 的 ConcurrentHashMap 之类的并发数据结构,就需要掌握算法的原理和代码实现细节了。
计算机网络
- 对于绝大部分开发人员来说,能够熟练掌握抓包工具抓取 TCP/IP 包,并且能够看懂包信息,定位网络问题就行了。
- 而对于运维人员来说,抓包、路由协议、组网配置等就需要深入掌握了。
操作系统
- 对于绝大部分开发人员来说,掌握基本的操作系统原理和概念,能够使用操作系统提供的工具来定位程序问题就行了。
- 而对于驱动开发、内核模块开发的技术人员来说,操作系统原理、实现机制和代码都需要深入掌握。
如何让理解更加深入?
应对这个问题办法就是第 19 讲中介绍的“链式学习法”,通过领域分层将基础技术和顶层的实用技术关联起来,形成系统化的理解,这样能够理解得更深,记得更牢固。
基础积累会不会浪费?
- 如果是前后两个工作的领域基本一致,那么基础技术的积累基本上是可以通用的。
- 如果前后两个工作领域差异很大,那么基础技术的积累确实可能无法通用。
小结
- 基础能力是指工作任务相关的基础能力,不是整个计算机技术的基础能力。基础不等于底层,不等于源码,也不等于不变。
- 提升基础的第一步,就是使用技能图谱的方式,从工具、生态、容器和原理这 4 个维度细化基础能力的范围。
- 提升基础技术的技巧包括:根据工作内容来决定基础技术的学习深度;通过链式学习法将基础技术和实际用到的技术系统串起来;跨领域转岗要慎重,要转的话就尽早转。