HIT软件构造实验总结

## 在这门课刚开始的时候,老师就强调要养成写博客的好习惯,把自己的收获分享给大家。好吧,我可能并没有养成这个好习惯。这里还是要反省自己的懒惰的,所以这几天复习过后来总结一下自己对这门课的实验的收获

首先来看实验的部分

实验1
第一个实验主要考察我们对于Java语言的悉程度,现在的我看来,这个实验的确没什么难度。不过刚开始上手的时候,由于不熟悉Java还是遇到了一些困难。

  1. 阅读英文spec的困难
    之前我们的实验都是中文的实验手册,然而软件构造的第一个实验给我们英文的实验手册,实在是让人有点难受。其实这个实验的内容就是让我们按照他的规定补全一些函数,函数的功能,参数,返回值的描述都用注释的形式给出了,当然都是英文的,这刚刚开始的确会有点困难,后面才发现,我们之后的实验天天都得和这些注释打交道。
  2. junit
    这个实验我第一次接触到junit测试,第一次导入junit包的时候,我把junit5导进去了,然后实验的代码出现了一堆error。还是那个时候太年轻,连junit的版本都不会看QAQ。

总的来说,这个实验带给我的都是因为第一个实验不熟悉各种环境导致的困难。其实现在回头看看,这个实验每个问题都有在暗示后面的实验。这个实验难度还是不高的,只不过对于刚上手的人来说并不友好

实验2
从这个实验开始,我们就开始逐渐从0开始设计ADT了。这个实验主要有以下三个部分

  1. Poetic Walks
    这个部分有个非常浪漫的中文名–诗意行走。这个名字并不重要,其实这就是个和图有关的实验。这个部分第一次接触到泛型编程。这个实验给了我们一个大致的代码框架,也就是一个泛型接口,我们需要对于这个接口完成两个具体实验。按照数据结构的思想来说的话,这两个具体实现就是邻接表以及邻接矩阵。最后利用我们写好的这两个具体的实现,完成诗意行走,其实就是图的搜索。。。
  2. 实验1中的Social Network重新设计
    在实验1里,我们写了一个关于社交关系的图。在实验1的时候,我是完全按照数据结构里图 实现去写的这样一个社交网络,然后实验2就要求我们利用我们以及写好的代码去完善实验1的这个部分。这个部分给我一个很大的感触就是感受到了代码复用的好处,如果在一开始写一段代码就考虑到复用,就是build for reuse。这个想法其实给我在写实验3的时候带来了很大的方便。
  3. Play Chess
    下棋下棋下棋。这是第一个让我有点崩溃的部分,为什么这么说呢。前面的一些问题,很多都是环境配置的问题,这个问题就是代码的问题了。其实前面实验1写的社交网络算是从头开始设计了,但是那个问题太简单了。这个下棋的问题其实相比起来是比较复杂了。

总的来说这个实验难度中等吧,这个实验里也是第一次要求我们写注释,AF,RI之类的,算是实验1的一个升级版吧。

实验3+4+5
对于我们大多数人来说,实验3一定是噩梦的开始,设计ADT,泛型编程,设计模式,GUI,代码量巨大(悄咪咪:可能是太困难了吧,困难到有些人坚持不了底线,做一些不好的事,大家一定要保护好自己的代码哦)

还是先来说说实验内容吧。其实这个实验就是需要设计轨道系统。按照实验2 的思路,需要按照泛型编程的思想,也就是说我们的轨道系统是可以复用的,可以作为api提供给他人。然后我们需要利用我们写好的代码,完成3个具体的应用场景,有田径比赛,行星系统,原子轨道,社交网络,APP网络。我当时选择的事行星,原子以及社交网络。

其实说到底,这个实验最难的还是ADT设计,因为有些类需要我们设计成immutable的,而有些类就需要mutable。如何去调整各个类之间的关系是十分重要的。我当时下手之前,构思了很长时间,在草稿纸上画了很多遍类图。但是,无论有多少思路,等到真正下手的时候才能知道怎样写合适。

不要以为这就完事了,当我设计好ADT之后,才发现GUI以及可视化也是令人恼火的问题。这里推荐一个插件windowsbuilder,这个插件可以让你的eclipse像VS一样可视化地编辑窗口。其次是可视化,可视化的问题最难解决的部分在于动态显示,例如行星系统就需要让行星动起来。这里我先分析一下利用repaint()进行动态显示的一些问题。我们可以习惯写一个JFrame然后在这上面使用Paint()进行绘图操作,然后利用repaint()完成更新。可是我当时这么写的时候发现会有闪烁问题。使用发现了下面的问题。
HIT软件构造实验总结_第1张图片
repaint()方法在重量级组件的时候会调用update方法,在轻量级组件的时候会调用paint方法
恰恰JFrame是轻量级组件,所以Frame不运行update方法
后面我利用JPanel就不会闪烁。那么他俩有啥区别呢。
JFrame的paint方法是继承Container类中的,而JPanel的paint方法是继承JComponent类中的,看看他俩之间方法的差异:
HIT软件构造实验总结_第2张图片
JPanelpaint是按顺序画的,而JFrame是通过类似剪切的操作实现的,所以这就是闪烁的原因吧。大家都愿意自己看到的动画和PPT一样吧,所以闪烁问题当时还是花了我一段时间的。

