电子商务网站建设的核心是,seo西安,采购平台官网,建设项目查询还有三天面一个JAVA软件开发岗#xff0c;之前完全没学过JAVA#xff0c;整理一些面经......
大佬整理的#xff1a;Java面试必备八股文_-半度的博客-CSDN博客
另JAVA学习资料#xff1a;Java | CS-Notes
Java 基础Java 容器Java 并发Java 虚拟机Java IO目录
int和Inte…还有三天面一个JAVA软件开发岗之前完全没学过JAVA整理一些面经......
大佬整理的Java面试必备八股文_-半度的博客-CSDN博客
另JAVA学习资料Java | CS-Notes
Java 基础Java 容器Java 并发Java 虚拟机Java IO目录
int和Integer的区别
包装类及其作用
HashMap
Java HashMap 常用方法如下表
HashMap为什么线程不安全如何保障HashMap线程安全
Key为什么不重复?哈希冲突...
JVM(Java虚拟机)运行时数据区怎么分
JMMJava内存模型
1.什么是JMM
2.JMM的三大特性原子性、可见性、有序性
3.关于同步的规定
4.解释说明
JMM中的八种操作
Java有哪些锁syn底层是什么
Synchronized 同步锁 JVM、JRE和JDK的关系
JVMJava虚拟机(Java Virtual Machine)Java程序需要运行在虚拟机上不同的平台都有自己的虚拟机所以Java语言实现了跨平台。JREJava运行环境(Java Runtime Environment)指的是Java的运行时环境包括需要的大量的类库和Java的虚拟机。JDKJava开发工具包Java Development Kit提供了Java的开发环境和运行环境。
int和Integer的区别
1、数据类型不同int 是基础数据类型而 Integer 是包装数据类型 2、默认值不同int 的默认值是 0而 Integer 的默认值是 null 3、内存中存储的方式不同int 在内存中直接存储的是数据值而 Integer 实际存储的是对象引用当 new 一个 Integer 时实际上是生成一个指针指向此对象 4、实例化方式不同Integer 必须实例化才可以使用而 int 不需要 5、变量的比较方式不同int 可以使用 来对比两个变量是否相等而 Integer 一定要使用 equals 来比较两个变量是否相等。 来源Java基础 - Integer和int的区别_程序员老石的博客-CSDN博客_integer和int的区别
包装类及其作用
因为Java 的设计理念是一切皆是对象在很多情况下需要以对象的形式操作比如 hashCode() 获取哈希值或者 getClass() 获取类等。
包装类的作用在 Java 中每个基本数据类型都对应了一个包装类包装类的存在解决了基本数据类型无法做到的事情泛型类型参数、序列化、类型转换、高频区间数据缓存等问题。
Java基本数据类型包装类型4 种整型byte: 占用1个字节取值范围-128 ~ 127Byteshort: 占用2个字节取值范围-215 ~ 215-1Shortint占用4个字节取值范围-231 ~ 231-1Integerlong占用8个字节Long2 种浮点类型float占用4个字节Floatdouble占用8个字节Double字符类型char: 占用2个字节Character真假类型boolean占用大小根据实现虚拟机不同有所差异Boolean
引用数据类型String 类 接口 抽象类 枚举 数组
HashMap
HashMap 是一个散列表它存储的内容是键值对(key-value)映射。
HashMap 实现了 Map 接口根据键的 HashCode 值存储数据具有很快的访问速度最多允许一条记录的键为 null不支持线程同步。
HashMap 是无序的即不会记录插入的顺序。
HashMap 继承于AbstractMap实现了 Map、Cloneable、java.io.Serializable 接口。
HashMap 的 key 与 value 类型可以相同也可以不同可以是字符串String类型的 key 和 value也可以是整型Integer的 key 和字符串String类型的 value。
HashMap 中的元素实际上是对象一些常见的基本类型可以使用它的包装类。
HashMap 类位于 java.util 包中使用前需要引入它语法格式如下
import java.util.HashMap; // 引入 HashMap 类
以下实例我们创建一个 HashMap 对象 Sites 整型Integer的 key 和字符串String类型的 value
HashMapInteger, String Sites new HashMapInteger, String();
Java HashMap 常用方法如下表
更多语法见Java HashMap | 菜鸟教程
方法描述clear()删除 hashMap 中的所有键/值对clone()复制一份 hashMapisEmpty()判断 hashMap 是否为空size()计算 hashMap 中键/值对的数量put()将键/值对添加到 hashMap 中putAll()将所有键/值对添加到 hashMap 中putIfAbsent()如果 hashMap 中不存在指定的键则将指定的键/值对插入到 hashMap 中。remove()删除 hashMap 中指定键 key 的映射关系containsKey()检查 hashMap 中是否存在指定的 key 对应的映射关系。containsValue()检查 hashMap 中是否存在指定的 value 对应的映射关系。replace()替换 hashMap 中是指定的 key 对应的 value。replaceAll()将 hashMap 中的所有映射关系替换成给定的函数所执行的结果。get()获取指定 key 对应对 valuegetOrDefault()获取指定 key 对应对 value如果找不到 key 则返回设置的默认值forEach()对 hashMap 中的每个映射执行指定的操作。entrySet()返回 hashMap 中所有映射项的集合集合视图。keySet()返回 hashMap 中所有 key 组成的集合视图。values()返回 hashMap 中存在的所有 value 值。merge()添加键值对到 hashMap 中compute()对 hashMap 中指定 key 的值进行重新计算computeIfAbsent()对 hashMap 中指定 key 的值进行重新计算如果不存在这个 key则添加到 hasMap 中computeIfPresent()对 hashMap 中指定 key 的值进行重新计算前提是该 key 存在于 hashMap 中。
HashMap为什么线程不安全如何保障HashMap线程安全
Hashmap如何保证线程安全_马腾.♔的博客-CSDN博客_hashmap如何保证线程安全
在JDK1.7中HashMap采用头插法插入元素因此并发情况下会导致环形链表产生死循环。 虽然JDK1.8采用了尾插法解决了这个问题但是并发下的put操作也会使前一个key被后一个key覆盖。 由于HashMap有扩容机制存在也存在A线程进行扩容后B线程执行get方法出现失误的情况。
扩容容量必须是 2 的幂次方、最大容量为 1 30 、若当前数据/总数据容量加载因子Hashmap将执行扩容操作默认加载因子为0.75
线程安全Map的三种方法 Key为什么不重复?哈希冲突...
引入哈希表的目的是使查找和处理一个数时不经过比较让时间复杂度保持在O(1)这样就是为了加快查询效率这里我们需要了解有关如何设计哈希函数以及尽可能地避免哈希冲突的方法。
JVM(Java虚拟机)运行时数据区怎么分
JVM: Java Virtual Machine(Java虚拟机)是用来执行Java字节码二进制的形式的虚拟机计算机。JVM是运行在操作系统之上的与硬件没有任何关系。
JVM - 运行时数据区详细篇_星辰与晨曦的博客-CSDN博客
JVM——运行时数据区域_喵喵超牛的博客-CSDN博客_jvm运行时数据区 如上图运行时数据区包括五个部分蓝色区域多个线程共享黄色区域每一个线程独占在java API 一个java虚拟机就对应一个Runtime类一个Runtime就对应一个运行时数据区。
程序计数器Program Counter Register程序计数器是一块较小的内存空间可以把它看作是当前线程所执行的字节码的行号指示器。Java虚拟机栈Java Virtual Machine Stack描述的是Java方法执行的内存模式每个方法在执行的同时都会创建一个线帧Stack Frame用于存储局部变量表、操作数栈、动态链接、方法出口等信息每个方法从调用直至执行完成的过程都对应着一个线帧在虚拟机栈中入栈到出栈的过程。本地方法栈Native Method Stack与虚拟机栈的作用一样只不过虚拟机栈是服务于Java方法的而本地方法栈是为虚拟机调用Native本地方法服务的。Java堆Java Heap是Java虚拟机中内存最大的一块是被所有线程所共享的在虚拟机启动的时候就创建好了Java堆唯一的目的就是存放对象的实例几乎所有的对象实例都是在这里分配内存的。方法区Method Area也叫元空间方法区就是用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译后的代码等数。方法区是很重要的系统资源是硬盘和CPU的中间桥梁承载着操作系统和应用程序的实时运行。
栈是运行时的单位堆是存储时的单位
JMMJava内存模型
JMMJava内存模型详解_加油进大厂的博客-CSDN博客_jmm
1.什么是JMM
JMM 是Java内存模型 Java Memory Model。它本身只是一个抽象的概念并不真实存在它描述的是一种规则或规范是和多线程相关的一组规范。通过这组规范定义了程序中对各个变量包括实例字段静态字段和构成数组对象的元素的访问方式。每个JVM 的实现都要遵守这样的规范有了JMM规范的保障并发程序运行在不同的虚拟机上时得到的程序结果才是安全可靠可信赖的。如果没有JMM 内存模型来规范就可能会出现经过不同 JVM 翻译之后运行的结果不相同也不正确的情况。
计算机在执行程序时每条指令都是在CPU中执行的。而执行指令的过程中势必涉及到数据的读取和写入。由于程序运行过程中的临时数据是存放在主存物理内存当中的这时就存在一个问题由于CPU执行速度很快而从内存读取数据和向内存写入数据的过程跟CPU执行指令的速度比起来要慢的多硬盘 内存 缓存cache CPU。因此如果任何时候对数据的操作都要通过和内存的交互来进行会大大降低指令执行的速度。因此在CPU里面就有了高速缓存。也就是当程序在运行过程中会将运算需要的数据从主存复制一份到CPU的高速缓存当中那么CPU进行计算时就可以直接从它的高速缓存中读取数据或向其写入数据了。当运算结束之后再将高速缓存中的数据刷新到主存当中。
JMM 抽象出主存储器Main Memory和工作存储器Working Memory两种。
主存储器是实例对象所在的区域所有的实例都存在于主存储器内。比如实例所拥有的字段即位于主存储器内主存储器是所有的线程所共享的。工作存储器是线程所拥有的作业区每个线程都有其专用的工作存储器。工作存储器存有主存储器中必要部分的拷贝称之为工作拷贝Working Copy。
所以线程无法直接对主内存进行操作此外线程A想要和线程B通信只能通过主存进行。
2.JMM的三大特性原子性、可见性、有序性
1.原子性 一个或多个操作要么全部执行要么全部不执行执行的过程中是不会被任何因素打断的。
2.可见性 只要有一个线程对共享变量的值做了修改其他线程都将马上收到通知立即获得最新值。
3.有序性 有序性可以总结为在本线程内观察所有的操作都是有序的而在一个线程内观察另一个线程所有操作都是无序的。前半句指 as-if-serial 语义线程内似表现为串行后半句是指“指令重排序现象”和“工作内存与主内存同步延迟现象”。处理器为了提高程序的运行效率提高并行效率可能会对代码进行优化。编译器认为重排序后的代码执行效率更优。这样一来代码的执行顺序就未必是编写代码时候的顺序了在多线程的情况下就可能会出错。
在代码顺序结构中我们可以直观的指定代码的执行顺序, 即从上到下按序执行。但编译器和CPU处理器会根据自己的决策对代码的执行顺序进行重新排序优化指令的执行顺序提升程序的性能和执行速度使语句执行顺序发生改变出现重排序但最终结果看起来没什么变化在单线程情况下。
有序性问题 指的是在多线程的环境下由于执行语句重排序后重排序的这一部分没有一起执行完就切换到了其它线程导致计算结果与预期不符的问题。这就是编译器的编译优化给并发编程带来的程序有序性问题。
Java 语言提供了 volatile 和 synchronized 两个关键字来保证线程之间操作的有序性volatile 是因为其本身包含“禁止指令重排序”的语义synchronized 是由“一个变量在同一个时刻只允许一条线程对其进行 lock 操作”这条规则获得的此规则决定了持有同一个对象锁的两个同步块只能串行进入。
3.关于同步的规定
线程解锁前必须把共享变量的值刷新回主内存。线程加锁前必须将主内存的最新值读取到自己的工作内存。加锁解锁是同一把锁。
4.解释说明
在JVM中栈负责运行主要是方法堆负责存储比如new的对象。由于JVM运行程序的实体是线程而每个线程在创建时JVM都会为其创建一个工作内存有些地方称为栈空间工作内存是每个线程的私有数据区域。而JAVA内存模型中规定所有变量都存储在主内存中主内存是共享内存区域所有线程都可以访问。
但线程对变量的操作读取赋值等必须在自己的工作内存中进行。首先要将变量从主内存拷贝到自己的工作内存空间然后对变量进行操作操作完成后再将变量写回到主内存。由于不能直接操作主内存中的变量各个线程的工作内存中存储着主内存中的变量副本因此不同的线程之间无法直接访问对方的工作内存线程间的通信传值必须通过主内存来完成。
JMM中的八种操作
为了支持 JMMJava 定义了8种原子操作用来控制主存与工作内存之间的交互
read 读取作用于主内存将共享变量从主内存传送到线程的工作内存中。load 载入作用于工作内存把 read 读取的值放到工作内存中的副本变量中。store 存储作用于工作内存把工作内存中的变量传送到主内存中。write 写入作用于主内存把从工作内存中 store 传送过来的值写到主内存的变量中。use 使用作用于工作内存把工作内存的值传递给执行引擎当虚拟机遇到一个需要使用这个变量的指令时就会执行这个动作。assign 赋值作用于工作内存把执行引擎获取到的值赋值给工作内存中的变量当虚拟机栈遇到给变量赋值的指令时就执行此操作。lock锁定 作用于主内存把变量标记为线程独占状态。unlock解锁 作用于主内存它将释放独占状态。
Java有哪些锁syn底层是什么
java中都有哪些锁?_羡羡ˇ的博客-CSDN博客
Java中常见的各种锁-超全面_【JAVA】玩家的博客-CSDN博客
Synchronized 同步锁
Java提供的一种原子性内置锁(关键字)用于解决多个线程间访问资源同步性问题保证其修饰的方法或代码块任意时刻只能有一个线程访问synchronized它可以把任非NULL 的对象当作锁。它属于独占式悲观锁同时属于可重入锁。每个对象都可以使用它当作同步监视器, 当线程进入使用Synchronized修饰的代码块中会自动获取内部锁 , 此时其他线程想要访问此同步代码时只能被阻塞, 等待锁的释放(前一个线程执行完, 或者出现异常,调用了wait()方法等), 在进入synchronized会从 主内存把变量读取到自己工作内存在退出的时候会把工作内存的值写入到主内存保证了原子性。
synchronized的实现是通过字节码指令完成的 , 我们可以通过反编译去看具体的底层实现。 代码块的同步是利用monitorenter和monitorexit这两个字节码指令。在虚拟机执行到monitorenter指令时首先要尝试获取对象的锁。 当前线程拥有了这个对象的锁把锁的计数器1当执行 monitorexit指令时将模计数器-1当计数器为 0 时锁就被释放了。
另外synchronized 通过在对象头设置标记达到了获取锁和释放锁的目的。