2011-08-06

给孩子照相真难啊

先看照片。



有模特的潜质吧?

在一棵苹果树下,发现了很多被雷阵雨打下的苹果








今天周末, 孩子午睡醒后一家人出去散步。我也带上了相机。想给老婆孩子照几张像。

机器上挂的还是35mm F/2,这头我现在用的几率最高了。没想到,到了室外不好用了。因为,如果远了照,孩子人在相片上显得太小了,这个头有点小广角。 可如果离近了,儿子不老实,根本不配合,要么就往你跟前走,来抓相机,要么就是不看你。照了几张,觉得不好用,索性回去换了85mm F/1.8 又出来,这次可以远远地瞄他了。不过近了就耍不开了。

出去一共大概一小时,我忙活出了一身汗。没事光做蹲起练习了。

最后发现就得勤按快门,回来再选。
传几张觉得还凑合的吧。以后还得多照。这夏天一直冷飕飕,眼看就要过去了,应该趁天气好多给儿子照点照片。

2011-07-01

一盘炒猪肝,二两黄酒

从周1到周4,在上下班的路上把<许三观卖血记>看完了。余华的小说,看过的不多。很早的时候看了<活着>和<黄昏里的男孩>。《黄昏》是个中短篇的合集。现在已经印象不是十分深刻了,只有其中几篇很典型的还有印象。今年年初又看了第二遍<活着>,最近这刚看完许三观。

他的文字好像就和他的那些主人公一样,都是朴实无华,再普通平凡不过了。可往往就是这些普通却能打动人心。 主人公大都以农村或者邻村的小城镇为背景,而且有个共同特点就是有点愚昧的老实本分人。 他总能通过这些平常人的平常生活,让人们感觉到生活的艰辛的同时,也体会到人性恶的一面。

这个许三观,也是这群平凡的人中的一员。一本书下来,其实就像平铺直叙,没有什么大的波澜。首先说他这个人物,我感觉是:
老实,本分 -尽管多次卖血,但从未做过什么亏心事(林芬芳的事除外)
有点愚昧 - 对抽血的理解
很好面子,心地善良 - 我理解对于一乐的一些做法其实是面子问题,他其实是最爱这个儿子的。对于他的善良,多处都有体现。给李小勇叫魂这个片段很典型。
乐观的态度 - 他其实是有点阿Q精神的。不管什么多难,他其实还都是乐观地去看待。饥荒年月他生日的晚上给大家在床上炒菜是个很典型的例子。
一个让人尊敬的父亲 - 这就很明显了。

网上的文化人多,总能挖掘更深层次的东西。什么更深层次的揭露和批判拉等等。 这就不评论这些了,咱也没那水平,只是对于几个情节,可能和网上一些人的看法不太一样。

1 对林芬芳的强奸
这个事他做的可能并非他所愿。是为了维护心里的一种平衡或一种报复。因为那时候的林芬芳,这个全城最胖的女人,不仅已经完全没有了妩媚诱人的资质,而且当时还断着一条腿。去强奸这样的人说实话真需要点勇气。
2 最后一次去卖血
就是全文最后,新血头不收他的血,并挖苦他的那次。那时候他已经年过花甲,而且吃喝不愁了。用他的话说,是为了吃炒猪肝喝黄酒去卖血。其实他完全可以去饭店直接吃。我觉得他要的不是那些吃食,而是想回味往日里吃那些东西时的感觉。他卖血一次次帮助家里度过难关,平时他本本分分,省吃俭用。只有卖血以后到饭店点菜的时候,才有一种得意,成就感,吃着炒猪肝,喝着黄酒,他能体会到,他存在的举足轻重的意义。当年老了,儿子都成年了,生活的坎坷少了,他不用去卖血了。但他还是想去体会那种成就感,那种自豪感。一盘炒猪肝,二两黄酒,就是他那些感觉的最直接表现。恐怕是为了这,他才又一次走进医院。

这本小说有多处能打动人,但让我印象最深的:

-“你要是我亲生的儿子,我最爱的就是你” 我要是一乐,我可能得哭了。
-冬天在去上海的路上一个城镇(名字忘了)的桥边喝冰水的情景。和与旁边好心人们的对话。

