1.上一行代码与下一行代码无运算关系,可以使用 enter 实现换行,
但在命令行窗口需要使用 shift + enter进行换行,否则它会执行以上的指令
2.上一行代码与下一行代码存在运算关系,可以使用 … 换行
[1] CAN_DeInit 描述 将外设 CAN 的全部寄存器重设为缺省值。
函数源代码 void CAN_DeInit(CAN_TypeDef* CANx) { /* Check the parameters */ assert_param(IS_CAN_ALL_PERIPH(CANx)); if (CANx == CAN1) { /* Enable CAN1 reset state */ RCC_APB1PeriphResetCmd(RCC_APB1Periph_CAN1, ENABLE); //强制或释放APB1挂载的外设 /* Release CAN1 from reset state */ RCC_APB1PeriphResetCmd(RCC_APB1Periph_CAN1, DISABLE); } else { /* Enable CAN2 reset state */ RCC_APB1PeriphResetCmd(RCC_APB1Periph_CAN2, ENABLE); /* Release CAN2 from reset state */ RCC_APB1PeriphResetCmd(RCC_APB1Periph_CAN2, DISABLE); } } 分析 入参类型为CAN_TypeDef*,该数据类型是对CAN外设寄存器的抽象,具体如下。结构体成员与STM32参考手册中CAN章节列出的CAN寄存器逐一对应。
typedef struct { __IO uint32_t MCR; __IO uint32_t MSR; __IO uint32_t TSR; __IO uint32_t RF0R; __IO uint32_t RF1R; __IO uint32_t IER; __IO uint32_t ESR; __IO uint32_t BTR; uint32_t RESERVED0[88]; CAN_TxMailBox_TypeDef sTxMailBox[3]; CAN_FIFOMailBox_TypeDef sFIFOMailBox[2]; uint32_t RESERVED1[12]; __IO uint32_t FMR; __IO uint32_t FM1R; uint32_t RESERVED2; __IO uint32_t FS1R; uint32_t RESERVED3; __IO uint32_t FFA1R; uint32_t RESERVED4; __IO uint32_t FA1R; uint32_t RESERVED5[8]; #ifndef STM32F10X_CL CAN_FilterRegister_TypeDef sFilterRegister[14]; #else CAN_FilterRegister_TypeDef sFilterRegister[28]; #endif /* STM32F10X_CL */ } CAN_TypeDef; 函数内部首先利用断言机制assert_param判定入参是否合理,断言在标准库代码中随处可见,其主要用于代码调试阶段来debug,实现如下:
目录 结论:对于图像处理,还是直接用PIL先处理比较好1. 用PIL读入后,是直接对图像整体做操作2. 如果要涉及到像素的处理(3个步骤)3. 以下为本次实验记录 结论:对于图像处理,还是直接用PIL先处理比较好 再补充一点:在深度学习中最好采用png的图像格式,可参考:深度学习中图像格式选用jpg还是png?答:png
关于numpy.array的两个知识点:
取得array所有元素中的的最大值:np.max(array)对比两个array是否所有元素都相同:(array1 == array2).any(),只会返回一个True或者False,如果没有.any()进行比较,则会返回很多个True或False 1. 用PIL读入后,是直接对图像整体做操作 常用操作:
先用PIL读入:
from PIL import Image image = Image.open(image_path) 裁剪 crop:newimage = image.crop(box),box是一个四元组: ( x m i n , y m i n , x m a x , y m a x ) (x_{min},y_{min},x_{max},y_{max}) (xmin,ymin,xmax,ymax),指明了左上、右下两个坐标位置
缩放 resize:newimage = image.resize((w, h), Image.ANTIALIAS),(w,h)是指定缩放后的宽高,Image.ANTIALIAS表示会高质量缩放,不过现在使用的话会有警告,介意的话按照指示更改为Resampling.LANCZOS即可
旋转 rotate:newimage = image.rotate(-45),-45表示指定的旋转角度(当旋转角度为负数时,则表示顺时针旋转),可改为其他任意数字,旋转后默认以黑色填充画面(若想要更改填充颜色为其他颜色,则可参见我的另一篇博客:【数据增强】用cv2旋转图像并自定义填充背景颜色(主要用到cv2.getRotationMatrix2D 和 cv2.warpAffine))
翻转 transpose:newimage = image.transpose(0),0表示选择的某种方式进行翻转,翻转共有6种方式,取值为0~5,依次为:[‘左右镜像’, ‘上下镜像’, ‘旋转90°’, ‘旋转180°’, ‘旋转270°’, ‘颠倒顺序’]
通过Edit Configurations进行配置
点击加号,并且选择Shell Script
配置参数:
Script path:
Mac系统的为bin目录+startup.sh
Windows系统为bin目录+startup.cmd
配置成功之后
Nacos就会出现在idea的启动选项中了
这种方法实际上只是为了简便启动nacos的操作,还是需要掌握命令行的启动方式的!
目前我了解到的有2种方法:
1、利用iter(dataloader)
将iter(dataloader)都放到一个list,遍历list
iter_list = [iter(loader_train_landmark), iter(loader_train_imagenet), iter(loader_train_product10k)] for i in range(len(iter_list)): iter_dataloader = iter_list[i] for images, target in iter_dataloader: 2、可以使用zip+cycle来合并两个dataloader
先认识几个nignx内置变量: $request_uri: 则是请求的整个字符串,包含了 后面的query_string的;
$remote_addr:则是发送下载请求的主机ip;
$body_bytes_sent :传送页面的字节数
认识几个nignx指令: post_action :当主请求完成后,进行的请求。
internal:指令指定某个location只能被“内部的”请求调用,外部的调用请求会返回”Not found” (404)
“内部的”是指下列类型:
proxy_pass:转发请求
worker_processes 1; events { worker_connections 1024; } http { include mime.types; default_type application/octet-stream; client_max_body_size 1024M; sendfile on; keepalive_timeout 1800; gzip on; upstream bdata { server 192.168.0.115:8085; } server { listen 80; server_name 域名; charset utf-8; # 在请求该路径下的文件后, 执行after_apirelease, 请求你的服务端接口将本次数据记录 location ^~ /bdata/app/query/apirelease/ { proxy_pass http://bdata; proxy_set_header Host $host:$server_port; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-NginX-Proxy true; proxy_http_version 1.
<template> <div style="width:100%;" v-resize="bodyResize"> <div ref='echartsSankeyRef' style="width:100%;height:500px"></div> </div> </template> <script> import echarts from 'echarts' import { reactive, ref, toRefs, computed, watch, onMounted } from '@vue/composition-api' let option = { tooltip: { trigger: 'item', triggerOn: 'mousemove' // formatter: (params) => { // console.log(params) // let { source, target, value } = params.data // return `${source}-->${target}:${value}` // } }, series: { type: 'sankey', // 桑基图 是一种特殊的流图(可以看作是有向无环图) layout: 'none', orient: 'horizontal', // 布局方向 left: 0, bottom: 0, right: 0, // 桑基图的高亮状态。 emphasis: { focus: 'adjacency' // 聚焦关系图中的邻接点和边的图形 }, // 描述了每个矩形节点中文本标签的样式。 label: { show: true, // https://echarts.
ESP32/ESP8266自动下载电路原理解析瞧这里:ESP8266/ESP32自动下载电路原理分析
其中 EN引脚上的RC电路必不可少,如取值不当会导致不能实现自动下载。
经常听人说有ESP32 UART自动下载不可用,而换了上电自复位电容就正常了的情况。今天看下实际波形。
手头有一个ESP32电路,其 R=10K,C=10uF,自动下载时的波形如下。
黄 - EN
蓝 - BOOT(GPIO0)
波形不好看,但能够实现自动下载功能。
查了ESP32的技术规格书,esp32_datasheet_cn
按照手册的说法,高电平最小值为VDD的0.75倍。VDD为3.3V时,高电平最小阈值为 2.475V。
上图选取的触发电平为 1.2V,之后BOOT脚均为高电平,按道理其不具备自动下载的条件,但实际可行。兴许是EN的电平阈值与数字IO的不同,没准比1.2V还要低一些。
参照官方原理图,改为 R=10K,C=1uF。再次观察。
黄 - EN
蓝 - BOOT(GPIO0)
一切正常,与原理假想的相符。如果再遇到ESP32/ESP8266不能自动下载,这回知道该怎么做了吧。
目录
一.关系的完整性
二.实体完整性
三.参照完整性
四.用户自定义完整性
一.关系的完整性 关系的完整性是指关系中的数据及具有关联关系的数据间必须遵循的制约条件和依存关系,以保证数据的正确性、有效性和相容性。
关系模型中的三类完整性约束:
实体完整性(Entity Integrity)参考完整性(Referential Integrity)用户自定义完整性(User-defined Integrity) 实体完整性和参考完整性是关系模型必须满足的完整性约束条件,被称作是关系的两个不变性,应该由关系系统自动支持。
二.实体完整性 指主属性值不能取空null,它具有唯一标志性--主码约束性。
实体完整性保证关系中的每个元组都是可识别的和唯一的。
表中不允许存在如下记录:
无主键值的记录主键值相同的记录 原因:实体必须可区分。 例如:其中学号为主键。
学号姓名年龄性别专业000001张三18男法学000002李四18男人工智能000001张三18男法学 在上表中就出现了主键值重复的情况,当在表中定义了主键时,数据库管理系统会自动保证数据的实体完整性,即保证不允许存在主键值为空的记录以及主键值重复的记录。
三.参照完整性 也称为引用完整性,指外码或者空或者与其对应关联表的主码相等--外码约束性。
在关系模型中,实体以及实体之间的联系都是用关系来表示的参照完整性就是描述实体之间的联系的参照完整性一般是指多个实体或者关系之间的关联关系参照完整性规则就是定义外键与被参照的主键之间的引用规则外键一般应符合:或者值为空或者等于其所参照的关系中的某个元组的主键值外码不能是这个关系(参照关系)的主码 以选课为例:
选课表中的学号就称为选课表里的一个外码,它对应的是学生表中的学号。其中,选课关系为参照关系,学生关系为被参照关系。
四.用户自定义完整性 也叫域完整性(Domain Integrity)或者语义完整性,是对数据表中字段属性的约束,它包括字段的值域、类型及有效规则等。
是针对某一具体应用领域定义的数据约束条件反映某一具体应用所涉及的数据必须满足应用语义的要求实际上就是指明关系中属性的取值范围,防止属性的值与应用语义矛盾关系模型应提供定义和检验这类完整性的机制,以便用统一的系统方法处理它们,而不要由应用程序承担这一功能
EtherCAT(以太网控制自动化技术)是一个以以太网为基础的开放架构的现场总线系统,EterCAT名称中的CAT为ControlAutomation Technology(控制自动化技术)首字母的缩写。最初由德国倍福自动化有限公司(Beckhoff AutomationGmbH)研发。EtherCAT为系统的实时性能和拓扑的灵活性树立了新的标准,同时,它还符合甚至降低了现场总线的使用成本。EtherCAT的特点还包括高精度设备同步,可选线缆冗余,和功能性安全协议(SIL3)。
Ethernet/IP是一个面向工业自动化应用的工业应用层协议。它建立在标准UDP/IP与TCP/IP协议之上,利用固定的以太网硬件和软件,为配置、访问和控制工业自动化设备定义了一个应用层协议西蒙公司开发
PROFINET由PROFIBUS国际组织(PROFIBUS International,PI)推出,是新一代基于工业以太网技术的自动化总线标准。作为一项战略性的技术创新,PROFINET为自动化通信领域提供了一个完整的网络解决方案,囊括了诸如实时以太网、运动控制、分布式自动化、故障安全以及网络安全等当前自动化领域的热点话题,并且,作为跨供应商的技术,可以完全兼容工业以太网和现有的现场总线(如PROFIBUS)技术,保护现有投资。
PROFINET是适用于不同需求的完整解决方案,其功能包括8个主要的模块,依次为实时通信、分布式现场设备、运动控制、分布式自动化、网络安装、IT标准和信息安全、故障安全和过程自动化。
MODBUS/TCP是简单的、中立厂商的用于管理和控制自动化设备的MODBUS系列通讯协议的派生产品。显而易见,它覆盖了使用TCP/IP协议的 “Intranet”和“Internet”环境中MODBUS 报文的用途。协议的最通用用途是为诸如PLC’s,I/O模块,以及连接其它简单域总线或I/O模块的网关服务的。
MODBUS/TCP协议是作为一种(实际的)自动化标准发行的。既然MODBUS已经广为人知,该规范只将别处没有收录的少量信息列入其中。然而,本规范力图阐明MODBUS中哪种功能对于普通自动化设备的互用性有价值,哪些部分是MODBUS作为可编程的协议交替用于PLC’s的“多余部分”。
它通过将配套报文类型“一致性等级”,区别那些普遍适用的和可选的,特别是那些适用于特殊设备如PLC’s的报文。
POWERLINK=CANopen+Ethernet
鉴于以太网的蓬勃发展和CANopen在自动化领域里的广阔应用基础,EthernetPOWERLINK 融合了这两项技术的优点和缺点,即拥有了Ethernet的高速、开放性接口,以及CANopen在工业领域良好的SDO 和PDO 数据定义,在某种意义上说POWERLINK就是Ethernet 上的CANopen,物理层、数据链路层使用了Ethernet介质,而应用层则保留了原有的SDO和PDO对象字典的结构
虽然这些工业以太网都是国际标准,但是指的是IEC 61784里的标准,但是这些工业以太网不都是标准的以太网。即这些工业以太网并不都是符合IEEE802.3U的标准,这当中只有Modbus-TCP和EtherNet/IP是符合IEEE802.3U的,只有符合IEEE802.3U标准的,才能与IT和以太网将来的发展相兼容。而不符合IEEE802.3U标准的,基本上可以讲不是以太网,它们都对以太网进行了修改,或者是硬件或者是软件,已经不是以太网了。
各种工业以太网的区别其实主要就是协议的区别,其中最主要的还是应用层协议的区别,我们知道,按照ISO的参考模型,网络被划分为7层。
a. Modbus TCP和EtherNet/IP的区别主要是应用层不相同,ModbusTCP的应用层采用Modbus协议,而EtherNet/IP采用CIP协议,这两种工业以太网的数据链路层采用的是CSMA/CD,因此是标准的以太网,另外,这两种工业以太网的网络层和传输层采用TCP/IP协议族。还有一个区别是,Modbus协议中迄今没有协议来完成功能安全、高精度同步和运功控制等,而EtherNet/IP有CIPSafety、CIP Sync和CIP Motion来完成上述功能,所以才有Schneider加入ODVA,成为ODVA的核心成员来推广EtherNet/IP。由于这两种网络都是标准的TCP/IP以太网,所以所有标准以太网节点都可以接入这两种网络。
b. b. 至于EthernetPowerLink(EPL), Ethernet PowerLink就是个怪胎,PowerLink虽然在物理层和数据链路层还是采用标准的以太网,但是它又添加了另一个数据链路层,此EPL数据链路层在结构上为于以太网数据链路层之上。我们知道数据链路层的一个子层的MAC(介质访问)层的作用是[color=#FF0000]决定哪一个节点可以占有总线,也即决定哪个节点一个发送数据[/color]。所以本来由以太网的数据链路层来决定哪一个节点占用总线,现在它被位于它之上的EPL数据链路层给架空了,由这个EPL数据链路层通过软件的方式来决定哪个节点发送数据。所有在这样的一个EPL工业以太网系统中,不能使用交换机,只能使用HUB,所以对100M的网络,EPL总的带宽是小于100m,一盘情况下只有40-50M,而如果采用交换机的工业以太网,它的带宽可以达到大几百M,另外在EPL网络上,所有的节点都要实现EPL数据链路。没有实现EPL数据链路层的节点不能接入此网络。
c. PROFINET分为原来划分为v1,v2,v3,现在一般称为ProfiNetCBA、ProfiNet IO和ProfiNet IRT.也就是通过以太网来实现对等通讯、实时控制和运动控制。v1采用TCP/IP协议,采用标准的以太网,而V2和V3不采用tcp/ip协议,这两种都绕过tcp/ip协议,采用另外的网络层和传输层协议,开发ProfiNet采用开发人员人员认为tcp/ip协议增加了数据在网络中的传输延迟,其实这是一种误解,据美国密歇根大学的教授研究后认为数据在TCP/IP中的传输延迟很小,他们研究得出数据在经过TCP,IP栈时延迟只有不到100微秒,如果采用UDP/IP时就更小,同时他们研究也得出数据在不同应用层延时比较大,不同的协议延迟不一样,但是相差不是很大,从200us-800us不等,他们经过实验后认为以太网的基础设施(指交换机、网卡等)和TCP/IP协议并不是影响工业以太网实时性的主要原因,而认为应用层协议才是主要原因。所以密歇根大学的教授认为绕开TCP/IP协议没有丝毫的意义,反而由于缺少了TCP/IP协议,使得设备也就缺少了IT功能,与其它现场总线没有区别。 ProfiNet V3就更特别了,它不完全采用标准以太网的数据链路层,有一不时间采用以太网的数据链路层(CSMA/CD),而另外一部分时间采用自己的数据链路层,通过一个高精度的时间来完成。所以ProfiNet V3也就不是标准的以太网了,也就给Profinet v3带来如下的问题:不能采用标准的交换机、不能采用标准的以太网芯片、与企业网相连可能会出现问题,与标准以太网相连还要特殊的网关、添加和删除一个节点都需要重新组态网络和重新启动网络、至今没有千兆网络,还有最重要的是,当标准以太网以后发展了后,它不能与标准以太网相兼容,不具有将来以太网所应具有的功能。
d. EtherCat这种工业以太网也很奇怪,它们不使用标准的芯片,一般不使用交换机,软件也不是标准的,对以太网的数据帧进行了一些修改,我们知道一个数据帧只有一个源节点,但是对于EtherCat一个数据可能有多个源节点,即一个数据是由多个节点发送的数据组合而成的。所以对于这样的网络,标准的以太网设备也不能接入这样的网络。
我认为Ethernet/IP和ProfiNet这两种工业以太网都适合各个行业,并不象heidai讲的应用的行业不一样。首先这两种工业以太网都用于传输非实时数据,还可传输实时数据,即可以用于离散控制,也可用于过程控制(当然现在还不能用于本安应用)。其次,这两种工业以太网都可用于网络功能安全传输,Ethernet/IP有CIP Safety协议,而ProfiNet有Profisafe协议,还有在运动控制方面ProfiNet有 ProfiNet IRT,而EtherNet/IP则有CIP Safety,二者都可以用于中高端的运动控制。最后两者都有基于IEEE1588的高精度时钟同步。而Modbus TCP,EtherCat和PowerLink,都只能完成部分控制任务,如Modbus TCP一般只作常规IO实时和非实时数据。而EtherCat和PowerLink则更象是为运动控制而开发的,这二者好像没有功能安全、在PLC和DCS控制方面也没有得到大自动化公司的支持,况且这两者又对以太网进行修改,一个在软件,另一个在软件和硬件方面都进行了修改,都不能兼容标准的以太网设备,个人认为这样做得不偿失,为满足运动控制而不能兼容已有的标准的以太网设备而开发的工业以太网并不是以太网,与其说是工业以太网还不如说是另一种现场总线。
我认为工业以太网的竞争将会在Ethernet/IP和ProfiNet间进行,而其它工业以太网都是这两者的陪衬,将会逐渐退出市场。
EtherNet/IP以后将由罗克韦尔自动化、Omron、施耐德和思科公司来推动,而ProfiNet将由业界老大西门子公司带领一些小公司去奋斗,由国内PLC厂商中的老二、老三和老五对老大,不知谁将引导未来。
其实,工业以太网里还有几个怪胎,举两个例吧:
SynqNet: 丹纳赫主导的,几乎只用在运动控制,而且据说只用在了半导体机械行业(奇怪的是,不才也搞半导体机械很久了,却从来没看到过SynqNet,孤陋寡闻啊)。只用了以太网的硬件,完全和我们平常说的以太网没有任何关系,连MAC层都没有。当然如此运用,速度性能当然好,但未来难说。
Sercos III: 光纤SercosII的新一代以太网版本,背后推手是博世力士乐,只用在运动控制。也基本上是只用了以太网底层硬件,系统里竟然连switch都不允许用。速度当然快,但只比SercosII快了一倍。估计用了SercosII的用户,谁会去更新到一个没快了多少的新系统啊,还没问世,就已经不被业界看好了。
我个人认为,最后一定是大西洋两岸的两大巨人之间的角力,就像以前的现场总线战争,最后还不是Profibus和DeviceNet,别的都只能当陪衬的角色?
当然,现在大家都在看中国这个大西洋两岸以外的单一最大市场,中国把砝码放在谁这一边,可能会使天平倾斜一点。但最后,肯定两者都会存在的。我个人认为,咱们应该选Ethernet/IP这一边站
中国用户和制造商应选择Ethernet/IP还是ProfiNet,各人的看法有所不同,不过我认为firstrazor所说的没错,有于ProfiNet采用了专门的芯片、网卡、交换机等以太网基础设施,虽然ProfiNet应用层协议是公开的,但这些芯片却是专用,国内的制造商要想开发符合ProfiNet标准的设备,确要依赖于这些芯片,受制于提供芯片的公司,也就是西门子公司,因此可以将ProfiNet并不是完全开放的。而相反,Ethernet/IP不论是在软件还是硬件上都是标准和开放的,国内的工业以太网制造商还是选择EtherNet/IP为好,至于最终用户的选择,当然是从可靠性、价格、兼容性和可替换性方面考虑,可靠性方面,二者没有明显区别,在其它方面Ethernet/IP具有明显的优势
注:SQL语句中的关键字和函数大小写不敏感。
SQL语句执行顺序: from-->where-->group by -->having --- >select --> order
第一步:from语句,选择要操作的表。
第二步:where语句,在from后的表中设置筛选条件,筛选出符合条件的记录。
第三步:group by语句,把筛选出的记录进行分组。
第四步:having语句,设置条件筛选分组后的数据。
第五步:select语句,选取经过上述流程后的结果集。
第六步:order by语句:将select后的结果集按照顺序展示出来。
注意:
掌握SQL语句执行流程非常重要,是理解并写好SQL语句的前提,根据实际业务逻辑要执行的数据库操作对应到SQL语句的执行流程能够帮助我们快速写出相应功能的标准SQL语句。
select: 作用:选取结果集。位置:位于SQL语句开始。 from: 作用:from后跟要操作的数据表。数据表形式:单个表、多个并列的表、多个进行join的表。位置:位于select之后。 where: 作用:设置条件,过滤记录。位置:位于from之后。 where语句中的运算符: 运算符描述=等于<>不等于。注:一些版本中也可为!=。>大于<小于>=大于等于<=小于BETWEEN 在某个范围内LIKE匹配某种模式IN在多个可能值之中 where语句中的条件类型: 逻辑运算:
AND:且,同时满足多个条件的值。OR:或,满足多个条件中至少一个即可。 特殊条件:
IS NULL:空值判断。
BETWEEN:在范围之间的值。IN:在多个可能值之中。LIKE:模糊查询。 group by: 作用:用于结合结合聚合函数,感觉一个列或多个列对结果集进行分组。位置:一般位于where后或者SQL语句末尾位置。 having: 作用:筛选分组后的各组数据,一般和聚合函数结合使用。位置:一般位于SQL语句末尾。 常用聚合函数:
函数作用sum(列名)求和max(列名)最大值min(列名)最小值avg(列名)平均值first(列名)第一条记录last(列名)最后一条记录count(列名)统计记录数 注:count(*)为统计所有记录数 order by: 作用:用于对结果集按照一个或者多个列进行排序。位置:一般位于SQL语句末尾。 排序:
默认按照升序对记录进行排序,如果按照降序对记录进行排序,需加DESC关键字。order by多列时,先按照第一个column_name排序,再按照第二个column_name排序。 排序实例:
order by A # A升序排列 order by A desc,B # A 降序(优先),B 升序排列 order by A ,B desc # A 升序(优先),B 降序排列 where和having区别: where在group by前, having在group by 之后。where中不能使用聚合函数,having中可以使用聚合函数。原因:因为聚合函数是针对结果集进行的,但where是在查询结果集之前进行,故where中不能使用聚合函数;having是针对结果集做筛选的,故一般把聚合函数放在having中。
1.创建软链接
ln -s [新的源文件或目录] [软链接文件]
例:ln -s /data/html/ /var/www/html
需要html目录不存在
2.修改软链接
就是重新软链即可
ln -sf /data/html/ /var/www/html
3.删除软链接
rm –rf ./软链接名称 --仅仅删除软链接,源文件没有被删除
rm -rf ./软链接名称/ --把软链接以及软链接指向下的内容删除
一般使用:ln -s -f 源目录 新目录
目录
1. 前言
2. DMA简介
2.1 DMA概念 2.2 DMA原理和实现 2.3 DMA传输过程
2.4 DMA传输需要的参数
2.4.1 transfer size
2.4.2 transfer width
2.4.3 burst size
2.4.4 DMA传输方式
3. Linux DMA子系统体系结构
4. DMA控制器与CPU怎样分时使用内存
4.1 停止CPU访问内存
4.2 周期挪用
4.3 DMA与CPU交替访问内存
5. DMA 导致的问题
5.1 关于流式 DMA 和一致性 DMA 的区别
6. 参考文章
1. 前言 最近在学习Linux DMA相关的内容,会从DMA控制器驱动(provider,提供DMA服务)和使用DMA控制器提供的服务的外设驱动(consumer)这两个方面,来分析介绍DMA Engine的体系结构。
2. DMA简介 2.1 DMA概念 DMA(direct memory access),即不经过CPU,直接访问内存。因为不管是memory和memory之间还是memory和设备之间进行数据搬运,对CPU来说都是枯燥乏味的,且非常浪费CPU的时间,造成CPU无法及时处理一些实时的事件。因此,为了解放CPU,可以让CPU在搬运数据的这段时间可以去做更有意义的事情,工程师们就设计出来一种专门用来搬运数据的器件,即DMA控制器,让它来协助CPU进行数据搬运工作,下图是DMA的硬件示意图。
2.2 DMA原理和实现 DMA 的原理:即CPU将需要迁移的数据的位置告诉给DMA,包括源地址,目的地址以及需要迁移的长度,然后启动DMA设备,DMA设备收到命令之后,就去完成相应的操作,最后通过中断反馈给CPU。
DMA的实现:在实现DMA传输时,是DMA控制器掌控着总线,也就是说,这里会有一个控制权转让的问题,我们当然知道,计算机中权限最大的就是CPU,这个DMA暂时掌管的总线控制权当前也是CPU赋予的,在DMA完成传输之后,会通过中断通知CPU收回总线控制权。
2.3 DMA传输过程 DMA传输的过程:一个完整的DMA传输过程必须经过DMA请求、DMA响应、DMA传输、DMA结束这四个阶段。
DMA 请求:CPU对DMA控制器初始化,并向I/O接口发出操作命令,I/O接口提出DMA请求。
DMA 响应:DMA控制器对DMA请求判别优先级以及屏蔽位,向总线裁决逻辑提出总线请求,当CPU执行完成当前的总线周期之后即可释放总线控制权。此时,总线裁决逻辑输出总线应答,表示DMA已经就绪,通过 DMA 控制器通知I/O接口开始DMA传输。
废话部分: 前些日子在网易云音乐,偶然的机会入坑了有声书《北派盗墓笔记》,后来一边看原文,一边听小说,收费之后就只看了。
本来在手机上看,后来想在kindle上看。但是由于小说还没有更新完,就只能隔一段时间,下载一部分,复制到kindle上,然后继续重复这个操作。
网上没有现成的txt可以下载,那么就只能复制粘贴,然后做成awz文件。鉴于重复的机械性工作很无聊,就写了Python做爬虫将小说爬取下来。
正文部分: 爬取分为两种思路:
1.找到小说目录页面,然后通过目录里提供的章节链接一个一个的保存内容
2.找到一篇内容,通过下一页的按钮的链接,一个个的保存下一篇的内容
在网上随手一搜就有很多现成的项目,于是我就复制了一个代码,然后进行修改
参考的文章:https://www.jianshu.com/p/2fd0739c2df2
这个采用的是第二个思路,然后这个网址有一个问题,它会把一个章节,分割成两个章节,进而变成两个网页很不方便,于是就换了一个网站作为书籍的来源
话不多说,上代码吧
# -*- coding: utf-8 -*- """ Created on Mon Sep 19 10:14:00 2022 @author: Martin """ import re import requests import parsel # 网页提取文字xpath、re、css from unicodedata import normalize # normalize方法将Unicode字符转换为正常字符 headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36 Edg/83.0.478.45'} def paper_download(url): """ 适用网站:https://www.exiaoshuo.com """ response = requests.get(url=url, headers=headers) selector = parsel.
转自:
Java.lang.Byte类之parseByte(String s, int radix)方法的简介说明
下文笔者将讲述Byte类中的parseByte(String s, int radix)方法的功能简介说明,如下所示:
parseByte(String s, int radix)方法的功能
parseByte(String s, int radix)方法:
基于第二个参数将字符串解析为字节
注意事项: 1.参数中的字符串必须为十进制数字(数字的前面可以有一个加号或减号) 2.以下情况将抛出异常信息(NumberFormatException) 第一个参数是null或零长度的字符串。 基数小于Character.MIN_RADIX或大于Character.MAX_RADIX。 用字符串表示的值不是byte类型的值 parseByte(String s, int radix)方法语法
public static byte parseByte(String s, int radix) throws NumberFormatException 参数说明: s:一个字符串(字符串内容为十进制数字,前面可以有一个加号或减号) radix:运用基数当解析s 返回值: 返回一个使用十进制表示的字节值 例:
package com.java265.other; import org.junit.Test; public class other { /** * java265.com 测试示例分享 */ @Test public void test() { /** * Byte类 parseByte方法的示例 */ Byte b1, b2; b1 = Byte.
概述 本文主要讲到了openssl的基本使用方法,开发环境为windows,开发工具为VS2019.本文主要是说明openssl如何使用,不介绍任何理论知识,如果有不懂的,请自行百度。个人建议下一个everything查询工具,真的很好用,比window自带的查询快了很多,可以查询自己想要的文件
OPENSSL安装 安装过程网上有很多,OPENSSL安装,注意你安装的OPENSSL的版本以及位数(32位或者64位),假如我安装的是64位的openssl,安装目录为D:\Program Files\OpenSSL-Win64,你可以自行选择你的安装目录,安装完成后,查看安装的openssl版本,使用控制台输入openssl version即可
秘钥key和公钥的生成 在控制命令行中输入以下命令:
openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -sha256 -days 365 网上有很多生成秘钥和公钥的文章,不过都没成功,最后在stackoverflow找到了可以用的方法,原文地址为:openssl秘钥和公钥的生成,以下是截图
Enter PEM pass phrase:提示输入pem文件的密码,注意,后面要用到这个密码,可以使用自己常用的密码,输入后会再次确认密码,然后就是一些基本信息,可以默认为空。截图如下,基本上这时候就得到了秘钥key.pem和公钥cert.pem,后面要用到这2个文件。,生成的位置为当前目录,比如我的就是在C:\Users\86138,即控制台的显示目录。
项目设置 使用VS创建一个控制台项目,创建一个客户端和服务器项目,由于我下载的是64位,openssl3.0版本。因此我项目也是64位的。
项目的配置,服务器端和客户端都是相同配置,这里我就只说一个即可,主要是设置openssl的lib和头文件的路径,这和使用任外部库都是一样的。截图如下,注意我的openssl安装位置为D:\Program Files\OpenSSL-Win64,请选择你安装位置即可。
预处理器里添加2个定义:CRT_SECURE_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;
附加依赖项:libssl.lib;openssl.lib;libcrypto.lib;liblegacy.lib;
最后将前面生成的cert.pem和key.pem放到exe目录下,为什么放到这个目录,是因为下面的代码用到的这2个文件是当前目录,不管怎么样,只要能找到这2个文件即可。
配置很简单,就上面几步,基本上就可以了。
代码部分 客户端代码 #include <stdio.h> #include <errno.h> #include <malloc.h> #include <string.h> # include <winsock2.h> #include <ws2tcpip.h> #include <openssl/ssl.h> #include <openssl/err.h> #define FAIL -1 #pragma comment(lib, "Ws2_32.lib") //Added the LoadCertificates how in the server-side makes. int OpenConnection(const char* hostname, int port) { SOCKET sd; struct hostent* host; struct sockaddr_in addr; WORD wVersionRequested; WSADATA wsaData; int err; /* Use the MAKEWORD(lowbyte, highbyte) macro declared in Windef.
一、JAAS配置# Zookeeper配置JAAS
zookeeper环境下新增一个配置文件,如zk_server_jass.conf,内容如下:
Server {
org.apache.kafka.common.security.plain.PlainLoginModule required
username=“admin”
password=“admin”
user_admin=“admin”;
};
其作用是:在改zookeeper节点创建了一个Server节点,其中
org.apache.kafka.common.security.plain.PlainLoginModule required 是加密机制为PLAIN的处理类。在kafka-client包下
username、password是zookeeper之间通讯的用户名和密码,
user_admin="admin"的结构是user_[username]=[password],定义kafka-broker(zookeeper客户端)连接到zookeeper时用的用户名和密码。
注意jaas配置都要以;结尾
Kafka-Broker配置JAAS
在kafka-broker环境下新增配置,如kafka_server_jaas.conf,内容如下:
用于broker和zookeeper之间的认证,对应zk_server_jass.conf中的【user_admin=“admin”】配置 Client {
org.apache.kafka.common.security.plain.PlainLoginModule required
username=“admin”
password=“admin”;
};
定义kafka客户端与broker的认知信息 KafkaServer {
org.apache.kafka.common.security.plain.PlainLoginModule required
username=“admin”
password=“admin”
user_admin=“admin”
user_alice=“alice”;
};
Client:用于broker和zookeeper之间的认证,对应zk_server_jass.conf中的【user_admin=“admin”】配置
KafkaServer:集群中,broker之间用节点中的username,password进行通讯
KafkaServer:kafka客户端(producer,consumer)连接broker时,用该配置下user_[username]=[password]结构配置的账号密码登录
Kafka-Producer配置JAAS
在kafka-broker环境下新增配置,如kafka_producer_jaas.conf,内容如下:
Client {
org.apache.kafka.common.security.plain.PlainLoginModule required
username=“admin”
password=“admin”;
};
Client:客户端登录服务端认证信息,对应broker配置中user_[username]=[password]定义的配置
Kafka-Consumer配置JAAS
新增kafka_consumer_jaas.conf,配置同producer
从以上配置可以得出结论:
username=“admin” password="admin"配置格式有两种场景
1、是用于服务端集群之间的认证信息,定义在Server节点里
2、用户登录服务端的认证信息,定义在Client节点里
user_[username]=[password]配置定义在Server节点里,用于提供给客户端登录。
以上关系是:Zookeeper:Kafka-Broker关系里,Zookeeper是服务端,Kafka-Broker是客户端;Kafka-Broker:Kafka-Producer、Kafka-Consumer关系里,Kafka-Broker是服务端,Kafka-Producer、Kafka-Consumer是客户端
二、SASL配置# zookeeper的sasl配置
zookeeper.properties配置文件新增:
authProvider.1=org.apache.zookeeper.server.auth.SASLAuthenticationProvider
requireClientAuthScheme=sasl
jaasLoginRenew=3600000
修改zookeeper-server-start.bat,新增一个配置KAFKA_OPTS
SetLocal
set KAFKA_OPTS=-Djava.
目录
数据库分类:
数据库的操作:
库的操作:
表的操作:
增删改查:
新增 inert into:
删除 delete: 修改 updata:
查询 select: 关系运算符:
逻辑运算符:
查询进阶:
数据库分类: 数据库大体可以分为 关系型数据库 和 非关系型数据库
关系型数据库(RDBMS):简单来说,关系模型指的就是二维表格模型,而一个关系型数据库 就是由二维表及其之间的联系所组成的一个数据组织。
常用的关系型数据库如:
1. Oracle:甲骨文产品,适合大型项目,适用于做复杂的业务逻辑,如ERP、OA等企业信息系统。收费。
2. MySQL:属于甲骨文,不适合做复杂的业务。开源免费。
3. SQL Server:微软的产品,安装部署在windows server上,适用于中大型项目。收费。
4. MariaDB: 基于 MySQL 的一个开源数据库产品。
非关系型数据库: (了解)不规定基于SQL实现。现在更多是指NoSQL数据库,如:
1. 基于键值对(Key-Value):如 memcached、redis 2. 基于文档型:如 mongodb 3. 基于列族:如 hbase 4. 基于图型:如 neo4j
数据库的操作: 运行mysql客户端, 连接服务器:
mysql -uroot -p (-u指定用户名, -p需要输入密码)
(运行这句之后才是在数据库中打SQL语句,这步是linux的指令)
SQL语句注意事项: sql语句不区分大小写、不区分单引号和双引号;
每一条sql语句默认都是以英文的分号 ' ; ' 作为结尾;
内存溢出是Android开发中一个老大难的问题,相关的知识点比较繁杂,绝大部分的开发者都零零星星知道一些,但难以全面。本篇文档会尽量从广度和深度两个方面进行整理,帮助大家梳理这方面的知识点(基于Java)。
一、Java内存的分配
这里先了解一下我们无比关心的内存,到底是指的哪一块区域:
如上图,整个程序执行过程中,JVM会用一段空间来存储执行期间需要用到的数据和相关信息,这段空间一般被称作Runtime Data Area (运行时数据区),这就是咱们常说的JVM内存,我们常说到的内存管理就是针对这段空间进行管理。Java虚拟机在执行Java程序时会把内存划分为若干个不同的数据区域,根据《Java虚拟机规范(Java SE 7版)》的规定,Java虚拟机所管理的内存包含了5个区域:程序计数器,虚拟机栈,本地方法栈,GC堆,方法区。如下图所示:
各个区域的作用和包含的内容大致为:
(1)程序计数器:是一块较小的内存空间,也有的称为PC寄存器。它保存的是程序当前执行的指令的地址,用于指示执行哪条指令。这块内存中存储的数据所占空间的大小不会随程序的执行而发生改变,所以,此内存区域不会发生内存溢出(OutOfMemory)问题。
(2)Java虚拟机栈:简称为Java栈,也就是我们常常说的栈内存,它是Java方法执行的内存模型。Java栈中存放的是一个个的栈帧,每个栈帧对应的是一个被调用的方法。每一个栈帧中包括了如下部分:局部变量表、操作数栈、方法返回地址等信息。每一个方法从调用直至执行完成的过程,就对应着一个栈帧在虚拟机栈中入栈到出栈的过程。在Java虚拟机规范中,对Java栈区域规定了两种异常状况:1)如果线程请求的栈深度大于虚拟机所允许的深度,将抛出栈内存溢出(StackOverflowError)异常,所以使用递归的时候需要注意这一点;2)如果虚拟机栈可以动态扩展,而且扩展时无法申请到足够的内存,就会抛出OutOfMemoryError异常。
(3)本地方法栈:本地方法栈与Java虚拟机栈的作用和原理非常相似,区别在与前者为执行Nativit方法服务的,而后者是为执行Java方法服务的。与Java虚拟机栈一样,本地方法栈区域也会抛出StackOverflowError和OutOfMemoryError异常。
(4)GC堆:也就是我们常说的堆内存,是内存中最大的一块,被所有线程共享,此内存区域的唯一目的就是存放对象实例,几乎所有的对象实例都在这里分配。它是Java的垃圾收集器管理的主要区域,所以被称为“GC堆”。当无法再扩展时,将会抛出OutOfMemoryError异常。
(5)方法区:它与堆一样,也是被线程共享的区域,一般用来存储不容易改变的数据,所以一般也被称为“永久代”。在方法区中,存储了每个类的信息(包括类名,方法信息,字段信息)、静态变量、常量以及编译器编译后的代码等内容。Java的垃圾收集器可以像管理堆区一样管理这部分区域,当方法区无法满足内存分配需求时,将抛出OutOfMemoryError异常。
我这里只做了一些简单的介绍,如果想详细了解每个区域包含的内容及作用,可以阅读这篇文章:【朝花夕拾】Android性能篇之(二)Java内存分配。
二、Java垃圾回收
垃圾回收,即GC(Garbage Collection),回收无用内存空间,使其对未来实例可用的过程。由于设备的内存空间是有限的,为了防止内存空间被占满导致应用程序无法运行,就需要对无用对象占用的内存进行回收,也称垃圾回收。 垃圾回收过程中除了会清理废弃的对象外,还会清理内存碎片,完成内存整理。
1、判断对象是否存活的方法
GC堆内存中存放着几乎所有的对象(方法区中也存储着一部分),垃圾回收器在对该内存进行回收前,首先需要确定这些对象哪些是“活着”,哪些已经“死去”,内存回收就是要回收这些已经“死去”的对象。那么如何其判断一个对象是否还“活着”呢?方法主要由如下两种:
(1)引用计数法,该算法由于无法处理对象之间相互循环引用的问题,在Java中并未采用该算法,在此不做深入探究;
(2)根搜索算法(GC ROOT Tracing),Java中采用了该算法来判断对象是否是存活的,这里重点介绍一下。
算法思想:通过一系列名为“GC Roots” 的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链(Reference Chain),当一个对象到GC Roots没有任何引用链相连(用图论来说就是从GC Roots到这个对象不可达)时,则证明对象是不可用的,即该对象是“死去”的,同理,如果有引用链相连,则证明对象可以,是“活着”的。如下图所示: 那么,哪些可以作为GC Roots的对象呢?Java 语言中包含了如下几种:
1)虚拟机栈(栈帧中的本地变量表)中的引用的对象。
2)方法区中的类静态属性引用的对象。
3)方法区中的常量引用的对象。
4)本地方法栈中JNI(即一般说的Native方法)的引用的对象。
5)运行中的线程
6)由引导类加载器加载的对象
7)GC控制的对象
拓展阅读:
Java中什么样的对象才能作为gc root,gc roots有哪些呢?
2、对象回收的分代算法
已经找到了需要回收的对象,那这些对象是如何被回收的呢?现代商用虚拟机基本都采用分代收集算法来进行垃圾回收,当然这里的分代算法是一种混合算法,不同时期采用不同的算法来回收,具体算法我后面会推荐一篇文章较为详细地介绍,这里仅大致介绍一下分代算法。
由于不同的对象的生命周期不一样,分代的垃圾回收策略正式基于这一点。因此,不同生命周期的对象可以采取不同的回收算法,以便提高回收效率。该算法包含三个区域:年轻代(Young Generation)、年老代(Old Generation)、持久代(Permanent Generation)。
1)年轻代(Young Generation)
所有新生成的对象首先都是放在年轻代中。年轻代的目标就是尽可能快速地回收哪些生命周期短的对象。新生代内存按照8:1:1的比例分为一个Eden区和两个survivor(survivor0,survivor1)区。Eden区,字面意思翻译过来,就是伊甸区,人类生命开始的地方。当一个实例被创建了,首先会被存储在该区域内,大部分对象在Eden区中生成。Survivor区,幸存者区,字面理解就是用于存储幸存下来对象。回收时先将Eden区存活对象复制到一个Survivor0区,然后清空Eden区,当这个Survivor0区也存放满了后,则将Eden和Survivor0区中存活对象复制到另外一个survivor1区,然后清空Eden和这个Survivor0区,此时的Survivor0区就也是空的了。然后将Survivor0区和Survivor1区交换,即保持Servivor1为空,如此往复。当Survivor1区不足以存放Eden区和Survivor0的存活对象时,就将存活对象直接放到年老代。如果年老代也满了,就会触发一次Major GC(即Full GC),即新生代和年老代都进行回收。新生代发生的GC也叫做Minor GC,MinorGC发生频率比较高,不一定等Eden区满了才会触发。 2)年老代(Old Generation)
在新生代中经历了多次GC后仍然存活的对象,就会被放入到年老代中。因此,可以认为年老代中存放的都是一些生命周期较长的对象。年老代比新生代内存大很多(大概比例2:1?),当年老代中存满时触发Major GC,即Full GC,Full GC发生频率比较低,年老代对象存活时间较长,存活率比较高。此处采用Compacting算法,由于该区域比较大,而且通常对象生命周期比较长,compaction需要一定的时间,所以这部分的GC时间比较长。 3)持久代(Permanent Generation)
持久代用于存放静态文件,如Java类、方法等,该区域比较稳定,对GC没有显著影响。这一部分也被称为运行时常量,有的版本说JDK1.7后该部分从方法区中移到GC堆中,有的版本却说,JDK1.7后该部分被移除,有待考证。
3、内存抖动
不再使用的内存被回收是好事,但也会产生一定的负面影响。在 Android Android 2.
算法功底是程序员的灵魂,设计模式是程序员的骨架。
实现 int func(int n) 函数,或者int n换成double n
n整型时:假如返回类型是整数,结果只保留整数的部分,小数部分将被舍去;
n是double时,保留小数点后3位
(1)二分法求解(可以再优化) public class Test02 { public static void main(String[] args) { // FIXME 这里用5来测试 double N = 5; System.out.println(N + " 开根号保留三位小数后的值是:" + String.format("%.3f", func(N))); } static double func(double N) { double middle = 0; double left = 0; double right = N; // 这里以保留小数点后三位为例,保留小数点后三位对应的就是"1e-3" while (right - left > 1e-3) { // 第(1)步:middle = (left + right) / 2 middle = (left + right) / 2; if (middle * middle < N) { // 第(2.
在日常的开发工作中,我们时常会遇到导出Word文档报表的需求,比如公司的财务报表、医院的患者统计报表、电商平台的销售报表等等。
导出Word方式多种多样,通常有以下几种方式:
1. 使用第三方Java工具类库Hutool的Word工具类,参考网址为https://www.hutool.cn/docs/#/poi/Word生成-Word07Writer;
2. 利用Apache POI 和 FreeMarker模板引擎;
3. 第三方报表工具。
上面的几种方式虽然可以实现Word文档的导出,但有以下缺点:
第一种方式操作简单,但也只能生成简单的Word文档,无法生成有表格的Word文档;
第二种方式可以生成复杂的Word文档,但是还要进行Word转xml,xml转ftl的双重转换,不适合内容经常变更的Word文档;
第三种方式有时候不适合对格式要求严格的文档。
那么,有没有既简单又高效的导出Word的方法呢?答案是肯定有的。接下来我就来介绍一种用Java语言实现的,通过XDocReport和FreeMarker模板引擎生成Word文档的方法。
准备环境 开发语言:
Java7及以上的版本。
开发工具:
Eclipse/Idea。
第三方依赖库:
XDocReport、POI、Freemarker。
模板语言:
FreeMarker。
Word编辑器:
Microsoft 365或其他版本较高的Word编辑器。
示例Word模板 制作模板 Word模板如上图,可以看到,结构比较简单,包括两个部分,第一部分是纯文字和数字,第二部分主要是表格。我们在实际的开发过程中生成的报表几乎都是动态生成的,所以模板中的数字和表格里的数据都要替换成我们后台的实际数据。
替换Word模板中的动态变量,我们需要掌握两个知识点:
1.Word文档中的Word域,word域是引导Word在文档中自动插入文字、图形、页码或其他信息的一组代码。在这里我们可以把 Word域理解成标识符,这个标识符表示Word文档中要被替换的内容;
2.FreeMarker模板下的变量表达式,比如用${city}替换Word示例模板中的北京市。
了解了以上两个概念后,我们就可以动手编辑Word模板了,步骤如下:
1. 首先在Word模板中选中要替换的文本,在这儿拿标题中的"北京市"为例,然后键盘使用 Ctrl + F9 组合键将其设置为域,此时文本会被"{}"包围,接着鼠标右键选择【编辑域(E)...】:
2. 在弹出的对话框中,类别选择“邮件合并”,域名选择 "MergeField",域属性中的域名填入模版表达式${city},点击【确定】按钮:
3. 编辑后的效果如下:
4. 掌握替换文本的方法后,我们可以把Word模板第一部分需要替换的内容都替换成模板变量:
Word模板中表格数据的处理 表格中的数据实质上就是对集合的遍历。
表格数据的处理其实和上面对文本内容的处理是类似的,只不过要在Word模板中加上集合的变量,Java代码中也要有对集合进行特对的处理(这个在后面的代码展示部分会说)。
具体操作步骤如下:
1. 选定表格中要替换的文本,然后键盘使用 Ctrl + F9 组合键将其设置为域,接着鼠标右键选择【编辑域(E)...】:
2. 在弹出的对话框中,类别选择“邮件合并”,域名选择 "MergeField",域属性中的域名填入模版表达式${goods.num},点击【确定】按钮;
3. 重复步骤2,替换表格中的其他文本内容:
后台代码 添加依赖到pom.xml文件
<dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>4.
目录 什么是OpenCV安装OpenCV1.下载安装包2.解压缩3.下载CMake并完成配置4.下载依赖5.编译并安装6.OpenCV环境配置 代码示例图片处理视频处理虚拟机获取摄像头权限播放视频摄像头录制 参考资料 什么是OpenCV OpenCV是一个基于Apache2.0许可(开源)发行的跨平台计算机视觉和机器学习软件库,可以运行在Linux,Windows,Mac等操作系统上。
它轻量级而且高效——由一系列 C 函数和少量 C++ 类构成,同时提供了Python、Ruby、MATLAB等语言的接口,实现了图像处理和计算机视觉方面的很多通用算法。
在系统中安装了Opencv库后,我们就可以通过引入头文件的方式使用OpenCv中的各种算法,用于计算机视觉以及图像处理。
安装OpenCV 安装OpenCV的过程很复杂,可能会多次失败。建议有耐心多试几次。
系统:Linux(Ubuntu18.04.1)软件:OpenCv下载版本:4.6.0 1.下载安装包 下载地址:https://github.com/opencv/opencv/releases
github网站访问有时候很卡,有能力的可以使用魔法上网。
2.解压缩 下载好后,可以在文件夹中看见被下载好的压缩包文件(我的是在当前用户目录下)
在终端打开该路径,使用指令解压:
unzip opencv_4.x.zip 解压缩后可以看见文件夹。
3.下载CMake并完成配置 sudo apt-get cmake 下载完成后,在进入之前解压的文件夹,创建并进入一个build文件夹。
cd opencv_4.x mkdir build cd build 使用以下指令配置cmake:
cmake -DCMAKE_BUILD_TYPE=Release \ -DOPENCV_GENERATE_PKGCONFIG=ON \ -DCMAKE_INSTALL_PREFIX=/usr/local .. 这里我参考了博客:https://blog.csdn.net/spiremoon/article/details/105812303
之前我照着老师给的参考博客进行下载,在完成所有安装操作后,输入打印OpenCv版本的指令时会提示以下报错:
Package opencv4 was not found in the pkg-config search path. Perhaps you should add the directory containing `opencv4.pc’ to the PKG_CONFIG_PATH environment variable 原因是在完成安装后,OpenCv没有生成Opencv4.pc文件。在OpenCv4以前的版本是会自动生成该文件的。到了4版本,OpenCv默认不会自动生成.pc文件。因此在配置cmake时一定要带上如下参数:
前言 本文介绍注意力机制的概念和基本原理,并站在计算机视觉CV角度,进一步介绍通道注意力、空间注意力、混合注意力、自注意力等。
目录
前言
一、注意力机制
二、通道注意力机制
三、空间注意力机制
四、混合注意力机制 五、自注意力机制
六、注意力基础
6.1 注意力机制原理
6.2 注意力机制计算过程
一、注意力机制 我们可以通过眼睛看到各种各样的事物,感知世界上的大量信息;可以让自己免受海量信息的干扰,是因为人的选择能力,可以选择重要的信息,而忽视不重要信息。
举个例子,下面有一张图片,当我们看到这张图片的时候会下意识把注意力集中到熊猫的身上,而忽略背景。
即:在观看这幅图像的时候,并非能够对图片的所有信息给予相同的关注度,而是将注意力着重放在某个局部区域。
同样,希望网络也具有这种能力,从而在网络中引入了注意力机制。注意力机制,是对输入进行加权再输出,希望网络关注到的地方给较大的权重,不希望网络注意的地方给较小的权重。
再举个例子,在自然语言处理领域,在分析一句话的时候,并不是所有的词的信息都需要被关注,可以选择重要的词分析,即可理解句子所传达的语义。
二、通道注意力机制 通道注意力机制的代表模型是:压缩和激励网络(Squeeze-and-Excitation Networks,SENet)。SENet 分为压缩和激励两个部分,其中压缩部分的目的是对全局空间信息进行压缩,然后在通道维度进行特征学习,形成各个通对道的重要性,最后通过激励部分对各个通道进行分配不同权重的。
上图是SE模块的结构, 在压缩部分,输入的元素特征图的维度是 H×W×C,H、W 和 C 分别代表高度、宽度和通道数。压缩部分的功能是将维数从 H×W×C 压缩至1×1×C,即把 H×W 压缩为 1×1 维,这个过程由全局平均池化实现。
在激励部分,需要将压缩部分得到的 1×1×C 的维度融入全连接层,预测各个通道的重要程度,然后再激励到前面特征图对应通道上进行操作。采用简单的门控机制与Sigmoid 激活函数。
小结:在通道注意力机制,学习各个通道的重要性时,是先对特征图的空间进行压缩,然后在通道维度进行学习,得到各个通道的重要性。
三、空间注意力机制 空间注意力机制的代表模型是:空间变换神经网络(Spatial Transformer Networks,STN),STN 能够对各种形变数据在空间中进行转换并自动捕获重要区域特征。它能够保证图像在经过裁剪、平移或者旋转等操作后,依然可以获得和操作前的原始图像相同的结果。
举个例子,在MNIST 数字分类的中应用STN,该分类过程一共包含 4 个步骤:
MNIST中的数字,是经过随机平移、缩放和旋转处理;把它们输入到STN网络中;通过STN网络,预测前面输入数字的变换(是平移了?还是缩放了?或是旋转了?)STN网络预测出“变换前的数字”,即没经过变换的数字是怎样的最终进行分类预测 STN 网络包括局部网络、参数化网络采样(网络生成器)和差分图像采样。
局部网络:预测输入数字的变换(是平移了?还是缩放了?或是旋转了?)
网络生成器:获得输出特征图坐标点在输入特征图中坐标点的对应位置。
四、混合注意力机制 在混合注意力机制中,通道注意力和空间注意力可以通过串联、或者并联的方式进行组合。
混合注意力机制的代表模型是:卷积注意力模块(Convolutional Block Attention Module,CBAM),它包括通道注意力模块CAM、和空间注意力模块SAM。
CBAM的模型结构如下,它对输入的特征图,首先进行通道注意力模块处理;得到的结果,再经过空间注意力模块处理,最后得到调整后特征。
通道注意力模块CAM
CAM的输入是特征图,维度设为HxWxC;其中H是指特征图的高度,W是指宽度,C是指通道数。
它的思路流程是:
首先对输入的特征图,进行全局池化和平均池化;(在空间维度进行池化,压缩空间尺寸;便于后面学习通道的特征)然后将得到全局和评价池化的结果,送入到多层感知机中MLP学习;(基于MLP学习通道维度的特征,和各个通道的重要性)最后将MLP输出额结果,进行“加”操作,接着经过Sigmoid函数的映射处理,得到最终的“通道注意力值”。 计算公式如下:
空间注意力模块SAM
SAM的输入是CAM输出的特征图。
Linux下实现Mysql的主从复制 前言条件准备 配置主库配置主库步骤:1. 配置主库的配置文件2.重新启动mysql服务3.在主库中创建一个用户,用于进行主从库之间通信4.执行以下Sql,记录下File和Position的值 配置从库配置从库步骤:1.配置从库的配置文件2.重新启动mysql服务3.登录进去之后,配置关于主库的信息 测试是否主从复制有效 前言 本篇是基于CentOs7下,以及mysql8的版本进行配置主从复制 条件准备 已经安装好CentOs7系统的虚拟机两台两台虚拟机上都配置好了ip地址以及都安装好了mysql数据库第一台虚拟机的ip : 192.168.226.129第二台虚拟机的ip : 192.168.226.130 配置主库 任选一个虚拟机上的mysql作为主库,假设我选择ip地址为192.168.226.129的这台虚拟机上的mysql作为主库,选择ip地址为192.168.226.130的这台虚拟机上的mysql作为从库 配置主库步骤: 1. 配置主库的配置文件 一般来说mysql的配置文件都存放在/etc目录下,叫做my.cnf,但是mysql8默认是没有这个文件的,如果没有的话,需要自己手动创建,配置文件的内容在Linux下安装mysql里面有,使用命令:vim /etc/my.cnf添加以下内容在[mysqld]下 log-bin=mysql-bin #开启二进制日志 server-id=100 #服务器唯一标识,id不一定要是100,可以自定义数字,只要保证主库和从库的id不一样就行。 2.重新启动mysql服务 systemctl restart mysqld 3.在主库中创建一个用户,用于进行主从库之间通信 需要分两步进行:
第一步:create user 用户名 identified with 'mysql_native_password'by '密码'; 创建一个用户
第二步:grant replication slave on *.* to 用户名; 给该用户授权
//登录主库,并输入主库密码 mysql -uroot -p //创建一个用户,作为信任用户进行主从库之间通信 mysql> create user xiaoming identified with 'mysql_native_password'by 'Root@123456'; mysql> grant replication slave on *.* to xiaoming; //刷新 mysql> flush privileges; 4.
前言
目录
一、扫雷游戏的实现步骤
1.打印目录
2.初始化棋盘
3.打印棋盘
4.随机布置雷
5.排雷
二、具体代码展示
1.game.h
2.game.c
3.test.c
前言 扫雷游戏是我童年的回忆,我感觉对我的感触还挺深的,在这里实现一下扫雷游戏,致敬我那回不去的童年。
一、实现扫雷的步骤 注:这里各个数组的数都进行了预定义,以便后续进行修改。
#define ROW 9 #define COL 9 #define ROWS ROW + 2 #define COLS COL + 2 #define COUNTS 12 1.打印目录
void menu() { printf("******************\n"); printf("**** 1.play ****\n"); printf("**** 0.exit ****\n"); printf("******************\n"); } 2.初始化棋盘
这里使用两个二维数组一个用于展示,一个用来布置雷。
(1)布置雷的数组全部初始化为‘0’,
(2)展示的数组全部初始化为 ‘*’。
这里需要将初始化为我们想要的字符的进行传参。
void init_board(char board[ROWS][COLS], int rows, int cols, char ret) { int i = 0; int j = 0; for (i = 0; i < rows; i++) { for (j = 0; j < cols; j++) { board[i][j] = ret; } } } 3.
我们用SolidWorks做好三维图纸后,必然要做的工作就是导出工程图纸,但是有时可能脑子一抽选错了模板,但是工程图导出工作做到一半再去换模板重新对工程图进行修改设置是一件非常麻烦而且浪费时间的工作。下面小编分享一下在半路修改工程图模板的方法:
1.进入需要更改模板的工程图,在左边的设计树中鼠标右键点击“图纸”,在弹出的菜单中点击“属性”。
2.在弹出的对话框中,“图纸格式/大小”一栏里,选择需要的工程图模板,然后点击“应用更改”,就会发现工程图模板已经改变,但是视图并没有消失。
3.此时只需要双击视图(要双击视图本身,不要双击成标注),在左侧的对话框中修改成合适的比例尺就可以了。
1、将指定时间转为时间戳 //传入指定时间 public void convertToTimestamp(String time) { try { Date date = new SimpleDateFormat("yyyy-MM-dd").parse(time); Calendar cal = Calendar.getInstance(); cal.setTime(date); long timestamp = cal.getTimeInMillis(); System.out.println("10位时间戳="+timestamp); System.out.println("13位时间戳"+timestamp/1000); } catch (ParseException e) { e.printStackTrace(); } } 2、将时间戳转为时间格式 //传入时间戳即可 public String conversionTime(String timeStamp) { //yyyy-MM-dd HH:mm:ss 转换的时间格式 可以自定义 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); //转换 String time = sdf.format(new Date(Long.parseLong(timeStamp))); return time; }
嵌入式 —— Linux 学习之路(二):Docker 一、Ubuntu1604 安装 Docker1、使用官方安装脚本自动安装2、使用国内 daocloud 一键安装命令3、手动安装a)卸载旧版本b)更新 apt 包索引c)安装 apt 依赖包,用于通过HTTPS来获取仓库d)添加 Docker 的官方 GPG 密钥e)写入软件源信息,设置稳定版仓库f)更新并安装 最新版本的 Docker Engine-Community 和 containerdg)测试 Docker 是否安装成功h)查找仓库中 Docker-CE 的版本i)安装指定版本的方式(与步骤 f 的区别) 4、查看 Docker 版本信息5、启动与停止 Docker 服务6、卸载 Docker 二、Win7 安装 Docker三、为什么要学习 Docker1、Linux 的部署形式2、虚拟化技术3、虚拟出一个隔离的程序运行环境4、容器技术5、为什么要选择 Docker 四、Docker 安装部署1、Docker 引擎2、Docker Daemon3、Rest 接口4、Docker Client5、Docker 平台组成6、安装 Dockera)开启 Linux 内核的流量转发(暂未使用)b)加载修改内核的参数,配置文件(暂未使用)c)安装 Docker 参考第一章节d)镜像加速器e)修改 Docker 配置文件f)重新启动服务g)查看 Docker 进程h)查看 Docker 是否正确启动 五、启动第一个 Docker 容器1、获取镜像2、运行镜像,生成容器 六、Docker 的生命周期七、Docker 镜像的原理1、 快速实践,使用 Docker,来切换不同的发行版,内核使用的都是宿主机的内核2、理解什么是 Docker 镜像4、Docker 为什么分层镜像5、可写的容器层6、Docker 镜像的内容 八、获取镜像1、镜像托管仓库2、搜索镜像3、查看本地的镜像文件有哪些4、下载 Docker 镜像5、查看 Docker 镜像的存储路径 6、使用不同的镜像,生成容器7、如何查看 centos 的标签信息 九、查看镜像1、查看本地镜像 十、删除镜像1、下载一个 hello-world 镜像2、运行 hello-world 生成容器3、删除 hello-world4、查看正在运行或运行过的容器5、删除容器记录 十一、镜像管理1、批量删除镜像的用法(危险)2、批量删除容器3、导出镜像4、导入镜像5、查看镜像详细信息 十一、容器管理1、创建 + 启动2、运行一个挂掉的容器3、查看容器日志的方法4、进入容器空间内5、查看容器的详细信息6、容器的端口映射7、容器的提交 十二、Dockerfile 创建镜像1、创建镜像的两个方法2、官方提供的 Dockerfile 实例3、dockerfile 主要组成部分4、Dockerfile 指令 十三、快速入门 Dockerfile1、通过 Dockerfile,构建 nginx 镜像,且运行容器后,生成的页面是"
安装PyQt5
pip install PyQt5 -i https://pypi.douban.com/simple
安装PyQt5-tools
pip install PyQt5-tools 或者 pip install PyQt5-tools -i https://pypi.douban.com/simple
配置系统的环境变量
在桌面上右键单击“我的电脑”,在弹出的快捷菜单中选择“属性”->“高级系统设置”->“高级”,单击环境变量按钮,在系统变量Path中添加pyqt5-tools目录的绝对路径。
在 Windows 命令行输入 echo %Path% 命令。如果一切正常,则会在返回的 Path 路径中看到刚才配置的路径。
【如果没看到,系统需要重启后方能看到 或者 你的环境变量没配置OK】
添加外部工具【PyCharm -> 文件 -> 设置 -> 工具 -> 外部工具】
我们先添加 QT Designer ,可以参考截图设置。
“名称” : 这里可以自定义的
“程序”:选择的是 “designer.exe” 的安装目录,
“工作目录”: 根据实际情况配置,这里我直接使用的是 宏 F i l e D i r FileDir FileDir
添加 Pyuic
“名称”: 这里可以自定义的
“程序”:选择的是 “pyuic5.exe” 的安装目录
“实参”: F i l e N a m e FileName FileName -o F i l e N a m e W i t h o u t E x t e n s i o n FileNameWithoutExtension FileNameWithoutExtension.
项目结构 代码编写 pom文件
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>com.qiniu</groupId> <artifactId>qiniu-java-sdk</artifactId> <version>[7.7.0, 7.7.99]</version> </dependency> <dependency> <groupId>com.squareup.okhttp3</groupId> <artifactId>okhttp</artifactId> <version>3.14.2</version> <scope>compile</scope> </dependency> <dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> <version>2.8.5</version> <scope>compile</scope> </dependency> <dependency> <groupId>com.qiniu</groupId> <artifactId>happy-dns-java</artifactId> <version>0.1.6</version> <scope>test</scope> </dependency> </dependencies> yml文件
server: port: 8077 oss: qiniu: accessKey: secretKey: # 空间名称 bucketName: # 存储区域 zone: huabei # 访问域名 domain: spring: thymeleaf: cache: false 配置类
解决办法: maven clean一次就好了
我的问题是springboot 换了 版本之后,用tomcat启动报这个错. 原因,很有可能是不同的springboot版本都引入了spring web的jar包,导致了重复冲突, maven clean就好了
1.案例效果图展示 2.地图缩放和平移 与地图缩放和平移功能有关的字段属性有:
● roam[boolean, string]:是否开启鼠标缩放和平移漫游。默认不开启。如果只想要开启缩放或者平移,可以设置成 'scale' 或者 'move'。设置成 true 为都开启
● zoom[number]: 当前视角的缩放比例
● scaleLimit[object]: 滚轮缩放的极限控制,通过min, max最小和最大的缩放值,默认的缩放为1。
配置项geo和 series中具体代码如下:
aspectScale: 0.75, // 地图的长宽比 z:1, zoom:1.2, // 当前视角的缩放比例。 roam: 'scale', // 是否开启鼠标缩放和平移漫游。默认不开启。如果只想要开启缩放或者平移,可以设置成 'scale' 或者 'move'。设置成 true 为都开启 scaleLimit:{ // 滚轮缩放的极限控制,通过min, max最小和最大的缩放值,默认的缩放为1 min: 0.8, max: 1.6 }, 3.整个地图和地图某一区域阴影效果 整个地图实现阴影或者3D效果,需要echarts中配置项geo和series中同时设置阴影效果(或者series系列数组中设置2个元素),series浮在geo上面,二者中series的z的值要大于geo中z的值,并且geo相对series有阴影偏移距离,注意在series中的itemstyle中不设置shadowOffsetX和shadowOffsetY;地图中某一区域的阴影效果可以在data数据中具体的元素中对itemStyle进行设置,具体代码如下:
itemStyle: { normal: { areaColor: "#d0b6de",// 地图区域的颜色 shadowColor:"rgba(186,85,211,.5)",// 阴影颜色。支持的格式同color。 borderColor:'#503d27', borderWidth: 1, shadowBlur: 1,// 图形阴影的模糊大小。该属性配合 shadowColor,shadowOffsetX, shadowOffsetY 一起设置图形的阴影效果。 shadowOffsetX:6, // 阴影水平方向上的偏移距离。 shadowOffsetY:6, // 阴影垂直方向上的偏移距离。 }, emphasis: { label:{ show:false } } 4.
其实文章也是以前做好的记录,现在把笔记放在博客上面来,方便管理和查看, 所以有一些细节问题并没有图文说明,等后期正真操作一遍的时候来把图片和说明补充完成。 本文给出两种方式,第一种gcc-arm-none-eabi 来编译, 第二种利用插件导入KEIL工程,可以执行编译调试烧录 ..添加第二种方式,利用插件 2021/9/16 ..添加目录栏目 ..添加第一种方式的部分图片和说明 2021/9/17 ..添加环境变量添加步骤示意图 ..添加 Makefile 的修改说明 ..添加 openocd 下的烧录过程说明 ..添加 gcc 下的 printf 重定义 2021/9/23 ..Embedded IDE 插件自动安装失败处理方法 ..添加 openocd 下载安装说明 2021/10/1 ..添加 mingw 安装详细说明 ..添加使用 Jlink 烧录出现问题说明 2021/10/2 ..添加本文用到所有的工具包下载(CSDN资源) 2021/10/14 ..添加jlink问题7.4小结(未解决) 2021/11/20 ..结构调整,内容添加优化 2022/8/24 目录 一、使用 VSCode + gcc + openOCD 开发1、安装 gcc-arm-none-eabi-xxx2、环境变量添加示意图3、安装mingw4、安装openocdopenocd的操作模式 5、Makefile的修改6、烧录过程的说明7、使用 Jlink 烧录问题说明7.1 openocd下如何识别J-Link7.2 openocd使用 J-Link swd模式7.3 J-Link 恢复到 SEGGER J-Flash 使用7.4 换板子出现的Jlink烧录问题(未解决) 8、gcc下pirntf 的重定义 二、使用 VScode插件Embedded IDE进行开发1、安装 Embedded IDE插件2、Embedded IDE插件配置操作说明3、STM32F103 工程编译烧录示例4、nRF52832 工程编译烧录示例 结语 一、使用 VSCode + gcc + openOCD 开发 文章中所用到的工具版本都可以网上下载,我在对此文章完善的过程中也发现了,每次换个地方下载比较麻烦,所以我把用到的工具打包了一份:本文用到的所有工具集合
#Java实现头像上传
看网课的时候视频中用到下方的路径
== String realPath = session.getServletContext().getRealPath(“/upload”);==
这样会导致一个问题,就是每次服务器重启之后,这个文件就会找不到,不过也不用担心,在企业里如果文件很多就会有专门的文件服务器,写ip地址加文件名字就行,自己解决这个bug的话,我用到的是写在本地文件中,下面开始代码环节
首先要写一个配置类,因为大多数浏览器为了安全不允许访问你的本地文件,所以写一个映射路径,这段代码的意思就是一个拦截器,只要访问addResourceHandler(“xxx”)这个路径就会映射到addResourceLocations(“mmm”)这个真实路径
public static final int AVATAR_MAX_SIZE =10 *1024*1024; //设置上传文件的最大值 public static final List<String> AVATAR_TYPE = new ArrayList<>(); //限制上传文件的类型 static { AVATAR_TYPE.add("image/jpeg"); AVATAR_TYPE.add("image/png"); AVATAR_TYPE.add("image/bmp"); AVATAR_TYPE.add("image/gif"); AVATAR_TYPE.add("image/webp"); } //上面是无关的东西 //在这里我写在了控制层,可以传参到业务层写,JsonResult<>是模型类 public JsonResult<String> updateUserAvatar (HttpSession session, MultipartFile file){ if (!AVATAR_TYPE.contains(file.getContentType())){ //这些是抛出的异常可以不用管,但是也会介绍一下,file是上面的形参 throw new FileTypeException(); // 文件类型不符异常 } if (file==null){ throw new FileEmptyException(); //文件空异常,如果文件是个空,扔出去 } if (file.getSize()>AVATAR_MAX_SIZE){ throw new FileSizeException(); //文件大小异常 } //第一步::写一个路径,和配置类一样 String realPath = "
在conf文件夹下面server.xml里面的<Host>标签内最下面添加
<Context path="/" docBase="/amp-admin" debug="0" reloadable="true"></Context>
path是用户访问路径,docBase是tomcat访问文件路径
使用Qtcreator的IDE工具点击对应生成按键可生成目标文件。同样使用qmake命令生成Makefile文件,运行Makefile也可以生成可执行文件。qmake是一个协助简化跨平台进行专案开发的构建过程的工具程式,Qt附带的工具之一 ,详见qmake_百度百科 (baidu.com)。
qmake生成可执行文件的步骤如下:
1、在.pro文件下执行qmake生成Makefile。
2、执行make -j8 //并行编译
注意:上面步骤需要注意是,若编译有问题时,可以make clean一下,删除make生成的产物,删除Makefile、.qmake.stash文件,再重新编译。
3、运行目标程序test1
介绍通过qmake编译工程的博文也可参考[qt creator]qmake生成makefile_wanxiu.的博客-CSDN博客_qmake生成makefile
一丶创建用户 右键点击登录名→新建登录名
二丶设置管理员权限 进入【服务器角色】在右侧的服务器角色面板中,勾选public
服务器角色说明sysadmin执行SQL Server中的任何操作serveradmin配置服务器设置setupadmin安装复制和管理扩展过程securityadmin管理登录和CREATE DATABASE的权限以及阅读审计processadmin管理SQL Server进程dbcreator创建和修改数据库diskadmin管理磁盘文件 三丶设置非管理员权限 进入【用户映射】在右侧的面板中勾选该账号可以进行管理操作的数据库名称!并在该面板下面的【数据库角色成员身份】中勾选db_owner项!
注意:如果给你个无系统管理权限的账号指定管理一个数据库时,则一定要勾选db_owner项!否则该账号无法看到该数据库中的任何数据表!
数据库角色成员身份说明db_owner可以执行数据库中技术所有动作的用户db_accessadmin可以添加、删除用户的用户db_datareader可以查看所有数据库中用户表内数据的用户db_datawriter可以添加、修改或删除所有数据库中用户表内数据的用户db_ddladmin可以在数据库中执行所有DDL操作的用户db_securityadmin可以管理数据库中与安全权限有关所有动作的用户db_backoperator可以备份数据库的用户(并可以发布DBCC和CHECKPOINT语句,这两个语句一般在备份前都会被执行)db_denydatareader不能看到数据库中任何数据的用户db_denydatawriter不能改变数据库中任何数据的用户 四丶进入【状态】设置连接引擎授权
PHP中变量的作用域不像java, c中的那样有明确的限定。比如, 我们在一个php文件中有这样一段代码:
$data = ['a', 'b', 'c']; //在foreach循环中建立了变量$key和$value foreach ($data as $key => $value) { //do nothing here } //在foreach外面仍然可以访问这两个变量 var_dump($key); var_dump($value); 在这个foreach循环中定义的变量$key和$value, 在foreach外面也是可以访问的。上面代码的执行结果是:
int(2) string(1) "c" 当然,如果这个foreach是在一个function内,那么在这个function外是不能直接访问这两个变量的。
例子 例1 看下面这个例子:
$data = ['a', 'b', 'c']; foreach ($data as $key => $value) { $value = &$data[$key];//引用 } print_r($data); 执行的结果是:
Array ( [0] => b [1] => c [2] => c ) 我们可以看到变量$data的值已经被改变了! 这很奇怪吧! 我们在循环中打印变量:
$data = ['a', 'b', 'c']; foreach ($data as $key => $value) { $value = &$data[$key];//引用 echo $key, ': ', $value, ' => ', json_encode($data) .
背景 项目上基于apisix-runner,我们自己写了一些插件,执行点为ext-plugin-pre-req,按照apisix的官方文档上我们知道ext-plugin-req 的执行顺序是在大多数 APISIX built-in plugins之前;但是实际apisix的插件的执行点在阶段(phase)来说上划分的更为细化。
💡 ext-plugin-pre-req: executed during handling the request, before most of the APISIX built-in plugins (Lua language plugins)
问题 遇到的问题:在做链路追踪时,需要将zipkin插件的span和ext-*中的自定义插件的span关联
解决 按照ext-plugin-pre-req的定义,执行顺序是优先于大多数的apisix内置插件的,但是不包括zipkin,根据apisix的官方文档介绍,在相同的执行阶段,优先级高的先执行。
Plugin Develop | Apache APISIX® – Cloud-Native API Gateway
在conf/config-default.yaml配置中定义了plugins的优先级
plugins: # plugin list (sorted by priority) - real-ip # priority: 23000 - client-control # priority: 22000 - proxy-control # priority: 21990 - zipkin # priority: 12011 #- skywalking # priority: 12010 #- opentelemetry # priority: 12009 - ext-plugin-pre-req # priority: 12000 - request-id # priority: 11010 - fault-injection # priority: 11000 - mocking # priority: 10900 - serverless-pre-function # priority: 10000 #- batch-requests # priority: 4010 - cors # priority: 4000 - ip-restriction # priority: 3000 - ua-restriction # priority: 2999 - referer-restriction # priority: 2990 - csrf # priority: 2980 - uri-blocker # priority: 2900 - request-validation # priority: 2800 - openid-connect # priority: 2599 .
目录:
(1)用动态规划算法解决背包问题
(2)用动态规划算法解决最大子序和问题
(1)用动态规划算法解决背包问题 有一个背包,容量为4,要求达到的目标为装入的背包的总价值最大,并且重量不超出,同时装入的物品不能重复。 图一
图二
核心思想 将大问题划分为小问题进行解决,从而一步步获取最优解的处理算法。且经分解得到的子问题往往不是互相独立的。
假设 i:商品。
j:重量。
v[i]:第i个商品的价值(价格G)。
w[i]:第i个商品的重量。
v[i][j]:在前i个商品中,能够装入容量为j的背包中的最大价值。
公式 (1)v[i][0]=v[0][j]=0;
表示填入表的第一行和第一列是0,如图二。
(2)当w[i]>j时:v[i][j]=v[i-1][j];
当准备加入新增的商品的容量大于当前背包的容量时,就直接使用上一个单元格的装入策略。
(3)当j>=w[i]时:v[i][j]=max{v[i-1][j],v[i]+v[i-1][j-w[i]];
当准备加入新增的商品的容量小于当前背包的容量时,采用以上公式计算。
——v[i-1][j]:就是上一个单元格的装入的最大值;
——v[i]:表示当前商品的价值;
——v[i-1][j-w[i]]:装入v[i]后,背包中余剩的容量为[j-w[i]],此时在v[i-1],即上一个单元格中寻找重量为[j-w[i]]的格子;
举例 求v[3][4]:即图二右下角最后一格。
此时i=3.j=4,含义为:在前3个商品中,能够装入容量为4的背包中的最大价值。
w[i]=w[3]=3,则与当前的背包容量进行比较:w[i]<j,符合公式(3)。
因此v[i][j]=v[3][4]=max{v[2][4],v[3]+v[2][4-3]}=max{3000,2000+1500}=2000+1500。
所以v[3][4]=3500。
代码演示 public class KnapsackProblem { public static void main(String[] args) { //物品的重量 int[] w = {1, 4, 3}; //物品的价值 int[] val = {1500, 3000, 2000}; //背包的容量 int m = 4; //物品的个数 int n = val.length; //表示在前i个物品中能够装入容量为j的背包中的最大价值,其中有一行和一列为0,因此要加1 int[][] v = new int[n+1][m+1]; //为了记录放入商品的情况,我定义一个二维数组 int[][] path = new int[n+1][m+1]; /** * 公式1 * 初始化第一行和第一列,可不去处理,因为默认为0。 */ for(int i = 0; i < v.
Linux 镜像文件ISO下载地址:
http://archive.kernel.org/centos-vault/7.5.1804/isos/x86_64/
选择:
CentOS-7-x86_64-Minimal-1804.iso
下载就OK,下载后可以在虚拟机上进行运行。
阿里云镜像站点:centos-7-isos-x86_64安装包下载_开源镜像站-阿里云
下载方法参考链接:https://www.jianshu.com/p/a63f47e096e8
我们以监控Oracle为例,(目前仅有x86版本,可以下载源码针对不同环境使用golang环境自己编译)
监控什么指标下载对应系统的exporter插件,统一下载地址:https://prometheus.io/download/
监控指标对应的grafana展示模板,统一下载地址:https://grafana.com/grafana/dashboards
oracledb_exporter下载地址:https://github.com/iamseth/oracledb_exporter
oracle client下载地址:https://www.oracle.com/database/technologies/instant-client/downloads.html
环境准备 已完成Prometheus的配置安装已完成Grafana的配置安装下载oracledb_exporter插件 开始配置 第一步 # 下载Oracledb_exporter wget https://github.com/iamseth/oracledb_exporter/releases/download/0.2.9/oracledb_exporter.0.2.9-ora18.5.linux-amd64.tar.gz # 解压运行 tar -zxvf oracledb_exporter.0.2.9-ora18.5.linux-amd64.tar.gz # 下载oracle-instantclient18.5-basic-18.5.0.0.0-3.x86_64.rpm # 上传至服务器并安装 rpm -ivh oracle-instantclient18.5-basic-18.5.0.0.0-3.x86_64.rpm 开始运行 第一步配置Oracle client # 创建client目录 mkdir -p /usr/lib/oracle/12.1/client64/network/admin/ # 编辑监听文件 vim /usr/lib/oracle/12.1/client64/network/admin/tnsnames.ora ## 填写以下内容 ORCL = (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = *IP*)(PORT = 1521)) (CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME = *SID*) ) ) # 编辑环境变量配置文件 vim ~/.bashrc ## 输入以下内容 export ORACLE_HOME=/usr/lib/oracle/12.
LAMBDA表达式常用 (全) 这里主要是将数据库中的常用操作用LAMBDA表达式重新表示了下,用法不多,但相对较常用,等有时间了还会扩展 ,并将查询语句及LINQ到时也一并重新整理下: 1.select语句:books.Select(p=>new { p.Title, p.UnitPrice, p.Author});//需用匿名方式 2.where语句:books.Where(p=>p.UnitPrice==100&&p.Title=”ABC”); 补充: 像数据库中的LIKE ‘%c++%’,LAMBDA中用p.Title.Contains(“c++”)表示; 像数据库中的LIKE ‘c%’,LAMBDA中用p.Title.StartWith(“c”)表示; 像数据库中的LIKE ‘%c’,LAMBDA中用p.Title.EndsWith(“c”)表示; Where的另一种表现形式: books.Where(p=>{ var ret = p.UnitPrice>30&&p.Title.Contains(“c++”); return ret; }); 3.排序语句: 像数据库中order by 升序: 通过 “对象.OrderBy(p=>p.UnitPrice)”实现 像数据库中order by 降序: 通过 “对象.OrderByDescending(p=>p.UnitPrice)”实现 像数据库中order by UnitPrice desc,Title asc: 通过 ”对象.OrderByDescending(p=>p.UnitPrice).ThenBy(p=>p.Title)” 反过来则是: ”对象.OrderBy(p=>p.UnitPrice).ThenByDescending(p=>p.Title)” 4.组函数: var max = books.Where(p => p.CategoryId == 1001).Max(p => p.UnitPrice); var min = books.Min(p => p.UnitPrice); var count = books.Count( ); var avg = books.
哪些python的编程软件值得推荐? 编写python源代码的软件.首推的Pycharm。
PyCharm用于bai一般IDE具备的功能,比如, 调试、语法高亮、Project管理、du代码跳转、智能提示、自动完zhi成、单元测试、版本控制另外,PyCharm还提供了一些很好的功能用于Django开发,同时支持Google App Engine,更酷的是,PyCharm支持IronPython。
其次是sublime text,Sublime Text 支持多种编程语言的语法高亮、拥有优秀的代码自动完成功能,还拥有代码片段(Snippet)的功能,可以将常用的代码片段保存起来,在需要时随时调用。
支持 VIM 模式,可以使用Vim模式下的多数命令。支持宏,简单地说就是把操作录制下来或者自己编写命令,然后播放刚才录制的操作或者命令。
还有Jupyter, Jupyter Notebook(此前被称为 IPython notebook)是一个交互式笔记本,支持运行 40 多种编程语言。
最后就是最基本的nopad++,最开始的时候是实用这款作为开发工具进行基础练习。
谷歌人工智能写作项目:小发猫
有什么软件可以写python 编写python源代码的软件.首推的Pycharmtypescript获取成员变量类型。
PyCharm用于bai一般IDE具备的功能,比如, 调试、语法高亮、Project管理、du代码跳转、智能提示、自动完zhi成、单元测试、版本控制另外,PyCharm还提供了一些很好的功能用于Django开发,同时支持Google App Engine,更酷的是,PyCharm支持IronPython。
其次是sublime text,Sublime Text 支持多种编程语言的语法高亮、拥有优秀的代码自动完成功能,还拥有代码片段(Snippet)的功能,可以将常用的代码片段保存起来,在需要时随时调用。
支持 VIM 模式,可以使用Vim模式下的多数命令。支持宏,简单地说就是把操作录制下来或者自己编写命令,然后播放刚才录制的操作或者命令。
还有Jupyter, Jupyter Notebook(此前被称为 IPython notebook)是一个交互式笔记本,支持运行 40 多种编程语言。
最后就是最基本的nopad++,最开始的时候是实用这款作为开发工具进行基础练习。
学python需要什么软件 学python需要的软件:1、sublime Text:是一款非常流行的代码编辑器,支持Python代码编辑,同时兼容所有平台,并且丰富的插件扩展了语法和编辑功能,迅捷小巧,具有良好的兼容性,很受编程人士的喜爱。
2、Vim:Vim和VI是一种模型编辑器,它将文本查看从文本编辑中分离,VIM在原始VI之上做了诸多改进,包括可扩展模型和就地代码构建,VIMScripts可用于各种Python开发任务。
3、Visual Studio Code:Visual Studio Code是一款兼容Linux、Mac OS,X和Windows平台的全功能代码编辑器,可扩展并且可以对几乎所有任务进行配置,对于Python的支持可以在Visual Studio,Code中安装插件,只需快速点击按钮即可成功安装,且可自动识别Python安装和库。
Python由荷兰数学和计算机科学研究学会的吉多·范罗苏姆于1990年代初设计,作为一门叫做ABC语言的替代品。Python提供了高效的高级数据结构,还能简单有效地面向对象编程。
Python语法和动态类型,以及解释型语言的本质,使它成为多数平台上写脚本和快速开发应用的编程语言,随着版本的不断更新和语言新功能的添加,逐渐被用于独立的、大型项目的开发。
以上内容参考:百度百科-Python。
用Python编程需要哪些软件? 《Python 3.9.7软件》百度网盘资源免费下载:链接: ?pwd=nhfc 提取码: nhfcPython 3.9.7最新正式版是一种面向对象、直译式计算机程序设计语言,也是一种功能强大而完善的通用型语言,已经具有十多年的发展历史,成熟且稳定。
python具有非常简捷而清晰的语法特点,且几乎可以在所有的操作系统中运行,非常适合完成各种高层任务,随着不断的更新优化,逐渐被用于独立的、大型项目的开发,只为给用户更加完美的操作体验。
python编程用什么编辑器 Sublime Text它可以跨平台,还拥有丰富的插件和主题、代码补全、语法高亮等功能,主题配置也非常简单,所以特别适合新手来使用。
IDLE如果是Windows系统,可以使用IDLE,它是Python自带的编辑器,刚开始可以使用它来进行操作,IDLE具有语法高亮功能,还允许在IDLE中运行程序,如果有一些debug,也会自动帮我们处理好。
色相是色彩的首要特征,是区别各种不同色彩的最准确的标准。事实上任何黑白灰以外的颜色都有色相的属性,而色相也就是由原色、间色和复色来构成的。色相,色彩可呈现出来的质地面貌。自然界中各个不同的色相是无限丰富的,如紫红、银灰、橙黄等。色相即各类色彩的相貌称谓。
十色相图
十色相图
在色相&色调(Hue&Tone)体系中,10色相分别指:红色(Red)、橙色(Orange)、黄色(Yellow)、黄绿色(Green Yellow)、绿色(Green)、蓝绿色(Blue Green)、蓝色(Blue)、蓝紫色(Violet)、紫色(Purple)、品红色(Magenta)。
十二色相图
十二色相图
十二色相环是由原色(primary hues),二次色(secondary hues)和三次色(tertiary hues)组合而成。色相环中的三原色是红、黄、蓝色,彼此势均力敌,在环中形成一个等边三角形。
十六色相图
CCS十六色相环由两部分构成,分别是:
十六色相图
1、CCS基础色相环:CCS将红(R)、橙(O)、黄(Y)、黄绿(YG)、绿(G)、蓝(B)、群青(U)、紫罗兰(V)这8个具有代表性的颜色按秩序排列,构成基础色相环。这8个颜色又能构成4组完全对应的补色组合,红和绿、橙和蓝、黄和群青、黄绿和紫罗兰。
2、CCS16色色相环:在这8个色相中,等间距各增加一个颜色,橙红(OR)、橙黄(OY)、青黄(gY)、叶绿(LG)、蓝绿(BG)、群青蓝(UB)、青紫(UV)、紫红(VR),就形成了16色色相环。
24色相图
24色相图
奥斯特瓦尔德颜色系统的基本色相为黄、橙、红、紫、蓝、蓝绿、绿、黄绿8个主要色相,每个基本色相又分为3个部分,组成24个分割的色相环,从1号排列到24号。
在24色相环彼此相隔十二个数位或者相距180度的两个色相,均是互补色关系。互补色结合的色组,是对比最强的色组。使人的视觉产生刺激性、不安定性。相隔15度的两个色相,均是同种色对比,色相感单沌、柔和、统一、趋于调和。
相关参考
如果这些都没解决,那么就在这个文件中,run一下:
大家自行下载XAPP585相关的资源。
serdes_1_to_7_mmcm_idelay_sdr逻辑先完成phase shifting,确保时钟n和p的相位差为零,然后在进行bslip对时钟数据进行滑动并识别,当PLL锁定失效时,重新进行phase shifting和bslip,然后用恢复好的rxclk和rxclk_div去接收数据。
1.本文部分素材来源网络,版权归原作者所有,如涉及作品版权问题,请与我联系删除。
2.未经原作者允许不得转载本文内容,否则将视为侵权;
3.转载或者引用本文内容请注明来源及原作者;
4.对于不遵守此声明或者其他违法使用本文内容者,本人依法保留追究权等。
上图红色部分为PLLE2_ADV源语功能,其余部件为人为添加的电路,包括输入缓冲、输出缓冲、反馈方式。
// CLKOUT0 = CLKIN1 / DIVCLK_DIVIDE * CLKFBOUT_MULT / CLKOUT0_DIVIDE // CLKFBOUT 由 CLKIN1锁定输出,经过缓冲区后进入 PLL CLKFBIN,PLL 对 CLKFBIN 经过 CLKFBOUT_MULT 倍频然后分频得到每个通道的时钟进行输出 PLLE2_ADV #( .BANDWIDTH ("OPTIMIZED" ), .CLKFBOUT_MULT (7*MMCM_MODE ), // CLKFBOUT_MULT 为 CLKFBIN 时钟的倍频系数 .CLKFBOUT_PHASE (0.0 ), // 反馈时钟相位偏移 .CLKIN1_PERIOD (CLKIN_PERIOD ), // 输入时钟1约束(ns) .CLKIN2_PERIOD (CLKIN_PERIOD ), // 输入时钟2约束(ns) .CLKOUT0_DIVIDE (1*MMCM_MODE ), // 0通道分频、占空比、相位参数 .CLKOUT0_DUTY_CYCLE (0.5 ), .CLKOUT0_PHASE (0.0 ), .CLKOUT1_DIVIDE (4*MMCM_MODE ), // 1通道分频、占空比、相位参数 .CLKOUT1_DUTY_CYCLE (0.5 ), .
在Created生命周期Data生成,请求返回的数据需要挂载在data上,所以Created里是可以请求的,但 Created 的这时候DOM还没有初始化;
Mounted生命周期里DOM才渲染完成
beforeCreate // 这时候data,methods函数未挂载
created // data已挂载、methods函数已挂载
beforeMount // 相关的render函数首次被调用,dom未挂载
mounted // dom已渲染挂载完成
beforeUpdate
updated
beforeDestroy
destroyed
如果我们的请求不需要获取/借助/依赖/改变DOM,这时请求可以放在Created
反之则可以放在Mounted里
异步请求数据
1、对于作为子组件被调用的组件里,异步请求应当在mounted里调用,因为这个时候子组件可能需要涉及到对dom的操作;
2、对于页面级组件,当我们需要使用ssr(服务端渲染)的时候,只有created是可用的,所以这个时候请求数据只能用它;
3、对于页面级组件, 当我们做异步操作时,涉及到要访问dom的操作,我们仍旧只能使用mounted;
对于一般情况,created和mounted都是可以的;
总结 经过四个月在华清远见的学习,我收获了很多东西。这四个多月算是高考后,最充实的一段时间。
一开始的时候算是比较轻松的,因为C语言在大学学过,有些比较基础的东西还是比较简单。在华清学习,该阶段主要是查漏补缺,有很多细节上的地方得到了很好的补充,比如各种情况计算字节大小,尤其是结构体的大小,有32位64位之分,还有默认对齐位数,在以前是不知道的。还有像指针这类难点也得到了突破,不仅是指针的概念的,还有多级指针,const修饰指针等等难点,老师还讲了指针数组,数组指针等比较容易混淆的知识。在这期间和后面的c高级阶段,还学习了一个重要的东西,就是Linux操作系统。Linux因为它的开源,可移植性和可裁剪性,非常符合嵌入式的使用要求,所以我以后常接触的也是该操作系统。然后学习了IO操作,对文件操作有了深刻的认识。接下来就是面试的重点了,网络编程,这部分算是一个难点,其中tcp,udp是比较常用的传输层协议,他们的主要区别就是tcp可靠,udp不可靠,容易数据丢失。基于这些协议来写服务器,然后通过并发,IO多路复用来实现多个用户同时使用服务器传递数据,其中比较了select、poll和epoll几种方法,不过IO多路复用是伪并发,真正的并发是进程和线程来实现的,这种也实例过。进线程应该算是比较基础的内容,但是是比较重要的内容,它的难点主要在进线程通信部分。线程通信有个同步和互斥的概念,这两种容易搞混,同步是让不同线程按一定的顺序执行,互斥是保护临界资源,一个线程在用的时候,另一个线程不能用,从概念上感觉两个没有关系,但其实同步的过程算是完成了互斥的操作。进程通信方式比较多,有无名管道,有名管道、信号,共享内存,消息队列,信号量等。共享内存是进程的,全局变量是线程的通信方式,之前记错了。
C++在大学里是有这个课程的,但是当时混了,没学到什么,完全忘了,这次基本算是个新东西,不过它是在c语言的基础上发展上来的,所以还是有很多学过的地方,前期学起来还是比较轻松,不过后面有点难,比如重载,重写,重定义的区别,就很容易搞混,但多练几次还是能总结规律,比如重载是在同一区域(同在父类或同在子类)里才有的概念,不同区域才区分重写和重定义,然后重写是函数名,参数,返回值都一样,还必须有virtual,其余全算重定义。
然后学习了QT,QT算是比较有意思的东西,它没多少逻辑上的难点,主要都是用别人定义好的东西。它特有的机制是信号与槽,例如一个按钮,按下会有一个信号,这个信号会触发一个槽函数,槽函数里面去实现各种功能。整体还是不难,唯一难的就是不知道,很多没见过就想不起用它,以为要自己写,其实别人都已经弄好了,比如播放器,摄像头,这些QT已经有写好的类了。自己写了个音乐播放器,其实都不能算自己写的,大部分都是用QT的,自己写了个界面。
后面的就比较难了,关于底层的内容。ARM学了个汇编语言,写个加减倒还是挺简单,一旦涉及循环,递归就难搞了,而且想参照C语言程序写一个稍微长一点的代码就难以下手。然后就是各个模式下的寄存器,有点乱。系统移植,课程内容算是简单,就是跟着老师一步步走,只是让我自己重新移植有点困难,过程复杂,还是得看视频一步一步跟着。有点担心工作了怎么办,工作移植的系统肯定需要不同功能,不知道到那找。驱动开发就有点麻烦了,操作麻烦,写代码也麻烦。整体学下来基本不会。只能指望后面工作了继续学习。
在学习过程中,我的懒癌频发,导致很多时候有点跟不上,不过也有客观因素,我的路程有点远,每天有接近3小时在路上,也少了很多练习时间。归根结底还是没有被逼到绝境,感觉到的压力还是不够,对自己的目标有点低了,之前就想的出去能有7千就不错了,现在能有6千就好了,对自己的要求太低了。
工作了应该不会这样随遇而安了,工作的压力是能直接感受到的,到时自己赚钱自己花,消费肯定会很高,这肯定会逼着自己多赚钱。因为即使现在没什么钱,还是想要追求一些好东西,只能从其他地方减少开支来支持我的爱好。
因为我学的不怎么样,所以接下来我想先找一个还可以的工作,先进入嵌入式这个行业,然后在一个地方沉淀几年,为自己增加经验,增加涨薪的筹码。
华清这个地方还是不错的,老师都很热情,有问题都会给你解答。不吹不黑,大部分都很好,只是有些老师的水平还是有点不够,不过在前面相对简单的阶段。最好的一点是学不走了可以滑班,跟着下一个版班继续学,我就滑过一回。要是大学里就知道这个就好了,在这里学几个月,然后校招找个好公司,也算是有个高的起点了。
总的来说这4个多月还是很值的,学到了很多东西,明确了以后奋斗的目标。
在MySQL中可以使用IF、IFNULL、NULLIF、ISNULL函数进行流程的控制。
1、IF()函数的使用 在mysql中if()函数的用法类似于java中的三目表达式
IF(expr1,expr2,expr3),如果expr1的值为true,则返回expr2的值,如果expr1的值为false,则返回expr3的
SELECT IF(TRUE,'A','B'); -- 输出结果:A SELECT IF(FALSE,'A','B'); -- 输出结果:B SELECT job,IF(ename='SMITH','罗罗',null) AS ename FROM emp LIMIT 3 结果:
2、IFNULL()函数的使用 IFNULL(expr1,expr2),如果expr1的值为null,则返回expr2的值,如果expr1的值不为null,则返回expr1的值。
SELECT IFNULL(NULL,'B'); -- 输出结果:B SELECT IFNULL('HELLO','B'); -- 输出结果:HELLO SELECT job,IFNULL(coom,'hehe') AS ename FROM emp 结果:
3、NULLIF()函数的使用 NULLIF(expr1,expr2),如果expr1=expr2成立,那么返回值为null,否则返回值为expr1的值。
SELECT NULLIF('A','A'); -- 输出结果:null SELECT NULLIF('A','B'); -- 输出结果:A 4、ISNULL()函数的使用 ISNULL(expr),如果expr的值为null,则返回1,如果expr1的值不为null,则返回0。
SELECT ISNULL(NULL); -- 输出结果:1 SELECT ISNULL('HELLO'); -- 输出结果:0
1.达梦数据库的下载 1.百度网盘下载
【达梦8数据库百度网盘下载地址】_小小盗草人的博客-CSDN博客_达梦数据库下载百度云
2.官网下载 武汉达梦数据库有限公司
2.达梦数据库的安装 1.达梦数据库在windos以及linux的安装卸载 - 顾众生 - 博客园 2.windows安装达梦数据库_橘子很皮额1的博客-CSDN博客_windows安装达梦数据库
达梦数据库默认密码是SYSDBA ,建议自己设置,提高安全性
3.dataGrip连接达梦数据库 DataGrip连接达梦数据库 - &大飞 - 博客园
4.更改用户密码
1.5 高速缓存至关重要 高速缓存cache memory
原因:可以优化因 cpu,硬盘,主存,性能差距过大导致导致执行时间拉长
作用:存放热数据,容量比寄存器大,比访问内存快
1.6存储设备形成层次结构 寄存器,L1高速缓存,L2高速缓存,L3高速缓存,主存,本地磁盘,远程磁盘
1.7操作系统管理硬件 作用:
1:防止硬件被失控的应用程序滥用。
2:向应用程序提供简单一致的机制来控制复杂而又通常大不相同的低级硬件设备。
1.7.1进程 上下文切换
当操作系统决定把控制权从当前进程转移到某个新进程时就会进行上下文切换。即保存当前进程上下文,恢复新进程上下文。
1.7.2线程 一个进程可以由多个线程执行单元组成,共享上下文和全局数据。
本文主要内容为MapGISGDB本地数据库的使用,包括:GDB企业管理器的认识、GDB本地数据库的创建方法、GDB本地数据库的备份和恢复。
1. GDB企业管理器的认识 GDB是地理数据的资源管理器,主要对空间数据进行有序组织与管理。
GDB数据管理包括:
1.1 数据分类管理
栅格数据,CAD数据,简单要数类,对象类,注记类,关系类,元数据等。
1.2 数据的转换
栅格数据,CAD数据,简单要数类,对象类,注记类,关系类,元数据等。
1.3 中间件的使用
通过配置中间件支持AUTOCAD、ARCGIS、SQL SERVER、ORACLE的使用。
1.4 数据权限管理
角色和用户权限管理。
1.5 数据备份与恢复
本地数据库、网络数据库的备份和恢复。
2. GDB本地数据库的创建方法 打开软件,在MapGIS资源中心界面,点击【GDB企业管理器】。
在企业管理器窗口,展开GDB连接,在【MapGISLocal】上右键→【创建数据库】。
点击【下一步】。
输入地理数据库名称,点击【下一步】。
指定数据库存放的路径,点击【下一步】。
点击完成。
数据库创建日志信息:
创建完成后,可以在MapGISLocal下看到创建的数据库了,MapGIS数据库的后缀名为.HDF。
接下来可以往数据库中导入一个矢量数据。展开数据库→空间数据→要素类→导入→其他数据。
点击【浏览】按钮,定位到矢量数据存放路径,然后点击转换。
在导入的数据上右键→预览:
再来导入一个栅格数据测试一下。展开数据库→空间数据→栅格数据集→导入→导入影像。
点击【添加文件】,定位到栅格数据存放路径,然后点击【转换】。
在导入的数据上右键→预览:
可以看到,数据库的创建和入库工作比较简单。
3. GDB本地数据库的备份方法 MapGIS中数据库的备份和恢复跟SQL Server数据库的操作原理相同。
选择需要备份的数据库,例如Test,右键→注销,然后进行拷贝。
点击【是】注销数据库,其实就是分离操作。
找到数据库存放路径,进行复制备份。
C:\MapGIS K9 SP3\Sample 4. GDB本地数据库的恢复方法 右键【MapGISLocal】→【附加数据库】。
选择备份好的数据库,指定一个新的附加名称,点击确定。
在MapGISLocal上右键→【刷新】,按照常理你就可以看到附加的数据库了。如果刷新不起作用,就重新打开GDB管理器吧。
附加成功。
刘一哥GIS 个人简介:刘一哥,多年研究地图学、地理信息系统、遥感、摄影测量和GPS等应用,精通ArcGIS等软件的应用,精通多门编程语言,擅长GIS二次开发和数据库系统开发,具有丰富的行业经验,致力于测绘、地信、数字城市、资源、环境、生态、国土空间规划、空间数字建模、无人机等领域深度应用。
刘一哥GIS技术博文首页:https://geostorm.blog.csdn.net 【推荐阅读】: 地理信息系统(刘一哥GIS)精品专栏合集
《GIS/ArcGIS风暴》
《ArcGIS10.X从入门到精通系列实验教程》(视频)
《GIS逢考必过宝典》
《ArcGIS遇上Python》
《ArcGIS实验教程从入门到精通》(附配套实验数据)
《ArcGIS Pro从入门到精通系列精品教程(微课版)》
《GIS程序设计》
《ArcGIS Engine二次开发从入门到精通》
Variable(变量) 目前官方已经弃用variable了,tensor可以直接设置requires_grad=True
来源: torch.autograd.Variable()
(一)特点 variable是一种可以不断变化的变量,符合反向传播,自动求导、参数更新的属性,除此之外和tensor没有本质区别。可通torch_data(torch_data) 进行tensor到Variable的转换variable默认不被求导 (requires_grad属性默认为False) (二)组成属性 data : 得到对象的tensor数值grad : 得到反向传播梯度requires_grad :是否需要求梯度 (三)代码展示 from torch.autograd import Variable x = Variable(torch.Tensor([3]), requires_grad=True) a = Variable(torch.Tensor([5]), requires_grad=True) bias = Variable(torch.Tensor([9]), requires_grad=True) c = Variable(torch.Tensor([12]), requires_grad=False) # 设置一个不需求导做对比 # 构建一个计算图 y = a * x + bias * c # y = a * x + bias * c= 5 * 3 + 9 * 12 # 反向传播 y.backward() # same as y.
使用MediaPipe中的面网格 Media Face Mesh做人脸面部检测调用电脑摄像头或读取电脑端的视频时出现问题:AttributeError: module ‘mediapipe.python.solutions.face_mesh’ has no attribute 'FACE_CONNECTIONS’的解决方法:
大家在使用mediapipe这个库时,经常会遇到这个问题,而导致代码报错,这时因为随着库的更新,这个函数已经换成新的名字了
将这个函数
mpFaceMesh.FACE_CONNECTIONS 换成下面这个:
mpFaceMesh.FACEMESH_CONTOURS 这样代码就可以正常运行了。
目录 为什么不强制停止
如何用 interrupt 停止线程
sleep 期间能否感受到中断
停止线程的方式有几种
总结
启动线程需要调用 Thread 类的 start() 方法,并在 run() 方法中定义需要执行的任务。启动一个线程非常简单,但如果想要正确停止它就没那么容易了。
为什么不强制停止 对于 Java 而言,最正确的停止线程的方式是使用 interrupt。但 interrupt仅仅起到通知被停止线程的作用。而对于被停止的线程而言,它拥有完全的自主权,它既可以选择立即停止,也可以选择一段时间后停止,也可以选择压根不停止。
为什么 Java 不提供强制停止线程的能力呢?
事实上,Java 希望程序间能够相互通知、相互协作地管理线程,因为如果不了解对方正在做的工作,贸然强制停止线程就可能会造成一些安全的问题。
比如:
线程正在写入一个文件,这时收到终止信号,它就需要根据自身业务判断,是选择立即停止,还是将整个文件写入成功后停止。如果选择立即停止就可能造成数据不完整,不管是中断命令发起者,还是接收者都不希望数据出现问题。
如何用 interrupt 停止线程 while (!Thread.currentThread().isInterrupted() && more work to do) { do more work } 我们一旦调用某个线程的 interrupt() 之后,这个线程的中断标记位就会被设置成 true。每个线程都有这样的标记位,当线程执行时,应该定期检查这个标记位,如果标记位被设置成 true,就说明有程序想终止该线程。
回到源码,可以看到在 while 循环体判断语句中,首先通过 Thread.currentThread().isInterrupt() 判断线程是否被中断,随后检查是否还有工作要做。&& 逻辑表示只有当两个判断条件同时满足的情况下,才会去执行下面的工作。
来段代码瞅瞅。
public class StopThread implements Runnable { @Override public void run() { int count = 0; while (!
什么是IO? Input:输入
Output:输出
我们之前学习过的scanf、printf、getchar、putchar、gets、puts这些都是标准输入输出
标准输入:数据从键盘拷贝到内存
标准输出:数据从内存拷贝到显示屏
笼统的输入和输出:
输入:数据从文件拷贝到内存--》读文件
输出:输出从内存拷贝到文件--》写文件
标准IO 2.1什么是标准IO
(1)标准:ANSI C的标准
(2)标准IO:ANSI C标准提供的一系列用来进行输入和输出的函数
(3)只要操作系统有c库就可以使用标准IO
(4)标准IO有缓存区
(5)标准IO在系统调用之上构造的
2.2文件的概念
2.3什么是缓存区,什么是系统调用
系统调用:内核给应用程序留的接口(函数)
标准IO有缓冲区,文件IO没有缓冲区,有缓冲区可以减少系统调用的次数,系统的开销就会减少
全缓存:缓冲区满、强制刷新、文件关闭、程序结束时刷新缓冲区
行缓存:遇到换行符、缓冲区满、强制刷新、文件关闭、程序结束时刷新缓冲区
不缓存:没有缓存区
打开文件,就会有缓冲区产生,就会有流存在,所以我们也说打开了流,读文件也叫对流进行读操作,写文件也叫对流进行写操作,关闭文件也叫关闭流。
或者我们说对流进行读写操作,实际上也是对文件进行读写操作。
总结:对流的操作就是对文件的操作
打开一个文件,就会有缓冲区产生,也会有一个FILE类型的变量的产生,这个FILE类型是一个结构体,用来描述一个打开的文件(一个打开的流)的详细信息,所以如何操作文件(流)就是通过指向这个结构体变量的指针来操作的
FILE *的指针其实是操作文件(流)的handle(句柄)
打开文件:FILE *类型指针产生
读写文件关闭文件:用FILE*类型的指针来操作
2.4、标准IO相关函数
注意:不需要刻意去记忆这些函数,需要用的时候去查,多用用就熟了,我们需要做的是理解流程,也就是在哪里需要用到这些函数以及用的时候流程是什么。
Fopen fread fgetc fgets fwrite fputc fputs fclose fseek ftell
Fopen 功能:打开一个文件(流)
参数:1、文件的路径 2、打开方式
返回值:成功:文件流指针 失败:NULL
对文件(流)进行读写操作 按字符读写(fgetc、fputc)--》文本文件 Feof函数可以测试是否到达文件末尾(文件末尾是有结束标志的),如果是文件结束标志就返回非0,如果返回值为0,就表示没有到文件末尾
参数:c 要写入文件的字符的ASCII值
Stream 要操作的流
返回值:成功 c
失败 -1
按行(字符串)读写(fgets、fputs)--》文本文件 功能:从stream中读字符串,将读到的字符串存放在地址为s,大小为size的这块空间中
返回值:什么时候会返回?
当读到换行符的时候会返回,并且换行符也会被读到,还不够size-1个字节没有遇到换行符,读够了size-1个就会返回 因为最后要存放’\0’
所以:fgets比gets更安全,因为fgets最多读size-1个,而gets读了size个也可以
大纲 1事先准备2说明3名词解释4搭建4.1 创建网路4.2 创建成员 5 创建终端节点6 在成员中创建对等节点 1事先准备 AWS 账户Linux 客户端(EC2 实例)一个 VPC创建接口 VPC 终端节点的权限允许在所需端口上进行通信的 EC2 安全组 2说明 由于aws提供的托管模式的区块链的搭建,我们通过aws的Amazon Managed Blockchain配合docker + Hyperledger Fabric 来搭建属于我们自己的区块链服务(私链)或直接加入到公链里面。
3名词解释 网络:指的提供账本 (ledger) 与 智能合约 (smart contract) 的底层架构。成员:指的是网络上的唯一识别 (unique identity)。对等节点:网络上的节点,负责储存账本。 4搭建 4.1 创建网路 地址:https://console.aws.amazon.com/managedblockchain/
我们这里是以私链作的教程
点开链接
我们可以看到aws的区块链框架只支持Hyperledger Fabric,这里我们选择框架的版本是2.2版本。网络版本我们选择入门填写网络名称和描述
投票策略
当我们填完上述的网络名称和投票策略以后,点击下一步开始创建我们的成员。 4.2 创建成员 填写成员配置
填写Hyperledger Fabric 的证书CA 配置
开启日志记录并点击下一步
我们在检查没有问题后点击创建
整个创建过程需要20-30分钟,所以大家不要慌张
通过上图我们可以看出我们的第一步创建一个网络和一个成员完成了 5 创建终端节点 这里需要将我们创建的blockchain加入到我们准备的vpc 和安全组里面
6 在成员中创建对等节点 这里我们要勾选上日志,后面调试的时候我们需要通过日志系统来解决
到此我们在aws控制台上的操作已经完成了,接下来我们要在ec2上通过docker搭建客户端部分了
本人学习zst_2001的课程总结如下链接:软件设计师 上午题 #9 设计模式_哔哩哔哩_bilibili
(上午题主要分清题目表达的意思是什么模式,然后很喜欢考适用性--上午题)
(下午题一定要java基础语法不然就很难通过了,我就是下午没过,各位加油呀!)
目录
设计模式总和:
创建型模式:
Abstract Factory(抽象工厂):
Builder(生成器):
Factory Method(工厂方法): Prototype(原型):
Singleton(单例):
结构型模式:
Adapter(适配器):
Bridge(桥接):
Compsite(组合): Decorator(装饰): Facade(外观): Flyweight(享元): Proxy(代理):
行为型模式: Chain of Responsibility(责任链):
Command(命令):
Iterator(迭代器):
Mediator(中介者):
Memento(备忘录): Observer(观察者) :
State(状态): Strategy(策略): Template Method(模板方法):
Visitor(访问者):
设计模式总和: 创建型模式: Abstract Factory(抽象工厂): Builder(生成器): Factory Method(工厂方法): Prototype(原型): Singleton(单例): 结构型模式: Adapter(适配器): Bridge(桥接): Compsite(组合): Decorator(装饰): Facade(外观): Flyweight(享元): Proxy(代理): 行为型模式: Chain of Responsibility(责任链): Command(命令): Interpreter(解释器):
Iterator(迭代器): Mediator(中介者): Memento(备忘录): Observer(观察者) : State(状态): Strategy(策略): Template Method(模板方法): Visitor(访问者):
MYSQL压测 常用的mysql压测工具有两个
1、Mysql自带的压力测试工具——Mysqlslap
2、第三方工具sysbench进行压力测试
一、MySQL自带的压力测试工具——Mysqlslap mysqlslap是mysql自带的基准测试工具,该工具查询数据,语法简单,灵活容易使用.该工具可以模拟多个客户端同时并发的向服务器发出查询更新,给出了性能测试数据而且提供了多种引擎的性能比较。mysqlslap为mysql性能优化前后提供了直观的验证依据,系统运维和DBA人员应该掌握一些常见的压力测试工具,才能准确的掌握线上数据库支撑的用户流量上限及其抗压性等问题。
1、更改其默认的最大连接数 再对mysql进行压力测试之前,需要更改其默认的最大连接数,
vim /etc/my.cnf
systemctl restart mysqld.service
进入mysql中查看最大连接数
进行压力测试
注意:mysqlslap好像会与default-character-set=utf8冲突
建议测试前先my.cnf文件中的default-character-set=utf8注释掉
mysqlslap --defaults-file=/etc/my.cnf --concurrency=100,200 --iterations=1 --number-int-cols=20 --number-char-cols=30 --auto-generate-sql --auto-generate-sql-add-autoincrement --auto-generate-sql-load-type=mixed --engine=myisam,innodb --number-of-queries=2000 -uroot -pabc123 --verbose
#模拟测试两次读写并发,第一次100,第二次200,自动生成SQL脚本,测试表包含20个init字段,30个char字段,每次执行2000查询请求。测试引擎分别是myisam,innodb。
–defaults-file=/etc/my.cnf 从/etc/my.cnf文件中读取默认选项
–concurrency=100,200 测试并发的线程数/客户端数,第一次100,第二次200
–iterations=1 指定测试重复次数1次
–number-int-cols=20 指定测试表中int列的数量
–number-char-cols=30 指定测试表中varchar列的数量
–auto-generate-sql 自动生成 SQL 语句
–auto-generate-sql-add-autoincrement 在自动生成的表中添加自增列
–auto-generate-sql-load-type=mixed 测试的负载模型,包括 mixed, update, write, key,read,默认是 mix
–engine=myisam,innodb 指定建表时的存储引擎
–number-of-queries=2000 指定每个线程执行的 SQL 语句数量上限(不精确)
–verbose 更详细的输出
Average number of seconds to run all queries #运行所有查询的平均秒数
# 如n=3,m=4
# 第一次出队:1
# 第二次出队:3
# 最后留下:2
python代码>>
def fun(n,m): circle=[] # 队伍列表 # 列表中每个元素的值代表这些人的实际编号,1..2..3...n for i in range(1,n+1): circle.append(i) num=1 # 从1开始报数 # 队伍中不是只剩下一个人,就要报数 while len(circle)!=1: # 每次都是列表最左面的数报数;当报完一次数,将列表最左面的这个数 放在列表最后面 ,准备下轮接着报 circle.append(circle.pop(0)) # 报完1后还要接着报2...3...4...m num+=1 # 当下一个将要报到约定数m时,需有人出列,就是目前列表最左端的那个准备报数的人,将其删除 if num==m: del circle[0] num=1 # 结束循环后,列表中只剩下一个人,将其返回 return circle[0] # 测试用例 res = fun(3,4) print(res)
https://www.librecad.org/
LibreCAD的基本使用
使用记录 How to add new lff font into LibreCAD?
command
寻找下一个访问点的方法: (1)邻接矩阵:因为邻接矩阵的列的编号顺序是从小到大,所以寻找下一个访问点可以直接访问当前访问点对应行的第一个非零元素(w未被访问) (2)邻接表:访问该点对应的边表,且前提是边表的所有结点是由下标从小到大进行排列 核心算法代码: /*无向图邻接矩阵*/ void DFSTraverse(int arc[][MAX_VERTEX], DataType *vertex, int *visited, int vertexNum, int v) { //v是遍历的起始位置的编号 static int flag = 0; if (flag == 0) {//第一次需要初始化 initvertex(vertexNum, visited); flag = 1; } visit(vertex, v); //输出访问过的顶点信息 visited[v] = 1; for (int i = 0; i < vertexNum; i++) { //因为是邻接矩阵,所以编号的顺序本来就是由小到大的.所以不用遍历找 if (arc[v][i] != 0 && visited[i] == 0) DFSTraverse(arc, vertex, visited, vertexNum, i); //二维数组传参,调用时实参直接写数组名 } } /*有向图邻接表*/ void DFSTraverse(VertexNode *adjList, int *visited, int vertexNum, int v) { static int flag = 0; if (flag == 0) {//第一次需要初始化 initvertex(vertexNum, visited); flag = 1; } visit(adjList, v); //输出访问过的顶点信息 visited[v] = 1; ArcNode *p = adjList[v].
MySQl优化:使用 jemalloc 分配内存 安装 jemalloc yum install jemalloc -y 在mysqld_safe脚本最前面添加如下信息 vim /mysql/mysql57/bin/mysqld_safe export LD_PRELOAD="/lib64/libjemalloc.so.1" 重启启动mysql实例 systemctl restart mysqld3306 验证是否使用了 jemalloc lsof -n | grep jemalloc mysqld 5508 mysql mem REG 253,0 212096 1580 /usr/lib64/libjemalloc.so.1 mysqld 5508 5509 mysql mem REG 253,0 212096 1580 /usr/lib64/libjemalloc.so.1
目录 前言: 一、程序流程控制:分支结构
(1)if-else结构
(2)Switch-case结构
二、程序流程控制:循环结构
(3)for循环结构
(4)while循环结构
(5)do-while循环结构
(6)while(true)结构的使用
(7)嵌套循环的使用
(8)特殊关键字的使用:break、continue
前言: 控制流程(也称为流程控制)是 计算机 运算领域的用语,意指在 程序 运行时,个别的指令(或是陈述、 子程序 )运行或 求值 的顺序。不论是在 声明式编程语言或是函数编程语言中都有类似的概念。 在声明式的编程语言中, 流程控制指令 是指会改变程序运行顺序的指令,可能是运行不同位置的指令,或是在二段(或多段)程序中选择一个运行。 继续运行位在不同位置的一段指令(无条件分支指令)。 若特定条件成立时,运行一段指令,例如C语言的switch指令,是一种有条件分支指令。 运行一段指令若干次,直到特定条件成立为止,例如C语言的for指令,仍然可视为一种有条件分支指令。
一、程序流程控制:分支结构 概述:
1.流程控制语句是用来控制程序中个语句执行顺序的语句,可以把语句组合成能完成一定功能的小逻辑模块。
2.流程控制方式采用结构化程序设计中规定的三种基本流程结构,即:
顺序结构:程序从上到下逐行执行,中间没有任何判断和跳转。
分支结构:根据条件选择性地执行某段代码。
有if-else和switch-case两种分支语句。
循环结构:根据循环条件,重复性的执行某段代码。
有while、do...while、for三种循环语句。
注:JDK1.5提供了foreach循环,方便的遍历集合、数组元素。
(1)if-else结构 1.说明:
1.else结构是可选的。
2.针对条件表达式:
如果多个表达式之间是互斥关系,那个判断和执行语句声明在上面都无所谓
如果多个表达式之间是有交集的关系,需要根据实际情况,考虑清楚应该将那个结构声明在上面。
如果多个表达式之间是有包含的关系,通常情况下,需要将范围小的声明在范围大的上面。否则,范围小的就没有机会执行了。
3.if-else是可以相互嵌套的。
注意:
1.if 语句至少要有一个else语句,必须在else if语句之后;
2.一旦一个else if语句为true,其他语句不再执行;
3.语句有若干else if语句,必须在else语句之前;
if语句的三种格式:
格式1:
if (条件表达式){ 执行代码块
}
格式2:二选一
if (条件表达式){ 执行代码块1 }else { 执行代码块2 } 格式3:多选一
从5月16日加入华清嵌入式这个大家庭到现在,已经过去了将近5个月的时间,我也是从一个对嵌入式近乎0基础的人慢慢变成了可以做出项目的人。在这4个半月的时间,我认识了很多认真负责的老师和勤奋好学的同学,结交了朋友,学会了人生道理,接下来我就讲一下我在华清这四个半月所经历的事吧。
第一,对于老师层面。在华清这4个半月以来,最强烈的就是老师的技术非常高端和扎实,完全足够给我们讲解知识,帮我们拓展知识面。记得刚入学这半个月,班级上大部分人对C语言不了解,甚至没接触过这个知识。老师讲完一遍,大部分人还是一知半解,班主任得到大家的反馈后,直接跟领导联系,换了一个不同风格的老师,给大家补习,这就看出来华清这个教育机构,对于我们学院来讲,真的是很用心,同一知识点愿意花时间以确保各位同学可以学会。然后每节课都有线上和回放,记得有一次我因为肠胃生病,跑了趟医院,请了半天假,第二天身体不舒服没办法去线下上课,如果是像我们上学那样,这段课程我是肯定落下了,但是在华清,我可以通过课程回放来学习下午落下的课程,第二天 我可以在家线上学习,同步老师的课程,这点非常便利,因为平时自己有不会的知识,也可以观看回放进行重新吸收。在华清这几个月的学习,每个阶段都会更换老师,换成在这个阶段专业知识最强的老师来授课,每个技术老师的专业水准都非常的高,都是所在领域的大牛,平时自己看书很难理解的部分,老师可以很清晰明了的给你解决。不仅可以帮你拓展知识层面,还会以身作则,告诉你很多社会行业经验。再就是华清的老师,真的非常非常负责,我们的班主任,每天都会监督大家按时上课,交作业,考试这些。如果我迟到了,或者没有上晚自习,班主任都会给我打电话询问原因。刚来成都的时候,我有点水土不服,手上长了一点湿疹,记得那次跟班主任说,老师会告诉我怎么处理,买什么药,整个办公室的老师,有几位都在告诉我买什么药,让我觉得身处异乡,却觉得很温暖。所以在老师这个层面,我觉得无论是技术还是责任心,华清的老师都没有让我失望。
第二,对于就业方面。其实华清这个名字,对于嵌入式行业还是很响亮的,最初我就是在网上搜索嵌入式方面的教育机构,看了一下风评,华清远见这个名字就很清晰的出现在我的视野当中,然后我去询问了这方面工作的同学,没想到他就是华清远见沈阳分部毕业的同学,他很强烈告诉我找教育机构真的可以来华清,亲身体验,很不错,也找到了工作。随后我来到华清远见程度分部,跟咨询老师聊了很多,心里更加有底了,然后我就报名了。现在在这里也学习了很久了,在课程都学完后,会有专门的就业老师来帮我们找工作,教我们写简历更好的更充分的体现我们所学的知识以便更好找到满意的工作。也会找我们聊天,了解我们所意向的城市,对我们进行模拟面试,就业面试的回答技巧之类,全方位的帮我们提高自己的面试水平,更加的专业。这些对我们的就业有很大的帮助。所以因为我自己亲身经历,所以我敢说,华清的就业方面真的是既有专业领域的认可也非常负责。
第三,我想说学习氛围方面。来到华清,像我们班,往届生和应届生几乎是对半分。无论是往届生,还是应届生,大家都对学习非常认真,晚自习几乎是没有人离开,大家都是坐在自己的位置上复习白天学习的内容,预习明天所学的知识。大家都很安静,自己学自己的。不会的可以问老师,我觉得对于任何工作,任何行业,学习氛围真的尤为重要,再这样的氛围,大家互相之间,监督着学,互相比着学,谁也不想落后,这样的氛围,怎么会学不好呢。学习的过程中,也经历过疫情,在家学习,大家都会按时截图自己所学的内容,学习效率丝毫不比线下授课差,所以,在华清,我也结交了很多优秀的学员,这可能是我宝贵的资源。
第四,对于服务方面。华清的服务方面真的非常人性化。对于很多没有经济来源的学生,华清可以让你先来学习,工作以后,有经济来源后再还学费。这一点给了很多想学知识的却没有经济收入的学生一个很好机会。然后就是在华清学习的学生,比如我们班有几个同学,因为是非相关专业,所以学习比较吃力,学校可以免费让你去下个月开的班级,重新学习这个月的内容,这点真的很好,大家即便没有学会知识,也不担心会一直跟不上们可以去新开的班级重新学习,一切都是以我们的学习成果为标准。所以华清的服务真的非常贴心和负责。
最后,在华清这四个半月的学习,教会了我想学习的知识,过程也是让我感到充实,温暖。感谢华清远见给了我这次重新跨越专业的学习机会。这段时间的旅途,不仅教会了我知识,也教会了我解决问题的思路,我会牢牢记住。希望华清远见可以越办越好,在未来的日子里,希望我和华清远见都可以各自奔赴,各自精彩,希望华清远见越办越好!
1.概念
云服务器 ECS(Elastic Compute Service)是一种安全可靠、弹性可伸缩的云计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。
用户无需提前购买硬件,即可迅速创建和释放任意多态服务器
2.特点
1)ECS的最重要的特点就是弹性,支持垂直和水平扩展两种能力
2)ECS一般提供自动宕机迁移,数据备份和回滚,系统性能报警等功能,稳定性更高
3.阿里云服务器的使用 1)地址:云服务器ECS_云主机_服务器托管_弹性计算-阿里
2) 大家可以用支付宝扫描登录,避免了实名认证
3)可以点击免费试用一个月
根据自己需要设置:
我的设置:通用推荐-->学生-->1核2G-->CentOS7.6-->1M-->40G-->现在设置,更多选项默认就行-->同意协议
创建成功
点击最右边的三个小点重置一下密码,搜索密码
然后来到安全组,设置一下开放的端口
4.云端环境准备
以下部署基于Centos7 系统环境
注意:记得一定要去安全组开放相应的端口
相关的安装包和安装教程大家到我的百度网盘拿一下:链接:百度网盘 请输入提取码
提取码:yyds
4.1,安装mysql
1)卸载Centos7自带mariadb
# 查找 rpm -qa|grep mariadb # mariadb-libs-5.5.52-1.el7.x86_64 # 卸载 rpm -e mariadb-libs-5.5.52-1.el7.x86_64 --nodeps 2)解压mysql
# 创建mysql安装包存放点 mkdir -p /usr/server/mysql # 解压 tar xvf mysql-5.7.34-1.el7.x86_64.rpm-bundle.tar 3)执行安装
# 切换到安装目录 cd /usr/server/mysql/ yum -y install libaio yum -y install libncurses* yum -y install perl perl-devel # 安装 rpm -ivh mysql-community-common-5.
第一章 .Net Core入门 1 .net core入门
第二章 .Net Core重难点知识 2.1 C#新语法
2.2 异步编程
2.3 LINQ
第三章 .Net Core核心基础组件 3.1 依赖注入
3.2 配置系统
3.3 日志
第四章 Entity Framework Core基础 4.1 EF Core
4.2 EF Core的实体配置
4.3 数据库迁移
4.4 关系配置
第五章 EF Core高级技术 5.1 EF Core原理
5.2 EF Core性能优化
5.3 表达式树
第六章 ASP.NET Core Web API基础 6.1 ASP.NET Core Web入门
6.2 Restful
6.3 ASP.NET Core Web API技术选择
第七章 ASP.NET Core基础组件 7.1 ASP.
python主要用来干什么? python主要用来编辑脚本。Python的用途真的很多很多,如果你自制力强,有上进心,想通过学习来改变现状,那么学习Python可以让你点亮高薪人生。
有对Python感兴趣的同学就赶快学习起来吧,既然选择要学python编程学Python可以做..Python是一个高层次的结合了解释性、编译性、互动性和面向对象的脚本语言。
Python的设计具有很强的可读性,相比其他语言经常使用英文关键字,其他语言的一些标点符。
Python由荷兰数学和计算机科学研究学会的Guido van Rossum于1990年代初设计,作为一门叫做ABC语言的替代品。Python提供了高效的高级数据结构,还能简单有效地面向对象编程。
Python语法和动态类型,以及解释型语言的本质,使它成为多数平台上写脚本和快速开发应用的编程语言,随着版本的不断更新和语言新功能的添加,逐渐被用于独立的、大型项目的开发。
谷歌人工智能写作项目:小发猫
python语言主要是做什么的 python是一款应用非常广泛的脚本程序语言,谷歌公司的网页就是用python编写typescript操作。python在生物信息、统计、网页制作、计算等多个领域都体现出了强大的功能。
python和其他脚本语言如java、R、Perl 一样,都可以直接在命令行里运行脚本程序。
使用Python编程的方法/步骤:1、首先下载安装python,建议安装2.7版本以上,3.0版本以下,由于3.0版本以上不向下兼容,体验较差。
2、打开文本编辑器,推荐editplus,notepad等,将文件保存成 .py格式,editplus和notepad支持识别python语法。
脚本第一行一定要写上 #!usr/bin/python表示该脚本文件是可执行python脚本如果python目录不在usr/bin目录下,则替换成当前python执行程序的目录。
3、编写完脚本之后注意调试、可以直接用editplus调试。调试方法可自行百度。脚本写完之后,打开CMD命令行,前提是python 已经被加入到环境变量中,如果没有加入到环境变量,请百度。
4、在CMD命令行中,输入 “python” + “空格”,即 ”python “;将已经写好的脚本文件拖拽到当前光标位置,然后敲回车运行即可。
更多Python相关技术文章,请访问Python教程栏目进行学习!以上就是小编分享的关于python语言主要是做什么的的详细内容希望对大家有所帮助,更多有关python教程请关注环球青藤其它相关文章!
python主要可以做什么 python主要可以做Web 和 Internet开发、科学计算和统计、桌面界面开发、软件开发、后端开发等领域的工作。Python是一种解释型脚本语言。
Python可以应用于众多领域,如:数据分析、组件集成、网络服务、图像处理、数值计算和科学计算等众多领域。
互联网公司广泛使用Python来做的事一般有:自动化运维、自动化测试、大数据分析、爬虫、Web 等。扩展资料python的主要优点:简单易学:Python是一种代表简单主义思想的语言。
阅读一个良好的Python程序就感觉像是在读英语一样。它使你能够专注于解决问题而不是去搞明白语言本身。因有极其简单的说明文档,Python极其容易上手。
运行速度快:Python 的底层是用 C 语言写的,很多标准库和第三方库也都是用 C 写的,运行速度非常快。免费、开源资源:Python是FLOSS(自由/开放源码软件)之一。
使用者可以自由地发布这个软件的拷贝、阅读它的源代码、对它做改动、把它的一部分用于新的自由软件中。FLOSS是基于一个团体分享知识的概念。
可扩展性:如果需要一段关键代码运行得更快或者希望某些算法不公开,可以部分程序用C或C++编写,然后在Python程序中使用它们。参考资料来源:百度百科-Python。
编程语言python是用来干什么的? python的作用: 1、系统编程:提供API(ApplicationProgrammingInterface应用程序编程接口),能方便进行系统维护和管理,Linux下标志性语言之一,是很多系统管理员理想的编程工具。
2、图形处理:有PIL、Tkinter等图形库支持,能方便进行图形处理。3、数学处理:NumPy扩展提供大量与许多标准数学库的接口。
4、文本处理:python提供的re模块能支持正则表达式,还提供SGML,XML分析模块,许多程序员利用python进行XML程序的开发。
5、数据库编程:程序员可通过遵循PythonDB-API(数据库应用程序编程接口)规范的模块与MicrosoftSQL Server,Oracle,Sybase,DB2,MySQL、SQLite等数据库通信。
python自带有一个Gadfly模块,提供了一个完整的SQL环境。扩展资料:python中文就是蟒蛇的意思。在计算机中,它是一种编程语言。
Python(英语发音:/ˈpaɪθən/),是一种面向对象、解释型计算机程序设计语言,由GuidovanRossum于1989年底发明,第一个公开发行版发行于1991年。
Python语法简洁而清晰,具有丰富和强大的类库。它常被昵称为胶水语言,它能够把用其他语言制作的各种模块(尤其是C/C++)很轻松地联结在一起。
常见的一种应用情形是,使用Python快速生成程序的原型(有时甚至是程序的最终界面),然后对其中有特别要求的部分,用更合适的语言改写。比如3D游戏中的图形渲染模块,性能要求特别高,就可以用C++重写。
1发展历程编辑自从20世纪90年代初Python语言诞生至今,它逐渐被广泛应用于处理系统管理任务和Web编程。Python已经成为最受欢迎的程序设计语言之一。
python主要是做什么 在我看来,Python 可以做任何事情。无论是从入门级选手到专业级选手都在做的爬虫,还是Web 程序开发、桌面程序开发还是科学计算、图像处理,Python都可以胜任。
Python为我们提供了非常完善的基础代码库,覆盖了网络、文件、GUI、数据库、文本等大量内容,被形象地称作“内置电池(Batteries included)”。
用Python开发,许多功能不必从零编写,直接使用现成的即可。除了内置的库外,Python还有大量的第三方库,也就是别人开发的,供你直接使用的东西。
当然,如果你开发的代码通过很好的封装,也可以作为第三方库给别人使用。许多大型网站就是用Python开发的,例如YouTube、Instagram,还有国内的豆瓣。
很多大公司,包括Google、Yahoo等,甚至NASA(美国航空航天局)都大量地使用Python。
龟叔给Python的定位是“优雅”、“明确”、“简单”,所以Python程序看上去总是简单易懂,初学者学Python,不但入门容易,而且将来深入下去,可以编写那些非常非常复杂的程序。
总的来说,Python的哲学就是简单优雅,尽量写容易看明白的代码,尽量写少的代码。如果一个资深程序员向你炫耀他写的晦涩难懂、动不动就几万行的代码,你可以尽情地嘲笑他。
python学习网,免费的python学习网站,欢迎在线学习!
python能做什么? python可以做:1、Web开发;2、数据科学研究;3、网络爬虫;4、嵌入式应用开发;5、游戏开发;6、桌面应用开发。
在Java网络开发的过程中接触NIO是必不可少的,在NIO中有一个重要的组件那就是 **ByteBuffer **,下面就来通过图文的方式来讲解ByteBuffer的使用以及一些操作的原理。
1. ByteBuffer实现原理 对于ByteBuffer来说主要有五个重要属性如下:
mark(int类型): 记录当前索引的位置position(int类型): 读模式:表示接下来可以读取的数据位置, 写模式:表示可以写入数据的位置limit(int类型): 读模式:表示可以写入数据大小,写模式:表示可以写入数据大小。 默认是ByteBuffer的capacitycapacity(int类型): ByteBuffer的容量hb(byte array): 实际数据存储byte数组 Tips: 几个数据之间的大小关系mark <= position <= limit <= capacity
示意图如下:
2. 读写模式 ByteBuffer主要有读写模式,Java原生的和Netty的ByteBuf有不同的。ByteBuffer的读写模式需要自己进行切换。
2.1 写模式 写模式示意图如下:
从上图可以看出来初始化后capacity是固定了。limit的值可以进行设置。当有新的数据写入position指针会进行移动。能写入的数据由limit确定。
2.2 读模式 读模式示意图如下:
如何把写入的数据读取出来,首先要将写模式转换成成读的模式。否则会读模式会在在写的指针往后进行读取。随着数据读取position指针也会进行移动,limit会限制指针移动的位置。
Tips: flip 方法用于读写模式切换
对于ByteBuffer主要是弄清楚四个变量 position、limit、mark、capacity 四者之间的关系转换以及读写的关系转换。
3. 使用示例 下面会结合例子以及示图来说明ByteBuffer的一些基本使用和一些常见API的操作。如下是一个简单的使用示例:
public class ByteBufferExample { public static void main(String[] args) { ByteBuffer allocate = ByteBuffer.allocate(20); //分配一个大小为20bytes的ByteBuffer System.out.println(allocate.capacity()); //20 System.out.println(allocate.limit()); // 20 System.out.println(allocate.position()); //0 System.out.println("--------------------"); allocate.putLong(10L); System.out.println(allocate.capacity());//20 System.
1.第一种绑定方法使用 ElementName + Path
<Button Command="{Binding SubmitCommand}" CommandParameter="{Binding ElementName=textBox1,Path=Text}" Content="提交参数"></Button> 2.第二种绑定方式。 RelativeSource
<Button Content="单击命令带参数" Command="{Binding ClickWithButtonCommand}" CommandParameter="{Binding RelativeSource={RelativeSource Mode=Self}}"/> <ComboBox> <i:Interaction.Triggers> <i:EventTrigger EventName="SelectionChanged"> <i:InvokeCommandAction Command="{Binding SelectionComboBoxCommand}" CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ComboBox}}"/> </i:EventTrigger> </i:Interaction.Triggers> <ComboBoxItem Content="张三"/> <ComboBoxItem Content="李四"/> <ComboBoxItem Content="王五"/> </ComboBox> 3.绑定自身
<Grid> <Ellipse Fill="Black" Height="100" Width="{Binding RelativeSource={RelativeSource Self},Path=Height}"> </Ellipse> </Grid
1 、按压键盘“Ctrl+Tab” 键选择已经在 SolidWorks 中打开的文件。
2、 使用“方向键/按压鼠标中键”可以旋转模型。按压 “Ctrl+方向键/按压鼠标中间”可以平行移动模型。按压 “Alt+方向键/按压鼠标中键”可以将模型沿顺时针或逆时针方向旋转。
3 、可以按压“Z” 来缩小模型或按压“Shift +Z”来放大模型。
4 、可以点击工具栏中的"显示/删除几何关系"的找出草图中过定义或悬空的几何关系。然后点击“压缩”来使草图完全定义。
5、可以按住 “Ctrl” 键并且拖动一个参考基准面来快速地复制出一个平行基准面,同时可以精确定义两个基准边之间的距离。
6 、可以在FeatureManager 设计树中拖动特征改变其位置,从而改变特征的顺序。
7、如果隐藏线视图模式的显示不够精准,可以在“工具——选项——文档属性——图象品质——线架图和高品质HLR/HLV分辨率”进行修改,以调整显示品质。
8 、您可以用拖动FeatureManager 设计树上的退回控制棒或直接拖动设计树底部的横线来退回其零件中的特征。
9 、在空白处点击鼠标右键,使用选择过滤器工具栏,您可以方便地选择实体。 10、 按住“Ctrl”键并从FeatureManager 设计树上拖动特征图标到你想要修改的边线或面上,就可以在此边线或面上完成圆角、倒角、以及孔的复制。同理,拉伸等特征也可以凭此操作来完成复制。
11、直接从FeatureManager 设计树上拖动特征图标到你想要修改的边线或面上,就可以将选中的特征“剪切”到此边线或面上。
12 、点击菜单上的“工具——选项——系统选项——颜色”,然后从列表中选择一个特征类型,接着点击“编辑”来选择颜色,可以对选中的特征类型指定颜色。
13 、在绘制草图时可以经常使用 “Esc”键将光标恢复到选择模式下。在选择模式下再按压“回车”键可以使用上一个命令。
14、当对话框打开时您可以使用视图工具栏上的图标工具或直接按压“空格键”来调整模型的视角方位。
15、 在工程图中可以将光标移到剖面视图的剖面线上,单击右键并选择其属性选项来改变剖面线。
16、您可以在零件上生成特征的阵列,以及阵列的阵列。在装配体中,您可以生成零部件的阵列以及装配体层特征的阵列。
17、如要确认工具栏按钮的功能,可以将光标移到工具栏上的图标按钮上停留一会儿,工具提示即会显示按钮的功能,并且在状态栏上会出现此工具按钮的功能描述。
18、完全定义的草图将会以黑色显示所有的实体,若有欠定义的实体则以蓝色显示。
19、 装配体中所放入的第一个零部件会默认成固定。若要移动它,将鼠标放在该零部件上点击右键,并点击“浮动”。
20 、在使用零件族表格时,将尺寸名称复制和粘贴到表格中会是一个较好的方式,这样能够确保尺寸名称相吻合。
21 、剖切线可以包括圆弧。当你能生成此剖面视图时,通过将适当视图的段落旋转到投影平面的方式来展开剖面视图。
22 、在装配体体中按住 “Ctrl”键,并且在FeatureManager 设计树中拖动一个零件或子装配体到绘图窗口内,就可以在装配体上生成该零件或子装配体的另外一个实例,即复制选中的零件或子装配体。
23 、将文件从资源管理器拖动到 SolidWorks 的窗口中,可以同时打开多个SolidWorks 的文件。
24、 点击菜单上的“工具——自定义——命令”,可以增加或消除工具栏中的图标按钮。
25 、点击工具栏上的“评估——干涉检查”来查找装配体中零件发生交叉干涉的位置。
26、若要改变特征名称可以在FeatureManager 设计树中的特征名称上缓慢点击鼠标左键两次,然后键入新的名称。
27、 可以使用菜单上的“隐藏/显示项目”来切换基准面、基准轴以及原点的显示或关闭。
28 、在“工具——自定义——键盘”中可以设定最常用命令的快捷件。
29、 点击绘图窗口顶部的“剖面视图”可以在模型上生成一个剖面视图。
#include<stdio.h> int main() { int a,b,c,d=1,e=0; printf("输入一个0,100000的数\n"); scanf("%d",&a); while(a!=0) { b=a%10; c++; a=a/10; if((b+c)%2==0) { e=e+d; } d=d*2; } printf("%d",e); return 0; } 初学阶段,简单记录一下,如果有优化代码的方案可以发出来交流一下,多多吸取不同的意见。
dminit 是 DM 数据库初始化工具。在安装 DM 的过程中,用户可以选择是否创建初始数据库。如果当时没有创建,那么在安装完成之后,可以利用创建数据库工具 dminit 来创建。
系统管理员可以利用 dminit 工具提供的各种参数,设置数据库存放路径、段页大小、是否对大小写敏感等,创建出满足用户需要的数据库。该工具位于安装目录的 /bin 目录下。
语法如下:
dminit KEYWORD=value
例如,初始化一个数据库,放在 /home/test/dmdbms 目录下,数据页 PAGE_SIZE 大小为 16 K。
./dminit PATH=/home/test/dmdbms PAGE_SIZE=16
dminit 使用较为灵活,参数较多。用户可使用“dminit HELP”快速查看各参数。
dminit HELP
格式: dminit KEYWORD=value
例如: dminit PATH=c:\dmdata PAGE_SIZE=16
关键字 说明(默认)
-----------------------------------------------------------------------------
INI_FILE 初始化文件dm.ini存放的路径
PATH 初始数据库存放的路径
CTL_PATH 控制文件路径
LOG_PATH 日志文件路径
EXTENT_SIZE 数据文件使用的簇大小(16),可选值:16、32、64,单位:页
PAGE_SIZE 数据页大小(8),可选值:4、8、16、32,单位:K
LOG_SIZE 日志文件大小(256),单位为:M,范围为:64M ~ 2G
CASE_SENSITIVE 大小敏感(Y),可选值:Y/N,1/0
CHARSET/UNICODE_FLAG 字符集(0),可选值:0[GB18030],1[UTF-8],2[EUC-KR]
SEC_PRIV_MODE 权限管理模式(0),可选值:0[TRADITION],1[BMJ],2[EVAL]
LENGTH_IN_CHAR VARCHAR类型长度是否以字符为单位(N),可选值:Y/N,1/0
SYSDBA_PWD 设置SYSDBA密码(SYSDBA),密码长度为9到48
SYSAUDITOR_PWD 设置SYSAUDITOR密码(SYSAUDITOR),密码长度为9到48
使用CubeMX对STM32进行PWM配置 一、使用CubeMX进行基本配置 1、选择定时器通道 随便选择一个为例子,TIM2的channel 1
2、对TIM2 channel1的预分频器、自动重装值等进行设置 时钟配置的是72MHZ的,预分频器就设置的71
关于PWM的模式选择
(1)、PWM mode 1:
在向上计数中,当计数值小于CCR值时输出高电平,计数值大于CCR值时输出低电平;在向下计数中,当计数值小于CCR值时输出低电平,计数值大于CCR值时输出高电平;
(2)、PWM mode 2:
在向上计数中,当计数值小于CCR值时输出低电平,计数值大于CCR值时输出高电平;在向下计数中,当计数值小于CCR值时输出高电平,计数值大于CCR值时输出低电平;
PWM频率:Freq = CK_PSC/(PSC+1)/(ARR+1)
PWM占空比:Duty = CRR/(ARR+1)
PWM分辨率:Reso = 1/(ARR+1)
二、在keil 5 中进一步完善 1、开启定时器1的通道1的PWM输出 在stm32f1xx_hal_tim.c里面找到HAL_TIM_PWM_Start()函数开启定时器1的通道1的PWM输出
/* USER CODE BEGIN TIM2_Init 2 */ HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_1); /* USER CODE END TIM2_Init 2 */** 在主函数里面或者其它地方都可以,我是在定时器的初始化里面开启的
2、改变CCR的值(改变占空比) 有两种方法,一种是调用hal库里面的__HAL_TIM_SetCompare()函数,还有一种就是直接操作寄存器`
/* USER CODE BEGIN 2 */ int speed=0; __HAL_TIM_SetCompare(&htim2,TIM_CHANNEL_1,speed); TIM2->CCR1 = speed; 与上方作用相同 /* USER CODE END 2 */
文章目录 一:Zookeeper集群组成1.1 Leader领导者1.2 Follower跟随者1.3 Observer观察者 二:zookeeper的数据结构--目录树2.1 Node节点的分类2.2 并发写同名path覆盖问题-序列节点2.3 server宕机导致session切换问题2.4 总结 三: zookeeper的选主机制3.1 zk的事务id--Zxid3.2 zk集群的2888和3888端口3.3 zk集群选主的规则3.4 zk集群选主案例3.5 zk集群不可用状态 四:zk中的数据一致性协议ZAB4.1 示例4.2 为啥leader挂了进入无主状态后要停止服务 一:Zookeeper集群组成 1.1 Leader领导者 zookeeper是基于读写分离设计的,leader既可以进行读操作,也可以进行写操作,而其它的follower和Observer只能处理client的读操作。
一个Zookeeper集群中有且只能有一个leader,而且必须有leader。zookeeper数据一致性采用的是最终一致性,所以一旦leader发生了单点故障,为了避免client从zk集群中取出错误的数据,整个服务器会进行不可用状态。所以如何在原先的leader挂掉之后快速选举一个新的leader是zk集群可靠性的关键,这点之后会讲。
1.2 Follower跟随者 Follower是作为leader的从属出现的,由于zk的最终一致性,follower最终会具备全量数据即zk特性中的统一视图,完全可以来降低leader的读压力,解决client的读操作。当leader挂掉之后,集群会进行选主工作,会从follower中选举出一个新的leader,从中可以看成follower还具备发起选举leader,以及投票权。
1.3 Observer观察者 observer的功能比follower更加单一,它不具备像follower选举新的leader的权利,它仅仅只有接收client读操作的权力。
如何配置Observer:
大家可以去zookeeper中文网上看教程:zookeeper中文网
二:zookeeper的数据结构–目录树 zookeeper和redis一样也可以储存数据,redis是以kv结构和五大基础数据类型来储存数据的,那zookeeper是如何来储存数据的呢?
图片摘自zookeeper中文网
zk储存数据类似于kv结构,key是路径path,value是data
zk是以节点为单位来储存数据的,但是zk是作为分布式协调服务出现的,虽然zk能够储存数据且数据可靠,但是一定不要将zk当作数据库用,zk在以读为主的系统中效率最高,如果频繁的写数据,或者写占用内存大的数据会降低zk的性能,zk更多的是储存ip,config配置中心,以及一些简单的数据,也可以做分布式锁,但一定不要把它当数据库用。
zk中node最多储存1M的数据。
2.1 Node节点的分类 持久节点:永久储存的节点
临时节点:zk和redis等中间件不一样,zk是没有连接池这种概念的,客户端通过session与zk server进行连接,我们可以选择将节点保存在session中,但保存在session中的节点会随着client断开或者session有效期过期而丢失。
2.2 并发写同名path覆盖问题-序列节点 我们可以通过create path date 向指定目录下创建一个节点,但如果是并发环境下,多个客户端向zookeeper同一个目录下设置相同名称的节点就会产生覆盖问题,后面执行的会把前面执行的覆盖掉。如果我们不想覆盖的话,只需要为每一个名称后面拼接一个唯一标识的后缀即可。
在zookeeper中可以通过 create -s path data 来创建一个名称序列化节点
注意:实际存入的是序列化后的节点,所以get的时候要用序列化后的文件目录路径。
注意这个拼接的后缀id是递增且不会回退的,也就是说我们可以利用这种机制来设置按照时间先后对这个同名的key进行排序,这个会在zk实现分布式锁的时候用到,后面会讲。
2.3 server宕机导致session切换问题 如果客户端连接zookeeper集群其中任意一台server,并向session中写入临时节点数据,这时,如果这台server发生宕机,那么在zookeeper集群任然可用的前提下,会自动切换到另一台server,并且储存在server中的数据并不会发生数据丢失,会与新的server建立一个同sessionid的session并保留之前的数据。
一开始连接 155机
手动关闭155server后切换到154服务器
发现其session id没有发生变化,在故障转移时,session也会跟着转移并保留内部数据。
2.4 总结 目录树的结构可以帮我们完成很多功能
一、错误处理 默认情况下,Spring Boot提供/error处理所有错误的映射
对于机器客户端(例如PostMan),它将生成JSON响应,其中包含错误,HTTP状态和异常消息的详细信息(如果设置了拦截器,需要在请求头中塞入Cookie相关参数)
对于浏览器客户端,响应一个“ whitelabel”错误视图,以HTML格式呈现相同的数据
另外,templates下面error文件夹中的4xx,5xx页面会被自动解析
二、底层相关组件 那么Spring Boot是怎么实现上述的错误页相关功能的呢?
我们又要来找一下相关源码进行分析了
首先我们先了解一个概念:@Bean配置的类的默认id是方法的名称,但是我们可以通过value或者name给这个bean取别名,两者不可同时使用
我们进入ErrorMvcAutoConfiguration,看这个类名应该是和错误处理的自动配置有关,我们看下这个类做了什么
向容器中注册类型为DefaultErrorAttributes,id为errorAttributes的bean(管理错误信息,如果要自定义错误页面打印的字段,就自定义它),这个类实现了ErrorAttributes, HandlerExceptionResolver(异常处理解析器接口), Ordered三个接口 @Bean @ConditionalOnMissingBean( value = {ErrorAttributes.class}, search = SearchStrategy.CURRENT ) public DefaultErrorAttributes errorAttributes() { return new DefaultErrorAttributes(); } 点进去后发现,这个类是和我们响应页面中的message、error等字段有关
向容器中注册一个id为basicErrorController的控制器bean(管理错误相应逻辑,不想返回json或者错误视图,就自定义它) @Bean @ConditionalOnMissingBean( value = {ErrorController.class}, search = SearchStrategy.CURRENT ) public BasicErrorController basicErrorController(ErrorAttributes errorAttributes, ObjectProvider<ErrorViewResolver> errorViewResolvers) { return new BasicErrorController(errorAttributes, this.serverProperties.getError(), (List)errorViewResolvers.orderedStream().collect(Collectors.toList())); } 这个控制器就和前面我们返回json或者错误视图有关
声明类型为DefaultErrorViewResolver,id为conventionErrorViewResolver的bean(管理错误视图跳转路径,如果要改变跳转路径,就自定义它) @Configuration( proxyBeanMethods = false ) @EnableConfigurationProperties({WebProperties.class, WebMvcProperties.class}) static class DefaultErrorViewResolverConfiguration { private final ApplicationContext applicationContext; private final Resources resources; DefaultErrorViewResolverConfiguration(ApplicationContext applicationContext, WebProperties webProperties) { this.
vue的生命周期是什么 Vue 实例从创建到销毁的过程,就是生命周期。也就是从开始创建、初始化数据、编译模板、挂载Dom→渲染、更新→渲染、卸载等一系列过程,我们称这是 Vue 的生命周期。
vue生命周期的作用是什么?
让我们在控制整个Vue实例的过程时更容易形成好的逻辑。
要想很好滴了解Vue生命周期就要看下官方给的图
我们可以清晰的看出顺序从上到下被执行,其中我们能看见你的有8的标志性的函数我们先在来
介绍下!
1、创建前(beforeCreate) 对应的钩子函数为beforeCreate。此阶段为实例初始化之后,此时的数据观察和事件机制都未形成,不能获得DOM节点。
2、创建后(created) 对应的钩子函数为created。在这个阶段vue实例已经创建,仍然不能获取DOM元素。
3、载入前(beforeMount) 对应的钩子函数是beforeMount,在这一阶段,我们虽然依然得不到具体的DOM元素,但vue挂载的根节点已经创建, 下面vue对DOM的操作将围绕这个根元素继续进行;beforeMount这个阶段是过渡性的,一般一个项目只能用到一两次。
4、载入后(mounted) 对应的钩子函数是mounted。mounted是平时我们使用最多的函数了,一般我们的异步请求都写在这里。在这个阶段,发送请求 启动定时器 绑定自定义事件。
5、更新前(beforeUpdate) 对应的钩子函数是beforeUpdate。在这一阶段,vue遵循数据驱动DOM的原则。beforeUpdate函数在数据更新后虽然没立即更新数据,但是DOM中的数据会改变,这是Vue双向数据绑定的作用。
6、更新后(updated) 对应的钩子函数是updated。在这一阶段DOM会和更改过的内容同步。
7、销毁前(beforeDestroy) 对应的钩子函数是beforeDestroy。在上一阶段Vue已经成功的通过数据驱动DOM更新,当我们不再需要vue操纵DOM时, 就要解绑自定事件 清除定时器,取消订阅消息等收尾工作。
8、销毁后(destroyed) 对应的钩子函数是destroyed。在销毁后,会触发destroyed钩子函数。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="root"> <!-- <h2>当前n的值是:<span v-text="n"></span></h2>--> <!-- <button @click="add">点我n++</button>--> <!-- <button @click="bye">点击销毁vm</button>--> </div> <script src="./js/vue.js"></script> <script> Vue.config.productionTip = false; let vm = new Vue({ el: '#root', template: ` <div> <h2>当前n的值是:<span v-text="
pca 1 PCAtools 1.1 加载R包 library(PCAtools) library(tidyverse) 1.2 加载数据,构建表达矩阵和分组信息(以iris为例) iris <- as.data.frame(iris) iris <- iris %>% mutate(class = str_c("a",1:dim(iris)[1],sep = "")) rownames(iris) <- iris$class iris <- iris[,-6] head(iris) Sepal.Length Sepal.Width Petal.Length Petal.Width Species a1 5.1 3.5 1.4 0.2 setosa a2 4.9 3.0 1.4 0.2 setosa a3 4.7 3.2 1.3 0.2 setosa a4 4.6 3.1 1.5 0.2 setosa a5 5.0 3.6 1.4 0.2 setosa a6 5.4 3.9 1.7 0.4 setosa # 构建矩阵 expr=iris[c(1,2,3,4)] # 表达矩阵,行是基因,列是样本名 head(expr) Sepal.
SpringBoot整合jdbcTemplate执行SQL脚本文件 DriverManagerDataSource dataSource=new DriverManagerDataSource(); dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");//连接mysql dataSource.setUrl("jdbc:mysql://ip:3306"); dataSource.setUsername("root"); dataSource.setPassword("root"); JdbcTemplate jdbcTemplate=new JdbcTemplate(dataSource); Map<String, Object> map = jdbcTemplate.queryForMap(""); System.out.println(map); int update = jdbcTemplate.update(""); System.out.println(update); File file=new File("xxx.sql"); FileReader fileReader=new FileReader(file); BufferedReader bf=new BufferedReader(fileReader); StringBuffer sb=new StringBuffer(); String line; while ((line = bf.readLine()) != null) { sb.append(line); sb.append("\n"); } System.out.println(sb); jdbcTemplate.execute(sb.toString()); Connection connection = jdbcTemplate.getDataSource().getConnection(); ScriptRunner runner = new ScriptRunner(connection); runner.setAutoCommit(true); File file = new File("xxxx.sql"); if (file.getName().endsWith(".sql")) { runner.setFullLineDelimiter(false); runner.setDelimiter(";");//语句结束符号设置 runner.setLogWriter(null);//日志数据输出,这样就不会输出过程 runner.
文章目录 前言一、mysql主从复制原理(一)为啥要用主从复制?(二)什么是Mysql主从复制?(三)mysql主从复制原理剖析①原理:②通俗的来讲:③注意: (四)主从复制搭建种类及过程图 二、主从搭建概览三、主从搭建步骤(一主一从)(一)新建主服务器实例①起一个服务②配置文件③重启服务④进入mysql-master容器⑤创建数据同步用户 (二)新建从服务器实例①起一个服务②配置文件③重启服务④在主数据库中查看主从同步状态⑤进入mysql-slave容器⑥在从数据库中查看主从同步状态(参数说明)⑦在从数据库中开启主从同步 (三)测试主机新建库并插入数据从机进行数据查询 前言 存储数据的时候我们一般使用文件,如果随着数据量的剧增,有些文件我们将面临打开时间过长或者,打不开的风险,所以我们可以使用数据库进行大量数据存储,使用数据库进行存储的时候又会考虑到数据库的性能问题,如何提高数据库使用的性能就是我们今天要学的,主数据库进行增删改业务,从数据库进行查询业务,既提升了数据库的性能,又保障了数据的安全性。
一、mysql主从复制原理 (一)为啥要用主从复制? 在业务复杂的系统中,有这么一个情景,有一句sql语句需要锁表,导致暂时不能使用读的服务,那么就很影响运行中的业务,使用主从复制,让主库负责写,从库负责读,这样,即使主库出现了锁表的情景,通过读从库也可以保证业务的正常运作。
做数据的热备(采用多级主从数据库,可以将写入的数据立即同步到存储数据库)
架构的扩展。业务量越来越大,I/O访问频率过高,单机无法满足,此时做多库的存储,降低磁盘I/O访问的频率,提高单个机器的I/O性能。
(二)什么是Mysql主从复制? MySQL 主从复制是指数据可以从一个MySQL数据库服务器主节点复制到一个或多个从节点。MySQL 默认采用异步复制方式,这样从节点不用一直访问主服务器来更新自己的数据,数据的更新可以在远程连接上进行,从节点可以复制主数据库中的所有数据库或者特定的数据库,或者特定的表。
(三)mysql主从复制原理剖析 ①原理: (1)master服务器将数据的改变记录二进制binlog日志,当master上的数据发生改变时,则将其改变写入二进制日志中;
(2)slave服务器会在一定时间间隔内对master二进制日志进行探测其是否发生改变,如果发生改变,则开始一个I/OThread请求master二进制事件
(3)同时主节点为每个I/O线程启动一个dump线程,用于向其发送二进制事件,并保存至从节点本地的中继日志中,从节点将启动SQL线程从中继日志中读 取二进制日志,在本地重放,使得其数据和主节点的保持一致,最后I/OThread和SQLThread将进入睡眠状态,等待下一次被唤醒。
②通俗的来讲: 从数据库会生成两个线程,一个I/O线程,一个SQL线程;I/O线程会去请求主数据库的binlog,并将得到的binlog写到本地的relay-log(中继日志)文件中;主数据库会生成一个log dump线程,用来给从数据库I/O线程传binlog;SQL线程,会读取relay log文件中的日志,并解析成sql语句逐一执行; ③注意: master将操作语句记录到binlog日志中,然后授予slave远程连接的权限(master一定要开启binlog二进制日志功能;通常为了数据安全考虑,slave也开启binlog功能)。slave开启两个线程:IO线程和SQL线程。其中:IO线程负责读取master的binlog内容到中继日志relay log里;SQL线程负责从relay log日志里读出binlog内容,并更新到slave的数据库里,这样就能保证slave数据和master数据保持一致了。Mysql复制至少需要两个Mysql的服务,当然Mysql服务可以分布在不同的服务器上,也可以在一台服务器上启动多个服务。Mysql复制最好确保master和slave服务器上的Mysql版本相同(如果不能满足版本一致,那么要保证master主节点的版本低于slave从节点的版本)master和slave两节点间时间需同步 (四)主从复制搭建种类及过程图 一主一从 实际生产环境中并不一定会使用
主主复制 可以防止某机器宕机,而带来的不必要的损失
一主多从 如果查询工作较多操作较为频繁可以选这种模式
多主一从 写入操作较多的时候可以选这种模式
级联复制 级联复制一般用于数据的存储备份。
二、主从搭建概览 1、从库通过手工执行change master to 语句连接主库,提供了连接的用户一切条件(user 、password、port、ip),并且让从库知道,二进制日志的起点位置(file名 position 号); start slave
2、从库的IO线程和主库的dump线程建立连接。
3、从库根据change master to 语句提供的file名和position号,IO线程向主库发起binlog的请求。
4、主库dump线程根据从库的请求,将本地binlog以events的方式发给从库IO线程。
5、从库IO线程接收binlog events,并存放到本地relay-log中,传送过来的信息,会记录到master.info中
6、从库SQL线程应用relay-log,并且把应用过的记录到relay-log.info中,默认情况下,已经应用过的relay 会自动被清理purge
三、主从搭建步骤(一主一从) (一)新建主服务器实例 ①起一个服务 创建主服务器,端口映射到3307
参考版本 2019.3, 箭头(->)表示菜单顺序
常用设置菜单路径 修改主题:
Apperance & Behavior -> Apperance -> UI Options -> Theme
代码自动(软)换行:
Setting ->Editor -> General -> Soft Wraps -> 选择"Use soft wraps in editor", (新版本是"Soft-wrap files *", 添加需要自动换行的文件扩展名)
修改代码字体:
Setting ->Editor -> General -> Font
注释用斜线不在行头:
Setting ->Editor -> Code Style -> PHP -> Wrapping and Braces -> Keep when reformatting -> 取消"Comment at first column"
以及:
Setting ->Editor -> Code Style -> PHP -> Code Generation -> Comment Code -> 取消 “Line comment at first column”
python皮卡丘编程代码 import turtledef getPosition(x, y): (x) (y) print(x, y)class Pikachu: def __init__(self): self.t = turtle.Turtle() t = self.t t.pensize(3) t.speed(9) t.ondrag(getPosition)def noTrace_goto(self, x, y): self.t.penup() (x, y) self.t.pendown() def leftEye(self, x, y): self.noTrace_goto(x, y) t = self.t t.seth(0) t.fillcolor('#333333') t.begin_fill() t.circle(22) t.end_fill() self.noTrace_goto(x, y+10) t.fillcolor('#000000') t.begin_fill() t.circle(10) t.end_fill() self.noTrace_goto(x+6, y + 22) t.fillcolor('#ffffff') t.begin_fill() t.circle(10) t.end_fill() def rightEye(self, x, y): self.noTrace_goto(x, y) t = self.t t.seth(0) t.fillcolor('#333333') t.begin_fill() t.circle(22) t.
这种情况一般是 激活码过期或者出现问题,当我们打开idea超过三十分钟,idea会自动关闭
解决方法在下面
首先 下载插件
(把这个网址复制并打开)
https://plugins.zhile.io/files/ide-eval-resetter-2.1.6.zip
进入idea
打开设置
寻找到离线导入插件(刚刚下载的插件)(我这边在 插件市场搜不到) 选择我们要导入的插件jar包
下载成功后 apply
我是这也修好的 如果你修不好的话 也请不要问我
1. 场景 通过小程序智能识别通用文字功能,可将名片上的相关信息进行识别实现数据化,然后同步到爱客CRM创建线索,无需人工再一一对照名片信息进行录入,省时省力。
2. 如何搭建自动化流程? 提前准备工作:
集简云账号爱客CRM账号手机端-微信app 整体思路:a. 集简云平台【搭建数据流程】→ b. 手机端小程序【上传名片】→ c. 回到集简云平台【完善流程】→ d. 登录爱客CRM【查看线索】
a. 集简云平台【搭建数据流程】
进入集简云主界面,点击左侧导航栏【新建流程】,开始创建数据流程
步骤1:选择触发应用(触发是指当一个事件发生时,触发数据流程。 而产生触发事件的应用系统就是触发系统,每个流程中仅有一个触发功能,执行功能可有多个)
1)选择触发应用【集简云小程序】 2)选择触发动作【当小程序上传图片智能识别数据时】,保存进行下一步
3)字段设置【触发数据类型:通用文字识别】
4)获取样本数据(样本数据是一条真实的数据,主要有两个作用,一是这些数据在后续的步骤中需要使用到,二是可以检查此步骤是否按照我们期待的来执行,保障我们的流程能够正常走通,不会在流程保存后出现大量的错误问题。因此,我们建议不要跳过获取样本环节)
注:这里集简云小程序的样本数据为模拟样本数据,真实的样本数据需要我们搭建完整个流程保存后,去手机端搜索"集简云小程序"上传营业执照进行触发
步骤2:选择执行应用(执行应用是用于执行动作的应用系统。每个流程中仅有一个触发功能,执行功能可有多个)
1)选择执行应用【爱客CRM】
2)选择执行动作【创建线索】,保存进入下一步
3)选择账户,首次使用需要点击【添加新账户】,然后会自动弹出 "授权帮助文档",按步骤操作即可,这里我们选择已添加好的账户
4)字段匹配,先随便添加一个字段,待真正的样本数据生成后再一一进行填写
5)获取到一条样本数据
6)右上角【保存该流程】
b. 手机端小程序【上传名片】
打开手机-微信搜索"集简云小程序"-按照指示一一操作上传名片即可
c. 回到集简云平台【完善流程】- d. 登录爱客CRM【查看线索】
近两年,基于纯视觉BEV方案的3D目标检测备受关注,all in one方式,确实能将基于camera的3D检测算法性能提升一大截,甚至直逼激光雷达方案,这次整理了领域中一些备受关注的multi-camera bev纯视觉感知方案,包括DETR3D、BEVDet、ImVoxelNet、PETR、BEVFormer、BEVDepth、BEVDet4D、BEVerse等!
1.DETR3D(CoRL 2021) DETR3D: 3D Object Detection from Multi-view Images via 3D-to-2D Queries
在自动驾驶的环视相机图像中做3D目标检测是一个棘手的问题,比如怎么去从单目相机2D的信息中预测3D的物体、物体形状大小随离相机远近而变化、怎么融合各个不同相机之间的信息、怎么去处理被相邻相机截断的物体等等。
将Perspective View转化为BEV表征是一个很好的解决方案,主要体现在以下几个方面:
BEV是一个统一完整的全局场景的表示,物体的大小和朝向都能直接得到表达;
BEV的形式更容易去做时序多帧融合和多传感器融合;
BEV更有利于目标跟踪、轨迹预测等下游任务。
DETR3D是21年非常经典的多视角图像3D目标检测工作,论文介绍了一种多camera三维目标检测框架。与直接从单目图像估计3D box或使用深度预测网络从2D信息生成3D目标检测输入数据的现有工作不同,论文的方法直接在3D空间中操纵预测。DETR3D从多个camera图像中提取2D特征,然后使用稀疏的3D对象查询集索引到这些2D特征,使用相机变换矩阵将3D位置链接到多视图图像。最后,模型对每个对象查询进行边界框预测,使用一个set-to-set的损失来计算GT和预测之间的差异。这种自顶向下的方法优于自底向上的方法,其中对象边界框预测遵循逐个像素深度估计,因为它不受深度预测模型引入的复合误差的影响。此外,DETR3D不需要后处理,如非最大值抑制,大大提高了推理速度,在nuScenes基准上实现了SOTA!
如上图所示,object queries是类似DETR那样,即先随机生成 M个bounding box,类似先生成一堆anchor box,只不过这里的box是会被最后的loss梯度回传的。(蓝线)然后通过一个子网络,来对query预测一个三维空间中的参考点 cℓi (实际上就是3D bbox的中心)。通过角标我们可以看出,这个操作是layer-wise、query-wise的。绿线利用相机参数,将这个3D参考点反投影回图像中,找到其在原始图像中对应的位置。黄线从图像中的位置出发,找到其在每个layer中对应的特征映射中的部分。红线利用多头注意力机制,将找出的特征映射部分对queries进行refine。这种refine过程是逐层进行的,理论上,更靠后的layer应该会吸纳更多的特征信息。(黑色虚线框之后)得到新的queries之后,再通过两个子网络分别预测bounding box和类别,然后就进入loss部分,性能提升如下图所示:
2.BEVDet(2021) High-Performance Multi-Camera 3D Object Detection in Bird-Eye-View
自主驾驶感知周围环境进行决策,这是视觉感知中最复杂的场景之一。在解决2D目标检测任务方面的成功创新激励领域寻求一种优雅、可行和可扩展的范式,从根本上推动该领域的性能边界。为此,论文贡献了BEVDet范式,BEVDet在鸟瞰图(BEV)中执行3D对象检测,其中定义了大多数目标值,并且可以方便地执行路线规划。论文仅仅重用现有的模块来构建其框架,但通过构建独占数据增强策略和升级非最大抑制策略来大幅提高其性能。在实验中,BEVDet在精度和时间效率之间提供了一个很好的平衡。作为一个fast版本,BEVDet Tiny在nuScenes val集上的mAP和NDS得分分别为31.2%和39.2%。它与FCOS3D相当,但只需要11%的计算预算,即215.3 GFLOPs,并以15.6 FPS的速度运行(9.2倍)。另一个被称为BEVDet的高精度版本的基础分数为39.3%的mAP和47.2%的NDS,大大超过了所有公布的结果。在相当的推理速度下,它大大超过FCOS3D,+9.8%的mAP和+10.0%的NDS。BEVDet整体结构如下所示:
如上所示,BEVDet采用模块化设计,由四个模块组成:图像视图编码器,包括主干(Resnet+swin-transformer)和neck(FPN-LSS),首先用于图像特征提取,视图转换器将特征从图像视图转换为BEV(网络将图像视图特征作为输入,并通过分类方式密集预测深度。然后,分类分数和导出的图像视图特征用于渲染预定义的点云。最后,可以通过沿垂直方向(即,如上图示的Z坐标轴)应用汇集操作来生成BEV特征)。BEV编码器进一步编码BEV特征。最后,基于BVE特征构建任务特定头部,并预测3D对象的目标值。下图为各个模块的详细参数!
BEVDet在nuscenes上的性能对比如下:
3.ImVoxelNet(WACV 2022) Image to Voxels Projection for Monocular and Multi-View General-Purpose 3D Object Detection
论文基于多视图RGB的3D对象检测任务引入端到端优化问题,为了解决这个问题,提出了ImVoxelNet,这是一种新的基于单视点或多视点RGB图像的三维目标检测的全卷积方法。在训练和推理期间,每个多视图输入中的单目图像的数量可以变化;实际上,对于每个多视图输入,这个数字可能是唯一的。ImVoxelNet成功地处理了室内和室外场景,这使其具有通用性。在RGB图像的所有方法中,它在KITTI(单目)和nuScenes(多视图)基准上实现了最先进的机动车检测结果。而且,在SUN RGB-D数据集上优于现有的基于RGB的3D对象检测方法。在ScanNet上,ImVoxelNet为多视图3D对象检测设定了新的基准。ImVoxelNet网络结构如下所示:
论文的方法接受一组任意大小的RGB输入以及相机姿态。首先使用2D卷积主干从给定图像中提取特征,然后将获得的图像特征投影到三维体素体。对于每个体素,来自多个图像的投影特征通过简单的元素平均聚合。接下来,将具有指定特征的体素体积传递到称为颈部的3D卷积网络。颈部的输出用作最后几个卷积层(头部)的输入,预测每个锚的边界框特征。生成的边界框被参数化为(x,y,z,w,h,l,θ),其中(x,y,z)是中心坐标,w,h,l表示宽度、高度和长度,θ是围绕z轴的旋转角。
针对户外场景,论文将3D目标检测重新表述为BEV平面中的2D对象检测,遵循常规做法。使用了在KITTI和nuScenes数据集上似乎有效的2D anhcor-head。由于室外3D检测方法是在汽车上评估的,因此所有物体都具有相似的尺度,属于同一类别。对于单尺度和单类检测,Head由两个平行的二维卷积层组成。一层估计类概率,而另一层回归边界框的七个参数。
针对室内场景:论文提出现代室内3D对象检测方法都对稀疏点云表示执行深度霍夫投票,相反,论文使用中间特征的密集体素表示。据我们所知,没有用于3D对象检测的密集3D多尺度头部。受二维检测方法FCOS的启发,论文构建了这样的头部。原始FCOS头部接受来自FPN的2D特征,并通过2D卷积层估计2D边界框,为了使FCOS适用于3D检测,将2D卷积替换为3D卷积来处理3D输入。遵循FCOS和ATSS,应用中心采样来选择候选对象位置。在这些工作中,选择了9名(3×3)候选目标;由于论文在3D空间中操作,将每个对象的候选位置限制为27个(3×3×3)。生成的头部由三个三维卷积层组成,分别用于分类、定位和中心度,权重在所有对象尺度上共享。
室外性能对比分析:
项目场景: 在运行ssm项目的时候,运行服务器,可以出现初始界面,但是在输入URL后,IDEA后台出现
18-Sep-2022 09:17:01.738 信息 [Catalina-utility-1] org.apache.catalina.startup.HostConfig.deployDirectory Web应用程序目录[D:\Tomcat\apache-tomcat-9.0.56\webapps\manager]的部署已在[125]毫秒内完成
九月 18, 2022 9:17:26 上午 org.apache.catalina.core.ApplicationContext log
信息: Initializing Spring DispatcherServlet 'springmvc'
之后便没有任何反应
原因分析: 因为服务器启动没有问题,猜想可能是因为读取不到数据库数据
解决方案: 通过排查发现,我的mysql版本是8.0.25,而maven添加的mysql版本是8.0.22,所以controller层无法读取到数据
1.安装常用网络命令net-tools工具包
[root@oracle network-scripts]# yum -y install net-tools
2.查看自己的IP [root@oracle network-scripts]# ifconfig
自己的ip是ens33下的 192.168.128.128(查看Ip是为了设置固定IP时可以直接将这个IP设为你的固定IP)
3.IP配置信息
[oracle@oracle ~]$ vim /etc/sysconfig/network-scripts/ifcfg-ens33
TYPE="Ethernet" #网卡类型:以太网
PROXY_METHOD="none"
BROWSER_ONLY="no"
BOOTPROTO="dhcp" #IP获取方式 dhcp:动态IP static:静态IP
DEFROUTE="yes"
IPV4_FAILURE_FATAL="no"
IPV6INIT="yes"
IPV6_AUTOCONF="yes"
IPV6_DEFROUTE="yes"
IPV6_FAILURE_FATAL="no"
IPV6_ADDR_GEN_MODE="stable-privacy"
NAME="ens33" #网卡名称:
UUID="0f43a4e9-104d-423c-a3ee-86677483f6f5"
DEVICE="ens33" #物理设备名
ONBOOT="yes" #是否自动引导,即随机自启
设置为静态IP的方法
--step1:将IP获取方式改为静态
BOOTPROTO="static"
--step2:添加IP信息
IPADDR="192.168.128.128" # 设置的静态IP地址 3-127
NETMASK="255.255.255.0" # 子网掩码
GATEWAY="192.168.128.2" # 网关地址
DNS1="192.168.128.2" # DNS首选服务器
DNS2="192.168.128.0" # DNS备选服务器
--step3:重启网络服务
service network restart
到这,固定IP基本就设置成功了
再去主机配置一下
1.找到更改适配器选项
2.找到VMnet8并打开
3.点击属性
一、显示目录信息(-ls)
hadoop fs -ls / 二、在hdfs上创建目录(-mkdir)
普通创建:hadoop fs -mkdir /xiaolin递归创建:hadoop fs -mkdir -p /xiaolin/xiaoyin 三、从本地剪切文件粘贴到hdfs上(-moveFromLocal)
mkdir xuan.txthadoop fs -moveFromLocal xuan.txt /xiaolin 四、把本地文件复制到hdfs上(-copyFromLocal或者-put)
hadoop fs -copyFromLocal xuan.txt /hadoop fs -put xuan.txt / 五、从hdfs复制文件到本地上(-copyToLocal或者-get)
hadoop fs -copyToLocal /xiaolin ./ hadoop fs -get /xiaolin ./ 六、在hdfs里拷贝文件路径到另一个路径上(-cp)
hadoop fs -mkdir /xiaonahadoop fs -cp /xiaolin/xuan.txt /xiaona/ 七、追加文件到hdfs里的文件末尾(-appendToFile)
vim zero.txthadoop fs -appendToFile zero.txt /xiaolin/xuan.txt 八、显示文件内容(-cat)
hadoop fs -cat /xiaolin/xuan.txt 九、修改文件所属权限(-chmod)
hadoop fs -chmod 777 /xiaolin/xuan.txt 十、移动文件(-mv)
1 内容介绍 1998年,Norden E. Huang(黄锷:中国台湾海洋学家)等人提出了经验模态分解方法,并引入了Hilbert谱的概念和Hilbert谱分析的方法,美国国家航空和宇航局(NASA)将这一方法命名为Hilbert-Huang Transform,简称HHT,即希尔伯特-黄变换。
HHT主要内容包含两部分,第一部分为经验模态分解(Empirical Mode Decomposition,简称EMD),它是由Huang提出的;第二部分为Hilbert谱分析(Hilbert Spectrum Analysis,简称HSA)。简单说来,HHT处理非平稳信号的基本过程是:首先利用EMD方法将给定的信号分解为若干固有模态函数(以Intrinsic Mode Function或IMF表示,也称作本征模态函数),这些IMF是满足一定条件的分量;然后,对每一个IMF进行Hilbert变换,得到相应的Hilbert谱,即将每个IMF表示在联合的时频域中;最后,汇总所有IMF的Hilbert谱就会得到原始信号的Hilbert谱。
2 部分代码 clear all;
close all
signal=load('Signal.txt');
N=length(signal);
fs=1840; % 采样频率
wp=[50 150]*2/fs; %对原始信号进行滤波处理
ws=[30 200]*2/fs;
rp=1;
rs=15;
[num wn]=cheb2ord(wp,ws,rp,rs);
[b,a]=cheby2(num,rs,wn);
s=filter(b,a,signal);
S=s'; % 将滤波后信号赋值给S
YSS=S; % 滤波信号为始信号
ts=(1/fs); % 采样时间
t=0:ts:ts*(N-1); %画图---滤波后信号
figure(1)
plot(t,s); set(gcf,'color',[1,1,1]);
grid on; xlabel('Time(ms)');
ylabel('amplitude(mv)');
title('时域图');
legend('115kHz');
axis([0,0.5,-inf,inf]);
% 设置程序中需要用到的标志位
overf=0; % 是否结束信号分解过程
overimf=0; % IMF的结束标志
%信号处理部分
SD=1; % 设置程序中需要的SD、初值
HH=0.01*ones(1,N); % 设置程序中需要的HH初值
LInux系统时钟
基础概念
Linux的时钟分为系统时钟(System Clock)和硬件时钟(Real Time Clock ,简称RTC)。
硬件时钟:芯片时钟,由计算机主板上的时钟芯片提供。在计算机关机的情况下,一直保持走时,由主板上的纽扣电池长时间给时钟芯片供电。
系统时钟:操作系统提供的时钟,指当前Linux内核中的时间。开机时会从硬件时钟读取时间。
Linux下的常见时钟命令:
datehwclocktimedatectl date命令常见用法
date直接执行,查看系统时间
指定格式
date "+%Y-%m-%d %H:%M:%S" 设置(修改)时间
date -s "2022-09-17 15:29" hwclock
hwclock直接执行,查看硬件时间hwclock -w:同步系统时间到硬件时钟hwclock -s: 同步硬件时间到系统时间 timedatectl常见用法
命令作用timedatectl查看系统时钟设置timedatectl set-time “2022-09-17 15:39:45”设置系统时间timedatectl set-ntp true/false控制是否与网络时间同步timedatectl set-timezone Asia/Shanghai设置时区timedatectl list-timezones列出所有时区timedatectl set-local-rtc 1设置硬件时钟为本地时间timedatectl set-local-rtc 0设置硬件时钟为协调世界时间(UTC时间) 时间同步主要有ntp和chrony两种方式,具体配置方式可自行百度查询。
使用Https://域名/接口路径 调用后台接口 以阿里云免费DV单域名证书和Windows系统为例
1. 获取阿里云单域名证书 搜索SLL证书进入控制台:
点击SSL证书 - 免费证书 - 立即购买:
创建证书 - 证书申请 :
切换到申请域名的网站,将下列信息填到域名解析中:
下载对应的服务器,这里选nginx:
2. nginx配置修改 nginx目录创建cert文件夹,将下载下来的证书解压放到cert目录下:
修改nginx.conf配置文件:
重启nginx,使用https://域名/接口访问接口:
文章目录 前言一、实现流程二、实现步骤 1.简易菜单界面2.创建棋盘3.对棋盘初始化4.打印棋盘5.玩家落子6.电脑落子7.判断输赢三.具体代码展示 前言 三子棋是我们小时候常玩的小游戏,它的游戏方法比较简单,就是在一个棋盘上分先后手,下放不同位置的棋子,当你有三个棋子连接到一条线上(横向、竖向、斜向均可),你就赢得了比赛,简而言之是比较容易的,下面我们通过C语言实现它(这里是实现玩家与电脑对下,电脑随机落子)。
提示:以下是本篇文章正文内容,下面案例可供参考
一、实现流程 1.创建简易菜单。
2.初始化棋盘。
3.打印棋盘。
4.玩家下棋(用‘x’表示玩家输入的坐标)输入行和列,用 ‘ * ’ 表示玩家落子。
5.电脑下棋(电脑随机下棋),用 ‘ # ’ 表示电脑落子。
6.判断输赢
二、使用步骤 1.创建菜单 1.开始游戏 0.退出游戏
void menu() { printf("*********************\n"); printf("******* 1.play ******\n"); printf("******* 0.exit ******\n"); printf("*********************\n"); } 2.创建棋盘 这里用到的是char类型的二维数组来演示。
使用宏代码的优点:
1.提高代码的可读性
2.方便以后对其进行修改,只需要修改宏定义的值不需要修改其他值。
#include <stdlib.h> #include <time.h> #define ROW 3 #define COL 3 3.初始化棋盘 用字符‘ ’表示我们棋盘上的尚未落子的位置。
void init_board(char board[ROW][COL], int row, int col) { int i = 0; int j = 0; for (i = 0; i < row; i++) { for (j = 0; j < col; j++) { board[i][j] = ' '; } } } 4.
一. 问题:在pom.xml文件中导入spring坐标报错 ··· 控制台输出错误信息:
Cannot resolve org.springframework:spring-context:pom:5.2.10.RELEASE failed to transfer from https://repo.maven.apache.org/maven2 during a previous attempt. This failure was cached in the local repository and resolution is not reattempted until the update interval of central has elapsed or updates are forced. Original error: Could not transfer artifact org.springframework:spring-context:pom:5.2.10.RELEASE from/to central (https://repo.maven.apache.org/maven2): transfer failed for https://repo.maven.apache.org/maven2/org/springframework/spring-context/5.2.10.RELEASE/spring-context-5.2.10.RELEASE.pom
··· 如图:
二. 解决方法 ·· 步骤1:找到 springframework 目录文件,将其删除,并重启IDEA后再在pom.xml文件中重新导入Spring坐标。
··· 步骤2:若成功导入spring坐标,则 springframework 目录文件中可以看到以下文件。若导入失败,则多次重复步骤1操作。
最近在使用软件的时候,发现在不同的系统中,界面有时候显示中文,有时候显示英文。
后来发现是在软件启动的时候,读取系统的语言,于是需要参照下面的方式修改系统的语言
1、查看当前语言 locale 下面 LANG=en_US.UTF-8 是当前语言
2、查看是否存在中文语言包 locale -a | grep zh_CN zh_CN.utf8 是简体中文,如果没有zh_CN.utf8,就安装语言包,如果存在可以直接设置。
3、安装中文语言包 若是在第二步中,没有 zh_CN.utf8 ,那么需要安装中文语言包,使用下面的命令:
yum install kde-l10n-Chinese 4、修改系统默认语言 4.1 临时修改,重启服务器之后会失效 直接执行下面的指令
LANG="zh_CN.UTF-8" 4.2 永久修改,重启服务器之后不会失效(方法一) 编辑 /etc/locale.conf 文件,增加下面的内容
LANG=zh_CN.UTF8 然后重启,即可
4.2 永久修改,重启服务器之后不会失效(方法二) 直接执行下面的指令
localectl set-locale LANG=zh_CN.UTF8 然后重启,即可
该层次attention模型总共分为3层
word sequence encoder + word-level attention layer
line encoder + line-level attention layer
hunk sequence encoder + hunk attention layer
模型结构如下:
Word encoder.给定一行 𝑠𝑖𝑗,其中包含单词序列 𝑤𝑖𝑗𝑘,我们使用双向 GRU 来从两个方向的单词上下文中总结信息。为了捕获此上下文信息,双向 GRU 包括一个前向 GRU,它从𝑤𝑖𝑗1 到𝑤𝑖𝑗𝑊 读取行𝑠𝑖𝑗,以及一个从𝑤𝑖𝑗从𝑤𝑖𝑗读取行的反向 GRU。ℎ𝑖𝑗𝑘总结了单词𝑤𝑖𝑗𝑘并考虑了它的邻接单词。
Word attention.基于邻接词对于预测结果并不全都是同等重要的,我们使用注意机制来突出对预测很重要的单词日志消息的内容和行嵌入向量。首先,通过一个全连接层以获得隐藏的表示。
其中 ReLU 是校正后的线性单元激活函数。定义一个词向量,能够固定回答“什么是最有用的词”。词向量是随机初始化的,且在训练过程中进行学习。然后,我们将𝑢𝑖𝑗𝑘与单词上下文向量𝑢𝑤的相似度作为单词的重要性衡量,并通过softmax函数获得归一化的重要性权重𝛼𝑖𝑗𝑘:
最后,对于每一行𝑠𝑖𝑗,其向量根据词的重要性计算为词嵌入向量的加权和,输入到Line encoder层,如下所示:
Line encoder.和word encoder相似,同样使用了双向GRU从两个方向的单词上下文中总结信息并考虑了它的邻接单词。
Line attention.我们使用注意力机制来学习用于形成一个大块向量的重要线,如下所示:W𝑠 是我们需要向其提供给定线注释的完全连接层(即𝑠𝑖𝑗). 我们定义𝑢𝑠 作为行上下文向量,可以被视为固定查询“什么是信息行”答案的高级表示。𝑢𝑠 在训练过程中随机初始化并学习。𝑡𝑖 是𝑖-删除(添加)代码中的i-th hunk的大块向量。
Hunk encoder.给定一个大块向量ti,继续使用双向GRU形成移除(添加)代码的嵌入向量,如下所示:
Hunk attention.我们再次使用注意力机制学习用于形成移除(添加)代码嵌入向量的重要大块,如下所示:
Wh是用于为给定hunk提供注释的完全连接层(即ℎ𝑖). 𝑢𝑡 是一个大块头上下文向量,它可以被视为对固定查询“什么是有信息的大块头”的答案的高级表示。类似𝑢𝑤 和𝑢𝑠 , 𝑢𝑡 在训练过程中随机初始化和学习。e, 本部分末尾收集的是删除(添加)代码的嵌入向量。为了方便起见,我们表示e𝑟 和e𝑎 分别作为删除代码和添加代码的嵌入向量
一、域名备案 【手把手教程】个人域名如何备案 阿里云ICP 网站备案
二、域名解析 阿里云如何解析域名
三、解析域名到服务器指定端口号 首先新建一个 ‘test’ 子域名,记录类型为 “A”,将子域名解析到 ‘118.187.xxx.xxx’ (你的服务器IP地址,也就是服务器的默认80端口) 2、再新建一个主机记录为 “www” 的域名 ,记录类型为 “隐式URL”,记录值为刚刚建的 “子域名:端口号”
3、再新建一个主机记录为 “@” 的域名 ,其它设置和上一步相同
4、完成。通过 “www.shikun.com” 或 “shikun.com” 即可访问服务器的 8000 端口
SQL 优化的过程可以分为逻辑优化和物理优化两个部分。逻辑优化主要是基于规则的优化,简称 RBO(Rule-Based Optimization)。物理优化会为逻辑查询计划中的算子选择某个具体的实现,需要用到一些统计信息,决定哪一种方式代价最低,所以是基于代价的优化 CBO(Cost-Based Optimization)。
本文将主要介绍Kingbase数据库的逻辑优化规则。
准备数据: create table big(id int , bname varchar(20)); create table middle(id int , bname varchar(20)); create table small(id int , sname varchar(20)); insert into big select generate_series(1 , 1000), dbms_random.string('l',5) ; insert into middle select generate_series(501 , 1000), dbms_random.string('l',5) ; insert into small select generate_series(951 , 1050), dbms_random.string('l',5) ; 逻辑优化分类 [逻辑优化分类] |选择下推 |谓词下推 |逻辑分解优化 ⇒ |连接顺序交换 | |等价类推理 逻辑优化 ⇒ | |子查询提升 |逻辑重写优化 ⇒ |子连接提升 |表达式预处理 |外连接消除 逻辑分解优化 选择下推 连接条件直接下推到自己所涉及的基表上。
文章目录 一、Docker网络实现原理二、Docker的网络模式1、host模式1.1 host模式原理1.2 host模式实操 2、Container模式2.1 模式原理2.2 container模式实操 3、none模式4、bridger模式4.1 bridge模式的原理4.2 bridge实操 5、overlay模式6、自定义网络模式6.1 为什么需要自定义网络模式?6.2 创建自定义网络6.3 删除docker网络6.4 创建指定容器的ip 一、Docker网络实现原理 暴露端口
docker使用Linux桥接,在宿主机虚拟一个Docker容器网桥(docker0),docker启动一个容器时会根据Docker网桥的网段分配一个IP地址,称为Container-IP。
同时Docker网桥是每个容器的默认网关,因为在同一宿主机内的容器都接入同一个网桥,这样容器之间就能通过容器的Container-IP直接通信。
Docker网桥是宿主机虚拟出来的,并不是真实存在的网络设备,外部网络是无法寻址到的,这也意味着外部网络无法直接通过Container-IP访问到容器。
如果容器希望外部访问能够访问到,可以通过映射容器端口到宿主主机(端口映射),即docker run创建容器时候通过 -p 或 -P 参数来启动,访问容器的时候就通过【宿主机IP】:【容器端口】访问容器。
docker run -d --name test1 -P nginx #(大写P)启动容器时,将容器端口递增映射到主机上(端口范围为49153开始,后面自增) (宿主机的端口:容器端口) docker run -d --name test2 -p 55555:80 nginx #(小写p)启动容器时,将容器端口映射为主机端口的55555端口 //后面都没有加/bin/bash,为啥? //加了/bin/bash后,会影响到commad(命令),镜像里面的命令默认是启动nginx,加了/bin/bash后,相当于有多条命令,但是它只会执行一台命令,所有就不执行启动nginx的命令。 //如果加了/bin/bash,那怎么启动容器中的nginx呢? #可以直接进入容器执行nginx启动,或则 docker exec -it 【容器名】 /bin/bash -c "nginx" 还可以查看iptables的映射关系
iptables -nL -nat 然后可在浏览器访问宿主机ip加映射的端口
查看容器日志信息
docker logs 【容器ID】 或者 cd /var/lib/docker/containers/ 目录下找到指定的容器ID目录,然后进入找到一个json.log的文件,这里面也会存在日志,平常删除,直接删除这里面即可。 二、Docker的网络模式 Host : 容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口。