实训总结

实训总结


总述

为期一个月的实训算是告一段落了,在这一个月的时间里,我们可以说完成了许多之前没有接触过的任务,也学到了许多未曾学习过的知识。这次实训主要分为三个阶段,总的来说是呈现一种层次递增状态。具体可以见下图
这里写图片描述
接下来想要具体述说一下每个阶段的收获和感想。

阶段一

阶段一主要算是对项目的一个初步了解和一些准备学习工作。首先我们要学会使用Vi, JAVA, Ant 和 Junit, 这些再阶段一学习报告中也有叙说过。然后我们需要自己配置好环境。不得不承认,一直以来,我对于配置环境变量都有一些恐惧心理,尤其是在windows上的各种配置总是会遇到各式各样的问题。这次在云平台上已经把大部分环境配置好了,对于我这种人来说可谓是一大福音,不过学会配置这些东西还是挺重要的。具体的配置过程和java、vim的学习报告可以参考之前写的第一阶段自学报告,这里就不再详细介绍

接下来是要学习sonarqube,简单介绍一下吧。
Sonar是一个用于代码质量管理的开源,用于管理源代码的质量,可以从七个维度检测代码质量
通过插件形式,可以支持包括java,C#,C/C++,PL/SQL,Cobol,JavaScrip,Groovy等等二十几种编程语言的代码质量管理与检测

sonarQube能带来什么?

1、糟糕的复杂度分布
文件、类、方法等,如果复杂度过高将难以改变,这会使得开发人员难以理解它们,且如果没有自动化的单元测试,对于程序中的任何组件的改变都将可能导致需要全面的回归测试

2.重复

显然程序中包含大量复制粘贴的代码是质量低下的

sonar可以展示源码中重复严重的地方

3.缺乏单元测试

sonar可以很方便地统计并展示单元测试覆盖率

4.没有代码标准

sonar可以通过PMD,CheckStyle,Findbugs等等代码规则检测工具规范代码编写

5.没有足够的或者过多的注释

没有注释将使代码可读性变差,特别是当不可避免地出现人员变动时,程序的可读性将大幅下降

而过多的注释又会使得开发人员将精力过多地花费在阅读注释上,亦违背初衷

6.潜在的bug

sonar可以通过PMD,CheckStyle,Findbugs等等代码规则检测工具检测出潜在的bug

要使用sonar首先得配置好变量。幸运的是,sonarqube已经在云平台基本配置好了,我们只需要启动就可以了。要想用sonar检测代码要写好属性文件,再启动soanr-runner,之后就可以再localhost网页上看到检测结果了。说到sonarqube,感觉算是这次实训收获到的很重要的一个工具吧。以往在写代码的过程中,因为种种原因,并没有怎么注意代码风格的问题。代码的注释也寥寥无几。这次用到了sonar之后,才发现自己的代码居然有如此多的错误。像常见的错误中,比如if else等语句没有用大括号,用了默认的构造函数,变量命名不规范,重复的语句过多等等。这些都是平时写代码时不曾注意的问题,在实际应用中可能会出现很很多问题。这种情况下,sonar带给我们的帮助就很大了,帮助我们在实际运用中不会使代码变得很难维护。
下面是sonar检测后的主界面。
这里写图片描述
至于编译运行BugRunner就相对比较简单了。我们也可以从编译运行后的界面中看出些端倪,明白我们要做的程序到底是怎么样的。

阶段二

阶段二的任务相比阶段一可以说是一个质的飞跃,工作量也是成倍增长。可以对阶段二做一个总的概述,就是在回答问答题的基础上理解gridworld中类的具体含义,再通过各种例子来写出自己的各种继承的类,从而学会许多方法。值得一提的是,这一阶段我们可以去学习eclipse的使用方法,这可以使我们的代码编译等工作变得方便许多。虽然我可能更中意idea一些,不过由于云平台上提供的是eclipse,所以还是采用了eclipse作为主要的IDE。在这里想发一点苦水:因为对eclipse的使用不太熟悉,在导入文件等操作时遇到了许多问题,经常会遇到一些诸如找不到类库的问题。不得不承认eclipse的反人类之处。不过往好的方面想想,这也算是一种训练吧,让自己更理解基层的原理了。

