编程之美 - 创作后记

转眼一年过去了,《编程之美》就要出版了。

回想大家一起合作的日子,我自己学到了很多东西。当初,看到邹欣老师的倡议

,觉得创作这样的一本书还 是挺有意义的,并且抱着跟其他优秀同事学习的想法,有幸成为了一位“作者”。其实,我觉得把我的名字挂在书上,有点尸位素饕的感觉。在编写《编程之美》的 过程中,我贡献甚微。相反,伴随着我从学生到软件开发工程师的角色转变,其他作者无形中给我上了一堂课。

最开始,我们先收集题目,大家一起讨论改进各个问题的解法,然后去掉一些
面试时并不合适的问题,手头也有了不少草稿。我一度认为,一切进展得都很“顺利”,应该很快就“大功告成”了。但很快地,我发现这些草稿,离“书”的要求还很远。

后来,事实也证明后面的工作才是最重要的。其实我是一个表达很不好的人,写作文对我来说从来都是一件头痛的事情(写这篇文章的时候也不例外)。刚开始,我 总是三言两语就写完自己的想法,有时甚至是不成熟的想法,然后就以为差不多了。相反,其他同事在这方面就做得很好,更懂得如何去把一个问题描述清楚,写得 有条理、通俗易懂。

如何进行版本维护?如何保证写作风格尽可能统一?如何把一件看似简单的事情做好?这些问题,我压根就没有考虑过。

类似地,在软件开发方面, 可能也有不少跟我一样的微软新员工,觉得自己大大小小的程序也写了一些,软件开发也就是写写几行程序,没太大问题。以前自己写程序的时候,可以随意地按自 己喜欢的方式做,变量名也不会考虑命名,函数的接口可以不用考虑,反正整个程序都在自己心里。但这就有点像是我们自己随意记录草稿和笔记,除非只是给自己 看,不考虑会有其他人阅读。不然,这草稿和笔记别人根本看不明白。这样想来,做软件开发和写一本书还真是有很多相似之处。写书,希望相关的读者能读懂;而 写软件也希望能让用户用的明白。一个团队合作开发软件,就像一伙人一起写一本书。因为你的代码需要维护,因为多人合作开发,而不是“单兵作战”,如何设计 和定义模块接口,管理维护代码?我们再也难做到整个程序都在自己的掌控之中。还有,如何写可靠安全的代
码呢…….这些是软件开发中经常碰到的问题,也是面试时应聘者容易忽略的问题。

当年,我被面试[JZ1] 的时候,曾碰到一个问题:完成下面归并排序函数,将有序数组arrX和arrY归并排序的结果存到arrZ数组中。

bool MergeSort(int* arrX, int nX, int* arrY, int nY, int* arrZ, int nZ)

在面试房间的白板上,当时我很快就把整个程序写完了,然后开始想后面有些什么难题呢?但,面试官简单的几句话就让我无言以对——“你有没有考虑数组指针arrX和arrY是否为空?它们的分配空间是否可能重叠?”那时,我还认为这些太苛刻了吧。

但在实际软件开发的时候,正是这些细节,可能会带来潜在的bug。以前,会觉得一个出错的可能性为百万分之一的程序尚可忍受,但在类似搜索引擎这种每天
被大量用户使用的软件系统上,这样的错误却是无法容忍的。

对我个人来说,参与创作 《编程之美》,给了我与其他同事合作及一起学习的机会。虽然读者们不能像我一样亲历写书过程中受到的启发,但相信读者们也可以从书中或难或易的问题里得到 一些启发。一本书的出版,就像一个新的软件系统的发布和上线。出版(发布)前的心情总是很复杂,既兴奋却多少也有些担心。兴奋,是因为我们的努力可能会带 给读者帮助,希望大家能从中得到一些启发,即使在面试的时候并不一定会碰到这些具体的问题;担心,则当然是害怕由于我们的疏忽,时间和水平的有限而存在潜 在的bug,希望读者们多指正。

Chen Yuan

我 应该算是最早知道将要编写《编程之美——微软技术面试指南》这本书的少数几个人之一。那时邹欣老师正在对《移山之道——VSTS开发指南》进行最后的润 色,而我还在学校里上研究生课程,生平第一次接受正统的计算机专业教育。当邹老师问我要不要参与编写时,作为一名自诩的“文学青年”而不是“计算机高 手”,我毫不犹豫地答应了。

