如何成为优秀的程序员?

作为一个从业快10年的程序员,我想给新入行的程序员们一些建议。这些建议是我希望自己可以在毕业时就读到的,也希望它们可以帮助你成为一个更好的程序员。

简单归纳一下,总共有7条:

  1. 保持健康
  2. 编程之外的爱好
  3. 持续学习
  4. 正确应对犯错
  5. 不要囿于角色
  6. 展示你的创意
  7. 刻意练习手速

下面我来详细说说每一点。

保持健康

三寸气在千般用,一旦无常万事休。

——《金瓶梅》

首先要说的当然是健康,脱离了这个本钱,一切都无从谈起。

久坐、不运动、睡眠不足、不注意及时补充水分、长期的伏案工作等都会对健康造成很大的影响,而不幸的是,程序员这几样全都占了。很多程序员往往年纪轻轻就已经有了各种各样的疾病:颈椎病、腰椎间盘突出、高血脂/高血压、胆结石、腱鞘炎等等,关于程序员过劳死的新闻更是隔一段时间就来刺激一下我们的神经。

研究表明,长期保持同一姿势(不论坐着还是站着)对身体都有不同程度的害处,而且这种害处是无法事后弥补的。也就是说,如果白天上班坐8个小时,那么就算你下班后去健身房练一个小时也于事无补。这几年很流行的“站立式办公”也是一样,如果你白天站立时间过久,会对膝关节造成较大的压力,同样会损害健康。比较推荐的方式是,写30-40分钟代码就起来走一走,喝杯水,远眺一会,跟同事聊聊天。

我知道,作为程序员我也常遇到那种写代码写High了连厕所也不想去的时候。不过为了长远的健康,还是要养成良好的习惯。

戒除不良习惯

除了长时间保持同一姿势之外,许多程序员还有各种不良习惯。比如:

  • 吸烟
  • 喝酒
  • 嗜糖(碳酸饮料,其他高糖饮料)

这些习惯一般都会被美其名曰提神,大家都知道,程序员加班在业界算是比较常见的,萎靡不振是常态。然而这些号称提神的方法,其实没有一个是真正管用的。这些不良习惯说到底都是一种“毒瘾”,跟吸食大麻在本质上并无二致。不过好消息是你完全可以戒除这些不良习惯,只需要坚持一段时间,让“毒瘾”过去就好了(和真正的毒瘾一样,它们更多的是精神依赖,一旦你战胜了自己对它的精神依赖,就可以获得自由)。

我在大学和刚开始工作的前几年,也有烟瘾。写代码写累了就会去办公室外边冒一根,那种一氧化碳中毒带来的短暂微醺感确实令人有放松的错觉,但是抽完烟回来写代码会感觉更累。而且口中老感觉有异味,咽喉不适,最主要的是精神萎靡,终于有一天我受不了了,决定戒烟(事实上和很多人一样,之前也有过无数次的戒烟)。当烟瘾发作的时候,我就去喝杯水,晚上则站站桩(站完之后口齿生津,神清气爽)。刚开始的3天是最难的,一周之后我基本可以控制住去抽烟的欲望,然后就越来越轻松,完全感觉不到烟瘾对我的影响了。

碳酸饮料、高糖饮料也是一样。在饮食本来就不充裕的自然界,我们的祖先遇到了富含可以为身体提供能量的糖(比如蜂蜜),自然会大量摄入。这种嗜糖的基因在今天还在不断的产生作用,但是不同的是,我们现在可以很轻松的在食物、饮料中摄入比身体所需多得多的糖。这些糖会给健康带来很多问题,比如肥胖,高血糖,冠心病等等。

更多时候,我们想要喝饮料更多的是精神上的依赖,也就是上面说到的“毒瘾”。戒除对糖的依赖比烟和酒要困难一些,因为生活中有很多陷阱,比如酸奶、面包、饼干、水果等等。

零度可乐的陷阱

现在香烟的包装上印有焦油含量,有10mg的、有15mg的。焦油含量是影响一支烟口感的重要因素,通常说的“绵”其实是说焦油含量较低,这会让你感觉比较健康。然而陷阱是,一支烟抽完觉得不过瘾,神经感受到的刺激不够强烈,这会驱动你抽第二支,结果吸入的焦油反而更多。本来15mg焦油的一支烟就可以让你过瘾,现在两支10mg的才能达到同样的效果,相当于摄入了20mg。

零度可乐也是一样,那种无糖的有着甜味的添加剂会刺激你对糖的渴求,你需要摄入更多的糖来抵消这种虚幻的渴求,然后变得更不健康。

有人可能会说,没有这些嗜好,那活着有什么意思呢?相信我,当你戒除了这些“毒瘾”,有了一个健康的体魄,才真正能体会到活着的乐趣。当你为这些嗜好所控制,产生的那种病态的舒适感其实是虚无缥缈的。

一些建议

有规律的做一些运动可以缓解颈椎、腰椎的不适,可以加快新陈代谢的速度,消耗多余的、会沉积下来的能量。比如比较容易接触到、也容易上手的运动:

  • 瑜伽/普拉提
  • 乒乓球
  • 跳绳

选择一个适合自己的运动方式,然后将其培养成一个习惯(比如坚持每周两次瑜伽,或者每天中午打30分钟的乒乓球)。如果这些和工作有冲突的话,比如公司要求长期晚上加班,那你可以考虑换一家公司。

培养一个编程之外的爱好

如果让不同的人对程序员打标签并排序,一定会排在前三。在任何的聚会上,程序员总是很容易被识别出来的:聪明、戴眼镜、话不多、略显闷骚、聊天容易冷场等等。也难怪,长期钻研技术,沉浸在非黑即白的二进制世界,爱刨根问底,这样很容易把天聊死。

我建议新手程序员可以找一个编程之外的爱好,一来可以拓展自己的社交圈,周末可以有个不一样的过法(而不是宅在家里写代码);二来可以帮助你成为更好的程序员。

你肯定有过这样的经历:一个编程问题一直困扰着你,试了很久都找不到解决方法,结果出去散了会儿步,或者和别人唠家常,突然脑海里灵光一闪,想到了问题的答案。事实上,我们大脑的工作方式就是如此奇妙,换一个完全不同的上下文就可以让大脑得到很好的休息,而且往往可以产生1+1>2的效果。写代码写累了去听听音乐,或者打一会乒乓球就可以很好的缓解疲劳,甚至可以打开思路,产生新的灵感。

一些建议

学习一项与编程无关的技能,比如:

  • 乐器(如吉他,架子鼓)
  • 绘画(素描,水粉,水彩等)或者书法
  • 制作美食
  • 某一项武术(拳击,泰拳,空手道等)

这些看似毫不相干的爱好可以帮助大脑休息。另外需要注意的是,你无需真正成为某一项爱好的专家,不要有额外的压力:担心演奏不好、没有绘画天赋等等。没关系,它只是一个爱好而已。

