当前位置: 首页 > news >正文

如何让一个类作为可调用对象被thread调用?

如何让一个类作为可调用对象,被 std::thread 调用

在 C++ 中,可以让一个类对象作为可调用对象(Callable Object),然后用 std::thread 进行调用。要实现这一点,主要有三种方法:

  1. 重载 operator()(仿函数)
  2. 使用成员函数
  3. 使用 std::bindstd::function

1. 方法一:重载 operator()(仿函数)

最常见的方式是定义一个仿函数(functor),即重载 operator() 使类的实例可直接调用。

示例

#include <iostream>
#include <thread>class CallableObject {
public:void operator()() {  // 让对象像函数一样调用std::cout << "Thread running with CallableObject\n";}
};int main() {CallableObject obj;std::thread t(obj);  // 直接将对象传给 std::threadt.join();return 0;
}

解析

  • CallableObject 重载了 operator(),因此它的实例 obj 可以像函数一样被调用。
  • std::thread 可以直接接受 obj 作为参数,调用 operator()
  • 线程执行 obj.operator()(),输出:
    Thread running with CallableObject
    

2. 方法二:使用类的成员函数

可以直接用类的成员函数作为 std::thread 的目标,但要注意非静态成员函数需要绑定对象

示例

#include <iostream>
#include <thread>class Worker {
public:void run() {  // 成员函数std::cout << "Thread running with member function\n";}
};int main() {Worker worker;std::thread t(&Worker::run, &worker);  // 传递成员函数指针和对象t.join();return 0;
}

解析

  • &Worker::runWorker成员函数指针
  • &worker 传入对象指针,std::thread 需要对象来调用成员函数
  • 线程执行 worker.run(),输出:
    Thread running with member function
    

3. 方法三:使用 std::bind 绑定成员函数

如果 std::thread 需要额外的参数,可以用 std::bindstd::function 绑定成员函数和对象。

示例

#include <iostream>
#include <thread>
#include <functional>class Worker {
public:void run(int x) {std::cout << "Thread running with parameter: " << x << "\n";}
};int main() {Worker worker;std::thread t(std::bind(&Worker::run, &worker, 42));  // 绑定成员函数和参数t.join();return 0;
}

解析

  • std::bind(&Worker::run, &worker, 42) 绑定 worker.run(42)
  • std::thread 线程启动后会执行 worker.run(42)
  • 输出:
    Thread running with parameter: 42
    

4. 方法四:使用 std::function 结合 Lambda

另一种方式是用 std::function 存储可调用对象(比如 Lambda 或仿函数),然后传给 std::thread

示例

#include <iostream>
#include <thread>
#include <functional>class Worker {
public:void run(int x) {std::cout << "Thread running with parameter: " << x << "\n";}
};int main() {Worker worker;std::function<void()> func = std::bind(&Worker::run, &worker, 42);std::thread t(func);t.join();return 0;
}

解析

  • std::function<void()> 存储 worker.run(42)
  • std::thread 线程执行 func()
  • 输出:
    Thread running with parameter: 42
    

5. 选择哪种方式?

方法特点适用场景
仿函数(operator())直接使用对象,无需额外绑定线程对象无需额外参数
成员函数需要对象指针才能调用适用于普通类成员函数
std::bind 绑定成员函数允许传递额外参数需要动态传递参数时
std::function结合 std::bind,适用于通用接口适用于异步任务调度

对于简单任务,建议使用 重载 operator()。对于需要参数的任务,建议使用 std::bindstd::function


6. 组合使用:多个线程调用类对象

可以创建多个线程,并让它们执行类中的函数:

#include <iostream>
#include <thread>
#include <vector>class Worker {
public:void run(int id) {std::cout << "Thread " << id << " is running\n";}
};int main() {Worker worker;std::vector<std::thread> threads;for (int i = 0; i < 5; ++i) {threads.emplace_back(&Worker::run, &worker, i);}for (auto& t : threads) {t.join();}return 0;
}

输出

Thread 0 is running
Thread 1 is running
Thread 2 is running
Thread 3 is running
Thread 4 is running

