本来一直打算等到09年初再考虑跳槽的,目前最大的需求是把助学贷款还完。一个非常偶然的机会,听说说周末有个华为招聘会,于是决定碰碰运气。如果再加上这次去华为面试我已经是第三次参加华为的面试了:第一次是还没毕业的时候,在夫子庙状元楼那次,第二面就挂了,还花了我50块钱打车回江宁,亏死了。第二次是在年初在江苏议事园那次,等我冲锋陷阵到最后一轮时,一个领导跟我讲,这次我们招聘的是08届毕业生,于是又铩羽而归了。

     今天是周三了,距上周六面试已经过去好几天了,自己甚至有有点奇怪自己这几天来会这么淡定:从早上八点半开始,到下午五点钟结束,过五关斩六将,仅仅在第五面结束时和我谈薪水后稍稍有点激动,回来后就没什么感觉了。一整天中接触到不少华为内部的人:技术人员,hr,前台mm,经理等等,除了第二轮有点压力测试的意思,稍稍感觉有点累,其他几轮都比较轻松,人都比较nice,没有传说中那么压抑。

      下面就按顺序说说那些让我感觉很舒服的人吧:第一轮技术面试,是个长得蛮慈祥的中年人,让我挑个比较有心得的项目说说,说说自己的职责以及体会,他对我说的内容也比较感兴趣,聊得也蛮投机的 。感觉自己现在和陌生人谈话已经能够比较放得开了,不会有太多的紧张的感觉,可能是工作一年中的变化吧,我比较欣慰:-) 。还有就是一个HR,和我聊聊天,主要涉及工作意向,以及对自己的认识,也聊得不错。再后来就是和Boss面试了,应该是里面的一个领导,具体是什么职位我也不清楚了,看起来有三十多岁,长得蛮精神的一个人,谈的内容主要还是技术,可是这次我表现不太好,同样的一个项目,早上和那个技术人员谈论时,就很能吸引住他,下午和Boss谈时,我说得也不够清楚,所以boss也听得直皱眉头,再后来他问我在这工作的一年里有没有自己去尝试着总结一下什么,比如自己做些小工具什么的。这下难住我了,平时开发也就在IDE里敲敲打打,最多在有些时候用点ant,我印象比较深的还有自己写程序去帮我做一些比较枯燥的“copy-paste”的事情(这个是我现在才想起来的,当时完全忘记有这回事了)。可是这些东西还不够抽象,还没有到达小工具的高度。后来他举了个例子,说比如调试程序时,要用查看log怎么办,我说log4j啊,按不同级别输出到不同的地方(文件或者控制台),原来这些东西我一直在用了可惜就是没有注意总结,和这位boss的面试在后半部分还不错了,在最后,boss给了我个建议,“基本素质不错,但平时多做点总结,善于总结才能提高效率”。 一个陌生人能够对我提出这样中肯的建议,我蛮感谢他的。最后谈到待遇问题:预计是在5k 到6k,具体等总部审批过后才知道。

     确实华为在很多人眼里有点过于压抑,现在提供的待遇也不如以前那么有竞争力,我想我应该能够承受得住,至少能够从现在的公司里跳到一个大的公司也不错,以后的路会很宽阔。

     现在还在等消息,虽然说5面全过基本上问题就不大了,但是我也不报太大期望,就像我在那次集体面试时报的心态一样,放下担子,你的效率会提高很多,而且即使失败了,也不会太过沮丧,默默收拾行囊,重新来过。

    

    公开课:
    最近看了两个比较有名的公开课:《公平》和《幸福课》
     《公平》告诉了我:在很多时候,人们不得不做选择,这些选择没有对错,只是代表了每个人不同的价值观。
     正是这门课程,颠覆了我从小就被教育的非对即错,非黑即白的观念,那些被我误解了的人们,在这里跟你们说声对不起,原谅我当年的无知与鲁莽。

     《幸福课》的老师刚出场的时候,他身上的那种气场就感染了我,即使是通过电脑屏幕,你依然能够从他的动作,他的眼神、他的语气上感受到他身上的那份宁静,心如止水,宠辱不惊。记得有这么一个笑话:“幸福是什么?幸福就是,我能吃着,你看着,我坐着,你站着”。这是最简单的物质的幸福,试想:当你从那个"看着"、"站着"的人变成"吃着"、“坐着”的人的以后,你得到幸福了,然后⋯⋯  你的幸福感会持续多久?现在我还记得自己得到第一个手机、第一个笔记本电脑、第一个MP3播放器、第一个智能手机、第一个iPod的那些时刻,那种幸福或许会持续一天、一周或者再久一些,但是终归会消逝于平淡,这种通过获取物质而得到的幸福感是短暂的,不可延续的。只有获得了精神上的宁静,幸福才是长久的、延续的。
 
     团队:
     再来说说团队里的事情,前几天跟一个一起入职的同事聊天,都谈到了一种共同的感觉——因为事情比较少而感到了一种不安全感,其实就是姜鹏的这篇博客 里提到的存在感,一个人在团队里有了存在感,这种不安全感就会随之消失。

     自己:
     再来说说自己,综观自己这短短二十多年里遇到的各式各样的人,有一种人看起来总是眉头紧皱,脸色阴沉、有着说不完的抱怨,你能明确地感受到——他/她不快乐。然而也有另外一种人,你总是在某个时候听到他/她爽朗的笑声,你很少能够听到他们的抱怨,他/她有很多兴趣爱好,总是有说不完的话题,也很乐于分享。不幸的是,我更接近于第一种,而在ThoughtWorks,你会发现大多数人都更接近于第二种,同样,放下轻车熟路的java进入ruby&rails 的世界也是。都会让我感受到一些压力。一开始,是有点不适应,在读了《哪来的天才》这本书之后,对于这种压力有了新的认识,对于我来说,是从“舒适区”进入了“学习区”。这才是进入了提高的通道。

     同事:
     最近公司邮件组里发起了关于如何在国内开展Social Impact Project的大讨论,其中有个比较好的点子是:帮助留守儿童与他们外出打工的父母保持联系,以弥补空间带来的情感上的隔离。我才意识到原来这帮人不仅仅是在为自己讨生活,他们确确实实在考虑着如何通过自己的一点努力来帮助那些需要帮助的人们,能与这样一群人一起工作,真是一件很幸福的事情。

