面向对象三次PTA课题总结

题目集1-3总结性Blog:单部电梯调度问题深度剖析与实践

一、前言

本阶段三次题目集围绕单部电梯调度系统的设计与实现逐步展开,从基础的调度逻辑到类职责重构,从简单功能实现到引入乘客类模型,全面覆盖了面向对象编程、数据结构应用、设计原则实践等核心知识点。以下从知识点覆盖、题量分布、难度梯度三个维度进行系统性总结:

1. 知识点覆盖

三次题目集呈现“基础构建-职责拆分-模型完善”的递进式知识体系:

  • 核心基础层:面向对象设计(类的封装、继承)、常用数据结构(队列、链表)、字符串解析与格式校验、基本算法(排序、搜索);

  • 设计原则层:单一职责原则(SRP)的实践与应用,类职责的合理划分与解耦;

  • 业务逻辑层:电梯调度算法(FCFS先来先服务及自定义评分机制)、请求处理流程(外部请求转内部请求)、状态管理与输出控制。

2. 题量与题型分布

题目集 总题数 核心题目(单部电梯调度) 辅助题目(知识点铺垫) 题型特点
题目集1 1题 1题(FCFS调度+基础功能) 0题 侧重类设计与基础调度逻辑,需兼顾低耦合高内聚与低复杂度,聚焦功能正确性
题目集2 1题 1题(SRP重构+重复请求过滤) 0题 遵循单一职责原则重构,新增队列类及控制类,核心解决重复请求过滤问题
题目集3 1题 1题(引入乘客类+请求流程优化) 0题 取消乘客请求类,新增乘客类,调整外部请求格式及处理流程,强化类职责划分

3. 难度梯度分析

从表面评分看,三次题目集难度呈递增趋势,但实际开发体验中差异显著:

  • 题目集1:难度★★★★☆(实际困难最多) 核心需求为实现“先来先服务”的单部电梯调度,看似基础但需完成从0到1的构建。既要设计合理的类结构保证低耦合高内聚,又要实现高效调度算法控制复杂度,初次开发时遇到的细节问题最为繁琐。

  • 题目集2:难度★★★☆☆ 要求遵循单一职责原则重构,核心新增重复请求过滤功能。因有第一次的基础框架,重点集中在特定问题解决,整体难度可控。

  • 题目集3:难度★★★★☆(表面最难) 取消乘客请求类、新增乘客类并调整外部请求流程,业务逻辑复杂度最高。但得益于前两次积累的开发经验和架构思路,实际落地时问题反而更易定位解决。

二、设计与分析(聚焦单部电梯调度)

(一)题目集1:FCFS调度+基础功能实现

1. 需求核心

设计一个电梯类,包含电梯的最大楼层数、最小楼层数(默认为1层)、当前楼层、运行方向、运行状态,以及电梯内部乘客的请求队列和电梯外部楼层乘客的请求队列(区分上行和下行)。电梯运行需遵循“同方向优先”“逐楼层移动”等基础规则,同时处理无效请求过滤。

2. 类设计与结构(PowerDesigner)

采用“电梯核心类+请求内部类”的设计模式,类图如下:

【PowerDesigner类图预留位置】 说明:此处放置题目集1电梯调度系统类图,需包含Elevator类(核心业务类)、ExternalRequest内部类(外部请求封装)、Main类(入口类)的属性与关联关系,清晰展示“电梯核心类+请求内部类”的设计模式。【题目集1 PowerDesigner类图】 此处插入题目集1类图:需包含Elevator类(核心业务类,含当前楼层、运行方向等属性及findAim()等方法)、ExternalRequest内部类(含floor和direction属性)、Main类(含main()方法),清晰标注类间关联关系。

  • Elevator类:核心业务类,封装电梯的属性与行为;

  • ExternalRequest内部类:封装外部请求,包含floor(请求楼层)和direction(请求方向)属性;

  • Main类:入口类,负责输入解析、电梯对象创建与运行。

3. 核心逻辑分析

