It’s time to say goodbye

  刚写好了Farewell Letter,发出去了。离职的手续只剩下一个最后的签字。三个月在IBM的时间,很快就过去了。收获还是很多的,就不一一列出了(以后有机会再写吧,呵呵,先开个空头支票)。
  这里每个人都很nice,当你遇到问题的时候都会热情地帮助你。特别是我的mentor, Stephen,总是会耐心解答我的问题。而团队活动,一次滑雪,一次Team Show,特别是Team Show,让我感到这个团队的凝聚力。最后的时候经理的appreciation让我信心大增。
  很喜欢这里的工作环境,虽然不像Google那么夸张,两年后搬到IBM大厦以后应该会更好吧。技术气氛很浓厚,大家就像一家人,经理也和我们一起玩。不喜欢机关、事业单位那种Office Politics。
  对于IBM,我想还是那一句话来概括:
          IBM是家大公司。
 

哈根达斯在美国,在中国

 以前曾在网上看到文章说Haagen Dazs在美国和欧洲是垃圾食品,觉得被骗了。后来又有文章说这是国内枪手的文章。也就信了,继续觉得那是个好品牌。今天在Food版上看到了又一篇贬Haagen Dazs了,还贴出了Amazon.com的图。这下我也不得不信了,自己上Amazon查了查,结果发现果然如此。第一个搜索结果(附图)是16oz的,1oz = 30g,$3.99。也就是一斤的Haagen Dazs只有32块不到。我们可以对比一下Mac。在美国,一个汉堡是$0.99,国内肯定没有8块钱。而在国内的Haagen Dazs,即使是在超市买的,32块钱不知道可以买到几克。

Java Servlet文件上传解决方案(主要针对中文)

以前做动力中心那个网站的时候,由于用户要求要上传图片以及一些文件,所以要一个上传Servlet的组件。最后选中了SmartUpload,至少在Baidu上搜,到处都是。
没想到这才是噩梦的开始。主要问题是在中文文件名上。后来找了很多资料,用了一个迫不得已的最后方法:重新编译SmartUpload,加上中文的解决方法。后来也不知道怎么也就OK了。
前几个月动力中心的硬盘挂了,数据全丢了。不巧,我这里也没有备份,工作室的备份也丢了。没有办法,只好从一个旧的版本改起。其实中文开发的问题还是很多的,即使在Windows下好好的,到Linux下也会出各种各样的问题(比如Locale是en_US.UTF8)等等。
再也恢复不起来原来的办法了。后来也是在网上找到的资料,说是可以用Commons里的FileUpload. Jakarta Commons名气挺大的,我一起想学学,却一直忘,也不知道该怎么用(以前只听过BeanUtils, 用来注入一个bean的)。
马上从Apache下了一个来试试。注意,要用起来FileUpload,还要下一个Commons IO。里面对国际化的支持还是不错的,至少我用item.getName()出来的居然就有中文。
但保存文件还是遇到了问题。为了对国际化的良好支持,要达到以下几点:在页面显示的文件名要是中文的,下载的时候保存的文件名也要是中文的,同时文件要保存在一个目录下。
在做链接生成的时候,我发现浏览器会把链接中的中文自动encode成UTF-8的URL表示(就是%20%30那种)。没错,文件保存也可以用这个名字,这样在不支持中文路径的linux上也可以保存中文文件名了。然后我自己写了一个下载的Servlet,用于从本地读取文件内容,并写入response.getWriter()里。这样的话文件名自动就成中文了。至于重名问题,我的链接是这么写的: http://www.test.com/download/1892649237492/%8D%82.txt 结果文件名会自动转成中文的(IE6, FF1.5通过)。但是实际的文件名是1892649237492%8D%82.txt,就是没有了”/”,这一点,在Download Servlet里解析。同时DownloadServlet里加了一些逻辑,保护系统的安全。

I’m an engineer

  上星期有个QSE(Quality Software Engineer)的session,来了两个美国佬,Don & Brent(上一篇我也提到的)。session在十楼,有一次我们正好和Don一起坐电梯上楼。我的mentor看到Don的上衣口袋里有很多东西,好奇地问了一句:"Why are you carrying so many stuff in your pocket? Are these the gift for the session?" Session里为了活跃气氛,一般回答问题的会有一些小礼物的。Don开始如数家珍地像我们介绍口袋里的东西:"This is a pen, a QSE pen, a gift. This is a pen for signiture; this is a pencil, a ruler…" 里面有好多东西,小小的上衣口袋都塞满了,呵呵。
  最后,Don意味深长地说了一句:"Because I’m an engineer." Don已经在IBM做了30多年了,虽然已经是QSE的主管(应该是),却仍然把自己看成是一个engineer. 那句话说的好像:"I’m an engieer. I’m proud of it" 这是来自一个工程师受到普遍尊重的国度。
  而在这里,“官本位”盛行了两千年,工的地位始终是抬不起头来。无论一个人对技术是多么的热爱,最后还是要做管理,而不管他的管理有多么拙劣,技艺有多么精湛。