总结

  • 让类成为可调用对象的常见方式:
    1. 仿函数(重载 operator()
    2. 成员函数(使用 &Class::method, &object 绑定)
    3. 使用 std::bind() 绑定成员函数
    4. 使用 std::function 存储可调用对象
  • 推荐用法
    • 简单的可调用对象仿函数
    • 普通成员函数std::thread t(&Class::method, &object)
    • 需要传参的成员函数std::bindstd::function
    • 多个线程调用同一个对象std::vector<std::thread>

多个线程调用同一个对象 ➝ std::vector<std::thread>

在 C++ 多线程编程中,我们经常希望多个线程同时调用同一个对象的成员函数。这通常用于:

  • 并行计算(多个线程操作同一个数据对象)
  • 任务调度(多个线程调用同一个处理对象)
  • 服务器/多客户端模型(多个线程访问同一个服务器对象)

使用 std::vector<std::thread> 可以创建多个线程,并让它们调用同一个对象的成员函数


1. 示例:多个线程调用同一个对象的成员函数

#include <iostream>
#include <thread>
#include <vector>class Worker {
public:void doWork(int id) {std::cout << "Thread " << id << " is working\n";}
};int main() {Worker worker;  // 所有线程共享这个对象std::vector<std::thread> threads;for (int i = 0; i < 5; ++i) {threads.emplace_back(&Worker::doWork, &worker, i);}for (auto& t : threads) {t.join();}return 0;
}

可能的输出(线程执行顺序可能不同):

Thread 0 is working
Thread 1 is working
Thread 2 is working
Thread 3 is working
Thread 4 is working

2. 代码解析

  1. 创建 Worker 对象

    Worker worker;
    
    • 这里 worker所有线程共享的对象
  2. 使用 std::vector<std::thread> 管理多个线程

    std::vector<std::thread> threads;
    
    • std::vector<std::thread> 存储多个 std::thread 对象,避免单独管理多个线程对象。
  3. 创建多个线程并调用 worker.doWork(i)

    for (int i = 0; i < 5; ++i) {threads.emplace_back(&Worker::doWork, &worker, i);
    }
    
    • &Worker::doWork:获取 Worker 类的成员函数指针。
    • &worker:传入对象指针,确保 doWorkworker 对象上调用。
    • i:传入线程的 ID,作为参数。
  4. 等待所有线程完成

    for (auto& t : threads) {t.join();
    }
    
    • 遍历 threads,对每个线程调用 join(),确保主线程等待所有子线程完成。

3. 线程安全问题

如果 Worker 类的 doWork 方法修改了成员变量,可能会发生数据竞争(Race Condition)。

示例:线程不安全

#include <iostream>
#include <thread>
#include <vector>class Worker {
private:int counter = 0;  // 共享变量public:void doWork(int id) {++counter;  // 线程不安全std::cout << "Thread " << id << " incremented counter to " << counter << "\n";}
};int main() {Worker worker;std::vector<std::thread> threads;for (int i = 0; i < 5; ++i) {threads.emplace_back(&Worker::doWork, &worker, i);}for (auto& t : threads) {t.join();}return 0;
}

可能的错误输出

Thread 0 incremented counter to 1
Thread 1 incremented counter to 2
Thread 2 incremented counter to 3
Thread 3 incremented counter to 2  // ❌ 竞争导致错误
Thread 4 incremented counter to 5

问题:

  • 多个线程同时修改 counter,导致数据竞争(Race Condition)。
  • 线程 3 可能在 counter = 2 之前读取旧值,导致计数错误。

4. 解决方案:使用 std::mutex 保护数据

使用 std::mutex 保护 counter,防止数据竞争。

#include <iostream>
#include <thread>
#include <vector>
#include <mutex>class Worker {
private:int counter = 0;std::mutex mtx;  // 互斥锁public:void doWork(int id) {std::lock_guard<std::mutex> lock(mtx);  // 加锁++counter;std::cout << "Thread " << id << " incremented counter to " << counter << "\n";}
};int main() {Worker worker;std::vector<std::thread> threads;for (int i = 0; i < 5; ++i) {threads.emplace_back(&Worker::doWork, &worker, i);}for (auto& t : threads) {t.join();}return 0;
}

