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

项目 内容
这个作业属于哪个课程 首页 - 2026年春季软件工程 - 北京航空航天大学 - 班级博客 - 博客园
这个作业的要求在哪里 [I.3] 个人作业:结课总结 - 作业 - 2026年春季软件工程 - 班级博客 - 博客园
我在这个课程的目标是 掌握软件工程的核心方法论与实践技巧,建立规范的软件研发思维,能独立完成从需求分析到软件发布的全流程开发,同时提升团队协作与项目管理能力
这个作业在哪个具体方面帮助我实现目标 通过回顾一个学期的实践与学习,对照学期初阅读《构建之法》时提出的问题进行反思总结,梳理自己在软件工程各阶段中获得的知识点和成长

一、提问回顾

链接到以前提问题的博客:[I.1] 个人作业:阅读和提问 - lhl-lsyycf - 博客园

在学期开始时,我阅读了《构建之法》全书,提出了五个问题。经历了一个学期的结对项目和两个阶段的团队项目后,我对这些问题有了新的理解。以下是对每个问题的回顾与解答。


问题1:中小团队手工测试文档化的落地矛盾

原始问题:在人数少于5人的微型研发团队中,手工测试的文档化应该如何平衡"可追溯、可交接"的规范性和"快迭代、轻流程"的实际需求?

现在的理解

在"启元知微"团队项目中,我们恰好面临了类似的情境。团队共7人,且没有专职测试人员,测试工作全部由开发人员交叉完成。为了平衡规范与效率,我们的具体做法是:

  1. 不追求全量手工测试文档,但保留核心路径的验收清单。在 Alpha 和 Beta 阶段,我们都制定了"发布前回归清单"(例如 Alpha 阶段有 R-01 到 R-12 共12项回归项),这些清单简洁但覆盖了核心用户路径,既不会占用大量编写时间,又能保证关键功能的可追溯性。
  2. 用缺陷记录表替代冗长的测试文档。我们按 P0/P1/P2 记录缺陷,Alpha 阶段共记录 12 个缺陷,Beta 阶段集中修复 3 个明确缺陷。这种轻量化的记录方式,既保证了问题的可追踪,又没有给团队带来额外的文档负担。
  3. 自动化测试是更好的"文档"。我们在三个仓库中配置了 CI/CD,Backend 和 RAG 仓库有 pytest 自动化测试,Frontend 有 TypeScript 类型检查和构建检查。这些自动化测试本身就是最好的"活文档",每次提交都会自动验证功能是否正常。

结论:书中的手工测试规范确实更适用于中大型项目。对于微型团队,最低标准应该是:核心路径有验收清单 + 缺陷有记录 + 尽可能引入自动化测试。形式不重要,关键是团队能在出问题时快速定位、在交接时有据可查。


问题2:开发兼任测试/QA时,如何保证质量保障的独立性?

原始问题:当开发人员同时负责测试和质量保障工作时,如何通过流程设计弥补"自己测自己代码"的思维盲区?

现在的理解

当我们身兼开发与测试两职时,确实容易产生“自己测自己代码”的盲区。在实际开发中,我们验证了以下几种轻量化的解决方案来弥补这一缺陷:

  1. 交叉测试:我们采用"模块负责人自测 + 交叉走查 + 发布前集中回归"的方式。例如后端开发者写完接口后,由前端开发者在联调时从用户视角进行测试,这种天然的交叉验证非常有效。许多 Bug(如 SSE 流式结束事件不统一、Token 过期后接口失败等)都是在交叉联调中被发现的。
  2. 场景化测试:我们设计了多个典型用户场景(课前预习、考前复习、刷题模考、论坛互助等),让不同的团队成员以"角色扮演"的方式走完整个用户路径。这种方式让测试者跳出了"我的代码没问题"的思维定势。
  3. AI 辅助生成测试用例:在结对项目中,我们利用大模型批量生成边界测试用例,弥补了人工测试容易忽略边缘情况的缺陷。
  4. 自动化 CI 作为底线:即使所有人都忘了测试,CI 流水线也会在每次提交时自动运行测试,这是防止质量滑坡的最后一道防线。