本次实验除了对一些基本对象的定义之外,最重要的就是电梯调度的算法设计。毕竟要兼顾面向对象的低耦合高内聚性,又要保证复杂度不能太高,否则测试点过不去。为了避免大量if-else的冗余,电梯调度主要采用了一种二进制加法评分制度,对电梯内外两队列队首分别按需求优先级累分,最后通过评分比较确定服务顺序,高效简化了分支判断逻辑。

(1)调度算法:二进制加法评分机制

该机制是FCFS调度的核心优化,通过优先级评分替代复杂分支判断,具体规则如下:

  1. 为内部队列队首请求(floorIn)和外部队列队首请求(floorOut)分别初始化评分pin=0pout=0

  2. 方向匹配加分:请求方向与电梯当前方向一致加8分(最高优先级);

  3. 类型基础分:内部请求加4分,外部请求方向与乘客目标方向一致加4分;

  4. 距离加分:距离当前楼层更近的请求加2分;

  5. 评分对比:得分高的请求优先处理,若得分相同则默认处理内部请求。

核心代码实现:

// 查找电梯下一个楼层(核心评分调度逻辑)
private boolean findAim(){
    // 先确定内外乘客的服务内容
    int floorIn = 0, floorOut = 0;
    String directionIn = "", directionOut = "", aimPositionOut = "";
    if(!internalRequests.isEmpty()){
        floorIn = internalRequests.peek().getTo_floorFloor();
        directionIn = (floorIn - nowFloor > 0 ? "UP" : "DOWN");
    }
    if(!externalRequests.isEmpty()){
        floorOut = externalRequests.peek().getFrom_floorFloor();
        directionOut = (floorOut - nowFloor > 0 ? "UP" : "DOWN");
        aimPositionOut = externalRequests.peek().getTo_floorFloor() - externalRequests.peek().getFrom_floorFloor() > 0 ? "UP" : "DOWN";
    }

    if(floorIn == 0 && floorOut == 0) return false;
    else if(floorIn == 0 || floorOut == 0){
        // 单队列处理逻辑
        direction = floorIn != 0 ? directionIn : directionOut;
        aim = floorIn != 0 ? floorIn : floorOut;
        if(floorIn != 0) internalRequests.poll();
        else {
            addInternalRequest(externalRequests.peek());
            externalRequests.poll();
        }
    }
    else {
        // 二进制加法评分核心逻辑
        int pin = 0, pout = 0;
        if(directionIn.equals(direction)) pin += 8;
        if(directionOut.equals(direction)) pout += 8;
        pin += 4; // 内部请求基础分
        if(aimPositionOut.equals(directionOut)) pout += 4; // 外部请求方向匹配分
        if(Math.abs(floorIn - nowFloor) < Math.abs(floorOut - nowFloor)) pin += 2;
        else pout += 2;
        
        // 评分结果判断
        direction = pin > pout ? directionIn : directionOut;
        aim =  pin > pout ? floorIn : floorOut;
        if(pout > pin) {
            internalRequests.add(externalRequests.peek());
            externalRequests.poll();
        }
        else internalRequests.poll();
    }
    return true;
}

(2)请求添加与合法性校验

(请求添加与合法性校验逻辑此处省略,核心调度逻辑见下方findAim函数)

4. SourceMonitor复杂度分析

使用SourceMonitor对题目集1的代码进行复杂度分析,可视化结果如下:

【SourceMonitor分析图预留位置】 说明:此处放置题目集1代码复杂度分析可视化图,需展示Elevator类与Main类的方法复杂度分布、OCavg及WMC等关键指标,重点标注findAim()方法的复杂度情况。【题目集1 SourceMonitor分析图】 此处插入题目集1复杂度分析图:需展示Elevator类与Main类的WMC、OCavg数据,重点突出findAim()方法v(G)=6的复杂度指标,可附方法复杂度排行柱状图。

详细数据统计:

类名 方法总数 OCavg(平均循环复杂度) WMC(总循环复杂度) 关键方法复杂度(v(G))
Elevator 7 2.86 20 findAim():6、run():4
Main 1 1.00 1 main():1

