它不是clickbait标题,但我知道为什么看起来像这样。
我已经非常清楚地表达了对10x开发人员的想法。我认为,某个人的代码生成量是其他人的10倍,这已经使人望而却步,这会拖慢其他开发人员的速度。我认为,如果您通过减慢其他所有人的速度来实现这一目标,那么10倍的收益并不重要。我认为10倍必须考虑您如何影响他人。
矛盾的是,这为如何成为10倍开发人员提供了一条途径:授权和支持其他人,以便完成另外9名开发人员的工作。您可以通过使其他九个开发人员的工作流程平滑2倍来实现。您还可以通过使其他18个开发人员的工作流程平滑50%,或使其他90个开发人员的工作流程平滑10%来做到这一点。
在某个时候,您在X中最大的收获就是可以改善其他开发人员的生态系统。有时候,我成功的时候(从推动工作场所变化到教授计算机科学课程),我注意到我正在使用三种技术中的一种或多种。所以我想在这里列出他们。
学习是工作。有时候,这很无聊或困难。除非他们明白为什么要这么做,否则人们不会从事这种工作。这不只是告诉他们为什么那么简单。理解来自与材料的接触。
假设您想对代码进行重大更改,从而影响团队的工作流程。如果您勇往直前而没有买入,那么团队会对此表示不满(正如我们在此处详细讨论的那样)。因此,我建议从有关更改原因的对话开始:
是什么困扰着您团队当前的工作流程,从而促使您推动解决方案?您是否不得不在不同的地方一遍又一遍地编写相同的代码而感到烦恼?您是否厌倦了尝试使用不透明工具的方式?您是否正在失去花费时间和金钱的事物?在您推您的解决方案之前,请确保您的同事感受到您的痛苦,将其拉到那里。
在进行大型重构之前,我将与团队中的关键人员故意进行配对,以解决重构所能解决的问题。我希望他们亲身经历痛苦;我想听听他们说“噢,天哪,这很烦人。”在我承认团队中绝大部分人都感到痛苦之后,我会提出我的解决方案,并提议率先进行重构。我将就重构后我们的工作流程如何变化做出简明的解释,并指出为什么我认为新方法比我们现在做的更好。我有关于旧方法的“负面评价”,可以用它来吸引其他人对我团队的关注和同意。这种方法使我能够为重构提供支持,然后在引领重构的过程中,看起来就像我要为团队工作一样。
想象一下相同的场景,相同的重构,但是我没有独自社交解决方案,而是独自一人去执行重构并进行推送。我的团队不了解重构所解决的痛苦,因此他们所看到的只是学习新的做事方式的痛苦。在他们看来,我似乎是单方面决定将他们搞砸了-与团队成员所做的相反。请记住,在两种情况下,我都编写了相同的代码。唯一的区别是我如何介绍它。
我们如何知道正确的代码更改是什么?这很棘手,但其中一项指导原则对我有很大帮助:
迈克尔·费瑟斯(Michael Feathers)在有关无边缘编程的各种讨论中对此进行了大量讨论(这里对其中一些原理进行了更详细的介绍)。但出于示例目的,这里有一些简单的解决方案,它们使我特别感到骄傲的是复杂的问题:
我通过删除某些有时被伪装,有时不可靠的删除按钮解决了一个棘手的问题(如果您需要更多详细信息,请点击此处是PR)
我解决了React-Native中节拍器延迟的问题,该问题中计算量大的操作可能导致计划任务的延迟。该应用碰巧还需要以原始速度的各种倍数播放曲目。因此,我以120 BPM的速度录制了节拍器的声音文件,通过将音乐家请求的BPM除以120来计算播放该速度的速度,并编写了一种方法,将其封装到expo-av上以播放准确的节奏声音文件。节拍器和回音。
我解决了一个问题,即通过意识到一个问题是假的来调节一个人应该多久记录一次情绪(假设阻止“让我们确保他们至少经常记录一次”),并让他们尽可能多地记录他们的情绪(详情请点击这里。
这些解决方案均使代码更整洁,并消除了产品的多个问题。但是它们不是天才的解决方案。实际上,正是由于复杂的问题并没有尖叫“我有一个脑袋解决方案”,他们才容易被错过。
缺点之一:科技行业通常会因采用优雅的解决方案而浪费大量代码而获得奖励。陈琳最近在推特上发布了他在优步的经历。 Chen对此评论的回应是,该评论起初有些咸,但随后却明确阐明了技术行业如何运作的一个要素:为了获得风险投资,技术主管必须使他们的工作显得创新。因此,他们被迫通过申请专利或跳上最新趋势来人为地“使其具有创新性”。就Uber和iOS开发而言,当务之急是烧毁了它们。
学术界是相似的:《机器学习精炼》的作者杰里米·瓦特(Jeremy Watt)博士阐明了学者们如何使其作品显得新颖才能被发表,为了保持工作而必须被发表,因此他们被迫人为地区分类似的概念-而不是简单地进行卷积。
梅卡·奥克雷克(Mekka Okereke)有一个很好的解释,说明如何抵消一些工程师的责任。它与我们的“首先建立动力”方法有很多共同之处,即从问题开始,而不是解决方案。
我的一位移动软件开发专业的学生问我,在测试正在开发的Python应用程序时应该考虑使用哪些框架。我是这样说的:
在Python中,有两个主要选项:unittest和pytest。两者都工作正常。在团队中工作时,我倾向于使用pytest,因为输出更好。但是...当我教Python时,我根本不使用测试框架。我编写了调用正在测试的方法的方法,然后使用Python的内置assert关键字来检查修改后的对象的状态或返回值。原因是,在学生理解我们为什么测试之前,我不想跳入可以用来测试的所有不同内容的复杂性。我尝试使用可以理解这一点的最小工具集。
我认为,教育方法要解决的一大问题是引入先决条件,使所讨论的主题更难而不是更容易。 Fluent Forever创始人Gabriel Wyner阐明了语言学习通常如何依赖翻译-这是一项整体,独立且困难的技能。因此,当我尝试帮助某人建立直觉时,我将尝试消除尽可能多的依赖关系。
我将向您展示一个使用Python进行测试教学的示例。我从与《紧急工作与司法通过法》的学员分享的笔记本中取出了此示例。她正在编写Sudoku求解器。当然,要解决数独问题,它有助于知道何时解决数独问题。
假设我们从一个类似但更简单的难题开始;每行和每一列必须每个数字都拥有一个副本,如下所示:
拼图= [[1,2,3,4],[2,1,4,3],[3,4,1,2],[4,3,2,1],]
它显示了一种表示问题空间的方式-列表列表。我们可以为此创建一个Puzzle类,其中包含各种方法。我还没有这样做。我正在做的事情很简单,可以说明要点:我们需要一种表示数据的方法。这是一种以最小的依赖性和间接性表示数据的方法。
我们将为测试做同样的事情,不涉及测试框架(还!):
def valid_puzzle(puzzle):尝试:#Python是鸭子类型的,因此在这里我们检查输入是否是我们期望的类型is_a_list = type(puzzle)。__name__ ==" list" assert(is_a_list)#检查拼图是否为正方形number_of_rows = len(puzzle)number_of_columns = len(puzzle [0])assert(number_of_rows == number_of_columns)#宽度和高度相同assert(len(set([len(row))对于拼图中的行]))== 1)#每行的长度都相同#检查用于拼图中行的解决方案的数字:assert(len(set(row))== len(row))#仅以下一项行中的任何给定数字#数字的范围是1到行的大小,但assert(max(row)== len(row))#在4个项目的行中,最大数字是4,以此类推assert(min(row(row) )== 1)#最小的数字始终为1#由于我们检查了行的最大和最小数目,#并且由于我们检查了数据是正方形,所以#我们可以假设列中的最大数目和don&# 39; t不必检查。 #检查索引列中是否只有给定数字之一,枚举(拼图)中的项:column = []拼图中的行:column.append(row [index])assert(len(set (column))== len(column))返回"此解决方案有效!"除外:对不起!这不是有效的难题解决方案。"
我们不在乎什么?我们不想断言这个谜题是9×9(实际上,如果我们断言这一难题,那么当前的表示方法太简单了,难以通过)。因此,我们可以使检查器适用于任何大小的谜题:
Greater_puzzle = [[1、2、3、4、5、6、7],[1、2、3、4、5、6、7],[1、2、3、4、5、6、7] ,[1、2、3、4、5、6、7],[1、2、3、4、5、6、7],[1、2、3、4、5、6、7],[ 1、2、3、4、5、6、7],] valid_puzzle(bigger_puzzle)>抱歉!这不是有效的拼图解决方案。
ninex9_puzzle = [[3,1,6,5,7,8,4,9,2],[5,2,9,1,3,4,7,6,6,8],[4,8,7, 6,2,9,9,5,3,1],[2,6,3,4,1,5,9,8,8,7],[9,7,4,8,6,3,1,2, 5],[8、5、1、7、9、2、6、4、3],[1、3、8、9、4、7、2、5、6],[6、9、2 3、5、1、8、7、4],[7、4、5、2、8、6、3、1、9]] valid_puzzle(ninex9_puzzle)此解决方案有效!
因此,我们有一个解决方案。现在,让我们谈谈我们解决方案的问题。有什么不好的呢?
好吧,如果解决方案无效,则错误消息不会告诉您哪个断言失败或原因。
定义assert_solved方法后,必须在某处显式调用它才能使其运行。
这是我介绍测试框架的思想的地方。 Pytest和unittest都包含以下功能:
解释一下,如果测试失败,那么测试要寻找什么,取而代之的是
为了自动运行测试类中的所有方法,我们可以使用Python的一种数据模型方法获取方法和属性的列表,使用另一种数据模型方法过滤掉属性,然后调用每个方法。这是一篇博文,几乎演示了该操作。可是等等!我们不想调用类中的每个方法,因为它会包含所有特殊方法!我们如何解决呢?嗯,一种实现方法是在每个方法签名的开头都放置相同的前缀,并对其进行过滤。现在,学生了解了为什么测试框架可能需要以“ test!”开头的测试方法名称。
为了使异常冒泡,我们必须专门捕获其中的AssertionErrors,但要在那里阻止。然后,我们可以用第二个除外块来处理任何其他错误,或者我们可以重新抛出所有其他错误。
为了提供更清晰的输出,我们需要在如何存储传递到断言中的变量方面发挥创意,以便可以将它们找回并打印在AssertionError捕获中。
这是我可以介绍测试库的地方。因为我们花了一些时间来了解这些库的工作原理,所以它们不再听起来像魔术。学生了解他们的工作方式,因为他们实施了一个简单的方法,然后至少讨论了一个真正的人如何工作。 PyTest不再是某种神秘的天才盒子。我发现这种方法不仅可以转移知识,还可以帮助新Python开发人员树立信心和技能。
无论我作为一名开发人员拥有什么乘数,我都认为我从做这三件事中得到了收益。
我通过与他人互动来激发他们的动力,从而出售自己的解决方案。我试图找到解决棘手问题的解决方案。当我帮助他人建立直觉时,我会尝试消除进入障碍。