NMS

对NMS的理解内容,如有不对请指出。 在引进NMS概念之前我们先介绍IOU(交并比),因为在NMS中选出框图起到至关重要的作用 1、IOU(交并比) 对于bounding box的定位精度,有一个很重要的概念,那就是定位精度评价公式:IOU。 IOU表示了bounding box 与 ground truth 的重叠度,如下图所示: 矩形框A、B的一个重合度IOU计算公式为: IOU=Area(A∩B)/Area(A∪B) 就是矩形框A、B的重叠面积占A、B并集的面积比例: IOU=SI/(SA+SB-SI) 如何计算IOU(交并比) 首先求出重合面积: 选取两个矩形框左顶角的横,纵坐标的最大值,x21,y21;选取两个矩形框右下边角的横纵坐标的最小值,x12,y12; 重合面积计算: inter= 并集的面积计算: b = 计算IOU: 具体实例如下: 有了IOU(交并比)的概念理解,接下来我们就进入正题,介绍NMS 2、NMS概念 NMS也即非极大值抑制。在最近几年常见的物体检测算法(包括rcnn、sppnet、fast-rcnn、faster-rcnn等)中,最终都会从一张图片中找出很多个可能是物体的矩形框,然后为每个矩形框为做类别分类概率: 所谓非极大值抑制:依靠分类器得到多个候选框,以及关于候选框中属于类别的概率值,根据分类器得到的类别分类概率做排序,具体算法流程如下: (1)将所有框的得分排序,选中最高分及其对应的框 (2)遍历其余的框,如果和当前最高分框的重叠面积(IOU)大于一定阈值,我们就将框删除。(为什么要删除,是因为超过设定阈值,认为两个框的里面的物体属于同一个类别,比如都属于狗这个类别。我们只需要留下一个类别的可能性框图即可。) (3)从未处理的框中继续选一个得分最高的,重复上述过程。 举例说明:(1)(2),这里设定交并比>=0.6就删除对比框图,留下最高分的框图;对于低于阈值的框图留下,然后在剩下的框图中排序,选出置信度值高的框图,然后重复交并比比较这个过程。 (1)选出Dog这个框图 (1)选出Bike这个框图 ———————————————— 版权声明:本文为CSDN博主「zouxiaolv」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/zouxiaolv/article/details/107400193

Trojan的兴起

Trojan的兴起 Trojan的兴起 Trojan的兴起要从11月的防火墙阻断说起,那段时间SS,SSR以及v2Ray的VMess加密协议全部中招,只有Trojan和V2Ray的WebSocket+TLS模式没有问题。 为什么SS,SSR,V2Ray都中招了呐?当下的上网只有两种方式:一种就是加密流量,一种就是伪装流量,加密协议就像SS,SSR以及V2Ray的VMess加密协议,他把你的网络流量加密封装成没有任何特征的数据包;但从墙的角度看,你的数据流量就是未知数据流量,其实这就是最明显的特征,虽然墙不知道里面的内容,但是他可以判断数据量的大小,从而阻断你。另一种就是伪装流量,简单来说将流量伪装成正常的HTTPS流量,这种是一种非常普遍的流量,对于墙来说,互联网上HTTPS的数据是海量的,想要从这种正常的海量的数据中区分出哪个是tz,这还是有很大难度,更不会冒然阻断你。 Trojan和V2Ray的WebSocket+TLS模式非常相似,他们都模仿了互联网上最常见的HTTPS协议来诱骗墙认为他就是HTTPS,从而不被识别。 测试结果表明,无论是在电脑端还是在手机端,Trojan的速度都是略高于V2Ray的。原因有两点:1.Trojan其实是TCP+TLS模式,他的加密只有一层就是TLS,V2Ray不但有TLS加密,还有本身的VMess加密.2V2Ray的WebSocket也会比他的TCP性能差一些,不过WebSocket也有一定的好处就是可以套用CDN,它可以隐藏你的VPS。 Trojan只是V2Ray的WSS模式的精简版。它除去了V2Ray的一些协议和加密所以速度稍微快一些。

latex调整caption图表标题行间距、字体大小、左对齐

论文模板中设置的caption字体为五号加粗,由于标题太长,多行显示时行间距一直不对,latex小白,探索了两天终于给解决了。 问题解决 刚开始尝试修改模板,虽然也可以实现,但修改后的格式会破坏一些图表上下文之间的间距。考虑到长标题的图表并不多,因此尝试对单个图表进行修改 方法1 :设置\captionsetup \begin{figure} \centering \subcaptionbox{}{\includegraphics[scale=0.33]{ExtendedYaleB10_data_tSNE.png}} \subcaptionbox{}{\includegraphics[scale=0.33]{ExtendedYaleB10_proposed1_tSNE.png}} \subcaptionbox{}{\includegraphics[scale=0.33]{ExtendedYaleB10_proposed2_tSNE.png}} \captionsetup{font={small,bf,stretch=1.25},justification=raggedright} \caption{Extended Yale B数据集前$10$类实验的t-SNE可视化(a)原始样本; (b)SC-LRDG1学习到的亲和矩阵;(c)SC-LRDG2学习到的亲和矩阵} \label{fig_ExtYaleB10_Visualization} \end{figure} 通过\captionsetup{font={small,bf,stretch=1.25}, justification=raggedright} 来进行重新修改caption格式。 字体设为small(对应五号字体,还有其他选择\tiny\scriptsize\footnotesize\small\normalsize\large\Large\LARGE\huge\Huge)bf表示加粗显示stretch=1.25表示1.25倍行距justification=raggedright设置左对齐,默认情况应该就是左对齐,不齐可能是设置了首部缩进。 由于字体选项中都是固定的,如果需要其他字号,需要手动设置 方法2:\fontsize设置字号 \begin{figure} \centering \subcaptionbox{}{\includegraphics[scale=0.33]{ExtendedYaleB10_data_tSNE.png}} \subcaptionbox{}{\includegraphics[scale=0.33]{ExtendedYaleB10_proposed1_tSNE.png}} \subcaptionbox{}{\includegraphics[scale=0.33]{ExtendedYaleB10_proposed2_tSNE.png}} \captionsetup{font={bf},justification=raggedright} \caption{\fontsize{10.5bp}{17bp}Extended Yale B数据集前$10$类实验的t-SNE可视化(a)原始样本; (b)SC-LRDG1学习到的亲和矩阵;(c)SC-LRDG2学习到的亲和矩阵} \label{fig_ExtYaleB10_Visualization} \end{figure} 通过对\caption中字体设置,\fontsize{10.5bp}{17bp} 小五号字体就是10.5磅,单位磅基本与bp一样,17bp对应行间距,10.5*1.3*行距倍数=行间距bp。

c语言生成exe文件,打开exe文件闪退怎么办

首先 我们要明白生成的exe文件本质是控制台程序,这些都是依赖于windows的控制台窗口,程序执行完就退出了。(比如,如果你程序中有scanf语句,那么打开exe的时候不会立马结束,而是等待你的输入,等跑完程序,再自动关闭,就是这个道理) 下面介绍几种常用解决办法 第一种:加个头文件windows.h,然后在代码段末尾加个 system(“pause”); 这里的system就是调用从程序中调用系统命令(和shell命令)。 system(“pause”)就是从程序里调用“pause”命令; 而“pause”这个系统命令的功能很简单,就是在命令行上输出一行类似于“Press any key to exit”的字,等待用户按一个键,然后返回。还是同样的道理,等待用户输入,才能算执行完毕。 第二种: 在exe文件同目录下新建一个txt文档,里面输入如下内容 xx.exe pause 然后退出保存,把后缀txt改为bat然后运行,那个xx就是文件的名字。 然后打开.bat文件运行程序。(.bat文件命名随意) 这里的.bat文件是批处理文件(也被称为批处理程序或脚本)是无格式的文本文件,它包含一条或多条命令。它的文件扩展名为 .bat 或 .cmd。在命令提示下键入批处理文件的名称,操作系统就会按照该文件中各个命令出现的顺序来逐个运行它们。(使用批处理文件,可以简化日常或重复性任务。) 这里执行了xx.exe这个程序,并且调用了pause。 类似法1 第三种: 用getch(); 文首添加#include <conio.h> 在代码段末尾加上getch();就可以了 方法当然并不唯一,希望对你有所帮助

[INS-06006]Passwordless SSH connectivity not set up between the following node(s)

