自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(591)
  • 收藏
  • 关注

原创 java面试-0324-synchronized怎么保证三性、可重入?

synchronized 使用监视器锁(monitor)实现互斥,同一时刻只有一个线程能持有锁并执行同步块/方法。进入/退出同步块时,JVM 插入内存屏障(隐含 Load 和 Store 屏障),禁止同步块内指令与外部重排序。进入 synchronized 块时,先清空工作内存中共享变量的值,使用共享变量时需要从主内存中重新读取最新值。synchronized锁对象有个计数器,线程获取锁后+1计数,线程执行完毕后-1,直到清零释放锁。其他线程尝试获取锁时会阻塞,等待锁释放后竞争锁,防止操作交错。

2025-11-03 09:49:07 314

原创 java面试-0323-synchronized关键字√方法和代码块锁对象区别?同步代码、静态同步方法原理?

都是基于监视器Monitor实现,线程执行同步代码块前会尝试获取监视器monitor,失败则阻塞等待锁释放,持有锁的线程休眠或阻塞时,其他线程需等待,除非异常触发锁释放。同步代码块原理:编译后产生字节码指令monitorenter和monitorexit,插入到同步代码块的开始位置、方法结束处和异常处。同步代码块synchronized (实例对象/this/xxx.class) {} 锁对象是实例对象/Class对象。非公平锁、悲观锁、可重入锁、互斥锁、保证原子性、可见性、有序性。

2025-11-03 09:48:36 253

原创 java面试-0321-volatile原理√

当处理器发现本地缓存失效后,就会从内存中重读该变量数据,即可以获取当前最新值(一次读取64字节缓存行)相当于一个内存屏障(一组处理指令),用来实现对内存操作的顺序限制。第一个操作是volatile读时,不管第二操作是什么,都不能重排序,确保 volatile 读之后的操作不会被编译器重排序到 volatile 读之前。第二个操作是volatile写时,不管第一操作是什么,都不能重排序,确保 volatile 写之前的操作不会被编译器重排序到 volatile 写之后。

2025-11-02 09:00:00 334

原创 java面试-0322-volatile与atomic变量区别?

volatile不能保证原子性。atomic变量可以保证原子性。

2025-11-02 09:00:00 199

原创 java面试-0320-volatile特性?怎么保证?场景?√

非阻塞性:依赖内存屏障而非锁,避免线程阻塞和上下文切换,性能优于synchronized。可见性:写操作刷新到主内存,读操作加载最新值(遵循 Happens-Before 规则)单例双重检查禁止重排序:修饰单例实例,禁止初始化时的指令重排序,确保线程安全。不保证复合操作的原子性(如 i++),需结合锁或原子类使用。有序性:通过内存屏障禁止volatile变量读/写重排序。多线程环境下的单次读写。状态标记位:如布尔变量停止线程。

2025-11-01 10:45:05 432

原创 java面试-0319-as-if-serial了解吗?单线程的程序一定是顺序的吗?

单线程程序可能发生指令重排,但 as-if-serial 保证~保证单线程情况下指令重排序后内存可见性问题和一致性问题。

2025-11-01 10:44:34 188

原创 java面试-0318-happens-before理解

线程终止(Thread Termination Rule)线程内操作 happens-before Thread.join()/isAlive() 检测。传递性(Transitivity) A happens-before B,B happens-before C,那么A happens-before C。线程启动(Thread Start Rule)Thread.start() happens-before 线程内操作。如果操作A happens-before 操作B,则A的结果对B可见。

2025-10-31 13:17:09 307

原创 java面试-0317-指令重排?

JMM 通过 Happens-Before 规则和同步机制控制重排序,确保多线程情况下指令重排序后内存可见性和一致性。为了提高性能,从源码到最终实际执行的指令序列经历3种重排序,有内存可见性问题和一致性问题。多级缓存和写缓冲导致读写操作在不同线程间看似乱序。编译器在不改变单线程语义下重排指令。CPU利用多核和流水线重排指令。

2025-10-31 13:16:39 190

原创 java面试-0316-JMM内存模型(Java Memory Model)概念?为什么线程要用自己的内存?

