HashMap是线程安全的吗?如果不是该如何解决?
不是线程安全的,可以通过HashTable
,Collections.synchronizedMap()
将HashMap
转为线程安全的集合,ConcurrentHashMap
解决:
HashTable
是古老的API
,JDK1.0
时就出现了,同步方案不成熟,性能不好;synchronizedMap
方法主要是使用synchronize
关键字;- 推荐使用
ConcurrentHashMap
降低锁的粒度提高并发能力
请你说说Java的四种引用方式
强软弱虚
强引用:通过new
关键字创建的引用都是强引用,不会被回收
软引用:只有内存不足时才会被回收,例SoftReference
弱引用:进行垃圾回收时就会回收,例WeakReference
虚引用:虚引用无法获取对象,回收之前进行销毁工作(资源释放)或者给个通知,必须配合引用队列一起使用ReferenceQueue
,例PhantomReference
请你讲一下G1的垃圾回收器
将堆划分为多个大小相等的region
区域,region
可以扮演Eden
、survivor
、老年代,还有一个特殊区域,超过一半region
可以视为humongous region
,大对象区域;
维护一个优先级列表,优先回收优先级较高的,优先级评分规则,回收对象空间大小和回收时间长短,也叫混合收集,mixedGC
;
回收跟不上创建使用FullGC
;
缺点:适用范围有限,适用大内存应用场景,小内存应用场景建议使用CMS
请你说说内存溢出
OOM:out of memory
,申请的内存大于系统所能提供的内存,导致无法申请足够内存,所以出现内存溢出
原因:
- 代码出现死循环
- 不在使用的对象仍被引用,没有被删除,导致内存泄露
- 从数据库一次取出过多数据
JVM
内存参数设置过小
解决:
- 修改
JVM
内存参数大小 - 分析日志,
debug
运行代码排查 - 使用内存工具动态查询内存使用情况
内存溢出一般出现在堆和方法区:
- 堆,创建的对象实例过多
- 方法区,使用反射创建大量动态类
请你说说内存泄露
不在使用的对象还被引用,没有被删除,导致内存泄露,可用的内存越来越少
解决:查看日志;使用内存分析工具进行排查和调试;使用java.lang.ref
包下的引用方式
请你说说数据库引擎有哪些,各自有什么区别
InnoDB
:MySQL
默认的数据库引擎,支持事务、主键,行级锁,默认的事务隔离级别为RR(repeatable read)
MyISAM
:MySQL
简单的数据库引擎,表级锁,不支持事务、主键,查询效率高
MongoDB
:MongoDB
数据库引擎,优点高性能、高可用,适用于分布式应用场景
简单介绍spring
IOC
和AOP
是spring
的核心
IOC:inverse of control
,控制对象的创建能力反转,交给spring
容器,使程序员专心业务代码开发,无需关系对象的创建、销毁、对象之间的依赖关系等,降低代码耦合度,DI(dependency injection)
依赖注入是IOC
实现方式
AOP:aspect oriented program
,面向切面编程,是对OOP
(oriented object program
面向对象编程)的补充,将一些与业务代码无关,但又被业务代码所调用的代码抽取出来,例如事务、权限、日志等,有利于代码可维护性和可重用性,实现方式是动态代理