qileilove

blog已经转移至github,大家请访问 http://qaseven.github.io/

MATLAB中关于MySQL数据库的操作

首先要安装mysql驱动程序包,详细步骤如下:
  Step 1:将mysql-connector-java-5.1.7-bin.jar文件拷贝到......\MATLAB\R2009a\java\jar\toolbox
  Step 2:到......\MATLAB\R2009a\toolbox\local目录下,找到classpath.txt文件,打开,并添加用来加载mysql的jdbc驱动语句:
  $matlabroot/java/jar/toolbox/mysql-connector-java-5.1.7-bin.jar
  Step 3:重新打开MATLAB即可
  驱动程序安装成功后,接来下要是matlab连接mysql数据库的代码:
  conn=database('databasename','username','password','driver','databaseurl')
  连接成功后,返回连接对象。
  参数如下:
  *databasename: 数据库名称.
  *driver: JDBC driver.
  *username and password: 用户名和密码.
  *databaseurl: 类似于jdbc:subprotocol:subname. subprotocol是数据库类型,
  subname类似于//hostname:port/databasename.
  如果matlab和数据库建立了连接,将返回类似于如下信息:
Instance: 'SampleDB'
UserName: ''
Driver: []
URL: []
Constructor: [1x1com.mathworks.toolbox.database.databaseConnect]
Message: []
Handle: [1x1 sun.jdbc.odbc.JdbcOdbcConnection]
TimeOut: 0
AutoCommit: 'off'
Type: 'Database Object'
  连接mysql的代码如下:
  conn = database('tissueppi','root','root','com.mysql.jdbc.Driver','jdbc:mysql://localhost:3306/tissueppi');
  连接成功后,就可以用exec函数执行sql语句
  exec函数执行sql语句并返回一个开指针
  语法如下:
  curs =exec(conn,'sqlquery')
  例如:curs = exec(conn, 'select * fromcustomers')
  执行完查询后,还要将查询结果从开放cursor对象导入到对象curs中,该功能是用
  cursor.fetch函数实现的。

语法如下:
  curs =fetch(curs)
  使用curs.Data来显示数据,curs.Data返回一个CELL结构,可以先把CELL结构转换成
  MATRIX结构再取值:
  cur=cell2mat(cur)
  a=cur(1,1);
  则查询结果就加到了向量a中
  注意:
  在exec函数执行查询过程中,有的sql语句要输入变量,这时可使用strcat函数完成该
  功能。
t =strcat(s1, s2, s3, ...)
for(t=1:10)
sql1 = strcat('select count(did) from rss_genepairs_u wheregocc>=',num2str(t),' || gomf>= ',num2str(t),' || gobp >=',num2str(t));
end
  完整代码如下:
conn =database('tissueppi','root','root','com.mysql.jdbc.Driver','jdbc:mysql://localhost:3306/tissueppi');
for t=0.5:0.01:0.91
for x=0.5:0.1:11
sql = strcat('select count(did) from rss_genepairs_x2 where score<=',num2str(x),' and did in(select did fromrss_genepairs_u where gocc >=',num2str(t),' || gomf>= ',num2str(t),' || gobp >=',num2str(t),')');
aTemp = exec(conn,sql);
aTemp = fetch(aTemp);
a = aTemp.Data;
a = cell2mat(a);
a= a(1,1);
end
end

posted @ 2014-05-08 16:49 顺其自然EVO 阅读(2289) | 评论 (0)编辑 收藏

用Asp.net还原与恢复sqlserver数据库

上次做了个项目,涉及到数据库的还原和恢复,到网上找了一下,是利用SQLDMO实现的,只要添加SQLDMO引用就好了,然后利用下边的类的方法就可以实现了。
  我把原作者的类扩充了一下,可以自动识别web.config里 的数据库连接字符串,可以通过变量设置还原恢复的信息。
  需要注意的时还原,还原的时候问题最大了,有别的用户使用数据库的时候无法还原,解决办法就是在MASTER数据库中添加一个存储过程:
createprockillspid(@dbnamevarchar(20))
as
begin
declare@sqlnvarchar(500)
declare@spidint
set@sql='declaregetspidcursorfor
selectspidfromsysprocesseswheredbid=db_id('''+@dbname+''')'
exec(@sql)
opengetspid
fetchnextfromgetspidinto@spid
while@@fetch_status<>-1
begin
exec('kill'+@spid)
fetchnextfromgetspidinto@spid
end
closegetspid
deallocategetspid
end
GO
  在还原之前先执行这个存储过程,需要传递dbname,就是你的数据库的名字。下边是类的原代码:(web.config里的数据库连接字符串是constr)
