《Dubbo 实现原理与源码解析 —— 精品合集》 《Netty 实现原理与源码解析 —— 精品合集》
《Spring 实现原理与源码解析 —— 精品合集》 《MyBatis 实现原理与源码解析 —— 精品合集》
《Spring MVC 实现原理与源码解析 —— 精品合集》 《数据库实体设计合集》
《Spring Boot 实现原理与源码解析 —— 精品合集》 《Java 面试题 + Java 学习指南》

摘要: 原创出处 阿里巴巴中间件 「石佳宁」欢迎转载,保留摘要,谢谢!


🙂🙂🙂关注**微信公众号:【芋道源码】**有福利:

  1. RocketMQ / MyCAT / Sharding-JDBC 所有源码分析文章列表
  2. RocketMQ / MyCAT / Sharding-JDBC 中文注释源码 GitHub 地址
  3. 您对于源码的疑问每条留言将得到认真回复。甚至不知道如何读源码也可以请教噢
  4. 新的源码解析文章实时收到通知。每周更新一篇左右
  5. 认真的源码交流微信群。

作者 | 石佳宁

“最重要的是选择,最困难的是坚持。”

我是在 2014 年入职饿了么,从前端和 PHP 一直做到后端架构和团队,从 2014 年到 2017 年陆续负责过公司客服、销售、代理商、支付、清结算、订单这些业务的产研与团队;2018 年从业务研发团队抽身,6 个人组起一个小组投身机器学习,试图结合实际的业务场景通过技术改造业务;2019 年回归到平台(中台)研发,负责交易、金融、营销三个中台的研发和团队工作。基于我在饿了么4年和阿里巴巴 2 年研发经历,从技术、业务、管理和架构层面分享一些我的思考。

技术层面

对开发同学而言,技术是立身之本,虽然往往面试造火箭入职拧螺丝,但不可否认的是,技术就是你从业的的基石。不管是基本的动手能力还是问题分析能力,包括你的思维逻辑乃至对事物认知的能力,技术思维都会时刻影响你。最明显的影响就是当你面对无数个问题的钉子时,技术是不是你最顺手的那把锤子。

技术上我比较关注的几个层面:

  • 基本功(语言、编码这个层面,主要是动手能力)
  • 大型分布式系统的实战经验(RPC、SOA、MySQL、Redis、MQ)
  • 项目( DB 设计、API契约、DDD抽象、链路设计、项目风险把控)
  • 稳定性(可用 & 资损)

1. 稳定性

稳定性是一个先有意识再有能力的事儿。记得在 2015 年年初,张雪峰加入饿了么担任 CTO 之后,从他嘴里最常听到的一句话就是“研发要对生产环境有敬畏”。

2014年下半年,各方人马开始杀入外卖市场,饿了么启动百城计划进行业务扩张,短时间内从10+城市覆盖到100+城市,日订单量也很快从10万上涨到100万。业务井喷的同时,技术还没有做好足够的准备。我印象中,2014年下半年几乎每天中午交易量都有新高,但同时也伴随着系统宕机、限流扩容、紧急调优、客服爆线、技术加班熬夜的问题。

我曾在新乡的客服中心看到有的客服同学突然崩溃,耳机直接摔下来离开工位,因为每天会接收到大量用户的来电责问,就在那一刻其实你才会清晰且直观的感受到:你在编辑器的每一行代码,你在服务器的每一次发布,会对现实世界很多活生生的人有直接的影响,你会突然意识到你的工作比你之前以为的要重要且有意义。

所谓研发要对生产环境有敬畏,就是你知道你的作品会对别人产生不好的影响,你会为不好的结果感到惭愧与内疚,这就产生了敬畏。应急处理有一个基本原则:“以业务影响最小为主,优先恢复为核心目的,不要纠结手段和根因。”

别把你的懊悔、决心、对稳定性的思考、各种奇妙的idea以及执行力体现在事故复盘会上,系统的安全生产和火灾一样,事前才有意义。

2. 链路设计

大部分产研缺少全链路的视角,往往看到的是自己负责的点,但是对于一条线乃至整个面是看不到的,也没有机会去思考这些,而对于一些大项目和长链路系统而言,这是致命的。

