在真实工作中的编程是怎么样的,与学校里有什么不同?
原文为知乎问题《在真实工作中的编程是怎么样的,与学校里有什么不同?》下的回答。
初入公司的迷茫
刚进公司时,在正式动手写代码前,往往需要理解代码库(code base)。这个过程至少会持续1个月,具体时长取决于所在项目的规模。在此期间,你得调动浑身解数,去理解前辈们是如何解决一个个实际问题的。有时你会沾沾自喜,觉得某个技巧自己经常使用,前辈们也算有见识;但大部分时候,你会感到一头雾水。
此阶段,每天的工作就是看文档、看设计图、读代码、设断点调试(debug)、进行临时性修改(hack)、修复问题(fix)以及向同事请教。你会感到身心俱疲,觉得工作无聊透顶。
此外,刚进公司你会发现,项目组使用的一些工具和技术比较冷门、奇葩,与大学时用的成熟集成开发环境(IDE)相比,非常难用。你可能会忍不住抱怨:“谁想出用这个工具的!谁写的这么糟糕的工具!”,心里满是失望。
逐渐融入与成长的波折
随着时间推移,你开始了解业务领域,掌握了一定的领域知识,有能力判断哪些是权衡之举、哪些是权宜之计、哪些是精妙设计、哪些是遗留代码。领导也注意到了你的进步,开始给你安排简单任务,比如修改明显的漏洞(bug)或实现简单的新特性。这时你可能会产生一种掌控全局的错觉,迅速完成功能并提交,还幻想得到表扬。然而,不出所料,提交的100行代码里可能会被找出10个问题,其中2个是严重的逻辑错误、4个是未实现的需求、2个是用户界面(UI)错误、2个是边界条件未检查。你心里不爽,觉得自己的代码很厉害,却不被认可。
这时领导会轻描淡写地说:“我们提交之前要进行代码审查(code review)”。于是你找同事帮忙检视代码,10分钟后,自己漂亮的代码被改得面目全非,你虽欲哭无泪,但又不想得罪前辈,只能默默提交修改后的代码。
经过几个月的挣扎,你逐渐摸清了工作的门道,开始运用大学时期学到的技巧和知识。领导发现后,安排你组织技术交流会。你精心准备PPT,在家排练,还加入一些幽默段子。会议很成功,同事对你刮目相看,你重新找回“驾驭”的感觉,甚至幻想自己未来成为架构师。
随着工作的深入,你提交的代码越来越多,之前没在意的代码规范文档开始给你带来麻烦,但这并非大问题。领导开始强调代码质量,你则抱怨旧代码的设计,想要重构和创新。
紧急任务中的挑战与协作
此时,组里新来了从其他部门调过来的老员工老李,领导组织大家热情欢迎他,你心里虽不服气,但老李人很好,你们相处融洽。
机会很快来了,公司要紧急实现一个演示功能,这关系到百万级合同能否拿下,领导亲自飞往客户处坐镇,走时嘱托你和老李负责组里的工作。你十分激动,买好泡面和零食,准备通宵作战。
领导发来功能要求,你半懂不懂,其中提到的一些其他模块,你只在技术交流大会上听说过,从未调用过它们的应用程序编程接口(API),也没读过相关代码,开始心虚。但你还是决定先行动,找到一些相似功能的旧代码,没时间完全读懂就开始复制粘贴并调试。一个通宵后,总算把熟悉的后台部分调通了,却又遇到前台的麻烦。你虽了解JavaScript(原名为ECMAScript)和JQuery对象与DOM对象的区别,但还是看不懂前台代码。无奈之下,你拉下脸问老李,老李让你去休息,他来帮忙。你心里五味杂陈,既不甘又不好意思,还有些感激。
第二天下午你醒来,老李已完成前台工作并交给一线调试。你打开代码运行,功能已实现。你松了口气,泡了碗泡面,啃代码时却因代码太多而不耐烦,决定查收邮件放松。邮箱里满是新员工培训资料、部门联谊活动通知,最多的是服务器发来的构建报告(build report)和测试报告(test report)。
接下来你不知道该做什么,决定接着写新特性,但心里忐忑不安,既想知道前线情况,又不敢打扰领导。就这样忐忑地过了一天,你回家洗了澡,定好闹铃安心睡觉。
第二天一早到公司,收到领导邮件,得知演示成功,客户满意,进入谈判阶段。你虽高兴,但又有些失落,思考后明白,虽然是好消息,但自己似乎没起到关键作用,没有那种强烈的成就感。
之后开庆功会,饭局上大家聊家常、领导分享国外见闻,大领导表扬了大家,但庆功会平淡结束,你还是有些失落。
工作角色转变与新的挑战
生活回归正常,但与以前不同了。你除了开发工作,还有学习推广新技术等新任务,开始与领导彻夜长谈,分享经验和见闻,接触到提高团队能力、完善自动化测试、提高代码质量和性能、增强功能可配置性等工作。你开始淡定接受新工作,不再幻想一夜成名。
然而,接下来几个月,除了修改自己遗留的bug,你几乎没提交新代码,每天的工作变成看框架、读代码、看技术文档、学习新工具、浏览技术论坛等,你开始觉得缺乏成就感,怀念写代码的日子。
一天晚上,只有你和领导加班,你问领导为什么自己的任务与别人不同,领导说把你当作未来的技术主管培养。你又问技术主管的工作内容,领导没直接回答,只说以后你会知道。
同事的故事与自我认知
和你同一天入职的晓明勤奋开朗,但似乎不太适合开发工作,他总是难以理解代码中的逻辑错误。领导发现后,安排他向配置管理(CM)方向发展。晓明在这个方向表现出色,无论任务多繁琐,他都能按部就班完成,对各种脚本也了如指掌,且有耐心,能解决服务器的各种奇葩问题,大家都很喜欢和信赖他。
有一天,晓明找你请教一个bug问题。你自信地检查代码,却没发现问题,询问现象后查看日志,也没想通。你仔细检查各个环节,还是没找到原因。于是你开始在搜索引擎上寻找相似问题,不断做出假设并否定,最后怀疑是编译器的问题。你通过反编译工具查看服务器上编译过的字节码,发现是兼容性问题。你兴奋地给晓明讲解,他却没听懂,还称你为“大神”。后来你发现很多人都被他称为“大神”,你有些失落,但也习惯了这种落差。你意识到自己并非万能,即使在学校是佼佼者,在工作中也有很多不懂的地方,世界很大,需要不断学习。
阅读书籍与重构的尝试
项目不那么紧张了,你和领导都有了更多时间。领导推荐你看一些设计类的书,如《领域驱动设计》《企业应用架构模式》《修改代码的艺术》等,你想起刚来公司时领导推荐的《重构》《设计模式》,翻开时那种醍醐灌顶的感觉仍记忆犹新。你欣然答应阅读。
阅读过程中,你发现这些书写得很好,但应用到实际代码时却困难重重。书中的问题域和公司的需求、架构不同,很多技巧在公司项目中并不适用。你有些不耐烦,但还是简单翻完了后半部分,觉得自己差不多明白了书中的方法,迫不及待想试试。
你向领导提出重构代码的想法,领导没有惊讶,而是询问你具体的实施方法。你没想过这个问题,回答按领域驱动设计的方法构造充血领域模型。领导进一步询问实施细节,并给你讲解重构代码要保证单元测试全通过,大型重构需要使用高覆盖率的自动化测试,还要确保原有功能不被破坏等知识。你如沐甘霖,再次发现工作中有很多复杂问题,前辈们发明了各种系统化的方法来解决。
讨论后决定,你负责监督并提高自动化测试的覆盖率,同时可以先构造新的模型代码并提交,但发布时不包含这些代码。新代码写好后先内部测试,确保没问题后再策略性发布。
你兴奋地开始重构代码,打开核心业务代码,想象着改好后的完美样子。但一开始就遇到问题,第一行代码就不知道怎么改,是关于日志的。你思考很久,也没想到解决方案,不知道日志算不算业务逻辑,放在哪里合适。对着日志代码看了一下午,依然毫无头绪,你甚至想删掉日志代码。最后你决定给自己放一天假,回家看电影睡觉。
推开门,外面下雪了,漫天雪花飞舞,昏黄的路灯下,雪花反射出温暖的光。你想起家乡,对江南的湿冷有了新的感悟。你觉得生活就是这样,有得意也有失望,期待和得意总是悄然变化,但不管怎样,你庆幸自己成为程序员,对现在的自己感到骄傲。
总结
作为一个工科男,总结如下:
- 工作后的代码量远没有学校时大作业那么多,但要更严谨。
- 要面对很多遗留代码,需要弄懂它们,不像在学校基本都是从头开始编写。
- 同事们各有所长,无论在学校是什么角色,在公司都对公司有不同的贡献。
- 不可能什么都会,工作才是学习的开始,大学生活只是让你做好准备。
- 除了代码和技术,还要考虑业务知识、测试、质量、生产效率和可持续性。
- 机会总是有的,要做好准备。
- 学校所学非常有用,但理论和实践有巨大鸿沟,这需要靠经验和工程判断力(engineering judgment)来弥补。
最后祝喜欢编程的大家都成为架构师!