输出

Thread 0 incremented counter to 1
Thread 1 incremented counter to 2
Thread 2 incremented counter to 3
Thread 3 incremented counter to 4
Thread 4 incremented counter to 5

修改点

  • 使用 std::mutex 互斥锁,防止多个线程同时访问 counter
  • std::lock_guard<std::mutex> 自动管理锁,避免手动 lock() / unlock()

5. 结论

  • 多个线程可以调用同一个对象的成员函数,可以使用 std::vector<std::thread> 统一管理线程。
  • 如果成员函数只读,不修改成员变量,线程是安全的。
  • 如果成员函数修改成员变量,必须使用 std::mutex 保护数据,防止数据竞争(Race Condition)。
  • std::vector<std::thread> 让多个线程的管理更加方便,避免单独管理多个 std::thread 变量。

这种模式在多线程服务器、任务分发、并行计算等场景非常常见。

相关文章:

如何让一个类作为可调用对象被thread调用?

如何让一个类作为可调用对象&#xff0c;被 std::thread 调用 在 C 中&#xff0c;可以让一个类对象作为可调用对象&#xff08;Callable Object&#xff09;&#xff0c;然后用 std::thread 进行调用。要实现这一点&#xff0c;主要有三种方法&#xff1a; 重载 operator()&…...

OpenWrt 串口终端常用命令---拓展篇

以下进一步拓展 OpenWrt 串口终端常用命令,新增更多高级操作与场景化工具,助你深入掌握系统管理与调试技巧: 一、系统信息与状态查询(扩展) 硬件详细探测 cat /proc/mtd # 查看 Flash 分区表(MTD 设备) mtd info # 显示 MTD 分…...

线上接口tp99突然升高如何排查?

当线上接口的 TP99 突然升高时&#xff0c;意味着该接口在 99% 的情况下响应时间变长&#xff0c;这可能会严重影响系统的性能和用户体验。可以按照下面的步骤进行排查。这里我们先说明一下如何计算tp99&#xff1a;监控系统计算 TP99&#xff08;第 99 百分位数的响应时间&…...

如何借助人工智能AI模型开发一个类似OpenAI Operator的智能体实现电脑自动化操作?

这几天关于Manus的新闻铺天盖地&#xff0c;于是研究了一下AI智能体的实现思路&#xff0c;发现Openai 的OpenAI Operator智能体已经实现了很强的功能&#xff0c;但是每月200美金的价格高不可攀&#xff0c;而Manus的邀请码据说炒到了几万块&#xff01;就想能不能求助人工智能…...

langchain系列(终)- LangGraph 多智能体详解

目录 一、导读 二、概念原理 1、智能体 2、多智能体 3、智能体弊端 4、多智能体优点 5、多智能体架构 6、交接&#xff08;Handoffs&#xff09; 7、架构说明 &#xff08;1&#xff09;网络 &#xff08;2&#xff09;监督者 &#xff08;3&#xff09;监督者&…...

springboot旅游管理系统设计与实现(代码+数据库+LW)

摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本旅游管理系统就是在这样的大环境下诞生&#xff0c;其可以帮助使用者在短时间内处理完毕庞大的数据信息&a…...

【前端跨域】WebSocket如何实现跨域通信?原理、实践与安全指南

在实时通信场景&#xff08;如在线聊天、实时数据推送&#xff09;中&#xff0c;WebSocket因其高效的双向通信能力成为首选技术 然而&#xff0c;当客户端与服务器部署在不同源时&#xff0c;跨域问题同样可能阻碍WebSocket的连接 一、WebSocket与跨域的关系 WebSocket的跨…...

Go红队开发—格式导出

文章目录 输出功能CSV输出CSV 转 结构体结构体 转 CSV端口扫描结果使用CSV格式导出 HTML输出Sqlite输出nmap扫描 JSONmap转json结构体转jsonjson写入文件json编解码json转结构体json转mapjson转string练习&#xff1a;nmap扫描结果导出json格式 输出功能 在我们使用安全工具的…...

