又到了一年的军训季,我的脑海中闪现出军训时的一幅幅画面,我控制不住的落下几颗泪珠,但嘴角却是微微上扬的。我关上灯,外面亮晶晶的月光从窗户钻进来洒落在深褐色的书桌,并在墙上映出窗帘和我的影子,我托腮站在书桌前,微风透过窗帘吹乱了我额头前的几缕丝发,我轻轻地把它挽到耳朵后,慢慢地闭上我的眼睛,好像又回到了我们开始军训的时候:
“一二一、一二一……”我们在操场上踏着参差不齐的步伐,听着总教官的口号,不停的整理队形,我们有4千多名新生,因为军训,让我们在数量庞大且相互之间不认识的情况变为后来的相互认识、相互了解。
最令我们头疼的是站军姿,我们有一次站了两个小时的军姿,不少的同学在经过暴晒之后晕倒,但都在休息一会儿并感觉自己好些时回来接着站,当宣布站军姿结束时,同学们都纷纷转动自己的脚,以求得到舒缓 。当太阳射出一束束耀眼的光圈时,我们脱下帽子进行一个多小时的暴晒,我们脸的颜色与刚军训时差的不是一两度!晒黑不可怕,晒伤才痛苦—我们晚上回到寝室的时候,感觉自己的脖子和脸像是被烫伤一样锥心的疼。当下着倾盆大雨时,我们还继续进行训练,在这期间既好玩又痛苦:在走正步的时候脚用力踩水坑,水飞溅出来,洒在旁边同学的裤脚上;在我们全身湿透、冷风吹来瑟瑟发抖时,顽皮的男同学把另外一个男同学的衣服更加贴近身体,那感觉真的是“透心凉、心飞扬”!我们的帽沿不时滴下一颗颗水珠,嘴唇发紫,身体止不住的颤抖,可教官还是没有叫我们停下休息的意思。我们心想:没人性啊!参谋长说:“我们军队就是女生当男生用,男生当畜生用。”我们风里、雨里都度过。
不过当中也有苦中作乐的地方:我们看到了以前从未看到过的格斗—当中体现了中国男儿的阳刚之美,更是少不了休息之余我们用吼唱出来的军歌,这些都是我们在日常生活中看不到、听不到的。相对于那些光鲜亮丽的舞台来说,我们在军训期间的舞台实在是简陋,在草坪的正中央就是舞台,大家坐着围成一圈圈并用手机的手电筒随着节奏挥舞着。
军训结束后,参谋长进行总结时说:“我看到你们那么痛苦地在下面站着,其实我也是心疼你们的,但正因为爱你们,才对你们这么严格。”在所有教官要离开时,我们进行了一次正式的告别!总教官喊着响亮的口号对我们进行最后一次的训练,我们熟练地变换队形,随后教官排成一排向我们致以军人最高的礼节—敬礼!我们纵然有千言万语却说不出口,只有伸起沉重的右手向他们回敬,我们饱含泪水,保持着敬礼的姿势看着他们从主席台前一步一步向操场口走去,直到他们的背影在远处消失,我们还是盯着出口看,久久不肯回头。
我慢慢地张开双眼并打开灯,翻阅着我们军训时的照片,回味着那时的点点滴滴,抚摸着叠得整整齐齐的军训服装……我鼻子一酸,只好把它重新放回衣柜里,轻轻的关上衣柜门……
版权归作者所有,任何形式转载请联系作者。
作者:咖啡茶(首发自豆瓣)
来源:https://www.douban.com/note/690250036/
很多实际的项目,我们都难以有充足的数据来完成任务,要保证完美的完成任务,有两件事情需要做好:(1)寻找更多的数据。(2)充分利用已有的数据进行数据增强,今天就来说说数据增强。
作者 | 言有三
编辑 | 言有三
mall
1 什么是数据增强?
数据增强也叫数据扩增,意思是在不实质性的增加数据的情况下,让有限的数据产生等价于更多数据的价值。
比如上图,第1列是原图,后面3列是对第1列作一些随机的裁剪、旋转操作得来。
每张图对于网络来说都是不同的输入,加上原图就将数据扩充到原来的10倍。假如我们输入网络的图片的分辨率大小是256×256,若采用随机裁剪成224×224的方式,那么一张图最多可以产生32×32张不同的图,数据量扩充将近1000倍。虽然许多的图相似度太高,实际的效果并不等价,但仅仅是这样简单的一个操作,效果已经非凡了。
如果再辅助其他的数据增强方法,将获得更好的多样性,这就是数据增强的本质。
数据增强可以分为,有监督的数据增强和无监督的数据增强方法。其中有监督的数据增强又可以分为单样本数据增强和多样本数据增强方法,无监督的数据增强分为生成新的数据和学习增强策略两个方向。
2 有监督的数据增强
有监督数据增强,即采用预设的数据变换规则,在已有数据的基础上进行数据的扩增,包含单样本数据增强和多样本数据增强,其中单样本又包括几何操作类,颜色变换类。
2.1. 单样本数据增强
所谓单样本数据增强,即增强一个样本的时候,全部围绕着该样本本身进行操作,包括几何变换类,颜色变换类等。
(1) 几何变换类
几何变换类即对图像进行几何变换,包括翻转,旋转,裁剪,变形,缩放等各类操作,下面展示其中的若干个操作。
水平翻转和垂直翻转
随机旋转
随机裁剪
变形缩放
翻转操作和旋转操作,对于那些对方向不敏感的任务,比如图像分类,都是很常见的操作,在caffe等框架中翻转对应的就是mirror操作。
翻转和旋转不改变图像的大小,而裁剪会改变图像的大小。通常在训练的时候会采用随机裁剪的方法,在测试的时候选择裁剪中间部分或者不裁剪。值得注意的是,在一些竞赛中进行模型测试时,一般都是裁剪输入的多个版本然后将结果进行融合,对预测的改进效果非常明显。
以上操作都不会产生失真,而缩放变形则是失真的。
很多的时候,网络的训练输入大小是固定的,但是数据集中的图像却大小不一,此时就可以选择上面的裁剪成固定大小输入或者缩放到网络的输入大小的方案,后者就会产生失真,通常效果比前者差。
(2) 颜色变换类
上面的几何变换类操作,没有改变图像本身的内容,它可能是选择了图像的一部分或者对像素进行了重分布。如果要改变图像本身的内容,就属于颜色变换类的数据增强了,常见的包括噪声、模糊、颜色变换、擦除、填充等等。
基于噪声的数据增强就是在原来的图片的基础上,随机叠加一些噪声,最常见的做法就是高斯噪声。更复杂一点的就是在面积大小可选定、位置随机的矩形区域上丢弃像素产生黑色矩形块,从而产生一些彩色噪声,以Coarse Dropout方法为代表,甚至还可以对图片上随机选取一块区域并擦除图像信息。
添加Coarse Dropout噪声
颜色变换的另一个重要变换是颜色扰动,就是在某一个颜色空间通过增加或减少某些颜色分量,或者更改颜色通道的顺序。
颜色扰动
还有一些颜色变换,本文就不再详述。
几何变换类,颜色变换类的数据增强方法细致数还有非常多,推荐给大家一个git项目:
https://github.com/aleju/imgaug
预览一下它能完成的数据增强操作吧。
2.2. 多样本数据增强
不同于单样本数据增强,多样本数据增强方法利用多个样本来产生新的样本,下面介绍几种方法。
(1) SMOTE[1]
SMOTE即Synthetic Minority Over-sampling Technique方法,它是通过人工合成新样本来处理样本不平衡问题,从而提升分类器性能。
类不平衡现象是很常见的,它指的是数据集中各类别数量不近似相等。如果样本类别之间相差很大,会影响分类器的分类效果。假设小样本数据数量极少,如仅占总体的1%,则即使小样本被错误地全部识别为大样本,在经验风险最小化策略下的分类器识别准确率仍能达到99%,但由于没有学习到小样本的特征,实际分类效果就会很差。
SMOTE方法是基于插值的方法,它可以为小样本类合成新的样本,主要流程为:
第一步,定义好特征空间,将每个样本对应到特征空间中的某一点,根据样本不平衡比例确定好一个采样倍率N;
第二步,对每一个小样本类样本(x,y),按欧氏距离找出K个最近邻样本,从中随机选取一个样本点,假设选择的近邻点为(xn,yn)。在特征空间中样本点与最近邻样本点的连线段上随机选取一点作为新样本点,满足以下公式:
第三步,重复以上的步骤,直到大、小样本数量平衡。
该方法的示意图如下。
在python中,SMOTE算法已经封装到了imbalanced-learn库中,如下图为算法实现的数据增强的实例,左图为原始数据特征空间图,右图为SMOTE算法处理后的特征空间图。
(2) SamplePairing[2]
SamplePairing方法的原理非常简单,从训练集中随机抽取两张图片分别经过基础数据增强操作(如随机翻转等)处理后经像素以取平均值的形式叠加合成一个新的样本,标签为原样本标签中的一种。这两张图片甚至不限制为同一类别,这种方法对于医学图像比较有效。
经SamplePairing处理后可使训练集的规模从N扩增到N×N。实验结果表明,因SamplePairing数据增强操作可能引入不同标签的训练样本,导致在各数据集上使用SamplePairing训练的误差明显增加,而在验证集上误差则有较大幅度降低。
尽管SamplePairing思路简单,性能上提升效果可观,符合奥卡姆剃刀原理,但遗憾的是可解释性不强。
(3) mixup[3]
mixup是Facebook人工智能研究院和MIT在“Beyond Empirical Risk Minimization”中提出的基于邻域风险最小化原则的数据增强方法,它使用线性插值得到新样本数据。
最近学习了lamada的常见使用方法,发现其实lamada表达式的确是匿名内部类一种简便的使用,话不多说,如下举例
Student studentww=new Student("wangwu",99,"code"); Student studentclr=new Student("clr",100,"qianduan"); findFirst().get();过滤:要返回list中单个对象的数据时候,且有过滤条件的
Student students=studentLIst.stream().filter(e->e.getName().startsWith("w")).findFirst().get(); .map(e->e.getAge())取数据操作:将对象中的某个字段取出来组成list
lIst.stream().map(e->e.getAge()).collect(Collectors.toList()); .sorted(Integer::compareTo) 排序且取出第一个
studentLIst.stream().map(e->e.getAge()).sorted(Integer::compareTo).findFirst().get(); .sorted(Integer::compareTo) 排序且返回list<Integer>
studentLIst.stream().map(e->e.getAge()).sorted(Integer::compareTo).collect(Collectors.toList()); .sorted((p1,p2)->p1.getAge()-p2.getAge()) 排序且返回list<Student>
studentLIst.stream().sorted((p1,p2)->p1.getAge()-p2.getAge()).collect(Collectors.toList()); (e)->{studentLIst11.add(e);}); 将满足条件的放入另外一个List
studentLIst.stream().filter((e)->e.getAge()>99).forEach((e)->{ studentLIst11.add(e); }); 一开始接触lamada表达式会感觉有点难以理解,慢慢就好了,习惯就好。加油
版权声明:本文为博主原创文章,转载请注明出处。 https://blog.csdn.net/amoscn/article/details/86544468
@Cleanup
当在处理文件对象,或者数据库资源时,我们总是会忘记close,可能引发内存溢出。
如果手动去调用close方法,代码又会非常长,现在有了@Cleanup , 我们不再需要担心这些问题。
您可以使用@Cleanup确保在代码执行路径退出当前作用域之前自动清除给定资源。 您可以通过使用@Cleanup注释来注释任何局部变量声明来执行此操作,如下所示:
@Cleanup InputStream in = new FileInputStream(“some / file”);
因此,在您所在范围的末尾,调用in.close()。 保证通过try / finally构造运行此调用。 请看下面的示例,看看它是如何工作的。
如果要清理的对象类型没有close()方法,而是其他一些无参数方法,则可以指定此方法的名称,如下所示:
@Cleanup(“dispose”)org.eclipse.swt.widgets.CoolBar bar = new CoolBar(parent,0);
默认情况下,清除方法假定为close()。 不能通过@Cleanup调用带有1个或多个参数的清理方法。
为了方便理解,我们假设该内存资源是一扇门。初始化的时候,这扇门默认是打开的,等于说允许你在房间里做一些事情(看书,打游戏,睡觉) - 方法调用。将内存资源回收当作把门关掉,也就是不再允许你再做上述动作。(也许有人说,我可以关门看书,打游戏,睡觉!!!只是示例而已,别杠!!!)
看代码!非常简单易懂!!
package com.amos.lombok;
import lombok.Cleanup;
/**
* @author chenjun
*/
public class Door {
/**
* 门是否打开
* true : 打开
* false : 关闭
*/
private boolean openStatus;
public Door(boolean openStatus) {
this.openStatus = openStatus;
本机部署了Android自动化测试环境(Appium+Python),每天定时执行任务,遇到了一个问题,就是启动模拟器前,都需要在cmd程序中执行adb start-server,来启动adb服务,想着能不能写个定时任务,每天开机后就启动cmd并执行命令。
经上网查阅资料后得知可以写个bat批处理文件,代码如下
@echo off start "C:\Windows\System32\cmd.exe" adb start-server taskkill /f /im cmd.exe 第二行代码是启动cmd程序;
第三行代码是在cmd中执行指令;
第四行代码是执行指令后关闭cmd程序窗口,该代码可以用exit替换;
那么写好bat批处理文件之后怎么去执行呢,这里提供以下几种方法:
1.把bat文件放到本机的启动文件夹中,具体路径可以在所有程序中的启动文件夹找到;
2.创建任务计划
在所有程序中搜索【任务计划】,然后创建任务,输入任务名称和描述,选择触发器和操作,选择脚本,即可创建任务
计划任务执行后如果出现因为用户未登录到网络,因此未执行所要求的的操作,指定的服务不存在,错误信息,更改如下配置即可解决
3.在cmd中使用命令行工具schtasks来创建
这方法相对前面两种办法会复杂一点,具体请参考网上教程
一、filezilla server 安装指南:FileZilla是一款免费而且开源的FTP工具。包括FileZilla Client,FileZilla Server两个版本。FileZilla Server只提供了windows系统下的版本,我们要将本地的网站网页文件上传到网站服务器,或从服务器下载网页文件,只需FileZilla Client客户端版本就可以了。filezilla server 安装指南。
1、官方下载
2、安装时候按默认安装即可。
3、首先要进行服务器全局参数设置:点“Edit”菜单,选“Settings”
General settings(常规设置):
Listen on Port:监听端口,其实就是FTP服务器的连接端口。
Max.Number of users:允许最大并发连接客户端的数量。
Number of Threads:处理线程。也就是CPU优先级别。数值调得越大优先级越高,一般默认即可。
下面的是超时设置,自上至下分别为:连接超时、传输空闲超时、登入超时。单位为秒。
Welcome message页面设置客户端登录成功以后显示的Welcome信息。建议不要用软件默认的,因为任何软件都不能保证没有什么漏洞,如果在这里暴露软件名称的话,一旦这个FTP Server软件有什么安全漏洞,别有用心的人知道了服务器软件的名称就可能针对性地发起攻击。所以建议这里设置的信息不要包含任何服务器资料。
IP Filter(IP过滤器)页面,设置IP过滤规则,在上面栏目中的IP是被禁止的,下面的是允许的。
Passive mode settings(被动传输模式设置):这个页面要重点关注。如果服务器本身直接拥有公网IP,可以选软件默认的“Default”。
倘若服务器是在局域网里面,在一个网关后面,那么就要选择第二项“Use the follwoing IP”,并且在下面的输入栏填写公网的IP地址;否则,客户端用PASV被动模式可能无法连接FTP服务器。因为服务器是在内网中,在客户端使用PASV模式连接服务器的时候,服务器收到连接请求之后需要把自身的IP地址告诉客户端,由于服务器在内网中,它侦测到的IP地址是内网的(如192.168.0.5),它把这个IP地址交给客户端,客户端自然无法连接。在这里设置了指定的IP地址后,服务器就会把这个公网合法的IP地址提交给客户端,这样才能正常建立连接。
如果服务器是动态IP的,那么可以选择下面的“Retrieve external IP address from”,利用FileZilla官方网站免费提供的IP查询页面获取当时的公网合法IP,然后服务器把这个公网合法IP地址提交给客户端。当然静态IP也可以用这个,只不过没有必要。
这个设置页面对服务器位于内网的情况非常重要。有些FTP服务器端没有这个设置项目,客户端就只能用Port主动模式连接。当然有些客户端软件针对这个问题有专门的设置,如FlashFXP的站点设置中只要选中“被动模式使用站点IP”就可以了。
对于在局域网中的服务器,如果服务器没有置于DMZ区,那么强烈建议选中下面的“Use custom port range”定义PASV端口范围。由于PASV模式中,是服务器随机打开端口,然后把打开的端口号告诉客户端,让客户端连接打开的端口。但是因为服务器处于网关后面,如果网关那里没有做对应的端口映射,客户端从外网就无法连接服务器打开的端口,导致PASV模式连接失败。在这里限定服务器打开的端口范围,然后到连接外网的网关那里,对服务器的这些端口做端口映射(虚拟服务)。这需要服务器和Internet网关设备配合设置,这样外网的客户端才能用PASV模式连接进来。
Security settings(安全设置):这里的两个选项关系到能否FXP。软件默认状态“Block incoming server-to-server transfers”和“Block outgoing server-to-server transfers”两项都是选中的,前面那项是禁止连入的服务器对传,后面是禁止传出的服务器对传。也就是说默认状态不允许FXP,如果需要使用FXP,那么就把这两个项目取消选择。注意FXP传输除了跟这个页面的设置有关,还跟IP过滤器有关。
Admin Interface setting(管理员界面设定):这个就是登录配置服务器界面的一些参数。端口号的设置在安装的时候也出现过。下面两栏可以定义允许远程登录配置的网络界面和IP地址。在最下面更改管理员口令。
Logging(日志):设定是否启用日志记录功能以及日志文件大小和文件名。
Speed Limits(速度限制):这个是全局参数,默认状态不限速。可以选中“Constant Speed Limit of”并填写限速数值来实现速度限制,下载(传出)和上传(传入)可以分别设置。还可以根据时段自定义限速规则——“Use Speed Limit Rules”,比如这台服务器或者网络连接除了做FTP服务器之外还有别的用途,需要根据时间调度,不能让FTP传输挤占所有网络带宽影响其它的网络服务;就可以通过这里设置。
Filetransfer compression(文件传输压缩设置):MODE Z FTP协议是一种实时压缩的传输协议。在这种模式下,发送方的数据在发出之前先进行压缩,再送到网络链路中传输,接收方将收到数据实时解包,在本地还原重组成原文件。这种模式可以大幅度减少网络中的数据流量,提升传输效率(速度)。当然对于已经压缩过的文件,就几乎没有效果了。要使用这种传输模式,需要服务器端和客户端都支持MODE Z协议。
单调栈-LeetCode 85.最大矩形
给定一个仅包含 0 和 1 的二维二进制矩阵,找出只包含 1 的最大矩形,并返回其面积。
示例:
输入:
[
["1","0","1","0","0"],
["1","0","1","1","1"],
["1","1","1","1","1"],
["1","0","0","1","0"]
]
输出: 6
枚举每一行,当前行的每一列就可以组成一个类似于上图的柱状图,然后就是求柱状图中的最大矩形,更新最大值即可. stack<int> s; vector<int> v; class Solution { public: int maximalRectangle(vector<vector<char>>& matrix) { if(matrix.empty()) return 0; int row=matrix.size(),col=matrix[0].size(); v.clear(); int ans=0; for(int i=0; i<row; i++) { for(int j=0; j<col; j++) { if(i==0) { v.push_back(matrix[i][j]=='1'?1:0); } else { v[j]=(matrix[i][j]=='1'?v[j]+1:0); } } ans=max(ans,largestRectangleArea()); } return ans; } int largestRectangleArea() { while(!s.empty()) s.pop(); int maxarea=0,n=v.
服务器的Redis连接不上解决方案 前言解决方案 前言 如果你看到这里,我默认你已经安装好了redis,并且已经成功的在虚拟机的Linux系统中ping通。
我真的是太气愤了!!!网上虽然确实有一大堆人出谋划策,帮助大家解决学习过程中遇到的Bug。但是!!!能不能不要千篇一律复制粘贴!!对自己写的东西负责好吗!!!
从头到尾,我看了百来篇技术博客、文档,都是说bind 127.0.0.1注释掉(确实需要),受保护模式改为no设置密码主机和虚拟机ip要在同一网段等(根本不需要)…还有要不就是贴一堆failure trace代码!!连那种没有用的代码问问题的时候都要粘上来,谁有那个心情看啊!!!
请务必答应我错误代码放精华部分就行了好吗!!!
好吧,上面是牢骚,接下来才是正题!!
如果你已经用完了上述所有方法还是无法解决redis desktop manager无法连接虚拟机中的redis时,罪魁祸首一定是你的虚拟机防火墙。
解决方案 最好的测试是不是虚拟机中的linux系统的防火墙在捣鬼的办法如下:
打开你windos系统的cmd,敲 telnet linux系统ip 端口号,如:telnet 192.168.192.171 6379
(linux系统的Ip应该都知道咋看吧,敲ifconfig取第一个出现的Ip地址就行了)
如果提示telnet不是内部外部指令啥的,打开控制面板,依次点击下图中矩形框中的东西
如果出现(当然我输6380是为了截图失败的结果,你应该输的估计是6379)那就说明的确是你的centos的防火墙在整幺蛾子!
依次输入如下代码:
/etc/init.d/iptables stop /sbin/iptables -I INPUT -p tcp --dport 6379 -j ACCEPT /etc/init.d/iptables save service iptables restart 完了之后,可以查看一下是否开放成功,检查状态的代码:/etc/init.d/iptables status
一般到这里就差不多解决了,最后记得改完配置一定要重启!重启!重启!
重启后输入 telnet 192.168.192.171 6379
/* Jedis jedis = new Jedis("192.168.192.171", 6379); String ping = jedis.ping(); System.out.println(ping); jedis.set("age","20"); System.out.println(jedis.get("age"));*/ ValueOperations ops =redisTemplate.opsForValue(); ops.set("name","JustinNeil"); System.out.println(ops.get("name")); ValueOperations ops1 =stringRedisTemplate.
C#实现PDF文件转Word文件,需要引入Spire.Pdf.dll和Spire.License.dll,免费版本的Spire.Pdf只支持转换10也以内的PDF。这里为大家提供了付费版的百度网盘下载链接: https://pan.baidu.com/s/1R3BhMQh8XwAUcE-Pa_OOBA 提取码: 4k1f
下载好后,把Spire.Pdf.dll和Spire.License.dll拷到项目文件夹中(位置任意,找得到就行)。
程序中添加引用
因为代码量较少,这里建一个控制台应用程序做演示,代码如下:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Spire.Pdf; using Spire.License; namespace pdfToWord { class Program { static void Main(string[] args) { PdfDocument doc = new PdfDocument(); doc.LoadFromFile(@"C:\Users\Administrator\Desktop\高效Web前端框架Layui教程.pdf");//pdf物理路径 Console.WriteLine("转换中请耐心等待....."); doc.SaveToFile(@"C:\Users\Administrator\Desktop\高效Web前端框架Layui教程.doc", FileFormat.DOC);//生成word的物理路径 Console.WriteLine("转换成功"); } } } 转换成功,可以看到桌面已经生成相应的word文件,并且成功打开
文章目录 引用类型 引用类型 引用数据类型 :
1. 引用数据类型定义 : 类型名称& 变量名 = 对应类型变量名称 ; //① 定义 普通 类型 变量 int a = 8; //② 定义 引用类型变量, 格式 : 类型名称& 变量名 = 对应类型变量名称 ; int& b = a; 2. 上述引用数据类型解析 : int& 是引用数据类型 , b 是 a 的引用 ;
① 变量定义本质 : int a = 8; 分配一块内存存放 int 类型数据 8 , 将该内存赋予一个别名 a ;② 引用定义本质 : 给变量 a 所在内存赋予另外一个别名 b ; 3.
1、树转换为二叉树
由于二叉树是有序的,为了避免混淆,对于无序树,我们约定树中的每个结点的孩子结点按从左到右的顺序进行编号。
将树转换成二叉树的步骤是:
(1)加线。就是在所有兄弟结点之间加一条连线;
(2)抹线。就是对树中的每个结点,只保留他与第一个孩子结点之间的连线,删除它与其它孩子结点之间的连线;
(3)旋转。就是以树的根结点为轴心,将整棵树顺时针旋转一定角度,使之结构层次分明。
树转换为二叉树的过程示意图
2、森林转换为二叉树
森林是由若干棵树组成,可以将森林中的每棵树的根结点看作是兄弟,由于每棵树都可以转换为二叉树,所以森林也可以转换为二叉树。
将森林转换为二叉树的步骤是:
(1)先把每棵树转换为二叉树;
(2)第一棵二叉树不动,从第二棵二叉树开始,依次把后一棵二叉树的根结点作为前一棵二叉树的根结点的右孩子结点,用线连接起来。当所有的二叉树连接起来后得到的二叉树就是由森林转换得到的二叉树。
森林转换为二叉树的转换过程示意图
3、二叉树转换为树
二叉树转换为树是树转换为二叉树的逆过程,其步骤是:
(1)若某结点的左孩子结点存在,将左孩子结点的右孩子结点、右孩子结点的右孩子结点……都作为该结点的孩子结点,将该结点与这些右孩子结点用线连接起来;
(2)删除原二叉树中所有结点与其右孩子结点的连线;
(3)整理(1)和(2)两步得到的树,使之结构层次分明。
二叉树转换为树的过程示意图
4、二叉树转换为森林
二叉树转换为森林比较简单,其步骤如下:
(1)先把每个结点与右孩子结点的连线删除,得到分离的二叉树;
(2)把分离后的每棵二叉树转换为树;
(3)整理第(2)步得到的树,使之规范,这样得到森林。
根据树与二叉树的转换关系以及二叉树的遍历定义可以推知,树的先序遍历与其转换的相应的二叉树的先序遍历的结果序列相同;树的后序遍历与其转换的二叉树的中序遍历的结果序列相同;树的层序遍历与其转换的二叉树的后序遍历的结果序列相同。由森林与二叉树的转换关系以及森林与二叉树的遍历定义可知,森林的先序遍历和中序遍历与所转换得到的二叉树的先序遍历和中序遍历的结果序列相同。
Windows下Beyond Compare 4 30天评估到期了的话,可以尝试下面两种方式:
破解方式
把Beyond Compare 4安装文件夹下面的BCUnrar.dll文件删掉就行了,但是这种依然会提示在试用期
BC4注册码:
可以用下面这个注册码,有效期是到2019年12月
— BEGIN LICENSE KEY —
H1bJTd2SauPv5Garuaq0Ig43uqq5NJOEw94wxdZTpU-pFB9GmyPk677gJ
vC1Ro6sbAvKR4pVwtxdCfuoZDb6hJ5bVQKqlfihJfSYZt-xVrVU27+0Ja
hFbqTmYskatMTgPyjvv99CF2Te8ec+Ys2SPxyZAF0YwOCNOWmsyqN5y9t
q2Kw2pjoiDs5gIH-uw5U49JzOB6otS7kThBJE-H9A76u4uUvR8DKb+VcB
rWu5qSJGEnbsXNfJdq5L2D8QgRdV-sXHp2A-7j1X2n4WIISvU1V9koIyS
NisHFBTcWJS0sC5BTFwrtfLEE9lEwz2bxHQpWJiu12ZeKpi+7oUSqebX+
— END LICENSE KEY -----
历史文章:
JAVA微信企业付款到零钱(十分钟搞定)
微信授权获取用户openId的方法和步骤
一个微信号同时支持多个环境网页授权
微信两种签名算法MD5和HMAC-SHA256
https://blog.csdn.net/liyundiyi/article/details/80310322
可视图讲解神经元w,b参数的作用
在我们接触神经网络过程中,很容易看到就是这样一个式子,g(wx+b),其中w,x均为向量.比如下图所示:
加入激活函数为g(x),我们就可以用公式g(w1x1+w2x2+b)(注:1,2均为下标,公众号很难打,下面所有的公式均是)来表示神经元的输出。
其中b为神经元的偏置.那么w,b这些参数的作用有没有最直观的感受呢?以及我当时学习的时候问师兄的,每个神经元为什么要加上偏置b,不加又有什么后果呢?
下面通过二维可视化图来直观说明一下它们的作用:
加入我们激活函数用的是sigmoid函数,它的图像如下:
我们很容易看到sigmoid函数的作用是将输入映射到一个(0,1)的输出范围
现在我们还是有一个简单的任务,需要将下面三角形和圆形进行分类:
利用上面神经元训练可以得到一个直线,去线性分开这些数据点.方程如下:
w1x1+w2x2+b=0,我们就可以得到下面这条类似的直线去线性分割好俩种不同类型的数据点.
那么这条边界找到了.而这个边界是w1x1+w2x2+b=0的方程,而w1x1+w2x2+b是作为激活函数sigmoid的输入处理.
激活函数将这个输入映射到(0,1)的范围内.那么可以增加一个维度来表示激活函数的输出.
我们认为g(x)>0.5就为正类(这里指圆形),g(x)<0.5就为负类,这里指三角形类.得到的三维图如下:第三维z可以看成是一种类别!(比如圆形就是+1、三角形就是-1)
图来自:Hugo Larochelle课程ppt
那么就可以真正的可视化说明一下w.b等参数的作用在图中是怎么体现的~
我们从上图很容易得到,当我们将这个三维图进行投影的时候,就是我们上个用直线分割好俩类的平面图,三维图中的那个分割平面投影下来就是方程w1x1+w2x2+b=0.
右边输出为1的部分就是说w1x1+w2x2+b>0,导致激活函数输出>0.5,从而分为正类( 圆形类),左边输出为-1的部分就是说w1x1+w2x2+b<0,导致激活函数输出<0.5,从而分为负类( 三角形类)
1 w参数的作用 其中w参数的作用,我们可以得到,是决定那个分割平面的方向所在.分割平面的投影就是直线w1x1+w2x2+b=0
我们解释如下,在二个输入中,可以得到w=[w1,w2],令方程w1x1+w2x2+b=0,那么该直线的斜率就是-w1/w2。随着w1,w2的变动,直线的方向也在改变,那么分割平面的方向也在改变~
2 b参数的作用 其中b参数的作用,是决定竖直平面沿着垂直于直线方向移动的距离,当b>0的时候,直线往左边移动,当b<0的时候,直线往右边移动.
我们通过例子解释如下:首先我们可以肯定是直线方向不变,因为我们没有动斜率的任何参数,只是改变b,要说明的就是为什么当b>0的时候,直线往左边移动,当b<0的时候,直线往右边移动.
假设我们有直线方程x1+x2-3=0,画出这个图像如下:
此时我们将b减小到0,图像变为如下:
我们从上面图像中很容易得到结论:
当b>0的时候,直线往左边移动,当b<0的时候,直线往右边移动.
有了b参数可视化作用之后,我们很容易解决我一开始的问题.每个神经元为什么要加上偏置b,不加又有什么后果呢?下面通过二维可视化图来直观说明一下它们的作用:
3 每个神经元为什么要加上偏置 我先不说为什么一定要加入偏置b,就还是上面的分类问题,假如我现在的样本点是如下这种:
此时我们希望得到的线性方程分割线是下面这种,能够正确的将俩类进行分开:
到这个时候,我想我们已经明白了,如果没有偏置的话,我们所有的分割线都是经过原点的,但是现实问题并不会那么如我们所愿.都是能够是经过原点线性可分的。
原文来源:作者:忆臻
可视图讲解神经元w,b参数的作用
</div>
基本概念 这里介绍一种用于n维图像数据的边界优化和区域分割的分割技术。该分割算法来自论文:Interactive Graph Cuts for Optimal Boundary & Region Segmentation of Objects in N-D Images。该方法通过交互式的或自动的定位一个或多个代表“物体”的点以及一个或多个代表“背景”的点来进行初始化—这些点被称作种子(Seed并被用于分割的硬约束(hard constraints)。另外的软约束(soft constraints)反映了边界和/或区域信息。基本原理如下图:
图弧的权重计算如下。
示例演示 我们利用OpenCV的GCGraph(实现最大流最小割)实现了Graph Cut算法。下面是核心算法的代码,完整的工程代码链接。
cv::Mat GraphCut::runInitially(const std::vector<cv::Point> &objectseeds, const std::vector<cv::Point> &backgroundseeds) { Mat image; // copy of image_ for computing if (image_.channels() == 3) { cvtColor(image_, image, cv::COLOR_RGB2GRAY); } else { image_.copyTo(image); } //update mask and compute intensity distributions uchar objecthist[256] = { 0 }; int objectcount = 0; uchar backgroundhist[256] = { 0 }; int backgroundcount = 0; uchar pixel = 0; for (auto &p : objectseeds) { pixel = image.
一、题目描述 有n个物品,它们有各自的体积和价值,现有给定容量的背包,如何让背包里装入的物品具有最大的价值总和?
为方便讲解和理解,下面讲述的例子均先用具体的数字代入,即:eg:number=4,capacity=8
二、总体思路 根据动态规划解题步骤(问题抽象化、建立模型、寻找约束条件、判断是否满足最优性原理、找大问题与小问题的递推关系式、填表、寻找解组成)找出01背包问题的最优解以及解组成,然后编写代码实现。
三、动态规划的原理 动态规划与分治法类似,都是把大问题拆分成小问题,通过寻找大问题与小问题的递推关系,解决一个个小问题,最终达到解决原问题的效果。但不同的是,分治法在子问题和子子问题等上被重复计算了很多次,而动态规划则具有记忆性,通过填写表把所有已经解决的子问题答案纪录下来,在新问题里需要用到的子问题可以直接提取,避免了重复计算,从而节约了时间,所以在问题满足最优性原理之后,用动态规划解决问题的核心就在于填表,表填写完毕,最优解也就找到。
最优性原理是动态规划的基础,最优性原理是指“多阶段决策过程的最优决策序列具有这样的性质:不论初始状态和初始决策如何,对于前面决策所造成的某一状态而言,其后各阶段的决策序列必须构成最优策略”。
四、背包问题的解决过程 在解决问题之前,为描述方便,首先定义一些变量:Vi表示第 i 个物品的价值,Wi表示第 i 个物品的体积,定义V(i,j):当前背包容量 j,前 i 个物品最佳组合对应的价值,同时背包问题抽象化(X1,X2,…,Xn,其中 Xi 取0或1,表示第 i 个物品选或不选)。
1、建立模型,即求max(V1X1+V2X2+…+VnXn);
2、寻找约束条件,W1X1+W2X2+…+WnXn<capacity;
3、寻找递推关系式,面对当前商品有两种可能性:
包的容量比该商品体积小,装不下,此时的价值与前i-1个的价值是一样的,即V(i,j)=V(i-1,j);还有足够的容量可以装该商品,但装了也不一定达到当前最优价值,所以在装与不装之间选择最优的一个,即V(i,j)=max{V(i-1,j),V(i-1,j-w(i))+v(i)}。 其中V(i-1,j)表示不装,V(i-1,j-w(i))+v(i) 表示装了第i个商品,背包容量减少w(i),但价值增加了v(i);
由此可以得出递推关系式:
j<w(i) V(i,j)=V(i-1,j)j>=w(i) V(i,j)=max{V(i-1,j),V(i-1,j-w(i))+v(i)} 这里需要解释一下,为什么能装的情况下,需要这样求解(这才是本问题的关键所在!):
可以这么理解,如果要到达V(i,j)这一个状态有几种方式?
肯定是两种,第一种是第i件商品没有装进去,第二种是第i件商品装进去了。没有装进去很好理解,就是V(i-1,j);装进去了怎么理解呢?如果装进去第i件商品,那么装入之前是什么状态,肯定是V(i-1,j-w(i))。由于最优性原理(上文讲到),V(i-1,j-w(i))就是前面决策造成的一种状态,后面的决策就要构成最优策略。两种情况进行比较,得出最优。
4、填表,首先初始化边界条件,V(0,j)=V(i,0)=0;
然后一行一行的填表:
如,i=1,j=1,w(1)=2,v(1)=3,有j<w(1),故V(1,1)=V(1-1,1)=0;又如i=1,j=2,w(1)=2,v(1)=3,有j=w(1),故V(1,2)=max{
V(1-1,2),V(1-1,2-w(1))+v(1) }=max{0,0+3}=3;如此下去,填到最后一个,i=4,j=8,w(4)=5,v(4)=6,有j>w(4),故V(4,8)=max{
V(4-1,8),V(4-1,8-w(4))+v(4) }=max{9,4+6}=10…… 所以填完表如下图:
5、表格填完,最优解即是V(number,capacity)=V(4,8)=10。
五、代码实现 为了和之前的动态规划图可以进行对比,尽管只有4个商品,但是我们创建的数组元素由5个。
#include<iostream> using namespace std; #include <algorithm> int main() { int w[5] = { 0 , 2 , 3 , 4 , 5 }; //商品的体积2、3、4、5 int v[5] = { 0 , 3 , 4 , 5 , 6 }; //商品的价值3、4、5、6 int bagV = 8; //背包大小 int dp[5][9] = { { 0 } }; //动态规划表 for (int i = 1; i <= 4; i++) { for (int j = 1; j <= bagV; j++) { if (j < w[i]) dp[i][j] = dp[i - 1][j]; else dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - w[i]] + v[i]); } } //动态规划表的输出 for (int i = 0; i < 5; i++) { for (int j = 0; j < 9; j++) { cout << dp[i][j] << ' '; } cout << endl; } return 0; } 六、背包问题最优解回溯 通过上面的方法可以求出背包问题的最优解,但还不知道这个最优解由哪些商品组成,故要根据最优解回溯找出解的组成,根据填表的原理可以有如下的寻解方式:
报错信息为:
解决方案:
此问题为时区问题,在 JDBC 的连接 url 部分加上 serverTimezone=UTC 即可。
bsdiff的基本原理 bsdiff是由Conlin Percival开源的一个优秀的差分算法,而且是跨平台的。在Android系统中所使用的imgdiff本质上就是bsdiff。
bsdiff的依据
在传统更新中,包含了复制和插入两种操作,复制指的是找到old文件中所匹配的部分,将其复制到新文件中。插入指的是将old文件中所没有的数据插入到新文件中。这种方式在二进制文件更新中并不适用,因为对源代码进行少量的修改就会导致二进制文件产生较大的差异,从而复制和插入指令增多,生成的更新包远大于理想状态。所以bsdiff并没有这样做,在一个新的二进制文件,往往会包含这样几部分:不受更新代码影响的部分,更新代码后直接影响的部分,更新代码后间接影响的部分。
不受更新代码影响的部分:这一区域变化非常稀疏,即使有变化也是部分指针或寄存器的地址进行了一两个字节的变动,这就导致字节差异几乎为0
更新代码后间接影响的部分:在更新了源代码后,有些代码和数据的地址会发生偏移,而且偏移值相同。
也就是说,在新旧两个文件中,源代码块相同的部分,字节差异为0或一个固定值,这个固定值就是地址变化的偏移量。由于这一特性,导致产生的数据将会是高度可压缩的。在bsdiff算法中会找到这两部分,求出字节差异,作为diff string并进行压缩保存。
如图在old中添加代码块1(和代码块A不相关),在二进制文件中会导致代码块A的地址发生偏移,偏移值是相同的,这样old中的代码块A和new中的代码块A求字节差异时就会为一个固定值,具有高度可压缩性。
更新代码后直接影响的部分:如上图,当添加了代码块1后,会导致二进制文件产生新的数据,这部分数据在old中并不存在,bsdiff算法会将其作为extra string进行压缩保存。所以到这里我们能够得出bsdiff的更新数据=diff string+extra string。
bsdiff更新数据的基本结构 bsdiff更新数据由四部分组成:Header,ctrl block,diff block,extra block。
Header的结构: start/byteslength/bytescontent08"BSDIFF40"88the length of ctrl block168the length of diff block248新文件的大小 ctrl block:这部分内容是由(x,y,z)组成。x代表从old中读取x字节和diff block中读取x字节做字节加运算,y代表从extra block中读取y字节数据并且插入到新文件中,z代表在old中向前移动z字节。
diff block:记录了diff string,也就是字节的差值
extra block:记录了new文件中新生成的字节值
算法基本分析 bsdiff主要可以分为三部分:
1.通过排序技术对old文件的内容进行排序,形成字典序。这里的排序使用的是后缀排序时间复杂度nlogn,空间复杂度O(n),当然也可以使用hash技术进行排序。
2.通过二分法查找最长的匹配len,有了这个len,就可以计算出diff string,和extra string.
3.将diff string+extra string压缩到更新文件中。
关于后缀排序和二分法查找可以自行百度或google。下面边阅读代码边进行分析
1
2
3
4
5
off_t *I; off_t scan,pos,len;
off_t lastscan,lastpos,lastoffset; off_t oldscore,scsc;
off_t s,Sf,lenf,Sb,lenb;
上面有几个变量代表的意义,对分析算法有着很重要的意义。I代表已经排好的字典序,scan代表new中要查询的字符,pos代表old中相匹配的字符,len代表匹配的长度,lastscan=scan-lenb,lastpos=pos-lenb。lastoffset=scan-pos。lastoffset为new和old的偏移量,如果在old中的内容A在new中可以找到,而且A+lastoffset=new中的A,则认为old和new中的A相同。oldscore代表相同内容的len,scsc代表new中开始和old中比较是否相同开始的位置,而old中开始的位置是scsc+lastoffset。lenf代表扩展前缀,lenb代表扩展后缀。
1 while(scan<newsize) { 2 oldscore=0; 3 4 for(scsc=scan+=len;scan<newsize;scan++) { 5 len=search(I,old,oldsize,new+scan,newsize-scan, 6 0,oldsize,&pos); 7 printf("
代码段一:
""" Author: yeahthon Date : 2019-08-09 12:28:47 E-mail: yeahthon@163.com """ class AnonymousSurvey(): """收集匿名调查问卷的答案""" def __init__(self, question): """储存一个问题,并为储存答案做准备""" self.question = question self.responses = [] def show_question(self): """显示调查问卷""" print(question) def store_response(self,new_response): """储存单份调查问卷""" self.responses.append(new_response) def show_results(self): """显示收集到的所有答案""" print("Survey result:") for response in responses: print('- ' + response) 代码段二:
""" Author: yeahthon Date : 2019-08-09 12:50:20 E-mail: yeahthon@163.com """ from survey import AnonymousSurvey #定义一个问题,并创建一个表示调查的AnonymousSurvey对象 question = "what language did you first learn to speak?
输入一个字符,按一次回车
#include<stdio.h>
void main()
{
int i;
char ch;
for( i=0;i<10;i++ ){
printf("input %d : ", i+1);
scanf("%c%*c", &ch ); //用%*c吸收掉回车符。不然,下一次读字符,就会读到这个回车符。
printf("%c:%d\n", ch, ch ); //输出字符和ASCII值 %c表示输出按字符,%d表示输出按ascii值。
}
}
连续输入字符,直到回车结束(这时,不需要加过滤操作)
#include<stdio.h>
void main()
{
int i;
char ch;
for( i=0;i<10;i++ ){
scanf("%c", &ch ); //或用ch=getchar();
if ( ch=='\n')
break; //遇回车结束输入
printf("%c:%d\n", ch, ch ); //输出字符和ASCII值
}
}
用户在键盘输入时,所有的按键不会直接反应到程序变量中,而是先存储到输入缓存区中,程序在读取数据时,是从输入缓存中读取。所有的按键都会映射成相应的字符,如:回车、空格等都是有效的字符,所以,在读字符时,程序不会自动忽略它们,如果需要忽略,需要进行程序代码控制。
system.cpu.util[<cpu>,<type>,<mode>] # cpu 具体编号就是CPU的具体核心,为空就代表CPU所有核心 # type 就是CPU的不同状态值 idle, nice, user (default), system (default for Windows), iowait, interrupt, softirq, steal,其中idle表示空闲,user表示用户使用 # mode avg1 表示平均1分钟的值,avg5,avg15 同理,为空表示当前时间 # example system.cpu.util[,user,avg1] 下面的监控项为系统自带,如下图 system.cpu.util[,idle] 监控项键值 system.cpu.util[,idle] 监控cpu的空闲时间,单位%
只需要创建触发器就行了
{192.168.1.72:system.cpu.util[,idle].avg(1m)}<10 cpu空闲时间小于10%,也就是使用率大于90%
avg(1m):1分钟平均值
目录 1. 总概述2. 各部分2.1 main.js2.2 App.vue 3.总目录 1. 总概述 index.html+App.vue+main.js简介:
#名称作用1index.html挂载页面div id = “app” 挂载点2App.vue主组件所有页面都在App.vue下进行切换3main.js入口文件初始化vue实例,并引入所需要的插件 运行顺序:
index.htmlApp.vue的export外的js代码main.jsApp.vue的export里面的js代码 (如果有) 2. 各部分 2.1 main.js main.js是我们的入口文件,主要作用是初始化vue实例,并引入所需要的插件
2.2 App.vue App.vue是我们的主组件,所有页面都是在App.vue下进行切换的。其实你也可以理解为所有的路由也是App.vue的子组件。所以我将router标示为App.vue的子组件。
3.总目录 vue项目各目录名称及作用:
1、昨天能正常运行的代码,今天早上打开报了这个错误:
度娘了一通,发现这个相关的不是很多,但是可以肯定是编码的问题。
最后,解决了。
就是在每一个open指定编码格式为utf-8,再执行,程序完美运行了。
我是分割线我是分割线我是分割线我是分割线我是分割线
2、真正的原因
代码调试通之后,打开语料集发现昨天正常的中文语料,今天打开乱 码 了。各种操作不行,最后发现是系统问题:非Unicode程序语言被切换成英文了
解决方法:
https://jingyan.baidu.com/article/54b6b9c0a0c4d72d583b470b.html
这是win10,win7也是一样的。
修改后,重启,再打开发现已正常显示中文。
既然是系统问题,那是不是那份代码文件本来是没问题的?
把刚才加的encoding='utf-8’删除掉,再运行,果然是正常的。
综上,我程序报错的真正原因是系统语言切换的问题。
简单说明 直接放代码不友好,说句话缓冲一下....这里的模板复制不会直接红一片(体验会好一些),哦,对了,使用函数C(n,m)之前,需要先用init()预处理一下,不然C(n,m)的结果就是0了。
代码区 typedef long long ll; const ll mod = 1e9 + 7; const int Max = 1e6 + 10; ll fact[Max], ifact[Max]; //fact[i]是i的阶乘,ifact[i]是阶乘的除法逆元,两者用于求组合数 ll pow_mod(ll n, ll k) { ll res = 1; n = n % mod; while (k > 0) { if (k & 1) res = res * n % mod; n = n * n % mod; k >>= 1; } return res; } void init() //初始化 { fact[0] = ifact[0] = 1; for (int i = 1;i < Max; i++) { fact[i] = (fact[i - 1] * i) % mod; ifact[i] = pow_mod(fact[i], mod - 2); } } ll C(ll n, ll m) { if (n < m || m < 0) return 0; //不合法 return (fact[n] * ifact[m] % mod) * ifact[n - m] % mod; }
最近遇见了一个很搞得事情,在tomcat下启动项目时自己写的定时程序被执行了两次,导致程序启动了两个线程,使定时任务在几秒间隔内执行了两次,后来通过日志查到,原来是tomcat将项目启动了两次,为什么呢?我的问题原因是由于tomcat下配置的问题;为了让程序可以通过域名直接访问,而不用输入项目名,所有要对tomcat配置项目的映射,由于客户那里配置的有问题所有导致程序启动两次。
错误配置:
<Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true" xmlValidation="false" xmlNamespaceAware="false"> <Context docBase="/usr/local/apache-tomcat-6.0.29/webapps/XXX" path="" reloadable="true"></Context> <Context docBase="/usr/local/apache-tomcat-6.0.29/webapps/XXX" path="/admin" reloadable="true"></Context> </Host>
以上配置,由于host节点配置了appBase为webapps,所有tomcat会加载webapps里的所有项目,下面又配置了webapps里的项目,导致项目又加载一次,所以会导致项目重复加载,定时程序会在几秒之内重复执行,后来改了一下配置好了,
如下正确配置:
<Host name="localhost" appBase="" unpackWARs="true" autoDeploy="true" xmlValidation="false" xmlNamespaceAware="false"> <Context docBase="/usr/local/apache-tomcat-6.0.29/webapps/XXX" path="" reloadable="true"></Context> <Context docBase="/usr/local/apache-tomcat-6.0.29/webapps/XXX" path="/admin" reloadable="true"></Context> </Host>
--------------------- 版权声明:本文为CSDN博主「小鹏求知」的原创文章,遵循CC 4.0 by-sa版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/u011081244/article/details/62422013
### 初始安装
```
# 下载插件
pip install jupyter # -i https://pypi.tuna.tsinghua.edu.cn/simple/ --trusted-host pypi.douban.com
# 添加环境变量
export PATH="$PATH:/opt/Python-3.6.9/bin"
# 生成配置
jupyter notebook --generate-config
# 修改配置ip为机器的地址
vim /root/.jupyter/jupyter_notebook_config.py
c.NotebookApp.ip = 'localhost'
# 启动
jupyter notebook --allow-root &
```
- 打开网页
http://localhost:8888/?token=88862887dbcf7b780110da7aefbc5ac5a36a17d6a7430eb8
### 安装插件
```
pip install jupyter_contrib_nbextensions
jupyter contrib nbextension install --user
pip install jupyter_nbextensions_configurator
jupyter nbextensions_configurator enable --user
```
重启jupyter, 进入主页标签页`Nbextensions`,
- 勾选`hinterland` 启用代码自动补全
- 勾选`Select CodeMirror Keymap` 启用键盘,可选vim
### 安装主题
二、日志系统
1.经常听 DBA 同事说,MySQL 可以恢复到半个月内任意一秒的状态。
2.更新流程还涉及两个重要的日志模块,它们正是我们今天要讨论的主角:redo log(重做日志)和 binlog(归档日志)。
3.【我。WAL 技术,粉板与账本的配合,高效灵活。给个满的判断、或时点触发,正式更新到硬盘。mysql优化,偏应用级的优化。linux优化,偏系统级的优化。】
有了 redo log,InnoDB 就可以保证即使数据库发生异常重启,之前提交的记录都不会丢失,这个能力称为crash-safe。
4.MySQL 整体来看,其实就有两块:一块是 Server 层,它主要做的是 MySQL 功能层面的事情;还有一块是引擎层,负责存储相关的具体事宜。上面我们聊到的粉板 redo log 是 InnoDB 引擎特有的日志,而 Server 层也有自己的日志,称为 binlog(归档日志)。
【我。更新不写到硬盘;不影响新的查询吗?】
5. redo log 的写入拆成了两个步骤:prepare 和 commit,这就是”两阶段提交”。【我。中间插入一步—-写binlog;】
三、事务隔离
1. MySQL 的事务隔离级别的现象和实现,根据实现原理分析了长事务存在的风险,以及如何用正确的方式避免长事务。
2.如果你是业务开发负责人同时也是数据库负责人,你会有什么方案来避免出现或者处理这种情况呢?
3.一天一备跟一周一备的对比。好处是“最长恢复时间”更短。
4.事务。 在一个事务时间内,容易发生冲突或错乱时,就要引入事务、来控制。
事务就是要保证一组数据库操作,要么全部成功,要么全部失败。在 MySQL 中,事务支持是在引擎层实现的。你现在知道,MySQL 是一个支持多引擎的系统,但并不是所有的引擎都支持事务。比如 MySQL 原生的 MyISAM 引擎就不支持事务,这也是 MyISAM 被 InnoDB 取代的重要原因之一。
5. ACID(Atomicity、Consistency、Isolation、Durability,即原子性、一致性、隔离性、持久性),今天我们就来说说其中 I,也就是“隔离性”。
当数据库上有多个事务同时执行的时候,就可能出现脏读(dirty read)、不可重复读(non-repeatable read)、幻读(phantom read)的问题,为了解决这些问题,就有了“隔离级别”的概念。
在谈隔离级别之前,你首先要知道,你隔离得越严实,效率就会越低。因此很多时候,我们都要在二者之间寻找一个平衡点。SQL 标准的事务隔离级别包括:读未提交(read uncommitted)、读提交(read committed)、可重复读(repeatable read)和串行化(serializable )。这4种隔离级别,并行性能依次降低,安全性依次提高。
出自:http://www.good5.top/2019/08/05/%E3%80%8Amysql%E5%AE%9E%E6%88%98%E3%80%8B%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B01/
搭建网站的不同方式:
一、1台服务器,1个IP地址,1个网站(访问量大的网站)
1、安装软件包前配置yum源:[root@localhost ~]# vim /etc/yum.repos.d/base.repo
2、挂载光盘镜像:[root@localhost ~]# mount /dev/sr0 /mnt
3、安装软件包:[root@localhost ~]# yum install httpd –y(软件名称:Apache,后台服务名称:httpd,协议名称:http和https)
4、启动服务:[root@localhost ~]# systemctl start httpd
5、关闭防火墙和seLinux:
[root@localhost ~]# systemctl stop firewalld
[root@localhost ~]# setenforce 0
6、在默认存放网页的位置编辑一个界面:[root@localhost ~]# vim /var/www/html/index.html
7、重启httpd服务通过访问网站进行测试:[root@localhost ~]# systemctl restart httpd
8、切换到apache配置文件存放的目录下:[root@localhost ~]# cd /etc/httpd/conf
9、在编辑配置文件之前可以先进行备份:
10、如果改变默认存放网页的位置,同样也是可以访问界面的,如下操作:
1)在根下创建目录:[root@localhost~]# mkdir -p /www/html
2)编辑配置文件修改信息:[root@localhost ~]# vim /etc/httpd/conf/httpd.conf
3)再刚创建的路径下编辑一个界面:[root@localhost ~]# vim /www/html/index.html
4)重启服务:[root@localhost ~]# systemctl restart httpd
5)再次访问网页:
注意:我们开始是把selinux关闭的,所以修改路径访问没有问题。但如果selinux开启,那么这时访问到的是Apache的欢迎界面,修改selinux的安全值后才可以正常访问。
二、1台服务器,1个IP地址,2个网站,使用不同的主机名,比如www.163.com和tech.163.com 可以是一台服务器上的两个网站,都用的80端口。也就是基于名称的虚拟主机。
1、IPV4的公网IP很珍贵的,如果一个网站一个IP,那么就会浪费掉很多IP,如果使用域名就不会有这种浪费,首先安装所需要软件包:
题目链接 POJ-1459 Power Network
题目分析 题意:
简单来说,由多个源点向多个汇点传输数据,每个源点传出的数据是有限的,每个汇点接受的数据也是有限的,某些点之间可以传输一定量的数据,求最大流。
思路:
相比于普通的最大流问题,这个地方的源点和汇点不唯一,而且源点的最大流出容量也有所限制,其实我们只要简单处理了一下,就可以将这类问题转化为普通的最大流问题。
我们在图中新增一个超级源点s和一个超级汇点t,由超级源点s向每个源点连一条容量为对应最大流出容量的边,再从每个汇点向超级汇点t连一条容量为对应最大流入容量的边,这样处理之后,问题就转化为了求超级源点到超级汇点之间的最大流了
代码区 #include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<queue> #include<string> #include<fstream> #include<vector> #include<stack> #include <map> #include <iomanip> #define bug cout << "**********" << endl #define show(x,y) cout<<"["<<x<<","<<y<<"] " //#define LOCAL = 1; using namespace std; typedef long long ll; const int inf = 0x3f3f3f3f; const ll mod = 1e6 + 3; const int Max = 1e4 + 10; struct Edge { int to, next; int flow; }edge[Max << 2]; int n, out, in, m; int head[110], tot; int dis[110]; //表示顶点到源点的距离标号 void init() { memset(head, -1, sizeof(head));tot = 0; } void add(int u, int v, int flow) { edge[tot].
Linux下普通用户和超级用户的切换
普通用户显示符号位$
超级用户显示符号位#
一般进入时可以输入账号密码进入普通用户与超级用户
普通用户进入超级用户:
输入su,回车,再输入登陆密码
超级用户切换到普通用户:
su mwf (mwf是我的普通用户名)
1. linux初级指令 1.1系统管理相关命令 登录基本信息
当前登录用户名:
#管理员用户指示符
$普通用户提示符hostname:查看主机名who:查询登录到系统的用户whoami:确定自己的身份history:查看当前用户运行命令的历史ifconfig:显示或设置网络设备的指令 ,我们可以用这个命令查看自己服务器的ip地址ping:ping是Windows,Unix和linux系统下的一个命令。ping也属于一个通信协议,是tcp/ip协议的一部分。利用ping命令可以检查网络是否连通(ctrl+c 退出) 1.2目录操作命令 pwd 命令 显示当前路径cd 命令 切换目录
用法:cd 目录路径
cd ./ 当前路径
cd …切换到上级目录
cd / 切换到根目录
cd ~ 切换到当前用户主目录(home底下以用户名命名的文件夹)/root目录
cd /opt 切换到opt目录mkdir 创建目录
mkdir 目录名 -p 递归创建目录
注意:
mkdir只能创建一个文件夹,不能创建文件
创建多层文件夹:mkdir -p lenmon/lenmon62rmdir 删除空目录
用法:
rmdir 目录名
rm -rf 目录名/文件名 2. linux中级指令 文件操作命令 touch 新建文件 用法:touch xxx.txt
vi 是linux下常用的,功能强大的文本编辑器
按键盘i进入编辑状态
退出编辑按esc
不保存退出 :q! 强制退出
保存退出: :wq
进入文件的时候:
– 输入/ : 搜索
1. 模拟图像 : 空间坐标和明暗程度连续变化 , 计算机无法直接处理的图像 , 又称光学图像 。
2. 数字图像 :指用计算机存储和处理的图像,是一种空间坐标和灰度均不连续的、用离散数学表示的图像。数字图像的最小单元是像素 。
3. 遥感数字图像 (digital image) : 是以数字形式表述的遥感图像。不同的地物能够反射或辐射不同波长的电磁波,利用这种特性,遥感系统可以产生不同的遥感数字图像。
4. 电磁波谱: 按电磁波在真空中传播的波长或频率,递增或递减排列,则构成电磁波谱 。
5. 反射波谱:地物反射电磁辐射的能力,随所反射的电磁波波长变化而变化。如以横坐标表示波长的变化,纵坐标表示其反射率(或反射亮度系数)可构成反映 反射光谱特性 的曲线,称为反射光谱曲线 。
6. 高光谱图像:是指利用很多很窄的电磁波波段从感兴趣的物体中获取有关数据得到的遥感图像,波段多,波段范围一般 <10nm 。
7. 高空间分辨率图像:空间分辨率 < 10m 遥感图像 。
8. 遥感影像地图 :以航空和航天遥感影像为基础,经几何纠正 ,配合数字线划图和 少量注记,将制图对象综合表示在图面上的地图。遥感影像地图具有一定的数学基础,有丰富的光谱信息与几何信息,又有行政界限和属性信息,直接提高了可视化效果 。
9. 遥感图像模型 :传感器探测地物电磁波辐射能量所得到的遥感图像从理论角度归纳出的一个具有普遍意义的模型。
10. 多源信息融合 :将多种遥感平台、多时相、遥感数据之间以及遥感与非遥感数据之间的信息组合匹配的技术,复合后将更有利于综合分析,一般包括匹配和复合两个步骤 。
11. 像素 :数字图像最基本的单位是像素,像素是 A/D 转换中的取样点,是计算机图像处理的最小单元;每个像素具有特定的空间位置和属性特征。像素值称为亮度值 ( 灰度值 /DN 值 ) 。亮度值的高低由传感器所探测到的地物辐射强度决定 。由于地物反射或辐射电磁波的性质不同且受大气影响不同,相同地点不同图像(不同波段、时期、种类)的亮度值可能不同,因此灰度值是相对的,仅能在图像内部相互比较。只有来源于同一物理过程或经标准化处理后才能将两景图像灰度值进行比较 。
12. 遥感图像解译:从遥感图像上获取目标地物信息的过程称为遥感图像解译,分为目视解译(直接观察或借助辅助判读仪器:颜色、形状、位置)和计算机解译(模式识别和人工智能) 。
13. 遥感数字图像处理 :是通过计算机图像处理系统对遥感图像中的像素进行的系列操作过程。
PostgreSQL安装(Mac) 文章目录 PostgreSQL安装(Mac)1. 简介2.参考文献3.开始安装4.数据库配置的初始化和修改5. 登录数据库6. 初始化数据库7. 常用控制台命令 好记性不如烂笔头啊,还是记录一下! 最近自己做的独立游戏需要对数据库选型,主要有两个选择:
1. MySQL号称最流行的数据库
2. PostgreSQL号称最先进的数据库
最后经过一番考量,最后选择了PostgreSQL,本篇博客主要记录的安装过程,可供同学们参考。
本篇博客介绍的是Mac下的安装过程
1. 简介 1.PostgreSQL: 是以加州大学伯克利分校计算机系开发的 POSTGRES,现在已经更名为PostgreSQL,版本 4.2为基础的对象关系型数据库管理系统(ORDBMS)。PostgreSQL支持大部分 SQL标准并且提供了许多其他现代特性:复杂查询、外键、触发器、视图、事务完整性、MVCC。同样,PostgreSQL 可以用许多方法扩展,比如, 通过增加新的数据类型、函数、操作符、聚集函数、索引。免费使用、修改、和分发 PostgreSQL,不管是私用、商用、还是学术研究使用。
2.参考文献 老习惯,列出本文参考和引用的文档和博客,致以崇高的敬意,感兴趣的可以去看看
http://postgresapp.com/http://postgresapp.com/documentation/cli-tools.htmlhttp://www.yiibai.com/postgresql/2013080439.html 3.开始安装 安装很简单,我是直接用brew安装的:
brew install postgresql 等待运行完后,就安装在了usr/local/Cellar/postgresql/目录下
# 配置一下环境变量: echo -e 'export POSTGRESQL_HOME='${POSTGRESQL_INSTALL_PATH}'\nexport PATH=${POSTGRESQL_HOME}/bin:$PATH\nexport PGDATA='${POSTGRESQL_INSTALL_PATH}'/data\n'>> /etc/profile source /etc/profile POSTGRESQL_INSTALL_PATH为你的安装路径
4.数据库配置的初始化和修改 初始化数据库配置:
pg_ctl -D ${POSTGRESQL_DATABASE_PATH} initdb POSTGRESQL_DATABASE_PATH是我自动化安装脚本中的变量,可以改为你任何想初始化到的路径下,我用的是POSTGRESQL_DATABASE_PATH='/usr/local/data/postgres'
然后进入初始化后的目录:
cd ${POSTGRESQL_DATABASE_PATH} 可以在这个目录下看到很多文件,需要修改的是pg_hba.conf和postgresql.conf
pg_hba.conf中主要是一些权限配置,就是配置了哪些IP用什么方式可以登录到数据库postgresql.conf主要就是一些数据库的细节配置。 pg_hba.conf我做了如下修改:
# 修改监听地址 sed -i "s/#listen_addresses = 'localhost'/listen_addresses = '*'/g" postgresql.conf # 修改监听端口 sed -i 's/#port = 5432/port = 5432/g' postgresql.
Windows API 中有两个函数可以用来创建画刷。
CreateSolidBrush 函数可以用来创建一个指定颜色的实心画刷,原型为:
HBRUSH CreateSolidBrush( COLORREF crColor ); // crColor为画刷颜色
1
CreateHatchBrush 函数可以用来创建一个指定颜色的含有特定阴影样式的画刷,原型为:
HBRUSH CreateHatchBrush(http://www.amjmh.com)
int fnStyle, //画刷样式
COLORREF crColor //画刷颜色
);
1
2
3
4
fnStyle 可以有6种取值:
- HS_BDIGONAL:45度向上,自左至右的阴影(///)
- HS_CROSS:表示水平直线和垂直直线交叉阴影(+++)
- HS_DIAGCROSS:45度交叉阴影(XXX)
- HS_FDIAGONAL:45度向下自左至右的阴影(\\\)
- HS_HORIZONTAL:水平阴影(---) - HS_VERTICAL:垂直阴影
--------------------- 转载于:https://www.cnblogs.com/ly570/p/11304705.html
根据取证工具的功能,取证工具分为三大类 : 第一类是实时响应工具 , 第二类是取证复制工具 , 第三类是取证分析工具。
根据取证工具的用途, 取证工具分为三大类:第一类是磁盘文件取证复制工具, 第二类是内存文件取证工具,第三类是取证分析工具。
1 磁盘取证 在计算机的取证领域中,取证人员在取证调查的整个过程中证明证据媒体没有在任何方面被篡改是至关重要的。其中一种方法是对原始的证据媒体作一个映象复制,并对映象复制品展开调查,以防止对原始证据的任何更改。
1.1 镜像工具 dd dd if=/dev/xvdb of=cyqdrive.dd bs=1024 count=1G 参数解释:
if=文件名(源文件) of=文件名(输出文件) bs=bytes(同时设置读入/输出的块大小为bytes个字节) count=blocks(总大小)
详细用法:https://www.cnblogs.com/jikexianfeng/p/6103500.html
1.2 与netcat的结合 dd 为我们生成磁盘的位镜像文件,而 netcat 将拷贝通过网络传输到远程主机。
(1)首先在远程主机上,启动 netcat 作为一个监听,用 netcat 监听 TCP 的 3452 端口,并将镜像写入文件 myimage.dd。
nc -l -p 3452 > myimage.dd
-l 监听模式,用于入站连接
-p 监听端口(本地端口号)
(2)然后你可以对服务器进行镜像拷贝:
dd if=/dev/xvdb of=cyqdrive.dd bs=1024 count=1G | nc 192.168.1.1 3452
1.3 FTK Imager for Linux 使用 FTK Imager 工具用户可以创建原始证据媒体的取证映象,如本地硬盘、闪盘、软盘、Zip 驱动器、CD、DVD 等。
目标要求:
1、 界面border去掉原本windows自带的对话框格式,采取扁平化设计;
2、 简化安装流程,不要弹出那么多安装向导页,不要让用户一直点“下一步”,简洁人性化;
3、 安装界面可加载漂亮的背景图片;
4、 优化安装包安装时间。
原型设计:
界面1
界面2
界面3
开发工具:
因为之前采用Inno setup设计,而且它拥有Pascal脚本引擎,功能算强大,故采用Inno setup。
主要流程:
流程图
由图中可以清晰地看出,所有向导页之间都是通过“下一步”或者“上一步”进行驱动更换的。
概要分析:
这里需要调用两个美化插件动态库:botva2.dll和InnoCallback.dll,用于界面的美化和功能完善。这里就不全部把代码贴出来了,只针对其中的要点进行分析概括。
在开始之前,先了解一下inno setup基本的过程和函数。
//该过程在开始的时候改变向导或者向导页,不要指望使用InitializeSetup函数实现改变向导页的功能,因为InitializeSetup函数触发时向导窗口并不存在。 procedure InitializeWizard(); //该函数在安装程序初始化时调用,返回False 将中断安装,True则继续安装. function InitializeSetup(): Boolean; //该过程提供用户完成预安装和安装之后的任务,更多的是提供了安装过程中的状态。参数CurStep=ssInstall是在程序实际安装前,CurStep=ssPostInstall是实际安装完成后,而CurStep=ssDone是在一次成功的安装完成后、安装程序终止前(即点击finish按钮后执行)。 procedure CurStepChanged(CurStep: TSetupStep); //当用户单击下一步按钮时调用。如果返回True,向导将移到下一页;如果返回False,它仍保留在当前页。 function NextButtonClick(CurPageID: Integer): Boolean; //向导调用这个事件函数确定是否在所有页或不在一个特殊页 (用PageID 指定) 显示。如果返回True,将跳过该页;如果你返回False,该页被显示。注意: 这个事件函数不被wpWelcome、wpPreparing 和wpInstalling 页调用,还有安装程序已经确定要跳过的页也不会调用 (例如,没有包含组件安装程序的wpSelectComponents)。 function ShouldSkipPage(PageID: Integer): Boolean; //在新向导页 (由CurPageID 指定) 显示后调用。 procedure CurPageChanged(CurPageID: Integer); 1、 界面border去掉原本windows自带的对话框格式,采取扁平化设计
//设置欢迎向导页的尺寸大小: WizardForm.Center WizardForm.BorderStyle:=bsNone; //去掉对话框border WizardForm.ClientWidth:=601; WizardForm.ClientHeight:= 341; WizardForm.
【洛谷】P1192 台阶问题 题解 原题地址:https://www.luogu.org/problem/P1192
题目描述
有N级的台阶,你一开始在底部,每次可以向上迈最多K级台阶(最少1级),问到达第N级台阶有多少种不同方式。
输入输出格式
输入格式:
两个正整数N,K。
输出格式:
一个正整数,为不同方式数,由于答案可能很大,你需要输出ans mod 100003后的结果。
输入输出样例
输入样例#1:
5 2
输出样例#1:
8
说明
时空限制: 1000ms/128MB
对于20%的数据,有N ≤ 10, K ≤ 3
对于40%的数据,有N ≤ 1000
对于100%的数据,有N ≤ 100000,K ≤ 100
思路:
1、之前做过k==2的台阶问题,状态转移方程是f[i]=f[i-1]+f[i-2],这题规律也一样。
2、第0阶台阶就有1种方法可到达,第n阶的走法就是从n-k阶到n-1阶的走法之和。
3、注意每次求出来的数都要求模,否则数据有可能太大导致数组溢出。
代码如下:
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> using namespace std; int f[1000010]={0}; //数组初始化为0 int main() { int n,k; scanf("%d%d",&n,&k); f[0]=1; //初始条件 for(int i=1;i<=n;i++) //进行遍历递推 { for(int j=1;j<=k&&i-j>=0;j++) //阶数最少1到最大k阶依次累加 f[i]+=f[i-j]; f[i]%=100003; //求模,防止溢出 } printf("
WX开放平台申请网站应用,获得APPID和SECRET,第三方应用接入WX登录
APPID:xxxxxxxxxxxxxx
SECRET:yyyyyyyyyyyyyyy
第一步:调用微信登录接口,用户扫码登录,生成code
https://open.weixin.qq.com/connect/qrconnect?appid=xxxxxxxxxxxxxx&redirect_uri=https%3A%2F%2Fp7yrpa.natappfree.cc&response_type=code&scope=snsapi_login&state=200
结果: http://79n8s3.natappfree.cc/?code=0610Xey313BXSQ15G6v31H6wy310Xeyv&state=200 第二步:请求以下路径通过code获取access_token 参数:appid=APPID,secret=SECRET,code=填写上一步生成的code,grant_type=“authorization_code”,生成access_token
https://api.weixin.qq.com/sns/oauth2/access_token
https://api.weixin.qq.com/sns/oauth2/access_token?appid=xxxxxxxxxxxxxx&secret=yyyyyyyyyyyyyyy&code=061OWZMX1Rl7LZ0qICMX1I9CMX1OWZMK&grant_type=authorization_code
https://api.weixin.qq.com/sns/oauth2/access_token?appid=xxxxxxxxxxxxxx&secret=SECRETyyyyyyyyyyyyyyy&code=0610Xey313BXSQ15G6v31H6wy310Xeyv&grant_type=authorization_code
结果: { "access_token":"ACCESS_TOKEN", 接口调用凭证 "expires_in":7200, access_token接口调用凭证超时时间,单位(秒) "refresh_token":"REFRESH_TOKEN", 用户刷新access_token "openid":"OPENID", 授权用户唯一标识 "scope":"SCOPE", 用户授权的作用域,使用逗号(,)分隔 "unionid": "o6_bmasdasdsad6_2sgVt7hMZOPfL" 当且仅当该网站应用已获得该用户的userinfo授权时,才会出现该字段。 } 第三步:请求以下链接进行refresh_token 参数:appid=APPID,grant_type=‘refresh_token’,refresh_token=填写上一步获取到的refresh_token参数
https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=APPID&grant_type=refresh_token&refresh_token=23_ivXL7QsljTjYUJaifpGajw6DaWu3N-2A5-GewcFpSEK_xZ_CSBGBJ35HpXS-qa4GwbsvrEHbibwJWma3OKpYr73m3ZnAi25_V3pezwRSO10
https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=APPID&grant_type=refresh_token&refresh_token=REFRESH_TOKEN
结果: { "access_token":"ACCESS_TOKEN", 接口调用凭证 "expires_in":7200, access_token接口调用凭证超时时间,单位(秒) "refresh_token":"REFRESH_TOKEN", 用户刷新access_token "openid":"OPENID", 授权用户唯一标识 "scope":"SCOPE" 用户授权的作用域,使用逗号(,)分隔 } 第四步:请求以下连接查询用户基本信息 参数:access_token=填写上一步获取的access_token,openid=填写上一步获取的openid
https://api.weixin.qq.com/sns/userinfo
结果: {"openid":"ooooooooooooo", "nickname":"朝", "sex":1, "language":"zh_CN", "city":"Hangzhou", "province":"Zhejiang", "country":"CN", "headimgurl":"http:\/\/thirdwx.qlogo.cn\/mmopen\/vi_32\/Q0j4TwGTfTIlicQP4zdmtiaDkLEus7e8GMHZXnnD2YqLWpgEPl5QGPAKe02x4nMwZricqBOzo8gF0mm3gLyL0zh2Q\/132", "privilege":[], "unionid":"oniwU5vxax7qU27Xdy3Cb-MYvYeE"}
QQ开放平台申请网站应用,获得APPID和APPKEY,第三方应用接入QQ登录
APPID:xxxxxxxxx
APPKey:yyyyyyyyyyyyyyyyyyy
第一步:请求一下路径获得code 参数:response_type=code , client_id=APPID,redirect_url=注册appid时填写的主域名下的地址,注意需要将url进行URLEncode。state=随机字符串
https://graph.qq.com/oauth2.0/authorize?response_type=code&client_id=xxxxxxxxx&redirect_uri=http%3A%2F%2Fwww.chicrodz.com%2Fqq%2Fafterauth.htm&state=201
第二步:请求一下地址获得access_token 参数:grant_type=authorization_code , client_id=APPID ,client_secret=APPKEY,code=上一步请求返回路径中的authorization code(有效期10分钟),redirect_uri=与上面一步中传入的redirect_uri保持一致。
https://graph.qq.com/oauth2.0/token?grant_type=authorization_code&client_id=xxxxxxxxx&client_secret=yyyyyyyyyyyyyyyyyyy&code=F9F34D8CB5AD4E483FDE73CB2909AA25&redirect_uri=https%3A%2F%2Fwww.chicroattire.com%2Fhome
第二步返回正确结果:
access_token=C22FD2C6694873C937700BF0771B99B1
&expires_in=7776000
&refresh_token=4961F7CFCEA168CEBFC2758DB7C275C0
第二步返回错误结果: callback( {"error":100019,"error_description":"code to access token error"} ); 第三步:获得openID 参数:access_token=在第二步返回的结果中
https://graph.qq.com/oauth2.0/me?access_token=C22FD2C6694873C937700BF0771B99B1
第三步返回结果: callback( {"client_id":"xxxxxxxxx","openid":"oooooooooooooooooooooooooooo"} ); 第四步: 获得用户基本信息 参数如下:
https://graph.qq.com/user/get_user_info?access_token="+accessToken+"&oauth_consumer_key="+appId+"&openid="+openId
https://graph.qq.com/user/get_user_info?access_token=C22FD2C6694873C937700BF0771B99B1&oauth_consumer_key=xxxxxxxxx&openid=oooooooooooooooooooooooooooo
第四步返回的结果: { “code”: 200,
“data”: {
“ret”: 0,
“msg”: “”,
“is_lost”: 0,
“binding_status”: true,
“gender”: “男”,
“is_yellow_vip”: “0”,
“city”: “拉特纳普勒”,
“year”: “1995”,
“level”: “0”,
“figureurl_2”: “http://qzapp.qlogo.cn/qzapp/xxxxxxxxx/oooooooooooooooooooooooooooo/100”,
“figureurl_1”: “http://qzapp.qlogo.cn/qzapp/xxxxxxxxx/oooooooooooooooooooooooooooo/50”,
“is_yellow_year_vip”: “0”,
直接自定义一个NoScrollViewPager 他直接继承ViewPager
public class NoScrollViewPager extends ViewPager { // 是否禁止 viewpager 左右滑动 private boolean noScroll = true; public NoScrollViewPager(Context context, AttributeSet attrs) { super(context, attrs); } @Override public boolean onTouchEvent(MotionEvent arg0) { if (noScroll){ return false; }else{ return super.onTouchEvent(arg0); } } @Override public boolean onInterceptTouchEvent(MotionEvent arg0) { if (noScroll){ return false; }else{ return super.onInterceptTouchEvent(arg0); } } } 用法就跟ViewPager一样 直接在xml里面使用就行了
打开注册表,找到HKEY_CLASSES_ROOT\Directory\Background路径,删除对应的快捷方式即可
转载于:https://www.cnblogs.com/oneweek/p/11299056.html
转自百度知道https://zhidao.baidu.com/question/295921974.html
采样频率的意思是单位时间的采样次数。要确定采样频率,应该根据被测模拟量的变化动态以及测量需求决定。
对于特定的硬件环境以及转换位数来说,转换时间是确定的,也就是说在确定的主频、分频系数以及转换分辨率下,硬件的转换时间是固定的,这个时间的具体值可以通过查阅AD转换芯片的数据手册获得。
总的来说,对于快速变化的被测量需要采用较高的采样频率,对于缓变量可以采用较低的采样频率以节约单片机的处理资源。但是无论如何采样频率不应该突破转换时间的限制!
更多追问追答
追问
如果我确定需要的采样频率为150k,ad最高采样频率200k。是否是通过定时器设置来促发采样频率为150k?即设置定时器每1/150k采样一次? 追答
不错,在定时器中断中启动采样这样可以的。 不过,一般所谓的AD最高采样频率是在连续转换的方式下,像你上面的流程是单次采样,通常单次采样的时间要大大长于连续转换的,也就是说实际上达不到200K。这点需要注意!此外你还要考虑采样数据的处理输出的时间,否则采样就没有意义了。
#第三个参数用于计算单应矩阵的方法。 可以使用以下方法: #0 - 使用所有点的常规方法 #CV_RANSAC - 基于RANSAC的鲁棒方法 #CV_LMEDS - 最少中位数的鲁棒方法 #第四个参数取值范围在1到10,绝一个点对的阈值。原图像的点经过变换后点与目标图像上对应点的误差 #超过误差就认为是异常值 #返回值中H为变换矩阵.mask是掩模,在线的点 H,mask = cv2.findHomography(src_pts,dst_pts,cv2.RANSAC,5.0) 我们之前使用了查询图像,找到其中的一些特征点,我们取另外一个训练图像,找到里面的特征,我们找到它们中间最匹配的。简单说就是我们在一组图像里找一个目标的某个部分的位置。
我们可以使用一个calib3d模块里的函数,cv2.findHomography().如果我们传了两个图像里的点集合,它会找到那个目标的透视转换。然后我们可以使用cv2.perspectiveTransform()来找目标,它需要至少4个正确的点来找变换。
我们看过可能会有一些匹配是的错误而影响结果。哟啊解决这个问题,算法使用了RANSAC或者LEAST_MEDIAN(由标志决定)。提供正确估计的好的匹配被叫做inliers,而其他的叫做outliers。cv2.findHomography()返回一个掩图来指定inlier和outlier。
code
首先,和正常一样,我们找到SIFT特征,用比率检测来找最匹配的。
import numpy as np
import cv2
from matplotlib import pyplot as plt
MIN_MATCH_COUNT = 10
img1 = cv2.imread('box.png',0) # queryImage
img2 = cv2.imread('box_in_scene.png',0) # trainImage
# Initiate SIFT detector
sift = cv2.SIFT()
# find the keypoints and descriptors with SIFT
kp1, des1 = sift.detectAndCompute(img1,None)
kp2, des2 = sift.
什么是NPOI? NPOI是指构建在POI 3.x版本之上的一个程序,NPOI可以在没有安装Office的情况下对Word或Excel文档进行读写操作。
NPOI是一个开源的C#读写Excel、WORD等微软OLE2组件文档的项目。
使用NuGet安装NPOI NuGet直接搜索NPOI,目前版本是v2.4.1,将其安装至项目即可。
安装完成后,项目会自动为我们添加这4个引用
同时还需要在程序中引入NPOI.SS.UserModel;NPOI.XSSF.UserModel;NPOI.HSSF.UserModel;三个命名空间
废话不多说,直接上代码 DataTable导出Excel /// <summary> /// Datable导出成Excel /// </summary> /// <param name="dt"></param> /// <param name="file">导出路径(包括文件名与扩展名)</param> public static void TableToExcel(DataTable dt, string file) { IWorkbook workbook; string fileExt = Path.GetExtension(file).ToLower(); if (fileExt == ".xlsx") { workbook = new XSSFWorkbook(); } else if (fileExt == ".xls") { workbook = new HSSFWorkbook(); } else { workbook = null; } if (workbook == null) { return; } ISheet sheet = string.
每篇一句 NBA里有两大笑话:一是科比没天赋,二是詹姆斯没技术
前言 上篇文章 介绍了Spring环境下实现优雅的方法级别的数据校验,并且埋下一个伏笔:它在Spring MVC(Controller层)里怎么应用呢?本文为此继续展开讲解Spring MVC中的数据校验~
可能小伙伴能立马想到:这不一样吗?我们使用Controller就是方法级别的,所以它就是直接应用了方法级别的校验而已嘛~对于此疑问我先不解答,而是顺势再抛出两个问题你自己应该就能想明白了:
上文有说过,基于方法级别的校验Spring默认是并未开启的,但是为什么你在Spring MVC却可以直接使用@Valid完成校验呢? 可能有的小伙伴说他用的是SpringBoot可能默认给开启了,其实不然。哪怕你用的传统Spring MVC你会发现也是直接可用的,不信你就试试 类比一下:Spring MVC的HandlerInterceptor是AOP思想的实现,但你有没有发现即使你没有启动@EnableAspectJAutoProxy的支持,它依旧好使~ 若你能想明白我提出的这两个问题,下文就非常不难理解了。当然即使你知道了这两个问题的答案,还是建议你读下去。毕竟:永远相信本文能给你带来意想不到的收获~
使用示例 关于数据校验这一块在Spring MVC中的使用案例,我相信但凡有点经验的Java程序员应该没有不会使用的,并且还不乏熟练的选手。在此之前我简单“采访”过,绝大多数程序员甚至一度认为Spring中的数据校验就是指的在Controller中使用@Validated校验入参JavaBean这一块~
因此下面这个例子,你应该一点都不陌生:
@Getter @Setter @ToString public class Person { @NotNull private String name; @NotNull @Positive private Integer age; @Valid // 让InnerChild的属性也参与校验 @NotNull private InnerChild child; @Getter @Setter @ToString public static class InnerChild { @NotNull private String name; @NotNull @Positive private Integer age; } } @RestController @RequestMapping public class HelloController { @PostMapping("/hello") public Object helloPost(@Valid @RequestBody Person person, BindingResult result) { System.
1 练习版: 1 进步版: 2 @control 3 *Group.java 4 package com.qsy.student.control; 5 import com.qsy.student.dao.StuDao; 6 import com.qsy.student.daoImpl.DaoImpl; 7 import com.qsy.student.entity.Role; 8 9 public class Group extends Role { 10 @Override 11 public void work() { 12 System.out.println("我是组长,负责组内的同学的学习及生活的任务"); 13 StuDao stuDao=new DaoImpl(); 14 stuDao.work2(); 15 } 16 } 17 *ManageWork.java 18 package com.qsy.student.control; 19 import com.qsy.student.entity.Role; 20 public class ManageWork { 21 22 //通过以下方法,能够查看到每种角色的工作任务 23 public void getWork(Role role){ 24 25 role.
最近做个小界面,之前有用过qchart虽然比qwt好用一点,但是bug还是有那么些,总体还行吧。当前想实现的功能就是讲数据以柱状图的形式实现,并且在柱状图的顶部显示每个柱状图的数据,同时提供Tooltip功能。那么就开始说说如何创建吧。
1、首先定义实现qchart对象
m_char=new QChart(); m_char->setAnimationOptions(QChart::SeriesAnimations);//动画显示 2、接下来,定义实现 QBarSeries对象,记住一定要在构造函数中加m_char,这个对象实际上理解为就是你X轴S1,1、3号线的集合,
m_series=new QBarSeries(m_char); 3、然后就是建立XY轴了,
m_typeAxis = new QBarCategoryAxis(); //m_typeAxis->append(categories); m_char->createDefaultAxes();//创建默认的左侧的坐标轴(根据 QBarSet 设置的值) m_char->setAcceptTouchEvents(true); m_char->setAxisX(m_typeAxis, m_series);//设置坐标轴 m_typeAxisY = new QValueAxis; m_typeAxisY->setRange(0, 40); // m_typeAxisY->setTickCount(10); //设置多少格 //m_typeAxisY->setMinorTickCount(5); //设置每格小刻度线的数目 m_char->setAxisY(m_typeAxisY, m_series); 4、生成 QChartView对象,将m_char加入其中;
m_mybarView=new QChartView(m_char); m_mybarView->setRenderHint(QPainter::Antialiasing); 5、将m_mybarView这个对象加入到你得布局当中即可。
m_barview=new MyBarView(bvp); ui->barChartView->addWidget(m_barview->m_mybarView); 6、如果你要tooltip功能,你需要使用这样的信号与槽,
connect(m_series, SIGNAL(hovered(bool, int, QBarSet*)), this, SLOT(sltTooltip(bool, int, QBarSet*))); void MyBarView::sltTooltip(bool status, int index, QBarSet *barset) { if (m_tooltip == 0) m_tooltip = new ChartTip(m_char); if (status) { int yindex=m_barSetList.
控件 控件及继承关系图
【Window】窗口
【Control】除Window外其他所有组件都继承自Control
布局:
【Container】
【VerticalLayout】垂直布局:其内元素按照竖直方式排列
【HorizontalLayout】水平布局:其内元素按照水平方式排列
【TileLayout】平铺布局:例如360工具箱。属性columns[列数,如(4)]与itemsize[子项固定大小,如(128,128)]不能同时使用。
【TabLayout】标签页,配合Option使用。
【ChildLayout】
功能控件:
【ActiveX】
【WebBrowser】浏览器
【Label】标签
【Button】按钮
【Text】文本
【Progress】--【Slider】进度条--进度条按钮
【Edit】输入框,支持showhtml。
【RichEdit】输入框,不支持showhtml。支持多行,直接打回车即可。
【Option】标签
【ScrollBar】滚动条
【GifAnimGif】动画
【Combo】下拉框
【List--ListHeader】--【ListHeaderItem】--【ListLabelElement】--【ListTextElement】--【ListContainerElement】列表
【TreeView】--【TreeNode】树
属性 详细属性查看官方Duilib文件夹内的"属性列表.xml"。
【name】控件名字,同一窗口内必须唯一。建议命名格式"控件类型名称",例如:"btnClose";"optionMain"。
【bkcolor】背景颜色。如:0xFFFFFFFF。一般的颜色RGB表示都是六位,这里的八位中的前两位为FF,后面六位与普通RGB颜色编码相同。RGB颜色参考
【bkcolor2】背景渐变色2,和bkcolor配合使用,如(0xFFFFFF00)。
【bkcolor3】背景渐变色3,和bkcolor、bkcolor2配合使用,如(0xFFFF00FF)"。
【bkimage】背景图片,如(bk.bmp或file='aaa.jpg' res='' restype='0' dest='0,0,0,0' source='0,0,0,0' corner='0,0,0,0' mask='#FF0000' fade='255' hole='false' xtiled='false' ytiled='false')。
【width】控件预设的宽度,如(100)。
【height】控件预设的高度,如(30)。
【text】显示文本,如(测试文本)。
【tooltip】鼠标悬浮提示,如(请在这里输入你的密码)。
【enabled】是否可以响应用户操作,如(true)。
【mouse】本控件是否可以响应鼠标操作,如(true)。
【mousechild】本控件的子控件是否可以响应用户操作,如(true)。
【visible】是否可见,如(true)。
【menu】是否需要右键菜单。
【float】【pos】是否采用绝对定位以及位置(左上右下)。如float="true" pos="10,10,10,10"。只有float为true时,pos才有效,只有float为true,无pos时内容不显示。更多用法见补充的布局技巧
【padding】外边距,如(2,2,2,2)。边距不属于此控件。
【inset】容器的内边距,如(2,2,2,2)。边距属于此控件。
【bordercolor】边框颜色,如(0xFF000000)。
【focusbordercolor】获得焦点时边框的颜色,如(0xFFFF0000)。
【align】文字对齐方式。在option中可以取left、right、center、top、button,如(center)。
【textpadding】文字显示的边距,如(2,2,2,2)。
【endellipsis】句末显示不全是否使用...代替,如(true)"/>
【showhtml】是否使用类html富文本绘制,如(false)。
【vscrollbar】是否使用竖向滚动条,如(true)。只有内容超出容器后才会显示滚动条。
自己需要先定义vscrollbar滚动条
<Default name="VScrollBar" value="" />
【hscrollbar】是否使用横向滚动条,如(true)。只有内容超出容器后才会显示滚动条。
最近使用sqlite3_bind_*()函数时遇到一个问题,插入的数据是乱码,并且英文,中文都是乱码,并且插入的数据都是一样的乱码,除了字符串,其他类型的数据是正常的,代码如下:
.... sqlite3_stmt *stmt; unsigned int rec_offset = 0; if (sqlite3_prepare_v2 (dbHandle, cmdString, strlen(cmdString), &stmt, NULL) == SQLITE_OK) { for (unsigned int i = 0; i < row_num; ++i) { for (unsigned int k = 0; k < columnVector.size(); k++) { switch (columnVector[k].type) { case DB_DATATYPE_STRING : { char * tmp_char = (char*)malloc (columnVector[k].data_size); memcpy (tmp_char, (char*)data_buffer + rec_offset, columnVector[k].data_size); sqlite3_bind_text (stmt, k + 1, tmp_char, columnVector[k].data_size, SQLITE_STATIC); free (tmp_char); break; } case DB_DATATYPE_INT: { int tempInt; memcpy (&tempInt, (char*)data_buffer + rec_offset, sizeof(int)); sqlite3_bind_int(stmt, k + 1, tempInt); break; } .
**
javax.management.ObjectName;ObjectName报异常 **
其他人说时oracle的jar包问题,我都没用oracle ,后面经过排查。完美解决,并取得需要的东西
try catch就可以了
try{ MBeanServer beanServer = ManagementFactory.getPlatformMBeanServer(); Set objectNames = beanServer.queryNames(new ObjectName(":type=Connector,"), Query.match(Query.attr(“protocol”), Query.value(“HTTP/1.1”))); port= objectNames.iterator().next().getKeyProperty(“port”); System.out.println(port); }catch(Exception e){ e.printStackTrace(); }
Kinect相关topic (1)RGB图像:/camera/rgb/image_color
ROS数据格式:sensor_msgs/Image
OPENCV数据格式:Mat
图像尺寸:640*480
像素数据类型:8UC3
(2)深度图像:/camera/depth/image
ROS数据格式:sensor_msgs/Image
OPENCV数据格式:Mat
图像尺寸:640*480
像素数据类型:32FC1 或 16UC1
(3)点云数据(无整合RGB): /camera/depth/points
ROS数据格式:sensor_msgs/Image
PCL点云库数据格式:pcl::PointCloud<pcl::PointXYZ>
图像尺寸:有序点云,640*480
像素数据类型:double
RGB以及深度图像的像素数据类型非常关键,一旦出错便不能得到正确的坐标
像素坐标系到世界坐标系的转化 [u,v,d]---->[x,y,z] // 相机内参 const double camera_factor=1000; const double camera_cx=325.5; const double camera_cy=253.5; const double camera_fx=518.0; const double camera_fy=519.0; //深度图中(m,n)处的值 ushort d = depth.ptr<ushort>(m)[n]; //点P的世界坐标 p.z = double(d)/camera_factor; p.x = (n-camera_cx)*p.z/camera_fx; p.y = (m-camera_cy)*p.z/camera_fy; camera_factor是深度图里给的数据与实际距离的比例。
由于深度图给的都是short (mm单位),camera_factor通常为1000。
[x,y,z]---->[u,v,d] u = (x*fx)/z + cx ; v = (y*fy)/z + cy ; d = z*camera_factor