俗话说,如果您不对旧代码感到羞耻,那么您就不会成长为一名程序员-我同意这一观点。 我40多年前开始从事娱乐节目编程,而30年前开始从事娱乐行业编程工作,所以我犯
了很多错误。 作为计算机科学教授,我教我的学生如何从错误中学习-他们的错误,我的错误以及陌生人。 我认为是时候谈论我的错误了,以免失去谦虚。 我希望有人会觉得有用。
第三名-Microsoft C编译器
我学校的老师认为,“罗密欧与朱丽叶”不应该被视为悲剧,因为英雄们没有悲惨的内--他们只是表现得像青少年一样愚蠢。 然后我不同意他的观点,但现在我认为他认为是一个合理的内核,尤其是在编程方面。
当我在麻省理工学院读完第二年的时候,我在生活和编程方面都还很年轻,没有经验。 夏季,我在Microsoft的C编译器团队中进行了实践,最初是从事例程的工作,例如提供概要分析支持,然后我被委托负责编译器中最有趣的部分(我认为)-后端优化。 特别是,我必须改进分支语句的x86代码。
决心为每种可能的情况编写最佳的机器代码,我急忙冲入游泳池。 如果值分布的密度很高,则将它们输入
转换表中 。 如果他们有一个共同的除数,我就用它使表更密集(但前提是可以使用
位移来完成除法)。 当所有值均为2的幂时,我执行了另一个优化。 如果值的集合不满足我的条件,我将其分为几个可优化的情况,并使用已经优化的代码。
那是一场噩梦。 多年后,他们告诉我继承我代码的程序员讨厌我。
经验教训
正如David Patterson和John Hennessy在《计算机体系结构和计算机系统设计》一书中所写的那样,体系结构和开发的主要原理之一是,总体而言,一切都应尽可能快地运行。
加速常见案例将比优化罕见案例更有效地提高生产力。 具有讽刺意味的是,普通情况通常比罕见情况简单。 这种合理的建议意味着您知道哪种情况是常见的-只有通过仔细的测试和测量,才有可能。
为了辩护,我可以说我试图弄清楚分支运算符的实际情况(例如,存在多少个分支以及常量的分布方式),但是在1988年,此信息不可用。 但是,当当前的编译器无法为我想到的人工示例生成最佳代码时,我不应该添加特殊情况。
我需要打电话给有经验的开发人员,并与他一起思考什么是常见案例,并专门处理它们。 我会写更少的代码,但这甚至很好。 正如Stack Overflow创始人Jeff Atwood所写,程序员最大的敌人是程序员:
我知道,正如我们所有人一样,你们有最好的意图。 我们创建程序,喜欢编写代码。 这样我们就安排好了。 我们认为,使用磁带,自制拐杖和少量代码可以解决任何问题。 不管编码人员承认这一点有多痛苦,最好的代码是不存在的代码。 每条新生产线都需要调试和支持,需要理解。 在添加新代码时,您应该轻而易举地去做,因为所有其他选项都已用尽。 许多程序员编写了太多的代码,这使其成为我们的敌人。
如果我编写了涵盖普通情况的简单代码,那么在必要时进行更新将容易得多。 我留下了一个没人想惹的烂摊子。
第二名:社交媒体广告
当我在Google从事社交媒体广告工作(还记得Myspace吗?)时,我用C ++编写了如下内容:
for (int i = 0; i < user->interests->length(); i++) { for (int j = 0; j < user->interests(i)->keywords.length(); j++) { keywords->add(user->interests(i)->keywords(i)) { } }
程序员可能会立即看到错误:最后一个参数应该是j,而不是i。 单元测试没有发现错误,我的审阅者也没有注意到它。 进行了启动,有一天晚上,我的代码进入了服务器,并使数据中心中的所有计算机崩溃。
没什么可怕的事。 它们都没有中断,因为在全球发布之前,代码已在同一数据中心内进行了测试。 除非SRE工程师短时间退出打台球并进行少量回滚。 第二天早上,我收到了一封带有故障转储的电子邮件,修复了代码,并添加了可能显示错误的单元测试。 由于我遵循了协议-否则我的代码将无法运行-没有其他问题。
经验教训
许多人确信这样的重大错误一定是被解雇的罪魁祸首,但事实并非如此:首先,所有程序员都是错误的,其次,他们很少犯两次错误。
实际上,我有一个熟悉的程序员-一位出色的工程师,他因一个错误而被解雇。 在那之后,他被Google聘用(并很快晋升)-他诚实地谈到了面试中的错误,她并不被认为是致命的。
以下是IBM传奇负责人Thomas Watson所说的话:
宣布了一项价值约一百万美元的政府订单。 IBM Corporation-或更确切地说,个人是Thomas Watson Sr.-确实想要得到它。 不幸的是,销售代表无法做到这一点,IBM失败了。 第二天,这名官员来到沃森先生的办公室,在他的办公桌上放了一个信封。 沃森先生甚至没有调查他-他正在等待一名雇员,并且知道这是一封辞职信。
沃森问出了什么问题。
销售代表详细描述了招标的进度。 他称可以避免的错误。 最后,他说:“沃森先生,谢谢您让我解释一下。 我知道我们需要多少订单。 我知道他有多重要,”并且即将离开。
沃森在门口走向他,看着他的眼睛,然后把信封放回去,上面写着:“我怎么让你走? 我刚刚在你的教育上投入了一百万美元。
我有一件T恤,上面写着:“如果您真的从错误中学到的东西,那么我已经是高手了。” 实际上,就错误而言,我是科学博士。
第一名:App Inventor API
真正可怕的错误会影响大量用户,会成为公众,长期存在并由不允许他们的人做出来。 我最大的错误是满足所有这些条件。
越差越好
我在90年代读研究生时就读过
理查德·加布里埃尔 (
Richard Gabriel )关于这种方法的
文章 ,我非常喜欢它,因此我向学生们提出了要求。 如果您记不太清,请刷新一下内存,内存会很小。 在本文中,“做到正确”的愿望和“越糟越好”的方法在许多方面都形成了对比,包括简单性。
应当:设计应该易于实现和接口。 接口的简单性比实现的简单性更为重要。
越差越好:设计应该在实现和接口上简单。 实现的简单性比接口的简单性更为重要。
暂时忘记它。 不幸的是,我忘记了很多年。
应用发明者
在Google工作期间,我是
App Inventor团队的一员,该团队是一个在线开发环境,为初学者Android开发人员提供拖放支持。 那是2009年,我们急于及时发布alpha版本,以便在夏天我们可以为秋季可以使用学习环境的老师举办大师班。 我自愿实现精灵,怀念我以前在TI-99 / 4上编写游戏的方式。 对于那些不了解的人:子画面是可以移动并与其他程序元素进行交互的二维图形对象。 精灵的例子有飞船,小行星,小球和球拍。
我们用Java实现了面向对象的App Inventor,因此只有一堆对象。 由于球和小精灵的行为非常相似,因此我创建了一个抽象的小精灵类,它具有属性(字段)X,Y,速度(速度)和航向(方向)。 他们使用相同的方法来检测碰撞,弹跳到屏幕边框等。
球和子图形之间的主要区别在于所绘制的内容-实心圆或栅格。 自从我第一次实现精灵以来,指定图像所在位置的左上角的x和y坐标是合乎逻辑的。
当精灵开始工作时,我决定可以用很少的代码实现球形对象。 唯一的问题是,我采用了最简单的方法(从实现者的角度出发),指出了围绕球的轮廓的左上角的x和y坐标。
实际上,正如任何数学教科书和其他提及圆的资料所教导的那样,有必要指出圆心的x和y坐标。
与我过去的错误不同,不仅是我的同事,还有数百万的App Inventor用户都遭受了这一痛苦。 他们中的许多人还是孩子,或者是编程新手。 在处理存在球的每个应用程序时,他们必须执行许多不必要的动作。 如果其余的错误我都笑着记得,那么今天这会让我大汗淋漓。
我终于在十年后的最近一次修补此错误。 “已修补”而不是“固定”,因为正如Joshua Bloch所说,API是永恒的。 无法进行会影响现有程序的更改,我们添加了OriginAtCenter属性,在旧程序中为false,在以后的所有程序中为true。 用户可以向任何人提出一个合法问题,以找到参考点而不是中心。 给谁 十年前一位懒于创建普通API的程序员。
经验教训
在使用API时(几乎每个程序员有时都要做),您应该遵循Joshua Bloch的视频“
如何创建一个好的API以及为什么它如此重要 ”
中概述的最佳技巧:
- 该API可以给您带来极大的好处,也可能带来极大的伤害 。 好的API可以创建忠实的客户。 坏变成了你永恒的噩梦。
- 像钻石一样的公共API是永恒的 。 尽力而为:没有其他机会尽其所能。
- API的时间表应该简短 -一页包含类和方法的签名以及描述,一行不要超过一行。 如果第一次出现这种情况并不理想,则可以轻松重组API。
- 在实现API甚至制定其规范之前,请描述使用场景 。 这样,您就可以避免完全不起作用的API的实现和规范。
如果我至少写了一个带有人工脚本的小提要,很可能我会发现一个错误并予以纠正。 如果没有,那么我的一位同事肯定会这样做。 任何具有深远影响的决定都必须至少考虑一天(这不仅适用于编程)。
理查德·加布里埃尔(Richard Gabriel)的文章的标题为“更糟,更好”,表明了市场上首先出现的优势-即使产品不完美-而其他人一直在追求理想的时代。 考虑到Sprite代码,我知道我什至不必编写更多代码即可完成所有应做的事情。 不管喜欢与否,我犯了个严重错误。
结论
程序员每天都会犯错误-无论是编写带有错误的代码,还是不想尝试会提高他们的技能和生产力的东西。 当然,您可以成为一名程序员,并且不允许出现像我这样的严重错误。 但是要成为一个优秀的程序员而又不意识到自己的错误并且不从错误中学习是不可能的。
我经常遇到那些认为自己犯了太多错误,因此不适合编程的学生。 我知道冒名顶替综合症在IT中是多么普遍。 我希望您能学习我列出的课程-但要记住主要内容:我们每个人都会犯错-可耻,有趣,可怕。 如果将来我没有足够的资料继续撰写本文,我会感到惊讶和沮丧。