我的建议是,对你所负责的系统,它关键的上下游、核心业务的链路一定要熟悉,包括数据、接口(调用、功能、逻辑)、各种异常的处理和特殊的设计。能帮你达成这一目的的最简单的办法就是画图、画图、画图!重要的结论说三遍,一定要自己能把系统的大图画出来,然后做到可以根据大图随意放大和缩小。放大到将链路画到业务场景里,突出业务逻辑和上下游交互,缩小到某一次调用的处理逻辑大致是怎样,数据是怎么变化。

经常画图,不用纠结形式和标准,重要的是形成自己理解系统的一个框架,一个自己的思维方式,需要的时候可以随时拿出来用。

日常不管是聊需求还是做系统设计,习惯性的把图画出来,就达成了一半。剩下的一半就要看图去想、去找问题。

3. 技术债务

永远不要骗自己说,现在为了这个需求先挖一个坑,过一段时间再来填(重构 or 重做)。

技术债务和金融债务一样,它必然存在,并且会像无赖一样一直赖着,隔三差五会爆发一下。随着时间的推移和业务的发展,你会发现架构越来越混乱,不同系统的领域边界越来越模糊,系统和需求与组织关系的映射越来越复杂,服务内编码风控越来越不一致,重复的轮子一个接一个隐蔽的出现。

“太忙了没时间梳理哪些问题”、“改那些问题需要上下游一起改,费时费力,推不动”、“现在还没出问题,而且正在整理了,别催”。这是我们经常会听到的声音。其实,技术同学多少都有点代码洁癖,有很多问题不处理不是主观的原因,而是客观上因为精力、时间、ROI等因素,往往要等问题真的爆发后,大家才能狠下心去处理那些问题 。

我以前处理技术债务的思路,是要有一个检查清单,我会定期的复盘所有的系统,并且结合自己团队和其他团队的事故去全量扫雷。系统本身是一个平衡的产物,是时间、功能、风险、未来可能性等几个方向平衡的结果。所以技术债务对于研发同学的考验,不在于你怎么在日常工作中保证系统技术债为0,而是你要评估清楚在有限的资源和时间下,哪些问题是刻不容缓的,哪些问题是可以往后放的。

很难想象一个没有技术追求的团队能开发出一个健壮的、可维护性好、可扩展性好的系统。相反,这种业务代码的堆砌,从短期看也许是“较快”实现了业务需求,但是从长远来看,这种烂系统的增加会极大地阻碍业务的发展,形成一个个的黑洞应用,而工程师被裹挟在业务需求和烂系统之间,疲于应对,心力交瘁。这种将就将导致系统腐化堕落,技术债越垒越高,丑陋的代码疯狂滋长,像肿瘤一样消耗你所有的能量,最后还要你的命。

4. 警惕大项目

并不是所有人都有能力操盘大项目,也不是所有人都能够平衡好交付压力、上线质量、产品逻辑以及时间窗口,这是一个非常有挑战的工作,需要纯粹的技术能力之外的很多软性能力来辅助,比如组织的沟通协作能力、向上要权要责的能力、平衡产品业务期望的的能力、突发情况应急转变的能力等。越大的项目对于Owner的要求也越高,真能把大项目做好不怎么留大坑的少之又少。

大项目从启动到立项所用的时间很多时候是远超项目实际的开发周期的,项目的顺利推进需要“妥协”,但项目的成功需要坚持。很多项目之所以失败,是在做的过程中方方面面不断妥协,最后做出来的东西已经远离了最开始想要的样子。

业务层面

除了技术之外,研发同学对业务层面也需要提升认知与重视。

对于研发而言,业务就像是外语,你不理解业务就好比人在异国,与周围的环境格格不入,并且容易吃亏!相比产品、业务、运营等其他工种,技术更喜欢和技术打交道,业务在大多数同学眼中是混沌且缺少秩序的,没有技术那样清晰的实现路径和稳定共识的知识结构。并且技术相对容易证伪,而业务往往就是不停的尝试,研发都讨厌“不确定性”。但是在一个庞大的组织里想把技术做好,就必然要与业务打交道,毕竟业务才是一家公司存在的核心价值。