其实可能这个实验给我的困难并不是完全来自ADT设计,其实ADT设计老师讲的十分详细,设计起来并不是太困难,只不过大多数人不知道该如何下手,其实更多是不敢下手,我觉得很多问题是你下手写了才知道的,在我设计ADT的过程中,并不是线性的,而是迭代的,其实ADT的设计可能到我写完所有代码的完成,因为在我写代码的时候经常需要去修改前面的设计,我觉得这样一个过程才是正确的,毕竟只有发现问题才能解决问题,才能有进步,想要一步成功是不可能的。然后就是在写代码的过程中积累很多不常见的问题。说实话,这个实验的确给人的收获很多很多。
******************************************************分割线 ***********************************************
实验3大概折磨了大家快一个月的时间,后面的实验4,实验5其实都是建立在实验3的基础上的。也比较简单。
实验4:最让我不满的实验
还是把实验4单独挑出来说一下把,本来实验4和实验5都比较简单,但是因为实验4的确是让我最不满的一个实验,这里我还是想像个愤青一样抒发一下。

实验4的内容是让我们优化自己的实验3的代码,优化的部分包括,IO性能以及一些关键算法的性能,并且最后给了我们一些十分大的实验数据去测试。

在实际的实验过程中,我们发现,其实IO读取一个大文件花费并不高,如果选用合适的IO策略,几ms就可能完成对文件的读取,然后整个构建的过程可能需要几十分钟,是不是很恐怖。所以大多的时间花费来自于构建。

举个例子,在行星轨道系统中,当我们读入一颗行星的数据后,我们需要判断这颗行星是不是存在或者这颗行星所需要的轨道是不是已经被占用。所以大量的时间就花费在查找上面。这里先分享几个技巧:

  1. 关于动态表
    Java中动态表其实是有初始大小的,当初始大小被占满后,会重新开辟一块新的空间,大小是原来的两倍,然后将之前的数据复制过来,所以频繁的增大,复制是一个很耗时的工作。所以这里可以先设置一个较大的空间。这样会有一点小小的帮助。
  2. 关于大量数据的查找
    当数据很庞大的时候,用遍历的方法去查询是一件很不现实的事情。所以我们想到了hashcode,哈希表在查询方面的性能是十分优秀的,所以我很自然的用了hashset去修改我们代码,的确很好用,但是又发现了新的需求,这样我只能很快知道数据是不是存在,但是如果我想取出那个数据呢。好像hashset并没有按照哈希值获取数据的功能啊。于是,两分钟之后,hashset的源码给我了灵感,原来hashset的内部实现是hashmap,真的是佩服写Java库的那些工程师,还有这种操作,所以我就直接用hashmap代替了hashset的功能。

那么为什么我说对这个实验不满呢,其实就算用了这些方法去提升了代码的性能,其实还是有一个问题的,那就是正确性的问题,我觉得不能默认用户输入是合法的,上课老师说,要把用户当傻瓜,虽然这里老师给的,以及经过大佬加持的实验数据没什么问题,但是,用户依旧是傻瓜,不能为了性能放弃合理化检验。但是其实合理化检验是很耗时的过程,尤其是社交网络的合理化检验,所以我当时问一些同学是怎么做到那么快的,发现其实很多人都抛弃了这个部分,这样追求速度是没有意义的,可能这个实验的设置是问题的吧,我不愿意放弃我对于正确性的追求,可能是我能力不够,没法追求那么快的速度吧。
******************************************************分割线 ***********************************************
实验5很简单了,只是一些工具的使用,很舒服的一个实验哦

实验6:猴子过河
哈尔滨工业大河发生的一个真实的关于过河的故事。
这个实验其实我是很喜欢的,很有意思。本次实验的主题是多线程编程,多线程机制能充分利用多核处理器的处理能力,提升软件性能。经过前几次实验的洗礼,在写这个实验的实验明显发现有了点游刃有余的感觉。这个实验的关键在于:锁。
如何用锁的技术?为了让我们的线程安全,我们就必须需要用到锁的方法,因为不可能限制数据共享,而且数据当然是mutable的。所以锁的位置很关键,锁的范围太大,性能就会下降,范围太小,就会出现bug,而且多线程的bug是很难处理的。所以锁的控制最好就放在对共享数据有修改的地方。

到此为止,6个实验就回顾完了,其实收获还是很大的。感觉自己的代码能力有了很大的提高。而且课上的内容还是很有用的。对于我个人而言,我觉得设计一些可复用的代码是很有意义的,而且利用复用的手段去写代码也是很有意义的,老师说要进入编程的黑洞,才能提高自己的水平。这些实验虽然有让我不爽的地方,但是能有收获我就不计较了(emmmmmm)。写博客还是很好的,希望可以坚持下去吧。

你可能感兴趣的:(HIT软件构造实验总结)