大话java面试-java基础-3

1、ReentrantLock和Synchronized的区别,以及实现原理

ReentrantLock是java代码实现,Synchronized是字节码实现,ReentrantLock可使用公平锁、可根据Condition分组唤醒线程、而不是像synchronized要么随机唤醒一个线程要么唤醒全部线程,ReenTrantLock提供了一种能够中断等待锁的线程的机制,通过lock.lockInterruptibly()来实现这个机制。

ReentrantLock内部实现原理:AbstractQueuedSynchronizer简称AQS,AQS维护一个volatile int state字段和双向队列来实现。AQS详解

Synchronized实现原理:代码块时是在字节码中加入moniterenter和moniterexit,当执行到moniterenter时会获取锁定对象的锁,方法时是在Class文件的方法表中将该方法的access_flags存放ACC_SYNCHRONIZED。锁定的对象的加锁是通过对象头MARKWORD中指向的当前对象的ObjectMoniter来加锁。Synchronized的内部实现原理以及Moniter实现原理

2、jvm问题排查

1、程序hung住:线程死锁、线程堵塞。通过jps获取当前进程id,jstack -l pid,出现BLOCKED、deadlock。

2、CPU100%: jps查看pid,top -H -p pid查看cpu最高的线程id,jstack pid> a.log 然后在a.log中搜索线程id的16进制。

3、频繁full gc:可能是oom。jmap -dump:format=b,file=/home/admin/dump.bin pid导出堆的信息,用VisualVM进行分析。jstat -gcutil pid查看gc情况。一次线上OOM排查经过

3、java 中的锁 -- 偏向锁、轻量级锁、自旋锁、重量级锁

偏向锁适用于单个线程时提高性能,轻量级锁适用于多个线程交替执行。

偏向锁:首先CAS修改线程id为当前线程id,失败并且线程id不是当前线程,在安全点判断持有锁的线程是否存在,不存在标示为未锁定,存在升级为轻量级锁。

轻量级锁:复制MARKWORD到LOCK record里,CAS修改线程id为当前线程id,失败并且线程id不是当前线程,进入自旋CAS获取,获取失败升级为重量级锁。执行结束,复制的那份MARK word用CAS替换,如果失败也进入重量级锁。java 中的锁 关于偏向锁、轻量级锁将的不是很好,参考这个《JVM源码分析之synchronized实现

4、堆外内存使用以及回收机制

堆外内存时jvm以外的内存,当建立一个堆外内存的时候会在堆中创建一个Cleaner对象对应DirectByteBuffer,当DirectByteBuffer对象被回收时,把cleaner对象放到ReferenceQueue队列,在FULL gc时会调用ReferenceQueue中所有Cleaner对象的clear方法。也可以手动获取Cleaner对象,并调用clear方法进行回收。堆外内存的回收机制分析

ByteBuffer buffer = ByteBuffer.allocateDirect(1024 * 1024 * 200);//200M堆外内存

((DirectBuffer)buffer).cleaner().clean();//手动回收

5、强引用、软引用、弱引用、虚引用

强引用:只要引用存在永不回收。比如new 一个对象。

软引用:内存溢出之前进行回收。SoftReference。应用:缓存

弱引用:第二次垃圾回收时回收。WeakReference。

虚引用:垃圾回收时回收。PhantomReference。

6、动态代理

jdk动态代理:被代理类必须实现了接口。原理实现InvocationHandler接口,内部还是使用的反射。

cglib代理:被代理类不时必须实现接口,性能比不上jdk,通过继承被代理类来实现。需要实现MethodInterceptor接口。

7、ArrayList、Vector、HashSet、HashTable默认容量和扩容

ArrayList:默认容量:10 扩容增量:1.5*原数组长度

Vector:默认容量:10 扩容增量:2*原数组长度

HashSet:默认容量:16 扩容增量:2*原数组长度

HashTable:默认11 扩容增量:2*原数组长度+1

8、浅拷贝和深拷贝的区别

浅拷贝:只拷贝当前对象,而当前对象引用的其它对象还是引用同一个对象。

深拷贝:不仅拷贝当前对象还拷贝当前对象引用的对象。

A a = new A();A b =a;//只是引用 不叫拷贝

9、线程的五种状态和线程池的五种状态以及状态流转

线程五种状态:新建New、就绪Runnable、运行Running、阻塞Blocked及死亡Dead。

线程的状态流转

线程池的5种状态:Running、ShutDown、Stop、Tidying、Terminated。

线程池的状态流转

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 一、多线程 说明下线程的状态 java中的线程一共有 5 种状态。 NEW:这种情况指的是,通过 New 关键字创...
    Java旅行者阅读 4,761评论 0 44
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,805评论 18 399
  • Java8张图 11、字符串不变性 12、equals()方法、hashCode()方法的区别 13、...
    Miley_MOJIE阅读 3,758评论 0 11
  • 今天(9月25日)早晨,陈龙爱妻章龄之在微博上晒出一组一家四口的幸福出街照,并配文:“这样一天天的过日子。就好满足...
    简娯阅读 248评论 0 1
  • 如果每一天都有这样清澈的蓝天 如果每一个生命沉淀以后都希望重生 放逐生命慢慢的游到水里呼吸 离苦得乐,自由自在。
    戒乐阅读 285评论 0 0