Kubernetes Job与CronJob实战:从原理到YAML编写与排障

用Kubernetes跑服务跑久了,你会发现工作负载并不只有“常驻”这一种形态。很多场景需要的是跑一次就结束的任务:数据迁移、批量回刷、报表生成,或者每天固定时间跑一次的定时任务。Kubernetes专门为这两类需求设计了两个控制器:Job,负责运行一次性任务;CronJob,负责按时间表定时触发Job。这篇文章不会照搬官方文档,我会把这两个资源从原理、YAML写法、实操命令到常见坑一次性讲清楚,零基础也完全能跟着动手跑一遍。

1. 为什么需要 Job 和 CronJob?

1.1 工作负载的三种“生命周期”

在Kubernetes里,不同的控制器对应不同的任务脾气。Deployment、StatefulSet这种是“长期服役型”,它们的目标是保持Pod永远在跑,就算容器挂了也要立刻拉起来,用户随时都能访问到服务。而Job和CronJob则属于“跑完就走型”和“到点就干型”。

用一个超市的比喻来看:Deployment像是便利店的全职店员,开门就在,打烊才走;Job像是临时工,接到一个任务(例如盘点库存),干完活就下班,不会一直耗在店里;CronJob像是店长设置好的闹钟,每到固定时间就自动喊一个临时工来干活,比如每天凌晨三点补货、每周一早上清算账目。

这个“生命周期”差异是最核心的认知。很多刚接触Kubernetes的人会把一次性任务也塞进Deployment,然后部署一个永远空转的容器来“占坑”,靠外部脚本去触发里面的业务逻辑。这样做不是不行,但非常别扭:空转容器浪费资源,任务结束了系统也不知道,日志和状态都得自己想办法收集,更不用说并发控制、失败重试这些能力全部要自己写。

1.2 什么样的任务适合交给 Job

Job天生适合那些“进程退出即代表任务完成”的工作。常见的例子包括:

  • 数据库迁移、历史数据回刷、字段补录;
  • 批处理计算,比如按天汇总埋点数据;
  • 生成报表、导出数据文件;
  • 镜像构建、依赖打包等CI/CD场景的收尾任务;
  • 一次性初始化,比如创建数据库表结构、预置数据字典。

这类任务有一个共同特征:业务代码执行完,容器进程会正常退出,而且退出码是0。Job控制器会盯着这个结果,把任务的完成情况记录在状态里。

如果一个任务跑完容器却不会自动退出,那它就不适合直接交给Job来处理,除非你在业务代码里显式增加了退出逻辑。同样的,CronJob则是“定时触发”的Job,只要把任务包进Job模板里,剩下的时间调度就交给它了。

2. Job 的核心模型:这些参数决定了任务怎么跑

2.1 先写一个最小的 Job

看一段最基础的Job定义:

apiVersion: batch/v1 kind: Job metadata: name: first-job spec: template: spec: containers: - name: task image: busybox:1.36 command: ["/bin/sh", "-c", "echo job is done && sleep 3"] restartPolicy: Never

逐行解释一下。apiVersion用的是batch/v1,这是Job和CronJob的API组;kind就是Job;spec.template里写的其实是Pod模板,结构和Deployment里的Pod模板一模一样。但注意,这里没有replicas字段,因为Job不直接声明“我要跑几个副本”,而是通过completions和parallelism来管理,这个下一节会说。

还有一个必须注意的点:spec.template.spec.restartPolicy在Job里只能设成Never或者OnFailure,绝对不能设成Always。原因很简单:如果容器退出后总是被重新拉起来,那任务永远没有结束的一天,Job也就失去了“跑完即止”的意义。你如果写成Always,API Server会直接拒绝创建。

创建这条Job只需要一条命令:

kubectl apply -f first-job.yaml

然后观察:

kubectl get job kubectl get pods -l job-name=first-job

你会发现Pod很快从ContainerCreating变成Running,又变成Completed。整个生命周期里,没有哪个ReplicaSet在背后“保活”,因为Job根本不关心保活,它只关心“有没有成功跑完”。

2.2 completions 和 parallelism:跑几个、怎么跑

这是Job最重要的两个参数,绝大多数业务场景都是在跟这两个字段较劲。

先看默认情况:如果不写completions和parallelism,它们的默认值都是1,表示“只创建1个Pod,成功1次就结束”。这适合临时任务。

改成串行执行多个任务:

spec: completions: 3 parallelism: 1

