![](https://img-blog.csdnimg.cn/20201014180756916.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
Java基础知识
intimexy
这个作者很懒,什么都没留下…
展开
-
为什么 ConcurrentHashMap 读操作不需要加锁?
来源:http://tinyurl.com/y685vvv9 目录 ConcurrentHashMap的简介 get操作源码 volatile登场 是加在数组上的volatile吗? 用volatile修饰的Node 总结 我们知道,ConcurrentHashmap(1.8)这个并发集合框架是线程安全的,当你看到源码的get操作时,会发现get操作全程是没有加任何锁的,这也是这篇博文讨论的问题——为什么它不需要加锁呢? Concu...转载 2020-12-14 21:37:50 · 194 阅读 · 0 评论 -
Hashmap的结构,1.7和1.8有哪些区别
(一) Hashmap的结构,1.7和1.8有哪些区别 不同点: (1)JDK1.7用的是头插法,而JDK1.8及之后使用的都是尾插法,那么他们为什么要这样做呢?因为JDK1.7是用单链表进行的纵向延伸,当采用头插法时会容易出现逆序且环形链表死循环问题。但是在JDK1.8之后是因为加入了红黑树使用尾插法,能够避免出现逆序且链表死循环的问题。 (2)扩容后数据存储位置的计算方式也不一样:1. 在JDK1.7的时候是直接用hash值和需要扩容的二进制数进行&(这里就是为什么扩容的时候为啥一定必须是转载 2020-12-14 21:32:50 · 145 阅读 · 0 评论 -
Java中常见的锁及其优化
常见锁 作为并发编程的一部分,锁机制是必不可少的,常见的锁有以下几种: 乐观锁、悲观锁、自旋锁、同步锁、递归锁、重量级锁、轻量级锁、偏向锁、分段锁,下面就来一一介绍一下这些锁: 1.乐观锁 乐观锁是一种乐观思想,它主要用在读多写少的场景。它认为别的线程在拿数据的时候只负责拿,并不会对数据进行改变,所以不会上锁。但是它在更新的时候会判断一下在此期间别人有没有对数据进行更新,采取先时先读当前的版本号,然后再进行加锁操作(比较当前的版本和上一次的版本号是否相等,如果一样就更新,如果不一样则重新进行CAS操作转载 2020-12-14 21:23:50 · 219 阅读 · 0 评论 -
CAS的实现原理
原文链接:https://blog.csdn.net/david_lua/article/details/103331688 本文导读: 前言如何保障线程安全CAS原理剖析CPU如何保证原子操作解密CAS底层指令小结 1 前言 日常编码过程中,基本不会直接用到 CAS 操作,都是通过一些JDK 封装好的并发工具类来使用的,在 java.util.concurrent 包下。 但是面试时 CAS 还是个高频考点,所以呀,你还不得不硬着头皮去死磕一下这块的技能点,总比一问三不知强吧?转载 2020-12-13 15:02:32 · 935 阅读 · 0 评论 -
是否真的理解了偏向锁、轻量级锁、重量级锁(锁膨胀)、自旋锁、锁消除、锁粗化,知道重偏向吗?
知识准备: 在开始前,首先清楚系统PV信号机制 荷兰学者Dijkstra于1965年提出的信号机制是一种有效的进程同步与互斥工具。 1)整型信号与PV操作 信号量是一个整型变量,根据控制对象的不同被赋予不同的值。信号量分为如下两类: (1)公用信号量。实现进程间的互斥,初值为1或资源的数目。 (2)私有信号量。实现进程间的同步 ,初值为0或某个正整数。 信号量 S的物理意义:S≥0表示某资...转载 2020-12-13 14:58:43 · 287 阅读 · 0 评论 -
synchronized的几种加锁方式
1、修饰普通方法(锁住的是当前实例对象) 同一个实例调用会阻塞不同实例调用不会阻塞public class SynchronizedTest { //锁住了本类的实例对象 public synchronized void test1() { try { logger.info(Thread.currentThread().getName() + " test1 进入了...转载 2020-12-13 14:52:20 · 2970 阅读 · 2 评论 -
从mian()方法的创建说起:守护线程和非守护线程
创建一个mian()方法做了哪些事情?守护线程和非守护线程创建守护线程 创建一个mian()方法做了哪些事情? 创建方法 当我们创建了一个main()方法时,JVM为我们做了哪些事情?只是简单的开辟一个mian线程,执行mian()方法中的方法体吗? 用代码验证一...转载 2020-12-10 16:26:16 · 475 阅读 · 0 评论 -
深入浅出Java中的clone克隆方法
Java中对象的创建 clone顾名思义就是复制, 在Java语言中, clone方法被对象调用,所以会复制对象。所谓的复制对象,首先要分配一个和源对象同样大小的空间,在这个空间中创建一个新的对象。那么在java语言中,有几种方式可以创建对象呢? 1 使用new操作符创建一个对象 2 使用clone方法复制一个对象 那么这两种方式有什么相同和不同呢?...转载 2020-12-10 16:19:12 · 124 阅读 · 0 评论 -
volatile是如何保证可见性和有序性的
volatile保证可见性的原理 可见性问题 可见性问题指的是一个线程在访问一个共享变量的时候,其他线程对该共享变量的修改对于第一个线程来说是不可见的,下面通过一个例子可以发现可见性问题。 public class Visable { private static boolean flag = true; public static void main(String[] args) throws InterruptedException { new Thre.转载 2020-12-10 16:16:39 · 3737 阅读 · 1 评论 -
整数最大值+1问题
先看一个问题:i + 1 < i 成立吗?答案是肯定的。下面我们用代码来证明: @Test public void test(){ int i = Integer.MAX_VALUE; System.err.println("i="+i+",i+1="+(i+1)+" result:"+((i+1)<i)); }输出结果如下:i=2147483647,i+1=-214748364...转载 2020-12-10 16:11:39 · 1074 阅读 · 0 评论 -
反射的作用及缺点
反射是什么呢?当我们的程序在运行时,需要动态的加载一些类这些类可能之前用不到所以不用加载到jvm,而是在运行时根据需要才加载 作用:用于在运行时需要检测或修改程序行为的地方,比如说可以动态加载类啊,实现AOP啊 缺点: 1.性能问题。反射包括了一些动态类型,所以 JVM 无法对这些代码进行优化。因此,反射操作的效 率要比那些非反射操作低得多。我们应该避免在经常被 执行的代码或对性能要求很高的程&n...转载 2020-11-24 16:48:43 · 1703 阅读 · 1 评论 -
重温数据结构:深入理解红黑树
读完本文你将了解到: 什么是红黑树 黑色高度 红黑树的 5 个特性红黑树的左旋右旋 指定节点 x 的左旋 右图转成左图指定节点 y 的右旋左图转成右图 红黑树的平衡插入 二叉查找树的插入 插入后调整红黑树结构 调整思想 插入染红后的调整有 2 种情况 根据 TreeMap 的代码来验证这个过程 红黑树的平衡删除 二叉查找树的删除 删除后的结构调整 调整思想 删除转载 2020-11-24 16:19:07 · 89 阅读 · 0 评论 -
如何理解成员变量在堆内,局部变量在栈内?
成员变量在堆内存里,局部变量在栈内存里。(基础类型)我有疑惑:既然成员变量存在于对象中,对象存在于堆中,所以成员变量存在于堆中。那么按照这样的推理,局部变量存在于方法中,而方法存在于对象中,对象存在于堆中,那是不是可以说局部变量存在于堆中?解决思想当对象new出来,实体存在于堆,对象的成员变量已经在堆上分配空间,但对象里面的方法是没有出现的,只出现方法的声明,方法里面的局部变量并没有创建。等到对象调用此方法...转载 2020-11-24 16:10:59 · 1534 阅读 · 0 评论 -
单利模式的优缺点和使用场景
文章转自:http://www.tools138.com/create/article/20150929/020009847.html 单利模式的优缺点和使用场景 首先介绍一下单例模式: 单例模式(Singleton),也叫单子模式,是一种常用的软件设计模式。在应用这个模式时,单例对象的类必须保证只有一个实例存在。许多时候整个系统只需要拥有一个的全局对象,这样有利于我们协调系统整体的行为。比如在某个服务器程序中,该服务器的配置信息存放..转载 2020-11-20 18:06:18 · 687 阅读 · 0 评论 -
Vector的线程安全与线程不安全
其实这个标题就有点猎奇了。其实对于大多数人来说,线程安全线程不安全,听起来更像是一种编码理论,实际并不会用到,而对于现在的Java程序员来说更是如此,层出不穷的框架早就帮我们明里暗里处理好了线程安全的问题,但是,我还是觉得有必要了解这些东西。其实对于Vector来说,大多数人可能比较陌生,知道的最多的就是面试的时候要说出它和ArrayList的区别,即一个是线程安全的一个不是,仅此而已,今天翻到别人写的代码,看到了这个vector,一时间没看懂这是啥玩意,花了几分钟了解了一下,觉得还是很有意思的,就给大家转载 2020-11-20 17:59:07 · 1224 阅读 · 0 评论 -
链表之头插法和尾插法
头插法:生成的链表和我输入的数据顺序是相反的,所以又称逆序建表法。 例如:e d c b a 建成的链表就是 head->a->b->c->d->e 算法步骤: ①创建一个只有头结点的空链表。 ②根据待创建链表的元素个数n,循环n次执行以下操作: ●生成一个新结点*p; ●输入元素值赋给新...转载 2020-11-20 17:40:02 · 733 阅读 · 0 评论 -
HashMap工作原理和扩容机制
HashMap工作原理HashMap扩容 1 HashMap的扩容时机2 HashMap的扩容过程 补充 1 容量必须是2的幂2 rehash References 1. HashMap工作原理 HashMap作为优秀的Java集合框架中的一个重要的成员,在很多编程场景下为我们所用。HashMap作为数据结构散列表的一种实现,就其工作原理来讲单独列出一篇博客来讲都是不过分的。由于本文主要是简单总结其扩容机制,因此对于HashMap的实现原理仅做简单的...转载 2020-11-20 17:35:58 · 516 阅读 · 0 评论 -
Java线程池实现原理详解
文章目录 原理概述线程池的几个主要参数的作用任务提交后的流程分析源码解析1. 提交任务相关源码2. Worker的结构3. 添加Callable任务的实现源码4. shutdown和shutdownNow方法的实现 总结 原理概述 其实java线程池的实现原理很简单,说白了就是一个线程集合workerSet和一个阻塞队列workQueue。当用户向线程池提交一个任务(也就是线程)时,线程池会先将任务放入workQueue中。workerSet中的线程会不断的从workQue.转载 2020-11-15 18:21:16 · 101 阅读 · 0 评论 -
处理器是如何调度进程
概念 发生进程切换时,本质是CPU资源占用者间的切换。此时需要保存当前进程在PCB中的执行上下文(CPU状态),然后恢复下一个进程的执行上下文。 处理机调度涉及两个方面,一是选择进程:从就绪队列中挑选下一个占用CPU运行的进程。二是选择CPU资源:从多个可用CPU中挑选就绪进程可使用的CPU资源。 准则 调度策略是指确定如何从就绪队列中选择下一个执行进程,可以理解为调度算法。评价算法的基准有以下几个: 1.CPU使用率:CPU处于忙状态的时间百分比2.吞吐量:单位时间内完成的进程数量3.周转时间:转载 2020-11-13 18:42:36 · 362 阅读 · 0 评论 -
子进程与线程的区别
1、相同点: (a)二者都具有ID,一组寄存器,状态,优先级以及所要遵循的调度策略。 (b) 每个进程都有一个进程控制块,线程也拥有一个线程控制块。 (c) 线程和子进程共享父进程中的资源;线程和子进程独立于它们的父进程,竞争使用处理器资源;线程和子进程的创建者可以在线程和子进程上实行某些控制,比如,创建者可以取消、挂起、继续和修改线程和子进程的优先级;线程和子进程可以改变其属性并创建新的资源。 2、不同点: (a...转载 2020-11-13 18:35:43 · 2746 阅读 · 0 评论 -
进程的基本概念以及如何创建子进程
进程是一种动态描述,但是并不代表所有的进程都在运行。进程有两个基本元素,一个是程序代码(可能被执行相同程序的其他程序共享)和代码相关联的数据集。 任何计算机都包含一个基本的程序集合,称为操作系统(它的上层是shell),它的目的:往下,与硬件交互,管理所有的硬件资源;往上,为用户程序提供一个良好的执行环境。 我们应该知道程序是一个二进制文件,它存在与硬盘,当它运行的时候就有了动态的属性,此时有了两份拷贝,一份在...转载 2020-11-13 18:32:08 · 1143 阅读 · 0 评论 -
进程间通信的8种方式
前言进程通信: 每个进程各自有不同的用户地址空间,任何一个进程的全局变量在另一个进程中都看不到,所以进程之间要交换数据必须通过内核,在内核中开辟一块缓冲区,进程A把数据从用户空间拷到内核缓冲区,进程B再从内核缓冲区把数据读走,内核提供的这种机制称为进程间通信。 进程间通信(IPC)介绍 进程间通信(IPC,InterProcess Communication)是指在不同进程之间传播或交换信息。 IPC的方式通常有管道(包括无名管道和命名管道)、消息队列、信号量、共享存储、Socket、Stream转载 2020-11-08 16:39:14 · 602 阅读 · 0 评论 -
操作系统为什么要分用户态和内核态
在CPU的所有指令中,有一些指令是非常危险的,如果错用,将导致整个系统崩溃。比如:清内存、设置时钟等。如果所有的程序都能使用这些指令,那么你的系统一天死机n回就不足为奇了。所以,CPU将指令分为特权指令和非特权指令,对于那些危险的指令,只允许操作系统及其相关模块使用,普通的应用程序只能使用那些不会造成灾难的指令。Intel的CPU将特权级别分为4个级别:RING0,RING1,RING2,RING3。 &nb...转载 2020-11-08 16:35:19 · 2373 阅读 · 1 评论 -
用户态和内核态的概念区别
究竟什么是用户态,什么是内核态,这两个基本概念以前一直理解得不是很清楚,根本原因个人觉得是在于因为大部分时候我们在写程序时关注的重点和着眼的角度放在了实现的功能和代码的逻辑性上,先看一个例子: 1)例子 C代码 1. void testfork(){ 2. i...转载 2020-11-08 16:29:25 · 401 阅读 · 0 评论 -
面试公平锁/非公平锁/可重入锁/递归锁/自旋锁谈谈你的理解
一、公平锁/非公平锁/可重入锁/递归锁/自旋锁谈谈你的理解公平锁:多个线程按照申请的顺序来获取锁。非公平锁:多个线程获取锁的先后顺序与申请锁的顺序无关。【ReentrantLock 默认非公平、synchronized】总结:非公平锁的吞吐量比公平锁大。可重入锁(又名递归锁):线程可以进入任何一个它已经获取锁的同步代码块中。可重入锁的最大作用:避免死锁自旋转:是指尝试获取锁的线程不会立即阻塞,而是采用循环的方式去尝试获取锁。好处:减少线程上下文切换的消耗缺点:循环会消耗CPU二、手写一个自转载 2020-11-06 18:46:08 · 120 阅读 · 0 评论 -
IO多路复用机制详解
高性能IO模型浅析 服务器端编程经常需要构造高性能的IO模型,常见的IO模型有四种: (1)同步阻塞IO(Blocking IO):即传统的IO模型。 (2)同步非阻塞IO(Non-blocking IO):默认创建的socket都是阻塞的,非阻塞IO要求socket被设置为NONBLOCK。注意这里所说的NIO并非Java的NIO(New IO)...转载 2020-11-04 18:23:14 · 168 阅读 · 1 评论 -
java中的基本数据类型和引用数据类型以及它们的存储方式堆内存和栈内存
一 基本数据类型 数据类型在计算机语言里面,是对内存位置的一个抽象表达方式,可以理解为针对内存的一种抽象的表达方式。基本类型:简单数据类型是不能简化的、内置的数据类型、由编程语言本身定义,它表示了真实的数字、字符和整数。在java中基本数据类型一共有8种,包括 byte:Java中最小的数据类型,在内存中占8位(bit),即1个字节,取值范围-128~127,默认值0; short:短整型,在内存中占16位,即2个字节,取值范围-32768~3转载 2020-11-04 18:19:47 · 1783 阅读 · 0 评论 -
IO模式和IO多路复用(阻塞IO、非阻塞IO、同步IO、异步IO等概念)
IO模式和IO多路复用(阻塞IO、非阻塞IO、同步IO、异步IO等概念) 百科程序员 2018-08-05 11:57:58 网络编程里常听到阻塞IO、非阻塞IO、同步IO、异步IO等概念,总听别人装13不如自己下来钻研一下。不过,搞清楚这些概念之前,还得先回顾一些基础的概念。 回到顶部 1 基础知识回顾 注意:咱们下面说的都是Linux环境下,跟Windows不一样哈~~~ 1.1 用户空间...转载 2020-11-04 18:16:25 · 377 阅读 · 0 评论 -
服务器里的吞吐量指的是什么
吞吐量:系统在单位时间内处理请du求的数量。只不过是一个很宽泛的术zhi语,大家经常指的吞吐量dao的单位可能是:TPS/QPS、页面数/秒、人数/天、处理业务数/小时等等。几个相关的概念:TPS、QPS、RPSTPS:Transactions Per Second(每秒事务处理数),指服务器每秒处理的事务次数。一般用于评估数据库、交易系统的基准性能。QPS:Queries Per Second(查询量/秒),是服务器每秒能够处理的查询次数,例如域名服务器、Mysql查询性能。RPS:Request原创 2020-11-04 16:30:25 · 4383 阅读 · 0 评论 -
成员变量在堆内存里,局部变量在栈内存里
成员变量在堆内存里,局部变量在栈内存里。(基础类型)我有疑惑:既然成员变量存在于对象中,对象存在于堆中,所以成员变量存在于堆中。那么按照这样的推理,局部变量存在于方法中,而方法存在于对象中,对象存在于堆中,那是不是可以说局部变量存在于堆中?解决思想当对象new出来,实体存在于堆,对象的成员变量已经在堆上分配空间,但对象里面的方法是没有出现的,只出现方法的声明,方法里面的局部变量并没有创建。等到对象调用此方法时,为了加快运行的速度,方法中的局部变量才会在栈中创建,所以,方法中的局部变量是在栈...转载 2020-11-02 18:58:53 · 3383 阅读 · 1 评论 -
标记、清除算法是如何处理循环引用
目前的GC算法有两个大分类:引用计数与可达性。下面来说说引用计数法是如何统计所有对象的引用计数的,再对比分析可达性算法是如何解决引用技术算法的不足,好比说循环引用。循环引用 举个栗子:有两个对象,A引用B,B引用A。 这种情况下两个对象都存在引用,那么是否这两个对象就无法被GC了呢?先卖个关子,让我们记住这种情况,带着疑问往下读,接下来了解一下GC算法的一些概念。 GC采用的算法 1.引用计数算法:每个对象都有一个引用计数器,当对象被引用时计数器+1,对象引用失效的时候,引用计数器-1,当计数为0转载 2020-11-02 18:54:30 · 843 阅读 · 0 评论 -
深入理解程序、 jvm实例、进程、线程的关系
深入理解程序、 jvm实例、进程、线程的关系 问题引出实验进程的概念线程的概念结论 问题引出 命令启动了两个java程序,它们之间是什么关系? java程序又和JVM之间是什么关系,它们是共用一个JVM,还是每个java程序,都有一个JVM? 进程和程序是什么关系,进程和线程是什么关系? 实验 用命令启动两个一样的java程序。 #java HelloWorld 用jvisual观察到有两个HelloWorld程序的进程。 进程的概念 在多道程序工作的环境下,操作系统必须能够实现...转载 2020-11-02 18:51:10 · 316 阅读 · 0 评论 -
死锁面试题(什么是死锁,产生死锁的原因及必要条件)
什么是死锁? 所谓死锁,是指多个进程在运行过程中因争夺资源而造成的一种僵局,当进程处于这种僵持状态时,若无外力作用,它们都将无法再向前推进。 因此我们举个例子来描述,如果此时有一个线程A,按照先锁a再获得锁b的的顺序获得锁,而在此同时又有另外一个线程B,按照先锁b再锁a的顺序获得锁。如下图所示: 产生死锁的原因? 可归结为如下两点: a. 竞争资源 系统中的资源可以分为两类:可剥夺资源,是指某进程在...转载 2020-10-25 18:16:39 · 239 阅读 · 0 评论 -
为什么说Java中只有值传递
对于初学者来说,要想把这个问题回答正确,是比较难的。在第二天整理答案的时候,我发现我竟然无法通过简单的语言把这个事情描述的很容易理解,遗憾的是,我也没有在网上找到哪篇文章可以把这个事情讲解的通俗易懂。所以,就有了我写这篇文章的初衷。这篇文章中,我从什么是方法的实际参数和形式参数开始,给你讲解为什么说Java中只有值传递。 辟谣时间...转载 2020-10-23 18:17:25 · 246 阅读 · 0 评论 -
递归调用过多导致的栈溢出问题说明
今天在排查一个导致程序奔溃的bug,经调试发现其中的原因:代码中使用到CTreeCtrl树控件,控件中有上千个节点,代码中为实现相关的应用,需要递归遍历整个树控件,从而导致栈溢出的问题。 那么过多的递归调用为什么会引起栈溢出呢?事实上,函数调用...转载 2020-10-23 18:10:25 · 2047 阅读 · 0 评论 -
有了基本类型为什么还要有包装类?
相信每一个刚走上互联网行业的小白,都在面试的时候被问过这个问题。这个问题的确不难,如何回答的有深度,有条理才是真正的考点。作为一位面试官,我给大家画个方向,分析下这个问题应该怎么回答。正文 这个问题的重心不仅仅在于考察对包装类存在合理性的认识,也在考察对基本数据类型存在意义的理解。 我们都知道在Java语言中,new一个对象存储在堆里,我们通过栈中的引用来使用这些对象。但是对于经常用到的一系列类型如int、boolean… 如果我们用new将其存储在堆里就不是很高效——特别是简单的小的变量。所以,同C转载 2020-10-22 13:44:25 · 444 阅读 · 0 评论 -
Java中基本数据类型和包装类型的区别
1、包装类是对象,拥有方法和字段,对象的调用都是通过引用对象的地址;基本类型不是 2、包装类型是引用的传递;基本类型是值的传递 3、声明方式不同: 基本数据类型不需要new关键字; &nbs...转载 2020-10-22 13:35:01 · 420 阅读 · 0 评论 -
并发volatile关键字如何保证可见性和有序性及底层实现原理
Volatile用法首先我们先了解一下volatile关键字的用法 ,volatile被喻为轻量级的"synchronized",它只是一个变量修饰符,只能用来修饰变量不能修饰方法和代码块。 经典的用法:双重校验锁实现单例 public class Singleton { private volatile static Singleton singleton; private Singleton (){} public static Singleton getSing转载 2020-10-20 18:25:58 · 955 阅读 · 0 评论 -
volatile有序性和可见性底层原理
文章目录 1、缓存一致性2、JMM3、volatile可见性原理1、lock前缀指令角度2、内存屏障角度 4、volatile有序性原理1、指令重排序2、内存屏障角度 5、happens-before规则6、as-if-serial语义1、数据依赖性2、as-if-serial语义 7、指令重排序面试题 1、缓存一致性 1、首先,编译之后Java代码会被编译成字节码.class文件,在运行时会被加载到JVM中,JVM会将.class转换为具体的CPU执行指令,CPU.转载 2020-10-20 18:19:54 · 863 阅读 · 0 评论 -
HashMap的负载因子为什么不设置为1或者0.5而是0.75
在Java基础中,集合类是很关键的一块知识点,也是日常开发的时候经常会用到的。比如List、Map这些在代码中也是很常见的。个人认为,关于HashMap的实现,JDK的工程师其实是做了很多优化的,要说所有的JDK源码中,哪个类埋的彩蛋最多,那我想HashMap至少可以排前五。 也正是因为如此,很多细节都容易被忽视,今天我们就来关注其中一个问题,那就是: 为什么HashMap的负载因子设置成0.75,而不是1也不是0.5?这背后到底有什么考虑? 大家千万不要小看这个问题,因为负载因子是HashMap中转载 2020-10-18 19:49:56 · 1103 阅读 · 0 评论