ThoughtWorks:毕业生的“死亡矿井”

在古老的艾泽拉斯大陆东部王国的土地上,有一个名叫“月溪镇”的村庄。每个魔兽世界的联盟玩家几乎都在这里留下过足迹,因为这里有一个副本,叫做死亡矿井。当联盟玩家出了新手村,成长到12、3级左右的时候,就可以挑战死亡矿井了。这里有丰富的经验、大量的金币和足以让人脱胎换骨的装备。一般玩家都会选择找高等级的玩家带刷,10次、20次……甚至直到20级。但也有少数玩家,会召集5个小伙伴,一起挑战里面的各个boss,小心翼翼,步履维艰,但却十分享受……

1-deadmines

如果把刚刚离开大学校园的毕业生比作魔兽世界的人类玩家,在经历了北郡修道院(大学课程)的初出茅庐、艾尔文森林(公司实习)的小试身手,击杀霍格(毕业论文)的锋芒毕露,来到人烟寥寥的西部荒野(社会),下一站是哪呢?你该去哪里提升装备、练习操作,又该去哪里学习技能、磨炼意志呢?

熟悉游戏的老司机肯定会说,去刷“死矿”啊。

没错,如开头所说,“死亡矿井”这个副本正是为这样的玩家准备的。那么对于毕业生来说,什么样的公司具备这样的环境呢?作为一名在ThoughtWorks工作了三年的老骚客(ThoughtWorker),目睹过众多毕业生从生根发芽到野蛮生长最后尽情怒放的过程。我可以负责任地说,ThoughtWorks就是毕业生的“死亡矿井”。

为什么呢?因为她骨骼清奇、特立独行,是互联网时代的一股清流。

ThoughtWorks大学和思沃学院

ThoughtWorks最吸引毕业生的一点不外乎TWU(ThoughtWorks University)了。每一个来到ThoughtWorks的毕业生都可以去印度浦那参加为期5周的集中培训,和那些聪明、勤奋、富有激情的外国同事一起,共同学习公司文化、敏捷方法论和软件开发技能。

2-twu

不同背景、不同文化的相互冲击,往往能催生意想不到的化学反应。我曾见过很多毕业生从TWU归来之后,鱼跃龙门、破茧成蝶。

除此之外,你还有可能参加思沃学院(ThoughtWorks Academy)或郑大夜校的培训,帮你在真正上项目之前打下坚实的基础。

在刚刚结束的为期六周的思沃学院暑期特训营里,就有将近100名在校学生完成了步入社会之前的重要一课。

国际化的视角和眼界

在ThoughtWorks,你将获得其他公司很难拥有的国际化视角和眼界。

ThoughtWorks是一家跨国公司,拥有包括Martin Fowler在内的众多国际知名技术专家。这些专家每年都会聚在一起,经过几天的头脑风暴和激烈讨论,产生出一份独具特色的技术趋势报告——ThoughtWorks技术雷达。ThoughtWorks的项目在技术选型时都会参考技术雷达,同时,这些项目也会反过来影响技术雷达,为它提供实践基础。

因此,ThoughtWorks所使用的技术一直都在引领潮流。以前端技术为例,P项目从11年开始引入AngularJS,14年尝试ReactJS,而今年则开始Aurelia的各种趟坑。又如微服务架构,该项目从12年开始服务化拆分之路,Martin Fowler在13年底来北京考察,对我们的实践给予了充分肯定,并在14年3月份写下了那篇著名的文章Microservices。而当今年国内刮起微服务旋风时,我们早就开始在雷达中提醒大家不要盲目迷信了。

由于缺乏国际化的视角和眼界,国内很多公司容易陷入一些误区,比如对大数据的盲目迷信,比如Gitflow,比如用Jenkins搭建部署流水线……在ThoughtWorks,这些错误往往会被扼杀在萌芽状态。

所以,你可以一直站在巨人的肩膀上,看到的风景自然与其他人不同

4-giant

先进的软件开发方法和工程实践

在ThoughtWorks,你除了可以和诸多大牛谈(结)笑(对)风(编)生(程),还能学习很多先进的编程理念,掌握优秀的软件开发方法和工程实践。

