尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

数字电路仿真作业集4-6 阶段性开发总结与深度复盘

数字电路仿真作业集4-6 阶段性开发总结与深度复盘
📅 发布时间:2026/6/21 18:27:17

一、前言

在本学期的软件工程实践课程中,我依次完成了数字电路仿真方向的三份作业,分别是作业集4基础逻辑门电路仿真、作业集5多功能器件拓展仿真和作业集6支持子电路嵌套的分层仿真。三份作业并不是独立的内容,而是循序渐进、层层拔高的训练过程。从最开始只实现简单的与、或、非门电路,到新增译码器、多路选择器等复杂器件,最后完成支持子电路嵌套的分层仿真系统,整体难度、代码量、逻辑复杂度都在不断提升。

作业集4属于入门练习,主要帮助我熟悉Java抽象类、继承和多态的使用方式,理解数字电路信号传播和迭代仿真的基本原理。题目逻辑简单,分支判断少,边界用例数量有限,重点在于掌握基础的面向对象写法和仿真流程。作业集5在原有门电路的基础上增加了多种特殊功能器件,包括三态门、译码器、多路选择器、多路分配器等,部分器件拥有多引脚、多输出的特点,不再是简单的单一输出逻辑,需要针对不同器件单独重写计算方法和输出格式,代码量明显增加,需要处理的边界情况也多了很多。

作业集6是三份作业中难度最高、综合性最强的一次训练。本次作业新增了子电路分层嵌套功能,程序需要同时处理主电路和多个子电路,并且保证子电路信号相互隔离、互不干扰。除此之外,还需要完成输入语法校验、信号冲突检测、错误信息输出等功能,输入格式分支多、逻辑嵌套深,对代码结构和调试能力要求很高。整体来看,三次作业完整覆盖了面向对象编程、容器使用、迭代仿真算法、文本解析、分层程序设计等知识点,让我从只会简单功能实现,慢慢开始学会考虑代码结构、程序鲁棒性和运行稳定性。

二、设计与分析

为了更客观地分析自己的代码质量,我使用了SourceMonitor工具统计代码规模与复杂度,同时利用PowerDesigner梳理整体类结构。结合工具生成的数据和类图,我对三次作业的代码设计、实现思路和存在的问题进行详细分析。

2.1 代码量化数据分析

通过SourceMonitor统计得到三份作业的核心代码数据,包括代码行数、类数量、方法数量、圈复杂度等,能够直观看出三次作业的提升与不足,具体数据如下:

作业批次 有效代码行数 自定义类数量 核心方法数 平均方法行数 最大圈复杂度
作业集4 442行 7个 12个 18行 22
作业集5 715行 11个 18个 23行 28
作业集6 1036行 13个 26个 30行 41

从数据可以明显看出,随着功能不断增加,代码体量和复杂度持续上升。圈复杂度不断变高,主要原因是输入解析的判断分支越来越多,从最基础的输入、连线解析,到作业集6需要额外判断子电路开始、子电路结束、语法错误、信号冲突等多种情况,导致方法内部if-else判断非常多。同时我也能发现自己代码的通病:很多重复逻辑没有及时抽取工具方法,导致代码冗余度偏高,部分方法写得过长,不够精简。

2.2 分作业类结构设计分析

2.2.1 作业集4 基础单层电路设计

屏幕截图 2026-06-21 180829

作业集4的整体结构比较简单,我设计了一个抽象父类Component,统一存放所有逻辑门共有的属性,包括器件名称、输出值、输入引脚映射集合等,同时定义通用的赋值方法和抽象方法compute()、getType()等。所有具体的逻辑门,比如与门、或门、非门、异或门、同或门,全部继承自这个抽象类,并重写各自的计算逻辑。

电路仿真的核心逻辑全部放在CircuitSimulator类中,专门负责读取输入、解析连线关系、循环更新信号、迭代仿真、最后排序输出结果。这种设计的好处是结构清晰,实体类和仿真调度类分工明确,非常适合刚学习面向对象的练习。

但缺点也很明显,父类中固定写死了输入引脚数量相关的抽象方法,只能适配普通的二值输出逻辑门,扩展性比较差,后面作业5新增多输出器件时,原有父类结构就显得不够灵活。

2.2.2 作业集5 多功能器件拓展设计

屏幕截图 2026-06-21 180851

