20172314 2017-2018-2 《程序设计与数据结构》第九周学习总结
教材学习内容总结
11章
-
异常处理
- 异常:非正常对象或错误对象,由程序或运行时环境抛出,可根据需要进行相应的捕获和处理。
- 错误:与异常的区别在于错误代表不可恢复的问题并且必须捕获处理。
- 处理异常:根本不处理异常、在异常发生时处理异常、在程序的某个位置集中处理异常。
-
未捕获的异常
程序如果不处理异常,程序将结束执行,并输出异常的具体信息:是什么异常、抛出异常的原因、并调用堆栈踪迹信息,指明发生异常的方法、文件、代码行号及其他异常方法,显示引起异常发生的各个方法的调用顺序。 -
try-catch语句
- try语句块中为可能抛出异常的语句块,每一个catch为一个异常处理器,如果没有异常抛出,则执行try-catch后的语句,如果有异常,catch处理完异常后继续执行之后的语句。
- 一条try语句后可以有一个或多个catch,具体执行那个catch由发生的异常决定。
-
finally子句
一条try-catch语句可以有一个可选的finally子句,如果有,必须在所有的catch子句之后,并且一定会执行,只有try语句时仍可以有finally语句。 -
异常的传递
在某处发生异常时,将会传递给所有调用该方法的方法,所以当我们执行一个程序出现错误时,可能会由于一处错误而显示一系列错误。 -
异常类层次结构
各种异常的类由继承关系结合在一起,形成了类层次结构。
-
自定义异常
-
可由Exception类或他的后代类派生一个新类来定义一个新的异常
-
throw:例11.5
if (value < MIN || value > MAX)
throw problem;
throws:用在方法头
public static void main(String[] args) throws OutOfRangeException
throw和throws在自定义异常时需成对出现除非使用try-catch语句解决。
-
-
可检测异常与不可检测异常
- 可检测的异常如果不捕获和处理,则必须含有throws子句
- Java中不可检测的异常只有RuntimeException类的对象或该类的后代。
-
I/O异常
- 流是一个有序的字节序列,可以做输入源或输出目标。
- 有三种标准I/O流,是三种对象,标准输入流(System.in),标准输出流(System.out),标准错误流(System.err)。
- IOException是几个异常类的父类,代表试图执行I/O操作时发生的问题。
-
文件读写
字节操作流:OutputStream、InputStream(FileOutputStream、FileInputStream)
字节缓冲流:BufferedOutputStream、BufferedInputStream
字符操作流:Writer、Reader(重要:FileWriter、FileReader)
字符缓冲流:BufferedWriter、BufferedReader
12章
- 递归思想
- 递归是一种编程技术,允许一个方法调用自己以达目的
- 例1:求n!
factorial(n){ if(n == 1) return 1; else return factorial(n-1)*n; }
- 例2:求n的累加
sum(n){ if(n == 1) result =1; else result = n+ sum(n-1); return result; }
- 无穷递归
非递归定义部分称为基本情况。一个递归定义中必须有非递归定义部分才能使递归最终结束,否则会产生无穷递归,类似无限循环,无法终止。 - 迭代求和 (每种递归方法都可以由循环迭代替换。)
sum = 0;
for (int number = 1; number <= num; number++)
sum += number;
- 直接递归:方法调用自己的递归
- 间接递归:一个方法调用其他方法,最终导致调用自己。
教材学习中的问题和解决过程
- 问题一:书上I/O异常中写到
一个数据储存(如文件)可以作为一个程序的输入流或输出流,但一般不能同时既是输入流又是输出流。
我理解的是输入流和输出流就是写入文件和读取文件信息,在代码例子中,同一个文件就是可以存入数据并输出的,所以感觉有点矛盾。
- 问题一解决:我觉得是我对输入流和输出流的理解有误,书上的定义是
将流作为输入流时,可以从输入流读信息;作为输出流时,可以将信息写入输出流。
不是很理解,但找到了通俗易懂的解释:如何理解输入流与输出流概念其中写到:
java io流按照java io流的方向可以分为输入流和输出流输入流是将资源数据读入到缓冲Buffer中,输出流是将缓冲Buffer中的数据按照指定格式写出到一个指定的位置,所以这两个流一般同时使用,才有意义。例如你要做文件的上传,你要先用输入流将待上传文件读入缓冲,然后用输出流将文件写出到网络服务器的一个位置,则上传成功;若是文件下载,则先获得输入流,来读取网络服务器中的一个文件,然后用输出流写到本地的一个文件中。
所以简单来说,输入流就是读文件,输出流就是写文件。输入流和输出流不能同时操作一个文件。
-
问题二:汉诺塔用递归方法实现的理解。
-
问题二解决:将N-1个圆盘移到空闲的塔座上,在将最大的圆盘移到目的地,然后再将N-1个圆盘从当前位置移到目的地。这种方法具有内在的递归性,因为每次处理剩下的N-1个圆盘都遵从同样的处理过程。
-
问题三:课本例11.2中有
code.substring(3,7)
,没有用过substring方法,不理解。 -
问题三解决:在查看了API文档后得知第一种情况是返回一串字符的指定开始处到结尾的字符串;第二种情况是字符串的开头和结尾的索引值都可以指定,返回某一段字符串。
代码调试中的问题和解决过程
-
问题一:在做PP11.1时,由于要在没有“DONE”的情况下,用户可以一直输入,但我写的不能一直输入,会在没有输入DONE的情况下自动终止。
-
问题一解决:在用户第一次输入之后,在循环中,我定义的用户输入的变量是与第一次输入不同的,如图,这样就不能循环了,所以要把后几次输入的也改为变量a,执行完一次while循环后可以再次执行,在对while循环作出修改之后,就可以实现了。
while (!(a.equalsIgnoreCase("DONE"))) { System.out.println("请继续输入字符输入完毕则输入“DONE”:\n"); a = scan.nextLine(); StringTooLongException xxx = new StringTooLongException(a); if (a.length() > 20) throw xxx; }
-
问题二:在做PP11.2时,为了添加try-catch语句,便在从用户输入的第二次开始进入循环,在循环中添加try-catch,但在运行时发现了疏漏的地方,如果第一次就输入超过20个字符,并不会提示错误。
-
问题二解决:在修改时,我想着只要在第一次输入时也加上try- catch语句就行了,但却造成了如果第一次输入不符合,则程序终止,因为没有a提供给循环,所以必须把所有用户输入的地方都放在循环里,从第一次输入就进入循环,使用try- catch语句处理,就想到了定义一个空字符串来开始循环,在用户输入值后这个字符串也随之改变,即可实现。
-
问题三:PP12.1做完后测试,发现radar判断无误,而fywwyf判断出错。
-
问题三解决:在判断语句中,开始认为只要判断一个字符和多个字符两种情况即可,在多个字符递归判断,就可以检索完毕。但在出错之后,想到如果前侧到fywwyf中的ww时,判断两者相等之后,再次返回的equals方法为str.substring(1, str.length() - 1),即为0,所以要加上判断只有两个字符时的情况,这样想像fywwyf这样的偶数对称和radar这样的奇数对称都可以判断正确。
-
问题四:在创建文件时并进行文件的读写时,查看文件中的数据总是一个正方形的框。
-
问题四解决:当时查看自己的代码,没有发现什么明显的错误,在老师同学的帮助下,我正确修改并知道了错误的原因。就是我使用的方法FileInputStream和FileOutputStream,这就将byte型数组写入文件输入流中,而我输入的是String型的数据,所以要用输入字符型的方法,改为
Writer fileWriter1 = new FileWriter(file);
和Reader fileReader1 = new FileReader(file);
、BufferedReader buff = new BufferedReader(fileReader1);
即可。
字符: 人们使用的记号,抽象意义上的一个符号。 '1', '中', 'a', '$', '¥', ……
字节: 计算机中存储数据的单元,一个8位的二进制数,是一个很具体的存储空间。 0x01, 0x45, 0xFA, ……
![](https://images2018.cnblogs.com/blog/1333122/201805/1333122-20180513220428785-1567539505.png)
![](https://images2018.cnblogs.com/blog/1333122/201805/1333122-20180513220438751-752383535.png)
![](https://images2018.cnblogs.com/blog/1333122/201805/1333122-20180513220446461-1842721195.png)
![](https://images2018.cnblogs.com/blog/1333122/201805/1333122-20180513220507568-950309118.png)
代码托管
上周考试错题总结
-
错题一:
-
错题一解析:BufferedReader对象必须与Reader对象一起构造。System.in取而代之的是一个输入流对象。为了使用上面的定义,BufferedReader构造器中的对象必须被更改为(new InputStreamReader(System.in))。
BufferedReader keyboard = new BufferedReader(new InputStreamReader(System.in));
在API文档中也有说明
-
错题二:
-
错题二解析:当时做的时候很粗略,不知道D项确切的解释,就随便选了,看了解析之后,知道了异常出现时,可以选择忽略异常,也可以通过try-catch处理或者将异常传播到可以处理的另一种方法,但是是不会抛出一个异常类的。
结对及互评
点评:
-
博客中值得学习的或问题:
* 王禹涵的博客问题记录非常详细,很认真。
* 谭鑫的博客对于问题的描述很细致,解决问题的过程也有记录,很好。 -
基于评分标准,我给谭鑫的博客打分:12分。得分情况如下:
- 进度条中记录学习时间与改进情况的加1分
- 代码Commit Message规范的加1分
- 错题学习深入的加1分
- 结对学习情况真实可信的加1分
- 问题加分8分
- 基于评分标准,我给王禹涵的博客打分:12分。得分情况如下:
- 排版精美的加一分
- 有动手写新代码的加1分
- 代码Commit Message规范的加1分
- 错题学习深入的加1分
- 结对学习情况真实可信的加1分
- 问题加分7分
点评过的同学博客和代码
- 本周结对学习情况
- 结对学习内容
教材第11和12章- 阅读11.1-11.6、12.1-12.3章节
- 代码托管到git@OSC,参考一下使用开源中国托管代码
- 完成课后自测题,并参考答案学习
- 完成课后练习题
- 完成程序设计项目:至少完成PP11.1、PP11.2、PP12.1、PP12.9
其他
这周课本内容不算很难,但是不太容易想到,有关I/O方面的理解还不是很透彻。
学习进度条
代码行数(新增/累积) | 博客量(新增/累积) | 学习时间(新增/累积) | |
---|---|---|---|
目标 | 5000行 | 30篇 | 400小时 |
第一周 | 93/93 | 1/1 | 20/20 |
第二周 | 305/398 | 1/2 | 20/38 |
第三周 | 328/651 | 2/4 | 25/60 |
第四周 | 1013/1689 | 1/5 | 30/90 |
第五周 | 795/2407 | 1/6 | 30/120 |
第六周 | 1117/2921 | 1/7 | 30/150 |
第七周 | 703/3511 | 1/8 | 40/190 |
第八周 | 1139/4701 | 2/10 | 40/230 |
| 第九周 | 681/5382 | 2/12 | 40/270 |