qileilove

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

Python简单速度测试

 刚开始接触python,对其飘逸的语法所“震撼”,与其说是在写代码,还不如说是在说一段代码。
  刚开始学吧,写个简单的程序练一下手吧,就写了一个归并排序的算法
def merge(num_list,l_b,l_e,r_b,r_e):
temp=[]
begin=l_b
while l_b<=l_e and r_b<=r_e:
if num_list[l_b] < num_list[r_b]:
temp.append(num_list[l_b])
l_b=l_b+1
else:
temp.append(num_list[r_b])
r_b=r_b+1
while l_b<=l_e:
temp.append(num_list[l_b])
l_b=l_b+1
while r_b<=r_e:
temp.append(num_list[r_b])
r_b=r_b+1
for index in range(0,len(temp)):
num_list[begin+index]=temp[index]
def mergeSort(num_list,b,e):
if b<e:
mid=int((b+e)/2)
mergeSort(num_list,b,mid)
mergeSort(num_list,mid+1,e)
l_b=b
l_e=mid
r_b=mid+1
r_e=e
merge(num_list,l_b,l_e,r_b,r_e)
def main():
num_list=[5,4,1,7,9,8,6,5,4,7]
mergeSort(num_list)
if __name__=="__main__":
main()
 写完感觉还不错,于是乎上网看看别人用python咋写的。果然出乎我的预料,我仿造其格式,写了一下
def mergeSort(num_list):
if len(num_list)<=1: return num_list
mid=int(len(num_list)/2)
return merge(mergeSort(num_list[:mid]),mergeSort(num_list[mid:]))
def merge(l_list,r_list):
temp_list=[]
while l_list and r_list:
temp_list.append(l_list.pop(0)) if l_list[0]<=r_list[0] else temp_list.append(r_list.pop(0))
return temp_list+l_list+r_list
  短小精悍,刚开始我怀疑 这么写的效率有没有问题啊。因为我原来的算法在函数之间不用传参数,就简单测试一下,再次出乎的预料,通过跑10w次,我原来的算法接近5s,而这个算法不到4秒,好吧,以后还是要使用python的思维写python代码,不过真的很优雅。

posted @ 2014-06-04 10:57 顺其自然EVO 阅读(298) | 评论 (0)编辑 收藏

识别访问端的操作系统

//识别访问端的操作系统
function PDD() {
//平台、设备和操作系统
var system = {
win: false,
mac: false,
xll: false
};
//检测平台
var p = navigator.platform;
system.win = p.indexOf("Win") == 0;
system.mac = p.indexOf("Mac") == 0;
system.x11 = (p == "X11") || (p.indexOf("Linux") == 0);
//跳转语句
alert(p);
if (system.win) {
alert("win");
} else if (system.mac) {
alert("mac");
} else if (system.x11) {
alert("X11 Or Linux");
} else {
alert("android");
}
if (system.win || system.mac || system.xll) {
} else {
window.location.href = "android.aspx";
}
}

posted @ 2014-06-04 10:50 顺其自然EVO 阅读(182) | 评论 (0)编辑 收藏

测试之路1—熟悉使用Junit

 测试有很多种,不仅仅是手动测试,往往还要用到所谓“自动化测试”,其实我的理解也就是自己写个程序去测试。
  最近在公司实习,用到自动化测试,因为程序都是用java编写的,所以我也用java编写单元测试程序。一般都在java中已经导入junit
  import junit.framework.TestCase;
  但是我看老大给我的例程都没与引入这个类,而是引入了
<pre name="code" class="java">import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.*;
  然后,老大叫我根据他给的例程自己去创建单元测试程序,然后运行,创建实际的任务。
  创建任务,看似不是很难,但仍要花点时间去了解Junit是怎么样的,所以我需要先了解一下。
  首先这也是一个类,和其他java的类一样,无非引入了Junit的类,然后我就发现了这个类并没有显式的写出自己的构造方法,而是只有一些看似比较常见对于字符串操作的方法。
  唯一不同的是它在每一个方法前都有一个注解。就和前面import的东西一样,有@after,@Before,@Test。
  那么这些注解就是单元测试的关键了:
  你要在方法的前面使用 @Test标注,以表明这是一个测试方法;用@Before来标注它“在任何一个测试执行之前必须执行的代码 ;在这种测试函数的前面加上@Ignore 标注,这个标注的含义就是 “ 某些方法尚未完成,暂不参与此次测试;
  那么最最简单实现单元测试花其实只要做两步就可以测试程序了:初始化,测试。而测试的代码放在@Test标注的方法内即可。如图所示,就是一段单元测试的代码:
public void creatAAC_Task() throws DocumentException {
//      String[] sampleratelist = { "24000", "32000", "44100", "48000" };
String[] sampleratelist = { "24000" };
for (int j = 0; j < sampleratelist.length; j++) {
TaskPara model = new TaskPara();
model.setTaskName("AAC_" + sampleratelist[j]);
//model.setVideoCodec("h264");
model.setVideoProfile("Main");
model.setAudioCodec("aac");
//model.setAudioProfile("LC");
model.setSamplerate(sampleratelist[j]);
String content = taskcaseAPIs.createTaskXML(model);
String xmlString = arcvideo.addNewTask(content);
assertTrue(!xmlString.contains("<errors>"));
//compare(e://xml2.xml);
String taskID = taskAPIs.getTaskID(xmlString);
String delXML = arcvideo.deleteTask(taskID);
assertTrue(delXML.contains("<success></success>"));
}
}
  而运行这个方法也不需要直接用main函数作为入口地址,只需要选择该方法,点击右键Run as->Junit test 或Debug as->Junit test。即可运行该单元测试方法,运行的结果是直接在服务器上创建一个任务,如下图所示:
  那么任务就已经被创建好了。而任务的名称就是方法里输出任务的字符串。
  这就是一个简单的单元测试。

posted @ 2014-06-04 10:50 顺其自然EVO 阅读(197) | 评论 (0)编辑 收藏

SQL Server 监控统计阻塞脚本信息