我自己就尝试过很多不同的爱好,比如素描、书法等。

持续学习

软件开发是一个需要终身学习的行业(其实如果你不想做那种混吃等死的人的话,基本上每个行业都是这样)。我毕业的时候,SSH(Spring Struts Hibernate)是Web开发的主流,jQuery则是前端的新锐。有一些企业开始尝试AdobeActionScript,不过这个语言很快就消逝在了人们的视野中。基于jQUery,但是融入了MVC理念的Backbone.js提供更高级的抽象能力,成为了开发“大型”前端应用的首选;紧随其后的,大而全的Angular.js则通过内置的双向绑定、依赖注入、完善的测试支持等让前端开发变得和后端开发一样健全;再后来虚拟DOMReactive范式React栈则又一次颠覆了前端的开发方式。虽然现在还不知道下一次的颠覆会在哪里发生,但是可以肯定的是它一定会发生

除了基础框架之外,各种构建工具也是层出不穷,从最早和后端放在一起的mavenrake,到基于NodeJSgrunt,再到gulp,到webpack,最后又回归到npm script

程序员被裹挟在技术演进的洪流中,不能自已。作为程序员,你不但要非常扎实的掌握基础知识(操作系统原理,计算机网络,数据结构,算法等),还需要有非常强的快速学习能力,以及愿意不断去学习的态度,而后者可能更重要。

一些建议

  • 读书
  • 通过视频/文本教程等学习新技术

建议新手每天抽出一个小时来读书,周末可以多读一些。ThoughtWorks有个读书雷达,是一个很不错的书单,包括了很多的经典书籍。读书之外,还可以在线学习一些教程,比如TutorialplusEgghead等,都非常值得经常去看看,如果有比较新鲜有趣的技术,不妨自己亲自动手试一试。

关于英文能力

毫不夸张的说,英文能力是优秀程序员和普通程序员的华丽分割线。有了好的英文能力,可供你学习的资料库会立刻扩大数百甚至数千倍:海量的优质免费教程,视频,和优秀的中文教程一样,它们都深入浅出,通俗易懂,风趣幽默,只不过中文的会比较少,而且一般总是会滞后于英文版本而已。

英文能力不但可以帮你熟悉各种前端库、CSS框架等的介绍。还可以让你学习世界各国程序员对各种库的测评、框架的使用心得、踩过的坑等等。

我在2012年加入ThoughtWorks的时候,面试时磕磕绊绊的说不出话来。等到6个月试用期结束的时候,已经可以出差去澳洲和客户的OPs谈笑风生了。2013年的8月,在印度普内,我已经可以用英文给来自世界各国的学生讲课。

除了更顺畅的和不同文化的人交流、讨论问题之外,可以明显感觉到学习的速度变得更快,更有效率。

我自己实践过的一个比较有效的方法。我每天会花两个小时(早晚各一个小时)看澳洲之音上的视频,我会听写出视频中的每一句话,如果听不清就重复,有的句子可能会重复十遍。听到最后,视频中的每句话我都能听懂,而且能一边听一边写出来。这样坚持了差不多3个月,我基本上就可以听懂客户的需求澄清,开会的时候也可以比较完整的听明白每个人讨论的点。

其实诀窍就是坚持,这3个月中,每天两个小时,我没有一天间断。过了这一关之后,就很容易了,尽量多听多说就好。

另一个提高的方法是翻译书,我更建议你跟另外一个有经验的同事一起翻译,大家互相监督,也有个照应,比较不容易半途而废。

正确应对犯错

斯坦福大学的Carol Dweck教授通过一些实验和后续的研究提出了很有名的心智模型(Mindset)理论,简而言之,她发现不同的人们对待失败这件事有着完全不同的态度:有一类人害怕失败,失败后会变得不能接受,而且容易否定自身并影响进一步的尝试,Dweck教授称这类人为固定型思维模式(Fixed Mindset);而另一类人则“喜欢”失败,视失败/犯错为学习的一种方式,他们更关注过程而不是结果,Dweck教授称其为成长型思维模式(Growth Mindset)。

Dweck在演讲中提到,通过向成长型思维模式的转变,关注从失败/犯错中学习,人们的潜力可以得到很好的发挥,也更容易获得理想的结果。

很多新人不敢尝试,又不愿意让同事知道自己的不足,这样的态度会导致他更倾向于选择更容易的工作,这样就可以避免暴露自己的不足,久而久之就会形成恶性循环。其实企业对于新人的期望一般都不会很高,对于新人犯错也是有容忍度的,新人要勇于承认自己的不足,勇于尝试新的事物,勇于犯错并从中学习。

承认自己的不足在刚开始是一件很困难的事情,不过在尝试过几次之后,你就会发现其实也没有那么恐怖。你慢慢会喜欢那种不带任何包袱的、全身心聚焦在学习本身上的快乐。

不要被角色限制

都梁在《血色浪漫》里有段描述陕北农民的文字:

钟跃民惊讶地发现,在如此贫困恶劣的生存状态下,村民们却很少愁眉苦脸, 他们始终很乐观,他们最喜欢谈论的话题是饮食男女。在饮食方面,由于他们没见过更好的食品,所以坚持认为酸汤饺子和油泼辣子是天下最美味的食品,如果有人提出世上还有很多更好吃的东西,那大家会一致认为此人太没见过世面,这八成是没吃过酸汤饺子,才在这儿胡咧咧.

就像酸汤饺子并非天下最美味的食品一样,开发也不是世界上最牛逼的工作。任何一个良好的,健康的产品、项目都需要不同的角色共同配合,共同努力。如果仅仅将自己局限在程序员这一角色,时间久了未免会有坐井观天的狭隘。

作为程序员,既可以往上游去探索需求的梳理,用户痛点的分析,业务价值的挖掘,又可以向下游如测试的编写,产品的发布,运维监控。视野开拓了,才有可能对产品有整体的了解,也更容易在程序员这个角色上做的更好。

作为新人,能在自己擅长的方面发挥长处当然很好,但是如果仅仅局限在自己擅长的方面则未免太过单薄。如果你在前端非常有经验,那么除了将这些经验和知识分享给别人之外,你还可以向别的角色学习他们擅长的技能,比如向测试学习自动化、SBE等;向后端学习高性能,高可用服务器的技术、数据库设计及优化、API设计等;向DevOps学习运维技能,自动化provision技能等等。

这些不同的技术不但可以让你的视野更加开阔,也可以为自己以后尝试不同的角色和机会打好基础。以我自己为例,我刚工作的时候是一个Java开发,后来开始做产品的前端开发。换了工作后又跑到Linux下用C写服务。再后来加入ThoughtWorks后,正经职位是开发,不过在项目上还兼职过一段时间QA,在有些项目上,当UX不在场的时候还可以做些简单的设计,在技术社区当讲师,还在一些客户现场做过咨询顾问。我自己觉得在不同的角色上切换非常有意思,我自己也很享受整个过程。