结论:即使没有专职测试人员,通过交叉测试、场景化测试、AI 辅助生成用例和自动化 CI,依然能在一定程度上保证质量保障的有效性。关键不是角色的独立性,而是视角的独立性——让不同的人从不同的角度去审视同一份代码。


问题3:跨界创新如何避免陷入"外行式伪创新"的陷阱?

原始问题:非领域专家的跨界创新,该如何平衡"跳出行业固化思维的想象力"和"领域内的专业约束与客观规律"?"非拿手领域的创新"的边界在哪里?

现在的理解

经历了结对与团队项目的打磨,我对何为真正的“创新”有了更务实的认识:

  1. 创新的前提是深入理解用户痛点。在"启元知微"项目中,我们的创新不是凭空想象的,而是基于充分的社会调研:我们调查了北航工科学生的学习压力、课程困难、AI工具问题等,发现了"通用大模型缺乏学科专业性"和"垂直学习平台缺乏智能交互"的市场空白,然后才决定做"课程感知的 RAG 问答"这个方向。
  2. "跨界"成功者其实都具备目标领域的底层能力。在结对项目中,我们使用 PIMC + Alpha-Beta 剪枝来实现花见小路的博弈 AI。虽然我们不是游戏AI领域的专家,但我们具备算法设计和系统优化的基础能力,因此能够将博弈理论有效地转化为工程实现。反过来,如果我们完全不懂算法,仅凭"创新灵感"是不可能做出有竞争力的 AI 的。
  3. AI 辅助编程降低了"跨界"的技术门槛,但没有降低"理解力"的门槛。我们在结对项目中大量使用了 Vibe Coding,AI 帮助我们处理了 Rust 语法、所有权机制等我们不熟悉的技术细节,但核心的博弈策略、状态机设计、评估函数权重,都必须由我们人类来思考和推演。

结论:书中的观点并没有弱化领域专业能力的作用。70%的创新者在"拿手领域之外"做出创新,不代表他们是完全的门外汉——他们往往具备目标领域的底层思维模型,只是没有被该领域的既有范式所束缚。真正的跨界创新,需要足够的领域理解 + 来自其他领域的新视角,两者缺一不可。


问题4:短周期敏捷迭代中,ZBB要求是否会加剧技术债的堆积?

原始问题:在2周一次的敏捷短迭代中,每个迭代末期都要求完成 ZBB,会不会导致开发团队采用临时的修复方案,反而堆积技术债?

现在的理解

这个问题在我们的 Alpha 和 Beta 两个真实迭代周期中得到了直接的检验:

  1. Alpha 阶段确实存在"打补丁"的情况。为了在截止日期前跑通核心路径,我们对一些问题采取了临时方案。例如论坛模块使用了 FORUM_STUB=true 的内存桩模式来绕过真实数据库依赖,SSE 流式结束事件的处理在 Backend 和 RAG 之间不统一但能用。这些确实是技术债。
  2. 但 Beta 阶段证明了"先清零、后偿债"的节奏是可行的。Beta 阶段的核心目标就是基于 Alpha 暴露的 5 类痛点进行深度改进。我们将 Alpha 阶段遗留的论坛 Stub、事件格式不统一、错题本断链等问题,全部转化为 Beta 阶段的正式需求并逐一修复。
  3. ZBB 的关键不在于"清零",而在于"分类"。我们在 Alpha 发布时明确记录了 3 个遗留缺陷(2 个 P2 和 1 个降级处理的 P1),它们不影响核心流程,因此允许带入 Beta。这种"P0/P1 必须清零,P2 可以带入下一迭代"的分级策略,既避免了为了清零而打补丁,又保证了核心质量。

