@OverWrite BlogJava

  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  128 随笔 :: 0 文章 :: 29 评论 :: 0 Trackbacks

2008年4月10日 #

httpclient已停止维护,其替代产品为 Apache HttpComponents 。 官方声明如下(详细信息点击这里):
The Commons HttpClient project is now end of life, and is no longer being developed. It has been replaced by the Apache HttpComponents project in its HttpClient and HttpCore modules, which offer better performance and more flexibility.

HttpClient 是 Apache Jakarta Common 下的子项目,可以用来提供高效的、最新的、功能丰富的支持 HTTP 协议的
客户端程工具包,并且它支持 HTTP 协议最新的版本和建议。本文首先介绍 HTTPClient,然后根据作者实际工作经验给出了一些常见问题的解决方法。 

所以打算用HttpClient的朋友,可以考虑使用HttpComponents 了。
HttpComponents 入门,笔者认为 iteye上的一篇文章写的不错,大家可以参考 《HttpComponents入门解析》
posted @ 2012-08-12 17:50 vesung 阅读(392) | 评论 (0)编辑 收藏

现在本本屏幕越来越小, 在上面运行eclipse就会显得字体小, 那么如何调整字体大小那?
方法一:
    打开菜单 window->preferences->general->appearance->colors and fonts
打开basec里面的text font 进行编辑会弹出一个字体编辑的窗口, 在里面调整字体即可。

方法二:
    因为eclipse版本众多,所以菜单路径也会有所差异。 还有一种方法可以不用担心不同版本的差异:
    开始先打开菜单 window->preferences   在左上角数据font 回车, eclipse就会自动搜索出可以设置字体的地方了。 接下来打开basec里面的text font 进行编辑会弹出一个字体编辑的窗口, 在里面调整字体即可。 


一点小技巧希望对大家能有所帮助。
posted @ 2012-07-26 14:46 vesung 阅读(43754) | 评论 (1)编辑 收藏

这篇文章在chinaunix上看到,写的很不错。希望能对学习linux的人有所帮助。

随着Linux应用的扩展许多朋友开始接触Linux,根据学习Windwos的经验往往有一些茫然的感觉:不知从何处开始学起。作为一个 Linux系统管理员,我看了许多有关Linux的文档和书籍,并为学习Linux付出了许多艰苦的努力。当真正获得了一份正式的Linux系统管理工作 后,我更加深刻地理解了Linux的灵魂:服务与多用户。Linux系统知识是非常广博的,但是只要掌握了重点知识,管理它并没有想象中的那么可怕。在下 面我会将作为系统管理员的一些工作心得和总结出来的经验系统地介绍给大家。

一、 学习的目的

通过Linux的学习掌握UNIX的目的想必不用多说了,在这个网络人才身价倍增的年代,想靠技术吃饭又不想掌握网络和编程技术是不明智的。当一人第一次 听说Linux并跃跃欲试的时候,总会提出几个?,它是什么(What)? 为什么要用它(Why)? 怎样学习它(How)?做为开放源码运动的主要组成部分,Linux的应用越来越广泛,从我们平时的娱乐、学习,到商业、政府办公,再到大规模计算的应 用。为了满足人们的需求,各种各样的、基于Linux的应用软件层出不穷。只要具备了LinuX的基本功,并具有了自学的能力之后,都可以通过长期的学习 将专项内容予以掌握。

二、 从命令开始从基础开始

常常有些朋友一接触Linux 就是希望构架网站,根本没有想到要先了解一下Linux 的基础。这是相当困难的。虽然Linux桌面应用发展很快,但是命令在Linux中依然有很强的生命力。Linux是一个命令行组成的操作系统,精髓在命 令行,无论图形界面发展到什么水平这个原理是不会变的,Linux命令有许多强大的功能:从简单的磁盘操作、文件存取、到进行复杂的多媒体图象和流媒体文 件的制作。这里笔者把它们中比较重要的和使用频率最多的命令,按照它们在系统中的作用分成几个部分介绍给大家,通过这些基础命令的学习我们可以进一步理解 Linux系统:

●安装和登录命令:login、 shutdown、 halt、 reboot 、mount、umount 、chsh
●文件处理命令:file、 mkdir、 grep、dd、 find、 mv 、ls 、diff、 cat、 ln
●系统管理相关命令: df、 top、 free、 quota 、at、 lp、 adduser、 groupadd kill、 crontab、 tar、 unzip、 gunzip 、last
●网络操作命令:ifconfig、 ip 、ping 、 netstat 、telnet、 ftp、 route、 rlogin rcp 、finger 、mail 、nslookup
●系统安全相关命令: passwd 、su、 umask 、chgrp、 chmod、chown、chattr、sudo、 pswho

三、 选择一本好的Linux书籍

无论在论坛还是读者反馈中,我们看到最多的问题往往是某个新手,在安装或使用linux的过程中遇到一个具体的问题就开始提问,很多都是重复性的问题,甚 至有不少人连基本的问题描述都不是很清楚。这说明很多初学linux的人还没有掌握基本功。怎样才能快速提高掌握linux的基本功呢? 最有效的方法莫过于学习权威的linux工具书,工具书对于学习者而言是相当重要的。一本错误观念的工具书却会让新手整个误入歧途。目前国内关于 linux的书籍有很多不过精品的不多,笔者强烈建议阅读影印本的“o'reilly原版linux图书”,而且出版社还提供了一个非常好的路线图


四 、养成在命令行下工作

一定要养成在命令行下工作的习惯,要知道X-window只是运行在命令行模式下的一个应用程序。在命令行下学习虽然一开始进度较慢,但是熟悉后,您未来 的学习之路将是以指数增加的方式增长的。从网管员来说,命令行实际上就是规则,它总是有效的,同时也是灵活的。即使是通过一条缓慢的调制解调器线路,它也 能操纵几千公里以外地远程系统。

