JIT编译

JIT编译

提示

请解释下方法内联、逃逸分析等动态编译优化方法

上一节中,我们概述了Java编译执行的整个过程,其中包括:前端编译、类加载、解释执行、JIT编译、AOT编译。本节我们详细讲解其中的JIT编译。尽管JIT编译相关的知识比较偏底层,但对于程序员来说也并非完全没有感知,比如在做性能测试时,我们经常会发现,循环多次执行被测代码时,被测代码的执行速度会变快。这是因为前几次代码的执行为解释执行,但循环执行多次之后,虚拟机便发现代码为热点代码,就会启动JIT编译,在进行编译的同时进行编译优化,将字节码编译为高效的机器码。之后执行代码便直接执行高效的机器码,而非解释执行字节码,因此,代码的执行速度就变快了。实际上,JIT编译过程会涉及非常多的细节内容,这其中就包括JIT编译器、分层编译、热点探测、编译优化,接下来我们就详细讲解一下JIT编译的这4部分内容。


Mr.ZhangJava大约 13 分钟
原子类

原子类

提示

Java代码的执行效率真的比C++等编译型语言低吗?

从本节开始,我们进入专栏的JVM模块。JVM模块分四部分讲解,它们分别是:编译执行、内存模型、垃圾回收、JVM实战。

在专栏的第一节中,我们讲到,高级语言可以粗略的分为三类:编译型语言、解释型语言、混合型语言,其中,Java属于混合型语言。混合型语言也叫做半解释型语言,它融合了编译型语言和解释型语言的特点,既兼顾了可移植性,又兼顾了执行效率。本节,我们就先粗略介绍一下Java的编译执行的整个过程,其中就包括前端编译、类加载、解释执行、JIT编译执行、AOT编译这5部分内容。在后面的几节中,我们对其中较复杂的类加载、JIT编译再进行详细讲解。

img
img

我们经常听说,Java语言的执行效率没有C/C++语言高,为什么这么说呢?这样的说法是否是事实呢?带着这些问题,我们开始今天的学习。


Mr.ZhangJava大约 12 分钟
反射

反射

为什么通过反射创建对象要比使用new创建对象慢?

尽管在平时的业务开发中,我们很少会用到反射、注解、动态代理这些比较高级的Java语法,但是,在框架开发中,它们却非常常用,可以说是支撑框架开发的核心技术。比如,我们常用的Spring框架,其中的IOC就是基于反射实现的,AOP就是基于动态代理实现的,配置就是基于注解实现的。尽管在业务开发中,我们不常用到它们,但是,要想阅读开源框架的源码,掌握这些技术是必不可少的。接下来,我们就来讲讲反射、注解、动态代理。本节我们重点讲下反射。


Mr.ZhangJava大约 15 分钟
注解

注解

注解的配置方式相对于XML配置文件有什么优缺点?

对于Java程序员来说,注解应该一点都不陌生,一些注解我们天天都在用,比如@Override、@Deprecated、@SuppressWarning等。除了这些Java内建注解(built-in anotation)之外,我们还可以定义注解,比如,Spring框架就自定义了@Service、@Controller等很多注解,我们可以使用注解替代XML配置文件来提供配置。本节,我们就详细讲解一下注解。在开始之前,给你留一个思考题:相对于XML配置文件的配置方式,使用注解来做配置有何优缺点?带着这个问题,我们开始今天的学习吧。


Mr.ZhangJava大约 13 分钟
动态代理

动态代理

为什么基于JDK实现的动态代理要求原始类有接口?

前面我们讲到,反射、注解、动态代理是在框架开发中经常用到的3个高级Java语法。在上两节中,我们讲解了其中的反射和注解。本节,我们讲解剩下的动态代理。我们熟悉的Spring AOP、Dubbo RPC等框架都有用到动态代理。在平时的开发中,我们也经常利用动态代理,为代码添加额外的功能,比如日志、事务、鉴权限流、性能监控等。在面试中,我们也经常被问及动态代理相关的问题,比如为什么基于JDK实现的动态代理必须要求原始类有接口?带着这个问题,我们开始今天的学习。


