C++代理模式详解:从基础到高级应用
1. 代理模式基础概念回顾在正式探讨代理模式的变体之前我们需要先明确经典代理模式的核心机制。代理模式属于结构型设计模式其主要目的是为其他对象提供一种代理以控制对这个对象的访问。这种模式在C中尤为常见因为它能很好地解决直接访问对象时带来的问题。代理对象在客户端和目标对象之间起到中介作用这种架构带来了几个显著优势可以控制客户端对真实对象的访问权限能够在访问真实对象前后添加额外的操作逻辑作为真实对象的替身降低系统耦合度对客户端隐藏真实对象的复杂性典型的UML类图包含三个核心角色Subject抽象主题声明真实主题和代理主题的共同接口RealSubject真实主题定义了代理所代表的真实对象Proxy代理维护一个引用使得代理可以访问真实主题// 经典代理模式基础实现 class Subject { public: virtual void Request() 0; virtual ~Subject() default; }; class RealSubject : public Subject { public: void Request() override { std::cout RealSubject handling request\n; } }; class Proxy : public Subject { RealSubject* real_subject_; public: Proxy() : real_subject_(new RealSubject()) {} ~Proxy() { delete real_subject_; } void Request() override { // 前置处理 std::cout Proxy preprocessing\n; // 委托给真实对象 real_subject_-Request(); // 后置处理 std::cout Proxy postprocessing\n; } };关键提示代理模式与装饰器模式在实现上很相似但设计意图不同。装饰器模式重在增强功能而代理模式重在控制访问。2. 虚拟代理延迟加载的实践艺术2.1 虚拟代理的核心机制虚拟代理(Virtual Proxy)是代理模式中最常用的变体之一它通过延迟加载技术优化系统性能。当创建一个对象开销很大时虚拟代理可以推迟对象的实际创建和初始化直到真正需要使用时才进行加载。这种技术在大数据量处理、图像加载等场景中尤为有效。例如在文档处理软件中可能只需要显示当前可见页面的图像其他页面的图像可以等到用户滚动到对应位置时再加载。class Image { public: virtual void Display() 0; virtual ~Image() default; }; class RealImage : public Image { std::string filename_; public: RealImage(const std::string filename) : filename_(filename) { LoadFromDisk(); } void Display() override { std::cout Displaying filename_ \n; } private: void LoadFromDisk() { std::cout Loading filename_ from disk (expensive operation)\n; } }; class ImageProxy : public Image { std::string filename_; RealImage* real_image_ nullptr; public: ImageProxy(const std::string filename) : filename_(filename) {} ~ImageProxy() { delete real_image_; } void Display() override { if (!real_image_) { real_image_ new RealImage(filename_); // 延迟加载 } real_image_-Display(); } };2.2 虚拟代理的性能优化策略在实际工程中虚拟代理的实现往往比基础示例复杂得多。我们需要考虑以下几个关键优化点线程安全多线程环境下延迟加载可能导致竞态条件// 线程安全的虚拟代理实现 class ThreadSafeImageProxy : public Image { std::mutex mutex_; std::atomicRealImage* real_image_{nullptr}; std::string filename_; public: void Display() override { if (!real_image_.load(std::memory_order_acquire)) { std::lock_guardstd::mutex lock(mutex_); if (!real_image_.load(std::memory_order_relaxed)) { auto* new_image new RealImage(filename_); real_image_.store(new_image, std::memory_order_release); } } real_image_.load(std::memory_order_acquire)-Display(); } };内存管理需要考虑何时释放代理对象持有的资源加载策略可以预加载部分数据或实现后台加载实战经验在大型项目中虚拟代理常与对象池模式结合使用避免频繁创建销毁大对象带来的性能损耗。3. 保护代理访问控制的精妙实现3.1 保护代理的基本原理保护代理(Protection Proxy)通过代理对象控制对真实对象的访问权限。这种模式在需要实现不同级别访问控制的系统中非常有用例如操作系统资源访问企业应用中的权限管理多用户环境下的数据隔离class Database { public: virtual void Query(const std::string sql) 0; virtual ~Database() default; }; class RealDatabase : public Database { public: void Query(const std::string sql) override { std::cout Executing: sql \n; } }; class User { std::string name_; int access_level_; public: User(std::string name, int level) : name_(std::move(name)), access_level_(level) {} int GetAccessLevel() const { return access_level_; } }; class DatabaseProxy : public Database { RealDatabase real_db_; User user_; public: DatabaseProxy(User user) : user_(std::move(user)) {} void Query(const std::string sql) override { if (CheckAccess(sql)) { real_db_.Query(sql); } else { std::cout Access denied for query: sql \n; } } private: bool CheckAccess(const std::string sql) { // 简单示例根据SQL类型和用户权限判断 bool is_sensitive sql.find(DELETE) ! std::string::npos || sql.find(UPDATE) ! std::string::npos; return !is_sensitive || user_.GetAccessLevel() 5; } };3.2 保护代理的高级应用在实际系统中保护代理的实现通常更加复杂和灵活基于角色的访问控制(RBAC)class RBACProxy : public Database { std::unordered_mapstd::string, std::setstd::string permissions_ { {admin, {SELECT, INSERT, UPDATE, DELETE}}, {editor, {SELECT, INSERT, UPDATE}}, {viewer, {SELECT}} }; // 实现略... };属性基访问控制(ABAC)动态权限检查避坑指南保护代理的性能瓶颈往往在权限检查环节。对于高频访问的系统建议使用缓存优化权限检查结果将静态权限检查移到编译期通过模板元编程实现权限的批量检查接口4. 智能指针代理C资源管理的核心武器4.1 unique_ptr作为代理C标准库中的智能指针本质上就是代理模式的实现它们代理了原始指针的生命周期管理。unique_ptr是最基础的智能指针代理它提供了独占所有权的语义。templatetypename T class UniquePtrProxy { T* ptr_; public: explicit UniquePtrProxy(T* p nullptr) : ptr_(p) {} ~UniquePtrProxy() { delete ptr_; } // 删除拷贝构造和赋值 UniquePtrProxy(const UniquePtrProxy) delete; UniquePtrProxy operator(const UniquePtrProxy) delete; // 移动语义 UniquePtrProxy(UniquePtrProxy other) noexcept : ptr_(other.ptr_) { other.ptr_ nullptr; } UniquePtrProxy operator(UniquePtrProxy other) noexcept { if (this ! other) { delete ptr_; ptr_ other.ptr_; other.ptr_ nullptr; } return *this; } T operator*() const { return *ptr_; } T* operator-() const { return ptr_; } explicit operator bool() const { return ptr_ ! nullptr; } };4.2 shared_ptr与weak_ptr的代理模式shared_ptr实现了引用计数的共享所有权代理而weak_ptr则是一种观察者代理不影响引用计数但可以安全地观察资源状态。templatetypename T class SharedPtrProxy { struct ControlBlock { T* ptr; int ref_count; // 可能还有删除器、分配器等 explicit ControlBlock(T* p) : ptr(p), ref_count(1) {} ~ControlBlock() { delete ptr; } }; ControlBlock* cb_; public: explicit SharedPtrProxy(T* p nullptr) : cb_(p ? new ControlBlock(p) : nullptr) {} ~SharedPtrProxy() { if (cb_ --cb_-ref_count 0) { delete cb_; } } // 拷贝构造和赋值 SharedPtrProxy(const SharedPtrProxy other) : cb_(other.cb_) { if (cb_) cb_-ref_count; } SharedPtrProxy operator(const SharedPtrProxy other) { if (this ! other) { if (cb_ --cb_-ref_count 0) { delete cb_; } cb_ other.cb_; if (cb_) cb_-ref_count; } return *this; } // 移动语义 SharedPtrProxy(SharedPtrProxy other) noexcept : cb_(other.cb_) { other.cb_ nullptr; } // 其他接口... };性能考量智能指针代理虽然方便但会带来一定的性能开销。在性能关键路径上需要权衡是否使用智能指针代理。5. 远程代理分布式系统的通信桥梁5.1 远程代理的基本架构远程代理(Remote Proxy)为位于不同地址空间的对象提供本地代表。这种代理模式在分布式系统中非常常见例如RPC框架CORBA分布式对象系统// 接口定义 class Calculator { public: virtual int Add(int a, int b) 0; virtual ~Calculator() default; }; // 真实对象服务端 class RealCalculator : public Calculator { public: int Add(int a, int b) override { return a b; } }; // 远程代理客户端 class RemoteCalculatorProxy : public Calculator { std::string server_address_; public: explicit RemoteCalculatorProxy(std::string address) : server_address_(std::move(address)) {} int Add(int a, int b) override { // 模拟网络通信 std::cout Sending request to server_address_ \n; // 实际实现中会使用网络库发送请求 // 这里简化为直接调用本地函数 return a b; } };5.2 远程代理的高级特性现代远程代理实现通常包含以下高级特性连接池管理负载均衡故障转移请求重试序列化/反序列化class EnhancedRemoteProxy : public Calculator { ConnectionPool pool_; LoadBalancer lb_; Serializer serializer_; public: int Add(int a, int b) override { int retries 3; while (retries--) { try { auto conn pool_.GetConnection(lb_.SelectServer()); auto request serializer_.SerializeRequest(Add, {a, b}); auto response conn-SendRequest(request); return serializer_.DeserializeResponseint(response); } catch (const NetworkException e) { if (retries 0) throw; } } throw std::runtime_error(Operation failed after retries); } };调试技巧远程代理的调试往往比较困难。建议实现详细的请求/响应日志添加请求ID便于跟踪实现模拟模式(Mock Mode)用于本地测试6. 缓存代理性能优化的利器6.1 缓存代理的基本实现缓存代理(Cache Proxy)通过存储请求结果来优化性能特别适用于计算密集型或IO密集型的操作。常见的应用场景包括数据库查询缓存Web代理缓存计算结果的缓存class ExpensiveOperation { public: virtual int Compute(int x) 0; virtual ~ExpensiveOperation() default; }; class RealOperation : public ExpensiveOperation { public: int Compute(int x) override { std::cout Performing expensive computation for x \n; // 模拟耗时操作 std::this_thread::sleep_for(std::chrono::milliseconds(100)); return x * x; } }; class CacheProxy : public ExpensiveOperation { RealOperation real_op_; std::unordered_mapint, int cache_; std::mutex mutex_; public: int Compute(int x) override { std::lock_guardstd::mutex lock(mutex_); auto it cache_.find(x); if (it ! cache_.end()) { std::cout Cache hit for x \n; return it-second; } std::cout Cache miss for x \n; int result real_op_.Compute(x); cache_[x] result; return result; } };6.2 高级缓存策略生产环境中的缓存代理通常需要更复杂的策略LRU缓存淘汰策略templatetypename K, typename V class LRUCache { size_t capacity_; std::liststd::pairK, V items_; std::unordered_mapK, typename std::liststd::pairK, V::iterator map_; public: V* Get(const K key) { auto it map_.find(key); if (it map_.end()) return nullptr; items_.splice(items_.begin(), items_, it-second); return it-second-second; } void Put(const K key, const V value) { // 实现略... } };缓存失效策略分布式缓存支持缓存预热性能指标缓存代理的效果通常用命中率(Hit Rate)衡量。良好的缓存设计应该达到80%以上的命中率。7. 代理模式的现代C实现技巧7.1 使用std::function实现通用代理现代C提供了更灵活的方式来实现代理模式例如使用std::function和lambda表达式class GenericProxy { std::functionvoid() pre_action_; std::functionvoid() post_action_; std::functionvoid() real_action_; public: templatetypename Pre, typename Real, typename Post GenericProxy(Pre pre, Real real, Post post) : pre_action_(pre), real_action_(real), post_action_(post) {} void Execute() { if (pre_action_) pre_action_(); if (real_action_) real_action_(); if (post_action_) post_action_(); } }; // 使用示例 GenericProxy proxy( [] { std::cout Before action\n; }, [] { std::cout Real action\n; }, [] { std::cout After action\n; } ); proxy.Execute();7.2 可变参数模板实现通用代理工厂templatetypename Subject class ProxyFactory { public: templatetypename... Args static auto CreateProxy(Args... args) { return [](auto... funcArgs) { // 前置处理 std::cout Proxy preprocessing\n; // 调用真实对象 Subject subject(std::forwardArgs(args)...); auto result subject(std::forwarddecltype(funcArgs)(funcArgs)...); // 后置处理 std::cout Proxy postprocessing\n; return result; }; } }; // 使用示例 auto proxy ProxyFactorystd::plusint::CreateProxy(); int result proxy(5, 3); // 输出预处理和后处理信息返回87.3 代理模式与CRTP的结合奇异递归模板模式(CRTP)可以用来实现静态多态的代理templatetypename Derived class ProxyBase { public: void Operation() { static_castDerived*(this)-PreOperation(); static_castDerived*(this)-RealOperation(); static_castDerived*(this)-PostOperation(); } }; class ConcreteProxy : public ProxyBaseConcreteProxy { friend class ProxyBaseConcreteProxy; void PreOperation() { std::cout Pre\n; } void PostOperation() { std::cout Post\n; } void RealOperation() { std::cout Real\n; } };现代C建议优先使用标准库提供的工具如智能指针、function等实现代理模式而非手动实现。这能减少错误并提高代码可维护性。8. 代理模式在真实项目中的应用案例8.1 图形系统中的应用在图形渲染引擎中代理模式被广泛用于纹理代理延迟加载大纹理模型代理处理复杂模型的LOD(Level of Detail)渲染命令代理批处理渲染命令class Texture { public: virtual void Bind() 0; virtual ~Texture() default; }; class RealTexture : public Texture { GLuint texture_id_; std::string file_path_; public: explicit RealTexture(const std::string path) : file_path_(path) { // 实际加载纹理数据 std::cout Loading texture from path \n; texture_id_ /* OpenGL纹理创建 */; } void Bind() override { glBindTexture(GL_TEXTURE_2D, texture_id_); } }; class TextureProxy : public Texture { std::unique_ptrRealTexture real_texture_; std::string file_path_; public: explicit TextureProxy(std::string path) : file_path_(std::move(path)) {} void Bind() override { if (!real_texture_) { real_texture_ std::make_uniqueRealTexture(file_path_); } real_texture_-Bind(); } };8.2 网络通信中的应用在网络库中代理模式常用于连接代理管理物理连接池协议代理处理不同协议转换加密代理透明地处理数据加密class NetworkConnection { public: virtual void Send(const std::vectoruint8_t data) 0; virtual std::vectoruint8_t Receive() 0; virtual ~NetworkConnection() default; }; class SSLConnectionProxy : public NetworkConnection { std::unique_ptrNetworkConnection underlying_; public: explicit SSLConnectionProxy(std::unique_ptrNetworkConnection conn) : underlying_(std::move(conn)) {} void Send(const std::vectoruint8_t data) override { auto encrypted Encrypt(data); underlying_-Send(encrypted); } std::vectoruint8_t Receive() override { auto data underlying_-Receive(); return Decrypt(data); } private: std::vectoruint8_t Encrypt(const std::vectoruint8_t data) { // 实现加密逻辑 return data; } std::vectoruint8_t Decrypt(const std::vectoruint8_t data) { // 实现解密逻辑 return data; } };8.3 游戏开发中的应用在游戏开发中代理模式被用于AI代理控制NPC行为物理代理简化碰撞检测存档代理管理游戏状态保存class GameEntity { public: virtual void Update(float delta) 0; virtual ~GameEntity() default; }; class RemotePlayerProxy : public GameEntity { NetworkClient network_; PlayerState cached_state_; public: void Update(float delta) override { // 从服务器获取最新状态 cached_state_ network_.GetPlayerState(); // 根据缓存状态更新本地表现 // ... } };架构经验在大型系统中代理模式常与其他模式结合使用如代理工厂创建不同类型的代理代理装饰器在代理基础上添加功能代理观察者实现状态变更通知9. 代理模式的性能考量与优化9.1 代理模式的开销分析代理模式虽然提供了很多好处但也会引入一定的性能开销间接调用开销通过代理调用真实对象需要额外的虚函数调用或间接寻址内存开销代理对象本身需要占用内存同步开销线程安全的代理需要锁或其他同步机制9.2 代理模式的优化策略针对不同的性能瓶颈可以采用以下优化策略内联小型代理templatetypename Subject class InlineProxy : public Subject { Subject real_subject_; public: void Operation() final { // 前置处理 real_subject_.Operation(); // 可能被内联 // 后置处理 } };使用模板减少运行时开销批量处理操作无锁设计class LockFreeCacheProxy { std::atomicCacheImpl* cache_{nullptr}; public: int Compute(int x) { CacheImpl* current cache_.load(std::memory_order_acquire); if (current current-Has(x)) { return current-Get(x); } int result RealCompute(x); CacheImpl* new_cache UpdateCache(x, result); cache_.store(new_cache, std::memory_order_release); return result; } };性能测试建议在实现代理模式时应该测量基础性能指标实现代理后再次测量比较两者的差异只有当收益大于开销时才使用代理模式10. 代理模式的测试与调试技巧10.1 代理模式的单元测试测试代理模式时需要特别关注代理是否正确转发调用前置和后置处理是否正确执行特殊情况下代理的行为TEST(ProxyTest, VirtualProxyLazyLoading) { ImageProxy proxy(test.jpg); // 此时真实对象不应被加载 EXPECT_EQ(GetResourceCount(), 0); proxy.Display(); // 应该触发加载 EXPECT_EQ(GetResourceCount(), 1); } TEST(ProxyTest, ProtectionProxyAccessControl) { User low_priv(guest, 1); DatabaseProxy proxy(low_priv); EXPECT_THROW(proxy.Query(DELETE * FROM users), AccessDeniedError); }10.2 代理模式的调试技巧调试代理模式时的一些实用技巧在代理中添加详细的日志记录实现代理的状态检查方法使用装饰器模式临时添加调试功能class DebugProxy : public Subject { Subject* real_; public: void Operation() override { std::cout [DEBUG] Entering Operation\n; auto start std::chrono::high_resolution_clock::now(); real_-Operation(); auto end std::chrono::high_resolution_clock::now(); std::cout [DEBUG] Operation took std::chrono::duration_caststd::chrono::microseconds(end - start).count() μs\n; } };测试金字塔建议对于代理模式的测试应该覆盖单元测试测试单个代理的功能集成测试测试代理与其他组件的交互性能测试确保代理不会成为系统瓶颈11. 代理模式的反模式与常见误用11.1 代理模式的常见反模式过度代理创建不必要的代理层导致系统复杂化循环代理代理之间相互引用导致死锁或栈溢出功能膨胀在代理中添加过多与核心功能无关的逻辑11.2 代理模式的正确使用准则单一职责每个代理应该只负责一种控制逻辑透明性客户端不应感知代理的存在理想情况下适度使用只在确实需要控制访问时使用代理模式设计警示当发现代理类变得过于复杂时考虑是否应该将部分功能移到真实主题中是否应该拆分成多个专门的代理是否应该使用其他模式替代代理模式12. 代理模式与其他模式的关系12.1 代理模式与装饰器模式虽然实现相似但两者有本质区别特性代理模式装饰器模式目的控制访问添加功能对象创建通常由代理管理通常由客户端管理关注点访问机制增强行为生命周期可能控制真实对象生命周期不控制被装饰对象生命周期12.2 代理模式与适配器模式适配器模式关注接口转换而代理模式关注访问控制// 适配器接口转换 class LegacySystem { public: void OldMethod() {} }; class Adapter : public NewInterface { LegacySystem legacy_; public: void NewMethod() override { legacy_.OldMethod(); } }; // 代理访问控制 class Proxy : public Interface { RealSubject real_; public: void Method() override { // 访问控制逻辑 real_.Method(); } };12.3 代理模式与外观模式外观模式简化接口代理模式控制访问特性代理模式外观模式对象数量一对一一对多目的控制对单个对象的访问提供简化接口复杂性可能增加复杂性通常减少复杂性13. C20/23中的新特性对代理模式的影响13.1 概念(Concepts)与代理模式C20的概念可以用于约束代理的模板参数templatetypename T concept Subject requires(T t) { { t.Request() } - std::same_asvoid; }; templateSubject S class ConceptProxy { S subject_; public: void Request() { // 前置处理 subject_.Request(); // 后置处理 } };13.2 协程(Coroutines)与异步代理C20协程可以实现异步代理AsyncTaskint AsyncProxy::Compute(int x) { // 可以在等待时执行其他操作 co_await std::suspend_always{}; // 异步执行实际计算 auto result co_await real_subject_.AsyncCompute(x); // 后处理 co_return result 1; }13.3 模块(Modules)与代理模式模块可以更好地封装代理的实现细节// Proxy.ixx export module Proxy; export { class Proxy { // 实现... }; }未来展望随着C标准的发展代理模式的实现将变得更加简洁和安全特别是在模板代理和异步代理方面。14. 代理模式的最佳实践总结经过多年的C开发实践我总结了以下代理模式的最佳实践明确代理目的在创建代理前明确是要控制访问、延迟加载、缓存还是其他目的保持代理精简代理应该只包含与访问控制相关的逻辑业务逻辑应放在真实主题中考虑线程安全多线程环境下使用的代理需要仔细设计同步策略测量性能影响始终测量代理引入的性能开销确保收益大于成本文档化代理行为明确记录代理的特殊行为和约束条件对于C特定的建议优先使用智能指针管理代理持有的资源考虑使用模板实现通用代理利用RAII管理代理中的资源对于性能关键的代理考虑constexpr和编译期计算最后需要强调的是虽然代理模式功能强大但不应过度使用。只有当确实需要控制对对象的访问时才应该引入代理层。在简单的场景中直接使用对象通常更清晰高效。

