如何提升 Java 编程内力?
可能很多初学者在学完 SpringBoot 之后,做了 1-2 个项目之后,不知道该去学习什么了,其实这时候需要去学习的东西还有很多,接下来我会列举一下主要需要从哪些方面来对 Java 编程深入学习,提高自己的编程内力!
对于这些进阶方面的内容,我也整理了一份 PDF,点击查看
高并发进阶
我们自己在学习中做的项目一般不会放到真正环境去测试,而且测试的话,一般也是发送单个请求,看整个业务流程是否正确,并没有考虑到 并发安全
的问题,那么在数据量大的项目中,多线程、并发安全问题是很重要的,因此并发相关的内容是需要去进一步增强的
就比如高并发场景下,对于共享数据的操作,要加上锁,否则会出现线程安全的问题,这里举个最简单的例子,i ++ 操作是分为 3 个步骤执行的:
1.读取 i 的值
2.将 i 的值加一
3.写入 i 的值
那么可能线程 A 和线程 B 同时执行第 1 步,取到相同的 i 值,那么对同一个 i 值加一,两个线程执行两次 i++ 应该加 2,最后的结果确实加 1,造成了线程不安全
该如何进阶呢?
对于并发中的 synchronized、volatile 一定要了解,以及分布式锁要了解
分布式锁用在哪些场景呢?
用在多个接口同时操作一个数据的场景下,比如对缓存列表的构建,假设列表缓存的构建时机有两个:
- 第一个是真正来查询该用户分享的内容列表时(延迟构建,在真正查询时再进行构建,避免占用 Redis 内存),此时先在数据库中查询分页数据,再去缓存中构建分页缓存
- 第二个是用户修改或者新增分享的内容时,此时通过 RocketMQ 来异步通知,去对缓存中的分页列表进行重新的构建
那么可以来看一种并发下的极端情况会出现的问题:
当用户 A 新增分享的时候,另一个用户 B 此时正好来查询用户 A 的分享列表,用户 B 线程先去缓存中查询,发现没有,再去数据库中查询用户 A 的分享列表,此时 B 拿到了 A 新增分享之前的旧数据,此时如果用户 A 新增分享并落库,并且去缓存中对用户 A 的列表缓存进行重建,那么此时缓存列表中是用户 A 的最新数据,但是此时用户 B 的线程在数据库中已经查到了用户 A 的旧数据,用户 B 的线程继续执行,将用户 A 的旧数据给放入到列表缓存中,覆盖掉了用户 A 更新的缓存,那么此时就会导致缓存数据库不一致
这时候就需要去在这两个操作缓存列表的位置 添加分布式锁
,保证顺序操作,而不会并发操作!
JVM 进阶
在 JVM 方面,也是要深入理解的,因为你在 Java 代码中写的一些变量、方法等等都是基于 JVM 来进行存储的,那么对于 JVM 的 内存模型
肯定要了解:堆、栈、方法区
JVM 中另一块重要的内容就是 垃圾收集
,这里主要需要了解常见的一些垃圾收集算法的垃圾收集器,要了解 JVM 收集垃圾的流程
最后进阶方面就是 JVM 的调优
,说是调优,其实就是处理一些线上环境的 JVM 问题,就比如你肯定要给 JVM 添加监控,那么如果监控到 JVM 的 GC 停顿时间很长怎么办呢?
可以看看一般就是 gc 次数过多,而 full gc 停顿时间比较长,一般就是频繁发生 full gc,那么为什么会频繁 full gc?
那么可能就是因为频繁去创建大对象,JVM 发现对象在新生代放不下,因此直接放到老年代,导致老年代很快空间不足,频繁发生 full gc
设计模式进阶
设计模式是想高级开发进阶的必经之路,因为设计模式中提供了很多经过长时间检验的特定问题解决方案,掌握了设计模式,写出的代码具有更好的健壮性、可维护性和可扩展性
并且利用好设计模式,可以使得代码具有更好的重用性,拒绝 code shit moutain!
如果你之后需要去设计一个系统架构,那么如果不了解设计模式,可能无法做出很好的设计
总结博客
在学习、工作之余,一定要善于总结,通过写文章来总结,可以将自己工作中碰到的一些亮点和困难点提炼出来,以及未来的一些改进之处,总结的多了之后,就可以对我们平时做的工作有很清晰的认知,避免出现,在面试的时候,面试官问:“你平时做的工作中遇到过什么困难吗?”,一时半会也想不起来,就算想起来,由于没有提前准备,说的也磕磕绊绊,所以一定要去总结博客!
你通过将自己学到的内容总结出来提供价值给其他人之后,你也可以从中获利,像比较厉害的一些大佬都有整理笔记的习惯:
- 美团技术团队
- 吕文翰
- 柳伟卫
- pdai
源码进阶
如果继续向高级工程师进阶,源码是必须要了解的,为什么非要去学习源码呢?
首先,对于常用的中间件,比如 RocketMQ,我们去学习它的源码,那么在生产环境中,如果 RocketMQ 出了一些问题,可以直接从源码级别定位问题,去解决问题,如果不了解源码的话,可能要折腾很长时间了
其次,目前广泛使用的中间件的架构设计的都是很好的,包括设计模式、线程池的使用非常标准,我们可以去学习源码中如何使用,进而引进到我们自己的项目中,提升系统架构设计的能力
生产经验进阶
最后就是生产经验的能力了,这考验我们接触项目的生产环境到底多不多,以及对于生产中的一些部署和问题的解决
比如说,现在基本上分布式系统中都会有网关系统,那么网关系统我们如何去部署了,部署几台,部署机器的配置是怎样的?
那么每天打到网关上的流量是多少,高峰期的 QPS 是多少?
如果访问量增长,怎么去抗下更高的请求数量呢?
上边这些就是考察生产环境方面的能力,因此在工作中,机器上线之后,一定要去给系统部署上监控,多去看看监控,了解系统最大承载并发请求的能力以及机器的配置,因为不同机器配置下,可以处理的请求量也是不同的!