编程中有什么真的是邪恶的吗?[关闭]


41

因此,出现了很多问题,询问是X邪恶,是Y邪恶。

我的观点是,没有语言构造,算法或任何有害的东西,只有那些被滥用的语言。天哪,如果您看上去很努力,甚至还有goto的有效用法

那么,在编程中是否存在绝对邪恶的东西,那在所有情况下都与最佳实践完全不兼容?如果是这样,那是什么?还是只是不好的程序员不知道什么时候合适?

编辑:明确地说,我不是在谈论程序员的工作(例如不检查返回码或不使用版本控制-它们是不良程序员做出的选择),我的意思是工具,语言,语句,无论是什么,坏...


21
空是邪恶的!十亿美元的错误 程序员
.stackexchange.com / questions / 22912 /…

22
@Amir Resaei,如果您在插入reecord时不知道该值,则必须为null!反复使用空值的方法要差得多。
HLGEM 2010年

4
@HLGEM:您能否分享Haskell的“也许”之类的替代方案“差得多”?
LennyProgrammers 2010年

24
每天200代表上限确实是邪恶的。

4
@HLGEM:这对于当前的SQL数据库可能是正确的,我以为我们在谈论编程语言。
LennyProgrammers 2010年

Answers:


46
  1. 魔术数字。
  2. 隐性本质上是邪恶的,这就是原因:

8
1.有理由拥有它们。2. Haskell中的类型推断是我喜欢的一种隐式类型。
马特·艾伦

1
+1表示魔术数字,这是我在一家非常大的公司生活的祸根。同样,“迷失在过去”的原因是将比例缩放为1000而不是1024,从而导致严重循环中的巨大开销,每个人都不敢消除,因为他们不知道还会受到什么影响。
geekbrit 2010年

7
嗯,隐含性有时非常整洁。明确性是针对汇编程序员的。
Macke 2010年

6
关于#2:我看得出您在那儿做了什么...对不起我猜不到的人的不满。
拉里·科尔曼

5
@拉里,我开玩笑。我只是不同意。
JSBձոգչ2010年

77

编程中没有真正的邪恶。

<rant>

许多人认为有邪恶的事情的原因是,当他们第一次上编程课时,它就被捣碎了。“不要使用goto!始终规范化数据库!永远不要使用多重继承!” 之所以采取这些措施,是因为这些“邪恶”的做法很容易被滥用,而不是因为它们本身就很糟糕。它们的用途很少,您一开始只能说“从不”。真正邪恶的是在说:“没有理由考虑不是“最佳实践”的任何东西”,因为有一个地方是完美的。

</ rant>


10
+1-最佳做法是概括,对于所有概括,都会有例外。
乔恩·霍普金斯

1
++我赞成你。太棒了!
Mike Dunlavey 2010年

3
+1:前一段时间,我在正在处理的C代码中添加了一个新的goto,因为其中已经有很多代码。它比重构快。我告诉我的妻子,他也是一名程序员,她问:“亲爱的,你还好吗?你发烧了吗?” 我目前正在编写一些代码,其中另一个人编写了一个跳转到循环中间的C goto。我永远不会自己写它,每次看到它都会向内咒骂,但它达到了最终的考验:它有效。
Bob Murphy

1
+1-我在校外从事一些C代码的研究,这些代码经常使用“ goto exit”或“ goto error_exit”。我不得不说,它使代码看起来更简洁,而不是具有多个return语句。我的座右铭是,一切都有它的位置。(甚至单身人士;
eSniff 2010年

1
@JonHopkins-这就是为什么我更喜欢谈论“良好做法”的原因。
理查德

58

枪不杀人,人杀人。

以同样的方式,开发工具不是邪恶的,程序员可以使用它们。


1
这是一个很好的类比。
Maxim Zaslavsky 2010年

14
枪不杀人。子弹做。:)

4
枪支在帮助人们杀人方面大有帮助。更糟糕的是,我不明白您要提出的观点:谁曾声称开发工具是邪恶的?这个答案肯定有一些聪明之处,因为它获得了很多赞成票。但是我完全看不到它。
康拉德·鲁道夫

1
@fennec子弹不会杀死人,人们会杀死人。除非机器最终变得有感觉,否则我将进入掩体。
antony.trupe

5
枪不杀人,说唱歌手杀人。
乔恩·霍普金斯

36

编程中有什么真的是邪恶的吗?