相关新闻

Java IO体系深度解析:BIO、NIO与AIO对比与实践

Java IO体系深度解析:BIO、NIO与AIO对比与实践

1. Java IO体系全景解析Java IO体系是每个Java开发者必须掌握的核心基础,也是面试中高频出现的"硬骨头"。我见过太多候选人能说出BIO/NIO/AIO这几个缩写,却讲不清底层机制和适用场景。今天我们就从操作系统层面开始,彻底拆解这套体…

2026/10/15 14:03:58 阅读更多 →
2025最新Java面试题精讲:从Tomcat到Shiro的原理链路串讲

2025最新Java面试题精讲:从Tomcat到Shiro的原理链路串讲

简介:面向Java后端开发者与2025年求职者,整理的高频面试题文档,围绕Java核心高频考点系统梳理了Tomcat运行原理、Spring IOC/DI与AOP、JVM运行机制、包装类与基本数据类型区别、Shiro权限标签、Servlet生命周期以及Java作用域七个主题展开&am…

2026/10/15 14:03:58 阅读更多 →
前端社招面试复盘:从基础原理到性能优化与工程化实战

前端社招面试复盘:从基础原理到性能优化与工程化实战

前阵子刚面完一个前端工程师的社招岗位,趁着记忆还热乎,把整场面试里涉及的知识点、我的回答思路、答得不好的地方,以及事后复盘下来的改进方案,全部梳理了一遍。这篇文章我先把公司信息隐掉,只保留岗位本身和考核内容…

