带老弟做项目,凉了

总结程序员在团队开发中常犯的问题,千万注意!

大家好,我是鱼皮,还记得我的老弟小阿巴么?

之前,我曝光了这个初学前端的孩子第一次写后端代码时出现的囧事:前端老弟第一次写后端,崩了!

这篇文章发出来后,更多人认识了小阿巴,觉得他是个有趣的编程小辣鸡。但小阿巴是一个孤傲有志向的孩子,不想一直在大家面前出笑话。于是,这货不服气,又来找我,想跟着我做新项目。

正好,要开发一个新功能,就拉小阿巴一起吧。而且这次,整个大功能交给他全权负责!

没想到,小阿巴依然很快就完成了开发,兴致冲冲地提交了代码,拉着我来评审。

然而,当我看了他写的代码后,我发现,事情并不简单。

小阿巴真是太牛逼了,一些编程新手在团队开发中常犯的问题,这货一个也没避开,全都踩雷上了。

于是我决定再次曝光他,并且总结了他的问题,希望大家引以为戒。

💣 团队开发雷区

格局小了

小阿巴写的代码中,有很多 “死” 值,比如有好几个地方用到了同一个机器的 IP 地址:

// 文件 1
getConnectByIp("8.8.8.8");

// 文件 2
getLinkByIp("8.8.8.8");

// 文件 3
return {
  ip: "8.8.8.8"
}

我问他为啥这么写,他的回答不出所料:就是图省事儿~

这就跟我们复制粘贴一样,把重复的代码粘贴很多遍,写的时候是挺爽,但万一后面要修改了呢?要一个个地把所有粘贴的代码都改掉?

如果都是一个人写代码还好,自己可能还记得有哪些重复的代码,但如果是一个团队呢?

假如同事 A 写了一段代码,同事 B 和同事 C 都复制了他的代码:

但后来同事 A 发现自己的代码有 Bug!于是就只修改了代码 A,然而代码 B 和代码 C 依旧存在 Bug。

毕竟大家都喜欢复制代码的,尤其是在大团队中,你根本不知道自己的代码究竟被多少人复制了!一个 Bug 永流传啊。

所以无论是从可扩展性还是可维护性的角度,尽量少写 “死” 代码、少写重复的代码,可以将重复的值抽离成独立的变量、常量或配置文件,将重复的代码封装成组件,并编写文档和注释指引他人使用。一般代码重复 3 次,就可以考虑抽象了,别偷懒,要不然以后更惨。

过于自我

小阿巴在实现 “计算指定日期和当前日期相差的天数” 功能时,新引入了一个依赖库叫 Day.js

但事实上,项目已有日期处理库 Moment.js ,完全可以轻松地实现上述功能,没必要再去重复引入一个同类的日期处理库。

我问小阿巴,为啥要再引入新库,他的回答不出所料:俺用的熟!

大家可能觉得给项目引入重复依赖库并没有什么错对吧,但是对于团队项目来说,每个人如果都因为自己的习惯而引入重复库,可能存在很多问题:

  1. 依赖冲突:同事 A 引入 Log4j 日志库,同事 B 引入 Logback 日志库,项目可能就跑不起来了。
  2. 项目加重:每人都引入自己熟悉的库,那整个项目就会像滚雪球一样越滚越大,而且想拆分或去除某一部分,说不定雪球就碎了。

再举个夸张的例子,三位不同技术栈的前端开发一起来做项目,结果出现了三大框架出现在同一项目的三足鼎立局面:

这种项目的维护难度可想而知。

所以在团队中,架构师还是很重要的,最好事先给项目定下规矩:项目都给我用这个框架!日期处理都要用这个库!日志都要用那个库!

这就是技术选型的问题了,要综合考虑业务适应性、团队成员学习成本等。

但无论如何,谨慎给项目引入新依赖,不要一言不合就另辟蹊径!最好先仔细扫一遍项目现在的依赖,如果已经有能满足需求的,那直接用岂不美哉?实在要引入新依赖,也最好跟你的合作伙伴一起商量下,万一出了什么冲突可就不好了~

急不可耐

我看了小阿巴写的功能,惊讶地发现他根本就理解错需求了啊!

我让他拧个螺丝,这货给我造了个汽车?

// 预期
luoSi = ningLuosi();
// 小阿巴
car = buildCar();

连做什么都没搞清楚,就迫不及待直接上手写代码了,这可是大忌,典型的出力不讨好。

在企业中,我们作为开发,经常会和产品经理友好交流,要把需求彻底理解了,才能去设计方案,方案设计好才能去写代码,在整个过程中一定要和需求方反反复复确认清楚!

我打算再给小阿巴一个机会,这次过了好几天他才提交了代码,我一看,这货真的是拧好螺丝了,只不过。。。

项目里已经有扳手给他拧螺丝,结果这货自己造了个扳手?

function ningLuosi() {
    // 预期:一行代码解决  
  useBanShou();
  // 小阿巴,省略 1000 行代码
  const tool = buildBanShou();
  xxxxxxx
}

