BLOG-1
前言:三次题目集知识点、题量、难度总结
面向对象程序设计课程中,我通过三个阶段的题目集训练,从基础语法逐步深入到复杂系统设计,体验了软件开发迭代过程,深化了对面向对象编程的理解。
第一次题目集为基础夯实阶段,围绕Java基础语法与简单类设计,难度中等偏易,我全部完成并满分,掌握了字符串处理、正则表达式等基础技能,打下坚实基础。
第二次题目集为面向对象深化阶段,难度中等,考察单一职责原则等能力,我完成2题,电梯调度因超时未得分,理解了类职责划分的重要性。
第三次题目集为系统架构设计阶段,难度困难,培养迭代开发等能力,我完成1题,电梯调度迭代设计未完成,体会到复杂系统设计的挑战,暴露了自身不足。三次题目集难度递增,知识从基础扩展到架构设计。虽遇电梯调度困难,但明确了改进方向,提升了编程能力与工程思维。
设计与分析:单部电梯调度程序的三次迭代演进
2.1 第一次迭代:单类设计的深度分析
在第一次电梯调度程序的实现中,我提交了一个相对完整的代码,但在实际测试中由于性能问题只得到了零分。现在回过头来分析这份代码,能够清晰地看到其中存在的问题和改进空间。
import java.util.*;
public class Main{
public static void main(String[] args){
Scanner sc=new Scanner(System.in);
int a=sc.nextInt(),b=sc.nextInt();
Lift e=new Lift(a,b);
while(sc.hasNext()){
String s=sc.next();
if(s.equalsIgnoreCase("end"))break;
if(s.contains(",")){
String[] p=s.substring(1,s.length()-1).split(",");
e.addOut(Integer.parseInt(p[0]),p[1]);
}else e.addIn(Integer.parseInt(s.substring(1,s.length()-1)));
}
e.run();
}
}
class Lift{
int mi,ma,cu;
String di;
Set
public Lift(int m,int M){mi=m;ma=M;cu=1;di="UP";}
void addIn(int f){if(f>=mi&&f<=ma)in.add(f);}
void addOut(int f,String d){
if(f<mi||f>ma)return;
if(d.equals("UP"))up.add(f);
else if(d.equals("DOWN"))dn.add(f);
}
void run(){
while(!in.isEmpty()||!up.isEmpty()||!dn.isEmpty()){
if(di.equals("UP"))up();
else dn();
}
}
void up(){
for(;cu<=ma;cu++){
if(check())proc();
else out();
if(cuma||(in.isEmpty()&&up.isEmpty()))break;
}
if(!dn.isEmpty())di="DN";
}
void dn(){
for(;cu>=mi;cu--){
if(check())proc();
else out();
if(cumi||(in.isEmpty()&&dn.isEmpty()))break;
}
if(!up.isEmpty())di="UP";
}
boolean check(){
boolean s=in.remove(cu)||(di.equals("UP")?up:dn).remove(cu);
return s;
}
void proc(){
out();
System.out.println("Open Door # Floor "+cu);
System.out.println("Close Door");
}
void out(){
System.out.println("Current Floor: "+cu+" Direction: "+(di.equals("UP")?"UP":"DN"));
}
}
代码架构分析:
我采用了一个Lift类来承载所有功能,这种设计思路源于对面向对象理解的不足。从代码结构来看,这个类包含了电梯的所有状态(当前楼层、方向)和三个集合用于存储不同类型的请求。这种将所有功能集中在一个类中的做法,虽然在小型程序中看起来简单,但实际上违反了软件设计的多个基本原则。
核心算法问题:
分析我的实现代码,调度算法采用了最简单的逐层扫描方式。up()和dn()方法通过循环遍历每一层楼来检查是否需要停靠。这种方法的时间复杂度很高,特别是在高层建筑中,电梯需要逐层移动和检查,即使中间很多楼层没有请求。
void up(){
for(;cu<=ma;cu++){
if(check())proc();
else out();
if(cu==ma||(in.isEmpty()&&up.isEmpty()))break;
}
if(!dn.isEmpty())di="DN";
}
这种算法的效率问题及设计缺陷分析:这种算法的效率问题直接导致了运行超时。电梯在每一层都会停顿并输出状态信息,即使该楼层没有任何请求需要处理。
从面向对象设计角度看,这个实现存在几个关键问题:1.单一职责原则的违反:Lift类同时承担了状态管理、请求处理、调度算法、输入输出等多个职责。2.缺乏抽象层次:没有对不同类型的请求进行抽象,直接使用原始数据类型进行存储和处理。
通过分析代码运行过程,我识别出几个主要的性能瓶颈:1.请求检查的效率低下:每次移动都需要检查三个集合2.方向切换策略简单:只在端点切换方向,没有考虑中途的请求
2.2.第二次迭代:多类协作架构的理解
第二次迭代要求按照给定的类图进行多类设计,这让我第一次真正理解了职责分离的重要性。虽然没能完成代码实现,但通过分析类图,我对良好的软件架构有了深刻认识。这次设计将系统划分为四个核心类,每个类都有明确的职责边界。电梯类专注于状态管理,外部请求类封装请求信息,队列类负责数据管理,控制类实现调度算法。这种划分体现了单一职责原则的精髓。
通过分析类图,我理解了各个类之间如何通过清晰定义的接口进行协作。控制器作为协调者,使用电梯的状态信息和队列中的请求数据来做出调度决策。这种松耦合的设计使得系统更加灵活和可维护。在理解控制器类的设计时,我认识到智能调度算法的重要性。determineDirection()和getNextFloor()等方法体现了更加精细的控制策略,相比第一次实现中的简单方向切换,这种设计能够更有效地处理复杂的请求模式。虽然没有完成实现,但我认识到这种多类协作的设计实际上体现了多种设计模式的思想。控制器模式、队列模式等的应用,使得系统架构更加清晰和健壮。
2.3.第三次迭代:引入乘客类的架构演进
第三次迭代在第二次的基础上引入了乘客类,这是对系统概念的又一次重要抽象。通过统一内部和外部请求的表示方式,系统架构变得更加简洁和一致。用乘客类取代分离的内部和外部请求,这种设计的精妙之处在于它统一了系统的核心概念。无论请求来自电梯内部还是外部,都通过乘客对象来表示,只是属性的设置有所不同。这种统一简化了系统的理解和维护。从第一次的单类设计,到第二次的多类协作,再到第三次的概念统一,这个演进过程完美体现了软件设计的迭代改进思想。每一步都在前一步的基础上进行优化,既保持了连续性,又实现了质的提升。通过分析这三次迭代的设计思路,我对面向对象设计的核心原则有了更深刻的理解。封装、抽象、继承和多态不仅仅是理论概念,而是指导我们做出更好设计决策的实用工具。乘客类中的getDirection()方法就是一个很好的例子,它体现了对象行为的合理封装。
2.4.总结:这三次迭代的设计演进给了我一个重要启示:好的软件设计是一个不断学习和改进的过程。从最初只关注功能实现,到后来关注架构质量,再到关注概念的一致性和系统的可扩展性,这种思维层次的提升比单纯完成代码更有价值。
虽然第二次和第三次迭代没有完成代码实现,但通过深入分析设计思路和架构演进,我在软件设计理念和方法论方面获得了重要成长。这种对良好设计原则的理解,将为未来的软件开发工作提供坚实的基础。
三、改进建议:面向可持续改进的编码优化策略
第一次迭代电梯程序的深度重构建议
架构层面的重构方向:基于对第一次电梯程序代码的分析,我认为需要进行彻底的重构。首要任务是按照单一职责原则重新划分类的职责边界。应该将现有的单类拆分为四个核心组件:电梯状态管理器专门负责电梯的当前状态维护,请求处理器专注于请求的验证和存储,调度算法器实现智能的楼层选择策略,输出控制器处理所有的显示逻辑。
算法性能的优化策略:在调度算法方面,我建议采用LOOK算法替代当前的逐层扫描方式。这种算法能够让电梯在最高请求楼层和最低请求楼层之间往返运行,而不是机械地到达端点再反向。同时需要实现请求预排序机制,在添加请求时就按照楼层顺序排列,减少运行时的排序开销。还应该引入方向优化逻辑,优先处理顺路请求,避免不必要的方向切换。
代码质量的提升路径:在代码结构方面,我建议建立完善的异常处理机制,对无效楼层、错误格式等输入情况进行优雅处理。同时引入配置参数系统,将电梯的运行参数如加速度、开关门时间等外部化,提高系统的灵活性。最重要的是建立完整的日志记录体系,为调试和性能分析提供数据支持。
测试策略的改进方案:我建议采用测试驱动开发的方式,先编写测试用例再实现功能。特别是要为调度算法编写全面的单元测试,覆盖各种边界情况和异常场景。同时建立性能测试套件,确保程序在大规模请求下仍能保持高效运行。
多类协作设计的持续优化建议
架构扩展性的提升:在理解了多类协作的设计理念后,我认为可以进一步引入接口抽象层。定义电梯操作接口、调度策略接口等,使得具体的实现可以灵活替换。同时考虑采用依赖注入的方式管理类之间的依赖关系,降低耦合度。
设计模式的应用深化:我建议在控制器中引入策略模式,将不同的调度算法如SCAN、LOOK、FCFS等封装成可替换的策略。同时可以使用观察者模式来管理电梯状态的变化通知,让相关组件能够及时响应状态更新。
性能监控机制的建立:为了持续优化系统性能,我建议建立运行时的性能监控机制。记录电梯的空闲时间、平均等待时间、运行效率等关键指标,为后续的算法优化提供数据依据。同时可以实现动态参数调整,根据实时负载情况自动优化调度参数。
乘客类设计的演进优化
领域模型的精炼:在乘客类的设计基础上,我建议进一步丰富领域模型。可以引入旅程概念,将一次完整的乘梯过程抽象为独立的业务对象。同时建立楼层管理器,封装楼层的相关行为和约束。
业务逻辑的封装优化:我建议将更多的业务逻辑封装在适当的对象中。比如方向判断逻辑可以进一步细化,考虑电梯当前负载、能耗等因素。请求验证逻辑应该更加完善,包括楼层有效性、方向合理性等多维度检查。
系统可观测性的增强:为了支持持续的改进,我建议建立完善的可观测性体系。包括运行日志、性能指标、业务事件等多个维度的监控。通过数据分析来发现系统的瓶颈和优化机会,形成改进闭环。
编码实践的持续改进建议
开发流程的规范化:制定编码规范,统一代码风格和质量标准。引入静态代码分析工具,自动检测代码中的潜在问题。
重构时机的把握:根据代码坏味及时识别重构需求。当发现类职责过重、方法过长、重复代码等问题时,应该立即安排重构。建立技术债务管理机制,定期评估和偿还技术债务。
学习改进的机制化:建立定期的技术分享,积累常见的解决方案和最佳实践。通过复盘每次迭代的经验教训,形成持续改进的组织能力。
我认为需要培养产品化思维,不仅要考虑代码的正确性,还要考虑可维护性、可扩展性、性能等工程化指标。同时建立用户视角,理解真实用户的使用场景和需求。将代码质量作为首要考量因素,确保代码变更不会引入回归问题。最重要的是建立持续改进的文化,将优化作为日常开发的一部分。这些改进建议不仅适用于电梯调度程序,也具有普遍的指导意义。通过持续的技术改进和工程实践,我们能够不断提升软件开发的质量和效率,真正实现可持续的改进目标。
总结:面向对象编程学习的深度反思与成长
本阶段学习成果综合性总结
通过三次题目集的系统训练,我在面向对象编程领域获得了实质性的成长和突破。这一阶段的学习不仅仅是语法和技术的积累,更重要的是编程思维和工程理念的根本转变。
在知识体系构建方面,我完成了从基础语法到系统设计的完整跨越。第一次题目集让我夯实了Java编程基础,掌握了字符串处理、正则表达式和简单类设计等核心技能。第二次题目集引导我进入面向对象设计的深水区,理解了单一职责原则、状态管理和业务建模的重要性。第三次题目集则让我初步接触了系统架构设计和迭代开发理念,虽然实现上存在困难,但在设计思维上获得了重要启发。
在工程能力培养方面,我经历了从"能运行"到"好设计"的重要转变。最初我只关注代码能否正确运行,后来逐渐认识到代码质量、可维护性和可扩展性的价值。通过电梯调度程序的三次迭代设计,我深刻体会到良好的架构设计对软件质量的决定性影响。
在问题解决能力方面,我学会了更加系统化的分析方法。从最初的盲目调试,到后来的逻辑推理和性能分析,我逐渐建立了科学的调试思路。特别是在处理复杂系统时,分层思考、模块化分析的方法让我能够更有效地定位和解决问题。
需要进一步学习和研究的领域
基于本阶段的学习体会,我认识到在以下几个领域需要深入学习和研究:
在设计模式与架构方面,我需要系统学习常用的设计模式及其应用场景。特别是对于复杂系统的架构设计,需要掌握更多的实践经验和设计原则。如何在不同约束条件下做出合理的设计权衡,这是需要长期积累的重要能力。
在算法与数据结构方面,电梯调度程序的经历让我认识到算法优化的重要性。我需要加强算法思维训练,学习更多高效的算法设计和分析方法。同时,理解数据结构对算法性能的影响,掌握在不同场景下选择合适数据结构的能力。
在软件工程实践方面,我需要学习更多工程化的开发方法和工具。包括版本控制、持续集成、自动化测试、代码审查等现代软件开发实践。这些工程实践对于保证软件质量和团队协作至关重要。
在系统分析与建模方面,我需要提升抽象思维和建模能力。学会从需求中识别核心概念,建立准确的领域模型,设计合理的系统架构。这方面的能力决定了软件设计的质量和可持续性。
对教学体系的改进建议
基于本阶段的学习体验,我对课程教学提出以下改进建议:在教学内容的组织方面,我建议增加更多真实项目的案例分析和代码审查环节。通过分析优秀的开源项目或往届学生的优秀作业,能够更直观地理解良好设计的原则和实践。同时,建议提供更多关于调试技巧和性能优化的专题指导,这些实用技能对学生的工程能力培养至关重要。
在实践环节的设计方面,我建议建立更加循序渐进的练习体系。对于复杂如电梯调度的题目,可以提供中间步骤的参考实现或设计思路提示,帮助学生理解架构演进的过程。同时,建议组织小组代码重构活动,让学生在协作中相互学习和提高。
在学习资源的建设方面,我建议建立更加完善的知识库和FAQ系统。收集整理常见问题的解决方案、典型错误的分析以及优秀代码的范例,为学生提供更丰富的学习参考资料。特别是对于设计原则和架构模式,提供更多具体实例的讲解。
在课程反馈机制方面,我建议建立更及时和具体的作业反馈渠道。除了自动评测系统的结果外,提供更多关于代码质量、设计思路的个性化反馈。可以引入助教代码审查机制或同伴互评活动,让学生从多个角度了解自己代码的优缺点。
对学习方法的反思与调整
通过这一阶段的学习,我也认识到需要调整和优化自己的学习方法:我需要建立更加系统的知识整理习惯,及时总结每个题目集中的收获和教训,形成自己的知识体系。同时,应该加强理论学习和实践的结合,在理解设计原则的基础上,通过实际编码来深化认识。我还需要培养持续改进的工程思维,将每次作业不仅视为任务完成,更视为技术成长的机会。主动思考代码的优化空间,勇于尝试新的设计思路和技术方案。最重要的是,我需要建立更加积极主动的学习态度,遇到困难时不轻易放弃,而是通过查阅资料、请教老师、与同学讨论等多种途径寻求解决方案。这一阶段的编程学习让我深刻认识到,软件开发的精髓不在于语法的熟练,而在于设计思维和工程能力的培养。这种认知的转变将对我未来的技术成长产生深远影响,为成为合格的软件工程师奠定坚实基础。
浙公网安备 33010602011771号