今天早上法国的实习PM气冲冲地跑过来,指着我鼻子就问“你有什么权利发昨天晚上的那封信?”。
事实上在他来之前我就知道要糟。事情是这样的,我们在马尼拉(菲律宾首都)有个地铁项目,明天我就要去Onsite了,这是最后一次Onsite,任务是升级新版本软件,并且解决一切问题,如果顺利的话,这个项目就可以结束了。
这个项目上到法国的项目经理,RIS(类似于系统架构师的职位),下到我们这边的项目经理,开发人员,测试人员,只有我有过5次Onsite经验。也就是说我是最熟悉这个项目的。因此以前的项目经理给了我一些小小的权利,可以直接和马尼拉那边的工程师联络,讨论一些任务安排之类的事情,也可以通过他先非正式的和客户谈谈,看看客户的想法。我承认这个做法比较随意,但是带来的效果却很好,就像XP中提倡的开发人员和用户直接面对面一样。因此我一直这样做,并没有受到什么指责。
而昨天,这位实习PM发给我一个Schedule,告诉我明天到菲律宾后每天干什么,非常简单的一个计划,一共就7行字。但是他并没有通知其他人,因此我就“自作主张”地把这个计划发给了马尼拉的工程师,由于他是直接和我工作的人,因此我需要和他讨论详细的计划,比如哪个小时做什么事情,遇到情况怎么恢复等等。因此我在原Schedule上面增加了非常详细的步骤,甚至详细到一个report有多少大,需要多少U盘才能放得下的地步。其中最重要的一点,也就是我和这位实习PM计划中有所不同的一点是,在升级过程中,我会帮助客户每天都拿到报表;而他的计划中是把报表一直存放在车站计算机上面直到3天后才能让客户看到。但这一点我没有理解清楚,他的计划中也没有提到这一点。我一直以为我上次告诉他,我们的客户要求每天都能看到报表之后他已经同意我的方案。现在看来他根本没有考虑我的提议,也没有把这件事情告诉法国那边的PM和RIS。而最糟糕的是,直到今天,我们的客户对我什么时候去,我们怎么升级系统还根本一无所知。基于这几点,我提议马尼拉的工程师将此计划非正式的给客户看一下,看看他们的意见。
结果这份信不知道怎么就转到了法国PM手里,又转到了RIS的手里,他们很明显认为我挑战了他们的权威,因此回信把我的计划驳回,同时CC给了这位PM和我们的CTO(两个都是法国人)。
于是就发生了早上的那一幕。这位实习PM怒气冲冲地对我吼:“我才是这个项目的负责人,你不是!” 这句话把我气得不行,至今为止,和我合作过得PM各个都是和和气气的有事大家一起商量。从来没有指着对方鼻子吼的。就算以前在法国,那里的PM再怎么喜欢阴人,表面上还是很和气的。
然后我木然地看着他,他还不过瘾,又加了几句,“你只是一个工程师,你没有权力直接和客户联络,你只要照着我说的做就可以了,在计划的安排上,你没有任何自由!联络客户是我的指责,不用你来代劳!”。
我没有反驳他,但我还是问了一下他是否已经把这个计划交给客户评审,同时如果他们要每天都看到Report怎么办。他随口回答了我一句:“我会和法国的PM讨论。”
我知道整件事我的确错了,我的确逾越了我的权限。因为他没有给我这个权限。另外一个错误就是和这位实习PM沟通太少,毕竟刚刚开始合作,双方的摩擦是少不了的。同时也显示出我太年轻,对这种事情的处理还不够老练。
但我觉得我是下意识地不想和这个人沟通,因为他除了有事找我,平时走过路过连正眼都不会看我一眼。我有几次主动和他打招呼,他睬都不睬我。这位实习PM显然是一个对级别,职位看得很重的人。我显然和他的职位相差太多。对付这种人,我想老祖宗的“韬光养晦”是一个不错的办法。
在写这篇文章之前,我心里还有气,因此我觉得到了Site上,绝对不主动做任何不在我范围内的事情。如果客户不知道计划,我就不开工。
但现在我的想法又变了,我没必要因为这件小小的事情改变自己,我坚信我自己没有做错,我会积极的和这位PM沟通,把这最后一次Onsite做好。这才是双赢的局面。这也是我在这个公司第一个能够Close的项目,我不希望在我手里搞砸。
2007年6月19日星期二
对不起,我逾越了
发帖者
凌浩
时间:
6/19/2007 12:22:00 下午
0
评论
标签: 杂七杂八
2007年5月25日星期五
Java RMI 极速攻略
回家作业上要用到RMI,这两天抽了点时间学习了一下,感觉上手还算简单,但有些设置之类的时间长了怕记不住,因此花点时间写了这个入门攻略。
---------------------------------
RMI简介
RMI就是Remote Method Invocation,类似与RPC。 它的原理同CORBA, DCOM,.net remoting相似,但是比他们要简单很多。详细的介绍可以看参考资料部分的[SUN公司的RMI教程]http://java.sun.com/developer/onlineTraining/rmi/RMI.html
实做
下面分几步来完成一个简单例子----login(这个功能用的快烂了)
想法是,server端程序提供接口方法login,接收两个参数,用户名和密码,为了简单起见,我们直接返回true。在client端调用server端的方法,看看是否能够顺利返回true。
该程序没有任何意义,仅仅用于演示RMI的开发过程。
1. 定义远程接口
远程接口如下:(ICustomer.java)
import java.rmi.Remote;
import java.rmi.RemoteException;
//
// This is remote interface for Customer
public interface ICustomer extends Remote{
public boolean login(String username, String password)
throws RemoteException;
}
2. 实现远程接口
实现文件是真正的业务逻辑所在。和RMI基本上没有任何关系。
要注意的是
- 类要继承java.rmi.UnicastRemoteObject 并且实现刚才定义的接口。
- 每个方法都要抛RemoteException
- 要有显示的构造函数
实现文件如下: (ICustomerImpl.java)
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.server.UnicastRemoteObject;
public class ICustomerImpl extends UnicastRemoteObject
implements ICustomer{
public ICustomerImpl() throws RemoteException{
}
public boolean login(String username, String password )
throws RemoteException{
return true;
}
}
3. 服务器端启动程序
服务器端启动程序做两件事
- 加载服务器端对象到JVM中
- 将该对象注册到RMI Registry
在这个例子里面,我使用的是一般的控制台程序,据说可以用Tomcat代替,我想这个应该是可行的。毕竟,只要有个JVM能够加载对象,就能把对象注册到RMI Registry里面去。
代码如下(Server.java):
import java.rmi.Naming;
public class Server.java{
public static void main(String[] arg){
try{
ICustomerImpl cu = new ICustomerImpl();
//创建服务器端对象
Naming.rebind("cust", cu);
//注册
}catch(Exception e){
System.err.println("launcher error");
e.printStackTrace();
}
}
}
4. 编译服务器端程序
先假设所有的代码都放在d:\rmitest\下面
先到该目录下,编译所有的代码
javac Server.java
接下来,肉戏来了,需要用rmic来编译实现文件产生存根(stub),如果对这个词不是很了解,请参考一些跨进程访问的资料,一般的解决方案都是用存根/代理实现。
rmic -keep ICustomerImpl
在 运行rmic之前一定要用javac编过,rmic是找编译好的类的,不是找源程序的。rmic的工作原理是,首先反编译 ICustomerImpl.class,加入rmi架构需要的代码,然后把这个中间过程产生的Java文件编译成 ICustomerImpl_stub.class
-keep 就是让它保留中间产生的java文件。
这样基本上服务器端的事情都做完了。
客户端做这几件事情:
- 查找服务器端接口,要指定ip地址,端口号,接口注册名
- 然后可以是用接口的方法
import java.rmi.Naming;
import java.rmi.RemoteException;
public class Client{
public static void main(String[] args){
try{
ICustomer p =
(ICustomer)Naming.lookup("rmi://localhost/cust");
System.out.println(p.login("linghao","1234"));
}catch(RemoteException re){
System.out.println(re);
}catch(Exception e){
System.out.println(e);
}
}
}
客户端实际上是通过stub类来和服务器端通讯的,因此,运行的时候需要把接口文件,stub文件和客户文件放一块儿。
6. 安全策略
跨进程,跨机器访问一个不能避免的问题就是权限问题。
RMI中,是用java的访问权限管理 有两种方法来设置权限
1. 建立一个新文件test.policy,放在和server端代码一起,文件内容为
grant codeBase "file:/d:/rmitest/"
{
permission java.security.AllPermission;
};
或者在命令行中运行policytool,选"添加规则项目",在后面出来的那个对话框中,codebase填 file:/d:/rmitest/ ,然后选择"添加权限",许可中设置"All Permission".然后一路ok返回。然后选文件->另存为,取名字为test.policy放到server端程序的同一目录。
7. server端启动
首先要启动RMI注册器,这时候会出现一个空白的dos窗口,不要关掉它,否则注册服务器就没有了。
start rmiregistry
其次启动服务器端程序
java -Djava.rmi.server.codebase=file:/d:/rmitest/
-Djava.security.policy=test.policy Server
如果出现access permission exception的话,说明可能权限文件没设好,打开来看看。
注意,服务器端的两个程序都是不会返回的,每次你都要开个新窗口
8. Client端启动
注意ICustomer,ICustomerImpl_Stub.class 和 Client.class要放在一起
java Client运行后,如果一步一步照着做的话,应该能看到返回值为true;
9. 小结
本文是对RMI开发的一个极其简单,极其粗浅的介绍。很多系统的知识都没有写出来,目的就为了大家刚接触的时候上手快一些。
很多介绍也是某一种可选的方案(为了快速学习而选择的方案)罢了,专业的代码需要考虑更多的内容,比如下面列出的一些就需要考虑:
- 服务器端程序不一定要继承java.rmi.UnicastRemoteObject, 实现更灵活
- 端口号如果不写就是用默认的1099,但是也可以自己指定
- 服务器端的安全设置
- 远程调用的开销很大,是否要考虑一些模式如Gateway, DTO之类的。
- 服务器端的宿主容器选择
更深层次的介绍还是请查看参考资料里面列的链接。
参考资料
事实上,大多数的书都很厚,如果像快速的学习RMI的用法就不要看那些书。看完了,项目也结束了。
一些有用的Link
[sun公司的RMI教程]http://java.sun.com/developer/onlineTraining/rmi/RMI.html
[sun公司的RMI培训资料]http://java.sun.com/docs/books/tutorial/rmi/running.html
发帖者
凌浩
时间:
5/25/2007 12:54:00 下午
0
评论
标签: Java
2007年5月15日星期二
windows server 2003 中DCOM 权限设置
Windows2003加强了DCOM的权限管理,其设置和window2000中稍有不同。
首先打开 注册表,在HKLM\Software\Microsoft\Ole下面加上两个DWORD类型的键
ActivationFailureLoggingLevel (1)
CallFailureLoggingLevel(1)
这两个键可以把失败的登录尝试记录下来。比如你用xxx尝试登录,结果得到800706ba的错误
然后运行DCOMCNFG,在My Computer上面右键,然后选择Default Property标签,Default Authentication Level 选择None,Default Impersonation Level选择Impersonate.
这里很奇怪,就算选择别的选项,关掉再打开,又会回到这两个选项。
然后选择 COM Security标签,在Access Permission , Launch and Run Permission 里面把刚才失败的用户名加上,并赋予 Remote Access, Remote Launch 的权限。
然后最重要的,在防火墙里面把RPC服务的端口135打开。打开端口似乎需要重启计算机,否则用netstat -a -b 查看一下是否真的打开。
当然,这个方法只能运用于信任度高的局域网内,否则就危险了。
发帖者
凌浩
时间:
5/15/2007 01:48:00 下午
0
评论
标签: Windows技术
2007年5月14日星期一
2007年5月4日星期五
《大剑》Claymore
发帖者
凌浩
时间:
5/04/2007 09:08:00 上午
0
评论
标签: 杂七杂八
2007年5月2日星期三
heroes实在是太精彩了
这一集(1E20)中,HIRO来到了未来,见到了未来的HIRO。尽管上一集的时候我已经预料到这是一个黑暗的未来,但是没想到竟然会这么黑暗。
塞拉杀了内森和那个会变身的女人,结果变成了美国总统,愚弄民众长达5年。一个骗子能做到这个份上真是神乎其技了。超级白痴的马特助纣为虐,终于帮着塞拉获得了克莱尔的再生能力,又杀了未来的HIRO。克莱尔的fans们估计要哭了,编剧们为了将邪恶进行到底终于那她开刀了(还真是开刀呢)。妮其失去了自己的儿子迈伽和D.L.,成为了彼特的女友。伯纳特好像成了地下党,专门帮有特异功能的人逃脱塞拉的掌控。Mohinder变成了塞拉(总统)的御用教授,看来读书人就是好骗。
变化最大的还是要数彼特,似乎他已经完全掌握了自己靠近别人所学到的能力。连HIRO的时间静止都学会了。人也变得非常稳重成熟起来。(没办法,不变的酷一点,怎么能把大美女妮其骗到手呢?)除了塞拉他是唯一一个身怀数种技能的人了,不愧是塞拉的宿敌。不过塞拉最强的那招念力不知道他学会了没有?那简直是和JEDI武士一样的王道能力啊。如果他也会念力,再学习一下日本剑,穿个灰袍子,绝对是一个JEDI。
真是佩服编剧的天马行空的能力啊,不过本来这种科幻片玩的就是想象力。没有点special ability 怎么行。
片尾最后就是塞拉终于熬不住显出真面目和彼特对决。两个人都有超强的实力,一个是靠杀人吸收了无数的能力,一个是通过修炼,慢慢掌握自己靠近有能力的人所暂时学到的能力。
两人的对决谁会赢呢?不知道,也没有必要知道,无论如何,那个黑暗的时代是不会改变了。重要的是现在,不是吗?现在将会更难了!
发帖者
凌浩
时间:
5/02/2007 10:47:00 下午
0
评论
标签: 杂七杂八
2007年4月21日星期六
大勇和小花的欧洲游记
大勇和小花的欧洲游记 www.dayong.name
在网上逛的时候无意中遇到了这个网站,美涣美仑的Flash,悠扬美妙的音乐,再加上熟悉的画面引起了我极大的兴趣。
我很久没有这么仔细,这么悠闲的在网上阅读文章了。进入他们2005年的游记慢慢品读,发现细腻的文字出自小花之手,照片则出自大勇之手,两者配合的天衣无缝。耳边飘着法文音乐,思绪已经跟着他们的步伐一路畅游欧洲了,真是奇妙的感觉。
发帖者
凌浩
时间:
4/21/2007 09:06:00 下午
0
评论
标签: 旅游
手机小知识
觉得有用,因此转贴过来:
- 大家都知道用手机拨长途,前面加拨17951可以获得优惠价。但是,我们都不知道,必须手动拨号才能享受,重拨键系统不识别!
- 要想查询手机中的信息预定,请拨“0000”到186201,系统就会回复一个短信,列明所有的定制信息。如果想退定,就拨“00000”到186201即可。
- 锂电池的手机请不要等电量彻底耗尽再充电,因为锂电池和原来的镍电池不同,没有记忆功能,而且完全耗尽反而会影响电池中成份的反应。
- 打电话时,如果信号很弱,只有一格,请尽量停止通话,因为这时候手机的辐射最强。
发帖者
凌浩
时间:
4/21/2007 08:36:00 下午
0
评论
2007年4月9日星期一
Father and Daughter
小L正在打游戏,老L笑眯眯的走到小L旁边,“最近UML学的怎么样了?”
“嗯,还可以”小L应付了一声。
老L仍旧笑眯眯的说,“那就出道题目考考你吧”
于是老L随手在纸上画了一个简单的类图
“你看看这个关系对不对呢?”
小L抬头一看,哑然失笑,“那还用问,当然是正确的!”
“错!”老L眼神开始严厉起来。
“为什么?”小L关了游戏机,不服气的问道,“父亲和女儿不就是继承关系吗?”
老L没有回答小L的问题,指着图说道:“泛化关系就是is-a关系,那女儿是父亲吗?”
小L心里咯噔一下,他已经知道自己错在哪里了。
老L继续说下去,“这女儿啊,是永远不可能成为父亲的,就算以后结婚了,也是成为母亲。除了一种情况,她是个同性恋,她和另外一个女人结婚了,然后她让她孩子叫她‘爸爸’!”
“好吧,我承认我错了,但是他们到底是什么关系呢?”小L反问道。
“你再来看看这个图”,老L又拿出一张白纸,画了另一个图。
“那这个图对不对呢?”老L又是笑眯眯的问。
“嗯……这个是拥有关系,父亲拥有女儿,应该是对的吧……”小L觉的有点头大了,自己在看书的时候觉得都看懂了,怎么遇到个这么简单的问题就开始犯迷糊了呢?
“我要首先纠正你的用语,用语规范才能学好东西。这个是聚合,表达的是has-a的关系……”,老L看了看小L,继续说道,“这个关系也是错的。”
“为什么?父亲拥有女儿,说起来虽然有点别扭,但应该还是对的吧。”
“是错的,因为聚合表达的是整体-部分关系,女儿是父亲的一部分吗?如果父亲被车撞死了,女儿要怎么办?女儿也得自杀。因为聚合有个同生共死的概念在里面。而且聚合常常这样画……”说着老L在画上加上了重数(multiplicity)
小L一看也哑然失笑,的确这是错误的。
“事实上,聚合是不推荐使用得东西,在你初学得时候,尽量不要去用它。”
“好吧,再看看这个”老L又画了一个图。
“这是组合”小L有点想起来了,“我总是把实心的菱形和空心的菱形搞混,不过现在我记住了,这里是一个father拥有1到多个女儿,这个肯定是对的了。”
“让你失望了,这个还是错的!”老L说道,“虽然组合的逆重数常常是1,但是他归根结底和聚合是差不多的,都是表明has-a这个概念的。比如代码可以这样写……”
class Father {
Daughter d = new Daughter();
……
}
“从这个关系里面可以看到,女儿是做为父亲的一个属性,也就是特性存在的。而且最重要的,父亲知道女儿,但女儿知道父亲吗?不知道!所以这个是错的”
“你是对的”小L垂头丧气的说道,“那,到底他们是什么关系?”
“呵呵”,老L笑着说到,“看看这个图”
“这不就是一般的关联吗?”小L疑惑的问道。
“对,父女的关系就是一般的关联,另外还有两个role: be father of 和 be daughter of。他们的关系只能用关联来表示”。
“原来是这样,看来我还要自己得仔细得去思考UML的细节问题啊……”小L拿起几张图一一对照过去,若有所悟得说道。
发帖者
凌浩
时间:
4/09/2007 12:59:00 上午
0
评论
标签: UML
2007年1月30日星期二
开张了
很久以前就从msn space搬到blogger了,但是一直没有时间装修这里,今天稍微弄了一下,准备开张营业了。
发帖者
凌浩
时间:
1/30/2007 12:44:00 下午
0
评论
标签: 杂七杂八