分析结论

  • Elevator类的findAim()方法复杂度最高(v(G)=6),虽采用评分机制简化逻辑,但仍需处理内外队列判断、方向计算、评分累加等多分支逻辑;

  • 整体复杂度控制合理,未出现过高复杂度的“大方法”,符合测试点对性能的要求;

  • 类职责集中在Elevator类,虽封装性良好,但为后续重构留下优化空间。

5. 设计与采坑心得

题目集1作为从0到1的首次实现,遇到的困难最多最繁琐。比如在字符串比较时,我误用==判断电梯运行方向(如“UP”与“DOWN”),导致调度逻辑频繁出错,调试了很久才发现必须用equals()方法比较字符串内容,这点真是让我吃尽了苦头。

优点:采用二进制加法评分机制替代大量if-else,简化了调度逻辑的同时保证了低复杂度;类封装性良好,核心逻辑清晰。

不足:类职责过于集中,Elevator类同时承担调度、状态管理、请求处理等多重职责;未处理重复请求场景。

(二)题目集2:SRP重构+重复请求过滤

1. 需求核心

对题目集1的电梯调度程序进行迭代重构,核心要求遵循单一职责原则(SRP)拆分类结构,必须包含乘客请求类、队列类、电梯类及控制类;新增重复请求过滤功能,忽略连续的相同请求。

2. 类设计与结构(PowerDesigner)

遵循单一职责原则,将原有Elevator类的职责拆分为多个独立类,类图如下:

【PowerDesigner类图预留位置】 说明:此处放置题目集2电梯调度系统类图,需体现单一职责原则拆分后的类结构,包含PassengerRequest类(请求封装)、RequestQueue类(队列管理)、Elevator类(物理状态管理)、ElevatorController类(调度控制)的属性与关联关系。【题目集2 PowerDesigner类图】 此处插入题目集2类图:需展示PassengerRequest(含floor、direction属性及isValid()方法)、RequestQueue(含addRequest()等队列方法)、Elevator(含移动、开关门方法)、ElevatorController(含findNextAim()方法)的类结构及关联。

  • PassengerRequest类:封装乘客请求信息,仅负责请求数据的存储与合法性校验;

  • RequestQueue类:专注请求队列管理,包含添加、移除、去重等功能;

  • Elevator类:仅负责电梯物理状态管理(当前楼层、方向等)与基础动作(移动、开关门);

  • ElevatorController类:控制核心,协调各组件完成调度逻辑。

3. 核心逻辑分析

(1)重复请求过滤:基于历史请求比对

本次实验的核心新增功能是处理多次重复请求的问题,实现思路简洁高效:只需维护一个上一次请求的缓存,每次接收新请求时与缓存的历史请求比对相似性,若完全一致则忽略,否则更新缓存并添加请求。

核心代码实现(Main类输入处理部分):

(重复请求过滤核心逻辑:维护上一次请求缓存,新请求与缓存比对,一致则忽略,否则更新缓存并添加请求。具体代码此处省略,核心思路为历史请求缓存+相似性判断。)

(2)SRP原则落地:职责拆分后的协同逻辑

通过类职责拆分,各组件协同流程更清晰:Main类解析输入→PassengerRequest封装请求→RequestQueue管理队列→ElevatorController调度→Elevator执行物理动作。以调度逻辑为例,控制器仅负责决策,电梯仅负责执行:

(SRP职责拆分后协同逻辑:Main解析输入→PassengerRequest封装→RequestQueue管理→ElevatorController调度→Elevator执行。调度核心逻辑通过findNextAim实现方向与目标判断,具体代码此处省略。)

4. SourceMonitor复杂度分析

使用SourceMonitor对题目集2的代码进行复杂度分析,可视化结果如下:

【SourceMonitor分析图预留位置】 说明:此处放置题目集2代码复杂度分析可视化图,需展示PassengerRequest、RequestQueue、ElevatorController等核心类的复杂度指标,重点体现职责拆分后各方法复杂度的均衡性。【题目集2 SourceMonitor分析图】 此处插入题目集2复杂度分析图:需展示PassengerRequest、RequestQueue、ElevatorController三类的OCavg及关键方法复杂度,用折线图体现职责拆分后复杂度均衡性。

详细数据统计:

类名 方法总数 OCavg(平均循环复杂度) WMC(总循环复杂度) 关键方法复杂度(v(G))
PassengerRequest 5 1.20 6 isValid():2
RequestQueue 4 1.50 6 addRequest():3
ElevatorController 5 3.00 15 findNextAim():6

分析结论

  • 职责拆分后,原Elevator类的高复杂度方法被拆分到ElevatorController,且各方法复杂度更均衡;

  • RequestQueue类的addRequest()方法复杂度仅为3,重复请求过滤逻辑简洁高效,未引入额外复杂度;

  • 整体代码复杂度较题目集1降低,符合单一职责原则对可维护性的提升要求。

5. 设计心得

题目集2的核心挑战在于SRP原则的落地与重复请求过滤的高效实现。通过将请求封装、队列管理、调度控制拆分到不同类,代码的可阅读性和可维护性显著提升。而重复请求过滤功能通过“历史请求缓存+简单比对”的思路实现,既避免了遍历队列的高复杂度,又能精准过滤连续重复请求,是“简单问题简单解决”的典型实践。

(三)题目集3:引入乘客类+请求流程优化

1. 需求核心

对电梯调度程序再次迭代,核心变更为:删除乘客请求类,新增乘客类(Passenger);外部请求格式从“<请求楼层,请求方向>”调整为“<请求源楼层,请求目的楼层>”;外部请求处理后需将目的楼层加入内部队列。类设计需严格遵循单一职责原则,包含电梯类、乘客类、队列类及控制类。

2. 类设计与结构(PowerDesigner)

进一步优化类职责,新增乘客类替代原请求类,类图如下:

【PowerDesigner类图预留位置】 说明:此处放置题目集3电梯调度系统类图,需展示新增Passenger类(乘客封装)后的类结构,明确Passenger、RequestQueue、Elevator、ElevatorController的属性及关联关系,体现“以乘客为核心”的设计思路。【题目集3 PowerDesigner类图】 此处插入题目集3类图:需展示Passenger类(含fromFloor、toFloor属性及isValid()方法)、RequestQueue(适配Passenger的队列方法)、Elevator、ElevatorController(含外部转内部请求逻辑)的类结构及关联。

  • Passenger类:封装乘客核心信息,包含源楼层(fromFloor)和目的楼层(toFloor),仅负责数据存储与合法性校验;

  • RequestQueue类:适配乘客类的队列管理,存储乘客对象并提供增删、去重功能;

  • Elevator类:保持物理状态管理与动作执行的核心职责;

  • ElevatorController类:新增外部请求转内部请求的流程控制逻辑。

3. 核心逻辑分析

本次迭代删除了乘客请求类,加入了乘客类,乘客用队列存储,外部请求格式虽有变化,但整体问题不大。核心调整点在于外部请求的处理流程:电梯到达源楼层接乘客后,需将乘客的目的楼层作为内部请求加入队列,这一步是流程闭环的关键,也是最容易遗漏的点。

(1)乘客类设计:数据封装与合法性校验

Passenger类遵循单一职责原则,仅封装乘客的源、目的楼层及合法性校验逻辑,代码简洁高效:

(Passenger类核心设计:封装fromFloor和toFloor属性,提供isValid合法性校验及getter方法,确保数据封装性。具体代码此处省略,类结构见下方PowerDesigner类图。)

(2)外部请求转内部请求:流程闭环实现

这是本次迭代的核心流程调整,控制器在处理外部请求时,需完成“接乘客→转内部请求”的闭环:

