刚退出了一个项目,简称为X项目。这个项目中,还是遇到了不少问题,也解决了部分问题,还是挺有收获的,所以总结一下。

虽然标题说是短期项目总结,但其实这个项目并不短, 持续了约3年时间。 所谓的短,只是我呆在这个项目的时间短。我是在项目跑了2年多之后,在还有大半年就要结束的时间点进去的。而因为我进去大概4个多月后项目就进入维护期,我也就离开了项目,

我进去的目的有以下几个:

1. 简单帮助一下开发和bug维护(这不是主要的,因为在我加入时项目进度已经可控,加入后应该算是一个普通的开发输出)。

2. 了解项目中出现过的以及现在仍存在问题,分析并给予建议(项目历史上发生过不少问题,过去质量和客户满意度都比较低)。

3. 接触并了解团队成员,必要时给予正向激励。

4. 对我个人来说, 也可以学到一些自己原本不具备的软技能

闲话少说, 下面列一下这个项目中遇到的,而且很可能在其他项目中也会出现的问题,以及一些个人想法:

1. 部分文档过时陈旧不准确, 没人维护, 也没什么人看

2. Code review流程形同虚设,reviewer直接点merge,或者提的comment被无视。有些merge request(简称MR)没有添加恰当的reviewer(如维护别人写的功能时,一般应添加功能的作者)

3. 复制粘贴现象严重,而且部分开发对自己粘贴来的代码不负责。

4. 代码风格不统一,而且团队貌似没意识到代码风格的重要性。

5. 任务优先级变化频繁,需要leader每天重新安排任务,同一个任务可能一天内改几次被分配人。 对开发来说, 每天要做的任务可能变更3-4次。

6. 如果开发发现了bug, 没有统一确定的处理流程,经常是私底下沟通,要么发现人修复,要么原作者修复。

7. 项目有多个需要维护的大分支,因为项目架构的原因,切换分支后需要一系列的脚本/命令/调整配置(有时),而且还经常性会把环境搞坏,需要整个环境重新部署一遍。 成本巨大。 在开发熟悉业务和代码后,切换大分支成为耗时最多的活动。

8. 由于项目所用技术比较陈旧, 部分开发人员渴望学习,但是不知道可以学什么(缺乏指导和建议),这种渴望和现状的矛盾导致开发人员有时会表现出沮丧和不自信。

好了,问题罗列完了,下面一个个分析问题和列出我能想到的解决办法(如果有的话),而这些问题可以合并成几个主题。

- 文档问题

其实这个问题,说容易也容易,说难也难。这是一个循环问题,良性循环或者恶性循环。

所谓良性循环,就是团队发现有什么信息需要重复传达或使用时,就将这些信息记录成文档,并告知团队。 此外,每次发现信息需要更新时,都积极更新文档。每次有什么疑问先去文档中查找。自助式解决问题。

恶性循环则相反, 要么不将重复使用的信息形成文档,要么发现信息更新或文档过时却不更新文档。 不更新文档则文档内容陈旧不准确,就更没有人看文档了,如此循环下去,文档最终会因为过时和不准确变得无效,文档形同虚设,团队也失去了看文档的意识和习惯。

简单的是, 每个文档都不要求完美, 只是在信息可重用时创建,有一个众所周知(团队内)的文档入口, 尽可能多的人有写和更新文档的自觉。

难的是,积重难返,如果长期不更新, 很多文档完全过时,需要重写。 且如果文档包含标准类的东西,项目中期重新推广会比初期就坚持执行难度大得多,因为大家已经形成不同的习惯。

想解决文档问题,预防胜于治疗。预防则是从项目前期开始,让更多人参与进文档创建和更新, 且都需要遵守。如果到了项目中后期,要改就跟要做手术差不多了, 要大家放下手头的工作去改文档,需要更大的决心和执行力,而且对进度会有影响,如果改了之后执行情况依然如故,那过段时间文档又会变得过时无效,这段改文档的时间也就被部分浪费了。

- 代码质量

