我作为一名软件工程师如何在两年内获得四次加薪
或者更好的标题应该是:“如何成为工作中的叛逆者并不断提高技艺”。
原始帖子发布于iamtk.co。
免责声明:
- 这些想法和见解来自于一个在非常特殊的行业工作的特权人士。
- 我的目的不是炫耀,而是分享我的经验,希望你能窃取一些想法。
- 将金钱视为生活中的宝贵资本是可以的,但在这篇文章中我将重点介绍如何提高我的技艺。
在讲述我的经历之前
这篇文章,我会聊聊技能、经历、机遇和心态,基本上就是我如何提升自己的技能。
我一直专注于旅程,并没有打算在公司里发展。这不是我的目标。其实我并没有真正的目标,只是想在工作中享受乐趣,寻求自主权和掌控力,拥有一个可以学习很多东西的空间。
考虑到这一点,我的经验或许无法帮助你在职业阶梯上“攀登” 。但我希望你能从中汲取一些经验,并运用它们来改善你的工作生活。
此外,如果你的目标是在公司中成长、攀登职业阶梯并获得加薪,也许我将来会写到这方面的内容,但这里有两条(肤浅的)建议:
- 了解职业阶梯(如果您的公司有的话):为了能够获得晋升,您需要了解自己所处的位置以及对下一级别的期望是什么。
- 与你的经理合作:利用一对一会议来了解职业阶梯的期望,获取反馈,并询问你可以参与的项目。所有能帮助你更上一层楼的事情。
还有很多其他方法可以让你获得加薪,但对我来说,这些是帮助你迈出第一步的基本要素。由于我不想这篇文章的重点是晋升,我可能会就这个话题另写一篇文章。不过,你也可以在网上找到一些很棒的内容,可能比我未来写的文章更好。
我的经历
外部因素
首先,我必须说,我拥有重要的外部因素。QuintoAndar 是巴西发展最快的初创公司之一。目前,它的估值为 51 亿美元。它是房地产行业的一家创新型公司,其商业模式在巴西行之有效。
事实上,一家公司正在赚钱,投入了大量的资金,并且不断发展,这对于加薪和晋升来说是一个非常重要的因素。
除此之外,这家公司还吸引了真正的人才,不仅在工程领域,而且在产品和其他组织领域。
在我看来,这种文化对工程师来说很棒,因为我总是觉得这是一个安全的地方,可以展示和讨论我的新想法,分享我对什么有效或无效的诚实意见,并且总是受到激励去挑战现状。
因此,这些是与我的技能和工作无关的重要外部因素:
- QuintoAndar 是一家快速发展的公司
- 多年来,其财务状况持续增长
- 真正有才华的人
- 优秀的工程师文化(但不仅仅如此)
实现我的团队目标
在我的工作中,我的注意力始终放在团队和季度目标上。对我来说,真正重要的是了解团队的目标、我们应该关注的业务指标,以及我们为什么要做这一系列功能。
为了让每个人都参与进来,我们创建了一个 Notion 页面,其中包含我们团队所有业务和产品相关的内容。我还创建了一个仪表盘,其中包含 Amplitude 平台上所有重要的页面,以便更轻松地访问关键指标。
理解“为什么”只是第一步。作为工程师,我们的职责之一就是帮助解决“如何”的问题,并提出解决方案。
与产品经理、设计师和其他工程师的合作是团队成功的关键。我觉得这部分很少被提及,而且我刚开始从事软件工程工作时,对它一直有点模糊。在这里, “合作”有很多不同的含义,但我将列出一些我过去实践过的想法:
- 想法可以来自不同的地方:你的经理、项目经理、设计师,或者团队以外的任何人。在理解了想法(以及最重要的问题)之后,你可以运用你的工程背景以及你当前正在开发的系统的知识,帮助塑造和完善解决方案。
- 您可能了解您正在处理的系统的痛点。
- 凭借您的背景,您可以想到不同的解决方案:每个解决方案都需要您和您的团队付出努力和时间。
- 协商在实施后有更多时间来完善所选解决方案,该解决方案需要更快地部署到实际用户,但缺乏一些工程最佳实践。
- 或者更好的是,协商时间来交付已经内置最佳实践的功能或产品。
- 创意可以来自您:一项功能、一款产品或一项您认为可以提升用户体验和业务指标的改进。稍后,我们将分享我领导Web 性能项目以及作为一名具有产品意识的软件工程师的经历。
- 打造安全的协作空间:如果公司文化已经营造出这样的环境,让你能够安心地讨论想法、提出自己的观点或表达不同意见,那么合作就变得轻而易举。拥有一个日益多元化的团队对于丰富团队讨论至关重要,而拥有一个安全的空间是让人们能够无所畏惧地进行讨论的基石。
- 通过要求团队中的每个人提出问题、讨论和分享意见来创造空间。
- 积极倾听人们的意见,关心他们所说的话,并记录下这些见解,以完善所讨论的想法。
- 拥有更好的产品开发流程:讨论策略的空间、讨论季度目标和指标的空间、讨论工程挑战和架构/解决方案的空间。
关键在于,随着你作为一名工程师的成熟,你不仅要编写代码来交付产品,还要参与软件工程的各个方面。你明白,改善团队、流程、交付和开发体验是你“职责”的一部分。
挑战现状:一切都可以改进
我需要强调的是,QuintoAndar 的文化不仅要求我挑战现状,而且还始终激励我改进——或者说提高——所有不理想的方面。所以,在这样一个环境里,我可以质疑一切,尝试各种想法,然后改进那些行不通或可以改进的地方。
当考虑改进公司内部事务时,目标是让组织变得更好。我会想到流程、技术、团队文化、开发者体验等等。
我的想法一直是先做一些无法规模化的事情:专注于我的团队,尝试各种实验,从中学习,并不断改进。如此循环,直到想法成熟。当我觉得它已经可以规模化时,我就可以将其分享给更广泛的群体,比如一个部落(一组小队/团队)或整个组织。
一个好的解决方案总是源于一个定义明确的问题(或者一个定义明确的、可以改进的方面)。这就是为什么理解问题和背景如此重要。每天与工程问题打交道让我对事物的运作方式有了更深入的理解,并让我能够思考如何改进它。
由于我在一家大型科技公司工作,所以技术、模式和惯例对于我们快速发展但始终注重质量至关重要。
我的第一个计划是创建关于如何使用 React、优化、不变性以及 JavaScript 和 React 测试的指南。指南文档是一个很好的举措,因为首先,我们可以在公司范围内规范这些约定和模式;其次,它们提高了对这些主题的认识,作为工程师,我们可以讨论我们想要采用和规范化的约定。我喜欢整个过程,主要是因为总是能从其他工程师那里得到反馈、不同的观点和见解,并且我们能够为日常遇到的常见问题提出很好的解决方案。
通过这第一个举措,我增强了信心,相信自己能够在工程领域不断改进。对于遇到的每一个问题,我都记录下自己想到的解决方案和模式,并与其他工程师分享。
我记得以前我们没有机会在 PWA 中使用 Hooks。所以我做了一些实验(React Hooks、Context API 和 Pokemons),并分享了它们。
关于 JavaScript 模式,我还尝试了一些关于闭包和柯里化、React 中的国际化抽象和函数式编程的想法。
随着我们的代码库变得越来越复杂,我们开始难以对其进行推理,主要是状态管理部分,我们大量使用了 Redux。
“键入”我们的状态管理给了我们更多的信心,并使我们更清楚地了解应用程序中数据的结构。
选择 TypeScript 来处理这个问题让我学习了更多,并创建了一个用 TypeScript 思考的思维模型。由于我们几乎所有代码库都在使用 React,因此提供React 和 TypeScript 如何协同工作的示例非常重要。
测试应用程序一直是公司里大家最感兴趣的话题。我们有一些小型的公会来讨论这些想法,并创建我们想要使用的模式和约定。我可以分享我的两个实验:TDD、JavaScript 和 React,以及React 测试库的基本方法。我认为 TDD 是一个更个性化的过程,但使用测试库是我们测试应用程序的默认选择。
技术总是在不断变化和改进。我们看到许多库的出现,其中两个引起了我们的注意:react-query和swr 。我用它们做了实验,我和我的同事为react-query制定了一个架构决策记录 (ADR) 。我们看到了使用这种模式的潜力,可以取代 redux-pack 和 redux-saga,因为它们曾是我们性能方面的瓶颈。此外,react-query 提供了一种更直观的方法,并专注于解决服务器缓存问题。
除了技术之外,我们还可以考虑开发人员的经验。工程时间变得越来越重要。
我们最近发现,新款 2021 款 M1 MacBook 将我们的 Android 开发时间缩短了一半。
— Jameson (@softwarejameson) 2021 年 11 月 3 日
因此,对于一个 9 人团队来说,3.2 万美元的笔记本电脑实际上可以在 2022 年节省 10 万美元的生产力。盈亏平衡点发生在 3 个月。
简而言之,工程工时比笔记本电脑贵得多!
但在我看来,这不仅重要,而且对许多正在扩张业务的公司来说至关重要。你不需要一个单独的团队或平台小组来提高工程师的生产力,作为工程师,我们总是可以设计更好的流程并解决生产力瓶颈。我们可以与经理沟通,为这类工作分配更多时间,甚至可以从头开始创建一个新的团队。
我的确研究过开发者体验,不得不说,我玩得很开心。我写了一篇关于这方面经验的文章,如果你想看看的话:DX 和前端工程中的软件可维护性。
但总结一下,我当时针对的是工程师的痛点:
- 监控:检测新系统,创建仪表板链接,记录如何每天使用监控系统。
- 测试:试验新的测试工具,分享这些经验的见解,编写如何使用它们的指南和示例,展示不同的模式。
- CI/CD:不仅优化了 CI 构建以提高开发人员的工作效率,还实现了发布流程的自动化。之前需要使用 GitHub 标签,现在只需合并 PR,新的变更就会自动部署。
- 代码格式化:现在结合使用 Prettier 和 ESLint 规则。我能够在不到一周的时间内用 Prettier 格式化整个代码库。而且,由于我们有高质量的自动化测试和监控系统的支持,我们对此充满信心。此外,我还实现了一个预提交钩子,用于在代码库的每次提交时运行 Prettier 和 ESLint。
- Web 性能:我之前有机会从事 Web 性能项目,但在这种情况下,我可以致力于使用性能工具来收集真实的用户指标(核心 Web 生命力)。
监控和测试是进行更多实验、重构和自信地修改代码的基石。自动格式化代码带来了巨大的好处,它让工程师可以讨论业务规则和架构,而不是争论是否需要添加分号。Web 性能工具是衡量任何与软件性能改进相关的举措的基石。加快持续交付速度可以提升每位参与该项目的工程师的体验。构建持续交付体系也能让开发者的体验更加流畅。
挑战现状部分的最后一部分是知识共享。
对我来说,我喜欢记录和分享我所学、研究或实验的一切。文档格式多种多样,可以是文章、指南、Notion 文档、用于技术讲座的幻灯片,也可以是 Moleskine 上的简单笔记,用于根据草稿创作内容。
我已经这样做了 8 年,所有内容都记录在这里:著作。
这是一种与队友分享学习成果的方式,同时也能与技术社区分享想法。这个过程帮助我理清思路,并更深入地了解我之前尝试过的每个主题。
首先是写作,其次是任何我想分享的内容。写下并整理想法和实验是创作其他内容的基础。通过撰写文章,我基本上详细列出了所有我想分享的内容,这些内容可以转化为指导方针(例如,本文的测试方案)、工程评论,或者技术讲座的幻灯片,就像我在“Web 性能改进”中所做的那样。
但我最喜欢的是把我的文章变成与团队讨论的话题。我们有一个叫做“Guildinha”(小公会)的小组会议,每个工程师都可以围绕一个主题来计划会议。这始终是一个非正式的会议,大家可以聊天、讨论,互相学习。
有了更多的知识和经验,我在三年的工作中,也能够以正式和非正式的方式指导我的同事。与他人交流,帮助他们在职业发展中成长,并以某种方式影响他们的工作,这总是一件很愉快的事情。
提高我的技艺
在我在本文中涉及的所有主题中,我发现最有趣的是:提高我的技艺。
我之前在两篇文章中部分地写到了这一点:
我知道我不是机器,但我一直在寻找学习更多知识的方法,去了解我关心的事物。每一天。每一次。永远。
我一直在重新思考我在空闲时间学习的方式,通常有三种方式
- 基础知识
- 一经请求
- 局部最大值与全局最大值
当我思考基本原理时,我会想到“第一性原理”。软件工程的基石是什么?我们绝对确定什么是真的?基于这一原理进行推理,我们可以理解和解决更困难、更复杂的问题。
在软件工程领域,我们有大量的知识可供学习。当我还是一名后端工程师时,我的重点是理解 API、系统架构、自动化测试和数据库。对于每个主题,我都能深入研究并理解其基本原理。有了更深入的理解,我就能将这些知识串联起来(或者说“串联各个点”),从而解决后端工程中更棘手的问题。
前端工程也是如此。我从 HTML 和 CSS 开始,然后学习了更多 JavaScript。现在,我们需要更好地理解其他东西才能完成这项工作(或者至少是更复杂的工作),例如构建系统(编译器和打包器)、自动化测试(用于组件和集成)、浏览器引擎等等。
知识是无限的,我不会学到所有的东西,但从第一原理推理不仅能帮助我解决复杂的问题,还能帮助我了解我所缺少的知识差距。
按需学习基本上是指当我在工作或业余项目中遇到新的挑战,需要某种特定的知识来解决问题时。当我在工作中需要了解监控、测试和 Web 性能时,这种情况就会发生;在我目前的业余项目中,我需要更好地理解 CMS 和文本编辑器时,这种情况也会发生。
局部最大值 vs 全局最大值是我最近学到的东西之一。这对我来说非常违反直觉,但随着我做得越来越多,我越来越清楚地认识到,知识组合多元化的重要性。
如果你是一名 JavaScript 工程师,那么显而易见的选择就是不断学习 JavaScript,但很快你就会陷入局部极限。我所做的是,首先走出舒适区,学习 TypeScript以及如何充分利用类型系统。我的下一步是学习更多关于浏览器、算法和数据结构的知识。现在,我投入时间和精力学习编译器、打包器的工作原理以及 Rust。我所学的一切都对我的工作以及我对工程的理解有着直接或间接的影响。
在工作中也是如此。我的方法是积极寻求来自经理和同事的反馈,并思考如何成为一名更好的软件/产品工程师。
积极寻求反馈是我职业生涯早期就想养成的习惯。早期,我的想法是“反馈很棒,我随时乐意接受反馈”。但这还不够。我上一份工作的做法是每周与我的经理开一次会,并总是询问她对我当周工作的看法:
- 我做得很好并且应该继续做的事情
- 我做得还不错,可以改进或做得更好
- 我所做的事情并不是那么好,可以改进
我认为这些要点是讨论我可以学习、做和养成习惯的事情的一个很好的起点。
另一件事是提供反馈和想法,让项目变得更好。我每周都会记录一些可以改进的地方,并与我的经理分享,讨论如何在我们的流程和项目代码库中实现这些改进。
另一种获得反馈的有效方法是制定你的个人发展计划 (IDP)。我之前写过这方面的文章,但它的核心是为你的(职业)成长制定一个计划。通过这份共享文档,我可以随时与我的经理讨论我正在走的路、我正在学习的内容、我感兴趣的东西,并获得关于如何改进我的行为和习惯的反馈和建议。这也是一种提高自我认知的好方法,可以与你的经理分享你最喜欢的东西,并可能获得与你的技能和兴趣相交的项目。我非常喜欢制定我的 IDP,并且我制作了一个公开版本与我的队友分享。每个人都知道我在学习什么,这是在团队内讨论和分享更多知识的起点。
但如果你不想制定职业发展计划也没关系。总有其他方法可以激励你的团队接受(和给予)反馈。为了获得同事的反馈,我首先给他们每个人提供了(正式和非正式的)反馈,并友好地告诉他们,如果他们有时间,我也很乐意接受反馈。
关于如何成为一名更好的产品/软件工程师,有很多关于产品意识工程师的非常有趣的文章,但我将通过我的视角和经验对这个话题发表我的看法。
对我来说,第一步是了解你正在开发的产品。
它是面向最终用户的产品吗?
- 客户是谁?
- 我可以通过数据了解他们的行为吗?
- 与采访过他们的设计师交谈,并记录下他们的见解。
- 业务如何运作?
它是针对内部利益相关者的产品吗?
- 这些利益相关者使用该产品的目标是什么?
- 缺少哪些功能?
- 一般的抱怨是什么?
这是针对工程师的产品吗?
- 他们目前的工作流程是怎样的?
- 他们高兴的事情是什么?
- 他们因为什么事而生气?
但是对于所有这三个(以及任何其他)群体,我们始终可以考虑用户体验(用户体验的痛点是什么?)并找到帮助他们实现目标的方法。
弄清楚你正在开发的产品是一个很好的起点。多问一些关于业务、用户以及产品使用方式的问题,也是加深对产品的了解的有效途径。
我通常会做的第二件事是了解后续步骤、OKR,以及团队对产品的目标。理解我们为什么要创建这个功能X,以及我们想要实现的相关指标,并积极参与讨论,探讨应该做什么以及如何做。
在这些会议上向工程师敞开大门真是太棒了,因为我们不仅可以帮助我们思考产品理念,还能让我们深入了解产品背后的软件。由于我们拥有工程和软件背景,这在制定策略和讨论工程 X 产品权衡时非常有用。
不要错过了解更多产品信息的机会,如果可能的话,积极参与战略和规划会议。
用有趣的项目挑战自己
有趣的项目可以成为你工作学习经历的基石。做一个具有挑战性的项目,你可能会学到很多东西。有些东西你不知道,需要去探索和学习;有些东西你了解,可以做得更好。完成这类项目后,回顾一下哪些地方做得好,哪些地方可以改进,会很有益处。这总是一种学习的经历。
我喜欢具有挑战性的项目,首先,我喜欢挑战。其次,因为每当我有机会学习新事物时,我总是乐在其中。最后,因为我喜欢回顾过去的自己,并为我所做的工作感到自豪。
我做的事情:
- 从零开始构建产品和业务:
- 为摄影师打造了一款全新的应用程序
- 在关联产品中建立销售业务
- 针对房地产业主产品的 Web 性能优化
- 前端工程开发人员经验
- CI/CD 优化、监控系统和自动化测试
在所有这些项目中,我总能学到很多东西。构建摄影师应用程序是我第一次使用无服务器函数和 React。构建联盟产品是我第一次使用 Clojure 和支付系统。提升 Web 性能是我第一次深入研究 Web 性能并构建工具(主要是 Webpack)。对 DX 的思考让我对工程师的工作流程有了宏观的了解,我也可以将这些知识运用到其他地方。
具有挑战性的项目始终是自我提升的绝佳工具,因为它们是持续学习和提升技能的机会。寻找有趣的项目并持续学习。回顾过去的自己,并为自己的决定和进步感到自豪,这种感觉真是太棒了。
记日记
我有记录一切的习惯。从学习到读书笔记,从文章构思到每日日记,我都会记录。日记是我日常生活的一部分,它帮助我思考,也为我提供了反思过去所做事情的空间。
这些是我遇到的一系列想法,你也可以利用它们来为自己谋利:
记录我完成的所有事情
What
:我正在从事的项目是什么,我正在解决的问题是什么,或者我实现的功能是什么。How
:解决方案和架构决策如何,我负责哪些 PR,权衡是什么,团队如何合作,以及我在整个项目中扮演什么角色。Learnings
:我会做哪些不同的事情——可以是架构、解决方案、流程、授权、沟通、优先级,任何可以改进的事情,你可以将其作为另一个项目的学习经验。
了解你的工作的影响
- 对我来说,首先应该 100% 清楚的事情是:我们正在解决的问题是什么,为什么(这通常来自 PM、设计师或商务人员),以及我们应该如何解决这个问题。
- 考虑到这一点,我密切关注重要的“指标”:
business/ux
:我与 PM 和设计师一起了解我们将要关注的业务指标和 OKR。engineering
:性能、构建时间、错误日志、监控系统。dx
:我的队友反馈了哪些痛点,并制定了解决这些问题的举措。
每周文件
- 正如我所说,我会记录所有事情。这已经成为一种习惯。每周结束时,我都会把每天的记录整理成一份周记。
- 看到我所做的事情、所学到的东西以及必须克服的挑战,真是太酷了。
季度文件
- 以这种方式记录也很棒,因为我可以将我在季度末写的所有笔记汇总在一起,它就像一份报告文件,公司里每个人都想知道我在做什么。
- 该文件还可作为与经理交谈的“吹牛文件”。
- 你的经理很容易了解你的成就。
- 您的经理可以轻松地使用此文档来促进您的晋升(如果您对此感兴趣的话)。
这就是为什么我认为记录和日志如此重要。养成一个小小的习惯,在积累了所有工作之后,会产生巨大的影响。作为工程师,我们往往关注日常生活中的小事,但拥有这种对工作的宏观视野是值得的。这让我感到自豪,并意识到自己的进步。
最后的话
正如我在本文开头所写,尽管标题是一个真实的故事,金钱也是我们生活中宝贵而重要的资本,但我还是想谈谈技能、经验、机遇和心态。基本上,我是如何提升自己能力的。我希望这篇文章能对你的职业生涯有所帮助。欢迎你借鉴一些你觉得有趣的想法,并将它们运用到你的生活中。
最后,我要说声谢谢!感谢QuintoAndar优秀的企业文化,以及与我共事的优秀同事:我的同事、我的经理、领导,以及利益相关者,他们让我成为了最好的自己。我心中只有感激。
资源
著作
- 优化 React Progressive Web App 的性能
- React Hooks、Context API 和 Pokemons
- 闭包、柯里化和酷炫的抽象
- 为 React intl 消息构建抽象
- JavaScript 中的函数式编程原则
- React 和 Redux 中的一致状态管理
- 使用 TypeScript 进行思考的思维模型
- 使用 React、TypeScript 和测试库进行 UX 研究
- TDD、简单函数和 React 组件
- React 测试库的基本方法
- 使用 react-query 在 React 中获取数据
- 前端工程中的 DX 和软件可维护性