我的第一本英文技术书

2021年6月更新 不知不觉已经过去快一年了,我来更新下这篇的后续。 首先我想分享给大家的是:这本书的纸质版已经由APress出版社正式出版了! 从原来的博客发布至今的近一年中,这本书经历了很多次的编辑和重构。事实上,在这本书有了初稿之后,我就曾请求同事Martin Fowler帮我review并提供一些早期的反馈,不过他当时还在忙于《重构》第二版的审校工作,所以只是放入了他的backlog里,直到去年7月才review完成。Martin的批注非常仔细,从目录结构,到遣词造句,再到实例与主题的关联度,以及参考文献等等方面,差不多有近10页。我根据这些批注重新组织了书的结构,并删减了差不多1/4的内容,使得结构和内容更聚焦。此外,Hannah又在此基础上进行了英文的编辑和润色,以及对一些代码实例的建议。 去年圣诞前后,APress的编辑找到我,表示他们有讲此书出版为纸质书并在他们平台上发售的意向。在经历了数个月的编辑,审校,勘误之后,这本书终于出版为纸质版本。在上周末我收到了出版社寄来的几本样书。看到自己的名字印刷在封面上是一种奇妙的感觉,开心当然是有的,不过随之而来的又是一些隐约的担忧:担心书中技术终会过时,担心有不好的comments等等。不过该来的终觉会来,这大约也是出版的一部分吧。 另外,感谢那些鼓励我的、默默提供勘误的、报告bug的人们,没有你们的帮助,这本书不会最终成为可能。 我的第一本英文技术书 太长不读 我写了一本关于React+TDD的英文书,你可以从这里免费获得(更新:和APress出版社的合同中明确要求需要从其他渠道将其下线)。在我写这篇文章的时候,读者大约是1000+。虽然读者不算多,但是通过一些渠道收集到的反馈还算不错,已经超出我自己预期很多了。如果你读完觉得还不错,而且愿意帮我宣传一下我会非常感激,如果你想要做一些修订甚至翻译的话那就更棒了(有一个俄罗斯小伙在帮我翻译俄文版,不过他貌似拖稿十分严重)。 缘起 实话实说,写这本书纯属意外之举,最开始的时候对于内容和形式是完全没有计划的,更不用说用另外一门语言作为载体了。应该是在2017年年末的时候,我在华为的无线部门做一个网管产品的Web化,人员能力提升显然是Web化的核心了 – 毕竟功能需要开发人员一行行去实现。当时该部门中的大部分开发同事的Web技能都比较薄弱,一些有经验的同时则每日被业务需求缠身无法顾及能力构建,因此引入外部的培训来填补这个空缺。 这个看起来是Web开发101的培训还有一些其他需求,比如用户故事拆分、自动化测试和TDD等等敏捷开发的基本内容。我为团队设计了一些循序渐进的例子作为培训的素材,并在后来的几轮迭代中进行了内容的删减和补充。培训的结果还是不错,有一半以上的同事对Web开发产生了兴趣,有人则开始意识到自动化测试(以及TDD)可以减少回归测试的工作量。 正如你所料,这个培训的一个副产品就是这本书的原型了。在培训结束之后我正好有了几周的beach时间,我用这些时间将内容变成一个教程:从一个简单的例子,逐步完善成一个前端应用。其中涉及了诸如Tasking,ATDD,用户故事等。 过程 初稿 原型是很容易的,素材是现成的,只需要将其以符合逻辑的方式连接起来即可。比如我想要描述通过TDD的方式开发一个应用的全过程,那么首先我需要讲清楚我们要做一个什么应用,此外我需要说清楚如何用TDD来完成这个应用。根据经验,人们喜欢循序渐进的方式来阅读,先做一个简单需求,然后逐步增强,并在过程中将学到的内容应用,然后推广到后续需求的开发中,并通过实现更加复杂需求习得我想要传递的知识/技巧。 TDD的101(通过例子来说明Tasking和测试驱动的过程) 介绍demo应用,搭建应用所需的环境 设计并实现一个简单需求 实现一个更复杂的需求 循序渐进…… 编辑初稿的过程中,正好有个掘金小册的编辑联系我有没有意向写个小册子。虽然最后由于篇幅和主题的选择方向没有合作,但是和编辑沟通的过程帮助我很好的梳理了草稿的结构。 英文版 在草稿写完之后,我找到几个同事做了快速的review并做了一些修改。到了2018年3月,我开始准备来澳洲的LTA,既然英语会是我接下来几年的主要语言,那么提升英文能力就成了优先级很高的事情。而学习语言的窍门就是:没有什么比实际使用一门语言更能提升语言能力的了。 于是我开始尝试把草稿翻译成英文版。开始的时候我还会保持双语版本的同步,到后来带宽不足的时候就只能把精力放到英文版上了。第一个完整的英文版发布于2018年5月,后面虽然陆续有些小的修改,主体部分没有太大的变化。 到了澳洲之后,读了很多英文原版的书籍/文章之后,发现了书中很多的语言错误,又在一个假期里集中修改过一轮,可读性有了一些提高。 重构 到了2019年的9月,经过了近1年2个纯React的项目后,我对与React及其生态的理解,以及在应用TDD(特别是和传统上认为的TDD很难在复杂/时间不允许的项目上实施)的认识上都有了新的发展。于是又将其中很多章节重写了,比如丢弃了pupeeteer改成cypress,采用react-testing-library而不是enzyme等等。另外,结构上也做了重新整理。 由于这些颠覆性的修改,我将其重新命名为Mastering Test Driven Development with React,并声明其为前一个版本的第二版。 到了2020年4月,由于covid-19在澳洲的肆虐,我们开始全面WFH。一方面突然有了很多时间,另一方面我意识到线上沟通时英文在有些时候还是会变成blocker,于是我又花费了一些时间来提升英文。于是又开始了一轮的re-wording。 在你今天阅读这本书的时候,你大约会惊叹于英文表达之地道,语法之准确以及用词之精准。这些都和我的英文水平没有太大关系。在5月的一天,一位澳洲同事Hannah Bourke写邮件给我,表示她通读了这本书,非常喜欢其中的讲述方式和实例以及节奏,她表示愿意帮我近一步润色。她通过PR的方式重新整理了本书的语言(目前已经完成了70%),由于Hannah本身就是前端Dev,所以很多表达方式也被重写为更容易被读者理解的方式。 一些收获 关于英文写作 语言的学习是个漫长而痛苦的过程,同样的内容,要从一门语言中的表述要翻译成另一门语言需要的更多的是重写而不是literal translation。从LTA开始我就开始刻意的用英文写作,还尝试把一些文章翻译并投稿给英文版洞见。 通过这些练习,我觉得我至少不再惧怕这件事情本身。英文表达当然有不地道的地方,但是读者也不是语言学家,大多数时候他们都可以准确无误的get到你的意思。即使有些复杂概念无法一次理解,通过评注或者提问等等,总是会搞清楚的。 关于自信构建 在这本书的写作过程中,我个人最大的收获应该是:当你制定了一个目标,不论这个目标开始开起来有多么的不切实际,一旦你开始细化这个目标并逐步实施,你就已经离这个目标不远了。当然,和每个任务一样,事情走到最后可能会和最开始的目标并不完全契合,但这大约是我们无法掌控的那部分了,就随他去吧。

