这篇文章将会详细透彻地讲清楚 Java 的 HashMap,包括 hash 方法的原理、HashMap 的扩容机制、HashMap 的加载因子为什么是 0.75 而不是 0.6、0.8,以及 HashMap 为什么是线程不安全的,基本上 HashMap 的常见面试题,都会在这一篇文章里讲明白。
HashMap 是 Java 中常用的数据结构之一,用于存储键值对。在 HashMap 中,每个键都映射到一个唯一的值,可以通过键来快速访问对应的值,算法时间复杂度可以达到 O(1)。
这篇文章将会详细透彻地讲清楚 Java 的 HashMap,包括 hash 方法的原理、HashMap 的扩容机制、HashMap 的加载因子为什么是 0.75 而不是 0.6、0.8,以及 HashMap 为什么是线程不安全的,基本上 HashMap 的常见面试题,都会在这一篇文章里讲明白。
HashMap 是 Java 中常用的数据结构之一,用于存储键值对。在 HashMap 中,每个键都映射到一个唯一的值,可以通过键来快速访问对应的值,算法时间复杂度可以达到 O(1)。
讲真,Stack 这个类在 Java 应用中并不常用,但栈这个数据结构在整个计算机体系中却十分重要。所以我们还是放到集合框架里来讲一讲。
栈(stack),有些地方喜欢称呼它为堆栈,我就很不喜欢,很容易和 heap(堆)搞混,尤其是对于新手来说,简直就是虐心。
栈是一种非常有用的数据结构,它就像一摞盘子,第一个放在最下面,第二个放在第一个上面,第三个放在第二个上面,最后一个放在最上面。
Arthas 是阿里开源的一款线上 Java 诊断神器,通过全局的视角可以查看应用程序的内存、GC、线程等状态信息,并且能够在不修改代码的情况下,对业务问题进行诊断,包括查看方法的参数调用、执行时间、异常堆栈等信息,大大提升了生产环境中问题排查的效率。
Arthas 的官方网站是 https://arthas.aliyun.com/doc/,目前最新的版本是 3.7.2。
前面我们已经讲了 JVM 性能监控工具之命令行篇,本篇我们来介绍一些可视化的性能监控工具,包括 JConsole、VisualVM、Java Mission Control 等,阿里的 Arthas 我们留到后面单独去讲。
可视化工具比命令行工具强大的地方就在于这些工具提供了更直观、更易于理解的性能数据视图,肉眼看上去,脑子就能快速 get 到问题所在,那这篇就来带大家看看这些工具的强大之处。
记得 2014 年我在写大宗期货交易平台的时候,遇到了一些棘手的问题,可能是因为我的并发编程知识掌握的不够扎实,导致出现了内存泄漏的问题。
当时排查了好久,用的工具就是 JDK 自带的 jconsole,之前也没有过类似的性能监控经验,就导致在查找问题的时候非常痛苦,至今印象深刻。
那今天我们就从工具篇出发,来看看这些命令行工具的具体使用方法,以及如何排查问题。
除了我们的老朋友 java 和 javac 命令,在 Java 的 bin 目录下,还有很多其他的命令行工具,比如说用于性能监控的 jps、jstat、jinfo、jmap、jstack、jcmd 等等。
给定一个 32 位有符号整数,将整数中的数字进行反转。
示例 1:
输入: 123
输出: 321
垃圾回收对于 Java 党来说,是一个绕不开的话题,工作中涉及到的调优工作也经常围绕着垃圾回收器展开。面对不同的业务场景,往往需要不同的垃圾收集器才能保证 GC 性能,因此,对于面大厂或者有远大志向的球友可以卷一下垃圾收集器。
就目前来说,JVM 的垃圾收集器主要分为两大类:分代收集器和分区收集器,分代收集器的代表是 CMS,分区收集器的代表是 G1 和 ZGC,下面我们来看看这两大类的垃圾收集器。
前面我们讲栈虚拟机和寄存器虚拟机的时候,提到过栈帧结构;在讲字节码指令的时候,又提到了栈帧中的操作数栈,那今天我们就来详细地讲一讲 JVM 的栈帧结构,好让大家对栈帧有一个更加清晰的认知。
本来这节内容是打算直接讲字节码指令的,但讲之前又必须得先讲指令集架构,而指令集架构又分为两种,一种是基于栈的,一种是基于寄存器的。
那不妨我们这节就单独来讲讲栈虚拟机和寄存器虚拟机,它们有什么不同,以及各自的优缺点。
关于栈这个数据结构,我们前面曾讲过,戳链接直达。
寄存器(Register)是中央处理器(CPU)内用来暂存指令、数据和地址的存储器,也是 CPU 中读写最快的存储器。
以上三点构成不可能三角,即一款垃圾回收器不可能同时满足三点。随着硬件水平的提升,内存占用不再是我们关注的重点,评估垃圾回收器性能时,重点关注吞吐量和暂停时间。吞吐量和暂停时间是相互矛盾的,目前我们追求的效果是:在最大吞吐量优先的情况下,减小暂停时间。