Mr.ZhangJava大约 14 分钟
函数式编程

函数式编程

函数接口、Lambda表达式、方法引用、Stream流

在《设计模式之美》中,我们详细讲解了现在主流的三种编程范式:面向过程、面向对象和函数式编程。其中提到,函数式编程并非一个很新的东西,早在50多年前就已经出现了。近几年,函数式编程越来越被人关注,出现了很多新的函数式编程语言,比如Clojure、Scala、Erlang等。一些非函数式编程语言也加入了很多特性、语法、类库来支持函数式编程,比如Java、Python、Ruby、JavaScript等。本节,我们就来讲讲Java语言对函数式编程的支持。


Mr.ZhangJava大约 15 分钟
JMM

JMM

提示

但凡讲到多线程,我们就不得不讲一下Java内存模型。Java内存模型用来解决多线程的三大问题:可见性问题、有序性问题、原子性问题。Java内存模型也是面试中的常考点。比如:

Java内存模型中的“内存”两个字如何理解?跟多线程有什么关系?

既然CPU支持MESI等缓存一致性协议,为什么还会有可见性问题?

volatile的作用是什么?等等。

对于Java内存模型,我们分3节讲解。本节详细讲解多线程的三个问题是如何产生的,以及简单介绍对Java内存模型是干什么的。下一节详细讲解Java内存模型如何解决多线程的三大问题。下下一节讲解为什么CPU支持MESI等缓存一致性协议,还会有可见性问题?


Mr.ZhangJava大约 39 分钟
线程安全

线程安全

提示

线程安全、临界区、竞态是学习多线程的过程中,经常遇到的几个概念。因此,本节我们就来详细讲解一下这它们,为以后的学习做铺垫。那么,线程安全中的安全两字如何理解呢?什么样的代码是线程安全的代码?什么样的代码线程不安全的代码?如何做到线程安全?围绕着这几个问题,我们开始本节的学习。

一、线程安全概念

在Java中,线程安全或不安全描述的对象既可以是类,也可以是函数。


Mr.ZhangJava大约 8 分钟
线程

线程

提示

有了进程为什么还要有线程?线程越多执行就越快吗?

尽管在平时的开发中,我们很少会直接编写多线程代码,但是,常用的框架和容器,无一例外的都会用到多线程。比如,Dubbo、Tomcat均使用多线程来处理请求。业务代码一般运行在这些框架或容器中,因此,也就间接的会用到多线程。只有对多线程的使用和原理有透彻的了解,我们才能编写出线程安全且高性能的代码。

在正式的学习如何编写多线程代码之前,我们先介绍多线程方面的一些基础理论知识,其中包括:线程的由来、调度策略、线程状态、线程模型、Java线程的实现方式。


Mr.ZhangJava多线程大约 25 分钟
ConcurrentHashMap

ConcurrentHashMap

提示

分段加锁:HashMap线程不安全的原因及ConcurrentHashMap的实现

HashMap是在开发中经常用到的容器,但是,它不是线程安全的,只能应用于单线程环境下。在多线程环境下,Java提供了线程安全的HashTable、SynchronizedMap,但是,两者因为采用粗粒度锁来实现,并发性能不佳。于是,JUC便开发了ConcurrentHashMap,利用分段加锁等技术来提高并发性能。本节,我们就来详细讲解一下ConcurrentHashMap的实现原理,这也是面试中经常被问到的地方。

这里特别声明一下,HashMap和ConcurrentHashMap在JDK7和JDK8中的实现方式均有较大差别,在本节中,我们参照JDK8中的实现方式来讲解。


Mr.ZhangJava多线程大约 18 分钟
2
3