-困难时期他卖了血,一家去吃面条,让一乐去吃烤山芋的时候。一乐可能还不懂事,但是真替他心疼。

-结尾时,许玉兰数落三个儿子的话,想着许三观的经历,看着扎心

这应该算个喜剧故事吧,不光是个happy ending,内容穿插也有不少让人发笑的小段。可就这么个喜剧却是让人揪着信看完的。写个blog,做个记号。

突然这周末也想吃盘炒猪肝了...

2011-06-09

根据不同网络环境快速切换系统的代理服务器

工作性质决定,我经常需要带着公司的笔记本在不同客户的不同网络环境里工作。这些网络环境有这么几种:
  • 无代理,直接连外网
  • 有代理,无须登录认证,连外网
  • 有代理(多个),都需认证外连
笔记本里很多程序或者配置文件都是与网络相关的, 比如 maven的settings.xml, ~/.hgrc, eclipse的网络, 浏览器, 终端 等等。换个客户,修改代理很烦人。 别的同事大都用windows,有个软件Proxomitron 有proxy transparent forwarding功能, 把代理设置成localhost:port,然后通过在软件选择可以帮他们快速切换,并且这个软件还可以对发送/接收的数据进行过滤等功能。我因为懒,就一直wine这个软件来实现我自己的代理切换,虽然用着还算稳定,但是总是不爽。  搜索了一下于proxomitron功能类似的有privoxy,这个也有代理转发,消息过滤功能。 而且linux的软件好就好在配置文件都是文本,有了sed/awk可以想怎么改就怎么改,然后再reload/restart 服务就可以了。但是后来发现一个问题,无法forward到需要登录的代理,查了一下,加http header "Proxy-Authorization"可以,但是在那个action file里加+add-header.. 通过调试发现这个header总加不上。无奈作罢,接着wine将就吧,可这一将就将就了1年。呵呵。

其实我挺懒的,能将就就将就了。这2天决定腾出手来要把这个问题给解决了。因为有两个资深同事几乎每次看到我用vi编辑东西就说闲话,说ultraedit/notepad++操作多简易,多快捷。有时候用我的电脑他们就抓狂地骂shit。因为我是美国英语键盘布局,而且eclipse里用了vi-plugin。他们每次都说linux阿,vi阿就是shit. 我每次都不搭理他们,心想谁爱用什么就用什么得了,不就是个干活儿么,顺手就行了。最近被他们看到wine的proxomitron,又被冷嘲热讽好一阵,郁闷。俩人资格也算挺老了,咋就这么没完没了呢。所以干脆,换!

选了另一个代理软件:tinyproxy。这个也不支持直接的需登录代理转发,也要通过AddHeader。但是这个一次就实验通过了。关于Proxy-Authorization这个header,可以通过正常连接并登录那个代理服务器然后在firebug或者chrome的developer tool通过查看Request Header找到。 然后就是写个脚本sed 修改相应的配置行,然后reload了。当然也可以根据不同环境弄多个配置文件,然后用脚本选择cp。我觉得还是就一个文件,然后修改好。要么一旦对配置文件中其他地方修改了,还要把各个环境配置文件相应的地方都改。