2026/10/15 14:03:58 阅读更多 →

最新新闻

深圳松岗燃气灶维修|华帝燃气灶检修|面板积水接口漏气故障检查|欧米到家服务电话

深圳松岗燃气灶维修|华帝燃气灶检修|面板积水接口漏气故障检查|欧米到家服务电话

导读:厨房燃气灶天天用,遇到打不着火、黄火、松手就灭、闻到燃气味,先别慌着换。下面把深圳报修最高频的问题按"自己能查 → 师傅上门"的顺序拆开讲,帮你一眼定位问题、避开低价引流和小病大治。 📞 24小时…

2026/10/15 14:38:50 阅读更多 →
FPGA实现ABS防抱死控制器:从ModelSim仿真到板级验证完整流程

FPGA实现ABS防抱死控制器:从ModelSim仿真到板级验证完整流程

简介:面向大二数字电子技术实验课,这份资源以FPGA实现ABS(绝对值)加法器为核心项目,支持对有符号输入进行取绝对值运算,适合正在完成Vivado仿真与硬件验证作业的学生参考,也适用于初次接触Xilin…

2026/10/15 14:38:50 阅读更多 →
微服务容器化实战:Docker镜像构建与K8s部署关键实践

微服务容器化实战:Docker镜像构建与K8s部署关键实践

