斯蒂芬·金的写作建议

斯蒂芬·金【注1】已经写了48本书(34本是畅销书),或许对写作略知一二。为了成为一名更好的作家,斯蒂芬·金常常建议一个人必须“多读多写。我没有看到这两种方法之外的其它方法,没有捷径。”

阅读和写作有个共通的地方:词语是最小的阅读和写作的组成单位,它们组成了最伟大的思想和故事。它们在个人的想法之间架起了桥梁。书的作者通过词语的运用向读者分享其思想。这些词语具有分量;它们饱含深意。

“关于涵义,是一项巨大的事务。如果你持怀疑态度,想想你一直以来听到有人说的‘我无法描述’或‘这不是我的本意’。考虑一下一直以来你自己表达的那些东西,通常是索然无味或严重的挫败感。词语仅仅是涵义的代表;甚至在最乐观的情况下,写作差不多总是词不达意。”——斯蒂芬·金

让你的作品变得更好的两个要素就是,忽略不必要的词语,不要堆砌词汇。太多无味的词语让作品晦涩,辞藻的过多使用会赶走读者。你可以通过大量阅读让自己在写作和词语运用的理解上做得更好。斯蒂芬·金不管去哪儿,总是随身携带一本书。

“阅读是作家生命的有创造力的中心。不管去哪儿,我都带一本书,并找到所有能够投入的各种机会。技巧就是教会自己以随便翻翻或深度的方式阅读。书是独特的、可携带的魔法。”——斯蒂芬·金

斯蒂芬·金对于主动和被动语态做了有趣的总结。他是这样说的:“动词有两种形态:主动的和被动的。对于主动动词,句子的主语在做某事。对于被动动词,某事在被句子的主语做。主语只是让它发生。你应该避免被动语态。”被动或主动动词的使用对读者有影响。当主动语态出现时,虽然读者通常容易被吸引,但是有时候被动语态可以较好地表达一个角色的性格。

语法的运用,比如动词,对涵义有着重要影响。在组词成句时,我们有一些必须遵循的规则,如果我们不遵循这些普通的规则,那么涵义就表达不出来。语法规则是我们清晰地表达的方式,误用语法会引起错误表达和混淆。为了增加清晰的重要性,斯蒂芬·金强烈建议把你的思想分成多个部分。单个复杂的思想在分成两部分时,更容易被理解。读者是你主要关心的对象,你从来不想让你的读者自己去想,“他在说什么??”

刚开始写作的时候,斯蒂芬·金大学里的第一个写作教授John Gould建议他“关上门写作,再打开门重写。”对你作品的反馈是重要的。但是,正如斯蒂芬·金指出的,“你不能一直取悦于所有读者;你甚至不能一直取悦某些读者,但是你真的应当在某些时候至少取悦一部分读者。”

关于文字描写的最终思想是需要提及的。

“优秀的文字描写是一项博学的技能,这就是如果你不大量阅读和写作就不能成功的主要原因之一。文字描写从形象化你想让读者体验的过程开始。文字描写从作者的想象开始,但是应该在读者的想象里停下。好的文字描写关键要以清晰地看见开始,而以清晰地写作结束,某种使用清新的图片和简单的词汇的某种作品。优秀小说的基本规则之一就是,如果你能向我们展示一样东西,那么永远不要告诉我们这样东西。”——斯蒂芬·金

原创文章,转载请注明: 转载自腊八粥

本文链接地址: 斯蒂芬·金的写作建议

使用最好技术的不可见成本:AngularJS

很多企业家都对 使用最好的技术代表着什么 存在盲区:他们认为这更像是新技术将提供的功能,需要多长时间完成编码,以及是否值得。

他们常常忽略了基于公司能力去选择前沿技术的后果,而是雇佣、做SEO、兼容很多浏览器和集成通用插件。