我们一向推崇的工程实践包括:Clean Code、TDD、持续交付……你很难看到那些扛着云计算大数据机器学习乃至深度学习大旗的互联网公司谈论这些,而这些恰恰是摩天大楼的地基。我曾见过很多资深的开发团队不知道怎么写测试,更玩不转持续集成。没有这些基础的实践,如何做到高质量交付呢?

除此之外,对于敏捷的孜孜以求使得我们的很多项目可以成为业界的标杆。如果你不知道敏捷该怎么做,来咨询ThoughtWorks是肯定没有错的。所以,你一定能够在这里掌握敏捷方法论的精髓,从而在未来指导你的项目。

愿意帮助你成长的团队

ThoughtWorks对于新人的要求是宽容而严格的。

宽容在于对犯错的态度。人都会犯错,但不同公司对于错误的容忍度可谓天壤之别。在某些公司,可能会因为一个小小的错误就开除你,但在ThoughtWorks,犯错是被包容甚至是鼓励的,只要你是因为想学习而不是蓄意破坏。

严格在于,我们会每个月对新人进行组内考核,俗称interview++。如果团队其他成员认为你某些方面需要改进,这些信息会毫无保留地传达给你。

虽然看似严格,但其实团队的每一个人都特别希望看到你成长,并愿意尽一切可能帮助你成长。我们不会在意你最终会超过我们,相反,如果你能够超越我们,并在更大的舞台上展示自己,我们会因曾经在你成长的道路上帮助过你而感到骄傲

5-road

这种帮助可以到什么程度呢?即便是初出茅庐的毕业生,也有可能在试用期之后就成为team leader。是的,你没听错。在ThoughtWorks,这样的机会对每个人都是平等的。相比于经验和能力,我们更看重你是否有意愿快速成长。如果有,我们非常愿意尝试让你承担更多的职责,做出更多的贡献。

例如,W项目共有6-8个小组,每个小组大概7-8人规模。曾经有一段时间所有的team leader都是毕业刚满一年且在团队中资历最浅的新人。这样的胆魄不是所有公司都有的(除非资深的人都走光了)。而这些新人也不负众望,项目在他们的带动下有条不紊地推进着。如今他们也在ThoughtWorks或其他公司承担着更重要的职责。

此外,如果你足够优秀,很可能被每天都在写代码、业余时间做吉他的中国区CTO收为弟子,由他亲手培养。是不是想想都有点小激动?

参与项目的方方面面

今年上半年,ThoughtWorks的C项目举办了一次规模空前的技术大会。在三周的时间内分享了24个话题(其中18个来自项目内部),内容涵盖开发、架构、需求、测试、安全、运维等多个方面。

7-project

对于以上话题中的内容,团队的每个成员都能参与其中。是的,ThoughtWorks希望每个开发者都能成为全栈工程师,而且开放的文化和宽松的氛围也允许你随便修改项目里的任何一行代码。从前端到后端,从开发到运维。所以,你不会像在有些公司那样,工作多年却只涉及一两个模块,管中窥豹,只见一斑,无法在一个制高点鸟瞰项目的全景。

扁平的组织结构和轻松的工作氛围

在ThoughtWorks,虽然也有所谓的领导来负责公司运营和制定各种制度,但绝大多数的员工都是和你平级的。你可能会看到有人在拍桌子争吵,但那绝对是争论某个问题,对事不对人,更不是什么办公室政治。

这样的组织结构得以成为有志者的梦想平台。我们更看重的是影响力而不是职位,只要有人愿意追随你,就非常容易推动你想做的事情。比如,曾经有一位毕业生同事,非常喜欢体验设计,自己能力提升了之后,大家都很艳羡他的能力并愿意追随他的脚步,中国区的用户体验团队几乎就是他以一己之力建立起来的。还有前面提到的思沃学院,也是由几位自带教书育人光环的同事一手打造。

而工作氛围可以“轻松”到什么程度呢?下图为不修边幅顶着一头怒发的北京办公室运营总监在午休时和其他同事一起众乐乐玩FIFA。

8-xiaoqiang

当然,我们是专业的服务公司,每个人都具备高度的自律性,这些场景只会出现在休息时间。

积极倡导经济和社会公正

