Macbook pro 更新镁光 M4 固件

11年上半年买的镁光 M4 SSD,最近两天老是无缘无故的死机,尤其是编辑完代码,保存的时候,猜测是硬盘出了问题。记得当时看到 M4 的固件是有缺陷的,工作时间超过一定时间后,在 windows 就会蓝屏。只是由于懒,一直没更新固件,今天被迫更新完固件,就不再死机了。

如果你的情况和我差不多,请继续往下看升级固件的过程。

1, 在 http://www.crucial.com/support/firmware.aspx 这里找到你用的型号,如果和我一样,就选择 Crucial m4 2.5-inch SSD 。

2, 下载 Manual Boot File for Windows and Mac® ,解压得到一个 ISO ,顺便可以看看官方的 instruction guide, 有中文文档。

3,如果你的 Macbook 有光驱,身边有刻录盘(CD 或者 DVD 都可以),用 Mac 自带的磁盘工具刻录此 ISO 镜像。

4,光盘放入光驱,关机。接着开机,同时按住 option 键。如果你的电脑能在选着启动盘的位置直接看到光盘,那就直接启动。如果不能看到,选择 recovery HD,从恢复盘启动成功后,点左上角的启动磁盘,可以看到下图:

选择启动磁盘

如果看到左边的有 windows 图标的光盘,那恭喜你,快成功了,选择它,启动磁盘。

5,升级固件工具会自动寻找符合条件的硬盘,中途需要手工输入一个 “yes” 进行确认,然后等待它自动升级,直到看到升级成功的提示。

6,退出光盘,按住电源键强制关掉电脑,重启,完成。

如果你的电脑支持从 USB 启动,也可以用官方文档里给的创建 USB 启动盘的方式来创建启动盘(需要一台 windows 机器),不过我使用此方法没成功,机器不能从此 U盘启动。

发表在 Mac | 3 条评论

Javascript API alfred workflow

Alfred 2.0 是 Mac 下的一个提升效率的软件,可以搜索应用,搜索文件,使用的是 spotlight 的索引,所以非常快。还可以直接使用 google 搜索,自定义搜索,还有很多其他功能,你不妨点开上面的地址去看看。这里要说的是它的 workflow 功能,可以自己写代码去处理输入的 keywords ,然后指定打开某个 URL ,或者执行某个命令,打开某个文件等等等等。

http://www.alfredworkflow.com/ 这个地方有很多 Alfred workflow ,这个社区还不够成熟,找东西还不是那么方便,有耐心的话,你不妨去这里淘淘。想开发的话,暂时还找不到官方开发文档,还好这东西比较简单,看看例子和别人写的,应该很容易上手。

前两天晚上,我一边摸索,一边写,做了一个查找 Javascript API 的 workflow 。看下面的截图:

截图

用过 workflow 的人一看就懂。

当然现在做的还不够好,还不能直接显示每个 API 的简单使用方法,这个等我有空再优化优化。

下载地址在这里:http://api.allenm.me/jsapiworkflow/jsapi-workflow.alfredworkflow

源码托管在 Github: https://github.com/allenm/jsapi-workflow 欢迎 fork , 欢迎 pull request .

Alfred 绝对是在 Mac 下提升工作效率的利器,用 Mac 的同学快快试试吧。对了,workflow 是需要付费后才可以使用的功能。既然能够帮助你提升效率,付点钱也值得。

发表在 tools | 2 条评论

密码保护:Bye bye , 2012

这是一篇受密码保护的文章,您需要提供访问密码:

发表在 生活 | 要查看留言请输入您的密码。

The new beginning

2012年12月21日过去了,大家都安然无恙,世界末日并没有来,所有人都重生了。我个人的工作也迎来了全新的开始。12月24号,我正式开始到支付宝上班了。