意思是“总共要成功完成3次,但同一时间只跑1个Pod”。第一个Pod成功退出后,控制器创建第二个,再成功退出,创建第三个,直到COMPLETIONS列变成3/3。这种模式适合有先后依赖关系的批处理,比如先删旧数据、再灌新数据、最后做校验。

再看固定并行度:

spec: completions: 10 parallelism: 3

意思是“一共要成功10次,但允许同时最多跑3个Pod”。控制器会动态创建Pod:刚开始一次性创建3个,其中某个成功退出后,马上再创建一个补齐,始终维持有3个在跑,直到成功总数达到10。适合处理一批相互独立的任务,比如把100个文件分片上传。

还有一种组合是parallelism大于completions,比如completions: 3、parallelism: 5,控制器会一口气创建5个Pod,多出来的2个可能处于等待状态,实际上意义不大。我建议保持parallelism小于等于completions,否则不仅浪费资源,还容易让人对“进度”产生误解。

这里有一个很有用的设计:当配置了completions大于1时,Kubernetes会给每个Pod注入一个JOB_COMPLETION_INDEX环境变量,从0开始递增,标识这个Pod负责第几个完成位置。

echo "我是第 ${JOB_COMPLETION_INDEX} 个分片"

如果你的任务需要分片处理(比如10个分片的数据),这个变量可以直接帮你区分每个Pod应该处理哪一段数据,非常顺手。

2.3 backoffLimit 和 activeDeadlineSeconds:失败之后怎么办

任务不可能永远一帆风顺。镜像拉不下来、磁盘写满、代码抛出异常,Pod都会失败。Job对待失败的态度不是无限重试,而是受制于两个参数。

backoffLimit:默认值是6,表示最多允许“失败的Pod个数”为6。注意这里不是“重试6次”。如果你设置parallelism: 5并且5个Pod同时全部失败,那一次就消耗掉5个额度,控制器只够再重试1个Pod。超过额度后,Job会被标记为失败,整体状态显示Failed。

activeDeadlineSeconds:给整个Job设定一个运行时间上限。比如你预期任务30分钟能跑完,但害怕出现“僵尸进程卡住不退出”的情况,就设置activeDeadlineSeconds: 3600,一旦整个Job从开始到当前时间超过3600秒还没完成,控制器会直接终止所有关联Pod,并把Job标记为失败。

这里还要强调一个很容易被忽略的编程要求:业务逻辑必须幂等。因为Job重试会重新创建Pod,完全可能把同一段逻辑执行两遍。比如一个“给用户充值”的任务,如果在执行中途失败,重试时又把相同请求发送一次,用户就会收到两份钱。解决思路有几种:

  • 数据库里加唯一索引,重复提交直接跳过;
  • 业务代码里先查再写,状态已经是目标值就说明之前做过;
  • 利用JOB_COMPLETION_INDEX做分片锁,同一个分片不会同时被两个Pod处理。

2.4 任务完成后怎么自动清理

Job完成后,对应的Pod不会自动消失,会以Completed状态留在集群里。这是为了让你有时间看日志。但如果任务频繁执行,一堆Completed Pod堆在那里也会占用资源。

从Kubernetes 1.23开始,可以在Job的spec里加上:

spec: ttlSecondsAfterFinished: 100

意思是Job完成后100秒,控制器自动把这个Job以及它管理的Pod整个清掉。实际操作中我一般设成300到600秒,既留出观察日志的时间,又不会让历史任务堆积成灾。

3. 亲手运行一个 Job:从创建到日志到清理

3.1 准备一个练习环境

学习Job不需要特别复杂的集群,Minikube、Kind这种单节点集群完全够用。只要有kubectl能连上集群就行。建议先建一个独立的namespace,避免练习的Pod和正式环境的资源混在一起:

kubectl create ns job-demo

后续所有命令都带着-n job-demo,或者先把上下文切过去:

kubectl config set-context --current --namespace=job-demo

3.2 创建带索引的批处理任务

我们创建一个能体现completions和索引特性的Job。它的功能非常简单:跑3个Pod,每个Pod输出自己是第几个分片,然后睡10秒模拟业务处理。

apiVersion: batch/v1 kind: Job metadata: name: batch-hello spec: completions: 3 parallelism: 1 template: spec: restartPolicy: Never containers: - name: echo image: busybox:1.36 command: - /bin/sh - -c - | echo "Task ${JOB_COMPLETION_INDEX} started" sleep 10 echo "Task ${JOB_COMPLETION_INDEX} done"