Sharp 存在任意文件读取漏洞( DVB-2025-8923)

免责声明 本文所描述的漏洞及其复现步骤仅供网络安全研究与教育目的使用。任何人不得将本文提供的信息用于非法目的或未经授权的系统测试。作者不对任何由于使用本文信息而导致的直接或间接损害承担责任。如涉及侵权,请及时与我们联系,我们将尽快处理并删除相关内容。 0x01…...

C++数组,链表,二叉树的内存排列是什么样的,结构体占多大内存如何计算,类占多大内存如何计算,空类的空间是多少,为什么?

C数组是连续存储的&#xff0c;C数组元素依次存放在相邻的内存地址之中&#xff0c;并且内存大小相同。 C链表是离散存储的&#xff0c;C链表是由节点构成的&#xff0c;每个节点之中存在节点的值以及指向下一个节点的指针&#xff0c;每个节点是动态分配的。 C二叉树也是离散…...

【vLLM 教程】使用 TPU 安装

vLLM 是一款专为大语言模型推理加速而设计的框架&#xff0c;实现了 KV 缓存内存几乎零浪费&#xff0c;解决了内存管理瓶颈问题。 更多 vLLM 中文文档及教程可访问 →https://vllm.hyper.ai/ vLLM 使用 PyTorch XLA 支持 Google Cloud TPU。 依赖环境​ Google Cloud TPU …...

【RAG】基于向量检索的 RAG (BGE示例)

RAG机器人 结构体 文本向量化: 使用 BGE 模型将文档和查询编码为向量。 &#xff08;BGE 是专为检索任务优化的开源 Embedding 模型&#xff0c;除了本文API调用&#xff0c;也可以通过Hugging Face 本地部署BGE 开源模型&#xff09; 向量检索: 从数据库中找到与查询相关的文…...

【RAG】RAG 系统的基本搭建流程(ES关键词检索示例)

RAG 系统的基本搭建流程 搭建过程&#xff1a; 文档加载&#xff0c;并按一定条件切割成片段将切割的文本片段灌入检索引擎封装检索接口构建调用流程&#xff1a;Query -> 检索 -> Prompt -> LLM -> 回复 1. 文档的加载与切割 # !pip install --upgrade openai…...

PSIM积累经验

1、三极管的部署报错。 出错信息&#xff1a; 元件&#xff1a; R 名称&#xff1a; R2 Error: The RLC branch R2 is connected to the gate node of the switch Q1. The gate node should be connected to an On-Off Controller output. Refer to the switch Help p…...

C++之vector类(超详解)

这节我们来学习一下&#xff0c;C中一个重要的工具——STL&#xff0c;这是C中自带的一个标准库&#xff0c;我们可以直接调用这个库中的函数或者容器&#xff0c;可以使效率大大提升。这节我们介绍STL中的vector。 文章目录 前言 一、标准库类型vector 二、vector的使用 2.…...

Go学习笔记

<!-- 注意* --> 初始化工程 go mod init GoDemo 结构体&#xff0c;接口 type i struct{} type i interface{} 条件&#xff0c;选择 循环 键值对 make(map[string]int) 切片&#xff0c;集合 make([]int,10) 函数 通道 Channel make(chan int) ​ ch <- v…...

前端杂的学习笔记

什么是nginx Nginx (engine x) 是一个高性能的HTTP和反向代理web服务器 Nginx是一款轻量级的Web 服务器/反向代理服务器&#xff0c;处理高并发能力是十分强大的&#xff0c;并且支持热部署&#xff0c;启动简单&#xff0c;可以做到7*24不间断运行 正代和反代 学习nginx&a…...

痉挛性斜颈护理:全方位呵护,重燃生活希望

痉挛性斜颈是一种以颈部肌肉不自主收缩导致头部向一侧扭转或倾斜为特征的疾病。对于痉挛性斜颈患者而言&#xff0c;科学有效的护理能够显著提升其生活质量&#xff0c;辅助病情的改善。 生活护理&#xff1a;在生活环境布置上&#xff0c;要充分考虑患者行动的便利性。确保室内…...

