查看原文
其他

实习经验分享之二 | 记我呆过的牛人密度最高的技术团队

2017-08-20 叶顺平 技艺丛谈


在上一篇文章《实习经验分享之一 | 在小公司,实习生和职场新人,学什么?怎么学?》中,我分享了第一次实习经历。那一年,假如说自己所有成长,那么更多的是野蛮生长,正如一个朋友阅读文章后总结的那样——「#用心做事+主动要活+及时复盘#才能野蛮生长」。文末提到,我会在下一篇文章中分享下我的第二次实习经验。此时,夜深人静,正适合回忆前尘往事。


当我在上一家公司实习遇到瓶颈的时候,一个猎头联系到了我。你没看错,实习生招聘,也可以使用猎头。一个好的实习生,工作产出并不会比正式员工少,而公司付出的成本却小得多。


这一次,听说对方是个前谷歌工程院副院长创立的创业公司,为求保险,我郑重其事写了封求职信:


贵公司您好,本人对互联网领域富有激情,工作认真,技术扎实,经常关注 IT 领域最近的热点和最新技术进展。关注并研究国内外各大 IT 公司的发展历程和优势所在。


本人在一个创业公司领导开发了一个即时通信产品,从明确需求,到框架分析与设计,到关键功能的实现,源码管理,任务分配,性能优化,bug 跟踪与排除,甚至到软件安全与发布都积累了相当丰富的经验。


本人的学习能力强,从开始实习时的毫无经验,到之后成为研发主力,到现在成为项目负责人,都是通过自己的学习与探索而来的。


本人对技术富有激情,相信技术可以改变生活,改变世界也相信通过我的不断努力,我自己能够成长为一名优秀的软件工程师。

我对自己的期望是,通过不断努力,
深入研究互联网基础协议和对应的协议栈实现源代码,并研究几个互联网的核心应用,包括搜索引擎,web 服务器和浏览器,P2P 下载技术,即时通信等,与此同时多多编写代码,总结 IT 最新产品的热点与技术难点,最后能够成长为一名顶尖的软件架构师,软件产品设计师。


我不知道一封求职邮件在当时有没有帮助。不过如果我看到哪位同学不仅简历过硬,技术好,还有心思写一封热情洋溢的求职邮件,我一般会第一时间让 HR 安排面试。


面试还算比较顺利。我没做什么思考,就答应加入这家公司。这家公司叫云壤。2010 年那会,移动互联网才刚刚兴起,云计算也还没当前这么如火如荼。云壤,云壤,这家公司是打算做云时代的土壤啊,大地之上,万物生发。我喜欢这个名字。


我在 2010 年9月15日前后入职云壤,在后面的几个月内,虽然面临着校园招聘这件大事,不过由于我在这家公司实习还比较开心,收获颇丰,只是聊过一两家公司,后来便决定毕业后留在这家公司工作了。当时还给前公司的老板写过一封邮件,其中提到我在云壤一个多月的收获,以及能给公司带去的价值。以下是邮件内容中的相关片段:


由于我面临毕业选择公司的问题,因此我想问问,假如我回去的话,不知道您那边能够给什么样的待遇。我先说说我回去能够做些什么工作吧:


  1. 构建 linux 开发环境,build 系统(争取集成C, C++, java, thrift, protobuf, python, php等)

  2. 构建 linux 开发基础库,包括字符串处理,文件操作,flags,logging,性能分析,内存检测等框架

  3. 构建 RPC 框架,实现跨语言互操作。

  4. 建立代码规范系统,编写(翻译)详尽的代码规范,并在之后的新员工入职后得到切实的落实

  5. 建立 code review 系统,

  6. 建立 code monitor 系统

  7. 搜集并维护开发中常用的第三方库

  8. 实现一个简单的软件状态监控基础库和一个简单的 HTTP Server

  9. 由于我最近购买并阅读了 javascript,jquery 等书籍,之后相关的方向我也可以进行开发

  10. 编写大量的 apache 模块或其他 HTTP server 模块。由于阅读了相关的代码,简单的模块我一般一两天就能搞定。

  11. 对 HTTP 协议进行深入研究并总结相关文档,让整个公司对 HTTP 协议及服务器和浏览器行为有一个深入的理解

  12. 假如需要编写一个主题爬虫或者什么,我可以使用 C++ 编写一个通用而又可配置的爬虫。

  13. 研究网站开发相关开源项目,并按照公司的需要进行修改,增强。比如研究服务器的性能,js 代码的性能,网页的响应速度等。

  14. 配合 XX,重新整理 IM 服务器端代码等。


