第一次Blog作业分析总结
1.前言
题目集五:
该题目集的题量为五道。
第一题为求身份证号校验位,难度为中等,
主要涵盖知识点:1.数组/列表的遍历和操作。2.基本的算术运算(乘、加、取模)。3.条件判断或字典的使用。4.输入验证和简单的错误处理。5.字符串和整数的转换。
第二题为求解一元二次方程,难度为入门,
主要涵盖知识点:1.类的定义与封装:使用 private 修饰符封装类的属性。提供公共的 getter 方法访问私有属性。2.构造方法:定义构造方法初始化对象的属性。3.方法定义与调用:定义多个方法分别实现不同的功能(如计算判别式、计算根等)。4.条件判断:根据判别式的值,判断方程的根的情况5.异常处理(隐式):检查 a=0 的情况,直接终止程序
第三题为验证码校验,难度为入门,
主要涵盖知识点:1.正则表达式:用于快速匹配字符串模式。2.字符串操作:检查长度、遍历字符、判断字符类型。
第四题为QQ号校验,难度为入门,
主要涵盖知识点:1.正则表达式(Regular Expression):正则表达式是一种强大的字符串匹配工具,可以用于检查字符串是否符合某种模式。本题的关键是构造一个正则表达式,用于匹配 5-15位数字且不以0开头 的字符串。2.字符串长度检查:QQ号必须是 5-15位,因此需要检查字符串的长度是否在范围内。3.首位字符检查:QQ号不能以 0 开头,因此需要检查第一个字符是否是 1-9。4.字符范围检查:QQ号的字符只能是 0-9,因此需要检查每个字符是否都是数字。5.Java 字符串操作:使用 String.matches(regex) 方法检查字符串是否匹配正则表达式。或者手动遍历字符串的每个字符,检查是否符合要求。
第五题为单部电梯调度程序,难度为中等,
主要涵盖知识点:1.OOP设计(类、封装、方法)。2.队列管理(内部/外部请求区分)。3.状态机(电梯状态转换)。4.调度算法(SCAN算法,同方向优先)。5.输入处理(无效请求过滤)。6.边界条件(楼层范围、静止状态处理)。
题目集六:
该题目集的题量为三道。
第一题为点与线(类设计),难度为简单,
主要涵盖知识点:1.类的设计与封装(Point 和 Line 类)。2.构造方法与 Getter/Setter。3.数据验证(坐标范围检查)。4.数学计算(两点间距离公式)。5.字符串格式化输出(保留两位小数)。6.输入处理(Scanner 读取多类型数据)。
第二题为汽车风挡玻璃雨刷问题(类设计),难度为中等,
主要涵盖知识点:1.类设计与封装:需要设计合理的类结构来表示雨刷控制系统。将控制杆和刻度盘作为类的属性或独立类进行封装。2.状态管理:控制杆有4种状态(停止、间歇、低速、高速),刻度盘有5种状态(1-5),需要管理这些状态的合法转换。3.条件逻辑与状态转换:根据输入指令(1-4)改变系统状态,处理边界条件(如已经在最高档时再升档)。4.表格数据处理:需要将题目提供的速度表格转换为程序逻辑,根据控制杆和刻度盘的组合确定最终速度。5.输入处理:读取并验证用户输入(1-4为有效,其他值结束),处理连续的输入指令。6.枚举类型应用:适合使用枚举来表示控制杆的固定档位。
第三题为单部电梯调度程序(类设计),难度为较难,
主要涵盖知识点:1.单一职责原则(SRP):将原电梯类的职责分解到多个专门的类中,每个类只负责一个明确的功能领域。2.类设计模式:请求类:封装乘客请求信息,队列类:管理请求的存储和检索,电梯类:封装电梯属性和基本行为,控制类:负责调度逻辑。3.输入验证与过滤:楼层范围验证(忽略超出范围的请求),重复请求过滤(忽略连续的相同请求)。4.状态管理:电梯运行方向(UP/DOWN)的状态管理,电梯当前位置跟踪。5.请求处理逻辑:区分内部请求(<楼层>)和外部请求(<楼层,方向>),处理请求的优先级和顺序。6.边界条件处理:处理最小/最大楼层限制,处理连续相同请求的情况。
题目集七:
该题目集的题量为三道。
第一题为销售步枪问题,难度为简单,
主要涵盖知识点:1.面向对象设计:类封装、单一职责原则。2.输入验证:检查数据合法性。3.数学计算:销售额和分段佣金。4.输出格式化:保留两位小数。
第二题为蒙特卡罗方法求圆周率,难度为简单,
主要涵盖知识点:1.蒙特卡罗方法:随机采样与概率统计。2.几何计算:圆内点判定与距离公式。3.输入验证:数据合法性检查。4.误差分析:浮点数比较与精度控制。5.随机数生成:Math.random() 的使用。
第三题为单部电梯调度程序(类设计-迭代),难度为较难,
主要涵盖知识点:1.面向对象设计(SRP、类间协作)。2.队列管理(内部/外部请求分离)。3.状态机(电梯状态转换)。4.调度算法(SCAN算法优化)。5.输入/输出处理(请求解析、模拟输出)
题目集五、六、七中最后一题都为单部电梯调度程序,其难度也较其他题目更为困难棘手,三道题目实现了需求及技术上的迭代,进一步满足不同需求和涉及到更多更复杂的思考计算。
2.设计与分析
第一次单部电梯调度程序:
设计一个电梯类,具体包含电梯的最大楼层数、最小楼层数(默认为1层)当前楼层、运行方向、运行状态,以及电梯内部乘客的请求队列和电梯外部楼层乘客的请求队列,其中,电梯外部请求队列需要区分上行和下行。
电梯运行规则如下:电梯默认停留在1层,状态为静止,当有乘客对电梯发起请求时(各楼层电梯外部乘客按下上行或者下行按钮或者电梯内部乘客按下想要到达的楼层数字按钮),电梯开始移动,当电梯向某个方向移动时,优先处理同方向的请求,当同方向的请求均被处理完毕然后再处理相反方向的请求。电梯运行过程中的状态包括停止、移动中、开门、关门等状态。当电梯停止时,如果有新的请求,就根据请求的方向或位置决定移动方向。电梯在运行到某一楼层时,检查当前是否有请求(访问电梯内请求队列和电梯外请求队列),然后据此决定移动方向。每次移动一个楼层,检查是否有需要停靠的请求,如果有,则开门,处理该楼层的请求,然后关门继续移动。
使用键盘模拟输入乘客的请求,此时要注意处理无效请求情况,例如无效楼层请求,比如超过大楼的最高或最低楼层。还需要考虑电梯的空闲状态,当没有请求时,电梯停留在当前楼层。
请编写一个Java程序,设计一个电梯类,包含状态管理、请求队列管理以及调度算法,并使用一些测试用例,模拟不同的请求顺序,观察电梯的行为是否符合预期,比如是否优先处理同方向的请求,是否在移动过程中处理顺路的请求等。为了降低编程难度,不考虑同时有多个乘客请求同时发生的情况,即采用串行处理乘客的请求方式(电梯只按照规则响应请求队列中当前的乘客请求,响应结束后再响应下一个请求),具体运行规则详见输入输出样例。
输入格式:
第一行输入最小电梯楼层数。
第二行输入最大电梯楼层数。
从第三行开始每行输入代表一个乘客请求。
- 电梯内乘客请求格式:
<楼层数> - 电梯外乘客请求格式:
<乘客所在楼层数,乘梯方向>,其中,乘梯方向用UP代表上行,用DOWN代表下行(UP、DOWN必须大写)。 - 当输入“end”时代表输入结束(end不区分大小写)。
输出格式:
模拟电梯的运行过程,输出方式如下:
- 运行到某一楼层(不需要停留开门),输出一行文本:
Current Floor: 楼层数 Direction: 方向 - 运行到某一楼层(需要停留开门)输出两行文本:
Open Door # Floor 楼层数Close Door
分析:这个电梯调度系统的设计核心在于通过面向对象的方式将电梯的各种状态和行为合理封装,Elevator类负责维护电梯当前楼层、运行方向和状态等基础属性,同时管理内部请求队列和按方向区分的外部请求队列,ElevatorController类则专注于调度逻辑的实现,采用类似SCAN算法的策略来控制电梯移动,优先处理同方向请求并在端点反转方向。输入处理模块需要严格验证楼层范围并区分内外请求,对于无效输入和重复请求能自动过滤,确保系统健壮性。输出方面则按照要求规范显示电梯运行状态和开关门动作。整个设计通过将状态管理、队列处理和调度算法分离到不同类中,既遵循了单一职责原则,又为后续可能的扩展(如多电梯协作)保留了空间,虽然当前采用串行方式处理请求简化了并发问题,但基础架构已经为更复杂的调度场景奠定了基础,特别是在请求队列管理和方向决策方面体现了良好的可扩展性。
第二次单部电梯调度程序:
对之前电梯调度程序进行迭代性设计,目的为解决电梯类职责过多的问题,类设计要求遵循单一职责原则(SRP),要求必须包含但不限于设计电梯类、乘客请求类、队列类以及控制类。
电梯运行规则与前阶段单类设计相同,但要处理如下情况:
- 乘客请求楼层数有误,具体为高于最高楼层数或低于最低楼层数,处理方法:程序自动忽略此类输入,继续执行
- 乘客请求不合理,具体为输入时出现连续的相同请求,例如
<3><3><3>或者<5,DOWN><5,DOWN>,处理方法:程序自动忽略相同的多余输入,继续执行,例如<3><3><3>过滤为<3>
输入格式:
第一行输入最小电梯楼层数。
第二行输入最大电梯楼层数。
从第三行开始每行输入代表一个乘客请求。
- 电梯内乘客请求格式:
<楼层数> - 电梯外乘客请求格式:
<乘客所在楼层数,乘梯方向>,其中,乘梯方向用UP代表上行,用DOWN代表下行(UP、DOWN必须大写)。 - 当输入“end”时代表输入结束(end不区分大小写)。
输出格式:
模拟电梯的运行过程,输出方式如下:
- 运行到某一楼层(不需要停留开门),输出一行文本:
Current Floor: 楼层数 Direction: 方向 - 运行到某一楼层(需要停留开门)输出两行文本:
Open Door # Floor 楼层数Close Door
PowerDesigner的相应类图:

分析:
这个电梯调度系统的设计将原本臃肿的电梯类拆分为四个核心类:Elevator类只负责维护电梯基本状态(当前楼层、运行方向、运行状态)和物理动作(移动、开关门);PassengerRequest类封装乘客请求信息,包括请求类型(内部/外部)、目标楼层和方向;RequestQueue类专门管理请求的存储、验证和过滤,自动处理无效楼层和重复请求;ElevatorController类则集中实现SCAN调度算法,控制电梯运行逻辑。整个系统运行时,输入解析器将用户输入转换为PassengerRequest对象并交给RequestQueue进行验证和去重,ElevatorController从队列中获取请求并指挥Elevator移动,在移动过程中动态检查各楼层是否有需要处理的请求,通过这种职责分离的设计,不仅解决了原始电梯类负担过重的问题,还使输入验证、请求管理和调度算法可以独立变化和扩展,特别是RequestQueue对无效请求的自动过滤机制和ElevatorController的方向优先调度策略,既满足了功能需求又保证了系统的健壮性,输出模块严格遵循规定的格式要求,在电梯经过和停靠时输出相应状态信息,整个架构清晰且易于维护。
第三次单部电梯调度程序:
对之前电梯调度程序再次进行迭代性设计,加入乘客类(Passenger),取消乘客请求类,类设计要求遵循单一职责原则(SRP),要求必须包含但不限于设计电梯类、乘客类、队列类以及控制类。
电梯运行规则与前阶段相同,但有如下变动情况:
- 乘客请求输入变动情况:外部请求由之前的
<请求楼层数,请求方向>修改为<请求源楼层,请求目的楼层> - 对于外部请求,当电梯处理该请求之后(该请求出队),要将
<请求源楼层,请求目的楼层>中的请求目的楼层加入到请求内部队列(加到队尾)
注意:本次作业类设计必须符合如上要求(包含但不限于设计电梯类、乘客类、队列类以及控制类),凡是不符合类设计要求此题不得分。
输入格式:
第一行输入最小电梯楼层数。
第二行输入最大电梯楼层数。
从第三行开始每行输入代表一个乘客请求。
- 电梯内乘客请求格式:
<楼层数> - 电梯外乘客请求格式:
<请求源楼层,请求目的楼层>,其中,请求源楼层表示乘客发起请求所在的楼层,请求目的楼层表示乘客想要到达的楼层。 - 当输入“end”时代表输入结束(end不区分大小写)。
输出格式:
模拟电梯的运行过程,输出方式如下:
运行到某一楼层(不需要停留开门),输出一行文本:
- 运行到某一楼层(不需要停留开门),输出一行文本:
Current Floor: 楼层数 Direction: 方向 - 运行到某一楼层(需要停留开门)输出两行文本:
Open Door # Floor 楼层数Close Door
SourceMontor的生成报表内容以及PowerDesigner的相应类图:

分析:
这次迭代设计最大的变化是用Passenger类替代了原来的PassengerRequest类,使设计更加贴近现实场景,Passenger类不仅包含乘客的当前楼层和目的楼层信息,还能自然地表示乘客从进入电梯到离开的全过程,当处理外部请求时,系统会自动将乘客的目的楼层加入内部队列,这种设计巧妙地模拟了现实中乘客进入电梯后按下目标楼层按钮的行为;Elevator类继续负责电梯状态管理但移除了请求处理逻辑,RequestQueue类现在管理的是Passenger对象队列并新增了请求转换功能,当电梯到达乘客的源楼层时,会自动把该乘客的目的楼层转为内部请求;ElevatorController类的调度算法也相应调整,需要同时考虑乘客的当前位置和目的地的逻辑关系,这种设计不仅更符合实际电梯运作流程,还通过Passenger对象的生命周期管理使系统行为更加清晰,输入处理模块需要解析新的请求格式并创建Passenger对象,同时保持对无效请求的过滤能力,输出模块则继续按照规范显示电梯运行状态,整个架构通过将乘客实体显式建模,使系统各组件职责更加单一明确,特别是将请求生成和转换逻辑从控制类分离出来,既满足了SRP原则又为后续可能的扩展(如乘客属性多样化)奠定了基础。
3.踩坑心得
楼层范围验证不完整:只验证了初始输入的最小/最大楼层,但忘记在请求处理时验证每个请求的楼层是否在范围内。
重复请求过滤逻辑错误:只比较相邻请求是否相同,但忽略了方向(如<5,UP>和<5,DOWN>是不同的请求)。
大小写处理不当:对"end"的识别需要不区分大小写,但"UP"/"DOWN"必须大写。
控制类做太多工作:把请求验证、队列管理都放在控制类中,违反SRP。
电梯类过于简单:只作为数据容器,没有封装电梯行为。
方向判断错误:当电梯空闲时选择下一个请求的方向逻辑不正确。
开门条件不完整:只检查当前楼层是否有请求,但忽略了方向匹配。
初始状态处理不当:电梯默认位置和方向设置错误。
空队列处理:没有请求时程序行为未定义。
极端楼层请求:同时有minFloor和maxFloor的请求时处理错误。
4.改进建议
边界测试:最小和最大楼层请求,连续相同请求过滤,端点折返行为。
方向测试:混合UP/DOWN请求的处理,空闲时方向选择。
异常测试:非法楼层输入,格式错误请求,空队列处理。
请求队列优化:使用PriorityQueue实现请求优先级,按方向分区存储请求。
内存优化:对已完成请求及时清理,使用对象池管理请求对象。
先完成基础类框架,确保结构符合要求。实现基本请求处理流程,通过简单测试用例。逐步添加SCAN算法逻辑。完善边界条件和异常处理。进行全面的测试验证。最后考虑性能优化和扩展功能。
5.总结
通过这三次迭代设计,我深刻理解了软件设计原则和模式在实际项目中的应用演进:
-
从最初将所有功能塞入一个电梯类,到逐步拆分为乘客(请求)类、队列类、控制类和电梯类,每个类的职责越来越清晰明确。这种演进让我体会到良好架构是如何通过迭代逐步形成的。
-
在迭代过程中,观察者模式(请求队列与电梯状态)、状态模式(电梯运行状态)和策略模式(调度算法)等设计模式自然而然地被应用,而非刻意为之。
-
三次迭代对输入验证的要求逐步严格,从简单的楼层验证到复杂的重复请求过滤,让我认识到健壮性设计是系统工程的基础。
-
从简单的FIFO到SCAN算法,再到考虑目的楼层的优化调度,理解了算法选择对系统性能的关键影响。
这三次迭代让我认识到,好的软件设计是一个不断演进的过程,需要平衡当前需求与未来扩展,在简单与复杂之间找到恰当的平衡点。

浙公网安备 33010602011771号