时光的时光

昨天又因为一些问题搞到很晚(或者说很早哈)回家。

洗完澡拿起手边的《时光的时光》随便翻翻,看别人的人生历程总是那么有激励感。

“我们不是要把小说改编成电影,而是要拍摄他的人生”,虽然只看了2页,但是这句话真的很励志。

我们的人生究竟是什么?是有钱是有人是有地位? 还是自己不断的完善,最后平凡地离开?

很多人都会问?为什么不对自己好一点,人生在世吃吃喝喝,可是到头来,到了父母的年纪你又会怎样?其实我并不了解爸妈现在在家是怎么过的,只是觉得有点。。。

其实人生就是这样,不断吸收,充实自己,最后平凡地离开,不带来一丝,不带走一片。

解决EXPECT中读取中文的问题

公司的linux不知道啥情况把console设置成了中文,导致回车后密码提示为:“密码:”

原来写的expect脚本去自动跳的脚本因此歇菜了。

现在用简单的方法就可以了:在所有命令前都加上:export LC_ALL=en_US这样保证每次执行结果都正确就可以了。非常简单。

2012-4-13

其实这不算一个不一样的周五,最近每到周五特别想回家,很奇怪。

但前天的PS邮件还是提醒了我,今天不太一样。一早元吉说是不是发一个邮件?我想了想说:好吧。可是我不想发,道理很简单,我发出来的邮件一定有一定作为主管代表公司的成分,我不想发这样的邮件。

中午胡魁(现在应该叫回唐蜜)自己发了一个邮件:say goodbye。其实在我们这里很少真正有人离职会自己发个邮件的,但是他发了,寥寥数语却让我感到很感慨。我大概已经记不得最早我们是怎么见面的,我唯一记得的真的就是他的代码质量和对代码的追求,这个已经不再年轻的程序员,还能保持这样的执着,我想公司里找不出多少这样的人。我现在常常做的一件事情就是对着eclipse一声叹息,很多人都不理解,为啥我会这样,那是因为我看到了一些不喜欢的代码。

就是这样一位同学在一个多月前提出了离职,其实离职前转过来的时候我很高兴,因为我觉得我可以给他很多有意思的项目,因为我的确给了,别人我不敢提这么高的要求,但是对他可以放心。但这一切太晚了,他告诉我去年其实就想离开了,离开这些没有追求的环境里。

晚上我们也都说到,当无数开发无数有儿有女的开发在公司彻夜加班的时候,换来的却只是一些业务的同学的敲锣打鼓,我也想说嗤之以鼻这四个字。人活着到底为了什么?

那晚,唐同学说到,其实10万年薪和20万差别不大就是几个平米而已,这不是100万和1000万的差别,是的,回想我们的过去,那个夜晚我们也都思考这些问题,虽然大家都有点不行了,但是不影响我们的讨论。

我回了他的邮件,只是说到他的代码是很漂亮的,其他的我真说不出来。

离开下班的时候又处理了一个擦屁股的事情,又不小心面了一个外包,吃饭晚了,自然这一次我没有含糊,没有用我惯常的保护措施,我直接一瓶下去了,当时还好,但是过了一会就不行了,我记得我在那里抽筋,然后走了一路吐了一路,全吐干净了,胃好难受。

然后再喝,再吃。。。

唐同学大概真的醉了,我们开始说胡话了,他的酒量我真是没有发现,因为在我印象里他不喝酒,实际上他却喜欢喝。在我印象里他不是那种泡吧的人,事实却刚好相反,好吧。。。有一种认识太晚的感觉。

其实我以前不怎么喝酒,一来水平不行,喝一点就胃不行加上有时候肝也会不舒服,但是这次却发现大家喝多了,喝吐了,说了很多肺腑的话,这是一种很有意思的文化,在公司有时候有些东西需要照顾别人的心情需要照顾自己的位子有些东西不能多说出来,但是在这里不一样,我们更喜欢叫大家的真名,其实大家的名字我是都知道的,我一直在记忆着大家的两个名字,因为我想我们也许真的可以联系很久的,就是这样。

说到这里我又有点沉默了,我想还是不要了。

最后要感谢大家给我上的家庭课,知道了老婆爱人是怎么样的感觉,其实以前我一直不太懂也不明白,我自以为我经历了那么多,对于女人对于感情我了解够多了,其实却不是,因为我没有得到过的总是缺失的,好吧。。。

2012年4月13日我会记住的,谢谢大家

晚秋-你为什么要用他的叉子?!

这看起来只是一个笑话,却是全片的一个非常有意思的次高潮.

anna对那个男人一直还有那么一点点那么一点点.

但是这个叫勋的男人在这一刻,担负起了一个成熟男人的气质,他突然说,你为什么用了我的叉子. 因为那个王晶还在用那种占有的感觉, 让anna感到很无语,但对他的那最后一点气息始终伴随着他.

在饭桌上最后的那些对话绝对是本片的一个经典,一种中国式的坑,加上美国式的文化表达, 合作起来,

