![](https://img-blog.csdnimg.cn/20201014180756926.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
Java
文章平均质量分 83
SKY技术修炼指南
欢迎我的关注公众号:SKY技术修炼指南
展开
-
HashSet能同时存入引号包围和new出来的两个String对象吗
今天面试遇到一个很有意思的问题,先说一下这个问题的背景,面试的时候被问到有两个String对象,分别是String a="abc"和String b=new String(“abc”),问这两个对象同时存进HashSet吗?了解这个问题之前我们先看看HashSet的源码。HashSet源码解析话不多说,先看代码。public HashSet() { map = new HashMap<>();}首先是HashSet的构造方法,我们可以看到HashSet在构造方法里调用了一下原创 2021-07-28 21:42:07 · 491 阅读 · 0 评论 -
动态代理了解一下?
介绍动态代理之前,先介绍一下什么是代理模式。当我们不想访问或者不能直接访问一个对象的时候,我们就需要用到代理模式。代理模式一般涉及到委托类与代理类两个概念,代理类用于为委托类处理一些事务,代理类对象常常与委托类对象相关联。代理模式可以分为静态代理和动态代理,静态代理需要为每一个委托类实现一个代理类,程序运行之前代理类的.class文件就已经存在了,而动态代理则是在运行时利用反射机制动态生成的。静态代理为了帮助大家看懂静态代理,我们举个简单的例子,小丽要买一只口红,但是这只口红在国内买不到,只有美国有得原创 2021-01-31 20:04:14 · 104 阅读 · 0 评论 -
腾讯面试官:ThreadLocal会产生内存泄露的原因是什么
通常情况下,我们在内存中创建的变量是可被多个线程同时访问的,Java通过ThreadLocal实现了线程数据隔离的机制。ThreadLocal的用法既然前面提到了ThreadLocal存储的变量是线程隔离的,我们不妨就测试一下是否如我们所说。我们先创建两个线程,然后为这两个线程设置ThreadLocal变量。public class ThreadLocalDemo { private static ThreadLocal<String> threadLocal = new Thre原创 2020-11-08 20:38:55 · 323 阅读 · 0 评论 -
聊聊Java 8的Lambda表达式和函数式接口
Java 8作为Java的一个里程碑版本,提供了很多特性,本文主要介绍Java 8的Lambda表达式及函数式接口的内容。Lambda表达式Java引入Lambda表达式是为了简化代码,使代码更加简洁优雅。因此,一般使用Lambda表达式的代码也是比较简短的。那么Lambda表达式的代码可以写的多简洁呢?我们看看下面的几个例子。public void fun1() { Thread t = new Thread(() -> System.out.println("Hello")); t.s原创 2020-10-30 22:04:03 · 109 阅读 · 0 评论 -
小米面试官:说说Java的反射
反射是框架设计的灵魂。什么是反射反射是Java中的一种运行机制,与我们正常的代码思路完全不同,只有在运行时才会知道要操作的类是什么,能够完全访问类的属性和方法(包括private修饰的属性和方法)。反射的使用方式反射主要有四种使用方式,分别是知道类名直接根据类名className.class获取Class对象、根据类路径Class.forName("classPath")获取Class对象、根据对象实例通过getClass()方法获取Class对象以及通过类加载器使用loadClass("clas原创 2020-10-25 22:38:48 · 125 阅读 · 0 评论 -
字节面试官:synchronized能保证可见性吗
synchronized是Java并发中最常见的关键字之一,使用锁保证线程间同步,下面介绍synchronized相关内容。synchronized的三种用法synchronized主要有三种用法,分别是修饰普通方法、静态方法和代码块,下面用代码分别演示一下三种用法。修饰普通方法synchronized修饰普通方法作用于对象实例,进入同步代码前获得当前对象实例的锁。public class SynchronizedDemo { public static void main(String[原创 2020-10-21 20:33:05 · 7923 阅读 · 22 评论 -
Java内存模型
本文介绍一下Java多线程中比较重要的部分——Java内存模型,也就是我们说的JMM。很多人会把Java内存模型和Java内存区域弄混,Java内存区域又叫运行时数据区,我们之前在介绍Java虚拟机的文章中也已经讲过了,有兴趣的朋友可以翻一翻我之前的文章。但是这两个概念也并不是完全没有关系,我们先简单回顾一下Java内存区域的概念。Java内存区域主要分为线程共享的堆和方法区以及线程私有的程序计数器、虚拟机栈和本地方法栈。下图展示了Java内存模型的结构。主内存是多个线程共享的区域,对应上面的Jav原创 2020-09-13 22:28:21 · 57 阅读 · 0 评论 -
Java线程通信
线程通信是Java线程部分的重点,我们介绍一下常见的几种线程通信方式。线程锁与同步锁机制是线程通信的一种重要方式。当多个线程竞争某一个对象时,一旦某个线程获得对象就会立刻将其上锁,其他线程只能等待锁被释放才可以继续竞争。当我们需要进行多个线程间的同步时,经常利用线程锁完成。在下面的代码中,两个线程总会有一个执行先后顺序,但后执行的线程必须等待先执行的代码运行结束才可以执行。public class ObjectLock { private static Object obj = new Ob原创 2020-09-12 22:59:17 · 128 阅读 · 0 评论 -
不会吧不会吧,不会有人连线程池都没听说过吧
在上一篇文章中,我们介绍了创建线程的三种方法,但实际开发中如果需要频繁创建线程则不会使用前文说的那三种方法,而是选择使用线程池创建线程。使用线程池可以有效减少在手动创建线程过程中产生的开销,方便线程进行统一管理,提高系统资源利用率。在阿里巴巴Java开发手册中也强制规定了要使用线程资源必须通过线程池创建,不允许在应用中自行显式创建线程。下面介绍几种常见的线程池:newFixedThreadPool(固定大小的线程池)newCachedThreadPool(可缓存线程的线程池)newS原创 2020-08-09 10:33:57 · 109 阅读 · 0 评论 -
从Java创建线程入门多线程
本文是Java多线程系列的第一篇文章,关于线程的基础知识这里不多介绍,在我之前的文章中就已经介绍过了,不熟悉什么是线程的同学可以先去看一下。操作系统-进程与线程从最老生常谈的Java创建线程方式谈起稍微了解过一点Java多线程编程的朋友一定知道,Java创建线程的方式一般有三种:重写Thread类、实现Runnable和实现Callable接口,当然线程池也算是创建线程的一种方式,但那就扯远了,我们暂时从这三种方式聊起。重写Thread类public class CreateThreadTest原创 2020-08-04 21:01:22 · 118 阅读 · 0 评论 -
类加载器与双亲委派模型
之前说到类加载机制的相关原理,这次来谈谈类加载器以及双亲委派模型的概念。类加载器类加载器是Java进行类加载的重要部分,但它的作用又不仅仅局限于进行类加载这么简单。对于两个类,如果要比较它们是否“相等”,首先要确认这两个类来自通过一个类加载器,否则谈论这两个类是否相等将毫无意义。这里的“相等”,包括代表类的Class对象的equals()方法、isAssignableFrom()方法、isInstance()方法的返回结果。类加载器一般被分为三种:启动类加载器、扩展类加载器、应用程序类加载器。启原创 2020-07-21 20:11:54 · 89 阅读 · 0 评论 -
类加载机制
之前我们了解过class文件的存储格式,本文将介绍虚拟机如何加载class文件。类的生命周期一般来说,类的生命周期被划分为加载、验证、准备、解析、初始化、使用和卸载几个阶段,其中验证、准备和解析被统称为连接阶段。解析的过程顺序不确定,可能在初始化开始之后才开始,这常常出现在Java的晚绑定(动态绑定)中。类加载过程加载“加载”和“类加载”听起来十分相似,但是加载只是类加载的一个阶段。加载阶段的三个任务:通过类的全限定名获取类的二进制字节流。将二进制字节流转化成运行时数据结构。在内存中生原创 2020-07-20 19:18:05 · 109 阅读 · 0 评论 -
关于HashMap,你想知道的可能都有
在现在的互联网大厂面试中,HashMap几乎是必问的知识点。因此本文对HashMap进行系统性的总结,将HashMap常见的知识点都整理出来。前面铺垫了两篇红黑树的文章,终于进入这篇HashMap了。如果有不知道什么是红黑树的同学,先去看一下我前面讲红黑树的文章。本科数据结构课程的漏网之鱼-红黑树(上)本科数据结构课程的漏网之鱼-红黑树(下)简介相信大家之前或多或少都接触过HashMap,这是一种用来存放键值对的数据结构。它实现了Map接口,是最常用的Java容器之一。在JDK7及之前版本中,H原创 2020-07-10 23:09:27 · 154 阅读 · 0 评论 -
class类文件结构(这是一篇非常枯燥的文章)
我们知道,Java文件编译后会产生一个字节码文件(.class文件),本文介绍字节码文件的文件结构相关内容。前言Java诞生之初就宣称的“一次编译,处处运行”的性质一直是Java的一大特点,而Java实现这个特点的方式是将.java文件编译成.class文件,通过JVM屏蔽系统差异实现的。事实上,不仅是Java,其他的比如Kotlin、Groovy等语言也都可以通过编译成字节码文件运行在Java虚拟机上,而Java虚拟机也并不关心被编译成字节码文件之前是什么语言。类文件结构按照Java虚拟机规范原创 2020-06-21 22:26:28 · 143 阅读 · 0 评论 -
后浪-下一代垃圾收集器
随着Java虚拟机技术的不断发展,垃圾收集器也进行了大量迭代。前面介绍了7种经典的垃圾收集器,各有优缺点。Serial GC虽然是最古老的垃圾收集器,但由于设计简单,未必就是过时的收集器。CMS收集器由于自身有些算法缺陷,在JDK9中被标记为废弃,在最新版的JDK14中,CMS已经被彻底移除,进入了历史垃圾堆。我们可以发现G1收集器在JDK的各个版本中仍然在不断改进,并且成为了JDK9到JDK13的默认垃圾收集器。今天,我们要介绍的三种垃圾收集器算是垃圾收集器的新发展。Epsilon收集器我们看一下J原创 2020-06-16 19:45:14 · 175 阅读 · 0 评论 -
深入理解Java虚拟机-垃圾收集器
在前面的文章中,我们提到了几种常见的垃圾收集算法,今天咱们来说一说商用Java虚拟机中经典的垃圾收集器。新生代收集器我们首先介绍三种新生代的垃圾收集器,分别是Serial收集器、ParNew收集器和Parallel Scavenge收集器。Serial收集器Serial收集器是最古老的垃圾收集器,曾经是新生代垃圾收集的唯一选择。这是一种单线程的垃圾收集器,采用标记-复制算法,在进行垃圾收集时,所有的工作线程都会停止等待垃圾收集完成,也就是所谓的“Stop the world”。对于服务器来说,可原创 2020-06-07 21:55:12 · 132 阅读 · 0 评论 -
谈谈Java容器-LinkedList
之前的文章中,我们谈到了ArrayList的源码分析,在今天的文章中,我们来看一种和ArrayList非常相似的Java容器——LinkedList。链表谈到LinkedList,我们就不得不谈到它的底层数据结构——链表。private static class Node<E> { E item; Node<E> next; Node<E> prev; Node(Node<E> prev, E element, Nod原创 2020-06-05 18:41:21 · 202 阅读 · 0 评论 -
深入理解Java虚拟机-垃圾收集算法
今天讨论的话题是垃圾收集算法,主要介绍一下标记-清除、标记-整理和标记-复制算法,还会基于这些算法讲一下分代垃圾收集算法。标记-清除算法首先讲一下标记-清除算法,这是最早出现也是最基础的一种算法。从名字就可以看出该算法分为两个过程:标记和清除。标记可以是标记存活对象,也可以是标记将要回收的对象,清除自然就是将要回收的对象的内存收回。我们通过一张图来了解标记-清除算法。上图中青色的部分是存活对象,棕色部分是可回收的对象,空白部分是未使用的内存。在一次垃圾回收以后,标记为可回收的对象均被清除。这种算法原创 2020-06-01 17:23:00 · 133 阅读 · 0 评论 -
谈谈Java容器-ArrayList
ArrayList是面试中常见的Java容器,也算是Java中比较简单的容器,我们今天就来讲讲ArrayList的源码和常见的面试点。概述ArrayList是一种底层基于数组实现的容器,并且能够实现随元素数量增加而进行动态扩容。与LinkedList相比,ArayList非常适合于查找元素,原因在于ArrayList底层实现原理是数组存储的内存在物理上是连续的,但增加和删除元素时,ArrayList比起LinkedList就比较慢了。此外,ArrayList时线程不安全的容器,要使用线程安全的集合容器原创 2020-05-28 18:54:20 · 161 阅读 · 0 评论 -
深入理解Java虚拟机-判断对象是否存活算法与对象引用
在之前的文章中我们谈到过Java内存区域的概念,我们知道Java中的对象一般存放在堆中,但是总不能让这些对象一直占着内存空间,这些对象最终都会被回收并释放内存,那么我们如何判断对象已经成为垃圾呢?这篇文章会提出两种算法解决这个问题。另外,本文还要谈一谈对象引用相关的知识,这在面试中也是经常被问到的问题。判断对象是否存活算法引用计数算法引用计数算法的原理比较简单,在对象中添加一个引用计数器,当有一个引用指向一个对象时,这个对象的引用计数器会加1,当引用不再指向对象时,引用计数器便减1。当引用计数器的值原创 2020-05-25 13:40:56 · 231 阅读 · 0 评论