毕业两年半以来,一直在阿里B2B工作,在这里收获了很多,无论是在技术上还是其他方面都成长了不少。但是今年越来越感觉自己成长变慢了。是的,不论是谁,都不可能一直快速的成长,总会慢慢变缓。但是我还是觉得我应该去换个环境挑战一下,去尝试新的东西,或许可以唤醒差不多沉睡的激情。恰好这个时候有个机会去支付宝,那就去试试吧。

现在已经在新工作岗位一周了,很多东西对我来说都是新的。虽然还是干前端,前端的知识没有怎么变,但是各种工作环境、开发环境都是大不一样的。虽然都属于阿里集团,还是有很多东西不一样。很久没有过这种感觉了,很久没有过这种什么都要问,什么都不清楚的感觉了。我不知道是害怕,还是兴奋,或许这两种感觉都有吧。

总觉得不能让自己太舒适,在太舒适的环境下,很容易就失去战斗力,我不知道如果我在一家公司呆上十年,还能不能去换工作,能不能去适应其他公司。我觉得自己还是年轻的,所以有机会,就要换换环境,多看看不同的世界,增加自己的人生阅历。人活在这个世界上,不就去体验各种不同的事情吗?总干一种事情有啥意思,很快就是失去激情。

在B2B的这么多时间,从身边的同事身上学到了不少,在这里也感谢他们,在这里就不一一列举了,在这里列举姓名也不太好。这中间有前端、有后端开发、有设计师,有产品经理。最让我感动的,是 21 号这天,同事给我准备的礼物。同事很用心的准备了一个留言册,让熟知我的人都给我留言,还贴上我的照片。看到大家送我的话,倍感亲切,这些都是这两年多来,和我在一起共事的兄弟姐们们。我想当我不开心的时候,就拿出来翻翻,有你们的鼓励,我会走的更好。另外这个同事还准备了一个很特别的大号淘公仔,这个淘公仔是一个牛B的设计师根据我的样貌特意绘出来的。这两个礼物实在是太棒了,我已经无法用语言来表达我的感激之情。总之,感谢这位为我准备礼物的同事,为我绘淘公仔的设计师,以及在留言册上给我写祝福的同事们,你们这些朋友是我这两年来最大的收获,我会永远记住你们。

临走B2B的时候,还发生了一些不开心的事情,这里就说下吧,以后就不再提了。在运营产品的思路上,我和运营和产品人员发生了一些争执,我坚决不同意采用一些不那么阳光的手段去运营,我坚定相信,不使用这些手段也照样能把产品做起来。但是他们并不同意我,他们就开始举例微信啊、早期的淘宝啊,等等。或许是我有点理想主义吧,我一直的看法都是,并不能因为别人这样做,我们就要这样做,哪怕明知这个事情不那么阳光,违反价值观、违反道德。也并不是别人那样做成功了,我们不那样做就成功不了。不过争执归争执,我还是衷心祝福这个产品能做起来,能发展的好,这个是我最近半年来一直在为之付出的产品,多少含有我的心血,希望它好。

这应该是 2012 年的最后一篇博客了,2013 年的第一篇博客,应该是对 2012 年的总结吧,这一年我变化了很多,我收获了很多,也失去了很多,等过段时间在慢慢写吧。

未来怎么样?换个环境后,我会怎么样?我都不清楚,我只知道我会努力去把事情做好,去继续提高自己的能力。这一切不是才刚刚开始吗?

发表在 生活 | 6 条评论

通过网络共享 hosts 配置的工具

Web dev 们经常需要绑定 hosts 来切换到开发环境吧。如果你是一名前端开发,还需要去调试不同浏览器下的表现吧,经常还要开几个虚拟机。一个项目组的成员也经常需要共享一套 hosts 。那么如何方便在多台电脑之间共享和管理 hosts 呢?

自从我发现 @oldj 写的一个 hosts 管理工具 SwitchHosts 支持从 URL 获取 hosts 后,我就想为这个功能写个小工具。这几天空余时间比较多,现在这个工具的第一版已经上线了: hosts.allenm.me

屏幕快照 2012-12-20 下午3.55.39