part2

这个part的任务主要是写几个继承Bug的类,来做到许多不同的动作,比如说循环移动,移动成一个字母,随机移动。要改写这些动作,重点在于改写act函数里的行为,通过条件判断和函数的调用来完成不同的要求。总的来说不是特别复杂,只要能理解每个任务的要求的话还会不难完成的。
这个举几个例子
这是circlebug的效果
这里写图片描述

Zbug
这里写图片描述

其余的类也比较好了解,只要能弄清底层原理就ok了。

part3

par3训练了我们自行测试所写代码的能力。主要要求是写一个Jumper类,使actor可以跳两格,并且一定情况下可以跳过岩石。说实话写出一个Jumper类并不算难,但是要想设计出一个好的测试方案还是需要动动脑子的。具体的方案可以查看涉及文档测试报告

part4

这个part4需要我们扩展Critter 类,其实道理和bug也类似。当Critter 遇到其他物件时可能会改变颜色,或是改变方向,或是直接吃掉其他物件。这里随机选一个例子。

kingcrabcritter(吃掉周围一切除了岩石的物件)
这里写图片描述

ChameleonKid(根据周围物件颜色改变颜色)
这里写图片描述

QuickCrabCritter(随机选择两个方向中一个 )
这里写图片描述

part5

这部分要我们想办法改变gird的存储结构。我们可以采用链表或哈希表或树结构的方式改变。另外,我们要自己建一个UnboundedGrid。判断是否合法时要判断长宽是否大于零。扩展地图时新建一个数组,将原来的数组拷贝过去,剩余的那部分都是空的。
这里写图片描述

阶段三

到了阶段三就基本变成一些扩展性的任务了。总的来说都比较新颖,需要花费一定的时间去理解。

ImageProcessing

本实验要求同学们利用本实验软装置,实现一个利用二进制流读取Bitmap图像,并且能够进行简单地处理和保存的软件。具体为以下功能:

  1. 利用二进制流读取Bitmap位图文件。
  2. 把读取彩色图像转换成灰度图像;
  3. 提取并且显示彩色图像各个色彩通道;
  4. 把处理完的图像保存为bmp格式图像。
  5. 编写Junit测试程序,测试输出的图片是否与goal文件夹下的图片一致。(比较位图宽度、位图高度以及像素值)

这个程序目的在于让我们了解图片保存的本质,以及让我们熟悉这些图片处理的api,主要需要用到扩展库ImageReader。写图片因为可以用到Bufferedimage所以相对较为简单,具体实现为:

//创建一个BufferedImage变量,用于写入图片。
BufferedImage bi = new BufferedImage(w, h, fileType);

//创建一个Graphics变量,用于画出需要保存的图片
        Graphics g = bi.getGraphics(); 
