尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
Spring Bean Scope 全解析:从 singleton 到 prototype 的创建机制与实战陷阱
Spring 的 Scope 这个知识点我印象里很多人是面试背概念写代码全默认。直到某天线上一个单例 Service 注入的 prototype Bean 出了并发状态串号的问题我才真正意识到Scope 不是在讨论一个对象能活多久而是在决定程序每次向容器要一个名字时容器是递给你同一个老面孔还是现场给你捏个新人。这篇文章就是围绕Spring 中不同 Scope 的 Bean 创建机制展开的我会把 singleton、prototype、request/session 这些 Web 作用域、自定义 Scope以及它们背后最值得注意的创建时机、代理机制和生命周期差异一次说透。不管你是刚上手 Spring Boot 的新人还是写了好几年业务但没怎么碰过高级用法的人看完应该都能在项目里做出更稳的选择。1. Scope 的本质Bean 定义与实例之间的一对多关系很多人一开始会把Bean当成已经被创建出来的那个对象但 Spring 里其实有两个完全不同的东西BeanDefinition 和 Bean 实例。不理解这层区别Scope 是怎么运作的就永远隔着一层纱。1.1 BeanDefinition 只是一张图纸Spring 容器启动的时候并不会立刻把你所有业务类都 new 出来。它首先做的是读图纸扫描 Component、Service、Repository、Controller解析 Bean 方法或者读 XML 里的 bean 标签统统转换成一个个 BeanDefinition注册到容器内部的注册表里。BeanDefinition 里记着这个 Bean 的类名、是否延迟加载、初始化方法是什么、销毁方法是什么、自动装配模式是什么当然也包括 Scope。这里有个很关键的认知BeanDefinition 本身不产生任何实例。你可以把 BeanDefinition 想象成餐厅菜单上的一道菜名它不意味着后厨已经做好了一盘菜放在保温柜里只代表客人点了这道菜厨房有本事做出来。Spring IoC 的核心思想本来就是先收集元数据再按需创建对象而不是启动时把所有可能用到的对象一股脑全造出来。1.2 真正触发创建的是 getBean() 和依赖注入那实例到底是什么时候创建的真正的触发点是 getBean() 调用以及依赖注入。你在任意代码里做Autowired注入或者通过ApplicationContext.getBean(xxx)去拿最终都会走到AbstractBeanFactory.doGetBean()这个方法。在这个方法内部Spring 会先看一眼目标 Bean 的 Scope 是什么如果是 singleton它会先去单例缓存里找找不到才走创建逻辑如果是 prototype它不会查任何缓存直接调用 createBean 创建新实例如果是 request、session 这类自定义 Web 作用域它会从当前作用域容器里找找不到再创建。所以说Scope 控制的核心可不是这个 Bean 能活多久而是容器在收到创建请求后如何决定返回已有对象还是新对象。prototype 翻译成原型其实有点误导它更像一次性地每次新建而 singleton 的单例则是全局缓存一份永远复用。想透彻了这一点后面再聊创建时机就顺了。还有一个细节容易被忽略容器在启动过程中会主动预实例化一部分 Bean。在AbstractApplicationContext.finishBeanFactoryInitialization里有个preInstantiateSingletons方法它会遍历所有注册的 singleton BeanDefinition把那些非抽象、非懒加载的 Bean 全部提前拿到手。这也是为什么你偶尔只是启动一个 Spring Boot 项目却感觉好像一下子创建了成百上千个对象——它们大多是被预实例化的 singleton而不是 prototype。prototype 不会有这种待遇它是懒到极致的你不主动 getBean 或者找容器注入它永远不出现。2. singleton 与 prototype创建时机、内存模型和选择依据这两种 Scope 是日常开发里出现频率最高的也是大多数面试题喜欢挖的点。它俩的差别表面是一个还是多个实际是容器在创建机制上的完全不同的两条路线。2.1 singleton 的三级缓存到底在缓存什么singleton 是 Spring 的默认 Scope绝大多数业务类——Service、Repository、Controller、配置类——都应该是 singleton。原因是业务服务通常是无状态的同一个实例可以被任意多个线程安全地复用不创建新对象省内存、省 GC性能也最好。singleton 的创建机制主要在DefaultSingletonBeanRegistry里。容器维护了三个相互独立的 Map俗称三级缓存缓存名称作用第一级singletonObjects存放创建完成、已经经历过完整生命周期的成品 Bean第二级earlySingletonObjects存放提前暴露的半成品 Bean为了支持循环依赖第三级singletonFactories存放 ObjectFactory 工厂用于生成提前暴露的早期引用如果一个 singleton Bean 在创建过程中依赖了另一个 singleton Bean而对方又反过来依赖它就会形成循环依赖。三级缓存解决的就是这个问题A 创建到一半先把一个早期引用借给 B 用B 完成后 A 再继续初始化。这里要提醒一句循环依赖虽然技术上能解但业务上往往是设计出问题的信号能避免还是尽量避免别把三级缓存当成纵容耦合的挡箭牌。默认情况下singleton 在容器启动时就完成预实例化。如果你不想某个单例那么积极可以给它加Lazy注解让它在第一次被使用的时候才创建。但Lazy只是延迟了创建时机并没有改变全局只有一个实例这个本质。2.2 prototype 的创建流程每次都走完整生命周期prototype Bean 的创建逻辑要简单粗暴得多每次 getBean 都是一个新的开始。在doGetBean里Spring 检测到是 prototype 后直接走 createBean 方法走完整个 Bean 生命周期实例化、属性填充、执行各种 BeanPostProcessor、执行 Aware 回调、执行 PostConstruct 和 init-method。创建完就把对象交给调用方自己这边不留存根不缓存不记录引用。很多人以为 prototype 就是new 一个对象这么理解只对了一半。它确实每次都是新的但它依然享受 Spring 的依赖注入、AOP 增强、注解回调等一系列容器能力。区别只在于singleton 对同一个名字只会执行一次完整的创建然后所有调用者共享那一个结果prototype 对同一个名字可以在不同时间点创建出无数个彼此无关联的个体。还有个很重要的坑prototype 的创建时机是第一次被获取或者每次被注入。如果你在一个 singleton 的构造函数里注入了 prototype实际上只会在那个 singleton 创建时注入一次之后这个 singleton 一直抱着那个新实例不放——这跟直觉完全相反。很多人栽在这上面后面第 5 章我会专门讲怎么正确地把 prototype 用起来。2.3 Scope 选择从什么角度去考虑直接给一张对比表方便你做选型对比项singletonprototype实例数量整个容器最多一个或每个容器一个每次获取都会新建创建时机默认容器启动时预创建或首次获取时每次 getBean 时缓存有三级缓存中的单例池没有缓存创建完即交付销毁管理容器关闭时统一销毁执行回调容器完全不跟踪不执行销毁回调线程安全要求必须无状态或自身安全每次独立实例天然隔离但长期持有仍需小心典型场景Service、Repository、配置类有状态轻量对象、复杂组合依赖、临时执行器实际项目里我的建议是默认全用 singleton只有在这个 Bean 本身需要保存每次会话特有的状态并且状态不能由方法参数传递时才考虑 prototype。Spring 社区里有一句经验之谈如果你发现自己在用 prototype 解决并发问题第一件事不应该是改 Scope而是检查是不是把可变状态放在了不该放的地方。prototype 是工具不是兜底方案。3. request/session/application/websocketWeb 作用域的创建机制与代理模式进入 Web 环境之后Scope 的玩法又不一样了。Spring 在内置容器里预注册了 request、session、application、websocket 这几个 Web 作用域它们的命名很直观但背后的创建机制和代理机制如果不搞清楚踩坑是分分钟的事。3.1 Web 作用域的本质把 Bean 塞进本来就有的作用域容器以 Spring Boot 内嵌容器为例容器在启动过程中会检测到 Web 环境并把几个 Scope 对象注册到 BeanFactoryRequestScope、SessionScope、ApplicationScope、WebSocketScope。你可以去翻 Spring 源码这几个类的实现其实都不复杂底层逻辑高度一致——去对应的存储容器里找找不到就调用 ObjectFactory 创建然后把新实例放回去。Web 作用域实例存放的位置生命周期边界requestHttpServletRequest 的 attribute一次 HTTP 请求sessionHttpSession 的 attribute一个用户会话applicationServletContext 的 attribute整个 Web 应用websocketWebSocketSession 的 attribute一个 WebSocket 连接会话举个具体例子RequestScope 的 get 方法大致是这样先通过 RequestContextHolder 拿到当前线程绑定的请求对象从请求的 attribute 里取名为 beanName 的实例如果取不到就执行 objectFactory.getObject() 创建再把新实例放回 attribute。整个过程对使用者来说是透明的你只需要声明Scope(request)剩下的交给容器。这里要特别说一句application 和 singleton 在数量上很像都是整个应用基本一份实例但语义上不一样。singleton 是容器级的单例当你部署多个应用共享同一个容器进程时比如一个传统应用下挂多个 Web 应用每个 Web 应用会有自己独立的 ApplicationContext所以 singleton 在每个应用里各有一份。而 application scope 是直接绑定在 ServletContext 上的以 Web 应用为单位存储。不过在 Spring Boot 单应用场景下两者差别并不大主要是在传统多 Web 应用部署时才有区分意义。3.2 Scoped Proxy为什么注入 request Bean必须要代理假设现在有一个 singleton 的全局配置服务它想注入一个Scope(request)的当前用户信息 Bean。问题来了singleton 是在容器创建时被实例化的那一刻根本不一定有 HTTP 请求在飞就算有注入进来的也只是那一次请求的对象。之后换一个用户再来singleton 手里的实例还是上一个用户的这不就串了Spring 的解决方案是 Scoped Proxy注入进来的是一个代理对象而不是目标 Bean 本身。这个代理在每次方法调用时都会从 RequestContextHolder 重新获取当前请求再从当前请求的 scope 容器里取出真正的目标对象然后把调用转发给它。这样设计之后singleton 持有的永远是一个取货码每次用的时候拿取货码到当前请求里去换真货。实现方式有两种ScopedProxyMode.INTERFACESJDK 动态代理要求目标类必须实现至少一个接口ScopedProxyMode.TARGET_CLASSCGLIB 子类代理不要求接口但目标类不能是 final。实际开发里如果你直接写Scope(request)而没配 proxyModeSpring 在注入到 singleton 的时候往往会直接报错提示no thread-bound request found或类似的问题。原因就是它真的去尝试获取当前请求了但当前根本不在请求生命周期中。正确写法是Component Scope(value request, proxyMode ScopedProxyMode.TARGET_CLASS) public class CurrentUser { private String userId; // getter/setter }这样 CurrentUser 的调用方只要注入 CurrentUserSpring 自动给你塞一个代理所有方法调用都发生在当前请求这个上下文里。3.3 代理模式在使用中的几个隐性坑代理模式虽然好用但引入代理对象之后一些平时被忽略的细节会冒出来。第一个是 self-invocation 问题。CGLIB 生成的代理是目标类的子类代理对象调用目标方法时能生效的前提是方法调用从代理对象发起。如果你在代理对象内部另一个方法内部直接调用了 this 的同类的另一个方法那就绕过了代理层不会重新走 scope 获取逻辑。这和事务注解上的 self-invocation 失效是同一个坑。第二个是 identity 问题。代理对象和真实对象不是同一个引用你拿注入的 CurrentUser 和从 request attribute 里手动取出来的实例做比较得到的是 false。做 instanceof 检查通常没问题但如果有人用equals()或hashCode()做业务判断也可能出现意外结果因为这些方法如果没有在代理里特殊处理走的是代理类自身的逻辑。第三个是序列化问题。CGLIB 代理类要支持序列化得满足额外条件如果你把这个 Bean 往 Redis 里写或通过远程接口传出去很可能因为代理对象里套着一个复杂的目标对象引用而在序列化时踩坑。稳妥做法是不让 Web 作用域 Bean 跨界传出去远程调用前转成 DTO 或者普通值对象。4. 自定义 Scope当内置 Scope 不够用时的扩展机制说实话大部分项目一辈子都用不上自定义 Scope。但一旦你遇到了每个线程都要有自己的专用实例或者每个租户要有独立上下文之类的需求你就能体会到一个通用扩展点有多救命。Spring 的 Scope 接口设计得非常干净扩展一个作用域本质上就是实现一个接口再注册一下。4.1 Scope 接口的五个方法各自的职责是什么public interface Scope { Object get(String name, ObjectFactory? objectFactory); Object remove(String name); void registerDestructionCallback(String name, Runnable callback); Object resolveContextualObject(String key); String getConversationId(); }逐个拆开看get从当前作用域存储里找名为 name 的实例找不到就调用 objectFactory.getObject() 创建这是整个 Scope 的创建入口remove把指定实例从当前作用域移除返回被移除的对象registerDestructionCallback注册一个销毁回调当作用域结束、对象需要被销毁时执行这是自定义 Scope 管理 bean 生命周期的关键resolveContextualObject按 key 解析出当前作用域上下文里的某个对象一般用来暴露上下文信息比如从 request scope 里解析出 HttpServletRequestgetConversationId返回当前作用域的标识 IDSpring 会话管理相关功能会用到。4.2 手写一个线程级 Scope让每个线程都拥有独立 Bean我来演示一个最常见的自定义场景线程级 Scope。需求很简单同一个 Bean每个线程拿到的都是自己线程专属的实例线程之间互不干扰。实现思路就是用一个 ThreadLocal 包一层 Map。public class ThreadScope implements Scope { private static final ThreadLocalMapString, Object THREAD_SCOPE ThreadLocal.withInitial(HashMap::new); Override public Object get(String name, ObjectFactory? objectFactory) { MapString, Object map THREAD_SCOPE.get(); Object instance map.get(name); if (instance null) { instance objectFactory.getObject(); map.put(name, instance); } return instance; } Override public Object remove(String name) { return THREAD_SCOPE.get().remove(name); } Override public void registerDestructionCallback(String name, Runnable callback) { // 线程结束时的清理逻辑后面再说 } Override public Object resolveContextualObject(String key) { return null; } Override public String getConversationId() { return String.valueOf(Thread.currentThread().getId()); } }注册这个 Scope 到容器里可以借助 BeanFactoryPostProcessorConfiguration public class ThreadScopeConfig { Bean public static BeanFactoryPostProcessor threadScopeRegister() { return beanFactory - { if (beanFactory instanceof ConfigurableBeanFactory) { ((ConfigurableBeanFactory) beanFactory).registerScope(thread, new ThreadScope()); } }; } }之后需要线程级实例的 Bean加注解就行Component Scope(thread) public class ThreadContextHolder { // 每个线程独立的字段 }这个方案在模拟并发请求、测试隔离、批量任务分片等场景下非常好用。4.3 自定义 Scope 时最容易忽略的三个细节第一是清理。ThreadScope 如果不主动清理 ThreadLocal在线程池复用线程时上一次任务的残留数据会漏到下一个任务里这比内存泄漏更隐蔽也更危险。所以最好在任务跑完时显式调用 remove或者注册回调在线程结束时统一清理。第二是销毁回调。Scope 接口里 registerDestructionCallback 的意义就是让作用域结束时有地方安放销毁逻辑。比如线程级作用域你要在线程结束的时候遍历 Map逐个执行注册进去的 Runnable实现类似 PreDestroy 的效果。Spring 只保证 singleton 的销毁回调由容器调用自定义 Scope 的销毁时机完全取决于你自己。第三是代理模式。自定义 Scope 一样会遇到高作用域 Bean 注入低作用域 Bean的问题如果你的 thread Bean 要被 singleton 注入同样需要给 thread Bean 加 proxyMode否则这个线程级隔离就会失效。机制和 request 的代理完全一致理解了一个就理解了全部。5. prototype 依赖的生命周期陷阱为什么容器不帮你销毁它这是 prototype 使用中争议最大的地方也是网上问题最多的点之一。很多人以为 prototype Bean 既然由容器创建销毁也应该由容器统一处理结果写了个 PreDestroy 方法容器关闭时一看压根没执行。5.1 初始化回调执行销毁回调却不执行的真相先看结论prototype Bean 的初始化生命周期PostConstruct、InitializingBean、init-method会执行但销毁生命周期PreDestroy、DisposableBean、destroy-method不会执行。原因其实在容器实现上singleton 实例创建完成后Spring 会把它登记到可销毁实例清单里持有引用等容器关闭时统一清理。但 prototype 实例创建完之后容器直接把引用交给你了自己没有保存任何记录。等容器关闭时它根本没有办法知道你手上还有哪些 prototype 实例自然也无从执行销毁回调。这一点在官方文档里写得很直接该作用域不负责 prototype Bean 的销毁调用方负责资源清理。所以如果你让一个 prototype Bean 持有了数据库连接、文件句柄、网络流用完不自己关是真的会泄漏的容器帮不上忙。5.2 把 prototype 正确注入 singleton 的四种姿势前面提过直接在 singleton 里 Autowired 一个 prototype结果只会注入一次。那正确的做法是什么我按推荐程度排序第一种在 singleton 方法里直接用 new。如果这个 prototype 不依赖别的 Spring Bean那 new 是最简单可靠的不折腾容器性能还好。缺点是放弃了依赖注入和 AOP 能力。第二种通过 ApplicationContext 手动获取。注入 ApplicationContext每次需要时调用context.getBean(PrototypeBean.class)。能用但对容器 API 侵入强测试也不方便。第三种用 ObjectProvider。Spring 4.3 起推荐的方式Service public class OrderService { private final ObjectProviderPriceCalculator calculatorProvider; public OrderService(ObjectProviderPriceCalculator calculatorProvider) { this.calculatorProvider calculatorProvider; } public void calculate(Order order) { PriceCalculator calculator calculatorProvider.getObject(); // 每次拿到的都是新实例 } }第四种用 Lookup 方法注入。这在需要以方法为粒度每次新实例时很优雅Service public class OrderService { public void calculate(Order order) { PriceCalculator calculator createCalculator(); // 每次调用返回的是新实例 } Lookup public PriceCalculator createCalculator() { // 这里写死返回 null 即可Spring 会生成子类并重写 return null; } }Lookup 的原理也是 CGLIB 子类代理所以 OrderService 这个类不能是 final方法是 public 效果最好。这两种方式我实际项目里都用过ObjectProvider 更推荐因为它不要求类满足代理条件语义也清晰。5.3 资源型 prototype 的清理建议如果你的 prototype Bean 确实持有需要释放的资源我的习惯是这样的让 Bean 实现 AutoCloseable然后在调用方用 try-with-resources 或者在 finally 块里显式关闭。Scope(prototype) Component public class BatchWriter implements AutoCloseable { private BufferedWriter writer; Override public void close() { // 释放资源 } }调用方try (BatchWriter writer provider.getObject()) { writer.write(batch); }如果你更喜欢由容器统一管理清理的体验可以考虑把这种 Bean 的 Scope 改成 request 或自定义的会话 Scope让作用域结束成为销毁回调的触发点。但一般业务里显式关闭是更符合直觉的做法别把所有生命周期责任都甩给容器。6. 实战排查三类常见 Scope 错误的表现与根因定位写代码的时候 Scope 的问题很难一眼看出来因为它经常是代码能跑但行为诡异。我把过去几年见得最多的四类问题整理出来每一条都带上排查思路帮你遇到类似现象时能快速定位。6.1 现象一singleton 里的状态在并发下互相串台有用户反馈多个并发请求同时操作同一个业务组件时数据出现了互相覆盖。排查链路是这样走的第一步先看这个组件的 Scope。如果它是 singleton再往下看第二步检查组件里有没有可写实例字段。如果有一个很典型的 pageNum、currentCount、tempCache 之类的字段问题几乎就锁定了多个线程共享同一个组件实例状态被彼此改写。这种问题有两个层面的解法。第一层把问题 Bean 改成 prototype让每个线程各用各的实例。但要注意的是如果调用方是 singleton前面的注入一次陷阱会让你改了个寂寞必须配合 ObjectProvider 或 Lookup 使用。第二层也是我更推荐的重构掉可写状态。把共享数据从实例字段挪到方法参数里Bean 保持无状态这远比依赖 Scope 切换要稳。当时我们排查后发的根因其实就是有人在 singleton 的成员变量里放了个分页游标——那不是 Scope 的锅是设计没做对。6.2 现象二启动时或首次注入时报 No thread-bound request found这个报错信息非常典型翻译过来就是线程上没有绑定请求对象。触发场景一般是一个 Scope(request) 的 Bean 被某个 singleton 直接在字段注入而容器在启动阶段或非请求线程中初始化这个 singleton。这时候 Spring 去获取 request Bean发现当前线程根本没有绑定 HTTP 请求上下文于是异常直接抛出。解决办法很明确如果是 Web 作用域 Bean 注入 singleton加proxyMode ScopedProxyMode.TARGET_CLASS或者干脆把注入改成 ObjectProvider延迟到真正有请求的时候再 getObject。这里有个判断经验报错如果发生在启动阶段多半是字段直接注入导致预实例化提前触发如果发生在异步线程里往往是请求上下文没传递过去。两种场景处理方式不同先确认触发时机再动手。6.3 现象三prototype 之间形成循环依赖容器直接拒绝singleton 的循环依赖靠三级缓存能救回来但 prototype 的循环依赖是救不了的。如果你让两个 prototype Bean 相互注入Spring 会抛出 BeanCurrentlyInCreationException。道理也不复杂prototype 创建时根本不缓存也不提前暴露早期引用A 创建到一半需要 BB 创建到一半又需要 A而 A 此时还在创建中且没有任何可以被提前拿出来的对象。Spring 发现你又在创建一个正在创建中的 prototype直接判定循环创建报错终止。遇到这种问题别想着配置层面绕过去正确做法是重构对象依赖关系。拆掉 A 和 B 之间的循环引用把其中一个改成非构造函数注入或者让其中一个变成 singleton 作为门面prototype 只依赖它而不反向依赖。Spring 官方对 prototype 循环依赖的态度就是不支持也不打算支持。6.4 现象四异步线程里调用 request Bean上下文说丢就丢最后分享一个特别常见的场景你在接口里把一个含业务逻辑的任务丢进了 CompletableFuture.runAsync 或线程池然后在异步任务里调用了注入的 Scope(request) Bean结果抛出了和 6.2 类似的No thread-bound request found。原因在于 RequestContextHolder 默认就是 ThreadLocal 实现的主线程的请求上下文不会自动传递给子线程。这是我个人踩得最多的一次接口里把当前用户的 request Bean 传进了异步任务结果子线程里拿到的是个代理代理想从线程上找请求属性结果发现这个新线程压根没有绑定任何请求。解决思路有两个方向在提交异步任务之前把当前 RequestContextHolder 的 attributes 取出来放进子线程再设置回去用完之后恢复。线程池任务类或者用一个 TaskDecorator 统一处理会比较好维护。更简单的是跨线程传递不是 Scope 该干的事。在进入异步任务之前把 request Bean 里的数据转成一个普通的值对象或 DTO 传进去异步任务里不要依赖任何 Web 作用域 Bean。这个方法虽然没有技术含量但在生产环境最不容易出幺蛾子。我后来定了一条团队习惯Web 作用域的 Bean 只活在请求处理的主链路里凡是出了这条链路要么转值对象要么重新从当前上下文取绝不隐含地跨线程依赖。这条习惯执行下来异步加多线程场景里的诡异 bug 少了大半。最后再分享一个很实用的小原则在项目里我默认所有 Bean 都是 singleton如果要用 prototype就从 ObjectProvider 获取并且明确知道自己在为谁承担销毁责任如果是 Web 作用域要么用代理要么只用 ObjectProvider 在请求线程内取用而自定义 Scope则永远是内置 Scope 确实覆盖不了需求时的最后一张牌。把这几个大原则刻进日常编码习惯里Scope 给你带来的惊喜就会远远少于惊吓。
RELATED

相关推荐

Qwen 27篇论文深度复盘:从架构选型到垂直分支的技术决策

Qwen 27篇论文深度复盘:从架构选型到垂直分支的技术决策

如果你打算把这27篇论文当作一个开源模型家族的编年史来读,我的建议是先别急着按发布时间排序。第一次接触这类大型模型家族的深度复盘时,我踩过的坑就是天天刷PDF,结果前后版本的技术点乱成一锅粥,读完只记得"参数又变多了&…

📅 2026/10/19 18:00:33
模型超越榜单背后:评测方法、开源部署与真实应用

模型超越榜单背后:评测方法、开源部署与真实应用

这周的AI圈讨论热度,比此前几场发布会加在一起还要高。起因很简单:一个过去几个月被默认“无人能撼动”的头部实验室 L,突然被一家此前并不显眼的团队压了过去。消息最先从某个众包评测榜单上传出,随后几天内,各路博主…

📅 2026/10/19 18:00:33
随机森林预测电池RUL:不依赖电化学方程的稳定建模方法

随机森林预测电池RUL:不依赖电化学方程的稳定建模方法

简介:本资源是一套基于Python随机森林算法的锂离子电池剩余寿命(RUL)预测完整实践方案,面向机器学习入门者与电池健康状态研究初学者,适用于课程设计、毕设选题及工程实训等场景。资源包共117个文件,含106个…

📅 2026/10/19 17:55:32
MORE NEWS

更多资讯

📰

任意组合深度图、相机位姿与内参:map-anything-apache-fp16 进阶输入配置详解

【免费下载链接】map-anything-apache-fp16 项目地址: https://ai.gitcode.com/hf_mirrors/mlx-community/map-anything-apache-fp16 点击查看 免费下载 map-anything-apache-fp16 是 MapAnything(Meta 与 CMU 的度量级前馈式 3D 重建模型)的…

📰

social-content - SKILL

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

📰

交通规划四种增长系数法:OD矩阵迭代与Python实现

简介:交通规划中的交通量预测是城市路网设计的关键环节。压缩包面向交通规划课程学习者与相关从业者,以4个MATLAB脚本分别实现弗兰特法、底特律法、平均系数法与佛尼斯法,覆盖基于历史增长、设施饱和度、平均增长率和路网迭代分配等多种预测思…

📰

量化策略回测源码解析:用Python+pandas打造可复现的交易流水线

简介:一套完整的量化策略源码包,面向量化交易初学者与策略研究者,覆盖个股日线行情从数据采集到模型评估的完整流程。压缩包内共18个文件,包括10个Python脚本、7个SQL数据库脚本和1个说明文档,整体仅56KB,体…

📰

PVTv2 b0到pvt_v2_b4全尺寸横评:5分钟教你选对轻量级视觉骨干网络

【免费下载链接】pvt_v2_b4 项目地址: https://ai.gitcode.com/OpenGVLab/pvt_v2_b4 点击查看 免费下载 PVTv2(Pyramid Vision Transformer v2) 是计算机视觉领域最受欢迎的轻量级视觉骨干网络(backbone)之一。本文以…

📰

The Impact of Fine-tuning Large Language Models on Automated Program Repair

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

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