程序员进阶攻略 ############## .. raw:: html
目录 .. sidebar:: 目录 .. contents:: .. raw:: html
作者简介:: 胡峰 京东成都研究院技术专家 胡峰,从毕业到今天,在程序这条道路上已经走了十多年了,前期在金融、电信行业写写程序,最近七年在互联网行业从事电商应用相关系统的技术工作,也一路从程序员成长为了一名架构师。 .. figure:: https://img.zhaoweiguo.com/knowledge/images/jikes/jinjies/roadmap.png 成长线的表意图,有两个部分:图上左侧的路径,是匹配不同成长阶段,对应不同职业角色;右侧是一条由不同成长阶段组成的成长线 启程:: 1. 初心 2. 技术方向 3. 技术地图 修炼:: 设计: 1. 架构与实现 2. 模式与框架 3. 多维与视图 编程: 1. 代码与分类 2. 粗放与精益 3. 炫技与克制 4. 编程的三阶段进化 Bug: 1. Bug 的空间属性 2. Bug 的时间属性 3. Bug 的反复出现 修行:: 计划: 1. 根源:计划的愿景 —— 仰望星空 2. 方式:计划的方法 —— 脚踏实地 3. 检视:计划的可行 —— 时间与承诺 4. 评估:计划的收获 —— 成本与收益 执行: 5. 障碍:从计划到坚持,再到坚持不下去的时候 6. 执行:从坚持到持续,再到形成自己的节奏 精进思维: 1. 信息:过载与有效 2. 领域:知识与体系 3. 转化:能力与输出 4. 并行:工作与学习 习惯: 1. 时间:塑造基石习惯 2. 试试:一种 “坏” 习惯 3. 提问:从技术到人生的习惯 4. 偏好:个人习惯的局限与反思 展现: 1. 写作:写字如编码 2. 画图:一图胜千言 3. 演讲:表达的技术 职场阶梯: 1. 定义:阶梯与级别 2. 晋升:评定与博弈 3. 关系:学徒与导师 工程: 1. 核心:安全与效率——工程技术的两个核心维度 2. 过程:规模与协作 —— 规模化的过程方法 3. 思维:科学与系统 —— 两类问题的两种思维解法 徘徊:: 如何: 1. 职业倦怠:如何面对? 2. 局部最优:如何逃离? 3. 沟通之痛:如何改变? 4. 技术停滞:如何更新? 5. 无法实现:困扰与反思 6. 完成作品:理想与现实 7. 代码评审:寄望与哀伤 8. 人到中年:失业与恐惧 该不该: 1. 该不该去创业公司? 2. 该不该接外包? 选择: 1. 技术干货那么多,如何选? 2. 技术分歧,如何决策? 3. 技术债务,有意或无意的选择? 4. 选择从众,还是唯一? 5. 选择工作,还是生活? 寻路:: 1. 侠客行:一技压身,天下行走 2. 江湖路:刀剑相接,战场升级 3. 御剑流:一击必杀,万剑归心 4. 三维度:专业、展现与连接 5. 三人行:前辈、平辈与后辈 6. 三角色:程序员、技术主管与架构师 7. 三视角:定位、自省与多维 蜕变:: 1. 工作之余,专业之外 2. 跨越断层,突破边界 3. 成长蓝图,进化跃迁 启程 ==== 一. 技术地图-掌握 ----------------- 1. 开发平台:: 包括一种编程语言、附带的平台生态及相关的技术 开发平台决定了你会成为什么类型和方向的程序员。比如:服务端、客户端或前端开发等 a. 编程语言 b. 平台生态 2. 常用算法:: 表达的是一个计算的动态过程,它引入了一个度量标准:时空复杂度 3. 数据结构:: 数组 Array 链表 Linked List 队列 Queues 堆栈 Stacks 散列 Hashes 集合 Sets 树 Trees 图 Graphs 二. 技术地图-了解 ----------------- 1. 数据存储:: SQL 关系型数据库(如:MySQL、Oracle) NoSQL 非关系型数据库(如:HBase、MongoDB) Cache 缓存(如:Redis、Memcached) 按了解的深度需要依次知道如下几点: a. 如何用?在什么场景下,用什么数据存储的什么特性? b. 它们是如何工作的? c. 如何优化你的使用方式? d. 它们的量化指标,并能够进行量化分析? 2. 测试方法:: 测试思维是一种与开发完全不同的思维模式 开发与测试这两种相反视角的切入维度,能真正长期地提高你写代码的效率和水平 3. 工程规范:: 代码结构 代码风格 4. 开发流程:: 敏捷方法论 导师制 5. 源码管理:: 最基本诉求: a. 并行:以支持多特性,多人的并行开发 b. 协作:以协调多人对同一份代码的编写 c. 版本:以支持不同历史的代码版本切换 修炼 ==== 架构与实现 ---------- 把一种想法、一个需求变成代码,这叫 “实现”,而在此之前,技术上有一个过程称为设计,设计中有个特别的阶段叫 “架构”。关于软件架构的共同认知:软件系统的结构与行为设计。而实现就是围绕这种已定义的宏观结构去开发程序的过程。 『架构』是一种结构设计,它同时可能存在于不同的维度和层次上:: 1. 高维度: 指系统、子系统或服务之间的切分与交互结构 2. 中维度: 指系统、服务内部模块的切分与交互结构 3. 低维度: 指模块组成的代码结构、数据结构、库表结构等 不论工作在哪个维度的架构师,他们工作的共同点包括下面 4 个方面:: 1. 确定边界:划定问题域、系统域的边界 2. 切分协作:切分系统和服务,目的是建立分工与协作,并行以获得效率 3. 连接交互:在切分的各部分之间建立连接交互的原则和机制 4. 组装整合:把切分的各部分按预期定义的规则和方法组装整合为一体,完成系统目标 .. note:: 架构师的交付成果是一整套决策流,文档仅仅是交付载体,而且仅仅是过程交付产物,最终的技术决策流实际体现在线上系统的运行结构中。 『实现』的最终交付物是程序代码,但这个过程中一般会有下面 6 个方面的考虑:: 1. 选型评估 2. 程序设计 3. 执行效率 4. 稳定健壮 5. 维护运维 6. 集成部署 .. figure:: https://img.zhaoweiguo.com/knowledge/images/architectures/jk-jinjies/implement1.png 『实现』6 方面对应的详细内容 .. important:: 架构与实现过程中,最重要的关注点是『熵』。实现的核心关注点,用一个字表达:简。 .. note:: 架构与实现之间,存在一条鸿沟,这是它们之间的断裂带。断裂带出现在架构执行过程之中,落在文档上的架构决策实际上是静态的,但真正的架构执行过程却是动态的。 .. important:: 当系统规模足够大了,没有任何架构师能够把控住全部的细节。在实践中,建议定期对系统的状态做快照,而非去把握每一次大大小小的变化,因为那样直接就会信息过载。 .. note:: 在做快照的过程中我会发现很多的细节,也许和我当初想的完全不一样,会产生出一种 “要是我来实现,绝对不会是这样” 的感慨。但在我发现和掌握的所有细节中,我需要做一个判断,哪些细节上的问题会是战略性的,而我有限的时间和注意力,必须放在这样的战略性细节上。而其他大量的实现细节也许和我想的不同,但只要没有越出顶层宏观结构定义的边界即可。系统是活的,控制演化的方向是可行的,而妄图掌控演化过程的每一步是不现实的。关注与把控边界,这就比掌控整个领地的范围小了很多,再确认领地中的战略要地,那么掌控的能力也就有了支撑。架构与实现的鸿沟会始终存在,在这条鸿沟上选择合适的地方建设桥梁,建设桥梁的地方必是战略要地。 .. note:: 架构升级,仅仅是一次系统的重新布局与规划,成本和效率的重新计算与设计,“熵” 的重新分布与管理。 .. important:: 架构是关注系统结构与行为的决策流,而实现是围绕架构的程序开发过程;架构核心关注系统的 “熵”,而实现则顺应 “简”;架构注重把控系统的边界与 “要塞”,而实现则去建立 “领地”;所有架构的可实现性都是等效的,但实现的成本、效率绝不会相同。 让架构与实现分道扬镳的原因有:: 1. 沟通问题:如信息传递障碍 2. 水平问题:如技术能力不足 3. 态度问题:如偷懒走捷径 4. 现实问题:如无法变更的截止日期(Deadline) 模式与框架 ---------- .. note:: 《建筑的永恒之道》:每个模式都描述了一个在我们的环境中不断出现的问题,然后描述了该问题的解决方案的核心,通过这种方式,我们可以无数次地重用那些已有的成功的解决方案,无须再重复相同的工作。 模式是前人解决某类问题方式的总结,是一种解决问题域的优化路径。但引入模式也是有代价的。设计模式描述了抽象的概念,也就在代码层面引入了抽象,它会导致代码量和复杂度的增加。而衡量应用设计模式付出的代价和带来的益处是否值得,这也是程序员 “火候” 能力另一层面的体现。 .. note:: 框架和模式的共同点在于,它们都提供了一种问题的重用解决方案。其中,框架是代码复用,模式是设计复用。另外,中台,其实本质就是行业业务规则的抽象和平台化 多维与视图 ---------- * 系统设计的思考维度与展现视图 .. note:: 用更系统化的视图去观察和思考,想必也会让你得到更成体系化的系统设计。 机械设计课程时学习了 “三视图”:: 三视图是观测者从三个不同位置观察同一个空间几何体所画出的图形, 是正确反映物体长宽高尺寸正投影的工程图,在工程设计领域十分有用 .. note:: UML 是一种类似于传统工程设计领域 “三视图” 的尝试,但却又远没有达到 “三视图” 的精准。 1. 组成视图 ^^^^^^^^^^^ .. note:: 组成视图,表达了系统由哪些子系统、服务、组件部分构成。 .. figure:: https://img.zhaoweiguo.com/knowledge/images/architectures/jk-jinjies/architecture-view1.png 《京东咚咚架构演进》:对系统进行了一次微服务化的架构升级,而微服务的第一步就是拆分服务,并表达清楚拆分后整个系统到底由哪些服务构成,所以有了下面这张系统服务组成图。 每一类服务提供逻辑概念上比较相关的功能,而每一个微服务又按照如下两大原则进行了更细的划分:: 1. 单一化:每个服务提供单一内聚的功能集 2. 正交化:任何一个功能仅由一个服务提供,无提供多个类似功能的服务 * 《京东咚咚架构演进》: https://blog.csdn.net/zdy0_2004/article/details/50166733 2. 交互视图 ^^^^^^^^^^^ .. note:: 交互视图,表达了系统或服务与外部系统或服务的协作关系,也即:依赖与被依赖。 .. figure:: https://img.zhaoweiguo.com/knowledge/images/architectures/jk-jinjies/architecture-view2.png 这是一张宏观大倍率的整体交互视图示例。它隐藏了内部众多服务的交互细节,强调了终端和服务端,以及服务端内部交互的主要过程。 .. note:: 如果我们把目光聚焦在一个服务上,以其为中心的表达方式,就体现了该服务的依赖协作关系。所以,可以从不同服务为中心点出发,得到关注点和细节更明确的局部交互细节图,而这样的细节图一般掌握在每个服务开发者的脑中。当我们需要写关于某个服务的设计文档时,这样的局部细节交互图也应该是必不可少的。 3. 部署视图 ^^^^^^^^^^^ .. note:: 部署视图,表达系统的部署结构与环境。 .. figure:: https://img.zhaoweiguo.com/knowledge/images/architectures/jk-jinjies/architecture-view3.png 部署视图,从不同的人员角色出发,关注点其实不一样,不过从应用开发和架构的角度来看,会更关注应用服务实际部署的主机环境、网络结构和其他一些环境元素依赖。这是一张强调服务部署的机房结构、网络和依赖元素的部署图示例。 .. note:: 部署视图本身也可以从不同的视角来画,这取决于你想强调什么元素。上面这张示例图,强调的是应用部署的 IDC 及其之间的网络关系,和一些关键的网络通讯延时指标。因为这些内容可能影响系统的架构设计和开发实现方式。 4. 流程视图 ^^^^^^^^^^^ .. note:: 流程视图,表达系统内部实现的功能和控制逻辑流程。 .. figure:: https://img.zhaoweiguo.com/knowledge/images/architectures/jk-jinjies/architecture-view4.png 本图是咚咚消息投递的一个功能逻辑流程表达。可以用「流程图」来表达系统设计与实现的流程,也可以像本图一样用「类 UML 的序列图」 .. note:: 逻辑流程一般分两种:业务与控制。有些系统业务逻辑很复杂,而有些系统业务逻辑不复杂但请求并发很高,导致对性能、安全与稳定的要求高,所以控制逻辑就复杂了。这两类复杂的逻辑处理流程都需要表达清 5. 状态视图 ^^^^^^^^^^^ .. note:: 状态视图,表达系统内部管理了哪些状态以及状态的变迁转移路径。 .. figure:: https://img.zhaoweiguo.com/knowledge/images/architectures/jk-jinjies/architecture-view5.png 状态视图示例 .. note:: 无状态服务相比有状态的服务和系统要简单很多,一个系统中不是所有的服务都有状态,只会有部分服务需要状态,我们的设计仅仅是围绕在,如何尽可能地把状态限制在系统的有限范围内,控制其复杂性的区域边界。 代码与分类 ---------- * 工业级编程的代码分类与特征 按代码的作用,大概都可以分为如下三类:: 1. 功能 是实现需求的业务逻辑代码,反映真实业务场景,包含大量领域知识 难点: 需求信息源自用户的内心,通过表达显性地传递,最终固化成了代码,以程序的形态反馈给用户 但信息在这个链条中的每个环节都可能会出现偏差与丢失, 即使最终整个链条上的各个角色都貌似达成了一致 但最终也可能发现用户的心理诉求要么表达错了,要么被理解错了 2. 控制 是控制业务功能逻辑代码执行的代码,即业务逻辑的执行策略 包括: a. 编程领域熟悉的各类设计模式,都是在讲关于控制代码的逻辑 b. 微服务架构模式下关注的控制领域,包括: 通信、负载、限流、隔离、熔断、异步、并行、重试、降级 控制代码,都是与业务功能逻辑不直接相关的,但它们和程序运行的性能、稳定性、可用性直接相关 3. 运维 是方便程序检测、诊断和运行时处理的代码 它们的存在,才让系统具备了真正工业级的可运维性。 包括: a. 检测诊断性代码: 日志 b. 编程模式:面向切面编程(AOP) 通过早期的有意设计,可以把相当范围的检测诊断代码放入切面之中, 和功能、控制代码分离,保持优雅的边界与距离 c. 特定的编程语言平台: 如 Java 平台,有字节码增强技术,可干净地把这类检测诊断代码和功能、控制代码彻底分离 另一类: 方便在运行时,对系统行为进行改变的代码。 通常这一类代码提供方便运维操作的 API 服务,甚至还会有专门针对运维提供的服务和应用 例如:备份与恢复数据、实时流量调度等 .. note:: 提供一项服务,功能代码满足了服务的功能需求,控制代码则保障了服务的稳定可靠,运维代码让系统具备了真正工业级的可运维性。 .. note:: 功能、控制、运维,三类代码,在现实的开发场景中优先级这样依次排序。有时你可能仅仅完成了第一类功能代码就迫于各种压力上线发布了,但你要在内心谨记,少了后两类代码,将来都会是负债,甚至是灾难。而一个满足工业级强度的程序系统,这三类代码,一个也不能少。 粗放与精益 ---------- * 编程的两种思路与方式:: 写得粗放,写得多 写得精益,写得好 * 粗放经营(Extensive Management),泛指技术和管理水平不高,生产要素利用效率低,产品粗制滥造,物质和劳动消耗高的生产经营方式。 * 精益生产(Lean Production),简言之,就是一种以满足用户需求为目标、力求降低成本、提高产品的质量、不断创新的资源节约型生产方式。 .. important:: 编程,其实一开始哪有什么完美,只有不断变得更好。好不是完美,好是一个过程,一个不断精益化的过程。 .. note:: 编程价值观:世上没有完美的解决方案,任何方案总是有这样或那样一些因子可以优化。一些方案可能面临的权衡取舍会少些,而另一些方案则会更纠结一些,但最终都要做取舍。 .. note:: 编程的背后是交付程序系统,交付关心的是三点:功能多少,质量好坏,效率快慢。真实的编程环境下, 你需要在三者间取得平衡,哪些部分可能是多而粗放的交付,哪些部分是好而精益的完成,同时还要考虑效率快慢(时间)的需求。 炫技与克制 ---------- .. note:: 炫技:除了增加不必要的复杂性外,也可能更容易出 Bug .. note:: 对于新技术,即使从我知道、我了解到我熟悉、我深谙,这时也还需要克制,要等待合适的时机。新技术的应用,也需要等待一个合适的出击时刻,也许是应用在新的服务上,也许是下一次架构升级。 克制的编程方式:: 1. 克制的编码 每次写完代码,需要去反思和提炼它,代码应当是直观的,可读的,高效的 2. 克制的代码 即使站在远远的地方去看屏幕上的代码,甚至看不清代码的具体内容时 也能感受到它的结构是干净整齐的,而非 “意大利面条” 似的混乱无序 3. 克制的重构 每次看到 “坏” 代码不是立刻就动手去改,而是先标记圈定它 然后通读代码,掌握全局,重新设计 最后再等待一个合适的时机,来一气呵成地完成重构 编程的三阶段进化 ---------------- 编程的进化过程,大概会经历下面三个阶段:: 阶段一:调试代码 Debugging 初级阶段: 需要逐渐降低使用 Debug 功能的频率,才有可能走入第二阶段 阶段二:编写代码 Coding 目标:达到信、达、雅 阶段三:运行代码 Running 目标:又快又好 .. note:: 基准测试和测试人员做的性能测试不同。测试人员做的性能测试都是针对真实业务综合场景的模拟,测试的是整体系统的运行;而基准测试是开发人员自己做来帮助准确理解程序运行效率和效果的方式,当测试人员在性能测试发现了系统的性能问题时,开发人员才可能一步步拆解根据基准测试的标尺效果找到真正的瓶颈点,否则大部分的性能优化都是在靠猜测。 .. note:: 一个新东西引入到核心服务中,不理解实现原理,是用不好的,还可能埋坑,这是必要的成本 一个新东西引入需要至少三步:: 1. 第一步,他去阅读资料和代码搞懂该工具的实现原理与机制并能清晰地描述出来 输出: 原理性描述说明文档 2. 第二步,去对该工具进行效果测试,又称功能可用性验证 输出: 样例使用代码 3. 第三步,进行基准性能测试,或者又叫基准效率测试(Benchmark),以确定符合预期的标准 输出: 基准效率测试结果 Bug 的空间属性 -------------- * 环境依赖与过敏反应 从 Bug 出现的 “时空” 特征角度来分类:: 1. 空间:环境过敏 2. 时间:周期规律 .. note:: 运行环境发生变化,程序就出现异常的现象,我称其为 “程序过敏反应”。 Bug 的时间属性 -------------- * 周期特点与非规律性 周期特点:: 这类 Bug 因为会周期性地复现,相对还是容易捕捉和解决。 比较典型的呈现此类特征的 Bug 一般是资源泄漏问题。 比如,Java 程序员都不陌生的 OutOfMemory 错误,就属于内存泄漏问题,而且一定会周期性地出现。 非规律性:: 没有规律性的 Bug,才是让人抓狂的。 方法: 1. 经验性的怀疑与猜测,再去反过来求证 2. 采用工具,直接引入代码 Profiler 等性能剖析工具 就可以准确地找到有性能问题的代码段,从而避免了看似有理却无效的猜测 能称得上神出鬼没的 Bug 只有一种:海森堡 Bug(Heisenbug)。 其认为观测者观测粒子的行为会最终影响观测结果。 所以,我们借用这个效应来指代那些无法进行观测的 Bug, 也就是在生产环境下不经意出现,费尽心力却无法重现的 Bug。 海森堡 Bug 的出现场景通常都是和分布式的并发编程有关。 Bug 的反复出现 -------------- * 重蹈覆辙与吸取教训 重蹈覆辙型错误,总结下来大概都可以归为以下三类原因:: 1. 粗心大意 一些非常低级的、因为粗心大意而导致的 Bug 2. 认知偏差 认知偏差,是重蹈覆辙类错误的最大来源 3. 熵增问题 程序规模变大,复杂度变高之后,再去修改程序或添加功能就更容易引发未知的 Bug 例: 3.5 版本 QQ 的用户在线规模进入亿时代 “昵称” 长度增加一半,需要两个月 增加 “故乡” 字段,需要两个月 最大好友数从 500 变成 1000,需要三个月 如何避免重蹈覆辙:: 1. 优化方法 粗心大意: 通过开发规范、代码风格、流程约束,代码评审和工具检查等工程手段来加以避免 通过补充单元测试在运行时做一个正确性后验,反过来去发现这类我们视而不见的低级错误 认知偏差: 一般没什么太好的自我发现机制,但可以依赖团队和技术手段来纠偏。 每次掉坑里爬出来后的经验教训总结和团队内部分享, 另外就是像一些静态代码扫描工具也提供了内置的优化实践, 通过它们的提示来发现与你的认知产生碰撞纠偏 熵增问题: 业界不断迭代更新流行的架构模式就是在解决这个问题 微服务架构相对曾经的单体应用架构模式,就是通过增加开发协作 部署测试和运维上的复杂度来换取系统开发的敏捷性 在协作方式、部署运维等方面付出的代价都可以通过提升自动化水平来降低成本, 但只有编程活动是没法自动化的,依赖程序员来完成, 而每个程序员对复杂度的驾驭能力是有不同上限的 微服务本质上就是将一个大系统的熵增问题 局部化在一个又一个的小服务中。 而每个微服务都有一熵增的极限值,而这极限值是要低于该服务负责人的驾驭能力上限的 对于一个熵增接近极限附近的微服务,服务负责人就需要及时重构优化,降低熵的水平 而高水平和低水平程序员负责的服务本质差别在于熵的大小 熵增问题若不及时重构优化,最后可能会付出巨大的代价。 2. 塑造环境 建立和维护有利于程序员及时暴露并修正错误 挑战权威和主动改善系统的低权力距离文化氛围, 这其实就是推崇扁平化管理和 “工程师文化” 的关键所在。 故障处理方式 非技术背景的管理者通常喜欢用流程、制度甚至价值观来应对问题, 技术背景的管理者则喜欢从技术本身的角度去解决当下的问题 两者需要结合,站在更高的维度去考虑问题: 规则、流程或评价体系的制定所造成的文化氛围,对于 错误是否以及何时被暴露,如何被修正有着决定性的影响 修行 ==== 根源-计划的愿景 --------------- * 根源:计划的愿景 —— 仰望星空 需求模型 ^^^^^^^^ .. note:: 上世纪四十年代(1943 年)美国心理学家亚伯拉罕・马斯洛在《人类激励理论》中提出了需求层次理论模型,它是行为科学的理论之一。 .. figure:: https://img.zhaoweiguo.com/knowledge/images/jikes/jinjies/Maslow's hierarchy1.png 马斯洛的经典金字塔图:需求层次模型。马斯洛把底层的四类需求:生存、安全、归属、尊重归类为 “缺失性” 需求,它们的满足需要从外部环境去获得。而最顶层的 “自我实现” 则属于 “成长性” 需求。成长就是自我实现的过程,成长的动机也来自于 “自我实现” 的吸引。 生涯发展 ^^^^^^^^ 生涯提出了四个维度:: 1. 高度:背后的价值观是影响与权力。代表性关键词有:追逐竞争、改变世界 2. 深度:背后的价值观是卓越与智慧。代表性关键词有:专业主义、工匠精神 3. 宽度:背后的价值观是博爱与和谐。代表性关键词有:多种角色、丰富平衡 4. 温度:背后的价值观是自由与快乐。代表性关键词有:自我认同、精彩程度 回首无悔 ^^^^^^^^ 计划,就是做选择,你在为未来的你做出选择,你在选择未来变成 “谁”。如果你还在为今天的自己而后悔,那就该为明天的自己做出计划了。 方式-计划的方法 --------------- * 方式:计划的方法 —— 脚踏实地 目标 ^^^^ 在设定目标这个领域,马克・墨菲(Mark Murphy)曾提出过一种 HARD 方法:: 1. Heartfelt 衷心的,源自内心的 体现了你的兴趣、偏好与心灵深处的内核 2. Animated 活生生,有画面感的 对这个目标形成的愿景是否足够清晰,在头脑中是否直接就能视觉化、具象化 3. Required 必须的,需求明确的 马斯洛需求模型层次决定的 如: 写作一方面本是自带属于第三层次的社交属性, 但另一方面更多是一种成长性的自我实现需求在激发。 完成一部作品,需要明确一个主题,持续地写作 4. Difficult 困难的,有难度的 决定了目标的挑战门槛 以 HARD 目标法为指导,根据目标的清晰度,大概可以划分为如下三个阶段:: 1. 目标缺乏,随波逐流 2. 目标模糊,走走停停 3. 目标清晰,步履坚定 .. note:: Easy choices, hard life. Hard choices, easy life.容易的选择,艰难的生活;艰难的选择,轻松的生活。 方法 ^^^^ * 目标是愿望层面的 * 计划是执行层面的 从『时间维度』,可以拟定 “短、中、长” 三阶段的计划:: 1. 短期 拟定一年内的几个主要事项、行动周期和检查标准 一年可以完成几件事或任务 2. 中期 近 2~3 年内的规划,对一年内不足以取得最终成果的事项,可以分成每年的阶段性结果 两三年可以掌握精熟一门技能 3. 长期 我的长期一般也就在 5~7 年周期,属于我的 “一辈子” 的概念范围了,而 “一辈子” 当有一个愿景 达成一个愿景,实现一个成长的里程碑 从『路径维度』,订计划可以用一种 SMART 方法:: 1. Specific 具体的 2. Measurable 可衡量的 3. Achievable 可实现的 4. Relevant 相关的 5. Time-bound 有时限的 .. figure:: https://img.zhaoweiguo.com/knowledge/images/jikes/jinjies/smart1.png 计划跟踪表示意图 .. figure:: https://img.zhaoweiguo.com/knowledge/images/jikes/jinjies/smart2.png 计划与实际执行对比示意图 .. note:: 按 SMART 原则方法使用计划跟踪表的优点是:简单、直接、清晰。但缺点也明显:即使百分百完成了所有的计划,也都是预期内的,会缺乏一些惊喜感。而因为制定目标和计划会有意识地选择有一定难度的来挑战,所以实际还很难达成百分百。 .. important:: 计划是准备,变化才是永恒,而计划就是为了应对变化。可以把计划表按优先级排得满满的,但永远只做那些计划表顶部最让自己感到 HARD 的事情。变化来了,就把它装进计划表中,看这样的变化会排在哪个位置,和之前计划表前列的事情相比又如何。如果变化的事总能排在顶上,那么说明你的人生实际就在不断变得更精彩,做的事情也会让你更激动。而如果变化老是那些并不重要却还总是紧急的事情,老打断当下的计划,那么也许你就要重新审视下你当前的环境和自身的问题了。另外,有时也需要果断的放弃计划,应对新的变化。 德国人打仗时,关于计划的思考。做最好的计划,然后上战场的时候,不用他。因为战场上变化实在太快了,但是因为计划,我们知道我们有多少坦克,有多少物资,有多少士兵。越是变化的时代,我们越是要计划,计划的本质,是盘点当下,了解自己,审视自己。 计划对团队作用:: 1. 统一上上下下的意志和决心,明确战略方向,盘清楚资源家底 2. 临时应变者,可以有一个资源框架可以用,知道自己能干什么 3. 形成一个个小型的执行板块,小组织也能用 检视-计划的可行 --------------- * 检视:计划的可行 —— 时间与承诺 .. note:: 要让计划可行,就是选择合适的事项,匹配正确的周期,建立合理的预期,得到不断进步的反馈。兴趣让计划更容易启动,而承诺让计划得以完成。可行的计划应该是:有限的时间,适合的周期,兴趣的选择,郑重的承诺。 兴趣VS承诺:: 吴军: 凡事从 0 分做到 50 分,靠的是直觉和经验;从 50 分到 90 分,就要靠技艺了。 凭借兴趣驱动的尝试,结合直觉和经验就能达成 50 分的效果,而要到 90 分就需要靠技艺了。 而技艺的习得是靠刻意练习的,而刻意练习通常来说都不太有趣。 要坚持长期的刻意练习,唯一可靠的办法就是对其做出郑重的承诺。 评估-计划的收获 --------------- * 评估:计划的收获 —— 成本与收益 做计划自是为了有收获,实现愿景也好,获得成长也罢,每一份计划背后都有付出与收获的关系。如果计划的收益不能高于执行它付出的成本,那么其实这种的计划就几乎没有执行价值。 * 成本与机会 * 结果与收益 在获得结果的路上,这个世界上似乎有两类人:: 1. 第一类人,自己给自己施加约束,保持自律并建立期望 2. 第二类人,需要外部环境给予其约束和期望 .. note:: 生活也许不会像计划那样发生,但对待生活的态度可以是:期待伟大的事情发生,同时也要保持快乐和幸福,即使它没能发生。 障碍-从计划到坚持 ----------------- * 障碍:从计划到坚持,再到坚持不下去的时候 .. note:: 设定一个计划并不困难,真正的困难在于执行计划。若你能够坚持把计划执行下去,想必就能超越绝大部分人,因为大部分人的计划最终都半途而废了。 计划生命周期的阶段:: 1. 酝酿 计划的早期雏形阶段;这阶段最大的障碍来自内心:理性与感性的冲突 感性: 需要坚持的事情,通常都 “不好玩”,而人是有惰性的,内心里其实并不愿意去做 理性: 去完成这些计划,对自己是有长远好处的 2. 启动 计划从静止到运动的早期阶段;这阶段的最大障碍是所谓的 “最大静摩擦力” 万事开头难 3. 执行 计划实现过程中最漫长的阶段;这阶段的最大障碍就是容易困倦与乏味。 漫长的坚持过程期,大部分时候都是很无聊、乏味的,真实的人生就是这样,没有那么多戏剧性的故事 4. 挫败 不是一个阶段,而是坚持路上的一些点;正是在这些点上你遭遇了巨大的挫败感 .. note:: [第三阶段:执行]坚持,特别是长期的坚持,是需要动力的,而动力来自目标和意义。而获得目标与意义的最好方式是讲好一个故事。你看,成功的企业家会把未来的愿景包进一个美好的故事里,让自己深信不疑;然后再把这个故事传播出去,把所有相信这个故事的人聚在一起去追寻这个故事;最后,这个关于未来的故事就这样在现实中发生了。 .. important:: 漫长的人生,你需要为自己讲好一个故事。 .. figure:: https://img.zhaoweiguo.com/knowledge/images/jikes/jinjies/story1.png :width: 70% .. figure:: https://img.zhaoweiguo.com/knowledge/images/jikes/jinjies/story2.png :width: 70% .. figure:: https://img.zhaoweiguo.com/knowledge/images/jikes/jinjies/story3.png :width: 70% .. note:: [第四阶段:失败]遭遇挫败,你会进入一种心情与情绪的低谷,这个时候有很高的概率做出放弃的决策。经验:不要在挫败的情绪低谷期进行任何的选择与决策。可以暂时放下这件事,等待情绪回归到正常,再重新理性地评估计划还是否该坚持。 .. important:: 每经历一次挫败之后,你还选择坚持,那么就已经收获了成长。 执行-从坚持到持续👍 --------------------- * 执行:从坚持到持续,再到形成自己的节奏 .. note:: 在执行过程中,容易半途而废的一个很可能的原因在于节奏出了问题。 计划的节奏 ^^^^^^^^^^ :: 一个计划被制定出来后,我们通常会根据它的周期设定一个执行的节奏。 跑100米和跑拉松肯定是用不同的节奏在跑 用全力冲刺的方式跑马拉松肯定坚持不了太长时间 如:每周三篇更新的节奏,这样的写作节奏对于我来说基本已经算是全力冲刺了,所以时间就不能拉得太长 .. note:: 你可能也遇到过,计划的节奏总是会被现实的 “意外” 打断,每次计划的节奏被打断后,都会陷入一种内疚的挫败感中;然后就强迫自己去完成每日计划列表中的每一项,否则不休息,最终也许是获得了数量,但失去了质量。在这样的挫败中纠结了几次后,你慢慢就会发现,现实总是比计划中的理想情况复杂多变。 怎么应对这些 “意外”:: 按程序员的思考方式,我会为所有计划中的事情创建了一个优先级队列, 每次都只取一件最高优先级的事情来做。 而现实总会有临时更高优先级的 “意外” 紧急事件插入,处理完临时的紧急事件, 队列中经常还满满地排着很多本来计划当天要做的事情。 以前,我总是尝试去清空队列,不清空不休息,但实际上这很容易让人产生精疲力竭的感觉。 如今,我对每个计划内的事情对应了一个大致的时间段, 如果被现实干扰,错过了这个时间段,没能做成这件计划内的事情,就跳过了, 一天下来到点就休息,也不再内疚了。 举例来说: 我计划今晚会看看书或写篇文章,但如果这天加班了,或者被其他活动耽误了, 这件计划中的事情也就不做了。 但第二天,这件事依然会进入队列中,并不会因为中断过就放弃了。 只要在队列里,没有其他事情干扰,到了对应的时间段就会去执行。 他人的节奏 ^^^^^^^^^^ .. note:: 拿我的写作节奏来说,在七年中也慢慢从每月一篇提升到了每周一篇。有些作者写作速度一直都很快,可能是每天一篇。但如果我要用他们的节奏去写作,可能一开始坚持不了多久就会放弃写作这件事了。 .. note:: 关于节奏的体会是:每个人都会有自己不同的节奏,这需要自己去摸索、练习,并慢慢提升。如果开始的节奏太快,可能很快就会疲惫、倦怠,很容易放弃;但如果一直节奏都很慢,则会达不到练习与提升的效果,变成了浪费时间。 .. note:: 看见别人跑得太快没了踪影,心里会很是焦急。有时太急迫地 “追赶”,最后反而阻挡了你稳步前进的步伐和节奏。BTW: 就像跑步时被对手带乱的节奏 自己的节奏 ^^^^^^^^^^ .. note:: 找到自己的节奏,就是在每天略感挑战的状态下,形成不断加速前行,直到一个最终接近匀速的状态。匀速是我们能长期坚持的临界点,它能让我们跑得更久,跑得更远。 经验是:: 把自己的时间安排成一段一段的,高度集中和高度分心交叉分布。 如: 某段时间需要高度集中注意力,就可以处理或思考一些比较难的事情。 比如,50 ~ 60 分钟,集中注意力处理工作事务,远离手机信息推送及其他各种环境的打扰; 然后休息一会儿,10 ~ 15 分钟左右,回复一些聊天或邮件这类其实不需要那么高注意力的事情。 精进思维: 信息-过载与有效 ------------------------- * 信息:过载与有效 :: 信息过载: 现实 疲于奔命: 陷阱 心智模型: 方法 一击中的: 策略 筛选:心智模型:: 从两个角度来考虑: 1. 信息和知识本身的价值 信息和知识的价值是一个主观的判断, 有一个客观点的因子是获取门槛: 众利勿为,众争勿往 2. 我需要怎样的信息和知识 心理学上有一个 “心智模型” : “心智模型” 是用于解释个体对现实世界中某事所运作的内在认知历程, 它在有限的领域知识和有限的信息处理能力上,产生合理的解释。 只有少部分人会更理性地认知到这个模型的存在,而且不断通过吸收相关信息和知识来完善这个模型 更多的众人依赖的是所谓的 “感觉” 和 “直觉” 实际上 “感觉” 和 “直觉” 也是 “心智模型” 产生的一种快捷方式 .. note:: “心智” 这两个字合在一起是一个意思,分开为 “心” 和 “智” 两个字又可以分别解释为:“心” 是你对需要的选择,从心出发;“智” 是对价值的判断,智力的匹配。 .. important:: 储备了信息,建立了知识,最终都是为了应用。 .. note:: 注意力是一种有限的资源,你要是不擅长不集中注意力,你就不擅长集中注意力。——万维钢 .. note:: 挑选那些真正值得做和学的东西去让大脑满负荷运转,但凡投入决心去做的事情,就需要百分百投入。这就是专注于少而精的东西,深入了解这些东西,进入到更深的层次上。深可以无止境,那到底多深才合适?我的答案是:让你的内心对取得的效果感受到满意的深度层次上。它的反面是:但凡心存疑虑,不是那么确定要全力投入的事情,干脆就不做了。 精进思维: 领域-知识与体系 ------------------------- * 领域:知识与体系 知识-点 ^^^^^^^ .. figure:: https://img.zhaoweiguo.com/knowledge/images/jikes/jinjies/knowledge1.png 我的成长时间线上相关技术领域知识点 因为时代、公司或项目的原因,有很大的随机性去接触很多不同的技术点。但如果你总是这样被客观的原因驱动去随机点亮不同的 “点”,那么你终究会感到有点疲于奔命,永远追不上技术的浪潮。 知识-线 ^^^^^^^ .. figure:: https://img.zhaoweiguo.com/knowledge/images/jikes/jinjies/knowledge2.png 我个人的成长发展 “T 线图”。在整个纵向的技术线上,最终汇总到顶点,会形成一种新的能力,也就是我对这条纵向线的 “掌控力”。到了这个 “点” 后,在这里可以横向发展,如图中,也就有了新的能力域:领导力和组织力。 一个个点,构成了基本的价值点,这些点串起来,就形成了更大的价值输出链条。在这条路上,你也会有一条属于自己的 “T 线”,当这条线成型后,你的价值也将变得更大。 知识-面 ^^^^^^^ .. figure:: https://img.zhaoweiguo.com/knowledge/images/jikes/jinjies/knowledge3.png 我近些年工作面的分层图 .. note:: 在相对传统的行业,做偏业务的开发,技术栈相对固定且老化,难度和深度都不高,看不到发展方向,期望找到突破口。若你也出现这样的情况,那就说明你从事的业务开发,其单个技术点的价值上限较低,而选择更新、更流行的技术,你就是期望提升单个技术点的价值,但单个技术点的价值是相对有限的。反过来,如果很难跳脱出自身环境的局限,那么也可以不局限于技术,去考虑这些传统的业务价值,从技术到业务,再上升到用户的接入触达,考虑产品的场景、形态和人群是如何去为这些用户提供的服务、产生的价值。当你对整个业务面上的价值点掌握的更多,能抓住和把握核心的价值链条,去为更广、更大的价值负责,那么你就能克服自己的成长发展困境,找到了另外一条出路了。同时,你也为自己织就了一张更大的领域之网。 .. important:: 在整个面形成了一个领域,在这个面上你所能掌控的每条线就是你的体系。在这条线的 “点” 上,你解决具体问题,是做解答题;但在整个面上你选择 “线”,是做选择题。 知识-体 ^^^^^^^ .. note:: 体是经济体或其中的单元。你的 “面” 附着在什么 “体” 上决定了它的价值上限。如果 “体” 在高速增长并形成趋势,你就可能获得更快的发展。 .. note:: 从电力时代到信息时代再到智能时代,互联网、电商、移动互联网,这些都是 “体” 的变化。今天互联网行业的软件工程师,他们面临的挑战和难度不见得比传统的机械或电力工程师更大,只不过他们所从事的 “点” 所属的 “面”,附着于一个快速崛起的 “体” 上,获得了更大的加速度。 .. important:: “体” 的崛起,是时代的机遇。 总结 ^^^^ .. note:: 【总结】在领域知识体系中,“点” 是利器,“线” 是路径,“面” 是地图;而就我们个体而言,“点” 是孤立知识点的学习掌握,而 “线” 是对这些点的连接,“面” 则构成了完整的知识体系网。 精进思维: 转化-能力与输出 ------------------------- * 转化:能力与输出 个人,建立好了知识体系,各方面都明了了,但有时做起事来却还会感觉发挥不出来;团队,牛人众多,但感觉做出的事情效果却很一般。这类问题的症结,多就出在从体系积累到输出转化的环节 个体 ^^^^ .. figure:: https://img.zhaoweiguo.com/knowledge/images/jikes/jinjies/knowledge4.webp 从学会一个知识,到能够熟练应用其去输出能力,大概会经历的过程。PS:其中的一个关键是有闭环。 团队 ^^^^ 体系的三个核心点:: 1. 流程规则 2. 工具系统 3. 规范共识 .. note:: 没有流程规则,“机器” 体系就不知该如何运转;缺乏工具系统支撑,就没法监视和控制这个体系的运转效率与效果;而如果未能在团队形成共识并达成规范,“机器” 体系就不可能“和谐”运转起来。所以,流程规则,建立其运行轨道;工具系统,支撑其高效运行;规范共识,形成了协调合奏。 团队能力输出就是这样一个 “机器” 体系运行的过程。那么团队的强弱就由两方面决定:: 一是团队中所有个体形成的体系力量之和 二是由流程规则、工具系统和规范共识共同决定的转化效率 .. note:: 【实例】有个高级测试工程师,在他晋升测试架构师级别的述职时,提到他的一项工作就是搭建测试体系来帮助团队改善测试工作的效率和效果。在进行阐述时,他完整地描述了这个体系 “机器” 的各个零部件组成,他制造的很多工具和系统,却缺失了关于体系的一些最重要的方面:这个体系是如何运转的?它提供了哪些系统和仪表盘监控指标来支撑和反映其运转状态?为什么这个体系能在团队里运转? 转化 ^^^^ 从个体到团队,都是通过搭建体系来积蓄力量,再通过体系的运转来输出能力。 .. note:: 积蓄力量和转化力量共同思维方式是体系化、工具化。体系,从工程维度看就像生产流水线,而体系的运转就是开动了生产流水线。搭建并调校出一条高转化输出能力的体系生产线,是真正具有核心竞争力和护城河的事情 要想产生更大的成果,取得更大的成功,我们需要找到放大个体或团队能力的杠杆支点。我们需要做的就是不断打磨这条流水线,提升转化输出好产品或好结果的效率与良品率。 .. note:: 个体和团队的强弱,一方面取决于我们在体系中积蓄的力量的总量,另一方面在于体系运作的转化输出率。体系决定了力量的总量,而转化决定了拳拳到肉的痛感。 精进思维: 并行-工作与学习 ------------------------- * 并行:工作与学习 程序员,工作以产出代码为主,从初级到高级,代码的负债属性逐步降低,资产属性不断提升,最终成为高品质的个人贡献者。 学习 ^^^^ .. note:: 有选择性的学习就需要找出真正与你近期规划有关的学习路径。 :: 1. 第一维度的书,聚焦于一个技术领域并讲得透彻清晰 学习语言最高效的方法就是看一本该领域的经典入门书 2. 第二维度的书,聚焦于特定领域经验总结型的书 这类书最有价值的地方是其聚焦于领域的思想和思路。 适合在有一些实际编程和工程经验后阅读 过早地看这类书反而没什么帮助,甚至还会可能造成误解与困扰 过早接触了第二维度的书,却预期得到第一维度的收获,自然无所获了 .. figure:: https://img.zhaoweiguo.com/knowledge/images/jikes/jinjies/knowledge5-level.webp 技术学习资料的层次结构示例图:Tutorial(指南) 和 API Reference(应用编程接口参考) 层次的信息资料能帮助你快速上手开发,而 Spec(技术规范)和 Code(源代码)会帮助你深刻地理解这门技术。而其他相关的技术书籍和文章其实是作为一种补充阅读,好的技术书籍和文章应该有官方资料中未涵盖的特定经验或实践才算值得一读。 .. important:: 每当我们接触一项新技术的时候,都要把手头的资料按照类似这样的一个金字塔结构进行分类。如果我们阅读了一些技术博客和技术书籍,那么也要清楚地知道它们涉及到的是金字塔中的哪些部分。——张铁蕾《技术的正宗与野路子》 路径 ^^^^ .. note:: 如果一生要工作三十多年,前十年你多在做解答题,解决一个又一个问题。那么在大约走过这三分之一后,你就会开始做越来越多的选择题。为什么呢?因为一开始可能没有太多可供你选择的机会。而后续做好选择题,则需要大量学习,还需要不断地试错。 你所尝试提升的事情都有一个增长曲线,这个曲线有两种形态:: 1. 对数增长形态:这种类型在初期增长很快,但随后进展就越发困难 对数增长也意味着更容易退步,因为起步阶段是如此陡峭 关注点需放在养成长期习惯上, 因为虽然开始增长很快,但需要小心一旦停止努力它可能会向下滑落, 所以一定要慎之又慎,坚持形成自己的习惯和节奏 2. 指数增长形态:这种类型在初期增长很慢,但存在积累的复利效应 指数增长则意味着存在一个拐点的 “突变” 时刻 关键点在于坚持到拐点出现 如:写作 在呈指数增长的领域内,到处都是半途而废者。 所以,做本质是指数增长曲线的事情时,柔韧且持久的思维模式是关键。 成长的瓶颈:: 工作多年后,技能的增长就又进入了对数的平缓区域,通常其回报呈现递减趋势。 也就是说你在其上花的功夫越来越多,但你感到越来越难产生洞察以获得新的收益。 其难处在于找到新的突破点,重新回到曲线陡峭上升的部 价值贡献的放大器:: 1. 产品自带的价值放大器 如:数千万或数亿人使用的软件服务 2. 转管理者或架构师 这些角色无非都是自带杠杆因子的,所以也有价值放大的作用 拉姆·查兰《领导梯队》把人才潜能分成三种:: 1. 熟练潜能 关注当前专业领域且十分熟练,但没有显示出在开发新能力上的努力,竭力维持现有技能 2. 成长潜能 按需开发新能力,显示出高于当前层级要求的其他技能,如:专业、管理、领导 3. 转型潜能 持续有规律地开发新能力,追求跨层级的挑战和机会,展现雄心壮志 注: 人力资源管理中的高潜人才盘点,基本就来自这套模型,主要就是识别出这三类潜能人才 总结 ^^^^ 程序员的工作形式是编程产出代码,本质是完成需求,交付系统;但在工作中容易陷入不断完成的循环怪圈,要打破它,就需要你持续学习并有意识地关注交付代码的品质和属性,一方面提升了交付质量,另一方面也获得了个人成长。 而学习的路在时间上是永远持续的,在空间上也是有路径的;有效的学习需要你关注学习曲线的变化,遵循有体系的技术学习框架,匹配适合当前阶段的学习资源。 忙起来就没时间学习的真正原因:: 多数人为了逃避真正的思考愿意做任何事情 习惯: 时间的习惯 ---------------- * 时间:塑造基石习惯(上)—— 感知与测量 * 时间:塑造基石习惯(下)—— 切割与构建 .. note:: 第一个 “基石” 习惯,在精确地感知与测量时间之后,你才可能更准确地 “预知” 未来。第二个 “基石” 习惯:将时间切割成建造你心中“大教堂”的合适“石材”。 感知时间 ^^^^^^^^ 为何人随着年龄的增大觉得时间过得越来越快?:: 有共性的回忆趋向粘合在一起,标志性的回忆倾向于鹤立鸡群。 心理学家认为: 我们对时间的感知同时和我们的经历有关。 如果一件事对于我们来说是 “激动人心” 的,这样的记忆在我们脑海中感觉到的时间会更长。 测量时间 ^^^^^^^^ 苏联科学家柳比歇夫《奇特的一生》:: 通过自创的 “时间统计法” 在一生内取得了惊人的成就 类似的方法: 记下一年来经历的所有有意义的事件(除去每日的例行工作),我称之为 “时间日志”。 方法类似记账,把记金额明细改成了记时间明细,借此以追踪我的时间都花在哪里去了 记录与测量时间的实践好处:: 使你对时间的感觉越来越精确。 每个人都感觉 “时间越过越快”,为什么会有这样的感觉? 这种感觉会使得我们产生很多不必要的焦虑。 而基于 “事件 - 时间日志” 的记录可以调整你对时间的感觉。 在估算任何工作时,都更容易确定 “真正现实可行的目标” 切割时间 ^^^^^^^^ 记录测量时间,让我对时间的感知更精确,而面对自然产生的每天一块的“时间原石”,每个清晨就要确定:把它切成什么样?由哪些石块组成?哪些是用来建造大教堂的石材?确定后,将其压在心上,临睡前再记录下今天从心上搬走了哪些石块,以及花了多少时间。这样时间于我就真的变成了一块块石头,比轻烟、流水、薄雾更有形,更易抓住,也没那么容易悄悄地溜走了。 构建时间 ^^^^^^^^ 适当的构建方式,是指在时间的 “基石” 习惯之上,建立其他的习惯。比如:: 好些年前开始,我会从每周的时间里切出来一块,专用于写作,慢慢就形成了写作的习惯。 这意味着,我从现有的 “时间石材” 中拿出了一部分,用于构建写作的习惯, 然而 “时间石材” 的总量是有限的,我必须在其上建立有限数量的习惯,我得做出选择。 任何行动的发生,都需要两种努力才有可能:: 1. 第一种,是行动本身固有需要的努力,如跑步,跑一公里和跑十公里固有需要的努力是不等量的 2. 第二种,指决策是否执行此行动的努力,决定跑一公里还是跑十公里的决策意志力消耗,也不会一样 .. note:: 构建习惯的目的,以及它们能起作用的原因在于:它能消除行动中第二种努力的决策消耗。 习惯,它的表象和形式给人的感觉是在重复一件事,但它的内在与核心其实是不断产生交付,持续的交付。 总结 ^^^^ :: 1. 要形成时间习惯,要通过有意识的感知和测量来发现时间是怎么流失的 2. 要完成建设你心中 “大教堂”,要通过切割 “时间原石” 来完成 “时间石材” 的准备 3. 在养成了时间的基石习惯之上,挑选和构建其他习惯来完成 “大教堂” 的持续建设与交付 习惯: 试试的习惯 ---------------- * 试试:一种 “坏” 习惯 .. note:: 好些年前,移动开发还在升温阶段时,我也不可避免地被这样一种潮流所裹挟过。我开始看一些关于 iOS 开发的书,从语言到工具。其实,尝试学习一种新技术并不是坏事,即使是被技术潮流所裹挟,但问题出在,这次尝试的终点在哪里?我当时的尝试完全没想清楚终点在哪儿。后来热度下来了,其他工作任务也多了,也就慢慢遗忘了。回过头来看,这只是浪费了一些时间和精力罢了。 人工智能与机器学习热了起来,这次尝试的终点就是想搞清楚关于人工智能与机器学习的三件事:: 1. 它的原理与应用场景 2. 它的前世今生 3. 它如今已抵达的边界 搞清楚这三件事,虽不会让我成为机器学习的专家,但会提升我对于这个热门技术的判断力。 因为,现实中我需要判断一些真实的业务场景该如何结合这样的技术, 这就需要了解它们的应用场景和一些原理。 试一试,需要有更清晰的终点:: 1. 验证猜想 最熟悉:因为编程中的调试其实最重要的目的就是验证猜想 如:引入一种新技术或框架,验证 API 的调用结果或运行输出是否如你所想, 即使最终否决了,那你也获得了判断的依据与知识。 2. 收获结果 定义清楚你尝试的这件事,到底能收获怎样具体的结果。 比如:考试,尝试的收获就是要通过。 3. 体验过程 有时候结果并不确定, 比如,创业:体验过程恐怕多于收获最终结果。 4. 理解现实 尝试一个新东西或学习一个新知识,有时未必真是为了将来有朝一日能用上它, 而主要是为了完善你的知识与认知体系,然后再去理解现实为什么是这样的 这种尝试事实上扩大了你的知识边界,尝试的也许是孤点, 但你可以进一步找到它们的连接处,形成体系 总结 ^^^^ 试一试,是走出舒适区的一次行动,这本是一个好的出发点,但若只有一个模糊的终点,那么它带来的更可能就是无谓的浪费。 .. note:: 试一试,不仅要有一个好的出发点,还需要一个清晰的终点,在这个终点你可能:验证猜想、收获结果、体验过程、理解现实。而在起点和终点之间,你需要选择一条更现实的路径,通过不断地尝试,走出自己的体系。 28 | 提问: 从技术到人生的习惯 ----------------------------- 提问这个习惯,我有三个层面的理解:: 1. 如何问? 2. 问什么? 3. 为何问? 如何问-提问之术 ^^^^^^^^^^^^^^^ .. note:: 提问的第一个原则:提供足够的信息,让人能够回答。 草率的问题是懒惰的问题,通过搜索引擎就能简单获得;草率的问题是模糊的问题,让人没法回答。而更有意义的提问是把解答题变成选择题,提供你的选项,展现你探索了哪些路径,省去了可能产生的反问。也许你的某条路径已经非常接近答案了,只是卡在了某个点上,知道答案的人一看就明白了,也很容易回答。 .. note:: 提问的第二个原则:提供更多的选项,让人方便回答。 即使你的问题能够回答,也方便回答,但也可能得不到回答。因为,回答问题需要有驱动力。提问本是一种索取,要让人有更多的回答动力,还需要付出。付出一种态度,表达感谢;付出一份可供交换的视角,建立讨论的基础。 .. note:: 提问的第三个原则:提供交换价值,建立讨论基础,表达感谢态度,让人乐于回答。 How To Ask Questions The Smart Way中文名是《提问的智慧》中归纳了关于提问之术的三个方面:: 1. 提让人能够回答的问题:草率的问题,只能得到一个草率的答案。 2. 提让人方便回答的问题:你得到的答案的好坏取决于提问的方式和开发答案的难度。 3. 提让人乐于回答的问题: 只索取而不愿思考和付出的提问者, 要么什么也得不到, 要么只会得到 RTFM 或 STFW 问什么-求解之惑 ^^^^^^^^^^^^^^^ .. important:: 第一个需要建立的习惯:提出好问题比寻找已有问题的答案可能更有意义和价值。寻找答案,通向的是已有的结果;而提出新问题,也许会导向未知的宝藏,它可能是获得新知的起点。 .. important:: 第二个需要建立的习惯:当遇到暂时没有答案的问题时,先记录下来。 当我开始写作后,就开始养成了这个习惯。大部分过去写的文章都来自于这些问题记录,定期地回顾下,曾经困扰我的问题,今天能解决了吗?一开始有很多具体的技术性问题,就因此写了很多技术文章。后来又有了更多复杂的问题,也就又写了不少思考性的文章。每写一篇,意味着当下的我对这个问题至少有了答案。无论这个答案如何,从某种意义上说,今天的我相比当时面临问题没有答案的我,就已经成长了。 .. note:: 先从一个记录问题,积攒 “问什么” 的习惯开始,不断去积累并留下一些东西,将来再定时去回顾这些问题,也许就会得到意外的收获。 把暂时这阶段还没法回答的问题按一种模式记录下来,比如下面这样:: 1. 问题的上、下文 2. 问题的具体描述 3. 问题的解决思考和思路 4. 问题的解决方案和具体技术或办法 5. 问题解决后留下的思考或其他延伸的疑问 .. note:: 保持积累,持续给予,终有所获。 为何问-价值之道 ^^^^^^^^^^^^^^^ .. note:: 选择决定命运,什么来决定选择?价值观。 价值观,是我们对事情做出判断,进行选择取舍的标准。每个人都有价值观,无论你能否清晰地定义与表述它,这些观念都决定了你的行为标准。 .. important:: 第三个习惯:为何而问?获得答案,认清自我,选择自己的价值之道。 总结 ^^^^ :: 1. 如何问,是关于提问的 “术” 考虑让人能够回答,方便回答和乐于回答; 2. 问什么,是关于成长的 “惑” 积累问题,寻找答案并分享,从而完成价值积累、传递与交换 3. 为何问,是关于选择的 “道” 价值观的选择决定了不同的道 29 | 偏好: 个人习惯的局限与反思 ------------------------------- 习惯形成VS共识达成:: 很多约定俗成的代码规范,基本就是从早期一些人的习惯中加以提炼总结出来的, 然后形成了大家共同认可的好方法,并在组织层面形成了规范。 形成了规范的东西,就不再是从个人习惯的角度去强加于人了,而是大家的共识达成。 “编程智慧” 类的好方法,不太好形成具体的规范描述:: 1. 设计模式。 遵守设计模式能让你少踩坑的,但如何灵活地采用合适的模式又是另一种智慧 2. 术语约定。 约定了术语,总是能让口头的概念和落在代码上的东西保持一致 减少沟通歧义,从而更高效。 3. 单元测试。 这比任何的评审来得可靠, 哪里该写多少测试用例,哪里可以不写,这又是智慧了。 但不要刻意为了追求覆盖率而去写,覆盖率的技术统计方法其实是很唬人的 4. 随时重构。 对于技术债务,每个月付点“利息”,比好几年后“连本带息”还感觉轻松 这条的特殊点在于,这可能是大部分程序员都认可的好方法, 但却不是大部分人的习惯。 因为技术上的债,实在自己还不起,总是可以推脱出去给下个“倒霉的家伙”, 但从长远角度看,这样的推脱不会让你获得成长,甚至还会阻碍你的发展。 30 | 写作: 写字如编码 --------------------- 参见:``如何写作`` 31 | 画图: 一图胜千言 --------------------- 参见:``架构:架构图技巧`` 32 | 演讲: 表达的技术 --------------------- 参见:``如何演讲`` 33 | 定义: 阶梯与级别 --------------------- 判断不同级别,选择三个相对容易判断的维度:: 1. 具备什么能力? 2. 解决什么问题? 3. 产生多大影响? 1. 初级 ^^^^^^^ 多属于刚入职场的新人。这个级别基本完成的都是螺丝钉级别的工作,影响很有限。 2. 中级 ^^^^^^^ .. note:: 相对初级最大的质变在于:独立性。 基本要求就是:: 完成动作、达成品质和优化效率,属于公司 “动作执行” 层面的中坚力量 .. note:: 不少同学卡在这一阶段,就是因为虽然不断在完成工作,但却没有去反思、沉淀、迭代并改进,从而导致自己一直停留在了不断的重复中。所以,在工作中要保持迭代与改进,并把你的经验分享给新来的初级同学,这样在未来之路你不仅会走得更快,而且也可能走得更轻松。 3. 高级 ^^^^^^^ .. note:: 不仅要能独立完成工作,还要能独立负责。他们能独立负责一个大系统中的子系统或服务,并成为团队骨干或最重要的个人贡献者。 在 “动作执行” 层面:: 不仅能独立完成高级难度的开发任务, 而且在用户体验(品质提升)和性能优化(优化效率)方面有全面的考量。 也就是说, 不仅仅可以把开发任务完成得又快又好,而且还能清晰地定义出多快、多好。 比如, 一个服务的响应时间 99.9% 是在 20 毫秒内, 内存消耗最大不超过 1G,并发吞吐量 10000+/s, 类似能用清晰的数据来定义服务品质和效率。 高级别需要面对的问题就不再是单一维度的技术问题了,他们需要结合业务特性去考虑设计合理的解决方案。熟悉业务领域内的应用系统架构以及各个部分使用的技术,能根据业务特性,合理进行分层设计,实现高效率、低成本的运维或运营。 .. note:: 初、中级别的能力提升与影响输出是通过经验的归纳总结与分享,那么高级则需要在经验这种偏个体特性的基础上,再进行抽象提炼,沉淀方法论。换言之,通过个人的经验,研究行业的优秀实践,再结合自身实践和逻辑推导,沉淀出切合现实的方法论,并在团队内部推广应用。 4. 资深 ^^^^^^^ 有深度和资历(即广度)两个层面,对应到职业生涯路线上,也有两个方向:: 1. 资深工程师 2. 架构师 除了经验分享和方法论沉淀,还有产品和团队两个考虑维度:: 即使是做纯技术的东西,最终的影响也是通过技术产品来完成的; 而另一方面则是团队的梯队建设、结构调整与协作优化,决定了团队外在表现。 这两个维度: 前者可能资深方向侧重多一些, 后者则是架构师方向需要侧重思考实践的。 5. 专家 ^^^^^^^ .. note:: 表明了某种领域的明确建立。 积累多年,建立体系,形成领域,他们需要解决的最重要的问题是:: 面向未来不确定的战略问题 这就像机器学习用过去长期积累的数据,建立起一个模型,用来预测和判断未来。未来不可测,但建立好了一个领域体系后,当未来到来时,就可以很快地将新出现的信息加入到现有的领域体系中去,从而修正模型,做出快速地调整与决策。 34 | 晋升: 评定与博弈 --------------------- 标准维度 ^^^^^^^^ :: 1. 通用能力,包括学习能力、沟通能力和领导能力等 2. 业务能力,包括业务理解和领域建模等 3. 技术能力,包括深度、广度和技能应用等 4. 影响力,如知识总结、知识传承和人才培养 过程识别 ^^^^^^^^ :: 靠 “域” 的判断。 域,即领域,包含了:责任域和能力域 责任域,就是你负责什么,这个相对容易识别。而能力域则过于抽象,很难清晰识别,在述职这样的形式中,最容易判断的仅仅是表达和沟通能力;至于业务和技术能力,虽不那么容易判断,但好在其有最好的展现形式:作品。 对于程序员,作品可以是一个完整的系统,但其展现不应该是一系列的技术点,而是先有整体(面),再深入局部(点),应该是一个画龙点睛的过程。从这样的展现过程中就能很好地体现出晋升者的业务与技术能力。 博弈权衡 ^^^^^^^^ 四个概念的含义如下:: 1. 民意:人民的意图; 2. 民义:人民最在乎的公平和正义; 3. 民力:人民让渡给国家和政府维护公平和正义的必要力量; 4. 民利:人民的利益。 .. note:: 在现代社会中,一切都是有成本的,绝对的正义是不存在的。当给予一部分人正义时,可能要以在其他地方付出巨大的成本为代价。如果一个判决伸张了正义,但是让受害的一方更倒霉,这就违背了司法中关于民利的原则。——吴军 晋升的本质是承担更大的责任,而责任和能力是需要匹配的,晋升就是完成这样一种匹配关系的过程。保持不断学习和提升能力,找到并承担起合适的责任域,那么后续的晋升并贴上一个相应的职级标签,就是一件自然而然的事情了。 35 | 关系: 学徒与导师 --------------------- 导师(Mentor)制度的初衷是为了帮助新员工快速熟悉公司环境,并提供工作技能和个人成长的帮助,正所谓 “传帮带”。 .. note:: 给人当学徒,就给你提供了这个机会。你现在把自己和一个高手连接在了一起,你可以从内部了解第一手的经验。这就是学徒工作的协议:用礼敬和服务,换取机会——而这个机会还不是立功露脸的机会,而是学习实践的机会。——万维钢有篇文章叫《给前辈铺路的人》 .. note:: 作为导师,带好了徒弟,接手并取代了你当前正在做的事情,你才有可能解放出来去做更高层次和更大维度的事情。而作为学徒,你需要吸取德里克的经验:学习和成长是自己的事,严肃待之,行动起来,自助者,人亦助之。 36 | 核心: 安全与效率——工程技术的两个核心维度 --------------------------------------------- 核心 ^^^^ .. note:: 核心,意味着最重要的,一切复杂的工程技术方案都是围绕着它来运转。 复杂系统的目的:: 一是为了确保安全(Safety) 二是为了提高效率(Efficiency)。 安全与效率的平衡,是所有工程技术的核心。 安全 ^^^^ .. figure:: https://img.zhaoweiguo.com/knowledge/images/jikes/jinjies/security1.png 工程 “安全“ 的狭义和广义分类 安全开发:: 就是为了保障交付的程序代码是高质量、低 Bug 率、无漏洞的。 从开发流程、编码规范到代码评审、单元测试等, 都是为了保障开发过程中的 “安全” 安全运维:: 就是为了保障程序系统在线上的变化过程中不出意外,无故障。 但无故障是个理想状态,现实中总会有故障产生, 当其发生时最好是对用户无感知或影响范围有限的。 安全运行:: 为了应对 “峰值” 等极端或异常运行状态,提供高可靠和高可用的服务能力。 效率 ^^^^ .. figure:: https://img.zhaoweiguo.com/knowledge/images/jikes/jinjies/efficiency1.png “效率”的划分 开发效率:: 个体,就是程序员个人 除了受自身代码设计与编写能力的影响,同时还要看其利用工具的水平。 源码管理工具与技巧可以避免无谓的冲突与混乱; 代码模板与开发框架能大幅度提升代码产出效率; 持续集成工具体系则能有助于快速推进代码进入可测试状态。 群体,就是一个团队 其开发效率最大的限制经常是架构导致的。 一个工程项目几年后,代码库越来越大,而功能越改越困难。 一个小功能变化,也要改上好几天,再测上好几天 这通常都是架构的问题,导致了团队群体开发效率的下降 以后端服务架构技术演进的变化为例: 从单体应用到面向服务架构思想,再到如今已成主流的微服务架构实践, 它最大的作用在于有利于大规模开发团队的并行化开发, 从而提升了团队整体的效率。 理想情况,每个微服务的代码库都不大, 变化锁闭在每个服务内部,不会影响其他服务。 微服务化一方面提升了整体的开发效率, 但因为服务多了,部署就变复杂了,所以降低了部署的效率。 但部署效率可以通过自动化的手段来得到弥补。 另一方面,每个微服务都是一个独立的进程, 从而在应用进程层面隔离了资源冲突,提升了程序运行的 “安全” 性。 运维效率:: 可以从 “检查”“诊断” 和 “处理” 三个方面来看: 1. 检查: 一个运行的系统,是一个有生命力的系统,并有其生命周期。 在其生命周期内,要定期检查,获取系统的“生命体征”的多维度信息汇总, 供后续的诊断分析。 2. 诊断: 当异常 “体征” 指标出现时,很难简单地判断到底哪里才是根本原因, 需要关联的因果性分析来得出结论, 最后智能地发出告警,而不是被告警所淹没。 3. 准确地诊断之后,才能进行合适地处理 常见的线上处理手段有如下三类: 1. 恢复:重启或隔离来清除故障、恢复服务 2. 变更:修改配置或回滚程序版本 3. 限制:故障断路或过载限流 运行效率:: 关键就是提高程序的 “响应性”,若是服务还包括其 “吞吐量”。 所有的优化手段都可以从下面两个维度来分类: 1. 更多 2. 更快 负载均衡器让更多的机器或进程参与服务,并行算法策略让更多的线程同步执行。 异步化、无锁化和非阻塞的算法策略让程序执行得更快, 缓存与缓冲让数据的读写更快。 .. note:: 有时在某些方面 “安全” 和 “效率” 之间是相互冲突的,但工程技术的艺术性就恰恰体现在这冲突中的平衡上。 37 | 过程: 规模与协作 —— 规模化的过程方法 ----------------------------------------- 需求与调度 ^^^^^^^^^^ .. note:: 可以学习、借鉴下操作系统的资源调度策略。 几种常见的调度策略:: 1. 先来先执行 2. 执行起来最快的先执行 3. 占用资源最少的先执行 4. 释放资源最多的先执行 5. 高优先级的先执行 需求调度,可以像操作系统一样运转,形成一个规模化的需求调度体系,并通过多种调度策略来平衡需求的响应性和投入产出的价值最大化。 设计与开发 ^^^^^^^^^^ 规模化的设计思路,一方面是自顶向下去完成顶层设计,另一立面就是要让系统具备自底向上的演化机能。 顶层设计主要做两件事:: 一是去建立系统的边界。系统提供什么?不提供什么?以怎样的形式提供? 二是去划定系统的区域。也就是系统的层次与划分,以及它们之间的通信路径。 一个规模化的系统既要靠前瞻的设计视野,也依赖后验的演化机能,这样才可能将前瞻蓝图变成美好现实。 测试与运维 ^^^^^^^^^^ 以测试为例进行规模化的最佳方式,就是打造一条 “测试机器” 流水线 关于打造 “机器” 的三个核心点,这里再强调一次:: 1. 流程规则 2. 工具系统 3. 规范共识 每一个具备一定规模的组织都有对应的规模化工程过程,而且这个过程的形成受公司文化、团队构成、组织架构,甚至业务特性共同决定 38 | 思维: 科学与系统 —— 两类问题的两种思维解法 ----------------------------------------------- 什么是工程思维?从过往经验中提炼出的理解是:一种具备科学理论支撑,并成体系的系统化思维。 做了多年的软件开发工程,碰到和解决了数不清的问题,最终这些问题,稍微抽象一下,可以归为以下两类:: 1. 可以简单归因的问题:属于直接简单的因果关系 2. 难以简单归因的问题:属于间接复杂的因果关系 科学与理论 ^^^^^^^^^^ 第一类问题,现象清晰,归因明确,那么它唯一的难处就是为这个问题找到最优的解决方案。求解最优化问题,就需要科学与理论的支持,也即:科学思维。 .. note:: 科学常常指出正确的方向,而工程则是沿着科学指出的方向建设道路;在工程中必须首先使用在科学上最好的方法,然后再作细节的改进。——吴军《计算机科学与工程的区别》 .. important:: 理论的意义不在于充当蓝图,而在于为工程设计实践提供有约束力的原理;而工程设计则依循一切有约束力的理论,为实践作切实可行的筹划。简言之,科学理论确定了上限,工程实践画出了路线。 系统与反馈 ^^^^^^^^^^ 第二类问题,结果明确,但归因很难,那么找到真正的原因就是第一个需要解决的难点。这时,我们就需要用另一种思维方式:系统思维。 系统问题的典型特征:: 1. 多次试图解决一个问题,却总是无效 2. 新人来了就发现问题,老人一笑了之 .. note:: “所谓系统,就是一个由很多部分组成的整体,各个部分互相之间有联系,作为整体又有一个共同的目的。” ——万维钢《线性思维与系统思维》 一个系统中可以有若干个正反馈和若干个负反馈回路,正反馈回路让系统或者增长、或者崩溃,是要偏离平衡,负反馈回路则尽力保持系统的平衡。对你想要解决的这个问题而言,可能就有一个回路,正在起主导的作用!如果你能发现在系统里起主导作用的回路是什么,你就抓住了系统的主要矛盾,你就找到了问题的关键所在。 总结 ^^^^ 软件工程,是研究和应用如何以系统性的、规范化的、可度量的过程化方法去开发和维护软件;而实际上软件开发本身就是一个系统工程,里面存在很多没法简单归因的第二类问题,它们没有通用的解法,只有通用的思维。 .. note:: 一个优秀的工程师应该同时具备科学思维和系统思维,它们是工程思维的两种不同表现形态:系统思维洞察问题本质,科学思维发现最优解法。 徘徊 ==== 39 | 职业倦怠: 如何面对 ----------------------- 倦怠感 ^^^^^^ 1974 年,美国临床心理学家弗罗伊登贝格尔(Herbert J. Freudenberger)首次提出 “职业倦怠” 的概念,用来指人面对过度工作时产生的身体和情绪的极度疲劳。 * 短时的倦怠期。这种短期的倦怠感觉其实和感冒差不多常见,年年都能碰上一两次 * 长期的倦怠感。它与你对当前工作的感受有关 工作区 ^^^^^^ .. figure:: https://img.zhaoweiguo.com/knowledge/images/jikes/jinjies/work-zone1.png 工作的 “三区域” 图 * 目的意义,这是工作的终极之问。它决定了你的很多选择,以及你接受什么、拒绝什么,是工作愿景背后的灵魂所在。 * 职业生涯,是个人一生职业愿望的追寻过程。它由长期目标驱动,是追寻 “目的意义” 的一条你所期望的路径 * 工作岗位,这不过是你现在上班的地方,包括了位置、角色、关系、职责与薪酬的总和。 40 | 局部最优: 如何逃离 ----------------------- .. note:: 机器学习就有一个类似的局部最优化问题,即:算法进入了局部最优解。 徘徊 ^^^^ 当你知道自己做得很好,但却没有感觉到成长与进步时,那么也许你就正在徘徊了。 逃离 ^^^^ 站在局部的最优点,走出徘徊的第一步,总是从下山开始,而这样的选择并不容易。 41 | 沟通之痛: 如何改变 ----------------------- .. note:: Code is cheap, talk is the matter! 程序员最容易产生沟通争论的地方:: 沟通需求和沟通技术方案 .. note:: 教训是:千万不要让两个都自我感觉很牛的程序员去同时设计一个技术方案。假如不巧,你已经这么干了并得到了两个不同的方案,那么记住,就别再犯下一个错:让他们拿各自的方案去 PK。因为这样通常是得不到你想要的“一个更好的方案”,但却很可能会得到“两个更恼怒的程序员”。 该怎么解决:: 1. 以理服人 把握一个度,对事不对人,切勿意气用事 技术的 “理” 包括:先进性、可验证性、和团队的匹配性、时效性、成本与收益 不合适的“理” 包括:风格、口味、统一、政治等 2. 以德服人 经验丰富、德高望重的“老司机”裁决,并且双方也都是认可的 “老司机”裁决最好站在他所认同的 “理” 这个客观存在上 3. 以力服人 粗暴的权力来裁决,看双方部门老大或老大的老大,谁更有力或给力 .. note:: 沟通一般有两个目的:一是获取或同步信息;二是达成共识,得到承诺。前者需要的是清晰的表达和传递,后者就需要更深的技巧了。这些技巧说起来也很简单,核心就是换位思考、同理心,外加对自身情绪的控制,但知易行难在沟通这件事上体现得尤其明显。 认识与改变 ^^^^^^^^^^ 对沟通做下拆解,它包括三个方面:: 1. 内容 对不同的人,你就需要准备不同的内容 2. 形式 包括: 面对面、书面、演讲…… 3. 风格 一对一的私下沟通 一对多的场景,比如演讲、汇报和会议 .. note:: 判断一个程序员是否具备 “换位思考” 的能力有一个好方法,那就是看他怎样向没有技术背景的人解释技术问题。——保罗·格雷厄姆(Paul Graham)《黑客与画家》 沟通之难就在于清晰地传递内容和观点。当你要向其他人详细解释某样东西的时候,你经常会惊讶地发现你有多无知,于是,你不得不开始一个全新的探索过程。这一点可以从两个方面来体会:: 1. 你只需要尝试写点你自认为已经熟悉掌握的技术,并交给读者去阅读与评价。 2. 每过一段时间(比如,一个季度或半年)尝试去总结,然后给同事分享下你工作的核心内容,再观察同事们的反应和听取他们的反馈,你就能体会到这一点了。 .. note:: 沟通改变的第一步就是从考虑接收方开始的,看看接收方能吸收和理解多少,而非发送了多少。而沟通问题的三个方面——内容、方式与风格——的考虑,都是为了让接收更方便和容易。 42 | 技术停滞: 如何更新 ----------------------- 关于 “刻意练习”:: 1. 只在 “学习区” 练习,练习时注意力必须高度集中 2. 把训练的内容分成有针对性的小块,对每一个小块进行重复练习 3. 在整个练习过程中,随时能获得有效的反馈 .. note:: 在决策科学中有一个概念叫 “基础比率(Base Rate)”:所谓基础比率,就是以前的人,做同样的事,做到的平均水平。也就是说,如果别人做这件事需要那么长时间,基本上你也需要那么长时间,因为可能你没有那么特殊。 深度路线VS广度路线:: 深度路线学习方式: 如果需要学习新技能来解决工作上的一个具体问题 这是解决特定问题的一种捷径,属于痛点驱动式方法, 能让你快速排除障碍,解决问题 广度路线: 面临一种新兴技术,比如,近年火热的人工智能与机器学习, 不是要解决一个具体问题,而是要对这类新兴技术方向做评估、判断和决策 那么学习的方式就又完全不同,这时采用广度路线学习就更合适。 《软技能》一书的作者曾在书中分享过他的一个十步学习法:: 1. 了解全局 2. 确定范围 3. 定义目标 4. 寻找资源 5. 学习计划 6. 筛选资源 7. 开始学习,浅尝辄止 8. 动手操作,边玩边学 9. 全面掌握,学以致用 10. 乐为人师,融汇贯通 从「深度、广度」看十步学习法:: 在深度路线学习中,对全局、范围、目标的定向更聚焦, 因此寻找、筛选的资源会更窄,学习计划的迭代期更短, 很快就走完了前 6 步,并进入动手实践、反复迭代的过程中,直到把问题解决。 在广度路线的学习中,前 6 步会花去大量的时间, 因为这时你面临的问题其实是对新技术领域边界的探索。 .. note:: 在英语中,技能对应的词是 Skill,而能力对应的是 Ability。技能是你习得的一种工具,那么能力就是你运用工具的思考和行为方式,它是你做成一件事并取得成果的品质。 从程序员到架构师,“架构” 显然不是一种技能,而是综合应用多种技能的能力。 .. note:: 同时保养很多技能是不太合理和现实的,更优化的选择是:持续保养主要的生存技能,合理开发辅助技能,形成自己独有的技能组合,沉淀能力模型,发展能力矩阵。 43 | 无法实现: 困扰与反思 ------------------------- “技术上无法实现!”的真正原因:: 1. 不知 成为了遮挡我们因不知而畏惧的面具 2. 不愿 成为了我们推脱的借口 反思:: 大部分的用户需求,技术上总是可以实现的。 这些需求的真正限制,要么是时间,要么是资源。 思考框架:: 1. 全局背景 针对每一类问题的方案,可以先去大概有个了解,但这里还不需要很深入 2. 聚焦范围 本质就是从上面的全局分类中,聚焦一个范围,然后集中深入调研评估 3. 定义标准 需要清晰定义这部分问题解决的成功标准。 4. 深度评估 有些是你已经轻车熟路的实现路径, 另一些则是你可能从未走过的陌生之路。 .. note:: 当面对任何一个需求,除非能一下从理论上发现其实现的物理限制,我们恐怕不能够再轻易说出 “技术上无法实现” 了。即使真的是无法实现的需求,也有可能通过变通需求的方式来找到一条可实现的路径。“技术上无法实现” 的口头禅仅仅是我们阻挡需求的快捷方式,但这样的思维也阻碍了我们进一步去找到真正的实现路径和优化方案。 44 | 完成作品: 理想与现实 ------------------------- .. note:: 维基百科上对“作品”的定义是:作品,亦称创作、创意、著作,是具有创作性,并且可以通过某种形式复制的成品。从这个定义来看,作品最重要的特质是:创作与创意。 .. important:: 一个场景:当你给别人介绍自己时,只需要介绍自己的作品,而不再需要介绍自己的技能。 成长的路上,写过的代码最终也许会烟消云散,但完成的作品会成为你点亮的勋章。 .. note:: 技术需要懂的是产品提供的核心服务和流程,并清晰地将其映射到技术的支撑能力与成本上。 显性特征VS隐性特征:: 新函数取代了旧函数,那多余的旧函数就变成了负债而非资产,是需要去清理的。 重构代码变得更简洁和优雅,可读性增强,节省了未来的维护成本。 一个能同时服务一万人的程序实例,没法加十个实例简单变成能同时服务十万人的系统 这些都是技术冰山下的隐性特征 显性的错误会有测试、产品甚至最终用户来帮你纠正,但隐性的错误却很难有人能及时帮你发现并纠正。 45 | 代码评审: 寄望与哀伤 ------------------------- 代码评审的初衷是提高代码质量,在代码进入生产环境前经过同行评审来发现缺陷,降低损失概率。 .. note:: 一般的代码审查速度约是一小时 150 行,对于一些关键的软件,一小时数百行代码的审查速度太快,可能无法找到程序中的问题。对于产品生命周期很长的软件公司而言,代码审查是很有效的工具。 .. important:: 投入巨大的时间成本 —— 一小时审查 150 行代码,再快就不利于发现潜在缺陷了,而且更适用于长生命周期的产品。 .. note:: 代码评审较多的都是研发通用底层技术产品或中间件的团队,而做业务开发的团队则较少做代码评审。两者对比,底层技术产品或中间件的需求较稳定,且生命周期长;而业务项目,特别是尝试性的创新业务,需求不稳定,时间要求紧迫,并且其生命周期还可能是昙花一现。 困境:: 1. 困境一,Deadline 已定,时间紧迫,天天加班忙成狗了,谁还愿意搞代码评审? 很多时候都不是我们自己能确定和改变的。 2. 困境二,即使强制推行下去,如何保障其效果? 团队出于应付,每次走个过场,那么也就失去了评审的初衷和意义。 3. 困境三,团队人员结构搭配不合理,新人没经验的多,有经验的少。 新人交叉评审可能效果不好, 老是安排经验多的少数人帮助 Review 多数新人的代码, 新人或有收获,但对高级或资深程序员又有多大裨益? 一个好的规则或制度,总是需要既符合多方参与者的个体利益 又能满足组织或团队的共同利益, 这样的规则或制度才能更顺畅、有效地实施和运转。 4. 困境四,有人就是不喜欢别人 Review 他的代码,他会感觉是在找茬。 比如,团队中存在一些自信超强大的程序员,觉得自己写的代码绝对没问题, 不需要别人来给他 Review。 参考路径:: 在 Google,任何代码,在被进行严格或者明确的代码评审之前,是不允许提交的。 这一点,Google 是通过工具自动就控制了未经评审的代码就没机会进入代码库。 .. note:: 给自己 Review 是一种自省,自我的成长总是从自省开始的。 46 | 人到中年: 失业与恐惧 ------------------------- .. note:: 最可怕的失业就来自变革引发的技能性淘汰(如:国企下岗),其次是环境引发的萧条(如:金融危机),再次是技能虽然还有普适价值,但自身却适应不了环境变化带来的改变与调整。 中年人和年轻人本应在不同的战场上。年轻时,拼的是体力、学习力和适应能力,是做解答题的效率与能力;中年了,拼的是脑力、心力和决策能力,是做对选择题的概率。 .. note:: 跟年轻的大脑相比,中年大脑在两个方面的性能是下降的:计算速度和注意力。其他方面,比如模式识别、空间想象能力、逻辑推理能力等等,性能不但没有下降,而且还提高了。 47 | 该不该去创业公司 --------------------- 一. 期望 ^^^^^^^^ :: 1. 自由成长 相对成熟的大公司,会有更大的自由度,能接触的东西更多, 但需要处理的问题也更多、更杂, 会让人更容易自由成长为一种解决各类问题的多面手。 对于程序员而言,可能就是综合能力更强,但在特定的专业领域又不够精深 2. 变身土豪 因上努力,果上随缘,尽人事,听天命。 3. 追求梦想 你愿为 “喜欢” 支付多大的成本与代价? 二. 条件 ^^^^^^^^ :: 1. 创始人创业的目的是什么?期望是什么? 创业毕竟是一段长期的旅程,大家的目的、价值观、期望差距太大, 必然走不长远 2. 创始人以前的口碑和信用如何? 有信用污点的人并不值得合作与跟随,而且创业公司期权,最终能否兑现? 就国内的创业环境而言,这一点也很是关键。 3. 公司的核心团队成员如何? 看看之前都有些什么样的人,你对这个团队的感觉契合么? 价值观对味么?这个团队是合作融洽,还是各怀鬼胎? 有些小公司,人虽不多,办公室政治比大公司还厉害。 4. 对你的定位是什么? 创业公司在发展初期容易遇到技术瓶颈, 会以招 CTO 的名义,来找一个能解决当前技术瓶颈的专业人才。 也许你解决完问题,渡过了这个瓶颈, 但这之后老板会觉得你的价值还足够大么? 有句话是这么说的:“技术总是短期被高估,长期被低估”。 而你自身还能跟得上公司的发展需要么? 5. 公司是否有明确的业务方向? 业务的天花板多高?有哪些对手?相对竞争的核心优势是什么? 业务的天花板有多高?也就是能做到多大? 三. 决策 ^^^^^^^^ .. note:: 决策之前,期望是内省,条件是外因;决策就是将客观的外因与主观的内省进行匹配判断选择的过程。 实例: 你有一个机会经过一条路,这条路两边都是大大小小的宝石,但你只能走过这条路“一次”,捡起其中“一块”宝石,中间不能更换。这里捡到最大的宝石就是最优策略,但你怎么实现这个最优策略呢?其实没有方法能保证。 .. note:: 先哲的建议是,前 1/3 的路径,你只观察周围的宝石,最大的有多大,平均大小大概在什么水平,但不出手捡。经过这前 1/3 的路程,你应该有一个预期的大小标准,这个标准可能略比平均大小大一些,但不应该以之前看见的最大的宝石为标准。再走剩下的 2/3 路程时,你只要看见第一个符合这个标准的宝石,就可以出手捡起,之后快速走完全程。 这个方法虽不能保证你捡到最大的宝石,但可以很大概率保证你捡到符合自己预期标准大小的宝石,而这个预期标准,就是你的 “满意标准”。这个捡宝石的决策就是 “满意决策”,满意决策是一种折衷决策,只是在当时情况下可选的最佳行动方案。 比如你想在3个月内找到工作,那么1/3就是1个月 .. note:: 人生中会有很多类似 “捡宝石” 这样的决策场景:找工作、找伴侣、选房子、买股票,甚至是买任何东西,只不过因为其中大部分东西的购买支付代价低,所以你不会有太大的决策压力。前 1/3 的路程就是让你在决策前充分观察、调研、确定你的满意标准,之后面对第一个满意对象就能够直接决策,然后继续快速前行。 满意决策的方案就是让你做完决策不纠结,即使后来回头看离最优还有差距,也不遗憾。因为,人一生要面对的决策很多,“满意决策” 的办法让你省下了 2/3 纠结的路程,继续快速前行。 48 | 该不该接外包 ----------------- 桥水基金创始人雷・达里奥(Ray Dalio),也是近年畅销书《原则》的作者,制作过一个视频叫《三十分钟看清经济机器如何运转》,他在视频的末尾提出了三条建议:: 1. 不要让债务的增长速度超过收入 2. 不要让收入的增长速度超过生产率 3. 尽一切努力提高生产率 .. note:: 生产率是一个宏观经济术语,用到程序员个人身可以理解为是个人价值的产出率,即如下等式: ``个人生产率 = 个人价值的产出率`` 程序员赚钱的方式:: 1. 咨询 / 培训 2. 演讲 / 分享 3. 投稿 / 翻译 4. 写书 5. 写博客 / 公众号 6. 课程 / 专栏 7. 兼职 / 外包 个人价值的提升可能不会立刻反映到当下的收入上,就像公司的内在价值提升了可能股价还没涨一样。但长期来看,价格总是要回归价值的,这是经济规律,宏观如国家,微观如个人。 梁宁有篇文章就叫《赚钱的事和值钱的事》,文中总结了这两点的差别:: 1. 赚钱的事,核心是当下的利差,现金现货,将本求利。 2. 值钱的事,核心是结构性价值,兑现时间,在某个未来。 值得接的外包,它包括下面一些特性:: 1. 如果外包项目对你的技术积累有好处,那么收点钱去实践提升下正好一举两得; 其实参与开源项目,本质就是不收钱的外包项目?它的收益就是让你更值钱。 2. 外包项目的成果具有可复制、可重用性 这样就可以通过大量复制和重用来降低一次性开发成本; 而成本和比较优势才是外包模式的核心竞争力所在啊。 3. 外包项目不是临时一次性的,而是需要长期维护的 而这种维护的边际成本可以依靠技术工具手段不断降低, 那这样的外包项目就是一个长期赚钱的 “机器” 了 .. note:: 去做值钱的事,打造值钱的结构,从知识结构、技能结构到作品结构与产品结构,然后等待某个未来的兑现时间。 49 | 技术干货那么多, 如何选 --------------------------- 循证与决策路径 ^^^^^^^^^^^^^^ .. note:: 循证大概是一个原始诉求,通过分析别人走过的路径,来拨开自己技术道路探索上的迷雾。 选择一种架构和种技术的依据是什么?Rod Johnson 认为,应该是基于实践的证据、来自历史项目或亲自试验的经验…… .. note:: 循证方式的技术决策路径:阅读技术干货文章,想从别人的分享中获得对自己技术方案的一个印证。这就是一种行业的实践证据,毕竟想通过听取分享去印证的,通常都是走过了一条与自己类似的道路。技术道路的旅途中充满着迷雾与不确定性,我们不过是想在别人已走过的类似道路中获得指引和启发,并得到迈出坚实下一步的信心。 循证的方式就是:即便你看到了一个更好的技术与架构方式,但也要结合自身的实际情况去思考实践的路径。例如:消息模型,作为一个核心的底层架构模型,也许刚起步未上线时,变更优化它只需要一两个程序员一两周的时间;但经过了数年的演进,再去完全改变时,就需要各端好几个团队配合,并忙上一两个季度了。 .. note:: 循证,不一定能立刻给你的当下带来改变,但可以给你的演进路径方向带来调整,未来将发生改变。 切磋与思考方式 ^^^^^^^^^^^^^^ .. note:: 技术干货多了以后,在类同的领域都能找到不同公司或行业的实践分享,这时不仅可以循证,还能够达到切磋和多元化思考的目的。 同一个技术方案在不同的时期,面临不同的环境,就会带来不同的成本,并做出不同的选择与取舍。虽然看起来是在走类似的路,但不同的人,不同的时代,不同的技术背景,这些都导致了终究是在走不同的路。路虽不同,但可能会殊途同归吧。 .. note:: 切磋带来的思考是:你不能看见别人的功夫套路好,破解难题手到擒来,就轻易决定改练别人的功夫。表面的招式相同,内功可能完全不同。切磋,主要是带给你不同的思维方式,用自己的功夫寻求破解之道。 连结与知识体系 ^^^^^^^^^^^^^^ 干货多了,时间有限,自然就存在一个优先级的选择阅读问题。出发点很简单,有两点:基于功利性和兴趣。 .. important:: 把过去自己所掌握的所有技术总结编织成一张 “网”,若一个技术干货分享的东西离我的 “网” 还太远,我就会放弃去了解。因为如果不能连结到这张 “网” 中,形成一个节点,我可以肯定它就很难发挥任何作用,很可能是我看过之后没多久就遗忘了。 .. note:: 如今技术发展百花齐放、遍地开花,但人生有限,所以你必须得有一种方式去做出选择,最差的可能就是所谓的随性选择。我觉得很多情况下是需要一个选择指导框架的,而对于如何选择阅读技术干货的问题,前面比喻的那张 “网” 就是一个我自己的指导框架。 即便是针对同一个问题或场景,我们也可以将已知的部分连结上新的知识和实践,形成更密、更牢固的技术体系之网。 .. note:: 从干货中提取知识和经验总结的案例,形成对已有知识的连结。这就是不断加固并扩大自己的技术知识体系之网。 .. important:: 总结来说:面对众多的技术干货,从循证出发,找到参考,做出技术决策,决定后续演进路线;在演进路上,不断切磋,升级思考方式,调整路径,走出合适的道路;在路上,把遇到的独立的知识点,不断吸收连结进入自己的技术知识体系之网。 50 | 技术分歧, 如何决策 ----------------------- 技术是客观的,有绝对正确与否的标准判断吗?:: 1. 关系数据库范式 VS 分布式领域反范式设计 2. 设计模式 VS 反模式设计 3. 物理删除数据 VS 设置删除标识位 “康威定律” 是这么说的:任何组织在设计一套系统时,所交付的设计方案在结构上都与该组织的沟通结构保持一致。康威定律告诉我们系统架构的设计符合组织沟通结构时取得的收益最大。 原则 ^^^^ .. note:: 康威定律,是和组织的团队、分工、能力与定位有关的,其本质是最大化团队的核心能力,最小化沟通成本。 在足够大的组织中,沟通成本已经是一个足够大的成本,有时可能远超采用了某类不够优化的技术方案的成本。每一次人事组织架构变动的背后,都意味着需要相应的技术架构调整去适应和匹配这种变化,才能将沟通成本降下来。而技术方案决策的核心,围绕的正是关于方案的实施成本与效率。 .. note:: 【原则】问题的解决方案处在技术分工的临界地带就容易产生这样的争论,而技术的临界区,有时就是一些无法用技术本身的优劣对错来做判断的区域。这时,最佳的选择只能是将前后端整体全盘考虑,以 **成本和效率** 为核心来度量,应该由哪方来负责这个临界区。 成本与效率背后的考量又包括如下因素:: 1. 团队:这是人的因素,关于团队的水平,掌握的技术能力和积累的经验 2. 环境:能利用的环境支持,公司内部的平台服务或外部的开源软件与社区 3. 技术:技术本身的因素,该项技术当前的成熟度,潜在的发展趋势 4. 约束:其他非技术约束,比如管理权限的干涉、限定死的产品发布日期等 .. note:: 技术没有绝对的标准,适合的技术决策,总是在受限的约束条件下,围绕成本与效率做出的选择权衡。 51 | 技术债务, 有意或无意的选择 ------------------------------- 认知 ^^^^ 技术债务,最早源自沃德・坎宁安(Ward Cunningham) 1992 年在一次报告上创造的源自金融债务的比喻,它指的是在程序设计与开发过程中,有意或无意做出的错误或不理想的技术决策,由此带来的后果,逐步累积,就像债务一样。 .. note:: 我们采用了一个非最优或不理想的技术方案时,就已经引入了技术债务。而这个决定,可能是有意的,也可能是无意的。有意产生的债务,一般是根据实际项目情况,如资源与期限,做出的妥协。 技术债务分成了好几类(from: 《老码农看到的技术债务》):: 1. 战略债务 特点是,负债时间长,但利息不算高且稳定,只要保持长期 “付息”,不还本金也能维持下去。 2. 战术债务 一般是为了应对短期紧急情况采取的折衷办法。这种债务的特点就是高息,其实说高利贷也不为过。 3. 疏忽债务 这类债务一般都是无意识的 管理 ^^^^ 不同角色关注的债务分类与形态也不太一样:: 1. 架构师关注的更多是战略债务,保持系统能够健康长期演进的债务平衡。 作为架构师,就像 CFO,需要长期持续地关注系统的资产负债表。 战略债务可能更多体现为架构、设计与交互方面的形态。 2. 开发工程师: 具体某个功能实现层面的代码债务,则更多落在相关的关注范围内 3. 测试工程师: 会关注质量方面的债务 一到交接时,各种文档债务就冒出来了 .. note:: 管理债务的目标就是识别出债务,并明了不同类型的债务应该在何时归还,不要让债务持续累积并导致技术破产。 只要感觉到团队生产力下降,很可能就是因为有技术债的影响。这时,我们就需要识别出隐藏的债务,评估其 “利率” 并判断是否需要还上这笔债,以及何时还。 清偿 ^^^^ 认识并理解了技术债务,识别出了系统中的各种债务,并搞清楚了每种债务的类型和利率,这时就需要确定合理的清偿还债方式了。 .. note:: 需要以周或月为单位计算的债务算作大债务,而只需一个程序员两三天时间内归还的债务算作小债务。 小债务的归还,基本都属于日常的重构活动,局限在局部区域,如:: 模块、子服务的实现层面。 大债务的归还,比如:架构升级:: 就需要仔细地考虑和分析机会成本与潜在收益 所以大债务归还要分三步:: 1. 规划:代表愿景 分析哪些债务需要在什么时间还,机会成本的损失与预期收益是多少 2. 计划:代表路径 细致的债务分期偿还迭代计划 3. 跟踪:代表过程 真正上路了,确认债务的偿还质量与到位情况 信用 ^^^^ 程序员的信用,更多体现在面对技术债务的态度和能力 —— 有意识地引入债务,并有计划地归还债务;无意识地引入债务,发现之后,有意识地归还。 52 | 选择从众, 还是唯一 ----------------------- .. important:: 走众争之路,拼的是努力,只能成为平均的普通人;走少有人走的路,拼的是选择、勇气和毅力,可以让你遇见独特的风景,为稀缺的机会创造可能性;走独一无二的路,真的是要拼天赋了。 .. note:: 2% 的人创造内容,而 98% 的人消费内容;写作,就是这么一件少有人走的路。要么写点值得读的东西,要么做点值得写的事情。——本杰明・富兰克林。写作本身就是一个关于选择的活动,而值得写的东西,本来也是稀少的。选择少有人走的路,通常也意味着你要大量地尝试,考虑自己的长处加上刻意的练习,虽不能保证成功,但却在创造可能性。 小技巧:待办事项列表(TO-DO List)所有的日常计划都应该是备用的 B 计划( Plan B),而真正的 A 计划(Plan A)就是变化 53 | 选择工作, 还是生活 ----------------------- .. note:: 人若没有目标,就只好盯着感受,没有平衡,只有妥协。 认清自己当前阶段的目标,定义清楚这个阶段的平衡点。一个阶段内,就不用太在意每一天生活与工作的平衡关系,应放到整个阶段中一个更长的周期来看,达到阶段的平衡即可。通过短期的逃避带来的平衡,只会让你在更长期的范围内失衡。 .. note:: 作为个人,你需要承担起定义并掌握自己生活轨迹的重任,如果你不去规划和定义自己的生活,那么别人就会为你规划,而别人对平衡的处理你往往并不认同。结合当下的处境与状态,没有静态的平衡,只有动态的调整。 .. note:: 紧要的是,去过你想要的生活,而非不得不过的生活。 借用一下投资交易中的一种颇有启发的策略:年轻时,要更多投资于风险更高、波动更大、但潜在收益也更大的股权类权益;随着年纪见长,就要慢慢增大更稳定和确定的债券类投资比例,降低股权比例。把这个思路用在平衡工作与生活上的话,大概是这样,假如对于一个非常有事业心和野望的人(可以理解为风险偏好大的人),大学毕业平均是 22 岁,那么就应该是 120 - 22 = 98,也就是 98% 的精力花在工作上,当然这里是广义上的 “工作”。而对于那些刚毕业但没有那么大野心的年轻人,也应该投入大约 80%(这是用 100 来减) 的精力在 “工作” 上。 .. note:: 人生,就是在风险中沉浮,平衡的交易策略就是用来应对风险与波动的。 我们应该追求过好这一生,而非追求平衡,如何才算 “好”,每个人都会有自己的答案。我的答案是:不是通过努力工作来过上想要的生活,而是先设定了想要的生活,自然而然工作就会成为生活中合适的一部分。 总结:: 1. 缺乏真正的目标时,只好盯着感受,把平衡当作目标,由此带来平衡选择的困扰 2. 不同的处境与状态,会有不同的平衡点,需要做出规划与选择 3. 短期只有此消彼长,长期才能动态平衡 4. 早期年轻时的高投入,换取将来平衡的能力与选择权 寻路 ==== 54 | 侠客行: 一技压身, 天下行走 ------------------------------- .. note:: 技能模型才是区分不同专业人才特点和价值的核心关键点。 工程师思维的大道,就是先创造一个好模型,然后想办法实现这个模型,工程师关心的是能不能用这个模型创造出东西来。 .. note:: 避开 “达芬奇诅咒”,围绕核心硬技能,发展 “一主多辅” 的技能模型树。 55 | 江湖路: 刀剑相接, 战场升级 ------------------------------- 技能的成长速度总会进入平缓阶段,并慢慢陷入瓶颈点,然后也许你就会感到焦虑;而焦虑只是一种预警,此时你还未真正陷入困境,但若忽视这样的预警,不能及时进行认知和技能升维,将有可能陷入越来越勤奋,却越来越焦虑的状态,结果走入 “三穷之地”(包括如下三种 “穷”):1. 结果穷:技能增长的边际收益递减;2. 方法穷:黔驴技穷,维度过于单一;3. 时间穷:年龄增长后你能用来成长的时间会变少,分心的事务更多,而且专注力会下降。 .. note:: 认知和技能升维带来新的成长收益,同时防止了单一维度的死胡同,而年长的优势正在于经验带来的理解力和思考力的提升。 56 | 御剑流: 一击必杀, 万剑归心 ------------------------------- .. figure:: https://img.zhaoweiguo.com/knowledge/images/jikes/jinjies/chengzhang1.png 程序员成长阶段要求的帮助和提供的指导变化趋势示意图:蓝色三角区域表明,随着你从入门初级成长到高级程序员的过程中,需要得到的帮助和指导越来越少;而红色三角区域表明,你能提供的帮助和指导应该越来越多。所在,在前面那个想象的 “泡面拔刀” 的场景中,作为高级程序员的你,更理想的做法应该是去指导年轻程序员如何解决问题的思路,而不是自己拔刀,唰唰两下搞定。 .. note:: 拔刀术,是亲自动手斩杀问题,难处在于维度单一,后期进境陷入瓶颈停滞;御剑术,是指导他人解决问题,难处在于打破习惯,剥离自我;万剑诀,是借助他人使之实现,难处在于剑的养成。它们的共通之处,都是基于长期的编程和工程训练,建立的系统化思维能力,创造模型来解决问题,而变化在于模型的适用对象不同,导致需要不停地调试合适的 “模型参数” 来适配问题,并且不论是技术框架还是人的 “模型参数” 都是在变化之中的。 “万剑诀” 是一项高杠杆率的技能。而高杠杆率的活动包括:: 1. 一个人可以同时影响很多人 2. 一个人可以对别人产生长远的影响 3. 一个人所提供的知识和技能,会对一群人的工作造成影响 * 如果走上同时影响多人的路线,这就是一条团队管理和领导者之路; * 如果走上影响长远的路线,你可能乐于分享、传授,这可能是一条布道师的路线; * 如果你通过提供知识和技能来影响其他一群人的工作,那么这可能是一条架构师的路线。 57 | 三维度: 专业, 展现与连接 ----------------------------- 涉及个人发展的方向分成了三个维度,包括:: 1. 专业 Profession 2. 展现 Presentation 3. 连接 Connection 1. 专业 Profession ^^^^^^^^^^^^^^^^^^ a. 专业能力:: 数学:数学就是计算机科学的基础; 物理:程序世界中的基本定律,如 CAP、NP、算法与数据结构; 化学:程序世界中的 “元素” 和属性,如编程语言平台、各类框架和系统特性。 语文:能写代码,能写好文档,起得好名字,表达好逻辑,让代码更可读、可懂; 英语:第一手的技术材料多来自英语世界; 生物:不同的技术都发展出了不同的生态体系,今天的系统几乎都在某种生态之中; 历史:任何一门新技术,都有其历史渊源,它从哪里来,将会到哪里去; 艺术:编程是一门艺术,一种逻辑与审美的表达; 经济:成本、收益、效率,有关技术决策的核心; 建筑:有关架构的一切,钢筋、水泥、脚手架、灾备、抗压、防单点以及相关的权衡。 b. 专业行为:: 包括规范化的工作流程和作风,严格的职业纪律与操守 敏捷专家肯特·贝克(Kent Beck)说过一句话: “我不是个优秀的程序员,我只是一个有着优秀习惯的普通程序员。” c. 专业产出:: 最终产出的结果是稳定的,可预测的,处在一定品质标准差范围内的。 2. 展现 Presentation ^^^^^^^^^^^^^^^^^^^^ 展现也对应着专业的三个子维度:: a. 展现专业能力:包括代码、架构、认知、决策 b. 展现专业行为:包括沟通、交流、表达、协作 c. 展现专业产出:包括作品、方案、洞察、演示 不同的展现形式:: a. 代码:Github 等提供最直接的围绕专业能力中编程能力的展现形式、证据和历史 b. 交流:日常的即时通讯、邮件、会议、交谈与协作中,展现关于专业行为的一切 c. 演讲:专业产出的重要形式,如汇报(业绩产出)、分享(作品与影响力产出) d. 写作:文字作品,一种长尾影响力的产出形式 3. 连接 Connection ^^^^^^^^^^^^^^^^^^ Dunbar’s Number:: 10: 好朋友 50% 以上的社交时间都值得花在每个阶段最好的这 5 个朋友身上 100: 指一年至少联系一次的人 1000: 凯文·凯利《一千个铁杆粉丝》(1000 true fans) 10000: 拥有一万个关注者。拥有了反馈,形成有效的讨论和互动。 100000+: 体现了一个信息、观点与影响力的传递网络 .. note:: 强连接交流情感,弱连接共享信息。而建立连接的关键在于:给予。 58 | 三人行: 前辈, 平辈与后辈 ----------------------------- 领域,是一个你自己的世界,在这个世界中,你不断地提出问题并找到有趣或有效的解决方案。进入这个世界的人,碰到的任何问题,你都解决过或有解决方案,慢慢地人们就会认识到你在这个世界拥有某种领域,并识别出你的领域。 .. note:: 针对培养新人,要以成长思维去考虑,而不仅仅是产能视角。为了获得长期的产能效率,有时不得不承担一些短期的成本压力。 .. note:: 前辈探路开拓,同辈携手并行,后辈参考借鉴。 59 | 三角色: 程序员, 技术主管与架构师 ------------------------------------- 从程序员到架构师不仅仅是一个名称的变化,它也意味着技能和视角的转变。 技术主管 ^^^^^^^^ 技术主管:: 1. 约 70% 的时间花在开发任务分解分配、开发实践、代码审核和风险识别上 2. 约 30% 的时间花在为保障系统按时交付所需要的各种计划、协作、沟通和管理上 .. note:: 拉姆·查兰 (Ram Charan) 写的《领导梯队》一书中提到:一个人的工作角色中至少有百分之五十以上的时间是花费在管理事务上,那么他的角色才算是一个经理(Manager)。所以技术主管(经理)更多还是偏重于技术工作,有点类似产品经理属于以经理命名却非真正的经理角色。 技术主管实际相比团队里的其他程序员对系统的视角更开阔,以更有策略和长远的方式来考虑问题。他们即使拥有比团队里所有其他程序员更高超的开发实现技能,对所有开发任务拥有最强大的实现自信,也需要转变为另一种 “借助他人使之实现” 的能力和自信,因为技术主管是一个承担更广泛责任的角色,必然导致能够专注有效编码的时间会相比以前减少很多,而这一点正是优秀程序员转变为技术主管所面临的最大挑战之一。 .. note:: 技术主管是一个过渡,继续往前走,如果偏向 “主管” 就会成为真正的管理者(经理),如果偏向 “技术” 就会走向架构师。 架构师 ^^^^^^ 技术主管的角色与架构师这一角色会产生一些职责上的重叠,事实上我认为在团队规模比较小的时候(十来人的规模),架构师和技术主管的职责几乎完全重叠,甚至技术主管还会代理一些团队主管的角色。 .. figure:: https://img.zhaoweiguo.com/knowledge/images/jikes/jinjies/architect2.png 架构师能力模型 如果把技术主管想成是站在楼顶看整个系统,那么架构师此时就是需要飞到天上去看整个系统了。架构师站在更高的空中维度去做关于软件系统的抽象和封装。如果技术主管的抽象和封装层次更多考虑的是语言函数、设计模式、代码结构等这一类的事务,那么架构师是站在整体软件系统高度,考虑不同子系统之间的交互关系、技术的合理性、需求的完整性、未来的演进性,以及技术体系发展与组织、产品商业诉求的匹配度。 .. note:: 架构师来对一些技术争端和方案进行决策判断,很多情况在于程序员对架构师在技术领域内专业力和影响力的信任,而建立这种专业力和影响力是实际构建架构师非权威领导力的来源。“非权威领导力”相对权威而言,管理者的权威领导力来自于公司正式任命的职位和职权,而架构师在大部分公司基本连职位职责都没定义清楚,更没有职权一说,所以实际上就不会有任何权威领导力。所以,架构师要发挥更大的作用和价值就需要去构建自己的非权威领导力,而这需要长期的专业力和影响力积累。 .. note:: 除此之外,架构师还承担着在技术团队和非技术团队(例如:产品设计等团队)之间的接口作用,明确产品的边界,勾勒技术蓝图,协调不同技能的技术团队协作,完成最终的软件系统交付。这时架构师的角色就像服务化架构中的 API,定义了协作规范、交互协议和方式,但并不会聚焦在具体的实现上。 .. figure:: https://img.zhaoweiguo.com/knowledge/images/jikes/jinjies/architect3.png 程序员、技术主管和架构师的职责表 60 | 三视角: 定位, 自省与多维 ----------------------------- “视角的选择,对解题的难易,关系重大”。而关于成长,放到程序模型中来类比,就是一道图论题,我们求解的是适合自己的最优路径。 分析成长路径难题的三个视角:: 1. 定位 2. 自省 3. 多维 1. 定位 ^^^^^^^ 定位,是一个时间视角,回顾初心,定位未来。定位的视角,是关于一条成长的时间路径,它关乎:昨日初心,今日功课,明日机会。 2. 自省 ^^^^^^^ 自省,自我的视角,关乎自身,是一个观察自己成长路上行为的角度。自省,从埋头做事,到旁观者视角的自我反思。 .. note:: 用「海尔迈耶系列问题」来问问自己,如果有回答不上来的,说明你对这项技术掌握并不充分,那就还不足以应用到实际项目里。 3. 多维 ^^^^^^^ 多维,是一个空间视角,关乎如何选择不同维度的成长路径。多维的路径,其实是从一个核心基础维度去扩散开的。 .. note:: 打造多维度竞争力的前提是,要先在一个维度上做得足够好,让其成为你赖以生存的维度,这个维度就是你的核心基础维度,而它是其他维度得以发展的根基。 关于“精通”可以拆解成两个层面:: 1. 第一层面,如学校时期学过的卖油翁所说的“无他,惟手熟尔” 表达了在当前维度的不断精进 关于精进:《程序员修炼之道:从小工到专家》 2. 第二层面,在一个领域形成自己的体系和方法论 方法体系即:“哲学” .. note:: 在第一层面上你达成了品质和效率,然后在第二个层面上,抽象出了当前维度的 “解”,那么就可以通过 “启发式” 方法应用到其他维度,具备了向其他维度扩展的基础,从一个细分领域到另一个关联领域的 “精通” 能力。 所谓 “启发式” 方法,就是 “在某个视角里,使用这个规则能够得到一个解,那么你受此启发,也许可以把这个规则用在别的问题上,得到别的解”,而规则就是你在一个维度里抽象出来的方法论体系。 .. note:: 工程师的这个求解模型,可以转移应用到其他很多与你息息相关的工作生活领域,比如投资理财,把钱存银行定期赚钱的概率解无限接近百分百;但买基金、买股票的概率解对大部分人来说就完全靠赌和猜了,因为缺乏一个合适的模型去求解,而对领域建模应该是程序员的强项,也是可迁移扩展到其他维度的能力。即使是学习成长本身,也可以用工程模型来求解。这时你的学习维度就需要扩展一下,不仅仅局限于你当前的专业领域,还可以了解点神经科学,认知心理学之类的,并配合自己的现实情况、作息习惯,去建立你的学习模型,获得最佳学习效果。而学习效果,也是一个 “概率解”。虽然你不能知道确切的值,但我想你肯定能感觉出不同模型求解的效果好坏。 蜕变 ==== 61 | 工作之余, 专业之外 ----------------------- 工作之余你可以有多种选择,但若被工作环境所困,导致专业力进境阻碍,可以开启业余项目来突破这种限制;而业余项目带来的诸多益处,从此也为你走向专业之外打开了一个新的视角与空间。 62 _ 跨越断层, 突破边界 ----------------------- 技术人前进的三个主要方向:: 1. “高” 指的是 “高级(High-grade)” 往高等级走的技术人,离 “精” 自然只能越来越远, 毕竟站的高就只能看得广,但很难看得精确了 2. “精” 代表 “精确(Precision)” 就是把一门技术做到真正的精通 要做到精,其实越往后付出越多 3. “尖” 则是 “尖端(Advanced)” “尖” 是理论界的突破之路。 只有能推进人类科技进步的技术才称得上尖端 .. note:: “高” 是往宏观走,“精” 是往微观走,“尖” 是去突破边界。 高 ^^^ 高的两条典型路线如下:: 1. 程序员 — 架构师 — 技术领导者 2. 程序员 — 技术主管 — 管理者 架构工作的实质是创造一个模型,来连接、匹配关于业务、技术和团队之间的关系。其中的 “业务” 属于架构师工作内容中的领域建模;“技术” 是匹配领域模型的技术实现模型;“团队” 是关于个体之间如何组合的结构,需要满足个体技术能力与技术实现模型的匹配。由这三个元素连接和匹配构成的模型中,“业务” 是变化最频繁的,其次是 “团队”,而变化频次最低的反倒是 “技术”。 .. note:: 技术像是一根棍子,能发挥多大价值,取决于棍子本身的品质和运用的方式。而往高处走的技术人,要跨越这条路径的断层,就是要认识清楚这个价值网络,并找到最适合技术发挥的价值点。 精 ^^^ 走向专家之路,就是精确地找到、建立你的领域,并不断推高壁垒和扩大边界的过程。 .. note:: 高的路线,需要借助技术的杠杆,认清所处的价值网络,找到合适的价值点,撬动更大的价值;精的路线,在做事情的成功率和速度接近自己的极限后,只能去提升事情的量级,才能发挥出专家的价值。 63 _ 成长蓝图, 进化跃迁 ----------------------- 一. 成长路线 ^^^^^^^^^^^^ .. figure:: https://img.zhaoweiguo.com/knowledge/images/jikes/jinjies/growth1.png 对走过的路和未来的路概括 几个阶段:: 1. 开发代码(Develop Code) 2. 开发系统(Develop System) 3. 开发产品(Develop Product) 4. 开发团队(Develop Team) 5. 开发梦想(Develop Dream) 二. 战略蓝图 ^^^^^^^^^^^^ 波士顿矩阵模型,把公司业务分成下面四类:: 1. 现金牛业务 就个人来说,自然是一份稳定的工作,产生现金,维持个人生活的基本面 关键点:活在当下 2. 明星业务 就个人来说,为未来 5 到 10 年准备的, 就是现在还并不能带来稳定的现金流但感觉上了轨道的事 比如:理财 关键点:活在未来 3. 问题业务 就个人来说,是一些自身的兴趣探索领域。 比如:写作和英语 关键点:活在多维 4. 瘦狗业务 行业在发展,技术也在进化,曾经你赖以为生的 “现金牛” 技能, 可能过几年后就会落后,逐渐变成了 “瘦狗” 就个人来说,果断地放弃旧技能、开发新技能 关键点:活在过去 三. 进化跃迁 ^^^^^^^^^^^^ 跃迁是量子力学里的概念,指电子吸收能量后,突然跳到更高的能量级,这种不连续、跳跃的突变,我们称之为 “跃迁”。 个人成长的跃迁也需要能量,在这里能量就是知识、技能和能力。完成 “能量” 的积累就需要持续地学习和实践行动,而持续行动又靠什么来驱动?内心的自驱力,这是稳定有效的驱动力来源,若没有自我驱动的力量是不太可能带来持续行动的。 总结 ^^^^ .. note:: 从开发代码到开发梦想,你可以画出一张你的成长路线图,从而走上进化跃迁的道路;上了路后,接着你可以利用工程师的思维模式和商业工具模型,建立一个你的成长战略蓝图去指导你如何走这条路。剩下的,就让你的努力、选择和运气来帮助你完成不断的跃迁变化吧。