当前位置: 首页 > news >正文

美团一面面经

第一个问题:介绍一下最近做的项目

第二个问题:我对你项目有个地方比较感兴趣啊。就是你用的那个二级缓存,你的吞吐量有多大啊,为什么需要使用二级缓存?

答: 在二级缓存策略下,笔记详情接口的吞吐量为 9282/s , 平均响应时间为 10ms, 相比较直接走数据库查询,肯定是快的非常多。

第三个问题:缓存和数据库的一致性是如何保证的呢?

第四个问题:Redis是集中缓存,Caffeine是本地缓存,通常来说MQ的消息是机器中的一个实例去消费的,那其他实例的缓存如何解决?

第五个问题:我们在生产环境上它一个服务,可能部署多台机器。消费不会每台机器都消费同一个消息吧,所以你的代码应该考虑这种场景。

第六个问题:什么叫缓存穿透?

当用户访问的数据,既不在缓存中,也不在数据库中,导致请求在访问缓存时,发现缓存缺失,再去访问数据库时,发现数据库也没有要访问的数据,没办法构建缓存数据,来服务后续的请求。当有大量这样的请求到来时,数据库的压力骤增,这就是缓存穿透问题。

第七个问题:讲解一下布隆过滤器的原理

布隆过滤器由[初始值都为0的位图数组]和[N个哈希函数]两部分组成。当我们写入数据库时,在布隆过滤器里做个标记,这样在下次查询数据是否存在数据库时,只需要查询布隆过滤器,如果查询到数据没有被标记,说明不在数据库中。
布隆过滤器会通过3个操作完成标记:

  • 第一步,使用N个哈希函数分别对数据进行哈希计算,得到N个哈希值
  • 第二步,将第一步得到的 N 个哈希值队位图数组的长度取模,得到每个哈希值在位图数组的对应位置、
  • 第三步,将每个哈希值在位图数组的对应位置设置为1。

第八个问题:讲一下令牌桶和漏桶的区别吧。

令牌桶与漏桶算法对比

8.1. 令牌桶(Token Bucket)

  • 工作原理:令牌以固定速率生成并存储在桶中,请求需要消耗令牌来进行处理。令牌可以积攒,允许一定的突发流量。
  • 特性
    • 允许突发流量
    • 请求可以等待令牌
    • 控制流量的平均速率
  • 适用场景:API 限流、网络流量控制、带宽管理等。

8.2. 漏桶(Leaky Bucket)

  • 工作原理:请求进入桶后,以固定速率处理,如果桶满了,新的请求会被丢弃。没有突发流量,输出速率恒定。
  • 特性
    • 不允许突发流量
    • 固定速率输出
    • 超过容量的请求会丢失
  • 适用场景:防止流量洪峰、稳定带宽控制、视频流输出等。

8.3. 令牌桶与漏桶的区别

特性令牌桶(Token Bucket)漏桶(Leaky Bucket)
流量控制允许突发流量,流量灵活不允许突发流量,流量平稳
请求处理请求可以等待令牌请求超出容量会被丢弃
输出速率可变速率,平滑流量恒定速率输出
典型应用API 限流、带宽控制防止流量洪峰、视频流稳定输出
总结:
  • 令牌桶适合平滑控制并允许突发流量的场景。
  • 漏桶适合对输出速率有严格要求并不允许突发流量的场景。

第九个问题: Ratelimiter令牌桶实现流量削峰防止打垮数据库,那么这个令牌桶是本地限流吗还是全局限流?

本项目采用的是本地API进行的局部限流,没有存到Redis进行全局限流。全局限流是不管加多少机器,要求整个服务一秒。

第十个问题:能说一下Java中线程池中有哪些参数以及其中的作用。

第十一个问题:如果使用无界队列作为线程池中的阻塞队列会有什么情况。

如果在线程池中使用 无界队列(如 LinkedBlockingQueue)作为阻塞队列,可能会导致以下几个问题:

  1. 线程池的核心线程无法及时释放

无界队列没有大小限制,意味着可以无限制地接受任务。当任务被提交到线程池时,任务会被放入队列中,即使所有线程池中的工作线程都忙碌,队列也会继续接收新的任务。这样,线程池的核心线程数可能会一直存在,而不会有线程因任务完成而被释放。
结果:线程池的核心线程数不会因为任务排队而减少,可能会导致线程池中的线程始终处于活动状态,浪费系统资源。

  1. 内存占用过大