无论code review、代码风格还是复制粘贴,这些问题都指向一个目标,就是代码质量。 代码质量好坏也直接影响项目质量。

代码质量不好不是一朝一夕导致的,也不是一个人的责任。要解决这个问题,需要整个团队一起花费一定的时间。

根据项目当时情况,由于项目后续时间并不多,加上个人经验和知识有限,我的目标只是想代码质量往较正确的方向发展,能改进多少算多少。

最终我做的事情包括下面这些:

1. 制定代码规范并让团队认可接受。引入eslint,并将eslint添加到CI流程,辅助代码规范的执行

2. 制定code review标准。并在日常code review中将想法传播给团队,磨合出一个大家认可的code review标准。

3. 实现一个基类和一个node脚本,自动化实现新模块时的人工操作,隐藏部分重复逻辑,且标准化一些常见功能的实现方法。这样降低大家理解代码的难度,当发现有较好的实现方法时,也可以推广给整个团队。

4. 发现部分希望学习、提高或改变的同事,尽量分享经验和正向激励他们。项目所用框架陈旧,与他们一起发现框架以外的可以学习的东西。如代码可读性、扩展性,如何设计组件,可用的设计模式,如何优化开发流程等等。

5. 最后一点不是我做了的事情,而是我没有做的事情,就是将问题归咎于具体某人。首先这不是某一个人的问题,而是整个项目的问题。如果责怪某人,被责怪的人会有情绪反弹,将不会配合后续的改变建议,这只会增加开展工作的困难。

经过这个过程,深刻体会到一个道理,当我们想别人往某个目标改变时,不要只告诉目标,也告知到达目标的方法,最终更有希望达到我们期望的目标。因为有时别人不是不愿意改变,而只是不知道怎么做,在不知道怎么做的情况下,很多人就会放弃改变,而这时一位责备催促没有太大意义。

再者,这是一个持续了挺久的项目,项目中各人都已经养成自己的各种习惯,这时不适合大刀阔斧或者强势要求别人改变,这只会引发冲突和对抗,不利于事情推进。更好的方式首先要理解团队,然后让团队在尽量痛苦小的情况下缓缓的改变,并给与改变的具体方法。

- 任务分配策略

上面任务分配的问题这里就不重复了,直接说可能导致的问题:

1. 每天更新任务优先级且需要当天分配任务,这会导致开发的自发性被遏制。如这一天完成分配的任务后,开发无法自行领取更多的任务。 因为每天的优先级变化导致没人知道今天这个bug明天是否还需要改。如果不需要,花在上面的时间就是浪费。

2. 同一给bug频繁更改指定人。 我们都知道,拿到bug之后不是马上就能改代码的。要先研究。研究包括切换分支,重现,阅读代码,想方案。 这一个过程往往不比改写代码和改完测试的时间短。如果一个bug分配给一个开发后,过一段时间又安排给别人,那么前一个人虽然没把bug改好,但是其花在研究阶段的时间几乎都被浪费了。如果这种情况是常态,那么团队的低效基本是可以预见的。

3. 一个功能的bug分配给对该功能陌生的开发处理。 这个做法不敢一棒打死,有多种情况。

  a. 当没有进度压力时,这么做也是一种知识分享,可以降低项目将来维护的风险。

  b. 如果是核心开发人员,可能完成的功能较多,如各种公用方法和组件,此时若这些东西的bug都分配给他,一来并不公平,二来造成贡献越多,工作越多,可能打击团队实现公用方法和组件的积极性。

  c. 当有进度压力时,如果功能足够复杂,接到陌生功能的bug的开发需要花费大量的时间了解需求、功能如何使用、代码如何实现等等。 这也一定程度上导致效率不高。

至于解决,也不是单任务分配人可以解决的,这往往有客户、进度的压力。 下面说一下我个人看法:

1. 尽量让任务的优先级的有效时间长一点。 这面对客户的同事有较好的谈判技巧。好处是,当开发完成当天分配的任务后,有机会自行领取更多熟悉的或适合自己的任务,提高团队效率和积极性。