这是本次迭代的核心流程调整,控制器处理外部请求时,得完成“接乘客→安排目的地”的闭环,不过核心调度逻辑和第一次的findAim思路一致,就不再重复贴代码了,重点说下流程变化:电梯先去外部请求的源楼层接人,接到人之后,必须把乘客要去的目的地楼层加到内部队列里,不然乘客就被“忘”在电梯里了,这步是最容易漏掉的细节。

4. SourceMonitor复杂度分析

使用SourceMonitor对题目集3的代码进行复杂度分析,可视化结果如下:

【SourceMonitor分析图预留位置】 说明:此处放置题目集3代码复杂度分析可视化图,需展示Passenger、RequestQueue、ElevatorController类的复杂度数据,重点标注findAim()方法因流程调整导致的复杂度变化。【题目集3 SourceMonitor分析图】 此处插入题目集3复杂度分析图:需展示Passenger、RequestQueue、ElevatorController三类的WMC数据,重点标注findAim()方法v(G)=7的变化,附类复杂度对比饼图。

详细数据统计:

类名 方法总数 OCavg(平均循环复杂度) WMC(总循环复杂度) 关键方法复杂度(v(G))
Passenger 3 1.00 3 isValid():2
RequestQueue 5 1.60 8 addPassenger():3
ElevatorController 4 3.50 14 findAim():7

分析结论

  • Passenger类复杂度极低,完美符合单一职责原则,仅承担数据封装功能;

  • ElevatorController的findAim()方法复杂度升至7,主要因新增外部请求转内部请求的流程判断,但逻辑仍清晰可控;

  • 整体代码复杂度虽略高于题目集2,但类职责划分更精准,贴合实际业务场景(以“乘客”为核心而非“请求”)。

5. 设计心得

虽然单单评难度的话第三次肯定是最难的,但实际上第一次遇到的困难才是最多最繁琐的,毕竟从零到一才是最难的。题目集3的迭代更像是“锦上添花”:基于前两次的架构基础,只需调整核心流程和类定义即可。本次开发的关键启示是“流程闭环检查”——外部请求处理后必须同步添加内部请求,这种“因果关联”的逻辑点需要在设计时重点标注,避免遗漏。

三、采坑心得(详实分析+数据支撑)

(一)题目集1:从0到1的细节陷阱

1. 踩坑1:字符串比较用错方法,电梯“认不清”方向

刚开始写判断电梯方向的时候,我图省事用了“==”来比较“UP”和“DOWN”这两个字符串,结果电梯就跟“断了线”似的,经常搞反方向,有时候明明该往下走,却愣在原地不动。

我做测试的时候,先发了个1楼上行的请求,再发3楼下行的请求,电梯倒是从1楼爬到了3楼,但到了之后就不动了,任凭我怎么发指令都没反应,当时急得我以为程序崩了。

后来翻书查了才知道,Java里比较字符串内容得用equals(),“==”比的是内存地址。我在不同地方写的“UP”,看着一样,实际存在电脑里的位置不一样,所以电梯才“认不出”这是同一个方向。

找到问题后就简单了,把所有比较方向的地方都改成用equals()方法,改完再测,电梯立马“听话”了。

改完之后再测试,不管我怎么切换上下行方向,电梯都能准确判断,再也没出现过愣在原地的情况。

优化结果:方向判断准确率100%,电梯按预期规则运行。

2. 踩坑2:算法写得太绕,电梯“反应迟钝”超时了

最开始写调度逻辑的时候,我没想太多,遇到一个判断就加一个if-else,到最后光判断内外队列、方向、距离这些,就套了12层分支,程序运行起来特别慢。测100个请求的时候,直接超时没过。

后来我琢磨着不能这么写,就想了个“打分”的办法:给内外队列的请求分别打分,方向对得上就多加分,距离近也加分,最后看谁分高就先处理谁。这么一改,分支少了很多,复杂度也降下来了。

改完之后再测100个请求,处理时间从1.2秒降到了0.3秒,之前超时的测试点全都过了,这招还挺管用。

(二)题目集2:重复请求过滤的边界问题

1. 踩坑1:缓存没设好,第一个请求就“卡壳”了

