创业项目该如何选择技术?

这些年,许多人问过我下面相同的问题:

  我开始了一个新项目,你认为我该使用什么技术呢?

通常,这些人属于下面两类中的一类:

  • 已经做出决定的技术人员
  • 需要鼓励支持的非技术人员

在一天结束的时候,我怀疑这些人是否真正关心我的答案。或许他们只是想知道我们是否面对相同的问题或只是需要鼓励支持。

坦白的说,作为一名工程师,我信奉这个说法:伟大的想法可由几乎任何技术构建。它们都有自己的优点和缺点。无论你选择什么技术,你都要为它带来的风险买单。但真的,你项目的成功与否更多的取决于愿景、领导团队、执行和市场,而并非技术的选择。

现在,我是一个负责人,我每天做技术上的决断。当我选择了一个特定技术时,我要能够证明这个决定,向我自己、我的合合伙人/员工和潜在的投资者。我根据项目及公司愿景做技术选择。

项目要成功你必须有一个坚定的愿景。如果你能将你的愿景转化成一组衡量你每个决定的值,你的前进道路会更清晰,也更容易找到合适的加入你的人。

除了愿景,许多初创公司专注于文化。人们都说文化是由创始人、最初的几个员工及产品本身确立的,然而,技术抉择对公司文化有直接影响这个说法却没怎么被提到。

你的项目初创可能基于J2EE、Oracle、Perl、PHP、Rails、Node.js或.NET,随之而来你的团队工程师将有不同的期望,不同的价值观,和不同的关注点。这些技术没有本质上是坏的。伟大的事情都有各自不凡的所在。它们伴随而来的是一种文化。

几年前,我遇到一位负责人选择使用Node.js来搭建自己的应用。出于好奇,我问他为什么选择Node。他的回答很简单:基础的工程师对Node.js很兴奋,所以我可以更容易招募到愿意免费贡献的人,因为他们希望积累相关经验。

这个决定显式地定义了工程师文化和团队成员——那些能够在这个项目中工作或感兴趣这个项目上工作的人。

问一个不一样的问题

那么我们不应该问什么技术是我们需要使用的, 我们应该问我们自己:

  这个技术符合我们公司的核心价值观吗?

这显然是个更为之困然的问题,因为你需要切切实实地了解你公司的核心价值观。这将是创建一个成功项目的关键。

你不能盲目地套用技术就像你不用套用别人的商业计划那样。这是公司身份的一部分,你的核心价值观,你的目标,你的团队,你的期望都是跟别人不一样的。

关于“这技术在某某公司用得适合啊”这样的论据是很少有效的。例如Facebook使用PHP,它“在Facebook公司用得很适合”,但是这意味着我们选都应该使用PHP吗?

技术文化联盟

要具体描述这些技术社区的特性是很困难的,但我会个你分享我在不同选择上的观点与看法。请自由在评论里分享自己的看法,也可以包括关于其他技术社区的。

古典学校: 

这里有些是“经典“的语言:他们已经被使用很长的一段时间,并且被证明他们的价值。他们的使用范围已经很广泛,但却引不起别人更大的激情。

注意:我在这没有提及Perl,因为我并不知道有哪个创业项目是以Perl作为核心技术来创建的(6?)。

PHP

理念:

  • 功能都实现出来,这非常重要
  • 就像互联网的基础一般
  • 只要有一个方法去实现它,那么就不会被破坏
  • 只要它运行起来并且速度很快,那么其他东西都是没有意义的
  • 不要太理论化了,我们的语言是非常通熟易懂的,任何人一眨眼的功夫就能上手了。你可以用Java做同样的事情看看!
  • 面向对象是种落后的想法

常见的使用例子: (在2013年中期)

  • 你的第一个web app
  • Wordpress/Drupal的扩展

个人观点:

PHP拥有它光荣的日子。它真的让web开发更加简单,容易上手. 但是, 大概因为大量新的程序员开始使用PHP并且它拥有个不是那么地坚持自己观点的社区,所以只有少数人能写出漂亮的PHP代码。

良好的拥有规范的代码例子是很难找到的,并且我甚至不敢肯定PHP拥有自身的规范。这导致了PHP社区以糟糕的代码质量,缺乏测试,安全问题如同梦魇和像在2000年代初期般的落后品味而著名。

拥有良好规范约定,开发流程和指南的强大的PHP团队,是可以完成伟大的事情的,但这样团队很稀少。

Java

