
馬俊昌
寫一本關於編程的書,是我大概15年前就有的一個想法,當時,我體會到了編程中數據結構的美妙和神奇,有一種收穫的喜悅和分享的衝動。這種收穫是我反覆閱讀教程十幾遍,花大量時間上機練習調試得到的,這是一個比較痛苦的過程。我想,如果把我學到的知識更爲清晰易懂地表達出來,其他人不就可以掌握編程容易一些,並體會到那種喜悅了嗎?不過,當時感覺自己學識太淺,要學習的東西太多,想一想也就算了。
看這本書是因爲想在校招入職之前好好學下 Java,粗略過了一遍後發現 ROI 實在是太低,大部分內容其實和 Go 差不多,但 Java 獨特的部分講的卻一般,需要自己下來重新找別的資料學習。但也花了好幾個小時看完,還是整理下。 ## 編程基礎與二進制 - switch 語句在分支較多時會使用跳錶,類似二分,時間複雜度更低。 - 三個點作爲可變長度參數,類似 Go 中的語法糖。 - 計算機系統主要使用棧來存放函數調用過程中需要的數據,包括參數、返回地址,以及函數內定義的局部變量。 ## 面向對象 - 棧存放函數的局部變量,而堆存放動態分配的對象,還有一個內存區,存放類的信息,這個區在 Java 中稱爲方法區。 - 使用默認方法就可以在超多實現類的情況下給接口新增方法。 - 受檢異常和未受檢異常區別就是 Java 的對待方式,受檢異常必須進行處理。同時父類是 RuntimeException 則是未受檢異常,父類是 Exception 是受檢異常。 - try 或 catch 中的 return 語句會在 finally 執行結束後才執行,同時 finally 中並不能修改返回值。避免在 finally 中使用 return 或拋出異常。 - hashCode 和 equals 方法聯繫密切,對兩個對象,如果 equals 方法返回 true,則 hashCode 也必須一樣。反之不要求 。 - String 類中提供了很多看似修改的方法,其實是通過創建新的 String 對象來實現的,原來的 String 對象不會被修改。 ## 泛型與容器 - Java 泛型底層就是 Object 強轉。 - 泛型就是類型參數化,處理的數據類型不是固定的,而是可以作爲參數傳入。 - 通配符形式能做的類型參數形式都可以做,只是更簡單,可讀性更好。 - 在迭代過程中若想進行結構性變化則使用迭代器提供的方法,每次發生結構性變化的時候 modCount 都會增加,而每次迭代器操作的時候都會檢查 expectedModCount 是否與 modCount 相同,這樣就能檢測出結構性變化。 - Java 8 對 HashMap 的實現進行了優化,在哈希衝突比較嚴重的情況下,即大量元素映射到同一個鏈表的情況下(具體是至少 8 個元素,且總的鍵值對個數至少是 64),Java 8 會將該鏈表轉換爲一個平衡的排序二叉樹 (紅黑樹)。 - HashSet 內部就是一個 HashMap。 - TreeMap 使用紅黑樹實現,實現了去重和有序。 - 一個配置文件有一些鍵值對形式的配置項,但其中有一些鍵是重複的,希望保留最後一個值,但還是按原來的鍵順序輸出, LinkedHashMap 就是一個合適的數據結構。它可以保持插入順序或訪問順序。 ## 文件 - 一般讀寫文件需要兩次數據複製,比如讀文件,需要先從硬盤複製到操作系統內核,再從內核複製到應用程序分配的內存中。操作系統運行所在的環境和應用程序是不一樣的,操作系統所在的環境是內核態,應用程序是用戶態,應用程序調用操作系統的功能,需要兩次環境的切換,先從用戶態切到內核態,再從內核態切到用戶態。這種用戶態/內核態的切換是有開銷的,應儘量減少這種切換。 ## 併發 - 在 Java 中創建線程有兩種方式:一種是繼承 Thread;另外一種是實現 Runnable 接口。 - synchronized 實例方法實際保護的是同一個對象的方法調用,確保同時只能有一個線程執行 - 若只是保證內存可見性可以使用 volatile,更輕量級。 - ABA 是不是一個問題與程序的邏輯有關,一般不是問題。而如果確實有問題,解決方法是使用 AtomicStampedReference,在修改值的同時附加一個時間戳,只有值和時間戳都相同才進行修改。 - 關於 ThreadLocal,簡單總結來說:1)ThreadLocal 使得每個線程對同一個變量有自己的獨立副本,是實現線程安全、減少競爭的一種方案。2)ThreadLocal 經常用於存儲上下文信息,避免在不同代碼間來回傳遞,簡化代碼。3)每個線程都有一個 Map,調用 ThreadLocal 對象的 get/set 實際就是以 ThreadLocal 對象爲鍵讀寫當前線程的該 Map。 - ConcurrentHashMap 採用分段鎖技術,將數據分爲多個段,而每個段有一個獨立的鎖,每一個段相當於一個獨立的哈希表,分段的依據也是哈希值,無論是保存鍵值對還是根據鍵查找,都先根據鍵的哈希值映射到段,再在段對應的哈希表上進行操作。採用分段鎖,可以大大提高併發度,多個段之間可以並行讀寫。看這本書是因爲想在校招入職之前好好學下 Java,粗略過了一遍後發現 ROI 實在是太低,大部分內容其實和 Go 差不多,但 Java 獨特的部分講的卻一般,需要自己下來重新找別的資料學習。但也花了好幾個小時看完,還是整理下。 ## 編程基礎與二進制 - switch 語句在分支較多時會使用跳錶,類似二分,時間複雜度更低。 - 三個點作爲可變長度參數,類似 Go 中的語法糖。 - 計算機系統主要使用棧來存放函數調用過程中需要的數據,包括參數、返回地址,以及函數內定義的局部變量。 ## 面向對象 - 棧存放函數的局部變量,而堆存放動態分配的對象,還有一個內存區,存放類的信息,這個區在 Java 中稱爲方法區。 - 使用默認方法就可以在超多實現類的情況下給接口新增方法。 - 受檢異常和未受檢異常區別就是 Java 的對待方式,受檢異常必須進行處理。同時父類是 RuntimeException 則是未受檢異常,父類是 Exception 是受檢異常。 - try 或 catch 中的 return 語句會在 finally 執行結束後才執行,同時 finally 中並不能修改返回值。避免在 finally 中使用 return 或拋出異常。 - hashCode 和 equals 方法聯繫密切,對兩個對象,如果 equals 方法返回 true,則 hashCode 也必須一樣。反之不要求 。 - String 類中提供了很多看似修改的方法,其實是通過創建新的 String 對象來實現的,原來的 String 對象不會被修改。 ## 泛型與容器 - Java 泛型底層就是 Object 強轉。 - 泛型就是類型參數化,處理的數據類型不是固定的,而是可以作爲參數傳入。 - 通配符形式能做的類型參數形式都可以做,只是更簡單,可讀性更好。 - 在迭代過程中若想進行結構性變化則使用迭代器提供的方法,每次發生結構性變化的時候 modCount 都會增加,而每次迭代器操作的時候都會檢查 expectedModCount 是否與 modCount 相同,這樣就能檢測出結構性變化。 - Java 8 對 HashMap 的實現進行了優化,在哈希衝突比較嚴重的情況下,即大量元素映射到同一個鏈表的情況下(具體是至少 8 個元素,且總的鍵值對個數至少是 64),Java 8 會將該鏈表轉換爲一個平衡的排序二叉樹 (紅黑樹)。 - HashSet 內部就是一個 HashMap。 - TreeMap 使用紅黑樹實現,實現了去重和有序。 - 一個配置文件有一些鍵值對形式的配置項,但其中有一些鍵是重複的,希望保留最後一個值,但還是按原來的鍵順序輸出, LinkedHashMap 就是一個合適的數據結構。它可以保持插入順序或訪問順序。 ## 文件 - 一般讀寫文件需要兩次數據複製,比如讀文件,需要先從硬盤複製到操作系統內核,再從內核複製到應用程序分配的內存中。操作系統運行所在的環境和應用程序是不一樣的,操作系統所在的環境是內核態,應用程序是用戶態,應用程序調用操作系統的功能,需要兩次環境的切換,先從用戶態切到內核態,再從內核態切到用戶態。這種用戶態/內核態的切換是有開銷的,應儘量減少這種切換。 ## 併發 - 在 Java 中創建線程有兩種方式:一種是繼承 Thread;另外一種是實現 Runnable 接口。 - synchronized 實例方法實際保護的是同一個對象的方法調用,確保同時只能有一個線程執行 - 若只是保證內存可見性可以使用 volatile,更輕量級。 - ABA 是不是一個問題與程序的邏輯有關,一般不是問題。而如果確實有問題,解決方法是使用 AtomicStampedReference,在修改值的同時附加一個時間戳,只有值和時間戳都相同才進行修改。 - 關於 ThreadLocal,簡單總結來說:1)ThreadLocal 使得每個線程對同一個變量有自己的獨立副本,是實現線程安全、減少競爭的一種方案。2)ThreadLocal 經常用於存儲上下文信息,避免在不同代碼間來回傳遞,簡化代碼。3)每個線程都有一個 Map,調用 ThreadLocal 對象的 get/set 實際就是以 ThreadLocal 對象爲鍵讀寫當前線程的該 Map。 - ConcurrentHashMap 採用分段鎖技術,將數據分爲多個段,而每個段有一個獨立的鎖,每一個段相當於一個獨立的哈希表,分段的依據也是哈希值,無論是保存鍵值對還是根據鍵查找,都先根據鍵的哈希值映射到段,再在段對應的哈希表上進行操作。採用分段鎖,可以大大提高併發度,多個段之間可以並行讀寫。
閱讀速度5000字/分鐘 1、本書主題:Java教學 2、速讀建議:工具書內容大同小異,會有很多重複性知識。已知的部分快速略過,未知的先做個標記。 >> 可汗學院的創始人是薩爾曼·可汗,他自己錄製了3000多個短視頻,主要教中小學生基礎課。他爲每門課程建立了知識地圖,地圖由知識點組成,知識點之間有依賴關係。每個知識點都有一個視頻,每個視頻10分鐘左右,他的講解清晰透徹,極受歡迎。 >> 變量就是給數據起名字,方便找不同的數據,它的值可以變,但含義不應變。 >> 抽象是相對於具體而言的,一般而言,具體類有直接對應的對象,而抽象類沒有,它表達的是抽象概念,一般是具體類的比較上層的父類。比如,狗是具體對象,而動物則是抽象概念;櫻桃是具體對象,而水果則是抽象概念;正方形是具體對象,而圖形則是抽象概念。 >> 多維數組只是一個假象,只有一維數組,只是數組中的每個元素還可以是一個數組,這樣就形成二維數組;如果其中每個元素還都是一個數組,那就是三維數組。
很好的一本書。適合剛工作1-3年的java工程師閱讀 本科就是計算機專業的我,學java其實也有10年了,但是可以說是從入職現在的公司以來,才真正把自己當做一個java工程師。兩年來,雖然也參與了不少項目,甚至有些項目是自己一個人寫的。但寫的大多數都是些業務邏輯,即使如此,也寫的並不優雅整潔。什麼設計模式,反射,泛型等幾乎沒怎麼用過。所以其實對於自己的java是很不自信的。 通過這本書,算是查漏補缺一下,很多地方看的有點心急(也和手機端不方便閱讀大段代碼有關),流於蜻蜓點水了。但是即便如此,還是感覺收穫了很多。比如: 對繼承,接口的理解。字符集的分類與原理。反射,依賴注入容器,lambda表達式的運用等等。
這是一本講java細節不錯的書
這本書對於java的知識點介紹比較詳細,特別適合工作了一段時間或者換工作的同學,查漏補缺、溫故知新,對於初學者來說有點難度。關於容器那些章節介紹的尤爲詳細,結合數據結構與算法、夾雜一點設計模式,個人感覺尤爲精彩。
Java這門語言之所以能夠快速發展,與其豐富的類庫和工具、開發效率、代碼可讀性、安全性、穩健性、可移植性、多線程處理能力有很大關係,選擇了Java,就不必像C/C++那樣經常要重複造輪子,很多框架可供選擇,能夠實現大部分功能,而且這些代碼在不斷優化。《Java編程的邏輯》這本書,不僅僅涉及到Java基礎的部分,還有更加深入的內容。程序就是數據結構+算法,書中對Java的數據結構和算法進行了詳細的介紹,對於常用的功能,作者先是提供一些可行的方案和思路,然後對算法的源碼進行剖析,分析Java底層是怎麼實現這些功能的,爲什麼要這樣實現,怎麼在已有類的基礎上擴展功能。 技術只是工具,更重要的是思想和規則,比如: 1、用更多的時間研究問題本身,然後用更少的步驟去解決問題。 2、自頂向下設計,通用的算法,性能一般不是最優的。 3、複雜的功能,往往可以通過簡單功能的組合或者重複去實現。 4、用時間換取空間或者用空間換取時間。 5、優先使用工具,而不是造輪子。 6、把一個大的問題拆分成一系列小的問題去解決。 要領悟Java的編程邏輯,就要有紮實的基本功,這本書可以作爲Java技術指南來查閱,值得反覆閱讀,反覆學習。
書很爛,寫的像教科書一樣,遠遠不及python從入門到實踐,讀到類的繼承就已經讀不下去了,我還買的是實體書,這本書也就是已經會用java的人用來查缺補漏,或者當工具書的,對於想用這本書入門的人來說實在是差得非常遠,因爲書中永遠沒有涉及現實使用的案例,讀繼承不知道爲什麼要繼承,繼承用來幹啥的,讀父類子類不知道用在哪,和所有的教科書一樣,從定義到解析到例子,上來就是專業術語,不配合解析,1句話裏恨不得塞10個專業名詞,就是不說這個東西平時怎麼用,在現實中爲什麼這麼定義,是出於什麼樣的原因。我是看書看不下去了,專門下了個微信讀書來寫書評的。決定以後不會再買任何編程類的書了,直接從教學視頻開始學就行了,買書是真沒用
讀的有點晚了 應該在工作半年後就讀的 本書適合學完Java 並完成1個項目後閱讀。本書對基礎語法只是複習性的介紹,對Java的基礎庫原理有宏觀的介紹,一步步引導,容易讀懂,有助於以後深入學習Java庫和框架
內容很多,每個點都結合具體代碼講解的很詳細,可以當做一本字典吧,以後哪部分有問題可以翻一翻。
好棒,牆裂推薦,對於知道怎麼做,卻不知道爲什麼要這麼做的程序員,最爲有益