当年我还是个学生的时候,有一次去参加欢聚时代的一个面试,有一道面试题记忆尤新,让你来实现一个定时任务,你会怎么做?为了简化问题,我们只用考虑内存方案,不用考虑数据持久化。

数组法

最简单的,我们可以把所有的任务存放在一个数组里面,然后,每隔单位时间遍历整个数组,找到是否有任务满足当前时间,如果有,那么从数组中取出,然后执行。每隔单位时间查询算法复杂度为O(N)。

那么,新增一个任务怎么操作呢?我们只要简单地往数组中追加一个元素即可,算法时间复杂度为O(1)

优先队列法

评估一个算法,我们既要考虑它的查询算法复杂度,也要考虑他的插入算法复杂度。在定时任务场景中,很显然,查询场景是非常多的。几乎我们每个单位时间都要轮询一遍,那么我们有没有优化算法的可能呢?

我们每次查询,都只要查询时间最接近当前时间的,时间比当前时间更早的,肯定被我们丢弃了。所以这个题目,等价于我们查询队列里面时间最小的。我们不禁想到一个熟悉的数据结构,优先队列!活着我们可以使用一个小根堆进行实现。

每次我们插入一个新的定时任务,我们将一个任务插入优先队列,每次插入的时候,队列内部需要进行调整,算法时间复杂度为O(logN)。值得注意的是,在讨论算法时间复杂度的时候,logN是Base2的,也就是说,如果N等于8的时候,logN就是3。

同理,虽然我们可以在O(1)的时间里面找到时间最小的任务,但是如果我们取出这个元素,优先队列需要做内部的调整,这个算法时间复杂度也是O(logN)的。

时间轮法

上述优先队列的算法,综合算法时间复杂度是O(logN)的,已经很高效了,但是在我们大并发的分布式系统下,这个速度,还是太慢了。我们有没有更高效的算法呢?

那便是时间轮算法,时间轮是一个环形队列,按照时间的单位区分,我们假设1秒,每个单位里面,是一个链表,用来存储定时任务。

可能你会问,一个环形队列里面的元素,毕竟是优先的,如果超过了长度,我们该怎么办呢?我们可以联想到我们家里的水表,是不是也有很多个轮子,每一个轮子的单位不一样!

同样,时间轮也是如此,我们可以用多级时间轮进行优化,就跟我们的时钟或者水表一样,这一层的走了一圈,下一层的才走了一格。

那么,这个算法的 时间复杂度怎么计算呢?插入的时候,我们从最低层开始查找,找到在哪一层,然后直接插入对应的刻度。假如我们的时间轮有5层,那么我们最多查找5次。

查询的时候,我们每一秒都是推动时间轮的滚动,每次都是直接取队首的元素,相当于算法时间复杂度为O(1)。当转了一圈的时候,把下一层的下一格再推下来。这样子,我们一个元素,最多会从第5层,逐渐插到第1层,综合下来一个元素最多会被插入5次,在算法时间复杂度评估的时候,我们通常会忽略常数,最终算法时间复杂度为O(1)。

总结

一个非常简单的面试题,竟然有好几种不同的解法。这才是算法与数据结构的魅力,欢迎大家关注我,共同学习,共同进步。大家的支持是我继续唠嗑的动力。同名公众号(沙茶敏碎碎念)

