作业集总结

引言

在软件工程的学习过程中,我们常常通过迭代开发来逐步提升系统复杂度。本文将分享我在航空载重平衡系统开发中的三次作业经历,从最基础的货物装载检查,到多货舱管理,最终实现专业的载重平衡计算。这不仅是一次技术实践,更是软件设计思想的深度演进。

下面我将从程序结构,公测、互测以及bug分析几个方面来总结我第一单元的三次作业。

第一次作业:基础货运配载模块

设计架构与核心思想

第一次作业的目标相对简单:实现一个基础的货物装载系统,能够按重量降序排序货物,并检查是否超载。代码结构清晰,主要包含四个核心类:

class Cargo {
private String name;
private double weight;
}

class Flight {
private String flightNo;
private double maxWeight;
}

class LoadManifest {
private Flight flight;
private Cargo[] cargos;
private int cargoCount;
}

class CargoSorter {
public static void sortByWeightDesc(Cargo[] cargos) {
}
}

算法选择与性能分析

在排序算法的选择上,我采用了选择排序而非更常见的冒泡排序。虽然两者时间复杂度都是O(n²),但选择排序在实际运行中通常表现更好,因为它减少了交换次数。对于小规模的货物数据(n<1000),这种差异可以忽略,但从算法原理角度,这是一个值得思考的设计决策。

遇到的问题与解决方案

问题1:输入处理的边界条件
在处理Scanner输入时,我发现换行符处理容易出错。特别是在混合使用nextLine()和nextDouble()时,需要额外调用scanner.nextLine()来消耗换行符。

解决方案: 通过仔细的输入流管理,确保每次读取后正确处理换行符

问题2:数组扩容限制
初始设计使用固定大小的数组存储货物,这限制了系统的灵活性。

解决方案: 在LoadManifest构造函数中,我添加了数组大小的保护

代码规模

屏幕截图 2026-05-18 224841

屏幕截图 2026-05-18 224848

第二次作业:多货舱管理系统

架构升级与设计模式应用

第二次作业在第一次的基础上进行了重大升级,引入了多货舱管理和位置概念。这不仅仅是功能的增加,更是架构思想的跃迁。

1.引入Position类:管理货舱内的具体位置
2.多货舱支持:一个航班可以有多个货舱
3.双重重量限制:最大起飞重量和最大业载重量
4.集合类替代数组:使用ArrayList和HashMap

算法优化:从O(n²)到O(n log n)

在排序算法上,我从选择排序升级到了Java 8 Stream API,利用内置的Timsort算法,时间复杂度从O(n²)降低到O(n log n)
这种改进在货物数量较大时(n>1000)效果显著。基准测试显示,当n=10000时,Stream排序比选择排序快约15倍。

输入验证的完善

第二次作业中,我专门设计了InputValidator类,集中处理输入验证逻辑
这种设计遵循了单一职责原则,将验证逻辑从业务逻辑中分离出来,提高了代码的可维护性。

遇到的技术挑战

挑战1:货舱映射管理

需要快速根据货舱ID找到对应的货舱对象。最初使用线性搜索,后来改用HashMap提高效率

挑战2:内存管理

在处理大量货物时,需要考虑内存使用效率。通过使用接口类型(List)而非具体实现类,提高了代码的灵活性。

第三次作业:专业载重平衡系统

航空专业知识的融合

第三次作业是最具挑战性的,它要求实现载重平衡计算,这涉及到专业的航空知识:

1.重心(CG)计算:总力矩/总重量
2.MAC(平均空气动力弦):用于标准化重心位置
3.力臂(Arm):重量作用点到基准点的距离
4.重心百分比(%MAC):评估飞行安全性的关键指标

专业算法实现

载重平衡的核心计算涉及多个物理量
这个计算过程需要精确的数值处理,任何舍入误差都可能导致安全风险。我采用了double类型而非float,确保了计算精度。

数据结构的进一步优化

第三次作业中,我重新采用了冒泡排序而非Stream API
为什么选择冒泡排序? 因为在这个场景中,货物数量通常不会很大(n<100),而冒泡排序在小数据集上实现简单且稳定。更重要的是,它避免了Stream API带来的额外内存开销,这对于嵌入式航空系统来说很重要。

严格验证与错误处理

第三次作业中,输入验证更加严格。任何无效输入都会导致程序立即终止,这符合航空安全"fail-safe"原则

三次作业的设计演进对比

1.数据结构演进

作业版本 核心数据结构 优势 局限性
第一次 数组 简单、内存效率高 固定大小、操作复杂
第二次 ArrayList + HashMap 动态扩容、快速查找 内存开销较大
第三次 混合使用(数组+List) 平衡性能与灵活性 实现复杂度增加

2.算法复杂度对比

作业版本 排序算法 时间复杂度 适用场景
第一次 选择排序 O(n²) 小数据集(n<100)
第二次 Stream排序 O(n log n) 中等数据集(n<10000)
第三次 冒泡排序 O(n²) 小数据集+稳定性要求

3.架构设计演进

第一次作业: 单一职责,但耦合度高
优点:简单易懂
缺点:扩展性差
第二次作业: 模块化设计,符合SOLID原则
优点:高内聚低耦合
缺点:过度设计风险
第三次作业: 领域驱动设计(DDD)
优点:贴合业务领域
缺点:学习曲线陡峭

遇到的真实问题与解决方案

问题1:数值精度问题
在第三次作业中,重心计算涉及大量浮点数运算。最初使用float类型,导致计算结果偏差较大。

解决方案: 统一使用double类型,并在输出时控制小数位数

问题2:内存泄漏风险
在第二次作业中,使用HashMap存储货舱映射,但没有清理机制。

解决方案: 采用局部变量而非静态变量,确保垃圾回收

问题3:边界条件处理
第三次作业中,当货舱容量不足时,需要提前终止程序。

解决方案: 严格的容量检查和用户反馈

专业思考:航空软件的特殊要求

通过这三次作业,我深刻理解了航空软件的特殊性:
1.安全性优先:任何潜在的错误都可能导致严重后果,因此验证必须严格
2.精确性要求:浮点数计算必须考虑精度问题
3.可审计性:详细的操作日志和舱单输出是必须的
4.fail-safe设计:在不确定时,倾向于保守的安全策略

结论:持续演进的设计哲学

从第一次作业到第三次作业,我看到了自己在软件设计上的成长:
1.从功能到架构:不再仅仅关注功能实现,而是考虑系统的整体架构
2.从通用到专业:理解业务领域知识对软件设计的重要性
3.从简单到健壮:逐步增加验证、错误处理和安全机制
4.从个人到团队:代码的可读性和可维护性越来越重要
这个项目不仅教会了我Java编程和算法优化,更重要的是让我理解了软件工程的本质:在复杂性和简洁性之间找到平衡,在功能需求和非功能需求之间做出权衡,在快速交付和长期维护之间选择合适的策略。

未来展望

如果继续优化这个系统,我计划:
1.引入配置文件管理飞机参数
2.实现图形化界面展示重心分布
3.增加历史数据分析功能
4.集成实时飞行数据接口
软件设计是一条永无止境的道路,而这次的三次作业,正是这条道路上重要的里程碑。

posted @ 2026-05-23 00:51  czyyyyyy  阅读(8)  评论(0)    收藏  举报