结论:ZBB 不应该被理解为"每个迭代末尾所有 Bug 必须归零",而应该理解为"每个迭代末尾,所有已知 Bug 都必须被明确处理——要么修复,要么有意识地推迟并记录"。关键在于"已知"和"处理",而不是"零"。这种理解下,ZBB 完全适用于敏捷短迭代,不会加剧技术债,反而是控制技术债的有效手段。


问题5:技术水平差距过大的两人结对编程,是否违背了其设计初衷?

原始问题:如果结对的两人技术水平差距过大,结对编程是否会变成单向教学,完全违背了平等互补的设计初衷?

现在的理解

虽然我和搭档在结对项目中技术水平相近,合作非常顺利,但随着 AI 辅助编程的深度介入,我发现衡量“水平差距”的维度本身已经发生了变化:

  1. AI 重新定义了"技术水平差距"。在传统结对编程中,技术水平主要体现在"能否快速写出正确的代码"。但在 Vibe Coding 时代,语法细节和底层实现可以交给大模型完成,人类开发者的核心价值转移到了规则架构的推演、算法设计、测试覆盖的思考上。因此,两个人即使在编码能力上有差距,但只要在逻辑思维和领域理解上能互补,结对编程依然是高效的。
  2. AI 辅助时代的结对编程,本质上是"两个架构师的结对"。我们的实际体验是:两人先在白板上结对画出状态机和数据流,共同拟定 Prompt 的约束条件,然后由一人"驾驶"大模型生成代码,另一人充当"人类编译器"和"逻辑审阅者",逐行审查大模型产出的核心逻辑。这种模式下,结对编程的价值不但没有被 AI 削弱,反而被拔高到了纯粹的架构和逻辑层面。
  3. 但对 AI 生成代码的审查盲区是新的挑战。我们在实践中发现,大模型生成代码速度极快,有时会产生惰性,直接运行而不仔细审查,导致一些隐蔽的边界 Bug 在测试阶段才暴露。

结论:AI 时代的结对编程确实不再需要两人的"编码能力"相当,但需要两人的"思考能力"相当。书中关于结对编程的描述需要与时俱进——在 AI 辅助编程的语境下,结对编程从"两个程序员轮流敲键盘"演变成了"两个架构师共同指挥 AI 完成工程实现",其核心价值依然成立,甚至更加重要。


二、未解决的问题

至此,关于质量保障、测试文档化以及敏捷迭代的疑问,都在项目落地中找到了答案。

仍然部分未解决的是问题3(跨界创新的边界)。虽然我对"跨界创新需要底层能力"有了更清晰的认识,但一个更深层的问题仍然困扰着我:在 AI 极大降低技术实现门槛的时代,"领域底层能力"的定义本身是否在发生变化? 过去,你需要精通 Rust 的所有权机制才能实现高性能系统——现在大模型可以帮你处理这些语法层面的问题。那么,未来的"跨界创新"是否会变得更容易?"外行式伪创新"的边界是否在缩小?这个问题可能需要更长时间的观察才能回答。


三、新的问题

随着项目经验的积累,旧的疑惑被解开,但基于新的开发模式,我又产生了以下思考:

新问题1:AI 辅助编程中,人类开发者的核心不可替代能力到底是什么?

在结对项目和团队项目中,我大量使用了 AI 辅助编程。AI 能处理语法转换、代码生成、Bug 修复、测试用例生成等大量工作。那么,在 AI 越来越强大的未来,软件工程师的核心不可替代能力到底是什么?是需求理解?架构设计?还是对 AI 输出的审查与判断?如果 AI 也能做架构设计,那人类软件工程师的终极价值在哪里?

新问题2:当产品的核心价值依赖外部 AI 模型时,如何建立自己的技术壁垒?

"启元知微"的核心竞争力之一是课程感知的 RAG 问答,但其底层依赖的是外部 LLM/Embedding API。如果这些 API 涨价、不可用或被竞品获得同等接入权限,我们的产品壁垒在哪里?在"AI 基础设施日益大众化"的时代,应用层产品如何建立自己的护城河


