第二次bolg作业
第四单元(JML 规格编程,三次迭代)
核心知识点:JML 行为规格语言、契约式编程、图存储与查询优化、容器性能调优、异常规范;
题量:每次作业包含图节点增删、连通性查询、最短路径、换乘路径等十余类查询接口,单次代码量 400~700 行;
难度梯度:HW9 基础无向图(简单)→HW10 有权图 + 距离查询(中等)→HW11 地铁换乘多约束查询(困难);
核心难点:严格遵循 JML 前置 / 后置条件、暴力遍历导致超时、容器数据一致性维护。
第五单元(多线程电梯调度,三次迭代)
核心知识点:生产者消费者模型、线程同步锁、线程安全、Look/SSTF 调度算法、多电梯资源竞争、换乘逻辑;
题量:单 / 多部电梯、人数限制、负楼层、动态新增电梯、换乘路径,并发时序逻辑复杂;
难度梯度:单电梯捎带(简单)→多部电梯容量限制(中等)→多类型电梯 + 换乘机制(困难);
核心难点:线程死锁、共享队列同步失效、调度算法饥饿、换乘状态标记错乱。
第六单元(数字电路仿真程序 4,四次迭代)
核心知识点:组合模式、抽象元件继承、文本词法解析、信号拓扑传递、子电路命名空间、多优先级异常校验;
题量:基础逻辑门→复合组合元件→时序电路→子电路复用 + 异常检测,输入语法分支极多;
难度梯度:基础门电路仿真(易)→多引脚控制元件(中)→子电路封装(难)→全量异常分级校验(极难);
核心难点:组合模式分层实现、子电路独立命名空间隔离、连接语句多异常优先级判定、信号拓扑循环计算。
三套作业总代码量超 2000 行,覆盖形式化设计、并发编程、设计模式工程落地三大 OO 核心模块,全程使用 IntelliJ IDEA 搭配 MetricsReloaded 插件完成代码度量,依靠 JUnit 单元测试与黑箱随机对拍完成全量测试,下文从设计分析、采坑、改进、综合收获分层复盘。
一、设计与源码度量分析(附 Metrics 报表、UML 类图解读)
本章节每套作业分别讲解 UML 类图整体结构、MetricsReloaded 量化指标、整体架构设计思路,结合 ev (G) 基本复杂度、iv (G) 设计复杂度、v (G) 圈复杂度、OCavg 平均复杂度、WMC 总权重复杂度五项核心指标分析代码优劣,全程结合代码实际运行数据、类结构逻辑进行解释,做到有图、有量化数据、有落地心得。
(一)第四单元 JML 规格编程 设计分析
- UML 类图整体架构
整体采用三层分层结构,层级边界清晰:第一层为数据实体层,包含 MyPerson 节点实体、MyPath 边实体,仅负责存储基础属性与 get/set 访问方法;第二层为容器管理层,MyPathContainer 作为基础无向图容器封装节点、边的增删公共逻辑,MyGraph 继承基础容器扩展权重与最短路径查询,MySubway 再次继承有权图,实现地铁换乘专属查询逻辑;第三层为异常与程序入口层,自定义多类规格相关异常,主运行类仅负责读取输入、调用容器接口,全程严格匹配 JML 规格完成入参校验。
整体继承链路清晰,父类封装通用逻辑,子类仅拓展专属业务,初步符合开闭设计原则。 - Metrics 代码度量报表解读(HW11 最终完整版本核心类)
整套代码中复杂度最高的类为 MySubway 换乘容器,总权重复杂度 WMC 达到 53,平均方法复杂度 OCavg 为 3.31,远超底层基础容器。其中核心换乘查询方法 getTransferPath 是全项目复杂度峰值,圈复杂度 v (G)=16,设计复杂度 iv (G)=15,基本复杂度 ev (G)=6。
指标背后代表的代码问题十分直观:v (G)=16 意味着该方法内部存在 16 条互不相同的独立执行路径,测试阶段至少需要 16 组独立用例才能完整覆盖全部分支;iv (G)=15 代表该方法高频依赖其他多个类的接口,类与类之间耦合度极高,底层容器数据结构一旦修改,换乘查询逻辑必须同步改动,维护成本大幅提升;ev (G)=6 说明方法内部存在多层嵌套循环与多重 if 判断,代码结构化程度差,后续重构拆分难度很大。
底层基础容器 MyPathContainer 总权重复杂度仅 18,平均方法复杂度 1.42,内部增删节点、路径的方法圈复杂度全部控制在 3 以内,逻辑简单清晰,几乎不存在隐藏 bug;MyPerson 实体类、所有自定义异常子类仅包含基础属性与构造方法,各类复杂度指标均维持在极低水平,无任何设计缺陷。 - 架构设计心得
项目初期开发思路完全直译 JML 自然语言描述,使用双层 List 分别存储节点与边,每一次连通性、路径查询都需要暴力遍历全部存储元素,公测阶段大批量测试用例出现运行超时。后期重构时将存储容器替换为 HashMap,以元素 ID 作为键实现 O (1) 快速查询,连通性引入并查集缓存、最短路径预生成距离矩阵,把单次查询时间复杂度从线性级别降低至常数级别,解决超时问题。
但整套架构存在明显设计短板:顶层 MySubway 容器承担了全部换乘业务查询逻辑,没有拆分独立的查询工具类,违反单一职责原则;所有查询逻辑全部耦合在顶层容器内部,后续新增换乘约束、换乘权重时,必须直接修改 MySubway 核心代码,破坏开闭原则。
(二)第五单元 多线程电梯调度 设计分析 - UML 类图架构(生产者消费者标准模型)
整体基于生产者消费者并发模型搭建,类间交互关系划分明确:InputThread 为生产者线程,持续读取控制台输入的乘客请求,将请求写入全局共享等待队列;Controller 调度器作为全局共享资源管理者,统一维护等待乘客队列、换乘乘客队列,通过同步机制控制多线程读写竞争;Elevator 为消费者线程池,每一台电梯对应独立线程,循环从调度器获取可捎带乘客,完成上下行、开关门、乘客换乘全流程;Customer 实体存储乘客起点、终点、换乘标记等基础信息;SafePrint 作为工具类实现线程安全打印,规避多线程同时输出造成的文字乱序。
程序运行时序固定:主函数启动输入线程与全部电梯线程,输入线程持续投放乘客请求,多台电梯竞争获取待运送乘客,到达换乘楼层后将需要中转的乘客写入换乘队列,由调度器二次分配给对应电梯完成换乘。 - Metrics 度量报表解读(第三次多电梯换乘完整版)
整套代码中 Elevator 电梯类总权重复杂度 WMC 为 34,平均方法复杂度 OCavg=2.71,其中电梯运行主循环 run 方法圈复杂度 v (G)=13,设计复杂度 iv (G)=11。主循环内部包含上行、下行、开门、乘客进出、换乘条件多重分支判断,是整个并发程序的逻辑核心,大量调用调度器同步接口,线程之间耦合紧密。
调度器 Controller 总权重复杂度 26,平均复杂度 2.36,hasPassenger 乘客判断方法圈复杂度达到 26,方法内部需要同时遍历等待队列、电梯内部乘客、换乘队列三层循环,分支数量极多,是程序运行性能瓶颈。
Customer 乘客实体类平均复杂度偏低,但换乘判断方法认知复杂度偏高,需要同时校验楼层范围、电梯可达楼层、行进方向十余层条件,极易遗漏边界场景;输入线程与安全打印工具类逻辑极简,各项复杂度指标全部处于合理区间。 - 架构设计心得
生产者消费者模型天然适配输入生成请求、电梯消费请求的业务场景,全局统一调度队列避免单台电梯独立维护请求列表造成的数据割裂。三次迭代开发过程中,仅需要新增换乘队列、电梯容量上限判断逻辑,电梯基础运行、开关门代码完全复用,代码复用率表现较好。
架构存在三处核心缺陷:第一,没有抽象调度算法接口,SSTF、Look 两种调度逻辑直接硬编码在调度器内部,后续新增调度策略必须修改调度核心;第二,同步机制全部采用方法级 synchronized 粗粒度锁,多电梯并发运行时频繁阻塞,程序整体吞吐量下降;第三,Customer 实体同时存储乘客基础信息、换乘状态标记,一个类承担两类无关数据存储职责,不符合单一职责设计要求。
(三)第六单元 数字电路仿真 4(含子电路 + 异常检测)设计分析 - UML 组合模式类图(严格匹配题目 Composite/Leaf 设计要求)
顶层抽象类 CircuitComponent 作为组合模式统一父类,规定 calcOutput 计算输出、getPins 获取引脚两套通用接口,所有电路组件都继承该抽象类,实现统一调用;BaseGate 为基础门抽象叶子类,衍生 AndGate 与门、OrGate 或门、NotGate 非门、XorGate 异或门、XnorGate 同或门五个具体元件,属于组合模式中的 Leaf 叶子节点,不可再拆分内部组件;SubCircuit 子电路类为 Composite 复合容器,内部存储基础门、甚至嵌套其他子电路,维护子电路输入输出引脚映射关系,递归调用内部元件完成信号电平计算;Lexer 词法解析类负责拆分所有输入文本,区分主电路、子电路、连接语句、全局输入信号;SignalMap 全局信号管理器统一存储所有引脚电平,同时处理连接关系映射、各类输入异常检测;额外维护异常优先级枚举,统一规范错误输出文本。
完全贴合题目指定组合模式设计思路:基础逻辑门是最小叶子单元,子电路是可包含多个元件的复合单元,主电路无需区分普通门元件与子电路,直接调用统一计算接口,实现无差别信号运算。 - Metrics 度量报表解读(最终完整仿真程序)
整套代码复杂度最高的类为 Lexer 词法解析类,总权重复杂度 62,平均方法复杂度 4.12,核心连接语句解析方法 parseConnectLine 圈复杂度 v (G)=28。该方法需要拆分带中括号的连接语句,同时按照题目给定优先级依次校验五类连接异常,多层 if 分支判断异常等级,是全项目分支最多、最容易出现逻辑漏洞的方法。
信号管理器 SignalMap 总权重复杂度 45,平均复杂度 3.75,异常校验方法 checkConnectError 圈复杂度 19,遍历全部连接引脚检测多信号冲突、引脚顺序颠倒、无输入输出等边界错误,同时耦合词法解析结果与全局电平存储表;子电路 SubCircuit 总权重 31,递归计算方法 recursiveCalc 圈复杂度 12,逐层遍历内部所有元件,按照依赖关系递归计算电平,存在循环电路依赖的潜在风险。
五个基础门子类平均复杂度仅 1.2,各自重写 calcOutput 计算方法,逻辑独立拆分,依靠多态实现不同门电路运算规则,可快速拓展全新元件,架构拓展性优秀;主仿真启动类逻辑简单,各项复杂度指标全部偏低。 - 架构设计心得
组合模式是本次作业最大的学习收获,统一抽象基础门与子电路,上层调用代码不需要感知底层组件类型,只需要调用通用计算接口。迭代开发第三、第四版本新增子电路功能时,仅需要新增 SubCircuit 复合容器类,原有全部基础门、信号管理、解析代码不需要任何改动,完美契合开闭原则。
架构两处明显短板:第一,Lexer 词法解析类职责过度臃肿,同时承担文本拆分、子电路解析、连接语句识别、异常判定多项无关工作,平均复杂度居高不下;第二,信号计算没有提前生成拓扑排序缓存,每次输出全部元件电平都需要全量递归遍历,大量重复运算,大规模电路场景下运行效率偏低。
二、采坑心得(详实数据、测试用例、代码结构佐证)
(一)第四单元 JML 单元典型 Bug 与踩坑
直译 JML 暴力遍历导致超时(公测 3 个测试点未通过)
故障现象:HW10 有权图最短距离查询功能,每次调用遍历全部节点与边完成计算,节点规模达到 1000 个时程序运行超时。
量化数据佐证:单条查询未优化前平均运行耗时 1200 毫秒,改用距离缓存矩阵优化后单次查询耗时降低至 15 毫秒,性能提升数十倍。
问题根本原因:开发初期误解 JML 规格作用,JML 仅约束程序输出结果,不会限制内部实现方式,机械直译规格中的数学求和逻辑,没有采用空间换时间的优化思路。
修复方案:新增全局距离二维缓存数组,增加、删除路径时同步更新缓存数据,查询距离直接读取缓存数值,不再实时遍历计算。
JML 前置条件校验缺失,规格异常未抛出
故障现象:调用查询接口传入不存在的节点 ID,程序没有按照 JML 要求抛出 PersonNotExistException 异常,互测阶段被针对性测试用例捕获。
标准复现测试用例:调用 queryBlockSum 连通性查询方法,入参传入不存在的 ID-999,程序无任何异常输出,违背 JML requires 前置约束。
根因:所有查询接口方法开头没有统一校验节点 ID 是否存在,直接进入核心计算逻辑。
修复方案:封装独立工具方法 checkPersonExist,全部查询接口第一行统一调用该方法,不存在对应节点则直接抛出指定规格异常。
并查集缓存更新逻辑不同步,连通性查询结果错误
故障现象:删除图中路径后,并查集连通关系没有同步重置,原本互不连通的节点会被判定为连通,查询结果完全失真。
代码结构漏洞:并查集仅在新增路径时更新父子关系,删除路径没有配套的回滚、重置逻辑,缓存数据与实际图结构不一致。
最终解决方案:放弃并查集缓存优化,改用 BFS 广度优先搜索动态实时查询连通块,保证节点、路径增删后查询结果完全一致。
(二)第五单元 多线程电梯并发踩坑(线程安全、调度、换乘)
粗粒度同步锁造成多电梯严重阻塞(强测 6 个性能测试点得分偏低)
故障现象:三台电梯同时尝试从全局等待队列获取乘客,同一时间仅一台电梯能够读取队列数据,剩余电梯长时间阻塞等待,程序运送效率极低。
度量指标佐证:调度器所有读写队列方法全部添加方法级 synchronized 锁,方法设计复杂度 iv (G) 偏高,电梯线程与调度器耦合严重,并发能力受限。
修复方案:替换同步锁机制,引入 ReentrantReadWriteLock 读写分离锁,读取乘客队列使用共享读锁,修改队列数据时使用独占写锁,优化后多电梯并发吞吐量提升六成。
换乘乘客状态标记缺失,程序无限死循环无法结束
故障现象:乘客抵达换乘楼层后,没有标记换乘完成状态,重复写入换乘队列,电梯反复接送同一批中转乘客,程序持续运行无法正常退出。
标准复现测试用例:乘客起点 1 层、终点 3 层,需要在 15 层换乘;电梯抵达 15 层后没有修改乘客换乘完成布尔标记,乘客持续停留在换乘队列中。
根因:Customer 实体的 needExchange 换乘判断逻辑仅校验楼层条件,没有更新换乘完成状态标识。
修复方案:乘客完成换乘操作后立即修改 haveExchanged 布尔标记,后续判断时直接跳过已完成换乘的乘客。
电梯载客计数逻辑存在遗漏,超出容量限制仍允许乘客进入
互测攻击测试案例:电梯最大载客容量 7 人,连续放入 8 名乘客,程序没有任何拦截,违反题目容量约束。
代码漏洞根源:电梯初次开门的入客逻辑没有增加人数判断,仅常规开关门时统计电梯内部乘客数量,同类业务逻辑分散在多个分支方法中,极易遗漏边界判断。
开发教训:同类业务判断逻辑不能分散在多处分支,统一封装 addPassengerCount 计数工具方法,所有乘客进出场景统一调用。
线程结束标记缺失,程序运行完毕无法正常退出
故障根因:没有设计全局程序停止布尔标记,输入线程读取完全部输入数据后没有修改停止状态,电梯循环持续阻塞等待新乘客请求。
修复方案:输入线程读取完毕所有输入后,修改调度器全局 stop 停止标记;电梯运行循环第一步先判断停止标记,标记为 true 则直接结束线程。
(三)第六单元 数字电路仿真踩坑(解析、异常、子电路、信号)
连接语句异常判断顺序颠倒,错误输出提示(样例 8 全部判定错误)
题目规定异常优先级从高到低依次为:多条输出引脚、无输入引脚、无输出引脚、输入输出顺序颠倒、引脚信号冲突。
初期开发 Bug:代码优先检测引脚信号冲突,再判断多输出引脚异常,当同一行连接语句同时包含两类错误时,输出低优先级报错信息,与样例输出标准不符。
修复方案:严格按照题目给定优先级顺序依次判断异常,一旦匹配某一类错误,立即输出对应 ERROR 提示,终止当前行解析流程,不再校验后续异常类型。
子电路命名空间隔离失效,主电路与子电路同名元件电平相互覆盖
标准复现测试用例:主电路存在非门 N1,子电路 C1 内部同样定义非门 N1,两者信号电平存储时互相覆盖,电路运算结果完全错乱。
根因:全局信号存储容器仅使用元件名称作为键,没有增加子电路编号区分不同命名空间。
修复方案:子电路内部所有引脚存储键统一拼接子电路编号前缀,格式为 C1-N1-0,主电路普通引脚直接使用元件引脚名,两类命名空间完全隔离,不存在键值覆盖问题。
元件输入引脚缺失校验遗漏,无完整输入的元件依旧输出计算结果(样例 6 不满足要求)
故障现象:异或门 X2 仅接入 1 号输入引脚,缺少必需的 2 号引脚,程序依旧计算并输出电平,没有按照要求忽略该元件。
根因:元件 calcOutput 计算方法没有提前校验该元件全部规定输入引脚是否存在有效电平信号。
修复方案:每一种基础门计算电平前,遍历该元件要求的全部输入引脚编号,若存在任意引脚无有效信号,标记元件计算结果无效,最终输出阶段直接跳过该元件。
词法解析文本处理漏洞,带中括号的连接语句识别失败
初期处理逻辑直接对整行文本按空格分割,没有剥离首尾中括号符号,分割后第一个 token 附带左括号、最后一个 token 附带右括号,无法匹配引脚名称。
修复方案:解析连接语句时,先截取中括号内部纯文本内容,去除首尾符号后再进行空格分割,消除特殊符号对匹配逻辑的干扰。
输入引脚多信号冲突检测逻辑缺失,多条连接指向同一引脚不报错
数据结构设计缺陷:全局信号容器仅存储引脚对应的电平数值,没有记录该引脚信号来源的输出引脚,无法判断是否存在多路信号输入同一引脚。
修复方案:新增独立映射容器 pinSource,键为输入引脚名称,值为提供信号的输出引脚;新增连接关系时,若输入引脚已存在映射记录,直接抛出引脚信号冲突异常。
通用踩坑总结
第一,迭代开发时直接复制上一版旧代码复用,会同步遗留历史隐藏 Bug,第五单元换乘功能直接复用单电梯基础代码,遗漏载客容量判断逻辑;
第二,圈复杂度 v (G) 超过 10 的方法是 Bug 高频出现区域,多层循环、多重 if 分支极易漏掉边界测试场景,必须拆分为多个小型工具方法;
第三,单纯依靠黑箱随机测试无法覆盖规格前置条件、多异常优先级这类细分分支,单元测试是兜底的核心手段;
第四,迭代开发过程中新增功能直接修改原有核心类,持续提升代码耦合度,后期重构、修复缺陷成本成倍上涨。
三、代码可持续改进建议
结合三套作业的量化度量指标、架构固有缺陷,从分层解耦、设计模式落地、运行性能、自动化测试、异常管理、迭代拓展预留接口六个维度,给出可直接落地的长期改进方案。 - 分层拆分,降低单类复杂度,解决 WMC、OCavg 指标超标问题
针对第四单元 JML 图程序:将换乘路径、最短路径查询逻辑剥离至独立 QueryTool 工具类,MySubway 容器仅负责存储原始数据,所有复杂计算委托工具类执行,降低顶层容器总权重复杂度;
针对第五单元电梯程序:把调度算法单独抽象 ScheduleStrategy 顶层接口,SSTF、Look 两种算法分别实现独立子类,调度器仅持有策略对象,后续新增调度规则无需修改调度核心代码;
针对第六单元数字电路程序:将 Lexer 词法解析类拆分为文本拆分 Lexer、异常校验 ErrorChecker 两个独立类,文本处理与错误判定完全解耦,解决解析方法圈复杂度过高的问题;
通用改进原则:单个类代码超过 300 行、总权重复杂度 WMC 超过 30 时,必须拆分辅助工具类,单一类只负责一类独立职责。 - 充分落地设计模式,强化代码开闭原则
JML 图单元引入工厂模式统一创建 MyPerson、MyPath 实体,实体参数校验逻辑集中在工厂内部,消除项目各处重复的新建对象判断代码;
电梯单元采用模板方法模式封装电梯运行基础流程,上行、下行、开关门作为可重写钩子函数,后续新增特殊类型电梯仅需要重写对应钩子方法;
数字电路单元完善完整组合模式体系,未来新增 D 触发器、JK 触发器等时序元件,仅需要新增 Leaf 叶子子类;新增译码器、多路选择器等复合元件,统一继承 BaseComposite 复合父类,原有解析、信号计算代码无需改动。 - 程序运行性能优化方案
JML 图查询模块:将全量预生成距离缓存改为惰性缓存,仅用户触发查询时计算对应节点距离,减少程序初始化内存开销;
多线程电梯模块:替换基础 ArrayList 等待队列,使用 ConcurrentLinkedQueue 线程安全容器;读写分离锁替换全局粗粒度 synchronized 锁,提升多电梯并发效率;
数字电路信号计算模块:增加拓扑排序预处理逻辑,按照信号依赖先后顺序统一计算电平,避免无意义重复递归遍历;已经完成计算的引脚电平添加全局缓存,重复读取时直接复用缓存结果。 - 搭建完整自动化测试体系,降低公测、互测 Bug 概率
单元测试层面:使用 JUnit 覆盖全部工具方法、所有分支边界场景,针对 JML 每条 requires 前置条件、ensures 后置条件编写对应独立测试用例;
自动化对拍层面:使用 Python 脚本批量生成随机输入数据,同时运行本人代码与标准参考程序,自动比对两行输出文本,批量定位逻辑差异;
边界专项用例:单独整理空白输入、引脚信号冲突、多层嵌套子电路、电梯满载、非法 JML 节点 ID 等极限场景用例,单独批量测试;
提交门禁规范:正式提交代码前使用 MetricsReloaded 自动校验复杂度,圈复杂度 v (G) 超过 15 的方法必须拆分重构,否则禁止提交评测。 - 异常与输入解析逻辑解耦
三套作业统一存在硬编码异常提示、异常判定与文本解析耦合的问题,优化方案分为三层:
第一,统一定义全局异常枚举类,枚举内部存储异常优先级、标准输出文本,后续新增异常类型仅拓展枚举条目,不需要修改全部分支判断逻辑;
第二,词法解析类仅负责切分原始文本生成 token 序列,所有异常校验逻辑委托独立校验类执行,文本解析与错误提示完全分离;
第三,自定义项目专属业务异常类,替代直接控制台打印 ERROR 文本,上层主程序统一捕获异常对象并输出标准提示,便于后续拓展日志记录、错误定位功能。 - 预留迭代拓展接口,适配未来需求升级
JML 图模块:抽象图权重顶层接口,后续新增费用、通行时间等多维度权重,不需要修改原有路径查询接口;
电梯模块:抽象电梯能力接口,定义电梯可达楼层、最大载客容量通用方法,新增特种电梯仅需要实现该接口;
数字电路模块:抽象引脚顶层接口,区分输入引脚、输出引脚、控制引脚三类实现,第三版时序电路需要的控制引脚可以无缝接入现有架构;子电路输入输出映射统一使用 Map 容器存储,天然支持多输入、多输出子电路拓展。
四、阶段综合性总结
(一)三套作业学到的核心能力
契约式形式化开发思维(JML 单元)
彻底摆脱依靠主观阅读理解需求的开发模式,学会使用无歧义规格语言约束代码输入输出边界,清晰区分需求标准与内部实现方案;理解性能优化不能破坏 JML 前置、后置约束条件,建立大型多人协作项目的标准化开发规范认知。
并发多线程开发与线程安全管控(电梯单元)
熟练掌握生产者消费者经典并发模型,理解共享资源同步锁的使用场景,掌握死锁产生条件与规避手段;能够区分粗粒度锁、细粒度读写锁对并发性能的不同影响;学会多线程运行时序分析、线程安全打印设计,理解调度算法对系统整体吞吐量的决定性作用。
设计模式工程化落地实操(数字电路单元)
完整落地组合模式,理清叶子节点与复合容器之间 is-a 继承、has-a 包含两类核心关系,掌握递归组合结构的数据运算逻辑;学会分层抽象架构设计,把频繁变更的业务逻辑(各类门、子电路)与稳定底层模块(文本解析、信号存储)完全隔离,深度理解开闭原则对迭代开发的核心价值。
代码度量与质量重构通用方法论
熟练使用 MetricsReloaded 解读三类复杂度指标,依靠量化数据客观定位高耦合、高风险代码;掌握拆分独立方法、抽象顶层接口、缓存重复计算、分层解耦四类通用重构手段,能够从架构根源减少程序隐藏 Bug。
工程化全流程测试思维
建立三层完整测试体系:单元测试覆盖底层工具逻辑、黑箱对拍批量验证整体输出、边界专项用例覆盖极限场景,不再依靠人工手动少量造用例测试;能够针对增量迭代需求针对性设计新增分支、异常场景测试用例。
(二)现存能力短板,后续深入学习方向
设计模式掌握程度片面
仅能够熟练落地组合模式、简易工厂模式,观察者、策略、模板方法等常用模式仅停留在理论认知层面,没有在完整项目中独立搭建多模式协同架构,后续自主搭建小型综合项目练习多模式组合使用。
多线程高级机制掌握不足
仅会基础 synchronized 同步锁、普通阻塞队列,CountDownLatch、Semaphore 信号量、自定义线程池参数调优等高级并发工具完全不熟悉;多线程死锁定位、并发性能调优实战经验匮乏。
形式化验证工具使用薄弱
JML 规格仅依靠人工逐行对照代码检查,不会使用配套工具自动校验规格实现一致性,无法自动化生成符合前置约束条件的测试输入。
算法优化思路局限
JML 图、数字电路两套程序大量使用暴力遍历逻辑,最短路径、拓扑排序等基础图论算法仅能基础调用,缺少缓存、剪枝优化思维,面对大规模输入数据极易出现超时问题。
代码规范与工程文档意识薄弱
迭代新增的方法、复杂逻辑缺少规范 Javadoc 注释,关键业务流程没有文字说明;异常提示、常量数值全部硬编码分散在代码各处,没有统一常量、枚举容器管理,代码可读性较差。
(三)整体学习感悟
从课程前期第一单元表达式处理面向过程暴力编码,到本次第四、五、六单元分层抽象、设计模式落地、并发编程、形式化规格开发,完整走完面向对象从基础入门到工业级工程落地的全部学习流程。三套迭代作业漫长的调试、重构、性能优化过程,让我真正理解面向对象开发不只是简单创建类、使用继承语法,核心是抽象、解耦、可拓展、可测试的整套工程化思想。
增量迭代作业高度模拟真实企业软件开发流程:需求持续叠加更新、历史代码需要兼容复用、原有业务逻辑不能大面积改动,倒逼我主动思考架构分层、开闭原则的实际落地方式;多线程调度、多层嵌套子电路这类高复杂度场景教会我拆分复杂问题,将大型系统拆解为多个独立可复用组件;代码度量工具提供客观量化评判标准,不再仅凭主观感受判断代码设计优劣。
后续学习阶段,我会针对性巩固并发编程、设计模式、算法优化三大短板,编写代码前优先完成 UML 架构建模,严格遵循单一职责、开闭两大核心设计原则,重视单元测试与代码注释规范,把本次复盘总结的避坑、重构经验运用到后续所有开发任务中。同时本次完整复盘博客可以作为简历工程实践素材,完整展示需求迭代、架构设计、故障排查、性能优化全链路开发能力。
浙公网安备 33010602011771号