面向对象第一次博客作业总结反思

写在前面寒假也没有好好学java,第一次作业就很狼狈,用学得一知半解的java语法写了个半面向过程的程序;之后两次作业也是暴露了很多问题,只能边debug边补知识,往往到了周三下午还在紧张地测试改程序,终于第四周轻松了有机会对自己的经验做一个总结、大家分享前几次作业中遇到的问题与解决方法。这次博客总结会按三次作业的顺序总结自己学到的知识,然后分析一些bug和解决方法,最后再对自己的程序做度量分析。


 

第一次作业:多项式运算

  我觉得本次作业最培养的是认真阅读指导书的习惯并熟悉java的基本语法,并推荐了java的正则表达式与try catch异常处理,可以说是在为后来的作业打基础,但是这期间学到的知识也很多,不妨从正则表达式开始:

 

  1.正则表达式

   首先向大家分享一个我学习正则表达式的网站:

   http://www.runoob.com/java/java-regular-expressions.html

   里面对正则表达式各符号的用途与用法有很详细的介绍,基本这三次作业需要用到的知识都涵盖了,相信大家通过几次作业都已经完全掌握了这些基础知识,但是在这里我遇到了几个问题,还因为这里的疏忽导致了之后作业公测的bug……是很惨的教训了。

 

  2.Matcher()与Matches()

    很多人都用的是matches方法来进行正则表达式匹配,matches要求对整个表达式的匹配,由于大多数人都用的这种方法,在这里只举一个最最简单的例子:

    

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class example {
    private static final String REGEX = "foo";    //foo bar 就像  hello world 一样常见,常被用来举例
    private static final String INPUT = "fooooooooooooooooo";
 
    public static void main( String args[] ){
       Pattern pattern = Pattern.compile(REGEX);
       Matcher matcher = pattern.matcher(INPUT);
       
       System.out.println("matches(): "+matcher.matches());
   }
}    

 

 

 

     但是我是在通过上面的链接学习正则表达式时看到了另一个方法,直接上一张截图:

    

    这里设置好pattern和matcher对象后,是通过matcher类的find方法去匹配的,可以通过matcher.group()来调用被匹配的字符串,特殊的是group(0)返回的是匹配到的整个表达式,group(1...)返回的是匹配字符串的子串,而若find匹配失败,直接调用group(0)时会出现异常,这里正好用一个try catch包住。当时读到这里,一拍脑门节写进自己的代码了……也就是下面这个样子:

 1          String pattern = "^foooo$";
 2         Pattern r = Pattern.compile(pattern);
 3         Matcher m = r.matcher(S);
 4         
 5         try {
 6             m.find();
 7             m.group(0);
 8         } catch (Exception e){
 9              System.out.println("ERROR");
10             System.out.println("#不符合输入格式");
11             System.exit(0);
12         }        

 

   这个方法虽然有点“土”,但是基本功能还是能实现的,也可以通过find()的返回值进行判断,但是find方法与matches是有区别的,matches是整个表达式的匹配而find只要局部匹配就能成功调用group(),所以这种写法必须在正则表达式首尾加上^$表示“从头匹配到尾”,我自己因为第二次作业是忘了加^$导致不合法的输入“漏”了过去,在处理请求时crash了…所以只是介绍自己的经验,也许这一方法在其他地方会更好用,但是电梯作业中还是推荐使用matches()。

 

  3.正则表达式爆栈

  第一次公测很多同学第30个点都爆红了,这个测试点是一个压力测试,当有20个多项式每个50项再用一个完整的正则表达式进行匹配时,会因为正则的回溯而爆栈。关于正则表达式的原理与爆栈的原因。一个可行的解决方法是分层分步地进行匹配,先判断多项式(大括号)的合法性,再用一个正则表达式匹配每一项的合法性。

   在知乎上找到了一个介绍正则表达式实现原理的专栏,讲得很明了,也贴在这里:

  https://zhuanlan.zhihu.com/p/27417442

 

  4.try catch

  经过几次作业,大家对异常处理已经很熟悉了,赶第一次作业时我只看了一点,写成上面那段代码中的样子就交了上去,但是搜索try catch时后面联想词会出现finally与throw,现在有时间不妨多看两眼学习一下。首先,try catch finally是一系列异常处理,曾经找到过一张图很好地概括了其间的关系:

  5.本次作业度量分析

  

  6.类图

 


 

  

第二次作业:傻瓜电梯

  1.感想

    写了第二次作业傻瓜电梯,看看自己的各种bug,发现原来电梯还是个挺智能的东西…昨天刚刚看到一篇文章说现在的电梯按特定的组合键还能进入“独立模式”调度更复杂QAQ。因为这不再是面向过程一个文件干到底,所以在上手前先构思各个类之间的功能与结构是很重要的,埋头狂写后期就可能会面临疯狂打补丁甚至重写的情况 (眼泪不争气地就流下来了.gif),指导书与课件给出了很好的框架,但是在框架下有非常丰富的发展空间,第三次电梯作业更是如此,虽然结构类似,但是互评时面对上千行陌生代码想读懂对方的思想还是一个非常痛苦的过程… 

  2.parse(解析)

  比起写一个函数去将字符串转成整型并处理正负号前导零,不如试试Number类自带的parse方法,举个栗子:

public static void main(String args[]) {
    int n1 = Integer.parseInt("+0001");
    Double n2 = Double.parseDouble("-009527");
        
    System.out.println( "n1:" + n1 + " n2:" + n2);
}

 

  但是要注意传给parse的字符串必须是能被转换的,若是传入了不合法的字符,则会导致crash。

  3.LinkedList 遍历的一个问题

  刚刚写完自测同质请求时发现,有时会漏过一条同质没有删掉而是执行了,后来发现原来是在用for循环遍历队列时,删掉一条请求后,会指向下一条请求,这是再i++会漏过一条指令。

  4.度量分析

 

  5.类图

第三次作业:聪明一点的调度策略

  1.作业分析

    ALS调度内容丰富了很多,bug类型也更多了,但是还是不如现实中的电梯…一番打量后感觉有两个思路(也许还有其他更优秀的做法),一个是按楼层刷请求、一个是模拟电梯的运行时间,前者更符合生活实际,但是两种方法都有很多细节问题,处理不好容易出bug。我一开始很多问题都没考虑到,到了周二周三一直在疯狂打补丁……很多判断直接加在了main函数里(orz知错了),代码越写越长也越来越丑,虽然加了尽量多的注释,但是也是难为互测时拿到我代码的同学了……

  2.度量分析

  

  3.类图

  

 

   4.bug分析

  在互评阶段我测试别人的程序时发现了自己的一个bug,而侥幸最后对方没有发现:在输出与主请求目标同层的捎带请求时,我会直接输出主请求的信息,然后在捎带请求队列(我新建了一个LinkedList存放所有可被捎带的请求)找出所有同层的捎带请求然后按时间顺序输出。而实际上应当是将这一条主请求与所有捎带请求一起按输入的顺序输出,也就是我的输出顺序在特定的情况下会有错误。

posted @ 2018-04-04 14:15  nerdary  阅读(221)  评论(0编辑  收藏  举报