理念:

  • 可移植性
  • 像C/C++般的能力和表现,但却能够自动管理内存
  • 更多地关注面向对象
  • IDE是必须有得
  • 我们要消耗所有的内存,因为它们是一文不值的
  • 线程处理是个好方法!
  • 不要提起Java applets
  • 看看我可爱的JVM!
  • 开源(但拥有者为Oracle)
  • 缓慢但更为安全的开发流程

个人观点:

Java是非常有趣的。在几年前很多开发者已经厌倦了Java,他们找到了其他新大陆。他们开始转向一些脚本语言,像PHP,Pyhton,Ruby或者一些更加难懂小众的语言像Erlang。

尽管如此,Google通过Android展示了Java并不像我们脑海里的那么糟糕(只要你并不是使用J2EE或者Swing)。现在有一种”赶时髦“的趋势视乎暗示着Java再次变得酷起来了。这些大多建立在两件事情上:

  • JVM
  • 让人难以置信高质量的代码库

即便如此,对于我们来说,花一整天来编写Java程序看起来并不是一件吸引人的事。如果你打算依靠Java的堆栈,那么有一系列的其他JVM语言供你选择,他们成熟而且兼容Java扩展的库(例如:Scala, Groovy, JRuby, Clojure),你总是可以混搭使用它们。

自从大量毕业生学习Java后,聘请Java程序员并非一件难事,但是要找那些前期创业公司,高水准的工程师并且对写Java程序感兴趣是一件极具挑战性的事情。

另外注意:如果你的目标是Android,那么不用想得太复杂,即使你认为其他JVM语言更好,你也要坚持使用官方的堆栈。

我们仍然有许多的原因在你的创业项目里使用Java技术,但你可能会想同时使用一些的”更快,更灵活“的解决方案(Ruby, Python, Node…)。对于公司跟工程师来说,一个多语言环境带来了大量的价值,这就是为什么Java社区看起来节奏很慢,但却肯定是活跃的。

Java绝大部分是吸引了那些受到了传统的训练的工程师,他们向往舒适,有重复性,总所周知的编程模式。他们习惯关于使用这种语言,这种工具,这种自然的节奏。或许他们并不是最具有求知欲的开发者,但是他们却是很可靠的(当然,你要挑选了正确的人)。

C#/.NET

理念:

  • 是更加好的Java
  • 最初是为了桌面与嵌入式软件设计的
  • 我们比开发Java的小伙伴们拥有更好的IDE
  • 虽然是企业级般的重量了,但是我们提供了大部分Rails很酷的特性
  • 我们有矛盾的开源版本
  • 缓慢但更为安全的开发流程

个人观点:

当我回顾C#在发布C#5的时候,我不得不惊叹,我真的对该语言新的特性留下了深刻的印象。单从纯粹的语言设计角度来看,C#是有一丁点的领先于 Java。在Visual Studio里写Javascript时的欣悦感让我感到很惊喜(自从我用VS主要为了C++后,我真的再也没有期待过什么了)。

另一件让我印象很深的是:C#可利用的文档的质量非常显著!但是C#并不是开源的,和Visual Studio + MSDN 非常昂贵,并且整个环境都因为licenses跟内存损耗而变得很糟糕,这些事实多少让这个好印象打折扣了。

微软正在慢慢地往开源发展,所以有了更多像Azure的开源方案。但是作为一个社区,.NET仍然是微软开发的中心。作为创业者,你应该考虑下你对开源与拥有企业支持的文化之间对比的看法。

C#大部分吸引了Java群体中的变向者:这些工程师们寻求稳定性和有保障的合同远胜于追求开源。还有他们可以容忍IIS!

明确的可替代品

 

在过去的这些年,有两个动态语言对于新的创业项目来说变得十分受宠:Python and Ruby。这两个语言实际上有非常多相似的地方。现在Python因为后台apps而著名(因为NLP, biotech, APIs, SOA的因素 )而另一方方面,Ruby因为面向用户的apps而著名。尽管这两个语言都受到了一样的限制(主要是性能跟并发性),但是他们的核心价值和社区有着不一样 的专注点。

Python

理念:

  • 只有一种显而易见的做事方法
  • 代码要漂亮简洁和明确
  • 文档是关键
  • 有较强的语言设计引导

个人观点:

作为一个更喜欢ruby的人来说,我常常嫉妒python项目文档的质量。同时python设计的初衷——给你一个正确的编程方式却又让我又爱又恨。通常这一初衷对于团队来说很好,但某些时候可能令人抓狂。