2. 非必要不要短时间内变更任务分配人,避免浪费开发人员花在研究、准备、尝试上的时间。因为代码最终提交前可以做很多事情。这也依赖于下一点,不要太随意的安排任务。

3. 若一个bug或任务,是基于公用功能,建议按一般的任务处理,即根据各开发的工作量,尽量均衡的分配下去,简单说就是谁任务较少谁处理。 如果非公用功能,只具体页面或功能模块,建议让熟悉该功能的开发处理。

 - 开发分支切换问题

这个点本来我以为是比较特殊的,不太具有普遍性,不过细想之后,觉得从这个问题还是可以得到一些通用的启发,所以还是继续聊一下。

这个问题其实也可以叫做开发环境问题。咱这个项目有几个大分支,每次切换大分支后,需要重新部署、设置、执行一大堆东西,而且即使执行完可能还是会部署失败,如果部署失败就需要重新安装环境并设置、执行另一大堆东西。如果某个开发切换大分支后出现问题,为了排除这个问题并进行正常开发,往往需要花费几个小时,一个上午或下午可能就这么过去了。

我经过一段时间折腾,想出了一个方法,就是为每个大分支准备一个单独的开发环境,单独配置, 即某个环境只能基于某个大分支,要在另一个大分支做任务就直接开启另一个开发环境。这个做法很笨,却有效,帮我节省了非常多时间。

虽然我当时问题是解决了,但是折射出另一个问题。我先定义一个词: “开发准备”, 这个词我想用来表达一个状态,在该状态下,我开发所需的代码、运行时环境、变量、数据都已就绪,可以进行开发任务。而这个项目如果要切换大分支,想要达到开发准备的状态,成本是不固定的,运气好的时候几分钟,运气不好几小时。我想说的问题就是, 对于项目的新成员,或者老成员要切换任务工作,达到开发准备的成本应该尽可能低,因为这个成本会贯穿项目始终并且被重复无数次。值得花费很大的代价来降低这个成本。 而我们这个项目有其特殊性,但是这个成本是不是真的无法再降低呢? 我认为答案是否定的。我们可以将更多的脚本、配置、命令集成到唯一的一个编译或部署命令中,让更多的人工操作可以自动完成。这可以减少很多因人工操作导致的问题,也减少人的精力消耗和被打断的次数。

在这个项目我不知道具体要怎么做。不过在以后的项目中,我的目标是,一键达到开发准备。即切换分支后,达到开发准备的人工成本是0或者只需要执行一次脚本或命令。 我相信这能极大提高开发效率。

----------------

很久没写博客,写的不好而且拖拖拉拉在好多天内写完的。就当作给自己做的记录自己慢慢看吧。

也谢谢其他人的观看和指正。

2019.11.09

