【笔面试真题】Flow++赋乐科技-面试-2022年1月25日
一、概括
涉及JVM的GC、三色标记
并发部分的锁
Java集合中的hashmap、list
kafka中ISR相关
硬件相关-有无DMA
自定义类(代码)
缺陷:锁、list
二、JVM相关内容
1、如何判断什么是垃圾
(1)方法1:有无引用指向-reference count
无法解决循环引用
(2)可达性分析/根可达算法
从根main函数上能找到的对象
2、介绍一下常见的垃圾回收算法
(1)标记-清除算法(Mark-Sweep):碎片化现象
(2)拷贝复制算法(Copying):有用的拷贝到另一半(空闲面),但浪费空间
(3)标记-整理算法(Mark-compact):清除垃圾后,把有用的往前放
(4)分代收集算法:
堆:新生代(Tenured Generation)+老年代
非堆:永久代(Permanet)
新生代回收大量对象,老年代回收少量对象
3、不同的垃圾回收器
Serial Old/Serial
Parallel Old/ParNew/Parallel Scavenge
CMS(Concurrent Mark Sweep)
G1
ZGC
4、描述一下三色标记算法
在Concurrent Mark Sweep,CMS-并发垃圾回收器中
并发(GC+业务线程分别进行)操作存在在的问题:浮动垃圾
如何找到没有引用的对象-三色标记算法
黑、白、灰
存在问题:
(1)业务线程标记已回收对象指向被引用节点(白色),采取Incremental Update
(2)上述并发方式,容易产生漏标,remark再标一遍
三、Java并发-常见的锁
常见的锁分类大致有:排它锁、共享锁、乐观锁、悲观锁、分段锁、自旋锁、公平锁、非公平锁、可重入锁等。
1.公平锁 / 非公平锁:是否按顺序申请锁
2.可重入锁 / 不可重入锁:是否可重复或递归调用,ReentrantLock和synchronized/两次调用lock()不释放导致死锁
3.排他锁 / 共享锁:C.U.T包下的ReeReentrantLock/ReentrantReadWriteLock
4.互斥锁 / 读写锁:访问共享资源前加锁/读时加锁、写时加锁、不加锁(既是共享锁,也是排他锁)
5.乐观锁 / 悲观锁:java.util.concurrent.atomic包下面的原子变量类使用CAS/synchronized和ReentrantLock等独占锁只给一个进程使用
6.分段锁:是一种锁的设计,ConcurrentHashMap就是基于分段锁实现高效并发
7.偏向锁 / 轻量级锁 / 重量级锁:一段同步代码一直被一个线程所访问/锁是偏向锁的时候,被另一个线程所访问,偏向锁就会升级为轻量级锁/锁为轻量级锁时,另一个线程自旋一定次数时还没有获取到锁,就会进入阻塞
8.自旋锁:CAS是英文单词Compare and Swap(比较并交换),当一个线程在获取锁的时候,如果锁已经被其它线程获取,那么该线程将循环等待,然后不断的判断锁是否能够被成功获取,直到获取到锁才会退出循环
四、java集合
1、HashMap
JDK1.7:Entry数组 + 链表
JDK1.8:Node 数组 + 链表/红黑树,转红黑树提高查询效率到O(logN)
2、HashMap是否线程安全,如何保证线程安全
使用 ConcurrentHashMap保证线程安全
或者使用
Collections.synchronizedMap(hashMap),使其实现同步
3、ConcurrentHashMap如何保证线程安全
采用锁分段技术,将整个Hash桶进行了分段segment,也就是将这个大的数组分成了几个小的片段 segment,而且每个小的片段 segment 上面都有锁存在,那么在插入元素的时候就需要先找到应该插入到哪一个片段 segment,然后再在这个片段上面进行插入,而且这里还需要获取 segment 锁
4、HashMap 与 HashTable 的区别
HashTable 基于 Dictionary 类,而 HashMap 是基于 AbstractMap
HashMap 的 key 和 value 都允许为 null,而 Hashtable 的 key 和 value 都不允许为 null
Hashtable 是线程安全的,而 HashMap 不是线程安全的
5、List的subList返回的对象和原始的引用相关吗
不会返回新的list对象
返回原来list的从[fromIndex, toIndex)之间这一部分的视图,实际上,返回的list是靠原来的list支持的。
对原来的list和返回的list做的“非结构性修改”(non-structural changes),都会影响到彼此对方。
如何删除一个list的某个区段:list.subList(from, to).clear();--将元素释放并清空内部属性
6、String的subString
返回一个新的字符串,是原始字符串的子字符串
字符串会存放在堆内存
返回一个新的字符串对象
五、kafka的ISR队列和OSR队列
1、含义
ISR(In-Sync Replicas),副本同步队列。ISR中包括Leader和Follower。如果Leader进程挂掉,会在ISR队列中选择一个服务作为新的Leader。有replica.lag.max.messages(延迟条数)和replica.lag.time.max.ms(延迟时间)两个参数决定一台服务是否可以加入ISR副本队列,在0.10版本移除了replica.lag.max.messages参数,防止服务频繁的进去队列。
任意一个维度超过阈值都会把Follower剔除出ISR,存入OSR(Outof-Sync Replicas)列表,新加入的Follower也会先存放在OSR中。
2、深层次理解
(1)消息组成
LEO:从哪落盘,即表示下一条待写入数据的index【下一条待写入位置】
HW:表示数据从哪消费,HW之前的数据对消费者可见,能够被消费者消费
firstUnstableOffset:第一条未提交数据
lastStableOffset:最后一条已提交数据
LogStartOffset:起始位置
(2)如何通过更新LEO,进行副本同步
leader和follower都有HW,LEO会选择ISR中HW和自身LEO最小的进行写入,LEO落盘后,进行+1
当leader挂掉,变为follower后,follower的HW会覆盖当前节点的HW,会导致数据丢失
六、DMA--延伸到零拷贝机制
“Direct Memory Access(存储器直接访问)。这是指一种高速的数据传输操作,允许在外部设备和存储器之间直接读写数据。整个数据传输操作在一个称为"DMA控制器"的控制下进行的。CPU除了在数据传输开始和结束时做一点处理外(开始和结束时候要做中断处理),在传输过程中CPU可以进行其他的工作(前提是未设置停止CPU访问)。这样,在大部分时间里,CPU和输入输出都处于并行操作。因此,使整个计算机系统的效率大大提高”。
DMA方式中,主存与I/0设备之间有一条数据通路(专用数据总线),则交换信息时无需像中断一样调用中断服务程序,数据不经过CPU,直接通过这条线传输,所以DMA是需要硬件支持的。【使用硬件传输数据】
1、含义
DMA是一种内存访问技术;
可以独立于CPU, 直接读、写系统存储器、外设等
2、使用原因
把比较固定的任务让DMA来做,可以减轻CPU负担,提高系统的效率
DMA具有一般CPU没有的高效操作,提高系统的吞吐率
3、kafka的零拷贝机制
传统的传输方式
零拷贝机制--没有去内存中拷贝数据
无需经过CPU拷贝数据到内存中
从硬盘直接读到操作系统内核的读缓冲区里面
根据 Socket 的描述符信息,直接从读缓冲区里面,写入到网卡的缓冲区里面
具体实现:-使用NIO机制,实现了直接内存缓冲区的开辟
应用程序通过调用mmap(),将不同的虚拟地址映射到了同一物理地址,即内核缓冲区,使程序在用户态可以直接读取并操作内核空间的数据
使用DMA的方式将磁盘数据读取到内核缓冲区,然后通过内存映射的方式,使用户缓冲区和内核读缓冲区的内存地址为同一内存地址
七、自定义类-list实现栈
import java.util.LinkedList; /** * Created by lili on 15/11/14. */ public class MyStack { private LinkedList linkedList; public MyStack() { linkedList = new LinkedList(); } public void push(Object o) { linkedList.addFirst(o); } public Object pop() { //删除并返回 return linkedList.removeFirst(); } public boolean isEmpty() { return linkedList.isEmpty(); } }
本文来自博客园,作者:哥们要飞,转载请注明原文链接:https://www.cnblogs.com/liujinhui/p/15844460.html