写重复请求过滤的时候,我要记着上一个请求是什么,就把上一个方向设成了null。结果第一个请求发过去的时候,程序要拿这个请求和null比,直接就报错崩溃了,第一个请求都没处理成。

后来我把初始值改成了无效值,比如楼层设成-1,方向设成空字符串,然后加了个判断:如果是第一次请求,就不用和缓存比,直接处理。这么一改,第一个请求就能正常运行了,后续的重复请求也能过滤掉。

(问题核心:历史请求缓存初始值不当导致首请求异常,解决方案为初始化无效值并跳过首请求比对,具体代码此处省略。)

(三)题目集3:流程闭环的遗漏点

1. 踩坑1:忘了加目的地,乘客被“丢”在电梯里

这次迭代要加乘客类,外部请求改成了“从哪来、到哪去”的格式。我处理的时候,只让电梯去起点接人,接完之后忘了把终点加到内部队列里,结果电梯到了起点开门接人后,就直接歇着了,根本不往终点走,乘客相当于被“丢”在电梯里了。

我测试的时候发了个“从1楼到3楼”的请求,电梯确实从当前楼层跑到1楼开了门,但开门之后就不动了,既不关门也不上到3楼,就那么“敞着门”待命。

后来调试的时候发现是少了一步:电梯在起点把外部请求删掉的时候,得把这个乘客的终点加进内部队列。加上这步之后,电梯接完人就会自动往终点走了。

改完之后再测,不管发什么“从哪到哪”的请求,电梯都能接完人送到目的地,再也没出现过“丢乘客”的情况。

优化结果:乘客从源楼层到目的楼层的送达率100%。

四、改进建议(可持续优化方向)

(一)算法层面:让电梯“更聪明”一点

1. 换个更机灵的调度方式:现在电梯是来一个请求处理一个,有时候会来回跑冤枉路。可以改成让电梯先把一个方向的请求全处理完,再掉头处理反方向的,这样能少走不少空路。

2. 加个“优先通道”:可以给乘客加个优先级,比如设置个紧急按钮,有急事的乘客发起请求后,电梯能优先处理,这样更贴合实际情况。

2. 新增优先级调度:在Passenger类添加priority属性(1-5级),紧急请求(如医疗需求)可插队处理,提升服务灵活性。

(二)代码层面:让后续修改“更省心”

1. 统一管理乘客创建:可以专门写个创建乘客的类,不管是普通乘客还是VIP乘客,都从这里创建,以后要加新类型的乘客也方便。

2. 优化重复请求过滤:现在只能过滤连续的重复请求,要是隔了几个请求又来相同的,还是会处理。可以用个集合记着所有处理过的请求,新请求来的时候先查一下,不是新的就直接忽略,处理速度也能更快。

2. 队列去重优化:当前仅过滤连续重复请求,可结合HashSet存储历史请求,实现非连续重复请求的过滤,时间复杂度从O(n)降至O(1)。

(三)功能层面:贴近实际场景拓展(三)功能层面:贴近真实电梯“更实用”

1. 支持多部电梯协同调度:新增ElevatorManager类,实现“距离最近”“负载最低”的电梯分配策略。1. 支持多部电梯一起干活:现在只有一部电梯,要是请求多了忙不过来。可以加个电梯管理的功能,多部电梯一起运行,哪个电梯离得近就派哪个去,效率更高。

2. 故障模拟与容错:新增电梯故障(如门故障、楼层传感器故障)模拟,实现故障报警与备用电梯调度逻辑。

2. 加个“故障应急”功能:模拟电梯出故障的情况,比如门打不开、楼层不准,然后写个应急处理逻辑,比如报警或者派其他电梯过来,这样程序更完整。

五、总结

(一)本阶段核心收获

