lizhe1985/
共2559个网摘 [
1 2 3 4 5 6 ...
86 ]
下一页 |
访问lizhe1985的个人空间
lizhe1985收录,使用标签:Web开发,时间:2008-9-16 13:36:50 | 相关网摘,我也收藏
来源:http://blog.csdn.net/java2000_net/archive/2008/09/16/2935913.aspx
URL重写,其实就是把带一大堆参数的url,变成一个看上去很规矩的url,主要目的是为了搜索引擎。
举例
/viewthread.jsp?id=1234
/viewthread.jsp?id=1235
/viewthread.jsp?id=1236
重写后,可以用
/viewthread/1234.htm
/viewthread/1235.htm
/viewthread/1236.htm
我目前使用Tomcat+Apache,尝试过三种重写的方法
一、Tomcat的过滤器
最典型的就是用 urlReweite的类库。大家爱如果有经验,自己写也不是很麻烦。
修改web.xml增加过滤器,然后配置个过滤的规则就可以了
web.xml修改部分
<!-- Set URL Rewrite-->
<filter>
<filter-name>UrlRewriteFilter</filter-name>
<filter-class>
org.tuckey.web.filters.urlrewrite.UrlRewriteFilter
</filter-class>
</filter>
<filter-mapping>
<filter-name>UrlRewriteFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
过滤规则
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE urlrewrite PUBLIC "-//tuckey.org//DTD UrlRewrite 2.6//EN"
"http://tuckey.org/res/dtds/urlrewrite2.6.dtd">
<urlrewrite>
<rule>
<from>/viewthread/(\d+).htm$</from>
<to>/viewthread.jsp?id=$1</to>
</rule>
</urlrewrite>
更多详情,请参考 http://www.java2000.net/p7782
二、使用Apache的mod
# 去掉这个前面的#,启用它
LoadModule rewrite_module modules/mod_rewrite.so
<VirtualHost _default_:80>
# 其它的配置数据
RewriteEngine On
# 下面三行实现动态解析
RewriteRule ^/viewthread/(\d+).htm$ /viewthread.jsp?id=$1 [L,PT]
</VirtualHost>
详细参考这里: http://www.java2000.net/p5422
三、使用系统的404错误进行
也就是页面没找到的错误
这个我就不写了,有兴趣的自己参考吧 http://www.java2000.net/p903
总结
第一种修改麻烦,但对于平稳运行的系统,是个不错的选择
第二种需要配置Apache,但 Apache的重启速度很快,适合于有可能经常变得情况,而且Apache Mod的效率还是不错的
第三种,最灵活,我一般简单的应用都是用这个实现的。
http://blog.csdn.net/java2000_net/archive/2008/09/16/2935913.aspx
lizhe1985收录,使用标签:无线移动,时间:2008-9-16 10:22:54 | 相关网摘,我也收藏
来源:http://blog.csdn.net/ttgjz/archive/2008/09/16/2934946.aspx
在编写手机程序时,经常要进行各个屏幕间的切换
功能:在主程序中有多个按钮,每一个按钮对应一个功能,每一个功能要不同的屏幕(元素)表现出来。
实现:
一、主程序中必然定义了一个display对像,如private Display display,它表示当前的屏幕。还有一些Displayable对像。如form,textfield等都是displayable的子类。在主程序中通过dipslay.sercurrent(displayable实例名); 即可将当displayable实例加入当前的屏幕。以下程序:
private Display display=Display.getDisplay(this);
private Form form = new Form(“New Form“);
public void startapp()
{
display.setcurrent(form);
}
作用是将form添加到当前的屏幕当中。
二、要想进行屏幕间的切换,只要将你想显示的东东放到到主程序的display对象中即可。主程序中定义了一个display,则要在另一个屏幕(我姑且把它称之为目标屏幕)中引用到主程序的display。
用以下代码说明:
mainmidlet.java:主程序,一个标准的midlet。
import javax.microedition.midlet.midlet;
import javax.microedition.lcdui.*;
public class mainmidlet extends midlet implements commandlistener {
private display display;
private form form = new form("wellcome!!");
private command okcommand = new command("ok",command.ok,1);
//选择ok,换到下一个屏幕
private form ns ;
private stringitem si = new stringitem("first screen","~_~");
public mainmidlet()
{
form.addcommand(okcommand);
form.append(si);
}
public void startapp() {
display = display.getdisplay(this);
display.setcurrent(form);
form.setcommandlistener(this);//对form加入commandlistener
}
public void pauseapp() {
}
public void destroyapp(boolean b){
}
public void commandaction(command c,displayable s)
{
if(c==okcommand)
{
ns = new nextscreen(display,form);//最关键的地方在这里:form:将父屏幕对象传下去,方便后退时返回父屏幕)
display.setcurrent(ns);
}
}
}
在这个midlet中,定义了一个display对像display。
以及一个两个displayable对象form form及stringitem si。运行后显示在屏幕当中。
还有个一command okcommand,其作用是触发下一个屏幕。
在public void commandlistener中可以看到,当当前按下的按钮是okcommand时,初始化一个nextscreen对象
ns = new nextscreen(display,form);
将display和form传入,作用就是进行屏幕的切换。
下面是nextscreen的实现:
nextscreen.java 第二个屏幕的代码
import javax.microedition.lcdui.*;
public class nextscreen extends form implements commandlistener {
private display display;
private displayable parent;
private command backcommand = new command("back",command.back,1);
private stringitem si = new stringitem("secondscrean","~_~");
public nextscreen(display d,displayable p)
{
super("nextscreen");
display = d;
parent = p;
append(si);
addcommand(backcommand);
setcommandlistener(this);
}
public void commandaction(command c,displayable s)
{
//返回上一个屏幕
if(c==backcommand)
{
display.setcurrent(parent);
}
}
}
它继承自form类。
在nextscreen中又定义了一个display display,将用它来标识当前的元素显示在哪一个屏幕中。
一个form form,一个stringitem si。这是当前屏幕中要显示的东东:)
构造函数中的super("secondscreen");的作用是使得nextscreen可以直接调中其父类form中的函数。
backcommand的作用是返回上一个屏幕。
将form,si及backcommand加入nextscreen中,一个nextscreen的实例就完成了。在主程序(mainmidlet)中,就是ns。
接下来,最关键的地方,就是在mainmidlet中的这一句:display.setcurrent(ns);
就是把ns在当前的屏幕中显示出来!这样就可以看到nextscreen中定义的各个元素(form,si)了!
然后想返回原屏幕,怎么办呢?这时nextscreen中的backcommand就起作用了。
仔细看这两句:
在mainmidlet.java中:
ns = new nextscreen(display,form);
它将form也传了进去。它有什么用呢?
在nextscreen的构造函数中:
dispaly =d;
这一句其实等于:nextscreen.display = mainmidlet.display;
这样,nextscreen就得到了当前的屏幕,它就随意的在上面放东东了。
parent = p;
这一句其实等于:nextscreen.parent = mainmidlet.form;
从字面意思不难理解,原来是把主程序的form当成parent(父母),这样就得到当前屏幕的前一个屏幕中所显示的内容!!
然后在commandaction中,如果backcommand按下了,则执行display.sercurrent(parent);这样,又把原来的屏幕给show出来了。
http://blog.csdn.net/ttgjz/archive/2008/09/16/2934946.aspx
lizhe1985收录,使用标签:Web开发,时间:2008-8-25 14:13:25 | 相关网摘,我也收藏
来源:http://www.blogjava.net/javaread/archive/2008/08/21/223561.html
现在java web框架非常多,林林总总,让很多人不知道选择那个好:JSF、Spring MVC、Stripes、Struts 2、Tapestry和Wicket,他们都是各有千秋,面对各种问题,八仙过海,各显神通。
这里就小话一下他们的优缺点。
JSF
优点:
Java EE标准,这意味着有很大的市场需求和更多的工作机会
上手快速并且相对容易
有大量可用的组件库
缺点:
大量的JSP标签
对REST和安全支持不好
没有一个统一的实现。既有SUN的实现,又有Apache的实现——MyFaces。
国内的OperaMasks还支持AJAX,以及有开发工具支持
Spring MVC
优点:
对覆盖绑定(overriding binding)、验证(validation)等提供生命周期管理
与许多表示层技术/框架无缝集成:JSP/JSTL、Tiles、Velocity、FreeMarker、Excel、XSL、PDF等
便于测试——归功于IoC
缺点:
大量的XML配置文件
太过灵活——没有公共的父控制器
没有内置的Ajax支持
Stripes (现已发布1.5版本)
优点:
不需要书写XML配置文件
良好的学习文档
社区成员很热心
缺点:
社区比较小
不如其他的项目活跃
ActionBean里面的URL是硬编码的
Struts 2
优点:
架构简单——易于扩展
标记库很容易利用FreeMarker或者Velocity来定制
基于控制器或者基于页面的导航
缺点:
文档组织得很差
对新特征过分关注
通过Google搜索到的大多是Struts 1.x的文档
Tapestry
优点:
一旦学会它,将极大地提高生产率
HTML模板——对页面设计师非常有利
每出一个新版本,都会有大量的创新
缺点:
文档过于概念性,不够实用
学习曲线陡峭
发行周期长——每年都有较大的升级
Wicket
优点:
对Java开发者有利(不是Web开发者)
页面和显示绑定紧密
社区活跃——有来自创建者的支持
缺点:
HTML模板和Java代码紧挨着
需要对OO有较好的理解
Wicket逻辑——什么都用Java搞定
就项目使用选择而言,
如果是稳健起见,structs是不错的选择;
如果小项目,我更请倾向于Stripes,够简单、简洁。
如果想用概念比较新的框架,可以选择JSF、tapestry,它们都是基于组件的,重用性比较好。(当然开发者也要要设计得好)
本文作者:javaread.com
http://www.blogjava.net/javaread/archive/2008/08/21/223561.html
lizhe1985收录,使用标签:Web开发,时间:2008-8-25 14:10:07 | 相关网摘,我也收藏
来源:http://www.blogjava.net/nokiaguy/archive/2008/08/23/223881.html
Web系统虽然现在很流行,但是分页问题一直长期困扰着Web系统的开发人员。对于不同的数据库,可能开发人员对分页的处理分有很大差别。个人认为,使用MySQL开发Web系统的程序员是感到最舒服的,因为,在MySQL中提供了limit语句,可以获得查询结果的一段数据。如下面的SQL语句所示:
select * from table1 limit 1, 20
上面的SQL表示从table1中查出记录,并返回从第2条开始的20条记录(第1条记录从0开始)。
对于其他的数据库,恐怕就没MySQL那么容易查询出记录段了。在SQL Server2005中也提供了类似MySQL的处理方法(可以使用ROW_NUMBER()函数来实现这个功能),SQL语句如下:
With t AS
(
SELECT contactid, namestyle, lastname,
ROW_NUMBER() over(order by namestyle) as RowNumber
FROM Person.Contact
)
select * from t
Where RowNumber Between 20 and 30
虽然上面的SQL语句虽然也可以实现和MySQL一样的功能,但却比MySQL的limit复杂一些。
如果在数据库中提供了实现Web分页的机制,就算复杂一些,也是可以解决的。但有效数据库可能并未提供这种机制。这就得使用更复杂的方法来实现Web分页,如在SQL Server2000中未提供ROW_NUMBER()函数,就有很多开发人员通过编写分页的存储过程来处理。这样做既复杂,又不通用。假设要移植到Oracle上,还得费一番功夫。
在本文给出一种直接使用Web中的Session对象来方式来实现分页的功能,Session是在Web系统中保存当前分话数据的。我们可以想象。分页的难点在哪里,就象MySQL中的limit语句一样,只需要有两个值:起使记录数和要获得的记录总数就可以了。要获得的记录总数这个我们很容易知道,一般就是分一页的记录数。但是起使记录数却很难获得。
如果使用自增键当然可以,但这要建立在表只增不删,而且id从1或一个已知的起始位置开始的情况。如果删除了表中的一些数据,自增键就不再是从1到n,依次递增了。也就是中间可能有空档。如自增键从20至100,中间可能只有10条记录。因此,单纯使用自增键并不能很好地解决分页问题。
但却可以将Session和自增键组合来解决分页问题。大家可以设想,在用户第一次查询时,如select * from table1 where field1 like '%abc%',这时将记录全部查出。假设每页显示50条记录,这时可以从头开始取出50条记录。这不会有任何问题。然后,当用户要查看第2页时,最普通的做是再执行一次上面的SQL语句,然后从第51第记录开始,再取出50条记录。如果这样做,将大大浪费服务器的资源。
为了解决这个问题,可以在每一次执行完上面的SQL语句后,除了取出前50条记录外,再通过记录的定位,将其他页面的起始id值保存在Session中(可以放在List对象中)。然后在用户要查看第2页或后面的页时,直接从Session中取出该页起始id的值,如果使用的是SQL Servlet数据库,可以使用top n,其中n表示每页记录数,来查询当前页的记录。
先拿Java为例来说明一下。下面的代码在Session中记录了第一页到最后一页的起始id:
// rs为记录集,其他语言的操作类似
ResultSet rs = stmt.executeQuery("select * from table1 where field1 like '%abc%'");
int n = 1;
while(rs.absolute(n))
{
int id = rs.getInt(id)
// 将id保存在Session中
n += 50;
}
从上面的代码可以看出,使用ResultSet的absolute来定位记录,并取出当前记录的id值(一个自增字段),并将其保存在Session中。
假设共查询出500条记录,那么Session中保存的id值有可能是下面的样子:
1 51 123 179 229 290 367 567 699
从上面的id值可以看出,中间有断档。但这9个id值之间的记录数都是50个。如下面的SQL语句将查询出50个记录:
select * from table1 where field1 like '%abc%' and (id >= 290 and id < 367)
假设用户要查看第3页的话,就会取出123和179,并将其加入select 语句的where条件,类似上面的SQL语句。这样用户除了第一次查询外,查看其他页都会只返回当前页面的记录了。
上面的方法还有一些问题,如当第一次返回的记录很多的话,使用absolute方法进行循环所有的记录可能有些慢,那可以在程序中做个约定,只循环41次,也就是保存前40页的记录,当用户要查看第41页的话,再取出第40页的开始记录的id值,将再次查询从该id值往后的所有记录,再记录40页的id值,也就是这时已经有80页的id记录被保存在Session中的。以此类推,
当然,这种方法也不可避免地遇到删除记录的情况,如果用户正在查看页面,这时某一页的记录被删除了,当用户再次要查看这页时,根据Session中保存的id区间,就会得到少于50的记录。在这种情况下,如果使用的是SQL Servlet,就好办一些,可以在where条件中只加id的上限,不加下限,然后使用top关键字来限制查询出的记录数,SQL语句如下:
select top 50 * from table1 where field1 like '%abc%' and id >= 290
如果使用的是其他数据库,没有类型top的关键字,可以在查询时多加一个区间,如用户要查询第2页的数据,可以将第2页和第3页的都查出来,这样一般就可以获得超过50条的记录。但如果记录数还不够(这个表的记录被删除的太多了),笔者建议重新查询所有的记录,重新更新一下Session对象中的id值。
总之,本算法就是在第一次查询时预先将后面页面的起始记录的id值事先保存起来,然后等待以后查看其他页面时使用。如果这时某个页面的记录被删除(如果当前页面记录数不足页面记录总数,被示为有记录删除),可以重新更新一下Session中的id值,然后根据新的id值再查一遍。但要注意的是这个id值最好使用数据库的自增型字段(一般的数据库,甚至桌面数据库都会有自增型字段类型)。为了尽量避免总更新Session中的id值,可以在查询一个页面时查询出两个页面的记录,这样在一般情况下,会保证记录数超过页面记录总数。但这样做一个缺点,就是可能两个相邻页面的记录有一定的重复。不过并没有太大影响。我们在网上看某些论坛的贴子时,有时可能也会发现两个相邻页面的记录有重复。
本分页方法适合于所有的数据库,无论是网络数据库(Oracle、SQL Servlet、DB2等),以及桌面数据库(access、paradox、pdf等)。并且不需要在数据库中建立额外的资源,如存储过程等。(当然,每个表需要有一个自增类型字段,这一点很关键)。
补充一下,这种方法只适合于一个排序字段的查询,而且这个排序字段值不能有重复的,也就是说得是有唯一索引的字段。在本文中使用了自增键来说明,但也可以是其他字段,如不重复的时间字段,按时间排序后。可以使用本文的方法。而且唯一字段区间值也可以使用其他的方式保存,如viewstate,hide input等。
http://www.blogjava.net/nokiaguy/archive/2008/08/23/223881.html
lizhe1985收录,使用标签:软件测试,时间:2008-8-25 14:06:57 | 相关网摘,我也收藏
来源:http://www.blogjava.net/xiaodu/archive/2008/08/23/223898.html
程序在实际应用当中,大数据量时对系统本身的影响是一个不得不面对的问题。
什么是tptp
Eclipse Test and Performance Tools Platform(TPTP)用它可以监测运行的并发线程数据、内存的使用情况等,是不款非常不错的性能测试工具,它是eclipse官方的一款插件项目.可以进行程序执行时间的统计分析、内存的监控、对象调用的分析等。
环境
本次用的tptp版本是4.4.0.2是当时比较稳定的版本,再多说一句,本想下载tptp的4.4.1 但是下载所有eclipse官方所有依赖的插件运行后一直都启动不了agent controller(tptp依赖的一个非常重要的服务项目),所以请大家注意,我是浪费了整两天时间也没搞懂为什么启动不了,所以用了 4.4.0.2.
jdk1.6
Business Intelligence and Reporting Tools (BIRT) 2.2.2
tptp.platform.runtime-TPTP-4.4.0.2
tptp.trace.runtime-TPTP-4.4.0.2
Data Tools Platform (DTP) 1.5.2
Graphics Editor Framework (GEF) 3.3.2
Eclipse Web Tools Platform (WTP) 2.0.2
Eclipse Modeling Framework (EMF and XSD) 2.3.2
eclipse3.3.2
以上是我的运行环境供大家参考,还可下载许多tptp相关的插件工具,具体的网址是:http://www.eclipse.org/tptp/home/downloads/?ver=4.4.1
注意相关的工具可能也有他依赖的插件工具.
运行tptp
安装tptp后启动eclipse将出现如下界面:
如果你的eclipse工具栏的位置将出现profile按钮(上图红色标记的按钮)说明tptp安装成功.
如果想测试你的程序,右键点击类文件选择Profile as--->Java Application将打开如下界面:
在打开此界面过程中系统进程中将多一个ACServer服务项,这也是tptp所依赖的一个非常重要的服务,在tptp4.4之前的版本agent controller(ACServer服务)
是需要用户手动打开此服务,agent controller可以在tptp的网站下载,注意要下载与你系统相符的agent controller版本,tptp4.4不需要另外下载agent controller
tptp自动启动agent controller,此服务的默认的端口为10002,使用时要查看端口是否被占用,再看上图,如果你的jdk是1.5可以选择jre1.5,如果jdk1.6需要选择jre1.5
or new来运行tptp,如果成功eclipse将改变为Profile and Logging透视图,如下图:
左侧将出现统计项,双击此项在右侧出现统计信息,如果eclipse中安装有mdt-uml工具插件,当右键点击统计项时会出现uml统计项,将出现uml的序列图.
此上只是tptp的基本应用,仅供参考,tptp的配置及应用还有很多,并且也可以测试web工程的应用,如果有兴趣大家可以去eclipse网站查看资料.
http://www.blogjava.net/xiaodu/archive/2008/08/23/223898.html
lizhe1985收录,使用标签:软件测试,时间:2008-8-6 16:24:13 | 相关网摘,我也收藏
来源:中国IT实验室
Usability的概念在中国开始逐渐为企业所认识,但是作为这个领域的核心词汇,usability的中文翻译仍未统一。目前存在着两个主流版本:“可用性”和“易用性”。这两个译法虽然只有一字之差,但它们所传达的含义却大相径庭。对这两者的取舍已经不仅仅是哪个更好一点的锦上添花的问题,而是哪个对哪个错的是非原则问题。“易用性”的使用对于正确理解usability具有极大的片面性和误导性,非常不利于其在中国的开展。
从英文原词上分析,usability是由use(动词)变化到usable(形容词)然后再转变为usability(名词)。Use这个词从动词到名词的过程还有另一种变化,就是从use(动词)到useful(形容词)再到usefulness(名词)。后者要比前者更“单纯”,变化的过程只是词性的改变而不涉及意思的转化。这些变化都围绕着use这个核心展开,因此在意思上都离不开“用”这个概念。-ability这个词根代表“具备某种行为特性”这样一个抽象的概念,故而在中文翻译中通常译为“可…性”,例如:readability(可阅读性)。因此,“可用性”这个译法是在严格遵从语言和翻译习惯的基础上形成的。“易用性”虽然也保留了这个“用”这个核心意思,但是其中的“易”字却完全是无中生有,因为在英文单词的整个变化过程中始终没有任何一丝“易”的意义出现。
对于为什么要人为加上“易”字,一个看似合理的解释是这是意译。那么usability是不是就是“易用”呢?不妨先看看usability的解释。世界标准组织对于usability的定义是“The extent to which a product can be used by specified users to achieve specified goals with effectiveness, efficiency and satisfaction in a specified context of use.”这个定义采用了effectiveness(效果)、efficiency(效率)和satisfaction(满意)三个维度来说明usability.尽管这三个维度并不构成usability的全部,但是在测量usability时它们是被最广泛采用的指标。如果说efficiency和satisfactory这两个维度还可以和“易用”扯上关系的话,那么effectiveness这个维度显然和“易用”是互相独立的两个概念。因此,意译这个说法同样是无法成立的。
事实上,“易用”在usability领域是有一个专门用语的,那就是ease of use.在英文文献中,没有人会简单地将ease of use与usability划等号。但是当usability进入中国以后,“易用性”却堂而皇之地以代言人的身份四处出现。也许有人认为“易用性”这个词比较直观,容易被大众理解和接受。殊不知这正是“易用性”的危害。如果放任“易用性”的使用, usability这个概念在中国恐怕将被局限在ease of use这个狭窄的范围之中。作为一个术语,是不是很容易从字面上理解其含义并不是第一重要的,“递归”这个术语就是一个很好的例子。对一个术语的翻译,在艰涩与误导之间永远都不应该选择误导。更何况“可用性”的译法远没有达到艰涩的地步。
让我们向“易用性”说不!
http://softtest.chinaitlab.com/kyx/758811.html
lizhe1985收录,使用标签:软件测试,时间:2008-8-6 16:20:47 | 相关网摘,我也收藏
来源:中国IT实验室
软件缺陷的描述是是软件缺陷报告的基础部分,也是测试人员就一个软件问题与开发小组交流的最初且最好的机会。
一个好的描述,需要使用简单的、准确的、专业的语言来抓住缺陷的本质。否则,它就会使信息含糊不清,可能会误导开发人员。准确报告软件缺陷是非常重要的,因为:清晰准确的软件缺陷描述可以减少软件缺陷从开发人员返回的数量提高软件缺陷修复的速度,使每一个小组能够有效的工作提高测试人员的信任度,可以得到开发人员对清晰的软件缺陷描述有效的响应加强开发人员,测试人员和管理人员的协同工作,让他们可以更好的工作在多年实践的基础上,我们积累了较多的软件缺陷的有效描述规则,主要是:
1. 单一准确每个报告只针对一个软件缺陷。在一个报告中报告多个软件缺陷的弊端是常常会导致缺陷部分被注意和修复,不能得到彻底的修正。
2. 可以再现提供缺陷的精确操作步骤,使开发人员容易看懂,可以自己再现这个缺陷,通常情况下,开发人员只有再现了缺陷,才能正确地修复缺陷。
3. 完整统一提供完整、前后统一的软件缺陷的步骤和信息,例如:图片信息,Log文件等。
4. 短小简练通过使用关键词,可以使软件缺陷的标题的描述短小简练,又能准确解释产生缺陷的现象。如“主页的导航栏在低分辨率下显示不整齐”中“主页”、“导航栏”、“分辨率”等是关键词。
5. 特定条件许多软件功能在通常情况下没有问题,而是在某种特定条件下会存在缺陷,所以软件缺陷描述不要忽视这些看似细节的但又必要的特定条件(如特定的操作系统、浏览器或某种设置等),能够提供帮助开发人员找到原因的线索。如“搜索功能在没有找到结果返回时跳转页面不对”。
6. 补充完善从发现bug那一刻起,测试人员的责任就是保证它被正确的报告,并且得到应有的重视,继续监视其修复的全过程。
7. 不做评价在软件缺陷描述不要带有个人观点,对开发人员进行评价。软件缺陷报告是针对产品、针对问题本身,将事实或现象客观地描述出来就可以,不需要任何评价或议论。
http://softtest.chinaitlab.com/qxian/758809.html
lizhe1985收录,使用标签:软件测试,时间:2008-8-6 15:55:51 | 相关网摘,我也收藏
来源:希赛网
通常采用以下一些方法进行源程序的静态分析。
① 生成各种引用表
直接从表中查出说明/使用错误等。如,循环层次表、变量交叉引用表、标号交叉引用表等。
为用户提供辅助信息。如,子程序(宏、函数)引用表、等价(变量、标号)表、常数表等。
用来做错误预测和程序复杂度计算。如,操作符和操作数的统计表等。
② 静态错误分析
静态错误分析主要用于确定在源程序中是否有某类错误或“危险”结构。
类型和单位分析:为了强化对源程序中数据类型的检查,发现在数据类型上的错误和单位上的不一致性,在程序设计语言中扩充了一些结构。如单位分析要求使用一种预处理器,它能够通过使用一般的组合/消去规则,确定表达式的单位。
引用分析:最广泛使用的静态错误分析方法就是发现引用异常。如果沿着程序的控制路径,变量在赋值以前被引用,或变量在赋值以后未被引用,这时就发生了引用异常。为了检测引用异常,需要检查通过程序的每一条路径。也可以建立引用异常的探测工具。
表达式分析:对表达式进行分析,以发现和纠正在表达式中出现的错误。包括:在表达式中不正确地使用了括号造成错误。数组下标越界造成错误。除式为零造成错误。对负数开平方,或对π求正切值造成错误。以及对浮点数计算的误差进行检查。
接口分析:关于接口的静态错误分析主要检查过程、函数过程之间接口的一致性。因此要检查形参与实参在类型、数量、维数、顺序、使用上的一致性;检查全局变量和公共数据区在使用上的一致性。
http://se.csai.cn/testtech/200808051155131216.htm
lizhe1985收录,使用标签:软件测试,时间:2008-8-6 15:53:46 | 相关网摘,我也收藏
来源:希赛网
终于明白了何谓“忙忙碌碌”,除了感叹古人造词的高深之外,也深刻为自己近期因为工作繁忙而没有积累而检讨。正所谓不积跬步,无以至千里。繁忙之余,还是决定和大家一起讨论一下最近接触的一个新的概念——专家评估。
这是近期用户体验测试引入一个新方法。整体的流程是邀请交互设计专家当场使用产品,产品设计、开发相关人员观察专家使用产品的全过程,在遍历整个产品细节后,由专家当场分享产品的使用体会。
单从这一流程就不难看出,专家评估与普通的用户体验测试的一个很大不同就是专家评估直接产出分析报告,并提供改进建议。就这点而言,专家评估更节省时间、更为有效。因为我们都知道,整理、分析用户行为需要大量的数据和前期的准备工作。
那么这是不是就意味着专家评估可以替代所有的一般用户体验测试?答案显然不是。专家评估的一个应用前提就在于它更适合功能简单的产品,因为只有满足这一点,参与评估的专家的行为才能更为真实的反映一种用户的习惯,而非凌驾于用户之上。
以我参与的这次评估活动为例,仔细观察,很容易发现,参与测试的专家由于自己的工作范围决定了其关注点有很大的不同。即专家的背景与结果的真实性仍然有很大的耦合。另外,由于专家的结果为现场分享,所以很容易产生“共鸣”,这就有可能将问题“放大”。因此,产品设计、开发人员不能盲目的接受这些分享,必须进一步的分析问题和建议,并将最终的结果反馈给专家评估小组,以供整个流程的改进。
当然以上仅仅是我的一些感受和看法,期待我们将产品越做越好,让测试更加有效。
http://se.csai.cn/testexe/200808061035161145.htm
lizhe1985收录,使用标签:软件测试,时间:2008-8-6 15:52:00 | 相关网摘,我也收藏
来源:希赛网
关于代码覆盖率,之前6年的工作经历中,只是依稀听闻过。之前的组织里,从未关注过这个指标,只是有一段时间用NUnit做了单元测试,主要是测试一些关键类关键方法是否正常,对代码覆盖率的印象就真的一直是停留在听闻的程度。汗一个!
前些时日,关于自动测试的讨论中有人提及到代码覆盖率,激发了我的好奇,到底什么是代码覆盖率?最重要的是于测试工作而言有怎样的价值呢?今天花了一点时间查了一下,有了初步的认识。大致归纳如下:
一、基本概念
代码覆盖率是单元测试活动任务之一;
覆盖率分语句覆盖率(即通常所说的行覆盖率)和分支覆盖率。
二、价值
代码覆盖率的分析能在一定程度上评判代码质量,一般覆盖率高的代码出错的几率会相对低一些。但是高覆盖率只是表示执行了很多的代码,并不意味着这些代码被很好地执行了。所以,似乎覆盖率测试结果出来并不能帮我准确的评价代码质量。那么我们为什么要做覆盖率测试呢?如何让它给我们带来价值呢?
1. 尽早评估代码质量
比如在开发的过程中,定时的去看整个项目的代码覆盖率,监控覆盖报告可以帮助开发团队迅速找出不断增长的但是没有相应测试的代码。例如,在一周开始时运行覆盖报告,显示项目中一个关键的软件包的覆盖率是 70%。如果几天后,覆盖率下降到了 60%,那么您可以推断:软件包的代码行增加了,但是没有为新代码编写相应的测试(或者是新增加的测试不能有效地覆盖新代码)。能够监控事情的发展,无疑是件好事。定期地查阅报告使得设定目标(例如获得覆盖率、维护代码行的测试案例的比例等)并监控事情的发展变得更为容易。如果您发现测试没有如期编写,您可以提前采取一些行动,例如对开发人员进行培训、指导或帮助。
2. 为功能测试关注点提供情报
假设覆盖报告在指出没有经过足够测试的代码部分方面非常有效,那么质量保证人员可以使用这些数据来评定与功能测试有关的关注区域,可以更有针对性地加强这些区域的测试,因为没有被测试代码覆盖到的区域,出错的几率应该相对更高。
3. 估计修改已有代码所需的时间
对一个开发团队而言,针对代码编写测试案例自然可以增加集体的信心。与没有相应测试案例的代码相比,经过测试的代码更容易重构、维护和增强。测试案例因为暗示了代码在测试工作中是如何工作的,所以还可以充当内行的文档。在另一方面,没有经过相应测试的代码更难于理解和安全地修改。因此,知道代码有没有被测试,并看看实际的测试覆盖数值,可以让开发人员和管理人员更准确地预知修改已有代码所需的时间。
当然,这样的理解还是比较浅层的,我想实际应用中除了以上三点之外,还有一个很重要的工作就是提高测试代码的质量来更好的体现代码覆盖率的价值。
http://se.csai.cn/testtech/200808041503091599.htm
lizhe1985收录,使用标签:Web开发,时间:2008-8-6 15:46:35 | 相关网摘,我也收藏
来源:开发者在线
Python是面向对象且开放源代码的动态编程语言,解释器由C编写。Jython是Python语言的Java实现,解释器使用100%的纯Java实现,在Jython的支持下,可以将Python代码迁移到Java虚拟机上运行。
已有不少动态语言给出了在Java VM之上的实现,如JRuby、Groovy、Jacl,但相比之下,Jython仍有其独到的优势:
Jython可实现Python动态编译为Java字节码,在不牺牲交互性的前提下,提升动态语言程序的执行效率
在Jython中可以继承已有的Java类,并有效的使用抽象类
可选的静态编译,允许创建applets, servlets, beans
Bean属性使得Java包在Jython中使用更为方便
在Jython中可以直接对Java类进行调用,与Java程序相比,Jython的实现代码量大大减少,同时在Jython中不必像Java那样声明类型,动态类型支持类型在运行时决定。Jython不仅赋予开发者所有可以调用的Python库,同时也为开发者引入庞大的Java类库,可以使开发者享用Java丰盛的资源。
即将发布1.0版本的Python Web开发框架Django目前也可以运行在Jython之上。Jim Baker在其Blog上撰文展示了Django向Jython平台的迁移情况,迁移时针对各文件的 测试结果也可随时查看。
Django被认为是”具有整齐务实设计的快速Web开发框架”,与Rails相似但同时也拥有超越Rails的亮点。如果感兴趣Django的开发,请移步IBM DeveloperWorks查看我之前撰写的一篇简短的入门教程。可以预计,伴随Django 1.0的推出和越来越多开发者的加盟,Django向Jython的迁移可能将成为吸引开发者使用Jython的杀手级应用。
http://www.builder.com.cn/2008/0805/1038892.shtml
lizhe1985收录,使用标签:Web开发,时间:2008-8-6 15:00:36 | 相关网摘,我也收藏
来源:IT专家网
一、 简介
AJAX,一个异步JavaScript和XML的缩略词,是最近出来的技术词语。异步意味着你可以经由超文本传输协议(HTTP)向一个服务器发出请求并且在等待该响应时继续处理另外的数据。这就意味着,例如,你可以调用一个服务器端脚本来从一个数据库中以XML方式检索数据,把数据发送到存储在一个数据库的服务器脚本,或者简单地装载一个XML文件以填充你的Web站点而不需刷新该页面。然而,在这项新技术提供巨大能力的同时,它也引起了在"Back"按钮问题上的很多争论。本文将帮助你确定在真实世界中何时使用AJAX是最佳选择。
首先,我假定你对缩略词JavaScript和XML部分有一个基本了解。尽管你能通过AJAX请求任何类型的文本文件,但是我在此主要集中讨论XML。我将解释怎样在真实世界中使用AJAX以及怎样在一个工程中评估它的价值。在你读完本文后,你将会明白什么是AJAX,在什么情况下,为什么以及怎样使用这项技术。你将要学习,在保持给用户提供直观体验的同时怎样创建对象,发出请求以及定制响应。
我已创建了一个适合于本文的示例工程(你可以下载源代码)。这个示例实现了一个简单的请求-它装载一个包含页面内容的XML文件并且分析数据以把它显示在一个HTML页面中。
二、 常规属性和方法
表1和2提供了一个属性和方法的概述-它们为Windows Internet Explorer 5,Mozilla,Netscape 7,Safari 1.2,和Opera等浏览器所支持。
表1属性
属性 描述
onreadystatechange 当请求对象变化时该事件处理器激活。
readyState 返回指示对象的当前状态的值。
responseText 来自服务器的响应串的版本。
responseXML 来自服务器的响应的DOM兼容的文档对象。
status 来自服务器的响应的状态码。
statusText 以一个字符串形式返回的状态消息。
表2方法
方法 描述
Abort() 取消当前HTTP请求。
getAllResponseHeaders() 检索所有的HTTP头值。
getResponseHeader("headerLabel") 从响应体中检索一个HTTP头部的值。
open("method","URL"[,asyncFlag[,"userName"[,"password"]]]) 初始化一个MSXML2.XMLHTTP请求,并从该请求指定方法,URL和认证信息。
send(content) 发送一个HTTP请求到服务器并接收响应。
setRequestHeader("label", "value") 指定一个HTTP头的名字。
三、 从哪里开始
首先,你需要创建XML文件-后面我们对之进行请求并作为页面内容进行分析。你正在请求的文件必须与目标工程驻留在相同的服务器上。
下一步,创建发出请求的HTML文件。当页面通过使用页面主体中的onload方法进行加载时,该请求发生。接着,该文件需要一个有ID的div标签,这样当我们准备好要显示内容时就可以对之进行定位。当你做完所有这些,你的页面的主体看上去如下:
<body onload="makeRequest('xml/content.xml');">
<div id="copy"></div>
</body>
四、 创建请求对象
为了创建请求对象,你必须检查是否浏览器使用XMLHttpRequest或ActiveXObject。这两个对象之间的主要区别在于使用它们的浏览器。Windows IE 5 及以上版本使用ActiveX对象;而Mozilla,Netscape 7,Opera和Safari 1.2及以上版本使用XMLHttpRequest对象。另外一个区别是你创建对象的方式:Opera,Mozilla,Netscape和Safari允许你简单地调用该对象的构造器,但是Windows IE需要把对象的名字传递到ActiveX构造器中。下面是怎样创建代码来决定要使用哪个对象和怎样创建它的示例:
if(window.XMLHttpRequest)
{ request = new XMLHttpRequest();}
else if(window.ActiveXObject)
{ request = new ActiveXObject("MSXML2.XMLHTTP");}
五、 发出请求
现在既然你已经创建了你的请求对象,那么你已经为向服务器发出请求作了准备。创建一个到事件处理器的参考以听取onreadystatechange事件。然后,该事件处理器方法将在状态发生变化时作出响应。一旦我们完成请求,我们就开始创建这个方法。打开连接以GET或POST一个定制的URL-在此是一个content.xml,并且设置一个布尔定义-是否你想要进行异步调用。
现在到了发出请求的时间了。在这个示例中,我使用了null,因为我们使用的是GET;为了使用POST,你需要使用下面这个方法发出一个查询串:
request.onreadystatechange = onResponse;
request.open("GET". url, true);
request.send(null);
六、 定制加载和错误处理消息
你为onreadystatechange方法创建的事件处理器正是集中进行加载和处理错误的场所。现在到了考虑用户并针对他们与之交互的内容的状态提供反馈的时候了。在这个实例中,我针对所有的装载状态代码提供反馈,并且也对最经常发生的错误处理状态代码提供一些基本的反馈。为了显示请求对象的当前状态,readyState属性包括显示在下表中的一些值。
值 描述
0 未初始化,对象没有用数据进行初始化。
1 装载中,对象正在装载它的数据。
2 装载结束,对象完成了它的数据的装载。
3 可交互,用户能与对象交互了,尽管它还没有装载结束。
4 完成,对象已经完全被初始化。
W3C中有很长的一串有关HTTP状态代码的定义。我选择了两个状态代码:
?200:请求成功了。
?404:服务器没有找到与所请求的文件相匹配的任何东西。
最后,我检查任何另外的状况代码-它们将生成一个错误并提供一个一般错误信息。下面是一个代码示例-你可以用之来处理这些情况。注意,我在定位我们前面在HTML文件的主体中创建的div ID并且对它应用装载和/或错误信息-通过innerHTML方法-这个方法用于设置在div对象的开始和结束标签之间的HTML:
if(obj.readyState == 0)
{ document.getElementById('copy').innerHTML = "Sending Request...";}
if(obj.readyState == 1)
{ document.getElementById('copy').innerHTML = "Loading Response...";}
if(obj.readyState == 2)
{ document.getElementById('copy').innerHTML = "Response Loaded...";}
if(obj.readyState == 3)
{ document.getElementById('copy').innerHTML = "Response Ready...";}
if(obj.readyState == 4){
if(obj.status == 200){ return true; }
else if(obj.status == 404)
{
// 添加一个定制消息或把用户重定向到另外一个页面
document.getElementById('copy').innerHTML = "File not found";
}
else
{document.getElementById('copy').innerHTML = "There was a problem retrieving the XML."; }
}
当状况代码为200时,这意味着请求成功。下面开始进行响应了。
七、分析响应
当你准备好分析来自请求对象的响应时,真正的工作开始了。现在你可以用你请求的数据开始工作。仅为测试目的,在开发期间,可以使用responseText和responseXML属性来显示来自响应的原始数据。为了存取XML响应中的结点,首先使用你创建的请求对象,定位到responseXML属性以检索(你可能已经猜测出来)来自响应的XML。定位到documentElement-它检索一个到XML响应的根结点的参考。
var response = request.responseXML.documentElement;
现在既然你有了到响应的根结点的参考,那么你可以使用getElementsByTagName()以结点名字来检索childNodes。下面一行用一个头部的nodeName来定位一个childNode:
response.getElementsByTagName('header')[0].firstChild.data;
使用firstChild.data可以允许你存取该元素中的文本:
response.getElementsByTagName('header')[0].firstChild.data;
下面是怎样创建这些代码的完整的例子:
var response = request.responseXML.documentElement;
var header = response.getElementsByTagName('header')[0].firstChild.data;
document.getElementById('copy').innerHTML = header;
八、需求分析
现在既然你知道怎样使用AJAX的基础知识,那么下一步就是决定是否在一工程使用它。须记住的最重要的事情是,在你还没有刷新页面时你无法使用"Back"按钮。为此,可以先专注于你的工程中的一小部分-它能够从使用这种类型的交互中受益。例如,你可以创建一个表单-它在用户每次输入一个输入字段或一个字母时查询一个脚本以便进行实时校验。你可以创建一个拖放页面-在释放一项时,它能够把数据发送到一个脚本中并把该页面的状态保存到一个数据库中。使用AJAX的理由毫无疑问是存在的;并且这种使用无论对开发者还是用户都会带来益处;这全依赖于具体的条件和执行情况。
还有其它方法可用来解决"Back"按钮的问题,例如使用Google Gmail-它现在能够为你的操作提供一种撤消功能而不刷新该页面。以后还会出现许多更具创造性的例子-它们将通过提供给开发者创建独特实时的体验的手段给用户带来更大的好处。
九、结论
尽管AJAX允许我们构建新的和改进的方式来与一个WEB页面进行交互;但是作为开发者,我们需要牢记产品是不考虑技术的;它关心的是用户以及其如何与用户进行交互。没有了用户群,我们构建的工程毫无用处。基于这个标准,我们就能评估应该使用什么技术以及何时使用它们来创建对相应用户有用的应用。
http://webservices.ctocio.com.cn/wsjavtec/25/8247525.shtml
lizhe1985收录,使用标签:无线移动,时间:2008-8-6 14:49:37 | 相关网摘,我也收藏
来源:http://www.blogjava.net/hadeslee/archive/2008/08/04/219945.html
在写J2ME程序的时候,我们一般都希望在真机运行的时候能有一些调试信息,一般在模拟器上运行的话,可以通过System.out.println来输出一些信息,但是在真机上运行的话,就看不到了,因为手机没有控制台啊.那时候如果想确认一些代码的执行情况,经常会用Alert弹出对话框的形式来实现,但是它也有一个不好的地方,那就是当有多个Alert的时候,后面的Alert会把前面的Alert给覆盖掉.后来想,能不能以日志的形式保存起来呢,然后再查看日志呢.参考了LWUIT的框架的LOG,好像它现在的源码还下载不到,只是查看了它的API,觉得用一个管理类通过静态方法统一来管理LOG是很好的一种方法,并且还支持自定义的LOG记录器以及自定义的log显示器.
代码如下:
首先是Logger,它是一个接口,它提供了日志的记录器所要做的一些事情.
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package com.hadeslee.insurance.mobile.log;
/**
* 一个日志生成器要实现的接口
* @author hadeslee
*/
public interface Logger {
public static final int FINE = 0;
public static final int INFO = 10;
public static final int DEBUG = 20;
public static final int WARNING = 30;
public static final int ERROR = 40;
/**
* 实现的log方法
* @param level 级别
* @param info 内容
*/
public void log(int level, String info);
/**
* 得到所有的日志内容
* @return 内容
*/
public String getLogContent();
/**
* 清除当前的日志
*/
public void clearLog();
}
然后是日志显示器,因为日志记录了之后,肯定是要被我们显示出来的,想要如何显示,可以实现此接口.
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package com.hadeslee.insurance.mobile.log;
/**
* 一个用于显示日志的接口,此接口用于LogManager来调用
* @author hadeslee
*/
public interface LogShower {
/**
* 显示日志,由LogManager调用此方法来显示日志
* 显示日志可以有多种方法,比如可以用列表来显示
* 也可以用TextArea来显示,还可以用Canvas来显示
* @param logContent 日志内容
* @param action 返回的时候要做的动作
*/
public void showLog(String logContent, BackAction action);
/**
* 内部的一个静态接口,实现此接口以供LogShower在
* 点击了返回之后,要做的事情
*/
public static interface BackAction {
/**
* 点击返回之后要做的事情
*/
public void back();
}
}
最后一个类就是LogManager,它只提供了静态方法供调用,它内部有一个默认的Logger实现和一个默认的LogShower实现,在此类中的Shower实现可能不通过,因为我用到了LWUIT里面的一些组件,这个可以自行修改,添加自己的默认实现.
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package com.hadeslee.insurance.mobile.log;
import com.hadeslee.insurance.mobile.log.LogShower.BackAction;
import com.hadeslee.insurance.mobile.util.Util;
import com.sun.lwuit.Command;
import com.sun.lwuit.Form;
import com.sun.lwuit.TextArea;
import com.sun.lwuit.events.ActionEvent;
import com.sun.lwuit.layouts.BorderLayout;
/**
* 日志管理器,所有的日志通过此日志管理器
* 进行统一的调用
* 此类相关的两个接口都有相应的默认实现,当然
* 也可以替换实现
* @author hadeslee
*/
public final class LogManager {
private static Logger log = new LoggerImpl();//具体的日志实现类
private static LogShower shower = new LogShowerImpl();//日志显示者
private LogManager() {
}
/**
* 安装自己实现的日志记录器
* @param log 新的日志记录器
*/
public static void install(Logger log) {
LogManager.log = log;
}
/**
* 安装自己实现的日志显示器
* @param shower 新的日志显示器
*/
public static void install(LogShower shower) {
LogManager.shower = shower;
}
/**
* 记录INFO级别的日志
* @param info 日志内容
*/
public static void info(String info) {
log.log(Logger.INFO, info);
}
/**
* 记录DEBUG级别的日志
* @param info 日志内容
*/
public static void debug(String info) {
log.log(Logger.DEBUG, info);
}
/**
* 记录ERROR级别的日志
* @param info 日志内容
*/
public static void error(String info) {
log.log(Logger.ERROR, info);
}
/**
* 记录WARNING级别的日志
* @param info 日志内容
*/
public static void warning(String info) {
log.log(Logger.WARNING, info);
}
/**
* 记录FINE级别的日志
* @param info 日志的内容
*/
public static void fine(String info) {
log.log(Logger.FINE, info);
}
/**
* 显示当前日志管理器的日志
* @param back 要返回的时候,做的动作
*/
public static void showLog(BackAction back) {
shower.showLog(log.getLogContent(), back);
}
/**
* 清除当前日志管理器的日志
*/
public static void clearLog() {
log.clearLog();
}
static class LogShowerImpl implements LogShower {
public void showLog(String logContent, final BackAction action) {
Form form = new Form("日志内容");
form.setScrollable(false);
final TextArea ta = new TextArea(logContent, 5, 10);
ta.setEditable(false);
form.addCommand(new Command("返回") {
public void actionPerformed(ActionEvent ae) {
action.back();
}
});
form.addCommand(new Command("清除") {
public void actionPerformed(ActionEvent ae) {
LogManager.clearLog();
ta.setText("");
}
});
form.setLayout(new BorderLayout());
form.addComponent(BorderLayout.CENTER, ta);
form.show();
}
}
static class LoggerImpl implements Logger {
private StringBuffer sb;
public LoggerImpl() {
sb = new StringBuffer(1024);
}
public void log(int level, String info) {
sb.append(getPrefix()).append("\n").
append(getLevelName(level)).append(":").
append(info).append("\n");
}
private String getPrefix() {
return "[" + Thread.currentThread() + "-" + Util.getCurrentTime() + "]";
}
private String getLevelName(int level) {
switch (level) {
case FINE:
return "FINE";
case INFO:
return "INFO";
case DEBUG:
return "DEBUG";
case WARNING:
return "WARNING";
case ERROR:
return "ERROR";
default:
return "UNKNOWN";
}
}
public String getLogContent() {
return sb.toString();
}
public void clearLog() {
sb.delete(0, sb.length());
}
}
}
以上的默认实现中,日志是记录在内存中的,可以用clearLog方法把它清除,当然,也可以自定久记录在RMS里面的日志,并且也要实现相关的clearLog的方法,添加这个方法是因为日志内容不可能让它永远无休止的增长.然后LogManager的showLog方法,就是利用LogShower的实现,把日志显示出来,还有一点,显示日志以后,为了能让LogShower知道,如何返回上一个界面,这里还应该实现一个BackAction方法.
http://www.blogjava.net/hadeslee/archive/2008/08/04/219945.html
lizhe1985收录,使用标签:Web开发,时间:2008-8-4 15:16:48 | 相关网摘,我也收藏
来源:开发者在线
Sun一直走在开源领域的前列,这次的JavaFX是一个构建于Java技术之上完整的运行时环境,可以用来交付到桌面、移动设备、手持设备和电视等环境的富互联网应用(RIA)。在这些里的每一个硬件平台上,这个新技术都提供一个脚本语言,以结合Java的威力用于快速开发有Flash效果和交互式图形用户接口的应用程序。但是这还远不是JavaFX所展示的全部,它还代表了Sun的一个里程碑式新商业策略和一门新前沿技术。InfoQ就此采访了Sun的首席技术官Bob Brewin,他解释了这一技术对Sun、Java开发者以及使用者等这些JavaFX所真正关注的对象的意义。
问到是什么驱动了Sun在这个时候向市场推出这个技术,Brewin没有像常人所想的那样回答说是为了更丰富、更快速开发桌面Web内容的需要,而是表示说JavaFX是对Flash和Ajax增长的一种回应,现在移动手机和电视屏幕比桌面浏览器离用户更近,在他的思想里,这些才是JavaFX最重要的驱动力。这正好印证了Sun在大会上所讲的将注意力放在消费者产品上的观点,这样Sun就有可能为Java技术占领最大范围的市场。Brewin指出,现在世界上大部分人在访问互联网内容时的首要选择不是桌面计算机,而是移动手机。
根据目标硬件平台的不同,JavaFX或者构建在Java SE上或者Java ME上,但是以Mobile的眼光来看,它更像是一个可以制作交互式内容的产品化脚本接口——一个设备上的完整操作系统,包括Linux内核和本地服务等。它应该被看作Windows Mobile、Symbian OS和其他移动Linux平台的竞争对手。在移动手机上运行时,JavaFX Mobile能实现内嵌在大多数移动手机里的电话服务。所以以这个观点来看,你就能明白这一技术和Sun最近从SavaJe处所获技术的关系。Linux 内核和CDC Personal Basis Profile Java runtime的目标是与高级智能手机一个级别的手持设备,以及电视和其他连接设备,但是Brewin说随着运行时的优化和完善,Sun也会将此应用到 CLDC MIDP等“功能手机(Feature Phone)”。因为整个JavaFX软件系列都将会开源,所以Sun期望能通过出售完整的设备平台来增加许可(License)收入,而不仅仅是 Java运行时环境。很多项目都在进行之中,甚至包括Solaris内核这一现在应用在大多数移动设备都有的ARM处理器上的简易操作系统。
问到JavaFX Script的起源,Brewin回答说这个用于脚本化交互式GUI的语言是由Sun工程师Chris Oliver所开发,当时他还在SeeBeyond技术公司(2005年被Sun收购)。很多开发者可能都熟悉它从前的名字——F3。JavaFX Script静态类型化并提供编译时错误检查机制,使得它有可能被用于开发可支持代码完成、超链接、重构等功能的强大工具。其他的语言特性包括类型推断(type-inference)、声明语法,以及完全支持2D图像、标准Swing组件和声明动画的自动数据绑定等。你还可以导入Java类,创建新的 Java对象,调用它们的方法,以及实现Java接口等。
相应的制作工具也在开发之中,但是在大会上Chris展示了一个由他自己开发的可用于JavaFX脚本化的交互式GUI构建器。这个工具包含在 JavaFX面向开发者社区所发布的初始版本里。因为脚本语言和工具在所有的目标平台上都保持一致,所以JavaFX看上去能实现Sun的“一次编写,处处运行”的承诺,甚至比Java自己做的还好。当然,在JavaFX脚本里被导入和调用Java对象会依赖提供的Java运行时。对于为只有有限资源和缺少Swing或者AGUI类库支持的CLDC设备所发布的JavaFX版本而言,它的功能某种程度上肯定会减弱。
桌面JavaFX现在所要考虑的一个问题是部署。对于从前没有安装过JRE的用户来说,JRE体积太大,而且现在从浏览器上进行按需安装的用户体验也不是特别好。Brewin在演讲中提出了一个可行的解决方案,在Java 6 Update 2里将会为JRE引入一种新型的部署模型,初次下载时体积非常小,只有在需要时才下载其他的JRE组件。他说这个概念非常类似Java 7中提到的Java Kernel项目。被问到类似的部署模型会不会用在Java ME上时,Brewin说当然有可能,这会由Java Community Process来推进。
让他对JavaFX和Adobe Flash做个对比时,Brewin回答说这是一个“苹果和橘子”的比较。Flash有很好的功能,但它永远不能交付Java类库的大部分功能,而 JavaFX可以。他说更好的比较是在JavaFX和Apollo(Adobe将要为桌面RIA提供的一个运行时)之间。在这个擂台上,他认为 JavaFX会非常有竞争力。
http://www.builder.com.cn/2008/0802/1032713.shtml
lizhe1985收录,使用标签:Web开发,时间:2008-8-4 15:15:27 | 相关网摘,我也收藏
来源:开发者在线
在五月份召开的JavaOne大会上,Sun微系统公司宣布了一个新的产品系列JavaFX,由JavaFX脚本和JavaFX Mobile组成。JavaFX脚本语言被用来让使用Java“Swing”用户接口库来创建富用户接口变得更加容易,该用户接口可以在支持Java标准版的任何设备上运行。Sun想要将该语言作为开放源代码项目发布。需要注意人们习惯将JavaFX脚本称为JavaFX或者JFX,但是Sun还是将JavaFX Mobile放到了JavaFX产品线中。我将在这篇文章中使用JFX来指代JavaFX脚本。
为什么又要一个脚本语言?
如今脚本语言当然受到了很多的压力。在以前的文章中,我曾经写过Ruby、JavaScript、Python、JavaServer Pages和Linden Scripting Language等Web service客户端。这些不同的语言共同的目的是尝试着通过提供一种连接现有组件的简单方式来让复杂应用的编写变的更加容易。在JFX的情况中,它最关心的组件是Swing用户接口组件,该组件最初出现在Java标准库1.2版以补充相当原始的Java AWT工具。
JFX基础
这个语言支持常见的变量类型,比如字符串、整型、浮点型和布尔值。对于list和array的扩展支持的语法,在我看来非常强大。这个语言还提供了异常的创建和处理,并且引入了新的想法,即任何对象可以被抛出,不仅仅是标准的Java Throwable类型。JFX脚本还可以导入Java类、创建Java对象和调用他们的方法。
JFX对象通过声明的方法来创建。这对于那些为“swing”Java用户接口类提供简化的class非常有用。我们在下面的完整脚本中查看一下JFX对象是如何通过声明的方式来创建的。
import javafx.ui.*;
Frame {
title: "Hello World from JavaFX"
width: 200
height: 80
content: Button {
text: "Hello World"
}
visible: true
}
在这个例子中,Frame和Button是用来隐藏将在屏幕上显示出来的JFrame和JButton对象的创建细节的脚本类型。这个Frame类有名为“title”、“width”、“height”、“content”和“visible”的公共“属性”,它们都在声明中被设置了。
消息处理问题
JFX也有每一个图形用户接口工具都会遇到的问题。点击按钮之类的用户事件一定不能和需要长时间执行任务的事件处理线程绑定,因为在该任务执行的时候,这个接口会毫无反应。JFX提供了“do”和“do later”原语来处理这个问题。我使用一段脚本来试验JFX显示出从天气预报服务站点检索出来的数据,其中使用了“do later”。首先,我定义了一个叫做WeatherData的JFX类。这个类有两个属性和一个操作。
import javafx.ui.*;
import java.net.URL;
import java.lang.StringBuffer ;
import java.lang.System;
import java.io.InputStreamReader;
import java.io.BufferedReader;
class WeatherData ...{
attribute source: String ;
attribute text: String ;
operation update();
}
http://www.builder.com.cn/2008/0802/1032714.shtml
lizhe1985收录,使用标签:Web开发,时间:2008-8-4 14:24:03 | 相关网摘,我也收藏
来源:IT专家网
一、概述
在Web应用中,有些报表的生成可能需要数据库花很长时间才能计算出来;有的网站提供天气信息,它需要访问远程服务器进行SOAP调用才能得到温度信息。所有这一切都属于复杂信息的例子。在Web页面中加入过多的复杂信息可能导致Web服务器、数据库服务器负荷过重。JSP代码块缓冲为开发者带来了随意地增加各种复杂信息的自由。
JSP能够在标记库内封装和运行复杂的Java代码,它使得JSP页面文件更容易维护,使得非专业开发人员使用JSP页面文件更加方便。现在已经有许多标记库,它们或者是商业产品,或者是源代码开放产品。但这些产品中的大多数都只是用标记库的形式实现原本可以用一个简单的Java Scriptlet实现的功能,很少有产品以某种创造性的方式使用定制标记,提供在出现JSP定制标记库之前几乎不可能实现的用法。
OSCache标记库由OpenSymphony设计,它是一种开创性的JSP定制标记应用,提供了在现有JSP页面之内实现快速内存缓冲的功能。虽然已经有一些供应商在提供各种形式的缓存产品,但是,它们都属于面向特定供应商的产品。OSCache能够在任何JSP 1.1兼容的服务器上运行,它不仅能够为所有用户缓冲现有JSP代码块,而且能够以用户为单位进行缓冲。OSCache还包含一些提高可伸缩性的高级特性,比如:缓冲到磁盘,可编程的缓冲刷新,异常控制,等等。另外,正如OpenSymphony的其他产品,OSCache的代码也在一个开放源代码许可协议之下免费发行。
本文以一个假想的拍卖网站设计过程为例,介绍OSCache的工作过程。这个假想的Web网站将包含:一个报告最近拍卖活动的管理页面;一个功能完整、带有各种宣传信息的主页;一个特殊的导航条,它包含了用户所有尚未成交的拍卖活动信息。
二、管理页面
拍卖网站包含一个管理报表,数据库服务器需要数秒时间才能创建这样一个报表。报表生成时间长这一点很重要,因为我们可能让多个管理员监视系统运行情况,同时又想避免管理员每次访问时都重新生成这个报表。为了实现这一点,我们将把整个页面封装到一个应用级的缓冲标记之内,这个缓冲标记每隔1小时刷新。其他供应商提供的一些产品也具有类似的功能,只是OSCache比它们做得更好。
为简单计,我们将不过多地关注格式问题。在编写管理页面时,我们首先把标记库声明加入到页面:
< %@ taglib uri="cachetags" prefix="cache" %>
接下来我们要用cache标记来包围整个页面。cache标记的默认缓冲时间是1小时。
< cache:cache> .... 复杂的管理报表 .... < /cache:cache>
现在管理页面已经被缓冲。如果管理员在页面生成后的一个小时之内再次访问同一页面,他看到的将是以前缓存的页面,不需要由数据库服务器再次生成这个报表。
三、主页
拍卖网站的主页显示网站活动情况,宣传那些即将结束的拍卖活动。我们希望显示出正在进行的拍卖活动数量,当前登录用户数量,在短期内就要结束的拍卖活动的清单,以及当前时间。这些信息有着不同的时间精确度要求。网站上的拍卖活动通常持续数天,因此我们可以把缓冲有效拍卖活动数量的时间定为6个小时。用户数量的变化显然要频繁一些,但这里我们将把这个数值每次缓冲15分钟。最后,我们希望页面中显示的当前时间总是精确的页面访问时间。
在主页中声明标记库之后,我们首先以不带缓冲的方式直接输出当前日期:
现在是:< %=new java.util.Date()%>
接下来,我们要显示一个清单,列出那些将在短期内结束的拍卖活动:
< cache:cache> < ul> < % // 构造一个包含最近拍卖活动的Iterator Iterator auctions = .... while (auctions.hasMore()) { Auction auction = (Auction)auctions.next(); %>< li>< %=auction%>< /li%< } %> < /ul> < /cache:cache>
最后,我们希望显示出正在进行的拍卖活动的数量,这个数字需要缓冲6小时。由于cache标记需要的是缓冲数据的秒数,我们把6小时转换成21600秒:
< cache:cache time="21600"> < % //查询数据库得到拍卖活动总数 int auctionCount = .... %> 本网站正在进行的拍卖活动有< %=auctionCount%>个! < /cache>
可以看到,我们只用少量的代码就构造出了一个带有复杂缓冲系统的主页。这个缓冲系统对页面各个部分分别进行缓冲,而且各个部分的缓冲时间完全符合它们各自的信息变化频繁程度。由于有了缓冲,现在我们可以在主页中放入更多的内容;而在以前没有缓冲的情况下,主页中放入过多的内容会导致页面访问速度变慢,甚至可能给数据库服务器带来过重的负载。
四、导航条
假设在规划网站的时候,我们决定在左边导航条的下方显示购物车内容。我们将显示出用户所拍卖的每一种商品的出价次数和当前报价,以及所有那些当前用户出价最高的商品的清单。
我们利用会话级的缓冲能力在导航条中构造上述功能。把下面的代码放入模板或者包含文件,以便网站中的其他页面引用这个导航条:
< cache:cache key="navbar" scope="session" time="300"> < % //提取并显示当前的出价信息 %> < /cache:cache>
在这里我们引入了两个重要的属性,即key和scope。在本文前面的代码中,由于cache标记能够自动为代码块创建唯一的key,所以我们不需要手工设置这个key属性。但在这里,我们想要从网站的其余部分引用这个被缓冲的代码块,因此我们显式定义了该cache标记的key属性。第二,scope属性用来告诉cache标记当前代码块必须以用户为单位缓冲,而不是为所有用户缓冲一次。
在使用会话级缓冲时应该非常小心,应该清楚:虽然我们可以让复杂的导航条减少5倍或10倍的服务器负载,但它将极大地增加每个会话所需要的内存空间。在CPU能力方面增加可能的并发用户数量无疑很理想,但是,一旦在内存支持能力方面让并发用户数量降低到了CPU的限制之下,这个方案就不再理想。
正如本文前面所提到的,我们希望从网站的其余部分引用这个缓冲的代码块。这是因为,当一个用户增加了一个供拍卖的商品、或者出价竞购其他用户拍卖的商品时,我们希望刷新缓冲,使得导航条下一次被读取时具有最新的内容。虽然这些数据可能因为其他用户的活动而改变,但如果用户在网站上执行某个动作之后看到自己的清单仍未改变,他可能会感到非常困惑。
OSCache库提供的flush标记能够刷新缓冲内容。我们可以把下面的代码加入到处理用户动作且可能影响这一区域的页面之中:
< cache:flush key="navbar" scope="session" />
当用户下次访问它时,navbar缓冲块将被刷新。
至此为止,我们这个示例网站的构造工作已经完成且可以开始运行。下面我们来看看OSCache的异常处理能力。即使缓冲的内容已经作废,比如在缓冲块内出现了Java异常,OSCache标记库仍旧允许我们用编程的方法显示这些内容。有了这种异常控制功能,我们可以拆除数据库服务器和Web服务器之间的连接,而网站仍能够继续运行。JSP 1.2规范引入了TryCatchFinally接口,这个接口允许标记本身检测和处理Java异常。因此,标记可以结合这种异常处理代码,使得JSP页面更简单、更富有条理。
OpenSymphony正在计划实现其他的缓冲机制以及一个可管理性更好的主系统,它将使我们能够对缓冲使用的RAM和磁盘空间进行管理。一旦有了这些功能,我们就能够进一步提高网站的响应速度和可靠性。
【结束语】
OSCache能够帮助我们构造出更丰富多彩、具有更高性能的网站。有了OSCache标记库的帮助,现在我们能够用它解决一些影响网站响应能力的问题,比如访问量高峰期、数据库服务器负荷过重等。
http://webservices.ctocio.com.cn/wsjavtec/186/8244686.shtml
lizhe1985收录,使用标签:无线移动,时间:2008-8-1 15:07:00 | 相关网摘,我也收藏
碰到两个问题,都是跟mmp文件有关的:
1,打包后的程序太大。
把mmp中改成16位色,效果和24位色差不多。sis安装文件的大小却从265k变成了105k。
2,有些图片是彩色的,有些却是黑白的。
SOURCE c16后面注意不要多了个 “,1 “ ,意思应该是mask,当然有些黑白有些彩色了。
3,另外需要注意的一点就是图片相关的东西修改后需要手动删除Symbian目录下的mbm和mbg文件才会重新生成。比较好的办法是搜索(项目名字.mb*),然后全部删除后再重新生成。
START BITMAP Mobile517.mbm
HEADER
TARGETPATH \resource\apps
SOURCEPATH ..\gfx
SOURCE c16 Main.bmp Search.bmp Collection.bmp MainSearch.bmp MainCollection.bmp MainTour.bmp Tour.bmp
END
http://www.sf.org.cn/Article/Graphics/200807/21139.html
lizhe1985收录,使用标签:无线移动,时间:2008-8-1 15:06:06 | 相关网摘,我也收藏
N95硬件中隐藏了一个加速度传感器(Accelerometers),该硬件来自STMicroelectronics,型号为LIS302DL。加速度传感器用于将重力或者运动加速度变换为电信号,Accelerometers很可能是继GPS之后的下一个重量级的硬件。Forum Nokia Wiki上有最权威的描述:http://wiki.forum.nokia.com/index.php/N95_sensor
Accelerometers API首先在NokiaResearchCenter(http://research.nokia.com/projects/activity_monitor)发布,目前可以支持N95,N95 8GB,N93i,N82等手机.该plug-in只能用于研究和开发用途,并含有如下Capabilities,根据Symbian安全性规则,你的应用程序不能含有比他更多的Capabilities:
LocalServices ,Location ,NetworkServices ,ReadDeviceData ,ReadUserData
SurroundingsDD ,SwEvent ,UserEnvironment ,WriteDeviceData ,WriteUserData
如何使用Accelerometers plug-in API开发应用程序。
首先下载:http://research.nokia.com/files/N95_RD_Accelerometer.zip
1,安装配置:
需要将N95AccelerometerPlugin.sis安装到你的手机(目前可以支持N95,N95 8GB,N93i,N82)
在开发环境中,将RDAccelerometer.h和RDAccelerometerObserver.h头文件放到SDK的\epoc32\include目录中,将*.dso和*.lib文件复制到SDK的\epoc32\release\armv5\LIB目录中
2,具体使用:
- 将库文件RDAccelerometer.lib添加到你应用程序的工程中
- 在你需要的类中继承MRDAccelerometerObserver接口,并实现HandleAccelerationL()函数接收来自加速度传感器的数据
- 创建一个CRDAccelerometer实例,并将上面提到的类作为参数传入
- 当实例创建完成后,加速度传感器数据会自动通过HandleAccelerationL()方法发送到应用程序中。
参数含义如下(参考RDAccelerometerObserver.h 获取更多信息):
- 1G加速度等于64
- 0G加速度等于0
- (-1G)加速度等于(-63)
- 删除CRDAccelerometer实例就可以停止接收来自传感器的数据
3,开发经验:
- 即使你将手机放在桌上不动,通过HandleAccelerationL()得到的数据还是略为有所改变。
- 每秒钟会有30帧的数据传入到HandleAccelerationL()中,非常耗电。
- 应用程序中尽量早地关闭传感器,在需要的时候再开启。
http://www.sf.org.cn/Article/symbiandev/200807/21135.html
lizhe1985收录,使用标签:无线移动,时间:2008-8-1 15:04:03 | 相关网摘,我也收藏
一般而言有如下几种方法:
1,在Container的ConstructL中,调用SetExtentToWholeScreen ();
缺点是一按下“选项”,StatusPane和CBA又出来了。
2,在View的DoActivateL中,调用AppUi()->ApplicationRect()。
同样有如上的问题。
iMobile517MainContainer = CMobile517MainContainer::NewL(AppUi()->ApplicationRect(), NULL, this );
3,通过隐藏Status Pane和CBA,这种方法比较灵光(需要和2同时使用)!
在Container的ConstructL函数中调用:
CEikStatusPane* statusp = iEikonEnv->AppUiFactory()->StatusPane();
if(statusp) statusp->MakeVisible(EFalse);
iEikonEnv->AppUiFactory()->Cba()->MakeVisible(EFalse);
http://www.sf.org.cn/Article/UserInterface/200807/21142.html
lizhe1985收录,使用标签:Web开发,时间:2008-8-1 14:59:02 | 相关网摘,我也收藏
来源:http://www.cnblogs.com/libinqq/archive/2008/07/31/1257699.html
很长时间没看 正则表达式了,碰巧今天用到,温故知新了一把 看书学习吧
50% 的举一反三练习中的原创。
一 javascript正则表达式的基本知识
1 javascript 正则对象创建 和用法
声明javascript 正则表达式
var reCat = new RegExp("cat");
你也可以
var reCat = /cat/; //Perl 风格 (推荐)
2 学习最常用的 test exec match search replace split 6个方法
1) test 检查指定的字符串是否存在
var data = "123123";
var reCat = /123/gi;
alert(reCat.test(data)); //true
//检查字符是否存在 g 继续往下走 i 不区分大小写
2) exec 返回查询值
var data = "123123,213,12312,312,3,Cat,cat,dsfsdfs,";
var reCat = /cat/i;
alert(reCat.exec(data)); //Cat
3)match 得到查询数组
var data = "123123,213,12312,312,3,Cat,cat,dsfsdfs,";
var reCat = /cat/gi;
var arrMactches = data.match(reCat)
for (var i=0;i < arrMactches.length ; i++)
{
alert(arrMactches[i]); //Cat cat
}
4) search 返回搜索位置 类似于indexof
var data = "123123,213,12312,312,3,Cat,cat,dsfsdfs,";
var reCat = /cat/gi;
alert(data.search(reCat)); //23
5) replace 替换字符 利用正则替换
var data = "123123,213,12312,312,3,Cat,cat,dsfsdfs,";
var reCat = /cat/gi;
alert(data.replace(reCat,"libinqq"));
6)split 利用正则分割数组
var data = "123123,213,12312,312,3,Cat,cat,dsfsdfs,";
var reCat = /\,/;
var arrdata = data.split(reCat);
for (var i = 0; i < arrdata.length; i++)
{
alert(arrdata[i]);
}
3 学习下 简单类 负向类 范围类 组合类
//简单类
var data = "1libinqq,2libinqq,3libinqq,4libinqq";
var reCat = /[123]libinqq/gi;
var arrdata = data.match(reCat);
for (var i = 0; i < arrdata.length; i++)
{
alert(arrdata[i]); // 1libinqq 2libinqq 3libinqq
}
//负向类
var data = "alibinqq,1libinqq,2libinqq,3libinqq,4libinqq"; //\u0062cf
var reCat = /[^a123]libinqq/gi;
var arrdata = data.match(reCat);
for (var i = 0; i < arrdata.length; i++)
{
alert(arrdata[i]); //4libinqq
}
//范围类
var data = "libinqq1,libinqq2,libinqq3,libinqq4,libinqq5"; //\u0062cf
var reCat = /libinqq[2-3]/gi;
var arrdata = data.match(reCat);
for (var i = 0; i < arrdata.length; i++)
{
alert(arrdata[i]); // libinqq2 libinqq3
}
//组合类
var data = "a,b,c,w,1,2,3,5"; //\u0062cf
var reCat = /[a-q1-4\n]/gi;
var arrdata = data.match(reCat);
for (var i = 0; i < arrdata.length; i++)
{
alert(arrdata[i]); // a b c 1 2 3
}
这些都是 js正则 最基本的使用方法,看不会的请复制到笔记本练习下,看会了再往下面看。
二 javascript 正则表达式是分组知识
1) 简单分组
Code
<script language="JavaScript">
<!--
/*正则表达式 简单的分组
举例 我们要查找字符串 MouseMouse
var reCat = /MouseMouse/gi;
尽管这是可以的,但是有点浪费。如果不知道Mouse 在字符串中到底出现几次时该怎么办,如果重复多次呢。
var reCat = /(mouse){2}/gi; 括号的意思列Mouse 将在一行连续出现2次。
*/
var data = "Ah-mousemouse";
var reCat = /(mouse){2}/gi;
var arrdata = data.match(reCat);
for (var i = 0; i < arrdata.length; i++)
{
alert(arrdata[i]);
}
//-->
</script>
2 复杂分组
Code
<script language="JavaScript">
<!--
/*正则表达式 复杂的分组
? 零次 或 一次
* 零次 或 多次
+ 最少一次 或 多次
*/
var data = "bb ba da bad dad aa ";
var reCat = /([bd]ad?)/gi; // 匹配出 ba da bad dad
var arrdata = data.match(reCat);
for (var i = 0; i < arrdata.length; i++)
{
alert(arrdata[i]);
}
// 同时 也不介意将分组放在分组中间
// var re = /(mom( and dad)?)/; 匹配出 mom 或 mon and daa
//-->
</script>
3 反向引用
Code
<script language="JavaScript">
<!--
/*正则表达式 反向引用*/
var sToMatch = "#123456789";
var reNumbers = /#(\d+)/;
reNumbers.test(sToMatch);
alert(RegExp.$1);
/*
这个例子尝试匹配后面跟着几个或多个数字的镑符合,并对数字进行分组
以存储他们。在调用 test 方法后,所有的反向引用都保存到了 RegExp 构造函数中
从 RegExp.$1(它保存了第一个反向引用)开始,如果还有第二个反向引用,就是
RegExp.$2,如果还有第三个反向引用存在,就是 RegExp.$3.依此类推。因为该组
匹配了 “123456780”,所以 RegExp.$1 中就存储了这个字符串。
*/
var sToChange = "1234 5678";
var reMatch = /(\d{4}) (\d{4})/;
var sNew = sToChange.replace(reMatch,"$2 $1");
alert(sNew);
/*
在这个例子中,正则表达式有两个分组,每一个分组有四个数字。在 replace() 方法的第二个参数
中,$2 等同于 “5678” ,而 $1 等同于 “1234”,对应于它们在表达式中的出现顺序。
*/
//-->
</script>
4 候选
Code
<script language="JavaScript">
<!--
/*正则表达式 候选 */
var sToMatch1 = "red";
var sToMatch2 = "black";
var reRed = /red/;
var reBlack = /black/;
alert(reRed.test(sToMatch1) || reBlack.test(sToMatch1));
alert(reRed.test(sToMatch2) || reBlack.test(sToMatch2));
/*
这虽然能完成任务,但是十分沉长,还有另一种方式就是正则表达式的候选操作符。
*/
var sToMatch1 = "red";
var sToMatch2 = "black";
var reRedOrBlack = /(red|black)/;
alert(reRedOrBlack.test(sToMatch1));
alert(reRedOrBlack.test(sToMatch2));
//-->
</script>
5 非捕获性分组
Code
<script language="JavaScript">
<!--
/*正则表达式 非捕获性分组
如果要创建一个非捕获性分组,只要在左括号的后面加上一个问号和一个紧跟的冒号:
*/
var sToMatch = "#123456789";
var reNumbers = /#(?:\d+)/;
reNumbers.test(sToMatch);
alert(RegExp.$1);
/*
这个例子的最后一行代码输出一个空字符串,因为该组是非捕获性的,
*/
var sToMatch = "#123456789";
var reNumbers = /#(?:\d+)/;
alert(sToMatch.replace(reNumbers,"abcd$1"));
/*
正因如此,replace()方法就不能通过 RegExp.$x 变量来使用任何反向引用,这段代码
输出的“abcd$1”而不是abcd123456789, 因为$1 在这里并不被看成是一个反向引用。
*/
//-->
</script>
6 前瞻
Code
<script language="JavaScript">
<!--
/*正则表达式 前瞻
前瞻 就和它名字一样,它告诉正则表达式运算器向前看一些字符而不是移动位置
*/
var sToMatch1 = "bedroom";
var sToMatch2 = "bedding";
var reBed = /bed(?=room)/;
alert(reBed.test(sToMatch1)); //true
alert(reBed.test(sToMatch2)); //false
//负向前瞻
var sToMatch1 = "bedroom";
var sToMatch2 = "bedding";
var reBed = /bed(?!room)/;
alert(reBed.test(sToMatch1)); //false
alert(reBed.test(sToMatch2)); //true
//-->
</script>
7 边界
Code
<script language="JavaScript">
<!--
/*正则表达式 边界
^ 行开头
$ 行结尾
\b 单词的边界
\B 非单词的边界
*/
var sToMatch = "Important word is the last one.";
var reLastWord = /(\w+)\.$/;
reLastWord.test(sToMatch);
alert(RegExp.$1); //one
/*
假如想查找一个单词,但要它只出现在行尾,则可以使用美元符号 ($)来表示它:
*/
var sToMatch = "Important word is the last one.";
var reLastWord = /^(\w+)/;
reLastWord.test(sToMatch);
alert(RegExp.$1); //Important
/*
在这个例子中,正则表达式查找行起始位置后的一个或多个单词字符。如果遇到非单词字符
匹配停止,返回 Important。 这个例子也可以用单词边界实现。
*/
var sToMatch = "Important word is the last one.";
var reLastWord = /^(.+?)\b/;
reLastWord.test(sToMatch);
alert(RegExp.$1); //Important
/*
这里,正则表达式用惰性量词来制定在单词边界之前可以出现任何字符,且可以出现一次或
多次(如果使用贪婪性量词,表达式就匹配整个字符串)。
*/
var data = " First second thind fourth fifth sixth ";
var reCat = /\b(\S+?)\b/g;
var arrdata = data.match(reCat);
for (var i = 0; i < arrdata.length; i++)
{
alert(arrdata[i]);
}
/*
使用单词边界可以方便地从字符串中抽取单词。
*/
//-->
</script>
8 多行模式
Code
<script language="JavaScript">
<!--
/*正则表达式 多行模式
要制定多行模式,只要在正则表达式想要匹配的行末的一个单词
*/
var data = " First second\n thind fourth\n fifth sixth";
var reCat = /(\w+)$/g;
var arrdata = data.match(reCat);
for (var i = 0; i < arrdata.length; i++)
{
alert(arrdata[i]);
}
/*
上面只返回一个单词 sixth,因为换行符阻挡了匹配,只能匹配行末的一个单词,
当然也可以使用 split() 方法将字符串分割成数组,但就得对每一行进行单独匹配。
以前不好好看书经常半吊子,看一半就仍了,导致用了好多 split, 其实很简单如下面
例子 只需要 m 参数进行多行匹配。
*/
var data = " First second\n thind fourth\n fifth sixth";
var reCat = /(\w+)$/gm;
var arrdata = data.match(reCat);
for (var i = 0; i < arrdata.length; i++)
{
alert(arrdata[i]);
}
//-->
</script>
至此结束,这些都是 javascript 正则表达式的基本方法,如果你看会了看复杂的正则你会有豁然开朗的感觉。
http://www.cnblogs.com/libinqq/archive/2008/07/31/1257699.html
lizhe1985收录,使用标签:信息化,时间:2008-8-1 13:24:15 | 相关网摘,我也收藏
来源:比特网
虚拟化就是把物理资源转变为逻辑上可以管理的资源,以打破物理结构之间的壁垒。未来,所有的资源都透明地运行在各种各样的物理平台上,资源的管理都将按逻辑方式进行,完全实现资源的自动化分配,而虚拟化技术就是实现它的理想工具。
虚拟技术的原理
虚拟技术需要解决服务器和操作系统的虚拟化、存储虚拟化、以及系统管理虚拟化等一系列问题。如今虚拟化开始从早期的存储虚拟化向服务器和操作系统的虚拟化以及整体的虚拟化发展。
虚拟化解决方案的底部是要进行虚拟化的计算机硬件,这台机器可能直接支持虚拟化,也可能不会直接支持虚拟化;那么就需要系统管理程序层的支持。系统管理程序,或称为 VMM,可以看作是平台硬件和操作系统的抽象化。在某些情况中这个系统管理程序就是一个操作系统;此时,它就称为主机操作系统。
系统管理程序之上是客户机操作系统,也称为虚拟机(VM)。这些 VM 都是一些相互隔离的操作系统,将底层硬件平台视为自己所有,但是实际上是系统管理程序为它们模拟出来的一种假象。
虚拟化技术相对来说是一种开源技术
目前很多企业已经掌握服务器运行的虚拟化技术,供应商正在推广将整个数据中心进行虚拟化的设想。这种设想就是,通过由新的虚拟化技术构建的数据中心平台,实现对服务器、
存储设备与网络设备进行动态管理。
虚拟化技术会成为运营中重要并且无处不在的因素,因而成为数据中心一种新形式的操作系统。这种观点在最近九月份VMware 公司的VMworld 2007大会上得到迅速传播。Intel公司的高级副总裁与总经理Patrick Gelsinger在一次演讲中说,"虚拟化技术颠覆了对操作系统的传统看法,并给我们提供了创建未来数据中心操作系统的机会。"
虚拟化技术同时也是一种节能技术
根据相关的研究显示,采用虚拟化技术使各使用者节省了高达70%的硬件成本。因为虚拟化技术可以帮助用户合并多种应用工作负荷,在单个系统上运行多种操作系统环境;优化应用开发,在单一系统上进行测试和开发;提高系统可用性,在系统之间迁移虚拟环境。
对于现在能耗日益紧缺的状况,虚拟化能将IT设施变得更为绿色,举例来讲:如果按照旧有的IT应用,4台服务器分别运行4个应用,每台服务器功耗为2KW,而每台服务器的资源占用率只有10%,总功耗为8KW;而引入虚拟化技术,将4个应用部署在更高级的服务器上,这样可能让服务器的资源占用率上升至70%,而总功耗仅为4KW。如果对于一个需要采购新设备的企业来说,使用虚拟化技术将会从IT采购成本、能源消耗乃至绿色环保均占有优势。
通过使用虚拟和系统管理这样的技术,客户最多可将管理成本减少40%,将IT利用率提高25%。所以虚拟化确实非作不可!
英特尔虚拟技术的特点
英特尔同微软,IBM、HP等都是虚拟技术的积极推动者。英特尔虚拟化技术更偏重于服务器,操作系统、存储层面的虚拟技术。英特尔虚拟化技术将给用户带来如下优势:
大幅降低成本。基于英特尔 技术的虚拟化解决方案能支持您在更少的物理服务器上整合更多应用,有效避免昂贵的数据中心扩展,同时降低管理成本。
铸造强劲性能。四核英特尔至强处理器可赋予您出色的性能和扩展空间,为您带来相当于双核系统 2.5 倍的平均虚拟化能力。英特尔虚拟化技术(英特尔VT)可降低在客户机和主机操作系统之间转换计算密集型软件的需求。
提高可管理性。虚拟化技术可支持您将多个服务器作为一个资源池进行管理,在其间自由移动和平衡工作负载,杜绝服务中断。
价值链厂商协同推进。英特尔善于推进上下游产业共同推进虚拟化技术,英特尔的技术领先地位体现在 Virtualize ASAP行业计划上,该计划可借助英特尔虚拟化技术,帮助开发在硬件上部署特别应用的最佳实践方案。
虚拟化的最适合应用——IDC和银行
虚拟化技术最能体现出其价值的地方就是数据中心和银行管理。如IDC数据中心是在意的是建设成本、设备的充分利用率以及节能。以虚拟化技术辅助数据中心设计,最多可降低建设成本70%,而通过虚拟化技术充分利用设备,可节能运行耗能40%,这将会对IDC数据中心产生决定性的影响。
而虚拟化技术在多操作系统平台整合方面有着充分的优势,如银行系统会接受各种机构的数据,也可能连入各种行业客户的应用系统,在虚拟平台上充分容许各类数据的交换就是必不可少的。
http://e.chinabyte.com/459/8243459.shtml
lizhe1985收录,使用标签:信息化,时间:2008-7-31 14:31:46 | 相关网摘,我也收藏
来源:比特网
人生病了,就不能正常工作;IT系统“得病”了,就会导致系统非计划的中断。
华佗说,上医者治未病,中医者治欲病,下医者治已病。治未病,其实就是在未得病时防止得病。体检可以帮助医生了解身体状况,判断可能要得什么病,有针对性地提出预防措施,从而达到治未病的效果。
在运维领域,IT系统健康检查同样可以达到治未病的境界。全面的系统健康检查可以帮助用户检查系统目前的状态,并分析其潜在的问题,进而给出解决这些问题的建议和方法,以便尽早发现系统存在的隐患,防患于未然,降低非正常系统中断的风险。
6月25日晚,欧锦赛电视直播信号中断,全球大多数球迷都错过了精彩进球镜头。
欧足联媒体技术部负责人亚历山大·福托伊解释道:“在下半场比赛中,我们受到了三次微小断电的影响。电力保护系统也出现问题,没能及时发现断电并自动切换到备用电源。这些断电的时间不到1毫秒,但这1毫秒的时间足以迫使我们的主控制室重启。重启过程需要几分钟,这就是信号中断的原因。”
看来,如果忽视对IT系统的体检,那么它就可能在最关键的时刻“掉链子”。
中信集团管理信息部副主任王卫乡
实时监控和系统体检的最终目的是一样的,但具体目的不一样,不能把两者弄混淆了,更不能相互替代。
日信证券信息技术中心副总经理王磊
IT系统的体检可以增强系统运维技术人员对系统的信心,不至于担心睡不着觉。
科来软件总经理罗鹰
网络事故也有潜伏期,就像癌症一样,不通过定期的网络分析是不会被发现的。
艾默生网络能源动力系统专家赵广涛
主动式的系统体检通过对设备或整个系统进行全面的检查,从而让IT运维技术人员摆脱充当救火队员的命运。
神州泰岳运维服务中心总经理梁德兴
体检分析要综合系统历史发展等多个维度进行,简单就事论事难免会陷入“头疼治头,脚疼治脚”的境地。
正因为IT系统给人们工作生活带来了方便,系统宕机才会引起大家的关注。无数事实告诉我们,IT系统也会得病。往往,最关键的时刻,IT系统可能宣布“罢工”。而究其原因,导火索可能只是一个小得不能再小的故障。
IT系统体检,刻不容缓。然而,消除对IT系统体检的误解,是IT系统体检成功的关键。
金融IT体检风暴
对欧锦赛电视信号中断一事,艾默生网络能源有限公司动力系统专家赵广涛说:“如果在赛前对动力系统有足够的检查,这种事故是完全可以避免的。这告诉我们,IT系统与我们人的身体很类似,也会突然发病,必须通过体检等措施消除隐患。”
奥运会期间,我国将吸引大量的海内外游客,这将对银行业务,尤其是信用卡业务提出高强度、大规模、综合性的需求,银行等金融机构必须全力保证信息系统的安全可靠和稳定运行。
2008年初,中国银行业监督管理委员会(简称银监会)宣布,将采取“先自查、后进场,边检查、边整改”的方式,开展奥运专项检查工作,确保 2008年奥运会期间银行业信息系统安全。自查工作重点包括以下几个方面:完善突发事件的应急处理机制;制订完善有效的业务连续性计划;做好业务系统压力测试工作,准备应对业务量突增的极端情况;密切关注电子银行业务的安全;加强银证系统跨行业应急机制的建设,应对股票市场波动引发的银行业务风险等。
2008年4月,中国证券监督管理委员会(简称证监会)召开证券期货监管系统的维护稳定工作视频会议,并下发《关于进一步做好维护市场稳定和安全运行工作有关事项的通知》,强调奥运期间要维护稳定,保障信息系统安全,并要求各机构单位提高系统的安全系数和等级。自此,大面积的券商、基金内部安全隐患排查开始。原本处于后台的技术部门,也被推到了风口浪尖。
检查之所以如此重要,是因为引发系统故障的原因大多不是难以解决的科技难题,而是隐藏在某个角落的小问题。大多数IT系统的故障,都是可以通过检查、测试、分析等手段得到预防和控制。这也是证监会、银监会等机构要求对IT系统进行检查的原因所在。
中国中信集团公司管理信息部副主任王卫乡表示,对于IT系统的健康性检查,主要目的是防患于未然,而要真正做到有效的预防,就要求检查结果必须能够为准确的预测提供依据。要保证检查结果的可信赖,就要消除对系统体检的误解,就需要考虑检查者是否合理,检查方法是否得当,检查对象是否全面,检查数据是否准确,检查分析是否到位等诸多环节。
误区一 把实时监控当成体检
“我们每天都在对系统进行体检,可以说实时的。”记者采访一位信息中心主任时,该主任如此说。他向记者展示了手机上的短信——机房里的温度异常的实时短信。另一位信息中心主任说:“我们每天都要对IT系统进行体检。我们每30分钟,检查一次主要业务系统的服务器;每天早上和晚上,我们要检查一次磁盘陈列柜。”
这种实时监控或日常巡检,是不是就是IT系统体检呢?王卫乡表示,实时监控和系统体检的目的有区别,实时监控是为了及时发现系统运行中的异常现象或故障,而系统体检是为了提前发现隐患,把故障消灭在萌芽状态。
赵广涛认为,被动的响应式服务,是IT运维的最初模式。在这种模式下,由于缺乏一种主动的预防性机制,“头痛医头,脚痛医脚”,使得系统的可靠性和可用性都无法得到保证。相反,主动式的系统体检则能通过一系列科学有效的措施,对设备或整个系统进行全面的维护,从而成为消除故障隐患、提高系统的可用性以及降低总体拥有成本的必要措施。
当然,实时监控也是必不可少的。日信证券有限责任公司信息技术中心副总经理王磊表示,通过实时监控我们可以提前发现设备运行异常情况,可第一时间解决问题,确保系统安全稳定运行。而通过非常严格的系统体检流程,定期或不定期地对集中交易柜台系统、网上交易系统的处理能力进行压力测试、容灾能力测试,并将这种体验测试制度化、流程化,这样可以最大限度防止异常情况发生。
系统体检的目的不只是获得一个类似体检表一样的表格,而且是为深入分析系统隐患提供依据。神州泰岳软件股份有限公司运维服务中心总经理梁德兴表示,IT系统健康检查的结果是要从多个数据中分析总结出目前系统存在的问题、可能的风险以及必要的预防措施。在这些过程中,问题分析过程显得尤为重要,后续风险防范措施都来源于对于问题的分析。问题分析要综合系统历史发展、系统预期发展、行业状况等多个维度进行,而绝非只是简单对系统目前的状况进行分析和就事论事。
网管软件或监控系统可以帮助运维人员随时掌握网络流量等指标的异常状态,但是却不会报告潜藏的木马。就像癌症等有很长的潜伏期一样,很多网络事故也有潜伏期,不通过定期的检查是不会被发现的。成都科来软件有限公司总经理罗鹰介绍:“我们一家客户的网络各项性能指标都很正常,监控软件没有异常提示。但是我们的技术人员通过网络分析软件发现,该网络的上行流量比较大。通常说来,网络用户访问下载等导致下行流量比较大,而上行流量应该很小。后来,我们通过分析发现,该网络已经被黑客置入了木马程序。”
误区二 只查设备不查制度
在采访时,一位信息中心负责人向记者出示了厚达两厘米的应急保障制度汇编。然而,记者发现,应急联系人列表中,竟然有数人已经离职。在问及该应急保障制度多久更新一次时,竟然发现,那个2005年就制定出来了应急保障制度,至今没有更新。而2005到现在的3年间,该公司的IT系统经过了两次较大规模的扩容。
对此,王磊说:“为了保证系统稳定运行,给IT系统做体检不仅应该包括硬件和软件系统的体检,还要包括对IT制度的更新、执行情况进行检查。”信息中心负责人要定期检查IT制度、IT系统运维手册如日常操作流程、应急方案等制度,要定期分析IT系统运维手册等制度的有效性和可操作性。
事实上,IT制度的检查和更新,也是中国证券业协会等行业组织的要求。《证券公司网上证券信息系统技术指引》要求,公司应制定网上证券业务的各项安全管理制度和规定,并应定期检查、测试,并根据实际情况及时调整,保证安全措施的持续有效。
梁德兴也指出,对于IT系统而言,人、技术和流程是必不可少的三个对象和环节。往往,检查者会比较关注技术,而对人和流程环节关注较少。因为从表面情况来看,大多数的IT系统问题暴露出的都是技术问题,事实真的如此么?深入分析一下,技术是人掌握和应用的,技术能否应用得好是由人按照既定的流程完成的,这样一来,谁能说只是与技术相关呢?因此,我们在进行IT系统检查过程中,要充分考虑这三个要素,做到检查对象的完整。
就机房体检来说,赵广涛认为,体检的覆盖面要广,不仅要包括机房环境类、设备类,还要包括机房设计与布局、应急措施和预案、维护技术和能力、维护制度与流程等机房软环境的检查。
误区三 体检增加额外成本
“检查,那么费钱的事情,我们银行怎么会做呢?领导对什么很重视,往往是口头上说的。我们的系统检查工作很简单,就是看看磁盘空间占用情况呀,内存使用情况呀,很简单的。”在记者联系采访时,某银行科技部的工作人员这样告诉记者。
IT系统体检确实有成本,不仅有硬的支出,还有隐性成本。罗鹰认为,购买相应的网络分析软件和专业服务需要一定的成本,这个成本是可以衡量的。比起网络安全隐患和故障带来的损失,这些成本所占比例是非常小的,也是非常有必要的。要分析出网络中隐藏的各类安全隐患,降低安全风险,不仅需要检查设备的指标数据,更需要对日常网络传输数据的监测分析,通过网络分析软件可以自动为管理者提供网络相应的基准数据线,并自动记录保存相应的历史运维数据,这样可以大幅降低信息中心运维成本。
当然,体检过于频繁,也会无谓地增加成本。赵广涛认为,对机房的全面体检,通常说来两三年一次就可以。但是,当机房改造或系统扩容之后,要再次对机房进行体检。而对于IT系统各类硬件、软件的体检,却不能间隔这么长的时间。王卫乡认为,对软硬件系统的体检的时间间隔,用户负责人需要根据自家的情况确定。通常说来,半年或一个季度检查一次就够了。
与成本相对的是收益,但IT系统体检的收益难以具体衡量。王卫乡认为,体检的收益没有一个具体的计算方法,但是可以明确的是,体检会减少后期运维成本。大部分公司很大一部分的IT成本消耗在对原有系统的维护上,系统体检工作的好坏会直接影响到后期系统运维成本。
也可以从另一个角度衡量IT系统体检的收益——机会成本。罗鹰认为,机会成本是IT设备在发生故障时对业务造成的成本,也是总体拥有成本的一个重要部分。机会成本更加不确定、更难量化,因此往往被人们所忽视,例如因关键网络设备故障所引起的营收损失,不能快速承载新业务来满足客户的新需求而导致的利润流失等。其它机会成本还包括因木马植入导致机密资料泄漏,系统崩溃造成的生产力损失,因不能及时补救而错失的商业机会等。
体检的收益还表现在为IT系统优化改造提供参考上。王磊介绍,日信证券通过系统体检发现,有很多的软件系统、硬件服务器、网络设备独立在各个系统中,存在资源分配不均的现象。在系统体检中发现的问题,我们可以通过整合集中系统,通过合理的规划设计让系统有效、均衡、充分、发挥作用。这样做可以减少大量的异构系统,减少运维人员,可减少设备投入,降低设备功耗。王磊说:“通过体检,我们可以节省IT投资,降低后期运维成本。”
总之,高度的专业性、宽广的覆盖面以及未雨绸缪式的IT系统体检,可以帮助用户检查系统和设备目前的状态,并分析其潜在的问题,进而给出解决这些问题的建议和方法,以便尽早发现系统存在的隐患,防患于未燃,降低非正常系统中断的风险。
http://e.chinabyte.com/467/8241467.shtml
lizhe1985收录,使用标签:Web开发,时间:2008-7-30 16:16:14 | 相关网摘,我也收藏
来源:开发者在线
今天,OpenAPI作为互联网在线服务的发展基础,已经成为越来越多互联网企业发展服务的必然选择。随着OpenAPI的发布数量不断增加,它的存在也开始暴露出越来越多的问题。一个基本的观点是:OpenAPI并不是万能的良方妙药,而是一个新的生态。
Twitter的运营问题
前几天在网上看到这样的一则有关Twitter的消息:
尽管最近又拿到了一笔风险投资,但Twitter似乎遇到了中年问题,前几天居然因为一台数据库服务器崩溃(原因是居