如果无界队列不断积压任务且没有适当的控制机制(如监控队列长度或主动抛弃任务等),可能会导致内存被任务堆积消耗,甚至导致 内存溢出。虽然无界队列不会像有界队列那样会阻塞新任务的提交,但无止境的任务积压会占用大量内存。
结果:内存消耗增大,可能导致 OutOfMemoryError 或系统性能下降。

  1. 无法控制队列的积压

使用无界队列时,线程池的负载可能无法被有效控制。线程池会尽最大能力执行任务,但是队列会无限制增长,从而影响系统的稳定性。没有队列大小的限制,无法保证任务的积压程度,导致任务可能会一直等待而得不到及时执行。
结果:可能出现某些任务长时间没有执行,系统响应时间不可预测,甚至导致任务丢失(如果不处理好队列)。

  1. 可能导致线程池过载

在一些极端情况下,如果系统不断提交任务而没有足够的工作线程来执行这些任务,尽管线程池会尝试分配空闲线程执行任务,但由于无界队列的存在,任务会无限制地积压,这就会导致线程池的负载过重,可能导致 资源耗尽(如 CPU 和内存等)。
结果:系统的性能会严重下降,甚至可能崩溃。

  1. 任务的延迟执行

无界队列可能导致任务的执行延迟,因为任务会被推入队列中等待执行,而队列的大小没有限制,可能会导致任务在队列中等待很长时间。虽然不会立即丢失任务,但任务的执行时间变得不可预测,系统的响应性降低。
6. 没有流量控制

有界队列能够有效地控制队列中的任务量,防止提交过多任务给线程池。而无界队列则没有这个控制能力,线程池可能会因为接收过多任务而导致过载,这样无法动态地应对高负载的情况。

解决方法:

使用有界队列:可以为队列设置大小限制,防止任务积压过多。常用的有界队列如 ArrayBlockingQueue。
使用自定义拒绝策略:当队列满时,可以通过 RejectedExecutionHandler 设置拒绝策略,抛弃任务、抛出异常、或者直接将任务提交到外部队列等。
动态调整线程池大小:可以通过合理的核心线程数和最大线程数来控制线程池的并发能力,避免过度并发。

总的来说,使用无界队列时需要谨慎,合理配置线程池和队列,确保系统的稳定性和性能。如果没有适当的流量控制和任务限制机制,可能导致系统过载、内存消耗过大或者任务积压问题。

http://www.lryc.cn/news/525075.html

相关文章:

  • 什么是报文的大端和小端,有没有什么记忆口诀?
  • Spring中BeanFactory和ApplicationContext的区别
  • 期货行业专题|基于超融合实现 IT 基础设施现代化与国产化转型实践合集
  • AI新玩法:Flux.1图像生成结合内网穿透远程生图的解决方案
  • Jenkins-pipeline Jenkinsfile说明
  • vue3中为什么引入setup,引入setup是为了解决什么问题,setup的执行时机是什么?返回值是什么
  • Ubuntu 安装 docker 配置环境及其常用命令
  • 自动化01
  • 音频入门(二):音频数据增强
  • MySQL管理事务处理
  • MySQL数值型函数详解
  • 54.DataGrid数据框图 C#例子 WPF例子
  • 总结6..
  • 复位信号的同步与释放(同步复位、异步复位、异步复位同步释放)
  • Gartner发布2025年网络治理、风险与合规战略路线图
  • 基于STM32的智能空气质量监测与净化系统设计
  • 人工智能之数学基础:线性代数中的线性相关和线性无关
  • 08 工欲善其事必先利其器—常用类
  • Redis实战-初识Redis
  • spring boot中实现手动分页
  • 【优选算法】5----有效三角形个数
  • C++打字模拟
  • 最新版pycharm如何配置conda环境
  • UML-对象图(Object Diagram)
  • Jmeter 动态参数压力测试时间段预定接口
  • 超大型集团合并报表数智管理转型
  • [MCAL]Mcu配置
  • Qt基础项目篇——Qt版Word字处理软件
  • 算法刷题笔记——图论篇
  • Java空指针异常处理:判空、Optional与Assert解析