序:最近看了一篇谷歌工程师总结自己十年来所学到的软技能,感觉说的很棒,特地翻译成中文,希望能分享给更多的人,原文内容非常多,计划分几篇翻译出来,个人的水平有限,感兴趣的朋友也可以进去看英文原文。原文地址是:software-engineering-soft-parts(Addy Osmani)
正文:
前言
今天我将分享一些我在谷歌浏览器团队中作为高级工程师在10年间学到的一些软件工程“软技能”。在我的10周年纪念日,我想反思一些一直伴随着我的经验。我希望这些在你的职业生涯中对你有所帮助。
在我看来,成为一名优秀的工程师就是不断积累经验。项目无论大小,都是一个往你的工具箱添加新技术和工具的机会。当你将在一个项目中学到的技术与在另一个项目中学到的工具配对来解决问题时,这会为你带来更大的进步。
学习新事物
以下建议有助于大多数初级或中级开发人员向前发展,用来应对不断变化的技术,构建复杂系统,同时遵循软件工程范式中的标准流程并发现新的最佳实践。尽可能应用第一原则。学习将问题分解成更小的部分是生活中最重要的技能之一。
精通
精通意味着高效的工作
这意味着您可以分辨出能带来价值的任务,并帮助您的团队将精力集中在这个方向上。这也意味着您知道如何避免一些无法为团队或者公司带来价值的工作——最好的工程师甚至可以引导整个团队远离那些无意义的工作。
我经常被问到,“我怎么知道我是否充分利用了我的时间?”。几乎总是有一些任务可以让你“感到”忙碌。这里真正的诀窍是确保你在做正确的事情。如果您想移山,请专注于移动针的任务,即使这任务很小。
你可以问自己一些问题:
- 我的目标是什么?我关注的任务是否与这些目标一致?
- 有什么我可以做不同或更好的事情吗?
批判性思考并提出合理的论点
批判性思维是独立思考以做出深思熟虑的决定的能力。投资于这项技能,以提高你的思路清晰。
作为工程师,我们有时会急于立即解决问题,因此感觉就像我们正在取得进展,或者看起来我们正在对利益相关者做出响应。如果我们没有充分考虑原因和后果,这可能会带来风险。换句话说,批判性思维是有目的地思考并形成自己的结论。这种以目标为导向的思维可以帮助您专注于根本原因问题,从而避免未来因没有思考造成问题的原因和后果而出现的问题。
概括地说,我喜欢根据批判性思维提出的一些问题是:
- 我们怎么知道我们正在解决真正的问题?
- 我们怎么知道我们正在以正确的方式解决问题?(即平衡严谨性和效率,考虑到我们对问题和约束的理解)
- 如果我们不知道问题的根源,我们如何确定根本原因?
- 我们如何将关键问题分解为可以进一步分析的更小问题?
- 一旦我们有了一个或多个假设,我们如何来评估它们?
- 如果我们受到限制(时间压力)而又不过度损害我们围绕问题的分析严谨性,我们可以采取哪些捷径?
- 证据是否充分支持结论?
- 我们怎么知道什么时候能解决?什么时候解决方案才是“足够好”?
- 我如何向所有利益相关者清晰、合乎逻辑地传达解决方案?
我发现这些问题通常会有所帮助。有时我们会解决问题的症状,却发现还会出现其他症状。在其他时候,我们可能会很快发布一个解决方案,但会在以后产生更多问题。从批判性思维的角度来看,我们可能会挑战假设,仔细研究风险/收益,寻找矛盾的证据,评估可信度并寻找更多数据来建立我们做正确事情的信心。
例如,我见过工程师犯的一个常见错误是假设相关性意味着因果关系(即,仅仅因为两件事相关并不一定意味着一个导致另一个)。一个批判性的思考者可能会反驳这样的假设,问我们为什么相信它们是正确的。
批判性思考者:
- 提出有意识的问题,清晰而准确地提出问题
- 收集和评估相关信息,验证他们可能如何回答问题
- 得出合理的结论和解决方案,根据相关标准和标准对其进行测试
- 在不同的思维系统中开诚布公地思考,根据需要识别和评估它们的假设、影响和实际后果
- 与他人有效沟通,找出复杂问题的解决方案
注意:批判性思维具有“软技能”和“硬技能”两个方面,因此包含在本文中。
建立强大的基础
掌握基础知识并反复应用以获取新技能。
学习基础知识的长期价值在于它们是可转移的。短期而言,它们可以帮助您做出更好的决策,并使代码更有效率。
可转移的技能
可转移的技能是您可以从一个项目带到另一个项目的技能。让我们从基本面来谈谈它们。
基础知识是任何软件工程师的根本。它们宏观和微观两层。宏观层是软件工程的核心,微观层是实现(例如技术栈、库、框架等)。
在宏观层面上,您学习的编程概念在很大程度上可以转移,而与语言无关。语法可能不同,但核心思想仍然相同。这包括:数据结构(数组、对象、模块、哈希)、算法(搜索、排序)、架构(设计模式、状态管理)甚至性能优化(例如急切与惰性评估、记忆化、缓存、惰性加载等)。这些是您将经常使用的概念,以至于往后了解到它们可能具有很大的价值。
在微观层面上,您将学习这些概念的实现。这可能包括:您使用的语言(JavaScript、Python、Ruby 等)、您使用的框架(例如 React、Angular、Vue 等)、您使用的后端(例如 Django、Rails 等)以及技术您使用的堆栈(例如 Google App Engine、Google Cloud Platform 等)。其中涉及的细节对于获得有效的专业知识可能很有价值,但并不总是可以转移的。
没有人有时间在职业生涯开始时学习所有内容。我们不应该过度索引基础知识,要去学习实际应用程序所需的内容。这就是“边做边学”。
效率
掌握基础知识可以帮助您编写更高效的代码。这包括时间复杂度(运行代码所需的时间)、内存使用以及性能和可维护性之间的权衡等概念。这些想法允许您在构建任何相当大的应用程序时做出有用的权衡。速度对于现代应用程序而言通常至关重要,并且通常会以明显的方式影响最终用户体验。
更好的决策
对宏观和微观基本面有很好的了解可以帮助您做出更好的决策。
您可以利用所获得的知识,根据任何项目的目标和限制,更好地决定使用哪些技术以及避免使用哪些技术。这可以帮助您避免为工作选择错误的技术或错误的工具的陷阱。
“在你明白什么时候不应该使用它之前,你还没有掌握一个它。” -@kelseyhightower
软件工程涉及考虑许多不同的层次——核心语言、实现、基础设施、工具和人员。对这些层次有一个表面的了解,可以让你编写程序更快。但真正了解基础知识(包括 O(n) 时间复杂度)可以帮助你走得更远,尤其是当语言和框架的格局随着时间而变化时。
相关阅读:
- The value of fundamentals in Software Engineering
- Why learning the fundamentals matters
- Learn the fundamentals of a good developer mindset