一个细节就是倒茶,体现了所有的人物关系,就像老舍的小说里那样细腻.此时的餐馆就如老舍的茶馆一般,发生这中国人人生中发生的很多事情.

而那个韩国人也渐渐明白了anna在车站用中文说的一切,这是全片一个重大的连接点,可说是非常重要,我想这也是这部片子能拿奖的一个重要地方. 这一段在我重看的时候真是演员到位,台词到位, 全片的完美之点.

不过我很怀疑韩国人是否能看懂这些, 特别那个叉子的故事, 很久没有那么需要细细品尝的影片了, 晚秋可以细细地去品味这一切. 就是这样.

晚秋-Do you want me?

Do you want me? 我想男人看了<晚秋>之后应该会记住这句话.

说实话在电影院并没有太在意,我想每部商业片都会有这些元素罢了.

回家下载了韩国版,重新看了一遍之后却发现了这段的关键作用.

anna见到曾经让她为之去死的男人,却发现男人对她说:7年了,发生了很多. 那种失望对于女人来说是非常残忍的. 那天发生了太多,之后却什么都没有了.

这个时候剧情恰好让她遇到了那个韩国人,勋.

于是anna对那个陌生的看起来油油的男人说了这句话,其实anna只是想放纵自己,她想去”背叛”,她想做一次”坏”女人,却发现,坏女人很难做…于是发生了电影里的那一幕.

剧情在这里也展开了,开始让这个男人蜕变的开始,直到最后那个男人对她说我们在那天等你回来. 可惜时间总是残酷的, 最后anna再一次没有等到那个男人, 但这一次她习惯了,没有了第一次的那种失望,全片在一片”莫名”中结束.

应该说结尾看起来这是一部相当不错,而且留下活口的片子. i like it.

关于在html5上实现资源节省的方案思考

目标:

在webkit内核的浏览器中实现固化资源的本地保存.首先来确定完成这件事情需要做的事情:

1 怎么管理缓存资源

2 怎么通知已经被缓存的资源需要更新

方案对比:

实际上在实现上有两套方案:

方案一:

applicationCache,这是一套原生的方案,它的基础可以看一下的原文介绍:

https://developer.mozilla.org/en/Using_Application_Cache

这种方案中有个天然的问题我们需要注意:
1) If entry.html is not listed in the example.appcache cache manifest file, visiting the entry.html page causes entry.html to be added to the application cache as a master entry.
所以可以确定,当前请求页面一定会被cache掉,经过测试无法对这个文件进行强制NETWORK因此这里需要特别注意使用场景的局限性.

2)更新是后置的,即使更性无法改变当前载入页

3)更新是全局性的,无法单独更新某个离线文件

4)最有效的更新方式是让manifest找不到(means 404),也不要配置fallback,这样可以保证想更新的时候及时更新,可以大部分解决2)中存在的问题

5)对于链接参数变化是铭感的,比如链接上显式的sessionId改变了同样会导致第一进入没有缓存(虽然sessionId本身的复用率非常高,但从机制上来说我无法确保这点)

方案二:

这是一个非典型的用法,也是一个看起来比较简单的技术方案(其实从实现来看这种方案在服务端并不复杂,但需要比较多的前台改造来配合,但不妨一试)

而且这种方案在客户端基于webview系统的时候也可以通过拦截指定的js调用来彻底解决资源存储的问题,而且可以在系统中比较透明实现.

这种方案基于localStorage来实施,首先我们知道js和css都可以通过js来实现延迟加载,传统的延迟加载实际就是延迟从网络来读,那么现在我们改变一下把从网络来读取编程了从localstorage来读取:

方案的综合评价:

方案一是一种原生方案,从前台角度来说是比较简单的,但是从实际来看其应用场景比较窄,对于大部分动态系统都很难支持,能在我们系统中直接使用的场景可能只有一些边栏页面和旺旺的对话框页面了.

方案二更多需要前后结合,特别是需要改变目前js框架系统来实施,但这种方案实际上的后台比较简单,而且适应性强,通过基于webiew框架实现的客户端系统同样可以通过”handle”其中的关键方法来实现本地资源的同步也不同担心协议和变更的限制,但这种方案对于应用改变会比较多,因此相对来说周期会长一些,但考虑到方案的优劣,建议实施二号方案,并且1和2本身并不矛盾,可以结合起来使用,那真的是如虎添翼.

由DETAIL被攻击想到的

昨天半夜detail被攻击,攻击形式其实很简单,就是访问某个url.

针对这样的模式我们可以做什么,对于一个无线网站?

1 不要简单的拒绝,查看它的访问特征,如果有固定特征完全可以引导到某几台固定的机器上,让他们蹂躏,hard的防御往往会导致更恐怖的结果.如果可以重定向攻击页面到制定地点和制定内容,悄无声息.

2 对于无线网络结合白名单才可以打开dod,否则就是一个悲剧.

 

发现一个wurfl的低级bug

java.lang.StringIndexOutOfBoundsException: String index out of range: -1error>>Mozilla/5.0 (compatible; MSIE 9.0; Windows Phone OS 7.5; Trident/5.0; IEMobile/9.0; Nokia; 800C)