1. 基于业务规划做技术规划

很多同学习惯于把计划等同于规划。阿里是一家尊重技术的商业公司,所有的团队都在谈业务、规划里是业务规划、周报里是业务项目、汇报里是业务成果、晋升的时候也要突出你的“战功”。相比技术本身,大家更关注技术改变了什么,在业务部分聊技术团队如何做规划的原因就在于此,这是公司运营的的起点(目的),延伸出来才有具体的技术规划和组织设计作为解决方案。

深刻理解业务并设计战略,拆解战役与项目,通过组织和各种机制确保项目的执行与落地,最终拿到业务结果,这是一个大公司的标准战略执行方式。研发同学做技术规划以及团队规划的时候,一定要考虑到你所在环境,公司今年要主打什么,所在大部门的目标是什么,对口的产品和业务现状如何,纯粹的技术迭代在业务上的好处在哪儿。另外,团队目前有哪些不可抗力,或者影响规划推进的阻力。

很多同学做规划的时候会习惯性按照这个思路进行:①总结现状(痛点) ② 对应的解决方案和策略 ③ 展望未来。有时候②和③的顺序会反过来。很多时候大家发现最终的部门规划和自己做的规划没什么关联,不知道怎么往哪个方向用力,或者干脆继续按照自己的计划先走着。

对大部分同学,我建议规划要实在。做技术规划前,找你周边的研发团队聊一下,找你对口的产品、运营聊一下,知道他们的目标是什么,知道公司几个重点是什么,然后结合你们目前的痛点,在现在和未来之前找平衡、找现在和未来都有收益的那部分。

规划中需要包含一些硬性的内容,比如这个目标要解决什么问题,怎么确定它解决了,解决得好不好,好的结果谁认可等。规划一定要有重点,没有重点那不叫规划,那是日程计划。很多同学对做规划不投入,也有自己的“想法”,比如公司业务或者战略变化太快、组织调整太频繁,下半年在哪个团队工作甚至做什么都不一定,所以规划做得并不认真。不否认变化频繁的存在,以及这种组织架构变化对规划的影响,但是如果你一直这样思考,你永远无法从变化中获得价值,因为你一直在置身事外。

2. 研发要比产品还懂业务

雷军说过:“永远不要试图用战术上的勤奋,去掩盖你战略上的懒惰。”对于研发同学,你要比业务同学更懂业务,才能找到技术与业务平衡的空间。对大部分同学而言,常常是只熟悉自己负责的系统,但是对于想要更大空间和更多成长的同学,我可以给出明确的结论:只熟悉自己负责的系统是不够的。

首先,不同的人对熟悉的定义不一样。对于你负责、你贡献代码、你进行设计并且完成需求交付的系统,单是熟悉远不够。你不仅要知道它的前世今生,思考它的一路成长,纠结它的未来发展,同时还要清楚它的风险与隐患,它的生与死。

基于你最清楚的核心系统,由它开始做业务场景上的外延,以此了解你的上下游,并且能做到结合业务场景去挖掘。从业务的角度、从产品的链路、从技术的调优和隐患多个视角去切,让自己的设计维度与视角不断拉升,这样你有把握或者有掌控力的范围会越来越大,未来才会有更多的机会。

管理层面

团队是一个宏观与微观并存的事物,宏观上我们说组织、讲战略、定规划、要排兵布阵,微观上我们关注沟通、成长、情绪。大部分同学之所以在微观上受挫,就是因为没能把握到宏观的节奏。公司是一个盈利组织,技术中心是一个成本部门,技术中心之所以会有某一个组织,那么一定是:“公司期望这个组织解决某一类问题,并且解决到一定程度。”

所以在这里你要理解一个关键词,“结果和KPI”并不取决于你怎么定义它,而是给你下放目标的组织与管理者对你的期望是怎样的,你们的GAP往往未必是结果的差别,而是期望的落差。

1. 拥抱变化