ThoughtWorks有三大支柱:经营可持续的业务、推动IT变革和追求软件卓越、积极倡导社会和经济公正。这是支撑ThoughtWorks商业模式的核心,是ThoughtWorks的基石,影响着我们所做出的每一项决策。

尽管“推动IT变革和追求软件卓越”似乎更像是一家有使命感的IT公司的slogan,但实际上最让ThoughtWorker们引以为豪的并不是P2(第二大支柱),而是P3——积极倡导社会和经济公正。ThoughtWorks每年都会从利润中播出专款用于社会公益项目,帮助弱势群体。比如我们曾经开发的一款专为听障人士服务的手机App心声,可以通过语音识别技术帮助听障人士与不会手语的健听人沟通、看电视、看视频和打电话。

ThoughtWorks拒绝性别歧视,员工的男女比例在IT公司里绝对属于较低水平。并且前面提到的思沃学院还在去年创建了“卓越女生实验室”,专门帮助希望在IT领域有所发展的在校女生。ThoughtWorks也不看重学历,有很多一般大学甚至大专学历的员工,依然能够在这里施展才华。

以上是我目前能想到的ThoughtWorks的几个优势,不一而足。看了这些,你是否也觉得这里就是那个能让你旧貌换新颜的“死亡矿井”呢?

来吧,来ThoughtWorks吧,和我们一起,Stop working,Start amazing!

Share

我为什么选择ThoughtWorks?

前一阵在知乎上看到一篇关于“选择某大公司还是ThoughtWorks”的提问,于是毫不犹豫地点了进去。果不其然,除了一些同事的安利回答(尤其以Phodal同学的安利最为严重)外,也没有太多有价值的参考了。对于这种一边倒的回答,我只想说我喜欢……额不,不是这句,应该是,很可能会有阴谋论者以为是营销套路吧?

其实选择哪家公司,并不是一件多么难以抉择的事情。如果选择了某家公司却发现不适合自己,那就趁早走人呗。我相信在就业上能够有所选择的人,是不会因为在一家公司待了几个月发现不合适,辞职出来后就找不到工作的。既然现在能拿到ThoughtWorks的offer,几个月或几年以后,只会拿到更好的,不是吗?而至于是否适合自己这个问题,就只有自己才能感受了,其他人的回答只是参考。我相信题主已经做出了选择,等他过段时间再来更新吧。

ThoughtWorks是一家奇特的公司,奇特到她的员工很少有说她坏话的,不管是在职还是离职;奇特到也有一些“ThoughtWorks终身黑”一直致力于各种嘲讽。当然,对于大多数人来说,她是神秘的。

1-mystery

因为她所倡导宣扬的东西,在其他公司尤其是传统IT企业来说都太难以推进了。比如Clean Code、比如TDD、比如持续交付(当然,如果你认为这些实践对于软件开发来说无足轻重,欢迎来辩)。因此曾经有不少技术圈网红希望能够到ThoughtWorks参观,无非就是想看看,“你们说你们XXX做得很好,到底是不是真的啊。”

我在加入ThoughtWorks之前也抱有这样的疑问。因为当我看着上千行的方法发呆时,他们说超过15行甚至5行就算大方法;当我们还在没有单元测试的深渊中挣扎时,他们已经TDD得不亦乐乎;当我刚开始用Jenkins搭建好构建环境,《持续交付》出版了;当我们终于搭建起分布式应用,觉得差不多算是SOA了,人家已经把大服务砍成微服务了!同样是程序员,这么一比怎么就感觉自己不会写程序了呢?他们简直就是神一般的存在啊。

2-hero

到底是不是真的呢?以我有限的ThoughtWorks项目经验来回答:“并不全是真的。”超过15行的方法比比皆是;TDD倒是一直在践行,但是团队成员对它的质疑从来就没有停止过;持续交付还在路上,还做不到每天都部署到生产环境,我们相比Amazon还差着好几千个Facebook;而一度客户对我们的challenge是,“别再加服务了!”