using System;
using System.Configuration;
using System.Data.SqlClient;
using System.Data;
namespace web.base_class
{
/// <summary>
/// DbOper类,主要应用SQLDMO实现对Microsoft SQL Server数据库的备份和恢复
/// </summary>
public class DbOper
{
private string server;
private string uid;
private string pwd;
private string database;
private string conn;
/// <summary>
/// DbOper类的构造函数
/// </summary>
public DbOper()
{
conn=System.Configuration.ConfigurationSettings.AppSettings["constr"].ToString();
server=cut(conn,"server=",";");
uid=cut(conn,"uid=",";");
pwd=cut(conn,"pwd=",";");
database=cut(conn,"database=",";");
}
public string cut(string str,string bg,string ed)
{
string sub;
sub=str.Substring(str.IndexOf(bg)+bg.Length);
sub=sub.Substring(0,sub.IndexOf(";"));
return sub;
}
/// <summary>
/// 数据库备份
/// </summary>
public  bool DbBackup(string url)
{
SQLDMO.Backup oBackup = new SQLDMO.BackupClass();
SQLDMO.SQLServer oSQLServer = new SQLDMO.SQLServerClass();
try
{
oSQLServer.LoginSecure = false;
oSQLServer.Connect(server,uid, pwd);
oBackup.Action = SQLDMO.SQLDMO_BACKUP_TYPE.SQLDMOBackup_Database;
oBackup.Database = database;
oBackup.Files = url;//"d:/Northwind.bak";
oBackup.BackupSetName = database;
oBackup.BackupSetDescription = "数据库备份";
oBackup.Initialize = true;
oBackup.SQLBackup(oSQLServer);
return true;
}
catch
{
return false;
throw;
}
finally
{
oSQLServer.DisConnect();
}
}
/// <summary>
/// 数据库恢复
/// </summary>
public string DbRestore(string url)
{
if(exepro()!=true)//执行存储过程
{
return "操作失败";
}
else
{
SQLDMO.Restore oRestore = new SQLDMO.RestoreClass();
SQLDMO.SQLServer oSQLServer = new SQLDMO.SQLServerClass();
try
{
oSQLServer.LoginSecure = false;
oSQLServer.Connect(server, uid, pwd);
oRestore.Action = SQLDMO.SQLDMO_RESTORE_TYPE.SQLDMORestore_Database;
oRestore.Database = database;
oRestore.Files = url;//@"d:/Northwind.bak";
oRestore.FileNumber = 1;
oRestore.ReplaceDatabase = true;
oRestore.SQLRestore(oSQLServer);
return "ok";
}
catch(Exception e)
{
return "恢复数据库失败";
throw;
}
finally
{
oSQLServer.DisConnect();
}
}
}
private bool exepro()
{
SqlConnection conn1 = new SqlConnection("server="+server+";uid="+uid+";pwd="+pwd+";database=master");
SqlCommand cmd = new SqlCommand("killspid",conn1);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("@dbname","port");
try
{
conn1.Open();
cmd.ExecuteNonQuery();
return true;
}
catch(Exception ex)
{
return false;
}
finally
{
conn1.Close();
}
}
}
}

posted @ 2014-05-08 16:47 顺其自然EVO 阅读(135) | 评论 (0)编辑 收藏

oracle数据库备份

1. 文件查看
  数据文件、控制文件、日志文件查看如下:
  select file#, status, enabled, name from V$datafile;--查看数据文件
  select * from v$controlfile;--控制文件
  select * from v$logfile;--日志文件
  2. 三种备份方法
  1)导入/导出(import/export)
  1.支持类型: table, user, tablespace, full database
  2. 导入导出例子:
exp system/manager@TEST file=d:\export.dmp full=y--将数据库TEST完全导出(全库备份),用户名system 密码manager 导出到D:\daochu.dmp中
exp system/manager@TEST file=d:\export.dmp owner=(system,sys)--将system和sys的表导出
exp aichannel/aichannel@TEST file= d:export.dmp tables= (tab1,tab2)--将tab1表和tab2表导出
imp system/manager@TEST file=d:\export.dmp tables=(tab1,tab2);--将export.dmp中tab1表和tab2表导入
imp system/manager@TEST file=d:\export.dmp;
  3. 注意:若用户权限不够时需要修改权限
  --先以system/manager登录
  --授予权限
  grant exp_full_database, imp_full_database to username;
  2)冷备份(非归档模式)
  1. 步骤:shutdown数据库---> copy文件---> start数据库
  2.  例子:
connect tigger/sccot as sysdba;
shutdown immediate;
cp d:/test*.dbf d:export   --cp 文件  目标文件夹    数据文件
cp d:/test*.ctl d:export   --控制文件
cp d:/test*.log d:export   --日志文件
startup;
  3)热备份(归档模式)
  1. 说明:前提条件是数据库运行在归档模式(oracle数据库安装默认运行在非归档模式)
  2. 将数据库转换为归档模式如下:(注意数据库必须已装载到此实例并且不在任何实例中打开)
  --需先关闭数据库并加载数据库
shutdown immediate;
startup mount;--(startup nomount 启动实例;startup mount 启动实例加载数据库; startup 启动实例加载数据库打开数据库)
alter database archivelog;--数据库必须已装载到此实例并且不在任何实例中打开
  3. 归档相关操作
