May 17th, 2012
时隔一年半,又接了个翻译的活儿。
在我继续之前,我先声明,所有的翻译工作,尤其是技术翻译,最主要的目的,是为了让更多不愿意、没时间、没有合适渠道或者因为语言障碍很难直接从源头获取相关知识的人受益。这是一贯的宗旨,背离了这个,一切都是浮云。我为自己有机会有能力做这些工作感到骄傲。
上一次翻译,出发点无外乎两个:一、帮忙;二、尝鲜。“帮忙”这件事,我自认为做得还不错,因为除了自己本来要翻译的那本之外,还同时救了另一本的急。但是对方领不领情,我说了不算。至于说“尝鲜”,因为是头一次翻译整本书,当然新鲜,但过程也是痛苦的,没做过的人很难体会,所以算得上还不错的体验,至少知道了翻译一本书意味着什么。
那这一次呢?“帮忙”说不上,因为是我自己很想让更多的人了解并使用Scala,这是等了很久的一本好书,编辑与我一拍即合。“尝鲜”当然更无从谈起了,这样的苦差,若不是真心想让这本书与尽快国内的读者见面,可能我老早就躲得远远儿的。
大约是4月初拿到的样书和合同,初读过后,真正开始全速翻译,是在今年的五一小长假,加上3天调休/年假和之后紧跟着的周末,连着8天的时间,全脱产,完成了22章中16章的初译,后来恢复正常作息时间表后,又花了一周时间,完成了余下的6章。
听上去有些不可思议是吧?之前我还在微博上说,那些一年翻译7、8本书的人,怎么可能保证翻译的质量呢?看来我得收回那样的话。翻译质量差,可能是因为时间紧,也可能是别的原因。经过训练的人,对于自己熟悉的领域,是完全可以做到脱产半个月完成一本300+页的书的初译的。只不过,如果让我连轴转,在工作之余,一年翻译个7、8本,我也会吃不消,因为我无法保证对不同技术领域都有同样浓厚的兴趣和准确理解原作的认知。
今天是一个里程碑,所有初稿整理完毕进入审稿环节。在此预祝本书顺利完成审稿和编加,早日与读者朋友们见面。就这样吧。
Tags: scala, translation
Posted in Work | No Comments »
March 25th, 2012
Arch Linux的包管理工具pacman引入签名机制已经有一段时间,目的是解决长期被人诟病的Arch包更新不够安全的疑虑。不过这一波更新也带来不少新的问题,主要是很多最终用户没有得到足够详细明确的指引,正确或者说建议的做法是什么,以至于很多用户干脆关闭了这个特性,多少有些可惜。
不论采取何种方式来看待这次的pacman升级,这些都是每个用户自己的选择,我不作评判,只是把我认为对的,同时也是官方建议的做法,用中文重新组织转述一遍,供大家参考。
pacman-4.0的升级,主要是增加了对软件包签名的校验,对于无法通过校验的包,根据本地配置项,给出提示乃至禁止用户继续更新。这样做的好处是避免用户无意识中下载和安装了被人恶意篡改的软件包,使其电脑被入侵和控制。在完整配置好pacman-4.0之前,你可能在做更新或安装新的软件包时,系统提示某密钥未知或无法导入某某的签名,导致更新或安装无法继续。配置pacman-4.0的过程很简单:
首先,pacman-key –init 在本机初始化你的PGP keyring,如果提示熵entropy不足,等一等,随便做些别的事情,很快就完成了。
然后,找到Arch Linux用于对所有35个开发和30个受信最终用户的密钥进行签名的5个master key (https://www.archlinux.org/master-keys/):
Allan McRae – AB19 265E 5D7D 2068 7D30 3246 BA1D FB64 FFF9 79E7
Dan McGee – 27FF C476 9E19 F096 D41D 9265 A04F 9397 CDFD 6BB0
Ionuț Mircea Bîru – 44D4 A033 AC14 0143 9273 97D4 7EFD 567D 4C7E A887
Pierre Schmitz – 0E8B 6440 79F5 99DF C1DD C397 3348 882F 6AC6 A4C2
Thomas Bächler – 6841 48BB 25B4 9E98 6A49 44C5 5184 252D 824B 18E8
将它们导入(只需要输入每个key的最后8位):
# pacman-key -r FFF979E7 CDFD6BB0 4C7EA887 6AC6A4C2 824B18E8
并添加信任(只需要输入每个key的最后8位):
# pacman-key –edit-key FFF979E7 CDFD6BB0 4C7EA887 6AC6A4C2 824B18E8
这里会出现 gpg> 命令提示符,依次输入lsign,选择y,输入trust,选择3,输入save保存,重复,直至5个key都具备 3 = I trust marginally 这个级别的信任。
至此,你的pacman(以及依赖pacman的yaourt等命令行工具)就可以正常工作了。建议大家随时留意官方公告和master key页面,为防止安全漏洞出现,至少在初始化配置时,尽可能从多个源确定这些key的合法性。
Tags: arch, gpg, linux, pacman
Posted in Tech | 2 Comments »
March 25th, 2012
有时候我们会接到运维人员的投诉,说某台跑着Java应用的服务器CPU飙高很严重,这时我们连上去看应用日志往往并不能发现问题所在。简单重启应用服务器当然通常能解决问题,但治标不治本,我们还是需要知道到底是什么环节除了问题。这时就体现出stacktrace的重要性了。
首先,ps -ef 找出Java应用服务器的进程PID。
然后,ps -eLo pid,lwp,nlwp,pcpu,stime,etime,args | grep <PID> 查看是哪个Linux轻量进程(LWP,对应Java的线程)占着CPU。
最后,jstack <PID> (或kill -3 <PID>) 输出stacktrace,将前一个步骤中获得的十进制的LWP ID(比如7016)转换成十六进制(比如0x1b68),然后在stacktrace输出中查找nid=0x????(比如nid=0x1b68),即可定位到问题线程对应的stacktrace位置,以便我们进一步分析问题的原因。
Tags: java, linux
Posted in Tech, Work | No Comments »
March 24th, 2012
RHEL/CentOS自带的vnc-server安装好(yum install vnc-server)以后,启动起来默认是xterm和twm的界面,而并非大家更熟悉的gnome桌面环境。
其实修改起来很简单,用vncserver命令启动好VNC服务器之后,系统会在 ~/.vnc/ 目录下创建出一个 xstartup 文件,打开将最后两行注释掉,改成 gnome-session &:
#!/bin/sh
# Uncomment the following two lines for normal desktop:
# unset SESSION_MANAGER
# exec /etc/X11/xinit/xinitrc
[ -x /etc/vnc/xstartup ] && exec /etc/vnc/xstartup
[ -r $HOME/.Xresources ] && xrdb $HOME/.Xresources
xsetroot -solid grey
vncconfig -iconic &
#xterm -geometry 80×24+10+10 -ls -title “$VNCDESKTOP Desktop” &
#twm &
gnome-session &
完成后 vncserver -kill :1 ; vncserver 重启VNC服务即可。
Tags: CentOS, gnome, RHEL, vnc
Posted in Tech, Work | No Comments »
March 24th, 2012
工作需要,最近前前后后处理了N个RHEL服务器转CentOS的case,做到不想做,记录一下过程,作为文档留底。至少今后要是有人问我要支持,我可以理直气壮地丢个链接给他/她搞定。
首先,从一个已知的CentOS源,比如 http://mirrors.163.com/centos/5.8/os/x86_64/ 下载如下rpm包:python-iniparse、yum、yum-metadata和yum-fastestmirror,以及RPM-GPG-KEY文件。其中5.8是目前5.x系列最新的,x86_64对应64位的系统。
# wget -c http://mirrors.163.com/centos/5.8/os/x86_64/CentOS/yum-3.2.22-39.el5.centos.noarch.rpm
# wget -c http://mirrors.163.com/centos/5.8/os/x86_64/CentOS/yum-metadata-parser-1.1.2-3.el5.centos.x86_64.rpm
# wget -c http://mirrors.163.com/centos/5.8/os/x86_64/CentOS/yum-fastestmirror-1.1.16-21.el5.centos.noarch.rpm
# wget -c http://mirrors.163.com/centos/5.8/os/x86_64/CentOS/python-iniparse-0.2.3-4.el5.noarch.rpm
# wget -c http://mirrors.163.com/centos/5.8/os/x86_64/RPM-GPG-KEY-CentOS-5
然后,卸载RHEL自带的yum,并安装CentOS版的yum相关包和密钥。
# rpm -aq | grep yum | xargs rpm -e –nodeps
# rpm -ivh python-iniparse-0.2.3-4.el5.noarch.rpm
# rpm -ivh yum-metadata-parser-1.1.2-3.el5.centos.x86_64.rpm
# rpm -ivh yum-fastestmirror-1.1.16-21.el5.centos.noarch.rpm yum-3.2.22-39.el5.centos.noarch.rpm
# rpm –import RPM-GPG-KEY-CentOS-5
接下来,在 /etc/yum.repo.d/ 目录添加CentOS-Base.repo文件。
[base]
name=CentOS-5 – Base – 163.com
mirrorlist=http://mirrorlist.centos.org/?release=5&arch=$basearch&repo=os
baseurl=http://mirrors.163.com/centos/5/os/$basearch/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-5
#released updates
[updates]
name=CentOS-5 – Updates – 163.com
mirrorlist=http://mirrorlist.centos.org/?release=5&arch=$basearch&repo=updates
baseurl=http://mirrors.163.com/centos/5/updates/$basearch/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-5
#packages used/produced in the build but not released
[addons]
name=CentOS-5 – Addons – 163.com
mirrorlist=http://mirrorlist.centos.org/?release=5&arch=$basearch&repo=addons
baseurl=http://mirrors.163.com/centos/5/addons/$basearch/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-5
#additional packages that may be useful
[extras]
name=CentOS-5 – Extras – 163.com
mirrorlist=http://mirrorlist.centos.org/?release=5&arch=$basearch&repo=extras
baseurl=http://mirrors.163.com/centos/5/extras/$basearch/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-5
#additional packages that extend functionality of existing packages
[centosplus]
name=CentOS-5 – Plus – 163.com
mirrorlist=http://mirrorlist.centos.org/?release=5&arch=$basearch&repo=centosplus
baseurl=http://mirrors.163.com/centos/5/centosplus/$basearch/
gpgcheck=1
enabled=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-5
#contrib – packages by Centos Users
[contrib]
name=CentOS-5 – Contrib – 163.com
mirrorlist=http://mirrorlist.centos.org/?release=5&arch=$basearch&repo=contrib
baseurl=http://mirrors.163.com/centos/5/contrib/$basearch/
gpgcheck=1
enabled=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-5
最后,执行 yum update 更新。
Tags: CentOS, RHEL, yum
Posted in Tech, Work | No Comments »
March 14th, 2012
我也当一回标题党。不过既然来了,就随便看看吧。
事情源于今天和新开发团队的一次内部讨论。相信有很多开发人员,尤其是Java和.NET开发人员,都是在面向对象的语境中成长起来的,可能有不少也和曾经的我一样:对面向对象有着某种不可言说的情感,因为它的气场太过于强大。你可能觉得有些地方不对,但又说不出个所以然。大家都这么做,自然有其道理,你默默对自己说,然后就move on了。
简单两句话过一下背景:我们新开发项目采用WPF/Caliburn.Micro,团队虽然有.NET经验,但对WPF和MVVM并不熟悉,大部分人几乎是从零开始。在讨论ViewModel中如何响应View的事件时,有同学提到能不能把View的上下文乃至UIElement对象传递给ViewModel,以便可以直接”操控”View的显示效果。对于做过MVVM的同学来说,这是个典型的n00b问题,答案当然是”不推荐”,因为之所以要MVVM,就是为了逻辑与视图解耦,你这么干,不是反其道而行之,又给绕回去了嘛。
话虽这么说,但要把习惯了WinForm和伪OO的思维重新拉回正轨,让大家重新审视面向对象以及背后的动机,还真得费一番口舌。
面向对象的核心特征之一,就是数据(名词)与操作数据的方法(动词)放在一起:你定义一个类,加入一些字段,再加入一些操作这些字段的方法,暴露其中的一部分或者全部供其他对象使用。不过这有什么不对呢?和我们的讨论又有什么关系呢?你问。
函数式编程的核心特征之一,函数(动词)是头等公民:给定某个输入,总是得到某个输出,干干净净的逻辑,没有外部可见的中间状态,没有特例。
在面向对象主导的世界里,除了有大量提供方法/接口,本质上被控制的对象之外,你经常需要扮演的角色是控制这些对象的总管(另一个对象),你手里握着一堆苦力,他们有哪些技能,多大的能耐,在什么时间做什么事,怎么做,都是你来告诉你来指挥。套用Animal Farm的比喻来说,有些对象生来比其他对象更平等。
在函数式主导的世界里,你以函数和数据结构的方式定义好所有的规则所有的逻辑,剩下的就是自主自治的数据实体。任何人都不天然掌管另一些人,他们只是通过约定好的方式进行协作,大家做好份内的事,君子协定,互不干涉,共生共赢。
视线再拉回我们前面提到的案例:作为ViewModel,你拿到UI控件的句柄,对你有什么好处呢?你无非是习惯了总管的角色,事必躬亲。什么都管的结果就是,可能什么都管不好。假如我们只是定义规则,在什么条件具备的情况下,该发生什么事,比如在输入字段A和输入字段B相同的情况下,确认按钮可以被点击,这样按钮可以自己说,好的,规则我已经很清楚了,我会管好自己,在该亮的时候亮,请大家放心,而不是由总管时刻关注着字段A和字段B的任何变化,然后不断的给确认按钮下命令说,你,亮起来!你,灰掉!
现实中面向对象的最大问题,或者说最大的误用,是保留了太多自己的状态数据,然后又将可以改变自己这些状态的操作的权力拱手交给他人,而在这个过程中,有意无意地忽视了规则和契约的重要性。多么可怕!
古人说,form is liberating,适当的形式/规约带来自由。在我看来函数式就是这样一种比面向对象更加好的form,而通常与之hand-in-hand携手同行的,是代码的可测试性。这就是我无论如何也要在团队中捅破这层窗户纸的原因。
Tags: FP, MVVM, OO
Posted in Tech, Work | No Comments »
August 3rd, 2011
可能很多人不以为然,写作和编程能有什么关系。
首先,写作促进我们思考。程序员每天的工作,不论是学习新知识新技术、理解软件需求、阅读代码/文档、设计框架、还是实现业务逻辑,都离不开思考。相信很多人都有过这样的体验: 对于某个设计或知识点,你以为自己想清楚了,但真要让你解释给别人听,你又会觉得无从下手,几轮过后回想当初,之前所看到和相信的不过是错觉,当你完整的向其他人转述一遍之后,你才算是真正想明白了。其实这个道理和书桌上放一只橡皮鸭/填充玩偶(然后向它讲述你的想法)的做法是相通的,只不过写作本身不光整理了思路,还留下了文档,同时,写作的过程也是不断加深印象、提升信心的过程,可谓一举多得。
其次,和写作一样,编程的主要目的是与世界交流,不论这个世界是指的机器的世界还是人的世界。要有效地与机器世界交流,你编写的代码必须符合一定的语法和范式,必须逻辑上讲得通,这样才有意义。而基本的写作训练可以让我们养成主动留意错别字、格式、拼写错误、逻辑错误的习惯。如C. A. R. Haore所说,我们宁要明显无错误的代码,不要无明显错误的代码。这点洁癖是好程序员必须具备的修养。这也是为什么我看到有明显拼写错误的程序员简历时,会直接把他/她们拉黑。同样地,我一直坚持认为,如果程序员写不出结构优良的纯文本文档,那么我们也不必指望他/她能够写出优雅的代码。除此之外,我们还可以再稍微发散一下: 开源项目那么多,满足类似需要的往往不止一个,为什么有的很成功,有的却无人问津? 主创/灵魂人物的写作能力,不论是代码、文档、邮件还是PPT,是很重要的分野。我相信,改变世界、影响更多的人,是很多程序员梦寐以求的,而要做到这一点,离不开写作。
最后,写作通常是程序员的短板,亦即最容易低成本高产出的地方。我一直很不喜欢人为地给不同专业背景的人贴上文科和理科的标签,仿佛他们之间没有交集似的。这样做的最大问题在我看来是一方天然地觉得另一方的知识对自己没价值,以至于形成了类似”写作是文科生的菜”、”编程是理科才要学的东西”等谬误。就我的观察,计算机科班出身的同学,往往文字表达能力不够强,可能多少和这种心理暗示有关。如此明显的短板,如果能够引起广大程序员群体的重视,肯在写作上持续投入,效果一定是惊人的。
Posted in Tech, Work | No Comments »
January 5th, 2011
在Vim中,我们可以通过set fencs=utf-8,gbk告诉它按照先utf-8后gbk的顺序自动识别打开文件的字符编码。Emacs也有一组字符编码相关指令,整理如下:
指令全名:set-buffer-file-coding-system
指令作用:改变当前buffer的编码
调用方法:(以目标编码gbk为例)
C-x f gbk
该指令还可以用于改变当前buffer的换行习惯(编码参数用dos或unix,对应\r\n或\n)。
指令全名:universal-coding-system-argument
指令作用:指定紧随其后的命令(如C-x C-f或C-x C-w等)所采用的编码
调用方法:(以目标编码gbk为例)
C-x c gbk
指令全名:revert-buffer-with-coding-system
指令作用:用指定编码重读当前buffer(如果打开时用错了编码)
调用方法:(以目标编码gbk为例)
C-x r gbk
指令全名:recode-region
指令作用:将以错误编码解码的选区以指定编码重新解码
调用方法:(以目标编码gbk为例)
M-x recode-region gbk utf-8
除了这些操作外,还有一种方法,那就是在文件开始的部分给出如下形式的指令,直接告诉编辑器在打开和保存时应采用的编码:
-*- coding: gbk -*-
接触过Python的同学是不是觉得很眼熟?
[补充] 查看当前编码选择的命令为:
M-x describe-coding-system 或 C-h C
也可在回车前输入具体的编码名称(如gbk)以查看详细说明。
Tags: emacs, tips
Posted in Tech | No Comments »
January 1st, 2011
回想大学时代,我第一本从头到尾读完的英文小说是Arthur Hailey的《Airport》,是在大学门口的外研书店买的。当时的想法很单纯:要证明自己的英文阅读水准不差,光靠新闻、应用文和专业文献是不够的,小说占到native speaker们日常阅读相当大的比重。如果能够啃下一本真正原汁原味的长篇小说,至少说明他们读什么,我也能读、能欣赏。最终花了一个礼拜,利用课余时间读完了。
这个看似不起眼的”成就”,对我自信心的建立至关重要。没有这个打底,后面恐怕也不会在知识”原始积累”的时候能有心有力去大量地阅读原版或影印版的书籍,并且往往能比别人更准确地把握原著要表达的意思。这个阅读小说原著的习惯一直延续到今天,量虽然不大,一直都有意识地在进行,比如前几年的《The Da Vinci Code》,这几年的《Animal Farm》、《1984》、《Twilight》等等。
就个人成长而言,光靠别人给你压力,给你找突破点是不够的。经验告诉我,影响自己最深远的,通常是那些自己给自己找的突破点。你能走多远,成为什么样的人,很大程度上取决于你自己。
Posted in Reading | 1 Comment »
December 30th, 2010
相信大家对SOA这个词并不陌生,很多企业都在讲我们要上SOA,也有很多企业在呼应:我们能帮忙。但究竟什么是SOA,SOA能做什么,如何在企业中推行SOA,采用什么样的技术,这些都是摆在我们面前的现实问题。
我为什么会对这本书产生兴趣?这要从我的工作说起。我从2004年开始投身到企业软件开发当中,具体而言,就是医院管理信息系统(HIS)。我们的团队,一直都是扮演独立软件厂商(ISV)的角色,为国内大中型医院提供高品质的HIS产品和服务。
接触过医院信息化的朋友都知道,医院对软件的需求是多方面的,通常很难有一家厂商能够提供从ICU/CCU、LIS、RIS/PACS到财务软件的全线产品和服务。而HIS在所有这些系统中,管理着医院的核心运营,贯穿医院业务的各个环节,经常需要和第三方系统进行通信。如何能更好地集成医院的各类资产,为医院这个特殊的企业提供优质的服务,与医院一同成长,就成为我们关注的焦点。
作为独立软件厂商,同时也考虑到医院的实际承受能力,我们很难说服自己和医院接受那些闭源SOA大厂高昂的产品服务价格。同时,出于对灵活配置和伸缩性的要求,我们在一开始就把目光锁定在开源产品上。
SOA为我们提供了架构设计丰富的营养和施展拳脚的平台。这本书要带给大家的,正是如何用开源的产品实现完整的SOA。在这个过程中,作者为我们分析了SOA的方方面面,对每个环节采用的技术都做了大量翔实的评估和介绍,对每个关键点都给出了详细的说明和完整的源代码。
如果你是企业主管、业务专家,相信你读完本书,会对SOA有更清楚的认识,对SOA能为你的企业带来什么样的价值会有更深的理解和体会。
如果你是架构师或程序员,相信你也和我一样,在阅读完本书之后,能更明白SOA的本质,掌握实际开发SOA的技能,懂得如何在企业或现有系统中引入SOA的思想。
得知博文视点引进并准备翻译这本书时,网上传来了质疑的声音,认为开源加上SOA,受众太小。我却不这么看。中国的软件产业,并非只剩下互联网和外包,除了叫得出名字的大公司,有大量中小型的独立软件厂商在暗自努力,他们在网上的曝光率很低,但都在踏踏实实地做事。他们是可爱、可敬的一批人,做的是幕后支撑企业运营的重要产品和服务,这本书也是为他们准备的。
在这里,我要特别感谢武汉博文视点的周筠老师,给我翻译本书的机会,与她相识是我的荣幸。感谢莫锡昌、成硕为审稿付出的宝贵时间。感谢编辑卢鸫翔、刘唯一和其他所有幕后工作者的辛勤劳动。
我还要感谢在事业上给予我重要帮助的两个人:毛颖和林勇,是他们的信任和鼓励让我走到今天。
最后要感谢我的家人,为了让我安心翻译这本书,牺牲了太多的周末和假期,谢谢你们对我的包容和支持,无私的爱当然要用无私的爱来回报,我爱你们!
在本书的翻译过程中,译者虽已尽力确保专业术语符合中文读者的习惯,也尽力将原著的真实意图以符合中文习惯的方式呈现给大家,毕竟水平有限,书中的问题和疏漏之处在所难免,恳请各位读者朋友批评指正,联系邮箱:gaoyuxiang.soa@gmail.com。
高宇翔
2010年11月于上海
Tags: transla
Posted in Work | No Comments »