MySQL的安装以及数据库的基本配置

MySQL的安装及配置 MySQL的下载 选择想要安装的版本&#xff0c;点击Download下载 Mysql官网下载地址&#xff1a;​ ​https://downloads.mysql.com/archives/installer/​​ MySQL的安装 选择是自定义安装&#xff0c;所以直接选择“Custom”&#xff0c;点击“Next”​ …...

WangEditor快速实现版

WangEditor快速实现版 效果 案例代码 后端 package com.diy.springboot.controller;import cn.hutool.core.util.IdUtil; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiImplicitParam; import org.sp…...

LeetCode Hot100刷题——反转链表(迭代+递归)

206.反转链表 给你单链表的头节点 head &#xff0c;请你反转链表&#xff0c;并返回反转后的链表。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4,5] 输出&#xff1a;[5,4,3,2,1]示例 2&#xff1a; 输入&#xff1a;head [1,2] 输出&#xff1a;[2,1]示例 3&#…...

10.2 继承与多态

文章目录 继承多态 继承 继承的作用是代码复用。派生类自动获得基类的除私有成员外的一切。基类描述一般特性&#xff0c;派生类提供更丰富的属性和行为。在构造派生类时&#xff0c;其基类构造函数先被调用&#xff0c;然后是派生类构造函数。在析构时顺序刚好相反。 // 基类…...

java项目之基于ssm的智能训练管理平台(源码+文档)

项目简介 智能训练管理平台实现了以下功能&#xff1a; 系统可以提供信息显示和相应服务&#xff0c;其管理员增删改查课程信息和课程信息资料&#xff0c;审核课程信息预订订单&#xff0c;查看订单评价和评分&#xff0c;通过留言功能回复用户提问。 &#x1f495;&#x1…...

29-验证回文串

如果在将所有大写字符转换为小写字符、并移除所有非字母数字字符之后&#xff0c;短语正着读和反着读都一样。则可以认为该短语是一个 回文串 。 字母和数字都属于字母数字字符。 给你一个字符串 s&#xff0c;如果它是 回文串 &#xff0c;返回 true &#xff1b;否则&#xf…...

(57)[HGAME 2023 week1]easyasm

nss&#xff1a;3477 [HGAME 2023 week1]easyasm 关于这个题吧&#xff0c;我还是和上一个题一样&#xff0c;我观察到了异或0x33 所以我就把result的结果跟0x33异或&#xff0c;然后我就就这样&#xff0c;做出来了...

FY-3D MWRI亮温绘制

1、FY-3D MWRI介绍 风云三号气象卫星&#xff08;FY-3&#xff09;是我国自行研制的第二代极轨气象卫星&#xff0c;其有效载荷覆 盖了紫外、可见光、红外、微波等频段&#xff0c;其目标是实现全球全天候、多光谱、三维定量 探测&#xff0c;为中期数值天气预报提供卫星观测数…...

Java集合面试题

引言 Java集合框架是Java编程中不可或缺的一部分&#xff0c;它提供了一系列用于存储和操作对象的接口和类。在Java面试中&#xff0c;集合框架的相关知识往往是必考的内容。本文将汇总一系列关于Java集合的面试题&#xff0c;帮助求职者更好地准备面试。 一、Java集合框架概…...

知识蒸馏综述Knowledge Distillation: A Survey解读

论文链接&#xff1a;Knowledge Distillation: A Survey 摘要&#xff1a;近年来&#xff0c;深度神经网络在工业界和学术界都取得了成功&#xff0c;尤其是在计算机视觉任务方面。深度学习的巨大成功主要归功于它能够扩展以对大规模数据进行编码&#xff0c;并且能够处理数十…...

ES映射知识

映射 映射类似于关系型数据库的Schema&#xff08;模式&#xff09;。 映射来定义字段列和存储的类型等基础信息。 {"mappings": {"properties": {"username": {"type": "keyword","ignore_above": 256 // 忽略…...

Spring Boot拦截器(Interceptor)与过滤器(Filter)深度解析:区别、实现与实战指南