如果有一天到处都用无线就好了,可以根据无线网的ID来自动切换。其实有线的也可以根据IP地址来自动切换,可对我这里有几个客户那里不适用。:(

目前和别的同事的proxomitron区别不大了。唯一一个就是人家是状态栏的小图标,用鼠标点点就行了,我得在终端里写个命令,不过用linux的谁不至少开着1个终端呢?也没什么问题。

脚本在自己的版本库里,没备份的必要就不贴了,也没什么特别之处。

2011-01-04

汉宝儿1周岁了

1月2日,汉宝儿一周岁了。去年在医院陪伴老婆生产的情景还像在眼前,这一年就忙忙碌碌地过去了。不由感叹时间飞的好快。

他的生日赶的还不错,正好是个周末。顺便抱怨一下这次的圣诞节,和新年。居然都是周末,弄的公共假日2个大节日才有1天!幸好年假有存货。

汉宝儿的生日玩了抓周游戏,老婆在网上查了一个抓周物品清单,照着准备了,没有的,我们就自由发挥了一下。总之样数不少。有图为证:


结果呢?那是很明确啊,别的一概不看,小寿星直奔主题啊!看图就知道了。第一抓的一霎那:


没看出来他还对音乐挺感兴趣啊,呵呵。我觉得可能是这个颜色太鲜艳了,对他来说吸引力比较大吧。旁边的笔记本电脑没开机。如果屏幕有东西,可能也会对他构成不小的吸引力。 不过不选电脑就好,做IT不是什么好职业。还有欧元票子的颜色也太土了,不吸引人,另外也可能是放的太少了,如果弄几万,厚厚的一叠票子,可能也会引起他注意。 :D  不过抓周就是个游戏,将来还是根据他的兴趣培养吧。 我也希望他通音律,最好是能掌握一件乐器。

午饭后,老婆就开始烤蛋糕了。说实话她对这个不是太在行,以前有过几次尝试,基本都以失败告终。这次是儿子生日,她可下了功夫,材料早早就采买好了,而且很全。把孩子哄睡后,她就开工了,只听厨房里时不时传出搅拌机的声音,过了半个来小时,飘出了刚烤熟蛋糕的香味。进去一看,这次还真不赖,但人家说这只是第一步,还有夹水果,涂奶油,再挤奶油花,写字等等工序。得,看来好事多磨啊。 。呵呵先来看个成品吧:


卖相的确不太好,不过这已经是她自己最好的作品了也是最用心的一个。问题出在涂奶油,和挤奶油花上。她要求比较高,每次完事都觉得不满意,于是抹平再来,经过几次反复,就成了这样了。不过味道还是不错的。

吹蜡烛是我代劳的。不过关上灯,看着那一点烛光,儿子还是很兴奋。吹了蜡烛,照个像:

功臣得露个面儿,老婆唱生日歌


一周岁有了个进步,以前总是叫“爸爸”很容易,叫妈妈很困难,半天才出个妈音。生日这天有变化,已经能比较轻易发出妈妈的音了。现在可以发音的有“爸爸,爷爷,奶奶,妈妈”另外再加个“奶妈”,叫妈妈没叫好的时候叫出来过。呵呵~~


另外人家别人的孩子都有了小男朋友,小女朋友了,俺们汉宝儿已经一周岁了,还单身呢,所以呢,这也征下小女友啊,放个照片,小家伙有点腼腆:






2010-12-09

几道java题

前阵子有个活儿,要出几道java题,主要考察:java基本,常用算法,annotation based spring/Hibernate(JPA) 是否熟练,每个部分不超过3个问题。 回答环境没有电脑,只有嘴+白板,时间尽量控制在60分钟以内(包括交谈)。现在这题已经用完了,翻译成中文贴这了。 不知道是不是整的太简单了。



java基础的 (2,3里选1题)
---------
1说运行结果: (预计2分钟)
Integer a = 707;
Integer b = 707;
System.out.println(a>=b);
System.out.println(a<=b);
System.out.println(a==b);  

a = 70;
b = 70;
System.out.println(a>=b);
System.out.println(a<=b);
System.out.println(a==b);  

2 如果一个类的一个private属性没有setter/getter方法, 这个属性的值可以被其他类获取/修改么?(如果回答可以,how) (3分钟)

3 简单介绍一下jvm的"warming up"。

4 通过class diagram(UML) 描述所有知道的java collection framework的classes 的相互关系。 (15-20分钟)

简单算法 (选2个问)
------
1 描述 Quick sort (5分钟)
2 描述 筛选法求质数 (5分钟)
3 如何存储稀疏矩阵 (3分钟)

Spring/Hibernate/jpa
----------------
1 什么是nested transactions? 具体在hibernate和JPA 的环境下如何定义(annotation based)?(1-2分钟)

2 下面伪代码的TryItOut class 中 tryIt()方法执行过程中,数据库会发生下面那种变化?说原因(5分钟)
    a - 执行完毕后,数据库没发生变化
    b - 当执行processList()方法,在for loop中处理List l中的元素的时候,每执行一次doUpdate(e), 数据库的相应记录将被更新
    c - myservice的processList方法执行过程中,数据库无变化,当该方法执行完毕,List l中的相应记录在数据库一次被更新。
public interface MyService{
    void doUpdate(Entity e);
    void processList();
}

@Service
public class MyServiceImpl implements MyService{
    @Autowired
    private EntityDao dao; // assume that EntityDao has methods doUpdate() and getAllEntries()
    
    @Transactional(readOnly=false) //declare transaction
    public void doUpdate(Entity e){
        dao.update(e);
    }

    public void processList(){
        List<Entity> l = dao.getAllEntries();
        for(Entity e : l){
            //here do some changes on the entity
            e.setX(foo);
            e.setY(bar);
            ....
            //now we want to do database update
            doUpdate(e);        
        }
    }

}

public class TryItOut{
    @Autowired
    private MyService myService;
    
    public void tryIt(){
        myService.processList();
    }
}

3 下面的代码片段意图是在OneBean实例化的时候利用其它的spring bean来初始化title属性。有没有问题,为什么?如果是有问题,如何改正? (5分钟)
@Component
public class OneBean{
    @Autowired
    private AnotherBean bean2; //Assume AnotherBean has property: String title, with getter and setter.

    private int a = 5;
    private String title = "OneBean_" + bean2.getTitle();

    //some other codes
    .....

}

简单说下想法

1.1,这个可能很多人都被问过。主要就是那两个"=="的比较。java是比较引用的,但是有个autoboxing。如果有这个意识,很容易就能答了,707的==,是false, 70 的 == 是True。

1.2 reflection可以实现

1.3 这个warming up的问题曾经遇到过。尤其是那种效率要求比较高的消息处理应用,应该避免jvm warming up的这个阶段,因为这个阶段速度比较慢。

1.4 collection恐怕是最常用的基本点之一了,所以这个得心里有数。

2算法的都是常用或常识的,不说了。

3.1 nested transaction JPA 不支持
3.2 应该是a,数据库无变化。 因为spring是proxy based aop。transaction manager也是要以proxy来管理transaction. 尽管那个update方法定义了transaction,但是调用的时候没经过proxy,是自身类里调用的,所以压根transaction manager就没起作用。虽然不报错,但是数据库没有变化。这个在spring文档关于transaction manager里有写,也是平时容易犯的错误之一。

3.3 这个在spring bean初始化的时候会报错,也是常见错误之一。因为bean2还没injected呢。 如果非要用spring bean来初始化另一个spring bean的成员变量,可以写一个方法 init()来做,然后定义这个方法的annotation为@PostConstruct 这样在这个方法里就可以引用已经injected bean了。但spring 缺省单例模式,这个要注意。

2010-11-24

转换汉宝儿的视频

老婆夏天在国内和汉宝儿呆了3个月。拍了不少视频,都是高清质量的mov文件。1,2分钟的视频就2,300mb。 总共拍了好几十个GiB。 这回来整理的任务就交给我了。首先得转换一下,mov的格式怪特殊的,还是avi比较好,另外文件的体积也可以相应地进行压缩一下,高清质量有时候没有必要。而且找这个情形拍下去,这硬盘肯定吃紧啊。

幸好mplayer带一个mencoder,可以执行很多视频相关的任务。 我对视频了解的也不多,只能研究man page + google, 能实现我所需要的这点功能就得了。

于是写了个小脚本,来做这个工作。 从技术上说没啥含量,就是一条命令,只不过一些参数被写死,比如bitrate, 2500 (SVCD质量), 音频,视频压缩编码(mp3, mpeg4)等;一些参数由用户给出。主要就是原始视频文件和视频尺寸(scale)。

脚本在这里:

ky_cv

要是像这种批量处理,就可以再写个脚本遍历目录里的原始视频文件,逐个转换,然后根据原始文件的日期来重命名或者分类。最后删除(可选)原始视频文件。这个脚本没什么意思就不贴了。

如果要快点,可以把要处理的目录分成2部分,分别进行批量转换同时进行并行处理。

脚本启动了以后,打开很早以前下载了但却一直没看的Pacific (血战太平洋), 看了4集。再看视频文件,所有视频的压缩转换和整理都已经完毕。

也许有更好的方法在linux里来做这种工作,谁知道的就指点一下。

btw, 上周日第一次在linux用视频语音聊天(skype),跟家人一起看汉宝儿的live show。效果还不错。 ;)

