[I.3] 个人作业:结课总结

[I.3] 个人作业:结课总结

项目 内容
这个作业属于哪个课程 2026 年春季软件工程
这个作业的要求在哪里 [I.3] 个人作业:结课总结
我在这个课程的目标是 理解并实践软件工程的完整过程,在个人、结对和团队项目中提高需求分析、设计实现、测试发布与团队协作能力。
这个作业在哪个具体方面帮助我实现目标 回顾学期初提出的问题,用一个学期的实践重新回答它们,并总结自己在软件生命周期各阶段形成的认识。

一、学期初问题回顾

学期初的阅读和提问博客:个人作业:阅读和提问

当时我提出了五个问题。现在回头看,这些问题并没有都得到一个简单的“是”或“否”,但我对它们的理解已经从基于直觉的猜测,变成了基于实际项目经历的判断。

1. AI 复审能不能替代同伴复审?

我现在的结论是:AI 可以替代一部分机械性的复审工作,但不能完整替代同伴复审;同时,同伴复审本身也不能替代自动化测试。

学期初,我认为 AI 很适合做第一轮检查,因为它速度快,也能发现命名、重复代码、常见边界条件和局部逻辑问题。这个判断现在仍然成立。在结对项目的第三阶段中,我们也使用了 AI 辅助完成部分工具函数、修复问题并优化策略。它对于明确、局部、容易验证的任务确实有效。

但是,实践让我发现,代码复审并不只是“找错”。在结对项目中,搭档提出了极小化极大算法的思路,也在实现过程中给出了更符合当前题目约束的处理方法。这类建议依赖双方共享的题目上下文、已有设计和实现成本,不能简单等同于 AI 的静态检查。到了团队项目中,复审还要判断一项修改是否符合模块边界、是否会破坏其他成员的工作、是否补充了必要测试、是否能够由责任人解释和维护。这些都涉及团队约定和责任归属。

同时,结对项目也让我认识到,不能把“有同伴复审”当作质量保证。在第二阶段中,我和搭档都曾通过阅读代码而遗漏一个计分逻辑错误,最后是新增测试暴露了问题。因此,更可靠的流程应当是:

自我检查 → AI 或静态工具检查 → 自动化测试 → 同伴复审。

这四层检查解决的问题并不相同。AI 适合扩大检查范围,测试负责给出行为证据,同伴复审负责处理上下文、设计取舍和责任确认。

这个问题仍有尚未完全解决的部分:随着模型能力持续提高,低风险代码中 AI 与人工复审的边界还会变化。我目前只能确定,高风险模块、架构变更和难以自动验证的业务规则,不能仅依赖 AI 给出结论。

2. 在 AI 辅助编程普及后,结对编程还有多大意义?

我现在认为,结对编程仍然有价值,但应该选择性使用,而不是把所有任务都强制变成两人同时工作。

在结对项目的前两个阶段中,朱城宇担任驾驶员,我担任领航员。领航员不需要把主要注意力放在输入语法和修正小错误上,因此更容易观察规则分支、整体结构和潜在遗漏。第三阶段交换角色后,我担任驾驶员,搭档提出了策略算法和实现建议,使最终方案明显优于我单独完成时的初始想法。

这说明人的结对价值并不只是“陪伴”或“提供情绪支持”,而在于:

  1. 两个人可以在编码过程中即时建立和校准同一个问题模型;
  2. 驾驶员关注当前实现,领航员能够保留更多注意力观察全局;
  3. 设计分歧可以立即讨论,不必等到代码完成后再返工;
  4. 隐性的思考过程会在交流中被表达出来,从而实现知识传递。

不过,结对编程也确实会增加即时人力成本。对于边界清楚、低风险、可独立验证的重复性工作,AI 辅助加异步复审往往更经济;对于规则明确但逻辑复杂、需要共同理解的新模块,结对编程更容易降低返工风险;对于高度探索性的任务,两个人同时试错有时反而不如先分别探索、再集中讨论。

因此,我对这个问题的回答从“AI 是否能够替代结对”变成了“什么风险等级和任务类型值得结对”。结对编程不是默认仪式,而是一种应按风险选择的工程手段。

结对项目博客:结对项目:花见小路

3. 小项目也要严格执行完整的个人软件过程吗?

我现在的结论是:小项目不一定需要完整、严格地执行每个 PSP 步骤,但仍然需要保留最有价值的测量和反馈环节。

在结对项目中,我们记录了估计时间和实际时间。三个阶段中,我的估计分别为 175、130、220 分钟,实际分别为 120、95、190 分钟。虽然估计并不准确,但这些数据让我看到了自己容易高估哪些环节,也让我注意到测试、复审和修改所占的时间并不是可以忽略的附属成本。

如果完全不记录过程,开发结束后往往只能得到“这次好像比预期快”或“这次改了很久”这样的模糊印象。PSP 的价值不一定在于表格本身,而在于让个人能够基于数据修正下一次决策。