五、用Unix思维思考Linux

由于Linux是参照Unix的思想来设计的,理解和掌握它就必须以Unix的思维来进行,而不能以Windows思维。不可否认,windows 在市场上的成功很大一部分在于技术思想的独到之处。可是这个创新是在面对个人用户的前提下进行的,而面对着企业级的服务应用,它还是有些力不从心。多年来 在计算机操作系统领域一直是二者独大:unix在服务器领域,Windows在个人用户领域。由此可见,用户需求决定了所采用的操作系统。不管什么原因, 如果要学习Linux,那么首先要将思维从Windows的“这个小河” 中拖出来,放入Unix的海洋。

六 、学习shell

对于Shell(中文名称壳),习惯Windows的读者肯定是非常陌生的,因为Windows只有一个“Shell”(如果可以说是Shell的话), 那就是Windows自己。用一句话容易理解的解释就是,shell是用户输入命令与系统解释命令之间的中介。最直观的说法,一种Shell有一套自己的 命令。举一个容易理解的例子,Linux的标准Shel是Bash Shel;Solaris的shell是B shell;Linux的Shell是以命令行的方式表现出来的。读者可能会不理解,Windows从命令行“进化”到了图形界面,那么Linux现在还 使用命令行岂不是一种倒退?

当初我刚刚接触Linux时就曾有过这种想法。可是后来发现,如果使用图形界面,那么分配给应用软件的资源就少了,在价格昂贵的服务器上,能够以较低的硬件配置实现同样的功能是非常重要的。

下面举例说明,一台服务器有1GB内存,假设其中512MB用于处理图形界面,若要安装一个需要784MB内存的数据库软件,惟一的办法就是扩大内存。但 是如果使用命令行,系统可能只需要64MB内存,其它的内存就可以供数据库软件使用了。使用命令行,不仅是内存,而且CPU及硬盘等资源的占用都要节省很 多。所以,作为服务器使用命令行是优点而不是缺点。既然Shell有这么多优点,就必须要学习它。
七、勤于实践

要增加自己Linux 的技能,只有通过实践来实现了。所以,赶快找一部计算机,赶快安装一个 Linux 发行版本,然后进入精彩的Linux世界。相信对于你自己的 Linux 能力必然大有斩获。此外,人脑不像计算机的硬盘一样,除非硬盘坏掉了或者是资料被你抹掉了,否则储存的资料将永远而且立刻的记忆在硬盘中。在人类记忆的曲 线中,你必须要不断的重复练习才会将一件事情记得比较熟。

同样的,学习 Linux 也一样,如果你无法经常学习的话,学了后面的,前面的忘了。你对Linux命令熟悉后你可以开始搭建一个小的Linux网络,这是最好的实践方法。 Linux是网络的代名词,Linux网络服务功能非常强大,不论是邮件服务器、Web服务器、DNS服务器等都非常完善。当然你不需搭建所有服务,可以 慢慢来。需要说明的是这个Linux网络对于初学者有两三台计算机即可。自己多动手,不要非要等着别人帮你解决问题。

八、学会使用文档

和私有操作系统不同,各个Linux的发行版本的技术支持时间都较短,这对于Linux初学者是往往不够的。其实当你安装了一个完整的Linux系统后其 中已经包含了一个强大的帮助,只是可能你还没有发现和使用它们的技巧。主流Linux发行版都自带非常详细的文档(包括手册页和FAQ),从系统安装到系 统安全,针对不同层次的人的详尽文档,仔细阅读文档后40%问题都可在此解决。查阅经典工具书和Howto,特别是Howto是全球数以万计的 Linux、Unix的经验总结非常有参考价值通常40%的问题同样可以解决。安装一个新的软件时先看README,再看INSTALL然后看FAQ,最 后才动手安装,这样遇到问题就知道为什么。如果说明文档不看,结果出了问题再去论坛来找答案反而浪费时间。

当查找文档时, 一定要看文档是在何种版本、何种环境及何种状态下出现的何种结果。对于文档的有效性, 一时还无法在操作前就知道结论如何,那么对某个专题或问题,阅读相关的多篇文章将会节省大量的时间,还可以保证尽量“干净”的环境,有效避免因为不同操作 所造成的更多问题。操作时要仔细核对各个步骤及输出的结果,尽量保持与文档一致。

九、在Linux论坛获取帮助

如果上面的措施没有解决问题,此时你就需要Linux社区的帮助了。需要说明的是你要有周全的思考,准备好你的问题,不要草率的发问,否则只会得到到草率 的回答或者根本得不到任何答案。越表现出在寻求帮助前为解决问题付出的努力,你越能得到实质性的帮助。最好先搜寻一下论坛是否有您需要的文章。这样可以获 得事半功倍的效果。

你需要提供精确有效的信息。这并不是要求你简单的把成吨的出错代码或者数据完全转储摘录到你的提问中。如果你有庞大而复杂的测试条件,尽量把它剪裁得越小 越好。可能你会遇到这种情况,对于一个问题会出现不同内容回答,这时你需要通过实践来验证。另外把这个问题放在其他Linux社区请求帮助也是一种选择。 如果得不到答案,请不要以为我们觉得无法帮助你。有时只是看到你问题的人不知道答案罢了。这时换一个社区是不错的选择。

十、学习专业英文

如果你想深入学习Linux,看不懂因为文档实在是太难了。写的最好的,最全面的文档都是英语写的,最先发布的技术信息也都是用英语写的。即便是非英语国家的人发布技术文档,也都首先翻译成英语在国际学术杂志和网络上发表。

通过man、info等命令,可以从在线帮助中快速地获得所需要的命令和操作方法。不要害怕海量的系统帮助,仔细阅读几个man或info文档就会发现, 这些帮助几乎都按照固定格式写成一命令名称、参数、参数说明、使用例子、参考等。当英语成为一种习惯,就会自觉地查找或订阅互联网上感兴趣的英文材料。这 样,在不知不觉中就已经和世界同步。

