qileilove

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

Java中复制文件的效率测试

 项目中用到了图片的上传,对于上传过程中,图片的复制项目组用了两种方法,一种是以java的IO流,另外一种是用org.apache.commons.io.FileUtils的工具类,今天我测试了一下,单纯考虑文件的复制效率,apache的工具类的效率是普通io流读取的3倍。
  下面是测试源码:
public class ImageTest {
public static void main(String[] args) throws IOException {
IOTest();
}
public static void fileUtilsTest() throws IOException {
// 趋近13毫秒后,就保持这个数值
File srcFile = new File("D:/1.apk");
File destFile = new File("E:/2.apk");
long sum = 0;
for (int i = 0; i < 10; i++) {
long startTime = System.currentTimeMillis();
FileUtils.copyFile(srcFile, destFile);
long endTime = System.currentTimeMillis();
sum += (endTime - startTime);
}
long average = sum / 10;
System.out.println("耗时" + average + "豪秒");
}
public static void IOTest() throws IOException {
// 50毫秒
File srcFile = new File("D:/1.apk");
File destFile = new File("E:/2.apk");
long sum = 0;
for (int i = 0; i < 10; i++) {
long startTime = System.currentTimeMillis();
InputStream is = new FileInputStream(srcFile);
// 把图片写入到上面设置的路径里
OutputStream os = new FileOutputStream(destFile);
byte[] buffer = new byte[400];
int length = 0;
while ((length = is.read(buffer)) > 0) {
os.write(buffer, 0, length);
}
is.close();
os.close();
long endTime = System.currentTimeMillis();
sum += (endTime - startTime);
}
long average = sum / 10;
System.out.println("耗时" + average + "豪秒");
}
}

posted @ 2014-01-24 16:06 顺其自然EVO 阅读(185) | 评论 (0)编辑 收藏

Oracle数据库连接命令

连接命令:
  conn
  例:conn system/manger
  它的意义是切换到system用户,其中sysytem是用户名,manager是密码。
  断开与当前数据库连接:
  disconn
  修改密码:
  passw
  输入passw之后系统就会让你输入新口令和旧口令,按照提示向下走。
  显示当前用户:
  show user
  断开连接并退出:
  exit
  ORACLE常用初始用户名和密码:
  1>系统管理员,一般进行权限分配使用
  SYSTEM MANAGER
  2>演示帐户,可进行基本的增删改操作
  SCOTT TIGER
  3>系统数据库拥有者,此帐户内拥有所有的系统信息
  SYS CHANGER_ON_INSTALL
  运行sql脚本:
  start和@
  例:
  sql>@:\a.sql或sql>start d:\a.sql
  编辑指定sql脚本
  edit
  例子:sql>edit d:\a.sql;
  将屏幕上的内容输入到指定文件中去。
  spool
  例子:sql>spool d:\bb.sql;意义是建立一个bb。sql文件。方便截图是的存放文件。
  第二步,你要获取你要截屏的东西。
  之后,
  spool off;
  到此截屏就结束了。

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

SQLite3数据库中的文件锁和同步机制

