我从毕业做程序员就开始用 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”的理解。
怎么样,看完是不是心情很沉重,感觉学不动了?有这种感觉很正常,如果时间倒回十几年,我一下看到这么多内容我也发愁。
以上说的是给大家一个参考,你也可以问问身边的技术大牛对精通的理解。然后结合自己的工作现状,找到一个自己认可的方向,慢慢学起了。
只要我们尽力做了,谁都可以成为自己的英雄。
你好,我是四猿外。
一家上市公司的技术总监,管理的技术团队一百余人。
我从一名非计算机专业的毕业生,转行到程序员,一路打拼,一路成长。
我会把自己的成长故事写成文章,把枯燥的技术文章写成故事。
欢迎关注我的公众号,关注后可以领取高并发、算法学习资料。