结对项目:博客问题清单
请将本文件在代码仓库外复制一份,一边阅读和完成结对项目、一边填写入代码仓库外的版本,或采取简记、语音备忘等方式记载较复杂问题的要点之后再补充。请不要将本文档内的作答提交到代码仓库。
Chapter.0 Belua multorum es capitums.(你是多首的怪物。)
引入
→ 📖 Q0.1(P) 请记录下目前的时间。
2025/3/27 20:20
调查
→ 📖 Q0.2(I) 作为本项目的调查:请如实标注在开始项目之前对 Wasm 的熟悉程度分级,可以的话请细化具体的情况。
I. 没有听说过;
II. 仅限于听说过相关名词;
III. 听说过,且有一定了解;
IV. 听说过,且使用 Wasm 实际进行过开发(即便是玩具项目的开发)。
没有听说过;Wasm ,对概念完全不了解,看了项目书首次看到这个东西。
总结
→ 📖 Q0.3(P) 请记录下目前的时间。
2025.3.27 20:30
Chapter.1 不畏迷茫,只管前进。(迷子でもいい、前へ進め。)
结对过程
→ 📖 Q1.1(P) 请记录下目前的时间。
2025.3.27 20:30
→ 📖 Q1.2(P) 请在完成任务的同时记录,并在完成任务后整理完善:
- 浏览任务要求,参照 附录A:基于 PSP 2.1 修改的 PSP 表格,估计任务预计耗时;
- 完成编程任务期间,依次做了什么(比如查阅了什么资料,随后如何进行了开发,遇到了什么问题,又通过什么方式解决);
-
见Chapter.1附录
-
首先我们查询了Wasm语言的相关概念,同时对几个课程组支持的语言类型进行调查,并进行选择。之后由我们一起讨论大致的实现思路与可能出现的问题。搞定初始思路后按照结对开发的流程进行开发。在开发过程中,对程序的运行出现一些疑问,之后在结合教程组教程指引与上网查询相关资料解决该问题。
测试
→ 📖 Q1.3(P) 请说明针对该任务,你们设计和实现测试的方法及过程,包括但不限于:出于对需求的哪些考虑设计了哪些测试用例、如何评估所设计测试的有效性 等等。
本次任务仅考虑单条贪吃蛇在单个果子情况下的运动问题,对贪吃蛇头部产生阻碍的要素仅有自身的蛇身与地图边缘,因此在理论上不存在不可达的情况,因此我们针对蛇头位置,与果子位置做了不同的假设以满足测试需求并输出每一步蛇身的移动方向,查看是否有冗余步骤,除此之外,我们还作了部分规格要求外的测试,通过扩张地图大小来进一步测试贪吃蛇路径规划的正确性。
→ 📖 Q1.4(I) 请说明单元测试对软件开发的作用。
- 及早发现缺陷,降低修复成本
- 快速定位问题:单元测试针对函数、方法等最小代码单元,能在开发阶段快速暴露逻辑错误,减少调试时间。
- 预防回归问题:每次代码修改后运行测试,确保现有功能不受影响,避免“修复一个Bug引入另一个Bug”。
- 驱动高质量代码设计
- 降低耦合度:为方便测试,开发者需编写模块化、职责单一的代码,间接提升代码的可维护性和扩展性。
- 测试驱动开发(TDD):先写测试再实现功能,迫使开发者明确需求,设计更合理的接口。
- 自动化验证,提升效率
- 持续集成支持:自动化测试可集成到CI/CD流程中,每次提交自动验证代码,及时反馈问题,加速迭代。
- 减少手动测试负担:覆盖全面的单元测试替代重复的手动检查,释放开发者精力专注于复杂任务。
- 优化调试过程
- 缩小问题范围:测试失败时,可直接定位到具体单元,避免在复杂系统中大海捞针,提升调试效率。
总结
→ 📖 Q1.5(P) 请记录下目前的时间,并根据实际情况填写 附录A:基于 PSP 2.1 修改的 PSP 表格 的“实际耗时”栏目。
2025.3.27 22:00
见Chapter.1附录
→ 📖 Q1.6(I) 请写下本部分的心得体会。
在本节任务中我担任代码员的身份,先了解了如何创建项目,然后开始编写代码,在较短时间内完成并通过测试。
Chapter.1附录
| Personal Software Process Stages | 个人软件开发流程 | 预估耗时(分钟) | 实际耗时(分钟) |
|---|---|---|---|
| PLANNING | 计划 | ||
| - Estimate | - 估计这个任务需要多少时间 | 5 | 5 |
| DEVELOPMENT | 开发 | ||
| - Analysis & Design Spec | - 需求分析 & 生成设计规格(确定要实现什么) | 10 | 10 |
| - Technical Background | - 了解技术背景(包括学习新技术) | 10 | 5 |
| - Coding Standard | - 代码规范 | 5 | 5 |
| - Design | - 具体设计(确定怎么实现) | 5 | 5 |
| - Coding | - 具体编码 | 20 | 10 |
| - Code Review | - 代码复审 | 5 | 5 |
| - Test Design | - 测试设计(确定怎么测,比如要测试哪些情景、设计哪些种类的测试用例) | 10 | 5 |
| - Test Implement | - 测试实现(设计/生成具体的测试用例、编码实现测试) | 5 | 5 |
| REPORTING | 报告 | ||
| - Quality Report | - 质量报告(评估设计、实现、测试的有效性) | 10 | 10 |
| - Size Measurement | - 计算工作量 | 5 | 5 |
| - Postmortem & Process Improvement Plan | - 事后总结和过程改进计划(总结过程中的问题和改进点) | 5 | 5 |
| TOTAL | 合计 | 95 | 75 |
Chapter.2 即使迷茫,也要前行。(迷子でもいい、迷子でも進め。)
结对过程
→ 📖 Q2.1(P) 请记录下目前的时间。
2025.3.27 22:15
→ 📖 Q2.2(P) 请在完成任务的同时记录,并在完成任务后整理完善:
- 浏览任务要求,参照 附录A:基于 PSP 2.1 修改的 PSP 表格,估计任务预计耗时;
- 完成编程任务期间,依次做了什么(比如查阅了什么资料,随后如何进行了开发,遇到了什么问题,又通过什么方式解决);
-
见Chapter.2附录
-
首先,我们一起讨论了第二节作业的需求,确认增量化开发的可行性,之后一起讨论需要用到的解决算法,解决思路问题后按照结对开发的流程进行开发。但是在初版代码完成后经测试发现代码逻辑出现问题,经再次思考后发现初次思路出现问题,再次修改解决思路按照结对开发的流程进行二次开发,最终完成。
代码可复用性与需求变更
→ 📖 Q2.3(P) 请说明针对该任务,你们对 🧑💻 T1 中已实现的代码进行了哪些复用和修改。
T1中我们完成了贪吃蛇对自身蛇身与地图边界的避障,通过在避障的前提下向果子行进。在本节任务中,引入新的障碍物,我们在复用自身蛇身与地图边界的避障逻辑的前提下更新了贪吃蛇对果子的寻路逻辑,能够主动避开障碍物,沿着最短路径向果子行动。
→ 📖 Q2.4(I) 请说明在编码实现时,可以采取哪些设计思想、考虑哪些设计冗余,来提高既存代码适应需求变更的能力。
一、核心设计思想
- 面向抽象而非实现
- 定义接口与契约:通过抽象接口(如支付方式、数据存储)定义模块间的协作规则,而非依赖具体实现。当需求变化时(如切换数据库类型),只需替换接口的实现,无需修改核心逻辑。
- 依赖注入:将模块的外部依赖(如网络服务、配置)通过参数动态传入,而非在内部硬编码。这降低了模块与具体实现的耦合度。
- 模块化与单一职责
- 功能隔离:将系统拆分为职责明确的独立模块(如用户认证、订单处理、日志记录)。每个模块仅关注单一功能,需求变更时只需调整受影响模块,避免“牵一发而动全身”。
- 领域驱动设计(DDD):通过限界上下文划分业务领域,明确模块的业务边界。例如,电商系统中“库存管理”与“促销活动”作为独立领域,各自封装核心逻辑,需求变化时互不干扰。
- 开闭原则:扩展而非修改
- 预留扩展点:在关键流程中预定义可扩展的步骤(如订单处理前后的钩子方法),允许通过新增逻辑(如添加折扣计算、风控检查)满足需求,而非直接修改原有流程。
- 插件化架构:支持通过插件动态添加功能(如文本编辑器支持多种语法高亮插件),使系统能够灵活适应未来需求。
- 组合优于继承
- 通过组合不同功能单元(如策略模式、装饰器模式)构建复杂行为,而非依赖多层继承。例如,支付功能可通过组合不同的风控策略、支付渠道实现,需求变更时只需调整组合方式。
二、适度设计冗余的策略
- 防腐层(Anti-Corruption Layer)
- 隔离外部系统影响:在核心业务与外部服务(如第三方API、遗留系统)之间增加适配层,将外部数据格式转换为内部标准。当外部接口变更时,只需修改适配层逻辑,避免核心业务被污染。
- 配置驱动设计
- 参数外置:将易变规则(如超时时间、API地址)提取到配置文件或环境变量中,而非硬编码在代码中。例如,调整短信服务的发送频率时,仅需修改配置文件,无需重新部署系统。
- 容错与兼容性设计
- 向后兼容:在接口升级时保留旧版本逻辑(如API的v1和v2共存),通过路由机制逐步迁移用户,避免强制升级导致系统中断。
- 默认值与降级策略:为可选功能提供默认实现(如无缓存时直接访问数据库),确保主流程在部分模块异常时仍可运行。
- 冗余抽象层
- 中间层封装:在底层技术(如数据库操作、文件读写)与业务逻辑之间添加抽象层。例如,通过统一的“数据访问接口”操作数据库,未来切换数据库类型时只需调整抽象层实现。
头脑风暴环节
**→ 📖 Q2.5(P) **只吃一个食物可满足不了贪吃蛇的欲望,请一起思考并简述以下场景中贪吃蛇的策略:
在 🧑💻 T2 的基础上,场地里不再是只有 1 个果子,而是总共有 n 个果子 (1 < n < 10 ),果子随机分布在场地中且不会刷新,保证不与障碍物重叠,保证每个果子均可达,且至少存在一条成功吃掉所有果子的路线,其余条件保持不变,请你找出一条吃完所有果子的行动路径。
可以采用A*+TSP算法来解决,通过TSP方法先计算蛇头到所有果子的最短路径与所有果子之间的最短路径,从而可以用近似 TSP 算法找出最佳吃果子顺序。 之后通过A* 公式:
$$
f(n) = g(n) + h(n)
$$
- $g(n)$ = 从蛇头到当前点的实际代价(路径长度)。
- $h(n)$ = 采用曼哈顿距离估算到目标果子的代价。
之后动态更新地图,采用A*算法继续求解即可。
总结
→ 📖 Q2.6(P) 请记录下目前的时间,并根据实际情况填写 附录A:基于 PSP 2.1 修改的 PSP 表格 的“实际耗时”栏目。
2025.3.28 00:30
见Chapter.2附录
→ 📖 Q2.7(I) 请写下本部分的心得体会。
在本节任务中我担任观察员的身份,帮助提出了一些问题,通过查阅资料找到了合适的思路。
Chapter.2附录
| Personal Software Process Stages | 个人软件开发流程 | 预估耗时(分钟) | 实际耗时(分钟) |
|---|---|---|---|
| PLANNING | 计划 | ||
| - Estimate | - 估计这个任务需要多少时间 | 5 | 5 |
| DEVELOPMENT | 开发 | ||
| - Analysis & Design Spec | - 需求分析 & 生成设计规格(确定要实现什么) | 10 | 10 |
| - Technical Background | - 了解技术背景(包括学习新技术) | 10 | 5 |
| - Coding Standard | - 代码规范 | 5 | 5 |
| - Design | - 具体设计(确定怎么实现) | 20 | 20 |
| - Coding | - 具体编码 | 40 | 30 |
| - Code Review | - 代码复审 | 5 | 5 |
| - Test Design | - 测试设计(确定怎么测,比如要测试哪些情景、设计哪些种类的测试用例) | 10 | 10 |
| - Test Implement | - 测试实现(设计/生成具体的测试用例、编码实现测试) | 20 | 20 |
| REPORTING | 报告 | ||
| - Quality Report | - 质量报告(评估设计、实现、测试的有效性) | 10 | 10 |
| - Size Measurement | - 计算工作量 | 5 | 5 |
| - Postmortem & Process Improvement Plan | - 事后总结和过程改进计划(总结过程中的问题和改进点) | 5 | 5 |
| TOTAL | 合计 | 145 | 130 |
Chapter.3 这就是我的前进、到我出场了!!!!!(It's MyGO!!!!!)
结对过程
→ 📖 Q3.1(P) 请记录下目前的时间。
2025.3.28 00:30
→ 📖 Q3.2(P) 请在完成任务的同时记录,并在完成任务后整理完善:
- 浏览任务要求,参照 附录A:基于 PSP 2.1 修改的 PSP 表格,估计任务预计耗时;
- 完成编程任务期间,依次做了什么(比如查阅了什么资料,随后如何进行了开发,遇到了什么问题,又通过什么方式解决);
-
见Chapter.3附录
-
首先阅读了有关assemblyScript的资料,然后结合第一问的代码先给出了一个简单的版本(直接选一个最近果子,只刨除禁止的方向)。但是逻辑上考虑到,在蛇数不同的情况下,竞争和生存的要求会发生变化,因此加入了动态判断的策略(两蛇竞争,多蛇生存)。最后经搭档指出,选单个最近果子的策略可能局限性比较大,因此综合所有最近果子的信息对方向进行考量。
需求建模和算法设计
→ 📖 Q3.3(P) 请说明你们如何建模这一需求。
任务给出了棋盘中自己蛇的位置,其他蛇的位置,以及果子的坐标等等数据,目的是尽可能吃到更多的果子,因为果子更新速度很快,即便是某一时刻给出一个静态的最短路径,也很快就不会再适用,因此选择最短视的贪心策略,直接去寻找最近的果子们。
在这一任务中,蛇判断方向的依据有以下几个。
- 该方向能不能尽可能快的吃到果子。
- 有没有其他蛇的蛇头或第1、2节(因为第四节所在的位置下轮如果没有别的蛇头补上,就一定会空出来,所以看作空气)。
- 是否躲避其他蛇可能撞击的蛇头。
- 墙壁,自身阻挡等因素。
- 为了最大化分数,多人场景下生存较为优先,双人场景下竞争为主要地位。
综合以上信息给出一个方向即可。
→ 📖 Q3.4(P) 请说明针对该任务,你们采取了哪些策略来优化决策。具体而言,怎么避免死亡?怎么吃到更多果子?如何编程实现。
首先需要计算离蛇头最近的果子,如果有多个,则全部记录下来。
创建一个数组记录四个方向的优越性,对于某一个最近的果子,如果其在蛇头的右上,则右和上各加一分。
对四个方向的分数排序,作为最初判断方向优越性的标准,这样的方法可以尽可能快的吃到一个最近的果子,相较于直接选定一个最近果子,这样的方式在有多个最近果子时,可以给出一个最快接近尽可能多最近果子的方法。并且设想如果有多个最近果子,直接选定一个最近果子的方式给出一个最优方向,但是该方向有第一节蛇身阻挡(或其他蛇)的情况,便会无法判断哪个方向更好,只能勉强从两个垂直方向随机选一个。但是像本算法这样综合其他最近果子的数据的方式,可以在这样的前提下给出一个除阻挡方向以外的较好的方向,使得选择不再那么单一。
然后将蛇头不可以前往的方向,比如第一节蛇身的方向,墙壁(如果靠墙)的方向,其他蛇的蛇头或前两节蛇身所在的位置的方向(如果紧贴蛇头)。
这些方向作为禁止方向,将其首先排除,如果排除后无结果,则说明必死无疑,因此随意选择一个方向结束。
之后对于非禁止的方向判断危险方向,危险方向即如果某个蛇头距离自己的蛇的蛇头只隔一个位置,那么这个蛇可能与蛇头相撞,具体来说如果在右上角有其他蛇的蛇头,则右和上作为危险方向。
如果不存在安全方向,则在危险方向里选择优越性最高的,否则选择安全方向之中优越性最高的。
对于多蛇场景,生存更重要,因为如果早早和别的蛇同归于尽只会双输,因此优先选择安全方向。
然而如果图中只剩一条其他的蛇,则预判规避对方的头往往会导致能吃到的果子更少,在竞争中处于劣势,因此如果只剩两条蛇则不会考虑危险方向,直接选择非禁止方向中的最优解。这样更可能压制对方的吃果子速度,如果同归于尽也没关系,因为分数往往可能占优。
软件度量
→ 📖 Q3.5(P) 请说明你们如何量度所实现的程序模块的有效性,例如:“如何说明我们的程序模块对弈能力很强?”尝试提出一些可能的定量分析方式。考虑到棋盘的随机性很大,少量对局的结果往往不能反映出竞争能力的强弱,因此所有的分析都建立在100局对局的基础上。
-
首先是判断吃果子的速度,不妨将两个分别以修改前的保守吃果策略和修改后的激进吃果策略的蛇放在一个棋盘之中,测量其胜出的对局,结果激进吃果以62:38胜出
-
然后判断综合考量最近果子信息是否有优势,将两个保守型且分别以单个贪心和综合贪心为吃果策略的蛇放在一个棋盘之中,综合贪心以55:45胜出。
-
最后将蛇与某自称小王老师的同学进行对战,两蛇局和四蛇局分别测试了30局,双蛇局大致打平,四蛇局碾压获胜(主要因为多蛇情况下优先生存)。
总结
→ 📖 Q3.6(P) 请记录下目前的时间,并根据实际情况填写 附录A:基于 PSP 2.1 修改的 PSP 表格 的“实际耗时”栏目。
2025.4.5 20:44
见Chapter.3附录
→ 📖 Q3.7(I) 请写下本部分的心得体会。
在本环节中,我们历经多次版本的修改,期间还和其他同学的贪吃蛇策略进行了测试比赛,在一步步修改中逐渐优化贪吃蛇的策略,在本环节与结对的同伴合作密切,真正体会到了结对的优势。
Chapter.3附录
| Personal Software Process Stages | 个人软件开发流程 | 预估耗时(分钟) | 实际耗时(分钟) |
|---|---|---|---|
| PLANNING | 计划 | ||
| - Estimate | - 估计这个任务需要多少时间 | 5 | 5 |
| DEVELOPMENT | 开发 | ||
| - Analysis & Design Spec | - 需求分析 & 生成设计规格(确定要实现什么) | 10 | 10 |
| - Technical Background | - 了解技术背景(包括学习新技术) | 10 | 5 |
| - Coding Standard | - 代码规范 | 5 | 5 |
| - Design | - 具体设计(确定怎么实现) | 40 | 120 |
| - Coding | - 具体编码 | 90 | 160 |
| - Code Review | - 代码复审 | 5 | 5 |
| - Test Design | - 测试设计(确定怎么测,比如要测试哪些情景、设计哪些种类的测试用例) | 10 | 10 |
| - Test Implement | - 测试实现(设计/生成具体的测试用例、编码实现测试) | 20 | 20 |
| REPORTING | 报告 | ||
| - Quality Report | - 质量报告(评估设计、实现、测试的有效性) | 10 | 10 |
| - Size Measurement | - 计算工作量 | 5 | 5 |
| - Postmortem & Process Improvement Plan | - 事后总结和过程改进计划(总结过程中的问题和改进点) | 5 | 5 |
| TOTAL | 合计 | 215 | 360 |
结对项目总结
结对过程回顾和反思
→ 📖 Q4.1(P) 提供两人在讨论的结对图像资料。

→ 📖 Q4.2(P) 回顾结对的过程,反思有哪些可以提升和改进的地方。
结对初期两人的合作并不熟练,略偏离结对的实践方向,而是两个人分别完成自己的任务,团队内交流较少,随着结对任务的进行与两人的逐步了解结对过程中的交流逐渐增多,流程逐渐规范。
→ 📖 Q4.3(I) 锐评一下你的搭档!并请至少列出三个优点和一个缺点。
优点:时间充足,踏实肯干,很好相处
缺点:比较腼腆,不太放得开
对结对编程的理解
→ 📖 Q4.4(I) 说明结对编程的优缺点、你对结对编程的理解。
优点:结对编程通过双人协作实现思维互补,既能集中资源快速推进任务,又能在编写过程中实时交叉验证代码逻辑,从源头降低代码缺陷率。两人在持续交流中碰撞技术思路,既能加速知识传递,也能拓宽解决问题的视角,形成良性互促的学习循环。
缺点:由于两位开发者需全程同步参与同一任务,短期来看可能牺牲并行开发效率,尤其在简单任务中易产生资源浪费。双方若存在技术认知差异或沟通风格冲突,可能导致决策效率下降甚至协作摩擦,同时持续高强度的协作容易引发注意力疲劳,影响长期工作节奏。
以我的实践经验来看,结对编程更适合技术方案复杂、容错率低的紧急任务,例如系统核心模块改造或线上问题攻坚。这种情况下,两位技术背景互补、协作默契的开发者搭档(如业务逻辑专家与性能优化能手)能形成合力,既保障交付质量,又避免单人决策盲区。