数据库产生阻塞(Blocking)的本质原因 :SQL语句连续持有锁的时间过长 ,数目过多, 粒度过大。阻塞是事务隔离带来的副作用,它是不可避免的,而且是一个数据库系统常见的现象。 但是阻塞的时间和出现频率要控制在一定的范围内,阻塞持续的时间过长或阻塞出现过多(过于频繁),就会对数据库性能产生严重的影响。
  很多时候,DBA需要知道数据库在出现性能问题时,有没有发生阻塞? 什么时候开始的?发生在那个数据库上? 阻塞发生在那些SQL语句之间? 阻塞的时间有多长? 阻塞发生的频率? 阻塞有关的连接是从那些客户端应用发送来的?.......
  如果我们能够知道这些具体信息,我们就能迅速定位问题,分析阻塞产生的原因,  从而找出出现性能问题的根本原因,并根据具体原因给出相应的解决方案(索引调整、优化SQL语句等)。
  查看阻塞的方法比较多, 我在这篇博客MS SQL 日常维护管理常用脚本(二)里面提到查看阻塞的一些方法:
  方法1:查看那个引起阻塞,查看blk不为0的记录,如果存在阻塞进程,则是该阻塞进程的会话 ID。否则该列为零。
  EXEC sp_who active
  方法2:查看那个引起阻塞,查看字段BlkBy,这个能够得到比sp_who更多的信息。
  EXEC sp_who2 active
  方法3:sp_lock 系统存储过程,报告有关锁的信息,但是不方便定位问题
  方法4:sp_who_lock存储过程
  方法5:右键服务器-选择“活动和监视器”,查看进程选项。注意“任务状态”字段。
  方法6:右键服务名称-选择报表-标准报表-活动-所有正在阻塞的事务。
  但是上面方法,例如像sp_who、 sp_who2,sp_who_lock等,都有或多或少的缺点:例如不能查看阻塞和被阻塞的SQL语句。不能从查看一段时间内阻塞发生的情况等;没有显示阻塞的时间....... 我们要实现下面功能:
  1:  查看那个会话阻塞了那个会话
  2:阻塞会话和被阻塞会话正在执行的SQL语句
  3:被阻塞了多长时间
  4:像客户端IP、Proagram_Name之类信息
  5:阻塞发生的时间点
  6:阻塞发生的频率
  7:如果需要,应该通知相关开发人员,DBA不能啥事情都包揽是吧,那不还得累死,总得让开发人员员参与进来优化(有些问题就该他们解决),多了解一些系统运行的具体情况,有利于他们认识问题、解决问题。
  8:需要的时候开启这项功能,不需要关闭这项功能
  于是为了满足上述功能,有了下面SQL 语句
SELECT wt.blocking_session_id                  AS BlockingSessesionId
,sp.program_name                         AS ProgramName
,COALESCE(sp.LOGINAME, sp.nt_username)   AS HostName
,ec1.client_net_address                  AS ClientIpAddress
,db.name                                 AS DatabaseName
,wt.wait_type                            AS WaitType
,ec1.connect_time                        AS BlockingStartTime
,wt.WAIT_DURATION_MS/1000                AS WaitDuration
,ec1.session_id                          AS BlockedSessionId
,h1.TEXT                                 AS BlockedSQLText
,h2.TEXT                                 AS BlockingSQLText
FROM sys.dm_tran_locks AS tl
INNER JOIN sys.databases db
ON db.database_id = tl.resource_database_id
INNER JOIN sys.dm_os_waiting_tasks AS wt
ON tl.lock_owner_address = wt.resource_address
INNER JOIN sys.dm_exec_connections ec1
ON ec1.session_id = tl.request_session_id
INNER JOIN sys.dm_exec_connections ec2
ON ec2.session_id = wt.blocking_session_id
LEFT OUTER JOIN master.dbo.sysprocesses sp
ON SP.spid = wt.blocking_session_id
CROSS APPLY sys.dm_exec_sql_text(ec1.most_recent_sql_handle) AS h1
CROSS APPLY sys.dm_exec_sql_text(ec2.most_recent_sql_handle) AS h2
 我们做一个测试例子来验证一下
  1:打开第一会话窗口1,执行下面语句
USE DBMonitor;
GO
BEGIN TRANSACTION
SELECT * FROM dbo.TEST(TABLOCKX);
--COMMIT TRANSACTION;
  2:打开第二个会话窗口2,执行下面语句
  USE DBMonitor;
  GO
  SELECT * FROM dbo.TEST
  3:打开第三个会话窗口3,执行下面语句
SELECT wt.blocking_session_id                  AS BlockingSessesionId
,sp.program_name                         AS ProgramName
,COALESCE(sp.LOGINAME, sp.nt_username)   AS HostName
,ec1.client_net_address                  AS ClientIpAddress
,db.name                                 AS DatabaseName
,wt.wait_type                            AS WaitType
,ec1.connect_time                        AS BlockingStartTime
,wt.WAIT_DURATION_MS/1000                AS WaitDuration
,ec1.session_id                          AS BlockedSessionId
,h1.TEXT                                 AS BlockedSQLText
,h2.TEXT                                 AS BlockingSQLText
FROM sys.dm_tran_locks AS tl
INNER JOIN sys.databases db
ON db.database_id = tl.resource_database_id
INNER JOIN sys.dm_os_waiting_tasks AS wt
ON tl.lock_owner_address = wt.resource_address
INNER JOIN sys.dm_exec_connections ec1
ON ec1.session_id = tl.request_session_id
INNER JOIN sys.dm_exec_connections ec2
ON ec2.session_id = wt.blocking_session_id
LEFT OUTER JOIN master.dbo.sysprocesses sp
ON SP.spid = wt.blocking_session_id
CROSS APPLY sys.dm_exec_sql_text(ec1.most_recent_sql_handle) AS h1
CROSS APPLY sys.dm_exec_sql_text(ec2.most_recent_sql_handle) AS h2
  如下图所,我们可以看到阻塞其它会话以及被阻塞会话的信息,如下所示
  现在上面SQL已经基本实现了查看阻塞具体信息的功能,但是现在又有几个问题:
  1:上面SQL脚本只适合已经出现阻塞情况下查看阻塞信息,如果没有出现阻塞情况,我总不能傻傻的一直在哪里点击执行吧,因为阻塞这种情况有可能在那段时间都不会出现,只会在特定的时间段出现。
  2:我想了解一段时间内数据库出现的阻塞情况,那么需要将阻塞信息保留下来。
  3:有时候忙不过来,我想将这些具体阻塞信息发送给相关开发人员,让他们了解具体情况。
  于是我想通过一个存储过程来实现这方面功能,通过设置参数@OutType,默认为输出阻塞会话信息,当参数为"Table" 时,将阻塞信息写入数据库表,如果参数为 "Email"表示将阻塞信息通过邮件发送开发人员。
  正好这段时间,我在YourSQLDba上扩展一些功能,于是我将这个存储过程放置在YouSQLDba数据库中。