July 1, 2020 1 min

如何写一本书

我在过去的几年中,写了4本书。有传统意义上的两本实体书:《JavaScript核心概念及实践》和《轻量级Web应用开发》,还有两本电子书《3周3页面》和《函数式编程乐趣》。当然对我而言,主职工作是软件开发,写作是个副业。 在写作的过程中,有一些有趣的心得。 写作本身是一个很好的学习过程(至少是一个驱动你学习的动力) 写书非常枯燥,特别是校对的时候 写作不会让你变得富有,但是有时候会让你开心(不总是) 写文章 vs 写书 写博客/文章和写书还是有很大差别的,一个明显的差异是写文章会比较随意,而且应该尽量保持精简。一篇文章提供一些信息即可,应该尽量远离细节(如果写一篇教程,则另当别论)。而写书则应该尽可能的深入细节,尽可能可以让读者依书自修。 投入与回报 首先要明白的一点是,不要指望用写书来赚钱,至少前4本是这样的。粗略的算一下:我的第一本书卖了3000册,每卖一本我可以得到4元RMB,一共就是12,000元RMB。而这本书我断断续续写了三年。那是很多个周末,很多个假期,很多个夜晚的付出换来的,如果真正要计算投入产出比的话(纯粹金钱上),这显然是一个毫不合算的事情。 作为一个参考,IBM developerWorks的投稿,千字200元,一般写5,000字以内,也就是800元RMB左右。而要写一篇这样的文章,我只需要一天(当然需要数周/数月的积累)。12,000元RMB需要写15篇文章,如果每周写一篇,不到4个月就可以写完,而且写文章比写书容易多了,毕竟篇幅比较短小,易于校对。而且对于大部分开发者来说,固定在一个主题上的难度要比15个独立的主题简单的多,因为无需特别深入。 所以根据经验,要抱着公益的情怀来写书。也就是说为了让知识更好的分享,让你学习到的先进科学技术来帮助更多的开发者,提高他们的开发效率,让他们可以在周末多休息一天。而至于翻译技术书籍,那基本上就是免费的了,完全是一个公益活动(耗时数月,斟酌字句,推敲表达方式,但是价格极为低廉:千字60元RMB),所以下次见了技术书籍的译者,就多少给他捐点吧,他们才是在为人民服务。 知识的诅咒 “知识的诅咒”是指人们在获得了某种知识之后,就无法想象没有这种知识的情况了。这种现象随处可见,比如一个你到了一个从未去过的陌生城市,遇到以为当地人,然后向他问路。当地人觉得已经说的很清楚了,但是你还是不知道该怎么走。另一个例子是:假设你不认识泰文,然后你打开任何一本泰文写的小说,你只能依稀感觉到这是一种文字,除此之外你并不能从中获取任何的信息。但是当你学习了一段时间泰文之后,再来看这本小说,之前的那种感受就再也没有了。 写书的时候,你首先需要具备某种知识。但是写书的目的是将这些知识传递给那些不具备此知识的人,而根据“知识的诅咒”,你又无法确知那些初学者会遇到哪些问题!解决这个问题的方法就是找初学者来试读。而且为了保险起见,还应该找尽可能多的人来试读。 写作方式 一种方式是自下而上的,写一些独立的文章,最后发现可以串起来,然后形成一本书,另一种方式是自上而下,但是又会逐步调整。根据经验,不论是写一篇简单的博客,还是写一本书,都需要按照自上而下的方式。随心所欲的写下去,基本上都收不住,而且整个文章支离破碎,貌似有很多内容,但是不成章法,读者也无法轻松的获取知识。 先列出大的章节,然后逐步细化,但是未必是按照顺序来写。先编写自己最熟悉的部分,然后逐步完善。例子的选取需要精妙而恰当,最好有图例来说明。 配图制作 一般而言,我在书中会使用两种图:流程图和一些截屏。截屏通常使用Mac OSX自身的功能就已经足够,而流程图我会采用一些额外的工具如: graphviz keynote/sketch 用Graphviz画图的好处就是可以将图像代码一样放入版本库来管理。 除此之外,我还学习了一些设计软件的基本用法,事实上只需要用一些简单的元素就可以做出非常专业的配图: 字形/字体(大小,粗细的变化) 颜色(基本的配色理论就可以做出很舒服的配色) 层次(尺寸,位置,颜色的深浅) 阴影 代码格式 书中实例需要很多代码来说明,如果是制作电子书的话,可以使用Markdown预处理器自带的功能来高亮。另外如果需要RTF格式,可以使用这些工具: highlight工具 intelij中的插件copy on steriod 这里有一篇博客来说明如何将你的代码带着格式拷贝到剪贴板中,拷贝之后,就可以将这些内容粘贴到Word或者Keynote中了。 jest.dontMock('../components/headline.jsx'); describe('Headline', function() { var React = require('react/addons'); var Headline = require('../components/headline.jsx'); var TestUtils = React.addons.TestUtils; it('#render', function() { var text = "this is a title"; var headline = TestUtils....

August 4, 2015 1 min

JavaScript核心概念及实践 - 勘误表

###《JavaScript核心概念及实践》勘误表 JavaScript核心概念及实践一书已经于2013年5月出版,由于时间原因以及作者的疏于检查,导致书中出现了一些错别字词等错误,现在将错误及更正列于此页,作者为对读者朋友带来的不便表示深深的歉意。 第一章第12页 “则向控制台打印:goodbay” 应为 “则向控制台打印:goodbye” 第二章第19页 “var y = x + “2”;// => 32” 注释中的数字32应为字符串类型 “var y = x + “2”;// => “32”” 第三章第36页 “对函数customize(options)的调用 constomize” 应为 “customize”。 同一页,3.4小节 “反回给前端的仍然是 JSON 对象” 应为 “返回给前端的仍然是 JSON 对象” 这里有一个非常仔细,质量很高的勘误表,由网友 @RednaxelaFX 整理。 这个页面将维持更新,如果有新的错误被发现,我会第一时间更新书籍的电子版本,并在此页面上更新。

May 16, 2013 1 min