字节面试的这道Java面试题各位能答上来吗:谈谈你对时间轮的理解?

简介: 一位工作了 7 年的程序员,去字节面试,被问到时间轮的问题。他说这个问题超出了他的知识面,自己也在网上也找了一些文章学习,但还是理解得不是很深刻。他希望让我出一期关于时间轮的面试题解析。今天,就给这位粉丝安排。

一位工作了 7 年的程序员,去字节面试,被问到时间轮的问题。他说这个问题超出了他的知识面,自己也在网上也找了一些文章学习,但还是理解得不是很深刻。他希望让我出一期关于时间轮的面试题解析。今天,就给这位粉丝安排。

另外,我把往期分享的视频全部整理成一份500页的PDF面试题解析配套文档,希望能够以此来提高各位粉丝的通过率,

ee90d9963df444db88b33d6e798a5b94.gif

如何获取? :

扫描文章底部名片领取!

1、什么是时间轮

时间轮,简单理解就是一种=个用来存储定时任务的环状数组,它的工作原理和钟表的表盘类似。

0b6606ca78a6db8e8c20651d3b78629a.jpg

它由两个部分组成, 一个是环状数组,另一个是遍历环状数组的指针。

首先,要定义一个固定长度的环状数组,然后数组的每一个元素代表一个时间刻度,假设每个刻度间隔是 1s,那么长度为 8 的数组,就代表 8 秒钟。

然后,就是有一个指针,这个指针按照顺时针无限地循环这个数组,每隔1个最小的时间单位就前进一个数组索引。

227ada304a4d465018ab4d256807ad78.jpg

这个指针完整地转1圈,就代表 8 秒钟,转两圈表示 16 秒,假设从 0 点 0 分 0 秒开始,转

一圈以后就到了 0 点 0 分 9 秒钟。

2、工作原理

时间轮,环状数组里面的每个元素,都是用来存储定时任务的容器,当我们向时间轮里面添加一个定时任务的时候,我们会根据定时任务的执行时间计算它所存储的数组下标。当然,有可能在某个时间刻度上会存在多个定时任务,这个时候会采用双向链表的方式来存储。

37c664988a74506218eef44328c51c29.jpg

当指针指向某个数组的时候,就会把这个数组中存储的任务取出来,然后遍历这个链表逐个运行里面的任务。

那如果某个定时任务的执行时间大于环形数组所表示的长度,一般可以使用一个圈数来表示该任务的延迟执行时间。比如,1个第 16 秒要执行的任务,那意味着这个任务应该是在第2圈的数组下标 为0 的位置执行。

3、优、缺点分析

使用时间轮的方式来管理多个定时任务的好处有很多,我认为有两个比较重要的优点:

1、减少定时任务添加和删除的时间复杂度,提升性能。

2、可以保证每次执行定时器任务都是 O(1)复杂度,在定时器任务密集的情况下,性能优势非常明显。

当然,时间轮也有缺点,对于执行时间非常严格的任务,时间轮不是很适合,因为时间轮算法的精度取决于最小时间单元的粒度。假设以 1s 为一个时间刻度,那小于 1s 的任务就无法被时间轮调度。

时间轮算法在很多框架中都有用到,比如 Dubbo、Netty、Kafka 等。

时间轮算法也是一个比较经典的设计。使用范围比较广,但是在实际应用中,大部分同学接触非常少。我认为这种设计思想或者这种数据结构,在我们实际应用中的某些特定场景也是可以借鉴和使用的。比如定时重试、衰减重试等等。

最后,我把往期分享的面试题全部整理成了1份10W字的文档,希望能够以此来提高各位粉丝的通过率

ee90d9963df444db88b33d6e798a5b94.gif

我是被编程耽误的文艺Tom,只弹干货不掺水!你们的支持就是我最大的动力!关注我,面试不再难!

