写给刚入行时的自己的建议

写给刚入行时的自己的建议

原始链接: blog.pragmaticengineer.com/advice-to-m...

回顾十多年前,我希望自己能早点养成一些习惯,这些习惯本可以帮我成长得更快、更专注。以下是我给刚入行做软件工程师的自己的一些建议。

1. 每年花时间读两本软件工程方面的书

每次我认真读完一本推荐的软件工程书籍,我的水平都会得到提升。所谓"认真读",指的是做笔记、和别人讨论章节内容、画图帮助理解、动手实践,并且反复阅读。

我真希望在刚做开发的头几年就去读这些书。 我直到工作第 5 年左右才开始这么做。当时,《C# In-Depth》、《Clean Code》和《Javascript: The Good Parts》等书大大提升了我的技术能力。当然,不是说非要读这几本(有些现在已经过时了),我的建议是:去找那些能让你在现有认知上继续深挖的书,无论是特定技术还是工程实践都可以。

我读书很慢,一次通常只读一两章。我会做笔记或划重点。读完后会做总结,并经常和别人讨论。这几年,我也开始在博客上写书评来反思所学。这些习惯不仅帮我成长为优秀的研发经理,对工程师阶段也同样有用。想找点灵感?可以看看我的阅读清单

为什么推荐看书而不是看博客或视频?因为短篇幅的内容通常只停留在表面。书籍包含的是深入且系统化的知识。写像这样的一篇博客只要几个小时,但我写一本关于软件工程师成长的书却花了一年多。读书是一种缓慢但极其深度的吸收方式。

目标不用定太高:半年读一本书就很棒了。选定一本书,然后花时间好好 读透。读完一两本后,我还强烈推荐你读读《如何阅读一本书》(我是认真的)。

2. 深入掌握你工作中使用的编程语言

我最早兼职写代码时用的是 PHP 和一点 JavaScript。大学里学了 C 和 C++,但我都不太喜欢。第一份全职工作我开始写 C#。当时我表面上懂很多语言,但没有一门精通的。

工作两年后,我开始对一件事感到苦恼:每次调试 C# 代码还要依赖高级开发人员。一位经常帮我调试的前辈似乎对这门语言的底层细节了如指掌。他推荐我学习《C# In Depth》。我照做了,花了大把时间钻研线程、垃圾回收、泛型的工作原理,硬啃下了协变、逆变等难懂的概念。

深入学习工作中所用的语言,是我做过最正确的决定之一。 虽然这是受前辈启发偶然开始的,但这门手艺成了我在公司和后来面试时的巨大优势。在随后的职业生涯中,我会刻意深入研究新语言和框架。比如在 Skype 时,我本来是去写 C# 的,但后来团队转向 JavaScript 和 WinJS,我就顺势深挖 JS 并精通了 WinJS,后来甚至在 Pluralsight 出了相关教程

你掌握的语言越多,就越能客观评估它们的优缺点。 后来我转做 iOS 开发时,已经精通了好几门语言。当 Swift 刚问世时,我参与了语言的讨论,还提议把读写反射加入路线图。因为了解语言特性,我在帮团队制定从 Objective-C 迁移到 Swift 的策略时更加游刃有余。掌握的语言越多,学新语言就越快,也更容易深挖底层原理。

3. 多和同事结对编程

现在结对编程似乎不太流行了。但在我刚入行时,极限编程(持续结对)、TDD(测试驱动开发)和群体编程很火。我职业生涯中几次最大的飞跃,都是在和别人结对编程后发生的。这比看任何书都管用。

让我记忆犹新的是,有一位同事给所有人的代码审查(Code Review)都非常严苛。有一天我受够了,决定不在工具里回复他,而是直接坐到他旁边,让他当面解释他的意见。结果我学到了很多东西,同时也直接告诉他我觉得有些评论不太公平。他接受了,并建议我以后只要觉得有争议就直接来找他结对编程。我照做了。这位同事极度追求性能,通过结对,我学到了很多关于性能瓶颈的细节;作为交换,我也教会了他很多关于代码可维护性的知识。

另一次美好的回忆是和另一位工程师做 TDD。我们轮流交接键盘,一个写测试,另一个写实现代码。为了完成一个复杂的系统模块,我们整整干了两天。这次经历让人大开眼界,在中途梳理边缘情况时,我们甚至完全推翻并改变了最初的方案。我们因此建立了深厚的友谊,在此后的几个月里合作得非常愉快。

4. 编写单元测试,并在 CI 中运行

高级工程师经常强调单元测试的重要性。但这看起来很违背直觉:为什么要花更多时间去写那些看起来微不足道的测试代码呢?我曾有很长一段时间都是这么想的。

想要真正体会单元测试的价值,你需要经历一次"顿悟(aha!)"时刻------也就是你自己写的测试挽救了整个局面的那一刻。但在此之前,你必须耐着性子去写测试,并让它们在 CI(持续集成)中运行。通常你需要坚持几个月,才能等来那个"顿悟"时刻。

