0%

【The Missing README】程序员说明书

我们学习了很多编码知识,但在工作中,却没有人教我们如何将这些知识用起来,这本小册子,就起到了这个作用。


更新历史

  • 2022.06.27:完成初稿

读后感

一本小册子,却有着非常深厚的内涵,可以说是融合了几十年软件工程精华,把书和实践读薄的好例子。接下来,就要靠我们自己一点一点实践,再把书读厚了

读书笔记

前方的路 The Journey Ahead

你的目的地 Your Destination

四大核心技能

  • 专业技术
    • 计算机科学基础知识
    • 使用 IDE,构建系统,调试、测试
    • 熟悉持续集成,指标、监控、配置和包管理系统
    • 编写测试代码
    • 进行架构设计
  • 执行能力
    • 通过代码解决问题
    • 了解自己工作的商业价值
    • 开发和上线新特性
    • 编写、测试和评审代码
    • 值班,排查操作问题
    • 可靠可依赖
    • 参与技术讨论,读书会等
  • 沟通能力
    • 读写能力
    • 快速接收及给出反馈
    • 寻求帮助
    • 识别问题
    • 写文档
    • 与他人交流有耐心
  • 领导力
    • 独立完成工作
    • 从错误中快速学习
    • 拥抱变化
    • 积极参与项目和计划
    • 帮助新成员
    • 提供有价值的反馈

旅程地图 A Map for Your Journey

  • 萌新 Peak Newb
    • 熟悉公司、团队
    • 参与培训
    • 阅读文档
    • 完成简单的小任务
  • 渐入佳境 Ramp-Up River
    • 中等的开发任务
    • 快速学习
    • 阅读已有代码
    • 熟悉代码如何构建、测试、部署
    • 和管理者熟悉
    • 参与季度计划会
  • 中流砥柱 Cape Contributor
    • 中大型开发任务
    • 编写生产级代码
    • 帮助团队成员
    • 参与代码评审
  • 运维不易 Operations Ocean
    • 保证服务稳定
    • 追踪指标、日志
    • 参与值班
  • 带领团队 Competence Cove
    • 编写技术设计文档
    • 参与项目计划
    • 平衡重构、新功能开发与日常维护

意识成长 Getting to Conscious Competence

学会学习 Learning to Learn

  • 提前学习 Front-Load Your Learning
    • 熟悉项目如何运转,阅读文档
  • 做中学 Learning by Doing
    • 真正上手写一写简单的代码
    • 不要担心弄坏东西
  • 用代码做实验 Experiment with Code
    • 通过修改代码来了解具体的执行流程
  • 阅读 Read
    • 团队文档
    • 设计文档
    • 代码
    • backlogs
    • 书籍、论文
  • 看演讲 Watch Presentations
    • 用 1.5 或 2 倍速看
    • 记笔记
  • 参与大会 Attend Meetups and Conferences(Sparignly)
  • 和有经验的工程师结对编程 Shadow and Pair with Experienced Engineers
  • 用个人项目做实验 Experiment with Side Projects

问问题 Asking Questions

  • 做研究 Do Your Research
  • 有时间范围约束 Timebox
    • 当指定时间没有得到结果时,请求帮助
  • 展示你的工作 Show Your Work
    • 问问题的时候组织已进行的内容,不要直接贴原始笔记
  • 不要打扰 Don’t Interrupt
  • 倾向于广播和异步交流 Prefer Multicast, Asynchronous Communication
  • 批量处理 Batch Your Synchronous Requests
    • 比如批量处理邮件,而不是来一个处理一个