SQLite3 提供了一个新的锁和同步机制来提高并发,减少死锁。
  SQLite3的锁和同步有PagerModule(pager.c)负责处理。PagerModue负责SQLite事务的ACID,也提供缓存功能。PagerModue不需要知道BTree,字符编码, 索引的结构,  Pager Module用来管理Page, 一个Page对应一个DiskBlock, 大小一般是1024Byte。
  1. SQLite3 数据库的锁状态
  UNLOCKED
  SHARED
  RESERVED 保留锁, 表示数据库将被写,  一个数据库只能有一个保留锁, 保留锁可以和共享锁共存,与PENDING锁的不同之处在于还能获得新的共享锁,PENDING锁被激活时, 不能再获得共享锁。
  PENDING
  EXCLUSIVE
  2.  回滚日志文件
  如果有更新数据库操作, SQLite就会生成回滚日志文件, 以"-journal"的文件名结尾, 与数据库文件存放在同一目录下。如果多个数据库同时工作, 每个数据库都有自己的回滚日志文件, 并且还有一个master journal日志文件。master journal没有数据, 只包含各个回滚日志文件名。每个数据库的回滚日志文件也会包含masterjournal文件名。
  当访问数据库时发现有"hot journal"时, SQLite就会进行回滚工作, 回滚结束就删除回滚日志文件。
  处理"hot journal"
  (1) 尝试获得SHAREDLOCK, 如果失败, 立即结束, 返回SQLITE_BUSY
  (2) 检查是否有"hotjournal", 如果没有立即返回, 否则继续执行以下步骤
  (3) 尝试获得PENDINGLOCK, 然后EXCLUSIVELOCK, 如果失败, 表示其他进程正在做回滚, 释放所有锁, 关闭数据库, 返回SQLITE_BUSY。否则继续执行
  (4) 读回滚日志文件, 回滚数据库文件
  (5) 删除回滚日志文件
  (6) 删除masterjournal 文件
  (7) 释放PENDINGLOCK和EXCLUSIVELOCK, 但是保留SHAREDLOCK
  3. 写数据库文件步骤
  (1) 获得共享锁
  (2) 获得RESERVEDLOCK, 如果失败, 返回SQLITE_BUSY, 否则继续执行
  (3) 生成回滚日志文件, 写入磁盘, 等待写完成继续执行
  如果是单个数据库文件
  (4) 请求获得PENDINGLOCK
  (5) 请求获得EXCLUSIVELOCK
  (6) flush/fsync, 将更新写入磁盘
  (7) 删除回滚日志文件
  (8) 释放EXCLUSIVELOCK, PENDING LOCK, RESERVED LOCK, 获得SHARED LOCK
  如果是多个数据库文件事务
  (4) 请求获得PENDINGLOCK 和EXCLUSIVELOCK, 确保所有数据库都获得EXCLUSIVELOCK
  (5) 生成masterjournal文件和每个数据库的回滚日志文件
  (6) flush/fsync, 将更新写入磁盘
  (7) 先删除masterjournal 文件, 再删除所有的回滚日志文件
  (8) 释放所有数据库上的EXCLUSIVELOCK, PENDING LOCK
  4. SQL事务
  默认SQLite autocommit=true
  BEGIN TRANSACTION - COMMIT 命令使得SQLite不在autocommit下工作。当SQLite执行BEGIN命令时, 不会获得任何锁, 直到执行到第一个SELECT, 才获得一个SHARED LOCK, 执行到UPDATE/INSERT/DELETE才获得REVERSED LOCK, 当缓存满或者COMMIT时才请求获得EXCLUSIVE LOCK。
  COMMIT并非真正的将更新写到磁盘, COMMIT使得SQLITE回到autocommit=true 模式, autocommit会负责将更新写到磁盘。

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

Linux源码包软件的安装与卸载

 Linux软件安装与卸载(源码包形式):一般情况下linux程序的发布不能像windows那样,直接打包成一个setup.exe文件,然用户安装 时直接按下一步就完成了,因为它对库的依赖比较严重下面就来看下linux下软件源码包安装与卸载:
  Linux软件的源代码分发是指提供了该软件所有程序源代码的发布形式,需要用户自己编译成可执行的二进制代码并进行安装,其优点是配置灵活,可以随 意去掉或保留某些功能/模块,适应多种硬件/操作系统平台及编译环境,缺点是难度较大,一般不适合初学者使用。
  1、*.src.rpm形式的源代码软件包
  安装:rpm -rebuild *.src.rpm
