20172302 《程序設計與數據結構》第九周學習總結

<hr/> 2018年學習總結博客總目錄:[第一週](http://www.cnblogs.com/hzy0628/p/8539037.html) [第二週](http://www.cnblogs.com/hzy0628/p/8584976.html) [第三週](http://www.cnblogs.com/hzy0628/p/8642935.html) [第四周](http://www.cnblogs.com/hzy0628/p/8671888.html) [第五週](http://www.cnblogs.com/hzy0628/p/8746606.html) [第六週](http://www.cnblogs.com/hzy0628/p/8830819.html) [第七週](http://www.cnblogs.com/hzy0628/p/8870071.html) [第八週](http://www.cnblogs.com/hzy0628/p/8940111.html) [第九周](http://www.cnblogs.com/hzy0628/p/9027708.html) <hr/>html

教材學習內容總結

第11章 異常

1.一個異常是指一個定義非正常狀況或錯誤的對象,由程序或運行時環境拋出,能夠根據須要進行相應的捕獲和處理。而錯誤相似於異常,可是錯誤表明不可恢復的問題而且必須捕獲處理。java

2.一個異常確實表明了一個錯誤,可是異常只是表明了一種意外的狀況,即一種在正常條件下不會發生的狀況,異常處理提供了一種處理異常的有效方式。git

3.程序設計中異常處理有如下三種選擇: · 根本不處理異常 · 當異常發生時處理異常 · 在程序某個位置集中處理異常程序員

4.對於未進行捕獲的異常,當異常發生時,程序會當即結束執行,並輸出與異常有關的信息,第一行輸出信息代表拋出異常類型及緣由,其餘行爲方法調用堆棧蹤影信息(call stack trace),指明異常發生位置。其中第一個蹤影行指出發生異常的方法、文件、代碼行號,如有其餘行,則指出調用異常方法的其餘方法。算法

5.try-catch語句:用於定義如何處理一種指定的異常。try語句塊能夠有多個相關聯的catch子句,每一個catch子句稱爲一個異常處理器。執行try語句塊中語句,若沒有拋出異常,將繼續執行try語句後語句,若是其中某處發生了異常,並存在該catch子句,則當即轉移到相應的catch子句處理異常,執行之後再轉移到整個try-catch語句後的語句繼續執行。一個try-catch語句能夠有一個可選的finally子句,用於定於一段不管是否有異常發生都將執行的代碼語句。編程

6.異常的傳遞:若是一個異常的發生處沒有捕獲和處理該異常,則該異常將會傳遞給上級調用方法(外層調用),異常也能夠在外層調用中使用try-catch語句塊進行處理和解決。數組

7.異常的層次結構:Throwable是Error類和Exception類的父類,許多類型的異常類都由Exception類派生。自定義異常:可由Exception類或它的後代派生一個新類來定義的一個新的異常。 數據結構

8.可檢測異常和不可檢測異常ide

  • 可檢測異常必須由方法進行捕獲,或者必須在可能拋出或傳遞異常方法的throws子句中列出來。在方法頭中追加一條throws子句,就明確承諾了該方法在異常發生時將拋出或傳遞異常。對於可檢測異常,若是發生該異常的方法不捕獲和處理這個異常,則必須在該方法定義的聲明頭中包含throws子句。函數

  • 不可檢測異常是RuntimeException類的對象或該類的後代類對象,其餘異常均爲可檢測異常。

第12章 遞歸

1.遞歸是一種編程技術,容許一個方法調用本身以達到最終的目的,遞歸是一種以自身定義自身的過程。

2.列表的定義包含了非遞歸定義和遞歸定義兩部分,非遞歸定義又稱做基本狀況。若是隻有遞歸的那部分,則遞歸將會永無終止,這種狀況被稱爲無窮遞歸。

3.遞歸編程,遞歸編程利用遞歸思想,一個簡單的例子(求n的階乘)。遞歸方法一定有一條if-else語句,其中一個分支爲檢測基本狀況的值,另外一分支做爲遞歸部分使用。

factorial(n){
	if(n == 1) return 1;
    else return factorial(n-1)*n;
}

4.遞歸與迭代的比較:迭代與遞歸其實均可以解決同一個問題,重點在於哪一個方法更方便,對於有些問題,遞歸可能用起來很精煉簡單,但對於迭代則比較複雜;相反地,有些問題則是使用迭代更爲簡單。

5.直接遞歸與間接遞歸:一個方法調用本身的遞歸,稱爲直接遞歸。若是一個方法調用其餘方法,最終致使再次調用本身,這稱爲間接遞歸。間接遞歸能夠有若干層間接調用的深度,下面是間接遞歸的一個調用過程圖。

6.遞歸的應用:(1)迷宮問題(2)漢諾塔問題

迷宮: 從起始位置(0,0)到終點位置(7,12)搜索 traverse(row,column){ if(出口(7,12)且值爲1)true;3 else { done=traverse(row+1,column) if(!done)traverse(row,column+1) if(!done)traverse(row-1,column) if(!done)traverse(row,column-1) } if(done)(row,column)=7; }

漢諾塔問題:  將最頂上的N-1個圓盤從原始塔座移到附加塔座  將最大的圓盤從原始塔座移到目標塔座  將N-1個圓盤從附加塔座移到目標塔座

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

  • 問題1:首先就是關於堆棧蹤影這裏,主要是作藍墨雲題目時就混淆了,不理解堆棧蹤影的使用和產生。

  • 問題1解決方案:看課本的講解始終就是不能理解,因而看到有書上【例11.3】,就把它敲了一遍,作完以後,理解了藍墨雲的那道題目。

觀察這個,咱們能夠看到它的異常其實最早發生的地方應該是在Level1處,其次是Level2,最後纔是Level3,而後main函數中沒有try語句塊,就會直接拋出異常結束程序運行,而後在堆棧蹤影中能夠看到顯示的從上到下依次是Level三、Level二、Level1的異常,這其實符合棧的入棧和出棧的規則,先放的會在最裏面,也就會後彈出,也就是會顯示在下面。

  • 問題2:關於書上的可檢測異常和不可檢測異常,這裏本身也是不明白,還有throws子句究竟是應該怎麼去使用?

  • 問題2解決方案:這裏是有王志偉同窗分享給個人一些資料,而後結合書上的理解,總的來講,就是可檢測異常方法定義的聲明頭中要追加throws子句,在方法中咱們要添加throw語句,拋出問題。 同時對於可檢測異常,若是發生異常的方法不捕獲和處理這個異常,字必須在該方法中定義的聲明頭中包含throws子句,否則異常將不會進行拋出。 對於不可檢測異常,它只能是RuntimeException類的對象或該類的後代類對象,不須要throws子句和throw語句,對於它的處理有如下的三種方式。 對於咱們自定義的一個異常,目前我使用過的都是可檢測的異常,關於不可檢測的自定義異常尚未使用過。

對未檢查的異常(unchecked exception )的幾種處理方式: 一、捕獲 二、繼續拋出 三、不處理 對檢查的異常(checked exception,除了RuntimeException,其餘的異常都是checked exception )的幾種處理方式: 一、繼續拋出,消極的方法,一直能夠拋到java虛擬機來處理 二、用try...catch捕獲 注意,對於檢查的異常必須處理,或者必須捕獲或者必須拋出。

參考連接:檢查異常和未檢查異常的不一樣之處

  • 問題3:續上面的一個小問題,就是錯誤和異常究竟是有什麼區別?

  • 問題3解決方案:這裏找了一份資料,再也不重複了,見下。

1).java.lang.Error: Throwable的子類,用於標記嚴重錯誤。合理的應用程序不該該去try/catch這種錯誤。絕大多數的錯誤都是非正常的,就根本不應出現的。 java.lang.Exception: Throwable的子類,用於指示一種合理的程序想去catch的條件。即它僅僅是一種程序運行條件,而非嚴重錯誤,而且鼓勵用戶程序去catch它。 2).Error和RuntimeException 及其子類都是未檢查的異常(unchecked exceptions),而全部其餘的Exception類都是檢查了的異常(checked exceptions). checked exceptions: 一般是從一個能夠恢復的程序中拋出來的,而且最好可以從這種異常中使用程序恢復。好比FileNotFoundException, ParseException等。檢查了的異常發生在編譯階段,必需要使用try…catch(或者throws)不然編譯不經過。 unchecked exceptions: 一般是若是一切正常的話本不應發生的異常,可是的確發生了。發生在運行期,具備不肯定性,主要是因爲程序的邏輯問題所引發的。好比ArrayIndexOutOfBoundException, ClassCastException等。從語言自己的角度講,程序不應去catch這類異常,雖然可以從諸如RuntimeException這樣的異常中catch並恢復,可是並不鼓勵終端程序員這麼作,由於徹底沒要必要。由於這類錯誤自己就是bug,應該被修復,出現此類錯誤時程序就應該當即中止執行。 所以,面對Errors和unchecked exceptions應該讓程序自動終止執行,程序員不應作諸如try/catch這樣的事情,而是應該查明緣由,修改代碼邏輯。 RuntimeException:RuntimeException體系包括錯誤的類型轉換、數組越界訪問和試圖訪問空指針等等。 處理RuntimeException的原則是:若是出現 RuntimeException,那麼必定是程序員的錯誤。例如,能夠經過檢查數組下標和數組邊界來避免數組越界訪問異常。其餘(IOException等等)checked異常通常是外部錯誤,例如試圖從文件尾後讀取數據等,這並非程序自己的錯誤,而是在應用環境中出現的外部錯誤。

