大牛程序员是如何入行的?(附带Web开发者入行指南)
当我刚刚入行成为一名软件开发者的时候,我对自己所要从事的工作一无所知。我那时非常沮丧。我觉得这份工作没什么意思,我甚至都不认为我是“得到了一份工作”。我之所以告诉你这件事,原因在于:如果你已经捧起本书探求答案,你对这种感觉一定似曾相识。
别担心,这很正常。事实上,这也很自然。
让我说得直白一些:想成为一名软件开发者,你其实并不需要是个天才,甚至都不需要必须拥有平均水平以上的智商。
当你刚进入软件开发领域的时候,你要么感觉不知所措,要么感觉就像脚踝上绑好重物然后跳入万丈深渊,你或许做错了什么,或许你根本就不是人类,也许两者兼具。
无论如何,当你进入软件开发行业的时候,你应该想到这一行的艰辛和困惑,但你却没有想到——我打赌。
我是如何入行的
我还记得自己最开始自学编程的时候,并没有像今天这样拥有那么多的资源。事实上,我任何资源都没有。
我下载了一个流行的MUD游戏[1]的源代码(这是一个多用户版本的“地牢围攻”游戏,类似于《魔兽世界》,但没有图形只是文字)。是的,那是在遥远的“使用调制解调器拨号到BBS系统”的年代。
我甚至不知道我在看的东西到底是什么。我所知道的就是,我想创建一个属于自己的MUD版本,添加我自己规划的功能,并且最关键的是,我还要把这一功能掩藏在一堆奇奇怪怪的字符串之中。
刚开始我把一切搞得一片狼藉。我修改了变量的值,我搜罗了一些据说能够给对手致命一击的“秘籍”代码。我拿来改了改,重新编译了MUD,看看会发生什么事。有时我能得到我想要的结果,有时干脆编译都通不过。伴随着观察怎样做会行之有效而怎样做又一无是处的过程,我学会了。尽管我还是不知道我在做什么,但是在“摆弄”这些代码一周左右的时间后,我居然创建了一个MUD游戏的新版本,这个新版本中居然真的包含了一些我自己做的功能。
在成为一个专业高效的程序员的漫漫长路上,这只是一个开端,而我们每个人都需要一个开端。
我之所以告诉你这个故事,是因为直接动手做要比捧起一本教科书、走进大学或者参加编程训练营……都要重要得多。“千里之行,始于足下”,我相信这才是踏上编程之路的正确方式。你必须做些小打小闹的修修补补的工作,看看怎样是可行的,怎样又是“此路不通”的。我确信这才是学习的最佳方式。(参见《软技能:代码之外的生存指南》之“十步学习法”。)
但是,学习编码与学习“如何开启软件开发的职业生涯”是截然不同的两件事情。你的确需要学习如何编程,但软件开发远远不止编程。本章恰恰是关于编程之外的内容。
了解专业
首当其冲,你需要知道关于开发软件的一些东西。这比你想象的更容易,也更困难。
本书的有整整一篇内容都在论述“关于软件开发你需要知道些什么”,但是这里我只是给你一个快速浏览。
软件开发不仅仅是编程。编程是其中的一个重要部分,但是如果只知道如何编程,你不会走得很远;尤其是当你想在这个领域中脱颖而出的话。
大多数软件开发项目背后的想法其实就是要把一个手工的过程自动化,或者换句话说,就是要创建一种新的自动化方式来做一些对于手工操作而言过于困难的事情。
看看我,我现在正在使用的字处理软件Google Docs写这本书。如果我不用Google Docs或者其他字处理软件来输入本章的文字,那我只能选择使用打字机,或者干脆完全手写。如果我想编辑好文档格式然后打印出来,那我只能一个字符接着一个字符地手工排版好,然后才能打印。如果我想修改一些错误,尤其是拼写错误,那我得在手边放上一整瓶的涂改液(可能还需要一瓶威士忌)。
如今,不仅有Google Docs,还有一系列硬件和软件程序能够帮助我自动化打字以及手写全书的过程。我想你已经明白了这一点。因此,请允许我向你强调一个核心概念,在踏上软件开发的职业生涯早期你就应该了解的一个概念,越早越好:在自动化某一个过程之前,你必须知道手动完成这件事情的全过程。
理解问题
太多拥有雄心抱负和丰富经验的软件开发者在试图编写一个软件时并不完全理解这个软件应该做什么。他们想直接跳进去编码。(在MUD游戏的例子中,这个方法兴许还不错。但它并不适合用来创建软件产品。)显而易见的,你比他们更聪明,因为你正在阅读本书。
软件开发的过程往往都是从对问题的透彻理解开始的。也就是,你需要自动化些什么?
不同的软件开发方法论在解决这方面问题时都有不同的方法,但是这个问题现在还不是最重要的。当下,关键点在于,在某种程度上,你必须收集一些需求,借此建立对要解决的问题的理解,然后才开始编写代码。
这个过程可以很简单,只需要与潜在客户交流一下,讨论需要构建怎样的系统、它应该如何运行,也可以很正式,创建一份完整的需求规格说明书文档。
设计
只有理解了问题之后,你才可以构想出设计方法,也就是,问题如何以代码的方式来解决——注意,这个过程依然发生在编写代码之前。
你可以将这个过程看成是构建代码的架构蓝图。同样,不同的软件开发方法论实现该过程的方法多种多样,但最重要的是,在着手开始编码之前,你需要做出某种程度的设计。
这条规矩同样适用于大规模软件开发与小规模软件开发。一些熟悉敏捷软件开发(这一点我们将在后面的章节中讨论)的开发者认为他们不需要任何设计,他们可以马上开始编码。尽管敏捷开发的重点在于“轻前期设计”,但是设计仍然是必不可少的。
想要盖好了一幢房子,你可不能把标准板材随心所欲地堆在一起就算了事。
写代码
一旦对软件的设计有了一些了解,你就应该编写一些测试用例来定义软件应该做什么(称为测试驱动开发,即TDD),也可以着手开始编码。(我们会在后面的章节中进一步讨论TDD。)
写代码本身是一门学问。因此,这里我们不会深入讨论,但我会推荐给你两本必读的关于编写代码的经典名著。我推荐的第一本书是Steve McConnell的《代码大全》,这是每位软件开发者都应该阅读的经典著作。我推荐的第二本是Robert Martin的《代码整洁之道》,这是另一本经典名著,它能在如何写出更出色的代码方面助你一臂之力。这两本书将帮助你学习如何结构化你的代码,以及如何编写易于理解和维护的代码。
这两本书都对我的编码技能产生了深远的影响,尤其是在如何澄清问题和如何设计方面。
测试和部署
那么,代码一旦被写出来,我们就可以发布软件了,对吗?
错。接下来应该是测试代码的过程。同样,不同的测试方法实施的测试过程也不尽相同,但总体来说,在将软件代码交付给最终用户之前实施某种形式的测试还是必要的。举例来说,在传统的瀑布式开发项目中,测试发生在项目的最后,但在敏捷项目中,每次迭代后(通常持续两周左右)都会有测试活动。
代码只有在经过了测试之后,才可以部署,这本身就是一个完整的过程。
本书后续内容中将有一章是关于部署的,这里我们就不讨论细节了。概括地讲,部署就是将已完成的软件安装在服务器上、上载到应用程序商店或者以其他某种方式能够让既定用户访问到该软件的过程。这个过程可能相当烦冗复杂。在这个过程当中,代码可能(那几乎是一定)会出些小毛病,所以需要将代码签入源代码库中,这样保障不同版本的代码及其在各个时间段的变更都能得到有效存储。
在一些处理卷和数据的复杂应用程序中,部署还可能涉及某种数据库的活动。数据库通常存储应用程序的用户数据或者配置信息,它也需要随着源代码的更新而不断更新。
许多软件开发团队使用持续集成的方式,在开发者“签入”程序的时候自动生成代码。
不只是写代码
最后,千万不要忘记调试。作为一个开发者,你大量的时间都将用于发掘你写的(或者别人写的)代码为什么不能正常工作的原因。
综上所述,软件开发远不只写代码那么简单。
在找到一份真正的软件开发工作之前,你需要了解上述所有知识。至少你要拥有一些经验和技能,如果达到精通的水准那就更好了。
但是,别害怕。本书的目的就是为你做好一切准备,或者,至少给你一个面面俱到的介绍,从而可以指引你走上正确的方向。你得自己备好行囊,旋即阔步进入软件开发的广阔天地,但至少,我可以告诉你该准备些什么。
做好计划
“好的,John,我已经知道了,软件开发不只是写代码,我会花很多时间调试代码,但是你还没有告诉我如何开始从事软件开发工作呢。”是的。我明白你的意思,但你猜怎么着?有一个好消息:你已经开始了,祝贺你!
拿起一本像本书这样的书,并且真正试图去理解软件开发并不只是写代码,你已经比大多数软件开发者拥有了一个更好的开端。
我知道,这里我又犯了自我感觉良好的毛病。但这的确是真话。有一天当你变成了一位像我一样牢骚满腹的老软件开发者时,你也会向别人唠叨同样的事情。
现在,我们讲得更实际一些——你需要一份计划。是的,一份真刀真枪、切实可行的、言简意赅的计划,一份规划你怎样从一个对软件开发一无所知的小白成长为无所不知的软件开发大拿的计划。
想做到这一点,有很多条路可供选。我会在后面的章节中论及其中的部分内容。但是,所谓“锲而不舍,金石可镂”,与其绞尽脑汁、苦苦思索该选择哪条路,还不如选好一条路之后持之以恒、坚持到底。
把计划组合在一起
让我们谈谈你的计划应该包含哪些内容。
首先,你需要开诚布公地评估一下自己当前所处的位置,以及你需要学习哪些东西。你有编程经验吗?你了解编程语言吗?你创建过应用程序吗?还是你彻头彻尾就是一个新手?本书前面内容提到过的其他技能,你是否拥有一两样?你对数据库、源代码控制、TDD、测试、调试或者各类软件开发方法有所了解吗?还有,问问自己:你想做哪种类型的软件开发工作?
当然,每个人都想成为游戏开发者,但是这切合实际吗?这真的就是你想开始的地方吗?你愿意把精力都耗费在这条漫长而又孤独并且充满竞争的道路上吗?
太多的人终其一生都会沿着一个方向执着前行,却不会在发轫之始就去深思熟虑以谋定而动。花一些时间回答这些问题吧,这样你才可以在策马扬鞭走上这条职业之路时计划周全。
别误会我。我将竭尽所能让本书对你有所裨益,但其实我能帮到你的也仅限于此:我可以给你为成为一个优秀的甚至伟大的软件开发者所需要的所有信息,但是你必须亲自动手把它们组合成一个有机的、为你自己量身定做的行动计划,然后你要做的就是遵循这个计划。
制订计划
一旦你对这些问题已经考虑成熟,那么现在制订一个切实可行的计划恰当其时!
制订计划的最好方式就是以终为始——从想要达成的目标开始一步一步倒着排。你必须要制订一个具体的目标——你想成为哪种软件开发者,而不是像“学习编程”或者“成为一名软件开发者”这样泛泛的说法。
在本书第三篇“关于软件开发你需要知道些什么”中,我将全景展现所有值得你去考虑的关于软件开发的不同种类的角色与职位,但你也可以自己做一些研究以确定哪一种才是最适合自己的。
计划的内容必须尽可能具体,这样你才会了解你需要学习什么,你该如何制作简历,你应该报名参加哪种学校或者培训课程,甚至你需要申请哪些职位。
我知道做出这些决策与承诺是很困难的,但我无法不去强调这是多么重要!关于你想成为哪种软件开发者这件事,你考虑得愈是具体而微,一切就会愈发唾手可得。
你将能够清楚直白地告诉自己你需要学习什么,以及你需要为职业生涯的每一步做些什么。
谁想当运动员
我们举个例子:假设你想成为一名运动员。
这是一个相当宽泛的问题。你应该成为怎样的一名运动员呢?也许你应该练练举重和跑步,也许你应该练习游泳,或者也许你应该练习打网球。那你能不能把所有这些事情都做了,甚至练更多的项目,以便为成为一名全能运动员做准备,在任何一支队伍里都可以出色发挥。这听起来是多么荒谬可笑啊!事实上,当一个人许愿说“我想成为一名软件开发者”时,听起来也是荒诞不经的。因此,“选择你的运动项目”很重要。
一旦你了解了一项运动,你就知道为了那项运动该如何训练自己,这将使你的生活更容易——相信我。从目标开始,以终为始,以此来决定为了达成那个目标你需要知道什么、你需要做什么。
一旦你如法炮制,就可以制订出自己的计划。你的计划应该以从需要学习的东西开始。弄清楚你需要的学习顺序以及如何学习是至关重要的。然后,你应该尽一切所能搞清楚:为了得到自己的第一份工作,针对你所要申请的职位,你需要做好哪些准备工作。最后,为了得到这份工作,你还需要制订一份切实可行的计划——你要去哪里看看?你打算申请哪个职位?你打算怎样申请?可能还需要增加一个计划,列出你在得到第一份工作之后如何继续个人发展与实施在职教育。
有点儿不知所措?没关系。我写这本书就是要让这一切对你而言简单易行。
在接下来的几章中,我会帮你了解自己需要哪些知识,以及如何获取这些知识,同时在后面几篇中,我将就如何找工作给予你详细的指导。而现在,你需要开始思考你的计划应该是什么样子,并且试图弄清楚自己想成为哪种开发者。
向John提问:可是我真的不知道自己想成为哪种开发者?
没关系。如果你刚刚入行,你可能都不知道自己有哪些选择——除游戏开发者以外。
幸运的是,想弄清楚这个问题也不是什么难事,只需要做一些调研。
在本书后续的一些内容中(主要是在第三篇“关于软件开发你需要知道些什么”中)我会介绍软件开发者的种类,但是你也不妨自己做一些调研;询问一些你认识的软件开发者,他们在做些什么,或者直截了当地问他们“你是哪种开发者”;思考一下,在创新和研发领域,有哪些相关的技术和编程语言是你自己感兴趣的。
在软件开发这一行,有很多的职业发展通道和技术专长领域,你大可以选择其中的一部分作为自己的主攻方向。你可以选择Web应用程序方向,也可以选择移动应用程序方向,你也可以写一段调节冰箱温度的代码,也许你想要编写怎样把宇航员送入太空的程序。
三思之后,着手做一些调研工作。只要你的问题正确,答案也不难找到。
具体示例
我总是觉得,真实的例子最有用。因此,让我们来看一个真实的场景:某人想成为一名Web开发者,选择以Node.js作为主要技术方向。
目标 成为Node.js开发者。
计划 学习
- 学习JavaScript的基础知识。
- 学习Web页面和Web开发技术,如HTML和CSS。
- 学习Node.js的基础知识。
- 可以编写某种用Node.js开发的简单的Web应用程序。
- 学习开发者用于开发Node.js应用程序的不同架构和技术。
- 基于上述原因,列出某些和Node.js一起使用的架构的技术。
- 学习某些和Node.js一起使用的数据库技术。
- 学习计算机科学的基础知识,例如:
- 算法;
- 数据结构。
- 学习有关编写优质代码的最佳实践。
- 学习Node.js应用程序的架构设计的方法。
为找到第一份工作所需的准备工作
- 开始在我所在的地区搜寻有关招聘Node.js开发者的广告,找出岗位要求必须具备的技能。
- 列出本地我有可能找到工作的公司名单。
- 开始参与本地用户组的活动。
- 开始与本地的其他Node.js开发者的联谊活动。
- 聘请一位简历写手,请他帮忙写一份优秀的简历。
- 实操面试时可能遇到的编程问题。
- 实操模拟面试活动。
- 构建一个应用程序作品集,包含有数个自己开发的应用程序,以备面试时演示。
找到一份工作
- 跟我的关系网的所有联系人都打好招呼,让他们熟知我的价值、我正在找寻什么样的工作。
- 开始申请一个初级职位,或者实习开发的职位。
- 每天至少申请两个职位。
- 每次面试之后都要做总结,确定我还需要在哪些技能上增长功力。
你的计划一开始可以简略一些,之后随着你了解到的自己应该学习和掌握的东西越来越多,你需要让自己的计划越来越翔实。
拥有一份计划永远是至关重要的。你可以不断地调整和变更计划,但是如果你连一份计划都没有,你会漫无目的地随波逐流,更有可能会因为心情沮丧而放弃。
本文摘自刚刚上架新书《软技能2 软件开发者职业生涯指南》
- 作为一名软件开发者,我该如何起步?
- 我该如何培养自己的技术能力?
- 我该如何谈判薪水?在合同制员工和正式职员之间我该如何选择?
- 我该如何跟我的老板、同事打交道?我该如何对待职场偏见?我该如何跟技术女性打交道?我该如何成为一名技术女性?
- 我真正需要知道什么?又该如何学习它们?
- 大学学历教育、编程训练营还有自学成才,该选哪一种?
- 我如何找到一份工作?如果没有经验,我该怎么办?
- 我怎样才能通过面试?
- 身在职场我该怎样穿着?
- 我怎样才能推动自己的职业发展提升到一个新的水平?
这是一本为软件开发者量身定做的职业发展指南,处于任何发展阶段的软件开发者,都将从本书中获益。如果你是软件开发/编程的初学者或者只是对软件开发感兴趣的人士,可以通过本书了解如何开启软件开发的职业之旅,如何获得第一份工作;如果你是中级软件开发者,可以通过本书发现自己的知识短板,学会如何进一步拓展和掌握新的技术技能,如何学习新的编程语言,如何提升技术水平,如何在自己梦想的编程工作中深耕细作;如果你是身经百战的专业软件开发者,可以通过本书了解如何拓展和推进自己的职业生涯,如何更好地与同事和老板相处,如何推销自己的想法,如何做好向上管理,如何升职加薪。