但是,与其他企业不同的是,ThoughtWorks一直把这些优秀实践作为追求的目标。前路也许坎坷,但永远不会放弃。对于“代码坏味道”的争执可能贯穿整个Code Review,不辩个淋漓尽致不痛快,不为别的,只为把代码写好;TDD虽然有争议,但都在努力学习,各种workshop和培训纷至沓来,不为别的,只为get一门新技能,融会贯通突破极限成为大神;企业应用的持续交付难度比互联网要大得多,但这条路我们也基本上趟出来了,并且会坚持走下去;至于微服务,经过了那段低潮期,我们从各个方面开始调整,已经基本找到了应对之道

3-solution

所以,重要的不在于这些东西我们现在做得好不好,而在于我们一直在往好的方向上做。而在这个过程中,收获最多的不就是人的成长吗?

回到主题上来,我当初为什么选择ThoughtWorks呢?坦白地讲,对于一个在国企工作多年饱尝了世间冷暖、见识过项目百态技术却没啥进步的我来说,在换工作时并没有太多可选择的余地。要不是在拿到ThoughtWorks offer的两周前我的人生导师推荐我去ThoughtWorks试试,我可能就去一家房地产企业做甲方的技术经理了。

但选择公司这一行为不仅仅发生在当初挑offer时,也发生在每年的离职季。每年春天,拿完年终奖、过完年,那些对promotion不甚满意的年轻人就开始躁动起来,人员流动如滔滔江水连绵不绝。对于每个人来说,是去是留都要做个了断。那么我为什么每次都选择ThoughtWorks呢?

4-insights

14年初,我刚刚过试用期,对ThoughtWorks的一切都还处于看似懂了但现在看来其实too young的阶段。那时我留下来的理由非常简单,我还没有领悟到这家公司的精华,还需要不断地学习。

15年初,我所在的项目新启动了子项目,使用ReactJS作为前端框架,同时还引入了node.js。对于一心想学习JavaScript的我来说简直如沐春风。在这个时间点,国内很多公司都还没有引入ReactJS。顺便说一句,该项目从10年便引入了AngularJS,同样是国内领先。对于新技术孜孜不断地追求把我牢牢地拴住了。

时间来到去年底今年初,一位同事找到了包括我在内的几个人,成立了一个“地下组织”,开始互助写作。所谓“互助”其实就是互相督促、互相建议、互相伤害而已。除我之外,其他人都是公司里举足轻重的人物,不知道这位同事为啥会找到默默无闻的我。在其他公司,这种事发生的概率恐怕会很小。谁管你有什么特长喜欢什么呢?

5-who-cares

而在ThoughtWorks,这样的地下组织有很多。志同道合的同事们会自发地聚集在一起,为做成点事情而努力。比如BQConf和CDConf,都是大家觉得想做点什么,于是找到了一拨人一起做,需要公司帮助的时候再找领导谈。没有一个是自上而下的“委派”。半年来我们这个组织诞生了不少优秀文字、演讲和播客,以及最新的ThoughtWorks读书雷达

三个月前,我们这个小组织进行了一次团建,期间问到是什么动力促使自己坚持下来。一些同事的回答让我动容。他们的大意是说,“希望通过自己的微薄之力,保持ThoughtWorks在社区的影响力,不能让ThoughtWorks的招牌砸在我们这一代ThoughtWorker的手中。”一个普通的员工对自己的公司爱得如此深沉,让我肃然起敬。不知道文章开头和ThoughtWorks比较的那家大公司有没有员工愿意无偿做这些事情,反正我是真的为能和这样的人成为同事而感到骄傲。

行文至此,已是深夜。心有戚戚,无以言表。思绪万千,不知所云。

以上,献给入职三周年的我。

Share

微服务概述

“微服务”这个术语在过去几年如雨后春笋般涌现,它是一种构建可独立部署服务套件的软件设计方式。虽然这样的架构风格没有明确的定义,但它们在组织方式、业务能力、自动化部署、智能化终端以及对语言与数据的去中心化等方面具备共同的特征。

以下内容摘自Martin Fowler的网站

“微服务”,又一个出现在拥挤的软件架构街道的新名词。虽然我们的第一反应是不屑一顾,但它的确是一个出镜率越来越高的软件设计风格。在过去的几年中,我们已经看到很多的项目使用了微服务,目前来看效果不错,我们很多同事已经将它作为构建企业应用的默认方式。但很遗憾,并没有很多资料解释微服务是什么以及如何实现微服务。

