20155303 2016-2017-2 《Java程序設計》第七周學習總結


20155303 2016-2017-2 《Java程序設計》第七周學習總結

教材學習中的問題和解決過程

  • 『問題一』SimpleDateFormat中每個字符的含義都是什么?

『問題一解決』:API文檔中有詳細的說明:

比如以下程序,我定義的格式是 yyyy-ww-DD ,輸出結果表示當前日期是該年第14周,第97天。

  • 『問題二』:課本P435提到 clone() 復制對象的功能,這屬於創建對象的方式嗎?

『問題二解決』clone() 復制對象與 new 都是創建對象的方式。之前課本上曾介紹過淺層復制(Shallow Copy)與深層復制(Deep Copy),這次借助 clone() 進一步學習。

【復制參考與復制對象】:回顧之前學過的“復制參考”,編寫以下程序:

當執行完Person p1 = p;之后真的創建了一個新對象嗎?我們來看一下打印結果:

可以看到打印的地址值是相同的。也就是說,這一步只實現了引用的復制,也就是p1與p指向了一個相同的對象“Person("Justin", 20150001)”。

clone()能夠實現復制對象,而不僅僅是復制參考。以下面這個程序為例:

打印結果為:

可以看出,clone()重新分配內存,而不是把原對象的地址賦給了一個新的引用變量。

【淺拷貝與深拷貝】:繼續分析上例,ID是基本數據類型,直接將數值拷貝過來就行。但是name是String類型的,它只是一個引用,指向一個真正的String對象,那么對它的拷貝有兩種方式:

①直接將源對象中的name的引用值拷貝給新對象的name字段;

②根據原Person對象中的name指向的字符串對象創建一個新的相同的字符串對象,將這個新字符串對象的引用賦給新拷貝的Person對象的name字段。

這兩種拷貝方式分別叫做淺拷貝和深拷貝。

修改上面的代碼,如果name的地址值相同,說明兩個對象的name都指向同一個String對象,是淺拷貝;如果兩個對象的name的地址值不同,那么就說明指向不同的String對象,也就是在拷貝對象的時候,同時拷貝了name引用的String對象,也就是深拷貝。

運行結果如下:

name的地址值是相同的,所以這種拷貝方式是淺拷貝。

那么如何實現深拷貝呢?我們必須在類中實現Cloneable接口,並且重寫clone方法,創建一個拷貝類的對象,如下程序:

打印結果為:

可以看到,兩個對象的p指向的不是同一個對象,這就是深拷貝。

  • 『問題三』:課本P435提到“想比較兩個Calendar”的時間日期先后,可以使用after()before()方法。那么,這兩個方法具體怎么使用呢?

『問題三解決』:查詢API文檔可知,after()返回值為布爾類型,其等價於compareTo(when)>0,為真返回true,否則返回false。before()同理,等價於compareTo(when)<0

代碼調試中的問題和解決過程

  • 『問題一』:運行課本P432HowOld程序時,忽略了L類型轉換,得到了下面錯誤的結果(433歲!?):

365*24*60*60*1000后面添加Ll得到正確輸出:

『問題一解決』365*24*60*60*1000的計算結果是31536000000,超出了int范圍,在二進制中只保留后32位,為1471228928,因此會出現以上錯誤結果。使用計算器或許能更加清晰地展示出來:

  • 『問題二』:關於System.currentTimeMills()方法的使用問題。

『問題二解決』:查詢API文檔可知,currentTimeMills()返回值代表1970年1月1日0時0分0秒0毫秒至今經過的毫秒數。

考慮到這一點,可以調用該方法計算程序運行時間。以下面這個程序為例,在主線程開始和結束時分別調用currentTimeMills()方法,計算差值即為程序運行時間(單位:毫秒):

需要注意的是,同一程序程序運行時間也有可能不同,這與此時CPU狀態有關,所以此方法只能大致估計程序的運行時間。不過可作為程序優化的一點參考。

代碼托管

上周考試錯題總結

  • 『題目一』

下面哪條命令可以把 f1.txt 復制為 f2.txt ?(AC)

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

『考點』:copy是Windows下的命令。cat f1.txt > f2.tx 通過輸出重定向實現了復制。

  • 『題目二』

Given an instance of a Stream, s, and a Collection, c, which are valid ways of creating a parallel stream? (Choose all that apply.)

給定一個Stream的實例s, 一個Collection的實例c, 下面哪些選項可以創建一個並行流?(DF)

A .new ParallelStream(s)

B .c.parallel()

C .s.parallelStream()

D .c.parallelStream()

E .new ParallelStream(c)

F .s.parallel()