这里我把parallelism设为1,目的是看到严格串行的效果:第一个Pod跑完,第二个才会创建。

保存为batch-hello.yaml后执行:

kubectl apply -f batch-hello.yaml

3.3 用三个命令观察完整生命周期

开一个终端窗口,实时查看Job状态:

kubectl get job -w

你会看到COMPLETIONS从0/3变成1/3、2/3、最后3/3。这就是控制器在“数数”:每多一个成功Pod,计数就加一。

再看Pod列表:

kubectl get pods -l job-name=batch-hello

刚开始可能只有一个Pod,名字是batch-hello-xxxxx。等它Completed之后,才会出现第二个。串行效果一目了然。

等Job显示3/3之后,查看某个Pod的日志:

kubectl logs pod/batch-hello-xxxxx

你应该能看到类似下面这样的输出:

Task 0 started Task 0 done

通过kubectl describe job batch-hello可以看到更详细的信息,包括事件的完整时间线:什么时候创建Pod、Pod什么时候成功退出、Job什么时候判定完成。排障时这个命令非常有用。

3.4 清理:先看日志再删Job

看完日志,任务就可以删掉了:

kubectl delete job batch-hello

删除Job会把它下面管理的Pod一起清掉。所以我的习惯是:先收集所有需要留存的日志,再去删Job。如果Job设置了ttlSecondsAfterFinished,甚至不需要手动删。

实际操作中还有一个细节:如果某个Pod失败了,你想手动删除它,Job控制器会认为“这个位置缺人”,立刻创建一个新Pod顶上来。这是Job的自我修复逻辑,不是故障。

4. 进阶操作:多个 Pod 并发处理任务队列

4.1 固定任务数并行和工作队列模式

上面例子是串行,但很多业务场景需要并行:一大批数据要按分片处理,10个Pod同时开跑,速度能快好几倍。

Job支持两种主流的并行风格:

  • 固定任务数并行:预先知道总共要完成多少份工作,设置completions: N、parallelism: M;
  • 工作队列模式:任务总量不确定,Pod自己去一个外部队列领活,领完就退出,不设置completions。

零基础阶段,先把固定任务数并行吃透就够了。工作队列模式往往需要依赖消息中间件,等真正到了生产环境再学也不迟。

4.2 一个能落地的分片并行案例

假设业务表里有10万条用户数据,需要为每条数据补算一个“会员等级”。如果把所有数据都放在一个Pod里串行处理,可能要跑两三个小时;拆成多个分片并行,时间能缩短到十几分钟。

在Job里可以这样设计:

  • completions: 20:把10万条数据拆成20个分片,每个分片5000条;
  • parallelism: 4:同时最多4个Pod跑,防止数据库连接被压垮;
  • 每个Pod通过JOB_COMPLETION_INDEX知道自己负责第几个分片;
  • 业务SQL里用取模方式定位分片,例如:
UPDATE user SET vip_level = 'gold' WHERE user_id % 20 = ${JOB_COMPLETION_INDEX} AND vip_level != 'gold';

这个SQL本身就幂等,因为WHERE条件限制了只会处理自己分片内的数据,而且即使重复执行,vip_level已经是gold的数据也不会被再次更新。

这里我想提醒一个容易踩的坑:并发度不是越大越好。如果数据库连接池上限是100,每个Pod要占20个连接,那parallelism最多只能设5,设成10大概率会把数据库连接池打爆。合理并行度可以按这个公式估算:

合理并行度 = min(集群可用Pod配额, 数据库连接池上限 / 每个Pod连接数, 业务可容忍的峰值压力)

保守起见,刚开始先设小一点,看监控曲线再逐步上调。生产环境千万不要一上来就parallelism: 50。

4.3 索引失败重试的一个小细节

固定任务数并行模式下,如果某个Pod失败,新创建的Pod会继承原来那个Pod的JOB_COMPLETION_INDEX,相当于“同一分片换个人继续干”。这种设计保证了分片不会丢失,也让进度统计变得可靠。

遇到失败时,你可以通过Pod的标签筛选出失败记录:

kubectl get pods -l job-name=xxx --field-selector=status.phase=Failed

观察失败Pod的日志,多半能找到原因。排查完再删掉失败Pod,让控制器重新创建一个补齐分片。

5. CronJob:定时任务的调度者

5.1 CronJob 和 Job 的关系

CronJob其实是一个“定时触发器包着Job模板”的复合体。每到设定的时间点,CronJob控制器会基于jobTemplate创建一个真实的Job,然后Job再去创建Pod。所以YAML结构上是典型的俄罗斯套娃:CronJob里套一个Job的spec,Job的spec里再套一个Pod模板。