我们雇佣的前端工程师建议了AngularJS,在做了研究之后,发现Google支持它,我们决定尝试。Ember.js貌似太新而没有太多的最新文档,我们听说,即便Backbone.js已经非常普遍了,AngularJS与Backbone.js相比,是更加优雅的解决方案。

这个决定让我们感到高兴,但是我们对于随之而来的、没有预料到的、很多不同问题感到吃惊,在我们首次决定使用AngularJS时,并没有小心权衡。下面是你采用AngularJS之前应该考虑的一些地方,而实际上适用于任何新的前沿技术。

1)低版本浏览器

AngularJS不支持低于8的IE版本。目前,我们的网站不支持IE8和IE9,我们仍然在尽量解决中。搞清楚IE10当中的bug花了不少时间。所有IE用户占到了25%流量,IE8和IE9大约占到了这部分流量的80%。还不能使用我们网站的用户是相当多的,严重影响了我们的转化率。

面向IE8和IE9这些低版本浏览器编程已经足够困难了,在那些浏览器很少能处理好CSS怪异现象的前提下,增加一个新的前沿前端技术也就成了相当巨大的障碍。

2)SEO

如果你有完全用AngularJS实现的app,那意味着相当有可能你的源代码只是JavaScript文件。Google还没有找到抓取动态内容的有效方法,如果你不做出一些调整,你可就要倒霉了。

我们有了存在于AngularJS SPA(单页应用程序)之外的“混合”页面,它们是Django(我们在用Python框架)里的普通页面,内容是可被爬虫抓取的。这些页面只在一个地方调用了AngularJS,那就是搜索框,当你搜索的时候,AngularJS会被调用。

这意味着我们有必要让一堆附属内容散落在中央AngularJS的app周围。

这也意味着在页头和页尾的某些代码需要被复制,因此当我们想增加一个类库或标签时,我们需要在两个地方增加。

3)Adsense、Clicktale以及很多类库都不能直接使用了

Adsense不能在载入动态内容的网站运行。事实上,做个变通方案,是可以让它成为可能(iFrame等等)的,但是违反了服务条款(TOS:terms of service)。这意味着,AngularJS以及使用了Ajax的任何东东,都不能直接使用Adsense了。

我稍微休息一会儿:是的,世界上最重要的在线广告领导者还没有找到一种在动态载入内容的网页上呈现广告的简单方法。而AngularJS是新兴的、通过Ajax载入动态内容的,肯定不可以了,Google也没有找到有效的解决方案也是让我颇受震动的。

Adnsense不能正常运行是因为它要等到DOM被构造好以后,才能基于网页内容实例化广告。它是在网页载入完成之后才执行的,但是对于AngularJS之类的“单页应用程序”,你从来不需要重新载入一个页面,所有内容都是动态载入的,在“页面”直接实现了无缝切换。

花了一整天找到的解决方案就是使用Doubleclick For Publishers【注2】,一个不同的Google产品,通过它来载入Adsense。一旦新的“页面”被载入,我们不得不“刷新”广告区域。这是个小伎俩,却是有效的。

真的花了好长时间才搞定的。

与Clicktale类似,我们使用软件监视用户会话并找到可用性问题。对于普通网页,你只需一段代码,但是对于我们的网站,我们不得不使用它们的特定API。

本来5分钟的事情,以色列的技术团队来来回回搞了一周。

4)程序员

很多程序员对新技术不了解,因此当雇人的时候,你不会有太多选择。

在我们发起了重要的合作伙伴关系的那一天,前端程序员离职了,我们才碰到了这个问题。我们招到了某个员工的一个白俄罗斯朋友,他实际上有对AngularJS贡献过源代码。他们从他的日程上抽出时间作为对我们的个人支持。但是我们说到的大部分人没有AngularJS经验,通常的反应会是“是的,我们正打算学习呢,因为它绝对是未来,但是我们还没有这方面的专家。”

总结

总之,在你面临使用AngularJS之类的新技术的选择时,你需要考虑的因素有很多,决不仅仅是“它是一个不错的框架”。你需要考虑招到人有多大难度,这个人要了解该框架,像SEO之类业务的其它方面的后果、广告集成以及跨浏览器兼容。

