Android进程常驻:多模块保活方案与避坑指南

简介:《进程常驻探索》压缩包内含csdnactivity与servicelive1两个安卓工程模块,面向需要深入理解服务常驻与进程优先级调优的移动开发者和系统开发者,解决后台服务容易被回收、关键进程无法持续运行的难题。项目从实际代码出发,系统演示守护进程、服务管理器、启动脚本以及Supervisor/NSSM等第三方工具的常驻方案,并结合nice值、Windows优先级类等调度策略,帮助读者理解进程创建、执行、等待与结束的生命周期机制。资源共69个文件、16.9MB,以20个Java源码和18个XML配置为主体,配有20张PNG图解(覆盖工程结构、运行流程与优先级说明),另有2个AIDL接口、Gradle构建脚本、ProGuard规则及1个JAR依赖库,目录结构清晰,目前已有319人学习/下载。两份工程分别从界面与服务的场景演示不同常驻实现路径,内含完整源码、配置文件与说明文档,可导入开发环境直接运行分析,并借助跨进程接口理解通信保活方式;配合图片可系统梳理守护进程化、服务注册、优先级调整、内存释放与自动重启等关键知识点,同时关注资源消耗、安全性与系统兼容性,可作为后台保活与服务稳定运行设计的工程参考,便于二次开发时直接复用其中的进程管理思路。

1. 进程常驻不是玄学:这份多 module 资源到底在解决什么

做 Android 的开发者应该都有过这种经历:App 退到后台不到五分钟,进程就被系统回收,来电悬浮窗、消息推送、计步统计全部断掉。我拆过不少号称“保活”的项目,网上一搜一大把,但真正能跑通、能过厂商测试、能在不同 ROM 上稳定住的不多。这份「进程常驻探索 内含多个 module」是一套面向 Android 的多模块常驻工程,把前台服务、双进程守护、WorkManager 兜底、开机广播四种手段封装成独立模块,按需接入,而不是把所有代码塞进一个 Service 里硬扛。它适合做即时通讯、运动健康、系统工具类 App 的开发者,也适合想彻底搞懂 service 生命周期、进程优先级和厂商后台限制之间关系的人。

2. 先看底层逻辑:进程优先级、LMK 与五类常驻方案的选型边界

常驻这件事看起来是“写代码”,本质上是“和系统博弈”。Linux 内核里每个进程都有一个 oom_adj 值,Android 在原生 Linux 之上又包了一层 LMK(Low Memory Killer)策略,当系统内存吃紧时,会从 oom_adj 数值高的进程开杀。理解这个优先级队列,才能明白为什么有的 Service 写了几十行就能活一天,有的写了全套保活,一划后台就没了。

2.1 进程优先级不是秘密:oom_adj 决定谁先死

Android 进程从高到低大致分为五档:前台进程(adj=0)、可见进程(adj=1)、服务进程(adj=2)、后台进程(adj=8)、空进程(adj=9)。前台进程指当前正在和用户交互的 Activity、正在执行 onReceive 的 BroadcastReceiver,或者绑定了用户正在交互组件的前台 Service;服务进程就是正在运行普通 Service 但没有 UI 的进程;后台进程是 Activity 已经不可见的进程;空进程则是没有任何组件存活、只留了一个空壳的进程。

实际系统里,oom_adj 值会被各种因素动态调整。举个最常见的例子:一个 App 退到后台,Activity 不可见了,它的 adj 会从 0 慢慢升到 8、9,但如果里面有一个正在运行的前台服务,那么 adj 会保持在 0;如果只有普通 service,那么 adj 会停在 2,比后台 Activity 还靠前。这就是为什么很多人觉得“Service 加个 onStartCommand 就能活”——它确实比什么都强的进程优先级高,但一旦系统内存大幅吃紧,LMK 照样把 adj≥2 的杀干净。