USE [YourSQLDba]
GO
IF NOT EXISTS(SELECT * FROM sys.objects WHERE object_id=OBJECT_ID(N'[Maint].[BlockingSQLHistory]') AND type='U')
BEGIN
CREATE TABLE Maint.BlockingSQLHistory
(
RecordTime                        DATETIME           ,
DatabaseName                      SYSNAME            ,
BlockingSessesionId               SMALLINT           ,
ProgramName                       NCHAR(128)         ,
UserName                          NCHAR(256)         ,
ClientIpAddress                   VARCHAR(48)        ,
WaitType                          NCHAR(60)          ,
BlockingStartTime                 DATETIME           ,
WaitDuration                      BIGINT             ,
BlockedSessionId                  INT                ,
BlockedSQLText                    NVARCHAR(MAX)      ,
BlockingSQLText                   NVARCHAR(MAX)      ,
CONSTRAINT PK_BlockingSQLHistory  PRIMARY KEY(RecordTime)
)
END
GO
  存储过程如下所示:
USE [YourSQLDba]
GO
IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[Maint].[sp_who_blocking]') AND type in (N'P', N'PC'))
DROP PROCEDURE [Maint].[sp_who_blocking]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
--==================================================================================================================
--        ProcedureName         :            [Maint].[sp_who_blocking]
--        Author                :            Kerry    http://www.cnblogs.com/kerrycode/
--        CreateDate            :            2014-04-23
--        Description           :            监控数据库阻塞情况,显示阻塞会话信息或收集阻塞会话信息或发送告警邮件
/******************************************************************************************************************
Parameters                   :                                    参数说明
********************************************************************************************************************
@OutType         :            默认为输出阻塞会话信息,"Table", "Email"分别表示将阻塞信息写入表或邮件发送
@EmailSubject    :            邮件主题.默认为Sql Blocking Alert,一般指定,例如“ServerName Sql Blocking Alert"
@ProfileName     :            @profile_name 默认值为YourSQLDba_EmailProfile
@RecipientsLst   :            收件人列表
********************************************************************************************************************
Modified Date    Modified User     Version                 Modified Reason
********************************************************************************************************************
2014-04-23             Kerry         V01.00.00         新建存储过程[Maint].[sp_who_blocking]
*******************************************************************************************************************/
--==================================================================================================================
CREATE PROCEDURE [Maint].[sp_who_blocking]
(
@OutType
VARCHAR(8) ='Default'                  ,
@EmailSubject
VARCHAR(120)='Sql Blocking Alert'      ,
@ProfileName
sysname='YourSQLDba_EmailProfile'      ,
@RecipientsLst
VARCHAR(MAX) = NULL
)
AS
BEGIN
SET NOCOUNT ON;
DECLARE @HtmlContent  NVARCHAR(MAX) ;
IF @OutType NOT IN ('Default', 'Table','Email')
BEGIN
PRINT 'The parameter @OutType is not correct,please check it';
return;
END
IF @OutType ='Default'
BEGIN
SELECT db.name                                 AS DatabaseName
,wt.blocking_session_id                  AS BlockingSessesionId
,sp.program_name                         AS ProgramName
,COALESCE(sp.LOGINAME, sp.nt_username)   AS UserName
,ec1.client_net_address                  AS ClientIpAddress
,wt.wait_type                            AS WaitType
,ec1.connect_time                        AS BlockingStartTime
,wt.WAIT_DURATION_MS/1000                AS WaitDuration
,ec1.session_id                          AS BlockedSessionId
,h1.TEXT                                 AS BlockedSQLText
,h2.TEXT                                 AS BlockingSQLText
FROM sys.dm_tran_locks AS tl
INNER JOIN sys.databases db
ON db.database_id = tl.resource_database_id
INNER JOIN sys.dm_os_waiting_tasks AS wt
ON tl.lock_owner_address = wt.resource_address
INNER JOIN sys.dm_exec_connections ec1
ON ec1.session_id = tl.request_session_id
INNER JOIN sys.dm_exec_connections ec2
ON ec2.session_id = wt.blocking_session_id
LEFT OUTER JOIN master.dbo.sysprocesses sp
ON SP.spid = wt.blocking_session_id
CROSS APPLY sys.dm_exec_sql_text(ec1.most_recent_sql_handle) AS h1
CROSS APPLY sys.dm_exec_sql_text(ec2.most_recent_sql_handle) AS h2;
END
ELSE IF @OutType='Table'
BEGIN
INSERT INTO [Maint].[BlockingSQLHistory]
SELECT GETDATE()                               AS RecordTime
,db.name                                 AS DatabaseName
,wt.blocking_session_id                  AS BlockingSessesionId
,sp.program_name                         AS ProgramName
,COALESCE(sp.LOGINAME, sp.nt_username)   AS UserName
,ec1.client_net_address                  AS ClientIpAddress
,wt.wait_type                            AS WaitType
,ec1.connect_time                        AS BlockingStartTime
,wt.WAIT_DURATION_MS/1000                AS WaitDuration
,ec1.session_id                          AS BlockedSessionId
,h1.TEXT                                 AS BlockedSQLText
,h2.TEXT                                 AS BlockingSQLText
FROM sys.dm_tran_locks AS tl
INNER JOIN sys.databases db
ON db.database_id = tl.resource_database_id
INNER JOIN sys.dm_os_waiting_tasks AS wt
ON tl.lock_owner_address = wt.resource_address
INNER JOIN sys.dm_exec_connections ec1
ON ec1.session_id = tl.request_session_id
INNER JOIN sys.dm_exec_connections ec2
ON ec2.session_id = wt.blocking_session_id
LEFT OUTER JOIN master.dbo.sysprocesses sp
ON SP.spid = wt.blocking_session_id
CROSS APPLY sys.dm_exec_sql_text(ec1.most_recent_sql_handle) AS h1
CROSS APPLY sys.dm_exec_sql_text(ec2.most_recent_sql_handle) AS h2;
END
ELSE IF @OutType='Email'
BEGIN
SET @HtmlContent =
N'<head>'
+ N'<style type="text/css">h2, body {font-family: Arial, verdana;} table{font-size:11px; border-collapse:collapse;} td{background-color:#F1F1F1; border:1px solid black; padding:3px;} th{background-color:#99CCFF;}</style>'
+ N'<table border="1">'
+ N'<tr>
<th>DatabaseName</th>
<th>BlockingSessesionId</th>
<th>ProgramName</th>
<th>UserName</th>
<th>ClientIpAddress</th>
<th>WaitType</th>
<th>BlockingStartTime</th>
<th>WaitDuration</th>
<th>BlockedSessionId</th>
<th>BlockedSQLText</th>
<th>BlockingSQLText</th>
</tr>' +
CAST (
(SELECT db.name                                  AS TD, ''
,wt.blocking_session_id                   AS TD, ''
,sp.program_name                          AS TD, ''
,COALESCE(sp.LOGINAME, sp.nt_username)    AS TD, ''
,ec1.client_net_address                   AS TD, ''
,wt.wait_type                             AS TD, ''
,ec1.connect_time                         AS TD, ''
,wt.WAIT_DURATION_MS/1000                 AS TD, ''
,ec1.session_id                           AS TD, ''
,h1.TEXT                                  AS TD, ''
,h2.TEXT                                  AS TD, ''
FROM sys.dm_tran_locks AS tl
INNER JOIN sys.databases db
ON db.database_id = tl.resource_database_id
INNER JOIN sys.dm_os_waiting_tasks AS wt
ON tl.lock_owner_address = wt.resource_address
INNER JOIN sys.dm_exec_connections ec1
ON ec1.session_id = tl.request_session_id
INNER JOIN sys.dm_exec_connections ec2
ON ec2.session_id = wt.blocking_session_id
LEFT OUTER JOIN master.dbo.sysprocesses sp
ON SP.spid = wt.blocking_session_id
CROSS APPLY sys.dm_exec_sql_text(ec1.most_recent_sql_handle) AS h1
CROSS APPLY sys.dm_exec_sql_text(ec2.most_recent_sql_handle) AS h2
FOR XML PATH('tr'), TYPE
) AS NVARCHAR(MAX) ) +
N'</table>'
IF @HtmlContent  IS NOT NULL
BEGIN
EXEC msdb.dbo.sp_send_dbmail
@profile_name = @ProfileName    ,
@recipients   = @RecipientsLst    ,
@subject      = @EmailSubject    ,
@body         = @HtmlContent    ,
@body_format  = 'HTML' ;
END
END
END
GO
  最后在数据库新建一个作业,调用该存储过程,然后在某段时间启用作业监控数据库的阻塞情况,作业的执行频率是个比较难以定夺的头痛问题,具体要根据系统情况来决定,我习惯2分钟执行一次。
  最后,这个脚本还有一个问题,如果阻塞或被阻塞的SQL语句是某个存储过程里面的一段脚本,显示的SQL是整个存储过程,而不是正在执行的SQL语句,目前还没有想到好的方法解决这个问题。我目前手工去查看阻塞情况,如果非要查看存储过程里面被阻塞的正在执行的SQL,一般结合下面SQL语句查看(输入阻塞或被阻塞会话ID替代@sessionid)