Team show

上周四,各个部门分别选出一两个team show的节目,参加员工活动。我们team在专门开会考虑了一个小时了以后(嗯,用的上班时间,老板正好不在,呵呵),并观看了网上几段视频以后,决定整一个Super Mario Live Show。出于体形和面相的考虑,洪光毫无疑问是Mario的不二人选。做道具、排练,整了好几个中午和下午,不过还是很有意思的。我做了一个子弹,呵呵,用脚下的硬纸版做的(本来给我的图片是个炮弹,害我做了一个暴kawayi的炮弹以后被否决了。。。)。
演出是这样的:两个人拉起块幕布,然后用barco(就是投影仪)搞出一个聚光灯的效果,然后洪光在原地跑,所有的道具,比如云、树、怪物在后面移动,同时配合事先录好的音效(这个最牛了),结果就成了Live Show了。洪光为此还到了孕妇装商店买了吊带服,呵呵。
演出的效果自然很劲爆,顶磨菇,踩磨菇,踩乌龟,吃金币,下管道,打怪,无敌,摘旗都有,最搞笑的莫过于PAUSE了,呵呵,一瞬间都停了,打出一个PAUSE,然后关灯,换衣服(刚吃了花,要把外面的红衣服换成白衣服,呵呵)。音效的配合也N好。我们的配合也无敌了。我的戏份不多,就拿了一个子弹(用柄连着),然后模拟子弹打怪。
(照片的话我没暂时拿到)
UCD的team show是一个音乐剧~~也很不错。最搞笑的是他们演到一半,几个戴着写了"BUG"的帽子的家伙,唱着“我们是害虫”闯进来,发现进场的时候不对,大家狂笑,说真出BUG了~~
最后是来CDL做QSE的两个老外,给CDL写了一着歌,底下是歌词,根据"Jingle Bell"的Chorus来唱的。"…"代表我忘词了,呵呵。

CDL, we do well,
we all love to test.
We do code and service too,
and we have energy.


Give us a big job to do,
and we’ll give you a quality.

javascript获取textarea光标选择位置和内容方法(IE, Firefox)

在网上用baidu找了很久,找到的都是IE的方法,Firefox都不能用。 而且很多要用到<textarea>.focus()方法,用起来很不方便。
后来转用Google,搜了下”textarea cursor”,第一个就有好方法。我根据最后一个家伙的comments,写了一个sample,应该还是挺好用的。
原文地址:http://weblogs.asp.net/skillet/archive/2005/03/24/395838.aspx
<html>
<head>
<title>TEST</title>
<style>
body,td{
font-family: verdana, arial, helvetica, sans-serif;
font-size: 12px;
}
</style>
<script type=”text/javascript”>
var start=0;
var end=0;
function add(){
var textBox = document.getElementById(“ta”);
var pre = textBox.value.substr(0, start);
var post = textBox.value.substr(end);
textBox.value = pre + document.getElementById(“inputtext”).value + post;
}
function savePos(textBox){
//如果是Firefox(1.5)的话,方法很简单
if(typeof(textBox.selectionStart) == “number”){
start = textBox.selectionStart;
end = textBox.selectionEnd;
}
//下面是IE(6.0)的方法,麻烦得很,还要计算上’\n’
else if(document.selection){
var range = document.selection.createRange();
if(range.parentElement().id == textBox.id){
// create a selection of the whole textarea
var range_all = document.body.createTextRange();
range_all.moveToElementText(textBox);
//两个range,一个是已经选择的text(range),一个是整个textarea(range_all)
//range_all.compareEndPoints()比较两个端点,如果range_all比range更往左(further to the left),则                //返回小于0的值,则range_all往右移一点,直到两个range的start相同。
// calculate selection start point by moving beginning of range_all to beginning of range
for (start=0; range_all.compareEndPoints(“StartToStart”, range) < 0; start++)
range_all.moveStart(‘character’, 1);
// get number of line breaks from textarea start to selection start and add them to start
// 计算一下\n
for (var i = 0; i <= start; i ++){
if (textBox.value.charAt(i) == ‘\n’)
start++;
}
// create a selection of the whole textarea
var range_all = document.body.createTextRange();
range_all.moveToElementText(textBox);
// calculate selection end point by moving beginning of range_all to end of range
for (end = 0; range_all.compareEndPoints(‘StartToEnd’, range) < 0; end ++)
range_all.moveStart(‘character’, 1);
// get number of line breaks from textarea start to selection end and add them to end
for (var i = 0; i <= end; i ++){
if (textBox.value.charAt(i) == ‘\n’)
end ++;
}
}
}
document.getElementById(“start”).value = start;
document.getElementById(“end”).value = end;
}
</script>
</head>
<body>
<form action=”a.cgi”>
<table border=”1″ cellspacing=”0″ cellpadding=”0″>
<tr>
<td>start: <input type=”text” id=”start” size=”3″/></td>
<td>end: <input type=”text” id=”end” size=”3″/></td>
</tr>
<tr>
<td colspan=”2″>
<textarea id=”ta” onKeydown=”savePos(this)”
onKeyup=”savePos(this)”
onmousedown=”savePos(this)”
onmouseup=”savePos(this)”
onfocus=”savePos(this)”
rows=”14″ cols=”50″></textarea>
</td>
</tr>
<tr>
<td><input type=”text” id=”inputtext” /></td>
<td><input type=”button” onClick=”add()” value=”Add Text”/></td>
</tr>
</table>
</form>
</body>
</html>