1. 为什么微服务架构师必须亲手敲开Docker这扇门我带过不少刚从单体应用转型过来的Java开发者,他们能熟练写Spring Boot、画UML图、调优JVM参数,但一提到“容器化部署”,眼神里常闪过一丝犹豫——不是不会,而是没真正把镜像build出…

2026/10/15 14:38:50 阅读更多 →
SQLite FTS5 context-mode语境高亮原理与实战

SQLite FTS5 context-mode语境高亮原理与实战

1. “context-mode”不是功能开关,而是SQLite FTS5全文检索的底层执行范式你第一次在SQLite文档里看到“context-mode”这个词,大概率是在FTS5的MATCH查询语法说明里——它不像ORDER BY或LIMIT那样直白,也不像CREATE VIRTUAL TABLE那样显眼。…

2026/10/15 14:38:50 阅读更多 →
数字电路实验:4位补码绝对值电路设计与FPGA实现

数字电路实验:4位补码绝对值电路设计与FPGA实现

简介:面向大二数字电子技术实验的完整绝对值加法器工程包,配套Vivado仿真与FPGA实现全流程,围绕ABS加法器设计,涵盖符号位判断、取反加一等核心逻辑。包体共79个文件、约435KB,以rst报告、rpt时序报告、pb配置、xdc约束…