Spring Boot拦截器&#xff08;Interceptor&#xff09;与过滤器&#xff08;Filter&#xff09;深度解析&#xff1a;区别、实现与实战指南 一、核心概念对比 1. 本质区别 维度过滤器&#xff08;Filter&#xff09;拦截器&#xff08;Interceptor&#xff09;规范层级Serv…...

Debian二次开发一体化工作站:提升科研效率的智能工具

在科研领域&#xff0c;数据处理是实验成功的关键环节之一。随着实验数据的复杂性和规模不断增加&#xff0c;传统的数据处理方法已经难以满足科研人员的需求。这时&#xff0c;一体化工作站应运而生&#xff0c;成为科研实验数据处理的 “智能大脑”。 一体化工作站&#xff…...

swift-5-汇编分析闭包本质

一、枚举、结构体、类都定义方法 方法占用对象的内存么&#xff1f; 不占用 方法的本质就是函数 方法、函数都存放在代码段&#xff0c;因为方法都是公共的&#xff0c;不管 对象一还是对对象二调用都是一样的&#xff0c;所以放在代码段&#xff0c;但是每个对象的成员不一样所…...

Linux安装升级docker

Linux 安装升级docker Linux 安装升级docker背景升级停止docker服务备份原docker数据目录移除旧版本docker安装docker ce恢复数据目录启动docker参考 安装找到docker官网找到docker文档删除旧版本docker配置docker yum源参考官网继续安装docker设置开机自启配置加速测试 Linux …...

小程序事件系统 —— 33 事件传参 - data-*自定义数据

事件传参&#xff1a;在触发事件时&#xff0c;将一些数据作为参数传递给事件处理函数的过程&#xff0c;就是事件传参&#xff1b; 在微信小程序中&#xff0c;我们经常会在组件上添加一些自定义数据&#xff0c;然后在事件处理函数中获取这些自定义数据&#xff0c;从而完成…...

推荐一些免费开源支持Vue3甘特图组件

文章目录 前言一、dhtmlxGantt二、frappe-gantt三、vue-ganttastic四、gantt-elastic五、v-gantt六、vue-gantt-schedule-timeline-calendar七、vue-gantt八、总结 前言 在现代项目管理和任务调度中&#xff0c;甘特图是一种非常实用的工具。它能够直观地展示任务的时间安排、…...

Dify 本地部署教程

目录 一、下载安装包 二、修改配置 三、启动容器 四、访问 Dify 五、总结 本篇文章主要记录 Dify 本地部署过程&#xff0c;有问题欢迎交流~ 一、下载安装包 从 Github 仓库下载最新稳定版软件包&#xff0c;点击下载~&#xff0c;当然也可以克隆仓库或者从仓库里直接下…...

nlp培训重点-5

1. LoRA微调 loader&#xff1a; # -*- coding: utf-8 -*-import json import re import os import torch import numpy as np from torch.utils.data import Dataset, DataLoader from transformers import BertTokenizer """ 数据加载 """cl…...

XWiki使用war部署在tomcat9

xwiki部署 官方文档&#xff0c;比较详细。 https://www.xwiki.org/xwiki/bin/view/Documentation/AdminGuide/Installation/InstallationWAR/ xwiki是基于java的开源知识库&#xff0c;可以替代Confluence。有多种部署方式&#xff0c;本文使用war方式部署在tomca下&#x…...

CTA策略【量化理论】

CTA策略演变史 全称&#xff1a;Commodity Trading Advisor &#xff08;商品交易顾问&#xff09; CTA最开始是指通过为客户提供期权、期货方面的交易建议&#xff0c;或者直接通过受管理的期货账户参与实际交易&#xff0c;来获得收益的机构或个人。 随着市场的发展&#…...

旋转编码器原理与应用详解:从结构到实战 | 零基础入门STM32第四十七步

主题内容教学目的/扩展视频旋转编码器电路原理&#xff0c;跳线设置&#xff0c;结构分析。驱动程序与调用。熟悉电路和驱动程序。 师从洋桃电子&#xff0c;杜洋老师 &#x1f4d1;文章目录 一、旋转编码器是什么&#xff1f;二、内部结构揭秘2.1 机械组件解剖2.2 核心部件说明…...

