|
2005年11月19日
blog也搬迁了:http://blog.sina.com.cn/liuwendao
来武汉快三年了,留在北京的最后一件物件-电吉它,也被我拿到武汉来了
我们这么混,能成功吗?
立帖为证
军事演习区,一位妇女驾车在大桥前被一名军官拦住:“对不起,公民,您现在不能过去。”“为什么?”“这座桥在一小时前被炸毁了。”“您能告诉我这究竟是怎么回事吗?”“很抱歉,不行。我本人已于2小时前阵亡。” 伊万看电视,是勃在演讲。伊万觉得无聊,换了一个,还是勃在演讲,又换一个,还是他。伊万一连拨了几十个台,最后累了,准备关电视。这时候电视画面变成一个KGB,怒气冲冲地叫:“你再敢换?再敢换?再换判你10年大牢!” 某日苏联举行国庆**,沿着大街开来了炮兵、机械化步兵、坦克、自行火炮、战术导弹、战略核导弹,破坏力一个比一个大;队列末尾却是两个带公文包的矮子。在看台上勃列日涅夫惊讶地说:“这两个人破坏力比核导弹还大!他们是什么人?” KGB头子说:“不是我的人。” 国防部长说:“没见过他们。” 苏联总理说:“他们是国家计委的...” 戈尔巴乔夫视察农场,看到猪儿乖乖,一时兴起站在猪中间照了张像。 待到报纸准备发表时,编辑为照片的标题犯了难?? “戈尔巴乔夫同志和猪在一起”不好。 “猪和戈尔巴乔夫同志在一起”也不好。 报纸出版后,照片下的说明文字是?? “左起第三位是戈尔巴乔夫同志” 勃列日涅夫和美国总统卡特在瑞士开会,休息时间两个人很无聊,就开始比谁的保膘更忠诚。卡特先来,他把自己的报膘叫进来,推开窗(外面是20层楼)说:“约翰,从这里跳下去!” 约翰哭着说:“你着么能这样呢,总统先生,我还有老婆孩子呐。” 卡特被感动了,流着泪说是自己不对,叫约翰走了,然后抡到勃列日涅夫,他也大声叫自己的保膘伊万。 “伊万,从这里跳下去!” 伊万二话不说就要往下跳,卡特一把抱住他说:“你疯了?跳下去会死的!” 伊万一边挣扎着要跳下去一边说:“放开我,混蛋,我还有老婆孩子呐。” 早年莫斯科修地铁,工程师将方案上报斯大林审批。不久,方案发下来,上面有斯大林的签字。 细心的工程师发现图纸上多了一个圆型的茶杯印,于是莫斯科地铁就多了一条环形线。 斯大林肃反时期的苏联。一位内务人民委员部审判员结束一天的审判工作,回到办公室,突然一个人大笑起来。对面办公桌的同事奇怪的问道:“有什么好笑的事吗?”“是啊,”审判员用手帕擦着笑出来的眼泪:“一个很好笑的笑话……”“哦?说来听听?”“你疯了吗?!我刚判了说这笑话的家伙五年苦役!” 苏联30年代肃反扩大化时期。内务人民委员部的一间牢房里关了三个人,彼此间谈起坐牢的原因。 第一个人说,我因为反对了党书记彼得罗夫; 第二个人说,我因为支持了彼得罗夫; 第三个人说,我就是彼得罗夫。 戈尔巴乔夫和他的司机开着车在路上,戈尔巴乔夫突发异想,说:让开!我来开。一个老警察和一个新警察在路上值勤,见一辆车歪歪扭扭的开得疯快,老警察就对新警察说:去!好好收拾一下。新警察将车拦住之后,又没趣没趣地回来了。老警察问:怎么?里面是谁?新警察回答说:我也不知道里面是谁,反正给他开车的是戈尔巴乔夫。 美国外交代表团到苏联访问,苏联接待官员陪他们参观“建设的伟大成就”,并且得意的说:“到了下一个五年计划,每个苏联家庭都可以拥有一架私人飞机!”美国人惊讶的问:“ 他们要飞机干什么呢?”苏联官员说:“当然有用啊……譬如你在莫斯科听说列宁格勒开始供应面包了,你可以马上开着飞机赶去排上队。” 一位公民打电话到基辅电台问主持人:“共产主义到底是艺术还是科学?” 主持人说:“我也不清楚,但我肯定不是科学” “为什么?” “如果是科学的话,他们应该拿狗做试验。” 斯大林在大会上引经据典地说:“马克思和列宁说1+1=2,而托洛茨基和布哈林说1+1不等于3。是托洛茨基和布哈林说的对呢?还是马克思和列宁说得对呢?”下面听众一脸疑惑,“毫无疑问,是马克思和列宁说的对!”底下热烈鼓掌,“托洛茨基和布哈林是帝国主义派来的间谍,说1+1不等于3的人罪不容赦……” 列宁快去世了,叫赶快把继承人斯大林召进克里姆林宫来,临终有几句话要嘱托。“不瞒你说,我还有一个隐忧啊,斯大林。”“说吧,亲爱的伊里奇。”斯大林专心地听着。“那就是,人们会跟你走吗?不知你想过了没有?”“他们一定会跟我走的。”斯大林强调说,“一定会!” “但愿如此。”列宁说,“我只是担心,万一他们不跟你走,你怎么办?”“没问题!”斯大林答道:“那他们就得跟你走!” 集体农庄庄员伊万在河里捉到一条大鱼,高兴的回到家里和老婆说:“看,我们有炸鱼吃了!” “没有油啊。” “那就煮!” “没锅。” “烤鱼!” “没柴。” 伊万气死了,走到河边把鱼扔了回去。那鱼在水里划了一个半圆,上身出水,举起右鳍激动地高呼:“斯大林万岁!” “瑞典能否建立共产主义”? “不能。” “为何?” “列宁同志说了:共产主义不在山那边。” 一个苏联KGB特工和一个美国CIA特工互相吹嘘各自的机构是如何的杰出。 那个KGB特工首先发言说,“我们拥有你们美国过去15年里所有导弹发射的详细数据。” CIA特工说:“这不算什么。我们CIA掌握着你们苏联未来15年里所有当选的中央委员名单。” 一艘航行在大海上的轮船快要沉了,船长叫乘客赶紧跳海,但他喊了半天没有一个人跳,一个社会学家说我来喊,他去喊过之后所有的人都跳下海去了。船长觉得奇怪,问他是怎么喊的,社会学家回答说:我对法国人说这样跳下去很浪漫,我对西班牙人说这样跳下去很潇洒,我对英国人说这样跳下去是一种体育运动,我对美国人说这样跳下去有利可图,我对苏联人说这样跳下去是革命行动。 在苏联的一趟公交车,一个男的非常谦恭地问站在他身旁的另一个男的:“同志,请问您是克格勃吗?” 那人答道:“不是。” 又问:“那您有没有亲戚或朋友是克格勃呢?” 答:“没有。” 还问:“那您是否跟克格勃有些交往或联系?” 答:“没有,你要干嘛啊!” 该男生气地说:“干嘛,他妈的,你踩着我的脚了!” 赫鲁晓夫作报告,批判斯大林。忽然,有人从台下递了个纸条,写道:当他做坏事的时候,你在哪里?赫鲁晓夫一看这个条子,大声怒喝道:“是谁写的,给我站出来。”台下雅雀无声,没有人站出来。赫鲁晓夫接着说道:“同志们,我当时就和你们现在一样,你们知道我当时为什么不敢站出来了吧” 勃列日涅夫:同志们,美国人登上了月球,我们不能再等了,党决定让你们上太阳。 宇航员:总书记同志,我们会被烧死的。 勃列日涅夫:没关系,同志们,党都替你们想好了,你们晚上去。 电影《这里的黎明静悄悄》试映时,由于其中有部分裸体镜头,因此主管电影审核的官员曾试图把这部电影禁演,幸亏勃列日涅夫内部观看时感动得热泪盈眶,这部优秀的电影才有幸与观众见面,成为世界电影史上不朽的篇章。而另一部电影由于其中有主人公走到教堂时跪地痛哭的镜头,被电影审核官员认为是宣扬宗教而准备勒令裁掉这部分内容,恰恰勃列日涅夫看到这里时动了感情,因此这个镜头得以幸存下来。 当年的捷克斯洛伐克政府中,设立了一个“海军部”,结果,苏联老大哥就对捷克人说:你们是内陆国家,设什么海军部? 捷克人回答说:那你们不是也设了文化部吗?
最近看到越来越多的人使用mina,甚至在线下也碰到合作公司的库中使用MINA,出于好奇,尝试一下用自己的blog做一下调查,访问本blog的兄弟,如果您使用MINA作为自己的通讯基础件,请留言介绍一下自己
软件开发的世界里充满了不理解, 客户不理解软件是怎样开发的、经理不理解开发人员、开发人员不理解指挥者。问题在于软件开发惊人的困难,造成很少有开发人员能够说出软件自始至终是怎样开发的,并能够对这个过程中会遇到的不同选择所隐含的结果表现出适度的理解。 在软件开发人员还很年轻的时候(十几岁或二十出头),他们通常集中精力学习和使用技术,称自己为perl程序员、Linux专家、EJB开发人员、.NET开发人员等。对他们来说技术是最重要的事情。因为技术在不断的变化,年轻的程序员倾向于大致学习一个技术,在一到两个项目中使用,然后重新开始学习新技术或者是学习以前使用过的技术的最新发展。这里的问题是,他们一遍又一遍的重复的学习的不过是同样的低层次基本技能的不同风味。 幸运的是,很多开发人员在经过了几轮技术学习之后逐渐意识到:一旦用COBOL、Java、C#等语言为事务控制编写过代码,就会开始认识到基本的、本质的东西是不变的。不同环境下的数据库访问、用户界面设计等领域也是同样的情况。不久以后,开发人员逐渐认识到无论具体的技术怎样,很多基础性的东西是保持不变的,这些基础性的东西有的在学校里讲过,有的没有。 这种认识经常发生在开发人员接近三十岁或刚过三十岁的时候,通常是人们开始稳定下来,结婚、买房的时候。这是比较幸运的情况,因为上面提到的这些新的个人需求意味着他们不可能再投入大量的时间去学习新的技术,他们需要用这些时间和家庭成员在一起。突然的,高层次的角色如项目负责人、项目经理、(非敏捷的)建模人员等对他们变得非常有吸引力,因为这些角色不需要持续花费大量的时间和精力去学习新技术。于是,等到开发人员开始真正学到技艺的时候,他们已经处于离开开发人员角色的转变过程中了。所幸的是,新的“小年轻”不断的跟上来,这个过程在不断的循环重复。最终的结果是:大部分最活跃的正在开发软件的人通常不是最称职的做这件事的人,而他们自己甚至还不知道。
来自pythoncn的maillist,呵呵,挺有意思 ------------- 像Chris Qie <longroad1999@gmail.com>这样的在公共论坛用侮辱性言语挑起骂战并从中获取某种不知名快感的人,在Usenet文化中有一个名称:
-
Troll
。
- Troll作动词是钓鱼的意思,指那些人发表某种言论后等待别人的攻击性回复,从而获得快感。Troll还有一个意思是斯堪的纳维亚神话中一种长相丑陋、爱恶作 剧、令人讨厌的巨人,和那些找骂的人有相似之处,因此也被引申过来形容那些 人,做名词使用。回troll的贴则被称为feed the trolls,即给trolls喂食。
- Trolls有很多种,像Chris Qie只是其中一种,即使用种族歧视性语言激怒别人,好让别人回帖骂他。comp.lang.python上著名的troll: Xah Lee则是长年在各个 script语言讨论组上交叉张贴无关内容或用错误百出的话语对某种语言或者文化进 行攻击。但无论那种troll,他们的目的都是一样的:想通过怪诞的举动引起别人 的注意。这是一种病态心理,是一种未成熟,类似小孩“人来疯”似的举动。
- Trolls的存在对公共空间是破坏性的。它们的post会引起很多人回帖,甚至会有情绪激动者采用谩骂的方式回敬,这些人被称为trollhunter。这些行为正中trolls 的下怀,使他们获得被骂的快乐,从而更加积极的trolling。而且即使 trollhunter的动机是好的,也会给论坛带来不好影响,使其他用户接收到大量无 关信息和攻击性信息,成为受害者。公共空间的和谐性被破坏。
- Trolls最愿意看到别人回他的贴,无论是正儿八经指出他的错误还是义愤填膺的对他谩骂。对一个troll来说,最能让他感到沮丧的则是没有人理他。而我们,正是 应该让他们沮丧,失去trolling的动力。
- 对待trolls的方法,一方面要靠大家自觉,克制自己回帖的冲动,不给他们喂食。
另一方面,在邮件列表这种有管理员的公共空间,可以向管理员提出封禁trolls的 提案。
- 下图是我从c.l.python上Keith Thompson对Xah Lee的trolling行为提醒公众的帖子中拷贝过来的图片(请使用等宽字体观看)
+-------------------+ .:\:\:/:/:.
| PLEASE DO NOT | :.:\:\:/:/:.:
| FEED THE TROLLS | :=.' - - '.=:
| | '=(\ 9 9 /)='
| Thank you, | ( (_) )
| Management | /`-vvv-'\
+-------------------+ / \
| | @@@ / /|,,,,,|\ \
| | @@@ /_// /^\ \\_\
@x@@x@ | | |/ WW( ( ) )WW
\||||/ | | \| __\,,\ /,,/__
\||/ | | | jgs (______Y______)
/\/\/\/\/\/\/\/\//\/\\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
/*-------------------------------------------
程序员的进化——从学生到首席执行官
翻译 2002 王咏刚
http://www.contextfree.net/
转译自 Omri's Computer Humor Page
http://www.cs.bgu.ac.il/~omri/Humor/
-------------------------------------------*/
-------------------------------------------------------------------------------- 中学阶段
10 PRINT "HELLO WORLD" 20 END -------------------------------------------------------------------------------- 大学一年级
program Hello(input, output) begin writeln('Hello World') end. -------------------------------------------------------------------------------- 大学高年级
(defun hello (print (cons 'Hello (list 'World)))) -------------------------------------------------------------------------------- 初级程序员
#include <stdio.h> void main(void) { char *message[] = {"Hello ", "World"}; int i;
for(i = 0; i < 2; ++i) printf("%s", message
); printf("\n"); } -------------------------------------------------------------------------------- 编程老鸟
#include <iostream.h> #include <string.h>
class string { private: int size; char *ptr;
public: string() : size(0), ptr(new char('\0')) {}
string(const string &s) : size(s.size) { ptr = new char[size + 1]; strcpy(ptr, s.ptr); }
~string() { delete [] ptr; }
friend ostream &operator <<(ostream &, const string &); string &operator=(const char *); };
ostream &operator<<(ostream &stream, const string &s) { return(stream << s.ptr); }
string &string::operator=(const char *chrs) { if (this != &chrs) { delete [] ptr; size = strlen(chrs); ptr = new char[size + 1]; strcpy(ptr, chrs); } return(*this); }
int main() { string str;
str = "Hello World"; cout << str << end
return(0); } -------------------------------------------------------------------------------- 编程高手
[ uuid(2573F8F4-CFEE-101A-9A9F-00AA00342820) ] library LHello { // bring in the master library importlib("actimp.tlb"); importlib("actexp.tlb");
// bring in my interfaces #include "pshlo.idl"
[ uuid(2573F8F5-CFEE-101A-9A9F-00AA00342820) ] cotype THello { interface IHello; interface IPersistFile; }; };
[ exe, uuid(2573F890-CFEE-101A-9A9F-00AA00342820) ] module CHelloLib {
// some code related header files importheader(<windows.h>); importheader(<ole2.h>); importheader(<except.hxx>); importheader("pshlo.h"); importheader("shlo.hxx"); importheader("mycls.hxx");
// needed typelibs importlib("actimp.tlb"); importlib("actexp.tlb"); importlib("thlo.tlb");
[ uuid(2573F891-CFEE-101A-9A9F-00AA00342820), aggregatable ] coclass CHello { cotype THello; }; };
#include "ipfix.hxx"
extern HANDLE hEvent;
class CHello : public CHelloBase { public: IPFIX(CLSID_CHello);
CHello(IUnknown *pUnk); ~CHello();
HRESULT __stdcall PrintSz(LPWSTR pwszString);
private: static int cObjRef; };
#include <windows.h> #include <ole2.h> #include <stdio.h> #include <stdlib.h> #include "thlo.h" #include "pshlo.h" #include "shlo.hxx" #include "mycls.hxx"
int CHello::cObjRef = 0;
CHello::CHello(IUnknown *pUnk) : CHelloBase(pUnk) { cObjRef++; return; }
HRESULT __stdcall CHello::PrintSz(LPWSTR pwszString) { printf("%ws\n", pwszString); return(ResultFromScode(S_OK)); }
CHello::~CHello(void) {
// when the object count goes to zero, stop the server cObjRef--; if( cObjRef == 0 ) PulseEvent(hEvent);
return; }
#include <windows.h> #include <ole2.h> #include "pshlo.h" #include "shlo.hxx" #include "mycls.hxx"
HANDLE hEvent;
int _cdecl main( int argc, char * argv[] ) { ULONG ulRef; DWORD dwRegistration; CHelloCF *pCF = new CHelloCF();
hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
// Initialize the OLE libraries CoInitializeEx(NULL, COINIT_MULTITHREADED);
CoRegisterClassObject(CLSID_CHello, pCF, CLSCTX_LOCAL_SERVER, REGCLS_MULTIPLEUSE, &dwRegistration);
// wait on an event to stop WaitForSingleObject(hEvent, INFINITE);
// revoke and release the class object CoRevokeClassObject(dwRegistration); ulRef = pCF->Release();
// Tell OLE we are going away. CoUninitialize();
return(0); }
extern CLSID CLSID_CHello; extern UUID LIBID_CHelloLib;
CLSID CLSID_CHello = { /* 2573F891-CFEE-101A-9A9F-00AA00342820 */ 0x2573F891, 0xCFEE, 0x101A, { 0x9A, 0x9F, 0x00, 0xAA, 0x00, 0x34, 0x28, 0x20 } };
UUID LIBID_CHelloLib = { /* 2573F890-CFEE-101A-9A9F-00AA00342820 */ 0x2573F890, 0xCFEE, 0x101A, { 0x9A, 0x9F, 0x00, 0xAA, 0x00, 0x34, 0x28, 0x20 } };
#include <windows.h> #include <ole2.h> #include <stdlib.h> #include <string.h> #include <stdio.h> #include "pshlo.h" #include "shlo.hxx" #include "clsid.h"
int _cdecl main( int argc, char * argv[] ) { HRESULT hRslt; IHello *pHello; ULONG ulCnt; IMoniker * pmk; WCHAR wcsT[_MAX_PATH]; WCHAR wcsPath[2 * _MAX_PATH];
// get object path wcsPath[0] = '\0'; wcsT[0] = '\0'; if( argc > 1) { mbstowcs(wcsPath, argv[1], strlen(argv[1]) + 1); wcsupr(wcsPath); } else { fprintf(stderr, "Object path must be specified\n"); return(1); }
// get print string if(argc > 2) mbstowcs(wcsT, argv[2], strlen(argv[2]) + 1); else wcscpy(wcsT, L"Hello World");
printf("Linking to object %ws\n", wcsPath); printf("Text String %ws\n", wcsT);
// Initialize the OLE libraries hRslt = CoInitializeEx(NULL, COINIT_MULTITHREADED);
if(SUCCEEDED(hRslt)) {
hRslt = CreateFileMoniker(wcsPath, &pmk); if(SUCCEEDED(hRslt)) hRslt = BindMoniker(pmk, 0, IID_IHello, (void **)&pHello);
if(SUCCEEDED(hRslt)) {
// print a string out pHello->PrintSz(wcsT);
Sleep(2000); ulCnt = pHello->Release(); } else printf("Failure to connect, status: %lx", hRslt);
// Tell OLE we are going away. CoUninitialize(); }
return(0); } -------------------------------------------------------------------------------- 黑客初阶
#!/usr/local/bin/perl $msg="Hello, world.\n"; if ($#ARGV >= 0) { while(defined($arg=shift(@ARGV))) { $outfilename = $arg; open(FILE, ">" . $outfilename) || die "Can't write $arg: $!\n"; print (FILE $msg); close(FILE) || die "Can't close $arg: $!\n"; } } else { print ($msg); } 1; -------------------------------------------------------------------------------- 黑客有成
#include <stdio.h> #define S "Hello, World\n" main(){exit(printf(S) == strlen(S) ? 0 : 1);} -------------------------------------------------------------------------------- 黑客高手
% cc -o a.out ~/src/misc/hw/hw.c % a.out -------------------------------------------------------------------------------- 黑客大虾
% cat Hello, world. ^D -------------------------------------------------------------------------------- 初级经理
10 PRINT "HELLO WORLD" 20 END -------------------------------------------------------------------------------- 中级经理
mail -s "Hello, world." bob@b12 Bob, could you please write me a program that prints "Hello, world."? I need it by tomorrow. ^D -------------------------------------------------------------------------------- 高级经理
% zmail jim I need a "Hello, world." program by this afternoon. -------------------------------------------------------------------------------- 首席执行官
% letter letter: Command not found. % mail To: ^X ^F ^C % help mail help: Command not found. % damn! !: Event unrecognized % logout --------------------------------------------------------------------------------
下午写完设计,趴在武汉办公室的窗户上看风景,天气好的时候,左面长江右边东湖都可以看到,其实想想在武汉出差也挺不错的,呵呵
彼得·德鲁克在他的《 卓有成效的管理者 》当中,阐述了知识工作者管理的秘诀,那就是知识工作者的工作效率来自于对其工作的有效性以及他的工作是否有所成就。这本1966年出版的管理学书籍经过近50年的时间,反而越发显得适应潮流。 而卓有成效的知识工作管理者现在显得比过去任何时候都要短缺,也比现时任何人才都要短缺。在现时这个信息爆炸,案例丰富的年代,战略眼光与部署格局对于一个企业人才不再如此重要,对于企业战略,任何有管理常识、了解企业实情的人大都可以分析得很到位,关键是要找到合适的人去实施。知道什么样的人合适,以及找到这个合适的人,成为企业家最需要做的事情。而成为那个合适的人,则成为草根阶层走入舞台中央的必备能力。 附一篇来自经济观察报刘军的《 笨蛋,最重要的是人!》 --------------------------------- 2005年10月8日管理大师彼得·德鲁克曾经讲过一个他和《时代》《财富》等杂志的出版人亨利·鲁斯交往的故事。鲁斯有个很好的新杂志方案——试图创办“从美国人思考角度出发”的高格调文化杂志,他去向德鲁克求教。德鲁克分析了一番说,“这份企划案很棒,不过晚了50年。”接着,他对鲁斯说出了最重要的话:“此外,《时代》的人也无法胜任。我猜,你想鼓励一些外面的作家来为这本杂志执笔,并以一般大众为读者群。但是你的专长却是叫自己手下人搞定,因此大有不同。” 鲁斯回答说,“我来向你请教,正因为我猜想你会这么说。”他因而放弃了这个计划,因为他深知人的重要性。经过十多年的西方管理教育和知识传播,中国企业管理者已经熟知战略的理性分析,与重视人比起来更重视事,另外先建立制度、而不是依靠人的观念也被广泛接受。不过,我却逐渐感觉到,在这些问题上我们可能有点矫枉过正,对于知识型工作、对于管理,或许人更重要,是应该优先考虑的。 9月底,索尼新任CEO、美国人霍华德·斯特林格(Howard Stringer)宣布索尼的战略调整计划:全球裁员一万人,缩减工厂数目,出售1200亿日元的不动产与股票等非核心资产,对消费电子业务进行架构调整、将权力集中到这一业务的最高主管手中。在过去五年中,索尼逐渐失去消费电子霸主地位,业绩很不理想,这背后的根本原因正是这些战略调整所触及的问题。对于这一点,大概稍微有点管理常识的人都知道,我想索尼前CEO出井伸之自然了然于心,他之下的索尼高管也清楚。不过,大概只有霍华德·斯特林格、索尼历史上第一个外国人CEO、这个日本文化的局外人才能推行上述改革。 战略,有管理常识、了解企业实情的人大都可以分析得很到位,但真正去做,就需要“合适的人”。我一直相信,选择霍华德·斯特林格作为继任者,是出井伸之的最重要的决策,体现这个亚洲最优秀的商业领袖的领导才能。卡洛斯·戈恩已经因成功在日产汽车(Nissan)实现大逆转而成为全球最知名的管理者之一,他当初所做的关闭工厂与裁员、破除日本式企业联盟等措施,都是众所周知的弊端,但惟有他这个合适的人才能推动变革。斯特林格和戈恩都是在这种情境下最合适的人,只是恰巧他们都是外国人。 Google、微软和李开复之间的纷争一直没有停息的迹象。在这个过程中李开复把自己再次塑造成了最优秀的技术专家形象,但如果相信这一点,我们就错误理解了Google的智慧。如果要一流的中文搜索研发人才,Google的最佳人选绝对不是李开复,而可能是李彦宏。如果它的战略诉求点是这个,它可以百度买下,从而得到李彦宏。但是,Google在中国,需要的哪里是什么技术专家、研发中心?现在Google中国战略要的合适的人是据称是“技术专家”的李开复,但他在公众心目中的号召力和政府公关能力才是Google所看重的。 我们也可以循同样的视角来看待雅虎和阿里巴巴之间的联姻。这一次是把雅虎中国的业务交道马云手中去让他照料,因为对于谁了解中国市场和能够帮助雅虎发现中国市场潜力这个问题,马云是最佳答案。雅虎在中国的最近两次战略行动目标都首先是为了“人”。上一次是雅虎在中国收购3721,反而让其老板周鸿一担任中国区总裁,从而让雅虎中国从跨国公司在华分支机构这样的角色变成勇猛的中国本土企业。但在经历一段发展时期之后,雅虎中国就需要更合适的人。我们可以认为,这是雅虎、阿里巴巴联姻的主要原因之一。 先建立制度、体系,而不是“因人设事”这样的观点被广泛接受,可是,我们忘记了这个观念背后的工业化背景:所有人的都被当成了可替换的零件,所以制度体系最重要。但是,对于知识型工作来说,特别是非重复的创造性工作,每个人的工作方式、结果都截然不同。 我们所设计的制度体系,在当前的人员安排下也似乎运转正常。但是,由于这些人是无法替换的,人走了,看似精妙的体系也就出现出现问题了。这个时候,是去做不可能完成的任务:寻找适合制度体系的一摸一样的人?还是更改体系?或者看得更远点,在现在的情境下,我们根本就不该把制度体系的重要性神话到这种程度?针对知识型工作的讨论,和上文对最高管理者的讨论并非没有联系,因为在我看来,管理工作是最重要的、最具创造性的知识工作。 吉姆·柯林斯在《从优秀到卓越》说卓越公司是“先人后事”:这些公司的主管不是先确定目的地(先有方向、愿景、战略),然后才把人们引向那里;他们首先让合适的人上车(不合适的人自然请下车),然后才决定去向何处。他所说的虽是方向、远景,但大体上和制度是同一类型的事物。我们都应该了解,合适的人更重要,那些看似严密的战略分析和完善的制度体系有时候会变成令人难以忍受的障碍,因为它们和“合适的人”可能是完全矛盾的,这些人通常都难以放到一个既定的模子中去。
今天将webwork2.2.1更换成webwork2.2.2,出现了一个奇怪的异常,每次启动后,都会报出: org.xml.sax.SAXParseException: Element type "global-exception-mappings" must be declared. com.opensymphony.xwork.config.ConfigurationException: Caught exception while loading file xwork.xml with nested exception org.xml.sax.SAXParseException: Element type "global-exception-mappings" must be declared. 如果将xwork.xml中的 global-exception-mappings注释掉便好
头疼了几个小时解决不了,不得不求助飞云小侠 飞云小侠一出手果然不同,马上定位了问题所在 就是这句: <!DOCTYPE xwork PUBLIC "-//OpenSymphony Group//XWork 1.1.1//EN" "http://www.opensymphony.com/xwork/xwork-1.1.1.dtd">
原来虽然几次升级webwork.jar,但是xwork.xml的DTD解析还是用的原来的DTD,顶多就是改了DTD的地址,也就是将这句 "http://www.opensymphony.com/xwork/xwork-1.1.dtd">
改为这样 "http://www.opensymphony.com/xwork/xwork-1.1.1.dtd">
而实际上解析DTD是靠的前面那句 <!DOCTYPE xwork PUBLIC "-//OpenSymphony Group//XWork 1.1.1//EN" >
原来一直是 <!DOCTYPE xwork PUBLIC "-//OpenSymphony Group//XWork 1.0//EN" >
于是就出现了上面的问题 多谢飞云小侠的帮助^_^
自工作以来,我就养成了睡前读书的习惯,这一年在武汉,实在买不到一些好书,每次回北京总要带很多书过来,最近再次面临回京购书的局面,在回京之前总不能闲着,于是从去年看过的书中乱翻,以第一感觉来决定自己最想重读那本书,结果选中了温博格的《成为技术领导者-解决问题的有机方法》 两年前,当一位同窗好友集齐全套的温博格系列的时候,我曾很不屑的说他:一个人写那么多书,质量显然没保证,买他作甚?现在看来,当时确是井底之蛙了,温博格的书中少有瑕疵,尤其是后期作品,读来总是让人意犹未尽。 过去的几年里,我看过很多书,无论是早期GOF的设计模式,Martin Fowler的企业架构系列,还是Rod的J2EE开发厚厚的两卷本,甚至我最喜欢的POSA系列,虽然都会给人技术方面成长的感觉,但最好情况下也只是让我感觉到技艺的变化。 而管理方面的书籍,则大多走入两个极端,要么是学院式的分析解构,要么是江湖术士式的技巧集合。就像过去我曾很喜欢DEBORAH G. ANCONA的那本组织行为学和曾士强的中国式管理,但现在看来,DEBORAH关注组织多过于关注团队,而曾士强则过于强调中国人的心理情结,实用归实用,但可能不太适合技术人员的口味,读他的书让人感觉有些厚黑,让我常常想到一句俗语:人老精,鬼老灵。
而温博格的写作方式,如同Ken在英文版序中所说,会引起大量的思考,对温博格的文字的思考,思考对温博格文字的思考,以及对自身思考的思考....通过温博格的书,让我体会到的事是,读书,有时候是为了实用,而的有时候,则纯粹是为了过瘾。 本书中温博格的MOI模型,实际上不是一个行为指导手册,而是带来了更加宏观和可思考的空间,让你对自己在团队中的行为更加有目的性,也更加有效。我仍然记得两年前,上述同窗好友在某技术论坛发表的一篇名为《任务分解和任务分配》的帖子,现在看来,在该贴中提出的Effective Communication仍然太过于关注技术视角了,而现在,我则更加注重人文关怀,包括对技术架构。这一点,在本书第十章得到了精彩的阐述。
下面的内容,来自于本书第三章摘录
各种各样的想法是解决问题的核心,没有想法就不可能找到解决方案,但想法太多又会杂乱无章,领导者需要对想法的交流进行有效的管理。以下是领导者常用的12种典型的管理想法交流的方法以及点评。 > 为团队提供一个聪明的想法。尽管这是最显而易见的领导者行为,而且有时新的想法的确会起到关键性作用,但事实上真正全新的想法是非常罕见的。比发掘一个新的聪明想法更重要的是创建一个合适的环境,是能够解决问题的想法一旦提出就能被大家意识到。 > 鼓励和借鉴有用的旧想法。尽管有些领导者不愿意承认,但他们实际上是根深蒂固的模仿者。最优秀的领导者不仅承认这一点,而且将其视为一门艺术而精心培育。 > 认真完善团队成员提出的想法。大部分解决问题型领导者在完善一个想法上花费的时间比提出这个想法多上百倍的精力。 > 放弃自己的想法并支持团队采纳的想法,但只有当每个成员都充分了解你的想法时才予以放弃。放弃或保留你的想法是相当简单的,难的是要做到理智和公正。 > 尽管时间压力很大,仍然不要吝啬花时间听其他人解释他们的想法。迫于时间压力,大部分想法没有经过充分理解就被否决了,事实上,其中一些想法可以为我们节省的时间是花在了解错误想法上时间的上百倍。 > 检验别人提出的想法。在任何给定的环境中,绝大部分的想法都是没用的,但到底哪些才是有用的呢?领导者要做的就是分析和检验这些想法。 > 为了保持想法的交流,不要轻易否定团队成员的想法。尽管检验这些想法是非常重要的,但几乎没有什么想法会危险到使我们来不及重新考虑一下我们的第一反应,就必须立刻否定。 > 如果你不得不否定一个想法,那么一定要明确,你所否定的只是这个想法,而不是提出这个想法的人。解决问题型领导者一直清楚地知道,并不是所有的想法对每个问题都有帮助,但他们更知道,团队中的每一个成员都是有用的。 > 在给出你的想法之前要先对它进行检验。没有人可以聪明到提出所有建设性的想法,而一个喋喋不休地发表自己未经仔细考虑的想法的人却能有效地阻止其他人给出自己的想法。 > 当时间和人力吃紧时,不要再考虑新的想法而应该专注于现有的想法。 > 鼓励团队成员放弃以前曾经成功过,但并不适用于现在情况的想法。 > 如果一个已被否定的想法对问题的其他部分有价值,就应该重新采纳它。其实没有绝对不好的想法,之所以“不好”只是因为它们出现在不适当的地点或时间。
去年年底,osgi R4发布,eclipse建立equinox项目,标志着以osgi为核心的组件管理模型正式进入使用阶段,鉴于今年年初jsr291的推出,osgi正式走向java世界的前端,遂建立osgi观察者group,希望能同所有关心和喜爱osgi的国内技术人员共同进步。 加入osgi观察者:
最近的忙碌加上精神压力,让我患上了胃病,每天吃完饭都会难受好一阵子,给自己学医的儿时好友打电话,被劝之:“人生苦短,要学会善待自己每一天”。遂发此文为戒。
附一篇BJUG中Tin发的文章《白天纽约黑夜巴黎》 ------------------------------- 白天纽约黑夜巴黎 ------------------------------- 【王文华/文】
我在赶些什么?我耗尽青春用尽全力,拼命追求身外之物,结果我真的比别人有钱、有名吗?更重要的,我真的因此而快乐吗?远方有广阔的地平线,为何我还在原地摇过时的呼拉圈?
纽约和巴黎,代表了我人生的两个面向。纽约是白天,巴黎是黑夜。纽约是前半生,巴黎是下半场。
三十五岁之前,我认定纽约是世上最棒的城市。我在加州念研究所,毕业后迫不及待地去纽约工作。一做五年,快乐似神仙。我爱纽约的原因跟很多人一样:她是二十世纪以来世界文化的中心。丰富、方便。靠着地铁和出租车,你可以穿越时间,前后各跑数百年。人类最新和最旧、最好和最坏的东西,纽约都看得见。
所以在纽约时,我把握每分每秒去体会。白天,我在金融机构做事,一天十小时。晚上下了班,去NYU学电影,一坐四小时。在那二十多岁的年纪,忙碌是唯一有意义的生活方式。活着,就是要把自己榨干,把自己居住的城市,内外翻转过来。
这种想法并不是到纽约才有的。其实从小开始,台湾人就过着纽约生活。纽约生活,充满新教徒的打拚精神和资本主义的求胜意志。相信人要借着不断努力,克服万难、打败竞争。活着的目的,是更大、更多、更富裕、更有名。权力与财富,是纽约人的两个上帝。而能帮你走进天堂的鞋,就是事业、事业、事业。
在这种弱肉强食的生活方式,为了保持领先,每个人都在赶时间、抢资源。进了电梯,明明已经按了楼层的钮,那灯也亮了,偏偏还要再按几下,彷佛这样就可以快一点。出了公司,明明已经下班了,却还要不停讲手机,摇控每一个环节。在纽约,为达目的,可以不择手段,甚至赶尽杀绝。在纽约,没有坏人,只有失败者。
台湾,是不是也变成这样?
每一件事,都变成工作。上班当然是工作,下班后的应酬也是工作。有人谈恋爱是在工作,甚至到酒店喝酒、KTV狂欢,脸上都杀气腾腾,准备拚个你死我活。
我曾热烈拥抱这种生活,并着迷于这种因为烧烤成功而冒出的焦虑。这种焦虑让我坐在椅子边缘,以便迅速地跳起来闪躲明枪暗箭。这种警觉性让我练就了酒量和胆量、抗压性和厚脸皮。但也养成了偏执和倔强、优越感和势利眼。在纽约时我深信:能在这里活下来的,都是可敬的对手。黯然离开的,统统是输家。人生任何事,绝对要坚持到底。半途而废的,必定有隐疾。在这不睡的城市,每天我醒来,带着人定胜天的活力,跟着法兰克辛纳屈唱〈纽约?纽约〉:「如果你能在纽约成功,你可以在任何地方成功!」是的,在纽约,现代的罗马竞技场,我要和别人,以及自己,比出高低。
这套想法,在我三十五岁以后,慢慢改变。
第一件动摇我想法的,是父亲的过世。我父亲一生奉公守法、与人为善。毫无不良嗜好,身体健康地像城堡。七十二岁时,他得了癌症、引发中风,经历了所有的痛苦和羞辱。他一生辛勤工作、努力存钱、坚信现在的苦可以换得更好的明天。我们也相信一分耕耘、一分收获,用在纽约拚事业的精神照顾他。但两年的治疗兵败如山倒,最后他还是走了。父亲逝世的那天,我的价值系统崩溃了。我一路走来引以为傲的「纽约精神」,没想到这么脆弱。
不止在病床,也在职场。当我在企业越爬越高,才发现「资本主义」在职场中也未必灵验。上过班的都知道,很少公司真的是「开放市场」、「公平竞争」。大部分的同事都觉得你不是朋友、就是敌人。职场上伟大的,未必会成功。成功的,有时很渺小。很多人一辈子为公司鞠躬尽瘁,最后得到一支纪念笔。那些卷款潜逃的,反而变成传奇。
慢慢的,我体会到:世上有一种比「善有善报、恶有恶报」更高、更复杂的公平。人生有另一种比「功成名就」更幽微、更持久的乐趣。那是冲冲冲的美式资本主义,所无法解释的。
我能在哪里找到那种公平和乐趣呢?我想过西藏、不丹、非洲、纽西兰。然后,我注意到法国。
住纽约时,法国是嘲讽的对象。身为经济、科技、和军事强权的美国,谈起法国总是忍不住调侃一番。法国是没落的贵族,值得崇拜的人都已作古。法国人傲慢,高税率让每个人都很慵懒。动不动就罢工,连酒庄主人都要走上街头。
搬回台湾后,普罗旺斯、托斯卡尼突然流行。我看了弗朗西斯?梅思的《美丽的托斯卡尼》,其中一句话打动了我:「在加州,时间像呼拉圈。我扭个不停,却停在原地。在托斯卡尼,我可以在地中海的阳光下,提着一篮李子,逍遥地走一整天。」
是啊!我在赶些什么?我耗尽青春用尽全力,拚命追求身外之物,结果我真的比别人有钱、有名吗?更重要的,我真的因此而快乐吗?远方有广阔的地平线,为何我还在原地摇过时的呼拉圈?
当我重新学习法国,我发现法国和美国代表两种截然不同的生活方式。美国人追求人定胜天,凡事要逆流而上。法国人讲究和平共存,凡事顺势而为。纽约有很多一百层的摩天大楼,巴黎的房子都是三百年的古迹。纽约不断创新,巴黎永远有怀旧的气息。巴黎人在咖啡厅聊天,纽约人在咖啡厅用计算机。纽约有人潮,巴黎有味道。纽约有钞票,巴黎有蛋糕。
不论是政府或个人,法国人都把精神投注在食、衣、住、行等「身内之物」。就让美国去做老大哥吧。要征服太空、要打伊拉克、要调高利率、要发明新科技,都随他去。法国人甘愿偏安大西洋,抽烟、喝酒、看足球、搞时尚。当美国人忙出了胃溃疡,法国人又吃了一罐鹅肝酱。
讲到吃,法国有三百种起司、光是波尔多就有五十七个酒的产区。晚上六点朝咖啡厅门口一坐,一杯红酒就可以聊三个小时。九点再去吃晚餐,一直吃到隔天凌晨。他们在吃上所花的时间,跟我们上班时数一样。但讽刺的是:他们没有「All You Can Eat」。
吃很重要,但也要会挑时间,朋友介绍我去试一家法国餐厅,提醒我他们礼拜二、四晚上休息。「为什么?」我问。他说:「因为主厨要回家看足球。」
聪明的主厨懂法律。法国法律规定一周工作最多三十五小时,大部分的人一年有五周的假期。而美国人把加班当作自己有价值的表示,度假时还拿着手机回E-mail。法国人比美国人会玩。每年六月的巴黎音乐节,从午后到深夜,几百场露天音乐会在各处同时举行,人多到地铁都暂停收费。每年十月的「白夜」,平日入夜就打烊的店面,彻夜营业到清晨七点。每年夏天,巴黎市政府在塞纳-马恩省河右岸布置了三段、总长一.八公里的人工海滩。细砂、吊床、躺椅、棕榈树,自然海滩有的景致这里都有,让没有钱去海边度假的民众,也可以享受到海滩风光。
当然,法国这么深厚的文化,不可能只从吃喝玩乐而来。美国人读书,为了考证照。法国人读书,为了搞情调。每年十月的读书节,大城市的火车站内,民众轮流上台朗诵诗句。书店营业到天明,整晚有现场演奏的乐曲。「美食书展」选在铜臭味最重的证券交易所举办。小镇书展的书直接「长」在树上,读者必须爬到树上,把书摘下来品尝。
一直跟着美国走的台湾人,会心动吗?
我心动了。十一月我到巴黎,一位法国朋友来接待我。临走前我问他:「明天你要干嘛?」
「我要去银行。」
「然后呢?」我问。
「我不懂你的意思......」
对我来说,「去银行」是吃完午饭后跑去办的小事。对法国人来说,这是他一天全部的行程。法国人总是专心而缓慢的,每天把一件小事做好。
这样的生活,对美国或台湾人来说,实在是太颓废了。的确也是。法国失业率接近10%,高税率让雇主宁愿打烊休息,免得帮员工缴税。巴黎闹区纸醉金迷,但郊区的少数民族却没有工作机会。这些都是黑暗面,但对于每日被强光烤焦的台湾人,阴暗也许提供了喘息空间。生命的终点都一样,有钱人的丧礼只是比较多人上香。不断的追赶只是提前冲向谢幕,为什么不把时间花在慢慢为生命暖场?你不需要一辈子鞠躬尽瘁、死而后已。你可以偶尔伸伸懒腰、安步当车。
我从巴黎回来,台北并没有改变。关了两周的手机再度响起,一通电话找不到我的人会连续狂call十通。和朋友见面,他很关心地问我:「好了,你现在工作也辞了、欧洲也去了,接下来有什么projects?」
「Projects」?多么纽约的字眼。
我真想说:「好好生活,不就是人生最大的project?」但我知道在熙来攘往的台北街头,在不到四十岁的年纪,这样说太矫情了。况且,我今天之所以有钱有闲享受法式生活,不也正因为我曾在美式生活中得到很多利益?我仍热爱工作、热爱纽约,但已不用像二十岁时一样亦步亦趋、寸步不离。
所以我说:「我还是会早起,白天努力写作。但到了晚上,我想关掉手机。」
世界少了我,其实无所谓。但我少了我,还剩什么?
他笑一笑:「你这是用纽约来过白天,用巴黎来过黑夜。」
唉,他讲得真好!这应该是一个完美的妥协吧。也许有一天,我能创造自己的「白夜」,让白天和黑夜融合在一起。但我还没到那个境界。
「明天星期一,你要干嘛?」他问。
「我要去银行。」
「然后呢?」
我张大眼睛,停顿了一下。
「然后呢?」他追问。
「然后我会摩拳擦掌,认真地写一篇文章。」
我们是不是也应该学一学法国人呢?提高些生活质量,注意身体。
很久没更新blog了,实在太忙,今天看到有朋友在我去年的blog《 MINA is a good framwork 》中回复提到比较一下MNA和QuickServer,遂写一篇小文: First for all, QuickServer is licensed as LGPL, and MINA as ASL 从我个人角度而言,去年看过QuickServer的源码,我在项目中采用的每一个框架或类库都会做综合评价,通常不会是一个原因导致我采用或没有采用某个库或框架,具体最后没有采用QuickServer的原因忘记了,但是当时给我的总体感觉是,QuickServer虽然很方便,但不会让我在架构上得到新的好处。而它最大的优点则是,支持JDK1.3(如果没记错的话),另外就是License的问题 下面看一看来自TrusinLee的评论: Thank for the information about another network application framework. I found a few differences: * QuickServer supports blocking mode. (MINA supports only non-blocking mode, but you can make your operation block at your will.) * QuickServer provides GUI-based admin. (MINA doesn't have one yet, but will have full JMX support soon, which is a standard.) * QuickServer uses java.util.logging. (MINA uses SLF4J, which is a safe replacement of commons-logging.) * QuickServer uses its own XML settings. (MINA provides Spring framework integration instead.) * QuickServer can specify maximum number of clients allowed. (MINA can do this using a filter, but not implemented by default. Of course, this will be implemented as an overload prevention filter.) * QuickServer team has one crew. (MINA has three crews.) * QuickServer project started in 2003. (MINA started in 2005.) * QuickServer has a difference event handler interface from MINA. (You'll have to compare it by yourself. IMHO, MINA has one simple enough handler which covers all QuickServer provides.) * QuickServer doesn't support UDP at all. (MINA does) * QuickServer doesn't support client-side API at all. (MINA does) * QuickServer integrated authentication and text protocol in its core. (MINA didn't and they are considered as a cross-cutting concern that a filter should take care of. IMHO, MINA is more extensible here.) 至于对MINA更详细的介绍,可以看看我去年翻译的MINA的Tutorial
MinaTutorialInChinese
MINA的应用,在MINA的Testimonials中有两个项目: 开源Flash server:red5 http://ludonet.leonardo.it/的game server 还有,就是MINA所在的项目,Apache的LDAP
摘要: Eclipse3.1刚刚release的时候,它的RCP发布功能就很吸引我,当时正好有个小东西要做,就用了这个功能发布了一个小程序,似乎很多人推荐用NSIS,但是我觉得Eclipse的这个功能似乎更方便,几乎不用担心任何部署的问题。
阅读全文
Blog有一个多月没有更新了,今年8个月的忙碌生活,以及最后两个月的突击使我彻底失去了热情,无论是工作还是写blog,目前只想每天休息休息,看看书。 12月底回了一趟北京,然后又顺路回大连家中办了点事情,待了三天,又飞回武汉着手招人和培训的工作,为明年的工作做准备,技术上有些事情还得自己动手,不知道这忙碌的生活什么时候可以停歇.....
在妖精群里还跟非鱼说要写一篇关于架构师职责的Blog,暂时还是没心情写,不过自从那次在群里讨论过架构师的职责之后,似乎已经有很多人写了这方面的文章,在blogjava中就有很多了,架构师之家的文章数目也一下激增起来。
近期blogjava也是好戏连台,虽然不写,看着也是过足瘾了。
canonical是个很好的写手,学理论物理出身的思维缜密果然不同凡响,关于架构师的职责那篇,已经把能写的都写尽了。江南白衣 搞的springside.org.cn看起来也很吸引人,有理想的好青年的典范。非鱼的几篇关于架构的文章也写的很扎实,预备役架构师是有些谦虚了,呵呵。Jerry在经过一段时间的忙碌之后,似乎又再次复活了,以每天一到两篇的速度持续更新blog,让我着实佩服他的精力,几篇blog的涉猎范围so广,足见积累之深。老庄最近似乎也是琐事缠身,除了在上月底被Rx反敲丧钟的时候露了几次脸,就没怎么出现过,看来年底了哪里都是忙碌的时候。Raimundox近期多次出手,除了对老庄的《丧钟》系列的再次释疑之外,还为我们贡献了Smalltalk的入门手册,实为近期技术blog中风头最劲的一个了。飞云小侠也更新渐少了,除了今天预告了WebWork2.2的发布,已经10天没更新了。近期weide的技术架构评估也是颇为扎眼,算是近期最全面完整的一篇技术文章了,显然是花了精力了,难怪达到14709的访问量 :)
2005年让我感觉到人的精力毕竟有限,以及,一个纯技术人员能发挥的能量实在太小了,虽然不情愿,但这可能促使我更早的脱离纯技术岗位,真是凌乱的一年......
开发一个基于消息的解决方案是不容易的事情,在生产中操作这样一个产品同样也是一个挑战:一个基于消息的集成解决方案一天可以产生、路由和转换成千上万的消息。我们不得不处理异常、效率瓶颈或改变合作系统。而为了使事情变得更加有挑战性,组件经常被分布在不同的平台和机器上,甚至位于不同的地理位置。
System Management包含以下几种模式
l Control Bus
l Detour
l Wire Tap
l Message History
l Message Store
l Smart Proxy
l Test Message
l Channel Purger
除了与生据来的复杂性、分布式集成的规模以及个性化的应用之外,低耦合的架构使得测试和debug变得更加困难。Martin Fowler将这个症状称为“架构师的梦想,开发者的梦魇”。低耦合的架构原则以及间接的依赖于外部系统提供了灵活性。然而,测试一个消息生产者不了解消息消费者的系统可能会是一个挑战。另外异步的和时间相关的消息使得事情变的更加复杂。举例来说,消息方案可能被设计没有被成消息生产者者必须从接受者那里得到一个回应。同样的消息基础设施通常保证传输消息,但不能保证传输时间。这是的开发基于消息传送结果的测试用例变得困难。
当监控一个消息解决方案,我们可以在两个抽象层面上跟踪消息流。一个典型的系统管理方案监控多少消息被发送或者它多长时间得到一个被处理的消息。这些监控方案不检查消息数据,除了可能会检查消息头中的几个字段(比如消息标识或者消息历史)。与之相对的,BAM(business activity monitoring)方案聚焦于包含在消息中的有效数据,举例来说,发生在过去一小时的所有订单的金额。System Management中的很多模式都足够通用并可以用在以上两个目的中(监控消息头或者消息内容)。然而,由于BAM本身就是一个新领域,并且需要从数据仓库中获得很多数据(有些我们根本就没有涉及到),我们决定在系统管理的内容中讨论这些模式。
系统管理模式被设计用于为保持一个基于消息的复杂系统的运转所提出的需求并提供工具。System Management的模式涉及三个种类:监控和控制,观察和分析消息流量,测试和调试。
监控和控制
一个Control Bus提供一个单独的控制点来对一个分布式方案进行监控和管理。它将多个组件连接到一个中心管理控制台,这里可以显示每个组件的状态并且监控通过每个组件的消息流量。控制台同时也可以用于发送控制命令给组件,比如,转变消息流。
我们可能想要在路由消息时添加附加的步骤,比如验证或者日志。由于这些步骤可能使效率降低,所以我们可以通过Control Bus来控制他们开关。一个Detour为我们提供这种能力。
观察和分析消息流量
有时我们想要在不影响主要消息流的情况下观察消息的内容。一个Wire Tap允许我们接入到消息流中。
当我们调试一个基于消息的系统,知道一个特定的消息在哪使很有帮助的。Message History保留一个消息访问过的所有组件的日志,而不需要增加组件间的依赖。
然而Message History依赖于单独的消息,一个中心的Message Store可以提供一个穿越系统的每个消息的完整记录。结合Message History,Message Store可以分析所有消息穿过系统的可能路径。
Wire Tap, Message History, 和Message Store帮助我们分析异步的消息流。为了跟踪发送到请求-应答service的消息,我们需要在消息流中插入一个Smart Proxy。
测试和调试
在部署前测试一个消息系统是一个非常好的注意。但是测试不应该停止在部署前。你应该有能力验证正在运行的消息系统运行持续的运行正常。你可以周期性的发送一个Test Message到系统中并验证结果。
当一个组件失败或者运行不正常,它可以简单的终止,并放弃一个channel中的剩余消息。在测试期间这是很有用的。一个Channel Purger可以为我们做这些。
最近身体不太好,转贴一则文章,提醒自己多多休息和锻炼。 ------------------------
只要踏入在我们IT这个行业, 过不了几年身体就是亚健康状态,过渡的话就可能会“过劳死”,要想防止“过劳死”,就必须了解身体为我们发出的“过劳死”信号。
研究者认为:在这27项症状和因素中占有7项以上,即是有过度疲劳危险者,占10项以上就可能在任何时候发生“过劳死”。同时,在第1项到第9项中占两项以上或者在第10项到18项中占3项以上者也要特别注意,这27项症状和因素分别是:
1.经常感到疲倦,忘性大;
2.酒量突然下降,即使饮酒也不感到有滋味;
3.突然觉得有衰老感;
4.肩部和颈部发木发僵;
5.因为疲劳和苦闷失眠;
6.有一点小事也烦躁和生气;
7.经常头痛和胸闷;
8.发生高血压、糖尿病,心电图测试结果不正常;
9.体重突然变化大,出现“将军肚”;
10.几乎每天晚上聚餐饮酒;
11.一天喝5杯以上咖啡;
12.经常不吃早饭或吃饭时间不固定;
13.喜欢吃油炸食品;
14.一天吸烟30支以上;
15.晚上10时也不回家或者12时以后回家占一半以上;
16.上下班单程占2小时以上;
17.最近几年运动也不流汗;
18.自我感觉身体良好而不看病;
19.一天工作10小时以上;
20.星期天也上班;
21.经常出差,每周只在家住两三天;
22.夜班多,工作时间不规则;
23.最近有工作调动或工作变化;
24.升职或者工作量增多;
25.最近以来加班时间突然增加;
26.人际关系突然变坏;
27.最近工作失误或者发生不和。
针对如何摆脱过度疲劳,何永成博士开出如下处方:
消除脑力疲劳法:适当参加体育锻炼和文娱活动,积极休息。如果是心理疲劳,千万不要滥用镇静剂、安眠药等,应找出引起感情忧郁的原因,并求得解脱。病理性疲劳,应及时找医生检查和治疗。
饮食补充法:注意饮食营养的搭配。多吃含蛋白质、脂肪和丰富的B族维生素食物,如豆腐、牛奶、鱼肉类,多吃水果、蔬菜,适量饮水。
休息恢复法:每天都要留出一定的休息时间。听音乐、绘画、散步等有助解除生理疲劳。
科学健身方法:一是有氧运动,如跑步、打球、打拳、骑车、爬山等;二是腹式呼吸,全身放松后深呼吸,鼓足腹部,憋一会儿再慢慢呼出;三是做保健操;四是点穴按摩。
哥们, 上面27条在你身上出现几条症状了? 怕怕吧?
建议哥们们每天早上和傍晚各抽出一小时锻炼身体,毕竟身体是革命的本钱!
转自: 电子商务论坛 http://bbs.eczn.com/
上面下划线的是我有的问题,你都有哪些?
经过这半年的使用,WTP在我们组内已经从只用于开发Web Service的工具变成web开发的首选插件 虽然只是0.7版,但WTP的设计确实很好,目前WTP1.0已经release到了M9,还有20几天就到达release date了,热烈期待中....
在ESB中另外一个重要的课题就是Message Endpoint,这是关于一个应用程序如何连接到一个消息系统,并通过它来发送和接收消息。如果你在面向一个消息API编程,则你就正在开发一个endpoint代码。商业中间件通常都提供了这些工具。
l Messaging Gateway
l Messaging Mapper
l Transactional Client
l Polling Consumer
l Event-Driven Consumer
l Competing Consumers
l Message Dispatcher
l Selective Consumer
l Durable Subscriber
l Idempotent Receiver
l Service Activator
发送和接收模式
有些endpoint模式既可以使用在发送方也可以使用在接受方。它们描述一个应用连接一个消息系统的一般情况。
包装消息代码 - 一个应用不应该意识到正在使用消息同另外一个应用程序通讯,大多数应用代码应该在不知道message的情况下被编写。在应用集成的地方,应该有一个薄薄的一层代码来执行应用的集成部分。当集成是由消息实现的,这层将应用连接到消息系统的代码称为一个Message Gateway
数据转换 - 当发送者和接受者使用不同的数据格式,或者不同的消息格式(支持不同的发送和接收者),在这种情况下,使用一个Message Mapper来在应用格式和消息格式之间转换数据。
外部控制的事务 - 消息系统在内部和外部使用事务,默认的,每个发送和接收方法在他们自己的事务中运行。Message生产者和消费者应可选的使用一个Transactional Client来控制事务,当你需要将几个消息一起发送伙通过其他事务服务整理消息时是很有用的。
消息消费者模式
其他endpoint模式只适用于消息消费者,发送消息是简单的。棘手的问题是决定一个消息应该何时发送,它应包含什么,以及怎样将它送到接受者 - 这是为什么我们有很多消息结构模式 - 但是一旦消息被构建,发送它是很容易的。另一方面,接收消息 - 很麻烦。因此许多endpoint模式是关于接收消息的。
接收消息的一个最重要的主题就是流量控制:一个应用控制,或者调节它消费消息的速度。一个潜在的问题是任何server都面临着大量的客户端请求会使其超载。通过远程过程调用(RPI),server几乎受到客户端调用的支配。同样的,通过消息,server不能控制客户端发送请求的速度 - 但是server可是控制它处理这些请求的速度。应用不必像消息系统传送消息那么快的接收并处理消息;使用一个Message Channel可以使它在一个可接收的速率上处理消息。然而,当消息积累太多,而server还有资源可以处理的更快,它可以使用同步message消费者来加快速度。所以使用这些消息消费者模式可以让你的应用将速度控制在它可以承受的范围。
许多消息消费者模式都是成对出现的,你可以任选一个使用。
同步或异步接受者 - 可以使用轮询消费者或一个事件驱动消费者。轮询提供最好的流量控制,因为如果server忙,则它不再继续轮询消息,所以message将阻塞在队列。事件驱动的消费者倾向于消息到达便触发处理,所以有可能会使server超载,但是每个消费者每次只处理一个消息,所以限制消费者的数量可以有效的控制消费速度。
消息分派 vs 消息获取 - 另外一个二选一的模式是一堆消费者如何处理一堆消息。如果每个消费者获得一个消息,他们可以并行的处理消息。最简单的方法是Competing Consumers,也就是一个点对点的channel有多个消费者。每个都可能获得任何消息;消息系统的实现决定那个消费者获得消息。如果你想控制消息到消费者的匹配过程,使用Message Dispatcher。这时只有一个消费者接收消息,但是将委派消息到一个执行者去处理。一个应用程序可以通过限制消费者或执行者的数量来控制流量。当然,分派者Message Dispatcher也可以实现一个流量控制行为。
接收所有消息或者过滤 - 默认的,任何到达一个Message Channel的消息对于监听着这个channel的Message Endpoint都是可用的。然而有些消费者并不打算处理channel上的任何消息,而是希望只处理其中几种。这样一个识别的消费者可以使用一个Selective Consumer来描述它将接收什么类型的消息。然后消息系统将只将匹配的消息对该接受者描述为可用。
当断开连接的时候订阅消息 - Publish-Subscribe Channels带来的问题是,如果一个消费者感兴趣一个channel,但是现在网络是断开的怎么办?是不是一个未连接的应用将错过发布的消息,即使它已经订阅过该消息?默认的,是的,订阅只对连接的订阅者有效,为了使应用不会因为连接而错过订阅的消息,要使用Durable Subscriber。
等幂 - 有时一个消息可能被传输不只一次,可能因为消息系统不确定该消息是否已经被成功的传递过,或者可能因为Message Channel的QoS被设置较低来提高效率。另一面的,消息接受者认为每个消息只会被传输一次,并且当它们重复处理相同的消息,它们会出错。一个Idempotent Receiver可以优雅的处理重复的消息,并且阻止它们引起接收者应用的发生错误。
同步或异步服务 - 另外一个选择是一个应用应该暴露它的service为同步(RPI)还是异步的(Messaging)。不同的客户端可能喜欢不同的方式;不同的环境可能需要不同的方式。既然很难选择,就一起使用。一个Service Activator连接一个Message Channel到一个应用的同步服务以便当一个消息被接收,service就被调用。同步客户端可以简单的直接调用service;异步客户端可以通过发送消息调用service。
Message Endpoint的相关主题
Message Endpoint的另外一个重要主题是很难同其他模式共同应用Transactional Client。Event-Driven Consumer通常不能适当的在外部控制事务,Message Dispatcher也必须小心的设计这个问题,Competing Consumers的事务也是个重大问题。最安全的使用Transactional Client是使用一个单独的Polling Consumer,但是这不会是一个令人满意的解决方案。
这里特别要提到应该会保证成功的JMS风格的MDB,EJB的一种。一个MDB是一个消息消费者,它即使一个Event-Driven Consumer又是一个支持J2EE分布式事务的Transactional Client,并且它可以作为Competing Consumers动态的池化,甚至作为一个Publish-Subscribe Channel。这是在一个自由的应用中实现这些是一个困难且乏味的组合,但是这个功能作为一个EJB容器的内建的功能被提供。(MDB框架如何实现的?本质上,容器通过一个动态改变大小的可重用的执行者的线程池来实现了一个Message Dispatcher,在那里每个执行者自己使用自己的session和事务来消费消息。)
最后,紧记一个单独的Message Endpoint可以很好结合几个不同的模式。一组Competing Consumers可以被作为Polling Consumers实现,同时也可以是一个Selective Consumers并且可以作为一个Service Activator调用一个应用的service。
一个Message Dispatcher可以是一个Event-Driven Consumer和一个使用Messaging Mapper的一个Durable Subscriber。无论一个endpoint实现什么模式,它总是一个Messaging Gateway。所以,不要考虑使用哪种模式 - 而要考虑如何结合他们。这是使用模式解决问题的魅力所在。
要实现一个Message Endpoint有很多选择。Message Endpoint模式用于解释这些选择是什么以及如何最好的使用它们。
通常,通过消息系统集成的应用很少有同样的消息格式。比如说,一个帐务系统同一个CRM系统对客户对象是有着不同的概念的。基于这个,一个系统可能将消息存储在关系表中,另一个可能存储在文件中。集成已存在的系统通常意味着我们没有修改系统以便使他们更好的一起工作的自由。然而,集成方案不得不协调和解决各种系统之间的不同。Message Translator模式提供了一个通用的解决方案。这里解释几种特定的Message Translator。
Message Transformation包含以下几种模式:
l Envelope Wrapper
l Content Enricher
l Content Filter
l Claim Check
l Normalizer
l Canonical Data Model
大多数消息系统放置特定的需求在消息头的格式和内容中。我们包装有效数据到一个Envelope Wrapper中以适应消息基础设施的需求。如果消息需要穿过不同的消息基础设施,可以结合多个Envelope Wrapper。
如果原始系统不能提供目标系统需要的数据域,可以使用一个Content Enricher。它可以查找缺少的信息并从已有数据中计算出它。Content Filter正好相反,它从消息中删除不需要的数据。Claim Check也从消息中删除数据,但是它将存储他们以便以后取回。Normalizer将多个不同格式的消息翻译成统一格式。
消除依赖
消息转换在集成中是一个很深的话题。Message Channels和Message Routers可以通过消除应用必须知道另外一个应用的位置的需求从而解除应用间的基本依赖。
一个应用可以发送一个消息到Message Channel而不必担心谁来取出消息。然而消息格式增加了另外一种依赖。如果一个应用不得不将消息格式化成另外一个应用的数据格式,通过Message Channel解耦的说法就像一个幻想。接收系统的任何改变或切换到另外一个接收系统都需要对发送应用进行改变。Message Translators可以帮助除去这种依赖。
元数据管理
将消息从一个消息格式转换到另一个格式需要操作元数据 - 描述数据格式的数据。
元数据在两个并行系统之间的集成中扮演着非常重要的角色。一个处理实际的消息数据,另外一个处理元数据。许多用于处理消息数据的模式也同样可以管理元数据。比如说,Channel Adapter不仅可以从一个系统中移进和移出消息,还可以从一个外部应用中获取元数据,并将其加载到一个元数据仓库中。使用这个仓库,集成开发者可以定义应用元数据与Canonical Data Model.之间的转换。
元数据集成
举例来说,上面的图描述了两个需要交换客户信息的应用的集成。每个系统的客户数据的定义稍有不同。从A到B的消息需要转换一下才能被B接收。如果Channel Adapters可以抽取元数据的话,创建一个转换将非常简单。然后这个元数据可以被放入一个仓库,大大的简化了Message Translator的配置和验证。元数据可以被存储成不同的格式。通常XML消息使用XSD格式。其他EAI工具实现所有元数据格式,但是允许管理员导入或导出到其他格式。
消息系统外的数据转换
这些转换模式组成的很多原则可以被应用于非消息集成。比如说,File Transfer可以执行系统间的转换工作。类似的,Remote Procedure Invocation必须使请求使用要调用的service的格式,即使应用本身的格式可能不同。典型的,需要调用程序来执行转换。一些最成熟的转换引擎组成了ETL工具,比如Informatica或者DataMirror。这些工具一般都一次转换大量的数据,而不是转换单个消息。
Message System应专注于几种基本的Message Translator模式。而不应该关心实体间结构转换的细节(不同的数据模型之间的转换,比如ER模型不支持多对多关系而其他的支持这种)。关于这个主题最老也使最相关的书是Kent的《Data and Reality》。
在前面的关键组件中我们提到了Messages。当两个应用想要交换数据,他们将数据包装在一个message中。但是一个Message Channel不能传输原始数据,它只能传输包含在一个message中的数据(即传输特定格式的数据)。
Message在消息系统中处于信息载体的位置,而在ESB中,还消息识别、序列以及生存周期等职责。
Message的结构涉及以下几个模式:
l Command Message
l Document Message
l Event Message
l Request-Reply
l Return Address
l Correlation Identifier
l Message Sequence
l Message Expiration
l Format Indicator
创建和发送一个Message产生以下几个问题:
消息意图 - Message最终是为了运送一些数据,但是发送者可能有其他目的,比如它希望接受者使用消息做些事情。它可以发送一个Command Message,指定它希望调用的接受者上的函数或方法。发送者告诉接受者运行那些代码。发送者可以发送一个Document Message来传送它的数据结构到接受者。发送者发送数据到接受者,但是不指定接受者应该做什么。
或者它可以发送一个Event Message,通知接受者发送者那里有一个改变。发送者不应告诉接受者应该怎样适应这个改变,而只应提供通知。
返回一个应答 - 当一个应用发送一个消息,它通常期望得到一个回应来确定消息被处理并提供一个结果。这是一个Request-Reply场景。Request通常是一个Command Message,而应答是一个包含返回值或异常的Document Message。请求者应该在请求中指定一个Return Address来告诉应答者使用哪个通道来传回应答。请求者可能在一个处理过程中发送多个请求,所以应答应该包含一个Correlation Identifier来指出这个应答对应哪个请求。
有两个Request-Reply场景需要注意;它们都包含了一个Command Message请求和一个对应的Document Message应答。在第一个场景中,Message RPC,请求不但要调用应答者的函数,而且期望一个返回值。这是RPC。另一个场景中,Message Query,请求者执行一个查询;应答者执行查询并在应答中返回结果。这是远程查询。
大量的数据 - 有时应用想要传送大量的数据结构,放入一个单独的message里面不是很合适。在这种情况下,将他们分解成可管理的消息块并将他们作为Message Sequence发送。这些消息必须按顺序发送,以便接受者能够充足原始数据结构。
慢速消息 - 消息系统的一个问题是发送者通常不知道接受者要多久才能接受到消息。然而,消息的内容可能是时间敏感的,所以如果消息在某一时间内没有被接受,它将被忽略并取消。在这种情况下,sender应该使用Message Expiration来指定一个到期时间。如果消息系统在规定时间内无法传输一个消息,应该将它取消并删除到Dead Letter Channel中。同样的一个receiver接受到一个超出该时间点的消息,也要取消该消息。
总之,只选择使用消息是不够的。使一个消息工作的其他决定性因素来自于消息所要完成的任务。
|