但如果给一个十几分钟即可完成、影响范围很小的修改也套用完整流程,过程成本可能超过收益。因此,我更认同一种“最小可用 PSP”:至少记录任务估计、实际耗时、主要缺陷、测试结果和一次简短复盘;对于陌生技术、核心算法、反复出现问题的模块,再增加更细的设计和缺陷统计。

也就是说,流程的严格程度应该与任务风险、陌生程度和未来复用价值相匹配,而不是只按项目规模机械决定。

4. 小团队什么时候应该正式分工?

我原来倾向于用团队人数来判断是否需要正式分工。团队项目结束后,我认为更合理的判断标准是:当协作成本、模块耦合或责任不清开始造成重复劳动和遗漏时,就应该建立正式的责任边界。

Z-Spire 团队共有六人。项目早期通过技术负责人、前端、后端、策划、美术和项目经理等角色完成初步分工,并使用 WBS、Issue 和任务分配明确每项工作的责任人。这使战斗、地图、卡牌、素材、文档和发布工作能够并行推进。如果没有责任人,一项跨模块问题很容易变成“大家都以为别人会处理”。

但正式分工不等于固定分工。我最初主要承担技术负责人相关工作,后续也参与了战斗界面、关卡推进、动画音效、缺陷修复和测试补充。其他成员同样会根据项目需要跨角色支援。实践中更有效的方式是:

每个模块有一个明确的最终责任人,但任何成员都可以支援;角色用于减少责任模糊,而不是建立岗位壁垒。

我认为出现以下情况时,小团队就应该正式分工:任务已经能并行展开;模块之间存在稳定接口;同类问题反复无人处理;交付时间要求不同成员同时推进;关键模块出现故障却找不到最终负责人。

5. 成熟的软件工程模型是不是只适合大团队?

我的回答是:成熟模型中的原则适用于小团队,但完整仪式未必适用。小团队应该提取高收益机制,而不是照搬大型组织的全部流程。

在团队项目中,我们没有建立复杂的层级审批,但保留了 Issue、分支、Pull Request、测试、构建、发布检查和文档同步等机制。Alpha 阶段优先保证核心流程能够跑通,Beta 阶段再补充自动化回归、场景测试、兼容性检查和发布出口条件。临近期末时,团队也会根据成员时间减少不必要会议,以更灵活的方式协调工作。

这些经历说明,软件工程模型真正有价值的部分是:让需求可验证、让变更可追踪、让质量有证据、让责任可定位。小团队不需要为了“过程完整”增加多层审批和大量会议,但也不能因为人数少就只靠口头约定和个人记忆。

我现在更认同“最小充分过程”:只保留能够显著降低当前项目风险的机制,并在风险变化时调整流程强度。

二、仍未完全解决的问题与新问题

经过一个学期,原来的问题已经有了阶段性答案,但并没有彻底结束。我仍然认为以下问题值得继续研究。

1. AI 生成代码的责任应该如何界定?

团队可以要求标注 AIGC、补充测试并由责任人解释代码,但当 AI 生成内容越来越多时,如何衡量真实贡献、如何证明责任人理解了代码、出现缺陷后由谁承担维护责任,仍然没有统一答案。未来的软件工程过程可能需要的不只是“是否使用 AI”的记录,而是一套对可解释性、可复现性和责任归属的验收机制。

2. 如何测试“好玩”和“体验好”?

自动化测试能够验证伤害计算、卡牌效果、存档恢复和场景流转,却不能直接证明游戏好玩。真实玩家能够指出 UI 不清楚、节奏拖沓或数值失衡,但这类反馈往往主观、零散。如何把玩家意见转化为通关率、卡牌选择率、退出位置、重复游玩率等可分析数据,并避免只根据少量样本过度调整,是团队项目后仍然留下的问题。

3. 如何在快速迭代中避免文档与代码脱节?

文档过少会增加理解成本,文档过多又可能迅速过期。我们在项目中已经遇到过规格和实际实现存在历史差异的情况。以后我希望进一步探索:哪些信息应该写进长期文档,哪些应该通过类型、测试和代码结构表达,哪些只需要保留在 Issue 和 Pull Request 中。

三、软件生命周期六个阶段中学到的知识点

阶段 我学到的一个知识点 结合项目的理解
需求 需求必须可验证 “界面更好看”“游戏更有反馈”不是可验收需求。更好的写法应明确用户场景、预期行为和通过标准。例如,新玩家能否在五分钟内理解移动和出牌,关键 UI 是否遮挡,失败后能否顺利重新开始。个人案例分析中“可编辑 PPTX”名义上存在、实际不能编辑,也说明功能名称不等于需求已经满足。
设计 通过职责分离控制变更影响范围 结对项目中把输入解析与规则计算分开,使测试更容易定位问题;团队项目中使用数据驱动方式组织卡牌、敌人和事件,并将状态、战斗计算、商店逻辑和 UI 逐步拆分。设计的价值不是让结构看起来复杂,而是让下一次修改不需要同时理解整个系统。
实现 先形成可运行闭环,再增量扩展 Alpha 阶段最重要的不是堆积孤立功能,而是让地图探索、战斗、奖励和继续推进形成完整流程。Beta 阶段再加入更多关卡、动画、道具和存档。一个始终可运行的主干,比多个无法集成的“完成模块”更有价值。
测试 测试是规则的可执行表达 结对项目中,人工阅读遗漏的问题最终被测试发现;团队项目中,卡牌效果、敌人行动、地图、商店、奖励、存档和 UI 都逐步建立自动化回归。与此同时,自动化测试还必须与场景测试和真实玩家测试结合,因为正确运行不等于体验良好。
发布 发布需要明确的出口条件 发布不只是执行打包命令。Beta 阶段同时检查类型、自动化测试、生产构建、主要场景、Issue 状态和兼容性,并要求没有未解决的 P0/P1 阻断问题。发布标准把“我觉得差不多”变成团队可以共同确认的证据。
维护 可维护性本质上是降低下一次安全修改的成本 模块边界、回归测试、Issue 记录、文档同步和可复现的随机种子,都是为了让未来的人更容易理解、定位和修改。维护不是项目结束后的附加工作,而应从第一次设计和提交代码时开始。

