Service层单元测试实践 为了更好的持续集成,我们需要单元测试覆盖到逻辑层(Service)和数据访问层(Dao)。 1. Service层开展单元测试的困境 Dao层我们可以使用Unitils、Spring、Dbunit结合,Dbunit方便开发人员准备数据,Spring配置文件也为单元测试专门做了优化,使用了测试数据源,事务的问题也解决。 但是Service层的问题就复杂很多,遇到的问题主要如下 1、业务逻辑复杂,分支繁多。不仅要构造正常的情况,还要测试异常的分支,这比Dao仅仅是几条sql就复杂多了。复杂的逻辑加上很多异常无法构造,一些关键的异常分支无法覆盖。 2、数据库垂直切分的设计,Service层不得以操作了多个数据库,而连接多个数据库导致测试极慢,另外还因为涉及到跨数据库事务的难题,这个时候使用DBUnit来准备每个数据库的数据的方法已经不能适应了,整个数据库的环境是不稳定的。 3、Service层的Spring配置文件复杂,不仅包括了数据库的配置,还有JMS队列、缓存等等。启动测试就需要这些环境的配合,稍微一个不小心就会出现配置错误,整个测试失败。测试受环境影响,容易集成失败。 2. 解决方案 经过大量的实践,我们认为不应该是让Service层的单元测试依赖太多的东西,,单元测试要体现“单元”的概念,不依赖数据库、不依赖Spring上下文。 根据这个原则,我们考虑使用使用Mock对象,把Service层用到的Dao等对象都一一mock并插入到Service对象中。然后通过Unitils模拟Dao的返回值,或者抛出异常。这样就可以把Service的测试完全隔离开。经过处理后,Service的覆盖率和处理速度都得到了提升。 下面根据一个实际的例子讲解如何开展Service层的单元测试。 订单业务逻辑是这样一个场景: 用户在网站上下了一个订单,后台处理订单,OrderService对象提供了一个processOrder的方法给外部调用,首先根据订单Id获取订单的信息,根据订单中关联的accountId获得用户的帐户相关信息,然后判断帐户中的余额是否大于当前订单的金额,如果是,则在用户帐户上扣取订单相应的金额,然后返回成功。如果否,则直接返回失败。 OrderService的代码如下 Java代码 收藏代码 public class OrderService { OrderDao orderDao; AccountDao accountDao; /** * 处理订单,在用户的帐户中扣取订单的金额 * * @param orderId * @return */ @Transactional public boolean processOrder(int orderId) { // 获取订单详情 Order order = orderDao.getOrder(orderId); Assert.notNull(order, "orderId is valid"); // 获取帐户信息 Account account = accountDao.getAccount(order.getAccountId()); Assert.notNull(account, "accountId is valid"); // 判断当前用户帐户余额是否大于订单的金额 if (account.getBalance() > order.getOrderAmount()) { // 更新用户的帐户余额,减去订单的金额 accountDao.
获悉Spark最近要出书了,突然有很多感慨,心想不如写点东西出来,算是友情支持,也算是个人总结。观点尽量中立,内容尽量煽情。
2015年2月已经出书,
完整电子版下载地址:
http://download.csdn.net/detail/yangzhaohui168/9090369
本着牛哥“站在巨人的肩膀上”的理论,在捧Spark之前,要先捧一下她的前辈们。大数据系统中最核心的莫过于分布式处理框架,因为框架负责job执行的方方面面,如job分解、task调度与执行、错误容忍、数据流等等。较早(04年发表)也是最重要的贡献是Google的MapReduce框架,她将函数式编程思想引入到分布式数据处理中,仅仅用两个函数(map和reduce)就解决了一大类的大数据批处理问题,用户也再也不用担心分布式带来的诸多系统层面问题。MapReduce缺点也很明显:处理流程过于固定,不支持迭代,job执行时间一般较长。MapReduce的开源实现Hadoop在08年的时候赢得了TeraSort冠军,开始占领市场,到今天,整个生态圈已经庞大到有些臃肿。微软在沉寂了几年后,08年推出了与MapReduce直接竞争的Dryad,以DAG型的数据流取代了MapReduce固定的数据流,更复杂但功能更强。次年的DryadLINQ将更多的函数式思想(其实很多来源于C#的LINQ)引入到分布式编程范型中,到今天看来也非常先进。好了,该Spark登场了,Spark最大的贡献在于她的数据模型RDD,以前的框架都把数据当成原始的KV键值对,整个处理流程中不同阶段的数据没有明确关系。RDD给出了明确的数据逻辑关系,建立了数据依赖及数据模型,最后也能方面地将数据模型转化为具体的处理任务。Spark的编程范型其实借鉴了DryadLINQ的范型。至于内存cache、迭代计算等特性,其实把MapReduce或Dryad的实现机制改动一下也可以做到。当然这些特性对减低job执行时间很重要,也是Spark的卖点。对了,EPFL的Scala语言也功不可没,名字上就很scalable。她的关键词是学院派、函数式、静态类型、面向对象、Java兼容。多数人认为Scala是Java的接班人。如果将Spark比作孙悟空,Scala就是他的金箍棒。
学术喷完了,喷一下出书的问题。不得不说,当一个东西写成书的时候,是这个东西成熟的时候,也意味着在学术上已经out了。《Hadoop: The Definitive Guide》09年出版,是Hadoop炙手可热的时候,大多数人(也包括我自己)都是从这本书开始入门的。11年的《Programming Pig》也不错,12年的《Programming Hive》也可以,这些书都是在系统还没有到1.0版本的时候出的,佩服O'Reilly的速度。这本书也是在Spark还在0.7版本(可能出版的时候已经0.8/0.9)的时候出的,全书应该2-300页,用法介绍应该会多些,不过对广大用户应该够用了。O’Reilly书的特点就是新但不深入,对于想要了解内部运行机制的人来说,还是阅读代码吧。J
再谈一下Berkeley这些Geek们,他们继承了Bill Joy的光芒,一定要做前沿、实用、solid的工作,这也是为什么他们的论文题目总是“SystemName: A system for ***”。从底层Tachyon到框架Spark,到资源管理Mesos,再到上层Shark/MLBase/Bagel/Streaming等等,都是很系统的工作。对他们真是又爱又恨,爱的是系统都开源,可以学习到先进技术;恨的是他们把idea都想完做完了,J
最早关注Matei是他为Hadoop做的各种调度器:LATE/Delay/Fair调度器。LATE那篇引用率很高,貌似我也贡献了一个引用。但是调度器的贡献用户一般感受不到,这显然不是Matei去Berkeley的初衷。09年Matei综合了前辈们的工作,加上头脑风暴和原型实现,在10年的HotCloud发了他的占位paper。之后的2年,不断设计、实现、优化、与互联网企业推广试用,终于在12年系统成型并夺得NSDI的best paper。Shark也类似,可见做system,不仅苦逼,还需要执着与承受力。古语云“天时地利人和”,AMPLab全占了。不过最重要的是,这些Geek们在光明的道路上一直勇敢向前,值得我们学习与效仿。这些Geek们也很nice,在邮件列表上有问必答,“知无不言,言无不尽”,很受用。Matei今年要毕业当老师了,好想知道他带学生的样子。
有幸3月份在清华见到了Shark的作者Reynold Xin,请教了不少问题,也祝贺Shark高中SIGMOD 2013。辛博士在国内的推广活动比较成功,希望多来做做报告。国内还有很多单位如Intel对Spark的贡献挺大,他们是对开源有激情、有能力的一帮人,赞一下。
不多废话了,有时间还是多想想为这个项目贡献点东西吧。
另外,强烈建议封面换为海星,不然怎么体现Spark。等到Shark出书的时候,再整成鱼而且是鲨鱼吧。
@JerryLead
csxulijie@gmail.com
PhD Candidate @ ISCAS
Intern @ System Research Group, MSRA
2013-04-27
转自:http://www.cnblogs.com/jerrylead/archive/2013/04/27/Spark.html
结构体是C语言中一种非常重要的数据结构。与数组不同,结构体类型的变量的成员变量(数组称元素)可以具有不同的类型,并通过成员变量的名称获取指定成员。联合和结构体相似,但联合类型的变量的所有成员都共享同一存储空间,每次只能存储一个成员。枚举类型是一组命名了的整数值。结构体、联合、枚举和数组都是用于创建多种多样的、与基本数据类型同样的用户自定义的数据类型。
结构体 结构体类型的声明 结构体类型的声明格式如下:
struct { 类型 成员变量1; 类型 成员变量2; ... } 变量1, 变量2; 变量1和变量2都是该结构体类型的变量,结构体类型的变量的成员变量按声明的顺序在内存中依序存储。结构体为其所有成员设置了单独的命名空间,因此可以在结构体外存在与结构体内成员同名的变量。
结构体类型变量的成员可以是数组类型的变量,数组变量的元素也可以是结构体类型的。
结构体类型的变量的初始化 结构体类型的变量的初始化是依次列出结构体类型的变量各成员的值,用,隔开,并用大括号扩起来,形式如下
struct { 类型 成员变量1; 类型 成员变量2; ... } 变量1 = {成员变量1的初始值, 成员变量2的初始化值,...}, 变量2 = {成员变量1的初始值, 成员变量2的初始化值,...}; 注意:初始化式中的初始化值必须按结构成员的声明顺序给出,且初始化式中的表达式必须是常量表达式。
结构体类型的变量的操作 结构体类型的变量通过成员名称访问其内部的成员,其访问格式为:
结构体类型变量.成员变量 .是C语言的一个运算符,优先级和++和--相同,几乎高于所有其他的运算符。
结构体类型变量的成员是一个左值,可以看作一个变量使用。类型一致的结构体类型变量之间可以使用赋值运算符相互赋值。
使用结构体类型作为函数的参数和返回值时,实际上使用的都是结构体类型的变量的副本。这样结构比较大的时候,会产生大量的开销,所以一般都使用结构体类型的变量的指针。
结构体类型 按照声明结构体类型时定义变量的方式要求变量必须在一个地方完全声明,否则当在新的地方用同样的方式定义变量时,不仅造成代码的结构臃肿,更重要的是C语言会将这些变量看成是不同的类型。为了解决这个问题,C语言利用结构标记来标识特定结构体类型的名字,这样就可以在别的地方使用结构标记来声明属于同样结构体类型的变量了。结构标记的声明格式如下:
struct 结构标记 { 类型 成员变量1; 类型 成员变量2; ... } 变量1, 变量2; struct 结构标记 变量3; struct 结构标记 变量4; 注意:使用结构标记时,不能省略标记前面的struct单词。
除了使用结构标记,还可以使用typedef来为定义结构体类型的别名,其使用形式为:
typedef struct { 类型 成员变量1; 类型 成员变量2; .
转自:http://www.365mini.com/page/difference-of-define-and-const.htm
众所周知,在PHP中(PHP 4及以后),我们可以使用函数define()来定义常量,例如:
<?php define('PI', 3.14159); //定义一个名为PI的常量 echo PI; //输出:3.14159 ?> 不过,在PHP 5.3.0之后,除了使用函数define()之外,我们还可以使用PHP关键字const来定义常量。
例如:
<?php //以下代码需在PHP 5.3.0及之后的版本中运行 const PI = 3.14159; //使用const关键字定义一个名为PI的常量 echo PI; //输出:3.14159 ?> 虽然上述两种方式均可以定义常量,但是它们之间有什么不同之处呢。下面我们来一一讲解PHP中define()函数和const关键字定义常量的区别:
1.版本差异
首先,毫无疑问的是,两种定义常量的方式之间存在版本差异,函数define()在PHP4和PHP5中均可使用,关键字const只能在PHP 5.3.0及其后的版本中使用。
2.定义位置的区别
由于函数define()定义的常量是在执行define()函数时定义的,因此可以在函数内、循环内、if语句内等函数能够被调用的任何地方使用define()函数定义常量。与define()不同的是,由于const关键字定义的常量是在编译时定义的,因此const关键字定义常量必须处于最顶端的作用区域。这也就意味着不能在函数内、循环内以及if语句之内用const来定义常量。
<?php //使用const关键字定义常量必须处于最顶端的作用区域 //也就是可以在编译时直接解析定义的地方 const DEMO = 'DEMO'; class Person{ const MAN = '男'; const WOMAN = '女'; } interface USB{ const VERSION_2 = '2.0'; const VERSION_3 = '3.0'; } ?> 3.对值的表达式支持的差异
虽然关键字const和define()定义的常量值都只能为null或标量数据(boolean,integer,float和string类型)以及resource类型(不推荐定义resource类型的常量,否则可能出现无法预知的结果)。不过,由于关键字const定义常量是在编译时定义的,因此const关键字定义的常量值的表达式中不支持算术运算符、位运算符、比较运算符等多种运算符,而这些运算符在define()函数定义常量时都是可以直接使用的。
<?php define('DEFINE_VAR1', 1 << 1); //const CONST_VAR1 = (1 << 1); //const不支持位运算符,PHP会报语法错误 define('DEFINE_VAR2', 1 + 1); //const CONST_VAR2 = 1 + 1 ; //const不支持算术运算符,PHP会报语法错误 define('DEFINE_VAR3', 1 == 1); //const CONST_VAR3 = 1 == 1 ; //const不支持比较运算符,PHP会报语法错误 $value = 3; define('DEFINE_VAR4', $value); //const CONST_VAR4 = $value ; //const不支持变量形式的值,PHP会报语法错误 define('DEFINE_VAR5', true || false); //const CONST_VAR5 = true || false ; //const不支持逻辑运算符,PHP会报语法错误 define('DEFINE_VAR6', 'Hello'.
CAS的核心就是其Ticket,及其在Ticket之上的一系列处理操作。CAS的主要票据有TGT、ST、PGT、PGTIOU、PT,其中TGT、ST是CAS1.0协议中就有的票据,PGT、PGTIOU、PT是CAS2.0协议中有的票据。 一 名词解释
TGT(Ticket Grangting Ticket) TGT是CAS为用户签发的登录票据,拥有了TGT,用户就可以证明自己在CAS成功登录过。TGT封装了Cookie值以及此Cookie值对应的用户信息。用户在CAS认证成功后,CAS生成cookie,写入浏览器,同时生成一个TGT对象,放入自己的缓存,TGT对象的ID就是cookie的值。当HTTP再次请求到来时,如果传过来的有CAS生成的cookie,则CAS以此cookie值为key查询缓存中有无TGT ,如果有的话,则说明用户之前登录过,如果没有,则用户需要重新登录。
ST(Service Ticket) ST是CAS为用户签发的访问某一service的票据。用户访问service时,service发现用户没有ST,则要求用户去CAS获取ST。用户向CAS发出获取ST的请求,如果用户的请求中包含cookie,则CAS会以此cookie值为key查询缓存中有无TGT,如果存在TGT,则用此TGT签发一个ST,返回给用户。用户凭借ST去访问service,service拿ST去CAS验证,验证通过后,允许用户访问资源。
PGT(Proxy Granting Ticket) Proxy Service的代理凭据。用户通过CAS成功登录某一Proxy Service后,CAS生成一个PGT对象,缓存在CAS本地,同时将PGT的值(一个UUID字符串)回传给Proxy Service,并保存在Proxy Service里。Proxy Service拿到PGT后,就可以为Target Service(back-end service)做代理,为其申请PT。
PGTIOU(Proxy Granting Ticket IOU) PGTIOU是CAS协议中定义的一种附加票据,它增强了传输、获取PGT的安全性。
PGT的传输与获取的过程:Proxy Service调用CAS的serviceValidate接口验证ST成功后,CAS首先会访问pgtUrl指向的https url,将生成的 PGT及PGTIOU传输给proxy service,proxy service会以PGTIOU为key,PGT为value,将其存储在Map中;然后CAS会生成验证ST成功的xml消息,返回给Proxy Service,xml消息中含有PGTIOU,proxy service收到Xml消息后,会从中解析出PGTIOU的值,然后以其为key,在map中找出PGT的值,赋值给代表用户信息的Assertion对象的pgtId,同时在map中将其删除。
PT(Proxy Ticket) PT是用户访问Target Service(back-end service)的票据。如果用户访问的是一个Web应用,则Web应用会要求浏览器提供ST,浏览器就会用cookie去CAS获取一个ST,然后就可以访问这个Web应用了。如果用户访问的不是一个Web应用,而是一个C/S结构的应用,因为C/S结构的应用得不到cookie,所以用户不能自己去CAS获取ST,而是通过访问proxy service的接口,凭借proxy service的PGT去获取一个PT,然后才能访问到此应用。
二 代码解析
CAS Ticket类图
TicketGrantingTicket 的 grantServiceTicket方法 方法声明:public synchronized ServiceTicket grantServiceTicket(final String id,final Service service, final ExpirationPolicy expirationPolicy, final boolean credentialsProvided)
方法描述:
1:生成SerivceTicketImpl
2:更新属性:
this.previousLastTimeUsed = this.lastTimeUsed;
半同步/半异步并发模式:父进程监听到新的客户端连接请求后,以通信管道通知进程池中的某一子进程:“嘿,有新的客户连接来了,你去accept,然后处理下!”,从而避免在进程间传递文件描述符。这种模式中,一个客户连接上的所有任务始终有同一个进程来处理。
具体细节,尽在代码中:
#ifndef PROCESSPOOL_H #define PROCESSPOOL_H #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <assert.h> #include <stdio.h> #include <unistd.h> #include <errno.h> #include <string.h> #include <fcntl.h> #include <stdlib.h> #include <sys/epoll.h> #include <signal.h> #include <sys/wait.h> #include <sys/stat.h> //描述一个子进程的类 class process { public: process() : m_pid( -1 ){} public: pid_t m_pid; //子进程pid int m_pipefd[2];//子进程与父进程通信管道(父进程通过管道通知选定的子进程:“有新的连接到来,你去accept") }; //进程池类:将需要处理的逻辑任务封装为任务类,作为模板参数,以提高代码复用 template< typename T > class processpool { private: //构造函数,creat函数调用 processpool( int listenfd, int process_number = 8 ); public: //给定服务器监听的socket,和进程数,创建子进程。(注:单例模式)。 为静态函数,因此可以直接以类名调用 static processpool< T >* create( int listenfd, int process_number = 8 ) { if( !
一、什么是JAVA的反射机制
Java反射是Java被视为动态(或准动态)语言的一个关键性质。这个机制允许程序在运行时透过Reflection APIs取得任何一个已知名称的类的内部信息,包括其方法(诸如public, static 等)、父类(例如Object)、实现接口(例如Cloneable),也包括属性和方法的所有信息,并可于运行时改变属性值或调用方法。
Java反射机制容许程序在运行时加载、探知、使用编译期间完全未知的类。Java可以加载一个运行时才得知名称的类,获得其完整结构。
简言之,JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
二、JDK中提供的Reflection API
Java反射相关的API在包java.lang.reflect中,JDK 1.6.0的reflect包如下图:
该类下的几个主要类和接口 三、JAVA反射机制提供了什么功能
=========================================
Java反射机制提供如下功能(用途):
在运行时判断任意一个对象所属的类
在运行时构造任意一个类的对象
在运行时判段任意一个类所具有的成员变量和方法
在运行时调用任一个对象的方法
在运行时创建新类对象
=======================================
一个对象的创建分三步完成:
1、加载类到内存; 2、静态资源初始化; 3、创建对象;
一个类对应一个字节码文件*.class,反射研究的就是字节码文件;一个字节码文件中主要包含类的成员变量、方法、构造方法;通过该字节码文件可以获取该类的相关信息。同一个字节码文件可以构建多个对象;
//类的字节码文件 MyA a1=new MyA(); //获得该类的字节码文件 Class clazz=a1.getClass(); 对象类型有字节码文件,基础的数据类型也有相应的字节码文件。
int.class void.class 在使用Java的反射功能时,基本首先都要获取类的Class字节码对象,再通过Class对象获取其他的对象。
1、获取类的Class字节码对象
Class 类的实例表示正在运行的 Java 应用程序中的类和接口。获取类的Class对象有多种方式:
2、获取类的属性
可以通过反射机制得到某个类的某个属性,然后可以改变对应于这个类的某个实例的该属性值。JAVA 的Class<T>类提供了几个方法获取类的属性。
public Field getField(String name) 返回某类一个public修饰的成员变量(public,包括父类中定义);
public Field[] getFields() 返回一个数组,数组中包含某类下的public修饰的所有成员变量(public,包括父类中定义);
public Field getDeclaredField(String name) 返回某类一个private修饰的成员变量(private,不包括父类中定义);
public Field[] getDeclaredFields() 返回一个数组,数组中包含某类下的所有private修饰的成员变量(private,不包括父类中定义);
3、获取类的方法
通过反射机制得到某个类的某个方法,然后可以调用对应于这个类的某个实例的该方法,Class<T>类提供了几个方法获取类的方法。
public Method getMethod(String name,Class<?>... parameterTypes) 通过方法名和方法的入参得到一个某类下的public修饰的Method方法对象(public,包括父类中定义);
1:安装ggplot2
install.packages('ggplot2')
2:导入gglot2包
require(ggplot2)
3:查看帮助
help(ggplot2)
4:画mtcars测试下
ggplot(mtcars, aes(x = wt, y = mpg)) + geom_point(colour = "red", size = 3)
Learning Spark: Lightning-Fast Big Data Analysis 中文翻译行为纯属个人对于Spark的兴趣,仅供学习。
如果我的翻译行为侵犯您的版权,请您告知,我将停止对此书的开源翻译。
Translation the book of Learning Spark: Lightning-Fast Big Data Analysis is only for spark developer educational purposes. If I violated your copyright, please let me know.
Learning Spark 英文原版 Learning Spark: Lightning-Fast Big Data Analysis http://shop.oreilly.com/product/0636920028512.do
在 databricks 官网上发布了此书的优惠码(promo code: BWORM),在购买时别忘了使用省银子。 https://databricks.com/spark/developer-resources
中文翻译 GitHub: https://github.com/gaoxuesong/learning-spark-lightning-fast-big-data-analysis
GitBook: http://xuesong.gitbooks.io/learningspark/
GitBook is a tool for building beautiful books using Git and Markdown. It can generate your book in multiple formats: PDF, ePub, mobi or as a website.
#!/bin/sh myFile="/var /log/httpd/access.log" if [ ! -e "$myFile" ]; then touch "$myFile" fi -e和-f的区别是,-f代表常规文件(regular file),-e代表所有任何类型文件 参考如下: -e filename 如果 filename存在,则为真 -d filename 如果 filename为目录,则为真 -f filename 如果 filename为常规文件,则为真 -L filename 如果 filename为符号链接,则为真 -r filename 如果 filename可读,则为真 -w filename 如果 filename可写,则为真 -x filename 如果 filename可执行,则为真 -s filename 如果文件长度不为0,则为真 -h filename 如果文件是软链接,则为真 4. myPath="/var/log/httpd/" 5. myFile="/var /log/httpd/access.log" 6. 7. # 这里的-x 参数判断$myPath是否存在并且是否具有可执行权限 8. if [ ! -x "$myPath"]; then 9. mkdir "
multiple plots in one page
cookbook-R-multiplot
# Multiple plot function # # ggplot objects can be passed in ..., or to plotlist (as a list of ggplot objects) # - cols: Number of columns in layout # - layout: A matrix specifying the layout. If present, 'cols' is ignored. # # If the layout is something like matrix(c(1,2,3,3), nrow=2, byrow=TRUE), # then plot 1 will go in the upper left, 2 will go in the upper right, and # 3 will go all the way across the bottom.
数据抽象:是指定义数据和函数成员的能力; 封装:是指从常规访问中保护类成员的能力。 接口:成员函数定义了类的接口。通过将定义类所用到的数据和成员函数设置维为private来封装类。
第十二章: 类 1、 构造函数的初始化式只在构造函数的定义中而不是声明中指出。 2、 使用构造函数的初始化列表与在构造函数体中对类的成员变量进行赋值的区别:本质就在于前者是对变量进行初始化,而后者是对变量进行赋值。 理解:构造函数的执行分为两个阶段:先初始化阶段,再是普通计算阶段。 在初始化阶段构造函数将调用类类型的构造函数(没有初始化列表时调用默认构造函数)对类类型的成员变量进行初始化,在普通计算阶段才执行构造函数体的语句,因此在这时是对成员变量进行赋值,覆盖初始化阶段的初始值。 对内置类型,根据对象定义的位置不同,初始化阶段会不同(对全局对象,会将内置类型初始化为0,而局部变量则不初始化); 另外,对于那些const对象成员、引用成员、没有默认构造函数的类类型(否则会调用其默认构造函数,但其没有)等,则必须提供初始化列表进行显示初始化。 3、 建议构造函数使用初始化列表:一是效率:免去了普通计算阶段的复制过程;二是:对于那些const对象成员、引用成员、没有默认构造函数的类类型(否则会调用其默认构造函数,但其没有)等,则必须提供初始化列表进行显示初始化。 4、 注意:成员初始化的次序与成员定义的次序相同(而不是按在初始化列表中出现的次序进行),所以应尽量按定义的次序来给出初始化列表,并注意用一个成员来初始化其他成员时的先后问题。 5、 一个类只有没有定义任何构造函数时才会自动生成合成的默认构造函数。对类类型调用其默认构造函数进行初始化;而对内置类型,当对象定义在全局时才进行初始化,在局部对象中不进行初始化。 6、 如果类包括内置或复合类型(指针 引用)等成员,则不应依赖于合成的默认构造函数,应该定义自己的构造函数来初始化这些变量。 7、 类通常应该定义一个默认构造函数,并且在默认构造函数中给成员提供的初始应该指出对象时“空”的。 8、 为所有形参提供默认实参的构造函数也定义了默认构造函数。 9、 默认构造函数的使用误区:使用类A的默认构造函数定义对象: A a();//这是错误的,因为这会被编译器解释为定义了一个参数为空,返回一个对象A的函数。因此用默认构造函数时不能在后面带括号(带有参数的非默认构造函数则可以带括号,在括号里给出实参值)。但这种用法是对的:A a=A();//右边调用默认构造函数创建对象,并用该对象初始化对象a. 10 、隐式类类型转换:用单个实参来调用的构造函数定义了从参数类型到类类型的以个隐式转换。如此,可在需要一个类类型的地方传递一个该参数类型,从而编译器会调用该构造函数并以该参数为实参构造一个所需的类类型的临时对象。 但注意:这种隐式转换是否为我们所需要的!否则应该避免。 11、 抑制由构造函数定义的隐式转换: 将构造函数声明为explict来防止构造函数被用作隐式类型转换之用: 在构造函数声明前加上关键字explicit(在类外的构造函数定义体上不能再加explicit)。 此时编译器不不再使用构造函数作为类型转换(编译器会报错)。 12、 为转换而显示的使用构造函数: 任何构造函数(包括默认)都可以显示的创建临时对象,即类名后面直接带括号,括号里面给出要调用的构造函数的参数,而不给出对象名。(如:A();//创建一个无名的临时对象)。 13、 通常,除非用明确的理由需要隐式转换,否则单参数的构造函数前都应该加上explict以避免错误。 当需要类型转换时可用显示使用构造函数来显示的创建临时对象。 13、 类成员的显示初始化:当没有定义构造函数,且所有数据成员都为共有时,可按初始化数组元素的方式来初始化所有数据成员 如: struct A { int i; int* p}; A a={0,0};//a.i=0; a.p=o; (根据数据成员的声明次序进行初始化) 14、 友元机制允许一个类将其非共有成员的访问权授予指定的函数或类。 Friend只能出现在类内部。 友元声明可以在类中的任意位置:友元不是该类的成员,u因此它们不受其声明出现部分的访问控制影响。 15、 Static类成员:是类的组成部分,而不是某个对象的组成部分(为类的全体对象共有,因此可用于在类的全体对象间传递信息,如记录创建了多少个该类的对象)。Static的成员,只用在类中声明时指定static,在内外定义时不用重复指定为static。 16、 static数据成员:存在于类类型的每个对象中,且独立于该类的某个特定对象而存在,与该类关联,而非该类的某个对象。 Static数据成员必须在类外部定义(正好一次),因为其不是通过类的构造函数来初始化的,而是在定义时进行初始化。 常在类的非内联函数的定义文件中定义static数据成员(不用再重复指定为static),定义时与定义一般成员函数一样,需要在类型后,变量明前指定完全限定名,以指定属于哪个类,如: int A::static_member=10;(注,只要出现全完限定名,其后面的内容就是在类作用域中。) 特殊的:对cosnt static int 数据成员,只要其初始化式是一个常量表达式,就可以直接在类中进行初始化,(但其他类型的cosnt static数据成员,还是需要在类外部进行定义初始化):
桑基图可以用来表示各个节点之间转换 在R中可以直接定义点点之间的关系后使用相应的package画桑基图:
方法一: riverplot
library(riverplot) # 构造连接节点的数据框 edges = data.frame(N1 = paste0(rep(LETTERS[1:4], each = 4), rep(1:5, each = 16)), N2 = paste0(rep(LETTERS[1:4], 4), rep(2:6, each = 16)), Value = runif(80, min = 2, max = 5) * rep(c(1, 0.8, 0.6, 0.4, 0.3), each = 16), stringsAsFactors = F) # 筛选80%的记录,以免每个点都对应到4个点 edges = edges[sample(c(TRUE, FALSE), nrow(edges), replace = TRUE, prob = c(0.8, 0.2)),] head(edges) nodes = data.frame(ID = unique(c(edges$N1, edges$N2)), stringsAsFactors = FALSE) # nodes$x = as.
题目
数轴上从左到右有n各点a[0], a[1], ……,a[n -1],给定一根长度为L的绳子,求绳子最多能覆盖其中的几个点。
思路一
遍历所有区间跟绳子L比较。 i遍历区间起点,j遍历区间终点。 时间复杂度为O(n^2)
代码一
<code class=" hljs cpp" style="box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; padding: 0.5em; color: rgb(0, 0, 0); border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; display: block; background-color: transparent !important;"> <span class="hljs-comment" style="box-sizing: border-box; color: rgb(136, 136, 136);">/*------------------------------------- * 日期:2015-02-08 * 作者:SJF0115 * 题目: 绳子覆盖 * 来源:百度2014 * 博客: ------------------------------------*/</span> <span class="hljs-preprocessor" style="box-sizing: border-box; color: rgb(136, 0, 0);">#include <iostream></span> <span class="
题目
数轴上从左到右有n各点a[0], a[1], ……,a[n -1],给定一根长度为L的绳子,求绳子最多能覆盖其中的几个点。
思路一
遍历所有区间跟绳子L比较。 i遍历区间起点,j遍历区间终点。 时间复杂度为O(n^2) 代码一
/*------------------------------------- * 日期:2015-02-08 * 作者:SJF0115 * 题目: 绳子覆盖 * 来源:百度2014 * 博客: ------------------------------------*/ #include <iostream> #include <vector> #include <cstring> #include <algorithm> using namespace std; class Solution { public: // points 给定点 L 绳子长度 int RopeCover(vector<int> points,int L) { int size = points.size(); if(size <= 0){ return 0; }//if // 所能覆盖的最多点数 int max = 0; int start = 0,end = 0; // i起点 j终点 遍历所有区间; for(int i = 0;i < size-1;++i){ for(int j = i+1;j < size;++j){ if(points[j] - points[i] <= L && j - i + 1 > max){ max = j - i + 1; start = i; end = j; }//if } }//for cout<<"
很多前端都是用.clearfix:after{ .....} 和 .clearit{....}的组合 来清除浮动, 下面我来讲解下这俩种的用法: 首先大家切页面经常用到浮动 float:left; float:right; 有浮动就需要清除他们,
after伪类由于受到ie6 7的不支持所以大多数时候,一般都需要定义一个固定的class名设置属性clear的值both的div 两者配合使用.
<style type="text/css">
*{ margin: 0; padding: 0}
.left{ float: left;}
.clearfix:after { content:"."; display:block; height:0; visibility:hidden; clear:both; } //伪类清除
.clearfix { zoom:1; } .clearit { clear:both; height:0; font-size:0; overflow:hidden; } //设置class名清除
.main{ width: 1000px;}
.myRight,.myLeft{ width: 200px; height: 200px; background: #ddd;}
.myRight{ background: red}
</style>
///第一种结构
<div class="main">
<div class="myLeft left">左侧</div>
<div class="myRight left">右侧</div> </div>
2019独角兽企业重金招聘Python工程师标准>>> ####在配防火墙时,能关就关,不能关就开端口
一、介绍
(1)如果是伪分布式模式,可以考虑将防火墙直接关掉(一般不用于生产,按照分布式的来也可以,2将介绍分布式的)
查看防火墙状态,命令:service iptables status
改变防火墙命令: 1)永久性生效,重启后不会复原 开启: chkconfig iptables on 关闭: chkconfig iptables off 2)即时生效,重启后复原 开启: service iptables start 关闭: service iptables stop 我们要做的是:命令:service iptables status 来查看防火墙是否启动,启动了就关闭: service iptables stop ,不管原先防火墙是否启动,以命令: chkconfig iptables --list查看服务开机开启状态,用: chkconfig iptables off将状态设为off
(2)如果是分布式模式,就要请管理员将防火墙中需要的端口开启,:他肯定不会为你hadoop关防火墙,如果自己管防火墙,可以进行以下配置:
修改/etc/sysconfig/iptables 文件,添加以下内容: -A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT -A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT
最近刚刚换了新部门,被安排的工作通过wmi监控hyper-V虚拟机,与其说wmi监控虚拟机,不如说,通过wmi查看hyper-V宿主机的相关参数,从而得到宿主机上挂载的虚拟机的状态。我们采用vbs脚本连接wmi,通过WQL语句查询相关参数,这里就不详细说vbs脚本,主要整理下,监控指标以及wmi命名空间和属性。
上面写了好多次WMI,其实对于我们来说这个词还是比较熟悉的,当你打开我的电脑的管理界面时候,服务下面就是WMI服务,什么是WMI呢,这里我就不解释了,因为我也是百度,没有形成自己的定义。如何查看WMI呢,就我所了解的有两种方式:一、通过win+R打开运行界面,输入wbemtest,然后回车,
此界面就是windows自带的WMI连接工具,点击连接,选择命名空间。二、采用其他WMI查看工具,可以通过WMI下载链接进行下载,如下图所示:
命名空间:Root\CIMV2
属性:
Win32_OperatingSystem:获取宿主机系统版本、物理内存使用情况、虚拟内存使用情况
Win32_PerfRawData_PerfOS_Memory:获取宿主机内存交换空间、页面空间等数据
Win32_PerfRawData_VidPerfProvider_HyperVVMVidPartition:获取被分配的物理页面、远程物理页面
Win32_PerfRawData_HvStats_HyperVHypervisorRootPartition:获取虚拟TLB页面、保存页面数据
Win32_PerfRawData_VmmsVirtualMachineStats_HyperVVirtualMachineHealthSummary:获取虚拟机健康状态
Win32_PerfRawData_HvStats_HyperVHypervisor:获取逻辑处理器数量、虚拟处理器数量
Win32_ComputerSystem:获取宿主机系统信息、物理处理器数量、物理内存大小等信息
Win32_Service:获取系统服务信息
Win32_PerfRawData_HvStats_HyperVHypervisorVirtualProcessor:获取宾客CPU使用率、管理程序CPU使用率、CPU空闲率(需要通过RunTime计算)
Win32_PerfRawData_Tcpip_NetworkInterface:获取物理机网络信息
Win32_PerfRawData_PerfDisk_PhysicalDisk:获取IO数据
Win32_LogicalDisk:获取磁盘空间信息
Win32_PerfRawData_NvspSwitchStats_HyperVVirtualSwitch:获取虚拟交换机信息
Win32_PerfRawData_StorageStats_HyperVVirtualStorageDevice:获取虚拟储存状态(但是我没有获取到,据了解,不同服务器有不同)
Win32_PerfRawData_IdePerfProvider_HyperVVirtualIDEController:获取虚拟IDE信息
Win32_PerfRawData_EthernetPerfProvider_HyperVLegacyNetworkAdapter:获取Legacy虚拟网络适配器信息
Win32_PerfRawData_NvspNicStats_HyperVVirtualNetworkAdapter:获取虚拟适配器信息
Win32_PerfRawData_HvStats_HyperVHypervisorPartition:获取页面信息、虚拟处理器
Win32_PerfRawData_PerfOS_Processor:获取宿主机CPU使用数据
(还有很多其他通用属性,在所有的windows系统都可是查到的,我这里就不一一列举了,有兴趣的可以自己看看研究下)
命名空间:root\virtualization\v2(不同的系统取得命名空间也会有些差异,我们是server 2008 r2的,但是总体来说root\virtualization这部分不会变,最后的\v2这个看情况)
属性:
MSVM_ComputerSystem:获取宿主计算机、虚拟机系统信息,包括系统名称、主机名称、运行时间(虚拟机)、安装时间(虚拟机)、运行状态等
Msvm_Memory:获取宿主机和虚拟机内存数据,包括物理机内存、numa节点内存、虚拟机分配内存
Msvm_Processor:获取逻辑处理器、虚拟机分配的处理器使用情况
以上是我再开发过程中使用到的内容,属性和指标可能对应的不是很好,如果那里有问题,请大家告诉我,我再修改。
进行协议解析时,总是会遇到各种各样的数据转换的问题,从二进制到十进制,从字节串到整数等等
废话不多上,直接上例子
整数之间的进制转换:
10进制转16进制: hex(16) ==> 0x1016进制转10进制: int('0x10', 16) ==> 16 类似的还有oct(), bin() ------------------- 字符串转整数: 10进制字符串: int('10') ==> 1016进制字符串: int('10', 16) ==> 1616进制字符串: int('0x10', 16) ==> 16 ------------------- 字节串转整数: 转义为short型整数: struct.unpack('<hh', bytes(b'\x01\x00\x00\x00')) ==> (1, 0)转义为long型整数: struct.unpack('<L', bytes(b'\x01\x00\x00\x00')) ==> (1,) ------------------- 整数转字节串: 转为两个字节: struct.pack('<HH', 1,2) ==> b'\x01\x00\x02\x00'转为四个字节: struct.pack('<LL', 1,2) ==> b'\x01\x00\x00\x00\x02\x00\x00\x00' ------------------- 字符串转字节串: 字符串编码为字节码: '12abc'.encode('ascii') ==> b'12abc'数字或字符数组: bytes([1,2, ord('1'),ord('2')]) ==> b'\x01\x0212'16进制字符串: bytes().fromhex('010210') ==> b'\x01\x02\x10'16进制字符串: bytes(map(ord, '\x01\x02\x31\x32')) ==> b'\x01\x0212'16进制数组: bytes([0x01,0x02,0x31,0x32]) ==> b'\x01\x0212' ------------------- 字节串转字符串: 字节码解码为字符串: bytes(b'\x31\x32\x61\x62').
举例介绍matlab coder的使用方法
工具/原料 matlab
方法/步骤 MATLAB Coder 工具是 MathWorks 公司在 2011年推出的 Matlab2011a版本中推陈出新的产品,它可以将MATLAB 函数直接生成 C 代码。主要作用体现在一下几点。
1、集成: MATLAB算法变成源代码或者静态库,用于已有的C环境。
2、原型:MATLAB算法作为独立可执行文件。在没有MATLAB的环境下进行使用。
3、加速:是代码更高的效率执行,生成 MEX文件,使代码加速不同倍速。
4、实现:转成C/C++ ,代码用于嵌入式处理器。
本文主要介绍如何用MATLAB Coder将MATLAB代码转化为C/C++代码,并进行加速。
从MATLAB到C/C++步骤
1、 安装matlab2011a或者更新版本,下面例子以2013版本为基础介绍;
简单生成一个foo.m文件;
functionc = foo(a, b)%#codegen
%Thisfunction muliplies a and b
c =a * b
其中,%#codegen可以防止出现警告错误。
在命令窗口,输入mex -setup,选中一个存在的编译器,界面如下;
5、在命令窗口输入coder(图形界面),回车,弹出MATLABCoder Project对话框;
6、在New选项卡Name中输入一个工程名foo.prj;点击Ok,弹出MATLAB Coder MEX Function对话框;
7、单击变量a,选择Define by Example…,弹出MATLAB Coder Define by Example对话框,在MATLAB Expression中输入5,点击OK;同样变量b也进行相应操作,输入6;
8、 选中Build选项卡,Output type选项中我们可以选择输出类型,他可以生成MEX文件,动态链接库,静态链接库,可执行文件,为了看生成的C/C++ 代码,选择c/c++ Static Library;选中Generate code only;
9、 点击More settings,选择ALL Setting,找到Advanced,Language选择C++;