參考連接:Java----異常類(錯誤和異常,二者區別)

  • 問題4:遞歸和迭代具體應該怎麼去區分使用,二者具體的分別在哪些方面,哪些問題使用哪一種更加方便?

  • 問題4解決方案:這裏也是在找資料,從網上找的認爲比較好的一份是這樣,作成了一個表:

這個會幫助了個人理解,可是還不太明白的地方是「迭代不容易理解」,但如今給個人感受是遞歸好像是不容易理解吧,可能後面的迭代會比較複雜不容易理解吧,還看了這麼一個答案:

電影故事例證: 迭代——《明日邊緣》 遞歸——《盜夢空間》

參考連接:深究遞歸和迭代的區別、聯繫、優缺點及實例對比

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

  • 問題1:編程項目PP12.1,這裏要對PalindromeTester程序改成遞歸版本,以前的這個程序忘了,又從新看,從新找思路,方向有了之後仍是有一些問題,見圖。 先是這樣,沒有輸出,什麼都沒有。

而後又是這樣,拋出異常:

  • 問題1解決方案:一開始看遞歸,比較亂一些,這個題目一開始有的思路就是從兩端來開始讀取,讀取第一個字符和最後一個字符,進行比較,再使用String類的substring方法將去掉首和尾字符的字符串進行遞歸,這樣就能夠完成程序編寫。但一直卡着的地方是到底要它怎麼才能結束遞歸,也就是基本狀況怎麼設置,這裏想不明白,就致使了第一次的無輸出,而後又在草稿紙上從新想了一遍整個程序設計的過程(這個步驟在一開始沒有作,由於感受很複雜,就想在過程遇到了再去從新想),這樣就浪費了一些時間,但其實也以爲一開始作整個程序設計又不知道從哪入手。完成以後,再次運行,出現了第二個問題:拋出異常。選擇了三個字符最簡單的就進入了Debug調試。