用来定义多线程中变量的访问规则的抽象模型,用来解决变量的可见性、有序性和原子性问题,确保线程安全。每条线程都有私有的本地内存,存储共享变量的副本,线程间无法访问彼此本地内存。指令重排:本地内存允许 CPU 和编译器优化指令顺序,提高性能。并发性能:避免多线程竞争主内存,减少同步开销和线程安全问题。读取时若本地副本过时,从主内存加载最新值。性能优化:本地内存速度快,提升执行效率。共享变量修改后通过同步机制刷新到主内存。线程读写共享变量时操作本地内存。共享变量存储在主内存中。

2025-10-30 16:37:15 459

原创 java面试-0315-父子线程怎么共享数据?原理?

Thread初始化时检查父线程的inheritableThreadLocals,若不为空,调用createInheritedMap复制到子线程的 inheritableThreadLocals。用InheritableThreadLocal。子线程创建时,复制父线程的 inheritableThreadLocals(ThreadLocalMap)到子线程。Thread t = new Thread() {//子线程。

2025-10-30 16:36:44 502

原创 java面试-0314-ThreadLocalMap为什么key设计成弱引用?内存泄露问题及解决方案?

保证ThreadLocal没有强引用时回收(ThreadLocalMap里面Entry的)key,ThreadLocal执行set、get、remove时会将key为null的Entry进行清理。通过 expungeStaleEntry 或 cleanSomeSlots。线程存活(如线程池),ThreadLocal回收后,Entry的value强引用未清理,导致内存泄漏或数据污染 (下次访问时值不变)使用后在finally 块中调用 remove() 清理 Entry。

2025-10-29 09:23:50 171

原创 java面试-0313-ThreadLocalMap怎么解决Hash冲突?如何计算hash?扩容机制?

触发:元素数 ≥ 阈值(table.length * 2/3)时,调用 rehash() 清理过期 Entry,若仍超阈值(threshold - threshold/4),触发 resize():创建2倍容量新数组,遍历旧数组,重新计算哈希值(开放定址法),插入新数组,清理过期 Entry。哈希值从0每次递增 0x61c88647(斐波那契散列增量,基于黄金分割约1.618),确保哈希分布均匀,减少冲突。

2025-10-29 09:23:20 329

原创 java面试-0312-ThreadLocal理解?场景?原理?

ThreadLocal通过(静态内部类)ThreadLocalMap实现线程间的数据隔离,ThreadLocalMap存储在Thread的threadLocals字段中。用户信息上下文:控制层拦截请求的 token 并解析用户信息(如 UserContext)存入ThreadLocal,方便在其他层访问。事务管理:存储事务上下文(如 Spring @Transactional),确保线程内事务在同一个线程中传播和一致性。数据库连接:维护线程独享的 Connection(如 JDBC),避免线程间冲突。

2025-10-28 18:04:05 231

原创 java面试-0311-java中线程通信方式?

CountDownLatch、CyclicBarrier、Semaphore等并发工具类。Thread.join、interrupt()和isInterrupted()

2025-10-28 18:03:34 156

原创 java面试-0309-并发编程三要素?

原子性:一个操作或一组操作要么全部执行成功,要么完全不执行,不会被其他线程干扰。可见性:一个线程对共享变量的修改,其他线程能立即知道。有序性:程序执行的顺序按照代码的先后顺序执行。

2025-10-27 09:00:00 178

原创 java面试-0310-线程安全概念?原因?如何保证线程安全?线程同步实现方式?

线程同步:互斥同步:synchronized、ReentrantLock、ReadWriteLock、协作同步:Semaphore、CountDownLatch、CyclicBarrier、Condition,适合多线程修改共享数据,但可能有性能开销。并发工具类:CountDownLatch、CyclicBarrier、Semaphore、Fork/Join框架等工具类。线程局部变量(ThreadLocal):为每个线程提供独立变量副本,避免竞争,适合线程隔离数据(如会话状态)

2025-10-27 09:00:00 295

原创 0307-java线程上下文切换概念?

操作系统在多个线程之间切换执行时,保存当前线程的执行状态并恢复另一个线程的执行状态的过程。

2025-10-26 09:00:00 191

原创 java面试-0308-守护/用户线程区别?

区别:程序运行完毕,JVM会等待用户线程完成后关闭,但不会等待守护线程完成,因此守护线程中不能用finally确保关闭或清理资源。Daemon:运行在后台为前台线程服务。如垃圾回收线程、守护线程的子线程。User:运行在前台执行具体任务,如main线程。

2025-10-26 09:00:00 208

原创 java面试-java线程状态及转换?

runnnable:运行状态,java将操作系统的就绪和运行两种状态统称为运行中。waiting:等待状态,线程等待其他线程通知或者中断。time_waiting:超时等待状态,在指定时间返回。terminated:终止状态,线程执行完毕。blocked:阻塞状态,线程阻塞与锁。new:初始状态,线程被创建。

2025-10-25 09:01:05 349

原创 java面试-0305-java线程调度方法?sleep()和wait()区别?

wait():阻塞挂起当前线程,直到其他线程调用motify/notifyAll或者线程的interrupt()方法,抛出InterruptedException异常才返回。interrupt():中断线程并设置中断标志为true,使wait、join、sleep抛出InterruptedException,不停止线程。notify()/notifyAll():随机唤醒一个/唤醒所有在共享变量上调用wait系列方法后被挂起的线程。interrupted():检测线程中断,清除中断标志位。

2025-10-25 09:00:35 425

原创 java面试-0304-线程运行时异常会怎么样?主线程能捕获子线程异常吗?

主线程可用Thread.setDefaultUncaughtExceptionHandler(new MyUncaughtExceptionHandler())捕获子线程异常。用ExecutorService 的 submit 方法运行任务,Future.get() 捕获子线程的异常。如果线程在终止前未正确清理资源(如文件句柄、数据库连接),可能导致资源泄漏。如果异常没有捕获,线程会停止执行并释放持有的对象监视器。

2025-10-24 08:36:47 243

原创 java面试-0303-java停止线程方法?

使用volatile布尔变量作为标志位/interrupt方法中断线程。在线程的run方法中while检查标志位\中断状态。Thread.currentThread().isInterrupted()) {//响应中断。// 线程被中断时的清理代码。// 线程结束前的清理代码。

2025-10-24 08:36:17 201

原创 java面试-0302-创建线程方式?run和start方法区别?调用2次start会怎么样

JVM 检测到线程状态不是New(threadStatus!= 0),抛出IllegalThreadStateException,线程不会再次启动。System.out.println("结果 " + futureTask.get());//调用后会阻塞主进程的继续往下执行。继承Thread并重写run方法;实现Runnable接口并实现run方法;start方法使线程进入就绪状态并在得到CPU时间后执行run方法;run方法普通方法调用,不会创建新线程。通过线程池(ExecutorService)

2025-10-23 08:38:19 476

原创 java面试-0301-并发/并行/串行、进程/线程区别?

线程:CPU 调度的最小单位,进程内的执行单元,共享进程资源(内存、文件句柄),但有独立栈、程序计数器和寄存器。进程:程序运行和资源分配的基本单位,拥有独立虚拟地址空间、内存、文件句柄等,进程间通过管道、消息队列通信。并发:多个任务在同一时间段交替执行,通过时间片轮转或任务切换,看似同时进行,强调逻辑同时性。并行:多个任务在同一时刻同时执行,依赖多核 CPU 或多机器,强调物理同时性。串行:任务顺序执行,无交叠或同时进行。

2025-10-23 08:37:48 309

原创 java面试-0220-HashSet、LinkedHashSet、TreeSet实现?和ArrayList区别?

键可为 null,线程不安全,查询 O(1)。基于 TreeMap(红黑树),按自然顺序(Comparable)或 Comparator 排序,不重复。基于 HashMap(键存元素,值固定为 Object),无序、不重复。基于动态数组,元素有序(按插入顺序),允许重复和 null 值。基于 LinkedHashMap,维护双向链表,有序,不重复。按索引访问,线程不安全。查询 O(1),插入/删除 O(n),键不可为 null,线程不安全,查询 O(log n).键可为 null,线程不安全。

2025-10-22 14:41:36 485

原创 java面试-0219-ConcurrentHashMap为什么比Hashtable效率高/区别?

ConcurrentHashMap (JDK8):链表超8转为红黑树,查询 O(log n),适合高冲突场景。ConcurrentHashMap:用CAS + synchronized锁单桶,锁粒度小,并发度高。Hashtable:synchronized 锁定整个 Map。ConcurrentHashMap:无锁读,volatile保证可见性,并发度高。Hashtable:扩容锁整个Map,阻塞所有操作。Hashtable:读操作锁整个Map,并发度低。Hashtable:仅链表,查询 O(n)。

2025-10-22 14:41:05 357

原创 java面试-0218-jdk8中ConcurrentHashMap实现?put/get方法执行过程?怎么保证可见性?

CAS用于无锁更新(如数组初始化或桶头节点替换),若失败或涉及复杂操作(如链表插入、红黑树调整)则synchronized 锁定单个桶,锁粒度更小,保证原子性和线程安全。1.计算哈希值(高低16位异或,& 0x7fffffff 确保正数),定位桶索引(table.length - 1) & hash。2.如果数组未初始化,通过CAS初始化,如果桶为空,通过CAS插入新节点。否则synchronized锁桶,链表插入(key 相同覆盖,否则尾插)或红黑树操作。计算哈希值,定位桶索引。

2025-10-21 09:10:52 617

原创 java面试-0217-jdk7中ConcurrentHashMap实现?put/get方法执行过程?

Segment 是 ReentrantLock,管理一个 HashEntry 数组,HashEntry用于存储键值对。线程安全:分段锁(默认 16 个 Segment),操作只锁住对应 Segment,允许不同 Segment 并发操作。遍历链表,key 相同则更新 value(volatile 确保可见性),否则头插法插入新节点。无锁读取,volatile(HashEntry 的 value 和 next)保证可见性。遍历链表,比较哈希值和 key(equals),返回 value 或 null。

2025-10-21 09:10:22 349

原创 java面试-0216-HashMap和LinkedHashMap、TreeMap、HashTable√、ConcurrentHashMap区别?

键不可为 null,基于 Node 数组 + 链表/红黑树(链表超 8 转为红黑树),高并发性能优于Hashtable。线程安全,JDK 7 用分段锁(Segment),JDK 8 用 CAS + synchronized(锁单桶)。继承 HashMap,维护双向链表,记录插入顺序或访问顺序(accessOrder=true)。键不可为 null,默认容量 11,扩容 2 倍 + 1,锁粒度大,性能较低。键可为 null,线程不安全,默认容量 16,扩容 2 倍。

2025-10-20 19:58:56 295

原创 java面试-0215-HashMap有序吗?Comparable和Comparator区别?集合如何排序?

List: Collections.sort(list)(需元素实现 Comparable)或 Collections.sort(list, comparator)(自定义 Comparator)Map:TreeMap 按键自动排序(基于 Comparable 或构造时传入 Comparator)Set:TreeSet 自动排序(基于 Comparable 或构造时传入 Comparator)独立类实现,compare(T o1, T o2) 方法比较两个对象。灵活定义外部排序规则,无需修改原类。

2025-10-20 19:58:26 266

原创 java面试-0214-HashMap在jdk1.8的优化?为什么?

JDK 1.8 利用数组长度为 2 的幂次方特性,通过简单的位运算(hash & oldCapacity)确定节点的新索引(保持不变或原索引加旧数组长度),结合高低位链表分离机制批量转移节点,大幅提高扩容效率。JDK 1.8 改为尾插法,插入节点时追加到链表尾部,扩容时保持链表顺序,避免环形链表问题,提高多线程环境下的稳定性和扩容效率。JDK 1.8 优化为仅 1 次移位和 1 次异或(高 16 位与低 16 位异或),在保持低冲突率的同时降低计算开销,提高散列效率。

2025-10-19 08:00:00 314

原创 操作系统的概念和作用

2025-10-19 08:00:00 423

原创 java面试-0212-hashMap解决哈希冲突的方法?解决hash冲突的常用方法?hash冲突后,将元素放到链表头还是尾√/HashMap为什么不是线程安全的?

因为多线程哈希冲突时没加锁,计算出来的位置可能被其他线程的put覆盖,正常应该形成链表;在扩容过程中,线程 1 正在转移节点到新数组,线程 2 同时执行 put 操作,可能将新元素插入到旧数组或新数组,导致部分元素未被正确转移,最终丢失。线程1执行put时,因为元素个数超出阈值而导致出现扩容,扩容期间线程1被挂起,此时线程2执行get可能为null,因为元素还没有迁移完成。链地址法,哈希冲突时使用链表将冲突的元素串起来(HashMap),链表过长时转为红黑树。再哈希法:哈希冲突时使用另外一种哈希算法。

2025-10-18 08:30:00 178

原创 java面试-0211-HashMap初始容量计算?扩容触发条件?容量为什么是2的幂次方?扩容机制?扩容后的位置计算?为什么负载因子是0.75?

充分利用数组空间,减少hash冲突,如果length不是2的次幂,比如15,length–1=14,二进制为1110,h与操作最后一位都为0,0001,0011,0101,1001,1011,0111,1101这几个位置不能存放元素了,此时数组可用位置变少。初始容量默认16,范围:16-2^30,可指定,太大浪费内存,太小可能因扩容性能下降,因为扩容时要创建2倍容量数组并插入元素。太低,hash冲突减少,查找快,但频繁扩容增加 rehashing 开销,浪费空间。扩容时无需重新计算哈希值,~

2025-10-18 08:00:00 182

原创 java面试-0209-HashMap实现原理?put/get方法执行过程?

jdk1.8HashMap的底层数据结构是Node数组+链表+红黑树​向HashMap添加键值对时,步骤如下获取元素时用哈希函数计算键key的哈希值,通过(n - 1) & hash计算数组下标,判断内部数组对应下标数据的key与key是否相等,是则直接返回,否则,判断节点是否为树节点,是则查找红黑树直到找到key相等的,否则遍历链表查找key相等的值,没有则返回null

2025-10-17 08:00:00 156

原创 java面试-0210-HashMap怎么判断key相等?怎么计算hash、设计原因?为什么是亦或而不是与?数组位置?不用hashCode方法直接计算数组位置?经典计算hash的方法?

使数据分布更均匀,减少hash冲突,hashCode的高位参与运算增加低位的随机性。0 : (h = key.hashCode()) ^ (h >>> 16) key的hashCode低16位与高16位异或。数字分析法:取key的某些数字(如十位)选择分布均匀的部分作为哈希值。哈希值是否相等(key.hash==),key引用相等(key==),或者key的equals相等。key.hashCode() 返回 int(-2³¹ ~ 2³¹-1),可能为负数或超出数组范围。

2025-10-17 08:00:00 196

原创 java面试-0213-HashMap为什么不用二叉树或者平衡树呢?为什么链表要转红黑树/不直接用红黑树?链表转换为红黑树阈值是8?红黑树转链表阈值是6?

红黑树节点的大小大概是链表节点的两倍,(因包含左右子节点、父节点和颜色字段),且维护开销较高(需旋转和调整颜色)。基于统计分析和性能测试选择的折中点。负载因子0.75时,服从泊松分布,当单个桶内的元素达到8个的概率小于千万分之一,红黑树将查询从 O(n) 优化为 O(log n)如果插入的数据是有序的,普通二叉搜索树会退化为链表,查询、插入和删除操作复杂度从 O(log n) 退化为 O(n)。平衡二叉树(如AVL树)在插入和删除时要多次旋转和更新平衡因子,而红黑树只需较少的旋转和调整颜色。

2025-10-16 09:23:11 1006

原创 java面试-0208-java中的CopyOnWriteArrayList?

写操作在复制数组上执行,再将原数组的引用指向新数组。内存占用大,性能开销大。读写不竞争,适合读多写少。

2025-10-16 09:19:59 376

原创 java面试-0207-List怎么序列化?为什么用transient修饰数组?

通过ObjectOutputStream和ObjectInputStream的readObject、writeObject方法或者json。用transient修饰存储元素的elementData数组,避免序列化多余null值。

2025-10-16 09:19:29 422

原创 java面试-0206-ArrayList扩容机制?和LinkedList区别?

ArrayList查找快(数组索引:偏移量查找O(1)),增删慢(扩容可能需要复制数组和移动元素O(n)),适合末尾添加、随机访问场景,LinkedList查找慢(移动指针从头或从尾遍历O(n))、增删快(改变前后驱节点指向O(1)),适合中间插入删除,顺序访问场景。ArrayList基于数组,内部使用 Object[] 存储元素,内存空间连续,可能存在空闲空间,存在一定空间浪费。ArrayList支持随机访问,通过下标获取元素,实现了RandomAccess接口,LinkedList不支持,没有实现。

2025-10-15 12:30:03 320

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除