-->

大厂晋升指南_43_加餐四_学习基础技术你对基础的理解准确吗

你好,我是华仔。

如果说IT技术领域有哪个说法最深入人心,那一定是基础很重要。

而如果说有哪个说法,让很多人花费了大量时间去学习,却没什么效果的话,那多半也是这句话,我相信你都被人准准教诲过。

做技术基础很重要,一定要打好基础,比如说数据结构和算法操作系统、本译原理等话。

而且很多公司面试的时候,也采用了面试造航母工作拧螺丝的方式,对基础能力的考察远远超过实际工作需要。

结果很多人费了很大的力气来提升所谓的基础能力,但是却发现根本看不到提升效果,工作中也用不上很白,浪费时间和精力。

难道说基础很重要?这个说法不对吗?其实这个说法本身没有问题,但是它太模糊,太笼统了,很难准确的理解,再加上一些口口相传的经验误导,搞得很多人都掉到坑里去了。

这一讲,我来跟你聊聊,到底什么才是基础,怎么提升基础技术才能事半功倍,基础能力确实很重要。

但是对于什么才是基础,业界并没有统一的定义。

不过有几个错误的观点流传很广,误导了很多人。

毕竟最典型的就是接下来我要说的这三个第一个错误观点是基础,等于底层。

第些人以为越底层的东西越基础,比如操作系统、内核、编译原理、CPU的指令和内存。

毕竟从字面意思来理解,底层的东西当然是基础了,而且是越底层越重要。

因为越底层越通用。

第二个错误观点是基础,等于源码。

有些人喜欢show me the code,认为只有源码才是最基础的东西。

源码面前没有秘密,要学基础,就一定要去看源码,要自己能写出来,才算真正掌握了基础能力。

第三个错误观点是基础,等于不变。

有些人认为不变的东西才是基础,比如数学算法和数据原构、计算机组成原理、汇编语言,甚至包括离散数学和逻辑电路等。

把这些学好了以后,无论做什么都用得上。

很多人抱着这样的想法去提升基础,结果却没什么效果。

我有个同事花了六个月时间去研究编译原码,感觉没什么收获,然后找我来讨论原因。

我还有位朋友花了大量的时间来看linux内核源码,看完好像知道了一些源码,但线上出了问题之后,连linux定位工具都不会用。

也有很多技术人员用了很多时间来背算法和数据结构的源码。

但在实际工作中,要么不知道什么时候用什么算法,要么就滥用算法。

明明一个很简单的逻辑,也要硬套一个算法。

要想打好基础能力,首先要明确什么才是真正的基础能力。

我的观点是,基础能力是指工作任务相关的。

基础能力不是整个计算机技术的基础能力,核心就是工作相关,千万不要单纯照搬别人口中的基础能力。

基于这个观点,我们来澄清一下前面提到的几个错误观点。

第一,基础不等于底层。

如果底层技术和当前的工作内容没有关系,那就不是工作要求的基础能力,比如CPU指令和内存寻址。

对于做嵌入式开发来说是基础,而对于做安卓IOS业务开发来说,就不是基础了。

第二,基础不等于源码。

如果当前的工作并不需要我们去修改其源码,或者理解其源码细节,那就不是工作要求的基础能力。

比如linux内核源码和hot sport虚拟机源码,对于做虚拟机开发来说肯不是基础呀,但是对于java业务开发来说就不是基础了。

第三,基础不等于不变,不变的东西确实应用很广,但是随着技术的稳展,不变的东西越来越稳定,封装也越来越抽象,基本上就可以认为不需要再关注它了。

这就像电一样,我们天天用电学的原理,你只要上过中学基本都重要。

但是我相信现在没有人在使用电器的时候,还要去翻一翻物理课本吧。

很多人为了证明基础很重要,都会去建房子的例子。

因为地基是房子的基础,但其实你认真思考一下,就算是建房子打地基的方式也是不断变化的。

古人用夯土打地基,后来用石头打地基,现在用钢筋水泥打地基,而且工人在用钢筋水泥打地基的时候,也不需要知道如何制造水泥,如何炼钢这样的基础知识。

麻省理工大学以前有一门非常火的课程,叫做计算机程序的构造和解释,但后来他们停止了这门课,并给出了原因。

