自己有个习惯,从高中开始就喜欢利用少许时间在百度知道回答感兴趣的问题,并且完全原创(经过多年,各种形式问答已经是我的最大兴趣之一,我也对旁人提出的问题具有较高敏感度),大致7年间发现很多人有志于从事软件开发方向,他们有的是在校大学生,有的是高中生感兴趣,有的是在校初中生就想学习编程,或者毕业后想转行到编程,有基础好的,也有基础很一般的,他们的问题大致都可以笼统的归结为两类:
对于第一类,是见招拆招,自己熟悉的领域一般能给出精彩回答,自己暂时不熟悉的分支领域则尽量不回答或者以经验和推测的形式引导他们参考某些Helper。对于第二类,由于各个计算机分支领域多少都是相通的,所以我可以给出自己的综合分析结论作为建议给他们参考。
第一类好解决,会就是会,没碰过的就给人指大致方向和思路;第二类则是定位+心理预期问题,良好的定位是成功的一半(不排除某些人没定位,直接刻苦投入,也能走得很远)。
此篇文章重点希望通过全景鸟瞰+分支细节该如何顺序去学习,来构造一个较为通用的指引。
>> 1. 计算机专业领域一共有几个大方向,十几个分支方向,而每个分支方向又有几十个小方向,每一个方向的深入学习与熟练到一定火候都不是一朝一夕,互相之间也不是完全没联系的,但是无论是初学者还是中前期学习者都应该选择一个大方向并在其中的一个小方向内深入(为什么要这么早就选择具体的分支方向?后面说)。
>> 2. 这里列出计算机的几个大方向(非编程开发类的我就不说了):
基本方向:
单片机、嵌入式方向网络编程:涉及到服务器程序、客户端开发、脚本设计等系统编程:基础API开发、桌面开发、系统程序开发、服务程序图形学:3D、2D、图像识别、人脸识别音频:语音识别、音频解码、音频软件编译原理:编译器设计、脚本解释器、虚拟机、非自然语言翻译系统应用层开发:利用高层语言去开发表层应用 安全:反工程、病毒、反病毒、木马、反木马、软件破解、软件加壳附加方向:
人工智能:遗传算法、神经网络、灰色系统等等游戏设计:各种游戏引擎设计以及业务逻辑设计等>> 3. 基本方向是学习者一定要选的,附加方向只是基于基本方向的一些锦上添花,但是不管学习者怎么选,最开始某些东西一定要深入而不是只是懂就够(当然学习者对自己要求不应该低),我把这个列出来:
以上几个基础就是学习者成为一个融汇各个主要分支牛人必须学的(当然不是指理论,而是理论+实践编码能力)。
>> 4. 以上都是大的基础,要一一攻破并深入学习,虽然网络时代计算机专业知识爆炸式的增长,但是以上几个基础掌握后,会发现,以后的什么新的理论和技术都是基于这些大基础,学习者就很容易理解了(或者且当你对方法论比较感兴趣,在方法论的催化下+以上浑厚基础,会有一种被打通任督二脉的感觉)。
>> 5. 我为什么开头不讲学习者要具体学什么怎么顺序学呢?因为那些技术学习者要掌握的话,根本可以自己解决(翻书+实践的反复循环),但是如果没有一个对自己现在投入的努力和【以后形成的能力和层次积淀的预测】的基本了解,那么毕业后虽然也能找到不错的工作,薪水也可能高,但是却不是一个大牛(虽然这之间确有转化关系,仅个人见解)。
现在才开始讲学习顺序(一种可能的顺序,并且大部分被我验证或预测过)。
C语言是可以写很多核心和高级的东西,而不只是小东西,编码技巧有很多可以提高的空间之处。
学习者的学习顺序应该是:
C:建议有时间的话,学到这个程度-做一个超级马里奥出来,并能够读取文本脚本来更新关卡。
C++:写一个2D图形引擎,封装掉细节,实现面向对象设计和可复用设计(但是2D图形引擎注重效率,对复用的设计理念显然不需要太在乎,所以最具有复用挑战力的是外表简洁,内部设计复杂而高度灵活如WPF的GUI),并且用到《设计模式》中提到的一些设计模式,这样才能算对C++有一个很好的掌握。
MFC:MFC技术虽然据说前期一段时间冷下来了(近期又有新的热度,貌似融入了新的血液),但是学习者能熟练掌握它,才能短期内证明学习者的C++OO技术够纯熟,严格证明学习者掌握了MFC很简单,学习者只要用MFC做出一个非内核的杀毒引擎简化版就差不多了。推荐的书有《深入浅出MFC》。
《Windows程序设计》:和MFC不同的是,用的是windows核心SDK,也就是Windows API,这本书学完后,学习者才能从操作系统层面上算掌握了win32 平台下的机理(其实win64和win32大部分API机理类似)。
C#:C#里集合了当代和前沿计算机科学里最先进的一些语法(虽然执行效率一直被人质疑),但是学习者学完C#并深入后,至少能够算是对计算机语言有一个更加深刻的理解了。如何证明学习者C#学的不错了?也很简单,再次写一个随便什么游戏。如果更加证明自己呢?用它写一个P2P网络对战游戏。
>> 6. 作为进阶学习编程语言的附加要求,其它语言建议也学习下,学之前可以先看《冒号课堂》(告诉你各种范式语言之间的关系,让你对编程语言有一种截然不同的全新视野的掌握)。
如果学习者注意的话,会发现我说的学习顺序都是沿着语言和某些技术的,为什么呢?因为这些语言和技术涉及到特定的领域技术和计算机理论思想,比如【真正】学完了C++或C#的话,就不单指学完了C++或C#,而是把多种语言范式都学习了一遍,以及现代的程序开发思维(因为里面用到了很多让学习者一劳永逸的技术)
以上5个步骤都是基础大步骤,要解决的话要没1-2年应该不够。
与此同时,要尽快选出文中学习者感兴趣的方向作为3-5年的长期方向,不要担心过早选择分支方向会有什么损失,因为计算机很多分支是相通的,只有学习者把分支方向深入进去,才能真正理解很多理论的实践意义。并且一旦学习者在某个分支领域形成了较强的优势(比如,到公司里只有学习者这方面最强),那么学习者就是稀缺人才。
关于大方向的细分步骤就暂时先说到此处,有兴趣学习者的主要就是要把我说的这几个基础步骤先解决,同时平时要注重大方向理论结合实际去编码和开发。
>> 7. 最后,再从资本论的角度去度量一下为什么要深入至少1-2门技术,而非只是泛泛的都学。
一个公司不需要一个功能对应的所有可选技术类型,通常只要其中1-2种(就如服务器脚本语言,为了便于开发维护和人员更替,也都是集中在1-2种。就算会N种技术,一个时间段只能从事其中一种工作。完全不用担心自己好不容易深入的技术公司正好不用(你进公司之前,不光是公司选你,你也在选公司),另一方面,技术也是相通的,深入一个再深入另一个同类技术,是【极其】容易的(建立在时间+实践)。
泛学的东西,你能用1个月、半个月、1星期、几天学会,别人也能(再者,学会不难,熟练成习惯并转化为开发效率,才是问题,因为这不是技巧问题,而是时间成本问题),那么这就完全没有竞争优势了,你泛学了N种技术,而公司正好需要其中之一时,别人只要投入也同样这么短的时间就能临时追上你的泛学程度的步伐,何必呢?而你要赶上别人花了几年的深入程度的东西,不可能只需要花几个月(除非你之前早已深入了类似的东西,但这就推翻了你是在泛学的前提,所以不用考虑这种情况)。
我评估两个人之间的领域能力的差距是这么来的:一个人如果想超过另一个人的某个分支领域能力,要花多久?如果要花几天或几个月,说明差距不大,如果要花几年,就是很大的能力差距了。(时间是衡量能力的最终极标准:当然建立在正态分布和个体特殊差异之上)
曾经有人问我,怎么才算深入的学习了某东西,有个专攻JAVA的人问我这个问题("如何彻底深入理解JVM”),我不假思索就果断的回答他:要真的深入一个东西,只需要实现一个类似的东西。他还是没对上号,然后当时我进一步说:如果你能实现一个类似于JVM的东西,不就代表你深入理解了JVM吗?
当然,以上学习和认知思路并非唯一的,但至少我认为是多种学习路径中较为可行的。