提示:不同厂商会砍掉原生 LMK 换成自己的统一内存管理(如各种“内存回收机制”“智能后台清理”),这些策略不看 adj,看的是 App 是否在白名单、电源是否优化、以及用户是否主动锁定。所以原生理论说完了,实战里最常见的翻车点反而在厂商策略上。

2.2 五类常驻方案横向对比:强度、副作用与适用场景

这份资源里把常驻手段拆成了五个模块,其实对应五种完全不同的实现路径。它们不是互相替代的关系,而是层层兜底的关系。我按实际效果和使用成本整理了一张表:

方案实现原理保活强度副作用适用场景
前台服务startForeground 提升进程优先级,adj=0较强必须常驻通知,用户可手动移除音乐播放、导航、运动记录
双进程守护两个 Service 互相绑定,A 挂掉时 B 拉起 A中(被厂商限制)CPU 耗电、内存占用高内部组件互相健康检查
WorkManager系统级任务调度,Doze 模式下也能周期性执行中最小间隔 15 分钟,可能延迟数据同步、上报、清理
广播拉活监听开机、网络切换、解锁等系统广播弱(8.0 后限制)用户可见耗电、被标记开机自启、网络变化补偿
推送拉起长连接被系统杀掉后,厂商推送通道来唤醒强(有推送通道时)依赖厂商 ROM 支持国内主流厂商设备

从这张表能看出,没有哪一种是“银弹”。前台服务强度最高,但用户会看到一条常驻通知,而且 Android 13 以后用户可以一键停止;双进程守护在原生系统上表现不错,到了国产 ROM 上经常被连锅端;WorkManager 看着中规中矩,但它胜在是系统级 API,不会被打上“恶意保活”标签。

2.3 选型边界:为什么“永不杀”在 Android 12 后是伪命题

很多开发者找这类资源,心里想的其实是“有没有一种办法让我这个 App 永不被杀”。我的结论很直接:在原生 Android 12 及以上,前台服务启动被加了限制,后台进程不能随意调起前台服务;Android 14 对前台服务类型又做了强制校验。也就是说,“永不杀”在系统级已经不存在,任何第三方代码都不可能绕过系统限制。

那还做常驻干嘛?答案是争取“最大概率存活”和“最快恢复”。前台服务保证 App 在内存充足时不被挪到后台进程;双进程守护保证进程被异常杀死后,另一个进程在最短时间内把它拉起来;WorkManager 保证即使进程全没了,系统也会在合适时机把任务重新跑一遍。这套组合拳打下来,用户看到的 App 行为是“基本不掉链子,死了也能自己活过来”。选型时先问自己:你需要的是前台持续运行,还是后台保活之后快速恢复?前者选前台服务为主,后者选守护 + WorkManager 组合。

3. 拆开多 module 工程:结构与核心 service 代码怎么写

“内含多个 module”是这个资源最大的结构亮点。每个常驻方案都封装成了独立的 Gradle module,相互解耦,可以按需依赖。这比把所有代码写成一个大杂烩 Service 强很多,因为你可以只引入你需要的保活能力,不用的模块完全不占代码体积。我按实际依赖顺序从下往上拆开看。

3.1 module 划分与依赖关系:core 提供什么,service 模块消费什么

整个工程大致分为六个模块:core(公共基础)、service-foreground(前台服务)、service-daemon(守护进程)、service-workmanager(兜底任务)、service-receiver(广播拉活)、app(宿主壳)。依赖方向是从 app 向下依赖各个 service 模块,service 模块之间不互相依赖,都只依赖 core。core 里放的是保活场景的公共配置:通知渠道 ID、ServiceAction 常量、SP 存储的工具类、统一的状态上报接口。

// core/src/main/java/.../KeepAliveConfig.kt object KeepAliveConfig { const val CHANNEL_ID = "channel_keep_alive" // 通知渠道,保持一致 const val ACTION_START = "action_start" // 启动前台服务 const val ACTION_STOP = "action_stop" // 停止前台服务 const val DAEMON_ACTION = "daemon_action" // 守护进程互绑标记 enum class ModuleType { FOREGROUND, DAEMON, WORK_MANAGER, RECEIVER } }

逻辑说明:core 模块不包含任何 Android 四大组件,只提供常驻相关的常量和工具方法,这样 service 模块之间不会出现循环依赖,谁需要谁直接 import。所有的跨模块通信全部走 Intent action,不直接持有对方类引用,这样能做到单个模块被裁剪时,其他模块的代码不需要改动。

参数说明:CHANNEL_ID 是通知渠道的标识,Service 和创建通知的地方必须用同一个字符串,否则 Notification 无法弹出。ModuleType 是为了在统一的上报逻辑里区分当前是哪种保活方式,方便后续日志排查和埋点统计。

3.2 前台服务 module:startForeground 正确姿势与通知渠道

前台服务是整套方案的地基,也是唯一能让你进程 adj 保持为 0 的代码路径。这段代码的关键点有两个:一是通知渠道必须在 Android 8.0+ 建立,否则通知栏不显示;二是从 Android 10 开始,startForeground 需要传入 foregroundServiceType 参数,到了 Android 14 这个 type 还必须在 Manifest 里声明,否则运行时抛异常。

// service-foreground/src/main/java/.../KeepAliveForegroundService.kt class KeepAliveForegroundService : Service() { override fun onCreate() { super.onCreate() createNotificationChannel() } override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { val notification = buildNotification() // 传入 type:媒体播放只是示例,按实际用途改成对应的类型 startForeground( NOTIFICATION_ID, notification, ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PLAYBACK ) return START_STICKY } private fun createNotificationChannel() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { val channel = NotificationChannel( KeepAliveConfig.CHANNEL_ID, "常驻服务", NotificationManager.IMPORTANCE_LOW // LOW 避免弹出声音 ) channel.description = "用于维持后台运行" getSystemService(NotificationManager::class.java) .createNotificationChannel(channel) } } override fun onBind(intent: Intent?): IBinder? = null }

逻辑说明:onStartCommand 返回 START_STICKY,表示 Service 被系统杀死后,系统会尝试重建它,并在 onStartCommand 重新传入 null Intent。这是原生系统里最简单的一层“自动恢复”机制。前台服务一旦 startForeground 成功,进程的 adj 会被拉高到前台级别,LMK 不会优先杀它。

参数说明:FOREGROUND_SERVICE_TYPE_MEDIA_PLAYBACK 只是一个占位类型。如果你的 App 实际用途是导航、通话、远程传输,必须改成对应类型,并且在 Manifest.xml 的 service 节点里加 android:foregroundServiceType 属性。前后不匹配时,部分 ROM 会直接把服务杀掉并报 SecurityException。

3.3 双进程守护 module:AIDL 绑定与拉活逻辑的边界

双进程守护的思路是:A 进程和 B 进程各自跑一个 Service,互相 bind。A 被系统杀了,A 的 onDestroy 还没来得及执行时,B 通过 binder 连接断开感知到 A 死亡,然后 B 主动调 startService 把 A 拉起;A 反过来监听 B。这个方案在原生系统和部分老设备上表现不错,但在 Android 8.0 之后,后台执行限制让它越来越难做。

// service-daemon/src/main/java/.../DaemonService.java public class DaemonService extends Service { private final DaemonBinder mBinder = new DaemonBinder(); private static boolean isRunning = false; public static boolean isRunning() { return isRunning; } @Override public IBinder onBind(Intent intent) { return mBinder; } @Override public void onCreate() { super.onCreate(); isRunning = true; // 绑定对方进程的服务;这里写死另一个守护 service 的 action Intent intent = new Intent("com.xxx.daemon.SECOND"); intent.setPackage(getPackageName()); bindService(intent, mConnection, Context.BIND_AUTO_CREATE); } private ServiceConnection mConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { // 连接成功,说明对方进程还活着 } @Override public void onServiceDisconnected(ComponentName name) { // 对方进程死了,立刻尝试拉起 startService(new Intent(DaemonService.this, SecondDaemonService.class)); } }; @Override public void onDestroy() { super.onDestroy(); isRunning = false; if (mConnection != null) { unbindService(mConnection); } } }

逻辑说明:onServiceDisconnected 是双守护的核心回调。两个 Service 绑定的是不同进程,Modify 当对方进程被 LMK 杀掉时,binder 会断开,触发这个回调,当前进程马上尝试把对方拉起来。被拉起的 Service 在 onCreate 里又会重新去绑定对面进程的服务,这样就形成了一个祈使循环。

参数说明:BIND_AUTO_CREATE 表示在绑定时如果目标服务不存在就自动创建。这里有个常见误区:两个 Service 必须跑在不同进程中,否则相互 bind 是同一个进程内的绑定,进程一旦被杀死,两个 Service 一起死,守护循环根本建立不起来。

3.4 WorkManager 兜底 module:周期任务与约束参数

双进程守护再怎么折腾,也挡不住用户手动从任务管理器滑掉,或者厂商把这些进程连根清除。此时系统级的 WorkManager 反而最靠谱——它由系统进程调度,即使你的 App 进程被杀,任务仍有机会在系统决定的时间被执行。它非常适合做兜底。

// service-workmanager/src/main/java/.../KeepAliveWorker.kt class KeepAliveWorker(context: Context, params: WorkerParameters) : CoroutineWorker(context, params) { override suspend fun doWork(): Result { // 兜底动作:检查主 Service 是否在运行,不在就拉起 val isServiceRunning = isServiceRunning(KeepAliveConfig.ACTION_START) if (!isServiceRunning) { val intent = Intent(applicationContext, KeepAliveForegroundService::class.java) applicationContext.startForegroundService(intent) } return Result.success() } }
// app/src/main/java/.../WorkManagerScheduler.kt fun scheduleKeepAlive(context: Context) { val request = PeriodicWorkRequestBuilder<KeepAliveWorker>(15, TimeUnit.MINUTES) .setConstraints( Constraints.Builder() .setRequiredNetworkType(NetworkType.NOT_REQUIRED) .build() ) .setBackoffCriteria(BackoffPolicy.LINEAR, 1, TimeUnit.MINUTES) .build() WorkManager.getInstance(context).enqueueUniquePeriodicWork( "keep_alive_work", ExistingPeriodicWorkPolicy.KEEP, request ) }

逻辑说明:PeriodicWorkRequestBuilder 的最小周期是 15 分钟,这是系统硬性约束,传小于 15 分钟会被直接忽略。setBackoffCriteria 表示任务失败后按线性退避重试,第一次等 1 分钟,之后递进,避免频繁重试加剧耗电。enqueueUniquePeriodicWork 的 KEEP 策略至关重要——如果已经有一个相同名字的周期任务在排队,就保留旧的,否则每次调用都会新建一个任务,导致任务重复执行。

参数说明:NetworkType.NOT_REQUIRED 表示不依赖网络条件,适合保活场景。如果你改成 CONNECTED,在无网络环境下任务会一直等待,兜底效果就打了折扣。work 运行在后台线程,sample 里是协程,不要在里面做耗时超过 10 秒的操作,否则会被系统判定为异常退出。

4. 常驻方案避坑:五次翻车现场的起因与解决

常驻代码的坑不是“写完不跑”,而是“当时跑得通,换设备、换系统版本就炸”。我把自己在这套多 module 工程里踩过的坑整理成五条,每一条都按现象、原因、解决来写,后面集成别走同样的路。

4.1 前台服务明明加了,还是被系统杀了

现象:在 A 手机上开着前台服务,通知栏也有常驻通知,但内存一紧张服务还是没了;或者启动时直接闪退,Logcat 里是 ForegroundServiceDidNotStartInTime 的异常。

原因:常见的两个坑。一是没有在启动后 5 秒内调用 startForeground,超时后系统直接丢 ANR 异常并杀掉进程;二是启动前台服务的方式用的 startService,而不是开始 Android 8.0 后的 startForegroundService。前者保证了前台服务的类型声明,后者则没有真正把服务提升到前台优先级。

解决:代码里统一使用 startForegroundService 启动,并在 onStartCommand 第一行调用 startForeground,入参必须和 Manifest 里声明的 foregroundServiceType 完全一致。如果业务上没法决定类型,可以在 Manifest 里写 android:foregroundServiceType="specialUse",并且让 type 参数传 -1,但这样在 Google Play 上架会比较被动,国内分发没问题。

4.2 双进程守护导致 CPU 飙高、手机发热

现象:两个守护 Service 跑起来后,用 Profiler 一看,两个进程的 CPU 占用都在 10% 以上,手机明显发热,循环拉起的日志刷个不停。

原因:最常见的是误用了“轮询检查”而不是“Binder 死亡监听”。工程里如果写了一个 while(true) 循环每分钟检查一次对方进程在不在,两个进程都在做这种事,CPU 自然拉满。另一种情况是 onServiceDisconnected 被触发后拉起了对方,但对方因为某种原因启动失败,于是这边又拉,那边又断,形成死循环。

解决:第一,去掉所有主动轮询,改用 Binder 的死亡回调,逻辑只在状态变化时执行;第二,在拉起动作里加状态保护,比如记录上次拉起时间,5 秒内不重复拉;第三,给守护进程设定退出条件,当 App 主界面不可见且用户主动退出时,允许守护进程一起退出,避免“僵尸互拉”。

4.3 WorkManager 周期任务到了 15 分钟不执行

现象:在部分品牌手机上,锁屏放置一夜,第二天看日志发现周期任务一次都没跑;偶尔手动打开 App,任务又突然集中执行好几次。

原因:WorkManager 虽然由系统调度,但任务的真实触发时间依赖 Idle state、电量状态和厂商后台管理。国产 ROM 的省电策略会把你的 App 加入“待机清理名单”,系统认为应用不可见时就冻结它的所有任务,包括 WorkManager。另一个原因是周期任务的最小间隔虽然设了 15 分钟,但系统可能因为 Doze 模式把它延后到下一次唤醒。

解决:把 Doze 模式的白名单和厂商自启动权限引导做进去,这是绕不开的一步。代码里可以检测当前是否在白名单内,不在则引导用户跳转相关设置页添加;判断逻辑封装在 core 模块中,避免业务代码重复写。同时,把 WorkManager 和前台服务切换成“前台服务保当前,WorkManager 兜底”的搭配,而不是单靠 WorkManager 一条路。

4.4 通知显示不出来,前台服务直接崩溃

现象:在国产 ROM 上运行,通知栏看不到常驻通知,但代码里明明创建了通知渠道;有些设备上一启动就抛 Channel is not registered 的断言异常。

原因:Android 8.0 之后通知渠道必须在创建后才能发通知,如果你在不同模块里各创建了一次渠道,用的 channelId 相同但 importance 不同,后创建的会覆盖前创建的缓存配置,导致第一个发通知的地方取不到有效渠道。另一个原因是 App 在通知开关里被用户关闭了通知权限,渠道被系统禁用,此时 startForeground 仍被调用,就会抛异常。

解决:把通知渠道的创建统一放在 core 模块里,由 app 启动时先执行一次,不要在每个 service 模块各自创建。service 模块发通知前检查 canUseNotification 权限,拿不到权限时降级处理,比如退化成普通后台任务而不是硬调 startForeground。注意降级后进程优先级会掉,但总比崩溃强。

4.5 进程被杀后 START_STICKY 并没有把服务拉回来

现象:手动从后台任务管理划掉 App,或者系统内存吃紧处死进程,结果服务一直没重新启动,直到下次用户点开 App 才活过来。

原因:START_STICKY 只在系统内存适中、进程被异常杀掉时才会重建。如果进程是被用户手动强制停止,系统直接标记该 App 为“已停止”,之后一段时间内任何后台启动动作都不会生效;后台管理任务里的“滑动清除”和“强制停止”效果相似,但实现路径不同,很多厂商把前者也当成后者处理。

解决:这套场景下不能依赖 START_STICKY 当唯一恢复手段,让双进程守护和 WorkManager 在极端情况去兜底。手动停止后,最有效的拉起时机是用户下一次主动触摸 App 图标时,系统解除已停止状态,你再通过前台服务把整个保活链条重新挂上。可以在 Activity 的 onStart 里检测服务是否存活,不存在就重新拉起。

5. 进阶验证:把“尽量活着”变成可量化的三层保障

常驻方案不应该是写了代码就觉得“应该能活”,而是每改一次都要有明确的验证数据。我实际操作时会把常驻拆成三层,按优先级执行,并建立一套快速验证流程,每次集成新模块都用同一套方式来验收。

三层分别是:前台服务兜底当前状态、双进程守护兜底异常被杀的恢复、WorkManager 兜底两个进程全灭后系统级任务重放。每一层都有明确的验收命令。第一层看进程存活,执行 adb shell ps -A | grep 包名,看返回内容;第二层看守护恢复,用 adb shell am kill 包名 杀掉主进程,观察 3 秒内守护进程是否把它拉回来,Logcat 里能看到 binder 断开与重建的日志;第三层看 WorkManager,杀掉 App 所有进程后等待下一个 15 分钟周期,或直接执行 adb shell cmd jobscheduler run -f 包名 强制触发一次作业。

验证时不能只看“进程在不在”,还要看耗电曲线和崩溃日志。用 Profiler 观察 CPU 每分钟平均占用,如果常驻比正常业务还多出 3 个百分点的 CPU,说明拉活逻辑有问题,多半是轮询或死循环在作怪。给 main 进程和守护进程分别打不同的统计事件,半小时内如果反复出现 kill 和 restart,就该检查守护循环是不是在空转。

从那以后,我每次集成这套多 module 工程,都强制走一遍验证流程:先跑 30 分钟观察存活率,再手动模拟一次强杀、一次后台任务滑动清除、一次系统内存压力测试,最后看耗电曲线和崩溃率。这套流程帮我及时排掉了不少厂商 ROM 上的意外表现,也避免了把“看起来能跑”误当成“真能扛”。希望帮到你。

本文还有配套的精品资源,点击获取

相关新闻

AI调研工具一键生成问卷,从筹备到数据分析全流程自动化

AI调研工具一键生成问卷,从筹备到数据分析全流程自动化

一提调研&#xff0c;很多人下意识想到的就是“又要设计问卷了”。但这个痛&#xff0c;其实不在于设计本身&#xff0c;而在于设计之前的筹备&#xff1a;你要确认调研目标到底想问出什么&#xff0c;要把它拆成哪些维度&#xff0c;每个维度下又该问哪些题&#xff0c;选项怎…

2026/10/20 11:49:46 阅读更多 →
大模型提示词工程实战指南:从角色设定到思维链的五大技巧

大模型提示词工程实战指南:从角色设定到思维链的五大技巧

大模型提示词工程&#xff0c;说白了就是学会和大模型“好好说话”&#xff0c;把脑子里的模糊需求翻译成它听得懂的指令。别小看这件事——同样一个模型&#xff0c;有人能让它当编程助手、数据分析师、文案策划&#xff0c;有人却只能得到又空又水的回答。差别几乎全在提示词…

2026/10/20 11:49:46 阅读更多 →
Swift+UIKit实现猫眼风格选座:座位渲染到订单提交的完整闭环

Swift+UIKit实现猫眼风格选座:座位渲染到订单提交的完整闭环

简介&#xff1a;一份iOS电影选座功能实现源码包&#xff0c;面向需要开发票务类或影院App选座模块的开发者&#xff0c;以类似猫眼App的选座流程为蓝本&#xff0c;完整覆盖界面布局、数据管理、座位交互与网络同步等环节。项目使用自定义滚动视图承载座位图&#xff0c;通过座…

2026/10/20 11:49:46 阅读更多 →

最新新闻

水风光互补调度与净现值计算:MATLAB资源包实战指南

水风光互补调度与净现值计算:MATLAB资源包实战指南

简介&#xff1a;本资源面向计算机、电子信息工程、数学等专业的大学生及新能源调度方向研究者&#xff0c;提供水风光互补调度系统的净现值计算与不同网格装机容量、出力系数影响分析的完整MATLAB实现方案&#xff0c;可用于课程设计、期末大作业与毕业设计。压缩包共18个文件…

2026/10/20 12:26:14 阅读更多 →
情感化无感防刷与手势阻尼反馈:基于用户注意力疲劳度动态微调按钮交互阈值

情感化无感防刷与手势阻尼反馈:基于用户注意力疲劳度动态微调按钮交互阈值

在电商狂欢秒杀、限量潮流球鞋发售或火热赛事抢票的关键瞬间&#xff0c;前端页面承受着来自全球数百万用户的极速疯狂连击。 面对这种狂热的并发点击&#xff0c;传统的防刷防重复提交方案往往充斥着一种“居高临下的冰冷傲慢”&#xff1a; 方案一&#xff1a;粗暴弹窗报错—…

2026/10/20 12:26:14 阅读更多 →
推理引擎底层逻辑与优化实践:从计算图到量化部署

推理引擎底层逻辑与优化实践:从计算图到量化部署

做推理引擎方向有段时间了&#xff0c;经常有人拿着模型部署的报错来问我&#xff0c;聊到最后发现卡点往往不在算子实现上&#xff0c;而是对“推理”这件事本身的底层逻辑没吃透。这篇文章就是想把这些基础的东西掰开揉碎讲清楚&#xff0c;从模型是什么、推理时计算机到底在…

2026/10/20 12:26:14 阅读更多 →
AI智能体架构图绘制指南:四层框架与实战排查

AI智能体架构图绘制指南:四层框架与实战排查

画AI智能体架构图这件事&#xff0c;看着不难&#xff0c;翻车率却很高。前阵子帮一个小团队评审方案&#xff0c;对方贴出一张图&#xff1a;中间一个“LLM”的大框&#xff0c;左边拖进来几个接口&#xff0c;右边连着一个数据库&#xff0c;就敢叫“AI智能体架构图”。我说这…

2026/10/20 12:26:14 阅读更多 →
动效运行时弹簧物理引擎:纯 TypeScript 实现 RK4 龙格-库塔高精度数值积分

动效运行时弹簧物理引擎:纯 TypeScript 实现 RK4 龙格-库塔高精度数值积分

在现代自然交互动效中&#xff0c;传统的基于固定时间持续与三次贝塞尔曲线&#xff08;Cubic-bezier&#xff09;的过渡动画&#xff0c;正日益暴露出其致命的机械感与割裂感。 假设一个用户正在用手指拖拽一个浮动卡片&#xff1a;当手指松开时&#xff0c;卡片已经具有了初速…

2026/10/20 12:26:14 阅读更多 →
Flink SQL与DataStream本质差异:从API选择到生产就绪

Flink SQL与DataStream本质差异:从API选择到生产就绪

1. 为什么这节课是Flink学习者真正的分水岭我带过不少刚接触流处理的开发者&#xff0c;他们往往在学完DataStream API后会陷入一种“我已经会了”的错觉——能写个WordCount、能接Kafka、能做简单窗口聚合&#xff0c;就以为掌握了Flink。直到某天被业务方甩来一份需求&#x…

2026/10/20 12:25:14 阅读更多 →

日新闻

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实现详解

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

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

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

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

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

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

如果你的信息流最近也天天刷到“机器人大脑”这个词&#xff0c;你会发现一个很有意思的现象&#xff1a;每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型&#xff0c;有人指的是运动控制系统&#xff0c;还有人指的是能理解物理世界的端到端模型。在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 阅读更多 →