简而言之,微服务是一种将单个应用以许多微小的服务所组成的服务套件的形式来构建软件的方法,每个微服务拥有自己的轻量级数据处理模块以及通信机制(通常是HTTP API的形式)。微服务围绕业务能力和各自独立的自动化部署机制构建而来。由于微服务需要极少的集中管理,因此各个服务可以使用不同的编程语言以及不同的存储技术。

为了解释微服务的设计风格,我们先来把它和单块架构风格做一个比较。单块架构的应用只有一个单元。企业应用常常包含三个主要部分:客户端用户界面(包括运行在用户计算机浏览器中的 HTML 页面和 JavaScript)、数据库(包括保存在常见的关系型数据库中的各种表)和服务器端应用程序。服务器端应用程序处理 HTTP 请求,执行业务逻辑,在数据库中检索和更新数据并选择和渲染 HTML 视图发送到浏览器。此服务器端应用程序是一个完整的、 单一的逻辑可执行单元。任何对系统的更改都需要构建和部署完整的服务器端应用程序的新版本。

这样的单块服务器是构建系统最自然的方式。所有处理请求的业务逻辑都在同一个进程中,它允许你使用编程语言的特性来将整个应用划分为类、函数及命名空间。利用某些方法,你可以在笔记本电脑中运行和测试应用程序,并使用部署流水线确保新的更改通过了测试,并部署到了生产环境中。最后你可以通过增加运行实例并进行负载均衡,对应用进行横向扩展。

单块应用是可行的,但越来越多的人在使用的过程中受挫,尤其是随着越来越多的应用被部署到云中。整个系统的更新周期是被绑在一起的——对应用的一小部分进行了更改,就需要整个系统重新构建和部署。随着时间的推移它往往很难保持一个良好的模块化结构,继而难以保证新的更改只影响其所在的模块。需要对应用进行扩展时,只能将整个应用一起进行扩展,而不是扩展应用中的某个部分,这也消耗了更多的资源。

MicroservicesFowler

这些挫折导致了微服务的架构方式:以服务套件的形式构建软件。微服务是独立部署的和可扩展的,每个服务都有明确的模块边界,甚至允许不同的服务使用不同的编程语言,它们甚至可以由不同的团队管理。

我们不认为微服务架构是什么创新,它的历史可以追溯到 Unix 年代的设计思想。但还没有足够多的人考虑过采用微服务架构,如果他们使用微服务,很多软件开发过程会变得更好。

了解更多信息:

詹姆斯和马丁的文章接着罗列了9个微服务的特点来定义什么是微服务架构,并探讨了其与面向服务的架构(SOA)的关系,最后论述了这种风格是否是企业软件的未来。

请到这里继续阅读:http://martinfowler.com/articles/microservices.html

James Lewis是 ThoughtWorks 的资深咨询师,也是技术顾问委员会的成员。James 的兴趣点在整合企业级系统时采用小型的相互协作的服务构建应用。他已经成功得构建了许多采用微服务的系统,并且在最近的几年里一直是社区的活跃分子。

Martin Fowler 是一位作家,演讲家和大名鼎鼎的软件开发者。如何组件化软件系统的问题一直困扰着他,一些模棱两可的答案并没有让他满意。他希望微服务不要辜负倡导者们所提出的承诺。

Share