SELECT   [Spid] = er.session_id
,[ecid]
,[Database] = DB_NAME(sp.dbid)
,[Start_Time]
,[SessionRunTime]    = datediff(SECOND, start_time,getdate())
,[SqlRunTime]=     RIGHT(convert(varchar,
dateadd(ms, datediff(ms, sp.last_batch, getdate()), '1900-01-01'),
121), 12)
,[HostName]
,[Users]=COALESCE(sp.LOGINAME, sp.nt_username)
,[Status] = er.status
,[WaitType] = er.wait_type
,[Waitime] = er.wait_time/1000
,[Individual Query] = SUBSTRING(qt.text, er.statement_start_offset / 2,
( CASE WHEN er.statement_end_offset = -1
THEN LEN(CONVERT(NVARCHAR(MAX), qt.text))
* 2
ELSE er.statement_end_offset
END - er.statement_start_offset ) / 2)
,[Parent Query] = qt.text
,[PROGRAM_NAME] = program_name
FROM    sys.dm_exec_requests er
INNER JOIN sys.sysprocesses sp ON er.session_id = sp.spid
CROSS APPLY sys.dm_exec_sql_text(er.sql_handle) AS qt
WHERE   session_Id = @sessionid;
English »
 
Text-to-speech function is limited to 100 characters

posted @ 2014-06-04 10:49 顺其自然EVO 阅读(349) | 评论 (0)编辑 收藏

