用Java十多年了,我也不敢說“精通”

我從畢業做程序員就開始用 Java,到現在已經工作快 20 年了。減去我做手遊用 C++、Lua 的幾年,再減去後來轉管理寫代碼少的時間,我真正寫 Java 代碼的時間至少也在 10 年以上。

如果你問我“Java 已經精通了嗎?”,說實話,還是有點心虛。

Java 博大精深,那麼多知識點,肯定有我不懂的。另外,每個人對“精通”都有自己的理解,有人覺得是精於使用,有人覺得是精於底層原理,也有人覺得是精於框架。

但是,畢竟用 Java 十多年了,我可以說說我自己對“精通 Java”的理解。

Java 語言覆蓋的知識很廣泛,但是總的來說,最重要的是以下三個方面:

  1. Java 基礎知識
  2. Java 併發編程
  3. 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等。

二、精通 Java 併發編程

要精通 Java 併發編程,像準確理解進程和線程啊,弄懂死鎖、Race Condition、編程模式什麼的啊,已經算是必要的前提了。在這個基礎上,大概要在基礎上再深入學習如下三個方面:

線程的基礎知識

這部分注意兩個細微的知識點以及理解一個模型。

第一個知識點是 volatile 的特性,使用場景和底層實現細節。第二個知識點是 wait 和 sleep 的區別,掌握到 JVM 實現細節最好。

這兩個知識點是妨礙咱們精通線程知識的兩大主要阻礙。

除了這兩個知識點,更要深入理解的就是 Java 的內存模型——除了瞭解 Java 的內存模型是個什麼東西之外,還需要知道 Java 的內存模型爲什麼這樣設計,這樣設計的好處是什麼,帶來的問題又是什麼?

Java 併發框架

這裏說的併發框架,主要說的是 java.util.concurrent 下的接口和類。

建議除了跟着書練習一遍使用之外,最好是把裏面的源碼讀一下。

多線程編程模式

以前我說大家找工作了解下多線程編程模式,看書就可以了。但是要精通的話,除了看書之外,最好找一些著名開源項目來學習。

比如 Netty,對照着多線程編程模式,把 Netty 中實現的模式代碼都好好看一遍,明白各種模式的優缺點和模式之間是如何一起混用以達到最佳效果的。

三、精通 JVM 底層

對於 JVM 的學習,我曾經寫過一篇文章,大家可以參考學習。

JVM君,你過分了

除了這篇文章的建議以外,我最近對研究 JVM 又有了一些新的感悟,補充如下:

  • 字節碼方面:可以看《深入理解 JVM 字節碼》

  • JVM 的垃圾回收方面:建議以《垃圾回收的算法與實現》爲綱領,開始選擇性的讀《深入 Java 虛擬機:JVM G1GC 的算法與實現》,《JVM G1 源碼分析和調優》其中一本書。

以上就是我對“精通 java”的理解。

怎麼樣,看完是不是心情很沉重,感覺學不動了?有這種感覺很正常,如果時間倒回十幾年,我一下看到這麼多內容我也發愁。

以上說的是給大家一個參考,你也可以問問身邊的技術大牛對精通的理解。然後結合自己的工作現狀,找到一個自己認可的方向,慢慢學起了。

只要我們盡力做了,誰都可以成爲自己的英雄。


你好,我是四猿外。

一家上市公司的技術總監,管理的技術團隊一百餘人。

我從一名非計算機專業的畢業生,轉行到程序員,一路打拼,一路成長。

我會把自己的成長故事寫成文章,把枯燥的技術文章寫成故事。

歡迎關注我的公衆號,關注後可以領取高併發、算法學習資料。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章