2010-11-16

要抓问题特性,少走弯路: Jboss集群下transaction-like队列管理

最近几天一直在解决一个工作上的问题。 在这里记录下来,以后用到可以参考。

有时候脑子真是就往一处使傻劲。看来直觉有时候是好的,但是有时候还是需要站在高处来看一下问题的特点,根据问题的特点来寻找解决方案。

以前做了一个项目,其实是个中间件,接受客户机的HTTP (get/post) 请求,然后按照一个比较复杂的逻辑,转换成特定格式的HTTP, SOAP或REST请求,最后发送到另外一个系统(blackbox),读取该系统的返回值,再返回给特定客户机。对那些特定的需要较长时间的请求(一个客户请求可能最终转换成包含上万个SOAP请求,并包含gpg, scp, ftp等子任务),为客户机程序提供callback接口,来查询工作状态。

简单图示:


最近,客户提出一个改动,说那个blackbox的系统,会定期down掉几个小时。这个downtime是可以提前预知的。现在要求,在黑盒子down的这段时间,对于那些不是需要长时间的请求,进行队列管理,也就是我的中间件(叫它MW)要对这些请求入队,等DOWNTIME过去以后,再dequeue,发送到黑盒子系统。

有几个需要注意的地方。
  •  对于每个客户的请求是transaction like的。要一个接一个地发送。就是说,某客户发了请求1,2,3,向黑盒子发请求的时候,要先发1,1处理完毕,再发2,2结束再发送3。因为3个请求有可能是“创建数据”,“查询数据”,"更新数据“. 【顺便说一下,尽管specification上写的是transaction-like ,但是我觉得这个词用的并不合适。因为涉及到transaction 就有ACID,就是like起码也有rollback等特性,这些在这个项目中并没体现。其实 for the same Client, a request should not be dequeued and sent to BLACKBOX until receiving the response of previous request 的描述更恰当些】
  •  集群环境队列的同步以及并行dequeue的调度。
  •  downtime过后,因为有可能我的MW仍在处理队列中的请求,所以从客户新进的请求仍然可能会进行入队操作,而不是直接转换,发送到黑盒子。
  •  jboss(任一或全部)down再start,不影响整个队列操作。

