• 原文作者:朱众 授权本技术博文转载。


刚进公司时,在你正式动手写代码前,很可能要理解code base。这一过程至少持续1个月,取决于你所在项目的规模。你会发现你不得不使用你浑身所学之能事,理解上古程序员是如何解决一个个实际的问题的。有的时候你沾沾自喜,“哈哈,这个技巧劳资经常用,你们也算有点见识”。但大部分时候你很糊涂。

在此阶段,你每天的工作就是看文档,看设计图,读代码,放断点debug,hack,fix,问同事。

你很累。你很无聊。

此外,刚进公司的你,会发现你的项目组正在使用一些奇葩工具、冷门技术,他们非常不好用,尤其跟你大学时候用的成熟IDE相比。你可能会想砸键盘,“谁特么想出来的用这个工具!谁特么写的这么sb的工具!”

你很失望。

渐渐的,你开始了解了你们的业务领域,所谓的掌握了一定的领域知识,你开始有能力判断哪些是权衡,哪些是权宜,哪些是极精妙的设计,哪些是遗留代码。

你的领导也发现了这一点,于是开始给你安排简单的任务。他们可能是改一些显而易见的bug,可能是实现一个最简单的新特性。此时你会有一种驾驭的错觉,你很快的写好了功能,提交,开始幻想自己精妙的代码收到表扬。当然,不出意料的是,你提交的100行代码里被找出了10个bug,其中2个是很严重的逻辑错误,4个是未实现的需求,2个是ui错误,2个是边界条件未检查。

你心里十分不爽,“妈的劳资这么屌炸天的代码你们都不懂得欣赏!”

此时你的领导过来轻描淡写地来了一句,“我们提交之前要进行code review”。

于是你找了你身边比较和善经常解答你问题的小哥来代码检视,10分钟之后,你漂亮的代码被改得面目全非,你欲哭无泪,又不想得罪前辈,于是默默地提交了这不知道是谁写的代码。

就这样挣扎着过了几个月,你开始摸清了门道,于是你开始运用你大学时期课内或者课外学到的引以为傲的技巧和知识了。领导自然也发现了这一点,于是他开始安排你组织技术交流会,你精心准备好了ppt,自己在家排练,并且试图加入一些或者高冷或者没品的幽默段子。

会议很成功,你感觉到同事开始对你刮目相看,你开始飘飘然,重新拾回“驾驭”的感觉,心想“就你们这帮码农,劳资以后可是架构师!”

渐渐的,你开始进入了状态,你提交的代码越来越多。刚进公司时你从来没打开过的代码规范文档开始回来找你麻烦,不过这不是大问题。领导开始对你强调质量,而你则在心里抱怨旧代码的设计。你想要重构,你想要创新,你想要搞一个大新闻。

与此同时,组里新来了一位同事老李,是从其他部门调过来的老员工,领导组织组里盛情欢迎了他,你心里不服,但是他是个好人,你们谈笑风生。

机会来了。

公司要紧急实现一个演示功能,百万级的合同能不能拿下来就看这次了,你的领导已经亲自飞往客户那里坐镇,他走时跟你说,“组里就靠你和老李了!”

你十分激动,买好了泡面和零食,准备通宵作战,给领导提供最犀利的火力支援。

第一个功能点谈下来了。领导发给你了要求。

你发现你半懂不懂。

里面提到的一些其他模块,你在每月组织的技术交流大会里听说过,但你写过的那点代码里从没调用过他们的API,你更没读过他们的代码。你有点不知所错,开始心虚。

不管了,先开始干。

你找到了一些相似的功能,翻出了一些发霉的陈年旧代码,注释里写着2004/06/18。你没有时间完全读懂,你开始复制粘贴,直接debug。当然,代码报错了,你开始挨个解决,就这样,一个通宵。

第二天早上,你总算把你熟悉的后台部分调通了,你发现了新的麻烦。