当时我在云壤实习时间不到两个月,学习到的东西确实不算少。从上面的邮件内容可以看到,由于我之前主要做的是 Windows 开发,在实习的最初一个多月里,我主要学习了:软件构建工具、代码基础库、跨语言 RPC 框架 (可以作为微服务基础)、系统性的代码规范,代码审核(Code Review)系统,持续集成工具(比如 Jenkins)、第三方库、服务监控、前端开发、HTTP 服务、性能优化、爬虫等。


看起来,在云壤实习的一个多月时间,我学习到的东西,比在之前公司的一年还多。这说明了选择一个技术范的公司实习,是非常有必要的。当然,之前一年的努力,也为自己独立解决问题、主动学习搭下了还可以的基础。


云壤是一家技术文化非常浓厚的公司,我刚入职的时候,公司大约 20 个人,我当时的员工号是 21 号。当时给我安排的企业导师是来自谷歌的前高级工程师。在云壤创业三年后,他回到谷歌,目前在谷歌总部,任 Staff Software Engineer。


当时我在搜索研发团队,团队大约十来个人。云壤的核心团队出自谷歌,其保存了来自谷歌的几个习惯,其一便是 TGIF 文化,有关 TGIF 文化,以后有机会再专文论述。其二是工程师的 Start Project 。 


Boilerplate Detection 就是我的第一个项目。它是一个实现网页正文抽取的项目,要求使用通用算法,从网页中抽取正文。正文抽取这个事情,对网页搜索的价值不小,因为我们知道网页中很多信息价值不大,比如广告链接,底部的友情链接,版权信息,头部的导航栏,左右两侧的相关链接等。不过正文抽取的难度还是挺大的,大部分的垂直网站抽取很简单,通过配置一个模版文件,底层使用 DomTree + XPath 实现即可。不过要抽取任何网站的正文,难度却不小,原因很简单,互联网世界太复杂了,不同的网站,网页结构千变万化。为了解决这个问题,我当时学习了公司的 html parser,xpath parser,并基于 xpath parser 实现了一个 template parser——一个通用的网页解析库,支持从配置文件加载规则,解析特定网站的网页,基本做到零代码实现网站解析。


Start Project 相对比较独立,复杂度相对较低。后来我自己作为企业导师,也给很多新人设置过不尽相同的 Start Project。企业设置 Start Project,一般希望新人能够做到几个事情:


  1. 学习代码风格指南

  2. 熟悉开发环境

  3. 学习如何使用源码管理工具

  4. 学习如何发 Code Review,并通过代码审核过程,熟悉代码风格

  5. 学习代码基础库,比如如何打日志,如何解析命令行参数等

  6. 了解相关的项目代码,比如做正文抽取 ,需要熟悉网页解析相关的库代码

  7. 独立完成项目

  8. 在项目实现过程中,熟悉相关同事


当时我的导师没有给我的 Start Project 明确提出要求,不过基本上也是围绕上面的几个点来做的。


在实现 Template Parser 的过程中,有一个来自 360 的同事,给我了不少指导。当时他刚刚实现完网页解析库,包括 Html parser 和 Xpath parser。由于刚实现不久,我又是使用这些库的第一批吃螃蟹的人,因此在开发过程中,遇到了很多 Bug, 在解决这些 Bug 的过程中,我从这位同事身上学到了很多调试技巧。


