一、开篇词
开篇词 | 程序行知:走在同样的路上,遇见自己的风景
这是一个关于路径与行路的专栏。
有时选择对了合适的路,比光顾着赶路要重要得多。
这是一条成长线的表意图,有两个部分:图上左侧的路径,是匹配不同成长阶段,对应不同职业角色;右侧是一条由不同成长阶段组成的成长线,包括如下:
- 征途:启程之初
- 修炼:程序之术
- 修行:由术入道
- 徘徊:道中彷徨
- 寻路:路在何方
- 蜕变:破茧成蝶
“启程之初”,是你刚踏上程序之路面临的一些问题和感悟。”程序之术”,是你工作早期的主要内容,以修炼编程技能为主。除了编程写代码,还有很多其他的内容,这是另外一个维度的修行之路,也即 “由术入道”。
工作数年,成长到一定阶段,你可能会面临一个成长平台期的困扰,在此就进入了 “道中彷徨” 的徘徊期。这些困扰和彷徨很多都关乎选择,这期间是你发出 “路在何方” 之问的寻路期。最后,你坚定了道路,继续前行,前面的路上还有一道 “断层”,突破之后你将会蜕变,最终 “破茧成蝶”。
二、征途:启程之初
01 | 初心:为什么成为一名程序员?
⾸次接触
初⼼未有。
选择专业
初⼼已有,但却是混乱的。
转换专业
初⼼虽已不乱,但依然未明。
转换⾏业
初⼼才算渐渐明了。
⼼明⾏远
作者过去18年的成⻓线
02 | 初惑:技术方向的选择
选择语⾔
选择技术⽅向,从某种意义上讲就是选择语⾔。
要是我来选,我会如何选择语⾔呢?我会选择那些展现出蓬勃⽣命⼒的语⾔。
只熟悉语⾔本身是远远不够的,其实是要熟悉整个⽣态圈。
选择回报
选择技术⽅向,选择语⾔,本质都是⼀种投资。
选择确定性的回报,要⽐抱着赌⼀把的⼼态更可取。看看当前的市场需求是什么,最需要什么,以及⻓期需要什么。
⽐如,今天技术的热潮在⼈⼯智能、机器学习、区块链等上⾯,这是市场最需要的,⽽市场给的价格也是最⾼的。所以,你应该投⼊这⾥么?先别头脑发热,看看⾃⼰的基础,能否翻越⻔槛,及时上得了⻋吗?
技术的选择,都是赚取⻓期回报,短期的波动放在⻓期来看终将被抵消掉,成为时代的⼀朵⼩浪花。
选择⾏业
搞清楚了语⾔、技术⽅向和回报的关系后,最后做出选择的⽴⾜点通常会落在⾏业上。
选语⾔,就是选职业,⽽选职业⾸先选⾏业。
先想想⾃⼰想从事哪个⾏业的软件开发;然后,再看看:这个⾏业的现状如何?⾏业的平均增速如何?和其他⾏业相⽐如何?这个⾏业⾥最好的公司相⽐⾏业平均增速⼜如何?最后,再看看这些最好的公司都⽤些什么样的技术栈和语⾔。如果你想进⼊这样的公司,那就很简单了,就选择学这样的技术和语⾔。
03 | 初程:带上一份技能地图
在程序的技能地图中,可以从两个不同程度的维度来说明:
- 掌握:意味着是一开始就要求熟练掌握的硬技能,这是生存之本。而至于掌握的深度,是动态的,倒是可以在行进过程中不断去迭代加深。
- 了解:相对掌握不是必需,但也需要达到知其然的程度,甚至知其所以然更好。
掌握
开发平台
开发平台,它包括一种编程语言、附带的平台生态及相关的技术。开发平台决定了你会成为什么类型和方向的程序员。比如:服务端、客户端或前端开发等。其中进一步细分客户端还可以有 Windows、Mac、iOS 和 Android 等不同的平台。
- 编程语言
- 平台生态
常用算法
算法,表达的是一个计算的动态过程,它引入了一个度量标准:时空复杂度。
结合工作实际的业务场景,我们需要去设计更贴合需求的算法,而只要是算法它都受到时空复杂度的约束,而我们只是在其中进行平衡与折衷。
数据结构
数据结构通常都和算法一起出现,但算法表达的是动态特性,而数据结构表达的是一种静态的结构特性。
最基础和常用的数据结构:
- 数组 Array
- 链表 Linked List
- 队列 Queues
- 堆栈 Stacks
- 散列 Hashes
- 集合 Sets
- 树 Trees
- 图 Graphs
了解
数据存储
如今广泛流行的数据存储系统有下面三类:
- SQL 关系型数据库(如:MySQL、Oracle)
- NoSQL 非关系型数据库(如:HBase、MongoDB)
Cache 缓存(如:Redis、Memcached)
按了解的深度需要依次知道如下几点:
如何用?在什么场景下,用什么数据存储的什么特性?
- 它们是如何工作的?
- 如何优化你的使用方式?
- 它们的量化指标,并能够进行量化分析?
测试方法
在写代码的时候,用测试的思维与方式(提供单元测试)去审视和检测代码。
开发与测试这两种相反视角的切入维度,能真正长期地提高你写代码的效率和水平。
工程规范
最基础的工程规范是代码规范,包括两个方面:
- 代码结构
- 代码风格
开发流程
在开发流程方法论上,敏捷基本已经横扫天下,所以我们至少要了解下敏捷开发方法论。
先了解,再优化。
源码管理
至少要了解 Git,并用好它。
对源码进行管理的最基本诉求有以下三点:
- 并行:以支持多特性,多人的并行开发
- 协作:以协调多人对同一份代码的编写
- 版本:以支持不同历史的代码版本切换
总结
红色区域相对更小而聚焦,是需要掌握的部分,要求深度;蓝色区域的部分更广而泛,需要广度。
04 | 初感:别了校园,入了江湖
重剑⽆锋
作为⼀名新⼊职的程序员,⾸要之事就是配备⼀台电脑。
因为这是我们程序员每天使⽤最多的⼯具,如果你不在乎你的⼯具,可能你也就不会在乎你的时间和效率。
野蛮⽣⻓
现在的公司基本都会给新⼊职的同学配备⼀个⽼员⼯,俗称 “导师”。
我觉着新⼊⾏的同学,尽量不要去依赖此类导师制。职场的第⼀个台阶就是形成独⽴性:独⽴承担职责的能⼒。
⻘春有价
思考⼀个问题:你能在⼗年后做到相⽐刚毕业时稳定收⼊增⻓⼗倍吗?也就是说现在⽉薪⼀万的⼈,⼗年后能⽉⼊⼗万吗?难,⾮常难。
关于知识、⻅识和能⼒的积累与相应价值的变现,理论与现实的对⽐可能如下图,纵坐标:年薪(单位万),横坐标:⼯作年限。
现实不太可能因为你的能⼒每增⻓ 20% 就会⽴刻体现在你的收⼊上。现实有两种可能:⼀种存在⼀个拐点让你的积累获得相应的价格体现,另⼀种也可能不存在这个拐点,停留在某个⽔平位。其中拐点就是我们现实中常说的机遇吧。
⽆论怎样,要想获得拐点出现的机遇,可能你也只能持续努⼒地积累下去。
三、修炼:程序之术
05 | 架构与实现:它们的连接与分界?
把⼀种想法、⼀个需求变成代码,这叫 “实现”,⽽在此之前,技术上有⼀个过程称为设计,设计中有个特别的阶段叫 “架构”。
是什么
⾏业⾥关于软件架构的共同认知:软件系统的结构与⾏为设计。
做什么
从定义上,你已知道架构是⼀种结构设计,但它同时可能存在于不同的维度和层次上:
- ⾼维度:指系统、⼦系统或服务之间的切分与交互结构。
- 中维度:指系统、服务内部模块的切分与交互结构。
低维度:指模块组成的代码结构、数据结构、库表结构等。
在不同规模的团队中,存在不同维度的架构师,但不论⼯作在哪个维度的架构师,他们⼯作的共同点包括下⾯4个⽅⾯:
- 确定边界:划定问题域、系统域的边界。
- 切分协作:切分系统和服务,⽬的是建⽴分⼯与协作,并⾏以获得效率。
- 连接交互:在切分的各部分之间建⽴连接交互的原则和机制。
组装整合:把切分的各部分按预期定义的规则和⽅法组装整合为⼀体,完成系统⽬标。
架构师的交付成果是⼀整套决策流,⽂档仅仅是交付载体,⽽且仅仅是过程交付产物,最终的技术决策流实际体现在线上系统的运⾏结构中。
实现的最终交付物是程序代码,但这个过程中会发⽣什么?⼀般会有下⾯6个⽅⾯的考虑:
选型评估;
- 程序设计;
- 执⾏效率;
- 稳定健壮;
- 维护运维;
集成部署。
下表为其对应的详细内容:
我以交付⼀个功能需求为例,讲述下这个过程。
我以交付⼀个功能需求为例,讲述下这个过程。实现⼀个功能,可能全部⾃⼰徒⼿做,也可能选择⼀些合适的库或框架,再从中找到需要的API。
确定了合适的选型后,需要从逻辑、控制与数据这三个⽅⾯进⼀步考虑程序设计:
- 逻辑,即功能的业务逻辑,反映了真实业务场景流程与分⽀,包含⼤量业务领域知识。
- 控制,即考虑业务逻辑的执⾏策略,哪些可以并⾏执⾏,哪些可以异步执⾏,哪些地⽅⼜必须同步等待结果并串⾏执⾏?
数据,包括数据结构、数据状态变化和存取⽅式。
开始编码实现时,你进⼀步要考虑代码的执⾏效率,需要运⾏多⻓时间?要求的最⼤等待响应时间能否满⾜?并发吞吐能⼒如何?运⾏的稳定性和各种边界条件、异常处理是否考虑到了?上线后,出现 Bug,相关的监控、⽇志能否帮助快速定位?是否有动态线上配置和变更能⼒,可以快速修复⼀些问题?新上线版本时,你的程序是否考虑了兼容⽼版本的问题等?
最后你开发的代码是以什么形态交付?如果是提供⼀个程序库,则需要考虑相关的依赖复杂度和使⽤便利性,以及未来的升级管理。如果是提供服务,就需要考虑服务调⽤的管理、服务使⽤的统计监控,以及相关的 SLA 服务保障承诺。
以上,就是我针对整个实现过程⾃⼰总结的⼀个思维框架。如果你每次写代码时,都能有⼀个完善的思维框架,应该就能写出更好的代码。这个思维框架是在过去多年的编程经验中逐步形成的,在过去每次写代码时如果漏掉了其中某个部分,后来都以某种线上 Bug 或问题的形式,让我付出了代价,做出了偿还。
“实现”作为⼀个过程,就是不断地在交付代码流。⽽完成的每⼀⾏代码,都包含了上⾯这些⽅⾯的考虑,⽽这些⽅⾯的所有判断也是⼀整套决策流,然后固化在了⼀块块的代码中。
因为实现是围绕架构来进⾏的,所以架构的决策流在先,⼀定程度上决定了实现决策流的⽅向与复杂度,⽽架构决策的失误,后续会成倍地放⼤实现的成本。
关注点
架构的⼀个核⼼关注点:熵。
软件系统或架构,会因为变化⽽腐坏。⼀开始清晰整洁的架构与实现随着需求的变化⽽不断变得浑浊、混乱。这也就意味着系统的”熵”在不断增⾼。
如果你不关注、也不管理系统的”熵”值,它最终的发展趋势就如图中的蓝线,⼀直升⾼,达到临界点,届时你就不得不付出巨⼤的代价来进⾏系统架构升级。⽽实现中重构与优化的动作则是在不断进⾏减”熵”,作出平衡,让系统的”熵”值在安全的范围内波动。
实现的核⼼关注点:简。
简,是简单、简洁、简明、简化,都是在做减法,但不是简陋。关于实现的全部智慧都浓缩在了这⼀个字⾥,它不仅减少代码量,也减少了开发时间,减少了测试时间,减少了潜在 Bug 的数量,甚⾄减少了未来的维护、理解与沟通成本。
架构关注复杂度的变化,⾃然就会带来简化,⽽实现则应当顺着把”简”做到极致。
断裂带
架构与实现之间,存在⼀条鸿沟,这是它们之间的断裂带。
断裂带出现在架构执⾏过程之中,落在⽂档上的架构决策实际上是静态的,但真正的架构执⾏过程却是动态的。架构师如何准确地传递架构决策?⽽开发实施的效果⼜如何能与架构决策保持⼀致?在这个过程中出现实施与决策的冲突,就⼜需要重新协调沟通讨论以取得新的⼀致。
但在我发现和掌握的所有细节中,我需要做⼀个判断,哪些细节上的问题会是战略性的,⽽我有限的时间和注意⼒,必须放在这样的战略性细节上。⽽其他⼤量的实现细节也许和我想的不同,但只要没有越出顶层宏观结构定义的边界即可。系统是活的,控制演化的⽅向是可⾏的,⽽妄图掌控演化过程的每⼀步是不现实的。
关注与把控边界,这就⽐掌控整个领地的范围⼩了很多,再确认领地中的战略要地,那么掌控的能⼒也就有了⽀撑。架构与实现的鸿沟会始终存在,在这条鸿沟上选择合适的地⽅建设桥梁,建设桥梁的地⽅必是战略要地。
等效性
任何架构的可实现性,是完全等效的,但实现本身却不是等效的,对不同的⼈或不同的团队可实现性的可能、成本、效率是绝对不等效的。
架构升级,仅仅是⼀次系统的重新布局与规划,成本和效率的重新计算与设计,”熵”的重新分布与管理。
总结
- 架构是关注系统结构与⾏为的决策流,⽽实现是围绕架构的程序开发过程;
- 架构核⼼关注系统的”熵”,⽽实现则顺应”简”;
- 架构注重把控系统的边界与 “要塞”,⽽实现则去建⽴ “领地”;
所有架构的可实现性都是等效的,但实现的成本、效率绝不会相同。
架构和实现之间有⼀条断裂带,⽽让架构与实现分道扬镳的原因有:
沟通问题:如信息传递障碍。
- ⽔平问题:如技术能⼒不⾜。
- 态度问题:如偷懒⾛捷径。
- 现实问题:如⽆法变更的截⽌⽇期(Deadline)。
06 | 模式与框架:它们的关系与误区?
设计模式
在我看来,模式是前⼈解决某类问题⽅式的总结,是⼀种解决问题域的优化路径。但引⼊模式也是有代价的。设计模式描述了抽象的概念,也就在代码层⾯引⼊了抽象,它会导致代码量和复杂度的增加。⽽衡量应⽤设计模式付出的代价和带来的益处是否值得,这也是程序员 “⽕候” 能⼒另⼀层⾯的体现。
开发框架
⼀个框架是⼀个可复⽤的设计组件,它统⼀定义了⾼层设计和接⼝,使得从框架构建应⽤程序变得⾮常容易。因此,框架可以算是打开”快速开发”与”代码复⽤”这两扇⻔的钥匙。
但若不巧,哪天某个框架在某些情况下出现了问题,在搞不懂框架原理的情况下,就总会有⼈惊慌失措。
如今,框架带来的束缚在于,同⼀个问题,会有很多不同框架可供选择。如何了解、评估、选择与取舍框架,成了新的束缚。
框架,既是钥匙,也是枷锁,既解放了我们,也束缚着我们。
两者关系
框架和模式的共同点在于,它们都提供了⼀种问题的重⽤解决⽅案。其中,框架是代码复⽤,模式是设计复⽤。
框架采⽤了⼀种结构化的⽅式来对特定的编程领域进⾏了规范化,在框架中直接就会包含很多模式的应⽤、模式的设计概念、领域的优化实践等,都被固化在了框架之中。框架是程序代码,⽽模式是关于这些程序代码的知识。
07 | 多维与视图:系统设计的思考维度与展现视图
UML 是⼀种类似于传统⼯程设计领域 “三视图” 的尝试,但却⼜远没有达到 “三视图” 的精准。
在多年的⼯程实践中,我逐渐得到了⼀些维度的视图,下⾯就以我近些年⼀直在持续维护、设计、演进的系统(京东咚咚)为例来简单说明下。
组成视图
组成视图,表达了系统由哪些⼦系统、服务、组件部分构成。
每⼀类服务提供逻辑概念上⽐较相关的功能,⽽每⼀个微服务⼜按照如下两⼤原则进⾏了更细的划分:
- 单⼀化:每个服务提供单⼀内聚的功能集。
正交化:任何⼀个功能仅由⼀个服务提供,⽆提供多个类似功能的服务。
如上,就是我们系统的服务组成视图,⽤于帮助团队理解整体系统的宏观组成,以及个⼈的具体⼯作内容在整个系统中的位置。
了解了服务的组成,进⼀步⾃然就需要了解服务之间的关系与交互。
交互视图
交互视图,表达了系统或服务与外部系统或服务的协作关系,也即:依赖与被依赖。
由于咚咚系统的业务场景繁多,拆分出来的服务种类也⽐较多,交互关系复杂。所以可以像地图⼀样通过不同倍率的缩放视⻆来表达和观察服务之间的交互关系。
如下图,是⼀张宏观⼤倍率的整体交互视图示例。它隐藏了内部众多服务的交互细节,强调了终端和服务端,以及服务端内部交互的主要过程。这⾥依然以地图作类⽐,它体现了整体系统主⼲道场景的运动过程。⽽每⼀个服务本身,在整体的交互图中,都会有其位置,有些在主⼲道上,⽽有些则在⽀线上。
如果我们把⽬光聚焦在⼀个服务上,以其为中⼼的表达⽅式,就体现了该服务的依赖协作关系。所以,可以从不同服务为中⼼点出发,得到关注点和细节更明确的局部交互细节图,⽽这样的细节图⼀般掌握在每个服务开发者的脑中。当我们需要写关于某个服务的设计⽂档时,这样的局部细节交互图也应该是必不可少的。
在逻辑的层⾯了解了服务间的协作与交互后,则需要更进⼀步了解这些服务的部署环境与物理结构。
部署视图
部署视图,表达系统的部署结构与环境。
部署视图,从不同的⼈员⻆⾊出发,关注点其实不⼀样,不过从应⽤开发和架构的⻆度来看,会更关注应⽤服务实际部署的主机环境、⽹络结构和其他⼀些环境元素依赖。下⾯是⼀张强调服务部署的机房结构、⽹络和依赖元素的部署图示例。
部署视图本身也可以从不同的视⻆来画,这取决于你想强调什么元素。上⾯这张示例图,强调的是应⽤部署的 IDC 及其之间的⽹络关系,和⼀些关键的⽹络通讯延时指标。因为这些内容可能影响系统的架构设计和开发实现⽅式。
⾄此,组成、交互和部署图更多是表达系统的宏观视图:关注系统组合、协作和依存的关系。但还缺乏关于系统设计或实现本身的表达,这就引出了流程和状态两类视图。
流程视图
流程视图,表达系统内部实现的功能和控制逻辑流程。
可能有⼈喜欢⽤常⻅的流程图来表达系统设计与实现的流程,但我更偏好使⽤ UML 的序列图,个⼈感觉更清晰些。
下图是咚咚消息投递的⼀个功能逻辑流程表达,看起来就像是 UML 的序列图,但并没有完全遵循 UML 的图例语法(主要是我习惯的画图⼯具不⽀持)。⽽且,我想更多⼈即使是程序员也并不⼀定会清楚地了解和记得住 UML 的各种图例语法,所以都⽤⽂字做了补充说明,也就没必要⼀定要遵循其语法了,重点还是在于要把逻辑表达清楚。
逻辑流程⼀般分两种:业务与控制。有些系统业务逻辑很复杂,⽽有些系统业务逻辑不复杂但请求并发很⾼,导致对性能、安全与稳定的要求⾼,所以控制逻辑就复杂了。这两类复杂的逻辑处理流程都需要表达清楚,⽽上图就是对业务功能逻辑的表达示例。
除了逻辑流程的复杂性,系统维持的状态变迁很可能也是另⼀个复杂性之源。
状态视图
状态视图,表达系统内部管理了哪些状态以及状态的变迁转移路径。
像咚咚这样的 IM 消息系统,就⾃带⼀个复杂的状态管理场景:消息的已读/未读状态。它的复杂性体现在,它本身就处在⼀个不可控的分布式场景下,在⽤户的多个终端和服务端之间,需要保持尽可能的最终⼀致性。
为什么没法满⾜绝对严格的最终⼀致性?如下图所示,IM 的 “已读/未读” 状态需要在⽤户的多个终端和服务端之间进⾏分布式的同步。按照分布式 CAP 原理,IM 的业务场景限定了 AP 是必须满⾜的,所以 C ⾃然就是受限的了。
所有的业务系统都⼀定会有状态,因为那就是业务的核⼼价值,并且这个系统只要有⽤户使⽤,⽤户就会产⽣⾏为,⾏为导致系统状态的变迁。⽐如,IM 中⽤户发出的消息,⽤户的上下线等等都是⾏为引发的状态变化。
但⽆状态服务相⽐有状态的服务和系统要简单很多,⼀个系统中不是所有的服务都有状态,只会有部分服务需要状态,我们的设计仅仅是围绕在,如何尽可能地把状态限制在系统的有限范围内,控制其复杂性的区域边界。
08 | 代码与分类:工业级编程的代码分类与特征
回顾我曾经写过的各种系统代码,按代码的作⽤,⼤概都可以分为如下三类:
功能
功能代码,是实现需求的业务逻辑代码,反映真实业务场景,包含⼤量领域知识。
⼀个程序软件系统,拥有完备的功能性代码仅是基本要求。因为业务逻辑的复杂度决定了功能性代码的复杂度,所以要把功能代码写好,最难的不是编码本身,⽽是搞清楚功能背后的需求并得到正确的理解。之后的编码活动,就仅是⼀个”翻译”⼯作了:把需求”翻译”为代码。
控制
控制代码,是控制业务功能逻辑代码执⾏的代码,即业务逻辑的执⾏策略。
控制代码,都是与业务功能逻辑不直接相关的,但它们和程序运⾏的性能、稳定性、可⽤性直接相关。提供⼀项服务,功能代码满⾜了服务的功能需求,⽽控制代码则保障了服务的稳定可靠。
有了控制和功能代码,程序系统终于能正常且稳定可靠地运⾏了,但难保不出现异常,这时最后⼀类 “运维” 型代码便要登场了。
运维
运维代码,就是⽅便程序检测、诊断和运⾏时处理的代码。它们的存在,才让系统具备了真正⼯业级的可运维性。
功能、控制、运维,三类代码,在现实的开发场景中优先级这样依次排序。有时你可能仅仅完成了第⼀类功能代码就迫于各种压⼒上线发布了,但你要在内⼼谨记,少了后两类代码,将来都会是负债,甚⾄是灾难。⽽⼀个满⾜⼯业级强度的程序系统,这三类代码,⼀个也不能少。
⽽对三类代码的设计和实现,越是优雅的程序,这三类代码在程序实现中就越是能看出明显的边界。为什么需要边界?因为,”码以类聚,⼈以群分”。功能代码易变化,控制代码固复杂,运维代码偏繁琐,这三类不同的代码,不仅特征不同,⽽且编写它们的⼈(程序员)也可能分属不同群组,有⾜够的边界与距离才能避免耦合与混乱。
09 | 粗放与精益:编程的两种思路与方式
认识到我的编程⽅式和习惯在那⼏年已经慢慢发⽣了变化,形成了明显的两个阶段的转变。这两个阶段是:
- 写得粗放,写得多
- 写得精益,写得好
多与粗放
⼀个典型的粗放式编程场景⼤概是这样的:需求到开发⼿上后,开始编码,编码完成,⼈⾁测试,没问题后快速发布到线上,然后进⼊下⼀个迭代。
这个阶段是必要的,它因⼈、因环境⽽异,或⻓或短。
因为每做出⼀个垃圾作品,都会吸取上⼀次制作的错误教训,然后在做下⼀个作品时得到改进。
在通往 “更好” 的路上,总会经过 “更多” 这条路。
好与精益
编程的难点是,⽆论你在开始动⼿编程时看过多少有关编程理论、⽅法、哲学与艺术的书,⼀开始你还是⽆法领悟到什么是编程的正确⽅法,以及什么是”完美” 的程序。毕竟纸上得来终觉浅,绝知此事要躬⾏。
别被所谓 “完美” 的程序所困扰,只管先去盯住你要⽤编程解决的问题,把问题解决,把任务完成。
编程,其实⼀开始哪有什么完美,只有不断变得更好。
⼀个道理:好不是完美,好是⼀个过程,⼀个不断精益化的过程。
10 | 炫技与克制:代码的两种味道与态度
代码读得多了,慢慢就会感受到好代码中有⼀种味道和品质:克制。但也会发现另⼀种代码,它也会散发出⼀种味道:炫技。
炫技
在程序员的成⻓路径上,攀登公司的晋升阶梯时,通常会采⽤同⾏评审制度,⽽作为技术⼈就容易倾向性地关注项⽬或⼯程中的技术含量与难点。
这样的制度倾向性,有可能导致⼈为制造技术含量,也就是炫技了。
除了增加不必要的复杂性外,炫技的代码,也可能更容易出 Bug。
炫技是因为你想表达得不⼀样,就像平常说话,你要故意说得引经据典去彰显⾃⼰有⽂化,但其实效果不⼀定佳,因为我们更需要的是平实、易懂的表达。
克制
在说克制之前,先说说什么叫不克制,写代码的不克制。
其实对于新技术,即使从我知道、我了解到我熟悉、我深谙,这时也还需要克制,要等待合适的时机。
不克制的⼀种形态是容易做出臆想的、通⽤化的假设,⽽且我们还会给这种假设安⼀个⾮常正当的理由:扩展性。不可否认,扩展性很重要,但扩展性也应当来⾃真实的需求,⽽⾮假设将来的某天可能需要扩展,因为扩展性的反⾯就是带来设计抽象的复杂性以及代码量的增加。
那么,如何才是克制的编程⽅式?我想可能有这样⼀些⽅⾯:
- 克制的编码,是每次写完代码,需要去反思和提炼它,代码应当是直观的,可读的,⾼效的。
- 克制的代码,是即使站在远远的地⽅去看屏幕上的代码,甚⾄看不清代码的具体内容时,也能感受到它的结构是⼲净整⻬的,⽽⾮ “意⼤利⾯条” 似的混乱⽆序。
- 克制的重构,是每次看到 “坏” 代码不是⽴刻就动⼿去改,⽽是先标记圈定它,然后通读代码,掌握全局,重新设计,最后再等待⼀个合适的时机,来⼀⽓呵成地完成重构。
11 | 三阶段进化:调试,编写与运行代码
⼀路⾛来⼗多年后,再回溯编程之路的经历,总结编程的进化过程,⼤概会经历下⾯三个阶段。
调试代码 Debugging
编程第⼀阶段的 “调试代码 Debugging” 时期。这个时期或⻓或短,也许你曾经为各种编程⼯具或 IDE 提供的⾼级 Debug 功能激动不已,但如果你不逐渐降低使⽤ Debug 功能的频率,那么你可能很难⾛⼊第⼆阶段。
编写代码 Coding
翻译讲究 “信、达、雅”,编码亦如此。
那么何谓 “信、达、雅” ?它是由我国清末新兴启蒙思想家严复提出的,他在《天演论》中的 “译例⾔” 讲到:
译事三难:信、达、雅。求其信已⼤难矣,顾信矣,不达,虽译犹不译也,则达尚焉。
信,指不违背原⽂,不偏离原⽂,不篡改,不增不减,要求准确可信地表达原⽂描述的事实。
这条应⽤在编程上就是:程序员需要深刻地理解⽤户的原始需求。虽然需求很多时候来⾃于需求(产品)⽂档,但需求(产品)⽂档上写的并不⼀定真正体现了⽤户的原始需求。关于⽤户需求的”提炼”,早已有流传甚⼴的”福特之问”。
福特:您需要⼀个什么样的更好的交通⼯具?
⽤户:我要⼀匹更快的⻢。
⽤户说需要⼀匹更快的⻢,你就跑去 “养” 只更壮、更快的⻢;后来⽤户需求⼜变了,说要让⻢能在天上⻜,你可能就傻眼了,只能拒绝⽤户说:”这需求不合理,技术上实现不了。”可⻅,⽤户所说的也不可 “信” 矣。只有真正挖掘并理解了⽤户的原始需求,最后通过编程实现的程序系统才是符合 “信” 的标准的。
达,指不拘泥于原⽂的形式,表达通顺明⽩,让读者对所述内容明达。
这条应⽤在编程上就是在说程序的可读性、可理解性和可维护性。
按严复的标准,只满⾜ “信” ⼀条的翻译,还不如不译,⾄少还需要满⾜ “达” 这条才算尚可。
同样,只满⾜ “信” 这⼀条的程序虽然能准确地满⾜⽤户的需要,但没有 “达” 则很难维护下去。因为程序固然是写给机器去执⾏的,但其实也是给⼈看的。
雅,指选⽤的词语要得体,追求⽂章本身的古雅,简明优雅。
雅的标准,应⽤在编程上已经从技艺上升到了艺术的追求,这当然是很⾼的要求与⾃我追求了,难以强求。⽽只有先满⾜于”信” 和 “达” 的要求,你才有余⼒来追求 “雅” 。
运⾏代码 Running
编程相对翻译,其超越 “信、达、雅” 的部分在于:翻译出来的⽂字能让⼈读懂,读爽就够了;但代码写出来还需要运⾏,才能产⽣最终的价值。
写程序我们追求 “⼜快⼜好”,并且写出来的代码要符合 “信、达、雅” 的标准,但清晰定义 “多快多好” 则是指运⾏时的效率和效果。为准确评估代码的运⾏效率和效果,每个程序员可能都需要深刻记住并理解下⾯这张关于程序延迟数字的图:
12 | Bug的空间属性:环境依赖与过敏反应
从今天开始,咱们专栏进⼊ “程序之术” 中关于写代码的⼀个你可能⾮常熟悉,却也常苦恼的⼩主题:Bug。
技术性 Bug 可以从很多维度分类,⽽我则习惯于从 Bug 出现的 “时空” 特征⻆度来分类。可划为如下两类:
- 空间:环境过敏
- 时间:周期规律
环境过敏
环境,即程序运⾏时的空间与依赖。
过敏在医学上的解释是:”有机体将正常⽆害的物质误认为是有害的东⻄。”⽽我对 “程序过敏反应” 的定义是:”程序将存在问题的环境当作正常处理,从⽽产⽣的异常。”⽽潜在的环境问题通常就成了程序的 “过敏原”。
应对之道
应对环境过敏,⾃然要先从了解环境开始。
环境那么复杂,你需要了解到何种程度呢?我觉得你⾄少必须关⼼与程序运⾏直接相关联的那⼀层环境。
怎么理解呢?以后端Java 程序的运⾏为例,Java 是运⾏在 JVM 中,那么 JVM 提供的运⾏时配置和特性就是你必须要关⼼的⼀层环境了。⽽ JVM 可能是运⾏在 Linux 操作系统或者是像 Docker 这样的虚拟化容器中,那么 Linux 或 Docker 这⼀层,理论上你的关⼼程度就没太多要求,当然,学有余⼒去了解到这⼀层次,⾃是更好的。
收集信息,不仅仅局限于相关直接依赖环境的配置和参数,也包括⽤户输⼊的⼀些数据。
整体简单总结⼀下就是:空间即环境,包括了程序的运⾏和依赖环境;环境是多维度、多层次的,你对环境的理解越全⾯、越深⼊,那么出现空间类 Bug 的⼏率也就越低;对环境的掌控有⼴度和深度两个⽅向,更有效的⽅法是先⼴度全⾯了解,再同步与程序直接相连的⼀层去深度理解,最后逐层深⼊,”各个击破”。
13 | Bug的时间属性:周期特点与非规律性
Bug 有了时间属性,Bug 的出现就是⼀个概率性问题了,它体现出如下特征。
周期特点
周期特点,是⼀定频率出现的 Bug 的特征。
这类 Bug 因为会周期性地复现,相对还是容易捕捉和解决。⽐较典型的呈现此类特征的 Bug ⼀般是资源泄漏问题。
⾮规律性
没有规律性的 Bug,才是让⼈抓狂的。
好的办法就应该是采⽤⼯具,直接引⼊代码 Profiler 等性能剖析⼯具,就可以准确地找到有性能问题的代码段,从⽽避免了看似有理却⽆效的猜测。
神出⻤没
能称得上神出⻤没的 Bug 只有⼀种:海森堡 Bug(Heisenbug)。
这个 Bug 的名字来⾃量⼦物理学的 “海森堡不确定性原理”,其认为观测者观测粒⼦的⾏为会最终影响观测结果。所以,我们借⽤这个效应来指代那些⽆法进⾏观测的 Bug,也就是在⽣产环境下不经意出现,费尽⼼⼒却⽆法重现的 Bug。
海森堡 Bug 的出现场景通常都是和分布式的并发编程有关。
14 | Bug的反复出现:重蹈覆辙与吸取教训
Bug 除了时间和空间两种属性,还有⼀个特点是和程序员直接相关的。本质重复的错误,导致⼀些 Bug 总是以不同的形态反复出现。
重蹈覆辙
重蹈覆辙的错误。
- 粗⼼⼤意
- 认知偏差
- 熵增问题:程序规模变⼤,复杂度变⾼之后,再去修改程序或添加功能就更容易引发未知的 Bug。
吸取教训
优化⽅法
- 粗⼼⼤意,可以通过开发规范、代码⻛格、流程约束,代码评审和⼯具检查等⼯程⼿段来加以避免。甚⾄相对写错别字,代码更进⼀步,通过补充单元测试在运⾏时做⼀个正确性后验,反过来去发现这类我们视⽽不⻅的低级错误。
- 认知偏差,⼀般没什么太好的⾃我发现机制,但可以依赖团队和技术⼿段来纠偏。每次掉坑⾥爬出来后的经验教训总结和团队内部分享,另外就是像⼀些静态代码扫描⼯具也提供了内置的优化实践,通过它们的提示来发现与你的认知产⽣碰撞纠偏。
- 熵增问题,业界不断迭代更新流⾏的架构模式就是在解决这个问题。微服务本质上就是将⼀个⼤系统的熵增问题,局部化在⼀个⼜⼀个的⼩服务中。⽽每个微服务都有⼀个熵增的极限值,⽽这个极限值⼀般是要低于该服务负责⼈的驾驭能⼒上限的。对于⼀个熵增接近极限附近的微服务,服务负责⼈就需要及时重构优化,降低熵的⽔平。⽽⾼⽔平和低⽔平程序员负责的服务本质差别在于熵的⼤⼩。
塑造环境
总结经验教训,加深印象避免再犯的形式。认识问题的本质,修正真正的错误。
建⽴和维护有利于程序员及时暴露并修正错误,挑战权威和主动改善系统的低权⼒距离⽂化氛围,这其实就是推崇扁平化管理和 “⼯程师⽂化” 的关键所在。
⼀旦系统出了故障⾮技术背景的管理者通常喜欢⽤流程、制度甚⾄价值观来应对问题,⽽技术背景的管理者则喜欢从技术本身的⻆度去解决当下的问题。我觉着两者需要结合,站在更⾼的维度去考虑问题:规则、流程或评价体系的制定所造成的⽂化氛围,对于错误是否以及何时被暴露,如何被修正有着决定性的影响。
四、修行:由术入道
15 | 根源:计划的愿景——仰望星空
在前⾯第 2 章节 “程序之术“ 中,我已把对”设计“”编程“和”Bug“的思考与理解都分享给你了。今天开始进⼊第 3 章节,是关于成⻓修⾏中 “由术⼊道“ 的部分,⽽”道”的维度众多,我就先从和个⼈成⻓最直接相关的 “计划体系“ 讲起。它会有助于你⼀步⼀步⾛向你”理想的⾃⼰”,所以可别⼩看它的重要性。
需求模型
需求层次理论认为个体成⻓发展的内在⼒量是动机,⽽动机是由多种不同性质的需要所组成,各种需要之间,有先后顺序与⾼低层次之分,每⼀层次的需要与满⾜,将决定个体⼈格发展的境界或程度。 其层次模型的经典⾦字塔图示如下:
在⼈⽣的不同阶段,会产⽣不同层次的⽬标需求。
需求⾦字塔底部两层属于物质层次的 “经济基础”,⽽再往上则进⼊了更⾼精神层次的 “上层建筑”。就个体⽽⾔,⾼层次需求要⽐低层次需求具有更⼤的价值。在 “⽣存” 和 “安全” 基本满⾜的保障基础之上,我们才会更从容地向内求,更多地探求内⼼,进⽽向外索,对外去探索、发现和建⽴不同的圈层关系,以满⾜上层的社交 “归属”、获得 “尊重” 与 “⾃我实现” 的需求。
⻢斯洛把底层的四类需求:⽣存、安全、归属、尊重归类为 “缺失性” 需求,它们的满⾜需要从外部环境去获得。⽽最顶层的”⾃我实现” 则属于 “成⻓性” 需求。成⻓就是⾃我实现的过程,成⻓的动机也来⾃于 “⾃我实现” 的吸引。就像很多植物具有天⽣的向阳性,⽽对于⼈,我感觉也有天⽣的 “⾃我实现” 趋向性。
⼈⽣最激荡⼈⼼的时刻,就在于⾃我实现的创造性过程中,产⽣出的⼀种 “⾼峰体验” 感。正因为⼈所固有的需求层次模型,我们才有了愿望,愿望产⽣⽬标,⽬标则引发计划。
⽣涯发展
在攀登需求⾦字塔的过程中,我们创造了关于⼈⽣的 “⽣涯”。⽽ “⽣涯” ⼀词最早来⾃庄⼦语:
吾⽣也有涯,⽽知也⽆涯。以有涯随⽆涯,殆已。
“涯” 字的原意是⽔边,隐喻⼈⽣道路的尽头,尽头已经没了路,是终点,是边界。正因如此,⼈⽣有限,才需要计划。著名⽣涯规划师古典有⼀篇⽂章《你的⽣命有什么可能?》对⽣涯提出了四个维度:⾼度、宽度、深度和温度。这⾥就借他⼭之⽟,来谈谈我的理解。
- ⾼度:背后的价值观是影响与权⼒。代表性关键词有:追逐竞争、改变世界。
- 深度:背后的价值观是卓越与智慧。代表性关键词有:专业主义、⼯匠精神。
- 宽度:背后的价值观是博爱与和谐。代表性关键词有:多种⻆⾊、丰富平衡。
温度:背后的价值观是⾃由与快乐。代表性关键词有:⾃我认同、精彩程度。
每个⼈的⼈⽣发展路线都会有这四个维度,只是不同⼈的偏好、愿望和阶段不同导致了在四个维度分布重⼼的差异。在不同维度的选择,都代表了不⼀样的 “⽣涯”,每⼀种 “⽣涯” 都需要⼀定程度的计划与努⼒。
虽有四种维度,四个⽅向,但不代表只能选其⼀。虽然我们不太可能同时去追求这四个维度,但可以在特定的⼈⽣不同阶段,在其中⼀个维度上,给⾃⼰⼀个去尝试和探索的周期。所以,这就有了选择,有了计划。⽽计划会有开始,也会有结束,我们需要计划在⼈⽣的不同阶段,重点开始哪个维度的追求,以及⼤概需要持续的周期。
⼈⽣本是多维的,你会有多努⼒、多投⼊来设计并实现⾃⼰的⽣涯规划呢?不计划和努⼒⼀下,也许你永远⽆法知道⾃⼰的边界和所能达到的程度。
所以,总要开始计划做点啥,你才能知道⾃⼰的 “涯” 到底有多远;⽽计划就是在系统地探索⽣涯,甚⾄⼈⽣的⽆限可能性。
回⾸⽆悔
关于后悔,有研究说:”我们最后悔的是没做什么,⽽不是做过什么。”回味⼀下,这个结论也确实符合我们的感觉。
若放到前⾯⻢斯洛需求⾦字塔中,”理想的⾃⼰” 就是站在顶端 “⾃我实现” 位置的那个⾃⼰;⽽ “义务的⾃⼰” 正在⾦字塔下⾯四层,挣扎于现实的处境。如果你从来没有去向 “理想的⾃⼰” 望上⼀眼,⾛上⼀步,将来终究会后悔的。事实上,研究结论也证明了这点:70% 以上的⼈都会后悔没有成为 “理想的⾃⼰”。
计划,就是做选择,你在为未来的你做出选择,你在选择未来变成 “谁”。如果你还在为今天的⾃⼰⽽后悔,那就该为明天的⾃⼰做出计划了。
16 | 方式:计划的方法——脚踏实地
就拿我来说,每年结束我都会做⼀次全年总结,然后再做好新⼀年的计划,⼀开始这个过程确实挺艰难且漫⻓的,因为毕竟要想清楚⼀年的计划还是挺难的。但慢
⽬标
富有成效的计划的第⼀步,便是确定⽬标。
在设定⽬标这个领域,国外⼀位研究者⻢克·墨菲(Mark Murphy)曾提出过⼀种 HARD ⽅法。HARD 是 4 个英⽂词的⾸字⺟缩写:
- Heartfelt 衷⼼的,源⾃内⼼的
- Animated 活⽣⽣,有画⾯感的
- Required 必须的,需求明确的
Difficult 困难的,有难度的
我们为什么要⽴ HARD ⽬标?有⼀句话是这么说的:
Easy choices, hard life. Hard choices, easy life.
容易的选择,艰难的⽣活;艰难的选择,轻松的⽣活。
⽅法
⽬标是愿望层⾯的,计划是执⾏层⾯的,⽽计划的⽅式也有不同的认识维度。
从时间维度,可以拟定 “短、中、⻓” 三阶段的计划:
- 短期:拟定⼀年内的⼏个主要事项、⾏动周期和检查标准。
- 中期:近 2~3 年内的规划,对⼀年内不⾜以取得最终成果的事项,可以分成每年的阶段性结果。
⻓期:我的⻓期⼀般也就在 5~7 年周期,属于我的 “⼀辈⼦” 的概念范围了,⽽ “⼀辈⼦” 当有⼀个愿景。
短期⼀年可以完成⼏件事或任务,中期两三年可以掌握精熟⼀⻔技能,⻓期的 “⼀辈⼦” 达成⼀个愿景,实现⼀个成⻓的⾥程碑。
从路径维度,订计划可以⽤⼀种 SMART ⽅法,该⽅法是百年⽼店通⽤电⽓创造的。SMART 也是 5 个英⽂词的⾸字⺟缩写:
Specific 具体的
- Measurable 可衡量的
- Achievable 可实现的
- Relevant 相关的
Time-bound 有时限的
讲讲我如何通过 SMART 来跟踪个⼈年度计划执⾏的。按SMART ⽅式定义的计划执⾏起来都是可以量化跟踪的,我通常⽤如下格式的⼀张表来跟踪:
其实,⼀年值得放进这张表的就那么⼏件事,每件事⼜可以分解为具体的⼏个可量化的任务,再分解到⼀年 50 周,就可以很明显地看出理想计划和现实路径的曲线对⽐。
有时你可能会觉得计划没有变化快,或者计划好的⼈⽣,过起来好机械,没劲。其实计划是准备,变化才是永恒,⽽计划就是为了应对变化。为此,我经常会把计划表按优先级排得满满的,但我永远只做那些计划表顶部最让⾃⼰感到 HARD 的事情。
变化来了,就把它装进计划表中,看这样的变化会排在哪个位置,和之前计划表前列的事情相⽐⼜如何。如果变化的事总能排在顶上,那么说明你的⼈⽣实际就在不断变得更精彩,做的事情也会让你更激动。⽽如果变化⽼是那些并不重要却还总是紧急的事情,⽼打断当下的计划,那么也许你就要重新审视下你当前的环境和⾃身的问题了。
17 | 检视:计划的可行——时间与承诺
程序员啊,有⼀个特点就是偏乐观,所以对于计划的估计总是过于乐观,乐观地期待 “惊喜”,然后⼜”惊吓”地接受现实。那如何才能让计划更具可⾏性呢?⼜可以从哪些⽅⾯来检视呢?
时间与周期
计划的第⼀个影响因素是和时间有关。
我的经验是:做计划不能靠模糊的感觉,⽽是需要精确理性的计算。
先来计算下,⼀年,我们到底有多少时间?⼀个正常参与社会⼯作的⼈,时间⼤约会被平均分成三份。
- 其中的 1/3(约 8 ⼩时)会被睡过去了。
- 另⼀个 1/3 你会贡献到和你的⼯作有关的各种事项中。
最后的 1/3 就是我们常说的决定⼈⽣的业余 8 ⼩时。
⼀年 52 周,会有⼀些法定的⻓假和个⼈的休假安排,我们先扣除两周⽤于休假。那么⼀天业余 8 ⼩时,⼀年算 350 天,那么⼀年总共有 2800 ⼩时的业余时间。但实际这 2800 ⼩时⾥还包括了你全部的周末和⼀些零星的假期,再预扣除每周 8 ⼩时⽤于休闲娱乐、处理各种社会关系事务等等,那么你还剩下 2400 ⼩时。
这 2400 ⼩时就是你可以⽐较⾃由地⽤来安排的全部业余时间了,这就是理性计算的结果。这样看来,⼀年实际能⽤来计划的时间并不多,需要仔细挑选合理的事项,放进计划表,并真正地执⾏。⽽实际,⼀年中你还需要把时间合理地分配在 “短、中、⻓” 三种不同周期的计划上。
短期:完成事项,获取结果,得到即时反馈与成就感(⽐如:写这个专栏)。
- 中期:学习技能,实践经验,积累能⼒(⽐如:学⼀⻔语⾔)。
⻓期:建⽴信念,达成愿景(⽐如:成⻓为⼀名架构师)。
你可以从时间的维度,看看你计划的时间安排是否合理分配在了不同周期的计划事项上。如果计划的事项和周期匹配错了,计划的执⾏就容易产⽣挫败感从⽽导致半途⽽废。
要让计划可⾏,就是选择合适的事项,匹配正确的周期,建⽴合理的预期,得到不断进步的反馈。
兴趣与承诺
吴军有⼀个观点:
凡事从 0 分做到 50 分,靠的是直觉和经验;从 50 分到 90 分,就要靠技艺了。
凭借兴趣驱动的尝试,结合直觉和经验就能达成 50 分的效果,⽽要到 90 分就需要靠技艺了。⽽技艺的习得是靠刻意练习的,⽽刻意练习通常来说都不太有趣。要坚持⻓期的刻意练习,唯⼀可靠的办法就是对其做出郑重的承诺。
通过兴趣来启动,但要靠承诺才能有效地执⾏下去。感兴趣和做承诺的差别在于,只是感兴趣的事,到了执⾏的时候,总可以给⾃⼰找出各种各样的原因、借⼝或外部因素的影响去延期执⾏;⽽承诺就是这件事是每天的最⾼优先级,除⾮不可抗⼒的因素,都应该优先执⾏。
兴趣让计划更容易启动,⽽承诺让计划得以完成。
可⾏的计划应该是:有限的时间,适合的周期,兴趣的选择,郑重的承诺。
18 | 评估:计划的收获——成本与收益
做计划⾃是为了有收获,实现愿景也好,获得成⻓也罢,每⼀份计划背后都有付出与收获的关系。如果计划的收益不能⾼于执⾏它付出的成本,那么其实这种的计划就⼏乎没有执⾏价值。
执⾏计划的成本通常是你付出的时间或⾦钱,但收益则没那么明确,这就需要你去仔细评估和取舍。
成本与机会
计划即选择,⽽但凡选择就有成本。
从经济学思维的⻆度,做计划就是做选择,选择了某些事情;⽽选择了这些事情,就意味着放弃了另外可能做的事情,这⾥⾯的成本就是机会成本。机会成本是放弃的代价,选择这些事情从⽽放弃的其他可能选项中拥有最⾼价值的事情。
计划才能给你真正的⾃由,你对计划的控制⼒越强,离⾃由也就更近了。
结果与收益
计划得到了执⾏,产⽣了预期的结果,才会有期望的收益。
在获得结果的路上,这个世界上似乎有两类⼈:
- 第⼀类⼈,⾃⼰给⾃⼰施加约束,保持⾃律并建⽴期望;
第⼆类⼈,需要外部环境给予其约束和期望。
要获得好的结果,你就要做第⼀类⼈,需要对⾃⼰有更⾼的期望,需要有⾃驱⼒。
那么如何理解收益结构?以我现阶段的状态来说,已有三个直接收益结构:
专业
- 写作
理财
专业,⾃然是指程序专业技能,通过出售⾃⼰的时间和⼈⼒资源来获取⼀份相对稳定的⼯资收⼊来源。写作,到今天这个专栏出品后,终于可以通过作品的形式产⽣直接收益,它只需⼀次性投⼊时间来完成作品。⽽理财属于资产性收益,就是任何等价于钱的家庭动产或不动产,能产⽣利息、分红或租⾦的收⼊,它需要⻓期的收⼊结余积累。
19 | 障碍:从计划到坚持,再到坚持不下去的时候
为什么那么多计划都半途⽽废了?在执⾏计划时,你会碰到怎样的障碍?我想从计划⽣命周期的各个阶段来分析下。
酝酿
酝酿期,是计划的早期雏形阶段;这阶段最⼤的障碍来⾃内⼼:理性与感性的冲突。
启动
启动期,是计划从静⽌到运动的早期阶段;这阶段的最⼤障碍是所谓的”最⼤静摩擦⼒”。
执⾏
执⾏期,是计划实现过程中最漫⻓的阶段;这阶段的最⼤障碍就是容易困倦与乏味。
坚持,特别是⻓期的坚持,是需要动⼒的,⽽动⼒来⾃⽬标和意义。⽽获得⽬标与意义的最好⽅式是讲好⼀个故事。你看,成功的企业家会把未来的愿景包进⼀个美好的故事⾥,让⾃⼰深信不疑;然后再把这个故事传播出去,把所有相信这个故事的⼈聚在⼀起去追寻这个故事;最后,这个关于未来的故事就这样在现实中发⽣了。
挫败
挫败,不是⼀个阶段,⽽是坚持路上的⼀些点;正是在这些点上你遭遇了巨⼤的挫败感。
遭遇挫败,你会进⼊⼀种⼼情与情绪的低⾕,这个时候有很⾼的概率做出放弃的决策。⽽我的经验是,不要在挫败的情绪低⾕期进⾏任何的选择与决策。可以暂时放下这件事,等待情绪回归到正常,再重新理性地评估计划还是否该坚持。
你为了做成⼀件事,定⼀个计划,在执⾏计划的过程中,在 “酝酿””启动” 和 “执⾏” 的不同阶段都会碰到各种障碍,可能都会让你产⽣⼀种快坚持不下去了的感觉。每到此时,你都要想想清楚,哪些是真正客观的障碍?哪些是主观的退却?
20 | 执行:从坚持到持续,再到形成自己的节奏
在执⾏过程中,容易半途⽽废的⼀个很可能的原因在于节奏出了问题。
计划的节奏
⼀个计划被制定出来后,我们通常会根据它的周期设定⼀个执⾏的节奏。
⻓期,就像⻓跑,跑五千⽶是⻓跑,跑⻢拉松(四万多⽶)也是⻓跑,但我们知道跑五千⽶和跑拉松肯定是⽤不同的节奏在跑。
⼀个中期的⽬标,也许是⼀年。
⼀个短期的⽬标,可能是⼏个⽉。
你可能也遇到过,计划的节奏总是会被现实的”意外”打断,每次计划的节奏被打断后,都会陷⼊⼀种内疚的挫败感中;然后就强迫⾃⼰去完成每⽇计划列表中的每⼀项,否则不休息,最终也许是获得了数量,但失去了质量。在这样的挫败中纠结了⼏次后,你慢慢就会发现,现实总是⽐计划中的理想情况复杂多变。
计划更多是给予预期和⽅向,去锚定现实的⾛向,但在⾏进的过程中,”意外” 难免会出现。所以,你要从⼼理上接受它,并从⾏为上合理地应对它。
下⾯我就来说说我是怎么应对这些”意外”的。
按程序员的思考⽅式,我会为所有计划中的事情创建了⼀个优先级队列,每次都只取⼀件最⾼优先级的事情来做。⽽现实总会有临时更⾼优先级的 “意外” 紧急事件插⼊,处理完临时的紧急事件,队列中经常还满满地排着很多本来计划当天要做的事情。
以前,我总是尝试去清空队列,不清空不休息,但实际上这很容易让⼈产⽣精疲⼒竭的感觉。如今,我对每个计划内的事情对应了⼀个⼤致的时间段,如果被现实⼲扰,错过了这个时间段,没能做成这件计划内的事情,就跳过了,⼀天下来到点就休息,也不再内疚了。
他⼈的节奏
跑⻢拉松的时候,⼀⼤群⼈⼀起出发,最后到达终点时却是稀稀拉拉。这说明每个⼈的节奏是不同的,即便同⼀⼈在不同阶段的节奏也是不⼀样。
每个⼈都会有⾃⼰不同的节奏,这需要⾃⼰去摸索、练习,并慢慢提升。如果开始的节奏太快,可能很快就会疲惫、倦怠,很容易放弃;但如果⼀直节奏都很慢,则会达不到练习与提升的效果,变成了浪费时间。
⾃⼰的节奏
找到并控制好⾃⼰的节奏,才能⻓期匀速地奔跑,才能更⾼效地利⽤好⾃⼰的时间和注意⼒。
对于每⽇计划的执⾏节奏,我⾃⼰的经验是:把⾃⼰的时间安排成⼀段⼀段的,⾼度集中和⾼度分⼼交叉分布。
21 | 信息:过载与有效
⾄此,专栏已⽤6篇⽂章讲完了我关于”计划体系“这个主题的理解与思考 ,你是不是已经有点按捺不住想要赶快上路实践了?不急,接下来分享的主题是关于 “精进思维“ 的,它会让你在按计划上路时,会有更好的跑步姿态,从⽽跑得更轻松、更有效率。
现状:信息过载
信息时代,作为离信息距离最近的职业之⼀,程序员应该最能感受这个时代的信息洪流与知识迭代的速度有多快。
状态:疲于奔命
在⾯对这股信息与知识的洪流时,有时我们会不⾃觉地就进⼊到了 “疲于奔命”模式中。
因为每天感觉有太多的信息要处理,太多的知识想学习。计划表排得满满的,似乎每天没能完成当天的计划,就会产⽣焦虑感,造成了⽇复⼀⽇的 “疲于奔命” 状态。
筛选:⼼智模型
⾯对⼤量的信息和知识,我们该如何应对?这可以从两个⻆度来考虑:
- 信息和知识本身的价值
我需要怎样的信息和知识
第⼀点,信息和知识的价值是⼀个主观的判断,有⼀个客观点的因⼦是获取⻔槛。如果⼀个信息或知识随处可得,⼤家都能接触到,甚⾄变得很热⻔,那么其价值可能就不⼤。
第⼆点,就提出了⼀个关于如何筛选信息和知识的问题。⼼理学上有⼀个 “⼼智模型” :
“⼼智模型” 是⽤于解释个体对现实世界中某事所运作的内在认知历程,它在有限的领域知识和有限的信息处理能⼒上,产⽣合理的解释。
每个⼈都有这样的 “⼼智模型”,⽤来处理信息,解释⾏为,做出决策。不过只有少部分⼈会更理性地认知到这个模型的存在,⽽且不断通过吸收相关信息和知识来完善这个模型;更多的众⼈依赖的是所谓的 “感觉” 和 “直觉”。但实际上 “感觉” 和 “直觉”也是 “⼼智模型” 产⽣的⼀种快捷⽅式,只是他们没有理性地认知到这⼀点。
理解了以上两点,再把⼤量的信息和知识限定在我们所处的程序领域,就会得到⼀个合理的答案。
“⼼智” 这两个字合在⼀起是⼀个意思,分开为 “⼼” 和 “智” 两个字⼜可以分别解释为:“⼼” 是你对需要的选择,从⼼出发;”智” 是对价值的判断,智⼒的匹配。
应⽤:⼀击中的
储备了信息,建⽴了知识,最终都是为了应⽤。
没有⽬的的学习是徒劳的,它仅仅是在我们的头脑中流过⼀遍,流过的痕迹很快⼜会被新的信息冲刷⼲净。不管我们拥有怎样的 “最强⼤脑”,在⾯对这股信息与知识洪流时,都⼏乎可忽略不计。
你得挑选那些真正值得做和学的东⻄去让⼤脑满负荷运转,但凡投⼊决⼼去做的事情,就需要百分百投⼊。这就是专注于少⽽精的东⻄,深⼊了解这些东⻄,进⼊到更深的层次上。深可以⽆⽌境,那到底多深才合适?我的答案是:让你的内⼼对取得的效果感受到满意的深度层次上。它的反⾯是:但凡⼼存疑虑,不是那么确定要全⼒投⼊的事情,⼲脆就不做了。
最后,总结下在信息爆炸的时代,我们该如何有效处理、吸收和消化信息:
- 信息过载是现实;
- 疲于奔命是陷阱;
- ⼼智模型是⽅法;
- ⼀击中的是策略。
22 | 领域:知识与体系
其实个⼈的成⻓有很多⽅⾯,但对于程序员的成⻓最重要的就是知识体系的构建,这其实就是⼀个 “点线⾯体” 的演进过程。
下⾯我会结合⾃⼰的成⻓路线来梳理下这个体系的建⽴过程。
点
进⼊任何⼀个知识领域,都是从⼀个点开始的。
在你⼊⾏后,我想你可能也会因为时代、公司或项⽬的原因,有很⼤的随机性去接触很多不同的技术点。但如果你总是这样被客观的原因驱动去随机点亮不同的 “点”,那么你终究会感到有点疲于奔命,永远追不上技术的浪潮。
线
当形成的点⾜够多了后,⼀部分点开始形成线,⽽另⼀些点则在技术趋势的演进中被⾃然淘汰或⾃⼰主动战略放弃。
那你到底该如何把这些零散的点串成线,形成⾃⼰的体系与⽅向呢?如下图,是我的⼀个成⻓ “T 线图”,它串联了如今我沉淀下来的和⼀些新发展的 “点”。
我从成为了⼀名 Java 程序员开始,在这条 “T线” 上,先向下⾛,专注于解决业务需求碰到的技术问题。先⾃然地要向下⾄少⾛⼀层,接触 Java 的运⾏平台 JVM。⽽⼜因为早期做了⼏年电信项⽬,要和很多⽹络设备(包括各类⽹元和交换机等)通信,接触⽹络协议编程;后来⼜做了即时消息(IM)领域的⼯作,⽹络这⼀块就⼜继续增强了。⽽⽹络编程依赖于操作系统提供的 I/O 模型和 API,⾃然绕不过 OS 这⼀块。
在 Java 领域⾛了多年以后,以前涉猎的技术点就逐步暗淡了。⽽再从程序员到架构师,就开始往上⾛,进⼊更纯粹的 “架构与设计” 领域,在更宽的范围和更⾼的维度评估技术⽅案,做出技术决策与权衡,设定技术演进路线。
但是,再好的技术⽅案,再完美的架构,如果没有承载更有意义的业务与产品形态,它们的价值和作⽤就体现不了。所以不可避免,再往上⾛时就会去了解并评估 “业务与产品”,关注⽬标的价值、路径的有效性与合理性。
在整个纵向的技术线上,最终汇总到顶点,会形成⼀种新的能⼒,也就是我对这条纵向线的 “掌控⼒”。到了这个 “点” 后,在这⾥可以横向发展,如图中,也就有了新的能⼒域:领导⼒和组织⼒。
⼀个个点,构成了基本的价值点,这些点串起来,就形成了更⼤的价值输出链条。在这条路上,你也会有⼀条属于⾃⼰的 “T线”,当这条线成型后,你的价值也将变得更⼤。
⾯
线的交织,将形成⾯。
当我试着把我最近六年多在电商客服和即时通讯领域的⼯作画出来后,它就织就了下⾯(如图所示)的这个”⾯”。
我从最早的聚焦于某个业务点和技术栈,逐步延伸扩展到整个⾯。因为 IM 这个产品本身具备很深的技术栈,⽽且也有⾜够多元化的应⽤场景,这样整个⾯就可以铺得特别宽⼴。这也是为什么我已经在这个⾯上耕耘了六年多之久。
但事实上,我并不掌握这个⾯上的每个点,整个团队才会分布⼯作在整个⾯上,每个个体贡献者也只会具体⼯作在这个⾯上的某个或某些点。但我们需要去认清整个⾯的价值体系,这样才能更好地选择和切⼊⼯作的点,创造更⼤的价值。
⽽有时候,我也了解到有些程序员的⼀些说法是这样的:在相对传统的⾏业,做偏业务的开发,技术栈相对固定且⽼化,难度和深度都不⾼,看不到发展⽅向,期望找到突破⼝。若你也出现这样的情况,那就说明你从事的业务开发,其单个技术点的价值上限较低,⽽选择更新、更流⾏的技术,你就是期望提升单个技术点的价值,但单个技术点的价值是相对有限的。
反过来,如果很难跳脱出⾃身环境的局限,那么也可以不局限于技术,去考虑这些传统的业务价值,从技术到业务,再上升到⽤户的接⼊触达,考虑产品的场景、形态和⼈群是如何去为这些⽤户提供的服务、产⽣的价值。
当你对整个业务⾯上的价值点掌握的更多,能抓住和把握核⼼的价值链条,去为更⼴、更⼤的价值负责,那么你就能克服⾃⼰的成⻓发展困境,找到了另外⼀条出路了。
同时,你也为⾃⼰织就了⼀张更⼤的领域之⽹。在整个⾯形成了⼀个领域,在这个⾯上你所能掌控的每条线就是你的体系。在这条线的 “点” 上,你解决具体问题,是做解答题;但在整个⾯上你选择 “线”,是做选择题。
体
体是经济体或其中的单元。
你的 “⾯” 附着在什么 “体” 上决定了它的价值上限。如果 “体” 在⾼速增⻓并形成趋势,你就可能获得更快的发展。
从电⼒时代到信息时代再到智能时代,互联⽹、电商、移动互联⽹,这些都是 “体” 的变化。今天互联⽹⾏业的软件⼯程师,他们⾯临的挑战和难度不⻅得⽐传统的机械或电⼒⼯程师更⼤,只不过他们所从事的 “点” 所属的 “⾯”,附着于⼀个快速崛起的 “体” 上,获得了更⼤的加速度。
“体” 的崛起,是时代的机遇。
总结来说,就是:在领域知识体系中,”点” 是利器,”线” 是路径,”⾯” 是地图;⽽就我们个体⽽⾔,”点” 是孤⽴知识点的学习掌握,⽽ “线” 是对这些点的连接,”⾯” 则构成了完整的知识体系⽹。
23 | 转化:能力与输出
个⼈,建⽴好了知识体系,各⽅⾯都明了了,但有时做起事来却还会感觉发挥不出来;团队,⽜⼈众多,但感觉做出的事情效果却很⼀般。
这类问题的症结,多就出在从体系积累到输出转化的环节,它涉及两个实体的转化问题:
个体
我们从学会⼀个知识,到能够熟练应⽤其去输出能⼒,⼤概会经历如下过程:
所以,对于个体⽽⾔,刚建⽴起⼀个初步的知识体系,到能真正充分发挥出这个体系的⼒量,才仅仅是刚开始。
团队
如果说个体的能⼒输出像出拳,那么团队的输出就像战争了。
《原则》的作者是雷·达⾥奥描述了⼀个思想和实践,就是把公司当作 “机器” (原⽂是 Machine)来管理运转。在作者看来管理者就像是⼯程师,⽽⼯程师维护机器运转的⼯作状态我们都能想象到,或通过机器的运⾏仪表盘监控机器的运转状态,或通过指标优化机器的运⾏效率。⽽达⾥奥的 “机器” 就是他建⽴的管理公司的体系。
曾经,我们团队有个⾼级测试⼯程师,在他晋升测试架构师级别的述职时,提到他的⼀项⼯作就是搭建测试体系来帮助团队改善测试⼯作的效率和效果。在进⾏阐述时,他完整地描述了这个体系 “机器” 的各个零部件组成,他制造的很多⼯具和系统,却缺失了关于体系的⼀些最重要的⽅⾯:
- 这个体系是如何运转的?
- 它提供了哪些系统和仪表盘监控指标来⽀撑和反映其运转状态?
为什么这个体系能在团队⾥运转?
以上三个问题,就反映了 “机器” 体系的三个核⼼点:
流程规则
- ⼯具系统
规范共识
没有流程规则,”机器” 体系就不知该如何运转;缺乏⼯具系统⽀撑,就没法监视和控制这个体系的运转效率与效果;⽽如果未能在团队形成共识并达成规范,”机器” 体系就不可能”和谐”运转起来。所以,流程规则,建⽴其运⾏轨道;⼯具系统,⽀撑其⾼效运⾏;规范共识,形成了协调合奏。
团队能⼒输出就是这样⼀个 “机器” 体系运⾏的过程。那么团队的强弱就由两⽅⾯决定,⼀是团队中所有个体形成的体系⼒量之和,⼆是由流程规则、⼯具系统和规范共识共同决定的转化效率。
转化
从个体到团队,都是通过搭建体系来积蓄⼒量,再通过体系的运转来输出能⼒。
这⾥的共同思维⽅式是:体系化、⼯具化。这是⼀种标准的⼯程师思维模式,巧妙的是它依然可以⽤在⾮⼯程的领域。体系,从⼯程维度看就像⽣产流⽔线,⽽体系的运转就是开动了⽣产流⽔线。搭建并调校出⼀条⾼转化输出能⼒的体系⽣产线,是真正具有核⼼竞争⼒和护城河的事情。
个体和团队的强弱,⼀⽅⾯取决于我们在体系中积蓄的⼒量的总量,另⼀⽅⾯在于体系运作的转化输出率。体系决定了⼒量的总量,⽽转化决定了拳拳到⾁的痛感。
24 | 并行:工作与学习
该如何在⼯作的同时,保持学习,并持续成⻓与进阶呢?我想,可以先从分析”程序员的⼯作本质是什么”开始着⼿。
⼯作
程序员的主要⼯作是:编程,产出代码,完成需求,交付程序系统。
程序员按其⼯作技能和经验,⼤体⼜分为三个阶段:初级、中级和⾼级。这三个级别的程序员的主要⼯作都是编程与产出代码,产出代码的数量也许相差不⼤,但产出的代码属性就可能有明显差别。
什么是代码属性?它包括资产与负债两类。由⼤量初级程序员产出的代码并以此构建的软件系统,如果最终能完成交付,那么很可能资产和负债性基本持平。
从初、中级⾛向⾼级程序员,就不仅仅是交付代码,完成⼯作,还要有后续的更⾼要求。如:达成品质、优化效率。⽽在不断晋级的路上,跨越的⻔槛就在于此,很多⼈⽐较容易被卡在不断地在完成⼯作,但却没有去反思、沉淀、迭代并改进,导致⼀直停留在了不断重复的怪圈之中。
程序员,⼯作以产出代码为主,从初级到⾼级,代码的负债属性逐步降低,资产属性不断提升,最终成为⾼品质的个⼈贡献者。⽽从完成到追求品质和完美的路上,不仅仅是靠⼯作实践的经验积累,还需要有意识地持续学习。
学习
持续学习,是让你突破不断循环怪圈的不⼆法⻔。
在⼯作中,我⼀直有观察到⼀个现象,很多⼈因为离开学校后,⼯作任务多,压⼒⼤,从此就停⽌了系统地学习。在《浪潮之巅》⼀书中,吴军写道:
国内: ⼩时候努⼒,到⼤学后就不努⼒了。
国外: 到⼤学后才开始努⼒,很快就超过国内学⽣。
学习还需要聚焦和主动选择,毕竟你的精⼒和时间都是有限的。⽽有选择性的学习就需要找出真正与你近期规划有关的学习路径。
对于学习语⾔本身我觉得最⾼效的⽅法就是看⼀本该领域的经典⼊⻔书。⽐如,对于 Java 就是《Java 核⼼技术》或《Java 编程思想》,这是我称之为第⼀维度的书,聚焦于⼀个技术领域并讲得透彻清晰。
在有了该语⾔的⼀些实际编程和⼯程经验后,就可以看⼀些该领域第⼆维度的书,⽐如:《Effective Java》《UNIX 编程艺术》等,这些是聚焦于特定领域经验总结型的书,这类书最有价值的地⽅是其聚焦于领域的思想和思路。
如果过早地看这类书反⽽没什么帮助,甚⾄还会可能造成误解与困扰。
⽽另外⼀些技能,像 Java 开发⼯作需要⼤量使⽤的开源框架⼜该如何学习?张铁蕾曾写过⼀篇《技术的正宗与野路⼦》,其中介绍了如何⽤真正 “正宗” 的⽅式去学习并快速掌握这些层出不穷的开源新框架和技术。
这⾥就借⽤原⽂⾥的⼀张图(重新按统⼀⻛格绘制了下),每⼀项开源框架或技术相关的学习资料可以组织成下⾯这张⾦字塔形的结构图。
Tutorial(指南) 和 API Reference(应⽤编程接⼝参考) 层次的信息资料能帮助你快速上⼿开发,⽽ Spec(技术规范)和 Code(源代码)会帮助你深刻地理解这⻔技术。⽽其他相关的技术书籍和⽂章其实是作为⼀种补充阅读,好的技术书籍和⽂章应该有官⽅资料中未涵盖的特定经验或实践才算值得⼀读。
张铁蕾在⽂中如是说:
每当我们接触⼀项新技术的时候,都要把⼿头的资料按照类似这样的⼀个⾦字塔结构进⾏分类。如果我们阅读了⼀些技术博客和技术书籍,那么也要清楚地知道它们涉及到的是⾦字塔中的哪些部分。
我深以为然,关于技术学习我们不能简单地蜻蜓点⽔、复制粘贴、拿来主义,应是去建⽴你的知识 “⾦字塔”,形成体系结构,⽽每次的学习实践都是在不断完善你的 “⾦字塔”。⾄于更多技术性学习的细节,若你感兴趣的话,也可以去看看那篇⽂章。
路径
保持学习,不断成⻓,⼯作也许还在重复,但成⻓却在迭代上升,然后才会有机会⾯临更多可选择的路径。
程序员在攀登职场阶梯的道路上,⾛过了⾼级,后⾯还会有好些分叉路线。⽐如,转到脱离技术的纯管理岗或者技术管理岗。技术主管或架构师某种意义上都属于技术管理岗,不懂技术是做不了这两个⻆⾊的;或者继续沿着深度领域⾛,成为细分领域专家。
⾯对怎么选路的问题,我近些年学习的收获是这样的:选择⾛最适合实现个⼈价值的路。这就是我的基础选择价值观。
拉姆·查兰有本书叫《领导梯队》,书⾥把⼈才潜能分成三种:熟练潜能、成⻓潜能和转型潜能。原书对这三点做了详细的特征描述,我简单提炼下主要特点:
- 熟练潜能:关注当前专业领域且⼗分熟练,但没有显示出在开发新能⼒上的努⼒,竭⼒维持现有技能。
- 成⻓潜能:按需开发新能⼒,显示出⾼于当前层级要求的其他技能,如:专业、管理、领导。
转型潜能:持续有规律地开发新能⼒,追求跨层级的挑战和机会,展现雄⼼壮志。
⼈⼒资源管理中的⾼潜⼈才盘点,基本就来⾃这套模型,主要就是识别出这三类潜能⼈才。”熟练潜能” 已是我们这⾏对学习的最低要求,在程序员这个技术⽇新⽉异的⾏业⾥,维持现有技能确实已经让不少⼈感觉很竭⼒了。
程序员的⼯作形式是编程产出代码,本质是完成需求,交付系统;但在⼯作中容易陷⼊不断完成的循环怪圈,要打破它,就需要你持续学习并有意识地关注交付代码的品质和属性,⼀⽅⾯提升了交付质量,另⼀⽅⾯也获得了个⼈成⻓。
⽽学习的路在时间上是永远持续的,在空间上也是有路径的;有效的学习需要你关注学习曲线的变化,遵循有体系的技术学习框架,匹配适合当前阶段的学习资源。
25 | 时间:塑造基石习惯(上)——感知与测量
⾄此,咱们专栏已⽤4篇⽂章分享了我关于”精进思维“这个主题的理解与思考,期待以后你能得⼼应⼿并游刃有余地持续进阶。
接下来,咱们专栏⼜会进⼊⼀个新的主题:习惯。
养成好的习惯能帮助我们更快地成⻓,⽽在所有的好习惯中,关于时间的习惯是其中的基础,我称之为 “基⽯”习惯。如果你的时间习惯不好,那你做其他事情的效率往往也就不⾼。
那么,该如何塑造好时间这块 “基⽯”呢?我觉得在有效地应⽤之前,先需要精确地感知与测量。
感知时间
曾经在知乎上看到个问题:”为何⼈随着年龄的增⼤觉得时间过得越来越快?”这个问题的⼏句答案,解答了我多年以来的困惑:
有共性的回忆趋向粘合在⼀起,标志性的回忆倾向于鹤⽴鸡群。⼼理学家认为:我们对时间的感知同时和我们的经历有关。如果⼀件事对于我们来说是 “激动⼈⼼” 的,这样的记忆在我们脑海中感觉到的时间会更⻓。
测量时间
有⼀本书叫《奇特的⼀⽣》,主要是关于⼀位苏联科学家柳⽐歇夫的故事,他通过⾃创的 “时间统计法” 在⼀⽣内取得了惊⼈的成就。⽽我在遇到这本书之前,已经在使⽤⼀种类似的⽅法:我会记下⼀年来经历的所有有意义的事件(除去每⽇的例⾏⼯作),我称之为 “时间⽇志”。
我按每周来记录,每周⾥⾯有每天的事件记录和所花费的时间。
这就是关于时间的第⼀个 “基⽯” 习惯,在精确地感知与测量时间之后,你才可能更准确地”预知” 未来。
26 | 时间:塑造基石习惯(下)——切割与构建
为了更有效地利⽤好你每天有限的时间,就需要你重新审视并调整你的时间切割与构建⽅式。
切割时间
转换⼀下看待时间的⽅式。
两个⼯⼈正在⼯地搬⽯头,⼀个路⼈正好⾛过,就问他们在做什么?
第⼀个⼯⼈说:”我在把⽯头从这边搬过来,并垒在⼀起。”
第⼆个⼯⼈说:”我在盖⼀座华丽的教堂,盖好后,你再来欣赏我的作品。”
关于时间的第⼆个 “基⽯” 习惯:将时间切割成建造你⼼中”⼤教堂”的合适”⽯材”。
构建⽅式
适当的构建⽅式,是指在时间的 “基⽯” 习惯之上,建⽴其他的习惯。
⽐如,好些年前开始,我会从每周的时间⾥切出来⼀块,专⽤于写作,慢慢就形成了写作的习惯。这意味着,我从现有的 “时间⽯材” 中拿出了⼀部分,⽤于构建写作的习惯,然⽽ “时间⽯材” 的总量是有限的,我必须在其上建⽴有限数量的习惯,我得做出选择。
任何⾏动的发⽣,都需要两种努⼒才有可能:第⼀种,是⾏动本身固有需要的努⼒,如跑步,跑⼀公⾥和跑⼗公⾥固有需要的努⼒是不等量的;第⼆种,指决策是否执⾏这种⾏动的努⼒,决定跑⼀公⾥还是跑⼗公⾥的决策意志⼒消耗,我想也不会⼀样。
构建习惯的⽬的,以及它们能起作⽤的原因在于:它能消除⾏动中第⼆种努⼒的决策消耗。
我之所以选择构建写作习惯⽽不是跑步习惯的原因是,对⼀个像我这样的程序员⽽⾔,写⽂章和写代码的感觉很接近,它就好像是⼀种刚好在程序员的能⼒边界线外不远处的事情。这样,写作⾏动所需要付出的两种努⼒,感觉都还在可以应对的范围,属于能⼒边界附近不远的事情,也是正适合⽤来扩张能⼒边界的事,有⼀种挑战的刺激感,⼜不⾄于望⽽⽣畏。
所以,在时间 “基⽯” 习惯之上构建的习惯应该是你能⼒范围之外的⾏动。如果⼀项⾏动通过习惯慢慢变成了能⼒范围之内的事,那么你以后再去做类似的事,其实就不需要再付出什么决策努⼒了,也就不再需要习惯来帮忙了。
习惯,它的表象和形式给⼈的感觉是在重复⼀件事,但它的内在与核⼼其实是不断产⽣交付,持续的交付。
如果你要构建⼀个习惯,就要运⽤好基因中本已存在的关于 “采集和狩猎” 的本能:⾼度专注,跨出边界,持续交付。
末了,我把上、下两篇的内容⼀起提炼总结为如下:
- 要形成时间习惯,要通过有意识的感知和测量来发现时间是怎么流失的。
- 要完成建设你⼼中 “⼤教堂”,要通过切割 “时间原⽯” 来完成 “时间⽯材” 的准备。
- 在养成了时间的基⽯习惯之上,挑选和构建其他习惯来完成 “⼤教堂” 的持续建设与交付。
27 | 试试:一种”坏”习惯
曾经,我碰到⼀些程序员问我:”我以前是做安卓的,现在想试着学下后端服务开发,你觉得怎样?”我⼀下⼦就卡住了,不知该如何回答才好。原因是:学习本是个好事,但前⾯加个 “试着” 似乎感觉就不太好了。
好的出发点
“试⼀试” 的初衷本来就该是好的,它表达了⼀种好奇⼼,以及尝试⾛出舒适区的勇⽓。
程序员这个职业,会带来⼀些职业习惯。⽐如,可能会经常性地去尝试⼀些新东⻄,然后看看它是否如预期般那样被应⽤或实现。
模糊的终点
这⾥,”试⼀试”的”坏”习惯的”坏”字之所以加上双引号,就在于它的出发点本是好的,但如果终点是模糊的,那就”坏”了。
近些年来,就出现过⼏轮的技术热,⽐如,刚进⼊移动互联⽹时代就⼤热、但如今已经回归常温的移动开发,曾经⼤热现已降温的云计算与⼤数据,以及还在热度中的⼈⼯智能、机器学习和区块链等。⾯对这些技术热,很多⼈都跃跃欲学之、试之。可能你也不例外。那么,到底为什么你会想去尝试⼀种新技术?是你仔细思考后的主动选择,还是说或多或少⼜被技术潮流所裹挟?
好些年前,移动开发还在升温阶段时,我也不可避免地被这样⼀种潮流所裹挟过。我开始看⼀些关于 iOS 开发的书,从语⾔到⼯具。其实,尝试学习⼀种新技术并不是坏事,即使是被技术潮流所裹挟,但问题出在,这次尝试的终点在哪⾥?
我是想转型成为⼀名移动开发⼯程师吗?还是说我有⼀个想法,需要开发⼀个 App 来达成?抑或我仅仅是想学习并了解下移动开发是怎么回事,从⽽进⼀步提升下技术的⼴度理解与视野?
然⽽以上皆不是,我当时的尝试完全没想清楚终点在哪⼉。后来热度下来了,其他⼯作任务也多了,也就慢慢遗忘了。回过头来看,这只是浪费了⼀些时间和精⼒罢了。
⼏年后,⼈⼯智能与机器学习⼜热了起来,我⼜开始尝试学习起来,但较上次不同的是,这次我把尝试的终点定义得很清楚。我不是想转型成为⼀名机器学习领域的算法⼯程师,也不是因为它很热就”随波逐流”地被潮流裹挟,我这次尝试的终点就是想搞清楚关于⼈⼯智能与机器学习的三件事:
- 它的原理与应⽤场景;
- 它的前世今⽣;
它如今已抵达的边界。
搞清楚这三件事,虽不会让我成为机器学习的专家,但会提升我对于这个热⻔技术的判断⼒。因为,现实中我需要判断⼀些真实的业务场景该如何结合这样的技术,这就需要了解它们的应⽤场景和⼀些原理。
另外,⼀⻔新技术很少是凭空冒出来的,了解它们的前世今⽣,会更有效地知道,哪些⽅⾯已经有了成熟的⽅案,哪些地⽅还在⻘涩的探索期。再结合它当前的边界,就知道如何定义清楚需要,形成合理的技术⽅案,⽽不会产⽣过度的妄想。
试⼀试,需要有更清晰的终点。关于终点,你也可以从下⾯⼀些⽅⾯来考虑:
1. 验证猜想。这个部分程序员就很熟悉了,因为编程中的调试其实最重要的⽬的就是验证猜想。引⼊⼀种新技术或框架,验证 API 的调⽤结果或运⾏输出是否如你所想,即使最终否决了,那你也获得了判断的依据与知识。
2. 收获结果。定义清楚你尝试的这件事,到底能收获怎样具体的结果。⽐如:考试,尝试的收获就是要通过。
3. 体验过程。有时候结果并不确定,⽐如,创业的结果未必就⼀定是成功,那么这样的尝试难道就没有意义了吗?有的,因为创业的超低成功率,所以,体验过程恐怕多于收获最终结果。
4. 理解现实。你尝试⼀个新东⻄或学习⼀个新知识,有时未必真是为了将来有朝⼀⽇能⽤上它,⽽主要是为了完善你的知识与认知体系,然后再去理解现实为什么是这样的。
现实的路径
“试⼀试” 的路径是有限的,毕竟终究离不开现实的约束。
有时候,你因为现实⼯作需要,可能需要不停地在各种技术栈上切换。⽽很多技术可能过了那段时间,就再也⽤不上了,这样的技术尝试难免会让⼈感觉可惜。但通过我前⾯列出的关于 “终点” 的⽅⾯,再来分析下这个现实场景。
⾸先,你得⾯对现实,这样的技术尝试在现实中太多太多了,有时就是没得选择。
其次,如果觉得仅仅⼀次性收获的结果,不值得你投⼊的时间和精⼒,那就可以从 “理解现实” 的⻆度去挖掘。这些知识,从学以致⽤的⻆度很快就过时了,但它们并不是完全孤⽴的,事实上计算机程序体系内的很多知识都不是完全孤⽴的,它们都有相互的联系与连接点。
从理解的⻆度,这类技术切换的尝试事实上扩⼤了你的知识边界,尝试的也许是孤点,但你可以进⼀步找到它们的连接处,形成体系。因为很多现实的原因,每个⼈的起点和路径都不会⼀样,但我们都是从某⼀点开始去慢慢摸索、尝试,最终⾛出⼀个属于⾃⼰的体系来的。
最后,当你有了⾃⼰的体系,也可能有了更多的尝试选择权,就可以体系为中⼼,去有选择地尝试对你更有意义或价值的事了。
28 | 提问:从技术到人生的习惯
提问这个习惯,我有三个层⾯的理解:
如何问?提问之术
⼀个能够回答的具体问题,⼀般都是解答题形式,表达清楚你的解答⽬的,也许你的困扰在⾼⼿那⾥根本就不存在。你只是⾛了⼀个弯路⽽已,这样不仅绕过了障碍,还获得了⼀条近(先进的)路,这就是有意义的提问。
⾄此,就得到了提问的第⼀个原则:提供⾜够的信息,让⼈能够回答。
草率的问题是懒惰的问题,通过搜索引擎就能简单获得;草率的问题是模糊的问题,让⼈没法回答。⽽更有意义的提问是把解答题变成选择题,提供你的选项,展现你探索了哪些路径,省去了可能产⽣的反问。也许你的某条路径已经⾮常接近答案了,只是卡在了某个点上,知道答案的⼈⼀看就明⽩了,也很容易回答。
这就是提问的第⼆个原则:提供更多的选项,让⼈⽅便回答。
即使你的问题能够回答,也⽅便回答,但也可能得不到回答。因为,回答问题需要有驱动⼒。提问本是⼀种索取,要让⼈有更多的回答动⼒,还需要付出。付出⼀种态度,表达感谢;付出⼀份可供交换的视⻆,建⽴讨论的基础。
这就是提问的第三个原则:提供交换价值,建⽴讨论基础,表达感谢态度,让⼈乐于回答。
归纳下关于提问之术的三个⽅⾯:
- 提让⼈能够回答的问题:草率的问题,只能得到⼀个草率的答案。
- 提让⼈⽅便回答的问题:你得到的答案的好坏取决于提问的⽅式和开发答案的难度。
- 提让⼈乐于回答的问题:只索取⽽不愿思考和付出的提问者,要么什么也得不到,要么只会得到 RTFM(Read TheFucking Manual) 或 STFW(Search The Fucking Web)。
问什么?求解之惑
先从⼀个记录问题,积攒 “问什么” 的习惯开始,不断去积累并留下⼀些东⻄,将来再定时去回顾这些问题,也许就会得到意外的收获。对于程序员,总会碰到各种技术问题,就从这些最具体的问题开始,把暂时这阶段还没法回答的问题按⼀种模式记录下来,⽐如下⾯这样:
- 问题的上、下⽂;
- 问题的具体描述;
- 问题的解决思考和思路;
- 问题的解决⽅案和具体技术或办法;
问题解决后留下的思考或其他延伸的疑问。
当遇到暂时没有答案的问题时,先记录下来。
为何问?价值之道
提问的⽬标是获得答案,⽽答案于我们⾃⼰⽽⾔是⼀种价值;为何⽽问,就是发问于我们的价值之道,最终指向的⽬的是:认清⾃我。
值得问 “为何” 的问题不多,但总会遇到,它是⼀道选择题,有关我们的价值选择。我们最关⼼的是⾃⼰的命运,⽽关于命运有⼀句话是这么说的:
选择决定命运,什么来决定选择?价值观。
价值观,是我们对事情做出判断,进⾏选择取舍的标准。每个⼈都有价值观,⽆论你能否清晰地定义与表述它,这些观念都决定了你的⾏为标准。
为何⽽问?获得答案,认清⾃我,选择⾃⼰的价值之道。
关于提问,今天就分享到这⾥,我总结提炼下:
- 如何问,是关于提问的 “术“,考虑让⼈能够回答,⽅便回答和乐于回答;
- 问什么,是关于成⻓的 “惑“,去积累问题,寻找答案,并分享出来,从⽽完成了价值的积累、传递与交换;
- 为何问,是关于选择的 “道“,价值观的选择决定了不同的道。
成⻓的过程,⼀般都是从提出⼀个问题开始,找到答案,再融⼊⾃身的价值观,完成下⼀次更好的选择,周⽽复始,形成习惯,化作天性。
29 | 偏好:个人习惯的局限与反思
⾃⼰的习惯或癖好对别⼈本该是⽆所谓的,但在团队合作中,有些时候,我们可能会不⾃觉地去维护,甚⾄推⼴这种习惯。这种 “不⾃觉” 的⾏为是值得我们警惕和反思的。
习惯形成
即使某种的习惯最后也许真的变成了⼤家认同的好⽅法,⼀开始也不该以个⼈的⽅式直接去强加于⼈。因为强加于⼈,总是容易带来分歧和争论,最终可能好习惯还没机会带来收益,却因为分歧争论直接带来了损失。
但编程中总结出来的⼀些⽅法和原则,很多可能就是始于个⼈习惯,最后逐渐传播并演化形成了普遍共识。
共识达成
⼀些 “编程智慧” 类的好⽅法,不太好形成具体的规范描述。下⾯,我就结合我⾃⼰的⼯作经历和经验,列举⼀些规范建议:
- 设计模式。遵守设计模式总是能让你少踩坑的,但如何灵活地采⽤合适的模式⼜是另⼀种智慧了。
- 术语约定。约定了术语,总是能让⼝头的概念和落在代码上的东⻄保持⼀致,减少沟通歧义,从⽽更⾼效。
- 单元测试。这⽐任何的代码评审都来得可靠,哪⾥该写多少测试⽤例,哪⾥可以不写,这⼜是智慧了。但不要刻意为了追求覆盖率⽽去写,覆盖率的技术统计⽅法其实是很唬⼈的,有些覆盖率很⾼的项⽬,该有的 Bug 还是有的。
- 随时重构。对于技术债务,每个⽉付点”利息”,⽐好⼏年后”连本带息”去还要感觉轻松得多。这条的特殊点在于,这可能是⼤部分程序员都认可的好⽅法,但却不是⼤部分⼈的习惯。因为技术上的债,实在⾃⼰还不起,总是可以推脱出去给下个”倒霉的家伙”,但从⻓远⻆度看,这样的推脱不会让你获得成⻓,甚⾄还会阻碍你的发展。
分辨反思
编程中除了好⽅法,还有些确实只是个⼈习惯的东⻄,如果我们不去留⼼区分,很容易模糊了两者的界限。
那⼤家都认同并形成共识的⽅法就⼀定能形成习惯吗?也未必,这需要我们去分辨和反思。
总结来说:
在你从程序新⼈成⻓起来的过程中,要学会区分,哪些确实是值得学习与推⼴的好⽅法,哪些仅仅是⾃⼰的个⼈习惯,特别是在你成⻓到开始成为技术管理者之后。
反过来看,程序⾏业,编程实践中,存在⼤量流⾏的概念、模式、原则,甚⾄哲学,它们的产⽣都有其历史背景和过程,并在⼀定范围内形成了共识。但你依然需要去对这些流⾏的共识进⾏分辨和反思,看看哪些才是适合你的好⽅法。若真是好⽅法,也可以进⼀步将其培养成⾃⼰的习惯。
30 | 写作:写字如编码
程序员群体有个共同的弱点,那就是写得了代码,解决得了问题,但却不能很好地展现⾃⼰的能⼒。从今天开始,咱们专栏即进⼊⼀个关于 “展现” 的主题,聊聊(写作、画图和演讲)三类最常⻅的展现⼿段。
其中,展现的最常⻅形式之⼀就是:写作,它是⼀种能随着时间去沉淀的⻓尾展现形式。
把每⼀篇⽂字当作⼀个需求,把写作当成在编码的过程去完成这个需求,它会⾮常类似于程序开发的整个过程,包括需求、设计、实现、测试和交付五个阶段。
需求
程序的需求,对应于写作的主题。
对于我来说,写作主题的来源可以有很多⽅⾯:有时,是来⾃身边的⼯作和⽣活中的事件引发的感触;有时,是阅读过程中突然产⽣的启发与领悟;有时,则是曾经⼀直困惑的问题突然碰到或找到了答案……这些都属于灵感乍现的时刻,也是我写作主题的来源。
但只是等到写的时候去灵光⼀现是很难保障持续写作的主题供应的,所以为了持续写作,我很多时候在⼤脑的潜意识⾥都会考虑主题的问题,等有了灵光⼀闪的时刻,就随时记录下来,形成⼀个主题列表。这个主题列表,就有些像产品的需求特性列表了,呆在需求池⾥等待被 “实现”,也即,”写出来”。
随⼿记录的主题可能很多,但真正能写的时间和精⼒却有限,因此你得挑选值得写的主题。如果把每⼀篇⽂字想象成⼀件产品,那么定义写作的主题,就像定义产品的灵魂,你得确定⼀个产品的⽬标、定位,以及⾯向的读者⼈群。
⼀个好的主题很可能是⼀篇好⽂字的开端,毕竟如果⼀开始产品⽅向错了,实现得再好⼜能有多⼤意义呢?
设计
程序开发的设计⼀般分为两个层⾯:
概要设计
在软件程序系统的设计中,这部分内容主要是架构设计,系统或⼦系统的拆分、交互逻辑、边界等等。⽽对于写作⽽⾔,这部分对应的就是设计本篇⽂字的逻辑结构,换⾔之,即在主题确定的基础上,采⽤怎样的逻辑去展开主题,形成合适的衔接。
⽐如,我写的⽂章多为随笔散⽂类,⽽散⽂的结构,上过中学语⽂课的我们都知道:形散⽽神不散。其中的 “神”,就包括了⽂章的核⼼主题观点,以及围绕主题展开的逻辑结构、⽂字附着的延展线条等。
详细设计
有了逻辑⻣架后,就需要补充真正有⾎有⾁的⽂字了。
围绕主题想表达的观点,考虑需要添加哪些⽀撑观点的素材,以及设计整理、引出和排布这些素材的⽅式。⽽为了让⽂字更有阅读的趣味,还需要有适当的故事,因为⼈们都喜欢读故事,⽽⾮说教,那故事⼜该如何切⼊与布局?这也是需要考虑的点。
另外,这些素材或故事⼜从哪⾥来?只能来⾃平时的阅读积累。⼤部分我们读过的东⻄很快就会被遗忘,所以为了在需要的时候找到合适的内容,就需要在平时的阅读时记录笔记,留下索引,必要时再根据笔记索引的关键词去搜索。
实现
写⽂字和编码在实现层⾯最⼤的差异是:实现过程的技能和要求不同。
在实现技能层⾯,程序是⽤计算机语⾔来表达的,⽂字是⽤⾃然语⾔来表达的。计算机语⾔的逻辑性和精确表达能⼒要⽐⾃然语⾔强得多,⾃然语⾔是模糊的、混沌的、不精确的。因此写得⼀⼿好程序的⼈,不⼀定能写得⼀⼿好⽂字,因为他们需要驾驭的语⾔的特性完全不同。
测试
每次写完⼀篇⽂章后,就感觉⾃⼰好像是被清空了,甚⾄不再想去读⼀遍,这时我就会把它”扔”在⼀边。
写作的过程中,⼤脑从冷的状态逐步升温,直到进⼊⼀种很热的状态,⽂字就是在这样的状态下⾃然流淌出来的。直到写完之前,⼤脑⼀直在⾼速运作,就像⼀颗 100% 利⽤率的 CPU,它的温度很⾼。写完后,CPU 终于降低了负载,但温度的降低还需要⼀个过程。
⽽对写完的⽂字再读⼀遍,进⾏再编辑和优化,这就像软件开发中的测试过程。但我需要在⼀个冷却的状态下进⾏,站在⼀个读者或编者的视⻆去重新审视这篇⽂章。所以,这个过程通常发⽣在写作完成后的⼀天或⼏天之后。这中间的间隔,我称之为写作后的冷却时间。只有在冷却的状态下,我才能更客观地检视⾃⼰写的⽂字,同时进⾏合适地编辑和修改,这个过程就是对⽂字的测试。
交付
交付,就是发布这篇新写的⽂字,让它⾯对读者,获得反馈与验证价值。
写作与⽂字的价值实现分两部分,写完后就完成了对⾃我的价值实现,⽽交付后才算完成了对他⼈的价值实现。
31 | 画图:一图胜千言
能不能画好图和⼯具的关系并不⼤。
为何?
程序员不是主要写代码的么,为什么需要画图?
有些程序员会认为写好代码就好,画好图有什么⽤?程序员成为架构师后是不是就天天画架构图,成为了所谓的 PPT 架构师?曾经读过⼀篇⽂章《在⾸席架构师眼⾥,架构的本质是…》,⾥⾯提出了⼀个架构师能⼒模型图,(我重新绘制)如下:
结合我⾃⼰的经历和经验,这个能⼒模型针对架构师这个岗位来说还是⽐较符合的。程序员出⾊到了⼀定程度后想成⻓为⼀名架构师,就需要看看能⼒模型中的其他⽅⾯。⽽掌握好画图技法,对这个能⼒模型有什么帮助吗?
前⾯讲系统设计的⽂章《多维与视图》中我已经给出过结论:”⽤更系统化的视图去观察和思考,想必也会让你得到更成体系化的系统设计。”
⽽画图对于能⼒模型中的 “抽象思维” 就起到了⼀种锻炼,其作⽤就是帮助你在不同的层次上去思考系统设计,并具象化这个设计。既然具象化了设计,那么再基于此去沟通交流⾃是事半功倍。成为架构师之后,你⾃⼰明⽩还不是主要的,要让别⼈明⽩才更重要。
此外,站在⼀个多层次、全⽅位的系统架构图⾯前,在不同抽象维度上描绘了系统的各个重要⽅⾯,想必更容易看到问题的本质,也能更好地发现和找到系统的症结。如果解决系统的问题就像⾛迷宫,那么你是直接钻进去反复尝试寻找出路,还是站在更⾼的维度去俯视迷宫然后再找最佳的问题解决路径呢?
想必在更宏观和全局的视野下,与系统所有相关⼈员进⾏清晰准确地交流,直击问题本质,那么再进⾏正确⽽适当的技术决策与平衡取舍也没那么难了,对吧?⾄于 “多领域知识” 和 “技术前瞻性” 这两⽅⾯好像确实和画图的关联性不强,但如果”多领域知识”不限于程序技术领域,那画图也算⼀个领域的知识吧。
如何?
⼀些基本认知和感觉还不错的实践⽅式。
图形
我画技术图例时只会使⽤⼀些最基础的图形,⽐如:矩形、圆、三⻆、菱形、⽓泡、箭头,这些最基本的图形⼏乎所有的画图软件都会⾃带的,所以⼯具的依赖性很低,但真正画时的操作效率却⼜很⾼。
当然,⼀些著名外部系统可能都有各⾃知名的 Logo 图标,如果有时为了表达和这些著名外部系统间的交互,也会直接使⽤它们的 Logo 图标。如下⾯图示,就是我常⽤的⼀些画图图形元素。
颜⾊
使⽤⼤部分⼈觉得美的颜⾊。那⼤部分⼈觉得美的颜⾊是什么呢?彩虹⾊,当然这⼀点也我没有做过专⻔调查,只是凭经验得来。所以我⼀般⽤的颜⾊就是彩虹七⾊,外加两种经典⾊:⿊、⽩。这样就有九种颜⾊加上好⼏种基本图形,可以组合出⼏⼗种表达不同组件的图形元素,基本也就够⽤了。
彩虹七⾊包括:红、橙、⻩、绿、⻘、蓝、紫。但七种颜⾊的选择也是有优先级,在⼀本讲设计的书中 Designing with theMind in Mind(中⽂译本《认知与设计》)提出了下⾯⼀些⾊彩使⽤准则:
- 使⽤饱和度、亮度以及⾊相区分颜⾊,确保颜⾊的⾼反差,因为⼈的视觉是为边缘反差⽽优化的。
- 使⽤独特的颜⾊,因为⼈最容易区分的颜⾊包括:红、绿、⻩、蓝、⽩和⿊。
- 避免使⽤⾊盲⽆法区分的颜⾊对,⽐如:深红-⿊,深红-深绿,蓝⾊-紫⾊,浅绿-⽩⾊。
- 使⽤颜⾊之外的其他提示,对有颜⾊视觉障碍的⼈友好,⽽且也增强了可理解性。
避免强烈的对抗⾊,⽐如:红⿊,⻩⿊。
当然红有好多种红,绿有好多种绿,该⽤哪种呢?看下图所示,给出了 RGB 三原⾊的配⾊数值,这属于个⼈偏好,在 Mac的显示器下看起来很舒服。但若⽤在其他场合,⽐如投影什么的,就可能需要根据投影实际效果进⾏微调了。
审美
审美对最终的效果呈现有很⼤影响,这得感谢苹果总设计师乔纳森·伊夫(Jonathan Ive)把⼤众的审美倾向全部带⼊到扁平化时代,所以实际中我只需要把图形弄得扁平,去掉⽴体、阴影什么的,看起来就还不错了。
⼏何?
“⼏何” 不是数学⾥的⼏何,⽽是掌握画图技法到底代价⼏何?⼜价值⼏何呢?
学会使⽤⼀种简单的软件,使⽤简单的图形和配⾊,在最有效率的情况下画出⼀幅效果还不错的图例,也是很有价值的。
当然你可能会认为只有写出的代码才有价值,其实这⾥你可能忽视了⼀个⼤部分程序员都认同的观点:代码也是写给⼈看的。程序员不会认为⼀份机器能运⾏⽽⼈很难看懂的代码是好代码,⽽画好图就能更好地帮助你去思考代码的组织和呈现⽅式。
32 | 演讲:表达的技术
我确实有⽐较系统地思考和琢磨过演讲的价值、效果以及提升的⽅法,现在我将其分享给你,希望能对你的成⻓或者职业道路有所帮助。
价值与效果
写作的展现,是⼀种⼴度路线,产⽣间接、⻓尾效应;演讲的展现,是⼀种深度路线,产⽣直接、深度连接。
为什么说写作是⼴度⽽演讲是深度的?过去⼏年,我读过很多的⽂章、书,但还能记得住只⾔⽚语的都⾮常少。即使当时⼀些给我⾮常多启发与触动的⽂字,如今也只能记得当时触动的感觉,却忘了触动的内容。但好些年前,我参加过⼏次⾏业⼤会,有那么⼏场演讲,现在回想起来,不仅记得当时深受启发的触动感,甚⾄还能记得当时的内容。
这就是演讲带来的深度效应,它的现场感更⽴体,有助于留下更深刻的记忆,持续发挥影响的时间也超过了⽂字。
演讲的现场⽴体感带来的深度效应,也只能留在现场。即使我们把整个演讲过程录制成为视频,观看视频的过程也会损失很⼤⼀部分深度影响⼒,也许这就是为什么有⼈会去看现场演唱会的原因。
所以,演讲的最⼤价值就在于这样的深度效应。但现场感并不⼀定带来深度影响,也可能是把⼈ “催眠” 了。那如何发挥好演讲的效果呢?这⾥我就先谈谈我⾃⼰的⼀些经历和感悟。
经历与感悟
成⻓路上,终究会遇上演讲;从没遇上演讲的程序员,可能天花板就会⽐较低。
准备与发挥
⼀场演讲,包括前期准备和现场发挥两个阶段,⽽前期充分的准备是现场良好发挥的基础。
那前期可以准备的内容有哪些?我梳理了有如下维度:
框架
演讲的框架和程序的架构有点类似,⼀般我都从下⾯⼏个⽅⾯来设计:
- ⽬标:本次演讲需要达成的⽬标是什么?
- 听众:本次演讲的受众是哪些⼈?
重点:本次演讲要传递的关键点有哪些?
那么⼀场技术分享的框架线,可能有如下:
引出主题:结合⽬标与听众来确定。
- ⾃我介绍:让听众了解你,证明你有资格讲这个主题。
- 重点结构:每⼀个关键点的分析、讲解,可以从以下⽅⾯来拆解。
- 问题:这个点上存在什么问题?
- 历史:这个问题的历史由来是什么?
- ⽅法:你是⽤什么⽅法解决这个问题的?
- 原因:为什么要⽤这个⽅法,要在这个阶段,以及这样解决问题?
- 细节深⼊:有⼀定细节深⼊,更有说服⼒。
- 总结回顾:结束前的再次总结和提炼,以加深印象。
材料
在框架线清晰后,就进⼊了演讲材料的准备阶段。其中的材料包括三类:
第⼀类是幻灯⽚。到底要准备多少⻚的幻灯⽚?这个取决于框架线和演讲时⻓。但这⾥幻灯⽚的最⼤作⽤在于:
- 辅助演讲者的结构记忆与信息表达;
辅助听众的信息吸收、理解与消化。
也就是说,演讲的主⻆还是讲,⽽幻灯⽚仅仅是配⻆。
第⼆类是演讲稿。讲之前你可以先写下来你所要讲的内容,这样会有助于组织信息、梳理逻辑和提炼语⾔。
我们的正常语速⼤约是每分钟150~200个汉字,但在演讲的压⼒环境下,可能会出现不⾃觉地加速,⽆意识地跑偏,甚⾄语⽆伦次。如果想要提供更精确的信息传递和表达,那么演讲稿就是必需的。
第三类是⼩故事。⼈是情感动物,故事的影响效应远⾼于数据和逻辑,即使是在做技术分享时。
以前听过⼀些技术分享感觉⽐较枯燥、催眠,就在于技术基本都在讲逻辑、讲数据,听久了⾃然疲劳。⽽穿插⼀些 “⼩” 故事,则可以加深前⾯数据和逻辑的影响效应。这⼀点很多慈善募捐组织早就学会了,再⼤⽐例的穷困数据,也⽐不上⼀张⾐不蔽体的⼩⼥孩照⽚来得有效。
节奏
⼀段持续时间的演讲中,有没有⼀些关键的时间点呢?当然是有的。
⼀个是开场。据研究统计,⼀场演讲给⼈留下的印象和评价,开场的数秒⾄关重要。这可能和⼀开始是否能抓住听众的注意⼒有关。
另⼀个是峰终。管理界有⼀个 “峰终定律(Peak-End Rule)”:在 “峰” 和 “终” 时的体验,主宰了对⼀段体验好或者不好的感受,⽽在过程中好或不好体验的⽐重、时间⻓短,对记忆的感觉差不多没有影响。也就是说,如果在⼀段体验的⾼峰和结尾,你的体验是愉悦的,那么你对整个体验的感受就是愉悦的,即使这次体验总体来看,更多是⽆聊和乏味的时刻。
峰终定律,在管理上决定了⽤户体验的资源投⼊分布,只需要重点投⼊设计好 “峰终” 体验。⽽演讲,也是⼀⻔体验艺术,它的 “峰” 前⾯说了⼀处——开场(抓注意⼒);另⼀处,可能是中间某⼀处关键点(提供独特的⾼价值内容或观点)。
表演
演,即表演和发挥;表演的准备,有三个层级,如下图(原图来⾃ Tim Urban’s Memorization Spectrum,翻译后重绘制):即兴发挥、框架内发挥和严格遵从剧本。
做了前述准备的演讲,算是在框架内发挥。如果还准备了演讲稿,那么练习熟练后,基本算是接近了 3A 这个层级,但演讲稿,还算不上是剧本,所以只是接近。按 3 这个层级的准备,是把演讲当作了⼀出舞台剧,有严格的剧本,需要经过反复地排演练习。
演讲,本是表达的艺术,但对程序员的要求远没到艺术的层次;先能表达,再求精确,技术达标,⾜矣。
33 | 定义:阶梯与级别
从今天开始,咱们专栏会开启⼀个⼤家可能都⽐较感兴趣的主题:程序员的职场阶梯,以及攀登阶梯的晋升博弈。
腾讯的 5 个⼤级别与我⾃⼰⼀路⾛来经历的⼏个阶段感觉会⽐较匹配⼀些,⽽⼤级别之间的分界线也会更明显⼀些。我对升级阶梯的定义也是 5 个:初级、中级、⾼级、资深和专家。
⾄于对不同级别的定义,我选择了三个相对容易判断的维度:
- 具备什么能⼒?
- 解决什么问题?
- 产⽣多⼤影响?
初级
初级,多属于刚⼊职场的新⼈。
这个级别基本完成的都是螺丝钉级别的⼯作,影响很有限。但如果从这个阶段你就开始定期归纳总结这些局部的⼯作经验,不断优化⼯作内容,并能在团队⼩组内部做出分享,甚⾄帮助其他同学解决问题,那就说明你已经⾛上了⼀条快速成⻓的通道。
中级
中级,相对初级最⼤的质变在于:独⽴性。
初级同学经过两三年⼯作历练,对实现各种业务功能、开发规范流程都很熟练了,摆脱了对基本指导的依赖性,这时就进⼊了中级阶段。中级⼯程师已经能够独⽴承担开发任务,设计实现他们负责的系统模块,以及通过搜集有效信息、资料和汲取过往经验来解决⾃⼰⼯作范围内遇到的问题。
中级这个层⾯的基本要求就是:完成动作、达成品质和优化效率,属于公司 “动作执⾏” 层⾯的中坚⼒量。观察下来,这个级别的⼯程师多数都能做到完成,但品质可能有瑕疵,效率上甚⾄也有很多⽆效耗散。不过,效率和品质总是在不断的迭代中去完善,⾃身也会在这个过程中不断成⻓并向着下⼀个阶梯迈进。
不少同学卡在这⼀阶段,就是因为虽然不断在完成⼯作,但却没有去反思、沉淀、迭代并改进,从⽽导致⾃⼰⼀直停留在了不断的重复中。所以,在⼯作中要保持迭代与改进,并把你的经验分享给新来的初级同学,这样在未来之路你不仅会⾛得更快,⽽且也可能⾛得更轻松。
⾼级
⾼级,不仅要能独⽴完成⼯作,还要能独⽴负责。他们能独⽴负责⼀个⼤系统中的⼦系统或服务,并成为团队⻣⼲或最重要的个⼈贡献者。
相⽐于中级,⾼级⼯程师在 “动作执⾏” 层⾯,不仅能独⽴完成⾼级难度的开发任务,⽽且在⽤户体验(品质提升)和性能优化(优化效率)⽅⾯还都能做出更全⾯的考量。也就是说,他们不仅仅可以把开发任务完成得⼜快⼜好,⽽且还能清晰地定义出多快、多好。⽐如,⼀个服务的响应时间 99.9% 是在 20 毫秒内,内存消耗最⼤不超过 1G,并发吞吐量 10000+/s,类似能⽤清晰的数据来定义服务品质和效率。
另外,⾼级别需要⾯对的问题就不再是单⼀维度的技术问题了,他们需要结合业务特性去考虑设计合理的解决⽅案。熟悉业务领域内的应⽤系统架构以及各个部分使⽤的技术,能根据业务特性,合理进⾏分层设计,实现⾼效率、低成本的运维或运营。
初、中级别的能⼒提升与影响输出是通过经验的归纳总结与分享,那么⾼级则需要在经验这种偏个体特性的基础上,再进⾏抽象提炼,沉淀⽅法论。换⾔之,通过个⼈的经验,研究⾏业的优秀实践,再结合⾃身实践和逻辑推导,沉淀出切合现实的⽅法论,并在团队内部推⼴应⽤。
资深
资深,有深度和资历(即⼴度)两个层⾯,对应到职业⽣涯路线上,也有两个⽅向。
- 资深⼯程师
架构师
在偏基础研发、算法和特定技术复杂领域,会向 “资深⼯程师” ⽅向发展,属于深度优先。⽽在⾯向业务开发的领域,业务复杂度⾼于技术复杂度,则会向 “架构师” ⽅向发展,属于⼴度优先。
但⽆论深度还是⼴度,进⼊这个级别即说明你在特定领域都已经具备了相当的积累。这时你是作为相关领域的专家,深度参与和⽀持团队项⽬,在领域内进⾏关键的技术判断和决策,进⽽帮助团队项⽬或产品加速成功。在这个层次上,你⾯临的都是⼀些更复杂的、具备⼀些灰度(不是⾮此即彼,⽽是需要折中权衡)特性的问题,这时就需要你能够全⽅位、多层次、多⻆度地深⼊理解问题,评估每种⽅案的收益、成本和潜在未来的⻓短期影响等。
这个层次的影响⽅⾯,除了经验分享和⽅法论沉淀,还有产品和团队两个考虑维度:即使是做纯技术的东⻄,最终的影响也是通过技术产品来完成的;⽽另⼀⽅⾯则是团队的梯队建设、结构调整与协作优化,决定了团队外在表现。这两个维度,前者可能资深⽅向侧重多⼀些,后者则是架构师⽅向需要侧重思考实践的。
专家
专家,表明了某种领域的明确建⽴。
也许架构师和资深⼯程师也具备在特定细分技术领域的深厚积累,说明他们和专家⼀样也有属于⾃⼰的领域,但这个领域还不算明确建⽴,它还需要有公认的影响⼒。公认影响⼒实际指⼀个范围,如果是公司的技术专家,那么范围就是公司或⾏业。
34 | 晋升:评定与博弈
晋升的结果和个⼈利益有直接的绑定关系,⽽且这个过程从来都不是⼀个简单的是和否的选择,那你该如何看待这个”不简单”的晋升过程呢?
标准维度
先站在评定者的⻆度,假设你作为⼀名评委,你会如何去评定?⼜有怎样的标准呢?
技术晋升评定是依赖⼈的判断,本是⾮常主观的⼀个过程,但为了规避这种过于”拍脑袋”的主观性,就需要去制定标准。制定标准的初衷也是为了给评定过程增加客观性,将⼈的主观判断约束在⼀定的客观范围内。
我在参考了⼀些⾏业⾥⼤公司的晋升和技术素质模型,并结合当时团队的具体现状,制定了出了⼀些标准维度:
- 通⽤能⼒,包括学习能⼒、沟通能⼒和领导能⼒等;
- 业务能⼒,包括业务理解和领域建模等;
- 技术能⼒,包括深度、⼴度和技能应⽤等;
影响⼒,如知识总结、知识传承和⼈才培养。
除以上 4 个⼤维度外,还有⼀项 “⼯作业绩” ,不属于现场技术评定的维度,直接来源于过去⼀年的⼯作业绩评价。每个⼤维度会占据⼀定的⽐重,然后可以针对每个⼤维度去打分。
虽然有了客观的标准维度去细分判断,但⼈打分在细微之处依然会有主观的偏好。
过程识别
晋升识别过程是⼀条链路,⽽技术标准评定只是其中的⼀个环节。
晋升过程启动⼀般由 HR 部⻔驱动发起,经过各个部⻔直属领导提报候选⼈,再经由技术委员会进⾏专业线评定,再去到管理层复议,最后⼜回到 HR 部⻔最终确定。
第⼀个环节,HR 部⻔的责任是对提报候选⼈进⾏晋升资格确认。第⼆个环节,部⻔从满⾜资格的员⼯中进⾏提报,部⻔的作⽤是对提报员⼯过去⼀年在本部⻔⼯作绩效的认可;第三个环节,就进⼊了技术委员会组织的专业线技术评定,⽽通过技术标准评定后,是对其专业综合能⼒的认可。
最后,就进⼊到管理层复议环节,这个环节会有⼀个冲突点存在。公司每年的晋升名额也是有限的。⼀般公司每年的晋升名额都会有⼀个⽐例限制,这是出于控制成本与优化⼈才结构的考虑,因⽽经过前⾯的环节,最后到达这⾥的⼈数可能多于这个名额。所以,管理层复议其实就是对最后多出来的⼈数,综合考虑整体和局部的利益,进⾏调节筛选。
了解了评定的标准和过程,就可以反过来站在晋升者的⻆度想想,如何才能更有效地被识别出来?
晋升述职过程仅仅只有 10 到 20 分钟,即使采⽤了前⾯所述的标准维度,晋升述职者也只能在有限的时间内把过去⼀、两年的⼯作成果、能⼒成⻓展示在⼏个点的范围内。这对于评定者来说,就像在管中窥豹了,看不到全貌,看完⼏个展示的特征点后就需要判断这到底是 “豹⼦”(符合下⼀级别的晋升标准)还是 “猫”(不符合)。
我在做晋升评委时,就⼀直被这样的判断所困扰,多数述职同事都在这⼏个点上表现得很好。这就像是说,如果是豹⼦,它确实该有这些特征点,反过来,拥有这些特征点的就⼀定就是豹⼦么?这些特征点,是豹⼦的唯⼀或⾜够有区分度的标志性特征吗?
我发现靠 “点” 上的判断,准确度⾃⼰其实也完全没把握,后来就想到了⼀种更好的⽅式,靠 “域” 的判断。域,即领域,包含了:责任域和能⼒域。能⼒和责任总是相辅相成的。
责任域,就是你负责什么,这个相对容易识别。⽽能⼒域则过于抽象,很难清晰识别,在述职这样的形式中,最容易判断的仅仅是表达和沟通能⼒;⾄于业务和技术能⼒,虽不那么容易判断,但好在其有最好的展现形式:作品。
对于程序员,作品可以是⼀个完整的系统,但其展现不应该是⼀系列的技术点,⽽是先有整体(⾯),再深⼊局部(点),应该是⼀个画⻰点睛的过程。从这样的展现过程中就能很好地体现出晋升者的业务与技术能⼒。
识别的过程,本质是在解⼀个概率问题,当参与这个过程的两⽅(评定者和晋升者)都这样努⼒去考虑时,我想这样的过程就会有更⾼的准确率。
博弈权衡
晋升过程因为涉及太多个⼈的利益,所以评定过程的公平性是所有参与⽅都关⼼的问题。
晋升的本质是承担更⼤的责任,⽽责任和能⼒是需要匹配的,晋升就是完成这样⼀种匹配关系的过程。⼀个公司中的责任域是有限的、发展的、变化的,那你当下具备的能⼒域是否匹配相应的责任域?你正在学习和开发的新能⼒域,是否能在组织中匹配上合适的责任域?这才是看待职场阶梯与晋升的正确⽅式。
保持不断学习和提升能⼒,找到并承担起合适的责任域,那么后续的晋升并贴上⼀个相应的职级标签,就是⼀件⾃然⽽然的事情了。
35 | 关系:学徒与导师
现在很多公司都有⼀种带新⼈的导师(Mentor)制度,导师制的初衷是为了帮助新员⼯快速熟悉公司环境,并提供⼯作技能和个⼈成⻓的帮助,正所谓 “传帮带”。
这是⽤制度建⽴并约束了⼀种在新、⽼员⼯之间的关系,这本是⼀个很好的出发点。但想要类似这样的制度关系发挥期望的作⽤,恐怕就需要 “导师” 和 “学徒” 都有⼀个更⾼层次的清晰认知,毕竟制度只能在其中起到催化的作⽤。
起源
导师制诞⽣于⼗四世纪,那时的年轻男⼥们可以⽤⾃⼰最富余的资产——时间,去交换当时最稀缺的资源——培训。在那个时代,经验丰富的⼿艺⼈,⽐如,铁匠、鞋匠、⽊匠等,他们指导这些年轻⼈,并承诺将来某天年轻⼈能学会他们的技能然后去开创属于⾃⼰的事业。作为交换,年轻⼈会提供低成本且廉价的劳动⼒。
导师
有经验的程序员、⽼员⼯,站在 “导师” 的视⻆,会如何看待这样的关系呢?
从某种意义上来讲,经验丰富的程序员,就和中世纪的⽼师傅⼀样,他们经历了⼤量的时间犯过⼤量的错误,积累了很多难以⾔说的经验价值。他们已经经历过你所犯的错误,已然能够轻松应对如今让你痛苦和头疼的问题,所以他们具有能够引导你迈向正确⽅向的潜能。
但反过来想,他们为什么要指导你?只是因为公司有个导师制,并安排了他成为你的导师?那么这样的指导通常也就变成了上⾯那种场景。为什么他们要牺牲⾃⼰的⼯作时间,甚⾄私⼈时间来⽆私地指导你?也许作为新同学的你,甚⾄包括制度的制定者本身,可能也没从这个⻆度来看待该问题。
职场导师制,如果公司没有相应⾜够的考核、评价和激励制度⽀撑,那么这种师徒关系实际上没有任何约束,完全靠运⽓、投缘之类的。站在导师的⻆度,对于凑巧碰到的⼀个职场新⼈,他有什么样的利益或情感驱动要去更积极地做这件事呢?其实最直接的,还是由对⽅的态度和⾏动来驱动的。
学徒
反过来,站在 “学徒” 的视⻆,该如何看待这样的关系?万维钢有篇⽂章叫《给前辈铺路的⼈》说得很有现实意义:
给⼈当学徒,就给你提供了这个机会。你现在把⾃⼰和⼀个⾼⼿连接在了⼀起,你可以从内部了解第⼀⼿的经验。这就是学徒⼯作的协议:⽤礼敬和服务,换取机会——⽽这个机会还不是⽴功露脸的机会,⽽是学习实践的机会。
机会,就是得到更快的成⻓与发展。从导师多年积累的经验中获益,能够缩短获得这些知识经验的时间,并且避免重复错误。但这⾥⾯可能还有个障碍,就是⾃尊⼼的问题,态度不够谦虚,那么也许是性格还需磨练。如果态度谦虚,双⽅都投⼊了适当的时间和精⼒,那么导师当年花了⼗数年才学会或领悟到的东⻄,学徒也许只⽤短短⼏年就能学到,绕过了没必要的重复路线。
从学徒⽅⾯来说,必要的、简单的、低技术含量或重复性的⼯作也是必须的,不应该被认为是⼀种浪费或牺牲。当你在免费获得⼤量的知识和帮助的同时,却抱怨时间投⼊太多,或者时间不够,其实是短视的。因为:
当你给⼈铺路的时候,你实际上也在左右他的前进⽅向。
关系
现实中,对于师徒关系,会有⼈有这样的疑问:”教会徒弟,会饿死师傅吗?”也许中世纪时期的师徒关系会有这样的担忧,但如今这个信息时代,知识根本不稀缺,也没有所谓的 “⼀招鲜,吃遍天” 的绝招。反过来说,带好了徒弟,接⼿并取代了你当前正在做的事情,你才有可能解放出来去做更⾼层次和更⼤维度的事情。
⽽作为学徒,你需要吸取德⾥克的经验:学习和成⻓是⾃⼰的事,严肃待之,⾏动起来,⾃助者,⼈亦助之。
36 | 核心:安全与效率——工程技术的两个核心维度
在”修⾏:由术⼊道“模块的最后⼀个主题,我们聊聊⼯程,不是具体的⼯程的技术,⽽是抽象的⼯程之道。
做了很多年的⼯程,开发了各种各样的系统,写了⽆数的代码,说起这⼀切,我们都在谈些什么?
我们谈过程,从需求⼯程到开发流程,从编码规范到同⾏评审,从持续集成到⾃动部署,从敏捷开发到极限编程;我们谈架构,从企业级到互联⽹,从⾯向服务架构(SOA)到微服务架构(Microservice);我们谈复杂性,从⾼并发到⾼性能,从⾼可⽤到⾼可靠,从⼤数据到⼤容量。
那么对于这⼀切,你感觉这⾥⾯的核⼼是什么?
核⼼
核⼼,意味着最重要的,⼀切复杂的⼯程技术⽅案都是围绕着它来运转。
⼀个电⼒⾏业的故事。
记得有个给我们上课的主讲⽼师是个须发皆⽩的⽼先⽣,进⻔后掏出⼀堆零件放在讲台上。⼀盏酒精灯、⼀个⼩⽔壶、⼀个叶⽚、⼀个铜光闪闪的⼩电机、⼀个⼩灯泡。⽼先⽣往壶⾥倒了些⽔,点燃酒精灯,不⼀会⼉⽔开了,从壶嘴⾥喷出了蒸汽,带动叶⽚旋转,然后⼩灯泡就亮了。
⽼先⽣说:”这就是电⼚。如果烧的是煤炭,这就是燃煤电⼚;如果烧的天然⽓,这就是燃⽓电⼚;如果获得热能的⽅式是核裂变,这就是核电⼚;如果带动叶⽚的能量来⾃从⾼处流向低处的⽔流,这就是⽔电⼚。”
“你们或许会问:那我们看到的电站怎么这么复杂?答案其实很简单,电站需要复杂系统的⽬的:⼀是为了确保安全(Safety),⼆是为了提⾼效率(Efficiency)。安全与效率的平衡,是所有⼯程技术的核⼼。”
听完这个故事,我觉着所谓 “⼤道⾄简” ⼤概就是这样的感觉了。
安全
安全,之于信息⼯程技术领域,包括了 “狭义” 和 “⼴义” 两个⽅⾯的安全范畴。如下图所示:
狭义的安全,就是传统信息安全领域的 “安全攻防” 范畴。⽐如,客户端的跨站脚本攻击(XSS)、服务端数据库的 SQL 注⼊、代码漏洞以及针对服务可⽤性的拒绝服务攻击(DDoS)等。这个⽅⾯的 “安全” 含义是信息技术⾏业独有的,但前⾯电站例⼦中指的 “安全” 更多是 “⼴义” 层⾯的。
在程序技术上的 “⼴义” 安全范畴,我划分了三个⽅⾯:
- 安全开发,就是为了保障交付的程序代码是⾼质量、低 Bug 率、⽆漏洞的。从开发流程、编码规范到代码评审、单元测试等,都是为了保障开发过程中的 “安全”。
- 安全运维,就是为了保障程序系统在线上的变化过程中不出意外,⽆故障。但⽆故障是个理想状态,现实中总会有故障产⽣,当其发⽣时最好是对⽤户⽆感知或影响范围有限的。
- 安全运⾏,就是为了应对 “峰值” 等极端或异常运⾏状态,提供⾼可靠和⾼可⽤的服务能⼒。
效率
效率,从程序系统的⻆度看,同样也是从 “开发””运维” 和 “运⾏” 三个⽅⾯来考虑。如下图所示:
开发效率,可以从 “个体” 和 “群体” 两个⽅⾯来看。
个体,就是程序员个⼈了,其开发效率除了受⾃身代码设计与编写能⼒的影响,同时还要看其利⽤⼯具的⽔平。更好的源码管理⼯具与技巧可以避免⽆谓的冲突与混乱;代码模板与开发框架能⼤幅度提升代码产出效率;⽽持续集成⼯具体系则能有助于快速推进代码进⼊可测试状态。
群体,就是⼀个团队,其开发效率最⼤的限制经常是架构导致的。如果你在⼀个⼯程项⽬上写过⼏年代码后,多半会碰到这样⼀种场景,代码库越来越⼤,⽽功能越改越困难。明明感觉是⼀个⼩功能变化,也要改上好⼏天,再测上好⼏天,这通常都是架构的问题,导致了团队群体开发效率的下降。
以后端服务架构技术演进的变化为例,从单体应⽤到⾯向服务架构思想,再到如今已成主流的微服务架构实践,它最⼤的作⽤在于有利于⼤规模开发团队的并⾏化开发,从⽽提升了团队整体的效率。理想情况下,每个微服务的代码库都不⼤,变化锁闭在每个服务内部,不会影响其他服务。
运维效率,可以从 “检查””诊断” 和 “处理” 三个⽅⾯来看。
⼀个运⾏的系统,是⼀个有⽣命⼒的系统,并有其⽣命周期。在其⽣命周期内,我们需要定期去做检查,以得到系统的 “⽣命体征” 的多维度信息数据汇总,以供后续的诊断分析。
准确地诊断之后,才能进⾏合适地处理。和治病不同,⼤部分的故障都可以通过常⻅的处理⼿段解决,极少存在所谓的 “不治之症”。⽽常⻅的线上处理⼿段有如下三类。
- 恢复:重启或隔离来清除故障、恢复服务;
- 变更:修改配置或回滚程序版本;
- 限制:故障断路或过载限流。
运⾏效率,关键就是提⾼程序的 “响应性”,若是服务还包括其 “吞吐量”。
程序运⾏的⾼效率,也即⾼响应、⾼吞吐能⼒,所有的优化⼿段都可以从下⾯两个维度来分类:
- 更多
更快
负载均衡器让更多的机器或进程参与服务,并⾏算法策略让更多的线程同步执⾏。异步化、⽆锁化和⾮阻塞的算法策略让程序执⾏得更快,缓存与缓冲让数据的读写更快。
37 | 过程:规模与协作——规模化的过程方法
⼯业级规模化的程序系统开发包括了⼀系列的过程,⽽这⼀系列过程的起点是:需求。
需求与调度
需求,有时会有很多不同的表达形式,包括:客户的诉求、⽤户的请求、⽼板的要求,但这些不同的表达形式,不⼀定是真正的需求。
如何对过多的需求进⾏排序?可以学习、借鉴下操作系统的资源调度策略。
- 先来先执⾏
- 执⾏起来最快的先执⾏
- 占⽤资源最少的先执⾏
- 释放资源最多的先执⾏
⾼优先级的先执⾏
为什么需要排序?
- 最⼤化⽤户、客户和⽼板的整体满意度;
- 最⼤化价值与产出,让最多的资源投⼊到最有价值的需求上。
设计与开发
规模化的设计思路,⼀⽅⾯是⾃顶向下去完成顶层设计。顶层设计主要做两件事:
- ⼀是去建⽴系统的边界。系统提供什么?不提供什么?以怎样的形式提供?
⼆是去划定系统的区域。也就是系统的层次与划分,以及它们之间的通信路径。
⽽系统的区域划分,也是为了让系统内部各部分之间的耦合降低,从⽽让开发⼈员在属于⾃⼰的区域内更⾃由地发挥。
规模化设计思路的另⼀⾯,就是要让系统具备⾃底向上的演化机能。因为,⾃顶向下的设计是前瞻性的设计,但没有⼈能做到完美的前瞻性设计;⽽⾃底向上的演化机能,是后验性的反应,它能调整修复前瞻性设计中可能的盲点缺陷。
⼀个规模化的系统既要靠前瞻的设计视野,也依赖后验的演化机能,这样才可能将前瞻蓝图变成美好现实。
测试与运维
以测试为例进⾏规模化的最佳⽅式,就是打造⼀条 “测试机器” 流⽔线,⽽我在《转化:能⼒与输出》⼀⽂中写到了关于打造 “机器” 的三个核⼼点,这⾥再强调⼀次:
- 流程规则
- ⼯具系统
规范共识
围绕这三个核⼼点,我们再来看看 “测试机器” 如何打造?
从开发提测,机器⾃动下载提测版本分⽀代码,进⾏构建编译打包,实施代码规范性检查测试,通过后发布测试环境,进⾏分层次的各类⾃动化专项测试。如:⽤户终端层、通信协议层、服务接⼝层、数据存储层的各项测试,全部通过后,⽣成相应的测试报告,进⼊下⼀步发布流程。这就是测试体系的”流程”,⽽”规则”就是其中定义的各种测试项检查约束。
上述流程中涉及的”⼯具系统”包括:代码规范检查⼯具、终端 UI 的⾃动化测试⼯具、通信协议与服务端接⼝调⽤的模拟⼯具、数据⼀致性校验⼯具、测试报告⽣成⼯具、测试 Bug 统计分析与收敛趋势等可视化展现⼯具,等等。
最后,”规范共识” 是整个团队对这个流程环节、⾥⾯具体规则的定义以及 Bug 分类等⽅⾯达成的共识,这决定了这台 “测试机器” 运转的协调性与效率。
测试通过后,发布到线上就进⼊了运维阶段,⾏业⾥已经有⼤量的关于 DevOps 的分享内容,⽽它的本质也就是打造了⼀台”运维机器” 流⽔线,这和我上⾯描述的 “测试机器” 运转类同,只是有不同的规范共识、流程规则和⼯具系统,便不再赘述了。
到了规模化的测试与运维阶段,看⼀个团队的⽔平,就是看这台 “机器” 的制作⽔准与运转效率。
38 | 思维:科学与系统——两类问题的两种思维解法
写了多年代码,做了好多的⼯程,不停地完成项⽬,但如果你⼀直仅仅停留在重复这个过程,那么就不会得到真正的成⻓与提
⾼。你得从这些重复做⼯程的过程中,抽象提炼出真正解决问题的⼯程思维,⽤来指导未来的⼯程实践。
⼯程思维:⼀种具备科学理论⽀撑,并成体系的系统化思维。
做了多年的软件开发⼯程,碰到和解决了数不清的问题,最终这些问题,我发现稍微抽象⼀下,可以归为以下两类:
- 可以简单归因的问题:属于直接简单的因果关系;
- 难以简单归因的问题:属于间接复杂的因果关系。
上⾯的描述可能有点抽象,那具体该怎么理解呢?这⾥我分别举两个例⼦:线上有个 Bug,找到了有问题代码⽚段,需要⼀个优化实现⽅案来解决,这就是第⼀类问题,原因和结果⾮常明确清晰;线上⽼是出故障,⽽且反复总出意外故障,对于这个结果,它的原因是什么,这就很难简单归因了,就属于第⼆类问题。
对于这两类问题,我想讲讲两种不同的思维框架提供的解法。
科学与理论
第⼀类问题,现象清晰,归因明确,那么它唯⼀的难处就是为这个问题找到最优的解决⽅案。求解最优化问题,就需要科学与理论的⽀持,也即:科学思维。
吴军⽼师也曾在⼀篇⽂章《计算机科学与⼯程的区别》⾥指出:
科学常常指出正确的⽅向,⽽⼯程则是沿着科学指出的⽅向建设道路;在⼯程中必须⾸先使⽤在科学上最好的⽅法,然后再作细节的改进。
我做在线客服系统时碰到⼀个问题和滴滴打⻋的匹配问题⾮常类似,打⻋是⼈和⻋的匹配,⽽咨询客服是⼈和客服的匹配。抽象来看,这个匹配的算法并不复杂,但因为涉及到⾮常具体且繁琐的业务规则,实现起来就有特别多业务逻辑,导致性能有问题。这就是软件⼯程现实中的第⼀类问题,需要找到优化⽅案。
理论的意义不在于充当蓝图,⽽在于为⼯程设计实践提供有约束⼒的原理;⽽⼯程设计则依循⼀切有约束⼒的理论,为实践作切实可⾏的筹划。
简⾔之,科学理论确定了上限,⼯程实践画出了路线。
系统与反馈
第⼆类问题,结果明确,但归因很难,那么找到真正的原因就是第⼀个需要解决的难点。这时,我们就需要⽤另⼀种思维⽅式:系统思维。
回到前⾯举的例⼦,线上⽼是出故障,⽽且反复出意外故障。如果简单归因,查出故障直接原因,发现是代码写得不严谨,实现有不少漏洞和问题,仔细看就能分析出来,但触发条件罕⻅不容易测出来,于是提出解决⽅案是增加代码评审(CodeReview)流程来保障上线代码的质量。
关于代码评审就是我从业多年来遇到的⼀个⾮常有意思的问题,⼤家都觉得它有⽤,也都说好,但很多时候就是执⾏不下去。因为它不是⼀个简单问题,⽽是⼀个系统问题。万维钢在《线性思维与系统思维》这篇⽂章⾥,给出了⼀些系统问题的典型特征,其中有两条是这样说的:
多次试图解决⼀个问题,却总是⽆效;
新⼈来了就发现问题,⽼⼈⼀笑了之。
⼀个优秀的⼯程师应该同时具备科学思维和系统思维,它们是⼯程思维的两种不同表现形态:系统思维洞察问题本质,科学思维发现最优解法。
五、徘徊:道中彷徨
39 | 职业倦怠:如何面对?
从今天起,咱们专栏即进⼊第 4 个⼤主题——“徘徊:道中彷徨“。成⻓的途中,我们总会⾯临很多的困扰与惶惑,这些困扰和彷徨很多都关乎选择,只有了解并认清这类困惑,我们才可能做出最合适的选择。
职业⽣涯的路上,每个⼈都会碰到职业倦怠期,我也不例外。曾经好⼏次,我都陷⼊其中。如今从中摆脱出来后,我就想尝试搞清楚这样⼀种状态的根源,思考⼀种⽅法来缩短它持续的时间,或者说增加它出现的时间间隔。
那职业倦怠到底是怎样的⼀种感受呢?
倦怠感
1974年,美国临床⼼理学家弗罗伊登⻉格尔(Herbert J. Freudenberger)⾸次提出”职业倦怠“的概念,⽤来指 ⼈⾯对过度⼯作时产⽣的身体和情绪的极度疲劳 。
职业倦怠感⼀般将可以明显感知到的分为两种。
⼀种是短期的倦怠感。它出现的状态,可以⽤两个英⽂单词来形象地表达:Burnout(燃尽,精疲⼒尽)和 Overwhelm(难以承受)。
另⼀种更可怕的倦怠感是⻓期的,它与你对当前⼯作的感受有关。
其实真正的⼯作,应该是⼀种积极的、有⽬标的事情,它能让我们实现对⾃我和他⼈的价值,并且乐在其中。但即使⼀开始我们是在做这类真正的 “⼯作”,时间久了后,也难免碰到职业倦怠感,这时我们可能就会困惑:难道我已不再热爱现在的⼯作了?对于这种状态,有⼀个说法是这样的:
倦怠,意味着你在这⼀关打到头了,⽽新的⼀关的钥匙,就在你⼿上。
遇到这种情况的本质,其实是我们⾃⼰的 “⼯作区” 发⽣了转移和变化,从⽽脱离了原来的 “⼯作态”,碰到了倦怠感。
当倦怠感出现时,”⼯作态” 就隐退了;⽽为了消除倦怠感,我们就需要找回 “⼯作态”。
⼯作态
⼯作态,如其名,是⼀种⼯作的状态,⼀种让我们在⼯作中感觉到美好的状态(beautiful state);是做我们喜欢的⼯作时表现出来的⼀种状态。
现代⼼理学上有个概念叫 Flow,⼀般译作 “⼼流”,也是⼀种⼯作状态,它是⼈在专注进⾏某些⾏为时所表现出的⼼理状态,⽐如艺术家创作时的状态。在此状态下的⼈们,通常不愿被打扰,也⽐较抗拒中断,个⼈的精神⼒将完全投注在某种活动上,同时还会伴随⾼度的兴奋与充实感。
那么 “⼯作态” 和⼼流有何不同?”⼯作态”,其实是我⾃⼰发明的⼀个概念,它的定义覆盖的期限更⻓久,就像⻓跑中的节奏;⽽⼼流的定义更像是⼀种 “⼯作态” 的局部过程表现,像⼀次短程冲刺。你没法⻓时间地处于⼼流状态,但在相当⻓的⼀段时间周期内,你可以处在 “⼯作态” 中,就像电影中那位缝匠,⼏⼗年如⼀⽇的,每天早晨都会⾃动进⼊那样⼀种 “⼯作态”。
职业倦怠期,显然是与 “⼯作态” 互斥的⼀种状态。所以,要脱离职业倦怠期,最有效的⽅式就是进⼊ “⼯作态” ;⽽进⼊ “⼯作态” ,最核⼼的地⽅在于找到⾃⼰的 “⼯作区”。
⼯作区
关于⼯作区,我想借⽤下⾯⼀张图来展示。
“⼯作区” 的概念不是我发明的,其原始概念图来⾃国外⼀个站点,我将其翻译和重绘了⼀下。其中定义了关于⼯作的三个区域,也就是说每⼀份⼯作都包含了这三个⽅⾯:
- ⽬的意义 Purpose
- 职业⽣涯 Career
- ⼯作岗位 Job
⽬的意义,这是⼯作的终极之问。它决定了你的很多选择,以及你接受什么、拒绝什么,是⼯作愿景背后的灵魂所在。每个⼈⼯作都会有⾃⼰的⽬的与意义,⽽且还会随着⼯作过程发⽣变化(或者说进化更合适些)。追寻⽬的与意义,这可能是你、我⼀⽣的⼯作。
职业⽣涯,是个⼈⼀⽣职业愿望的追寻过程。它由⻓期⽬标驱动,是追寻 “⽬的意义” 的⼀条你所期望的路径。⽽这条路径并不唯⼀,它因⼈⽽异,因你的 “⽬的意义” ⽽异。它构建在你⼯作过程中的所有经历、经验、决策、知识、技能与时运的基础之上。
⼯作岗位,这不过是你现在上班的地⽅,包括了位置、⻆⾊、关系、职责与薪酬的总和。
这三个区域会有交集,这⾥我举个实际的例⼦。假如你⼯作的 “⽬的意义” ⾮常现实,就是希望有更多的收⼊改善家庭⽣活,住更⼤的房⼦,开更好的⻋。⽽现在的 “⼯作岗位” 能够提供这样让你满意的收⼊⽔平,那么你就会感到 “快乐幸福”。
⽽若你对 “职业⽣涯” 路径的期望是从程序员到架构师,甚⾄再到 CTO,当前的 “⼯作岗位” 能提供这样的发展路径,那你就会充满 “激励驱动”。显然,职业⽣涯⼀路达到 CTO,收⼊⽔平会更⾼,与你的现实 “⽬的意义” 相符合,那你就会感到 “成就满⾜”。
如图中所示,这三者相交的那个位置,就是你的 “⼯作区”。在这个区域内,⼯作让你有驱动⼒,感到快乐,充满成就感。找到了 “⼯作区”,很⾃然就会进⼊ “⼯作态”。
当职业倦怠时,⾃然是远离了⼯作区,这时很容易产⽣的⼀个决策是:换⼀份⼯作。我曾经就做过这样的决策。换⼀份⼯作没有对错好坏之分,它能改变你的⼯作岗位,甚⾄也能改变你的职业⽣涯路径,但它唯⼀不能改变的就是你对 “⽬的意义” 的思考与认识。
做⾃⼰所爱,是对的;爱上⾃⼰所做,也是对的,关键就是要找到什么在真正驱动你前进。
丹⻨哲学家索伦·克尔凯郭尔(Søren Kierkegaard)说过⼀句话:
Life can only be understood backwards; but it must be lived forwards.
只有向后回⾸时才能理解⽣活,但⽣活却必须向前。
40 | 局部最优:如何逃离?
在求解最优参数的算法中,很多都有⼀个缺陷,就是容易达到⼀种局部最优点,即:参数的选择尝试收敛到了⼀⼩块范围内,⽆论再怎么尝试变化都没法取得更优的结果。⽽从全局来看,这并不是最优的选择,但算法此时就进⼊了⼀种尝试的徘徊状态,这就是局部最优点,但算法并不知道这到底是不是全局最优的。
对于我们这些⾃诩智能的⼈,在成⻓的路上,其实也经常陷⼊这样的成⻓局部最优点。
爬⼭
关于成⻓最形象的类⽐便是爬⼭,但爬到⼭顶的路并不总是向上的。
我们在成⻓(爬⼭)的路上,会进⼊局部最优点。⼀⽅⾯可能是 “⼭形” 所致,要继续上⼭的路需要先向下⾛,⽽向下的疑虑⼜会让我们徘徊不前。另⼀⽅⾯,可能是此 “⼭” 只有这么⾼了,就像⻘城⼭,你想看云海,可能就得换⼀座⼭了。
徘徊
所有的局部最优点,都意味着我们爬到了⼀定阶段,在这个位置徘徊不去,恋恋不舍。
看清了⾃⼰⽬标的⾼⼭,发现⾃⼰爬错了⼭,要舍得离开;停留在低矮的⼭上,⽆论再努⼒,看到的⻛景也有限。
逃离
如何知道你正站在局部最优点上徘徊呢?当你知道⾃⼰做得很好,但却没有感觉到成⻓与进步时,那么也许你就正在徘徊了。
进⼊局部最优,徘徊于局部最优,逃离局部最优,都是你的选择。⽽站在局部的最优点,⾛出徘徊的第⼀步,总是从下⼭开始,⽽这样的选择并不容易。
41 | 沟通之痛:如何改变?
隔壁专栏(左⽿听⻛)的陈皓以前在他的博客上写过⼀篇⽂章叫《技术⼈员的发展之路》,⾥⾯提及职业发展到⼀定阶段,也许你就会碰上⼀些复杂的⼈和事,这种情况下他写道:
这个时候再也不是 Talk is cheap, show me the code! ⽽是,Code is cheap, talk is the matter!
这⾥的 Talk 其实就是沟通,在⼯作中你要是留⼼观察,就会发现很多沟通问题,⽐如,跨团队开会时常发⽣的⼀些分歧和争论。沟通,越发成为⼀件重要的事,⾄少和写代码同等重要;沟通清楚了,能让我们避免⼀些⽆谓的需求,少写不少⽆效的代码。
然⽽现实中, 沟通问题,有时却被作为程序员的我们有意或⽆意地回避与忽略了。⾯对沟通问题,我们该如何看待和分析这个问题,并做出⼀些改变呢?
⽊讷与沉默
⽊讷与沉默,这两个名词似乎已变成了程序员的标签,它们形象地体现了程序员在沟通中的表现。
需求没沟通清楚,写出来的代码,即使没 Bug 将来也可能是负债。
争论与⽆奈
程序员最容易产⽣沟通争论的地⽅:沟通需求和沟通技术⽅案。
在程序员的职业⽣涯路上,我们不可避免地会碰到和同事关于技术⽅案的争论。我从中得到的教训是:千万不要让两个都⾃我感觉很⽜的程序员去同时设计⼀个技术⽅案。
假如不巧,你已经这么⼲了并得到了两个不同的⽅案,那么记住,就别再犯下⼀个错:让他们拿各⾃的⽅案去 PK。因为这样通常是得不到你想要的”⼀个更好的⽅案”,但却很可能会得到”两个更恼怒的程序员”。
既然分歧已经产⽣了,为了避免⽆谓的争论,该怎么解决呢?
以理服⼈
⾸先,把握⼀个度,对事不对⼈,切勿意⽓⽤事。
我所理解的技术的 “理” 包括:先进性、可验证性、和团队的匹配性、时效性、成本与收益。另外还有⼀些不合适的”理”,包括:⻛格、⼝味、统⼀、政治等。
以德服⼈
找⼀个主观的⼈来做裁决吧。
这个⼈通常就是公司所谓的经验丰富、德⾼望重的”⽼司机”了,并且双⽅也都是认可的,⽐如架构师之类的。
以⼒服⼈
最差的状况就会⾛到这⼀步,特别在跨⼤部⻔的沟通中。
技术⽅案⽆法达成⼀致,也没有⼀个跨两个部⻔的有德之⼈可以转圜化解,就会升级到这个地步。最后就是靠粗暴的权⼒来裁决,看双⽅部⻔⽼⼤或⽼⼤的⽼⼤,谁更有⼒或给⼒。⼀般来说,⾮关键利益之争实在没有必要⾛到这⼀步了。
认识与改变
做出改变的第⼀步是要能认识到,否则改变不可能发⽣。
按照程序员解决技术问题的习惯,就是把⼀个⼤问题拆解为多个部分的⼩问题,那这⾥我们也对沟通做下拆解,它包括三个⽅⾯:
- 内容
- 形式
- ⻛格
从内容上看,虽说你想沟通的本质是同⼀样东⻄或事情,但针对不同的⼈,你就需要准备不同的内容。
换位思考本质上就是沟通技巧中的⼀种。
从形式上看,沟通其实不局限于⾯对⾯的谈话。⾯对⾯交谈是⼀种形式,书⾯写作⼜是另外⼀种形式,连写代码本身都是在和未来的⾃⼰或某个你尚未谋⾯的程序员沟通。
从⻛格上看,不同⽅式和场景的沟通可以有不同的⻛格。⽐如⾯对⾯沟通,有⼀对⼀的私下沟通,⻛格就可以更随性柔和些;也有⼀对多的场景,⽐如演讲、汇报和会议,⻛格就要正式⼀些,语⾔的⻛格可能就需要更清晰、准确和锐利⼀些。
沟通之难就在于清晰地传递内容和观点。当你要向其他⼈详细解释某样东⻄的时候,你经常会惊讶地发现你有多⽆知,于是,你不得不开始⼀个全新的探索过程。这⼀点可以从两个⽅⾯来体会:
- 你只需要尝试写点你⾃认为已经熟悉掌握的技术,并交给读者去阅读与评价。
- 每过⼀段时间(⽐如,⼀个季度或半年)尝试去总结,然后给同事分享下你⼯作的核⼼内容,再观察同事们的反应和听取他们的反馈,你就能体会到这⼀点了。
所以,沟通改变的第⼀步就是从考虑接收⽅开始的,看看接收⽅能吸收和理解多少,⽽⾮发送了多少。⽽沟通问题的三个⽅⾯——内容、⽅式与⻛格——的考虑,都是为了让接收更⽅便和容易。
从认识我们的本性开始,控制情绪,从⽽去规避⽆奈的争论;认识清楚沟通问题的本质是要⽅便接收,达成共识,保持换位思考和同理⼼,改变⾃会发⽣。
42 | 技术停滞:如何更新?
技术停滞
技术停滞是如何发⽣的?
在程序员⾜够熟练了之后,每天的这种编程实战型⼯作就不会再是处于 “学习区” 的练习了,⽽是进⼊了 “舒适区” 的⾃动完成。然⽽很多熟练程序员的⽇常⼯作则是在 “舒适区” 的⾃动完成,⼯作之外则是另⼀种 “舒适区” 的娱乐休闲。
停滞,就是这样发⽣的。
技能保养
感觉停滞的技能,如果⼯作依然需要它,其⼤的技术⽅向发展趋势依然明朗,那么这样的技能是值得好好保养,并继续提⾼的。⽽保养和提升技能的⽅法,”刻意练习” 依然是不⼆之选。
关于 “刻意练习”,有时我们即使⼀直保持在 “学习区” 的重复练习,却也可能感觉不到进步,这有可能是因为重复的次数和强度还不够。
在决策科学中有⼀个概念叫 “基础⽐率(Base Rate)”:
所谓基础⽐率,就是以前的⼈,做同样的事,做到的平均⽔平。
也就是说,如果别⼈做这件事需要那么⻓时间,基本上你也需要那么⻓时间,因为可能你没有那么特殊,只是每个⼈都会”觉得”⾃⼰是特殊的、例外的罢了。
重复,是有针对性的强化练习,其本身是练习过程,⽽⾮练习内容。每⼀次的重复过程中都需要根据反馈进⾏有针对性的调整,以取得练习效果的进步。
技能开发
技能不仅仅会停滞,还有可能会过时。
旧技术过时了,肯定是因为有另⼀种新的技术来取代了它,我们只需定期保持跟踪,观察现有掌握的技术是否可能被新出现的技术所取代。⼀般来说,新旧技术的更替都是有⼀定周期和⼀个持续的过程的,这期间给了我们⾜够的时间来学习和开发基于新技术的新技能。
⽽针对不同的学习⽬标,采⽤的学习路线也会不同。
如果需要学习新技能来解决⼯作上的⼀个具体问题,那这样的⽬标更适合采⽤深度路线学习⽅式,这是解决特定问题的⼀种捷径,属于痛点驱动式⽅法,能让你快速排除障碍,解决问题,⽽⾮先找到相关书籍,从头读到尾,知道⼀个整体⼤概。
⼀般技术书籍的组织⽅式都是按主题的相关性来编排的,系统体系性很强,但却不是按你解决问题需要知道的内容来组织的。所以,技术书籍更适合于在你解决问题的过程中⽤来参考。完整地读技术书籍能增⻓你的知识,但却⽆法快速习得技能,并解决你的问题。
反过来,另⼀种情况,⾯临⼀种新兴技术,⽐如,近年⽕热的⼈⼯智能与机器学习,你不是需要解决⼀个具体问题,⽽是要对这类新兴技术⽅向做评估、判断和决策。那么学习的⽅式就⼜完全不同,这时采⽤⼴度路线学习就更合适。
对如何开发⼀⻔新技能,《软技能》⼀书的作者曾在书中分享过他的⼀个⼗步学习法:
- 了解全局
- 确定范围
- 定义⽬标
- 寻找资源
- 学习计划
- 筛选资源
- 开始学习,浅尝辄⽌
- 动⼿操作,边玩边学
- 全⾯掌握,学以致⽤
乐为⼈师,融汇贯通
这个⽅法和我⾃⼰在实践中养成的习惯基本⼀致。在深度路线学习中,对全局、范围、⽬标的定向更聚焦,因此寻找、筛选的资源会更窄,学习计划的迭代期更短,很快就⾛完了前 6 步,并进⼊动⼿实践、反复迭代的过程中,直到把问题解决。
⽽在⼴度路线的学习中,前 6 步会花去⼤量的时间,因为这时你⾯临的问题其实是对新技术领域边界的探索。这就像以前玩《魔兽争霸》游戏中,先去把地图全开了,看清楚了全貌,后⾯再进军时就能选择最优路径,避免了瞎摸索。
这个类⽐中不太恰当的是,游戏中开地图实际挺简单的,但现实的技术领域中,地图全开基本是不太现实的,⼀是地图实在太⼤,⼆是地图本身也在演变中。只能说尽可能在前期的探索中,所开的地图范围覆盖更⼴⾄需要去解决的问题领域。
沉淀能⼒
技术也许会停滞,技能也可能会过时,但其中的能⼒却可以沉淀下来,应⽤于下⼀代的技能之上。
技术也许会停滞,技能也可能会过时,但其中的能⼒却可以沉淀下来,应⽤于下⼀代的技能之上。汉语中容易把能⼒和技能混为⼀谈,在英语中,技能对应的词是 Skill,⽽能⼒对应的是 Ability。技能是你习得的⼀种⼯具,那么能⼒就是你运⽤⼯具的思考和⾏为⽅式,它是你做成⼀件事并取得成果的品质。
那么程序员需要去沉淀哪些能⼒?
作为程序员最基本的⾃然是代码能⼒。能够写程序,只能算是技能过关吧,⽽能写好程序,才算具备了程序员的基本代码能⼒。代码能⼒的识别,最简单的⽅式就是维护⼀份公开可跟踪的记录,⽐如参与开源项⽬贡献,在 GitHub 上留下你的代码简历。
从程序员到架构师,”架构”显然不是⼀种技能,⽽是综合应⽤多种技能的能⼒。架构师也许不像在⼯程师阶段需要写⼤量代码,但实际没有代码能⼒是做不了架构的。代码能⼒是架构能⼒的底层能⼒要求。但仅此⼀项能⼒却也远远不⾜,这⾥就先不展开了,后⾯会专⻔有⼀篇⽂章谈架构师能⼒模型这个主题。
除了技术能⼒,如果有可能可以适当跨出技术的边界,去了解下产品、管理、运营和传播等⽅⾯的能⼒。为什么呢?⼀⽅⾯,技术能⼒的提升总会到达平台期,增⻓变得缓慢,⽽了解学习⼀下其他⽅⾯的全新能⼒,可能会让你找到新的成⻓点,重新找回快速成⻓的感觉。
另⼀⽅⾯,个⼈很多综合能⼒的差别,有时就是要靠作品来体现的。完成作品需要有⼀些产品思维,需要⾃我规划与管理能⼒,⽽推⼴作品需要运营和传播能⼒。这些相关的能⼒,最终都会成为你核⼼能⼒体现——作品——的放⼤器。
虽有俗语说:”技多不压身”,但实际很多技能是有保养成本的,编程技能就是⼀种,特别是和特定技术有关的编程技能。所以,同时保养很多技能是不太合理和现实的,更优化的选择是:持续保养主要的⽣存技能,合理开发辅助技能,形成⾃⼰独有的技能组合,沉淀能⼒模型,发展能⼒矩阵。
43 | 无法实现:困扰与反思
程序员有句⼝头禅叫:”技术上⽆法实现!”这句话,⼀仔细思考,就惊讶地发现⼀个事实:这句⼝头禅背后隐藏着⼀个阻碍我们成⻓的陷阱。
困扰
当接到⼀个需求或碰到⼀个问题,我们回上⼀句:”技术上⽆法实现!”这是真的⽆法实现吗?还是隐藏着其他的困扰?
不知
因为不知和不解⽽⼼怀畏惧。因为畏惧,所以我⽤了这句⼝头禅来回避了一些问题,甚⾄没有去调研⼀下技术可⾏性,就由此固步⾃封,在这⽚知识领地留下⼀⽚空⽩,也不能为客户创造更进⼀步的价值。
不愿
当时我说出的那句”技术上⽆法实现”,只是因为觉得很麻烦,不愿意⽽已。后来睡醒后,回了⼀些⾎,有了能量,觉得应该接受这个挑战。因为客户的需求变化就是⼀个客观事实,也不会因为我的主观意愿⽽改变。
反思
你需要⼀个办法去应对⼀个让你觉得 “技术上⽆法实现” 的需求。我建议不要⽴刻像我当年那样做出如此简单的判断就推脱过去,其实我们完全可以把这样的问题放在下⾯这样的框架中去思考下。
全局背景
这⼀步的⽬的并不是要找到并确定实现⽅案,只是对这⼀问题涉及主题的相关内容有⼀个全局性的了解。
近年我都在做京东咚咚,⼀个 IM 系统,所以就以此举个例⼦吧。不时我们会收到⽤户反馈在安卓客户端应⽤切到后台就会收不到消息,这⾥⽤户只是提供了⼀个说法,甚⾄都不算现象。但这是⼀个问题,⽽且是⼀个我觉得在技术上⽆法百分百根除的问题,换⾔之就是我可能想不出⼀个⽅案能让我的所有⽤户都再也不会碰到类似的问题。
⽽⽤户碰到这样的问题可能的原因有:
- 移动弱⽹络,消息投递失败率⾼;
- 应⽤切后台就被系统杀掉,所以收不到;
- 第三⽅推送渠道,⽐如:某⼀类⽤户完全没有这种渠道可达;
应⽤本身的问题,⽐如:Bug,版本碎⽚导致的兼容性问题。
以上简单的问题分类,背后都隐藏着⼀个解决或优化问题所需的巨⼤且复杂的实现⽅案。针对每⼀类问题的⽅案,可以先去⼤概有个了解,但这⾥还不需要很深⼊。
聚焦范围
对上⾯列出的全局背景问题分析分类后,会发现没有⼀个是轻松容易就能解决的。⽽且这时还必然⾯临资源和时间的问题,也就是在特定的资源和时间下,我应该优先解决哪类?所以,这⼀步的本质就是从上⾯的全局分类中,聚焦⼀个范围,然后集中深⼊调研评估。
定义标准
前⾯说了⽤户仅仅反馈了⼀个说法,站在⽤户的⻆度,他们总是希望没有任何问题的。但站在我的⻆度,我知道我只聚焦了⼀部分问题,所以我需要清晰定义这部分问题解决的成功标准。
⽐如,针对应⽤切后台就被系统杀掉,对⽤户⽆感知,所以认为收不到消息是有问题的。针对这个问题的聚焦范围,我可以提供第三⽅推送渠道在⼗分钟内的推送通知补偿,重新唤醒⽤户重回应⽤,避免消息的遗漏。通过估算每⽇活跃⽤户和可能投递给第三⽅渠道消息通知量以及第三⽅渠道⾃⼰标榜的投递成功率和业界⼀些经验数据,就能估算出该解决⽅案的标准:通知唤醒到底能补偿多少⽤户的指标
深度评估
有了范围和标准,剩下的就是深度评估⽅案路径问题。⼤体上任何⼀个⽅案,其中有些是你已经轻⻋熟路的实现路径,另⼀些则是你可能从未⾛过的陌⽣之路。
44 | 完成作品:理想与现实
有时⼯作久了,会陷⼊这样⼀种状态中,整天不停地写代码,开发业务需求,周⽽复始,⽇⼦⻓了,⾃然觉着厌倦,感到似乎真的有点像 “码农” 了,⽇出⽽作,⽉落⽽息。在过去的某个时期,我应该也陷⼊过这样的循环之中,后来⼜是如何脱离的呢?
困境:代码与罗⻢
陷⼊这样⼀种写代码的 “困境”,还是要回归到写代码这件事本身上。
写代码是因为有需求,需求来⾃业务的发展需要,经过产品经理再传递到程序员。刚开始,作为⼀个新⼿程序员,不停地为各种需求写代码。开发完⼀个,接着⼜是下⼀个,⽣⽣不息,循环不⽌。
⼀开始也许会感觉有些累,但并没有产⽣太多的厌倦。这是⼀个从不熟悉到熟悉再到熟练的过程,这⾥有太多的新东⻄可以去探索和尝试,让你在疲惫中依然能获得了好奇⼼的满⾜和成⻓的快感,因此不会感觉厌倦。
那技能从不熟悉到熟练需要多久呢?现在成为专家的要求已经有了共识:⼀万⼩时的刻意练习。但达成熟练要不了那么久,也许两三年⾜矣。有句俗语叫:”条条⼤道通罗⻢”。罗⻢,⼀座城市,包罗万象,类⽐到程序员这⾥就像⼀个个需要完成的业务需求。⼏年过去,每⼀条通往”罗⻢”的⼤道都被你⾛过了,再去往”罗⻢”时,⾃然找不到新鲜感了,困倦油然⽽⽣。
在⼀万⼩时的刻意练习中,”罗⻢”已逐渐成为过去的熟悉、熟练区,⽽离开”罗⻢”便是要进⼊下⼀个陌⽣的学习区。但也许还会有⼀种 “现实” 的困境让你不得不继续⾛向当前的”罗⻢”,那么这时就不妨换⼀个视⻆:既已对通往当前”罗⻢”的所有路都了然于胸,闭眼可达,那就仔细观察了解现在”罗⻢”的构成与运作机制,也许将来有机会去创造属于⾃⼰的”罗⻢”。
理想:作品与创作
代码作品,可以⼩到⼀段函数、⼀个类,⼤到⼀个库或框架、⼀个服务,甚⾄⼀个系统。但打磨代码作品的⽅式,应该是定期对⾃⼰写完的代码进⾏沉淀、梳理和规整,提取可复⽤的功能,同样的功能只写⼀次,形成⾃⼰专属的编码脚⼿架和代码库。在以后的学习实践中定期反思,不断优化其效率和品质。
对于你来说,今天的作品虽不⼀定能⽴刻给你带来经济收益,但在你打磨作品的过程中,把”条条通往罗⻢的⼤道”都⾛完了,甚⾄还反复⾛试图找到更优化的路线,这会让你掌握系统化的知识和体系化的能⼒,同时还会让你的作品变得更值钱。你可以想象这样⼀个场景:当你给别⼈介绍⾃⼰时,只需要介绍⾃⼰的作品,⽽不再需要介绍⾃⼰的技能。
现实:产品与特性
作品要实现直接的经济收益,必须还要⾛完从作品到产品之路。
有个说法是:要做好技术需要懂业务和产品。这⼤体没什么问题,但需要提到的细节是懂的⽅向。技术不需要了解业务产品的每⼀个显性特征,⼀个⾜够⼤的业务产品,有⽆数的显性特征细节,这些全部的细节可能分散在⼀群各⾃分⼯的产品经理们中。所以应该说,技术需要懂的是产品提供的核⼼服务和流程,并清晰地将其映射到技术的⽀撑能⼒与成本上。
⽤⼀段新算法实现的函数取代了旧函数,那么多余的旧函数就变成了负债⽽⾮资产,是需要去清理的。重构代码变得更简洁和优雅,可读性增强,节省了未来的维护成本。⼀个能同时服务⼀万⼈的程序实例,你知道你没法加⼗个实例就能简单变成能同时服务⼗万⼈的系统。这些都是技术冰⼭下的隐性特征,显性的错误会有测试、产品甚⾄最终⽤户来帮你纠正,但隐性的错误却很难有⼈能及时帮你发现并纠正。
45 | 代码评审:寄望与哀伤
我们都知道代码评审(Code Review)很有⽤、很重要,但现实中我所经历的和看到的团队,很少有能把代码评审落地得很好,并发挥出其应有作⽤的。这个问题困扰我已久。
感性认识
代码评审的作⽤,有⼀定经验的程序员们想必都会有感性认识。
代码评审的初衷是提⾼代码质量,在代码进⼊⽣产环境前经过同⾏评审来发现缺陷,降低损失概率。
理性分析
代码评审对于发现潜在缺陷很有⽤,相⽐测试能发现的缺陷率⾼⼀倍,但也需要投⼊巨⼤的时间成本 —— ⼀⼩时审查 150 ⾏代码,再快就不利于发现潜在缺陷了,⽽且更适⽤于⻓⽣命周期的产品。
多种困境
如果把代码评审作为⼀个必要环节引⼊到研发流程中,也许还有⼀些关于如何实施代码评审的困境。
- 困境⼀,项⽬期限 Deadline 已定,时间紧迫,天天加班忙成狗了,谁还愿意搞代码评审?这是⼀个最常⻅的客观阻碍因素,因为 Deadline 很多时候都不是我们⾃⼰能确定和改变的。
- 困境⼆,即使强制推⾏下去,如何保障其效果?团队出于应付,每次⾛个过场,那么也就失去了评审的初衷和意义。
- 困境三,团队⼈员结构搭配不合理,新⼈没经验的多,有经验的少。新⼈交叉评审可能效果不好,⽽⽼是安排经验多的少数⼈帮助 Review 多数新⼈的代码,新⼈或有收获,但对⾼级或资深程序员⼜有多⼤裨益?⼀个好的规则或制度,总是需要既符合多⽅参与者的个体利益⼜能满⾜组织或团队的共同利益,这样的规则或制度才能更顺畅、有效地实施和运转。
- 困境四,有⼈就是不喜欢别⼈ Review 他的代码,他会感觉是在找茬。⽐如,团队中存在⼀些⾃信超强⼤的程序员,觉得⾃⼰写的代码绝对没问题,不需要别⼈来给他Review。
参考路径
Google 以⼀种强硬的姿态来制定了关于代码评审的规则,规则适⽤范围是全公司,对任何⼈都不例外。即使⾯对团队中超⾃信且强⼤的程序员也⽆例外,要么遵守规则,要么离开组织。这⼀点从 C 语⾔和 Unix 的发明者、图灵奖得主——肯·汤普森(Ken Thompson)在 Google 的趣事中可以⼀窥其规则的强硬性,作为 C 语⾔发明者之⼀的他因为没有参加 Google 的编程语⾔能⼒测试所以⽆法在 Google 提交 C 代码。
所以,像 Google 这样的公司对于代码评审属于⾼度认可且有公司制度和规则的强硬⽀持,再辅助⾃动检测和控制⼯具的严格执⾏,⼀举就破解了以上四类困境。但要实践类似 Google 这样严格的代码评审制度和规则,似乎对于⼤部分公司⽽⾔都有不⼩的挑战,这需要公司制度、团队⽂化和技术⼯具三⽅⾯都能⽀持到位,⽽且还要让各⽅对实施此项制度的收益和代价取得⼀致认可,岂是易事?
现实选择
以前尝试过要在团队内部做代码评审,听说兄弟团队搞得不错,然后就⼀起交流经验。交流开始不久就跑偏了,重⼼就落在了应该选个什么好⽤的代码评审⼯具来做,如今想来这完全是舍本逐末了。
即使在最差的环境下,完全没有⼈关⼼代码评审这件事,⼀个有追求的程序员依然可以做到⼀件事,⾃⼰给⾃⼰ Review。就像写⽂章,我写完⼀篇⽂章不会⽴刻发布,⽽是从头脑中放下(Unload),过上⼀段时间,也许是⼏天后,再⾃⼰重新细读⼀遍,改掉其中必然会出现的错别字或⽂句不通畅之处,甚或论据不充分或逻辑不准确的地⽅,因为我知道不管我写了多少⽂字,总还会有这些 Bug,这就是给⾃⼰的 Review。
给⾃⼰ Review 是⼀种⾃省,⾃我的成⻓总是从⾃省开始的。
代码评审,能提升质量,降低缺陷;代码评审,也能传播知识,促进沟通;代码评审,甚⾄还能影响⼼理,端正姿势。代码评审,好处多多,让⼈寄予希望,执⾏起来却⼜不免哀伤,也许正是因为每⼀次评审的收益是不确定的、模糊的,但付出的代价却是固定的,包括固定的评审时间、可能延期的发布等。
46 | 人到中年:失业与恐惧
恐惧感:谋⽣
当你感到害怕丢掉⼯作时,说明已经不再年轻了,⼀种为了谋⽣的恐惧感油然⽽⽣。
中年,每个⽉⽐年轻那会⼉挣得更多了,职位也更⾼了,⽣活变得更安适和稳定,这时真正潜伏着的威胁开始出现:技能的上升曲线可能越过了⾼点,⾛⼊平缓区,甚⾄也许在以缓慢⽽不易觉察的⽅式下降,⽽我们却安之若素。
⽆惧感:舍⽣
假如你在⼀份⼯作中,对丢掉⼯作本身产⽣了恐惧,那你做⼯作的形式很可能会⾛向谨⼩慎微。
⽽偏偏是要对⼯作的⽆惧感才能真正释放你的潜⼒,发挥你的能⼒,让你能够留在原地甚或更进⼀步。
作为程序员,我们只有⼀个位置:专业阵地。这是⼀个专业性要求⽐较⾼的职业,我们被雇佣并要求成为⼀名专业⼈⼠,所以应该像⼀个专业⼈⼠⼀样⾏事。普通劳动者和专业⼈⼠的区别在于,普通劳动者主要被动接受指令去执⾏任务,⽽专业⼈⼠则在其领域内⾃⼰⽣成指令,同时在领域外还会向同事或上级提供来⾃该领域的输出:专业建议。
普通劳动者是⼀种劳动⼒资源,他们保证执⾏,⽽专业⼈⼠则是保证选择的执⾏⽅向是有意义的,执⾏路径是优化的。作为专业⼈⼠,我们需要去坚持和持续地打磨专业⼒,守住这块阵地。有时我在想,是专业让⼈拥有⽆惧感呢,还是⽆惧了才能⾛向更专业?也许,”谋⽣的恐惧”害怕失去的不过是⼯作岗位,”舍⽣的⽆惧”才能塑造专业的职业⽣涯吧。
安全感:重⽣
安全感,是渴望稳定、安全的⼼理需求,是应对事情和环境表现出的确定感与可控感。
中年⼈和年轻⼈本应在不同的战场上。年轻时,拼的是体⼒、学习⼒和适应能⼒,是做解答题的效率与能⼒;中年了,拼的是脑⼒、⼼⼒和决策能⼒,是做对选择题的概率。
年轻时,我们打的是突击站,左冲右突;中年了,我们打的是阵地战,稳步推进;如今,我们进⼊了⼈⽣的中场战事。这场战事从谋⽣的恐惧感开始,给予我们警示;到舍⽣的⽆惧感,让我们摆脱束缚,整装待发;最后经过重⽣的安全感,推动我们再次上升。
47 | 该不该去创业公司?
我和我身边的同事都收到过来⾃创业公司的邀约,⾯临这样的选择,会同时有感性和理性的因素。感性的因素也许每个⼈都不尽相同,但理性的⽅⾯,更有普适性,从中我慢慢提炼和完善成了⼀组选择决策框架。
期望
为什么要加⼊创业公司,你的期望是什么?也许有下⾯⼏种原因:
⾃由成⻓
创业公司相对成熟的⼤公司,会有更⼤的⾃由度,能接触的东⻄更多,但需要处理的问题也更多、更杂,会让⼈更容易⾃由成⻓为⼀种解决各类问题的多⾯⼿。这对于程序员⽽⾔,很可能就是综合能⼒更强,但在特定的专业领域⼜不够精深。
变身⼟豪
业界坊间⼀直流传着创业公司上市 IPO ⼀夜变身⼟豪的故事。
变身⼟豪,其实需要的是增值 100 倍的机会,⽽最低的下注⾦额是⼀年的收⼊。加⼊创业公司就是⽤你的时间下注,能否撞上 100 倍的机会,很多时候就是靠时运。因上努⼒,果上随缘,尽⼈事,听天命。
追求梦想
也许创业做的事情正是你梦想的、喜欢做的事情,⼈⽣有时不就是挣钱来买⼀些 “喜欢” 么?那么你愿为 “喜欢” ⽀付多⼤的成本与代价?
条件
搞清楚了⾃身的期望与需要付出的成本和代价,再来理性地看看其他⽅⾯的因素。
- 创始⼈创业的⽬的是什么?期望是什么?创业毕竟是⼀段⻓期的旅程,⼤家的⽬的、价值观、期望差距太⼤,必然⾛不⻓远,身边就⽬睹过这样的例⼦。
- 创始⼈以前的⼝碑和信⽤如何?有信⽤污点的⼈并不值得合作与跟随,⽽且前⾯说的创业公司期权,最终能否兑现?就国内的创业环境⽽⾔,这⼀点也很是关键。
- 公司的核⼼团队成员如何?看看之前都有些什么样的⼈,你对这个团队的感觉契合么?价值观对味么?这个团队是合作融洽,还是各怀⻤胎?有些⼩公司,⼈虽不多,办公室政治⽐⼤公司还厉害。
- 对你的定位是什么?创业公司在发展初期容易遇到技术瓶颈,会以招 CTO 的名义,来找⼀个能解决当前技术瓶颈的专业⼈才。也许你会被名头(Title)吸引,解决完问题,渡过了这个瓶颈,但这之后⽼板会觉得你的价值还⾜够⼤么?有句话是这么说的:”技术总是短期被⾼估,⻓期被低估”。⽽你⾃身还能跟得上公司的发展需要么?
- 公司是否有明确的业务⽅向?业务的天花板多⾼?有哪些对⼿?相对竞争的核⼼优势是什么?很多做技术的同学都不太关⼼业务的商业模式,也许这在⼤公司可以,毕竟船⼤,⼀般也就感觉不到⻛浪。但在创业公司则不然,业务的天花板有多⾼?也就是能做到多⼤?如果公司业务没有明确的⽅向和优势,你憧憬着踏上了⽕箭,结果却是⼩舢板,起⻛时感觉还⾛得挺快,⻛⼀停,就只好随波荡漾了。
决策
决策之前,期望是内省,条件是外因;决策就是将客观的外因与主观的内省进⾏匹配判断选择的过程。
决策很难,让⼈经常很⽭盾,很沮丧。往回看,我们总能找到适合⾃⼰的最优决策路径,但当初却并没有选到这条路,所以沮丧。往前看,其实有⽆数的路径分⽀,我们怎么可能选中最优路径,有这样的⽅法吗?没有。
48 | 该不该接外包?
以前我曾接到过⼀些关于程序外包站点的营销邮件,也看到过身边有些⼈选择去接⼀些外包,赚点外快。当然也有⼈找到过我做外包项⽬,这时我就必须做出⼀个评估和选择,⾯对外包赚钱的诱惑,到底该如何进⾏更好的选择呢?
赚钱与诱惑
外包的直接诱惑,就是能⽴刻增加⼯资之外的收⼊,赚点外快。
只是,这种⽅式的赚钱性价⽐真的⾼吗?短期的直接收⼊回报诱惑很⼤,但⻓期的代价和成本呢?
成本与⽐较
接外包的短期成本是你的时间,那⻓期的成本和代价呢?
桥⽔基⾦创始⼈雷·达⾥奥(Ray Dalio),也是近年畅销书《原则》的作者,制作过⼀个视频叫《三⼗分钟看清经济机器如何运转》,他在视频的末尾提出了三条建议:
不要让债务的增⻓速度超过收⼊。
不要让收⼊的增⻓速度超过⽣产率。
尽⼀切努⼒提⾼⽣产率。
这三条建议虽然是针对宏观经济的,但我理解转化⼀下⽤在个⼈身上也是⽆⽐正确啊。特别是第⼆条,现下多接外包提⾼了当下的收⼊,但⻓期可能会抑制你的⽣产率,让你失去竞争⼒。
⽣产率是⼀个宏观经济术语,⽤到程序员个⼈身上可不能直⽩地理解为产出代码的效率,正确的理解我认为是个⼈价值的产出率,即如下等式:
个⼈⽣产率 = 个⼈价值的产出率
基于以上理解,⾯临当初的外包项⽬我的选择是:拒绝。因为,它带来的收⼊是⼀次性的,不具备积累效应,⽽且相⽐我的全职⼯作收⼊还有差距,短期也许能增加点收⼊,但也没有其他任何意义了。如果⽼是去接这样的事情,⻓期的代价必然是个⼈⽣产率的降低,得不偿失。
但我确实还做⼀些不赚钱的事,⽐如过去多年经常写作,偶尔翻译,我所做的这些事情的直接⽬的都和提⾼现阶段的收⼊(⽴刻多赚钱)没关系,只是想尽可能地在提⾼个⼈价值的同时提升价值产出率,也就是说在做达⾥奥所说的第三条建议。
不过,个⼈价值的提升可能不会⽴刻反映到当下的收⼊上,就像公司的内在价值提升了可能股价还没涨⼀样。但⻓期来看,价格总是要回归价值的,这是经济规律,宏观如国家,微观如个⼈。
值钱与选择
该不该接外包的选择本质是:选择做赚钱的事,还是值钱的事?
我观察多数真正拉开差距的阶段是在⼯作的⼗年到⼆⼗年之间,根据个⼈的价值积累⼤⼩,价值结构变现的机遇,拉开的差距是数量级的差别,会让你⽣出”当时看起来我们差不多,但如今他⼲⼀天能抵我⼲上⼀个⽉甚⾄⼀年了”的感慨,所以前⼗年不妨把关注的焦点放在个⼈价值的增值上。
最后,再总结下到底”该不该接外包”这个问题。我认为值得接的外包,它包括下⾯⼀些特性:
- 如果外包项⽬对你的技术积累有好处,那么收点钱去实践提升下正好⼀举两得;其实参与开源项⽬,本质上不就是不收钱的外包项⽬?它的收益就是让你更值钱。
- 外包项⽬的成果具有可复制、可重⽤性,这样就可以通过⼤量复制和重⽤来降低⼀次性开发成本;⽽成本和⽐较优势才是外包模式的核⼼竞争⼒所在啊。
外包项⽬不是临时⼀次性的,⽽是需要⻓期维护的,⽽这种维护的边际成本可以依靠技术⼯具⼿段不断降低,那这样的外包项⽬就是⼀个⻓期赚钱的 “机器” 了。
所有以上特性都反映了⼀个本质:去做值钱的事,打造值钱的结构,从知识结构、技能结构到作品结构与产品结构,然后等待某个未来的兑现时间。
49 | 技术干货那么多,如何选?
如今,已是技术⼲货进⼊了爆炸期,那我们该如何挑选与应对?
循证与决策路径
为什么我们会去挑选和阅读技术⼲货⽂章?我想,循证⼤概是⼀个原始诉求,通过分析别⼈⾛过的路径,来拨开⾃⼰技术道路探索上的迷雾。
我们去阅读技术⼲货⽂章,想从别⼈的分享中获得对⾃⼰技术⽅案的⼀个印证。这就是⼀种⾏业的实践证据,毕竟想通过听取分享去印证的,通常都是⾛过了⼀条与⾃⼰类似的道路。技术道路的旅途中充满着迷雾与不确定性,我们不过是想在别⼈已⾛过的类似道路中获得指引和启发,并得到迈出坚实下⼀步的信⼼。
这就是循证⽅式的技术决策路径。
循证,不⼀定能⽴刻给你的当下带来改变,但可以给你的演进路径⽅向带来调整,未来将发⽣改变。
切磋与思考⽅式
技术⼲货多了以后,在类同的领域都能找到不同公司或⾏业的实践分享,这时不仅可以循证,还能够达到切磋和多元化思考的⽬的。
切磋带来的思考是:你不能看⻅别⼈的功夫套路好,破解难题⼿到擒来,就轻易决定改练别⼈的功夫。表⾯的招式相同,内功可能完全不同,就像⾦庸⼩说⾥的鸠摩智⾮要⽤⼩⽆相功催动少林七⼗⼆绝技,最后弄得⾃废武功的结局。
切磋,主要是带给你不同的思维⽅式,⽤⾃⼰的功夫寻求破解之道。
连结与知识体系
⼲货多了,时间有限,⾃然就存在⼀个优先级的选择阅读问题。
就我个⼈来说,我的出发点很简单,有两点:基于功利性和兴趣。说起功利性也别觉得不好,毕竟整个商业社会都是基于功利性为基础的,所以基于此的选择其实是相当稳定的。考虑下所在组织和团队的功利性需求来做出技术的选择,有时甚⾄是必须的,⽽不能完全由着兴趣来驱动。
总结来说:⾯对众多的技术⼲货,从循证出发,找到参考,做出技术决策,决定后续演进路线;在演进路上,不断切磋,升级思考⽅式,调整路径,⾛出合适的道路;在路上,把遇到的独⽴的知识点,不断吸收连结进⼊⾃⼰的技术知识体系之⽹。
50 | 技术分歧,如何决策?
作为⼀名程序员或技术⼈,总会碰到这样的场景:在⼀些技术评审会上,和其他程序员就技术⽅案产⽣分歧与争论。如果你是⼀名架构师或技术 Leader,站在技术决策者的⽴场和⻆度,该如何去解决分歧,做出决策呢?
绝对
曾⼏何时,我以为技术是客观的,有绝对正确与否的标准判断。
做技术这么些年下来,关于技术⽅案的判断,曾经以为的绝对标准,今天再看都是相对的。
相对
的确是的,适合的技术决策总是在相对的条件下做出的。
康威定律告诉我们系统架构的设计符合组织沟通结构时取得的收益最⼤。这是⼀个经过时间检验和验证过的规律与⽅法,体现的就是⼀个相对的选择标准,那在这背后,有没有隐藏着关于技术决策更通⽤的判断原则呢?
原则
康威定律,是和组织的团队、分⼯、能⼒与定位有关的,其本质是最⼤化团队的核⼼能⼒,最⼩化沟通成本。
在⾜够⼤的组织中,沟通成本已经是⼀个⾜够⼤的成本,有时可能远超采⽤了某类不够优化的技术⽅案的成本。每⼀次⼈事组织架构变动的背后,都意味着需要相应的技术架构调整去适应和匹配这种变化,才能将沟通成本降下来。⽽技术⽅案决策的核⼼,围绕的正是关于⽅案的实施成本与效率。
成本与效率背后的考量包括如下因素:
- 团队:这是⼈的因素,关于团队的⽔平,掌握的技术能⼒和积累的经验;
- 环境:能利⽤的环境⽀持,公司内部的平台服务或外部的开源软件与社区;
- 技术:技术本身的因素,该项技术当前的成熟度,潜在的发展趋势;
约束:其他⾮技术约束,⽐如管理权限的⼲涉、限定死的产品发布⽇期等。
在技术的理想世界中,技术决策的纯粹部分,其决策原则都和成本效率有关;⽽其他⾮纯粹的部分,其实都是 “政治” 决策,没有所谓通⽤的原则,只和博弈与利益有关。
最后,简单总结下:技术没有绝对的标准,适合的技术决策,总是在受限的约束条件下,围绕成本与效率做出的选择权衡。对于⼀些纯粹的技术理想主义者,追求技术的完美与合理性,初⼼本不错,但也许现实需要更多的⾏动柔性。
51 | 技术债务,有意或无意的选择?
在编程的路上,我们总会碰到历史系统,接⼿遗留代码,然后就会忍不住抱怨,那我们是在抱怨什么呢?是债务,技术债务。以前说过,代码既是资产也是债务,⽽历史系统的遗留代码往往是⼤量技术债务的爆发地。
认知
技术债务,最早源⾃沃德·坎宁安(Ward Cunningham) 1992 年在⼀次报告上创造的源⾃⾦融债务的⽐喻,它指的是在程序设计与开发过程中,有意或⽆意做出的错误或不理想的技术决策,由此带来的后果,逐步累积,就像债务⼀样。
以前看过另⼀位程序员写的⼀篇⽂章,名字就叫《⽼码农看到的技术债务》,印象还是⽐较深刻的。⽂中把技术债务分成了好⼏类,我记得的⼤概有如下:
- 战略债务
- 战术债务
- 疏忽债务
战略债务,是为了战略利益故意为之,并⻓期存在。我理解就是在公司或业务⾼速发展的阶段,主动放弃了⼀些技术上的完备与完美性,⽽保持快速的迭代与试错性。在这个阶段,公司的战略利益是业务的抢占,所以此阶段的公司都有⼀些类似的⼝号,⽐如:先完成,再完美;优雅的接⼝,糟糕的实现。
战术债务,⼀般是为了应对短期紧急情况采取的折衷办法。这种债务的特点就是⾼息,其实说⾼利贷也不为过。
疏忽债务,这类债务⼀般都是⽆意识的。从某种意义上来说,这就是程序员的成⻓性债务,随着知识、技能与经验的积累,这类债务会逐步减少。另⼀⽅⾯,如果我们主动创造⼀个关注技术债务的环境,这类债务就会被有意识地还掉。
管理
对于技术债务,开发团队中的不同⻆⾊关注的债务分类与形态也不太⼀样。
⽐如架构师关注的更多是战略债务,保持系统能够健康⻓期演进的债务平衡。作为架构师,就像 CFO,需要⻓期持续地关注系统的资产负债表。战略债务可能更多体现为架构、设计与交互⽅⾯的形态。⽽具体某个功能实现层⾯的代码债务,则更多落在相关开发⼯程师的关注范围内。测试⼯程师,会关注质量⽅⾯的债务,⽽⼀到交接时,各种⽂档债务就冒出来了。
管理债务的⽬标就是识别出债务,并明了不同类型的债务应该在何时归还,不要让债务持续累积并导致技术破产。⼀般来说,只要感觉到团队⽣产⼒下降,很可能就是因为有技术债的影响。这时,我们就需要识别出隐藏的债务,评估其 “利率” 并判断是否需要还上这笔债,以及何时还。
清偿
⾸先,我们认识并理解了技术债务,识别出了系统中的各种债务,并搞清楚了每种债务的类型和利率,这时就需要确定合理的清偿还债⽅式了。
对于战略债务,⻓期来说都是持续付利。业务⾼速发展期保持付息,稳定期后⼀次性归还。
战术债务,因为利息很⾼,所以⼀般都是快借快还。⽽疏忽债务,需要坚持成⻓性归还策略,⼀旦发现过去的⾃⼰写下了愚蠢的代码,就需要主动积极地确认并及时优化,清偿这笔代码实现债务。
其次,还债时,我们主要考虑债务的⼤⼩和还债的时机,在不同的时间还债,也许研发成本相差不⼤,但机会成本相差很⼤。
除了技术债务的管理与清偿,我们还需关注技术债务与作为程序员的我们之间的信⽤关系,因为毕竟债务也是我们⽣产出来的。
信⽤
⽣产并拥有技术债务的程序员,并不代表其信⽤就差。
程序员的信⽤,更多体现在⾯对技术债务的态度和能⼒ —— 有意识地引⼊债务,并有计划地归还债务;⽆意识地引⼊债务,发现之后,有意识地归还。
52 | 选择从众,还是唯一?
想要取得成就,就会⾯临竞争,⼏乎所有的成就,都是直接或间接通过与他⼈的⽐较来评价的。理解了这样的评价与竞争关系,想要取得成就,出类拔萃,就意味着你要做出选择:选择从众、随⼤流,还是选择⼀条只属于⾃⼰的路?
不同的选择,意味着⾯临的竞争⽔平不同,付出的努⼒⾃不相等。
众争
有时,我们会下意识不⾃觉地选择从众,随⼤流;这样的选择往往给⼈更安全的感觉,但这样的选择也意味着更激烈的竞争。
先努⼒拉开差距,再去找到少有⼈⾛的适合⾃⼰的路。
稀少
2% 的⼈创造内容,⽽ 98% 的⼈消费内容;写作,就是这么⼀件少有⼈⾛的路。
写作本身就是⼀个关于选择的活动,⽽值得写的东⻄,本来也是稀少的。选择少有⼈⾛的路,通常也意味着你要⼤量地尝试,考虑⾃⼰的⻓处加上刻意的练习,虽不能保证成功,但却在创造可能性。
稀缺
稀少的事情,你可以有计划地去持续做;但真正稀缺的东⻄,⽐如:机会,却不会随时有。
独⼀
独⼀⽆⼆的路,要么是没有竞争的,要么是别⼈没法竞争的。
独⼀,可遇不可求;遇,也先得有遇的基础,它包括:异常的努⼒,不错的运⽓,⾮凡的能⼒,也许还有特别的天赋。
最后,总结提炼下今天的内容:
- ⾛众争之路,拼的是努⼒,只能成为平均的普通⼈;
- ⾛少有⼈⾛的路,拼的是选择、勇⽓和毅⼒,可以让你遇⻅独特的⻛景,为稀缺的机会创造可能性;
- ⾛独⼀⽆⼆的路,真的是要拼天赋了。
53 | 选择工作,还是生活?
随着⼯作⽇久,越发陷⼊⼀种关于⼯作与⽣活平衡的选择困惑。
处境
⼯作与⽣活的平衡,到底是怎样⼀种状态?
曾经我以为的平衡是这样的,我想很多⼈也这样以为过,⼯作与⽣活是完全隔离的。
每个阶段会有每个阶段的⽣活⽬标。刚毕业时,对我来说合适的⽬标应该是:⾃⼒更⽣,好好⽣存下来并获得成⻓。再之后⼏年,⽣活⽬标会进化到:恋爱成家。再往后,⽬标也随之发展为:事业有成,家庭幸福。⽽我当时的症结在于,错把平衡当作了⽬标,⽽实际平衡更多是⼀种感受。有句话是这么说的:
⼈若没有⽬标,就只好盯着感受,没有平衡,只有妥协。
认清⾃⼰当前阶段的⽬标,定义清楚这个阶段的平衡点。⼀个阶段内,就不⽤太在意每⼀天⽣活与⼯作的平衡关系,应放到整个阶段中⼀个更⻓的周期来看,达到阶段的平衡即可。通过短期的逃避带来的平衡,只会让你在更⻓期的范围内失衡。
作为个⼈,你需要承担起定义并掌握⾃⼰⽣活轨迹的重任,如果你不去规划和定义⾃⼰的⽣活,那么别⼈就会为你规划,⽽别⼈对平衡的处理你往往并不认同。
结合当下的处境与状态,没有静态的平衡,只有动态的调整。
关系
⼯作与⽣活的关系,短期的每⼀天总在此消彼⻓地波动,但⻓期,应该是可以动态平衡的;当从⻓期的视⻆来看待⼯作与⽣活时,会发现⼆者之间并没有那么明显的分界线。
⻓期的视⻆决定了,⽆论⼯作还是⽣活追求的都不应该是最后的⽬标或⽬的 —— ⼀种終点状态。你必须得关注过程,这个过程才是你的⽣活。所以,⽣活包括了⼯作,有时候甚⾄是⾮常艰⾟的⼯作。
⼯作就不过是⽣活的⼀部分,何必需要去平衡。与其去平衡两者,不如从整体⻓期的⻆度去选择⼀种平衡的⽣活。⼀段时间,也许你的⽣活中充满了⼯作;⼀段时间,你决定减少⼀些⼯作,去交交朋友,谈个恋爱。再⼀段时间后,有了孩⼦,你决定把曾经⽣活⾥的⼀部分,⽐如玩游戏,换成陪孩⼦玩游戏。也许你没法每⼀天都能做到这样⾃如地选择,但从⼀个⻓期的⻆度(五到⼗年)你总是可以选择的。
紧要的是,去过你想要的⽣活,⽽⾮不得不过的⽣活。
⽐例
选择⼯作在⽣活中的⽐例问题,是⼀个关于优先级和价值观的问题。从操作上来说,它其实是⼀个交易问题,关乎⾃⼰的所得和所失的交易。选择⼆者间的交换⽐例,意味着我们要进⾏权衡取舍,并为之承担相应的结果。
⼯作与⽣活的平衡⽐例选择,既然从操作上是交易问题,那么我们也就可以借⽤⼀下投资交易中的⼀种颇有启发的策略:年轻时,要更多投资于⻛险更⾼、波动更⼤、但潜在收益也更⼤的股权类权益;随着年纪⻅⻓,就要慢慢增⼤更稳定和确定的债券类投资⽐例,降低股权⽐例。
⽽且,这个策略还有⾮常具体的量化指标。就是⽤ 100 或 120 减去你的年龄来得到你应该投资股权的⽐例。⾄于到底是⽤ 100 还是 120,取决于你⼼理的⻛险承受能⼒和偏好。
把这个思路⽤在平衡⼯作与⽣活上的话,⼤概是这样,假如对于⼀个⾮常有事业⼼和野望的⼈(可以理解为⻛险偏好⼤的⼈),⼤学毕业平均是 22 岁,那么就应该是 120 - 22 = 98,也就是 98% 的精⼒花在⼯作上,当然这⾥是⼴义上的 “⼯作”。⽽对于那些刚毕业但没有那么⼤野⼼的年轻⼈,也应该投⼊⼤约 80%(这是⽤ 100 来减) 的精⼒在 “⼯作” 上。
对于这个策略,我的理解是早期的⾼投⼊,是为了将来需要更多平衡时,能获得这种平衡的能⼒。在我有限的⻅识和理解能⼒之内,我是认同这个⽐例的。⼀开始就想获得安稳与平衡,⼈过中年之后是否还能获得这样的安稳与平衡,感觉就⽐较靠运⽓。掌控⾃⼰能把握的,剩下的再交给时代和运⽓。
⼈⽣,就是在⻛险中沉浮,平衡的交易策略就是⽤来应对⻛险与波动的。
我们应该追求过好这⼀⽣,⽽⾮追求平衡,如何才算 “好”,每个⼈都会有⾃⼰的答案。我的答案是:不是通过努⼒⼯作来过上想要的⽣活,⽽是先设定了想要的⽣活,⾃然⽽然⼯作就会成为⽣活中合适的⼀部分。
末了,我总结下今天的内容:
- 缺乏真正的⽬标时,就只好盯着感受,把平衡当作了⽬标,由此带来了平衡选择的困扰;
- 不同的处境与状态,会有不同的平衡点,需要做出规划与选择;
- 短期只有此消彼⻓,⻓期才能动态平衡;
- 早期年轻时的⾼投⼊,换取将来平衡的能⼒与选择权。
六、寻路:路在何方
54 | 侠客行:一技压身,天下行走
从今天开始,我们进⼊了专栏的第 5 部分 —— 寻路:路在何⽅?这是⼀条关于⽅向、⻆⾊和⾃我定位的探索,那就让我们开始⼀起⾛⾛这条程序江湖路吧。
⼤约三年前吧,读到⼀篇⽂章《为何我⼯作⼗年,内⼼仍⽆⽐恐慌》,来⾃⼀位腾讯产品总监的演讲分享。⽂中分析了⼀个让其感到恐慌与焦虑的深层次原因:好像不会什么技能,技能⻔槛低。
这种恐慌和焦虑感在这个⾏业中普遍存在,不⽌于产品经理,程序员也⼀样。⼀些传统⾏业的⽣命已经远超过⼀个⼈的寿命,⽽ IT 互联⽹⾏业还不满三⼗岁,也许正是因为其还很年轻,⽣命⼒旺盛,远超传统⾏业的发展速度和新陈代谢规律,让其中的从业者深感疲惫,同时对未来⼜充满了不确定性,⽽未来的不确定性通常正是让我们感到焦虑的⼀个主要原因。
⻔槛
技能的⻔槛⾼低,决定了让我们产⽣恐慌和焦虑的⽔位线。
程序员职业其实是有⼀定硬技能⻔槛的,但这种⻔槛随着技术和⼯具的进步正在变得越来越低。如今 IT 互联⽹⾏业当然是繁荣的,繁荣的⾏业带来利差,⾃会吸引⼤量其他⾏业的从业者进⼊,⽽这些进⼊者⾃然会选择⻔槛低的职业⼯种来跨越边界。
程序员看似是很有技术含量的硬技能⻔槛,实际远不如医⽣这个千年来的 “古⽼” 职业,⾏业的最低技能⻔槛要求挡不住很多⼈热情地涌⼊,⽽技能成⻓的天花板也感觉并不⾼,如何能不恐慌与焦虑?
模型
之前看过⼀本武侠⽞幻⼩说,⾥⾯有⼀些⻆⾊就叫 “天下⾏⾛”,他们都有⾃⼰厉害的独⻔绝技,不厉害怎能天下⾏⾛。其中,剑客的剑快,野⼈的身体坚硬如铁,和尚从不说话修的闭⼝蝉,⼀开⼝就⼈⼈⾊变,这些就是他们独特的技能模型。
技能模型才是区分不同专业⼈才特点和价值的核⼼关键点。
⽽技能模型的形成是⼀系列选择的结果。⽽这种选择,可能⼀开始是⽆意的,⽐如我成为⼀名 Java 程序员是偶然的,⽽你成为⼀名 C++ 程序员也可能是偶然的,早期的技能点亮策略有很多的偶然性。但到了后期,我们逐渐成⻓,有了更多的经验和选择权,这时就需要主动选择去建⽴⾃⼰的技能模型。
以前⽂章写过关于 “知识体系”的内容,那它和技能模型有什么区别?知识体系本质也是⼀种知识模型,但技能模型更深⼀个层次,因为技能是对知识的应⽤。知识模型构筑了理论边界,技能模型是实践的路径。
路径
那么,关于技能模型这条实践路径该如何去选择和构建呢?
程序员作为⼯程师的⼀种,必须得有⼀项核⼼硬技能,这是需要⻓时间积累和磨练的技能,要花⼤⼒⽓的,⽽这个⼤⼒⽓和⻓时间,也正是这⻔技能的⻔槛。关于技能的习得有⼀个流⾏的看法是:花 20% 的时间快速获得某个领域 80% 的知识和技能。这看起来像是⼀种学习的捷径,但⼀个硬技能领域最核⼼的竞争⼒往往都是最后那 20% —— 也就是你⽤那 80% 的功夫反复磨练出来的最后 20% 的技艺。
我们⼤部分普通⼈,拥有的是有限的时间与才华,⾯对的是⽆限的兴趣和技能,同时修炼多个核⼼硬技能是不明智,甚⾄是不可⾏的。记得以前读万维钢有篇⽂章介绍了⼀本书叫《达芬奇诅咒》,⽂艺复兴时期的达芬奇是⼀位多才多艺的⼈,但⼀个⼈如果像达芬奇⼀样对什么东⻄都感兴趣,但⼜没有和达芬奇匹敌的才华,很可能尝试了很多,最终却⼀事⽆成,这就中了 “达芬奇诅咒”。
构建核⼼技能模型其实是关于才华和技能的战略。《达芬奇诅咒》⼀书作者就选择技能领域推荐了三个标准:
- 你确实喜欢
- 你在这个领域有天赋
- 这个领域能挣到钱
到这⾥,关于技能的焦虑和建⽴技能模型的⽅法,我们就探讨完了,最后总结提炼下:
- 程序员这⾏的技术⻔槛没想的那么⾼,所以就此易引发恐慌和焦虑;
- 建⽴你⾃⼰的技能模型,才能提升⻔槛和核⼼竞争⼒;
- 避开 “达芬奇诅咒”,围绕核⼼硬技能,发展”⼀主多辅”的技能模型树。
55 | 江湖路:刀剑相接,战场升级
回⾸⾃⼰的成⻓之路,通常每五年就会感觉碰到⼀个成⻓的瓶颈点。在传统 IT ⾏业的第⼀个五年后,我就感觉明显进⼊技术成⻓的瓶颈期;之后也算有点运⽓,通过转换到互联⽹⾏业升级到了新的技术维度。
⼜过了五年,站在⼗年后的⼀端,回望过去,⼑剑相接,如梦似幻,我渐渐感知到突破这次瓶颈的道路,就意味着⾛向⼀个升级后的新战场。
⼑剑相接:杀⼈术
⼀个程序员修成 “杀⼈术” ⼤概需要多久?按照⼀万⼩时理论,如果你在某⼀领域每天持续学习和实践练习⼗⼩时,最快也要三年。但这三年是没算各种可能的中断的,⽐如:⽣病、偷懒、假期休闲娱乐等等,所以⼤部分⼈的平均时间可能需要五年。
经历了⼀万⼩时的杀⼈术训练与实战后,技能增⻓曲线已经进⼊了对数增⻓的平缓期,过于单⼀的技术维度成为了我们的瓶颈和焦虑的源头,该如何去突破这样的瓶颈点?
认知升维:化形
爱因斯坦说过:”我们不能⽤制造问题时同⼀⽔平的思维来解决问题。”
技能维度的瓶颈问题,经常会让作为程序员的我们陷⼊⼀种常⻅的平⾯思维⽅式。
我们需要到更⾼的维度去寻找答案。⽽更⾼的维度就是认知的维度,所以⾸先需要的是升维我们的认知结构。
在我修⾏成术的过程中出现了好多新技术,当时我总想忙完这阵就抽空去学习了解下。但⼀过⼏年也⼀直没能抽出空去看,如今再去看时发现好些当年的新技术已不需再看了。五年成术是⽴⾜于⼀点,成⽴身之本;⽽下⼀阶段不该是寻找更多的点,⽽是由点及线、由线成⽹、由⽹化形。围绕⼀个点去划线,由⼀组线结成⽹,最后由⽹化成形,“化形” 表达了⼀种更⾼级的知识和技能运⽤形态,⽐⼀堆离散的知识技能点有价值得多。
⽽对于认知升维,由点及线、由线成⽹、由⽹化形,其实⾛的是⼀种 “升维学习” 之道。这个过程⼏乎没有终点,是⼀个持续学习、不断完善的过程,最终结多⼤的⽹,成什么样的形,全看个⼈修为。⼀条线⾄少要两个点才能画出,那么第⼆个点的选择就要看能不能和第⼀个点连起来了,⽽这⽐在⼀个维度上去预测和乱踩点要有效得多。
升维化形,化的正是技能模型,⽽这套模型基本决定了你的功⼒⾼低。
战场升级:⼗⾯埋伏
结⽹化形,⾛上升维之道,因⽽战场也变⼤了,但你的时间并没有增多,这就存在⼀个理论学习和战场实战的⽭盾。
到底是应该更宽泛地看书学习建⽴理论边界,还是在实战中领悟提升?关于这点,你需要选择建⽴适当的平衡,⾛两边的极端都不合适。在学校的学习更多是在建⽴理论体系,⽽在⼯作前五年的成术过程则更多是偏实战。
再之后的阶段⼜可能需要回归偏理论,提升抽象⾼度,从具体的问题中跳出来,尝试去解决更⾼层次、更⻓远也更本质的问题。⽽从更现实的⻆度来看,你的环境也会制约你能参与实战的经历,导致有些东⻄靠实战可能永远接触不到,不去抽象地思考是⽆法获得和领悟的。
“⼗⾯埋伏” 这样的技能维度显然⽐ “霸王举鼎” 要⾼出不少,⽽升维后的技能,也需要升级后的战场才发挥得出来。
技能的成⻓速度总会进⼊平缓阶段,并慢慢陷⼊瓶颈点,然后也许你就会感到焦虑;⽽焦虑只是⼀种预警,此时你还未真正陷⼊困境,但若忽视这样的预警,不能及时进⾏认知和技能升维,将有可能陷⼊越来越勤奋,却越来越焦虑的状态,结果⾛⼊”三穷之地”(包括如下三种”穷”):
- 结果穷:技能增⻓的边际收益递减;
- ⽅法穷:黔驴技穷,维度过于单⼀;
时间穷:年龄增⻓后你能⽤来成⻓的时间会变少,分⼼的事务更多,⽽且专注⼒会下降。
认知和技能升维带来新的成⻓收益,同时防⽌了单⼀维度的死胡同,⽽年⻓的优势正在于经验带来的理解⼒和思考⼒的提升。
最后,总结下今天的分享内容,在程序江湖上,从⼑剑相接到战场升级⾛的是这样⼀条升维路:
- ⼑剑相接的战场,我们靠 “杀⼈术” 也即硬技能求⽣存,但时间久了就会有瓶颈;
- 技能升维,需要认知结构先升维,”我们不能⽤制造问题时同⼀⽔平的思维来解决问题”;
- 升维后的技能,也需要⼀个升级后的新战场,⾛上理论结合实践的 “谋战” 之路。
56 | 御剑流:一击必杀,万剑归心
在前⽂《江湖路》中我找到的路是⼀条 “战场升级,技能升维“ 之路,技能与战场的升维演化是⼀个相辅相成的过程。进⼊了升级后的战场,也需要升维后的技能模型,那我们该如何从旧有的技能模型进⾏升维演化呢?
拔⼑斩
拔,提⼿旁,喻义需要亲⾃拔⼑动⼿。
⽽拔⼑术源⾃⽇本古武道,其核⼼思想便是⼀击必杀。
拔⼑术正是我们第⼀阶段的技能模型,在我们追求 “天翔⻰闪” 的境界时,看上去并不遥远,但越⾛到后⾯,却越来越慢了,似乎永远也到不了,这就是已经进⼊了第⼀阶技能的瓶颈区间了。
在瓶颈区中,进境缓慢近乎停滞,就可以尝试下技能升维 —— 从 “拔⼑” 到 “御剑” —— 看能否在新的战场找到突破点。
御剑术
御,双⼈旁,喻义贴身教授与把控。
御剑术,这个招数的类⽐来⾃好多年前(我那会还读初中吧)玩过的⼀个电脑游戏——《仙剑奇侠传》,我记得这也是游戏⾥主⻆在第⼆阶段学会的技能。如果过去⾯临问题你需要拔⼑解决,那这⾥的 “⼑” 就是你的知识、技能和经验。那御剑术⾥的”剑” ⼜是什么?
记得以前读过⼀篇关于⾼级程序员的⽂章,其中提出了⼀个组合三⻆的观点,先看下⾯这张图:
图中蓝⾊三⻆区域表明,随着你从⼊⻔初级成⻓到⾼级程序员的过程中,需要得到的帮助和指导越来越少;⽽红⾊三⻆区域表明,你能提供的帮助和指导应该越来越多。所在,在前⾯那个想象的 “泡⾯拔⼑” 的场景中,作为⾼级程序员的你,更理想的做法应该是去指导年轻程序员如何解决问题的思路,⽽不是⾃⼰拔⼑,唰唰两下搞定。
对,很多⾼级程序员都会以 “等把他教会,我⾃⼰早都搞定了” 为由,忍不住⾃⼰拔⼑。理解、掌握并应⽤好⼀种知识和技巧是你的 “拔⼑术”,但分享传递并教授指导这种知识和技巧才是 “御剑术”,⽽ “剑” 就是你⾯前更年轻、更初级的程序员。
从 “拔⼑术” 到 “御剑术”,其技能模型的招式和对象变化了,但本质框架却是类同的,这⾥的关键点是:如何剥离⾃我,通过他⼈来完成设计和实现,并达成解决问题的⽬标。
万剑诀
诀,⾔字旁,喻义以⾔引导,影响多于控制。
所有的程序员都是从修⾏ “拔⼑术” 开始,但只有极少数⼈最终⾛到了剑⼼ “天翔⻰闪” 的境界,所有未能突破的我们都进⼊了瓶颈停滞区。我们不断学习和练习,终于练到拔⼑由⼼,收发⾃如,终成习惯,但要将这个技能升维,跨越战场,却正是需要打破这个习惯。
其中,从 “拔⼑术” 到 “御剑术” 是习惯的打破;从 “御剑术” 到 “万剑诀” 则是量级的变化。因⽽,”御剑术” 是修⾏ “万剑诀”的必经之路。嗯,游戏⾥也是这么设定的。
“万剑诀” 正如其名,御万剑⽽破敌。回到现实中,这是⼀项⾼杠杆率的技能。⽽⾼杠杆率的活动包括:
- ⼀个⼈可以同时影响很多⼈。
- ⼀个⼈可以对别⼈产⽣⻓远的影响。
⼀个⼈所提供的知识和技能,会对⼀群⼈的⼯作造成影响。
这就是 “万剑诀” 的核⼼要诀。应⽤到程序员修⾏之路上:如果⾛上同时影响多⼈的路线,这就是⼀条团队管理和领导者之路;如果⾛上影响⻓远的路线,你可能乐于分享、传授,这可能是⼀条布道师的路线;如果你通过提供知识和技能来影响其他⼀群⼈的⼯作,那么这可能是⼀条架构师的路线。
“万剑诀” 和 “御剑术” 的共通之处在于都以⼈为剑,观察、揣摩每把剑的特性,先养剑再御剑最后以诀引之。若 “拔⼑术” 是⾃⼰实现的能⼒,那 “御剑术” 和 “万剑诀” 都是借助他⼈使之实现的⾃信和能⼒,只是后者相⽐⽽⾔规模更⼤,杠杆率更⾼。”万剑诀” 的重⼼在追求问题解决的覆盖⾯,⽽⾯临每个具体问题时就需要依赖每把剑的锋利度了。
另外,”御”之⼀字更着重了⼀层控制的含义,⽽ “诀” 之⼀字在于影响多于操控,这⾥⾯的关键点就是:剑本身的成熟度。不够成熟的剑只能 “御” 之,⾜够成熟的剑⽅能 “诀” 之。
拔⼑术,是亲⾃动⼿斩杀问题,难处在于维度单⼀,后期进境陷⼊瓶颈停滞;御剑术,是指导他⼈解决问题,难处在于打破习惯,剥离⾃我;万剑诀,是借助他⼈使之实现,难处在于剑的养成。
57 | 三维度:专业、展现与连接
曾经在和朋友探讨个⼈发展的问题时,讨论出⼀个 PPC 理论,该理论粗略地把涉及个⼈发展的⽅向分成了三个维度,包括:
- 专业 Profession
- 展现 Presentation
- 连接 Connection
⽽像程序员这样的专业技术⼈员,都倾向于在专业维度不断发展提升,却往往忽略了另外两个维度。如果三个维度综合发展的话,可能会得到 1 + 1 + 1 >> 3 的效果,即三个维度相加远远⼤于 3 的效果。
专业 Profession
什么才算是 “专业”?其实没有⼀个标准定义,我尝试将其进⼀步分解为三个⼦维度。
专业能⼒
专业能⼒,包含了知识和技能。以程序员为例,具备专业能⼒的软件⼯程师应该拥有系统的知识体系和相应技能。
专业⾏为
专业⾏为,包括规范化的⼯作流程和作⻛,严格的职业纪律与操守。
专业能⼒加上专业⾏为,会让你从周围的合作者那⾥得到⼀个做事很专业的评价。
专业产出
专业产出,指最终产出的结果是稳定的,可预测的,处在⼀定品质标准差范围内的。
所有技能维度的成⻓都是⼀条对数增⻓曲线,迟早会进⼊上升的平缓区,在这个区间 “投⼊增⻓⽐” 不⾼,这时就可以适当发展下后⾯两个维度,将会是不错的选择。
展现 Presentation
展现建⽴于专业的基础之上,所以展现也对应着专业的三个⼦维度。
- 展现专业能⼒:包括代码、架构、认知、决策;
- 展现专业⾏为:包括沟通、交流、表达、协作;
展现专业产出:包括作品、⽅案、洞察、演示。
对应这些展现的需求,有不同的展现形式,⽆外乎下⾯这些。
代码:Github 等开源站提供了最直接的围绕专业能⼒中编程能⼒的所有展现形式、证据和历史;
- 交流:在⽇常的即时通讯、邮件、会议、交谈与协作中,展现了关于专业⾏为的⼀切;
- 演讲:有关专业产出的重要形式,如汇报(业绩产出)、分享(作品与影响⼒产出);
写作:⽂字作品,⼀种⻓尾影响⼒的产出形式。
在⼤部分情况下,你的专业价值评估都是由你的展现⽔平来决定的。
连接 Connection
我把社交连接分成了 5 个圈层,⼀般每个⼈都会具备前两个圈层,⽽只有在展现的基础之上,才有扩⼤连接到后⾯三个圈层的可能性。
10
⼈⽣的每⼀个阶段,都会有⼀些最要好的朋友,也就是好朋友,这是我们社交关系中最强的连接了。⼀般这个数字都低于 10,⽽我⾃⼰的经历是,每⼀个阶段其实都没有超过 5 个。
50% 以上的社交时间都值得花在每个阶段最好的这 5 个朋友身上。
100
曾经熟悉的同学、同事们,⼤部分都在这个圈层中,除此,也会有⼀些当下新认识的熟⼈。总之,这个圈层中都是⼀些你们彼此还算认识,并且在⼀定程度上也彼此认同对⽅⼀部分价值的⼈。
以上就是⼏乎所有⼈都有的社交连接圈层。再往后的三个圈层,就只有极少数⼈拥有了。
1000
2008 年,著名科技作家凯⽂·凯利写了⼀篇⽂章《⼀千个铁杆粉丝》(1000 true fans),这⾥的 1000 连接圈层就是这么来的。
他⼤概是这么计算的,通过出售创作作品每年从每个铁杆粉丝上获取100美元的收⼊,那么每年⼤概有10万美元的收⼊,就⾜够⽣活了。今天,获得 1000 个粉丝不算太难,但在前⾯加上铁杆,就太难了。所谓铁杆,就是不论你创作的是什么,他们都愿意⽀付买单。
⽽我理解 1000 个铁杆也不必是固定的同⼀批⼈,可能是流⽔变化的 1000 ⼈,他们只是每年为你不同的作品⽀付买单⽽已,但前提就是你得有持续的创作能⼒。
10000
这个层次是拥有⼀万个关注者(如:微博)或订阅者(如:微信公众号)。
这个量级才算是拥有了培育⾃⼰观点和内容种⼦的⼀块⾃留地,在这块⼟地上你可以播下你的观点,可能有⼈⽀持,也有⼈反对,更多⼈是不置可否,但⾄少你可以开始拥有了反馈。但若没有这块⾃留地,你的声⾳或观点⼏乎不会在互联⽹上收到什么反馈,也⽆法形成有效的讨论和互动。
100000+
⾃从有了微信公众号,100000+ 现在也是⼀个神奇的数字了;100000+ 的存在,体现了⼀个信息、观点与影响⼒的传递⽹络。
五种连接圈层,第⼀层次 “10” 的连接是强连接;其他的都是弱连接,弱连接的价值在于获取、传递与交换信息。强连接交流情感,弱连接共享信息。
⽽建⽴连接的关键在于:给予。也许并不需要物质上的给予,仅仅是⼼理上或是虚拟的给予。所以说为什么展现是扩⼤连接的基础,展现即创作表达,创作即给予。另外,建⽴连接得先提供价值,⽽且还得源源不断。
关于 PPC 个⼈发展理论的分享就到这⾥了,我们总结⼀下:
- 专业,建⽴价值内核;
- 展现,提供价值输出;
- 连接,完成价值交换。
专业是价值,展现是⽀点,连接是杠杆。
58 | 三人行:前辈、平辈与后辈
孔⼦说:”三⼈⾏,必有我师”。原意中的”三”是虚数,泛指多⼈,意思是身边的任何⼈都可以成为你的⽼师,拥有值得你学习的地⽅。成⻓的路,本是⼀条越⾛⼈越少的路,但若有伙伴同⾏,你会⾛得更远,⾛得更久。
这就是成⻓路上的三⼈⾏,此时的”三”不再是虚数,⽽是指代身边的三类⼈,它们是:
- 前辈
- 同辈
- 后辈
这三类⼈代表了不同的成⻓路径和成⻓阶段。你应该有⼀个动态的列表,在成⻓的不同阶段将这三类⼈中的典型代表放在这个列表中仔细观察。
如果放在职场上,前辈可能就是你的上级,是⽐你更资深和有经验的⼈,是⾛在你前⾯的⼈;同辈⾃是你的同事,你们在不同的领域各有所⻓,甚⾄在同⼀领域做得⽐你还好,但不管怎样肯定是让你尊敬的⼈;⽽后辈可能是你的下属,他们也许正在⾛你曾经⾛过的路,可能正在做你⼀年、两年或三年前做过的事,⽽且可能做得⽐当时的你更好。
如果你在身边都找到了这三类⼈的典型代表,你观察他们,便是以他们为尺来度量⾃⼰;你学习他们,便是以他们为模来塑造⾃⼰;你加⼊他们,便是从后辈的重复中去反思过去,从同辈的领域中去扩展当下,从前辈的脚印中去引领未来。
前辈
前辈,是那些⾛在你前⾯的⼈,他们不⽌⼀个,且每个⼈都会有不同的路径。观察他们的路径,哪个更适合⾃⼰,哪个⼈的哪些⽅⾯让你更想要去模仿。在职场上,这些⼈似乎都有差不多的等级,但实际上每个⼈都有不同的特点和路径。
在不同的阶段,会有不同的前辈。⽽最适合作为前辈代表的⼈,应该在你前⽅不远处,因为这样的观察、模仿和借鉴才更有意义。毕竟⾛在你前⽅太远的⼈,他们的⾏为⽅式和路径你都很难看得清晰,⽽且很可能你们的⼯作活动已经处在不同的维度了,这阶段的你还理解不了。⽐如,刚⼊⻔的新⼿,适合观察和借鉴的前辈应该是⽐较熟练的中级⼯程师,⽽不是架构师。
前辈的价值在于:他们⾛过的路,你不⽤再去摸索,只需快速顺着⾛下去。
⼗多年前,我以为程序员的成⻓终点是架构师,后来我知道了,程序员的⾃然连续成⻓终点是资深程序员,也许还有 “神” 级程序员。但架构师却是从某个点开始断裂分叉的另⼀条路,从程序员到架构师,就需要跨越⾮连续性断点,⽽转型到技术管理者也会⾯临同样的⾮连续性断点。
前辈的另⼀个价值在于塑造环境,⽽环境决定了整体的平均⽔平线,在这个环境中的个体很少有能⼤幅偏离的。在⼀个既定环境中,有强悍的前辈是我们的好运⽓。
同辈
同辈,本是那些与你并⾏前进的⼈。
同辈,特别是临近的同辈间普遍存在竞争,这也是所谓的 “同辈压⼒” 的来源。⽽很多时候我们的进步就是被这种压⼒逼出来的,这样压⼒转化为动⼒,同辈就成为了动⼒源。
每⼀个同辈都可以拥有⾃⼰独特的领域,他们之间得以互相观察,并能相互沟通、交流与合作。
领域,是⼀个你⾃⼰的世界,在这个世界中,你不断地提出问题并找到有趣或有效的解决⽅案。进⼊这个世界的⼈,碰到的任何问题,你都解决过或有解决⽅案,慢慢地⼈们就会认识到你在这个世界拥有某种领域,并识别出你的领域。然⽽,计算机专业毕业的程序员们,⼈⼈都拥有专业,但⼯作⼗年后,不是⼈⼈都能拥有领域。
同辈,除了竞争,也有碰撞与交流,它会成为你的催化剂。
后辈
后辈,他们正沿着你⾛过的路直⾯⽽来。
⼈,似乎不犯⼀些错,就成⻓不了,也许这就是成⻓的成本。
成⻓路上三⼈⾏,有前辈、同辈和后辈。前辈塑造环境,开辟道路,留下脚印;同辈之间有竞争,也有交流与合作,既带来压⼒,也激发动⼒,催化能⼒;后辈带来反思,也提供⽀持。
前辈探路开拓,同辈携⼿并⾏,后辈参考借鉴。
59 | 三角色:程序员、技术主管与架构师
还记得开篇词中我画了⼀个程序员的成⻓路径图,其中在图的左侧部分展示了程序员成⻓路径上⼀些主要阶段的定义,在我们从初级⾛向资深的过程中,会⾯临⼀条⽀路,在这条路上不仅普遍称呼的名称不同了,⼯作内容可能也发⽣了变化,⻆⾊的转换会带来不少的困惑。
这条路就是从 “程序员” 到 “技术主管” 再到 “架构师” 的路径,下⾯我们就来看看这条路径上的三个⻆⾊有何不同?
程序员与寻路
当我刚进⼊软件⾏业成为⼀名程序员时,我的理想就是成为⼀名架构师。
作为资深程序员出身的架构师,单兵作战能⼒都是极强的,就像《进击的巨⼈》中的利威尔兵⻓,具备单挑巨⼈的能⼒。可当⾯对成群结队的巨⼈来袭时,个⼈单挑能⼒的作⽤始终有限。
这时,从程序员到架构师不仅仅是⼀个名称的变化,它也意味着技能和视⻆的转变。
是的,我是到了资深程序员阶段直接转向了架构师。⽽在路径图上还有另⼀条路,会经历另⼀个⻆⾊:技术主管,这是⼀个从程序员到架构师阶段的过渡⻆⾊。
技术主管与过渡
技术主管,有些公司可能⼜叫 “技术经理”,英⽂⼀般是”Tech Leader”或简称”TL”。
技术主管是开发团队中的某位程序员需要对整个开发团队负责时所承担的⻆⾊。既要对最终交付的软件系统负责,另外也会像⼀个程序员⼀样去开发实现系统。⼀般⼀个技术主管约 70% 的时间可能花在了开发任务分解分配、开发实践、代码审核和⻛险识别上,⽽余下 30% 的时间则花在为了保障系统按时交付所需要的各种计划、协作、沟通和管理上。
在拉姆·查兰 (Ram Charan) 写的《领导梯队》⼀书中提到:⼀个⼈的⼯作⻆⾊中⾄少有百分之五⼗以上的时间是花费在管理事务上,那么他的⻆⾊才算是⼀个经理(Manager)。所以技术主管(经理)更多还是偏重于技术⼯作,有点类似产品经理属于以经理命名却⾮真正的经理⻆⾊。
例如:在⼀个开发团队中经常会碰到技术⽅案和实现细节⽅⾯的分歧,如果程序员⽆法⾃主友好地完成对不同技术意⻅的统⼀,这时候技术主管就需要介⼊去了解两种不同意⻅所造成的冲突,对事不对⼈地去把问题搞清楚,分析各⾃⽅案的利弊,必要的时候甚⾄能够提出第三种更好的技术⽅案,以帮助开发团队达成共识。
另⼀⽅⾯,技术主管即使在⽇常的开发实现中,重点的内容⼀般也不是放在某个具体的功能实现上。在完成了具体的开发任务评估、分解并分配后,技术主管应该负责设计整体代码的结构和规范,必要时引⼊能提⾼整个团队⽣产⼒的新⼯具,推⼴代码模板,总结最佳实践。并且技术主管需要经常性地关注整个团队完成⼀项研发任务的⽔平和实际要求的⽔平之间的差距问题,让团队不仅满⾜及时的软件系统交付,同时⼜得到成⻓。
现实中,⼀个开发团队中最优秀的程序员容易被指定承担技术主管的⻆⾊,但优秀的程序员⼜很容易陷⼊到实现功能的细节中,满⾜于完美的实现,优雅简洁的代码。但实际上,这样优秀的程序员转⼊技术主管这个⻆⾊后,就很容易尝试控制设计和代码的实现,他们很难接受代码不按照他们希望的⽅式去编写,这个是他们作为优秀程序员⼀直以来的⼯作习惯,⻓此以往他们⾃身很容易变成整个开发团队的瓶颈,⽽团队⾥的其他成员也未能得到⾜够的锻炼和成⻓。
所以技术主管实际相⽐团队⾥的其他程序员对系统的视⻆更开阔,以更有策略和⻓远的⽅式来考虑问题。他们即使拥有⽐团队⾥所有其他程序员更⾼超的开发实现技能,对所有开发任务拥有最强⼤的实现⾃信,也需要转变为另⼀种 “借助他⼈使之实现” 的能⼒和⾃信,因为技术主管是⼀个承担更⼴泛责任的⻆⾊,必然导致能够专注有效编码的时间会相⽐以前减少很多,⽽这⼀点正是优秀程序员转变为技术主管所⾯临的最⼤挑战之⼀。
最适合技术主管⻆⾊⼈,不⼀定是团队中编程能⼒最好的⼈,但必然是团队中编程、沟通和协作能⼒最综合平衡的⼈。⽽技术主管之所以是⼀个过渡,就在于继续往前⾛,如果偏向 “主管” 就会成为真正的管理者(经理),如果偏向 “技术” 就会⾛向架构师。
架构师与取舍
架构师是⼀个在业界拥有知名的称谓,但在绝⼤部分公司却不属于⼀个职位序列,许多公司都很纠结于如何定义架构师的⻆⾊,以及架构师所做的⼯作。
前⾯我在 31 | 画图:一图胜千言 中引⽤过⼀篇⽂章《在⾸席架构师眼⾥,架构的本质是…》中提到的架构师能⼒模型图,我结合⾃⼰的经验和理解,稍微扩展解释了⼀下,如下:
看过了架构师的能⼒模型,我们再来试着分析下其对应的职责。技术主管的⻆⾊与架构师这⼀⻆⾊会产⽣⼀些职责上的重叠,事实上我认为在团队规模⽐较⼩的时候(⼗来⼈的规模),架构师和技术主管的职责⼏乎完全重叠,甚⾄技术主管还会代理⼀些团队主管的⻆⾊。
随着软件系统复杂度和规模的提升,团队也相应变⼤,那么⼀个架构师此时所处的职责位置就开始和技术主管区别开来。如果把技术主管想成是站在楼顶看整个系统,那么架构师此时就是需要⻜到天上去看整个系统了。
架构师站在更⾼的空中维度去做关于软件系统的抽象和封装。如果技术主管的抽象和封装层次更多考虑的是语⾔函数、设计模式、代码结构等这⼀类的事务,那么架构师是站在整体软件系统⾼度,考虑不同⼦系统之间的交互关系、技术的合理性、需求的完整性、未来的演进性,以及技术体系发展与组织、产品商业诉求的匹配度。
这是相对技术主管更⾼维度的全局视⻆,另⼀⽅⾯依然有很多技术主管可能感觉没把握的技术决策和技术争端需要架构师的介⼊协调。之所以要找架构师来对⼀些技术争端和⽅案进⾏决策判断,很多情况在于程序员对架构师在技术领域内专业⼒和影响⼒的信任,⽽建⽴这种专业⼒和影响⼒是实际构建架构师⾮权威领导⼒的来源。
何谓 “⾮权威领导⼒”?⾮权威⾃是相对权威⽽⾔,管理者的权威领导⼒来⾃于公司正式任命的职位和职权,⽽架构师在⼤部分公司基本连职位职责都没定义清楚,更没有职权⼀说,所以实际上就不会有任何权威领导⼒。所以,架构师要发挥更⼤的作⽤和价值就需要去构建⾃⼰的⾮权威领导⼒,⽽这需要⻓期的专业⼒和影响⼒积累。
除此之外,架构师还承担着在技术团队和⾮技术团队(例如:产品设计等团队)之间的接⼝作⽤,明确产品的边界,勾勒技术蓝图,协调不同技能的技术团队协作,完成最终的软件系统交付。这时架构师的⻆⾊就像服务化架构中的 API,定义了协作规范、交互协议和⽅式,但并不会聚焦在具体的实现上。
在更⼤规模的系统上,架构师似乎还要去涉猎更多的跨领域知识,否则很可能⽆法做出最适合的技术决策。但⼈终究是有局限的,你不可能学完所有的领域,所以特定的领域⼜会涌现⼀些垂直领域的架构师。⽐如:数据架构师、⽹络架构师、业务架构师、安全架构师。因⽽某⼀个领域背景出身的架构师,对其他领域也只能做个初步了解,当需要做出关于涉及其他领域的架构决策时,就需要和其他领域的垂直架构师做深度的沟通交流,以辅助决策判断。
⼀旦选择⾛⼊架构师这条路,基本你就从⼀名出⾊的程序员这个领域⾛出,需要尽快去补充上⾯能⼒模型中指出的其他能⼒。这⼀点会让刚刚⾛上这条路的程序员很不适应,因为承担了更多其他职责,就必然会减少在编码实现的时间,慢慢就会怀疑⾃⼰的编码能⼒会退化,也跟不上⼀线最新的技术栈、各种酷酷的新⼯具。
舍得,舍得,没有舍就没有得。成为架构师会拥有⼀个更⽴体的知识、技能矩阵,这是你的得,获得了⼀个⾯,在某些点上必然⾯临被超越的结局。⼯作在⼀个⾯上,⼀个有经验的架构师应该能够很好地表达某些技术指导原则,借助他⼈使之实现,并且了解和把握什么时候该插⼿,什么时候该放⼿。
这就是架构师从技术 “实现⼒” 到 “掌控⼒” 再到 “决策⼒” 的能⼒变迁。
从程序员,到技术主管,再到架构师,名称变化了,⻆⾊的困惑我们也分析了,最后总结下这三种⻆⾊的⼯作内容和职责,如下表:
每种⻆⾊有不同的技术和组织职责,只是在每种职责分配的时间⽐例不太⼀样。看完上表的职责范围,是不是感觉有时安安静静地做个程序员,要⼼净多了。
60 | 三视角:定位、自省与多维
记得以前阅读时碰到过⼀个观点,是关于 “视⻆” 的,其中说道:”视⻆的选择,对解题的难易,关系重⼤”。⽽关于成⻓,放到程序模型中来类⽐,就是⼀道图论题,我们求解的是适合⾃⼰的最优路径。
⾯对这道成⻓路径的难题,我们可以从哪些视⻆来求解?我⾃⼰找到了下⾯三个视⻆。
定位
定位,是⼀个时间视⻆,回顾初⼼,定位未来。
程序员的⼯作实际更贴近于⼯匠,既有创造性的⼯艺性⼯作,也有模式化的⼯程性⼯作。想清楚⾃⼰成为程序员的初衷是什么?如果只是为了进⼊⼀个相对⾼薪的⾏业,得到⼀份⼯资⾼于平均⽔准的⼯作,终究是⾛不了太远的。
⾃⼰才是职业⽣涯的管理者,要想清楚⾃⼰的发展路径:远期的理想是什么?近期的规划是什么?⽽今⽇的任务和功课⼜是什么?今⽇之任务或功课哪些有助于近期之规划的实现,⽽近期之规划是否有利于远期之理想?
定位的视⻆,是关于⼀条成⻓的时间路径,它关乎:昨⽇初⼼,今⽇功课,明⽇机会。
⾃省
⾃省,⾃我的视⻆,关乎⾃身,是⼀个观察⾃⼰成⻓路上⾏为的⻆度。
如果你想要学习⼀⻔新技术或在项⽬中引⼊⼀项技术,就可以试试套⽤ “海尔迈耶系列问题” 来⾃省⼀番。
- 你学习这项技术的⽬标是什么?清晰地表述出来。
- 这项技术现在是怎么做的?有什么局限吗?
- 这项技术有什么创新之处?为什么它能够取得成功?要是在项⽬中引⼊这项技术,谁会关⼼?
- 如果这项技术能成功,会带来怎样的变化?
采⽤这项技术的成本、⻛险和收益⽐如何?你需要花费多少资源(时间、⾦钱)?如何去评估它的效果?
程序员有时粗浅地学习并了解了⼀点新技术,就想着如何应⽤到真实的项⽬中。这时⽤上⾯的问题来问问⾃⼰,如果有回答不上来的,说明你对这项技术掌握并不充分,那就还不⾜以应⽤到实际项⽬⾥。
除了技术领域,你成⻓路上的许多⾏动,都可以此为参考坐标来反思:”这项⾏动的⽬标清晰吗?⾏动的⽅法有可参考的吗,局限在哪?我能有何创新之处?完成这项⾏动,会给我带来怎样的变化?我要付出多少时间、⾦钱和精⼒?⾏动过程中我该如何评估?⾏动结束的标准是什么?”
这就是 ⾃省,从埋头做事,到旁观者视⻆的⾃我反思 。
多维
多维,是⼀个空间视⻆,关乎如何选择不同维度的成⻓路径。
有些时候,程序员写了⼏年代码,觉得太枯燥乏味,就想着是不是可以转管理,⽐如转技术主管之类的。从技术到管理似乎就是⼀条多维度的发展路径,是这样吗?不是的,这不叫多维扩展,⽽仅仅是想从⼀个维度逃离,转换到另⼀个维度。
打造多维度竞争⼒的前提是,要先在⼀个维度上做得⾜够好,让其成为你赖以⽣存的维度,这个维度就是你的核⼼基础维度,⽽它是其他维度得以发展的根基。其中,”⾜够好”的程度,可能就是指我们常说的 “精通”。
关于”精通”的概念,每个⼈的理解可能会有所不同,但我认为”精通”肯定不是⽆所不知,⽽是可以拆解成两个层⾯:第⼀,如学校时期学过的卖油翁所说的”⽆他, 惟⼿熟尔”;第⼆,在⼀个领域形成⾃⼰的体系和⽅法论。
第⼀个层⾯,表达了在当前维度的不断精进,在精进这个⽅向上,有⼀本书和咱们专栏主题类似,但更微观⼀些,偏向于 “术”的层⾯,但⼜有点从 “术” 悟 “道” 的意思。这本书叫《程序员修炼之道:从⼩⼯到专家》,书⾥覆盖了⼀名程序员真正⾯临的⼀些问题,⽐如:
- 与软件腐烂作⽃争
- 避开重复知识的陷阱
- 编写灵活、动态、可适应的代码
- 使你的代码 “防弹”
- 捕捉真正的需求
- ⽆情⽽有效的测试
⽆处不在的⾃动化
这些具体问题的解法,就是第⼀层⾯。然后逐步上升到了第⼆层⾯,它的⽅法体系,⼀篇书评中将其称为本书的 “哲学”:
本书的哲学将渗⼊你的意识,并与你⾃⼰的哲学交融在⼀起。它不⿎吹,它只是讲述什么可⾏,但在讲述中却⼜有更多的东⻄到临,我们有时称之为 “⽆名的品质(Quality without a name)”。
当这些问题倒下⽽你还在程序员的阵地上时,想必你就会让⼈感受到那种 “⽆名的品质”,此时你也就在当前维度⾛到了 “精通”的⻔前。在第⼀层⾯上你达成了品质和效率,然后在第⼆个层⾯上,抽象出了当前维度的 “解”,那么就可以通过 “启发式” ⽅法应⽤到其他维度,具备了向其他维度扩展的基础,从⼀个细分领域到另⼀个关联领域的 “精通” 能⼒。
所谓 “启发式” ⽅法,就是 “在某个视⻆⾥,使⽤这个规则能够得到⼀个解,那么你受此启发,也许可以把这个规则⽤在别的问题上,得到别的解”,⽽规则就是你在⼀个维度⾥抽象出来的⽅法论体系。
简⾔之,多维的路径,其实是从⼀个核⼼基础维度去扩散开的。
最后,我们总结下,在求解成⻓的最优路径时,视⻆的不同,对求解的难度差别巨⼤。我分享了我的三个视⻆:定位,时间视⻆;⾃省,⾃我视⻆;多维,空间视⻆。
七、蜕变:破茧成蝶
61 | 工作之余,专业之外
程序员的主流成⻓发展路线,是⼀个明显的”T”形线路。在纵深⽅向上,⼯作到⼀个阶段后,可能我们就会感到深⼊不下去了,⽽且越⾛会越有沉滞的感觉;在横向上,是⼴度⽅⾯,包括技术专业之外的领域,也会感觉了解甚少,短板明显。
有时候,要想产⽣真正的成⻓转变与发展突破,就不应⾃我局限于当下的⼯作内容和技术专业。
⼯作之余
⼯作,是技术发展纵深线中很重要的⼀个实践部分,但因为⼯作的内容和环境的限制,会把你困在⼀定的阶段,此时⼯作之余的内容将发挥很关键的作⽤。
即使再忙,有些⼈就喜欢在业余时间做点事情,这可能是⼀种性格特质,拥有这种性格和热情的⼈,总是能在忙碌的⼯作之余安排点其他内容,⽐如:
- 看看程序设计相关的书、⽂章和博客;
- 参加⼀些技术主题论坛或会议;
- 写写技术博客;
创建⾃⼰的业余项⽬(Side Project)。
以上前两条是接收和学习知识,第 3 条是总结和提炼知识,最后第 4 条则是实践所学,获得新的技能或加强旧的技能经验。
在做业余项⽬中最⼤的收获是:完整地经历⼀次创造。
专业之外
专业是你的核⼼领域,⽽专业之外则是你的辅助领域;核⼼属于硬技能领域,辅助属于软技能领域,这也是”T”线中的横向延伸部分。
那么该怎样选择辅助的软技能领域呢?如果你的⼯作之余是在做⼀件业余项⽬,那么我想下⾯⼀些领域就是你在做业余项⽬之时更感缺乏的技能。
创造与洞察
⼯程师,是⼀个创造者,创造模型来解决问题,但⼜不应该⽌步于此。
你的业余项⽬是你的作品,作品是创造出来的,按作品原始的需求是满⾜了作者创造的愿望,但业余项⽬要能取得成功就需要得到真正的⽤户,⽽获取⽤户就需要洞察,洞察⽤户的需要。
我记得以前读过⼀篇博⽂,来⾃著名 JavaScript 程序员尼古拉斯·泽卡斯(Nicholas C.Zakas,《JavaScript⾼级程序设计》⼀书作者),他写了⼏条职业建议,其中第⼀条就是:
不要成为做快餐的 “厨师”。
也就是说,不要像外卖接单⼀样,别⼈点什么,你就做什么。应该搞清楚你正在做的事情的价值和出发点,你不仅仅是实现代码,还要想想为什么要实现它。当你多想了后⼀步,在实现的过程中就会有更多的洞察。
开启过⾃⼰业余项⽬的程序员,已经⾛出了 “创造” 这⼀步,但多数还是失败在 “洞察” 这⼀点上。
表达与展现
安安静静地写代码固然是不错的,但代码很多时候没法很直接⽅便地展现出你的真实能⼒和⽔平。
如果你的代码能给你作证,只有⼀个可能场景,那就是找到了⼤量直接使⽤你代码的⽤户,这就是成功开源作品的⽅式。否则,⼤部分时候你只能说你⽤代码完成了什么事情,做出了什么作品。
如果,你有好作品,就值得好好地展现,甚⾄还要不遗余⼒地推销它。
沟通与决策
⼀个⼈的能⼒再强,也是有限的。当你想做更多、更⼤的事情时,就不可避免地要借助他⼈的⼒量,这时所⾯临的就将是⼤量的沟通了。
沟通⼀般有两个⽬的:⼀是获取或同步信息;⼆是达成共识,得到承诺。前者需要的是清晰的表达和传递,后者就需要更深的技巧了。这些技巧说起来也很简单,核⼼就是换位思考、同理⼼,外加对⾃身情绪的控制,但知易⾏难在沟通这件事上体现得尤其明显。
即使是⼀个坏的决策也⽐始终不做决策要好,因为在⾏动的过程中⽐”陷”在原地有可能产⽣好的改变。
最后总结下:⼯作之余你可以有多种选择,但若被⼯作环境所困,导致专业⼒进境阻碍,可以开启业余项⽬来突破这种限制;⽽业余项⽬带来的诸多益处,从此也为你⾛向专业之外打开了⼀个新的视⻆与空间。
⼯作之余,专业之外,就是⼀条”T”线纵横交错发展的路线,当两条线都画得⾜够⻓了,在⾯临成⻓路上的断层时,才有机会与可能实现跨越。
62 | 跨越断层,突破边界
在程序员的成长阶梯上,到了一定阶段,我们可能会面临方向的选择,不同的方向选择意味着不同的路径,会碰到不同的断层,而跨越断层也需要不同的方法。
那我们会面临怎样的方向选择呢?
方向
在我的技术成长路上,我看到了三个方向,正好可以用三个字来表达:“高””精””尖”。
“高” 指的是 “高级(High-grade)”,”精” 代表 “精确(Precision)”,而 “尖” 则是 “尖端(Advanced)”。这是我所看到的技术人前进的三个主要方向,而这三个方向的走向往往还是互斥的。
高级,说的不是更高级的技术,因为技术之间的横向比较没有高低级之分。这里的”高级”,如其英文是更高等级的意思,是职位和人的级别。而往高等级走的技术人,离 “精” 自然只能越来越远,毕竟站的高就只能看得广,但很难看得精确了。
精确,就是把一门技术做到真正的精通。现在技术的分工越来越细,通常能精通一两个细分领域已实属不易。而要做到精,其实越往后付出越多,但感觉提升却变得越来越慢。都到 95 分了,再往后每提升 1 分都需要付出艰辛的努力。走到细微深处,也很难再看得远、看得广了。
尖端,似乎听起来像 “精” 的极致,其实不然,这完全是另一条路。”高” 与 “精”,是工业界的实践之路,而 “尖” 是理论界的突破之路。只有能推进人类科技进步的技术才称得上尖端,就如 IT 界历史上著名的贝尔实验室里的科学家们做的工作。
“高” 是往宏观走,”精” 是往微观走,”尖” 是去突破边界。
这三条路,”高” 和 “精” 的方向在业界更常见,而 “尖” 不是工业界常规的路,毕竟业界拥有类似贝尔实验室这样机构的公司太罕见,所以 “尖” 的路线更多在学术界。因而后面我们主要探讨 “高” 和 “精” 两个方向的路径断层与跨越方法。
高
高的两条典型路线如下:
- 程序员—架构师—技术领导者
程序员—技术主管—管理者
往高处走,每一次角色的转变,都是断层。有时候,公司里到了一定级别的程序员就会被冠以架构师的称呼,但工作的实质内容依然是资深程序员平时做的事,如:一些关键系统的设计和实现,解决一些困难的技术问题。
这些工作中的确有一部分也算是架构师的内容,但如果不能认识到架构师工作内容的实质,再往高处走也就很难实现断层的跨越了。而架构工作的实质是创造一个模型,来连接、匹配关于业务、技术和团队之间的关系。
其中的 “业务” 属于架构师工作内容中的领域建模;”技术” 是匹配领域模型的技术实现模型;”团队” 是关于个体之间如何组合的结构,需要满足个体技术能力与技术实现模型的匹配。由这三个元素连接和匹配构成的模型中,”业务” 是变化最频繁的,其次是 “团队”,而变化频次最低的反倒是 “技术”。
每一项元素发生变化,都意味着架构模型需要去适应这种变化,适应不了变化的模型就需要升级。而常见的组织架构调整,也就意味着 “团队” 的沟通路径变化了,因为康威定律(系统设计的通信结构和设计系统的团队组织的沟通结构是一致的)的缘故,必然带来架构模型的适应性变化调整。
透过具体的实质再往高处抽象到本质,你会发现架构工作的本质是在通过模型调优生产关系,从而提高生产效率和生产力。这是一条杠杆之路,通过找到其中的关键支点去放大输出,扩大价值。
在架构模型三元素中,技术本身就是一种杠杆,而团队和业务是价值支点。
而另一个价值支点,是借助团队,但这只适合高级别的技术人员,比如:技术管理者或架构师。但团队也需要能创造真正的价值,才能实现利用杠杆放大价值的效果。在商业环境下,任何一种产品业务形态,其最终能实现价值,都会存在一个价值网络。这个网络中覆盖了各种角色,技术只是其一,若要找到最好的价值支点,那么通常会在离价值来源比较近的地方。
精
精的路线是一条 “专家” 之路。
曾经在前文《定义:阶梯与级别》中定义过 “专家”,我说:专家可能就是某个领域中你绕不过去的人吧。这个定义中包含两个点,一个是领域,另一个是绕不过去。第一点表达了某个范围,第二个则模糊地表达了这个范围的大小,绕不过去其实是一个很大的范围了。
走向专家之路,就是精确地找到、建立你的领域,并不断推高壁垒和扩大边界的过程。
那么如何建立属于自己的、更大范围内且具备足够识别性的领域?这就是 “精” 的路径中的非连续性断层问题。曾经读过一篇吴军的文章,谈到了工程师成长中的类似问题,他用了一个公式来描述解法:
成就 = 成功率 x 事情的量级 x 做事的速度
在连续的成长阶段,我们的成长主要体现在不断提升做事的熟练度,也就是上述公式中的速度和成功率,但这两个指标到了一定的熟练度阶段后就会碰到物理极限。实际情况是,一个资深的工程师的速度甚至不会比一个初级工程师快两倍,但可能成功率会高几倍,甚至十倍,这就是传说中的一个顶十个的程序员,但离极限也就差不远了。
而要成为传说中以一敌百的程序员,只有一个可能,他们做的事情和其他人不在一个量级上。现实案例中,就有如 Linus 这样的人。所以,一直做同样的事,都是写代码,也可以跨越断层,但关键是,你写的代码体现在什么量级的事情上。
之前在工程思维中总结过:问题的量级变了,逻辑就不一样了。作为程序员,我们会有直观的感受,用户量级越过了一定的门槛后,我们编写、维护和部署程序系统的方式都会发生本质的变化。而提升量级最难的就在于我们要放下曾经熟悉的方式和习惯,站在更高的维度去看更大量级的事情,并且找到适合这个量级事情的合适解决方案。
面临成长路上的非连续断层,以及角色之间的无形壁障,该如何跨越断层,突破边界?我们着重从成长路线的两个方向:”高” 和 “精”, 提供了分析和解法。
- 高的路线,需要借助技术的杠杆,认清所处的价值网络,找到合适的价值点,撬动更大的价值;
- 精的路线,在做事情的成功率和速度接近自己的极限后,只能去提升事情的量级,才能发挥出专家的价值。
63 | 成长蓝图,进化跃迁
回顾过去,我们会清晰地看见走过来的路线,但面向未来我们又该如何走下去?但凡过往,皆为序章,过去不可变,未来才是希望,而如何去规划并管理好未来的成长进化之路,才是我们当下要面临的主要任务。
我们先从一个高度抽象的维度,来看看这条成长之路。
成长路线
结合我自己的经历、思考与总结,我对走过的路和未来的路概括成如下这张图:
图中描述了好几个阶段,从一个阶段到下一个阶段,都会经历一次转折。
开发代码(Develop Code)
从刚走出学校到进入职场成为一名新手程序员,在最初的一两年内,你可能都处在这个阶段。不停地大量写代码,为各类系统的”大厦”添砖加瓦,像块海绵一样,把自己吸得满满的,朝 9 晚 24 地工作与学习,并不时自嘲为 “码农”。
这个阶段,你为生存所需(迫),会强烈地渴望成长。
开发系统(Develop System)
三、五年后,你可能从初级、中级成长到了高级,此时你不再仅仅是写代码搬砖,而是开始负责起或大或小的整个系统。这时,你最关心的是如何用最好的技术方案,去开发、优化和完善系统。
开发产品(Develop Product)
从高级走向资深、专家或架构师,你会发现你的技术执行技能已经优化到了相当的程度,这时往前多走一步,关注你所实现的系统所属的产品,会让你打开新的空间,找到更有效率和效果的实现路径,减少做无用功。
而且在技术的世界里,有很多面向开发者的技术型产品,这个领域中最适合承担起产品经理角色的就应该是各类资深的技术专家和架构师了。
开发团队(Develop Team)
当你选择走上技术主管并转变为一名管理者,那么人和团队将成为你的主要开发对象,而不再是代码了,这是成为管理者的必经之路。
开发梦想(Develop Dream)
梦想这个东西也会随着岁月与你相伴成长,梦想实际永远在前方,它只是不断引领着你往前走。梦想相对而言是一个感觉上很 “虚” 的概念,它可能需要产品作为载体,也需要团队来一起开发创造。如此,梦想的引力就会引发你向一名创新者或领导者的方向进化跃迁。比如说,十多年前,刚毕业时,我的梦想是成为一名架构师,如今已然实现。
战略蓝图
战略这个词,通常会和组织、公司关联在一起;那假想下,如果个人是一家公司,那么这家 “公司” 的战略该如何确定?
在分析战略之前,我们需要先分析下公司的业务。为了更好地分析清楚公司的主要业务,这里借鉴下咨询公司爱用的商业分析模型:波士顿矩阵。实际有很多不同的分析模型,我只是觉得这个最简单,比较适合像个人这样的小小微 “公司”。
波士顿矩阵模型,把公司业务分成下面四类:
现金牛业务,比较形象地表达了就是产生现金的业务。比如谷歌的搜索业务、微软的 Windows 操作系统,都是它们的现金牛业务,有很高的市场占有率,但成长率相对就比较低了。
就个人来说,现金牛业务自然是一份稳定的工作,产生现金,维持个人生活的基本面,当然稳定之外越高薪越好。程序员这个职业就是很好的现金牛业务,行业繁荣,工作也比较稳定,专注于这个业务,不断提升薪资水平,这就是:活在当下。
明星业务,比较形象地表达了很有前景的新兴业务,已经走上了快速发展的轨道。比如:亚马逊的云计算(AWS)就是它的未来之星。而个人呢?如果你的现金牛业务(级别和薪资)已经进入行业正态分布的前 20%,那么再继续提升的难度就比较大了。
个人的明星业务是为未来 5 到 10 年准备的,就是现在还并不能带来稳定的现金流但感觉上了轨道的事。于我而言,是投资理财。人到中年,除了劳动性收入,资产性收益将作为很重要的补充收入来源,而当资本金足够大时,很可能就是未来的主要收入来源。当你开始在考虑未来的明星业务时,这就是:活在未来。
问题业务,比较形象地表达了还有比较多问题的业务领域,面临很多不确定性,也就是还没走上正轨。将来到底是死掉,还是成为新的明星业务,现在还看不清楚。比如谷歌的无人驾驶、机器人等业务领域都属于此类。
就个人而言,可能是一些自身的兴趣探索领域。于我来说,目前就是写作和英语,即使写作已经开了专栏,但并不算是稳定可靠的收入来源,主要还是以兴趣驱动,投入时间,不断探索,开拓新的维度,这就是:活在多维。
瘦狗业务,比较形象地表达了一些食之无味、弃之可惜的业务。瘦狗业务要么无法产生现金流,要么产生的现金流不断萎缩。今日之瘦狗,也许是昨日的明星或现金牛,比如像诺基亚的功能机。
就个人而言,行业在发展,技术也在进化,曾经你赖以为生的 “现金牛” 技能,可能过几年后就会落后,逐渐变成了 “瘦狗”,无法果断地放弃旧技能、开发新技能,可能就如诺基亚一般在新的时代被淘汰。固守瘦狗业务,那就是:活在过去。
业务模型构成了你的蓝图,而对你的各种业务进行与时俱进地布局与取舍,这就是战略。
进化跃迁
明晰了路线,掌握了蓝图,该如何完成你的成长进化跃迁呢?
跃迁是量子力学里的概念,指电子吸收能量后,突然跳到更高的能量级,这种不连续、跳跃的突变,我们称之为 “跃迁”。我借用了这个概念来类比成长,从如上定义中有几个关键点:
- 吸收能量
- 更高能量级
非连续跳跃
个人成长的跃迁也需要能量,在这里能量就是知识、技能和能力。完成 “能量” 的积累就需要持续地学习和实践行动,而持续行动又靠什么来驱动?内心的自驱力,这是稳定有效的驱动力来源,若没有自我驱动的力量是不太可能带来持续行动的。
学习行动计划、养成行动习惯都是为了提升行动的效率,行动积累了足够的 “能量” 后,就向更高能量级跳跃。这里更高的能量级是对知识和能力的更高维度抽象的比喻,比如:知识模型和技能体系,就比孤立的知识点和技能拥有更高的能量级。
而第三个关键点:非连续跳跃,说明这样的进化有突变的特征。而个人知识的积累与能力的提升,其实都是比较缓慢而连续的,非连续的跳跃其实体现在机会和运气上。合适的机会若没能降临,你就没法完成跃迁。
连续的成长积累是你能掌控的部分,而跃迁的机会、运气则属于概率成分,你的努力可能一定程度上提高了概率,但它并不能导致必然的跃迁结果发生。即使机会没能到临,努力过后也许有无奈,也该当无悔了。
最后,我们总结下:
从开发代码到开发梦想,你可以画出一张你的成长路线图,从而走上进化跃迁的道路;上了路后,接着你可以利用工程师的思维模式和商业工具模型,建立一个你的成长战略蓝图去指导你如何走这条路。剩下的,就让你的努力、选择和运气来帮助你完成不断的跃迁变化吧。
八、结束语
尾声 | 始于知,终于行
成长的本质,就是两个字:知行——始于知,终于行。
知
知,起于阅读;当你决定学习一样东西时,自然就会从阅读开始。从阅读中学习,要么是直接获得知识,要么就是从别人的学习经历或经验中找到值得自身借鉴的参考与启发。
先有 “知”,方有 “行”。知,只是行的方法;行,才是知的目的。
行
纸上得来终觉浅,绝知此事要躬行。