archive log list;--查看是否出于归档模式;
alter system set log_archive_start =true scope =spfile; --启用主动归档
select name from v$archived_log; --查询归档日志
alter system set log_achive_start=false scope=spfile;--将数据库切换为归档模式
archive log stop;
archive log start;
4. 热备份具体步骤如下:
shutdown immediate;
startup mount;
alter database archivelog;
alter database open;
alter tablespace users begin backup; --设置备份模式;
host copy d:\oracle\*.dbf d:\export;--拷贝
alter tablespace users end backup ;--结束备份状态
alter system switch logfile--切换日志,使用当前日志归档
  5. 不足之处:不能出错
  6. 优点:备份时数据库仍然可以使用,备份时间短
  3.RMAN备份和恢复工具(rocovery manager)
  1)说明:
  1.RMAN是 ORACLE提供的一个备份与恢复的工具,可以用来执行完全或不完全的数据库恢复。
  2.RMAN不能用于备份初始化参数文件和口令文件。
  3. 与传统工具相比,RMAN具有独特的优势:跳过未使用的数据块。当备份一个RMAN备份集时,RMAN不会备份从未被写入的数据块,而传统的方式无法获知那些是未被使用的数据块。
  4. RMAN可以进行增量备份(增量备份是针对于上一次备份(无论是哪种备份):备份上一次备份后,所有发生变化的文件)
  2)例子:
  --准备工作:
  connect tiger/sccot;
  startup mount
  alter database archivelog
  alter database open
  --查看备份相关信息
  list backupset;
  --备份全库
  backup database;
  --备份表空间
  backup tablespace tp1;
  --备份全库删除旧的归档日志
  backup databse plus archivelog delete input;--备份全库及控制文件、服务器参数文件与所有归档的重做日志,并删除旧的归档日志
  --备份表空间删除旧的归档日志
  backup tablespace system plus archivelog delete input;
  --备份归档日志
  backup archivelog all delete input;
  --查看备份信息
  list of backup sets;
  --0增量备份(等于全备份)
  backup incremental level=0(level 0) database;
  --1级增量备份
  backup incremental level 1 database;
  注意:0级增量备份和完全备份唯一的区别,0级增量备份能作为增量备份的基础,而全备份不能作为增量备份的基础

posted @ 2014-05-08 16:47 顺其自然EVO 阅读(209) | 评论 (0)编辑 收藏

浅谈Java中的对象和对象引用

 在Java中,有一组名词经常一起出现,它们就是“对象和对象引用”,很多朋友在初学Java的时候可能经常会混淆这2个概念,觉得它们是一回事,事实上则不然。今天我们就来一起了解一下对象和对象引用之间的区别和联系。
  1.何谓对象?
  在Java中有一句比较流行的话,叫做“万物皆对象”,这是Java语言设计之初的理念之一。要理解什么是对象,需要跟类一起结合起来理解。下面这段话引自《Java编程思想》中的一段原话:
  “按照通俗的说法,每个对象都是某个类(class)的一个实例(instance),这里,‘类’就是‘类型’的同义词。”
  从这一句话就可以理解到对象的本质,简而言之,它就是类的实例,比如所有的人统称为“人类”,这里的“人类”就是一个类(物种的一种类型),而具体到每个人,比如张三这个人,它就是对象,就是“人类”的实例。
  2.何谓对象引用?
  我们先看一段话:
  “每种编程语言都有自己的数据处理方式。有些时候,程序员必须注意将要处理的数据是什么类型。你是直接操纵元素,还是用某种基于特殊语法的间接表示(例如C/C++里的指针)来操作对象。所有这些在 Java 里都得到了简化,一切都被视为对象。因此,我们可采用一种统一的语法。尽管将一切都“看作”对象,但操纵的标识符实际是指向一个对象的“引用”(reference)。”
  这段话来自于《Java编程思想》,很显然,从这段话可以看出对象和对象引用不是一回事,是两个完全不同的概念。举个例子,我们通常会用下面这一行代码来创建一个对象:
  Person person = new Person("张三");
  有人会说,这里的person是一个对象,是Person类的一个实例。
  也有人会说,这里的person并不是真正的对象,而是指向所创建的对象的引用。
  到底哪种说法是对的?我们先不急着纠结哪种说法是对的,再看两行代码:
  Person person;
  person = new Person("张三");
  这两行代码实现的功能和上面的一行代码是完全一样的。大家都知道,在Java中new是用来在堆上创建对象用的,如果person是一个对象的话,那么第二行为何还要通过new来创建对象呢?由此可见,person并不是所创建的对象,是什么?上面的一段话说的很清楚,“操纵的标识符实际是指向一个对象的引用”,也就是说person是一个引用,是指向一个可以指向Person类的对象的引用。真正创建对象的语句是右边的new Person("张三");
  再看一个例子:
  Person person;
  person = new Person("张三");
  person = new Person("李四");
  这里让person先指向了“张三”这个对象,然后又指向了“李四”这个对象。也就是说,Person person,这句话只是声明了一个Person类的引用,它可以指向任何Person类的实例。这个道理就和下面这段代码一样:
  int a;
  a=2;
  a=3;
  这里先声明了一个int类型的变量a,先对a赋值为2,后面又赋值为3.也就是说int类型的变量a,可以让它的值为2,也可以为3,只要是合法的int类型的数值即可。
  也就是说,一个引用可以指向多个对象,而一个对象可不可以被多个引用所指呢?答案当然是可以的。
  比如:
  Person person1 = new Person("张三");
  Person person2 = person1;
  person1和person2都指向了“张三”这个对象。
  关于对象和对象引用的区别和联系暂时就讲这么多了,感兴趣的朋友可以查阅相关文档和资料。

posted @ 2014-05-08 16:46 顺其自然EVO 阅读(128) | 评论 (0)编辑 收藏

