OO前三次作业总结
代码结构
方法:
public Dispatcher()
public void dispatch()
电梯调度原理:
维护的请求队列保证队首永远是有效请求(即非同质请求),每次调度过程为:
1、将队首(设为front)弹出。
2、调用Elevator.move()方法,移动电梯,并改变电梯状态。
3、根据front的类型,调用RequestQueue.cleanByElevator()方法,或者调用RequestQueue.cleanByFloor()方法,将请求队列内的同质请求清除,保证队首永远不是同质请求。
ALS_Dispatcher 类
ALS_Dispatcher 类继承自 Dispatcher类,重写了dispatch方法,调度原理太复杂实在没时间重写了QAQ,如有兴趣,代码中有些许注释可以食用。
public class ALS_Dispatcher extends Dispatcher
public ALS_Dispatcher()
public void dispatch()
public static void main(String[] args)
Request 类
属性:
private String type;
private String dir; //方向
private String StrForm; //请求的原有字符串格式
private int n,m;
private long T;
方法:
public Request()
public boolean isValid() //判断这个请求是否有效
public Request(String reqstr) //构造方法
public void setT(long x)
public void setType(String x)
public String getType()
public int getFloor()
public String getdir()
public long getT()
public void print()
public boolean equals(Request req) //判断相同请求
public String getStrForm()
Floor 类
属性
private int UP_button;
private int DOWN_button;
private int last_req_time;
private int self_floor;
方法
public Floor(int x)
public boolean recive(Request req) //判断本次请求是否有效,与按钮关联,但本次作业未使用
public Floor()
RequestDeque 类
属性
private Deque<Request> deque;
方法
public class RequestDeque
public RequestDeque()
public boolean isEmpty()
public Request peekFirst()
public Request peekLast()
public Request pollFirst()
public Request pollLast()
public void offerFirst(Request req)
public void offerLast(Request req)
public void print()
public void cleanByElevator(Request now_req,Elevator elevator) //用于清除同质电梯请求
public void cleanByFloor(Request now_req,Elevator elevator) //用于清除同质楼层请求
public void cleanByElevatorMain(Request now_req,Request main_req,Elevator elevator) //用主请求清除同质电梯请求
public void cleanByFloorMain(Request now_req,Request main_req, Elevator elevator) //用主请求清除同质楼层请求
public void removeSameByMain(Elevator elevator, Request req,Request main_req)
public void removeSame(Elevator elevator,Request req)
public boolean canCarry(Elevator elevator, Request main_req, Request now_req)
public void remove(Request req)
public Request haveCarry(Elevator elevator, Request main_req) //判断是否可以捎带
public Request haveSameFloorCarry(Elevator elevator, Request main_req) //判断是否有同层的捎带请求
public RequestDeque getSameFloor(Elevator elevator,Request main_req,Request now_carry) //将同层的捎带请求以请求队列的形式返回
public Request getMinIndRequest()
public void readRequestDeque()
Elevator 类
重写了toString()方法。
属性
private int last_floor;
private double last_close_time;
private String last_dir;
private int main_floor;
private double main_close_time;
private String main_dir;
private Request last_req;
方法
public class Elevator implements ElevatorMovement
public Elevator()
public void move(Request req)
public String getLastDir()
public int getLastfloor()
public void setMainStatus(Request req) //设置主请求执行后的状态,但电梯并未真正移动
public void moveToMainStatus(Request req) //将电梯移动到主请求结束状态
public void changeMainStatus(Request main_req,Request now_carry) //用捎带请求改变当前主请求完成状态
public int getMainFloor()
public String getMainDir()
public double getMainCloseTime()
public double getLastCloseTime()
public boolean canDoBeforeMain(Request now_carry,Request main_req)
public double getMinArriveTime(Request req)
public double getCompleteTime(Request req)
public String toString(Request req)
ElevatorMovement 接口
使用接口规范Elevator运动方式。
public interface ElevatorMovement {
public void move(Request req);
public void moveToMainStatus(Request req);
}
自己的bug
我的第二次、第三次作业中并没有被发现bug,那就分析一下第一次作业吧~第一次作业中公测挂了2个测试点,互测挂了1个测试点。互测的一个测试点是因为和README自相矛盾了,因为当时改了代码却没有修改README。
如何发现别人的bug
1、先读README:
就作业而言,README的作用不像真实开发过程中一般用来让人了解程序的用法,因为大家程序的用法基本都一样。而是主要用来规范用户对程序的输入输出,对自己所做的容错机制加以明确。对于互测环节,直接通过阅读README,就可以发现一些设计的bug,尤其是对非法情况不加以限制,例如指令条目、数字长度等,都会直接导致bug的出现。
2、查看输入部分代码,重点看正则
正则中容易出现“+”,“*”等操作符,对这样的操作符不小心使用很可能导致爆栈。
3、手动构造bug分类树小数据
现有分类树其实比较完善了,但是公测的分类树数据比较弱,可以手动增加一些条目进行增强。
4、随机生成大数据,并使用多份程序进行对拍
使用脚本,随机生成大数据,与多份的程序答案进行交叉验证。实际上数据的体量越大自然就越容易暴露错误,而我们第二次和第三次都对指令条数做了限制,100行其实不容易发现错误。不过,我们的目的是找出代码逻辑上的漏洞,于是可以对测试代码稍加修改,使得其支持更大体量的数据,比如10000条,之后就可以充分利用随机数据进行测试了,只要随机的次数足够多,问题基本上会被暴露出来。
5、精读代码
如果这份代码在以上四个环节都闯关成功,那么就可以开始精读代码、私人订制测试了,该过程时间较长,因此放在最后比较合理。闯过这关,一般我就认为被测人的代码真正bug free了。
心得体会
注释还是不注释,这是个问题
第一次、第三次分到的作业应该都出自高手,虽然不是没有bug,但是代码十分简洁,让我自愧不如,不过他们都没有注释。在和同学们的交谈中,仿佛同学们怕在互测中暴露自己的真实思路,都不太愿意添加注释,我认为这种想法是不对的。并不是说你不加注释,别人就看不懂你的代码了,注释与不注释的唯一区别是测试者轻轻松松的读完你的代码还是非常闹心的读完你的代码。因此虽然我每次作业写得比较麻烦,但是我会积极地添加注释。不仅因为这在实际生产生活中是必要的,也会有与人方便予己方便的效果。
都跟你说了要用Try Catch