其实大多数时候不需要你去拥抱,变化会突如其来的抱住你,勒紧你的脖子让你有那么一瞬间觉得呼吸困难。互联网公司之所以变化快,很大程度取决于它的业务属性,相比传统公司,互联网公司能更快、更清晰地感受到与市场的契合程度,并且及时调整策略。

结合这几年的经历,到最近两年加入阿里巴巴,我的核心感悟有两个:

一是对业务的发展和环境的变化要敏感。如果能在变化到来之前主动发起变化,那么化被动为主动是最好的。即使不能,也要清晰地去感受和思考变化背后的动力在哪儿,去找到关键的发力点,让自己可以适应变化。

二是变化带来的工作内容的调整、汇报线的调整、团队的变化等,不管好坏,在一个时间段内都是相对的,而不是一个人工作生涯中绝对的。在不可能事事如意的情况下,调整自己的心态,让自己从情绪中跳出来,更多关注事情本身会是一个更好的选择。

2. 加人不能解决问题

即使嘴上再怎么说“不能”,但是动作会很诚实,依然会尽可能多地要HC,希望把更多“核心”的系统建设在你的职责范围内。其实,从管理的角度,你可以看一下你有没有“有效加人”,一些技术Leader不关注新人的 Landing ,相当于只盯数量不盯质量,最后结果肯定是一塌糊涂的。

从绝对理论的角度,加人肯定是有帮助的,你的资源变多了,周转的空间和操作的余地都丰富了。但是从经验看,大部分情况下,加人没有产生最终的价值变化(项目的结果、业务的成败)。因为系统的开发、项目的推进并不是单纯的资源堆砌,1000 人日的系统哪是 1000 个人做一天就做出来的。真实的世界里,我们往往不是败在资源的使用量上,而是资源的使用方向和使用效率上。

3. 有意识地向上管理

这个问题源于过去经历的两个点:一是我经历了无数次的组织关系调整,我发现不管是我自己还是我团队的同学,大家相比于自己做什么以及带不带人、带多少人外,更关注的是自己的汇报线。自己汇报给谁,谁是我Leader,我和他处不处得来,他能不能让我有提高、有成长。二是很多同学会对与Leader的相处关系有困惑。

基于这两个点,我把向上管理作为一个单独的话题加了进来,先说结论:要!要!要!必须要!一定要!

连马老师都说员工离职的三大要素之一就是和Leader处不来,你怎么还能心安理得的忽略它。如果大家对于向上管理还停留在服从甚至谄媚的态度来处理你们的关系,我只能说太稚嫩了。我没有系统地学过向上管理,也没有体系化地看过这方面的书,所以我只说一下自己的理解。

个体在一个组织里想得到报酬和收益,基本的方法就是促进组织的成长与提高,并且同步提高自己,这样就可以从中分得自己的那份收益。这就要求你产出的结果是要对组织有正向溢出的,但是这个方向与标准并不是所有人都清楚或者能准确地把握到。

经常有绩效差的同学很沮丧甚至抱怨说自己经常加班,甚至是部门走的最晚的,周末也要处理工作等。先不讨论背景,如果命中上面这一条的,我先给你个忠告:除了按件计费的工厂,其它任何地方体力上的付出与最终结果都没有明显的直接关系。就像你上学的时候一定有那么几个别人家的孩子,要么就是特别努力学习特别好,要么就是看上去每天和你一起玩,但是成绩总是碾压你。从学校到社会,这个现象并没有消失,别迷信加班和体力上的付出,大多数人只要能不去思考,在体力上愿意做出的付出,远超你我的想象。

与Leader相处和沟通,本质上是为了达成一致的目标和互相认可的结果。这是一个非常关键的初衷,我有时候开玩笑和团队的同学聊,说你们要好好看看我的Leader到底想干嘛,这样你们做出来,我好去汇报。方向、节奏、结果的对焦对于工作的展开和拿成绩是至关重要的,同时你要从他身上获取更多的信息以便于自己的判断决策和学习,不断从他们身上吸取养分。

在一些环境中,体力上的付出是必须的,但是仅有体力上的付出最终只能感动你自己,你的团队并不想每天陪你加班到11点或者发布到凌晨2点,更没有兴趣凌晨1点半还拉个电话会讨论方案。所以一定要做好“期望管理”,Leader对你的期望、对项目的期望、你对他给予你空间和支持的期望,大家一定要对焦清楚,并且目标一致。

