Liangshan

Inner peace.

我的工程师公理(译)

上次提到过,我不喜欢写一些时效性很强的内容(强调我不是没时间写博客)。一年多过去了,终于又看到一篇值得翻译的文章,网上能找到另外一篇现成的中文翻译,是一个简化的版本。我还是决定完整的翻译一下,不过每一条标题我认为都应该简短精炼,所以有些没有完全按照原文翻译。

这篇文章涵盖了编程的经验、对编程这份工作的理解、什么是职业态度等方面。其中的一些观点我深表赞同,有些观点超越了我认知的层级,将我带到更高的视角中。所以我个人非常推荐这篇文章。

工程师的未来

今天本来在睡午觉,突然感觉有种写东西的冲动,爬起来把最近一直在思考的事情记录一下。

如今开发软件的方式正在发生深刻的变革,回想起刚毕业的时候做软件开发工程师,和现在已经截然不同了。

精益敏捷开发

我们团队一直在实践 Scrum,同时我对精益软件开发里面的一些思想又非常认可。 确切的说,精益软件开发是从敏捷开发思想中进一步发展而来,所以今天混在一起谈一下精益开发中的「消除浪费」和敏捷开发中的「回顾会议」。

My 2018

2008 年毕业一晃已经十年过去了,今年破天荒写一次年终总结吧。起因是昨天我们团队内部做了一些分享,其实是为了记录一下团队做过的事情。我本来以为我对团队了如指掌,但听完大家各自的分享,竟然还是有些莫名的感动,原来我们做了这么多事情。因此也算有感而发,这篇年终总结其实就是自己的管理心得总结。

0 - Optimizing For Happiness

这句话是 GitHub 早期员工在 2010 年左右介绍 GitHub 的时候,在一个演讲中提到的。这是我看过的对我影响最大的 PPT,这里面的理念到现在我都深信不疑。文章的基本逻辑是这样的:

  1. Optimizing For Happiness = Investing In Humans
  2. Investing In Humans = A Happy Team
  3. A Happy Team = A Great Product
  4. A Greate Product = Happy Users
  5. Happy Users = Paying Customers
  6. Paying Customers = More Money

综上可得 Optimizing For Happiness = More Money (当然是老板 ^_^)。

我也是照着做的,让他们开心工作,不想做的事情不强迫。但也许也有特例,比如公司组织的社交活动大家不想去就不去,我来搞定。但事实证明,这样做未必是对的,至少要分情况讨论。团队的人是高兴了,但可能给别人一种我们很高冷的感觉。我作为管理者需要考虑这样的影响和印象到底是好还是不好。

1 - Documentation VS Presentation

我们团队一直非常重视知识的积累和持续改进,按照我之前的想法这样就够了。但其实不够,因为缺了一步——展示给别人。和写文档最大的不同是,PPT 的关注点是思考过程,而不是像文档很详细的内容,思考过程恰恰是最能了解设计者思路,展示演讲者能力的。对演讲者自己来说,即是一次彻底的总结,也是向不了解某件事情的人展示自己价值的方式。让优秀的工程师发光,让他的成果被别人认可,而不只是把事情做好就够了,这是我近期想法的一个很大转变。

2 - 今天上线 VS 从长计议

做为管理者,经常需要平衡一个需求是「今天上线」还是「从长计议」,从一名工程师角度出发,我其实一直倾向于后者,把事情想清楚,好好设计一下再做,而不是在系统里到处临时打补丁。然而站在管理者的角度重新来看这个问题,未必是互斥的。很多事情其实可以「今天上线」,然后记个技术债慢慢「从长计议」。从最终结果来看,这样的策略各方的反馈是最好的。

3 - 定期回顾是个好习惯

我从 Scrum 里面保留了计划会、回顾会这样的形式。其中回顾会是每两周一次,每次开始之前都会点一杯奶茶、一份鸡蛋仔,然后互相「吐槽」。

从 2018 年 3 月份开始,我们已经沉淀了 30 多条切实可行的经验,团队成员提出了数十个真正改进了我们系统的想法。这些都是我们独有的、自发的、原创的宝贵经验,回顾会变成了大家最期待的环节(也可能只是期待吃的)。2019 年我们的回顾会要继续开下去。

4 - 总结

