当前位置: 首页 > news >正文

java开发面试题(提高篇)

java开发面试题

  • 一、API扩展
    • (1) synchronized关键字底层锁升级是怎样实现的
    • (2)volatile关键字是什么
    • (3)IO和NIO的区别
    • (4) HashMap的put操作流程是怎么样的
    • (5)说说你对ThreadLocal的理解
  • 二、JVM技术
    • (1)JVM的构成
    • (2)JVM堆的构成和分配内存的过程
    • (3) 内存中方法和变量存在位置
    • (4)什么是内存泄露以及导致的原因
    • (5)四大引用类型的GC回收特点是什么
  • 三、redis
    • (1)redis是什么
    • (2)基础数据类型有哪些
    • (3)什么是缓存穿透及解决方案
    • (4)什么是缓存雪崩及解决方案

一、API扩展

(1) synchronized关键字底层锁升级是怎样实现的

java中,锁是一种用于线程同步的机制,为了提高性能,就那些锁升级操作。
1.偏向锁:当一个线程获取锁时,会在对象头部记录该线程的ID,并标记为偏向锁,此后再次执行相同线程请求锁的操作,就可以直接获得锁
2.轻量级锁(自旋锁):多个线程竞争同一个锁时,偏向锁就会升级为轻量级锁。轻量级锁使用CAS(比较-交换) 操作来实现
将对象头部的标记字段修改为指向线程私有的锁记录。如果CAS操作成功,表示当前线程获取了锁。
3.重量级锁:当多个线程竞争同一个锁并且轻量级锁获取失败,会升级为重量级锁,依赖于操作系统的底层同步机制。会导致线程阻塞和切换,且性能开销较大,重量级锁会让未获取到锁的线程进入阻塞状态。一旦锁被释放,操作系统会唤醒其中一个等待的线程,以此来解决竞争问题

(2)volatile关键字是什么

  1. 可见性:保证了变量的可见性,当修改此变量的值时,其他线程可以立即看到修改后的值,不会使用缓存中的旧值。
  2. 禁止指令重排序:指令重排序是编译器和处理器为了提高执行效率而进行的操作,可能会导致多线程程序出现问题。
  3. 不保证原子性:如果一个操作涉及到多个步骤,且需要保证原子性的话,还需要使用其他的同步手段:synchronized关键字等

(3)IO和NIO的区别

1.阻塞与非阻塞
IO是阻塞的,也称为同步模型。如果没有数据可读或无法立即写入,线程会被阻塞;相反,NIO是非阻塞(异步)
2.缓冲
IO使用字节流和字符流,通常用缓冲流提供缓冲功能,NIO的Channel和Buffer提供内置缓冲功能。
3.数据处理方式
IO是以流为基础的,每次读取一个或多个字节或字符。NIO是以缓冲区(Buffer)为基础的,可以一次读取或写入过个数据。
4.选择器
NIO中的selector提供多路复用的功能,一个线程处理多个Channel的IO操作。这种机制允许同时监听多个输入流,只有在有数据可读或可写时才会被唤醒。

(4) HashMap的put操作流程是怎么样的

1.计算键的哈希值:通过hashCode()方法计算,键对象转换为整数计算出来哈希值,将键映射到哈希表的索引位置
2.映射哈希值到数组索引位置,进行与操作(hash& (length -1))
3.检查数组位置是否已经存在元素:为空表示没有冲突,直接将值放入
4.冲突处理:如果该位置已经存在元素,需要进行冲突处理。HashMap才用拉链法来解决冲突,找到相同的健泽更新对应的值。
5.动态扩容:插入键值对后,判断是否需要扩容,当前元素数量大于等于负载因子乘以容量,则需要扩容。

(5)说说你对ThreadLocal的理解

ThreadLocal是一个Java中的线程局部变量。主要是用来为每个线程提供一个独立的变量副本,每个线程都可以独立地操作自己的副本互不干扰。

  1. 线程隔离:都有独立的副本,线程之间的变量不会相互冲突,可以避免数据竞争和线程安全问题。
  2. 解决共享资源问题:多个线程需要访问同一个变量时,可以使用ThreadLocal来解决,无需使用锁或者同步机制。
  3. 垃圾回收:使用ThreadLocalMap来存储每个线程的变量副本,键是ThreadLocal实例本身,值是该线程的变量副本。线程结束后,线程本地变量会自动被回收,不会造成内存泄漏。

二、JVM技术

(1)JVM的构成

1.类加载子系统:负责将类读到内存,校验类的合法性、对类进行初始化
2.运行时数据区:方法区、堆区、栈区、计数器,负责存储类信息、对象信息、执行逻辑
3.执行引擎:负责从指定地址对应的内存中读取数据然后解释执行以及垃圾回收
4.本地库接口:负责实现java语言与其他编程语言的协同

(2)JVM堆的构成和分配内存的过程

主要用于创建JAVA对象,由年轻代老年代构成,年轻代又分Eden 伊甸园区和两个幸存者区

1.编译器通过逃逸分析确定对象是栈还是堆上分配
2.如果是堆上分配,首先检测是否可在TLAB(线程本地分配缓冲区)上直接分配
3.如果TLAB上无法直接分配则在Eden加锁区进行分配
4.如果Eden区无法存储对象,则执行Yong GC
5.如果Yong GC之后 还不足以存储对象,则直接分配在老年代

