入职后发现项目组代码异常混乱,是去是留?

如题,应届生刚毕业入职还在试用期。拿到代码后发现不仅混乱而且没有任何文档,公司技术靠心口相传。工程维护的人太多了几乎都是在“和稀泥”,代码可读性真心非常差。带我的人直接甩来源码没有任何讲解,让限期实现功能,感觉学不到东西毫无发展。现在想想这offer除了京户也没什么吸引力了。 我一直在反思是不是自己的问题,是我太矫情了么?是不是其他公司也是这种情况?还是我应该换一个技术实力更好的公司,可以从优质的代码…
关注者
1959
被浏览
256583

158 个回答

假设你在改进它

一般来说你看到的那种旧代码都是原始积累阶段的粗暴堆积出来的,以及中间根据各种需求不断打补丁出来的。

你需要做的第一件事应该是完整的理解原代码的所有语义。也就是先读懂你看现在看上去很乱的代码是在做什么。你要理解,那份代码是到目前为止“良好运行”的一个版本,即使是没有注释、没有文档、没有好的设计和代码风格。你要做的就是完整理解原代码在干什么,模块和模块之间的关系、哪些是过度耦合的、哪些可能是中间打补丁打出来的,哪些是隐式约定的(所谓当前代码里的潜规则)...。能搞明白是干什么的,现在的代码是如何分层、模块之间是如何依赖的...。

好了,你现在有两个选择:
1. 在原来的代码上先把你的Leader交代的任务在原来的代码里找到合适的位置插入,完成打补丁的任务,当然要尽量保证你新加的代码风格良好、符合编码规范、不引入新BUG、保证它再次“良好运行”。然后了事。
2. 此时,如果你有时间,你可以跟你的Leader说你想改进这份代码,争取到他的同意后给你时间去做。如果他支持你,那么,下一步。

这个时候你可以做的刚好是学以致用,比如说学过《重构-改善既有代码的设计》、《编写可读代码的艺术》、《编程格调》之类的,或者你看过Google的各种编码规范,比如Google C++ 编码规范。那么此时应该是可以用得上的。但是首先你要找你的leader确认下本队是否有内部的编码规范,一般来说会有一份,即使没人执行。这一步,你可能需要得到明确的编码规范版本,否则的话你可能会产生另一个让后面的人觉的代码很乱的新版本。而且毕竟你对于他们来说是新手,也不能确认你改的就是更好的,你是否对风格和规范有偏见和非我发明症等等。

接着,你可以根据你的理解,从最简单的外围代码开始逐步改进。最简单的,从整理注释开始,把那些写的不那么好的注释重新写清楚,注释风格做到统一。接着也许是代码排版的重构,也是先考虑一致性。然后可能是函数的命名、成员的命名、函数的访问限制等等等。如果你学过那些如何改进代码的各种技巧,并且自己有过一定的经验,你可以小步迭代改进...,每一步你都要保证修改后的代码逻辑上是和旧的一致的,但是排版更一致、命名更一致、风格更良好、语义更清晰。记住,重构不要引入任何新功能,它是一个小步迭代的过程,先把东西写的更简洁、清晰、才是最重要的。这个过程也不是你秀语言技能的地方,你需要的是用尽量少的东西,但把代码写的更一致、清晰、易读等。那些书里都有讲。

这样的过程并不轻松,但能学到很多东西。
好多忽悠楼主重写的,让我想起十年前年轻的自己。
这里说点不同意见:
从公司利益角度来说,如果系统已经发布给客户(上线),不要重写。
从个人利益角度来说,可以私下尝试重写来提升自己的能力,但不要试图用来替换已经上线的版本。

理由:
一个刚进公司的新人,对整个系统的了解可以说浅薄之极,你看到的东西、能理解的东西,只是冰山露出水面的那一小角,只是巨大的地下皇陵表面的一层浮土。你只看到了代码混乱这一个问题,但忽视了系统已经解决了的几百几千个其它问题,而一个系统的真正价值却来源于它解决的问题,也就是说,新手容易关注缺点而忽略价值。
这种情况下让新手来重写,可想而知结局一定是灾难性的。事实上就算让精通熟悉这个系统的老手来重写,结果也很可能是灾难性的,因为人的大脑容量有限,今天改动的代码几周之后可能就完全忘光了,更不要说去回忆几年前写过的代码。当时为什么这么写,为了优化做了哪些权衡,这些记忆早都已经烟消云散,重写的时候还要再重新面对一次同样的困难,而这次的解决方案还真就未必比之前的更好。

废话说了这么多,来个国外的老程序员Joel Spolsky在2000年写的文章:
Things You Should Never Do, Part I
(15年前就已经有大牛总结过经验了,可见多读书有多么重要)
他的论点来源于一个简单的事实:
It’s harder to read code than to write it.
写代码容易,读代码难。
年轻的程序员似乎还认识不到这一点,但任何一个老程序员都会非常的认同这句话。

还有一个更详尽的带图表的分析:
vibratingmelon.com/2011
这篇文章的观点主要是:
1. 重写的代码即便能完全达到旧代码的所有功能、性能需求,为产品带来的竞争力也只有边际提升。(这个很好理解,因为代码的规范性和清晰度对产品的功能性没有直接帮助,只能降低远期的维护成本)
2. 由于重写代码过程中需要花费额外的钱和时间,可能会出现一些意外状况,比如预算不够了,核心程序员离职了,或是重写的产品没有达到原有产品的所有功能和性能需求,那么这个结果可能是灾难性的,重写的产品要么胎死腹中,要么市场竞争力反而更低了。(我马上想到一个例子,迅雷客户端,中间重写多少次都是越写越烂,最后大家都还在用原始的精简版)

当然以上并不是说我们写代码就不用管架构,随便敷衍了事一下算了。这显然也是不对的,具体情况具体分析,需要先看一下我们在公司写代码的目的和目标是什么。
有理想的人往大了说写代码是为了更好的服务人类,但不考虑开源和兴趣爱好之类的话,像我这样喜欢钱的小人往实际了说,写代码的本质目的是为了给公司和自己盈利,所以一切能够提高产出投入比的措施都是可取的,一切降低了产出投入比的措施都是不可取的。
在开发的早期环节,好好设计一下架构显然能够降低未来维护的隐性成本,所以好好设计架构是可取的。
在项目已经上线之后,重写代码在最坏情况下可能导致项目失败,最好情况下也只能获得边际效益提升,却同时要花费高额成本,所以重新设计架构重写代码是不可取的。
嗯你问如果公司的项目或产品代码混乱到无法再加入新功能或提升性能,跟时代严重脱节怎么办,那么应用以上原则,这时候既然这个项目已经快死了,那么放到新项目里重写显然是最合理的选择。