是前台。你对前台并不熟悉。你知道javascript的原名叫ECMAScript,你知道JQuery对象和dom对象的区别,但是你发现你还是看不懂你们的前台代码。

怎么办?

好吧,你决定拉下脸,问老李。老李看你的样子,说,“你去睡一会吧,我来帮你看”。你心里有些不甘,有些不好意思,也有些感激。你很想自己把它们做出来,但你不会,而且时间也来不及了。你想学学他是怎么做的,但是你的大脑已经停止工作了。于是你疲惫地笑了笑,“好,交给你了。你看一下这里这里还有这里...我就去睡半个小时,一会就回来找你。”

你这一觉睡到了下午。

你醒来一看表,震惊的弹起来,赶紧回办公室找老李。老李已经从你的座位回到自己的座位上了,正在慢悠悠地喝茶。你有些惊喜地问他,“怎么样?”他回头看见你回来了,说,“放心吧,已经给一线调试了,你去吃点饭吧。”

你哪里有心思吃饭。你惊讶地对老李说了声“好的!太好了!”然后回到你的座位上迫不及待得打开代码开始运行。正如老李所说的,功能已经实现了。你轻舒一口气,拿出一碗泡面泡上,开始啃代码,心里想的是“这次一定要准备好,防止下次再出乱子。”

啃着啃着,你有些不耐烦了,因为你发现代码越看越多,已经超出了你的大脑容量。你想了一下,决定先放在一边,查收一下邮件放松一下。

邮箱里又是塞满了新员工培训的资料,各个部门的联谊活动通知,当然最多的是服务器发来的build report和test report。没什么有趣的事。

你想了一下接下来要干嘛。算了,还是接着写新特性吧,测试们还等着你呢。但是你其实很忐忑,你的心早已飘去了前线,但是你知道你不能发邮件问状况,因为你领导可能几天没睡了,何况你也并没有什么特别紧急的事。你破天荒的把邮件客户端开着,留意每一个新收到的邮件。

就在这样的忐忑中,一天过去了。反正也没什么事,你回家好好洗了个澡,定了个早早的闹铃,安心的睡觉了。

第二天一大早你就跑去公司,果然邮箱里有了领导的邮件,上面写道“演示很成功,客户很满意,接下来是谈判阶段。家里的开发兄弟你们太棒了!”

当然,你很高兴。但是又有一点失落。你不太明白为什么,于是你想了一下。随后你似乎明白了,虽然这是一个好消息,但是好像跟你又没什么关系,跟任何人似乎都没什么关系,好像是一件自然而然的事情一样,并没有“holy shit”超神的声音。

过一会,你的大领导,项目总经理回复了你领导的邮件,说“干得好!同时也对家里的兄弟提出表扬!回来开庆功会!”你心里略有一些期待,“不错”,你想到,虽然主角不是你,但是你毕竟也是功臣。

你为庆功会暗自准备了很久,你在网上浏览跟领导吃饭该说些什么,你想好了很多概括性的有内涵的问题来证明你对项目的理解,你也想多了解一些项目的大方向。

几天之后,你领导回来了,大家开了庆功会。饭局上,大家聊聊家常,聊聊你领导在国外的见闻,大领导知道了你的名字,大家似乎很随意的打了一会牌,就这样平平淡淡的结束了。你略有一些失落。

生活回归正常。

但似乎又跟以前不那么一样。

你在开发工作以外,有了新的任务,其中包括学习推广新技术等等。你开始跟你领导彻夜长谈。他与你分享他的经验,你与他分享你的见闻。你开始接触他的工作,比如提高团队能力,完善自动化测试,提高代码质量,提高代码性能,增强功能可配置性等等。你开始淡定的接受新的工作,而不再幻想一朝成名的瞬间。毕竟,迎接挑战才是你真正感兴趣的事。

不过,这接下来的几个月里,除了改自己先前遗留下来的bug,你几乎没有提交任何代码。你每天的工作变成了看框架,读代码,看技术文档,学习试验新工具,浏览技术论坛等等。你开始觉得有一些缺乏成就感,也有点怀念绿绿的单元测试结果和噼里啪啦弹钢琴一般飞舞的手。