这也是新手常犯的问题,不看项目文档就上手写代码,结果有现成的轮子、简单的写法不用,非要自己再去造轮子,费事费力。

盲目自信

我感觉小阿巴有一行代码写的有问题,于是就本地运行了一下,果然发现了一个 Bug,页面直接崩溃了!

我把小阿巴叫过来问:你写完代码测试了不?你觉得功能有问题不?

他一脸自信地回答:没测,这功能不就是增删改查,能有啥问题?

于是我给他演示了一遍 Bug,他瞬间羞红了脸,哑口无言。

大家想象中好像经验丰富的程序员写代码更快,但事实上,经验越丰富,他们越会小心谨慎,在写完代码后认认真真地测试,而不是盲目相信经验和直觉。测试也千万不要只是草草地自己点一遍没问题就算了,而是要尽量覆盖所有正常,尤其是 异常 的情况。毕竟用户不听话,你无法想象这些家伙能在你的系统中干出什么事!

小心异常情况

制造屎山

小阿巴的代码非常干净清爽,一个文件千行代码,一样注释都没有,我把他叫过来给我讲讲自己的代码,他竟然都支支吾吾说不出来!

一行注释没有也就罢了,代码还写的歪歪扭扭,不遵循代码规范,如果人人都是小阿巴,巨型屎山指日可待。

public static void main( String[] args) {
 System.out
    .println("i" 
+ "am" 
          + "shuai");
     }

过眼云烟

通读一遍小阿巴的代码,除了上面的问题外,我还发现了很多小的错误。

于是我问他:你写完代码后,自己会再通读几遍呢?

结果这货竟然害羞极了,支支吾吾地说:没。。。没读过。。。

天啊!还有多少朋友和小阿巴一样,自己的代码犹如过眼云烟,写完就再也不看了呢?

自己写过的代码一定要多读几遍,就和考试做卷子一样的,检查一遍能发现很多问题。而且自学编程的时候,又没人逼你交卷对吧,还是要花些时间养成好习惯。

我现在写完代码至少会读三遍:写完一个子功能读一遍、测试前读一遍、提交前读一遍。即便如此,仍然出现过 Bug。

再说了,你自己写过的代码自己都不愿意看,还要别人审查的时候来看你的烂代码,发现问题再给你打回去修改,这不是浪费别人的时间么?久而久之,谁愿意看你的代码?谁愿意和你合作呢?

此外,即使有别人帮你审查代码,但有些问题也很难发现,线上出了问题肯定还是你背大锅。没有人可以拯救你的 Bug,除了你自己。

敷衍了事

最后这点,就是我之前专门写文章提到的大部分同学写代码的现状:仅仅满足于代码可运行、功能可用,而不注重细节、不做优化。

比如小阿巴的这段代码:

for(int i = 0; i < maxNum; i++) {
  doSomething1();
}
for(int i = 0; i < maxNum; i++) {
  doSomething2();
}

实际上是可以将两个同样的循环进行合并的:

for(int i = 0; i < maxNum; i++) {
  doSomething1();
  doSomething2();
}

很多同学一直抱怨自己整天增删改查,项目没竞争力。但实际上,你在做每个项目的过程中,都有很多进步空间。要仔细挖掘,而不是敷衍了事。

关于这点,大家可以看看我的编程习惯:我写代码时的小倔强


怎么样,这些雷你是否也踩过呢?团队开发可千万不能像自己写代码那样随意,希望大家把这些问题熟记于心,做一名优秀的程序员、可靠的队友。

那么问题来了,后面还要不要带小阿巴做项目呢?🐶

最后再送大家 帮助我拿到大厂 offer 的学习资源~

跑了,留下 6T 的资源!

我是如何从零开始自学编程,拿到腾讯、字节等大厂 offer 的,可以看这篇文章,不再迷茫!

我学计算机的四年,共勉!

原创不易,如果觉得文章不错,希望 <stron> 支持下 ❤️</stron>

#Java开发##学习路径#
全部评论
不错
点赞 回复 分享
发布于 2021-06-27 00:21
有些问题我也遇到过,不过工期太短,没办法,只能先跑再说。。
点赞 回复 分享
发布于 2021-06-27 12:39

相关推荐

