随笔-88  评论-77  文章-48  trackbacks-0
  2006年6月1日

发布21个已知被微软黑屏的序列号提醒相关用户不要冒险去验证升级

发布21个已知被微软黑屏的序列号,提醒使用该序列号的用户就不要冒险去验证升级了。

已知被黑屏的序列号(这21个序列号是我今天一个个通过验证测试出来的结果):

XP8BF-F8HPF-PY6BX-K24PJ-TWT6M 

F4297-RCWJP-P482C-YY23Y-XH8W3

HH7VV-6P3G9-82TWK-QKJJ3-MXR96

HCQ9D-TVCWX-X9QRG-J4B2Y-GR2TT

MRX3F-47B9T-2487J-KWKMF-RPWBY

T72KM-6GWBP-GX7TD-CXFT2-7WT2B

QHYXK-JCJRX-XXY8Y-2KX2X-CCXGD

DG8FV-B9TKY-FRT9J-6CRCC-XPQ4G

MFBF7-2CK8B-93MDB-8MR7T-4QRCQ

MRX3F-47B9T-2487J-KWKMF-RPWBY

DFXFM-DKWTG-MYDWJ-68DQF-YBCYG

TB7JC-3VJKY-J3VMR-PP8TP-HMTWY

KR88V-RCBCB-D78QP-V4FF9-JW77M

HWCTG-CQPWK-D22DQ-JD7TQ-GXVW8

Q7TG8-MQ3BK-RHXQC-YDXJD-6Q6M3

BP6XM-YXMKY-V4Q74-KJP8X-VW3CQ

BFBPF-TF64Y-BT8T9-DQJFY-3TH7W

GQ9CX-QDFPR-XFRMF-T3M94-2JG9Y

XPF44-PDM32-XT4B8-R8W8C-CPP6T

RC7QJ-KX66J-V4R9W-32HC4-CJH2B

DDQXW-THQ8M-79V6K-2YFGH-R793Q

注:但有网友反映MRX3F-47B9T-2487J-KWKMF-RPWBY这个序列号有些地方能通过正版验证,有些地方不能通过正版验证,看来微软这次验证还分蛮细的,并可以按地区来判断序列号是否为盗版和正版呀。
posted @ 2008-10-26 00:40 崛起的程序员 阅读(368) | 评论 (0)编辑 收藏

AJAX 流行之后,总想好好学习一下。但是众多的框架实在难以选择。说明一下 ASP.NET AJAX 并不包括在 AJAX 框架之中。
刚开始学了 JQuqery, 众多的 $get(),...等等符号早已把我搞晕了。暂时就放弃了。
后来学习 ASP.NET AJAX ,在微软的领导下,逐渐由服务器端转向客户端编程。 激起我客户端编程的兴趣,
才想起学习一下了 Jquery.
      随着WEB2.0及ajax思想在互联网上的快速发展传播,陆续出现了一些优秀的Js框架,其中比较著名的有Prototype、YUI、jQuery、mootools、Bindows以及国内的JSVM框架等,通过将这些JS框架应用到我们的项目中能够使程序员从设计和书写繁杂的JS应用中解脱出来,将关注点转向功能需求而非实现细节上,从而提高项目的开发速度。
      jQuery是继prototype之后的又一个优秀的Javascript框架。它是由 John Resig 于 2006 年初创建的,它有助于简化 JavaScript™ 以及Ajax 编程。有人使用这样的一比喻来比较prototype和jQuery:prototype就像Java,而jQuery就像ruby. 它是一个简洁快速灵活的JavaScript框架,它能让你在你的网页上简单的操作文档、处理事件、实现特效并为Web页面添加Ajax交互。

它具有如下一些特点:
1、代码简练、语义易懂、学习快速、文档丰富。
2、jQuery是一个轻量级的脚本,其代码非常小巧,最新版的JavaScript包只有20K左右。
3、jQuery支持CSS1-CSS3,以及基本的xPath。
4、jQuery是跨浏览器的,它支持的浏览器包括IE 6.0+, FF 1.5+, Safari 2.0+, Opera 9.0+。
5、可以很容易的为jQuery扩展其他功能。
6、能将JS代码和HTML代码完全分离,便于代码和维护和修改。
7、插件丰富,除了jQuery本身带有的一些特效外,可以通过插件实现更多功能,如表单验证、tab导航、拖放效果、表格排序、DataGrid,树形菜单、图像特效以及ajax上传等。

jQuery的设计会改变你写JavaScript代码的方式,降低你学习使用JS操作网页的复杂度,提高网页JS开发效率,无论对于js初学者还是资深专家,jQuery都将是您的首选。
jQuery适合于设计师、开发者以及那些还好者,同样适合用于商业开发,可以说jQuery适合任何JavaScript应用的地方,可用于不同的Web应用程序中。
官方站点:http://jquery.com/  中文站点:http://jquery.org.cn/

1.2、目的
通过学习本文档,能够对jQuery有一个简单的认识了解,清楚JQuery与其他JS框架的不同,掌握jQuery的常用语法、使用技巧及注意事项。

二、使用方法
在需要使用JQuery的页面中引入JQuery的js文件即可。
例如:<script type="text/javascript" src="js/jquery.js"></script>
引入之后便可在页面的任意地方使用jQuery提供的语法。

三、学习教程及参考资料
请参照《jQuery中文API手册》和http://jquery.org.cn/visual/cn/index.xml
推荐两篇不错的jquery教程:《jQuery的起点教程》和《使用 jQuery 简化 Ajax 开发》


四、语法总结和注意事项

1、关于页面元素的引用
通过jquery的$()引用元素包括通过id、class、元素名以及元素的层级关系及dom或者xpath条件等方法,且返回的对象为jquery对象(集合对象),不能直接调用dom定义的方法。

2、jQuery对象与dom对象的转换
只有jquery对象才能使用jquery定义的方法。注意dom对象和jquery对象是有区别的,调用方法时要注意操作的是dom对象还是jquery对象。
普通的dom对象一般可以通过$()转换成jquery对象。
如:$(document.getElementById("msg"))则为jquery对象,可以使用jquery的方法。
由于jquery对象本身是一个集合。所以如果jquery对象要转换为dom对象则必须取出其中的某一项,一般可通过索引取出。
如:$("#msg")[0],$("div").eq(1)[0],$("div").get()[1],$("td")[5]这些都是dom对象,可以使用dom中的方法,但不能再使用Jquery的方法。
以下几种写法都是正确的:
$("#msg").html();
$("#msg")[0].innerHTML;
$("#msg").eq(0)[0].innerHTML;
$("#msg").get(0).innerHTML;

3、如何获取jQuery集合的某一项
对于获取的元素集合,获取其中的某一项(通过索引指定)可以使用eqget(n)方法或者索引号获取,要注意,eq返回的是jquery对象,而get(n)和索引返回的是dom元素对象。对于jquery对象只能使用jquery的方法,而dom对象只能使用dom的方法,如要获取第三个<div>元素的内容。有如下两种方法:
$("div").eq(2).html();    //调用jquery对象的方法
$("div").get(2).innerHTML;  //调用dom的方法属性

4、同一函数实现set和get
Jquery中的很多方法都是如此,主要包括如下几个:
$("#msg").html();    //返回id为msg的元素节点的html内容。
$("#msg").html("<b>new content</b>");  
//将“<b>new content</b>” 作为html串写入id为msg的元素节点内容中,页面显示粗体的new content

$("#msg").text();    //返回id为msg的元素节点的文本内容。
$("#msg").text("<b>new content</b>");  
//将“<b>new content</b>” 作为普通文本串写入id为msg的元素节点内容中,页面显示<b>new content</b>

$("#msg").height();    //返回id为msg的元素的高度
$("#msg").height("300");  //将id为msg的元素的高度设为300
$("#msg").width();    //返回id为msg的元素的宽度
$("#msg").width("300");  //将id为msg的元素的宽度设为300