十一、在社区共享你的经验

随着Linux应用的扩展,出现了不少Linux社区。其中有一些非常优秀的社区:水木清华、其中有一些非常优秀的社区:www.linuxforum.net(国内最高水平GNU站点)、http://www.chinaunix.net/ (中国最大的Unix技术社区),随着知识的不断积累,就可以把自己动手解决一些前人没有遇到的问题写出文档在网络上共享给其他读者。这个时候,也就成为 了一名“高手”。Linux的使用者一般都是专业人士,他们有着很好的电脑背景且愿意协助他人,Linux高手更具有鼓励新手的文化精神。

最后是一个笔者的Linux学习的路线图(roadmap):

●了解Linux 的基础知识,这些包含了用户管理、群组的概念、权限的观念等;
●掌握至少50个以上的常用命令;
●掌握.tgz、.rpm等软件包的常用安装方法
●学习添加外设,安装设备驱动程序(比如网卡)
●熟悉Linux文件系统 和目录结构。
●掌握vi,gcc,gdb等常用编辑器,编译器,调试器 。
●理解shell别名、管道、I/O重定向、输入和输出以及shell脚本编程。
●网络的基础包括: 掌握路由概念、OSI七层网络模型、TCP/IP模型及相关服务对应的层次对于Linux学习非常重要的。然后学习Linux环境下的组网。
posted @ 2008-07-31 17:49 vesung 阅读(387) | 评论 (0)编辑 收藏

国外开发者博客中有一篇有趣的文章,将程序员按水平像软件版本号那样划分为不同的版本。相对于在招聘时分为初级,中级,高级程序员,直接表明需要某种语言N版本的程序员或许更方便直接。根据作者的观点,可将WEB开发者大致分为以下几个版本:

Alpha:阅读过一些专业书籍,大多数能用Dreamweaver或者FrontPage帮朋友制作一些Web页面。但在他们熟练掌握HTML代码以前,你大概不会雇佣他们成为职业的WEB制作人员。

Beta:已经比较擅长整合站点页面了,在HTML技巧方面也有一定造诣,但还是用Tables来制作页面,不了解CSS,在面对动态页面或数据库连接时还是底气不足。

Pre Version 1 (0.1):比Beta版的开发者水平要高。熟悉HTML,开始了解CSS是如何运作的,懂一点JavaScript,但还是基于业余水准,逐步开始关心动态站点搭建和数据库连接的知识。这个版本的WEB开发人员还远不能成为雇主眼中的香饽饽。

1.0: 能够基本把控整个站点开发,针对每个问题尽可能的找到最直接的解决办法。但对可测性,可扩展性以及在不同(层)框架下如何选择最合适的WEB设计工具尚无概念。这个版本的WEB开发者有良好的技术基础,需要有进一步的帮助和指导。

 

2.0:懂面向对象的编程语言,理解分层开发的必要性,关注代码分离,对问题寻找更完美的解决方法,偶然也会考虑设计模式的问题,但对此仍然概念不清。属于优秀的初级开发者,能完成较松散的代码开发(相对大型严谨的站点开发而言),在面对较复杂问题寻找解决办法时需要周边人的帮助。

3.0:开始较为深入的理解面向对象编程和设计模式,了解他们的用途,当看到好的设计模式时能看透其本质,逐步关注分层的架构解决办法和可测试性。理解不同的开发语言并能说出他们的异同(例如各自的优势)。属于优秀的中级别开发者,雇主也确信他们最终能找到问题的解决办法,这个版本的人可以给1.0和2.0的开发者以指导。但他们对架构的理解仍然不够清晰,值得一提的是,只要给予一些指导,他们能很快理解并熟记做出的决定,以及选定方案的优势所在。

4.0:理解模式,重视用户的反馈。着手研究方法论,架构设计和软件开发的最佳入口。头脑中已经形成了超越开发语言,技术架构的整体方案,可根据需求解构程序。能从理论的角度,不同模式如何融合成最佳形态,将多种X-驱动的模式应用到不同的方案中。是精通多语言的高手,理解不同系统和方法论的细微差别,属于高级程序员。这个级别的人能够轻易的辅导2.0和3.0的程序员,将他们推向更高的级别。

5.0:从系统的角度考虑问题。对各种系统结构有深入研究,能对整个代码架构中的问题进行改进。在团队粘合性以及代码安全性方面有杰出贡献。对1.0到4.0版本的开发人员出现的问题能及时察觉,让整个团队保持积极性且保持兴奋的状态创建软件解决办法。举例来说,他们总是对新的技术和信息保持饥渴状态,试图用最简便的方案解决开发任务。在整个IT团队中获得信任,属于高级程序员和架构师。

那么,您属于哪个版本的程序员呢?

posted @ 2008-06-29 23:28 vesung 阅读(619) | 评论 (1)编辑 收藏

中国互联网审查制度的不透明一直为人所诟病。现在还不清楚56.com是因为什么开罪了监管机构,也不知道该网站会关闭多久。这些疑问也表明笼罩整个中国互联网视频领域的风险,即使是那些有明智投资方支持的大型互联网公司也面临着同样的问题。该网站至少募集了3,000万美元资金,投资方中包括风险投资巨头Sequoia Capita和华特•迪斯尼(Walt Disney Co.)旗下的Steamboat Ventures。

网络视频主管部门之一的中国国家广电总局(SARFT)没有回复记者就56.com问题的采访申请。该网站首席财务长张福兴(Jay Chang)拒绝发表评论,其投资方的人士也拒绝置评。

看来清理行动开始下狠手了。
posted @ 2008-06-23 08:54 vesung 阅读(343) | 评论 (0)编辑 收藏