2026/10/15 14:38:50 阅读更多 →
Kubernetes Service五种类型原理与实战避坑指南

Kubernetes Service五种类型原理与实战避坑指南

1. 这不是“配个YAML就完事”的服务暴露课——Kubernetes Service到底在解决什么问题?你有没有遇到过这样的场景:刚把一个Web应用的Pod部署到集群里,curl一下Pod IP能通,但一换到Service ClusterIP就503?或者明明写了N…

2026/10/15 14:37:48 阅读更多 →

日新闻

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

1. 为什么选择容器化方式部署 LoRa 网络服务LoRa 物联网项目落地时,网络服务器是整个链路的核心枢纽。它负责接收网关上报的数据包、完成去重与解密、再把有效载荷分发给上层应用。早期大家习惯把网络服务器直接装在物理机上,依赖一堆系统库和特定版本的…

2026/10/15 0:00:46 阅读更多 →
共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

1. 共享推理服务里,扩缩容到底难在哪做过大模型推理服务部署的人,大概都经历过这样的场景:一个团队共用一套推理集群,A 业务跑的是 7B 的小模型,B 业务跑的是 72B 的大模型,C 业务白天流量高、晚上几乎归零…

2026/10/15 0:00:46 阅读更多 →
Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

1. 引子:一次内核恐慌引发的追查先从一个真实场景说起。某次我给一台老旧的嵌入式设备折腾系统裁减,为了把启动时间压进两秒以内,我手贱地把一串自认为“没用”的 systemd 服务给 disable 了,其中就包括systemd-remount-fs.servic…

2026/10/15 0:00:46 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/14 3:30:28 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/14 16:30:29 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/15 13:48:15 阅读更多 →

月新闻

我发现了一个新思路:用 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/15 0:14:36 阅读更多 →
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/14 22:45:47 阅读更多 →
黑夜航拍船只数据集训练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/15 9:49:14 阅读更多 →