首页 文章 精选 留言 我的

精选列表

搜索[快速入门],共10000篇文章
优秀的个人博客,低调大师

liunx入门知识总结

了解以下Linux下的重要目录/proc, /sys, /SElinux, /bin, /usr/lib, /usr/local, /var, /tmp : /proc 此目录的数据都在内存中,如系统核心,外部设备,网络状态,由于数据都存放于内存中,所以不占用磁盘空间,比较重要的目录有/proc/cpuinfo、/proc/interrupts、/proc/dma、/proc/ioports、/proc/net/*等 /sys 文件系统访问 Linux内核 /SELinux SELinux是一种基于域-类型模型(domain-type)的强制访问控制(MAC)安全系统,它由NSA编写并设计成内核模块包含到内核中,相应的某些安全相关的应用也被打了SELinux的补丁,最后还有一个相应的安全策略。 /bin /usr/bin: 可执行二进制文件的目录,如常用的命令ls、tar、mv、cat等。 /usr 应用程序存放目录,/usr/bin 存放应用程序, /usr/share 存放共享数据,/usr/lib 存放不能直接运行的,却是许多程序运行所必需的一些函数库文件。/usr/local:存放软件升级包。/usr/share/doc: 系统说明文件存放目录。/usr/share/man: 程序说明文件存放目录,使用 man ls时会查询/usr/share/man/man1/ls.1.gz的内容建议单独分区,设置较大的磁盘空间 /usr/lib /usr/lib:/usr/local/lib: 系统使用的函数库的目录,程序在执行过程中,需要调用一些额外的参数时需要函数库的协助,比较重要的目录为/lib/modules。 /usr/local 这里主要存放那些手动安装的软件,即不是通过“新立得”或apt-get安装的软件。它和/usr目录具有相类似的目录结构。让软件包管理器来管理/usr目录,而把自定义的脚本(scripts)放到/usr/local目录下面。 /var 放置系统执行过程中经常变化的文件,如随时更改的日志文件 /var/log,/var/log/message: 所有的登录文件存放目录,/var/spool/mail: 邮件存放的目录, /var/run: 程序或服务启动 /tmp 一般用户或正在执行的程序临时存放文件的目录,任何人都可以访问,重要数据不可放置在此目录下 重要命令. du, df, top, free, pstack, su, sudo(sudo -, sudo -s), adduser, password 1.du命令:du [选项] 文件 (1)功能该命令是显示指定文件以及下的所有文件占用系统数据块的情况,如果没有文件,默认为是当前工作目录 -a 显示所有文件对系统数据块的使用情况 -b 显示数据块大小时以字节为基本单位 -c 除了显示文件对系统数据块的使用情况外还显示出文件的总和 -s 只显示文件数据块总大小,不显示文件名 -x 只显示当前目录,但不统计子目录 2.df命令:du [选项] 文件名 (1)功能该命令与du命令相似,只不过是df计算的是当前文件所以数据快的使用情况(包括前不久删除的文件),而du只是计算当前存在的所有文件的数据快的使用情况 -a 递归显示各文件及其子目录的数据块利用 -h 方便阅读时显示 -H 和-h一样,只不过1k = 1000;而不是1024 -i 显示inode信息 -k 区块为1024字节 -T 文件系统类型 3.top命令: (1)功能:相当于windows下的资源管理器,可以查看当前CPU的使用情况,各进程的状况 (2)选项 -b 批处理 -I 忽略过失 -c 显示完整的治命令 -s 保密模式 4.free命令 (1)功能:显示所有内存利用率。包括实体内存,虚拟的交换文件内存,共享内存区段,以及系统使用的缓冲区等。 (2)选项 -b 以bype为单位显示 -k 以KB为单位显示 -m 以MB为单位显示 -o 不显示缓冲区 -t 显示内存总和列 5.pstack命令 (1)功能:进程跟踪 6.su命令 (1)功能:切换用户(由root用户向普通用户切换时不需要密码,由普通用户向root用户切换时需要密码) 6.password命令用来修改用户命令,但需要注意,root用户可以修改任何用户的密码,但普通用户只能修改自己的密码(这里涉及s权限的相关知识)。

优秀的个人博客,低调大师

Mycat(入门篇)

Mycat是什么 Mycat是一款基于阿里开源产品Cobar而研发的开源数据库分库分表中间件(基于Java语言开发)。官网所言:Mycat国内最活跃的、性能最好的开源数据库中间件! 一个彻底开源的,面向企业应用开发的大数据库集群 支持事务、ACID、可以替代MySQL的加强版数据库 一个可以视为MySQL集群的企业级数据库,用来替代昂贵的Oracle集群 一个融合内存缓存技术、NoSQL技术、HDFS大数据的新型SQL Server 结合传统数据库和新型分布式数据仓库的新一代企业级数据库产品 一个新颖的数据库中间件产品 Mycat关键特性 支持SQL92标准 支持MySQL、Oracle、DB2、SQL Server、PostgreSQL等DB的常见SQL语法 遵守Mysql原生协议,跨语言,跨平台,跨数据库的通用中间件代理 基于心跳的自动故障切换,支持读写分离,支持MySQL主从,以及galera cluster集群 支持Galera for MySQL集群,Percona Cluster或者MariaDB cluster 基于Nio实现,有效管理线程,解决高并发问题 支持数据的多片自动路由与聚合,支持sum,count,max等常用的聚合函数,支持跨库分页 支持单库内部任意join,支持跨库2表join,甚至基于caltlet的多表join 支持通过全局表,ER关系的分片策略,实现了高效的多表join查询 支持多租户方案 支持分布式事务(弱xa) 支持XA分布式事务(1.6.5) 支持全局序列号,解决分布式下的主键生成问题 分片规则丰富,插件化开发,易于扩展 强大的web,命令行监控 支持前端作为MySQL通用代理,后端JDBC方式支持MySQL、PostgreSQL、Oracle、DB2、SQLServer、MongoDB、巨杉 支持密码加密 支持服务降级 支持IP白名单 支持SQL黑名单、sql注入攻击拦截 支持prepare预编译指令(1.6) 支持非堆内存(Direct Memory)聚合计算(1.6) 支持PostgreSQL的native协议(1.6) 支持mysql和oracle存储过程,out参数、多结果集返回(1.6) 支持zookeeper协调主从切换、zk序列、配置zk化(1.6) 支持库内分表(1.6) 集群基于ZooKeeper管理,在线升级,扩容,智能优化,大数据处理(2.0开发版) 安装与使用 下载(目前最新发行版是1.6.5):http://dl.mycat.io/ 安装:解压即可 配置:Mycat是基于Java开发的,确保安装好了Java环境,可命令行输入:java -version 进行测试。Linux下还需配置Mycat的解压目录:vim /etc/profile,配置完成后使用:source /etc/profile: export JAVA_HOME=xxx export MYCAT_HOME=xxx 运行(Linux): ./mycat start 启动 ./mycat stop 停止 ./mycat console 前台运行 ./mycat install 添加到系统自动启动(暂未实现) ./mycat remove 取消随系统自动启动(暂未实现) ./mycat restart 重启服务 ./mycat pause 暂停 ./mycat status 查看启动状态 运行(Windows):双击bin/tartup_nowrap.bat,如果出现闪退,可在cmd命令行运行,并查看出错原因 内存配置:启动前,一般需要修改JVM配置参数,打开conf/wrapper.conf文件,可根据本机配置情况修改为512M或其它值 # Java Additional Parameters #wrapper.java.additional.1= wrapper.java.additional.1=-DMYCAT_HOME=. wrapper.java.additional.2=-server wrapper.java.additional.3=-XX:MaxPermSize=64M wrapper.java.additional.4=-XX:+AggressiveOpts wrapper.java.additional.5=-XX:MaxDirectMemorySize=2G wrapper.java.additional.6=-Dcom.sun.management.jmxremote wrapper.java.additional.7=-Dcom.sun.management.jmxremote.port=1984 wrapper.java.additional.8=-Dcom.sun.management.jmxremote.authenticate=false wrapper.java.additional.9=-Dcom.sun.management.jmxremote.ssl=false wrapper.java.additional.10=-Xmx4G wrapper.java.additional.11=-Xms1G 连接测试: 测试mycat与测试mysql完全一致,mysql怎么连接,mycat就怎么连接 命令行:mysql -uroot -proot -P8066 -h127.0.0.1(其中,user和password可在conf/server.xml配置查找,8066是默认的服务端口,也可以在conf/server.xml中配置修改) 客户端:1.3和1.4版本目前部分工具无法连接,会提示database not selected,建议使用高版本的Mycat,1.5版本已经修复了部分客户端工具的连接 常见分库分表产品对比 分库分表产品 MyCat Sharding-JDBC Cobar Cobar-client TDDL 分库 有 有 有 有 未开源 分表 有 有 无 无 未开源 中间层 是 否 是 否 否 ORM支持 任意 任意 任意 仅MyBatis 任意 数据库支持 任意 任意 仅MySQL 任意 任意 社区情况 活跃 活跃 停更 未知 未知 相关链接 Mycat官网 Mycat从零开始 Mycat权威指南 GitHub:Mycat-Server Wiki:Mycat-Server Issues:Mycat-Server mysql中间件研究(Atlas,Cobar,TDDL) mysql中间件研究(Atlas,Cobar,TDDL,Mycat,Heisenberg,Oceanus,Vitess,OneProxy)

优秀的个人博客,低调大师

JavaScript面向对象入门

什么是JavaScript? 我们可以从几个方面去说JavaScript是什么: 基于对象 javaScript中内置了许多对象供我们使用【String、Date、Array】等等 javaScript也允许我们自己自定义对象 事件驱动 当用户触发执行某些动作的时候【鼠标单机、鼠标移动】,javaScript提供了监听这些事件的机制。当用户触发的时候,就执行我们自己写的代码。 解释性语言 [x] javaScript代码是由浏览器解析的,并不需要编译。 基于浏览器的动态交互技术 既然javaScript是由浏览器解析的,那么它肯定要基于浏览器。 javaScript让网页变得更加“灵活"" 弱类型 [x] 像java、c++等编译型语言,要先定义变量,后使用。javaScript能够直接使用,不需要先定义 JavaScript变量类型 javaScript变量可分为三种类型: 基本类型【number、string、boolean】 javaScript是弱类型语言,在运行的时候才知道具体的类型是什么。所有类型都用var来修饰。 特殊类型【null、undefined】 当定义了变量,没有任何赋值的时候,该变量就是undefined类型 复合类型【数组、对象、函数】 javaScript对象的类型 在JavaScript中对象的类型可分为4种: 内置对象【String、Math、Array】 自定义对象【程序员自己创建的对象】 浏览器对象【windows、document、history、status等等与浏览器相关的对象】 ActiveXObject(XMLHttpRequest)对象【异步对象,使用AJAX用到的对象,使用该对象与服务器进行异步交互】 定义函数三种方式 函数是属于特殊类型的一种,在另外一篇博文已经讲解了创建对象、创建类的几种方式,可参考:http://blog.csdn.net/hon_3y/article/details/69362242 值得注意的是:javaScript定义函数的时候,参数的类型是不用声明的! 正常方式 下面就定义了一个名称为mysum的函数 function mysum(num1,num2){ return num1 + num2; } var myresult = mysum(100,200); alert("myresult="+myresult); Function定义 在JavaScript中, 一切皆是对象,函数也可以用一个对象来代表:Function,我们可以使用Function来创建对象: 函数参数全都是字符串,最后一个字符串是方法体 var youresult = new Function("num1","num2","return num1+num2"); alert( youresult(1000,2000) ); 由于这种方法写起来并不好些,可读性也不太好,因此很少使用【不推荐使用】 匿名创建函数 其实这种和第一种差不多,只不过是将一个无名的函数赋值给一个变量。那么这个变量就代表了这个函数。 var theyresult = function(num1,num2){ return num1 + num2; } alert( theyresult(10000,20000) ); theyresult这个变量就代表了函数。 创建对象 方式① 直接使用new Object() var obj = new Object(); 方式② 使用空的{}大括号 var obj2 = {}; 测试 增加属性,访问属性 我们要为创建的对象增加属性和访问属性的值! 使用.操作符增加属性 JavaScript是弱类型的语言,可以动态的添加属性。 obj.age = 20; obj.name = "zhongfucheng"; obj.say = function () { alert("hello"); }; 测试 使用.操作符访问属性 var aa = obj.age; var bb = obj.name; 测试 使用[]操作符访问属性 var aa = [obj["age"]]; var bb = [obj["name"]]; 测试 创建类 方式① 使用function来模拟创建类,function充当了构造函数 //测试函数 function test() { var teacher = new Teacher(); } //使用function来模拟类 function Teacher() { } 测试 方式② 上面的function来模拟类很容易和函数混淆。 我们一般这样做:用一个变量记住一个匿名的function当做是类,function充当了构造函数 function test() { var teacher = new Teacher(); } var Teacher = function () { }; 测试 方式③ 使用JSON语法来创建类,也就是对象直接量定义方法 var obj = { age: 20, str: "zhongfucheng", method:function () { alert("aaa"); } }; 测试 公有属性和方法 我们创建公有属性应该在类中指定,创建公有方法应该使用原型对象prototype prototype定义的属性就类似于Java的静态成员:在原型对象上定义了属性,拥有这个原型对象的function所创建的对象也拥有定义的属性!所以,我们方法中就使用prototype var obj = function Teacher(name) { this.name = name; if( typeof obj._init=="undefined") { obj.prototype.setName = function (name) { this.name = name; }; obj.prototype.getName = function () { alert(this.name); }; } obj._init = true; }; 创建两个不同的Teacher对象,name属性是不一样的。而它们共享同一份setName()和getName()方法 值得注意的是:prototype定义的属性只可读的。如果你想要使用具体对象写prototype的属性,实际上并不是写,而是重新为该类定义了一个同名(和prototype同名)的属性。在读取同名属性的时候,优先读取对象上的属性,而不是prototype的。 私有属性 我们在Java中,定义私有属性是通过关键字private来修饰的。。 在JavaScript中是没有这样的关键字的,我们需要这样做:定义在方法内【也就是function内部,也可以看作成构造函数】的变量,就是私有变量。 var obj = function Teacher(name) { //这是私有属性,外界不能访问 var age = 23; //这是公有属性,外界可以访问 this.name = name; //想要访问私有变量age,只能在这里编写方法来访问。其余的地方都不行! //我们通常就是在这里编写公有方法来访问私有属性 }; 静态属性和方法 在JavaScript中定义静态属性其实就是通过prototype原型对象来定义的。 定义静态的时机: 当类的某个值与对象无关期望所有位置看到的结果是一样的时候,就可以定义为类静态属性。 如果类的一个方法做的是和具体对象无关的操作,而是做一些工作操作的时候,就可以将这个方法定义为静态的类方法。 //静态属性TYPE Book.TYPE = “IT”; Book.print = function(){alert(Book.TYPE);} JavaScript中的for in循环 在学习AJAX的时候,发现JavaScript中for in循环,这种循环对于遍历JSON是很好用的。于是写下了这篇博文 for in循环本质上是forEach循环,它主要有两个作用 遍历数组 遍历JavaScript对象 遍历数组 当使用for in来遍历数组的时候,它的循环计数器是数组元素的索引值 var a = ['a', 'b', 'c']; for(var index in a) { alert(index); } 效果: 遍历JavaScript对象 当使用for in来遍历对象的时候,它的循环计数器是对象的属性名 //对象json上,包含了两个对象a和b属性 var json = {a:{num:1},b:{num:2}}; for(var name in json){ alert(name); } 效果 JS打气球游戏 在B站中看见了一个JS大气球这么一个教程,才知道原来JS+HTML5+CSS3能那么有趣。但是视频中没并没有给出源码。于是在别人的博客中搜到了对应的源码以及他自己实现的思路,该博主对其进行了改编。 http://www.cnblogs.com/morang/p/7636148.html 以上的博文有源码的下载。下面我就直接贴上源码了。思路就在博文中。 <!DOCTYPE html PUBLIC "-//WAPFORUM//DTD XHTML Mobile 1.0//EN" "http://www.wapforum.org/DTD/xhtml-mobile10.dtd"> <html> <head> <title>气球大战</title> <meta name=viewport content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=0"> <style> /*CSS3能够将气球描绘出来,使用到了圆形、旋转、阴影等技术*/ body{margin:0px;padding:0px;} #ballDiv{position: fixed;top: 0;left: 0;} .balloon{ width:150px; height:150px; position:absolute; left:0px; top:0px; background-color:#f3778d; border-radius:50% 50% 10% 50%; transform:rotate(45deg); box-shadow:1px 1px 20px 20px pink inset; z-index:10; } /*这里使用到了伪元素,可以不用到html中定义元素就可以实现功能了!*/ .balloon:after{ width:20px; height:20px; content:""; display:block; background:transparent; position:absolute; right: -15px; bottom: -15px; border-left:5px solid pink; border-top:5px solid pink; } /*这里使用到了伪元素,可以不用到html中定义元素就可以实现功能了!*/ .balloon:before{ width: 2px; height: 50px; content: ""; display: block; background: #ffc0cb; position: absolute; right: -10px; top: 100%; margin-top: -16px; transform: rotate(-45deg); } </style> </head> <body> <div id="gameinfo" style="transform: translateZ(360px);"> <p> 最高连击:<span id='maxDoubleHit'>0</span> </p> <p> 本次游戏:<span id='currentDoubleHit'>0</span> </p> <p id="gamemsg" style="display:none;"> <span style="color:red;font-weight:bold;"> Game Over </span> <button onclick="javscript:location.reload();"> 重新开始 </button> </p> </div> <div id="ballDiv"> </div> <!--<div class="balloon"></div>--> <script> var maxDoubleHit=localStorage.getItem('eliminateCount')||0 var currentDoubleHit=0 //当做一个缓存池,优化性能的。 var bnElements=[];//存放所有气球 var random=Math.random;//随机函数 var wW=window.innerWidth;//窗口宽度 var wH=window.innerHeight;//窗口高度 var ballW=160;//气球的宽度 var ballH=300;//气球的宽度 var minSpeed=3;//最小速度,每次向上移动至少3px var speedNum=5;//速度的定量 var defBnNumber=5;//初始化气球 var moveTimer; var isEnd=false; var jindex=1; var ballDiv=document.getElementById('ballDiv'); //初始化 init(defBnNumber); //移动 move(); //绑定单击事件 bindClick(); //游戏信息 document.getElementById('maxDoubleHit').innerText=maxDoubleHit function record(){ if(isEnd){ clearTimeout(moveTimer); bnElements=[]; document.getElementById('gamemsg').style.display='block'; document.getElementById('gameinfo').style='transform: translateZ(360px);position: fixed;top:0;left:0;z-index:999'; } else{ init(1); document.getElementById('currentDoubleHit').innerText=++currentDoubleHit; if(currentDoubleHit>maxDoubleHit){ document.getElementById('maxDoubleHit').innerText=currentDoubleHit; localStorage.setItem('eliminateCount',currentDoubleHit) } } } //初始化气球 function init(num){ //创建一个虚拟文档节点 var docFragment=document.createDocumentFragment(); for(var i=0;i<num;i++){ var bnElement=document.createElement('div'); bnElement.className='balloon'; //速度随机,限定最小值 var speed=Math.max(minSpeed,~~(random()*speedNum)); bnElement.setAttribute('speed',speed);//~~取整 移动速度 bnElement.setAttribute('id','ball-'+jindex++); //分散排列 var x=(~~(random()*wW))-ballW; x=Math.max(0,x); bnElement.style.left=x+'px'; bnElement.style.top=wH+'px';//露一点出来 //1.先将创建的气球放入创建的虚拟文档节点 docFragment.appendChild(bnElement); bnElements.push(bnElement); } //2.将虚拟文档节点添加到body中 ballDiv.appendChild(docFragment); } //使用定时器来对气球进行移动。 function move(){ var bl=bnElements.length for(var i=0;i<bl;i++){ var currentElement=bnElements[i] if(currentElement==null){ continue; } var offsetTop=currentElement.offsetTop; if(offsetTop>0){//窗口中 //offset就是针对窗口的位置来进行移动的。 var speed=currentElement.getAttribute('speed'); currentElement.style.top=offsetTop-speed+'px' } else{ //移除dom节点 //ballDiv.removeChild(currentElement); //移除数组中 //bnElements.splice(i,1); //init(1); isEnd=true; record(); } } moveTimer=setTimeout(move,1000/30); } //对所有的气球进行单击监听事件,不要单独为每个气球来进行监听,这样耗费性能! function bindClick(){ ballDiv.addEventListener('click',clickFunc,false); function clickFunc(e){ if(!isEnd && e.target.className=='balloon'){ bnElements.splice(bnElements.lastIndexOf(e.target),1); //这里使用call主动调用,在boom方法中我们就可以使用this指针了。 boom.call(e.target,function(){ e.target.parentNode.removeChild(e.target); record(); }); } } } function boom(callback){ //var that=this; //替换了上下文,但是没有使用this的意义. var speed=this.getAttribute('speed'); this.timer=setInterval(function(){ this.style.opacity=0.1*(speed--) if(speed<1){ callback&&callback(); clearInterval(this.timer); } }.bind(this),30); } </script> </body> </html> 看了视频也学到了之前一直没有注意的东西: CSS3很厉害啊,能将方形的div转成是椭圆形的[也就是气球的形状],还有盒子的阴影设置。 使用伪元素就可以不用直接在html中设置标签了。配合CSS3也能够做出对应的样式。 使用实体边框配合CSS3也可以做出不同的形状样式 在生成元素的时候,可以先将要生成的元素加入到文档片段中,再使用文档片段来进行一次性添加到body上,这样性能会好很多! 使用~~运算符能够取整数 限定气球的边界就可以使用max和min函数来进行限定。这也是很好用的。 移动气球我们需要用到定时器。 使用call主动调用方法,把目标对象传递过去的话,我们就可以使用this指针了。 在定时器中使用bind(this),就可以在定时器中使用this指针的,因为定时器默认是由浏览器window来进行调用的,默认是不能使用this的 绑定单击事件的时候,不要使用循环来进行绑定,这样太耗费性能了,我们可以使用监听事件来进行一次绑定。 在遍历元素数组的时候,条件是元素数组的长度时,我们可以先把该元素数组的长度初始化出来,那么也可以提升性能!不然就每次判断前都要去查询数据的长度! for(var i=0,len = array.length; i<len;i++){} 如果文章有错的地方欢迎指正,大家互相交流。习惯在微信看技术文章,想要获取更多的Java资源的同学,可以关注微信公众号:Java3y 更多的文章可往: 文章的目录导航

