# 混沌学习法
在外界,流传着各种学习法:费曼学习法、番茄学习法等等,不过它们都太过通用了,我这里传授的学习法为:混沌学习法,也即编程世界的“九阳神功”。通过该学习法,可以迅速掌握编程的任何一门语言、任何一门技术、任何一门算法、任何一门框架。同理,可以尝试将该学习法推理到其他领域皆是如此。
内功心法
曾经我在B站的视频中,给出了这样一个的结论:
- Java SE的每个知识点就如同点点繁星,如果只有一颗,那么显得也不是那么有趣,但是如果是一片繁星,想必再是个钢铁直男,也会感觉到心旷神怡吧。所以,我们需要讲这些知识点连接起来(基础变量、面向对象、线程、集合、IO)
- J2EE的框架基于Jave SE 的内容进行构建,比如Tomcat、Weblogic、ActiveMQ等等(所有基于Java语言开发的便是如此),我将这种基于这些SE知识点开发的中间件称之为:点连成了线
- 基于Java SE的其他技术:Spring技术栈、Netty NIO框架等等框架的出现,让我们在编写业务时,极大的提高了效率,且减少了错误的发生,而我们将这些技术与J2EE的技术(包括上面调到中间件)进行组合,就得到了面。我称之为:线组成了面
- 对于架构师而言,我们知道,需要整体把握整个业务线和技术,架构师应该是项目组中比产品更熟悉业务的人,同时对于技术本身也需要有过硬的底子。这时,就需要架构师将上面的技术栈与团队进行整合,然后把控好风险点,进行指导开发,把控进度,确保项目不会出重大问题(谁又能保证不出现任何问题呢?)。我称之为:面组成了体
基于上述的结论来说,我仅仅只是将其作为Java Coder来进行描述(也就是他们口中说的Java 架构师,其实架构师分语言呢?如果分,那么我觉得这不是合格的架构师)。如果我们以整个编程世界来给出结论,那将会是什么样子呢?
语言进化史推理
我们来看语言进化史推理:
- 计算机由一堆硬件构成:CPU(控制、计算)、内存(存放数据和代码)、硬盘(持久化存储)、IO(读入和写出数据)
- CPU执行指令,根据指令来操作内存、硬盘、IO
- CPU只认识010101,这种二进制语言
- 于是乎,不可能让程序员来编写这种010101010的代码吧?这时我们开发了一个中间件:汇编器,我们可以用英语+助记符(eg:movl $1,%eax(寄存器,了解下即可) -> 二进制为 010101010101000000001)来编写代码了,然后由汇编器来给我们将这些由英语+助记符转为二进制代码,而这种 英语+助记符 的语言我们称之为汇编语言
- 有了汇编语言,我们能干些啥?答案就是:面向CPU编程,因为我们需要使用这些英语:mov(移动)、add(添加)、sub(减)来控制CPU。但是,这真的好吗?面向机器编程这很没劲,同时也会很累,我们就不能面向人类编程吗?以人类方便简单理解的方式来编写程序,于是,我们就如同在汇编语言和机器语言中间加一个汇编器一样,我们引入C语言,然后在C语言和汇编语言中间加一个编译器就好,于是移动代码只需要:int a=1,没烦恼了。至于它如何变为汇编语言,交给编译器吧
- 程序员在使用C语言时,常常感到压抑,因为需要学习的内容太多,如果说汇编语言是面向CPU编程,那么C语言就是面向操作系统编程,那么就需要了解操作系统的内存管理机制(虚拟地址、线性地址、物理地址),这时就出现了指针的概念,而且需要手动分配内存、手动释放内存,而如果程序员一旦忘记了释放内存,就会导致内存泄漏等等这些问题。那么人们又开始想了,能不能做出一门语言,去掉不易理解的指针,自动管理分配、释放内存,这时一众基于虚拟机的语言就出现了,如Java语言
从上面的语言发展史来看,我们发现这里的点线面体分别为:
- 点:二进制的机器语言
- 线:面向CPU编程的汇编语言
- 面:面向操作系统的C语言
- 体:面向JVM的java语言
操作系统的出现推理
接下来我们来看操作系统的出现推理:
- 我们虽然可以用高级语言与计算机沟通,但是总不能让任何人:程序员、普通人员,使用编程语言(机器语言、汇编语言、一众高级语言等)直接操作计算机
- 那么这时引入了一个用于管理这些硬件的软件:OS(操作系统),其他用户只需要面向操作系统编程(程序员)使用即可(普通开发人员),对于这些硬件的管理,安全保护等等均由操作系统来完成
- 这时就会引入一个问题:操作系统需要完成哪些功能呢?我们知道基础硬件有:IO设备、磁盘、内存、CPU,而我们需要在计算机中执行任务,那么这时就涉及到:设备管理(IO设备)、文件管理(磁盘)、内存管理(内存)、CPU管理(CPU)、任务调度管理(任务)
- 这时为了完成这些功能,出现了Unix、Windows两大阵营(Linux、MacOS等等都是衍生自Unix血统),这两个阵营面向点不同:Windows面向普通用户、Unix面向程序员,目前我们用得最多最广泛的便是Linux系统
从上面的操作系统的出现推理来看,我们发现这里的点线面体分别为:
- 点:计算机硬件(学习时,需要用到:基础物理、电路原理、数字逻辑、计算机组成原理等等)
- 线:操作系统的管理功能:设备、文件、内存、CPU、任务
- 面:基于这些管理功能实现的上层应用:QQ、微信等等
结论
《大学》有这样一句话:知止而后有定,定而后能静,静而后能安,安而后能虑,虑而后能得。物有本末,事有终始。知所先后,则近道矣。对于学习计算机而言,说的是:定、静、安、虑、得,这何尝不是"学而不思则罔,思而不学则殆"。我们在学习时需要以平常心来学习,切勿急躁,且对于知识学习而言,理应知其先后,也即我们前面描述的:点、线、面的理解,这时在掌握点后,我们可以通过学习线来将之前点的碎片知识进行整合记忆,同理,我们可以通过学习面来将线的碎片知识进行关联,所以,这里可以看到最重要的便是”点“。
万事开头难,如何形成点的知识也是需要大量的时间与精力,从中医的角度来说,笔者这里建议,早上起早来学习(6:00 8:00 效果最佳),晚上保证良好的睡眠,我看很多朋友学习总是在骗自己,明着努力了,看到了大半夜,但是由于人脑相当疲惫,这时的努力只是表象,深层次而言根本抓不住任何一个点,相反欺骗了自己学习,然后陷入恶性循环,最终:学了还得忘、忘了还得学的地步。
以上种种因素,笔者这里强烈建议各位在最清醒的时候进行点的记忆,而且要形成一个习惯,不要一天看,第二天松懈,这时是无法拥有点的记忆,更不用说在学习线的时候对点进行关联。要做到这些只需要保证:
- 充足睡眠
- 大脑清醒
- 心无旁骛
- 切记勿焦虑(知止而后有定,定而后能静,静而后能安,安而后能虑,虑而后能得)
- 切记勿急功近利(相信来到星球的都是对编程感兴趣的,想培养自己的学习思维的,急功近利的学习,总是在欺骗自己)
- 咬牙坚持(一个月后,你将会习惯现在的学习方式)
- 多门知识融合学习,抽取共同点,形成点、线、面
在保证以上几点的情况下,只要各位坚持不懈的学习下去,一切交给时间,你会发现当你的底层知识形成了庞大的知识脉络后,对于新的知识(新语言、新框架等等)会变得非常容易吸收理解,这样你将会把之前用于培养底层脉络的时间,加倍的偿还回来,你将会看到:你几分钟、几小时搞定别人花费几十倍的时间都搞不定的知识和问题,这时恭喜您达到大成。
优缺点
但是这样的点、线、面还是具备一些缺点,我们来继续分析。我们先来谈优点吧:
- 当整个学习方法坚持学习后,将会拥有旁人不具备的深厚内功(计算机底层)
- 对任何一个新的知识将会快速掌握
- 对任何线上的问题,不管有多复杂,总会有解决方案和思维
- 涨薪升值会呈现指数上升
- 不会因为技术的变更、年龄的增长而焦虑
- 不会因为被他人贩卖焦虑和PUA影响(因为你已经有了自己的学习理念和技巧,心坚如石,如何受影响,你只会从中分析他们的手段来加强自身的学习罢了)
缺点:
- 消耗周期较长(需要大量时间来积累点和线的知识)
- 需要培养对于计算机的兴趣(没有兴趣,如何支撑你坚持下去呢)
- 对精神和肉体是一种折磨(刚开始使用这套学习方法时,将会痛苦不堪,从医学角度来说,人脑在接收新事物时将会非常抵触,不要怪自己,是人都会如此,因为需要产生新的神经细胞,然后关联,本身就是拉扯痛苦。而对于精神而言,看着周围(培训班等等)填鸭式的教学,看起来短时间背了很多东西,靠忽悠拿到了高薪,实则是在提前消耗自己未来的根基,因为底子不稳,达到年龄后,将会自动退出。而读者可能看到这样的涨薪、高薪假象,会时长怀疑自己是不是不行,这也是一种折磨)
- 短时间内看起来然并卵(短时间由于没有积累太多的点,这时没法进行关联,更谈不上对面的构建)
总结
其实不难看到,对于后期的优势来说,前期的这些缺点是可以接受的,其实也就是开始使用这套学习方法的第一个月会感到焦虑不安,坚持一个月后,将会习以为常了。
例子
口说无凭,我们这里以一个实际例子来说明,如何使用混沌学习法。这个例子也非常的简单:
public class Demo{
public static void main(String[] args) {
System.out.println("Hello World");
}
}
2
3
4
5
6
7
8
9
#include<stdio.h>
int main(){
printf("%s","Hello World");
return 1;
}
2
3
4
5
6
7
8
9
以上两个例子分别为Java和C的Demo,仅仅向屏幕输出了Hello World字符串。读者看过很多书和博客,他们认为Hello World的例子仅仅只是输出这么简单,在书籍和博客中草草带过,只教会了读者如何去使用工具:javac、IDE、gcc等等编译,这会有如下弊端:
- 无法让读者提升编程兴趣(很多事都是兴趣使然,没有兴趣如何坚持?再好的学习方法不坚持有何用)
- 无法让读者对整个编程世界进行一个概览(基本的点都没有,如何连成线,更不用说面)
- 浪费了一个最好的机会:很多新人朋友来学习编程语言时,就是一张白纸,此时最好在上面进行勾勒,但是由于这种仅展示工具和教输出的行为,就给这张白纸画上了失败的一笔
现在让我们用混沌学习法来看看,如何从这么简单的一个例子中分析出点、线、面。
笔者先给读者一个很好地技巧:多问为什么(问给你自己)。由于很多读者都是Java Coder,那么我们先以Java语言来进行提问:
- 编写的这个程序在计算机中如何存储的(这时引入了 编码和磁盘存储 的知识点)
- 编写的这个程序在使用javac编译称demo.class时发生了什么(这时引入了 编译原理 的知识点)
- java 运行的时候,这些字节码是如何执行的(这时引入了 JVM、操作系统 的知识点)
很好,如果你问了自己这三个问题,恭喜您,你已经掌握了混沌学习法的第一步:找知识点。我们不难看出,从这些问题中我们看到了:编码和磁盘存储、 编译原理、JVM、操作系统 。此时,读者在找到这些点后,根据自己的知识脉络来进行吸收转换(如果是新人朋友,那么就以这几个点作为自己的学习目标,将他们的底层原理通过书籍、百度、实验、源码来进行补充构建,这时这些点往下就会衍生出更多的知识点,此时您的知识脉络已经构建完成。读者应该可以看到:这些知识点就是GC Root,您只需要通过书籍、百度、源码连接扩展下去即可~)。
我们再来看C语言的自我问答:
#include<stdio.h>
干了什么,这是什么,有何用(这时引入了 宏定义 的知识点)printf("%s","Hello World")
; 为什么这么写就输出了(这时引入了 函数 的知识点)return 1
;为什么我们需要返回1(这时引入了 函数 的知识点)gcc demo.c
,自动生成了a.out
文件,期间发生了什么?(这时引入了 宏替换、编译、汇编 的知识点)
C语言相较于Java而言问题较多,不过读者可以看到,随着问题的变多,我们可以进行连线扩展的知识点就越多。这时我们继续往下对这些知识点构建出更多的知识网。
接下来我们来进行混沌学习法的第二步:知识点联想、对比记忆。
何为混沌?其实就是融合。读者可以将C语言的自我问答与Java语言的自我问答进行结合,这时得出如下问题:
- C需要
#include<stdio.h>
宏定义来引入printf函数,为啥java不需要(此时进行对比学习得到结论:Java自动导入了java.lang的类,所以不需要手动导入) - C中使用
printf("%s","Hello World")
格式化输出,java为何没有(此时进行对比学习得到结论:Java也有,只不过在demo中没有使用) - C中需要return 1;java为何没有(此时进行对比学习得到结论:C语言编译器的不同要求需要有返回值,同时根据规范定义,需要保留返回值。而Java语言由于JVM规范定义,主函数不需要定义返回值。抽取共同点:规范定义)
- C需要gcc 中:宏替换、编译、汇编流程,才能执行,java语言为何只需要javac、然后java就可以执行(此时进行对比学习得到结论:java语言也进行了这些流程,只不过在JVM中进行)
此时读者可以好好体会下混沌学习法的魅力:
- 通过知识点进行脉络扩展(找到“GC Root ”知识点,往下关联)
- 通过对比联想记忆,可以同时对多门知识点同时学习
- 通过对比学习,可以抽取多门知识的共同点,找到他们的共同“GC Root”,然后同时进行脉络扩张
我们不难看见混沌学习法的核心:多问为什么?不然,你找不到“GC Root”。
说明
本学习法仅作为参考,读者可以从中进行优化扩展,有任何建议、想法、体会,均可在星球的本文下进行评论和标注,这套学习法就像最初的“永春”,各位可以向李小龙学习,进行多家方法融合感悟出自己的“截拳道”。本星球内的后面的知识编写,将会以混沌学习法的方式来进行,也即:知识点联想、对比记忆。读者在阅读时,多问自己为什么,然后从笔者给出的线索进行GC关联(毕竟:方法给你了,如果自己不使用这套学习法,别人做出来的只能是别人的)。