第二次blog 题目集8和9分析

一.前言
本篇文章总体分析PTA中题目集8-题目集9:

<1> 题目集8总共3道题目,前2道均为简单题,分别为点线面问题和雨刷问题的扩展继承和多态;第三道题为中等题,为航空货运管理系统的类设计,以及类间关系设计。

<2> 题目集9总共3道题,前两道均为简单题,魔方问题考核抽象类的继承和多态,实现程序的扩展;点线面问题(容器类)考核对容器的使用(ArrayList和LinkedList)实现对点,线和面对象的增删改查和遍历操作;第三道为中等题,为题目集8的航空货运管理系统程序的后续重构以及继承和多态的设计,重点实现对客户类型(Customer),支付方式(PayMethod)和货物类型(Cargo)的泛化处理。
题量中等,不少也不多。

二.设计与分析
题目集8航空货运管理系统题目分析:
输入格式:
客户编号
客户姓名
客户电话
客户地址
运送货物数量
[货物编号
货物名称
货物宽度
货物长度
货物高度
货物重量
]//[]内的内容输入次数取决于“运送货物数量”,输入不包含“[]”
航班号
航班起飞机场
航班降落机场
航班日期(格式为YYYY-MM-DD)
航班最大载重量
订单编号
订单日期(格式为YYYY-MM-DD)
发件人地址
发件人姓名
发件人电话
收件人地址
收件人姓名
收件人电话
输出格式:
① 如果订单中货物重量超过航班剩余载重量,程序输出The flight with flight number:航班号has exceeded its load capacity and cannot carry the order. ,程序终止运行。
② 如果航班载重量可以承接该订单,输出如下:
客户:姓名(电话)订单信息如下:

航班号:
订单号:
订单日期:
发件人姓名:
发件人电话:
发件人地址:
收件人姓名:
收件人电话:
收件人地址:
订单总重量(kg):(货物计费重量总和)(非实际总重量)
微信支付金额:
货物明细如下:

明细编号 货物名称 计费重量 计费费率 应交运费
1 ...
2 ...
输入输出样例1:
C002
张伟
13712345678
北京市朝阳区
4
P001
电子产品
50
30
20
2
P002
办公文具
40
25
15
5
F005
实验器材
30
40
50
12
E003
防护包装
60
60
60
32
CA1501
北京市首都国际机场
上海浦东国际机场
2025-05-10
100
ORD20250424-006
2025-04-24
北京市海淀区中关村
李强
13987654321
上海浦东新区
王芳
15823456789
客户:张伟(13712345678)订单信息如下:

航班号:CA1501
订单号:ORD20250424-006
订单日期:2025-04-24
发件人姓名:李强
发件人电话:13987654321
发件人地址:北京市海淀区中关村
收件人姓名:王芳
收件人电话:15823456789
收件人地址:上海浦东新区
订单总重量(kg):58.0
微信支付金额:1850.0
货物明细如下:

明细编号 货物名称 计费重量 计费费率 应交运费
1 电子产品 5.0 35.0 175.0
2 办公文具 5.0 35.0 175.0
3 实验器材 12.0 35.0 420.0
4 防护包装 36.0 30.0 1080.0
相关数据分析如下:



题目集9航空货运管理系统题目分析:
输入格式:

客户类型[可输入项:Individual/Corporate]
客户编号
客户姓名
客户电话
客户地址
货物类型[可输入项:Normal/Expedite/Dangerous]
运送货物数量
[货物编号
货物名称
货物宽度
货物长度
货物高度
货物重量
]//[]内的内容输入次数取决于“运送货物数量”,输入不包含“[]”
航班号
航班起飞机场
航班降落机场
航班日期(格式为YYYY-MM-DD)
航班最大载重量
订单编号
订单日期(格式为YYYY-MM-DD)
发件人地址
发件人姓名
发件人电话
收件人地址
收件人姓名
收件人电话
支付方式[可输入项:Wechat/ALiPay/Cash]

输出格式:

客户:姓名(电话)订单信息如下:

航班号:
订单号:
订单日期:
发件人姓名:
发件人电话:
发件人地址:
收件人姓名:
收件人电话:
收件人地址:
订单总重量(kg):
[微信/支付宝/现金]支付金额:

货物明细如下:

明细编号 货物名称 计费重量 计费费率 应交运费
1 ...
2 ...

输入输出样例1:

Individual
C004
陈明
19676543210
广州市天河区
Dangerous
7
E001
精密仪器
60
80
100
110
E002
实验器材
30
40
50
12
E003
防护包装
60
60
60
32
J001
电子产品
30
40
20
2.5
J002
机械配件
55
75
40
28
J003
办公设备
60
80
100
72
J004
宣传资料
25
35
5
0.7
MU5302
广州白云国际机场
成都双流国际机场
2025-05-12
3000
ORD20250412-003
2025-04-12
广州市越秀区环市东路368号
赵敏
13766523212
成都市武侯区人民南路四段1号
周涛
15478965432
Wechat

客户:陈明(19676543210)订单信息如下:

航班号:MU5302
订单号:ORD20250412-003
订单日期:2025-04-12
发件人姓名:赵敏
发件人电话:13766523212
发件人地址:广州市越秀区环市东路368号
收件人姓名:周涛
收件人电话:15478965432
收件人地址:成都市武侯区人民南路四段1号
订单总重量(kg):270.7
微信支付金额:8224.5

货物明细如下:

明细编号 货物名称 计费重量 计费费率 应交运费
1 精密仪器 110.0 20.0 2200.0
2 实验器材 12.0 80.0 960.0
3 防护包装 36.0 50.0 1800.0
4 电子产品 4.0 80.0 320.0
5 机械配件 28.0 50.0 1400.0
6 办公设备 80.0 30.0 2400.0
7 宣传资料 0.7 80.0 58
相关数据分析:


三.采坑心得:

题目集9航空运输管理系统:
遇到的小问题:
未校验客户类型 . 货物类型 .支付方式的合法性(如输入非 Individual/Corporate)
货物数据与客户 .订单数据结构关联混乱
输入货物数量为 0 时,程序崩溃或输出异常
航班最大载重量为负数时未校验
货物尺寸为负数时未处理
学会了:
输入验证的重要性:未校验输入导致程序在异常数据下崩溃
数据结构设计优先:前期设计好类关系可避免后期重构
分模块测试:先测试计费逻辑,再集成输入输出模块
日期格式解析错误(如 2025-05-03 未被识别为非法日期)
题目集8航空运输管理系统:
遇到的小问题:
货物的计费重量需取 实际重量 与 体积重量(长 × 宽 × 高 ÷6000) 的最大值,但我误取最小值或忽略体积重量计算。
输入 运送货物数量 后,未按次数循环读取货物信息,导致数据错位或遗漏

学会了:
输入输出流程控制:健壮性处理
掌握输入校验逻辑:
对必填项、类型、格式进行全面校验,避免程序因非法输入崩溃
业务逻辑实现:复杂规则拆解
拆解问题:
将 “计算订单总运费” 拆解为 “单个货物计费重量计算”→“费率匹配”→“运费累加” 三个子步骤。
掌握条件判断与循环:
使用 if-else 判断载重是否超限,使用 for 循环处理多个货物信息。

四.改进建议:

1增强封装性
将类属性设为 private,通过 getter/setter 访问。
对敏感数据(如电话、地址)增加校验逻辑。
使用枚举管理固定值
客户类型、货物类型、支付方式用枚举替代字符串比较。
为枚举添加属性(如费率),减少硬编码。
分层设计
分离数据模型(如 Cargo、Customer)与业务逻辑(如 OrderProcessor)。
用工厂模式创建对象,简化初始化逻辑。
2输入输出处理
输入校验
对数值范围(如重量、尺寸)、格式(如日期、电话)、类型(如枚举值)严格校验。
用正则表达式验证字符串格式(如日期 YYYY-MM-DD)。
异常处理
使用 try-catch 捕获输入异常(如非数字、日期解析错误)。
提供友好的错误提示并允许用户重试。
输出格式化
使用 printf 或 String.format 对齐表格数据(如货物明细)。
统一数值精度(如金额保留 1 位小数)。
3业务逻辑优化
计费规则抽象化
将计费逻辑(体积重量计算、费率匹配)封装到独立方法或类中。
通过配置文件或数据库动态管理费率,避免硬编码。
流程控制简化
使用状态模式管理订单处理流程(如创建、校验、支付)。
用流 API(Stream)简化集合操作(如计算总重量)。
4代码质量与可维护性
模块化设计
将功能拆分为独立方法(如 readCustomer()、calculateFreight())。
减少方法长度,单个方法只负责单一职责。
常量与配置
将固定值(如体积重量换算系数 6000)定义为常量。
外部化配置(如费率、日期格式),便于修改。
注释与文档
添加方法注释说明业务规则(如计费公式)。
对复杂逻辑(如多重条件判断)提供解释。
5测试与健壮性
边界测试
覆盖极端情况(如货物数量为 0、重量为负数、日期在过去)。
测试临界值(如刚好达到航班载重上限)。
防御性编程
对集合操作前检查是否为空(如 cargos.isEmpty())。
使用不可变集合(如 Collections.unmodifiableList)防止数据篡改。
6性能与扩展性
数值精度
用 BigDecimal 处理金额计算,避免浮点数精度误差。
数据结构优化
根据业务场景选择合适的集合类型(如频繁查找用 HashMap)。
扩展性设计
预留接口(如 DiscountStrategy)便于添加新的计费策略。
使用依赖注入降低模块间耦合。

五.总结:

Java学习任重而道远,以后需注意:
1面向对象编程
类与对象:深入理解封装、继承、多态的本质,如通过private修饰符隐藏属性,利用抽象类 / 接口实现代码复用。
设计原则:掌握单一职责、开闭原则等,避免臃肿类设计,例如将业务逻辑拆分为独立服务类。
常见设计模式:工厂模式、单例模式(线程安全实现)、策略模式(如计费规则动态切换)的应用场景与实现细节。
2核心类库与 API
集合框架:对比List(有序可重复)、Set(无序唯一)、Map(键值对)的底层结构(如 ArrayList 的动态扩容机制、HashMap 的哈希冲突处理)。
并发包(java.util.concurrent):线程安全类(如ConcurrentHashMap)、锁机制(ReentrantLock)、线程池(ThreadPoolExecutor)的原理与使用规范。
IO 与 NIO:区分字节流(FileInputStream)与字符流(BufferedReader),理解 NIO 的通道(Channel)与缓冲区(Buffer)模型,提升文件操作效率。
3异常处理与内存管理
异常体系:明确 Checked 异常(如IOException)与 Unchecked 异常(如NullPointerException)的处理策略,合理使用try-catch-finally结构。
垃圾回收(GC):掌握引用类型(强引用、弱引用)、GC 算法(标记 - 清除、复制算法),通过System.gc()提示回收但不强制触发。
内存泄漏排查:避免长生命周期对象持有短生命周期引用,如静态集合未及时清理元素。
4多线程与并发编程
线程基础:Thread与Runnable的区别,线程状态(新建、运行、阻塞)转换条件,通过join()、interrupt()控制线程协作。
同步机制:synchronized关键字的作用范围(对象锁、类锁),对比volatile(可见性)与Atomic类(原子性)的适用场景。
线程安全实践:避免竞态条件,如通过Lock接口实现公平锁,或使用ConcurrentHashMap替代非线程安全的HashMap。
5性能优化与工程实践
字符串操作:优先使用StringBuilder/StringBuffer(线程安全)拼接字符串,避免String对象频繁创建。
反射与动态代理:理解Class.forName()的类加载机制,动态代理在 AOP(如日志拦截、事务管理)中的应用。
单元测试:掌握JUnit框架,编写覆盖边界条件(如参数为null)的测试用例,提升代码健壮性.
加油!加油!加油!

posted @ 2025-05-20 10:48  花宵道中  阅读(34)  评论(0)    收藏  举报