apiVersion: batch/v1 kind: CronJob metadata: name: cron-job spec: schedule: "0 2 * * *" jobTemplate: spec: template: spec: restartPolicy: OnFailure containers: - name: task image: busybox:1.36 command: ["/bin/sh", "-c", "echo timer works"]

CronJob创建的Job,名字会自动带上时间戳,类似cron-job-1721234567,查日志时一眼就能认出是哪个周期的任务。

5.2 Cron 表达式的5个字段

Linux用户看到这个应该不陌生,CronJob的表达式和系统crontab基本一致,一共5个字段:

分钟 小时 日期 月份 星期

常用的几组写法:

表达式含义
0 2 * * *每天凌晨2点
*/15 9 * * 1-5工作日每天9点起每15分钟一次
0 0 1 * *每月1号零点
30 20 * * 0每周日晚上8点半
*/5 * * * *每5分钟一次(调试时好用)

调试CronJob时,我习惯先用*/5 * * * *快速验证逻辑,确认没问题再改成正式的调度周期。等任务真正跑起来,再改成每天、每周这种低频周期。

5.3 时区问题:最容易踩的坑

CronJob的调度时间是按照kube-controller-manager所在节点的时区计算的,而大部分集群默认是UTC。在中国大陆,你写0 2 * * *,实际跑的是UTC凌晨2点,也就是北京时间早上10点。这个问题上线的团队基本都踩过。

解决办法有三种:

第一种,手动把cron表达式换算成UTC时间。北京时间凌晨2点,UTC是前一天傍晚6点:

schedule: "0 18 * * *"

第二种,如果集群版本较新,可以直接在CronJob里写timeZone字段:

spec: schedule: "0 2 * * *" timeZone: "Asia/Shanghai"

这个字段在较新的Kubernetes版本中支持,用之前先确认一下集群版本。好处是直观,缺点是如果集群版本太老,YAML可能无法通过校验。

第三种,在容器内部设置TZ环境变量:

env: - name: TZ value: "Asia/Shanghai"

但这只能保证容器内日志时间显示正确,改变不了调度器的触发时间。经常有人在这里产生误解:明明容器里时间是北京时间了,为什么任务还是提前了8小时跑?答案就是时区问题出在调度层,不在容器层。

5.4 并发策略、宽限期与历史保留

CronJob有四个容易被忽略的参数,生产环境几乎必设。

第一个是concurrencyPolicy,三个值:

  • Allow:允许并发。上次任务没跑完,这次到点照常新起一个Job;
  • Forbid:禁止并发。上次没跑完,这次直接跳过;
  • Replace:上次没跑完,把上次的取消掉,开启这次的。

默认是Allow。如果你的任务要求互斥(比如数据库锁表备份),一定要设成Forbid,否则两个任务同时操作同一批数据,后果只能自己扛。

第二个是startingDeadlineSeconds,指错过调度后最多追补多长时间。比如集群短暂不可用,错过了凌晨2点的任务,如果设置了600,控制器会在2点过后的600秒内尝试补执行;如果超过了这个窗口,这次调度就算彻底错过,并且被记录为失败。不设置这个字段,一旦控制器长时间停机,可能会一次性把成百上千次错过的调度全部补执行,直接把下游系统压垮。

第三个是历史记录保留数:

spec: successfulJobsHistoryLimit: 3 failedJobsHistoryLimit: 3

默认值分别是3和1。设太小不利于排查问题,设太大资源消耗也大。我通常都设3到5,够用且不占地。

第四个是suspend,用来暂停调度。比如某天要停机维护,又不想删除CronJob定义,可以把suspend设成true,恢复时再改回false。注意,suspend只影响之后新的调度,不会清理历史Job。

5.5 一个完整的日志清理 CronJob

下面这个例子综合了上面所有要点:每天凌晨2点(北京时间)清理临时目录,同一时间段只允许一个任务,任务本身最多运行10分钟,完成后保留最近3次成功记录:

apiVersion: batch/v1 kind: CronJob metadata: name: daily-tmp-clean spec: schedule: "0 18 * * *" timeZone: "Asia/Shanghai" concurrencyPolicy: Forbid startingDeadlineSeconds: 600 successfulJobsHistoryLimit: 3 failedJobsHistoryLimit: 3 jobTemplate: spec: backoffLimit: 2 activeDeadlineSeconds: 600 template: spec: restartPolicy: OnFailure containers: - name: cleaner image: busybox:1.36 command: - /bin/sh - -c - | echo "cleaning tmp files at $(date)" find /tmp -type f -mtime +7 -delete echo "clean done"