13号走的内推。18号下午打电话约面,3.19号下午四点开始面试。开局就先做了20分钟的笔试题。笔试题不是算法题,是那种场景题。例如给你一个订单Order类,使用Stream流对其进行处理,取出金额是前100的Order并进行排序,并且按照不同的订单类型拆出来多个List。只要不是算法题就直接拿捏了。之后开始面试⚽1.自我介绍⚽2.实习业务⚽3.你们这个项目的优势是什么,他解决了什么场景下的问题?&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;讲了一下一整个平台的技术演进历史,强调我们一整个平台的技术演进都是为了敏捷开发。这个项目的优势就是实现&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;了快速处理海量需求,避免了传统后端模式的发版测试流程。⚽4.代码热部署的技术选型是怎么做的?为什么不选择Groovy(包太重,6.8M对线上压力大,而且有学习成本)⚽5.为什么要对类加载器手动置空,仅仅依赖JVM的垃圾回收不可以吗?&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;线上脚本多,即使是测试接口也需要进行动态加载,残余下来的类需要被回收掉,降低元空间压力。⚽6.你说你们在测试接口的时候,会置空对应的热部署脚本的类加载器?如何做到的?&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;提供两个接口测试和部署,抽出来热部署的逻辑作为公共方法。在测试接口中进行手动置空类加载器让其回收⚽7.统计接口的调用量的技术是怎么做的?用了本地缓存+redis+MQ,有没有考虑到消息丢失和重复消费的问题?&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;强调业务更加关注数量级,接口调用量每隔一个小时进行调用。丢失一个小时的数据对于整体的接口调用量不构成什么大的影响。考虑风险和收益比没有做这个功能。⚽8.你认为你这段实习中,收获最大的是什么?&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1.技术增长&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2.理解业务,不同的业务有不同的适用技术和解决场景。自己在美团的这四个月会更加考虑一个业务下的解决方案。&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;追求风险和收益比,而不是死磕技术。比如在做接口调用量的时候,我一开始也会考虑幂等和丢失,在写代码上造&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;成了很大的困难,mt指导之后才明白不是所有的问题都需要从技术上解决⚽9.为什么不考研?&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;表明自己有自己的规划,将来要做知识付费和网络教育。考研只是手段而不是目的。我既然有自己的目标,那相比较&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;于考研来讲,尽早的进入一家优秀的公司,在四五年时间来进行快速的成长才是自己想要的。⚽10.频繁的full&nbsp;gc怎么看?&nbsp;&nbsp;&nbsp;&nbsp;拉dump文件在本地分析,强调说dump是堆状态,因此拉dump文件的方式只能查看堆空间的oom,排查不出来&nbsp;&nbsp;&nbsp;元空&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;间的,因为元空间在本地内存。但是元空间很好排查,基本就是加载的类太多了。到这里就直接爽了,面试官说最后在快速的过一下八股,这些应该对我都挺简单的。这话一说我就知道稳了。⚽11.讲一讲线程池的核心参数和对应的执行流程⚽12.在Spring&nbsp;的框架中加一个AOP,他的实现原理是怎么样的?&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;这里引到了Cglib。因为前面有讲到java&nbsp;agent。这里提了一嘴Cglib底层是依赖于asm这种字节码修改框架。而Java&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;agent之所以可以动态的修改线上服务,其实也是因为使用了asm这个字节码修改框架。⚽13.SQL慢了你会考虑从哪些维度排查?&nbsp;&nbsp;&nbsp;&nbsp;索引失效,索引选错,查的数据太多,数据库抖动(脏页正在flush到磁盘),多表join,查询的语句没有索引⚽14.在用mq的时候会考虑什么?数据预估不要把mq打爆。对应的业务场景允不允许消息丢失,允不允许重复消费,重试机制,死信队列,人工告警,配消费者和生产者的时候不要出现跨地域的情况。例如不要出现消息投递到上海的机器之后,北京的消费者进行消费。尽量选择同一地域的。⚽15.在使用redis的时候会考虑什么一致性问题⚽16.除了单例和工厂模式之外,自己还有没有用过其他的设计模式策略模式,简历中有提到⚽17.syn和reentrantlock的底层原理直接秒,和面试官多扯了一会AQS开放性问题:⚽1.平时有没有关注过大模型?知道底层原理吗?双非本科真是跪了,平时哪有接触过这个。和面试官聊了一下自己平时会用windsurf生成demo来学习以及借助windsurf看源码。⚽2.为什么写公众号,创作动力是什么?想做知识付费,大一大二的时候在tg和V2EX上受到过很多帮助,要传递热情。输出倒逼输入。⚽3.原创占比多少?我反问了一下面试官认为什么是原创,面试官说看我CSDN很多都是已经有的内容,问我是不是只是在做归纳总结的工作。向面试官表达自己在最开始的时候是写CSDN,当时刚开始学Java,也没有什么自己的思考,所以就像他说的一样只是在归纳总结。但是随着自己学习的深入和有一段美团实习之后,自己就开始全面转向微信公众号。开始输出一些自己的思考和对中间件源码的解读。举了一下自己写过的京东hotkey探测中间件源码的解读。表达自己认为自己的博客一共有两个阶段,CSDN是归纳总结,后期转向微信公众号开始正式做自己的内容输出。⚽4.对一段实习的要求是什么?有什么想法吗?⚽5.对工作地点在成都有什么什么看法?有了美团实习之后的第一次面试。很爽,自己也开始慢慢的表达自己对于一些观念的看法。和面试官聊的很不错,等待二面ing#牛客AI配图神器##牛客激励计划##蚂蚁##Java#
查看22道真题和解析 牛客激励计划
点赞 评论 收藏
分享
评论
7
6
分享

创作者周榜

更多
牛客网
牛客企业服务