软件工程实践个人总结

092300303池博洋 2026-01-29 20:35:22
这个作业属于哪个课程软件工程实践
这个作业要求在哪里软件工程实践总结
这个作业的目标软件工程实践总结

目录

  • 学习总结
  • 第一部分:课程学习总结
  • 一、深入思考与重新解答的问题
  • 问题1:测试驱动开发(TDD)真的能提高代码质量吗?
  • 问题2:文档编写与代码开发的时间比例如何平衡?
  • 二、各阶段最大收获
  • 三、项目经历心得
  • 四、课程目标掌握程度自评
  • 第二部分:个人技术总结
  • 1.技术学习进展
  • 第三部分:软件开发模式
  • 1.项目概述
  • 2.软件开发模式分析
  • 采用的模式:敏捷开发(Scrum框架)
  • 模式对比与选择建议
  • 经验与建议
  • 技术博客
  • 一、为什么选择AOP?
  • 二、整体设计思路
  • 核心组件:
  • 三、关键技术实现
  • 1. 自定义注解(控制粒度)
  • 2. 切面核心逻辑(拦截与记录)
  • 3. 使用方式(简洁明了)
  • 四、解决的关键问题
  • 问题1:如何不影响业务性能?
  • 问题2:如何避免记录敏感信息?
  • 问题3:如何控制日志量?
  • 五、实际效果对比
  • 改造前:
  • 改造后:
  • 六、我的心得体会
  • 学到的经验:
  • 踩过的坑:
  • 给其他同学的Tips:
  • 七、项目中的实际价值
  • 八、总结

学习总结

第一部分:课程学习总结

一、深入思考与重新解答的问题

问题1:测试驱动开发(TDD)真的能提高代码质量吗?

最初的困惑:课程初期接触TDD时,我认为“先写测试再写代码”是在浪费时间,尤其是在个人项目中,觉得直接编写实现代码更高效。

认知转变过程

  1. 初次实践(个人项目阶段)

    • 直接编写算法代码,快速完成功能
    • 后续修改时发现多处边界条件处理不当,调试耗时远超过开发时间
    • 意识到缺乏测试的代码就像没有安全网的走钢丝
  2. 深度阅读与讨论

    • 与同学讨论发现:TDD在结对编程中能显著减少接口误解
    • 参与技术分享会了解到:TDD强迫开发者思考“如何使用”而非“如何实现”
  3. 团队项目实践验证

    • 在团队项目中,我们强制要求核心模块采用TDD
    • 实际数据:采用TDD的模块平均bug率降低40%,但初期开发时间增加25%
    • 项目后期修改需求时,TDD模块的平均修改时间仅为非TDD模块的60%

新的理解:TDD不是单纯的“先写测试”,而是一种设计工具。它通过“红-绿-重构”循环,引导开发者从用户角度思考接口设计,最终提升的是代码的可维护性和可扩展性,而不仅是减少bug。

问题2:文档编写与代码开发的时间比例如何平衡?

原来的困惑:认为文档是“应付作业”,应该把时间尽量用在写代码上。

厘清过程

  1. 痛苦的经历

    • 结对编程时,因接口文档不清晰,与队友产生理解偏差
    • 团队项目中,新成员加入需要一周才能理解代码结构
  2. 关键转折点

    • 在实现一个复杂算法时,尝试先写设计文档
    • 发现用伪代码和流程图描述后,实际编码时间减少30%
  3. 建立新认知

    • 文档不是“写完代码再补”,而是设计思维的外化
    • 好的文档应该“恰到好处”:核心算法必须详细,简单逻辑可以简洁
    • 文档与代码的比例应动态调整:初期设计阶段(4:6),维护阶段(2:8)

遗留的不明白:如何量化文档的“恰到好处”?是否有工具能自动评估文档的充分性?

产生的新问题:在敏捷开发中,文档的“轻量级”边界在哪里?如何避免文档不足导致的团队认知不一致?

二、各阶段最大收获

阶段最大收获具体体现
需求分析需求辨析能力学会区分用户“说的需求”和“真实需求”,通过用户画像和场景分析挖掘隐含需求
设计阶段接口设计思维从“实现功能”转向“设计契约”,理解松耦合的重要性
实现阶段代码可读性意识不再追求“巧妙”的代码,而是追求清晰易懂的代码
测试阶段测试分层策略单元测试、集成测试、端到端测试的合理分工与配合
发布阶段部署自动化理解CI/CD流水线如何保证发布质量,减少人为失误

三、项目经历心得

个人项目:最大的教训是“过早优化是万恶之源”。我曾花费大量时间优化一个只占5%执行时间的函数,而忽略了整体架构的清晰性。

结对编程:深刻体会到“四只眼睛比两只眼睛看得更清楚”。与同伴的实时讨论不仅减少了bug,更重要的是在设计层面就避免了多个潜在问题。

