20155232 2016-2017-3 《Java程序设计》第6周学习总结

20155232 2016-2017-3 《Java程序设计》第6周学习总结

教材学习内容总结

  • 第十章 异常处理

1.从应用程序来看,如果要将数据从源取出,可以使用输入串流。

2.如果要将数据写入目的地,可以使用输出串流。

3.输入串流代表对象为java.io.inputStream实例,输出串流对象为java.io.oututStram实例。
注意在不使用inputstream与outputstream时,必须使用close()关闭串流,也可使用JDK7尝试自动关闭资源语法。

4.FileInputStream与InputStream的子类,可以指定文件名创建实例,一旦创建文档就开启,接着可用来写数据不使用时都要使用close()关闭文档

5.InputStream、outputstream提供串流基本操作,如果想要为输入输出的数据做加工处理,可以使用打包器类。

6.常用的打包器具有缓冲区作用的BufferedInputStream、Bufferedoutputstream。

7.具备数据转换处理作用的DataInputStream、DataOutputStream。

8.具备对象串行化能力的ObjectInputStream、ObjectOutputStream等。

9.对字符数据的读取,提供了java.io.Reader类。

10.对字符串的写入提供了java.io.writer类。

11.FileReader、FileWriter可以对文档做读取与写入,读取或写入时默认使用操作系统默认编码做字符转换。
提示再启动JVM时,可以指定-Dfile.encoding来指定所使用的编码。

12.Reader,Writer有一些装饰器类可以用,如果串流处理数据的字节数据,实际上代表某些字符的编码数据,而想要字节数据装换为对应的编码字符,可使用InputStreamReader,OutputSteamWriter对串流数据打包。

13.BufferedReader,BufferedWriter可对Reader,Writer提供缓冲区作用。对效率有所帮助。

14.PrintWriter与PrintStream使用上极为相似,除了对Outputstream打包之外,printwriter还可以对writer进行打包。

15.父类中的方法,核心类:
image
image

16.标准输入输出:

标准输入输出

System.in:标准输入,默认关联到键盘(终端输入)

System.out:标准输出,默认关联到显示器(终端输出)

System.err:标准错误,默认关联到显示器(终端输出)

输入输出重定向:setIn,setOut,setErr

  • 第十一章

1.使用java.lang.Thread的静态sleep()方法,让目前流程暂停指定时间注意指定的单位是毫秒。

2.线程的生命周期
image

3.撰写类操作java.lang.runnable接口,达到main以外独立设置流程。

4.创建Thread实例来执行Runnable实例定义的run()方法,使从main开始的流程由主线程执行。

5.要启动线程执行指定流程,调用Thread实例的start()方法。

6.除了将流程定义在Runnable的run()方法之外,另一个撰写多线程程序的的方式,就是继承Thread类,重新定义run()方法。

7.操作Runnable接口的好处就是较有弹性,类还可以继承其他类。

8.如果主线程中启动了额外线程,默认会等待被启动的所有线程都执行完,run()方法才终止JVM。

9.若Thread被标示为Daemon线程,在所有的非DAaemon线程都结束时,JVM就会自动终止。

11.在调用Thread实例start()方法后,基本状态为可执行,被阻断,执行中。

12.线程有优先权,可使用Thread的setpriority()方法设定优先权,设定值为1到10,默认为5。超出设定值会抛出IllegalArgumentException

13.数字越大,优先权越高,排班器越优先排入CPU注意如果优先权相同,则输流执行。

14.当某线程进入Blocked时,将另一线程排入cpu执行,避免cpu空闲下来,是改进效能的方式之一。

15.线程因输入输出进入Blocked状态后,在阻断情况结束后,会回到Runnable状态,等待排班器排入执行。一个进入Blocked状态的线程,可以由另一个线程调用该线程的Interrupt()方法,使离开Blocked状态。

16.如果A线程正在运行,流程中允许B线程加入,等到B线程执行完毕后再继续A线程流程,则可以使用join()方法完成这个需求。

17.线程完成Run()方法后就会进入Dead,不可以再调用start()方法,否则抛出

IllegalThreadStateException

