第三次总结

Posted on 2025-06-22 22:13  yumi12138  阅读(22)  评论(0)    收藏  举报

 

一、前言

在本学期的学习过程中,Blog、PTA 作业、实验以及线上线下课程共同构建起一套层次分明、衔接紧密的学习体系,全方位助力知识吸收与实践应用。 Blog 作业的设置尤其注重培养解决实际问题的能力。尽管首次接触时难免感到棘手,但随着对 SourceMonitor 工具的深入了解,我逐渐掌握了代码复杂度分析与质量评估的方法。这种数据驱动的分析手段让我对代码中的潜在问题有了更清晰的认识,也促使我主动运用该工具优化编程习惯,形成了良性循环。 PTA 作业的难度梯度设计科学,既有像首次电梯问题那样逻辑错综复杂的挑战,也有大量中等难度的巩固性题目。以电梯问题为例,其涉及的多线程调度与状态管理曾让我抓不到头脑,但通过反复调试与重构,最终还是有点收获的后续题目的循序渐进则确保了知识的系统性积累。 实验环节的阶梯式难度设置与迭代式开发要求,有效锻炼了我们的代码优化能力。不过,当前实验提交系统的效率有待提升,相比专业 IDE 的即时反馈,现有系统的延迟性在一定程度上影响了调试体验。建议老师能整合更高效的开发工具,进一步提升学习效率。 线上课程作为预习环节,为线下教学奠定了坚实基础。不会让我成功弥补了线上学习中对理论定义的模糊认知,使知识体系更加完整。 总体而言,这种紧凑且富有挑战性的学习安排,让我在实践中不断深化理论理解,逐步形成了完整的知识架构。期待未来能在实验工具与教学资源方面进一步优化,为学习体验注入更多动力。

二、面向对象技术总结

在pta的练习过程中,我们先从最简单的面向对象编程开始,比如说简单的输入圆柱体的半径和高,进而输出圆柱体的体积

import java.util.Scanner; // 导入 Scanner 类用于输入

public class Main {
    public static void main(String[] args) {
        // 创建 Scanner 对象用于输入
        Scanner sc = new Scanner(System.in);

        // 读取半径 r
        double r = sc.nextDouble(); // 使用 nextDouble() 读取 double 类型

        // 读取高度 h
        double h = sc.nextDouble(); // 使用 nextDouble() 读取 double 类型

        // 计算体积
        double v = Math.PI * r * r * h; // 使用 Math.PI 获取更精确的 π 值

        // 输出结果,保留两位小数
        System.out.printf("%.2f", v);

        // 关闭 Scanner
        sc.close();
    }
}

这种就是一个最简单的面向对象编程,然后第二个pta习题集就上升了一些难度,不过使用上学期写过的编程题进行从C语言到java的改写,其实C语言和java的基础语法结构相近,但是C语言是纯粹的面向过程语言,而java是面向对象语言,都需要对内存管理有所了解,但是它们的实现方式不同。我们要了解、掌握类、对象、继承、多态、封装等面向对象的核心概念,我们需要从“过程”为中心 转变为以“对象”为中心,将现实世界的事物抽象成类和对象。pta题目集3中训练的是java中数组的定义、如何输入、熟悉使用的过程。而题目集4就是一个java的简单的面向对象的实现,在这4道题中我锻炼了熟练写getter,setter和构造方法的能力,题目集4中主要是正则表达式的训练,我对正则表达式还是掌握的不是很熟练,下面列举一下

正则表达式

正则表达式是由字符和特殊符号组成的模式,用于描述字符串的匹配规则。在 Java 中,正则表达式常用于:

验证输入数据格式(如邮箱、手机号)

提取字符串中的特定内容

替换文本中的部分内容

分割字符串

