面试题day24
oppo
提前批 8.24 一面
-
java几种集合,应用场景,ArrayList和LinkedList区别
list set map,有序可重复 无需不可重复 key不可重复value可重复
数据结构不同、效率不同、存储空间不同
-
tcp/udp联系区别,为什么3次握手,四次挥手的双方状态变化,time_wait状态干嘛的,多久,为什么
传输内容不同、可靠性、速度、是否连接
慢开始、拥塞控制、快重传、快恢复
防止在最后一次ack未接受,2msi
-
设计模式了解吗,抽象工厂模式,开闭原则
针对产品族;开放拓展、禁止修改
-
主播直播间用户进出有日志,包括uid/time/action,统计出同时在线人最多的一个时间
MITH a AS ( SELECT time, sum( action ) over ( ORDER BY time ) As number FRON login_action ) SELECTtime, max(number )FROM a;
-
cas了解吗,内存屏障是什么,violate关键字有什么用,除了禁止重排序呢
compareandswap,用预期值和内存值比较,相等替换新值
ABA用版本号解决、占用内存
LongAdder 是把 value 分成若干cell,并发量低的时候,直接 CAS 更新值,成功即结束。并发量高的情况,CAS更新某个cell值和需要时对cell数据扩容,成功结束;更新失败自旋 CAS 更新 cell值。取值的时候,调用 sum() 方法进行每个cell累加。
线程可见性、禁止指令重排
-
java的hashmap底层结构,扩容机制
- 链表散列+红黑树
- 扰动函数
(h = key.hashCode()) ^ (h >>> 16);
低16位与高16位做异或操作^,减少hash碰撞
- 扩容
- 链表引发
- 链表长度大于8,判断是否转为红黑树
- 数组大小大于64,转红黑树
- 数组大小小于64,扩容
- 链表长度大于8,判断是否转为红黑树
- 数组引发
- 数组元素大于容量与扩容因子之积,扩容
- 链表引发
- 死循环
- 元素覆盖
-
redis为啥这么快,多路复用有几种,区别呢,为什么epoll遍历就绪链表比select更快
io多路复用
只传入修改部分、返回文件操作符、数组限制
-
kafka高可用架构了解吗,为什么kafka吞吐量很高
-
一致性算法了解哪些,讲一下raft算法的写入读取,以及选举流程,写入的同时读到了未写入的节点会有什么问题,raft怎么解决的
转转
Java后端开发
-
自我介绍,项目介绍
-
项目的超卖如何解决的?
数据库库存乐观锁、消息队列
-
排序算法有哪些?
-
堆排序的时间复杂度?说说堆排序的排序过程,是怎么得到这个时间复杂度的?
O(nlogn)
-
Object类中有哪些方法?
clone getClass toString finalize equals hashCode wait notify notifyAll
-
wait()和sleep()的区别?
作用时机、释放锁、从属
-
线程池的参数和作用?线程池的执行流程/原理?
核心线程数、最大线程数、阻塞队列、线程存活时机、时间单位、拒绝策略、线程工厂
核心线程数、阻塞队列、最大线程数、拒绝策略
-
JVM内存模型,垃圾回收算法?
方法区 堆
本地方法栈 虚拟机栈 程序计数器 直接内存
动态链接 局部变量 操作数栈 返回地址
edon s0 s1 old 8:1:1:20
清除、复制、整理
引用计数法 可达性分析
本地方法栈 虚拟机栈 常量 静态变量
-
HashMap的容量为什么要初始化为2的n次幂?
(n-1)&hash==hash%n的成立条件
-
ConcurrentHashMap的扩容过程,源码有没有看过?
- 1.7
- 扩容时,对待扩容Segment内部会进行扩容,不影响其他Segment对象
- 扩容时,先生成新的数组,然后转移元素到新数组中
- 扩容的判断也是每个Segment内部单独判断的,判断是否超过阈值
- 1.8
- 如果某个线程put时,发现没有正在进行扩容,那么该线程一起进行扩容
- 如果某个线程put时,发现没有正在进行扩容,则将key-value添加到ConcurrentHashMap中, 然后判断是否超过阈值,超过了则进行扩容
- ConcurrentHashMap是支持多个线程同时扩容的。扩容前也是生成一个新数组,在转移元素时,先将原数组分组,将每组分给不同的线程来进行元素的转移,每个线程负责一组或多组的元素转移工作
- 1.7
-
说说你对Synchronized的理解,底层原理?
- 加锁方式
- 同步代码块(monitorenter和monitorexit)
- 同步方法(ACC_SYNCHRONIZED)
- 操作流程
- 首先会进入 EntryList 集合,当线程获取到对象的monitor后,进入 _Owner区域并把monitor中的owner变量设置为当前线程,同时monitor中的计数器count加1;
- 若线程调用 wait() 方法,将释放当前持有的monitor,owner变量恢复为null,count自减1,同时该线程进入 WaitSet集合中等待被唤醒;
- 若当前线程执行完毕,也将释放monitor(锁)并复位count的值,以便其他线程进入获取monitor(锁);
- 锁优化
- 加锁方式
-
除了Synchronized,还知道Java中的其他锁吗?
-
说说你对Lock/ReentraLock的理解?有没有看过源码
- 核心思想
- 如果被请求的共享资源空闲,则将当前请求资源的线程设置为有效的工作线程,并且将共享资源设置为锁定状态。如果被请求的共享资源被占用,那么就需要一套线程阻塞等待以及被唤醒时锁分配的机制,这个机制 AQS 是用 CLH 队列锁实现的,即将暂时获取不到锁的线程加入到队列中。
- 操作流程
- AQS 使用一个 int 成员变量来表示同步状态,通过内置的 FIFO 队列来完成获取资源线程的排队工作。AQS 使用 CAS 对该同步状态进行原子操作实现对其值的修改。
- 公平锁和非公平锁
- 非公平锁在调用 lock 后,首先就会调用 CAS 进行一次抢锁,如果这个时候恰巧锁没有被占用,那么直接就获取到锁返回了。
- 非公平锁在 CAS 失败后,和公平锁一样都会进入到
tryAcquire
方法,在tryAcquire
方法中,如果发现锁这个时候被释放了(state == 0),非公平锁会直接 CAS 抢锁,但是公平锁会判断等待队列是否有线程处于等待状态,如果有则不去抢锁,乖乖排到后面。
- 条件队列
- AQS中实现ConditionObject,它实现了Condition接口,实现一个绑定在锁上的条件队列Condition,替代了 Object 监视器方法
- 核心思想
-
说说你对MySQL索引的理解,什么是聚簇索引和非聚簇索引?
加快数据查找
外键 事务 mvcc 锁
uuid消耗空间,雪花算法时间回拨
-
如何根据索引查找数据的,索引执行的流程/原理?
主键直接查、非主键会回表
-
MySQL的事务隔离级别?
ru rc rr s
-
MySQL是如何解决幻读的?
间隙锁 mvcc
-
Redis有哪些了解,基本数据类型有哪些,底层实现知道吗?
TYPE ENCODING 解释 REDIS_STRING
REDIS_ENCODING_INT
使用整数值实现的字符串对象。 REDIS_STRING
REDIS_ENCODING_EMBSTR
使用 embstr
编码的简单动态字符串实现的字符串对象。REDIS_STRING
REDIS_ENCODING_RAW
使用简单动态字符串实现的字符串对象。 REDIS_LIST
REDIS_ENCODING_ZIPLIST
使用压缩列表实现的列表对象。 REDIS_LIST
REDIS_ENCODING_LINKEDLIST
使用双端链表实现的列表对象。 REDIS_HASH
REDIS_ENCODING_ZIPLIST
使用压缩列表实现的哈希对象。 REDIS_HASH
REDIS_ENCODING_HT
使用字典实现的哈希对象。 REDIS_SET
REDIS_ENCODING_INTSET
使用整数集合实现的集合对象。 REDIS_SET
REDIS_ENCODING_HT
使用字典实现的集合对象。 REDIS_ZSET
REDIS_ENCODING_ZIPLIST
使用压缩列表实现的有序集合对象。 REDIS_ZSET
REDIS_ENCODING_SKIPLIST
使用跳跃表和字典实现的有序集合对象。 -
Redis的缓存淘汰策略、持久化机制说一下?
- 定时删除
- 创建一个定时器,当key有过期时间时,时间一到,定时器任务就会立即执行 将expires区域和k-v区域都删除
- 优点:节约内存
- 缺点:cpu压力较大,此时无论cpu负载量多高,都会占用cpu来释放,影响redis的吞吐量
- 惰性删除
- 数据过期后,并不会立刻删除 等到该数据下次访问的时候,redis才会删除该数据,并返回该值为nil
- 优点:节省cpu的资源
- 缺点:可能存在大量的,无人访问的数据会一直存在服务器
- 定期删除
- 每秒钟定期对redis中每个库的数据进行轮询 轮询的数据,对过期的数据随机删除一部分 如果随机删除的数据占轮训数据的比例超过一定值,继续轮询删除
- aof 命令
- rdb 快照 默认
- 定时删除
-
反问环节