在某些领域python有很多优秀的库,并且这些库和你想解决的问题有关,这种情况下python可能是最好的选择。python开发者知道怎样去讨论交流他们的代码。他们用文档记录所做的事情并且用面向过程来描述他们务实的方法。

但是python在互联网流行前就已经存在,如果你关注的是并发和高吞吐量,那么这个并发性很差的动态解释语言可能不是一个很好的选择。

python主要吸引的是那些想要一个现代但通过充分验证的语言的更加务实和经验丰富的全栈开发者。

Ruby/Ruby on Rails

理念:

  • 为人而不是机器而设计的Designed for humans, not machines
  • 极端的灵活性:如果陷入困境的话,是你的原因,那是你
  • 一切力求简单、优雅并充满乐趣
  • DSL至上,尽DSL
  • 测试非常重要
  • 事情变化很快,保持学习
  • 激情活力的社区

个人意见:

就我而言,Ruby是我几年来的首选语言。你会发现令人难以置信的、大量的Ruby开源代码。Rails实在是一个了不起的Web框架,如果你知道如何使用工具的话它让使大多数的Web项目容易实现。

但灵活性和过快的开发周期也有缺点。随时准备在你的代码上投入大量时间以保持其更新以及分离废弃老的库。如果不能依靠缓存,一个成功应用的吞吐量往往被缺乏良好的并发支持限制。

Ruby开发者主要是用Rails开发,所以与框架特性相比基本不会去深入核心语 言本身的特性。他们往往是充满好奇心且机会主义的(以一个很好的方式),有些实用主义,关心代码质量/结构和测试覆盖率。Rails开发者早期采用它的典 型原因是由于该框架本身默认使用的一些新技术(coffeescript、turbolinks、CSS预处理器……)。

Ruby和Rails主要吸引了那些想把事情做得快而优雅的开发者。相比于底层计算细节,这些开发者往往是以产品导向的,他们更关心的目的和客户价值的实现。

新成员

这是些让人们兴奋的语言/技术。他们代表了运行在“云端”的编程语言的设计新浪潮。

Node.js (Javascript)

Node.js不是一门编程语言,但它是使JS在服务器端运行最流行的方法。和我对Ruby的大部分评论是关于Rails一样,相比JS我更关注Node。

理念:

  • 为实时驱动的应用程序而设计,高吞吐量、低延迟
  • DIY
  • 小的内核,剩余的内容由社区维护
  • 低耦合
  • 借鉴Ruby/Python

个人意见:

我觉得Node.js很有趣。在技术上Node没有太多新内容。Python有Tornado/Twisted,Ruby有EventMachine,C有 libevent。

事件驱动的框架已经使用了一段时间,但Node具有两大优势:*大多数JS库是非阻塞*大多数Web开发者不管怎样都要写一些JS。

在前端和后端使用相同编程语言的想法吸引了不少人,但值得与否还有待验证。

Node提供了巨大的吞吐量(只要你坚持IO操作),它很容易上手,而且写起来很有趣。

由于其本身具有事件驱动性,调试及测试面临挑战,回调处理是可维护性的地狱。我希望Node能够提供一种官方的今后或承诺的解决方案。略显凌乱的文档使在现有项目里跳转时有些困难。

Node的开发者大都是它的早期的接受者,他们更喜欢自定义而不是按惯例创建结构/模式,这样使他们觉得更舒服。它吸引开发者使用已知的语言(JS)去处 理高层的并发。Node作为一个框架处理的水平比经典的MVC更底层一些。Node开发者们也真的喜欢这个在服务器和客户端使用相同语言的想法。

Clojure

理念:

  • 实用且符合现代人使用的Lisp
  • 一切皆是数据
  • 并发性,并发性,并发性
  • 让那该死的可变状态见鬼吧
  • 能够很好地与Java协作
  • 稍微靠近科研路线,但并不影响他的实用性

个人观点:

我最喜欢Clojure的一点是它的lisp精神。一旦你攻克了它的圆括号和操作符/参数顺序,那么Clojure将很可能让你重新思考你构建代码的方式。对于处理数据跟强迫你保持代码简短这两方面来说,它真的很棒并且高效。

让我头疼的是我并非拥有足够的聪明去更多地编写Clojure。当我尝试去追踪那些数据时,我的大脑会出现溢出。对于该语言来说异常通常是没意义的,假如你尝试解决别人代码的bug,这将会是机具挑战的事情因为Clojure本身是复杂的语言,并且可以用宏来拓展。最后,Clojure社区并不是真的面向web开发,Clojure完成的大多数作品都是以数据作为中心的。