展示你的创意

将一个创意、复杂概念或者想法简洁而准确的描述出来是一个非常重要的能力。我见过太多的程序员都是沉默寡言,讲东西声音又小,又紧张,即使有很好的想法也难以完整的表述出来。

不过这个能力是可以锻炼的,只需要借助原型的制作就可以了:

  • 画图
  • 静态原型
  • 纸上原型

俗话说,一图胜千言。你只需要学习一些简单的绘画技巧就可以大大提高自己的表述能力。

通过用静态页面(HTML/CSS/JS),mock数据等方式,快速的将创意表达出来是程序员的一个优势,你可以用静态数据、数据文件等方式,通过一些简单的代码快速的作出可以做交互的原型,然后通过和用户不断确认的方式来渐进增强,这种做法可以避免太大的浪费,尽早的将客户价值交付。

原型并不局限在草图,可以工作的静态页面,还可以是一个清晰简洁的演讲。基于PPT的原型还可以用来分析目前产品痛点、对比方案的优劣、展示自己的看法等等。

纸上原型是另一种低成本,可供快速交流沟通的原型方式:

(图片来自我在ThoughtWorks的同事刘海生)

手速

关于程序员是否要求很快的手速是一个颇具争议的话题。支持者认为这属于基本功,每个程序员都应该打字都很快;反对者则认为程序员的价值在于思考并解决问题,追求速度快,那还不如招个打字员。我个人的观点是,好的程序员应该有很快的手速(包括打字的速度,但不局限于此)。

我在ThoughtWorks西安办公室组织过很多次提升手速的工作坊,比如三周三页面闪电计划等。基本原则就是对一个具体的“作业”,不断的重复练习。

最近带两个新人,我给他们布置了一个简单的作业:

图片来源:dirbbble.com

基本要求是以最快的速度实现这个页面,并有一点微小的交互(比如选择联系人之后的checkbox会显示选中状态,剩余invites的数量减少等)。第一次做他们用了5个多小时(连同搭建环境,安装Node.js,npm包等),第二次用时2个半小时,第三次用时1个半小时,第四次用时50分钟。

对同一个页面的不断练习听起来是在做重复工作,其实可以联系到很多的内容:

  • 命令行的熟悉程度
  • 快捷键的使用
  • 搜索引擎的使用
  • Stackoverflow的使用

当你真的可以熟极而流的时候,你才有时间来考虑如何优化,比如如何抽取模板工程(这样下次做同样的事情就会快很多),如何精简DOM结构,如何用命令行工具来帮助自己提速等。手速是大前提,没有速度,一切优化都是脑海中的意淫,无法真实落地。

总结

要成为一个厉害的程序员,首先当然是要有一个好的身体。此外需要培养一个编程之外的爱好,这样可以让你活的像一个正常人(而不是传统的工科书呆子)。程序员是一个需要不断学习,不断充实的职业,在学习的过程中,英文能力可以帮助你学的更快,更有效,另外正确的应对学习过程中必然会犯的错误,并将每次错误都当成学习的机会。

开发只是软件开发流程中的一环,程序员需要拓展自己的视野,和其他角色一起配合才能保证产品的交付。在日常的开发中,程序员还需要快速、准确的将自己的想法和创意表达出来。最后,更快速的完成手头的工作可以让你有更多的时间来思考,来改进那些低效的工作方式。

扩展阅读


更多精彩洞见,请关注微信公众号:思特沃克

Share

从程序员到培养者

最近,看到越来越多当初一起写代码的程序员朋友,成为了Team Lead,Tech Lead,Manager,Buddy,Sponsor,Coach,Trainer,Mentor。

我一方面为他们感到骄傲,骄傲他们走出了舒适区,从一名单纯的程序员,走进了培养者的行列。另一方面也为他们感到担心,担心他们会和我刚开始那样手足无措。

去年6月,在工作的第8个年头,我加入了思特沃克学院,从程序员变成了培训师。我还清楚地记得当时满脑子的困惑:

  • 讲一天课嗓子会不会哑啊?哑了第二天怎么办?
  • 学员觉得我的课很无趣怎么办?我会不会像高中的政治老师一样,成为催眠师?
  • 学员在课堂上提出刁钻的问题挑战我,我该如何应对?

第一次培训的场景还历历在目,与其说培训,不如说是演讲。一个人干巴巴地讲了一天,学员在下面不断地点头,偶尔一下点过了、碰到桌面才被惊醒,擦掉嘴角的口水继续点头。不过,从那次以后,我就再也不担心嗓子会哑了。为了增强自信心,我参加了「视觉引导工作坊」、「发声训练」、「幽默训练营」。甚至在做了10个月培训后,还自掏腰包参加了最贵的TTT培训。

我看到我的程序员朋友们,在成为培养者后,同样感到迷茫和困惑,因此想把我的一点心得分享给大家,期望能帮大家少走一些弯路。本文不谈为什么要成为培养者,只谈培养者应该具备的心态、可以使用的技术和一些实用的技巧。

成为培养者之后,在学员们一次一次的正向反馈中,我更加热爱这个角色。并逐渐确认了自己的使命:

成为一名专业的培养者,灵活运用培训、咨询、教练、引导、辅导等技术,身体力行地影响他人做出积极的改变!

如何解读呢?首先,培训、咨询、教练等都是技术,作为一名培养者,不应该限定自己使用什么技术,就好比程序员不应该限定自己是「Java 程序员」、「Ruby 程序员」一样。只要能发展他人,都应该为我所用。其次,我认为培养者必须身体力行。作为培养者,如果我自己都没做过,就教给别人,那是不负责任;我做过了却不持续做,说明我不是真的认同。我特别信奉一句话:

The day you stop learning, the day you should stop training.

如果我自己都不学习、不成长,怎么能要求别人学习成长呢?再次,人只能改变自我,没有人可以改变别人,我只能改变自己,从而影响别人。最后,积极的改变。不能仅仅限定为教技术,心态的变化、习惯的养成比学会具体的技术要有价值的多。

心态篇

培养别人的过程就像是把水从一个瓶子倒入另一个瓶子。首先需要打开对方的瓶盖,打开瓶盖就是建立信任、安全感。让学员知道凭什么要跟我学、跟我能学到什么、学了有什么用、我会如何教、他需要如何配合等等。其次,如果直接对着对方瓶口倒,大部分水都会流出去,因为对方的瓶子有瓶颈,那就是学员过去的经历和经验。我们需要借助一些工具,才能把水又快又多地倒进对方的瓶子。所以,我们要调整好自己的心态,运用发展他人的技术,才能影响他人做出积极的改变。

不必等自己成为专家,才开始培养别人。

培养者应该放低自己,不是「教」什么,而是抱着一种「分享」的心态。当然,你需要对自己所分享的知识有判断力。大海之所以能纳百川,就是因为它把自己放得足够低。