这个例子可以原样复制到测试集群里跑,把timeZone字段去掉也能兼容老版本。

6. 实战中我踩过的坑与排查技巧

6.1 Job侧问题速查表

现象可能原因排查顺序
Pod一直Pending节点资源不足、镜像拉取受限看kubectl describe pod事件,确认是不是Insufficient cpu或ImagePullBackOff
Pod一直Running但不结束应用没有正常退出,进程在前台挂着进Pod看进程树,确认是否有子进程没回收;检查业务代码退出逻辑
Job失败后疯狂重试backoffLimit设太大,或者代码每次启动就崩溃kubectl describe job看失败原因,先修代码再调参数
多个Pod数据重复处理并行任务缺少分片约束或幂等检查JOB_COMPLETION_INDEX使用情况,确认SQL/脚本按取模分片
Job完成但Pod还在这是正常行为,用来保留日志设置ttlSecondsAfterFinished自动清理,或者手动删除Job
节点重启后Pod被驱逐节点压力大,Pod里业务长时间占用太多内存看Evicted事件,给容器加resources.limits,必要时用activeDeadlineSeconds限制总时长

6.2 CronJob侧问题排查清单

  • kubectl get cronjob显示ACTIVE,但对应Job没出来:检查suspend是不是true,或者concurrencyPolicy: Forbid且上一轮任务还没结束。
  • 任务比预期早了或晚了8小时:八成是UTC时区问题,按上一节说的方法换算,或者用timeZone。
  • 某个任务被跳过但找不到失败记录:看看是不是因为上一轮运行超时且并发策略是Forbid,控制器直接丢弃了本次触发。
  • 历史Job堆积如山:successfulJobsHistoryLimit没设置,或者设置值太大,老Job没人清理。
  • 集群停机后一恢复,瞬间创建大量Job:典型表现是没有startingDeadlineSeconds,积压的错过的调度被一次性触发。生产环境务必要设这个字段。

6.3 有用的排查命令

看到任务状态不对劲,我一般按这个顺序排查:

# 1. 看整体状态 kubectl get jobs -n 命名空间 kubectl get pods -n 命名空间 | grep job名 # 2. 看事件 kubectl describe job 任务名 -n 命名空间 # 3. 看具体Pod日志 kubectl logs -l job-name=任务名 -n 命名空间 --tail=200 # 4. 如果是CronJob,先看它自己状态 kubectl describe cronjob 任务名 -n 命名空间 # 5. 查看集群级别事件,很多问题能直接看到原因 kubectl get events --sort-by=.metadata.creationTimestamp

我个人还有个习惯:给每个Job和CronJob都加上明显的标签,比如team=data-backfill、purpose=monthly-report。等任务堆多了以后,用kubectl get job -l purpose=monthly-report筛选起来非常舒服。

6.4 走完一次任务后,我自己会坚持的两个习惯

第一,任何Job任务,尤其是CronJob里包着的任务,我一定会保证业务代码具备幂等性。这不是洁癖,而是Job重试、Pod重建、并发策略这些机制决定了“跑两遍”在Kubernetes里是常态,如果不提前防住,故障时只会火上浇油。

第二,凡是需要留存结果或日志的任务,我不会只依赖Pod的stdout。Pod一旦被清理,日志就没了。更稳妥的方案是:业务把关键结果写入对象存储或数据库,Pod层面的stdout只作为排查辅助。

这两个习惯帮我撑过了好几个凌晨的告警走廊。Job和CronJob本身不复杂,复杂的是怎么让任务在“可能被重复执行、可能被跳过、可能跑一半断了”的现实里依然不出错。把这些边界想清楚,比背一百个YAML字段都管用。

相关新闻

基于对话框的MFC俄罗斯方块:源码解析与开发实战

基于对话框的MFC俄罗斯方块:源码解析与开发实战

简介:一份基于MFC对话框框架的俄罗斯方块游戏源码,适合学习Windows图形界面编程与经典游戏逻辑的C开发者。项目以对话框为主窗体,涵盖控件布局、消息映射、按钮事件处理,并实现方块生成、旋转、碰撞检测与消行计分等核心算法&…

2026/10/20 14:50:59 阅读更多 →
移动应用逆向分析全链路:从APK静态侦察到动态Hook与协议逆向

