← 返回题目列表

Cron 表达式的格式是怎样的?如何使用?

高频 简单 第 2 / 25 题 更新于 2026/07/28
任务调度Cron表达式定时任务Quartz

简化版

Cron 表达式用来定义定时任务的触发时间规则。Quartz/Spring 的 Cron 是 6 位(或 7 位),从左到右依次是:秒 分 时 日 月 周(年)。每个位置可以用具体数字、或特殊字符:*(任意值)、?(不指定,用于日和周互斥)、-(范围)、,(枚举)、/(步长)、L(最后)、#(第几个)。例如 0 0 2 * * ? = 每天凌晨 2 点整、0 0/30 * * * ? = 每 30 分钟、0 0 9 ? * MON-FRI = 周一到周五早上 9 点。关键:「日」和「周」不能同时指定(会冲突),其中一个要用 ?

详细版

Quartz Cron 6 位格式(Spring 也用这个):

秒   分   时   日   月   周
*    *    *    *    *    ?
0-59 0-59 0-23 1-31 1-12 1-7或SUN-SAT

(注意:Linux crontab 是 5 位——分 时 日 月 周,没有秒;Quartz 是 6 位有秒。别搞混。)

特殊字符:

字符含义例子
*任意值每一个
?不指定(仅日/周)日和周互斥时用
-范围MON-FRI 周一到周五
,枚举1,15 第1和15
/步长0/30 从0开始每30
L最后L 月末、6L 最后一个周五
#第几个6#3 第三个周五
W最近工作日15W 最近15号的工作日

常见例子:

0 0 2 * * ?          每天凌晨 2 点
0 0/30 * * * ?       每 30 分钟
0 0 9 ? * MON-FRI    周一到周五早上 9 点
0 0 0 1 * ?          每月 1 号 0 点
0 0 0 L * ?          每月最后一天 0 点
0 15 10 ? * 6#3      每月第三个周五 10:15

完整版教学

一、Cron 表达式是什么

Cron 表达式是用一串字符精确描述定时任务触发时间规律的方式。定时任务框架(Quartz、Spring @Scheduled、XXL-JOB)都用 Cron 表达式来配置「任务什么时候执行」。它非常灵活,能表达从「每秒」到「每月最后一个工作日」这样复杂的时间规则。掌握 Cron 表达式是配置定时任务的基本功。

二、格式:6 位(Quartz)vs 5 位(Linux)

要先分清两种 Cron 格式,别搞混:

  • Quartz / Spring 的 Cron:6 位(可选第 7 位年),从左到右:秒 分 时 日 月 周(年)
  • Linux crontab 的 Cron:5 位,从左到右:分 时 日 月 周没有秒)。

面试和 Java 开发主要用 Quartz 的 6 位格式。各位置的取值范围:

  • :0-59
  • :0-59
  • :0-23
  • :1-31
  • :1-12(或 JAN-DEC)
  • :1-7(1=周日…7=周六,Quartz)或 SUN-SAT

三、特殊字符详解

Cron 的强大在于特殊字符,让时间规则能灵活表达:

  • *(星号)任意值/每一个。在「分」位置就是「每分钟都触发」。
  • ?(问号)不指定值,只能用在**「日」和「周」**这两个位置。用于解决日和周的冲突(见下节)。
  • -(连字符)范围MON-FRI 表示周一到周五,10-12 表示 10、11、12。
  • ,(逗号)枚举多个值1,15 表示 1 号和 15 号。
  • /(斜杠)步长/间隔0/30 在分位置表示「从 0 分开始,每 30 分钟」(即 0 分、30 分)。
  • L(Last)最后。在「日」位置 L 表示月末最后一天;在「周」位置 6L 表示当月最后一个周五。
  • #(井号)第几个。在「周」位置 6#3 表示当月第三个周五。
  • W最近的工作日15W 表示离每月 15 号最近的工作日(周末则顺延到最近的周一/周五)。

四、关键坑:日和周互斥

Cron 里最容易踩的坑是——「日」和「周」两个位置不能同时指定具体值,其中一个必须用 ?

原因:「日」和「周」会互相冲突。想想 0 0 0 15 * 1(每月 15 号 且 每周一 0 点)——15 号和周一大部分时候不是同一天,同时限定会产生歧义。所以 Quartz 规定:这两个位置,你指定其中一个、另一个就必须用 ?(表示不指定)

  • 想「每月 15 号触发」(不管星期几):0 0 0 15 * ?(周用 ?)。
  • 想「每周一触发」(不管几号):0 0 0 ? * MON(日用 ?)。