不说废话了,直接看代码:
页面:
<html>
<head>
<script type='text/javascript' src='jquery.js'></script>
<script type='text/javascript'>
//js代码1
<script>

<body>
<table>
 
<tr>
  
<td>级联菜单</td>
  
<td>
    
<select name='city' class='amenu'>
     
<option value=''>-市局全部-</option>
     
<option value='1'>a市</option>
     
<option value='2'>b市</option>
     
<option value='3'>c市</option>
    
</select>
  
</td>
  
<td>
    
<select name='country' class='amenu'>
     
<option value=''>-县局全部-</option>
     
<option value='1'>test</option>
    
</select>
  
</td>
  
<td>
    
<select name='taxOffice' class='amenu'>
     
<option value=''>-所全部-</option>
     
<option value='1'>test</option>    
    
</select>
  
</td>
  
<td>
    
<select name='taxOffical' class='amenu'>
     
<option value=''>-职员全部-</option>
     
<option value='1'>test</option>    
    
</select>
  
</td>
 
</tr>
</table>
</body>

对应的js代码:
js代码1:
//本菜单是4级级联菜单,采用jquery框架来实现
$(document).ready(function(){
 
//为所有class为amenu的元素绑定onchange事件
 $('.amenu').change(function(){
  
//记录本级菜单标志
  var orgLevel = this.name;
  
//下级菜单
  var nextMenu = $(this).parents().next().children[0];
  
//ajax动作提交的对象(后台采用java程序)
  var postUrl = 'pubOrgAjax.do';

  
//如果本菜单是最后一级菜单的话则不做任何动作
  if(orgLevel=='taxOffical') return true;
  
//本级菜单选择为全部选项,则下级菜单也置为全部
  if(this.value == ''){
   
var firstOption = nextMenu.option[0];
   nextMenu.length
=0;
   nextMenu.options.add(firstOption);
   
return true;
  }


  
//ajax动作
  $.post(postUrl,{orgFlag:orgLevel,orgCode:this.value},function(xml){
    
var dicts = $('dict',xml);
    
if(dicts.length<1){alert('返回数据错误,请重新登陆');return false;}
    
//清空nextMenu
    if(nextMenu.options[0].value == ''){
      
var firstOption = nextMenu.options[0].text;
      nextMenu.length 
= 0;
      nextMenu.options.add(
new Option(firstOption,''));
    }
else{
      nextMenu.length 
= 0;
    }

    
//为清空后的nextMenu填充新值
    for(var i=0;i<dicts.length;i++){
      
var newOption = new Option($('name',dicts[i]).text(),$('code',dicts[i]).text());
      nextMenu.options.add(newOption);
    }

    
  }
);
  
 }
);
}
);

后台返回的数据格式:
<?xml version="1.0" cencodeing="gbk"?>
<ajax-response>
<response>
 
<dict>
    
<code>1</code>
    
<name>市局1</name>
 
</dict>
 
<dict>
 
 
</dict>

 
</response>
</ajax-respnse>

posted @ 2008-06-12 09:44 vesung 阅读(9831) | 评论 (5)编辑 收藏

Yahoo本周发表研发一年的Yahoo!BrowserPlus预览版,这是一个用来延伸网络应用的平台,开发人员可透过该平台结合桌面程序,而用户只要透过浏览器就能执行利用该平台开发的网络应用。

现阶段BrowserPlus平台所提供的功能包括自桌面拖曳、客户端的图像处理,以及桌面通知工具等。Yahoo指出,BrowserPlus的最大特色就是可以直接新增或更新服务而不用重新启动浏览器,甚至不需重新下载网页,对使用者而言,这代表在执行这些新应用时不用进行安装或受到其他干扰;开发人员则能透过单一的功能呼叫检视或启动新服务。

Yahoo展示了基于BrowserPlus所设计的应用范例,其中一个为照片上传工具Photo Uploader,该工具参考了Flickr Uploader桌面应用程序的功能,用户可以透过浏览器,从桌面上拖曳照片,并进行诸如旋转、改变大小以及特效等简单的编辑功能。

BrowserPlus属于近来风行的丰富网络应用程序(RIA)平台,Yahoo利用该平台替开发人员处理了复杂的软件发表及更新功能,让开发人员及使用者皆能从中受益。

Yahoo目前仅允许Yahoo及其合作伙伴使用BrowserPlus,预计在公开版本发表后才会供其他开发人员使用。现阶段BrowserPlus支持Windows XP及Mac OS X等操作系统,以及IE、Firefox及Safari等浏览器,未来将支持更多的平台。

Yahoo指出,Yahoo致力于开发开放的平台,其中一项重点是提供开发人员用来开发内容的客户端工具,Yahoo先前已释出Yahoo用户接口链接库(Yahoo!User Interface Library,YUI)开放源码计划,BrowserPlus则是提供以浏览器为基础的网站开发解决方案,该平台之后也将朝开放的目标前进。

丰富网络应用程序平台成为各大业者争相竞逐的领域,市场上类似的平台还包括微软发表的Silverlight、Adobe的AIR,以及Mozilla基金会所开发的Prism等

posted @ 2008-06-05 08:50 vesung 阅读(415) | 评论 (0)编辑 收藏

(转载)
2007年6月项目准备开始了,刚来到一个新的项目组,什么都是新的,除了我自己。

需要一个新的框架来开发项目,香港的同事决定使用Dojo,DWR, 我开始学习使用dojo,时间很短,但是我还是基本上熟悉了dojo的基本控件和架构。在此基础上搭建起了项目的基本框架。这是一个单页面,基于ajax和dojo widget的系统,一切都那么的新奇,又充满挑战,但是既然dojo有这么多后台,又有香港同事的推荐,我显得自信满满。