简单来说就是这门课程不是为今天的程序员准备的,而是为二十世纪八十到九十年代的程序员准备的这是因为那个时候的程序员是通过组合简单和深刻理解的部件来构建复杂系统。

而现在的程序员在复杂的商业硬件和大型的开发库上面来构建复杂系统。

就算程序员想了解这些底层硬件和开发库,也可能因为商业秘密等原因无法做到按照工作相关这个原则。

我举两个常见的例子对比说明一下。

第一个例子,java业务开发和AGDK开发,他们都是java相关的开发。

我们假设一个是用java来在linux平台上,基于spring boot框架完成业务开发,另一个是要负责阿里的AJDK开发。

那么他们的基础能力差异,如文稿中表格所示。

第二个例子,安卓业务开发和安卓动态化框架,他们都是安卓相关的开发。

我们假设一个是做业务开发,一个是开发动态化框架。

那么他们的基础能力差异如文稿中表格所示,明确了工作相关这个原则之后,提升基础的第一步就是使用技能图谱的方式。

从以下四个维度来细化基础能力的范围。

第一个维度是工具,主要包括工作中常用的工具,比如IDE、编程语言问题定位工具和版本管理工具等。

第二个维度是生态,它主要包括系统或者产品运行时依赖的所有组件或者系统。

比如说第三方库、中间件、数据库、文件系统和游戏引擎等。

第三个维度是容器,它主要指系统或者产品在哪里运行,比如安卓IOS、 linux浏览器和云服务器等。

第四个维度是原理,它指的是需要我们掌握的原理,知识,常见的有计算机网络和数据结构的。

我们以前端开发为例,基础能力的范围我整理成了一张思维导图,放在了文稿中。

你可以看一下,有了技能图谱之后,我们就能够大致的了解每个技术领域的基础能力到底包括哪些了。

明确了基础能力的定义和范围,我们就可以把有限的时间和精力用在更有价值的地方,避免眉毛胡子一把抓,从而实现投入产出效率的最大化。

但是单个基础技术怎么学,这也很关键,否则学习还可能是事倍功半。

常见的学习误区有两个。

第一个是认为既然是基础技术,那肯定是掌握的越深越好。

比如数据结构和算法、计算机网络和操作系统,这些几乎是所有程序员的基础。

所以每一项都应该深入了解,但是这样做还是会导致你浪费很多时间和精力。

以数据结构和算法为例,很多人学习的时候都采用了背代码的方式,认为只有自己能手写这些代码才算是真正的掌握。

而且有些面试官在面试的时候,喜欢让应聘者写简单的算法代码,进一步强化了这样的认知。

我就曾经跟几个这样的面试官聊过,对话过程几乎一模一样,很有意思。

我问面试官,为什么你们要用这种方式来判断应聘者的水平?面试官回答说,如果一个程序员连个简单的算法都写不出来,那就说明他肯定不合格。

我又问,那你们要自己修改算法和写数据结构吗?面试官回答说,怎么可能直接用java库里面的自己写的质量,怎么跟java库的比呀?我又问一般你们考什么算法和数据结构?面试官回答说,冒泡啊、快排啊、链表啊字符串之类的。

我又问,那为何你们不要求手写b加数不手写、concurrent hash map这些呢?这些难度更高。

面试官回答说这个要求有点高呀,现场写不完,其实我自己也写不出来。

在上面的对话中,我们可以看到,其实这种面试方式就属于面试造航母工作。

拧螺丝不能判断应聘者水平高低,只能反映出他们面试准备程度的高低。

而且能考的也就是这么几个简单的数据结构和算法题目。

因为面试官自己也只能看懂这几个。

第二个误区是认为要完全掌握基础,一定要掌握源码这个观点,更加容易导致你投入大量时间,却没什么收获,尤其是linux内核源码、JVM虚拟机源码和mysql源码。

这些。

如果你不具备深厚的CC加加的开发功力,基本上连看都看不懂,更不用说考虑代码规模和复杂度了。

即便是netty,这些代码相对少一些的开源项目,就算你拥有很强的java开发技术,要想每一行代码都了解,也要花非常多的时间。

因为一个成熟的开源项目都是几十个人,用了很多年的时间慢慢积累的。

你一个人想一下子就全部搞懂所有代码,这是不现实的。