18.Thread类上定义有stop()方法,不过被标示为Deprecated,表示过去确实定义过,后来因为某些问题,这些API没有直接剔除。

19.若要停止线程,最好自行操作,不要使用stop()方法(包括暂停,重启)

20.线程一旦进入某个群组,就无法更换群组。

21.线程存取同一对象相同资源时,可能引发竞速情况,这样的类是不安全的。

22.每个对象都会有个内部锁定。被标示为synchronized的区块将被监控。

23.若在方法上标示synchronized,则执行方法必须取得该实例的锁定。

24.执行synchronized范围的程序代码期间,若调用锁定对象的wait()方法,线程会释放对象锁定,并进入对象等待集合,处于阻断状态。

25.放在等待的线程不会参与cpu排班,wait()可以指定等待时间,时间到之后线程会再次加入排班。
注意如果指定时间为0或不指定,则线程会持续等待,直到被中断或告知。

26.被竞争锁定的对象用notify()时,会从对象等待集合中随机通知一个线程加入。如果调用notifyAll(),所有等待集合中的线程都会被通知参与排班,这些会与其他线程共同竞争对象锁定。

教材学习中的问题和解决过程

  • 问题一

课本p305页代码中


            while ((length = input.read(data)) != -1) 

这里代码中的-1有什么用?

  • 解决方案一:

在上网查找了一下得到如下结果:虽然代码不一样,但是知道了-1代表了读取完毕。
image
image
image

  • 问题二

