变量先定义,再赋值使用变量类型char:字符型,占用一个字节int:整形,通常反映了所用机器中整数的最自然长度float:单精度浮点型double:双精度浮点型…后面基本类型补充完整小例子#include<stdio.h>intmain(){//声明变量chara;intb;floatc;doubled;//变量赋值a='a';b=520;c=3.14;d=3.141592653;printf("char类型是%c\n",a);printf("我爱你%d\n",b);printf("圆周率是:%.2f\n",c);printf("圆周率后九位:%11.9f\n",d);return0;}常量定义后不能被改变,为了与变量区别,使用常量名使用大写常量的定义格式:#define常量名常量内容#include<stdio.h>//常量的定义#defineURL"https://bigdataboy.cn"intmain(){printf("大数据男孩网址:%s\n",URL);return0;}
C程序运行C语言的需要先编译成->汇编语言->机器语言,然后给CPU执行。C语言的优势灵活度高、可移植性高、效率高灵活度高:源代码最终编译成机器语言,也就是我们所说的可执行文件,从此CPU就可以直接执行灵活度高:C语言不仅提供多种运算符,还可以完成类似于计算机底层操作的位运算;语法简单,约束少;丰富多变的结构和数据类型;还拥有可以直接操作计算机硬件能力。可移植性高:可移植性高是指源代码在不需要做改动或只需稍加修改,就能够在其他机器上编译后正确运行,因此使用C语言的编译程序更便于移植。另外,无论是Windows系统、Linux系统还是苹果的MacOS系统,抛开现象看本质,它们都与C语言有不可分割的联系。我的第一个C语言程序打印HelloWorld#include<stdio.h>intmain(){printf("HelloWorld\n");return0;}代码说明/**我的第一个C语言程序**/#include<stdio.h>//引入模块/**main()主方法,一个c程序只有一个主方法**/intmain()//int表示返回值类型{printf("HelloWorld\n");//语句需要分号结尾return0;//返回值}运行测试在运行之前,Linux需要安装gcc,安装命令yuminstallgcc#编译C程序[root@nodesie1]#gcctest.c-otest#执行编译后的C程序[root@nodesie1]#./testHelloWorld
使用非直接缓冲区方式完整代码:点我查看创建文件流//创建文件流FileInputStreamfis=newFileInputStream("1.jpeg");//输入文件FileOutputStreamfos=newFileOutputStream("2.jpeg");//输出文件获取通道通过文件流获得通道//获取通道FileChannelfisChannel=fis.getChannel();FileChannelfosChannel=fos.getChannel();分配缓存区(Buffer)//分配指定大小的缓冲区ByteBufferbyteBuffer=ByteBuffer.allocate(1024);传递数据把输入通道里数据,通过Buffer传递给输出通道,最后输出//将通道的数据存入缓冲区while(fisChannel.read(byteBuffer)!=-1){byteBuffer.flip();//切换为读取数据模式//将缓冲区的数据写入通道中fosChannel.write(byteBuffer);byteBuffer.clear();}关闭通道&流//关闭通道&流fisChannel.close();fosChannel.close();fis.close();fos.close();使用内存映射文件方式完整代码:点我查看创建文件流//创建文件流FileInputStreamfis=newFileInputStream("1.mp4");//输入流FileOutputStreamfos=newFileOutputStream("2.mp4");//输出流获取通道通过文件流获得通道//获取通道FileChannelfisChannel=fis.getChannel();FileChannelfosChannel=fos.getChannel();创建内存映射文件//创建内存映射文件MappedByteBuffermappedByteBuffer=fisChannel.map(FileChannel.MapMode.READ_ONLY,0,fisChannel.size());fosChannel.write(mappedByteBuffer);关闭流fisChannel.close();fosChannel.close();
说明统计各个用户每个月访问的次数,显示出以下信息:用户名、月份、访问次数测试数据tom,2020-01,5tom,2020-01,15jack,2020-01,5tom,2020-01,8jack,2020-01,25tom,2020-01,5tom,2020-02,4tom,2020-02,6jack,2020-02,10jack,2020-02,5数据导入Hive#建表createtabletest(namestring,monthString,pvint)rowformatdelimitedfieldsterminatedby',';#从本地导入数据loaddatalocalinpath'/root/info.txt'intotabletest;#查询数据select*fromtest;统计按照month分组,pv相加,最后显示name,month,sum(pv)字段如下面写法出现一个错误,出现这个错是因为,在使用分组的时候,聚合的时只规定了pv的聚合方式,name的聚合方式没有确定。hive>selectname,month,sum(pv)>fromdefault.test>groupbymonth;FAILED:SemanticException[Error10025]:Line1:7ExpressionnotinGROUPBYkey'name'而根据我们需要的统计结果,是需要month,name一起分组。selectname,month,sum(pv)fromdefault.testgroupbymonth,name;
说明在软件使用中,大多数需要使用多线程来实现,并且需要线程长久执行,所以就需要用到死循环,哪如何停止该死循环线程呢?监控文件是否修改完整代码:点击查看主界面代码importsysimportosfromPyQt5.QtWidgetsimport(QWidget,QApplication,QTextEdit,QPushButton,QBoxLayout)fromPyQt5.QtCoreimport(QThread,pyqtSignal)classWindow(QWidget):def__init__(self,parent=None,*args,**kwargs):super().__init__(parent,*args,**kwargs)self.initUI()definitUI(self):self.setWindowTitle('停止多线程死循环')self.resize(550,450)#创建多行文本框qtext_edit=QTextEdit()qtext_edit.resize(530,430)qtext_edit.setObjectName("edit")#创建三个按钮pushButton=QPushButton()pushButton.setText("导入文件")pushButton.clicked.connect(self.open_file)#导入文件qpush_button_start=QPushButton()qpush_button_start.setText("开始监控")qpush_button_start.clicked.connect(self.start_monitor)#连接开始监控槽函数qpush_button_stop=QPushButton()qpush_button_stop.setText("停止监控")qpush_button_stop.clicked.connect(self.stop_monitor)#连接停止监控槽函数#添加到垂直布局到父控件v_layout=QBoxLayout(QBoxLayout.TopToBottom)self.setLayout(v_layout)#添加水平布局控件lrlayout=QBoxLayout(QBoxLayout.LeftToRight)lrlayout.addWidget(pushButton)lrlayout.addWidget(qpush_button_start)lrlayout.addWidget(qpush_button_stop)v_layout.addWidget(qtext_edit)v_layout.addLayout(lrlayout)defopen_file(self):print("导入文件")#开始监控defstart_monitor(self):print("点击开始")#停止监控defstop_monitor(self):print("点击停止")if__name__=='__main__':app=QApplication(sys.argv)window=Window()window.show()sys.exit(app.exec_())监控文件是否更新线程监控文件需要开启一个线程,不然主界面就会出现假死classThread(QThread):#自定义修改时间信号file_time=pyqtSignal(float)def__init__(self,path:str,parent=None):super().__init__(parent)#文件路径self.path=path#死循环状态self.status=True#默认文件最后修改时间self.endTime=0.0def__del__(self):self.wait()defrun(self)->None:whileself.status:#判断文件修改时间ifself.endTime!=os.path.getmtime(self.path):self.endTime=os.path.getmtime(self.path)#发送文件修改信号self.file_time.emit(self.endTime)self.sleep(1)导入文件&更新文本框内容defopen_file(self):print("导入文件")#选择文件self.file_Name_Type=QFileDialog.getOpenFileName(self,"选取文件")ifself.file_Name_Type=="":print("\n取消选择")returnself.qtext_edit.append(f"导入文件路径{self.file_Name_Type[0]}")#添加文本框内容defset_text(self,text:str):self.qtext_edit.append(f"文件最后修改时间{text}")开始&停止监控事件点击开始监控开启监控线程,点击停止监控,修改死循环条件#开始监控defstart_monitor(self):self.thread=Thread(self.file_Name_Type[0])#接收文件修改时间信号self.thread.file_time.connect(self.set_text)self.thread.start()#停止监控defstop_monitor(self):self.thread.status=False效果
安装&加载pip3installxlrd-ihttps://mirrors.aliyun.com/pypi/simple/importxlrd打开Excel文件path='data/在线表格2.0.xlsx'data=xlrd.open_workbook(path)获取sheet名称#返回所有的sheet名称names=data.sheet_names()#返回类型为是一个列表得到表格对象#通过索引获取操作的表格对象table=data.sheet_by_index(0)行操作得到有效行#获取该表格中的有效行数nrows=table.nrows得到行对象#通过索引获取操作的表格对象table=data.sheet_by_index(0)#获取该把表格中的有效行数rows=table.nrows#使用有效行去遍历得到行对象forrinrange(rows):v=table.row(r)print(v)获得具体数据这是通过行对象获取数据#通过索引获取操作的表格对象table=data.sheet_by_index(0)#获取该把表格中的有效行数rows=table.nrows#使用有效行去遍历得到行对象forrinrange(rows):o,t,s=table.row(r)[0].value,table.row(r)[1].value,table.row(r)[2].valueprint(o,t,s)直接获取一行的数据,然后组成list#通过索引获取操作的表格对象table=data.sheet_by_index(0)#通过索引顺序获取#获取该把表格中的有效行数rows=table.nrows#使用有效行去遍历得到行对象forrinrange(rows):o=table.row_values(r)print(o)列操作获取有效列#获取该表格中的有效行数cols=table.ncolsprint(cols)得到列对象#通过索引获取操作的表格对象table=data.sheet_by_index(0)#通过索引顺序获取#获取该把表格中的有效列数cols=table.ncols#使用有效行去遍历得到列对象forcinrange(cols):t=table.col(c,start_rowx=0,end_rowx=None)print(t)获得具体数据这是通过列对象获取数据#通过索引获取操作的表格对象table=data.sheet_by_index(0)#通过索引顺序获取#获取该把表格中的有效列数cols=table.ncols#使用有效行去遍历得到列对象forcinrange(cols):t=table.col(c)[0].valueprint(t)直接获取一行的数据,然后组成list#通过索引获取操作的表格对象table=data.sheet_by_index(0)#通过索引顺序获取#获取该把表格中的有效列数cols=table.ncols#使用有效行去遍历得到列对象forcinrange(cols):t=table.col_values(c)print(t)常用函数合计path='test.xlsx'#读取文件data=xlrd.open_workbook(path)data.sheet_names()#返回所有的sheet名称的listtable=data.sheet_by_index(0)#通过索引获取操作的表格对象table=data.sheet_by_name(sheet_name)#通过名称获取操作的表格对象行操作nrows=table.nrows#获取该sheet中的有效行数table.row(rowx)#返回由该行中所有的单元格对象组成的列表table.row_types(rowx,[start_colx=0],[end_colx=None])#返回由该行中所有单元格的数据类型组成的列表table.row_values(rowx,[start_colx=0],[end_colx=None])#返回由该行中所有单元格的数据组成的列表table.row_len(rowx)#返回该列的有效单元格长度列操作ncols=table.ncols#获取列表的有效列数table.col(colx,[start_rowx=0],[end_rowx=None])#返回由该列中所有的单元格对象组成的列表table.col_types(colx,[start_rowx=0],[end_rowx=None])#返回由该列中所有单元格的数据类型组成的列表table.col_values(colx,[start_rowx=0],[end_rowx=None])#返回由该列中所有单元格的数据组成的列表
IO&NIO的区别NIOJavaNIO(NewIONonBlockingIO)是从Java1.4版本引入的一个新的IOAPI,可以替代标准的JavaIOAPI。NIO与原来的IO有着同样的作用和目的,但是使用的方式不同,NIO支持面向缓冲区的、基于通道的IO操作。NIO将更加高效的方式进行文件读写操作。区别IONIO面向流(Stream)面向缓冲区(Buffer)阻塞IO(BlockingIO)非阻塞IO(NonBlockingIO)无选择器(Selecors)缓冲区(Buffer)创建缓冲区(allocate)缓冲区本质就是数组,用于存储不同的数据缓冲区类型:ByteBuffer、CharBuffer、ShortBuffer、IntBuffer、LongBuffer、FloatBuffer、DoubleBuffer//分配一个指定大小的Byte缓冲区(大小必须指定)ByteBufferbbuffer=ByteBuffer.allocate(1024);读&取缓冲区的两大核心方法缓冲区放入数据(put)放入方法put()有很多重载这里说明一下第一种:put(byte[]src,intoffset,intlength)byte[]src:放入缓冲区的数组intoffset:放入缓冲区数组的偏移量intlength:偏移量向后放入length位数据到缓冲区后两个参数为可选,不设置,表示把整个数组放入缓冲区。//Strings="abcde";byte[]bytes=newbyte[]{'a','b','c','e','f'};//数据放入缓冲区//bbuffer.put(s.getBytes());bbuffer.put(str.getBytes());读取缓冲区数据(get)在读取缓冲区数据之前,需要转换缓冲区模式为读取模式。bbuffer.flip();//读取缓冲区数据首先需要切换缓冲区模式System.out.println(bbuffer.get(0));//97打印出来的是字节码清空缓冲区但是'清空'后,缓冲区的数据依然存在,处于被遗忘状态bbuffer.clear();缓冲区的四大核心属性大小关系:mark<=position<=limit<=capacitycapacity:容量,代表缓冲区存储数据的大小,一旦声明不能改变limit:界限,表示缓冲区可以操作数据的大小(limit后的数据不能进行读写)position:位置,表示缓冲区正在操作数据的位置。mark:标记,表示记录当前position的位置,可以通过reset()恢复到mark位置。创建缓冲区时写入数据时读取数据时mark记录position的位置@Testpublicvoidtest(){byte[]bytes=newbyte[]{'a','b','c','e','f'};//创建放入数据切换模式ByteBufferbuf=ByteBuffer.allocate(10);buf.put(bytes);buf.flip();//记录position的位置buf.mark();//创建新的数组取出缓冲区的数据,添加到des字节数组byte[]des=newbyte[buf.limit()];buf.get(des,0,2);//输出数组的值System.out.println(newString(des,0,2));System.out.println(buf.position());buf.reset();//恢复position到mark位置System.out.println(buf.position());}
说明什么是Mycat一个彻底开源的,面向企业应用开发的大数据库集群支持事务、ACID、可以替代MySQL的加强版数据库一个可以视为MySQL集群的企业级数据库,用来替代昂贵的Oracle集群一个融合内存缓存技术、NoSQL技术、HDFS大数据的新型SQLServer结合传统数据库和新型分布式数据仓库的新一代企业级数据库产品一个新颖的数据库中间件产品官网:http://www.mycat.org.cn/开源地址:https://github.com/MyCATApache/Mycat-Server相关版本配置说明软件版本MycatMycat-server-1.6.7.5MySQL5.7下载Mycat解压到任意目录配置文件说明进入Mycat的conf/目录下,主要注意这3个配置文件schema.xml:中定义逻辑库,表、分片节点等内容rule.xml:中定义分片规则;server.xml:中定义用户以及系统相关变量,如端口等配置schema.xml文件官方文件里注释太多,太杂,看着太费劲,可以先进行删减该配置说明:逻辑库名TESTDB,相当于一个数据库,逻辑表名table,相当于数据库里的一张表,这张表里的数据放在了dn1,dn2,dn3,dn4这个四个真实的数据库里。<?xmlversion="1.0"?><!DOCTYPEmycat:schemaSYSTEM"schema.dtd"><mycat:schemaxmlns:mycat="http://io.mycat/"><!--name逻辑数据名称取消sql限制,把sqlMaxLimit="-1"--><schemaname="TESTDB"checkSQLschema="false"sqlMaxLimit="100"><!--name:逻辑表名称dataNode:逻辑表数据存放的节点rule:逻辑表的分片规则规则对应rule.xml里面--><tablename="sbtest1"dataNode="dn1,dn2,dn3,dn4"rule="rule1"/><!--逻辑表可以配置多个--></schema><!--数据节点对应的数据库,这里都配置在一个机器上,可分布式配置--><dataNodename="dn1"dataHost="localhost"database="db1"/><dataNodename="dn2"dataHost="localhost"database="db2"/><dataNodename="dn3"dataHost="localhost"database="db3"/><dataNodename="dn4"dataHost="localhost"database="db4"/><!--数据的节点的链接信息,name需要对应上<dataNode/>标签里的dataHost--><dataHostname="localhost"maxCon="1000"minCon="10"balance="0"writeType="0"dbType="mysql"dbDriver="native"switchType="1"slaveThreshold="100"><!--心跳语句--><heartbeat>selectuser()</heartbeat><!--配置写入主机--><writeHosthost="hostM1"url="localhost:3306"user="root"password="123456"></writeHost></dataHost></mycat:schema>配置server.xml文件该文件可以不用配置配置rule.xml<?xmlversion="1.0"encoding="UTF-8"?><!DOCTYPEmycat:ruleSYSTEM"rule.dtd"><mycat:rulexmlns:mycat="http://io.mycat/"><!--分片规则名称--><tableRulename="rule1"><rule><!--分片字段--><columns>id</columns><!--分片的方法--><algorithm>mod-long</algorithm></rule></tableRule><functionname="mod-long"class="io.mycat.route.function.PartitionByMod"><!--分片的节点数量--><propertyname="count">4</property></function></mycat:rule>MySQL创库创表创建真实库创建真实表启动Mycat进入Mycat注意在Linux下,如果进入MySQL需要端口,一定要加上host,不然指定的端口不会生效。mysql-uroot-h127.0.0.1-P8066-p插入数据在插入数据时,分片规则字段数据尽量不要太接近,不然看不出效果。
相关配置版本组件版本Hadoop2.9.2Jdk1.8.0_221CentOS7.7Sqoop2.6.0MySQL5.7.30MySQL驱动5.1.48Sqoop说明把Sqoop当作一个工具就好,它的主要作用就是把传统数据库的数据与大数据存储互导数据。MySQL<->HDFSMySQL<->Hive使用SQL作为导入条件等安装MySQL#没有wget,则执行这个yuminstallwget#下载MySQL5.7wgethttp://repo.mysql.com/mysql57-community-release-el7-10.noarch.rpm#安装rpm包yum-yinstallmysql57-community-release-el7-10.noarch.rpm#通过Yum来安装MySQL,会自动处理MySQL与其他组件的依赖关系yuminstallmysql-community-server#启动MySQLsystemctlstartmysqld.service#查看密码greppassword/var/log/mysqld.log修改MySQL密码原本密码强度需要大小写母特殊字符数字,最少8位,我们把密码改简单一点#首先进入MySQLmysql-uroot-p#查看密码策略SHOWVARIABLESLIKE"%password%";#修改密码长度策略为5就是密码长度最短5位SETGLOBALvalidate_password_length=5;#修改密码强度策略0就不需要大小写字母和符号SETGLOBALvalidate_password_policy=0;#修改密码SETPASSWORD=PASSWORD("123456");复制驱动把MySQL驱动复制到Sqoop的lib/目录下。cpmysql-connector-java-5.1.38-bin.jar/usr/local/src/sqoop-1.4.7/lib/测试是否连接成功通过Sqoop查看MySQL数据库。sqooplist-databases\--connectjdbc:mysql://127.0.0.1:3306\--username'root'\--password'123456'MySQL—>HDFS首先需要在MySQL建好需要导出的表,以及添加好内容#创建test数据库craetedatabasetest;#创建stab表createtablestab(idint,namevarchar(20));#插入stab表数据insertintostab(id,name)values(1,"big"),(2,"data"),(3,"boy");使用Sqoop导出,命令关键字import(导入)sqoopimport\--connect'jdbc:mysql://127.0.0.1:3306/test'\--table'stab'\--username'root'\--password'123456'\--target-dir'/sqoop/stab'\--fields-terminated-by'|'\--split-byid某些参数含义—connect:MySQL数据库地址—table:需要导出表的表名—target-dir:表导出的HDFS地址—fields-terminated-by:设置导出数据字符分隔符—split-byid:HDFS上数据的分区规则(最好该字段是int类型,默认为主键),上命令,表示安装id字段分区,如果不分区,就把--split-byid替换成-m1即可-m:表明需要使用几个map任务并发执行如果设置为2,则表示:第一个map执行拆分字段值为(1,25)之间的数据,处理结果会在一个分区第二个map执行拆分字段值为(26,50)之间的数据,处理结果会在另一个分区HDFS—>MySQLSqoop不能创建表,所以需要实现把表创建完成。清空test数据库里stab表的数据,命令关键字export(导出)truncatetabletest.stab;使用Sqoop从HDFS导入到MySQLsqoopexport\--connect'jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf-8'\--username'root'\--password'123456'\--table'stab'\--export-dir'/sqoop/stab'\--fields-terminated-by'|'\-m1
安装&加载pip3installpymongo-ihttps://mirrors.aliyun.com/pypi/simple/importpymongo连接MongoDB服务client=pymongo.MongoClient("mongodb://localhost:27017/")print(client)--------------#Mongo服务MongoClient(host=['localhost:27017'],document_class=dict,tz_aware=False,connect=True)获取所有数据库dblist=client.list_database_names()print(dblist)-------------#所有数据库名称['admin','config','local']创建数据库&获取数据库对象如果没有该数据库则创建db=client["db"]print(db)---------#db数据库对象Database(MongoClient(host=['localhost:27017'],document_class=dict,tz_aware=False,connect=True),'db')创建集合&获取集合如果没有该集合则创建#创建集合collection=db["collection"]print(sets)-----------#sets集合对象Collection(Database(MongoClient(host=['localhost:27017'],document_class=dict,tz_aware=False,connect=True),'db'),'sets')#获取所有集合sets=db.list_collection_names()print(sets)--------------#该数据库所有集合['collection']插入数据#插入一条数据data={"name":"bigdataboy","age":"18"}x=collection.insert_one(data)print(x.inserted_id)--------#数据的_id5ed666e1bca2037c30662e97#插入多条数据datas=[{"name":"大数据男孩","age":"18"},{"name":"bigdataboy","age":"16","addr":"China"},{"name":"bigdataboy","age":"18"}]x=collection.insert_many(datas)print(x.inserted_ids)---------------------#插入数据的_id[ObjectId('5ed667e044fb69d445e510d8'),ObjectId('5ed667e044fb69d445e510d9'),ObjectId('5ed667e044fb69d445e510da')]自定义_id#链式写法collection=pymongo.MongoClient("mongodb://localhost:27017/")["db"]["collection"]#数据自行固定_iddatas=[{"_id":"1","name":"大数据男孩","age":"18"},{"_id":"2","name":"bigdataboy","age":"16","addr":"China"},{"_id":"3","name":"bigdataboy","age":"18"}]i=collection.insert_many(datas)print(i.inserted_ids)---------------------#插入数据的_id['1','2','3']查看所有数据collection=pymongo.MongoClient("mongodb://localhost:27017/")["db"]["collection"]forxincollection.find():print(x)------------#所有数据{'_id':'1','name':'大数据男孩','age':'18'}{'_id':'2','name':'bigdataboy','age':'16','addr':'China'}{'_id':'3','name':'bigdataboy','age':'18'}
前言这个是2.0版本,使用现在流行的前后端分离思想重构。体验网址:https://douyin.bigdataboy.cn源码地址:https://github.com/bigdataboy2020/fastapi_douyin使用到的技术后端:语言:PythonWEB框架:FastAPI(现代、快速(高性能)的Web框架)服务器框架:Uvicorn(基于asyncio开发的一个轻量级高效的web服务器框架)反向代理:Nginx(高性能的HTTP和反向代理web服务器)进程管理:Supervisor(ython开发的一套通用的进程管理程序)前端:UI框架:LayUI静态文件存放:Nginx前端部署宝塔添加网站上传前端源码api请求域名可以部署后端之后,再来修改部署后端再添加一个网站,用于添加反向代理修改后端配置&上传源码允许浏览器跨域请求的网址。需要修改成自己的前端域名。宝塔添加Python项目Python版本需要3.6以上。添加进程守护运行目录:/www/wwwroot/api.bigdataboy.cn网站目录启动参数:/www/wwwroot/api.bigdataboy.cn/api_venv/bin/uvicornmain:app按照自己的网站目录改改守护进程配置成功如下,这时只需要去Python项目管理器再启动一次该项目就行。配置反向代理即可部署成功,有问题联系QQ876545500