[I.3] 个人作业:结课总结
[I.3] 个人作业:结课总结
| 项目 | 内容 |
|---|---|
| 这个作业属于哪个课程 | https://edu.cnblogs.com/campus/buaa/BUAA_SE_2026_LR |
| 这个作业的要求在哪里 | https://edu.cnblogs.com/campus/buaa/BUAA_SE_2026_LR/homework/15687 |
| 我在这个课程的目标是 | 学习快速开发一个软件项目的全流程 |
| 这个作业在哪个具体方面帮助我实现目标 | 总结在课程中学到的技能和方法 |
一、前序提问博客链接
前序提问博客链接:
[l.1] 个人作业:阅读与提问 - samlee1020 - 博客园
一个学期前,我在阅读教材时提出了一些关于 PSP、单元测试、敏捷开发、代码规范、架构设计、团队分工和工程师评价的问题。当时这些问题更多来自过去个人课程项目的经验,尤其是编译器、操作系统实验等偏个人开发、偏底层实现的项目。经过本学期的软件工程课程实践,包括个人项目、结对编程和团队项目后,我对这些问题有了一些新的理解。
二、对原有问题的回顾与解答
问题一:PSP 中精确到分钟的时间记录是否真的有意义?
学期初我对 PSP 的疑问是:实际开发中经常会被打断,设计、编码、调试也常常交织在一起,精确到分钟记录时间是否只是增加负担。
经过本学期实践后,我的理解有所变化。PSP 的重点不一定是“精确到每一分钟”,而是通过记录让开发者意识到时间花在哪里。比如在个人项目和结对项目中,我发现自己经常低估调试和环境配置的时间,而高估真正写代码的时间。如果完全不记录,就容易产生“我今天写了很久代码”的错觉,但实际上大量时间可能花在查文档、修环境、沟通需求或者反复试错上。
因此,我现在认为 PSP 的价值不在于追求绝对精确,而在于帮助个人建立估算能力。对于学生开发者来说,可以不必机械地精确到分钟,但至少应该记录大致时间分布,例如需求理解、编码、调试、测试、写文档分别花了多少时间。这样在后续项目中,才能更现实地安排进度。
问题二:复杂系统软件中,单元测试的边界在哪里?
我原来认为,对于编译器这类状态复杂、模块耦合强的系统,强行写单元测试可能会拖慢进度。这个问题在本学期实践后仍然有一定保留,但我对“测试”的理解更宽了一些。
单元测试不一定要求把每一个内部函数都单独 mock 出来测试。对于复杂系统,可以把测试边界放在相对稳定的接口上。例如编译器项目中,与其单独测试某个语法分析函数,不如准备一组源程序输入,检查最终输出、中间代码或者错误信息是否符合预期。这更接近集成测试或回归测试,但同样能起到保证质量的作用。
在团队项目中,我也体会到,如果没有任何测试,项目后期很难判断一次修改是否破坏了已有功能。尤其是多人协作时,测试不仅是检查代码正确性,也是保护他人代码不被误伤的工具。所以我现在认为,对于学生项目,不必追求很高覆盖率,也不必形式化地执行 TDD,但至少应该有一些关键功能的测试用例和回归检查。
问题三:敏捷开发在学生团队中会不会流于形式?
这个问题是我本学期感受最深的问题之一。课程项目最初计划做一个 Unity 2D 横板战斗小游戏,我负责 UI 部分。但实际推进过程中,除了组长之外,大部分成员对 Unity 并不熟悉,学习成本较高,后续项目逐渐变成主要由组长推动,团队整体参与度不足。
这让我更加认识到,敏捷开发并不是开会、写任务板、做迭代这些形式本身。敏捷真正依赖的是持续交付、及时反馈和团队成员的主动承担。如果团队成员缺乏共同目标,技术栈又超出多数人的能力范围,那么敏捷流程很容易变成表面上的任务分配,无法真正提高效率。
所以我现在的答案是:敏捷在学生团队中不是解药,也不是毒药,关键取决于团队是否具备执行敏捷的基础。对于学生团队来说,轻量化的敏捷可能更合适,例如每周明确一个小目标、每个人交付一个可见成果、遇到问题及时同步,而不是机械模仿企业中的完整敏捷流程。
问题四:代码规范与底层实现冲突时如何取舍?
学期初我认为,底层代码中常见位操作、硬编码和复杂逻辑,可能天然与“优雅规范”冲突。现在我认为,这两者并不完全矛盾。
代码规范的目的不是让所有代码都写得像业务代码一样简单,而是让代码在特定场景下尽可能可理解、可维护。底层代码确实可能需要为了性能或硬件约束使用复杂写法,但这并不意味着可以完全放弃规范。更合理的做法是:核心性能路径可以接受复杂实现,但需要通过命名、注释、封装和文档解释清楚为什么这样写。
在团队项目中,我也发现规范的重要性不只体现在代码美观上,更体现在协作上。即使是简单 UI 代码,如果命名混乱、资源路径随意、场景结构不清楚,其他成员也很难继续维护。因此我的理解是,规范可以向底层现实做局部妥协,但不能完全消失。
问题五:需求明确时,过度遵循设计原则是否属于过度设计?
我原来认为,如果需求非常明确,例如编译器规格固定,就没有必要为了未来扩展牺牲当前简洁性。经过实践后,我仍然认同这一点,但也补充了一层理解:反对过度设计,并不等于不要设计。
在课程项目中,最初设想是做横板战斗小游戏,但实际开发中需求并没有一开始就完全稳定。角色、战斗、UI、关卡、素材等内容都可能变化。如果前期完全没有设计,后期很容易变成想到哪里写到哪里,最终导致维护困难。但如果一开始就设计过多复杂框架,又会因为团队技术能力不足而无法落地。
所以我现在认为,设计原则应该服务于实际需求和团队能力。学生项目中更适合做“刚好够用”的设计:核心模块之间边界清楚,接口不要过度复杂,先保证能跑起来,再逐步重构。设计不是为了炫技,而是为了降低后续修改成本。
问题六:模块分工是否会造成知识孤岛?
本学期项目进一步验证了我对这个问题的担忧。团队项目中,我被分配到 UI 部分,但由于对 Unity 整体开发流程理解不够,单独做 UI 很容易脱离角色控制、场景切换、游戏状态管理等整体逻辑。最终结果是,单纯按模块分工并不能保证协作有效,反而可能让每个人只了解自己名义上的一小块。
但我也认识到,完全不分工同样不现实。团队项目一定需要责任边界,否则会出现没人负责、互相等待的问题。比较合理的方式是“主负责人 + 基本全局理解”。每个人可以主负责一个模块,但至少要了解整个项目如何运行、自己的模块与其他模块如何交互。
因此,模块分工本身没有问题,问题在于是否有足够的接口说明、沟通机制和整体视角。学生团队尤其需要在早期统一项目结构和基本流程,否则后期很容易出现知识孤岛。
问题七:Bug 数量能否评价工程师水平?
我原来认为,单纯用 Bug 数量评价工程师可能会鼓励保守开发。本学期后,我更加认同这一点。Bug 数量只能反映一部分质量问题,不能脱离任务难度、功能复杂度和项目阶段单独评价。
在实践中,有些功能本身很简单,自然 Bug 少;有些功能涉及状态切换、资源加载、多人协作,即使开发者能力更强,也可能暴露更多问题。更合理的评价方式应该综合考虑:是否实现了核心功能、是否及时修复问题、是否留下清晰文档、是否降低了他人维护成本。
所以我现在认为,Bug 率可以作为参考指标,但不能作为唯一指标。软件工程更关注的是在约束条件下持续交付可用的软件,而不是单纯追求表面上的低 Bug 数量。
三、仍然没有完全弄清楚的问题
目前我仍然没有完全弄清楚的问题是:在学生团队中,如何让每个成员都真正投入项目,而不是最后变成少数人承担主要工作。
教材和课堂中给出了很多方法,例如任务分解、站会、燃尽图、代码评审、结对编程等。但在实际学生项目中,每个人的课程压力、技术基础、责任心和时间安排都不同,单靠流程工具很难解决动力不足的问题。这个问题可能不只是软件工程问题,也涉及团队管理、评价机制和个人责任感。
我目前的理解是,学生团队项目需要更小的目标、更明确的验收标准,以及更透明的贡献记录。否则即使形式上有团队,实际也可能退化成少数人完成项目。
四、新产生的问题
经过本学期实践,我产生了一个新的问题:
对于学生团队项目来说,技术选型应该优先考虑“想做的效果”,还是优先考虑“团队能掌握的技术”?
例如本学期我们最初选择 Unity 2D 横板战斗小游戏,是因为这个方向看起来比较有趣,也容易展示成果。但实际执行时,团队大多数成员并不熟悉 Unity,导致学习成本和开发成本都被低估。最后项目推进不理想。
因此我现在认为,学生项目的技术选型不能只看最终效果,还要看团队已有能力、学习时间、可拆分程度和最低可交付版本。如果一个技术栈只有少数人能掌握,那么它很容易导致团队协作失衡。
五、六个阶段中学到的知识点
1. 需求阶段:需求必须可落地、可验收
在需求阶段,我学到的知识点是“需求分析不能只停留在想法层面”。一开始我们设想做 Unity 2D 横板战斗小游戏,这个方向听起来完整,但如果没有进一步拆成可验收的功能,例如主菜单、角色移动、攻击判定、敌人 AI、血条 UI、关卡切换等,就很难判断每周到底完成了什么。
需求阶段最重要的不是把项目描述得很宏大,而是明确最低可行版本。对于学生团队来说,需求越具体,后续分工和进度管理越容易。
2. 设计阶段:模块边界要结合团队能力
在设计阶段,我学到的知识点是“模块化设计”。游戏项目可以拆成 UI、角色控制、战斗系统、关卡系统、资源管理等模块。但实践中我发现,模块边界不能只从功能角度切分,还要考虑成员是否理解模块之间的依赖关系。
比如 UI 不只是画按钮,还要和游戏状态、场景切换、玩家血量等逻辑交互。如果设计阶段没有说明这些接口,后续实现就会困难。因此设计阶段需要明确模块之间如何通信,而不是只写一个分工表。
3. 实现阶段:技术栈学习成本会直接影响进度
在实现阶段,我学到的知识点是“技术风险”。Unity 对初学者并不是简单拖拽就能完成项目,场景、组件、脚本、资源、动画、输入系统都需要学习。如果团队低估技术栈学习成本,项目进度就会受到很大影响。
这让我认识到,实现阶段不只是写代码,还包括熟悉工具链、搭建环境、阅读文档和解决工程问题。以后做项目时,应该更早做技术验证,而不是等到正式开发时才发现很多东西不会。
4. 测试阶段:测试不是最后才做的事情
在测试阶段,我学到的知识点是“持续测试”。游戏项目中很多问题不是编译错误,而是运行时体验问题,例如按钮是否能点击、场景是否能跳转、UI 是否遮挡、角色状态是否正确。这类问题如果堆到最后才测试,会很难集中修复。
因此测试应该贯穿开发过程。哪怕没有完整自动化测试,也应该在每次实现一个小功能后手动验证,并记录问题。对于学生项目来说,简单的测试清单也比完全没有测试要好。
5. 发布阶段:能在别人电脑上运行才算完成
在发布阶段,我学到的知识点是“可交付性”。一个项目在开发者自己的电脑上能运行,并不代表已经完成。真正发布时,还要考虑打包、依赖、资源路径、版本说明、运行环境等问题。
这与我之前做后端项目、编译器项目的经验也类似:代码写完只是第一步,能否被别人复现和使用才是工程化的一部分。发布阶段要求我们从使用者角度检查项目,而不是只从开发者角度看功能。
6. 维护阶段:文档和交接比想象中重要
在维护阶段,我学到的知识点是“可维护性”。团队项目中,如果只有某一个人真正理解项目结构,那么后续修改和维护就会高度依赖这个人。一旦出现成员变动、转会或时间冲突,项目就容易停滞。
因此,维护阶段不只是修 Bug,还包括保留必要的文档、说明项目结构、记录已知问题和后续计划。软件工程中的文档并不是形式主义,它在团队协作不稳定时尤其重要。
六、结合个人项目、结对编程和团队项目的心得
通过本学期的软件工程课程,我最大的体会是:软件工程不是单纯教人怎么写代码,而是教人在不确定、有限时间和多人协作的条件下,尽量把项目推进到可交付状态。
在个人项目中,一个人可以凭借完整的上下文快速推进,也更容易定位问题。但个人项目的问题是缺少外部反馈,容易低估时间,也容易忽视测试和文档。在结对编程中,我体会到沟通和代码可读性的重要性。两个人一起完成任务时,代码不再只是写给自己看,思路表达、接口约定和互相理解都会影响效率。
团队项目给我的感受最复杂。一方面,我看到了团队协作中理想与现实的差距:如果成员技术基础不同、投入程度不同,即使有流程和分工,项目也可能推进困难。另一方面,这也让我更理解软件工程课程为什么强调需求、设计、测试、发布和维护。因为真实项目的问题往往不是“会不会写某一行代码”,而是“大家能不能围绕同一个目标持续交付”。
这学期的项目完成情况并不理想,但它反而让我更真实地看到了软件工程中的问题:技术选型不能脱离团队能力,分工不能脱离整体理解,流程不能代替责任心,代码完成也不等于项目完成。相比学期初只从书本和个人经验提出疑问,现在我对这些问题的理解更加具体,也更加认识到软件工程实践的复杂性。
总的来说,这门课让我意识到,软件开发不是个人英雄主义,也不是流程表格本身,而是在现实约束下不断协调需求、人员、技术和时间。即使项目结果不完美,这些过程中的反思本身也是软件工程学习的一部分。

浙公网安备 33010602011771号