优秀的个人博客,低调大师

Python入门:内置函数

可创建一个整数列表,一般用在 for 循环中。 函数语法 range(start, stop[, step]) 参数说明: start: 计数从 start 开始。默认是从 0 开始。例如range(5)等价于range(0, 5); end: 计数到 end 结束,但不包括 end。例如:range(0, 5) 是[0, 1, 2, 3, 4]没有5 step:步长,默认为1。例如:range(0, 5) 等价于 range(0, 5, 1) 示例: >>>range(10) # 从 0 开始到 10 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] >>> range(1, 11) # 从 1 开始到 11 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] >>> range(0, 30, 5) # 步长为 5 [0, 5, 10, 15, 20, 25] >>> range(0, 10, 3) # 步长为 3 [0, 3, 6, 9] >>> range(0, -10, -1) # 负数 [0, -1, -2, -3, -4, -5, -6, -7, -8, -9] >>> range(0) [] >>> range(1, 0) [] for i in range(0,10) # i遍历从0到9 range() 返回对象(字符、列表、元组等)长度或项目个数。 语法 len()方法语法: len( s ) 参数 s -- 对象。 返回值 返回对象长度。 示例 以下实例展示了 len() 的使用方法: >>>str = "runoob" >>> len(str) # 字符串长度 6 >>> l = [1,2,3,4,5] >>> len(l) # 列表元素个数 5 for i in range(len(list)) len() 打印输出 语法 print(*objects, sep=' ', end='\n', file=sys.stdout) 参数 objects -- 复数,表示可以一次输出多个对象。输出多个对象时,需要用 , 分隔。 sep -- 用来间隔多个对象,默认值是一个空格。 end -- 用来设定以什么结尾。默认值是换行符 \n,我们可以换成其他字符串。 file -- 要写入的文件对象。 返回值 无。 示例 以下展示了使用 print 函数的实例: Python3 下测试 >>>print(1) 1 >>> print("Hello World") Hello World >>> a = 1 >>> b = 'runoob' >>> print(a,b) 1 runoob >>> print("aaa""bbb") aaabbb >>> print("aaa","bbb") # 默认空格间隔 aaa bbb >>> >>> print("www","runoob","com",sep=".") # 设置间隔符 www.runoob.com print() 方法对系列进行求和计算。 语法 sum(iterable[, start]) 参数 iterable -- 可迭代对象,如列表。 start -- 指定相加的参数,如果没有设置这个值,默认为0。 返回值 返回计算结果。 示例 以下展示了使用 sum 函数的实例: >>>sum([0,1,2]) 3 >>> sum((2, 3, 4), 1) # 元组计算总和后再加 1 10 >>> sum([0,1,2,3,4], 2) # 列表计算总和后再加 2 12 sum() 返回给定参数的最小值,参数可以为序列。 语法 以下是 min() 方法的语法: min( x, y, z, .... ) 参数 x -- 数值表达式。 y -- 数值表达式。 z -- 数值表达式。 返回值 返回给定参数的最小值。 实例 以下展示了使用 min() 方法的实例: #!/usr/bin/python print "min(80, 100, 1000) : ", min(80, 100, 1000) print "min(-20, 100, 400) : ", min(-20, 100, 400) print "min(-80, -20, -10) : ", min(-80, -20, -10) print "min(0, 100, -400) : ", min(0, 100, -400) 以上实例运行后输出结果为: min(80, 100, 1000) : 80 min(-20, 100, 400) : -20 min(-80, -20, -10) : -80 min(0, 100, -400) : -400 min() 返回给定参数的最大值,参数可以为序列。 语法 以下是 max() 方法的语法: max( x, y, z, .... ) 参数 x -- 数值表达式。 y -- 数值表达式。 z -- 数值表达式。 返回值 返回给定参数的最大值。 示例 以下展示了使用 max() 方法的实例: #!/usr/bin/python print "max(80, 100, 1000) : ", max(80, 100, 1000) print "max(-20, 100, 400) : ", max(-20, 100, 400) print "max(-80, -20, -10) : ", max(-80, -20, -10) print "max(0, 100, -400) : ", max(0, 100, -400) 以上实例运行后输出结果为: max(80, 100, 1000) : 1000 max(-20, 100, 400) : 400 max(-80, -20, -10) : -10 max(0, 100, -400) : 100 max()

优秀的个人博客,低调大师

Google Native Client入门

上午在去往上海的动车组上看到《Google正在测试ActiveX的继任者》这条新闻,因为前段时间一直在做一个证件信息采集的ActiveX控件,而众所周知,ActiveX的安全性是臭名昭著的,所以对这个所谓的“继任者”非常感兴趣,晚上回来后就第一时间试了试。 Native Client项目主页:http://code.google.com/p/nativeclient/ Native Client是一个在Web应用程序中运行本地代码(目前只支持x86架构)的开源的研究性技术,提供更好的“富客户端”用户体验。它允许网络开发者编写更强大的Web程序,这些程序直接通过系统运行而不用通过浏览器来进行,据Google称,它到最后将允许网络开发者开发和桌面软件一样的的web程序,这些程序将带来更快的速度。Native Client类似于微软的ActiveX技术,它还能在Linux和Mac OS X下运行。目前它尚未支持IE,仅支持Google Chrome, Firefox, Safari 和Opera。 本文实验所用OS:Hiweed2.0,官网:http://www.hiweed.com/ 要使它带的示例程序运行为Native Client的模块,你必须要有如下软件:1)Native Client。2)Python(版本在2.4或2.5)。3)一个浏览器(推荐Firefox3) 下面是安装Native Client的步骤: 1,从官网上获取nacl_linux_0.1_9308700.tgz文件,解压缩到你指定的目录下: tar xvf nacl_linux_0.1_9308700.tgz 2,验证Python版本(注意下面的V是大写字母)是2.4或2.5。 python –V 若版本过低或未安装python,则使用下述命令安装: sudo apt-get install python2.4 将示例作为Native Client应用程序来运行 现在来看如何在Native Client中运行一个示例。 1,进入到earth这个demo所在目录 cd install_dir/nacl/googleclient/native_client/tests/earth 2,运行earth这个demo python run.py 结果如图所示,标题“NaCl Application”表明你是在一个特定的进程中运行一个Native Client模块: 安装和使用插件 现在我们切换到浏览器中来运行Native Client模块,我们必须安装Native Client插件,然后把引用这些Native Client模块的页面给加载到浏览器中。 1,进入native_client目录 cd install_dir/nacl/googleclient/native_client 2,若你正在运行firefox,那就关闭它,否则插件可能安装失败。 3,使用如下命令安装插件,在安装过程中回答一个yes ./scons --prebuilt firefox_install Okay to continue? [y/n] y 4,检查最后输出的安装结果,成功的话就去启动firefox 5,在firefox中打开下面这个页面 install_dir/nacl/googleclient/native_client/scons-out/nacl/staging/index.html 这里列出了很多示例,可以自行玩玩。 使用make编译和运行单独的示例(仅限于Linux或Mac) 1,进入到你要编译运行的示例目录下,以earth为例: cd install_dir/nacl/googleclient/native_client/tests/earth 2,重新编译为一个单独的应用程序并运行: make debug run 3,重新编译为一个Native Client模块并运行: make release nacl run 这就是文章最开头显示的realease版本 4,移除掉你自行编译的版本,使用预编译好的版本,和前面两种比较下(其实就是第二种啦)。 make clean python run.py 附:1)Google为了说明这个东西的安全性还发了一篇paper,刚开始看,以后再补上笔记 2)为了方便起见,没有在Windows下测试,有兴趣可按照官方文档试试 3)不知是不是故意捉弄微软,Google推出的这个“ActiveX杀手”竟然在第一时间不支持IE。(哈哈,相信后续会支持的,否则还有啥用?) 参考资料: 1,Native Client Getting Started guide. 2, Building Native Client 本文转自Phinecos(洞庭散人)博客园博客,原文链接:http://www.cnblogs.com/phinecos/archive/2008/12/09/1351378.html,如需转载请自行联系原作者

优秀的个人博客,低调大师

ExtJS 2.0入门指南