Clojure主要吸引了那些处于边缘,对编程语言有求知欲,面相数据的程序员。如果你寻找有编程语言怪癖的数据处理专家,那么Clojure将会是吸引他们的好方法。

Scala

哲学:

  • 同时具有面向对象与函数编程世界的最佳优点
  • 让编译器为你做一些工作
  • 并发事务
  • 比Java少一些规范,但是目标在于相同或更好的性能
  • 与Java生态系统和谐共存

个人意见:

当目标是JVM时,Scala目前是我所选择的语言。它的学习曲线陡峭。 知道何时使用 FP 与 OOP是非常复杂的,而且在应对该语言语法本身时也是如此。

那就是说,获得使用FP的好处,同时又在需要的时候仍然保持OOP,是非常有用的。一旦你“掌握”了该语言的风格,写Scala实际上是令人愉快的,而且它的社区也非常友好。

Play框架确实很好,它提供了一个很好的替代Rails的选择,特别是对API开发来说。Twitter的工程师团队为此提供了许多资源与开源代码。

目前使用Scala是一个非常安全的选择。Java开发者会有舒适感并会尝试这种更加“现代的”语言。动态语言开发者不会感觉太陌生,并且获得了Java生态环境,性能提升,并发性和永恒性。如果编译时间不会使你感到沮丧的话,现有工具以及惯例使得在一个成长的团队中使用Scala非常不错。

不过就像Ruby,Scala社区的文档不是很丰富。我真的希望  API文档 可以重新编写得更直观,总的说来就是更有用。但是公平的说,已经有许多非常好的资源了,比如Martin Odersky (Scala的创造者)提供的Twitter的 Scala学校和Coursera的Scala 课堂之 FP 。

Scala主要是吸引了好奇的Java开发者,他们想要一些更现代的东西,就像Ruby/Python开发者想要他们语言的一个更具伸缩性的版本。对于吸引那些想拓展它们现存开发环境的伟大的开发者,以及那些可以充分利用该语言二元性的开发者来说,Scala是一个好方法。

Go

  • 更强大的C
  • 你可以自己管理内存,前提是你不能粗心大意
  • 直观的代码更好
  • 丰富的代码库
  • 效率很快..对于任何一个部分来说(从编译到执行)
  • 存在并行编程模式,并且简单使用
  • 文档很关键

个人观点:

我真的很喜欢Go(亦称Golang)。在我使用它几年之后,我选择使用它来开发我自己新项目的API。Go或许对于一些人来说有些无聊,但它的简洁与效率是真材实料的。

Go强迫你更多地去思考你的代码的结构,你的数据/代码行为,因为你不能总是坚持面向对象的编程模式。我发现我的代码总算变得容易调试,结构更简洁,但有时会重复性比较大(例如:错误处理)。

没有比Go更加方便地开发并发业务的语言了。一旦需要编译,你的代码编译加上运行的时间会比Rails服务器启动的时间还快。Go支持一些鸭子类型 (duck typing,动态类型的一种风格),这造就了从Ruby(举个例子)转换过来显得颇为简单。对比起一些脚本语言,它所编写产品的性能实在让人觉得惊叹, 并且它占用的内存很小。

Go被设计为一个人或是一个大团队都可以为同一代码库工作的语言,而且它的身旁有很多很棒的工具值得你使用。

然而,它不是完美的语言。有时第三方依赖库很让人头疼。当你在高水平编程中运用了Go会让你觉得它的水平太低了。有些语言设计时的决策有时会引起困惑(例子:交互式接口和结构化设计)。

初创公司里,Go看起来在性能和并发事务方面变得越来越流行。我见过很多初创公司用Go替代了Node,而且另一些公司添加了Go应用作为扩展程序。

Go社区里看起来混合了一些老的C/C++学校黑客和一些喜欢低水平语言的年轻人。Go语言和社区的领导者固执的相信让人们理解他们的想法是很容易的。同时他们也允许你能快速的评估你接受他们哲学后是有多么的舒适,而且可以发现是否能达到你的预期效果。

Go主要吸引着面向性能和结构体系的开发者。他们想要轻易的实现并发,要达到C的执行速度,也要达到Python/Ruby的开发速度。他们不想在找一个新的有趣的语言,他们需要一个坚定的妥协。

技术驱动理念

技术的选择会受到理念的影响。你需要清楚而谨慎地权衡你选用的技术是否与企业的价值观一致。做出正确的决定有助于你从技术细节的纠缠中摆脱出来,拥有更多投入商务运作的时间。