在我的职业生涯中,我对工作方式的态度发生了两到三次重大转变。起初,我只专注于工程——试图尽可能多地了解我正在使用的语言或库,非常注重“琐事”,并最终忽略他人的担忧,只是为了编写好的代码。这并不是说我不努力与同事相处或帮助他们,但我改进的努力都是为了我自己;毕竟,随着我变得更好,团队和公司也会做得更好。公平地说,这种方法并非完全没有道理。作为工程师,我们必须不断发展、学习更多、进步,因为这个行业变得越来越难,每天都需要更多的技术解决方案来解决更大的问题。这种方法在我的职业生涯的前半段对我来说效果很好,那时我资历尚浅,有这种自私(尽管是善意的)动机。
后来,我换了一份工作,在一个办公室里与比我整个职业生涯中合作过的工程师还要多的工程师一起工作。这份工作几乎让我崩溃。我从角色中较优秀的人之一变成了勉强糊口……将近两年。我努力取得成功,我经常感到自己不如周围的人,很多时候我不明白他们为什么要雇用我(事实证明,我的一些同事也有这种感觉)。但没有什么大的顿悟,也没有什么决定性的时刻扭转局面。只是一系列的艰难而彻底的失败,我从中只有两个选择——放弃或学习和成长。我尽力做到后者。当我回到一家规模较小的初创公司时,我亲眼看到了从头开始建立一种基于这些教训的文化是多么重要。
我的最后一次心态转变发生在初创公司被一家大公司收购后,我转型为管理层。我没有选择成为一名经理;管理层选择了我,因为他们给了我这个职位。他们还告诉我,虽然每个人都非常信任我,但他们选择我的最终原因是,他们觉得从内部晋升某人比从外部招聘某人动荡要小。收购后,我们的时间表非常紧迫,我的新公司不想因为引进一位不被团队信任的外部领导者而冒险。我发现这个阶段巩固了我之前学到的一切关于如何在工程岗位上取得成效的知识——并加大了我每天每分钟都需要应用这些教训的力度。
在 Twitter 上分享
2018 年 5 月,在与我们扩展团队的一位初级成员进行了一次特别有意义且有价值的对话后,我在 Twitter 上发布了关于职业发展的推文。这条 Twitter 帖子比我预期的更受关注,并且 Matt Broberg 邀请我为 Opensource.com 撰写这篇文章。(Matt 告诉我我不允许在这篇文章中说脏话,所以请理解他的管辖权不包括我的推文。)
如果您只是想看简短版本,这是简短版本
-
专注于改进您与他人的沟通方式,特别是沟通的内容、语气和及时性。
-
努力成为更强大的合作者——“角落里的工程师”不是您想要的头衔
-
了解负责某事意味着什么,并努力实现您的承诺。职业生涯的提升意味着更广泛的责任和更少的方向指导您该怎么做。
-
学会失败,并从失败中学习。您会经历很多失败,大多数是小失败……但也有一小部分大失败。不要让它使您脱轨;将其用作您下一个成功的垫脚石。
-
“解决问题”是您可以拥有的最重要的一项工程技能。
-
永不停歇地学习。如果您停止学习,您就会停止成长。如果您停止成长,您就无法迈向更大更好的事物。
-
学习 SQL;您以后会感谢我的
如何成为一名成功的工程师
最近,我们团队的一位年轻成员问我:“您希望软件工程师具备什么品质?”。他告诉我我的回答让他感到惊讶,并且与他得到的其他答案不同,但在过去的几天里,我最终与不同级别的许多人进行了同样的对话...
— Sean Kelly (@StabbyCutyou) 2018 年 5 月 31 日
在一位支持工程师向我咨询关于如何成长为软件工程师的建议后,我发布了这条推文(以及随后的帖子)。我认为他期望我列出一系列技术、工具和编程语言,这些可以帮助他在工程团队中找到一份工作。相反,我给了他一份需要关注的行为清单。我的想法是,无论您从事什么工作(尤其是在初级职位上),都可能会对您进行成功所需技术的培训。(至少在任何与如何以及雇用谁建立健康关系的地方,情况都是如此。)但我提到的事情是没有工程师可能会明确与他合作的事情,因为它们传统上与我们不幸地称之为“软技能”的东西保持一致。
我在这里暂停一下,声明“软技能”这个短语淡化了它们在成为一个全面发展的人,更不用说成为团队中成功的一员方面所起的作用。尽量避免称它们为“软技能”(我在这里使用它是因为可悲的是,这是我们都知道的术语)。“整体技能”可能是一个更好的术语,但它不太吸引人,而且说实话,我不是来向您推销花哨的新术语的。
我还想说,我即将阐述的内容并不是我认为我总是正确做到的事情,甚至不是我做了 15 年仍然不需要努力的事情。
但在我的职业生涯中,这些通常是我希望与之共事的优秀工程师的标志— Sean Kelly (@StabbyCutyou) 2018 年 5 月 31 日
重要的是要指出,这些不是您永远“实现”或停止增长的技能(我认为大多数技能都是如此,但在此上下文中尤其如此)。团队动态非常复杂。作为人,我们是善变的。我们有顺境和逆境,我们会挣扎,我们会崩溃。更糟糕的是,我们这样做的方式无法在 FAQ 中涵盖,也无法在脚本中自动化,这与我们运行的许多系统不同。我们的失败案例几乎是无限的,因此我们的学习能力、适应能力和恢复能力需要与之匹配。我失败过无数次,也接受我还会再失败无数次。但只要我一直在学习,我就一直在成长。我可以自信地说,在我职业生涯中,我最喜欢与之共事的人都在以下技能方面得分很高,主要是因为他们一直在努力提升这些技能。
现在也是时候指出,没有人应该期望您在所有这些技能或任何技能方面始终都做得完美。每个人都有糟糕的日子。关键是要让糟糕的日子成为例外,这样当事情变得有点太艰难,而您的反应方式(反思后)低于标准时,人们不会认为那是您的常态。这些技能将帮助您在团队中建立信誉,以便您在那些因为各种原因而无法发挥最佳水平的时刻兑现这些信誉。
善于沟通
他们知道如何有效地与他人分享他们的知识。他们知道何时应该更技术性/不那么技术性,以及使用更多/更少的细节。他们理解肢体语言的重要性。当事情进展不顺利时,他们不会躲藏起来,而是经常向上/向外沟通。— Sean Kelly (@StabbyCutyou) 2018 年 5 月 31 日
沟通是您作为一名高效工程师生活中最重要的部分之一。您可以在角落里当孤狼,编写出色的代码,而没有人干扰您的技艺,这种想法对于我们行业中 99% 的人来说是不现实的——甚至可能超过这个比例。虽然独自一人如此高效的浪漫想法非常诱人,但隐藏在其中的陷阱是,这些人通常被视为一种负担。
我以为我在职业生涯早期是一名优秀的沟通者,但我后来了解到,我在不重要的时候过度沟通,而在重要的时候沟通不足。我努力找到正确的平衡——何时变得过于技术性(我几乎总是这样做)以及何时只给出 50,000 英尺的概览——这取决于我与之交谈的人的类型。当事情进展不顺利或“尚未准备好被看到”时,我也会躲藏起来——我不会过早地寻求帮助,我会独自迭代设计,直到我觉得它们准备就绪,我将对方法的批评误解为对自己的批评。我花了数年时间才内化了需要尽早向同事公开我的想法、我的工作状态以及我的设计的原始性质。
我记得我注意到自己在这方面有所进步的时候。我当时正在进行一个小型但重要的工作项目,我没有等到问题累积到爆发的程度,而是每天都告诉我的经理项目的进展情况、我担心即将出现的障碍以及这对底线意味着什么。您可能会想“这不是站立会议的目的吗?”,但我们大多数人只是使用站立会议来列出我们所做的事情以及我们可能要做的事情。它不是用来进行对话的。但这正是我发现对我更有帮助的东西:对话。我们每天早上在我在安顿下来准备开始一天的工作时,就事情的进展情况进行了随意但详细的对话,时间不超过 10 分钟。对于项目的进展情况、风险以及我是否需要任何外部帮助,从来没有任何困惑。它教会了我尽早且经常地沟通,并且(在健康的环境中)我不会因为不完美而受到惩罚。相反,我因展示了我知道如何有效地沟通而获得了更大的自主权。
尝试与您的经理就您正在进行的工作进行对话。他们会为此感谢您(在奔赴他们的下一个会议之间)。
善于合作
他们知道何时是与他人合作的合适时机,以及何时是埋头苦干的合适时机。他们不怕向其他团队成员征求意见——包括更资浅的和更资深的。他们可以在不变得 defensive 的情况下捍卫自己的立场。— Sean Kelly (@StabbyCutyou) 2018 年 5 月 31 日
沟通是合作的基石,但建筑物并非仅由基石建成。有效的合作是在作为一个团队完成工作的框架内应用的沟通——有时是一个由两个人组成的团队,有时是一个由 20 个人组成的团队。有时合作是知道何时不让太多人参与,这样您就可以专注于将某些东西推进到足够具体以获得反馈的程度,有时是在您获得足够的反馈以确切知道您应该构建什么之前,什么都不开始。换句话说,这是一个平衡行为。但是,专注于成为一名高效的工程师意味着与他人合作——分享工作、分享想法、提供良好的反馈、良好地接受反馈,以及最重要的是,指导(并最终赞助)您周围的人。没有良好的沟通,您就无法进行良好的合作,反之亦然。它们是密不可分的。
但这需要您学习妥协,以便您可以在不变得 defensive 的情况下进行捍卫。支持您的工作或您的提案并给出您的理由是可以的,但要接受其他人可能对您正在做的事情有不同的看法或需求,并且这些意见也很重要。合作意味着就您的工作状态进行良好、健康,有时甚至是艰难的讨论。学习参与这些讨论而不会成为攻击者,并在不感到被攻击的情况下离开,是有效合作的一个主要方面。这需要整个团队共同努力,以确定一套使合作成为可能的规范。请记住,每个人都在这里尽力做到最好,但并非每个人对什么是最好的工作都有相同的想法。从这个起点开始建立信任。
关于导师:许多人可能会错误地认为导师制始终是两个人之间的一种正式伙伴关系,但情况并非总是如此。每当您与他人合作时,您都在被动地(或者,更好的是,主动地)向他们传授关于您自己以及您可以做的事情的知识,就像他们也在教您一样。有效的合作可以用一句著名的格言来概括:“涨潮会抬高所有船只”。它承认您在这里是为了支持他人,就像您期望他们支持您一样。最终,您会发现自己处于可以为您指导过的人提供支持和掩护的位置(称为赞助)——但是您永远不会仅仅通过努力成为不善于与他人合作的孤狼而达到目标。
另一个需要学习的重要教训是,合作不仅仅发生在工程层面;工程师经常(尤其是在重要项目中)需要跨业务领域进行合作才能完成工作。例如,您从事的工作可能会影响财务人员用来向业务干系人展示数字的报告管道。高优先级的任务通常会因其影响而受到很多关注。向上和向外沟通和协作变得越来越重要——尤其因为他们所有人对他们需要从您那里获得的信息都有略微不同的偏好。您可能会说,“好吧,那是经理的工作,这样工程师就可以继续工作了”,但这最终是不正确的。
有效管理工程师的一个目标是让他们对正确的干系人负责,并看着他们在这种光环下成长。将他们隐藏起来,您就会阻碍他们的成长。经理的平衡行为是知道工程师何时参加的会议太多,而不再有足够的时间坐在键盘前,但这又是另一回事了。对工程师提出与干系人直接合作的期望,您就可以帮助他们培养他们的整体技能。尝试阻止他们参与这些对话,最终您只会强化这样一种观念,即他们的唯一价值在于他们编写的代码行数,而不是他们为解决客户问题而构建的解决方案。
经理们,鼓励您的工程师与企业界的同事合作并建立关系。
承担责任
可以信任他们能够达到或超过他们的水平。他们努力在最后期限前完成任务(结合第 1 点和第 2 点),并且知道为什么按时完成任务很重要。或者他们可以帮助调整期望,以便业务的其他部门知道为什么无法按时完成任务。— Sean Kelly (@StabbyCutyou) 2018 年 5 月 31 日
管理责任是困难的,因为您获得的经验越多,您需要负责的事情范围就越大,而关于如何做的指导就越少。在实践中,这意味着负责任的行为是一种依赖于上下文的努力,并且通常为了承担更多责任,您需要学习如何管理自己,以便您可以处理更多任务,并以更大的自主性执行它们。
让我提供两个例子来澄清我的意思。在某个时候,我发现自己负责管理我们整个平台的排队和后台作业基础设施。这要求我对依赖此基础设施的其他工程师负责,以便他们不必积极担心其健康状况,提供关于如何向系统添加新功能或作业的清晰明确的建议,并帮助诊断他们的集成问题。我必须对整个公司的工程师和团队负责,不仅要负责系统的现有状态,还要帮助他们弄清楚如何增加他们对系统的依赖。幸运的是,当时我基本上只需要与其他工程师交互,因此这种情况在我当时的技能范围内是可控的。
后来,我负责平台财务支柱的大规模迁移。由于资金在平台中流动的齿轮最终会影响许多业务问题,因此突然之间,我需要与来自账单部门、各种产品经理和老板的老板们进行交互,更不用说所有我可能接触到的代码的工程师了。这需要我从未接触过的协调和协作水平。这也意味着我必须更擅长与非工程师人员交谈,他们基本上不关心工程问题,他们需要知道他们的工作会发生什么变化,并且他们只需要知道它会正常工作。对他们来说,问题不是技术问题,而是业务问题:我们需要这些数据,我们需要准确的数据,并且我们需要按时获得数据。再多的以工程为中心的对代码库老化的抱怨也无法安抚他们。这需要数月的计划、测试、执行、与我从未听说过但突然不得不信任我的人会面等等。我写了更多的电子邮件,参加了更多的会议,并且最终比我职业生涯中以往任何时候都花了更多的时间在我的首选编辑器之外。毫无疑问,这使我成为了一名更好的工程师。我第一次真正接触到我正在为其提供解决方案的真实客户,获得了他们的意见,让他们了解问题,并与他们找到了解决问题或边缘情况的折衷方案。这真是太棒了。
作为工程师,当我们承担更大、范围更广的项目时,我们需要拥抱这种责任的全部重量,而不仅仅是躲在我们的代码中。通过与工程团队和其他团队(包括非工程团队)联系,我对我要为谁构建和维护有了更好的理解,这帮助我理解了哪些优先级是真实的,哪些只是对更大目标的干扰。经理不能向工程师隐瞒这些机会,工程师需要知道他们何时准备好拥抱这些机会。
可以处理失败
这是一个棘手的问题,因为并非每个人都处于平等的地位——并且同样的错误可能会根据您的身份而受到不同的批评,这很不幸。但是,对如何从失败中学习并克服失败的普遍理解是必须的。— Sean Kelly (@StabbyCutyou) 2018 年 5 月 31 日
对于许多人来说,谈论这个问题可能会感到不舒服,因为失败自然而然地不会公平地发生。来自某些人口统计群体的人比其他人不成比例地面临对其表现的批评和最终评判。重要的是,每个人都要明白,解决这个问题始于您自己。不要因为您的同龄人尝试并失败而惩罚他们,就像您不希望受到惩罚或评判一样。将失败视为学习的一种方式来庆祝。太容易陷入拆台的陷阱,尤其是那些“不像我们”的人。不惜一切代价避免这种心态。他人的成功不会威胁到您自己的成功(在许多方面,它会帮助您成功),并且将您的精力集中在培养您周围的人身上会获得更大的回报。
像保证会失败一样计划。我不是说要着手失败,而是要吸取的教训是,当失败发生时,要预期并接受它。
如果您发现自己今天身处消极的“惩罚”文化中:改变它。立即改变它。在拉取请求 (PR) 上留下更有意义和协作性的反馈。问问自己,“我是在直接评判这个人,还是在提供关于代码的可操作反馈?” 了解“这是绝对应该改变的事情”和“这不是我会做的方式,但这并不意味着它是错误的”之间的区别。为此,您可以研究一个您可以使用的短语,该短语可以概括这种感觉,而无需直接说出来。例如,当有人向我征求关于某事的反馈,而它不是我会做的方式时,我会确保我理解他们的目标,解释我将如何处理它,并说“但您应该追随您的内心”。这样我就不是在告诉他们该怎么做,只是提供了关于其他人可能如何处理它的背景信息。如果他们选择不采纳我的建议,我也绝不会批评我的“追随您的内心”反馈。当您确实需要提供 критический 反馈时,请选择更好的措辞。“直言不讳”很容易变成“您对我来说并不重要,因此我可以随意使用任何语言来批评您的工作”。您可以诚实和直接,而无需生硬或粗暴。
总而言之,作为一名工程师,您需要学习如何看待失败的价值——因为您会经历很多失败。您从事的工作会崩溃,系统会突然崩溃,项目会失败,人们会被重新分配到其他工作,有时您只是会彻底犯错。这只是工作的一部分,学会不因此而气馁,而是将其视为学习机会,这将使您在职业生涯中成为一名更有效的工程师。
解决问题的能力
对寻求适当的解决方案和理解根本原因的自然倾向从未让任何我认识的工程师失望过。您不必成为编程领域的夏洛克·福尔摩斯才能成为一名优秀的解决问题者,您只需要奉献精神和专注力。— Sean Kelly (@StabbyCutyou) 2018 年 5 月 31 日
我建议人们关注的首要技术技能是解决问题。这也是并非每个人天生擅长的技能之一,但我认为每个人都可以通过足够的时间来学习。您需要专注于解决问题的策略,因为最终这就是您获得报酬的原因。
许多工程师最大的误解是他们获得报酬是为了编写代码。这是错误的。
您获得报酬是为了解决问题——但您使用的最常见的解决问题媒介是您选择的代码编辑器。因此,在您职业生涯的初期,解决问题的行为主要与您编写代码的能力有关——修复错误、遵循规范或一组大纲来添加新功能等等。但随着您职业生涯的进步以及您从事的工作范围的扩大,您会越来越发现越来越难的问题,最终会涉及到您无法仅用代码解决的问题。但推动这些解决方案——了解如何快速评估情况、利用您的经验来确定可能的原因,并努力证明或证伪这些假设——将永远是您工具箱中最重要的技能。
但这并不意味着您要孤立地坐着,直到您可以自己解决问题——良好的解决问题能力通常需要让其他人参与进来以帮助您思考。从外部角度看待问题可以提供一组关于您可能缺乏并且可能永远无法独自获得的信息。这是聘请来自不同背景的人员的众多原因之一——如果您周围的每个人都只知道什么是钉子,那么您将只会制造出更好的锤子,而隔壁的螺丝刀公司会抢走您的午餐。我们常常试图以一种解决方案只适合我们认为自己是谁的方式来解决问题。这会导致产品质量差、代码不灵活以及错失机会。挑战这一点。
当实际开始工作时,了解何时应该埋头苦干,何时应该广泛地进行解决问题的努力是您随着时间的推移需要磨练的这项技能的另一个方面。有时,您必须仅用自己的双手来解决问题;有时您需要他人的帮助。学习何时做每件事(您应该始终更偏向后者)是经验的标志。
承认这一点可能令人尴尬,但在我正在进行的一个项目中,我确实需要复习一些基本的数学知识——指数运算规则。起初,我很犹豫是否要寻求帮助。毕竟,工程师应该擅长数学。但我数学很糟糕。我从小到大在所有数学课上的成绩都平平,而且我的大学(谢天谢地,对当时的我说)对计算机科学没有很高的数学要求。在绞尽脑汁思考如何将一些基于指数的规则正确应用于一些财务数据后,我意识到自己是个懦夫。我走到离我最近的同事那里,请他帮我用白板写一些数学公式,以便我重新理解这些规则。他花了将近两个小时的时间和我一起在深夜重新学习了这是如何运作的。我现在有了一个我知道可以帮助我更好地审查代码的人,寻找更多错误或提供关于实施的更直接的反馈。我必须解决这个问题,但我不必独自解决它,并且最终得到了更简单的审查过程。我仍然认为这是我职业生涯中最令人愉快的事情之一。
乐于学习
我们的行业发展太快了。每天都有新技术出现,旧的“最佳实践”被揭露为我们一直以来都知道的欺诈行为等等。您不必跟上一切,但您应该享受学习的过程。— Sean Kelly (@StabbyCutyou) May 31, 2018
如果解决问题对你来说是自然而然的事情,你可能会认为学习也是如此。毕竟,如果解决问题不是收集和执行新信息的行为,那又是什么呢?
但是,很多人都觉得自己“完成”了学习,这很常见。他们已经从事这项工作 X 年了,他们觉得自己已经站稳脚跟,他们觉得自己是“权威”——而且他们很可能确实如此。但是技术和我们用来维护它的工具每天都在变化。你根本不能宣称自己“完成”了学习,在任何方面都不能。
具体来说,你总是有新的东西要学习,关于如何更有效地与他人合作,你总是有新的技术领域需要亲身实践,而且你总是在拐角处遇到下一个失败,等待你从中吸取教训。我真的没有太多明智的建议,除了说你不应该害怕遇到你不懂的东西,并承认你不知道。此外,你不必知道一切,尽管这很诱人。这是不可能的,如果你能信任你周围的人,你就不需要知道一切。参加其他团队的事后分析会议。在产品中找到你不理解的东西,然后去问别人。请你的老板帮你找到一个新的代码库领域来学习。渴望知识,知识会自己找到你的。
我特意告诉他“你会注意到我没有在其中提及任何特定的技术或工具”,这是有充分理由的。
你可以比上面那些更容易地被教会这些东西。你可以带一个具备上述所有素质的工程师,并教他们你的技术栈。— Sean Kelly (@StabbyCutyou) May 31, 2018
但反过来则不然——你无法让一个了解你的技术栈的工程师快速学会以上几点。事实上,一个人越资深,就越难纠正。
这就是为什么有时冒险聘用更年轻的工程师是最佳选择。— Sean Kelly (@StabbyCutyou) May 31, 2018
在 Twitter 话题中,我因使用“更年轻”这个带有偏见的词语而被正确地指出,所以我想首先澄清一下,我指的是“职业生涯更年轻”,而不是年龄。现在人们比以往任何时候都更容易改变职业,所以我们需要注意,不要仅仅根据年龄来对人产生偏见。
在我看来,这些技能比任何一项技术都重要。虽然很容易指出一些常年的主流技术,但这通常不是人们想听到的。他们想听到的是“学习 Kubernetes,因为它实际上是每个人都在做的,所以它永远不会过时永远不会。”或者“这个新的(Apache/Cloud Native Foundation/你从未听说过的其他联盟项目)将在五年内成为THE THING,所以现在就成为这方面的专家。”可悲的事实是,这些答案实际上对一个人的成长是有害的。你很有可能在任何地方找到一份工作,都会有你无法预测的自己的技术栈(但你可以打赌它会在某个地方有 SQL),你会在那份工作中花费大量时间来学习和成长,以管理该技术栈。
相反,当有人问你他们应该学习什么技术时,问问他们想学什么。他们对什么感兴趣?也许是图表,也许是统计学,也许是艺术或摄影或音乐。这些都可以指向有趣且小众的技术,合适的人会因为它们实现的结果而爱上它们,而不是关于它们如何准备接管的浮华博客文章。在个人层面上与人互动,找出让他们兴奋的是什么,以及他们希望用技术解决什么问题,并鼓励他们学习这些技术。
但是,如果有人问如何成为一名更好的工程师,请考虑一下什么会让团队想要聘用他们。以我的经验,这就是这篇博文中涵盖的技能和态度。在任何一天,我都会因为这些东西而聘用人,而不是任何一项技术或编程语言。
工程师通常认为“改进的途径是更努力地做技术”。学习更多技术,成为更深入的主题专家等等。虽然这没错,但也不完全准确。当你在职业生涯中前进时,你不能忽视上述技能组合。
— Sean Kelly (@StabbyCutyou) May 31, 2018
当我的团队中有人希望从初级职位晋升到更高级职位时,我首先会关注上述几点——因为更资深的人是更广泛地面向公众的人。他们无法避免与他人互动,因为他们对于完成工作至关重要。
— Sean Kelly (@StabbyCutyou) May 31, 2018
作为一名职业工程师,你花费时间最多的第一件事就是交谈。与其他工程师交谈,与产品经理交谈,与支持和销售人员交谈,与你的老板交谈,甚至可能不时与他们的老板交谈。能够有效地管理这些关系——通过成为一个多方位的良好沟通者,即使在意见不一致时也能与他人良好合作,处理日益困难和复杂的职责,从你不可避免地会遇到的失败中学习,而不是沉迷于失败,专注于将这些技能应用于解决问题(技术或其他方面),以及最重要的是始终成长和学习——这些技能将把你带入成功的工程职业生涯,而不是任何一项单独的技术技能。
除了 SQL 之外。你知道吗,帮自己一个忙,学习 SQL。任何告诉你某种本周流行的新数据库消除了学习 SQL 的必要性的人都在对你撒谎,无论他们是否意识到这一点。学习 SQL;它真的很有价值,而且不会过时。
如果你看到这里,这是一张我狗狗的酷照片 pic.twitter.com/3Ex92HOdyH
— Sean Kelly (@StabbyCutyou) May 31, 2018
10 条评论