我 本科读的是航空学院,在大二时闲得无聊抱着玩的心态才开始真正自学编程的,然后凭着热情和兴趣就一头扎了进来。但是,我心里一直有种隐隐的痛,我可以熟练 使用ASP.NET、AJAX很快地做出一个网站来,却对一些基本的数据结构、算法一知半解。唯一一次认真去读《数据结构》那本书还是保研机试前一夜临时 抱佛脚,通宵看了排序、树、图之类常考的重点。虽然最后考出来成绩不错,但自己斤两多少,自己最清楚。所以实际上我对许多公司偏重算法的面试一直以来都抱 有一种畏惧感和神秘感,而且非常仰慕那些受过ACM、ICPC训练过的同学,尤其是那些能很快分析出问题复杂度的人。

但 是毕竟我不是科班出身,而且只在学校里面做过一些简单的网站项目,这让我在很长一段时间里都抱有一种误解,即认为工程能力和算法解题能力是不相干的两回 事,佐证就在于有些人可以很轻松地解出一些算法题却无法用C#写一个真正可用的软件;而像我一样的人可以轻车熟路写出一个“看上去很美”的CMS系统,但 面对一些课本上的算法题时却手足无措。而且更要命的在于,简单的网站做多了,我逐渐认为做工程不需要所谓的算法,算法好只能让人拿到更高的课程分数或是竞 赛奖项,而在计算机科学这一非常讲究实践的领域中,只有良好的工程能力才有办法真正实现某个项目。于是,在很长一段时间里,我对那些能通过解出很难的算法 题拿到很好的offer的人都比较嗤之以鼻,并对那些公司的招聘标准感到疑惑不解――明明是我更能干活,实践经验和能力上更强,凭什么不要我而是他们呢?

我 觉得我最大的幸运在于,随后的一些经历让我很快走出了这个误区。在本科的最后一个学期,我幸运地获得了一个前往微软亚洲研究院实习的机会(面试时考了我一 道智力题而不是算法题J)。在实习过程中,我才“真正”地做了一个软件项目,并且通过和其他实习生的交流,“耳濡目染”地看到了许多现实中的研究性软件的 开发过程,这些经历带给了我许多前所未有的体验。在现实的软件开发中你会看到各种形式各异的需求,比如在一定数量的帖子中找出发帖最多的“水王”,在这之 前我开发过的网站最多也不过几千条记录,所以我即使用最简单的遍历也能很快实现这一功能,但是当你面对的是十万甚至百万级别的现实数据时,问题就从最基本 的“实现”变成了“更快更高效地实现”了!令我感到汗颜的是,我往往只能用效率最低的复杂度实现类似的功能,而面对如何更优雅更高效地实现它时,我常常感 到力不从心。

这 些经历让我逐渐意识到,我所沾沾自喜的工程实践能力实际上只是一种“实现”的能力,而在解决现实世界的实际问题时,更需要的是一种“优美的实现”,因为只 有在可接受的时间或空间约束条件下的实现才是真正能解决问题的答案。而如何找到所谓的“优美的实现”,一个人的算法能力在这里就起到了决定性的作用。算法 实际上是对现实问题的抽象,因为现实问题是复杂的,我们可以把它抽象成模型。寻找合适的数据结构表示问题模型,并通过分析,寻找到对应的解决算法,这种抽 丝剥茧的思维方式将会使得开发者事半功倍。那句著名的“软件 == 算法 + 数据结构”并非空穴来风,我也从这些经历中逐渐理解了微软等公司的招聘标准实际上没有错,因为他们需要找的是能真正通过分析来解决实际问题的人。如果把工 程实践能力比作一辆车的轮子,那只能说明这辆车具有了移动的能力,而让这辆车能又快又稳地运行,则需要算法分析能力这台强劲的发动机驱动,这两种能力是相 辅相成的。

我 觉得自己更大的幸运在于,在我逐渐明白了这些道理后,参与创作了《编程之美》这本书。编书的过程也是我自己动手解里面一道道有趣题目的过程,期间我对一个 个优美、巧妙的解法拍案叫绝,在遇到难题或想不通的时候,就通过与其他编者一起讨论解决,这些经历都让我不断体会到“解法之美”和“问题之美”。《编程之 美》里的许多题目实际上都来源于现实项目中所遇到的具体问题,它们或是实际问题的简化,或是改头换面以其他有趣的场景表示出来。但是万变不离其宗,通过把 问题抽象化,并运用算法分析寻找解决方案将是解题的利器。这种思考方式也是我们希望通过本书传递给读者们的。祝大家能在阅读的过程中体会到“美”的无处不 在。