at java.lang.String.substring(String.java:1931)
at java.lang.String.substring(String.java:1904)
at net.sourceforge.wurfl.core.utils.StringUtils.indexOfAnyOrLength(StringUtils.java:201)
at net.sourceforge.wurfl.core.matchers.NokiaMatcher.lookForMatchingUserAgent(NokiaMatcher.java:49)
at net.sourceforge.wurfl.core.matchers.AbstractMatcher.applyConclusiveMatch(AbstractMatcher.java:170)
at net.sourceforge.wurfl.core.matchers.AbstractMatcher.match(AbstractMatcher.java:120)
at net.sourceforge.wurfl.core.matchers.MatcherChain.match(MatcherChain.java:86)
at net.sourceforge.wurfl.core.matchers.MatcherManager.matchRequest(MatcherManager.java:92)
at net.sourceforge.wurfl.core.DefaultWURFLService.getDeviceForRequest(DefaultWURFLService.java:124)
at net.sourceforge.wurfl.core.DefaultWURFLManager.getDeviceForRequest(DefaultWURFLManager.java:99)
at net.sourceforge.wurfl.core.DefaultWURFLManager.getDeviceForRequest(DefaultWURFLManager.java:115)

 

看下代码:

protected String lookForMatchingUserAgent(SortedSet userAgentsSet, String userAgent) {

int tolerance = net.sourceforge.wurfl.core.utils.StringUtils.indexOfAnyOrLength(userAgent, new String[]{“/”, ” “}, userAgent.indexOf(“Nokia”));
if (logger.isDebugEnabled()) {
logger.debug(“Applying RIS with tolerance [" + tolerance + "] UA: ” + userAgent);
}
return net.sourceforge.wurfl.core.utils.StringUtils.risMatch(userAgentsSet, userAgent, tolerance);
}

遇到wp7的手机就不行了,是nokia的Matcher有问题.大家用wurfl最好还是try catch掉,血的教训啊.

http://drupal.org/node/1424064

MessagePack使用时要注意bean必须要有默认构造函数

在是用msgpack时可以通过两种方式来注册你的bean:

1 使用@Messagepack来标记你的类

2 使用代码注册:msgpack.register(T.class);

但是大家要注意必须要有默认构造函数否则messagepack就无法使用了.

wurfl 修改纪录<1>

虚假的MatchAll

在wurfl中有个matcher叫做:net.sourceforge.wurfl.core.matchers.CatchAllMatcher

实际上虽然这个类叫做cacheAll但是并不是如此的,首先请看到代码:

net.sourceforge.wurfl.core.classifiers.FilterChain:

public void filter(String userAgent, String deviceID) {

for (Iterator iterator = filters.iterator(); iterator.hasNext();) {
Filter filter = (Filter) iterator.next();
if (filter.canHandle(userAgent)) {
filter.filter(userAgent, deviceID);
break;
}
}
}

是那个break,实际上它的意思就是让每个明确的内容进入对应的filter中,这样利用matcher可以提高识别率或者其他的.

而在这里我想把一些虚拟的设备放进去,比如目前把UCWEB放进去了,下面是一些测试样例:

IUC(U;iOS 4.3.5;Zh-cn;320*480;)/UCWEB8.1.0.104/41/997

JUC (Linux; U; 2.3.4; zh-cn; GT-S5660; 320*480) UCWEB7.9.3.103/139/32160

我不希望去添加这些ua到patch中,这些ua太多了,而且意义不大,因为是同一个设备,至于怎么添加后面还有另外的解决方案这里先不提.

回到主题,我们现在就是要把break编程contiune就可以了,是这样的,但是wurfl有个很suck的地方,就是很多代码比较古老因此OO思想用的不好,比如:

FilterChain MatcherChina等这些类都没有接口方法,因此你只能直接extends这些类,问题是它的大部分属性又都是private的于是你不得不覆盖掉几乎所有的实现,现在我们就要覆盖实现了:

public void filter(String userAgent, String deviceID) {

for (Iterator iterator = filters.iterator(); iterator.hasNext();) {
Filter filter = (Filter) iterator.next();
if (filter.canHandle(userAgent)) {
filter.filter(userAgent, deviceID);
}
}
}

然后简单说下,怎么matcher的,现在这么改当然不能matcher,实际上你看过源码就知道,它的matcher是基于下面的组合:

Filter+Matcher+UserAgentNormalizer

Filter决定了有多少device可以被这个matcher查询,Matcher做的就是匹配设备,而我们这里的模糊匹配主要利用的这个地方,最后就是改变ua的序列化方法,你可以实现UserAgentNormalizer这个接口.

这些下一篇会详细介绍wurfl中关于matcher和filter的一些故事.

当然wurfl这个项目真的算不上优秀,很多代码质量比较差,需要一点点改.

对了最后提醒下上面这么改其实会有个害处就是初始化时间会大大加长,这个当然得益于list的遍历效率低下,这块也是需要之后再优化的,但好在这只是初始化时间,问题不是很大,之后也会介绍我是如何思考减少内存占用的方法,都不属于高科技的方法.