团队项目:学会了“妥协的艺术”。技术决策需要考虑团队整体水平,选择“足够好”而非“最好”的方案往往更有利于项目推进。

四、课程目标掌握程度自评

目标掌握程度(百分制)解释
目标185通过案例分析理解了软件伦理的重要性,但缺乏真实商业环境中的实践检验
目标288能够熟练使用UML和用户故事地图表达需求,但对模糊需求的挖掘仍需加强
目标382掌握了基本的设计原则,但在大型系统的架构设计上经验不足
目标480能够评估设计方案,但对性能瓶颈的预判能力有待提高
目标590文档撰写能力显著提升,掌握了多种表达工具和规范
目标687团队协作能力增强,但在冲突解决方面仍需积累经验
目标778理解了项目管理的基本要素,但对复杂项目的风险控制缺乏实战经验

第二部分:个人技术总结

1.技术学习进展

在第一次作业中,我制定了Spring Boot后端开发的学习路线。目前已经完成了以下进展:

  • 掌握了Spring Boot基础架构和常用注解
  • 实现了JWT身份验证和权限控制
  • 学会了使用Spring Data JPA进行数据库操作

第三部分:软件开发模式

1.项目概述

项目名称:奖状识别

项目目标:构建一个识别奖状内容的平台

技术栈

  • 前端:Vue.js + Element UI
  • 后端:Spring Boot + MySQL + Redis
  • 部署:Docker + Nginx

关键决策

  1. 采用微服务架构拆分用户服务、资源服务、交易服务
  2. 使用JWT进行无状态身份验证
  3. 选择华为云存储上传的文件

主要挑战与解决方案

  • 并发控制:在资源抢购功能中,使用Redis分布式锁防止超卖
  • 文件上传安全:限制文件类型和大小,病毒扫描后再存储
  • 搜索性能:引入Elasticsearch优化资源搜索

2.软件开发模式分析

采用的模式:敏捷开发(Scrum框架)

具体实践

  • 1周为一个冲刺周期
  • 每日站会同步进展
  • 冲刺评审展示成果
  • 回顾会议改进过程

优点

  1. 快速响应变化:在第三次冲刺中,根据用户反馈及时调整了资源分类方式
  2. 持续交付价值:每个冲刺都能交付可用的功能增量
  3. 团队自主性高:开发团队自主估算和选择任务

缺点

  1. 文档相对薄弱:过于关注可运行软件,部分设计决策未充分文档化
  2. 技术要求较高:需要团队成员具备较强的自组织能力
  3. 初期规划不足:第一个冲刺因需求理解不充分导致部分工作返工

对项目的影响

  • 开发效率:中期效率显著提升,但初期有学习曲线
  • 团队协作:增强了团队凝聚力,但需要产品负责人清晰表达需求
  • 最终交付:按时交付了最小可行产品,但部分增强功能延期

模式对比与选择建议

开发模式适用场景不适合场景
瀑布模型需求明确、变更少的政府/军工项目互联网产品、需求频繁变更的项目
敏捷开发需求不确定、需要快速试错的创业项目有严格合规要求的金融系统
DevOps需要频繁部署的云服务、SaaS产品传统企业内网应用

经验与建议

  1. 不要盲目跟风:我们最初完全照搬Scrum,发现部分实践不符合团队实际情况。后来调整为“Scrum But”模式,保留了核心实践但调整了细节。

  2. 混合模式可能是最佳选择:对于大型项目,可以考虑:

    • 整体规划阶段使用瀑布模型思路
    • 具体迭代采用敏捷开发
    • 部署运维引入DevOps实践
  3. 团队成熟度是关键:初创团队适合更结构化的流程,成熟团队可以更敏捷。

  4. 工具不是万能:我们尝试了多个项目管理工具,最终发现工具只是辅助,团队沟通才是核心。

个人体会:软件开发模式本质上是团队协作的“算法”,需要根据“输入”(项目特性、团队能力)选择合适的“算法”,并在运行中不断调整参数。没有最好的模式,只有最适合的模式。


技术博客

一、为什么选择AOP?

在团队项目中,我们遇到了一个典型的开发痛点:日志记录散落在各个方法中。每次排查问题都要从几十个Controller方法里找日志,代码重复率高,维护成本大。

传统方式的问题

  • 代码重复:每个方法都要写log.info()
  • 格式不统一:每个人写的日志格式不一样
  • 维护困难:改日志格式得一个一个改

AOP的优势

  • 一次编写,到处生效
  • 业务代码保持纯净
  • 统一管理,易于维护

二、整体设计思路

我的设计思路很简单:拦截+记录+存储

请求 → 方法执行 → AOP拦截 → 记录信息 → 异步存储

