本文目录一览:
帮我写一篇关于世界杯的英文短文普通点的(250个字)
Tag: java技术
apache commons-fileupload 上传组件1.0版,对临时文件的删除采用了deleteOnExit(),在jvm退出的时候删除临时文件。
如果一个应用有大量的文件上传,而又很不幸,使用了fileupload1.0,那内存肯定会引起一些问题,还可能导致jvm crash,因为这些要被删除的文件信息是保存在内存中的(Unix/Linux平台的jvm就是这种处理方式),至少它会引起java进程的内存占用一直在涨(它们所在用的内存不在java heap,而是在native heap中),你却找不出为什么在涨,所以如果还在使用commons-fileupload1.0,升级吧,对了,commons-fileupload1.1需要commons-io包,在common-fileupload1.1中,临时文件在它的File对象被收集的时候删除,这就聪明多了,也避免了内存“泄漏”,呵呵。
希望对大家有些帮助,其实java的内存问题,如果是java heap泄漏,可以通过gc日志看得到,最好不要内存一不正常,就只顾着检查java heap中的对象,如果gc正常,那么还是查查native code的问题吧,八成是由它引起来的,而且不好查。
又是好久没有写blog了,刚买了一本《Java Puzzlers》,好书,写这blog的时候还在看,放不下了,看了这本书,才知道什么东西都是学无止境,学吧那就,呵呵。
agilejava @ 01:55 | 阅读全文 | 评论 0 | 引用 0 | 编辑
世界杯2006-06-24
Tag:
每四年一回的世界杯开了10多天了,对我最直接的影响就是累。工作上我得上夜班,以保证系统的稳定,好处就是可以很有理由地看比赛,巴西的比赛每场都看,呵呵。最爱巴西,有种预感,巴西这回又是冠军。
上夜班也有点时间看书了,最近在看的书Ajax In Action 网站重构 Unix编程艺术,都是好书,呵呵。
今天休息,夜班上得我白天黑夜的乱过,现在还不困,郁闷。
agilejava @ 02:26 | 阅读全文 | 评论 2 | 引用 0 | 编辑
InetAddress.getLocalHost and InetAddress.getByName2006-06-02
Tag: java技术 Linux
可能许多习惯用java编程的程序员,想要获取本地的地址,采用的方法多是InetAddress.getLocalHost()。
getLocalHost在java中的实现先是取得主机名,之对取得的主机名进行解析,sun的jdk里的源代码可以看到:
String local = impl.getLocalHostName();
..........
InetAddress[] localAddrs;
..........
localAddrs = (InetAddress[]) InetAddress.getAddressFromNameService(local);
return localAddrs[0];
最近的问题是这样子的:一台Linux,它的主机名不知道谁给设置成了40.201这种名字,而在/etc/hosts里也没有它的配置。在调用InetAddress.getLocalHost()返回的地址竟然是40.0.0.201,这当然不是我想要的。
在我的Windows2000上测试一下(使用和Linux相同的jdk版本,sun jdk1.4.2_08),因为公司的主机名改了会有问题,就用下面的方法调用测试
InetAddress in =InetAddress.getByName("40.201");其原理是一样的,结果就抛出了异常:
java.net.UnknownHostException: 40.201: 40.201
at java.net.InetAddress.getAllByName0(InetAddress.java:1011)
at java.net.InetAddress.getAllByName0(InetAddress.java:981)
at java.net.InetAddress.getAllByName(InetAddress.java:975)
同样的jdk,在不同的操作系统上反应完全不一样,研究了两天,今天想通了些了,试着解释一下:
1.4版的InetAddress.getByName发现输入的参数是ip地址的时候,会先试着解析,如查发现它不是合法的ipv4地址,那么会把调用gethostbyname这一系统调用,关键就在于Linux和Windwos2000的gethostbyname的实现上有差别。
在Linux上用c写一个程序,调用gethostbyname("41.201")返回的结果是40.0.0.201;而在windows2000上返回了41.201,前者还算是一个合法的ip地址,后者就绝对不是了。这样在windows2000上的测试就抛出异常。
而在jdk1.5中,已经在java类库里做了一些必要的工作,统一了在不同平台上的行为,都返回了40.0.0.201,也不知道这是好还是坏。因为按常理来讲,40.201应该抛出一个异常,要不查问题都不好查了,呵呵。
教训就是,Linux的主机名可别用ip来做,要用也得用自己的真实ip,否则得到的结果想都想不到。
JDK1.5K K ,如果是一个ip地址,可别指望用InetAddress来验证它是否正确,是否可,因为它不会析这个ip地址的,在jdk1.5中,InetAddress.getByName("2222")返回了0.0.8.174,和在Linux平台上完全一样。
我也就理解这么多了,更深的东西还需要再学习。
一点建议:在做网络编程的时候,如果建立一个连接,最好是根据实际情况用setConnectionTimeout设置一个连接超时,否则系统默认的时间会很长(不同的操作系统默认值是不一样的),肯定会影响到系统的性能。
最近在学校开了一门计算机安全技术与实践,挺感兴趣,好好学习,呵呵。
agilejava @ 18:30 | 阅读全文 | 评论 1 | 引用 0 | 编辑
Tapestry4.0中的session2006-05-11
Tag: Tapestry JavaScript j2ee
Tapestry4之前在Page类中访问HttpSession或HttpRequest是很方便的,这样子就可以了IRequestCycle.getRequestContext().getSession(),昨天看了一下它的源代码,竟然有这样子的注释“
/**
* Returns the {@link RequestContext}. This is provided to ease the upgrade from Tapestry 3.0.
*
* @deprecated To be removed in 4.1.
*/
”
在4.1的时候会被删除,虽然我现在用得还是4.0,考虑到以后的升级还是决定不这样做了。
那只好这样子用了
/**注入Request*/
@InjectObject("infrastructure:request")
public abstract WebRequest getRequest();
public void login(IRequestCycle cycle) {
this.getRequest().getSession(true).setAttribute("user", getName());
}
上面的方法能够在session中保存对象,可想删除怎么办呢? this.getRequest().getSession(true)这样子得到的对象是Tapestry包装的WebSession,当中竟然没有removeAttribute这个方法,郁闷。看看Api中是怎么说的,attribute the new value for the attribute, or null to delete the attribute entirely.
找到答案了,把属性设为null就从session中删除这个对象了。
this.getRequest().getSession(true).setAttribute("user", null);
用了一段时间Tapestry觉得在开发的时候最好看看它的源代码,有些问题文档上没有,看源代码就很明白了。
最近在做新的项目,竟然把以前一想就头大的javascript用了不少,第一次发现原来javascript可以这样写,在写之前看了些Prototype的东西,在写我们自己的项目的一些页面功能时,参照着Prototype的方法来做,竟然也有点面向对象编程的感觉。
刚过完五一,工作起来状态恢复得慢,今天才差不多有些感觉了,继续努力工作,好好学习:)
agilejava @ 00:30 | 阅读全文 | 评论 1 | 引用 0 | 编辑
Hibernate POJO 是真正的POJO吗?2006-04-05
Tag: Hibernate Groovy
今天晚上改一个程序,发现了一个很奇怪的问题,hibernate所说的POJO并不像其宣称的那样,可以当做普通的java对象使用,至少有时不注意的时候会出问题,在写程序的时候,千万要注意这种情况。
晚上遇到的问题是这样子的,有一个对象Document,用Spring的HibernateTemplate load之后,我设置了这个对象的一个属性,例如一个叫做md5的属性,代码如下:
...开始事务
Document doc = hTemplate.load(new Interger(documenId),Document.class);
String content = doc.getContent();
String md5 = MD5.get(content);//计算文档内容的md5值
doc.setMd5(md5);
/*
getDocumentByMd5 的定义 :select doc.id from Document doc where doc.md5=:md5
在查询之前,数据库里的md5是惟一的,没有md5码相同的Document
*/
List list = hTemplate.getHibernateTemplate().findByNamedQueryAndNamedParam("getDocumentByMd5",
"md5", md5);
....结束事务
返回的list结果的里按照我的思维应该是空的,但是结果是返回的list的第一个元素的值就是doc的对象id。
按理讲程序的事务还没有提交,doc也没有被update,怎么就会查出结果了呢?太奇怪了。
研究了一下Hibernate2.17c的SessionImpl源代码,发现下面的注释,在作查询前,Hibernate要先检测在查询语句中出现的表涉及的对象是否被修改过,如果被修改过,那么先提交这些修改,之后再查询。这也解释了为什么刚修改过的对象,还没有提交修改,就在查询结果出查出来了。
/**
* detect in-memory changes, determine if the changes are to tables
* named in the query and, if so, complete execution the flush
*/
private boolean autoFlushIfRequired(Set querySpaces)
我就在想,这样的POJO是真正的POJO吗?而这些细节一般很难被注意到,反正我以后是不敢再这样子用了,在用Hibernate的时候,从它那儿得到的POJO对象小心使用,它可不是“真正的POJO”。
今天刚发现Groovy有vim的插件,很好用,语法加亮显示,下午在公司把它装上后,工作效率明显提高,不在满屏白字了,呵呵,从这里可以下载到这个插件,安装很方便。
Groovy目前竟然不支持java标准的for (int i=0;i10;i++) 循环,别的样式的for循环倒是有好几种,郁闷中。
注:上面说到的Hibernate的问题可以通过session.setFlushMode(FlushMode.COMMIT)设置提交来解决,abside的指点很正确,非常感谢。
Hibernate有四种FlushMode:NEVER,COMMIT,AUTO,ALWAYS,默认是AUTO,工作还需要再细心些。
(2006.06.07)
agilejava @ 00:33 | 阅读全文 | 评论 1 | 引用 0 | 编辑
JDK1.4 读文件的陷井2006-03-29
Tag: java技术 Linux
最近在工作遇到一个问题,too many open files异常,这个异常最终的结果导致Resin停止响应。
在我们的系统中是发现把一个目录当作文件来读取,而JDK1.4对这种情况虽然抛出了异常,但是已经打开的文件句柄没有及时的释放,最终超出了系统的限制,在Linxu下,可以用ulimit -a查看每个进程允许打开的文件个数,我们的是1024.
下面的代码解释了这种问题的发生,运行环境:JDK1.4
import java.io.*;
public class TestFile
{
public static void main(String[] args) throws Exception{
read("/opt/");
Thread.sleep(10000);
}
public static String read( String file )
{
String ret = null;
File f = null;
BufferedInputStream result = null;
ByteArrayOutputStream baos = null;
try{
f = new File( file );
if(!f.exists())
{
System.out.println("file:"+file+" does not exist");
return ret;
}
/*
在这里加上对是否是文件的判断
else if(!f.isFile()){
return null;
}
*/
result = new BufferedInputStream( new FileInputStream(f) );//这里会抛出异常
baos = new ByteArrayOutputStream();
.........
ret = new String(baos.toByteArray());
}catch(Exception e){
e.printStackTrace();
}finally {
try
{
if( result!=null ) result.close();
if( baos!=null ) baos.close();
f = null;
}catch(Exception e) {
e.printStackTrace();
}
}
return ret;
}
}
执行java TestFile之后,在线程等待的时候,用lsof -p 查看该java进程所打开的文件句柄,得到类似下面的结果:
COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME
java 7535 agile cwd DIR 8,1 4096 326402 /opt
可以看到,虽然读取/opt的时候会有异常抛出,但是文件的句柄并没有被释放,累积的结果就是too many open files.
刚才在jdk 1.5上做了测试,这个问题已经解决了,它的提示更友好:
java.io.FileNotFoundException: /opt (Is a directory)
而用lsof -p 查看的时候也没有发现有"/opt"
建议在jdk1.4上做开发的朋友,在读文件的时候一定要多加小心。
BTW:今天在机子上装了一个vmware,顺便装了一个Ubuntu5.10,感觉好极了,中文的支持也很好,这个BLOG就是在Ubuntu中的FIREFOX上写得,下面就是我的桌面。
agilejava @ 00:11 | 阅读全文 | 评论 0 | 引用 1 | 编辑
groovy的异常处理2006-03-27
Tag: Groovy
在Groovy中处理异常和在java中一样,原来一直想不通Groovy如何处理异常,原来它可以使用和java中一样的try/catch就行了.
try{
i = Integer.parseInt("abc")
}catch(Exception e){
print "catch:"+e
}
再仔细地看了一下Groovy网站上的介绍:
Groovy is an agile dynamic language for the Java Platform that has many of the features that people like so much in languages like Python, Ruby and Smalltalk, making them available to Java developers using a Java-like syntax.
终于明白Groovy是一种动态的java,它可以更有效地使用java编程,在java中可以使用的语法同样地在Groovy中基本上也可以使用,Groovy的语法更灵活。
下午写了一个Eclipse的插件,和以前一样,界面部分耗费了大约2/3的时间,需要一个设计器了,老这样子很累。有一个网站相当得好,,因为不常使用SWT/JFace,所以写界面的时候很费劲,从这个网站上学了不少东西,感谢。
从昨天开始下载Ubuntu 5.10,目前为止还是没有下载下来,晚上不关电脑,明天应该能回来安装了。
agilejava @ 01:34 | 阅读全文 | 评论 0 | 引用 1 | 编辑
Groovy嵌入java程序中缓存class2006-03-25
Tag: Groovy java技术
今天继续Groovy,下午使用Groovy遇到了一个,写了一个大约有90行的Groovy脚本,在一个jsp里做了一下测试,执行时间竟然要到1~2秒,经过测试发现95%的时间花在了编译上面,而我们的脚本可以随时需要修改,这可不能满足需要,看了一会儿Groovy的文件,发现它把每一个脚本均是编译成一个class之后构造一个GroovyObject调用其中的run方法,这么一来,可以缓存编译后的class来避免每次编译,时间不等人啊。
现在的策略是:
1.先看缓存中有没有与脚本对应的class,有则检查脚本的修改时间是否大于缓存中所记录的时间戳,如果大于,则重新编译,之后再缓存;如前述的条件均不满足,从缓存中取class
2.检查过缓存之后,根据得到的class构造出一个GroovyObject
3.调用groovyObject.setProperty将需要的参数绑定
4.调用run方法,取得返回结果
再运行测试的jsp,5毫秒,快了很多,能够满足系统现在的要求了。
而Groovy网站上讲的例子是很简单,但在生产环境下根本不能那么用,建议有用Groovy嵌入到java的项目,最好还是把class缓存起来,提高脚本执行的效率。
晚上把这个功能介绍给同事,让他们试用一下,效果非常好。
Groovy提供了一种有效的扩展系统的功能,还要继续挖掘它的潜力。
明天去上课,周末准备写一个eclipse 插件,看时间了。
agilejava @ 00:04 | 阅读全文 | 评论 1 | 引用 2 | 编辑
改名2006-03-23
Tag:
今天才注意到我的博客名叫agile sungny,sungny这个家伙好几年没到这里来了,以前还发个文章,估计都把这儿忘记了,正好我独占这里了,因此我决定改名,呵呵。
晚上搞了一下网页消重的工作,测试了一下,效果还不错,主要的算法是从上面学来的,明天下班后想想如何改进。
今天头儿有一个新的需求,世界杯就要来了,有些需求在现有中系统比较难以办到,昨天做的Groovy功能正好派上用处了,下班的时候试了一下效果,还是满意。
原来是想把每个Groovy脚本在第一次执行的时候编译成class后缓存起来,但是现有系统的内存占用简直是惊人,再搞这么多的class进去,肯定不行,所以只能牺牲一些效率了。
刚才在网上乱看,发现了一个博客价值评估工具 ,评估了一下我的博客,
agile sungny 评估价值:14,395 RMB
有1万多啊,呵呵,不知道他们是怎么搞出来的,透露一下就好了。
最近学习的时间少了许多,晚上睡觉前要看一个英文短文再睡,要不老师下回上课又要提问我了,统计了一下,第二次课我让提问了一回,第三次一回,第四课三回,还不会答,必须改变这种状况。
介绍一下“阿尔派”音响
在持续追求MobileEntertainment之后,随之而来的当然就是影像。Alpine率先注意到影像媒体的必要性,并以此确立了ALPINEINTELLI-GENTNETWORKSYSTEM这种通称为AI-NET系统的高速、高容量BUS系统。其对应范围不仅仅只是停留在与多媒体间的系统结合,更遍及到防盗用的保安系统中,甚至连庞大的DVD资料都能够处理。在自由自在地组合喜欢的系统的基础上,其操作性能亦非常出色,是能够构筑出最尖端画质、音质的灵敏系统。确立重低音的播放技术,调和整体的声音平衡Alpine在追求理想声音方面已取得的成果就是高效率、低失真并立的DDDrive方式扬声器(重低间扬声器)以及在实质电压下可将能力发挥到最大限度的V12功率放大器。2000年机种的主题就是高品质的重低音播放。
让汽车音响迷们可充分地享受到不会被随车而来的发动机声和行车声所掩盖住的、强力而又干脆的低音。从形成声音的主控单元开始,一直到放大器、扬声器,以这种思考方式使整个系统发出您未曾体验过的重低音效果。使稳定的高保真再现的STARCircuit制作出可最大限度地引发出BassEngine之特色的功率放大器也是Alpine2000年机种的主题。基于此概念Alpine开发出了2声道规格的MRV-T707与T407两个机种。另外还开发了STARCircuit,防止了音质劣化,使稳定的高保真再现成为可能。
alpine镜像密码有效期
alpine镜像密码有效期是30天。
alpine镜像在构建镜像过程中作为基础镜像占比越来越高,下面是alpine镜像中包管理工具apk使用相关示例:
1、apk-help命令查看完整的包管理命令。
2、apk update:从远程镜像源中更新本地镜像源索引。
3、apk add:安装PACKAGES并自动解决依赖关系,也可以从第三方仓库添加软件包。
Alpine 操作系统是一个面向安全的轻型 Linux 发行版。它不同于通常 Linux 发行版,Alpine 采用了 musl libc 和 busybox 以减小系统的体积和运行时资源消耗,但功能上比 busybox 又完善的多,因此得到开源社区越来越多的青睐。
在保持瘦身的同时,Alpine 还提供了自己的包管理工具 apk,可以通过网站上查询包信息,也可以直接通过 apk 命令直接查询和安装各种软件。
总结如下:
Alpine Linux Docker镜像基于Alpine Linux操作系统,后者是一个面向安全的轻型Linux发行版。不同于通常Linux发行版,Alpine Linux采用了musl libc和busybox以减小系统的体积和运行时资源消耗。在保持瘦身的同时。
Alpine Linux还提供了自己的包管理工具apk,可以在其网站上查询,或者直接通过apk命令查询和安装。