在西雅图亚马逊工作是种什么体验?
很多互联网小伙伴都关心工作和生活如何balance。
可在国内略显内卷的环境下,原本合理的需求都成了奢求。
相比之下,外企似乎更容易实现快乐工作,认真生活。
今天和大家分享一位好朋友GXSC在西雅图亚马逊总部多年的工作体验,看看他如何从懵懂新人成长为职场老炮。
全文内容较长,可以先收藏,或根据标题选择性阅读。
入职纯属偶然
我其实本来是想一直留在学校读书, 然后以后教书的。来西雅图的亚马逊纯属偶然。
这些年在亚马逊做开发, 感受最深刻的就是学到了很多东西。回头看刚入职的时候, 当时还真是很多事情都不懂。所以现在也不敢说自己懂什么。毕竟过个几年再看, 现在还是什么都不懂。我开始有时候还会以为自己是个工程师、以为做SDE的真的是做software development engineering。
这不是说所有的刚入职的应届生跟我当时一样什么都不懂。今年遇到一个本科实习生, 对于开发和管理上的见解非常深入, 不比某些SDE III弱。不知道他怎么领悟的。
最开始工作时我喜欢做些operations方面的苦活。因为当时觉得在西雅图10来万年薪已经很高了。组里大家不想干的活我就多做点才对得起这工资。当时组里同事对这个做法经常表示不解...因为一般当时最好的项目开发的活一般都是给实习生和SDE I做的。这样可以让这些新人多写code, 在做code review的时候就可以更方便培养他们的设计灵感。当然这些我当时都不懂。我当时看我们SDE III一直在干一些又累又没人欣赏的脏活累活, 所以我也干。
那个组做的系统当时并不容易理解。问题也多。我入组之前据说每晚得手动重启才不会把内存跑没。但是我反正新手, 也不知道问题所在。我还以为干这行就是这样。
后来做了一年多之后组里做了几次系统重构。新版本比老版本好懂多了, 也稳定多了, 我才开始感受到什么叫“好系统”。
之后大概有一两年, 做了不少系统设计, 学了很多销售领域相关的知识, 但是并没有抓到要领。当时也没意识到系统设计最重要的就是要好懂。那时候做设计主要靠灵感。等到换了组, 遇到了更难懂的系统、更大的设计问题, 才慢慢开始通过读书和找专家咨询来更正式地学习开发和管理。学习初期犯了很多设计、领导方面的错误。也没人跟我追究。这些错误对公司和组造成的伤害我到现在才明白。但是也没人跟我提过。有次我跟经理提到这些问题, 经理跟我说:“没有人是通过一直做出正确的选择来学习的。”
这些年也遇到几个比较普通的经理(虽然我也很喜欢他们, 但是当时不知道好经理是什么), 当时对薪水和职位就看得比较重。现在遇到了很好的经理, 可以从他那里学到很多开发、管理、以及销售领域相关的知识。对于薪水和职位就反而看得没那么重了。
即使是很普通的经理, 也都很关注我的成长。有的给我找mentor, 还有的带我去跟客户和领域方面的专家接触、学习, 带着我建立我自己的职业网络。
我也遇到过两个很差的经理。一般这种经理都不会很关心手下员工的成长(也有的是没时间管)。一般这种经理都不会在一个组留太久。大概几个月到一年半就会被转走。
亚马逊里只要你知道怎么操作, 很多事情可以大胆去做。其实级别越低,话语权越高。因为级别低的就算说错了、做错了也是理所当然。所以想说什么、想做什么, 只要目的是好的, 都可以大胆去尝试。当然了, 别违法。
接下来谈一下几件大家可能会比较关心的事情。
1. 关于是否应该来亚马逊
如果你不是太缺钱(比如学生债很重之类的), 亚马逊西雅图总部是一个适合职业成长的地方。亚马逊的应届生起薪不比别的类似公司低, 所以如果负债太重, 这类公司可能都不适合你。
不管你是什么专业, 都可以从这里的SDE I做起。现在亚马逊招的本科生中, 有很多理科非CS专业的。我也见过很多文科、医科的, 读个半年的电脑硕士就来亚马逊当SDE实习生的。
个人而言非常喜欢这样的员工。他们的思维模式往往非常灵活,可以给公司带来不同的视角。如果你背景就是CS, 也很好。这样上手快, 也有时间多学一些别的专业的东西。
传统上,亚马逊大多数组会给新SDE I甚至实习生从头到尾的"ownership" (近三年某些部门有一些变化, 之后会提到)。很多新人会去与客户谈项目、设计系统。一直到最后的购买硬件、发布功能、系统, 都可能是新人在主导的。这个ownership不应该被曲解为加班加点赶活。只是说这个实习生或者SDE I拥有整个项目最高的话语权。
比如我今年就看到一个组的实习生, 在花了几周与他的客户讨论和深入分析之后, 成功说服他的组员去放弃他的实习生项目。他的经理之后又花时间跟他一起开始了一个完全不同的项目。这种自主能力是亚马逊强调的ownership。
这里同时要注意, 自主和自私是不同的!有人来帮着做项目是好事。如何有效利用他人的帮助, 也是自主能力的一部分。
这种待遇在别的公司会比较少。这也是为什么有工作经验之后, 想面试进亚马逊难度反而会很高。一般工作经验3-5年的人, 面试亚马逊SDE II失败率很高。因为这个阶段的普通程序员是很少会做项目规划和系统设计的。然而亚马逊的员工有很多从实习生就在做这些。
反之也同理。我听说过不少起亚马逊SDE II跳槽到微软当Principal Engineer的事情。
当然并不是所有组都是这么好。这点之后会详细讨论。
2. 关于亚马逊中国
亚马逊中国的开发,现在的确不够自主。以前其实亚马逊印度也是全部都得听西雅图的命令。一方面是因为不是总部, 另一方面是印度文化上比较随和。
后来有一年派去印度一个Principal Engineer, 带领一群人建立这方面的思想, 最后改变了印度一些部门的文化。虽然有些部门还是老样, 但是很多印度部门已经自主化, 完全可以和西雅图这边的想法抗衡。个人希望这种文化也可以传播到中国。
3. 关于oncall
个人而言很喜欢oncall。oncall是学习机会。软件行业里大多工作都是在已有的老系统基础上开发的。oncall可以让我们学习到老系统在开发和成长过程中所犯的错误, 进而在自己做开发时能够有更好的质量和效率。
对于做新功能开发的人而言, 不去了解自己写的程序长期的隐患, 就是失去了能够让自己进化的学习机会。
工作中有时能遇到只喜欢开发新东西的员工。我对这种倾向不鼓励。但是亚马逊里的确也有组是专门这样做, 做完了程序给别的组做operations (oncall)。因为没有后顾之忧, 这样的程序很难保证质量。
如果一个新人加入了一个比较好的组, 这个新人很可能经常对于自己前一个月写的程序悔恨不已。组里会给新人犯错的机会。而犯的错通常会在oncall时被发现。
4. 关于组与组之间的差异
当时我入职的时候, 有人专门讲过这件事情:亚马逊的组的规划是以达尔文主义为中心的。所以每个组都是自主的个体, 任意发展。发展得好的就可以发扬光大, 发展得不好的就会被重组。
这是组和组之间体验不同的最大原因。
这个原因导致一个组好不好, 和它的经理、系统、开发者, 有直接关系。很多人对于Software Development Manager (SDM)的理解有误区, 以为就是看大家效率、监视一下项目进度、然后有时候给人升个职、有时候给人来个PIP...换句话说以为SDM只是个管人事、管项目日程的。这个误解来源于很多人对于项目“成功”的定义的误解:
亚马逊项目的成功的定义不仅仅是“解决了问题”, 更是“培养了人才”。
也就是说亚马逊SDM的核心任务是培养SDE。好的SDM其实是很少的。因为好的SDM必须有能力从各方面去培养手下的SDE。如果一个SDM手下有个SDE III, 这个SDM的能力至少得接近于Principal Engineer才能够有效培养他。
我已经有几年没遇到特别好的SDM了,直到最近才又遇到特别好的SDM。这几年遇到过很多比较普通的SDM。大致上普通SDM分两种:
一种往往只有管理经验, 却对软件开发的各种流程、系统设计、以及其工作的商业领域并不是特别了解。这样容易给组里带来一些非最优的项目和解决途径。而且很难领会到怎么有效管理SDE - 因为不懂什么样的开发流程适合他现有的处境。这处境包括小组的商务、包括组员的能力、包括与外组的关系等等。更糟糕的就是这样的SDM往往不懂得如何辅导他的SDE。
另一种虽然是SDE的背景, 但是缺乏管理经验, 经常挡在员工道上。比如有的会micromanage他最能自主的员工、却忘记管那些不能自主的员工。
这两种SDM都可以通过学习来进步。
所以如果在亚马逊工作, 并对自己的组经理不满意, 可以多了解了解别的组的一些做法, 用以改进自己的组、辅助自己的经理的进步。
一般没有人会阻止我们去做这些。当然了, 我们也需要有足够的工具去理解现有问题和实行改变。
做这些改变的过程, 也是我们学习的机会。具体的工具有很多。比如《Peopleware》就是一本这方面很不错的教材。
这里稍微提下PM的问题。有些朋友提到被PM赶活。 这是近三年在有些部门开始有的问题。 我所了解的一些组以前PM很少。这些年PM开始多了一些。一个好的组会知道自己什么时候需要PM, 什么时候需要cross-functional的SDE。并根据情况在这之间转换。通常一个组需要有大量合作时, 会需要一个PM。而好的PM应该促进SDE与客户的交流, 而不能总是直接自己去交流了, 然后给SDE丢requirements。SDE不理解客户具体的问题会导致解决方案难以适应未来的需求。主要的原因是SDE是最后做软件模型的人。如果SDE理解客户的具体问题, 就更能预测长期的需求, 进而会做出更合适的模型。所以所谓的系统设计, 设计的是所从事的领域的模型。对一个领域越了解, 系统就可以设计越能适应未来的需求。
如果发现组里PM不是在辅助项目, 而是在赶着别人干活, 并且抢了所有对外交流的活, 最好的做法是和自己的SDM一起重新定义PM的角色。这个重新定义的过程中, SDE和SDM应该积极去参与和做一些之前PM干的活, 比较自然地进行角色改变。好的PM可以促进各组之间的合作, 以及帮助大家扩张视野。
少数组所做领域相关的活都给PM在干, 导致SDE无法学习自己所工作的组的领域相关知识。比如一个SDE可能在推销组做了两年关于推销的程序, 但是完全不懂得基本的推销方案、无法自主解决基本的推销领域的问题。
这导致这些组里PM权势越来越大...还养成了少数经理什么项目不论大小都要看PRFAQ/BRD的恶习。不是说不应该写PRFAQ或者BRD。好的组在项目复杂时、投资比较多时, 也是要写的。但是当时比起PM, 更可能是经理带着SDE写, 而且是不需要写就不写。现在有些组是能写就写, 而且全是PM在写。这些与亚马逊end to end ownership的理念背道而驰, 也与亚马逊frugality和bias for action的理念背道而驰。
5. 关于薪酬
SDE I其实在很多地方都是看作是暂时的一个角色, 不可长久。一旦自主能力开发好了, 就是SDE II。SDE I如果做得好, 顶多底薪增加1.9%左右(我第一年好像只涨了0.1%还是多少)。但是SDE II做得好, 底薪可以每年增长6%左右(少数可以增长8%-13%), 直到增长到SDE II薪水封顶。
SDE II开始, 薪水慢慢向股票(RSU)转变。亚马逊给股票时会假设明年这个股票会涨。所以每年给的股数可能都比去年少。这个虽然有时会比较恶心, 最后交税时还是可以看到每年钱在往上涨的。
由于级别比较少, SDE II开始, 每个级别薪水区间可以很大。西雅图有的SDE II可能一年就10多万, 有的可能20多万, 有的接近30万。这与亚马逊股票浮动关系很大。
总之至少2018年, 就我个人了解:
SDE I: 13万到15万之间
SDE II: 14万到28万之间
SDE III: 16万到???之间
Principal Engineer: 据说比同级别的经理赚得多...
在美国, 员工之间讨论薪酬是被National Labor Relations Act保护的。阻碍员工讨论薪酬是违法的。所以大家也可以入职之后找同事了解一下别人的薪酬。薪酬隐私化是美国传统企业为了削弱员工的议价能力而制造的文化。但是如果你的同事不想讨论, 还是要尊重别人的。
我觉得亚马逊应该是喜欢留那些以长远目光看问题的人。贝索斯曾经说, 如果你计划做得长, 竞争对手就少。大多数竞争对手都在看每3个月的财报, 少数可以以三五年做计划。如果你做计划做到12年以上, 就没有人跟你比了。
所以只要你愿意放长线, 亚马逊给的报酬还是还可以的。
比如,如果一个员工是2012年大学毕业入职, 光他当年4万的signing bonus在2016年全部vest时就已经成了20多万。如果他到2018年都没卖, 就是40万了。
不过话说回来,如果有一个好的成长的机会, 长期的职业发展比这些短期的薪酬要重要。
6. 关于升职
之前提到亚马逊级别比较少。其实升到SDE II是件很不错的成就。升上去了, 你可以拿拿别的公司的Offer看看给多少。一般可能会被亚马逊当年给你的工资多一倍左右。
但是从另一个角度讲,最好着重于成长,而不是升职。亚马逊某部门这两年就出了一个问题:很多系统被设计得过度复杂。后来调查时发现, 都是因为设计复杂了容易忽悠人好升职。升上去的人, 很多不称职。
但是大家不要忘了,亚马逊是会PIP人的!能力差的经理一般专PIP那些工作不久的SDE I。其实SDE I是最不该PIP的。因为SDE I破坏力最小, 而且最容易训练。
职位越高, 越容易遇到经验比较足的经理。这些经理会着重审核SDE III和Principal。有个部门今年一年就开除了两个SDE III和一个Principal。
所以比起升职, 更重要的是成长。做得好总是会加薪的。做得不好, 升职了饭碗都不一定能保住。
当然SDE I也不要怕PIP。只要你做得好, 学得多, 你就不怕PIP。出PIP是件很光荣的事情。因为一个经理去PIP一个人, 代表着这个经理认为:
这个人造成伤害很大 这个人无法被训练
也就是说, PIP的确是用来开除人的。
但是如果被PIP的人出了PIP, 就很可能这个经理看错了。如果一个经理把一个好员工当成坏员工, 最后被开除的很可能是这个经理。所以在亚马逊, PIP是双向的。
7. 关于工作与生活
这个也是一个纯粹看经理和个人态度的事情。好的经理着重于提高效率, 坏的经理着重于增加坐班时间。如果遇到一个坏的经理, 那就得想办法训练他, 或者跟他的经理反应这方面的问题。亚马逊的小组里, 往往经理比SDE走得快。所以实在无法训练的经理跟上面反应一下把他转走就好。
我最开始的一个组比较幸运, 组里效率比较高。基本上中午到公司, 午饭一两个小时,下午5点准时回家。然而工作成就感很高。谈项目、解决问题、做开发,都速度很快。一个中型项目往往也就几周的事情。而且一两个人能搞定。每个项目都有时间重构现有系统来让之后的项目更容易。
这个组当年是没人想当经理的,因为这个组的经理很累。所有的SDE他都得指导。每天得考虑怎么样和SDE一起优化开发流程、帮手下的SDE联系上客户、卖项目给高层、应对客户非项目相关的问题。遇到SDE正在走弯路时还得很小心的诱导他走上正轨, 而不是否定他的工作。我们邮箱里24小时都可以看到他在发新的邮件, 不是催活儿, 而是帮组里解决一些琐碎的问题, 帮组员推脱一些客户不合理的要求, 找法务部帮组员研究新功能的合法性等等。这个经理是一个好经理。虽然我最近发现,有些非常罕见的经理可以做到同样的事情而不会像他那么累。
后来到的一个组就不太行了。常常连续周末加班几个月。全组人都加班, 什么都做不出来。有两年时间我的休假储蓄都是满的——有假没时间休。这样的情况一直持续到了换经理之后我才知道之前经理做法上的问题。但是我要是当时就知道这些问题和解决方式, 可能就会给那个经理一些反馈, 让他进行一些改善了。
8. 关于个人用硬件
每年亚马逊都会从员工那里汲取意见。硬件是2016年以前最大的抱怨之一。大家都觉得可以frugal, 但是frugal和cheap是两回事。太小气反而会浪费——员工每年开机、修电脑浪费的那些时间相对应的工资都可以给每个员工买好几台电脑了。所以2016年开始亚马逊给所有开发人员重新配了新的硬件。包括最新的手提电脑。最低配也是SSD和16G内存。现在我的Windows Laptop开机就十几秒。Mac不清楚。
硬件改善也包括重新配置显示器。可以选择双21寸显示器和单宽屏34寸的曲面显示器。宽屏显示器做Code Review很好用。双单屏做开发比较方便。看个人喜好了。
最近新入职的小朋友表示只能选双显示器。这是因为34寸的没货了。可以找IT Support那块申请。大概要等两个月。
新入公司员工可以选择用Mac或者PC。这个主要看习惯。有些组会推荐新人用Mac, 但是如果你没用过Mac, 最好别入坑。Mac可以直接进行开发, 不用连到Linux主机上。但是这样开发问题比较多。
PC是带Docking Station的, 很容易就可以和键盘、鼠标、显示器连起来。Mac的Dock得另购, 不一定能报销(跟自己老板商量)。没有Dock的话, 这些显示器、鼠标、键盘、电源、耳机什么的就得一条一条插...
写程序主要是在Linux上进行。但是有些组至少一半的活都并不是写程序。做设计、写文档、处理数据, 都是在PC上比较容易。因为Microsoft Project, Visio, Excel之类的软件, 在Windows上安装比较容易。
当你选好硬件之后, 5年后可以换新的手提电脑。如果你弄坏了或者想换个Mac, 公司会给你换个旧的电脑。同时5年的排期会重置。如果出现2016年大更新的话, 倒是可以免去排期。弄坏电脑的方式有很多种。我见过人泼咖啡的, 也见过直接用升降桌压裂的。
新员工标准配置是带一张升降桌的。我用的还是老款的木头Door Desk...主要是我喜欢这样的, 也方便我在办公桌附近搭别的东西。如果刚入职你没弄到升降桌,并且想要升降桌,一定要赶紧跟老板提,因为新员工换硬件比较容易。老员工以前换个升降桌得搞好几个月。不知道最近有没有什么改动。
9. 关于移民
移民这个事情好像不是亚马逊说了算的。以前只有SDE II能办绿卡。
2017年开始SDE I只要经理同意也可以办。当然不是一进公司就立马办。好像是要工作几个月才行。现在美国这个情况, 以后移民会怎么样谁也说不准。
10. 关于职业发展
前面提了一些如何应对经理、小组的问题。这些是主要成长的方式。在亚马逊其他的学习机会也很多。比如Principal of Amazon的演讲(POA), 以及各种"Learning Series"。POA并不需要是Principal Engineer才能去演讲, 也经常有SDE III去讲。
个人觉得, 早期的POA质量比较高。会谈一些比较基础的东西。比如我一直对SSL不是很了解, 当时就是从一个老POA里学的, 总算学懂了一时(现在又忘了)。还有关于Consensus Algorithm, 也是从2007年的老POA里学的。从2007年的演讲都可以从内网上找到。最近的POA和Learning Series有部分偏见比较重。往往让听众拿着一个解决方式去找问题。这种做法容易造成之前提到的系统过度复杂化的问题。
比如有一次有个人谈Data Oriented Design时, 恨不得把主程序都用data来表达。自己干脆只写这些数据的解析程序。这不是不行,但是在大多数场合是过分复杂的。这人为了让大家不提意见, 一开始发言就是"There is no silver bullet", 来堵大家嘴, 但是到最后也没提这个设计的隐患以及它不该被使用的场合。只提了句:"It might not fit your use case." 但是"which use case"恰恰应该是他整个演讲最重要的部分。
还有一次是我没听到的, 但是后来遇到某个组里的人, 他们已经有以event driven的方式做的一些系统, 非常好打理...但是其中一个SDE III拼命想做Process Oriented Architecture。我从来没听说个这种结构...听他的描述, 这个做法根本不适合他们的问题领域, 反而感觉是把系统做得更脆弱...后来才从他们组另外一个SDE III那里听说, 这人之前跑去看了一个Process Oriented Architecture的Principals of Amazon演讲...然后就盯着不放了...
那么话说回来, 职业发展到底怎么样做最好呢?这个可能真的得看人。但是我现在工作年数也不久, 还处于职业初期(前10年初期, 10-20年中期, 20-30年后期), 所以一方面只对SDE早期的成长有一些了解, 另也方面也只对我看到的一些SDE有一些想法。这只是一家之言, 不能以偏概全。具体上, 有些做法我也提不上来对哪些人不合适, 有些也许根本就是坏的做法, 只是我现在不知道而已。可以大概想到的就是如果你不在亚马逊, 你的公司也许很难接受下面这些做法。因为有些公司看待开发者的方式就是“程序员”。他们不会希望“程序员”去干涉商务, 也不需要“程序员”去建立商务模型。
在Adam Barr的新书《The Problem With Software: Why Smart Engineers Write Bad Code》 中, Barr提到, 程序员成长中一个最大的问题就是很多东西都是自学的,导致很多程序员不知道自己不懂什么, 而且还比较自信。这样容易导致理解错问题、学错方向。一个常见的错误就是过分注意程序性能而忽略可读性。这里很推荐在入职前后读一下这本书, 相信对大家的职业发展会有帮助。
10.1 入职
从入职到一年左右, 一般的SDE I最大的学习机会是写程序。一方面写程序本身是一种思维、建模上的锻炼(熟能生巧), 另一方面, 小组训练新人最有效的地方是Code Review。
Code Review里面别人提意见多是好事。当然也要多想想、问问为什么。一般的SDE II提的意见大概有一半不一定是对的...我之前就经常提错误的意见。最近遇到有些SDE III甚至Principal Engineer在Code Review上提的也不一定对。有时候他们是故意的——因为想看新人的自主能力。如果别人提的是对的, 下次就尽量不要犯同样的错误了。
Code Review的主要目的是培养SDE的习惯, 次要目的是提高程序质量。有些组(比如我的)有时候拿Code Review来保证程序的正确...这个做法...怎么说呢...Code Review有可能保证程序正确吗?有时候的确能找到一些bug, 但是要通过Code Review要保证程序没有bug, 按我一位mentor的说法, "it is an impossibly high bar." 写程序没bug是不可能的, 更何况读别人写的。读程序比写程序可难多了。
那么除了写程序、让别人Code Review、做别人的Code Review, 另外一个学习的方式就是把自己组里的程序多读读。这个是很累的。我一般最多读几个class就懒得继续了。只有在oncall的时候为了debug一些问题才能一直读下去, 因为有目标。这是为什么oncall也是学习很重要的一部分。不是为了debug, 漫无目的地读程序, 实在是太难受了。
除了这些, 可以考虑看一些2007年左右的POA演讲, 巩固一下基础。虽然我看了之后还做了笔记都很难记得多少。但是以后遇到的时候会比较有用。新的POA我觉得应该敬而远之。但是带着怀疑的态度去看看也可以。偶尔还是会有好的。
我看到不少新入职的朋友所在的组里的软件质量并不是特别好。组员给他们做的Code Review也不好。但是因为他们是新入职, 所以也意识不到。可以考虑读一下《Effective Java》的目录和《Head First Design Patterns》。前者在目录里有什么好奇的可以进去读下。后者是一本很适合初学者的培养审美的书。实在遇到一些组里吵架的问题, 比如怎么写test, 怎么做dependency injection之类的, 还可以参考Martin Fowler的博客(直接google相关话题和"Martin Fowler")。
入公司需要学的第一个设计模式可能就是Dependency Injection了。MSDN上对于Inversion of Control还有Dependency Injection的解释非常清楚。可以考虑看看。可能还会因为这个需要去学Guice或者Spring IoC Container。
10.2 写了读了很多程序, 什么算程序写得好?
之前提到培养审美, 这里想解释一下程序好看是什么意思。
要理解什么, 首先要理解大多数SDE做的并不是high-tech。我们大多不会在IEEE之类的发表论文。即使在学术界的时候发表过, 现在也没在发表。大多数SDE的工作是用商务模型所定义的程序来实现以前由人实现的商务功能的自动化。
程序作为商务模型的一个展现方式是写给人看的, 不是写给电脑看的。电脑看binary就可以了。电脑不在乎我们的设计, 也不在乎我们的结构。对电脑而言, Service Oriented Architecture是一种不有效利用资源的规划程序的方式。偶尔我们要担心一下程序是不是太浪费资源, 但是大多数时候程序是写给人看的。如果我们优化的是给电脑看我们的程序, 那么所有的程序都该用汇编写, 而且都应该是monolithic的(比如渲染引擎之类的)。
这种商务程序好不好主要在于是不是容易懂。有些程序过于复杂难懂, 看起来写得很高级, 其实是写得不好。
用“以后看这个程序的人会很蠢而且很懒”的心态下写程序可以预防这个问题。假设未来看这个程序的是未来的自己, 就很难会故意把程序写的太复杂。在优化程序设计时, 通常优化的也就是可读性。一个程序容易懂可以减少这个程序被改变、替换时的痛苦, 也就进而让商务模型得到了extensibility,flexibility和复杂度上的scalability。容易懂也就可以让浪费资源的步骤更明显, 更容易优化, 也就容易提高系统运作的scalability。容易懂也就让我们更容易debug, 于是bug就更少, 就可以增加reliablity。容易懂也就让我们更容易看到bottleneck, 也就是更容易增加availability。所以有多容易懂是测量一个程序好不好的主要方面。
10.3 程序容易懂了,那商务模型本身怎么做?
模型是某事物的一个表达方式(representation)。
同一个事物可以有很多的表达方式。每一个表达方式就是一个模型。模型之间不同的地方在于它省略的部分。一件事物的完整表达就是它自己本身。
通过省略不同的部分, 不同的模型会更适合不同的用途。
过于精细的模型虽然可以完成原本事物的本职, 但是往往很难懂, 也很难改变。过于粗糙的模型虽然容易懂, 但是却不能完成原本事物的职能。
所以在建模时, 我们会试图把复杂的事物分割之后分别建模, 保证每个部分都比较容易懂, 而又能照顾到细节。这许多被分割的模型之间的关系, 就是一个更抽象的模型。
想要给一个领域的商务问题建模, 就得了解这些需要解决、需要自动化的问题。
程序写熟、习惯养好这段时间, 慢慢也要了解自己的领域。做物流, 就得了解物流优化方式;做定价, 就得了解定价策略。具体的一些建模方面的东西我自己也做不太好, 但是大体方向是针对问题。
建模方面的技术可以参考 Eric Evans的《Domain Driven Design》。这书很枯燥, 不好读, 但是很有用。入门考虑先读Sam Newman的《Building Microservices》和Fred Brooks的经典《The Mythical Man-Month》 。后面这两本读起来不会脑壳疼。
以前有人提过这么个事:
很多在SDE II或者SDE III经验级别的人找他做design review时, 会拿6页的设计文件过去。6页除了一个自然段讲问题, 其他全是问题的解决方法。他看了之后先会说:“写得很好”(因为不想让别人不高兴), 然后说:“你用了多少篇幅写解法, 用同样的篇幅去写问题”。别人再来时, 写了6页问题。这时他说:“现在你列出这个问题的所有解法, 只是列出来, 不要去想细节, 也别管多蠢”。然后别人列出来了。然后他这时说:“现在做所有解法的trade-off analysis”。于是别人做了trade-off analysis。然后...然后就没有然后了。他跟我解释说:“最后他们选了哪个解法, 我其实不在乎,因为肯定错不到哪去。”
在过程的结尾, 这些SDE会对自己的领域更了解, 往往会做出比reivewer能做的更好的选择。
用这种方式产生的6页的设计文件的结构大概是这样的:
前5页讲问题, 最后1页总结解法的选择,外加6-20页的appendix列出所有解法、它们的trade-off analysis、以及更多的问题的研究。
这个过程, 通常是一系列Principal Consultation的过程。这个过程中, Principal Engineer会带着SDE建立问题的模型, 但是不会给任何答案(有位Principal Engineer提到, 当Principal最痛苦的就是明明知道答案但是却不能告诉别人...)。SDE会需要去见这个Principal Engineer很多次。这与亚马逊里有名的Principal Review是不同的。Principal Review通常是一个完整的文档拿去给一群Principal Engineer看一遍...这个做法很不受欢迎, 因为Principal Engineer很难纠正一个已经投资很多的设计。Principal Consult最开始的时候一般并没有6页文档。差不多半页描述一下大概的问题就够了,越短越好。这样意味着少走很多弯路, 也意味着你在尽早让Principal Engineer了解你解决的问题, 帮助你学习, 而不是在自以为已经解决之后想去找Principal Engineer“盖个章”。
Principal Consult的过程通常能让人学到很多建模的技巧, 以及自己商务领域的知识。做Principal Consultation是不需要看级别的。一般SDE II就可以去做。SDE I也可以去。当然大多数情况下, 先从最便宜的人用起, 比如自己组里的SDE。不够用了再往上走。
做了这类活动的SDE对设计基本上有了一定了解, 可以针对问题来设计解决方案。差不多看看最近的一些POA演讲也不会有什么危害了。
小结
我发现我这么多年, 就像一个故意饿自己的人。不给自己失败的机会, 让自己没有足够的信息、经验去总结和分析。开始接受失败后, 我熬出来的分析能力, 让我能够由少量失败去得到比常人多得多的成长。
这不代表你应该如此。正面地去锻炼, 去得到经验, 好好消化, 比这样变态的培养可能更有效。你的案例会更多, 你的分析也会更到位。
长期地去训练某个能力、体验失败、并反省, 其实是只有少数人能做到的。像我, 在工作了近十年后,才总算有了失败的勇气。
至于亚马逊, 我会把我的附近做好、改善局部问题。事实证明, 亚马逊的内部还是会注意到问题, 并且勇于改变的。但是这些改变往往有些延迟。而且局部问题根据情况不同, 可能需要更久才能真正改善。