有点难的地方就是既要让集群最大发挥并行操作的作用,又要保证客户请求的transaction-like。另外还有个2个jboss的同步问题。

开始考虑可以用JBOSS的HASingleton服务来做队列管理。后来发现,HASingleton是server层上的一个服务,用于这种情况并不合适。

然后就想怎么才能解决上面提到的那个困难。2个JBOSS的同步,还是得通过数据库,否则要做的东西太多了。所以就一直打算数据库里有个全局的flag,根据它,MW来做enqueue还是直接发到黑盒子。但在细小的地方总不是太保险,主要体现在2个JBOSS状态同步上。而且,这样一来,其实同一时间,只有一个JBOSS在工作,另一个必须等它完成了才能取队列里下一个请求。 在这上费了些时间,总不能完美解决问题。

前天晚上陪儿子玩的时候一想,既然这个"transaction-like"是存在单一的客户机身上的,为什么不每个客户设2个FLAG,一个是是否enqueue,另一个是是否有JBOSS在对这个客户进行dequeue。如果一个客户的请求在队列里已经没有了,再有从这个客户来的请求,MW就可以直接发送到黑盒子了,尽管队列里可能还有其它客户发来的requests。更重要的是,这样,就可以按客户来取队列里的请求,2个JBOSS也就可以同时工作了,效率也提高了。于是就这么设计并实现了。


当然后来对一些小问题做了一些特殊的实现。
  • 每个jboss有个heartbeat线程,这样,一个JBOSS通过heartbeat interval可以知道另外一个是不是还“活着”。如果DOWN了并且自己空闲(没有进一步的dequeuing任务),就接管当初正被它工作的那个客户的请求。
  • 当一个JBOSS着手处理一个客户的请求的时候,数据库记录下这个客户的ID。这样当这个JBOSS DOWN了,再启动后,可以知道之前的工作情况,以便继续工作 (如果还没被另一个JBOSS接管)。
  • DOWNTIME的标志由quartz来负责维护。它本身就支持cluster,所以省了一些事。