try { 
            g.drawImage(image, 0, 0, null);
            File iFile= new File(file + ".bmp");
//将BufferedImage写入文件中。 
            ImageIO.write(bi, "bmp", iFile);

而读取图片就比较复杂,在这过程我也遇到了许多困难。比如对位操作不熟悉导致获取的值不正确,未能跳过空白字符使得读出图像变斜等等。经过探讨后也算了解了这些操作的方法,在以后也能学以致用。

接下来看下具体实现的效果图吧。首先是读取图片。
这里写图片描述

然后将图片转换成其他颜色,这里是转换成了红色。
这里写图片描述
之后要测试我们的程序。我的思路是用getWidth、getHeight、getRGB分别测试比较位图宽度、位图高度以及像素值。测试结果也符合预期。

这里写图片描述

MazeBug

无环路迷宫在数据结构上表现为一棵树,采用深度优先搜索算法就可以走出迷宫。本实验的目的是让同学们学习、理解和应用深度优先搜索算法。本实验要求同学们在改进的GridWorld软件装置中实现深度优先搜索算法,从而使虫子走出迷宫。本实阿验需要用到软装置MazeBug。
深度优先算法算是一个比较经典的算法了。之前在数据结构课中也都已经解除学习过了。这次要做的MazeBug算是深度优先算法的一个应用了。我们这个要写的MazeBug也是要继承Bug这个基础类的。
基本操作和Bug没什么差别,这里就不再详述了。重点在于如何应用深度优先算法。我的思路是每次虫子在遇到分支时,都会给栈压入一个新值,相当于把每个分支的路线作为一个栈值。当遇到不能走的死路时,就会用回溯返回,并且pop出原来的路线,这样在下次选择时就不会选择这条死路了。如果要增加方向概率估计的话,需要在选择时增加一个判断函数。分别记录之前上下左右选择的次数,判断时选择之前选择最多的方向。而当遇到不能走的路回溯时则需要减去之前所走的方向。
这是具体所走的效果
这里写图片描述
当地图为unbounded时
这里写图片描述

N-Puzzle

以3*3拼图(8-数码问题)为例,在3*3的方格棋盘上,放置8个标有1、2、3、4、5、6、7、8数字的方块和1个空白格,空白格可以上下左右移动。要求通过反复移动空白格,寻找一条从某初始状态到目标状态的移动路径,如图1所示。

重排拼图游戏也叫N-数码问题(N-puzzle,N=M*M-1),高维数码问题(如15数码、24数码)常常被用来作为一些搜索算法的测试实例。本实验需要用到软装置Jiasaw。
这里写图片描述

这个实验需要用到广度优先搜索和启发式搜索。广度优先搜索就不用说了,大家都比较熟悉了,启发式搜索就比较新颖了。启发式搜索又称为有信息搜索,它是利用问题拥有的启发信息来引导搜索,达到减少搜索范围、降低问题复杂度的目的,这种利用启发信息的搜索过程称为启发式搜索。启发式策略可以通过指导搜索向最有希望的方向前进,降低了复杂性。通过删除某些状态及其延伸,启发式算法可以消除组合爆炸,并得到令人能接受的解(通常并不一定是最佳解)。我们所需写的启发式算法的部分是 评估函数。通过评估每一次移动的代价值,判断哪种方案会接近最优解。主要的评估值可以有(1)所有 放错位的数码 个数; (2) 所有 放错位的数码与其正确位置的距离 之和(曼哈顿距离); (3) 后续节点不正确的数码个数;(4)几何距离
这里我将曼哈顿距离的权重设为最多,放错位数码个数设置的较少。可以通过测试得出,仅仅时修改很细微的权重,最后跑出来的搜索节点值可能会有很大的差别。
通过测试样例可以得知自己的搜索结果
这里写图片描述

总结

  • 这次实训很多人一开始可能会觉得挺难上手的,不过大部分人在深入学习后可能也会发现里面的内容其实没有想象中的那么难,相信大家努力攻克难点之后都会有所收获的。
  • 问答题是这次实训的一个亮点,以往在写代码时比较少会去思考一些本质的问题,问答题可以说是督促我们去思考一些代码背后深层的东西,去探寻本源。在这种情况下,找出源码所在的位置还是比较重要的。
  • 这次项目实际上已经把大部分代码的框架搭好了,图形界面也已经封装在jar包内了,我们要做的实际上就是在原有类的基础上进行扩展,以实现不同的功能。实际上的生产生活中,我们程序员所做的工作也会有所类似,所以这次项目对于今后工作之后的经验还是很有帮助的。
  • 这次实训可以用到许多第三方类库,这些类库的功能是非常强大的。学习好这些类库对于我们的帮助也是巨大的,可以大大提高我们的编程效率。
  • 我们实际的编程中需要多多注意自己的代码规范,这对于代码的可读性和维护性来说都是意义重大的。Sonar确实是一个很好的代码风格检测工具,以后也需善加运用。
  • 我们在编写大型项目时最好要多多理解它的底层原理,虽然会比较辛苦,但是这对于实际编程效率的提示是巨大的,也更容易顺应底层的思想,希望以后学习中能贯彻到这些思想吧!
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值