[I.3] 个人作业:结课总结
| 项目 | 内容 |
|---|---|
| 这个作业属于哪个课程 | 软件工程 |
| 这个作业的要求在哪里 | [I.3] 个人作业:结课总结 |
| 我在这个课程的目标是 | 掌握软件工程的核心理论,协作完成软件项目开发 |
| 这个作业在哪个具体方面帮助我实现目标 | 回顾整个《软件工程》课程的开发过程,梳理自己在软件工程各阶段中获得的成长 |
一、提问回顾
链接到以前提问题的博客:[I.1] 个人作业:阅读和提问
Q1:MVP方法在什么情况下具有实际可行性?
MVP的核心目的不是验证这个功能是否完美,而是验证这个方向是否值得继续投入。点击量本身确实不能直接证明付费意愿,但它是一个低成本的方向信号,如果连点击的人都没有,那连讨论付费意愿的资格都没有。
在团队项目中,我们实际上也运用了MVP方法。在Alpha阶段,我们的功能并不完整,而是先用最简化的方式实现了核心流程,达到能快速让部分用户试用的效果。这个过程中我们发现,MVP的价值不在于它收集到的数据有多精确,而在于它能让你以最小的代价知道用户感兴趣的方向,让我们知道哪些功能有继续优化、继续付出的必要性。
其实,用户对体验缺陷的容忍度比我们想象的要高。只要明确告知用户这是早期测试版本,即使页面简陋,他们也愿意去尝试感兴趣的功能。他们更在意的是核心价值是否被验证,而不是界面是否精美。
Q2:非功能性需求的优先级判断标准是什么?
非功能性需求的优先级没有一个固定的标准,而是取决于具体的业务场景和利益相关者的诉求。
判断优先级时通常需要考虑几个维度,如涉及用户隐私和资金安全的需求通常具有最高优先级,而如果系统的核心使用场景对响应速度有刚性要求,那么响应速度的优先级就要高于并发。
很多时候不需要做二选一,而是可以通过架构设计寻找平衡点。非功能性需求也可以分阶段满足,第一版保证基础达标,后续迭代逐步强化。在我们的项目中,我们采用了核心功能保响应,非核心功能保稳定的策略。用户最常使用的操作路径优先保证速度,而一些低频操作则可以容忍稍长的等待时间。
Q3:我们应该如何平衡创新与调研之间的矛盾?
用户调研和产品愿景不是非此即彼的对立关系,而是互补的。核心是区分创新类型,用对调研方法。
如果是渐进式优化或者成熟的品类,用户调研价值极高。这类场景下,用户非常清楚自己的痛点,调研能精准指导迭代。而如果是颠覆性创新或者全新的品类,用户无法给出功能答案,但能暴露底层需求。福特的例子里,用户说要更快的马,表层诉求是马,底层需求是提升出行效率。而理解了更快更稳定这个深层需求后,才有可能想到汽车。
在团队项目中,我们既做了用户调研了解现有痛点,也保留了自己的产品判断。日常迭代以用户调研为核心做优化,同时预留少量资源做探索性创新,用MVP方法快速验证创新方向是否可行。
Q4:怎样动态调整产品功能的四个象限?
功能的象限定位不是一次性的分类工作,而应该成为每次迭代规划时的常规思考环节。
我们应该定期复盘,在每次迭代结束时,重新审视各个功能在当前市场环境和用户需求下的定位。对于已成“必要需求”的"前杀手功能",做不好用户会流失,但做好了也不会成为差异化优势。因此保持维护即可,将主要资源投向寻找和构建新的差异化功能,不要因为曾经投入了很多就舍不得放手,功能的象限定位变了,策略也要跟着变。
在项目迭代过程中,我们确实经历了功能定位的变化。最初我们认为运势模块的AI化是杀手功能,但随着开发的推进和用户反馈的收集,我们发现竞争对手也有类似功能,它逐渐变成了必要需求。我们项目后续就将重心从AI化转向了个性化,尝试构建新的差异化竞争力。
Q5:定义典型用户和场景是否容易变成一种形式主义的练习?
凭空编造的典型用户必然是形式主义,但基于真实调研提炼的典型用户对团队开发有很大帮助。
在团队项目中,我们一开始定义的典型用户确实比较模式化,年龄、职业、使用场景等都很笼统。但当我们做了一轮简单的用户调研后,再回头看之前定义的典型用户,发现很多假设都被推翻了。比如我们以为用户最关心的模块会是运势看板,但实际上他们最感兴趣的是答案之书部分。于是我们重新修改了典型用户的描述,加入了更多从真实用户那里获得的行为模式和痛点描述。
多人协作时,每个人心中的用户形象都不一样,典型用户能把抽象的用户具象化,大幅降低沟通成本。后续讨论功能时,大家都会以 “这个功能对典型用户张三有没有用” 为标准,彻底避免了 “我觉得用户需要” 的无效争论。
Q6:图形建模工作是否真的必要?
图形建模的价值在于它是一种低成本的沟通工具,在画图阶段发现问题,修改的成本远比在代码阶段发现问题要低得多。
对于复杂的模块间交互,画一个时序图能极大地帮助团队对齐理解,但对于简单的CRUD操作,口头沟通就够了。中小型敏捷团队不需要画全套UML图,只需要针对核心、易歧义的模块做轻量建模。
对于团队协作中的关键设计决策,图形化建模是非常有价值的沟通工具;但如果只是为了完成文档要求而画图,那确实会变成形式主义。
二、未解决的问题
问题大多在实践中得到了答案,但Q3中关于颠覆性创新的部分仍有困惑。
我们在课程中接触的都是渐进式的产品优化,对于从零到一的颠覆性创新,如何系统化地培养产品洞察力、如何科学地验证颠覆性方向的可行性,仍然没有可落地的方法论,似乎更多依赖核心成员的个人经验与直觉。我还不清楚是否存在什么流程或者方法可以降低颠覆性创新的失败概率。
三、新的问题
Q1:如何平衡临时的需求变更与既定的功能迭代?
在敏捷迭代中,我们经常会遇到临时的bug修复,往往需要立刻投入人力,而我们原本迭代计划里已经安排了既定的功能迭代。两者冲突时,二者应该如何平衡优先级?有没有明确的判断标准?
Q2:如何评估重构的投入产出比,以及选择什么时机启动重构最合适?
软件维护阶段,我们会发现原有的代码存在性能问题,已经无法通过简单的代码增删完成性能优化或者新功能的要求。这时候大家都知道应该重构,但重构本身耗时耗力,还可能引入新问题。那么,怎么评估重构的投入产出比,什么时候启动重构才是最佳时机?
四、各阶段学到的知识点
需求阶段
在需求分析阶段,我学到的最重要的知识点是如何将用户需求转化为可执行的用户故事,并进行优先级排序。
我们要区分用户需求表层诉求与底层动机,不能用户说什么就做什么,要挖掘诉求背后的真实痛点。
我们通过MoSCoW方法对需求进行分级,确保核心功能优先开发,在Alpha阶段优先实现MVP。这个方法让我们在Alpha阶段就能实现核心功能,获取第一批用户的使用体会,继而去调整Beta阶段的开发重点。
设计阶段
在设计阶段,我深刻体会到了模块化设计和接口约定的重要性。
在Alpha阶段时,前期后端API文档不够详细,字段类型、错误码格式、分页参数都没有统一定义,导致前后端接口对接时频繁返工。在Beta阶段我们痛定思痛,召开会议,会上前后端先共同制定API契约,文档确认无误后再分头开发。这次开发效率明显提升,前后端并行推进,联调时几乎没有前后端不匹配的问题。
实现阶段
团队制定了统一的Git规范、开发日志、PR流程和提交规范,确保代码风格一致、变更可追溯。这看起来是小事,但在实际协作中,统一的代码风格大大降低了阅读理解的成本,代码审查的效率也明显提高。
测试阶段
只测正常操作只能验证功能能不能跑,而空数据、非法输入、极端并发等边界场景,才能测出系统的可靠性。我们项目前期只测正常流程,所有接口都能返回正确结果,我们一度以为系统很稳定。后期专门补充了边界测试,找出了很多会导致系统崩溃的隐藏问题。
发布阶段
先让小范围用户试用,发现问题及时回滚,能避免全量上线后出现大规模故障。
我们采用了分批次发布的方式,在正式公开推广前,我们先邀请小范围同学进行测试,将心运岛部署到云服务器,邀请了30名左右目标用户进行测试,观察没有问题后再逐步扩大范围。
同时准备了快速回滚的方案,一旦发现严重问题,可以在几分钟内恢复到上一个稳定版本。在Beta阶段正式发布前,我们发现最新版本的个性化部分调用大模型实现的效果并不好,紧急回滚到了前一个版本,保证在规定时间上线项目。
维护阶段
我们团队在项目上线初期并没有很重视日志,觉得功能跑通了就没必要再加一堆打印语句。直到有一天,运势看板中的爱情、健康四个运势显示成了占位符,但我们自己反复测试都复现不了,完全一头雾水。有了这次教训,我们系统地完善了日志体系,并接入了简单的监控面板。
在项目上线后,我们通过日志记录了用户的操作行为和系统异常,这些数据不仅帮助我们发现和定位问题,还为后续的需求迭代提供了依据,哪些功能用户用得最多、哪些流程最容易出错,都一目了然。
五、心得体会
个人项目
这一阶段的上机作业虽然单个规模不大,但四个实验精准对应了软件工程不同维度的基础能力,是我从写代码向做工程转变的入门起点。个人项目最核心的价值在于,全程没有队友可以依赖,每一个报错、每一处逻辑漏洞、每一个卡壳的难点,都必须自己定位、自己推导、自己解决。
Lab1纠正了我粗放的编码习惯,让我意识到规范的命名与排版是降低维护成本的基础。Lab2的UML类图设计让我体会到先设计后编码的价值,前置梳理结构能大幅减少后期返工。Lab3的Java编程训练了我在既定框架下实现复杂逻辑的能力,学会在统一规范内落地需求。Lab4的项目运行调试,则补上了环境配置与问题排查的短板,锻炼了我独立定位、解决问题的能力。
这段全独立的开发经历让我明白,单人开发是夯实底层能力的必经之路。没有外部依赖反而能逼自己直面所有知识盲区,把每个知识点都扎实转化为自身的工程基本功。
结对编程
在结对编程中,我们第一次体会了驾驶员与领航员轮换的模式。写代码的人专注于功能实现,旁观的人跳出细节把控整体逻辑,能及时发现逻辑漏洞、边界遗漏和设计偏差。
在个人项目中,写错了一个变量名可能半天才发现,而在结对中,同伴可能在你刚敲完那一行就指出问题。这种即时性极大地提高了代码质量,最终成品的bug率比我单人开发时低了很多。
但协作过程也并非一帆风顺。我们两人的编码风格、命名习惯差异很大,互相阅读代码时效率极低,经常在变量命名、代码排版这类琐事上耗费时间。直到我们先统一了编码规范,再正式开始开发,配合效率立刻有了明显提升。
结对编程表面上是技术合作,本质上是一场持续的沟通练习。 你要把自己的思路清晰地讲出来,要能虚心接受别人的质疑,也要能理性地为自己的设计辩护。
团队
团队项目是学期最具分量的环节,也是我从写好代码到做好产品认知转变的关键。
项目初期,大家想实现的功能很多,数据看板、消息通知、权限管理、第三方登录、多语言支持。但时间和人力都有限,必须做减法。我们用功能四象限法对需求逐一筛查,哪些是必须有、哪些是可以有、哪些是以后有,砍掉了一批锦上添花的功能,集中火力保障核心数据展示和基础操作流程。
团队多人并行开发初期,我们没有划清模块职责,接口定义模糊,合并代码时频繁出现冲突,跨模块调用也经常对接失败。直到我们重新梳理了各模块的职责边界,敲定了统一的接口协议,每个人只需保证自己的模块符合接口规范,开发效率和稳定性才大幅提升。
定期站会、迭代复盘这种活动看起来占用时间,实则能尽早发现偏差、及时调整方向,远比最后集中返工的成本低得多。真正的高效,不是闷头猛干,而是用合理的流程保障方向不偏、节奏不乱。
回望整个团队项目,最大的收获不是写了多少行代码,而是完整地经历了一个功能"从需求到上线"的全链路。

浙公网安备 33010602011771号