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

项目 内容
这个作业属于哪个课程 https://edu.cnblogs.com/campus/buaa/BUAA_SE_2025_LR
这个作业的要求在哪里 https://edu.cnblogs.com/campus/buaa/BUAA_SE_2025_LR/homework/13465
我在这个课程的目标是 锻炼开发大型软件项目能力,掌握软件工程相关知识
这个作业在哪个具体方面帮助我实现目标 总结课程收获,提高软件工程能力

一、对之前问题的回答

提问博客: [I.1] 个人作业:阅读和提问

问题1:PM为什么不领导开发测试人员

书中认为产品设计需要在平等讨论的基础上进行,但在实际团队协作中,是否真的能做到完全平等的讨论?如果没有明确的决策者,可能会导致决策效率下降,最终影响项目进度。

文章认为 PM 不应该是开发和测试的领导,而是通过写好 Spec 来赢得尊重。但在实际项目中,如果 PM 缺乏领导权,是否可能导致团队执行力不足?尤其在大规模项目中,PM 需要一定的管理权力来确保产品方向的一致性,而不仅仅依赖个人影响力。

在我们团队开发过程中,提前确定了产品的各个功能和整体方向,但在一些小地方还是会出现矛盾。这时候我们选择具体细节以技术为主导,产品经理提出意见,优先保证技术人员熟悉自己负责的部分。

问题2:修改集集成到代码库中的疑问

书中提到互相依赖的任务要一起集成,那么该如何处理任务间的依赖呢?

网上一些资料提到可以使用 Feature Flags(功能开关) 来管理依赖,使得未完成的任务不会影响整体集成;还有的建议采用 分支合并策略,比如 GitFlow 或 Trunk-Based Development,以减少集成冲突。此外,还有一种做法是 Stub 和 Mock,即在依赖任务尚未完成时,使用模拟实现进行测试,避免集成受阻。

如果某个任务的依赖项开发进度落后,而整个项目又有固定的发布时间,应该如何权衡 等依赖完成 vs. 先行集成未完成部分?如果提前集成,如何保证不会影响已有功能的稳定性?

在开发过程中,我们基于分支和PR进行代码库管理与功能集成。每个功能在开发时分配一个以feature/开头的分支名,在完成开发后到dev分支上进行下一步测试。

我们的开发中出现了部分同学由于对技术栈不熟悉开发效率不高,导致进度落后的问题。我们的做法是根据依赖重要性决定是否延迟发布或拆分需求,如果核心功能,则先通过Mock保证进度,让需求方可以立刻使用;如果是非核心功能,则通过Feature Flags控制功能暂不开放,提交合并到dev上。

问题3:单元测试的独立性

单元测试的独立性意味着需要人为构造数据,而代码的复杂逻辑往往依赖于数据库、外部 API 或其他模块的返回值。在这种情况下,如何在保证测试独立性的同时,又能确保测试的真实性和可靠性?

在OO课中,我使用了JUnit对类进行测试;在数据库开发网站后端时,我会使用 JUnit 的 Mock 机制来模拟数据库查询和外部 API 的返回值,这样可以确保测试独立性。但有时候,Mock 的逻辑可能与真实环境的行为有所出入,导致测试通过但在实际运行中出现问题。此外,全面覆盖所有代码路径有时会带来维护成本上升的问题,特别是在代码频繁变化时,测试用例的调整成本较高。

如果单元测试完全依赖 Mock,是否会导致测试结果过于理想化,难以发现真实环境中的潜在问题?另外,对于某些涉及多线程、异步调用或时间依赖的代码路径,单元测试该如何确保覆盖并保持稳定?

在开发的实践中,我们对单元测试并没有100%覆盖率的要求,只需要覆盖业务的核心路径,达到50%即可。为了保证不污染开发环境数据,我们的数据库操作都会在单元测试执行结束后进行回滚。单元测试应该是针对方法、类,范围要尽量小,不应该和其他模块产生耦合。

针对复杂场景,我们进行模块间的集成测试,并综合使用CountDownLatch等工具控制多线程和异步的时序。

问题4:用例设计如何平衡清晰与复杂?

在用例设计中,如何确保主要成功场景既能清晰表达用户需求,又不会因技术细节的加入而变得复杂?