架构层面

还有一点我觉得也很重要,就是在架构层面,包括业务架构、技术选型和细节实现上,要有清醒的认知。

1. 最关键的是定义问题

爱因斯坦说过:“提出问题比解决问题更重要!”定义问题是个脑力活,解决问题是个体力活。大家往往习惯于看到一个问题就冲上去锤它,从概率上来讲,很大可能会陷入一个解决问题的黑洞,就是你不停地在解决问题,但是最终你的情况没有变好。

当你面临一个困难或者一个情况时,首先比较重要的是定义问题,这到底是要解决什么、解决了有什么好处、怎么确定解决了。其次是定义结构,这个问题的关键点组成,你对应的解法是怎样的,这其中得失要怎么权衡轻重,并且最终解决的效果如何贯穿和透传,由点及面。

一个团队可以不停歇的埋头干,但是未必会干出成绩。大部分习惯罗列面对的问题,但是对这些问题并没有做一个全局的分析和梳理,其实最难的就在“找问题”上。

2. 问题的本质没那么高深

有时我们做一个项目,可能有一个产品需求,大家看完觉得不好做或者做不了,因为系统现在不支持,改造成本太高,并且还伴有很多不确定的技术风险。相信很少有人在这种情况下会无脑的要求加人、加工期来解决这个问题。大多数情况下我们会看有没有捷径或者其他方案,让产品效果达成,哪怕技术实现脏一些、绕一些。

其实这时候横向纵向多挖一下或者多问几个问题,有可能就会有不一样的答案。这个需求在解决用户什么问题,目前这个解决方案是不是业务(产品、技术)上唯一的,这个解决方案会带来哪些成本和新的问题,目前正在推进的其他项目和这个问题会不会有关联,有没有其他团队也在解决类似的问题或者曾经解决过。

3. 达成目标

在工作中小到聊定一个API契约、中到上线一个需求、大到完成一次晋升,所有的事情都是有成功的方法的。找出短板、设定计划、抗住挫折、反复训练、根据反馈调优,就可以解决任何问题。《债务危机》的作者——桥水基金 CEO 达里奥总结了一个五步成功法,很有意思:

著名的大数学家波利亚有一本名著《怎样解题》,其中给了一个四步解题法,可能站在研发的角度看会更有感觉:

4. 持续学习才是根本

时代在持续发展和变化,现在正是波澜壮阔的年代,在这样的环境下,不管当前如何积累,都有可能随着发展的变化在短时间跌落谷底。公司能发展,一定是在某一个时期内非常契合环境的要求,但随着时间的变化,如果它的变化不能跟上来,那么也只会被时代抛弃。正所谓让你成功的,最终也将让你失败,比如柯达、诺基亚不能幸免,个体也难逃这样的规律。

这样的情况下,持续的学习和改变自身的能力才是研发同学最大、也是最强的优势。技术本身的日新月异要求你持续学习,同样的习惯放射到各个领域上,才会慢慢的取长补短,优化自身,所以如果说研发同学最需要什么,我认为持续的学习能力是最关键的。

正如饿了么创始人汪渊在之前接受采访时有一句话,让我很难忘:最重要的是选择,最困难的是坚持。

文章目录
  1. 1. 技术层面
    1. 1.1. 1. 稳定性
    2. 1.2. 2. 链路设计
    3. 1.3. 3. 技术债务
    4. 1.4. 4. 警惕大项目
  2. 2. 业务层面
    1. 2.1. 1. 基于业务规划做技术规划
    2. 2.2. 2. 研发要比产品还懂业务
  3. 3. 管理层面
    1. 3.1. 1. 拥抱变化
    2. 3.2. 2. 加人不能解决问题
    3. 3.3. 3. 有意识地向上管理
  4. 4. 架构层面
    1. 4.1. 1. 最关键的是定义问题
    2. 4.2. 2. 问题的本质没那么高深
    3. 4.3. 3. 达成目标
    4. 4.4. 4. 持续学习才是根本