在这里输入的每组 hosts 都会给一个供 SwitchHosts 这个本地软件访问的 URL ,在这个软件中填入url即可:

屏幕快照 2012-12-20 下午3.57.28

如果 web 端的 hosts 有更新,在 SwitchHosts 这个软件上点下更新按钮即可。

是不是该抛弃不停的复制粘贴 hosts 的方式了?

PS ,SwitchHosts 支持 Windows, Mac, Linux , 需要跨平台的同学也不必担心

PS2 ,不要用低版本的 IE 访问 http://hosts.allenm.me , 从没测试过 IE 。

欢迎反馈意见和建议,说说你工作中遇到的 hosts 的相关需求,如果现在的工具满足不了你,说不定你说出来接下来就满足你了。

发表在 tools | 标签为 , | 5 条评论

使用 SourceMap 来进行前端代码调试

今天在方凳会上做了一次 SourceMap 的分享。现在在博客上分享出来。

简介

什么是 SourceMap 呢?

在这个年代,对于前端开发来说,很少有用户浏览器执行的代码和我们写的 code 完全相同的情况。因为我们的代码一般要经过压缩、合并。另外现在还有 sass, less, stylus, coffscript, typescript 等等预编译语言。那么在这些情况下我们如何调试呢?SourceMap 就是为了解决这个问题而生的,虽然它还不够成熟,支持它的工具还不够多,但是我们能从它身上看到未来。

欲了解详情,请观看下面的 slide 吧。(有疑问或者建议可以在下面评论交流,或者微博 @allenm 进行交流)

sourcemap.001

sourcemap.003

sourcemap.004

sourcemap.005

继续阅读

发表在 WEB | 标签为 , | 4 条评论

BASE64 VLQ 编码规则

首先我们先来了解下 VLQ 是什么,VLQ 是 Variable-length quantity 的缩写,是一种通用的,使用任意位数的二进制来表示一个任意大的数字的一种编码方式。这个编码方式是在 MIDI 文件格式中定义的,用来节省空间。在其他地方也有很多类似这样的编码格式,比如在 Google’s protocol buffers 中,还有我们马上要讨论到的 BASE64 VLQ 中。想了解的更多,请参考wikipedia

我们先来看看 MIDI 中的 VLQ 编码是如何编码 137 这个数字的吧:(摘抄自 wikipedia)

  • 先把 137 转换成二进制:10001001
  • 7 bit 一组,把二进制分开,不足的补 0 ,变成 0000001 0001001
  • 把最低的7位拿出来,在最高位补0表示最后一位,变成 0000 1001,这个作为最低位,放在最后边。
  • 在其他组的最高位补 1 ,表示没有结束,后面跟着还有数据。在这里就是 1000 0001
  • 拼在一起,就变成了 1000 0001 0000 1001 .

这就是 VLQ 的变化过程。

那么什么是 Base64 VLQ 呢?和上面的变换过程有什么区别呢?

我们可以先来参考我博客的另外一篇文章,先来回顾下 Base64 编码:BASE64 编码规则

我们可以看到 Base64 是一种可以把二进制数据编码成用 ASCII 表示的一种编码规则,但是受限于 Base64 采用的字符集,一个 Base64 字符只能表示 6bit 的数据。所以上面的 VLQ 中 7 bit 一组的分组方式,在这里就要变成 5 bit 一组的分组了。

另外,Base64 VLQ 需要能够表示负数,于是规定了需要先把数字变成无符号数,用最后一位来作为符号标志位。我们直接来做一个变换吧,这样理解的最快。在例子中可以看到和上面的 VLQ 编码还是有一定差别的。