实习了差不多一个月,那个实现网页解析库的同事离职,由于我对解析库比较熟悉,有一个模块当时他让我接手。由于网页解析对搜索引擎的文档处理非常重要,属于公司内使用频率最高的基础库之一,而自己又在之前的使用中,碰到了很多棘手的 Bug,因此交接的时候颇有点胆战心惊。作为实习生,要勇敢接活,自己在上一家公司的经验总结嘛,因此只好咬咬牙接手。这时,接手 Html Parser 的一位同事,决定重写整个解析库。完蛋,他重写了,意味着我也必须要重写一翻。压力更是大。不过在我熟悉了 Html Parser 代码后,基本上抛弃掉了之前 XPath parser 的大部分代码,利用新实现的 Html Parser,实现了一个更高效优雅的 Xpath parser。 当发现自己有能力实现一个基础库,并且实现的质量并不比工作多年的牛人差的时候,一种莫名的自信油然而生。


在重构完 Xpath Parser 后,我实现了 Template Parser, 之后,实现了一个网页正文抽取库,也就是 Boilerplate detector 。由于实现的都是比较基础的库,公司内很多使用的同事。大家在使用的过程中,有什么问题都会找我交流,因此我也就和公司的很多同学渐渐熟悉起来。实现基础库,从别人的反馈中找到问题,反思自己代码的问题,不断完善自己的代码,这是一个非常有趣而锻炼人的过程。比如,别人的反馈,让你认识到接口的不合理、注释和文档的必要性、示例代码的重要性等。别人提的 Bug,让你不断提高调试技巧。别人的建议,让你体验到软件迭代的过程,让你思考哪些需求是可以使用现有接口满足的,哪些需求需要开发新接口,而怎么样的新接口,能够做到尽可能通用?需求那么多,如何抽象出需求的共性,最小化接口?别人对性能的吐槽,又让你不断尝试优化性能,学习内存优化和性能优化的各种技巧。而新需求的引入,如果兼容旧接口?旧接口如何一步步废弃掉?


正文抽取这个项目后来还有个小插曲。云壤后来和人民搜索达成了合作,而人民搜索和中科院的几个老师有一些合作。中科院的两个老师也做一些和正文抽取有关的事情,当时还到云壤找我交流。我一个实习生,他们可是硕导或博导,他们找我交流,可以想象我当时的压力有多大。不过压力就是动力,只要你克服了压力,迎难而上,成长便水到渠成。


在云壤实习的过程中,还有几个事情值得写一下。


其中一个事情是代码审核。云壤的代码审核非常严格,使用的是 Review Board 系统。当发起代码审核请求后,Reviewer 会接收到邮件提醒。而Reviewer 在做了很多评论后,发起人也会接收到邮件通知。截一个当年代码审核的图:


发起 Code review Request 时收到的邮件


代码评审完成后收到的邮件


在做代码审核的时候,从注释首字母的大小写,Url 还是 URL, 变量名,函数名,类名,文件名到 BUILD 文件,版权信息,数据结构,算法效率,再到软件架构等,Reviewer 都会竭尽所能,各种折磨你。在审查代码的时候,不是处女座的工程师,一个个都处女座起来,代码面前,一切都要奉行完美主义。一般的新人,前面一两次代码审核,都会接到上百个评审意见。我也不例外。后来在我 Review 别人代码的时候,也一口气提了上百个评审意见,以至于我的导师告诉我说:“别一下子提那么多的意见,悠着点,要不会让对方沮丧的。”确实,严格的代码审查,对于没有类似经验的人,容易有被冒犯的感觉。而假如你阅读别人的代码,这位同事可能不是你们组的,或者和你不熟悉,你发现了一些小问题,直接修改代码,并给对方发了个 Code Review,对方可能更容易觉得被冒犯。Talk is cheap, show me the code」,而在秀出代码后,能不能镇静面临别人的挑三拣四,才是考验程序员的三昧真火。



第二个事情是,我获得了面试别人的机会。一般大公司,实习生不会有面试别人的机会。当时云壤高手很多,按理说应该轮不到我面试别人。得到这样的机会,有点受宠若惊,我当然很重视。在之前的一篇文章中,我提到了我目前公司的面试标准,云壤当时使用的也是从 Google 借鉴的面试标准,有兴趣的同学,可以点击以下图片阅读。