我们对AngularJS非常满意,因为我们有资金和时间来开发长期内可持续的功能,不过,它一定不适合每一个人。

当前沿技术引发的所有潜在复杂问题出现时,做为一家公司,要确信你有能力搞定。

  • 原文地址:http://davidlitwak.com/the-unseen-cost-of-using-the-best-technology-angularjs
  • 注1:Clicktale成立于2006年,相对于偏统计的流量分析工具,Clicktale偏向定性,它可以告诉使用者为什么网站转化率上升了,用户体验上升了?而不是简单的流量多少,流量产生时间和流量渠道。主要是因为Clicktale能够录制网站访客行为,将访客的一举一动全都录制下来,并且通过播放器完整地展示。除了视频录制,还包括热力图、转化漏斗、表单分析等强大功能。Clicktale追踪数据的技术属于Javascript标记,类似市场上通用的跟踪,例如Adobe Sitecatalyst, google analytics, 百度统计,CNZZ等,代码安装非常简单和方便。http://www.clicktale.com
  • 注2:DoubleClick for Publishers(DFP)是Google的第三方广告托管解决方案,前身为Google Ad Manager,集成DoubleClick的DFP产品之后推出正式的DFP系统。https://www.google.com/dfp/

原创文章,转载请注明: 转载自腊八粥

本文链接地址: 使用最好技术的不可见成本:AngularJS

重构、重新架构、再设计与重写的区别

稍早的文章评论里,Jon Eaves表达了把重构做为动词过度使用的忧虑。尤其是重构(refactoring)【注1】和重新架构(rearchitecting)之间的界线非常模糊,重构被用作在你回头做第二遍的、任何行为的标签。你明白吗?Jon是对的。

被Martin Fowler定义的重构,是一个非常具体的术语,以数学上等同的具体术语为基础【注2】。重构是关于小的、“行为保留”的增加的、安全步骤。重构不是在应用程序里回头去“填充空白”的借口。

让我们给出一些具体的例子来说明什么不是重构,下面的行为都不被视作重构:

  • “优化”(又称作增加)错误处理。
  • 增加日志
  • 勉强塞满另一个功能
  • 提高测试覆盖率(虽然它非常接近重构了)
  • 当老板不在的时候,玩扫雷游戏

重构是“优化现有代码的设计”。在本文,优化意味着使之更加易于理解 和/或 更加灵活。下面的行为都被视作重构:

  • 把臃肿的方法拆分成较小的、功能集中的方法。
  • 重新命名变量和参数,使之更有意义。
  • 把功能从一个类移到另一个类(更加适当)。
  • 基于一个类的方法,产生一个接口,然后让这个类实现该新接口。

注意,我说的这些可以是重构的行为。决定它们是否属于重构的大部分因素在于你是如何去做的。重申:重构行为,是小而安全的步骤,最好是可逆的步骤。如果你不得不考虑它是否可以运行,那么它就不再是重构行为了。

那么如何区别重构与重新架构或再设计呢?重构是在键盘上完成的,接触真正的代码。而重新架构,最好是在白板上(或最近的酒吧)完成的。重新架构涉及了较大的愿景,考虑下一周/月/年的规划。重构是你用来帮助自己达成目标的技巧之一。

再设计(Redisigning)是一个术语,覆盖了任何时候你正在重新考虑的设计决定。由于敲代码是设计行为,甚至到了打字阶段,再设计肯定包含重构。毕竟,如果你不稍微再设计,就不太容易提高设计。然而,在通常情况,“再设计”意味着放弃老的解决方案,提出新的解决方案,或多或少地从头开始。如果你在白板上做再设计,可能是没问题的,与重新架构的举动类似,你仍然可以通过重构达成目标。如果你在键盘上完成再设计,这就不是重构了。