[C#解惑] #1 在构造函数内调用虚方法

谜题

在C#中,用virtual关键字修饰的方法(属性、事件)称为虚方法(属性、事件),表示该方法可以由派生类重写(override)。虚方法是.NET中的重要概念,可以说在某种程度上,虚方法使得多态成为可能。

然而虚方法的使用却存在着很大学问,如果滥用的话势必对程序产生很大的负面影响。比如下面这个例子:

public class Puzzle
{
    public Puzzle()
    {
        Name = "Virtual member call in constructor";
        Solve();
    }

    public virtual string Name { get; set; }

    public virtual void Solve()
    {
    }
}

如果您的Visual Studio没有安装ReSharper,那么上面的代码不会有任何异常。但如果安装了,在构造函数内部给Name赋值和调用Solve时就会在下面产生一个波浪线,即警告:virtual member call in constructor。

8142-20160126002554738-552318815

这是什么原因呢?我们在构造函数中调用虚方法,碍着ReSharper什么事儿了?

其实这个警告就是提醒我们不要在非封闭类型的构造函数内调用虚方法或虚属性。但为什么这样做不合适呢?在解惑之前,我们先来了解两个概念。

类型的初始化顺序

我们先来看这样一段代码:

class Base
{
    public Base()
    {
        Console.WriteLine("Base constructor");
    }
}
class Derived : Base
{
    public Derived()
    {
        Console.WriteLine("Derived constructor");
    }
}
static class Program
{
    static void Main()
    {
        new Derived();
        Console.Read();
    }
}
`</pre>

猜一猜它的输出结果是什么?

你也许已经猜到了,它的结果是:
<pre>`Base constructor
Derived constructor
`</pre>

我们在初始化一个对象时,总是会**先执行基类的构造函数,然后再执行子类的构造函数**。

### 虚方法调用

我们再来看一段代码:
<pre>`class Base
{
    public void M()
    {
        Console.WriteLine("Base.M");
    }

    public virtual void V()
    {
        Console.WriteLine("Base.V");
    }
}
class Derived : Base
{
    public new void M()
    {
        Console.WriteLine("Derived.M");
    }

    public override void V()
    {
        Console.WriteLine("Derived.V");
    }
}
static class Program
{
    static void Main()
    {
        var d = new Derived();
        Base b = d;
        b.M();
        b.V();
        d.M();
        d.V();
        Console.Read();
    }
}
`</pre>

再来猜一猜输出结果吧。

貌似应该是:
<pre>`Base.M
Base.V
Derived.M
Derived.V
`</pre>

但运行一下会发现,真正的结果是这样的:
<pre>`Base.M
Derived.V
Derived.M
Derived.V
`</pre>

这是为什么呢?

原来对于非虚方法调用,编译器会进行一些额外的“动作”。比如**找出所调用对象的实际类型**,以访问正确的方法表(调用`b.V()`的时候就会找到变量`b`的实际类型`Derived`,从而输出`Derived.V`)。

### 解惑

现在回到我们最初的谜题,virtual member call in constructor。结合以上两个知识点,会有哪些发现?

我们稍微改造一下虚方法调用的那个例子。
<pre>`class Foo
{
    public Foo(string s)
    {
        Console.WriteLine(s);
    }
    public void Bar() { }
}

class Base
{
    public Base()
    {
        V(); // Virtual member call in constructor
    }
    public virtual void V()
    {
        Console.WriteLine("Base.V");
    }
}
class Derived : Base
{
    private Foo foo;
    public Derived()
    {
        foo = new Foo("foo in Derived");
    }

    public override void V()
    {
        Console.WriteLine("Derived.V");
        foo.Bar(); // will throw NullReferenceException
    }
}

Base的构造函数中调用虚方法V()时,ReSharper会给出virtual member call in constructor的警告。这是因为V可以在Base的任意子类中被改写(override),而这种改写,很有可能使得它依赖于自己的构造函数,如上例所示。而由于之前提到的类型初始化顺序,在执行Base b = new Derived();这样的代码时,Base的构造函数要早于Derived的构造函数执行,因此在执行到foo.Bar()foo还是个空引用。

明白了吗?我们来简单总结一下。Virtual member call in constructor的警告是因为,对于Base b = new Derived();这样的代码:

  1. 基类构造函数的执行要早于子类构造函数
  2. 基类构造函数中对于虚方法的调用,实际调用的是子类中重写的虚方法

因此,ReSharper会警告我们,这么做存在隐患。

我们能完全避免这么做吗?很遗憾,答案是不能。比如如果项目中使用了NHibernate,框架本身要求ORM实体类中,所有与数据库列具有对应关系的属性都必须为虚属性。这是因为NHibernate为了实现延迟加载,会为每个实体类生成proxy,这些proxy需要重写实体类中属性的getter/setter。而有些时候,为了业务需要,我们不得不在实体类的构造函数中对这些属性进行某些操作(比如初始化)。

我认为这么做是技术选型所致的必然结果,是完全可以接受的。但我们要注意,在代码中保证那些可能会被继承的实体,在子类中重写那些虚属性时,不要依赖于子类自身的构造函数(这几乎是可以保证的,因为与数据库列映射的属性,只能是最简单的getter/setter)。

Share

C#读书雷达

大家都知道,ThoughtWorks的技术雷达每年都会发布两到三次,它不但是业界技术趋势的标杆,更提供了一种卓有成效的方法论,即打造自己的技术雷达。在这种思想的驱动下,我们诞生了自己的读书雷达。但这份雷达略显high level,缺乏某一具体领域的详细书单。又由于最近很多同事都跟我讨论过C#书籍的问题,于是突发奇想,“滥竽充数”地搞了这份C#读书雷达,权当是读书雷达于C#这一领域的补充。

跟技术雷达和读书雷达一样,C#读书雷达也是非常主观的。并且我只会列出我读过(或粗略翻看过)的书籍,所以难免会有疏漏(如果有其他好书,欢迎各位补充)。

这份雷达同样分为四个象限:语言、应用、底层和规范,并且包含三个环,分别为初级、中级、高级。

imageC#ReadingRadar.001

基础

这个象限下的书籍都是不错的入门读物,从C#基本语法到高级应用(ASP.NET、WCF),但都是泛泛而谈,要想了解更深入的内容,还是应该阅读相关的书籍。

这三本都是大部头,适合放到案边以供随时查阅。个人觉得有其中一本就足够了。

技巧

本象限的书籍介绍C#的一些高级技巧,是学习C#的进阶读物。读了这些书,你就能写出高效优雅的C#代码。

前两本是Bill Wagner的大作,大名鼎鼎的Effective家族中的两位重量级成员。其内容包括语言习惯、资源管理、表达设计、动态特性、泛型、多线程、LINQ等等。两本书共包含100个行之有效的改善C#代码的tips,是便携C#代码的最佳实践,相信它们一定能帮助我们提升代码质量,增强可维护性。虽然这两本中文版书名容易让人迷惑,但只要记住它们的英文名(Effective C#和More Effective C#)就可以了。

《深入理解C#》是我打算重点推荐的,它是我阅读过的最好的C#书籍没有之一。它不但介绍了从C# 1开始到C# 5的所有特性,还解释了设计者为什么要这样设计。比如像迭代器块这样的特性,其他书籍很可能一笔带过,但本书却花整整一章去深入探讨,并且在补充材料中介绍了编译之后的状态机。

底层

说来奇怪,关于JVM的书籍如百花齐放,也不乏一些国产好书,但跟CLR有关的却凤毛麟角,翻来覆去就只有《CLR via C#》。但话说回来,这样的书有此一本也就足够了。本书涵盖CLR基础、类型系统、语言特性、核心机制和线程处理,常看常新,是居家旅行的必备。

如果您常逛.NET社区,一定知道赵三本,即著名.NET程序员老赵推荐的三本.NET书籍(均在本雷达中)。不过这“三兄弟”其实还后续了一位“四弟”,也就是《Pro .NET Performance》。这是我读过的第二本(第一本是《CLR via C#》)深入介绍.NET类型系统和垃圾回收的书,并且它的关注点在性能,这个领域的书籍也确实偏少。本书国内已经引进,正在翻译,不出意外的话明年应该能买到。

规范

前三个象限(基础、技巧、底层)逐渐提高和深入,有点像台阶。而“规范”这个象限有点像扶手,帮助我们更好地提高。

相比其他领域.NET(或C#)也非常缺乏规范类的书籍,这大概也是因为有《.NET设计规范》这本标杆在。本书的作者来自微软.NET Framework团队,讲述了他们在设计.NET时的一些决策过程,包括命名规范、类型设计,同时还有经验丰富的框架设计师、业界专家及用户给出的评注,为书中的许多规范增色不少。并且,它不仅对于.NET的代码规范,对于其他语言来说,也大有裨益。

《C#语言规范》是一本免费书(严格地说应该是文档而不是书),就安安静静地躺在我们安装的.NET Framework文件夹里。它是C#语言的说明文档,是以上所有书籍的最终依据。我以前会打印出来装订好,放在手边当字典翻阅。

以上就是我的C#读书雷达。

Share