四、"做中学"——六个阶段的知识点

1. 需求阶段

知识点:NABCD 分析框架

在团队项目的选题和需求分析阶段,我学到了 NABCD(Need、Approach、Benefit、Competitor、Delivery)分析框架。在为"启元知微"项目做需求分析时,我们不仅要明确用户的痛点(N),还要分析现有竞品(C)的不足,找到自己的差异化优势(B),并规划如何将产品推广给用户(D)。这种结构化的思考方式,让需求分析从"我觉得这个功能很酷"的主观判断,变成了"用户确实需要、市场确实有空白、我们确实有方案"的客观论证。

2. 设计阶段

知识点:前后端协议的文档化至关重要

在"启元知微"的技术设计中,我深刻体会到了接口协议文档化的重要性。我们的系统由 Frontend、Backend、RAG 三个子系统组成,Backend 与 RAG 之间通过 HTTP 契约通信。在 Alpha 阶段,因为协议文档不够细致,Backend 与 RAG 的 SSE 事件格式不统一,导致联调时出现了大量问题。Beta 阶段,我们专门制定了 RAG 引用元数据协议(包括 references_meta JSON 格式、cite_id 分配规则、SSE 首帧 event: meta 协议),并将协议固化到 docs/rag_integration.md 中,联调效率显著提升。这让我明白:设计的核心产出不是代码,而是约束和契约

3. 实现阶段

知识点:分层架构与关注点分离

在团队项目的实现过程中,我学到了 endpoint -> service -> schema/model 的分层架构原则。后端代码中,endpoint 层负责参数校验和响应组装,service 层负责业务逻辑和事务编排,model 层负责数据持久化。这种分层使得代码职责清晰、模块可独立测试、需求变更时只需修改对应层级。例如,当 Beta 阶段需要增加"AI 深度解析"功能时,只需在 service 层增加新的编排逻辑,复用已有的 RAG 客户端和题库数据访问层,而不需要大面积改动既有代码。

4. 测试阶段

知识点:场景化测试比单元测试更能发现集成问题

在 Alpha 和 Beta 阶段的测试中,我发现场景化测试(即模拟真实用户的完整使用路径进行测试)比单元测试更能发现系统级的问题。例如,"错题复练 Session 过期后提交返回 500"这个 Bug,单元测试中很难覆盖到,因为它涉及 Redis TTL、答题提交、错题回收等多个模块的交互。但当我们以"学生做完题后长时间没交卷"的场景进行测试时,这个问题立刻暴露出来了。单元测试保证局部正确,场景测试保证整体可用,两者缺一不可。

5. 发布阶段

知识点:发布不是"把代码推上去",而是一套工程流程

在团队项目中,我学到了完整的发布流程:git push -> GitHub Actions CI/CD -> 构建/测试 -> 推送镜像 -> 服务器拉取 -> 健康检查 -> Alembic 迁移 -> 灰度/全量发布。我们的三个仓库共配置了 6 个 GitHub Actions 工作流(3 个 CI + 3 个 Deploy),release 分支触发部署工作流。发布前还需要检查 .env 环境变量配置、数据库迁移脚本是否已应用、RAG 服务是否健康等。这让我深刻理解了:发布是一个可复现、可回滚、可验证的工程流程,而不是"在服务器上手动操作"的一次性行为。

6. 维护阶段

知识点:可观测性是维护的基础

在 Beta 阶段,我们为"启元知微"增加了管理员统计视图和健康检查机制。后端提供 /api/v1/health 健康检查接口,检查应用、数据库和 Redis 的状态;管理员统计视图每 10 秒自动轮询健康检查接口,并以绿色/黄色/橙色/红色展示服务状态。同时,我们记录了用户行为日志(DAU、功能使用热度等),为后续迭代提供数据依据。这让我理解了:维护的前提是"能看见"——如果你不知道系统当前的状态,就无法进行有效的维护和改进


