联奕一面:
1、这段代码的输出结果是多少?t q z
package com.smart.community.test;public class Test {public class B{static {System.out.println("t");}public B(){System.out.println("z");}}public class A extends B{static {System.out.println("q");}public A(){System.out.println("w");}}public static void main(String[] args) {B a = new A();} }
2、Kafka、ActiveMQ、RocketMQ和RabbitMQ的区别
3、RocketMQ的推拉模式
推模式:每次producer每次生产了消息,会主动推给broker
推模式:broker将消息推向Consumer 优缺点:延迟小,实时性比较好,简化了Consumer端的逻辑,缺点:推送的速率和消费的速率不好去匹配
拉模式(RocketMQ选择的):消费者可以根据自身的情况来拉取消息的请求,如果消费者真的出现那种忙不过来的情况下,可以根据一定的策略去暂停拉取,更适合批量消息的发送,缺点是实时性较差
4、RocketMQ是如何实现拉模式
拉取模式分为普通轮询和长轮询两种方式
普通轮训:定时发起请求,服务端收到请求之后无论是否有数据更新,都立即回复
长轮训:Consumer向服务端发起请求,而服务端收到后不会立即去响应,而是hold住客户端连接,等待数据产生变更之后才会回复客户端,或者超过指定时间还未产生变更
对普通轮询进行一定程度的限制,客户端可以随时请求服务端,但是我并不一定立即回复你
5、RocketMQ消息堆积了怎么解决
8、业务执行时间可能超过设置的超时时间问题
(3)业务执行时间可能超过设置的超时时间
1)定时自动去续约(expire key second)
为该锁设置一个较小的lock_timeout,同时每隔一段时间在该锁过期之前,就自动的向服务器延长该锁的lifetime(看门狗)
动态续期:为分布式锁设置一个初始的过期时间,同时启动一个守护线程或定时任务来监控锁的剩余有效期。当检测到锁即将过期而业务操作尚未完成时,自动对锁进行续期,即延长锁的过期时间
使用Redlock算法:如果使用了分布式锁,可以考虑使用Redlock算法来提高锁的安全性和可靠性
合理评估超时时间:通过压力测试来评估业务操作的平均执行时间,然后根据测试结果来合理设置锁的超时时间。可以将超时时间设置为平均执行时间的1到2倍,以降低锁过期导致的问题风险
2)记录业务处理时长,设置过期时间:业务时长+一定时间
每次获取锁后,记录业务代码执行的时长,在redis中存一个上次时长,再次获取锁时 设置过期时间为上次时长+N秒
可以创建一个守护线程,也成为看门狗线程,这个线程的任务是实时监控业务线程的执行情况。如果发现业务线程仍在执行中,且未达到预定的超时时间,守护线程就会将锁的过期时间延长
可以使用Redisson工具类,Redisson会启动一个守护线程,这个线程会定期检査锁的状态,并在必要时对锁进行续期
我们可以先给锁设置一个LockTime,然后启动一个守护线程,让守护线程在一段时间后,重新去设置这个锁的LockTime。
看门狗
Redisson的看门狗机制就是这种机制实现自动续期的
Redisson看门狗机制, 只要客户端加锁成功,就会启动一个 Watch Dog。
-
leaseTime 必须是 -1 才会开启 Watch Dog 机制,如果需要开启 Watch Dog 机制就必须使用默认的加锁时间为 30s。
-
如果你自己自定义时间,超过这个时间,锁就会自定释放,并不会自动续期
-
续期原理
续期原理其实就是用lua脚本,将锁的时间重置为30s
-
Watch Dog 机制其实就是一个后台定时任务线程,获取锁成功之后,会将持有锁的线程放入到一个 RedissonLock.EXPIRATION_RENEWAL_MAP里面,然后每隔 10 秒 检查一下(internalLockLeaseTime / 3) 检查一下,
-
如果客户端 还持有锁 key(判断客户端是否还持有 key,其实就是遍历 EXPIRATION_RENEWAL_MAP 里面线程 id 然后根据线程 id 去 Redis 中查,如果存在就会延长 key 的时间),那么就会不断的延长锁 key 的生存时间。
如果服务宕机了,Watch Dog 机制线程也就没有了,此时就不会延长 key 的过期时间,到了 30s 之后就会自动过期了,其他线程就可以获取到锁
9、第一个线程拿到锁对象没有释放,那第二个线程怎么做?(队列,阻塞问题)
由于多个线程同时获取多个锁,但是获取锁的顺序不一致,导致互相等待对方释放锁。
(1)破坏占用且等待条件
在获取某个锁之前,释放已经持有的锁。这样可以避免多个线程同时持有多个锁而导致死锁的发生。例如,可以按照固定的顺序获取锁,这样可以避免不同的线程以不同的顺序获取锁而导致死锁
(2)破坏不可抢占条件
当一个线程持有一个锁时,其他线程无法抢占这个锁。为了避免死锁,可以设置超时时间,当一个线程无法在指定时间内获取到锁时,就会释放已经获取的锁,避免死锁的发生
(3)破坏循环等待条件
在获取锁时,按照一定的顺序获取锁,避免不同的线程以不同的顺序获取锁而导致死锁。例如,可以按照对象的哈希值获取锁,或者按照固定的顺序获取锁
11、压力测试怎么做?
使用JMeter工具,模拟大量用户并发访问系统,从而对系统进行压力测试
使用LoadRunner工具,模拟数以万计的用户并发访问系统,并对系统进行压力测试
JUnit是Java编程语言的一个单元测试框架,也可以用于压力测试。通过编写测试用例,并使用多线程或循环调用这些测试用例,可以模拟高并发的场景对系统进行压力测试
12、如何实现扫码登录?
13、讲一讲你对Seata的理解
Seata有四种模式:(背)
14、Seata的实现原理
TC、TM、RM
15、Redis和Redisson的区别
Redisson是Redis的一个儿子,它本质上是对Redis进行了很多封装。Redisson不仅提供了一系列的分布式Java常用对象,还提供了许多分布式服务。因此,Redisson可以理解为是对Redis进行了封装和扩展,使其更加方便地用于构建分布式应用和解决分布式系统中的一些问题
九安一面:
16、交付流程是怎么样的?
因为我们是坐外包的嘛,产品经理谈好需求之后,我们这边出一个需求文档给他们看,没问题之后就责任下放,任务分配,然后自测,交付第一版,之后会有第二版需求文档那些,然后线上出现bug了会上报组长,然后组长安排去解决
17、你还有什么问题要问么?
问公司人员架构,问公司技术架构或者问你自己工作中遇到的问题,当然也可以虚心请教刚才面试中没打出来的问题
每日物流一面:
14、Redis删除策略及区别?
惰性删除
定期删除
16、主从读写的原理?
17、索引失效?
18、如何保证消息不丢失?🐦
broker把消息保存在磁盘上时宕机
(1)把消息保存机制改为同步刷盘(但是会影响性能)
(2)
(3)master磁盘坏了呢?
19、网关前缀的原理?
StripPrefix=1
是一个过滤器,用于从请求的路径中删除前缀。在这个例子中,它将删除路径中的第1个部分(即第一个斜杠之前的部分)。例如,如果请求的路径是 /api/admin/info
,那么经过 StripPrefix=1
过滤器处理后,路径将变为 /admin/info
21、jvm了解过吗?
22、新生代用哪种模式?老年代用哪种模式?🐦
23、gc五种垃圾回收算法
(1)引用计数
JVM堆中的每个对象都有一个计数器,被引用就+1,断开就-1,为0就回收
(2)跟踪回收
利用JVM的对象引用图,从根结点遍历并标记对象,最后清除没被标记的对象
(3)压缩回收
把活跃的对象集中放到一个区域,然后在堆的另一端留空白(相当于清理碎片)
缺点是性能损失
(4)复制回收
把堆分为两个相同大小的区域,在任何时刻,只有其中一个区域被使用,直到这个区域被消耗完,