RHEL6上安装Oracle 11.2.0.4 RAC,安装GI创建互信的时候出现INS-06006]错误解决方法。 问题描述: GI安装中,到配置互信步骤,点击setup设置是成功的 但是点击test就出现报错 此处出现报错,是无法进行下一步的。 操作系统里检查互信情况: 1节点: [grid@2021-HIS1 ~]$ hostname 2021-HIS1 [grid@2021-HIS1 ~]$ ssh 2021-HIS2 Last login: Fri Mar 26 15:11:32 2021 from 2021-his1 [grid@2021-HIS2 ~]$ [grid@2021-HIS2 ~]$ hostname 2021-HIS2 2节点: [grid@2021-HIS2 ~]$ hostname 2021-HIS2 [grid@2021-HIS2 ~]$ ssh 2021-HIS1 Last login: Fri Mar 26 14:15:39 2021 from 2021-his2 [grid@2021-HIS1 ~]$ hostname 2021-HIS1 由此可见,互信是配置成功了的。 查询MOS:11.2.0.4 runInstaller: [INS-06006] Passwordless SSH connectivity not set up between the following nodes(s) (Doc ID 1597212.

cloudflare 批量域名ID

<?php /** * Title: 获取CloudFlare上的所有域名的ID (zone_identifier) * Author: Rudon <[email protected]> * Date: 2019-03-08 * * https://dash.cloudflare.com/ * https://api.cloudflare.com/#getting-started-resource-ids * https://api.cloudflare.com/#getting-started-requests > [Section] Requests + Pagination * https://api.cloudflare.com/#zone-list-zones * * */ /* https://dash.cloudflare.com/ Email address associated with your account */ $x_email = '[email protected]'; // Email for current account $x_auth_key = 'kj487ykhjilj3glsuliu'; // Global API Key,获取步骤:My profile > API Tokens > 下面的API Keys > Global API Key > View $how_many_domains_you_have = 1000; // Will be used as "

【GoCN酷Go推荐】protobuf生成Go代码插件gogo/protobuf

从 JSON 开始 谈到序列化,大家最先想到的可能是 JSON 或者 XML,这两种序列化协议都是基于文本的编码方式进行数据传输。类似的还有 YAML 等。 JSON 拥有许多优点,使之成为最广泛使用的序列化协议之一。如 JSON 协议简单,人眼可读,序列化后十分简洁且解析速度快。此外,JSON 具备 JavaScript 的先天性支持,被广泛应用于 Web Browser 的应用场景中,并且是 Ajax 的事实标准协议。 JSON 的适用场景比较多,典型应用场景包括: 公司外部之间传输数据量相对较小,实时性要求相对低的服务 基于 Web browser 的 Ajax 请求 接口经常发生变化,并对可调式性要求较高的场景,例如移动 App 与服务端的通信 然而,由于 JSON 本身的设计的一些特点,在一些场景下使用 JSON 仍然不是最优解。如: 需要标准的 IDL ,增强参与各方业务约束的场景。由于 JSON 协议往往只能使用文档的方式来进行约定,这可能会给调试带来一些不便与不明确 对性能和简洁性有较高要求的场景。JSON 在一些语言中的序列化和反序列化需要采用反射机制,所以在性能要求特别高场景下可能不是最优解 对于大数据量服务或持久化场景。JSON 进行序列化的额外空间开销比较大,这也意味着较大的内存和磁盘开销 对于以上场景, 使用一些基于 IDL ,存储方案为二进制存储的序列化方案则更为合适, 如 ProtoBuf、Thrift、avro等。 IDL: 参与通讯的各方需要对通讯的内容需要做相关的约定。为了建立一个与语言和平台无关的约定,这个约定需要采用与具体开发语言、平台无关的语言来进行描述。这种语言被称为接口描述语言(IDL),采用IDL撰写的协议约定称之为IDL文件。 什么是 Protobuf ProtoBuf 是 Protocol Buffers 的简称 ,是 Google 公司开源的一种语言无关、平台无关、可扩展的序列化结构数据的方案,它可用于(数据)通信协议、数据存储等。 ProtoBuf 是上述场景中比较适用的序列化方案之一。ProtoBuf 非常灵活,高效,我们可以通过定义 IDL (在这里是proto)文件,然后使用生成的源代码轻松的在各种数据流中使用各种语言进行编写和读取结构数据。甚至可以更新数据结构,而不破坏由旧数据结构编译的已部署程序。

NAT介绍

定义 网络地址转换NAT(Network Address Translation)是将IP数据报文头中的IP地址转换 为另一个IP地址的过程。 目的 随着Internet的发展和网络应用的增多,IPv4地址枯竭已成为制约网络发展的瓶颈。尽 管IPv6可以从根本上解决IPv4地址空间不足问题,但目前众多网络设备和网络应用大 多是基于IPv4的,因此在IPv6广泛应用之前,一些过渡技术(如CIDR、私网地址等) 的使用是解决这个问题最主要的技术手段。NAT主要用于实现内部网络(简称内网, 使用私有IP地址)访问外部网络(简称外网,使用公有IP地址)的功能。当内网的主机 要访问外网时,通过NAT技术可以将其私网地址转换为公网地址,可以实现多个私网 用户共用一个公网地址来访问外部网络,这样既可保证网络互通,又节省了公网地 址。 受益 作为减缓IP地址枯竭的一种过渡方案,NAT通过地址重用的方法来满足IP地址的需要, 可以在一定程度上缓解IP地址空间枯竭的压力。NAT除了解决IP地址短缺的问题,还带 来了两个好处: ● 有效避免来自外网的攻击,可以很大程度上提高网络安全性。 ● 控制内网主机访问外网,同时也可以控制外网主机访问内网,解决了内网和外网 不能互通的问题 NAT概述 NAT是将IP数据报文头中的IP地址转换为另一个IP地址的过程,主要用于实现内部网络 (私有IP地址)访问外部网络(公有IP地址)的功能。Basic NAT是实现一对一的IP地 址转换,而NAPT可以实现多个私有IP地址映射到同一个公有IP地址上。 Basic NAT Basic NAT方式属于一对一的地址转换,在这种方式下只转换IP地址,而不处理 TCP/UDP协议的端口号,一个公网IP地址不能同时被多个私网用户使用。 图 3-1 Basic NAT 示意图 图3-1描述了Basic NAT的基本原理,实现过程如下: Router收到内网侧Host发送的访问公网侧Server的报文,其源IP地址为10.1.1.100。Router从地址池中选取一个空闲的公网IP地址,建立与内网侧报文源IP地址间的 NAT转换表项(正反向),并依据查找正向NAT表项的结果将报文转换后向公网侧发送,其源IP地址是1.1.1.1,目的IP地址是2.2.2.2。Router收到公网侧的回应报文后,根据其目的IP地址查找反向NAT表项,并依据 查表结果将报文转换后向私网侧发送,其源IP地址是2.2.2.2,目的IP地址是 10.1.1.100。 由于Basic NAT这种一对一的转换方式并未实现公网地址的复用,不能有效解决IP地址短缺的问 题,因此在实际应用中并不常用。 NAT设备拥有的公有IP地址数目要远少于内部网络的主机数目,这是因为所有内部主机并不会同 时访问外部网络。公有IP地址数目的确定,应根据网络高峰期可能访问外部网络的内部主机数目 的统计值来确定。 NAPT 除了一对一的NAT转换方式外,网络地址端口转换NAPT(Network Address Port Translation)可以实现并发的地址转换。它允许多个内部地址映射到同一个公有地址 上,因此也可以称为“多对一地址转换”或地址复用。 NAPT方式属于多对一的地址转换,它通过使用“IP地址+端口号”的形式进行转换, 使多个私网用户可共用一个公网IP地址访问外网。 图3-2描述了NAPT的基本原理,实现过程如下: Router收到内网侧Host发送的访问公网侧Server的报文。比如收到Host A报文的 源地址是10.1.1.100,端口号1025。Router从地址池中选取一对空闲的“公网IP地址+端口号”,建立与内网侧报文 “源IP地址+源端口号”间的NAPT转换表项(正反向),并依据查找正向NAPT 表项的结果将报文转换后向公网侧发送。比如Host A的报文经Router转换后的报 文源地址为1.1.1.1,端口号16384。Router收到公网侧的回应报文后,根据其“目的IP地址+目的端口号”查找反向 NAPT表项,并依据查表结果将报文转换后向私网侧发送。比如Server回应Host A 的报文经Router转换后,目的地址为10.1.1.100,端口号1025。 NAT实现 Basic NAT和NAPT是私网IP地址通过NAT设备转换成公网IP地址的过程,分别实现一

php扩展配置动态链接库加载~,Linux下如何安装PHP扩展模块?

Linux下安装PHP扩展模块的方法:首先准PHP各配置文件,库文件,日志的存放位置;然后安装动态链接库;接着配置PHP加载,代码为【extension = XXX.so # 或绝对路径】;最后重启服务即可。 Linux下安装PHP扩展模块的方法: 1.找准位置 在安装PHP的扩展模块之前,首先要做的就是要找准PHP各配置文件,库文件,日志的存放位置;幸好PHP为我们提供了一个配置详情一览函数phpinfo()根据这个函数的输出,我们可以知道一切。 以CentOS为例,输出结果如下: 依据上面的信息就可以知道我们第三方库应该放到哪,这里可知是:/usr/lib64/php 注:Scan this dir for additional .ini files,这一项通过编译PHP使用–with-config-file-scan-dir指定。 2.安装动态链接库 从上面的phpinfo输出信息就可以看出PHP存放扩展模块库的路径是/usr/lib64/php,则首先我们进入终端,查看一下/usr/lib64/php目录下到底是什么。 modules及pear,很显然应该是modules目录,列表发现真的是这个目录。 这时只需将第三方动态链接库.so方件复制到此处即可.同时需注意保证文件属性与其他.so文件相同。 3.配置PHP加载 在安装好了.so动态链接库文件后,还需在php.ini中进行加载配置。 这里同window加载.dll文件是一样的道理。 由于上图中的php配置中配置了一项Scan this dir for additional .ini files,则只需在/etc/php.d中新建一个ini文件,依照其它文件在其中添加: extension = XXX.so # 或绝对路径 即可。 4.最后 为了验证我们的ini文件是否生效,则只需重启一下服务器,然后刷新查看phpinfo()输出的Additional .ini files parsed,这一项是否关联正确。 同时查看在php.ini中设置的error_log项中指定的错误日志文件是否有错误。 相关学习推荐:PHP编程从入门到精通

MTK camera启动流程

和你一起终身学习,这里是程序员Android 经典好文推荐,通过阅读本文,您将收获以下知识点: 一、Camera 框架介绍: Camera的框架分为Kernel部分和hal部分,其中kernel部分主要有两块: image sensor driver,负责具体型号的sensor的id检测,上电,以及在preview、capture、初始化、3A等等功能设定时的寄存器配置; isp driver,通过DMA将sensor数据流上传; HAL层部分主要有三部分组成: imageio,主要负责数据buffer上传的pipe; drv,包含imgsensor和isp的hal层控制; feature io,包含各种3A等性能配置; 这篇内容主要介绍开机过程中search sensor以及上电流程等内容。 二、Camera 启动流程 1、CameraService是在开机时启动的,启动后进行searchSensor的操作,会search系统有多少camera,开机时的search操作,只进行camera支持数量的遍历,以及sensor ID的读取操作,如下是hal部分的ASTAH绘制调用流程图,对应的接口的文件路径: HalSensorList: vendor/mediatek/proprietary/hardware/mtkcam/drv/src/sensor/common/v1/HalSensorList.enumList.cpp vendor/mediatek/proprietary/hardware/mtkcam/drv/src/sensor/common/v1/HalSensorList.cpp SeninfDrv: vendor/mediatek/proprietary/hardware/mtkcam/drv/src/sensor/mt6765/seninf_drv.cpp SensorDrv: vendor/mediatek/proprietary/hardware/mtkcam/drv/src/sensor/common/v1/imgsensor_drv.cpp (1) 这里先看enumerateSensor_Locked完成的工作,直接看代码: MUINT HalSensorList::searchSensors() { Mutex::Autolock _l(mEnumSensorMutex); MY_LOGD("searchSensors"); return enumerateSensor_Locked(); } MUINT HalSensorList::enumerateSensor_Locked() { SensorDrv *const pSensorDrv = SensorDrv::get(); SeninfDrv *const pSeninfDrv = SeninfDrv::createInstance(); //初始化seninf,配置ISP相关内容 pSeninfDrv->init(); //将所有的clk全部打开 pSeninfDrv->setAllMclkOnOff(ISP_DRIVING_8MA, TRUE); pSensorDrv->init(); for (MUINT i = IMGSENSOR_SENSOR_IDX_MIN_NUM; i <= max_index_of_camera; i++) { if((ret = pSensorDrv->searchSensor((IMGSENSOR_SENSOR_IDX)i)) == SENSOR_NO_ERROR){ //query sensorinfo querySensorDrvInfo((IMGSENSOR_SENSOR_IDX)i); //fill in metadata buildSensorMetadata((IMGSENSOR_SENSOR_IDX)i); pSensorInfo = pSensorDrv->getSensorInfo((IMGSENSOR_SENSOR_IDX)i); addAndInitSensorEnumInfo_Locked( (IMGSENSOR_SENSOR_IDX)i, mapToSensorType(pSensorInfo->GetType()), pSensorInfo->getDrvMacroName()); } } } (2) 下面主要看下searchSensor的流程,这里有去获取sensorList的内容:

php通过js加载数据,ajax实现加载数据的步骤详解

这次给大家带来ajax实现加载数据的步骤详解,ajax实现加载数据的注意事项有哪些,下面就是实战案例,一起来看一下。 加载数据的具体代码,供大家参考,具体内容如下 1.xssj.php 无标题文档 显示数据 $(document).ready(function(e) { //异步AJAX :执行chuli页面的同时,继续执行下面代码。效率高,不用等待,继续执行下面代码 //异步和同步 同步:效率不高,不能同时执行两件事情 $.ajax({ //async:false,//把异步关闭,相当于开启同步 url:"xschuli.php", dataType:"TEXT", //complete: function(){},//执行完成之后执行 //beforeSend: function(){},//发送处理请求之前,自动处理此方法 complete和beforeSend可以实现进度条 //error: function(){},//如果出错了执行此方法 success: function(data){ //success: function(){}是执行完成之前执行 var hang = data.split("|"); var str = ""; for(var i=0;i { var lie = hang[i].split("^"); str = str+""+lie[1]+""; } $("#sel").html(str); //alert($("#sel").val()); } }); //alert($("#sel").val()); $("#qu").click(function(){ alert($("#sel").val()); }) });

安卓图片裁剪——使用自定义View

目录 前言设计思路源码 前言 在图片操作中裁剪最为常见,安卓中常用的裁剪方式是通过调用 Bitmap.createBitmap(@NonNull Bitmap source, int x, int y, int width, int height) 等实现的,本文所展示的View便是以此为核心设计。 设计思路 在一个图片裁剪的过程中,我们可以看到其主要由以下两部分组成: 裁剪区域(裁剪框)图片区域(裁剪目标) 因此,我们可以将其抽象为两个矩形,裁剪结果即两个矩形取交集,即: 代表裁剪区域的矩形(下称cropRectF)代表图片区域的矩形(下称picRectF) 下面是对这两个矩形的几种设计思路: 对cropRectF: 使用固定尺寸比例设置cropRectF的大小,简单易行,且方便裁剪出固定比例的图片通过拖动边界自由变化cropRectF,这可以通过判断触点坐标是否在其边界或边界附近来判断拖动,从而改变cropRectF的大小 最终鉴于简单选择了前者,同时也加入了通过单指触摸拖动裁剪框,以缓解不能修正裁剪位置的缺陷; 对picRectF则添加了常用手势操作,双指平移图片和缩放图片,由此牵扯出两种方案: 可随意移动缩放图片,裁剪时通过取交集的方式获取结果,适用于裁剪结果可以包含透明区域同样可随意移动缩放图片,但其picRectF应当始终包含cropRectF,则裁剪结果取cropRectF的全集即可,适用于裁剪结果不应包含透明区域 最终采用了第二种方案,同时出于实践的目的也尝试了下在第一种方案中如何获取裁剪结果,部分代码如下: public Bitmap getCroppingResult() { if (picture != null) {// picture为Bitmap对象,即裁剪目标 // 构建裁剪框对应的区域 Region resultRegion = new Region((int) cropRectF.left, (int) cropRectF.top, (int) cropRectF.right, (int) cropRectF.bottom); // 与图片区域相交 resultRegion.op((int) picRectF.left, (int) picRectF.top, (int) picRectF.right, (int) picRectF.bottom, Region.Op.INTERSECT); Rect resultRect = resultRegion.getBounds();// 获取取交集后相交区域的矩形 if (!

华为设备的安全配置console及telnet

---配置console登录认证方式及超时时间--- [R1]user-interface console 0 //进入console配置模式 [R1-ui-console0] authentication-mode password //Console认证方式为password Please configure the login password (maximum length 16): 123 //设置console密码为密文形式123 [R1-ui-console0] idle-timeout 20 0 //设置超时时间为20min,默认为10min 使用quit返回视图模式,save保存后使用display current-configuration检查配置信息,乱码是加密后的密码; 验证console登陆,右键停止设备,然后重启后登陆提示需要输入密码 如果用crt登陆,需要q退出console重新再登陆会提示输入密码 ---远程Telnet 配置--- 1、配置密码登陆验证 [R1]user-interface vty 0 4 进入vty配置模式,0 4表示允许5个并发telnet连接0 1 2 3 4 [R1-ui-vty0-4]authentication-mode password 指定认证方式为password Please configure the login password (maximum length 16):123 配置telnet使用密文认证,密码123 [R1-ui-vty0-4]user privilege level 15 配置用户等级0-15 验证登陆:到R2路由器,telnet到R1 2、配置aaa登陆验证 [R1]user-interface vty 0 4 [R1-ui-vty0-4]authentication-mode aaa //修改指定认证方式为aaa [R1-ui-vty0-4]aaa //进入aaa视图

python中readline是什么意思,简单介绍Python中的readline()方法的使用

readline()方法从文件中读取一整行。尾部的换行符保持在字符串中。如果大小参数且非负,那么一个最大字节数,包括结尾的换行和不完整的行可能会返回。 遇到EOF时立即返回一个空字符串。 语法 以下是readline()方法的语法: fileObject.readline( size ); 参数 size -- 这是可以从文件中读取的字节数。 返回值 此方法返回从文件中读取的行。 例子 下面的例子显示了readline()方法的使用。 #!/usr/bin/python # Open a file fo = open("foo.txt", "rw+") print "Name of the file: ", fo.name # Assuming file has following 5 lines # This is 1st line # This is 2nd line # This is 3rd line # This is 4th line # This is 5th line line = fo.readline() print "Read Line: %s"

BERT、RoBerta、XLNet、ALBERT对比

BERT BERT堆叠了多层Transformer的Encoder模块,设计了两个任务来完成预训练: Masked LM:随机mask掉15%的token,其中80%替换为[MASK],10%替换为其它token,10%保留原单词。Next Sentence Prediction(NSP):从训练集中抽取A和B句,50%为A的下一句,50%为其它句子。 RoBerta 静态Mask VS 动态Mask 静态Mask:BERT对每一个序列随机选择15%的tokens替换成[MASK],而一旦被选中,之后的N个epoch就不能再改变。动态Mask:RoBERTa一开始把预训练的数据复制10份,每一份都随机选择15%的Tokens进行Mask,也就是说,同样的一句话有10种不同的mask方式。然后每份数据都训练N/10个epoch。 NSP VS w/o NSP RoBerta去除了NSP任务,每次输入连续的多个句子,直到最大长度512(可以跨文章)。这种训练方式叫做(FULL - SENTENCES),而原来的Bert每次只输入两个句子。 hyper-parameter 更大的batch_size更多的数据更高的学习率更长时间的训练 XLNet AR LM:利用上下文单词预测下一个单词的一种模型。但是在这里,上下文单词被限制在两个方向,要么向前,要么向后。 AE LM:从损坏的输入中重建原始数据的一种模型。它可以同时在向前向后两个方向看到上下文。 BERT存在的问题: 掩码导致的微调差异:预训练阶段因为采取引入[Mask]标记来Mask掉部分单词的训练模式,而Fine-tuning阶段是看不到这种被强行加入的Mask标记的,所以两个阶段存在使用模式不一致的情形,这可能会带来一定的性能损失。预测的标记彼此独立:Bert在第一个预训练阶段,假设句子中多个单词被Mask掉,这些被Mask掉的单词之间没有任何关系,是条件独立的,而有时候这些单词之间是有关系的,XLNet则考虑了这种关系。 XLNet在输入侧维持表面的X句子单词顺序,在Transformer内部,看到的已经是被重新排列组合后的顺序,是通过Attention Mask来实现的。从X的输入单词里面,也就是Ti的上文和下文单词中,随机选择i-1个,放到Ti的上文位置中,把其它单词的输入通过Attention Mask隐藏掉,于是就能够达成我们期望的目标。 双流自注意力机制 content stream self-attention h θ ( x z ≤ t ) h_{\theta}\left(\mathbf{x}_{\mathbf{z}_{\leq t}}\right) hθ​(xz≤t​​):标准的Transformer计算,能同时接触到单词x的特征信息和位置信息。query stream self-attention g θ ( x z < t , z t ) g_{\theta}\left(\mathbf{x}_{\mathbf{z}_{<t}}, z_{t}\right) gθ​(xz<t​​,zt​):只能接触到单词x的位置信息。 计算过程如下: g z t ( m ) ← Attention ( Q = g z t ( m − 1 ) , K V = h z < t ( m − 1 ) ; θ ) , ( query stream: use z t but cannot see x z t ) h z t ( m ) ← Attention ( Q = h z t ( m − 1 ) , K V = h z < t ( m − 1 ) ; θ ) , ( content stream: use both z t and x z t ) \begin{aligned} &g_{z_{t}}^{(m)} \leftarrow \text { Attention }\left(\mathrm{Q}=g_{z_{t}}^{(m-1)}, \mathrm{KV}=\mathbf{h}_{\mathrm{z}<t}^{(m-1)} ; \theta\right), \quad\left(\text { query stream: use } z_{t} \text { but cannot see } x_{z_{t}}\right)\\ &h_{z_{t}}^{(m)} \leftarrow \text { Attention }\left(\mathrm{Q}=h_{z_{t}}^{(m-1)}, \mathrm{KV}=\mathbf{h}_{\mathrm{z}<t}^{(m-1)} ; \theta\right), \quad\left(\text { content stream: use both } z_{t} \text { and } x_{z_{t}}\right) \end{aligned} ​gzt​(m)​← Attention (Q=gzt​(m−1)​,KV=hz<t(m−1)​;θ),( query stream: use zt​ but cannot see xzt​​)hzt​(m)​← Attention (Q=hzt​(m−1)​,KV=hz<t(m−1)​;θ),( content stream: use both zt​ and xzt​​)​

常见密码归纳(入门级)

** 常见密码归纳(入门级) ** 前言:前几天的比赛发现密码忘得有点多,今天总结一下吧。方便自己以后看看。 常见密码: 1:base密码(base16 ,32,64,58 ,85 ,100);: 2:ROT密码:ROT 5/13/18/47; 3:凯撒密码+变异凯撒; 4:栅栏密码,栅栏密码W型; 5:猪圈密码; 6:维吉尼亚; 7: 特殊密码:摩斯密码,培根密码,与佛论禅,百家姓,Uuencode编码转换 一:base家族: base算是最常见的密码之一,经常用到的base64/32/16,少见的有58,85,100,92,93。说一下各个的特点吧。 base64: 实例:YWRtaW4tcm9vdA== 特点:一般情况下密文尾部都会有两个等号,明文很少的时候则没有; 加密原理: Base64编码要求把3个8位字节(38=24)转化为4个6位的字节(46=24),之后在6位的前面补两个0,形成8位一个字节的形式。 如果剩下的字符不足3个字节,则用0填充,输出字符使用‘=’,因此编码后输出的文本末尾可能会出现1或2个‘=’。 base32: 示例:GEZDGNBVGY3TQOJQGE====== 特点:超过十位会有很多等号,一般大于三个; base16: 示例:61646D696E 特点:它的特点是没有等号并且数字要多于字母 下面的没有以上三种常见 base58 示例:**6tmHCZvhgfNjQu** 特点:它最大的特点是没有等号 Base58是用于比特币(Bitcoin)中使用的一种独特的编码方式,主要用于产生Bitcoin的钱包地址。 相比Base64,Base58不使用数字"0",字母大写"O",字母大写"I",和字母小写"l",以及"+“和”/"符号。 比特币的Base58字母表: 123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz base85: 示例:@:X4hDWe0rkE(G[OdP4CT]N# 特点:奇怪的字符比较多,但是很难出现等号。 base100: 示例:👘👛👤👠👥 特点:一堆Emoji表情 base小结::看到密文后,先看有没有等号 有等号,考虑64和32,等号特别多≥3个是32,否则64。 没等号,如果由数字和纯字母(大写)组成且数字多,大概率16;字母大小写都有,考虑58; 有@#等符号,直接base85;有enjoy表情,base100. 至于base91,92,这两个有点不常见,base91至少可以百度到,base92只能用下载的工具包或者自己跑脚本了。 base64/32/16解码网站:https://www.qqxiuzi.cn/bianma/base64.htm base58/85/91/100解码网站: http://www.atoolbox.net/Category.php?Id=27 注:虽然也包括64解密,但是没有最上边的好用,有时候解不出来。 遇到base92自求多福吧,我也只有一个工具包能解92而已 ROT密码: rot密码其实可以看作是凯撒密码的一种变式本质都是移位运算 rot密码按种类大致分为以下几类: rot5: 原理: 只将字符串中的数字进行加密,步数为5,同时在0-9十个数字进行循环,如1在rot5加密后为6,而6在rot5加密后为1。 特点:只对数字进行编码,用当前数字往前数的第5个数字替换当前数字,例如当前为0,编码后变成5,当前为1,编码后变成6,以此类推顺序循环。 rot13 只将字符串中的字母进行加密,步数为13,加密方式上最接近凯撒密码,分别在A-Z或a-z之间循环,如A在rot13加密后为N,Z在rot13加密后为M 特点: 只对字母进行编码,用当前字母往前数的第13个字母替换当前字母,例如当前为A,编码后变成N,当前为B,编码后变成O,以此类推顺序循环 rot18:字面意思(5+13=18) 即将上述两种加密方式结合,分别对数字和字母进行相应的操作 特点:由字母数字组成

Koa的学习

Koa的了解 Koa是express原班人⻢打造的轻量、健壮、富有表现力的nodejs框架。 使用Koa koa安装 * $ npm i koa一个简单的koa服务器 const Koa = require("koa"); //koa正常使用 let app = new Koa(); //使用 会有一个回调函数 ctx: context对象 app.use(async (ctx) => { //ctx.request === req; ctx.response === res; // ctx.response.body = "hello world"; ctx.body = "hello " console.log(ctx.url); }) Koa 利用中间件控制"上游",调用"下游“;koa是包含一组中间件函数的对象;可以将app.use里的函数理解成中间件通过next()将控制转交给另一个中间件; let m1 = async function(ctx, next) { console.log("m1"); //ctx.state 传递数据 //它就像一个中间间的贡献空间 ctx.state = { perPage: 5, totalPage: "13" } //将控制权,交给下一个中间件 next(); // ----->m2 // console.

Kettle中“字符串操作”功能算子的使用

ELT过程一般都是避免不了对字符串的操作,kettle中的“字符串操作”可以很便捷的帮我们处理一些关于字符串的问题,下面先对“字符串操作”的几个功能做一个介绍。 Trim type:用来去除字符串的首尾空白字符(如space,tab),这里可以选择去除字符串头部空白字符(left),字符串尾部空白字符(right),头尾都去除空白字符(both)。 Lower/Upper:就是简单的大小写转换,当然只是针对于英文字符的,汉字和数字是无效的。 Padding:追加字符串,可以选择头部追加(left),或者尾部追加(right),不过这个是要配合“Pad char”和“Pad length”使用的。 Pad char:只需要再输入框输入想要添加的字符串即可。 Pad length:输入长度,这个可以这么理解,假如说未追加内容的字符串是abc长度为3,想要追加的字符串是wq,是以right的方式追加的,如果输入的长度是3,那么结果是没有任何改变的;如果输入的长度是4,那么结果就是abcw;输入的是5,那结果就是abcwq;输入的长度是6,那结果就是abcwqw,相信说到这里应该就很清楚了,不管“Padding”选择的是right还是left,规则都是一样的。 InitCap:这个的作用就是保证字符串的首字母大写其余的字母都是小写,比如有一个字符串是aBC,如果InitCap的参数选择了“是”,那么结果就是“Abc”。 Escape:这个一般应用的较少,比如说选择了其中的“Use CDATA”,那么最后出来的字符串就是CDATA格式的字符串“<![CDATA[test_str]]>”,标红的部分就是原本的字符串,其它的就不一一介绍了,感兴趣的实验一下就明白了。 Digits:digits本身就是数字的意思,而选择的参数只有三两个“none、”“only”和“remove”,none就是不操作;only就是只保留数字,其他的字符不要;remove就是其他的字符都留下,只将数字字符去除掉。 Remove Special character:这个就很简单了,就是去除特殊字符,可以根据需求选择需要删除的字符,如空格(space)、换行符(line feed)等,这里就不一一介绍了,如有疑惑可以百度翻译。 每个部分的功能基本讲解清楚了,了解这个使用起来基本就没问题了,下面简单的介绍下如何使用。 1.核心对象->转换->字符串操作,将其拖拽到转换页面中,如下图所示 2.双击“字符串操作”,选择或者输入相关参数,前面已经讲解每个部分的作用和使用方法,这里就简单配置其中部分,如下图所示 3.库表中原始数据如图1所示,虚线标记的为空白字符(space),结果数据如图2所示 图1 图2 通过结果数据可以看出,就是按照配置的参数的规则对字符串进行操作,头部的空白字符已经去除掉了,并且追加的字符‘Q’也是按照输入的长度追加的MAN长度为3,输入长度为5,结果数据追加了两个字符‘Q’,WOMEN长度为5,结果数据没有变化,所以结果是正确的。

软考 - 高级信息系统项目管理师,考证好处、报考流程及知识体系

软考 及计算机技术与软件专业技术资格考试,简称软考。是由人力资源和社会保障部和工业和信息化部l联合组织实施的国家级考试。考试时间为每年5月底、11月中旬。在2008年以前,证书要继续教育,目前已改为终身有效。 信息系统项目管理师 高级信息系统项目管理师 是从事信息系统管理的高级管理人员、高级项目经理岗位的敲门砖;是政府承认的高级项目经理。相比于PMP证书,它的考试费用低,零门槛报考,无需继续教育,且在国内普遍认可;是非常合适的考证选择。 一、考证的好处 1. 职称评定 考过 高级信息系统项目管理师 可直接获得 高级职称。 2. 助力提薪 部分企业拿到证书也可以直接涨工资。 大部分高薪岗位招聘中,证书都是加分项或基本条件。 3. 助力一线城市落户 已广州2020年的政策为例,持有软考高级证书的人员,参保一个月,即可以人才引进方式申请落户。 另外大部分一线城市还提供政府补贴,直接发钱。 4. 助力项目招标 大部分政府项目要求,拥有中高级证书可获得加分,增加中标几率。 5. 抵扣个税 拿证当年可直接有3600元的专项扣除。 6. 领取补贴 部分地区拿证还有2000元现金补贴。 7. 入专家库 获高级职称可进入评标专家库。 二、参考流程 1. 考试报名 一般在考试前的3个月左右。 全国计算机技术与软件专业技术资格(水平)考试网上报名平台 2. 考场查询 一般在考试前一周查询考场并打印准考证。 3. 参加考试 带上身份证、准考证付考,非上机考试,需准备黑色中性笔和2B铅笔。 4. 成绩查询 一般在考试一个多月后出考试成绩。 5. 领取证书 一般在考试4-6个月领取证书,可以申请邮寄证书。 三、知识体系 信息系统项目管理涵盖内容 1. 信息系统知识 信息化基础:电子政务、企业信息化、电子商务、信息资源管理、物联网、云计算、大数据、互联网+、智慧城市、移动互联网、人工智能、区块链、5G…信息安全知识信息系统专业基础知识:软件工程、软件构件、软件系统结构、面向对象、典型应用集成技术、软件工具、计算机网络… 2. 项目管理知识 PMP十大知识领域项目立项与招标合同管理配置管理需求管理项目管理高级知识:项目集成、项目组合、战略管理、业务流程管理、知识管理… 3. 相关延伸知识 法律法规与标准规范:合同法、招投标法、著作权法、政府采购法、国标…工程监理知识管理科学基础知识:运筹学、系统模型、数量经济、应用数学…专业英语 知识点分值分布 1. 选择题 上午(09:00-11:30):选择题,满分75,45及格。 全部都是单选题目。 信息系统知识 软件技术 10分网络技术 10分集成技术 5分新技术&时事政治 5分 项目管理知识 项目管理 30分高级项目管理 5分运筹学 5分专业英语 5分 2.

PDP协议简介

文章目录 PDP ContextPacket Data Protocol (PDP)PDP context procedures访问点(Access points) PDP Context 1)PDP(Packet Data Protocol) context 即PDP上下文,保存用户面进行隧道转发的所有信息,包括RNC/GGSN的用户面IP地址、隧道标识和QoS等。 2)SM通过PDP context的激活、修改、去激活信令流程实现会话管理。PDP context 激活流程用于建立用户面的分组传输路由;PDP context修改流程修改激活的PDP context的QoS(Quality of Service)和TFT(Traffic Flow Template),在发生RAU(Routing Area Update)时,也用于修改SGSN到GGSN之间的隧道路由;PDP context去激活则用于拆除激活的PDP。 3)激活一个PDP上下文意味着发起一个分组数据业务呼叫。PDP上下文激活包括MS发起的激活及二次激活、网络发起的PDP上下文激活。 4)当HLR向SGSN插入用户数据且PDP上下文处于激活状态,SGSN可以发起PDP上下文修改流程;RAB重建,发生QoS改变,SGSN可以发起PDP上下文修改流程;SGSN之间的路由区更新,如果PDP上下文处于激活状态,SGSN可以发起PDP上下文修改过程。 5)PDP上下文去激活流程包括MS发起的、SGSN发起的和GGSN发起的PDP上下文去激活流程。 Packet Data Protocol (PDP) 提供在UE和网络之间能够交换IP数据包的分组数据连接,通常分组数据被限制到特定的服务,这些服务能够被访问通过所谓的访问点 对于UMTS分组数据框架, 分组数据协议上下文(PDP Context)是重要的概念之一。PDP Context有一个参数集记录,它包含了建立端到端连接的所有需要的信息: ● PDP类型 ● PDP 地址类型 ● QoS profile 请求 ● QoS profile 协商 ● 认证类型 (PAP 或 CHAP) ● DNS 类型(静态DNS或动态DNS) 对于终端,PDP Context主要被设计主要为了2个目的: ● 第一,PDP Context被设计为了分配一个PDP地址给移动终端,其类型为IPv4或IPv6 ● 第二,用QoS profile建立一个逻辑上的连接,通过UMTS网络利用PDP Context进行一系列的QoS属性协商

python 子线程阻塞主线程,Python多处理/线程阻塞主线程

我正在尝试用Python编写一个程序。我想写的是一个脚本,它会立即向用户返回友好的消息,但会在后台生成一个很长的子进程,该子进程处理多个不同的文件并将它们写入一个原始文件。我已经做了一些关于线程和处理的教程,但是我遇到的是,无论我尝试什么,程序都会一直等待直到子进程完成,然后才会向用户显示前面提到的友好消息。以下是我尝试过的: 线程示例:#!/usr/local/bin/python import cgi, cgitb import time import threading class TestThread(threading.Thread): def __init__(self): super(TestThread, self).__init__() def run(self): time.sleep(5) fileHand = open('../Documents/writable/output.txt', 'w') fileHand.write('Big String Goes Here.') fileHand.close() print 'Starting Program' thread1 = TestThread() #thread1.daemon = True thread1.start() 最后一种说法是在Python中并发运行线程实际上是不可能的。很公平。这些文章中的大多数都提到了多处理模块,所以我已经读过了,而且看起来相当简单。以下是我找到的一些资源: 下面是一个翻译成多处理的例子: ^{pr2}$ 我想要的是让这些程序立即打印“启动程序”(在web浏览器中),然后几秒钟后,一个文本文件出现在我授予写入权限的目录中。然而,实际发生的情况是,它们都有5秒钟没有响应,然后它们打印“启动程序”并同时创建文本文件。我知道我的目标是可能的,因为我已经用PHP实现了,使用了以下技巧://PHP exec("php child_script.php > /dev/null &"); 我想在Python中是可能的。请让我知道,如果我错过了一些明显的东西,或者我想这是完全错误的方式。谢谢你的时间!在 (系统信息:Python2.7.6,MacOSX小牛。Python与自制程序一起安装。我的Python脚本在apache2.2.26中作为CGI可执行文件运行)

Kettle的“增加序列”(自增字段)的使用

"增加序列"就是在流字段中加一个字段,简单的说就是可以把这个字段当成标记行号的一个字段或者字段值自增的字段,会根据具体设定的值来决定起始值和增长值,这里介绍如何使用“增加序列”。 1.核心对象->转换->增加序列,将此模块拖拽到转换中,如下图所示 2.配置参数,设置字段的起始值和增长值,这里设置的起始值为1,增长值为2,如下图所示 3.结果数据如下图所示 使用起来还是比较简单的,通过结果数据可以很好的观测效果,我个人平时对于“增加序列”使用较少,但是这里还是介绍一下,希望对有需要的朋友能提供些帮助。

Kettle生成UUID(随机数)的使用

在使用Kettle进行数据入库的时候,经常会涉及到为ID字段生成唯一标识,而UUID通常是我们生成唯一表示的选择,这个时候就需要使用到“生成随机数”功能算子,通过“生成随机数”可以生成UIID,下面就介绍下如何使用。 1.在核心对象中选择“输入“->”生成随机数”,将”生成随机数“功能算子拖入到转换页面当当中,如下图所示 2.双击“生成随机数“,然后输入字段名,再进行选择随机数类型,数据库中ID一般采用UUID这里也是以UUID作为示例,如下图所示 3.到这里生成随机数就配置完成了,不过这里生成的UUID是36位数的,如过数据库中的ID字段设计位32位的可以通过“转换“中的”字符串替换“功能算子将生成的36位UUID中的’-'替换掉,”字符串替换“这里就将参数配置展示,如下图所示 4.生成的UUID数据通过‘Preview data‘查看如下图所示 关于生成UUID的使用到这里介绍完成了,在“生成随机数”模块中还有很多别的类型的随机数,这个使用方法基本一致,具体就看业务场景的需求了。

java的面向对象基础(3) —— 接口,抽象类、内部类、匿名内部类

师承陈立臣 目录 抽象类(abstract)抽象类的使用方法抽象类的应用:模板方法模式 接口一、接口的概念二、接口的特点三、接口的使用四、接口实现与抽象类继承的区别五、接口的多继承 内部类概念成员内部类(使用较多)及应用:(1)创建成员内部类的实例(2)在成员内部类中访问外部类的成员方法和属性(3)外部类不能直接访问内部类的成员,必须先建立内部类的对象才能访问 成员内部类有以下限制 匿名内部类概念匿名内部类的创建与访问 抽象类(abstract) java中可以定义没有方法体(只有方法头)的方法,该方法由子类来具体实现。该没有方法体的方法我们称之为抽象方法,含有抽象方法的类我们称之为抽象类。 玩玩文字游戏: 有抽象方法的类,一定是抽象类。即抽象方法只能放在抽象类中。 但是抽象类中可以没有抽象方法,可以有具体方法。 注意: (1)抽象方法不能被调用 抽象方法代表一种不确定的操作或行为 (2)抽象类不能实例化 除非完成提示的方法体,但是不靠谱的使用方式(这种不靠谱的方式也是后面提及的匿名的内部类) 不可以被实例化,那怎么使用这个抽象类呢? 抽象类的使用方法 做一个类来继承这个抽象类,继承的时候把方法体实现了,如下: abstract class Test1 { abstract void printInfo(); //在抽象类里面的方法,要么完善方法体,要么作为抽象方法 } //没有方法体的方法,该方法由子类来具体实现 class Test2 extends Test1 //继承抽象类,从而使用抽象类 { @Override public void printInfo() { System.out.println("来自:test2"); } } public class Demo1 { public static void main(String[] args){ Test2 t2 = new Test2(); t2.printInfo(); } } 抽象类的应用:模板方法模式 模板方法模式定义: 父类抽象(abstract)化定义一系列方法作为模板(不具体),把一些步骤推迟到子类去实现,子类将重写这些方法以提供具体行为。 之前做的智能家居可以运行在多个平台上,比如51,32,树莓派,现在就定义在每个平台上完成这个项目的通用模板,然后再在具体平台实现,以51为例子(当然这只是一个类比,java在51单片机上不能运行): abstract class Control { abstract void getCommand(); //是概括了在不同平台上完成智能家居项目的模板 abstract void socketCommand(); //抽象化这些方法,在子类(类比于具体平台) abstract void lightControl(); //中再进行具体化 abstract void cameraControl(); public void work(){ //控制的基本流程 getCommand(); //接收指令 socketCommand(); //来自socket的指令 lightControl(); //灯的控制 cameraControl(); //相机的控制 } } class C51platform extends Control //当这个地方出现红色波浪线的时候 { //光标放上去,可以看到解决方法的快捷键 @Override //把抽象方法重写,全部具体实现 void getCommand() { System.

HTML学习总结

HTML学习总结 一、HTML1、简介2、具体介绍(1)文档(2)HTML文档说明(3)标题(4)文本格式(5)超链接(6)图片(7)文件路径(8)表格(9)列表(10)表单(十一)补充 一、HTML 1、简介 HTML是超文本标记语言,全称英文名为HyperText Markup Language。是一种用于创建网页的标准标记语言,HTML 运行在浏览器上,由浏览器来解析。 2、具体介绍 (1)文档 ①使用VS code,在该文本编辑器下创建文件,文件的后缀名为html。(开始练习文件数量较少,如果涉及项目工程,需养成良好习惯,将文件按照一定方式分文件放置!) ②HTML元素:HTML由许多元素组成,元素一般由一对标签构成,常见的有:<head>,<title>,<body>,<p>,<div>,<img>,<span>,<nav>等等。 一个元素是由三个部分组成:开始标签、内容、结束标签组成。 ③HTML文档(一般情况结构大致如下): <!DOCTYPE html> <html> <head> </head> <body> </body> </html> (2)HTML文档说明 ①注释:<!--注释内容-->。 ②空元素:没有内容的 HTML 元素被称为空元素。空元素是在开始标签中关闭的。 ③HTML 元素以开始标签起始,HTML 元素以结束标签终止。 ④HTML属性:一个空格,在属性和元素名称之间;属性名称,后面跟着一个 = 号;一个属性值,由一对引号 “” 引起来。 (3)标题 ①标题是通过 <h1> - <h6>(从大到小) 标签进行定义的。 例如: <h1>这是一个1标题。</h1> <h2>这是一个2标题。</h2> ②搜索引擎使用标题进行索引页面内容。 ③ h1 用作主标题(最重要的),其后是 h2(次重要的),再其次是 h3… ④HTML水平线:通过<hr>标签建立水平线进行分割。 (4)文本格式 ①HTML使用标签来对输出的文件进行格式输出,但是使用比较少,如果需要进行美化,会使用CSS来进行。 ②常见文本格式标签: <em> 着重文字 <i> 斜体字 <small> 小号字 <strong>加重语气 <sub> 下标字 <sup> 上标字 <ins> 插入字 <del> 删除字 。。。。。。 (5)超链接 ①HTML 使用超级链接与网络上的另一个文档相连,点击即可跳转。

Android MVVM 模式介绍

目录 1.MVVM模式分为Model,View,ViewModel 注意点 2.MVVM模式图 3.Android MVVM架构 4.Databinding框架 Note: 5.双向绑定使用到的注解 1)@InverseBindingAdapter 2)@InverseBindingMethod与@InverseBindingMethods 3)@InverseMethod 4)@Bindable 6.ViewModel 的生命周期 7.MVVM的优势和劣势 7.1优势 7.2劣势 1.MVVM模式分为Model,View,ViewModel (1).Model:数据层,包含数据实体和对数据实体的操作 (2).View:界面层,对应于Activity,XML,View,负责数据显示以及用户交互。 (3).ViewModel:关联层,将Model和View进行绑定,Model或者View更改时,实时刷新对方。 注意点 1.View只做和UI相关的工作,不涉及任何业务逻辑,不涉及操作数据,不处理数据。UI和数据严格的分开 2.ViewModel只做和业务逻辑相关的工作,不涉及任何和UI相关的操作,不持有控件引用,不更新UI。 2.MVVM模式图 3.Android MVVM架构 View 显而易见Activity/Fragment便是MVVM中的View,当收到ViewModel传递过来的数据时,Activity/Fragment负责将数据以你喜欢的方式显示出来。View还包括ViewDataBinding,上面中并没有体现。 ViewModel ViewModel作为Activity/Fragment与其他组件的连接器。负责转换和聚合Model中返回的数据,使这些数据易于展示,并把这些数据改变即时通知给Actvity/Fragment。 ViewModel是具有生命周期意识的,当Activity/Fragment销毁时ViewModel的onClear方法会被回调,你可以在这里做一些清理工作。LiveData是具有生命周期意识的一个可观察的数据持有者,ViewModel中的数据有LiveData持有,并且只有当Activity/Fragment处于活动时才会通知UI数据的改变,避免无用的刷新UI。 Model Repository及其下方就是model了。Repository负责提取和处理数据。数据来源可以是本地数据库,也可以来自网络,这些数据统一有Repository处理,对应隐藏数据来源以及获取方式。 Binder绑定器 Android中的数据绑定技术由DataBinding和LiveData共同实现。当Activity/Fragment接收到来自ViewModel中的新数据时(由LiveData自动通知数据的改变),将这些数据通过DataBinding绑定到ViewDataBinding中,UI将会自动刷新。 4.Databinding框架 Databinding和MVVM的关系 MVVM是一种架构模式,DataBinding是一个实现数据和UI绑定的框架,是实现MVVM模式的工具。 引入DataBinding 引入DataBinding的方式很简单,我们只需要在App的build.gradle添加如下代码即可 android{ ..... dataBinding { enabled = true } } Databinding常用方法 1).BindingAdapter注解设置自定义属性 public class TripleRadioRecyclerView extends RecyclerView { ... @BindingAdapter("scrollListener") public static void addOnScrollListener(TripleRadioRecyclerView recyclerView, IScrollListener listener) { recyclerView.

友元、运算符的重载

一、友元函数和友元类 1、友元函数 在C++中我们我们通常可以将全局函数或者类的成员函数声明为类的友元函数,这样友元函数便可以访问类对象 中的私有成员。我们可以用friend关键字将其声明为友元函数。 1、将全局函数声明为类的友元函数 以friend关键字声明的全局函数称为类的友元函数,友元函数可以通过类对象访问它的私有成员。可以在类内 对全局的友元函数进行声明,在类外对其进行定义。(也可以在类内对全局的友元函数进行定义,此时它仍然为全局 函数)。 2、将一个类的成员函数声明为另一个类的友元函数 它类似于将全局函数声明为类的友元函数,区别在于它是类的成员函数而已。 3、友元函数的主要作用: 实际上在C++中将另一个函数声明为类的友元函数主要作用是服务于运算符的重载,友元的全局函数没有this 指针,因此只能通过类对象来访问类的私有成员。即全局的运算符重载函数的操作对象是类对象。 2、友元类 将一个类B声明为另一个类A的友元类,则友元类B中所有的成员函数都是类A的友元函数。注意此时友元类需要 进行提前声明,友元的关系是单向的,不可传递的。 例:友元函数及友元类的使用范例 二、运算符的重载 运算符的重载实际上是重载运算符函数,重载运算符函数有两种形式:全局的友元函数和类的成员函数。一般 将双目运算符重载为类的友元函数;将单目运算符重载为类的成员函数,此时注意类的成员函数有一个隐藏的形参 this指针。但是,对于赋值复合运算符=,+=, *=等必须重载为类的成员函数。 运算符重载有一定的规则,例如不可以改变运算符的优先级、不可以改变运算符的操作数等等,同时还有一些 运算符是不能重载的,这里就不做太多阐述。 1、运算符重载函数的一般形式 1、运算符重载函数的函数名为 “operator 运算符” 2、运算符的操作数作为运算符重载函数的参数 3、运算符的运算结果对应着运算符重载函数的返回值。 **注意:** 标准输入流istream和标准输出流ostream的前面是不能用const关键字进行修饰的,因为标准输入或输出流 对象在进行IO操作时,实际上是不断的向标准输入流对象或标准输出流对象中写入数据的,他们的状态不断的在变 化,因此不能用const关键字进行修饰。 2、双目运算符的重载 一般将双目运算符重载为全局的友元函数,执行运算符相当于调用相应的运算符函数。 操作数1 运算符 操作数2 《====》 operator运算符(操作数1, 操作数2) 标准输入设备:istream类对象 cin >> obj; 《=====》 operator>>(cin, obj); 标准输出设备:ostream类对象 cout << obj; 《====》 operator<<(cout, obj); 例:定义一个分数类,并从标准输入中完成对象的输入,利用标准输出来输出分数对象。 **3、重载单目运算符 ** 一般将单目运算符重载为类的私有成员函数,此时有一个隐藏的形参this指针。使用运算符实际上是调用运算 符重载函数。 运算符 操作对象 《====》 操作对象.operator运算符(); 例2:以分数类FS为基础,重载前置++运算符 分析:前置“++”运算符的结果为操作对象的值 int a = 3; cout << ++a << a << endl; 结果:4 4 前置“++”运算符重载函数: FS operator++() { this->son = this->son + this->mother; return *this; } 例3:以FS类为基础,重载后置“++”运算符 分析:int a = 3; cout << a++ << a << end; 结果:3 4 后置“++”运算符重载函数: FS operator++(int) //哑元,起到标识作用 { FS temp = *this; this->son = this->son + this->mother; return temp } 例4:赋值运算符的重载 赋值复合运算符是特例,虽然它们是双目运算符,但是依然把他们重载为类的成员函数。 分析: 1、返回值类型为FS是为了达到链式赋值的效果:a = b = c 2、返回值使用引用的原因:避免调用拷贝构造函数,节省空间;达到可以使用“()”实现优先赋值的效果 int f1 = 1, f2 = 2, f3; (f3 = f2) = f1;===>在返回值处使用引用时:f3 = 1, f2 = 2, f1 = 1;(说明:(f3=f2)的结果为f3) ====>在返回值处不用引用时:f3 = 1, f2 = 1, f1 = 1; FS &operator=(const FS &fs) { //防止自赋值 if(&fs == this) return *this; this->son = fs.

关于多个事务并发执行的一个问题

今天群里一个哥们提了一个问题,他面试中遇到的,问题大概是这么个意思: 现在有10个任务,每个任务需要执行10s,用线程池并发处理,每个线程会插入数据,需求:只要有一个线程插入数据失败了,其他的所有线程的数据都需要回滚。 这个是一个并发事务问题,也可以说是一个分布式事务问题,解决方案也不少,这里基于一种两阶段提交的方式进行处理。 即这里主线程作为事务协调者,多个线程作为参与者,直到参与者全部执行了事务操作后会给协调者返回执行结果,在此期间协调者会一直阻塞,同时参与者也会阻塞直到协调者收到所有参与者的执行结果,只要有一个参与者执行失败,协调者就会通知所有参与者都进行回滚操作,反之则提交事务。 代码如下: 建表语句: create table `abc` ( `age` int (11) ); Mapper 接口: /** * @author Dongguabai * @description * @date 2021-03-24 18:49 */ public interface AbcMapper { @Insert("insert into abc values (#{val})") int insert(@Param("val")Object val); } 测试类: @Autowired private AbcMapper abcMapper; @Autowired private PlatformTransactionManager transactionManager; private CountDownLatch countDownLatch = new CountDownLatch(10); private final Object lock = new Object(); private volatile boolean commit = true; @Test public void tes() throws InterruptedException { ExecutorService executorService = Executors.

C# 实现视频监控系统(附源码)

去过工厂或者仓库的都知道,在工厂或仓库里面,会有很多不同的流水线,大部分的工厂或仓库,都会在不同流水线的不同工位旁边安装一台电脑,一方面便于工位上的师傅把产品的重要信息录入系统,便于公司系统数据采集分析。另一方面严谨的工厂或仓库也会在每个工位上安装摄像头,用于采集或监控流水线上工人的操(是)作(否)习(偷)惯(懒)。 好了,闲话少说,咱们直入主题吧! 本系统监控系统,主要核心是使用AForge.NET提供的接口和插件(dll),感兴趣的朋友也可以去他们官网查看文档http://www.aforgenet.com/framework/documentation.html Talk is cheap,show me the code! 系统初始化时,首先检查工位的机台是否开启了摄像头,具体检测代码如下: /// <summary> /// 监控bind /// </summary> private void bind() { try { FilterInfoCollection videoDevices = new FilterInfoCollection(FilterCategory.VideoInputDevice); if (videoDevices.Count <= 0) { MessageBox.Show("请连接摄像头"); return; } else { CloseCaptureDevice(); if (!Directory.Exists(path)) Directory.CreateDirectory(path); videoSource = new VideoCaptureDevice(videoDevices[0].MonikerString); videoSource.VideoResolution = videoSource.VideoCapabilities[0]; sourcePlayer.VideoSource = videoSource; sourcePlayer.Start(); } } catch (Exception ex) { MessageBox.Show(ex.Message); } } 好了,摄像头没问题,咱在检查网络是否正常(这事儿可以交给运维,当然也可以通过程序控制,具体校验网络代码比比皆是,此处忽略,如有兴趣的朋友可以在公众号Call我一起探讨),至于为什么要校验网络,一部分是用于机台系统的数据采集,另一部分就是录制的视频文件不可能存储在工位机台上,不然流水线和工位足够多,岂不是一个工位一个几天的查看视频监控嘛!咱这都是智能化时代,录制的视频可以保存在本地,不过为了方便起见,需要定时清理,定时上传到服务器便于领导审查。视频上传到服务器一般用到最多的莫非两种情况,1.网络足够稳定,足够快的可以直接和服务器开个磁盘映射(共享目录),视频录制完后系统直接剪切到服务器保存即可。2.把不同时段录制的视频先存储到本地,然后单独开发个定时任务FTP定时上传即可。今天先跟大家分享下第一种方法,第二种方法也比较简单,有兴趣的朋友可以公众号call我一起探讨。 不知不觉又扯了一堆废话,都是实在人,直接上源码吧: /// <summary> /// 开启或者关闭程序后将多余文件copy到相应目录,并开启磁盘映射上传到共享目录 /// </summary> private void CopyFilesToServer() { try { //遍历 当前PC文件夹外是否存在视频文件,如存在,移动到目标目录 string newPath = path + MacAddressPath + @"

eNSP入门常用命令(一)以及模拟双PC双路由互通

eNSP入门常用命令(一)以及模拟双PC双路由互通 1. 基本命令 system-view 用户进入系统命令 缩写 sys sysname 修改系统名命令 interface 参数(接口名称)进入接口命令 缩写 int 参数(接口名称) ip address xxx.xxx.xxx.xxx 子网掩码 缩写 ip add xxx.xxx.xxx.xxx 子网掩码(子网掩码可用24代替) undo 不执行命令 quit 返回上一视图命令 return 直接返回用户视图命令 display this 查看当前配置命令(此命令只可以在接口视图下使用) 缩写 dis this 2. 附图 3.模拟双路由互通 拓扑图 配置PC机及路由IP 配置路由IP 之后使用quit命令返回到系统视图在进入g 0/0/1接口下配置IP AR2同理这里就不贴图了 关键配置 AR1 AR2

BMP图片-文件头部信息

BMP 图片也就是位图(bitmap),直接存储像素数据,几乎不进行压缩,图像信息丰富,比较明显的缺点就是占用空间大。 BMP 图片的结构很简单,首先是文件信息、接着是位图信息,然后是调色板信息,最后是位图数据。需要注意的是,文件头部信息的每一部分都是固定大小的,所以在处理文件头部信息时需要按 1 字节对齐的方式访问,或者在声明结构体时用关键字 “__attribute__((packed))” 取消字节对齐。 1. 文件信息 文件信息结构体: typedef struct tag_bitmap_file_header{ unsigned short file_type; unsigned int file_size; unsigned short reserved1; unsigned short reserved2; unsigned int offset_bits; } __attribute__((packed)) bitmap_file_header; 这个结构体的大小固定为 14 个字节。 file_type:文件标识,BMP 文件值固定为 0x4D42,存储为小端模式,转换成 ASCII 就是 “BM”。 file_size:整个文件的大小。 reserved1:保留。 reserved2:保留。 offset_bits:位图数据在文件中的偏移值,等于 “文件信息+位图信息+调色板信息”。 2. 位图信息 位图信息结构体: typedef struct tag_bitmap_info_header { unsigned int bitmap_info_size; int bitmap_width; int bitmap_height; unsigned short planes; unsigned short image_depth; unsigned int compression; unsigned int image_size; int x_pels_permeter; int y_pels_permeter; unsigned int color_used; unsigned int color_important; } __attribute__((packed)) bitmap_info_header; 这个机构体的大小固定为 40 个字节。

解决pythia中 raise InvalidGitRepositoryError(epath) 和 ValueError: Reference at ‘refs/heads/maste等一系列问题

问题描述: 在用pythia 训练模型时,出现: 2021-03-23T15:41:44 ERROR: /media/XXX/D20187A13362E67A/Run_python_module/mmf-0.3.1 Traceback (most recent call last): File "tools/run.py", line 94, in <module> run() File "tools/run.py", line 82, in run trainer.load() File "/media/XXX/D20187A13362E67A/Run_python_module/mmf-0.3.1/pythia/trainers/base_trainer.py", line 48, in load self.load_extras() File "/media/XXX/D20187A13362E67A/Run_python_module/mmf-0.3.1/pythia/trainers/base_trainer.py", line 142, in load_extras self.checkpoint = Checkpoint(self) File "/media/XXX/D20187A13362E67A/Run_python_module/mmf-0.3.1/pythia/utils/checkpoint.py", line 49, in __init__ self.repo = git.Repo(self.repo_path) File "/home/XXX/.conda/envs/pytorch101/lib/python3.7/site-packages/git/repo/base.py", line 181, in __init__ raise InvalidGitRepositoryError(epath) git.exc.InvalidGitRepositoryError: /media/XXX/D20187A13362E67A/Run_python_module/mmf-0.3.1 问题原因:本地git仓库未配置好 问题解决: 1、安装git(若已经安装则跳过) 参考博客: ubuntu下安装及配置git的方法(github) 按照上面链接执行完下图即可,后面就不用继续了。 2、在mmf-0.3.1文件夹下(这里0.3.1只是版本号!找到你对应使用的文件夹即可) 然后: git init # 如果只执行这一步,则会出现 raise ValueError("

(四)docker容器状态和容器生命周期

容器状态 在使用了几天docker之后,大概会用了,虽然坑走过了,再复现也不难,但是终归不想再重复一边。 之前听同事说,这个容器是可以被关闭的,额。。。担心容器里操作的数据没了,所以要了解一些容器的状态 首先要知道容器的状态: docker ps -a 返回的内容中,有一个字段是STATUS STATUS: 容器状态。 状态有7种: created(已创建) restarting(重启中) running(运行中) removing(迁移中) paused(暂停) exited(停止) dead(死亡) 这些状态中,最重要和常见的是除了restarting(重启中)和removing(迁移中)之外的五个状态,下面基本上网络上大部分的容器生命周期图都只包含五个状态:created(已创建),running(运行中),paused(暂停),exited(停止),dead(死亡)。 最常见的一种,当某容器因为某些原因变成exited状态时,可以使用start重新启动,例如:当运行时,提示这个容器未在运行,同时使用docker ps时没有显示出该容器 随后,想要重新新建一个容器,发现提示之前创建的容器其实还在,使用docker ps -a查看所有容器,看到:其实是处于exited状态 随后,使用docker start OCR重新启动了这个容器,检查了一下,里面的东西还是都在的。 类似exited(停止) UP还在运行中(running) 另外,如果想知道这些状态,最简单的方式是,docker --help,返回的信息中,可以看到: # 用来创建容器 create Create a new container # 在一个运行状态的容器中执行命令 exec Run a command in a running container # 杀死运行中的容器 kill Kill one or more running containers # 让容器暂停 pause Pause all processes within one or more containers # 恢复容器 unpause Unpause all processes within one or more containers # 重启容器 restart Restart one or more containers # 新建并初始化一个容器(注意 是一个新的容器) run Run a command in a new container # 启动一个被停止的容器 start Start one or more stopped containers # 暂停运行中的容器 stop Stop one or more running containers 参考:

有一种神奇的性格叫——INTJ

2.3.1 沙箱 要了解 INTJ 的性格,首先要明确一个叫做沙箱的概念。 INTJ,我们从这四个字母就能看出他的性格特点:内向的人本身就不喜欢与人交往,直觉让他们倾向于自己冥想,理性的思维使他们只关注事物的本身逻辑,判断的的特性让他们很少做出理解他人感受的举动。这四个功能都是那种较少和外界接触,相对独立的功能,合在一起自然使 INTJ成了十六种性格里最独立也最封闭的一种性格。 大多数人的功能是为了适应和认识外在的世界,INTJ 就完全走向另一个极端,纯粹的构建一个心中的完美的世界,也就是他们心目中的那个理想国。这就是建造沙箱的初衷,需要一个仿真的环境来模拟世界的运行。 2.3.1.a 这个沙箱分为三个部分, 获取并处理信息,逻辑分析信息,推测事件的发展。三个部分并非是有先后顺序,而是互相作用。预见发展我们前面介绍内向直觉的时候已经提到了,我们来看另两个部分的运作过程,首先是信息处理系统 2.3.1b INTJ 当然也靠感觉来获得外界信息,他们有着自己的一整套的 信息处理模式: 首先呢,他们会观察,在观察的同时进行分析; 第二步,吸收有价值的信息,进行收集; 第三部,对吸纳的信息进行归类; 第四步,就是建立模型,或者说叫建立一个数据库 最后就是根据这个数据库来总结经验,同时指导未来的行动。这套信息处理模式是建立在大量的信息收集和处理的过程上的。有些人反应快是因为他们头脑灵光,而 INTJ反应快则是因为他们能够迅速调取经验。 2.4.1.2c 当然,借助这个逻辑分析能力,INTJ 的学习水平也是数一数二的。有一个统计:在美国,INTJ 的学历水平是第二高的,仅次于 ENTJ。由于他们的高 IQ,几乎所有的 INTJ 的学习成绩都处于中上水平。INTJ 一个很显著的特征就是通常他们的数学都很好,数理思维活跃。而很重要的一个原因是他们能够 创造超越具体问题本身的解决方法,所以他们通常理解一种问题会非常快,能很快的掌握一种理论,或者是学习一种技能。而且还有最重要的一点:他们能爆种。 2.3.2 爆种。 和文艺作品里强化肉体的开挂不同,这种爆种是在意识层面的,表现为一种强大而专注的精神能力,即在短时间内迅速掌握某种能力的能力,就像开基因锁那样。 2.3.2.1 现在我教大家如何爆种。爆种的步骤有: 首先,你要完全封闭情感。到怎样的程度呢?喜怒哀乐全部抛到脑后,甚至会认为你跟你老妈说句话都是没有意义的。你们会感觉这好难,但是对于 INTJ 来讲,反正他们正常的时候也压抑情感。 第二,要无视任务外的一切。山崩地裂天打雷劈事不关己高高挂起。哪怕外面飞来个扎古你都熟视无睹。 第三,不做多余的事情。一旦全身心专注,甚至上根本连考虑别的事情的时间都没有。 你们要做的只是眼前这件事,只考虑怎么做这件事,假如这是一道题,你要考虑的只是他的运算过程和结果。 一定要强调是以全部的精力,高度的专注,其他的事情都是浪费时间:吃饭浪费时间,约会浪费时间,洗澡浪费时间,做爱浪费时间。这都不算,真正爆种的人会认为睡觉浪费时间而且没有意义一旦老子爆种了,就连睡觉都是浪费时间,因为它没有意义。这时候,他们衡量事物的标准就是有没有意义,INTJ 的 T 理性和 J 判断达到最大值:既然睡觉影响我工作了,那就没有意义。但是作为一个人,他的肉体承受能力是有限的。如果长时间维持超频般的状态,他们的身体就会受不了。停止爆种只有两种情况,要么任务完成,要么身体垮掉。通常是后者。在这个时候,INTJ 星人就渴望自己成为一具机器,一具不受肉体束缚,专注思维爆炸的机器。所以我们才会有这种说法:INTJ 的思维模式就像一具没有感情的计算机。 2.3.2.2 人在什么时候能爆种呢? 学生当然是应付考试:有一些 INTJ 型的学霸会周期性爆种,比如一天爆两个小时搞定一切什么的,在平时你会发现他们的学习并不是那么刻苦;还有一些 INTJ 型人根本就不学习,甚至认为上课是没什么必要的,在考试前一周爆种,成绩通常情况下也不算差 第二点 自学:许多 INTJ 在脱离学校式教育系统后靠自学掌握了各种技能。原因多种多样:因为要吃饭,因为好玩,因为我瞧不起的某个人也会所以我也要会——这样的。一般来讲,INTJ 的独立学习能力非常强大。 第三点 从事战略策划工作:这时候你会感受到平时少言寡语无存在感的 INTJ 此时光环全开魅力爆表的效果,INTJ 当领导我们后面会继续讲。 第四点 今天的计划没有完成:这个好理解,INTJ 是计划的奴隶嘛。一本书没有看完,一篇论文没有写完,哪怕今晚不睡觉也要做下去,否则会很空虚,进而对自己的存在产生疑问。

MFC获取窗口句柄号的六种方法

CClientDC dc(this); CString fun1; //直接获得 fun1.Format("%ld", AfxGetMainWnd()->m_hWnd); fun1 = "AfxGetMainWnd()->m_hWnd方法获取句柄号 = " + fun1; dc.TextOut(20, 50, fun1); //通过AfxGetApp()间接获得 fun1.Format("%ld", AfxGetApp()->GetMainWnd()->m_hWnd); fun1 = "AfxGetApp()->GetMainWnd()->m_hWnd方法获取句柄号 = " + fun1; dc.TextOut(20, 70, fun1); //当前窗口 fun1.Format("%ld", GetForegroundWindow()->m_hWnd); fun1 = "GetForegroundWindow()->m_hWnd 方法获取句柄号 = " + fun1; dc.TextOut(20, 90, fun1); //当前活动的窗口句柄 fun1.Format("%ld", GetActiveWindow()->m_hWnd); fun1 = "GetActiveWindow->m_hWnd方法获取句柄号 = " + fun1; dc.TextOut(20, 110, fun1); //窗口名 AfxGetMainWnd()->SetWindowText("我的程序"); CWnd *hwnd = FindWindow(NULL, "我的程序"); if (hwnd) { fun1.Format("%ld", hwnd->m_hWnd); fun1 = "

lotus 开源C2优化版本

lotus 开源C2优化版本 开源C2优化lotus 开源C2优化 显卡3090 git clone https://github.com/jackoelv/bellperson.git cd bellperson/ git checkout origin/3090 vim Cargo.toml version = “0.12.3” 修改为 version = “0.12.5” [package] name = "bellperson" authors = [ "dignifiedquire <me@dignifiedquire.com>", "Sean Bowe <ewillbefull@gmail.com>", ] description = "zk-SNARK library" documentation = "https://docs.rs/bellperson" homepage = "https://github.com/filecoin-project/bellman" license = "MIT/Apache-2.0" repository = "https://github.com/filecoin-project/bellman" version = "0.12.5" readme = "README.md" edition = "2018" lotus 先编译一次 env RUSTFLAGS="-C target-cpu=native -g" FFI_BUILD_FROM_SOURCE=1 make clean all cd extern/filecoin-ffi/rust/ vim Cargo.

matlab 求x y关系,怎么用MATLAB建立数据间的函数关系

可以使用Matlab自带的sftool工具箱,来拟合。举例说明其求解方法: 在命令窗口下,输入 >> x=[565。454 562。058 561。39 563。782 567。 941 571。255 571。938 569。5]; >> y=[528。012 525。544 521。447 518。108 517。407 519。857 523。953 527。356]; >> z=[1。 792 1。818 1。783 1。769 1。772 1。77 1。794 1。794]; >> sftool 选择“Polynomia”l项,x的Degrees为1,y的Degrees为3 在Results窗口就会出现,你要的结果。 Linear model Poly13: f(x,y) = p00 p10*x p01*y p11*x*y p02*y^2 p12*x*y^2 p03*y^3 where x is normalized by mean 566。 7 and std 4。095 and where y is normalized by mean 522。7 and std 4。111

高情商下载SUNRGBD数据集

低情商 直接下载,几Kb的网速,要下一百多天。 高情商 edge浏览器+迅雷浏览器扩展插件,一晚上就下载好了。

node.js学习

初步感受Node.js //引入kttp模块 const http = require("http"); //创建服务器 const serve = http.createServer((req, res) => { // 发送 HTTP 头部 // HTTP 状态值: 200 : OK // 内容类型: text/plain console.log("hello"); //黑窗口中显示 // 发送响应数据 "Hello World" res.end("hello world"); //页面中显示 }) serve.listen(3000) //端口 这是初步的node 启动node 在黑窗口中 cd 找到你这个文件的绝对路径 cmd黑框框清空 输入cls命令 切记 每次在编译器修改完内容,都需要在黑窗口在Ctrl+c关闭,在重新开启 nodemon安装与启动 npm i nodemon -g 指令 (全局安装) 它可以免除那些复杂的操作 做完修改后自动更新 启动的话就会变成==nodemon 1.js== nodemon 1.js 启动服务 下面的这个问题是 nodemon 只能在黑窗口中来启动 下面是解决上面问题 从而实现在编译器内运行启动 在电脑下面搜索 windows PowerShell

计算广告

第一章 在线广告综述 广告的定义:广告是由已确定的出资人通过各种媒介进行的有关产品(商品、服务和观点)的,通常是有偿的、有组织的、综合的、劝服性的非人员的信息传播活动。 主动参与方一般性术语是谁出资人需求方广告主、代理商媒体供给方变现平台 被动参与方受众 传统媒体广告 品牌广告,brand awarenedd直接效果广告,direct response 广告的根本目的是广告主通过媒体达到低成本的用户接触。 ROI:投入产出比,return on investment 一切付费的信息、产品或服务的传播渠道,都是广告。 在线广告的表现形式 横幅广告,banner ad文字链广告,textual ad富媒体广告,rich media ad视频广告,video ad交互式广告,playable ad社交广告,social ad移动广告,mobile ad邮件营销广告,Email Direct Marketing,EDM、激励广告团购游戏联运固定位导航 在线广告技术术语 在广告业务中,数据变闲是附着在流量变现的基础上的。 展示广告、合约广告:在互联网上展示横幅广告的产品形式。 合约广告:展示广告的售卖模式。 定向广告:对不同的受众呈现不同的广告创意。 定向广告系统对计算技术的两个需求: 受众定向:通过技术手段标定某个用户的性别、年龄或其他标签。广告投放:将广告投送由直接嵌入页面变为实时响应前端请求,并动态决策和返回合适的广告创意。 担保式投送:GD,Guaranteed Delivery,以合约的方式进行,媒体与广告主约定广告位、时间段和投放量,并在此基础上确定合同的总金额以及量未达标的情况下的赔偿方案。 RPM:Revenue per Mille,千次展示收益。 CPM:Cost per Mille,按千次展示付费。 CPC:Cost per Click,按点击付费。这种产品的RPM一般达不到合约广告的水平,但它使大量媒体的剩余流量,即没有能力通过合约售卖的流量,有了可行的变现手段。 在线分配问题:一是如何有效地将流量分配到各个合约相互交叉的人群覆盖上;二十要在在线的环境下实时地完成每一次展示决策。 带约束优化:如果将各合约的量看做约束条件,将广告效果看做目标函数,则可以利用带约束优化的数学框架来解决。 竞价广告:在竞价模式下,供给方只向广告主保证质,即单位流量的成本,但不再给出量的保证。对于每一次展示,则按照收益最高这样简单的原则来决策。 搜索广告、付费搜索:互联网广告最主要的金矿。付费搜索也是一种定向广告,即根据用户即时兴趣定向投送的广告,而即时兴趣的标签就是关键词。 上下文广告:如果将用户的搜索词换成正在页面中的关键词,可以将此产品从搜索结果页照搬到媒体页面上。 广义第二高价:与直觉不同的是,在如何向广告主收取每次竞价费用这一点上,并不是按照微观上最优的方案实施就可以达到整个市场最大的收益。如果是计费按照第一高价,那么竞价者经常只会出到自己承受上限。 如果是计费按照第二高价,那么竞价者会可能会出到自己承受上限的价格,因为最终价格是自己出价的下一价格。这样的机制通常来说平台(媒体)收益会更高。通常来说第二高价,指的是在位置拍卖中,向赢得某个位置的广告商收取其下一位广告主的出价。在线广告竞价广告最常见的定价策略,是广义第二高价(Generalized Second Pricing, GSP)策略。 广告网络:广告网络产品,批量地运营媒体的广告位,按照人群或上下文标签售卖给需求方,并用竞价的方式分配流量。 实时竞价:RTB,广告网络的竞价过程是内部进行的,这无法满足广告主定制化的人群选择和优化要求。设想下面两种情形。 (1) 某电商网站准备通过广告召回它的流失客户。 (2) 某银行准备通过已有的信用卡用户找到相似的潜在用户群,并通过广告触达他们。 显然,这些人群仅靠广告平台自己的数据无法得到。这样的需求催生了一种开放的竞价逻辑,让需求方按自己的人群定义来挑选流量,这就是实时竞价(Real Time Bidding),它将竞价过程由广告主预先出价,变成每次展示时实时出价。只要把广告展示的上下文页面URL,以及访客用户标识等信息传给需求方,它就能进行完成定制化的人群选择和出价。 广告交易平台:AD Exchange,ADX,市场上产生了聚合各媒体流量,采用实时竞价方式进行变现的新产品形态。事实上,如果我们把ADN的交易方式想象成场外交易市场,那么ADX与股票交易所有类似的作用。 需求方平台:Demand Side Platform,DSP,通过实时竞价,按照定制化人群标签采买广告,这样的产品就是需求方平台。 程序化交易:基于DSP的广告采买,非常类似于股票市场上的程序交易。这样的广告采买方式也叫做程序化交易。

利用pytorch 实现循环神经网络(RNN)

利用pytorch 实现循环神经网络 循环神经网络代码实现输出结果 循环神经网络 这里有一篇英文文章说的比较好,这里我直接拿来用了,同时也可以帮大家提升一下英文水平,哈哈哈 原文 代码实现 import torch import torch.nn as nn import torchvision import torchvision.transforms as transforms #device configuration device=torch.device('cuda'if torch.cuda.is_available()else 'cpu') #hyper-parameters sequence_length=28 input_size=28 hidden_size=128 num_classes=10 num_layers=2 batch_size=100 num_epochs=5 learning_rate=0.01 #MNIST dataset train_dataset=torchvision.datasets.MNIST(root='../../data/',train=True,transform=transforms.ToTensor(),download=True) test_dataset=torchvision.datasets.MNIST(root='../../data',train=False,transform=transforms.ToTensor()) #data loader train_loader=torch.utils.data.DataLoader(dataset=train_dataset,batch_size=batch_size,shuffle=True) test_loader=torch.utils.data.DataLoader(dataset=test_dataset,batch_size=batch_size,shuffle=False) #recurrent neural network(many to one) class RNN(nn.Module): def __init__(self,input_size,hidden_size,num_layers,num_classes): super(RNN, self).__init__() self.hidden_size=hidden_size self.num_layers=num_layers self.lstm=nn.LSTM(input_size,hidden_size,num_layers,batch_first=True) self.fc=nn.Linear(hidden_size,num_classes) def forward(self,x): #set initial hidden and cell states h0=torch.zeros(self.num_layers,x.size(0),self.hidden_size).to(device) c0=torch.zeros(self.num_layers,x.size(0),self.hidden_size).to(device) #forward propagate LSTM out,_=self.

计算机网络知识点————ACL (访问控制列表)

ACL访问控制列表 一、访问控制列表的工作原理1.访问控制列表在接口应用的方向 二、访问控制列表的处理过程1.ACL工作原理2.ACL两种作用3.ACL种类4.ACL的应用原则 一、访问控制列表的工作原理 ACL(访问控制表)通过包过滤技术,在路由器上读取OSI七层模型的第三层和第三层包头中的信息。根据预先定义好的规则,对包进行过滤,从而达到访问控制的目的。 第三层传输层 —— 数据段——源端口、目的端口 —————————————————————— 通信四元组 第四层网络层 —— 数据包——源IP、目的IP ACl是一组规则的集合,它应用在路由器的某个接口上。对路由器接口而言,访问控制列表有两个方向。 出:已经过路由器的处理,正离开路由器的数据包。 入:已到达路由器接口的数据包。将被路由器处理。 如果对路由器的某接口应用了ACL,那么路由器对数据包应用该组规则进行顺序匹配,使用匹配即停止的,不匹配则使用默认规则的方式来过滤数据包 1.访问控制列表在接口应用的方向 出: 已经过路由器的处理,正离开路由器接口的数据包。 入:已到达路由器接口的数据包,即将被被处理。 数据是有去又回的,进去的时候是进口,回来的时候就是出口,出去的时候是出口,回来的时候就是进口。 列表应用到接口的方向与数据方向有关 二、访问控制列表的处理过程 根据我们预先定义好的规则对包进行过滤 1.ACL工作原理 当数据包从接口经过时,由于接口启用acl,此时路由器会对报文进行检查,然后做出相应的处理 2.ACL两种作用 1.用来对数据包做访问控制 2.结合其他协议,用来匹配范围 3.ACL种类 1.基本acl(2000-2999):只能匹配源IP地址 2.高级acl(3000-3999):可以匹配源IP、目标IP、源端口、目标端口等三层和四层的字段。 3.二层acl(4000-4999):根据数据包的源MAC地址、目的MAC地址、802.1q优先级、二层协议类型等二层信息制定规则(仅作了解) 4.ACL的应用原则 基本acl,尽量用在靠近目的点 高级acl,尽量用在靠近源的地方(用来保护带宽和其他资源) (1)ACL的应用规则 1.一个接口的同一个方向,只能调用一个acl 2.一个acl里面可以有多个rule规则,按照规则ID从小到大排序,从上往下依次执行 3.数据包一旦被某个rule匹配,就不再继续向下匹配 4.用来做数据包访问控制时,默认隐含放过所有(华为设备)

pq下垂控制单相逆变器matlab仿真,学习下垂控制的逆变器并联原理,如何实现仿真P1?-控制器/处理器-与非网...

下垂控制通过模拟同步发电机的自同步和电压下垂特性,可以实现多个逆变器的无通讯并联。只需采样各个逆变器的输出电压和电流,根据下垂控制策略就能实现多逆变器模块的同步,均流运行。 下面是来自《一种微电网多逆变器并联运行控制策略 张庆海》关于下垂控制讲的比较清晰易懂的部分,我们可以先来了解一下基本的原理。 下图是含有 2 个分布式电源的微电网简化原理图: 有功功率和无功功率分别为: 看完论文后通俗的讲,下垂控制就是随着负载增大后根据下垂系数各自改变各自的输出幅度和相角,来实现 P 和 Q 的均分。但是随着采样和线路阻抗的原因,一定会影响均流性能,这都是后续要讨论的话题。在这里只聊聊最基本的下垂控制实现哈。 三相电网的 PQ 可以通过下式计算得出: 所以单相电网也可以参考这个算法,只需要在虚拟出一个正交的 beta 出来,所以可以使用 sogi 的方法得到,也可以直接用微分器重建一个正弦波出来。 S1: PQ 计算是实现下垂控制的第一步,模型可见: 运行输出: 单相 PQ 计算: 使用 2 个 LPF 后输出: S2: 根据下垂控制公式分别计算幅值和相角,相角度的计算类似于锁相环中的实现: S3:为了快速测试下垂控制性能这里使用压控电压源来模拟逆变器的功率级,后续会补上逆变器的部分。总体模型如下,测量 PCC 点的电压用来做计算 PQ。各自计算输出的 Vd-set 和 theta 经过 dq>abc 变换得到 abc 三个调制波。 在阻性负载下测试均流性能,可见在轻负载时频率要高于重负载时,PQ 均流都很不错。 在 RCD 负载时测试,可见 PQ 依然可以很好的均流: 小结:简单的介绍了最基础的下垂控制的实现原理和仿真模型,并对线性和非线性负载做了测试,发现使用下垂控制 PQ 确实能实现非常不错的并联均流效果。这里为了快速了解下垂控制实现,用了可控电压源代替逆变器,后面会用逆变器来进行测试。 致谢:蓝狐大大,小欧大大,在我学习下垂控制上给予了非常大的帮助。 参考文献: 1,一种微电网多逆变器并联运行控制策略 张庆海 彭楚武 陈燕东 金国彬 罗安 湖南大学电气与信息工程学院 感谢各位观看,有关下垂控制的技术问题,可以与我继续交流,谢谢。

Windows常用运行命令

Windows常用运行命令 打开运行窗口 使用Win+R快捷键或右键开始--运行菜单,在打开输入框输入命令回车或确定 微软官方文档:https://docs.microsoft.com/zh-cn/windows-server/administration/windows-commands/windows-commands 常用命令: 画图 mspaint 计算器 calc 记事本 notepad 注册表 regedit 启动项 msconfig 控制面板 control 服务列表 services.msc 资源管理器 explorer 任务管理器 taskmgr 查看系统版本号 winver 运行命令汇总: 1.calc:启动计算器 2.appwiz.cpl:程序和功能 3.certmgr.msc:证书管理实用程序 4.charmap:启动字符映射表 5.chkdsk.exe:Chkdsk磁盘检查(管理员身份运行命令提示符) 6.cleanmgr: 打开磁盘清理工具 7.cliconfg:SQL SERVER 客户端网络实用工具 8.cmstp:连接管理器配置文件安装程序 9.cmd.exe:CMD命令提示符 10.自动关机命令 Shutdown -s -t 600:表示600秒后自动关机 shutdown -a :可取消定时关机 Shutdown -r -t 600:表示600秒后自动重启 rundll32 user32.dll,LockWorkStation:表示锁定计算机 11.colorcpl:颜色管理,配置显示器和打印机等中的色彩 12.CompMgmtLauncher:计算机管理 13.compmgmt.msc:计算机管理 14.credwiz:备份或还原储存的用户名和密码 15.comexp.msc:打开系统组件服务 16.control:控制面版 17.dcomcnfg:打开系统组件服务 18.Dccw:显示颜色校准 19.devmgmt.msc:设备管理器 20.desk.cpl:屏幕分辨率 21.dfrgui:优化驱动器 Windows 7→dfrg.msc:磁盘碎片整理程序 22.dialer:电话拨号程序 23.diskmgmt.msc:磁盘管理 24.dvdplay:DVD播放器 25.dxdiag:检查directx信息

php 钉钉 免登,钉钉免登陆前端操作详解

在钉钉免登陆中,前端操作是很重要的,因为在前端我们需要调用钉钉的jsapi来获取code,而这个code值是至关重要的。所以我 再次清清楚楚的解析一遍前端的操作。下面的是我写的demo,我讲以这个demo为例进行讲解。 先是demo的主页代码: [html] html> dingding-1 var _config = ; //调用jquery需要的库,手机版和电脑版的不同 //手机版钉钉免登引入的jsapi,和电脑版引入的不同 //获取code码值的js文件 钉钉test 未知 然后是调用jsapi前端的js代码文件demo.js(我放在项目的javascripts文件夹下) 代码如下: [html] dd.config({ //实现验证 agentId : _config.agentId, corpId : _config.corpId, timeStamp : _config.timeStamp, nonceStr : _config.nonceStr, signature : _config.signature, jsApiList : [ "runtime.info", "biz.contact.choose", "device.notification.confirm", "device.notification.alert", "device.notification.prompt", "biz.ding.post", "biz.util.openLink" ] }); dd.ready(function() { //验证成功 dd.runtime.permission.requestAuthCode({ //获取code码值 corpId : _config.corpId, onSuccess : function(info) { alert("authcode: " + info.code); $.ajax({ url : "userinfo?code=" + info.code + "

v-bind——Class 与 Style 绑定

前言 本篇记录一下的v-bind指令,从简单使用到复杂应用。 简述 v-bind 主要用于动态地属性绑定,比方你的class属性,style属性,value属性,href属性等等,只要是属性,就可以用v-bind指令进行绑定. 简单使用 <div id="app"> //错误写法 <img src="{{imgURL}}" alt=""> //正确写法 <img v-bind:src="imgURL" alt=""> <a v-bind:href="aHref">v-bind的基本使用</a> <!-- 语法糖,动态绑定简写--> <img :src="imgURL" alt=""> <a :href="aHref">v-bind的基本使用</a> </div> <script> const app = new Vue({ el:"#app", data:{ message:"Hello Ting,I am Key!", imgURL:"https:www.baidu.com", aHref:"https://blog.csdn.net/weixin_43745075?spm=1001.2101.3001.5343" } }) </script> 绑定class 1.绑定方式:对象语法 对象语法的含义是:class后面跟的是一个对象 2.用法: 1.直接通过{ }绑定一个类,isActive是一个boolean值 <h2 :class="{'active':isActive}">Hello Ting, I am Key!</h2> 2.通过判断,传入多个值 <h2 :class="{'active':isActive,'family':isFamily}">Hello Ting, I am Key!</h2> 3.和普通的类同时存在,并不冲突 注:如果isActive和isFamily都为true,那么会有size/active/family三个类 <h2 class="size" :class="{'active':isActive,'family':isFamily}">Hello Ting, I am Key!

Redis中的跳跃表详解

简介 跳跃表(skiplist)是一种随机化的数据结构,是一种可以与平衡树媲美的层次化链表结构——查找、删除、添加等操作都可以在对数期望时间下完成。 Redis 的五种基本结构中,有一个叫做 有序列表 zset 的数据结构,它类似于 Java 中的 SortedSet 和 HashMap 的结合体,一方面它是一个 set 保证了内部 value 的唯一性,另一方面又可以给每个 value 赋予一个排序的权重值 score,来达到 排序 的目的。 它的内部实现就依赖了一种叫做 「跳跃列表」 的数据结构。 本质是解决查找问题 我们需要这个链表按照 score 值进行排序,这也就意味着,当我们需要添加新的元素时,我们需要定位到插入点,这样才可以继续保证链表是有序的,通常我们会使用 二分查找法,但二分查找是有序数组的,链表没办法进行位置定位,我们除了遍历整个找到第一个比给定数据大的节点为止 (时间复杂度 O(n)) 似乎没有更好的办法。 假如我们每相邻两个节点之间就增加一个指针,让指针指向下一个节点,如下图: 这样所有新增的指针连成了一个新的链表,但它包含的数据却只有原来的一半 (图中的为 3,11)。 现在假设我们想要查找数据时,可以根据这条新的链表查找,如果碰到比待查找数据大的节点时,再回到原来的链表中进行查找,比如,我们想要查找 7,查找的路径则是沿着下图中标注出的红色指针所指向的方向进行的: 通过新增加的指针查找,我们不再需要与链表上的每一个节点逐一进行比较,这样改进之后需要比较的节点数大概只有原来的一半。 利用同样的方式,我们可以在新产生的链表上,继续为每两个相邻的节点增加一个指针,从而产生第三层链表: 在这个新的三层链表结构中,我们试着 查找 13,那么沿着最上层链表首先比较的是 11,发现 11 比 13 小,于是我们就知道只需要到 11 后面继续查找,从而一下子跳过了 11 前面的所有节点。 可以想象,当链表足够长,这样的多层链表结构可以帮助我们跳过很多下层节点,从而加快查找的效率。 更进一步的跳跃表 跳跃表 skiplist 就是受到这种多层链表结构的启发而设计出来的。按照上面生成链表的方式,上面每一层链表的节点个数,是下面一层的节点个数的一半,这样查找过程就非常类似于一个二分查找,使得查找的时间复杂度可以降低到 O(logn)。 但是,这种方法在插入数据的时候有很大的问题。新插入一个节点之后,就会打乱上下相邻两层链表上节点个数严格的 2:1 的对应关系。如果要维持这种对应关系,就必须把新插入的节点后面的所有节点 (也包括新插入的节点) 重新进行调整,这会让时间复杂度重新蜕化成 O(n)。删除数据也有同样的问题。 skiplist 为了避免这一问题,它不要求上下相邻两层链表之间的节点个数有严格的对应关系,而是 为每个节点随机出一个层数(level)。比如,一个节点随机出的层数是 3,那么就把它链入到第 1 层到第 3 层这三层链表中。为了表达清楚,下图展示了如何通过一步步的插入操作从而形成一个 skiplist 的过程:

mac安装QT及QT基本使用

mac安装QT及QT基本使用 目录 QT安装QT基本使用 1. QT安装 根据需求下载对应QT版本(官网会下载速度很慢),地址:http://mirrors.ustc.edu.cn/qtproject/archive/qt/ 打开下载好的安装进行安装。(我点了很多次安装才显示安装界面)选择需要安装的插件,点击安装即可。注意点 邮箱必填,如果之前没有申请,需要申请。可以参考这边安装流程,很简单我就忘了截图了,mac安装Qt教程 安装成功页面展示 2. QT基本使用 1. 创建测试项目 文件->新建文件或项目,选择创建项目类型。 创建项目填写信息。名称自定义,创建路径在QT目录下,并在QT目录下创建workspace目录当工作目录。 选择qmake 选择kits,如果没有对应kit,说明没有安装qmake,qmake安装教程:https://blog.csdn.net/Marco_L/article/details/107243963 最后点完成即可。 如果运行结果展示到了终端上,取消方法: debug无法显示,在终端设置版本号。 defaults write com.apple.dt.lldb DefaultPythonVersion 2 检查是否设置成功

关系型数据库和Nosql非关系数据库的优缺点介绍,选择分析

读过这篇文章后,你会对关系数据库和非关系数据有个非常清晰的了解 关系型数据库:Oracle,Microsoft SQL Server,MySQL,PostgreSQL,DB2,Microsoft Access, SQLite,Teradata,MariaDB(MySQL的一个分支),SAP; 非关系型数据库:MongoDB,Redis,Couchbase,HBase,neo4j,Amazon DynamoDB,Memcached,Microsoft Azure Cosmos DB,CouchDB,Elasticsearch,Splunk,Solr,MarkLogic,Sphinx,Cassandra,Datastax Enterprise,Accumulo,Hazelcast 注意:以下文章都是转载的,转载链接都在每个段落的下方 一、关系型数据库 当今十大主流的关系型数据库 Oracle,Microsoft SQL Server,MySQL,PostgreSQL,DB2,Microsoft Access, SQLite,Teradata,MariaDB(MySQL的一个分支),SAP 1.什么是关系型数据库 关系型数据库:指采用了关系模型来组织数据的数据库。 关系模型指的就是二维表格模型,而一个关系型数据库就是由二维表及其之间的联系所组成的一个数据组织。 2.关系型数据库的优点: 1.容易理解:二维表结构是非常贴近逻辑世界的一个概念,关系模型相对网状、层次等其他模型来说更容易理解 2.使用方便:通用的SQL语言使得操作关系型数据库非常方便 3.易于维护:丰富的完整性(实体完整性、参照完整性和用户定义的完整性)大大减低了数据冗余和数据不一致的概率 3.关系型数据库存在的问题 1.网站的用户并发性非常高,往往达到每秒上万次读写请求,对于传统关系型数据库来说,硬盘I/O是一个很大的瓶颈 2.网站每天产生的数据量是巨大的,对于关系型数据库来说,在一张包含海量数据的表中查询,效率是非常低的 3.在基于web的结构当中,数据库是最难进行横向扩展的,当一个应用系统的用户量和访问量与日俱增的时候,数据库却没有办法像web server和app server那样简单的通过添加更多的硬件和服务节点来扩展性能和负载能力。当需要对数据库系统进行升级和扩展时,往往需要停机维护和数据迁移。 4.性能欠佳:在关系型数据库中,导致性能欠佳的最主要原因是多表的关联查询,以及复杂的数据分析类型的复杂SQL报表查询。为了保证数据库的ACID特性,必须尽量按照其要求的范式进行设计,关系型数据库中的表都是存储一个格式化的数据结构。 数据库事务必须具备ACID特性,ACID分别是Atomic原子性,Consistency一致性,Isolation隔离性,Durability持久性。 二、非关系型数据库 MongoDB,Redis,Couchbase,HBase,neo4j,Amazon DynamoDB,Memcached,Microsoft Azure Cosmos DB,CouchDB,Elasticsearch,Splunk,Solr,MarkLogic,Sphinx,Cassandra,Datastax Enterprise,Accumulo,Hazelcast 1.什么是非关系型数据库 非关系型数据库:指非关系型的,分布式的,且一般不保证遵循ACID原则的数据存储系统。 2.非关系型数据库结构 非关系型数据库以键值对存储,且结构不固定,每一个元组可以有不一样的字段,每个元组可以根据需要增加一些自己的键值对,不局限于固定的结构,可以减少一些时间和空间的开销。 3.优点 1.用户可以根据需要去添加自己需要的字段,为了获取用户的不同信息,不像关系型数据库中,要对多表进行关联查询。仅需要根据id取出相应的value就可以完成查询。 2.适用于SNS(Social Networking Services)中,例如facebook,微博。系统的升级,功能的增加,往往意味着数据结构巨大变动,这一点关系型数据库难以应付,需要新的结构化数据存储。由于不可能用一种数据结构化存储应付所有的新的需求,因此,非关系型数据库严格上不是一种数据库,应该是一种数据结构化存储方法的集合。 4.不足: 只适合存储一些较为简单的数据,对于需要进行较复杂查询的数据,关系型数据库显的更为合适。不适合持久存储海量数据 5.非关系型数据库的分类 非关系型数据库都是针对某些特定的应用需求出现的,因此,对于该类应用,具有极高的性能。依据结构化方法以及应用场合的不同,主要分为以下几类: 5.1面向高性能并发读写的key-value数据库: key-value数据库的主要特点是具有极高的并发读写性能 Key-value数据库是一种以键值对存储数据的一种数据库,类似Java中的map。可以将整个数据库理解为一个大的map,每个键都会对应一个唯一的值。 主流代表为Redis, Amazon DynamoDB, Memcached, Microsoft Azure Cosmos DB和Hazelcast 5.2面向海量数据访问的面向文档数据库: 这类数据库的主要特点是在海量的数据中可以快速的查询数据 文档存储通常使用内部表示法,可以直接在应用程序中处理,主要是JSON。JSON文档也可以作为纯文本存储在键值存储或关系数据库系统中。