cd /usr/src/dist/RPMS
rpm -ivh *.rpm
  卸载:rpm -e packgename
  说明:rpm --rebuild *.src.rpm命令将源代码编译并在/usr/src/dist/RPMS下生成二进制的rpm包,然后再安装该二进制包即可。packgename 如前所述。
  2、*.tar.gz/*.tgz、*.bz2形式的源代码软件包
  安装:tar zxvf *.tar.gz 或 tar yxvf *.bz2 先解压
  然后进入解压后的目录:
  默认安装(不指定安装目录):
./configure 配置
make 编译
make install 安装
  或者指定安装目录:
./configure --prefix=安装目录
make 编译
make install 安装
  卸载:make uninstall 或 手动删除
  说明:建议解压后先阅读说明文件,可以了解安装有哪些需求,有必要时还需改动编译配置。有些软件包的源代码在编译安装后可以用make install命令来进行卸载,如果不提供此功能,则软件的卸载必须手动删除。由于软件可能将文件分散地安装在系统的多个目录中,往往很难把它删除干净, 那你应该在编译前进行配置,指定软件将要安装到目标路径:./configure --prefix=目录名,这样可以使用“rm -rf 软件目录名”命令来进行干净彻底的卸载。与其它安装方式相比,需要用户自己编译安装是最难的,它适合于使用Linux已有一定经验的人,一般不推荐初学者 使用。
  关于Linux下软件的安装与卸载lanche已经讲了这么多,但可能还会有人问怎么知道一个tar.gz/bz2包是二进制文件包呢还是源代码包? 如果你用过压缩工具就会明白,压缩包未必就是软件,它也可能是备份的许多图片,也可能是打包在一起的普通资料,要分辨它到底是什么最好的办法就是查看包里 的文件清单,使用命令tar ztvf *.tar.gz / tar ytvf *.bz2或者在X-Window下使用图形化的ArK压缩档案管理工具都可以,源代码包里的文件往往会含有种种源代码文件,头文件*.h、c代码源文 件*.c、C++代码源文件*.cc/*.cpp等;而二进制包里的文件则会有可执行文件(与软件同名的往往是主执行文件),标志是其所在路径含有名为 bin的目录(仅有少数例外)。

posted @ 2014-01-24 15:57 顺其自然EVO 阅读(316) | 评论 (0)编辑 收藏

操作系统的几个问题

学习操作系统是一件复杂的事情,靠的不仅仅是智慧,更关键的是坚持不懈,下面是笔者总结的几个问题,相当于是个读书笔记,留作考究。
  什么是DOS系统调用?
  系统功能调用是DOS为用户提供的常用函数,大概80多个,可以在汇编语言程序中直接调用,这些程序的主要功能包括:
  设备管理,如键盘、显示器、打印机、磁盘等的管理;
  文件管理和目录操作;
  其他管理,如内存、时间、日期等。
  调用方法:
  DOS功能调用程序已按顺序编号——功能号(00H~68H)
  调用方法是:
  功能号——>AH
  入口参数——>指定寄存器
  INT 21H
  什么是BIOS中断调用?
  BIOS的全称是ROM BASIC I/O SYSTEM,即只读存储器基本输入输出系统;它是一组固化到微机主板上的一个ROM芯片的子程序,主要功能包括:
  驱动系统中所配置的常用外设;
  开机自检,引导装入;
  提供时间、内存容量及设备情况等参数。
  什么是MBR?
  (来自于维基百科)
  主引导记录(Master Boot Record,缩写:MBR),又叫做主引导扇区,是计算机开机后访问硬盘时所必须要读取的首个扇区,它在硬盘上的三维地址为(柱面,磁头,扇区)=(0,0,1)。在深入讨论主引导扇区内部结构的时候,有时也将其开头的446字节内容特指为“主引导记录”(MBR),其后是4个16字节的“磁盘分区表”(DPT),以及2字节的结束标志(55AA)。因此,在使用“主引导记录”(MBR)这个术语的时候,需要根据具体情况判断其到底是指整个主引导扇区,还是主引导扇区的前446字节;
  主引导扇区记录着硬盘本身的相关信息以及硬盘各个分区的大小及位置信息,是数据信息的重要入口。如果它受到破坏,硬盘上的基本数据结构信息将会丢失,需要用繁琐的方式试探性的重建数据结构信息后才可能重新访问原先的数据。主引导扇区内的信息可以通过任何一种基于某种操作系统的分区工具软件写入,但和某种操作系统没有特定的关系,即只要创建了有效的主引导记录就可以引导任意一种操作系统(操作系统是创建在高级格式化的硬盘分区之上,是和一定的文件系统相联系的)。
  MBR的组成
  启动代码
  主引导记录最开头是第一阶段引导代码。其中的硬盘引导程序的主要作用是检查分区表是否正确并且在系统硬件完成自检以后将控制权交给硬盘上的[[引导程序]](如[[GNU GRUB]])。 它不依赖任何操作系统,而且启动代码也是可以改变的,从而能够实现[[多系统引导]]。
  硬盘分区表
  硬盘分区表占据主引导扇区的64个字节(偏移01BEH--偏移01FDH),可以对四个分区的信息进行描述,其中每个分区的信息占据16个字节。具体每个字节的定义可以百度'''硬盘分区结构信息'''。
  结束标志字
  ''结束标志字'' 55,AA(偏移1FEH-偏移1FFH)是'''主引导扇区'''的最后两个字节,是检验主引导记录是否有效的标志。
  实模式和保护模式?
  实模式,又叫实地址模式,CPU完全按照8086的实际寻址方法访问从00000h--FFFFFh(1MB大小)的地址范围的内存,在这种模式下,CPU只能做单任务运行;寻址公式为:物理地址=左移4位的段地址+偏移地址,即:物理地址是由16位的段地址和16位的段内偏移地址组成的。
  保护模式,又叫内存保护模式,寻址采用32位段和偏移量,最大寻址空间4GB,在这种模式下,系统运行于多任务,设计这种模式的原因和好处是:保护模式增加了寻址空间,增加了对多任务的支持,增加了段页式寻址机制的内存管理(分段机制使得段具有访问权限和特权级,各应用程序和操作系统的代码和核心是被保护的,这也是多任务支持的实现关键和保护这个名字的由来)。寻址过程为:物理地址=由段地址查询全局描述符表中给出的段基址+偏移地址,即:物理地址由影像寄存器中的基址加上16位或者32位的偏移组成。
  保护模式与实模式相比:
  提供了段间的保护机制,防止程序间胡乱访问地址带来的问题;
  访问的内存空间变大。
  为什么分段之后还要分页?
  关于内存分页机制,可以查看http://blog.csdn.net/cuifengqinghan/article/details/17595727中关于分页机制的部分;
  你可能已经知道,分段管理机制已经提供了很好的保护机制,为什么还要引入分页管理机制呢?其实它的目的在于实现虚拟存储器。
  虚拟内存是计算机系统内存管理的一种技术。它使得应用程序认为它拥有连续的可用的内存(一个连续完整的地址空间),而实际上,它通常是被分隔成多个物理内存碎片,还有部分暂时存储在外部磁盘存储器上,在需要时进行数据交换。
  这样有一个直观的好处就是:物理内存碎片的使用和内存消耗殆尽拿出一部分硬盘空间来充当内存使用,缓解内存的紧张。

posted @ 2014-01-24 15:56 顺其自然EVO 阅读(1240) | 评论 (1)编辑 收藏

OpenGL模板缓冲区与模板测试

帧缓冲区有许多缓冲区构成,这些缓冲区大致分为:
  颜色缓冲区:用于绘图的缓冲区,它包含了颜色索引或者RGBA颜色数据。
  深度缓冲区:存储每个像素的深度值,当启动深度测试时,片段像素深度值和深度缓冲区深度值进行比较,决定片段哪些像素点数据可以替换到颜色缓冲区中。
  模板缓冲区:就像使用纸板和喷漆一样精确的混图一样,当启动模板测试时,通过模板测试的片段像素点会被替换到颜色缓冲区中,从而显示出来,未通过的则不会保存到颜色缓冲区中,从而达到了过滤的功能。
  累积缓冲区:累积缓冲区允许你把渲染到颜色缓冲区的值,拷贝到累积缓冲区。在多次拷贝操作到累积缓冲区时,可以用不同方式的把颜色缓冲区内容和当前累积缓冲区的内容进行重复混合
  模板测试
  模板测试只有存在模板缓冲区的情况下进行,模板测试把像素存储在模板缓冲区的点与一个参考值进行比较(glStencilFunc),根据测试结果,对模板缓冲区的值进行响应的修改glStencilOp
  void glStencilFunc (GLenum func, GLint ref, GLuint mask);
  func:GL_NEVER 从来不能通过
  GL_ALWAYS 永远可以通过(默认值)
  GL_LESS 小于参考值可以通过
  GL_LEQUAL 小于或者等于可以通过
  GL_EQUAL 等于通过
  GL_GEQUAL 大于等于通过
  GL_GREATER 大于通过
  GL_NOTEQUAL 不等于通过
  ref: 参考值
  mask:掩码,书上说模板测试只在哪些对应为1的位上进行。(不是很确定具体作用)
  举例:glStencilFunc (GL_LESS, 1.0, 1.0);模板缓冲区对应的像素点的值如果小于1.0,则通过模板测试
  void glStencilOp (GLenum fail, GLenum zfail, GLenum zpass);
  fail模板测试未通过时该如何变化;zfail表示模板测试通过,但深度测试未通过时该如何变化;zpass表示模板测试和深度测试或者未执行深度测试均通过时该如何变化
  GL_KEEP(不改变,这也是默认值)
  GL_ZERO(回零)
  GL_REPLACE(使用测试条件中的设定值来代替当前模板值)
  GL_INCR(增加1,但如果已经是最大值,则保持不变),
  GL_INCR_WRAP(增加1,但如果已经是最大值,则从零重新开始)
  GL_DECR(减少1,但如果已经是零,则保持不变),
  GL_DECR_WRAP(减少1,但如果已经是零,则重新设置为最大值)
  GL_INVERT(按位取反)
  未启用模板缓冲区
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glTranslatef(0, 0, -20);
glColor3f(1.0f,1.0f,1.0f);
dRadius = 5.0*(sqrt(2.0)/2.0);
glBegin(GL_LINE_STRIP);
for (dAngel=0;dAngel<380.0;dAngel+=0.1)
{
glVertex2d(dRadius*cos(dAngel),dRadius*sin(dAngel));
dRadius*=1.003;
}
glEnd();
glColor3f(1.0f,0.0f,0.0f);
glRectf(-5,-5,5,5);

初始清除背景填充颜色为蓝色
  以上这部分代码可以用如下3张图表示绘制的过程
  开启模板缓冲区
void init()
{
glClearColor(0,0,1.0,0);
glClearStencil(0);
glClearDepth(1.0f);
glEnable(GL_STENCIL_TEST);
}
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);//1
glLoadIdentity();
glTranslatef(0, 0, -20);
glStencilFunc(GL_NEVER,0x0,0xFF);  //2
glStencilOp(GL_INCR,GL_INCR,GL_INCR);//3
glColor3f(1.0f,1.0f,1.0f);
dRadius = 5.0*(sqrt(2.0)/2.0);
glBegin(GL_LINE_STRIP);
for (dAngel=0;dAngel<380.0;dAngel+=0.1)
{
glVertex2d(dRadius*cos(dAngel),dRadius*sin(dAngel));
dRadius*=1.003;
}
glEnd();
glStencilFunc(GL_NOTEQUAL,0x1,0xFF);  //4
glStencilOp(GL_KEEP,GL_KEEP,KEEP); //5
glColor3f(1.0f,0.0f,0.0f);
glRectf(-5,-5,5,5);
  当执行到1处,3个缓冲区都被清空
  颜色缓冲区:每个像素点颜色都是蓝色
  深度缓冲区:每个像素点深度都是1.0
  模板缓冲区:每个像素点模板值都是0
  执行到2,3处,模板测试条件是从不通过测试,如果不通过测试结果是模板值+1
  接着应用模板测试进行绘制一组点,由于模板测试条件是从不通过测试,所以颜色缓冲器值不会变化,但是绘制的点对应的像素点的模板值变为1,此时
  颜色缓冲区:每个像素点颜色都是蓝色
  深度缓冲区:每个像素点深度都是1.0
  模板缓冲区:点数组对应的模板值是1,其他区域像素点的模板值还是0
  执行到4,5处,模板测试条件是模板值不一定1则通过测试,如果不通过测试结果是模板值+1
  接着应用刚才的模板测试进行绘制一个(-5,-5,5,5)的矩形,在这个矩形区域内,像素点的模板值分为2中,值为1的是上1步的点数组。值为0的是上一步非的点数组像素点。那个根据模板测试条件,模板值为0的像素点通过测试,可以进行替换颜色缓冲区的值(替换成红色),模板值为0的像素点不能通过测试,因此不能改变颜色缓冲区的值
  颜色缓冲区:(-5,-5,5,5)区域内 模板值为0的像素点为红色,其他区域都为蓝色
  深度缓冲区:每个像素点深度都是1.0
  模板缓冲区:点数组对应的模板值是1,其他区域像素点的模板值还是0
模板查询
  可以用glGetInteger函数获取与模板相关的参数值
#include "header.h"
float dRadius =0;
float dAngel;
float aspect=0;
void init()
{
glClearColor(0,0,1.0,0);
glClearStencil(0);
glClearDepth(1.0f);
glEnable(GL_STENCIL_TEST);
}
void display()
{
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
glLoadIdentity();
glTranslatef(0, 0, -20);
////glStencilFunc(GL_ALWAYS, 0,0x00);
glStencilFunc(GL_NEVER,0x0,0xFF);
glStencilOp(GL_INCR,GL_INCR,GL_INCR);
glColor3f(1.0f,1.0f,1.0f);
dRadius = 5.0*(sqrt(2.0)/2.0);
glBegin(GL_LINE_STRIP);
for (dAngel=0;dAngel<380.0;dAngel+=0.1)
{
glVertex2d(dRadius*cos(dAngel),dRadius*sin(dAngel));
dRadius*=1.003;
}
glEnd();
glStencilFunc(GL_NOTEQUAL,0x1,0xFF);
glStencilOp(GL_INCR,GL_INCR,GL_INCR);//
glColor3f(1.0f,0.0f,0.0f);
glRectf(-5,-5,5,5);
glutSwapBuffers();
}
void reshape(int w, int h)
{
glViewport(0,0,w,h);
aspect = (w*1.0)/h;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60, aspect, 1, 100);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
//glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGBA|GLUT_STENCIL);
glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGBA|GLUT_STENCIL|GLUT_DEPTH);
glutInitWindowPosition(200,200);
glutInitWindowSize(600,600);
glutCreateWindow("模板缓冲区与模板测试");
glewInit();
init();
glutReshapeFunc(reshape);
glutDisplayFunc(display);
glutMainLoop();
return 0;
}

posted @ 2014-01-23 11:53 顺其自然EVO 阅读(3436) | 评论 (0)编辑 收藏

从测试数据来看Node.js和Java EE的性能区别

本文作者Marc Fasel是一名高级顾问、架构师、软件开发者。他有着18年的构建大规模、高性能企业App的经验。在这篇文章里,他通过做测试的方式(在Node.js App上和Java伺服器App上分别进行性能测试),一步步将测试过程、结果、结论写出来,分析两者的性能区别。(以下是编译内容)
  本文是通过从CouchDB上读取JSON数据来比较Node.js和Java EE之间的性能的。究竟谁的性能更好些?为了回答这一问题,只有在一系列的性能测试下运行Node.js App和Java EE App,才能得出最终结果来。
  准备阶段
  首先是在Node.js App上和Java伺服器App上分别进行了性能测试。每个App上都是用了相同的后端作为初始Node.js App:CouchDB。除此还使用了CouchBase Single Server版本1.1.3。创造出一万份大小4KB的随机文本样本文件。测试机器是配备2.4 GHZ、Intel Core 2 Duo、4 GB RAM和Mac OS X的iMac。另外,在一个独立的机器上使用Apache JMeter作为测试驱动器。
  Java EE
  Java伺服器是运行在一个版本为7.0.21的Apache Tomcat上的,默认配置运行在Java 1.6上。数据库驱动程序是版本0.30的CouchDB4J,驱动程序没有缓存选项,所以,没有完成任何配置。
  接下来的这个Java代码是一个伺服器的代码,可以通过CouchDB获取文档,将数据作为一个JSON对象来处理。
  通过使用JMeter测试驱动器来测试伺服器在不同的并发性基础之上,下面的表格数字就展现出不同的并发需求——平均的响应时间,和每秒相应的所对应的回复。
  从表格里就可以看出,当并行需求在增加的时候,响应时间就会有所变化。每10个并行需求的响应时间平均起来是23毫秒,100个并行需求的响应时间平均起来就是243毫秒。
  比较有趣的部分是,响应时间的平均数和并行需求的数量有着线性相关关系,所以,并行需求增长十倍就会导致每个需求的响应时间增长十倍。这使得在每秒钟处理需求数量是相当恒定的,不管有10个并发请求或150个并发请求,都无所谓。在所有观察到的并发服务请求数量大约为每秒420。
 Node.js
  Node.js App 使用Cradle CouchDB驱动程序0.57版本,运行在Node.js 0.10.20,为了给驱动程序创造相等的条件,运行时的缓存必须要关闭的。
  接下来的数据显示Node.js程序通过一个给定的ID从CouchDB里传递同样的JSON文档:
  Node.js系统数目如下:
  正如前面所说的一样,平均的响应时间和并行需求数量呈线性相关关系,每秒钟处理需求数量是相当恒定的。Node.js相对较快20%,例如,在10个并行需求里,509个需求/秒VS.422需求/每秒。
  结论
  Node.js解决问题的速度比Java EE快20%,这的确有点出乎意料——一种解释语言和一种编译语言在一个VM中的速度是一样快的,这没有多年的优化过程是绝对达不到的。
  其实,Node.js和Java EE规模超出正常的服务器需求。每秒400-500的请求数量可以说是相当不错。谷歌是世界上最大的网站,每天有大约50亿个请求,如果换算成秒的话,也就是57870个请求/秒。这也是谷歌域名在世界范围内的需求数量,所以如果你有一个运行在一台机器上的、400需求/秒的网站的话,那你的这个网站可以说是相当的大了。平均每天100万个需求也就意味着11.5需求/秒。这是一个很重要的数字。
  在这个性能测试里,在单线程的Node.js和多线程的Java EE之间的采用不同的并发模型对最后的结果是没有影响的。如果想要在更高并发水平里测试Node.js的性能,就必须要考虑到开放文件数量这一问题。

posted @ 2014-01-23 11:53 顺其自然EVO 阅读(294) | 评论 (0)编辑 收藏

基于Selenium2与Python自动化测试环境搭建

工具选择
  Python版本: 选择2.7.3, Why? 目前大部分第三方库和工具对2.7都有简单的安装包,不需要自己做太多处理,比2.6内置了一些包,不需要再安装; Python3.x不支持Se2.0
  Selenium版本:选择2.0+,Why? 因为从2.0开始,Se已经和WebDriver集成在一起了,WebDriver提供了非常多的API和自动化测试处理方法。
  脚本开发:Eclipse(JDK:选择1.6版本),其中插件选择:PyDev
  代码库管理:SVN,使用SVN对整个框架下的内容进行版本管理
  环境搭建步骤(Windows7, 32位)
  我用的安装包都在这里  http://download.csdn.net/detail/spring292713/4551979
  包括   python-2.7.3.msi   setuptools-0.6c11.win32-py2.7.exe   MySQL-python-1.2.3.win32-py2.7.msi
  IEDriverServer_Win32_2.25.3.zip     chromedriver_win_23.0.1240.0.zip
  第一步:安装Python
  根据下面的地址,直接一键安装,全部默认方式。
  下载地址:http://www.python.org/getit/
  我安装在 “D:/Develop/Python ”
  然后设置Python的环境变量, Path:“D:\Develop\Python;”
  第二步:安装Python的SetupTools
  其实SetupTools就是一个帮助你安装第三方工具包的增强工具软件,根据下面的地址下载,然后一键安装。下载地址:
  http://pypi.python.org/packages/2.7/s/setuptools/setuptools-0.6c11.win32-py2.7.exe#md5=57e1e64f6b7c7f1d2eddfc9746bbaf20
  下载完后双安装即可
  第三步:安装Python的包管理工具 pip—有点类似SetupTools ,但是比它强大
  利用第二步安装的SetupTools进行安装,打开DOS界面,进入到目录:
  D:\Develop\Python\Scripts, 然后敲入命令:easy_install pip, 等待完成就OK。
  第四步:安装基于Python的Selenium包
  打开DOS界面,进入到目录: D:\Develop\Python\Scripts
  然后敲入命令: pip install selenium or pip install –U selenium,其中:里面一些警告可以暂时不用管,如果想找到原因,Pls 百度 or 谷歌 一下!


 测试代码:
<span style="font-size:18px;"><span style="background-color: #ffffff;">#-*-coding:utf-8-*-
from selenium import webdriver
import unittest
class Login(unittest.TestCase):
def setUp(self):
self.driver = webdriver.Firefox()
self.driver.implicitly_wait(30)
self.base_url = "http://blog.csdn.net"
self.verificationErrors = []
self.accept_next_alert = True
def test_login(self):
driver = self.driver
driver.get(self.base_url + "/spring292713")
driver.find_element_by_link_text(u"登录").click()
driver.switch_to_frame("logfrm")
driver.find_element_by_id("u").clear()
driver.find_element_by_id("u").send_keys("spring292713")
driver.find_element_by_id("p").clear()
driver.find_element_by_id("p").send_keys("xxxoo")
driver.find_element_by_id("aLogin").click()
def tearDown(self):
self.driver.quit()
self.assertEqual([], self.verificationErrors)
if __name__ == "__main__":
unittest.main()</span><span style="color:#3333ff;"><strong>
</strong></span></span>
  若登陆成功,说明OK了!!
  <span style="background-color: #009900; color: #ffffff; font-size: 18px; font-family: Arial, Helvetica, sans-serif;">加上 chromedriver.exe 和 IEDriverServer.exe 后,降代码的第六行改成</span>
  driver = webdriver.Ie()   或    driver = webdriver.Chrome() 可测试在IE或Chrome下的效果。
  但是很不幸,我在win7下测试成功,在XP下测试只有Firefox能通过!!

posted @ 2014-01-23 11:47 顺其自然EVO 阅读(342) | 评论 (0)编辑 收藏

从传统ERP测试向主流互联网测试转型

  昨天晚上微博上有测试同仁 @testGM 想了解下如何从传统ERP测试向主流互联网测试转型。我本人在来淘宝之前就是做传统ERP测试的,现在在淘宝做了这么长时间,对互联网测试也有一定的了解,就想谈谈自己的看法。
  特意说明下,我这边了解到的传统ERP测试就是4或5年前的ERP测试情况,不代表目前的整体情况,说的不对的地方 望谅解。
  整体策略:
  谈过如何转型,那就是知己知彼了。首先自己要了解传统ERP测试的优点和缺点以及特点,也要了解互联网测试的相关特点,从而给自己设定一个计划来快速转型,目的很简单,发挥在传统ERP测试的优势来弥补互联网测试的劣势,或者达到一种较好的平衡。
  传统ERP测试VS互联网测试
  (1)C/S架构:来淘宝之前,我是在MS做传统ERP的测试,这个ERP是MS从国外收购过来的,主要给中小企业提供ERP服务,大家应该知道,那时候,ERP是C/S架构的企业软件,现在很多ERP系统都是走B/S架构的。说实话,我不了解现在ERP系统的B/S架构和互联网产品的B/S架构的区别,所以这方面我就不继续说了。C/S架构带来的是什么呢?很显然,就是版本升级的非实时性。我记得我们当时每次修复bug后,都是将修复后的代码文件交给技术支持,然后由技术支持来重新import到版本中。
  (2)流程严格:这个就不多说了,在传统流程中,把文档和review和前后接入准则做的都是非常好的,我在MS那边的时候,提交bug、修复bug、回归bug都是很严格要求的,包括验证bug的TC,都是写的很详细的。还有就是fix bug的 old code/new code的细节,反看互联网测试这些都是很少去做的。
  (3)业务逻辑复杂:记得在MS我们要学习很多关于库存管理、财务管理,报表管理等很多行业知识,一方面给测试的复杂度带来了挑战,另一方面对业务逻辑的沉淀就显得非常重要了,记得当时有很多这样的业务文档要学习,当然也有一些人不做开发或测试,去做ERP的实施了。反看互联网测试上层业务变化还是非常快,业务逻辑变化也快,而且也没有ERP那么复杂的业务逻辑,从而测试接触到的都是非行业核心的东西。
  (4)测试效率:前面几个特点也说明了传统ERP的测试效率应该很一般,的确是的,包括ERP传统测试技术的发展,这个原因也是多方面的,我觉得很大一方面是开发架构和技术的变化不大,导致测试技术的变化也不大。大家可以看看互联网的开发技术变化多快,很多新技术和架构都是在互联网产品上应用起来的,同样的映射就是测试也必须在测试技术上提高从而跟上开发的步伐。包括接口自动化测试、分层自动化、持续集成、A/B Test等等,很多测试技术在互联网上应用较多。很多测试同仁也认为互联网的测试技术很牛B,一方面互联网测试必须找到很多较先进和流行的测试方法或技术或框架来提高效率。其实做传统ERP测试的人也是很牛B的,在国内的特点,就是太封闭了,不去外面交流来寻找新的方法和技术,国内估计很难找,那就去国外找啊,相信总能找到的。
  其实对比这个还有一些特点:比如传统测试,职责明确;而互联网测试就是责任共享;传统测试就是大步迈进,而互联网测试强调的是小步快走。
  说了那么多,大家可能会问,我到底怎么转型啊,怎么更快的啊。
  目标确定了,既然要做互联网测试,那就了解互联网产品测试的特点呗,有哪些核心的技术和框架呗。建议想转型的人,从下面几个角度考虑:
  (1)测试方法:大家可能会说,测试设计方法应该差别不多,是的,的确不大,但还是有差别的,建议各位看看互联网产品的公共功能的测试设计方法,我之前的blog也有提到。多了解下同样的边界值和组合测试法在互联网产品上是如何测试设计的。
  (2)自动化测试:一方面,把自己做ERP自动化测试的经验带过来,我记得我在MS做ERP自动化测试的时候,那是MS的测试自己开发的测试框架,很牛X,我仔细的了解了下该框架的架构,发现Client的界面都是建模的等特点。后来到淘宝,做页面自动化时,就提出了类似的建议并一直使用至今。另一方面,就是学习分层自动化测试和持续集成,多学习下java语言以及互联网产品的开发架构,包括相关的基础技术,数据库Linux命令啥的。一步一步来,先从页面自动化框架开始玩玩,从使用到熟悉到精通,搞起来,然后就是接口自动化,类似的过程。持续集成也是一样。
  (3)测试流程:需要了解互联网产品的测试流程,大部分是走敏捷的,虽然很多走的乱七八糟的,但是就是那个样子,流程乱,测试开发信息脱节,交互设计信息脱节,太多的问题存在了,回归测试和冒烟测试的重要性和严谨性等等都是大打折扣的。这些东西在传统里面就做的非常好,你可以把这些实践拿过来在互联网产品的测试上实践,虽然因为各种各样的原因,有很多难以做起来,但是不要忘记这些好的东西,慢慢的坚持,总会有进步的。
  (4)测试心态:这个大家可能觉得奇怪了,为啥要看测试心态。只是提前打个预防针而已,互联网测试 很枯燥,很乏味,你需要测试很多浏览器,兼容看看;你还会发现很多bug,虽然很多是前端bug,但是你发现和回归都很痛苦;你会不停的关注性能测试以及线上反馈;你还会担心你测试的页面是否有安全漏洞;你还会痛苦的发现我做了那么多,测试技术还这鸟样。不管怎么样,你还是要坚持下去,目前来看,就是互联网的测试技术发展较快,能把你的眼界打开,看到更多的彩虹。
  我接触了很多做传统ERP测试的同仁,当然也有非ERP的测试,大部分人都是很仔细,很有耐心的,在互联网产品上继续保持这个,你肯定有前途,当然测试技术上也要跟上大家的步伐。

posted @ 2014-01-23 11:47 顺其自然EVO 阅读(205) | 评论 (0)编辑 收藏

Sqlite数据库的加密

 1、创建空的sqlite数据库。
//数据库名的后缀你可以直接指定,甚至没有后缀都可以
//方法一:创建一个空sqlite数据库,用IO的方式
FileStream fs = File.Create(“c:\\test.db“);
//方法二:用SQLiteConnection
SQLiteConnection.CreateFile(“c:\\test.db“);
  创建的数据库是个0字节的文件。
  2、创建加密的空sqlite数据库
  //创建一个密码为password的空的sqlite数据库
SQLiteConnection.CreateFile(“c:\\test2.db“);
SQLiteConnection cnn = new SQLiteConnection(“Data Source=c:\\test2.db“);
SQLiteConnection cnn = new SQLiteConnection(“Data Source=D:\\test2.db“);
cnn.Open();
cnn.ChangePassword(“password“);
  3、给未加密的数据库加密
SQLiteConnection cnn = new SQLiteConnection(“Data Source=c:\\test.db“);
cnn.Open();
cnn.ChangePassword(“password“);
  4、打开加密sqlite数据库
//方法一
SQLiteConnection cnn = new SQLiteConnection(“Data Source=c:\\test2.db“);
cnn.SetPassword(“password“);
cnn.Open();
//方法二
SQLiteConnectionStringBuilder builder = new SQLiteConnectionStringBuilder();
builder.DataSource = @”c:\test.db“;
builder.Password = @”password“;
SQLiteConnection cnn = new SQLiteConnection(builder.ConnectionString);
cnn .Open();
  分页
  select * from messages limit 10,100;
  表示跳过10行,取100行的返回结果。

posted @ 2014-01-23 11:46 顺其自然EVO 阅读(1754) | 评论 (0)编辑 收藏

仅列出标题
共394页: First 上一页 156 157 158 159 160 161 162 163 164 下一页 Last 
<2024年11月>
272829303112
3456789
10111213141516
17181920212223
24252627282930
1234567

导航

统计

常用链接

留言簿(55)

随笔分类

随笔档案

文章分类

文章档案

搜索

最新评论

阅读排行榜

评论排行榜