计算机视觉cv2入门之图像的读取,显示,与保存

在计算机视觉领域&#xff0c;Python的cv2库是一个不可或缺的工具&#xff0c;它提供了丰富的图像处理功能。作为OpenCV的Python接口&#xff0c;cv2使得图像处理的实现变得简单而高效。 示例图片 目录 opencv获取方式 图像基本知识 颜色空间 RGB HSV 图像格式 BMP格式 …...

基于Canvas和和原生JS实现俄罗斯方块小游戏

这里是一个完整的H5俄罗斯方块游戏&#xff0c;使用了 HTML CSS JavaScript (原生) 实现&#xff0c;支持基本的俄罗斯方块玩法&#xff0c;如&#xff1a; ✅ 方块自动下落 ✅ 方向键控制移动、旋转、加速下落 ✅ 方块堆叠、消行 ✅ 计分系统 在 canvas 上绘制游戏&#x…...

阿里云 QwQ-32B 模型调研文档

阿里云 QwQ-32B 模型调研文档 ——技术解析、部署实践与微调指南 一、模型概述 QwQ-32B 是阿里云开源的轻量化大语言模型,以 320 亿参数 实现与 DeepSeek-R1(6710 亿参数)相当的推理性能。其核心优势包括: 参数效率:1/20 参数量达成竞品性能,显存需求降低 70%部署灵活性…...

【玩转23种Java设计模式】结构型模式篇:组合模式

软件设计模式&#xff08;Design pattern&#xff09;&#xff0c;又称设计模式&#xff0c;是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性、程序的重用性。 汇总目录链接&…...

Eolink:专为开发者设计的API协作平台

Eolink Apikit 是一款集 API 设计、管理、自动化测试、Mock 和异常监控于一体的全生命周期智能协作平台&#xff0c;旨在提升 API 研发和管理的效率。以下是对其功能和特点的详细介绍&#xff1a; 核心功能&#xff1a; API 设计与文档管理&#xff1a;Apikit 提供了强大的 API…...

【Python】为什么要写__init__.py

文章目录 PackageA(__init__特性)应该往__init__.py里放什么东西&#xff1f;1、包的初始化2、管理包的公共接口3、包的信息 正常我们直接导入就可以执行&#xff0c;但是在package的时候&#xff0c;有一种__init__.py的特殊存在 引入moduleA.py&#xff0c;执行main.py&…...

golang 从零单排 (一) 安装环境

1.下载安装 打开网址The Go Programming Language 直接点击下载go1.24.1.windows-amd64.msi 下载完成 直接双击下一步 下一步 安装完成 环境变量自动设置不必配置 2.验证 win r 输入cmd 打开命令行 输入go version...

30-判断子序列

给定字符串 s 和 t &#xff0c;判断 s 是否为 t 的子序列。 字符串的一个子序列是原始字符串删除一些&#xff08;也可以不删除&#xff09;字符而不改变剩余字符相对位置形成的新字符串。&#xff08;例如&#xff0c;"ace"是"abcde"的一个子序列&#…...

AI 驱动的软件测试革命:从自动化到智能化的进阶之路

&#x1f680;引言&#xff1a;软件测试的智能化转型浪潮 在数字化转型加速的今天&#xff0c;软件产品的迭代速度与复杂度呈指数级增长。传统软件测试依赖人工编写用例、执行测试的模式&#xff0c;已难以应对快速交付与高质量要求的双重挑战。人工智能技术的突破为测试领域注…...

深度相机进行目标物体的空间姿态(位姿)估计

利用深度相机&#xff08;如Kinect、Intel Realsense、Zed相机等&#xff09;进行目标物体的空间姿态&#xff08;位姿&#xff09;估计&#xff0c;通常结合了3D点云处理、目标识别和位姿优化算法。以下是完整的实现流程、算法选择及注意事项&#xff1a; 一、实现流程 1. 目…...