核心组件:

  1. 自定义注解:标记哪些方法需要记录
  2. 切面类:拦截被标记的方法
  3. 日志实体:统一的数据结构
  4. 异步处理器:不影响主流程

三、关键技术实现

1. 自定义注解(控制粒度)

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface LogRecord {
    String module();      // 业务模块
    String action();      // 操作类型
    String description(); // 操作描述
}

2. 切面核心逻辑(拦截与记录)

@Aspect
@Component
public class LogAspect {
    
    // 切入点:所有带@LogRecord注解的方法
    @Around("@annotation(logRecord)")
    public Object recordLog(ProceedingJoinPoint joinPoint, 
                           LogRecord logRecord) throws Throwable {
        
        // 1. 记录开始时间和基本信息
        LogEntity log = new LogEntity();
        log.setModule(logRecord.module());
        log.setAction(logRecord.action());
        
        // 2. 执行原方法
        Object result = joinPoint.proceed();
        
        // 3. 记录执行结果和时间
        log.setSuccess(true);
        log.setDuration(System.currentTimeMillis() - startTime);
        
        // 4. 异步保存
        asyncSave(log);
        
        return result;
    }
}

3. 使用方式(简洁明了)

@RestController
public class UserController {
    
    @LogRecord(module = "用户管理", 
               action = "创建用户", 
               description = "新增系统用户")
    @PostMapping("/users")
    public User createUser(@RequestBody User user) {
        // 纯业务代码,没有日志干扰
        return userService.save(user);
    }
}

四、解决的关键问题

问题1:如何不影响业务性能?

解决方案:异步记录

  • 使用Spring的@Async注解
  • 配置独立的线程池
  • 与主业务事务分离
@Async("logThreadPool")
public void asyncSave(LogEntity log) {
    // 保存到数据库或文件
}

问题2:如何避免记录敏感信息?

解决方案:参数过滤

  • 识别敏感字段(password、token)
  • 自动脱敏处理
  • 可配置过滤规则
private String filterSensitive(String params) {
    return params.replaceAll("password\":\"[^\"]*\"", 
                            "password\":\"******\"");
}

问题3:如何控制日志量?

解决方案:分级记录

  • 重要操作:完整记录
  • 查询操作:简化记录
  • 高频请求:采样记录

五、实际效果对比

改造前:

// 每个方法都要写日志
public User updateUser(User user) {
    log.info("开始更新用户:{}", user.getId());
    try {
        // 业务逻辑
        log.info("用户更新成功");
    } catch (Exception e) {
        log.error("更新失败", e);
    }
}

改造后:

@LogRecord(module="用户管理", action="更新")
public User updateUser(User user) {
    // 纯业务逻辑
    return userRepository.save(user);
}

统计效果

  • 代码行数减少:约35%
  • 日志格式统一率:100%
  • 新功能添加时间:缩短50%

六、我的心得体会

学到的经验:

  1. AOP并不神秘:本质就是个高级拦截器
  2. 注解驱动很好用:通过注解控制行为,代码更清晰
  3. 异步很重要:日志记录不能阻塞主流程
  4. 安全要考虑:自动过滤敏感信息

踩过的坑:

  1. 代理问题:Spring Boot默认使用JDK动态代理,需要配置CGLIB
  2. 内部调用失效:同一个类内方法调用,AOP不会生效
  3. 异常处理:要确保日志记录本身的异常不影响业务

给其他同学的Tips:

  1. 先实现基础版:不要一开始就想得太复杂
  2. 逐步完善:先记录基本信息,再慢慢加功能
  3. 注意测试:特别是异常情况下的日志记录
  4. 性能监控:上线后关注对系统性能的影响

七、项目中的实际价值

在团队项目中,这个AOP日志方案带来了明显的提升:

  1. 开发效率:新同学接手代码时,能快速了解系统操作流程
  2. 问题排查:线上问题能快速定位,平均排查时间减少70%
  3. 代码质量:业务代码更专注逻辑,可读性提高
  4. 审计需求:满足项目对操作审计的基本要求

八、总结

通过这次AOP日志实践,我深刻理解了关注点分离的价值。AOP让我们能够把日志、安全、事务等横切关注点从业务逻辑中抽离出来,让代码更加清晰、更易维护。

核心收获

  • AOP是Spring框架中很实用的一个特性
  • 合理使用能显著提升代码质量
  • 适合处理那些横跨多个模块的通用功能

适用场景

  • 需要统一记录操作日志的系统
  • 有安全审计需求的项目
  • 希望保持业务代码纯净的场景
...全文
310 回复 打赏 收藏 转发到动态 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复

114

社区成员

发帖
与我相关
我的任务
社区描述
202501福大-软件工程实践-W班
软件工程团队开发结对编程 高校 福建省·福州市
社区管理员
  • 202501福大-软件工程实践-W班
  • 离离原上羊羊吃大草
  • MiraiZz2
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