偶然和一位资深的朋友聊起一些有关程序员如何学习的话题, 想想也许我们所思考的问题, 也许正好是很多想做程序或想学程序的人的迷雾, 于是顺手就把它写下来, 期望能够给正准备走上程序之路或已经在这路上的朋友些许的启发.文章颇长, 本人一个字一个字码出来的, 如果您有耐心全部读完, 希望会对您用.
本文以下所指的程序员, 都是基于BS开发的web程序员, CS俺不熟^_^
1.整体的学习思维
学习的思维大致分成两种, 一种是理科方式的步步为营, 一种是文科方式的高屋建瓴. 这么说起来好像不够形象, 其实就像挖一口池塘, 理科学习推崇挖一节推进一节的方式往前挖, 每一节都是从上挖到底,一节一节步步为营, 而文科方式是从整体面上挖一遍, 再整体挖一遍, 一层一层的从上往下挖.
那么问题是, 编程究竟是属于理科还是文科? 这好像是个不用讨论的问题, 当然理科嘛.但是,从编程学习的知识体系来看, 编程却未必全如理科般一节锁一节, 有时候却更像是文科的写文章.这就有了两种方式的讨论, 究竟学一门编程语言, 是按照纵向一节一节推, 还是按照横向一遍一遍学?其实, 在我看来, 这里有个区分:
1.1基础知识学习
从编程语言学习的角度来说, 应该是按理科学习的方式一节一节往前推的方式好. 因为, 这些基础的理论知识都是环环相扣, 而且每个基础概念理解起来都相对比较简单, 都是写固定的思维方式和算法代码, 但是这之前的每一个简单的基础知识都会是后面需要的知识基石, 一步是夹生饭, 后面都都是夹生饭, 再回头来折腾就费事了. 所以, 这需要每一步理解透, 这样虽然开始慢, 但是随着基础概念的牢固掌握, 后面会越来越快.
1.2框架学习
当基础知识告一段落的时候, 往往大多数人是直接往框架学习上走, 框架之本质其实就是一个工具, 那么这个工具用整体的方式来学习, 效果会更好. 为什么这么说呢, 因为每一个框架都会采用大量的设计模式, 如果脱离开框架来专门精研设计模式, 会发现学会了模式基础还是看不懂框架原理, 而一节一节的读, 太容易被那些抽象但是不影响工具使用的概念困扰住. 但是如果是整体的看一遍框架指南, 对这些模式比如依赖注入, 观察者模式等等的用法会有直观的感性认识, 虽然还很模糊, 没关系, 先拿着手册整体依样画葫芦的做一遍,看不懂就跳过去,整体看一遍就大致理解一些, 整体的多看几遍, 等对基础用法都很熟练了, 再专门来理解核心概念就不那么费劲了.
而框架本身是工具, 对于学习工具而言, 实际的操作就很重要, 因此, 如果没学过框架, 可以先简单的整体了解一个框架的手册内容, 至少粗读一遍, 读不懂就找个视频讲解来看一遍整体的用法, 有了整体的了解后, 拿来尝试按手册示例代码做一两个小项目, 而后, 再回头整体的看一遍, 总结出框架的核心知识点, 再做以两个项目, 这样整体式的一遍一遍学习, 每学一遍就会深入一点, 做几个项目, 一个框架的知识就了然于胸了.然有有多余的精力, 再去深入源码级别, 当然, 这个因人而异, 如果你压根就不想看源码, 当熟练了用法, 那些设计模式的核心用法和观念也就有了, 应该说, 研究或者不研究源码, 都不会影响你对某个框架的理解和应用了.
2.程序员学习的基本理念
2.1 理解和记忆
没一种编程语言都会有大量的内置函数或内置类, 因此, 记忆这些内置功能就显的很重要, 这跟学英语背单词是一个道理, 学程序不背一些函数或类的用法, 那么写起代码就会感慨书到用时方恨少. 拿电脑来打个比方, 外部你还没记忆的知识, 当作是存放在硬盘上的数据, 你已经记忆下来的知识, 是在内存中的数据, 假如你写程序的时候总是靠翻手册或查百度来拼凑代码, 就好比每一次程序调用伴随着大量的IO操作, 时间耽误在查资料上, 而大脑中真正的逻辑功能还是空闲的, 这样的开发效率是很低的.
但是那么多的函数名和类名, 而且都是英文额...如果靠强制性的死记硬背, 那真是很让人头疼的一件事, 因此, 掌握一套有效的记忆策略就显得很重要, 其实记忆策略本身并不是很悬的技术, 只要找对一种方法, 进行合理的训练, 就有能力达到一定的记忆效率.
目前市面上流行的记忆术最多的也就三大类, 逻辑记忆, 图像记忆和声音记忆, 再加一个思维导图学习法.对于程序员这样需要专门记忆很多名词的人来说, 花时间训练一套记忆法, 绝对是非常必要的. 而记忆法本身是可以训练的, 这是很正常的事情. 市面上能找到有关记忆的培训视频都是在强调图像记忆, 但是我强烈不推荐, 这里面有太多市场化的吹嘘成分, 因为做程序员的都知道, 计算机处理图片和声音以及影像信息的速度, 远远没有处理文字信息来的快, 我相信大脑也是, 图像能够很快速的反映, 但是记忆诸如手册方法这样的大量信息, 花花绿绿的图片会让大脑奔溃. 个人觉得比较合适的记忆方式是逻辑记忆法, 台湾有一位陈光老师专门研究逻辑记忆法, 还写了一本书叫<吸英大法>, 里面有一套很有效的逻辑记忆方法, 记忆单词很管用, 记忆内置函数和内置类也很有效果.(里面也说明了, 成人在6岁以后, 图像记忆能力已经衰退, 而让成人用图像记忆法, 实际是一种开倒车的行为, 具体如果您有兴趣, 可以把这本电子书找来看看).
当然, 有句话叫理解的越多, 需要记忆的越少. 记忆是学习编程不可缺少的一环, 但是理解每个记忆的概念更为重要, 因为函数名或类名可能换一套语言就变了, 但是这其中的逻辑观念是不会变的, 正如你要截取文字, 可能每套语言的函数名不同, 但是基本的逻辑都大差不差的就那么回事.其实, 理解的越多, 能记下的就会越多, 同时, 如果你没理解, 只是先记下了, 那么当拿来用的时候, 同样理解的也会越快.这是一个辅助学习的两个互补工具, 有时候不理解, 记下来就理解了.
2.2 清晰的知识分类
我不会很推崇思维导图能干什么, 但是拿思维导图来做思维整理确实蛮好用. 编程的知识很杂, 而且体系很庞大, 因此清晰的知识分类会显得很重要, 当然, 我不是很建议一开始就来做知识分类, 因为我个人试过一开始就分类提取一些核心知识, 但是整体的核心知识看完之后, 跟没学过一样, 所有的细节都漏了, 开发的时候还是需要一遍又一遍的翻手册. 知识分类应该是基于对整个知识的熟练掌握之后. 举个学习框架laravel的例子, 假如一开始学就拿个导图软件来画画图图, 然后画完的时候感觉很有整体的感觉, 到要拿来用的时候, 还是一脑袋空白, 实际上什么也没记住. 而如果对框架知识本身有一定的操作体验, 本身的知识细节比较清楚的情况下, 归纳和提炼知识会让记忆量大幅度降低. 比如学laravel的ORM,一对一,一对多, 多对多, 多态关联, 如果之前都操作的熟练了, 那么几个类方法一抽出来画在导图上, 那一大篇的ORM知识就都记住了.
其实清晰知识分类的另外一个好处就是, 学习的信心会有很大的提升, 假如学完一个体系的知识, 没归纳整理之前, 似乎总是感觉盲人摸象, 但是整体整理一遍, 整个知识架构会都串起来, 对知识感知的信心就会一下子踏实起来.
2.3 编程的实际操作
编程本身是跟实际操作相关的学科, 抛开前面说的理论记忆层面, 也就是说每一个知识点, 最终的实际效果都是能跑在计算机上得出一个结果, 因此, 实际操作就非常重要. 对于编程操作而言, 其核心依旧是一门匠艺, 在实际操作的训练上, 跟学书法学木匠, 本质上没有太大的区别.
理论上的东西需要取理解和记忆, 操作上的东西就是训练而已.
老祖宗教我们学书法的时候, 无非是三步走, 临帖, 背贴, 脱贴. 而程序的操作也是一样, 一段代码拿过来, 什么都看不懂, 没关系, 找一个编辑器抄一遍总会, 简单逻辑的代码在操作的时候抄一遍, 放到解释器或编译器上面跑一遍, 结果出来后说不定就看懂了, 还没看懂, 再抄一遍, 原先不理解的, 下一遍就理解了, 就这么回事.一个需求出来不知道怎么想流程, 先stackoverflow上查查看, 有没有人家写好的, 拿回来依样画葫芦临摹就好了, 等临摹到一定的代码量, 也就把一些基本的逻辑代码背下来了, 逻辑过程代码背的多了, 基本功就扎实了, 创作就不再是问题.
2.4 框架的实际操作
现在的项目开发大多是用框架搭积木, 一块一块的填空. 框架的本身理念上的知识, 您可以参照前面的学习, 框架的实际操作, 实际上可以把它当作一个软件, 也就是说, 学一套框架的操作, 本质上跟学Excel没有太大的区别. 也就是一个用代码来操作数据相关的逻辑, 一个用鼠标点一点就可以出数据结果的差别;一个前面有前端,后面有数据库, 是为了实现业务逻辑; 一个是界面和数据都绑在一起操作而已, 是为了实现数据操作.
那么学Excel操作的时候, 很多人都不会是找书本来慢慢一点一点啃出来才能做表格的吧? 大多数是打开软件界面, 每个按钮点一遍过去看效果怎么样, 不懂再百度问问看, 再实际操作两张表, 再不懂翻翻手册, 那么基础的操作就这么熟练了, 遇到数据高级查询这些高级应用, 再去翻看手册或是查资料问别人, 掌握原理再操作, 用的熟了, 就是Excel高手了, 而实际上, 学会操作Excel的20%就可以完成这个软件80%的操作, 要再花80%的时间去研究VBA, 那是为Excel20%的应用去学习, 要不要学?要用到再说^_^
框架操作也可以是这样, Excel有界面, 框架有手册嘛, 每本手册的描述一般都是权威且清晰的, 对着手册做, 好比点按钮. 有些要花80%的时间才能弄懂的(比如翻源码), 先别去管, 因为从应用的角度看, 你可能一辈子都不需要去了解一套框架后面的源码, 假如真的到要翻源码的应用, 那也可以考虑换一个框架.就像Excel的vba, 我要用到vba的时候, 就直接换Access了, 谁有那么多时间去研究个Excel的编程.
3 .学习历程
一个程序员的学习历程, 大致分为以下三个阶段:
3.1 看山是山
这个时候的学习, 就是针对原生语法上的学习, 对核心概念再数据操作结果上的理解, 这个阶段的理解就是编程就是一门编程语言, 学C就拿C的if...else..., 用一些prinf写一些逻辑代码, 学python就是python的基础代码操作, 能够写一两个小应用, 学PHP能够做一两个小网站, 这个时候的概念就是这个语言这样做可以作出这个东西, 任何东西一拿过来就是先想代码怎么敲, 函数用什么, 类库用哪个......这个阶段讲究代码的个性化, 讲究思维的抽象化, 也就是我能够用更精巧的代码逻辑, 我就更厉害, 以及动不动的设计模式, 也就是说, 在这个阶段就是代码层面的代码, 没别的.
在这个阶段其实是很难对底层的实现原理有深刻的认识的, 即使认识, 也仅是在某些教科书的描述性的理解. 但是值的一提的是, 现在有些的企业面试却颇为无聊, 企业面试一般会出一些很艰深的原理性和底层性的知识, 来考一些面试基础岗位的程序员, 而实际上要对那些面试的知识真的认识的很深刻, 那他真的不需要靠面试找工作. 这挺讽刺, 但是现实就是这样, 所以就会有很多的培训机构专门应对这些面试考试题目做一些强化, 尽管这个时候, 能答对题目, 不代表程序员的层次就上去了, 只是这些题目会做对. 当然, 这也无可厚非, 每个人都要谋口饭吃嘛.
3.2 看山不是山
当学完基础知识的应用之后, 大多数程序员都开始了框架生涯, 后端的要搭个界面, bootstrap就来了, 要做个前端SPA应用, vue或react就来了,高大上一些的, angular就凑上去了, 后端TP, laravel, django, spring, 爬虫的Scrapy, 各种各样五花八门的框架搭建应用, 这个时候, 语言的隔阂就很小了, 比如angular是用typescript写的, 但是就是只会javascript的程序员, 稍稍翻一翻ts的文档, 套着框架开发也没问题, 我做PHP的, 稍稍翻下python的基础语法, 也能用django写项目, 我做python的, 看了下php写爬虫也没问题, 好像基础编程语言的隔阂越来越小, 也就是语言本身的特性几乎都转化为了设计模式层面的思维, 好像说,基础语言我只要看懂语法就可以了, 其他的都是框架层面的概念, 前端不管是react还是angular, 反正语法都差不多, 也都有rxjs的东西, 那么就是玩大而泛之的概念, 开始充斥各种模式的概念:单例,观察者,装饰器,依赖注入, 控制反转.......
在这个阶段, 好像采用的编程语言是什么压根就不是太所谓, 重要的是框架要好用, 好用就叫他优雅, 不好用就是坑, 而采用这些框架的终极目的, 就是快速搭建应用, 来项目了, 来单子了, 拿个框架, 快速上手, 配上数据库, 配上CURD的业务逻辑, 一个项目快速上线, 中大型项目用中大型适应的好修改好维护框架, 小型项目用高性能框架.......一切皆框架, 剩下的, github上找车轮, 要验证码的, 有! kaptcha, 要全文索引, 有! Elasticsearch, 在框架的前提下, 绑上一堆车轮子, 然后项目就快速上线跑起来了.
这好像也没什么, 也是大多数程序员的宿命, 或者说是大多数程序员的技术终点(因为需要再往下走, 要么不写程序了, 要么就写特高级没市场的程序了, 总之再下去是大多数程序员不会走的路). 写程序就是谋条活路, 有人付钱的程序才是好程序, 其他的, 我们大多数人管不了那么多.应该说, 有了这个层面的最大量的群体, 才会有各式各样配合这个群体的构建工具出现,都是几个命令快速搭建, 因为群体最多, 所以讨论的也最多, 同时, 这个层面也最复杂, 各式各样的工具让人晕头转向, 各式各样高达上的名词让人摸不到边, 猿生如此..........^_^
3.3 看山还是山
当然, 还是有人走"少有人走的路", 这里的少有人, 不是程序员转管理的高级, 而是真正技术上的高级. 依然有人会抵达程序员成佛作祖的境界, 这个阶段我不太敢多写, 因为, 我达不到. 所以, 这一小段, 是见过猪跑却没吃过猪肉的人写的关于猪的传说, 未必正确, 您蛮看看就好.
其实, 当把一两套框架玩到出神入化的境界, 就会回归到原生层面去看底层的代码, 会去深入的研究底层的逻辑, 会仔细去比较没种数据库查询的性能差距, 一路追到框架的原生设计, 或是SQL, 甚至是解释器, 这是进入看山还是山的必经之路.
而在这个境界里, 会更重要的回归到语言本质上面, 当然, 什么编程语言会不会用已经不是问题, 那关键的考量是为什么要用这个语言, 这个语言的这些特性在将来会出现什么问题, 比如angular1.0和2.0, 用js和ts的考量, 用什么场景可以用什么模式, 性能追求还是效率追求....等等等等, 而这个境界上, 其实还是一门编程语言本身的特性, 绕老绕去, 绕不过动态类型?静态类型? 接口? 线程? 进程? 弱类型强类型? 而真正精道的, 也还是回归到语言本身的实现原理上.
当然, 这个境界所专注的, 已经不是在于一门语言的howTo, 而是why! 就是很多面试题里的概念, 当然, 是这些考题背后真正的运作机理以及这些机理会产生的影响了.
4.关于web的一些框架的题外话
4.1 前端框架
传统的基础HTML+JS+CSS咱就不说了, 说点看山不是山的吧...
Bootstrap不用说, 几乎是每个前端人员的入门ABC, 但是我说的是, 如果一个后端要用Bootstrap, 好歹先了稍微学下less嘛, 虽然懒得看整个bootstrap的源代码, 好歹把variables.less的变量用法看一遍, 再按照BS首页的入门提示自己编译一下源码, 这样也不至于一个BS界面写出来, 怎么看就怎么像BS.
jQuery有即将被angular还是react的哪个SPA框架KO的传说, 不过传说终归是传说, Angular6要入门前的一堆肥肥的概念就会把很多人挡在门外, react就更不用说, 加上rxjs那些异步概念, jQuery看看扬言要替换它的对手笑笑说, "还早", 所以,没别的说的, 这还是值的学的,而且很多场合, 用它最方便.
然后就是前端的三个典型了, vue, react, angular, 当然, 学会其中一套, 另外两个也就容易学, 其实玩到项目层面上, 都差不多.其实前端框架, 无非就是把后端框架的模板处理和路由功能拿过来强化一番而已, 单纯web而言, 我个人并没有觉得有很多优势, 但是手机端的混合式开发, 这些框架就好用的多.
vue文档的开发者比较聪明, 它的文档比较容易带你入坑(前端框架,一入前端深似坑啊), vue文档怕吓坏我们这些没胆的宝宝, 特意把构建工具这些放到最后面, 先用熟悉的jQuery方式把人"拐卖"进入它的圈子, 然后, 告诉你小宝宝别怕, 我很简单易学好用, 但是到组件化应用的时候, 整体难度上其实和另外两个差距不大,没办法, 它要完成这些事, 要做成一个前端框架, 路由, 服务器通信,组件间通信这些技术它一个也没法更简单, 做SPA就是这样的嘛, 能开发这些框架的人都是人精, 它没理由在同等功能上做的更简单, 不过vue的文档对入门更友好一些, 它的文档也是"渐进式"文档.
angula6呢, 由于采用的是typescript, 大多数人没学过, 得重新学了. 当然有些ES6的基础的话,更容易理解, 其实无论是ES6,还是typescript,或是python,甚至最新的java11, 感觉都在向统一方向进化, 语言特性也越来趋于相似.所以学新的ts倒也还不是事儿,关键是angular6自身框架设计中的核心概念, 依赖注入,控制反转, 组件编程等等概念学起来还是有一定难度的, 操作也挺繁琐的. 我个人觉得, angular6最大的问题还是轮子太少, 每个组件都得自己编样式, 都得自己写逻辑, 别人写好可用的东东不多, 比如我要做个后台, github上的adminlte拿过来随便改改我就用了, 用angular一个个重写, 写到哪年去.那除非说我后台用API框架或者用框架提供API,数据都给前端处理, 这还是值的考虑的, 毕竟要是用jQuery操作DOM再加上数据, 那得搞死人.
react没用过, 正打算学, 有学过的朋友欢迎留言讨论下.
当然, 前端这些框架, 就少不了几个构建工具了, gulp, webpack, 哦,还不能少了NPM这个前端的革命性命令行工具,网上这些工具的视频教程一抓一大把, 我就不一一赘述了.
4.2后端框架
后端框架典型的, python系列的django, PHP系列的laravel, thinkPHP和phalcon, java和.net的我不熟悉,就不说了, 说点我熟悉的.
其实一套后端框架所要做的事情也基本类似, 处理路由, 数据, 视图, 但是在框架的易用性上考量, laravel应该是这些后端web框架的佼佼者(github的星星数量可见一斑),django好用的地方是它自带了一个通用性很高的后台管理系统, 在这个基础上, 做后台可以免去不少工作, 但是路由传参的时候还是依赖于ORM找到的id, 不如laravel的模型绑定来的方便, 至于其他方面, 其实每个框架都差不多, 只是我一般用python来写爬虫和做服务器脚本, 不太喜欢用python的web框架, phalcon的好处是原理性的文档非常全面, 最新的phalcon7在易用性上有很大的提升, thinkPHP除了文档注释是中文的, 好像没有找到可圈可点的地方.这些框架综合考量的话, 我个人比较推崇laravel, 它的ORM,路由处理,模板处理,验证机制以及第三方可引用的库之间的衔接都做的非常到位,只要按照手册的规则, 目前没有发现有什么坑, 代码比较人性化, 不过如果要从性能上考量的话, phalcon不可多得, 因为这个框架单纯用C写, 所以概念的描述会非常到位, 文档很不错.
当然, 说道这些框架, php的构建工具composer不得不提一下, 其实也没啥提的, 反正我常用的composer命令不会超过5个, 自己看手册咯.............
5.最后
最后不得不说, 写的很晚了,困了,想睡觉^_^............
其实本文的焦点应该在如何学习上再深入一些, 只是写着写着, 好像有点跑题, 扯一些题外话, 只是自己使用一些框架的观点, 未必完全正确, 您姑且读之, 也欢迎您指正.