绝对。不能动动脑子去想想自己在做什么,为什么要这么做,这是所有编程弊端的根源。


2
+1。但是s /考虑/理解/的含义,这会更好。
理查德

根据爱因斯坦的说法,人类的愚蠢不是有限的。
尼尔斯2010年

25

空的通用异常处理程序,即:

catch(Exception ex)
{
}

我毫不怀疑有人可以给我一个有效的用例-但是,老实说,它会非常有创意……至少您需要一个解释。


1
+1如果其他人没有,我要添加此内容
康拉德·弗里克斯

1
真?“我不在乎是否失败”永远不会有效,在任何可能的情况下都不会生效吗?并非一定要保证每件事都成功或失败,尤其是在小型一次性实用工具中。不首先考虑的另一种情况是真正的邪恶。
SilverbackNet 2010年

4
我在旧版代码All中看到了这一点。的。时间。更糟糕的是,当我更改它时,人们会问我。
乔治·斯托克

5
我首先在其中添加了一封电子邮件通知,该通知向我发送“空捕获块命中”类型异常,然后将其释放到产品中,以便我可以看到为什么捕获实际上存在,以及在什么条件下捕获。然后我修复它。
CaffGeek

2
我会为Java中的检查异常投票:N
Nils,2010年

19

也许我可以左右翻转的问题,并询问是否有在节目是什么绝对完全好?如果您无法想到一件事情(我知道我无法做到),那么邪恶的概念也一样混乱。

常见的行为会导致错误,误解和其他普遍的混乱-但是说语言功能X本质上是邪恶的,那就是要承认您真的不了解功能X的目的。

有一些常见的行为可以节省很多心痛并避免一些误解-但是说语言功能Y本质上不错就是承认您不完全了解使用功能Y的所有含义。

我们是一个了解有限,见解深刻的人,这是危险的组合。夸张只是表达我们的观点,夸大事实直到成为虚构的一种方式。

但是,如果我能避免导致问题的行为并追求避免问题的行为,我可能会更有生产力。归根结底,这就是全部。


3
编程中的任何东西绝对完美吗?清晰明确的文档?
詹姆斯

4
@James清晰,写得很好的文档通常被用作无法阅读的代码的借口,并且如果代码过多,可能会成为束缚,需要与代码一起维护。清晰,写得好却完全过时的文档也可能变成纯粹的邪恶。
尤金·横田

工作代码!!!
Scott Whitlock 2010年

解释原因的评论。那很好。
Tim Williscroft 2010年

询问几个不同的开发人员,相同的代码是好是坏,您将得到不同的答案。要说那绝对是件好事,那会有些不准确。
Berin Loritsch 2010年


11

我认为剥皮,永久位于系统托盘中的自动更新程序,劫持文件关联和其他系统设置的应用程序都是邪恶的。

以及仅限Flash的网站。


10
因此,您是在告诉我Adobe是邪恶的?
大卫·默多克

10
@David:什么,你还不知道吗?
梅森惠勒

8
我会说,文件关联劫持的最严重原因是QuickTime。
2010年

一秒钟我以为你在谈论RealPlayer。(VLC的新用户!)
Mateen Ulhaq 2011年

2
我得出的结论是,Adobe和Apple所做的几乎所有事情都是邪恶的。
Brian Knoblauch

10

偶然发生的所有工作本质上都是邪恶的。

让我们考虑以下使用默认编译器选项的C程序,它恰好在我的机器上实际工作:

#include <stdio.h>
int main(int argc, char *argv[]) {
   char string[10];
   int y;
   for (y=0; y<10; string[12]++) {
      printf("%d\n", y);   
   }
}

没什么,这个程序增加循环计数器的方式真的没有任何借口。这只是未定义的效果,恰好在我的机器,编译器和默认选项上做正确的事情。


真好 很好的例子-花了我几秒钟来解决!凉。
Michael K 2010年

5
我认为这本质上是错误的,而不是本质上是邪恶的
劳伦斯·多尔

修复了格式字符串中的错字
user281377 2010年

3
梅尔会为此感到自豪。
巴里·布朗

我认为这很酷,几乎与在汇编器调用中使用结构覆盖数据结构的方式相同。在这里显然不是故意的,但随后您将其用作示例。权力会被破坏,直到威武者才能正确使用它。注意 那将是一个很好的面试问题。
2010年

10
那么,在编程中是否存在绝对邪恶的东西,那在所有情况下都与最佳实践完全不兼容?如果是这样,那是什么?