Ju Liang

在很久以后才意识到BOP原来是“Beauty Of Programming”的缩写——在我设置了outlook里bop puzzle目录接收bop组的邮件很久以后。

BOP,《编程之美——微软技术面试心得》,虽然标着“面试心得”有些落俗,但或许会让更多的人在看到副书名时受到较强的阅读刺激(我是倾向于“编程之美”这一书名的)。

接触BOP于2007年8月——来微软入职一个月后。而在大约一年前,也在为找工作做准备:写简历,在网上看笔试面试题,也包括面经,似乎也在图书馆的新书阅览室里读过一本简历/面试相关的书(后来也证明,这些确有帮助)。

2007年7月入职,然后是很多的training。邹欣是其中一个Engineering training的coach。一次,他在邮件中给了一个有趣的Stone Quiz,后来偶给了一个数学解,就幸运地来到BOP创作小组。

当 时BOP的题库都基本定了,初步的解答也有。接下来需要做的是review,包括解法的验证、给出新的算法、文字语言润饰、代码规范、标点符号、字体大小 颜色等等。题目的状态从active(待修阅)到peer review(我们修阅后)到editor review(出版社修阅后)再到active,如此多轮往返,直到大家都满意。这本书不在我们的commitment之内,没有分配常规的工作时间,所 以很多的时候大家会用周末开会,或者晚上在中餐馆小聚,谈下各自的进度,或者中午在日餐馆,一起review一组题目。在这个过程中,也很是享受,能分享 到别人算法的美妙,自己也会在细节处求精。(后来因为项目很紧,没能更多的投入,有很多歉意)

在面试中,我多次被问到,为什么选择计算机。源于兴趣——而这又多是缘于数学。虽然大概小学就喜爱数学的,但真正窥见数学其美是在高中图书馆的书堆里读了《趣味数论[JZ2] 》,书里也是列举了很多有趣的数论题目,从多个角度给出了优美的解答,用通俗简单的语言。很多年过去了,后来虽没有学数学专业,却仍是记得那本书,以致即使对于学文的人,我也会推荐他们读这本关于数论的书。

现在,对于学计算机的年轻人,我会向他们推荐《编程之美》,对于非学计算机的年轻人,我也会推荐《编程之美》,相信书中用通俗简单的语言解说的优美思想也会吸引他们的兴趣,让他们受益。

希望《编程之美》能让更多的人进入程序世界,感受这个世界中引人入胜的美。

Rui Hu

很久以前就听说邹欣老师要 出一本微软亚洲研究院关于编程艺术的书,但是自己很晚才加入到这个人才济济的编写团队中来,也因此错过了许多的故事。究其原因,大概有两条:一是因为邹欣 老师当年是自己的面试官,而且当年他给我出的第二个题目我当时并没有得到很好的结果,想起这个,心里总是有些忐忑;二是自认为对于编程的认识并不能说有多 么深刻精辟,自己和印象中的那种大师风范好像还相差非常远,怕在众多的武林高手面前献丑丢脸。因此也就犹豫到今年9月份才真正加入这个队伍做一点事情, “Better later than never”,后来发现,能够有幸加入到这样一个团队做这么一件有意义的事情,机会很难得。

自认为不是程序设计天才, 但对于那些传奇的程序设计大师境界,“虽不能至,心向往之”。自己看过不少关于计算机和程序设计方面的书籍,面试过一些程序员,也在实际的工作中遇到过很 多的编程问题,对于程序设计有了自己的一些体会。程序设计其实本质上是一个知识和能力综合应用的过程。要编写出好的程序来,基础知识很重要,如果基本的数 据结构和经典的算法都不知道,很难编出很好的程序来;但是当你有了一定的基础,基本了解了常用的数据结构和算法以后,想象力和思维方式就更为关键,正如爱 因斯坦所说:“想象力比知识更重要”。知道什么时候在什么样的问题上采用什么样的算法和数据结构,非常不容易;如果还能够将一些常用的算法和数据结构针对 特定的问题做一些优化和修改,甚至创造出一些新的数据结构和算法,就更为难得。