转载一个牛人~~以后努力的方向

陈华简介:
北大计算机系本科、硕士(04年夏天毕业的)
北大天网FTP搜索开发者、Maze开发者
毕业时获得微软研究院、工程院、IBM CRL三个Offer
在工程院干了两年后,今年年初辞职创业,并靠 www.kooxoo.com拉到了200万美元风险投资

下文是他04年毕业时写的总结,觉得比较有借鉴意义

http://blog.csdn.net/tangl_99/archive/2006/09/16/1231850.aspx

如何配置tomcat的ROOT为/

修改%TOMCAT_ROOT%/conf/Catalina/localhost下的Web应用配置文件。
1.删除或移走ROOT.xml,这个文件就 是tomcat的root配置;
2.修改server.xml, <Host>里加上
<Context docBase=”test” path=”” workDir=”work\Catalina\localhost\test” reloadable=”true”/>
docBase:为你的Web应用程序所在的路径,可以为相对和绝对路径, 相对路径 为相对于在<Host>里配置的属性appBase的路径;
path:为Web应用的上下文路径,保持为空则会绑定到root路径上;(其实就是如果没有被其他<Context>定义了,就到这个目录去。
workDir: 为Web应用的临时工作目录,存放编译后的类和页面。
Tomcat的doc:
If you specify a context path of an empty string (“”), you are defining the default web application for this Host, which will process all requests not assigned to other Contexts. The value of this field must not be set except when statically defining a Context in server.xml, as it will be infered from the filenames used for either the .xml context file or the docBase.
还有一个debug属性,经常看到人写,但在tomcat的文档里没有看到,不知道是为什么。
文档地址 http://tomcat.apache.org/tomcat-5.5-doc/config/context.html
<![CDATA[修改%TOMCAT_ROOT%/conf/Catalina/localhost下的Web应用配置文件。
1.删除或移走ROOT.xml,这个文件就 是tomcat的root配置;
2.修改server.xml, 里加上

docBase:为你的Web应用程序所在的路径,可以为相对和绝对路径, 相对路径 为相对于在里配置的属性appBase的路径;
path:为Web应用的上下文路径,保持为空则会绑定到root路径上;(其实就是如果没有被其他定义了,就到这个目录去。
workDir: 为Web应用的临时工作目录,存放编译后的类和页面。
Tomcat的doc:
If you specify a context path of an empty string (“”), you are defining the default web application for this Host, which will process all requests not assigned to other Contexts. The value of this field must not be set except when statically defining a Context in server.xml, as it will be infered from the filenames used for either the .xml context file or the docBase.
还有一个debug属性,经常看到人写,但在tomcat的文档里没有看到,不知道是为什么。
文档地址 http://tomcat.apache.org/tomcat-5.5-doc/config/context.html%5D%5D&gt;

“Working with Java Virtual Machine” 读书笔记(一)

在books24x7.com上在线看的这本书(不过不是免费的,IBM为员工买了这个网站的阅读权利),觉得有些东西有必要记下来。不知道有“一”还会不会有“二”,呵呵。
Chapter 2 Overview of JVM architecture, Section 2 Runtime Data Areas in JVM
JVM data area:
1. Method area
2. Heap
3. PC Register
4. Java Stack
5. Native Method Stack
Method area: Shared among all JVM thread
1. name
2. super class
3. class/interface
4. modifier
5. list of super interfaces
6. Other:
a. Constant pool
b. field info
c. method info
d. class var
e. ref to Classloader
f. ref to Class
Heap:
1. Handle pool: pointer to object(in object pool) & class(in method area)
2. Object pool (instances)
Such design is for the avoiding fragmentation
Stach: 2 types
1. Frame for func activation
2. Operand for instructions, arg & ret of JVM instruction
Java Stack Component
1. local var
2. execution env
3. operand stack
JDK — JRE — JVM — bytecode Interpreter, GC, Class manager, …
\            \
classlib — byte code
\
native