X短期项目总结的更多相关文章

  1. 项目展示$\beta$

    项目 内容 课程:北航-2020-春-软件工程 博客园班级博客 要求 Beta阶段项目展示 我们在这个课程的目标是 提升团队管理及合作能力,开发一项满意的工程项目 这个作业在哪个具体方面帮助我们实现目 ...

  2. 微信为什么发布 Mac 版?

    因为 Mac 就是好啊就是好啊,就是好…… 打完收工,谢谢,鼓掌 piapiapia……晚安! 这么写在京城行走会不会挨板砖呢?头像已经印到书上满世界的发出去了,虽然考虑到行走江湖求一个稳字,我还特意 ...

  3. GTD工具 Wunderlist使用心得总结

    前言: 先后使用过do.it.omnifocus,最后选择了wunderlist,看了他拓展性强.跨平台.免费三大优点.Wunderlist只是一个工具,重要是的GTD的思路.下面的分享是本人的使用案 ...

  4. Web信息架构——设计大型网站(第3版)(久负盛名经典再现,信息架构设计领域基石之作!)

    Web信息架构——设计大型网站(第3版)(久负盛名经典再现,信息架构设计领域基石之作!) [美]]Peter Morville(彼得·莫维尔)  Louis Rosenfeld(路易斯·罗森菲尔德) ...

  5. URL锚点HTML定位技术机制

    一.锚点是什么 锚点就等同于火影中的“飞雷神之术”,我们先看百科中锚点的解释: 使用命名锚记可以在文档中设置标记,这些标记通常放在文档的特定主题处或顶部.然后可以创建到这些命名锚记的链接,这些链接可快 ...

  6. Digital Ocean VS. Linode对比评测

    美国攻城师Zach Schneider是linode vps资深用户,他最近却转向了Digital Ocean,原因是什么呢?来看这篇digitalocean linode对比评测的文章: 用了两年的 ...

  7. Excel、Exchange 和 C# (摘要)

    Excel.Exchange 和 C#Eric GunnersonMicrosoft Corporation 2003年4月21日 摘要:Eric Gunnerson 将向您介绍如何使用 Outloo ...

  8. TypeScript体系调研报告

    作者简介:aoto 蚂蚁金服·数据体验技术团队 Q:为什么要写这边文章?这篇文章要表达什么? A:我们考虑在SPA应用中使用TS作为开发语言,我们需要一篇系统性介绍TS本身及周边的文章来论证在项目中使 ...

  9. 关于2011年meng-meng组产品《豆酱》的Review

    这个组是一个做手机应用的组,比较有特色. 经过我们的一致讨论,得出我们组对前辈的有关选题.团队.产品等几个方面的看法,以及我们的感想. 选题的特点: 这个选题对于一个短期项目来说是很合适的,经过较为详 ...

随机推荐

  1. 编译Netty源码遇到的一些问题-缺少io.netty.util.collection包

    缺少包和java类 下载好Netty的源码后,导入到IDE,运行自带的example时编译不通过. 如下图,是因为io.netty.util.collection的包没有 点进去看,确实没有这个包 发 ...

  2. weed3-2.1.开始纯java使用

    Weed3 一个微型ORM框架(只有0.1Mb哦) 源码:https://github.com/noear/weed3 源码:https://gitee.com/noear/weed3 纯java使用 ...

  3. Oracle - exp实战

    一.概述 exp/imp是oracle中的一个逻辑导出和导入工具,假想一个场景,当我们使用exp命令在对用户进行导出的时候,如果该用户中的某些表的数据有修改,或表结构进行了修改,或者表被删除,那么我们 ...

  4. react中报错Failed to set an indexed property on 'CSSStyleDeclaration': Index property setter is not supported

    产生这个报错的原因是我当时将样式写到了less文件,我在div中使用的使用应该是使用className = ,而我误写了一个style = .style里面当然没有自定义的className,所以产生 ...

  5. Pick of the Week'19 | Nebula 第 45 周看点--Nebula 到底是不是原生存储?

    每周五 Nebula 为你播报每周看点,每周看点由本周大事件.用户问答.Nebula 产品动态和推荐阅读构成. 今天是 2019 年第 45 个工作周的周五,来和 Nebula 看看本周有什么图数据库 ...

  6. RabbitMQ 在.Net 中的使用

    RabbitMQHelper public static class RabbitMQHelper { // 定义 RabbitMQ 基本参数 private static string HostNa ...

  7. 简洁优雅的Python教你如何在工作中“偷懒”

    前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 作者: A字头 PS:如有需要Python学习资料的小伙伴可以加点击下方链 ...

  8. pyhton的安装,环境变量的设置,pycharm的安装下载,中文汉化和字体的设置

    1.下载pycharm https://www.7down.com/soft/336988.html 1.pycharm的汉化下载汉化包:resources_cn.jar    放到pycharm的安 ...

  9. 龙芯(mips64)电脑安装NodeJS

    背景 龙芯是国产的cpu,采用是mips架构,就类似大家熟知的x86.arm. 最近在一台龙芯电脑(系统是中兴新支点,Linux)上调试前端应用(electron),于是就需要安装NodeJS. 但是 ...

  10. ORA-27468: ""."" is locked by another process

    You have a scheduler job that generated an error. When the error occurred, you attempted to disable ...