五、个人项目/结对编程/团队项目的心得

个人项目:独立思考的价值

个人作业(阅读提问和软件案例分析)让我学会了批判性地审视现有软件产品。在分析 GitHub 时,我不仅体验了其核心功能,还发现了博客时区渲染、大文件克隆等实际问题,并从软件工程的角度分析了其成因和改进方向。同时,通过 COCOMO II 公式估算 GitHub 的工作量(约 135372 人月),我第一次真实地感受到了大型软件系统的工程复杂度,理解了为什么"人月神话"说"向进度落后的项目中增加人手,只会使进度更加落后"。

结对编程:AI 时代的新范式

结对项目(花见小路)是我第一次将"AI 辅助编程"深度融入工程实践。最大的收获是发现了一种新的开发范式:人类定框架,AI 写代码。在实现 PIMC + Alpha-Beta 剪枝博弈 AI 的过程中,我和搭档负责推演算法架构、设计启发式评估函数的权重,然后将繁琐的 Rust 实现(如 xorshift64 伪随机数生成器、Action 4 不重复组合生成算法、借用检查器报错修复等)交给大模型完成。这让我深刻意识到:未来的软件开发,核心壁垒不再是熟练掌握某种语言的语法细节,而是能否准确构建系统模型、提出正确的算法思路,并精准地将其描述给 AI 去执行。

团队项目:软件工程的真正意义

"启元知微"从零开始,历经 Alpha 和 Beta 两个阶段,最终成为一个拥有 87 名注册用户、65 名活跃用户的真实产品。这段经历让我理解了软件工程这门学科存在的真正意义。

第一个感悟是:软件 = 程序 + 软件工程。 功能能跑只是第一步,真正让产品可持续的是清晰的需求管理(Issue + Milestone)、稳定的协议约束(rag_integration.md)、可追踪的数据库演进(Alembic 迁移脚本)、可复现的部署流程(CI/CD + Docker Compose)、可验证的测试体系(pytest + 场景化手测)和真实的用户反馈。

第二个感悟是:计划总是被改变,但计划的过程本身有价值。 Alpha 阶段我们拆分了 32 个子任务、估时 158 小时;Beta 阶段拆分了 15 个 Issue,每个都有明确交付件。虽然实际执行中总有偏差(例如 Beta 第一周实际剩余任务数高于计划),但正是因为有了详细的计划,我们才能清楚地知道"偏差了多少"并及时调整。

第三个感悟是:团队协作的核心是信息对齐。 在 7 人团队中,最大的挑战不是技术问题,而是信息同步。我们通过每周例会、飞书共享文档、GitHub Issue、协议文档等方式持续对齐,确保每个人都知道"当前进度如何"、"下一步做什么"、"阻塞点在哪里"。当出现跨模块联调问题时(如 RAG 引用协议、错题 Session TTL、禁言状态刷新冲突),往往不是某个人的代码写错了,而是两个模块的"理解"不一致。软件工程的很多工具和流程,本质上都是在解决人与人之间的信息对齐问题。


结语

一个学期前,我在读完《构建之法》后提出了5个问题,那时的我带着"书中说的对不对"的疑问。一个学期后,我发现大部分问题的答案不是"对或错",而是"在什么场景下、以什么方式适用"。

软件工程不是一套可以机械执行的规则,而是一门在实践中不断权衡、适配和演化的学问。这个学期最大的收获,不是掌握了某个框架或技术,而是建立了一种工程化的思维方式:面对问题时,先分析需求和约束,再设计方案和验证手段,最后在迭代中不断改进。

感谢软件工程这门课程,感谢团队中的每一位成员,感谢这段让我从"写代码的学生"成长为"初具工程思维的开发者"的旅程。

posted @ 2026-06-23 21:27  lhl-lsyycf  阅读(5)  评论(0)    收藏  举报