课本p325页代码:

 boolean isHareSleep = flags[((int) (Math.random() * 10)) % 2];
            if(isHareSleep) {
                out.println("兔子睡著了zzzz");
            } else {
                hareStep += 2;    
                out.printf("兔子跑了 %d 步...%n", hareStep);

在这里,flags数组有什么作用?

  • 解决方案:

我的理解是flag数组中随机函数产生的随机数非0的数字,数组就为非空,即boolean的值为True,反之,数组为空,即为False。可以用来判断兔子是否随机睡觉。

  • 问题三

线程退出后,进程就退出了,主线程创建的线程没有执行完就退出了。怎么解决

  • 解决方案

两个方式:
1、主线程等待子线程,用join;
2、子线程设置自己为守护线程。

  • 问题四

进程中线程之间的关系?

  • 解决问题

线程不像进程,一个进程中的线程之间是没有父子之分的,都是平级关系。即线程都是一样的, 退出了一个不会影响另外一个。

但是所谓的"主线程"main,其入口代码是类似这样的方式调用main的:exit(main(...))。

main执行完之后, 会调用exit()。

exit() 会让整个进程over终止,那所有线程自然都会退出。

代码调试中的问题和解决过程

  • 问题一:p309页运行时出现错误
    image
    image

  • 解决方案:
    上网搜索出现这个错误的原因,结果如下:image
    image
    image总结了一下,就是因为没有对args[]传值,没有加入参数,所以导致越界错误声明。

  • 问题二:
    课本p339页

package Thread;

public class ArrayListDemo {

    public static void main(String[] args) {
        ArrayList list = new ArrayList();
        Thread thread1 = new Thread(() -> {
            while (true) {
                list.add(1);
            }
        });

        Thread thread2 = new Thread(() -> {
            while (true) {
                list.add(2);
            }
        });

        thread1.start();
        thread2.start();
    }
}

按照书上的代码打上去,运行结果应该是发生ArrayIndexOutOfBoundException异常,但是在我编译的时候出现了如下错误:
image
image

  • 解决方案:

在仔细看书后,检查到了原因,是因为这个是用了课本6.2.5节中的方法,但是因为没有把这些程序放到同一个包中,所以找不到符号,不是代码本身的问题,因为在这个包中就没有定义这个方法。而书上所有代码都在同一个包中,所以编译可以通过。

  • 问题三:
    课本p350-p353 producer,consumer,代码编译都出现类似问题,显示找不到符号,但是这次代码都在同一个包中,所以出现了问题。
    image
  • 解决方案:
    image
    如上图,在编译时应注意先编译producer,和consumer,最后在编译含有main的主类,三个编译才能通过,最后在云心时一定要在同一个包中才能运行。

代码托管

  • 代码提交过程截图:

image
image
image
image

结对及互评

评分标准(满分10分)

  1. 从0分加到10分为止

  2. 正确使用Markdown语法(加1分):

    • 不使用Markdown不加分
    • 有语法错误的不加分(链接打不开,表格不对,列表不正确...)
    • 排版混乱的不加分
  3. 模板中的要素齐全(加1分)

    • 缺少“教材学习中的问题和解决过程”的不加分
    • 缺少“代码调试中的问题和解决过程”的不加分
    • 代码托管不能打开的不加分
    • 缺少“结对及互评”的不能打开的不加分
    • 缺少“上周考试错题总结”的不能加分
    • 缺少“进度条”的不能加分
    • 缺少“参考资料”的不能加分
  4. 教材学习中的问题和解决过程, 一个问题加1分

  5. 代码调试中的问题和解决过程, 一个问题加1分

  6. 本周有效代码超过300分行的(加2分)

    • 一周提交次数少于20次的不加分

6 其他加分:

  • 周五前发博客的加1分
    • 感想,体会不假大空的加1分
    • 排版精美的加一分
    • 进度条中记录学习时间与改进情况的加1分
    • 有动手写新代码的加1分
    • 课后选择题有验证的加1分
    • 代码Commit Message规范的加1分
    • 错题学习深入的加1分
      7 扣分:
    • 有抄袭的扣至0分
    • 代码作弊的扣至0分

点评模板:

  • 博客中值得学习的或问题:

    • xxx
    • xxx
    • ...
  • 代码中值得学习的或问题:

    • xxx
    • xxx
    • ...
  • 基于评分标准,我给本博客打分:XX分。得分情况如下:xxx

  • 参考示例

点评过的同学博客和代码

  • 本周结对学习情况
    • 20155215
    • image
    • 结对学习内容
      • 一起讨论课本代码,共同解决代码编译报错问题。
      • 前几周考试留下来的部分没有解决的试题。
      • 一起看JAVA教学视频。
      • 讨论知识点,交换学习体会和学习难点。
  • 上周博客互评情况

上周考试错题总结


    1. import java.util.*;
    2.
    3. Class FindStuff  {
    4.public static void main (String[]args)    {
    5,    //insert code here
    6.    c.put ("X", 123);
    7.    }
    8.  }
分别插入到第5行,哪几行允许代码编译?

A .
Map c= new SortedMap();

B .
HashMap c= new HashMap();

C .
HashMap c= new Hashtable();

D .
SortedMap c= new TreeMap();

E .
ArrayList c= new ArrayList();

F .
Map c = new LinkedHashMap();

答案: B D F

3.  import java.util.*;
    4.    class ForInTest  {
    5.static List list=new ArrayList();
    6.
    7.public static void main (String  []  args)  {
    8.list. add("a"); list. add("b");list. add( "c");
    9.    //insert code here
    10.    System.out.print (o);
    11.    }
    12.  }
哪一行插入到第9行将导致输出“abc"?

A .
for (Iterator o : list.iterator(); o.hasNext (); )

B .
for (Iterator o : list)

C .
for (Object o : list.iterator())

D .
for (Object o : list)

答案:D

  • 下列哪些项是泛型的优点? (选两项)
    A .
    不用向下强制类型转换

B .
代码容易编写
C .
类型安全

D .
运行速度快

答案:AD

原因:少选了C,看书看得还是不够仔细,只记住了大概。

  • Which of the following methods will not compile?

A .
private void method1(String name) {
if (name.equals("star"))
throw new IllegalArgumentException(name);
}

B .
private void method2(int age) {
if (age > 30)
throw Exception();
}

C .
public double method5() throws Exception {
return 0.7;
}

D .
protected double method4() throws Exception {
throw new Throwable();
}

答案:BD

  • What is the output of the following code?
class EJava {
void method() {
try {
guru();
return;
} finally {
System.out.println("finally 1");
}
}
void guru() {
System.out.println("guru");
throw new StackOverflowError();
}
public static void main(String args[]) {
EJava var = new EJava();
var.method();
}
} 

A .
guru
finally 1

B .
guru
finally 1
Exception in thread "main" java.lang.StackOverflowError

C .
guru
Exception in thread "main" java.lang.StackOverflowError

D .
guru

E .
The code fails to compile.

答案:B

  • 现有:
 1.   class  Parser extends  Utilis  {
   2.     public static void main (String  []  args)  {
   3 .          try  {  System. out.print (new  Parser ( ) .getlnt ("42")) ;
   4.     }  catch (NumberFormatException n) {
   5 .              System.out .println ( "NFExc" ) ;   }
   6.    }
   7.     int getlnt (String arg)  throws NumberFormatException{
   8.       return Integer.parselnt (arg) ;
   9.    }
   10. }
   11. class Utils {
   12.    int getlnt (String arg)  {  return 42;  }
   13. }
    

结果为 :

A .
NFExc

B .
42

C .
42NFExc

D .
编译失败

答案:B

  • 现有:
 1. class Flow {
 2.   public static void main(String [] args) t
 3.    try {
 4 .              System. out .print ("before") ;
 5 .                  doRiskyThing ( )  ;
 6.          System.out.print ("after ") ;
 7.    } catch (Exception fe) {
 8.          System.out.print ("catch") ;
 9.     }
 10 .          System. out .println ( " done") ;
 11.   }
 12.  public static void doRiskyThing() throws Exception{
 13.   
          }}

