7-13 15:00 第二家 线上面试 一面
自我介绍
离职原因
项目介绍
Q1:多线程怎么创建,参数怎么设置
A1:异步编排的一个线程池,CompletFuture;Executors;ThreadPoolExecutor
他这里问的应该是具体参数如何设置,核心线程数设置成什么,阻塞队列设置成什么等等
核心线程数,目前公司机器16c,CPU用的多话就16;IO多就32
非核心线程,核心*2
阻塞队列ArrayListBlockQueue,这个无所谓用哪个吧,生产基本都没出现过线程池刮的情况,除非是你代码写的太烂了
拒绝策略:abort,因为不太可能出现满的情况,这个用的默认的
后面就打断我了,进入Q2
Q2:用的JDK什么版本,JDK21虚拟线程了解过吗?
A2:JDK8/JDK17 springAI需要,了解过,类似于python的协程,传统一个请求对应一个OS线程,用的内核态,走的操作系统;虚拟线程是在JVM里面,类似于java对象,可以创建很多,并且内存占用小,传统需要涉及到上下文切换,寄存器的切换,比较重;并且虚拟线程碰到io会自动切换,也就是说我们可以用很少的虚拟线程处理大量的请求
Q3:Redis的zset怎么实现的?
A3:这里回答的说实话一般,数据过来忘记是怎么设置的,我记得是百分之25的记录晋升到下一层,然后构成一个多层级链表,比如最底层123456789,第二层13579,第三层1579,我们在查找的时候,依次从上向下查找,查6,就定位到57之间,依次向下查找
Q4:Redis的list怎么实现的?
A4:不清楚,ziplist压缩列表吧,这个没研究过
Q5:Redis的字符串怎么实现的?
A5:SDS,redisObject+数据存储空间,对象头包含,数据空间指针+空间大小+数据长度,数据长度<44字节,用的embstr,和对象头存一起,>=44字节,用的raw,另外开辟一个空间,并且后续如果修改数据长度embstr会直接转成raw,因为embstr存在缺陷,无法动态扩展长度,而raw可以动态扩展长度,后面没说完,被打断进入Q6
Q6:MQ怎么实现延迟消息?
A6:我只知道rabbitMq,TTL+死信队列,设置消息的过期时间,没有消费者,到期了,会自动被投递到死信的channel,由死信的消费者进行消费;或者通过rabbitMq的delayMessageExchange,指定header为x-delay-message(忘记是不是这个了),然后设置delay就能实现
Q7:我想知道的是为什么mq能判断他已经到期了?
A7:不明白到底啥意思,意思是我设置了5分钟的ttl,他怎么判断这5分钟 到期了?这个不知道,可能是算的吧,消息不能改ttl,因此在消息入库的那一刻就已经知道什么时候到期了,这个不是特别了解
Q8:mysql有哪些索引数据结构?
A8:这里面试官有点毒的,跟我扯半天,我说b树,叶子节点和非叶子节点都存数据,并且节点没有指针;然后演变成b+树,他说为什么要演变,我说b树查询速度不稳定啊,并且没有办法顺序遍历;他说哪不稳定了,和b+树不是一样吗,都是从树的头开始往下遍历,我说因为他都存节点,他的树一定比b+树高,b+树,只存索引和主键id,b树可能在中间就找到,也可能在最下层就找到,有的时候快有的时候慢,不稳定;b+树只会在叶子节点找到相对来说更加稳定
Q9:dubbo+zk用过吗?
A9:很早之前用过,现在都是用cloudalibaba那一套了,dubbo就是rpc调用的那一套吧;他说噢那你们注册中心用的nacos吧,我说是的
Q10:AI编程用的多吗?怎么用的?
A10:原先cursor+codex bash +claude code bash;cursor不太好用,java项目调试没发调试;后面idea插件有ccgui,用的idea+ccgui,一开始用的是opus4.5,然后用opus4.6,然后用glm5.1,然后用gpt5.5
Q11:碰到问题怎么排查?
A11:看碰到的是什么问题,正常范围内的报错,比如说用户参数填错了,外部接口报错了,这个不用排查,看一眼就知道了,并且有错误消息自动推送,可以及时反馈给客户;
如果是服务器问题,比如说stackOverflow、outofmemory,我记得应该是top -H,转十六进制,然后jstack pid grep 找到对应线程,查看对应代码,或者是通过jmap dump下来,到jvisualvm里面,看堆情况以及调用栈;或者jstat看GC情况
询问我有什么问题,结束
自我介绍
离职原因
项目介绍
Q1:多线程怎么创建,参数怎么设置
A1:异步编排的一个线程池,CompletFuture;Executors;ThreadPoolExecutor
他这里问的应该是具体参数如何设置,核心线程数设置成什么,阻塞队列设置成什么等等
核心线程数,目前公司机器16c,CPU用的多话就16;IO多就32
非核心线程,核心*2
阻塞队列ArrayListBlockQueue,这个无所谓用哪个吧,生产基本都没出现过线程池刮的情况,除非是你代码写的太烂了
拒绝策略:abort,因为不太可能出现满的情况,这个用的默认的
后面就打断我了,进入Q2
Q2:用的JDK什么版本,JDK21虚拟线程了解过吗?
A2:JDK8/JDK17 springAI需要,了解过,类似于python的协程,传统一个请求对应一个OS线程,用的内核态,走的操作系统;虚拟线程是在JVM里面,类似于java对象,可以创建很多,并且内存占用小,传统需要涉及到上下文切换,寄存器的切换,比较重;并且虚拟线程碰到io会自动切换,也就是说我们可以用很少的虚拟线程处理大量的请求
Q3:Redis的zset怎么实现的?
A3:这里回答的说实话一般,数据过来忘记是怎么设置的,我记得是百分之25的记录晋升到下一层,然后构成一个多层级链表,比如最底层123456789,第二层13579,第三层1579,我们在查找的时候,依次从上向下查找,查6,就定位到57之间,依次向下查找
Q4:Redis的list怎么实现的?
A4:不清楚,ziplist压缩列表吧,这个没研究过
Q5:Redis的字符串怎么实现的?
A5:SDS,redisObject+数据存储空间,对象头包含,数据空间指针+空间大小+数据长度,数据长度<44字节,用的embstr,和对象头存一起,>=44字节,用的raw,另外开辟一个空间,并且后续如果修改数据长度embstr会直接转成raw,因为embstr存在缺陷,无法动态扩展长度,而raw可以动态扩展长度,后面没说完,被打断进入Q6
Q6:MQ怎么实现延迟消息?
A6:我只知道rabbitMq,TTL+死信队列,设置消息的过期时间,没有消费者,到期了,会自动被投递到死信的channel,由死信的消费者进行消费;或者通过rabbitMq的delayMessageExchange,指定header为x-delay-message(忘记是不是这个了),然后设置delay就能实现
Q7:我想知道的是为什么mq能判断他已经到期了?
A7:不明白到底啥意思,意思是我设置了5分钟的ttl,他怎么判断这5分钟 到期了?这个不知道,可能是算的吧,消息不能改ttl,因此在消息入库的那一刻就已经知道什么时候到期了,这个不是特别了解
Q8:mysql有哪些索引数据结构?
A8:这里面试官有点毒的,跟我扯半天,我说b树,叶子节点和非叶子节点都存数据,并且节点没有指针;然后演变成b+树,他说为什么要演变,我说b树查询速度不稳定啊,并且没有办法顺序遍历;他说哪不稳定了,和b+树不是一样吗,都是从树的头开始往下遍历,我说因为他都存节点,他的树一定比b+树高,b+树,只存索引和主键id,b树可能在中间就找到,也可能在最下层就找到,有的时候快有的时候慢,不稳定;b+树只会在叶子节点找到相对来说更加稳定
Q9:dubbo+zk用过吗?
A9:很早之前用过,现在都是用cloudalibaba那一套了,dubbo就是rpc调用的那一套吧;他说噢那你们注册中心用的nacos吧,我说是的
Q10:AI编程用的多吗?怎么用的?
A10:原先cursor+codex bash +claude code bash;cursor不太好用,java项目调试没发调试;后面idea插件有ccgui,用的idea+ccgui,一开始用的是opus4.5,然后用opus4.6,然后用glm5.1,然后用gpt5.5
Q11:碰到问题怎么排查?
A11:看碰到的是什么问题,正常范围内的报错,比如说用户参数填错了,外部接口报错了,这个不用排查,看一眼就知道了,并且有错误消息自动推送,可以及时反馈给客户;
如果是服务器问题,比如说stackOverflow、outofmemory,我记得应该是top -H,转十六进制,然后jstack pid grep 找到对应线程,查看对应代码,或者是通过jmap dump下来,到jvisualvm里面,看堆情况以及调用栈;或者jstat看GC情况
询问我有什么问题,结束