超越成长阻碍 Overcoming Growth Obstacles

  • 冒充者综合症 Impostor Syndrome
    • 临床心理学家宝琳和苏珊娜在过去五年里接触了150位女性来访者。在别人眼里,她们是优秀的女性——受人尊敬的教授、博士学位获得者、优秀的大学生。然而,他们并不赞同这些所谓的“成功”:有人认为录取委员会在录取前就犯了错误;有人认为期末考高分是因为幸运或者某位教授偏袒;有人认为高估了自己,不能赢得现在的工作。
    • 意识到问题本身是自我强化的,不要被错误吓到
    • 放过自己,专注把事情做好
    • 很常见,淡定!
  • 邓宁-克鲁格效应 The Dunning-Kruger Effect
    • 能力欠缺的人在自己欠考虑的决定的基础上得出错误结论,但是无法正确认识到自身的不足,辨别错误行为,是一种认知偏差现象。这些能力欠缺者们沉浸在自我营造的虚幻的优势之中,常常高估自己的能力水平,却无法客观评价他人的能力
    • 开放心态,勇于犯错

该做和不该做的 Do’s and Don’ts

  • Do’s
    • 用代码做实验
    • 参加会议、线上社区、兴趣小组
    • 阅读论文和博客
    • 使用广播和异步交流方式
  • Don’ts
    • 不思考代码
    • 过多参与会议
    • 害怕问问题

和代码一起工作 Working with Code

软件熵 Software Entropy

软件熵是可以被管理的

  • 代码风格和 bug 检测工具 -> Clean Code
  • 代码评审 -> 传播知识,保持代码一致性
  • 持续重构 -> 降低软件熵

技术债 Technical Debt