重写(Re-writing)类似再设计,不过它只是在键盘上完成。重写通常是受到了头痛的伤害,但是它常常让你丢掉惰性而到达一个更好的地方。类似拍卖和搬到了印度班加罗尔。

在实战中,会遇到混合的情况。重构应该是一个开发人员使用的日常进程的一部分,当你这样看的时候,界线会变得模糊。比如:

  • 注意,你需要在业务逻辑里为第二种部件增加支持,这是一个设计行为。
  • 从现有部件抽出一个新的接口类,在此过程中重新命名现有部件,这是一个重构的行为。
  • 用新接口代替部件类的所有适合的引用,是一个重构行为。
  • 开发第二个部件,增加到应用程序里,是一个设计行为。

如果你最初开发了两个部件,后来才注意到公用的情况,该怎么办?好的,这是重构行为,可能要集中在以多态取代条件式的重构上。但是从外部看,这可能看起来非常像重写;必定(相对地)大量代码要消除掉。但是,不管你用什么方式削减,写第二个部件就不是一个重构行为。

重构更倾向于保持代码简单、灵活,而不是做对事情。做对事情经常涉及到添加新代码,或再设计应用程序的大块功能。使其灵活只是为了使其更加容易。这样说的话,重构最好被看做是一项赋能(enabling)行为。

如你所知,如果我写这篇文章不是在深夜,或许本文会更加连贯:) 如果你想更多了解重构,去看看Fowler的书。

原创文章,转载请注明: 转载自腊八粥

本文链接地址: 重构、重新架构、再设计与重写的区别

貌似离发布总还有两周

貌似不管我做什么、计划什么和开发什么……我总是离发布Workado还有两周时间。我一直在思考、甚至在说,这就是现在起3个月内最好的阶段。

这违背了我对大部分人说的话:

“先发布,然后再规划后面的。”

幸运的是,它还没有回来在后面咬我。来自Groove的Alex Turnball记录了当它尽量提供未来功能的发布日期时,它是如何伤害了他在一些客户面前的名声的。我没有给我们实际上要发布的工作设置期限,因为那个故事以及我认为它总是错误的。

尽管如此,我确实相信,距离发布第一个web应用程序还有两周是合理的。相较于基于业务的服务,还有一个完全不同的故事,比如《I was able to launch last week after 7 days》。

下面是确实没有根据计划进行的简短情况,我希望有人在某些地方能够吸取我的经验,以克服他们自己的一些延期。

找到合适的开发人员

Workado是我为upswinginteractive.com团队使用而开发的一套系统,已经投入使用3年了,不过直到去年,我决定把它做成可让公众获取的独立工具。自然地,我找最初参与的开发人员谈了,他表示感兴趣。

尽管如此我们还是意识到,这个工具将来需要实时更新和更多的客户端接口,这意味着我需要精通JavaScript的人。他是一个Ruby on Rails家伙,因此这行不通。

当所有这一切都搞清楚时,我正在准备内容和营销策略。随后我不得不转换思路,找到具有SaaS经验而且精通JavaScript的、物有所值的开发人员。我尽量通过当地渠道和我的圈子寻找这个人,但是运气不佳。公平起见,最初我希望找到一名对此感兴趣的合作伙伴/合伙人,但是很快知道情况不是这样的。

最终,我求助于oDesk。我找到一个不错的、对Node.js(后端)和AngularJS(前端)都真正了解的、加拿大开发人员。我本打算支付高价的,我只是觉得他的经验和技能比较值。从长期看,我希望某种意义上,这种支付不会让我失去公平。

现在是2月份,最初的版本预估要花费5周。

发布一个Beta版

的确足够了,开发都在按计划进行。到了第5周,我们有了一个可运行的工具。我把整个upswinginteractive.com团队转向了这个环境。

很明显,我们未能在这个时间点发布这个工具,用任务(我们还没有任务模板)在这个系统里获取客户要花很长时间。一些地方和你期望的不一样(下拉的活动列表)。我们不得不调整一些地方让这个工具更加直观,需要一个新手引导等等。

