我從畢業做程式設計師就開始用 Java,到現在已經工作快 20 年了。減去我做手遊用 C++、Lua 的幾年,再減去後來轉管理寫程式碼少的時間,我真正寫 Java 程式碼的時間至少也在 10 年以上。
如果你問我“Java 已經精通了嗎?”,說實話,還是有點心虛。
Java 博大精深,那麼多知識點,肯定有我不懂的。另外,每個人對“精通”都有自己的理解,有人覺得是精於使用,有人覺得是精於底層原理,也有人覺得是精於框架。
但是,畢竟用 Java 十多年了,我可以說說我自己對“精通 Java”的理解。
Java 語言覆蓋的知識很廣泛,但是總的來說,最重要的是以下三個方面:
- Java 基礎知識
- Java 併發程式設計
- JVM 底層知識
所以,所謂精通 Java 語言,可以大致等同於視為上述三個方面的精通。
Java 基礎知識的精通主要體現在,能很順暢的把 Java 的各種基礎資料結構、各種內建物件,都融合到實際的場景中,能以最快的速度、最佳的方案,去解決實際中的工作問題。
比如,大家在專案中,經常是不會區分物件是強引用還是弱引用的,統統都是強引用。如果一個精通 Java 基礎知識的工程師,就會根據實際情況,去靈活地運用強引用、弱引用。
Java 併發程式設計的精通主要體現在,能非常巧妙得把各種多執行緒設計模式以及併發包中的各種工具,去解決各種併發難題。
例如,使用 Future 和相關子類去提升程式的執行效率,用 CountDownLatch 去控制執行緒順序。
對 JVM 底層知識的精通主要體現在,能很快速地通過優化 JVM,去提升專案的效能,也能非常迅速準確地去找到專案出現的底層問題,直接進行根源性的解決。
比如,我們正在寫一個要嵌入到對方專案的一個監控客戶端。這個客戶端就需要保證不能因為它的嵌入,導致被嵌入專案的 CPU、記憶體出現大的耗費。也要保證,在不耗費大資源的情況下,還能快速無誤地傳遞資料。這時候,我們就應該利用自己對 JVM 垃圾回收的深入理解,去搞物件池化。
總之,Java 語言本身的精通,就體現在能利用 Java 去最優的提供技術解決方案,也能創造性的解決各種複雜的技術難題。
下面我們們就分開看看,如何能精通這些知識和技能。
一、精通 Java 基礎知識
要精通 Java 基礎知識,大家可以深度思考一下我對各個知識點提出的幾個問題:
Java 的型別轉換
Java 是一種強型別語言,在程式設計中就離不開各種各樣的型別轉換。
可是大家有沒有想過強制變換的底層細節是什麼?有沒有反過來想過,為什麼 Java 向上轉型是自動的,而向下轉型卻是強制的?
Java 的集合框架
Java 的集合框架用途是如此廣泛,只要你開發個稍微複雜點的專案,就根本避不開要用它。在學習的時候,大家可以想想這麼幾個問題:
- Java 的集合框架中的各種集合的最佳使用場景都是什麼?
- 集合框架中的各種集合的子類實現都是為了解決他們父類的哪些不足的?
- 為什麼在有了 Java 的集合框架後,我們還要使用 Guava 框架?
Java 的陣列
Java 的陣列大家都經常用了,可大家有沒有想過:
- 我們什麼時候使用陣列,什麼時候使用集合?
- Java 的底層是如何對陣列的越界進行檢查的?
- 為什麼 System.arrayCopy 方法會那麼快?
Java 的 String
- 你有沒有仔細看過 String 的程式碼呢?
- 有沒有想過 String 為什麼是不變的呢?
- String 中的哪些方法創造出共享同一個 char 陣列的字串,又有哪些創造出有獨立的 char 陣列字串呢?
介面和抽象類
Java 的介面和抽象類,在專案中如何最合適的使用一直都是一個不好解決的難題。大家在學習介面和抽象類的時候,可以想想:
- Java 的介面相比抽象類有什麼優勢?又有什麼劣勢?
- 它們之間的特點各有什麼不同?
- 有沒有去看過一些開源專案中各個抽象類和介面是如何定義和使用的?
equals 和 hashcode
Java 的 equals 和 hashcode 方法之間總是有著重要的關聯。
- 為什麼重寫 equals 方法要求 hashcode 方法也要跟著重寫?
- hashcode 方法都有哪些用處?
Java 的泛型和列舉
Java 的泛型和列舉對初學者來說是個比較難理解的知識點。還請大家多去查證一下:
- 泛型和列舉是為了解決什麼問題才會被引入的?
- Java 的泛型和列舉都有什麼獨有的特點?
- 泛型和列舉使用最經常出現的錯誤都有哪些?
Java 的 IO、NIO
IO 和 NIO 這裡的學習,我在以前的文章也提過幾次了。除了以前文章提過的一些學習建議,這裡也有幾個問題還請大家思考一下:
- Java 的 IO 有什麼缺陷才會引入 NIO 的?
- NIO 中有哪些是經常被開源框架著重使用的?
Java 的網路程式設計
Java 的網路原生程式設計大家可能真的不常用,但是它確實是 Java 中的非常重要的基礎,Java 的各種和網路相關的重要開源框架,之所以能擁有如此卓越的效能,都離不開 Java 原生網路底層優秀。
- 常用的 Java 開源網路框架,常用的程式設計模式有哪些?
- Java 提供的網路程式設計基礎,是不是還有什麼不足之處?
Java 的正規表示式
Java 的正規表示式,可能很多工作多年的程式設計師掌握的也不好。但是,在做字串匹配相關的業務時,是繞不開它的。
大家除了學習怎麼使用正規表示式以外,還需要思考下:
- 有相同功能,但是寫法不同的正規表示式之間,效能是不是有大的差別?
- 正規表示式能不能表達取反這個邏輯?
- 正規表示式在匹配上有哪些不夠用的地方?
Java 的 JDBC
- 為什麼我們總是習慣於 JDBC 的框架?
- 我們有沒有辦法使用 JDBC 去獲取資料庫中的各種後設資料?
- JDBC 的整體架構是什麼樣的?
- 有沒有什麼獨特的地方你曾經在某些開源框架中見過?
Date、Time、Calendar
- Java 的 Date、Time、Calendar 為什麼難用?
- 有沒有你覺得可以改進的地方?
- 為什麼 JodaTime 這個框架會被人認為勝過 Java 的原生 Date、Time等。
2、精通 Java 併發程式設計
要精通 Java 併發程式設計,像準確理解程式和執行緒啊,弄懂死鎖、Race Condition、程式設計模式什麼的啊,已經算是必要的前提了。在這個基礎上,大概要在基礎上再深入學習如下三個方面:
執行緒的基礎知識
這部分注意兩個細微的知識點以及理解一個模型。
第一個知識點是 volatile 的特性,使用場景和底層實現細節。第二個知識點是 wait 和 sleep 的區別,掌握到 JVM 實現細節最好。
這兩個知識點是妨礙我們們精通執行緒知識的兩大主要阻礙。
除了這兩個知識點,更要深入理解的就是 Java 的記憶體模型——除了瞭解 Java 的記憶體模型是個什麼東西之外,還需要知道 Java 的記憶體模型為什麼這樣設計,這樣設計的好處是什麼,帶來的問題又是什麼?
Java 併發框架
這裡說的併發框架,主要說的是 java.util.concurrent 下的介面和類。
建議除了跟著書練習一遍使用之外,最好是把裡面的原始碼讀一下。
多執行緒程式設計模式
以前我說大家找工作了解下多執行緒程式設計模式,看書就可以了。但是要精通的話,除了看書之外,最好找一些著名開源專案來學習。
比如 Netty,對照著多執行緒程式設計模式,把 Netty 中實現的模式程式碼都好好看一遍,明白各種模式的優缺點和模式之間是如何一起混用以達到最佳效果的。
3、精通 JVM 底層
對於 JVM 的學習,我曾經寫過一篇文章,大家可以參考學習:如何學JVM
除了這篇文章的建議以外,我最近對研究 JVM 又有了一些新的感悟,補充如下:
-
位元組碼方面:可以看《深入理解 JVM 位元組碼》
-
JVM 的垃圾回收方面:建議以《垃圾回收的演算法與實現》為綱領,開始選擇性的讀《深入 Java 虛擬機器:JVM G1GC 的演算法與實現》,《JVM G1 原始碼分析和調優》其中一本書。
以上就是我對“精通 java”的理解。
怎麼樣,看完是不是心情很沉重,感覺學不動了?有這種感覺很正常,如果時間倒回十幾年,我一下看到這麼多內容我也發愁。
以上說的是給大家一個參考,你也可以問問身邊的技術大牛對精通的理解。然後結合自己的工作現狀,找到一個自己認可的方向,慢慢學起了。
只要我們盡力做了,誰都可以成為自己的英雄。
你好,我是四猿外。
一家上市公司的技術總監,管理的技術團隊一百餘人。
我從一名非計算機專業的畢業生,轉行到程式設計師,一路打拼,一路成長。
我會把自己的成長故事寫成文章,把枯燥的技術文章寫成故事。
歡迎關注我的公眾號,關注後可以領取高併發、演算法學習資料。