$("input").val(");  //返回表单输入框的value值
$("input").val("test");  //将表单输入框的value值设为test

$("#msg").click();  //触发id为msg的元素的单击事件
$("#msg").click(fn);  //为id为msg的元素单击事件添加函数
同样blur,focus,select,submit事件都可以有着两种调用方法

5、集合处理功能
对于jquery返回的集合内容无需我们自己循环遍历并对每个对象分别做处理,jquery已经为我们提供的很方便的方法进行集合的处理。
包括两种形式:
$("p").each(function(i){this.style.color=['#f00','#0f0','#00f'][i]})  
//为索引分别为0,1,2的p元素分别设定不同的字体颜色。

$("tr").each(function(i){this.style.backgroundColor=['#ccc','#fff'][i%2]})  
//实现表格的隔行换色效果

$("p").click(function(){alert($(this).html())})    
//为每个p元素增加了click事件,单击某个p元素则弹出其内容

6、扩展我们需要的功能
$.extend({
  min: function(a, b){return a < b?a:b; },
  max: function(a, b){return a > b?a:b; }
});  //为jquery扩展了min,max两个方法
使用扩展的方法(通过“$.方法名”调用):
alert("a=10,b=20,max="+$.max(10,20)+",min="+$.min(10,20));

7、支持方法的连写
所谓连写,即可以对一个jquery对象连续调用各种不同的方法。
例如:
$("p").click(function(){alert($(this).html())})
.mouseover(function(){alert('mouse over event')})
.each(function(i){this.style.color=['#f00','#0f0','#00f'][i]});

8、操作元素的样式
主要包括以下几种方式:
$("#msg").css("background");    //返回元素的背景颜色
$("#msg").css("background","#ccc")  //设定元素背景为灰色
$("#msg").height(300); $("#msg").width("200");  //设定宽高
$("#msg").css({ color: "red", background: "blue" });//以名值对的形式设定样式
$("#msg").addClass("select");  //为元素增加名称为select的class
$("#msg").removeClass("select");  //删除元素名称为select的class
$("#msg").toggleClass("select");  //如果存在(不存在)就删除(添加)名称为select的class

9、完善的事件处理功能
Jquery已经为我们提供了各种事件处理方法,我们无需在html元素上直接写事件,而可以直接为通过jquery获取的对象添加事件。
如:
$("#msg").click(function(){alert("good")})  //为元素添加了单击事件
$("p").click(function(i){this.style.color=['#f00','#0f0','#00f'][i]})
//为三个不同的p元素单击事件分别设定不同的处理
jQuery中几个自定义的事件:
(1)hover(fn1,fn2):一个模仿悬停事件(鼠标移动到一个对象上面及移出这个对象)的方法。当鼠标移动到一个匹配的元素上面时,会触发指定的第一个函数。当鼠标移出这个元素时,会触发指定的第二个函数。
//当鼠标放在表格的某行上时将class置为over,离开时置为out。
$("tr").hover(function(){
$(this).addClass("over");
},
  function(){
   $(this).addClass("out");
});
(2)ready(fn):当DOM载入就绪可以查询及操纵时绑定一个要执行的函数。
$(document).ready(function(){alert("Load Success")})
//页面加载完毕提示“Load Success”,相当于onload事件。与$(fn)等价
(3)toggle(evenFn,oddFn): 每次点击时切换要调用的函数。如果点击了一个匹配的元素,则触发指定的第一个函数,当再次点击同一元素时,则触发指定的第二个函数。随后的每次点击都重复对这两个函数的轮番调用。
  //每次点击时轮换添加和删除名为selected的class。
  $("p").toggle(function(){
    $(this).addClass("selected");  
  },function(){
     $(this).removeClass("selected");
  });
(4)trigger(eventtype): 在每一个匹配的元素上触发某类事件。
例如:
  $("p").trigger("click");    //触发所有p元素的click事件
(5)bind(eventtype,fn),unbind(eventtype): 事件的绑定与反绑定
从每一个匹配的元素中(添加)删除绑定的事件。
例如:
$("p").bind("click", function(){alert($(this).text());});  //为每个p元素添加单击事件
$("p").unbind();  //删除所有p元素上的所有事件
$("p").unbind("click")  //删除所有p元素上的单击事件

10、几个实用特效功能
其中toggle()和slidetoggle()方法提供了状态切换功能。
如toggle()方法包括了hide()和show()方法。
slideToggle()方法包括了slideDown()和slideUp方法。

11、几个有用的jQuery方法
$.browser.浏览器类型:检测浏览器类型。有效参数:safari, opera, msie, mozilla。如检测是否ie:$.browser.isie,是ie浏览器则返回true。
$.each(obj, fn):通用的迭代函数。可用于近似地迭代对象和数组(代替循环)。

$.each( [0,1,2], function(i, n){ alert( "Item #" + i + ": " + n ); });
等价于:
var tempArr=[0,1,2];
for(var i=0;i<tempArr.length;i++){
  alert("Item #"+i+": "+tempArr[i]);
}
也可以处理json数据,如
$.each( { name: "John", lang: "JS" }, function(i, n){ alert( "Name: " + i + ", Value: " + n ); });
结果为:
Name:name, Value:John
Name:lang, Value:JS
$.extend(target,prop1,propN):用一个或多个其他对象来扩展一个对象,返回这个被扩展的对象。这是jquery实现的继承方式。
如:
$.extend(settings, options);  
//合并settings和options,并将合并结果返回settings中,相当于options继承setting并将继承结果保存在setting中。
var settings = $.extend({}, defaults, options);
//合并defaults和options,并将合并结果返回到setting中而不覆盖default内容。
可以有多个参数(合并多项并返回)
$.map(array, fn):数组映射。把一个数组中的项目(处理转换后)保存到到另一个新数组中,并返回生成的新数组。
如:
var tempArr=$.map( [0,1,2], function(i){ return i + 4; });
tempArr内容为:[4,5,6]
var tempArr=$.map( [0,1,2], function(i){ return i > 0 ? i + 1 : null; });
tempArr内容为:[2,3]
$.merge(arr1,arr2):合并两个数组并删除其中重复的项目。
如:$.merge( [0,1,2], [2,3,4] )  //返回[0,1,2,3,4]
$.trim(str):删除字符串两端的空白字符。
如:$.trim("  hello, how are you?   ");   //返回"hello,how are you? "

12、解决自定义方法或其他类库与jQuery的冲突
很多时候我们自己定义了$(id)方法来获取一个元素,或者其他的一些js类库如prototype也都定义了$方法,如果同时把这些内容放在一起就会引起变量方法定义冲突,Jquery对此专门提供了方法用于解决此问题。
使用jquery中的jQuery.noConflict();方法即可把变量$的控制权让渡给第一个实现它的那个库或之前自定义的$方法。之后应用Jquery的时候只要将所有的$换成jQuery即可,如原来引用对象方法$("#msg")改为jQuery("#msg")。
如:
jQuery.noConflict();
// 开始使用jQuery
jQuery("div   p").hide();
// 使用其他库的 $()
$("content").style.display = 'none';

posted @ 2008-09-21 21:24 崛起的程序员 阅读(308) | 评论 (0)编辑 收藏
1377-4167-5844-4698-0048-5821
posted @ 2008-03-02 19:35 崛起的程序员 阅读(332) | 评论 (0)编辑 收藏

Flex License:
1307-1581-4356-2616-4951-7949 (Commercial Version)
1307-1581-4356-2939-1231-4484 (Education Version)

Charting License:

1301-4581-4356-7349-9369-3351 (Commercial Version)

posted @ 2008-02-24 21:43 崛起的程序员 阅读(400) | 评论 (0)编辑 收藏

Today we shipped Visual Studio 2008 and .NET 3.5.  You can download the final release using one of the links below:

  • If you are a MSDN subscriber, you can download your copy from the MSDN subscription site (note: some of the builds are just finishing being uploaded now - so check back later during the day if you don't see it yet).

  • If you are a non-MSDN subscriber, you can download a 90-day free trial edition of Visual Studio 2008 Team Suite here.  A 90-day trial edition of Visual Studio 2008 Professional (which will be a slightly smaller download) will be available next week.  A 90-day free trial edition of Team Foundation Server can also be downloaded here.

  • If you want to use the free Visual Studio 2008 Express editions (which are much smaller and totally free), you can download them here

  • If you want to just install the .NET Framework 3.5 runtime, you can download it here.

Quick Tour of Some of the New Features

Visual Studio 2008 and .NET 3.5 contain a ton of new functionality and improvements.  Below are links to blog posts I've done myself as well as links to videos you can watch to learn more about it:

VS 2008 Multi-Targeting Support

VS 2008 enables you to build applications that target multiple versions of the .NET Framework.  This means you can use VS 2008 to open, edit and build existing .NET 2.0 and ASP.NET 2.0 applications (including ASP.NET 2.0 applications using ASP.NET AJAX 1.0), and continue to deploy these application on .NET 2.0 machines.  You can learn more about how this works from my blog post here:

ASP.NET AJAX and JavaScript Support

.NET 3.5 has ASP.NET AJAX built-in (no separate download required).  In addition to including all of the features in ASP.NET AJAX 1.0, ASP.NET 3.5 also now includes richer support for UpdatePanels integrating with WebParts, ASP.NET AJAX integration with controls like <asp:menu> and <asp:treeview>, WCF support for JSON, and many other AJAX improvements.

VS 2008 and Visual Web Developer 2008 also now have great support for integrating JavaScript and AJAX into your applications.  You can learn more about this from my blog posts here:

You can watch some videos that discuss ASP.NET AJAX and Visual Studio 2008 support for it here

I also highly recommend the excellent ASP.NET AJAX in Action book to learn more about ASP.NET AJAX (both client-side and server-side).

VS 2008 Web Designer and CSS Support

VS 2008 and Visual Web Developer 2008 Express includes a significantly improved HTML web designer (the same one that ships with Expression Web).  This delivers support for split-view editing, nested master pages, and great CSS integration.  Below are some articles I've written that discuss this more:

ASP.NET 3.5 also has a new <asp:ListView> control that provides the ability to perform rich data scenarios with total control over the markup.  It works nicely with the new CSS support in VS 2008.  You can learn more about it from my article here:

You can watch some videos that discuss the new Visual Studio 2008 web designer features and the new ListView/DataPager controls here

Language Improvements and LINQ

The new VB and C# compilers in VS 2008 deliver significant improvements to the languages.  Both add functional programming concepts that enable you to write cleaner, terser, and more expressive code.  These features also enable a new programming model we call LINQ (language integrated query) that makes querying and working with data a first-class programming concept with .NET. 

Below are some of the articles I've written that explore these new language features using C#:

Here are a few additional blog posts I've written that show off some of the new VS 2008 code editing support and some cool ways to use these new language features:

The Visual Basic team has also created some great free videos that cover LINQ.  You can watch them here.

Data Access Improvements with LINQ to SQL

LINQ to SQL is a built-in OR/M (object relational mapper) in .NET 3.5.  It enables you to model relational databases using a .NET object model.  You can then query the database using LINQ, as well as update/insert/delete data from it.  LINQ to SQL fully supports transactions, views, and stored procedures.  It also provides an easy way to integrate business logic and validation rules into your data model.  Below are some of the articles I've written that explore how to use it:

I think you'll find that LINQ and LINQ to SQL makes it much easier to build much cleaner data models, and write much cleaner data code.  I'll be adding more posts to my LINQ to SQL series in the weeks and months ahead (sorry for the delay in finishing them earlier - so much to-do and so little time to-do it all!).

Scott Stanfield is also working on creating some great LINQ to SQL videos for the www.asp.net site based on my article series above (all videos are in both VB and C#).  You can watch the first 4 videos in this series here.

Browsing the .NET Framework Library Source using Visual Studio

As I blogged a few weeks ago, we will be releasing a reference version of the .NET Framework library source code as part of this release.  Visual Studio 2008 has built-in debugger support to automatically step-into and debug this code on demand (VS 2008 can pull down the source for the appropriate .NET Framework library file automatically for you).

We are deploying the source servers to enable this right now, and will be publishing the steps to turn this feature on in the next few weeks.

Lots of other improvements

The list above is only a small set of the improvements coming.  For client development VS 2008 includes WPF designer and project support.  ClickOnce and WPF XBAPs now work with FireFox.  WinForms and WPF projects can also now use the ASP.NET Application Services (Membership, Roles, Profile) for roaming user data. 

Office development is much richer - including support for integrating with the Office 2007 ribbon, and with Outlook.  Visual Studio Tools for Office support is also now built-into Visual Studio (you no longer need to buy a separate product).

New WCF and Workflow projects and designers are now included in VS 2008.  Unit testing support is now much faster and included in VS Professional (and no longer just VSTS).  Continuous Integration support is now built-in with TFS.  AJAX web testing (unit and load) is now supported in the VS Test SKU.  And there is much, much more...

Installation Suggestions

People often ask me for suggestions on how best to upgrade from previous betas of Visual Studio 2008.  In general I'd recommend uninstalling the Beta2 bits explicitly.  As part of this you should uninstall Visual Studio 2008 Beta2, .NET Framework Beta2, as well as the Visual Studio Web Authoring Component (these are all separate installs and need to be uninstalled separately).  I then usually recommend rebooting the machine after uninstalling just to make sure everything is clean before you kick off the new install.  You can then install the final release of VS 2008 and .NET 3.5 on the machine.

Once installed, I usually recommend explicitly running the Tools->Import and Export Settings menu option, choosing the "Reset Settings" option, and then re-pick your preferred profile.  This helps ensure that older settings from the Beta2 release are no longer around (and sometimes seems to help with performance).

Note that VS 2008 runs side-by-side with VS 2005 - so it is totally fine to have both on the same machine (you will not have any problems with them on the same box).

Silverlight Tools and VS Web Deployment Project Add-Ins

Two popular add-ins to Visual Studio are not yet available to download for the final VS 2008 release.  These are the Silverlight 1.1 Tools Alpha for Visual Studio and the Web Deployment Project add-in for Visual Studio.  Our hope is to post updates to both of them to work with the final VS 2008 release in the next two weeks.  If you are doing Silverlight 1.1 development using VS 2008 Beta2 you'll want to stick with with VS 2008 Beta2 until this updated Silverlight Tools Add-In is available. 

posted @ 2007-12-02 02:24 崛起的程序员 阅读(845) | 评论 (0)编辑 收藏

PYHYP-WXB3B-B2CCM-V9DX9-VDY8T

在开始>设置>控制面版>添加或删除程序>卸载vs.net2008>出现卸载界面>点击Next>输入上面CD-key ->出现Success画面。。激动ING

本人使用的是VS2008 RTM版..


Microsoft.Visual.Studio.Team.System.2008.Team.Suite-ZWTiSO
ed2k: Microsoft.Visual.Studio.Team.System.2008.Team.Suite-ZWTiSO.iso  [3.83 Gb]
ed2k: Microsoft.Visual.Studio.Team.System.2008.Team.Suite-ZWTiSO.nfo  [5.8 Kb]
[ Add all 2 links to your ed2k client ]

Microsoft.Visual.Studio.2008.Professional.Edition-ZWTiSO
ed2k: Microsoft.Visual.Studio.2008.Professional.Edition-ZWTiSO.iso  [3.31 Gb]
ed2k: Microsoft.Visual.Studio.2008.Professional.Edition-ZWTiSO.nfo  [5.5 Kb]
[ Add all 2 links to your ed2k client ]

Microsoft.Visual.Studio.Team.System.2008.Development.Edition
ed2k: Microsoft.Visual.Studio.Team.System.2008.Development.Edition-ZWTiSO.iso  [3.81 Gb]
ed2k: Microsoft.Visual.Studio.Team.System.2008.Development.Edition-ZWTiSO.nfo  [5.5 Kb]
[ Add all 2 links to your ed2k client ]

Microsoft.Visual.Studio.Team.System.2008.Team.Foundation.Server.Workgroup.Edition-ZWTiSO
ed2k: Microsoft.Visual.Studio.Team.System.2008.Team.Foundation.Server.Workgroup.Edition-ZWTiSO.iso  [1.29 Gb]
ed2k: Microsoft.Visual.Studio.Team.System.2008.Team.Foundation.Server.Workgroup.Edition-ZWTiSO.nfo  [5.7 Kb]
[ Add all 2 links to your ed2k client ]

Microsoft.Visual.Studio.Team.System.2008.Test.Load.Agent-ZWT
ed2k: Microsoft.Visual.Studio.Team.System.2008.Test.Load.Agent-ZWTiSO.iso  [551.01 Mb]
ed2k: Microsoft.Visual.Studio.Team.System.2008.Test.Load.Agent-ZWTiSO.nfo  [5.7 Kb]
[ Add all 2 links to your ed2k client ]

posted @ 2007-12-02 02:21 崛起的程序员 阅读(20607) | 评论 (30)编辑 收藏

注册机下载地址

http://www.blogjava.net/Files/ioriqw/Altova%202008.rar
posted @ 2007-10-30 16:23 崛起的程序员 阅读(993) | 评论 (1)编辑 收藏
     摘要: 在网上找了一圈Ajax的Java框架,感觉不错的只有两个,一个是被提到比较多的DWR(Direct Web Remoting),另一个是刚刚1.0的Ajax4JSF。本文先用代码说话,各用两个框架开发同样功能的Ajax输入验证的小程序。在最后表达一下鄙人对这两个框架的浅见。·程序功能    页面上有两个输入框,一个填用户名,一个填密码。两个框空着时提示...  阅读全文
posted @ 2007-08-27 20:17 崛起的程序员 阅读(561) | 评论 (0)编辑 收藏
Go to window-preferences-java-installed jre's- edit
and add the values
-Xms512m -Xmx512m -Xss256k
(or the amount of memory you want)
eclipse starts tomcat with those values, so your memory problems should be solved
posted @ 2007-06-10 22:26 崛起的程序员 阅读(374) | 评论 (0)编辑 收藏
 
有个系统隐藏的文件夹System Volume Information会达到1G甚至20G,这是系统还原的文件夹,这个目录是WINDOWS对于大硬盘搜索方便的索引记录文件!会在WINDOWS空闲时自动记录,所以这个文件夹会越来越大,然后PF使用率不断上升,导致机器卡住!&W&D.C g V b j [ a
我们可以禁用这个自动索引功能!打开搜索功能->改变首选项->不使用制作索引服务->不,不要启用制作索引服务->确定。还有一件事,就是回到刚才的地方,下面还有一个“改变制作索引服务设置(高级)”,按下去,右键弹出的窗口中的那个索引服务->删除,就好了!海腾数据中心服务器论坛 Y \ M z(R1{
O

f ?&f t j9Y&] B `
SystemVolumeInformation\catalog.wci的文件用来存放索引文件,而且在系统空闲时,Windows会自动读硬盘更新索引,安装的文件越多,索引文件会越来越大。
       D Y }&X
删除索引服务:海腾数据、服务器论坛联盟、win服务器、代理服务器,邮件服务器、代码、程序、游戏下载、软件、电脑技术、设计、图片、信息发布 N i$y l z:M }
运行msconfig,然后选择服务选项,找到IndexingService,将前面的小勾去掉,再删掉文件夹即可。
posted @ 2007-04-11 10:36 崛起的程序员 阅读(1429) | 评论 (0)编辑 收藏

Introduction

Changing proxy settings of IE is a frequent requirement of mine. Then I got the idea of writing a tool by myself, at last. I have not found clear instructions on this. Many articles recommend to modify registry directly, but unfortunately their instruction is not enough. Most of them direct me to modify the following values in registry :-

[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings]
"ProxyEnable"=dword:00000001
"ProxyServer"=":"
"ProxyOverride"=""
"DisablePasswordCaching"=dword:00000001

Details

I tested it and find that it does not work at least on my computer.( I access internet by ADSL connection.) So I backed up registry and modified proxy settings via Internet Explorer, finding that [HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings\Connections] is also changed. So I wrote the following code snippet to change proxy settings:

Collapse
				void ShowError(long lerr)
{
    LPVOID lpMsgBuf;
    if (!FormatMessage( 
        FORMAT_MESSAGE_ALLOCATE_BUFFER | 
        FORMAT_MESSAGE_FROM_SYSTEM | 
        FORMAT_MESSAGE_IGNORE_INSERTS,
        NULL,
        lerr,
        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
        (LPTSTR) &lpMsgBuf,
        0,
        NULL ))
    {
        return;
    }
    MessageBox( NULL, (LPCTSTR)lpMsgBuf, "Error", MB_OK | MB_ICONINFORMATION );
    LocalFree( lpMsgBuf );
}
void CieproxyDlg::OnBnClickedOk()
{//set proxy server
    UpdateData();
    GetDlgItemText(IDC_EDIT1,m_sIEProxy);
    HKEY hk;
    LONG lret=RegOpenKeyEx(HKEY_CURRENT_USER,
        "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings",
        NULL,KEY_WRITE|KEY_SET_VALUE,&hk);
    if(lret==ERROR_SUCCESS&&NULL!=hk)
    {
        TCHAR* pbuf=m_sIEProxy.GetBuffer(1);
        lret=RegSetValueEx( hk,"ProxyServer",NULL,REG_SZ,pbuf,m_sIEProxy.GetLength());
        DWORD dwenable=1;
        lret=RegSetValueEx(hk,"ProxyEnable",NULL,REG_DWORD,
           (LPBYTE)&dwenable,sizeof(dwenable));
        RegCloseKey(hk);
    }
    const TCHAR* keyname3=_T(
      "software\\Microsoft\\windows\\currentversion\\Internet Settings\\Connections");
    lret=RegOpenKeyEx(HKEY_CURRENT_USER,keyname3,NULL,
        KEY_READ|KEY_WRITE|KEY_SET_VALUE,&hk);
    if(lret==ERROR_SUCCESS&&NULL!=hk)
    {
        DWORD dwtype;
        char pbuf[256];
        DWORD dwlen=sizeof(pbuf);
        constchar* valname="Connection to adsl3";
        lret=RegQueryValueEx(hk,valname,NULL,&dwtype,pbuf,&dwlen);
        if(lret!=ERROR_SUCCESS)
        {
            ShowError(lret);
        }
        pbuf[8] = 3;//enable proxy
        pbuf[4]=pbuf[4]+1;
        constchar* p=m_sIEProxy.GetBuffer(1);
        memcpy(pbuf+16,p,m_sIEProxy.GetLength());
        char c=0;
        for(int i=m_sIEProxy.GetLength();i<20;i++)
            pbuf[16+i]=c;
        m_sIEProxy.ReleaseBuffer();
        lret=RegSetValueEx(hk,valname,NULL,REG_BINARY,pbuf,dwlen);
        RegCloseKey(hk);
    }
    DWORD dwret;
    SendMessageTimeout(HWND_BROADCAST,WM_SETTINGCHANGE,NULL,NULL,
        SMTO_NORMAL,1000,&dwret);
}

void CieproxyDlg::OnBnClickedDisableProxy()
{
    UpdateData();
    GetDlgItemText(IDC_EDIT1,m_sIEProxy);
    HKEY hk;
    LONG lret=RegOpenKeyEx(HKEY_CURRENT_USER,
        "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings",
        NULL,KEY_WRITE|KEY_SET_VALUE,&hk);
    if(lret==ERROR_SUCCESS&&NULL!=hk)
    {
        DWORD dwenable=0;
        lret=RegSetValueEx(hk,"ProxyEnable",NULL,REG_DWORD,
            (LPBYTE)&dwenable,sizeof(dwenable));
        RegCloseKey(hk);
    }
    const TCHAR* keyname3=_T(
      "software\\Microsoft\\windows\\currentversion\\Internet Settings\\Connections");
    lret=RegOpenKeyEx(HKEY_CURRENT_USER,keyname3,
        NULL,KEY_READ|KEY_WRITE|KEY_SET_VALUE,&hk);
    if(lret==ERROR_SUCCESS&&NULL!=hk)
    {
        DWORD dwtype;
        char pbuf[256];
        DWORD dwlen=sizeof(pbuf);
        constchar* valname="Connection to adsl3";
        lret=RegQueryValueEx(hk,valname,NULL,&dwtype,pbuf,&dwlen);
        if(lret!=ERROR_SUCCESS)
        {
            ShowError(lret);
        }
        pbuf[8] = 1;//enable proxy
        pbuf[4]=pbuf[4]+1;
        lret=RegSetValueEx(hk,valname,NULL,REG_BINARY,pbuf,dwlen);
        RegCloseKey(hk);
    }
    DWORD dwret;
    SendMessageTimeout(HWND_BROADCAST,WM_SETTINGCHANGE,NULL,NULL,SMTO_NORMAL,
        1000,&dwret);
}

Problem with above code is that existing Internet Explorer instances don't know the change of settings. What is more, changing registry directly is not an elegant method. Then the following must be more attractive :

Collapse
BOOL SetConnectionOptions(LPCTSTR conn_name,LPCTSTR proxy_full_addr)
{
    //conn_name: active connection name. //proxy_full_addr : eg "210.78.22.87:8000"
    INTERNET_PER_CONN_OPTION_LIST list;
    BOOL    bReturn;
    DWORD   dwBufSize = sizeof(list);
    // Fill out list struct.
    list.dwSize = sizeof(list);
    // NULL == LAN, otherwise connectoid name.
    list.pszConnection = conn_name;
    // Set three options.
    list.dwOptionCount = 3;
    list.pOptions = new INTERNET_PER_CONN_OPTION[3];
    // Make sure the memory was allocated.if(NULL == list.pOptions)
    {
        // Return FALSE if the memory wasn't allocated.
        OutputDebugString("failed to allocat memory in SetConnectionOptions()");
        return FALSE;
    }
    // Set flags.
    list.pOptions[0].dwOption = INTERNET_PER_CONN_FLAGS;
    list.pOptions[0].Value.dwValue = PROXY_TYPE_DIRECT |
        PROXY_TYPE_PROXY;

    // Set proxy name.
    list.pOptions[1].dwOption = INTERNET_PER_CONN_PROXY_SERVER;
    list.pOptions[1].Value.pszValue = proxy_full_addr;//"http://proxy:80";// Set proxy override.
    list.pOptions[2].dwOption = INTERNET_PER_CONN_PROXY_BYPASS;
    list.pOptions[2].Value.pszValue = "local";

    // Set the options on the connection.
    bReturn = InternetSetOption(NULL,
        INTERNET_OPTION_PER_CONNECTION_OPTION, &list, dwBufSize);

    // Free the allocated memory.delete [] list.pOptions;
    InternetSetOption(NULL, INTERNET_OPTION_SETTINGS_CHANGED, NULL, 0);
    InternetSetOption(NULL, INTERNET_OPTION_REFRESH , NULL, 0);
    return bReturn;
}
BOOL DisableConnectionProxy(LPCTSTR conn_name)
{
    //conn_name: active connection name. 
    INTERNET_PER_CONN_OPTION_LIST list;
    BOOL    bReturn;
    DWORD   dwBufSize = sizeof(list);
    // Fill out list struct.
    list.dwSize = sizeof(list);
    // NULL == LAN, otherwise connectoid name.
    list.pszConnection = conn_name;
    // Set three options.
    list.dwOptionCount = 1;
    list.pOptions = new INTERNET_PER_CONN_OPTION[list.dwOptionCount];
    // Make sure the memory was allocated.if(NULL == list.pOptions)
    {
        // Return FALSE if the memory wasn't allocated.
        OutputDebugString("failed to allocat memory in DisableConnectionProxy()");
        return FALSE;
    }
    // Set flags.
    list.pOptions[0].dwOption = INTERNET_PER_CONN_FLAGS;
    list.pOptions[0].Value.dwValue = PROXY_TYPE_DIRECT  ;
    // Set the options on the connection.
    bReturn = InternetSetOption(NULL,
        INTERNET_OPTION_PER_CONNECTION_OPTION, &list, dwBufSize);
    // Free the allocated memory.delete [] list.pOptions;
    InternetSetOption(NULL, INTERNET_OPTION_SETTINGS_CHANGED, NULL, 0);
    InternetSetOption(NULL, INTERNET_OPTION_REFRESH , NULL, 0);
    return bReturn;
}

The usage is very straightforward:

				//set proxy
				const
				char* connection_name="Connection to adsl3";
    SetConnectionOptions(connection_name,"62.81.236.23:80");
//disable proxy 
    DisableConnectionProxy(connection_name);
    

Existing Internet Explorer instances are notified by INTERNET_OPTION_SETTINGS_CHANGED and INTERNET_OPTION_REFRESH

posted @ 2007-01-25 20:13 崛起的程序员 阅读(883) | 评论 (0)编辑 收藏
Hot Spot JVM5中的GC调优

Written by Halatu Hubisi


引言
有JAVA开发经验的朋友们一定碰到过下面的这种情况,那就是自己所开发的应用运行了一段时间后其性能或者响应速度会有明显的降低.这是由多方面的原因造成的即有程序本身的优化问题,也有运行环境问题.此运行环境即包括硬件环境也包括软件环境.大多数人第一个能想到的解决方法是提升硬件的配置而忽略了程序本身的运行环境JVM也提供了比较多的调优选项.本文将重点描述利用JVM的一些选项对GC进行调优.

约定:
1.读者应具备一定JAVA的知识.

2.本文中的JVM选项均以SUN公司发布的HotSpot JVM 5为准(不过大多数的选项在JVM1.3,JVM1.4中也是可用的).

3.以JAVA_HOME下demo/jfc/SwingSet2/SwingSet2.jar为例进行说明.

4.阅读本文需要一些关于GC的知识,可以到附录A中了解这些知识。

关键字:
JVM(java虚拟机),调优,GC(垃圾回收)

JVM GC调优
为了能够将JVM GC的调优能够使用在具体的实践当中,下面将利用若干个例子来说明GC的调优.
例1:Heap size 设置
JVM堆的设置是指java程序运行过程中JVM可以调配使用的内存空间的设置.JVM在启动的时候会自动设置Heap size的值,其初始空间(即-Xms)是物理内存的1/64,最大空间(-Xmx)是物理内存的1/4。可以利用JVM提供的-Xmn -Xms -Xmx等选项可进行设置。Heap size 的大小是Young Generation 和Tenured Generaion 之和。
当在JAVA_HOME下demo/jfc/SwingSet2/目录下执行下面的命令。
java -jar -Xmn4m -Xms16m -Xmx16m SwingSet2.jar
系统输出为:
Exception in thread "Image Fetcher 0" java.lang.OutOfMemoryError: Java heap space
Exception in thread "Image Fetcher 3" java.lang.OutOfMemoryError: Java heap space
Exception in thread "Image Fetcher 1" java.lang.OutOfMemoryError: Java heap space
Exception in thread "Image Fetcher 2" java.lang.OutOfMemoryError: Java heap space
除了这些异常信息外,还会发现程序的响应速度变慢了。这说明Heap size 设置偏小,GC占用了更多的时间,而应用分配到的执行时间较少。
提示:在JVM中如果98%的时间是用于GC且可用的Heap size 不足2%的时候将抛出此异常信息。
将上面的命令换成以下命令执行则应用能够正常使用,且未抛出任何异常。
java -jar -Xmn4m -Xms16m -Xmx32m SwingSet2.jar
提示:Heap Size 最大不要超过可用物理内存的80%,一般的要将-Xms和-Xmx选项设置为相同,而-Xmn为1/4的-Xmx值。

例2:Young Generation(-Xmn)的设置
在本例中看一下Young Generation的设置不同将有什么现象发生。
假设将Young generation 的大小设置为4M ,即执行java -jar -verbose:gc -Xmn4m -Xms32m -Xmx32m -XX:+PrintGCDetails SwingSet2.jar,屏幕输出如下(节选)
[GC [DefNew: 3968K->64K(4032K), 0.0923407 secs] 3968K->2025K(32704K), 0.0931870 secs]
[GC [DefNew: 4021K->64K(4032K), 0.0356847 secs] 5983K->2347K(32704K), 0.0365441 secs]
[GC [DefNew: 3995K->39K(4032K), 0.0090603 secs] 6279K->2372K(32704K), 0.0093377 secs]
[GC [DefNew: 3992K->23K(4032K), 0.0057540 secs] 6325K->2356K(32704K), 0.0060290 secs]
[GC [DefNew: 3984K->27K(4032K), 0.0013058 secs] 6317K->2360K(32704K), 0.0015888 secs]
[GC [DefNew: 3981K->59K(4032K), 0.0023307 secs] 6315K->2422K(32704K), 0.0026091 secs]
将程序体制并将Young Generation的大小设置为8M,即执行java -jar -verbose:gc -Xmn8m -Xms32m -Xmx32m -XX:+PrintGCDetails SwingSet2.jar,屏幕输出如下(节选)
[GC [DefNew: 7808K->192K(8000K), 0.1016784 secs] 7808K->2357K(32576K), 0.1022834 secs]
[GC [DefNew: 8000K->70K(8000K), 0.0149659 secs] 10165K->2413K(32576K), 0.0152557 secs]
[GC [DefNew: 7853K->59K(8000K), 0.0069122 secs] 10196K->2403K(32576K), 0.0071843 secs]
[GC [DefNew: 7867K->171K(8000K), 0.0075745 secs] 10211K->2681K(32576K), 0.0078376 secs]
[GC [DefNew: 7970K->192K(8000K), 0.0201353 secs] 10480K->2923K(32576K), 0.0206867 secs]
[GC [DefNew: 7979K->30K(8000K), 0.1787079 secs] 10735K->4824K(32576K), 0.1790065 secs]
那么根据GC输出的信息(这里取第一行)做一下Minor收集的比较。可以看出两次的Minor收集分别在Young generation中找回3904K(3968K->64K)和7616K(7808K->192K)而对于整个jvm则找回1943K(3968K->2025)和5451K(7808K->2357K)。第一种情况下Minor收集了大约50%(1943/3904)的对象,而另外的50%的对象则被移到了tenured generation。在第二中情况下Minor收集了大约72%的对象,只有不到30%的对象被移到了Tenured Generation.这个例子说明此应用在的Young generation 设置为4m时显的偏小。
提示:一般的Young Generation的大小是整个Heap size的1/4。Young generation的minor收集率应一般在70%以上。当然在实际的应用中需要根据具体情况进行调整。

例3:Young Generation对应用响应的影响
还是使用-Xmn4m 和-Xmn8m进行比较,先执行下面的命令

java -jar -verbose:gc -Xmn4m -Xms32m -Xmx32m -XX:+PrintGCDetails -XX:+PrintGCApplicationConcurrentTime -XX:+PrintGCApplicationStoppedTime SwingSet2.jar
屏幕输出如下(节选)
Application time: 0.5114944 seconds
[GC [DefNew: 3968K->64K(4032K), 0.0823952 secs] 3968K->2023K(32704K), 0.0827626 secs]
Total time for which application threads were stopped: 0.0839428 seconds
Application time: 0.9871271 seconds
[GC [DefNew: 4020K->64K(4032K), 0.0412448 secs] 5979K->2374K(32704K), 0.0415248 secs]
Total time for which application threads were stopped: 0.0464380 seconds
Young Generation 的Minor收集占用的时间可以计算如下:应用线程被中断的总时常/(应用执行总时?L+应用线程被中断的总时常),那么在本例中垃圾收集占用的时?L约为系统的5%~14%。那么当垃圾收集占用的时间的比例越大的时候,系统的响应将越慢。
提示:对于互联网应用系统的响应稍微慢一些,用户是可以接受的,但是对于GUI类型的应用响应速度慢将会给用户带来非常不好的体验。

例4:如何决定Tenured Generation 的大小
分别以-Xmn8m -Xmx32m和-Xmn8m -Xmx64m进行对比,先执行
java -verbose:gc -Xmn8m -Xmx32m-XX:+PririntGCDetails -XX:+PrintGCTimeStamps java类,命令行将提示(只提取了Major收集)

111.042: [GC 111.042: [DefNew: 8128K->8128K(8128K), 0.0000505 secs]111.042: [Tenured: 18154K->2311K(24576K), 0.1290354 secs] 26282K->2311K(32704K), 0.1293306 secs]
122.463: [GC 122.463: [DefNew: 8128K->8128K(8128K), 0.0000560 secs]122.463: [Tenured: 18630K->2366K(24576K), 0.1322560 secs] 26758K->2366K(32704K), 0.1325284 secs]
133.896: [GC 133.897: [DefNew: 8128K->8128K(8128K), 0.0000443 secs]133.897: [Tenured: 18240K->2573K(24576K), 0.1340199 secs] 26368K->2573K(32704K), 0.1343218 secs]
144.112: [GC 144.112: [DefNew: 8128K->8128K(8128K), 0.0000544 secs]144.112: [Tenured: 16564K->2304K(24576K), 0.1246831 secs] 24692K->2304K(32704K), 0.1249602 secs]
再执行java -verbose:gc -Xmn8m -Xmx64m-XX:+PririntGCDetails -XX:+PrintGCTimeStamps java类,命令行将提示(只提取了Major收集)
90.597: [GC 90.597: [DefNew: 8128K->8128K(8128K), 0.0000542 secs]90.597: [Tenured: 49841K->5141K(57344K), 0.2129882 secs] 57969K->5141K(65472K), 0.2133274 secs]
120.899: [GC 120.899: [DefNew: 8128K->8128K(8128K), 0.0000550 secs]120.899: [Tenured: 50384K->2430K(57344K), 0.2216590 secs] 58512K->2430K(65472K), 0.2219384 secs]
153.968: [GC 153.968: [DefNew: 8128K->8128K(8128K), 0.0000511 secs]153.968: [Tenured: 51164K->2309K(57344K), 0.2193906 secs] 59292K->2309K(65472K), 0.2196372 secs]
可以看出在Heap size 为32m的时候系统等候时间约为0.13秒左右,而设置为64m的时候等候时间则增大到0.22秒左右了。但是在32m的时候系统的Major收集间隔为10秒左右,而Heap size 增加到64m的时候为30秒。那么应用在运行的时候是选择32m还是64m呢?如果应用是web类型(即要求有大的吞吐量)的应用则使用64m(即heapsize大一些)的比较好。对于要求实时响应要求较高的场合(例如GUI型的应用)则使用32m比较好一些。
注意:
1。因为在JVM5运行时已经对Heap-size进行了优化,所以在能确定java应用运行时不会超过默认的Heap size的情况下建议不要对这些值进行修改。
2。Heap size的 -Xms -Xmn 设置不要超出物理内存的大小。否则会提示“Error occurred during initialization of VM Could not reserve enough space for object heap”。

例5:如何缩短minor收集的时间
下面比较一下采用-XX:+UseParNewGC选项和不采用它的时候的minor收集将有什么不同。先执行
java -jar -server -verbose:gc -Xmn8m -Xms32m -Xmx32m SwingSet2.jar
系统将输出如下信息(片段〕
[GC 7807K->2641K(32576K), 0.0676654 secs]
[GC 10436K->3108K(32576K), 0.0245328 secs]
[GC 10913K->3176K(32576K), 0.0072865 secs]
[GC 10905K->4097K(32576K), 0.0223928 secs]
之后再执行 java -jar -server -verbose:gc -XX:+UseParNewGC -Xmn8m -Xms32m -Xmx32m SwingSet2.jar
系统将输出如下信息(片段〕
[ParNew 7808K->2656K(32576K), 0.0447687 secs]
[ParNew 10441K->3143K(32576K), 0.0179422 secs]
[ParNew 10951K->3177K(32576K), 0.0031914 secs]
[ParNew 10985K->3867K(32576K), 0.0154991 secs]
很显然使用了-XX:+UseParNewGC选项的minor收集的时间要比不使用的时候优。

例6:如何缩短major收集的时间
下面比较一下采用-XX:+UseConcMarkSweepGC选项和不采用它的时候的major收集将有什么不同。先执行
java -jar -verbose:gc -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -Xmn64m -Xms256m -Xmx256m SwingSet2.jar
系统将输出如下信息(片段〕
[Full GC 22972K->18690K(262080K), 0.2326676 secs]
[Full GC 18690K->18690K(262080K), 0.1701866 secs
之后再执行 java -jar -verbose:gc -XX:+UseParNewGC -Xmn64m -Xms256m -Xmx256m SwingSet2.jar
系统将输出如下信息(片段〕
[Full GC 56048K->18869K(260224K), 0.3104852 secs]
提示:此选项在Heap Size 比较大而且Major收集时间较长的情况下使用更合适。

例7:关于-server选项 在JVM中将运行中的类认定为server-class的时候使用此选项。SUN 的Hot Spot JVM5 如果判断到系统的配置满足如下条件则自动将运行的类认定为server-class,并且会自动设置jvm的选项(当没有手工设置这选项的时候〕而且HOTSPOT JVM5提供了自动调优的功能,他会根据JVM的运行情况进行调整。如果没有特别的需要是不需要太多的人工干预的。SUN形象的称这个机制为“人体工学”(Ergonomics〕。具体可以参考http://java.sun.com/docs/hotspot/gc5.0/ergo5.html
*.具有2个或更多个物理的处理器
*.具有2G或者更多的物理内存
提示:此选项要放在所有选项的前面。例如:java -server 其他选项 java类

附录A:预备知识
JVM中对象的划分及管理

JVM根据运行于其中的对象的生存时间大致的分为3种。并且将这3种不同的对象分别存放在JVM从系统分配到的不同的内存空间。这种对象存放空间的管理方式叫做Generation管理方式。
1。Young Generation:用于存放“早逝”对象(即瞬时对象)。例如:在创建对象时或者调用方法时使用的临时对象或局部变量。
2。Tenured Generation:用于存放“驻留”对象(即较长时间被引用的对象)。往往体现为一个大型程序中的全局对象或长时间被使用的对象。
3。Perm Generation:用于存放“永久”对象。这些对象管理着运行于JVM中的类和方法。

JVM选项的分类

JVM有这么几种选项供使用.
1.供-X选项使用的项目,又称为非标准选项,不同厂商的此类型选项是有所不同的。例如:IBM的JVM用的一些选项在Sun的JVM中就不一定能生效。这种选项的使用方式如下:
java -Xmn16m -Xms64m -Xmx64m java类名
2.供-XX选项使用的项目,这种类型的选项可能要求有对系统信息访问的权限。所以要慎用。这种选项的使用方式如下:
java -XX:MaxHeapFreeRatio=70 -XX:+PrintGCDetails java类名
3.java选项(即在命令行执行java后提示的选项).
java -server -verbose:gc -d64 java类名

垃圾收集分类

在JVM中有两种垃圾方式,一种叫做Minor(次收集),另一种叫做Major(主收集)。其中Minor在Young Generation的空间被对象全部占用后执行,主要是对Young Generation中的对象进行垃圾收集。而Major是针对于整个Heap size的垃圾收集。其中Minor方式的收集经常发生,并且Minor收集所占用的系统时间小。Major方式的垃圾收集则是一种“昂贵”的垃圾收集方式,因为在Major要对整个Heap size进行垃圾收集,这会使得应用停顿的时间变得较长。

GC信息的格式

[GC [<collector>: <starting occupancy1> -> <ending occupancy1>, <pause time1> secs] <starting occupancy3> -> <ending occupancy3>, <pause time3> secs]
<collector> GC为minor收集过程中使用的垃圾收集器起的内部名称.
<starting occupancy1> young generation 在进行垃圾收集前被对象使用的存储空间.
<ending occupancy1> young generation 在进行垃圾收集后被对象使用的存储空间
<pause time1> minor收集使应用暂停的时间长短(秒)
<starting occupancy3> 整个堆(Heap Size)在进行垃圾收集前被对象使用的存储空间
<ending occupancy3> 整个堆(Heap Size)在进行垃圾收集后被对象使用的存储空间
<pause time3> 整个垃圾收集使应用暂停的时间长短(秒),包括major收集使应用暂停的时间(如果发生了major收集).
GC信息的选项
-XX:+PrintGCDetails 显示GC的详细信息
-XX:+PrintGCApplicationConcurrentTime 打印应用执行的时间
-XX:+PrintGCApplicationStoppedTime 打印应用被暂停的时间
提示:1.":"后的"+"号表示开启此选项,如果是"-"号那么表示关闭此选项。
     2.在不同的选项和不同的收集方式和类型下输出的格式会有所不同。

附录B:HotSpot JVM 选项
请参考JavaTM HotSpot VM Options

附录C:其他资源
http://java.sun.com/docs/hotspot/gc5.0/gc_tuning_5.html
http://java.sun.com/docs/hotspot/gc5.0/ergo5.html

posted @ 2006-11-28 19:23 崛起的程序员 阅读(436) | 评论 (0)编辑 收藏
清晨的时候,
在近春园曲折的小路上走,
看见一个老人坐在湖边悠闲地垂钓
依稀听见湿漉漉的笛声
婉约进树林深处,
老人专注的神情似乎能
漾起水中的波影,
然后目光被长长的眉须剪断,
扑闪在晨雾中捕捉着空气.
这是怎样一种美妙啊!
我在他身边坐下,静静等待
鱼儿的到来.半个小时过去了,
我的心情开始烦躁,
可老人的微笑一如既往.
"你们二十几岁的年轻人啊,
心就像一个玻璃杯,
透明,盛满了阳光."
老人说话跟垂钓一样,安详.
和仙风道骨的老人话别后,
我决定从粉绿的湖边继续往前走,
去探寻校园极致的景色,
享受年轻的心情,
呵呵,像玻璃杯……                                   
posted @ 2006-11-19 19:57 崛起的程序员 阅读(290) | 评论 (0)编辑 收藏
String strs = request.getParameter("yourstrs");
byte b[] = strs.getBytes("ISO-8859-1");
strs = new String(b);








简洁写法:


String convert = new String(request.getParmater("inputname").trim().getBytes("ISO8859_1"), "GBK");
posted @ 2006-11-10 09:53 崛起的程序员 阅读(239) | 评论 (0)编辑 收藏
关于tomcat4.0配置digest认证注意事项:
MemoryRealm作为事例
在server.xml中需要配置 红色字体为注意事项
<Realm className="org.apache.catalina.realm.UserDatabaseRealm"
                 debug="0" resourceName="UserDatabase" digest="MD5"/>

密码转换成密文的加密格式为:
{username}:{realm}:{cleartext-password}.

到bin/目录下找到digest.bat 文件执行如下命令得到密文
digest -a md5 admin:realm:admin

其中admin分别用户和密码,realm为所配置域名
admin:realm:admin:ae7cdd2406201487bcce77064b5fe10c

红色部分为加密后的密码。

完:
作者: Liming

posted @ 2006-11-09 04:30 崛起的程序员 阅读(2005) | 评论 (0)编辑 收藏
这是一篇很有趣的文档,所以摘要一下,其实类似阅读笔记,好像是3/25发布的:
不知怎么翻译Sweet Spots,难道翻译为甜处、甜头、蜜点、蜜穴?

本文基于对以下人的采访(最后两位的看法独到还是自己看吧!):
JSF             Jacob Hookom
RIFE            Geert Bevin
Seam            Gavin King
Spring MVC      Rob Harrop
Spring Web Flow Rob Harrop and Keith Donald
Stripes         Tim Fennell
Struts Action 1 Don Brown
Tapestry        Howard Lewis Ship
Trails          Chris Nelson
WebWork         Patrick Lightbody
Wicket          Eelco Hillenius


JSF(Jacob Hookom)

1、你认为你的framework的"甜点"在哪里?他最适合哪种类型的项目?
当你希望浏览器程序像桌面程序一样工作的时候,你可以遵循标准并获得大量第三方支持。它致力于降低复杂度。它允许你不与view和特定的action、参数传递、状态传递、渲染打交道就可以进行高质量的开发,不管是否使用工具。

2、它不适合于什么样的场景?在这些场景你推荐什么fremework?它是哪个?
它不适合大规模的、只读(其实指读为主)的网站。在这种情况推荐Struts,因为知识库丰富(应该指文档和用户群)。

3、在下面提到的framework中,你试验过他们么?如果试验过,你比较喜欢哪个?你不喜欢哪个?
Seam:
优点:非常简单直接
缺点:对于大项目过于简单;没有模块化开发的好例子
Struts:
优点:巨大的文档和用户群;跟着它没错
缺点:状态/行为的分离过于教条化
WebWork:
优点:比Struts易于使用
缺点:复杂的UI难于维护,UI代码过于复杂(JSF作者对action
Framework都攻击这一点)
Tapestry:
优点:概念新颖;可以应付复杂的UI
缺点:对于一个组件化(JSF主要竞争对手),它依然依附于page/action的概念

4、你的framework的未来会怎样?对于用户开发会有什么方便使用的变化?你会原生支持Ajax么?你们计划支持它了么?
他认为JSF这个标准下这些应该有第三方提供。JSF(2.0)会提供"Partial Faces Request",它是Ajax实现。JSF也会增强annotation组建编程。

5、有对你们的framework的传言需要澄清么?如果有,是哪个?很多JSF书都拿Struts作为对比。他认为这不能体现JSF的特点。他认为Struts和WebWork能做到的JSF也能做到。

6、你对Ruby on Rails的看法如何?
它与WebWork一样好用,它的CoC(Convention over Configration)和脚手架非常好用。他认为CoC可以被应用在任何framework,他认为这是RoR最大的优点。他还认为RoR会走上其它framework的路(复杂性),因为人们需要自己的扩展。

RIFE(Geert Bevin)

1、你认为你的framework的"甜点"在哪里?他最适合哪种类型的项目?
你可以付出10%的工作量,得到其它framework的90%的......,它是一个full-stack framework(如RoR)。它吸收了成熟的分层框架的架构,并将共同的优点汇集在一起。提供了web continuation,POJO驱动的CRUD生成,可扩展的基于组建的架构,无session的状态控制,关注REST作为API,双向无逻辑模版引擎,集成了内容控制框架(CMS?)。每个层次的组建提供了可复用性(AOP,site,sub-site,page,widget,portlet等)。适合于团队快速开发公共Web项目,适合喜欢开发可复用组件的人。

2、它不适合于什么样的场景?在这些场景你推荐什么fremework?它是哪个?
团队中的每个人都有其它framework的知识,难于培训他们。开发状态相关的服务器端Web组件,而不是用RIA或Ajax去实现。第三方支持很重要的情况下(可怜RIFE用户群还不大)。他推荐这种情况下使用JSF。或者在XML为主要发布形式的情况下,推荐Cocoon。

3、在下面提到的framework中,你试验过他们么?如果试验过,你比较喜欢哪个?你不喜欢哪个?
他试验过WebWork,JSF,Wicket。他喜欢WebWork的简单,但是不喜欢它的模版方式(tag的template,应该),它也不提供组件封装。他认为JSF的工具支持非常吸引人。Wicket的纯Java实现很不错,可惜XML配置很不爽。

4、你的framework的未来会怎样?对于用户开发会有什么方便使用的变化?你会原生支持Ajax么?你们计划支持它了么?
关于Ajax,RIFE刚刚集成了DWR,而且选定以后也使用这个。集成Dojo,Scriptaculous,Prototype都很容易集成进来。

5、有对你们的framework的传言需要澄清么?如果有,是哪个?这些错误理念:
  1)、RIFE的XML配置繁琐
  2)、RIFE是continuations server
  3)、RIFE重新造轮子没有提供新鲜东西
  4)、RIFE的模版语法很蹩脚过于简单和业余
  5)、RIFE是基于request的framework
  6)、RIFE的功能太多,学习曲线陡峭

6、你对Ruby on Rails的看法如何?
RoR对Java社区的冲击非常棒,元编成也得到了信任。RoR没什么特殊之处,也没有从Ruby语言获益很多。
我讨厌:它的模版。Partials(RoR中的组件)。URL的分散处理。Active Record提供了从数据库schema而来的DSL,但是却不是从domain model而来。没有l10n和i18n支持。手动状态转换。不能在JVM运行(......)。实际上脚手架生成了实际代码。Ruby缺少工具和IDE。

Seam(Gavin King)

1、你认为你的framework的"甜点"在哪里?他最适合哪种类型的项目?
拥有丰富用户交互体验的应用。方便实现多窗口的操作,回退的支持,单窗口多工作区,无状态浏览。对商务流程(BPM)的集成是独一无二的。Seam方便使用数据驱动的ORM。遵循JSF和EJB3,多任务支持(多窗口/多工作区),BPM的领先解决方案。

2、它不适合于什么样的场景?在这些场景你推荐什么fremework?它是哪个?
不适合只是将数据从数据库显示到网页的应用,这时应该使用PHP或RoR。不适合需要设计特别的HTML组件的情况,此时应该选用Tapestry或Wicket。还在使用JDK1.4的人们。还有那些喜欢Struts的人(嘿嘿,够狠)。

3、在下面提到的framework中,你试验过他们么?如果试验过,你比较喜欢哪个?你不喜欢哪个?
JSF:喜欢他的事件/交互模型。喜欢他的EL和模型绑定。不喜欢那么多XML(为什么没有annotation)。创建自己的controls太难了。
Tapestry:非常好。form验证是它的杀手锏!模版方式很有创意。不过非基于POJO的组件模型则让我对它失去兴趣。
RIFE:这个东西很怪,但是有创业也有趣。我想进一步学习。如果学习先要自费武功:D
Struts:这个东西的模型view绑定太复杂了。东西已经过时了。
WebWork:比Struts好一点,不过也过时了。XWork曾经是个很好的实现,不过现在也过时了。

4、你的framework的未来会怎样?对于用户开发会有什么方便使用的变化?你会原生支持Ajax么?你们计划支持它了么?
Portal支持。远程框架Seam Remoting Framework(Ajax)。模版消息的工具支持。以后还要集成ESB,计划引擎和异步支持。

5、有对你们的framework的传言需要澄清么?如果有,是哪个?
这些都不是真的:JSF不能处理GET requests。JSF post后无法redirect。JSF不能与REST共存。

6、你对Ruby on Rails的看法如何?
它是PHP的很好替代品。如果它有一个正经一点的持久化层它就可以和Java竞争了。

Spring MVC(Rob Harrop)和Spring Web Flow(Rob Harrop and Keith Donald)

1、你认为你的framework的"甜点"在哪里?他最适合哪种类型的项目?
Spring MVC:
稳定可扩展,支持了i18n、文件上传、异常处理,这些稳定的支持给开发者坚实的工作基础。是最佳实践,告诉你怎么做是最好的。与Spring集成,领先的IoC远生支持。支持,Spring社区活跃和庞大。Struts开发者可以平滑过渡。适合多种项目,可选的多种result类型。
Spring Web Flow:内置任务处理引擎,支持线性处理过程中的持续状态。抽象,减少开发的关注点。适合多种项目类型,插件支持Spring MVC、Struts、JSF等。

2、它不适合于什么样的场景?在这些场景你推荐什么fremework?它是哪个?
Spring MVC:不适合需要组件化开发的场景。它是一个request驱动的MVC。那些场景推荐JSF或Tapestry。
Spring Web Flow:处理线性页面流,不适合一般的"自由浏览"。当然Spring Web Flow可以与request驱动或者组件驱动共存。

3、在下面提到的framework中,你试验过他们么?如果试验过,你比较喜欢哪个?你不喜欢哪个?
Spring框架支持Struts和JSF集成。

4、你的framework的未来会怎样?对于用户开发会有什么方便使用的变化?你会原生支持Ajax么?你们计划支持它了么?
Spring MVC:简化JSP标签。更多的MVC配置schema。CoC风格的默认控制器、URL影射、view,学习Rails和Stripes的优点。增强数据绑定和验证(支持范型绑定)。Portlet支持。Spring也要接受Ajax,使用DWR库。
Spring Web Flow:一大堆,关心的可以自己看......

5、有对你们的framework的传言需要澄清么?如果有,是哪个?
Spring MVC难于配置。在Spring 2.0,将会改善,可以使用自己定义的基于schema的配置。

6、你对Ruby on Rails的看法如何?
Spring MVC:RoR非常有趣。不过现在就拿出来用还有点幼稚。这里举了个例子,关于变量的复数形式的处理,RoR会使用这样的CoC风格来处理变量list,而Spring MVC也实验了种种风格,但是受到的结果却很差。人们认为英语的复数很古怪,没有一定的规则,所以会带来混乱,如(person -> people)。所以Spring ...

Stripes(Tim Fennell)

1、你认为你的framework的“甜点”在哪里?他最适合哪种类型的项目?
与Spring MVC、WebWork等相同。它提供高质量action驱动的框架的同时,尽量简化配置,增进开发效率。Stripes适合复杂的数据交互的场合。这种情况下绑定验证的强项就完全体现出来了,能够很好的处理form和map转换等。

2、它不适合于什么样的场景?在这些场景你推荐什么fremework?它是哪个?
所有的action驱动的framework都适合用户在非Ajax驱动的情况下在一个页面进行松关联(loosely
related)和无状态交互的情况。适合每次都刷新的页面。管理多窗口间持续状态的应用会比较麻烦,此时应该选择JSF。不过我认为90%以上的Web程序都是前者,JSF只适合剩下的那9%,AJAX对于管理无状态UI更加适合。客户端不需要AJAX,则可以看看Wicket,它更加简单。

3、在下面提到的framework中,你试验过他们么?如果试验过,你比较喜欢哪个?你不喜欢哪个?
用过Struts、WebWork、Spring MVC。其中Struts做过商业项目,不过这个东西带来的麻烦远比带来的效率提升要多。它认为这些MVC都有三个缺点:暴露了过多的复杂性给可发者。没有提供足够的开发便利性,没有提供足够多的错误和提示信息,也没有date格式化等小的便利(其实有)。稳当太差。

4、你的framework的未来会怎样?对于用户开发会有什么方便使用的变化?你会原生支持Ajax么?你们计划支持它了么?
1.3要加入Inteceptor,实现AOP功能。验证系统要加强。支持Ajax。我还在寻找一个好的Ajax/javascript库。

5、有对你们的framework的传言需要澄清么?如果有,是哪个?
这些观点:1、Stripes使用了annotation代替XML,只是换汤不换药:由于元数据更接近代码,所以修改默认的配置非常方便,不像XML那样复杂,这是实质的变化。2、Annotation意味着你只能有一套配置:我认为90%的action都有自己的一套配置!Stripes会根据继承关系寻找Annotations,子类的annotation会覆盖父类的,因为像validation都是可以继承的,如果特别需要还可以覆盖。这样很合理。在1.3中允许validations基于UI事件进行。它向后兼容,不需要可以不用。

6、你对Ruby on Rails的看法如何?
我认为Java社区有很多可以从RoR学习的地方。Stripes学习了RoR的前端部分,开发者可以减少配置量。但是RoR的RHTML让我想到了以前的JSP中混乱的scriptlet。而后面的ActiveRecord是一个很好的理念,实现的也很好。ActiveRecord比Hibernate等复杂的ORM工具要容易理解,因为这样的特点RoR才引起了这么大的波澜。

Struts Action 1(Don Brown)

1、你认为你的framework的“甜点”在哪里?他最适合哪种类型的项目?
文档和用户基础,书籍和背后的支持。容易雇到人(也容易找工作)。虽然其他项目的理念比这个要先进,但是这些不算什么。实际上,Web层是很容易也很直接的。

2、它不适合于什么样的场景?在这些场景你推荐什么fremework?它是哪个?
如果你需要portlets或者复杂的页面(显示很多东西),那么Struts要么无法工作要么太枯燥。这种情况你需要一个基于组件的framework,如JSF、Tapestry/Wicket。

3、在下面提到的framework中,你试验过他们么?如果试验过,你比较喜欢哪个?你不喜欢哪个?
这些我基本都试验过,他们每个都工作的很不错。

4、你的framework的未来会怎样?对于用户开发会有什么方便使用的变化?你会原生支持Ajax么?你们计划支持它了么?
Struts Action2基于WebWork2,很快会开始。现在已经支持Ajax了,我们在寻找更加容易的开发方式,JSF支持(Struts Shale),continuation支持,还有支持更多的脚本语言(BSF扩展脚本撰写Action)。

5、有对你们的framework的传言需要澄清么?如果有,是哪个?
Struts太过时了,而且也不酷,难于使用。但是你可以自己修改或者扩展它。我认为团队对于你的限制远大于framework对你的限制。

6、你对Ruby on Rails的看法如何?
不需要D&D工具,旨在帮助开发人员提高开发效率的好例子。我们在Action2中将学习它的先进理念。

Tapestry(Howard Lewis Ship)

1、你认为你的framework的“甜点”在哪里?他最适合哪种类型的项目?
我想Tapestry对于中等规模或者大规模的应用会带来很多好处(甚至你可以在单页面的应用程序中获得好处)。这里有允许你创建新的组件的良好工具。Tapestry不关心数据从哪里来,很多“项目类型”都基于切面(aspect)(如CRUD vs. RSS feed vs. etc.)。我认为Tapestry非常容易与IoC集成(HiveMind或与Spring),方便进行测试。

2、它不适合于什么样的场景?在这些场景你推荐什么fremework?它是哪个?
我在其它Java framework中没有找到到强于Tapestry的优点。但是对于RoR,我自己没有使用过使用,很难说RoR中的项目应该是什么样子。我没有仔细对比过RIFE,它看起来受了RoR影响,尤其是类似ActiveRecord的数据访问层。但是如果你的应用需要特定的URL格式,那么在Tapestry中奋战胜算不大。

3、在下面提到的framework中,你试验过他们么?如果试验过,你比较喜欢哪个?你不喜欢哪个?
在这两年来我没怎么尝试过Tapestry以外的东西。我没怎么学习RoR,因为时间太有限了。

4、你的framework的未来会怎样?对于用户开发会有什么方便使用的变化?你会原生支持Ajax么?你们计划支持它了么?
Tapestry 4.0有很好的Ajax支持,通过Tacos库。而Tapestry4.1还要进一步强化这方面的支持。
Tapestry 5.0提供了明显的改进:没有abstract类(Tapestry的怪癖:)。没有强迫的继承关系。对属性进行annotation而不是方法。没有XML,只有模版和annotaions。只能类装载,自动寻找类的变化。最小化API,超越annotaion。面向方面(Aspect-oriented)模块构造,使用mix-ins。

5、有对你们的framework的传言需要澄清么?如果有,是哪个?
Tapestry3.0还不容易测试,4.0改善了一些。Tapestry只是个人秀;实际上我们有很多活跃的贡献者。Tapestry的学习曲线非场陡峭。它只有漂亮的模版实现;实际上Tapestry的特点在于状态管理(允许对象存储状态,而不是多线程的单例来管理requests之间的游离和持久状态)

6、你对Ruby on Rails的看法如何?
很有影响力。但是模版的实现非常丑陋。我听到了很多意见,关于RoR的优缺点。基于我的基本理解,这些观念对Tapestry4产生了影响(它对Tapestry 5影响更深)。
RoR意味着限制了你的选择:如果你选择RoR那么就要尊旬它的实践(CoC..),看起来你的钱会花的恨值。这些类似Microsoft的哲学。而Java更崇尚给你更宽松的选择,不限定你使用的工具,但是暧昧的说这需要你对你的工具理解更深。不仅对Tapestry,还对于JEE、Spring这写entire stack的框架,需要从RoR学习,不仅提供工具,还需要提供整套的解决方案。

Trails(Chris Nelson)

1、你认为你的framework的“甜点”在哪里?他最适合哪种类型的项目?
Trails的应用程序只需要Web界面和持久化的domain model就可以了。Trails给你的domain
model快速的提供一个界面,除了POJO自己不需要附加的代码。Trails允许你修改界面的外观和行为,包括验证、i18n、安全。这些都不需要java代码生成,不喜欢代码生成的人应该感觉很舒适。

2、它不适合于什么样的场景?在这些场景你推荐什么fremework?它是哪个?
Trails讲究够用就好。它允许你快速交付,问问你的客户:“这样够好么?”。这会改变你的工作流程,当然这不是可以覆盖所有需求的解决方案。当UI需求很高,Trails没有优势。我认为Trails适合于混合的应用,对于管理员他们只需要够用就好,那么就可以使用Trails。其它的部分我们可以订制开发,我们在使用Tapestry、Hibernate、Spring来实现这些部分,Trails正是基于它们。对于非交互的应用,Trails也不适合,如报表应用,可以考虑Eclipse BIRT。

3、在下面提到的framework中,你试验过他们么?如果试验过,你比较喜欢哪个?你不喜欢哪个?
我用Struts很多。它曾经是伟大的framework。主要的缺陷是它不能自动帮定数据到domain model。我也研究过JSF,它比Struts强,但是自定义组建非常难。Tapestry非常便于自定义组建,尤其对于建立高阶组件(有其它组件组成的)非常方便,Trails正在使用它。

4、你的framework的未来会怎样?对于用户开发会有什么方便使用的变化?你会原生支持Ajax么?你们计划支持它了么?
对于Trails来说我们站在巨人的肩膀上。Tapestry在ajax功能作了很多努力,所以Trails也不难与其共舞。但是我们需要创建更多的例子来演示这些。我们也致力于让Trails容易介入到已经进行的项目中。以后Trails还要加入基于实例的安全(instance-based security)(目前正在使用基于角色的role-based),还有method invocation。

5、有对你们的framework的传言需要澄清么?如果有,是哪个?
Trails是对RoR的移植。Trails的名字来自Rails。它是基于Rails的理念,但不是对它的移植。

6、你对Ruby on Rails的看法如何?
我认为我们有很多需要从RoR学习的地方,那将帮助我们享受开发Web程序的惬意。
posted @ 2006-08-18 00:02 崛起的程序员 阅读(187) | 评论 (0)编辑 收藏
程序员创业三关


当人们还在浩叹第一次网络泡沫破灭的时候,互联网已经悄悄迎来了它的第二个春天;从某种意义上看,甚至已经进入了夏天——热烈但不乏浮躁、兴奋但失之肤浅。某位投资人声称今年总共有三十亿美金资本进入中国,言下之意,大家都可以甩开膀子大干快上,登陆纳市不好说,搞笔钱进来花差花差多半是没问题的。

另一方面,程序员创业,在中国乃至国外,都不是什么新鲜事儿。我们是那么一群聪明、优秀的家伙,大脑发达,点子就像啤酒的泡沫,扑腾扑腾直往外冒,天生我才,有什么做不到的呢?遥想比尔盖茨当年,西装革履,谈笑间,多少豪杰灰飞烟灭……

于是我看到,无数公司成立了,眼看他雄心勃勃,眼看他一败涂地。成败固然不足以论英雄,然而英雄却不得不面对可能的成败。可惜的是,程序员朋友们在创业的时候,往往没有做好充分准备。据一些资料显示,百分之七十五的新创公司,会在两、三年内倒闭。笔者也曾经见过许多程序员创业失败的个案;成功或不成功,有很多因素制约;对于立志创业的程序员,至少应该突破三关。

第一是模式关。你的创业计划,也许起源于灵机一动。可惜的是,好点子并不能保证你创业成功。我相信多数程序员的点子,尚不至于低级到靠软色情、盗版、恶性SEO等等下作手段去骗取广告费的地步,但怎么从点子变成盈利模式,却是让很多创业者迷惑的事情。在一些业界聚会上,总听到类似“只要有流量,总有办法赚钱”之类的说法,在2000年持同样言论的创业者,多数已经成为失败的先烈,因为他们始终没明白,赚现钱的生意才是好生意。三大门户成功的要点,在于他们想出办法,把流量转化为盈利模式。缺乏有效的模式,流量只是成本。确定有效经营模式、组建有力创业团队,是首要任务。

第二是管理关。从程序员变成管理者,是艰难的过程。你得明白两件事:一、管理和写程序一样,是门科学;二、人和计算机不一样,人有感情、会出错。协调沟通能力,是程序员创业必备的素质。曾经眼见一些项目经理,和手下技术人员通过邮件争辩不休,甚至发展到在Blog上互相嘲讽,这样的管理,可谓彻底失败。另一个极端是,和手下称兄道弟、一团和气,工作被感情所左右,酒肉害了朋友。管理有那么难吗?我看未必。只做对公司有利的事,就是根本原则。在和你的手下打交道时,请三思:我这么做,对公司有好处吗?对事业有好处吗?如果答案是否定的,那你需要另一个解决方案。

第三是坚持关。一位多次创业不成功的朋友告诉我,他总结了一条“三年定律”,即任何事如果不能坚持三年,则一定失败。诚哉斯言!另一位朋友说,中国人相信机会,西方人相信方向和时间,虽有些偏激,却也不乏道理。许多程序员都属于思维活跃、点子特多的一类人,当有新鲜的想法出来时,他们倾向于放弃或冷落手上正在执行的计划。点子复点子,点子何其多,每天新点子,万事成蹉跎。西谚有云,双鸟在林不如一鸟在手;吃到嘴里的鸭子才是好鸭子,湖里那只鸭子看起来比较肥?也许吧,不过,吃了这只鸭子再去涉水抓那只,是不是更有把握呢?

文短意深,未尽之处不及一一道来。奉上忠言数句,与程序员朋友们共勉:你永远不是最聪明的人;手下比你强是好事;创业不怕起步晚,只怕起个不停。
posted @ 2006-08-15 14:49 崛起的程序员 阅读(276) | 评论 (0)编辑 收藏
在前些日子举办的2005年中国国际广播电视信息网络展览会上,瑞福特集团推出了“视讯梦网”的互动视讯运营平台,在网络电视正在火热的时候,“视讯梦网”的出现引起了很多人的关注。
推出“视讯梦网”品牌的互联天下将提供代收费服务,成为连接各SP与用户之间的纽带;并立志成为优秀的客户聚集者,通过统一的服务品牌和平台品牌建立并维持商业价值链上的多种客户关系,集中业务流量,形成庞大的用户规模。从这个商业模式上来看,很明显有模仿移动梦网的意味,从而使得移动梦网的模仿者又多了一个——自从移动梦网为中国移动带来巨大的成功以来,“联通在线”、“互联星空”、“天天在线”等都可以看到它的影子。有趣的是,移动梦网实际上也是模仿日本NTT DoCoMo的i-mode模式,模仿一定能够带来成功吗?

即便是中国成功的企业家在谈到创新和模仿时也有不同的看法,在不久前的一次论坛上,远大空调的张跃和泰康人寿的陈东升对此的观点截然不同,陈东升有一个著名的观点:"创新就是率先模仿"。他两次创业,"模仿"都起了很重要的作用。而张跃对“模仿”却不以为然,远大走的就完全是一条创新的路子。张跃总是时时不忘创新,认为这才是企业的生命力所在。

两个人的观点虽然不同,但他们达到的结果却很相似——他们都成功了。有人把创新分成不同的层次,原始性创新可算是“视讯梦网”的尖端、中间是创意型的技术改造、而处于金字塔底座的是大量的模仿性创新。张跃可能更重视前两个层次的创新,而陈东升更重视低层的创新。事实上模仿性创新可以发挥很重要的作用,日本企业其实就是这方面的典范,而在“学习日本经验”的运动中施乐公司率先实行的标杆管理,里面也有模仿性创新的因素。

所以,单纯地谈模仿是否能成功恐怕并没有多大意义,模仿移动梦网的瑞福特能否成功关键是看模仿中有没有创新,移动梦网的成功也是在于模仿中有创新。陈东升走遍各国探访先进的保险公司,其实是有选择的学习,集众家之长为己所用,也是一种创新。

模仿中最重要的就是不要失去自我,如果只是一味的模仿,没有创新,那最终的结果可能就会像邯郸学步的燕人一样,没学会别人,自己也不会走路了,只有爬着回去了。

Re:企业战略:创新还是模仿?

日本人的创新能力强吗?日本的科技我想在世界上应该有一定地位的.小日本的企业坚持一点:模仿+改良=创新.你有能力创新吗??没有或者不值得的话,那就请模仿吧!等把人家的技术的消化了再去创新!我想管理思想发展到今天我们都提倡学习型组织,迟早要到思考型组织,接下来就是创新型组织.创新是永远的主题,是大创新还是小创新?不同阶段的企业其策略重点也是不一样的,总的来说中国的企业大部分还是应该走模仿的道路,因为制造工厂说白了就是成本打天下!我们慈溪有个非常了不起的企业叫做"卓力"做电器的,大部分是出口生意.他的技术永远不会落后于他人,因为他会把全世界最新的产品买过来模仿.他的核心竞争力就是不断提高的比别人快一步的模仿力,这是一种能力!所以模仿和创新不是矛盾,也许会有一个境界的问题,但是我认为侧重点应该在模仿上,因为我们的发展阶段跟人家不一样.小企业多.连国家都说我们要抓大放小,小的一放,任何技术资源优势都没有,国家又不管,怎么办,唯一的优势就是流动----人才的流动,更重要的是信息的流动!
posted @ 2006-08-07 14:41 崛起的程序员 阅读(279) | 评论 (0)编辑 收藏
     康盛世纪首席执行官戴志康(25岁), PC POP首席执行官李想(25岁),MySee首席执行官邓迪(25岁)、总裁高燃(25岁)、技术主管张鹤翔(24岁),163888翻唱网首席执行官郑立(24岁),MaJoy总裁茅侃侃(23岁),非常在线首席执行官赵宁(23岁),“创智赢家”畅网科技首席技术官陈曦(24岁)……当这样一批二十多岁的精英集中出现在人们的视线中时,不由得让人惊呼,“80后”财富新生代正在崛起。

    似乎是数位少年作家的崭露头角,让人们开始注目“80后”。而当在人们眼中的“80后”还是代表着浮躁和反叛时,这个词却在悄悄地与财富画上连接符号,一批极为年轻的财富新贵的出现似乎是一夜之间,同时颠覆了人们心目中 企业家 的传统印象。
   
   也正由于他们的年纪之轻和拥有的财富之重,这段时间来,他们不断受到媒体和公众的追捧。

    看看上述这些代表人物从事的行业就知道,这批“80后”财富新贵的共同特点是夹了一本叫“互联网”的大课本匆匆上路了。互联网这座虚拟时空里的“大学”,在很多层面上反叛着以一间讲堂、一套书本、一种方言、一个系统为依托的传统 教育

    在李想看来,这正是“80后”的一代人所具有的互联网精神:完全不顾忌那些别人认为是必须去做的传统,破除墨守成规,只做最正确的事。

    和李想说话,你会发现他始终思路清晰、方向明确,回答每个问题不超过3句话,也挑不出一点废话。“我的方向和目标很明确,一开始我就知道我的事业方向就是互联网,然后我会确定每一个阶段的目标,一个一个去实现,所以我不会受到诱惑去烧钱,也不会因为碰到困难就放弃。”

    “像李想、戴志康这批‘80后’创业家的优势就在于他们创新能力很强,敢于尝试,想了就做。不像70年代的人干什么都思前想后,以致错过很多机会。”中华英才网总裁、著名人力资源专家张建国说:“但他们的问题是自我意识太强,而管理企业是要靠组织体系和团队协作的,因此,靠一个好的创意可以成就一个企业,但企业做大以后怎么管理好,这可能是‘80后’企业家应该注意的问题。”

    和张建国基本同龄的戴光对于儿子戴志康也有类似的担心,“你可以凭一项技术创业,但公司做大以后,如何从一个技术天才的角色中脱离出来,完成一个管理者的转型,是一个大问题”。

这些担心已经是李想们正在思考并一直着力解决的问题。

    “2003年时我的性格还是典型的‘80后’,太自我,不太考虑他人的感受。这给了我很多教训,让我慢慢改变,慢慢学会跳出来观察自己,学会了解每一个员工的性格和想法。”李想说,“而且我开始尝试用心跟别人沟通,而不是用脑子。用脑子太累,大家互相猜来猜去,我喜欢直截了当,怎么想的就怎么说。后来我发现其实大部分人都喜欢这种沟通方式,包括那些很有名的CEO们。所以规则不是不可以改写的,关键是你去不去做。”

    这正是“80后”财富新贵的共同特点,他们拥有与年龄不相符的成熟和老练。

    本期,我们走近“80后”财富新贵中的两位:李想和戴志康,也走访了其中一位的父亲,希望能从父辈的教育方式上对这批财富新贵的成功缘由有所挖掘。

    一个没有上过大学,一个做了大学的“半路逃兵”,李想和戴志康都没有受过完整的高等教育,但他们却创造了奇迹。

    这批没有接受正规高等教育却创业成功的年轻企业家的崛起,再次引发对现行高等教育的争议,中国高校究竟该培养什么样人才的问题又一次被提起。

    在关注他们成长的同时,我们也期待他们在今后的路上走得更加稳健和长久。

    见到25岁的PCPOP网首席执行官李想时,他的公司一片忙乱,所有的会议室都被腾出来接待面试者,李想准备继续扩大已有的100多人的团队,而他们2004年还显得空荡的公司变得拥挤不堪。李想说他已经在中关村一个新建的写字楼里租下了比现在大一倍的“新家”,马上就要搬家了。

    作为中国第三大中文 IT 专业网站——PCPOP网的创始人,李想持有公司50%以上的股份,身家在1亿元以上,网站去年的营业额收入近两千万元,利润一千万元,取20倍的市盈率,市场价值两亿元。但李想的野心决不仅限于此,“今年的营业额要达到去年的2.5倍,明年要超过1亿元,然后2008年达到一个上市的标准,这是我们未来几年发展的一个方向。”

    这个野心勃勃的年轻人8年前还是一个上不起网的高中生,当时一小时8元的上网费外加一小时4元的电话费对于一个孩子来说实在昂贵,后来上网费用降到只需一小时1元,他就是那时候开始接触互联网的,“我一碰互联网马上就迷上了,当时很单纯,就是因为可以在网上跟志同道合的人交流、学习知识”。
李想很快就开始做自己的IT资讯网站,网站的访问量很快就达到五六千人。当达到一万人时,就有
广告 商开始找他,要做广告,访问量一千次10元,‘我当时想,闲着也是闲着,就给他挂上了”。

    没有在意的李想两个月后收到了广告商6000元的付款,“我当时也很吃惊,这比我父母一个月加起来挣的还多。”不经意间挖到自己的第一桶金,本来心思就不在读书上的李想终于在高三毕业时作出了一个大胆决定:放弃考大学,自己创业。

    与李想同岁、同样靠互联网起家的康盛世纪科技有限公司CEO戴志康却是个从小和电脑泡到大的人。戴志康出生在大庆一个高级知识分子家庭,父亲戴光是大庆石油学院的博士后。还在上小学的戴志康没事就去鼓捣家里的电脑,从286到586,家里的电脑一次次为他升级,戴志康编程的本事也越来越高。

    2000年,戴志康竟然经过高考前一个月的突击准备考进一所知名大学的 通信 工程专业,这让老师同学大跌眼镜。然而进入大学一年级后,戴志康便很少在学校,而是自己在外创业。“我当时在外面租了个月租300块钱的房子,一天差不多15个小时都泡在电脑前面,闷头开发Discuz!”。

    Discuz!是一套能自动生成社区的软件,能让不懂技术的人也能管理自己设计的网络社区。刚开始研发时,戴志康并没打算以此创业,“我想毕业后找个好工作,所以开始研发Discuz!时只是兴趣,就想证明自己的能力。但在研发过程中,当我产生以此挣钱的念头时,就不再想找工作了。”

    现在,Discuz!已经是社区软件领域的老大,戴志康也开始进行公司的转型,把产品免费供应给客户,转而从为客户提供服务中获取收入。这个仍习惯于吃学校食堂、穿地摊衣服却开着银灰色 宝马 的年轻人,谈起自己公司的发展方向头头是道,老练得让人有些超出想像。

    宽松的家庭教育造就了创业素质

    戴志康的办公室立着一个空空的书架,“我不喜欢看书,我认为书是用来查的,不是用来翻的,我讨厌被动地接收信息,我喜欢从生活中掘取信息”。戴志康的学习与常人理解的不同,他既不靠学校也不靠书本,而是从生活的细节中学习。

    经常和朋友聊天到凌晨的戴志康,从中“偷学”到不少东西。

“另外,我喜欢独立思考。只有独立的人才会坚强。当遇到看似解决不了的困难时,不独立的人马上想到的是寻求帮助。但在一个商业社会里如果没有利益的关联,没有人会帮你,你获得了别人的帮助也就意味着自己商业利益的损失。”戴志康说,“再有,勇气和执著是创业必须的基本素质,而这两点独立的人很容易获得。”

    戴志康把这种独立思考能力的养成归功于家庭教育,“我父母的教育方式比较西化,给我很大的空间。当然,父母同时也要我自己负责任,什么都靠自己,不到万不得已他们不会伸手帮忙。而且我父母都是老师,每天和年轻人接触,心态也比较年轻。”

    戴志康的父亲戴光在向笔者总结他的教育方式时说,对孩子的培养不能限制得太死,要给孩子建议而不是命令,孩子觉得对的要采纳,要让他自己思考,不能给现成的答案,这样孩子才能有自信、有想法,不是一块只会跟着别人的木头。

    “我觉得戴志康之所以能取得一些成就,是他发挥了自己的特长,大学里就有了自己的产品,他的创造能力和创新思维特别强,又有敢想敢干的冒险精神,还有就是这孩子是个踏踏实实干事的人,能容得下事、容得下人。”戴光这样评价自己的儿子。

    无独有偶,李想同样来自一个环境宽松的家庭,他也把自己最重要的创业素质归结为“独立思考和总结能力强”以及不断学习的能力。“我小学时父母给的是命令,初中时给的是建议,高中时是从朋友的角度提出参考,到了高中以后就是信任了。父母给了我很多独立思考的机会,我基本没有受过什么束缚。”李想说。

    财富新贵引发教育新思考

    “因为出了我们这样一批人而在社会上引起什么‘高等教育无用论’,纯属瞎扯。现实是大学里没有目标、随波逐流的人太多了,所以我们这样目标明确并坚持下来的人才显现出来。

    ”没有上过大学的李想说。

    李想坦言,没有上大学的确是自己的一个遗憾,因为人生中缺少了一份体验。“如果你有明确的目标,大学绝对是一个非常好的学习场所。但相对于上学来说,更重要的是一个人要有目标和方向。”

    李想把现在的大学生分为两类:毕业后可以挑单位的和毕业后“海投”简历也找不到工作的,“凡是可以挑单位的学生,绝对是从大一起就有明确的目标并一直为之努力。现在很多大学生或者是迷茫,或者虽有目标,但一遇到困难,就‘喜新厌旧’,常立志而不立长志。”

    上了重点大学却半路“逃跑”的戴志康这样看待自己4年的大学生活:“我考通信专业时本来以为会学到数字通信,接触到一些大型的 交换机 ,结果到大三才学到收音机原理,大四才学了黑白 电视 机原理。大学的课程设置太落后于时代,与用人单位的实际需求太脱节。”

    本身就是大学教授的戴光坦言,现在大学的课程设置的确存在滞后问题。“虽然现在高等教育已进入 大众 化时代,但很多老师和高校管理者的思维还停留在精英教育上。精英教育是细线条的,什么都要讲到,是培养理论家的,而大众教育是粗线条的,应该给学生一定的空间,应该多一些应用性的东西。”

    清华大学科技园副主任、被誉为清华“创业之父”的罗建北认为,像戴志康、李想这样的人,在现有的大学体系中很难培养出来,因为在应试教育模式下,很难把创业所需的一些素质加入到教学中,“创业素质的培养和应试教育就是一对矛盾,因为你要学生多了解社会,从而发现市场的需求和商机,这都需要时间来实践,那考试怎么办?”

posted @ 2006-08-03 15:55 崛起的程序员 阅读(215) | 评论 (0)编辑 收藏
合肥留学生创业园 刘涛  
  易趣网上开店的人不少,而曲剑秋是其中比较特别的一个。小曲的特别之处是他经营自己的易趣网店的独特思路,和他的MBA(工商管理硕士)归国留学生的背景。小曲是英国名校爱丁堡商学院的MBA学生。
  小曲在网上卖的是玩具。他的网上商店名叫“Toys4U”。在易趣网按店铺名:Toys4U开心玩具检索就可以找到小曲的网上商店。打开网店的首页,你可以看到一个红色方块中的“:)”字符号正对你张开着笑脸。这是小曲的商标和网上商店的店标。“All U BUY IS NOT JUST TOYS”(你在这里得到的不仅仅是玩具!)这句意味深长的话向我们表达着这个小小网店的不同寻常的经营理念。
  小曲的小店才开了4个月每个月销售额上万元利润约在4000元左右,算是小有收获。
  抱着几分好奇和惊讶,我辗转联系上了这位放弃了很好的工作机会而选择网上开店创业的MBA归国留学生。电话里的小曲很是坦诚,对我的问题的回答应对之中还是可以感受到一位经过英国名校系统培训过的MBA的敏锐思路。
  小曲在英国呆了3年,其中一年半是在上学,另一年半是在实习。小曲上学的地点在爱丁堡。
  小曲家在大连办着企业,望子成龙的父母铁了心要掏30万元把小曲送到英国读MBA。小曲虽觉得MBA最好是有一定的阅历再读比较好。但还是服从了父母的安排。小曲从小喜欢玩具,一到英国就好比如鱼得水。小曲说在英国二三十岁的人隔一段时间给自己买一个心仪的玩具已成家常便饭,成人玩玩具已是再普通不过的事情。小曲说我不抽烟不喝酒,有点零钱就买玩具。在英国3年,小曲在网上就是eBay(www.ebay.com)和雅虎的玩具拍卖店的常客,对英国的玩具文化也是深有体会。小曲回国时玩具装满了箱,价值有几万元人民币的。小曲多年收藏了从美国、英国以及欧洲其它国家购买来的玩偶精品(从英国运回玩具的运费就高达1000英镑),其中不乏“花木兰”、“狮子王”、“小鸡快跑”和“星战前传”等全套造型玩偶。
  小曲的家境不错加上每到周末有时还有华人家庭请小曲去为孩子教钢琴一小时20英磅小曲小时候学过钢琴到英国后因参加了使馆组织的春节联欢会表演了弹钢琴算是打响了自己的品牌),让自己的个人爱好有了赚钱的机会,同时也让自己有了买玩具的零花钱。
  在结束了MBA的一年半课程后小曲争取到了一个机会,到玩具反斗城(Toys″R″us)做销售助理。玩具反斗城是一个非常有名的大型玩具超市它的分店遍及欧洲、北美乃至亚洲一些国家和地区。小曲实习的这家超市位于伦敦最繁华的牛津街上的Hamleys哈姆雷 。在玩具反斗城小曲对欧美的玩具文化有了更深的理解。小曲心想以后回国就以在中国建这样一个管理有序的大型玩具专营店为事业。
  在英国呆了3年后,小曲决定回国,上海是小曲的首选城市。小曲在上海与人合租了房子。小曲心目中的工作还是玩具行业,但小曲很快发现国内的大多玩具公司都是家族管理和家庭作坊,理念上并不能够彼此认同。后来终于打听到玩具反斗城在广州的公司可能在上海要招一个人,但小曲很快发现对方要的不过是大专毕业生。就算自己愿意从底层做起,恐怕别人会怀疑自己另有企图,而高级的职位人家更倾向于非公开招聘的方式。
  一次偶然的机会,小曲从一本讲述归国MBA的书上知道了易趣网,也知道了易趣网的掌门人BO(邵亦波先生,易趣网CEO)和谭海音小姐的创业故事。同样的归国留学背景让小曲对易趣网有了好感。易趣管理和操作的规范化、国际化,另外低成本的网上操作既是新商品发布的绝佳平台,又是一个最有效的市场信息搜集反馈的工具。小曲心想我为啥不选择创业作为自己的起点呢?MBA最终目标不都是能干出点事儿吗?无非是使创业的过程更加理性化。小曲开始在易趣建立自己的网上商店。一开始就坚信易趣提供的这个平台会被越来越多的人认可。在英国的3年多时间里一直在雅虎和eBay的英国网站上竞拍喜爱的动作玩偶(Action Figures)也是Toys″R″us网站(和亚马逊合并后证明了电子商务一样可以做得很好)的忠实顾客,3年下来竟也积攒了近十大箱子玩具运回国内。 绝大部分玩具都是中国制造的,但因为在国内没有销售而且终端顾客根本无法看到,这更加坚定小曲回国投身玩具销售,带给国人更多更好玩具的信念。就这样,回国没有多久的小曲制定了先在易趣开玩具店铺,通过其间和厂家以及顾客建立的良性纽带,进而巩固网上店铺并适时向外寻求加盟以拓展实体店铺的计划。
  小曲用自己租的住处作为自己网上商店的库房,客厅作为接待网上顾客看样的场所。自己在国外收藏的玩具当然是作为非卖品展示给客户,培养客户对玩具的爱好和对玩具文化的理解。同时也提高自己专业经营者的形象。同时小曲托在外贸工作的同学帮忙落实了国内的生产厂家。
  网店一开张小曲就感受到国内消费者对玩具的渴望。连续4个月每月都赢利4000元左右,月销售额在一万多。
  从香格里拉纪念版红毛熊熊的热销到由正版迪斯尼DISNEY系列玩偶所引起的不俗反响,小曲都是苦心经营,由于现在交易量很大,自己的女朋友也来帮忙,负责成交后网下的联系和交货发货。
  面对如此好的业绩,小曲说,这只是个开始,在以后的日子,仍会秉承一贯诚实经营、价格公道原则,诚心对待每一位新老顾客。还说,随着规模的扩大,买家将直接得到由于相关成本的降低而带来的实惠。
  问及在易趣开店的感受,小曲坦言说:体力和脑力的透支,但是精神上绝对放松,因为在做一件真正喜欢做的事情。赚钱绝不是第一位的(但绝对必要),否则一张英国MBA文凭加上在海外近三年学习工作的积累,也一定让小曲过得很好,但是那不是他所要追求的。他还说,每上传一件新商品,每看到买家收到玩具后满意的回复,打心眼儿里开心!
  小曲说起网上经营心得是:尽量及时回复买家留言和E-mail,没有人喜欢等待;商品选择要有自己的风格,物以稀为贵;买家永远是挑剔的,所以作为卖家的自己要不断改进商品和服务的质量。做玩具这一行,如同做时装店一样靠的是你进货的眼光,要了解你的客户。
  谈到4个月来通过网上商店对中国玩具市场的初步探索,小曲觉得相比之下中国的玩具消费市场还不是很发达,也不成熟。正因为如此才有了自己生存与发展的空间与机会。小曲说,既然我选择了这一行作为我的事业,我就要与市场一起成长。目前小曲的客户大多为收入2000元左右的年轻人。
  我问小曲想没想过将中国的玩具卖到国外去,小曲说不想,至少暂时不想,他更愿意为中国的消费者服务,“他们从我这里得到快乐,与国内的消费者之间我们更能够彼此认同。而如果卖给国外的消费者,他可能因我是个中国人而存有偏见,这是我无法接受的,万一我哪些方面做得不够,他又会说中国人怎样怎样,这也是我不愿看到的。我做这个不纯粹是为钱,如果单纯为钱我就不干这个了。”
  说到开网店的不足之处,小曲说,虽然网上开网店创业门槛低、投资小,但每次上传图片网上打理也怪费心费力的,一忙就精神高度紧张两个多小时。与网下店铺比,脑力的投入大多了。
通过充足的准备和网上的练兵,小曲准备利用自己经营网上商店建立起来的进货渠道,投资10万元在网下开一个玩具专营店。小曲的第一家以顾客为导向的先进管理的网下玩具专营店将在今年夏天于大连繁华地段开张营业。

案例分析


  看完了故事我们再做点儿分析,小曲特别之处在于他是一位MBA,而且是一位留学归来的MBA。但良好教育的最终目标是能干出点事儿,小曲也不例外,对玩具的强烈渴望梦想着拥有属于自己的玩具店,而后来所受的教育使得这种想法更加理性化。创业学也是MBA必修课之一。
  小曲现在初步展现在人们眼前的是一个充满生气、有自己独到经营理念、操作规范的网上店铺,三个月就成为在易趣有很高知名度和信用度的商铺。这是小曲将所学的知识在实践中给以应用的体现。 在同样做到初步开店成功的易趣个人网店店主中,小曲有着更广阔的视野、更好的策划、更详尽的目标、更高的目标。从一开始,小曲就认为易趣的模式必定可行,而且制定了“先在易趣开玩具店铺,通过其间和厂家以及顾客建立的良性纽带,进而巩固网上店铺并适时向外寻求加盟以拓展实体店铺”的计划。千里之行,始于足下。我们相信小曲会走的更远。
另外再来看一下目前小曲提供的一些数据:4个月来小曲共成交的客户有500多人。其中60%的客户会要求上门看货,上门看货后,全对小曲的专业性更加认可,并增大购买量。有本来在网上只不过是定了十几元的玩具,网下来一看定了几百元走。
  因此,我们可以看到即便是网上商店,网络也不是一切。网下的货要经得起推敲,网下看货等环节也要下功夫。网上商店只不过让客户通过网络知道你网下的地址。另外,网上不过是宣传联系客户,网下你也要做专业。开个玩具店也要开出水平来。
  我们再来看看对小曲的客户的一次性购买的情况:一次性购买最多的是1000元。买了500元以上商品的有20%,买了300元以上的有60%。
  因此,我们可以看到对于小曲这种产品单价在几十元上百元上下的玩具,这样的图表数据说明,大多购买者一次会挑好几样,这说明网上有这样的消费人群在你的网店可以提供比网下价格更好,品种更多的产品时,他们是愿意“疯狂”购物的。
  在小曲的500多个客户中有10%的人在四个月内重复购买了三四次。其中有十几个外地个体户上门来批发。批发的金额在几千元,对于批发的客户,小曲加上很少一点利润就出。小曲说这些生意我赚得很少,但我在帮厂家出货,我通过这些生意加强了与厂家的关系。
  因此,可见小曲的经营理念实施得比较到位,4个月内重复购买的客户已达30%。因此如果全年来统计会更高。因此,有没有回头客很重要,网店一定要有特色。另外,批发的客户数达到10%,交易额也不错,但创利在总利润额中所占比例很低,这与小曲的价格策略有关。
  可见,网络可以虚拟,生意还应以诚相待。小生意也要有远大目光,要做别人一辈子的生意,而不是一次两次。

posted @ 2006-07-28 09:29 崛起的程序员 阅读(303) | 评论 (0)编辑 收藏
posted @ 2006-07-27 19:03 崛起的程序员 阅读(239) | 评论 (0)编辑 收藏
诸位,咱当电子工程师也是十余年了,不算有出息,环顾四周,也没有看见几个有出息的!回顾工程师生涯,感慨万千,愿意讲几句掏心窝子的话,也算给咱们师弟师妹们提个醒,希望他们比咱们强!
  
    [1]好好规划自己的路,不要跟着感觉走!根据个人的理想决策安排,绝大部分人并不指望成为什么院士或教授,而是希望活得滋润一些,爽一些。那么,就需要慎重安排自己的轨迹。从哪个行业入手,逐渐对该行业深入了解,不要频繁跳槽,特别是不要为了一点工资而转移阵地,从长远看,这点钱根本不算什么,当你对一个行业有那么几年的体会,以后钱根本不是问题。频繁地动荡不是上策,最后你对哪个行业都没有摸透,永远是新手! 
  
    [2]可以做技术,切不可沉湎于技术。千万不可一门心思钻研技术!给自己很大压力,如果你的心思全部放在这上面,那么注定你将成为孔乙己一类的人物!适可而止为之,因为技术只不过是你今后前途的支柱之一,而且还不是最大的支柱,除非你只愿意到老还是个工程师!      
  
    [3]不要去做技术高手,只去做综合素质高手!在企业里混,我们时常瞧不起某人,说他“什么都不懂,凭啥拿那么多钱,凭啥升官!”这是普遍的典型的工程师的迂腐之言。8051很牛吗?人家能上去必然有他的本事,而且是你没有的本事。你想想,老板搞经营那么多年,难道见识不如你这个新兵?人家或许善于管理,善于领会老板意图,善于部门协调等等。因此务必培养自己多方面的能力,包括管理,亲和力,察言观色能力,攻关能力等,要成为综合素质的高手,则前途无量,否则只能躲在角落看示波器!技术以外的技能才是更重要的本事!!从古到今,美国日本,一律如此!
  
    [4]多交社会三教九流的朋友!不要只和工程师交往,认为有共同语言,其实更重要的是和其他类人物交往,如果你希望有朝一日当老板或高层管理,那么你整日面对的就是这些人。了解他们的经历,思维习惯,爱好,学习他们处理问题的模式,了解社会各个角落的现象和问题,这是以后发展的巨大的本钱,没有这些以后就会笨手笨脚,跌跌撞撞,遇到重重困难,交不少学费,成功的概率大大降低!   
  
    [5]知识涉猎不一定专,但一定要广!多看看其他方面的书,金融,财会,进出口,税务,法律等等,为以后做一些积累,以后的用处会更大!会少交许多学费!!    
  
    [6]抓住时机向技术管理或市场销售方面的转变!要想有前途就不能一直搞开发,适当时候要转变为管理或销售,前途会更大,以前搞技术也没有白搞,以后还用得着。搞管理可以培养自己的领导能力,搞销售可以培养自己的市场概念和思维,同时为自己以后发展积累庞大的人脉!应该说这才是前途的真正支柱!!!  
    [7]逐渐克服自己的心里弱点和性格缺陷!多疑,敏感,天真(贬义,并不可爱),犹豫不决,胆怯,多虑,脸皮太薄,心不够黑,教条式思维。。。这些工程师普遍存在的性格弱点必须改变!很难吗?只在床上想一想当然不可能,去帮朋友守一个月地摊,包准有效果,去实践,而不要只想!不克服这些缺点,一切不可能,甚至连项目经理都当不好--尽管你可能技术不错!       
  
    [8]工作的同时要为以后做准备!建立自己的工作环境!及早为自己配置一个工作环境,装备电脑,示波器(可以买个二手的),仿真器,编程器等,业余可以接点活,一方面接触市场,培养市场感觉,同时也积累资金,更重要的是准备自己的产品,咱搞技术的没有钱,只有技术,技术的代表不是学历和证书,而是产品,拿出象样的产品,就可技术转让或与人合作搞企业!先把东西准备好,等待机会,  否则,有了机会也抓不住!   
      
    [9]要学会善于推销自己!不仅要能干,还要能说,能写,善于利用一切机会推销自己,树立自己的品牌形象,很必要!要创造条件让别人了解自己,不然老板怎么知道你能干?外面的投资人怎么相信你?提早把自己推销出去,机会自然会来找你!搞个个人主页是个好注意!!特别是培养自己在行业的名气,有了名气,高薪机会自不在话下,更重要的是有合作的机会...      
  
    [10]该出手时便出手!永远不可能有100%把握!!!条件差不多就要大胆去干,去闯出自己的事业,不要犹豫,不要彷徨,干了不一定成功,但至少为下一次冲击积累了经验,不干永远没出息,而且要干成必然要经历失败。不经历风雨,怎么见彩虹,没有人能随随便便成功!
posted @ 2006-07-25 10:22 崛起的程序员 阅读(213) | 评论 (1)编辑 收藏
美国东部时间2004年9月29日早上10:58分(北京时间2004年9月29日晚10时58分),中国互联网人才招聘服务网站51job(前程无忧)成功登陆美国纳斯达克,开盘价为每存托股18.98美元,当天收市价为21.15美元,比发行价每股14美元上涨51%。前程无忧此次共发行了604万股美国存托股(ads),共筹得资金8453万美元……作为51job的创始人之一,首席执行长甄荣辉拥有公司30.6%的股份,是公司的第一大股东。”在国庆长假前的9月30日,国内各大媒体、网站纷纷报道了上述消息。

随着前程无忧的成功上市,又一个十亿(人民币)级的富翁走进了人们视线。也许人们津津乐道的是富豪们的身价排名,或是艳羡于他们“一夜暴富”的传奇,但是,在故事中的主人公看来,“事实上,成功一点都不难!最难的是:想成功,但没有计划!如果你有一个5年或者10年的成功目标,而且能够周密地计划,坚定地执行,那么,因为计划,成功率还是很高的。”

如果成功是能够被计划的,那么,出身于香港平民家庭的寒门“虎子”甄荣辉(1962年出生,属虎)依靠清晰的人生定位、严谨的职业发展路径计算、锲而不舍的努力与坚持,一步一步实现人生目标的创富故事将是可以被复制的……懵懂少年初识愁滋味无知贪玩的少年第一次经受了人生磨难,置之死地而后生的遭遇警醒了他内心深处的精英梦;洗澡排队、上厕所排队、做饭排队,香港平民的生存环境给他上了人生第一课:做任何事必须把握好时间与效率,看准了时机一定要毫不迟疑地冲上去。

少年时期的甄荣辉并没有显露出大器将成的先兆,反而以“懒”著称。

1962年甄荣辉出生在香港一个最普通的平民家庭。其父母是从广东“移居”到香港的,他和妈妈以及另外七八家20多口人“蜂居”在一套总面积不到80平米的公寓内,在这种高度拥挤状况下,做饭要排队,洗澡要排队,上厕所也要排队。做任何事必须要把握好时间与效率,这是家庭环境带给甄荣辉的重要一课。

炎热的夏天是最难过的。为了排队洗澡,他一放学就把洗漱用品准备好,然后每隔5分钟去洗澡间探查一次,一俟对方洗完走出房门,他一个箭步马上就冲了进去。生存的艰难,教育了一个十几岁的孩子,一定要抓住机会,看准了时机一定要毫不迟疑地冲上去。就从“抢”洗澡室开始,甄荣辉小小年纪便有了竞争意识。

因为父母都忙于打工挣钱养家,没有人顾及他的功课,于是那个时候的他每天回家把书包一扔就坐在沙发上看电视,然后看到很晚就去睡觉,尽可能地睡,一天睡16个小时。“我不是几天,几个月,而是几年的时间我都在跟自己说,哎呀,你怎么可以这么懒呢?每天到睡觉的时候我也会自责:今天一天又什么活也没干!明天一定不能这样!但是到了明天,依然还是看电视、睡觉,睡觉、看电视……”这样懒的直接后果是,在1979年他中学会考时,全香港30多家预科学校,没有一家愿意要他,因为他的中学实在太烂了。如果不能念预科,不能念大学,对于他这样一个毫无背景的平民家庭的孩子而言,前途是渺茫的。他第一次开始考虑前途问题,告诉自己:再苦再难一定要考上大学。“有一天我在烈日下排了很长很长的队去报名,好不容易挤上去,人家一看我的中学,皱皱眉说不要。拿着报名表出来,后面还有一大群人在排队。在太阳下烤得太久,我都几乎有些中暑了,但我还要打起精神去找下一所学校。我一边打着出租车找学校,一边告诉自己,如果过了这一关,一定要努力读书。”

人是需要一些难关才会成长的。经过这一次的打击,甄荣辉的自我意识开始觉醒,他仿佛变了一个人似的,开始知道发奋努力了。最后,他进入了一所位于偏远而荒凉的山上的预科学校。经过1979年到1981年两年预科的努力,他以优异成绩考入了香港中文大学工程系。
小小工程师胸怀鸿鹄志

香港这个成熟的商业社会教育他,走工程师的路很稳定,但是不会有大的成功,而走商业的路,就像在满布鲨鱼的大海,游得快就会赢,否则会被吃掉。为了获得更大的成功,他进入hp香港公司,成为一名顶级sales。

成长时期的磨难都是锻炼。不管是从小学、中学还是高中,甄荣辉和他的同代人一样,一直处于一种熙熙攘攘的竞争环境中,千军万马要挤一条踏向成功的独木桥。“所以,对于竞争来说,我从小也就习惯了。”

在英国统治下的香港,甄荣辉接受的是英国精英教育的熏陶,一定要成为社会精英人士,爬上去了就是爬上去了。香港这个成熟的商业社会教给他的第一课,是让他对商业的重要性有了认识,他的创业意识亦有所萌芽了。

1984年甄荣辉大学毕业时,大学组织了一次就业辅导,有来自ibm sales的销售总监及香港电讯的总工程师来给学生讲课。那时他想:如果我要成功的话,20年后我会是他们中的哪一位?了解他们的工作及看过当场表现后,甄荣辉直觉上很想做sales的工作。“走工程师的路肯定是很稳定,走商业的路,就好像在满布鲨鱼的大海,游得快就会赢,否则会被吃掉。”自信自己会游得快,向往有更大的成功,甄荣辉选择了挑战度高的商业工作,进入hp的sales & marketing部门,成为一名销售工程师。

hp的工作薪水不错而且稳定。他第一个月工资就是4900港元。甄荣辉似乎天生具有销售才干,三年后,他就成为公司的销售冠军。而到第四年,他每天只需工作不到两个小时,就可以完成业绩。“那个时候是蛮舒服的。因为你有一批大客户在你的手里面,你把他们伺候好了,这个客户其实是很难丢掉的。”那时他每天十点钟出去拜访客户,之后就没事了,但他不敢回家,怕回家老妈操心说,你干嘛这么早回来,是不是给炒鱿鱼了?于是他就去电影院看电影,一个礼拜看两三场电影,看到后来电影都没得看了,就跑到图书馆睡觉。

轻轻松松就能拿到30万(港元)的年薪收入(包括销售提成),而且作为销售状元,在hp的发展前景光明,这样的环境是很多人所羡慕的,但是甄荣辉却开始不满足,觉得挑战不够大。“我分析自己的现状,觉得这么发展下去,只有两个选择。一种选择是改变自己,适应环境。哎呀,你不要要求这么高了。还有一个就是改变环境。其实你会发现mba是一个很好的换环境的踏脚石。你可以在高科技公司里做事,你也可以去做咨询管理顾问,或者是去投资银行,还可以去消费品行业工作……学一个mba可以给你好多路的。”甄荣辉决定放弃hp的工作去读mba。


“小聪明”赢得大机会

mba毕业后的年薪将会在15万美元以上,而且有机会成为企业高级管理人员。他放弃了hp30万港元的年薪和稳定而轻松的工作,将全部的积累用作mba学费。他最终选择去欧洲念书,“因为欧洲学校只需要1年时间,不仅花钱少,而且还能早挣钱。”

1984年加入hp时,月工资是4900港元,当甄荣辉1988年离开hp的时候,他的年薪达到30万港元,他把在hp攒下的积蓄作为念mba的学费。当时他申请的是法国insead商学院。之所以选择这所学校,是因为它学时只有一年,而且学校知名度并不逊于美国院校。“读美国学校mba需要2年时间,而欧洲学校只需要1年时间。因此,去欧洲读书不仅花钱少,而且还能早挣钱。”他是这样计算的。

当他决定离开hp时,他接受了平生第一次专访,正是在那次访问上,他第一次清晰表达了自己的人生愿望。“我记得是一份计算机周刊方面的杂志,他们到惠普来采访销售架构。后来发现我是销售冠军,结果我又去念书,他们就来采访我。他们问我的人生目标,我说我希望毕业20年以后成为一个企业高级管理人员。”那时,他是25岁。

要去法国念书,必须会法语,可是甄荣辉当时没有任何法语基础,他又一次要挑战自己的极限了。他花了三个月来突击强化法语,但是在考试那天,他依然没有太多把握。不过,他发现法语考试主要是面试,由主考老师问几个问题,时间大约为15至20分钟。他担心自己的语言不过关,如果让老师放开问,自己听不懂再答不上来不就麻烦了!他事先准备好20多分钟的讲演内容。当面试老师提出第一个问题后,他就一口气地回答下去,一直回答了20分钟,根本没有给主考老师提问下一个问题的工夫。结果,他就这样通过了入学语言考试。

勤奋成就百万年薪经理人

“我要先在国外工作一段时间,看看国外公司是如何运作的。而有国外工作的经历,即使以后回香港也能对我的简历更有帮助。”在四个不同的工作意向中,他最后选择进入贝恩国际策略顾问公司英国办事处。

mba毕业以后,甄荣辉面临着几种选择:一是回香港工作,二是留在国外工作,或者加入高科技企业,或者进入咨询管理公司。四个方向的工作他都有选择的机会,“我决定要先在国外工作一段时间,因为刚出来一年就回香港,没有机会看看国外是怎么运作的,对我的简历可能也不是很有帮助。而选择做咨询,是因为它比较新鲜,可以接触不同的事情,见识面广。”最后,他选择了贝恩国际策略顾问公司(bain & company),先在其英国办事处工作。

尽管选择进入贝恩公司,对他是反复权衡之后的理性选择,他很喜欢这份工作,但贝恩却给了他一个下马威。上班三天之后有一个项目汇报会,他参加了这个两小时的会议,却发现有70%的内容都听不懂。连会议都听不懂,还怎么开展工作?他给远在香港的妈妈打电话说可能很快要回香港了。在这次会议上的受“辱”经历给他以巨大的打击,他明白自己还得要拼命努力,就像当初考大学,当初学习法语一样,爱拼才能赢。

经过半年的磨合,他发现和其他英国同事相比,语言是自己的短处,而分析推理能力是自己的长处。于是,甄荣辉把工作重点放到了项目调查方面,收集了大量数据,进行调查分析,并从中找出许多从前别人没有看到的东西。最初,他的工作是咨询顾问,当他把事先经过大量调查分析后的资料提供给项目经理时,项目经理似乎惊呆了,因为很少有一个咨询顾问工作像他那样深入。慢慢地,所有贝恩英国公司的经理们都点名要求甄荣辉加入他们的队伍。正是由于这样苦干加巧干,当该年贝恩英国要裁员三分之一时,他一个华人却被保留下来。

在加入贝恩两年多后,甄荣辉顺利地从咨询顾问升到经理。1991年他被派驻香港建立办事处,业务发展迅速。很快,在他一手策划下,贝恩又在北京开设了办事处,他出任贝恩中国总裁。1994年,32岁的甄在加入贝恩4年半后,成为贝恩公司历史上最年轻的副总裁以及最年轻的合伙人之一。这在“不up(提升)就out(离职)”、聪明人成堆的咨询公司实属难得。



“亿万富翁梦”的诱惑

做一个百万年薪的职业经理人,“薪水很高,职务也很稳定”,但是永远不会成为有影响力的企业家。“中国未来20年高速发展的经济环境将造就一批百亿级的富豪”,这一诱惑使得他不辞辛苦,屡次创业。

“作咨询顾问,每天接触到不同的客户,为不同的案子服务。今天你可能是被客户用直升机直接接到他们公司总部的楼顶上,你感受了大公司的豪华气派;明天你没准又要坐长途汽车在农村奔波,与泥土牛粪为伴。二者的巨大差异,让你深深感受到这个世界好像不公平。钱好像很重要,但是有些东西还不只是金钱带来的差异。然后你就会想,人生到底追求什么呢?”在成为年薪百万的财务自由人后,甄荣辉不再是那个为抢厕所而煞费苦心的少年小伙,不再是因为有钱能多吃一碗饭而高兴的大学生,不再是那个第一次拥有自己爱车而在雨中飙车的浪漫青年,他开始思考“人活着为什么”等哲学层面的问题,能够做一些更有社会影响力的事情,成为他的追求目标。

在甄荣辉的记忆中,1995年的一段经历对他触动很大:“那时我正负责百威啤酒的项目,贝恩总部也过来了一个高级合伙人专门负责这个项目。我们陪着百威啤酒董事长august busch在中国各地考察,贝恩的高级合伙人从来没来过中国,我全程陪同。有一天晚上,我们和老外在一起喝酒聊天,他们说在中国未来发展的二十年里面一定会出现十几位十亿美元家产的富翁。听到这句话,我心中咯噔一下,因为我以前没想过这个问题,但仔细一想觉得很有道理。香港在60年代到80年代的高速发展中,产生了十多个十亿美元的大富翁,大陆未来20年的高速发展难道不能产生新的富翁吗?你既然相信了在中国未来?0年会有几十个富豪出现,那你再想一想,自己还有机会排上吗?”

在大陆经济快速发展的大潮中,香港人甄荣辉做起了“亿万富翁梦”。对他而言,“这个出发点不是钱的问题,而是一种成就感。钱不一定就代表成就,但是在某种程度上还是反映了事业的成功,或者在市场上的影响力。”

天上不会掉下馅饼,更不会掉下财富。要实现“亿万富翁”的理想,坐在办公室等待,或者安于做一个朝九晚五的打工族肯定是不可能的,必须要投资,要创立自己的企业。去管理顾问公司的人一般做了两三年就都想出来自己做事,甄荣辉最初其实也是有过创业的想法与尝试。早在1991年,他就投资做了一种用声音传递邮件的系统,后来他还投资做过磁性材料等等,两次创业均以失败告终,但也使他学到了不少东西,“创业需要很大的精力,你必须全职去做;同时,团队也很重要。”

遭受过两次创业失败的打击,如果不敢再尝试,就此放弃,也就没有今天的前程无忧以及今天的甄荣辉了。从失败中总结出了一些经验与教训,1998年甄荣辉又开始尝试新的投资项目——人力资源服务。

互联网创造了新机会

互联网经济的兴起,给甄荣辉带来新的机会,风险投资成了最热的话题。甄荣辉想借此良机把网站作大,决定引入风险投资。他为前程无忧网设计了一个美好的前程:引入投资、上市、做成国际品牌。

1998年甄荣辉和他的创业伙伴成立了一家人力资源服务公司。

之所以选择这个领域,与他的一段经历分不开。1994年,当时任贝恩公司中国区总裁的甄荣辉需要招募新人,他先在一份英文媒体上刊登了招聘信息,但效果很差。后来,经北京同事指点,他选择了北京人爱看的一份当地媒体,结果反馈很好。但甄荣辉自己却感到当时报纸的印刷质量太差。当时香港的《南华早报》每周有多达200多页的招聘专版,人力资源市场十分活跃。但是,比香港人口还多的北京却没有这样一份专业的招聘纸媒体。他隐约找到了市场的需求空白。

到了1998年,大陆的人才交流市场日趋活跃,无论是用人单位还是求职者个人,他们迫切需要一个更专业的、定位于白领青年的招聘渠道。市场已经成熟!甄荣辉经人介绍,和《中国贸易报》合作,首先在北京推出了《中国贸易报.前程招聘专版》。北京《前程招聘专版》的推出,获得了很大成功,受到了企业以及求职者的普遍欢迎。受到北京市场的启发与鼓舞,甄荣辉和他的创业团队,开始在全国复制北京模式。五年多,在全国19个城市与当地媒体合作,推出了针对当地市场的《前程招聘专版》。

1999年,互联网经济正在全球兴起,网络给甄荣辉带来了新的机遇。

1999年1月,甄荣辉先在上海推出了career-post.com网站,当然内容只能算是《前程招聘专版》的电子版,是一些企业招聘信息的集纳。1999年底,互联网经济开始膨胀,风险投资成了最热的话题。甄荣辉想借此良机把网站作大,决定引入风险投资。他为自己设计了一个美好的梦想:引入投资、上市、做成国际品牌。网站也因此易名为无忧工作网(51job.com)。无忧工作网的赢利模式十分符合中国国情,也受到国外风险投资者的青睐,很快,在2000年2月,一笔金额为1400万美元的投资进入了甄荣辉的创业公司。

2000年以前,甄荣辉在前程无忧的角色还只是一个“天使投资人”,不参与具体的经营管理。等到2000年1400万美元的风险投资进入后,公司发展需要他全力以赴地投入,这时,他再次面临着人生的选择:是继续做一个百万美金年薪的打工皇帝,还是放弃眼前的舒适去做一个前途未卜的小公司的ceo,领取6万美元的年薪?此时,甄荣辉已经37岁,在贝恩干了11年,如果继续待下去,“薪水很高,职务也很稳定”,但“那时就有些怕,觉得可能再干20年还是这样”。同时,互联网的起飞让他看到挑战背后的巨大机会:“在互联网业,即使你去年做得成功,过了一个年头必须重新洗牌。这种充满刺激的感觉很过瘾。可以赢得很大,也可以输得很大,完全看自己的机遇与功力。”

2000年4月,甄荣辉经过慎重考虑,决定离开贝恩,出任前程无忧ceo。

做中国人的ge公司

也许你看不清路,但你能看得见那里有一座山,那就是你的目标。我一直相信人才服务这块业务有前景,我相信我们有一天是能做到10亿美元的;我希望有一天,前程能像ge公司那样成为行业典范,影响更多的中国企业乃至跨国企业。

甄荣辉认为他的成功“一半是运气,一半是努力”。一直有好运气的甄这次也不例外。

2000年2月,前程无忧的1400万美元风险投资到位,而到了2000年4月,网络经济的泡沫开始破灭,很多创业网站不能再在投资市场上拿到钱了。而有了这笔投资,前程无忧却获得一个空间去慢慢成长。“有了这几年的时间给我们成长,我们可以把我们的规模做大,把我们的管理做好,把我们的市场地位巩固。”中国的人才市场正处在发育阶段,机会无限,前程无忧得以随着中国人才市场的成熟而成长,在甄荣辉看来,“这是非常幸运、非常快意的事”。

前程无忧的发展,其实并非一帆风顺,也有过十分艰难的时候。2000年、2001年网络泡沫破灭,全球经济放缓,9.11事件后众多跨国企业招聘计划冻结,2003年又遇到sars事件,形势似乎从来不是一片光明。在最艰难的时候,甄荣辉有没有过后悔,有没有想过放弃?

“我们知道人才服务这一块肯定是值得做的,即使最早在北京的东花市小学起步的时候我们也看得见。香港《南华早报》的招聘周刊有200多页,我们的《前程招聘专版》到现在还没有发展到200多页。所以,我知道成功的机会肯定是有的,而且这个机会只有在中国才能找到。日本的人才网站每年几十个亿美元的营业收入,我相信我们有一天是能做十亿美元的。但是你说是哪一天呢,我也说不出来。你说到底有多长时间呢,你到底要做多少东西才能得到呢,这个可能是摸着石头过河。但是信心我是一直有的。”甄荣辉从来没有怀疑过自己的选择。

据新浪财经报告显示:从1999年到2002年的三年间,前程无忧营业收入就增长了25倍。到2002年,整个财年度实现盈利,销售收入约2000万美元,2003年销售收入为3544万美元,增长77%。2004年前三季度销售收入为4386万美元,较去年同期增长80%。“我们不断加快速度开设办事处,现在已在全国20个城市开设有分公司或办事处;我们又不断开发新产品,为客户提供招聘猎头、培训测评和人事外包等十多项专业的人力资源服务……我们的产品线很长,服务很深入,和客户的联系紧密。这就是我们的竞争优势。”

四年前甄荣辉放弃贝恩的百万年薪而出任前程无忧6万年薪的ceo时,他的计划是将51job运作上市,但这只是一个开始,他心中还有一个更宏伟的梦想——要做一间中国人的ge公司。在甄荣辉理想中,“当企业成为一个行业或企业群里的典范,它的影响力可以超过它规模的数倍甚至数十倍。譬如ge公司,它的影响力是全球的,经营ge不再是经营一个企业那么简单,它在经营企业人的思想,它在与世人分享领先的管理经验。现在,前程无忧还很小,但我希望有一天,前程能像ge公司那样成为行业典范,影响更多的中国企业乃至跨国企业。”

这不是一个5年10年的工程,20年够不够呢?“在我退休之前,我希望能够实现这个愿望。”甄荣辉又开始了一个新的人生计划!
posted @ 2006-07-25 10:22 崛起的程序员 阅读(381) | 评论 (0)编辑 收藏

对synchronized(this)的一些理解
 
一、当两个并发线程访问同一个对象object中的这个synchronized(this)同步代码块时,一个时间内只能有一个线程得到执行。另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块。

 

二、然而,当一个线程访问object的一个synchronized(this)同步代码块时,另一个线程仍然可以访问该object中的非synchronized(this)同步代码块。

 

三、尤其关键的是,当一个线程访问object的一个synchronized(this)同步代码块时,其他线程对object中所有其它synchronized(this)同步代码块的访问将被阻塞。

 

四、第三个例子同样适用其它同步代码块。也就是说,当一个线程访问object的一个synchronized(this)同步代码块时,它就获得了这个object的对象锁。结果,其它线程对该object对象所有同步代码部分的访问都被暂时阻塞。

 

五、以上规则对其它对象锁同样适用.

 

举例说明:

 

一、当两个并发线程访问同一个对象object中的这个synchronized(this)同步代码块时,一个时间内只能有一个线程得到执行。另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块。

 

package ths;

public class Thread1 implements Runnable {
public void run() {
synchronized(this) {
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName() + " synchronized loop " + i);
}
}
}
public static void main(String[] args) {
Thread1 t1 = new Thread1();
Thread ta = new Thread(t1, "A");
Thread tb = new Thread(t1, "B");
ta.start();
tb.start();
}
}

 

结果:

 

A synchronized loop 0
A synchronized loop 1
A synchronized loop 2
A synchronized loop 3
A synchronized loop 4
B synchronized loop 0
B synchronized loop 1
B synchronized loop 2
B synchronized loop 3
B synchronized loop 4

 

二、然而,当一个线程访问object的一个synchronized(this)同步代码块时,另一个线程仍然可以访问该object中的非synchronized(this)同步代码块。

 

package ths;

public class Thread2 {
public void m4t1() {
synchronized(this) {
int i = 5;
while( i-- > 0) {
System.out.println(Thread.currentThread().getName() + " : " + i);
try {
Thread.sleep(500);
} catch (InterruptedException ie) {
}
}
}
}
public void m4t2() {
int i = 5;
while( i-- > 0) {
System.out.println(Thread.currentThread().getName() + " : " + i);
try {
Thread.sleep(500);
} catch (InterruptedException ie) {
}
}
}
public static void main(String[] args) {
final Thread2 myt2 = new Thread2();
Thread t1 = new Thread(
new Runnable() {
public void run() {
myt2.m4t1();
}
}, "t1"
);
Thread t2 = new Thread(
new Runnable() {
public void run() {
myt2.m4t2();
}
}, "t2"
);
t1.start();
t2.start();
}
}

 

结果:

 

t1 : 4
t2 : 4
t1 : 3
t2 : 3
t1 : 2
t2 : 2
t1 : 1
t2 : 1
t1 : 0
t2 : 0

 

三、尤其关键的是,当一个线程访问object的一个synchronized(this)同步代码块时,其他线程对object中所有其它synchronized(this)同步代码块的访问将被阻塞。

 

//修改Thread2.m4t2()方法:

public void m4t2() {
synchronized(this) {
int i = 5;
while( i-- > 0) {
System.out.println(Thread.currentThread().getName() + " : " + i);
try {
Thread.sleep(500);
} catch (InterruptedException ie) {
}
}
}

}

 

结果:

 

t1 : 4
t1 : 3
t1 : 2
t1 : 1
t1 : 0
t2 : 4
t2 : 3
t2 : 2
t2 : 1
t2 : 0

 

四、第三个例子同样适用其它同步代码块。也就是说,当一个线程访问object的一个synchronized(this)同步代码块时,它就获得了这个object的对象锁。结果,其它线程对该object对象所有同步代码部分的访问都被暂时阻塞。

 

//修改Thread2.m4t2()方法如下:

public synchronized void m4t2() {
int i = 5;
while( i-- > 0) {
System.out.println(Thread.currentThread().getName() + " : " + i);
try {
Thread.sleep(500);
} catch (InterruptedException ie) {
}
}
}

 

结果:

 

t1 : 4
t1 : 3
t1 : 2
t1 : 1
t1 : 0
t2 : 4
t2 : 3
t2 : 2
t2 : 1
t2 : 0

 

五、以上规则对其它对象锁同样适用:

 

package ths;

public class Thread3 {
class Inner {
private void m4t1() {
int i = 5;
while(i-- > 0) {
System.out.println(Thread.currentThread().getName() + " : Inner.m4t1()=" + i);
try {
Thread.sleep(500);
} catch(InterruptedException ie) {
}
}
}
private void m4t2() {
int i = 5;
while(i-- > 0) {
System.out.println(Thread.currentThread().getName() + " : Inner.m4t2()=" + i);
try {
Thread.sleep(500);
} catch(InterruptedException ie) {
}
}
}
}
private void m4t1(Inner inner) {
synchronized(inner) { //使用对象锁
inner.m4t1();
}
}
private void m4t2(Inner inner) {
inner.m4t2();
}
public static void main(String[] args) {
final Thread3 myt3 = new Thread3();
final Inner inner = myt3.new Inner();
Thread t1 = new Thread(
new Runnable() {
public void run() {
myt3.m4t1(inner);
}
}, "t1"
);
Thread t2 = new Thread(
new Runnable() {
public void run() {
myt3.m4t2(inner);
}
}, "t2"
);
t1.start();
t2.start();
}
}

 

结果:

尽管线程t1获得了对Inner的对象锁,但由于线程t2访问的是同一个Inner中的非同步部分。所以两个线程互不干扰。

 

t1 : Inner.m4t1()=4
t2 : Inner.m4t2()=4
t1 : Inner.m4t1()=3
t2 : Inner.m4t2()=3
t1 : Inner.m4t1()=2
t2 : Inner.m4t2()=2
t1 : Inner.m4t1()=1
t2 : Inner.m4t2()=1
t1 : Inner.m4t1()=0
t2 : Inner.m4t2()=0

 

现在在Inner.m4t2()前面加上synchronized:

 

private synchronized void m4t2() {
int i = 5;
while(i-- > 0) {
System.out.println(Thread.currentThread().getName() + " : Inner.m4t2()=" + i);
try {
Thread.sleep(500);
} catch(InterruptedException ie) {
}
}
}

 

结果:

尽管线程t1与t2访问了同一个Inner对象中两个毫不相关的部分,但因为t1先获得了对Inner的对象锁,所以t2对Inner.m4t2()的访问也被阻塞,因为m4t2()是Inner中的一个同步方法。

 

t1 : Inner.m4t1()=4
t1 : Inner.m4t1()=3
t1 : Inner.m4t1()=2
t1 : Inner.m4t1()=1
t1 : Inner.m4t1()=0
t2 : Inner.m4t2()=4
t2 : Inner.m4t2()=3
t2 : Inner.m4t2()=2
t2 : Inner.m4t2()=1
t2 : Inner.m4t2()=0

posted @ 2006-07-19 10:55 崛起的程序员 阅读(304) | 评论 (0)编辑 收藏

Configuration cfg = new Configuration().configure("/hibernate.cfg.xml");

  for (Iterator iter = cfg.getTableMappings(); iter.hasNext();) {
   Table table = (Table) iter.next();
   for (Iterator iterator = table.getColumnIterator(); iterator.hasNext();) {

    Column column = (Column) iterator.next();
    System.out.println(column.getName());
   }

  }

posted @ 2006-07-17 11:39 崛起的程序员 阅读(432) | 评论 (0)编辑 收藏
     摘要: Spring Aop Step-By-Step 学习笔记(上)  www.uusam.com   最近由于工作需要,要求掌握关于 Spring 方面的东西。所以花了两个星期的时间来学习 Spring 的基本知识,主要包括 Ioc ...  阅读全文
posted @ 2006-07-05 17:26 崛起的程序员 阅读(349) | 评论 (0)编辑 收藏
MRX3F-47B9T-2487J-KWKMF-RPWBY(VOL 中国工商银行版)
QC986-27D34-6M3TY-JJXP9-TBGMD
DG8FV-B9TKY-FRT9J-6CRCC-XPQ4G(VOL 上海政府专用)
使用XP修改器修改成为以上任意一个序列号。修改完成后到如下地址验证是否通过,优先选择中国工商银行版本,有的xp使用上海政府专用的序列号不行。
http://www.microsoft.com/genuine/downloads/WhyValidate.aspx?displaylang=zh-cn


验证结束!

感谢您验证 Microsoft Windows 软件。


感谢您使用 Windows 正版增值计划 计划。现在您可以访问正版 Windows 用户资源。


验证成功后,可以下载更新安装Media Player 11 和 IE7。
posted @ 2006-07-05 15:31 崛起的程序员 阅读(2974) | 评论 (1)编辑 收藏
Sun公司一名员工自己创作的歌,关于Java EE 5,很有意思的一首歌,程序员业余生活也可以这么丰富!

地址:http://tap.javalobby.org/javaee5.mp3

歌词:
Ladies and gentlemen, this is Java EE 5!

One, two, three, four, five
There's a technology I use day and night
For my application with a web frontend
They told me to use .Net
But I really don´t wanna

So many bugs I fixed last week.
My code is neat and talk is a cheap
I like Glassfish, JSF, persistence API
And as I continue you know they´re gettin´ sweeter

So what can I do I really beg you my Lord
To me codin' it´s just like a sport
All the bad code from the past, let me dump it
Please set in the trumpet

A little bit of injection in my life
A little bit of persistence by my side
A little bit of NetBeans is all I need
A little bit of EJB's what I see
A little bit of standards in the sun
A little bit of XML all night long
A little bit web services here I am
A little bit of code makes me real man

This is Java EE 5!

Jump up and down and move your code around
Shake your head to the sound bury bad code under ground
Move one step left and one step right
One to the front and one to the side
Refactor it once and refactor it twice
If it looks like this you're doin´ it right

A little bit of injection in my life
A little bit of persistence by my side
A little bit of NetBeans is all I need
A little bit of EJB's is what I see
A little bit of standards in the sun
A little bit of XML all night long
A little bit web services here I am
A little bit of code makes me real man

This is Java EE 5!

本文来源:http://www.blogjava.net/Andyluo/archive/2006/06/30/javasong.html

posted @ 2006-07-04 08:47 崛起的程序员 阅读(330) | 评论 (0)编辑 收藏

 

1.下载http://www.eu.apache.org/dist/jakarta/tomcat-5/
这里注意,在jakarta-tomcat-5.0.28.exe以前是有默认的admin模块,在jakarta-tomcat-5.5.9.exe则没有安装默认的admin模块,这时http://127.0.0.1:8080/admin打开时则会出现
Tomcat's administration web application is no longer installed by default. Download and install the "admin" package to use it.
因此我们现在需要下载"admin"package 包
把jakarta-tomcat-5.5.x.zip  与   jakarta-tomcat-5.5.x-compat.zip  与  jakarta-tomcat-5.5.x-admin.zip
三个文件解压在同一个目录中
(如果使用jdk1.4,才需要compat.zip用jdk1.5就可以免了这个。)

2.修改jakarta-tomcat-5.5.x\conf\tomcat-users.xml.
添加管理员账号lizongbo,密码为lizongbopass.
新xml如下:
<?xml version='1.0' encoding='utf-8'?>
<tomcat-users>
  <role rolename="tomcat"/>
  <role rolename="role1"/>
  <role rolename="manager"/>
  <role rolename="admin"/>
  <user username="tomcat" password="tomcat" roles="tomcat"/>
  <user username="role1" password="tomcat" roles="role1"/>
  <user username="both" password="tomcat" roles="tomcat,role1"/>
  <user username="lizongbo" password="lizongbopass" roles="admin,manager"/>
</tomcat-users>


有时在%CATALINA_HOME%\server\webapps\admin\WEB-INF\web.xml里面也要做些修改


<!-- Security is active on entire directory -->
  <security-constraint>
    <display-name>Tomcat Server Configuration Security Constraint</display-name>
    <web-resource-collection>
      <web-resource-name>Protected Area</web-resource-name>
      <!-- Define the context-relative URL(s) to be protected -->
      <url-pattern>*.jsp</url-pattern>
      <url-pattern>*.do</url-pattern>
      <url-pattern>*.html</url-pattern>
    </web-resource-collection>
    <auth-constraint>
      <!-- Anyone with one of the listed roles may access this area -->
      <role-name>admin</role-name>
    </auth-constraint>
  </security-constraint>

  <!-- Login configuration uses form-based authentication -->
  <login-config>
    <auth-method>FORM</auth-method>
    <realm-name>Tomcat Server Configuration Form-Based Authentication Area</realm-name>
    <form-login-config>
      <form-login-page>/login.jsp</form-login-page>
      <form-error-page>/error.jsp</form-error-page>
    </form-login-config>
  </login-config>

  <!-- Security roles referenced by this web application -->
  <security-role>
    <description>
      The role that is required to log in to the Administration Application
    </description>
    <role-name>admin</role-name>
  </security-role>
无论是 Authetication ( 身份验证  还是 Authorization ( 权限管控  都只有设置相关的 admin ROLE, 当你想要新增或修改相关的 AA, 就必须修改这一个文件, 来符合你的环境.
3.修改jakarta-tomcat-5.5.x\conf\server.xml来解决编码问题。
(给Connector 添加URIEncoding参数,参考http://blog.csdn.net/darkxie/archive/2004/10/25/TOMCATAPP.aspx)
(可以设置成GB18030)
    <Connector port="8080"
               maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
               enableLookups="false" redirectPort="8443" acceptCount="200"
               connectionTimeout="20000" disableUploadTimeout="true" URIEncoding="GBK"
               compression="on" compressionMinSize="2048"
      noCompressionUserAgents="gozilla, traviata"
      compressableMimeType="text/html,text/xml"/>
 
    <Connector port="8009"
               enableLookups="false" redirectPort="8443" protocol="AJP/1.3" URIEncoding="GBK"/>
 

4.启用支持gzip压缩.
(http://www.linuxaid.com.cn/forum/showdoc.jsp?l=1&i=81169)
添加下列属性
 compression="on"
      compressionMinSize="2048"
      noCompressionUserAgents="gozilla, traviata"
      compressableMimeType="text/html,text/xml"
 
5.设置虚拟主机。
在jakarta-tomcat-5.5.x\下建立文件夹vhost\www.mydomain.com。
然后修改jakarta-tomcat-5.5.x\conf\server.xml
 
<Engine defaultHost="localhost" name="Catalina">
      <Host appBase="vhost/www.mydomain.com" name="http://www.mydomain.com/">
      </Host>
      <Host appBase="webapps" name="localhost">
      </Host>
      <Realm className="org.apache.catalina.realm.UserDatabaseRealm"/>
    </Engine>
 
6.添加数据库驱动,更新mail.jar和actiovation.jar
复制mysql-connector-java-3.0.16-ga-bin.jar,pg74.215.jdbc3.jar到 jakarta-tomcat-5.5.x\common\lib\
还有javamail 1.3.2的mail.jar,jaf-1_0_2的 activation.jar
msSQl 2000 JDBC sp3,msbase.jar,msutil,jar,mssqlserver.jar
 
 
7.配置SSL
参考 http://jakarta.apache.org/tomcat/tomcat-5.5-doc/ssl-howto.html
D:\j2sdk1.4.2_06\bin>%JAVA_HOME%\bin\keytool -genkey -alias tomcat -keyalg RSA
输入keystore密码:  lizongbossl
您的名字与姓氏是什么?
  [tomcat5.5.x]:  tomcat5.5.x
您的组织单位名称是什么?
  [jakarta]:  jakarta
您的组织名称是什么?
  [apache]:  apache
您所在的城市或区域名称是什么?
  [hzcity]:  hzcity
您所在的州或省份名称是什么?
  [gdp]:  gdp
该单位的两字母国家代码是什么
  [CN]:  CN
CN=tomcat5.5.x, OU=jakarta, O=apache, L=hzcity, ST=gdp, C=CN 正确吗?
  [否]:  y
 
输入<tomcat>的主密码
        (如果和 keystore 密码相同,按回车):

(必须密码一致,因此直接回车)
然后再把userhome(例如:C:\Documents and Settings\lizongbo\)下的.keystore复制到
tomcat的conf\目录下。
 (例如:D:\jakarta-tomcat-5.5.x\conf\.keystore
配置jakarta-tomcat-5.5.x\conf\server.xml
加上
    <Connector port="8443"
               maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
               enableLookups="false" disableUploadTimeout="true"
               acceptCount="100" scheme="https" secure="true"
               clientAuth="false" sslProtocol="TLS"
           keystoreFile="conf/.keystore"
           keystorePass="lizongbossl"> <!--与先前设置的密码一致-->
    </Connector>
8.禁止文件目录列表,
修改jakarta-tomcat-5.5.x\conf\web.xml,把listing设置为false
 
    <servlet>
        <servlet-name>default</servlet-name>
        <servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
        <init-param>
            <param-name>debug</param-name>
            <param-value>0</param-value>
        </init-param>
        <init-param>
            <param-name>listings</param-name>
            <param-value>true</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
 
 9.指定了自己的javaEncoding
(参考 http://gceclub.sun.com.cn/staticcontent/html/sunone/app7/app7-dg-webapp/ch6/ch6-4.html 

    <servlet>
        <servlet-name>jsp</servlet-name>
        <servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>
        <init-param>
            <param-name>fork</param-name>
            <param-value>false</param-value>
        </init-param>
                <init-param>
            <param-name>javaEncoding</param-name>
            <param-value>GB18030</param-value>
        </init-param>
        <init-param>
            <param-name>xpoweredBy</param-name>
            <param-value>true</param-value>
        </init-param>
        <load-on-startup>3</load-on-startup>
    </servlet>
 10.添加rar,iso等的mime-type映射
避免在浏览器里直接打开。
<mime-mapping>
<extension>mht</extension>
<mime-type>text/x-mht</mime-type>
</mime-mapping>
<mime-mapping>
        <extension>rar</extension>
        <mime-type>application/octet-stream</mime-type>
    </mime-mapping>
    <mime-mapping>
        <extension>iso</extension>
        <mime-type>application/octet-stream</mime-type>
    </mime-mapping>
    <mime-mapping>
        <extension>ape</extension>
        <mime-type>application/octet-stream</mime-type>
    </mime-mapping>
    <mime-mapping>
        <extension>rmvb</extension>
        <mime-type>application/octet-stream</mime-type>
    </mime-mapping>
    <mime-mapping>
        <extension>ico</extension>
        <mime-type>image/x-icon</mime-type>
    </mime-mapping>
10.1对html静态页面设置编码
<!--  修改下面两行以支持静态超文本的自动编码
  -->
 <mime-mapping>
  <extension>htm</extension>
  <mime-type>text/html;charset=gb2312</mime-type>
  </mime-mapping>
 <mime-mapping>
  <extension>html</extension>
  <mime-type>text/html;charset=gb2312</mime-type>
  </mime-mapping>
  </web-app>
 
11.添加welcome-file-list,并调整顺序。
 <welcome-file-list>   
        <welcome-file>index.jsp</welcome-file>
        <welcome-file>index.html</welcome-file>
        <welcome-file>index.htm</welcome-file>
        <welcome-file>default.html</welcome-file>
        <welcome-file>default.htm</welcome-file>
        <welcome-file>default.jsp</welcome-file>
    </welcome-file-list>

posted @ 2006-06-20 19:50 崛起的程序员 阅读(311) | 评论 (0)编辑 收藏
--h
--help
打印常用启动参数的描述。
--cp:p additional_classpath 将指定的类路径附加到 IDE 的类路径之前。
--cp:a additional_classpath 将指定的类路径附加到 IDE 的类路径之后。
--fontsize size 设置字体大小,在 IDE 用户界面中用磅表示。如果未使用此选项,则字体大小为 11 磅。
--jdkhome jdk_home_dir 注意:测试 IDE 时是采用所支持的 Java 2 SDK 版本进行的,并且该版本与 IDE 捆绑在一起;因此,在大多数情况下,不需要使用此开关。 对于所有支持的平台(除 Mac OS 之外),缺省 JDK 就是与本产品捆绑在一起的 JDK,它位于 <安装目录>/java 中。对于 Mac OS,缺省 JDK 为计算机上安装的最新 JDK。

请使用指定的 Java 2 SDK 版本而不要使用缺省的 SDK。在 Microsoft Windows 系统中,缺省情况下,加载器会在注册表中查找并使用最新的可用 SDK。

请在升级 IDE 使用的 SDK 之前,备份用户目录。如果以后需要恢复到先前的 JDK,可以切换到已备份的用户目录,从而确保不丢失任何设置。

要切换 IDE 的用户目录,请使用 -userdir 开关。

--Jjvm_option 将指定的标志直接传递给 JVM。
--locale language[:country[:variant]]

使用指定的语言环境。支持的语言包括:
英语 (en)、西班牙语 (es)、韩语 (ko)、日语 (ja)、法语 (fr) 以及简体中文 (zh_CN)。
例如,在 <系统驱动器>:\Program Files\Sun\Creator2\bin 目录下,键入:
creator.exe --locale es

--userdir userdir 显式指定用户目录,该目录是存储用户设置的位置。
如果在 UNIX 系统中未使用此选项,则缺省情况下存储位置为$HOME/.Creator/2_1

在 Microsoft Windows 系统中,缺省位置是您第一次启动 IDE 时指定的位置。在大多数情况下,该位置为<系统驱动器>:\Documents and Settings\<用户名>\.Creator\2_1

您可以在“关于”对话框中确定当前的用户目录。选择“帮助”>“关于”,然后选择“详细信息”标签。此标签列出了用户目录位置以及其他产品详细信息。
posted @ 2006-06-09 16:27 崛起的程序员 阅读(152) | 评论 (0)编辑 收藏

1.在JSP文件中加上:

<%@ page contentType="text/html; charset=utf-8" %>

<html:html lang="true"></html:html>

2.使用以下形式输出字符:

<bean:message bundle="index" key="Anonymous"/>

3.建立类似以下形式的文件(放在classses目录下):

application_en_US.properties

application_zh_TW.properties

application_zh_CN.properties

其中可能用到这样的命令:

native2ascii application_cn.properties application_zh_CN.properties

posted @ 2006-06-07 14:44 崛起的程序员 阅读(245) | 评论 (0)编辑 收藏

以下所说的struts-config.xml和ApplicationResources.properties等文件名是缺省时使用的,如果你使用了多模块,或指定了不同的资源文件名称,这些名字要做相应的修改。

1、“No bean found under attribute key XXX”
在struts-config.xml里定义了一个ActionForm,但type属性指定的类不存在,type属性的值应该是Form类的全名。或者是,在Action的定义中,name或attribute属性指定的ActionForm不存在。


2、“Cannot find bean XXX in any scope”
在Action里一般会request.setAttribute()一些对象,然后在转向的jsp文件里(用tag或request.getAttribute()方法)得到这些对象并显示出来。这个异常是说jsp要得到一个对象,但前面的Action里并没有将对象设置到request(也可以是session、servletContext)里。
可能是名字错了,请检查jsp里的tag的一般是name属性,或getAttribute()方法的参数值;或者是Action逻辑有问题没有执行setAttribute()方法就先转向了。
还有另外一个可能,纯粹是jsp文件的问题,例如<logic:iterate>会指定一个id值,然后在循环里<bean:write>使用这个值作为name的值,如果这两个值不同,也会出现此异常。(都是一个道理,request里没有对应的对象。)


3、“Missing message for key "XXX"”
缺少所需的资源,检查ApplicationResources.properties文件里是否有jsp文件里需要的资源,例如:


<bean:message key="msg.name.prompt"/>

这行代码会找msg.name.prompt资源,如果AppliationResources.properties里没有这个资源就会出现本异常。在使用多模块时,要注意在模块的struts-config-xxx.xml里指定要使用的资源文件名称,否则当然什么资源也找不到,这也是一个很容易犯的错误。

4、“No getter method for property XXX of bean teacher”
这条异常信息说得很明白,jsp里要取一个bean的属性出来,但这个bean并没有这个属性。你应该检查jsp中某个标签的property属性的值。例如下面代码中的cade应该改为code才对:

<bean:write name="teacher" property="cade" filter="true"/>


5、“Cannot find ActionMappings or ActionFormBeans collection”
待解决。

6、“Cannot retrieve mapping for action XXX”
在.jsp的<form>标签里指定action='/XXX',但这个Action并未在struts-config.xml里设置过。

7、HTTP Status 404 - /xxx/xxx.jsp
Forward的path属性指向的jsp页面不存在,请检查路径和模块,对于同一模块中的Action转向,path中不应包含模块名;模块间转向,记住使用contextRelative="true"。

8、没有任何异常信息,显示空白页面
可能是Action里使用的forward与struts-config.xml里定义的forward名称不匹配。


9、“The element type "XXX" must be terminated by the matching end-tag "XXX".”
这个是struts-config.xml文件的格式错误,仔细检查它是否是良构的xml文件,关于xml文件的格式这里就不赘述了。

10、“Servlet.init() for servlet action threw exception”
一般出现这种异常在后面会显示一个关于ActionServlet的异常堆栈信息,其中指出了异常具体出现在代码的哪一行。我曾经遇到的一次提示如下:

java.lang.NullPointerException
    at org.apache.struts.action.ActionServlet.parseModuleConfigFile(ActionServlet.java:1003)
    at org.apache.struts.action.ActionServlet.initModuleConfig(ActionServlet.java:955)


为解决问题,先下载struts的源码包,然后在ActionServlet.java的第1003行插入断点,并对各变量进行监视。很丢人,我竟然把struts-config.xml文件弄丢了,因此出现了上面的异常,应该是和CVS同步时不小心删除的。

11、“Resources not defined for Validator”
这个是利用Validator插件做验证时可能出现的异常,这时你要检查validation.xml文件,看里面使用的资源是否确实有定义,form的名称是否正确,等等。

posted @ 2006-06-07 14:43 崛起的程序员 阅读(245) | 评论 (0)编辑 收藏
这只小猫玩了它差不多也有一年多了,还没仔细瞅瞅长个什么样。当它耍性子的时候,常常弄的我手足无措,因为不懂它说出的一大堆乱七八糟的洋话。为了能让它说start就start,说down就down,下面要开始一段我训兽师的经历 ^_^。

宠物简介
Jakarta Tomcat服务器是一种Servlet/JSP容器,经历了3.x到4.0.x到4.1.x的变迁,现在最新的版本为5.0.x,支持Servlet2.4和JSP2.0规范,从apache网站上下载Tomcat 5,在环境变量中配置一下JAVA_HOME,小猫就能生灵活现的跑起来了。若小猫启动失败,DOS窗口会自动关闭,若运行catalina run命令DOS窗口是不会自动关闭的。

tomcat中有三个放置java库的地方,分别是/server/lib、/shared/lib和/common/lib。
区别:/server/lib - 其中的jar文件只能被tomcat服务器访问。
/shared/lib - 其中的jar文件可以被所有的Web应用访问,但不能被tomcat服务器访问到。
/common/lib - Web服务和tomcat服务器都可以访问的到。

server.xml文件解析 - 文件位置是<%CATALINA_HOME%>/conf/server.xml

配置虚拟主机
Host元素代表虚拟主机,在同一个Engine元素下可以配置多个虚拟主机。打开server.xml文件可以发现Engine元素下已经有一个名为localhost的Host元素了,可以在它后面加入下列代码:

< Host  name ="www.myname.com"  debug ="0"  appBase ="c:\myname"  unpackWar ="true"  autoDeploy ="true" >
    < alias > www.myname1.com </ alias >
    < alias > www.myname2.com </ alias >
    < Context  pathh ="/helloapp"  docBase ="helloapp"  debug ="0"  reloadable ="true" />
</ Host >  

Session的使用
Session是一种用来跟踪用户状态的机制,那它是怎么实现的呢?Servlet容器通过在客户端浏览器中保存一个Session ID来跟踪Session,调用session.getID()可以看到你的Session ID是多少。如果客户端支持Cookie,就把Session ID作为Cookie保持在浏览器中,现在绝大多数浏览器都会把Cookie功能打开,但如果用户禁止了Cookie呢?Java Servlet API中提出了另外一种机制,Servlet容器可以重写客户requst的URL,把Session ID添加到URL信息中,HttpServletResponse接口提供了这样的方法:public String encodeURL(String url)-先判断如果没有启用Session,例如jsp中<%@ page session="false"%>或执行了session.invalideate(),那么直接返回url,在判断客户端师父支持Cookie,如果不支持,就在url中加入Session ID的信息,然后返回修改后的url。

Session的管理
当一个sesson开始时,Servlet容器会创建一个HttpSession对象,在某些情况下把这些Httpsession对象从内存中转移到文件系统中或数据库中,需要访问的时候在把它们载入到内存中来。这样做的好处有两点:节约了内存的消耗,当web服务器产生故障时,还可以从文件系统或数据库中恢复Session的数据。
对于Session的管理,小猫提供了两个实现类:org.apache.catalina.session.StandardManager和org.apache.catalina.session.PersistentManager。
StandardManager -是默认的方法,当Tomcat服务器重启或重载的时候,会把Session对象保存到
<%CATALINA_HOME%>/work/Catalina/honstname/applicatonname/SESSIONS.ser(默认值)文件中,每个对象对应一个文件,以Session ID为文件名,例如:

< Context  path ="/helloapp"  docBase ="helloapp"  debug ="0"  reloadable ="true" >
    < Manager  className ="org.apache.catalina.session.StandardManager"  debug ="0"  
      maxActiveSessions="-1" checkInterval="60"
 / >
</ Context >

参数说明:checkInterval-检查session是否过期的时间间隔,以秒为单位,缺省值是60秒;
maxActiveSessions-可处于活动状态的session数。

PersistentManager -提供了更加灵活的管理方式,具有容错能力,可以及时把Session备份到Session Store中,可以控制内存中Session的数量。
小猫还提供了实现持久化Session Store的接口,org.apache.catalina.Store,目前提供了两个具体实现类:org.apache.catalina.FileStore和org.apache.catalina.JDBCStore。
server.xml中的配置File Store -

< Context  path ="/helloapp"  docBase ="helloapp"  debug ="0"  reloadable ="true" >
    < Manager  className ="org.apache.catalina.session.PersistentManager"  debug ="0"  saveOnRestart ="true"  
          maxActiveSessions
="-1"  minIdleSwap ="-1"  maxIdleSwap ="-1"  maxIdleBackup ="-1"   >
    < Store  className ="org.apache.catalina.session.FileStore"  directory ="mydir" />
    </ Manager >
</ Context >

参数说明:saveOnRestart-服务器关闭时,是否将所有的session保存到文件中;
maxActiveSessions-可处于活动状态的session数;
minIdleSwap/maxIdleSwap-session处于不活动状态最短/长时间(s),sesson对象转移到File Store中;
maxIdleBackup-超过这一时间,将session备份。(-1表示没有限制)

JDBCStore配置的区别:

< Store  calssName ="org.apache.catalina.JDBCStore"  driverName ="com.mysql.jdbc.Driver"  
    connectionURL
="jdbc:mysql://localhost/tomsessionDB?user=root&password="  
    sessionTable
="tomcat_session"  sessionIdCol ="session_id"  sessionDataCol ="session_data"  
    sessionValidCol
="session_valid"  sessionMaxInactiveCol ="max_inactive"  
    sessionLastAccessedCol
="last_access"  sessionAppCol ="app_name"  checkInterval ="60"  debug ="99"   />

Session失效时间的设定
在web.xml文件中,位于<servlet-mapping>和<welcome-file-list>元素之间加入如下代码,单位为分钟:

< session-config >    
    < session-timeout > 60 </ session-timeout >
</ session-config >

Tomcat的admin平台和manager平台
这是Tomcat中自带的两个Web应用,位于<%CATALINA_HOME%>/server/webapps/admin(manager),访问地址是http://localhsot:8080/admin(manager)。要访问这两个Web应用,需要在
<%CATALINA_HOME%>/conf/tomcat-users.xml中添加如下内容:
<user username="admin" password="1234" role="admin"/>           //对应admin Web应用
<user username="manager" password="1234" role="manager"/>   //对应manager Web应用

admin平台把所有可配置的信息分为三类:Tomcat Server、Resources、User Definition。
Tomcat Server-相当于server.xml中的<Server>元素及其子元素,<Service>、<Host>、<Context>、<Resources>、<Date Source>。
Resources-相当于server.xml中的<GlobalNamingResources>,共有四种资源:Date Source(JNDI数据源)、Mail Sessioin(JNDI Mail Session资源)、Environment Entry(环境变量)、User Database(安全域中的用户数据库)。
User Definition-与tomcat-users.xml相对应。

manager平台-列出来所有Web应用和状态,并提供了Start、Stop、Reload、 Undeploy命令,还可以发布
<%CATALINA_HOME%>/webapps目录下的Web应用或系统文件任意位置的WAR文件。

posted @ 2006-06-07 14:41 崛起的程序员 阅读(241) | 评论 (0)编辑 收藏
解决思路:
配置web工程web.xml加上
  <mime-mapping>
    <extension>doc</extension>
    <mime-type>application/msword</mime-type>
  </mime-mapping>
  <mime-mapping>
    <extension>xls</extension>
    <mime-type>application/vnd.ms-excel</mime-type>
  </mime-mapping>
修改后非常注意的要清空缓存这样才会弹出保存还是打开的窗口否则打开还是乱码.
posted @ 2006-06-02 12:32 崛起的程序员 阅读(1080) | 评论 (0)编辑 收藏
在weblogic下面增加虚拟目录
修改weblogic.xml
<?xml version="1.0" encoding="UTF-8"?>
<weblogic-web-app xmlns="
http://www.bea.com/ns/weblogic/80 " xmlns:xsi=" http://www.w3.org/2001/XMLSchema-instance " xsi:schemaLocation=" http://www.bea.com/ns/weblogic/80 http://www.bea.com/ns/weblogic/80/weblogic-web-app.xsd http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd ">
  <context-root>webdoc</context-root>
  <virtual-directory-mapping>
 <local-path>c:/word/doc</local-path>
 <url-pattern>/*</url-pattern>
  </virtual-directory-mapping>
</weblogic-web-app>

posted @ 2006-06-01 15:49 崛起的程序员 阅读(2495) | 评论 (3)编辑 收藏

                                      

使用Spring来创建一个简单的工作流引擎                     

spring是支持控制反转编程机制的一个相对新的框架。本文把spring作为简单工作流引擎,将它用在了更加通用的地方。在对工作流简单介绍之后,将要介绍在基本工作流场景中基于Spring的工作流API的使用。

  许多J2EE应用程序要求在一个和主机分离的上下文中执行处理过程。在许多情况下,这些后台的进程执行多个任务,一些任务依赖于以前任务的状态。由于这些处理任务之间存在相互依赖的关系,使用一套基于过程的方法调用常常不能满足要求。开发人员能够利用Spring来容易地将后台进程分离成活动的集合。Spring容器连接这些活动,并将它们组织成简单的工作流。

  在本文中,简单工作流被定义成不需要用户干预,以一定顺序执行的任意活动的集合。然而,我们并不建议将这种方式代替存在的工作流框架。在一些场景中,需要更多的用户交互,例如基于用户输入而进行的转向,连接或传输,这时,比较好的方法是配用一个单独的开源或者商业的工作流引擎。一个开源项目已经成功地将更复杂的工作流设计集成到spring中。

  如果你手上的工作流任务是简单的,那么,与功能完备的独立工作流框架相比,简单工作流的策略就会变得有意义,特别地,如果已经使用了spring,这种快速实现可以保证时间不会变得更加漫长。此外,考虑到spring轻量级的控制反转容器的特点,spring在资源负载上减少了资源负载。

  这篇文章简短地从编程主题的角度介绍工作流。通过使用工作流的概念,spring被用来作为驱动工作流引擎的框架。然后,讨论了生产部署选项。现在,让我们从工作流的设计模式和相关背景信息来介绍简单工作流的思想吧。

  简单工作流

  工作流模型是一个早在70年代就有人开始研究的主题,许多开发者都试图创建工作流模型规范。W.H.M. van der Aalst等人写了《工作流模型》白皮书(2003年7月),它成功地提炼出一组设计模式,这些设计模式准确地将大多数通用的工作流场景建模。当中,最普通的工作流模式是顺序模式 (Sequence pattern)。顺序工作流模式满足了简单工作流的设计原则,并且由一组顺序执行的活动组成。

  UML(统一建模语言)活动图通常被用来作为一个机制对工作流建模。图1显示了一个基本的使用标准UML活动图对顺序工作流过程的建模过程。

图 1顺序工作流模式

  顺序工作流是一个在J2EE中流行的标准工作流模式。J2EE应用程序在后台线程中,通常需要一些顺序发生的事件或者异步事件。图2中的活动图描述了一个简单的工作流,用来通知感兴趣的旅行者,他们感兴趣的目的地的机票价格已经下降的事件。

图 2.机票价格下降的简单工作流

- 作者: macrochen 2005年12月11日, 星期日 22:28

图1中的航线工作流负责创建和发送动态的email通知。过程中的每一步表示了一个活动(activity)。在工作流处于活动之前,一些额外事件必须发生。在这个例子中,事件是飞行路线费率的减少。

  让我们来简要的看一下航线工作流的业务逻辑。如果第一个活动找不到对费率减少通知感兴趣的用户,那么整个工作流就被取消。如果发现了感兴趣的用户,那么接下来的活动继续执行。随后,一个XSL(扩展样式表)转换生成消息内容,之后,记录审计信息 (audit information)。最后,工作流试图通过SMTP服务器发送这个消息。如果这个任务没有错误地完成,便在日志中记录成功的信息,进程结束。但是,如果在和SMTP服务器通讯时发生了错误,一个特别的错误处理例程将要管理这些错误。错误处理代码将会试着去重新发送消息。

  考虑这个航线的例子,一个明显的问题是:你怎么样有效地将顺序处理过程分解为单独的活动?这个问题被spring巧妙的处理了。下面,让我们快速地讨论spring的反转控制框架。

  控制反转

  Spring通过使用spring容器来负责控制对象之间的依赖关系,使得我们不再对对象之间的依赖负责。 这种依赖关系的实现就是大家所知道的控制反转(IoC)或依赖注射。参见Martin Fowler's "Inversion of Control Containers and the Dependency Injection Pattern"(martinfowler.com, 2004年2月)得到关于控制反转和依赖注射的更加深入的讨论。通过管理对象之间的依赖关系,spring就不需要那些只是为了使类能够相互协作,而将对象粘合的代码。

  作为spring beans的工作流组件

  在进一步讨论之前,现在是简要介绍spring中主要概念的恰当时候。接口ApplicationContext是从接口BeanFactory继承的,它被用来作为在spring容器内实际的控制实体和容器。

  ApplicationContext负责对一组作为spring beans的一组bean的初始化,配置和生命期管理。我们通过装配在一个基于XML的配置文件中的spring beans来配置ApplicationContext。这个配置文件说明了spring beans互相协作的本质特点。这样,用spring的术语来说,与其他spring beans交互的spring beans就被叫着协作者(collaborators)。缺省情况下,spring beans是作为单例存在于ApplicationContext中的,但是,单例的属性能够被设置为false,从而有效地改变他们在spring中调用原型模式时的行为。

  回到我们的例子,在飞机票价下降的时候,一个SMTP发送例程的抽象就被装配在工作流过程例子中的最后的活动(例子代码可以在 Resources中得到)。由于是第5个活动,我们命名它为activity5。要发送消息,activity5就要求一个代理协作者和一个错位处理句柄。



      class="org.iocworkflow.test.sequence.ratedrop.SendMessage">
     
         BR>     

     
        
     

  
/FONT>


  将工作流组件实施成spring beans产生了两个令人喜悦的结果,就是容易进行单元测试和很大程度上可重用能力。IoC容器的特点明显地提供了有效的单元测试。使用像spring这样的Ioc容器,在测试期间,协作者之间的依赖能够容易的用假的替代者替代。在这个航线的例子中,能够容易地从唯一的测试ApplicationContext中检索出像activity5活动这样的spring bean。用一个假的SMTP代理SMTP服务器,就有可能单独地测试activity5。

  第二个意外的结果,可重用能力是通过像XSL转换这样的工作流活动实现的。一个被抽象成工作流活动的XSL转换现在能够被任何处理XSL转换的工作流所重用。

  装配工作流

  在提供的API中(从Resources下载),spring控制了一些操作者以一种工作流的方式交互。关键接口如下:

Activity: 封装了工作流中一个单步业务逻辑
ProcessContext:在工作流活动之间传递具有ProcessContext类型的对象。实现了这个接口的对象负责维护对象在工作流转换中从一个活动转换到另一个活动的状态。
ErrorHandler: 提供错误处理的回调方法。
Processor: 描述一个作为主工作流线程的执行者的bean。

  下面从例子源码中摘录的代码是将航线例子装配为简单工作流过程的spring bean的配置。



  
     
        
           
           
           
           
           
         BR>     

     
         BR>      /property>
     
         org.iocworkflow.test.sequence.ratedrop.RateDropContextBR>     

   /property>

  SequenceProcessor类是一个对顺序模式建模的具体子类。有5个活动被连接到工作流处理器,工作流处理器将顺序执行这5个活动。

  与大多数过程式后台进程相比,工作流的解决方案真正的突出了高度强壮的错误处理。错误处理句柄可以单独地处理每个活动。这种类型的句柄在单一活动级别提供了细致的错误处理。如果没有单独处理单个活动的错误处理句柄,那么全局工作流处理器的错误处理句柄将会处理出现的问题。例如,如果在工作流处理过程中的任意时刻,一个没有被处理的错误出现了,那么它将会向外传播,被使用defaultErrorHandler属性装配的ErrorHandler Bean处理。

  更复杂的工作流框架将工作流转换之间的状态持久化存储到数据库中。在这篇文章中,我们仅仅对状态转换是自动完成的工作流感兴趣。状态信息仅仅在实际工作流运行时在ProcessContext中得到。在ProcessContext中,你仅仅能看到ProcessContext的接口的两个方法:


public interface ProcessContext extends Serializable {
      public boolean stopProcess();   
      public void setSeedData(Object seedObject);
   }


  用于航线例子工作流的具体的ProcessContext类是RateDropContext类。RateDropContext类封装了用于执行航线费率降低工作流必须的数据。

  到现在为止,经由缺省的ApplicationContext的作用,所有bean实例都已经成了单例。但是,对于每一个航线工作流的调用,我们必须创建一个新的RateDropContext类的实例。为了处理这种需求,需要配置SequenceProcessor,采用全限定类名作为processContextClass属性的值。对于每个工作流的执行,SequenceProcessor使用指定的类名从spring检索ProcessorContext类的一个新的实例。为了使这种机制能够起作用,非单件的spring bean或者类型org.iocworkflow.test.sequence.simple.SimpleContext的原型必须存在于ApplicationContext中(完整的列表,参见rateDrop.xml)。

  播种工作流

  既然我们知道怎样使用spring来组装一个简单的工作流,就让我们集中精力使用种子数据(seed data)示例工作流的过程。要明白怎样开始工作流,看一看在实际接口Processor上表现的方法:


public interface Processor {
      public boolean supports(Activity activity);
      public void doActivities();
      public void doActivities(Object seedData);
      public void setActivities(List activities);
      public void setDefaultErrorHandler(ErrorHandler defaultErrorHandler);
   }


  大多数情况下,工作流需要一些初始化激活才能开始。开始一个处理过程有两个选项:doActivities(ObjectseedData)方法或者无参数的doActivities()。下面的代码列表是包含在样例代码中为SequenceProcessor而实现的doActivities():


public void doActivities(Object seedData) {
   //Retrieve injected by Spring
   List activities = getActivities();
   //Retrieve a new instance of the Workflow ProcessContext
   ProcessContext context = createContext();
   if (seedData != null)
      context.setSeedData(seedData);
   //Execute each activity in sequential order
   for (Iterator it = activities.iterator(); it.hasNext();) {
      Activity activity = (Activity) it.next();
      try {
            context = activity.execute(context);
      } catch (Throwable th) {
         //Determine if an error handler is available at the activity level
         ErrorHandler errorHandler = activity.getErrorHandler();
         if (errorHandler == null) {
            getDefaultErrorHandler().handleError(context, th);
            break;
         } else {
            //Handle error using default handler
            errorHandler.handleError(context, th);
         }
      }
            //Ensure it's ok to continue the process
      if (processShouldStop(context, activity))
         break;
      }
   }

  在这个航空费用减少的例子中,工作流过程的种子数据包括航线信息和费率减少的信息。使用容易测试的航线工作流例子,通过doActivities(Object seedData)方法发出种子数据并激活一个单一的工作流过程是简单的:

BaseProcessor processor = (BaseProcessor)context.getBean("rateDropProcessor");
   processor.doActivities(createSeedData());


  这些代码是从包含在这篇文章中的测试例子中摘录的。rateDropProcessor Bean是从ApplicationContext中检索来的。rateDropProcessor实际上是装配成SequenceProcessor的实例来处理顺序执行。createSeedData()方法实例化一个对象,这个对象封装了初始化航线工作流所需要的所有种子数据。

  Processor选项

  虽然包含在源代码中的Processor具体的子类仅仅是SequenceProcessor,但是,许多Processor接口的实现也是可以想象得到的。可以开发其他工作流处理过程子类来控制不同的工作流类型,例如,另一种像并行切割模式那样有着变化的执行路径的工作流。对于简单工作流来说,因为活动的顺序是预先决定了的,所以SequenceProcessor是好的选择。尽管没有被包括进来,对于使用基于spring的简单工作流的实现来说,排他选择模式是另一个好的选择。当使用排他选择模式时,在每个活动执行之后,Processor具体类就会讯问ProcessorContext,接下来将要执行哪一个活动。

  注:有关并行切割,排他选择和其他工作流模式的更多信息,请参看W.M.P. van der Aalst等人写的《工作流模式》一书。

  启动工作流

  考虑到工作流过程常常需要异步执行的特点,使用分离的执行线程来启动工作流就变得有意义了。对于工作流的异步启动而言,有好几个选项;我们主要集中在其中的两个:积极地检测(actively polling)一个队列来启动工作流,或者使用通过ESB(enterprise service bus, 企业服务总线)的事件驱动方式来启动工作流,而Mule就是ESB的一个开源项目(关于Mule的更多信息,请参加"Event-Driven Services in SOA"(JavaWorld, 2005年1月)。

  图3和图4描绘了两种启动策略。图3中,积极检测在工作流中第一个活动经常检查资源的情形下发生,比如数据源或POP3邮件帐户。如果图3中的积极检测发现有任务等待处理,那么启动就会开始。

图 3. 通过积极检测来启动工作流

  另一方面,图4表示了使用JMS(JAVA消息服务)的J2EE应用程序把事件放到队列上的情形。一个通过ESB配置的事件监听器收到图4中的事件,并且开始工作流,这样,启动工作流过程。

图 4. 通过ESB事件来启动工作流

http://searchwebservices.techtarget.com.cn/tips/110/2127110.shtml

  使用所提供样例的代码,让我们更详细的看看主动选择启动方式与事件驱动的启动方式。


  积极检测

  积极检测是一种花费较少的启动工作流过程的方案。SequenceProcessor足够灵活,以使得能够通过平滑的选择工作来进行启动过程。尽管并不令人满意,在没有时间进行事件驱动子系统的配置和部署的许多情景中,积极检测是明智的选择。

  使用Spring的ScheduledTimerTask,检测模式就能够容易地装配。缺点就是必须创建额外的活动来进行检测。这个检测活动必须被设计来讯问某些实体,如数据库表,pop邮件帐户,或者Web服务,然后决定新的工作是否等待参与到工作流中。

  在所提供的例子中,PollingTestCase类实例化一个基于检测的工作流过程。使用一个有着积极检测处理过程与事件驱动的启动过程的不同之处在于,spring支持doActivities()方法的无参数版本。相反地,在事件驱动的启动中,启动处理过程的实体通过doActivities(Object seedData)方法提供了种子数据来启动工作流。检测方法的另一个缺点是:资源不一定能够被重复地使用。依赖于应用程序环境,这种资源的消耗是不可接受的。

  下面代码例子演示了使用积极检测来控制工作流启动的一个活动:

public class PollForWork implements Activity
{
   public ProcessContext execute(ProcessContext context) throws Exception {
      //First check if work needs to be done
      boolean workIsReady = lookIntoDatabaseForWork();
      if (workIsReady) {
         //The Polling Action must also load any seed data
         ((MyContext) context).setSeedData(createSeedData());
      } else {
         //Nothing to do, terminate the workflow process for this iteration
         ((MyContext) context).setStopEntireProcess(true);
      }
      return context;
   }
}


  此外,包含在例子代码的单元测试中的PollRates类提供了一个主动选举启动的可以运行的例子。PollRates模拟了对于航线费率下降的重复检查。

  通过ESB的事件驱动启动工作流

  理想地,一个包含了适当的种子数据的线程能够异步地启动工作流。这种情况的一个例子是收到从JAVA消息服务队列的消息。一个监听JMS队列或者主题的客户会收到通知,这个通知告知处理应该在onMessage()方法中开始工作流。然后,通过使用Spring和doActivities(Object seedData)方法就能够获得工作流处理器Bean。


  使用ESB,实际用于发送启动事件的机制能够恰当地从工作流处理器中分离出来。开源项目Mule ESB有紧凑地和Spring相集成的好处。任意传送机制,比如JMS,JVM,或者POP3邮箱都能够发起事件的传播。

  工作流的连续运行

  工作流引擎后台进程应该能够没有干扰地连续运行。对于正在运行的基于spring的工作流单一进程来说好,有几个选项。一个有着main()方法的简单Java类就足够演示与这篇文章伴随着的单元测试中的例子了。一个更加可靠的用于部署的机制是嵌入工作流到某种形式的J2EE组件中。Spring很好地支持和J2EE兼容的web应用程序归档或者war文件的集成。基于Java管理附件(JMX)服务归档和JBoss应用服务器(更多信息,参见JBoss homepage)支持的sar文件是更加合适的可部署组件,这种更合适的可部署组件也能够被用来将部署归档。在JBoss 4.0中,sar文件已经被大家所知道的deployer的格式所取代了。

  例子代码

  打包成zip格式的例程代码最好是用Apache Maven来使用它们。你能够在主源代码目录src/java找到API。src/java目录中有三个单元测试,包括:SimpleSequenceTestCase,RateDropTestCase和PoolingTestCase。要运行所有这些测试,在命令行shell中键入maven test,然后在编译和运行之前,Maven将会下载所有必需的jar文件。实际的XSL转换将会发生在两个测试中,它们的结果被管道输出到控制台。键入maven test:ui来拉出图形化的测试运行器,然后选择你想要运行的测试,并且观察控制台的结果。

  结论

  在这篇文章中你已经通过设计模式看到了工作流过程种类,在这些模式中,我们主要集中介绍了顺序模式。通过使用接口,我们来对基本工作流组件建模。通过装配多个接口实现到Spring,实现一个顺序工作流。最后还讨论了启动和部署工作流的不同选项。

  这里所提出的简单工作流技术肯定不是最终的和革命性的。但是,使用Spring来实现像工作流这样的通用任务是一个通过使用IoC容器而获得的效率的好的示例。由于减少了粘合性代码的需要,Spring在保持面向对象的约束同时,减少面向对象操作麻烦的程度。

http://macrochen.blogdriver.com/macrochen/1088243.html

什么是工作流引擎(Workflow Engine )- -

所谓工作流引擎是指workflow作为应用系统的一部分,并为之提供对各应用系统有决定作用的根据角色、分工和条件的不同决定信息传递路由、内容等级等核心解决方案。例如开发一个系统最关键的部分不是系统的界面,也不是和数据库之间的信息交换,而是如何根据业务逻辑开发出符合实际需要的程序逻辑并确保其稳定性、易维护性(模块化和结构化)和弹性(容易根据实际业务逻辑的变化作出程序上的变动,例如决策权的改变、组织结构的变动和由于业务方向的变化产生的全新业务逻辑等等)。 Workflow 引擎解决的就是这个问题:如果应用程序缺乏强大的逻辑层,势必变得容易出错(信息的路由错误、死循环等等)。

就好比一辆汽车,外表做得再漂亮,如果发动机有问题就只是一个摆设。应用系统的弹性就好比引擎转速方面的性能,加速到100 公里需要1 个小时(业务流程发生变动需要进行半年的程序修改)还能叫好车吗?引擎动不动就熄火(程序因为逻辑的问题陷入死循环)的车还敢开吗?

工作流解决方案与传统管理软件的关系传统的管理软件注重解决企业应用层现存的问题(例如提高企业的资源配置率或提高单一员工的生产效率)。例如:EXCEL 可以提高员工画表格的效率、财务软件可以规范财务人员的工作并提高帐目查询的效率、CRM 可以规范客户管理从而使客户资源掌握在公司手中而不是被一部分业务人员把持并提高客户响应时间、ERP 解决的是如何配置企业资源:使企业的人力资源、财力资源和物资资源能够根据业务的需求实现最大化配置。 workflow 关注的是如何缩短流程闲置时间,从而提高企业的业务处理能力并使企业能够关注于真正对企业有意义的增值业务上。从建立企业神经系统的角度也许更能理解两者的区别。传统软件不能解决工作流的问题,例如ERP 关注的是企业的资源配置,但不可能解决资源传输过程中的损耗和降低传输(流程)的成本;同样workflow也不能完全解决传统管理软件所能解决的问题,例如对生产管理的MRP 系统所能解决的生产过程控制通过workflow很难实现。但一个好的传统软件如果希望能自动化地在整个企业中应用起来,必须有一个强大的逻辑层,用以解决信息传递的逻辑判断和自动流转,这个时候就需要workflow的平台。所以说: 1.workflow 和传统管理软件不是同一种软件,不具可比性; 2.workflow 对于已经有传统管理软件的企业的作用非常明显,可以籍此平台整合企业的各种应用系统,使之成为一个完整的企业级应用,也就是通常所说的EAI. 3. 具备workflow功能的管理软件(workflow与传统管理软件的结合)对于传统管理软件有绝对的优势;4.workflow可以根据企业的需要开发解决信息传递问题的流程以及帮助企业开发与现有应用系统的接口

工作流自动化并不复杂因为下述几个原因,工作流自动化业界有" 适合处理复杂业务流程" 的名声。

1.常规工作流自动化软件包及其部署相当昂贵。通常,伴随产品的是长时期的咨询关系。所以为了非常简单的业务流程购买和部署软件是被不被采纳的。这些软件通常只被用于复杂、关键和控制成本相对较高而工作流自动化带来的效益明显的量产型工作流应用。因此经销商和用户都会不自觉地关注于将复杂的业务问题自动化。 2. 处于类似原因,工作流研究人士首先会关注解决了哪些复杂的业务流程问题。

而对于大多数案例而言,为解决简单工作流程问题部署自动化软件的成本显然是不经济的。这里遵循一条简单的道理:走之前必须先会爬,跑之前必须先会走。 3. 最后一条原因,也是"IT 业的尴尬".总经理对IT部门经理工作衡量的标准就是:能够解决复杂问题的能力。自然,IT经理就会不遗余力地解决那些复杂的问题,他们的方案通常也就复杂而且昂贵。

所有这些目前都在改变。针对桌面电脑的应用方案快速发展以及工作流解决方案的发展使解决日常工作流程问题成为可能。费用不再昂贵,部署更为简便。事实上,企业越来越意识到工作流的重要性,同时在部署复杂关键的流程自动化之前,愿意从一些简单的流程入手积累经验。

工作流会成为操作系统的一部分吗?

有人认为工作流会成为操作系统平台(例如WINDOWS 平台)的一部分。我们的观点是,基于下述几个原因,在可预见的未来,工作流不会成为操作系统的一部分: 1. 扩展表格、文字处理程序和数据库存在了20多年,成了家喻户晓的名词。这些技术被广泛理解和应用,也相应形成了各自的标准和相关术语。然而因为很多原因,直到今天这些技术也没有成为操作系统的一部分。最重要的原因之一是用户需要差异和选择的自由。相比较而言,工作流自动化软件是较新的技术,也更有差异性、不易被广泛理解并且比这些技术更为先进。因为工作流程的差异性和复杂性,工作流自动化的用户需要更多的选择空间。

2.财务软件包从电脑发明后就迅速普及了。这是实施、术语和规则被普遍接受的另一个领域。然而至今也没有哪种操作系统吹嘘集成了多少财务软件的功能。而工作流自动化软件比财务软件更为复杂和有差异性。 3. 操作系统提供商,例如微软和Sun ,不会为了使其系统具备工作流自动化的功能而大量改变他们现有的系统。他们有什么必要为工作流自动化软件投入开发和支持的成本呢? 4. 操作系统是为常规条件设计并使之最优化。正因如此,目前操作系统的开发成本几乎都要上亿美元。业务流程十分复杂并充满了例外情况,如在操作系统中内嵌工作流自动化程序会极大地增加开发成本和难度。因此,即便操作系统提供商决定做工作流软件,也会是巨额投入开发一套新的操作系统,而不是将工作流嵌入。

事实上,今天的很多优秀的工作流解决方案集成了短信息、页面服务、目标管理、文件管理和其他一些操作系统才提供的服务。

工作流自动化的主要成分工作流自动化如今成了管理的一句时髦话。市面上也有很多号称能激活工作流的自动化产品。只要他们的应用程序支持基本的E-mail功能,卖主就会随意地把" 激活工作流" 作为标签贴在产品上。然而,这类产品和真正工作流自动化软件之间的差别就如同写字版和Word之间的差别。我们相信,应用程序只有具备了下列主要特征,才能称其为工作流自动化解决方案:

能够画出工作流程图,当然以图形化界面设计的为佳;能为每个步骤设计电子表格;能将外部应用程序结合为工作流自动化的一部分;能与电子表格及企业数据库相连接;能设计基于复杂业务规则的条件型路由的工作流程图,最好无须编程;能根据功能、用户名称或上下级关系按规则传递信息;能够监控工作流执行状况;能够对工作流进行调节;能够模拟并测试工作流的行为;工作流的应用必须支持多用户并具高度可靠性;工作流的应用必须支持内部网或英特网及跨多种平台。

网友讨论工作流应该是一个中间件而不应该是一个完整的系统。工作流应该整合到其他系统中而不是单独使用。

工作流要完成的核心功能有流程设计,流程执行,流程和线程的调度,任务的分派与通知,集成已有信息系统(很多人忘了)。

工作流应该提供对组织机构,用户,权限管理,流程,任务的管理能力,但是对这些管理能力最基本实现方式是提供API ,而不是一个管理系统,即使把这些管理作为一个管理系统来实现(A ),也主要是用于演示,因为当工作流用于其它系统(B ),因为B 需要一个统一的管理界面,所以通常不会直接使用A.而表单设计,报表之类根本就是外围功能,是二次开发商的任务。

我基本赞同wangtaoyy 的说法,再补充一点。我觉得工作流与其说是中间件,还不如说是一个应用整合和集成的框架。类似在j2ee规范下各产商开发的应用服务器,工作流也应当是在wfmc标准下开发出来的" 容器" ,只要是满足了标准的应用程序或组件都能够在这个" 容器" 中按照预定的规则被调度和执行。我认为理想情况下工作流系统不应该提供API 作二次开发,工作流的内部对基于工作流的应用程序应当是完全不透明的,工作流应当提供给开发者的是一个类似于J2EE那样的标准,一套编程模型和接口模型。开发者在这个模型下去实现那些接口,开发出应用组件,再利用工作流提供的管理器进行" 注册".总而言之,对开发者而言,工作流是黑箱,他需要做的事情是开发标准组件,在工作流提供的UI管理工具中配置业务流程,包括业务过程、资源、权限、时间、规则等等。

1. j2ee 应用服务器也是中间件的一种。
2. 工作流要做成j2ee哪样的标准还是比较困难的, j2ee 重点在于提供开发全新系统的能力,所以可以制定比较好的容器- 组件标准,而工作流的重点是整合已经存在的系统,要在这些各式各样的老系统上强加标准是不现实的。
3.工作流应该提供api ,因为其他系统中的一些事件可能会启动一个流程,或者触发其他与流程相关的东西

工作流分为两种类型,一种是嵌入式的,另一种是非嵌入式的。这在WFMC的文档中已经有所介绍,大家可以找找看一下。按照工作流管理联盟的文档,大家说的都没有什么错误,只是侧重点不同。wangtaoyy 的观点倾向于前者,而coffeewoo 的观点倾向于后者。

我的看法并不是趋向于嵌入式工作流。我理解的工作流提供的api 并不是一般软件包的API ,而是一种服务方式的API ,类似于操作系统中的系统调用。

我们在软件中大量使用了操作系统提供的系统调用API ,但是操作系统并不是嵌入到我们软件系统中的。我认为工作流系统与操作系统有很强的可比性,只是工作流层次更高。比如流程设计相当于编程,模型相当于程序,流程实例相当于进程,流程分支相当于线程,操作系统要对进程和线程进行调度,工作流引擎要对流程实例和分支进行调度,操作系统和工作流系统都应该对内存进行管理避免耗尽系统内存,操作系统提供系统调用API 而工作流引擎提供工作流API.何其相似。

从功能的角度看:工作流系统的本职工作就是管理和控制业务流程,例如:流程实例的启动、停止;环节实例的启动、结束;任务的分配等等。从工作流系统的组成看:工作流系统应该包括流程引擎、流程定义工具、运行管理工具、api 系统。工作流系统应该该包括表单定义、组织机构定义及其管理、权限管理、数据流管理等等。

工作流系统虽然不包括上述功能,但是工作流系统一定会和上述功能发生交互关系,所以好的工作流产品并不是一个包办上述功能的产品,而是一个设计良好的能够和上述功能交互的系统。从和其他系统的关系看待工作流:如果站在基础业务平台的角度,那么,工作流系统、组织机构管理系统、表单自定义系统、权限管理系统、数据流管理系统、报表系统都是这个基础业务平台的服务。业务功能系统在运行的过程中会调用这些服务,这些服务之间本身也可能互相调用。例如:工作流服务和组织机构管理服务之间的关系就非常密切,尽管如此,如果认为工作流系统一定包含组织机构管理系统应该是不正确的。在oa系统中,表单自定义好像比较重要,而且流程常常需要引用表单上的数据,但是表单自定义绝对不是工作流系统的组成部分。流程在运行的过程中可能跨多个数据库系统,任务在流转的过程中需要“携带”大量的业务数据,但是这些也不是工作流要做的事情,完成这些工作的系统我称之为“数据流管理系统”。总之:从功能的角度,所有的功能都是必要的,但是从技术的角度,这些功能不可以做到一个“铁板一块”的所谓的“工作流”里面去。从技术发展的趋势看:工作流系统很可能发展成为一个类似关系型数据库管理系统的专职的系统。我那个工作流东东还在改进中,希望作出一个设计合理的(决对不是强行coding出来的),工程实用的东西出来

posted @ 2006-06-01 14:12 崛起的程序员 阅读(1977) | 评论 (0)编辑 收藏