浅谈Java中的对象和对象引用

 在Java中,有一组名词经常一起出现,它们就是“对象和对象引用”,很多朋友在初学Java的时候可能经常会混淆这2个概念,觉得它们是一回事,事实上则不然。今天我们就来一起了解一下对象和对象引用之间的区别和联系。
  1.何谓对象?
  在Java中有一句比较流行的话,叫做“万物皆对象”,这是Java语言设计之初的理念之一。要理解什么是对象,需要跟类一起结合起来理解。下面这段话引自《Java编程思想》中的一段原话:
  “按照通俗的说法,每个对象都是某个类(class)的一个实例(instance),这里,‘类’就是‘类型’的同义词。”
  从这一句话就可以理解到对象的本质,简而言之,它就是类的实例,比如所有的人统称为“人类”,这里的“人类”就是一个类(物种的一种类型),而具体到每个人,比如张三这个人,它就是对象,就是“人类”的实例。
  2.何谓对象引用?
  我们先看一段话:
  “每种编程语言都有自己的数据处理方式。有些时候,程序员必须注意将要处理的数据是什么类型。你是直接操纵元素,还是用某种基于特殊语法的间接表示(例如C/C++里的指针)来操作对象。所有这些在 Java 里都得到了简化,一切都被视为对象。因此,我们可采用一种统一的语法。尽管将一切都“看作”对象,但操纵的标识符实际是指向一个对象的“引用”(reference)。”
  这段话来自于《Java编程思想》,很显然,从这段话可以看出对象和对象引用不是一回事,是两个完全不同的概念。举个例子,我们通常会用下面这一行代码来创建一个对象:
  Person person = new Person("张三");
  有人会说,这里的person是一个对象,是Person类的一个实例。
  也有人会说,这里的person并不是真正的对象,而是指向所创建的对象的引用。
  到底哪种说法是对的?我们先不急着纠结哪种说法是对的,再看两行代码:
  Person person;
  person = new Person("张三");
  这两行代码实现的功能和上面的一行代码是完全一样的。大家都知道,在Java中new是用来在堆上创建对象用的,如果person是一个对象的话,那么第二行为何还要通过new来创建对象呢?由此可见,person并不是所创建的对象,是什么?上面的一段话说的很清楚,“操纵的标识符实际是指向一个对象的引用”,也就是说person是一个引用,是指向一个可以指向Person类的对象的引用。真正创建对象的语句是右边的new Person("张三");
  再看一个例子:
  Person person;
  person = new Person("张三");
  person = new Person("李四");
  这里让person先指向了“张三”这个对象,然后又指向了“李四”这个对象。也就是说,Person person,这句话只是声明了一个Person类的引用,它可以指向任何Person类的实例。这个道理就和下面这段代码一样:
  int a;
  a=2;
  a=3;
  这里先声明了一个int类型的变量a,先对a赋值为2,后面又赋值为3.也就是说int类型的变量a,可以让它的值为2,也可以为3,只要是合法的int类型的数值即可。
  也就是说,一个引用可以指向多个对象,而一个对象可不可以被多个引用所指呢?答案当然是可以的。
  比如:
  Person person1 = new Person("张三");
  Person person2 = person1;
  person1和person2都指向了“张三”这个对象。
  关于对象和对象引用的区别和联系暂时就讲这么多了,感兴趣的朋友可以查阅相关文档和资料。

posted @ 2014-05-08 16:46 顺其自然EVO 阅读(124) | 评论 (0)编辑 收藏

企业级软件开发需要什么样的框架?

 1)领域建模
  分析领域特定的问题。比如赶集网这一分类信息网站,她的定位是解决都市人寻求房屋出租、二手房、二手车、二手物品交易、求职招聘等生活信息的需求的。在领域建模阶段要解决的就是这个软件的定位问题,做什么不做什么。这一阶段由高层领导,市场销售及系统分析师等完成。
  2) 平台技术选择
  技术选型,比如用什么平台/架构(.net,j2ee,php,python等等)开发,采用什么服务器托管等。这一阶段由系统高层领导,系统分析师及系统架构师等完成。
  3) 解决方案
  根据选定的平台技术等给出一个可行的解决方案,说明系统会使用什么样的部署结构等。这一阶段由系统分析师及系统架构师等完成。
  4) 需求分析
  市场技术的可行性已经确定,接下来就是把做什么具体化了。把每一个功能模块及非功能性需求罗列出来。这一阶段由市场销售,系统分析师,产品经理,用户体验师,测试工程师等完成。
  5) 技术实现
  需求已经明确,接下来就是设计与实现了。除了实现系统的特定功能外,我们还要实现系统用户的验证与授权,系统日志与异常处理,发邮件与用户交互等。这一部分就是企业级软件开发中可以复用的切入点,也是和我们系统架构师,软件工程师的工作密切相关的部分。这一阶段由系统架构师,开发经理,软件工程师等完成。
  6)集成测试
  在预设的软硬件环境下,测试系统是否很好地满足了用户的需求。
  这一阶段由软件工程师,测试工程师等完成。
  7) 验收测试
  将系统交由用户或用户代表使用。可能会根据反馈进行一定的修改等。这一阶段由产品经理,用户或用户代表,软件工程师,测试工程师等完成。
  8)交付
  实际交给用户运营与使用。这一阶段由市场销售,技术代表,用户等完成。
  9) 维护
  根据用户实际使用中给出的反馈或提出的新需求等修改系统。
  这一阶段几乎是上面1-8的迭代过程。
  什么是框架?
  一个框架是在一个给定的问题领域内,一个应用程序的一部分设计与实现。
  框架中要包含什么?
  框架中应该提供通用的功能与实现,比如用户验证与授权,日志与异常处理,缓存策略与实现,发送邮件,定时数据处理(Jobs),数据访问策略与实现,多语言支持,通用UI组件等。
  为什么要开发框架?
  较大的软件开发公司都有自己的框架,因为框架中积累了很多通用的功能,可以直接复用。采用框架可以规范开发人员的设计与代码,有利于在一个项目内多人协同工作,一致性好,可维护性好。这样就可以提高质量,缩短开发周期,进而也就提高了生产率,降低了开发费用。
  我如何做框架?
  我的经验告诉我,开发框架一定要遵循简单封装,决不能过度设计。