在面试官上阵之前,一般有两到三次跟面的机会。当时 HR 给我安排了两次跟面,两个面试官都是谷歌出来的大牛,我跟在他们身边面试了两次,学到了不少东西。接触不同面试官的面试风格,对形成自己的面试风格有所帮助。比如作为面试官,下面几个问题的答案是什么?


  • 面试面什么?

  • 考察哪些知识点?

  • 整个面试流程分几个阶段?

  • 在纸上还是黑板上写代码?

  • 写代码花多长时间?

  • 面试问题怎么描述?

  • 遇到面试者不会,怎么提示?

  • 提示无效,是快速切换问题还是继续死缠烂打?

  • 如何考察面试者的临场应变能力?

  • 面试者刷过这道题怎么办?

  • 如何快速考察面试者的技术面?

  • 如何考察基础知识是否扎实?

  • 如何考察简历中的相关项目?


跟面了两次后,我自己准备了一些问题,作为后续面试别人的备选题。毕竟如果面试别人的问题,自己都不能掌握得很好,或者是背后的基础知识不扎实,不知道如何变通,面试现场就会有点尴尬。当时印象比较深刻的是,HR 让我一个实习生去面试工作了十几年的资深工程师,对方还是在知名互联网公司带几十个人团队的中层管理。可以想象得出,我当时的压力是有多大。不过整理了一下思路,我也就和对方聊起来了。


学无先后。面试的过程本来就是相互交流,相互选择的过程。这次面试,让我找到了自信,也了解到了自己和资深人士的距离在哪里。面试在于寻找对方的缺点,发现对方的亮点,挖掘对方的潜能。面试的过程,也是学习的过程。学习别人简历上的亮点,学习别人项目介绍中的经验,学习别人解决过的问题,遇到的 Bug ,踩过的坑等,都会使自己受益。这次的面试尤其如此。由于我把面试当成了学习,因此后来 HR 安排面试,我总是积极配合。


在目前这家公司,我也开始有意让表现比较优秀的实习生参与技术面试,尤其是帮忙面试其他实习生。目的就是希望他们也能够得到类似的锻炼。


再后来,我开始做爬虫系统,然后做索引相关的文档处理等,短短一年的实习,相比第一次实习经历,学到了更多的技能。正因如此,毕业时,大部分同学选择了大公司,而我选择留在了云壤。有了第一家的实习经历,我在这次实习中,践行了上文中总结的以下几个点:


  • 吃透代码。

  • 做好安排给自己的事情。

  • 不要隐藏自己的缺点,多向他人学习。

  • 多读书,多读经典书籍。

  • 多做笔记,多思考,多总结。

  • 多要活。


在这次实习中,我收获了较大成长,包括代码质量,编程规范,基础工具,面试经验,代码审核经验等。当然能够认识那么多的谷歌牛人和朋友,也是难得的一笔人生财富。而很多同学,在很多大公司分别实习了三四个月,并没有得到很好的锻炼。正所谓:“山不在高,有仙则名。水不在深,有龙则灵”,公司不在大小,小公司也有牛人。实习收获大小,不在公司大小,而在项目多少、项目难度。不在舞台有多大,而在你的心有多大,想学多少。



以下是几篇和本文关系密切的文章,也是我在云壤实习和工作的两年,学到的主要经验的几次总结,推荐没有读过的朋友们阅读下:


软件构建工具

C++ 基础库构建经验

云壤——从云端到归于尘土

代码审核之道


以下实习和应届校招相关的分享文章,应该对你也有帮助。没读过的话,就点击链接阅读吧。


技术实习攻略——记我熟悉的那些北大清华实习生们

☞实习经验分享之一 | 在小公司,实习生和职场新人,学什么?怎么学?

☞实习与校招全攻略 | 这一次,资深面试官和学霸面试者搞了个深度对谈

☞学好这几招,助你在技术面试中搞定面试官

☞面试官究竟想面啥?

☞北大学罢的校招面试之路


题图:来自互联网


这一次,iOS和安卓用户都可以给本公众号赞赏啦。不信?想试试看?那就长按以下小程序吧



您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存