getXY : function(element){ var y = element.offsetTop; var x = element.offsetLeft; while(element = element.offsetParent){ y += element.offsetTop; x += element.offsetLeft; } return (new Array(x,y)); } |
貌似是这个问题,递归代码在火狐下好像有问题,要打桩测一下(不打桩了,有log输出就容易了)
getXY : function(element){ var y = element.offsetTop; var x = element.offsetLeft; var i=0; while(element = element.offsetParent){ y += element.offsetTop; x += element.offsetLeft; i++; } //firefox debug console.log(i); console.log(y); console.log(x); return (new Array(x,y)); } |
在ie9下为4 120 100,正常
火狐为0 0 0,看来只要换个递归的写法就行了,
但是这个问题的原因要查清楚,项目里有这种风格写法的人,可能对于火狐的解析器来说
while(element = element.offsetParent)估计一开始就等于false啊..具体
测试下
具体文章javascript的互等性,要补一下了.
火狐下element.offsetParent一开始就等于null
还是要去打桩,bug无法确定了,有可能是递归写法问题,又可能是前面传的element对象不对
还是不用打桩,调试时的一个报错,说明火狐解析器对判断条件里的element = element.offsetParent的理解是正确的.
前面的传参不对,or火狐对offsetParent的属性理解不对(如果加悬浮布局,那么火狐下是直接父节点直接对应body的,然后当然是null,记得是),没有使用危险的css属性,应该不会有问题的啊,
getXY : function(element){ var y = element.offsetTop; var x = element.offsetLeft; var i=0; if(!element.offsetParent) console.log("null"); console.log(element.id); while(element = element.offsetParent){ y += element.offsetTop; x += element.offsetLeft; i++; } //firefox debug console.log(i); console.log(y); console.log(x); return (new Array(x,y)); } |
传参正确,获得的id和在ie下一样,不过应该没有并没有该id对应的对象在页面中存在,不过ie能理解,这个火狐也是认得,但是貌似这个parent对象火狐处理得和ie不同(直接为空,ie正常)
差点以为有又有什么我不知道的写法,xx_xx什么的可以直接一起获取,当然不可能啊,草,怪怪的语言,随时提心吊胆的
是 获取一个隐藏的input对象的父节点问题,导致常用的递归获取元素绝对坐标方法的递归失败.在firefox下,隐藏表单字段估计直接对应body节点 (猜的),那么就是为空(或者直接就是对象属性封装的问题,反正是bug),估计就是这个问题了,稍微修改后BUG被clear(在getXY里用固有结 构,把对象指向日期框后解决)
offsetParent这个属性是个level0的属性,实现各异
而jq中的>可以跳来跳去,会不会也有这个bug呢?还是jq处理了这个BUG,等有时间再去测试吧
接下来就是一些css问题,和修复原控件的select的fous问题,还是尽量不要用input这玩意在ie6下并不好,xinput控件调用又太麻烦了
基于先前研究,进销存模块使用的透明图片加div颜色属性实现的皮肤效果,可以进行日期控件在保证其他位置引用兼容性的前提下,进行和进销存模块独有的表单皮肤系统整合
在前辈的指导下修改了getYear(),getFullYear(),火狐是不支持 getYear()的,一开始我还以为那个控件一直是从Const里获得年月日的,其实是外部调用时传个date()对象?有时又在控件里建date()对象,当初可能是想做什么吧,中途可能放弃了,那Const里那个年月日是干嘛的,要好好看看去
发现火狐失去焦点事件的bug,可能比较难改,简单说就是点击旁边后,选择框不会关..选择时候的鼠标状态问题,火狐好像不会变选择手势呢
English » | | | | | | | | |
Text-to-speech function is limited to 100 characters
正交试验设计(Orthogonal experimental design)是研究多因素多水平的一种设计方法,它是根据正交性从全
面试验中挑选出部分有代表性的点进行试验,这些有代表性的点具备了“均匀分散,齐整可比”的特点,正交试验设计是一种基于正交表的、高效率、快速、经济的试验。
什么是因素(Factor):在一项试验中,凡欲考察的变量称为因素(变量)
什么是水平(位级)(Level):在试验范围内,因素被考察的值称为水平(变量的取值)
正交表的构成:
行数(Runs):正交表中的行的个数,即试验的次数。
因素数(Factors):正交表中列的个数。
水平数(Levels):任何单个因素能够取得的值的最大个数。正交表中的包含的值为从0到数“水平数-1”或从1到“水平数”
正交表的表示形式: L行数(水平数因素数)
正交表:
各列中出现的最大数字相同的正交表称为相同水平正交表。如L4(23)、L8(27)、L12(211)等各列中最大数字为2,称为两水平正交表;L9(34)、L27(313)等各列中最大数字为3,称为3水平正交表。凡是标准表,水平数都相等,且水平数只能取素数或素数幂。因此有7水平、9水平的标准表,没有6水平,8水平的标准表。
例如L9(34),它表示需做9次实验,最多可观察4个因素,每个因素均为3水平。
混合正交表:
一个正交表中也可以各列的水平数不相等,我们称它为混合型正交表,如L8(4×24),即:L8(41×24)此表的5列中,有1列为4水平,4列为2水平。再如L16(44×23),L16(4×212)等都混合水平正交表。
正交表的两个特点:
正交表必须满足这两个特点,有一条不满足,就不是正交表。
1)每列中不同数字出现的次数相等。例如,在两水平正交表中,任何一列都有数码“1”与“2”,且任何一列中它们出现的次数是相等的;在三水平正交表中,任何一列都有“1”、“2”、“3”,且在任一列的出现数均相等。这一特点表明每个因素的每个水平与其它因素的每个水平参与试验的几率是完全相同的,从而保证了在各个水平中最大限度地排除了其它因素水平的干扰,能有效地比较试验结果并找出最优的试验条件。
2)在任意两列其横向组成的数字对中,每种数字对出现的次数相等。例如,在两水平正交表中,任何两列(同一横行内)有序对子共有4种:(1,1)、(1,2)、(2,1)、(2,2)。每种对数出现次数相等。在三水平情况下,任何两列(同一横行内)有序对共有9种,1.1、1.2、1.3、2.1、2.2、2.3、3.1、3.2、3.3,且每对出现数也均相等。这个特点保证了试验点均匀地分散在因素与水平的完全组合之中,因此具有很强的代表性。
以上两点充分的体现了正交表的两大优越性,即“均匀分散性,整齐可比”。通俗的说,每个因素的每个水平与另一个因素各水平各碰一次,这就是正交性。
混合正交表选择正交表的时候需满足:水平数>=max(水平1,水平2,...),因素数>=(因素1+因素2+因素3+…)
混合正交表选择正交表的示例:
我们分析一下:
1、被测项目中一共有四个被测对象(4个因素),每个被测对象的状态(水平数)都不一样。其中,A、C水平数均为3,B的水平数为4,D的水平数为2。
2、选择正交表:
本题,水平数>=max(3,4,2)=4,因素数>=4,查询附录中的正交表,只有L16(45)的行数最少,行数取最少的一个,比较适合。
3、最后选中正交表公式:L16(45)
另外,当水平数和因素数的具体值确定时,正确的行数(试验次数)的计算方法是:
试验次数(行数)=∑(每列水平数-1)+1
如:L18(36 *61)=(3-1)*6+(6-1)*1+1=18;L8(27)=(2-1)*7+1=8
用正交表设计测试用例
设计测试用例的步骤:
1、有哪些因素(变量)
2、每个因素有哪几个水平(变量的取值)
3、选择一个合适的正交表
4、把变量的值映射到表中
5、把每一行的各因素水平的组合作为一个测试用例
6、加上你认为可疑且没有在表中出现的用例组合
如何选择正交表
1、考虑因素(变量)的个数
2、考虑因素水平(变量的取值)的个数
3、考虑正交表的行数
4、取行数最少的一个
设计测试用例时的三种情况:
1、因素数(变量)、水平数(变量值)相符
水平数(变量的取值)相同、因素数(变量)刚好符合某一正交表,则直接套用正交表,得到用例。
例子:
对某人进行查询,假设查询某个人时有三个查询条件:
根据“姓名”进行查询
根据“身份证号码”查询
根据“手机号码”查询
考虑查询条件要么不填写,要么填写,此时可用正交表进行设计
① 因素数和水平数
有三个因素:姓名、身份证号、手机号码。每个因素有两个水平:
姓名:填、不填
身份证号:填、不填
手机号码:填、不填
② 选择正交表
表中的因素数>=3
表中至少有三个因素的水平数>=2
行数取最少的一个
结果:L4(2^3)
③ 变量映射
姓名:1→填写,2→不填写;
身份证号:1→填写,2→不填写;
手机号码:1→填写,2→不填写;
④ 用L4(2^3)设计的测试用例
测试用例如下:
1:填写姓名、填写身份证号、填写手机号
2:填写姓名、不填身份证号、不填手机号
3:不填姓名、填写身份证号、不填手机号
4:不填姓名、不填身份证号、填写手机号
⑤增补测试用例
5:不填姓名、不填身份证号、不填手机号
测试用例减少数:8→5
2、因素数不相同
水平数(变量的取值)与某正交表相同,但因素数(变量)却不相同,则取因素数最接近但略大于实际值的正交表表,套用之后,最后一列因素去掉即可。
例子:
兼容性测试:
操作系统:2000、XP、2003
浏览器:IE6.0、IE7.0、TT
杀毒软件:卡巴、金山、诺顿
如果全部进行测试的话,3^3=27个组合,需要进行27次测试。
① 因素数和水平数
有三个因素:
操作系统、浏览器、杀毒软件
每个因素有三个水平。
② 选择正交表
表中的因素数>=3
表中至少有三个因素的水平数>=3
行数取最少的一个
结果:L9(3^4),如下图:
English » | | | | | | | | |
Text-to-speech function is limited to 100 characters
近日,Hitest在其技术博客上发表了一篇题为《并发用户数与TPS之间的关系》的
文章,文章对TPS和并发用户数做了详细的解释,并针对
性能测试中系统性能的衡量维度和测试策略给出了自己的建议。Hitest是
阿里巴巴技术质量部提供的一款Web&移动应用安全测试SaaS化服务平台,旨在帮助开发者简单快捷地进行
安全测试。
在文中,作者首先对并发用户数和TPS做了解释:
并发用户数:是指现实系统中操作业务的用户,在性能测试工具中,一般称为虚拟用户数(Virutal User)。并发用户数和注册用户数、在线用户数的概念不同,并发用户数一定会对服务器产生压力的,而在线用户数只是 ”挂” 在系统上,对服务器不产生压力,注册用户数一般指的是
数据库中存在的用户数。
TPS:Transaction Per Second, 每秒事务数, 是衡量系统性能的一个非常重要的指标。
作者认为现在很多从业人员在做性能测试时,都错误的认为系统能支撑的并发用户数越多,系统的性能就越好。要理解这个问题,首先需要了解TPS和并发用户数之间的关系:
TPS就是每秒事务数,但是事务是基于虚拟用户数的,假如1个虚拟用户在1秒内完成1笔事务,那么TPS明显就是1;如果某笔业务响应时间是1ms,那么1个用户在1秒内能完成1000笔事务,TPS就是1000了;如果某笔业务响应时间是1s,那么1个用户在1秒内只能完成1笔事务,要想达到1000TPS,至少需要1000个用户;因此可以说1个用户可以产生1000TPS,1000个用户也可以产生1000TPS,无非是看响应时间快慢。
也就是说,在评定服务器的性能时,应该结合TPS和并发用户数,以TPS为主,并发用户数为辅来衡量系统的性能。如果必须要用并发用户数来衡量的话,需要一个前提,那就是交易在多长时间内完成,因为在系统负载不高的情况下,将思考时间(思考时间的值等于交易响应时间)加到脚本中,并发用户数基本可以增加一倍,因此用并发用户数来衡量系统的性能没太大的意义。
作者最后做了综述,他认为在性能测试时并不需要用上万的用户并发去进行测试,如果只需要保证系统处理业务时间足够快,几百个用户甚至几十个用户就可以达到目的。据他了解,很多专家做过的性能测试项目基本都没有超过5000用户并发。因此对于大型系统、业务量非常高、硬件配置足够多的情况下,5000用户并发就足够了;对于中小型系统,1000用户并发就足够了。
性能测试需要一套标准化流程及测试策略,在实际测试时我们还需要考虑其它方面的问题,比如如何模拟成千上万来自不同地区用户的访问场景、如何选用合适的测试软件。性能测试对一些小的团队来说并非易事,不过前段时间阿里云发布了性能测试服务PTS,PTS可以帮助开发者通过分布式并发
压力测试,模拟指定区域和指定数量的用户同时访问,提前预知网站承载力。这就是
云计算给我们带来的便利。
English » | | | | | | | | |
Text-to-speech function is limited to 100 characters
打开终端
cd /java/tomcat
#执行
bin/startup.sh #启动tomcat
bin/shutdown.sh #停止tomcat
tail -f logs/catalina.out #看tomcat的控制台输出;
#看是否已经有tomcat在运行了
ps -ef |grep tomcat
#如果有,用kill;
kill -9 pid #pid 为相应的进程号
例如 pe -ef |grep tomcat 输出如下
sun 5144 1 0 10:21 pts/1 00:00:06 /java/jdk/bin/java -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djava.endorsed.dirs=/java/tomcat/common/endorsed -classpath :/java/tomcat/bin/bootstrap.jar:/java/tomcat/bin/commons-logging-api.jar -Dcatalina.base=/java/tomcat -Dcatalina.home=/java/tomcat -Djava.io.tmpdir=/java/tomcat/temp org.apache.catalina.startup.Bootstrap start
则 5144 就为进程号 pid = 5144
kill -9 5144 就可以彻底杀死tomcat
首先得知道如何查看进程:)
前面介绍的两个命令都是用于查看当前系统用户的情况,下面就来看看进程的情况,这也是本章的主题.要对进程进行监测和控制,首先必须要了解当前进程的情况,也就是需要查看当前进程,而ps命令就是最基本同时也是非常强大的进程查看命令.使用该命令可以确定有哪些进程正在运行和运行的状态、进程是否结束、进程有没有僵尸、哪些进程占用了过多的资源等等.总之大部分信息都是可以通过执行该命令得到的.
ps命令最常用的还是用于监控后台进程的
工作情况,因为后台进程是不和屏幕键盘这些标准输入/输出设备进行通信的,所以如果需要检测其情况,便可以使用ps命令了.
ps [选项]
下面对命令选项进行说明∶
-e显示所有进程.
-f全格式.
-h不显示标题.
-l长格式.
-w宽输出.
a显示终端上的所有进程,包括其他用户的进程.
r只显示正在运行的进程.
x显示没有控制终端的进程.
O[+|-] k1 [,[+|-] k2 [,…]] 根据SHORT KEYS、k1、k2中快捷键指定的多级排序顺序显示进程列表.对于ps的不同格式都存在着默认的顺序指定.这些默认顺序可以被用户的指定所覆盖.其中“+”字符是可选的,“-”字符是倒转指 定键的方向.
最常用的三个参数是u、a、x.
English » | | | | | | | | |
Text-to-speech function is limited to 100 characters
A:不带输出參数的
create procedure getsum @n int =0<--此处为參数--> as declare @sum int<--定义变量--> declare @i int set @sum=0 set @i=0 while @i<=@n begin set @sum=@sum+@i set @i=@i+1 end print 'the sum is '+ltrim(rtrim(str(@sum))) |
exec getsum 100
在JAVA中调用:
JAVA能够调用 可是在JAVA程序却不能去显示该存储过程的结果 由于上面的存储过程的參数类型int 传递方式是in(按值)方式
import java.sql.*; public class ProcedureTest { public static void main(String args[]) throws Exception { //载入驱动 DriverManager.registerDriver(new sun.jdbc.odbc.JdbcOdbcDriver()); //获得连接 Connection conn=DriverManager.getConnection("jdbc:odbc:mydata","sa",""); //创建存储过程的对象 CallableStatement c=conn.prepareCall("{call getsum(?)}"); //给存储过程的參数设置值 c.setInt(1,100); //将第一个參数的值设置成100 //运行存储过程 c.execute(); conn.close(); } } |
B:带输出參数的
1:返回int
alter procedure getsum @n int =0, @result int output as declare @sum int declare @i int set @sum=0 set @i=0 while @i<=@n begin set @sum=@sum+@i set @i=@i+1 end set @result=@sum |
在查询分析器中运行:
declare @myResult int
exec getsum 100,@myResult output
print @myResult
在JAVA中调用:
import java.sql.*; public class ProcedureTest { public static void main(String args[]) throws Exception { //载入驱动 DriverManager.registerDriver(new sun.jdbc.odbc.JdbcOdbcDriver()); //获得连接 Connection conn=DriverManager.getConnection("jdbc:odbc:mydata","sa",""); //创建存储过程的对象 CallableStatement c=conn.prepareCall("{call getsum(?,?)}"); //给存储过程的第一个參数设置值 c.setInt(1,100); //注冊存储过程的第二个參数 c.registerOutParameter(2,java.sql.Types.INTEGER); //运行存储过程 c.execute(); //得到存储过程的输出參数值 System.out.println (c.getInt(2)); conn.close(); } } |
2:返回varchar
存储过程带游标:
在存储过程中带游标 使用游标不停的遍历orderid
create procedure CursorIntoProcedure
@pname varchar(8000) output
as
--定义游标
declare cur cursor for select orderid from orders
--定义一个变量来接收游标的值
declare @v varchar(5)
--打开游标
open cur
set @pname=''--给@pname初值
--提取游标的值
fetch next from cur into @v
while @@fetch_status=0
begin
set @pname=@pname+';'+@v
fetch next from cur into @v
end
print @pname
--关闭游标
close cur
--销毁游标
deallocate cur
运行存储过程:
exec CursorIntoProcedure ''
JAVA调用:
import java.sql.*; public class ProcedureTest { public static void main(String args[]) throws Exception { //载入驱动 DriverManager.registerDriver(new sun.jdbc.odbc.JdbcOdbcDriver()); //获得连接 Connection conn=DriverManager.getConnection("jdbc:odbc:mydata","sa",""); CallableStatement c=conn.prepareCall("{call CursorIntoProcedure(?)}"); c.registerOutParameter(1,java.sql.Types.VARCHAR); c.execute(); System.out.println (c.getString(1)); conn.close(); } } |
C:删除数据的存储过程
存储过程:
drop table 学生基本信息表 create table 学生基本信息表 ( StuID int primary key, StuName varchar(10), StuAddress varchar(20) ) insert into 学生基本信息表 values(1,'三毛','wuhan') insert into 学生基本信息表 values(2,'三毛','wuhan') create table 学生成绩表 ( StuID int, Chinese int, PyhSics int foreign key(StuID) references 学生基本信息表(StuID) on delete cascade on update cascade ) insert into 学生成绩表 values(1,99,100) insert into 学生成绩表 values(2,99,100) |
创建存储过程:
create procedure delePro
@StuID int
as
delete from 学生基本信息表 where StuID=@StuID
--创建完成
exec delePro 1 --运行存储过程
--创建存储过程
create procedure selePro
as
select * from 学生基本信息表
--创建完成
exec selePro --运行存储过程
在JAVA中调用:
import java.sql.*; public class ProcedureTest { public static void main(String args[]) throws Exception { //载入驱动 DriverManager.registerDriver(new sun.jdbc.odbc.JdbcOdbcDriver()); //获得连接 Connection conn=DriverManager.getConnection("jdbc:odbc:mydata","sa",""); //创建存储过程的对象 CallableStatement c=conn.prepareCall("{call delePro(?)}"); c.setInt(1,1); c.execute(); c=conn.prepareCall("{call selePro}"); ResultSet rs=c.executeQuery(); while(rs.next()) { String Stu=rs.getString("StuID"); String name=rs.getString("StuName"); String add=rs.getString("StuAddress"); System.out.println ("学号:"+" "+"姓名:"+" "+"地址"); System.out.println (Stu+" "+name+" "+add); } c.close(); } } |
D:改动数据的存储过程
创建存储过程:
create procedure ModPro
@StuID int,
@StuName varchar(10)
as
update 学生基本信息表 set StuName=@StuName where StuID=@StuID
运行存储过程:
exec ModPro 2,'四毛'
JAVA调用存储过程:
import java.sql.*; public class ProcedureTest { public static void main(String args[]) throws Exception { //载入驱动 DriverManager.registerDriver(new sun.jdbc.odbc.JdbcOdbcDriver()); //获得连接 Connection conn=DriverManager.getConnection("jdbc:odbc:mydata","sa",""); //创建存储过程的对象 CallableStatement c=conn.prepareCall("{call ModPro(?,?)}"); c.setInt(1,2); c.setString(2,"美女"); c.execute(); c=conn.prepareCall("{call selePro}"); ResultSet rs=c.executeQuery(); while(rs.next()) { String Stu=rs.getString("StuID"); String name=rs.getString("StuName"); String add=rs.getString("StuAddress"); System.out.println ("学号:"+" "+"姓名:"+" "+"地址"); System.out.println (Stu+" "+name+" "+add); } c.close(); } } |
E:查询数据的存储过程(模糊查询)
存储过程:
create procedure FindCusts
@cust varchar(10)
as
select customerid from orders where customerid
like '%'+@cust+'%'
运行:
execute FindCusts 'alfki'
在JAVA中调用:
import java.sql.*; public class ProcedureTest { public static void main(String args[]) throws Exception { //载入驱动 DriverManager.registerDriver(new sun.jdbc.odbc.JdbcOdbcDriver()); //获得连接 Connection conn=DriverManager.getConnection("jdbc:odbc:mydata","sa",""); //创建存储过程的对象 CallableStatement c=conn.prepareCall("{call FindCusts(?)}"); c.setString(1,"Tom"); ResultSet rs=c.executeQuery(); while(rs.next()) { String cust=rs.getString("customerid"); System.out.println (cust); } c.close(); } } |
F:添加数据的存储过程
存储过程:
create procedure InsertPro
@StuID int,
@StuName varchar(10),
@StuAddress varchar(20)
as
insert into 学生基本信息表 values(@StuID,@StuName,@StuAddress)
调用存储过程:
exec InsertPro 5,'555','555'
在JAVA中运行:
import java.sql.*; public class ProcedureTest { public static void main(String args[]) throws Exception { //载入驱动 DriverManager.registerDriver(new sun.jdbc.odbc.JdbcOdbcDriver()); //获得连接 Connection conn=DriverManager.getConnection("jdbc:odbc:mydata","sa",""); //创建存储过程的对象 CallableStatement c=conn.prepareCall("{call InsertPro(?,?,?)}"); c.setInt(1,6); c.setString(2,"Liu"); c.setString(3,"wuhan"); c.execute(); c=conn.prepareCall("{call selePro}"); ResultSet rs=c.executeQuery(); while(rs.next()) { String stuid=rs.getString("StuID"); String name=rs.getString("StuName"); String address=rs.getString("StuAddress"); System.out.println (stuid+" "+name+" "+address); } c.close(); } } |
G:在JAVA中创建存储过程 而且在JAVA中直接调用
import java.sql.*; public class ProcedureTest { public static void main(String args[]) throws Exception { //载入驱动 DriverManager.registerDriver(new sun.jdbc.odbc.JdbcOdbcDriver()); //获得连接 Connection conn=DriverManager.getConnection("jdbc:odbc:mydata","sa",""); Statement stmt=conn.createStatement(); //在JAVA中创建存储过程 stmt.executeUpdate("create procedure OOP as select * from 学生成绩表"); CallableStatement c=conn.prepareCall("{call OOP}"); ResultSet rs=c.executeQuery(); while(rs.next()) { String chinese=rs.getString("Chinese"); System.out.println (chinese); } conn.close(); } } |
English » | | | | | | | | |
Text-to-speech function is limited to 100 characters
为了建立冗余较小、结构合理的数据库,设计数据库时必须遵循一定的规则。在关系型数据库中这种规则就称为范式。范式是符合某一种设计要求的总结。要想设计一个结构合理的关系型数据库,必须满足一定的范式。
1.1、第一范式(1NF:每一列不可包含多个值)
所谓第一范式(1NF)是指数据库表的每一列都是不可分割的基本数据项,同一列中不能有多个值,即实体中的某个属性不能有多个值或者不能有重复的属性。如果出现重复的属性,就可能需要定义一个新的实体,新的实体由重复的属性构成,新实体与原实体之间为一对多关系。在第一范式(1NF)中表的每一行只包含一个实例的信息。
在任何一个关系数据库中,第一范式(1NF)是对关系模式的基本要求,不满足第一范式(1NF)的数据库就不是关系数据库。
1.2、第二范式(2NF:非主属性部分依赖于主关键字)
第二范式(2NF)是在第一范式(1NF)的基础上建立起来的,即满足第二范式(2NF)必须先满足第一范式(1NF)。第二范式(2NF)要求数据库表中的每个实例或行必须可以被唯一地区分。为实现区分通常需要为表加上一个列,以存储各个实例的唯一标识。
第二范式(2NF)要求实体的属性完全依赖于主关键字。所谓完全依赖是指不能存在仅依赖主关键字一部分的属性,如果存在,那么这个属性和主关键字的这一部分应该分离出来形成一个新的实体,新实体与原实体之间是一对多的关系。为实现区分通常需要为表加上一个列,以存储各个实例的唯一标识。简而言之,第二范式就是非主属性部分依赖于主关键字。
1.3、第三范式(3NF:属性不依赖于其它非主属性)
满足第三范式(3NF)必须先满足第二范式(2NF)。简而言之,第三范式(3NF)要求一个数据库表中不包含已在其它表中已包含的非主关键字信息。例如,存在一个部门信息表,其中每个部门有部门编号、部门名称、部门简介等信息。那么在员工信息表中列出部门编号后就不能再将部门名称、部门简介等与部门有关的信息再加入员工信息表中。如果不存在部门信息表,则根据第三范式(3NF)也应该构建它,否则就会有大量的数据冗余。简而言之,第三范式就是属性不依赖于其它非主属性。
1.4、反三范式(反3NF:为了性能,增加冗余)
3NF提出目的是为了降低冗余,减少不必要的存储,这对于存储设备昂贵的过去是很有必要的,但是随着存储设备的降价以及人们对性能的不断提高,又有人提出反三范式。
所谓反三范式就是为了性能,增加冗余。以部门信息表为例,每个部门有部门编号、部门名称、部门简介等信息,按照3NF的要求,为了避免冗余,我们在员工表中就不应该加入部门名称、部门简介等部门有关信息,带来的代价是每次都要查询两次数据库。反三范式允许我们冗余重要信息到员工表中,例如部门名称,这样我们每次取员工信息时就能直接取出部门名称,不需要查询两次数据库,提升了程序性能。
二、MYSQL优化整体思路
MYSQL优化首先应该定位问题,可能导致MYSQL低性能的原因有:业务逻辑过多的查询、表结构不合理、
sql语句优化以及硬件优化,从优化效果来看,这四个优化点的优化效果依次降低:理清业务逻辑能够帮助我们避免不必要的查询,合理设计表结构也能帮助我们少查询数据库。对于sql语句优化,我们可以先使用慢查询日志定位慢查询,然后针对该查询进行优化,最常见且最有效的优化范式就是增加合理的索引,这个在上篇博客已经讲解,本篇博客将讲解其他一些优化手段或者注意点。
2.1、谨慎使用TEXT/BLOB类型
当列类型是TEXT或者BLOB时,我们应该特别注意,因为当选择的字段有 text/blob 类型的时候,无法创建内存表,只能创建硬盘临时表,而硬盘临时表的性能比内存表的性能差,所以如果非要使用TEXT/BLOB类型,应该单独建表,不要把TEXT/BLOB类型与核心属性混合在一张表中。对此,做一个实验如下:
//创建数据表 create table t1 ( num int, intro text(1000) ); //插入数据 insert into t1 values (3,'this is USA') , (4,'China'); //查询临时表创建情况 //注意,这里Created_tmp_disk_tables=4,Created_tmp_tables=10 mysql> show status like '%tmp%'; +-------------------------+-------+ | Variable_name | Value | +-------------------------+-------+ | Created_tmp_disk_tables | 4 | | Created_tmp_files | 9 | | Created_tmp_tables | 10 | +-------------------------+-------+ //使用group by查询数据 mysql> select * from t1 group by num; +------+-------------+ | num | intro | +------+-------------+ | 3 | this is USA | | 4 | China | +------+-------------+ 2 rows in set (0.05 sec) //再次查询临时表创建情况 //现在,Created_tmp_disk_tables=5,Created_tmp_tables=11 mysql> show status like '%tmp%'; +-------------------------+-------+ | Variable_name | Value | +-------------------------+-------+ | Created_tmp_disk_tables | 5 | | Created_tmp_files | 9 | | Created_tmp_tables | 11 | +-------------------------+-------+ |
English » | | | | | | | | |
Text-to-speech function is limited to 100 characters
1.质量管理模块的建立
质量管理是在质量方面指挥和控制组织的协调的活动。当前卷烟加工企业质量管理的主要职能是为实现组织的质量方针和目标,制定完善的技术和管理标准,实施全过程的监视与测量,通过质量控制与改进,确保整个过程稳定受控。
在质量管理与MES整合过程中,首先在基于质量管理标准的基础上,在MES系统中分别建立了Iterspec、Unilab、SPC、报表四个功能模块(图1), 组成质量管理系统(QZ_MES),分别承担不同的功能。通过各功能模块与质量管理职能的衔接,以及各功能模块间的交互作用, 从而实现质量管理的闭环式管理。
2.质量管理功能模块设计
2.1技术标准
技术标准是为确保产品质量建立的规范信息, 是生产过程中共同遵守的技术依据。这些规范信息的录入、维护和输出,通过MES系统的Iterspec功能模块来实现,Iterspec功能模块包含了烟叶原料、辅助材料、过程产品以及成品的加工工艺参数、BOM和质量检验、考核标准等规范信息,这些信息随MES将ER P下达的订单分解后的生产工单传递至各生产工艺段,指导生产,并经录入(维护)、存储之后可反复调用。
2.2监视与测量
功能模块是质量检验人员录入检验原始数据的客户端,该模块包括原料、材料、制丝过程、包装与卷制、主流烟气、感官质量、卷烟成品入库判定全生产过程的质量检验内容。在生产中,系统根据预设的规则,自动触发检验请求, 由系统自动、半自动、人工三种方式实现质量检验原始数据的录入, 并依据检验数据自动进行结果判定、存储和输出。
2.3质量控制
通过计算过程能力指数, 评价工序过程加工能力, 对生产过程进行过程质量控制。SPC功能模块利用控制图的原理,结合抽样及检测方法,提供了Xba r-R、Xba r-S、U图、P图、C图等多种控制图,以便于依据不同的质量特性进行选择, 及时进行质量预警,排除生产过程异常因素的干扰,预防不合格品的发生。
2.4质量改进
质量管理模块最终将各功能模块的质量信息进行收集, 按照日期、人、机、料、工序等条件或复合条件自动生成报表, 进行存储和打印。同时,以饼图、柱状图、趋势图等统计分析工具,直观的反映质量控制状况, 一方面有利于发现存在的关键质量问题,实施质量改进,另一方面又能为质量改进前后效果进行验证, 有效促进质量攻关活动的开展。
3.质量管理模块实现的功能
3.1质量管理模块发挥了可存储性功能
质量管理模块提供了强大的信息存储的空间,能够将日常的技术标准变更信息、质量检验的原始数据、过程质量控制状况进行存放,便于历史数据的查询和质量问题的追溯, 减少了日常记录管理和手工模式查询操作的时间,节省了原始记录存放空间, 可以让质量管理人员腾出更多时间与空间从事其他
工作,提高了工作效率。
3.2质量管理模块实现了统计报表功能
为了便于掌握质量管理信息, 质量管理模块根据存储的大量数据、预先设置的计算公式,以及统计报表模板,自动生成多层次和多角度统计报表,将点状的质量数据连成了网状信息,并在厂内实现共享功能, 不同部门及不同岗位人员依据各自的权限设置,都能够通过浏览器进行查询、浏览与自身相关的质量信息, 提高了质量信息沟通的及时性和准确性。
3.3质量管理模块探索了统计分析工具的应用
MES系统是一个建立在
数据库基础之上的管理系统,其中容纳了大量的质量数据, 为了将这些数据转化为有用的质量信息,实现以准确的数据管理质量,为质量决策服务,在统计报表的基础上,探索性的应用了控制图、饼图、趋势图等统计分析工具,直观的反映生产过程质量控制现状,分析当前的主要质量问题,预防不合格品的发生,为质量改进提供依据。
4.质量管理模块实现的关键技术
质量检验模块以Simatic IT unilab为开发工具,以
Oracle作为后台数据库开发的C/S结构应用系统,应用程序通过Configuration配置后连接数据库。MES的工单启动时,西门子的生产建模工具PM(Production modeler)调用unilab的COM方法进行检验样本的自动创建。对于数据的自动采集,制丝检验数据利用西门子的Historial组件连接自动化控制系统完成实时数据采集, 卷包检验数据利用Simatic IT Uniconnect组件与综合
测试台连接采集物理检验指标数据。避免了手工录入数据的错误,减少了劳动量, 提高了工作效率。对于样本得分,unilab在后台利用VBA按interspec制定的考核标准计算出考核得分。C/S模式具有交互性强、存储模式安全、相应速度快等优点。
5.总结
通过对MES系统在质量管理应用中的研究,初步实现了质量规范信息的传递、质量检验、质量控制等质量管理职能,完善了质量管理手段,增强了质量管理的能力。同时,在应用过程中我们更加认识到,加强质量管理基础建设,完善质量管理制度,规范质量管理流程,提高MES系统运行与质量管理实际职能的集成能力,是确保MES系统与质量管理达到高效整合的关键
English » | | | | | | | | |
Text-to-speech function is limited to 100 characters
1.下载
直接进入hp官网下载。
1)点击“立即获取LoadRunner”
2)填个人信息,随便填就可以了,带*号必填
3)同意条款
4)有三个东西可以下载:HP LoadRunner 12 Community Edition、HP LoadRunner 12 community Edition Addtional Components、Hp LoadRunner tutorial。
HP LoadRunner 12 Community Edition,这个就是LoadRunner12了。
HP LoadRunner 12 community Edition Addtional Components是LoadRunner12的附加组件,具体什么用我也不知道。
Hp LoadRunner tutorial是LoadRunner教程,挺详细的可以下载学习。
2.安装
双击下载后的HP LoadRunner 12 Community Edition的安装包,就可以安装了。要是提示缺少Microsoft Visual C++ 2005 Redistributable Package可进入官网下载。
安装Microsoft Visual C++ 2005 Redistributable Package时出现找不到vcredist.msi时,参考
安装Microsoft Visual Studio 2005出现如下提示
找不到vcredist.msi?
方法1:
解压安装包 vcredist_x86.EXE,里面将包含 vcredist.msi
方法2:
使用方法1,提示不是有效的安装文件,可以用下面的地址下载一个vcredist.msi
English » | | | | | | | | |
Text-to-speech function is limited to 100 characters
因电脑上装了两人系统,导致我的JIRA服务不能和tomcat同时启动,让我弄了好久都不知道是啥原因,经过请教,总算得出原来是JIRA的Port和Tomcat的Port冲突。在
server.xml中修改即可。<Server port="8006" shutdown="SHUTDOWN">两个改成不一样就好了。装好后,记得要配置环境变量,这个跟配置tomcat是一样的。之后记得破解哦。如果要汉化的话,也有相关操作说明。
破解说明:
1.将atlassian-extras-2.2.2.jar 覆盖至%JIRA_HOME%/atlassian-jira/WEB-INF/lib/atlassian-extras-2.2.2.jar
2.将atlassian-extras-2.2.2.crack 覆盖至先将这个文件复制到%JIRA_HOME%/atlassian-jira/WEB-INF/classes下,然后把文件中的MaintenanceExpiryDate项修改到你想要的日期
重启Jira
JIRA汉化
1、用管理员登录,进入管理页面;
2、进入插件页面
3、进入install标签页
4、点击
5、 在弹出的对话框中选择中文插件文件(.jar)
6、“中文插件文件.jar”下载地址:
文件名:JIRA-5.0-language-pack-zh_CN.jar
7、系统会自动安装,并转换语言为中文。
English » | | | | | | | | |
Text-to-speech function is limited to 100 characters
你为什么要写
自动化测试?为什么该选择用人工测试而不是自动化?什么时候该做这样的选择呢?事实上,几乎所有的测试工程师早晚都要面对的问题就是是否选择自动化以及自动化测试的程度。如果你只打算执行一次测试,根本没有必要自动化。可是,如果你打算测试两次呢?这也不意味着你应该使用自动化。有些软件在发布之前或者在维护阶段,可能需要执行上百次,上千次,甚至百万次的测试。有些因素有助于在具体环境下 准确地评估自动化的益处。如下是其中几个需要考量的因素:
投入
确定创建自动化测试的投资回报率(ROI--Return On Investment)的第一步是确定要花费的投入和成本。 有些种类的产品或功能的自动化很简单,而其他的自动化却不可避免得很麻烦。例如,应用程序编程接口(API--Application Programming Interface)测试,以及别的通过编程对象的方式 展现给用户的
功能测试,对其自动化往往都能够直截了当。而在另一方面,用户界面(UI--User Interface)的自动化测试常会遇到问题而需要花费更多的精力。----注---需要考量自动化的实施成本,难度太大的自动化不值得采用。
测试的生命期
一个自动化测试在变得无用之前将会运行多少次?对测试的长期价值的评估是决定是否对某个特定的场景或者
测试用例实现自动化的考量的一部分。要考虑被测试的产品本身的使用寿命和产品开发周期长度。对于短期内就要发布而且将来不打算更新的产品,和对于两年后要发布将来也会有多次更新发布的产品,自动化的选择必须是不一样的。----注---短期内即可结束且后期不再多次迭代的软件项目,自动化可不必采用。软件周期较长,会经历多次迭代过程,自动化对于后期的回归测试会很有帮助。
价值
要考虑自动化测试在其生命周期内的价值。有些测试人员说测试用例的价值是找到缺陷,但是很多自动化测试所找到的缺陷是在测试第一次运行时或者在写自动化测试时发现的。当缺陷被修复以后,这些测试成为了回归测试——确认最近的改动不会导致以前能够正常运行的功能停止
工作。很多自动化测试技术通过改变测试用的数据,或者改变每次测试运行路径的方法,从而在测试的生命期中继续找到缺陷。对一个生命周期很长的产品来说,不断增长的回归测试套件有很大的优势:随着底层软件功能越来越复杂,存在大量的能确认以前工作的功能能够继续工作的测试是极为有用的 。----注---对于后期需要多次迭代,或者项目完成后需要长期维护并进行版本更新的项目,自动化的实施有很大价值,便于后期的回归验证。
切入点
我目睹的许多成功的测试自动化项目都是测试团队从最开始的时候就参与了。代码写到尾声或者完成之后才开始想到加入自动化测试的项目通常都是失败的。----注---测试团队什么时候能参与项目的自动化测试过程中、项目时间安排是否允许加入自动化实施过程、测试人员的工作负载是否允许、人力资源的投入多少等都可能影响测试人员的自动化实施工作及效果。
准确性
好的自动化测试在每次运行后会报告准确结果。企业管理层对自动化测试最大的抱怨之一是自动化测试中误报的数量。误报是指测试报告中的测试失败是由测试本身的某些问题造成的,与产品无关。项目的有些领域(例如经常变化的用户界面组件)难以用自动化测试分析,且较容易产生误报。 ----注---测试团队的自动化实施是否确定能达到预期的要求和效果、是否存在较大的技术难点和障碍等问题应该在确定是否实施自动化时加以考虑,否则有可能达不到预期的自动化测试效果,反而浪费了人力和时间。
English » | | | | | | | | |
Text-to-speech function is limited to 100 characters