我從畢業做程序員就開始用 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”的理解。
怎么樣,看完是不是心情很沉重,感覺學不動了?有這種感覺很正常,如果時間倒回十幾年,我一下看到這么多內容我也發愁。
以上說的是給大家一個參考,你也可以問問身邊的技術大牛對精通的理解。然后結合自己的工作現狀,找到一個自己認可的方向,慢慢學起了。
只要我們盡力做了,誰都可以成為自己的英雄。
你好,我是四猿外。
一家上市公司的技術總監,管理的技術團隊一百余人。
我從一名非計算機專業的畢業生,轉行到程序員,一路打拼,一路成長。
我會把自己的成長故事寫成文章,把枯燥的技術文章寫成故事。
歡迎關注我的公眾號,關注后可以領取高並發、算法學習資料。