此时的挑战在于,这个开发人员已经着手他的下一个工作,他将一直忙到4月底。他有自己的优先级和要支付的账单,我理解,但是这不代表这件事没有搞砸。

自由职业者的挑战

当这个开发人员在5月份空闲的时候,我想我们将在5月中旬发布。这是我的第一个“距离发布还有两周”的时刻。

然而,他仅仅空闲了一周,就有了另一份工作,一直持续到6月份的第一周。

在这段时间,我开始寻找另外的开发人员。在周转不开的日子里,我设法雇佣了3个不同的开发人员。一个我比较熟,但是它有另外的工作,因此没法用。另外两个来自于oDesk的自由职业者,但是不顺手,因为他们没有linux经验,学习时间太长。

幸运的是,我的开发人员想起了其他人,让他过来帮助我在6月中旬搞定。

尴尬的bug

我计划在7月7号发布。然而,直到7月中旬,下一个里程碑还没有发布到服务器上,还产生了一些新bug,发现了一些其它bug,我们还经历了持续几天的服务器宕机。

尴尬的bug

如果你对产品的第一个版本没有感到愧疚,就说明你发布得太晚了。

我没有把这个引用的句子定在软木板上,仍然没有让我在当前条件下发布这款工具感到舒服的方法。

我在SEMrush准备了一个博客,但是我不得不暂停了,因为我们没有在7月分发布。8月5号是新的发布日期!

期望不要延期了。

我们来到了9月9号。尽管如此,我还是高兴地通报一下,只有4个未解决的bug,准备发布之前需要解决掉。下面是我们在Codebase上的发布里程碑的截图:

codebase上的里程碑截图

这意味着我真正觉得我会在即将到来的9月23号发布了。

结论

开发投入的时间越多,发布的可能性就越低。
——Jason Fried(37 signals)

这句话对我而言是非常重要的,因为我知道我现在就处于这个节点,项目正在“延期”。尽管如此,我还是在这段时间学到了很多。我享受大部分体验(bug和延期除外),我知道有了这个经验,将对未来的SaaS app发布有帮助。

在它发布的时候(数周之后……),我打算记录发布之前和发布之后我所做的工作。可以在这个博客的微系列里看到,保险起见,请订阅,在右边输入你的email,便于微系列上线的时候收到通知。

原文地址:http://justinmcgill.net/i-seem-to-always-be-two-weeks-from-launch/

原创文章,转载请注明: 转载自腊八粥

本文链接地址: 貌似离发布总还有两周

简单不等于容易

为什么越简单的技术对于开发人员越难

简单 != 容易

从Amazon Web服务到AngularJS之类的web框架,便利性驱动着世界上最好的技术。但是,更加快速地、变得有效率的“便利性”,经常伴随着一个隐藏的价格标签:为了变得真正有效率,你将不得不花些功夫。

伟大的技术经常貌似简单,新手们直觉上不需要太多努力就可以“学习”。当人们认为他们已经掌握了这门技术、而他们真正做的所有工作相当于是一个“hello world”程序的等价物时,问题就出现了。在你归咎于这个工具之前,你往往需要投入时间以正确地使用它。

关于AngularJS的“复杂感受”

让我们用AngularJS做例子。AngularJS是一个web应用程序框架——JavaScript代码类库、模板和其它软件的集合,目的是让开发人员更加容易地开发动态网页或web app。

正如Anand Mani Sankar建议的,问题在于AngularJS入门容易,简单掩盖了框架的力量:

[AngularJS]通过抽象了很多内部的复杂度,而只暴露程序开发人员关心的东东,大大简化了应用程序的开发过程。

听起来这是一项伟大的工作,它也让新手们在完成第一个“hello world”应用程序后,就觉得掌握了这套系统:

AngularJS旅程会产生复杂的感受。学习曲线与其它JS框架有着很大的不同。进入的门槛非常低。但是,当你开始深入的时候,学习曲线突然变得陡升了。