2018 年最大的感受就是,如果一个团队做的足够好,自己就会像一个太阳一样,不仅内部火热,还会辐射到其他团队。希望 2019 年,在这个所谓的寒冬,我们能继续开心工作。

分布式系统架构概述(译)

我其实很少翻译东西,首先是因为英文和中文水平都有限,很难做到信达雅,其次一般的文章自己看过就结束了,很少有要翻译的冲动。这次要翻译的是一篇概括性很强的文章,讲的是分布式系统中需要了解的基础概念,值得保存下来经常回顾。

有趣的是,这篇文章在 hacker newsreddit 上得到了基本相反的评价。我个人还是很认可这种概括性的文章的。就好像大学的课程大纲,有很强的指导作用。


两年前我做为移动开发工程师加入了 Uber,之前有一些后端开发的经验。我参与实现了 app 的支付模块——这个模块目前正在重写。之后,我开始进入工程管理领域,领导一个团队。这个团队负责很多和支付相关的后端系统,这意味着我更多的接触了后端开发的东西。

在 Uber 工作之前,我几乎没有分布式系统经验。我的教育背景是传统的计算机科学学位,之后做了十年全栈开发。虽然我之前略知一二,但我对分布式概念(如一致性,可用性或幂等性)没有太多的理解或欣赏。

在这篇文章中,我总结了一些构建大规模、高可用的分布式系统时需要了解的基本概念。这个系统就是 Uber 的支付系统,一个负载高达每秒数千次请求的系统,即使部分系统出现故障,关键支付功能也需要正常工作。 这是一个完整的清单吗? 也许不是。 但如果我早点知道这些的话,会让我的生活变得更轻松。 因此,让我们深入了解 SLA、一致性、数据持久性、消息持久性、幂等性以及我在工作中需要学习的其他一些内容。

什么是做事专业

我们经常说某些人做事很专业,或者不够专业。当我们在使用专业这个词的时候,到底指的是什么?什么事情会让你觉得对方很专业?什么事情恰恰相反呢?

本文探讨的是我认为一个软件工程师如何做是专业的,而不是如何成为一名某个领域的专家。其他行业的应该也大体相通。

认真学习阿里双11的技术

难得过年没有请假,有时间整理一下前几天看了别人转发的,关于阿里双十一的一些技术总结。原文应该叫「互联网技术超级工程」,有兴趣的可以去互联网上搜索一下,应该是免费提供下载的。

那些开源软件的升级版、定制版我就直接略过了,确实是要到一定规模才会遇到的问题,现在看也看不懂。说一些我觉得有意思的地方吧。

记一次性能调优

继上次做性能优化之后,再次针对我们刚刚全新升级的 app 做了一轮性能调优,而这个过程又引起了我一些思考,这里做一个记录。

根据多年的经验,性能问题一般都是由后端服务引起,API 服务器忙都是受后端服务的拖累所表现出来的现象。所以一入手就是监控各个后端服务的运行情况,初步定位瓶颈在数据库上。第一步就是趁着业务上将来要做全文检索,使用搜索引擎代替数据库作为列表的数据源。这个优化上线之后,高峰时数据库压力有了明显改善。然而这个改善并没有表现在前端页面的速度监控上,几乎所有页面都非常统一的在某些时间点会有长至几秒钟的响应时间,发生的时间间隔没有明显规律,大概几分钟一次,每次持续十几秒钟,并且这些异常并不跟我们的业务高峰有重合。

当时的猜测有 2 个,一个是仍然有什么慢查询影响了整个数据库的性能,从而影响了整站的性能。另外一个是某台机器有问题,所以所有落在那台机器上的请求都会变慢。要验证第二点是非常简单的,我单独拿了一台机器去独立运行最简单的一个业务,结果显示并没有什么变化。

再次确认 API 机器没有资源瓶颈的前提下,决定在代码里埋点统计执行时间,发现了一些执行很慢的代码块,慢的时间和那些异常时间也吻合,只是执行时长对不上。刚才提到异常时刻的响应时间以秒计算,这些慢查询最慢也就是几百毫秒,不在一个数量级。第一感觉就是也许这些慢查询累加起来就会将危害放大。总之优化这些地方最起码不是错误的,于是着手把这些找到的点都修正掉了。

然而那些监控图表上的毛刺像一根根的针一样依然存在,并且由于做了几轮优化,高峰和低谷的对比更加明显,这些图看起来就更诡异。