有一天晚上,只有你和你的领导在加班。你的问题困在心里很久了,于是你问道,“老大,为什么我的任务跟别人的不太一样了?” 老大说,“那当然了,你是当作未来的技术主管来培养的。”

突然的幸福让你不知所措,不过你克制地问道,“技术主管都是干什么的?” 老大并没有回答你,而是说,“以后你就知道了”。

生活还在继续。

跟你同一天入职的晓明是一个勤奋而又活泼开朗的人,但是你觉得他似乎入错了行。他总是挣扎着思考为什么他的代码中有逻辑错误。对你来说再简单直接不过的一段代码,他也很难读懂。领导也发现了这一点,所以安排他渐渐地向配置管理(CM)方向发展了。不过他似乎对这个很擅长,无论多么繁琐的任务,他总能按部就班的完成,各种纷杂的脚本他也一一了熟于胸,重要的是,他很有耐心,无论服务器出了什么奇葩问题,他都会跟它死磕到底。大家都很喜欢他,也很信赖他。

有一天,晓明像往常一样抓住你向你请教问题。是个bug。你已经习惯了从代码检视开始。你自信地叫他给你看代码。然而你并没有发现什么问题。于是你问什么现象。他说部署到服务器上就报错了。你看了一下日志。你没想通。于是你再仔细重新检查了一下是否各个环节都作对了。是的,没有什么问题。

好吧,你知道你遇到棘手的问题了。不过谁知道下一秒会不会就解决了呢?进公司这么久,各种奇葩问题对你来说早已是司空见惯。你打开搜索引擎,开始试图寻找相似的问题。你不断的做出假设,然后通过证据否定它们,然后再作出新假设……直到你突破了你的理智,你觉得可能是编译器出了问题。

真的假的?你从来没有想过编译器会出问题,就好像你从来没有想过你的肝脏有一天会报错一样。你觉得应该是自己错了,于是你仔细排查了一下其他的可能性,不,没有别的问题。于是你把服务器上编译过的字节码通过反编译工具打开,你发现了一件微妙的事情。于是你跟随着这个线索继续上网查找原因。终于,你发现是兼容性的问题。你发现了新大陆。

问题虽然复杂,但是你只需要简单调整一下代码就可以绕过这一问题,于是你三下五除二把代码改好了,测试,嗯,哈哈,果然没有问题。晓明在旁边看得发愣,问你,“咋回事啊?” 你心里有一丝淡淡的骄傲,你兴奋地把他拉过来看你搜到的网页,你把代码反编译之后跟源代码对比,你给他讲依赖加载的实现……你兴奋得讲了一大堆,他静静地听完之后,眨了眨眼,说,“大神啊!”

艹,他根本没听懂。你一下子泄了气。你也没什么可说的了,但也不知道该如何接茬,就谦虚道“没有没有,我不是大神”。

虽然如此,他依然天天跟着你“大神”“大神”得叫你,虽然你知道他很菜,但是当个伪“大神”也不错。你有点沾沾自喜,想说给你的同学听,又觉得太 low。要不发个状态“我不做大神好多年”?想想太蠢,只好作罢。

直到你发现还有好多人也被他称为“大神”。

失落?

有一点。

你都习惯这种失落了。自从意气风发地毕业之后,你再也没有那种强烈的胜利的感觉。你觉得生活似乎并不是你之前那样的一元化。大家都有各自完全不同的特长、兴趣、知识和经验,你也有你的,你并不是万能的。即使在上学的时候你从来都是班级里的佼佼者,但是你渐渐的发现世界还很大,你不会的还很多,山外有山,人外有人,路漫漫其修远兮,吾将上下而求索……

想到这,你的思绪突然中断了。你觉得自己实在是太优秀了,还懂得反思。你又开始了沾沾自喜,心想,自己如此优秀的人,总有一天会干出一番大事。于是你收拾收拾心情,继续工作。