『考點』Parallelstream()方法不存在,“P”不能大寫,所以A和E是不正確的。API中對parallel()的定義為:在Stream類中從現有流創建一個並行流,因此F是正確的,C是錯誤的。API中對parallelstream()的定義為:在Collection類中從一個集合創建一個並行流,因此D是正確的,B是錯誤的。

  • 『題目三』

Which of the following statements about the Callable call() and Runnable run() methods are correct? (Choose all that apply.) (ACDF)(My answer:CD)

A .Both can throw unchecked exceptions.

B .Callable takes a generic method argument.

C .Callable can throw a checked exception.

D .Both can be implemented with lambda expressions.

E .Runnable returns a generic type.

F .Callable returns a generic type.

G .Both methods return void

『考點』:查詢API文檔關於Callable接口的說明可以看到,Callable支持泛型,且CallableRunable都能拋出非受檢異常,而能拋出受檢異常的只有Callable

  • 『題目四』

What are some reasons to use a character stream, such as Reader/Writer, over a byte stream, such as InputStream/OutputStream? (Choose all that apply.)

在下列哪些情況下使用字符流(比如Reader/Writer)而不使用字節流(比如InputStream/OutputStream)?(AC)

A .More convenient code syntax when working with String data

B .Improved performance

C .Automatic character encoding

D .Built-in serialization and deserialization

E .Character streams are high-level streams

F .Multi-threading support

『考點』

A:字符流包含能夠非常便利處理字符串數據的方法,所以A是正確的;C:字符流有其特有的編碼方式,能夠自動處理字符編碼問題,C也是正確的。

其他選項,如B:性能改進,D:內置的序列化和反序列化,E:字符流是更高級的流,F:字符流支持多線程等等,這些說法都是不相關,或是不正確的。

  • 『題目五』

Assuming / is the root directory, which of the following are true statements? (Choose all that apply.)(A)

A ./home/parrot is an absolute path.

B ./home/parrot is a directory.

C ./home/parrot is a relative path.

D .The path pointed to from a File object must exist.

E .The parent of the path pointed to by a File object must exist.

『考點』

根目錄開始的路徑是絕對路徑,所以A是正確的,C是錯誤的。B是不正確的,因為路徑可能是文件系統中的文件(file)或目錄(directory)。文件對象可以指向文件系統中不存在的路徑,所以D和E是錯誤的。

  • 『題目六』

What is the result of executing the following code? (Choose all that apply.)(BDE)

String line;
Console c = System.console();
Writer w = c.writer();
if ((line = c.readLine()) != null)
    w.append(line);
w.flush();

A .The code runs without error but prints nothing.

B .The code prints what was entered by the user.

C .An ArrayIndexOutOfBoundsException might be thrown.

D .A NullPointerException might be thrown.

E .An IOException might be thrown.

F .The code does not compile.

『考點』:這是從控制台讀取一行並將其寫入控制台的正確代碼,B正確;查詢API文檔可知,調用console()方法可能會拋出NullPointerException異常,D正確;調用append()方法可能會拋出IOException異常。

結對及互評

本周結對學習情況

第七周博客互評情況

(稍后更新)

其他(感悟、思考等,可選)

這周的考試再一次給我們敲響警鍾,只看不動手,只讀不思考,都無法真正掌握。比如題中出現了一部分異常處理的知識,如果只靠死記硬背而不查詢API文檔,費時費力還很難達到靈活應用。這周學習任務比較輕松,可以利用這個機會鞏固前面所學知識,夯實基礎。

學習進度條

代碼行數(新增/累積) 博客量(新增/累積) 學習時間(新增/累積) 重要成長
目標 5000行 30篇 400小時
第一周 16/16 1/1 18/18 初步認識了Java
第二周 219/235 1/2 28/46 學習了Java的基本語法知識
第三周 766/1001 1/3 23/69 了解對象與參考的關系,以及封裝的概念與實現
第四周 984/1985 1/4 18/87 學習了繼承與多態的關系,以及接口的多態操作
第五周 866/2851 1/5 12/99 學習了異常處理,學會使用Collection收集對象
第六周 664/3515 1/6 15/114 認識字節流和字符流的繼承架構,學習線程與並行API
第七周 469/3984 1/7 13/127 認識Date與Calender

嘗試一下記錄「計划學習時間」和「實際學習時間」,到期末看看能不能改進自己的計划能力。這個工作學習中很重要,也很有用。
耗時估計的公式
:Y=X+X/N ,Y=X-X/N,訓練次數多了,X、Y就接近了。

參考:軟件工程軟件的估計為什么這么難軟件工程 估計方法

  • 計划學習時間:10小時

  • 實際學習時間:13小時

(有空多看看現代軟件工程課件:軟件工程師能力自我評價表)

參考資料


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM