【设计模式系列 (三) 】单例模式
⭐️在这个怀疑的年代我们依然需要信仰。个人主页 YYYing.⭐️设计模式系列专栏设计模式系列系列上期内容【设计模式系列 (二) 】万字详解工厂模式系列下期内容【设计模式系列 (四) 】建造者模式单例要解决的问题只有一句话保证一个类只有一个实例并提供一个全局访问点。本文代码取自design-pattern-cpp 仓库的design-pattern/singleton/使用 C11。为阅读方便片段省略了头文件保护宏。1. 概述WikipediaIn software engineering, the singleton pattern is a software design pattern that restricts the instantiation of a class to one object. This is useful when exactly one object is needed to coordinate actions across the system.在软件工程中单例模式是一种软件设计模式它将类的实例化限制为一个对象。当需要一个对象来协 调整个系统的操作时这很有用。GoFEnsure a class only has one instance, and provide a global point of access to it.确保某一个类只有一个实例并提供一个全局的访问点来访问这个实例。有些类在整个系统中本来就只需要一个对象——配置管理器、日志器、线程池、资源池。多造几个不但浪费资源还会让状态分散到多处难以协调。单例模式就是把这个唯一性用代码强制约束住而不是靠开发者自觉。2. 结构单例模式只有一个角色Singleton单例类。它需要三件事同时成立约束手段目的外部不能new构造函数私有化杜绝随意创建对象不能复制delete拷贝构造、delete赋值运算符杜绝Singleton s2 *s1;绕过唯一性提供唯一入口静态成员变量 静态getInstance()全局唯一访问点仓库中把这套约束抽成了宏Macros.h/** 禁止赋值运算符/拷贝构造/无参构造 */ #define SINGLETON_HEPLER(TypeName) \ private: \ TypeName() {}; \ TypeName(const TypeName) delete; \ TypeName operator(const TypeName) delete;如果我们想要让代码解耦用宏无疑是非常好的选择但我们还有一种很好的用法他的名字叫做CRTP奇异递归模版如果你对智能指针比较熟悉可能会对这个东西有印象这个东西我们留作悬念将在本文的最终展示。3. 五种实现按初始化时机分两大类饿汉模式程序启动类加载时就创建实例空间换时间。懒汉模式第一次调用getInstance()时才创建时间换空间。3.1 饿汉 · 非局部静态Singleton1class Singleton1 { SINGLETON_HEPLER(Singleton1) private: static Singleton1 instance; public: static Singleton1* getInstance(); }; ​ // cpp singleton::Singleton1 singleton::Singleton1::instance; singleton::Singleton1* singleton::Singleton1::getInstance() { return instance; }最简单没有并发问题也没有效率问题。但埋着一颗雷非局部静态对象的初始化顺序是不确定的。静态对象指具有静态存储期限的对象从定义处开始分配的内存一直保留到程序结束包括全局变量、命名空间内的对象、static修饰的对象。其中块作用域内的称为局部静态对象其余的都叫非局部静态对象。看一段演示代码。A.cpp里有个全局对象a构造时把key置为2B.cpp里有个全局对象b构造时读取a.getKey()并打印// A.cpp A::A() { key 2; } A a; // A 的全局变量 ​ // B.cpp B::B() { std::cout a.getKey() std::endl; } B b; // B 的全局变量 ​ // main.cpp int main() { return 0; }换个链接顺序结果就变了g -o main B.cpp A.cpp main.cpp # 输出 2 g -o main A.cpp B.cpp main.cpp # 输出 0原因是同一个编译单元内的非局部静态对象按定义顺序初始化顺序确定不同编译单元之间的初始化顺序是未定义的。第二行的b先于a构造读到的key是零初始化的0。这就是著名的静态初始化顺序问题SIOF。如果 A 和 B 都是单例B 的初始化又依赖 A 的实例程序行为就是随机的。3.2 饿汉 · 局部静态 辅助类Singleton2思路把单例对象从非局部静态改成局部静态再用一个辅助类在静态初始化阶段主动触发一次构造。class Singleton2 { SINGLETON_HEPLER(Singleton2) public: static Singleton2* getInstance(); private: class Creator { public: Creator(); static Creator m_creator; // 非局部静态静态初始化阶段就会被构造 }; }; ​ // cpp singleton::Singleton2::Creator singleton::Singleton2::Creator::m_creator; singleton::Singleton2::Creator::Creator() { Singleton2::getInstance(); // 在辅助类构造时触发单例的构造 } ​ singleton::Singleton2* singleton::Singleton2::getInstance() { static Singleton2 instace; // 局部静态 return instace; }为什么这样就安全了局部静态对象是首次执行到该声明时构造的这个时机由调用者决定而不由链接器决定。于是如果别的类在自己的静态初始化里先调用了Singleton2::getInstance()单例就在那一刻被构造顺序天然正确如果谁都没调用m_creator的构造也会兜底触发一次。两种情况都只会构造一次顺序始终明确SIOF 被消掉了。3.3 懒汉 · 裸指针Singleton3有缺陷class Singleton3 { SINGLETON_HEPLER(Singleton3) public: static Singleton3* getInstance(); private: static Singleton3* instance; }; ​ // cpp singleton::Singleton3* singleton::Singleton3::instance nullptr; singleton::Singleton3* singleton::Singleton3::getInstance() { if (!instance) { instance new singleton::Singleton3(); } return instance; }两个缺陷都是面试考点线程不安全。线程 1 判断instance为空开始new线程 2 此时判断instance仍然为空还没赋值回去也去new——最终创建出两个对象甚至可能拿到半成品对象。内存泄漏。类里只负责new没人负责delete。3.4 懒汉 · shared_ptr 双检锁Singleton4class Singleton4 { SINGLETON_HEPLER(Singleton4) public: static Singleton4* getInstance(); private: static std::shared_ptrSingleton4 instance; static std::mutex m_mutex; }; ​ // cpp std::shared_ptrsingleton::Singleton4 singleton::Singleton4::instance nullptr; std::mutex singleton::Singleton4::m_mutex; ​ singleton::Singleton4* singleton::Singleton4::getInstance() { if (!instance) // 第一重检查避免每次都加锁 { std::lock_guardstd::mutex lock(m_mutex); if (!instance) // 第二重检查防止重复创建 { instance std::shared_ptrSingleton4(new Singleton4()); } } return instance.get(); }为什么判断两次高频八股检查作用外层if实例已经存在时直接返回不加锁。锁的开销不小而getInstance()是高频调用不能每次都锁内层if两个线程可能同时通过外层检查然后排队等锁。第一个线程创建完释放锁后第二个线程拿到锁必须再判一次否则会重复创建这个版本的改进用std::shared_ptrRAII管理资源析构时自动delete解决内存泄漏用std::mutex加锁解决线程安全。但它仍然不完美依赖 C11shared_ptr、mutex双检锁在某些平台下会失效。第一重检查在锁外读instance与锁内的写构成数据竞争编译器/CPU 的指令重排序可能让另一个线程读到指针已赋值但对象尚未构造完的状态。这是经典的 DCLP 问题想了解的链接打不开就自己问ai或者搜搜其他文章吧。C11 下要写对需要把instance换成std::atomicSingleton*并配 acquire/release 内存序——但那还不如直接看下一节。虽然不是很完美但我也在其他面经中见到过双检锁单例的考察还是建议记下。3.5 懒汉 · 局部静态Meyers Singleton推荐class Singleton5 { SINGLETON_HEPLER(Singleton5) public: static Singleton5* getInstance(); }; ​ // cpp singleton::Singleton5* singleton::Singleton5::getInstance() { static Singleton5 instance; return instance; }这是 C 里公认最简洁、最正确的写法作者是《Effective C》的 Meyers所以叫Meyers Singleton。它依赖 C11 的Magic Static特性If control enters the declaration concurrently while the variable is being initialized, the concurrent execution shall wait for completion of the initialization.如果多个线程并发进入该变量的声明语句而变量正在初始化则并发线程会阻塞等待初始化完成。一句话总结线程安全编译器保证、不会内存泄漏静态对象自动析构、代码最短。五种写法对比Singleton1Singleton2Singleton3Singleton4Singleton5类别饿汉饿汉懒汉懒汉懒汉创建时机程序启动静态初始化阶段首次调用首次调用首次调用线程安全✅启动期单线程✅❌⚠️ 双检锁有平台风险✅内存泄漏✅ 无✅ 无❌ 有✅ 无RAII✅ 无主要问题SIOF 初始化顺序不确定多一个辅助类两个缺陷齐活依赖 C11、DCLP 风险—推荐度⚠️✅❌⚠️⭐推荐4. 优缺点与适用环境主要优点提供对唯一实例的受控访问单例类封装了唯一实例能严格控制客户何时、如何访问它节约系统资源内存中只有一个对象对频繁创建销毁的对象尤其明显可扩展为多例模式用同样的控制思路获得指定个数的实例。主要缺点没有抽象层扩展困难单例类通常直接暴露具体类名难以替换为子类职责过重违背单一职责原则既当工厂提供创建方法又当产品承载业务方法全局状态难以测试单元测试之间会互相污染依赖关系被隐藏在调用点而不是构造函数里在带 GC 的语言里长时间不使用的单例可能被回收导致状态丢失。适用环境系统只需要一个实例对象如唯一序列号生成器、资源管理器或资源消耗过大只允许创建一个对象客户端调用该类的单个实例时只允许通过一个公共访问点不能有其他途径。5. 面试专题5.1 开场题说说单例模式吧考察点是概念、创建方式、应用场景三块按这个顺序答概念单例模式确保一个类只有一个实例并提供一个全局访问点。实现上要私有化构造函数、禁止拷贝与赋值、提供静态的getInstance()。创建方式分饿汉和懒汉两类。饿汉在程序启动时就创建简单但没有延迟加载懒汉在首次使用时创建需要考虑线程安全。懒汉的演进路线是裸指针版线程不安全 内存泄漏→ 智能指针加双检锁RAII 解决泄漏加锁解决并发但双检锁在某些平台会失效→局部静态版Meyers Singleton依靠 C11 的 Magic Static既线程安全又不会泄漏是最推荐的写法。应用场景系统只需要一个实例或需要唯一的全局访问点时比如配置管理、日志、线程池、序列号生成器。5.2 高频追问清单追问答法饿汉和懒汉的区别初始化时机不同饿汉在程序启动/类加载时创建空间换时间懒汉在首次调用时创建时间换空间为什么要私有构造函数防止外部随意new唯一性从源头被破坏为什么还要删除拷贝构造和赋值运算符私有构造只挡住了newSingleton s2 *s1;或s2 *s1;仍能绕过必须一并delete双检锁为什么要判断两次外层为了已存在时免加锁性能内层为了防止多个线程同时通过外层检查后重复创建双检锁一定安全吗不一定。锁外读、锁内写构成数据竞争指令重排序可能让别的线程读到未构造完的对象。C11 正解是用std::atomic配 acquire/release或者直接用 Meyers 单例局部静态为什么线程安全C11 的 Magic Static 保证并发进入初始化时会阻塞等待初始化完成单例的内存泄漏怎么解决用静态对象自动析构或智能指针 RAII裸指针方案可以配atexit注册清理但不如前两者干净单例对象什么时候析构局部静态对象在main()结束后按构造的逆序析构裸指针new出来的永远不会析构单例是线程安全的吗陷阱题。线程安全的是创建过程不是单例本身。单例持有的共享数据仍然需要自己加锁保护单例有什么缺点没有抽象层扩展难、职责过重违背单一职责、全局状态导致单元测试互相污染、依赖关系被隐藏单例和静态类全静态方法的类有什么区别单例可以继承、可以实现接口、可以延迟初始化、可以多态并且明确持有一个对象静态类全部编译期绑定不受 OOP 规则约束单例可以继承吗可以把构造函数改成protected。但实践中很少这么用因为单例往往就是终态类5.3 建造者/工厂里也藏着单例一个很好的工程印证素材仓库里的ClassFactory反射机制的核心自己就是 Meyers 单例ClassFactory ClassFactory::getInstance() { static ClassFactory instance; return instance; }而它的注册动作来自DynamicClass的构造函数——IMPLEMENT_CLASS宏在静态初始化阶段 new 出一个DynamicClass构造时把自己的工厂函数注册进单例。这里同时用到了单例和非局部静态对象的初始化时机两个知识点是一道很好的综合面试题。5.4 什么时候不该用单例单例最大的问题不是写不出来而是被当成了全局变量的遮羞布。出现以下信号就该警惕只是为了到处都能拿到这个对象而用单例 → 应该用依赖注入把对象传进去单例里有大量可变状态且被多个模块读写 → 本质是全局变量并发和测试都会出问题单例之间有依赖初始化有先后 → 容易踩 SIOF慎用饿汉模式。6. 彩蛋CRTP 奇异递归模版前面五种写法都是在具体类里手写单例约束。如果工程里有十几个类要做单例在你不用宏的情况下样板代码会爆炸。CRTP奇异递归模板模式把这套约束抽成一个基类模板任何类只要继承它就自动变成单例。6.1 实现#pragma once #include memory #include mutex #include iostream using namespace std; template typename T class Singleton { protected: Singleton() default; Singleton(const SingletonT) delete; Singleton operator(const SingletonT st) delete; static std::shared_ptrT _instance; public: static std::shared_ptrT GetInstance() { static std::once_flag s_flag; std::call_once(s_flag, []() { _instance shared_ptrT(new T); }); return _instance; } void PrintAddress() { std::cout _instance.get() endl; } ~Singleton() { std::cout this is singleton destruct std::endl; } }; template typename T std::shared_ptrT SingletonT::_instance nullptr;6.2 使用class Point : public SingletonPoint { public: Point() { cout Point construct endl; } }; ​ int main() { auto p1 SingletonPoint::GetInstance(); auto p2 SingletonPoint::GetInstance(); ​ p1-PrintAddress(); p2-PrintAddress(); return 0; }输出Point construct 0123ABCD 0123ABCD this is singleton destruct两次地址相同shared_ptr指向同一个对象Point construct只打印一次this is singleton destruct在main()返回之后才出现——因为_instance是静态存储期对象直到程序退出才释放。6.3 CRTP 是什么Curiously Recurring Template Pattern派生类把自己作为模板参数传给基类模板。class Point : public SingletonPoint // ^^^^^^^^^^^^^^^ 自己传给自己这样一来基类在编译期就知道我派生出了谁于是可以在基类里直接new T、返回T的指针——不需要知道T的名字提供编译期多态基类里写static_castT*(this)-foo()就能调到派生类的实现没有虚函数表、没有运行期开销。本例只用到第一点GetInstance()是静态函数连static_cast都不需要。如果想让基类提供非静态的接口给派生类用就得靠static_castT*(this)向下转型那才是 CRTP 的典型用法。如果智能指针那块你比较熟练不妨可以发现我们enable_shared_fromxxx是同一个东西也就是我们的CRTP。6.4 这段代码里的三个关键点机制作用protected构造 delete拷贝/赋值与SINGLETON_HEPLER宏一样的效果但类型安全、可带成员、可调试不是文本替换std::call_once 局部静态once_flag保证只构造一次且是 C11 标准给的线程安全工具没有 DCLP 的重排序风险shared_ptrT _instanceRAII 自动释放不泄漏 nullptr属于常量初始化不参与动态初始化的顺序竞争天然避开 SIOF关于call_once相对双检锁的优势可以正面回答为什么不用双检锁once_flag的内部状态由标准库维护调用方不需要自己安排内存序写错了也不会退化成数据竞争。关于_instance nullptr它是常量初始化在动态初始化开始之前就已经完成所以这个指针本身不存在谁先谁后的问题对比 3.1 节的 SIOF。6.5 三个坑坑一挡不住外部new T。上面Point的构造函数是public的new Point照样能造出第二个对象此时它已经不是严格意义上的单例。要真正封住得让T自己私有化构造并把SingletonT设为友元class Point : public SingletonPoint { friend class SingletonPoint; // 让基类的 new T 能访问私有构造 private: Point() default; };注意派生类的私有构造不会自动被基类访问friend声明不能省。坑二call_once里抛异常会重试。如果T的构造函数抛异常这次调用算失败once_flag不会被置为已完成下一次GetInstance()会重新尝试构造。这既是特性构造失败允许重试也是坑构造函数里已经产生的副作用会重复执行一遍。坑三模板静态成员的定义必须放在头文件里。template typename T std::shared_ptrT SingletonT::_instance nullptr;写进.h是模板的正常写法不会链接冲突——因为它是模板每个T各自实例化一份。6.6 与其他实现对比宏SINGLETON_HEPLERMeyers 单例CRTP 模板单例shared_ptr 双检锁复用方式宏展开手写继承基类模板手写类型安全❌ 文本替换—✅—线程安全取决于写法✅✅call_once⚠️ DCLP 风险内存泄漏取决于写法✅ 无✅ 无✅ 无返回类型自定义引用/指针shared_ptrT指针主要缺点无法调试、易踩宏展开坑每个类都要写一遍构造函数需friend配合析构非虚平台相关性如果只想让代码最短C11 之后还有一个更简的变体基类是个空模板只负责提供GetInstancetemplate typename T class Singleton { public: static T GetInstance() { static T instance; return instance; } };本质还是 Meyers 单例只是用 CRTP 把写一遍变成了继承一下。6.7 面试问答追问答法什么是 CRTP奇异递归模板模式派生类把自己作为模板参数传给基类模板class D : public BaseD。基类因此在编译期就知道派生类的类型可实现编译期多态无虚函数开销为什么用 CRTP 写单例把私有构造 禁止拷贝 静态实例 唯一访问点这套约束抽成基类模板派生类继承即可避免每个单例类重复样板代码比宏更类型安全CRTP 单例和 Meyers 单例的关系不冲突是正交的两件事Meyers 说的是用局部静态实现懒汉CRTP 说的是如何复用单例约束。CRTP 基类里同样可以塞一个局部静态的 Meyers 单例为什么这里用call_once而不是双检锁once_flag由标准库保证只执行一次并且自带正确的内存序不需要手写atomic和 acquire/release避开了 DCLP 的重排序问题call_once里的函数抛异常会怎样这次算执行失败once_flag不置位下次调用会重新执行一遍这段代码算严格单例吗算一半。如果派生类构造函数是public外部仍能new唯一性被破坏。必须把派生类构造私有化并friend class SingletonT为什么_instance定义在头文件里没问题它是类模板的静态成员每个T各自实例化一份模板定义放头文件是标准做法不会重复定义为什么用shared_ptr而不是裸指针RAII静态存储期的shared_ptr在程序退出时自动delete对象不需要atexit或手工清理同时GetInstance()返回它时共享所有权析构时机可控结语单例模式仍然是面试经常考的一个点像我前面讲的这几篇对应的设计模式都是较为常用也常考的希望这篇文章能对你有所帮助。我是YYYing后面还有更精彩的内容希望各位能多多关注支持一下主包。无限进步我们下次再见

相关新闻

PanWatch 持仓页点一下会发生什么?TradingAgents 深度分析全流程实测

PanWatch 持仓页点一下会发生什么?TradingAgents 深度分析全流程实测

PanWatch 持仓页点一下会发生什么?TradingAgents 深度分析全流程实测 【免费下载链接】PanWatch PanWatch — AI stock monitoring for A-shares, HK & US markets, powered by TradingAgents. Portfolio insights, real-time alerts & automated reports.&…

2026/9/30 14:28:23 阅读更多 →
选蛋白营养产品别只看标注,科研实力才是核心标尺

选蛋白营养产品别只看标注,科研实力才是核心标尺

国民健康意识持续提升,蛋白营养产品市场快速扩容,各式各样蛋白粉、复合蛋白补给产品层出不穷。很多消费者挑选蛋白营养产品时,很容易陷入选购误区,仅仅对比包装上的蛋白质含量数值,忽略品牌背后完整的科研体系、原料验…

2026/9/30 14:27:23 阅读更多 →
计算机毕业设计选题推荐:基于大数据的环境空气质量数据可视化分析|毕业设计选题|计算机毕设|选题推荐|毕设指导|项目定制|源码|高质量项目

计算机毕业设计选题推荐:基于大数据的环境空气质量数据可视化分析|毕业设计选题|计算机毕设|选题推荐|毕设指导|项目定制|源码|高质量项目

✨作者主页:IT毕设梦工厂✨ 个人简介:曾从事计算机专业培训教学,擅长Java、Python、PHP、.NET、Node.js、GO、微信小程序、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇…

2026/9/30 14:27:22 阅读更多 →

最新新闻

Vue3 + Element Plus 中 SVG 图标组件化实战方案

Vue3 + Element Plus 中 SVG 图标组件化实战方案

1. 项目概述&#xff1a;为什么在 Vue3 Element Plus 项目里&#xff0c;SVG 图标不是“加个标签”就完事的&#xff1f;Vue3 Element Plus 项目里引入 SVG 图标&#xff0c;表面看只是把一个<svg>标签塞进组件里&#xff0c;但实际落地时&#xff0c;90% 的人会在第三…

2026/9/30 15:09:17 阅读更多 →
物联网赋能工程装备管控:工程机械远程监控方案,实现装备可视化综合远程管理

物联网赋能工程装备管控:工程机械远程监控方案,实现装备可视化综合远程管理

前言基建、矿山、市政项目施工现场高度分散&#xff0c;塔吊、推土机、搅拌机等工程机械分布在多个异地工地。传统装备管理模式存在诸多痛点&#xff1a;依靠现场人员人工记录设备工况&#xff0c;故障往往等到设备停机之后才被发现&#xff0c;属于被动抢修模式&#xff1b;设…

2026/9/30 15:09:17 阅读更多 →
YOLOv11-CLS图像分类C++部署实战:ONNX Runtime推理链路完整指南

YOLOv11-CLS图像分类C++部署实战:ONNX Runtime推理链路完整指南

简介&#xff1a;一份以C和ONNX Runtime为核心的YOLOv11-CLS图像分类模型部署文档&#xff0c;面向具备C与深度学习基础、从事计算机视觉或图像识别项目开发的工程师。文档为单个docx文件&#xff08;约37KB&#xff09;&#xff0c;结构紧凑&#xff0c;依次介绍项目背景、数据…

2026/9/30 15:09:17 阅读更多 →
MySQL配置文件完全指南:加载顺序、参数调优与常见问题排查

MySQL配置文件完全指南:加载顺序、参数调优与常见问题排查

1. 配置文件在哪&#xff1a;先搞清楚 MySQL 到底读了哪个文件很多人装好 MySQL 之后第一件事就是翻配置文件&#xff0c;结果翻遍了/etc/my.cnf、/etc/mysql/my.cnf、/usr/my.cnf都找不到自己想要的参数&#xff0c;或者改了文件重启之后参数根本没生效。这种体验我太熟悉了&a…

2026/9/30 15:09:17 阅读更多 →
Flutter开发OpenHarmony喝水提醒应用:跨端调度与本地通知实战

Flutter开发OpenHarmony喝水提醒应用:跨端调度与本地通知实战

如果你手里刚好有一台OpenHarmony开发板&#xff0c;想用Flutter给它写点实用工具&#xff0c;那喝水提醒这个项目绝对是个不错的起点。我最初的想法很简单&#xff1a;手机上的提醒类App不能直接装到开源鸿蒙设备上&#xff0c;原生开发又得重新学ArkTS&#xff0c;干脆走Flut…

2026/9/30 15:09:17 阅读更多 →
PyTorch Geometric实战指南:从Data构造到GNN训练部署

PyTorch Geometric实战指南:从Data构造到GNN训练部署

1. 项目概述&#xff1a;这不是又一个“Hello World”式的GNN教程你点开这篇内容&#xff0c;大概率不是为了看“图神经网络是什么”这种教科书定义——你手头正卡在一个真实场景里&#xff1a;可能是实验室里刚拿到的分子结构数据集&#xff0c;需要预测化合物活性&#xff1b…

2026/9/30 15:07:59 阅读更多 →

日新闻

Base64 图片头部特征识别:从文件头到格式判断的完整指南

Base64 图片头部特征识别:从文件头到格式判断的完整指南

1. 项目概述&#xff1a;为什么说看懂 base64 图片头部是基本功这几年跟 base64 打交道的机会越来越多&#xff0c;后端接口返回图片、前端渲染验证码、小程序里存小图、还有一些老系统导出报表&#xff0c;动不动就给你一段长到怀疑人生的 base64 字符串。很多人拿到字符串就直…

2026/9/30 0:00:35 阅读更多 →
Java公交站牌广告管理系统:JSP+Servlet+MySQL实战落地指南

Java公交站牌广告管理系统:JSP+Servlet+MySQL实战落地指南

简介&#xff1a;本资源是一份面向Java初学者与课程设计学生的公交站牌广告灯箱管理系统毕业设计文档&#xff0c;聚焦城市公共广告资源信息化管理痛点&#xff0c;提供从需求分析到技术实现的完整方案。文档采用标准学术论文结构&#xff0c;含摘要、英文摘要、目录及五章正文…

2026/9/30 0:00:35 阅读更多 →
用 Redis Lua 构建大模型 API 多租户原子配额治理体系

用 Redis Lua 构建大模型 API 多租户原子配额治理体系

我去年年底接了一个内部 AI 平台的治理需求&#xff0c;背景很直接&#xff1a;公司把 DeepSeek、MiniMax 这类大模型 API 统一封装成内部网关&#xff0c;开放给几个业务团队用。结果第一个月账单出来&#xff0c;额度直接超了 4 倍。仔细查日志&#xff0c;发现原因并不复杂—…

2026/9/30 0:00:35 阅读更多 →

周新闻

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解

如何划分训练/验证集&#xff1a;Spirula Studio五种eval_mode策略详解 【免费下载链接】spirula-studio Cross-vendor 3D Gaussian Splatting trainer - video to splat to mesh, Vulkan or CUDA. 项目地址: https://gitcode.com/GitHub_Trending/sp/spirula-studio Sp…