最近项目没有那么紧张了,你渐渐的多出了不少时间。你领导也是。所以他又推荐给你了几本书叫你看,都是一些设计的书,什么《领域驱动设计》、《企业应用架构模式》、《修改代码的艺术》等等。你想起了刚来的时候他叫你读的《重构》,《设计模式》等书,你还记得刚翻开它们时的那种醍醐灌顶、豁然开朗的感觉。你微微一笑,说“好”。

这些书写的真好,你感叹道。

读着它们,你总是不自禁地想起你们的代码。你非常能理解书里描述的现象,你觉得你们的代码有着同样的问题。可是当书里介绍解决方案时,你却发现理解它们很困难。书里面的问题域跟你们的不太一样,你们有着不一样的需求和架构。书里说对于数据库的操作要做这样的一层封装,可是你们除了数据库还有web service;书里说对于UI和业务逻辑要做这样的隔离,可是你们的UI并没有直接调用后台,也是通过web
service;书里面提到了好多技巧,你们并不需要……

你看得很无聊,渐渐的失去了耐心。简单翻完了书的后半部分,你觉得你差不多明白书里面说的方法了。一种乾坤大挪移练到第七层的感觉油然而生,你非常急切地想找点东西试试功力。

你踌躇满志地对你领导说,“我想对我们的代码 进 行 重 构 。”

出乎你意料的是,你领导一点都没有惊讶,而是笑眯眯的问你,“呦,好啊,你打算怎么搞啊?” 你没有想过这个问题,愣了一下,说,“就按照领域驱动设计的方法改啊,构造一个充血领域模型。” 领导继续笑眯眯,“好啊,那你打算怎么实施呢?”

怎么实施?什么叫怎么实施?改代码就是改代码咯,还怎么实施?你摆出了一个困惑的表情。

领导笑的更开心了,“你还记得《重构》里说过的,重构代码要保证单元测试全通过吗?但是现在你要重新设计,单元测试肯定都没用了,要重新改。你来看这个。” 他掏出一本书,指着某一章的标题说,“如果要对代码进行大型重构,只好退而求其次,使用高覆盖率的自动化测试来确保大部分功能的正确性。但是只是这样是远远不够的,我们还得保证原有功能没有被破坏,所以你还可以这样这样……”

你听的如痴如醉,如沐甘霖。你想起在学校里,如果你对代码不爽,你可以干脆删掉重写。你甚至都不需要一个版本控制工具。你从来没有想过在真正的工程中有这么多复杂的问题以及这么多聪明的前辈们发明了各种系统化的方法。你再一次发现了新大陆。

讨论之后的结论是,你负责监督并提高自动化测试的覆盖率,同时你可以先构造新的模型代码,也可以提交,但是在发布时并不把它们包含进去。当新的代码写好之后先内部测试,确保几乎没有问题了,再策略性的发布出去。

说干就干,你很兴奋。“终于可以写代码了!”你开心的对领导说。领导又笑了,“写代码并不是重点,重点是让它们正确的执行起来。” 你若有所思的点点头,心却早已飞到了你的新设计上。

你打开了看过改过无数遍的最核心的业务代码,心里想象着它们被你改好之后的样子,完美的领域模型、高内聚低耦合的类、优雅的代码、完备的注释、再加上同事们佩服的眼神……你觉得你快要像樱木花道一样笑出声来了。

但是细节之处有乾坤。

你发现你第一行就不知道怎么改。

是日志。

你想了半天,没有想到任何现成的解决方案。你问自己,日志算不算业务逻辑呢?算吧,它又对框架有很多依赖;不算吧,那把它放哪呢?你对着日志的代码看了整整一个下午,仍然毫无头绪。你觉得日志简直是破坏你优雅代码的杀手,你真恨不得把它们给删了……

算了,先不想了。你决定今天给自己放一天假,早早回家看个电影然后睡觉。