不妨还拿 137 来做示例吧。

  • 先把 137 转换成二进制:10001001
  • 由于 137 是正数,所以在最低位补0 变成 100010010
  • 按照 5bit 一组的方式分组,变成 01000 10010
  • 按照从低位到高位的顺序,以 5bit 一组为单位,依次拿出数据做转换。
  • 先拿出第一组 10010 , 因为后面还有数据,所以需要在高位补 1,变成 110010 ,编码成 Base64: y
  • 再拿出第二组,也是我们这里的最后一组,01000 , 由于是最后一组,所以在高位补 0 变成 001000,编码成 Base64: I
  • 按照从低位到高位的顺序把这些 ASCII 字符拼接起来,变成 yI

可以看到在 VLQ 中,编码顺序是从高位到低位,在 Base64 VLQ 中,编码顺序是从低位到高位。

那么如何解码呢?相信了解了编码过程后,解码过程就不必再讲解了。平时也基本不会去手工去算这些东西。这里推荐一个在线编码解码的网站:http://murzwin.com/base64vlq.html , 同时如果你想在代码中使用,Mozilla 的一个开源库里有相关实现:https://github.com/mozilla/source-map/blob/master/lib/source-map/base64-vlq.js,这个是 javascript 的实现,其他语言的实现,如果你需要,请自己找找,或者根据编码规则自己写一个。

说了这么多,好像还没讲 Base64 VLQ 运用在什么地方,这次我不打算说了,准备下一篇博客再来解释这个问题。

发表在 未分类 | 2 条评论

如果你想在 python 项目中使用 stylus

Stylus 是用 node.js 写的,所以在 nodejs 项目中集成 Stylus 是一件很方便的事情,特别是 expressjs 这样的 web framework 直接配置下就可以用了。在 expressjs 中一旦你修改了 .styl 文件,立马就会被转换成同名的 .css 文件。

如果你想在 Python 项目中获得这样的特性,不妨来试试我写的一个 python package 吧: live-stylus

由于这个 package 依赖 python stylus ,python stylus 最终是要依赖 nodejs 和 stylus node package 的,所以你还是需要安装 nodejs 和 stylus node package 的。

如果你没有使用过 nodejs ,请在 nodejs 官网查看安装方法,然后:

npm install -g stylus

即可完成 stylus node package 的安装。然后:

pip install live-stylus

即可安装 live-stylus 。使用方法非常简单,比如在一个 Flask 项目中:

from flask import Flask
from live_stylus import ConvStylus

app = Flask(__name__)

from views import *

if __name__ == "__main__":
    app.debug = True
    ConvStylus()
    app.run()

这样就可以监控你项目中的所有 .styl 文件的变化,从而实时的转换成 .css 文件了。更多的说明和使用方式请参考此项目的github 主页

发表在 python, WEB | 2 条评论

BASE64 编码规则

Base64 编码是一种可以把二进制文件编码成文本的编码规则。在很多地方地方都有用到,比如我们可以把图像转成 Base64 编码,然后内联到 HTML 或者 CSS 中。

Base64 编码用一些很常见的 ASCII 字符来表示 0-63 ,构成 6 个 bit 。用 A-Z 表示 0-25 ,a-z 表示 26-51 , 0-9 表示 52-61 , + 表示 62, / 表示 63 。那怎么把一个 byte(8bit) 用这种只能表示 6 bit 的字符表示呢?转换规则如下:

很简单吧,就是用4个 Base64 编码来表示 3 个 byte 的内容。

如果到末尾,凑不齐 3 byte 怎么办呢?如果只有一个 byte ,就在后面补4个 0 bit ,构成 2 个 Base64 编码,如果余下 2 byte ,就补 2 个 0bit ,构成 3 个 Base64 编码。理论上,这样做就足够判断最后还剩下几个 byte ,但是有些系统需要明确指明最后剩下的 byte ,需要用 = 号来把 Base64 编码的个数补全到 4 的倍数。也就是如果最后余下了一个 byte , 就在编码后的字符补上 == ,如果余下了 2 byte ,就补上 = .

有了这些知识就知道Base64的基本规则,想了解更多的请阅读:http://en.wikipedia.org/wiki/Base64

发表在 WEB | 标签为 , | 一条评论

VPS上部署 nodejs 应用并和现有应用共存