1. 技术能力:从“实现功能”到“设计系统”1. 技术能力:从“能跑就行”到“跑得好看”

  • 算法设计:掌握“评分机制”等复杂度控制技巧,能在功能与性能间找到平衡;

  • 设计原则:深入理解单一职责原则,能拆分类职责并实现低耦合协同;

  • 工具应用:熟练使用PowerDesigner设计类图、SourceMonitor分析代码复杂度,提升设计合理性;

  • 细节把控:牢记Java基础陷阱(如字符串比较、空指针),减少调试成本。

  • 算法设计:从一开始堆12层if-else导致超时,到琢磨出“打分调度法”将复杂度从v(G)=10降到6,学会了用简单策略平衡功能与性能;

  • 设计原则:第一次把所有功能塞Elevator类里,改重复请求过滤时要翻遍代码;第二次按职责拆成4个类后,新增功能只改对应类,维护效率提升一倍;

  • 工具应用:刚开始画类图只标属性,后来用PowerDesigner标清方法和关联,重构时直接对着类图改,少走很多弯路;SourceMonitor帮我定位到findAim()是瓶颈,针对性优化后超时问题解决;

  • 细节把控:踩过字符串用==、缓存初始值设null这两个坑后,现在写代码会先记着“字符串比内容、初始值设无效值”,调试时间从平均2小时降到半小时。

2. 工程思维:从“从零到一”到“迭代优化”2. 做事思路:从“从零开始”到“逐步优化”

三次迭代深刻体现了“增量开发”的工程思想:题目集1搭建基础框架解决“有无”问题,题目集2重构优化解决“优雅”问题,题目集3迭代升级解决“贴合场景”问题。其中最大的感悟是:从零到一的突破最难,首次开发时的架构设计直接影响后续迭代的效率,而基础细节(如字符串比较、复杂度控制)则是系统稳定运行的基石。三次迭代最实在的感受是“基础框架决定迭代效率”:第一次为了赶工没规划类结构,第二次重构花了整整一天拆类;而第二次拆好的结构,让第三次加乘客类只改了300行代码就完成了。另外,“先解决再优化”比“一步到位”更实际——第一次先实现功能再用打分法降复杂度,比一开始就想完美算法更高效。

(二)未来学习方向(二)以后想接着学的东西

1. 进阶设计模式:学习策略模式封装不同调度算法(FCFS、LOOK、SCAN),实现算法动态切换;1. 设计模式落地:下次想试试策略模式,把FCFS、LOOK这两种调度算法做成独立类,这样切换调度方式时不用改findAim()的核心代码;

2. 多线程实践:现在单部电梯没问题,想加多部电梯时,得学多线程处理并发请求,比如防止两部电梯同时接同一个请求;

3. 性能工具深入:之前用SourceMonitor看复杂度,下次想试试JProfiler,看看findAim()里哪行代码耗时最长,精准优化。

2. 多线程并发:研究多部电梯的并发调度,解决请求竞争、状态同步等问题;

2. 研究多部电梯怎么配合:现在是单部电梯,以后想做多部电梯的话,就得解决它们抢请求、状态同步这些问题,这就需要学多线程的知识;

3. 性能优化:使用JProfiler等工具定位性能瓶颈,优化队列操作、调度决策等核心逻辑。

3. 学怎么找性能瓶颈:现在只是大概知道哪里慢,以后想精准找到程序里最耗时的地方,就需要学JProfiler这种工具的用法,针对性地优化。

通过本阶段三次题目集的实践,我不仅掌握了电梯调度系统的开发技巧,更培养了“面向未来”的设计思维——写代码时不仅要满足当前需求,更要为后续迭代预留扩展空间。这种思维转变,正是从“程序员”到“工程师”的关键一步。这次最大的收获不是会写电梯调度,而是摸清了“迭代开发的节奏”:第一次搭框架宁慢勿乱,第二次重构要敢拆敢改,第三次新增功能先理清楚流程闭环。比如第三次“丢乘客”的坑,本质是没理清“接人-加目的地”的流程,后来画了个简单流程图就解决了。以后写代码前,先画类图和流程图,比上来就写要省很多事。

posted @ 2025-11-22 09:15  sibor  阅读(6)  评论(0)    收藏  举报