本篇博客是《软件开发者成长完全攻略》系列翻译文章第 1 章。
原文地址:How to Get Started in Software Development
当我刚开始学习软件开发的时候,我根本毫无头绪。
我感觉很沮丧。所有的东西我都看不懂,我甚至不认为我可以“掌握”编程。
我之所以告诉你这点是因为我觉得既然你选择了我这本书,说明你可能跟我那时的感觉是一样的。
不要担心,这很正常。事实上,这根本就是常态。
让我来彻底澄清一件事:你不需要是一个天才,甚至智力水平不需要超过平均水平,也能成为一个软件开发者。
对于一个刚刚进入软件开发大门的初学者,如果你没有觉得茫然,并感觉自己像是被在脚踝上绑着重物丢进池底的话,你可能是哪里做错了,也可能你压根就不是一个普通人——或者二者皆是。
无论如何,你应该清楚刚入门的时候是会感觉困难和混乱的,但是这种状态不会持续太久的——我向你保证。
我是如何起步的
依稀记得当我开始自学编程的时候。那时候并没有像现在这么多的编程资料。事实上,我根本没有任何的资料。
我去下载了一个很流行的 MUD 源码(Multi-User Dungeon 多人地下城,你可以将它想像成一个基于文本的魔兽世界,毕竟那是一个使用调制解调器进行拨号上网的时代)。
但是我根本搞不懂我看的代码是什么意思。我所知道的只是我想创建一个属于自己的修改版 MUD 并为其添加新的特性,而要达到这个目标的关键就隐藏在这一堆看不懂的神秘文本中。
于是我开始瞎搞,我修改了某些变量的值。我试图去寻找控制暴击机率的代码,并对其进行修改,重新编译,然后看看会发生什么。
有时候它照我的预想运行了,而有时候它根本编译不起来。在探索代码可以运行和不能运行的过程中,我已经学习到东西了。
我依然不懂我所修改的东西,但是经过了一个星期左右的“瞎搞”,我居然真的创建出了一个有我自己添加过功能特性的新版本 MUD。
成为一个娴熟的程序员还有很长的路要走,但我已经开始了 —— 所有人都需要一个开始。
我讲这个故事是想让你明白,相比直接拿起一本书,相比去大学或者培训机构,相比其它任何事情...这才是入门编程的正确方式。
你必须自己熟悉代码,了解哪些方式可以让它工作,而其它方式不行。(我确信这才是学习的最佳方式。请参考我的软技能一书中关于学习的章节。)
但是,学习如何编码跟如何进入到软件开发的世界之间还是有很大区别的。
没错,你必须先学会编码,但是软件开发并不仅仅是写代码,本章讲的就是关于代码之外的那些技能。
了解这个职业
首先,你需要了解一些软件开发的知识。
它比你想像中要来得容易,也要来得难。
本书有一整个小节专门讲述“软件开发所要掌握的技能”,但是我想先要这里做一个快速的综述。
软件开发并非只是写代码。编程是其中很大的一部分,但是如果只会编程的话,你可能走不了太远 —— 特别是当你想从工作中脱颖而出的话。
软件开发背后的思想是将手动的过程自动化,或者是创造一个新的自动化过程来完成一些无法使用手动完成的工作。
想像一下我现在正在使用的文字处理软件。我正在使用 Google Docs 写这篇文章。
如果没有 Google Docs 或者其它的文字处理软件,我就必须使用打字机或者手写的方式来写文章。
如果我想要对文章进行格式化,我就必须在打印前手动进行排版。
如果我想修改一些错误 —— 特别是拼写错误 —— 的时候,我需要在手边放上一瓶涂改液。(可能还需要一瓶威士忌。)
当然,现在不仅仅有 Google Docs 可以帮助我完成这些事情。还有很多其它的硬件或者软件可以帮我将手写或者排版的过程自动化,但是我想你已经明白我的意思了。
因此,在你上车之前,我需要特别强调一件事,这件事你越早知道越好。
在将一件事自动化之前,你必须知道如何手动完成它。
了解需求
太多有抱负 —— 同时也是有经验 —— 的开发者在没有完全理解软件功能需求的情况下进行开发。他们一心只想着写代码。(这对于学习编码来说没有问题 —— 就像上面 MUD 的例子 —— 但对于开发一个企业级软件却是行不通的。)
当然,你比他们更机智,因为现在在看这本书。
弄清楚待解决的问题是所有软件开发过程的第一步。你想实现自动化过程的是什么?
针对这个问题,不同的软件开发模式有不同的办法,不过对我们来说,目前那并不重要。现在最重要的是,你需要通过某些方法,去收集需求并在开发真正编码之前理解你需要解决的问题是什么。
这件事可以很随意,跟潜在的客户讨论下他想要的软件,以及这个软件有哪些功能。也可以很正式,编写一份标准的文档说明。
设计
一旦你明白需求是什么,你就可以开始设计如何使用代码完成这个需求了 —— 再次地,你需要在动手写代码之前完成设计。
可以把它视为你的代码架构蓝图。同样的,不同的软件开发模式有不同的方法来解决这个问题,但现阶段最重要的还是你需要在开发编码之前进行某种程度上的设计。
这对于不同规模的软件都适用。有些学习过敏捷开发(会在之后的章节中讨论到)的程序员觉得他们不需要任何设计,只需要开始编码就行了。虽然事前设计不是敏捷开发的重要,但是设计仍是必要的。
你不可能随随便便就写出一个软件来。
编码
只要设计完成后,你就可以开始针对这个软件的功能编写一些测试了(也就是测试驱动开发或 TDD),也可以直接开始写代码了。(我们会在后面的章节讲到 TDD。)
编码是一个专门的主题,所以在这里我并不会详细展开,不过我想推荐两本必读的关于如何写出好代码的书。
首先,我推荐 Steve McConnell 的《代码大全》,这是一本所有程序员都必读的经典书籍。
第二本是 Rober Martin 的《代码整洁之道》,教你如何写出更好代码的另一本经典书籍。
用现在的话讲就是,这两本书可以教你如何写出优雅的代码,即有良好的可读性,同时易于维护。
这两本书对我的编码技术有非常深远的影响,特别是在于代码的清晰性和设计上。
测试及发布
一旦编码完成了,我们就该发布了,不是吗?
错!现在进入到了对代码进行测试的流程。还是那句话,不同的开发模式有不同的办法来处理这个问题,但是通常来说,在软件正式发布给用户之前都需要进行某种程度上的测试。
比如对于传统的瀑布流开发模式,测试阶段处于整个软件开发过程的末期。但是,在敏捷项目中,在每一个迭代过程中都需要进行测试,每个迭代通常为 2 个星期左右。
一旦代码测试完成了,就开始进行发布了,关于发布也有它自己完整独立的流程。
我们现在还不会深入到细节中 —— 后面会有一整章专门讨论这个问题 ——,但是发布流程其实就是将开发完成的软件部署到服务器上,在 app store 上架,或者使用其它可以让用户获取到软件的方式。(这个过程可以相当复杂。)
在这个过程中,代码可能 —— 好吧,其实是必须 —— 被存放到源码仓库中,这个源码仓库会管理不同版本的代码,并且它在开发过程中的变化都会被存储下来。
在某些比较复杂的应用中,会涉及到数据的存储,这里我们还需要用到数据库。
数据库通常会用来存储应用的用户数据,或者一些配置信息,而这些数据也都需要跟随代码一起更新。
很多软件开发团队会使用某种形式的持续集成环境,它可以在代码被提交的时候自动进行构建。
编程不仅仅是写代码
最后,别忘了调试。作为一个开发者,你的大部分时间将会花在搞清楚为何你的 —— 或者别人的 —— 代码不能正常工作。
如你所见,软件开发可不仅仅是写代码这么简单。
在你找到一份真正的程序员工作之前,你需要对所有的这些技术有所了解。更进一步地,但愿你对这其中的某些技术能达到熟练的程度。
不要害怕,帮你达到上面的目标就是我写作这本书的目的 —— 或者至少给你指明一个正确的方向。你可能需要自己去学习所有的技术,但是至少我会告诉你如何去学习它们。
制定一个计划
好吧,John,现在我已经明白了软件开发不仅仅是写代码,并且我愿意花很多时间去进行调试,但是你还没告诉我如何入门呢?怎么说?
唔,是的。我明白你的意思,但是你知道吗?我有一个好消息告诉你:你已经入门了。恭喜。
在你拿起一本书,就像这本一样,并且开始理解软件开发不仅仅是写代码时,你已经比其他大多数的开发者有一个更好的开始了。
没错,没错,这种说法是有点自我感觉良好,但是它确实是真的。有一天当你成为一个像我一样老成的软件开发时,你也会说同样的话。
现在,让我们讲点更实用的,你需要制定一个计划。
是的,就是一个计划。一个真正的,不瞎逼逼的计划,它能让你从对软件开发一无所知(或者接近一无所知)成长为一个经验丰富的开发者。
你有很多不同的路可以走 —— 我会在后面的章节中一一介绍 —— 但是选哪条路不是最重要的,更加重要的是你要选一条路,并坚持走下去。
整合计划
让我们看看你的计划应该是什么样的。
首先,你需要对自己当前的水平有一个正确的评估,同时搞清楚需要学习哪些知识。
你有任何软件开发的经验吗?
你了解任何一门软件开发语言吗?
你之前写过任何应用吗,或者你完完全全就是从零开始?
我前面提到的其它技能呢?
你有没有掌握它们中的任何一项?
你对数据库,源码版本控制,测试驱动开发,测试,调试或者软件开发模式有任何的了解吗?
同时,问问你自己想做哪个方向的软件开发。
很多新手可能都想做游戏开发,但是这现实吗?如果是的话,你要从哪里开始?你有没有做好觉悟,投入大量的时间去应对挑战,去走这条很长并且很孤独的道路?
太多的人在没有经过任何的事前思考的情况下就朝着某个方向出发了。
花些时间去回答这些问题,这样你就会在开始前有一个合理清晰的计划。
不要误解我的意思,我当然会在本书中尽量帮助你解决这些问题,但是我不能代替你做全部的事情。
我能够给你提供成为一个好的,甚至是优秀开发者的所有信息,但是你需要自己将这些信息进行整合并制定一个适合自己的计划,然后照着这个计划走。
创建计划
一旦你对这些问题有了自己的思考,就到真正创建一个计划的时候了。
创建计划的最好方式就是从你想达到的目标进行倒推。
相比于“学习如何编程”或者“成为一个软件开发者”,你要对自己想成为哪个方向的开发有更明确的目标。
在本书的“你所需要掌握的软件开发知识”小节中,我会介绍不同的软件开发角色与工作类型以供你选择,你也可以自行上网搜索,来决定确定哪个最适合你。
你的目标要越具体越好,这样一来,你就可以知道自己需要学习哪些知识,如何制作简历以及作品集,想进入什么学校或者培训机构,甚至是应聘什么样的工作。
我知道做出选择和下定决心有多困难,但是关于目标的重要性我再怎么强调也不为过。
这个目标越具体,后续的学习就越容易。你会清楚地知道每一步需要学习什么知识,以及如何行动。
谁想成为一个“运动员”?
思考一下这个问题:假设你的目标是成为一个“运动员”。
这个目标就太宽泛了,你要如何训练自己成为一个“运动员”?
可能你会去举重和跑步,也有可能去训练游泳。同时,你还会去网球场上练习击球。
你会努力地去做所有运动训练,好让自己在最终决定时,可以加入任何一个运动团队。
这听起来很荒谬,对不对?这就跟有人想成为“软件开发者”一样 —— 实际上更甚 —— 荒谬。
相反地,你需要一开始就选定一项运动。
一旦你选定了这项运行,你就可以知道如何针对这项运行进行训练,这会让你活得更轻松 —— 相信我。
从目标开始进行倒推来确定达到这个目标所需要的知识和行动。一旦你完成这个步骤,就可以真正开始制定计划了。
计划的一开始应该是围绕所有你需要学习的技术。弄清楚所有这些知识的学习顺序,以及如何进行学习是至关重要的。
接着,你要弄清楚应聘一个岗位以及找到第一份工作需要准备哪些东西。
最后,你要为获得这份工作定一个确切的计划。你要在哪里找工作?你需要做什么?你申请的是什么样类型的工作?
我可能还会为你增加一个计划,那就是在找到第一份工作后,如何继续提升自己的开发能力及学习更多的知识。
这里的信息量可能有点多,但不要担心。我写这本书的目的就是为了让所有的这些对你来说都变得更加简单。
在接下来的几章中,我会帮你弄清楚你所要掌握的技术以及如何学习这些技术,在更后面的章节中,我会给你描述获得一份工作的所有细节。
现在,你可以开始思考你的计划应该是什么样的,以及尝试思考自己想成为哪种类型的软件开发者。
Hey John
但是我真的不知道自己想成为哪种类型的开发者?这是一个好问题。如果你是一个初学者,你甚至可能都不知道有哪些选择可以选 —— 除了游戏开发者。
幸运的是,这并不是一个很难弄清楚的问题 —— 虽然需要你进行一下网上搜索。
在这本书的后面,我会讨论一些软件开发者的类型。大多是在“你所需要掌握的软件开发知识”一节中,但是同时你也需要进行自己的搜索。
问一些你认识的软件开发者,他们做的是何种软件开发,以及他们是何种类型的软件开发者。
思考一下你对创造哪些东西更感兴趣,并搜索一下这个东西的相关技术及编程语言。
对于一个软件开发者来说,现在有太多的技术和相关的细分领域了。
你想开发 web 应用程序吗?手机应用呢?你想写代码来控制冰箱的恒温还是想向宇宙中发送宇航员?
仔细思考这些问题并进行搜索。如果你的问题是对的,那么答案就不会那么难找了。
一个具体的例子
我一直都觉得实例会起到很大的作用,所以现在我们来看一个真实的场景,一个想以 Node.js
为主要技术的 web 开发者的计划:
目标:成为一个 Node.js 开发者
计划:
- 学习
- 学习 JavaScript 基础
- 学习网页与 web 开发技术,如 HTML 与 CSS
- 学习 Node.js 基础
- 可以使用 Node.js 开发一些简单的 web 应用
- 学习不同的框架以及其它开发者用来开发 Node.js 应用的技术。
- 从上面的搜索中了解一些可以使用的技术及框架。
- 学习 Node.js 支持的某种数据库技术。
- 学习计算机科学基础:
- 算法。
- 数据结构。
- 学习写清晰代码的最佳实践。
- 学习如何设计 Node.js 应用的架构。
- 为找工作做准备
- 开始寻找在自己领域中的 Node.js 开发者的工作要求,并确定公司需要哪些技术。
- 列表出你最有可能获得工作的本地公司列表。
- 开始参加本地的技术分享会。
- 在网络上认识其它的本地 Node.js 开发者。
- 雇一个简历写手来帮助自己写一份好的简历。
- 练习技术面试的相关问题。
- 模拟面试。
- 建立一些 demo 应用的作用集供展示。
- 获得工作
- 联系自己网络上的所有人,让他们知道自己能提供什么样的价值以及我正在寻找哪种工作。
- 开始申请初级或者实习岗位的工作。
- 计划每天至少应聘两个公司。
- 面试后进行复盘,并决定哪些技术需要深入学习。
你的计划一开始会很粗糙,但是随着你对需要学习的内容有了更多的了解,就可以在计划中补充更多的细节了。
在一开始就准备好计划是相当重要的。你可以随时修改或者调整计划,但是如果你在一开始没有计划,你会像无头苍蝇一样乱撞,这有极大的可能导致沮丧并放弃学习。
在下一章中,我会帮助你进一步改进计划,我们会讨论成为一个软件开发工程师所需要掌握的技术。