作业集5完全沿用了作业4的父类结构,在此基础上新增了三态门、译码器、多路选择器、多路分配器。和普通逻辑门不同,译码器、分路器不再是单一输出,有的需要保存多个输出值,有的需要根据控制引脚选择输出通路。我通过子类重写compute方法,实现不同器件的专属计算逻辑,这也是多态最直观的应用。

本次作业我最大的设计问题出在结果打印部分。因为不同器件的输出格式不一样,我在print方法中使用了大量instanceof判断器件类型,导致整个打印方法非常臃肿,代码行数极多、圈复杂度很高。一旦后续新增器件,就必须修改这个方法,代码维护起来很麻烦,也不符合课程所讲的开闭原则,是我这次设计中最明显的短板。

2.2.3 作业集6 分层嵌套架构设计

屏幕截图 2026-06-21 180913

作业集6的改动最大,我对整体结构做了一次重构,将原来的Component类精简为Gate抽象类,去掉了冗余方法,让父类更加通用。本次作业最大的亮点是实现了子电路分层结构,程序需要同时管理主电路和多个子电路,每个子电路拥有独立的输入、输出、连线和器件集合,仿真时单独迭代收敛,最后再同步到主电路。

同时我改用正则表达式解析器件名称,替代了之前依靠下标截取字符串的方式,解析稳定性提升很多。为了减少重复代码,我把器件创建、引脚判断、编号提取、类型排序等通用逻辑都改成了静态工具方法。

不足之处是我把大量解析、校验、仿真调度的代码全部写在了Main方法里,导致主方法代码量巨大,结构很乱,可读性和可维护性都比较差,是典型的为了实现功能而忽略了代码结构。

2.3 核心流程分析

三次作业的仿真核心思路一致,都是迭代收敛算法。简单来说就是不断根据连线关系更新器件引脚输入,再调用每个器件的compute方法更新输出值,每一轮迭代都会对比信号是否发生变化,直到电路状态不再改变或者达到最大迭代次数,证明电路已经趋于稳定。

作业4、5只有单层电路,全局共用一套信号映射表,迭代逻辑简单、收敛速度快。作业6因为有子电路嵌套,需要先让每一个子电路单独迭代稳定,再把结果同步到主电路,最后再完成主电路迭代。双层迭代虽然实现了嵌套仿真功能,但也让整体流程变得复杂,很容易出现信号不同步、状态错乱的问题,需要仔细控制迭代次数和信号拷贝逻辑。

三、采坑心得

在三次作业的编码、公测、互测过程中,我遇到了很多真实的Bug和性能问题。大部分问题都不是思路错误,而是自己基础不扎实、API使用不规范、考虑边界不全、代码设计不合理导致的。下面结合具体代码问题、测试现象和数据详细复盘。

3.1 Integer包装类判值错误导致迭代无法收敛

这是我在作业4、5中踩的最大的坑。最开始更新引脚信号时,我直接用 != 判断新旧Integer值是否相等。在普通0、1信号的测试用例中,大部分情况可以正常运行,但在环路电路测试时,程序会一直迭代、无法稳定。

经过排查我才发现,Java的Integer包装类存在缓存机制,部分数值相同但对象地址不同,使用 != 判断会误认为数值发生了改变,持续触发迭代更新。我实测了15组环路测试用例,有8组出现无限迭代、无法稳态的问题,直接导致公测性能分没有拿满。

最后我将判断方式改为Objects.equals(),同时增加空值判断,才彻底解决这个问题。这次踩坑让我意识到,看似简单的数值判断,背后也有底层原理需要注意,不能凭直觉写代码。

3.2 字符串硬编码解析容错性差,极易报错崩溃

作业4和作业5我全部使用indexOf和substring截取字符串,解析器件名称和参数。这种写法非常依赖严格的输入格式,一旦输入有括号缺失、数字异常、多余空格等问题,程序直接抛出索引越界异常并终止。我后期测试了20组非法输入用例,有17组都会直接崩溃,程序完全没有容错能力。

对比作业6使用正则表达式分组匹配,能够稳定匹配合法格式,同时可以统一捕获异常、做空值兜底,程序健壮性提升非常明显。这让我明白,处理结构化文本输入时,正则是更规范、更稳定的方式,硬编码截取只适合极其简单的场景。

3.3 未设置迭代上限导致环路电路死循环

最开始写作业4时,我只考虑了正常电路会迭代收敛,没有考虑自反馈环路电路无法稳定的情况。当时代码没有最大迭代次数限制,遇到环路电路就会进入死循环,评测平台直接超时判错。实测5组环路测试用例全部卡死,严重影响公测成绩。