框架搭建的同事,也开始后了紧锣密鼓的招兵买马,一起都像是从零开始。陆陆续续,招了5个程序员和一个测试员。开始了整个项目的快速开发,由于需求由香港负责,而且需求做的比较细致,基本上问题很少。Dojo 却是麻烦不断。

首先的一个坏消息是当我们做完了几乎全部300个页面的时候,dojo宣布0.43不在得到支持,取而代之是完全不同的dojo0.9。 而且dojo0.9 还不是稳定的版本,问题多多,让我们骑虎难下,最后还是决定按兵不动。 随之而来,是dojo1.0,dojo1.1 的陆续发布,但是一直都无法让我看到希望的曙光。 与之相对的是ext在国内的广泛使用和热烈追捧。

Dojo 的控件有很多奇怪的地方,日期选择控件的行为非常怪异,与国内的使用习惯很不相同。而且样式极其丑陋,当字体放大缩小的时候更是丑陋。显示的格式和保存的格式需要分别指定。我们修改了大量的代码。

dojo 的下拉框也被用户投诉,过滤之后一定要再选择一次或者按回车才能选定结果,前台值和后台值分开操作也带来很多不变。

dojo 的验证文本框颜色现实有bug,我们不得不修改代码

dojo的对话框也有问题,对话框中无法在弹出对话框。对话框的操作和控制很不灵活。

js代码不利于管理,容易发生命名冲突。

 

致命的问题发生在项目的后期,在客户的系统进行测试时发现。dojo的性能非常差,在赛扬2G的电脑上,一个页面显示的时间竟然需要17秒。简直就是噩梦。

另外使用dojo的对话框时出现cpu占用100%而且一直不回落下来。

页面载入完成的时候,它有将整个页面重新刷新一次,又需要花费额外的5到8s时间,不仅花费更多的时间,而且严重影响客户体验。

 

还有开发过程中碰到的无数问题,虽然一个一个被解决,但是无疑是一次一次痛苦的煎熬。

 

最后,在性能面前,我被dojo彻底打败,如此的速度是任何客户都无法忍受的,客户不可能为了这个系统全部升级电脑cpu。而且还有很多未知的问题可能还没有被发觉,不如内存泄露,可能导致资源耗尽,内存耗尽。cpu 的占用可能在使用时间长了之后越来越高,等等,这些都是我担心的问题。

 

使用Ajax或者说Rich client,一定要谨慎啊。使用新的技术和框架,一定要谨慎,这是我的教训,希望给同行们一个参考。

posted @ 2008-06-04 11:32 vesung 阅读(2087) | 评论 (2)编辑 收藏

看两段代码:
import java.util.ArrayList;   
import java.util.List;   
  
public class TailRecursionTest {   
    
public static void main(String[] args) {   
        TailRecursionTest t 
= new TailRecursionTest();   
        
for (int i = 0; i < 10000; i++)   
            t.a(
0);   
    }
   
  
    
public void a(int j) {   
        j
++;   
        List list 
= new ArrayList<Integer>(100000);   
        
// 对list进行处理   
    }
   
}

没啥特殊的,仅仅是为了测试,我们将a方法调用10000次,a方法创建一个有100000个元素的list的局部变量。
第二个程序:
import java.util.ArrayList;   
import java.util.List;   
  
public class TailRecursionTest2 {   
    
public static void main(String[] args) {   
        TailRecursionTest2 t 
= new TailRecursionTest2();   
        t.a(
0);   
    }
   
  
    
public void a(int j) {   
        System.out.println(j);   
        j
++;   
        
if (j == 10000)   
            
return;   
        List list 
= new ArrayList<Integer>(100000);   
        
// 对list进行处理   
        a(j);   
    }
   
}
  

也没啥特殊的,就是将循环换成了递归,a方法做的事情没变。两个都跑一下,程序1顺利结束,程序2出问题了,啥问题?如下:
161  
162  
163  
164  
165  
Exception in thread 
"main" java.lang.OutOfMemoryError: Java heap space   
    at java.util.ArrayList.