如果总觉得问题在别人身上,就永远无法提高自己。

刚刚开始做培训时,有个问题让我夜不能寐:学员不跟我互动。我提出一个问题,没有人回答,我想请学员做个分享,没人愿意站起来。于是我抱怨学员不够积极主动。时间长了,我意识到根本不可能遇到一班积极主动的学员。我应该从自己身上找原因,于是我带着这个问题请教一位前辈,他的答案是:从始至终都要建立相互信任、轻松的学习氛围。当我自己做出了改变(详情见后面的技巧篇)后,再也没有冷过场。

(图片来自:http://t.cn/Ran4ps0)

程序员善于发现问题,而培养者需要善于发现亮点。

比起批评、指出不足、提出建议,更加重要的是:赞美、指出亮点、鼓励保持优点。一旦学员的积极变化得到鼓励,他就更有提升自己的动力,也就自然而然会去关注自己需要提升的地方。

比起我说了什么,我做了什么更重要。

为了给学员传递可视化实践的价值,我会把可视化融入到整个培训中,而不是通过言语来告诉他们。

比起学员说了什么,他做了什么更重要。

我们需要根据学员的反馈优化教学方法,培养者需要培养一种「全景式沟通」的能力。大部分人在沟通时只关注信息的传递,而培养者需要时刻关注对方的状态,以及沟通双方的关系和情感。

技术篇

如果不知道知识对自己有什么用,就很难提起学习的兴趣,也难有决心克服学习中遇到的困难。知识是用进废退的,我们应该极其功利地学习,甚至忘了学习这件事,专注于解决实际问题,学习只是解决问题过程中的一环。培养者有一个很大的责任--为学习赋予意义。比如学习编程语言,并不是为了以后用它找工作,或者在脑子里留下印象,以便以后要用的时候能更快地捡起来。而是学会如何学习一门编程语言,只有这样,才能应对五花八门、层出不穷的语言。培养者要会讲故事,描绘学成后的场景,激发学员的学习意愿。

在学习过程中:

  • 运用教练技术,用提问的方式,让学生自己找到解决方案;
  • 在进行团队讨论时,运用引导技术,帮助他们从同伴那里学习;
  • 在学员遇到问题时,运用辅导技术,循循善诱,用提问的方式激发学生自己找到答案;
  • 在学员掉坑里时,运用咨询技术,用丰富的经验让学生少走弯路。

每一门技术都是一个很大的领域,但我们并不需要成为专家才能应用这些技术,推荐几本入门书:

  • 《培训师》
  • 《唤醒沉睡的天才》
  • 《引导:团队群策群力的实践指南》
  • 《倾听术:轻松实现高效能沟通的秘密》

技巧篇

如何建立信任?

  • 提前和学员单独认识
  • 每次互动时叫出学员的名字
  • 鼓励每一次提问和发言

如何邀请学员提问?

提问的时候尽量避免使用「问题」这个字眼,因为问题可以是Problem,也可以是Trouble。当这么说时,提问就是在给别人制造麻烦。我会说:「有没有什么疑惑或者任何想法要跟大家分享一下?」提问后,面带微笑环视全场,看到谁有意向,就给他一个鼓励的眼神。一旦有人提问,先认同,消除提问者“害怕自己问了一个傻问题”的担心。「这是一个很好的问题」,这样说的时候也为自己争取到了一点思考的时间。回答结束后,确认一下:「有回答到你的问题吗?」来感谢对方的提问。

使用积极的词汇

  • 用「提升空间」代替「缺点」
  • 用「宵夜」代替「作业」
  • 用「困惑」代替「问题」

如果迫不得已必须要说消极的词汇,也尽量让它们从学员的口中说出来。比如:

最快完成的小组将获得一份神秘的奖励,没有在规定时间内完成的小组将接受严厉的~~~

配合一个邀请的手势,学员们一定会异口同声地说「惩罚」。然后我就说,“是你们自己说的,不关我的事哦”,甩锅成功。这里我避免说出「失败」的小组和「惩罚」这两个不够积极的词汇。

只和过去的自己比较

学员过去的经历不同,理解能力不同,切忌拿他们互相比较,那样领先的学员会很爽,他甚至会鼓励我开展更多的竞赛游戏,但对于进度较慢的学员却是一次又一次的打击,只会让TA失去学习的乐趣。只让学员和昨天的自己、上个星期的自己比较,肯定他们任何一点点的进步,他们就会越来越有信心,越来越享受学习。

偶尔使用同伴压力

有的学员可能会觉得自己是最优秀的,这时我也不需要告诉他什么,只需要将更优秀的学员可视化出来,让他感受到同伴压力。比如让他们分到一组做练习。

让每个学员都有挑战

对于能力确实比较强的学员,可以给他们设立更高的挑战,比如缩短他们做练习的时间,增加题目的难度,确保每个人都有收获。

上课时间到了,人没齐,怎么办?

通常的做法是等,但我要说这是大错特错的,因为这是在惩罚守规则的人。

对按时到位的人而言:既然准时到还要等,不如我下次也晚点到,避免浪费我的时间。对迟到的人而言:迟到了没有惩罚,也没错过什么,下次还这么干。所以这么做的结果就是,越来越不齐。我的做法是,准时开始,并且跟大家强调一下我们不能惩罚守规则的人。通常开场都是破冰或自我介绍之类的,小部分人错过了也没大碍。如果课程开始的内容就非常重要,那我也会准时开始,讲点别的有价值的东西,作为对准时到的人的奖励。

用手做引导,整只手

在引导学员发言时,一定要用整只手,而不是手指,或手里握着的任何东西。这是对学员的尊重。

用词精准

避免说「可能」,「大概」之类的词语,听起来没有底气。课间休息时,不要说我们大约休息10分钟。而是我们休息X分钟, AA点BB分正式开始下一堂课。

根据学生的能量安排教学活动

时刻关注学员的能量水平,调整课程的先后顺序,甚至同一门课,也可以用不同的形式。

以上,分享了我从程序员变成培养者以来九个月的心态变化,在发展他人的道路上所获得的成长以及积累的一些实用技巧。实际上,在这几个月的培养者经历中,收获最大的是我自己,为了帮助学生成长,我学习了时间管理、精力管理、习惯养成、知识管理等。在不断践行的过程中,养成了很多好的习惯,不仅在工作中收获了成就感,在与家人沟通、教育孩子方面也有所进步。如果你也是培养者,希望本文对你有所帮助,希望你也享受这个工作!


更多精彩洞见,请关注微信公众号:思特沃克

Share

为什么优秀的程序员喜欢命令行?

优秀的程序员

要给优秀的程序员下一个明确的定义无疑是一件非常困难的事情。擅长抽象思维、动手能力强、追求效率、喜欢自动化、愿意持续学习、对代码质量有很高的追求等等,这些维度都有其合理性,不过又都略显抽象和主观。

(图片来自:http://t.cn/R6I1yhJ)

我对于一个程序员是否优秀,也有自己的标准,那就是TA对命令行的熟悉/喜爱程度。这个特点可以很好的看出TA是否是一个优秀的(或者潜在优秀的)程序员。我周围就有很多非常牛的程序员,无一例外都非常擅长在命令行中工作。那什么叫熟悉命令行呢?简单来说,就是90%的日常工作内容可以在命令行完成。

当然,喜欢/习惯使用命令行可能只是表象,其背后包含的实质才是优秀的程序员之所以优秀的原因。

自动化

Perl语言的发明者Larry Wall有一句名言:

The three chief virtues of a programmer are: Laziness, Impatience and Hubris. – Larry Wall

懒惰(Laziness)这个特点位于程序员的三大美德之首:唯有懒惰才会驱动程序员尽可能的将日常工作自动化起来,解放自己的双手,节省自己的时间。相比较而言,不得不说,GUI应用天然就是为了让自动化变得困难的一种设计(此处并非贬义,GUI有着自己完全不同的目标群体)。

(图片来自:http://t.cn/R6IBgYV)

GUI更强调的是与人类的直接交互:通过视觉手段将信息以多层次的方式呈现,使用视觉元素进行指引,最后系统在后台进行实际的处理,并将最终结果以视觉手段展现出来。

这种更强调交互过程的设计初衷使得自动化变得非常困难。另一方面,由于GUI是为交互而设计的,它的响应就不能太快,至少要留给操作者反应时间(甚至有些用户操作需要人为的加入一些延迟,以提升用户体验)。

程序员的日常工作

程序员除了写代码之外,还有很多事情要做,比如自动化测试、基础设施的配置和管理、持续集成/持续发布环境,甚至有些团队还需要做一些与运维相关的事情(线上问题监控,环境监控等)。

  • 开发/测试
  • 基础设施管理
  • 持续集成/持续发布
  • 运维(监控)工作
  • 娱乐

而这一系列的工作背后,都隐含了一个自动化的需求。在做上述工作时,优秀的程序员会努力将其自动化,如果有工具就使用工具;如果没有,就开发一个新的工具。这种努力让一切都尽可能自动化起来的哲学起源于UNIX世界。

而UNIX哲学的实际体现则是通过命令行来完成的。

Where there is a shell, there is a way.

UNIX编程哲学

关于UNIX哲学,其实坊间有多个版本,这里有一个比较详细的清单。虽然有不同的版本,但是有很多一致的地方:

  1. 小即是美
  2. 让程序只做好一件事
  3. 尽可能早地创建原型(然后逐步演进)
  4. 数据应该保存为文本文件
  5. 避免使用可定制性低下的用户界面

审视这些条目,我们会发现它们事实上促成了自动化一切的可能性。这里列举一些小的例子,我们来看看命令行工具是如何通过应用这些哲学来简化工作、提高效率的。一旦你熟练掌握这些技能,就再也无法离开它,也再也忍受不了低效而复杂的各种GUI工具了。

命令行如何提升效率

一个高阶计算器

在我的编程生涯早期,读过的最为振奋的一本书是《UNIX编程环境》,和其他基本UNIX世界的大部头比起来,这本书其实还是比较小众的。我读大二的时候这本书已经出版了差不多22年(中文版也已经有7年了),有一些内容已经过时了,比如没有返回值的main函数、外置的参数列表等等,不过在学习到HOC(High Order Calculator)的全部开发过程时,我依然被深深的震撼到了。

简而言之,这个HOC语言的开发过程需要这样几个组件:

  • 词法分析器lex
  • 语法分析器yacc
  • 标准数学库stdlib

另外还有一些自定义的函数等,最后通过make连接在一起。我跟着书上的讲解,对着书把所有代码都敲了一遍。所有的操作都是在一台很老的IBM的ThinkPad T20上完成的,而且全部都在命令行中进行(当然,还在命令行里听着歌)。

这也是我第一次彻底被UNIX的哲学所折服的体验:

  • 每个工具只做且做好一件事
  • 工具可以协作起来
  • 一切面向文本

下面是书中的Makefile脚本,通过简单的配置,就将一些各司其职的小工具协作起来,完成一个编程语言程序的预编译、编译、链接、二进制生成的动作。

YFLAGS = -d
OBJS = hoc.o code.o init.o math.o symbol.o

hoc5:    $(OBJS)
    cc $(OBJS) -lm -o hoc5

hoc.o code.o init.o symbol.o: hoc.h

code.o init.o symbol.o: x.tab.h

x.tab.h: y.tab.h
    -cmp -s x.tab.h y.tab.h || cp y.tab.h x.tab.h

pr:    hoc.y hoc.h code.c init.c math.c symbol.c
    @pr $?
    @touch pr

clean:
    rm -f $(OBJS) [xy].tab.[ch]

虽然现在来看,这本书的很多内容已经过期(特别是离它第一次出版已经过去了近30年),有兴趣的朋友可以读一读。这里有一个Lex/Yacc的小例子的小例子,有兴趣的朋友可以看看。

当然,如果你使用现在最先进的IDE(典型的GUI工具),其背后做的事情也是同样的原理:生成一个Makefile,然后在幕后调用它。

基础设施自动化

开发过程中,工程师还需要关注的一个问题是:软件运行的环境。我在学生时代刚开始学习Linux的时候,会在Windows机器上装一个虚拟机软件VMWare,然后在VMWare中安装一个Redhat Linux 9

(图片来自:http://t.cn/R6IBSAu)

这样当我不小心把Linux玩坏了之后,只需要重装一下就行了,不影响我的其他数据(比如课程作业、文档之类)。不过每次重装也挺麻烦,需要找到iso镜像文件,再挂载到本地的虚拟光驱上,然后再用VMWare来安装。

而且这些动作都是在GUI里完成的,每次都要做很多重复的事情:找镜像文件,使用虚拟光驱软件挂载,启动VMWare,安装Linux,配置个人偏好,配置用户名/密码等等。熟练之后,我可以在30 - 60分钟内安装和配置好一个新的环境。

Vagrant

后来我就发现了Vagrant,它支持开发者通过配置的方式将机器描述出来,然后通过命令行的方式来安装并启动,比如下面这个配置:

VAGRANTFILE_API_VERSION = "2"

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
  config.vm.box = "precise64"
  config.vm.network "private_network", :ip => "192.168.2.100"
end

它定义了一个虚拟机,使用Ubuntu Precise 64的镜像,然后为其配置一个网络地址192.168.2.100,定义好之后,我只需要执行:

$ vagrant up

我的机器就可以在几分钟内装好,因为这个动作是命令行里完成的,我可以在持续集成环境里做同样的事情 – 只需要一条命令。定义好的这个文件可以在团队内共享,可以放入版本管理,团队里的任何一个成员都可以在几分钟内得到一个和我一样的环境。

Ansible

一般,对于一个软件项目而言,一个全新的操作系统基本上没有任何用处。为了让应用跑起来,我们还需要很多东西。比如Web服务器、Java环境、cgi路径等,除了安装一些软件之外,还有大量的配置工作要做,比如apache httpd服务器的文档根路径,JAVA_HOME环境变量等等。

(图片来自:http://t.cn/R6IBZKm)

这些工作做好了,一个环境才算就绪。我记得在上一个项目上,不小心把测试环境的Tomcat目录给删除了,结果害的另外一位同事花了三四个小时才把环境恢复回来(包括重新安装Tomcat,配置一些JAVA_OPTS,应用的部署等)。

不过好在我们有很多工具可以帮助开发者完成环境的自动化准备,比如:ChefPuppetAnsible。只需要一些简单的配置,然后结合一个命令行应用,整个过程就可以自动化起来了:

- name: setup custom repo
  apt: pkg=python-pycurl state=present

- name: enable carbon
  copy: dest=/etc/default/graphite-carbon content='CARBON_CACHE_ENABLED=true'

- name: install graphite and deps
  apt: name={{ item }} state=present
  with_items: packages

- name: install graphite and deps
  pip: name={{ item }} state=present
  with_items: python_packages

- name: setup apache
  copy: src=apache2-graphite.conf dest=/etc/apache2/sites-available/default
  notify: restart apache

- name: configure wsgi
  file: path=/etc/apache2/wsgi state=directory

上边的配置描述了安装graphite-carbon、配置apahce等很多手工的劳动,开发者现在只需要执行:

$ ansible

就可以将整个过程自动化起来。现在如果我不小心把Tomcat删了,只需要几分钟就可以重新配置一个全新的,当然整个过程还是自动的。这在GUI下完全无法想象,特别是在有如此多的定制内容的场景下。

持续集成/持续发布

日常开发任务中,除了实际的编码和环境配置之外,另一大部分内容就是持续集成/持续发布了。借助于命令行,这个动作也可以非常高效和自动化。

Jenkins

持续集成/持续发布已经是很多企业IT的基本配置了。各个团队通过持续集成环境来编译代码、静态检查、执行单元测试、端到端测试、生成报告、打包、部署到测试环境等等。

比如在Jenkins环境中,在最前的版本中,要配置一个构建任务需要很多的GUI操作,不过在新版本中,大部分操作都已经可以写成脚本。

这样的方式,使得自动化变成了可能,要复制一个已有的pipline,或者要修改一些配置、命令、变量等等,再也不需要用鼠标点来点去了。而且这些代码可以纳入项目代码库中,和其他代码一起被管理、维护,变更历史也更容易追踪和回滚(在GUI上,特别是基于Web的,回滚操作基本上属于不可能)。

node {
   def mvnHome

   stage('Preparation') { // for display purposes
      git 'https://github.com/jglick/simple-maven-project-with-tests.git'
      mvnHome = tool 'M3'
   }

   stage('Build') {
      sh "'${mvnHome}/bin/mvn' -Dmaven.test.failure.ignore clean package"
   }

   stage('Results') {
      junit '*/target/surefire-reports/TEST-.xml'
      archive 'target/*.jar'
   }
}

上面这段groovy脚本定义了三个阶段,每个阶段中分别有自己的命令,这种以代码来控制的方式显然比GUI编辑的方式更加高效,自动化也变成了可能。

运维工作

自动化监控

Graphite是一个功能强大的监控工具,不过其背后的理念倒是很简单:

  • 存储基于时间线的数据
  • 将数据渲染成图,并定期刷新

用户只需要将数据按照一定格式定期发送给Graphite,剩下的事情就交给Graphite了,比如它可以消费这样的数据:

instance.prod.cpu.load 40 1484638635
instance.prod.cpu.load 35 1484638754
instance.prod.cpu.load 23 1484638812

第一个字段表示数据的名称,比如此处instance.prod.cpu.load表示prod实例的CPU负载,第二个字段表示数据的,最后一个字段表示时间戳。

这样,Graphite就会将所有同一名称下的值按照时间顺序画成图。

(图片来自:http://t.cn/R6IxKYL)

默认地,Graphite会监听一个网络端口,用户通过网络将信息发送给这个端口,然后Graphite会将信息持久化起来,然后定期刷新。简而言之,只需要一条命令就可以做到发送数据:

echo "instance.prod.cpu.load 23 </span>date +%s<span class="pl-pds">" | nc -q0 graphite.server 2003

date +%s会生成当前时间戳,然后通过echo命令将其拼成一个完整的字符串,比如:

instance.prod.cpu.load 23 1484638812

然后通过管道|将这个字符串通过网络发送给graphite.server这台机器的2003端口。这样数据就被记录在graphite.server上了。

定时任务

如果我们要自动的将数据每隔几秒就发送给graphite.server,只需要改造一下这行命令:

  1. 获取当前CPU的load
  2. 获取当前时间戳
  3. 拼成一个字符串
  4. 发送给graphite.server2003端口
  5. 每隔5分钟做重复一下1-4

获取CPU的load在大多数系统中都很容易:

ps -A -o %cpu

这里的参数:

  • -A表示统计所有当前进程
  • -o %cpu表示仅显示%cpu列的数值

这样可以得到每个进程占用CPU负载的数字:

%CPU
  12.0
  8.2
  1.2
  ...

下一步是将这些数字加起来。通过awk命令,可以很容易做到这一点:

$ awk '{s+=$1} END {print s}'

比如要计算1 2 3的和:

$ echo "1\n2\n3" | awk '{s+=$1} END {print s}'
6

通过管道可以讲两者连起来:

$ ps -A -o %cpu | awk '{s+=$1} END {print s}'

我们测试一下效果:

$ ps -A -o %cpu | awk '{s+=$1} END {print s}'
28.6

看来还不错,有个这个脚本,通过crontab来定期调用即可:

#!/bin/bash
SERVER=graphite.server
PORT=2003
LOAD=</span>ps -A -o %cpu <span class="pl-k">|</span> awk <span class="pl-s"><span class="pl-pds">'</span>{s+=$1} END {print s}<span class="pl-pds">'</span></span><span class="pl-pds">

echo "instance.prod.cpu.load ${LOAD} </span>date +%s<span class="pl-pds">" | nc -q0 ${SERVER} ${PORT}

当然,如果使用Grafana等强调UI的工具,可以很容易的做的更加酷炫:

(图片来自:http://t.cn/R6IxsFu)

想想用GUI应用如何做到这些工作。

娱乐

命令行的MP3播放器

最早的时候,有一个叫做mpg123的命令行工具,用来播放MP3文件。不过这个工具是商用的,于是就有人写了一个工具,叫mpg321,基本上是mpg123的开源克隆。不过后来mpg123自己也开源了,这是后话不提

将我的所有mp3文件的路径保存成一个文件,相当于我的歌单:

$ ls /Users/jtqiu/Music/*.mp3 > favorites.list
$ cat favorites.list
...
/Users/jtqiu/Music/Rolling In The Deep-Adele.mp3
/Users/jtqiu/Music/Wavin' Flag-K'Naan.mp3
/Users/jtqiu/Music/蓝莲花-许巍.mp3
...

然后我将这个歌单交给mpg321去在后台播放:

$ mpg321 -q --list favorites.list &
[1] 10268

这样我就可以一边写代码一边听音乐,如果听烦了,只需要将这个后台任务切换到前台fg,然后就可以关掉了:

$ fg
[1]  + 10268 running    mpg321 -q --list favorites.list

小结

综上,优秀的程序员借助命令行的特性,可以成倍(有时候是跨越数量级的)提高工作效率,从而有更多的时间进行思考、学习新的技能,或者开发新的工具帮助某项工作的自动化。这也是优秀的程序员之所以优秀的原因。而面向手工的、原始的图形界面会拖慢这个过程,很多原本可以自动化起来的工作被淹没在“简单的GUI”之中。

(图片来自:http://cargocollective.com/)

最后补充一点,本文的关键在于强调优秀的程序员与命令行的关系,而不在GUI程序和命令行的优劣对比。GUI程序当然有其使用场景,比如做3D建模、GIS系统、设计师的创作、图文并茂的字处理软件、电影播放器、网页浏览器等等。

应该说,命令行优秀的程序员之间更多是关联关系,而不是因果关系。在程序员日常的工作中,涉及到的更多的是一些需要命令行工具来做支持的场景。如果走极端,在不适合的场景中强行使用命令行,而置效率于不顾,则未免有点矫枉过正,南辕北辙了。


更多精彩洞见,请关注微信公众号:思特沃克

Share

驱动力来自哪里——献给迷茫的程序员

驱动你做一件事情的动力来源是什么?一般来说动力来源有两种。

一种是生存本能带来的驱动力,即生物性驱动力。比如每天要吃饭、睡觉、上厕所,长大了要恋爱、结婚等。这种驱动力保证我们能够生存在这个世界上,是一种原始的驱动力。

另一种是奖励或者惩罚带来的驱动力,即外在动机。比如老板承诺工作干的好有奖金,我们就努力干活。如果上班迟到会罚款,我们会早起等。这种驱动力会改变人的行为,使其多做鼓励的事情,少做禁止的事情。

如果只依靠这两种驱动力,那么你的人生会变得精彩吗?很难。为什么呢?第一种驱动力只解决了你的生存问题;而第二种驱动力则约束了你的行为。你不想上班,但不得不上班。一旦你做某件事情获得了奖励,你就会对奖励上瘾。而当你认为你得到的奖励与你的付出不成正比时,你的行为就会松懈下来。

要想保持第二种驱动力长期有效,那么就需要管理者具有相当高的水平,比如确保内部公平和外部公平,报酬要高于平均水平,考核标准、衡量因素要广。这样的的公司和领导可遇而不可求。

那么除了这两种驱动力,还有没有第三种驱动力呢?在《驱动力》一书中,作者指出了第三种驱动力,那就是内在动机,即完成某件事情带来的成就感和愉悦感。比如你玩英雄联盟,完成了5杀,比吃了一顿满汉全席还爽。再比如你去跑步,第一次不间断跑了10公里,这种超越自己的感觉肯定会非常奇妙。你修复了一个存在已久的软件故障,那么今天就会感觉特别充实。这种没有人主动给你奖励或惩罚的事情你却干的津津有味。为了练好英雄联盟中的大局观,你研习了数千盘比赛录像。为了能够跑的更远,你查阅了很多跑步相关的教程、书籍。为了修复你遇到的bug,你不惜翻墙来搜集相关资料。

book

如果你能驾驭这第三种驱动力,那么恭喜你,你的人生会一直前进。

那么如何驾驭这第三种驱动力呢?作为程序员,你首先要问自己一个问题:“我真的喜欢编程吗?我能确定我当程序员不仅是为了养家糊口,而是为了实现自己的人生价值吗?” 这一点非常重要,它对你否能利用第三种驱动力有着决定性作用。如果你的答案是为了养家糊口,那么很可能你成为不了一个优秀的程序员,而且在这条路上你越走越疲倦;如果你的答案是真心喜欢编程,那也很可能说明不了什么问题,除非你每天都在主动地学习和进步。

在编程的路上想要利用第三种驱动力,请先忘却它可能给你带来的奖励,而是切实的学习知识,充实自己,奖励只是你进步途中的副产品。如果你做一件事情前先考虑它有没有价值,会不会给你带来收益,那么你还是在利用第二种驱动力。你在当时的环境中很难看清楚一件事情对以后有没有价值。

举个例子,AngularJS刚面世的时候,我一个同事对其非常感兴趣,研读了很多相关的资料,并积极试用,虽然那时候它极不成熟。在那个时间点其实看不出来它会带来什么收益,说不定过几个月AngularJS框架就会销声匿迹。但是几年下来,我这个同事已经是国内AngularJS的专家了,在社区里影响力很大,还发表了关于AngularJS的原创书籍。

angularjs

第三种驱动力,内在动力,其实就是自主性当你做些不是工作范畴之内的事情时,你反而离成功更近。再拿编程来举例,很多技术大牛在上班时间外,会写一些博客,参加一些社区聚会,翻译或者写书。做这些事情都是靠内在动力驱动的。所以他们成了大牛,而按部就班的程序员依然是普通的程序员。当你自发想做一些事情时,你无疑已经领先了很多人一大步,因为这些人都在原地踏步。

第三种驱动力是一种良性循环,很容易就可以把人变得乐观,积极向上,感觉生活充满希望。善于驾驭这种能力的人会在生活和工作中都使用它,把工作和生活统一起来,不再相互冲突。比如我平时喜欢跑步,从一次只能10公里,渐渐一次可以跑15公里、20公里、42公里….直到上周花了17小时跑了72公里山路,本来计划跑100公里的,但是膝盖受伤,不得不终止。没人强迫我这样跑,我跑完了也没有任何金钱上的奖励,而且跑步本身其实既枯燥又花钱。我喜欢跑,是因为想知道自己的极限在哪里,这就是一种挑战自我的精神。我不和别人比,只和自己比。

running

只要能证明今天的自己比昨天的自己更优秀,那么今天就是成功的一天。这种精神也会传染到我的工作中。工作中再大的困难都不算什么,别人能做到我也能。即使现在做不到,那么也会主动的寻找差距去弥补,去提升。如果你能从早上6点跑到第二天早上8点,那么你会发现很多以前对你来说不可能的事情都不再那么困难。

我们经常听说一些名人每天工作十多个小时还坚持健身、运动,这就是第三种驱动力的力量,即内在动机。这种驱动力不仅要用在工作上,更要用在生活上。这样生活和工作更容易成为统一体,每天才能充满阳光和斗志。

amazing

Share

我选择,我喜欢

你有男朋友吗?

你男朋友同意你做这个吗?

连续加班一个月你受得了吗?

2014年10月份初,我离开大连,踏入北京,开始毕业后继续找工作。

在北京的两个月时间,几乎是我独自经历过的最艰难的时光。刚到北京,手机被偷走,因为没有钱,联系了一个出租床位的房间,30多个女孩子住在一起。

那段时间做的最多的事,就是每天早上6点出门,奔波在北京的各大名校中赶校招,晚上12点回到住的地方,吃一点泡面,在室友已经熄灯睡觉的黑暗卧室里,开着台灯偷偷做笔试题。

1-night

而这些对我来说,都不能算什么。让我更觉无法接受的是,在我为数不多的过关斩将,到达最后一轮面试的时候,常常面临面试官抛给我本篇开头的那三个问题。

那一刻,他的表情似乎天经地义,而我无言以对,也心有不甘。我不明白它们之间有什么必然的联系。

是的,我是一名女程序员。

我喜欢写代码

在大学的时候,我第一次接触编程。我怀着一点疑惑和一点兴奋,报了一个叫做”计算机动画与游戏软件”的专业。那个时候很多人刚刚拿到智能手机,刚刚学会网上购物,我也期待着能搞出这些酷炫的新科技。

2-interesting

现在回想起来,那个时候的我有很多费解的问题:为啥C语言的语法就要这样写啊?为啥C++写起来和C语言不一样啊?为啥编程要学习线性代数啊?但同时我也会沉浸在偶尔写出一个能运行的程序的喜悦中。这种疑惑和欣喜的复杂感受让我一直不断尝试着写程序。

时间过得很快, 就业来临。我希望我能专注于准备一份作品,希望能让面试官眼前一亮,二话不说就录取我。但我甚至做不出来一个让我自己满意的作品。

我的学校是大连的一所二类本科,而我的专业是我们大学唯一一个工科专业。现实的结果就是,那些比较知名的企业,根本不会到我们学校招聘学生。我能做的就是,打听消息,在大连的那些名校里面奔走,争取一个笔试面试的机会。

但因为不是本校的学生,主考官会直接把我们这些没有接到笔试邀请的学生们堵在门外,告知我们笔试卷只有这些,没有接到通知的请离开。

考场内外,冷暖自知。

这是我喜欢的地方

2014年12月末的时候,就在我考虑是否要到超市做兼职的时候,我接到了ThoughtWorks的面试通知。如果不是TW这种风格的面试,我求职的坎坷之路可能更漫长。

比如,我不用在笔试试卷上写程序,而是收到了一个作业,在两天的时间内完成;

再比如,笔试试卷是主要以计算机思想为主的逻辑题,而不是各种语言基础知识或者操作系统基础知识;

再比如,HR面试时更多的是跟你聊聊各种事情发生时你的感受,而不是跟你谈薪水;

再比如,技术面试的时候,面试官更关注我对问题的思考,而不是我现在的基础是怎样的。

这样轻松的面试经历,让我意识到,其实的确存在这样的公司,它不是在考验你目前的能力是多少,它不关注你加入公司之后是否能立即为公司带来利益,它更关注的是你有没有思考的能力,有没有学习的能力,有没有对于技术的热情。

更重要的是,它的面试会忽视掉你的性别,我感受到了尊重。

我想,是因为我对技术有热情,喜欢思考,才能最后如愿加入ThoughtWorks,得到属于一份属于自己的工作。

一切才刚刚开始

我记得大二的时候,很喜欢听一首英文歌,里面有一句歌词,大意是”每一件令我挫败的事都让我感受到我还活着”。当时因为面临一些挫折和糟糕的心境,我删了这首歌。但现在回想起来,不得不说,我很感激我过去的这段经历。

至今,我已经转正半年多了。这半年的时间我所热爱的编程、技术以及我的能力有所提高吗?我的回答是肯定的。在现在的环境下,我可以学习到很多时下新鲜的技术,因为身边有很多人跟我有相同的志愿;我可以工作之余平衡学习读书和娱乐,因为我适应了新的学习方式,也拥有了一些让我能解决问题的能力。

3-luoxiaolin

刚加入公司的那段时间,我的神经每天都是紧绷的。我加入了一个非常庞大的项目,和客户合作至今7年整,项目上使用微服务架构,应用敏捷的开发方式。不要说我从来没有听说过微服务和敏捷,我那时连一个基础的Web项目都没有做过

那段时间我基本每天要和我的Buddy(公司安排帮助新人成长的老同事)一起在公司练习编程到深夜,学习各种各样的技术栈,给团队的其他成员分享我掌握的技术。当然敏捷的实践——结对编程也帮助了我很多,这种方式让我可以在工作中学习,不懂的问题通过提问的方式得到了及时反馈。

慢慢的,我开始独立完成交付任务,开始不止学习技术的表层,开始理解原理,开始深入学习,能参与技术决策和讨论。慢慢的,感觉自己的技术熟练起来。

让人怀念的TWU

还有一件对我影响非常深的事情,就是去印度TWU学习(公司提供的针对应届毕业生的培训计划)。现在我仍然能很清晰地记得,每天早上坐着公司的大巴在印度闷热的空气中思考今天的课程和工作,每天晚上回程的路上和来自不同国家的同事讨论中国的美食。

4-twu_day

那个环境就是一个多样的、丰富的文化融合。每天要和来自不同国家的人交谈,理解他们的行事方式,理解他们的想法,分享自己的想法,沟通,交流,最后达成一致。

我曾因为自己的建议不被采纳感到沮丧,也曾因为意见不合感到烦躁。但是交流和接受反馈让我适应不同的声音,走向一个真正理解别人和勇于正视自己的状态。在一个陌生的环境中,做一些自己从来没有做过的事,变得自信起来。我开阔了自己的眼界,还有收获到更开放的心态。

写在最后

我现在是什么状态?现在我的心态轻松了,我可以停止学习了吗?我可以享受这种安稳的舒适感了吗?我还是想说,不是的。我发现我将要学习的东西更多了,我接触的新领域更多了,我想要参与的事情更多了。每个人对自己的每个阶段都有不同的目标,我还在思考,我还在求知,我还在探索,因为我害怕一无所知的状态,因为我相信热情和努力能成就一个人的梦想。

5-read

所以,我到底做成了什么?其实,我没有什么成就,充其量我现在是一个合格的女程序员。但是每当我想起因为那些因为对未来的恐惧而无法入眠的夜晚,现在的我都感到坚定无所畏惧。尽管我还有很多未知的东西,尽管我还会犯错误。不被认可和失败是可怕而无助的,但不追求自己想做的事情更加令我恐惧。

现在别人问起我,“你为什么做程序员,多累啊”的时候,我可以回答,就因为我想做啊,想做就去做啊,还需要什么特别的原因吗?

 


你想看到的洞见,都在这里

wechat

Share