看了下上次博客发布的时间,9月9号,今天已经18号了。这几天一直在做一个模块,是对Ajax请求做响应的,后台的逻辑处理比较复杂,所以最近一直比较忙。现在那个模块功能基本上已经完成了,写点东西来总结下。

       先说前台:以前从来没用过ajax,原理也比较简单,就是用javascript模拟一个http请求,然后从服务器返回的response中读取返回值并显示在某个DIV里。现在的处理方式是在后台把数据的表示形式都拼好然后再通过response写回给浏览器。觉得这种实现方式好丑陋,.java文件里一堆的html代码,应该有更好的方法,研究中。                  

       再说后台: 后台的逻辑是按照基本设计书的描述来做的,从一个过程化的描述分析出一个个的domain确实是个挺痛苦的事情,有时候好多对象都是被创建删除多次。在创建对象的过程中,我一直把尽量把逻辑放在与之紧密相关的对象中(难道这又是贫血模型的思想?),这样在后期调试的时候,出了bug能够很快定位到与之相关的代码,而且最大可能地重用了代码。

    收到消息,下面又要进那个大的国际项目了,公司对这个项目比较重视,希望能够看到一个清晰的程序架构,能够从老员工学到一些东西。 抽空再看看《深入java虚拟机》,多了解下底层的东西,为自己增添些砝码。

         给一个现有的项目添加新功能,需要对数据库做更新:写SQL语句,创建PreparedStatementd对象,绑定参数,执行statement,提交事务,很简单的一件事。然而这里问题出现了,log里生成的SQL语句看起来异常地正确,但是却不能对数据库里的数据更新,JUnit运行失败。这个项目的框架构建者对PreparedStatement自己再做了层封装,实现了一个logable的PreparedStatement,所以日志里的sql都是和参数绑定好的,拿来在SQLDeveloper里运行,很完美,数据被更新了,得到了预想的结果。怎么会这样?挠头中……

         分析原因:SQL不正确?没有提交事务?仔细检查下代码,两个假设很快就被否定了。想什么招呢?从更新条件下手,总共有三个更新条件(where A= ? and B=? and  C=?)先把要更新的数据库表里的数据备份,然后修改SQL语句的更新条件成(where A = ?),运行JUnit,更新成功!然后慢慢增加更新条件,最终将问题锁定在条件B,只要加上条件B,JUnit就失败了,再看绑定B的那段代码:

  stmt.setString(2, XXX); 

再看数据库里的B对应的那个列的类型,是 Char(12)

查看了下Oracle官方网站里对数据类型的解释:

<table border="1" width="100%" style="font-family: Helvetica, Arial, Verdana, geneva, sans-serif; font-weight: normal; font-size: 100%" bordercolor="#A6A6A6"><tbody><tr style="font-family: verdana, geneva, helvetica, sans-serif; font-weight: normal; font-size: 100%"><td width="17%" style="font-family: verdana, geneva, helvetica, sans-serif; font-weight: normal; font-size: small">CHAR(size)</td><td width="18%" style="font-family: verdana, geneva, helvetica, sans-serif; font-weight: normal; font-size: small">Fixed length character data of length size bytes. This should be used for fixed length data. Such as codes A100, B102…</td></tr></tbody></table><p> </p><p>Char型是定长的,在这里DB里的数据都是12位的,长度小于的12的数据被存放到这个域时,oracle会自动用空格补足称12位。‘abc         ’和’abc’当然是不相等的。 </p><p>修改sql语句,改为“TRIM(B)= ?” ,再运行,更新成功。</p><p>这个问题虽然不难解决,但是解决问题的方法却也是值得mark下的。 </p><p> </p>

遇到这样一个需求:

     A = 1时,B=1

     A=2时:
     C(一个小时内的一个时间点)在00~29之间时、B=1。
     C在30~59之间时、B=2

     A=3时:
     C在00~19之间时、B=1。
     C在20~39之间时、B=2。
     C在40~59之间时、B=3。
     A=4时:
     C在00~14之间时、B=1。
     C在15~29之间时、B=2。
     C在30~44之间时、B=3。
     C在45~59之间时、B=4。

看起来一个稍复杂的需求,难道用"if else" 或者“switch”?我周围真有人这么干的。

再仔细观察下,用如下程序可以解决:

     int B= (C+1)/(60/A);
       
        if((C+1)%(60/A) > 0){

               //对B取上界

                B++; 
        }

小聪明而已,写下这个只是想提醒下自己,在编程时 “要用最少的代码最好地完成最多的事”