计算机方面的书籍很多,讲 述基本算法和常用数据结构的书也不少,《编程之美》的创作思想和一般的编程书籍不大一样,全书并不是给大家讲解一些计算机和程序设计的理论知识,而是通过 分析讲解实际生活中的一些问题,来启迪大家的思路,让大家体会程序设计的思维方式。这本书的独特之处就在于,它更强调的是描述程序设计的思维方式,分析的 是将实际问题抽象为计算机程序设计问题,并找到最优算法的过程,并且花了很多精力来比较各个算法的优劣,并分析各个算法的复杂度。

参与创作这本书,通过和邹欣老师以及其他作者之间的交流和讨论过程,我接触到了很多以前从未碰到的新奇的问题,学到了很多精巧的解法,更重要的是,开阔了自己的思路,也认识到了程序设计科学和艺术的博大精深,需要用一辈子去学习、提高。[JZ3] 希望,读者朋友们也能通过这本书得到自己的收获。

Tie Feng

实在很难相信,我这个不容易坚持持续做完且做好一件事情的人,竟然坚持花了近一年的时间和大家一起创作出了一本书。

历经重重修改、审阅,这本《编程之美》的修改已经接近了尾声。

这一年的时间,也正是我到微软工作的第一年,也经历了从一个求职者、软件工程师到面试官的角色转变。而这个过程,也伴随了整本书的出版过程。

作为一个曾经的求职者,当 时自己能够做的,就是搜集和整理能够在网络上搜刮到的所有题目。算法题、智力题以及各种面经。把各种题目做到让自己条件反射为止。而这本书的创作过程之 初,也同样如此。把自己经历过的、网络上看到的、同事们讨论过的题目统统都拿过来,进行分类和研究,作为撰写书籍的原材料。虽然美中不足的是有些题目的分 类略微牵强,但是,从分类的结果来看,也基本上代表了微软会经常probe面试者的几个方面: problem solving, coding skills, algorithm analysis skills。

而作为一个软件工程师,编 写程序是本职工作。每个新人必受的打击,就是code review。在这个review的过程中,你能够体会到多年的编程经验会体现在什么地方。你会发现就算是短短的几十行代码,review之后,可能一行 都不能用。的确如此,当你的产品发布出去之后,你希望它能够稳定使用,不出任何问题(当然,这是理想情况)。你会发现需要考虑的,实在有太多的问题。

在release了第一个 project之后,回过头来再看看同事们的解答,以及中间附上的代码,就能够清楚地从自己写的代码中看出编程的功力。自己工程的实践、同事们在code review过程中对代码提出的种种质疑,以及处理种种程序在实际运行中碰到的问题,也为我积累了更多的思考,并且会更加了解应该通过题目给读者传递怎样 的信息。

而当自己开始面试 candidate的时候,还是有更多的收获。在面试的高峰期,一周之内大概会有3个电话面试,3个on site 面试。在HR统计的结果中,我手上的通过率不到20%。在面试的过程中,我也会直接拿书稿中的题目来挑战面试者,希望能够看到有精彩的解法。同时,也是对 题目的一个有益的补充。不仅如此,怎样的面试题目才能挑选出一个合格的软件工程师?反过来,换到读者的角度,这个问题应该是,微软到底会出怎样的题目来甄 别求职者?

以我个人的经验来看,分析问题的方法更加重要。这也是在书中努力想传达给读者的重要信息。

从分析的套路上来说,作者们也都是通过先提供一个简单的方法,然后试图找出一个更好的办法,这样不断地挑战自己的智力来分析题目。

而这个过程,也正是面试的过程中,面试官和求职者的互动过程。这也是每一道题目想教会给读者的一个套路。

 正所谓“无招胜有招”、“万变不离其宗”。题目只仅仅是一个表象,面试的过程中希望看到的却是面试者真正的实力。

所以,也真心盼望读者能够在阅读本书的过程中,体会到面试官到底想probe出些什么skills。

在本书的创作过程中,从邹欣老师身上学到了不少东西。也让我明白了一个道理:不怕慢,就怕站。方向确定后,只要天天有行动,最终一定能够有结果。计划一定是要以执行为依托的。

限于作者们的水平,每一道题目的解答绝非尽善尽美,甚至还会有潜在的bug。也切盼能够得到读者的反馈。

 

    原文作者:phphot
    原文地址: https://blog.csdn.net/phphot/article/details/2290799
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