网站性能优化之外

前段时间在做我们内部一个业务的性能优化,过程里有些感想,这里记录一下。

略去具体的技术手段,我想到的其实超出了性能优化的范畴。

首先,优化上线之后引起了 2 个 bug,一个是重构之后某个代码分支没有测试到,另外一个是某处改动同时被其他页面引用,所以影响了该页面。 这印证了我一直以来的想法,写测试代码看似花了额外的时间,其实节省的都是将来修改 bug 的时间。如果没有这些测试代码,怎么有自信去不停的改进?

其次,在整个调优的过程中,我一直在想如果这些代码经过充分的讨论以及 Review,可能就不会被带到线上。因为一些是明显的慢查询,以及一些相关设计上的缺陷。所以 Code Review 看起来同样花了额外的时间,其实节省了将来重构的时间。

其实这两件事还可以结合起来看,没有 review 没有测试代码,或许在暗示工程师可以写烂代码,反正只要项目上线之前测试工程师能通过就可以了。

团队最怕的就是「内耗」,在这次优化过程中,我花了大概一个礼拜的时间。首先把性能数据可视化,以便能直观的看到优化效果,然后了解业务、分析代码,最后动手优化,前后改进了 3 个版本。我认为这已经是某种程度的内耗,因为原本可以做更有意义的事,但花了一个星期来做一些经过工程方法可以避免的事情。

另外想到的一个问题是,我们总是要平衡设计和施工速度。现在互联网公司的趋势是强调施工速度,而刻意避免过度设计。我也反对过度设计,但这并不等于什么都不管先实现再说。反对过度设计并不能成为自己写烂代码的借口。作为一个设计者,要知道哪些东西是「覆水难收」,哪些东西要留足可扩展性。而几乎任何时候,保持低耦合都是很重要的原则。

最后我想说的是,重视招聘和工程师文化的建设,或许这才是解决问题的根本。

多做一点点

自从决定 换个姿势写博客 之后,发现可写的内容越来越少了。

这次讲一个鸡汤故事。

故事要从我刚加入安居客说起,那时候刚刚加入一个相对有规模的团队,对身边的一切都充满着好奇,也折腾点东西。其实现在看来都是一些小儿科的东西,甚至有些是在重复造轮子,质量也不怎么样。但是凭着一股热情,还是打动了团队领导,把我介绍给 尔宁 认识,跟着学点东西。大概是 2012 年的春天,尔宁说我们找个人翻译一下 12 factors 吧,要么你来搞一下,业余时间弄一下就行。

当时还有另外一个工程师翻译的 ZeroMQ 文档 ,跟那个一比,才 12 页内容。我就说没问题。

我忽略了一个问题,把话写的短一点更难。这 12 条原则是高度抽象的,我当时的水平其实至少有一半都看不明白,里面举例使用的工具和软件也都没用过。12 页内容,我至少翻译了 1 个月。最后经过同事帮忙校对,放到 github 上,我自认为算是完事了。

但之后我慢慢发现,工作中遇到的几乎所有问题都能在 12 factors 里面找到答案,甚至每次回顾都能理解以前不懂的部分,所谓的「温故而知新」。于是我又重新整理了一遍翻译,watch 了这个项目(之前只有 star)。

不久之后收到提醒有一位日本的工程师提交了一个 PR,实现了对多语言同时在线的支持。我也依葫芦画瓢把简体中文版的提交了 PR,然后就被合并了,也就是现在看到的 简体中文版。顺便说一下,经过社区的贡献,现在 12 factors 有 11 种语言的版本。

之后基本上每个月都会收到邮件咨询一些 12 factors 的事情,直到有一天收到一封 O’reilly 编辑发来的邮件,内容大概是说 12 factors 太抽象了,他要写一本书扩展一下,找我是让我帮忙校对内容,主要是提提意见。作为回报我可以得到任意 2 本 O’reilly 的书籍,实体书或者电子书都可以。

以前都是 review 代码,这次有机会 review 别人写的书,另外英文原本的书至少也要 200 刀了。为了这些钱,我爽快的答应了。

每次工作累了,就拿书稿出来看一部分,这样断断续续两个礼拜也就弄完了。很快 2 本电子书就按照我的要求被打入了我 O’reilly 的账户。

这就是我当时只是答应多做一点点事情的结果。