根据Use Case 2.0的原则,主要成功场景应聚焦用户目标,使用自然语言描述交互步骤,避免涉及系统内部逻辑。但是,我实际开发过程中,技术约束和户需求常常是并存的,如果忽略技术细节,往往会造成场景描述的不清晰。

例如,在“用户登录”用例中,主场景描述为“用户输入账号密码后进入主页”,但实际开发中需明确身份验证接口的调用逻辑。如何在扩展场景中补充技术约束,同时保持主场景的简洁性?是否有工具或方法能动态关联主场景与扩展场景,避免文档臃肿?

在我们的文档中,在场景描述上,不出现太多的技术细节,更多是从用户操作的角度说明过程;在接口文档上,需要体现每个接口的功能、实现细节、调用的注意事项(比如权限检查、可能产生的副作用)。

对于一些特别复杂的Use Case(如用户发起聊天到发送消息),专门在技术文档中结合时序图等工具进一步说明。

问题5:压力测试

在Web项目开发中,压力测试主要是指高并发测试,主要需要解决的问题一方面是对数据库高并发访问,另一方面是高并发情况下的线程安全。

有时候可能会牺牲并发量进行请求限流、加锁来限制并发量保证安全性,也可以选择放弃部分安全性提高并发量,这种时候要如何权衡,是改由技术人员衡量还是由产品经理衡量?

书中提到了沿着时间轴增长,但是现代web应用中,后端只需要处理前端的请求,那么沿着时间轴增长这一压力测试方法仍然有效吗,又该怎么实现?

在我们实际进行压力测试的过程中,我们发现沿着时间轴增长这一方式仍然有效,可以很好的代表一种负载较大的情景。我们的系统依赖WebSocket长连接实现消息发送和接收,同时大量用户在线并且用户长时间在线都会导致WebSocket-Service的负载增加。

二、在项目中实践学到的知识点

需求分析

将项目的需求拆分为user story,明确各个需求的优先级,再进一步通过Use Case细化各个功能,确定出口条件。

设计

在设计阶段,我们首先对系统前后端进行了技术选型,确定了各部分的负责的功能。然后进行了系统设计和技术选型,明确各功能实现需要用到的技术、中间件、服务。

在设计时,要充分考虑开发人员的技术栈,不应该一味追求性能或者技术的优越性,应该优先与大多数开发者的能力相匹配,提高开发效率。

实现

采用微服务对业务过程进行解耦,提高合作开发的并行度,提升效率。

采用DDD设计思想,提高模块的可复用性。

使用SpringSecurity进行身份校验和接口权限检查,减少功能相似的重复代码。

测试

对核心方法、类做单元测试,提早发现问题。

发布

在团队项目中,我们进行了CI/CD实践。在提交到代码仓库后触发workflow,构建各个服务的Docker镜像并上传到镜像仓库中,服务器从镜像仓库中拉取最新的镜像并启动。

在这个过程中,我学会了Docker的使用,并对保证项目的安全有了体会。后端的敏感信息(如数据库,加密密钥)不会写在配置文件中上传到代码仓库,而是通过环境变量配置。

同时,我们的后端做了多环境管理和隔离,提供了三套独立环境:local,dev,prod。后端开发人员在local环境上开发,在完成后部署到dev环境供前端使用,最终项目发布时切换到prod,这极大提高了我们的开发效率,保证了数据安全。

维护

  1. 在代码中合理打日志,并在一个请求中通过传递TRACE_ID追踪各个服务的执行情况和调用链
  2. 在网关中异步记录接口执行情况到数据库,在管理员端提供接口进行可视化查询和分析,监控服务负载和健康

三、心得与总结

在结对编程中,我担任领航员,体会到了两人一起合作开发的高效,通过合作我们可以及时发现代码的问题,提高代码质量。

软工给了我第一次合作开发中大型多端应用的机会,在团队开发中,我担任运维和后端开发。由于我们的后端要同时供小程序用户端和web管理端使用,在统一的架构设计和团队沟通上对我有比较大的挑战,在这一过程中极大的提高了我的系统设计能力和沟通能力。同时,我们在后端上通过容器完成了CI/CD,在这个过程中,我初步掌握了Linux环境下服务部署方式,学会了Docker和Github workflow的使用。

posted @ 2025-06-19 15:12  XuanxuanRao  阅读(25)  评论(0)    收藏  举报