能夠看到這裏比較到最後,right表明字符串的最後的索引值,right成了-1,這裏也就是存在問題的地方,由於我一開始設置的條件是當left>right時程序會進入基本狀況,這裏就是有問題,當他們兩個值相等時就應該進入基本狀況,而不是再去進入遞歸,這樣修改一下,就完成了這個方法的編寫,這個方法最後的代碼見下:

public static boolean palindrometest(String obj) {
        int left = 0;
        int right = obj.length() - 1;
        boolean done = true;
        if (!done || left >=right) { }
        else{
            if (obj.charAt(left) == obj.charAt(right)&&left<right) {
                obj = obj.substring(1, obj.length() - 1);
                palindrometest(obj);
            }
            else
                if(left<right)
                    done = false;
             }
       return done;
    }
}

最後又對是迴文的奇數個字符的、是迴文的偶數個字符的和不是迴文的進行了一次測試:

  • 問題2:由於對遞歸的不太熟練,作PP12.9時也遇到了一點小問題,這裏也是算是半猜着作完了,具體問題見下面:

  • 問題2解決方案:我要輸出那個三角形的第5行時,輸出結果與書上的不一致,後來又把本身的代碼從新看了一遍,找到了問題,是一開始相加的那個每行的第一個和最後一個數爲1這裏給漏掉了,加上這個語句後就能夠正常輸出了,這是加在遞歸部分中循環以前的地方pascal[0] = 1; pascal[n-1] = 1;。而後結果以下:

其中註釋的部分一開始是有的,但後來又想到這個好像能夠不加,我就把它改爲了註釋,試着運行了一下,發現也能夠,就知道了以前的考慮是多餘的,在循環以前放上那條語句就已經包含了後面我所考慮的部分,就是想多了,就把那一部分刪掉了。後又發現代碼多餘:

這裏n=2時實際上是能夠記作遞歸狀況中的,基本狀況是能夠簡寫的,就把那部分註釋掉,運行以後也是正常的,不少時候本身考慮的不清楚,每每就會代碼寫的很複雜,本身讀起來都很吃力,要有一個完整的規劃寫起來纔會簡單並且高效。

  • 後補:後詢問餘坤澎同窗,這道題目要輸出的是整個三角形,而非單行,就又弄了很久,經過一個二維數組,寫了好些代碼,實現了該功能,程序運行截圖:

代碼託管

上週考試錯題總結

  • 1.An exception can produce a "call stack trace" which lists A . the active methods in the order that they were invoked <font color=#0000CD >B . the active methods in the opposite order that they were invoked</font> C . the values of all instance data of the object where the exception was raised D . the values of all instance data of the object where the exception was raised and all local variables and parameters of the method where the exception was raised E . the name of the exception thrown

  • 解析:堆棧蹤影的顯示其實也相似於咱們所學的棧的顯示,最後調用的方法將會放於棧頂,也就會是先打印出來,最早調用的將會在最後打印在屏幕上,這也就是原來調用順序的反序。堆棧跟蹤提供了儲存在運行時堆棧中的方法的名稱,方法名稱在堆棧中以相反的順序放置,也就是說,最先的方法是先放在這裏,下一個方法其次,等等,因此最近調用的方法是在堆棧上最後一項,這是第一個。堆棧跟蹤而後以相反的順序顯示全部活動的方法。

  • 2.An exception that could also arise in the try statement that does not have an associated catch statement is A . ClassNotFoundException B . IllegalArgumentException C . NegativeArraySizeException <font color=#0000CD >D . NullPointException</font> E . OutOfMemoryException

  • 解析:若是數組尚未被實例化,那麼可能就會拋出NullPointerException。ClassNotFoundException、IllegalArgumentException和OutOfMemoryException將不會被拋出,由於try語句中沒有任何代碼,它們要麼引用某個未知的類,要麼使用一個參數,要麼處理新內存的生成。只有當實例化一個數組時,纔有可能會出現NegativeArraySizeException。

  • 3.The idea that an object can exist separate from the executing program that creates it is called A . transience B . static <font color=#0000CD >C . persistence</font> D . serialization E . finality

  • 解析:對象存儲在內存中,當垃圾收集器再也不被引用時,它們會被垃圾收集器回收。當Java程序終止時,沒有引用對象,所以全部對象都被回收。然而,爲了未來的使用,可以保存任何給定的對象是可取的。這種特性稱爲persistence,它的功能是將對象的實例數據保存到文件中。這能夠經過將每一個實例數據寫入數據文件來完成,可是使用對象序列化簡化了。

  • 4.Character streams manage A . byte-sized data B . binary data <font color=#0000CD >C . Unicode characters</font> D . ASCII characters E . compressed data

  • 解析:字符流用於管理16位Unicode字符。這與用於管理任何字節大小數據的字節流不一樣,包括ASCII字符和其餘類型的二進制數據。

