已经不是第一次敲 Java 了, 真的应该感谢学院在大一暑期的时候开设了面向对象先导课程, 让我好歹磕磕绊绊地过了编手, 不至于在 OO 课来临直接过于难受其实我跟 JAVA 有着很大的缘分, 记得大一的时候, 学院给我们开设了第二课堂, 大部分同学为了给下学期的数据结构打好基础选择了 C 语言, 偏偏我头铁, 以为要把眼光放得长远选择了 Java 结果可想而知, 一点点编程基础没有的我在满是大佬的课堂疯狂划水, 讲的东西一个字都听不懂, 整个学期唯一的收获大概就是电脑上安装了 Eclipse 暑期课程抢救了我, 在安装了 Eclipse 的基础上敲了点代码, 入了门, 顺承地来到了 OO 的课堂
一以码为鉴, 可知己菜
太菜了, 是真的菜, 这大概是我最近这次互测拿到对方代码之后不由得发出的感慨, 别人是面向对象编程, 而我是真的面向对象编程, 或者说: 面向对象写面向过程编程
1 第一次作业重拾 Java
虽然之前有过编写 Java 程序的经验, 但那个时候也只是简单地学习了语法入了门, 没有理解 Java 编程的精髓, 写出来的程序有着浓厚的 C 语言味道, 再加上半年来没有加强训练, 第一次作业依然是在做回顾语法的过程整个工程文件只有 Main 和 Poly 两个类, 所有的方法都在 Poly 里面, 土豪式地实例化了 20 个 Poly 对象, 每个都开了 1000000 大小的数组(指数从 0 到 999999, 以下标为指数, 以内容为系数), 这种做法极大地简化了逻辑, 不用排序, 也不用担心数组会爆, 反正大于 999999 的指数就是 ERROR, 很暴力地做输入正则表达式分解多项式相加输出然后再自以为安全地写了通篇的 try-catch, 搞定
结果测试结果一出, 就傻眼了因为粗心, 没有看到作业指导书里面最多只允许 6 个字符长度的数字, 误以为最多支持 6 个前导 0 就行, 导致公测挂了一个点互测的时候又被挂了一个 crash, 没错, 通篇 try-catch 了也会 crash? 也希望各位同学引以为鉴, 不要以为 try-catch 就安全了因为我在正则表达式部分写了通配符 \*, 导致对于无限长的合法输入 (100 个多项式) 也纳入到了考虑范围中, 导致运行时爆了 Java 的运存, 连 catch 都崩了更不会 catch 到 exception 了第一次作业我从中吸取了很多教训, 这之后我除了 catch(Exception e), 还 catch(Error e), 彻底杜绝了 crash
很凑巧又不凑巧的是, 第一次作业我分配到了室友的代码, 室友之间肯定就这一次的作业有过交流, 我们两个的思路也是一样的, 虽然我还是尽可能地分析了代码, 但找不到任何 bug
2 第二次作业初试面向对象
从第二次作业开始, 无论是老师还是同学都在刻意地学习面向对象式的写法从这一次作业指导书可以看出来, 强行要求实现五个类就是要学生去体会对象这个概念, 制止过程式写法这一次的作业难点在于电梯时间和请求时间不同步, 有一部分同学选择模拟时间的方式将两个时间调同步这一种方法可以简化逻辑, 并且可以适用于接下来的任意一个电梯作业, 但模拟时间循环会导致程序运行完毕可能需要较长时间我采用了另一种方法让二者时间同步: 在电梯每开始执行一条指令到执行完毕的这一段时间, 记录所有请求的到来情况, 若某个按钮没有被点亮, 则接受请求, 即点亮按钮, 否则标记为同质请求老师说过, 面向对象实际上就是在搭积木, 我给每个楼层都设置了按钮, 电梯里也设置了按钮, 整部电梯系统就是由楼层, 电梯, 调度器搭起来的, 再搭配上请求类和请求队列类写完之后颇有一丝面向对象的意味, 就好像自己在 minecraft 里搭房子一样但是调度器类我觉得自己依然使用的面向过程的思路, 不同于楼层电梯请求, 我不能很好的把调度这一概念很好地抽象出来, 也没有太关注这一点抽到的代码也是洋洋洒洒一百行的调度类, 跟我有着一样的毛病
在测试自己的代码的时候, 我和小伙伴们一起对老师给出的错误分支树每一个分支都写了样例, 尽可能降低 bug 出现概率这次业我吸取了上一次的教训, 认真阅读了作业指导书, 并对照着自己的代码一遍又一遍检查, 所幸使得自己公测和互层都没有被扣分但是我分配到的代码也是一个大佬的, 用网站测试了我们构造的所有测试样例之后也没有发现他任何 bug, 证明了他代码逻辑的正确性进而进行鲁棒性测试, 测试极端输入和各种错误输入, 也没有发现问题, 正则表达式的匹配部分也运行良好, 不会因为奇特的情况 crash, 让我心灰意冷灰心之际突然发现他的编码格式是 GBK, 勉强报告了一个 incomplete
3 第三次作业继承 & 接口
这一次的作业可以说是很有难度了, 新的要求使时间不同步的基础上增加了新的困难: 捎带会影响同质性因为要用继承, 所以并不想破坏第二次的大体思路, 这意味着不能在扫描队列时先判断同质再判断捎带, 而要每条指令都去判断是否同质, 是否可以捎带捎带不但可以捎带新来的请求, 也可以捎带之前的请求, 这就使扫描不能从电梯开始运动时刻开始, 要从未执行的第一条指令开始除此以外小问题众多: 主指令变更同层输出顺序等等在敲代码之前我进行了很长时间的构思, 这也是我在学习数据结构开始总结到的经验: 先想好再动手, 不然 debug 的时候可能会哭整体架构设计完后也想了很多特殊情况: 主指令和捎带指令同层结束但捎带指令先执行这种事无巨细的构思给我后期的码代码带来了无限的便利
但是过分关注逻辑性, 又让我忽视了对象这个概念一个调度器类写了 300 行, 别的各个类最多也就 50 行, 让整个结构显得很不均匀, 调度器承担了太多的任务因为测试期间没有看到优秀的面向对象代码, 自己也不知道怎样的写法才是最好的, 直到这一次的互测分配虽然这个代码被我找到了同层输出顺序的 bug, 但他代码的抽象能力是真的很厉害, 第二次作业就很好地完成了调度器的抽象, 甚至把输入输出都抽象了出来, 既提高了代码的可读性, 让代码更整洁, 也减小了第三次作业的任务量, 不足数十行代码, 重构一小部分, 很漂亮地完成了任务学习了他的写法之后我决定小范围重构自己的代码
不过值得开心的一件事情就是本次作业依旧完美通过了公测和互测, 这一点十分得益于对错误分支树的遍历我认为是可以总结为经验的形式继续下去的
二感想
经过了几次 OO 作业, 我觉得 OO 课程最恐怖的地方是他的作业周期最好的方式是从周日开始构思, 周一敲代码, 周二完成, 周三稍作修改收工但凡犯了一点点拖延症, 敲代码的时候就会很被动, ddl 压头难免会恐慌, 就会造成琢磨不透彻, 思路不清晰, bug 繁多的现象给别人送去一份大礼包最近愈发感觉 Java 比 C 友好, 记得第一次作业的时候还要求写了一个 C 代码, 在享受过 Java 的 Arraylist 的便捷和 Eclipse 的自动补全之后, 开始写 C 语言竟然还有那么一丝茫然以前听大神说 C 是高级语言里的最低级语言, 看来是没错了
前文说过写面向对象的代码就像在 minecraft 里面搭房子, 这确实是我真正尝试用面向对象的思想写 Java 的感觉这不过现在房子搭地还不够好, 还要经过学习去研究怎么搭地基, 怎么搭房顶特别是接口的用处还没有学懂, 上节课老师也说过接口在这次作业看似用处不大, 不过在多线程作业时就会大放光彩, 但愿自己可以伴随着学习一点一点吃透 Java 的编程思想最近在基友群里看到了一个图片, 很生动地解释了面向对象思想中各个专有名词的概念
这幅图片蛮搞笑的, 不过确实能通俗地解释基本概念, 算得上是忙碌的学习生活中一点点乐子吧也希望自己的 OO 课程可以在忙碌得过程中伴随着乐子, 充实愉快得度过这个学期
来源: http://www.bubuko.com/infodetail-2546984.html