后来我添加了MAX_ITERATIONS常量,设置最大迭代次数,达到上限就强制终止循环,解决了卡死问题。这次问题让我明白写程序不能只考虑正常用例,极端边界情况必须提前预判,做好防护机制。

3.4 输出格式逻辑全部堆积,互测出现多处格式Bug

作业5中不同器件输出格式差异很大,普通门电路输出简单,译码器、分路器需要输出一串结果,多路选择器需要指定引脚编号。我当时为了省事,直接在打印方法中用大量if和instanceof判断器件类型,区分输出格式。

这种写法导致打印方法极度臃肿,圈复杂度很高,非常容易出现分支遗漏。在互测阶段,我的程序被测出4个正确性Bug,基本都是特殊器件输出格式错乱、内容缺失。

复盘后我意识到,器件自身的输出格式应该属于器件自己的属性,应该在子类中重写对应方法,而不是全部交给仿真器统一判断,这是典型的职责不清晰、单一职责原则没有落实到位。

3.5 正则API使用混淆,语法校验完全失效

作业6需要检测非法字符和多余空白,我最开始使用matches()方法进行匹配,但是测试发现所有非法用例都能正常通过,校验功能完全失效。

查阅资料和调试后我才分清两个方法的区别:matches()是匹配整个字符串,适合严格完整匹配;find()是扫描字符串任意位置,适合查找是否包含非法字符。我误用API导致前期所有语法校验形同虚设,很多错误输入无法拦截,公测丢失大量分数。

3.6 子电路信号未隔离,出现信号污染与冲突问题

作业6初期我没有给子电路单独的信号空间,所有电路共用全局信号表。当主电路输入和子电路输入重名时,信号会互相覆盖,导致仿真结果完全错误。同时我没有做信号冲突检测,当一个引脚被两个信号同时驱动时,程序无法识别错误,也不会输出规定的ERROR提示。

实测8组重名、多驱动冲突用例,全部出现结果异常。后续我为每个子电路单独创建信号集合,做到内外隔离,同时用Map记录每个引脚的信号来源,重复驱动直接报错,才解决该问题。

3.7 代码重复度高,维护效率低

三次作业我都存在同一个问题:很多相同的逻辑,比如引脚分割、信号取值、器件编号提取,在多个方法中重复编写,没有统一抽取工具类。导致我每次修改逻辑,都要改好几处代码,很容易出现改一处、漏一处的情况,隐性Bug非常多,代码复用率很低。

四、改进建议

结合三次作业暴露的问题,我从自己的实际编码水平出发,提出一些切实可行、能够长期优化、持续改进的方案,方便后续迭代和复习。

4.1 优化代码结构,拆分臃肿方法

后续编码我会主动规避“超大方法”,一旦发现方法行数过多、判断分支太杂,就拆分为多个小方法。尤其是作业6堆积在Main中的大量逻辑,我会重新抽离出独立的仿真工具类、解析类,让每个类、每个方法只负责一件事,让代码结构更清晰。

同时统一优化器件输出逻辑,在抽象父类定义输出方法,所有子类自己实现输出格式,彻底删除大量instanceof判断,让代码拓展性更强,新增器件不用修改原有核心代码。

4.2 封装通用工具方法,减少代码冗余

针对重复出现的字符串处理、数值判断、引脚解析、排序逻辑,我会统一封装成工具类,后续所有作业统一调用工具方法,不再重复编写。这样不仅可以精简代码,还能保证全局逻辑一致,避免多处修改导致的Bug。同时统一使用Objects.equals完成所有数值对比,彻底杜绝包装类判值问题。

4.3 完善异常处理与容错机制

之前的代码异常处理非常薄弱,很多解析、转换操作没有防护,遇到非法输入直接崩溃。后续我会对所有可能报错的代码增加异常捕获,针对非法格式、参数缺失、信号冲突等情况,输出规范的错误提示,保证程序不会轻易崩溃,提升代码鲁棒性。

4.4 优化仿真算法,提升运行效率

目前我的仿真逻辑是每次迭代全部器件全量计算,存在大量无效运算。后续可以改为惰性更新,只有输入信号发生变化的器件才重新计算输出,减少冗余运算。同时将所有正则表达式改为静态常量,避免反复创建匹配器,提升程序运行效率。

4.5 完善自测流程,搭建基础测试体系