最近,nodejs 很火,我也尝试用 nodejs 写了一个小应用,主要用到了 express framework 和 socket.io ,数据库使用的 mongodb.

我有一台Linode的VPS ,自然是想把应用部署在自己的VPS上面,为什么没有选择云服务呢?一方面是省钱,我已经为Linode付过钱了,一方面是更加自由,可以随心配置。这台Linode上已经部署了标准的 LAMP 环境,跑了几个 wordpress 。那这次部署自然是不能影响到现有应用。

我的部署方案主要要达到的目的有:

  1. nodejs 应用可以像一个守护进程(daemon)一样运行
  2. 提供一对简单的命令来 start / stop nodejs 应用
  3. 提供监控机制,当应用崩溃,可以及时重启它
  4. 不影响现有 PHP 应用,但是也要用 80 端口访问
  5. socket.io 提供的 websocket 功能正常使用

下面分享下我的部署经验,不一定好,我也是第一次部署,欢迎交流。

1,在 VPS 上安装 nodejs ,我 VPS 跑的是 Ubuntu 12.04 , 最简单的方式当然是通过 apt-get 来安装,但是直接 apt-get install 的话,安装的版本比较旧,建议采用 https://github.com/joyent/node/wiki/Installing-Node.js-via-package-manager这个页面提供的方法,先添加源,再来安装,就可以安装到最新的稳定版了。这里还有其他主要 Linux 发行版的安装方式可以参考。下面的步骤默认使用的 OS 是 Ubuntu 12.04。

2,安装 mongodb (如果使用的不是 mongodb ,请忽略此步) ,http://www.mongodb.org/downloads#packages 这里同样有包管理器的安装方式,照着做就好了。

3,把你的代码放到 VPS 上来,然后以开发模式运行一次试试,不出意外的话,应该是可以运行了,如果有其他依赖需要解决,请自行解决。

4,把 nodejs 应用变成一个 daemon 。 我使用 upstart 来完成此任务 ,高版本的 ubuntu 已经自带,如果没有,直接 apt-get install upstart 来安装。然后新建一个文件在 /etc/init/yourapp.conf, 文件内容如下

#!upstart
description "node.js server"
author      "joe"

start on startup
stop on shutdown

script
    # We found $HOME is needed. Without it, we ran into problems
    export HOME="/var/www"

    echo $$ > /var/run/yourapp.pid
    exec sudo -u username NODE_ENV=production /usr/bin/node /where/yourapp.js >> /var/log/yourprogram.sys.log 2>&1
end script

pre-start script
    # Date format same as (new Date()).toISOString() for consistency
    echo "[`date -u +%Y-%m-%dT%T.%3NZ`] (sys) Starting" >> /var/log/yourapp.sys.log
end script

pre-stop script
    rm /var/run/yourprogram.pid
    echo "[`date -u +%Y-%m-%dT%T.%3NZ`] (sys) Stopping" >> /var/log/yourapp.sys.log
end script

你需要修改上述文件的 username 为你想要运行应用的用户名,推荐 www-data ,不要使用 root ,比较危险。如果你不使用 www-data 来运行你的应用,记得把export HOME=""改成对应的 HOME 目录。/where/yourapp.js 是你应用的路径。/var/run/yourapp.pid是你应用的pid文件,/var/log/yourapp.sys.log是你应用的日志文件。这些内容都需要根据你的情况修改。NODE_ENV=production 是让你的 nodejs 应用运行在生产环境的环境变量,你可以在代码中通过 process.env.NODE_ENV来获取。

配置文件创建好后,你就可以使用下面命令来开启/关闭你的应用了。

#!sh
start yourapp
stop yourapp

5,监控你的应用。我们不能保证我们的代码总是运行的很好,总会有崩溃的可能,所以我们需要监控它的运行,当它挂掉后,重启它。这里使用 monit 来解决这个问题,安装方法自己去这个网站找吧。