我经历过两次。第一次是我接了个私活,给一个小型的在线赌场写后端引擎。API 涉及真实的金钱交易,我极其害怕出错,所以给所有代码都写了单元测试。项目最终延期了,部分原因是写测试太费时间,但我心里觉得这样做是对的。两年后,客户告诉我,好几次团队差点把致命 Bug 发到线上,全靠那些测试报错才拦了下来。

另一次是在开发网页版 Skype(web.skype.com)。当时我们团队很强,代码有全面的单元测试和集成测试覆盖。项目做了三个月时,一位工程师提议重构整个项目结构。这风险太高了,大家都投了反对票。

但他反驳说,有这么好的测试覆盖率,重构应该是小菜一碟:"只要测试通过,代码就没问题"。我半信半疑,结果还真是这样。花了一周重构后,他提交了一个巨大的改动,而什么都没坏。当时没有,后来也没有,所有测试都顺利通过。就在那一刻,我意识到了强大的测试套件能提供多么可靠的安全网,让你再也无惧重构。

5. 养成重构的习惯,并掌握重构工具

很多年来,在团队代码库里,我只敢做最小范围的改动。在个人项目里我敢大刀阔斧地重构,但对于不是完全由我负责的代码,我一直不敢动手。

后来在 Skype,我遇到了一位工程师。他总是不断地进行各种大大小小的重构,代码变得越来越好,而且他从来不把代码搞坏。他是怎么做到的?

在和他结对编程时,我发现他非常熟悉自己的 IDE,装了各种重构插件。提取方法、重命名变量、提取常量......这些操作他一秒钟就能搞定。

我意识到,我不敢重构是因为我缺乏练习,而且没有掌握好工具。 当我开始把重构作为每周的习惯后,我在实操和工具使用上都变得更强了。这个习惯让我受益匪浅,我只后悔没有早几年开始。

6. 优秀的软件工程能力源于经验,去多多积累吧

刚入行时,我很怕高级工程师。他们能一眼看出我没发现的 Bug,对我不懂的问题对答如流。我以为他们就是比我聪明、比我强,这就是现实。

现在,我和许多顶尖的软件工程师共事过,也指导过不少人,我发现完全没什么好怕的。最优秀的软件工程师不过是"学到的知识"加上"真实世界经验"的结合体。知识可以学,而经验需要你自己去争取。

多去寻找机会,接触不同的技术栈、不同的业务领域,去接手有挑战的项目。 我花了七八年才达到所谓的"高级"水平。但在 Uber 这种高速增长的公司,我看到有些人只用三四年就做到了。区别在哪?这些人一直在做有挑战的项目,拼命想跟上周围人的步伐,甚至中途换团队从零开始。他们总是主动要求做新项目,并在团队中率先尝试新技术。我后来也变成了这样的人,只可惜前几年不是。

7. 把学到的教给别人

学习一样东西最好的方法就是去教别人。我一开始是误打误撞这么做的。2010 年,我开始在 .NET 和 Windows Phone 的用户组做分享。虽然我讲得不好,但为了准备演讲,我学到了很多。

现在,每当我想彻底学懂一个东西时,我就会报名去参加公开演讲。 2017 年加入 Uber 一年后,我主动提出去讲"Uber 如何大规模发布后端更新"。报名时其实我并不完全了解公司是怎么做的(我之前主要做移动端开发并管理移动团队)。为了这次演讲,我别无选择,只能把所有细节都扒个底朝天。而且压力相当大:大约有 100 名本地开发者报名参加了那场活动。

许多人都证明了这种方法很管用。Shawn "Swyx" Wang 就是 #LearnInPublic(公开学习) 理念的代表人物。他的成长故事比我精彩得多:转行仅仅四年,就当上了 Netlify 和 AWS 的高级工程师,还写了一本关于学习心得的书。教别人的好处在于你稳赚不赔。你不仅自己学会了知识,还能帮助和启发他人。

我认识的优秀工程师,没有一个不是出色的老师和导师。你越早开始分享和教学,日后做起来就会越自然。

欢迎订阅我的每周邮件通讯,获取类似的文章。内容值得一读,这也是 Substack 上排名第一的技术类通讯

相关推荐
jonjia3 小时前
进入决策圈
程序员
jonjia3 小时前
2025 年的职业建议
程序员
jonjia3 小时前
专注真正重要的工作
程序员
jonjia4 小时前
工程师的绝望谷
程序员
jonjia4 小时前
高级工程师应该做些“额外投资” (Side Bets)
程序员
jonjia4 小时前
裁员时代的战术性工作指南
程序员
jonjia4 小时前
这不是你的代码库
程序员
jonjia4 小时前
科技行业的好日子结束了
程序员
jonjia4 小时前
大型科技公司的项目是如何失败的?
程序员