是; 标准C库函数gets()。C标准委员会正式弃用它是非常邪恶的,并且有望在下一版标准中消失。由一次库调用引起的混乱比破坏30年以上的旧代码的前景更可怕- 这就是多么邪恶。


对于那些不讲C的人来说,为什么它是如此邪恶呢?
乔恩·霍普金斯

8
gets()接受一个参数,即缓冲区的地址。从标准输入读取字符到缓冲区,直到看到换行符为止。因为它接收的只是缓冲区的地址,所以gets()不知道缓冲区有多大。如果将缓冲区的大小设置为10个字符,并且输入流包含100个字符,则多余的90个字符将立即在缓冲区之后写入内存,这有可能破坏堆栈。因此,它是受欢迎的恶意软件利用。它在设计上是不安全和不安全
约翰·波德


7

那么,在编程中是否存在绝对邪恶的东西,那在所有情况下都与最佳实践完全不兼容?

当然不是。这就像问我工具箱中的任何东西是否有害。除非我四岁,否则我的锤子对我来说是一个巨大的“好”。


我认为,当一个老人充分利用自己的能力来破坏好东西时,情况甚至更糟。
guiman 2010年


6

不要太认真,但是...

我们对“邪恶”有非常近视的看法。杀死很多其他人的人是邪恶的。从别人那里偷东西的人是邪恶的。每个国家(据我所知)过去都有一些邪恶。有些人想否认。

编程中有邪恶吗?我们无辜的程序员可能会想“不是真的”。但是,一旦我与一个广泛使用的分层数据库的发明者进行了交谈,就涉及到这个主题。是否想知道谁是最好的客户之一?共产主义波兰的秘密警察。

现在世界上有邪恶吗?你打赌 他们在使用程序员吗?你打赌


2
可能是邪恶的邪恶变种,超出了我的想象。与秘密警察相比,我们实际上只是在调皮。
乔恩·霍普金斯

@Jon:...而且在这个季节,每个人都知道“调皮的”和“很好的” :)
Mike Dunlavey 2010年

种族灭绝总是真正的邪恶,我对盗窃有不同的看法。窃取,虽然不是伤害他人的意图,但改善自己的结果。如果窃贼可以轻松地改善其结果而不会伤害他们从他们那里窃取的窃贼,那他们可能会。我认为这是不道德的,但不是真正的邪恶。
JD Isaacks 2010年

@约翰:罗宾汉?我明白你的意思。我认为,事实上,帕累托效率就是关于这一点的。这与当今的流行理论相反。天哪,我希望这不会引发一场火焰大战……
Mike Dunlavey 2010年

@John Isaacks-所以,你说的是一个小偷,他从一个普通的程序员那里偷了一辆车,一个小时内赚了6,000美元,而程序员通常说,两个月赚6,000美元,只是在“纠正失衡”?还是某些人喜欢小偷,只是认为自己比别人强,所以他们不必努力工作?
Jas 2010年

6

空是邪恶的根源!

https://softwareengineering.stackexchange.com/questions/22912/null-references-the-billion-dollar-mistake-closed

十亿美元的错误:我称之为我的十亿美元错误。这是在1965年发明空引用的。那时,我正在设计第一个全面的类型系统,用于面向对象语言(ALGOL W)的引用。我的目标是确保所有对引用的使用都绝对安全,并由编译器自动执行检查。但是我无法抗拒引入空引用的诱惑,仅仅是因为它是如此容易实现。这导致了无数的错误,漏洞和系统崩溃,在最近四十年中可能造成十亿美元的痛苦和破坏。近年来,许多程序分析器(例如Microsoft中的PREfix和PREfast)已用于检查引用,并在有可能不为空的风险时发出警告。诸如Spec#之类的最新编程语言引入了非空引用的声明。这是我在1965年拒绝的解决方案。CAR Hoare,2009年


阿米尔(Amir),显然很多人不明白这一点(如问题下方的HLGEM评论以及您所获得的低票数所证明)。由于可空引用在我们的思维中是如此根深蒂固,因此可能很难意识到它们并不是很自然。因此,也许您应该解释替代方案的工作方式,或者至少链接到可行的文章。–如果人们理解您的答案,我可以肯定这将是这里排名最高的答案之一,因为您的观点是100%有效的。
康拉德·鲁道夫

@Konrad Rudolph在我发送的“空引用,十亿美元的错误”下有关于此的答案。有些语言已删除了对Null的支持。
阿米尔·雷扎伊