安装好后,新建一个文件在/etc/init/monit/conf.d/yourapp.conf,文件内容如下:

#!monit
set logfile /var/log/monit.log

check process nodejs with pidfile "/var/run/yourapp.pid"
    start program = "/sbin/start yourapp"
    stop program  = "/sbin/stop yourapp"
    if failed port 3000 protocol HTTP
        request /
        with timeout 10 seconds
        then restart

需要替换 /var/run/yourapp.pid 为你刚才设置的 pid 文件,yourapp 替换成你刚才在 upstart 设置的。port 3000 设置成你的 nodejs 应用实际监听的端口号,timeout 时间,可以根据你的实际情况调整。这几行配置文件很容易看懂,就不解释了。

然后确保 /etc/monit/monitrc 文件存在 include /etc/monit/conf.d/* 这行, 同时,你也可以在这个文件里修改监控频率,根据你的实际情况调整。然后重启 monit: service restart monit让刚才的配置文件生效。

upstart 和 monit 的配置我是参考 http://howtonode.org/deploying-node-upstart-monit 这篇博客的,你也可以来这里看看。

6,配置 apache 。我们需要在 80 端口来访问 nodejs 应用,现在又存在 apache ,那最简单的方式就使用反向代理来解决这个问题了。首先,需要安装 mod_proxy 和 mod_proxy_http ,你可以现在 /etc/apache2/mods-enabled/ 这个目录查看是否已经安装了,如果没有安装,你可以通过 a2enmod 命令来快速安装。
然后,新建一个 virtualhost ,按照你的习惯,新建一个文件 include 进去,或者一起写在某个文件。virtualhost 配置如下:

    
<VirtualHost *:80>
    ServerAdmin webmaster@localhost
    ServerName yourhost.com

    ProxyRequests off

    <Proxy *>
        Order deny,allow
        Allow from all
    </Proxy>

    <Location />
        ProxyPass http://localhost:3000/
        ProxyPassReverse http://localhost:3000/
    </Location>
</VirtualHost>

如果你的应用不是跑在 3000 端口上,记得修改配置, ServeName 记得改成你的域名,然后把你的域名解析到你 VPS 的 IP 上来。 ProxyPass 的作用是用 yourhost.com 来代理 localhost:3000 。ProxyPassReverse 的作用是处理 30X 跳转的情况,会把 Location:中的 http://localhost:3000 替换成 http://yourhost.com 。现在开启你的应用,重启 apache , 访问试试看。

如果都配置对了,到这里就应该能正常访问了。

使用反向代理时,要特别注意一些事情。页面中 a 标签的 url 尽量使用省略域名的形式,例如 href="/login",因为如果你处理不好,写上了 http://localhost:3000 这个后端的域名加端口,点击后就打不开了。对于 30* 跳转,Location 的值如果是 “//localhost:3000/login” 这种省略了协议的形式,apache 的反向代理也是无能为力的,我在 express 某个非正式版发现了这个问题。建议 Location 也使用省略域名的形式,这样虽然不符合 HTTP 1.1 的规范,但是各个浏览器都能兼容,可以省去这样的麻烦。

等等,如果你和我一样,也使用了 socket.io 来提供 websocket 服务,你会发现,现在长链接虽然可以用,但是却不是走 websocekt 模式了,这是因为 websocket 是无法通过 mod_proxy 来反向代理的,那就要另外想办法了。我使用的办法是:直接让 websocket 的请求去连接应用监听的后端真实端口。

7, 如果你使用了 websocket ,可以在页面中埋点,把带有你应用真实监听端口的 URI 埋入页面,然后前端 js 获取此 URI ,再来 io.connect( server ) 就可以让 websocket 正常运行了。需要注意的是,这个带端口的 URI 的域名需要和你访问页面的域名保持一致,否则取不到 cookie ,就没法获取 session 了。

如果你有更好的方式,请在下面留言交流,或者新浪微博 @allenm 来交流

发表在 javascript | 标签为 , , | 2 条评论