Sankar然后引用了Ben Nadel关于AngularJS旅程的幽默描述

AngularJS的学习曲线

当然,一些人被卡在了谷底。比如,George Butiri从Google搜索到了很多关于“The reason Angular JS will fail”的文章。Butiri解释道,AngularJS实际上相当难,没有给出太多专门的例子来解释为什么是这样子,至少超过了“因为我更喜欢jQuery。”

太容易失败了

很多最好的技术都是这样。它刚开始时简单,不过如果你想真正掌握它,你将不得不投入大量时间。一些人开始势头很好,发现了复杂,然后抱怨这门技术没有永远地保持出乎意料的好。

对不起,真正的技术不是那样运转的。它总是需要努力,如果不能以正确的方式运行,就会失败。

看看NoSQL数据库,我在这个世界花了太多的时间。

NoSQL对于新手而言,无论是MongoDB、HBase还是Cassandra,喜欢兜售它的无模式特性(schema-less)。关系型数据库的旧世界需要僵硬的模式而且狂热!在NoSQL的新世界,定义数据结构的模式消失了,DBA们消失了,规则消失了!真简单!!

当然,这完全是胡扯。正如我的同事Asya Kamsky喜欢说的,“NoSQL != NoDBA.”(NoSQL与“没有数据库管理员”不是一回事儿。)

NoSQL不代表“没有DBA”。如果有人试图这样说服你,他们很可能要向你推销什么。这不意味着你有一个具有“DBA”头衔的团队或人员——然而,如果你有一个数据库,无论它是关系型,还是非关系型,那么一定有人担任“DBA”角色——如果他们不知道他们做的事情,那么在问题出现之前,一大堆工作将不会完成或被考虑到。

浏览关于NoSQL数据库、AngularJS或大部分你喜欢的技术方面的文章,我保证,如果不是大部分,也有很多是由那些感觉受欺骗的人写的,技术没有按照这种用户想要的方式运行,因为他们没有真正的投入。的确,有时候是技术失败了。多数情况则是令人触目惊心的。

但是,当技术没有神奇地减掉我们需要的工作时,我们常常在抱怨。

杠杆越少,幸福越多?

从这两者得到好处的一种方式就是通过可管理的服务,比如Amazon web服务的Redshift。Redshift是一个运行在云端的、完全管理的数据仓库。“完全管理”意味着它更容易使用,但是它也意味着用户失去了他们可能在Teradata或另一种企业数据仓库中的一些把手和杠杆(the knobs and levers)。

然而,这恰恰就是问题的关键。

正如AWS数据科学的总经理Matt Wood最近告诉我的,Redshift和其它AWS服务致力于通过移除复杂让用户易于使用。给用户更少的“杠杆”意味着AWS也给他们更少的失败方式。当然,技巧是在产品简单与用户控制之间找到平衡。

例如,Airbnb对Redshift刚开始是如何容易感到洋洋得意,但是随后就需要一些折衷(和投入):

我们面临的第一个挑战就是模式迁移。即使Redshift是基于Postgres 8.0的,“微妙的”不同仍然足够大,强迫你用Redshift的方式工作。我们尽量自动化模式迁移,但是问题比我们最初期望的更大,我们认为它超出了试验的范围。在Redshift里,索引,时间戳类型,数组,不被支持,这样你需要在你的模式里排除它们,或找到变通方案。

无论如何,Airbnb投入了努力,看到了至少五倍的性能提升和巨大的成本节约。起步容易,但是也值得继续投入。

也有很多伟大的软件,它们看起来使用简单。为了走出对于任何伟大技术的新手状态,你将不得不有目的地使用,你将不得不投入时间和努力来掌握它。

可以有免费的软件,但没有免费的午餐。

原文地址:http://readwrite.com/2014/09/08/simple-technology-hard-not-easy-angularjs-nosql

原创文章,转载请注明: 转载自腊八粥

本文链接地址: 为什么越简单的技术对于开发人员越难