vue在同一个组件内;
methods中的一个方法调用methods中的另外一个方法
可以在调用的时候 this.$options.methods.test2();
this.$options.methods.test2();一个方法调用另外一个方法;
new Vue({ el: '#app', data: { test:111, }, methods: { test1:function(){ alert(this.test) }, test2:function(){ alert("this is test2") alert(this.test) //test3调用时弹出undefined }, test3:function(){ this.$options.methods.test2();//在test3中调用test2的方法 } } }) 欢迎关注我的个人技术公众号!javascript艺术
一、NGINX 1.9之前,需要安装第三方的TCP插件:
http://www.cnblogs.com/i-blog/p/6165378.html
二、1.9之后直接使用Stream配置就可以了,当然需要先安装stream模块:
1.nginx 增加tcp
./configure --with-stream --with-pcre=../pcre-8.38
./configure --with-stream --without-http_rewrite_module
2.配置nginx.conf
stream { upstream sftp { hash $remote_addr consistent; server 127.0.0.1:22 max_fails=3 fail_timeout=30s; } server { listen 90; proxy_connect_timeout 1s; proxy_timeout 3s; proxy_pass sftp; } }
实际项目部署结构如下:
参考:http://www.webpiaoliang.com/xuexi/fwq/zj/20170423263321.html
使能python打印输出支持中文,包括终端输出和VSCode输出支持中文 方法一(简单且一劳永逸): 修改系统的环境变量,为系统增加这个环境变量: PYTHONIOENCODING=UTF8 注意,不是UTF-8,而是UTF8 windows:系统属性-高级-环境变量-新建:修改完成后不需要重启系统,但是需要重启VSCode此方法对VSCode执行python时输出乱码有效! 方法二(只对单个文件有效) 在想要解决打印中文乱码的文件中插入以下代码:
import io import sys sys.stdout=io.TextIOWrapper(sys.stdout.buffer,encoding='utf8')
本题要求在链表中查找第一个数据域取值为x的节点,返回节点的位序。L是一个带头结点的单链表,函数ListLocate_L(LinkList L, ElemType x)要求在链表中查找第一个数据域取值为x的节点,返回其位序(从1开始),查找不到则返回0。例如,原单链表各个元素节点的元素依次为1,2,3,4,则ListLocate_L(L, 1)返回1,ListLocate_L(L, 3)返回3,而ListLocate_L(L, 100)返回0。
函数接口定义: int ListLocate_L(LinkList L, ElemType x); 其中 L 是一个带头节点的单链表。 x 是一个给定的值。函数须在链表中查找第一个数据域取值为x的节点。若找到则返回其位序(从1开始),找不到则返回0。
裁判测试程序样例: //库函数头文件包含 #include<stdio.h> #include<malloc.h> #include<stdlib.h> //函数状态码定义 #define TRUE 1 #define FALSE 0 #define OK 1 #define ERROR 0 #define INFEASIBLE -1 #define OVERFLOW -2 typedef int Status; typedef int ElemType; //假设线性表中的元素均为整型 typedef struct LNode { ElemType data; struct LNode *next; }LNode,*LinkList; Status ListCreate_L(LinkList &L,int n) { LNode *rearPtr,*curPtr; //一个尾指针,一个指向新节点的指针 L=(LNode*)malloc(sizeof (LNode)); if(!
1. 摘要 通俗的理解__name__ == '__main__':假如你叫小明.py,在朋友眼中,你是小明(__name__ == '小明');在你自己眼中,你是你自己(__name__ == '__main__')。
if __name__ == '__main__'的意思是:当.py文件被直接运行时,if __name__ == '__main__'之下的代码块将被运行;当.py文件以模块形式被导入时,if __name__ == '__main__'之下的代码块不被运行。
2. 程序入口 对于很多编程语言来说,程序都必须要有一个入口,比如C,C++,以及完全面向对象的编程语言Java,C#等。如果你接触过这些语言,对于程序入口这个概念应该很好理解,C,C++都需要有一个main函数作为程序的入口,也就是程序的运行会从main函数开始。同样,Java,C#必须要有一个包含Main方法的主类,作为程序入口。
而Python则不同,它属于脚本语言,不像编译型语言那样先将程序编译成二进制再运行,而是动态的逐行解释运行。也就是从脚本第一行开始运行,没有统一的入口。
一个Python源码文件(.py)除了可以被直接运行外,还可以作为模块(也就是库),被其他.py文件导入。不管是直接运行还是被导入,.py文件的最顶层代码都会被运行(Python用缩进来区分代码层次),而当一个.py文件作为模块被导入时,我们可能不希望一部分代码被运行。
2.1 一个.py文件被其他.py文件引用 假设我们有一个const.py文件,内容如下:
PI = 3.14 def main(): print("PI:", PI) main() # 运行结果:PI: 3.14 现在,我们写一个用于计算圆面积的area.py文件,area.py文件需要用到const.py文件中的PI变量。从const.py中,我们把PI变量导入area.py:
from const import PI def calc_round_area(radius): return PI * (radius ** 2) def main(): print("round area: ", calc_round_area(2)) main() ''' 运行结果: PI: 3.14 round area: 12.56 ''' 2.2 修改const.py,添加if __name__ == "
class属性,在HTML属性中规定的是元素的类名,是指的某类元素,可以在style中为该类元素添加样式,因此具有.class类的元素都具有相同的样式。Bootstrap是当前比较受欢迎的一个前端框架,在jQuery的基础上进行了完善,因此都是对原生javascript的一种封装。在bootstrap当中,通过类的方式对元素进行样式的添加。不同的类名赋予了元素不同的样式,给元素添加了style。如Bootstrap当中的div class="container",相当于是给元素添加了以下样式,.container{padding-right: 15px; padding-left: 15px;margin-right: auto;margin-left: auto;}这样的一个样式,而我们只要为div添加上一个类名为container即可获得这样的样式,而不需要再通过添加样式表或者赶写内联样式的方式,非常方便简单
1.首先定义一个公共的vue组件; var eventHub = new Vue(); 2.在事件当前的组件中,在created中,用$on向公共的组件eventHub传递,translate是自定义的,getCardNum(data)是要在外部调用的方法; eventHub.$on('translate', function (data) { that.getCardNum(data); }); 3.最后在父组件中,注意负组件要用一个变量保存,var vm = new Vue({}); 4.在父组件中的methods的方法中定义一个方法,在方法里用$emit接收公共组件里的方法; var vm = new Vue({ el: '#example', data: { msg: 'Hello Directive', data: {} }, methods: { getCardNum: function (data, on) { eventHub.$emit('translate', data); } } }); 5.最后就可以在vue组件外部,或者文件外部调用getCardNum(data)这个函数,比如在html中就可以 onclick = vm.getCardNum() 这样来调用;vm是父组件 6.注意一定要把父组件的变量名写上 vm.getCardNum(); 我用vue开发的过程中,遇到java后台的弹窗页面想要调用我vue组件中的方法,可是后台的弹窗页面并没有在我的vue组件中,其他的页面想要调用的vue中的方法,只能在父组件中调用,于是研究了很久,最后确定,将组件中的function()方法传递到最上一层的父组件中,将负组件保存在变量中,最后直接在其他页面中调用方法,调用的时候,就不能用@click方法来调用了,因为后台的页面并不在我的vue组件内部,于是调用就是onclick = vm.getCardNum();这样调用,vm是父组件; 欢迎关注我的个人技术公众号!javascript艺术
因为平时经常需要对源代码进行重命名,但是一直没有找到太好用的工具,于是就自己写了一下,共享给大家。
用法:
Rename.exe /r 源1#替换1 /r 源2#替换2 /d 替换目录
注:
命令行中的目录参数末尾不要加斜杠
例:
Rename.exe /r "CnCrypt#MyCrypt" /r "5.1a#7.1a" /d "D:\CnCrypt Sources 5.1a"
结果:
1,所有文件中会替换 CNCRYPT 为MYCRYPT
2,所有文件中会替换 CnCrypt 为MyCrypt
3,所有文件中会替换 cncrypt为mycrypt
4,替换包括ANSI编码和UNICODE编码和所有其它二进制文件
5,所有目录名和文件名会以1,2,3同样规则进行替换
上两张替换前后对比图
下载链接:http://pan.baidu.com/s/1bo0zO7d
cat tail -f 日 志 文 件 说 明 /var/log/message 系统启动后的信息和错误日志,是Red Hat Linux中最常用的日志之一 /var/log/secure 与安全相关的日志信息 /var/log/maillog 与邮件相关的日志信息 /var/log/cron 与定时任务相关的日志信息 /var/log/spooler 与UUCP和news设备相关的日志信息 /var/log/boot.log 守护进程启动和停止相关的日志消息 系统: # uname -a # 查看内核/操作系统/CPU信息 # cat /etc/issue # cat /etc/redhat-release # 查看操作系统版本 # cat /proc/cpuinfo # 查看CPU信息 # hostname # 查看计算机名 # lspci -tv # 列出所有PCI设备 # lsusb -tv # 列出所有USB设备 # lsmod # 列出加载的内核模块 # env # 查看环境变量 资源: # free -m # 查看内存使用量和交换区使用量 # df -h # 查看各分区使用情况 # du -sh <目录名> # 查看指定目录的大小 # grep MemTotal /proc/meminfo # 查看内存总量 # grep MemFree /proc/meminfo # 查看空闲内存量 # uptime # 查看系统运行时间、用户数、负载 # cat /proc/loadavg # 查看系统负载 磁盘和分区: # mount | column -t # 查看挂接的分区状态 # fdisk -l # 查看所有分区 # swapon -s # 查看所有交换分区 # hdparm -i /dev/hda # 查看磁盘参数(仅适用于IDE设备) # dmesg | grep IDE # 查看启动时IDE设备检测状况 网络: # ifconfig # 查看所有网络接口的属性 # iptables -L # 查看防火墙设置 # route -n # 查看路由表 # netstat -lntp # 查看所有监听端口 # netstat -antp # 查看所有已经建立的连接 # netstat -s # 查看网络统计信息 进程: # ps -ef # 查看所有进程 # top # 实时显示进程状态(另一篇文章里面有详细的介绍) 用户: # w # 查看活动用户 # id <用户名> # 查看指定用户信息 # last # 查看用户登录日志 # cut -d: -f1 /etc/passwd # 查看系统所有用户 # cut -d: -f1 /etc/group # 查看系统所有组 # crontab -l # 查看当前用户的计划任务 服务: # chkconfig –list # 列出所有系统服务 # chkconfig –list | grep on # 列出所有启动的系统服务 程序: # rpm -qa # 查看所有安装的软件包
二叉树的深度 查看提交统计提问 总时间限制: 1000ms 内存限制: 65535kB 描述 给定一棵二叉树,求该二叉树的深度
二叉树深度定义:从根结点到叶结点依次经过的结点(含根、叶结点)形成树的一条路径,最长路径的节点个数为树的深度
输入 第一行是一个整数n,表示二叉树的结点个数。二叉树结点编号从1到n,根结点为1,n <= 10 接下来有n行,依次对应二叉树的n个节点。 每行有两个整数,分别表示该节点的左儿子和右儿子的节点编号。如果第一个(第二个)数为-1则表示没有左(右)儿子 输出 输出一个整型数,表示树的深度 样例输入 3 2 3 -1 -1 -1 -1 样例输出 2 #include<iostream> #include<cmath> #include<cstring> #include<algorithm> #include<iomanip> #include<queue> #include<stack> #include<vector> #include<set> #include<map> using namespace std; int Left[15]={0}; int Right[15]={0}; int d=0; void dfs(int i,int dep) { d=max(d,dep); if(Left[i]!=-1) { dfs(Left[i],dep+1); } if(Right[i]!=-1) { dfs(Right[i],dep+1); } } int main() { int n,l,r; cin>>n; memset(Left,0xff,sizeof(Left)); memset(Right,0xff,sizeof(Right)); for(int i=1;i<=n;++i) { cin>>l>>r; if(l!
Redis对于Linux是官方支持的,安装和使用没有什么好说的,普通使用按照官方指导,5分钟以内就能搞定。详情请参考:
https://blog.csdn.net/weixin_33446857/article/details/80842037
但有时候又想在windows下折腾下Redis,官方是不支持windows的。
最后如果你需要下载redis,可以去这里下载:
http://download.csdn.net/download/weixin_33446857/9981512#comment
解压后就可以了按操作流程来了,记住 ,我的redis是有密码的,如果不想设置密码可以手动去配置文件里改,怎么改,下面有说。
下载好之后直接解压,不用安装。目录如下:
在这里输入cmd,按回车或者快捷键:crtl与alt中间那个键(windows键)+R键
进入DOC操作系统窗口。如下图
找到redis解压路径,我的是:F:\kgdxkj\U盘\123456\新建文件夹\2.8.21\2.8.21
这时在DOC操作系统中第一步输入 f: 回车(我的目录在F盘,所以输入f:), 第二步输入 cd F:\kgdxkj\U盘\123456\新建文件夹\2.8.21\2.8.21 回车,(注意:cd后面有空格) 第三步输入 redis-server.exe redis.windows.conf 回车,这样就启动redis服务了。
启动redis服务的doc窗口,不用关闭,因为服务需要一直执行,如果想关闭服务,直接关闭DOC窗口就行。
下面开始测试使用:
首先再打开一个DOC操作系统窗口,前两步和前面的一样,第一步输入 f: 回车(我的目录在F盘,所以输入f:), 第二步输入 cd F:\kgdxkj\U盘\123456\新建文件夹\2.8.21\2.8.21 回车,(注意:cd后面有空格) 第三步输入redis-cli 回车
这样redis的客户端就被我们打开了,现在我们可以对redis进入操作了,redis都是通过对key的操作进行g“读”,“写”操作的, 方式如: set abc 123456789 这句话的意思是,设定一个key ,名字abc 它的值是123456789 。 get abc 这句话的意思读取key的名字是abc的值。假如出现以下错误:那么可能是你的redis有密码,如何查看redis的密码呢,进入redis目录,找到redis.windows.conf配置文件,搜索:requirepass,找到它,看看是不是有密码,这里我的密码是xwtec123
这时我们再输入auth xwtec123 回车,就可以了。
最后我们对redis进入读写操作如下图:
对redis的操作就不多简述了,这里简单演示几个
keys * : 意思是查看redis里所有的key,目前我的redis里有5个key如下图:
如果我们想看key是abc的值,可以输入 get abc 值是123456789
如果我们想看key是userName_1111的值,可以输入 getuserName_1111 值是我自己存的东西,如下图:
如果想删除指定的key,可以使用 del key 前面我的redis里有5个key,现在我删除key是abc,然后再 keys *,查询到所有的key是4个,abc这个key已被删除。如下图
完结!!!!
剩下靠大家自己研究
指数函数的性质 先来复习一下中学的课程:
指数函数的导数 对f(x) = ax求导:
ax右侧的那个极限似乎没有办法继续简化了,如果这个极限看作关于a的函数(之所以将极限看作关于a的函数,是因为在这个极限中,a是未知的,Δx是已知的):
函数在某一点导数的几何意义是该点处切线的斜率,所以M(a)也就是ax在x=0处切线的斜率。
如果y=2x,则,我们仍不知道M(a)是什么,暂且作为悬念。
e 我们知道e表示自然对数的底数,暂且不管自然对数到底是什么,只知道它确实存在。e有两个性质:
1) (ex)’ = ex
2) ex在x=0的导数是1
当我们想要继续对f(kx)=2kx,k∈R求导时,根据上节的公式(2),,这并没有解决问题,看起来更复杂了。如果已知函数某一点的导数,就能求得该函数压缩或伸展后在该点的导数,2kx仅仅是2x的压缩或伸展,在x=0处的斜率也不断向左或向右倾斜:
当k=1/M(2)时,(bx)在x=0处的导数是1,b = e,虽然暂时不知道它的值,但已经知道它确实存在。
对数的性质 自然对数的导数 自然对数是以e为底的对数,简写做ln
y=lne和y=ex互为反函数:
lnx求导 对于函数y = lnx,其反函数是ey = x,根据反函数微分法:
M(a)的真相 已经做了足够多的准备工作,是时候揭开M(a)的真相了。
在对指数函数y=ax求导时,我们得出(ax)’=axM(a)。根据对数的性质,elna = a,原函数需要使用对数进行一次变换:
根据链式求导法则,
所以,M(a) = ln(a)
指数函数的求导公式 由于已经知道了M(a),所以我们终于可以完成对指数函数的求导了。
对数函数求导公式:(ax)’ = axlna
示例:
(10x)’ = 10xln10, (2x)’ = 2x ln2
对数微分法 自然对数求导公式:(lnu)’ = u’/u,u是x的函数
根据该公式,(lnx)’ = x’/x = 1/x
示例1:(lnx)’ = x’/x = 1/x
示例2:(lnax)’ = (ax)’/ ax = (ax lna) / ax = lna
DPDK简介 DPDK是X86平台报文快速处理的库和驱动的集合,不是网络协议栈,不提供二层,三层转发功能,不具备防火墙ACL功能,但通过DPDK可以轻松的开发出上述功能。
DPDK的优势在于,可以将用户态的数据,不经过内核直接转发到网卡,实现加速目的。主要架构如图所示:
传统的socket方式与DPDK对比:
DPDK关键技术点:
使用大页缓存支持来提高内存访问效率。利用UIO支持,提供应用空间下驱动程序的支持,也就是说网卡驱动是运行在用户空间 的,减小了报文在用户空间和应用空间的多次拷贝。利用LINUX亲和性支持,把控制面线程及各个数据面线程绑定到不同的CPU核,节省了线程在各个CPU核来回调度。LOCKLESS, 提供无锁环形缓存管理,加快内存访问效率。收发包批处理 ,多个收发包集中到一个cache line,在内存池中实现,无需反复申请和释放。PMD驱动,用户态轮询驱动,可以减小上下文切换开销,方便实现虚拟机和主机零拷贝。 OVS+DPDK OpenvSwitch 以其丰富的功能,作为多层虚拟交换机,已经广泛应用于云环境中。Open vSwitch的主要功能是为物理机上的VM提供二层网络接入,和云环境中的其它物理交换机并行工作在Layer 2。
传统host ovs工作在内核态,与guest virtio的数据传输需要多次内核态和用户态的数据切换, 带来性能瓶颈. Ovs+Dpdk和Ovs本身之间的区别可以由下图简单来表示:
在早期OVS的版本中,为缓解多级流表查表慢的问题,OVS在内核态采用Microflow Cache方法。Microflow Cache是基于Hash的精确匹配查表(O(1)),表项缓存了多级查表的结果,维护的是每条链接粒度的状态。Microflow Cache减少了报文进用户态查多级表的次数。一条流的首报文进入用户态查表后,后续的报文都会命中内核中的Microflow Cache,加快了查表速度。但是对于大量短流的网络环境来说,Microflow Cache命中率很低,导致大部分报文仍然需要到用户态进行多级流表查找,因此转发性能提升有限。
而后,为了解决Mircoflow Cache存在的问题,OVS采用Megaflow Cache代替了Mircoflow Cache。与Mircoflow Cache的精确Hash查表不同,Megaflow Cache支持带通配的查表,所以可减少报文至用户空间查表的次数。庾志辉的博客中当时分析的就是关于megaflow的数据结构和查表流程,相关内容不在此赘述,请看上文中的链接。但是,由于OVS采用元组空间搜索(下文介绍)实现Megaflow Cache的查找,所以平均查表次数为元组表的数量的一半。假设元组空间搜索的元组表链为m,那么平均查表开销为O(m/2)。Mircoflow Cache和Megaflow Cache查表开销对比为O(1)< O(m/2)。因此,Megaflow Cache相比于Mircoflow Cache,尽管减少了报文进用户空间查表的次数,但是增加了报文在内核态查表的次数。
为此,OVS当前版本采用Megaflow Cache+Microflow Cache的流Cache组织形式,仍保留了Microflow Cache作为一级Cache,即报文进入后首先查这一级Cache。只不过这个Microflow Cache含义与原来的Microflow Cache不同。原来的Microflow Cache是一个实际存在的精确Hash表,但是最新版本中的Microflow Cache不是一个表,而是一个索引值,指向的是最近一次查Megaflow Cache表项。那么报文的首次查表就不需要进行线性地链式搜索,可直接对应到其中一张Megaflow的元组表。这三个阶段的查表开销如表所示。
DPDK 高性能(user space) 网卡驱动、大页内存、无锁化结构设计,可以轻易实现万兆网卡线速的性能。ovs-dpdk使vm到vm和nic到vm的整个数据传输都工作在用户态,极大的提升了ovs的性能。
另外,ovs-dpdk 结合了DPDK和vhost-user技术的优势。vhost-user是一个用户态的vhost-backend程序,从虚拟机到host上实现了数据零拷贝(zero copy)。
原生ovs与ovs-dpdk比较 (1)原生ovs数据流处理过程如下:
数据包到达网卡后,上传给Datapath;Datapath 会检查缓存中的精确流表是否可以直接转发这个包,如果在缓存中没有找到记录,内核通过netlink发送一个upcall给用户空间的vswitchd;vswitchd检查数据库以查看数据包的目的端口在哪里。这里要操作openflow流表,需要和ovsdb以及ovs-ofctl交互;刷新内核态流表内容;Reinject给datapath,重发数据包;再次查询流表,获取数据包精确转发规则后,按规则转发 (2)ovs-dpdk方式:
用户态进程直接接管网卡收发数据,采用“IO独占核”技术,即每个端口分配一个核专门用于数据收发,轮询式处理方式代替中断式处理,显著提高IO性能。
总结:
比较原生ovsovs-dpdkhost收发包通过host的linux内核访问网卡通过dpdk高速数据通道收发包内部交换在内核态datapath进行交换基于ovs,提供dpdk datapath的交换能力vm后端驱动使用vni,基于开源tap进行优化vhost-uservm前端驱动标准virtio设备标准virtio设备交换路径2个线程:物理网卡(中断机制)->转发线程->放到tap设备队列->vhost_net取包送给vcpu1个线程:物理网卡(DPDK DPM)->转发线程->送给vcpu 使用ovs-dpdk 硬件要求
网卡得支持DPDK,见:http://dpdk.org/doc/nics CPU得支持DPDK, 测试命令:cat /proc/cpuinfo |grep pdpe1gb 不一定非要支持DPDK硬件的网卡,因为DPDK也支持virtio dpdk driver.
实验数据:cat-dog 二分类,训练集:19871 验证集:3975 实验模型:resnet-18 batchsize:128*2 (一个K80吃128张图片)
存在的问题: 对训练集 accuracy可达0.99 loss=1e-2 -3,然而验证集 accuracy 0.5,loss 很高,试了多个初始学习率(0.1 — 0.0001)都不行
解决上述问题: 采取warm up方法 ,对上述问题有点帮助
训练resnet,由于不finetune,很容易过拟合,paper《Deep Residual Learning for Image Recognition》中对cifar10的实验用了一个trick是 warm up(热身),就是先采用小的学习率(0.01)进行训练,训练了400iterations之后将学习率调整至0.1开始正式训练。
一开始不以为然,我分别用了四个初始学习率 lr=0.1; 0.01; 0.001; 0.0001; 然后每1000个iterations就降低一次lr。然而这四种初始学习率都试过之后,发现,验证集的accuracy怎么都上不去,都是0.5~0.6之间,而训练集的可以到0.99。而resnet采用了batch normalization,在caffe中,batch normalization 就有一个“坑”,就是use_global_stats 的设置问题。training时候是关闭,testing的时候是要打开,deploy也是要打开的。 对于训练集accuracy达0.99,验证集accuracy是0.5+的情况,我以为是batch normalization出问题,于是乎各种捣鼓BN去了,最后试了一下warm up,网络在验证集的loss才有所下降。
来看看warm up 的loss,分别采用 0.01 0.001 0.001 0.0001,gamma=10 ;stepsize在图中已经隔断
71,谈谈你对Struts的理解。
1. struts是一个按MVC模式设计的Web层框架,其实它就是一个Servlet,这个Servlet名为ActionServlet,或是ActionServlet的子类。我们可以在web.xml文件中将符合某种特征的所有请求交给这个Servlet处理,这个Servlet再参照一个配置文件将各个请求分别分配给不同的action去处理。
(struts的配置文件可以有多个,可以按模块配置各自的配置文件,这样可以防止配置文件的过度膨胀)
2.ActionServlet把请求交给action去处理之前,会将请求参数封装成一个formbean对象(就是一个java类,这个类中的每个属性对应一个请求参数),
3.要说明的是, ActionServlet把formbean对象传递给action的execute方法之前,可能会调用formbean的validate方法进行校验,只有校验通过后才将这个formbean对象传递给action的execute方法,否则,它将返回一个错误页面,这个错误页面由input属性指定。
4.action执行完后要返回显示的结果视图,这个结果视图是用一个ActionForward对象来表示的,actionForward对象通过struts-config.xml配置文件中的配置关联到某个jsp页面,因为程序中使用的是在struts-config.xml配置文件为jsp页面设置的逻辑名,这样可以实现action程序代码与返回的jsp页面名称的解耦。
(以上,也可以结合自己使用感受谈自己的看法)
72、谈谈你对Hibernate的理解。
1. 面向对象设计的软件内部运行过程可以理解成就是在不断创建各种新对象、建立对象之间的关系,调用对象的方法来改变各个对象的状态和对象消亡的过程,不管程序运行的过程和操作怎么样,本质上都是要得到一个结果,程序上一个时刻和下一个时刻的运行结果的差异就表现在内存中的对象状态发生了变化。
2.为了在关机和内存空间不够的状况下,保持程序的运行状态,需要将内存中的对象状态保存到持久化设备和从持久化设备中恢复出对象的状态,通常都是保存到关系数据库来保存大量对象信息。从Java程序的运行功能上来讲,保存对象状态的功能相比系统运行的其他功能来说,应该是一个很不起眼的附属功能,java采用jdbc来实现这个功能,这个不起眼的功能却要编写大量的代码,而做的事情仅仅是保存对象和恢复对象,并且那些大量的jdbc代码并没有什么技术含量,基本上是采用一套例行公事的标准代码模板来编写,是一种苦活和重复性的工作。
3.通过数据库保存java程序运行时产生的对象和恢复对象,其实就是实现了java对象与关系数据库记录的映射关系,称为ORM(即Object RelationMapping),人们可以通过封装JDBC代码来实现了这种功能,封装出来的产品称之为ORM框架,Hibernate就是其中的一种流行ORM框架。使用Hibernate框架,不用写JDBC代码,仅仅是调用一个save方法,就可以将对象保存到关系数据库中,仅仅是调用一个get方法,就可以从数据库中加载出一个对象。
4.使用Hibernate的基本流程是:配置Configuration对象、产生SessionFactory、创建session对象,启动事务,完成CRUD操作,提交事务,关闭session。
5.使用Hibernate时,先要配置hibernate.cfg.xml文件,其中配置数据库连接信息和方言等,还要为每个实体配置相应的hbm.xml文件,hibernate.cfg.xml文件中需要登记每个hbm.xml文件。
6.在应用Hibernate时,重点要了解Session的缓存原理,级联,延迟加载和hql查询。
(以上,也可以结合自己使用JDBC时的繁琐谈hibernate的感受)
73,谈谈你对Spring的理解。
1.Spring是实现了工厂模式的工厂类(在这里有必要解释清楚什么是工厂模式),这个类名为BeanFactory(实际上是一个接口),在程序中通常BeanFactory的子类ApplicationContext。Spring相当于一个大的工厂类,在其配置文件中通过<bean>元素配置用于创建实例对象的类名和实例对象的属性。
2. Spring提供了对IOC良好支持,IOC是一种编程思想,是一种架构艺术,利用这种思想可以很好地实现模块之间的解耦,IOC也称为DI(Depency Injection)。
3. Spring提供了对AOP技术的良好封装, AOP称为面向切面编程,就是系统中有很多各不相干的类的方法,在这些众多方法中要加入某种系统功能的代码,例如,加入日志,加入权限判断,加入异常处理,这种应用称为AOP。
实现AOP功能采用的是代理技术,客户端程序不再调用目标,而调用代理类,代理类与目标类对外具有相同的方法声明,有两种方式可以实现相同的方法声明,一是实现相同的接口,二是作为目标的子类。
在JDK中采用Proxy类产生动态代理的方式为某个接口生成实现类,如果要为某个类生成子类,则可以用CGLI B。在生成的代理类的方法中加入系统功能和调用目标类的相应方法,系统功能的代理以Advice对象进行提供,显然要创建出代理对象,至少需要目标类和Advice类。spring提供了这种支持,只需要在spring配置文件中配置这两个元素即可实现代理和aop功能。
(以上,也可以结合自己使用感受谈自己的看法) 74,谈谈Struts的优缺点 优点: 1. 实现MVC模式,结构清晰,使开发者只关注业务逻辑的实现.
2.有丰富的tag可以用 ,Struts的标记库(Taglib),如能灵活动用,则能大大提高开发效率
3. 页面导航使系统的脉络更加清晰。通过一个配置文件,即可把握整个系统各部分之间的联系,这对于后期的维护有着莫大的好处。尤其是当另一批开发者接手这个项目时,这种优势体现得更加明显。
4. 提供Exception处理机制 .
5. 数据库链接池管理
6. 支持I18N
缺点:
一,转到展示层时,需要配置forward,如果有十个展示层的jsp,需要配置十次struts,而且还不包括有时候目录、文件变更,需要重新修改forward,注意,每次修改配置之后,要求重新部署整个项目,而tomcate这样的服务器,还必须重新启动服务器
二,Struts的Action必需是thread-safe方式,它仅仅允许一个实例去处理所有的请求。所以action用到的所有的资源都必需统一同步,这个就引起了线程安全的问题。
三,测试不方便. Struts的每个Action都同Web层耦合在一起,这样它的测试依赖于Web容器,单元测试也很难实现。不过有一个Junit的扩展工具Struts TestCase可以实现它的单元测试。
四,类型的转换. Struts的FormBean把所有的数据都作为String类型,它可以使用工具Commons-Beanutils进行类型转化。但它的转化都是在Class级别,而且转化的类型是不可配置的。类型转化时的错误信息返回给用户也是非常困难的。
五,对Servlet的依赖性过强. Struts处理Action时必需要依赖ServletRequest和ServletResponse,所有它摆脱不了Servlet容器。
六,前端表达式语言方面.Struts集成了JSTL,所以它主要使用JSTL的表达式语言来获取数据。可是JSTL的表达式语言在Collection和索引属性方面处理显得很弱。
七,对Action执行的控制困难. Struts创建一个Action,如果想控制它的执行顺序将会非常困难。甚至你要重新去写Servlet来实现你的这个功能需求。
八,对Action执行前和后的处理. Struts处理Action的时候是基于class的hierarchies,很难在action处理前和后进行操作。
九,对事件支持不够.在struts中,实际是一个表单Form对应一个Action类(或DispatchAction),换一句话说:在Struts中实际是一个表单只能对应一个事件,struts这种事件方式称为application event,application event和component event相比是一种粗粒度的事件
75,iBatis与Hibernate有什么不同?
相同点:屏蔽jdbc api的底层访问细节,使用我们不用与jdbc api打交道,就可以访问数据。
使用ffmpeg循环推流(循环读取视频文件)方法
命令如下:
ffmpeg -re -stream_loop -1 -i 2minTransformers6281_trailer1080p.flv -vcodec copy -f flv rtmp://192.168.1.26:1935/live/PFM_test_HD_test1
说明:
-stream_loop -1 中 -1 表示无限循环;0表示 不循环
2minTransformers6281_trailer1080p.flv 推的视频文件
rtmp://192.168.1.26:1935/live/PFM_test_HD_test1 推到server的流的地址
ffmpeg推流的局限性:
对于bit rate为2m左右的 flv 文件好像没啥问题,试过 4m及以上的就会报错:av_interleaved_write_frame(): Broken pipe 这个问题,还有待确认,先作为记录。
目前看来还是srs-bench 强大。 见:https://github.com/ossrs/srs-bench
现象:当网页中使用上传1个3M多的图片出现 Request Entity Too Large的提示,如下图所示
根据经验判断应该是上传文件大小被限制了,检查了应用配置是10M,把它设置成100M,重启服务也不能解决问题。
原来我们的tomcat是通过nginx发现服务代理的,问题就出现nginx服务器上,原来nginx默认长传文件的大小是1M,可在nginx的配置中修改。
解决方法:
1、打开nginx服务的配置文件nginx.conf, 路径一般是:/usr/local/nginx/conf/nginx.conf。
2、在http{}中加入client_max_body_size 100m,我这里配置的是100M。
http {
client_max_body_size 100m;
include mime.types;
default_type application/octet-stream;
3、重新nginx服务。
Launcher3简介 Laucnher3采用mv模式。 数据层为LauncherModel,采用异步加载方式读写数据。界面层为Launcher
(1~7 ) 准备工作
(8~12 ) 工作线程sWorkThread 执行任务LoadTask
(11~18 ) 找到适配的xml配置文件
(17~ 27) 解析xml数据,存入到workScreens favorites数据库
解析XML代码分析 解析各个标签Google采用了策略模式,各个节点都需要解析,但是只是解析方法不同,Google将解析逻辑抽调出来,采用策略模式,降低耦合性。 21 (1)拿到根据屏幕尺寸匹配出来的default_workspace_*x*.xml文件生成解析器XmlResourceParser (2)得到各个节点解析器对象集合 (3)循环调用parseAndAddNode开始解析节点 protected int parseLayout(int layoutId, ArrayList<Long> screenIds) throws XmlPullParserException, IOException { XmlResourceParser parser = mSourceRes.getXml(layoutId); beginDocument(parser, mRootTag); final int depth = parser.getDepth(); int type; HashMap<String, TagParser> tagParserMap = getLayoutElementsMap(); int count = 0; while (((type = parser.next()) != XmlPullParser.END_TAG || parser.getDepth() > depth) && type != XmlPullParser.END_DOCUMENT) { if (type !
最近突然手痒就想搞个贝塞尔曲线做个水波纹效果玩玩,终于功夫不负有心人最后实现了想要的效果,一起来看下吧:
效果图镇楼 一:先一步一步来分解一下实现的过程 需要绘制一个正弦曲线(sin)或者余弦曲线(cos)通过水平平移曲线来的到像水波波动的效果水平移动的同时还需要有水位上涨,也就是向上平移裁剪画布为圆形,在圆形区域绘制曲线通过上面4步就可以实现了 二:现在就来实现第一步,绘制一个sin曲线;这里画了一张图来帮助理解,在PhotoShop中我们绘制一个贝塞尔曲线可以清楚的看到它的控制点如图: 绘制贝塞尔曲线我们必须要知道三个点:起点、控制点、终点;有了这三个点我们就可以绘制一段简单二阶贝塞尔曲线。从图中我们可以看出 起点 控制点p1 x1 这三个点绘制了一段曲线,也就是通过path.quadTo()函数添加一个曲线路径。 假设我们需要绘制一个周期的sin曲线,那么我们就只需要知道起点、一个周期的宽度、振幅;就可以绘制一个sin曲线了。
三:下面就来看下代码的实际操作了,这里就直接省略掉一些画笔初始化的操作了可以点击这里查看源码 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); //获取view的宽度 width = getViewSize(800, widthMeasureSpec); //获取view的高度 height = getViewSize(400, heightMeasureSpec); //获取起点坐标 startPoint = new Point(0, height / 2); } 首先肯定是要获取到画布的大小才能确定好起点的坐标,有了起点坐标就可以开始绘制我们的曲线了
在ondraw()函数中进行曲线的绘制 /*sin曲线 1/4个周期的宽度*/ private int cycle = 200; /*sin曲线振幅的高度*/ private int waveHeight = 200; @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); path.moveTo(startPoint.x, startPoint.y); int j = 1; //循环绘制正弦曲线 循环一次半个周期 for (int i = 1; i <= 8; i++) { if (i % 2 == 0) { //波峰 path.
v-model v-model在双向绑定的时候会忽视value,checked,selected特征的初始值。 v-model可以绑定的控件有textarea,checked,radio,select。其他控件不能够通过v-model双向绑定
对于多个复选框,我们可以通过绑定一个数组的形式实现 <div id="app"> <input type="checkbox" value="jack" v-model="names" > <input type="checkbox" value="xiaoD" v-model="names" > <input type="checkbox" value="joe" v-model="names" > {{names}} </div> <script type="text/javascript"> var app = new Vue({ el: "#app", data: { names:[ ] } }) </script> 多个单选框 <div id="app"> <input type="radio" value="jack" v-model="name" > <input type="radio" value="xiaoD" v-model="name" > <input type="radio" value="joe" v-model="name" > {{name}} </div> <script type="text/javascript"> var app = new Vue({ el: "#app", data: { name: '' } }) </script> 下拉框selected <div id="
这篇博文是对前期学习的一个综合总结。
一、企业场景全量和增量的频率是怎么做的?
1.中小公司,全量一般是每天一次,业务流量低谷执行全备,备份时会锁表。
2.大公司周备,每周六00点一次全量,其他时间通过binlog做增量。(优点:节省备份时间,减小备份压力。缺点:增量的binlog文件副本太多,还原会很麻烦。)
3.一主多从,使用一个从库专门做备份,必要时可以做延时同步。
二、mysql的mysqldump备份什么时候派上用场?
1.迁移或者升级数据库时。
2.增加从库时候。
3.人为的sql语句误操作。
三、本次模拟的就是人为的误操作后进行紧急恢复。
1)误删数据库
一、工作场景
(1)两台数据库,主从状态,binlog日志开启。(主从配置http://blog.csdn.net/sj349781478/article/details/77519698)
(2)MySQL数据库每晚12:00自动完全备份。
0 0 * * * root mysqldump -u root -p -S /data/mysql3308/mysql3308.sock --all-databases --single-transaction --flush-logs --master-data=2 --events| gzip > /opt/database_`date '+%m-%d-%Y'`.sql.gz (3)某天早上上班,9点左右,接到反馈前端应用使用异常,程序报数据库不存在。
(4)进行紧急恢复!(利用备份的数据文件以及增量的binlog文件进行数据恢复.)
二、数据恢复思路
(1)利用全备的sql文件中记录的CHANGE MASTER语句,binlog文件及其位置点信息,找出binlog文件中增量的那部分。
(2)用mysqlbinlog命令将上述的binlog文件导出为sql文件,并剔除其中的drop语句。
(3)通过全备文件和增量binlog文件的导出sql文件,就可以恢复到完整的数据。
三、实例说明
场景:以全备的data数据库为例,data库中有cost表,全量备份时表中有三条记录,后续有插入的三条记录,某一时刻被误操作删除了data库。
1)发现库被删除:前端报故障过来说data库访问不了,或者监控发现data不存在;
2)向领导反馈或对外发布通知,数据库故障紧急维护;
3)刷新binlog,防止后续新增的在恢复过程中,会继续写入语句到该binlog,最终导致增量恢复数据部分变得比较混乱;
# mysqladmin -uroot -p -S /data/mysql3308/mysql3308.sock flush-logs
4)对当天凌晨备份的数据进行恢复(恢复时间与数据量大小成正比);
# gunzip < /opt/database_09-03-2017.sql.gz | mysql -uroot -p -S /data/mysql3308/mysql3308.sock
5)查看全备之后新增的binlog文件点
# gunzip database_09-03-2017.sql.gz
内容来自OpenCV-Python Tutorials 自己翻译整理
目标:
GrabCut算法原理与应用 创建交互式程序完成前景提取
原理: 首先用矩形将要选择的前景区域选定,其中前景区域应该完全包含在矩形框当中。然后算法进行迭代式分割,知道达到效果最佳。但是有时分割结果不好,例如前景当成背景,背景当成前景。测试需要用户修改。用户只需要在非前景区域用鼠标划一下即可。 如文档中的图片,运动员和足球被蓝色矩形保卫,其中有数个用白色标记修改的,表示前景区域,黑色表示背景区域。
首先,输入矩形框,矩形框外部区域都是背景。内部一定包含前景。
电脑对输入图像进行初始化,标记前景和背景的像素。
使用高斯混合模型(GMM)对前景和背景建模。
根据输入,GMM会学习并创建新的像素分布。对未知的像素(前景或背景不确定),根据他们与已知的分类像素关系进行分类。(类似聚类操作)
这样会根据像素的分布创建一幅图,图中节点是像素。除了像素点是节点以外,还有Source_node和Sink_node两个节点。所有的前景图像斗鱼Source_node相连。背景与Sink_node相连。
像素是否连接到Source_node/end_node依赖于权值,这个权值由像素属于同一类,也就是前景或者背景的概率来决定。如果像素的颜色有很大区别,那么他们之间的权重就很小。
使用mincut算法对图像进行分割。它会根据最小代价方程对图像分成source_node和sink_node。代价方程是指裁剪所有边上权重的和。裁剪完成后,所有连接到source_node的判定为前景,sink_node上的为背景。
继续此过程,直到分类收敛。
此网站有关于GrabCut算法的详细讲解
示例:
cv2.grabCut()函数参数
img 输入图像mask 蒙板图像,确定前景区域,背景区域,不确定区域,可以设置为cv2.GC_BGD,cv2.GC_FGD,cv2.GC_PR_BGD,cv2.GC_PR_FGD,也可以输入0,1,2,3rect 前景的矩形,格式为(x,y,w,h),分别为左上角坐标和宽度,高度bdgModel, fgdModel 算法内部是用的数组,只需要创建两个大小为(1,65)np.float64的数组。iterCount 迭代次数mode cv2.GC_INIT_WITH_RECT 或 cv2.GC_INIT_WITH_MASK,使用矩阵模式还是蒙板模式。 import numpy as np import cv2 from matplotlib import pyplot as plt img = cv2.imread('1.jpg') mask = np.zeros(img.shape[:2],np.uint8) bgdModel = np.zeros((1,65),np.float64) fgdModel = np.zeros((1,65),np.float64) rect = (50,50,450,290)#划定区域 cv2.grabCut(img,mask,rect,bgdModel,fgdModel,5,cv2.GC_INIT_WITH_RECT)#函数返回值为mask,bgdModel,fgdModel mask2 = np.where((mask==2)|(mask==0),0,1).astype('uint8')#0和2做背景 img = img*mask2[:,:,np.newaxis]#使用蒙板来获取前景区域 cv2.imshow('p',img) cv2.waitKey(0) 计算完成后mask里面值为0到3,其中0表示背景,1表示前景,2表示可能是背景,3表示可能是前景 代码中将0和2合并为背景 1和3合并为前景
var win1 = Ext.create('Ext.window.Window', { //实例化方法四 : 使用 完整的 Extjs 类名 width: 800, title: 'define test4', height:600 }); 主要涉及到Ext.js Inventory.js ClassManager.js Class.js Loader.js Boot.js
在ClassManager.js中,
create: function () { var name = arguments[0], nameType = typeof name, args = arraySlice.call(arguments, 1), cls; if (nameType === 'function') { cls = name; } else { if (nameType !== 'string' && args.length === 0) { args = [name]; if (!(name = name.xclass)) { name = args[0].
本文主要介绍mesos相关集群的安装和配置过程,主要在centos7中采用yum安装的方法,帮助快速搭建可用的mesos集群服务,可以借助marathon等工具,进行docker的管理。本文主要讲述该集群的安装和配置过程,并不涉及该集群的使用方法演示。 下面,我们开始安装过程,首先,我们有三台机器,IP分别为192.168.20.15,192.168.20.16,192.168.20.17,并目标安装以下组件, - zookeeper - mesos - docker - marathon - chronos
部署过程 环境 软件版本操作系统centos 3.10.0-514.el7.x86_64zookeepermesosphere-zookeeper-3.4.6 配置主机名及IP对应关系 在每台机器上,修改/etc/hostname,分别将其内容更改为host-1,host-2,host-3修改每台机器上的/etc/hosts文件,在每个hosts文件中都添加上主机与ip的对应关系,即(注意需要与hostname相互呼应) 192.168.20.17 host-2 192.168.20.15 host-3 192.168.20.16 host-1 主机名更改后,需要重启机器,使其生效
安装并配置zookeeper 添加库 rpm -Uvh http://repos.mesosphere.io/el/7/noarch/RPMS/mesosphere-el-repo-7-1.noarch.rpm通过yum为每台机器安装zookeeper, sudo yum install mesosphere-zookeeper编辑每台机器上的配置文件/etc/zookeeper/conf/zoo.cfg,在末尾添加 server.1=host-1:2088:3088 server.2=host-2:2088:3088 server.3=host-3:2088:3088 在此处中,server.X=A:B:C 其中X是一个数字, 表示这是第几号server. A是该server所在的IP地址. B配置该server和集群中的leader交换消息所使用的端口. C配置选举leader时所使用的端口。为每个节点设置不同的myid值,在/var/lib/zookeeper/myid中写入一个1到255范围的数值,需要注意的是,不能重复,并与上面的配置对应。可以参考如下命令 echo '2' | sudo tee /var/lib/zookeeper/myid开启服务并判断是否成功 打开服务 systemctl start zookeeper 查看状态 systemctl status zookeeper 尝试连接 cd /opt/mesosphere/zookeeper/bin/ ./zkCli.sh -server 127.0.0.1 注意,同样,我们需要用这个方法,要测试一下另外的两台机器,已保证均可正常连接。可以用quit命令退出连接 如果不能互连,请确实是否是防火墙的原因,可以现将防火墙进行管理,并测试 关闭防火墙 systemctl stop firewalld.service #停止firewall systemctl disable firewalld.
安装环境 Java环境
安装并启动Spark 下载并解压Spark wget https://d3kbcqa49mib13.cloudfront.net/spark-2.2.0-bin-hadoop2.7.tgz tar xzvf spark-2.2.0-bin-hadoop2.7.tgz /usr/local cd /usr/local ln -s spark spark-2.2.0-bin-hadoop2.7 cd spark 运行master和slave ./sbin/start-master.sh -h 192.168.0.166 ./sbin/start-slave.sh spark://192.168.0.166:7077 其中192.168.0.166是本地ip
下载Mysql JDBC 下载JDBC,然后解压到spark目录,然后配置conf/spark-defaults.conf
spark.driver.extraClassPath /usr/local/spark/mysql-connector-java-5.1.39-bin.jar spark.executor.extraClassPath /usr/local/spark/mysql-connector-java-5.1.39-bin.jar 运行scala命令(spark-shell) ./bin/spark-shell --master spark://192.168.0.166:7077 var jdbcDF = spark.read.format("jdbc").options( Map("url"->"jdbc:mysql://localhost:3306/collection?user=root&password=pw", "dbtable"->"collection.iqilu_news", "fetchSize"->"100", "partitionColumn"->"catid", "lowerBound"->"1", "upperBound"->"300", "numPartitions"->"30" )).load() // 其中Spark根据partitionColumn里的字段来决定并发,numPartitions是并发数 // 创建collection临时视图,以供下面查询使用 jdbcDF.createOrReplaceTempView("collection") var sqlDF = sql("SELECT title FROM collection ORDER BY id DESC LIMIT 10") // 查看数据 sqlDF.show() // 统计 sqlDF.
Mybatis的一个插件,PageHelper,非常方便mybatis分页查询。国内牛人的一个开源项目,有兴趣的可以去看源码,都有中文注释(ps:某些源码一大堆英文,痛哭流涕!)
在github上仓库地址为:Mybatis-PageHelper
它支持基本主流与常用的数据库,这可以在它的文档上看到。这里记录一下使用的基本方法
0.查看文档与使用准备 开发文档有中文文档也有英文文档
PageHelper官方文档
============================================
====================================================================================
1.配置拦截器插件 这个是配置在mybatis-config.xml文件中
文档中的示例:
<!-- plugins在配置文件中的位置必须符合要求,否则会报错,顺序如下: properties?, settings?, typeAliases?, typeHandlers?, objectFactory?,objectWrapperFactory?, plugins?, environments?, databaseIdProvider?, mappers? --> <plugins> <!-- com.github.pagehelper为PageHelper类所在包名 --> <plugin interceptor="com.github.pagehelper.PageInterceptor"> <!-- 使用下面的方式配置参数,后面会有所有的参数介绍 --> <property name="param1" value="value1"/> </plugin> </plugins> 我的配置:
<plugins> <plugin interceptor="com.github.pagehelper.PageInterceptor"> <!-- config params as the following --> <!--<!–分页参数合理化 –>--> <property name="reasonable" value="true"/> </plugin> </plugins> 一些配置参数的说明可以参考文档: 【分页插件参数介绍】
这里就说明一下reasonable的配置:
reasonable:分页合理化参数,默认值为false。当该参数设置为 true 时,pageNum<=0 时会查询第一页,pageNum>pages(超过总数时),会查询最后一页。默认false 时,直接根据参数进行查询。
那么如何选择这些配置参数,文档中也给出了详细说明:【如何选择配置这些参数】
2.在代码中使用 官方文档也有这部分说明和案例,那么我就以自己的使用案例
@RequestMapping("/emps") public String list(@RequestParam(required = false,defaultValue = "
折腾了好几天终于把cublas矩阵求逆调好了,但是依然还是有很多疑问,因为是按照网上别人的程序凑出来的。主要的疑惑有两点,在这里贴出来,希望有大神可以指点一二,大家交流交流。
①矩阵初始化的时候,matHost[0],为什么不可以像我注释掉的那两句那样子初始化,那样初始化的时候就会报错:expected an expression。
②为什么要定义一个在host端的指针srchd,它的内容却在device端,然后又要定义一个device端的指针srcDptr,最后再把srchd拷贝到srcDptr,为什么不能省略掉srchd,直接把srcDptr的内存开辟到device端,把数据从matHost直接拷贝到srcDptr,即
float **srcDptr;
cudaMalloc((void**)&srcDptr, sizeof(float*) * NUM);
for(int I=0;i<NUM;i++)
{
cudaMalloc((void**)&srcDptr[i],sizeof(float)*N*N);
cudaMemcpy(srcDptr[i],matHost[i],sizeof(float)*N*N,cudaMemcpyHostToDevice);
}
然后把srcDptr传给cublasSgetrfBatched。
这样我测试是行不通的,不知道是为什么。
③cublasSgetefBatched函数的那个参数pivot到底是什么,是矩阵的各阶顺序主子式吗?因为只有矩阵的各阶顺序主子式都不为0的时候才能进行LU分解,是这样的吗?
下面是我调通的代码:
#include<iostream> #include"cuda_runtime.h" #include<cublas_v2.h> #include<stdlib.h> #include<time.h> //矩阵的阶数 #define N 3 //有两个矩阵 #define NUM 2 int main() { //开辟一个二维的数组空间 float **matHost = new float*[NUM]; for(int i=0;i<NUM;i++) matHost[i] = new float[N*N]; //matHost[0] = {-0.997497,0.617481,-0.299417,0.127171,0.170019, //0.791925,-0.613392,-0.0402539,0.64568}; matHost[0][0] = -0.997497; matHost[0][1] = 0.617481; matHost[0][2] = -0.299417; matHost[0][3] = 0.127171; matHost[0][4] = 0.170019; matHost[0][5] = 0.
Dojo request (js ajax)向java后台传汉字乱码的通用解决方法 在开发项目的过程中,遇到了js向Java后台传汉字时出现乱码的情况。 解决的大体思想是,在js中进行编码,然后在java后台中进行解码。
前台编码 var str = encodeURI("将要传的汉字"); 后台解码 str = URLDecoder.decode(str , "utf-8"); 要引入java.net包,并要抛异常
1、需求 由于IOS原生开发对含有html标签的数据处理很麻烦,所以在做文章详情时,采用内嵌H5页面形式混合开发。
2、流程 ObjC将字符串类型的数据,通过Window上的JS方法将数据传递给JS。JS拿到数据渲染H5页面,并通知ObjC H5文档高度(JS实现图片正常显示,并正确返回文档的高度)。
3、实现 JS方法定义 index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"> <title>文章详情</title> </head> <body> <div class="article-wrapper"> <div class="article-content" id="content"> <p>数据加载中...</p> </div> </div> <script src="app.js"></script> <script> // 原生App中,通过调用articleDetail()方法,将数据传递到该页面, // js实现页面渲染 function articleDetail(content) { cap.init('#content', content); } </script> </body> </html> app.js
/* * Create by Capricorncd 2017 */ // 方法封装 var cap = function () { // 预加载图片 var LOADING_IMG = 'http://xmqvip1-1253933147.
本篇文章主要介绍了如何用多层神经网络BP算法做文本垃圾分类。
在多层神经网络BP算法里面,最核心的部分其实就是梯度下降。梯度下降的方法有很多种,这里使用的是感知机(Perceptions);当然还有其它的一些方法,例如RBF和Adaline两个梯度下降的方法。
之后我会写出两个python的脚本,一个是模块脚本,用来被调用的;另外一个是测试脚本,用来训练和测试用的。
这个部分是nn.py的模块,之后会调用里面的方程。
# -*- coding: utf-8 -*- """ Created on Sat Aug 19 17:14:07 2017 @author: CHEN Ming """ from numpy import tanh,multiply,unique,zeros,sign def mlp_test(x,W1,W2): z = tanh(W1*(x.T)) y = tanh(W2*z) return y,z def errorSample(yd,y): err = (yd-y) return err # 梯度下降 def backprop(W1,W2,err,x,yp,z,eta): delta2 = multiply(-err,(1-multiply(yp,yp))) delta1 = multiply( (W2*(delta2.tolist()[0][0])).T,(1-multiply(z,z)) ) W2 = W2-eta*delta2*(z.T) W1 = W1-eta*delta1*x; return W1,W2 # 只设置最大循环次数 def mlp(W1,W2,x,y,eta,maxIter): nbIter = 0 while nbIter<maxIter: nbIter = nbIter+1 for i in range(0,len(x)): ya,za = mlp_test(x[i,:],W1,W2) err = errorSample(y[i],ya) W1,W2 = backprop(W1,W2,err,x[i,:],ya,za,eta) taux = "
[20170828]grep过滤技巧.txt
--//经常使用grep过滤显示信息.
# ps -ef |grep oraagent oracle 13416 1 0 2016 ? 1-20:48:04 /u01/app/11.2.0.4/grid/bin/oraagent.bin grid 17423 1 0 2014 ? 2-03:32:14 /u01/app/11.2.0.4/grid/bin/oraagent.bin grid 21718 1 0 2014 ? 1-16:45:43 /u01/app/11.2.0.4/grid/bin/oraagent.bin root 87599 66070 0 09:38 pts/0 00:00:00 grep oraagent
--//这样有一个小小的遗憾,把执行grep oraagent信息也带了出来,许多人常用的方法是 # ps -ef |grep oraagent | grep -v grep oracle 13416 1 0 2016 ? 1-20:48:05 /u01/app/11.2.0.4/grid/bin/oraagent.bin grid 17423 1 0 2014 ? 2-03:32:15 /u01/app/11.2.0.4/grid/bin/oraagent.bin grid 21718 1 0 2014 ?
将数字转化成时间格式
from dateutil.parser import parse a=20170825 b=str(a) c=parse(b) print(c) 2017-08-25 00:00:00 将时间按照天排列,转化为一个数字,用来做时间序列分析
from matplotlib.pylab import date2num e = date2num(c) e Out[30]: 736566.0 将时间转化为时间戳
d=str(c) d Out[25]: '2017-08-25 00:00:00' from matplotlib.pylab import date2num timeArray = time.strptime(d, "%Y-%m-%d %H:%M:%S") timeArray Out[27]: time.struct_time(tm_year=2017, tm_mon=8, tm_mday=25, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=4, tm_yday=237, tm_isdst=-1) timestamp = time.mktime(timeArray) timestamp Out[29]: 1503590400.0
<style name="CustomDialogStyle" parent="@android:style/Theme.Dialog"> <item name="android:windowBackground">@android:color/transparent</item> <item name="android:windowNoTitle">true</item> <item name="android:backgroundDimEnabled">true</item> </style>关键是最后一个属性android:backgroundDimEnabled,设置为true时候,整个Dialog的大背景就是半透明的黑色,如果设置为false就是全透明。
<font color=‘darkgreen’,size=4.5> 优雅的增加一行,一定要优雅!
df=DataFrame(np.arange(16).reshape((4,4)),index=['a','b','c','d'],columns=['one','two','three','four']) df.loc['new_raw'] = '3' df Out[84]: one two three four a 0 1 2 3 b 4 5 6 7 c 8 9 10 11 d 12 13 14 15 new_raw 3 3 3 3 <font color=‘green’,size=4.5> 优雅的增加一列,一定要优雅!
df['new_colu']='12'#向 DataFrame 添加一列,该列为同一值 df Out[93]: one two three four new_colu a 0 1 2 3 12 b 4 5 6 7 12 c 8 9 10 11 12 d 12 13 14 15 12 new_raw 3 3 3 3 12
Centos系统添加多个IP,把新的IP添加绑定到网卡 vi /etc/sysconfig/network-scripts/ifcfg-eth0:1 DEVICE=eth0:1 ONBOOT=yes BOOTPROTO=static IPADDR=新增IP NETMASK=子网掩码 GATEWAY=网关地址 最后service network restart
http://blog.csdn.net/LEON1741/article/details/72846434
搞嵌入式开发和ARM开发搞了半辈子了,调试程序是不可避免的。接触了那么多的调试规范、调试工具、调试手段,彼此之间的关系却也不是特别清楚,今天就来捋一捋:
JTAG协议
JTAG(Joint Test Action Group,联合测试行动小组)是一种国际标准测试协议(IEEE 1149.1兼容),主要用于芯片内部测试。现在多数的高级器件都支持JTAG协议,如ARM、DSP、FPGA器件等。标准的JTAG接口是4线:TMS、 TCK、TDI、TDO,分别为模式选择、时钟、数据输入和数据输出线。 相关JTAG引脚的定义为:
TMS:测试模式选择,TMS用来设置JTAG接口处于某种特定的测试模式;TCK:测试时钟输入;TDI:测试数据输入,数据通过TDI引脚输入JTAG接口;TDO:测试数据输出,数据通过TDO引 脚从JTAG接口输出; JTAG协议在定义时,由于当时的计算机(PC机)普遍带有并口,因而在连接计算机端是定义使用的并口。而计算机到了今天,不要说笔记本电脑,现在台式计算机上面有并口的都很少了,取而代之的是越来越多的USB接口。所以,目前市场上已经很少看到它的身影了。
SWD接口
串行调试(Serial Wire Debug),应该可以算是一种和JTAG不同的调试模式,使用的调试协议也应该不一样,所以最直接的体现在调试接口上,与JTAG的20个引脚相比,SWD只需要4个(或者5个)引脚,结构简单,但是使用范围没有JTAG广泛,主流调试器上也是后来才加的SWD调试模式。
SWD和传统的调试方式区别:
SWD模式比JTAG在高速模式下面更加可靠。在大数据量的情况下面JTAG下载程序会失败,但是SWD发生的几率会小很多。基本使用JTAG仿真模式的情况下是可以直接使用SWD模式的,只要你的仿真器支持,所以推荐大家使用这个模式。在大家GPIO刚好缺一个的时候,可以使用SWD仿真,这种模式支持更少的引脚。在大家板子的体积有限的时候推荐使用SWD模式,它需要的引脚少,当然需要的PCB空间就小啦!比如你可以选择一个很小的2.54间距的5芯端子做仿真接口。 RDI接口
远程调试接口(Remote Debug Interface),是ARM公司提出的标准调试接口,主要用于ARM芯片的仿真,由于各个IDE厂商使用的调试接口各自独立,硬件无法进行跨平台的调试。现在众多的IDE厂家都逐步采用标准RDI作为ARM仿真器的调试接口,因此使跨平台的硬件调试成为可能。EasyJTAG由于使用标准RDI调试接口,因此在任何使用标准RDI接口的IDE调试环境中都可以使用,例如ARM公司的ADS1.2/IAR公司的EWARM 3.30 。
JLink仿真器
J-Link是德国SEGGER公司推出基于JTAG的仿真器。简单地说,是给一个JTAG协议转换盒,即一个小型USB到JTAG的转换盒,其连接到计算机用的是USB接口,而到目标板内部用的还是jtag协议。它完成了一个从软件到硬件转换的工作。
JLINK是一个通用的开发工具,可以用于KEIL、IAR、ADS 等平台。速度,效率,功能都很好,据说是众多仿真器里最强悍的。
ULink仿真器
ULINK是ARM/KEIL公司推出的仿真器,目前网上可找到的是其升级版本,ULINK2和ULINK Pro仿真器。ULINK/ULINK2可以配合Keil软件实现仿真功能,并且仅可以在Keil软件上使用,增加了串行调试(SWD)支持,返回时钟支持和实时代理等功能。开发工程师通过结合使用RealView MDK的调试器和ULINK2,可以方便的在目标硬件上进行片上调试(使用on-chip JTAG,SWD和OCDS)、Flash编程。
但是要注意的是,ULINK是KEIL公司开发的仿真器,专用于KEIL平台下使用,ADS、IAR下不能使用。
ST-Link仿真器
ST-LINK是专门针对意法半导体STM8和STM32系列芯片的仿真器。ST-LINK /V2指定的SWIM标准接口和JTAG / SWD标准接口,其主要功能有:
编程功能:可烧写FLASH ROM、EEPROM、AFR等;仿真功能:支持全速运行、单步调试、断点调试等各种调试方法,可查看IO状态,变量数据等;仿真性能:采用USB2.0接口进行仿真调试,单步调试,断点调试,反应速度快;编程性能:采用USB2.0接口,进行SWIM / JTAG / SWD下载,下载速度快;
在机器学习中,我们会利用一些指标(混淆矩阵、精确率、召回率、F1值、准确率)来判断我们模型的好坏,从而改进优化模型。下面介绍如何在TensorFlow下快速计算这些指标。
1、混淆矩阵
confusion_matrix = tf.contrib.metrics.confusion_matrix(labels_pred_all, labels_all, num_classes=None, dtype=tf.int32, name=None, weights=None) confusion_matrix = sess.run(confusion_matrix) 因为第一步所计算出来的混淆矩阵是一个Tensor,所以需要进行转换。
具体api详解:
https://haosdent.gitbooks.io/tensorflow-document/content/api_docs/python/contrib.metrics.html#confusion_matrix
值得注意的是:所计算出来的混淆矩阵,列是真实值(也就是期望值),行是预测值
2、四大指标:
有了混淆矩阵,计算四大指标就好办了。
accu = [0,0,0,0,0] column = [0,0,0,0,0] line = [0,0,0,0,0] accuracy = 0 recall = 0 precision = 0 for i in range(0,5): accu[i] = confusion_matrix[i][i] for i in range(0,5): for j in range(0,5): column[i]+=confusion_matrix[j][i] for i in range(0,5): for j in range(0,5): line[i]+=confusion_matrix[i][j] for i in range(0,5): accuracy += float(accu[i])/len_labels_all for i in range(0,5): if column[i] !
之前参照:http://blog.csdn.net/kimmking/article/details/17505637
遇到的情况情况很相似
通过核心HttpURLConnection连接当前新开发的医疗系统,由于当前conn方法已经连接过其他旧系统,没有问题;
当连接此系统时发现问题,新系统中用request.getInputStream()接受数据流都是NULL
之前考虑到是由于Shiro或者什么之类的拦截导致;
幸好找到这篇文章,可以解决
今天发现一个很奇怪的问题,我们系统里用REST方式做前后端的访问,具体就是所有的请求都是POST,URL对应处理的action,HTTP body里的json是请求参数;后端程序里从Request.getReader拿到json参数,然后调用相应的action来处理。有一个登陆接口,在页面ajax和Android里请求是正常的,但是在iphone里请求出错。调试了下,发现request.getReader拿不到数据。
通过tcpmon代理查看HTTP请求报文,对比下正确和错误的REST请求,感觉最大的问题可能是出现在Content-type上,进而发现application/x-www-form-urlencoded时,会出现这个问题,但是text/html,text/xml等格式都没有问题。这就能确定是Content-Type引起的了。
为什么Content-Type会引起这个问题呢?
我们知道request.getInputStream\getReader,都只能调用一次,调用过了,buffer里的数据就没有了。而request.getParameterXX方法也可能会解析buffer,如果这个调用过了,再调用getReader也会没有数据了。难道Content-Type不同的时候导致调用了这个?
调试下,追了追shiro和tomcat的代码,发现果然如此。
请求进来先进过shiro的filter,filter里试图拿到当前subject,先从cookie试着拿sessionId,不行就从URL中试着拿sessionId,还没有的话就从request.getParameter里获取sessionId,这里调用到了tomcat的request.getParameter实现:如果Content-Type是multipart/form-data或者application/x-www-form-urlencoded,则直接解析http body……问题就出现了。
简单的说就是,如果请求是application/x-www-form-urlencoded格式的话,shiro的filter在我们的servlet或action处理之前,就可能直接把request的body给读取并清空了。
通过这个实现我们也可以看到:除了这两个Content-Type之外的格式都不会有问题,登陆后sessionId放到cookie里了也不会有问题。
按理讲,我们用json应该手动设置Content-Type:application/json;因为application/x-www-form-urlencoded就是为了在body里使用类似QueryString的key-value格式。所以写代码的时候要注意了,如果某些HTTP库的实现里,默认POST是form格式的,如果你要自己处理HTTP body就需要手工的设置自己想要的Content-Type了。
知道怎么回事了,就很好处理了。在xcode里,将Content-Type改成text/html或application/json即可。
进一步的来看,shiro处理考虑到sessionId在cookie和url里,还考虑到一种情况:session藏在页面form的hidden里,通过form的post方式,把key-value作为http body来post到服务器端,shiro可能通过解析httpbody拿到sessionId,这个对session来说用处不大,因为我们一般都放到cookie或url的jsessionId里,但是对于某些需要自己处理http body的场景,shiro的filter显然破坏掉了后续对body的request.getReader读取。
处理机字长是指处理机能同时处理(或运算)的位数,即同时处理多少位(bit)数据。比如Intel Pentium 4处理器字长为32位,它能同时处理32位的数据,也即它的数据总线为32位。以前的处理器比如8086,则为16位处理器,现在新兴的64位处理器,它的数据吞吐能力更强,即能同时对64位数据进行运算。处理器的字长越大,说明它的运算能力越强。如果讲处理器的寻址范围,则要看处理器的地址总线的位数,而不是它的字长!这个要明白!比如Intel Pentium 4处理器的数据总线为32位,地址总线也是32位。8086的数据总线为16位,地址总线为20位。新兴的64位处理器的数据总线为64位,地址总线大部分是32位。这个清楚之后,再看地址总线与寻址范围的关系。存储单元是以字节(byte)为单位,N根地址总线能访问2的N次方个存储单元。于是有32位地址总线可以访问2的32次方个存储单元,即4GB。 8086处理器字长是16位,它的地址总线是20位,所以能访问2的20次方个存储单元,即1MB。 另外一点需要注意的就是,如果有些题目说:按“字”寻址,就说明是存储单元大小为字长的位数,按“字节”寻址,说明存储单元式字节的大小 。
转载请注明作者和出处:http://blog.csdn.net/c406495762 Github代码获取:https://github.com/Jack-Cherish/Machine-Learning/ 机器学习知乎专栏:https://zhuanlan.zhihu.com/ml-jack Python版本: Python3.x 运行平台: Windows IDE: Sublime text3
一 前言二 朴素贝叶斯改进之拉普拉斯平滑三 朴素贝叶斯之过滤垃圾邮件 收集数据准备数据 四 朴素贝叶斯之新浪新闻分类Sklearn 中文语句切分文本特征选择使用Sklearn构建朴素贝叶斯分类器 五 总结 一 前言 上篇文章Python3《机器学习实战》学习笔记(四):朴素贝叶斯基础篇之言论过滤器讲解了朴素贝叶斯的基础知识。本篇文章将在此基础上进行扩展,你将看到以下内容:
拉普拉斯平滑垃圾邮件过滤新浪新闻分类 二 朴素贝叶斯改进之拉普拉斯平滑 上篇文章提到过,算法存在一定的问题,需要进行改进。那么需要改进的地方在哪里呢?利用贝叶斯分类器对文档进行分类时,要计算多个概率的乘积以获得文档属于某个类别的概率,即计算p(w0|1)p(w1|1)p(w2|1)。如果其中有一个概率值为0,那么最后的成绩也为0。我们拿出上一篇文章的截图。
从上图可以看出,在计算的时候已经出现了概率为0的情况。如果新实例文本,包含这种概率为0的分词,那么最终的文本属于某个类别的概率也就是0了。显然,这样是不合理的,为了降低这种影响,可以将所有词的出现数初始化为1,并将分母初始化为2。这种做法就叫做拉普拉斯平滑(Laplace Smoothing)又被称为加1平滑,是比较常用的平滑方法,它就是为了解决0概率问题。
除此之外,另外一个遇到的问题就是下溢出,这是由于太多很小的数相乘造成的。学过数学的人都知道,两个小数相乘,越乘越小,这样就造成了下溢出。在程序中,在相应小数位置进行四舍五入,计算结果可能就变成0了。为了解决这个问题,对乘积结果取自然对数。通过求对数可以避免下溢出或者浮点数舍入导致的错误。同时,采用自然对数进行处理不会有任何损失。下图给出函数f(x)和ln(f(x))的曲线。
检查这两条曲线,就会发现它们在相同区域内同时增加或者减少,并且在相同点上取到极值。它们的取值虽然不同,但不影响最终结果。因此我们可以对上篇文章的trainNB0(trainMatrix, trainCategory)函数进行更改,修改如下:
""" 函数说明:朴素贝叶斯分类器训练函数 Parameters: trainMatrix - 训练文档矩阵,即setOfWords2Vec返回的returnVec构成的矩阵 trainCategory - 训练类别标签向量,即loadDataSet返回的classVec Returns: p0Vect - 侮辱类的条件概率数组 p1Vect - 非侮辱类的条件概率数组 pAbusive - 文档属于侮辱类的概率 Author: Jack Cui Blog: http://blog.csdn.net/c406495762 Modify: 2017-08-12 """ def trainNB0(trainMatrix,trainCategory): numTrainDocs = len(trainMatrix) #计算训练的文档数目 numWords = len(trainMatrix[0]) #计算每篇文档的词条数 pAbusive = sum(trainCategory)/float(numTrainDocs) #文档属于侮辱类的概率 p0Num = np.
丢失更新 两个人(甲和乙)同时读取一个数据,甲修改完数据并写回数据库。接着乙也修改数据并写回数据库。导致甲的修改被覆盖
读脏数据 甲修改了数据,乙读取甲修改后的数据,但由于某种原因甲撤销事务。导致乙读取的数据不正确
不可重复读 事务1读取数据后,事务2执行更新操作,使事务1无法再现前一次读取结果。或者说一个事务里读两遍,读出来的值不一致.第二次读到其他事务提交的结果
幻读 事务1读的过程之中,另外一个事务2往表里插了一条新数据,影响事务1的读取结果。与不可重复读的区别是不可重复读的重点是修改,幻读的重点在于新增或者删除记录,读出来的记录数不一样。从结果上看,不可重复读和幻读差不多。但从控制的角度来看, 两者的区别就比较大。 对于前者, 只需要锁住满足条件的记录。 对于后者, 要锁住满足条件及其相近的记录
之前老是忘记数据库事务的ACID特性,说到底还的归结与理解不够深入,这次用自己的话把数据库的ACID特性描述出来,加深理解。 什么是数据库事务? 用户定义的一个数据库操作序列。
数据库的ACID分别指:原子性、一致性、隔离性、持续性
原子性: 一个事务的对数据库的操作要么全做,要么全不做
一致性: 数据库的数据不会因为事务的执行而受到破坏。这个比较不好理解,比如银行存款和取款只差应该等于余额,如果存款或取款时不修改余额,数据库处于不一致的状态。这个性质又编写事务的程序员完成。
隔离性: 一个事务的执行不能被其它事务干扰,多个事务并发执行额结果和这些事务单独执行的结果一样。
持续性: 指提交的事务对数据的改变是永久的
@RunWith(SpringJUnit4ClassRunner.class) // 整合 @ContextConfiguration(locations = {"classpath:spring/application*.xml"}) // 加载配置 @TransactionConfiguration(transactionManager = "transactionManager") @Transactional public class UserServiceTest { /**(被注入的对象) * 该注解的对象也被mock了,(一般情况下)除了@mock的对象能注入, * 在UserServiceImpl类内部的其他@Autowired属性都为null */ @InjectMocks UserServiceImpl userService = mock(UserServiceImpl.class); /** * 注入到UserServiceImpl中,也就是注入到@InjectMocks标注的对象 */ @Mock private UserApiService userApiService; /** *因为该属性不需要被mock,但单元测试需要调用到该对象的方法,因此需要执行 * ReflectionTestUtils.setField( * AopTargetUtils.getTarget(userService),"wechatApiService",wechatApiService); * 来为userService对象设置属性 * (@Reference和@Autowired同类型) */ @Reference private WechatApiService wechatApiService; String userId = "asdfasdfasdfasdf"; @Before public void setUp() throws Exception { MockitoAnnotations.initMocks(this); //构造数据 UserResultDto userResultDto = new UserResultDto(); userResultDto.setUsername("hello"); userResultDto.
1、操作测试对象
前面讲到了不少知识都是定位元素,定位只是第一步,定位之后需要对这个元素进
行操作。鼠标点击或者键盘输入,这要取决于我们定位的是按钮还输入框。
一般来说,webdriver 中比较常用的操作对象的方法有下面几个
click 点击对象send_keys 在对象上模拟按键输入clear 清除对象的内容,如果可以的话submit 清除对象的内容,如果可以的话text 用于获取元素的文本信息 1.1 、鼠标点击与键盘输入
在我们本系列开篇的第一个例子里就用到了到 click 和 send_skys ,
coding=utf-8 from selenium import webdriver import time driver = webdriver.Firefox() driver.get("http://www.baidu.com") driver.find_element_by_id("kw").clear() driver.find_element_by_id("kw").send_keys("selenium") time.sleep(2) #通过 submit() 来操作 driver.find_element_by_id("su").submit() time.sleep(3) driver.quit() send_keys("xx") 用于在一个输入框里输入 xx 内容。
click() 用于点击一个按钮。
clear() 用于清除输入框的内容,比如百度输入框里默认有个“请输入关键
字”的信息,再比如我们的登陆框一般默认会有“账号”“密码”这样的默认信息。
clear 可以帮助我们清除这些信息。
1.2 、submit 提交表单
我们把“百度一下”的操作从 click 换成 submit 可以达到相同的效果:
#coding=utf-8 from selenium import webdriver import time driver = webdriver.Firefox() driver.get("http://www.baidu.com") driver.find_element_by_id("kw").send_keys("selenium") time.
本系列文章为原创,转载请注明出处。 作者:Dongdong Bai 邮箱: baidongdong@nudt.edu.cn
若您觉得本博文对您有帮助,请您为我点赞并关注我,以鼓励我写出更优秀的博文。谢谢!
Eigen: C++开源矩阵计算工具——Eigen的简单用法
Eigen库是一个开源的C++线性代数库,它提供了快速的有关矩阵的线性代数运算,还包括解方程等功能。Eigen是一个用纯头文件搭建起来的库,这意味这你只要能找到它的头文件,就能使用它。Eigen头文件的默认位置是“/usr/include/eigen3”.
由于Eigen库相较于OpenCV中的Mat等库而言更加高效,许多上层的软件库也使用Eigen进行矩阵运算,比如SLAM中常用的g2o,Sophus等。此外Eigen库还被被用于Caffe,Tensorflow等许多深度学习相关的框架中。
刚体运动中的旋转通常可以由旋转矩阵,旋转向量和四元数等多种方式表示(具体的转换公式请参见这篇博客),在Eigen库中也有其对应的实现。本文主要介绍刚体运动时旋转矩阵,旋转向量和四元数的初始化以及相互转换在Eigen中的实现方式。 Eigen库中各种形式的表示如下:
旋转矩阵(3X3):Eigen::Matrix3d 旋转向量(3X1):Eigen::AngleAxisd 四元数(4X1):Eigen::Quaterniond 平移向量(3X1):Eigen::Vector3d 变换矩阵(4X4):Eigen::Isometry3d 以下是具体的实现代码eigen_geometry.cpp:
#include <iostream> #include <Eigen/Dense> using namespace std; using namespace Eigen; int main(int argc, char **argv) { //下面三个变量作为下面演示的中间变量 AngleAxisd t_V(M_PI / 4, Vector3d(0, 0, 1)); Matrix3d t_R = t_V.matrix(); Quaterniond t_Q(t_V); //对旋转向量(轴角)赋值的三大种方法 //1.使用旋转的角度和旋转轴向量(此向量为单位向量)来初始化角轴 AngleAxisd V1(M_PI / 4, Vector3d(0, 0, 1));//以(0,0,1)为旋转轴,旋转45度 cout << "Rotation_vector1" << endl << V1.matrix() << endl; //2.使用旋转矩阵转旋转向量的方式 //2.1 使用旋转向量的fromRotationMatrix()函数来对旋转向量赋值(注意此方法为旋转向量独有,四元数没有) AngleAxisd V2; V2.
SCSS 笔记 内容来自 sass语法总结
编译 使用gulp-sass自动化编译 Gulp 配置 Sass 编译的示例代码:
var gulp = require('gulp'); var sass = require('gulp-sass'); gulp.task('sass', function () { gulp.src('./scss/*.scss') .pipe(sass({outputStyle: 'compressed'})) .pipe(gulp.dest('./css')); }); gulp.task('watch', function() { gulp.watch('scss/*.scss', ['sass']); }); gulp.task('default', ['sass','watch']); 编译错误 要用UTF-8文件路径及文件名不要用中文 输出方式 outputStyle的值可为:
1. 嵌套输出方式 nested
nav ul { margin: 0; padding: 0; list-style: none; } nav li { display: inline-block; } nav a { display: block; padding: 6px 12px; text-decoration: none; } 2.
一般网页上传文件大家都会用到这个标签
<input type="file" id="file_input"/> 我们可以通过这个标签选取文件,使用js进行文件上传等操作,同时,该标签同时可以选取多个文件
<input type="file" id="file_input" multiple="multiple" /> 但有些时候,进行其他操作的时候,用户需要获得文件夹路径,那么这种写法可以用该标签选取文件夹
<input type="file" id="file_input" webkitdirectory directory />
环境 Mac
安装expect brew install expect 使用 传参 # 表示获取执行脚本命名空格后第一个参数 set user [lindex $argv 0] 实际应用例子 ssh自动登录 #!/usr/bin/expect set user root set ipaddress 120.76.xx.xx set passwd xxx set timeout 30 spawn ssh $user@$ipaddress expect { "*password:" { send "$passwd\r" } "yes/no" { send "yes\r";exp_continue } } interact 或
#!/usr/bin/expect -f spawn ssh -p 22 developer@120.76.103.192 expect "*password:" send "Sound318\r" interact #操作完成 scp传输例子
#!/usr/bin/expect set user root set user host set pwd 123pwd set from_path 120.
转载请注明作者和出处: http://blog.csdn.net/c406495762
运行平台: Windows
Python版本: Python3.x
IDE: Sublime text3
文章目录 一 前言二 朴素贝叶斯理论1 贝叶斯决策理论2 条件概率3 全概率公式4 贝叶斯推断5 朴素贝叶斯推断 三 动手实战四 总结 一 前言 朴素贝叶斯算法是有监督的学习算法,解决的是分类问题,如客户是否流失、是否值得投资、信用等级评定等多分类问题。该算法的优点在于简单易懂、学习效率高、在某些领域的分类问题中能够与决策树、神经网络相媲美。但由于该算法以自变量之间的独立(条件特征独立)性和连续变量的正态性假设为前提,就会导致算法精度在某种程度上受影响。
本篇文章将从朴素贝叶斯推断原理开始讲起,通过实例进行辅助讲解。最后,使用Python3编程实现一个简单的言论过滤器。
二 朴素贝叶斯理论 朴素贝叶斯是贝叶斯决策理论的一部分,所以在讲述朴素贝叶斯之前有必要快速了解一下贝叶斯决策理论。
1 贝叶斯决策理论 假设现在我们有一个数据集,它由两类数据组成,数据分布如下图所示:
我们现在用p1(x,y)表示数据点(x,y)属于类别1(图中红色圆点表示的类别)的概率,用p2(x,y)表示数据点(x,y)属于类别2(图中蓝色三角形表示的类别)的概率,那么对于一个新数据点(x,y),可以用下面的规则来判断它的类别:
如果p1(x,y) > p2(x,y),那么类别为1如果p1(x,y) < p2(x,y),那么类别为2 也就是说,我们会选择高概率对应的类别。这就是贝叶斯决策理论的核心思想,即选择具有最高概率的决策。已经了解了贝叶斯决策理论的核心思想,那么接下来,就是学习如何计算p1和p2概率。
2 条件概率 在学习计算p1和p2概率之前,我们需要了解什么是条件概率(Condittional probability),就是指在事件B发生的情况下,事件A发生的概率,用P(A|B)来表示。
根据文氏图,可以很清楚地看到在事件B发生的情况下,事件A发生的概率就是P(A∩B)除以P(B)。
因此,
同理可得,
所以,
即
这就是条件概率的计算公式。
3 全概率公式 除了条件概率以外,在计算p1和p2的时候,还要用到全概率公式,因此,这里继续推导全概率公式。
假定样本空间S,是两个事件A与A’的和。
上图中,红色部分是事件A,绿色部分是事件A’,它们共同构成了样本空间S。
在这种情况下,事件B可以划分成两个部分。
即
在上一节的推导当中,我们已知
所以,
这就是全概率公式。它的含义是,如果A和A’构成样本空间的一个划分,那么事件B的概率,就等于A和A’的概率分别乘以B对这两个事件的条件概率之和。
将这个公式代入上一节的条件概率公式,就得到了条件概率的另一种写法:
4 贝叶斯推断 对条件概率公式进行变形,可以得到如下形式:
我们把P(A)称为"先验概率"(Prior probability),即在B事件发生之前,我们对A事件概率的一个判断。
P(A|B)称为"后验概率"(Posterior probability),即在B事件发生之后,我们对A事件概率的重新评估。
P(B|A)/P(B)称为"可能性函数"(Likelyhood),这是一个调整因子,使得预估概率更接近真实概率。
所以,条件概率可以理解成下面的式子:
后验概率 = 先验概率 x 调整因子 这就是贝叶斯推断的含义。我们先预估一个"
解决小目标检测问题的一般方法:提高输入图像的分辨率,会增加运算量;多尺度特征表示,结果不可控。 方法提出 论文使用感知生成式对抗网络(Perceptual GAN)提高小物体检测率,generator将小物体的poor表示转换成super-resolved的表示,discriminator与generator以竞争的方式分辨特征。Perceptual GAN挖掘不同尺度物体间的结构关联,提高小物体的特征表示,使之与大物体类似。包含两个子网络,生成网络和感知分辨网络。生成网络是一个深度残差特征生成模型,通过引入低层精细粒度的特征将原始的较差的特征转换为高分变形的特征。分辨网络一方面分辨小物体生成的高分辨率特征与真实大物体特征,另一方面使用感知损失提升检测率。在交通标志数据库Tsinghua-Tencent 100k及Caltech上实验。
Perceptual GAN 1. 概述 目标函数: G标识生成器,D是分辨器。训练G的过程,最大化D犯错的概率。x,z是大物体,小物体的表示。学习G将小物体的标识转换为超分辨的形式,使之类似于大目标的特征。由于信息的缺乏,这个过程比较困难。引入附加信息,学习大物体和小物体见的残差表示,即, 分辨器有两个分支,对抗分支分辨生成的小物体特征与实际大物体特征,感知分支解释生成表示的检测率增益。使用交替的方式优化生成器和分辨器网络的参数,解决对抗min-max问题。训练对抗网分支最大化分配相同标签给小物体生成特征和大物体特征的概率。分辨网络是为了尽可能的找出小物体生成特征和实际大物体特征的不同。这样监督生成网络生成更接近实际的小物体特征。Perceptual GAN总体结构如下图所示: 将物体分为大物体和小物体两个子集,感知分支先在大物体特征上训练,获得较高的检测率,然后使用小物体训练生成网络,两个子集对抗分支。交替训练生成网络和对抗分支,达到平衡点。 2. 生成网络 深度残差网络,增强小物体标识,生成器将conv1的输出作为输入,经历卷积,残差块学习大物体和小物体间的残差表示,学到的残差标识与原con5特征元素加操作,得到提升的表示。 3. 分辨网络结构 实验结果 与Faster-rcnn相比,小物体检测率确实提高很多,期待源码 生成网络生存的特征