+1可悲的事实是,大多数程序员对替代方案一无所知。我不反对存在空引用,只是反对它表示某种含义。它只是一个指向无效内存位置的指针-仅此而已。大多数程序员将其视为在域中具有某些含义(例如,不需要中间名字段,因此它可以为null)。在我的程序中,null除了语言规范中指定的内容之外,没有其他含义。对我来说,空引用始终是一个错误。如果字段是可选的,则使用适当的选项类型。
MattDavey

@AmirRezaei:在引用有用之前,应该如何处理已存在的引用?我建议,最好使此类引用指向显然不能取消引用的对象,而不是要求它们指向可以合法取消引用但无用的对象。尽管有时以某种方式声明引用很有用,这种引用要求在任何东西都可以看到它们之前先对其进行初始化,但始终必须如此,否则会造成鸡与蛋的问题。
2012年

6

复制粘贴代码。

如果您这样做时不发痒,那么您不是一个真正的程序员。


2
隐含在答案中:所有真正的程序员无论如何都制作了copypasta,所以他们知道它的感觉……
comestorm 2012年

5

我个人发现Donald Knuth的一句话:“过早的优化是万恶之源”,这是编程中的第一件事。从经验的角度来看(这表示我为此失败了)。

实际上,该短语的含义如下:在深入了解问题之前,请勿尝试在特定的环境,特定的PC或一组用户中了解问题。


4

令我惊讶的是,没有人将Globals视为真正的邪恶。在一个您不了解参数并且几乎无法控制它们发生的情况的环境中,没有更好的编程方法。混沌!我在所有编码中都严格禁止使用全局变量。


+1000如果可以的话,我会对此投票更高。当今编程中最大的问题。而且,无数的文章,对话和努力都在教育人们有关该问题的知识,我认为它永远不会改变。每个人都从初学者开始使用它们,很少看到它们的问题。我进入专业设置的几乎每个项目都会遭受过度使用的全局变量的困扰(主要是减去基于Spring的项目)。虽然在Spring项目中找到BlahBlahManager.getInstance()时一定会喜欢它。买了书,还是没得到。
chubbsondubs

6
找到我一个没有全局变量的简单应用程序。哦,它们被包裹,整理和保护了,并且在一个类和一个框架中,并且总体上更好。问题出在使用范围不当的变量。
Murph 2010年

2
全局变量不应该享有如此糟糕的声誉。就像@Murph所说的那样,有些事情是全球性的。文件系统是全局的(所有进程使用相同的文件);您的过程对于所有线程都是全局的;内存是全局的(另一个过程可能会耗尽您的内存并使您在安全使用内存降落伞时崩溃);该用户本人是全球性的(想想UI设计方面)。将固有的全局变量建模为全局变量(或Singleton,Service Locator或Registry)是没有错的。
kizzx2 2010年

3

没有工具天生就是邪恶的。除了一个用例之外,对于其他所有用户来说,它的存在可能完全是愚蠢的,但这并没有使它变得邪恶。它决定了程序员的正确使用方法。



3

我知道我说我不会发帖,但我会写一个答案。正如所有人都说不,没有邪恶,我会说是,绝对有邪恶

Setjmp / LongJmp是纯粹的邪恶。


1
+1我尚未看到Setjmp / LongJmp的正确用例。
奥利弗·韦勒

@Helper方法:哈哈,谢谢。我很高兴有人同意我的看法

4
try / finally / catch + throw通过Setjmp + LongJmp实现。
2010年

3
SetJmp + LongJmp可用于使用不带PTC的语言/编译器通过尾部调用来实现CPS(连续传递样式),而无需PTC(适当的尾部调用)。它是蹦床的优化版本。请
参见

1
比setjmp / longjmp更邪恶的是使用setjmp / longjmp来实现一个穷人的超轻量级线程库(正如我在DOS时代所看到的那样)。令人愉快的邪恶代码!:-)
Brian Knoblauch 2012年



2

尽管任何工具都可以用于善恶,但有些工具却是邪恶的,因为它们经常使不经常使用它们的程序员感到惊讶。

当处理小于32位的整数时,我认为Java中的无符号右移运算符(>>>)是邪恶的(令人惊讶地是不合适的)。

假设您有一个值为-1的字节b。

byte b = -1;  // binary: 1111 1111

无符号右移运算符将零移位到最左边的位。因此,假设移位7以得出1。

