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