#程序要学什么?   由于我们讨论的就是以编程作为职业,所以在本节中,对编程方向所要学习的内容的分类表述,也以职业方向作为分类的依据。这里我把编程可能涉及到的职业,分成了7个大的方向来表述,分别是后端、Web前端、原生移动、底层、游戏、硬件和其他(数据挖掘、运维等)。虽然我算是全栈工程师,除了第六个方向硬件之外,在十多年的工作生涯中,其他方向均有所涉猎,而又以后端、前端、底层等方向所花时间最长。话说回来,知识和技能均在日新月异,虽然我讲述的内容是当下应当学习的内容,但是这些内容不可避免会随着发展而过时,也非常希望大家能从这些内容的表述中,看到要学习的本质所在,而不是表面或者过时。 ##1、后端开发方向   除非是做的不联网的单机 PC 或者单机移动端应用,否则后端是一个永远都绕不过去的方向。并且在所有的产品中,在进入成功和成熟的发展阶段,后端对整个应用的作用是至为重要的,比如数据全部存储在后端,安全和敏感的算法也是存储在后端,应用的大压力处理也是在后端。以微信为例,从界面上模仿一个一模一样的应用,不是太难的事,但是要做到微信如此大用户规模,还能有如此体验的,我想这样的团队就凤毛麟角了,即使如此,在2015、2016年的除夕晚上,微信红包和消息还是出现了不可避免的卡顿和错误。如果你想从技术上寻求挑战,加强对后端的学习和理解,是必不可少的。另外,由于后端学习到一定程度,要学习的内容较多,在工程上牵涉的面也比较广,所以对人的要求和能力也有很高的要求,所以后端成为架构师是一个正常的选择,统筹整个项目的架构往往也是由后端人员来负责。      那么后端学什么,我们把后端也分为两个门类来阐述,一个是业务逻辑的开发后端,一个是服务和底层的后端,前者就是这里表述,而后者我们就在第4个方向上表述。   在当今业界,业务后端技术也主要分为好几大流派。从技术上讲,这三大派都无所谓谁优谁劣,评判标准还是回到我们职业规划的路子上来,不是为学技术而学技术,是要看工作前景的。以笔者对国内互联网的了解,区分如下: * 第一大派(侧重指互联网行业)是 LAMP(Linux+Apache+MySQL+PHP) 或者 LNMP(Linux+Nginx+MySQL+PHP)。 * 第二大派是 JavaEE(Spring+Strust2+Mybatis+MySQL)。 * 第三大派就属于小语种派了(可能是把 LAMP 中的 P 换成 Python,可能是 Ruby 的 ROR,或者是在互联网领域不流行,但是在传统软件比较流行的 Windows + IIS + SQL Server + ASP.NET(C#) 等)。   在同一段时间之内,我们最好专门于上面其中一个,并以此能达到求职的水平。而对于不同的技术派系,对于学习的侧重点也是不同的。LNMP 至今在国内互联网比较流行,我认为有三个主要的原因:    * 一是语言本身开发效率高,与 Java 开发后应用不同,构建一个 PHP 应用的开发环境和基本框架相当快速,而且结构简单,更新极为方便。 * 二是 PHP 技术本身学习门槛比较低,语言本身学习门槛低,无论是对于没有经验的小白还是数年有经验的 C 程序员。 * 三是语言开创的模式也有意思,当年的CGI 单进程页面模式,大部分情况下基本不用考虑内存的消耗,HTML 代码与 PHP 代码能混用。 * 四是语言的成长过程中有小伙伴的给力相助,这些小伙伴就是 Linux、Apache 和 MySQL。 学习 LNMP,对 PHP 语言的学习,并不是唯一的,甚至不是最重要的,即使对于初学者而言,PHP 语言语法的学习也就是一两周的事情。所以 LNMP 的学习,是一个整体的技术体系。 首先要学习Web开发的相关技术。 * A、首先是 HTTP 协议,DNS、IP、域名等基本的概念 * B、其次学习 HTML、CSS、JavaScript 等编程技术的基础 * C、然后学习 PHP 语言,通过结合 前端技术,来了解一个 Web 应用的构建过程,PHP 与 HTML、CSS、JavaScript 是如何互相嵌入,互相链接完成一个整个应用的多页面逻辑的。 * D、学习完基本构建,然后就进入部署环节,需要了解 Linux 和 Nginx。 * E、当应用做得复杂之后,就需要加上 MySQL 数据库,在这个过程中,需要学习 PHP 大量的函数库,如果光学习 PHP 语言,不学习函数库,基本上是做不了产品的。 * F、在真实的项目构建过程中,我们还需要大量地用到开发的框架,比如国内最流行的像 ThinkPHP,其他的比如 Yii、Symfony,也有一定的受众。 * G、其他的高阶部分,我们在第三节展开讲述。 学完以上这些内容,并且能够独立地使用这些技术,开发出常见的一些应用,比如做个门户站点、小的日志博客系统、商品交易系统,才算是成为一个合格的入门级 PHP 程序员。 第二大派是 JavaEE 方向,尽管看起来是完全不同的体系,但是在学习路径上有很多相似之处,当然也有非常多不同之处。 A、上面描述 PHP 时所讲的 A、B 两点对于无论是 LAMP、JavaEE 还是 ROR 都是适用的,所以这属于 Web 开发的通识技术。 B、在具体的技术方面,Java 由于其是编译语言,又是严谨的面向对象语言,在学习曲线上相比 PHP 而言更加地陡峭。 C、在构建 Web 页面的过程中,倒是差别不大。同 PHP 相对的也有 JSP,也是能混用 HTML、CSS 这些技术的。 D、但是在部署和框架等方面,复杂度就更大了。比如 PHP 的引用,一个简单的 require 就搞定了,并且有相当多的方面的函数库,不用外接函数库,基本上 PHP 可以搞定大部分的应用开发,但是 JavaEE 的开发,除了用到框架库之外,也需要用到大量其他的第三方库 E、Java 的包版本、库的依赖、中文问题、Struts 配置等都会让不少新手难以舒适地接受。 F、同 Apache 相对的,JSP 也有 Tomcat、Resin 等容器的使用。但是在部署方面也相对麻烦一些,当然,在实际的生产中,不可避免用一些构建工具帮我们完成除开发外的其他过程,比如 Maven、Ant、Gradle 等 G、另外需要学习的技术,比如 Linux、MySQL,我也是推荐的,这毕竟是应用运行的基石。   学习 Java,与 PHP 不同,相对会用到比较复杂的 IDE 工具,比如 Eclipse、Netbeans 等,虽然 PHP 开发也可以在这两个 IDE 上进行,但是这不是必选项,但是在大型的 Java 项目中,这就成了必选项,因为在运行的过程中的包依赖和管理,如果没有 IDE,会比较痛苦,导致命令行特别长。   第三大派的技术,我就不展开说了,因为在互联网领域相对使用非常少,但是也可以做相应的替换,比如在 C# 体系中。Linux 被换成了Windows,JSP 被换成了 ASP.NET,Apache 或者 Tomcat 被换成了 IIS,而 MySQL 被换成了 Oracle 或者 SQL Server,Eclipse 被换成了 Visual Studio。   论语言本身,C# 本身可能比 PHP 甚至 Java 都更具亮点,但是有很多事情是要看环境和机遇的。Python 和 Ruby 也是如此,语言本身的设计比 PHP 可能来得好,尽管在国外,他们的流行程度可能不亚于 PHP,但是环境已经形成,要改变绝非一日之功。另外,这些年正在兴起的 Web 后端开发技术,Go、Scala 也不可小瞧,至于另外一个 Node.js,我们在后面的技能延伸部分再展开讲述。 ##2、Web前端开发方向   相比后端业务逻辑开发 25 年以上的历史,Web 前端作为一个独立的职业存在,还不到 10 年。但是它的受重视程度已经超过了后端。这主要有四个原因: * 首先是技术本身结构的完善和复杂化,让这个工种的独立不但成为可能,而且成为必要。其需要的技术难度虽说没有 PHP 这么庞杂,但是难度并不见得小。 * 二是随着当今设备的成熟,可以在设备前端或者浏览器端进行更为复杂的交互,而开发所谓的富客户端应用有了天然的环境,性能瓶颈也不再是大的问题。 * 三是技术本身有良好的跨平台、跨终端特性,无论是移动端和还是 PC、TV 等设备,无论是在 Android 还是在 iOS,我们可以用几乎同样的代码,来完成功能,所以很受欢迎。 * 四是某些超级应用,比如移动端的微信等的出现,无论是营销,还是游戏娱乐领域,加速了对相关人才的需求。 鉴于以上四点,我们充分看好Web前端开发学习的前景和钱景。因为它不但是时下所需要的,更是代表趋势所需要的,并且由于难度的存在,有一定的竞争门槛。 Web 前端学什么?简单点说,就是 HTML+CSS+JavaScript,各位要说了,那这不就是后端 PHP语言学习的那一小部分基础嘛。话是这么说,但是技术学习,有层次之分,比如在 PHP 的学习中,我们更重要的是学习 HTML 的结构、CSS 的嵌入方式、简单样式来进行前后端代码的嵌入或者套页面,在 JavaScript 方面,也只需要学习基本的 JavaScript 语法,学会使用 jQuery,学会使用 Ajax 技术来前后端进行数据交互,就达到了要求了。但是如果以前端做为职业,内容一下子就更变更深和更宽起来。 * 在 HTML 方面,前端需要了解标签特性,需要学习 HTML5,需要学习规范,语义标签等。 * 而在 CSS 方面,除了熟识基本属性,像盒模型、浮动等相对高级的主题之外,CSS3 中的动画、新增布局等也是必须掌握的。需要能根据设计师所设计的 PSD 图片,象素级地也编写出相应的 HTML+CSS 代码,此之谓“切图”。切图还不能光简单地使用页面在PC浏览器上正常显示 ,还得考虑多终端的显示技术,此之谓“响应式设计”。怎么样,内容多多了吧。 * 而在 JavaScript 方面,要学习的内容也会多起来,闭包、作用域、原型链、动画特效、HTML5 中的特性,哪一个又能少呢?JavaScript 是出了名的难学的,因为其语法相当灵活,这还不要紧,JavaScript 语言,本身就处于急剧的升级过程中,你会看到,下一个版本增加的特性,不亚于新学 JavaScript。   前端学了这三个就够了吗?也是远远不够的,因为前端也在发展,项目也越做越大。    * 一个方面,语言本身的特性像 LocalStorage、WebSocket、Canvas 随着技术的发展需要加以利用,以获得更加强大的功能。而一个又一个的开源开发库的使用更是工作中必不可少的,这些开发库又从多个层面对语言特性进行提升,底层的库如 Underscore.js、Sugar.js,再上一层增强库比如 jQuery、Zepto、React 等,框架级的如 Angular.js、Backbone 等,其他的工具库像 Swfupload/WebUploader、 Ueditor、ECharts、Lightbox 等,都是工作中的利器,其他的像 Bootstrap 也更是让我们如虎添翼。 * 从另一个方面,前端开发人员也需要用到大量的工具来管理项目,获取库,所以像 npm、Bower、Less、Sass 等技术也成了前端开发人员必备的。前端开发人员的 IDE 还好,但是开发和调试工具的掌握也不是那么简单的,Chrome 开发者工具、Google Closure、PageSpeed 等的使用是必备技能。 * 第三,由于前端开发技术的流行和受众的广泛,这个方向的技术也在迅速地延展应用的范围。比如使用框架Cordova、PhoneGap等相关技术开发跨平台的混合式应用,使用React Native 开发跨平台的原生应用。   学完了这些,那只是基本功,在前端的开发和优化中,有多达三十条以上的优化准则,每一条背后的技术、原理和改进手段,是不是也应该关注呢?所以一个好的前端开发人员,是难得炼成的。如果做像微信这样的内部嵌入应用开发,还需要对微信自身的 API 体系和规则有所学习和了解。需要学习微信应用自有的 JSSDK 和其他的 API 规范。在它的生态体系内,就需要去遵守,这也是开发人员应该去做的。老板和产品经理,提出来的是构想和结果,而整个过程的探索和坑,是需要开发人员去走的。 ##3、原生移动开发方向   在有的公司里面,把原生移动开发方向也叫前端开发方向,但是我们这里做了区分。尽管第 2 个方向 Web 前端开发方向,我们也不断地提到移动设备和微信等,但是它是用 HTML5 跨平台的技术实现了移动端的 WebApp 应用的开发。这种技术的特点是需要依赖于浏览器或者浏览器内核而存在。就像微信的公众号文章,其实就是一个网页,内嵌在微信里能阅读,因为微信的公众号文章阅读器,本身就是一个浏览器内核。   而本节讨论的技术要点不同,是原生的移动应用,所谓原生,就是能安装在操作系统层面,是不需要一个内嵌浏览器,应用是使用操作系统的原生控件而实现的。 根据系统的不同,也有不同的实现方式。对于 Android 系统,就是使用 Java 来进行 Android 开发,对于 iOS 系统,就是使用 Objective-C 或者 Swift 等来进行开发,对于 Windows Phone 系统,就是使用 C# 等来进行开发。 当然,除此之外,原生应用也有跨平台的方式,比如 C++ 语言,比如 Flash 技术中的 Adobe Air,比如 C# 的 Xamarin,比如基于 JavaScript 的 React Native。尽管有如此多的第三方选择,不过我们还是主要讨论前者。   对于原生语言开发的学习,分为如下几个层次: * A、首先要学习的是原生语言本身,Java、Objective-C、Swift 或者 C#。 * B、正像学习了PHP语言语法本身并不能做出实际的后台应用一样,光学习了这些原生语言本身也是然并卵。还需要学习大量的开发库。这些开发库包括但不限于以下类型,界面控件库(拖拽方式和代码方式)、图形库、动画库、网络操作库、消息通知处理库、地图、硬件感应器库、事件操作库、数据存储库等等。 * C、还需要学习大量的为了方便某一操作的第三方库,比如对 JSON 和 XML 的解析、增强的网络操作、定制好下拉刷新控件、社交网络和广告统计 SDK、某些特定厂商如七牛的存储操作 SDK 等等。 * D、上面的这些内容是零散的,我们需要将其整合在一起,形成一个完整的产品,这个开发的过程,是在点的知识基础上形成面的过程,其中包括了提升项目开发中的非编程能力。 * E、在产品实现的基础上,在本方向的学习和实践中,有一个东西,比第 1、2 个方向的开发来得更为迫切,就是优化。由于 PC 端和服务器端的资源,相对比较充裕,而移动应用的资源则是相对比较稀缺的,所以在实现的基础上的优化也很关键。无论是代码写法、库的使用、还是素材使用、带宽占用,都需要重点关注,这样才能达到一个新的水平。 ##4、底层研发方向   底层是相对应用层开发而言的,第 1、2、3 个方向所讲述的技术都是应用层开发的技术,我们所开发的内容是跟某个具体的业务逻辑直接相关或者是用户看得见摸得着的技术。    * A、比如在后端开发方向中,我们可能需要使用 PHP 库的 API 来调用 MySQL 数据库,存储用户注册和登录所需要的用户身份信息。这里面不但涉及到 PHP 数据库 API 的使用,更涉及到用户信息的字段、存储等问题。 * B、在前端开发中,我们要使用响应式设计技术,在 PC 上和手机设备上美观地显示出用户的个人主页,可能是通过前端后端结合直接生成页面,在设备上渲染,也有可能是在页面脚本上预置好显示域,通过 Ajax或者BigPipe 等技术从服务器端获得取数据来组装显示。 * C、在原生移动开发方向中,通过网络获取到应用后端的用户数据,返回回来的可能是 JSON 或者 XML 数据,然后将用户的信息显示在界面的文本控件或者图片控件中。   底层研发则与此相对,是跟某个具体的业务逻辑操作关系不大,而是对一类应用都适用的一些系统底层服务,不同的业务,但是底层可能相似甚至相同。比如缓存服务、队列服务、全文检索服务,这类服务不被用户所直接感受到,但是对于一个大型应用而用,是至关重要的。此类服务的开发对人的要求更高,因为本身开发的调试难度大,对资源的要求也高,稳定性更是如此。此类服务所使用的技术,同前三个方向的技术也不相同,当然,比如说像 Java 语言,是可以发挥上用场的。 同前三个方向在学习的差异在哪里呢? * 1、这个方向上的技术,相对更新的频率是比较低的,比如前端,HTML5、响应式设计这样的新概念可能层出不穷。而底层的多线程、分布式文件系统、缓存算法更新的相对慢一些,即使有新的技术比如压缩算法经常出来,但是使用老的也没有太大影响。 * 2、对算法和数据结构的要求较高。在业务逻辑的开发中,可能调用库的 API,对数据进行组合和处理,就达到了要求,但是底层服务,可能需要面对的有大量的数据需要存储在内存中,我们就需要使用更为高效的数据结构进行内存存储,比如在网络上进行传输的内容,我们可能除了对内容压缩之外,可能还尽可能采用 MessagePack 这样的存储格式。 * 3、对语言本身的功底要求高,对于业务逻辑开发,重要的在于功能实现。对于底层服务,除了实现之外,稳定性要求也非常关键。比如使用 C 或者 C++ 进行开发,尤其需要关注内存的分配与回收。有些服务在短时间内看不出来内存的消耗,比如运行一天就泄漏了几 M 内存,但是长久积累,也必酿成大患。笔者的工作经验中,有运行三年还正常运行的服务。可以想见对开发者的要求之高。   那么,在这个方向上学什么呢?有多种不同的语言都能完成后端服务的开发,对于现有的团队,我们按团队所熟悉的和擅长的技术来进行推荐,比如你们团队有 Java 大牛,就用 Java,有 C/C++ 的牛人,就用 C/C++,有 JavaScript 大牛,Node.js 也是不错的选择。对于新入行的个人,我建议轻易不要以这个方向做为初始方向,除非你有良好的算法功底。   无论是 Java、C/C++、Node.js,还是 Go、Erlang、Python 等,各种语言一般都能完成后端服务,不过各自的强项有所区别。   比如 Java 可能在网络和库方面,相对更为丰富,但是吃内存较高,不过当前这不是太大的问题,Hadoop 生态系统中大量的服务基于 Java 而开发。   C/C++ 的运行效率相对较高,但是对人的要求也高,尤其是内存和数据解析这些环节上,需要自己干比较多的低层的活。普适面比较广泛,无论是内存型、CPU型、多线程型计算,它都是不错的选择。   Node.js 的服务则多见于 API 相关的服务,或者像 Websocket、Socket.io 这样的服务,能快速低成本地构建起服务原型,从服务原型到产品本身也容易升级。   Go、Erlang 的强大更偏向于分布式和海量并发链接一些。Python 则倾向于快速开发实现。   本方向适合在校专业的大学生来关注和较长时间地积累学习,不推荐新手作为职业而投入学习,尤其不适合转行的新手,但是对于一个成熟团队或者快速发展的团队,则是必须去关注的。 ##5、游戏开发方向   前面的四个方向,我们都可以用其中的技术,为游戏开发提供服务,大部分技术还可以发挥作用,但是本文还是将游戏部分独立开来,因为游戏实在是一个特殊的行业。从前端到后端,从移动端到底层服务端,从美术设计到策划运营,都有自己的特殊性。我们在这里也加以叙述。   一个游戏产品的产生,在开发阶段,主要包括三个工种:程序开发、游戏策划和美术设计,游戏策划相当于电影和电视剧的编剧这个工种,工作内容主要包含文案对话、场景的编写和描述、打怪或者掉宝等的数值设计、关卡经验升级策划等。美术设计就是我们在游戏中所能看到的界面、画面都是他们设计出来的,主要通过2D或者3D来表现,包含了战斗场景、人物角色、动作过程和特效设计等。   而程序开发则根据不同的产品,区分出了不同的程序开发工种。大体上分为端游、页游和手游,首先说页游,由于是内嵌在网页游戏器中的游戏,所以不需要下载客户端,在早些时候,2012 年之前吧,主要以 Flash 技术为主来进行开发,而今,HTML5 已经兴起,成为页游开发的主力技术之一。而端游则一般根据不同的桌面系统,需要开发不同的客户端,一般以 C++ 为主要计算机语言,比如在 Windows 上运行的端游戏,Visual C++ 和 MFC 技术,是必须要掌握的技术。手游则根据不同的平台,对基础技术的要求不同,比如 Android 平台,要学会基本的 Android 应用开发,iOS 平台,学会基本的 iOS 应用开发技术。对于跨平台的,就需要学习 HTML5 基础开发。然后在此基础上,进行拓展,拓展的技术之中,其中最重要的是游戏引擎技术。比如 Windows 上的端游,游戏引擎 DirectX、OpenGL 等是必学科目,由于跨平台游戏的兴起,cocos2d-x 这样的引擎也支持桌面游戏的开发,而在页游中,Flash 引擎、Unity 引擎,国内的 HTML5 引擎如 Egret、cocos2d-x HTML5 版,其他的如 Box2D 等都需要学习和应用。手游除了 OpenGL ES,还需要学习 cocos、cocos2d-x 和 Unity3D 等引擎。在这些引擎的学习中,所需要的语言,与基础语言也有别。比如 DirectX、OpenGL 在端游上一般是 C++,而在 iOS 和 Android 开发中,OpenGL ES 都有相应的 Objective-C 和 Java 版本,Flash 引擎,就是 ActionScript,Unity 插件的开发使用的各自平台的原生语言,本身场景的开发则需要 C# 语言支持。   后端的技术,同 1、4 两个方向的差别较小,我们可以使用 PHP 提供基本的接口服务,我们也需要使用一些底层的服务来对游戏的聊天啊、高并发进行支持。在此不再展开。   我想上面这些技术的描述,已经足以让你晕乎和望而生畏了,不要太紧张。我们总结一下。 * 1、无论端游、页游还是手游,本身基础平台应用的技术是要学习的。 * 2、如果不跨平台,就要在上面的基础之上,学习各自平台的游戏引擎。至于具体用到什么技术,看引擎而定。 * 3、如果跨平台,目前页游戏的 Flash、端游和手游的 C++ 技术,是需要学习的,也建议加以学习。 * 4、总体看来,游戏开发人员的要求相对 Web 开发、前端和原生应用开发水平而言,要求要高一些。 * 5、由于游戏行业的特殊性,工作强度和压力也会大很多,当然如果游戏成了,收入也是可观的。 ##6、智能硬件方向   互联网发展到今天,经历了人和信息互联、人和人互联两个大的阶段,现在进入人和物,物和人,物和物互联网的第三阶段,这个阶段,属于万物互联的时代。这个阶段,如何操控周围设备,制造新的设备的需求得到了空前的释放。这也得益于移动互联网的发展。智能手机的出现,智能手机中各种自带来的模块和传感器的存在,让这种互联提供了良好的基础设施。所以一个新的开发人员工种出现了,其实更严谨地说是开发工种升级,这个升级还是混搭的。 一方面,由于一般用 App 去操控硬件设备,所以前面说的原生移动应用开发方向的技术,也是这个方向的人所需要学习的。但是另一方面,还产生了两个小方向的分化,一个方向是应用层的,应用层的,需要对已有手机上的设备与操控、数据采集、读取、通讯有相当的了解。比如蓝牙芯片,比如陀螺仪、空气压力传感器,方向传感器,加速度、地理位置、温度、重力传感器等等,在应用层上对这些设备进行控制是相对比较简单的,因为智能手机系统的开发商,无论是 Android 和 iOS,都提供了相应的 SDK 对其进行访问和处理。另一个是相对底层的,过去也有一个开发工种,叫嵌入式或者硬件开发,偏硬件一些,一般来讲,以 Linux 方向的底层编程技术居多,这块涉及到 Linux 底层 C 开发、ARM 体系结构、Linux 的驱动、移植等内容。 在自己制作的硬件上,硬件作为数据发生或者采集端,通过不同类型的传感器采集不同的数据,比如步行、跳跃、心跳等,转换为数字数据,再通过蓝牙等常见模块与手机 App 的数据交换,从而实现硬件和手机的双向控制。 如果仅仅是作为硬件产品,上面这些内容可能也足够了,但是现在有一个新的现象是,对于智能硬件的开发,我们也不能仅限于数据收集和交换数据,还需要同社交网络比如像微信交换数据,这就需要我们的智能硬件产品接入微信硬件开放平台。 从上面的描述可以看出,智能硬件开发的学习可以总结如下: * 1、如果是偏硬件底层的开发,对底层驱动、Linux C、硬件体系结构的开发和认识是本方向特有的。 * 2、如果是偏应用层的开发,首先需要学习也是原生 APP 开发的那些技术优先。 * 3、然后才是跟硬件相关的 API,API 的学习相对是比较简单的,这原因是每一种硬件,它的操作不多,从而 API 也会比较精简。 * 4、总结来说就是这块的开发,对算法的要求水平并不是很高,但是对于可靠性,内存使用方面就颇为苛刻了。因为硬件的升级和资源都是比较大的问题。 ##7、其他相关方向   上面这些已经包含了当前的主要开发工种,但是是否已经全了呢。也不尽然,比如运维、测试、大数据等需要一定编程开发水平的专业并没有包含在前面的描述中,所以在这里也加以描述。   运维方向从狭义地来理解就是维护机房设施、机器设备、系统安装、软件升级这几个层面,也形成了一些不同的工种,比如网络管理员,可能偏重于网络设备和防火墙的维护,比如系统管理员(SA),偏重于系统维护、软件升级等,数据库管理员(DBA)偏重于数据库维护与优化。但是运维工作在这些年出现了两个趋势。一个是云计算平台的兴起,让运维的层面减少了对机房、机器、网络等设备的维护,另外一个方面增加了不少类型的监控服务,比如监控日志的,监控安全的,监控服务器性能的,监控域名健壮性的 DNSPod,监控应用程序性能的 OneAPM 等。第二个趋势是 DevOps,也就是说开发和运维要在一定程度上互相跨界。做开发的要明白运维,而反过来,做运维的童鞋也需要去了解开发,当然这个开发,是业务开发。比如你运维的是 PHP 站点,那么对 PHP 本身机理了解会让你如鱼得水。   即使只做运维,运维本身也有一些需要你去了解和学习的,当然,相比开发,这个学习的内容就少多了。在互联网公司做运维,第一个是 Shell,无论是开发监控脚本,还是自动化一些繁杂琐碎的工作流程,Shell 都是很好的粘合剂,所以 Shell 也称做胶水语言(Glue Language)。由于一般做运维要涉及到大量的日志分析等工作,当然这些工作 Shell,也可以完成,但是相对更专业一些的语言,Awk、Sed、Python 或者 PHP 如果能加以学习,将会让你的日志处理和分析工作如虎添翼。   运维在一个互联网公司中,相对职位需求是比较少的一个岗位,并且工作也相对更加繁琐,要求7X24小时响应,工资方面也较开发低一些。   测试按不同的分类方法,需要的能力不同,比如分为黑盒测试和白盒测试,前者如果是手工测试,一般并不需要编程水平,也接触不到代码,但是如果是自动化测试,就需要编写一些脚本,比如 iMacros、Selenium 这样的插件,就是支持自动化脚本录制、编写的,难度比较低。而白盒测试就比较好理解了,因为是从代码的层面去发现 BUG,并提出修正的建议,所以对编程语言的熟悉是必要的,当然需要什么,就看产品而定。如果是从功能测试、体验测试、性能测试等类型进行区分,手工测试部分不需要代码,自动化部分需要代码,而压力测试部分,像 LoadRunner 也是有专门的脚本的,命令行工具部分,只是学习命令行就 OK 了,还不到写代码的层面。   测试工作在比较正规的,开发模式比较成熟的团队需求更加迫切一切,在普通的小团队,或者产品快速开发的团队,缺少这种角色的存在。有几个原因,一是由于互联网的产品更新迭代太快,可能上午发现了BUG,下午就要上线,可能来不及有一个复杂的测试流程。其实来讲,产品的质量首先由开发人员把控,其次由产品人员来控制,只加给测试是不公平的,他们也是承受不起的。   最后再来说一下大数据领域,笔者在之前接触过一些做 JavaEE 的开发人员,他们想转到互联网公司工作,而大部分互联网公司并不需要纯粹的 JavaEE 开发人员,所以就选了大数据领域做为一个切入点,并转型成功。目前我们狭义地说大数据,都是指 Hadoop 生态系统,这个生态下面的软件,大部分都使用了 Java 软件开发,所以 Java 技能成为了从事大数据的必备技能之一。但是实际上从事大数据专业,开发的分量只占其中一部分,大部分的工作,在于构建和维护一个 Hadoop 集群,并采用其生态系统中各类不同的服务的服务来存储(Hadoop HBase)、处理(Sqoop、Flume)和分析数据(Hive、Pig、Manhout)。除此之外,在得到了一些结果了之后,还需要使用一些统计语言如R进行分析,最后使用Web或者移动Web App的前后端技术对结果进行展示。 关于学编程学什么这个话题的概述就讲完了,至于各个方面上详细需要学习什么,我想即使一个方向一本书也讲不完,所以不再详细展开,这里只给大家一个方向性的指引,同时也做几点补充说明。虽然我们的话题以程序员作为讨论的整体,但是大部分情况下更倾向于讨论互联网行业的程序员,因为这才是未来和方向,而不是纯软件领域。其次,互联网行业的程序员和软件领域的程序员存在相当大的不同。小到作息时间,比如软件领域的程序员可能作息是下了班,基本没有工作上的事情需要处理,而互联网领域的程序员可能随时需要联机处理故障,如果出了问题,中饭不能吃,熬夜也要及时解决,而软件领域的程序员,只要发布的时间未到,这个时间安排是不太紧急,是固定的。大到工作习惯和意识,软件领域的程序员,可能更看重软件工程,代码编写,但是不太考虑迭代,大用户量,而互联网领域程序员更看重实现和高性能并发。这些考虑,并无是非之分,有的只是习惯的差别。但是一旦这个角色发生切换的时候,这种意识也可相应地转变,否则是不能合格的。