20155227 2016-2017-2 《Java程序设计》第七周学习总结
教材学习内容总结
认识时间与日期
时间的度量
世界时:在1972年引入UTC之前,GMT与UT是相同的。
国际原子时(TAI),秒的单位定义是基于TAI,也就是铯原子辐射振动次数。
世界协调时间(UTC),UTC考虑了地球自转越来越慢而有闰秒修正,确保UTC与UT相差不会超过0.9秒。
就目前来说,即使标注为GMT(无论是文件说明,或者是API的日期时间字符串描述),实际上谈到时间指的是UTC时间。
年历简介
儒略历:修正了罗马历隔三年设置一闰年的错误,改采四年一闰。
格里高利历:改革了儒略历。
ISO 8601标准:采用统一的数据格式。
认识时区
每个地区的标准时间各不相同,涉及到地理、法律、经济、社会、政治等问题。
为了让人们对时间的认知符合作息,因而设置了UTC偏移。
认识Date与Calendar
Date
取得系统时间,方法之一就是使用System.currentTimeMillis()方法
,返回long类型整数,代表1970年1月1日0时0分0秒0毫秒至今经过的毫秒数。Date有两个构造函数可以使用,一个可使用epoch毫秒数构建,另一个为无自变量构造函数,内部亦是使用System.currentTimeMillis()
取得毫秒数,调用getTime()
可取得内部保存的epoch毫秒数值。
DateFormat
DateFormat是个抽象类,其操作类是java.text.SimpleDateFormat
,可以处理字符串时间格式。可以通过DateForm
的各种静态方法进行格式化,使用模式字符串自定义格式,使用parse()
方法将指定的字符串剖析为Date
实例。
Calendar
Date
现在建议作为时间轴上的瞬间代表,要格式化时间日期则通过DateFormat
,如果想要取得某个时间日期信息,或者是对时间日期进行操作,可以使用Calendar
实例。Calendar
是个抽象类,java.util.GregorianCalendar
是其子类,操作了儒略历与格里高利历的混合历,通过Calendar
的getInstance()
取得的Calendar
实例,默认就是取得GregorianCalendar
实例。
设定TimeZone
Calendar时会使用默认时区,可以使用java.util.TimeZone
的getDefault()
来取得默认时区信息。
JDK8新时间日期API
机器时间观点的API
真正可靠的信息只有内含epoch毫秒数
。同时也可以使用Instant的静态方法now()
取得代表Java epoch
毫秒数的Instant
实例。
人类时间观点的API
LocalDateTime只包括时间与日期,LocalDate只有日期,LocalTime只有时间,他们都是对时间的描述,没有时区信息。
如果你的时间日期需要带有时区,LocalDate、LocalTime等来补充缺少的信息。
对时间的运算
-
TemporalAmount:
TemporalAmount
的操作类是Period
和Duration
。ofPattern()
是java.time.format.DateTimeFormatte
r的静态方法,对于年、月、星期、日的日期差使用Period
类定义,plus()
方法可以接受Duration
实例来计算,对于时间计量,类Duration
来定义。 -
TemporalUnit:
plus()
方法另一重载版本接受java.time.temporal.TemporalUnit
实例,java.time.temporal.ChronoUnit
是TemporalUnit
实作类,使用enum
实作,定义了between()
等方法。 -
TemporalAccessor:定义了只读的时间对象读取操作,实际上Temporal是
TemporalAccessor
子接口,增加了对时间的处理操作,像是plus()
、minus()
、with()
等方法。
年历系统设计
JDK8采单一年历系统设计。如果需要其他年历系统,则需要明确实行java.time.chrono
中等操作了java.time.chrono.Chronology
接口的类。
教材学习中的问题和解决过程
- 问题1:书上P432的HowOld程序运行结果如下:
但其实这样计算得到的年龄并不准确,一年的毫秒数并不是如上面例子中那么简单计算的。
- 问题1解决方案:更改后的代码如下:
import java.time.*;
import java.util.Scanner;
import static java.lang.System.out;
public class HowOld2 {
public static void main(String[] args) {
out.print("輸入出生年月日(yyyy-mm-dd):");
LocalDate birth = LocalDate.parse(new Scanner(System.in).nextLine());
LocalDate now = LocalDate.now();
Period period = Period.between(birth, now);
out.printf("你活了 %d 年 %d 月 %d 日%n",
period.getYears(), period.getMonths(), period.getDays());
}
}
运行结果如下:
代码调试中的问题和解决过程
- 问题1:书上435页的代码为什么要调用clone()?
import static java.lang.System.out;
import java.util.Calendar;
public class CalendarUtil {
public static void main(String[] args) {
Calendar birth = Calendar.getInstance();
birth.set(1975, Calendar.MAY, 26);
Calendar now = Calendar.getInstance();
out.printf("岁数:%d%n", yearsBetween(birth, now));
out.printf("天数:%d%n", daysBetween(birth, now));
}
public static long yearsBetween(Calendar begin, Calendar end) {
Calendar calendar = (Calendar) begin.clone();
long years = 0;
while (calendar.before(end)) {
calendar.add(Calendar.YEAR, 1);
years++;
}
return years - 1;
}
public static long daysBetween(Calendar begin, Calendar end) {
Calendar calendar = (Calendar) begin.clone();
long days = 0;
while (calendar.before(end)) {
calendar.add(Calendar.DATE, 1);
days++;
}
return days - 1;
}
}
- 问题1解决方案:
避免调用yearsBetween()、datsBetween()之后传入的Calendar自变量被修改,两个方法都对第一个自变量进行了clone()复制对象的动作。
- 问题2:
教材p436页TimeZoneDemo.java代码结果时区ID显示的是Asia/Shanghai,为什么不是北京呢?
import static java.lang.System.out;
import java.util.TimeZone;
public class TimeZoneDemo {
public static void main(String[] args) {
TimeZone timeZone = TimeZone.getDefault();
out.println(timeZone.getDisplayName());
out.println("\t时区ID:" + timeZone.getID());
out.println("\t日光节约时数:" + timeZone.getDSTSavings());
out.println("\tUTC 偏移毫秒数:" + timeZone.getRawOffset());
}
}
- 问题2解决方案:
Java所支持的所有时区ID里面并没有Asia/Beijing,所以对于*时区的而言,显示的应该都是Asia/Shanghai。
代码托管
(statistics.sh脚本的运行结果截图)
上周考试错题总结
- 错题1
下面哪条命令可以把 f1.txt 复制为 f2.txt ?
A .cp f1.txt f2.txt
B .copy f1.txt f2.txt
C .cat f1.txt > f2.tx
D .cp f1.txt | f2.tx
E .copy f1.txt | f2.tx
正确答案: A C
总结:copy是Windows下的命令。cat f1.txt > f2.tx 通过输出重定向实现了复制。
- 错题2
下面代码*有()个线程?
public class ThreadTest {
public static void main(String args[]){
MyThread myThread =new MyThread();
Thread t1=new Thread(myThread);
Thread t2=new Thread(myThread);
t1.start();
t2.start();
}
}
class MyThread extends Thread {
...
}
A .1
B .2
C .3
D .4
答案:C
错误原因:忘了main所在的主线程。
- 错题3
如果有以下代码段:
Thread thread = new Thread(new ________________() {
public void run() {...}
});
空白部分指定哪些类型可以通过编译?
A .
Runnable
B .
Thread
C .
Future
D .
Executor
答案:AB
总结:查API文档,Thread 也实现了 Runnable 接口
- 错题4:
1. class Calc {
2. public static void main(String [] args) {
3. try {
4. int x = Integer.parselnt ("42a") ;
5. //insert code here
6. System.out.print ("oops");
7. }
8. }
9. }
下面哪行分别插入到第五行,会导致输 "oops" ?
A .
catch (IllegalArgumentException e) {
B .
} catch (IllegalStateException c) {
C .
} catch (NumbelFormatException n) {
D .
} catch (ClassCastException c) {
答案:AC
结对及互评
评分标准
-
正确使用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
点评过的同学博客和代码
-
本周结对学习情况
- 结对同学学号20155213
- 结对照片
- 结对学习内容
-
上周博客互评情况
其他(感悟、思考等,可选)
本周已经是自学java的第七周了,逐渐习惯了这种学习模式,但是通过这周的考试发现了自己学习中的很多问题。不仅仅是对教材基本内容的学习太过于表面,更大的问题是自己思考问题的思维能力不足,所以考试成绩十分糟糕。接下来要做的就是要学会自己总结提高,希望能摆脱现在的状态。
学习进度条
代码行数(新增/累积) | 博客量(新增/累积) | 学习时间(新增/累积) | 重要成长 | |
---|---|---|---|---|
目标 | 5000行 | 30篇 | 400小时 | |
第一周 | 10/10 | 1/1 | 20/20 | |
第二周 | 98/108 | 1/2 | 20/40 | |
第三周 | 401/509 | 1/3 | 15/55 | |
第四周 | 700/1209 | 1/4 | 20/75 | |
第五周 | 632/1841 | 1/5 | 20/95 | 了解Java的异常处理,学习Collection和Map架构 |
第六周 | 1040/2881 | 1/6 | 13/108 | 了解串流设计和线程 |
第七周 | 479/3360 | 2/8 | 15/123 | 了解Date及其相关知识,完成第一次实验 |
尝试一下记录「计划学习时间」和「实际学习时间」,到期末看看能不能改进自己的计划能力。这个工作学习中很重要,也很有用。
耗时估计的公式
:Y=X+X/N ,Y=X-X/N,训练次数多了,X、Y就接近了。
计划学习时间:20小时
实际学习时间:15小时
改进情况:不要仅仅是看书,要多思考。
(有空多看看现代软件工程 课件
软件工程师能力自我评价表)