记住:日和周,指定一个、另一个用 ? 写错(都用 * 或都指定)会报错或行为不符预期。

五、常见表达式解读

多看几个常用例子,培养语感(6 位:秒 分 时 日 月 周):

  • 0 0 2 * * ? → 每天凌晨 2:00:00(秒 0、分 0、时 2、日任意、月任意、周不指定)。
  • 0 0/30 * * * ? → 每 30 分钟(分从 0 开始每 30)。
  • 0 0 9 ? * MON-FRI → 周一到周五每天 9:00(日不指定、周一到周五)。
  • 0 0 0 1 * ? → 每月 1 号 0 点。
  • 0 0 0 L * ? → 每月最后一天 0 点。
  • 0 0 12 ? * SUN → 每周日中午 12 点。
  • 0 15 10 ? * 6#3 → 每月第三个周五 10:15。
  • */10 * * * * ? → 每 10 秒。

六、常见误区与追问

这道题面试时最容易丢分的地方,是把「Cron 表达式」答成一段泛泛的组件介绍。更稳的答法是先给结论,再沿着 分布式任务调度链路 拆清楚流程,最后补上异常场景、数字边界和选型取舍。

回答层次要讲清的内容容易漏掉的边界
核心定义Cron 用字段表达周期触发时间,面试要说清秒、分、时、日、月、周以及问号、星号、斜杠等含义不要停在名词解释
流程机制解析秒分时日月周字段 -> 计算下一次触发时间 -> 到点生成触发事件 -> 提交给执行器 -> 执行完成后计算下一轮说明谁触发、谁存储、谁通知、谁兜底
工程取舍0 0/5 * * * ? 表示从每小时第 0 分钟开始每 5 分钟触发一次;0 0 2 * * ? 表示每天 2 点触发调度系统解决统一触发和治理,业务侧仍要保证幂等,因为网络抖动和重试不可避免
Cron 表达式 面试拆解:
1. 解析秒分时日月周字段
2. 计算下一次触发时间
3. 到点生成触发事件
4. 提交给执行器
5. 执行完成后计算下一轮

记忆钩子:先区分调度中心、执行器、触发、路由、分片、重试和告警,再说明如何避免重复执行;回答时一定要落到题目中的「Cron 表达式」,不要把相邻中间件的能力混着讲。

  • 误区:Cron 所有框架字段数都一样。 Linux crontab 常见 5 字段,Quartz 常见 6 或 7 字段,含秒和可选年。
  • 误区:日和周可以随便同时指定。 Quartz 中日和周通常一个指定另一个用问号,避免语义冲突。
  • 误区:Cron 能保证任务不会重叠。 Cron 只负责触发时间,任务耗时超过周期时是否并发要靠调度框架控制。
  • 追问:星号和问号区别是什么? 星号表示任意值,问号表示不指定,常用于日和周字段互斥。
  • 追问:斜杠表达什么? 表示步长,例如 0/10 在秒字段表示从 0 秒开始每 10 秒。
  • 追问:如何避免写错 Cron? 用工具预览未来触发时间,并在测试环境验证时区和字段数。

七、加强记忆

Cron 表达式定义定时任务触发时间。Quartz/Spring 是 6 位(秒 分 时 日 月 周,可选年),Linux crontab 是 5 位(分 时 日 月 周,无秒)——别搞混。特殊字符:*(任意)、?(不指定,仅日/周)、-(范围如 MON-FRI)、,(枚举)、/(步长如 0/30 每30)、L(最后:月末/最后一个周几)、#(第几个如 6#3 第三个周五)、W(最近工作日)最大的坑:日和周互斥——不能同时指定具体值,指定一个、另一个必须用 ?(每月 15 号 0 0 0 15 * ?、每周一 0 0 0 ? * MON)。常用:0 0 2 * * ?(每天2点)、0 0/30 * * * ?(每30分)、0 0 9 ? * MON-FRI(工作日9点)、0 0 0 L * ?(每月最后一天)。口诀:6 位有秒(Quartz)、日和周指定一个另一个用 ?/步长 L最后 #第几个