【大数据离线开发】7.4 HBase数据保存和过滤器
7.4 数据保存的过程
注意:数据的存储,都需要注意Region的分裂
- HDFS:数据的平衡 ——> 数据的移动(拷贝)
- HBase:数据越来越多 ——> Region的分裂 ——> 数据的移动(拷贝)

业务越来越大,数据越来越大,必然会发生Region的分裂。
运维:可以通过增加节点,或者预分配的方式
7.5 HBase的过滤器
过滤器:相当于SQL语句中的where查询条件
使用下面java程序操作HBase,仅需要修改IP地址
package demo.filter;import java.util.ArrayList;
import java.util.List;import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.HColumnDescriptor;
import org.apache.hadoop.hbase.HTableDescriptor;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.HBaseAdmin;
import org.apache.hadoop.hbase.client.HTable;
import org.apache.hadoop.hbase.client.Put;
import org.apache.hadoop.hbase.util.Bytes;
import org.junit.Test;public class DataInit {@Testpublic void testCreateTable() throws Exception{//指定的配置信息: ZooKeeperConfiguration conf = new Configuration();conf.set("hbase.zookeeper.quorum", "192.168.157.111");//创建一个HBase客户端: HBaseAdminHBaseAdmin admin = new HBaseAdmin(conf);//创建一个表的描述符: 表名HTableDescriptor hd = new HTableDescriptor(TableName.valueOf("emp"));//创建列族描述符HColumnDescriptor hcd1 = new HColumnDescriptor("empinfo");//加入列族hd.addFamily(hcd1);//创建表admin.createTable(hd);//关闭客户端admin.close();}@Testpublic void testPutData() throws Exception{//指定的配置信息: ZooKeeperConfiguration conf = new Configuration();conf.set("hbase.zookeeper.quorum", "192.168.157.111");//客户端HTable table = new HTable(conf, "emp");//第一条数据Put put1 = new Put(Bytes.toBytes("7369"));put1.add(Bytes.toBytes("empinfo"), Bytes.toBytes("ename"), Bytes.toBytes("SMITH"));Put put2 = new Put(Bytes.toBytes("7369"));put2.add(Bytes.toBytes("empinfo"), Bytes.toBytes("sal"), Bytes.toBytes("800"));//第二条数据Put put3 = new Put(Bytes.toBytes("7499"));put3.add(Bytes.toBytes("empinfo"), Bytes.toBytes("ename"), Bytes.toBytes("ALLEN"));Put put4 = new Put(Bytes.toBytes("7499"));put4.add(Bytes.toBytes("empinfo"), Bytes.toBytes("sal"), Bytes.toBytes("1600")); //第三条数据Put put5 = new Put(Bytes.toBytes("7521"));put5.add(Bytes.toBytes("empinfo"), Bytes.toBytes("ename"), Bytes.toBytes("WARD"));Put put6 = new Put(Bytes.toBytes("7521"));put6.add(Bytes.toBytes("empinfo"), Bytes.toBytes("sal"), Bytes.toBytes("1250")); //第四条数据Put put7 = new Put(Bytes.toBytes("7566"));put7.add(Bytes.toBytes("empinfo"), Bytes.toBytes("ename"), Bytes.toBytes("JONES"));Put put8 = new Put(Bytes.toBytes("7566"));put8.add(Bytes.toBytes("empinfo"), Bytes.toBytes("sal"), Bytes.toBytes("2975")); //第五条数据Put put9 = new Put(Bytes.toBytes("7654"));put9.add(Bytes.toBytes("empinfo"), Bytes.toBytes("ename"), Bytes.toBytes("MARTIN"));Put put10 = new Put(Bytes.toBytes("7654"));put10.add(Bytes.toBytes("empinfo"), Bytes.toBytes("sal"), Bytes.toBytes("1250"));//第六条数据Put put11 = new Put(Bytes.toBytes("7698"));put11.add(Bytes.toBytes("empinfo"), Bytes.toBytes("ename"), Bytes.toBytes("BLAKE"));Put put12 = new Put(Bytes.toBytes("7698"));put12.add(Bytes.toBytes("empinfo"), Bytes.toBytes("sal"), Bytes.toBytes("2850"));//第七条数据Put put13 = new Put(Bytes.toBytes("7782"));put13.add(Bytes.toBytes("empinfo"), Bytes.toBytes("ename"), Bytes.toBytes("CLARK"));Put put14 = new Put(Bytes.toBytes("7782"));put14.add(Bytes.toBytes("empinfo"), Bytes.toBytes("sal"), Bytes.toBytes("2450"));//第八条数据Put put15 = new Put(Bytes.toBytes("7788"));put15.add(Bytes.toBytes("empinfo"), Bytes.toBytes("ename"), Bytes.toBytes("SCOTT"));Put put16 = new Put(Bytes.toBytes("7788"));put16.add(Bytes.toBytes("empinfo"), Bytes.toBytes("sal"), Bytes.toBytes("3000")); //第九条数据Put put17 = new Put(Bytes.toBytes("7839"));put17.add(Bytes.toBytes("empinfo"), Bytes.toBytes("ename"), Bytes.toBytes("KING"));Put put18 = new Put(Bytes.toBytes("7839"));put18.add(Bytes.toBytes("empinfo"), Bytes.toBytes("sal"), Bytes.toBytes("5000")); //第十条数据Put put19 = new Put(Bytes.toBytes("7844"));put19.add(Bytes.toBytes("empinfo"), Bytes.toBytes("ename"), Bytes.toBytes("TURNER"));Put put20 = new Put(Bytes.toBytes("7844"));put20.add(Bytes.toBytes("empinfo"), Bytes.toBytes("sal"), Bytes.toBytes("1500")); //第十一条数据Put put21 = new Put(Bytes.toBytes("7876"));put21.add(Bytes.toBytes("empinfo"), Bytes.toBytes("ename"), Bytes.toBytes("ADAMS"));Put put22 = new Put(Bytes.toBytes("7876"));put22.add(Bytes.toBytes("empinfo"), Bytes.toBytes("sal"), Bytes.toBytes("1100")); //第十二条数据Put put23 = new Put(Bytes.toBytes("7900"));put23.add(Bytes.toBytes("empinfo"), Bytes.toBytes("ename"), Bytes.toBytes("JAMES"));Put put24 = new Put(Bytes.toBytes("7900"));put24.add(Bytes.toBytes("empinfo"), Bytes.toBytes("sal"), Bytes.toBytes("950"));//第十三条数据Put put25 = new Put(Bytes.toBytes("7902"));put25.add(Bytes.toBytes("empinfo"), Bytes.toBytes("ename"), Bytes.toBytes("FORD"));Put put26 = new Put(Bytes.toBytes("7902"));put26.add(Bytes.toBytes("empinfo"), Bytes.toBytes("sal"), Bytes.toBytes("3000"));//第十四条数据Put put27 = new Put(Bytes.toBytes("7934"));put27.add(Bytes.toBytes("empinfo"), Bytes.toBytes("ename"), Bytes.toBytes("MILLER"));Put put28 = new Put(Bytes.toBytes("7934"));put28.add(Bytes.toBytes("empinfo"), Bytes.toBytes("sal"), Bytes.toBytes("1300"));//构造ListList<Put> list = new ArrayList<Put>();list.add(put1);list.add(put2);list.add(put3);list.add(put4);list.add(put5);list.add(put6);list.add(put7);list.add(put8);list.add(put9);list.add(put10);list.add(put11);list.add(put12);list.add(put13);list.add(put14);list.add(put15);list.add(put16);list.add(put17);list.add(put18);list.add(put19);list.add(put20);list.add(put21);list.add(put22);list.add(put23);list.add(put24);list.add(put25);list.add(put26);list.add(put27);list.add(put28); //插入数据table.put(list);table.close(); }
}

常见的过滤器
列值过滤器:select * from emp where sal = 3000;
列名前缀过滤器:查询员工的姓名 select ename form emp;
多个列名前缀过滤器:查询员工的姓名、薪水 select ename, sal from emp;
行键过滤器:通过Row可以查询,类似通过Get查询数据
组合几个过滤器查询数据:where 条件1 and(or)条件2
public class TestHBaseFilter {@Testpublic void testSingleColumnValueFilter() throws Exception{//列值过滤器: 查询薪水等于3000的员工// select * from emp where sal=3000//配置ZooKeeperConfiguration conf = new Configuration();conf.set("hbase.zookeeper.quorum", "192.168.157.111");//得到客户端HTable table = new HTable(conf,"emp");//定义一个过滤器SingleColumnValueFilter filter = new SingleColumnValueFilter(Bytes.toBytes("empinfo"), //列族Bytes.toBytes("sal"), //列名CompareOp.EQUAL, //比较运算符Bytes.toBytes("3000")); //值//定义一个扫描器Scan scan = new Scan();scan.setFilter(filter);//查询数据:结果中只有员工姓名ResultScanner rs = table.getScanner(scan);for(Result r:rs){String name = Bytes.toString(r.getValue(Bytes.toBytes("empinfo"), Bytes.toBytes("ename")));System.out.println(name);}table.close();}@Testpublic void testColumnPrefixFilter() throws Exception{//列名前缀过滤器 查询员工的姓名: select ename from emp;//配置ZooKeeperConfiguration conf = new Configuration();conf.set("hbase.zookeeper.quorum", "192.168.157.111");//得到客户端HTable table = new HTable(conf,"emp");//定义一个过滤器ColumnPrefixFilter filter = new ColumnPrefixFilter(Bytes.toBytes("ename"));//定义一个扫描器Scan scan = new Scan();scan.setFilter(filter);//查询数据:结果中只愿员工的姓名ResultScanner rs = table.getScanner(scan);for(Result r:rs){String name = Bytes.toString(r.getValue(Bytes.toBytes("empinfo"), Bytes.toBytes("ename")));//获取员工的薪水String sal = Bytes.toString(r.getValue(Bytes.toBytes("empinfo"), Bytes.toBytes("sal")));System.out.println(name+"\t"+sal);}table.close(); }@Testpublic void testMultipleColumnPrefixFilter() throws Exception{//多个列名前缀过滤器//查询员工信息:员工姓名 薪水//配置ZooKeeperConfiguration conf = new Configuration();conf.set("hbase.zookeeper.quorum", "192.168.157.11");//得到客户端HTable table = new HTable(conf,"emp");//二维数组byte[][] names = {Bytes.toBytes("ename"),Bytes.toBytes("sal")};//定义一个过滤器MultipleColumnPrefixFilter filter = new MultipleColumnPrefixFilter(names);//定义一个扫描器Scan scan = new Scan();scan.setFilter(filter);//查询数据ResultScanner rs = table.getScanner(scan);for(Result r:rs){String name = Bytes.toString(r.getValue(Bytes.toBytes("empinfo"), Bytes.toBytes("ename")));//获取员工的薪水String sal = Bytes.toString(r.getValue(Bytes.toBytes("empinfo"), Bytes.toBytes("sal")));System.out.println(name+"\t"+sal);}table.close(); }@Testpublic void testRowFilter() throws Exception{//查询员工号7839的信息//配置ZooKeeperConfiguration conf = new Configuration();conf.set("hbase.zookeeper.quorum", "192.168.157.11");//得到客户端HTable table = new HTable(conf,"emp");//定义一个行键过滤器RowFilter filter = new RowFilter(CompareOp.EQUAL, //比较运算符new RegexStringComparator("7839")); //使用正则表达式来代表值//定义一个扫描器Scan scan = new Scan();scan.setFilter(filter);//查询数据ResultScanner rs = table.getScanner(scan);for(Result r:rs){String name = Bytes.toString(r.getValue(Bytes.toBytes("empinfo"), Bytes.toBytes("ename")));//获取员工的薪水String sal = Bytes.toString(r.getValue(Bytes.toBytes("empinfo"), Bytes.toBytes("sal")));System.out.println(name+"\t"+sal);}table.close(); } @Testpublic void testFilter() throws Exception{/** 查询工资等于3000的员工姓名 select ename from emp where sal=3000;* 1、列值过滤器:工资等于3000* 2、列名前缀过滤器:姓名*///配置ZooKeeperConfiguration conf = new Configuration();conf.set("hbase.zookeeper.quorum", "192.168.157.11");//得到客户端HTable table = new HTable(conf,"emp");//第一个过滤器 列值过滤器:工资等于3000SingleColumnValueFilter filter1 = new SingleColumnValueFilter(Bytes.toBytes("empinfo"), //列族Bytes.toBytes("sal"), //列名CompareOp.EQUAL, //比较运算符Bytes.toBytes("3000")); //值//第二个过滤器:列名前缀 姓名ColumnPrefixFilter filter2 = new ColumnPrefixFilter(Bytes.toBytes("ename"));//创建一个FliterList//Operator.MUST_PASS_ALL 相当于 and//Operator.MUST_PASS_ONE 相当于 orFilterList list = new FilterList(Operator.MUST_PASS_ALL);list.addFilter(filter1);list.addFilter(filter2);//定义一个扫描器Scan scan = new Scan();scan.setFilter(list);//查询数据ResultScanner rs = table.getScanner(scan);for(Result r:rs){String name = Bytes.toString(r.getValue(Bytes.toBytes("empinfo"), Bytes.toBytes("ename")));//获取员工的薪水String sal = Bytes.toString(r.getValue(Bytes.toBytes("empinfo"), Bytes.toBytes("sal")));System.out.println(name+"\t"+sal);}table.close();}
}

7.6 HBase上的MapReduce
1、建立输入的表create 'word','content'put 'word','1','content:info','I love Beijing'put 'word','2','content:info','I love China'put 'word','3','content:info','Beijing is the capital of China'2、输出表:create 'stat','content'注意:export HADOOP_CLASSPATH=$HBASE_HOME/lib/*:$CLASSPATH
Mapper程序
//这时候处理的就是HBase表的一条数据
//没有k1和v1,<k1 v1>代表输入,因为输入的就是表中一条记录
public class WordCountMapper extends TableMapper<Text, IntWritable> {@Overrideprotected void map(ImmutableBytesWritable key, Result value,Context context)throws IOException, InterruptedException {/** key和value代表从表中输入的一条记录* key: 行键* value:数据*///获取数据: I love beijingString data = Bytes.toString(value.getValue(Bytes.toBytes("content"), Bytes.toBytes("info")));//分词String[] words = data.split(" ");for(String w:words){context.write(new Text(w), new IntWritable(1));}}
}
Reducer程序
// k3 v3 keyout代表输出的一条记录:指定行键
public class WordCountReducer extends TableReducer<Text, IntWritable, ImmutableBytesWritable> {@Overrideprotected void reduce(Text k3, Iterable<IntWritable> v3,Context context)throws IOException, InterruptedException {// 对v3求和int total = 0;for(IntWritable v:v3){total = total + v.get();}//输出:也是表中的一条记录//构造一个Put对象,把单词作为rowkey行键Put put = new Put(Bytes.toBytes(k3.toString()));put.add(Bytes.toBytes("content"), //列族Bytes.toBytes("result"), //列Bytes.toBytes(String.valueOf(total)));//输出context.write(new ImmutableBytesWritable(Bytes.toBytes(k3.toString())), //把这个单词作为key 就是输出的行键put); //表中的一条记录,得到的结果}}
main程序
public class WordCountMain {public static void main(String[] args) throws Exception {//获取ZK的地址//指定的配置信息: ZooKeeperConfiguration conf = new Configuration();conf.set("hbase.zookeeper.quorum", "192.168.157.111");//创建一个任务,指定程序的入口Job job = Job.getInstance(conf);job.setJarByClass(WordCountMain.class);//定义一个扫描器 只读取:content:info这个列的数据Scan scan = new Scan();//可以使用filter,还有一种方式来过滤数据scan.addColumn(Bytes.toBytes("content"), Bytes.toBytes("info"));//指定mapper,使用工具类设置MapperTableMapReduceUtil.initTableMapperJob(Bytes.toBytes("word"), //输入的表scan, //扫描器,只读取想要处理的数据WordCountMapper.class, Text.class, IntWritable.class, job);//指定Reducer,使用工具类设置ReducerTableMapReduceUtil.initTableReducerJob("stat", WordCountReducer.class, job);//执行任务job.waitForCompletion(true);}}
将编写的程序打包成jar包,上传到全分布或者伪分布环境下,启动环境运行,会有一个exception异常。
在Hadoop集群上会去访问HBase,需要HBase依赖

注意:export HADOOP_CLASSPATH=HBASEHOME/lib/∗:HBASE_HOME/lib/*:HBASEHOME/lib/∗:CLASSPATH


相关文章:
【大数据离线开发】7.4 HBase数据保存和过滤器
7.4 数据保存的过程 注意:数据的存储,都需要注意Region的分裂 HDFS:数据的平衡 ——> 数据的移动(拷贝)HBase:数据越来越多 ——> Region的分裂 ——> 数据的移动(拷贝) …...
CentOS7安装MariaDB步骤
文章目录1.配置MariaDB yum源2.安装MariaDBMariaDB数据库管理系统是MySQL的一个分支,主要由开源社区在维护,采用GPL授权许可。 MariaDB的目的是完全兼容MySQL,包括API和命令行,使之能轻松成为MySQL的代替品。 CentOS 6 或早期的版…...
软件测试13个最容易犯的错误
目录 一、 输入框测试 二、 搜索功能测试 三、 添加/修改功能 四、 删除功能 五、 上传图片功能测试 六、 查询结果列表 七、 返回键检查 八、 回车键检查 九、 刷新键检查 十、 直接URL链接检查(盗链问题) 十一、并发问题 十二、 业务流程测…...
华为OD机试真题Java实现【5键键盘的输出】真题+解题思路+代码(20222023)
🔥系列专栏 华为OD机试(Python)真题目录汇总华为OD机试(JAVA)真题目录汇总华为OD机试(C++)真题目录汇总华为OD机试(JavaScript)真题目录汇总文章目录 🔥系列专栏题目输入输出描述:示例1:示例2:解题思路代码实现运行结果:版权说明:题目...
化解射频和微波设计挑战的六个技巧
即使是最自信的设计人员,对于射频电路也往往望而却步,因为它会带来巨大的设计挑战,并且需要专业的设计和分析工具。这里将为您介绍六条技巧,来帮助您简化任何射频PCB 设计任务和减轻工作压力! 1、保持完好、精确的射频…...
linux内核—进程调度(核心)
目录 核心函数__schedule() 处理过程 1、选择下一个进程 2、切换线程 1)切换进程的虚拟地址空间 2)切换寄存器 3)执行清理工作 核心函数__schedule() 主要的调度程序 进入次函数的主要方法是: 1、显示阻塞:互…...
【STM32笔记】__WFI();进入不了休眠的可能原因(系统定时器SysTick一直产生中断)
【STM32笔记】__WFI();进入不了休眠的可能原因(系统定时器SysTick一直产生中断) 【STM32笔记】低功耗模式配置及避坑汇总 前文: blog.csdn.net/weixin_53403301/article/details/128216064 【STM32笔记】HAL库低功耗模式配置&am…...
【期末复习】例题讲解Dijkstra算法
使用场景Dijkstra算法用于解决单源点最短路径问题,即给一个顶点作为源点,依次求它到图中其他n-1个顶点的最短距离。例题讲解Dijkstra算法将图中所有顶点分成两部分,第一部分是已知到源点最短距离的顶点Known(K),第二部分是不知道到…...
Pytorch 基础之张量索引
本次将介绍一下 Tensor 张量常用的索引与切片的方法: 1. index 索引 index 索引值表示相应维度值的对应索引 a torch.rand(4, 3, 28, 28) print(a[0].shape) # 返回维度一的第 0 索引 tensor print(a[0, 0].shape) # 返回维度一 0 索引位置…...
JVM系统优化实践(1):JVM概览
您好,我是湘王,这是我的CSDN博客,欢迎您来,欢迎您再来~这是多年之前做过的学习笔记,今天再翻出来,觉得仍然是记忆犹新。「独乐乐不如众乐乐」,就拿出来分享给「众乐乐」吧。目前大多…...
优秀!19年后,它再次成为TIOBE年度编程语言
新年伊始,TIOBE发布了2022年度编程语言,C时隔19年再度登顶,成为2022年最受欢迎的编程语言。TIOBE在2003年首次统计编程语言的流行指数时,C便成为年度编程语言。2022年,C获得了最高的人气4.62%,紧随其后的是…...
剑指 Offer 26. 树的子结构
摘要 剑指 Offer 26. 树的子结构 输入两棵二叉树A和B,判断B是不是A的子结构。(约定空树不是任意一个树的子结构),B是A的子结构, 即 A中有出现和B相同的结构和节点值。 一、子树解析 思路解析:若树B是树A的子结构,则…...
他是00年的,我们卷不过他...
现在的小年轻真的卷得过分了。前段时间我们公司来了个00年的,工作没两年,跳槽到我们公司起薪18K,都快接近我了。后来才知道人家是个卷王,从早干到晚就差搬张床到工位睡觉了。 最近和他聊了一次天,原来这位小老弟家里条…...
C#开发的OpenRA的OpenGL创建纹理流程
C#开发的OpenRA的OpenGL创建纹理流程 由于OpenRA采用的是OpenGL来显示游戏画面, 那么它就必然采用纹理来显示了。 并且由于它是2D的游戏,所以3D的模型是没有的,只要使用纹理贴图,就可以完全实现了游戏的功能。 OpenGL的纹理要起作用,需要经过一系列的动作。 先要使用glGen…...
3D目标检测(一)—— 基于Point-Based方法的PointNet系列
3D目标检测(一)—— PointNet,PointNet,PointNeXt, PointMLP 目录 3D目标检测(一)—— PointNet,PointNet,PointNeXt, PointMLP 前言 零、网络使用算法 …...
《设计模式》策略模式
策略模式 前言 先了解一下设计模式的几种类似: 行为型设计模式(Behavioral Design Pattern)是指一组设计模式,它们关注的是对象之间的通信和协作。行为型设计模式描述了对象之间的职责分配和算法的封装,以及如何在运…...
【离散数学】1. 数理逻辑
1.数理逻辑 2. 集合论 3. 代数系统 4. 图论 离散数学:研究离散量结构及相互关系的学科 数理逻辑集合论代数系统图论 逻辑:研究推理的科学 数学方法:引进一套符号系统的方法 数理逻辑是用数学方法研究形式逻辑的科学,即使用符号化…...
Java8新特性学习
Java8新特性学习为啥使用Lambda表达式Lambda表达式的基础语法无参无返回有参无返回一个参数多参单个语句体类型推断四大内置核心函数式接口其他接口方法引用与构造器引用Stream简介什么是StreamStream操作步骤创建Stream中间操作终止操作(终端操作)归约与收集并行流…...
SPARK outputDeterministicLevel的作用--任务全部重试或者部分重试
背景 目前spark的repartition()方法是随机分配数据到下游,这会导致一个问题,有时候如果我们用repartition方法的时候,如果任务发生了重试,就有可能导致任务的数据不准确,那这个时候改怎么解决这个问题呢? …...
图数据库中的 OLTP 与 OLAP 融合实践
在一些图计算的场景下,我们会遇到同时需要处理 OLTP 和 OLAP 的问题。而本文就给了一个 OLTP 与 OLAP 融合实践的指导思路,希望给你带来一点启发。 Dag Controller 介绍 Dag Controller 是 NebulaGraph 企业版的图系统,经过反复测试无误后已…...
进程地址空间(比特课总结)
一、进程地址空间 1. 环境变量 1 )⽤户级环境变量与系统级环境变量 全局属性:环境变量具有全局属性,会被⼦进程继承。例如当bash启动⼦进程时,环 境变量会⾃动传递给⼦进程。 本地变量限制:本地变量只在当前进程(ba…...
脑机新手指南(八):OpenBCI_GUI:从环境搭建到数据可视化(下)
一、数据处理与分析实战 (一)实时滤波与参数调整 基础滤波操作 60Hz 工频滤波:勾选界面右侧 “60Hz” 复选框,可有效抑制电网干扰(适用于北美地区,欧洲用户可调整为 50Hz)。 平滑处理&…...
Unity3D中Gfx.WaitForPresent优化方案
前言 在Unity中,Gfx.WaitForPresent占用CPU过高通常表示主线程在等待GPU完成渲染(即CPU被阻塞),这表明存在GPU瓶颈或垂直同步/帧率设置问题。以下是系统的优化方案: 对惹,这里有一个游戏开发交流小组&…...
Swift 协议扩展精进之路:解决 CoreData 托管实体子类的类型不匹配问题(下)
概述 在 Swift 开发语言中,各位秃头小码农们可以充分利用语法本身所带来的便利去劈荆斩棘。我们还可以恣意利用泛型、协议关联类型和协议扩展来进一步简化和优化我们复杂的代码需求。 不过,在涉及到多个子类派生于基类进行多态模拟的场景下,…...
可靠性+灵活性:电力载波技术在楼宇自控中的核心价值
可靠性灵活性:电力载波技术在楼宇自控中的核心价值 在智能楼宇的自动化控制中,电力载波技术(PLC)凭借其独特的优势,正成为构建高效、稳定、灵活系统的核心解决方案。它利用现有电力线路传输数据,无需额外布…...
Go 语言接口详解
Go 语言接口详解 核心概念 接口定义 在 Go 语言中,接口是一种抽象类型,它定义了一组方法的集合: // 定义接口 type Shape interface {Area() float64Perimeter() float64 } 接口实现 Go 接口的实现是隐式的: // 矩形结构体…...
渲染学进阶内容——模型
最近在写模组的时候发现渲染器里面离不开模型的定义,在渲染的第二篇文章中简单的讲解了一下关于模型部分的内容,其实不管是方块还是方块实体,都离不开模型的内容 🧱 一、CubeListBuilder 功能解析 CubeListBuilder 是 Minecraft Java 版模型系统的核心构建器,用于动态创…...
用docker来安装部署freeswitch记录
今天刚才测试一个callcenter的项目,所以尝试安装freeswitch 1、使用轩辕镜像 - 中国开发者首选的专业 Docker 镜像加速服务平台 编辑下面/etc/docker/daemon.json文件为 {"registry-mirrors": ["https://docker.xuanyuan.me"] }同时可以进入轩…...
【碎碎念】宝可梦 Mesh GO : 基于MESH网络的口袋妖怪 宝可梦GO游戏自组网系统
目录 游戏说明《宝可梦 Mesh GO》 —— 局域宝可梦探索Pokmon GO 类游戏核心理念应用场景Mesh 特性 宝可梦玩法融合设计游戏构想要素1. 地图探索(基于物理空间 广播范围)2. 野生宝可梦生成与广播3. 对战系统4. 道具与通信5. 延伸玩法 安全性设计 技术选…...
学习STC51单片机32(芯片为STC89C52RCRC)OLED显示屏2
每日一言 今天的每一份坚持,都是在为未来积攒底气。 案例:OLED显示一个A 这边观察到一个点,怎么雪花了就是都是乱七八糟的占满了屏幕。。 解释 : 如果代码里信号切换太快(比如 SDA 刚变,SCL 立刻变&#…...
