【大数据离线开发】7.4 HBase数据保存和过滤器

news2024/11/13 12:04:11

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 {
	@Test
	public void testCreateTable() throws Exception{
		//指定的配置信息: ZooKeeper
		Configuration conf = new Configuration();
		conf.set("hbase.zookeeper.quorum", "192.168.157.111");
		
		//创建一个HBase客户端: HBaseAdmin
		HBaseAdmin admin = new HBaseAdmin(conf);
		
		//创建一个表的描述符: 表名
		HTableDescriptor hd = new HTableDescriptor(TableName.valueOf("emp"));
		
		//创建列族描述符
		HColumnDescriptor hcd1 = new HColumnDescriptor("empinfo");
		
		//加入列族
		hd.addFamily(hcd1);
		
		//创建表
		admin.createTable(hd);
		
		//关闭客户端
		admin.close();
	}

	@Test
	public void testPutData() throws Exception{
		//指定的配置信息: ZooKeeper
		Configuration 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"));
	
		//构造List
		List<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();		
	}
}



在这里插入图片描述

常见的过滤器

  1. 列值过滤器:select * from emp where sal = 3000;

  2. 列名前缀过滤器:查询员工的姓名 select ename form emp;

  3. 多个列名前缀过滤器:查询员工的姓名、薪水 select ename, sal from emp;

  4. 行键过滤器:通过Row可以查询,类似通过Get查询数据

  5. 组合几个过滤器查询数据:where 条件1 and(or)条件2

public class TestHBaseFilter {

	@Test
	public void testSingleColumnValueFilter() throws Exception{
		//列值过滤器: 查询薪水等于3000的员工
		//  select * from emp where sal=3000
		//配置ZooKeeper
		Configuration 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();
	}
	
	@Test
	public void testColumnPrefixFilter() throws Exception{
		//列名前缀过滤器  查询员工的姓名:  select ename from emp;
		//配置ZooKeeper
		Configuration 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();		
		
	}
	
	@Test
	public void testMultipleColumnPrefixFilter() throws Exception{
		//多个列名前缀过滤器
		//查询员工信息:员工姓名 薪水
		//配置ZooKeeper
		Configuration 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();			
	}
	
	@Test
	public void testRowFilter() throws Exception{
		//查询员工号7839的信息
		//配置ZooKeeper
		Configuration 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();	
	}  
	