刚推开门,哇!外面下雪了。

漫天的雪花翩翩飞舞,一扫平日晚上萧条的景象。昏黄的路灯照射下,雪花反射出暖暖的光。你想起了你在北国的家乡。北方的小伙伴们都说江南的湿冷让人难以忍受,“屋里跟屋外一样冷”。你在此时此刻却有了另外的感悟,你觉得说成”屋外跟屋里一样暖和”也说得通。

也许生活就是这样吧,你想到,并不总是得意,也并不总是失望。你的期待总是狡猾得伪装成另外的样子悄悄的进入到你的生活中,而你的得意又总是在指缝中流走,想握也握不住。但是不管怎么样,你觉得你很快乐,也很幸福。你很庆幸自己成为了程序员。你对现在的自己感觉到骄傲。

意识到你已经在门口发呆了很久,你笑了,笑自己什么时候变的这么多愁善感。你走出门去,踩在雪上,发出咯吱咯吱的声音……

[全文完]

[程序员的故事还没有完]

/** 后记

真的没有想到大家对这篇小文章(我都不知道能不能称为文章)这么喜欢,我本意只是想通过一些真实的细节来描述工作和学校的不同的,谁知道写着写着就成故事了:-D

其实后面还有更多有意思的故事,不过已经扯得太远了,想听的话带上好酒来找我吧!

至于你们所关心的老李,他是真的,但是他并不是扫地僧,他是前端大神,后来他把我们前端的js代码完全重写了一遍,他三十多岁,头发浓密,有一个可爱的小女儿,说话不多,但是喜欢讲内涵段子。

故事经过了加工,亦真亦假,人物也不是完全还原,但是看到你们留言说很真实,我非常开心!

最后,作为一个工科男,我决定总结一下:

  • 工作之后的代码量远没有学校时大作业那么多,但是要更严谨;

  • 但是你要面对很多遗留代码,你要把它们弄懂,不像在学校里你基本都是从头造轮子;

  • 同事们都是八仙过海,各有所长,无论你在学校里是当大腿还是抱大腿,在公司大家都对公司有着这样那样的贡献;

  • 你不可能什么都会,工作才是学习的开始,大学生活只是让你准备好;

  • 除了代码和技术,你还要考虑业务知识、测试、质量、生产效率和可持续性;

  • 机会总是有的,你要做的只是准备好;

  • 学校所学的非常有用,但是理论和实践有着巨大的鸿沟,这全靠你的经验和工程感 (engineering judgment);

我暂时只能想到这么多,更多的就靠大家自己发掘啦。

最后祝喜欢编程的大家都成为架构师!

iOS体会篇 大学编程到公司的过程的更多相关文章

  1. iOS开发网络篇—网络编程基础

    iOS开发网络篇—网络编程基础 一.为什么要学习网络编程 1.简单说明 在移动互联网时代,移动应用的特征有: (1)几乎所有应用都需要用到网络,比如QQ.微博.网易新闻.优酷.百度地图 (2)只有通过 ...

  2. iOS开发之网络编程--4、NSURLSessionDataTask实现文件下载(离线断点续传下载) <进度值显示优化>

    前言:根据前篇<iOS开发之网络编程--2.NSURLSessionDownloadTask文件下载>或者<iOS开发之网络编程--3.NSURLSessionDataTask实现文 ...

  3. iOS开发之网络编程--3、NSURLSessionDataTask实现文件下载(离线断点续传下载)

    前言:使用NSURLSessionDownloadTask满足不这个需要离线断点续传的下载需求,所以这里就需要使用NSURLSessionDataTask的代理方法来处理下载大文件,并且实现离线断点续 ...

  4. iOS开发之网络编程--2、NSURLSessionDownloadTask文件下载

    本文内容大纲: 1.回顾NSURLSessionTask 2.NSURLSessionDownloadTask大文件之block下载 3.NSURLSessionDownloadTask大文件之代理方 ...

  5. iOS开发之网络编程--使用NSURLConnection实现大文件断点续传下载+使用输出流代替文件句柄

    前言:本篇讲解,在前篇iOS开发之网络编程--使用NSURLConnection实现大文件断点续传下载的基础上,使用输出流代替文件句柄实现大文件断点续传.    在实际开发中,输入输出流用的比较少,但 ...

  6. iOS开发之网络编程--使用NSURLConnection实现大文件下载

    主要思路(实现下载数据分段写入缓存中) 1.使用NSURLConnectionDataDelegate以及代理方法.2.在成功获取响应的代理方法中,获得沙盒全路径,并在该路径下创建空文件和文件句柄.3 ...

  7. iOS开发之网络编程--小文件下载

    文件下载方式: 如果下载的文件比较小,下载方式: 直接用NSData的 +(id)dataWithContentsOfURL:(NSURL*)url; 利用NSURLConnection发送一个HTT ...

  8. 使用ReactiveCocoa实现iOS平台响应式编程

    使用ReactiveCocoa实现iOS平台响应式编程 ReactiveCocoa和响应式编程 在说ReactiveCocoa之前,先要介绍一下FRP(Functional Reactive Prog ...

  9. [转]使用ReactiveCocoa实现iOS平台响应式编程

    原文:http://www.itiger.me/?p=38 使用ReactiveCocoa实现iOS平台响应式编程 ReactiveCocoa和响应式编程 在说ReactiveCocoa之前,先要介绍 ...

随机推荐

  1. 字符串的最长回文串:Manacher’s Algorithm

    题目链接:Longest Palindromic Substring 1. 问题描述 Given a string S, find the longest palindromic substring ...

  2. 数组中存放对象之java中定义类数组存放类

    public class ClassArrayDemo { int age; String name; ClassArrayDemo(int age, String name) { this.age ...

  3. Servlet init()

    有时候希望在servlet首次载入时,执行复杂的初始化任务,但并不想每个请求都重复这些任务的时候,用init()方法他在servlet初次创建时被调用,之后处理每个用户的请求时,则不在调用这个方法.因 ...

  4. SQL语句删除字段,改变字段长度

    1.改变字段长度 ALTER TABLE T_MSG_SEND_R_ACC MODIFY reply_content VARCHAR(512); 2.删除字段ALTER TABLE MSG_TX_BA ...

  5. 阿里云服务器Centos 7安装PHP

    网上各种别人写的博客 我自己配置了一下php 开始安装的是压缩包 结果php -version 无显示 然后查找各种资料 请教了很多人 需要的环境一一配置了,但是虽然出现了安装成功,但是还是无法查看版 ...

  6. 216. Combination Sum III(medium, backtrack, 本类问题做的最快的一次)

    Find all possible combinations of k numbers that add up to a number n, given that only numbers from ...

  7. python中修改字符串的几种方法

    在Python中,字符串是不可变类型,即无法直接修改字符串的某一位字符.因此改变一个字符串的元素需要新建一个新的字符串.常见的修改方法有以下4种. 方法1:将字符串转换成列表后修改值,然后用join组 ...

  8. git 学习笔记(常用命令)

    1.新建一个文件,如果没有使用git add 命令将它提交到暂存区,那么这个文件就还没有被跟踪. 2.通过配置.gitignore文件可以指定要忽略的文件,被忽略的文件夹是不会被提交到暂存区的.所以这 ...

  9. Node.js 逐行读取

    逐行读取 稳定性: 2 - 不稳定 使用 require('readline'),可以使用这个模块.逐行读取(Readline)可以逐行读取流(比如process.stdin) 一旦你开启了这个模块, ...

  10. 新版Azure CDN HTTPS加速服务正式上线

    随着网络安全问题日益得到全民重视,HTTPS网络访问协议在互联网访问中得到了广泛的使用.Azure CDN也早在一年前的2015年4月上线了HTTPS加速服务.该加速服务上线一年以来,用户使用量逐渐增 ...