b >>>= 7;  // binary: 0000 0001 ?

但是,此操作完全不执行任何操作。b仍为-1。

甚至以下25个班次都无济于事:

byte b = -1;
for (int i = 0; i < 25; ++i) {
    b >>>= i;
    System.out.println(b); // always outputs -1
}

发生这种情况是因为b>>>=7大致翻译为

                                  1111 1111

1) the byte gets widened to a 32 bit int to make shifting possible
    1111 1111 1111 1111 1111 1111 1111 1111

2) the shift happens
    0000 0001 1111 1111 1111 1111 1111 1111

3) the resulting int gets narrowed to a byte again
                                  1111 1111

您将不得不更换

b >>>= i;

通过

b = (b & 0xFF) >>> (i % 8);     // >> would also work this time

使它像预期的那样工作。


1
我不懂Java,但为什么这很邪恶?您是说应该只在int上使用,而byte int不是int吗?我发现>>> a但很奇怪,因为我知道它是D的无符号右移,这不应导致-1。

@ acidzombie24绝对正确。>>>是无符号移位,>>是有符号移位。但是,当移位一个字节时,它首先被扩展为一个int(用符号填充),然后再移位。因此,即使“无符号”移位也将其符号扩展。实际上,结果是一个正整数,但是将其存储到一个字节后,它又是负数。
罗伯特2010年

哇,这真是邪恶。或者至少很可能给您带来意想不到的结果。我只是在想它不能将移位应用于一个字节吗?如果不将其转换为int并返回,则...不是很好。

@ acidzombie24没有用于执行字节操作的机器代码(加载/存储除外)。在JVM级别,32位是最小单位。因此,所有工作都必须由编译器或程序员来完成。编译器不会改变。我已将所需的调整添加到我的帖子中。
罗伯特2010年

2

我要扭转这个局面,并说,尽管没有绝对的邪恶,有一些工具和结构,这使得它更合理的对我们人类的软弱与这样一个有限的头骨大小犯错误比其他人。

因此,我想您可以根据人们犯错的可能性来谈论结构的弊端。当然,您可以用刀或带锯条的链锯来切面包,但是即使您能够小心翼翼地将其拉下来,一种面包也可能造成损坏。


2

用您的母语(不是英语)编写代码,用您的母语编写文档。然后将该项目外包给一家印度公司。

对你来说这是邪恶的!

PS:从记录来看,这确实发生了,印第安人并不觉得这很有趣。


1
也许他们应该以一种了解他们的方式开展业务……在进行该项目之前……
Merlyn Morgan-Graham 2010年

他们甚至怎么期望呢?您认为在全球范围内拥有非英语代码/文档是否很好?
2011年

1

我很想说延续,但是我认为正确的答案是编程中没有客观的,绝对的邪恶。另一方面,即使是最好的工具也可能被滥用。


没有多少人了解延续性,没有多少人有机会广泛使用延续性。您遇到了什么情况,使您确信自己是邪恶的?延续性真正改变游戏的一种情况是异步编程,尤其是在UI编程中,在这种情况下,您必须不断增加事件,以使UI不会冻结。异步编程会引起各种麻烦,因为重用在同步样式开发中确实非常有效。延续可以用于恢复同步样式,但可以防止冻结UI。太棒了
chubbsondubs

1
我不认为延续是邪恶的,但我认为社区中可能会有很多人,因为使用它们编写的任何代码都将自动“变得聪明”。
拉里·科尔曼

1

我认为编程本身并不是天生的邪恶。但是,编程通常是一种社交活动,不尊重周围的人可能是非常邪恶的。人们常常忘记大多数代码将与他人共享。大多阅读,有时也写。无论是开源的,公司正在发布的产品,还是聘请了一小部分顾问的公司,都将阅读程序。

这就是为什么存在这么多“被认为有害”的文章或人们说“从不”的一半的原因。使别人难以生活是所有邪恶的根源。是不是


1

是的,这里有很多邪恶的地方。例如:

Type1 variable1 = function12()
variable5 = variable1.myMethod(variable1+aGlobal);
variable2.otherMethod(anotherGlobal);

1

由于收益不足,增加了系统的总成本。它可能是太多的复制和粘贴,太复杂的体系结构,或使用昂贵但无效的商业产品。一般而言,所有软件技术都旨在降低系统的总成本,如果最终导致系统过于昂贵,那么我们做错了。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.