<init>(Unknown Source)   
    at TailRecursionTest2.a(TailRecursionTest2.java:
17)   
    at TailRecursionTest2.a(TailRecursionTest2.java:
20)   
    at TailRecursionTest2.a(TailRecursionTest2.java:
20)   
    at TailRecursionTest2.a(TailRecursionTest2.java:
20)   
    at TailRecursionTest2.a(TailRecursionTest2.java:
20

我倒,才运行166次了,heap就满了。问题在哪呢?oh,yep,你肯定想到了,是不是重复创建list这个大集合引起的呢?它不是局部变量吗?怎么也会溢出?是的,list是局部变量,在a的方法栈里引用着,指向heap上的大对象,更关键的问题在于,java是没有尾递归优化的,递归方法是不会使用同一个栈帧,每一次递归调用,都将压入新的栈帧,并且这个栈帧上又new了一个list变量,引用着heap上新的一个大集合。随着栈深度的增加, jvm里维持着一条长长的方法调用轨迹以便你能回来,在方法没有返回之前,这些list变量一直被各自的栈帧引用着,不能被GC,你说,能不OOM吗?

    也许,你想到了个补救方法来挽救程序2,就是每次在处理完list后,我把它设置为null,不让栈帧继续引用着它,咱编写对gc友好的代码,这不就行了,试试:


import java.util.ArrayList;   
import java.util.List;   
  
public class TailRecursionTest2 {   
    
public static void main(String[] args) {   
        TailRecursionTest2 t 
= new TailRecursionTest2();   
        t.a(
0);   
    }
   
  
    
public void a(int j) {   
        System.out.println(j);   
        j
++;   
        
if (j == 10000)   
            
return;   
        List list 
= new ArrayList<Integer>(100000);   
        
// 对list进行处理   
        list = null;  //gc友好   
        a(j);   
    }
   
}
 

得意洋洋,我跑一下看看,这次跑到4000多次,但是:
   
4289  
4290  
4291  
4292  
java.lang.StackOverflowError   
    at sun.nio.cs.ext.DoubleByteEncoder.encodeArrayLoop(Unknown Source)   
    at sun.nio.cs.ext.DoubleByteEncoder.encodeLoop(Unknown Source)   
    at java.nio.charset.CharsetEncoder.encode(Unknown Source) 

总结:在java里,递归最好咱还是别用,老老实实地while、for;就算递归了,最好递归方法不要new太大的对象,除非你能确定递归的深度不是那么大,否则OOM和堆栈溢出的阴影将笼罩着你。
posted @ 2008-06-03 09:14 vesung 阅读(1554) | 评论 (0)编辑 收藏

先看下面表格:

作用域
当前类 同一package 子孙类
其他package
public √   
√   
√   
√   
protected
√   
√   
√   
  × 
default √   
√   
  × 
  × 
private √   
  × 
  × 
  × 

不写时默认为default

我们先看类:

public class  Test 可以在任何地方访问,无论是否为当前package
class Test 只允许当前的package使用,不允许其它package使用
class 不与许prirvate和protected ,所以不讨论了

我们再看方法
private 的只允许类自己使用,子类都不可见。但允许inner类调用,因为inner类属于他自己。

class Test 里面的方法
  public 和default和protected 方法,允许同包的访问,因为类是default的,所以方法不可能大于它

public class Test 里面的方法
  private 只允许自己内部访问
 default 只允许同包的访问
  protected 只允许同包和子类访问
  public 可以任意访问
posted @ 2008-06-02 09:12 vesung 阅读(872) | 评论 (0)编辑 收藏

     摘要:   默认的序列化机制并不难操纵。然而,假若有特殊要求又该怎么办呢?我们可能有特殊的安全问题,不希望对象的某一部分序列化;或者某一个子对象完全不必序列化,因为对象恢复以后,那一部分需要重新创建。 此时,通过实现Externalizable接口,用它代替Serializable接口,便可控制序列化的具体过程。这个Externalizable接口扩展了Serializable,并增添了两个...  阅读全文
posted @ 2008-05-28 12:00 vesung 阅读(671) | 评论 (0)编辑 收藏

JNDI是J2EE中一个很重要的标准,通常我们是在EJB编程中用到, 
Tomcat4.0中提供了在JSP和Servelt中直接使用JNDI的方法,下面谈一下在Tomcat4.0中配置和使用JNDI的方法 
(以通过JNDI连接数据库为例) 
假设使用的数据库是mysql,实验例子在TOMCAT_HOME/webapps/DBTest目录中 

A.将mysql的JDBC连接库mm.mysql-2.0.9-bin.jar放入TOMCAT_HOME/common/lib中 

B.配置TOMCAT_HOME/conf/serer.xml文件在<Service>;段中加入一个Context: 
<Context path="/DBTest" docBase="DBTest" 
debug="5" reloadable="true" crossContext="true"> 
</Context> 
这是DBTest的根路径,这是为了在DBTest中使用做准备. 

C.在上面加入的<Context>;段加入 
<Resource name="jdbc/TestDB" 
auth="Container" 
type="javax.sql.DataSource"/> 

<ResourceParams name="jdbc/TestDB">
<parameter> 
<name>;factory</name> 
<value>;org.apache.commons.dbcp.BasicDataSourceFactory</value> 
</parameter> 

<!-- Maximum number of dB connections in pool. Make sure you 
configure your mysqld max_connections large enough to handle 
all of your db connections. Set to 0 for no limit. 
--> 
<parameter>
<name>;maxActive</name>
<value>;100</value>
</parameter>

<!-- Maximum number of idle dB connections to retain in pool. 
Set to 0 for no limit. 
-->
<parameter> 
<name>;maxIdle</name> 
<value>;30</value> 
</parameter> 

<!-- Maximum time to wait for a dB connection to become available 
in ms, in this example 10 seconds. An Exception is thrown if 
this timeout is exceeded. Set to -1 to wait indefinitely. 
--> 
<parameter> 
<name>;maxWait</name> 
<value>;10000</value> 
</parameter> 

<!-- MySQL dB username and password for dB connections --> 
<parameter> 
<name>;username</name>; 
<value>;test</value> 
</parameter> 
<parameter> 
<name>;password</name> 
<value>;test</value> 
</parameter> 

<!-- Class name for mm.mysql JDBC driver -->; 
<parameter>; 
<name>;driverClassName</name>; 
<value>;org.gjt.mm.mysql.Driver</value> 
</parameter> 

<!-- The JDBC connection url for connecting to your MySQL dB.--> 
<parameter> 
<name>;url</name> 
<value>;jdbc:mysql://localhost:3306/test</value> 
</parameter> 
</ResourceParams> 

这里每一个小段都有英文注解,是Tomcat提供的,我们可以将按照Sample加入,主要修改的是driverClassName, 
url,和用户帐号;需要强调的是"jdbc/TestDB"就是JDNI要查找的Name.

在web.xml中加入 
<resource-ref> 
<description>;DB Connection</description> 
<res-ref-name>;jdbc/TestDB</res-ref-name> 
<res-type>;javax.sql.DataSource</res-type> 
<res-auth>;Container</res-auth> 
</resource-ref> 
这里的jdbc/TestDb要和C中Resource段的name匹配 

posted @ 2008-04-25 09:02 vesung 阅读(426) | 评论 (0)编辑 收藏

一、DataSource接口是一个更好的连接数据源的方法:
  JDBC1.0是原来是用DriverManager类来产生一个对数据源的连接。JDBC2.0用一种替代的方法,使用DataSource的实现,代码变的更小巧精致,也更容易控制。
  一个DataSource对象代表了一个真正的数据源。根据DataSource的实现方法,数据源既可以是从关系数据库,也电子表格,还可以是一个表格形式的文件。当一个DataSource对象注册到名字服务中,应用程序就可以通过名字服务获得DataSource对象,并用它来产生一个与DataSource代表的数据源之间的连接。
  关于数据源的信息和如何来定位数据源,例如数据库服务器的名字,在哪台机器上,端口号等等,都包含在DataSource对象的属性里面去了。这样,对应用程序的设计来说是更方便了,因为并不需要硬性的把驱动的名字写死到程序里面去。通常驱动名字中都包含了驱动提供商的名字,而在DriverManager类中通常是这么做的。如果数据源要移植到另一个数据库驱动中,代码也很容易做修改。所需要做的修改只是更改DataSource的相关的属性。而使用DataSource对象的代码不需要做任何改动。
  由系统管理员或者有相应权限的人来配置DataSource对象。配置DataSource,包括设定DataSource的属性,然后将它注册到JNDI名字服务中去。在注册DataSource对象的的过程中,系统管理员需要把DataSource对象和一个逻辑名字关联起来。名字可以是任意的,通常取成能代表数据源并且容易记住的名字。在下面的例子中,名字起为:InventoryDB,按照惯例,逻辑名字通常都在jdbc的子上下文中。这样,逻辑名字的全名就是:jdbc/ InventoryDB。
  一旦配置好了数据源对象,应用程序设计者就可以用它来产生一个与数据源的连接。下面的代码片段示例了如何用JNDI上下文获得一个一个数据源对象,然后如何用数据源对象产生一个与数据源的连接。开始的两行用的是JNDI API,第三行用的才是JDBC的API:
   Context ctx = new InitialContext(); DataSource ds = (DataSource)ctx.lookup("jdbc/InventoryDB");Connection con = ds.getConnection("myPassword", "myUserName");
  在一个基本的DataSource实现中,DataSource.getConnection方法返回的Connection对象和用DriverManager.getConnection方法返回的Connection对象是一样的。因为DataSource提供的方便性,我们推荐使用DataSource对象来得到一个Connection对象。我们希望所以的基于JDBC2.0技术的数据库驱动都包含一个基本的DataSource的实现,这样就可以在应用程序中很容易的使用它。
  对于普通的应用程序设计者,是否使用DataSource对象只是一个选择问题。但是,对于那些需要用的连接池或者分布式的事务的应用程序设计者来说,就必须使用DataSource对象来获得Connection,原因在下面我们会提到。
   二、Connection pooling(连接池):
  连接池是这么一种机制,当应用程序关闭一个Connection的时候,这个连接被回收,而不是被destroy,因为建立一个连接是一个很费资源的操作。如果能把回收的连接重新利用,会减少新创建连接的数目,显著的提高运行的性能。
  假设应用程序需要建立到一个名字为EmpolyeeDB的DataSource的连接。使用连接池得到连接的代码如下:
   Context ctx = new InitialContext(); DataSource ds = (DataSource)ctx.lookup("jdbc/EmployeeDB");Connection con = ds.getConnection("myPassword", "myUserName");除了逻辑名字以外,我们发现其代码和上面举的例子的代码是一样的。逻辑名字不同,就可以连接到不同的数据库。DataSource对象的getConnection方法返回的Connection是否是一个连接池中的连接完全取决于DataSource对象的实现方法。如果DataSource对象实现与一个支持连接池的中间层的服务器一起工作,DataSource对象就会自动的返回连接池中的连接,这个连接也是可以重复利用的。
  是否使用连接池获得一个连接,在应用程序的代码上是看不出不同的。在使用这个Connection连接上也没有什么不一样的地方,唯一的不同是在java的finally语句块中来关闭一个连接。在finally中关闭连接是一个好的编程习惯。这样,即使方法抛出异常,Connection也会被关闭并回收到连接池中去。代码应该如下所示:
  try{…
  }catch(){…
  }finally{ if(con!=null)con.close();}
  三、分布式事务:
  获得一个用来支持分布式事务的连接与获得连接池中的连接是很相似的。同样,不同之处在于DataSource的实现上的不同,而不是在应用程序中获得连接的方式上有什么不同。假设DataSource的实现可以与支持分布式事务中间层服务器一起工作,得到连接的代码还是如下所示:
   Context ctx = new InitialContext(); DataSource ds = (DataSource)ctx.lookup("jdbc/EmployeeDB"); Connection con = ds.getConnection("myPassword", "myUserName");由于性能上的原因,如果一个DataSource能够支持分布式的事务,它同样也可以支持连接池管理。
  从应用程序设计者的观点来看。是否支持分布式的事务的连接对它来说没什么不同,唯一的不同是在事务的边界上(开始一个事务的地方和结束一个事务的地方),开始一个事务或者结束一个事务都是由事务服务器来控制的。应用程序不应该做任何可能妨碍服务的事情。应用程序不能够直接调用事务提交commit或者回滚rollback操作,也不能够使用事务的自动提交模式auto-commit mode(在数据库操作完成的时候自动的调用commit或者rollback)。 
 
在一个连接参与了分布式事务的时候,下面的代码是你不能做的(con表示支持分布式事务的连接Connection)。
  con.commit();或者con.rollback();或者con.setAutoCommit(true);对于通常的Connection来说,缺省的是auto-commit模式。而对于支持分布式事务的Connection来说,缺省不是auto-commit模式。注意,即使Connection是支持事务的,它也可以用于没有事务的情况。关于事务边界的限制只是是对分布式事务的情况下才成立的。
  配置支持连接池的DataSource的时候,涉及到配置ConnectionPoolDataSource对象,这个对象是三层体系结构中的中间层来管理连接池的。同样的,在配置支持分布式事务的时候,需要配置XADataSource,XADataSource是中间层用来管理分布式事物的对象。ConnectionPoolDataSource和XADataSource是由驱动提供商提供的,对应用程序的设计者来说是透明的。和基本的DataSource一样,系统管理员来配置ConnectionPoolDataSource和XADataSource对象。
  四、结果集(RowSet接口):
  结果集对象是一行行数据的容器。根据其目的,可以通过多种方法实现。RowSet及其相关的接口与JDBC2.0的标准扩展API有点不同,他们并不是驱动的一部分,RowSet是在驱动的上层实现的,可以由其它的任何人来实现他们。
  任何类型的rowset都实现了RowSet接口,RowSet接口扩展了ResultSet接口。这样RowSet对象就有了ResultSet对象所有的功能。能够通过getXXX方法得到数据库中的某列值,通过updateXXX方法可以修改某列值,可以移动光标,是当前行变为另一行。
  当然,我们更感兴趣的是RowSet接口提供的新的功能。作为一个JavaBean组件,RowSet对象可以增加或者删除一个listener(监听者),可以get或者set其属性值,这些属性中,有一个是字符串,表示一个对数据库Query请求,RowSet接口定义了设定参数的方法,也提供了执行这个请求的方法。这意味着RowSet对象能够执行查询请求,可以根据它产生的结果集进行计算。同样,RowSet也可以根据任何表格数据源进行计算,所以,它不局限于关系数据库。
  从数据源得到数据之后,RowSet对象可以和数据源断开连接,rowset也可以被序列化。这样,RowSet就可以通过网络传递给瘦客户端。
  RowSet可以被重新连接到数据源,这样,做的修改就可以存回到数据源中去。如果产生了一个listener,当RowSet的当前行移动,或者数据被修改的时候,监听者就会收到通知。例如,图形用户界面组件可以注册成为监听者,当RowSet更改的时候,图形用户界面接到通知,就可以修改界面,来符合它所表示的RowSet。
  根据不同的需要,RowSet接口可以通过多种方法来实现。Java software已经写了一个CachedRowSet实现,从http://developer.java.sun.com/developer/earlyAccess/crs/index.html中可以得到这个实现。
  与CachedRowSet类不样的是,JDBCRowSet类总是保持一个和数据源的连接。这样,在ResultSet外围简单到加了一层,是基于JDBC技术的驱动看起来象是一个简单的JavaBean组件一样。

  总结:JDBC2.0标准扩展API通过见DataSource注册到JNDI名字服务上,将JDBC技术扩展为一个全新的概念。使应用程序的代码更加精巧,易于控制。新的API支持了连接池,支持分布式的事务。最后,还使java应用程序可以在网络上传播结果集,是不可以滚动的ResultSet变成了可以滚动的RowSet。
posted @ 2008-04-21 08:58 vesung 阅读(3249) | 评论 (0)编辑 收藏

JDBC 2.0 API被划分为两部分:JDBC 2.0核心API和JDBC 2.0标准扩展API。核心API在java.sql里面。这是原来的版本就实现了的基本的功能。标准扩展API在javax.sql里面。由JDBC2.0规范新规定的一些接口在这里面。当然,JDBC2.0也对原来版本的java.sql核心做了一些改动。不过不是很大。原来JDBC1.0的程序可以不加修改的在JDBC2.0上运行。这是Java的一贯的良好的作风。最新的JDBC包可以从sun公司的网站上下载。 
  JDBC2.0的扩展API增加了一些数据访问和数据源访问的重大的功能。这中间有一些是主要用来做企业计算的。用JDBC2.0的新的扩展包,JDBC提供了一个从JAVA2平台的通用的数据访问的方法。
  首先,我们来看看JDBC标准扩展的API怎样来和JDBC2.0结合在一起的。JDBC2.0包括两个包:
  1、 java.sql包,个包里面是JDBC2.0的核心API。它包括了原来的JDBC API(JDBC 1.0版本),再加上一些新的2.0版本的API。这个包在Java 2 Platform SDK里面有。
  2、 javax.sql包,这里面是JDBC2.0的标准扩展API。这个包是一个全新的,在Java 2 Platform SDK, Enterprise Edition里面单独提供。
  JDBC2.0的核心API包括了JDBC1.0的API,并在此基础上增加了一些功能,对某些性能做了增强。使java语言在数据库计算的前端提供了统一的数据访问方法,效率也得到了提高。
  JDBC是向后兼容的,JDBC1.0的程序可以不加修改的运行在JDBC2.0上。但是,假如程序中用到了JDBC2.0的新特性,就必须要运行在JDBC2.0版本上。
  概括的来说,JDBC核心API的新特性在两个方面做了工作。一个是支持一些新的功能,另一个就是支持SQL3的数据类型。
  1、 在支持新功能方面:包括结果集可以向后滚动,批量的更新数据。另外,还提供了UNICODE字符集的字符流操作。
  2、 在支持SQL3的数据类型方面:包括新的SQL3数据类型,增加了对持久性对象的存贮。
  为了对数据的存取,操作更加方便,JDBC的新特性是应用程序的设计更容易了。例如:数据块的操作能够显著的提高数据库访问的性能。新增加的BLOB, CLOB,和数组接口能够是应用程序操作大块的数据类型,而不必客户端在存贮之前进行其它的处理。这样,就显著的提高了内存的使用效率。
   下面我们来介绍JDBC2.0的标准扩展API。标准扩展API分为如下几个方面:
  1、 DataSource接口:和Java名字目录服务(JNDI)一起工作的数据源接口。它提供了对数 吹囊恢指玫牧臃椒ā?br>;  2、 Connection pooling(连接池):可以重复使用连接,而不是对每个请求都使用一个新的连接。
  3、 Distrubute transaction(分布式的事务):在一个事务中涉及到了多个数据库服务器。
  4、 Rowsets:JavaBean组件包含了结果集,主要用来将数据传给瘦客户,或者提供一个可以滚动的结果集。
posted @ 2008-04-10 11:29 vesung 阅读(705) | 评论 (0)编辑 收藏