posted @ 2014-05-08 16:45 顺其自然EVO 阅读(219) | 评论 (0)编辑 收藏

再解Java中的String

今天朋友问我String的内容是真的不可变吗?我肯定告诉他是的?因为在我的主观意识里String就是一个不可变的对象。于是他给我发了这段程序:
public class StringTest {
public static void main(String[] args) throws Exception {
String a = "chenssy";
System.out.println("a = " + a);
Field a_ = String.class.getDeclaredField("value");
a.setAccessible(true);
char[] value=(char[])a.get(a);
value[4]='_';   //修改a所指向的值
System.out.println("a = " + a);
}
}
  看到这个简单的程序,我笑了,你这不是从底层来修改String的值么?从这里来理解String的值肯定是可以改变的啦(我们应该始终相信String的不可变性)!接着他再给我一段程序:
public class StringTest {
public static void main(String[] args) throws Exception {
String a = "chenssy";
String b = "chenssy";
String c = new String("chenssy");
System.out.println("--------------修改前值-------------------");
System.out.println("a = " + a);
System.out.println("b = " + b);
System.out.println("c = " + c);
//修改String的值
Field a_ = String.class.getDeclaredField("value");
a_.setAccessible(true);
char[] value=(char[])a_.get(a);
value[4]='_';   //修改a所指向的值
System.out.println("--------------修改后值-------------------");
System.out.println("a = " + a);
System.out.println("b = " + b);
System.out.println("chenssy");
System.out.println("c = " + c);
}
}

字体:        | 上一篇 下一篇 | 打印  | 我要投稿 

  乍看这程序是异常的简单,无非就是赋值、改值、输出嘛!可能你现在就会毫不犹豫的说太简单了结果就是……。但是!!你的毫不犹豫会害死你,而且你的结果很可能错误。那么运行结果是什么呢?
--------------修改前值-------------------
a = chenssy
b = chenssy
c = chenssy
--------------修改后值-------------------
a = chen_sy
b = chen_sy
chen_sy
c = chen_ssy
  修改前值很容易理解,但是修改后值呢?是不是有点儿不理解呢?你可能会问:为什么System.out.println("chenssy");的结果会是chen_ssy,System.out.println("c = " + c);也是chen_ssy呢?
  要明白这个其实也比较简单,掌握一个知识点:字符串常量池。
  我们知道字符串的分配和其他对象分配一样,是需要消耗高昂的时间和空间的,而且字符串我们使用的非常多。JVM为了提高性能和减少内存的开销,在实例化字符串的时候进行了一些优化:使用字符串常量池。每当我们创建字符串常量时,JVM会首先检查字符串常量池,如果该字符串已经存在常量池中,那么就直接返回常量池中的实例引用。如果字符串不存在常量池中,就会实例化该字符串并且将其放到常量池中。由于String字符串的不可变性我们可以十分肯定常量池中一定不存在两个相同的字符串(这点对理解上面至关重要)。
  我们再来理解上面的程序。
  String a = "chenssy";
  String b = "chenssy";
  a、b和字面上的chenssy都是指向JVM字符串常量池中的”chenssy”对象,他们指向同一个对象。
  String c = new String("chenssy");
  new关键字一定会产生一个对象chenssy(注意这个chenssy和上面的chenssy不同),同时这个对象是存储在堆中。所以上面应该产生了两个对象:保存在栈中的c和保存堆中chenssy。但是在Java中根本就不存在两个完全一模一样的字符串对象。故堆中的chenssy应该是引用字符串常量池中chenssy。所以c、chenssy、池chenssy的关系应该是:c--->chenssy--->池chenssy。整个关系如下:
  通过上面的图我们可以非常清晰的认识他们之间的关系。所以我们修改内存中的值,他变化的是所有。
  总结:虽然a、b、c、chenssy是不同的对象,但是从String的内部结构我们是可以理解上面的。String c = new String("chenssy");虽然c的内容是创建在堆中,但是他的内部value还是指向JVM常量池的chenssy的value,它构造chenssy时所用的参数依然是chenssy字符串常量。

posted @ 2014-05-08 16:45 顺其自然EVO 阅读(183) | 评论 (0)编辑 收藏

