我的技术和生活

  • NerveNet——俺也开始写框架了!

    感谢姆二,如果不是你,这篇文章和文中的框架可以提前半个月面世。我爱你和你妈。

    本文说明了我设计此框架的意图和实现的方式,框架本身还没写完。

    NerveNet(神经网)是一个JavaScript框架,帮助我们创造命名空间、生成事件总线,并进行依赖注入。未来它还会管理依赖,处理编译输出。

    我给框架命名时从Backbone那里获得了灵感,因为使用Backbone时发现各种欠缺,在逐步修补它们时,这个框架渐渐成形了。我希望,一,它能弥补Backbone欠缺的地方;二,不要依赖Backbone,以便在更多场景中发挥作用。

    (更多…)

  • 姆二诞生记

    姆二诞生记

    有道是瓜熟蒂落,经历过十月怀胎,终于到了一朝分娩。

    离京之前,虽然日子离预产期越来越近,但是可能因为工作安排的比较满,我一直没有特别紧张的感觉。终于,21号晚上,老婆打电话给我——手机一响候我就预感,这个电话内容非同一般——接起来一听,见红了,我瞬间紧张了起来。

    不过如我所说,我一直希望自己能够时候保持冷静,于是我尽量沉着的,拿出另一部手机,Google见红的定义以及还有多久会生(现在你们知道我为什么随身带那么多手机了吧)。确定还有几天准备时间之后,我稍稍安了心,然后和老婆确定了预备事项。

    23号一早,我飞去重庆,见到老婆,她表示还好,除了见红没有其它临产特征。于是我们一起吃了青蛙和烧烤,心满意足的上床睡觉。没想到姆二在肚皮里感知到我已经到位,当晚就折腾起来,第二天我们就住院了。

    在北京产检期间,我们深感医院人多之苦,决定在老家生产,并选择了重庆收费较高但是技术服务较好的金山医院作为姆二的诞生地。事实证明这个抉择十分英明。

    虽然之前上过课读过书,知识储备和心理准备自觉都不错,但到了临床才发现完全不够。老婆的宫缩比较奇葩,站起来走动,频率就会提高,很快就达到5、6分钟一次;一旦躺下,又会逐步降低,直到12~16分钟一次。结果,第一天的宫缩几乎徒劳无功,第二天助产士一验,宫口没开。

    没有办法只有继续等待。第二天的宫缩更痛了。然而一白天过去,宫口仍然没有进展。老婆渐感力不从心,我们商量了下,决定如果第三天还是这幅阵仗就直接剖了。熬到将近午夜,转机终于来了,助产士一摸,说开了将近一指头,有希望!周期性的宫缩让人根本无法入睡,于是医生开了支杜冷丁,打下去后我们都抓紧时间睡了觉,准备迎接次日的决战。

    我们一开始就打算上无痛分娩,刚好有一支美国团队在这里推广相关技术,所以第二天就跟他们确定了手术方案。但是老婆宫口迟迟不开,无痛也没法上,只能忍。第三天,宫口终于达到3cm的标准,于是马上开始无痛。老婆事后表示,美国人的药真好,打下去人立刻就放松了。

    在无痛和催产素的双重作用下,宫口迅速从3cm开到10cm,速度快到我不敢相信——尼玛这是打巫妖王的节奏啊,脚男们费死劲把阿萨斯搞到10%血,老弗丁一脚踹碎冰块手起刀落战斗就结束了……总之,第二产程开始,也就是真正的生产。

    这里我们遭遇到另一个难题。姆二的胎位不是很正,入院时B超显示枕横位,比之前的枕后位要好,但仍属于难产的类型;老婆挂着麻药,感觉不到宫缩,没法用劲。我们折腾了快1个小时,收效甚微。护士长马上跑去请示美国人,是否可以停药。这里必须批评美国人太教条了,他说没关系,让医生把手伸进去将胎儿的头转过来就行——问题在于,这边的医生也好助产士也好,都没这么操作过,直接临床就搞根本不可能;美国团队只有麻醉医师,没有接产医师,所以他们只能检查埋针和配药,无法帮助生产。

    事后证明,在场医生护士的抉择都是正确的。护士长和医生商量了下,把麻药停了,准备利用宫缩正胎位。过了一会儿,她发现老婆已经很累了,胎位似乎没变化,于是建议我们剖;我们俩处在崩溃边缘,立刻就同意了。护士长就出去准备手术,一边的助产士上前来,说老婆的宫颈骨盆情况都很好,姆二也不是很大,按理生的出来,喊我们再努力下。这时候,麻药劲儿已经下去了,老婆顺着宫缩用了3把力,竟然能看到姆二的头发了!

    助产士马上打电话给护士长取消手术,并召唤医生前来接生。呼啦啦屋里一下涌进来5、6个人,有医生有护士有助产士,还有实习的。我们先把老婆驾到厕所,利用坐便、宫缩、地球引力,把姆二的胎位彻底正了过来;再扶她继续躺在产床上努力。姆二的身体真不错,相当争气,胎心始终不乱。这次努力了40分钟,终于在15:54分,姆二完全生了下来,被医生扔到老婆的肚皮上,嗷嗷哭了两声,就睁开眼睛打量这个世界。

    目睹这一切后,我相信再过很多年我也能清晰的记得那个画面。不过我当时的心情很复杂,有点想哭,很激动,也有些茫然,然后,一首歌开始在我脑海里单曲循环——《The Circle of Life》。

    可能由于激动的缘故,之后的记忆比较含混,我走出产房给家人报喜,打电话发微博发微信;然后回病房;然后出院;然后抱孩子,换尿布,喂奶……然后,我就回到北京了,15天一晃而过。

    无论如何,当爹了,要更努力了!

    对了,从我们住院起,开始下雨;当老婆生完回到病房,云开日出,阳光穿透云层射到医院中庭天井花园中,煞是辉煌。我心中不禁暗暗叹道,姆二还真是奇人自有异象啊。最后上张新妈志得意满的照片。

    老婆和幺儿
    生完第一张
  • 买车记

    买车记

    搬家之后,我和老婆惊喜地发现,楼下的停车位似乎挺富裕,不像以前那样每天早上推箱子;而且停车费也不算贵,于是买车就被提上了日程。

    老火的是,我们还没牌。虽然来北京工作将近7年,中间未曾中断过,但是09年换工作的时候,因为两家公司的发薪日有差,导致社保中断了一次,于是到现在仍然没有摇号的资格。所以必须找些旁门左道。开始准备找神州租车,后来他们的销售有头没尾的玩消失,又没留下联系方式,只得作罢,准备租4S店的牌子。

    选车的过程没什么新鲜的。因为是第一辆车,准备买个10w左右能开就行。后来在汽车之家上看着看着就奔15w去了……最后确定买亲戚推荐的菲翔。选择菲翔一来相中他的样式,二来想追求与众不同,这款车比较少见。少见的表现就是全北京只有两家菲亚特的4S店,这也省事儿了,正合我意。打电话一问,其中一家的车牌是委托另外一家租赁公司做的,在我看起来似乎比租4S店的牌要靠谱一些。于是就决定买他们家的了。

    之后就是买车、选车、去租赁公司办手续,然后就是漫长的等待。因为中间手续比个人繁杂,租赁公司又要休周末,所以这一办就整整办了15个工作日(连双休19天)才拿到车。车长什么样我都快忘了……

    菲翔
    车牌还不错

    车到手后面临一个尴尬的境地:公司搬到我家附近;北京道路几乎随时都堵着。开车的机会少之又少。

  • 也谈提升代码可读性的小技巧

    看完了《编写可维护的JavaScript》,觉得他技巧性的东西讲得太少,还不如看《重构》来得实在。这里分享两个我常用的优化代码的技巧,好学常用。范例代码用的是JavaScript,其实几乎所有语言都用的到。

    逻辑扁平化

    我们工作中,可能会碰到一些比较复杂的逻辑,比如:满足条件1,不然XX;满足条件2,不然XX……如此都满足了才OO,写出来大概是这样:

    if (condition1) {
      if (condition2) {
        if (condition3) {
          // do
          // a
          // lot
        } else {
          // do zz
        }
      } else {
        // do oo
      }
    } else {
      // do xx
    }

    这样带来的结果就是逻辑嵌套后显得很复杂,不好读。如果再赶上缩进没搞好或者换行就更惨了。这个时候,通常可以提前中断代码执行来使得逻辑扁平化。提前中断的方法包括returnthrow,以及PHP中的die()exit()。重新整理后的代码如下:

    if (!condition1) {
      // do xx
      return;
    }
    
    if (!condition2) {
      // do oo
      return;
    }
    
    if (!condition3) {
      // do zz
      return;
    }
    
    // do
    // a
    // lot

    当然,有例外情况要排除的地方也很适用这种方法。甚至有激进的言论,表示不应该使用else,而都要这样提前中断。我觉得那样也有点过分,if ... else ... 的意义还是非常明确的。

    缩短超长逻辑判断

    有个从上古时期传下的不成文的规定,一行代码80个字符。随着显示器变大,这个老规矩应该打破。但是单行代码太长的话左右看起来也会很累,所以我们还是有必要控制。超长的代码经常出现在逻辑判断里,比如游戏中常见的检测子弹有没有打中玩家的代码,用较好的格式写出来大概是这样:

    if (bullet.x > enemy.x + enemy.width || bullet.y > enemy.y + enemy.height || bullet.x + bullet.width < enemy.x || bullet.y + bullet.width < enemy.y) {
      console.log('没打中');
    }

    这就已经不短了。有些时候我们还要加上enemy.damagable、!enemy.immunePhysical之类的其它条件判断,把这一行写的特别长。这个时候就需要我们用点小技巧将它缩短了。方法可能有多种,思路是一致的,就是提炼“目的”——将某一组判断的目的提炼成一个变量,既好读又能缩短代码。接下来还是用一段代码来说明吧:

    var isGod = !enemy.damagable || eneymy.immunePhysical, // 判断敌人是否不能攻击/上帝模式
        isHit = bullet.hitTest(eneymy); // 将刚才那一大串抽出方法“碰撞检测”
    if (!isGod && isHit) {
      enemy.die();
    }

    总结

    这两个小技巧都很简单,但对代码的可读性提高却很显著。各种各种的小技巧叠加起来,会让代码更好读,更容易维护。

  • 书评:《编写可维护的JavaScript》

    书评:《编写可维护的JavaScript》

    编写可维护的JavaScript
    书的封面

    评价:

    3星。如果手头宽裕,或者公司给买就买本看看。如果觉得自己水平欠佳,也推荐学习下。不然就算了。

    其中内容3.5,编辑2.5,综合起来就是3星了。

    适合人群:

    • 缺少规范编程训练的开发者,比如学生
    • 对整个开发环境缺乏了解的新人

    读后感

    很早就关注这本书,当时还只有英文版,前几日看到中文版上线,又是淘宝几个人译的,就赶紧买了,结果看后大失所望。

    最让我失望的是书里印刷错误很多,甚至连!=都能印成!==(第50页),估计道行浅的看到这儿就迷茫了。全书我看得比较细的是前面8章,几乎每章都有错误,实在让人如鲠在喉。

    整书的内容偏浅,讨论的多是差不多的几种方案选择其一,比如空格缩进、4空格2空格、注释要不要有空行之类。其实这种东西绝大多数语言都会涉及到,也没什么好坏之分,团队领导随便选一个就是了。真正对代码质量有较大帮助的是命名空间(第6章)、UI层解耦(第5章)、事件和逻辑接偶(第7章)。读完这几章本以为书会渐入佳境,结果后面都是很浅显的否定浏览器推断的做法,以及介绍使用Ant进行编译,就没什么意思了。

    在我看来,有些内容是不用多说的,比如用浏览器推断某种方法是否存在,提一嘴就行了;有些内容则是初段码农和高阶程序员的分水岭,这才值得大书特书。比如,复杂逻辑的扁平化处理、超长条件分拣成更易读的名字、模式的应用、大型项目的架构、消息机制,等等。可惜这些书里都没有提。至于Ant的介绍,至少我这种半路出家的非Java开发者并不熟悉,倒是直接node.js+grunt用起来挺顺手,而且每家公司的工具使用状况也不一样,是否直接写好几章真的有待商榷。

    我认为,如果自我感觉缺乏系统可靠的编程培训,可以看看这本书。如果想真正提高自己的代码质量,这本书价值不高。

  • 在某公司的那些年——最后的日子

    这篇日志很不好写。回去后,虽说过的不好,但是承蒙老板错爱,进入管理层,得以看到听到很多别人不知道的消息;这样一来,杀伤力大了不少,也就不能再放心吐槽。所以这篇文章可能反倒没有什么劲暴内容,等着看热闹的同学可能无法如愿了。

    (更多…)

  • Phonegap 2.6在Android上的Icon设置

    这个问题Google了半天也没找到答案,难道只有我碰到了?

    我的测试平台:Windows 8 + Eclipse 4.2 + ADT 21.1 + 小米 2 + Phonegap 2.6。

    开发测试一切正常,只是编译输出的应用装到手机上只能用默认图标,怎么都改不过来。我把所有res/drawable-xxxx里面的icon都换了也不行。然后修改AndroidManifest > Application > Application Attributes里的icon和logo设置,也不行。怎么试都不行,Google也找不到。安装时提示的图标正常,查看运行过/运行中的图标也正常,就那个桌面上的图标不对。

    刚才吃过饭,来回点,突然发现在Application Nodes里有个Activity,还可以设置icon和logo,想着反正也不亏,就也给填上了,居然OK了。

    哎,记一下,省得以后忘掉。

  • Phonegap 2.5的localStorage有Bug

    这两天重拾Phonegap发现一个Bug,用localStorage保存的东西,更新版本或者关掉重进就没了。我的环境是Phonegap 2.6 + Miui V5(Android 4.1)。

    我逐个尝试了使用window.localStorage替代localStorage、将调用localStorage的时机改到deviceready后等做法,均无效。Google、StackOverflow,亦没有结果。最后想起来,Phonegap不是开源的嘛,有issue list啊,一看,果然,从2.5开始Android版的localStorage就无法正常持久存储了。这个Bug要到2.7才会修复。

    以前还是太低端了,以后还是多逛逛Wiki和issue才是。

  • 《北京遇上西雅图》中的孕期误区

    电影《北京遇上西雅图》很好看,汤唯真女神,吴秀波演绎的伪屌丝也挺到位。不过里面难免会有一些镜头不够科学,都是影视剧中常犯的怀孕和生产错误,我决定科普一下产前课上所学的知识。

    (更多…)

  • 推荐类库 jquery-ui-touch-punch

    正如我在前一篇文章《前端框架点评》中所说,jQuery UI库中最有用的是那几个 xxxable,而不是里面的组件(因为自带样式且较丑)。所以当它们在某些环境下没法正常工作就比较老火了,比如draggable,在iPad之类的移动设备中,就无法使用,因为它没有针对触摸事件进行侦听。

    经过Google,发现有人已经解决了这个问题,就是我说的jquery-ui-touch-punch,开源,代码托管在github。直接在html中引用jQuery UI和这个补充包,后者会覆盖前者的实现,帮助它支持触摸拖动。感兴趣的同学可以到这个页面去尝试。感谢它的作者furf

    顺便说下我对开源、免费、盗版的态度。开源和免费都是好东西,影响着改变着我们的世界。但是决定一个作品一段代码一款产品是否开源免费的人,只能是其作者或者其版权拥有者,别人无权“替”他们做出选择。换句话说,我是反盗版的,对于海盗湾也无甚好感,对于那些有意无意忽视盗版危害反而替海盗湾摇旗呐喊的人,很是反感。

    现在的版权政策和专利制度,确实在某种程度上阻碍着创新,也给流氓(比如苹果)留下可乘之机。但是在更好的方案出台之前,我们只应该尽力输送好的原创作品给开源社区,而不是盗版他人的东西,再冠以自己“开放、分享”之名。那样太无耻了。