Redis安装及简单测试

 摘要: Redis是目前业界非常受到欢迎的一个内存数据库,一般用作系统的中间缓存系统,用以提升整体商业系统的吞吐量和响应速度。本文将简要介绍安装的主要过程以及给出一个简要的测试代码。
  1.  系统环境和版本说明
  操作系统选用Ubuntu 14.04, Redis的版本选取目前的最新稳定版本2.8.9. 客户端选用了Redis的Java版本jedis 2.4.2.
  2.  Redis的安装步骤
  a. 下载Redis的安装包
  wget http://download.redis.io/releases/redis-2.8.9.tar.gz
  b. 在目录下,解压按照包,生成新的目录redis-2.8.9
  tar xvfz redis-2.8.9.tar.gz
  c.  进入解压之后的目录,进行编译
  cd redis-2.8.9
  sudo make
  说明: 如果没有明显的错误,则表示编译成功
  d.  安装
  sudo make install
  说明: 一般情况下,在Ubuntu系统中,都是需要使用sudo提升权限的

 e.   在安装成功之后,可以运行测试,确认Redis的功能是否正常
  sudo make test
  f.  启动Redis服务
  查找Redis安装的目录:  find /  -name 'redis*'  ------ 在根目录下查找名称中含有redis的文件
  经过查找,发现Redis被安装到了/usr/local/bin/目录下。
  接下来,启动Redis服务:
  /usr/local/bin/redis-server
  说明: 从以上的截图中,可以发现启动的端口为缺省的6379. 用户可以在启动的时候,指定具体的配置文件,并在其中指定启动的端口。
  g.  查看Redis进程
  ps -ef | grep redis
  说明: 如果可以看到进程,说明启动正常。  3.   简单的Redis测试程序
  读者可以自行创建Eclipse项目,引入jedis的客户端包,测试程序如下:
public class RedisTest {
private Jedis jedis = null;
private String key1 = "key1";
private String key2 = "key2";
public RedisTest() {
jedis = new Jedis("localhost");
}
public static void main(String[] args) {
RedisTest redisTest = new RedisTest();
redisTest.isReachable();
redisTest.testData();
redisTest.delData();
redisTest.testExpire();
}
public boolean isReachable() {
boolean isReached = true;
try {
jedis.connect();
jedis.ping();
// jedis.quit();
} catch (JedisConnectionException e) {
e.printStackTrace();
isReached = false;
}
System.out
.println("The current Redis Server is Reachable:" + isReached);
return isReached;
}
public void testData() {
jedis.set("key1", "data1");
System.out.println("Check status of data existing:"
+ jedis.exists(key1));
System.out.println("Get Data key1:" + jedis.get("key1"));
long s = jedis.sadd(key2, "data2");
System.out.println("Add key2 Data:" + jedis.scard(key2)
+ " with status " + s);
}
public void delData() {
long count = jedis.del(key1);
System.out.println("Get Data Key1 after it is deleted:"
+ jedis.get(key1));
}
public void testExpire() {
long count = jedis.expire(key2, 5);
try {
Thread.currentThread().sleep(6000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (jedis.exists(key2)) {
System.out
.println("Get Key2 in Expire Action:" + jedis.scard(key2));
} else {
System.out.println("Key2 is expired with value:"
+ jedis.scard(key2));
}
}
}
public class RedisTest {
private Jedis jedis = null;
private String key1 = "key1";
private String key2 = "key2";
public RedisTest() {
jedis = new Jedis("localhost");
}
public static void main(String[] args) {
RedisTest redisTest = new RedisTest();
redisTest.isReachable();
redisTest.testData();
redisTest.delData();
redisTest.testExpire();
}
public boolean isReachable() {
boolean isReached = true;
try {
jedis.connect();
jedis.ping();
// jedis.quit();
} catch (JedisConnectionException e) {
e.printStackTrace();
isReached = false;
}
System.out
.println("The current Redis Server is Reachable:" + isReached);
return isReached;
}
public void testData() {
jedis.set("key1", "data1");
System.out.println("Check status of data existing:"
+ jedis.exists(key1));
System.out.println("Get Data key1:" + jedis.get("key1"));
long s = jedis.sadd(key2, "data2");
System.out.println("Add key2 Data:" + jedis.scard(key2)
+ " with status " + s);
}
public void delData() {
long count = jedis.del(key1);
System.out.println("Get Data Key1 after it is deleted:"
+ jedis.get(key1));
}
public void testExpire() {
long count = jedis.expire(key2, 5);
try {
Thread.currentThread().sleep(6000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (jedis.exists(key2)) {
System.out
.println("Get Key2 in Expire Action:" + jedis.scard(key2));
} else {
System.out.println("Key2 is expired with value:"
+ jedis.scard(key2));
}
}
}
  4. 总结
  本文简要直观介绍了Redis的安装和部署,并基于jedis的简单测试程序,说明了Redis的基本使用情况,更多的内容,可以查阅相关资料。

posted @ 2014-06-03 09:59 顺其自然EVO 阅读(577) | 评论 (0)编辑 收藏

JSP网页防止sql注入攻击

  SQL注入攻击指的是通过构建特殊的输入作为参数传入Web应用程序,而这些输入大都是SQL语法里的一些组合,通过执行SQL语句进而执行攻击者所要的操作,其主要原因是程序没有细致地过滤用户输入的数据,致使非法数据侵入系统。
  prepareStatement方法是防止sql注入的简单有效手段
  preparedStatement和statement的区别
  1、preparedStatement是statement的子方法
  2、preparedStatement可以防止sql注入的问题
  3、preparedStatement它可以对它所代表的sql语句进行预编译,以减轻服务器压力
  实例如下 
public User find(String username, String password) {
Connection conn = null;
PreparedStatement st = null;
ResultSet rs = null;
try{
conn = JdbcUtils.getConnection();
String sql = "select * from users where username=? and password=?";
st = conn.prepareStatement(sql);
st.setString(1, username);
st.setString(2, password);
rs = st.executeQuery(); //
if(rs.next()){
User user = new User();
user.setId(rs.getString("id"));
user.setUsername(rs.getString("username"));
user.setPassword(rs.getString("password"));
user.setEmail(rs.getString("email"));
user.setBirthday(rs.getDate("birthday"));
return user;
}
return null;
}catch (Exception e) {
throw new DaoException(e);
}finally{
JdbcUtils.release(conn, st, rs);
}

posted @ 2014-06-03 09:58 顺其自然EVO 阅读(412) | 评论 (1)编辑 收藏

SQL数据排序与分组

一、为什么要对数据进行分组
  数据分组:是按照逻辑次序把具有重复值的字段进行合并。
  二、GROUP BY子句
  语法:
SELECT column1,column2
FROM table1,table2
WHERE conditions
GROUP BY column1,column2
ORDER BY column1,column2;
  1、分组函数
  典型的分组函数—也就是用于GROUP BY子句对数据进行划分的函数—包括AVG、MAX、MIN、SUM、COUNT。
  2、对选中的数据进行分组
  数据分组是个简单的过程。被选中的字段(查询中SELECT之后的字段列表)才能在GROUP BY子句里引用;如果字段在SELECT语句里找不到,就不能用于GROUP BY子句。
  注:在对数据进行分组时,分组字段的次序不一定要与SELECT子句里字段次序相同。
  3、创建分组和使用汇总函数
  SELECT语句在使用GROUP BY子句时必须满足一定条件。特别是被选中的字段必须出现在GROUP BY子句里,除了汇总函数。
  注:具体数值在排序时位于NULL值之前,字符型在排序时位于NULL值之后。
  4、以整数代表字段名称
  像ORDER BY子句一样,GROUP BY子句里也可以用整数代表字段名称。
  三、GROUP BY和ORDER BY
  ORDER BY子句专门用于对查询得到的数据进行排序,GROUP BY子句也把查询得到的数据排序为适当分组的数据,因此,GROUP BY子句也可以像ORDER BY子句那样用于数据排序。
  使用GROUP BY子句实现排序操作的区别与缺点:
  1、所有被选中的、非汇总函数的字段必须列在GROUP BY子句里;
  2、除非需要使用汇总函数,否则使用GROUP BY子句进行排序通常是没有必要的。
  四、CUBE和ROLLUP语句
  ROLLUP语法:
  GROUP BY ROLLUP(ordered column list of grouping sets)
  MySQL ROLLUP语法:
  GROUP BY order column list of grouping sets WITH ROLLUP
  ROLLUP语句的工作方式:
  1、在完成了基本的分组数据汇总以后,
  2、按照从右向左的顺序,每次去掉字段列表中的最后一个字段,再对剩余的字段进行分组统计,并将获得的小计结果插入返回表中,被去掉的字段位置使用NULL填充。
  3、最后,再对全表进行一次统计,所有的字段位置均使用NULL填充。
  CUBE语法:
  GROUP BY CUBE(column list of grouping sets)
  CUBE语句在SQL Server和Oracle中都可以使用,MySQL尚不支持该语句。
  CUBE语句的工作方式:
  1、它对分组列表中的所有字段进行排列组合,并根据每一种组合结果,分别进行统计汇总。    2、最后,CUBE语句也会对全表进行统计。
  五、HAVING子句
  HAVING子句必须跟在GROUP BY子句之后,在ORDER BY子句之前。
语法:
SELECT column1,column2
FROM table1,table2
WHERE contidions
GROUP BY column1,column2
HAVING conditions
ORDER BY column1,column2;

posted @ 2014-06-03 09:56 顺其自然EVO 阅读(213) | 评论 (0)编辑 收藏

Java基于Socket文件传输示例

最近需要进行网络传输大文件,于是对基于socket的文件传输作了一个初步的了解。在一位网友提供的程序基础上,俺进行了一些加工,采用了缓冲输入/输出流来包装输出流,再采用数据输入/输出输出流进行包装,加快传输的速度。废话少说,先来看服务器端的程序。
  1.服务器端
package sterning;
import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class ServerTest {
int port = 8821;
void start() {
Socket s = null;
try {
ServerSocket ss = new ServerSocket(port);
while (true) {
// 选择进行传输的文件
String filePath = "D:\\lib.rar";
File fi = new File(filePath);
System.out.println("文件长度:" + (int) fi.length());
// public Socket accept() throws
// IOException侦听并接受到此套接字的连接。此方法在进行连接之前一直阻塞。
s = ss.accept();
System.out.println("建立socket链接");
DataInputStream dis = new DataInputStream(new BufferedInputStream(s.getInputStream()));
dis.readByte();
DataInputStream fis = new DataInputStream(new BufferedInputStream(new FileInputStream(filePath)));
DataOutputStream ps = new DataOutputStream(s.getOutputStream());
//将文件名及长度传给客户端。这里要真正适用所有平台,例如中文名的处理,还需要加工,具体可以参见Think In Java 4th里有现成的代码。
ps.writeUTF(fi.getName());
ps.flush();
ps.writeLong((long) fi.length());
ps.flush();
int bufferSize = 8192;
byte[] buf = new byte[bufferSize];
while (true) {
int read = 0;
if (fis != null) {
read = fis.read(buf);
}
if (read == -1) {
break;
}
ps.write(buf, 0, read);
}
ps.flush();
// 注意关闭socket链接哦,不然客户端会等待server的数据过来,
// 直到socket超时,导致数据不完整。
fis.close();
s.close();
System.out.println("文件传输完成");
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String arg[]) {
new ServerTest().start();
}
}
2.socket的Util辅助类
package sterning;
import java.net.*;
import java.io.*;
public class ClientSocket {
private String ip;
private int port;
private Socket socket = null;
DataOutputStream out = null;
DataInputStream getMessageStream = null;
public ClientSocket(String ip, int port) {
this.ip = ip;
this.port = port;
}
/** *//**
* 创建socket连接
*
* @throws Exception
*             exception
*/
public void CreateConnection() throws Exception {
try {
socket = new Socket(ip, port);
} catch (Exception e) {
e.printStackTrace();
if (socket != null)
socket.close();
throw e;
} finally {
}
}
public void sendMessage(String sendMessage) throws Exception {
try {
out = new DataOutputStream(socket.getOutputStream());
if (sendMessage.equals("Windows")) {
out.writeByte(0x1);
out.flush();
return;
}
if (sendMessage.equals("Unix")) {
out.writeByte(0x2);
out.flush();
return;
}
if (sendMessage.equals("Linux")) {
out.writeByte(0x3);
out.flush();
} else {
out.writeUTF(sendMessage);
out.flush();
}
} catch (Exception e) {
e.printStackTrace();
if (out != null)
out.close();
throw e;
} finally {
}
}
public DataInputStream getMessageStream() throws Exception {
try {
getMessageStream = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
return getMessageStream;
} catch (Exception e) {
e.printStackTrace();
if (getMessageStream != null)
getMessageStream.close();
throw e;
} finally {
}
}
public void shutDownConnection() {
try {
if (out != null)
out.close();
if (getMessageStream != null)
getMessageStream.close();
if (socket != null)
socket.close();
} catch (Exception e) {
}
}
}
 3.客户端
package sterning;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileOutputStream;
public class ClientTest {
private ClientSocket cs = null;
private String ip = "localhost";// 设置成服务器IP
private int port = 8821;
private String sendMessage = "Windwos";
public ClientTest() {
try {
if (createConnection()) {
sendMessage();
getMessage();
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
private boolean createConnection() {
cs = new ClientSocket(ip, port);
try {
cs.CreateConnection();
System.out.print("连接服务器成功!" + "\n");
return true;
} catch (Exception e) {
System.out.print("连接服务器失败!" + "\n");
return false;
}
}
private void sendMessage() {
if (cs == null)
return;
try {
cs.sendMessage(sendMessage);
} catch (Exception e) {
System.out.print("发送消息失败!" + "\n");
}
}
private void getMessage() {
if (cs == null)
return;
DataInputStream inputStream = null;
try {
inputStream = cs.getMessageStream();
} catch (Exception e) {
System.out.print("接收消息缓存错误\n");
return;
}
try {
//本地保存路径,文件名会自动从服务器端继承而来。
String savePath = "E:\\";
int bufferSize = 8192;
byte[] buf = new byte[bufferSize];
int passedlen = 0;
long len=0;
savePath += inputStream.readUTF();
DataOutputStream fileOut = new DataOutputStream(new BufferedOutputStream(new BufferedOutputStream(new FileOutputStream(savePath))));
len = inputStream.readLong();
System.out.println("文件的长度为:" + len + "\n");
System.out.println("开始接收文件!" + "\n");
while (true) {
int read = 0;
if (inputStream != null) {
read = inputStream.read(buf);
}
passedlen += read;
if (read == -1) {
break;
}
//下面进度条本为图形界面的prograssBar做的,这里如果是打文件,可能会重复打印出一些相同的百分比
System.out.println("文件接收了" +  (passedlen * 100/ len) + "%\n");
fileOut.write(buf, 0, read);
}
System.out.println("接收完成,文件存为" + savePath + "\n");
fileOut.close();
} catch (Exception e) {
System.out.println("接收消息错误" + "\n");
return;
}
}
public static void main(String arg[]) {
new ClientTest();
}
}
  这就实现了从服务器端向客户端发送文件的过程,当然,反过来,也一样.稍有不同.代码中对跨平台的细节没有实现,有时间或兴趣的朋友可以提供一下.

posted @ 2014-06-03 09:54 顺其自然EVO 阅读(195) | 评论 (0)编辑 收藏

Linux内核移植问题总结

移植一个内核会涉及到很多东西,对想学arm的人来说还是挺有帮助的,会比直接拿别人移植好的内核来跑有趣的多。
  一、串口打印问题
  内核移植的第一步就是要有打印输出。看不到打印信息,都不知道内核有没有跑起来。我移植 linux-2.6.35编译完成后运行,启动一直停在starting kernel . . .,检查machine-type、cpu-id、时钟、入口地址等可能会导致问题的地方都没有问题,最后想到可能是串口使用的引脚和内核不一致,最后才发现板子使用的是串口2作为打印输出(也是我一开始没想到的,因为一般都会默认使用串口1,纠结)。讲启动参数改成串口2,mx5_loco.c 里面的init串口改成UART2_BASE_ADDR,可以输出信息了。
  二、文件系统
  1、自己编译一个busybox来制作一个文件系统其实还是挺麻烦的,只能制作一个很简单的文件系统,因为是在flash上加载,所以我最开始尝试的是cramfs,加载文件系统阶段一直出错
  List of all partitions:
  1f00          131072 mtdblock0  (driver?)
  No filesystem could mount root, tried:  cramfs
  Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(31,0)
  这里只读到了一个块设备,block0,显然flash的分区没有成功,修改nandflash的分区,文件系统正常加载,启动参数如下
  setenv bootargs root=/dev/mtdblock3 rootfstype=cramfs rw console=ttymxc1,115200 init=/linuxrc
  2、加载成功有时会出现Kernel panic - not syncing: Attempted to kill init!,这个很多人说要开
  Kernel Features  --->
  [*] Use the ARM EABI to compile the kernel
  [*]   Allow old ABI binaries to run with this kernel (EXPERIMENTAL)(NEW)
  我试过好像没什么效果,出现这个问题有可能是文件系统的inittab和rcS两个文件有问题。
  3、jffs2文件系统
  JFFS2 error: (1) jffs2_build_inode_pass1: child dir"alsa" (ino #1159) of dir ino #1074 appears to be a hard link  JFFS2 error: (1) jffs2_build_inode_pass1:child dir "l" (ino #1170) of dir ino #1075 appears to be a hard link
  原由 : flash没有erase彻底.,多 nand erase几次就好了
  还有就是jffs2文件系统会有很多警告信息,我在源码里面将打印都去掉还是不行

posted @ 2014-06-03 09:52 顺其自然EVO 阅读(557) | 评论 (0)编辑 收藏

前端自动化测试工具doh学习总结(一)

 前言
  项目中需要用到前端自动化测试,自己被当作一个探针研究了下目前用的比较多的web自动化测试工具。一开始研究的是的selenium,但由于项目使用了大量的dijit控件,写起testCase来很费劲;最主要的是selenium有严重的浏览器兼容性问题,于是彻底放弃,改投doh门下,毕竟是dojo他爸爸开发的跟dojo继承起来非常方便。这几篇主要介绍doh、doh/Robot以及将doh与selenium结合进而与CI工具集成起来。
  一、DOH 是什么
  DOH 是 Dojo Objective Harness 的简称,是 Dojo 在 0.9 版本之后新增的单元测试工具。随着 Javascript 代码的数量和复杂度的增加,Web 前端开发者也需要一个 Javascript 代码的单元测试框架来保证自己写出来的 Javascript 代码是健壮的。所以,DOH 是 Web 前端开发者对 JUnit 的回应。DOH有如下特点:
  提供用户界面:JUnit中的红条测试失败、绿条测试通过,大家都已经很熟悉了,DOH也有类似的用户界面,用户在测试时更加一目了然;
  平台无关:DOH并不依赖某种浏览器平台,甚至不依赖于浏览器;用户可以根据自己的需要在命令行进行Javascript的自动化单元测试;
  支持Ajax:Ajax编程在Web前端开发中是必不可少的一环,DOH最有价值的一个特性就是支持Ajax的测试;
  不只适合与于Dojo,可用于任何JavaScript程序的单元测试。
  下载dojo源码包,解压后可以看到以下目录:
  二、DOH第一次亲密接触
  部署到服务器后,我们访问runner.html
  与JUnit类似,DOH也为我们提供了一个类似的界面,左侧表示运行的测试案例,右侧是测试日志,最上方的进度条表示的是本次运行中的已执行案例,同样绿色表示成功,红色表示失败。默认情况下会加载“dojo/tests/module.js”文件,该文件的作用就是像runner.html中加载dojo所有核心模块的测试案例。
  如果想要单独加载某一模块的测试案例,需要用到test参数指向该模块:
  http://<server>/util/doh/runner.html?test=dojo/tests/fx
我们可以吧测试案例放到自己的项目目录下,通过test参数指向自定义测试模块,这时需要用到paths参数:
  util/doh/runner.html?paths=org/myorg,../../../mycode/org/myorg&test=org/myorg/mymodule/tests/alltests
  paths参数中逗号前后的值相当于dojoConfig定义packages对象时的name和location
  同样在path中我们可以定义多个模块, 模块之间用“;”分隔开来
  util/doh/runner.html?paths=org/myorg,../../../mycode/org/myorg;com/mycom,../../../x/com/mycom&test=com/mycom/tests
  doh中测试模块要么是一个用来请求多个测试文件的文件,要么是一个使用doh.register方法注册时测试案例,或者两者皆有。
  define([
  "my/test/widget/Foo0",
  "my/test/widget/Foo1",
  "my/test/widget/Foo2"
  ]);
doh.register(...)
An almost 'magical' function. The doh.register() method accepts the function signatures of any of the other registration functions and determines the correct underlying function (listed below) to dispatch registration to. It's the function you'll most commonly use for registering Unit Tests.
doh.registerTest(group, testFuncOrObj)
This function registers a test as a member of the group 'group', and the test can either be a simple function definition or a 'Test Fixture', which is an object that defines the run requirements of the test.
doh.registerTests(group, testFuncOrObjArr)
This function registers an array of tests as a member of the group 'group'. The contents of the array of tests can be an array of simple test functions or an array of 'test fixtures', or a mix of them.
doh.registerTestNs(group, obj)
This function registers an object comprised of functions as a member of the group 'group'. Note that this function will only add in non-private (functions without an _ at the beginning of the name), as a test function. If you'd like to use fixtures (setUp(), tearDown(), and runTest()), please use doh.register(), doh.registerTest() or doh.registerTests().
doh.registerTestUrl(url)
This function registers a URL as a location to load tests from. The URL is used to populate the contents of an iframe, and usually refers to an HTML page that boot-loads D.O.H. internally for running tests in a segmented iframe. A good example showing this is the dojo/tests/fx.html. It loads dojo, doh, and then on dojo load completion calls doh.registerTests(). The D.O.H. instance in the iframe will proxy back the results of the test run to the primary D.O.H. instance.
  上面提到的dojo/test/fx模块中我们可以看到该文件中主要定义了两个TestSuite:
  define(["doh/main", "require"], function(doh, require){
  if(doh.isBrowser){
  doh.register("tests.fx", require.toUrl("./fx.html"), 30000);
  doh.register("tests.NodeList-fx", require.toUrl("./NodeList-fx.html"), 30000);
  }
  });
  对应于runner.html中
  打开该目录下的fx.html文件,我们可以看到该文件中定义了一系列TestCase
  doh中有两种测试结构:
  1、Simple Tests  将一个单独的函数放到doh.register参数testCase数组里
  同步形式:
  function mySimpleTest(doh){
  doh.assertTrue(true);
  }
  异步形式:
function mySimpleAsyncTest(doh){
var deferred = new doh.Deferred();
setTimeout(deferred.getTestCallback(function(){
doh.assertTrue(true);
}), 100);
return deferred;
}
  2、Test Fixture
  同步形式:
{
name: "thingerTest",
setUp: function(){
// Setup to do before runTest.//类似于JUnit中的@beforeTest
this.thingerToTest = new Thinger();
this.thingerToTest.doStuffToInit();
},
runTest: function(){
// Our test function to run.//类似于JUnit中的@Test
doh.assertEqual("blah", this.thingerToTest.blahProp);
doh.assertFalse(this.thingerToTest.falseProp);
// ...
},
tearDown: function(){
// cleanup to do after runTest.//类似于JUnit中的@afterTest
},
timeout: 3000 // 3 second timeout.//测试运行时间,超过改时间会报错
}
  异步形式:
{
name: "thingerTest",
setUp: function(){
// Setup to do before runTest.
this.thingerToTest = new Thinger();
this.thingerToTest.doStuffToInit();
},
runTest: function(){
// Our test function to run.
var deferred = new doh.Deferred();
setTimeout(deferred.getTestCallback(function(){
doh.assertEqual("blah", this.thingerToTest.blahProp);
doh.assertFalse(this.thingerToTest.falseProp);
}), 100);
return deferred;
},
tearDown: function(){
// cleanup to do after runTest.
},
timeout: 3000 // 3 second timeout.
}

posted @ 2014-05-29 11:42 顺其自然EVO 阅读(614) | 评论 (0)编辑 收藏

仅列出标题
共394页: First 上一页 104 105 106 107 108 109 110 111 112 下一页 Last 
<2024年11月>
272829303112
3456789
10111213141516
17181920212223
24252627282930
1234567

导航

统计

常用链接

留言簿(55)

随笔分类

随笔档案

文章分类

文章档案

搜索

最新评论

阅读排行榜

评论排行榜