Java中的字符流處理的最基本的單元是Unicode碼元(大小2字節),它一般用來處理文本數據。所謂Unicode碼元,也就是一個Unicode代碼單元,範圍是0x0000~0xFFFF。在以上範圍內的每一個數字都與一個字符相對應,Java中的String類型默認就把字符以Unicode規則編碼然後存儲在內存中。然而與存儲在內存中不一樣,存儲在磁盤上的數據一般有着各類各樣的編碼方式。使用不一樣的編碼方式,相同的字符會有不一樣的二進制表示。

  • 5.The term "exception propagation" means A . an exception is caught by the first catch clause B . an exception not caught by the first catch clause is caught by an outer (enclosing) catch clause C . exceptions are caught, sequentially, by catch clauses in the current try block D . exceptions always are caught by the outermost try block <font color=#0000CD >E . none of the above</font>

  • 解析:異常傳遞意味着一個異常被匹配的catch子句在當前try塊級別,若是沒有匹配,而後在下一個封閉try塊級別,依次進行,直到異常已經被匹配的try語句或異常的main函數和被Java虛擬機捕獲。

  • 6.Assume infile is a BufferedReader for a textfile and that the textfile is empty. What is returned from the message infile.readLine( ); ? A . 0 <font color=#0000CD >B . null</font> C . a special character known as the End-of-file marker (EOF) D . none of the above, the message causes a NullPointerException to be thrown E . none of the above, the message causes a EndOfFileException to be thrown

  • 解析:readLine()方法返回一個字符串,等於文件中的下一個文本項。若是文件爲空文件的,則返回null。

  • 7.A method that uses the Scanner class to obtain input does not require either catching or throwing an IOException. This is because A . the Scanner class does not call upon any classes that throw checked exceptions <font color=#0000CD >B . the Scanner class' methods call input methods in try statements and catch IOExceptions so that they are handled directly in the Scanner class</font> C . the Scanner class uses JOptionPane dialog boxes instead of java.io classes so that it does not have to deal with IOExceptions D . the Scanner class overrides the class IOException making it an unchecked exception E . none of the above, methods do require handling IOException even if thrown by a method in a Scanner class

  • 解析:經過擁有本身的catch(IOException.)catch語句,Scanner類中的任何代碼都會被本身所捕獲,這樣一來,可使用本身的異常處理,而不用處理這個可檢測異常。

  • 8.PrintWriter is a better output stream class that PrintStream because PrintWriter A . has both print and println methods and PrintStream only has print B . can output both byte and character streams and PrintStream can only output byte streams <font color=#0000CD >C . has error checking mechanisms as part of the class and PrintStream does not</font> D . will not throw checked exceptions and PrintStream will E . all of the above

  • 解析:PrintWriter類是一個Writer類,而PrintStream類是一個流類。主要的區別在於PrintWriter類是專門爲文件讀寫而設計的,所以PrintWriter類有錯誤檢查機制,而PrintStream則沒有這個錯誤的檢查機制。

  • 9.Which statement is true about BufferedWriters <font color=#0000CD >A . BufferedWriters are used because they improve runtime efficiency</font> B . BufferedWriters are used because they improve compile time efficiency C . BufferedWriters can be used with input streams as well as with output streams D . using a BufferedWriter obviates the necessity for catching IOExceptions E . none of the above

  • 解析:做爲提升程序執行效率的一種方法,BufferedWriters類容許累積輸出,直到緩衝區達到滿值,再去啓動輸出操做變得「有價值」,能夠減小輸出的次數,提升程序執行效率。

結對及互評

  • 本週結對學習狀況
    • 20172308

    • 博客中值得學習的或問題: 代碼中遇到的問題記錄的很是詳細,並且這周也在向他學習着圖片中使用紅框標明錯誤出現地方,這裏看起來很快可以抓到重點,不足的地方在於書上內容的總結仍是不夠詳細。

    • 結對學習內容:繼續共同窗習四則運算的編寫。

點評過的同窗博客和代碼

其餘(感悟、思考等)

感悟

  • 本週學習了異常和遞歸兩章內容,忽然發現這本書就剩下一章了,學的速度好快,再往回想,感受好多東西都還掌握的並不那麼牢靠,仍然須要去練習實踐。本週我以爲頗有意思的內容是那個漢諾塔問題,高中時數學老師提過這個題目,沒想到它是遞歸編程中經典的遞歸算法實例,這個頗有意思,可是對於代碼就沒那麼有意思了,看着看着就睡了,課下看了兩遍纔算是有些明白。還有就是本週編寫的代碼行數比較少一些,編程過程當中遇到的問題並很少,還算順利。

學習進度條

代碼行數(新增/累積) 博客量(新增/累積) 學習時間(新增/累積) 重要成長
目標 5000行 30篇 400小時
第一週 157/157 1/1 15/15
第二週 382/539 1/2 16/31
第三週 317/856 2/4 15/46
第四周 996/1852 1/5 24/70
第五週 578/2330 1/6 16/86 這周對上週第七章的學習有了更深的理解
第六週 475/2805 1/7 14/100 學習了數組方面的相關知識
第七週 629/3434 1/8 14/114 關於繼承有必定認識
第八週 1567/5001 3/11 25/141
第九周 428/5429 2/13 17/158 瞭解了遞歸內容並學習了IO流相關知識

參考資料

相關文章
相關標籤/搜索