ArrayList 从源码角度剖析底层原理

对于 ArrayList 来说,我们平常用的最多的方法应该就是 addremove 了,本文就主要通过这两个基础的方法入手,通过源码来看看 ArrayList 的底层原理。

add

默认添加元素

这个应该是平常用的最多的方法了,其用法如下。

接下来我们就来看看 add 方法的底层源码。

ensureCapacityInternal 作用为:保证在不停的往 ArrayList 插入数据时,数组不会越界,并且实现自动扩容。

继续阅读ArrayList 从源码角度剖析底层原理

浅谈JVM和垃圾回收

写在前面

简单的介绍一下JVM(Java Virtual Machine)吧,它也叫Java虚拟机。虽然它叫虚拟机,但是实际上不是我们所理解的虚拟机,它更像操作系统中的一个进程。JVM屏蔽了各个操作系统底层的相关的东西,Java程序只需要生成对应的字节码文件,然后由JVM来负责解释运行。

介绍几个容易混淆的概念,JDK(Java Development Kit) 可以算是整个Java的核心,其中有编译、调试的工具包和基础类库,它也包含了JRE

JRE(Java Runtime Environment),包含了JVM和基础类库。而JVM就是我们今天要聊的主角,开篇聊到,JVM负责解释运行,它会将自己的指令映射到当前不同设备的CPU指令集上,所以只需要在不同的操作系统上装不同版本的虚拟机即可。这也给了Java跨平台的能力。

JVM的发展

就跟我们用三方库一样,同样的功能有不同的实现。JVM也是一样的,第一款JVM是Sun公司的Classic VM,JDK1.2之前JVM都是采用的Classic VM,而之后,逐渐被我们都知道的HotSpot给替代,直到JDK1.4,Classic VM才完全被弃用。

继续阅读浅谈JVM和垃圾回收

深入了解ConcurrentHashMap

在上一篇文章【简单了解系列】从基础的使用来深挖HashMap里,我从最基础的使用中介绍了HashMap,大致是JDK1.7和1.8中底层实现的变化,和介绍了为什么在多线程下可能会造成死循环,扩容机智是什么样的。感兴趣的可以先看看。

我们知道,HashMap是非线程安全的容器,那么为什么ConcurrentHashMap能够做到线程安全呢?

底层结构

首先看一下ConcurrentHashMap的底层数据结构,在Java8中,其底层的实现方式与HashMap一样的,同样是数组、链表再加红黑树,具体的可以参考上面的HashMap的文章,下面所有的讨论都是基于Java 1.8。

继续阅读深入了解ConcurrentHashMap

【简单了解系列】从基础的使用来深挖HashMap

HashMap定义

说的专业一点,HashMap是常用的用于存储key-value键值对数据的一个集合,底层是基于对Map的接口实现。每一个键值对又叫Entry,这些Entry分散的存储在一个由数组和链表组成的集合中。当然在Java8中,Entry变成了Node

说的通俗一点,就像你去住酒店,你下单提供了你的手机号,然后到酒店了给你一个房卡,你知道了你的房号之后再根据这个房号去找对应的房间一样。

房号就是key,房间里就是value。你通过手机号下单到酒店给你房号可以理解为对key哈希的过程。你找的过程就是HashMap根据key取到对应value的过程

HashMap底层结构

继续阅读【简单了解系列】从基础的使用来深挖HashMap

初探Java类型擦除

什么是类型擦除

为了让你们快速的对类型擦除有一个印象,首先举一个很简单也很经典的例子。

// 指定泛型为String
List<String> list1 = new ArrayList<>();
// 指定泛型为Integer
List<Integer> list2 = new ArrayList<>();
System.out.println(list1.getClass() == list2.getClass()); // true

上面的判断结果是true。代表了两个传入了不同泛型的List最终都编译成了ArrayList,成为了同一种类型,原来的泛型参数String和Integer被擦除掉了。这就是类型擦除的一个典型的例子。

继续阅读初探Java类型擦除

来认识一下venus-init——一个让你仅需一个命令开始Java开发的命令行工具

源代码地址: Github仓库地址

个人网站:个人网站地址

前言

不知道你是否有过这样的经历。不管你是什么岗位,前端也好,后端也罢,想去了解一下Java开发到底是什么样的,它是不是真的跟传说中的一样。

于是你拿起键盘,用触控板 ? '' : 抄起鼠标‘,开始了Java淌坑之旅。在一把梭的操作之后,面对你搭建的环境,你陷入了深深的沉思,开始了吾日三省吾身的自我质疑中。这tm到底哪儿错了?到底哪儿在报错?这报错啥意思?

继续阅读来认识一下venus-init——一个让你仅需一个命令开始Java开发的命令行工具

如何在SpringBoot中集成JWT(JSON Web Token)鉴权

这篇博客主要是简单介绍了一下什么是JWT,以及如何在Spring Boot项目中使用JWT(JSON Web Token)。

关于JWT

什么是JWT

老生常谈的开头,我们要用这样一种工具,首先得知道以下几个问题。

  • 这个工具是什么,这个工具解决了什么问题
  • 是否适用于当前我们所处得业务场景
  • 用了之后是否会带来任何其他问题
  • 怎么用才是最佳实践

那什么是JWT呢?以下是我对jwt官网上对JWT介绍的翻译。

继续阅读如何在SpringBoot中集成JWT(JSON Web Token)鉴权

想在Java中实现Excel和Csv的导出吗?看这就对了

前言

最近在项目中遇到一个需求,需要后端提供一个下载Csv和Excel表格的接口。这个接口接收前端的查询参数,针对这些参数对数据库做查询操作。将查询到的结果生成Excel和Csv文件,再以字节流的形式返回给前端。

前端拿到这个流文件之后,最开始用ajax来接收,但是前端发送的请求却被浏览器cancel掉了。后来发现,发展了如此之久的Ajax居然不支持流文件下载。后来前端换成了最原始的XMLHttpRequest,才修复了这个问题。

继续阅读想在Java中实现Excel和Csv的导出吗?看这就对了

手把手教你如何优雅的使用Aop记录带参数的复杂Web接口日志

前言

不久前,因为需求的原因,需要实现一个操作日志。几乎每一个接口被调用后,都要记录一条跟这个参数挂钩的特定的日志到数据库。举个例子,就比如禁言操作,日志中需要记录因为什么禁言,被禁言的人的id和各种信息。方便后期查询。

这样的接口有很多个,而且大部分接口的参数都不一样。可能大家很容易想到的一个思路就是,实现一个日志记录的工具类,然后在需要记录日志的接口中,添加一行代码。由这个日志工具类去判断此时应该处理哪些参数。

但是这样有很大的问题。

继续阅读手把手教你如何优雅的使用Aop记录带参数的复杂Web接口日志

在Java中使用redisTemplate操作缓存

背景

在最近的项目中,有一个需求是对一个很大的数据库进行查询,数据量大概在几千万条。但同时对查询速度的要求也比较高。

这个数据库之前在没有使用Presto的情况下,使用的是Hive,使用Hive进行一个简单的查询,速度可能在几分钟。当然几分钟也并不完全是跑SQL的时间,这里面包含发请求,查询数据并且返回数据的时间的总和。但是即使这样,这样的速度明显不能满足交互式的查询需求。

继续阅读在Java中使用redisTemplate操作缓存