Alpha 阶段事后分析
设想和目标
-
我们的软件要解决什么问题?是否定义得很清楚?是否对典型用户和典型场景有清晰的描述?
当前计算机学院的核心专业课程《操作系统》的理论部分和实验部分建设都趋于成熟,实验平台也需要进一步开发完善。实验的参与者主要包含课程教师、助教和选课学生。这三类用户分别需要完成班级、权限管理,实验、教程管理,课下实验和课上考试等功能。
现有的平台对上述功能的实现尚不完善,各方面实现割裂,分散在不同的站点;各方面信息展示功能不佳,自动化程度有待提高;用户体验不佳。与此同时,校内各类课程平台的建设日臻完善,为了适配核心专业的课程定位,我们计划实现一个供教师、助教、学生使用的统一的课程平台。该平台能够一站式满足三类用户的主要需求,提供完善的信息展示机制,自动化程度高,具有良好的用户体验。
我们对平台中涉及到的相关概念(如 Lab、评测、教程等)、用户端、功能以及验收场景有着清晰的定义(见 OSome-平台概念介绍、功能规格说明书)。
在 功能规格说明书 中,我们列出了以教师用户、助教用户和学生用户的典型代表,并给出了实验、考试、班级管理等典型场景。
-
我们达到目标了么(原计划的功能做到了几个? 按照原计划交付时间交付了么? 原计划达到的用户数量达到了么?)
目标已经达到。
原计划共 12 个功能,包括:
- 学生端(6 项):首页通知、评测、进度查看、用户登录、个人信息、建议与反馈
- 教师端(5 项):用户管理、教学信息、公告管理、用户登录、评测记录
- 评测端(1 项):代码评测
以上 12 个功能均已实现。
5 月 7 日,我们邀请操作系统课程的沃天宇老师,进行长达三小时的视频会议。我们向沃老师展示了 OSome 平台的学生平台、教师平台,并听取了沃老师的建议。我们立即对老师反馈的问题进行了修改。最终,于 5 月 9 日晚,向全体操作系统老师和正在上操作系统课程的全体学生发布。
截止至 5 月 12 日 17 时(Alpha 阶段项目展示前夕),已有 241 人完成登录,共 141 名学生完成提交,提交题目 302 次,总共 API 访问次数 13024 次。考虑到发布仅 3 天,且本学期仅有 6 系和 21 系开课,该活跃量已经可以满足预期。
-
和上一个阶段相比,团队软件工程的质量提高了么? 在什么地方有提高,具体提高了多少,如何衡量的?
本项目为 Alpha 阶段,没有上一个阶段。此处仅概述本阶段的质量管理。
-
文档与代码规范:
- 每个仓库具有 readme,作为完整的开发指南,包含以下几方面的信息:
- 本地开发、构建说明
- 部署说明
- 配置说明
- 依赖说明
- 使用以下自动化工具检查代码质量,不通过时 CI/CD 失败:
- ESLint
- Prettier
- API 文档由 swagger 自动生成,省去人工维护的成本。
- 每个仓库具有 readme,作为完整的开发指南,包含以下几方面的信息:
-
可传承性:
- 代码质量
- 项目代码结构性好
- 层次清晰
- 标识符表意清楚,无需注释
- 重要概念有 OSome 平台概念介绍,避免混淆
- 指导质量
- 项目均有 readme.md,指导本地开发、测试流程
- 服务均有 docker-compose.yml 留档,可以使用同样的命令启动所有服务:
docker compose up -d
- 重要机制已形成固化记录(子站反代、Docker Registry 等),帮助使用
- 代码质量
-
单元测试:
完成 24 个重要 API 的单元测试,涉及 68 个测试用例,覆盖率达到 62.6%,共 1874 行代码。
-
DevOps:
-
CI/CD 是敏捷开发的关键:
我们为学生前端、教师前端、后端、评测端、评测环境都配置了 Gitlab CI/CD,从而自动进行回归测试、构建、部署到服务器,极大提高了团队开发效率——除了运维同学外,自动构建、部署的过程对于开发者来说是近乎透明的,开发者只需要知道有一个机制使得开发者每一次 push/merge 都能在服务器上看到效果,而不关心这个机制的具体实现。
-
Docker 容器技术也是敏捷开发与系统运维的关键。容器技术在我们的开发过程中起到了关键作用:
- 我们可以在一个机器上同时运行多个服务且互不冲突。
- 我们利用 Docker 镜像来包装、发布分布式评测机,只需在 V-TEST 上运行 docker-compose 即可自动拉取评测机镜像,扩充评测结点。
-
-
-
用户量, 用户对重要功能的接受程度和我们事先的预想一致么? 我们离目标更近了么?
用户量与预想几乎一致。
用户对重要功能的接收程度好。收到的 21 份使用反馈中,21 份均为有效反馈。所有的 21 份反馈均表示“非常满意”,满意率达到 100%。
用户的满意度反馈表示 Alpha 阶段取得了练好的结果,实现了大部分功能的集成,为 Beta 阶段的进一步开发打下了良好的基础。这也离“我们计划实现一个供教师、助教、学生使用的统一的课程平台。该平台能够一站式满足三类用户的主要需求,提供完善的信息展示机制,自动化程度高,具有良好的用户体验”的目标更进一步。
-
有什么经验教训? 如果历史重来一遍, 我们会做什么改进?
- 设计时要即时和老师沟通,了解用户需求,以免重构
- 开发期间出现了服务器宕机情况,形成处置文档
- 要保护好身体,不要再有人倒下了
- 要即时跟进项目,参与会议,接触技术栈,避免和项目脱节
计划
-
是否有充足的时间来做计划?
是,我们从1月份就开始对需求进行分析。
-
团队在计划阶段是如何解决同事们对于计划的不同意见的?
大家首先阐述自己的意见,之后同学们互相讨论优势劣势,最后由 yzr 同学统一决定。
-
你原计划的工作是否最后都做完了? 如果有没做完的,为什么?
都做完了,因为我们前期规划的好。
-
有没有发现你做了一些事后看来没必要或没多大价值的事?
开非常长时间的会,效率太低。
-
是否每一项任务都有清楚定义和衡量的交付件?
并不是所有任务都有清楚的定义。我们的任务是以 Issue 形式定义和衡量的,在介绍任务时一般比较概括,实现时有时还会对任务进行讨论。
交付件来说我们是通过同行评审的方式,在明确实现某个功能之后才能交付。
-
是否项目的整个过程都按照计划进行,项目出了什么意外?有什么风险是当时没有估计到的,为什么没有估计到?
确实出现了意外,有一位同学因为身体原因一段时间无法工作,我们紧急开了会议,将他的任务分配到了所有其他人手里。确实没有预料到有同学会因为本学期的课程身体不适,课程的带来的压力还是太大了。
-
在计划中有没有留下缓冲区,缓冲区有作用么?
没有留缓冲区。
-
将来的计划会做什么修改?
我们计划在之后设置缓冲区,比如在周日设置缓冲区,这样同学们可以调整自己的时间规划。
对项目未来计划做好风险备案,如果出现问题及时处理。
-
我们学到了什么? 如果历史重来一遍, 我们会做什么改进?
我们学习到如何进行团队开发。
如果再来一遍,我们会做更加详细的规划,对于各种意外情况做好预案,提升开会效率。
资源
-
我们有足够的资源来完成各项任务么?
是的。
-
各项任务所需的时间和其他资源是如何估计的,精度如何?
-
时间:在 Alpha 阶段的设计阶段,我们一起对每个任务进行评估,分析每个任务所需的相关技术、完成时间,以及任务之间彼此的依赖关系。对于需要的技术,我们会事先安排时间学习,并调通样例。这样,之后的开发过程就会比较顺利。在指定完成时间时,要注意被依赖的任务完成时间应当早于依赖的任务。
-
硬件:由于课程网站的特殊性,我们必须使用北航校内的硬件资源,还需要北航校内的域名。因此,我们与操作系统课程老师对接,拿到了所需的资源。
实践证明,我们在时间上的估计是比较准确的。绝大部分任务都是在 DDL 当天或之后一天以内完成的。
-
-
测试的时间,人力和软件/硬件资源是否足够? 对于那些不需要编程的资源 (美工设计/文案)是否低估难度?
我们的测试时间略有不足,单元测试覆盖率仅达到了 70%。人力资源和进件资源都是足够的。
由于我们是面向学生的课程平台,重在实用,因此对美工的要求没有那么高,也没有在上面花什么精力。我们的文案同样是以准确无误为主。难度与平时助教出题、发公告相近,并没有低估。
-
你有没有感到你做的事情可以让别人来做(更有效率)?
- gyp:无。我可以多帮 yzr 写一些 API,这样他就能有更多时间做测试。
- cjy:有。ch 对于前端的技术熟悉程度比我高,我其实对评测机更加熟悉,适合去完成评测机的编码。
- ptw:并不。我在负责范围内有较高的熟练度和一定的经验,交给其他成员来做会增加项目的技术积累成本。
- wwq:没有。我有较多的时间用于软工。
-
有什么经验教训? 如果历史重来一遍, 我们会做什么改进?
有一位同伴在中间生病隔离在了培训中心。在软工的同时要多睡大觉。
变更管理
-
每个相关的员工都及时知道了变更的消息?
是的。
变更消息如果是针对全体的,我们会在群聊或会议中提出;如果是针对部分的,则在对接中即时提出。
-
我们采用了什么办法决定“推迟”和“必须实现”的功能?
在制定需求时确定哪些是必须实现的功能,其他不必须实现的功能根据当前任务完成情况灵活调整。
-
项目的出口条件(Exit Criteria – 什么叫“做好了”)有清晰的定义么?
有,定义如下:
- 功能条件
- 在完成原定的 Alpha 阶段基本课程管理、学生使用、代码评测功能的基础上,按照操作系统课程老师的要求,新增基本的统计任务信息的功能。
- 测试条件
- 编写并通过全部单元测试,尽可能提高测试覆盖率。
- 进行简单的后端压力测试、评测机压力测试。压测情况下系统稳定不崩溃。
- 数据条件
- 创建 2022 春季学期计算机学院操作系统课程,并将该课程全部学生、助教、老师信息导入系统。
- 创建课程所需的题目、评测用例、评测脚本。
- 功能条件
-
对于可能的变更是否能制定应急计划?
能。
我们组保证至少两天开一次会,且成员之间随时保持联系,因此可以即时制定应急计划。
-
员工是否能够有效地处理意料之外的工作请求?
可以。
在 Alpha 阶段实现过程中,OS 老师提出了一些新的工作请求,我们评估工作量,结合需求的紧迫性,将新的工作请求分为:Alpha 完成、Beta 完成、暂不实现三类。
-
我们学到了什么? 如果历史重来一遍, 我们会做什么改进?
我们学到了要即时沟通,如果重来一遍,我们可能会更积极地和 OS 老师沟通。
设计/实现
- 设计工作在什么时候,由谁来完成的?是合适的时间,合适的人么?
- 设计工作按照涉及面大小、项目进度中所处位置安排其完成时间与人员。
- 对于全局性设计,在例会上或者即时聊天群组中提出,绝大多数情况都能得到较好的解决。
- 对于特定服务(前端/后端/评测端)的设计,由负责同学进行,在他们方便的时间进行单独或者结对设计。
- 对于架构性设计,由负责架构的同学设计,并与相关服务负责同学与合适的时间进行核验。
- 设计工作有没有碰到模棱两可的情况,团队是如何解决的?
- 有。
- 对于设计中的重大疑难,我们一般将其讨论范围扩大一级。即:
- 对于特定服务的设计,由所有负责该服务的同学决定,或由全体成员决定;
- 对于架构性设计,在例会上或者即时聊天群组中讨论决定;
- 对于全局性设计,在例会上讨论决定,或与相关需求方讨论决定。
- 团队是否运用单元测试(unit test),测试驱动的开发(TDD)、UML, 或者其他工具来帮助设计和实现?这些工具有效么? 比较项目开始的 UML 文档和现在的状态有什么区别?这些区别如何产生的?是否要更新 UML 文档?
- 团队积极部署现代化设计与验证流程,具体形成措施如下:
- 前端使用 Prettier / ESLint 自动验证代码质量,进行一定的代码测试,其通过作为顺利编译的前置条件。
- 后端对关键 API 进行了单元测试,测试通过作为 CI 通过的必要条件,形成了 TDD 机制。
- 数据模型构建采用由需求到 ER 图再到 SQL 结构的三级设计机制,其中 ER 图帮助我们对于概念进行抽象,并指导我们构建 SQL 层的实际数据模型。
- 现代化设计与验证流程帮助我们快速形成共识,提高开发效率。
- 项目开始时的 ER 图与现在的 ER 图由于一些细节设计的改动存在一定区别,已更新。
- 团队积极部署现代化设计与验证流程,具体形成措施如下:
- 什么功能产生的Bug最多,为什么?在发布之后发现了什么重要的bug? 为什么我们在设计/开发的时候没有想到这些情况?
- 评测端出现的 bug 最多。这是由于其涉及的环境与服务众多,交互逻辑与内部逻辑繁杂,测试成本和难度较高。
- 发布后目前没有发现新的 bug,只有发布前遗留的一个占用文件系统的 bug。
- 由于对于 GitLab API 与 golang 第三方软件包的了解不足。
- 代码复审(Code Review)是如何进行的,是否严格执行了代码规范?
- 修改由成员开启 Merge Request 请求合并开始,需要经过至少一位其他成员的审核后,方可合并进服务分支。这期间代码规范主要由自动化工具维护。人工审核主要聚焦逻辑部分。
- 我们学到了什么? 如果历史重来一遍, 我们会做什么改进?
- 学到了如何进行高效的设计/验证迭代。
- 如果重来一遍,我们会选择更早地形成单元测试机制,更早地进行 GitLab 使用培训,利用好计划阶段的时间,而非等到冲刺阶段还在进行计划的收尾工作。
测试/发布
-
团队是否有一个测试计划?为什么没有?
有。
-
是否进行了正式的验收测试?
是。
-
团队是否有测试工具来帮助测试?很多团队用大量低效率的手动测试,请提出改进计划:至少一个方面的测试要用自动化的测试工具,自动化的测试结果报告,比较测试结果的差异,等等。
有。测试分为白盒测试与黑盒测试:
- 在开发过程中,每一次合并到主分支时,需要其他成员复审代码,尽早发现代码缺陷。
- 在黑盒测试时,编写单元测试,并使用 CI 机制对每一次 push/merge 进行回归测试。
-
团队是如何测量并跟踪软件的效能(Performance)的?压力测试(Stress Test)呢? 从软件实际运行的结果来看,这些测试工作有用么?应该有哪些改进?
- 效能预估:SQL 连表操作原理探究与开销估计、数据库服务预部署测试等
- 效能跟踪:日志机制、前端资源压测、后端 API 压测
- 压力测试:
- 批量发送资源请求、批量发送 API 请求、批量发送评测请求等
- 详见 Alpha 阶段测试报告
- 这些测试帮助我们很好地预估了项目对负载的耐受能力。后续需要重点提升评测性能。
-
在发布的过程中发现了哪些意外问题?
服务器宕机,开发成员生病,开发初期非法数据引发系统出 bug。
-
我们学到了什么?如果重来一遍, 我们会做什么改进?
保重身体,保障开发服务器的数据库数据的正确性。
团队协作
-
团队的每个角色是如何确定的,是不是人尽其才?
如展示文档所述,我们根据技术栈等因素综合考量,将开发人员分组分工,做到人尽其才,并根据健康情况等因素灵活动态调整协作模式与分组分工安排,增强团队组织的鲁棒性。
-
团队成员之间有互相帮助么?
有。
-
当出现项目管理、合作方面的问题时,团队成员如何解决问题?
项目管理、合作方面的问题主要在例会过程中沟通解决。
-
每个成员明确公开地表示对成员帮助的感谢:
- gyp: 我感谢 ptw 对我的帮助,因为某个具体的事情: 帮助我掌握规范的开发流程。
- cjy: 我感谢 ptw 对我的帮助,因为某个具体的事情: 帮助我熟悉前端开发技术与规范。
- yzr: 我感谢 ptw 对我的帮助。ptw 对 dind 机制的熟练帮助我完成了评测机;全栈能力覆盖,发掘后端多处实现问题;运维技术高超,多次拯救了濒临崩溃的服务器。
- fxj: 我感谢 ptw 对我的帮助,因为某个具体的事情: 开发了燃尽图生成工具,方便例会文档编写;在我生病期间接手并分配我原先的工作。
- ch: 我感谢 ptw 对我的帮助,因为某个具体的事情: 修被我搞的乱七八糟的分支图。
- ptw: 我感谢全体成员对我的帮助。大家在团队面临严峻挑战时,对我的工作给予了充分的理解与全力的支持。这减轻了困难时期压在我身上的担子,也使得我们的项目仍旧能够达到 Alpha 阶段的出口条件,为 OS 课程布置理论作业提供了清晰准确的题目资源与稳定的评测平台。
- wwq: 我感谢 ptw 对我的帮助,因为某个具体的事情: 对前端的布局和代码风格提出了很有建设性的建议(比如学生前端 commit 分支树)。
总结
-
你觉得团队目前的状态属于 CMM/CMMI 中的哪个档次?
我们认为我们的团队处于CMMI 二级(管理级)阶段,团队目前有明确的计划和流程,会对每一个负责任务的同学进行培训,每一个 Issue 分配到人,权责到人。我们认为我们有能力完成所有同类项目的实施。
-
你觉得团队目前处于 萌芽/磨合/规范/创造 阶段的哪一个阶段?
创造阶段。
-
你觉得团队在这个里程碑相比前一个里程碑有什么改进?
没有前一个里程碑。
-
软件质量方面:
在前文已经介绍,我们对本阶段的项目开发制定了 文档与代码规范 以保证代码和文档的可传承性,并实现以 Merge Request 功能为核心的 Code Review 机制 ,通过 Review 后方贡献方可生效。。对重要 API 进行 单元测试 ,达到了较高的代码覆盖率。采用 Gitlab CI/CD 和 Docker 进行 持续集成部署 ,简化开发流程。
-
时间管理方面:
以模块化的整体规划为顶层,根据功能模块的技术难度与依赖关系设计。将任务划分为子任务作为中层,见 Alpha 阶段任务划分文档。在各子项目中创建 Issue 作为底层,实现项目进度的动态化管理。使用自动化工具绘制燃尽图,聚合底层数据,作为项目进度管理抓手。
-
分工协作方面:
根据技术栈等因素综合考量,将开发人员分组分工,实现效益最大化,技术积累成本最小化;根据健康情况等因素灵活动态调整协作模式与分组分工安排,增强团队组织的鲁棒性。
-
沟通对接模式:
我们有三种基本的沟通对接模式,用以完成开发阶段的任务分配、灵活解决各种问题。
- 基于功能对接的沟通:
- 前后端同学直接对接
- 应用开发同学与应用部署同学直接对接
- 基于需求对接的沟通:
- 安排 gyp、yzr 负责与需求方对接
- fxj 负责汇总与分析需求
- 基于设计迭代的沟通:
- 微信群直接沟通
- Scrum Meeting 直接沟通
- 基于功能对接的沟通:
-
-
你觉得目前最需要改进的一个方面是什么?
开会时间过长,
且时间阴间,需要注意效率,减少无关讨论。 -
对照敏捷开发的原则, 你觉得你们小组做得最好的是哪几个原则? 请列出具体的事例。
以有进取心的人为项目核心,充分支持相信他们:Alpha 开发中,我们坚持以 ptw 为技术领导核心,充分支持相信 ptw 的技术指导与系统设计,领导我们夺取 Alpha 阶段的伟大胜利。
只有不断关注技术和设计,才能越来越敏捷:Alpha 开发中,我们经常讨论某些代码实现的“优雅程度”,尽力保证项目可维护性。
-
正如我们前面提到的, 软件的质量 = 程序的质量 + 软件工程的质量,那团队在下一阶段应该如何提高软件工程的质量呢?
-
代码管理的质量具体应该如何提高? 代码复审和代码规范的质量应该如何提高?
- 代码管理质量:团队协商好代码规范和要求,对于不符合要求的代码及时指正
- 代码复审:多个人一块进行评审,在评审时给出自己的意见,不要直接合并
- 代码规范:更加细化规范要求,给出优秀范例供团队成员学习
-
整个程序的架构如何具体提高? 如何通过重构等方法提高质量,如何衡量质量的提高?
- 架构的提高:
- 后端的某些 SQL 语句过长,不利于维护,可考虑使用数据库视图来简化操作语句
- 评测端直接轮询数据库,考虑改为轮询后端
- 衡量重构的提高:
- 代码复用率提高
- 架构统一度提高
- 架构的提高:
-
其它软件工具的应用,应该如何提高?
GitLab 协作时可以添加 Label(如 bug、feature 等),便于区分各种 Issue。
-
项目管理有哪些具体的提高?
更合理地分工、更早地做计划、更全面的测试、更及时的对接、更敏捷的流程、更多维的管理。
-
项目跟踪用户数据方面,计划要提高什么地方?例如你们是如何知道每日/周活跃用户等数据的?
希望增加一些统计接口。目前是查 Log 获得。
-
项目文档的质量如何提高?
在文档分工协作方面,需要每个人撰写自己所从事的开发、管理方面工作的文档,其中大部分需要在工作开展的过程中自动形成。
汇总提交时,需要由专人将文档汇总整理,调整格式和部分内容,以更好地符合作业需求。
-
对于人的领导和管理, 有什么具体可以改进的地方? 请看《构建之法》关于PM、绩效考核的章节, 或者 《人件》等参考书
提高 PM 对项目整体的熟悉程度,成为类似“全栈领航员”的角色。
强化 PM 与项目成员的密切沟通,知悉项目难点,明晰时间节点,助推燃尽。
-
对于软件工程的理论,规律有什么心得体会或不同意见? 请看阅读作业。
适当记住用户的选择,以优化用户体验。
我们在 浏览题面 / 提交评测 的切换上记住了用户的选择,若用户进入了浏览题面页面,则下一次仍然进入浏览题面页面;若用户进入了提交评测页面,则下一次仍然进入提交评测页面,取得了不错的反响。
进行探索式测试,发现问题。
在测试评测机的过程中,我们采用了探索测试的方式,测试包括但不限于如下情况:
- 调用关机命令
- 无限 fork
- sleep 或死循环
- 尝试通过 system 调用 python
- 尝试在评测机中联网
我们发现了评测机的若干问题,并通过限制 Docker 可用资源等的方式进行了修正。
前后端分离的开发流程。
在前后端分离的架构下,我们采用初步确定 API,前后端分别实现并逐步对接的方式开发。
由于时间有限,前端没有采用 mockjs,而是先完成与 API 无关或关系较小的界面实现,待后端 API 完成后迅速对接,后端则通过 swagger 在没有前端的情况下开发与测试。
基于 Gitlab 的代码复审。
我们没有通过使用 todo/bug 等标记的方式完成代码复审,而是基于更加现代化的 Gitlab,我们使用 Issue 功能并把待办事项、软件缺陷等以 Issue 的形式管理起来。
践行敏捷开发流程。
现有的做法 敏捷的做法 流程和工具 个人和交流 完备的文档 可用的软件 为合同谈判 与客户交流 执行原定计划 响应变化 如上表所示,我们践行敏捷开发流程,尽早并持续地交付有价值的软件以满足需求。
-
发布博客时,要附上全组讨论的照片。