	@Test
	public void testFilter() throws Exception{
		/*
		 * 查询工资等于3000的员工姓名      select ename from emp where sal=3000;
		 * 1、列值过滤器:工资等于3000
		 * 2、列名前缀过滤器:姓名
		 */
		
		//配置ZooKeeper
		Configuration conf = new Configuration();
		conf.set("hbase.zookeeper.quorum", "192.168.157.11");
		
		//得到客户端
		HTable table = new HTable(conf,"emp");
		
		//第一个过滤器 列值过滤器:工资等于3000
		SingleColumnValueFilter 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 相当于 or
		
		FilterList 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> {

	@Override
	protected void map(ImmutableBytesWritable key, Result value,Context context)
			throws IOException, InterruptedException {
		/*
		 * key和value代表从表中输入的一条记录
		 * key: 行键
		 * value:数据
		 */
		//获取数据: I love beijing
		String 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> {

	@Override
	protected 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的地址
		//指定的配置信息: ZooKeeper
		Configuration 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,使用工具类设置Mapper
		TableMapReduceUtil.initTableMapperJob(Bytes.toBytes("word"),    //输入的表
				                              scan,    //扫描器,只读取想要处理的数据
				                              WordCountMapper.class, 
				                              Text.class, 
				                              IntWritable.class, 
				                              job);
		
		
		//指定Reducer,使用工具类设置Reducer
		TableMapReduceUtil.initTableReducerJob("stat", WordCountReducer.class, job);
		
        //执行任务
		job.waitForCompletion(true);
	}

}

将编写的程序打包成jar包,上传到全分布或者伪分布环境下,启动环境运行,会有一个exception异常。

在Hadoop集群上会去访问HBase,需要HBase依赖

在这里插入图片描述

注意:export HADOOP_CLASSPATH= H B A S E H O M E / l i b / ∗ : HBASE_HOME/lib/*: HBASEHOME/lib/:CLASSPATH

在这里插入图片描述

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/359919.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

美国原装KEYSIGHT E4981A(安捷伦) E4981A电容计

KEYSIGHT E4981A&#xff08;安捷伦&#xff09; Keysight E4981A&#xff08;安捷伦&#xff09;电容计为生产线中的陶瓷电容器测试提供了高速、可靠的测量。E4981A 实现了电容从小到大的测量能力&#xff0c;测量准确。Agilent E4981A 电容计有助于提高测试吞吐量&#xff0…

Structure|Alphafold2在肽结构预测任务上的基准实验

​题目&#xff1a;Benchmarking AlphaFold2 on peptide structureprediction 文献来源&#xff1a;2023, Structure 31, 1–9 代码&#xff1a;基准实验&#xff0c;比较了比较多的模型 1.背景介绍 由2-50个氨基酸构成的聚合物可以称为肽。但是关于肽和蛋白质之间的差异还是…

树莓派4b系统安装

文章目录一.树莓派系统和工具下载二.树莓派系统烧录一.树莓派系统和工具下载 树莓派系统下载&#xff1a;https://www.raspberrypi.com/software/operating-systems/ 下载系统镜像写入工具&#xff1a;Win32DiskImager https://sourceforge.net/projects/win32diskimager/ …

仅作笔记用:Windows 10 继续使用 IE 浏览器(针对23年2月14日的系统更新)

2 月 14 日更新后有部分 Windows 10 的用户反映 IE 浏览器无法使用&#xff0c;打开后变成 Edge 浏览器。由于有少数业内业务仍然必须使用 IE 浏览器&#xff0c;这里稍微研究了一下解决方法。 打开 IE 浏览器的时候会出现“IE已经合并进Edge浏览器”的提示&#xff0c;此时千…

华为手表开发:WATCH 3 Pro(10)获取心率

华为手表开发&#xff1a;WATCH 3 Pro&#xff08;10&#xff09;获取心率初环境与设备文件夹&#xff1a;文件新增第二页面引用包 import sensor from system.sensor;showHeartbeat.hmlshowHeartbeat.js修改首页 -> 新建按钮 “ 跳转 ”index.hmlindex.js 引用包&#xff1…

JVM系统优化实践(1):JVM概览

您好&#xff0c;我是湘王&#xff0c;这是我的CSDN博客&#xff0c;欢迎您来&#xff0c;欢迎您再来&#xff5e;这是多年之前做过的学习笔记&#xff0c;今天再翻出来&#xff0c;觉得仍然是记忆犹新。「独乐乐不如众乐乐」&#xff0c;就拿出来分享给「众乐乐」吧。目前大多…

BCN科研试剂:1263166-91-1,endo BCN-O-PNB,ENDO BCN - 活性酯(P-NPC)

试剂基团反应特点&#xff1a;endo BCN-O-PNB中在有机溶剂中很容易与含胺分子发生反应&#xff0c;PNB 是一个很好的离去基团&#xff0c;BCN 用于无铜点击化学反应。结构式&#xff08;Structural&#xff09;&#xff1a;基础产品数据&#xff1a;CAS号&#xff1a;1263166-9…

合并两个有序链表——递归解法

题目描述21. 合并两个有序链表难度简单2922收藏分享切换为英文接收动态反馈将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 示例 1&#xff1a;输入&#xff1a;l1 [1,2,4], l2 [1,3,4]输出&#xff1a;[1,1,2,3,4,4]示例…

【项目精选】基于B2C的网上拍卖系统_秒杀与竞价

点击下载源码 伴随着网络技术的广泛应用和高速发展&#xff0c;随着人们生活节奏的越来越快&#xff0c;越来越多的人们开始在网络中寻求便利。网络购物具备了省时、省事、省心、高效等特点&#xff0c;从而广泛被大众接受&#xff0c;并逐渐渗透到人们的生活中&#xff0c;成为…

当越来越多的企业不再使用FTP,该用什么更好的方案替代?

FTP作为第一个完整的文件传输协议&#xff0c;在互联网技术发展史上具有浓墨重彩的意义&#xff0c;它解决了文件传输协议有无的问题&#xff0c;在全世界范围内被广泛使用。但如今&#xff0c;随着网络技术的发展&#xff0c;企业生产类型和生产资料的丰富化&#xff0c;文件传…

Linux 系统目录结构

登录系统后&#xff0c;在当前命令窗口下输入命令&#xff1a; ls / 你会看到如下图所示: 树状目录结构&#xff1a; 以下是对这些目录的解释&#xff1a; /bin&#xff1a; bin 是 Binaries (二进制文件) 的缩写, 这个目录存放着最经常使用的命令。 /boot&#xff1a; 这里…

米尔电子MYC-YT507H测试u8g2_OLED显示库

最近在测试u8g2库&#xff0c;准备是在单片机上使用的&#xff0c;不过目前我看到其也是支持了linux设备的&#xff0c;所以想着是不是能在T507上跑下。搜了下已经是有人做了移植了。官方现在应该也是支持了的&#xff0c;我选择别人开源的&#xff0c;因为介绍的还比较详细。开…

【基础语法】JavaScript 全栈体系(三)

JavaScript 基础 第三章 常量 一、常量的基本使用 概念&#xff1a;使用 const 声明的变量称为“常量”。使用场景&#xff1a;当某个变量永远不会改变的时候&#xff0c;就可以使用 const 来声明&#xff0c;而不是let。命名规范&#xff1a;和变量一致常量使用 // 声明一…

python 之 海龟绘图(turtle)

注&#xff1a;从个人博客园移植而来 使用简介 python 2.6引入的一个简单的绘图工具&#xff0c;俗称为海龟绘图。3.x以上使用的话&#xff0c;可通过pip进行安装&#xff0c;命令为&#xff1a; pip/pip3 install turtle如果出现如下错误&#xff1a; 解决方式&#xff1a; …

UOS桌面操作系统搭建open vxn服务

UOS系统搭建openVPN一、环境说明二、服务端配置1、软件安装2、创建目录用来存放生成证书中要用到的各种文件3、准备证书生成相关文件4 、准备生成证书用的CSR相关配置5、生成CA证书6、生成服务端证书7、使用CA给服务端证书签名8、生成DH证书9、生成ta密钥10、生成客户端证书&am…

07 二叉树

开始系统学习算法啦&#xff01;为后面力扣和 蓝桥杯的刷题做准备&#xff01;这个专栏将记录自己学习算法是的笔记&#xff0c;包括 概念&#xff0c; 算法运行过程&#xff0c;以及 代码实现&#xff0c;希望能给大家带来帮助&#xff0c;感兴趣的小伙伴欢迎评论区留言或者私…

CHAPTER 1 Web Server - apache(httpd)

Web Server - apache1.1 概念介绍1.1.1 什么是Web Service?1.1.2 什么是Web Server?1.1.3 常见的Web服务程序有哪些?1.2 httpd1.2.1 httpd和apache的区别关系1.2.2 httpd版本介绍1.2.3 httpd安装1. yum 安装2. 编译安装1.3 通过systemctl管理httpd1.3.1 配置文件原因1.3.2 为…

析构函数、拷贝构造

1、析构函数析构函数的定义方式函数名和类名相同&#xff0c;在类名前加~&#xff0c;没有返回值类型&#xff0c;没有函数形参&#xff08;不能重载&#xff09;当对象生命周期结束的时候&#xff0c;系统会自动调用析构函数先调用析构函数&#xff0c;再释放对象的空间析构函…

C#中多态、抽象类、虚方法

多态、重装、重写 •多态&#xff1a;同一操作作用于不同的对象&#xff0c;可以有不同的解释&#xff0c;产生不同的执行结果&#xff0c;这就是多态性。抽象类、虚函数、接口三种方法实现的可以是多态性。•重载&#xff08;overload&#xff09;&#xff1a;对象中同名函数&…

【Galois工具开发之路】给你的JVM安装一个插件~

什么是DCEVM Dcevm&#xff08;DynamicCode Evolution Virtual Machine&#xff09;是Java Hostspot的一个扩展插件&#xff0c;属于开源性工具&#xff0c;非JDK官方提供&#xff0c;它允许你在运行环境下修改加载的类文件。当前虚拟机只允许修改方法体&#xff08;Method&am…