X短期项目总结
刚退出了一个项目,简称为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短期项目总结的更多相关文章
- 项目展示$\beta$
项目 内容 课程:北航-2020-春-软件工程 博客园班级博客 要求 Beta阶段项目展示 我们在这个课程的目标是 提升团队管理及合作能力,开发一项满意的工程项目 这个作业在哪个具体方面帮助我们实现目 ...
- 微信为什么发布 Mac 版?
因为 Mac 就是好啊就是好啊,就是好…… 打完收工,谢谢,鼓掌 piapiapia……晚安! 这么写在京城行走会不会挨板砖呢?头像已经印到书上满世界的发出去了,虽然考虑到行走江湖求一个稳字,我还特意 ...
- GTD工具 Wunderlist使用心得总结
前言: 先后使用过do.it.omnifocus,最后选择了wunderlist,看了他拓展性强.跨平台.免费三大优点.Wunderlist只是一个工具,重要是的GTD的思路.下面的分享是本人的使用案 ...
- Web信息架构——设计大型网站(第3版)(久负盛名经典再现,信息架构设计领域基石之作!)
Web信息架构——设计大型网站(第3版)(久负盛名经典再现,信息架构设计领域基石之作!) [美]]Peter Morville(彼得·莫维尔) Louis Rosenfeld(路易斯·罗森菲尔德) ...
- URL锚点HTML定位技术机制
一.锚点是什么 锚点就等同于火影中的“飞雷神之术”,我们先看百科中锚点的解释: 使用命名锚记可以在文档中设置标记,这些标记通常放在文档的特定主题处或顶部.然后可以创建到这些命名锚记的链接,这些链接可快 ...
- Digital Ocean VS. Linode对比评测
美国攻城师Zach Schneider是linode vps资深用户,他最近却转向了Digital Ocean,原因是什么呢?来看这篇digitalocean linode对比评测的文章: 用了两年的 ...
- Excel、Exchange 和 C# (摘要)
Excel.Exchange 和 C#Eric GunnersonMicrosoft Corporation 2003年4月21日 摘要:Eric Gunnerson 将向您介绍如何使用 Outloo ...
- TypeScript体系调研报告
作者简介:aoto 蚂蚁金服·数据体验技术团队 Q:为什么要写这边文章?这篇文章要表达什么? A:我们考虑在SPA应用中使用TS作为开发语言,我们需要一篇系统性介绍TS本身及周边的文章来论证在项目中使 ...
- 关于2011年meng-meng组产品《豆酱》的Review
这个组是一个做手机应用的组,比较有特色. 经过我们的一致讨论,得出我们组对前辈的有关选题.团队.产品等几个方面的看法,以及我们的感想. 选题的特点: 这个选题对于一个短期项目来说是很合适的,经过较为详 ...
随机推荐
- 从零开始的vue学习笔记(三)
事件处理 v-on 指令监听 DOM 事件,并在触发时运行一些 JavaScript 代码,示例: <div id="example-2"> <!-- `gree ...
- 收藏收藏:工作用了很久的自主开发的Sql Server代码生成器,我开源了(.NET Winform)
大家好,已经一年没见了,我的技术已经有了惊人的进步.于是乎就来为大家分享技术了,今天呢为大家带来的是很早之前开发的老工具分享给大家. 相信大家都使用过代码生成器,用起来顺手的有多少?根据自己的业务配置 ...
- 如何用python查看自己的电脑有几个核
今天在研究多进程的时候,如果想要充分利用多核CPU资源,最起码的一点你应该知道自己的电脑有几个核. 下面是用python3 的 os 模块来查看自己的电脑是几个核的方法. import os prin ...
- mysql5.5下载安装教程
下载地址:https://dev.mysql.com/downloads/mysql/ 这里选择的是5.5的版本: 步骤1: 步骤2: 步骤三: 步骤四: 步骤5: 步骤6: 步骤7: 步骤8: 步骤 ...
- JS---DOM---自定义属性引入和移除
总结:在html标签中添加的自定义属性, 如果想要获取这个属性的值, 需要使用getAttribute("自定义属性的名字")才能获取这个属性的值 html标签中有没有什么自带的属 ...
- HAProxy实现网站高并发集群
简介:HAProxy提供高可用性.负载均衡以及基于TCP和HTTP应用的代理,支持虚拟主机,它是免费.快速并且可靠的一种解决方案.HAProxy特别适用于那些负载特大的web站点,这些站点通常又需要会 ...
- 用python暴力破解压缩文件并不是万能,至少这个场景我告诉你密码你用代码也破解不了
看到论坛上各种贴子写用python进行暴力破解的文章,于是自己也想去尝试一下,不试不知道,一试吓一跳,真的就像那句有名的”python由入门到放弃“,把论坛上别人的脚本全部自己敲一遍,运行不报错,但也 ...
- 误区以为父组件render一次,子组件会重新初始化
初学react的时候我有一个误区,以为父组件render的一次,会将子组件先卸载,再将子组件重新初始化,事实证明不是. 这是对react生命周期函数不太清楚. 父子组件都初始化后,父组件再render ...
- FTP安装及配置
在centos7安装ftp服务 yum install -y vsftpd 启动服务 systemctl start vsftpd 自启动 systemctl enable vsftpd 查看端口 注 ...
- 计算机网络知识之TCP/IP协议簇
OSI参考模型 OSI的来源 OSI(Open System Interconnect),即开放式系统互联. 一般都叫OSI参考模型,是ISO(国际标准化组织)组织在1985年研究的网 ...