2026/9/30 13:14:22 阅读更多 →
SEO怎么推广速查手册新手避坑实战指南

SEO怎么推广速查手册新手避坑实战指南

SEO怎么推广速查手册新手避坑实战指南 模板网站太丑不够用?别急着加滤镜,那是治标不治本。很多老板盯着后台流量掉得眼红,却还在纠结首页Banner的圆角是不是3像素。这就像穿着西装去挖土,姿势不对,努力白费。我整理这份 速查手册…

2026/9/29 16:41:41 阅读更多 →
FireRed-OpenStoryline少样本仿写深度解析:AI Agent如何复刻你的独特文案风格与节奏

FireRed-OpenStoryline少样本仿写深度解析:AI Agent如何复刻你的独特文案风格与节奏

FireRed-OpenStoryline少样本仿写深度解析:AI Agent如何复刻你的独特文案风格与节奏 【免费下载链接】FireRed-OpenStoryline FireRed-OpenStoryline is an AI video editing agent that transforms manual editing into intention-driven directing through natural language …

2026/9/30 13:14:49 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践&#xff1a;原型怎样变成可用功能分类&#xff1a;[AI/大模型]细分主题&#xff1a;AI 增强型 CI/CD 流水线自动化与 GitOps 实践&#xff1a;Agent 工作流、工具调用与任务拆解&#xff1a;从原型到生产的验收清单很多团队在尝试用大…

2026/9/29 19:29:29 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战&#xff1a;复盘记录怎样真正派上用场分类&#xff1a;[工程技术]细分主题&#xff1a;Kubernetes 生产环境运维与排障实战&#xff1a;可复制的项目复盘模板与决策记录大部分团队的事故复盘报告&#xff0c;最后都变成了躺在 Confluence 或钉…

2026/9/29 5:58:00 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理&#xff1a;核心链路应该先拆哪一步分类&#xff1a;[工程技术]细分主题&#xff1a;Docker 容器化技术与镜像安全管理&#xff1a;核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用&#xff08;包含 Web 接口、后台…

2026/9/29 3:55:56 阅读更多 →