相关文章
|
1月前
|
监控 Java 应用服务中间件
高级java面试---spring.factories文件的解析源码API机制
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置、起步依赖和内嵌服务器等特性,极大地简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是spring.factories文件的解析源码API机制。
77 2
|
27天前
|
Java 程序员
Java社招面试题:& 和 && 的区别,HR的套路险些让我翻车!
小米,29岁程序员,分享了一次面试经历,详细解析了Java中&和&&的区别及应用场景,展示了扎实的基础知识和良好的应变能力,最终成功获得Offer。
67 14
|
1月前
|
存储 缓存 算法
面试官:单核 CPU 支持 Java 多线程吗?为什么?被问懵了!
本文介绍了多线程环境下的几个关键概念,包括时间片、超线程、上下文切换及其影响因素,以及线程调度的两种方式——抢占式调度和协同式调度。文章还讨论了减少上下文切换次数以提高多线程程序效率的方法,如无锁并发编程、使用CAS算法等,并提出了合理的线程数量配置策略,以平衡CPU利用率和线程切换开销。
面试官:单核 CPU 支持 Java 多线程吗?为什么?被问懵了!
|
1月前
|
存储 算法 Java
大厂面试高频:什么是自旋锁?Java 实现自旋锁的原理?
本文详解自旋锁的概念、优缺点、使用场景及Java实现。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
大厂面试高频:什么是自旋锁?Java 实现自旋锁的原理?
|
29天前
|
NoSQL 中间件 Java
字节面试:聊聊 CAP 定理?哪些中间件是AP? 哪些是CP? 说说 为什么?
45岁老架构师尼恩在其读者交流群中分享了关于CAP定理的重要面试题及其解析,包括CAP定理的基本概念、CAP三要素之间的关系,以及如何在分布式系统设计中权衡一致性和可用性。文章还详细分析了几种常见中间件(如Redis Cluster、Zookeeper、MongoDB、Cassandra、Eureka、Nacos)的CAP特性,并提供了高端面试技巧,帮助读者在面试中脱颖而出。尼恩还推荐了其团队编写的《尼恩Java面试宝典PDF》等资料,助力求职者准备面试,提升技术水平。
|
1月前
|
Java 编译器 程序员
Java面试高频题:用最优解法算出2乘以8!
本文探讨了面试中一个看似简单的数学问题——如何高效计算2×8。从直接使用乘法、位运算优化、编译器优化、加法实现到大整数场景下的处理,全面解析了不同方法的原理和适用场景,帮助读者深入理解计算效率优化的重要性。
36 6
|
1月前
|
存储 缓存 Java
大厂面试必看!Java基本数据类型和包装类的那些坑
本文介绍了Java中的基本数据类型和包装类,包括整数类型、浮点数类型、字符类型和布尔类型。详细讲解了每种类型的特性和应用场景,并探讨了包装类的引入原因、装箱与拆箱机制以及缓存机制。最后总结了面试中常见的相关考点,帮助读者更好地理解和应对面试中的问题。
67 4
|
2天前
|
Java
Java—多线程实现生产消费者
本文介绍了多线程实现生产消费者模式的三个版本。Version1包含四个类:`Producer`(生产者)、`Consumer`(消费者)、`Resource`(公共资源)和`TestMain`(测试类)。通过`synchronized`和`wait/notify`机制控制线程同步,但存在多个生产者或消费者时可能出现多次生产和消费的问题。 Version2将`if`改为`while`,解决了多次生产和消费的问题,但仍可能因`notify()`随机唤醒线程而导致死锁。因此,引入了`notifyAll()`来唤醒所有等待线程,但这会带来性能问题。
Java—多线程实现生产消费者
|
4天前
|
安全 Java Kotlin
Java多线程——synchronized、volatile 保障可见性
Java多线程中,`synchronized` 和 `volatile` 关键字用于保障可见性。`synchronized` 保证原子性、可见性和有序性,通过锁机制确保线程安全;`volatile` 仅保证可见性和有序性,不保证原子性。代码示例展示了如何使用 `synchronized` 和 `volatile` 解决主线程无法感知子线程修改共享变量的问题。总结:`volatile` 确保不同线程对共享变量操作的可见性,使一个线程修改后,其他线程能立即看到最新值。
|
4天前
|
消息中间件 缓存 安全
Java多线程是什么
Java多线程简介:本文介绍了Java中常见的线程池类型,包括`newCachedThreadPool`(适用于短期异步任务)、`newFixedThreadPool`(适用于固定数量的长期任务)、`newScheduledThreadPool`(支持定时和周期性任务)以及`newSingleThreadExecutor`(保证任务顺序执行)。同时,文章还讲解了Java中的锁机制,如`synchronized`关键字、CAS操作及其实现方式,并详细描述了可重入锁`ReentrantLock`和读写锁`ReadWriteLock`的工作原理与应用场景。