四、结合个人项目、结对编程和团队项目的心得

1. 个人作业:从“使用软件”到“验证产品承诺”

个人软件案例分析中,我选择了 banana-slides。最初我容易被完整的生成流程和较好的页面效果吸引,但真正沿着“生成—编辑—导出—再次编辑”的端到端路径测试后,我发现了两个更关键的问题:局部编辑没有准确执行指令,以及所谓可编辑 PPTX 最终仍可能是整页图片。

这次经历改变了我评价软件的方式。一个功能不能只看入口是否存在、按钮是否可点击,而要检查用户最终目标是否完成;一个 Bug 的严重程度,也不能只按是否崩溃判断,还要考虑它是否破坏产品的核心承诺。后来在团队项目写需求和测试报告时,我也更重视用户场景、验收标准和端到端链路,而不是只列模块清单。

个人案例分析博客:软件案例分析

2. 结对编程:协作的核心是共享问题模型

结对项目让我第一次比较完整地体验驾驶员和领航员角色互换。作为领航员时,我能更集中地检查分支和规则;作为驾驶员时,我能够直接感受到搭档的算法建议如何影响代码结构。这个过程让我认识到,结对编程不是一个人写、另一个人旁观,而是两个人持续校准对问题的理解。

我也看到了结对的边界:两个人仍可能一起忽略同一个错误,因此结对不能代替测试;如果任务过于简单,结对成本可能高于收益;如果任务高度探索,先独立形成方案再讨论可能更有效。

因此,我今后不会把结对编程理解为必须遵守的固定形式,而会把它用于高风险逻辑、新技术学习、架构讨论和容易产生理解分歧的任务。

3. 团队项目:软件工程首先是集成与责任

在 Z-Spire 项目中,我从早期的技术规格和整体框架,逐步参与到战斗界面、动画音效、泳池和迷雾关推进、Bug 修复和测试补充。个人完成一个功能,只需要保证自己理解代码;团队完成一个版本,则必须保证不同成员的产物能够在同一时间点稳定集成。

Alpha 阶段让我认识到“做出来”和“交付出来”的区别。只有当游戏能够下载、运行并完整体验一轮时,模块才真正形成产品价值。真实发布也暴露了内部开发不容易发现的问题,例如 UI 表达、术语理解和边界条件。

Beta 阶段让我进一步认识到,“更多功能”不等于“更高质量”。团队把重点转向自动化回归、场景测试、构建检查、Issue 跟踪和发布标准。项目最终能够通过类型检查、核心回归和生产构建,并关闭已记录的主要缺陷,依靠的不是某一个成员最后集中修补,而是逐步形成的工程流程。

团队项目还让我理解了责任的含义。责任并不是“这段代码是谁写的”,而是有人能够说明它为什么这样设计、如何验证、出了问题如何定位、下一位维护者如何继续修改。技术负责人也不只是写最难的代码,还要帮助团队建立共同结构、减少集成冲突,并在交付前关注整体风险。

团队博客:MAGICCELL 团队博客

五、课程总结

学期初,我对软件工程的理解更接近“开发软件时需要遵守的一组知识点和流程”。完成个人评测、结对编程、Alpha 和 Beta 两个阶段之后,我更愿意把它理解为:

在有限时间、有限人力和不完整信息下,对需求、成本、风险和质量作出可解释、可验证、可追踪的取舍。

需求分析不是把想法写得更长,而是明确用户目标和验收方式;设计不是追求复杂架构,而是控制变化范围;实现不是单纯增加代码量,而是持续保持可运行状态;测试不是项目末尾集中找错,而是用证据保护规则;发布不是上传文件,而是达到共同认可的出口条件;维护也不是结课后的事情,而是从第一次命名、第一次划分模块和第一次编写测试时就开始。

这个学期我最大的变化,是不再简单地询问“某个方法有没有用”,而会继续追问:它解决什么风险、需要多少成本、有什么证据证明有效、在当前项目中应该做到什么程度。原来的五个问题没有得到永久不变的答案,但我已经形成了一套更接近工程实践的判断方式。这也是我从这门课程中获得的最重要的收获。