可能会产生哪两项结果 ?(选两项)

A .
before catch

B .
before after done

C .
before catch done

D .
before after catch

答案:BC

  • 现有:
1.  class Guy  {  String greet()  {  return "hi";  }  j
2.  class Cowboy extends Guy  {  String greet()  {  return. "howdy";}}
3.  class  Wrangler  extends  Cowboy  {  String  greet()  {  return  "orch!"; } }
4.
5.  class Greetings2  {
6.   public  static void main (String  []  args)  {
7.     Guy g=new Wrangler();
8.    Guy g2=new Cowboy();
9.     Wrangler w2=new Wrangler();
10.    System. out .print (g.greet()+g2.greet()+w2 .greet());
11.    }
12.  }
结果是什么?

A .
hi hi ouch!

B .
ouch! howdy ouch!

C .
hi howdy ouch!

D .
编译失败

答案:B

 1. abstract class Color  {
    2.protected abstract  String getRGB();
    3.  }
    4.
    5. public class Blue extends Color  {
    6.    //insert code here
    7.  }
    和四个声明:
    public String getRGB()  {  return "blue";  }
    String getRGB()  {  return  "blue";  )
    private  String getRGB()  {  return  "blue";  }
    protected String getRGB()  {  return "blue";  )
分别插入到第6行,有几个可以通过编译?

A .
0

B .
1

C .
2

D .
3

答案:C

原因:看不太懂题目,代码也不太看得懂,我觉得这种程序类的题,希望老师能多讲解考过的试题或者课本上的代码,帮助我们更好地理解。因为之前的考试就只有答案没有解析,有的题目还是不太理解。

感悟心得

  • 对教材感悟
    第十章主要讲了串流与输入输出的关系,认识了InputStream outputstream继承架构,认识了reader,eriter继承架构。第十一章认识了Thread与Runnable,使用synchronized。了解了wait(),notify(),notifyAll()。

  • 对考试感悟
    这次考试,使用了蓝墨云这个APP,非常的不习惯,有点手忙脚乱,不太适应这种考试,而且觉得这次题目难度加大了很多,题目篇幅也有点大,代码类的题目加多,做不太完。还得慢慢去适应这种考试方式,提高速度与熟练度。

  • 课本中代码的部分展示与思考

1.p314页代码如图:
image
运行结果:
image
范例中有三个member实例,分别存储为文档之后再读取回来。

2.p325页代码如下:
image
运行结果:
image这个是课本上最简单的,也就是只有一个流程,就是从main()开始至结束的流程。兔子可能随机睡觉,运用了random函数。

课本p326-p327页将上面这个程序做了改进。

这个是兔子的流程,从run()开始。

package Thread;

public class Hare implements Runnable {
    private boolean[] flags = {true, false};
    private int totalStep;
    private int step;

    public Hare(int totalStep) {
        this.totalStep = totalStep;
    }

    @Override
    public void run() {
        while (step < totalStep) {
            boolean isHareSleep = flags[((int) (Math.random() * 10)) % 2];
            if (isHareSleep) {
                System.out.println("兔子睡着了zzzz");
            } else {
                step += 2;
                System.out.printf("兔子跑了 %d 步...%n", step);
            }
        }
    }
}

而乌龟的流程在如下代码中:

package Thread;

public class Tortoise implements Runnable {
    private int totalStep;
    private int step;

    public Tortoise(int totalStep) {
        this.totalStep = totalStep;
    }

    @Override
    public void run() {
        while (step < totalStep) {
            step++;
            System.out.printf("乌龟跑了 %d 步...%n", step);
        }
    }
}

image
在这个程序中,主线程执行main()定义的流程,main()定义的流程中建立了tortoiseThread与hareThread两个线程。要启动线程执行指定流程,必须调用Thread()的start()方法。

3.p330代码
image
image
使用了setDaemon(true)就是当前进程变为后台线程,对java来说,只要还有一个前台线程在运行,这个进程就不会结束。

4.课本p331代码:
image
image这个程序可以指定网页下载东西,在每次for循环,进行HTTP请求,然后进行文档写入。但是效率非常的低下。

5.课本333页代码:

image
image
Thread。sleep()会让线程进入Block状态,若此时有其他线程调用该线程的interrut()方法,会抛出异常对象,就会使线程“醒过来”。

6.p334页代码:
image
image
当线程使用join()加入另一线程时,另一线程会等待被加入的线程工作完毕,然后再继续他的动作。程序启动后,主线程开始,在主线程中新建threadB,并在启动后,将至加入主线程中,所以会先执行B,主线程才会继续原本的流程。

7.在课本p337页,uncaughtException()方法第一个参数可取的发生异常的线程实例,第二个参数可取得异常对象,运行结果显示了线程的名称及异常信息。
image
image

8.课本p338页中,t1,t2都属于同一个Threadgroup。t2没有设定Thread。UncaughtExceptionHandler实例。所以有默认的第三个处理方式。image
image

9.课本p344页代码如下:这个程序可能会发生死结,就是两个线程都处于不放开resource锁定的状态,在死结发生时陷入停顿状态。
image
image

10.课本p345页代码:
image
运行如下:thread1会调用Variable1.one(),thread2会调用Variable1.two(),有可能会发生thread2调用取i值后,切换至thread1不断执行,再切换至thread2取j值,有可能j远大于i。
image

11.在课本p364-p366程序中,将Pages.java和DirectExecutor.java和Download.java按这个顺序编译后,运行结果下载了
image

12.课本p371代码
image使用了newSingleThreadScheduledExecutor()返回的SchduledExecutorService。java.util.Date创建时,回去的当时系统时间,每次工作会执行2秒,而后延迟1秒,所以如图每三秒一个间隔。
image

13.课本p374页,在继承RecursiveTask之后,主要将子任务与求解过程撰写于compute()方法中,为了避免分解出过多的子任务,造成不必要的麻烦,n< 20就直接用循环求解。
image
image

14.课本p376-p378页代码,使用了BlockingQueue的操作ArrayBlockingQueue类,这样就不用处理麻烦的wait(),notify()流程了,简化了很多。image

学习进度条

代码行数(新增/累积) 博客量(新增/累积) 学习时间(新增/累积) 重要成长
目标 5000行 30篇 400小时
第一周 15/15 1/1 23/26
第二周 208/240 2/2 35/38
第三周 376/584 3/3 32/38
第四周 823/1407 4/4 28/30
第五周 986/2393 5/5 21/26
第六周 1258/3651 6/6 26/25

尝试一下记录「计划学习时间」和「实际学习时间」,到期末看看能不能改进自己的计划能力。这个工作学习中很重要,也很有用。
耗时估计的公式
:Y=X+X/N ,Y=X-X/N,训练次数多了,X、Y就接近了。

参考:软件工程软件的估计为什么这么难软件工程 估计方法

参考资料

posted @ 2017-04-01 10:52  短爪爪爪  阅读(360)  评论(5编辑  收藏  举报