hutool的定时任务不支持依赖注入怎么办_设计一个任务调度算法,时间轮算法,比优先队列更高效...相关推荐

  1. hutool的定时任务不支持依赖注入怎么办_分布式任务调度平台xxljob的内部原理,及在转转的落地实践...

    让世界因流转更美好 值此教师节来临之际,衷心祝愿所有的老师教师节快乐,身体健康,幸福平安,工作顺利,桃李满天下.您们辛苦了! 作者简介 · 杜云杰,架构师,转转架构部负责人,负责服务治理.MQ.云平台 ...

  2. hutool的定时任务不支持依赖注入怎么办_可调度定时任务在SpringBoot中的实践

    定时任务在我们的项目中或多或少都会使用到,不论你是初级程序员,还是有多年工作经验的中高级程序员,在项目中加一个定时任务去处理业务的一个aspect,为什么用了一个英文单词'aspect'?而不是'切面 ...

  3. hutool的定时任务不支持依赖注入怎么办_「架构」 - 定时任务 amp; Elastic-Job基本使用...

    一.配置zookeeper A.下载配置 # 下载zookeeper wget http://mirror.bit.edu.cn/apache/zookeeper/zookeeper-3.4.13/z ...

  4. 创建支持依赖注入、Serilog 日志和 AppSettings 的 .NET 5 控制台应用

    翻译自 Mohamad Lawand 2021年3月24日的文章 <.NET 5 Console App with Dependency Injection, Serilog Logging, ...

  5. ASP.NET Core Filter如何支持依赖注入

    概述 通过使用 ASP.NET Core 中的筛选器,可在请求处理管道中的特定阶段之前或之后运行代码.内置筛选器处理任务,例如:授权(防止用户访问未获授权的资源).响应缓存(对请求管道进行短路出路,以 ...

  6. 【朝夕技术专刊】Core3.1WebApi_Filter多种注册方式支持依赖注入

    欢迎大家阅读<朝夕Net社区技术专刊>第5期 我们致力于.NetCore的推广和落地,为更好的帮助大家学习,方便分享干货,特创此刊!很高兴你能成为忠实读者,文末福利不要错过哦! 01 PA ...

  7. python需要依赖注入吗_是否需要使用依赖注入容器?

    译文首发于 是否需要使用依赖注入容器?,转载请注明出处. 本文是依赖注入(Depeendency Injection)系列教程的第 2 篇文章,本系列教程主要讲解如何使用 PHP 实现一个轻量级服务容 ...

  8. .Net之时间轮算法(终极版)定时任务

    TimeWheelDemo 一个基于时间轮原理的定时任务 对时间轮的理解 其实我是有一篇文章(.Net 之时间轮算法(终极版)[1])针对时间轮的理论理解的,但是,我想,为啥我看完时间轮原理后,会采用 ...

  9. 【定时任务】时间轮算法

    目录 1 从定时任务说起 2 初识时间轮 3 绝对时间和相对时间 4 需要重复执行多次的任务 5 同一时刻存在多个任务 6 时间轮的数据结构 7 时间刻度不够用怎么办? 7.1 增大时间轮的刻度 7. ...

最新文章

  1. 日本推出机器人代理相亲,相亲现场帮你自我介绍
  2. Boost:序列化服务的测试程序
  3. 阿里云云客服平台正式商业化
  4. Android仿美团加载数据、小人奔跑进度动画对话框(附顺丰快递员奔跑效果)
  5. linux多线程select定时器,linux使用select实现精肯定时器详解
  6. PyCharm 2020.2.3复制粘贴及删除键修正
  7. Zalo营销大师2019版
  8. xpraid安装_在Win2003/XP安装光盘中集成RAID驱动 不用软驱装RAID/SATA/SAS驱动
  9. 利用谷歌浏览器模拟网速慢的情况
  10. Esp8266(NodeMCU)物联网芯片的基本简介
  11. win10自带的删除电脑流氓弹窗软件工具怎么用
  12. 全新小旋风万能蜘蛛池9.02开心版/站长必备SEO+带教程
  13. 东东动态夏目猫咪老师404官网html源码
  14. [机器学习] --- 红楼梦后四十回到底是谁写的?机器学习分析法
  15. 艾兰岛编辑器-实体模板
  16. Opencv的使用小教程3——利用轮廓检测实现二维码定位
  17. php 5万并发量怎么解决方案,【教程经验】PHP 并发场景的几种解决方案
  18. 【LeetCode - 1244】力扣排行榜
  19. 第三方支付(二):揭秘第三方支付包含哪些业务 | 牌照角色篇
  20. 中国蓝莓种植深加工市场分析及投资前景预测报告2022-2028年

热门文章

  1. LeetCode 212. 单词搜索 II(Trie树+DFS)
  2. nineoldandroid使用_nineoldandroid 详细使用并且实现drawerlayout侧滑动画
  3. 日期传递过程_买东西别再只看生产日期和保质期了!快算算你一天吃了多少添加剂?...
  4. python 量化交易_基于Python的量化交易工具清单(上)
  5. 微信小程序正则判断姓名和手机号
  6. 利用python创建学生管理系统软件代码赏析
  7. 科研福利!国内TOP3的超算中心,免费领2000核时计算资源
  8. Litho在美团动态化方案MTFlexbox中的实践
  9. python中mysql更新字段中传参问题
  10. 从特征分解到协方差矩阵:详细剖析和实现PCA算法