技术债是增加软件熵的主要原因,但是也是可以分类的,具体如下

  • 维度
    • 处理方式:鲁莽的 Reckless || 谨慎的 Prudent
    • 处理动机:有意的 Deliberate || 无意的 Inadvertent
  • 组合
    • Prudent + Deliberate = 我们先交付,之后再找时间还债(传统意义上的技术债)
    • Reckless + Deliberate = 没时间做设计啦,冲冲冲
    • Reckless + Inadvertent = 啥是分层设计?(也就是 unknown unknowns,这个是最应该避免的债务,影响很大)
    • Prudent + Inadvertent = 现在我们知道之前应该如何去做了(一般来说随着经验增长,就出现这种情况

尤其要避免 Reckless + Inadvertent

处理技术债 Addressing Technical Debt

  • 不要等到世界末日的时候才开始修复
  • 一点点进行重构

讨论技术债的框架

  • 说明现在的情况
  • 描述技术债的风险和成本
  • 说明一个解决方案
  • 讨论可能的方案
  • 进行权衡

修改代码 Changing Code

  • 使用修改祖传代码的算法 Use the Legacy Code Change Algorithm
    • 识别修改点
    • 找到测试点
    • 打破依赖
    • 编写测试
    • 修改和重构
  • 让代码比你发现它们的时候更加整洁 Leave Code Cleaner Than You Found It
  • 做增量改变 Make Incremental Changes
    • 尽量少搞那些天翻地覆的大改变
  • 做务实的重构 Be Pragmatic About Refactoring
    • 不是所有都需要重构
    • 重构是有机会成本的(比如开发新特性)
  • 使用集成开发环境 Use an IDE
  • 使用版本控制最佳实践Use Version Control System Best Practices
    • 学习 Git

避免掉坑 Avoid Pitfalls

  • 使用无聊的技术 Use Boring Technology
    • 新技术很吸引人,但不那么成熟
  • 不要太狂野 Don’t Go Rogue
    • 不能因为你不喜欢,就不遵循业界标准
  • 不要 Fork,如果不打算合并回主干 Don’t Fork Without Committing Upstream
    • 维护一套独立的 fork 是很难的
    • 大部分时候,社区就是最快的
  • 抵抗住重写的诱惑 Resist the Temptation to Rewrite

该做和不该做的 Do’s and Don’ts

  • Do’s
    • 增量重构
    • 重构 commit 和新功能 commit 区别开来
    • 每次修改不要太大
    • 使用稳定的技术
  • Don’ts
    • 滥用技术债这个词
    • 为了测试目的,将方法或变量设为 public
    • 成为语言 snob
    • 忽视公司标准和工具

编写可运行的代码 Write Operable Code

防御式编程 Defensive Programming

  • 避免空值 Avoid Null Values
    • 方法最开始就做 null 检查
  • 让变量不可变 Make Variables Immuatable
    • 可以避免非预期的修改
    • 也可以更好做并发编程
  • 使用类型提示和静态类型检查 Use Type Hinting and Static Type Checking
  • 校验输入 Validate Inputs
    • 不要相信你的输入,可能是任何东西
  • 使用异常 Use Exceptions
    • 不要用特别的返回值来表示错误,对于其他开发者来说增加很多理解成本
  • 清晰的异常 Be Precise with Exceptions
    • 自定异常的时候不要太通用,最终导致难以定位问题
  • 异常早抛出但晚处理 Throw Exceptions Early, Catch Exceptions Late
  • 聪明地重试 Retry Intelligently
  • 写幂等的系统 Write Idempotent Systems
  • 清理资源 Clean Up Resources

日志 Logging

  • 使用日志等级 Use Log Levels
    • TRACE / DEBUG / INFO / WARN / ERROR / FATAL
  • 让日志保持原子性 Keep Logs Atomic
    • 一行就是完整的日志,不要跨行,因为可能会有其他代码也在打日志
    • 如果确实没办法完整,记得带上唯一的 ID,便于聚合
  • 让日志快起来 Keep Logs Fast
    • 用最快的方式拼接字符串,不同方式可能差别很大
  • 不要记录敏感数据 Don’t Log Sensitive Data

指标 Metrics

  • 使用标识指标库 Use Standard Metrics Libraries
    • Counters / Gauges / Histograms
  • 测量所有东西 Measure Everything
    • 资源池
    • 缓存
    • 数据结构
    • CPU 密集操作
    • IO 密集操作
    • 数据大小
    • 异常和错误
    • 远程请求和响应

追踪 Traces

使用 TraceID,尤其在微服务场景下

配置 Configuration

  • 配置上不要玩创新 Don’t Get Creative with Configuration
  • 记录和验证所有的配置 Log and Validate All Configuration
  • 提供默认值 Provide Defaults
  • 让相关的配置成组 Group Related Configuration
  • 把配置当做代码看待 Treat Configuration as Code
    • 同样需要版本管理,不是法外之地
  • 保持配置文件整洁 Keep Confiugration Files Clean
  • 不要编辑已部署的配置 Don’t Edit Deployed Configuration

工具 Tools

  • 工具要能脚本化调用,这样才能自动化
  • UI 工具增加了不必要的开发复杂度,对开发者来说也没啥用

该做和不该做的 Do’s and Don’ts

  • Do’s
    • 编译错误比运行时错误好
    • 只要可能,就不可变
    • 检查输入和输出
    • 使用 bug 检查工具和类型推导
    • 在异常时清理资源
    • 让应用可配置
    • 验证和记录所有的配置
  • Don’ts
    • 使用异常作为应用逻辑
    • 使用返回码做异常处理
    • catch 你处理不了的异常
    • 写多行的日志
    • 手动修改服务器上的配置
    • 在配置文件里保存密码
    • 自定义配置格式
    • 使用动态配置

管理依赖 Managing Dependencies

依赖管理基础 Dependency Management Basics

  • 带语义的版本 Semantic Versioning
    • Major / Minor / Patch
  • 传递的依赖 Transitive Dependencies
    • 有直接依赖和间接依赖

依赖地狱 Dependency Hell

  • 循环依赖 circular dependencies
  • 钻石依赖 diamond dependencies:A 依赖 B 和 C,但是 B 和 C 依赖 D 的不同版本
  • 版本冲突 version conflict

避免依赖地狱 Avoid Dependency Hell

  • 隔离依赖 Isolate Dependencies
  • 小心添加依赖 Deliberately Add Dependencies
  • 固定版本 Pin Versions
  • 谨慎圈定依赖范围 Scope Dependencies Narrowly
  • 避免循环依赖 Protect Yourself from Circular Dependencies

该做和不该做的 Do’s and Don’ts

  • Do’s
    • 使用带语义的版本
    • 固定依赖版本的范围
    • 使用依赖报告工具来检查依赖
    • 添加依赖要谨慎
  • Don’ts
    • 使用 git 哈希作为版本号
    • 随意添加依赖
    • 引入循环依赖

测试 Testing

测试的用处 The Many Uses of Tests

  • 保证代码正确
  • 避免未来改动影响原有逻辑
  • 强迫开发者使用自己写的函数
  • 作为代码试验的游乐场
  • TDD

测试的类型 Types of Tests

  • 单元测试 Unit Test
  • 集成测试 Integration Test
  • 系统测试 System Test
  • 性能测试 Performance Test
  • 验收测试 Acceptance Test

测试工具 Test Tools

  • 模拟库 Mocking Libraries
  • 测试框架 Test Frameworks
  • 代码质量工具 Code Quality Tools
    • 静态代码分析器 Static Code Analyzer
    • 代码风格检查器 Code Style Checker
    • 代码复杂度工具 Code Complexity Tool
    • 代码覆盖工具 Code Coverage Tool

编写测试 Write Your Own Tests

  • 编写干净的测试 Write Clean Tests
    • 写明测试如何工作,如何执行测试,为什么写这个而测试
    • 避免硬编码值,避免复制代码
    • 测试基础功能
    • 测试的依赖与普通依赖要隔离
  • 不要过度测试 Don’t Overdo Testing
    • 不要过度追求高覆盖率
    • 测试风险最高的部分,才最有价值

测试原则 Determinism in Tests

  • 给随机数发生器固定的种子 Seed Random Number Generators
  • 单元测试中不要调用远程系统 Don’t Call Remote Systems in Unit Tests
  • 不要使用真实时间 Inject Clocks:便于控制时间变量,如超时情况下的检查
  • 避免睡眠和暂停 Avoid Sleeps and Timeouts
  • 关闭网络连接和文件句柄 Close Network Sockets and File Handles
  • 不要绑定固定端口 Bind to Port Zero
  • 生成独立的文件和数据库路径 Generate Unique File and Database Paths
  • 隔离和清理测试中的资源 Isolate and Clean Up Leftover Test State
  • 不要依赖测试的顺序 Don’t Depend on Test Order

该做和不该做的 Do’s and Don’ts

  • Do’s
    • 使用测试来复现 bug
    • 使用模拟工具来辅助编写单元测试
    • 使用代码质量工具来验证覆盖率、格式和复杂度
    • 固定随机数生成器的种子
  • Don’ts
    • 忽视添加新测试工具的成本
    • 依赖别人编写单元测试
    • 面向代码覆盖率写测试
    • 只用覆盖率作为质量保证

代码评审 Code Reviews

为什么要做代码评审 Why Review Code?

  • 发现 bug,保持代码整洁
  • 好的教学工具
  • 确保至少两人熟悉代码
  • 互相信任

评审你的代码 Getting Your Code Reviewed

  • 准备评审 Prepare Your Review
  • 通过预评审降低风险 De-risk with Draft Reviews:当有了设计逻辑思路,就可以先来个简单的评审
  • 不要利用评审来触发自动测试 Don’t Submit Reviews to Trigger Tests:是一种资源浪费,占用队列
  • 大量的代码变化先过一遍思路 Walk Through Large Code Changes
  • 对码不对人 Don’t Get Attached:遇到比较严厉的批评,不要觉得是对人的,是对代码的
  • 培养同理心,但不容忍粗鲁 Practive Empathy, but Don’t Tolerate Rudeness
  • 积极主动 Be Proactive:不要害羞,邀请大家来评审你的代码

审阅代码 Reviewing Code

  • 给评审请求排序 Triage Review Requests:区分优先级
  • 为评审预定时间 Block Off Time for Reviews:控制时间而不耽误其他工作
  • 了解改动 Understand the Change
  • 给出好理解的反馈 Give Comprehensive Feedback
  • 指出好的部分 Acknowledge the Good Stuff
  • 区分 Issue、建议和鸡蛋里挑骨头 Distinguish Between Issues, Suggestings and Nitpicks
  • 不要看都不看就通过评审 Don’t Rubber-Stamp Reviews
  • 不要局限于 Web 评审工具 Don’t Limit Yourself to Web-Based Review Tools
  • 不要忘记评审测试 Don’t Forget to Review Tests
  • 给出明确的结论 Drive to a Conclusion:通过,修改,还是重写

该做和不该做的 Do’s and Don’ts

  • Do’s
    • 提交评审前通过测试和风格检查
    • 提供合适的上下文帮助评审者理解
  • Don’ts
    • 看都不看就通过评审
    • 爱上自己的代码
    • 过分吹毛求疵
    • 让完美成为不错的敌人

交付软件 Delivering Software

分支策略 Branching Strategies

  • Gitflow
    • Develop Branch
      • Feature Branch
    • Hotfix Branch
    • Release Branch

构建阶段 Build Phase

  • 给包打上版本 Version Packages
  • 不同资源分开打包 Package Different Resources Separately

发布阶段 Release Phase

  • 不要 Release 之后就不管不顾 Don’t Throw Releases Over the Fence
  • 将包发布到 Release 库 Publish Packages to a Release Repository
  • 让发布不可变 Keep Releases Immutable
  • 经常发布 Release Frequentyly
  • 让 Release 发布计划透明 Be Transparent About Release Schedules
  • 发布改变日志和发布记录 Publish Changelogs and Release Notes

部署阶段 Deployment Phase

  • 自动部署 Automate Deployments
  • 让部署原子化 Make Deployments Atomic
  • 独立部署应用 Deploy Applications Independently

上线阶段 Rollout Phase

  • 监控上线情况 Monitor Rollouts
  • 灰度上线 Ramp Up with Feature Flags:部分用户可见新特性
  • 断路器上线 Protect Code with Circuit Breakers:出错自动使用老版本
  • 多版本并行 Ramp Service Versions in Parallel:金丝雀发布、蓝绿发布
  • 黑暗模式 Launch in Dark Mode:通过 traffic shadow 模拟线上情况

该做和不该做的 Do’s and Don’ts

  • Do’s
    • 使用 VCS 管理分支
    • 发布变更日志和 Release 笔记
    • 通知用户新版发布
    • 自动化部署
  • Don’ts
    • 发布无版本的包
    • 将配置、图片、语言包打包在一起
    • 利用 VCS 分发软件
    • 发布之后还修改包
    • 不监控就上线
    • 依赖部署顺序

值班 Going On-Call

重要值班技能 Important On-Call Skills

  • 空出时间 Make Yourself Available
  • 注意力集中 Pay Attention
  • 给工作排优先级 Prioritize Work
  • 清晰沟通 Communicate Clearly
  • 跟进你的工作 Trace Your Work

处理事故 Handling Incidents

  • 区分优先级 Triage
  • 协调通知团队 Coordination
  • 缓解问题 Mitigation:快速止血
  • 解决方案 Resolution
  • 跟进 Follow-Up

提供支持 Providing Support

通过支持用户,来了解你的代码是怎样被使用的

不要当英雄 Don’t Be a Hero

团队不应该只有一个救火队员,这样对大家都不好,对救火队员也是如此

该做和不该做的 Do’s and Don’ts

  • Do’s
    • 使用优先级类别,SLIs / SLOs / SLAs 来区分优先级
    • 使用科学方法来排查错误
    • 问自己五个 why,找到问题根源
    • 确认问题已被修复
  • Don’ts
    • 忽视警报
    • 不采取任何缓解措施,直接找问题根源
    • 成为能解决所有问题的英雄

技术设计过程 Technical Design Process

思考设计 Thinking About Design

  • 定义问题 Define the Problem
  • 做研究 Do Your Research
  • 进行实验 Conduct Experiments
  • 耐心一点 Give It Time:好的设计不是一次就可以搞定的

写设计文档 Write Design Documents

  • 记录重大变化 Document Consequential Changes
  • 明白为什么要写 Know Why You’re Writing
  • 学习协作 Learn to Write
  • 持续更新文档 Keep Design Documents Up-to-Date

使用设计文档模板 Using a Design Document Template

  • 简单介绍 Introduction
  • 现状及背景说明 Current State and Context
  • 改变的动机 Movitation for Change
  • 具体需求 Requirements
    • 用户视角需求
    • 技术需求:如必须支持 OpenAPI
    • 安全和兼容性需求
    • 其他需求:截止日期、预算等
  • 可能的方案 Potential Solutions
  • 推荐的方案 Proposed Solution
  • 设计和架构 Design and Architecture
    • 系统图 System Diagram
    • 界面及体验变化 UI/UX Changes
    • 代码变化 Code Changes
    • 接口变化 API Changes
    • 持久层变化 Persistence Layer Changes
  • 测试计划 Test Plan
  • 上线计划 Rollout Plan
  • 未解决的问题 Unresolved Questions
  • 附录 Appendix

合作设计 Collaborating on Design

  • 了解团队的设计评审流程 Understand Your Team’s Design Review Process
  • 不要总想搞大新闻 Don’t Surprise People
  • 对设计进行头脑风暴 Brainstorm with Design Discussions
  • 对设计做贡献 Contribute to Design

该做和不该做的 Do’s and Don’ts

  • Do’s
    • 使用设计文档模板
    • 阅读博客、论文、演讲来获取灵感
    • 批判性思考
    • 设计时用代码做实验
    • 写得简明扼要,并持续练习
    • 对设计文档也进行版本控制
    • 相互讨论设计思路
  • Don’ts
    • 过分留恋测试代码
    • 只探索一个解决方案
    • 忘记更新文档
    • 不参与团队设计讨论

创造可演进的架构 Creating Evolvable Architectures

了解复杂度 Understanding Complexity

  • 高依赖程度 High dependency 带来的是依赖其他代码的 API 或行为,会非常难以修改
    • 解法:仔细设计的 API + 有节制的使用抽象
  • 晦涩难懂 High obscurity 带来的是难以预估修改带来的副作用。需要花很多时间才能理解 + 全局变量太多 + 一处变化在多处有影响
    • 解法:清晰定义的 API + 标准的设计模式
  • 巨大惯性 High inertia 指的是很多服务都依赖的系统,这样的系统应该越简单越好,而相对来说少依赖的系统,可以复杂一些
  • 复杂度不能被消灭,但是我们可以选择把它们放在哪里

为演进设计 Design for Evolvability

  • KISS = Keep It Simple, Stupid
  • 你不会需要的 You Ain’t Gonna Need It:不要过度设计,使用-使用-复用原则
  • 最小吃惊原则 Principle of Least Astonishment
  • 封装领域知识 Encapsulate Domain Knowledge
    • Domain-Driven Design(DDD)

可演进的接口 Evolvable APIs

  • 保持接口简单 Keep APIs Small
    • 只添加立即要用的 API 方法和字段
    • 多个字段的 API 需要提供默认值
  • 暴露精心设计的服务接口 Expose Well-Defined Service APIs
    • 使用标准工具来定义服务接口,比如 OpenAPI(RESTful) + Protobuf(non-RESTful) + Thrift
    • 根据服务接口自动生成代码和文档
  • 保持接口兼容 Keep API Changes Compatible
    • 向前兼容 Forward-compatible
    • 向后兼容 Backward-compatible
  • 接口要有版本 Version APIs

可以演进的数据 Evolvable Data

  • 隔离数据 Isolate Databases
  • Use Schemas
  • 自动迁移 Automate Schema Migrations
  • 维护兼容性 Maintain Schema Compatibility

该做和不该做的 Do’s and Don’ts

  • Do’s
    • 牢记 YAGNI: “You Ain’t Gonna Need It”
    • 使用标准库和开发模式
    • 使用 IDL 来定义 API
    • API 和文档都需要进行版本管理
    • 不同应用的数据库要隔离
    • 为数据定义清晰的 schema
  • Don’ts
    • 无目的地构造过多抽象
    • 编写带有隐含顺序或参数要求的方法
    • 做不兼容的 API 改动
    • 啥数据都用 string 保存

敏捷计划 Agile Planning

敏捷宣言 The Agile Manifesto

  • 个体和互动 高于 流程和工具
  • 可工作的软件 高于 详尽的文档
  • 客户协作 高于 合同谈判
  • 响应变化 高于 遵循计划

敏捷计划框架 Agile Planning Frameworks

  • Scrum
  • Kanban
  • 极限编程
  • 精益方法

Scrum

  • 用户故事 User Stories
  • 任务 Tasks
  • 故事点 Story Points
  • 积压事项优先级 Backlog Triage
  • 冲刺计划 Sprint Planning

站会 Stand-ups

每个人都要回答 3 个问题:

  • 自上一次每日 Scrum 会议以来,我都干了些什么?
  • 从现在起到下一次每日 Scrum 会议的时间内我要做什么?
  • 我遇到了什么困难?

评审 Reviews

在每一个冲刺之后进行,团队只能展示可工作的软件,而不包括一些中间产物,例如架构图、数据库模式以及功能说明书等。利益干系人可以问问题,团队可以回答问题。在演示结束的时候,团队会询问利益干系人的意见和反馈,后者也有机会分享想法、感受和观点。如果需要,下一轮冲刺规划可以考虑加入修改。产品所有者可以把修改的内容添加到产品积压工作表中。如果需要立即修改,那么这些修改的需求就会出现在下一轮冲刺的积压工作表中。

复盘 Retrospectives

讨论可以改进工作方式的方法。团队和 Scrum 主管参会(产品所有者也可以参加)。每个人都要回答两个问题:在这一轮冲刺中有哪些事做得不错?未来有哪些事情可以改进?

路线图 Roadmaps

进行长期的产品规划,一般按照季度进行,大家一起根据 backlog 中的需求,确定产品演进路线。

该做和不该做的 Do’s and Don’ts

  • Do’s
    • 简短的站会
    • 清晰的用户故事
    • 一个冲刺只去做真的能做完的工作
    • 大的任务需要拆分为能在一个冲刺完成的诸多小任务
    • 使用故事点来预估工作量
  • Don’ts
    • 过分沉迷如何正确“敏捷”
    • 害怕修改敏捷流程
    • 忘记跟踪计划和设计工作

和领导一起工作 Working with Managers

沟通、目标和成长过程 Communication, Goals, and Growth Processes

  • 一对一沟通 1:1s
    • 愿景 Big Picture
    • 反馈 Feedback
    • 职业生涯 Career
    • 个人情况 Personal
  • PPPs
    • Progress
    • Plan
    • Problem
  • OKRs
  • 绩效评审 Performance Reviews

向上管理 Managing Up

  • 获取反馈 Get Feedback
    • 处境 Situation
    • 行为 Behavior
    • 影响 Impact
  • 给出反馈 Give Feedback
  • 讨论你的目标 Discuss Your Goals
  • 行动起来 Take Action When Things Aren’t Working

该做的和不该做的 Do’s and Don’ts

  • Do’s
    • 告诉领导你需要什么
    • 预约 1v1 时间
    • 记录 1v1 笔记
    • 记录日常工作成就
    • 使用 SBI 框架进行反馈
    • 思考长期职业规划
  • Don’ts
    • 向领导隐瞒困难
    • 把 1v1 当做状态同步会议
    • 靠记忆进行绩效评估
    • 给出肤浅的反馈
    • 被 OKR 束缚
    • 忍受差劲的领导

职业规划 Navigating Your Career

职业建议 Career Advice

  • 一专多强 Be T-Shaped
  • 努力提升自己 Participate in Engineering Programs
  • 掌握你的晋升 Steer Your Promotion
  • 谨慎换工作 Change Jobs Carefully
  • 掌握自己的节奏 Pace Yourself

最后的想法 Closing Thoughts

软件工程是一个充满了迷人挑战的伟大职业,我们可以为任何行业做出贡献,我们的工作可以改善数十亿人的生活。

和你喜欢的人一起解决你热爱的问题,就可以完成伟大的事情。

干杯!