20155318 2016-2017-2 《Java程序设计》第六周学习总结
20155318 2016-2017-2 《Java程序设计》第六周学习总结
教材学习内容总结
学习目标
- 理解流与IO
- 理解InputStream/OutPutStream的继承架构
- 理解Reader/Writer继承架构
- 会使用装饰类
InputStream和OutputStream
- 发生错误时返回```java.io.IOException``异常,所以表示为
public static void dump(InputStream src, OutputStream dest)
throws IOException{
close()
关闭串流InputStream
读入数据先置入byte数组read()
读入byte数组长度,返回实际读入的字节;-1表示未读到数据write()
指定写出(byte数组,初始索引,数据长度)
byte[] data = new byte[1024];
int length;
while ((length=input.read(data))!=-1){
output.write(data,0,length);
}
串流继承构架
- 流(Stream)是对「输入输出」的抽象
- 可以用那个这个图很好的概括IO流中的字符流和字节流的继承构架:
System
- System.in: 标准输入,默认关联到键盘(终端输入);
- System.out: 标准输出,默认关联到显示器(终端输出)
- System.err: 标准错误,默认关联到显示器(终端输出)
- System.setIn()重新指定标准输入来源,如指定为FileInpuStream可读取指定文档
- System.setOut()将输出结果指定至目的地,如指定在文档内输出
- System.setErr()指定标准错误输出串流
File&Byte
- FileInputStream是InputStream的子类,用于衔接文档读入数据;
- FileOutputStreamShi OutoutStream的子类,用于衔接文档写出数据
- 两种都操作都是以字节为单位,使用结束后都需要close()关闭文档
- ByteArrayInputStream和ByteArrayOutputStream以byte数组为单位
串流处理装饰器(打包器类)
- 缓冲区作用(将足够数据读至内存的缓存区,存取更快)
- BufferedInputStream与BufferedOutputStream
- 数据转换处理作用
- DataInputSream与DataOutputStream
- 对象串行化作用
- ObjectInputStream、ObjectOutputStream
字符处理类
1.Reader与Writer
- java.io.Reader类,字符数据读取,置入char数组
- java.io.writer类,字符数据写出
- 装饰器
- InputStreamReader与OutputStreamWriter制定编码
- BufferedReader与BufferedWriter缓冲区作用,提高效率
- PrintWriter打包
线程
- 在main()外分别定义独立流程,要启动线程执行制定流程,必须调用Thread实例的start()方法。
Thread tortoiseThread = new Thread(tortoise);
Thread hareThread=new Thread(hare);
tortoiseThread.start();
hareThread.start();
- Java中线程的创建有两种方式:
- 通过实现Runnable接口,将流程定义在方法之中,实例化Thread类(弹性)
- 通过继承Thread类,重写Thread的run()方法,将线程运行的逻辑放在其中(直接利用Thread类的方法
- 继承Thread类在创建多个对象的同时创建了多个线程,分别完成自己的任务
- 实现Runnable的相当于创建一个任务,然后实例化多个Thread,创建多个线程共同完成一个任务。
-
Daemon线程:非Daemon线程结束时JVM停止,setDaemon()方法可以设定Daemon线程。
-
基本状态(可执行、被阻断、执行中)
-
线程的优先权:
setPriority()
从1到10,默认5,数字越大优先权越高 -
Blocked状态,进入Thread.sleep(),离开interrupt()
-
安插线程join()
ThreadGroup(每个线程都属于某个线程群组)
- interrupt()中断群组中所有线程,
- setMaxPriority()设定群组中所有线程最大优先权
- activeCount()方法获取群组的线程数量
synchronized与volatile
- 任何线程要执行synchronize区块都必须先取得指定的对象锁定
- 不正确地使用synchronize有可能造成效能低下,甚至导致死结
- volatile保证单一变数可见,线程对共享内存中变量的存取,另一线程一定看得到
Lock、ReadWriteLock与Condition
- Lock接口主要操作类之一为ReentrantLock,可以达到synchronized的作用。
- ReadWriteLock接口定义了读取锁定与写入锁定行为,可以使用readLock()、writeLock()方法返回Lock操作对象。
- StampedLock类可支持了乐观读取操作。
- Condition接口用来搭配Lock,最基本用法就是达到Object的wait()、notify()、notifyAll()方法的作用。Condition的await()、signal()、signalAll()方法,可视为Object的wait()、notify()、notifyAll()方法的对应。
教材学习中的问题和解决过程
- 问题1:字符流和字节流的区别和联系
- 解决方案:因为数据编码的不同,而有了对字符进行高效操作的流对象。本质其实就是基于字节流读取时,去查了指定的码表。
- 字符流与字节流的区别:
- 读写单位不同:字节流以字节(8bit)为单位,字符流以字符为单位。
- 处理对象不同:字节流能处理所有类型的数据,而字符流只能处理字符类型的数据。
总结:只要是处理纯文本数据,就优先考虑使用字符流,除此之外都使用字节流。
- 字符流和字节流的一些打包器方法使用相似,因为二者本质相同
- 问题2:synchronized和lock二者都用在线程控制上,控制锁,那么二者有什么区别?
- 参考了很多博客依然……未解决
- 可以参考:深入研究 Java Synchronize 和 Lock 的区别与用法
代码调试中的问题和解决过程
- 问题1:课本P326的Tortoise程序中直接使用Runnable接口会报错
需要重新定义Runnable中的run()方法
那么能否直接重新构造一个run()方法而不定义这个接口呢?
- 解决方案:在网上搜索一下这个问题,发现与我有相同疑惑的人有很多,参考Java的接口有什么作用-知乎,其中说明接口是用来提示程序员做什么的,接口中的方法是告诉程序具体怎么做。例如JDK中的Comparable接口,当两个对象都满足这个接口时,是标明他们可以比较,但是具体的比较方法是其中的compareTo方法来执行的。
- Java中继承thread类与实现Runnable接口的区别又表明Java中线程的创建有两种方式:
- 通过继承Thread类,重写Thread的run()方法,将线程运行的逻辑放在其中
- 通过实现Runnable接口,实例化Thread类
-
问题2:如图出现错误提示
-
解决方案:改成和class同名的构造函数
public TortoiseThread(int totalStep)
错误提示消失 -
问题3:在编写课本p328-329的继承Thread类代码时,用到了target,出现如下错误提示:
提示显示target是Thread的private类,不能调用
- 解决方案:未解决
- 问题4:对着课本打p339的代码时,出现多次编译错误
- 解决方案:原因有二,一是检查后发现需要格外注意这个代码的细节
二是这个代码时同时进行两个线程,会发生ArrayIndexOutOfBoundsException异常。
- 问题5:在调试课本330页代码的过程中出现了如下问题:
- 解决方案:
public static void main(String[] args) {
Thread thread = new Thread(){
public void run(){
while (true){
System.out.println("Ozr");
}
}
};
thread.setDaemon(true);
thread.start();
}
程序执行正常,运行结果如下:
若将代码去掉thread.setDaemon(true);
这一行会出现如下结果:
代码托管
上周考试错题总结
上周考试是用的蓝墨云班课进行测试的,选了几道比较有代表性的错题记录:
- 错题1:(多选题|1分)
现有:
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行,哪几行允许代码编译?
- 答案:
B .HashMap c= new HashMap();
D .SortedMap c= new TreeMap();
F . Map c = new LinkedHashMap(); - 错题2:
创建一个只能存放String的泛型ArrayList的语句是哪项? - A. ArrayList
al=new ArrayList (); - B. ArrayList
al=new ArrayList () - C. ArrayList al=new ArrayList
(); - D. ArrayList
al =new List ();
答案:B - 错题3:(单选题|1分)
现有:
1. class Propeller2 {
2. pulolic static void main (String[]args)//add code here?
3. { new Propeller2().topGo(); }
4.
5.void topGo() //add code here?
6. { middleGo(); }
7.
8.void middleGo() //add code here?
9. { go(); System.out.println ("late middle"); }
10.
11. void go() //add code here?
12. {throw new Exception(); }
13. }
为使代码通过编译,需要在哪一行加入声明throws Exception?
- A .只在第11行
- B .在第8行和第11行
- C .在第5行、第8行和第11行
- D .在第2行、第5行、第8行和第11行
- 答案:D
结对及互评
评分标准
-
正确使用Markdown语法(加1分):
- 不使用Markdown不加分
- 有语法错误的不加分(链接打不开,表格不对,列表不正确...)
- 排版混乱的不加分
-
模板中的要素齐全(加1分)
- 缺少“教材学习中的问题和解决过程”的不加分
- 缺少“代码调试中的问题和解决过程”的不加分
- 代码托管不能打开的不加分
- 缺少“结对及互评”的不能打开的不加分
- 缺少“上周考试错题总结”的不能加分
- 缺少“进度条”的不能加分
- 缺少“参考资料”的不能加分
-
教材学习中的问题和解决过程, 一个问题加1分
-
代码调试中的问题和解决过程, 一个问题加1分
-
本周有效代码超过300分行的(加2分)
- 一周提交次数少于20次的不加分
-
其他加分:
- 周五前发博客的加1分
- 感想,体会不假大空的加1分
- 排版精美的加一分
- 进度条中记录学习时间与改进情况的加1分
- 有动手写新代码的加1分
- 课后选择题有验证的加1分
- 代码Commit Message规范的加1分
- 错题学习深入的加1分
- 点评认真,能指出博客和代码中的问题的加1分
- 结对学习情况真实可信的加1分
-
扣分:
- 有抄袭的扣至0分
- 代码作弊的扣至0分
- 迟交作业的扣至0分
点评模板:
-
博客中值得学习的或问题:
- xxx
- xxx
- ...
-
代码中值得学习的或问题:
- xxx
- xxx
- ...
-
基于评分标准,我给本博客打分:XX分。得分情况如下:xxx
点评过的同学博客和代码
- 本周结对学习情况
-
结对照片
-
结对学习内容
- 学习partner的代码并作出点评
- 学习partner的博客和自己的博客做对比,找出不足
- 上周博客互评情况
其他(感悟、思考等,可选)
这周学习量比较大,敲的代码也比较多,感觉对线程的理解还是很抽象,希望能通过后续的学习慢慢理解。
学习进度条
代码行数(新增/累积) | 博客量(新增/累积) | 学习时间(新增/累积) | 重要成长 | |
---|---|---|---|---|
目标 | 5000行 | 30篇 | 400小时 | |
第一周 | 50/100 | 1/1 | 24/24 | 安装学习Java的一系列软件 |
第二周 | 250/300 | 1/2 | 30/54 | 了解Java的基本语法 |
第三周 | 552/852 | 1/3 | 16/60 | 了解Java是面向对象的语言 |
第四周 | 717/1569 | 1/4 | 10/70 | 了解Java继承与接口 |
第五周 | 495/2064 | 1/5 | 6/76 | 了解异常处理,学会使用Collection收集对象 |
第六周 | 754/2818 | 1/6 | 6/82 | 了解串流和线程 |
-
计划学习时间:10小时
-
实际学习时间:6小时