之前我大多依靠评测平台和互测找Bug,自己自测不够全面。后续我会自己整理测试用例,包括常规用例、边界用例、错误格式用例、环路嵌套用例,批量自测,提前发现隐性问题,减少公测、互测的出错概率。

五、综合总结

5.1 学习收获

经过三次数字电路仿真作业的训练,我对Java面向对象编程的理解不再停留在课本理论,而是真正落地到实际项目开发中。我熟练掌握了抽象类、继承、多态的使用场景,能够根据需求设计基础的类结构,区分父类通用逻辑和子类个性化逻辑。同时我理解了迭代仿真的基本原理,知道数字电路如何通过程序模拟信号传播、状态更新、稳态收敛,对计算机仿真硬件电路的思想有了初步认知。

在编码能力上,我从最开始只会简单实现功能,慢慢学会考虑代码复杂度、稳定性、容错性和可维护性。通过大量Bug排查,我补齐了很多Java基础短板,包括包装类特性、正则API区别、集合使用细节、循环迭代边界问题等。同时学会使用SourceMonitor、PowerDesigner等工具分析代码质量和类结构,不再盲目写代码,能够简单量化自己的代码优缺点。

5.2 自身不足与后续学习方向

目前我的代码依然存在很多不足。首先是代码设计思维不足,只会基础的继承多态,不会灵活使用设计模式,代码结构很多时候是为了实现功能而拼凑,不够规范。其次是算法能力薄弱,仿真逻辑还是简单暴力遍历,没有使用更高效的拓扑排序思路优化执行顺序。再者是工程思维欠缺,异常处理、日志输出、模块化拆分都不够专业,代码只适合作业练习,不适合大型项目迭代。

后续我打算重点补强这几个方面:一是多看基础设计模式,尝试将工厂模式、模板模式应用到自己的代码中,优化器件创建和仿真流程;二是学习简单图论算法,优化电路仿真效率;三是刻意练习代码拆分,杜绝超大方法和臃肿类;四是加强自测能力,养成编码前后思考边界条件的习惯,减少低级Bug。5.3 整体感悟

这三次作业让我真切体会到,软件开发不仅仅是“代码跑通就行”。最开始写作业4时,代码简单、结构粗糙也能拿满分,但随着作业难度提升,前期结构设计的缺陷会被无限放大,导致后续代码臃肿、Bug频发、难以维护。这让我明白,写代码需要有长远思维,在实现功能的同时,要兼顾结构清晰、逻辑严谨、便于修改和拓展。

作为大一学生,我的工程能力和代码功底还比较薄弱,很多问题都是踩坑之后才明白原理。但每一次Bug排查、每一次代码重构、每一次复盘总结,都让我对Java编程和软件工程思想有了更深的理解。后续我会继续保持多写、多测、多复盘的习惯,慢慢改掉自己编码随意、考虑不全的问题,逐步提升自己的代码质量和工程实践能力。

相关新闻

  • 厦门抖音公会营业性演出许可证整套全包代办推荐 - 速递信息
  • 2026宁波抖音公会营业性演出许可证整套全包代办推荐 - 速递信息
  • 影刀RPA数据采集进阶:分页翻页、懒加载、反爬虫应对全解析

最新新闻

  • WinCE 6.0 GPS开发实战:从GPSID配置到经纬度数据解析
  • 2026年蚌埠市初三中考成绩不理想适合上什么学校? - 教育为先
  • 从12位到16位:嵌入式SAR ADC精度跃迁与校准实战
  • Ubuntu 20.04下用apt安装Java:稳定、安全、可维护的JDK部署方案
  • HunyuanVideo + DigitalOcean GPU:轻量级文生视频部署实战
  • “扩展域并查集”简介

日新闻

  • Visual C++运行库修复终极指南:5分钟快速解决Windows软件启动错误
  • 手把手教你构建统计局地区经济数据爬虫:从环境搭建到数据持久化全指南
  • 2026多Agent深度解析:用AI团队替代单一模型,四种架构实战落地

周新闻

  • Visual C++运行库修复终极指南:5分钟快速解决Windows软件启动错误
  • 手把手教你构建统计局地区经济数据爬虫:从环境搭建到数据持久化全指南
  • 2026多Agent深度解析:用AI团队替代单一模型,四种架构实战落地

月新闻

  • 【总结】入门篇:50句话让你记住架构核心概念
  • WeChatMsg技术方案解析:实现Mac微信数据自主管理的完整解决方案
  • WeChatMsg:革新性微信数据备份方案,打造你的专属数字记忆库

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号