C++设计模式(14)——享元模式
亦称: 缓存、Cache、Flyweight
意图
享元模式是一种结构型设计模式, 它摒弃了在每个对象中保存所有数据的方式, 通过共享多个对象所共有的相同状态, 让你能在有限的内存容量中载入更多对象。
问题
假如你希望在长时间工作后放松一下, 所以开发了一款简单的游戏: 玩家们在地图上移动并相互射击。 你决定实现一个真实的粒子系统, 并将其作为游戏的特色。 大量的子弹、 导弹和爆炸弹片会在整个地图上穿行, 为玩家提供紧张刺激的游戏体验。
开发完成后, 你推送提交了最新版本的程序, 并在编译游戏后将其发送给了一个朋友进行测试。 尽管该游戏在你的电脑上完美运行, 但是你的朋友却无法长时间进行游戏: 游戏总是会在他的电脑上运行几分钟后崩溃。 在研究了几个小时的调试消息记录后, 你发现导致游戏崩溃的原因是内存容量不足。 朋友的设备性能远比不上你的电脑, 因此游戏运行在他的电脑上时很快就会出现问题。
真正的问题与粒子系统有关。 每个粒子 (一颗子弹、 一枚导弹或一块弹片) 都由包含完整数据的独立对象来表示。 当玩家在游戏中鏖战进入高潮后的某一时刻, 游戏将无法在剩余内存中载入新建粒子, 于是程序就崩溃了。
解决方案
仔细观察 粒子Particle类, 你可能会注意到颜色 (color) 和精灵图 (sprite)这两个成员变量所消耗的内存要比其他变量多得多。 更糟糕的是, 对于所有的粒子来说, 这两个成员变量所存储的数据几乎完全一样 (比如所有子弹的颜色和精灵图都一样)。
每个粒子的另一些状态 (坐标、 移动矢量和速度) 则是不同的。 因为这些成员变量的数值会不断变化。 这些数据代表粒子在存续期间不断变化的情景, 但每个粒子的颜色和精灵图则会保持不变。
对象的常量数据通常被称为内在状态, 其位于对象中, 其他对象只能读取但不能修改其数值。 而对象的其他状态常常能被其他对象 “从外部” 改变, 因此被称为外在状态。
享元模式建议不在对象中存储外在状态, 而是将其传递给依赖于它的一个特殊方法。 程序只在对象中保存内在状态, 以方便在不同情景下重用。 这些对象的区别仅在于其内在状态 (与外在状态相比, 内在状态的变体要少很多), 因此你所需的对象数量会大大削减。
让我们回到游戏中。 假如能从粒子类中抽出外在状态, 那么我们只需三个不同的对象 (子弹、 导弹和弹片) 就能表示游戏中的所有粒子。 你现在很可能已经猜到了, 我们将这样一个仅存储内在状态的对象称为享元。
外在状态存储
那么外在状态会被移动到什么地方呢? 总得有类来存储它们, 对不对? 在大部分情况中, 它们会被移动到容器对象中, 也就是我们应用享元模式前的聚合对象中。
在我们的例子中, 容器对象就是主要的 游戏Game对象, 其会将所有粒子存储在名为 粒子particles的成员变量中。 为了能将外在状态移动到这个类中, 你需要创建多个数组成员变量来存储每个粒子的坐标、 方向矢量和速度。 除此之外, 你还需要另一个数组来存储指向代表粒子的特定享元的引用。 这些数组必须保持同步, 这样你才能够使用同一索引来获取关于某个粒子的所有数据。
更优雅的解决方案是创建独立的情景类来存储外在状态和对享元对象的引用。 在该方法中, 容器类只需包含一个数组。
稍等! 这样的话情景对象数量不是会和不采用该模式时的对象数量一样多吗? 的确如此, 但这些对象要比之前小很多。 消耗内存最多的成员变量已经被移动到很少的几个享元对象中了。 现在, 一个享元大对象会被上千个情境小对象复用, 因此无需再重复存储数千个大对象的数据。
享元与不可变性
由于享元对象可在不同的情景中使用, 你必须确保其状态不能被修改。 享元类的状态只能由构造函数的参数进行一次性初始化, 它不能对其他对象公开其设置器或公有成员变量。
享元工厂
为了能更方便地访问各种享元, 你可以创建一个工厂方法来管理已有享元对象的缓存池。 工厂方法从客户端处接收目标享元对象的内在状态作为参数, 如果它能在缓存池中找到所需享元, 则将其返回给客户端; 如果没有找到, 它就会新建一个享元, 并将其添加到缓存池中。
你可以选择在程序的不同地方放入该函数。 最简单的选择就是将其放置在享元容器中。 除此之外, 你还可以新建一个工厂类, 或者创建一个静态的工厂方法并将其放入实际的享元类中。
享元模式结构
1、享元模式只是一种优化。 在应用该模式之前, 你要确定程序中存在与大量类似对象同时占用内存相关的内存消耗问题, 并且确保该问题无法使用其他更好的方式来解决。
2、享元 (Flyweight) 类包含原始对象中部分能在多个对象中共享的状态。 同一享元对象可在许多不同情景中使用。 享元中存储的状态被称为 “内在状态”。 传递给享元方法的状态被称为 “外在状态”。
3、情景 (Context) 类包含原始对象中各不相同的外在状态。 情景与享元对象组合在一起就能表示原始对象的全部状态。
4、通常情况下, 原始对象的行为会保留在享元类中。 因此调用享元方法必须提供部分外在状态作为参数。 但你也可将行为移动到情景类中, 然后将连入的享元作为单纯的数据对象。
5、客户端 (Client) 负责计算或存储享元的外在状态。 在客户端看来, 享元是一种可在运行时进行配置的模板对象, 具体的配置方式为向其方法中传入一些情景数据参数。
6、享元工厂 (Flyweight Factory) 会对已有享元的缓存池进行管理。 有了工厂后, 客户端就无需直接创建享元, 它们只需调用工厂并向其传递目标享元的一些内在状态即可。 工厂会根据参数在之前已创建的享元中进行查找, 如果找到满足条件的享元就将其返回; 如果没有找到就根据参数新建享元。
伪代码
在本例中, 享元模式能有效减少在画布上渲染数百万个树状对象时所需的内存。
该模式从主要的 树Tree类中抽取内在状态, 并将其移动到享元类 树种类TreeType之中。
最初程序需要在多个对象中存储相同数据, 而现在仅需在几个享元对象中保存数据, 然后在作为情景的 树对象中连入享元即可。 客户端代码使用享元工厂创建树对象并封装搜索指定对象的复杂行为, 并能在需要时复用对象。
// 享元类包含一个树的部分状态。这些成员变量保存的数值对于特定树而言是唯一
// 的。例如,你在这里找不到树的坐标。但这里有很多树木之间所共有的纹理和颜
// 色。由于这些数据的体积通常非常大,所以如果让每棵树都其进行保存的话将耗
// 费大量内存。因此,我们可将纹理、颜色和其他重复数据导出到一个单独的对象
// 中,然后让众多的单个树对象去引用它。
class TreeType isfield namefield colorfield textureconstructor TreeType(name, color, texture) { …… }method draw(canvas, x, y) is// 1. 创建特定类型、颜色和纹理的位图。// 2. 在画布坐标 (X,Y) 处绘制位图。// 享元工厂决定是否复用已有享元或者创建一个新的对象。
class TreeFactory isstatic field treeTypes: collection of tree typesstatic method getTreeType(name, color, texture) istype = treeTypes.find(name, color, texture)if (type == null)type = new TreeType(name, color, texture)treeTypes.add(type)return type// 情景对象包含树状态的外在部分。程序中可以创建数十亿个此类对象,因为它们
// 体积很小:仅有两个整型坐标和一个引用成员变量。
class Tree isfield x,yfield type: TreeTypeconstructor Tree(x, y, type) { …… }method draw(canvas) istype.draw(canvas, this.x, this.y)// 树(Tree)和森林(Forest)类是享元的客户端。如果不打算继续对树类进行开
// 发,你可以将它们合并。
class Forest isfield trees: collection of Treesmethod plantTree(x, y, name, color, texture) istype = TreeFactory.getTreeType(name, color, texture)tree = new Tree(x, y, type)trees.add(tree)method draw(canvas) isforeach (tree in trees) dotree.draw(canvas)
享元模式适合应用场景
仅在程序必须支持大量对象且没有足够的内存容量时使用享元模式。
应用该模式所获的收益大小取决于使用它的方式和情景。 它在下列情况中最有效:
程序需要生成数量巨大的相似对象
这将耗尽目标设备的所有内存
对象中包含可抽取且能在多个对象间共享的重复状态。
实现方式
1、将需要改写为享元的类成员变量拆分为两个部分:
内在状态: 包含不变的、 可在许多对象中重复使用的数据的成员变量。
外在状态: 包含每个对象各自不同的情景数据的成员变量
2、保留类中表示内在状态的成员变量, 并将其属性设置为不可修改。 这些变量仅可在构造函数中获得初始数值。
3、找到所有使用外在状态成员变量的方法, 为在方法中所用的每个成员变量新建一个参数, 并使用该参数代替成员变量。
4、你可以有选择地创建工厂类来管理享元缓存池, 它负责在新建享元时检查已有的享元。 如果选择使用工厂, 客户端就只能通过工厂来请求享元, 它们需要将享元的内在状态作为参数传递给工厂。
5、客户端必须存储和计算外在状态 (情景) 的数值, 因为只有这样才能调用享元对象的方法。 为了使用方便, 外在状态和引用享元的成员变量可以移动到单独的情景类中。
享元模式优缺点
与其他模式的关系
你可以使用享元模式实现组合模式树的共享叶节点以节省内存。
享元展示了如何生成大量的小型对象, 外观模式则展示了如何用一个对象来代表整个子系统。
如果你能将对象的所有共享状态简化为一个享元对象, 那么享元就和单例模式类似了。 但这两个模式有两个根本性的不同。
1、只会有一个单例实体, 但是享元类可以有多个实体, 各实体的内在状态也可以不同。
2、单例对象可以是可变的。 享元对象是不可变的。
C++ 享元模式讲解和代码示例
享元是一种结构型设计模式, 它允许你在消耗少量内存的情况下支持大量对象。
模式通过共享多个对象的部分状态来实现上述功能。 换句话来说, 享元会将不同对象的相同数据进行缓存以节省内存。
使用示例: 享元模式只有一个目的: 将内存消耗最小化。 如果你的程序没有遇到内存容量不足的问题, 则可以暂时忽略该模式。
识别方法: 享元可以通过构建方法来识别, 它会返回缓存对象而不是创建新的对象。
概念示例
本例说明了享元设计模式的结构并重点回答了下面的问题:
它由哪些类组成?
这些类扮演了哪些角色?
模式中的各个元素会以何种方式相互关联?
main.cc: 概念示例
/*** Flyweight Design Pattern** Intent: Lets you fit more objects into the available amount of RAM by sharing* common parts of state between multiple objects, instead of keeping all of the* data in each object.*/struct SharedState
{std::string brand_;std::string model_;std::string color_;SharedState(const std::string &brand, const std::string &model, const std::string &color): brand_(brand), model_(model), color_(color){}friend std::ostream &operator<<(std::ostream &os, const SharedState &ss){return os << "[ " << ss.brand_ << " , " << ss.model_ << " , " << ss.color_ << " ]";}
};struct UniqueState
{std::string owner_;std::string plates_;UniqueState(const std::string &owner, const std::string &plates): owner_(owner), plates_(plates){}friend std::ostream &operator<<(std::ostream &os, const UniqueState &us){return os << "[ " << us.owner_ << " , " << us.plates_ << " ]";}
};/*** The Flyweight stores a common portion of the state (also called intrinsic* state) that belongs to multiple real business entities. The Flyweight accepts* the rest of the state (extrinsic state, unique for each entity) via its* method parameters.*/
class Flyweight
{
private:SharedState *shared_state_;public:Flyweight(const SharedState *shared_state) : shared_state_(new SharedState(*shared_state)){}Flyweight(const Flyweight &other) : shared_state_(new SharedState(*other.shared_state_)){}~Flyweight(){delete shared_state_;}SharedState *shared_state() const{return shared_state_;}void Operation(const UniqueState &unique_state) const{std::cout << "Flyweight: Displaying shared (" << *shared_state_ << ") and unique (" << unique_state << ") state.\n";}
};
/*** The Flyweight Factory creates and manages the Flyweight objects. It ensures* that flyweights are shared correctly. When the client requests a flyweight,* the factory either returns an existing instance or creates a new one, if it* doesn't exist yet.*/
class FlyweightFactory
{/*** @var Flyweight[]*/
private:std::unordered_map<std::string, Flyweight> flyweights_;/*** Returns a Flyweight's string hash for a given state.*/std::string GetKey(const SharedState &ss) const{return ss.brand_ + "_" + ss.model_ + "_" + ss.color_;}public:FlyweightFactory(std::initializer_list<SharedState> share_states){for (const SharedState &ss : share_states){this->flyweights_.insert(std::make_pair<std::string, Flyweight>(this->GetKey(ss), Flyweight(&ss)));}}/*** Returns an existing Flyweight with a given state or creates a new one.*/Flyweight GetFlyweight(const SharedState &shared_state){std::string key = this->GetKey(shared_state);if (this->flyweights_.find(key) == this->flyweights_.end()){std::cout << "FlyweightFactory: Can't find a flyweight, creating new one.\n";this->flyweights_.insert(std::make_pair(key, Flyweight(&shared_state)));}else{std::cout << "FlyweightFactory: Reusing existing flyweight.\n";}return this->flyweights_.at(key);}void ListFlyweights() const{size_t count = this->flyweights_.size();std::cout << "\nFlyweightFactory: I have " << count << " flyweights:\n";for (std::pair<std::string, Flyweight> pair : this->flyweights_){std::cout << pair.first << "\n";}}
};// ...
void AddCarToPoliceDatabase(FlyweightFactory &ff, const std::string &plates, const std::string &owner,const std::string &brand, const std::string &model, const std::string &color)
{std::cout << "\nClient: Adding a car to database.\n";const Flyweight &flyweight = ff.GetFlyweight({brand, model, color});// The client code either stores or calculates extrinsic state and passes it// to the flyweight's methods.flyweight.Operation({owner, plates});
}/*** The client code usually creates a bunch of pre-populated flyweights in the* initialization stage of the application.*/int main()
{FlyweightFactory *factory = new FlyweightFactory({{"Chevrolet", "Camaro2018", "pink"}, {"Mercedes Benz", "C300", "black"}, {"Mercedes Benz", "C500", "red"}, {"BMW", "M5", "red"}, {"BMW", "X6", "white"}});factory->ListFlyweights();AddCarToPoliceDatabase(*factory,"CL234IR","James Doe","BMW","M5","red");AddCarToPoliceDatabase(*factory,"CL234IR","James Doe","BMW","X1","red");factory->ListFlyweights();delete factory;return 0;
}
Output.txt: 执行结果
FlyweightFactory: I have 5 flyweights:
BMW_X6_white
Mercedes Benz_C500_red
Mercedes Benz_C300_black
BMW_M5_red
Chevrolet_Camaro2018_pinkClient: Adding a car to database.
FlyweightFactory: Reusing existing flyweight.
Flyweight: Displaying shared ([ BMW , M5 , red ]) and unique ([ CL234IR , James Doe ]) state.Client: Adding a car to database.
FlyweightFactory: Can't find a flyweight, creating new one.
Flyweight: Displaying shared ([ BMW , X1 , red ]) and unique ([ CL234IR , James Doe ]) state.FlyweightFactory: I have 6 flyweights:
BMW_X1_red
Mercedes Benz_C300_black
BMW_X6_white
Mercedes Benz_C500_red
BMW_M5_red
Chevrolet_Camaro2018_pink
来源:https://refactoringguru.cn/design-patterns/flyweight
仅供学习,非商业用途,侵删
相关文章:
C++设计模式(14)——享元模式
亦称: 缓存、Cache、Flyweight 意图 享元模式是一种结构型设计模式, 它摒弃了在每个对象中保存所有数据的方式, 通过共享多个对象所共有的相同状态, 让你能在有限的内存容量中载入更多对象。 问题 假如你希望在长时间工作后放…...
SpringCloud之Eureka客户端服务启动报Cannot execute request on any known server解决
项目场景: 在练习SpringCloud时,Eureka客户端(client)出现报错:Cannot execute request on any known server 问题描述 正常启动SpringCloud的Server端和Client端,结果发现Server端的控制台有个Error提示,如下&#…...
从零开始搭建kubernetes集群环境(虚拟机/kubeadm方式)
文章目录1 Kubernetes简介(k8s)2 安装实战2.1 主机安装并初始化2.2 安装docker2.3 安装Kubernetes组件2.4 准备集群镜像2.5 集群初始化2.6 安装flannel网络插件3 部署nginx 测试3.1 创建一个nginx服务3.2 暴漏端口3.3 查看服务3.4 测试服务1 Kubernetes简…...
【零基础入门前端系列】—表格(五)
【零基础入门前端系列】—表格(五) 一、表格 表格在数据展示方面非常简单,并且表现优秀,通过与CSS的结合,可以让数据变得更加美观和整齐。 单元格的特点:同行等高、同列等宽。 表格的基本语法࿱…...
C#开发的OpenRA的只读字典IReadOnlyDictionary实现
C#开发的OpenRA的只读字典IReadOnlyDictionary实现 怎么样实现一个只读字典? 这是一个高级的实现方式,一般情况下,开发人员不会考虑这个问题的。 毕竟代码里,只要小心地使用,还是不会出问题的。 但是如果在一个大型的代码,或者要求比较严格的代码里,就需要考虑这个问题了…...
mulesoft MCIA 破釜沉舟备考 2023.02.14.06
mulesoft MCIA 破釜沉舟备考 2023.02.14.06 1. A company is planning to extend its Mule APIs to the Europe region.2. A mule application is deployed to a Single Cloudhub worker and the public URL appears in Runtime Manager as the APP URL.3. An API implementati…...
Python网络爬虫 学习笔记(1)requests库爬虫
文章目录Requests库网络爬虫requests.get()的基本使用框架requests.get()的带异常处理使用框架(重点)requests库的其他方法和HTTP协议(非重点)requests.get()的可选参数网络爬虫引发的问题(非重点)常见问题…...
Splay
前言 Splay是一种维护平衡二叉树的算法。虽然它常数大,而且比较难打,但Splay十分方便,而且LCT需要用到。 约定 cnticnt_icnti:节点iii的个数 valival_ivali:节点iii的权值 sizisiz_isizi:节点iii的子…...
智能网联汽车ASIL安全等级如何划分
目录一、功能安全标准二、功能安全等级定义三、危险事件的确定四、ASIL安全等级五、危险分析和风险评定六、功能安全目标的分解一、功能安全标准 ISO 26262《道路车辆功能安全》脱胎于IEC 61508《电气/电子/可编程电子安全系统的功能安全》,主要定位在汽车行业&…...
Stable Diffusion 1 - 初始跑通 文字生成图片
文章目录关于 Stable DiffusionLexica代码实现安装依赖库登陆 huggingface查看 huggingface token下载模型计算生成设置宽高测试迭代次数生成多列图片关于 Stable Diffusion A latent text-to-image diffusion model Stable Diffusion 是一个文本到图像的潜在扩散模型ÿ…...
【cuda入门系列】通过代码真实打印线程ID
【cuda入门系列】通过代码真实打印线程ID1.gridDim(6,1),blockDim(4,1)2.gridDim(3,2),blockDim(2,2)【cuda入门系列之参加CUDA线上训练营】在Jetson nano本地跑 hello cuda! 【cuda入门系列之参加CUDA线上训练营】一文认识cuda基本概念 【cuda入门系列之参加CUDA线…...
【Python语言基础】——Python NumPy 数据类型
Python语言基础——Python NumPy 数据类型 文章目录 Python语言基础——Python NumPy 数据类型一、Python NumPy 数据类型一、Python NumPy 数据类型 Python 中的数据类型 默认情况下,Python 拥有以下数据类型: strings - 用于表示文本数据,文本用引号引起来。例如 “ABCD”…...
数据工程师需要具备哪些技能?
成为数据工程师需要具备哪些技能?数据工程工作存在于各个行业,在银行业、医疗保健业、大型科技企业、初创企业和其他行业找到工作机会。许多职位描述要求数据工程师、拥有数学或工程学位,但如果有合适的经验学位往往没那么重要。 大数据开发…...
Cosmos 基础 -- Ignite CLI(二)Module basics: Blog
一、快速入门 Ignite CLI version: v0.26.1 在本教程中,我们将使用一个模块创建一个区块链,该模块允许我们从区块链中写入和读取数据。这个模块将实现创建和阅读博客文章的功能,类似于博客应用程序。最终用户将能够提交新的博客文章&#x…...
Quartz 快速入门案例,看这一篇就够了
前言 Quartz 是基于 Java 实现的任务调度框架,对任务的创建、修改、删除、触发以及监控这些操作直接提供了 api,这意味着开发人员拥有最大的操作权,也带来了更高的灵活性。 什么是任务调度? 任务调度指在将来某个特定的时间、固…...
图解LeetCode——1233. 删除子文件夹(难道:中等)
一、题目 你是一位系统管理员,手里有一份文件夹列表 folder,你的任务是要删除该列表中的所有 子文件夹,并以 任意顺序 返回剩下的文件夹。 如果文件夹 folder[i] 位于另一个文件夹 folder[j] 下,那么 folder[i] 就是 folder[j] …...
Doris--简单使用
一、数据表的创建与数据导入 1.1、创建表 1.1.1、单分区 CREATE TABLE table1 (siteid INT DEFAULT 10,citycode SMALLINT,username VARCHAR(32) DEFAULT ,pv BIGINT SUM DEFAULT 0 -- 聚合模型, value column 使用sum聚合 ) AGGREGATE KEY(siteid, citycode, …...
使用GPT让你的RStudio如虎添翼
API的的调用目前来说不限制地区,但是OpenAI的API的申请限制了地区。运行的时候,如果出现了429,意味着你被限流了,需要等一会才行。 前提是,你需要注册一个OpenAI的账户,然后在https://openai.com/api/ 里申…...
Python 算法交易实验45 再探量化
说明 去年大部分精力都在构建底层架构和工具了,一直都没有时间搞量化。目前底层的数据库服务(ADB)和清洗(衍生 AETL) 工具已经好了,我想尽快的把量化启动起来。 内容 1 思想 作为交易来说,只有买卖。通过数据分析与模型,我们获得的增强点是决策。在合适的时候进行买卖的…...
Dubbo加载配置文件方式,加载流程,加载配置文件源码解析
配置方法 API配置 以Java编码的方式组织配置,Dubbo3配置API详解 :https://dubbo.apache.org/zh/docs3-v2/java-sdk/reference-manual/config/api/#bootstrap-api public static void main(String[] args) throws IOException {ServiceConfig<Greet…...
十大开源测试工具和框架,一定有你需要的
目录 前言 Katalon Studio Selenium Appium JMeter SOAP UI Robot Framework Watir JUnit Robotium Citrus 总结 前言 免费的开源框架和工具由于其开源特性,现在逐渐成为自动化测试的首选解决方案。区别在于,你是喜欢使用类库编写一个全新的…...
加密技术在android中的应用
1、算法基础 算法基础参照linux的全盘加密与文件系统加密在android中的应用 消息摘要算法 对称加密算法 非对称加密算法...
备战蓝桥杯【一维前缀和】
🌹作者:云小逸 📝个人主页:云小逸的主页 📝Github:云小逸的Github 🤟motto:要敢于一个人默默的面对自己,强大自己才是核心。不要等到什么都没有了,才下定决心去做。种一颗树,最好的时间是十年前…...
研报精选230214
目录 【行业230214艾瑞股份】中国增强现实(AR)行业研究报告【行业230214国信证券】信息安全深度剖析5:密评和信创双催化,密码产业开启从1到N【行业230214民生证券】磁性元器件深度报告:乘新能源之风,磁性元…...
【SSL/TLS】准备工作:证书格式
证书格式1. 格式说明1.1 文件编码格式1.2 文件后缀格式2. xca导出格式1. 格式说明 1.1 文件编码格式 1. PEM格式: 使用Base 64 ASCII进行编码的纯文本格式。后缀为“.pem”, ".cer", ".crt", ".key" 2. DER格式 二进制编码格式,文件…...
Linux常用命令---系统常用命令
Linux系统常用命令场景一: 查看当前系统内核版本相关信息场景二: sosreport 命令场景三: 如何定位并确定命令?场景四:查看当前系统运行负载怎场景五: 查看当前系统的内存可用情况场景六:查看网卡…...
C 结构体
C 数组允许定义可存储相同类型数据项的变量,结构是 C 编程中另一种用户自定义的可用的数据类型,它允许您存储不同类型的数据项。结构用于表示一条记录,假设您想要跟踪图书馆中书本的动态,您可能需要跟踪每本书的下列属性ÿ…...
手语检测识别
论文:Real-Time Sign Language Detection using Human Pose Estimation Github:https://github.com/google-research/google-research/tree/master/sign_language_detection SLRTP 2020 手语识别任务包括手语检测(Sign language detection&a…...
android fwk模块之Sensor架构
本文基于Android 12源码整理,包含如下内容: 通信架构应用层实现使用方式SensorManager抽象接口具体实现fwk层的实现native中的SensorManager的初始化流程native中的消息队列初始化与数据读取sensorservice实现HAL层的实现通信架构 应用层实现 涉及代码&…...
安装less-loader5出现webpack版本不兼容
今天遇到一个问题: 安装less-loader5之后其它包提示peerDependencies WARNING,意思是包版本不兼容。 【难题】 虽然NPM已经很自动化了,但依赖问题真的是一个难题,无法自动解决,需要人工干预调整。 【解决办法】 去查…...
怎么访问被禁止的网站/青岛seo网站建设公司
用于接收父组件传入的参数 简易版——数组的方式定义 props: [size, myMessage] 详细版——对象的方式定义 props: {// 限定参数的数据类型必须为字符串code: String, // 限定参数的类型为字符串型,或数值型 Numberparams2: [String, Number],name:{type:String…...
网站开发整合编辑器/天津百度搜索网站排名
主库:1、配置文件里面加入以下两行server-id1log-binMySQL-bin2、创建账户grant replication client,replication slave on *.* to rep从库ip identified by root;从库:1、配置文件加上以下几行server-id2relay-logrelay-binread-only 1replicate-ignore…...
朝阳网站搭建公司/设计公司企业网站
/* (程序头部注释开始) * 程序的版权和版本声明部分 * Copyright (c) 2011, 烟台大学计算机学院学生 * All rights reserved. * 文件名称:设计一个工资类(Salary)--完成各个功能 * 作 者: 雷恒鑫 * 完成日期: 2012年03 月13日 * 版 本 号&…...
企业网站制作规划/app下载注册推广平台
一,摘要 圣殿骑士首先向大家说声对不起,由于最近身体不适,同时也因为这些天一直在研究微软的云计算平台Windows Azure(公司项目需要),所以暂停了更新WPF 基础到企业应用系列索引,不过经过这几天…...
苏州建站公司兴田德润i网址多少/大数据培训班出来能就业吗
(声明:本系列所用的模式都来自GOF23中,本系列并不是讲23种经典设计模式,而是如何去使用这些模式) 前面我们设计了员工的工资,奖金,福利系统。今天客户又来增加需求了:"我们需要统计公司,部门,或者小…...
长春公司做网站/免费推广的平台
{"moduleinfo":{"card_count":[{"count_phone":1,"count":1}],"search_count":[{"count_phone":4,"count":4}]},"card":[{"des":"阿里技术人对外发布原创技术内容的最大平台&…...