开始! 我们将讲讲怎么使用ExtJS,来完成一些JavaScript常见的任务。如果你想自己试试,就应该先下IntroToExt2.zip,用来构建已下面的Ext代码。 Zip包里有三个文件:ExtStart.html,ExtStart.js和ExtStart.css。解包这三个文件到Ext的安装目录中(例如,Ext是在“C:\code\Ext\v2.0”中,那应该在"v2.0"里面新建目录“tutorial”。双击ExtStart.htm,接着你的浏览器打开启动页面,应该会有一条消息告诉你配置已完毕。如果出现了Javascript错误,请按照页面上的指引操作。 现在在你常用的IDE中或文本编辑器中,打开ExtStart.js看看。 Ext.onReady(function(){alert("Congratulations! You have Ext configured correctly!");}); Ext.onReady可能是你接触的第一个也可能是在每个页面都要使用的方法。这个方法会在DOM加载全部完毕后,保证页面内的所有元素能被Script引用(reference)之后调用。你可删除alert()那行,加入一些实际用途的代码试试。 Element:Ext的核心 大多数的JavaScript操作都需要先获取页面上的某个元素的引用(reference),好让你来做些实质性的事情。传统的JavaScript做法,是通过ID获取Dom节点的: var myDiv = document.getElementById('myDiv'); 这毫无问题,不过这样单单返回一个对象(DOM节点),用起来并不是太实用和方便。为了要用那节点干点事情,你还将要手工编写不少的代码;另外,对于不同类型浏览器之间的差异,要处理起来可真头大了。 进入Ext.element 对象。元素(element)的的确确是Ext的心脏地带,--无论是访问元素(elements)还是完成一些其他动作,都要涉及它。Element的API是整个Ext库的基础,如果你时间不多,只是想了解Ext中的一两个类的话,Element一定是首选! 由ID获取一个Ext Element如下(首页ExtStart.htm包含一个div,ID名字为“myDiv”,然后,在ExtStart.js中加入下列语句): Ext.onReady(function(){var myDiv = Ext.get('myDiv');}); 再回头看看Element对象,发现什么有趣的东东呢? Element包含了常见的DOM方法和属性,提供一个快捷的、统一的、跨浏览器的接口(若使用Element.dom的话,就可以直接访问底层DOM的节点。); Element.get()方法提供内置缓存(Cache),多次访问同一对象效率上有极大优势; 内置常用的DOM节点的动作,并且是跨浏览器的定位的位置、大小、动画、拖放等等(add/remove CSS classes, add/remove event handlers, positioning, sizing, animation, drag/drop)。 这意味着你可用少量的代码来做各种各样的事情,这里仅仅是一个简单的例子(完整的列表在Element API 文档中)。 继续在ExtStart.js中,在刚才我们获取好myDiv的位置中加入: myDiv.highlight();//黄色高亮显示然后渐退 myDiv.addClass('red');// 添加自定义CSS类 (在ExtStart.css定义) myDiv.center();//在视图中将元素居中 myDiv.setOpacity(.25);// 使元素半透明 获取多个DOM的节点 通常情况下,想获取多个DOM的节点,难以依靠ID的方式来获取。有可能因为没设置ID,或者你不知道ID,又或者直接用ID方式引用有太多元素了。这种情况下,你就会不用ID来作为获取元素的依据,可能会用属性(attribute)或CSS Classname代替。基于以上的原因,Ext引入了一个异常强大的Dom Selector库,叫做DomQuery。 DomQuery可作为单独的库使用,但常用于Ext,你可以在上下文环境中(Context)获取多个元素,然后通过Element接口调用。令人欣喜的是,Element对象本身便有Element.selcect的方法来实现查询,即内部调用DomQuery选取元素。这个简单的例子中,ExtStart.htm包含若干段落(<p>标签),没有一个是有ID的,而你想轻松地通过一次操作马上获取每一段,全体执行它们的动作,可以这样做: // 每段高亮显示 Ext.select('p').highlight(); Element.select在这个例子中的方便性显露无疑。它返回一个复合元素,能通过元素接口(Element interface)访问每个元素。这样做的好处是可不用循环和不分别访问每一个元素。 DomQuery的选取参数可以是一段较长的数组,其中包括W3C CSS3 Dom选取器、基本XPatch、HTML属性和更多,请参阅DomQuery API文档以了解这功能强大的库个中细节。 响应事件 到这范例为止,我们所写的代码都是放在onReady中,即当页面加载后总会立即执行,功能较单一——这样的话,你便知道,如何响应某个动作或事件来执行你希望做的事情,做法是,先分配一个function,再定义一个event handler事件处理器来响应。我们由这个简单的范例开始,打开ExtStart.js,编辑下列的代码: 复制代码 function MyparagraphClick() { alert("dsdf"); } function test(e) { var para = Ext.get(e.target); para.highlight(); Ext.MessageBox.show({title:'para clicked',msg:para.dom.innerHTML,width:400, buttons:Ext.MessageBox.OK,animEl:para}); } Ext.onReady(function() { var myDiv = Ext.get('myDiv'); myDiv.highlight(); myDiv.addClass('red'); myDiv.center(); Ext.select('p').highlight(); Ext.get('myButton').on('click',function() { alert("click me!"); }); var paragraphClick = function(e) { //alert("click wto"); Ext.get(e.target).highlight(); } Ext.select('p').on('click',test); }); 复制代码 现在,为了我们接下来阐述新概念的演示,请观察MessageBox的调用。乍一看,这像一连串的参数传入到方法中,但仔细看,这是一个非常特别的语法。实际上,传入到MessageBox.show的只有一个参数:一个Object literal,包含一组属性和属性值。在Javascript中,Object Literal是动态的,你可在任何时候用{和}创建一个典型的对象(object)。其中的字符由一系列的name/value组成的属性,属性的格式是[property name]:[property value]。在整个Ext中,你将会经常遇到这种语法,因此你应该马上消化并吸收这个知识点! 使用Object Literal的原因是什么呢?主要的原因是“可伸缩性(flexibility)”的考虑",随时可新增、删除属性,亦可不管顺序地插入。而方法不需要改变。这也是多个参数的情况下,为最终开发者带来不少的方便(本例中的MessageBox.show())。例如,我们说这儿的foo.action方法,有四个参数,而只有一个是你必须传入的。本例中,你想像中的代码可能会是这样的foo.action(null, null, null, 'hello').,若果那方法用Object Literal来写,却是这样, foo.action({ param4: 'hello' }),这更易用和易读. Grid Grid是Ext中人们最想先睹为快的和最为流行Widgets之一。好,让我们看看怎么轻松地创建一个Grid并运行。 复制代码 Ext.onReady(function() { var myData =[['Apple',29.89,0.24,0.81,'9/1 12:00am'], ['Ext',83.81,0.28,0.34,'9/12 12:00am'], ['Google',71.72,0.02,0.03,'10/1 12:00am'], ['Microsoft',52.55,0.01,0.02,'7/4 12:00am'], ['Yahoo!',29.01,0.42,1.47,'5/22 12:00am']]; var myReader =new Ext.data.ArrayReader({},[{name:'company'},{name:'price', type:'float'},{name:'change', type:'float'},{name:'pctChange', type:'float'},{name:'lastChange', type:'date', dateFormat:'n/j h:ia'}]); var grid =new Ext.grid.GridPanel({store:new Ext.data.Store({data: myData, reader: myReader}), columns:[{header:"Company", width:120, sortable:true, dataIndex:'company'},{header:"Price", width:90, sortable:true, dataIndex:'price'},{header:"Change", width:90, sortable:true, dataIndex:'change'},{header:"% Change", width:90, sortable:true, dataIndex:'pctChange'},{header:"Last Updated", width:120, sortable:true, renderer: Ext.util.Format.dateRenderer('m/d/Y'), dataIndex:'lastChange'}], viewConfig:{forceFit:true}, renderTo:'content', title:'My First Grid', width:500, frame:true}); grid.getSelectionModel().selectFirstRow(); }); 复制代码 这看上去很复杂,但实际上加起来,只有四行代码(不包含测试数据的代码)。 第一行创建数组并作为数据源。实际案例中,你很可能从数据库、或者WebService那里得到动态的数据。 接着,我们创建并加载data store, data store将会告诉Ext的底层库接手处理和格式化这些数据。不同的数据类型须在类Reader中指明。 接着,我们创建一个Grid的组件,传入各种的配置值,有: 新的data store, 配置好测试数据和reader 列模型column model定义了列columns的配置 其他的选择指定了Grid所需的功能 最后,通过SelectionModel告诉Grid高亮显示第一行。 不是太困难吧?如果一切顺利,完成之后你会看到像这样的: 使用Ajax 在弄好一些页面后,你已经懂得在页面和脚本之间的交互(interact)原理。接下来,你应该掌握的是,怎样与远程服务器(remote server)交换数据,常见的是从数据库加载数据(load)或是保存数据(save)到数据库中。通过JavaScript异步无刷新交换数据的这种方式,就是所谓的Ajax。Ext内建卓越的Ajax支持,例如,一个普遍的用户操作就是,异步发送一些东西到服务器,然后,UI元素根据回应(Response)作出更新。 客户端: <div id="msg"></div> <div>Name:<input type="text"id="name"/> <input type="button"id="okButton" value="确定"/> </div> 复制代码 Ext.onReady(function() { Ext.get('okButton').on('click',function() { var msg = Ext.get('msg'); msg.load({url:'http://localhost:8080/ajaxDemo/hello', params:'name='+ Ext.get('name').dom.value, text:'Updating'}); msg.show(); }); }); 复制代码 服务器端: 复制代码 import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class hello extends HttpServlet { public hello() { super(); } public void destroy() { super.destroy(); // Just puts "destroy" string in log // Put your code here } public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html"); PrintWriter out = response.getWriter(); out.print("From Server: hello,ajax!"); out.close(); } public void init() throws ServletException { // Put your code here } } 复制代码 本文转自Phinecos(洞庭散人)博客园博客,原文链接:http://www.cnblogs.com/phinecos/archive/2008/07/14/1242855.html,如需转载请自行联系原作者

优秀的个人博客,低调大师

《javascript入门经典》摘录

JavaScript中可以对内建对象进行扩展。 <html> <head><title>Test of heading method</title> </head> <body> <script LANGUAGE="JavaScript" type="text/javascript"> function addhead (level) { html = "H" + level; text = this.toString(); start = "<" + html + ">"; stop = "</" + html + ">"; return start + text + stop; } String.prototype.heading = addhead; document.write ("This is a heading 1".heading(1)); document.write ("This is a heading 2".heading(2)); document.write ("This is a heading 3".heading(3)); </script> </body> </html> 1,Prototype Prototype is free, open-source software. You can download it from its official website at http://prototype.conio.net/. Prototype is also built into the Ruby on Rails framework for the server-side language Rubysee http://www.rubyonrails.com/ for more information. 2,Script.aculo.us Script.aculo.us by Thomas Fuchs is one such library. It includes functions to simplify drag-and-drop tasks, such as rearranging lists of items. It also includes a number of Combination Effects, which enable you to use highlighting and animated transitions within your pages. 3,AJAX Frameworks The Prototype library, described previously, includes AJAX features. There are also many dedicated AJAX libraries. One of the most popular is SAJAX (Simple AJAX), an open-source toolkit that makes it easy to use AJAX to communicate with PHP, Perl, and other languages from JavaScript. Visit the SAJAX website for details at http://www.modernmethod.com/sajax. 4,Dojo (http://www.dojotoolkit.org/) is an open-source toolkit that adds power to JavaScript to simplify building applications and user interfaces. It adds features ranging from extra string and math functions to animation and AJAX. 5, The Yahoo! UI Library (http://developer.yahoo.net/yui/) was developed by Yahoo! and made available to everyone under an open-source license. It includes features for animation, DOM features, event management, and easy-to-use user interface elements such as calendars and sliders. 6, MochiKit (http://mochikit.com/) is a lightweight library that adds features for working with the DOM, CSS colors, string formatting, and AJAX. It also supports a nice logging mechanism for debugging your scripts. 本文转自Phinecos(洞庭散人)博客园博客,原文链接:http://www.cnblogs.com/phinecos/archive/2007/05/12/744215.html,如需转载请自行联系原作者

优秀的个人博客,低调大师

Hadoop学习笔记--入门

HaDoop0.23.0学习笔记 0.23介绍 HadoopMapReduceV2(Yarn)框架简介 原HadoopMapReduce框架的问题 对于业界的大数据存储及分布式处理系统来说,Hadoop是耳熟能详的卓越开源分布式文件存储及处理框架,对于Hadoop框架的介绍在此不再累述,读者可参考Hadoop官方简介。使用和学习过老Hadoop框架(0.20.0及之前版本)的同仁应该很熟悉如下的原MapReduce框架图: 图1.Hadoop原MapReduce架构 从上图中可以清楚的看出原MapReduce程序的流程及设计思路: 首先用户程序(JobClient)提交了一个job,job的信息会发送到JobTracker中,JobTracker是Map-reduce框架的中心,他需要与集群中的机器定时通信(heartbeat),需要管理哪些程序应该跑在哪些机器上,需要管理所有job失败、重启等操作。 TaskTracker是Map-reduce集群中每台机器都有的一个部分,他做的事情主要是监视自己所在机器的资源情况。 TaskTracker同时监视当前机器的tasks运行状况。TaskTracker需要把这些信息通过heartbeat发送给JobTracker,JobTracker会搜集这些信息以给新提交的job分配运行在哪些机器上。上图虚线箭头就是表示消息的发送-接收的过程。 可以看得出原来的map-reduce架构是简单明了的,在最初推出的几年,也得到了众多的成功案例,获得业界广泛的支持和肯定,但随着分布式系统集群的规模和其工作负荷的增长,原框架的问题逐渐浮出水面,主要的问题集中如下: JobTracker是Map-reduce的集中处理点,存在单点故障。 JobTracker完成了太多的任务,造成了过多的资源消耗,当map-reducejob非常多的时候,会造成很大的内存开销,潜在来说,也增加了JobTrackerfail的风险,这也是业界普遍总结出老Hadoop的Map-Reduce只能支持4000节点主机的上限。 在TaskTracker端,以map/reducetask的数目作为资源的表示过于简单,没有考虑到cpu/内存的占用情况,如果两个大内存消耗的task被调度到了一块,很容易出现OOM。 在TaskTracker端,把资源强制划分为maptaskslot和reducetaskslot,如果当系统中只有maptask或者只有reducetask的时候,会造成资源的浪费,也就是前面提过的集群资源利用的问题。 源代码层面分析的时候,会发现代码非常的难读,常常因为一个class做了太多的事情,代码量达3000多行,,造成class的任务不清晰,增加bug修复和版本维护的难度。 从操作的角度来看,现在的HadoopMapReduce框架在有任何重要的或者不重要的变化(例如bug修复,性能提升和特性化)时,都会强制进行系统级别的升级更新。更糟的是,它不管用户的喜好,强制让分布式集群系统的每一个用户端同时更新。这些更新会让用户为了验证他们之前的应用程序是不是适用新的Hadoop版本而浪费大量时间。 新HadoopYarn框架原理及运作机制 从业界使用分布式系统的变化趋势和hadoop框架的长远发展来看,MapReduce的JobTracker/TaskTracker机制需要大规模的调整来修复它在可扩展性,内存消耗,线程模型,可靠性和性能上的缺陷。在过去的几年中,hadoop开发团队做了一些bug的修复,但是最近这些修复的成本越来越高,这表明对原框架做出改变的难度越来越大。 为从根本上解决旧MapReduce框架的性能瓶颈,促进Hadoop框架的更长远发展,从0.23.0版本开始,Hadoop的MapReduce框架完全重构,发生了根本的变化。新的HadoopMapReduce框架命名为MapReduceV2或者叫Yarn,其架构图如下图所示: 图2.新的HadoopMapReduce框架(Yarn)架构 重构根本的思想是将JobTracker两个主要的功能分离成单独的组件,这两个功能是资源管理和任务调度/监控。新的资源管理器全局管理所有应用程序计算资源的分配,每一个应用的ApplicationMaster负责相应的调度和协调。一个应用程序无非是一个单独的传统的MapReduce任务或者是一个DAG(有向无环图)任务。ResourceManager和每一台机器的节点管理服务器能够管理用户在那台机器上的进程并能对计算进行组织。 事实上,每一个应用的ApplicationMaster是一个详细的框架库,它结合从ResourceManager获得的资源和NodeManager协同工作来运行和监控任务。 上图中ResourceManager支持分层级的应用队列,这些队列享有集群一定比例的资源。从某种意义上讲它就是一个纯粹的调度器,它在执行过程中不对应用进行监控和状态跟踪。同样,它也不能重启因应用失败或者硬件错误而运行失败的任务。 ResourceManager是基于应用程序对资源的需求进行调度的;每一个应用程序需要不同类型的资源因此就需要不同的容器。资源包括:内存,CPU,磁盘,网络等等。可以看出,这同现Mapreduce固定类型的资源使用模型有显著区别,它给集群的使用带来负面的影响。资源管理器提供一个调度策略的插件,它负责将集群资源分配给多个队列和应用程序。调度插件可以基于现有的能力调度和公平调度模型。 上图中NodeManager是每一台机器框架的代理,是执行应用程序的容器,监控应用程序的资源使用情况(CPU,内存,硬盘,网络)并且向调度器汇报。 每一个应用的ApplicationMaster的职责有:向调度器索要适当的资源容器,运行任务,跟踪应用程序的状态和监控它们的进程,处理任务的失败原因。 新旧HadoopMapReduce框架比对 让我们来对新旧MapReduce框架做详细的分析和对比,可以看到有以下几点显著变化: 首先客户端不变,其调用API及接口大部分保持兼容,这也是为了对开发使用者透明化,使其不必对原有代码做大的改变(详见2.3Demo代码开发及详解),但是原框架中核心的JobTracker和TaskTracker不见了,取而代之的是ResourceManager,ApplicationMaster与NodeManager三个部分。 我们来详细解释这三个部分,首先ResourceManager是一个中心的服务,它做的事情是调度、启动每一个Job所属的ApplicationMaster、另外监控ApplicationMaster的存在情况。细心的读者会发现:Job里面所在的task的监控、重启等等内容不见了。这就是AppMst存在的原因。ResourceManager负责作业与资源的调度。接收JobSubmitter提交的作业,按照作业的上下文(Context)信息,以及从NodeManager收集来的状态信息,启动调度过程,分配一个Container作为AppMstr NodeManager功能比较专一,就是负责Container状态的维护,并向RM保持心跳。 ApplicationMaster负责一个Job生命周期内的所有工作,类似老的框架中JobTracker。但注意每一个Job(不是每一种)都有一个ApplicationMaster,它可以运行在ResourceManager以外的机器上。 Yarn框架相对于老的MapReduce框架什么优势呢?我们可以看到: 这个设计大大减小了JobTracker(也就是现在的ResourceManager)的资源消耗,并且让监测每一个Job子任务(tasks)状态的程序分布式化了,更安全、更优美。 在新的Yarn中,ApplicationMaster是一个可变更的部分,用户可以对不同的编程模型写自己的AppMst,让更多类型的编程模型能够跑在Hadoop集群中,可以参考hadoopYarn官方配置模板中的mapred-site.xml配置。 对于资源的表示以内存为单位(在目前版本的Yarn中,没有考虑cpu的占用),比之前以剩余slot数目更合理。 老的框架中,JobTracker一个很大的负担就是监控job下的tasks的运行状况,现在,这个部分就扔给ApplicationMaster做了,而ResourceManager中有一个模块叫做ApplicationsMasters(注意不是ApplicationMaster),它是监测ApplicationMaster的运行状况,如果出问题,会将其在其他机器上重启。 Container是Yarn为了将来作资源隔离而提出的一个框架。这一点应该借鉴了Mesos的工作,目前是一个框架,仅仅提供java虚拟机内存的隔离,hadoop团队的设计思路应该后续能支持更多的资源调度和控制,既然资源表示成内存量,那就没有了之前的mapslot/reduceslot分开造成集群资源闲置的尴尬情况。 表1.新旧Hadoop脚本/变量/位置变化表 改变项 原框架中 新框架中(Yarn) 备注 配置文件位置 ${hadoop_home_dir}/conf ${hadoop_home_dir}/etc/hadoop/ Yarn框架也兼容老的${hadoop_home_dir}/conf位置配置,启动时会检测是否存在老的conf目录,如果存在将加载conf目录下的配置,否则加载etc下配置 启停脚本 ${hadoop_home_dir}/bin/start(stop)-all.sh ${hadoop_home_dir}/sbin/start(stop)-dfs.sh ${hadoop_home_dir}/bin/start(stop)-all.sh 新的Yarn框架中启动分布式文件系统和启动Yarn分离,启动/停止分布式文件系统的命令位于${hadoop_home_dir}/sbin目录下,启动/停止Yarn框架位于${hadoop_home_dir}/bin/目录下 JAVA_HOME全局变量 ${hadoop_home_dir}/bin/start-all.sh中 ${hadoop_home_dir}/etc/hadoop/hadoop-env.sh ${hadoop_home_dir}/etc/hadoop/Yarn-env.sh Yarn框架中由于启动hdfs分布式文件系统和启动MapReduce框架分离,JAVA_HOME需要在hadoop-env.sh和Yarn-env.sh中分别配置 HADOOP_LOG_DIR全局变量 不需要配置 ${hadoop_home_dir}/etc/hadoop/hadoop-env.sh 老框架在LOG,conf,tmp目录等均默认为脚本启动的当前目录下的log,conf,tmp子目录 Yarn新框架中Log默认创建在Hadoop用户的home目录下的log子目录,因此最好在${hadoop_home_dir}/etc/hadoop/hadoop-env.sh配置HADOOP_LOG_DIR,否则有可能会因为你启动hadoop的用户的.bashrc或者.bash_profile中指定了其他的PATH变量而造成日志位置混乱,而该位置没有访问权限的话启动过程中会报错 由于新的Yarn框架与原HadoopMapReduce框架相比变化较大,核心的配置文件中很多项在新框架中已经废弃,而新框架中新增了很多其他配置项,看下表所示会更加清晰: 表2.新旧Hadoop框架配置项变化表 配置文件 配置项 Hadoop0.20.X配置 Hadoop0.23.X配置 说明 core-site.xml 系统默认分布式文件URI fs.default.name fs.defaultFS hdfs-site.xml DFSnamenode存放nametable的目录 dfs.name.dir dfs.namenode.name.dir 新框架中namenode分成dfs.namenode.name.dir(存放nanametable和dfs.namenode.edits.dir(存放edit文件),默认是同一个目录 DFSdatanode存放数据block的目录 dfs.data.dir dfs.datanode.data.dir 新框架中DataNode增加更多细节配置,位于dfs.datanode.配置项下,如dfs.datanode.data.dir.perm(datanodelocal目录默认权限);dfs.datanode.address(datanode节点监听端口);等 分布式文件系统数据块复制数 dfs.replication dfs.replication 新框架与老框架一致,值建议配置为与分布式cluster中实际的DataNode主机数一致 mapred-site.xml Job监控地址及端口 mapred.job.tracker 无 新框架中已改为Yarn-site.xml中的resouceManager及nodeManager具体配置项,新框架中历史job的查询已从Jobtracker剥离,归入单独的mapreduce.jobtracker.jobhistory相关配置, 第三方MapReduce框架 无 mapreduce.framework.name 新框架支持第三方MapReduce开发框架以支持如SmartTalk/DGSG等非Yarn架构,注意通常情况下这个配置的值都设置为Yarn,如果没有配置这项,那么提交的Yarnjob只会运行在locale模式,而不是分布式模式。 Yarn-site.xml TheaddressoftheapplicationsmanagerinterfaceintheRM 无 Yarn.resourcemanager.address 新框架中NodeManager与RM通信的接口地址 Theaddressoftheschedulerinterface 无 Yarn.resourcemanager.scheduler.address 同上,NodeManger需要知道RM主机的scheduler调度服务接口地址 TheaddressoftheRMwebapplication 无 Yarn.resourcemanager.webapp.address 新框架中各个task的资源调度及运行状况通过通过该web界面访问 Theaddressoftheresourcetrackerinterface 无 Yarn.resourcemanager.resource-tracker.address 新框架中NodeManager需要向RM报告任务运行状态供Resouce跟踪,因此NodeManager节点主机需要知道RM主机的tracker接口地址 实验环境: 操作系统:Gentoo-linux-3.8.13i686 主机名IP: Namenode192.168.254.81 Datanode1192.168.254.91 Datanode2192.168.254.92 需要软件: Javajdk-8-linux-i586.tar.gz Hadoophadoop-2.3.0.tar.gz SshOpenSSH_5.9p1-hpn13v11##系统自带emergeopenssh-client–av 结构介绍: Namenode上部署namenode,resourcemanager,secondarynamenode Datanode1/2上部署datanode,nodemanager Java路径/home/hadoop/java Hadoop路径/home/hadoop/hadoop DFS路径/home/hadoop/DFS Hadooptmp路径/temp/hadoor-${user} 实验步骤: 创建用户---在81,91-92下(root): Useraddhadoop–d/home/hadoop Mkdir/home/hadoop Chown–Rhadoop:hadoop/home/hadoop Chmod–R750/home/hadoop Passwdhadoop 做hadoop账号ssh免验证---在81,91-92下(hadoop): Su–hadoop Ssh-keygen##全部默认 在81下(hadoop) Su-hadoop Cd~/.ssh Cpid_rsa.pubauthorized_keys Foriin`echo819192`;doscphadoop@192.168.254.$i:/home/hadoop/.ssh/;done 测试 如图:免验证打开 注意:第一次使用会有安全提示,确认yes Java的安装(hadoop): #Su-hadoop Tarzxvfjdk1.8.0.tar.gz–C/home/hadoop/ Mv/home/hadoop/jdk1.8.0/home/hadoop/java Hadoop的安装(hadoop): #Su–hadoop Tarzxvfhadoop-2.3.0.tar.gz–C/home/hadoop Mv/home/hadoop/hadoop-2.3.0/home/hadoop/hadoop Java和hadoop权限变更(root) #su–root Chown–Rhadoop:hadoop/home/hadoop/ 设置变量---在81,91-92下 Echo“exportJAVA_HOME=/home/hadoop/java”>>/etc/profile Echo“exportPATH=$PATH:$JAVA_HOME/bin”>>/etc/profile Echo“exportCLASSPATH=$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:./”>>/etc/profile Echo“HADOOP_HOME=/home/hadoop/hadoop”>>/etc/profile Echo“PATH=$PATH:$HADOOP_HOME/bin”>>/etc/profile Echo“JAVA_LIBRARY_PATH=$HADOOP_HOME/lib/native”>>/etc/profile Source/etc/profile Hadoop配置---在81上: Cd$HADOOP_HOME/etc/hadoop/ Vihadoop.env.xml 修改JAVA_HOME路径(考虑全局变量里面我们刚设置了JAVA_HOME,所以这里可以注销) ,如果修改,修改为: ExportJAVA_HOME=/home/hadoop/java Vicore-site.xml <configuration> <property> <name>fs.defaultFS</name> <value>hdfs://192.168.254.81:9000</value> </property> <property> <name>hadoop.tmp.dir</name> <value>/home/hadoop/DFS/hadoop-${user.name}</value> <description>Abaseforothertemporarydirectories.</description> </property> </configuration> Vihdfs-site.xml <configuration> <property> <name>dfs.namenode.name.dir</name> <value>/home/hadoop/DFS/hadoop/name1,/home/hadoop/DFS/hadoop/name2</value> <description>Namedir</description> </property> <property> <name>dfs.namenode.edit.dir</name> <value>/home/hadoop/DFS/hadoop/edit1,/home/hadoop/DFS/hadoop/edit2</value> <description>Editdir</description> </property> <property> <name>dfs.datanode.data.dir</name> <value>/home/hadoop/DFS/hadoop/data1,/home/hadoop/DFS/hadoop/data2</value> <description>Datadir</description> </property> <property> <name>dfs.datanode.data.http.address</name> <value>0.0.0.0:50075</value> <description>Thedatanodehttpserveraddressandport</description> </property> <property> <name>dfs.replication</name> <value>2</value> <description>dfsvalues</description> </property> </configuration> Vimapred-site.xml <configuration> <property> <name>mapreduce.framework.name</name> <value>yarn</value> </property> </configuration> Viyarn-site.xml <?xmlversion="1.0"?> <configuration> <!--sitespecificYARNconfigurationproterties--> <property> <name>yarn.nodemanager.aux-serivice</name> <value>mapreduce.shuffle</value> </property> <property> <description>TheaddressoftheapplicationsmanagerinterfaceintheRM.</description> <name>yarn.resourcemanager.address</name> <value>192.168.254.81:18040</value> </property> <property> <description>Theaddressoftheschedulerinterface.</description> <name>yarn.resourcemanager.scheduler.address</name> <value>192.168.254.81:18030</value> </property> <property> <description>TheaddressoftheRMwebapplication.</description> <name>yarn.resourcemanager.webapp.address</name> <value>192.168.254.81:18088</value> </property> <property> <description>Theaddressoftheresourcetrackerinterfacce.</description> <name>yarn.resourcemanager.resource-tracker.address</name> <value>192.168.254.81:8025</value> </property> </configuration> Vislaves 192.168.254.91 192.168.254.92 Vimasters 192.168.254.81 将81上面的/home/hadoop/java&hadoop同步到91-92下(hadoop) #su–hadoop Cd Foriin`seq9192`;doscp–r/home/hadoop/*hadoop@192.168.254.$i:/home/hadoop/;done 添加hosts解析---81,91-92(root) echo“192.168.254.81namenode”>>/etc/hosts echo“192.168.254.91datanode1”>>/etc/hosts echo“192.168.254.92datanode2”>>/etc/hosts 本文转自 chengchow 51CTO博客,原文链接:http://blog.51cto.com/chengchow/1397147,如需转载请自行联系原作者

优秀的个人博客,低调大师

elk入门概念详解

开始第一步 我们现在开始进行一个简单教程,它涵盖了一些基本的概念介绍,比如索引(indexing)、搜索(search)以及聚合(aggregations)。通过这个教程,我们可以让你对Elasticsearch能做的事以及其易用程度有一个大致的感觉。 我们接下来将陆续介绍一些术语和基本的概念,但就算你没有马上完全理解也没有关系。我们将在本书的各个章节中更加深入的探讨这些内容。 所以,坐下来,开始以旋风般的速度来感受Elasticsearch的能力吧! 让我们建立一个员工目录 假设我们刚好在Megacorp工作,这时人力资源部门出于某种目的需要让我们创建一个员工目录,这个目录用于促进人文关怀和用于实时协同工作,所以它有以下不同的需求: 数据能够包含多个值的标签、数字和纯文本。 检索任何员工的所有信息。 支持结构化搜索,例如查找30岁以上的员工。 支持简单的全文搜索和更复杂的短语(phrase)搜索 高亮搜索结果中的关键字 能够利用图表管理分析这些数据 索引员工文档 我们首先要做的是存储员工数据,每个文档代表一个员工。在Elasticsearch中存储数据的行为就叫做索引(indexing),不过在索引之前,我们需要明确数据应该存储在哪里。 在Elasticsearch中,文档归属于一种类型(type),而这些类型存在于索引(index)中,我们可以画一些简单的对比图来类比传统关系型数据库: Relational DB -> Databases -> Tables -> Rows -> Columns Elasticsearch -> Indices -> Types -> Documents -> Fields Elasticsearch集群可以包含多个索引(indices)(数据库),每一个索引可以包含多个类型(types)(表),每一个类型包含多个文档(documents)(行),然后每个文档包含多个字段(Fields)(列)。 「索引」含义的区分 你可能已经注意到索引(index)这个词在Elasticsearch中有着不同的含义,所以有必要在此做一下区分: 索引(名词)如上文所述,一个索引(index)就像是传统关系数据库中的数据库,它是相关文档存储的地方,index的复数是indices 或indexes。 索引(动词)「索引一个文档」表示把一个文档存储到索引(名词)里,以便它可以被检索或者查询。这很像SQL中的INSERT关键字,差别是,如果文档已经存在,新的文档将覆盖旧的文档。 倒排索引传统数据库为特定列增加一个索引,例如B-Tree索引来加速检索。Elasticsearch和Lucene使用一种叫做倒排索引(inverted index)的数据结构来达到相同目的。 默认情况下,文档中的所有字段都会被索引(拥有一个倒排索引),只有这样他们才是可被搜索的。 我们将会在倒排索引章节中更详细的讨论。 所以为了创建员工目录,我们将进行如下操作: 为每个员工的文档(document)建立索引,每个文档包含了相应员工的所有信息。 每个文档的类型为employee。 employee类型归属于索引megacorp。 megacorp索引存储在Elasticsearch集群中。 实际上这些都是很容易的(尽管看起来有许多步骤)。我们能通过一个命令执行完成的操作: PUT /megacorp/employee/1 { "first_name" : "John", "last_name" : "Smith", "age" : 25, "about" : "I love to go rock climbing", "interests": [ "sports", "music" ] } 我们看到path:/megacorp/employee/1包含三部分信息: 名字 说明 megacorp 索引名 employee 类型名 1 这个员工的ID 请求实体(JSON文档),包含了这个员工的所有信息。他的名字叫“John Smith”,25岁,喜欢攀岩。 很简单吧!它不需要你做额外的管理操作,比如创建索引或者定义每个字段的数据类型。我们能够直接索引文档,Elasticsearch已经内置所有的缺省设置,所有管理操作都是透明的。 接下来,让我们在目录中加入更多员工信息: PUT /megacorp/employee/2 { "first_name" : "Jane", "last_name" : "Smith", "age" : 32, "about" : "I like to collect rock albums", "interests": [ "music" ] } PUT /megacorp/employee/3 { "first_name" : "Douglas", "last_name" : "Fir", "age" : 35, "about": "I like to build cabinets", "interests": [ "forestry" ] } 结果: [root@master elasticsearch]# 1 2 3 4 5 6 7 8 9 curl-i-XPUT127.0.0.1:9200 /megacorp/employee/1 -d' { "first_name" : "John" , "last_name" : "Smith" , "age" :25, "about" : "Ilovetogorockclimbing" , "interests" :[ "sports" , "music" ] } ' 结果: 集群数据目录多一个了index megacorp名名称的(indices目录是 index名称的复数) [root@master elasticsearch]# 1 ls -l /tmp/elasticsearch/data/elasticsearch-cluster/nodes/0/indices/megacorp/ 1 2 3 4 5 6 7 total24 drwxr-xr-x5elasticsearchelasticsearch4096May1519:320 drwxr-xr-x5elasticsearchelasticsearch4096May1519:311 drwxr-xr-x5elasticsearchelasticsearch4096May1519:322 drwxr-xr-x5elasticsearchelasticsearch4096May1519:313 drwxr-xr-x5elasticsearchelasticsearch4096May1519:334 drwxr-xr-x2elasticsearchelasticsearch4096May1519:33_state 本文转自残剑博客51CTO博客,原文链接http://blog.51cto.com/cuidehua/1773685如需转载请自行联系原作者 cuizhiliang

优秀的个人博客,低调大师

docker入门

基础知识不回顾了,直接上。 docker的安装与启动 yum remove docker -y yum install docker-io -y #需要先配置好epel源 /etc/init.d/docker start chkconfig docker on 获取镜像 docker pull centos #从docker仓库下载一个镜像例如:docker pull centos:6.7 docker images #列出本地已存在的镜像 docker images centos #查看指定的镜像 运行 # docker run centos /bin/echo'Hello world' # docker run -i -t centos:6.7/bin/bash -i表示输入终端保持打开状态 -t表示开一个伪终端,并绑定到标准输入上 -c限制运行的某个容器的CPU配额【最大默认是1024】 --cpuset-cpus=设置可以绑定使用几个CPU,具体可以看help -d表示后台运行容器,只输出容器的ID到屏幕 -P表示--publish-all=false Publish all exposed ports to random ports --hostname=docker1.demo.com表示修改容器的hsotname --name=lnmp1 表示给启动的容器命名,不用随机名称 --dns=xx.xx.xx.xx自定义DNS服务器地址【不指定该参数的话,就是要外部主机的/etc/resolv.conf来配置容器】 --add-host "www.demo.com:192.168.2.2"在容器的/etc/hosts添加一条指定的DNS解析记录 --expose80 --expose 8080 #暴露端口在外部Expose a port or a range of ports --memory1G限制容器最大使用的内存 *centos后面如果不指定版本,则默认选择latest版本 输入exit或者Ctrl+d退出 # docker run -ti --name test3--hostname=docker1.demo.com --dns=192.168.2.2 --dns=8.8.8.8 lanmp:v1 /bin/bash #复杂的写法 # docker run -d ubuntu:14.04/bin/sh -c "while true; do echo hello world; sleep 1; done"以后台进程模式运行 # docker logs后面跟容器的NAMES 当利用docker run来创建容器时,Docker在后台运行的标准操作包括: 检查本地是否存在指定的镜像,不存在就从公有仓库下载 利用镜像创建并启动一个容器 分配一个文件系统,并在只读的镜像层外面挂载一层可读写层 从宿主主机配置的网桥接口中桥接一个虚拟接口到容器中去 从地址池配置一个ip地址给容器 执行用户指定的应用程序 执行完毕后容器被终止 # docker ps查看在运行中的docker实例进程 # docker logs insane_babbage 查看容器中的标准输出 # docker stop insane_babbage停止某个容器 # docker ps可以看到刚才启动的那个centos容器没有了 # docker ps -a可以看到所有的容器(包括已停止的) # docker start insane_babbage #如果加-i参数可以进入交互式的容器 # docker version查看docker客户端版本和进程的版本信息 ubuntu容器安装软件: 默认安装好的ubuntu docker是没有vim和ping这些命令的。 进入容器后,执行 # apt-get update # apt-get install vim -y 然后vi /etc/apt/sources.list添加阿里云的源地址。 # apt-get install inetutils-ping-y # ping www.qq.com即可 查看帮助信息 # docker只输入docker指令,系统会自动列出全部可用的命令列表 # docker images --help 创建镜像方法1:修改镜像 # docker run -i -t centos:6.7/bin/bash记下容器的ID,例如:e2d6c890682f 在容器中添加LAMP环境 # yum install httpd mysql mysql-server php php-mysql -y # exit退出容器 # docker commit -m "Add LAMPenv" -a "CentOS_LAMP" e2d6c890682f 6.7lamp 提交更新后的副本 -m message -a author # docker images可以看到已经生成了一个镜像 # docker run -i -t 6.7lamp/bin/bash用刚才创建的镜像启动容器 另外,可以使用docker commit -m 'my nignx' e2d6c890682fdemo/my_nginx:v1这种创建带明显标志的镜像。 启动的话使用docker run -d -p 88:80 --name "ningx_1" demo/my_nginx:v1即可。 方法2、dockerfile创建基于centos6.7的nginx的容器 mkdir /opt/docker-file cd /opt/docker-file mkdir nginx && cd nginx vi Dockerfile内容如下: # This is My First Dockerfile # Verson 1.0 # Author: Lee FROM centos:6.7 MAINTAINER Lee ADD pcre-8.36.tar.gz/usr/local/src<--- 1、需要事先把这个tar.gz包拷贝到当前目录下,即和Dockerfile在同一个目录下 ADD nginx-1.11.5.tar.gz/usr/local/src<---2、如果是个压缩包,拷到容器后会自动解压的,无需我们解压操作 RUN rm -fr /etc/yum.repos.d/* RUN wget -O/etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-6.repo RUN wget -O/etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-6.repo RUN yum clean all RUN yum install -y wget gcc gcc-c++ make openssl-devel RUN useradd -s /sbin/nologin -Mwww WORKDIR/usr/local/src/nginx-1.11.5 RUN ./configure--prefix=/usr/local/nginx --user=www --group=www --with-http_ssl_module --with-http_stub_status--with-pcre=/usr/local/src/pcre-8.36 && make && make install RUN echo 'daemon off;' >>/usr/local/nginx/conf/nginx.conf RUN sed 's@#user nobody;@user www;@g' nginx.conf ENV PATH/usr/local/nginx/sbin:$PATH EXPOSE 80 CMD ["nginx"] docker build -t dockfile:v2 .这样就可以创建镜像了 启动刚才创建的nginx docker容器的话,使用docker run -d -p 8888:80 dockfile:v2即可。 参数说明: 指令: FROM<image>[:tag>]或者FROM <image>@<digest> #必须是第一个非注释的行,用于指定所用到的基础镜像 MAINTAINER<author's detail> COPY["<src>", ..."<dest>"]复制本地主机的目录到容器里的指定目录 <src>是要复制的源文件或目录,支持通配符 <dest>目标路径,正在创建的镜像文件的文件系统路径(建议使用绝对路径) 说明:所有新复制生成的目录文件的UID和GID都是0 例如:COPY /home/template/server.xml/etc/tomcat/server.xml COPY *.conf /etc/httpd/conf.d/ 注意:src必须是build上下文的路径,即不能使用类似../../conf/*.conf,但是还是可以使用绝对路径例如/home/conf.d/*.conf;src如果是目录的话,递归复制会自动进行;如果有多个src,包括在src上使用了通配符,此时dest必须是目录,而且必须得以/结尾。 dest如果事先不存在,它会被自动创建,包括其父目录。 ADD类似COPY指令,额外还支持复制tar格式的文件及URL路径。【ADD比COPY用得更常见些】 例如:ADD haproxy.cfg /etc/haproxy/haproxy.cfg ADDlogstash_*.cnf /etc/logstash/ ADD http://www.demo.com/download/nginx.conf/etc/nginx/【URL格式指定的源文件,下载完成后其目标文件权限为600】 如果src是一个宿主机上的tar文件,则它将被解压展开成要给目录(类似tar xf命令,如果通过URL下载的是个tar文件,则不会被自动展开) ENV定义环境变量,此些变量可以被当前dockerfile文件中的其它指令所调用,调用格式为$variable_name或${variable_name} 语法: ENV<key> <value> 一次定义一个变量 或者ENV <key>=<value>...一次可以定义多个变量,如果value中有空白字符,要是\进行转义 如:ENV myName="Tom Lee" myDog='wang cai' 说明:ENV定义的环境变量在镜像运行的整个过程中一直存在,因此可以使用docker inspect查看,甚至可以用docker run --env=xxx来修改其值 USER指定运行容器时,或者运行RUN CMD ENTRYPOINT指令指定的程序时使用的用户名或者UID 格式:USER <UID>|<Username> WORKDIR为后续的RUN、CMD、ENTRYPOINT、COPY、ADD指令配置工作目录 如: WORKDIR/a WORKDIRb WORKDIRc RUNpwd 则最终路径为/a/b/c 另外, WORKDIR还可以调用由ENV定义的环境变量的值,如:WORKDIR $STATEPATH ENTRYPOINT VOLUME在目标镜像文件中创建一个挂载点,用来挂载主机上的卷或其他容器的卷。一般用来存放数据库和需要保持的数据等。 VOLUME<mountpoint> 例如:VOLUME ["/data/mysql","/data/Images"] 注意:如果mountpoint路径下事先有文件存在,则在挂载完成后,会同时显示当前的文件和挂载前的文件(AUFS的叠加原理)。 RUN 每个RUN都会另起一层,所以建议将多个命令放到一行,减少AUFS的层数。 格式: RUN <command> #会启动一个shell解释器 或RUN ["<executeable>","<param1>","<parma2>",...] #不会启动shell解释器 例如: RUNyum install iproute nginx && yum clean all RUN['/bin/bash','-c','yum','install','httpd'] CMD设定在docker run时默认执行的命令 格式:CMD <command>或CMD ["<executeable>","<param1>","<parma2>"] 或CMD["<param1>","<param2>",...]为ENTRYPOINT指令指定的程序提供默认参数。 如果dockerfile中存在多个CMD指令,则只有最后一个生效。 例如: CMD["/usr/sbin/httpd","-c","/etc/httpd/conf/httpd.conf"] ENTRYPOINT类似CMD指令,但其不会被docker run的命令行参数指定的指令所覆盖。且这些命令行参数会被当中参数送给ENTRYPOINT指令指定的程序 如果运行docker run时使用了--entrypoint选项,则此选项的参数可以覆盖掉dockerfile默认的entrypoint参数。 格式: ENTRYPOUNT<command> ENTRYPOUNT["executeable","<param1>","<param2>",...] 例如: 注意: 如果CMD和ENTRYPOINT都存在的话,则CMD的指令会被附加到ENTRYPOINT后,变成ENTRYPOINT的参数。 EXPOSE用于为容器指定要暴露的端口 格式:EXPOSE<port>[/protocol>][<port>[/<protocol>]]... 如: EXPOSE11211/tcp 11211/udp ONBUILD配置当所创建的镜像作为其它新创建镜像的基础镜像时,所执行的操作指令 例如:ONBUILD ADD my.cnf /etc/mysql/my.cnf 注意:ONBUILD不能自我嵌套,且不会触发。 导出镜像 # docker save -o/root/centos_lamp_v3.tar centos/lamp:v3 导入镜像 # docker load--input /root/centos_lamp_v3.tar 或者docker load </root/centos_lamp_v3.tar #这将导入镜像以及其相关的元数据信息(包括标签等) 移除镜像 # docker rmicentos/lamp:v3 注意:在删除镜像之前要先用dockerrm删掉依赖于这个镜像的所有容器。 想要删除untagged images,也就是那些id为<None>的image的话可以用 # docker rmi$(docker images | grep "^<none>" | awk "{print $2}") 要删除全部image的话 # docker rmi$(docker images -q) 删除已停止的容器 # docker rm -f$(docker ps -a -q) 移除容器 # docker rm5d6da6754d01 停止所有的container,这样才能够删除其中的images: # docker stop$(docker ps -a -q) 如果想要删除所有container的话再加一个指令: # docker rm$(docker ps -a -q) 从本地文件系统导入一个镜像 要从本地文件系统导入一个镜像,可以使用openvz(容器虚拟化的先锋技术)的模板来创建:openvz的 模板下载地址为templates。 比如,先下载了一个ubuntu-14.04的镜像,之后使用以下命令导入: catubuntu-14.04-x86_64-minimal.tar.gz |docker import - ubuntu:14.04 上传镜像 docker pushouruser/sinatra 进入容器 在使用-d参数时,容器启动后会进入后台。某些时候需要进入容器进行操作,有很多种方法,包括使用docker attach命令或nsenter工具等 # docker attach容器NAME 或者docker exec-ti容器ID /bin/bash 但是使用attach命令有时候并不方便。当多个窗口同时attach到同一个容器的时候,所有窗口都会同步显示。当某个窗口因命令阻塞时,其他窗口也无法执行操作了。使用attach进到容器后要退出的话,只能关闭xshell了,使用exit会导致整个容器的退出。 nsenter这个进入容器的命令也很好用(如果没有的话需要安装util-linux-ng)。 方法: dockerinspect --format"``.`State`.`Pid`"容器NAME或者容器ID号 #结果会输出一个容器的pid号 nsenter --target容器的pid号--mount --uts --ipc --net--pid 上面2条命令可以做成脚本,in.sh内容如下: #!/bin/bash CNAME=$1 CPID=$(dockerinspect --format"``.`State`.`Pid`" $CNAME) nsenter--target $CPID --mount --uts --ipc --net --pid sh in.sh容器的NAME或者ID号,即可进入容器。 导出容器快照到本地文件 # docker ps -a # dockerexport 容器名称> ubuntu.tar 导入容器快照为镜像 # cat ubuntu2.tar |dockerimport- test/ubuntu:v1 # docker images 自己基于centos构建nginx容器: 首先启动一个centos容器,然后在里面安装nginx(我这里是yum安装的nginx)。 修改nginx的配置文件,加上daemon off;参数。 然后继续。下面有2种方法启动容器时候让它自动启动nginx 方法1: dockercommit -m 'nginx_v1' eb919426f773 6.7_nginx_v1 dockerrun -d -p 888:88 --name 'nginx_v1' 6.7_nginx_v1 /usr/sbin/nginx 这样就可以了。 方法2: 修改容器的/etc/bashrc加上/usr/sbin/nginx -c/etc/nginx/nginx.conf dockerrun -d -p 888:88 --name 'nginx_v1' 6.7_nginx_v1 /bin/bash docker私有仓库的搭建 【作为仓库的虚拟机IP为:192.168.2.11】: #必须先启动docker registry【centos6上是这样的。在centos7上则变成了一个守护进程,需要用systemctl来启动】 # docker pullregistry # docker run -d-p 5000:5000 -v /opt/data/registry:/tmp/registry registry # docker ps记下容器NAME为kickass_wright #默认情况下,仓库会被创建在容器的/tmp/registry下。可以通过-v参数来将镜像文件存放在本地的指定路径。 # docker images列出当前的镜像 # docker tag88e44a5cbd17 192.168.2.11:5000/centos/lamp 格式:dockertag [OPTIONS] IMAGE[:TAG] [REGISTRYHOST/][USERNAME/]NAME[:TAG] # docker images Docker从1.3.X之后,与docker registry交互默认使用的是https,然而此处搭建的私有仓库只提供http服务,所以当与私有仓库交互时就会报上面的错误。为了解决这个问题需要在启动docker server时增加启动参数为默认使用http访问。 修改docker配置文件将代码加到/etc/sysconfig/docker的other_args="--insecure-registry192.168.2.11:5000"里面。 # docker stopkickass_wright停掉registry容器 #/etc/init.d/docker restart 重启docker # docker startkickass_wright启动registry容器 # docker push192.168.2.11:5000/centos/lamp 将本地镜像推送到本机上的私有服务器上 这样本地镜像就是上次到私有docker仓库了。 我们可以在其他节点测试能否下载这个镜像。如果没问题的话,就可以在本机上删除原有的docker镜像,如下: # docker rmi 192.168.2.11:5000/centos/lamp 在Node2节点(192.168.2.12)测试: # yum installdocker-io -y 修改docker配置文件将代码加到/etc/sysconfig/docker的other_args="--insecure-registry192.168.2.11:5000"里面。 #/etc/init.d/docker restart 重启docker # docker pull192.168.2.11:5000/centos/lamp从192.168.2.11的私有仓库下载镜像 # docker images可以看到已经下载好了相关的镜像 docker的监控命令: docker ps [-a] docker images docker statsContainer_name #实时查看某个容器的负载情况 docker topContainer_name #实时查看某个容器的状态统计(类似top命令) dockerinspect #查看容器或镜像的底层信息 例如:docker inspect-f'``.`Config`.`Hostname`'d413082da04e类似ansible的ansible -m setup的输出格式 此外,还有谷歌提供的CAdvisor web界面的监控工具;Scout工具,Data Dog工具,等。具体可参考: http://dockone.io/article/397 数据卷: 数据卷是一个可供一个或多个容器使用的特殊目录,它绕过UFS,可以提供很多有用的特性: 数据卷可以在容器之间共享和重用 对数据卷的修改会立马生效 对数据卷的更新,不会影响镜像 卷会一直存在,直到没有容器使用 *数据卷的使用,类似于Linux下对目录或文件进行mount 下面创建一个web容器,并加载一个数据卷到容器的/webapp目录: # docker run -d-P --name web -v /webapp training/webapp python app.py #这样只写名容器中的目录不写宿主机的目录的话,实际上是在宿主机的/var/lib/docker/volumes/xxxx/目录下的。不常用这种写法。 -v标记来创建一个数据卷并挂载到容器里。在一次run中多次使用可以挂载多个数据卷 *注意:也可以在Dockerfile中使用VOLUME来添加一个或者多个新的卷到由该镜像创建的任意容器。 挂载一个主机目录src/webapp作为容器的数据卷: # docker run -d-P --name web2 -v /src/webapp:/opt/webapp training/webapp python app.py #格式:-v本地路径:容器路径 *上面的命令加载主机的/src/webapp目录到容器的/opt/webapp目录。这个功能在进行测试的时候十分方便,比如用户可以放置一些程序到本地目录中,来查看容器是否正常工作。 *本地目录的路径必须是绝对路径,如果目录不存在Docker会自动为你创建它。 *注意:Dockerfile中不支持这种用法,这是因为Dockerfile是为了移植和分享用的。然而,不同操作系统的路径格式不一样,所以目前还不能支持。 Docker挂载数据卷的默认权限是读写,用户也可以通过:ro指定为只读。 # sudo docker run-d -P --name web -v/src/webapp:/opt/webapp:rotraining/webapppython app.py -v标记也可以从主机挂载单个文件到容器中 # docker run --rm-it -v ~/.bash_history:/.bash_history ubuntu /bin/bash【不同shell版本有所不同】 *注意:如果直接挂载一个文件,很多文件编辑工具,包括vi或者sed --in-place,可能会造成文件inode的改变,从Docker 1.1 .0起,这会导致报错误信息。所以最简单的办法就直接挂载文件的父目录。 数据卷容器: 如果你有一些持续更新的数据需要在容器之间共享,最好创建数据卷容器。 数据卷容器,其实就是一个正常的容器,专门用来提供数据卷供其它容器挂载的。 首先,创建一个数据卷容器dbdata,并在其中创建一个数据卷挂载到/dbdata: # docker run -i-t-v /dbdata--name dbdataubuntu:12.04/bin/bash 再启动2个容器测试 # docker run -i-t--volumes-from dbdata--name db1 ubuntu:12.04/bin/bash # docker run -i-t--volumes-from dbdata--name db2 ubuntu:12.04/bin/bash #注意:--volumes-from后面跟的是具备容器卷的那个容器名 此时容器db1和db2都挂载同一个数据卷到相同的/dbdata目录。三个容器任何一方在该目录下的写入,其他容器都可以看到。[即便原来的那个数据卷容器已经停止了] 查看数据卷实际的存放路径: docker inspect -f``.`Volumes`数据卷容器的NAME或ID map[/dbdata:/var/lib/docker/volumes/7c12ca73fe29f884ea5bee12c54da521c7450705264f76fe8629877302cd48aa/_data] 可以看到这个容器卷是把文件写入到/var/lib/docker/volumes下面的某个很长的字符串的目录下的_data/里面 容器和宿主机间文件拷贝的解决方法: docker ps获取目标容器的ID或者容器的名称 #我这里的是容器ID为52261df2fab6 docker inspect-f'``.`Id`'容器的ID #获取容器的ID全名称 得到一串类似52261df2fab612b24b3502c4ad98c22aff70ce9fa641c5c9f735ac2415e92da3 cp /root/test.log/var/lib/docker/devicemapper/mnt/52261d...xxx/rootfs/root/ #这样就把宿主机的test.log拷贝到容器的/root/目录下了。 #说明:上面的这个方法在CentOS6.7通过yum安装的docker-io测试通过。我另一台测试机安装的是docker-engine,则根本没有/rootfs/这个目录。 还可以使用多个--volumes-from参数来从多个容器挂载多个数据卷。 # docker run -i-t-v /dbdata--name dbdata ubuntu:12.04/bin/bash # docker run -i-t-v /webdata--name webdata ubuntu:12.04/bin/bash # docker run -i-t--volumes-from dbdata --name db1 --volumes-fromwebdata --name web1ubuntu:12.04 /bin/bash 此外,也可以从其他已经挂载了数据卷的容器来挂载数据卷。 *注意: 使用--volumes-from参数所挂载数据卷的容器自己并不需要保持在运行状态。 如果删除了挂载的容器(包括dbdata、db1和db2),数据卷并不会被自动删除。 如果要删除一个数据卷,必须在删除最后一个还挂载着它的容器时使用"docker rm -v容器名"命令来指定同时删除关联的容器。这可以让用户在容器之间升级和移动数据卷。另外,如果启动时候加了--rm参数,则容器关闭时自动删除容器并删除卷。 利用数据卷容器来备份数据 # docker run -i-t-v /dbdata--namedbdataubuntu:12.04 /bin/bash # cp /etc/issue/etc/group /dbdata 另外启动一个容器,对刚才的容器数据进行备份操作 # docker run--volumes-fromdbdata-v $(pwd):/backup --name bk1 ubuntu:12.04 tar czf/backup/backup.tar.gz /dbdata #格式:dockerrun--volumes-from要备份的容器名-v宿主机目录:/backup ubuntu:12.04 tar czf /backup/xx.tar.gz需要备份的容器的卷名称 *容器启动后,使用了tar命令来将dbdata卷备份为容器下的/backup/backup.tar.gz,这个容器执行完就自动退出了(因为没有-ti或-d参数), *同时在宿主机下当前目录下生成backup.tar.gz压缩文件(参数-v $(pwd):/backup就是这个作用). 利用数据卷容器来恢复数据 如果要恢复数据到一个容器,首先创建一个带有数据卷的容器dbdata2。 # docker run -it-v /dbdata --name dbdata2 ubuntu:12.04 /bin/bash 随便在/dbdata里面复制些文件,以便后面恢复数据时用于识别。 然后创建另一个容器,挂载dbdata2的容器,并使用tar解压备份文件到挂载的容器卷中。 #docker run --volumes-from dbdata2 -v $(pwd):/backup ubuntu:12.04 tar xf/backup/backup.tar.gz 本文转自 lirulei90 51CTO博客,原文链接:http://blog.51cto.com/lee90/1878276,如需转载请自行联系原作者

优秀的个人博客,低调大师

ElasticSearch入门 —— 集群搭建

一、环境介绍与安装准备 1、环境说明 2台虚拟机,OS为ubuntu13.04,ip分别为xxx.xxx.xxx.140和xxx.xxx.xxx.145。 2、安装准备 ElasticSearch(简称ES)由java语言实现,运行环境依赖java。ES 1.x版本,官方推荐至少使用jdk1.6的环境,建议使用oracle java,可以去官网下载,本文使用jdk-7u51-linux-i586.gz。ES可以去官网下载,也可以在这里下载,本文使用elasticsearch-1.0.1.tar.gz。 二、安装 1、安装JAVA 关于java的安装,请参照这里。 2、ES安装 (1)解压elasticsearch-1.0.1.tar.gz,sudo tar -zvxf elasticsearch-1.0.1.tar.gz,在当前路径生成目录:elasticsearch-1.0.1;为该目录做一个软连接ln -selasticsearch-1.0.1 elasticsearch。完成之后,目录结构如下图: (2)配置es。这里只做最简单的配置,修改ES_HOME/config/elasticsearch.yml文件,将node.name的值设置为“test-node1”,表示当前这个es服务节点名字为test-node1。 (3)启动ES。进入ES安装目录,执行命令:bin/elasticsearch -d -Xms512m -Xmx512m,然后在浏览器输入http://ip:9200/,查看页面信息,是否正常启动。status=200表示正常启动了,还有一些es的版本信息,name为配置文件中node.name的值。 (4)在另外一台机器上,安装同样的步骤安装ES,因为至少2台服务才算集群嘛!注意,在配置时,将node.name的值设置为test-node2,总之必须和之前配置值不同。 两台es服务同时起来,因为配置文件中均默认cluster.name=elasticsearch,所以这两台机器自动构建成一个集群,集群名字为elasticsearch。 3、elasticsearchservicewrapper安装 这个是对elasticsearch执行命令的包装服务,安装之后,方便elasticsearch的启动,停止等等操作。 (1)下载elasticsearchservicewrapper git clonehttps://github.com/elasticsearch/elasticsearch-servicewrapper,然后将目录下的service目录拷贝至ES_HOME/bin目录下。 (2)简单配置jvm的内存 修改ES_HOME/bin/service/elasticsearch.conf,set.default.ES_HEAP_SIZE=1024,该值根据机器的配置可自定义。 (3)安装启动服务 执行命令:ES_HOME/bin/service/elasticsearch install (4)启动/停止/重启服务 执行命令:ES_HOME/bin/service/elasticsearch start/stop/restart 4、插件安装 集群安装成功之后,需要对集群中的索引数据、运行情况等信息进行查看,索引需要安装一些插件,方面后续工作。工欲善其事必先利其器,下面介绍几个实用的插件: (1)head 和插件名字一样,首推这个插件。通过head,可以查看集群几乎所有信息,还能进行简单的搜索查询,观察自动恢复的情况等等。 执行下面的命令开始安装:sudo elasticsearch/bin/plugin -install mobz/elasticsearch-head 记得两台机器都安装一下哦。安装完成之后,在浏览器输入:http://ip:9200/_plugin/head/ ,可以查看显示效果。如下图: cluster health:green (2, 20) : 表示该集群目前处于健康状态,集群包含2台机器,索引总共20个分片。粗线绿框表示主分片,细线绿框为备份分片。 还有很多功能,请读者自己去体验。 (2)bigdesk bigdesk是集群监控插件,通过该插件可以查看整个集群的资源消耗情况,cpu、内存、http链接等等。 执行命令安装:sudo elasticsearch/bin/plugin -install lukas-vlcek/bigdesk 安装完成之后,在浏览器输入:http://ip:9200/_plugin/bigdesk/#nodes ,显示界面如下: 点击test-node1节点,可以查看单个节点的资源使用情况,包括JVM、Thread Pools、OS、Process、HTTP&Transport、Indice、File system。 ES的插件非常之多,请参考ES插件大全。 本文转自gaofeng36599 51CTO博客,原文链接:http://blog.51cto.com/786678398/1627402

优秀的个人博客,低调大师

深度学习入门指南

更多深度文章,请关注:https://yq.aliyun.com/cloud 简介 机器学习技术为现代社会的许多领域提供了强大的技术支持:从网络搜索到社交网络的内容过滤,再到电子商务网站的产品推荐。机器学习技术正越来越多的出现在消费级产品上,比如照相机和智能手机。 机器学习系统可用于识别图像中的对象,将语音转换成文本,选择搜索结果的相关项,以及匹配新闻、帖子或用户感兴趣的其他东西。 类似的应用越来越多,它们都使用了一种叫做深度学习的技术。 深度学习(也称为深层结构学习、层次学习或深度机器学习)是基于对数据中的高级抽象进行建模的算法,它属于机器学习的分支。最简单的例子,你可以有两组神经元:接收输入信号的神经元和发送输出信号的神经元。当输入层接收到输入时,它将输入的修改版本传递给下一层。在深层网络中,输入和输出层之间有很多层(层并不是由神经元构成,这里只是为了帮助你思考),这些层允许算法使用多个处理层,这些层包含了多个线性和非线性变换。 近来,深度学习技术使得机器学习发生了革命性的变化,并出现了很多伟大的成果。 它们大大改进了语音识别、视觉对象识别、对象检测以及许多其他领域(如药物发现和基因组学)的技术。 “深度学习”这个术语最早由Dechter(1986)引入机器学习,由Aizenberg等人(2000)引入人工神经网络(NN)。 深度学习的进一步普及得益于由Alex Krizhevsky发明的被称为“AlexNet”的卷积网络架构的出现。“AlexNet”在2012年的ImageNet比赛中击败了其他所有的图像处理算法,开创了在图像处理中使用深度学习架构的先河。 深度学习架构 生成式深度架构,旨在描述用于模式分析或合成目的的观测数据或可见数据的高阶相关特性,以及描述可见数据及其关联类的联合统计分布的特征。在后一种情况下,使用贝叶斯规则可以将这种类型的架构变成辨别式深度架构。 辨别式深度架构,旨在直接提供模式分类的辨别力,通常通过描述基于可见数据种类的后验分布来描述。 混合式深度架构,其目的是辨别,但通常辅以通过更好的优化或规则化的生成架构的结果,或者是其辨别标准被用来学习类别1中的任何一个深度生成模型的参数 尽管深度学习架构的分类很复杂,但在实践中经常用到的有深度前馈网络、卷积网络和循环网络。 深度前馈网络 前馈网络,通常被称为前馈神经网络或多层感知器(MLP),它是典型的深度学习模式。 前馈网络的目标是逼近某个函数f。例如,对于一个分类器,y=f(x)表示的是将输入x映射到类别y。前馈网络定义了一个映射 y=f(x;θ),并学习能产生最佳逼近函数的参数θ的值。 简单来说,网络可以定义为输入、隐藏和输出节点的组合。数据从输入节点流入,在隐藏节点中进行处理,然后通过输出节点产生输出。信息流经从x评估的函数,通过用于定义f的中间计算,最后到输出y。该网络中没有反馈连接,其中模型的输出反馈到自身,因此模型被称为前馈网络。该模型如图[1]所示。 图[1]:前馈神经网络 卷积神经网络 Source 在机器学习中,卷积神经网络(CNN或ConvNet)是一种前馈人工神经网络,其神经元之间的连接模式是受动物视觉皮层组织的启发而发明出来的。 个别皮质神经元对受限区域的刺激响应称为感受野。不同神经元的感受野部分重叠,这使得这些感受野像瓦片一样平铺。 单个神经元对其感受野内的刺激的反应可以用卷积运算近似地数学化。卷积网络的灵感来自于生物学,是多层感知器的变体。它在图像和视频识别、推荐系统和自然语言处理中具有广泛的应用。 LeNet是第一个卷积神经网络,它推动了深度学习领域的发展。自1988年以来,Yann LeCun的这项开创性工作多次成功迭代后成为了LeNet5。当时的LeNet架构主要用于字符识别,如阅读邮政编码、数字等等。 图[2]:一个简单的卷积神经网络模型 ConvNet有四个主要组件,如图2所示: 卷积层 激活函数 池化层 完全连接层 卷积层 卷积层基于术语“卷积”,它是对两个变量执行数学运算(f*g),以产生第三个变量。 它与互相关类似。 卷积层的输入是一幅 m x m x r 的图像,其中m是图像的高度和宽度,r是通道数,例如,对于RGB图像,r = 3 。 卷积层有大小为n x n x q的k个过滤器(或内核),其中n小于图像的维度,并且q小于等于通道数r,并且每个内核都可以不同。 激活函数 要实现复杂的映射函数,需要有非线性的激活函数,这样引入非常重要的非线性属性,使之能够近似于任何函数。激活函数对于压缩来自神经元的无界线性加权和也是非常重要的。这对于避免在处理层次上积累高值非常重要。有很多经常被用到的激活函数,比如Sigmoid、tanh和ReLU。 池化层 池化是一个基于样本的离散化过程。它的目标是对输入表示(图像、隐藏层输出矩阵等等)进行降采样,减少其维度,并允许对包含在子区域中的特征进行假设。 这样做的部分原因是为了提供一种抽象的表示形式来避免过度拟合。同样,它通过减少要学习的参数个数来降低计算成本,并为内部表示提供基本的转化恒定性。 比较突出的池化技术有:最大池化,最小池化和平均池化。 图[3]:2*2过滤器的最大池化示例 完全连接层 术语“完全连接”意味着上一层中的每个神经元都连接到下一层的每个神经元。完全连接层是传统的多层感知器,它使用softmax激活函数或输出层中的任何其他类似函数。 循环神经网络 在传统的神经网络中,我们假设所有的输入(和输出)是相互独立的。但是对于许多的任务来说,这是一个很糟糕的假设。如果你想预测一个句子中的下一个单词,你最好知道哪些前面的单词是什么。 RNN之所以称为循环,因为它们对序列的每个元素执行相同的任务,而输出依赖于先前的计算。还有一种理解RNN的方法,我们可以认为它有“记忆”的,它会捕获到截至目前计算出来的所有信息。 RNN中有循环,这使得在读入输入时能够跨神经元传递信息。在图[4]中,x_t是某种输入,A是RNN的一部分,h_t是输出。RNN有一些特殊的类型,比如LSTM、双向RNN,GRU等等。 图[4]:RNN模型 RNN可用于NLP、机器翻译、语言建模、计算机视觉、视频分析、图像生成、图像字幕等,这是因为在RNN中可以放置任意数量的输入和输出,并让它们一一对应、多对多对应。它架构存在多种形式,如图[5]所示。 图[5]:RNN描述了对矢量序列的操作 应用 在深度学习领域已经有了很多的研究,并且有很多特别的问题都使用深度学习模型得到了解决。这里有一些深度学习方面的优秀应用: 黑白图像彩色化 深度学习可用于参照照片中的对象及其上下文来对图像进行着色,就像人类进行着色一样。这个应用需使用非常大的卷积神经网络和监督层,通过添加颜色来重现图像。 机器翻译 文本翻译可以在没有对序列进行任何预处理的情况下进行,它允许算法学习单词之间的依赖关系及其与另一种语言之间的映射。大型LSTM循环神经网络的堆叠网络可用于机器翻译。 照片中物体的分类及检测 该任务是将照片中的对象归类到已知的对象组中去。在样例评测中,通过使用非常大的卷积神经网络能够获得非常好的结果。 Alex Krizhevsky等人在ImageNet分类中取得的突破性成果,被称为AlexNet。 自动手写生成 给定一个手写示例语料库,然后为给定的单词或短语生成新的笔迹。在笔迹样本被创建时,笔迹将作为一系列的坐标提供给笔。通过这个语料库,算法会学习笔的运动与字母之间的关系,然后生成新的示例。 自动打游戏 在这个应用中,模型将学习如何仅基于屏幕上的像素点来玩电脑游戏。这在深度增强模型领域中是一个非常难的任务,因为这个,DeepMind(现在是Google的一部分)赢得了很高的声誉。 生成模型聊天机器人 使用基于序列的模型来创建聊天机器人,该机器人在很多真实的对话数据集上进行训练,并学会生成自己的答案。要了解更多的详细信息,请访问这个链接。 总结 从本文可以得到这样的结论:深度学习模型可以用于各种任务,因为它能够模拟人脑。截止目前,专家们已经在这方面做了大量的研究,而且在不久将还有许多研究工作要做。尽管目前还存在信任问题,但在不久的将来,这个问题将会变得更加明朗。 文章原标题《A Beginners Guide to Deep Learning》,作者:Kumar Shridhar,译者:夏天,审校:主题曲。 文章为简译,更为详细的内容,请查看原文 本文由北邮@爱可可-爱生活老师推荐,阿里云云栖社区组织翻译。

优秀的个人博客,低调大师

Appium入门示例(Java)

一、环境准备: 见我另一篇文章:http://www.cnblogs.com/puresoul/p/4696638.html 二、使用Eclipse直接创建案例工程 1、打开Eclipse,【File】-->【New】-->【Project】 2、选择【Java Project】-->【Next】 3、输入工程名称Appium_demo,点击【Finish】 4、右键点击工程 New-Folder,新建两个文件夹:apps和libs,目录结构如下: 三、导入测试的类库 1、导入Selenum类库:http://docs.seleniumhq.org/download/ 1)selenium-server-standalone-2.44.0.jar 2)selenium-java-2.44.0.zip 2、导入Appium类库: 1)java-client-1.2.1.jar 3、右键点击工程空白处,选择【Build Path】-->【Configure Build Path】 四、下载测试APK 1、下载测试的文件ContactManager.apk:https://github.com/appium/sample-code/tree/master/sample-code/apps/ContactManager 2、将下载的apk放到项目的apps目录下 五、建立package包和案例文件 1、在src文件夹上右键单击,【New】-->【package】,输入包名:com.glen.demo,点击【Finish】 2、在package下新建类:ContactsTest.java,如下: 下载地址:https://github.com/appium/sample-code/tree/master/sample-code/examples/java/junit/src/test/java/com/saucelabs/appium 1 package com.glen.demo; 2 3 import io.appium.java_client.AppiumDriver; 4 import org.junit.After; 5 import org.junit.Before; 6 import org.junit.Test; 7 import org.openqa.selenium.By; 8 import org.openqa.selenium.WebElement; 9 import org.openqa.selenium.remote.CapabilityType; 10 import org.openqa.selenium.remote.DesiredCapabilities; 11 12 import java.io.File; 13 import java.net.URL; 14 import java.util.List; 15 16 17 public class ContactsTest { 18 private AppiumDriver driver; 19 @Before 20 public void setUp() throws Exception { 21 //设置apk的路径 22 File classpathRoot = new File(System.getProperty("user.dir")); 23 File appDir = new File(classpathRoot, "apps"); 24 File app = new File(appDir, "ContactManager.apk"); 25 26 //设置自动化相关参数 27 DesiredCapabilities capabilities = new DesiredCapabilities(); 28 capabilities.setCapability(CapabilityType.BROWSER_NAME, ""); 29 capabilities.setCapability("platformName", "Android"); 30 capabilities.setCapability("deviceName", "Android Emulator"); 31 32 //设置安卓系统版本 33 capabilities.setCapability("platformVersion", "4.3"); 34 //设置apk路径 35 capabilities.setCapability("app", app.getAbsolutePath()); 36 37 //设置app的主包名和主类名 38 capabilities.setCapability("appPackage", "com.example.android.contactmanager"); 39 capabilities.setCapability("appActivity", ".ContactManager"); 40 41 //初始化 42 driver = new AppiumDriver(new URL("http://127.0.0.1:4723/wd/hub"), capabilities); 43 } 44 45 @Test 46 public void addContact(){ 47 WebElement el = driver.findElement(By.name("Add Contact")); 48 el.click(); 49 List<WebElement> textFieldsList = driver.findElementsByClassName("android.widget.EditText"); 50 textFieldsList.get(0).sendKeys("Some Name"); 51 textFieldsList.get(2).sendKeys("Some@example.com"); 52 driver.swipe(100, 500, 100, 100, 2); 53 driver.findElementByName("Save").click(); 54 } 55 56 @After 57 public void tearDown() throws Exception { 58 driver.quit(); 59 } 60 } 六、 启动Android模拟器(也可以连接真机) 1、cmd输入:android avd,选择模拟器,点击【Start】即可。具体可参考:http://www.cnblogs.com/puresoul/p/4597211.html 2、启动好后,cmd输入:adb devices,确定设备是否连接上,如下图连接成功: 七、 启动Appium 方法一:cmd输入:appium 方法二: 1、直接双击appium gui图标(如下图): 2、点击右上角的启动按钮,启动日志如下: 八、 运行测试案例: 1、在eclipse中,项目右键>【Run As】>【JUnit Test】,运行过程截图如下: 2、运行日志: > Checking if an update is available > Update not available > Starting Node Server > warn: Appium support for versions of node < 0.12 has been deprecated and will be removed in a future version. Please upgrade! > info: Welcome to Appium v1.4.0 (REV 8f63e2f91ef7907aed8bda763f4e5ca08e86970a) > info: Appium REST http interface listener started on 127.0.0.1:4723 > info: [debug] Non-default server args: {"app":"F:\\workspace\\AppiumDemo\\apps\\ContactManager.apk","address":"127.0.0.1","logNoColors":true,"deviceName":"test","platformName":"Android","platformVersion":"18","automationName":"Appium"} > info: Console LogLevel: debug > info: --> POST /wd/hub/session {"desiredCapabilities":{"app":"F:\\workspace\\Appium_demo\\apps\\ContactManager.apk","platformVersion":"4.3","deviceName":"Android Emulator","platformName":"Android","appActivity":".ContactManager","browserName":"","appPackage":"com.example.android.contactmanager"}} > info: Client User-Agent string: Apache-HttpClient/4.3.4 (java 1.5) > info: [debug] Using local app from desired caps: F:\workspace\Appium_demo\apps\ContactManager.apk > info: [debug] Creating new appium session 97fd4549-c40a-4e96-a60a-6ffb9ed7fd01 > info: Starting android appium > info: [debug] Getting Java version > info: Java version is: 1.7.0_51 > info: [debug] Checking whether adb is present > info: [debug] Using adb from D:\android-sdk\sdk\platform-tools\adb.exe > info: [debug] Set chromedriver binary as: D:\Program Files\Appium\node_modules\appium\build\chromedriver\windows\chromedriver.exe > info: [debug] Using fast reset? true > info: [debug] Preparing device for session > info: [debug] Checking whether app is actually present > info: Retrieving device > info: [debug] Trying to find a connected android device > info: [debug] Getting connected devices... > info: [debug] executing cmd: D:\android-sdk\sdk\platform-tools\adb.exe devices > info: [debug] 1 device(s) connected > info: Found device emulator-5554 > info: [debug] Setting device id to emulator-5554 > info: [debug] Waiting for device to be ready and to respond to shell commands (timeout = 5) > info: [debug] executing cmd: D:\android-sdk\sdk\platform-tools\adb.exe -s emulator-5554 wait-for-device > info: [debug] executing cmd: D:\android-sdk\sdk\platform-tools\adb.exe -s emulator-5554 shell "echo 'ready'" > info: [debug] Starting logcat capture > info: [debug] Getting device API level > info: [debug] executing cmd: D:\android-sdk\sdk\platform-tools\adb.exe -s emulator-5554 shell "getprop ro.build.version.sdk" > info: [debug] Device is at API Level 18 > info: Device API level is: 18 > info: [debug] Extracting strings for language: default > info: [debug] executing cmd: D:\android-sdk\sdk\platform-tools\adb.exe -s emulator-5554 shell "getprop persist.sys.language" > info: [debug] Current device persist.sys.language: en > info: [debug] java -jar "D:\Program Files\Appium\node_modules\appium\node_modules\appium-adb\jars\appium_apk_tools.jar" "stringsFromApk" "F:\workspace\Appium_demo\apps\ContactManager.apk" "C:\Users\ADMINI~1\AppData\Local\Temp\com.example.android.contactmanager" en > info: [debug] No strings.xml for language 'en', getting default strings.xml > info: [debug] java -jar "D:\Program Files\Appium\node_modules\appium\node_modules\appium-adb\jars\appium_apk_tools.jar" "stringsFromApk" "F:\workspace\Appium_demo\apps\ContactManager.apk" "C:\Users\ADMINI~1\AppData\Local\Temp\com.example.android.contactmanager" > info: [debug] Reading strings from converted strings.json > info: [debug] Setting language to default > info: [debug] executing cmd: D:\android-sdk\sdk\platform-tools\adb.exe -s emulator-5554 push "C:\\Users\\ADMINI~1\\AppData\\Local\\Temp\\com.example.android.contactmanager\\strings.json" /data/local/tmp > info: [debug] Checking whether aapt is present > info: [debug] Using aapt from D:\android-sdk\sdk\build-tools\android-4.3\aapt.exe > info: [debug] Retrieving process from manifest. > info: [debug] executing cmd: D:\android-sdk\sdk\build-tools\android-4.3\aapt.exe dump xmltree F:\workspace\Appium_demo\apps\ContactManager.apk AndroidManifest.xml > info: [debug] Set app process to: com.example.android.contactmanager > info: [debug] Not uninstalling app since server not started with --full-reset > info: [debug] Checking app cert for F:\workspace\Appium_demo\apps\ContactManager.apk. > info: [debug] executing cmd: java -jar "D:\Program Files\Appium\node_modules\appium\node_modules\appium-adb\jars\verify.jar" F:\workspace\Appium_demo\apps\ContactManager.apk > info: [debug] App already signed. > info: [debug] Zip-aligning F:\workspace\Appium_demo\apps\ContactManager.apk > info: [debug] Checking whether zipalign is present > info: [debug] Using zipalign from D:\android-sdk\sdk\tools\zipalign.exe > info: [debug] Zip-aligning apk. > info: [debug] executing cmd: D:\android-sdk\sdk\tools\zipalign.exe -f 4 F:\workspace\Appium_demo\apps\ContactManager.apk C:\Users\ADMINI~1\AppData\Local\Temp\11572-12744-gdxu1q\appium.tmp > info: [debug] MD5 for app is b2d2916bb5388e1dc281ec3e71ef1234 > info: [debug] executing cmd: D:\android-sdk\sdk\platform-tools\adb.exe -s emulator-5554 shell "ls /data/local/tmp/b2d2916bb5388e1dc281ec3e71ef1234.apk" > info: [debug] Getting install status for com.example.android.contactmanager > info: [debug] Getting device API level > info: [debug] executing cmd: D:\android-sdk\sdk\platform-tools\adb.exe -s emulator-5554 shell "getprop ro.build.version.sdk" > info: [debug] Device is at API Level 18 > info: [debug] executing cmd: D:\android-sdk\sdk\platform-tools\adb.exe -s emulator-5554 shell "pm list packages -3 com.example.android.contactmanager" > info: [debug] App is installed > info: App is already installed, resetting app > info: [debug] Running fast reset (stop and clear) > info: [debug] executing cmd: D:\android-sdk\sdk\platform-tools\adb.exe -s emulator-5554 shell "am force-stop com.example.android.contactmanager" > info: [debug] executing cmd: D:\android-sdk\sdk\platform-tools\adb.exe -s emulator-5554 shell "pm clear com.example.android.contactmanager" > info: [debug] Forwarding system:4724 to device:4724 > info: [debug] executing cmd: D:\android-sdk\sdk\platform-tools\adb.exe -s emulator-5554 forward tcp:4724 tcp:4724 > info: [debug] Pushing appium bootstrap to device... > info: [debug] executing cmd: D:\android-sdk\sdk\platform-tools\adb.exe -s emulator-5554 push "D:\\Program Files\\Appium\\node_modules\\appium\\build\\android_bootstrap\\AppiumBootstrap.jar" /data/local/tmp/ > info: [debug] Pushing settings apk to device... > info: [debug] executing cmd: D:\android-sdk\sdk\platform-tools\adb.exe -s emulator-5554 install "D:\Program Files\Appium\node_modules\appium\build\settings_apk\settings_apk-debug.apk" > info: [debug] Pushing unlock helper app to device... > info: [debug] executing cmd: D:\android-sdk\sdk\platform-tools\adb.exe -s emulator-5554 install "D:\Program Files\Appium\node_modules\appium\build\unlock_apk\unlock_apk-debug.apk" > info: Starting App > info: [debug] Attempting to kill all 'uiautomator' processes > info: [debug] Getting all processes with 'uiautomator' > info: [debug] executing cmd: D:\android-sdk\sdk\platform-tools\adb.exe -s emulator-5554 shell "ps 'uiautomator'" > info: [debug] No matching processes found > info: [debug] Running bootstrap > info: [debug] spawning: D:\android-sdk\sdk\platform-tools\adb.exe -s emulator-5554 shell uiautomator runtest AppiumBootstrap.jar -c io.appium.android.bootstrap.Bootstrap -e pkg com.example.android.contactmanager -e disableAndroidWatchers false > info: [debug] [UIAUTOMATOR STDOUT] INSTRUMENTATION_STATUS: current=1 > info: [debug] [UIAUTOMATOR STDOUT] INSTRUMENTATION_STATUS: id=UiAutomatorTestRunner > info: [debug] [UIAUTOMATOR STDOUT] INSTRUMENTATION_STATUS: class=io.appium.android.bootstrap.Bootstrap > info: [debug] [UIAUTOMATOR STDOUT] INSTRUMENTATION_STATUS: stream= > info: [debug] [UIAUTOMATOR STDOUT] io.appium.android.bootstrap.Bootstrap: > info: [debug] [UIAUTOMATOR STDOUT] INSTRUMENTATION_STATUS: numtests=1 > info: [debug] [UIAUTOMATOR STDOUT] INSTRUMENTATION_STATUS: test=testRunServer > info: [debug] [UIAUTOMATOR STDOUT] INSTRUMENTATION_STATUS_CODE: 1 > info: [debug] [BOOTSTRAP] [debug] Socket opened on port 4724 > info: [debug] [BOOTSTRAP] [debug] Appium Socket Server Ready > info: [debug] [BOOTSTRAP] [debug] Loading json... > info: [debug] Waking up device if it's not alive > info: [debug] Pushing command to appium work queue: ["wake",{}] > info: [debug] [BOOTSTRAP] [debug] json loading complete. > info: [debug] [BOOTSTRAP] [debug] Registered crash watchers. > info: [debug] [BOOTSTRAP] [debug] Client connected > info: [debug] [BOOTSTRAP] [debug] Got data from client: {"cmd":"action","action":"wake","params":{}} > info: [debug] [BOOTSTRAP] [debug] Got command of type ACTION > info: [debug] [BOOTSTRAP] [debug] Got command action: wake > info: [debug] [BOOTSTRAP] [debug] Returning result: {"value":true,"status":0} > info: [debug] executing cmd: D:\android-sdk\sdk\platform-tools\adb.exe -s emulator-5554 shell "dumpsys window" > info: [debug] Screen already unlocked, continuing. > info: [debug] Pushing command to appium work queue: ["getDataDir",{}] > info: [debug] [BOOTSTRAP] [debug] Got data from client: {"cmd":"action","action":"getDataDir","params":{}} > info: [debug] [BOOTSTRAP] [debug] Got command of type ACTION > info: [debug] [BOOTSTRAP] [debug] Got command action: getDataDir > info: [debug] [BOOTSTRAP] [debug] Returning result: {"value":"\/data","status":0} > info: [debug] dataDir set to: /data > info: [debug] Pushing command to appium work queue: ["compressedLayoutHierarchy",{"compressLayout":false}] > info: [debug] [BOOTSTRAP] [debug] Got data from client: {"cmd":"action","action":"compressedLayoutHierarchy","params":{"compressLayout":false}} > info: [debug] [BOOTSTRAP] [debug] Got command of type ACTION > info: [debug] [BOOTSTRAP] [debug] Got command action: compressedLayoutHierarchy > info: [debug] [BOOTSTRAP] [debug] Returning result: {"value":false,"status":0} > info: [debug] Getting device API level > info: [debug] executing cmd: D:\android-sdk\sdk\platform-tools\adb.exe -s emulator-5554 shell "getprop ro.build.version.sdk" > info: [debug] Device is at API Level 18 > info: [debug] executing cmd: D:\android-sdk\sdk\platform-tools\adb.exe -s emulator-5554 shell "am start -S -a android.intent.action.MAIN -c android.intent.category.LAUNCHER -f 0x10200000 -n com.example.android.contactmanager/.ContactManager" > info: [debug] Waiting for pkg "com.example.android.contactmanager" and activity ".ContactManager" to be focused > info: [debug] Getting focused package and activity > info: [debug] executing cmd: D:\android-sdk\sdk\platform-tools\adb.exe -s emulator-5554 shell "dumpsys window windows" > info: [debug] Getting focused package and activity > info: [debug] executing cmd: D:\android-sdk\sdk\platform-tools\adb.exe -s emulator-5554 shell "dumpsys window windows" > info: [debug] executing cmd: D:\android-sdk\sdk\platform-tools\adb.exe -s emulator-5554 shell "getprop ro.build.version.release" > info: [debug] Device is at release version 4.3 > info: [debug] Device launched! Ready for commands > info: [debug] Setting command timeout to the default of 60 secs > info: [debug] Appium session started with sessionId 97fd4549-c40a-4e96-a60a-6ffb9ed7fd01 > info: <-- POST /wd/hub/session 303 54844.194 ms - 74 > info: --> GET /wd/hub/session/97fd4549-c40a-4e96-a60a-6ffb9ed7fd01 {} > info: [debug] Responding to client with success: {"status":0,"value":{"platform":"LINUX","browserName":"","platformVersion":"4.3","webStorageEnabled":false,"takesScreenshot":true,"javascriptEnabled":true,"databaseEnabled":false,"networkConnectionEnabled":true,"locationContextEnabled":false,"warnings":{},"desired":{"app":"F:\\workspace\\Appium_demo\\apps\\ContactManager.apk","platformVersion":"4.3","deviceName":"Android Emulator","platformName":"Android","appActivity":".ContactManager","browserName":"","appPackage":"com.example.android.contactmanager"},"app":"F:\\workspace\\Appium_demo\\apps\\ContactManager.apk","deviceName":"emulator-5554","platformName":"Android","appActivity":".ContactManager","appPackage":"com.example.android.contactmanager"},"sessionId":"97fd4549-c40a-4e96-a60a-6ffb9ed7fd01"} > info: <-- GET /wd/hub/session/97fd4549-c40a-4e96-a60a-6ffb9ed7fd01 200 10.271 ms - 758 {"status":0,"value":{"platform":"LINUX","browserName":"","platformVersion":"4.3","webStorageEnabled":false,"takesScreenshot":true,"javascriptEnabled":true,"databaseEnabled":false,"networkConnectionEnabled":true,"locationContextEnabled":false,"warnings":{},"desired":{"app":"F:\\workspace\\Appium_demo\\apps\\ContactManager.apk","platformVersion":"4.3","deviceName":"Android Emulator","platformName":"Android","appActivity":".ContactManager","browserName":"","appPackage":"com.example.android.contactmanager"},"app":"F:\\workspace\\Appium_demo\\apps\\ContactManager.apk","deviceName":"emulator-5554","platformName":"Android","appActivity":".ContactManager","appPackage":"com.example.android.contactmanager"},"sessionId":"97fd4549-c40a-4e96-a60a-6ffb9ed7fd01"} > info: --> POST /wd/hub/session/97fd4549-c40a-4e96-a60a-6ffb9ed7fd01/element {"using":"name","value":"Add Contact"} > warn: [DEPRECATED] The name locator strategy has been deprecated and will be removed. Please use the accessibility id locator strategy instead. > info: [debug] Waiting up to 0ms for condition > info: [debug] Pushing command to appium work queue: ["find",{"strategy":"name","selector":"Add Contact","context":"","multiple":false}] > info: [debug] [BOOTSTRAP] [debug] Got data from client: {"cmd":"action","action":"find","params":{"strategy":"name","selector":"Add Contact","context":"","multiple":false}} > info: [debug] [BOOTSTRAP] [debug] Got command of type ACTION > info: [debug] [BOOTSTRAP] [debug] Got command action: find > info: [debug] [BOOTSTRAP] [debug] Finding Add Contact using NAME with the contextId: multiple: false > info: [debug] [BOOTSTRAP] [debug] Using: UiSelector[DESCRIPTION=Add Contact, INSTANCE=0] > info: [debug] [BOOTSTRAP] [debug] Returning result: {"value":{"ELEMENT":"1"},"status":0} > info: [debug] Responding to client with success: {"status":0,"value":{"ELEMENT":"1"},"sessionId":"97fd4549-c40a-4e96-a60a-6ffb9ed7fd01"} > info: <-- POST /wd/hub/session/97fd4549-c40a-4e96-a60a-6ffb9ed7fd01/element 200 5585.076 ms - 87 {"status":0,"value":{"ELEMENT":"1"},"sessionId":"97fd4549-c40a-4e96-a60a-6ffb9ed7fd01"} > info: --> POST /wd/hub/session/97fd4549-c40a-4e96-a60a-6ffb9ed7fd01/element/1/click {"id":"1"} > info: [debug] Pushing command to appium work queue: ["element:click",{"elementId":"1"}] > info: [debug] [BOOTSTRAP] [debug] Got data from client: {"cmd":"action","action":"element:click","params":{"elementId":"1"}} > info: [debug] [BOOTSTRAP] [debug] Got command of type ACTION > info: [debug] [BOOTSTRAP] [debug] Got command action: click > info: [debug] [BOOTSTRAP] [debug] Returning result: {"value":true,"status":0} > info: [debug] Responding to client with success: {"status":0,"value":true,"sessionId":"97fd4549-c40a-4e96-a60a-6ffb9ed7fd01"} > info: <-- POST /wd/hub/session/97fd4549-c40a-4e96-a60a-6ffb9ed7fd01/element/1/click 200 3611.421 ms - 76 {"status":0,"value":true,"sessionId":"97fd4549-c40a-4e96-a60a-6ffb9ed7fd01"} > info: --> POST /wd/hub/session/97fd4549-c40a-4e96-a60a-6ffb9ed7fd01/elements {"using":"class name","value":"android.widget.EditText"} > info: [debug] Waiting up to 0ms for condition > info: [debug] Pushing command to appium work queue: ["find",{"strategy":"class name","selector":"android.widget.EditText","context":"","multiple":true}] > info: [debug] [BOOTSTRAP] [debug] Got data from client: {"cmd":"action","action":"find","params":{"strategy":"class name","selector":"android.widget.EditText","context":"","multiple":true}} > info: [debug] [BOOTSTRAP] [debug] Got command of type ACTION > info: [debug] [BOOTSTRAP] [debug] Got command action: find > info: [debug] [BOOTSTRAP] [debug] Finding android.widget.EditText using CLASS_NAME with the contextId: multiple: true > info: [debug] [BOOTSTRAP] [debug] Using: UiSelector[CLASS=android.widget.EditText] > info: [debug] [BOOTSTRAP] [debug] getElements selector:UiSelector[CLASS=android.widget.EditText] > info: [debug] [BOOTSTRAP] [debug] Element[] is null: (0) > info: [debug] [BOOTSTRAP] [debug] getElements tmp selector:UiSelector[CLASS=android.widget.EditText, INSTANCE=0] > info: [debug] [BOOTSTRAP] [debug] Failed to locate element. Clearing Accessibility cache and retrying. > info: [debug] [BOOTSTRAP] [debug] Finding android.widget.EditText using CLASS_NAME with the contextId: multiple: true > info: [debug] [BOOTSTRAP] [debug] Using: UiSelector[CLASS=android.widget.EditText] > info: [debug] [BOOTSTRAP] [debug] getElements selector:UiSelector[CLASS=android.widget.EditText] > info: [debug] [BOOTSTRAP] [debug] Element[] is null: (0) > info: [debug] [BOOTSTRAP] [debug] getElements tmp selector:UiSelector[CLASS=android.widget.EditText, INSTANCE=0] > info: [debug] [BOOTSTRAP] [debug] Element[] is null: (1) > info: [debug] [BOOTSTRAP] [debug] getElements tmp selector:UiSelector[CLASS=android.widget.EditText, INSTANCE=1] > info: [debug] [BOOTSTRAP] [debug] Element[] is null: (2) > info: [debug] [BOOTSTRAP] [debug] getElements tmp selector:UiSelector[CLASS=android.widget.EditText, INSTANCE=2] > info: [debug] [BOOTSTRAP] [debug] Element[] is null: (3) > info: [debug] [BOOTSTRAP] [debug] getElements tmp selector:UiSelector[CLASS=android.widget.EditText, INSTANCE=3] > info: [debug] [BOOTSTRAP] [debug] Returning result: {"value":[{"ELEMENT":"2"},{"ELEMENT":"3"},{"ELEMENT":"4"}],"status":0} > info: [debug] Responding to client with success: {"status":0,"value":[{"ELEMENT":"2"},{"ELEMENT":"3"},{"ELEMENT":"4"}],"sessionId":"97fd4549-c40a-4e96-a60a-6ffb9ed7fd01"} > info: <-- POST /wd/hub/session/97fd4549-c40a-4e96-a60a-6ffb9ed7fd01/elements 200 7287.293 ms - 121 {"status":0,"value":[{"ELEMENT":"2"},{"ELEMENT":"3"},{"ELEMENT":"4"}],"sessionId":"97fd4549-c40a-4e96-a60a-6ffb9ed7fd01"} > info: --> POST /wd/hub/session/97fd4549-c40a-4e96-a60a-6ffb9ed7fd01/element/2/value {"id":"2","value":["Some Name"]} > info: [debug] Pushing command to appium work queue: ["element:setText",{"elementId":"2","text":"Some Name","replace":false}] > info: [debug] [BOOTSTRAP] [debug] Got data from client: {"cmd":"action","action":"element:setText","params":{"elementId":"2","text":"Some Name","replace":false}} > info: [debug] [BOOTSTRAP] [debug] Got command of type ACTION > info: [debug] [BOOTSTRAP] [debug] Got command action: setText > info: [debug] [BOOTSTRAP] [debug] Using element passed in. > info: [debug] [BOOTSTRAP] [debug] Attempting to clear using UiObject.clearText(). > info: [debug] [BOOTSTRAP] [debug] Sending plain text to element: Some Name > info: [debug] [BOOTSTRAP] [debug] Returning result: {"value":true,"status":0} > info: [debug] Responding to client with success: {"status":0,"value":true,"sessionId":"97fd4549-c40a-4e96-a60a-6ffb9ed7fd01"} > info: <-- POST /wd/hub/session/97fd4549-c40a-4e96-a60a-6ffb9ed7fd01/element/2/value 200 16926.651 ms - 76 {"status":0,"value":true,"sessionId":"97fd4549-c40a-4e96-a60a-6ffb9ed7fd01"} > info: --> POST /wd/hub/session/97fd4549-c40a-4e96-a60a-6ffb9ed7fd01/element/4/value {"id":"4","value":["Some@example.com"]} > info: [debug] Pushing command to appium work queue: ["element:setText",{"elementId":"4","text":"Some@example.com","replace":false}] > info: [debug] [BOOTSTRAP] [debug] Got data from client: {"cmd":"action","action":"element:setText","params":{"elementId":"4","text":"Some@example.com","replace":false}} > info: [debug] [BOOTSTRAP] [debug] Got command of type ACTION > info: [debug] [BOOTSTRAP] [debug] Got command action: setText > info: [debug] [BOOTSTRAP] [debug] Using element passed in. > info: [debug] [BOOTSTRAP] [debug] Attempting to clear using UiObject.clearText(). > info: [debug] [BOOTSTRAP] [debug] Sending plain text to element: Some@example.com > info: [debug] [BOOTSTRAP] [debug] Returning result: {"value":true,"status":0} > info: [debug] Responding to client with success: {"status":0,"value":true,"sessionId":"97fd4549-c40a-4e96-a60a-6ffb9ed7fd01"} > info: <-- POST /wd/hub/session/97fd4549-c40a-4e96-a60a-6ffb9ed7fd01/element/4/value 200 21149.764 ms - 76 {"status":0,"value":true,"sessionId":"97fd4549-c40a-4e96-a60a-6ffb9ed7fd01"} > info: --> POST /wd/hub/session/97fd4549-c40a-4e96-a60a-6ffb9ed7fd01/touch/perform {"actions":[{"action":"press","options":{"x":100,"y":500}},{"action":"wait","options":{"ms":2}},{"action":"moveTo","options":{"x":100,"y":100}},{"action":"release","options":{}}]} > info: [debug] Pushing command to appium work queue: ["swipe",{"startX":100,"startY":500,"endX":100,"endY":100,"steps":0}] > info: [debug] [BOOTSTRAP] [debug] Got data from client: {"cmd":"action","action":"swipe","params":{"startX":100,"startY":500,"endX":100,"endY":100,"steps":0}} > info: [debug] [BOOTSTRAP] [debug] Got command of type ACTION > info: [debug] [BOOTSTRAP] [debug] Got command action: swipe > info: [debug] [BOOTSTRAP] [debug] Display bounds: [0,0][480,800] > info: [debug] [BOOTSTRAP] [debug] Display bounds: [0,0][480,800] > info: [debug] [BOOTSTRAP] [debug] Swiping from [x=100.0, y=500.0] to [x=100.0, y=100.0] with steps: 0 > info: [debug] [BOOTSTRAP] [debug] Returning result: {"value":true,"status":0} > info: [debug] Responding to client with success: {"status":0,"value":true,"sessionId":"97fd4549-c40a-4e96-a60a-6ffb9ed7fd01"} > info: <-- POST /wd/hub/session/97fd4549-c40a-4e96-a60a-6ffb9ed7fd01/touch/perform 200 903.431 ms - 76 {"status":0,"value":true,"sessionId":"97fd4549-c40a-4e96-a60a-6ffb9ed7fd01"} > info: --> POST /wd/hub/session/97fd4549-c40a-4e96-a60a-6ffb9ed7fd01/element {"using":"name","value":"Save"} > info: [debug] Waiting up to 0ms for condition > info: [debug] Pushing command to appium work queue: ["find",{"strategy":"name","selector":"Save","context":"","multiple":false}] > info: [debug] [BOOTSTRAP] [debug] Got data from client: {"cmd":"action","action":"find","params":{"strategy":"name","selector":"Save","context":"","multiple":false}} > info: [debug] [BOOTSTRAP] [debug] Got command of type ACTION > info: [debug] [BOOTSTRAP] [debug] Got command action: find > info: [debug] [BOOTSTRAP] [debug] Finding Save using NAME with the contextId: multiple: false > info: [debug] [BOOTSTRAP] [debug] Using: UiSelector[DESCRIPTION=Save, INSTANCE=0] > info: [debug] [BOOTSTRAP] [debug] Using: UiSelector[TEXT=Save, INSTANCE=0] > info: [debug] [BOOTSTRAP] [debug] Failed to locate element. Clearing Accessibility cache and retrying. > info: [debug] [BOOTSTRAP] [debug] Finding Save using NAME with the contextId: multiple: false > info: [debug] [BOOTSTRAP] [debug] Using: UiSelector[DESCRIPTION=Save, INSTANCE=0] > info: [debug] [BOOTSTRAP] [debug] Using: UiSelector[TEXT=Save, INSTANCE=0] > info: [debug] [BOOTSTRAP] [debug] Returning result: {"value":"No element found","status":7} > info: [debug] Condition unmet after 7910ms. Timing out. > info: [debug] Responding to client with error: {"status":7,"value":{"message":"An element could not be located on the page using the given search parameters.","origValue":"No element found"},"sessionId":"97fd4549-c40a-4e96-a60a-6ffb9ed7fd01"} > info: <-- POST /wd/hub/session/97fd4549-c40a-4e96-a60a-6ffb9ed7fd01/element 500 7913.313 ms - 195 > info: --> DELETE /wd/hub/session/97fd4549-c40a-4e96-a60a-6ffb9ed7fd01 {} > info: Shutting down appium session > info: [debug] Pressing the HOME button > info: [debug] executing cmd: D:\android-sdk\sdk\platform-tools\adb.exe -s emulator-5554 shell "input keyevent 3" > info: [debug] Stopping logcat capture > info: [debug] Logcat terminated with code null, signal SIGTERM > info: [debug] [BOOTSTRAP] [debug] Got data from client: {"cmd":"shutdown"} > info: [debug] [BOOTSTRAP] [debug] Got command of type SHUTDOWN > info: [debug] [BOOTSTRAP] [debug] Returning result: {"value":"OK, shutting down","status":0} > info: [debug] Sent shutdown command, waiting for UiAutomator to stop... > info: [debug] [BOOTSTRAP] [debug] Closed client connection > info: [debug] [UIAUTOMATOR STDOUT] INSTRUMENTATION_STATUS: current=1 > info: [debug] [UIAUTOMATOR STDOUT] INSTRUMENTATION_STATUS: id=UiAutomatorTestRunner > info: [debug] [UIAUTOMATOR STDOUT] INSTRUMENTATION_STATUS: class=io.appium.android.bootstrap.Bootstrap > info: [debug] [UIAUTOMATOR STDOUT] INSTRUMENTATION_STATUS: stream=. > info: [debug] [UIAUTOMATOR STDOUT] INSTRUMENTATION_STATUS: numtests=1 > info: [debug] [UIAUTOMATOR STDOUT] INSTRUMENTATION_STATUS: test=testRunServer > info: [debug] [UIAUTOMATOR STDOUT] INSTRUMENTATION_STATUS_CODE: 0 > info: [debug] [UIAUTOMATOR STDOUT] INSTRUMENTATION_STATUS: stream= > info: [debug] [UIAUTOMATOR STDOUT] Test results for WatcherResultPrinter=. > info: [debug] [UIAUTOMATOR STDOUT] Time: 89.301 > info: [debug] [UIAUTOMATOR STDOUT] OK (1 test) > info: [debug] [UIAUTOMATOR STDOUT] INSTRUMENTATION_STATUS_CODE: -1 > info: [debug] UiAutomator shut down normally > info: [debug] Cleaning up android objects > info: [debug] Cleaning up appium session > info: [debug] Responding to client with success: {"status":0,"value":null,"sessionId":"97fd4549-c40a-4e96-a60a-6ffb9ed7fd01"} > info: <-- DELETE /wd/hub/session/97fd4549-c40a-4e96-a60a-6ffb9ed7fd01 200 8799.959 ms - 76 {"status":0,"value":null,"sessionId":"97fd4549-c40a-4e96-a60a-6ffb9ed7fd01"} 参考:http://blog.csdn.net/jlminghui/article/details/41121479 本文转自贺满博客园博客,原文链接:http://www.cnblogs.com/puresoul/p/4696825.html,如需转载请自行联系原作者。

资源下载

更多资源
Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册