我们学习了很多编码知识,但在工作中,却没有人教我们如何将这些知识用起来,这本小册子,就起到了这个作用。
更新历史
- 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
软件工程是一个充满了迷人挑战的伟大职业,我们可以为任何行业做出贡献,我们的工作可以改善数十亿人的生活。
和你喜欢的人一起解决你热爱的问题,就可以完成伟大的事情。
干杯!