Appium IOS 自动化测试初探

 手机平台的自动化测试工具很多,之前研究过了安卓和苹果的原生自动化测试框架,经一些同事介绍,貌似Appium是个不错的工具。
  想记录一下研究的结果,也算是篇干货的文章
  在网上也看了一些视频,个人认为这个自动化测试的特点就是
  1. 多编程语言支持
  相对于传统的IOS UIautomation只能支持js语言,Appium起到了一个翻译的作用,它其实是一个CS架构,服务器和IOS模拟器或真机直接通讯,客户端和服务器之间用HTTP协议进行交互,所以客户端用什么语言其实不重要。下面会有一个python编程的实际例子。
  2. 远程测试支持
  正如上面说的,客户端和服务器之间用HTTP协议通讯,那么也就是说,客户端可以和服务器在同一台机器或者不同的机器。
  3. 较好的录制功能
  Appium提供了一个很好的录制工具,可以让程序员一步一步的把步骤进行精确的录制
  4. 单步调试
  程序员可以利用高级脚本语言,比如Python对被测程序进行单步调试,比如一条命令对应一个UI动作
  如何使用appium,基于2014年5月份发布的appium 1.0来说,大约是这样的,
  你必须要有xcode进行自动化测试的基础,如果没有的话,请先补习
  A. 如果是模拟器测试
  1. 选择应用安装包的位置
  2. 再选择期望的模拟器平台,IOS版本,再点Launch就可以了
  3. Launch之后会发现什么都没有,其实Appium已经运行了,请注意运行的窗口中有没有错误
  4. 下面就是录测试用例,点击一个蓝色的底,白色的i的按钮
  5. 过一段时间后就会出现inspector的窗口
  6. 下面是一个例子,比如我要点一个按钮,
  6.1 首先现在左边的树形窗口里面找到一个按钮的位置,有点类似Firebug找网页控件
  6.2 然后在下面的动作框选择你想要的动作,点击就是Tap,然后你会发现这个按钮真的被点击了(这是一个单步调试很直观的例子)


 7. 如何把录制变成脚本
  7.1 首先要点击inspector窗口的Record按钮
  7.2 选择你需要的编程语言
  7.3 再继续重复你需要做的UI操作
  7.4 最后就是把代码拷贝出去
  8. 如何重录测试
  8.1 关掉inspector,
  8.2 代码需要稍微的修改,Python的代码录出来居然有语法错误,这里给个例子,对照看就好了(当然必要的python库必须安装)
from selenium.webdriver.firefox.webdriver import WebDriver
from selenium.webdriver.common.action_chains import ActionChains
import time
import os
import selenium
success = True
desired_caps = {}
desired_caps['browserName'] = 'iOS'
desired_caps['platform'] = 'Mac'
desired_caps['version'] = '6.1'
desired_caps['device'] = 'iPad'
desired_caps['app'] = os.path.abspath('/Users/marshall/Library/Developer/Xcode/DerivedData/TestAutomation-empzzpwyyxctxidnwdsrtlssueqi/Build/Products/Debug-iphonesimulator/TestAutomation.app')
wd = selenium.webdriver.Remote('http://0.0.0.0:4723/wd/hub', desired_caps)
wd.implicitly_wait(60)
def is_alert_present(wd):
try:
wd.switch_to_alert().text
return True
except:
return False
try:
wd.find_element_by_name("First").click()
wd.find_element_by_name("Second").click()
finally:
wd.quit()
if not success:
raise Exception("Test failed.")
  8.3 运行代码,查看测试结果
  B. 如果是真机测试
  真机测试其实遇到了些问题,我大概说一下我的步骤
  1. 配置应用的BundleID和设备的UDID
  BundleID不知道怎么看的请用itools
  UDID不知道怎么找的请用iTunes或itools
  应用必须是你自己的开发者账号签名过的
  2. Launch Appium
  3. 点击inspector的按钮,接下来应用会显示在iPad上,但是过一会就会闪退(我试了好几个应用都有这个问题),我已经给Appium报告了一个bug,看看会不会有回复吧。
  如果有人在真机上成功使用inspector的,也请留言分享一下

posted @ 2014-05-08 16:42 顺其自然EVO 阅读(16017) | 评论 (1)编辑 收藏

巧用工具洞察用户行为

 冬夜的被窝里、飞驰狂奔的公车上、无聊乏味的课堂中掏出手机,打开手机QQ的阅读中心,翻开一本书看看不失为好的消遣方式,手机QQ除了提供好的阅读内容供用户消遣,用户研究人员和设计师也非常关心如何给用户带来好的阅读翻页操作体验,减少用户的翻页误操作情况,因此针对手机QQ4.5版的阅读中心用户翻页热区操作展开了一场测试
  研究目的
  目前手机QQ的新手引导图(测试时在用的是引导图一)是否会对用户操作有引导效果;
  跟踪用户在阅读过程中翻页(翻上一页、翻下一页和出菜单)操作的热区。
  实验设计
  按照用户是否有手机阅读经验分为新手用户(20人)和老手用户(20人),不同类型的用户均随机分为看引导图的用户和不看引导图的用户,测试的引导图除了当时在用的引导图一外,还包括备用的两张引导图,分别为下面的引导图二和引导图三。
  工具准备
  目前比较高端的眼动仪也只是记录用户眼睛的浏览轨迹,但是要记录用户在阅读过程中的操作轨迹,目前还没有,要开发在用户的阅读页面埋点在操作上也不现实,于是想到了市面上的一些好的画图软件,用户的操作过程可以通过画笔在隐藏的图层记录下来,但用户在操作过程中全然不知,最后在网上找到了两款比较好的画图软件,苹果端是 ArtStudio Lite,安卓端是SketchBook Mobile 。
  测试任务安排
  万事俱备,只欠用户,邀约来的用户中必须包括有手机阅读经验和无手机阅读经验的用户,随机截取书本的某三页的图片,如下:
  用户来了之后,按手机类型安装好画图软件,同时将书本页面导入到已经安装到用户手机里的画图软件中,在测试过程中不同的翻页操作使用不同的书本页面(为了后期统计方便),以iPhone端的ArtStudio Lite为例,操作如下:
  正式测试
  测试具体过程不详述,有几点心得与大家分享:
  尽量用用户自己的手机并强调用户让自己最习惯和自然的常用持机方式操作;
  每种操作对应一个测试图片,有利于后期数据整理;
  看引导图时控制时间,以防用户强行记忆,同时对引导图不做任何解释;
  每位用户的每种操作至少要有三次且每种操作的次序随机;
  适当的时候用一定的技巧掩盖来回切换图片(“不怎么灵敏,多翻几次”,“我看看是怎么回事”);
  PS:尽量不要让用户发现我们在记录他的操作轨迹,但是如果万一被用户发现,那就告诉用户测试是用来干什么,让用户用最自然的状态去操作 。
 测试结果
  下图是软件记录的用户分别翻下一页、出菜单和翻上一页的操作轨迹。
  将这些图片导入到photoshop,找到用户每次操作的起点坐标,录入到excel中。
  研究结论
  看过引导图二的用户在“上一页、出菜单和下一页”的操作上更集中。
  有小伙伴肯定会问,引导图对用户的翻页操作有效果就可以了,可是从实际观察用户的使用行为来看,用户容易忽略并错过引导图,因此设计中需要考虑到没有接收到引导图信息用户的操作习惯。
  写在后面的话
  随风潜入夜,润物细无声,作为一名用户研究人员,功力练就的最高境界就是希望能像诗中表达的意境,潜入并洞悉用户的内心,虽实际操作有一定难度,但工欲善其事,必先利其器,如果能手握利器,则可以在一定程度上做到,所谓的利器不一定是高大上的东西,小东西一样能做大事,身在设计部门,对一些常用软件也应保持一定的关注度,关键时候能拿来为我所用。
  结合本项目,在测试过程中由于还是有一些小的干预在里面,比如在操作过程中要切换图片,有了本次项目的经验,后续将加入开发的力量,做成专门的测试软件,记录用户的操作路径,实现工具的升级并用于以后类似的操作类基础性研究测试。