而如果你把时间浪费在这个地方,用来提升其他更有用的技术的时间就没有了。

所以说就算是同一个基础技术,不同的技术人员学习的深度也是不同的。

核心的原则,还是之前提到的工作相关下据工作内容来决定基础技术的学习深度。

下面我举几个常见的例子来说明。

第一个例子。

数据结构和算法对于绝大部分开发人员来说,主要是熟悉数据结构和算法的原理,优缺点与应用场景。

还有自己所用的编程语言,提供的算法和数据结构。

而对于中间件开发的技术人员来说,在做极致的、性能优化的时候,java的concurrent hash、 map之类的并发数据结构,就需要掌握算法的原理和代码,实现细节了。

第二个例子,计算机网络对于绝大部分开发人员来说,能够熟练掌握抓包工具,抓取TCPIP包,并且能够看懂包信息,定位网络问题就行了。

而对于运维人员来说,抓包路由协议、组网配置等等,就需要深入掌握了。

第三个例子,操作系统对于绝大部分开发人员来讲,掌握基本的操作系统原理和概念,能够使用操作系统提供的工具来定位程序问题就行了。

而对于驱动开发、内核模块开发的技术人员来讲,操作系统原理实现机制和代码都需要深入掌握。

明确学习深度之后,因为基础知识点比较多,看起来比较散,所以你可能学了很多知识,但是不知道他们之间的关联关系理解不够全面和深入应对这个问题。

办法就是第十九讲中介绍的链式学习法,通过领域分层,将基础技术和顶层的实用技术关联起来,形成系统化的理解,这样能够理解的更深,记得更牢固。

看到这里,你可能会有疑问,判断基础能力范围和基础技术学习深度的原则都是工作相关。

那么如果工作发生变化,岂不是很多基础技术的积累就白费了?这里就要看所谓的变,具体是怎么变。

如果是前后两个工作的领域基本一致,那么基础技术的积累基本上是可以通用的。

比如,我曾经从PHP服务端开发转为java服务端开发,在数据结构和算法、计算机网络数据库和操作系统方面的积累完全可以通用。

但如果前后两个工作领域差异很大,那么基础技术的积累确实可能无法通用。

比如我的一位同事从安卓开发转为服务端,后台开发,虽然数据结构和算法计算机网络可以通用,但是scret、 light数据库和安卓操作系统这些就不能通用了。

所以跨领域转岗一定要慎重,要转的话就尽早转越晚,损失越大我。

刚去UC的时候,是用CC加加做中间件,对高性能和网络都有比较高的要求。

于是我深入的学习了CPU和网络的一些基础知识。

最典型的就是SMP架构的CPU的force sharing问题。

这个知识识理论论属于计算机组组原理,理是计算机组组成,原理一般只会写CPU有LEL二l line问题,很少提到多核CPU的cache line对齐会导致force sharing问题,并且对性能有很大影响,mysql也被这个问题给坑过。

而disrutor的高性能则是采用padding,避免了这个坑。

你看到这里可能会急着想去看看,我说的forth sharing到底是什么。

别急,这个基础知识点在我后来负责业务开发的时候就没用了。

因为接触不到这个深度,但是做业务开发的时候,mysql的索引原理和elastic search的倒排索引,这些基础理论就很有用了。

因为你要设计合理的索引和存储方案。

不过这个时候你也不需要把b加数的数据结构写出来,只需要知道原理就可以设计合理的索引和存储方案了。

好了,现在我们回顾一下这一讲的重点。

第一个重点基础能力是指工作任务相关的基础能力,不是整个计算机技术的基础能力。

基础不等于底层,不等于源码,也不等于不变。

第二个重点提升基础的第一步就是使用技能图谱的方式,从工具、生态容器和原理这四个维度,细化基础能力的范围。

第三个重点提升基础技术的技巧,包括根据工作内容来决定基础技术的学习深度,通过链式学习法将基础技术和实际用到的技术系统串起来,跨领域转岗要慎重,要转的话就尽早转好了,这就是今天的全部内容,留意到课后思考题给你。

按照这一讲的内容,你能够整理出你当前工作岗位所要求的基础技术包括哪些,以及你需要学到怎样的深度吗?欢迎你把答案写到留言区,和我一起讨论。

相信经过深度思考的回答,也会让你对知识的理解更加深刻。