集合类
- HashMa为什么不是线程安全的?
- HashMap扩容流程是否是线程安全的,为什么?
- 如何设计线程安全的HashMap?
- CAS机制在ConcurrentHashMap中的具体体现?
答 :
- hashmap不是线程安全的,他源码里面没有加线程安全的处理
- 扩容流程不安全,多线程操作下可能会引入扩容死链(1.7),数据丢失(1.7、1.8)
- 可以仿照ConcurrentHashMap设计,引入CAS和synchronized锁机制
Redis
- Redis如何实现分布式锁?
- Redis去重方式了解几种,每种方式的优缺点?
- 讲一讲布隆过滤器?
答:
- 使用了set命令有个nx参数可以实现【key 不存在插入】,用它来实现分布式锁,需要考虑很多问题,怎么加锁、怎么释放锁、加锁线程和释放锁线程是否是一个。
- 可以用redis数据类型set、zset、HyperLogLog、布隆过滤器
- 布隆过滤器就相当于一个位图数组,初始值里面都是0,然后一些hash函数,先用hash函数在位图数组上标记,当我们要判断这个元素是否存在时,我们通过这些hash函数算出这个元素的一些hash值映射到数组上判断他是否为1,若有一个0则不存在。
JVM
- 有做过JVM调优吗?讲一个JVM调优的具体案例?
- 说一下JVM调优的命令?
- 线上服务CPU占用过高怎么排查?
答:
- 一个常见的JVM调优案例是调整内存大小。如果应用程序在运行中经常出现OutOfMemoryError错误,可能是因为堆内存不够用了。这时可以通过增加堆内存来解决这个问题。可以通过调整 -Xmx 和 -Xms 参数来调整堆内存的大小。 例如: -Xmx1024m -Xms1024m 这样可以将堆内存设置为1GB,并且初始堆内存和最大堆内存都设置为1GB。 另外,如果程序频繁出现Full GC,可能是因为新生代内存不够用了,可以通过调整-XX:NewSize和-XX:MaxNewSize来调整新生代内存的大小。 这只是JVM调优的一个方面,具体应用还需要根据不同场景来进行调整.
- JVM调优的命令有很多,常用的有:
-Xmx: 设置最大堆内存-Xms: 设置初始堆内存-XX:NewSize: 设置新生代内存大小-XX:MaxNewSize: 设置新生代最大内存-XX:SurvivorRatio: 设置新生代eden空间和survivor空间的比例-XX:+PrintGCDetails: 打印GC详细信息-XX:+PrintGCTimeStamps: 打印GC时间戳-XX:+PrintTenuringDistribution: 打印年龄分布信息-XX:+PrintGCApplicationStoppedTime:打印应用程序停顿时间信息 这些命令都是以“-XX:”开头的,可以在启动JVM时传入这些参数来调整JVM的运行状态.
怎么排查?
- 检查系统负载:通过命令
top或htop查看 CPU 和内存使用情况。如果系统负载过高,可能是因为系统资源不足。- 检查进程:使用命令
ps -ef或pstree查看进程使用情况。通过查看进程的 CPU 和内存使用情况,可以确定哪个进程导致 CPU 占用过高。- 分析日志:检查应用程序的日志,看看是否有任何异常输出。如果发现了异常的话,可能需要重启应用程序或者调整应用程序的配置。
- 使用工具:使用工具如jstack,jmap,jprofiler等查看线程堆栈信息,确定是否有死循环或者阻塞的线程。
- 检查网络状态:如果网络状态不佳,可能导致 CPU 占用过高。
- 检查磁盘状态:如果磁盘 IO 过高,可能导致 CPU 占用过高。
JUC
- volatile的实现原理?
- 讲一讲线程池的工作方式?
- 线程池的拒绝策略有哪些?
- 保证可见性、有序性,原因可以禁用CPU缓存,直接从主存中读取、使用内存屏障禁止指令重排序
- 提交任务到核心线程池,如果核心线程池没满,则创建线程,如果满了判断等待队列线程是否满了,若满了判断最大线程池满没有,如满了则执行拒绝策略。
- 拒绝策略一共有四种、直接抛弃不报异常、报异常直接抛弃、抛弃等待队列里等待最长时间的、使用主线程执行任务