(3) 内存中方法和变量存在位置

方法区:实例方法和静态方法,静态变量(都是属于类属性)
:实例变量(属于对象属性)
:局部变量(属于方法内部变量),调用方法时会获取到栈中进行执行

(4)什么是内存泄露以及导致的原因

程序运行时,动态分配的内存空间,在使用完毕后未得到释放,结果一直占用着内存单元,这个现象称为内存泄露
原因:

  1. 大量使用静态变量
  2. IO或连接资源没及时关闭
  3. 内部类的使用方式存在问题
  4. ThreadLocal应用不当,没有remove操作
  5. 缓存应用不当(尽量不要使用强引用–>对象类型定义的变量)

(5)四大引用类型的GC回收特点是什么

按照内存中的生命力强弱分出了四大引用类型,按强到弱分别是强引用、软引用(SoftReference)、弱引用(WeakReference)、虚引用

  1. 强引用
    即使内存溢出也不会销毁
Object o1=new Object();//这里的o1就是强引用
  1. 软引用
    内存不足时会被销毁
SoftReference<Object> sr=new SoftReference<Object>(new Object());//sr为软引用​
sr.get();//获取引用的对象
  1. 弱引用
    在GC触发时被销毁
WeakReference<Object> sr=new WeakReference<Object>(new Object());//sr为弱引用
  1. 虚引用
    相当于没有被引用,主要是用来记录被销毁的对象,当这个虚引用的对象被销毁时,此引用会存储到引用队列
ReferenceQueue<Object> referenceQueue=new ReferenceQueue<Object>();PhantomReference<Object> sr=new PhantomReference<Object>(new Object(),referenceQueue);//sr为虚引用

三、redis

(1)redis是什么

redis是一个使用C语言编写的高性能内存数据库,用键值对结构存储数据,一般用来做缓存、消息队列、分布式锁、同事支持事务、持久化等

(2)基础数据类型有哪些

  1. String 字符串
  2. list 列表
  3. hash 字典
  4. set 集合
  5. zset 有序列表

(3)什么是缓存穿透及解决方案

当访问一个缓存和数据库都不存在的key时,请求会直接打在数据库上,这时缓存就像被穿透了一样,起不到作用,加入有一些恶意的请求故意查询不存在的key,请求量很大,会对数据库造成很大的压力。
解决方案:

  1. 接口校验。 在最外层先做一层校验,用户鉴权,数据合法性校验等
  2. 缓存空值。当访问缓存和数据库都没有查询到值时,可以将空值写进缓存,但是设置较短的过期时间
  3. 布隆过滤器。存储可能访问的所有key,不存在的key直接被过滤,可把所有可能存在的key放在一个大的Bitmap中,查询时通过该bitmap过滤

(4)什么是缓存雪崩及解决方案

缓存服务器重启或者大量缓存集中在某一个时间段失效,造成瞬时数据库请求量大,导致系统崩溃
解决方案:

  1. 打散过期时间:不同的key设置不同的过期时间
  2. 做二级缓存:一级失效时,二级做兜底
  3. 加互斥锁:缓存失效后,通过加锁或者队列来控制写缓存的线程数量,减少压力
  4. 热点数据不过期
http://www.dtcms.com/a/343588.html

相关文章:

  • 2026 济南玉米及淀粉深加工展:从原料到创新产品的完整解决方案
  • 【算法精练】 哈夫曼编码
  • Eino 框架组件协作指南 - 以“智能图书馆建设手册”方式理解
  • Excel中运行VB的函数
  • Sklearn 机器学习 房价预估 线性回归模型实现预估
  • 【自用】JavaSE--网络通信
  • 项目架构分享 —— 离线数仓
  • 【neo4j】安装使用教程
  • 最新react,vue 解决无法使用js触发点击,解决方案
  • k8s存储类-storageclass部署
  • 日语学习-日语知识点小记-构建基础-JLPT-N3阶段(18):文法+单词第6回1
  • OpenHarmony之 蓝牙子系统全栈剖析:从协议栈到芯片适配的端到端实践(大合集)
  • 如何正确地捕获并处理异步操作中的错误
  • K 均值聚类算法学习总结
  • Flutter 线程模型详解:主线程、异步与 Isolate
  • 深入 RxJava 插件化开发:打造自定义操作符与监控体系
  • 物理电气协议标准:RS485 RS232
  • llama.cpp docker 镜像pull国内加速地址
  • 餐饮供应链:餐饮的“后端定海神针”
  • 《JavaScript不可变数据实践:Object.freeze与Proxy的实现逻辑、性能博弈及场景选型》
  • 详细讲解Java中的反射和经典面试题(保姆级别)
  • 【STM32入门教程】新建工程
  • 如何高效撰写AI领域学术论文——学习笔记
  • 【动手学深度学习】6.2. 图像卷积
  • DeepSeek-V3.1震撼升级:推理与Agent双突破
  • 20250820:一波三折!老设备国标接入 EasyGBS 的 “排雷” 记:从无流到花屏,换个协议全搞定
  • 8.21学习总结
  • 08.20CSP模拟赛总结
  • 中文房间悖论:人工智能理解力的哲学拷问
  • 【网络运维】Shell:变量进阶知识