posted @ 2014-05-08 16:41 顺其自然EVO 阅读(153) | 评论 (0)编辑 收藏

关于统一等价类划分的术语和过程

关于统一等价类划分的术语和过程
    等价类划分是很重要的软件测试设计技术之一。重要到几乎每一个测试员都要用到这项技术,他们中的一些人甚至还没有意识到被这他们称为 “常识”的实际上是一项正式的技术。
但不知何故,作为一个测试团队,我们就等价类划分的过程这一点上似乎无法达成一致意见。甚至连它的术语都意见不一。划分和类是同一回事吗?等级划分的有效和无效意味着什么?当我们了解什么是类之后,又该如何把它运用到测试用例中呢?我们需要输出划分吗?在这篇文章里,我会提出一个关于统一等价类划分的术语的建议,并努力找出一个单一的方法来得到测试用例。我汇总了许多测试专家的知识见解并且找出其中的共同点,努力做到不遭到一丝质疑地去除这些不统一。

来源
    参考咨询了多方来源,我汇集了关于等价类划分技术的信息,大多数作者都偏向Glenford Myers [1]和Boris Beizer [2]的观点。并不是所有的关于等价类划分技术的信息来源都描述了整个过程,也不是所有的都描述了同一个过程。最实用的关于怎样运用这项技术的信息是由Erik van Veenendaal [6]和Edward Kit [3]所描述的。

术语
零星碎片
    在等价类划分里,我们取输入一个电脑程序的内容,把它切成零星碎片,这本应由该程序自己以同样的方法处理的。
不同的来源里用不同的术语来描述这些碎片:
· Myers [1]认为: “等价类划分是通过考虑了每一种输入条件...确认的,并把它分成两至更多份以上。
· Black [9]:“等价类,也叫做等价分区。”
· Van Veenendaal [6]:“......等价类或者划分区......”
· De Grood [10]:“......有效和无效的等价类别......”
让我们看一看关于“划分”的专业术语的准确的起源“set theory”。我是找不到我的旧教科书来看了,但是我可以参考维基百科,它是这样写的:“集合S的一个划分P是两两不相交的非空子集,使得∪P = S。”,“集合S的任意一个分区P给S引入了一个等价关系,其中每个A∈P是就一个等价类。同样地,给S引入一个等价关系,不同的等价类的集合就是S的分区。”
我提议回归最初,坚持在set theory中使用的准确的术语。
从上面的准确的术语,我们学到了以下(下面是用简单明了英语改写了):
·划分是把东西切碎。
·某物被切成零星碎片的方法就被称为划分。
·这些零星碎片被称作类

    所以当我确定了整数1到10有两种划分时就意味着我可以用两种方法把它们切碎,也就是,奇数和偶数(这是第一种划分)或者质数和非质数(这是第二种)。把小于5的数和大于等于5的数分开会生成由两个类构成的第三种划分。

有效和无效
    一旦一个程序的输入范围被划分成等价类,我们就不得不在我们可以把它们与测试用例结合起来之前决出这些类里面哪些是有效的哪些是无效的。但是我们怎么定义“有效”?
· Black [9]:“...有效类...描述有效的情况,系统需要正常处理...”
· Van Veenendaal [6]:“等价类划分下的无效数据并不是说这个数据是错误的;而是指这个数据不在具体的划分范围之内。”
· Burnstein [7]:“…有效类…描述系统可以正常处理…的情况。”
· Van Veenendaal [6]:“无效类表示输入错误或异常”
别人告诉过我:一个类,当程序不指定输入来自该类时,它被认为是无效类。但是要是指定行为是一个错误信息,又该怎么办?D.J. de Grood [10] 说:“…并不是一个无效值,因为这次输入的错误处理已被具体…”。
我建议采纳和适应用于分类树方法中的定义。“有效类描述被测试对象有条不紊地处理的输入情况。无效类应该被测试对象引发错误处理反映。”这段引述的大部分都是和原文一样的,我加了一个词“应该”来覆盖错误处理机制(还)不到位的情况,我还用“类”替代了Grochtmann [4]原话中的“测试用例”。

