1. 自我介绍2. 线程池有哪些常见参数3. RPC 调用情况下你会使用怎么配置线程池?1. IO 密集型任务线程大多时间是在等待外部资源响应,此时线程处于空闲状态,CPU 利用率较低,可以设置较大线程数2. CPU 密集型任务,例如浮点计算等,很少会有阻塞情况,此时线程数多会造成上下文切换频繁影响性能能4. ConcurrentHashMap 底层的读写是怎么处理并发冲突的1. 读:将 value 和 链表 next 指针设置为 volatile,多线程修改 volatile 变量时不会使用自己的副本,是修改公共内存中的变量,每个线程都可以取到最新的数据,读的时候不需要加锁2. 写:首先判断有无冲突,如果没有冲突的话直接 CAS 插入即可,如果有冲突的话就 synchronized 锁住头节点遍历链表进行插入3. 扩容:ConcurrentHashMap 的扩容也是并发安全的,且支持多线程协同扩容。扩容时,会将原数组的桶迁移到新数组(容量翻倍)。多个线程可以同时参与数据迁移工作。系统会将任务拆分成一个个小的“区域”(TransferRegion),线程领取任务后进行迁移。在扩容期间,读操作依然可以正常进行(可能会读到旧数据或新数据,但最终一致性有保障),写操作则会协助扩容或等待。5. Synchronized 和 ReentrantLock 两种锁的选择1. Synchronized 关键字:使用方式简单,可以加在代码块和代码上,只能实现非公平锁,多线程来了之后谁抢到谁执行,而不是排队。JDK 1.6 引入了偏向锁和锁升级机制提高了性能,性能和 ReentrantLock 相差不大。底层通过 Java 对象头中的 Mark Word 标记字实现,标记字中有 2 比特记录当前锁状态,1. 无锁状态记录 hash 值和 GC 年龄2. 偏向锁状态记录当前线程 ID,当第一个线程来时记录3. 轻量级锁,记录持有锁的线程的锁记录,每一个线程都有自己的锁记录,第二个线程来时转为轻量级锁;4. 重量级锁:记录堆中的 ObjectMonitor 对象指针,这个对象有一个队列存储没有获取锁的线程进行排队,当线程执行完毕后会唤醒队列中的线程竞争锁2. ReentrantLock:通过 AQS 抽象队列同步器实现,底层有一个 state 记录冲入次数、一个先进先出 FIFO 的 DLQ 双向链式队列记录排队线程,公平锁先查看队列再竞争锁,非公平锁先尝试获取锁操作失败才入队列等待。6. Redis 为什么快7. Redis 大 key 怎么解决8. Hive2CK 导入数据是直接 CK 导入还是使用中间件9. ClickHouse 和 MySQL 底层有什么区别10. ClickHouse 主要的使用场景在哪里11. ClickHouse 并发支持如何12. ClickHouse 物化视图是什么13. Agent 项目用户转人工拦截率这个数据口径是怎么统计的,有没有遇到过用户找不到人工 Oncall 入口而投诉的14. 讲述一下你的冷热分层项目15. 你这个 OOM 问题是怎么排查的,最后怎么解决的(OkHttpClient 没单例且没指定线程池导致的 OOM)16. Kafka LAG 一般怎么排查(从提交消息消费成功出排查,查看是线程挂掉了还是处理该消息耗时太长导致 LAG17. 算法题:翻转01字符串 k 次,找到翻转后最长相同串(eg: 10101 k=1, res=3, 翻转一个0得到111, 翻转一个1得到000