符号 说明 示例
\d 匹配数字(0-9) "\\d" 匹配 "1" "5"
\D 匹配非数字 "\\D" 匹配 "a" "%"
\w 匹配字母、数字或下划线([a-zA-Z0-9_] "\\w" 匹配 "a" "5" "_"
\W 匹配非字母、数字或下划线 "\\W" 匹配 "@" " "
\s 匹配空白字符(空格、制表符等) "\\s" 匹配空格
\S 匹配非空白字符 "\\S" 匹配 "a"
. 匹配任意单个字符(除换行符) ".at" 匹配 "cat" "bat"


[abc]:匹配 ab 或 c 中的任意一个字符。
[a-z]:匹配小写字母 a 到 z 中的任意一个。
[A-Z]:匹配大写字母 A 到 Z 中的任意一个。
[0-9]:匹配数字 0 到 9(等价于 \d)。
[^abc]:匹配除 abc 之外的任意字符(^ 表示取反)。



封装


封装是通过限制对类内部属性的直接访问,防止外部代码修改数据,控制可见性,也是Java面向对象编程的基础,私有属性与公共接口分离,外部代码无法直接修改对象的属性,或者就是在接口处,定义行为。用其他实现类隐藏具体逻辑,那么主程序只需要调用相应的pay();方法,无需关心不同支付方式的差异,符合“接口隔离原则”。

interface PaymentMethod {
    void pay(); // 仅定义接口,不暴露实现
}

class AlipayPayment implements PaymentMethod {
    @Override
    public void pay() {
        System.out.println("使用支付宝支付"); // 具体实现被封装
    }
}

继承与多态

继承是子类通过extends关键字继承父类的非私有成员(属性和方法),并可添加自己特有成员或修改父类行为。但是继承是高耦合性的,父类的修改可能影响所有子类,需要小心设计。在动物进冰箱的实验中,所有的动物都继承Animal这个父类,这个父类中抽象封装了所有动物的共同属性(名字,体重),无需重复实现通用逻辑。多态的核心在于,统一接口,动态实现。比如在父类定义统一接口,子类选择性实现接口,在抽象类抽象方法,有子类具体实现,可以将不同的重写。这个在实验中可以很好的展现。

 


抽象类与接口

抽象类(Abstract Class) 是一种不能被实例化的类,它主要用于定义一组相关类的共同接口和部分实现。抽象类通过抽象方法强制子类提供具体实现,从而实现代码复用与行为规范的统一。在航天货运题目的时候,Cargo封装通用属性和calWeight()方法,子类直接复用,减少重复代码,提高开发效率,新增货物类型(如FragileCargo)时,只需继承Cargo并实现抽象方法。

接口

接口(interface)实现类必须覆盖所有方法,实验中用Comparable接口去实现动物排序问题,在雨刷问题中,我也使用的接口比较多,我定义了一个Agent接口包含了 dealSpeed(),show(String operationType),去重写这个显示方法,接口隐藏具体实现细节,客户端只需通过接口调用方法,无需关心内部逻辑。

 


集合框架

Java 集合框架是 Java 语言中用于存储和操作数据的核心组件,提供了一套高性能、易用且类型安全的接口和类。一共有两大分支,一个是Collection接口,存储 单一元素的容器,LIst,Set。一个是Map接口,可以存储键值对,例如动物实验中

// List示例:存储电器对象
List<Electronic> electronics = new ArrayList<>();

// Set示例:记录已使用的动物名称(确保唯一性)
static Set<String> usedNames = new HashSet<>();

// Map示例:未直接使用,但可用于优化动物工厂的名称生成逻辑

 

 提供类型安全,避免运行时ClassCastException,另一个计算动物的总重量时,可以不用挨个for循环,可以直接用stream API

// 计算电器中动物的总重量
public double getTotalAnimalWeight() {
    return animals.stream().mapToDouble(Animal::getWeight).sum();
}

// 过滤出攻击性动物
animals.stream()
    .filter(a -> a instanceof Aggressive && ((Aggressive) a).canAttack())
    .forEach(aggressiveAnimal -> { /* 处理攻击性动物 */ });

异常处理

受检异常(Checked Exception)必须显示处理,如FileNotFoundException,比如说文件读取的异常处理,FileNotFoundException是受检异常,必须通过throws声明或try-catch处理,代码选择通过throws将异常抛给调用者(JVM),未进行实际处理,增强程序的健壮性,避免因为文件不存在而崩溃,提供友好的错误提示

try {
    Scanner fileScanner = new Scanner(new File("d:/awsd/Node.txt"));
    // 读取文件内容
} catch (FileNotFoundException e) {
    System.err.println("错误:文件未找到 - " + e.getMessage());
    // 可添加默认数据或提示用户重新输入路径
}

在航空货物管理,在实际重量大于航班的承载重量时,我们可以抛出异常并终止订单创建,或者提供降级处理(如拆分订单)

 


JavaFX

我掌握了fx的基础控件(Button\Label\TextField),布局组件(FlowPane\BorderPane\StackPane),容器和舞台,样式和主题(CSS)等等,翻转课堂中,我们负责的板块是polygon和polyline ,我更多的掌握了多边形的画法,和他的一些角的锐利度的实现,和points属性、stroke属性。通过Points属性,可动态存储和修改多边形顶点的坐标集合,结合三角函数更能生成星形、螺旋线等复杂图形。Stroke属性则提供了丰富的描边控制选项,通过setStrokeLineCap()可设置端点样式为BUTT、ROUND或SQUARE,还可以通过setStrokeDashArray()实现自定义虚线模式。但是对于全部的知识我还是掌握的不够全面,还有待遇加强。



三、踩坑心得

 

1.在最近一次的谷仓问题中,原先是直接按数字进行处理输入的数据,创建List集合,List<AbstractGranary> a = new ArrayList<>();但是后面我直接就将这个传入这个创建的但是创建错误了,我发现我对这个定义理解的不清晰,总个创建的a是储存所有谷仓的列表,因为循环内部无法再访问列表 a(被局部变量遮蔽)所以我要创建临时变量,

AbstractGranary a1 = null; // 临时变量

如果不想添加临时变量,直接调用add()方法创建对象也是可以的

// 进一步简化:无需临时变量
if (length >= 20) {
    a.add(new CylinderGranary(height, radius));
} else if (length >= 15) {
    a.add(new CubeGranary(height, side));
} else if (length >= 5) {
    a.add(new ConeGranary(height, radius));
}

2.在雨刷程序拓展中,我觉得可以用数组和switch语句简化一下我的程序不用这样反复去设置对应的maxposition。

3.在航空货运管理系统中,我主要是最后的实际重量出了问题,搞了好久也没看出来,最后发现表格中的实际重量打印成了质量重量,把getWeight();改成calWeight();之后答案正确。

4.在电梯调度题目中,我之前一直停留在只能打印6楼之前的部分,发现问题出在remove移除内外部请求上,当外部请求3楼时会同时查找内外部的所有楼层的请求,并删除,后来我把这个remove这个函数拆开放进单独的内外部通过遍历进行删除。

5.静态方法无法实现多态。在动物进冰箱的实验中我将openDoor()写成了static 方法,在子类中就无法实现多态


四、改进意见和总结

希望老师可以上课之后立刻把ppt分享到群里,让我们能回去就温习,如果一个阶为了更好地促进知识吸收和巩固,希望老师能在每次课程结束后及时将当堂课的PPT分享至班级群。这样我们可以在课后第一时间对课堂内容进行系统复习,加深对知识点的理解和记忆。及时获取PPT能让我们在知识还新鲜时进行回顾,避免因时间间隔过长而导致遗忘,从而更高效地掌握课程内容。 同时,建议老师在每节课前将与当堂课内容对应的代码示例分享到群里。这些代码可以作为课堂学习的重要补充,帮助我们在听课过程中更好地理解理论知识与实际应用的结合。通过提前预习代码,我们能够在课堂上更有针对性地跟随老师的讲解,提高学习效率。此外,老师还可以根据当堂课的内容布置一些与之紧密对应的题目,让我们通过实际练习来巩固所学知识。这些题目应具有明确的针对性,能够覆盖课堂的重点和难点,让我们在解题过程中加深对知识点的理解和运用能力。 及时分享PPT和代码示例,以及布置针对性的题目,能够为我们创造一个连贯且高效的学习环境。这样的安排不仅有助于我们在课堂上更好地吸收知识,还能让我们在课后有足够的资源和机会进行复习和巩固,从而不断提升自己的学习效果。希望老师能够考虑这些建议,让我们的学习更加顺畅和高效。

博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3