移动应用逆向分析全链路:从APK静态侦察到动态Hook与协议逆向

1. 从“逆向分析一切”这个说法说起第一次看到“逆向分析一切”这个说法,我的反应是:这要么是个标题党,要么背后确实有一套成体系的工具链在支撑。后来陆续接触到一些做移动端安全研究、协议分析、竞品拆解的朋友,才发现这个说法虽…

2026/10/20 14:50:59 阅读更多 →
GBase 8c分布式数据库故障定位与运维实践全攻略

GBase 8c分布式数据库故障定位与运维实践全攻略

1. 故障定位的整体思路:先把排查顺序搞对1.1 分布式架构决定了排查链路GBase 8c是典型的shared-nothing分布式架构,一台“数据库”背后站着协调节点、数据节点、全局事务管理组件、集群管理组件等多类角色。这种架构最大的优势是水平扩展能力强&#xff…

2026/10/20 14:50:59 阅读更多 →

最新新闻

Python+MySQL学生管理系统:可视化界面落地与避坑指南

Python+MySQL学生管理系统:可视化界面落地与避坑指南

简介:这是一套面向Python与数据库初学者的学生管理系统实战项目,采用Python编写客户端逻辑、MySQL负责数据存储,适合正在学习桌面应用开发或需要完成课程设计的学生参考。压缩包共2个文件,包含1个py主程序与1个sql数据库脚本&…

2026/10/20 17:19:49 阅读更多 →
MySQL反斜杠转义全解析:从字符串插入到LIKE查询的避坑指南

MySQL反斜杠转义全解析:从字符串插入到LIKE查询的避坑指南

先交代一个真实翻车现场。有天业务方发来一张截图,某张配置表里的 Windows 路径字段,原本应该是C:\Users\某应用目录\data\config.ini,结果库里存成了C:Users某应用目录dataconfig.ini,所有反斜杠集体失踪。我一开始以为是应用层写…

2026/10/20 17:19:49 阅读更多 →
电商评论情感分析实战:从数据清洗到BERT蒸馏部署全记录

电商评论情感分析实战:从数据清洗到BERT蒸馏部署全记录

这个项目标题一看就是从实战里踩出来的,数据坑、部署、硬核笔记,说明作者真刀真枪跑过完整链路,不是拿公开数据集跑个demo就完事。文本分类和情感分析在NLP里属于入门必练但做好极难的方向,难就难在数据永远是脏的、标签永远是偏的…

2026/10/20 17:19:49 阅读更多 →
TensorFlow工业级AI工程实践:从计算图到TFX流水线

TensorFlow工业级AI工程实践:从计算图到TFX流水线

1. 这不是“学个框架”那么简单:TensorFlow到底在解决什么问题?很多人第一次听说TensorFlow,是在某次技术分享会上听到“谷歌开源的深度学习框架”,或者在招聘JD里看到“熟悉TensorFlow者优先”。但如果你真去翻它的GitHub仓库、读…

2026/10/20 17:19:49 阅读更多 →
双线性插值原理与C语言实现:图像缩放算法详解

双线性插值原理与C语言实现:图像缩放算法详解

简介:这份资源围绕双线性插值方法及实现展开,面向图像处理、计算机图形学与数值计算方向的学习者,尤其适合希望用C语言理解插值数学原理并动手实现的开发者。包内共31个文件,以h头文件、cpp源文件、obj目标文件为主,辅…

2026/10/20 17:19:49 阅读更多 →
Prescan+Simulink+CarSim联仿:多工况自动驾驶避障模型搭建与标定实战

Prescan+Simulink+CarSim联仿:多工况自动驾驶避障模型搭建与标定实战

做自动驾驶避障仿真的人,迟早会跟三个名字绑在一起:Prescan、Simulink、CarSim。标题里那套“不同工况避障模型”,说白了就是让一辆装有虚拟传感器的车,在模拟道路环境里遇到静止车、前车急减速、旁边车道突然切进来、行人横穿这些…

2026/10/20 17:18:48 阅读更多 →

日新闻

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →
ESP32舵机控制指南:原理、多路驱动与避坑实战

ESP32舵机控制指南:原理、多路驱动与避坑实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →
位移法实现一阶低通滤波:单片机ADC采样降噪实战

位移法实现一阶低通滤波:单片机ADC采样降噪实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/20 10:02:13 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/19 17:32:41 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/20 2:50:50 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 10:02:08 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 9:50:17 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 9:50:45 阅读更多 →