食谱
切片和切块
    现在大家都清楚了什么是划分(划分的过程),什么是类(划分结果)了,但还不明白输入域是如何被划分的。Van Veenendaal [6] 和Kit [3]就所有输入和通常它们是如何被划分做出了详细准确的概括。但是划分是一个测试员的工作吗?划分的基础已经在测试员要求之中了。例:“6岁以下的儿童在至少一位家长的陪伴下可免费进入”。就是按儿童的年龄和陪同者的人数划分免费的部分人群。但是我们必须确保顾客即要求工程师和软件开发员都以同样的方式来理解它。

结合类
    现在我们已经解释清楚了术语,我希望你们同意我做出的选择,我们来说说结合类吧。
等价类划分中所提到的来源中有许多的观点,所以再一次的,我们不得不作选择。
    首先让我们来看看软件构件测试的标准– BS 7925-2 [5]。这个标准给我们提供了自由, “在生成测试用例时,可以采取两种截然不同的方法。用第一种方法,一个测试用例在一对一的基础上生成每一个确定的划分区。用第二种方法,一组最小的测试用例生成并覆盖了所有确定的划分区。”请注意这句话中的“划分区”一词,我是提议用“类”的。
    大多数来源生成了覆盖所有有效类的一组最小的测试用例。接下来看看Myers的方法:“写一个测试用例,这个用例只覆盖不被覆盖的无效等价类之中的一个。”直到所有无效类都被覆盖。不把多个无效输入结合到一个测试用例中的理由Myers清楚地说明了,Kit and Veenendaal也这样解释到:“如果多个无效EC在同一个用例中被测试出来,一些测试可能无法执行,因为第一个测试可能会掩盖其他测试或者终止执行测试用例。”但是一些人([6], [9])提出一个单一的,完全无效的测试用例可能是有用的。尤其是在Web应用程序中,输入数据在被发送到服务器前经常先进入一个表格检查其有效性。让我为您展示以下几种结合类的菜单:
选择1—低脂餐
· 开胃小吃:一组最小的覆盖所有有效类的测试用例
· 主菜:一组最小的覆盖所有无效类的测试用例
· 饭后甜点:抱歉,没有甜点

选择2—常规餐
· 开胃小吃:一组最小的覆盖所有有效类的测试用例
· 主菜:一组测试用例,其中每一个用例每次只覆盖一个单一的无效类,除非所有的无效类都被覆盖(提供)了
· 饭后甜点:抱歉,没有甜点

选择3—丰盛餐
· 开胃小吃:一组最小的覆盖所有有效类的测试用例
· 主菜:一组测试用例,其中每一个用例每次只覆盖一个单一的无效类,除非所有的无效类都被覆盖(提供)了
· 饭后甜点:一个只覆盖最好的无效类的单一测试用例

选择4—(几乎)所有你能吃的
· 开胃小吃:一组最小的覆盖所有有效类的测试用例
· 主菜:一组测试用例,其中每一个用例每次只覆盖一个单一的无效类,除非所有的无效类都被覆盖(提供)了
· 饭后甜点:一组最小的覆盖覆盖所有无效类的完全无效的测试用例
· 额外: 给极度饥饿的人,我们提供了精心挑选的覆盖所有输出类的额外的测试用例组合套餐

    我们该如何选择呢?这个取决于我们对于测试之下的主题所知道什么。
    在低风险的情况下,你不是很饿的话,一组最小的测试用例或许是最好的选择。像上面的网站的例子,如果我们知道该软件是用来在开始一次计算前检查在表单中的字段中所输入的每个值的话,那么明智的做法就是添加额外的完全无效的测试案例。
    在高风险的情况下,我们想要确保每一个无效类被识别为无效并被视作无效来对待。所以我们至少需要一份不错的常规餐或者“所有你能吃的”。
但是额外呢?输出划分是有营养的一部分还是它只是让你发胖的部分呢?
另外,它还取决于实际情况和测试目标,当你在测试一个将输入转化为输出的模块(这经常发生),接着,该输出被用作另一个模块的输入时,知道是否所有的可能输出会因为正确的理由被接受或拒绝可能是相当有价值的。
    事实上,我们在这儿讲的是集成测试。为了执行一个这样的测试,必须生成接受模块的所有的可能输入类。因此,我们需要全面了解调用模块的输出。调用模块的范围必须符合被调用模块的域。正如Beizer所说:“…调用者的范围就是调用者对被调例程域的概念…”我们想证明这个观念是正确的。

posted @ 2014-05-08 16:41 顺其自然EVO 阅读(269) | 评论 (0)编辑 收藏

仅列出标题
共394页: First 上一页 115 116 117 118 119 120 121 122 123 下一页 Last 
<2025年4月>
303112345
6789101112
13141516171819
20212223242526
27282930123
45678910

导航

统计

常用链接

留言簿(55)

随笔分类

随笔档案

文章分类

文章档案

搜索

最新评论

阅读排行榜

评论排行榜