关于语言不可知论:你最有争议的编程观点是什么?

What's your most controversial programming opinion?

这绝对是主观的,但我想尽量避免它变得有争议。我认为,如果人们能恰当地对待它,这可能是一个有趣的问题。

这个问题的想法来自我对"你最喜欢的语言有五件事你讨厌吗?"的回答的评论线索。问题。我主张C中的课程应该默认密封——我不会把我的推理放在问题中,但我可能会写一个更完整的解释来回答这个问题。我对评论中讨论的热度感到惊讶(目前有25条评论)。

那么,你有什么有争议的意见?我宁愿避免这样的事情,结果是相当宗教,相对较少的基础(如支撑放置),但例子可能包括"单元测试实际上没有太大的帮助"或"公共领域真的很好"。重要的是(对我来说,不管怎样),你的观点背后有理由。

请陈述你的观点和推理——我鼓励人们投票赞成那些有充分理由和有趣的观点,不管你是否同意它们。


不在业余时间编写代码以取乐的程序员永远不会像那些程序员那样优秀。

我认为即使是最聪明和最有才华的人也永远不会成为真正优秀的程序员,除非他们把它当作工作来对待。也就是说,他们一边做一些小项目,或者只是在业余时间处理大量不同的语言和想法。

(注:我不是说优秀的程序员只做编程,但他们只做从9到5的程序)


你应该一直使用的唯一"最佳实践"就是"用你的大脑"。

太多的人跳上太多的乐队,试图把方法、模式、框架等强加于不值得他们去做的事情上。仅仅因为某件事是新的,或者因为某个受人尊敬的人有一个观点,并不意味着它适合所有人。

编辑:只是为了澄清——我认为人们不应该忽视最佳实践、有价值的观点等。只是人们不应该只是盲目地跳上某个东西,而不去想为什么这个"东西"如此伟大,它是否适用于我正在做的事情,它带来了什么好处/缺点?


"谷歌"没关系!

是的,我知道这冒犯了一些人,因为他们多年来的紧张记忆和/或精彩的编程书籍开始从一个任何人都可以在几秒钟内访问的资源的路旁跌落,但你不应该对使用它的人持这种态度。

我经常听到谷歌搜索问题的答案——批评的结果,这真的是毫无意义。首先,必须承认,每个人都需要参考资料。你不知道所有的事情,你需要去查查。尽管如此,你从哪里得到信息真的很重要吗?如果你在书中查到它,在谷歌上查到它,或者从一只会说话的青蛙那里听到你产生幻觉,这有关系吗?不,正确的答案就是正确的答案。

重要的是,你要理解材料,把它作为结束成功编程解决方案的手段,客户/你的雇主对结果很满意。

(尽管如果你从会说梦话的青蛙那里得到答案,你还是应该得到一些帮助)


实际上,代码中的大多数注释都是有害的代码复制形式。

我们大部分时间都在维护他人(或我们自己)编写的代码,而糟糕的、不正确的、过时的、误导性的注释必须位于代码中最令人讨厌的工件列表的顶部。

我想,最终很多人都会把它们抹掉,尤其是那些花坛怪兽。

更好的做法是集中精力使代码可读,必要时进行重构,尽量减少惯用语和怪癖。

另一方面,许多课程告诉我们,注释比代码本身更重要,因此下一行将添加一个到invoicetotal注释样式中。


XML被高估了

我认为在使用他们的大脑之前,有太多人跳上了XML的潮流…XML for Web东西很好,因为它是为它设计的。否则,我认为一些问题定义和设计思想应该优先于使用它的任何决定。

我的5分钱


并非所有的程序员都是平等的

通常,管理者认为developera==developerb仅仅是因为他们具有相同的经验水平等等。实际上,一个开发人员的性能可以是另一个开发人员的10倍甚至100倍。

谈论这件事在政治上是有风险的,但有时我想指出的是,即使几个团队成员看起来技能相同,但情况并非总是如此。我甚至看到过这样的情况:主要开发人员"无望",初级开发人员完成了所有实际工作——不过,我确保他们获得了荣誉。:)


我不明白为什么人们认为Java绝对是大学里最好的"第一"编程语言。

首先,我认为第一种编程语言应该强调学习控制流和变量的需要,而不是对象和语法。

另一方面,我相信那些在C/C++中没有调试内存泄漏经验的人不能完全理解Java带来了什么。

另外,自然的进展应该是从"我怎么能做到这一点"到"我怎么能找到这样做的图书馆",而不是反过来。


如果你只知道一种语言,不管你多么了解它,你都不是一个伟大的程序员。

似乎有一种态度说一旦你真的擅长C语言或Java或者你开始学习的任何其他语言,那就是你所需要的。我不相信——我所学的每一种语言都教会了我一些编程方面的新知识,我已经能够把它们带回到我的工作中去。我认为任何一个限制自己使用一种语言的人永远不会像他们那样优秀。

对我来说,它也表明了我缺乏某种求知欲和尝试的意愿,这并不一定符合我期望在一个真正优秀的程序员身上找到的品质。


性能确实很重要。


print语句是调试代码的有效方法

我认为,通过将代码与System.out.println或任何适用于您的语言的print语句混合使用来调试代码是非常好的。通常,这比调试更快,并且您可以将打印输出与应用程序的其他运行进行比较。

在进入生产阶段时,只需确保删除打印语句(或者更好地,将其转换为日志语句)。


你的工作就是让自己失业。

当你为你的雇主编写软件时,你所创建的任何软件都要以这样一种方式来编写,即任何开发人员都可以用最少的努力来获取和理解它。它设计良好,书写清晰一致,格式清晰,在需要的地方有文档记录,按预期每天构建,检入到存储库中,并进行适当的版本控制。

如果你被公共汽车撞了,被解雇,被解雇,或者辞职,你的雇主应该能够在一瞬间通知你,然后下一个家伙可以进入你的岗位,拿起你的代码,在一周内开始工作。如果他或她不能做到,那你就惨败了。

有趣的是,我发现有了这个目标,我对我的雇主更有价值。我越努力做到一次性,我对他们就越有价值。


1)商业应用程序闹剧:

我认为整个"企业"框架就是烟雾和镜子。j2ee,.net,大多数Apache框架和管理这些东西的大多数抽象产生了比它们解决的复杂得多的复杂性。

使用任何规则的Java或.NET ORM,或者任何假设的现代MVC框架,为那些"魔术"来解决繁琐、简单的任务。最后会编写大量难看的XML样板文件,这些文件很难验证和快速编写。你有大量的API,其中的一半只是集成其他API的工作,不可能回收的接口,以及抽象的类,只需要克服Java和C的不灵活。我们根本不需要这些。

所有不同的应用服务器都有自己的darned描述符语法,过于复杂的数据库和群件产品呢?

这并不是说复杂性==坏,而是说不必要的复杂性==坏。我曾在大型企业安装中工作过,其中一些是必要的,但即使在大多数情况下,解决大多数用例也只需要一些自行开发的脚本和简单的Web前端。

我将尝试用简单的Web框架、开放源代码DBS和简单的编程结构替换所有这些企业应用程序。

2)所需n年经验:

除非您需要顾问或技术人员来处理与应用程序、API或框架相关的特定问题,否则您实际上不需要具有5年应用程序经验的人员。你需要的是一个能够阅读文档的开发人员/管理员,他对你正在做的任何事情都有领域知识,并且能够快速学习。如果你需要用某种语言进行开发,一个优秀的开发人员将在不到2个月的时间内完成。如果您需要X Web服务器的管理员,他应该在两天内读完手册页和新闻组,并跟上进度。再少一点,那人就不值得他付出什么。

3)普通"计算机科学"学位课程:

大多数计算机科学和软件工程学位都是牛市。如果你的第一个编程语言是Java或者C语言,那么你就做错事了。如果你没有上好几门代数和数学的课程,那就错了。如果你不深入研究函数式编程,它是不完整的。如果你不能将循环不变量应用到一个微不足道的for循环中,作为一个假定的计算机科学家,你就不值得你的盐了。如果你在X和Y语言和面向对象方面都有经验,那就充满了S*。一个真正的计算机科学家从一种语言所使用的概念和句法的角度来看待它,把编程方法看作是众多方法中的一种,并且对这两种方法的基本原理有着很好的理解,因此选择新的语言、设计方法或规范语言应该是微不足道的。


吸气剂和二传手使用过度

我见过数以百万计的人声称公共领域是邪恶的,所以他们将其私有化,并为所有人提供获取者和设置者。我相信这与公开字段几乎是相同的,如果您使用线程(但通常不是这样),或者如果您的访问器具有业务/表示逻辑(至少是"奇怪的"),可能会有点不同。

我不赞成公共字段,而是反对为每个字段创建getter/setter(或属性),然后声称这样做是封装或信息隐藏…哈!

更新:

这个答案在它的评论中引起了一些争议,所以我会尽量澄清一下(我会保持原样不变,因为这是很多人反对的)。

首先:任何使用公共领域的人都应该坐牢

现在,创建私有字段,然后使用IDE为每一个字段自动生成getter和setter几乎和使用公共字段一样糟糕。

很多人认为:

private fields + public accessors == encapsulation

我说(自动或不自动)为您的字段生成getter/setter对有效地违背了您试图实现的所谓封装。

最后,让我引用鲍勃叔叔的话(摘自《清洁代码》第6章):

There is a reason that we keep our
variables private. We don't want
anyone else to depend on them. We want
the freedom to change their type or
implementation on a whim or an
impulse. Why, then, do so many
programmers automatically add getters
and setters to their objects, exposing
their private fields as if they were
public?


UML图被高估了

当然,有一些有用的图,例如复合模式的类图,但是许多UML图绝对没有价值。


意见:SQL是代码。像这样对待它

也就是说,就像你的C语言、Java或其他喜欢的对象/过程语言一样,开发一种可读和可维护的格式化风格。

我讨厌看到随意格式化的SQL代码。如果在一个页面上看到两种样式的花括号时都尖叫,那么当看到隐藏或模糊连接条件的自由格式SQL或SQL时,为什么不尖叫呢?


可读性是代码最重要的方面。

比正确性更重要。如果它可读,很容易修复。它也易于优化,易于更改,易于理解。希望其他开发人员也能从中学习到一些东西。


如果您是开发人员,您应该能够编写代码

去年我做了很多面试,在我的面试中,我要测试人们的思维方式,以及他们如何在白板上实现简单到中等的算法。我最初的问题是:

Given that Pi can be estimated using the function 4 * (1 - 1/3 + 1/5 - 1/7 + ...) with more terms giving greater accuracy, write a function that calculates Pi to an accuracy of 5 decimal places.

这是一个应该让你思考的问题,但是对于一个经验丰富的开发人员来说不应该是遥不可及的(它可以用大约10行C来回答)。然而,我们的许多候选人(据说是由该机构预先筛选的)甚至无法回答,甚至无法解释他们如何回答。所以过了一会儿,我开始问一些简单的问题,比如:

Given the area of a circle is given by Pi times the radius squared, write a function to calculate the area of a circle.

令人惊讶的是,超过一半的候选人不能用任何语言编写这个函数(我可以阅读最流行的语言,所以我让他们使用他们选择的任何语言,包括伪代码)。我们有"c开发人员",他们不能用c编写这个函数。

我对此感到惊讶。我一直认为开发人员应该能够编写代码。现在看来,这是一个有争议的观点。当然是面试中的候选人!

编辑:

关于第一个问题是好问题还是坏问题,以及你是否应该在面试中提出如此复杂的问题,评论中有很多讨论。我不会在这里深入探讨这个问题(这是一个全新的问题),除了说你基本上错过了帖子的要点。

是的,我说过人们不能在这方面取得任何进展,但第二个问题是微不足道的,许多人也不能在这方面取得任何进展!任何自称为开发人员的人都应该能够在几秒钟内写出第二个问题的答案,而不必思考。很多人不能。


使用匈牙利符号应处以死刑。

这应该引起足够的争议;)


设计模式对好的设计所造成的伤害远大于它们对它的帮助。

IMO软件设计,尤其是优秀的软件设计,太过多样化,无法有意义地捕捉到模式,尤其是在人们实际能记住的少量模式中——而且这些模式太抽象,人们无法真正记住太多的模式。所以他们没什么帮助。

另一方面,太多的人沉迷于这个概念,并尝试在任何地方应用模式——通常,在生成的代码中,您无法在所有(完全没有意义的)单例工厂和抽象工厂之间找到实际的设计。


代码越少越好!

如果用户说"就这样?"你的工作还是看不见的,做得对。荣耀可以在别处找到。


PHP吸吮;

证据在布丁里。


单元测试不能帮助您编写好的代码

进行单元测试的唯一原因是确保已经运行的代码不会中断。首先编写测试,或者向测试中编写代码是荒谬的。如果在代码之前编写测试,您甚至不知道边缘情况是什么。您可以拥有通过测试但在不可预见的情况下仍然失败的代码。

而且,优秀的开发人员将保持低内聚性,这将使得添加新代码不太可能导致现有代码出现问题。

实际上,我会更进一步地概括这一点,

软件工程中的大多数"最佳实践"都是为了防止坏的程序员造成过多的损害。

他们会抓住不好的开发人员,防止他们犯愚蠢的错误。当然,由于大多数开发人员都很差劲,这是一件好事,但优秀的开发人员应该得到一个通行证。


写一些小方法。程序员似乎喜欢编写looong方法,在那里他们可以做多种不同的事情。

我认为应该在任何可以命名的地方创建一个方法。


偶尔写一次垃圾代码没关系

有时,为了完成特定的任务,只需要一段快速而脏的垃圾代码。模式,窗体,SRP,无论什么…抛出一个控制台或Web应用程序,编写一些内联SQL(感觉很好),然后爆发出需求。


代码=设计

我不喜欢复杂的UML图和无休止的代码文档。在高级语言中,您的代码应该是可读的和可以理解的。复杂的文档和图表实际上不再是用户友好的了。

这是一篇关于代码即设计的文章。


软件开发只是一项工作

别误会,我很喜欢软件开发。最近几年我写了一篇关于这个问题的博客。我在这里花了足够的时间获得超过5000点的声誉。我在一家初创公司工作,每周工作60个小时,所花的钱比我作为一个承包商所能得到的要少得多,因为团队很棒,工作也很有趣。

但在宏伟的计划中,这只是一份工作。

它的重要性低于许多事情,如家庭、我的女朋友、朋友、幸福等,也低于其他我宁愿做的事情,如果我有无限的现金供应,如骑摩托车、帆船或滑雪板。

我认为有时候很多开发人员忘记了开发只是让我们在生活中拥有更重要的东西(并且通过做我们喜欢的事情来拥有它们),而不是成为最终目标本身。


我还认为在源代码管理中使用二进制文件没有什么问题。如果有充分的理由的话。如果我有一个程序集,我没有它的源,并且可能不一定在每个devs机器上的同一个位置,那么我通常将它粘贴在"二进制文件"目录中,并使用相对路径在项目中引用它。

相当多的人似乎认为我在同一句话中提到"源代码控制"和"二进制"都应该受到惩罚。我甚至知道有一些地方有严格的规定说你不能添加它们。


每个开发人员都应该熟悉现代计算机的基本体系结构。这也适用于以虚拟机为目标的开发人员(可能更严重,因为他们一次又一次地被告知他们不需要担心内存管理等问题)。


软件架构师/设计师被高估了

作为开发人员,我讨厌软件架构师的想法。他们基本上不再是全职编码,阅读杂志和文章,然后告诉你如何设计软件的人。只有那些真正以写软件为生的人才应该这样做。我不管你是不是5年前成为建筑师前世界上最好的程序员,你的观点对我来说毫无用处。

有争议怎么办?

编辑(澄清):我认为大多数软件架构师都是优秀的业务分析师(与客户交谈、编写需求、测试等),我只是认为他们在设计软件、高层或其他方面没有位置。


没有"一刀切"的发展方法

我很惊讶这是一个有争议的观点,因为在我看来这是常识。然而,在流行的博客上有很多条目提倡"一刀切"的发展方式,所以我认为我可能实际上是少数。

我所看到的被吹捧为任何项目的正确方法的东西——在任何关于它的信息被了解之前——是诸如测试驱动开发(TDD)、域驱动设计(DDD)、对象关系映射(ORM)、敏捷(Capital A)、对象定向(OO)等的使用,包括从方法论到体系结构的所有东西。O组件。当然,所有这些词都有很好的首字母缩写。

人们甚至在自己的博客上贴上徽章,比如"我是测试驱动的"或者类似的东西,就好像他们严格坚持一种单一的方法,不管项目的细节实际上是一件好事。

不是这样。

选择正确的方法、体系结构和组件等,不仅取决于您所从事的项目的类型及其独特的需求,还取决于您所从事的团队的规模和能力。


大多数专业程序员都很差劲

我遇到过太多为生计而做这项工作的人,他们对自己所做的工作简直是一无是处。糟糕的代码,糟糕的沟通技巧,对新技术毫无兴趣。太多,太多…


计算机科学学位并不能——也不应该——教你做程序员。

编程是一门贸易,计算机科学是一门研究领域。你可以是一个伟大的程序员,一个可怜的计算机科学家,一个伟大的计算机科学家和一个糟糕的程序员。理解两者的区别是很重要的。

如果你想成为程序员,学习Java。如果你想成为一名计算机科学家,至少要学习三种几乎完全不同的语言。例如(汇编程序、C、lisp、ruby、smalltalk)


SESE(单入口单出口)不是法律

例子:

1
2
3
4
5
6
7
public int foo() {
   if( someCondition ) {
      return 0;
   }

   return -1;
}

VS:

1
2
3
4
5
6
7
8
9
public int foo() {
   int returnValue = -1;

   if( someCondition ) {
      returnValue = 0;
   }

   return returnValue;
}

我和我的团队发现,在许多情况下,一直遵守这一点实际上会适得其反。


C++是有史以来最糟糕的编程语言之一。

它具有委员会设计的所有特征——它不能很好地完成任何给定的工作,而且做一些工作(如OO)非常糟糕。它有一个"厨房水槽"绝望,只是不会消失。

学习编程是一门可怕的"第一语言"。你得不到优雅,也得不到帮助(语言)。相反,您有bear陷阱和mine字段(内存管理、模板等)。

尝试学习OO概念不是一种好的语言。它的行为是"带有类包装器的C",而不是正确的OO语言。

我可以继续说下去,但暂时不谈了。我从未喜欢C++编程,虽然我在FORTRAN上"咬牙切齿",但我完全喜欢C语言的编程。我仍然认为C是伟大的"经典"语言之一。在我看来,C++当然不是。

干杯,

-R

编辑:响应对C++教学的评论。你可以用两种方式教C++——教给它"类固醇上的C"(从变量、条件、循环等)开始,或者教它作为一种纯粹的"OO"语言(从类、方法等开始)。您可以找到使用这些方法中的一种或其他方法的教学文本。我更喜欢后一种方法(OO第一),因为它强调C++作为一种面向对象语言的能力(这是C++的最初设计重点)。如果你想教C++"C",那么我认为你应该教C,而不是C++。

但是在我的经验中,C++作为第一语言的问题是,语言在一个学期里太大以至于不能教,而且大多数的"介绍"文本都试图覆盖一切。在"第一语言"课程中不可能涵盖所有的主题。你至少要把它分成两个学期,然后它就不再是"第一语言",我的意思是。

我教C++,但只是作为一种"新的语言"——也就是说,你必须精通一些以前的"纯"语言(不是脚本或宏),然后才可以参加课程。C++是一种很好的"第二语言",IMO.

-R

'其他编辑:(给康拉德)

我根本不同意C++在各个方面都是优越的。C。我花了多年的时间编写C程序,用于微控制器和其他嵌入式应用程序。这些设备的C编译器是高度优化的,通常产生的代码和手工编码的汇编程序一样好。当你移动到C++时,编译器会给你带来巨大的开销,以便管理你可能不使用的语言特性。在嵌入式应用程序中,通过添加类之类的东西(imo)几乎没有什么好处。您需要的是紧凑、干净的代码。你可以用C++编写它,但是你真的只是在写C,C编译器在这些应用程序中被优化了。

我写了一个MIDI引擎,首先在C,后来在C++(在供应商的请求下)为嵌入式控制器(声卡)。最后,为了满足性能需求(MIDI计时等),我们必须将所有核心代码恢复为纯C。我们能够使用C++来实现高级代码,并且具有非常好的类,但是我们需要C来获得较低级别的性能。C代码比C代码快了一个数量级,但是手工编码的汇编程序只比编译的C代码稍微快一点。这要追溯到20世纪90年代初,只是为了恰当地安排事件。

-R


你必须知道如何打字才能成为一名程序员。

这在那些不知道如何打字的人中是有争议的,但是他们坚持说他们能像任何打字员一样快速地进行两个手指的搜寻和啄食,或者他们不需要花那么多时间打字,或者智能感知减轻了打字的需要……

我从来没有见过会打字的人,但我坚持认为这没什么区别。

另见:编程最肮脏的小秘密


懒惰的程序员是最好的程序员

懒惰的程序员通常会找到减少编写代码所花费时间的方法(尤其是大量相似或重复的代码)。这通常转化为公司/团队中的其他开发人员可以从中受益的工具和工作流。

当开发人员遇到类似的项目时,他可能会创建工具来引导开发过程(例如,创建一个与公司的数据库设计范例一起工作的DRM层)。

此外,这些开发人员通常使用某种形式的代码生成。这意味着同一类型的所有错误(例如,代码生成器没有检查所有方法上的空参数)通常可以通过修复生成器而不是修复该错误的50多个实例来修复。

一个懒惰的程序员可能需要几个小时才能把第一个产品带出门,但这样可以节省你几个月的时间。


计算机科学或其他IT领域的学位确实使你成为一个更全面的程序员。

我不在乎你有多少年的经验,你读过多少博客,你参与了多少开源项目。一个资格(我建议超过3年)暴露给你一种不同的思维方式,给你一个伟大的基础。

仅仅因为你写的代码比一个拥有计算机科学学士学位的人好,并不意味着你比他好。你所拥有的,他可以在一瞬间得到,但事实并非如此。

拥有一个资格证明了你的承诺,事实上你将超越经验,使你成为一个更好的开发人员。开发人员擅长他们所做的工作,并且有资格,这可能是非常可怕的。

如果这个答案被否决,我不会感到惊讶。

而且,一旦你有了资格,你就慢慢地停止把自己和那些有资格的人(我的经验)比较。你知道,只要你能很好地合作,最后一切都无关紧要。

无论资质如何,始终对其他开发人员仁慈行事。


不要使用继承,除非你能解释为什么你需要它。


世界需要更多的哥特人

"我的教授告诉我,Gotos是坏的",Gotos经常被虔诚地避免,而且没有任何理由,它们有一个目的,在许多地方都会大大简化生产代码。

也就是说,99%的代码都不需要它们。


我以前因为在公共场合发表这些意见而被烧死,但现在我要说的是:

动态类型语言中编写良好的代码遵循静态类型约定

使用了python、php、perl和其他一些动态类型语言之后,我发现这些语言中编写良好的代码遵循静态类型约定,例如:

  • 重新使用具有不同类型的变量(例如,它的错误样式是获取一个列表变量并分配一个int,然后在同一方法中为变量分配一个bool)。用动态类型语言编写良好的代码不会混合类型。

  • 静态类型语言中的类型错误仍然是动态类型语言中的类型错误。

  • 函数通常设计为一次在单个数据类型上操作,因此接受T类型参数的函数只能明智地与T类型的对象或T的子类一起使用。

  • 为许多不同数据类型上的运算符设计的函数以一种将参数约束到定义良好的接口的方式编写。一般来说,如果两个类型为AB的对象执行类似的功能,但不是彼此的子类,那么它们几乎肯定实现了相同的接口。

虽然动态类型化语言当然提供了不止一种方法来破解一个难题,但这些语言中最优秀的、惯用的代码与用静态类型化语言编写的代码一样严格地关注类型。

动态类型不能减少程序员需要编写的代码量

当我指出有如此多的静态类型约定跨越到动态类型世界是多么的奇怪时,我通常会加上一句:"那么为什么要使用动态类型语言来开始呢?".即时响应是指能够编写更简洁、更具表现力的代码,因为动态类型允许程序员省略类型注释和显式定义的接口。但是,我认为最流行的静态类型语言,例如C语言、Java和Delphi,由于设计而庞大,而不是它们的类型系统的结果。

我喜欢使用带有真正类型系统(如ocaml)的语言,它不仅是静态类型的,而且它的类型推断和结构类型允许程序员省略大多数类型注释和接口定义。

ML语言家族的存在证明了我们可以享受静态类型的好处,同时动态类型语言中的写作也非常简洁。实际上,我使用ocaml的repl来处理临时的、一次性的脚本,与其他人使用Perl或Python作为脚本语言的方式完全相同。


花一整天时间回答StackOverflow问题的程序员可能没有完成他们要支付的工作。


代码布局很重要

也许大括号位置的细节应该保持纯粹的宗教争论——但这并不意味着所有的布局样式都是相同的,或者根本没有客观因素!

问题是,布局的优步规则,也就是说:"保持一致",听起来像是,被许多人用作拐杖,从不试图看他们的默认样式是否可以改进——而且,这甚至都无关紧要。

几年前,我在学习快速阅读技术,我学到了一些关于眼睛如何在"注视"中接收信息的知识,可以最理想地扫描页面,以及下意识地获取上下文的作用,这些知识让我想到了这是如何应用于代码的,尤其是在编写代码时。

它使我形成了一种本质上倾向于列式的风格,在可能的情况下,标识符在逻辑上分组并对齐(特别是,我对每个方法参数都有自己的行变得严格)。然而,与长列不变的结构相比,将结构分块改变实际上是有益的,这样你最终会得到矩形的孤岛,眼睛可以在一个固定装置中接受,即使你没有意识到阅读每个角色。

最终的结果是,一旦你习惯了它(通常需要1-3天),它就变得让眼睛高兴,更容易理解,也更快理解,而且对眼睛和大脑的负担也更少,因为它的布局方式使它更容易接受。

几乎没有例外,我要求尝试这种风格的每个人(包括我自己)最初都说,"啊,我讨厌它!"但一两天后,我说:"我爱它——我发现很难不回去,用这种方式重写我所有的旧东西!".

我一直希望有时间做更多的控制性实验,收集足够的证据,写一篇论文,但和以往一样,我忙于其他事情。然而,这似乎是一个向对有争议的技术感兴趣的人提起它的好机会。

[编辑]

我终于开始写博客了(在"意义到"阶段停留了很多年之后):第一部分,第二部分,第三部分。


意见:显式变量声明是一件大事。

我永远不会理解让开发人员浪费大量时间跟踪由变量名拼写错误引起的运行时错误的"智慧",而不仅仅是让编译器/解释器捕获这些错误。

没有人能比"我不用写‘int i;’"更能给我一个解释了。是的,当然,但跟踪运行时错误需要多长时间?


意见:在"调试"和"发布"构建之间永远不会有不同的代码

主要原因是发布代码几乎从未经过测试。最好在测试中运行与野外运行相同的代码。


意见:开发人员应该测试自己的代码

我看到过太多的垃圾被交给了测试,结果它并没有真正修复问题中的bug,导致了通信开销和培养不负责任的实践。


分页永远不是用户想要的

如果您开始讨论在数据库、业务逻辑、客户机等中在何处进行分页,那么您提出的问题是错误的。如果你的应用程序返回的数据比用户需要的多,那么你可以找到一种方法,让用户根据实际的标准而不是任意大小的块来缩小他们需要的数据。如果用户真的想要所有这些结果,那么就给他们所有的结果。你一次给谁20块钱?服务器?这比你的用户更重要吗?

[编辑:澄清,基于评论]

作为一个现实世界的例子,让我们看看这个堆栈溢出问题。假设我有一个有争议的编程意见。在我发帖之前,我想看看是否已经有一个答案可以解决相同的意见,所以我可以投反对票。我唯一的选择就是点击每一页答案。

我更喜欢以下选项之一:

  • 允许我搜索答案(一种我根据实际标准缩小所需范围的方法)。

  • 允许我查看所有答案,以便使用浏览器的"查找"选项(提供所有结果)。

  • 如果我只是想找到我以前读过的答案,但现在找不到了,这同样适用。我不知道它是什么时候发布的,也不知道它有多少选票,所以排序选项没有帮助。即使我这样做了,我还是要玩猜谜游戏才能找到正确的结果页面。答案是分页的,我可以直接点击十几页中的一页,这一点毫无帮助。

    ——骨形态发生蛋白B


    尊重单一责任原则

    乍一看,你可能并不认为这会引起争议,但根据我的经验,当我向另一个开发人员提到他们不应该在页面加载方法中做任何事情时,他们常常会推回……所以对于孩子们来说,请不要再建立我们经常看到的"做每件事"的方法。


    不编码的架构师是无用的。

    听起来有点刺耳,但这并不不合理。如果您是一个系统的"架构师",但是对所使用的技术没有实际的参与,那么您如何获得开发团队的尊重呢?你如何影响方向?

    架构师需要做更多的工作(与利益相关者会面、与其他团队谈判、评估供应商、编写文档、提供演示文稿等),但是,如果您从未看到架构师签入的代码……小心!


    对象不应处于无效状态

    不幸的是,许多ORM框架要求所有实体类都使用零arg构造函数,使用setter填充成员变量。在这些情况下,很难知道必须调用哪些setter才能构造有效的对象。

    1
    2
    MyClass c = new MyClass(); // Object in invalid state. Doesn't have an ID.
    c.setId(12345); // Now object is valid.

    在我看来,对象不可能发现自己处于无效状态,并且类的API应该在每次方法调用后主动强制其类不变量。

    构造函数和赋值函数方法应该原子地将对象从一个有效状态转换到另一个有效状态。这更好:

    1
    MyClass c = new MyClass(12345); // Object starts out valid. Stays valid.

    作为某些库的使用者,在试图使用对象之前跟踪是否调用了所有正确的setter是件很麻烦的事情,因为文档通常不提供有关类合同的线索。


    源代码管理:除了SourceSafe以外的任何内容

    另外:专用锁是邪恶的。

    我曾经在某个地方工作过,在那里他们认为独占锁意味着当您签入时,您保证人们不会覆盖其他人的更改。问题是,为了完成任何工作,如果一个文件被锁定,devs只需将其本地文件更改为可写,并在有机会时将源代码管理与其版本合并(或覆盖)。


    默认情况下,所有变量/属性都应为readonly/final

    这种推理有点类似于乔恩提出的关于类的sealed论证。程序中的一个实体应该有一个作业,并且只有一个作业。尤其是,对于大多数变量和属性来说,改变值绝对没有意义。基本上有两个例外。

  • 循环变量。但是,我认为这个变量实际上根本不会改变值。相反,它在循环结束时超出了范围,并在下一个循环中重新实例化。因此,不变性可以很好地处理循环变量,任何试图用手更改循环变量值的人都应该直接下地狱。

  • 蓄能器。例如,假设一个数组中的值求和的情况,甚至是一个列表/字符串,它收集了一些关于其他东西的信息。

    今天,有更好的方法来实现相同的目标。函数语言有更高阶的函数,python有清单理解,而.net有linq。在所有这些情况下,不需要可变累加器/结果保持器。

    考虑字符串连接的特殊情况。在许多环境(.NET,Java)中,字符串实际上是不可变的。那么为什么还要允许对字符串变量赋值呢?最好一直使用builder类(即StringBuilder)。

  • 我意识到今天的大多数语言并不是为了默许我的愿望而建立的。在我看来,所有这些语言都有根本的缺陷。如果将它们更改为默认情况下将所有变量视为只读,并且在初始化之后不允许对它们进行任何分配,那么它们将不会失去任何表现力、能力和易用性。


    意见:单元测试不需要预先编写,有时根本不需要。

    理由:开发人员在测试自己的代码方面很差劲。是的。这就是为什么我们通常有测试团队或质量保证小组。

    大多数时候,我们编写的代码是与要单独测试的其他代码交织在一起的,所以我们最终跳过了模式化的环来提供可测试性。并不是说那些模式是坏的,但它们有时会增加不必要的复杂性,所有这些都是为了单元测试…

    …这通常都不起作用。编写一个全面的单元测试需要大量的时间。往往比我们愿意付出的时间更多。测试越全面,如果它测试的对象的接口发生变化,它就越容易变得脆弱,从而强制重写不再编译的测试。


    认识到有时候足够好就足够好了,这是作为一个程序员你的价值的一次重大飞跃。

    注意,当我说"足够好"的时候,我的意思是"足够好",但这并不是什么废话。但是,当你在时间紧迫的时候,"一些恰巧有用的垃圾"可能被认为是"足够好的"。


    如果我有争议的话,我得建议乔恩·斯基特不是万能的。


    "爪哇吮吸"-是的,我知道意见绝对不是所有人持有的:

    我有这样的观点,因为我见过的大多数Java应用程序都是内存堆,运行速度慢,用户界面非常糟糕等等。

    G-man


    好吧,我说我会更详细地谈谈我的"封闭课程"意见。我想有一种方法可以显示出我感兴趣的答案,那就是我自己给出一个答案。

    意见:类应在C中默认密封#

    推理:

    毫无疑问,遗产是强大的。然而,它必须有所指导。如果有人以完全出乎意料的方式从基类派生,这可能会破坏基本实现中的假设。考虑基类中的两个方法,其中一个调用另一个方法-如果这些方法都是虚拟的,那么必须记录实现细节,否则,有人可能相当合理地重写第二个方法,并期望对第一个方法的调用能够工作。当然,一旦实现被记录在案,它就不能被改变…所以你失去了灵活性。

    C通过对默认方法进行密封,朝着正确的方向(相对于Java)迈出了一步。然而,我相信,进一步的步骤——让类在默认情况下被密封——会更好。特别是,很容易重写方法(或者不显式地密封不重写的现有虚拟方法),从而导致意外的行为。这并不能阻止你做任何你现在能做的事情——它只是改变一个默认值,而不是改变可用的选项。不过,这将是一个"更安全"的默认值,就像C中的默认访问始终是"当时可用的最私有的可见性"。

    通过让人们明确地说他们希望人们能够从他们的课程中获得灵感,我们会鼓励他们更多地思考这个问题。这也会帮助我解决懒惰的问题——虽然我知道我应该封闭几乎所有的课程,但实际上我很少记得这样做:(

    反参数:

    我可以看到这样一个论点:没有虚拟方法的类可以相对安全地派生出来,而不需要额外的不灵活性和通常需要的文档。我不知道现在该如何对付这个问题,除了说我相信意外打开类的伤害要比意外关闭类的伤害大。


    聪明的程序员是危险的。

    我花了更多的时间试图修复"聪明"程序员编写的代码。我宁愿有一个好的程序员,也不愿有一个非常聪明的程序员,他想通过编写只有他(或她)才能解释的代码来证明自己有多聪明。


    糟糕的程序员是语言不可知论者

    一个非常糟糕的程序员几乎可以用任何语言编写糟糕的代码。


    避免缩进。

    使用提前归还、继续或休息。

    而不是:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    if (passed != NULL)
    {
       for(x in list)
       {
          if (peter)
          {
              print"peter";
              more code.
              ..
              ..
          }
          else
          {
              print"no peter?!"
          }
       }
    }

    做:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    if (pPassed==NULL)
        return false;

    for(x in list)
    {
       if (!peter)
       {
           print"no peter?!"
           continue;
       }

       print"peter";
       more code.
       ..
       ..
    }


    如果您知道如何编程,则不适合在窗体上放置按钮

    这有足够的争议吗?;)

    无论我们多么努力,都几乎不可能与不得不使用我们的订单输入软件的53岁的Doris产生适当的共鸣。我们根本无法理解她想象的在电脑里发生的事情的心理模型,因为我们不需要想象:我们知道发生了什么,或者有一个非常好的主意。

    交互设计应该由非程序员完成。当然,这永远不会发生。矛盾的是,我很高兴这一点;我喜欢UI设计,尽管内心深处我知道我不适合它。

    欲知更多信息,请阅读《囚犯经营庇护所》一书。请注意,我发现这本书令人沮丧和侮辱;如果你是一个关心用户体验的开发人员,那么阅读起来很困难。


    在1970年1月1日之前,对与错是相反的…


    我可能会为此被烤,但是:

    让不可见的字符在python中具有语法意义是个坏主意

    它让人分心,给新手带来很多微妙的错误,在我看来,这并不是真正需要的。我见过的唯一一个没有自愿遵循某种像样格式指南的代码是来自一年级的CS学生。即使代码不遵循"好"的标准,也有很多工具可以将其强制为更令人满意的形状。


    应从OO语言中删除空引用

    来自Java和C语言背景,在正常情况下,从一个方法返回null来指示一个失败,我得出结论,空值会导致很多可避免的问题。如果只从代码中消除空引用,语言设计器可以删除与nullreferenceexceptions相关的整类错误。

    另外,当我调用一个方法时,我无法知道该方法是否可以返回空引用,除非我在实现中进行了深入研究。我希望看到更多的语言遵循F处理空值的模型:F不允许程序员返回空引用(至少对于用F编译的类),而是要求程序员使用option类型表示空对象。这种设计的好处在于,函数是否可以返回空引用等有用信息如何通过类型系统传播:返回类型'a的函数的返回类型与返回类型'a option的函数的返回类型不同。


    你不必为每件事都编程序

    我对每件事都感到厌倦了,但是每件事都需要被塞进一个程序中,就像这样总是更快。一切都需要网络化,任何事情都需要通过计算机来完成。请用你的笔和纸。它速度更快,维护更少。


    如果你不知道就好了。但如果你连谷歌都不能搜索,你就被解雇了。

    互联网是一种工具。如果你从中吸取教训,这不会让你变得更傻。


    单身不是坏事

    在现实世界中有一个单身汉的地方,而绕过他们的方法(即单态模式)只是伪装成单身汉。例如,一个记录器是一个单例的完美候选对象。另外,信息泵也是如此。我当前的应用程序使用分布式计算,不同的对象需要能够发送适当的消息。应该只有一个消息泵,每个人都可以访问它。另一种选择是将一个对象传递到可能需要的任何地方,并希望一个新的开发人员在不经过思考和思考的情况下不会有新的开发人员。单例的唯一性是最重要的部分,而不是它的可用性。单身汉在世界上占有一席之地。


    一幅画不值得千言万语。

    有些照片可能值一千字。他们中的大多数不是。这句陈词滥调的格言大多是不真实的,对于许多懒惰的经理来说,这是一个可悲的借口,他们不想仔细阅读创建的报告和文档,说"我需要你给我一个图表。"

    我妻子学的是语言学专业,她看到了一些与传统的图片和标识智慧相反的有趣证据:它们不会突破语言和文化障碍,它们通常不会在任何地方交流到与正确的文本一样多的信息,它们只是无法替代真实的交流。

    尤其是,如果线条未标记和无法解释,和/或每一线条都有不同的含义,而不是表示相同的关系(除非以某种方式彼此区分),则与线条相连的标记气泡是无用的。如果你的台词有时意味着关系,有时意味着行动,有时意味着时间的流逝,那么你真的很受欢迎。

    每一个优秀的程序员都知道你使用的是适合手头工作的工具,对吧?并非所有的系统都是最好的指定和记录在图片中。图形规范语言,可以自动转换成可证明是正确的、可执行的代码,或者是一个壮观的想法(如果存在的话)。在适当的时候使用它们,而不是在阳光下使用。实体关系图很棒。但并不是每件事都能概括成一幅图画。

    注意:一张桌子可能值它的黄金重量。但是一张桌子和一张照片不一样。再者,一段精雕细琢的短文可能更适合手头的工作。


    不要写代码,删除代码!

    正如一位聪明的老师曾经告诉我的:"不要写代码,写代码是坏的,删除代码是好的。如果你必须写代码-写小代码…"


    你需要注意那些痴迷于对象的程序员。

    例如,如果您编写一个类来为内置类型(如int或float)建模,那么您可能是一个痴迷于对象的程序员。


    外面有很多糟糕的教学。

    当乔尔说大脑中有一部分是用来理解一些人天生就没有的指针时,我们的开发人员会感到非常优越。我们中的许多人在这里讨论的话题都是深奥的,但有时这只是因为我们让它们如此。


    在开发代码时,最好记住优化。

    每当我这样说,人们总是回答:"过早的乐观是万恶之源"。

    但在调试之前我不是说优化。我甚至从来没有说过"优化",但是在设计代码时,请记住这可能成为一个瓶颈,并编写它,这样就可以快速地重构代码,而不会将API撕碎。

    雨果


    如果开发人员不能写出清晰、简洁和语法正确的评论,那么他们应该回去学习英语101。

    我们有开发人员和(恐怖的)架构师,他们写得不连贯。当审查他们的文件时,他们会说"哦,别担心语法错误或拼写——这不重要"。然后他们想知道为什么他们复杂的垃圾文件变成了复杂的错误代码。

    我告诉实习生,我指导你,如果你不能用口头或书面的方式传达你的伟大想法,你最好不要这些想法。


    C++是一种好的语言

    我几乎一个星期前就被另一个问题私奔了,因为他说C++不是一个很好的语言。所以现在我试着说相反的话。;)

    不,说真的,我当时想做的,现在再试试,就是C++有很多缺点。很难否认。它是如此的复杂,以至于学好它实际上是你一生可以奉献的东西。它使许多常见的任务变得不必要的困难,允许用户在没有编译器给出警告的情况下,先将头插入一个行为不定义、代码不可移植的海洋中。

    但许多人试图用的并不是无用的、陈旧的、过时的、令人讨厌的语言。它不应该被扫到地毯下而被忽视。没有它,世界就不会是一个更好的地方。它有一些独特的优势,不幸的是,隐藏在奇怪的语法背后,遗留的CRUFT,尤其是坏的C++教师。但他们在那里。

    C++在C语言或其他"现代"语言中编程时,我非常怀念的许多特性。这里面有很多C和其他现代语言可以学习的。

    它并不是盲目地关注OOP,而是探索和开创了通用编程。它允许令人惊讶的、富有表现力的编译时元编程生成非常高效、健壮和干净的代码。在C获得linq或lambda表达式之前,它从函数编程中吸取了差不多十年的经验。

    它允许您在编译时通过静态断言和其他元编程技巧捕获大量错误,这大大简化了调试,甚至在某些方面胜过了单元测试。(我更愿意在编译时捕获错误,而不是在运行测试时在编译后捕获错误)。

    变量的确定性破坏允许raii,一个非常强大的小技巧,使try/finally块和c的using块冗余。

    虽然有人指责它是"委员会设计的",但我会说是的,事实上,在这种情况下,这并不是一件坏事。看看Java的类库。又有多少类被弃用了?不应使用多少?有多少重复彼此的功能?有多少设计不好?

    C++的标准库要小得多,但总体来说,它设计得很好,除了一个或两个小疣(例如,EDOCX1 1),它的设计仍然很好。当一个特征添加到C++或它的标准库时,它会受到严格的审查。难道Java不能从中受益吗?.NET也同样,虽然它更年轻,而且设计得更好,但是它仍然积累了大量与现实不同步的类,或者设计得很糟糕。

    C++有很多其他语言无法比拟的优点。这是一种很好的语言


    源文件是20世纪的产物。

    在函数/方法的主体中,将过程逻辑表示为线性文本是有意义的。即使逻辑不是严格线性的,我们也有很好的编程结构(循环、if语句等),允许我们使用线性文本清晰地表示非线性操作。

    但是没有理由要求我在不同的文件中划分类,或者在这些文件中按特定的顺序对函数/方法/字段/属性等进行排序。为什么我们不能把所有这些东西都扔到一个大数据库文件中,让IDE动态地对所有东西进行排序?如果我想按名称对成员排序,那么我将单击"成员"表中的"成员"标题。如果我想按可访问性对它们排序,那么我将单击可访问性标题。如果我想将类视为继承树,那么我将单击按钮来执行此操作。

    也许可以从空间上看类和成员,就好像它们是虚拟世界中的某种实体。如果程序员愿意,IDE可以自动将彼此使用的类和成员放置在彼此附近,这样就很容易找到它们。图像能够放大和缩小这个虚拟世界。一直放大,你就可以给星系命名,其中有小类行星。放大到一个名称空间,你可以看到类行星与方法大陆和岛屿和内部类作为轨道卫星。放大到一个方法,你会看到…该方法的源代码。

    基本上,我的观点是,在现代语言中,不管你把类放在什么文件中,或者你定义类成员的顺序如何,我们为什么还要被迫使用这些古老的实践呢?还记得Gmail出来谷歌说"搜索,不要排序"的时候吗?那么,为什么同样的原理不能应用于编程语言呢?


    一个我已经辗转反侧一段时间了:

    数据就是系统。

    过程和软件是为数据而构建的,而不是反过来。

    没有数据,过程/软件的价值很小。没有流程或软件,数据仍然有价值。

    一旦我们了解了数据、它做什么、它如何交互、它在不同阶段存在的不同形式,只有这样才能构建一个支持数据系统的解决方案。

    成功的软件/系统/过程似乎具有敏锐的意识,即使不是狂热地注意到数据在任何给定时刻的"位置"。


    设计模式是石器时代编程语言设计的一个标志

    他们有自己的目的。很多好的软件都是用它们构建的。但事实上,有必要将这些关于代码如何工作/应该如何工作的心理抽象的"处方"编纂起来,这说明缺乏能够为我们处理这种抽象的编程语言。

    我认为,补救方法在于,语言允许您将越来越多的设计嵌入到代码中,方法是定义可能不存在或可能不具有一般适用性的语言构造,但在代码不断处理的情况下确实有意义。人们已经知道这个计划很多年了,而且计划宏有可能让大多数猴子雇佣尿裤子。


    以狂热者的热忱和错误的假设,即他们是铁板一块的规则,把那些著名的格言从语境中规划出来,这真让我恼火。例如,"过早的优化是万恶之源",正如这个线程所覆盖的那样。

    在国际海事组织,许多技术问题和解决方案对环境非常敏感,而全球最佳实践的概念是一个谬论。


    当我声称代码仅仅是我设计的一种表达时,我常常会被大声叫嚷。我非常不喜欢看到这么多开发人员在"动态"地设计系统的同时对其进行编码。

    当这些牛仔中的一个从马上摔下来的时候,浪费的时间和精力是惊人的——10次中有9次他们碰到的问题可以通过一些预先设计工作来解决。

    我觉得现代方法论并不强调设计在整个软件开发过程中的重要性。例如,当您甚至没有审查您的设计时,对代码审查的重要性!这太疯狂了。


    牛仔编码员做得更多。

    我一生都在创业的氛围中度过。如果没有牛仔编码员,我们将浪费无休止的周期来确保事情"正确"完成。

    我们知道,基本上不可能放弃所有的问题。牛仔编码员直接处理这些问题,并被迫比那些试图抛弃它们的人更快地解决它们。

    不过,如果你是牛仔编码,最好在别人维护之前先重构一下意大利面。我所知道的最好的使用连续重构。他们完成了大量的工作,不浪费时间去预测未来,通过重构,它变成了可维护的代码。

    不管过程有多敏捷,它总是妨碍一个好牛仔。


    Emacs较好


    应始终使用基于1的数组,而不是基于0的数组。基于0的数组是不自然、不必要和容易出错的。

    当我计算苹果、员工或小部件时,我从一开始,而不是从零开始。我教我的孩子们同样的东西。没有第0个苹果、第0个员工或第0个小部件这样的东西。使用1作为数组的基础更直观,更不容易出错。忘了加一减一地狱(就像我们过去常说的那样)。基于0的数组是计算机科学发明的一种非自然的构造——它们不反映现实,计算机程序应该尽可能反映现实。


    用户不是白痴——你是。

    我听过很多次开发人员说"白痴也是,白痴也是",我的回答通常是"他可能是个白痴,但你允许他成为一个白痴"。


    编程过程越多,代码就越差。

    在我8年左右的编程生涯中,我注意到了一些事情,这看起来很荒谬。这是获得质量的唯一方法,就是雇佣质量开发人员,尽可能地从他们身上删除流程和形式。单元测试、编码标准、代码/同行评审等只会降低质量,而不会提高质量。这听起来很疯狂,因为相反的情况应该是正确的(更多的单元测试应该导致更好的代码,伟大的编码标准应该导致更可读的代码,代码评审应该提高代码的质量),但事实并非如此。

    我认为归根结底,我们称之为"软件工程",实际上它是设计而不是工程。

    一些数字证实了这一说法:

    From the Editor

    IEEE Software, November/December 2001

    Quantifying Soft Factors

    by Steve McConnell

    ...

    Limited Importance of Process Maturity

    ...
    In comparing medium-size projects
    (100,000 lines of code), the one with
    the worst process will require 1.43
    times as much effort as the one with
    the best process, all other things
    being equal. In other words, the
    maximum influence of process maturity
    on a project’s productivity is 1.43. ...

    ... What Clark doesn’t emphasize is that
    for a program of 100,000 lines of
    code, several human-oriented factors
    influence productivity more than
    process does. ...

    ... The seniority-oriented factors alone
    (AEXP, LTEX, PEXP) exert an influence
    of 3.02. The seven
    personnel-oriented factors
    collectively (ACAP, AEXP, LTEX,
    PCAP, PCON, PEXP, and SITE §) exert a
    staggering influence range of 25.8!
    This simple fact accounts for much of
    the reason that non-process-oriented
    organizations such as Microsoft,
    Amazon.com, and other entrepreneurial
    powerhouses can experience
    industry-leading productivity while
    seemingly shortchanging process. ...

    The Bottom Line

    ... It turns out that trading process
    sophistication for staff continuity,
    business domain experience, private
    offices, and other human-oriented
    factors is a sound economic tradeoff.
    Of course, the best organizations
    achieve high motivation and process
    sophistication at the same time, and
    that is the key challenge for any
    leading software organization.

    §阅读文章了解这些缩略语的解释。


    要生产优秀的软件,您需要领域专家和优秀的开发人员。


    意见:框架和第三部分组件只能作为最后手段使用。

    我经常看到程序员会立即选择一个框架来完成一项任务,而不必学习工作所需的底层方法。某些事情不可避免地会被打破,或者我们会找到一个我们没有考虑到的限制,我们会立即陷入困境,不得不重新思考系统的主要部分。只要仔细考虑,框架就可以使用。


    生成的文档几乎总是一文不值。

    或者,作为推论:您的API需要为维护人员和用户提供单独的文档集。

    实际上有两类人需要了解您的API:维护人员,他们必须了解您的实现的细节才能在他们的工作中发挥效力;用户,他们需要一个高级的概述、示例和他们所访问的每个方法的效果的详细信息。

    我从来没有遇到过在这两个领域都成功生成的文档。一般来说,当程序员为工具编写注释以提取和制作文档时,他们的目标是在中间的某个地方——仅仅是足够的实现细节使用户感到厌烦和困惑,但还不足以显著地帮助维护人员,也不足以对用户提供任何真正的帮助。

    作为一个维护人员,我宁愿有干净、清晰的注释,不被你的auto-doc工具所要求的任何奇怪的标记所迷惑,告诉我为什么你以你的方式写了那个奇怪的switch语句,或者这个看似多余的参数检查修复了什么bug,或者其他我需要知道的东西,以在我工作时保持代码的干净和无bug。它。我希望这些信息就在代码中,与它所涉及的代码相邻,所以我不必搜索你的网站,以发现它处于一种可以供阅读的状态。

    作为一个用户,我总是希望有一个完整的、组织良好的文档(一组网页是理想的,但我也希望有一个结构良好的文本文件),告诉我你的API是如何构建的,什么方法做什么,以及我如何完成我想用你的API做的事情。我不想在内部看到您编写的允许我工作的类,或者它们在其中的文件。我当然不想下载你的源代码,这样我就可以准确地知道幕后发生了什么。如果你的文件足够好的话,我就不必这么做了。

    不管怎样,我就是这么看的。


    我最有争议的编程意见是发现性能问题不是度量,而是捕获。

    如果你在房间里猎捕大象(而不是老鼠),你需要知道它们有多大吗?不!你要做的就是看。它们的巨大性使它们很容易被发现!不必先测量。

    至少从gprof的论文开始,测量的概念就一直是常识。(Susan L.Graham等人,1982年)*一直以来,就在我们的眼皮底下,是一种非常简单和直接的方法来寻找值得优化的代码。

    作为一个小例子,下面是它的工作原理。假设您从调用堆栈中随机抽取5个时间样本,并且碰巧看到5个样本中有3个样本的特定指令。这告诉你什么?

    1
    2
    3
    4
    5
    6
    7
    .............   .............   .............   .............   .............
    .............   .............   .............   .............   .............
    Foo: call Bar   .............   .............   Foo: call Bar   .............
    .............   Foo: call Bar   .............   .............   .............
    .............   .............   .............   Foo: call Bar   .............
    .............   .............   .............   .............   .............
                    .............                                   .............

    它告诉您程序将花费60%的时间来完成该指令要求的工作。去掉它会去掉60%:

    1
    2
    3
    4
    5
    6
    7
    ...\...../...   ...\...../...   .............   ...\...../...   .............
    ....\.../....   ....\.../....   .............   ....\.../....   .............
    Foo: \a/l Bar   .....\./.....   .............   Foo: \a/l Bar   .............
    ......X......   Foo: cXll Bar   .............   ......X......   .............
    ...../.\.....   ...../.\.....   .............   Foo: /a\l Bar   .............
    ..../...\....   ..../...\....   .............   ..../...\....   .............
       /     \      .../.....\...                      /     \      .............

    粗略地说。

    如果您可以删除该指令(或者调用的次数要少得多),这大约是2.5倍的加速。(注意-递归是不相关的-如果大象怀孕了,它就不再小了。)然后你可以重复这个过程,直到你真正接近一个最佳状态。

    • 这不需要测量精度、函数计时、调用计数、图形、数百个样本,以及任何一种典型的分析工具。

    有些人在遇到性能问题时就使用这个方法,不知道有什么大不了的。

    大多数人从来没有听说过它,当他们听说它的时候,认为它只是一种劣质的取样方式。但是它是非常不同的,因为它通过给出呼叫站点的成本(以及终端指令)来确定问题,这是墙时钟时间的百分比。大多数的轮廓仪(不是全部)都不这样做,不管它们是使用采样还是仪器。相反,他们给出了各种各样的总结性测量结果,这些测量结果充其量只是问题可能位置的线索。下面是对这些差异的更广泛的总结。

    *事实上,论文声称gprof的目的是"帮助用户评估抽象的替代实现"。它并没有声称帮助用户找到需要替代实现的代码,而是在一个比函数更精细的级别。

    我的第二个最有争议的观点是,如果不是很难理解的话。


    客户并不总是对的。

    在我处理的大多数情况下,客户是产品所有者,也称为"业务"。通常,开发人员只是编写代码,而不是试图提供产品的既得利益。有太多的误解认为IT部门是"公司内部的公司",这是一堆垃圾。

    我觉得我的职责是帮助企业表达他们的想法-在相互理解的情况下,我对了解企业感兴趣,这样我就可以提供尽可能最好的体验。这条路线意味着有时产品所有者会要求他/她认为是下一次计算革命,让某人要么同意这一事实,要么解释为什么没有人以某种方式做某件事的更可能的原因。这是互惠互利的,因为产品所有者理解进入产品的思想,开发团队理解他们做的不仅仅是吊带代码。

    这实际上已经开始引导我们走上提高生产力的道路。怎样?由于双方意见不一致,沟通得到了改善,因此我们更有可能在过程中更早地聚在一起,为产品定义找到一个互利的解决方案。


    如果你不知道就好了。但如果你连谷歌都不能搜索,你就被解雇了。

    互联网是一种工具。如果你从中吸取教训,这不会让你变得更傻。


    如果你的文本编辑器不能很好地完成代码,那你就是在浪费每个人的时间。

    快速记住数千个参数列表、拼写和返回值(更不用说类结构和类似复杂的组织模式)是计算机擅长而人(相对而言)不擅长的任务。我全心全意地认为,让自己慢一点,避免使用小工具/功能狂热是提高效率和避免bug的好方法,但如果可以花费0,花30秒通过源代码或文档进行不必要的搜索根本没有好处…尤其是如果你只需要一个拼写(这比我们愿意承认的更频繁)。

    当然,如果没有一个编辑器为您的语言提供这种功能,或者任务足够简单,以至于在加载更重的编辑器所需的时间内将其删除,没有人会告诉您Eclipse和90插件是正确的工具。但请不要告诉我,像1999年那样在你周围走动的H-J-K-L的能力确实比每次你需要方法签名时点击Escape节省了你更多的时间…即使你不觉得"黑客"这么做。

    思想?


    好的程序员讨厌编码

    类似于"一个好的程序员是一个懒惰的程序员"和"代码越少越好",但按照这一理念,我已经成功地编写了一些应用程序,否则可能会使用几倍的代码(并且需要几倍的开发时间)。简而言之:在编码之前先思考。我自己的程序中的大多数部分最终导致了后来的问题,它们是我真正喜欢编码的部分,因此代码太多,因此写得很差。就像这段。

    好的程序员是设计师。

    我发现编程使用的概念与设计相同(与艺术中使用的设计概念相同)。我不确定其他程序员是否也会发现同样的事情是真的;也许这是右脑/左脑的事情。太多的程序都很难看,从代码到命令行用户界面,再到图形用户界面,很明显,这些程序的设计者实际上不是设计者。

    虽然在这种情况下,相关性可能并不意味着因果关系,但我注意到,随着我在设计方面的进步,我在编码方面的进步也越来越明显。在这两个地方都可以并且应该使用同样的过程来使事物变得合适和感觉正确。如果代码感觉不正确,它将导致问题,因为a)它是不正确的,或者b)您将假定它以一种稍后"感觉正确"的方式工作,然后它将再次是不正确的。

    艺术和代码不在光谱的两端;代码可以在艺术中使用,它本身也可以是一种艺术形式。

    免责声明:不幸的是,并不是我所有的代码都是漂亮的或"正确的"。


    不要评论你的代码

    注释不是代码,因此当事情发生变化时,很容易不更改解释代码的注释。相反,我更喜欢从代码中重构出垃圾代码,这样就没有理由发表评论了。一个例子:

    1
    if(data == null)  // First time on the page

    到:

    1
    2
    bool firstTimeOnPage = data == null;
    if(firstTimeOnPage)

    我唯一一次真正的评论是什么时候是一个托多或解释为什么

    1
    Widget.GetData(); // only way to grab data, TODO: extract interface or wrapper


    莫特没关系

    不是每个人都是"摇滚明星"程序员;我们中的一些人之所以这样做是因为这是一种美好的生活,而且我们不关心所有最新的时尚和趋势;我们只是想做我们的工作。


    我有争议的观点是:面向对象编程绝对是软件工程领域中最糟糕的事情。

    OOP的主要问题是完全缺乏一个每个人都能同意的严格定义。这很容易导致具有逻辑漏洞的实现,或者像Java这样的语言,遵循这种OOP意味着的奇异的宗教教义,同时迫使程序员完成所有这些扭曲和"设计模式",只是为了绕过特定的OOP系统的局限性。

    因此,oop欺骗程序员,让他们认为他们正在取得巨大的生产力收益,而oop在某种程度上是一种"自然"的思考方式,同时迫使程序员输入大量不必要的样板文件。

    既然没有人知道oop的真正含义,我们就浪费大量时间在关于x或y语言是否"真正oop"的琐碎争论上,那么对于一种被认为是"真正oop"的语言来说,什么奇异的货物崇拜语言特征绝对是"必不可少的"。

    我们不应该要求这种语言或那种语言是"真正的面向对象的语言",而应该观察实验所显示的语言特性,以实际提高生产力,而不是试图强迫它成为某种想象中的理想语言,或者确实迫使我们的程序符合"真正面向对象的程序"的柏拉图理想。"嗯"。

    与其坚持我们的程序符合柏拉图式的"真正面向对象"的理想,不如专注于遵循良好的工程原理,使代码易于阅读和理解,以及使用具有生产力和帮助性的语言的特性,而不管它们是否足够"OOP"。


    Boolean variables should be used only for boolen logic.In all other cases,use listations.(P)Boolean variables are used to store data that can only take on two possible values.The problems that arise from using them are frequently overlooked:好的,好的。

    • Programmers often cannot correctly identify when some piece of data should only have two possible values
    • The people who instruct programmers what to do,such as program managers or whoever writes the specs that programmers follow,often cannot correctly identify this either
    • 即使一个数据的皮耶塞是正确的识别,因为只有两个可能的国家,保证可能不在未来。

    (P)In these cases,using boolen variables leads to confusing code that can often be prevented by using listations.好的,好的。(P)例如好的,好的。(P)说一个程序是为一辆只有汽车和卡车的汽车编写软件。The programmer develops a thorough model of the business requirements for his software.了解到只有几类汽车焊是汽车和卡车,他更正了自己的身份,即他可以使用一种车辆内部的可变因素来表示车辆是一辆车还是一辆卡车。好的,好的。字母名称(P)The software is written so when EDOCX1 plus 0 is true a vehicle is a truck,and when EDOCX1 plus 0 is false the vehicle is a car.This is a simple check performed many times through the code.好的,好的。(P)没有麻烦的一切工作,直到有一天,当汽车载载着汽车的另一个死亡。The programmer has to update the software so it works correctly considering the dealership's business has changed.现在需要确定一辆车是一辆车,一辆卡车,还是一辆摩托车,三个可能的国家。好的,好的。(P)这项方案应如何执行?EDOC X1是一个波莉变量,所以它只能拥有两个国家。他可以从一个布尔到一些其他类型的国家,但这将打破现有的物流,并可能不是兼容的。The simpless solution from the programmer's point of view is to add a new variable to represent whether the vehicle is a motorcycle.好的,好的。字母名称(P)The code is changed so that when EDOCX1 plus 0 is true a vehicle is a truck,when EDOCX1 plus 4 is true a vehicle is a motorcycle,and when they're both false a vehicle is a car.好的,好的。(P)问题好的,好的。(P)有两个大问题与此解决:好的,好的。

    • The programmer wants to express the type of the vehicle,which is one idea,but the solution used two variables to do so.一些未与《守则》取得一致的因素将是,如果方案拟订者使用的只是一个变量,而该变量又具体说明了第六个实体。
    • 解决这一问题的办法是,增加一个新的Boolean并不意味着这一方案有任何改进之处,以便处理今后出现的这种情况。如果死亡之星堵住了公共汽车,方案将不得不通过增加新的Boolean而扭转所有这些步骤。

    (P)这不是开发者的失误,因为企业要求修改其软件,要求它审查现有的守则。但是,使用Boolean变量,首先是他制定的法典缺乏灵活性,难以适应不了解未来的要求("未来——方案")。When he implemented the changes in the quickest way,the code because harder to read.使用布尔变量是最后一个过早优化。好的,好的。(P)解决好的,好的。(P)在第一个地方使用一个清单将有助于预防这些问题。好的,好的。字母名称(P)To accommodate motorcycles in this case,all the programmer has to do is add EDOCX1 universal 5 to EDOCX1 pensional 6,and add new logic to handle the motorcycle cases.没有新的变量需要补充。Existing logic should't be disrupted.还有一些人对《守则》不感兴趣,他们可以轻松地理解《车辆类型》是如何被破坏的。好的,好的。(P)Cliff Notes好的,好的。

    不要使用只能存储两个不同状态的类型,除非您绝对确定两个状态总是足够的。如果将来可能需要两个以上状态,即使布尔值满足现有要求,也可以使用枚举。好的。好啊。


    我经常在ASP.NET/VB.NET中工作,发现ViewState绝对是一场噩梦。它默认在大多数字段上启用,并在每个网页的开头产生大量编码数据。页面上控件的大小越大,viewstate数据就越大。大多数人并不关注它,但它创建了一组大数据,这些数据通常与页面上执行的任务无关。如果未使用所有ASP控件,则必须手动禁用该选项。要么就是这样,要么对一切都有自定义控件。

    在我工作的一些页面上,有一半的页面是由viewstate组成的,这真的很遗憾,因为有更好的方法可以做到这一点。

    就语言/技术观点而言,这只是我能想到的一个小例子。这可能是有争议的。

    顺便说一下,您可能希望编辑此线程上的投票,它可能会受到一些影响;)


    你并不总是需要一个数据库。

    如果您需要存储少于几千个"东西",并且不需要锁定,那么平面文件可以工作,并且在很多方面都更好。它们更便于携带,您可以在紧急情况下手动编辑。如果您的数据和业务逻辑之间有适当的分离,那么如果您的应用程序需要它,您可以很容易地用数据库替换平面文件。如果您考虑到这一点来设计它,它会提醒您在数据和业务逻辑之间有适当的分离。

    ——骨形态发生蛋白B


    C(或C++)应该是第一个编程语言

    第一种语言不应该是简单的语言,它应该是建立学生的思想,为严肃的计算机科学做准备的语言。C是完美的,它迫使学生思考记忆和所有低级的东西,同时他们可以学习如何构造他们的代码(它有函数!)

    C++有一个额外的优点:它真的很烂:这样学生就可以理解为什么人们必须提出Java和C语言。


    这里有一个在我看来已经很多年了,但对每个人来说都是一个诅咒:在"发布"版本中用C(或C++)断言和EDCOX1×0""断绝几乎总是一个错误。(唯一的例外是时间或空间惩罚是不可接受的)。

    理由:如果断言失败,程序将进入一种状态

    • 从未测试过
    • 开发人员无法为
    • 开发人员已经有效地证明了不可想象。

    然而,不知何故,"行业最佳实践"是,当与客户的数据进行实时运行时,事情应该变得混乱,并希望获得最佳结果。


    所有源代码和注释应使用英语编写。

    用英语以外的语言编写源代码和/或注释会降低代码的可重用性,并且如果您不理解它们所用的语言,则更难进行调试。

    SQL表、视图和列也是如此,尤其是在使用缩写时。如果不缩写,我可以在线翻译表/列的名称,但是如果缩写了,我所能做的就是选择并尝试解密结果。


    "邪恶"这个词在StackOverflow和Simulator论坛上被滥用和滥用。

    使用它的人想象力太少。


    更新的语言和托管代码并不能使一个糟糕的程序员变得更好。


    如果以后要节省3倍的时间,那么只需编写一个抽象。

    我看到人们有时会写下这些疯狂的抽象,我想,"为什么?"

    除非抽象真的能节省你以后的时间,或者它能节省维护你代码的人的时间,否则人们似乎越来越多地在写意大利面代码。


    我真的不喜欢人们告诉我使用getter和setter,而不是在您应该能够同时获取和设置类变量时公开变量。

    如果要改变对象中的变量,我完全同意这一点,因此您不会得到这样的结果:a.b.c.d.e=某物;但我宁愿使用:a.x=某物;然后是a.s e t x(某物);我认为a.x=某物;实际上更容易阅读,更漂亮,然后在同一个示例中设置/获取。

    我看不出原因:

    空集(t x){-> x=x;}

    T gx(){返回X;}

    这是更多的代码,你一次又一次地做这些事情的时间会更多,而且只会让代码更难阅读。


    最好的代码通常是你不写的代码。作为程序员,我们希望通过编写一些很酷的方法来解决每个问题。只要我们能解决一个问题,并且仍然给用户80%的想要的东西,而不引入更多的代码来维护和测试,我们就为waaaay提供了更多的价值。


    类应该适合屏幕。

    如果你必须使用滚动条来查看你所有的班级,那么你的班级太大了。

    代码折叠和微型字体都在作弊。


    我通常都有相当大的争议性、强烈和强烈的意见,所以这里只有几个:

    "因为我们是微软的机构/合作伙伴/专家"从来都不是一个有效的论据。

    我现在工作的公司首先将自己定位为微软的专家。所以前面提到的论点被抛到了相当多的地方,我还没有看到它有效的上下文。

    我不明白为什么要在每个适用的领域推广微软的技术和产品,超越客户和员工的满意度,以及通用的语用学。

    这只是我对软件业政治深深仇恨的基石。

    Moss(Microsoft Office SharePoint Server)真是一派胡言。

    有点像第一个观点,但我真的认为莫斯,因为它是,应该被赶出市场。它花费了上百万的人去许可和建立网络标准,让开发者们非常不高兴。我还没有看到一个莫斯项目有一个总体的积极成果。

    然而,一个客户一次又一次地接近我们,要求我们提供moss解决方案。


    开发人员不应该测试自己的软件

    开发和测试是两个截然相反的学科。开发就是建设,测试就是拆除。有效的测试需要一种特定的心态和方法,在这种心态和方法中,您试图发现开发人员的错误,发现他们的假设中的漏洞,以及逻辑中的缺陷。大多数人,包括我自己,都无法将自己和他们自己的代码置于如此严格的审查之下,仍然保持客观。


    如果你想写一个好的软件,那就离开你的电脑。

    去和终端用户以及那些想要和需要软件的人一起玩。只有通过它们,您才能理解您的软件需要完成什么,以及它需要如何做到这一点。

    • 询问他们对现有流程的爱与恨。
    • 询问他们的过程的未来,它将走向何处。
    • 出去看看他们现在使用什么,找出他们的使用模式。您需要满足并匹配他们的使用期望。看看他们还经常使用什么,特别是如果他们喜欢并且能够有效地使用它。匹配。

    最终用户不会告诉RAT你的代码有多优雅,或者它使用什么语言。如果它对他们有用,他们喜欢使用它,你就赢了。如果这不能使他们的生活变得越来越好——他们恨它,你就输了。

    穿着鞋子走一英里-然后去写你的代码。


    我有一些……每件事都有例外,所以这些不难,也不快,但在大多数情况下确实适用。

    没有人关心你的网站是否有效,XHTML是否严格,是否符合标准,或者是否有W3C徽章。

    它可能会从其他Web开发人员那里为您赢得一些高分,但是其他浏览您的站点的人可能会给您一个垃圾,不管您是否验证了您的代码。绝大多数网络冲浪者都使用IE或火狐,而且由于这两种浏览器都能容忍非标准、非价格、无效的HTML,所以你真的不需要担心它。如果你为汽车经销商、技工、电台、教堂或当地的小企业建立了一个网站,你认为这些企业中有多少人关心有效的HTML?我冒昧地猜测它很接近0。

    大多数开源软件都是无用的、过于复杂的废话。

    让我安装一下我找到的这个好的OSS。看起来它应该做我想要的!哦,等等,首先我得安装另一个窗口管理器。好啊。然后我需要得到这个命令行工具并将其添加到我的路径中。现在我需要x、y和z的最新运行时。现在我需要确保这些进程正在运行。好的,很棒…所有配置。现在让我学习一套全新的命令来使用它。哦,酷,有人为它建立了一个图形用户界面。我想我不需要学习这些命令。等等,我需要这个库来让GUI工作。现在就下载吧。好了,现在开始工作了……废话,我弄不出这个糟糕的用户界面。

    听起来熟悉吗?OSS是一个非常复杂的系统,因为它的复杂度很高,安装起来很复杂,你需要成为一个专家才能完成,而且大多数人都不知道该怎么做。如此之多的项目被搁置一边,其他项目则是如此之小,以至于很少有人会使用它们,而一些体面的项目(Flowplayer、OScommerce等)的源代码过于复杂和膨胀,以至于无法编辑源代码。您可以编辑源…如果你能找出400个文件中哪一个包含需要修改的代码。当你得知这400个问题时,你真的遇到了麻烦。


    程序设计还处于初级阶段。

    尽管多年来编程语言和方法发展得很快,但我们仍有很长的路要走。标志清晰:

  • 语言文档随意地在Internet上传播(StackOverflow在这里有帮助)。

  • 语言不能在不破坏先前版本的情况下从语法上进化。

  • 调试通常还是用printf完成的。

  • 语言库或其他形式的大规模代码重用仍然非常罕见。

  • 显然,所有这些都在改善,但如果我们都能同意这是开始而不是结束,那就太好了。


    新的Web项目应该考虑不使用Java。

    我用Java做Web开发已经超过10年了。起初,与现有的替代方案相比,这是朝着正确的方向迈出的一步。现在,有比Java更好的选择。

    这确实只是解决问题的"魔锤"方法的一个具体案例,但这是一个非常痛苦的案例。


    开发人员都是不同的,应该这样对待。

    开发人员不适合放在盒子里,也不应该被这样对待。解决问题的最佳语言或工具与开发人员的关系与解决问题的细节同样重要。


    离塞尔科远点!!!!!

    网址:http://www.dbdebunk.com/page/page/857309.htm

    我认为使用代理主键比使用"自然"主键更有意义。

    @ocdecio:fabian pascal给出了(在他书的第3章数据库管理实践问题中,在你链接的页面的第3点中引用)作为选择稳定的关键的标准之一(它总是存在并且不会改变)。当自然键不具有这样的属性时,出于明显的原因,必须使用代理键,您在注释中对此进行了提示。

    你不知道他写了什么,你也不想去查,否则你会发现你确实同意他的观点。这里没有什么争议:他说"不要武断,要根据情况调整一般的指导方针,最重要的是,要用你的大脑,而不是武断的/食谱/古鲁的话"。


    过度使用面向对象编程

    有时候最好的答案就是简单的答案。


    SQL本来可以而且应该做得更好。由于最初的规范是有限的,多年来,不同的供应商一直在向不同的方向扩展该语言。为MS-SQL编写的SQL与Oracle、IBM、MySQL、Sybase等的SQL不同。其他严重的语言(以C++为例)被仔细地标准化,这样在一个编译器下编写的C++通常会在另一个编译器下编译。为什么不能更好地设计和标准化SQL?

    作为一种浏览器显示语言,HTML是一种严重失败的选择。我们花了数年时间通过css、xhtml、javascript、ajax、flash等对其进行扩展,以生成一个可用的UI,结果仍然不如您的基本厚客户端Windows应用程序好。另外,一个称职的Web程序员现在需要知道三种或四种语言才能创建一个合适的用户界面。

    哦,是的。匈牙利符号是令人憎恶的。


    大多数咨询程序员都很差劲,不应该允许他们编写生产代码。

    我想大概60%或更多


    大多数程序员都不擅长编程

    (你说的是"有争议的")。

    我坐在家里的办公室里,思考着一些编程问题,最后在书架上看到了我的"全谱只读存储器拆卸"副本,我想:

    "今天有多少程序员可以编写频谱ROM中使用的代码?"

    对于不熟悉它的人来说,频谱有一种基本的编程语言,可以做简单的二维图形(直线、曲线)、排序文件IO和浮点计算,包括转换函数,所有这些都是在16K的z80代码中完成的(一个<5MHZ的8bit处理器,没有fpu或整数乘法)。今天的大多数毕业生很难写出这么小的"你好世界"节目。

    我认为问题在于,能够做到这一点的程序员的绝对数量几乎没有改变,但以百分比计算,它很快就接近于零。这意味着,随着越来越多的程序员进入该领域,正在编写的代码的质量正在下降。

    在我目前工作的地方,有七个程序员,包括我自己。其中,我是唯一一个通过阅读博客、书籍、这个网站等和在家里"娱乐"编程来保持最新状态的人(我妻子经常对此感到惊讶)。还有一个程序员热衷于编写结构良好的代码(有趣的是,他使用Delphi做了很多工作)并重构糟糕的代码。其他的,嗯,不太好。关于它,你可以把它们描述为"蛮力"程序员——将强制不适当的解决方案,直到它们按照一种方式工作(例如,使用带有重复数组的C数组。调整大小以动态添加项,而不是使用列表)。

    现在,我不知道我现在所在的地方是否是典型的,尽管从我以前的职位上我可以说是典型的。有了事后诸葛亮的好处,我可以看到一些对任何项目都毫无帮助的常见模式(缺乏对代码的同行评审)。

    所以,7个程序员中有5个是垃圾。

    斯基兹


    应弃用大于运算符(>,>=)

    我试着用小于大于的优先顺序编码了一段时间,结果还是卡住了!我不想回去,事实上,我觉得在这种情况下,每个人都应该按我的方式去做。

    考虑常见的数学"范围"符号:0<=i<10

    这在代码中很容易理解,并且您已经习惯了看到这样的习惯用法:变量在中间重复,中间由&;&;连接:

    1
    2
    3
    4
    if (0 <= i && i < 10)
        return true;
    else
        return false;

    一旦你习惯了这种模式,你就永远不会看到愚蠢的样子

    1
    2
    if ( ! (i < 0 || i >= 9))
        return true;

    同样的方法。

    由于操作数趋向于非递减顺序,长的关系序列变得更容易处理。

    此外,对EDCOX1(0)的偏好体现在C++标准中。在某些情况下,operator=是用它来定义的!(如<代码> >!(A<B<B)


    编程任务只有在它不可能的时候才有趣,直到你确信自己能够成功地解决它为止。

    我想,这就是为什么我的许多项目最终都在一个名为"To_Be_Continued"的文件夹中完成了一半。


    每个开发人员在开始构建电子系统之前,应该花几个星期甚至几个月的时间开发基于纸的系统。他们也应该被迫使用他们的系统。

    开发一个好的基于纸张的系统是一项艰巨的工作。它迫使你考虑人性(繁琐的过程会被忽略,过于复杂的过程往往会崩溃),并教会你欣赏简单的价值(新的工作放在这个托盘里,QA的工作放在这个托盘里,存档放在这个盒子里)。

    一旦你学会了如何在纸上建立一个系统,建立一个有效的计算机系统通常会容易得多——人们实际上想要(并且能够)使用这个系统。

    我们开发的系统并不是由一支训练有素的自动化部队来操控的;真正的人使用它们,真正的人接受管理者的培训,管理者也是真正的人,他们没有太多时间来浪费培训时间来训练他们如何跳出你的圈套。

    事实上,对于我的第二点:

    应该要求每个开发人员运行一个交互式培训课程,向用户展示如何使用他们的软件。


    不应允许非开发人员管理开发人员。

    更正:没有开发经验的员工不允许管理开发人员。


    软件就像卫生纸。你花在上面的钱越少,屁股上的疼痛就越大。

    也就是说,外包很少是个好主意。

    我一直认为这是真的,但直到最近我才真正知道它的程度。我最近一直在"维护"(读作"修复")一些离岸代码,这是一个巨大的混乱。如果是内部开发的话,我们公司的成本很容易超过差异。

    企业之外的人对你的商业模式天生就不太了解,因此对任何在你的企业内工作的系统进行编程都不会有那么好的工作。而且,他们知道他们不必支持它,所以除了半途而废,没有别的动机。


    估计是给我的,不是给你的

    作为开发线经理,评估对我来说是一个有用的工具,可以计划我的团队正在进行的工作。

    它们不是在特定日期交付功能的承诺,也不是推动团队更努力工作的一根棍子。

    imho如果你强迫开发人员承诺评估,你会得到最安全的数字。

    例如

    I think a feature will probably take me around 5 days. There's a small chance of an issue that would make it take 30 days.

    If the estimates are just for planning then we'll all work to 5 days, and account for the small chance of an issue should it arise.

    However - if meeting that estimate is required as a promise of delivery what estimate do you think gets given?

    如果开发人员的奖金或工作保障取决于是否达到预期,你认为他们给出的是最准确的猜测还是他们最确定会遇到的猜测?

    我的这一观点与其他管理层存在争议,并被解释为我试图通过迂回的方式摆脱适当的目标,或我试图掩盖糟糕的绩效。每次都很难卖出,但我已经习惯了。


    随机收集库克的格言…

    • 最难学的语言是你的第二语言。

    • 最难学习的操作系统是您的第二个操作系统,尤其是如果您的第一个操作系统是IBM大型机。

    • 一旦你学会了几种看似不同的语言,你终于意识到所有的编程语言是相同的-只是语法上的细微差别。

    • 虽然一个人在没有学会任何装配的情况下都能很好地生产和销售,没有它,任何人都不会对计算有本质的理解。

    • 对于那些不太了解的程序员来说,调试器是最后的避难所。他们一开始在做什么。

    • 如果不利用硬件内存管理,任何操作系统都不会稳定。

    • 低级系统编程比应用程序编程容易得多。

    • 有最喜欢的语言的程序员只是在玩。

    • 首先编写用户指南!

    • 政策和程序适用于那些缺乏主动性的人。

    • (承包商的信条):告诉他们需要什么。给他们想要的。确保支票清零。

    • 如果你觉得编程不好玩,那就离开它,或者接受它,尽管你可能会生活在这样的环境中,你永远不会超过平均水平。

    • 就像那些老家伙必须学习.NET方法名一样,你必须学会图书馆的电话。但是没有什么新的。程序员的生活就是不断适应不同的环境,你的腰带上挂的工具越多,你就越是多才多艺、适销对路。

    • 你可能会在一开始就用小代码块来尝试一些想法,但是,一般来说,在你知道整个程序或者应用程序将被布局,你知道整个工作将完全一样广告。对于大多数至少具有一定复杂性的项目,我通常会把60%到70%的时间花在预先渗透思想上。

    • 理解编程与语言几乎没有关系,与算法也没有任何关系。所有那些漂亮的极客,都有多年来人们想出的令人难忘的首字母缩写。只是对实现cat剥皮的不同方式。当你把所有的Oopines、Radology、Development Methodology 37和Best Practice 42,您仍然需要处理具有以下基本构造块:

      • 作业
      • 条件句
      • 迭代
      • 控制流
      • 输入输出

    一旦你真的能把自己包裹起来,你最终会达到你的目的。从编程的角度来看,编写清单应用程序汽车零部件公司、图形实时TCP性能分析仪、数学模型一个恒星核心,或一个约会日历。

    • 初学者使用小代码块工作。当他们获得经验时,它们使用越来越大的代码块。当他们获得更多的经验时,他们使用小代码块。


    我不知道这是否真的有争议,但是如何处理:方法和函数名是您的代码可以拥有的最好的注释;如果您发现自己在写注释,把您正在注释的代码变成一个函数/方法。

    这样做有一个令人愉快的副作用,那就是迫使你很好地分解你的程序,避免发表与现实不同步的评论,给你一些你可以改进代码库的东西,给你的代码留下新鲜的柠檬味。


    90%的程序员都是非常糟糕的程序员,实际上我们所有人都没有工具来评估我们当前的能力水平(尽管我们通常可以回顾并认识到我们过去的糟糕程度)

    我不想发表这篇文章,因为这会激怒所有人,我不是真的想得到一个负分或者其他什么,而是:

    a)这不是问题的关键,而且

    b)这条线索中的大多数"答案"都证明了这一点。

    前几天我听到了一个很好的类比:编程能力的变化至少和运动能力一样大。我们中有多少人可以加入一个专业团队,真正提高他们的机会?


    复制/粘贴是万恶之源。


    编码不是打字

    编写代码需要时间。大多数时候,在编辑器窗口中,您只是在查看代码,而不是实际键入。不是经常删除,而是经常删除您所写的内容。或者从一个地方搬到另一个地方。或重命名。

    如果你长时间不停地敲打键盘,说明你做错了什么。

    推论:每天写的代码行数并不是程序员生产力的线性度量,因为一天写100行的程序员很可能比写20行的程序员更好,但写5000行的程序员肯定是一个糟糕的程序员。


    不要在数据库中使用存储过程。

    它们最初很好的原因——安全性、抽象性、单一连接——都可以在中间层使用集成了许多其他优势的ORM来完成。

    这一点肯定有争议。每次我提起它,人们都会把我撕成碎片。


    这一个主要是网络相关的,但是…

    为网页布局使用表格

    如果我正在开发一个需要压缩性能的大型站点,我可能会考虑它,但是没有什么比表更容易让我在浏览器上看到一致性。我开发的大多数应用程序都是为大约100-1000个用户开发的,一次最多可能有100个用户。表的额外膨胀不会以任何方式杀死我的服务器。


    递归最糟糕的是递归。


    在允许初级程序员实际编写或修改代码之前,他们应该被指派做几个月的对象/模块设计和设计维护。

    太多的程序员/开发人员在不了解好的设计元素的情况下达到了5年和10年的目标。当他们想要超越仅仅编写和维护代码的范围时,这可能是一个严重的问题。


    像SharePoint这样的企业内部网框架让我觉得整个企业界都是一只头埋在沙子里的巨大鸵鸟。

    我不仅在这里谈论Moss,我还与其他一些公司内部网产品合作过,而且绝对没有一个产品是伟大的,但是SharePoint(Moss)是迄今为止最糟糕的。

    • 这些系统中的大多数并不容易弥合内部网和因特网之间的鸿沟。所以作为一个远程工作者,你必须进入VPN。外部客户只是没有机会直接掌握你的内部信息。当然,这个价格可以定为美元。
    • 搜索能力总是令人遗憾的。很多时候其他部门根本不知道信息就在外面。
    • 信息碎片,人们开始抵制工作流或回复电子邮件
    • SharePoint开发是世界上最痛苦的开发形式。没有什么比SharePoint更差劲的了。我见过一些开发人员在和Moss一起工作一年多后打算退出它。
    • 无论开发人员多么讨厌Moss,无论最基本的项目需要多长时间才能推出,无论结果看起来多么新手,无论内容多么不可搜索和分散:

    每个人仍然继续使用和购买SharePoint,管理者仍然努力假装它不是撒旦的产物。

    微格式

    使用最初为可视化布局设计的CSS类-现在被分配给可视化和上下文数据是一种黑客攻击,充满了歧义。不是说功能不应该存在,而是修复该死的基础语言。HTML不是被黑客用来生成XML的,而是出现了XML语言。现在我们有了这些渴望脚本的孩子们,他们用黑客的HTML和CSS来做一些原本不该做的事情,这仍然很好,但我希望他们能把这些事情保持在自己的水平上,而不是制定一个标准。只不过是一些上流的屠夫!


    使用存储过程

    除非您正在编写由不可重用的SQL查询组成的大型过程函数,否则请将数据库的存储过程移动到版本控制中。


    编码是一门艺术

    有些人认为编码是一门艺术,另一些人则认为编码是一门科学。

    "科学"派认为,作为一种情况下获取最优代码的目标,编码就是研究如何获得最优代码的科学。

    "艺术"派认为,有很多方法可以获得一种情况下的最佳代码,这个过程充满了主观性,根据自己的技能和经验明智地选择是一种艺术。


    微软并没有很多人说的那么糟糕。


    python方法声明中的显式self是糟糕的设计选择。

    方法调用得到了句法上的优势,但声明没有。这是一个泄漏的抽象(按设计!)这会导致恼人的错误,包括运行时错误,在报告的参数数目中有一个明显的错误。


    这个怎么样:

    垃圾收集器实际上会损害程序员的工作效率,使资源泄漏更难查找和修复。

    注意,我说的是一般的资源,而不仅仅是记忆。


    让软件可配置是一个坏主意。

    可配置软件允许最终用户(或管理员等)选择太多的选项,这些选项可能不是全部都一起测试过(或者更确切地说,如果有多个非常小的数字,我可以保证不会进行测试)。

    因此,我认为配置硬编码(但不一定要避开常量等)的软件是一个好主意。使用合理的默认值运行,并且不允许更改它们。

    一个很好的例子是Google Chrome上的配置选项数量——但是,这可能仍然太多了:)


    我有争议的意见?Java并不吸引人,但Java API确实如此。为什么Java库坚持很难完成简单的任务?为什么他们不修复API,而是创建框架来帮助管理样板代码?这种观点可以适用于任何需要10行或更多行代码才能从文件中读取行的语言。


    任何有足够能力的库都太复杂而不能使用,任何简单到可以使用的库都缺乏成为一个好的通用解决方案所需的功能。

    我经常遇到这种情况。使用起来如此复杂的详尽的库,我把我的头发撕了下来,而简单易用的库却不能完全满足我的需要。


    微软应该停止支持任何与Visual Basic有关的东西。


    创建类似于患有疯牛病的椒盐卷饼的UML图的能力实际上不是一种有用的软件开发技能。

    绘制代码图的关键是可视化连接,以查看设计的形状。但是,一旦你通过了一个相当低的复杂程度,视觉化就太多了,无法在精神上进行处理。仅当您坚持使用直线时,以图形方式建立连接才是简单的,这通常会使图表比沿着主要方向巧妙地分组和布线的连接更难阅读。

    仅在广泛的交流目的中使用图表,并且只有当它们被理解为谎言时才使用图表。


    递归很有趣。

    是的,我知道这可能是对堆栈空间的无效使用,以及所有的爵士乐。但有时,与迭代算法相比,递归算法非常简单。当我可以在某个地方偷偷地使用递归函数时,我总是感到有点高兴。


    大多数开发人员都不知道

    是的。。你走吧。我已经说过了。我从我个人认识的所有开发人员那里发现了这一点。事实上,只有一把是好的。只有少数人知道应该测试代码…面向对象的开发方法实际上对您有所帮助。有人获得了开发人员的头衔,这让我非常沮丧,实际上他们所能做的就是复制粘贴一点源代码,然后执行它。

    总之…我很高兴像StackOverflow这样的计划已经开始。这有利于开发人员思考。有更好的方法吗?我做得对吗?也许我可以用这种方法来加快速度,等等…

    但是没有…大多数开发人员只是学习他们的工作需要的一种语言,并坚持使用它,直到他们自己变老,脾气暴躁,不知道发生了什么。他们只会得到一大笔薪水,因为他们比你大。

    啊…在IT界,生活是不公平的,将来我会采取措施忽视这些人。万岁!


    正在开发的绝大多数软件在收集需求时不涉及最终用户。

    通常只有一些经理提供"需求"。


    方法/函数参数的前提条件应该是语言的一部分,而不是程序员总是检查它。


    对于一个好的程序员来说,语言不是问题。

    这可能不是很有争议,但我听到很多其他程序员抱怨"他们为什么不都使用Delphi?""C·C吮吸","我会改变公司,如果他们强迫我使用Java"等等。我认为一个好的程序员是灵活的,能够用他一生中可能学过的任何编程语言编写好的程序。


    代码生成错误

    我讨厌那些要求您将代码生成(或复制粘贴)用于简单事物的语言,比如JavaBeans及其所有getter和setter。

    C的自动属性是朝着正确的方向迈出的一步,但是对于具有字段、属性和构造函数参数的优秀DTO,仍然需要大量的冗余。


    Web应用程序太糟糕了

    我的网络连接非常慢。我对几乎所有非谷歌网站的体验,至少令人沮丧。为什么没有人再写桌面应用程序了?哦,我明白了。没有人愿意为学习操作系统如何工作而烦恼。至少,不是窗户。上一次你必须处理WM_PAINT时,你的头爆炸了。创建一个工作线程来执行一项长任务(我的意思是,用Windows的方式执行)完全超出了您的能力。什么叫回拨?哦,天哪!

    垃圾收集很糟糕

    不,实际上不是。但是它让程序员像其他东西一样吃力。在大学里,他们教给我们的第一门语言是视觉基础(原版)。之后,还有另一个过程,老师假装他们教我们C++。但损失已经造成了。没有人真正知道如何使用这个深奥的关键词delete做到了。在测试了我们的程序之后,我们或者得到了无效的地址异常,或者内存泄漏。有时候,我们两个都有。在我的1%的教职员工中,只有一个人能自己管理自己的记忆(至少他假装),而且他在写这篇文章。其余的用vb.net编写程序,根据定义,这是一种糟糕的语言。

    动态打字糟透了

    当然,除非您使用的是汇编程序(这是一种值得称赞的动态类型)。我的意思是,动态的解释语言所带来的开销让它们很糟糕。别再愚蠢地认为不同的工具适合不同的工作了。C语言几乎适用于所有的东西(它速度快、功能强大、可移植),当它不够快(不够快)时,总是有内联汇编。

    我可能会想出更多的咆哮,但那将是以后,而不是现在。


    vb6既可用于善也可用于恶。在编码过于复杂的时代,它是一个快速的应用开发环境。

    我过去很讨厌vb,但我仍然嘲笑vb.net(可能是开玩笑的),因为我不喜欢经典的vb,但是在它的时代,没有什么能比得上它完成工作。


    需求分析、规范、设计和文档几乎永远都不适合"模板"。从一个空白文档开始,并开始输入"我将以这样的方式解释这一点,即如果我死了,其他人阅读了此文档,他们将知道我知道的一切,并且EE和"现在理解",然后从那里开始组织,让章节标题和类似内容自然地发展,并适合您指定的任务,而不是局限于某些企业或学校对您的文档应该是什么样子的想法。如果你必须做一个图表,而不是使用别人的正式的、不可理解的系统,你最好只是画一个有意义的图表,上面有一个清晰的图例,它实际上指定了你试图指定的系统,并传达了开发人员在另一端(通常是你,几年后)需要的信息。接收。

    [如果你必须这样做,一旦你写下了真正的文档,你可以经常把它放进你的组织强加给你的任何模板中。不过,您可能会发现自己必须添加章节标题和重复材料。]

    这些类型文档的唯一时间模板有意义的是,当您有大量的任务时,这些任务在性质上非常相似,只是在细节上有所不同。"编写一个程序,允许通过此调制解调器组进行一次性远程登录访问,使用C-Kermit驱动终端连接nexus,"为容量使用生成历史趋势和预测报告","使用此库为所有报告提供传真功能","为2000年问题修复此代码","向此选项卡添加数据库触发器""填充由第三方供应商提供给我们的软件产品"不能全部用同一模板描述,不管人们怎么想。而且,我的大学课程试图教给我和我的同学的要求和设计图表技术不能用来指定一个简单的计算器程序(每个人都知道)。


    编程既不是艺术也不是科学。这是一门工程学科。

    这不是艺术:编程当然需要创造力。这不能使它成为艺术。代码的设计和编写是为了正常工作,而不是为了情感上的移动。除了空白,出于美观的原因更改代码会破坏代码。虽然代码可以是美丽的,但艺术不是主要目的。

    这不是科学:科学和技术是不可分割的,但是编程是技术范畴。编程不是系统的学习和观察,而是设计和实现。

    这是一门工程学科:程序员设计和构建东西。优秀的程序员设计功能。他们了解不同实现选项的权衡,并选择适合他们正在解决的问题的方案。

    我敢肯定有人会喜欢解析单词,将艺术和科学的定义扩展到只包含编程或将工程限制在机械机器或硬件上。查字典。另外,"计算机编程艺术"是对艺术的一种不同用法,它意味着一种技能或工艺,如"对话艺术"中所说。编程的产品不是艺术。


    有时跳上流行音乐是可以的

    我厌倦了那些表现出"爷爷综合症"的人("你们这些孩子和你们新出现的测试驱动的发展"。过去十年中出现的每一项大技术都被吸干了。回到我的时代,我们写了真正的代码!"…你明白了)。

    有时流行的东西之所以流行是有原因的。


    如果你需要阅读手册,软件不够好。

    简单明了:—)


    大多数语言的拥护者制造了很多噪音。


    罗伯·派克写道:"数据占主导地位。如果您选择了正确的数据结构并组织得很好,那么算法几乎总是不言而喻的。数据结构而不是算法是编程的核心。"

    由于现在有数百万条记录中有任何重要的数据,我认为良好的数据建模是最重要的编程技能(无论是使用RDBMS,还是像SQLite、Amazon SimpleDB或Google Appengine数据存储之类的东西)。

    当所有的数据都存储在这样一个数据存储系统中时,不再需要复杂的搜索和排序算法。


    我的一个:

    长切换语句是您的朋友。真正地。至少在C。

    人们倾向于避免和劝阻他人使用长切换语句,因为它们是"不可维护的"和"具有糟糕的性能特性"。

    好吧,问题是在C中,switch语句总是自动编译为散列跳转表,所以实际使用它们是最好的方法?在性能方面,如果您需要简单的分支到多个分支。此外,如果案例语句是智能组织和分组的(例如按字母顺序),那么它们根本就不可管理。


    我认为,使用Try/Catch异常处理比使用简单的返回代码和相关的公共消息结构传递有用的错误消息更糟糕。

    用try/catch块乱丢代码不是解决方案。

    只是将异常传递到堆栈上,希望上面的内容可以做正确的事情,或者生成信息性错误不是解决方案。

    如果认为您有机会系统地验证适当的异常处理程序是否能够处理透明或不透明对象中可能出错的任何问题,那么这是不现实的。(还可以考虑后期绑定/外部库,以及随着系统的发展,调用堆栈中不相关函数之间不必要的依赖性)

    返回代码的使用很简单,可以很容易地系统地验证覆盖率,如果处理得当,将迫使开发人员生成有用的错误消息,而不是所有太常见的堆栈转储和模糊的I/O异常,这些异常对最终用户来说甚至是最有说服力的用户都是无意义的。

    ——

    我最后的反对意见是使用垃圾收集语言。别误会我……我在某些情况下喜欢它们,但一般来说,对于服务器/mc系统,它们在我看来没有位置。

    GC并不是一成不变的——即使是设计得非常好的GC算法,也可能基于依赖关系图中不明显的循环引用,对对象的依赖时间太长,甚至是永久性的。

    遵循几个简单模式和使用内存记帐工具的非GC系统不存在这个问题,但确实需要比GC环境在预先设计和测试中做更多的工作。这里的权衡是,在非GC中测试期间,内存泄漏非常容易被发现,而查找与GC相关的问题条件则是一个更困难的命题。

    内存是便宜的,但是当您泄漏昂贵的对象(如事务句柄、同步对象、套接字连接等)时会发生什么。在我的环境中,如果没有软件描述中的重要基础更改,您就无法想象您可以坐下来让语言为您担心这一点。


    每发现一个缺陷都要纠正。不仅仅是"严重性1"缺陷;所有缺陷。

    建立一种部署机制,使应用程序更新立即对用户可用,但允许他们选择何时接受这些更新。与用户建立直接的沟通机制,使他们能够报告缺陷,将他们的经验与更新联系起来,并提出改进建议。

    通过积极的测试,可以在创建缺陷的迭代过程中发现许多缺陷;立即纠正这些缺陷可以减少开发人员的中断,这是创建缺陷的重要因素。立即纠正用户报告的缺陷,就构成了一个建设性的社区,以产品改进取代产品质量成为谈话的主题。实施用户建议的与您的愿景和策略一致的改进会产生热情的福音传道者社区。


    汇编是最好的第一种编程语言。


    Web服务绝对糟糕,而且不是未来的发展方向。他们效率低下,无法保证按订单交货。Web服务不应该在同时写入客户机和服务器的系统中使用。它们主要用于米老鼠混搭类型的应用程序。它们绝对不应该用于任何面向连接的通信。

    由于Web服务是一个非常热门的话题,所以这种态度让我和同事们陷入了一些非常激烈的讨论中。任何要求使用Web服务的项目都注定要失败,因为很明显,它已经有了从管理层推下的荒谬需求。


    开发人员过度使用数据库

    开发人员通常将数据存储在一个DBMS中,该DBMS应该是代码或文件。我见过一个一列一行的表,它存储了"系统密码"(与用户表分开)。我见过数据库中存储的常量。我看到过数据库会让一个长大的编码员哭泣。

    有一种神秘的敬畏,冒犯的程序员对DBMS有一种敬畏——数据库可以做任何事情,但他们不知道它是如何工作的。DBA练习黑人艺术。它还允许责任转移:"数据库太慢","数据库做到了",其他借口也很常见。

    不加检查,这些编码人员继续在数据库中开发数据库,在系统中开发系统。(这个反模式有个名字,但我忘了它是什么。)


    最好的程序员在调试器中跟踪所有代码并测试所有路径。

    好。。。手术说有争议!


    一个好的开发人员需要知道的不仅仅是如何编码


    自己写是一个有效的选择。

    根据我的经验,当涉及到使用第三方代码来解决问题时,似乎有太多的热情。自力更生解决问题的选择通常不会让人产生误解。虽然我没搞错,但我不是在宣传从不使用图书馆。我要说的是:在您考虑使用的可能的框架和模块中,添加自己实现解决方案的选项。

    但为什么要编写自己的版本呢?

    • 不要重新发明轮子。但是,如果你只需要一块木头,你真的需要一个完整的车轮吗?换句话说,您真的需要OpenCV来沿轴翻转图像吗?
    • 妥协。为了能够使用特定的库,通常必须在设计上做出妥协。您必须包含的更改量是否值得您接受的功能?
    • 学习。你必须学会使用这些新的框架和模块。你要花多长时间?值得你花点时间吗?学习要比实施要花更长的时间吗?
    • 成本。并非每件事都是免费的。不过,这包括你的时间。考虑一下你将要使用这个软件会节省你多少时间,如果它值得的话,它的价格是多少?(还要记住,你必须花时间学习它)
    • 你是个程序员,不是…一个只把东西放在一起的人(对不起,没想到有什么机智的东西)。

    最后一点是有争议的。


    过早的优化并不是万恶之源!缺乏适当的计划是万恶之源。

    记得那把旧的海军锯子吗?

    Proper Planning Prevents P*ss Poor
    Performance!


    编程:这是一项有趣的工作。

    我似乎看到了两组通用的开发人员。那些不爱它,但又能干又有钱的人。另一个喜欢它的群体有点让人毛骨悚然。这似乎是他们的生活。

    我只是觉得这是一份报酬丰厚的工作,通常是有趣和有趣的。每天每分钟都有学习新事物的各种空间。我想不出我更喜欢的工作了。但这仍然是一项工作。我们会做出妥协,你所生产的产品也不会总是那么好。

    因为我的鼓手会在海滩上喝啤酒或和我的孩子们玩。


    汇编程序没有死

    在我的工作(拷贝保护系统)中,汇编程序编程是必不可少的,我曾与许多HLL拷贝保护系统合作过,只有汇编程序才给你真正的能力来利用代码中隐藏的所有可能性(如代码突变、低级的东西)。

    此外,只有汇编程序编程才能实现许多代码优化,查看任何视频编解码器的源代码,源代码是用汇编程序编写的,并优化为使用mmx/sse/sse2操作码。无论什么,许多游戏引擎都使用汇编程序优化的例程,甚至Windows内核也使用sse优化的例程:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    NTDLL.RtlMoveMemory

    .text:7C902CD8                 push    ebp
    .text:7C902CD9                 mov     ebp, esp
    .text:7C902CDB                 push    esi
    .text:7C902CDC                 push    edi
    .text:7C902CDD                 push    ebx
    .text:7C902CDE                 mov     esi, [ebp+0Ch]
    .text:7C902CE1                 mov     edi, [ebp+8]
    .text:7C902CE4                 mov     ecx, [ebp+10h]
    .text:7C902CE7                 mov     eax, [esi]
    .text:7C902CE9                 cld
    .text:7C902CEA                 mov     edx, ecx
    .text:7C902CEC                 and     ecx, 3Fh
    .text:7C902CEF                 shr     edx, 6
    .text:7C902CF2                 jz      loc_7C902EF2
    .text:7C902CF8                 dec     edx
    .text:7C902CF9                 jz      loc_7C902E77
    .text:7C902CFF                 prefetchnta byte ptr [esi-80h]
    .text:7C902D03                 dec     edx
    .text:7C902D04                 jz      loc_7C902E03
    .text:7C902D0A                 prefetchnta byte ptr [esi-40h]
    .text:7C902D0E                 dec     edx
    .text:7C902D0F                 jz      short loc_7C902D8F
    .text:7C902D11
    .text:7C902D11 loc_7C902D11:                           ; CODE XREF: .text:7C902D8Dj
    .text:7C902D11                 prefetchnta byte ptr [esi+100h]
    .text:7C902D18                 mov     eax, [esi]
    .text:7C902D1A                 mov     ebx, [esi+4]
    .text:7C902D1D                 movnti  [edi], eax
    .text:7C902D20                 movnti  [edi+4], ebx
    .text:7C902D24                 mov     eax, [esi+8]
    .text:7C902D27                 mov     ebx, [esi+0Ch]
    .text:7C902D2A                 movnti  [edi+8], eax
    .text:7C902D2E                 movnti  [edi+0Ch], ebx
    .text:7C902D32                 mov     eax, [esi+10h]
    .text:7C902D35                 mov     ebx, [esi+14h]
    .text:7C902D38                 movnti  [edi+10h], eax

    所以,如果你下次听到汇编程序死了,想想你看过的最后一部电影或者你玩过的游戏(以及它的版权保护)。


    代码就是设计


    不断测试

    您必须编写测试,并且必须首先编写它们。编写测试会改变编写代码的方式。它让你想一想你想让它实际做什么,然后你就跳进去写些什么,除了你想让它做什么以外,什么都能做。

    它也给你目标。看着你的测试变绿,你会有一点额外的信心,那就是你已经完成了一些事情。

    它还为编写边缘案例的测试提供了基础。因为您首先是针对测试编写代码的,所以您的代码中可能有一些钩子需要测试。

    没有理由不测试您的代码。如果你不这样做,你就是懒惰。我还认为您应该首先进行测试,因为这样做的好处超过了用这种方式编写代码所需的额外时间。


    有时您必须取消数据库的规范化。

    这一观点在大多数程序员中并不适用,但有时您必须牺牲一些东西,如规范化来提高性能。


    关系数据库对于Web应用程序来说很糟糕。

    例如:

    • 线程注释
    • 标签云
    • 用户搜索
    • 维护记录视图计数
    • 提供撤消/修订跟踪
    • 多步骤向导


    关系数据库系统将是最好的,因为切片面包…

    …当我们(希望)得到它们时,就是这样。SQL数据库太糟糕了,不好笑。

    我觉得有趣的是(如果是SAD的话)经过认证的DBA认为SQL数据库系统是关系数据库系统。对所述认证的质量有充分的说明。

    困惑的?读一下C.J.Date的书。

    编辑

    为什么称之为关系型,这个词是什么意思?

    现在,一个拥有强大(见鬼,任何)数学背景的程序员(或认证DBA,wink)是一个例外,而不是普通情况(我也是普通情况的一个实例)。带有表、列和行的SQL,以及被称为实体/关系建模的笑话,仅仅是对伤害的侮辱。难怪人们错误地认为关系数据库系统之所以被称为关系数据库系统是因为某些关系(外键?)在实体(表)之间是如此普遍。

    事实上,关系源于关系的数学概念,因此与集合理论和函数(在数学中,不是任何编程,意义上)密切相关。

    [http://en.wikipedia.org/wiki/finitary_relationship][2]:

    In mathematics (more specifically, in set theory and logic), a relation is a property that assigns truth values to combinations (k-tuples) of k individuals. Typically, the property describes a possible connection between the components of a k-tuple. For a given set of k-tuples, a truth value is assigned to each k-tuple according to whether the property does or does not hold.

    An example of a ternary relation (i.e., between three individuals) is:"X was-introduced-to Y by Z", where (X,Y,Z) is a 3-tuple of persons; for example,"Beatrice Wood was introduced to Henri-Pierre Roché by Marcel Duchamp" is true, while"Karl Marx was introduced to Friedrich Engels by Queen Victoria" is false.

    维基百科非常清楚:在一个SQL DBMS中,这样的三元关系将是一个"表",而不是一个"外键"(我可以随意重命名关系的"列":x=who,y=to,z=by):

    1
    2
    3
    4
    5
    6
    CREATE TABLE introduction (
      who INDIVIDUAL NOT NULL
    , to INDIVIDUAL NOT NULL
    , by INDIVIDUAL NOT NULL
    , PRIMARY KEY (who, to, by)
    );

    此外,它还将包含(可能包括其他行)此"行":

    1
    2
    3
    4
    5
    6
    7
    8
    9
    INSERT INTO introduction (
      who
    , to
    , by
    ) VALUES (
      'Beatrice Wood'
    , 'Henri-Pierre Roché'
    , 'Marcel Duchamp'
    );

    但不是这个:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    INSERT INTO introduction (
      who
    , to
    , by
    ) VALUES (
      'Karl Marx'
    , 'Friedrich Engels'
    , 'Queen Victoria'
    );

    关系数据库字典:

    relation (mathematics) Given sets s1, s2, ..., sn, not necessarily distinct, r is a relation on those sets if and only if it's a set of n-tuples each of which has its first element from s1, its second element from s2, and so on. (Equivalently, r is a subset of the Cartesian product s1 x s2 x ... x sn.)

    Set si is the ith domain of r (i = 1, ..., n). Note: There are several important logical differences between relations in mathematics and their relational model counterparts. Here are some of them:

    • Mathematical relations have a left-to-right ordering to their attributes.
    • Actually, mathematical relations have, at best, only a very rudimentary concept of attributes anyway. Certainly their attributes aren't named, other than by their ordinal position.
    • As a consequence, mathematical relations don't really have either a heading or a type in the relational model sense.
    • Mathematical relations are usually either binary or, just occasionally, unary. By contrast, relations in the relational model are of degree n, where n can be any nonnegative integer.
    • Relational operators such as JOIN, EXTEND, and the rest were first defined in the context of the relational model specifically; the mathematical theory of relations includes few such operators.

    And so on (the foregoing isn't meant to be an exhaustive list).


    我们在这里使用我们构建的模型-视图-控制器框架进行了大量的开发。我经常告诉我的开发人员我们需要违反MVC设计模式的规则,以使站点运行更快。对于开发人员来说,这是一个艰难的买卖,他们通常不愿意为任何事情牺牲设计良好的代码。但是在构建Web应用程序时,性能是我们的首要任务,因此有时我们必须在框架中做出让步。

    例如,视图层不应该直接与数据库通信,对吗?但是,如果您正在生成大型报告,应用程序将使用大量内存将数据传递到模型和控制器层。如果您有一个支持光标的数据库,它可以使应用程序从视图层直接访问数据库更快。

    绩效胜过发展标准,这是我有争议的观点。


    使用单元测试作为最后的手段来验证代码。

    如果您想验证代码是否正确,我更喜欢以下技术而不是单元测试:

  • 类型检查
  • 断言
  • 微不足道的可验证代码
  • 对于其他一切,都有单元测试。


    没有面向对象编程这样的东西。


    最佳实践是一种危险,因为它们要求我们用口号来代替思考。


    完成编码后,编写您的规范。(如果有的话)

    在我参与过的许多项目中,一开始就花了大量的精力用MicrosoftWord编写"规范"。这个过程在一次"签准"会议上达到了高潮,当时项目上的大人物都参与进来了,在那次会议之后,再也没有人看过这个文件。这些文档完全是在浪费时间,并不能反映软件的实际设计。这并不是说应用程序设计中没有其他有价值的工件。它们通常包含在索引卡、白板快照、鸡尾酒餐巾纸和其他类似的媒体上,这些媒体为应用程序的设计提供了一种时间表。这些通常是应用程序的真实规格。如果你要写一个Word文档(我不是特别说你应该)在项目结束时完成它。至少它可以准确地表示代码中所做的工作,并可能帮助一些人,比如QA团队或下一个版本开发人员。


    最简单的方法是最好的方法

    程序员喜欢解决假定的或推断的需求,这些需求会增加解决方案的复杂性。

    "我认为这段代码将成为性能瓶颈,因此我将添加所有这些额外的代码来缓解这个问题。"

    "我假设用户要做X,因此我将添加这个非常酷的附加功能。"

    "如果我让我的代码解决这个不需要的场景,这将是一个很好的机会,可以使用我一直感兴趣的新技术。"

    实际上,满足需求的最简单的解决方案是最好的。当出现新的需求或问题时,这也给了您最大的灵活性,使您能够将解决方案带向新的方向。


    javascript是一种"杂乱"的语言,但上帝保佑我,我喜欢它。


    不是真正的编程,但我不能仅仅为了它而忍受CSS布局。它具有反效果,令人沮丧,并且使维护成为浮动和利润率的噩梦,在这种情况下,更改单个元素的位置可能会使整个页面失去平衡。

    这绝对不是一个流行的观点,但是我在20分钟内就完成了我的表格布局,而CSS专家花费数小时来调整行高、边距、填充和浮动,只是为了做一些基本的事情,比如垂直居中一段。


    现代C++是一种优美的语言。

    好了,我说了。很多人真的讨厌C++,但老实说,我发现现代C++与STL /Boost风格编程在大多数时候都是一种非常有表现力、优雅和令人难以置信的语言。

    我认为大多数讨厌C++的人都是基于OO的坏经验。C++并不能很好地处理OO,因为多态通常依赖于堆分配的对象,C++没有自动垃圾收集。

    但是C++在真正的通用库和函数编程技术中真正闪耀,这使得构建难以置信的大型、高度可维护的系统成为可能。很多人说C++试图做所有的事情,但最终却什么也不做。我可能会同意它不像其他语言那样做OO,但是它比任何其他主流的基于C的语言做通用编程和函数式编程更好。(C++0X将进一步强调这一事实。)

    我还感谢C++如何让我在必要时获得低级,并提供对操作系统的完全访问。

    加上RAII。说真的。当我用其他基于C的语言编程时,我真的很怀念析构函数。(不,垃圾收集不会使析构函数无效。)


    大多数的面试问题都是毫无意义的。尤其是那些由程序员计算出来的。

    这是一个常见的情况,至少根据我和我的朋友的经验,在那里一个自大程序员,问你一些他花了几周时间搜索的棘手的问题。有趣的是,你回到家,一分钟内用谷歌搜索。就像他们经常试图用他们的精密武器打败你,而不是检查你是否是一个全面、务实的团队合作者。

    同样愚蠢的是,当你被要求提供高度可访问的基础知识时,比如:"哦,等等,让我看看你是否能在一张纸(sic!)上伪代码insert_name_here算法。".在申请高级编程工作时,我真的需要记住它吗?我应该有效地解决问题还是难题?


    我有争议的观点:OO编程被高估了很多(并且被视为一颗银弹),而它实际上只是工具箱中的另一个工具,没有更多!


    社交技能比技术技能更重要

    与那些不优秀的优秀程序员相比,拥有良好社会技能的优秀程序员将拥有更成功的执行者。


    有争议吗?我认为C++流使用< <和> >这一事实。我讨厌它。他们是轮班操作员。以这种方式重载它们显然是不好的做法。这让我想杀任何一个想到这是个好主意的人。GRRR


    工具、方法、模式、框架等不能代替经过适当培训的程序员。

    我厌倦了与那些认为最新的工具、方法、模式或框架是银弹的人(主要是经理)打交道,他们认为这将消除雇佣有经验的开发人员来编写他们的软件的需要。虽然,作为一个以拯救风险项目为生的顾问,我不应该抱怨。


    "评论是谎言"

    评论不会运行,很容易被忽略。最好用单元测试说明的清晰、重构的代码来表达意图。(当然是编写的单元测试TDD…)

    我们不写注释,因为它们冗长而晦涩,不知道代码中到底发生了什么。如果您觉得需要注释-找出代码中不清楚的地方,然后重构/编写更清晰的测试,直到不需要注释为止…

    …我从极限编程中学到了一些东西(当然,假设您已经建立了清理代码的团队规范…)


    例外应仅在真正例外的情况下使用。

    在我最近工作过的项目中,异常的使用似乎很猖獗。

    下面是一个例子:

    我们有拦截Web请求的过滤器。过滤器调用一个筛选程序,筛选程序的工作是检查请求是否有某些输入参数并验证这些参数。设置要检查的字段,抽象类确保参数不为空,然后调用由特定类实现的screen()方法来执行更多扩展验证:

    1
    2
    3
    4
    5
    6
    7
    public boolean processScreener(HttpServletRequest req, HttpServletResponse resp, FilterConfig filterConfig) throws Exception{          
                //
                if (!checkFieldExistence(req)){
                        return false;
                }
                return screen(req,resp,filterConfig);
        }

    checkFieldExistance(req)方法从不返回false。如果没有字段丢失,则返回true;如果字段丢失,则引发异常。

    我知道这是一个糟糕的设计,但问题的一部分在于,这里的一些架构师认为每次遇到意外情况时都需要抛出一个异常。

    另外,我知道checkFieldExistance(req)的签名确实会引发异常,这几乎是我们所有方法都会引发的——所以我没有想到该方法可能会引发异常而不是返回false。直到我把代码挖掘出来,我才注意到它。


    因为有上百个答案,我的答案可能最终会是未读的,但这是我最讨厌的。

    如果你是一个程序员,那么你很可能在网页设计/开发方面很差劲。

    对于程序员来说,这个网站是一个非常棒的资源,但是如果你在寻找XHTML/CSS帮助的话,它绝对是一个糟糕的地方。即使是这里的优秀Web开发人员也在分发指向90年代优秀资源的链接!

    当然,XHTML和CSS很容易学习。然而,你不仅仅是在学习一门语言!您正在学习如何很好地使用它,很少有设计师和开发人员能够做到这一点,更不用说程序员了。我花了很长时间才成为一名有能力的设计师,甚至更久才成为一名优秀的开发人员。我从10岁起就可以用HTML编码,但这并不意味着我很好。现在,我是一个有能力的设计师在程序,如photoshop和Illustrator,我完全能够写一个好的网站记事本,并能够写一些语言的基本脚本。不仅如此,我对搜索引擎优化技术有着敏锐的嗅觉,可以很容易地告诉你大多数人哪里出错了(提示:获取一些好的内容!).

    此外,这个地方是一个糟糕的网站标准建议资源。您不应该只编写代码来在不同的浏览器中工作。您应该始终遵循该标准,以便将来验证您的代码。当下一次浏览器更新到来时,您在网站上使用的修复通常会中断。不仅如此,好的浏览器还是遵循标准。最后,IE被允许破坏互联网的原因是你通过为IE编写网站代码来实现的!如果你继续为火狐做这些,那么我们又会输!

    如果你认为基于表的布局同样好,如果不比CSS布局好,那么你就不应该被允许谈论这个主题,至少在没有我先把你打倒的情况下。另外,如果你认为W3学校是最好的资源,那么你就是大错特错了。

    如果你是一个网页设计/开发新手,不要为这个地方操心(这里到处都是程序员,而不是网页开发人员)。去一个好的Web设计/开发社区,比如SitePoint。


    1。你不应该一直遵循网络标准。

    2。您不需要对代码进行注释。

    只要陌生人能理解。


    根据我得到的反馈量,我最有争议的观点显然是程序员并不总是读他们声称读过的书。紧接着,我认为受过正规教育的程序员比自学的同一个程序员更好(但不一定比自学的不同程序员更好)。


    我坚信非托管代码不值得麻烦。额外的可维护性费用与查找内存泄漏有关,即使最好的程序员偶尔引入,也远远超出了从C++语言中获得的性能。如果Java、C等无法获得所需的性能,则购买更多的机器。


    VB吸吮虽然一般来说没有太大的争议,但当你在一个VB的房子里工作的时候


    全球和/或独生子女并非天生邪恶

    我来自更多的系统管理员,Shell,Perl(和我的"真实"编程),PHP类型的背景;去年我被扔进Java开发GIG。

    单身汉是邪恶的。地球人是如此邪恶,他们甚至不被允许。然而,Java有像AOP这样的东西,现在有各种各样的"依赖注入"框架(我们使用谷歌Guice)。少了点,但我的东西肯定会给你什么?全球。嗯,谢谢。


    我认为在C中使用区域完全可以折叠代码,而在VS中,太多人试图说它隐藏了您的代码,使得很难找到东西。但是,如果您正确地使用它们,它们对于识别代码的各个部分非常有帮助。


    别害羞,要破例。异常是一种非常有效的信号故障方法,并且比任何返回代码系统都清楚。"异常"与这种情况发生的频率无关,而一切都与类所认为的正常执行条件有关。当除数为零时抛出异常是很好的,不管这种情况发生的频率如何。如果可能出现问题,请保护代码,这样就不会使用不正确的参数调用该方法。


    关系数据库浪费时间。改用对象数据库!

    关系数据库供应商试图愚弄我们相信,世界上唯一可扩展、持久和安全的存储是关系数据库。我是经认证的DBA。您是否曾花费数小时尝试优化查询,却不知道出了什么问题?关系数据库不允许您在需要时创建自己的搜索路径。你把对你的应用程序速度的大部分控制权交给了你从未见过的人,他们并不像你想象的那么聪明。

    当然,有时在维护良好的数据库中,他们会对复杂的查询给出快速的答案。但你为此付出的代价太高了!您必须在每次想要读取数据条目时编写原始SQL之间做出选择,这很危险。或者使用对象关系映射器,这会增加更多的复杂性和超出您控制范围的内容。

    更重要的是,你被积极地禁止提出智能搜索算法,因为到数据库的每一次往返都要花费你大约11毫秒的时间,太多了。假设您知道这个超级图算法,它将回答一个特定的问题,甚至可能在SQL中无法表达!,在适当的时候。但是,即使您的算法是线性的,而有趣的算法不是线性的,也不要考虑将它与关系数据库相结合,因为枚举一个大表需要花费您几个小时!

    将其与sandstonedb或gemstone进行比较!如果你进入Java,就给D4O一个镜头。

    所以,我的建议是:使用一个对象数据库。当然,它们并不完美,有些查询速度会变慢。但你会惊讶有多少会更快。因为加载对象不需要在SQL和域数据之间进行所有这些奇怪的转换。如果您真的需要某个查询的速度,那么对象数据库有您应该信任的查询优化器:您的大脑。


    反射在生产代码中没有位置

    反射破坏静态分析,包括重构工具和静态类型检查。反射也打破了开发人员对代码的正常假设。例如:向类中添加一个方法(不会在类中隐藏其他方法)不应该有任何效果,但是当使用反射时,其他代码可能会"发现"新方法并决定调用它。实际上,确定此类代码是否存在是很难的。

    我认为在代码生成器中使用反射和测试是很好的。

    是的,这确实意味着我试图避免使用反射的框架。(太糟糕了,Java缺少合适的编译时元编程支持)


    两个大脑比一个大脑思考得好

    我坚信,在提高代码质量和编程效率方面,结对编程是首要因素。不幸的是,对于管理层来说,这也是一个极具争议的问题,他们认为"更多的人手=>更多的代码=>$$!"


    您不能通过计算代码行来衡量生产力。

    每个人都知道这一点,但出于某种原因,这种做法仍然存在!


    你不应该以你发现的第一种方式来解决编码"有效"的问题。

    我真的不认为这会引起争议,但确实如此。人们从代码中的其他地方,在线上,或者从1999年出版的一本老书"在3.14159分钟内自学高级能力sqljava beansserver"中看到一个例子,他们认为自己知道一些东西,并将其复制到代码中。他们不会通过示例了解每一行的作用。他们不会考虑他们程序的设计,看看是否有一种更为有组织或更自然的方法来做同样的事情。他们不会试图让自己的技能设置保持最新,以了解他们使用的思想和方法在上一个千年的最后一年被弃用。他们似乎没有经验去了解他们正在复制的内容多年来给程序员造成了特别可怕的维护负担,并且他们可以通过更多的思考来避免。

    事实上,他们甚至没有意识到可能有不止一种方法可以做一些事情。

    我来自Perl世界,其中的一个口号是"有不止一种方法可以做到这一点"。(tmtowtdi)那些草草看了Perl的人已经把它写成"只写"或"不可读",很大程度上是因为他们看了我上面描述的思维方式的人写的蹩脚的代码。这些人对设计、可维护性、组织、减少代码重复、耦合、内聚、封装等都没有考虑,他们写得很糟糕。这些人以每种语言都有编程,而且很容易学习语言,有很多方法可以做事情,给他们足够的绳子和枪来射击和吊死自己。同时。

    但是,如果您在Perl世界中停留的时间比草率的观察要长,并且观察社区中的长时间工作者正在做什么,那么您会看到一件了不起的事情:优秀的Perl程序员会花一些时间寻找最佳的方法来做一些事情。当他们命名一个新的模块时,他们四处征求建议,并从人们身上激发他们的想法。他们把代码分发出去,以便得到查看、批评和修改。如果他们必须做一些令人讨厌的事情,他们将它以尽可能小的方式封装在一个模块中,以便以更有组织的方式使用。同一想法的几种实现可能会停留一段时间,但它们竞争的是精神共享和市场份额,它们竞争的方式是努力做到最好,其中很大一部分是使自己易于维护。真正优秀的Perl程序员似乎很难思考他们在做什么,并寻找最好的方法来做事情,而不仅仅是抓住第一个在他们大脑中穿行的想法。

    今天我主要在Java世界中编程。我看到了一些非常好的Java代码,但我也看到了很多垃圾,而且我看到了我在一开始描述的更多的心态:人们在第一个看起来很难工作的代码集中,不理解它,而不思考是否有更好的方法。

    你会在每种语言中看到这两种心态。我并不是试图具体地攻击Java。(实际上我在某些方面很喜欢它…也许这应该是我真正有争议的观点!)但我开始相信,每个程序员都需要花上好几年的时间来使用tmtowtdi风格的语言,因为尽管传统的智慧认为这会导致混乱和糟糕的代码,但实际上它似乎会让人们明白,你需要考虑你所做的事情的影响,而不是信任你。你的语言是为了让你不费吹灰之力做正确的事情而设计的。

    我认为你可能会在另一个方向上走得太远:即完全忽略你真正的需求和目标的完美主义(通常是你企业的真正需求和目标,通常是盈利能力)。但我不认为任何人都能成为一个真正伟大的程序员,而不需要学会投入比平均水平更大的精力去思考如何找到最好的(或者至少是最好的)编码方式。


    垃圾收集被高估了

    许多人认为在Java中引入垃圾收集是与C++相比最大的改进之一。我认为引言最好是非常小的,写得好的C++代码在适当的地方做所有的内存管理(像RAII这样的技术),所以不需要垃圾回收器。


    在许多情况下,使用regexs解析HTML是很好的

    每当有人发布关于栈溢出的问题,询问如何用regex实现一些HTML操作时,第一个答案是"regex是一个不足以解析HTML的工具,所以不要这样做"。如果发问者试图建立一个网络浏览器,这将是一个有用的答案。然而,通常,发问者希望做一些事情,比如向某个域的所有链接添加rel标记,通常是在可以对传入标记的样式做出某些假设的情况下,这对于regex来说是完全合理的。


    不是工具,是你

    每当开发人员尝试做一些新的事情,比如做UML图、任何类型的图表、项目管理,他们首先会寻找完美的工具来解决这个问题。在无休止的搜索后,发现不合适的工具,他们的动机就会匮乏。剩下的就是抱怨缺少可用的软件。这是一种洞见,即计划的组织在缺少一个软件的情况下死亡。

    好吧,只有你自己在和组织打交道。如果你习惯于组织,你可以使用或不使用软件(大多数情况下不用软件)。如果你不习惯组织,没人能帮你。

    因此,"没有合适的软件"只是一个根本没有被组织起来的最简单的借口。


    意见:不应该有任何编译器警告,只有错误。或者,以不同的方式编写代码时,应该始终使用-werror。

    原因:要么编译器认为它是应该纠正的,以防它是一个错误,要么它不需要修复,在这种情况下,编译器应该关闭。


    有太多的程序员编写了太多的代码。


    变量名称带有下划线

    甚至更糟

    大写的变量名称带有血腥下划线

    应该全局删除…带着偏见!茶花只是很好。(GLOLBAL常量不可承受)

    goto语句供11岁以下的开发人员使用

    任何不支持指针的语言都不值得命名

    净值=膨胀微软为网站开发所做努力的最好例子(无表情Web 2)是有史以来写过的缓慢膨胀的cr@pw@re的最好例子。(请尝试使用Web Studio)

    回应:好吧,让我来讨论一下下划线问题。从您提供的C链接:

    -全局常量应全部为带"u"分隔符的大写。我同意这一点,因为这很明显

    -以网络包为例。注意abc中的c和key中的k是如何混淆的。有些人不介意这一点,而另一些人则讨厌这一点,所以你会在不同的代码中找到不同的策略,所以你永远不知道该怎么称呼某个东西。

    我属于前一类。我非常仔细地选择名字,如果你一眼就看不出K是键的,那么英语可能不是你的第一语言。

    • C函数名

      • 在C++项目中,很少有C函数。
      • 对于C函数,使用所有小写字母的gnu约定,其中"u"作为单词分隔符。

    正当理由

    1
    * It makes C functions very different from any C++ related names.

    例子

    int一些血腥的功能{}

    这些"标准"和惯例只是时间上的任意决定。我认为,虽然它们有一定的逻辑意义,但它们会把代码弄得杂乱无章,而且会使代码变得短小、易读、笨拙、冗长、杂乱无章。

    C被采用为事实上的标准,不是因为它是友好的,而是因为它是普遍的。我可以用一种语法友好的高级语言在20行中编写100行C代码。

    这使得程序流很容易阅读,正如我们所知,一年或更长时间后重新访问代码意味着跟踪整个地方的breadcrumb跟踪。

    我确实使用了下划线,但是对于全局变量,它们是非常少的,而且非常明显。除此之外,一个精心设计的camelcaps()函数/变量名还没有让我失望!


    调试器是一根拐杖。

    这是如此的有争议,以至于我都不像以前那样相信它。

    反对者:我花了更多的时间来加快其他人大量的代码,所以任何有助于"我是怎么到这里来的"和"发生了什么"的东西,无论是尸检前还是尸检后都是有帮助的。

    但是,我很高兴地支持这样一个观点:如果你不理解你自己开发的或者你已经熟悉的代码的这些问题的答案,那么把你所有的时间花在调试器中并不是解决方案,而是问题的一部分。

    在点击"发布你的答案"之前,我在谷歌上快速检查了这个准确的短语,结果发现我不是唯一持有这个观点或使用这个短语的人。我在Fog Creek软件论坛上对这个问题进行了长时间的讨论,其中引用了包括Linus Torvalds在内的各种灯具作为著名的支持者。


    写大量的规范是徒劳的。编写正确的程序是相当困难的,但是编译器、调试程序、单元测试、测试人员等使检测和消除大多数错误成为可能。另一方面,当您使用类似于程序(即伪代码、UML)的类似详细级别编写规范时,您主要是自己编写的。如果你有一个能帮助你正确理解语法的工具,那你就应该庆幸自己。

    广泛的规范很可能是错误百出的。作者在第一次尝试时就获得了正确的机会,这与类似的大型程序在没有经过测试的情况下无bug的机会差不多。同行评审消除了一些错误,就像代码评审一样。


    大多数"用户友好"的第四代语言(包括SQL)都是一文不值的高估垃圾,这些垃圾本不应该被普遍使用。

    4GL通常有一个冗长而不明确的语法。尽管4GL应该允许"非技术人员"编写程序,但您仍然需要"技术人员"编写和维护程序。

    一般来说,4GL程序比更难写、更难读、更难优化。

    应尽量避免使用4GL。


    不是很有争议,但…Ajax在这个词出现之前就已经出现了,每个人都需要"放手"。人们用它来做各种各样的事情。但是没有人真正关心它。

    突然,砰!有人创造了这个词,所有人都加入了Ajax的行列。突然之间,人们就成了Ajax的专家,就好像动态加载数据的专家以前并不存在一样。我认为这是导致互联网遭受残酷破坏的最大因素之一。以及"Web 2.0"。


    默认情况下,数组应基于1而不是0。这并不一定是系统实现语言的情况,但是像Java这样的语言吞咽了比它们应该更多的C奇异性。元素1"应该是第一个元素,而不是第二个元素,以避免混淆。

    计算机科学不是软件开发。毕竟,你不会雇佣只学物理的工程师。

    尽可能多地学习数学。你不会使用它的大部分,但你需要能够这样想才能擅长软件。

    目前标准化的最好的编程语言是通用的Lisp,即使它是冗长的,并且有零基数组。这在很大程度上是由于被设计成写计算,而不是作为冯·诺依曼机器的抽象。

    至少90%对编程语言的比较性批评可以归结为"语言A有特性C,我不知道如何做C或语言B中的等价物,所以语言A更好。"

    "最佳实践"是我见过的最令人印象深刻的拼写"平庸"的方法。


    评论不好

    每当代码需要注释来解释它在做什么时,代码就太复杂了。我总是尝试编写一些不需要太多注释就能解释的代码。


    我可以不受封闭的生活。

    现在看来,每个人和他们的母亲都希望用一种语言来表达封闭,因为这是自切片面包以来最伟大的发明。我认为这只是另一个炒作。


    手动停止程序是发现性能问题的一种有效、经验证的方法。

    可信吗?不是大多数。是真的吗?当然。

    程序员的判断能力远远超过必要的。

    在这些岗位上见证所有被认为是"邪恶"或"恐怖"的事情。

    程序员对数据结构很满意。

    见证所有关于类、继承、私有与公共、内存管理等的讨论,以及如何分析需求。


    程序员需要与客户交谈

    一些程序员认为他们不需要和客户交谈。对于你的公司来说,这是一个非常好的写作方式,没有人能弄清楚它是为了什么,或者它是如何被使用的。

    你不能期望产品经理和业务分析师做出所有的决定。事实上,程序员应该在创建模块或特性的1000个(通常是很小的)决策中做出990个,否则产品将永远不会发布!所以要确保你的决定被告知。了解你的客户,与他们合作,观察他们使用你的软件。

    如果你打算写最好的代码,你希望人们使用它。对你的用户群感兴趣,向那些在那里的"愚蠢的白痴"学习。别害怕,他们会爱你的。


    如果它不值得测试,就不值得构建


    下骆驼壳是愚蠢和不做作的。

    使用较低的camelcase使名称/标识符(从这一点上使用的名称)看起来像是由两部分组成的东西。然而,上面的骆驼壳清楚地表明,所有的词都属于同一个词。

    匈牙利符号不同…因为名字的第一部分是一个类型指示符,所以它与名字的其余部分有独立的含义。

    有些人可能会争辩说,较低的camelcase应该用于函数/过程,特别是类内部。这在Java和面向对象的PHP中很流行。但是,没有理由这样做来表明它们是类方法,因为通过访问它们的方式,可以更清楚地看到它们只是类方法。

    一些代码示例:

    1
    2
    3
    4
    5
    6
    7
    # Java
    myobj.objMethod()
    # doesn't the dot and parens indicate that objMethod is a method of myobj?

    # PHP
    $myobj->objMethod()
    # doesn't the pointer and parens indicate that objMethod is a method of myobj?

    上面的camelcase对于类名和其他静态名称很有用。所有非静态内容都应通过访问方式识别,而不是通过名称格式识别!!)

    这是我的同种代码示例,其中名称行为由除名称之外的其他事物表示…(另外,我更喜欢用下划线来分隔名称中的单词)。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    # Java
    my_obj = new MyObj() # Clearly a class, since it's upper CamelCase
    my_obj.obj_method() # Clearly a method, since it's executed
    my_obj.obj_var # Clearly an attribute, since it's referenced

    # PHP
    $my_obj = new MyObj()
    $my_obj->obj_method()
    $my_obj->obj_var
    MyObj::MyStaticMethod()

    # Python
    MyObj = MyClass # copies the reference of the class to a new name
    my_obj = MyObj() # Clearly a class, being instantiated
    my_obj.obj_method() # Clearly a method, since it's executed
    my_obj.obj_var # clearly an attribute, since it's referenced
    my_obj.obj_method # Also, an attribute, but holding the instance method.
    my_method = myobj.obj_method # Instance method
    my_method() # Same as myobj.obj_method()
    MyClassMethod = MyObj.obj_method # Attribute holding the class method
    MyClassMethod(myobj) # Same as myobj.obj_method()
    MyClassMethod(MyObj) # Same as calling MyObj.obj_method() as a static classmethod

    因此,我的完全obcamelcase的主观意见。


    不要让你的业务逻辑进入数据库。或者至少,保持它很瘦。让数据库做它打算做的。让代码做代码要做的事情。时期。

    If you're a one man show (basically, arrogant & egotistical, not listening to the wisdom of others just because you're in control), do as you wish. I don't believe you're that way since you're asking to begin with. But I've met a few when it comes to this subject and felt the need to specify.

    If you work with DBA's but do your own DB work, keep clearly defined partitions between your business objects, the gateway between them and the DB, and the DB itself.

    If you work with DBA's and aren't allowed to do your DB work (either by policy or because they're premadonnas), you're very close to being a fool placing your reliance on them to get anything done by putting code-dependant business logic in your DB entities (sprocs, functions, etc.).

    If you're a DBA, make developers keep their DB entities clean & lean.


    继承是邪恶的,应该被弃用。

    事实上,在所有情况下,聚合都更好。静态类型的OOP语言不能避免继承,这是描述方法希望从类型得到什么的唯一方法。但是动态语言和duck打字没有它就可以生存。RubyMixins比继承功能强大得多,而且更易于控制。


    不好的IDE使编程语言很弱

    好的编程IDE确实使使用某些语言更容易、更好地进行监督。我有点被我的专业卡雷尔宠坏了,我为之工作的公司总是有最新的Visual Studio随时可用。

    在大约8个月的时间里,我在工作旁边做了大量的可可,Xcode编辑器使得使用这种语言变得非常困难。重载很难找到,处理打开文件的总体方式只会使您的屏幕非常混乱,非常快。这真是一种耻辱,因为可可是一种酷而有力的语言。

    当然,Xcode的铁杆粉丝们现在会投票否决我的职位,但是有太多的IDE确实更好。

    人们在改变主意,他们不应该

    这是我去年写的一篇博文的复制/粘贴。

    我的经验主要是关于荷兰市场,但也可能适用于任何其他市场。

    我们(我把所有的软件工程师都组织在一起)目前所处的市场可能对我们非常有利。无论价格如何,各公司都在拼命地寻找软件工程师(从现在起在SE)。如果你现在换工作,你几乎可以要求任何你想要的。在荷兰,现在有一种趋势,就是给两辆有工作的租赁汽车,只是为了让你为他们工作。这有多奇怪?我怎么能同时开两辆车??

    当然,这听起来对我们很好,但这也造成了非常不健康的情况。

    例如:如果你目前在一家快速发展的公司工作,并且你正试图吸引更多的同事,最终从地面上获得一些严肃的软件开发,没有人能在没有提供高工资的情况下找到你。想要找到高质量的同事是非常困难的。很多人被我们的工作所吸引,因为我们的工资很高,但这也意味着很多人没有正确的热情进入我们的市场。

    热情,是的,我认为这是正确的词。当你对工作充满热情时,你的工作不会在下午5点停止。您将整夜刷新所有开发RSS源。你将在互联网上搜索工作中可能会用到的最新技术。你将在一个月内启动十几个新的"有希望"项目,看看你是否能掌握几周前刚读到的最新技术(并找到一种实际使用该技术的有用方法)。

    如果没有这种热情,市场可能看起来很不错(因为汽车、金钱,当然还有我们吸引的性感女郎),但我认为只要是消防员或战斗机飞行员,就不会有那么有趣了。

    听起来我是在保护自己的工作,这在一定程度上是真的。但我也在努力保护自己不受那些我不想与之共事的人的伤害。我想对我读到的东西进行热烈的讨论。我希望能够和那些和我有着相同工作热情的人打架。我想要有正当理由与我共事的同事。

    我要找的人在哪里?!


    没人关心你的代码

    如果你不从事政府安全许可项目,又不从事金融工作,很可能没有人关心你在公司/客户群之外从事的工作。没有人嗅探数据包或者试图侵入你的机器来读取你的源代码。这并不意味着我们应该轻率对待安全问题,因为肯定有很多人只是想大闹一场,破坏你的辛勤工作,或者访问你公司存储的信息,比如信用卡数据或大量身份数据。但是,我认为人们过度关注其他人访问您的源代码和接受您的想法。


    原始数据类型过早优化。

    有些语言只使用一种数据类型(标量)就可以通过,它们做得很好。其他语言就不那么幸运了。开发人员只是把"int"和"double"放进去,因为他们必须写一些东西。

    重要的不是数据类型有多大,而是数据的用途。如果您有一个月中的某一天变量,那么它是有符号的还是无符号的,或者它是char、short、int、long、long long、float、double还是long double都不重要。一个月中的某一天,而不是一个月,或者一周中的某一天,或者其他什么都有关系。看乔尔的专栏文章,让错误的东西看起来是错误的;最初提出的匈牙利符号是一个好主意。正如在实践中使用的,它基本上是无用的,因为它说的是错误的东西。


    Microsoft Windows是软件开发的最佳平台。

    推理:微软用优秀而廉价的开发工具宠坏了它的开发者,平台和它的API都有很好的文档记录,平台正在以一种和谐的速度发展,这为开发者创造了很多机会,操作系统有一个庞大的用户群,这是很重要的,因为明显的商业原因,有一个很大的Windows开发者社区,我认为还没有因为选择微软而被解雇。


    HTML 5 + JavaScript将是未来使用最多的UI编程平台。Flash、Silverlight、Java applet等都将悄然而死。


    分心是邪恶的:)

    只有在你有充分理由的情况下才需要单独关注。否则,不要将它们分开。

    我遇到过太多的分离的场合,只是为了分离。Dijkstra所说的"最小耦合,最大内聚"的后半部分不应该被忘记。:)

    很高兴进一步讨论。


    在软件设计和开发方面,设计模式是浪费时间。

    别误会,设计模式是有用的,但主要是作为一种交流媒介。它们可以非常简洁地表达复杂的思想:工厂、单例、迭代器…

    但它们不应该作为开发方法。开发人员经常使用一系列基于设计模式的类来设计他们的代码,在可读性和性能方面,更简洁的设计会更好。所有这些都有一种错觉,即单个类可以在其域之外重用。如果一个类不是为重用而设计的,或者不是接口的一部分,那么它就是一个实现细节。

    设计模式应该用于在组织特性上命名,而不是规定代码的编写方式。

    (应该是有争议的,记得吗?)


    从长远来看,开源软件的成本更高

    对于常规的业务线公司,开源看起来是免费的,但有隐藏的成本。

    当考虑到质量、可变可用性和UI/UX的不一致性、互操作性和标准的困难、配置的增加、相关的培训和支持需求的增加时,开放源代码的总体拥有成本比商业产品高得多。

    精通技术的程序员类型可以解放开源并使用它运行;他们"得到它",并且可以采用它并定制它以满足他们的目的。另一方面,那些主要是非技术性的,但需要软件来运行其办公室、网络和网站的企业正冒着为自己带来痛苦的风险,在损失时间、生产力和(最终)支持费和/或放弃体验的成本方面,成本高昂。


    所有项目经理都必须有编码任务

    在我工作过的团队中,项目经理实际上是一名程序员,他很好地理解代码的技术问题,足以完成编码任务,所做的决策缺少通信中断,这在项目经理不参与代码的团队中经常发生。


    在我的工作场所,我一直在尝试引入更敏捷的/xp开发习惯。连续设计是我迄今为止感觉最困难的设计。也许我不应该把它说成"让我们把所有的架构团队集合起来,然后拍摄它们"…;)


    再见!(这有足够的争议吗)有时…所以给我们选择吧!例如,bash没有goto。也许这有一些内在的原因,但仍然存在。另外,goto是汇编语言的构建块。不,如果你说!:)


    记事本是一个完美的文本编辑器。(有时写字板用于非Windows换行)

    • 编辑配置文件
    • 查看日志文件
    • 发展

    我认识真正相信这一点的人!然而,他们将使用一个IDE进行开发,但是继续使用记事本进行其他的工作!


    我讨厌为新来的人提供短期课程的大学和学院。它完全是对艺术和编程科学的耻辱和蔑视。

    他们开始教C、JAVA、VB(令人作呕)给人们,而不掌握计算机的硬件和基本原理。首先应该通过莫里斯马诺的《计算机系统体系结构》等书来教机器,然后教机器解决问题的概念,而不是蚀刻一种编程语言的语义和语法。

    另外,我也不了解政府学校,大学教孩子使用商业操作系统和软件的计算机基础知识。至少在我的国家(印度),没有多少学生买得起操作系统,甚至是打折的办公服,更不用说开发软件巨头(编译器、IDES等)。这会导致盗窃和盗版,并使从他们研究所图书馆复制和窃取软件的行为成为正当行为。

    他们再次被教导使用一些产品,而不是基本思想。

    想想看,如果你只被教导2x2是4,而不是乘法的概念?

    或者,如果你现在被教导测量杆的长度,而不是毕达哥拉斯定理


    意见:数据驱动的设计把马车放在马的前面。它应该立即从我们的思想中消除。

    绝大多数软件与数据无关,而是与我们为客户解决的业务问题有关。这是一个问题域,涉及对象、规则、流程、案例和关系。

    当我们从数据开始设计,并在数据和数据之间的关系(表、外键和x到x关系)之后为系统的其余部分建模时,我们将整个应用程序约束为如何在数据库中存储和检索数据。此外,我们将数据库体系结构公开给软件。

    数据库模式是一个实现细节。我们应该可以自由地更改它,而不必对我们的软件的设计做任何重大更改。业务层永远不应该知道表是如何设置的,或者它是从视图或表中提取的,或者是从动态SQL或存储过程中获取表的。这种类型的代码永远不应该出现在表示层中。

    软件就是解决业务问题。我们处理用户、汽车、帐户、余额、平均值、摘要、转账、动物、消息、包裹、手推车、订单和各种其他真正的有形物品,以及我们可以对它们执行的操作。我们需要根据需要保存、加载、更新、查找和删除这些项目。有时候,我们必须以特殊的方式做这些事情。

    但是没有真正令人信服的理由让我们把应该在数据库中完成的工作从数据中移走,放到源代码中,可能放在单独的机器上(引入网络流量和降低性能)。这样做意味着我们要放弃几十年来为提高数据库中存储过程和函数的性能所做的工作。存储过程引入"又一个API"来管理的论点是似是而非的:当然是这样;API是一个保护您不受数据库模式影响的外观,包括主键和外键、事务、游标等的复杂细节,它防止您在源代码中将SQL拼接在一起。

    把马放回马车前面。考虑问题域,并围绕它设计解决方案。然后,从问题域中导出数据。


    小代码总是更好,但复杂吗?:而不是让我意识到有时大型代码更易于阅读。


    实现IDisposable的类库指南是错误的。

    我不经常分享这个,但我认为IDisposable的默认实现指南是完全错误的。

    我的问题不在于Dispose的过载,然后从定稿中删除该项目,而是我鄙视如何调用定稿器中的托管资源。我个人认为应该抛出一个异常(是的,由于将异常抛出到终结器线程中会带来所有的麻烦)。

    其背后的理由是,如果您是IDisposable的客户机或服务器,那么就有一种理解,即您不能简单地将对象放在一旁等待最终确定。如果您这样做了,这是一个设计/实现缺陷(取决于它是如何被遗留的和/或它是如何被暴露的),因为您不知道您应该知道的实例的生命周期。

    我认为这种类型的错误/错误是在竞争条件/与资源同步的级别上。不幸的是,由于调用了EDOCX1的重载(1),这个错误永远不会出现。

    编辑:如果有人感兴趣,我已经写了一篇关于这个主题的博客:

    http://www.casperhouse.com/post/a-better-implementation-pattern-for-idisposable.aspx


    Linq2SQL还不错

    我看到过很多关于linq2sql的帖子。我知道这不完美,但是什么?

    就个人而言,我认为它有其缺点,但总的来说,它对于原型设计或开发中小型应用程序都是很好的选择。当我考虑到它为我节省了多少时间来编写无聊的DAL代码时,我不能抱怨,尤其是考虑到不久前我们有过的其他选择。


    不加修饰的代码是人类的祸根。

    我认为注释对于代码是必要的。它们直观地将其划分为逻辑部分,并在读取代码时提供替代表示。

    文档注释是最低限度的,但是在编写新代码时,使用注释来拆分较长的函数会有所帮助,并且在返回到现有代码时可以更快地进行分析。


    代码的重用与其"可重用性"成反比。简单地说,因为"可重用"代码更复杂,而快速黑客更容易理解,所以它们可以被重用。

    软件故障应使系统停机,以便检查和修复。试图处理故障情况的软件通常比崩溃更糟糕。也就是说,在崩溃后重置系统更好,还是应该无限期地挂起它,因为故障处理程序有一个bug?


    软件开发人员、编码人员、程序员、架构师之间没有区别…

    我在这个行业工作了10多年,仍然觉得区分这些"角色"是非常愚蠢的。你写代码?你是个开发者。你花了一整天的时间来绘制奇特的UML图。你是…好。。我不知道你是什么,你可能只是想给别人留下深刻印象。(是的,我知道UML)。


    可以保护您的应用程序。

    每当有人问一个关于如何防止用户盗版他们的应用程序,或者如何保护它免受黑客攻击的问题,答案是这是不可能的。胡说。如果你真的相信这一点,那就让你的门不上锁(或者把它们从房子里拿下来!)也不用去看医生。你是凡人——试图治愈疾病只是推迟了不可避免的事情。

    仅仅因为有人可能会盗版你的应用或入侵你的系统并不意味着你不应该试图减少将要这样做的人的数量。你真正要做的是让它需要比入侵者/海盗愿意做的更多的工作来闯入。

    就像你家里的门闩和广告会把窃贼拒之门外,合理的反盗版和安全措施会让黑客和海盗挡在你的路上。当然,他们越想闯入,你就越需要安全保障。


    我相信Python的禅


    "程序员是天生的,不是天生的。"


    "一切都应该尽可能简单,但不能简单。"—爱因斯坦。


    有时候,接受一个例外是合适的。

    对于用户界面来说,提示用户错误消息是一种中断,而且通常他们什么也不做。在这个例子中,我只是记录它,当它出现在日志中时处理它。


    三元运算符绝对差劲。它们是懒惰编程的缩影。

    1
    user->isLoggedIn() ? user->update() : user->askLogin();

    这很容易搞砸。修订版有点变化2:

    1
    user->isLoggedIn() && user->isNotNew(time()) ? user->update() : user->askLogin();

    哦,是的,再多一点"零钱"。

    1
    2
    3
    user->isLoggedIn() && user->isNotNew(time()) ? user->update()
        : user->noCredentials() ? user->askSignup
            : user->askLogin();

    哦,废话,那另一个案子呢?

    1
    2
    3
    user->isLoggedIn() && user->isNotNew(time()) && !user->isBanned() ? user->update()
        : user->noCredentials() || !user->isBanned() ? user->askSignup()
            : user->askLogin();

    不,不,不。只需保存代码更改。别再懒惰了:

    1
    2
    3
    4
    5
    if (user->isLoggedIn()) {
        user->update()
    } else {
        user->askLogin();
    }

    因为第一次做对了,我们就不用一次又一次地转换你的垃圾三元了:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    if (user->isLoggedIn() && user->isNotNew(time()) && !user->isBanned()) {
        user->update()
    } else {
        if (user->noCredentials() || !user->isBanned()) {
            user->askSignup();
        } else {
            user->askLogin();
        }
    }


    当有人认为整个编程语言"笨拙"时,通常会发现他不知道如何使用它。


    程序化编程很有趣。OOP很无聊。


    获得节目报酬通常是男人时间最糟糕的用途之一。

    首先,你要和每天工作四分之一的埃尔邦人竞争。你需要说服你的雇主,你提供了一些埃尔博尼亚人永远无法提供的东西,并且你的东西值得一份宜居的薪水。随着埃尔博尼亚人越来越多的海外业务,真正的优势逐渐消失,管理层也知道这一点。

    另一方面,你花时间解决别人的问题。这是你可以用来提高自己的兴趣,或者解决你真正感兴趣的问题的时间。如果你认为你是通过解决其他男人的问题来拯救世界,那你为什么不让埃尔邦人帮你做呢?

    最后,软件方面的重大创新(visicalc、napster、pascal等)不是由小隔间农场创造的。他们是由一两个人创造的,没有预付款。你不能强制重新创建它。当一个有能力的程序员有了一个非常好的主意时,有时会发生这种神奇的事情。

    有足够的软件。有足够的软件开发人员。你不必成为一个可以雇佣的人。节省你的天赋、时间、头发和婚姻。让别人把他的灵魂出卖给键盘。如果你想编程,可以。但不要为了钱而这样做。


    "程序员必须同时进行编程,否则他们永远不会像那些做编程的人那样优秀。"

    正如科波洛克所说,想象一下,对于医生或士兵来说……

    最重要的不是他们是否编码,而是他们是否考虑编码。计算科学是一个智力练习,你不需要编写代码来思考那些使你成为一名程序员的问题。

    这不像爱因斯坦在研究结束后玩粒子和波的游戏。


    Java不是最好的东西。仅仅因为它带有一个"企业"标签并不能使它很好。它也不能使它变快。它也不能成为每个问题的答案。

    此外,ror并不是博客圈所吹捧的全部。

    当我在这的时候,OOP并不总是好的。事实上,我认为这通常是坏的。


    意见:大多数代码都很糟糕,因为这正是程序员想要的。

    间接地说,我们一直在培育一种极富创造力的文化。这并不是说我认为解决问题的方法没有创造性的元素——它确实有——只是它甚至与绘画这类东西根本不一样(参见保罗·格雷厄姆著名的《黑客与画家》一文)。

    如果我们把我们的行业转向这一方法,最终意味着让每个程序员都去开发他们想要的任何高度创造性和疯狂的东西。当然,对于任何规模的项目,试图将数十个不相关的、非结构化的、计划外的位组合成一个最终的一致位,根据定义是行不通的。这不是一个猜测,也不是一个估计,而是我们今天面对的行业状况。您在一个主程序中看到多少次功能的子位与代码的其余部分完全不一致?现在很普遍,很奇怪有人会用这些东西。

    复杂、复杂、丑陋的事情不断恶化,变得更加不稳定。如果我们正在建造一些物质的东西,地球上的每个人都会告诉我们这些东西有多么丑陋和混乱,但是由于它或多或少地被虚拟化所隐藏,我们能够摆脱一些我们这个物种将看到的最糟糕的制造过程。(你能想象一辆车,四个不同的人用四种不同的方式设计了四个不同的轮子吗?)

    但可悲的是,这一切中有争议的部分,是绝对没有理由这样做,除了历史上的文化是朝着更多的自由和更少的组织,所以我们保持这种方式(可能会变得更糟)。软件开发是一个笑话,但它是一个笑话,因为这正是程序员想要的(但绝不会在一百万年内承认这是真的,"管理层的阴谋"对大多数人来说是一个更好的理由)。

    在我们醒来意识到我们是拿着枪,指着枪,还扣动扳机的人之前,我们还要用脚连续射击多久?

    保罗。


    应禁止调试程序。这将迫使人们编写可通过单元测试进行测试的代码,并最终导致更好的代码质量。

    从所有编程IDE中删除复制粘贴。复制粘贴的代码非常糟糕,应完全删除此选项。那么程序员很可能太懒了,无法重新输入所有代码,所以他创建了一个函数并重用代码。

    每当你使用单打时,就给自己一巴掌。单例几乎从来都不是必需的,而且大多数时候只是全局变量的一个花哨名称。


    尽管我完全赞成测试驱动开发(TDD),但我认为在开发人员开始开发一个完整的开发周期(原型化问题的解决方案)之前,有一个至关重要的步骤。

    我们经常会被追赶,试图遵循我们的TDD实践的解决方案,可能会被误导,因为我们不太了解这个领域。简单的原型通常可以解释这些问题。

    原型是很好的,因为与首先编写测试(有时)相比,您可以快速地搅动和丢弃更多的代码。然后,您可以用一张空白的石板开始开发过程,但要有更好的理解。


    QA应该比开发更好地了解代码(间接)。QA得到报酬发现开发不打算发生的事情,他们经常这样做。:)(顺便说一句,我是一个开发人员,他只看重一大堆优秀的QA人员——远远超过少数人……极少数。


    我们是软件开发人员,而不是C/C/C/C++/PHP/Perl/Python/Java/…开发人员。

    在你接触了一些语言之后,学习一种新的语言并提高工作效率是一项很小的任务。也就是说你不应该害怕新语言。当然,有生产力和掌握一门语言有很大的区别。但是,这没有理由回避你从未见过的语言。当人们说"我是一个PHP开发者"时,或者当一个工作机会说"Java开发者"时,我就很烦。经过几年的开发经验,新的语言和API真的不应该让人望而生畏,从从未见过一种语言发展到高效使用它不应该花费很长时间。我知道这是有争议的,但这是我的观点。


    每当您向外部世界公开一个可变类时,您应该提供事件以使观察它的突变成为可能。额外的努力可能也会说服你让它永远不变。


    对标准的热情坚持妨碍了简单性。

    MVC对网站的评价过高。主要是风投,有时是M。


    在任何可能的地方和任何可能的地方使用类型推断。

    编辑:

    这是一个链接,指向我几个月前写的一篇关于我为什么这么想的博客。

    http://blogs.msdn.com/jaredpar/archive/2008/09/09/when-to-use-type-interrusion.aspx


    PHP文件中的HTML过多:有时是必要的

    PHP文件中的javascript过多:触发猛禽攻击

    当我很难弄清楚你在回音和?>?php'ing html(毕竟,php只是一个处理html的处理器),在其中添加了行和行的javascript,使其成为一个完全无法修复的混乱。

    人们必须理解这一点:它们是两种独立的编程语言。选择一种语言作为你的主要语言。然后继续寻找一种快速、干净和易于维护的方法,使您的主要语言包括第二语言。

    你总是在php、javascript和html之间跳来跳去的原因是你在这三个方面都不擅长。

    好吧,也许这并不完全有争议。我觉得这是一个总的发泄沮丧的话题:)


    用于Web的MVC应该比传统的MVC简单得多。

    传统的MVC包含"监听""事件"的代码,这样视图就可以不断地更新以反映模型的当前状态。然而,在Web范式中,Web服务器已经进行了监听,请求就是事件。因此,用于Web的MVC只需要是中介模式的特定实例:在视图和模型之间进行中介的控制器。如果一个Web框架是精心设计的,那么一个可重用的核心可能不应该超过100行。这个核心只需要实现"页面控制器"范式,但是应该是可扩展的,以便能够支持"前端控制器"范式。

    下面是我自己的框架的关键所在,它成功地用于财富100强网络硬件制造商为财富50强媒体公司生产的嵌入式消费设备中。我的方法比作SimalTalk以前的SimalTalk程序员和OrryLy书中关于最突出的Java Web框架的作者;此外,我已经将相同的框架移植到MODYPython /PSP。

    1
    2
    3
    4
    static function sendResponse(IBareBonesController $controller) {
      $controller->setMto($controller->applyInputToModel());
      $controller->mto->applyModelToView();
    }


  • 好的建筑是成长的,而不是设计的。

  • 管理者应该确保他们的团队成员总是低于他们的技术水平,无论这一水平是什么。当人们在舒适区工作时,他们会产生更高质量的代码。


  • 软件开发是计算机科学的一个很小的分支。

    人们有时似乎认为这两者是同义的,但事实上,计算机科学有很多方面,一般的开发者很少(如果有的话)接触到。根据一个人的职业目标,我认为有很多计算机科学专业的毕业生可能会在某种软件工程教育方面过得更好。

    我高度重视教育,拥有计算机科学理学士学位,并兼职攻读硕士学位,但我认为许多获得这些学位的人都把学位当作达到目的的手段,而获益甚微。我认识很多人,他们学的是我学的相同的系统软件课程,写的是我写的相同的汇编程序,直到今天,他们所做的一切都没有任何价值。


    软件开发是一门艺术。


    缺陷和增强请求相同

    除非您是根据固定价格合同开发软件,否则在确定积压工作的优先级时,"bug"、"增强"和"新特性"请求之间应该没有区别。好吧-也许这没什么争议,但是我在企业IT项目上工作过,那里的法令是"所有开放的bug都必须在下一个版本中修复",即使这没有给开发人员留下时间来开发最理想的新特性。因此,1%的用户遇到的问题,1%的时间优先于一个新功能,可能会立即对90%的用户有用。我喜欢将我的整个项目积压工作,对每个项目进行评估,并将其带到用户社区进行优先级排序——这些项目没有被分类为"缺陷"、"增强"等。


    了解"要做什么"至少和知道"如何"做同样重要,而且几乎总是比了解解决问题的"最佳"方法更重要。领域特定的知识通常对编写好的软件至关重要。


    如果一种编程语言的语法不直观,我不在乎它有多强大,而且我不能在一段时间内将它放在一边,在没有太多刷新细节的情况下重新使用它。我宁愿一种语言本身是直观的,而不是神秘的,但对于创建DSL来说是强大的。计算机语言是我的用户界面,我希望它的设计能像其他任何用户界面一样直观易用。


    使用存储过程易于维护,与使用ORM相比,部署较少是OO方式,因此很好

    我在很多项目中都听到过这样的说法,每当这些说法出现时,要解决它总是很困难的。


    我总是对的。

    或者通过讨论称之为设计。但如果我提出一些建议,你最好能证明我错的原因,并提出一个你可以辩护的替代方案。

    当然,这只有在我合理的情况下才有效。你很幸运,我很幸运。:)


    许多开发人员对将东西放在哪里有一种不发达的感觉,从而导致文件、类和方法级别的源代码组织混乱。此外,相当大比例的此类开发人员基本上对代码组织的问题充耳不闻。试图教导、哄骗、威胁或羞辱他们保持代码干净是徒劳的。

    在任何一个足够成功的项目中,通常都会有一个开发人员非常有组织感,他会悄悄地向代码库挥动扫帚以阻止熵。


    可用性问题从来不是用户的错。

    我无法计算当某个用户做了团队中每个人都认为"只是一件愚蠢的事情"的事情时,问题出现的频率。像"为什么会有人这样做?"或者"他为什么不做XYZ"通常会出现。

    尽管很多人对我这样说感到厌倦:如果一个现实生活中的用户试图做一些不起作用的事情,导致一些事情出错或导致意外的行为,那么这可能是任何人的错,但不是用户的错!

    请注意,我不是指故意滥用软件的人。我指的是软件的假定目标组。


    清理和重构在(团队)开发中非常重要

    团队发展中的许多工作都与管理有关。如果您使用的是bug跟踪器,那么只有当有人花时间关闭/构造东西并减少票据数量时,它才有用。如果您使用的是源代码管理,则需要有人在这里进行清理,并经常重新构造存储库。如果您正在编程,那么应该有人关心重构他人懒惰生产的东西。它是一些人在进行软件开发时所面临的大部分方面的一部分。

    每个人都同意这种管理的必要性。它总是第一个被跳过的东西!


    有时可以使用regex从HTML中提取一些内容。说真的,用一个钝器解析器争论,还是使用像//这样的快速regex?这并不完美,但是你的软件会运行得更快,而且你可能会使用另一个regex来验证提取的匹配是一个看起来像url的东西。当然,它是黑客的,可能会在几个边缘案例中失败,但对于大多数使用来说,它已经足够好了。

    基于大量的"如何使用regex get html?"几乎每天都在这里发布的问题,以及每个答案都是"使用HTML解析器"这一事实,应该引起足够的争议。


    永远不要让最佳实践或模式困扰着你。

    这些应该是指导方针,而不是一成不变的法律。

    我真的很喜欢这些模式,而gof的书或多或少也这么说,浏览的东西,提供了一种常见的行话。不是一派胡言。


    与文档不完整的代码相比,生成文档完整的代码所需的时间更少。

    当我说有据可查的话时,我的意思是说,在每一个步骤中,我都会用清晰的评论来传达你的意图。是的,输入评论需要一些时间。是的,你的同事都应该足够聪明,仅仅通过阅读你的描述性函数和变量名,并在你所有的可执行语句中快速浏览它们,就可以知道你想要什么。但这比你刚刚解释了你的意图要花更多的时间来完成,而且当代码的逻辑被证明是错误的时候,清晰的文档尤其有用。不是说你的代码永远都是错的…

    我坚信,如果您从开始一个项目到交付一个无缺陷的产品,编写好文档的代码所花费的时间会更少。首先,必须清楚地解释您正在做的事情,这迫使您清楚地思考它,如果您不能写一个清楚、简洁的解释您的代码正在完成什么,那么它可能设计得不好。出于另一个纯粹自私的原因,有良好文档记录和结构良好的代码更容易转储到其他人身上进行维护,从而使原始作者能够自由地创建下一个重要的东西。我很少会停止我正在做的事情来解释我的代码是如何工作的,因为对于那些能读英语的人来说,这是显而易见的(即使他们不能读C/C++ +C等)。还有一个原因是,坦率地说,我的记忆力不太好!我记不起昨天早餐吃了什么,更别提一个月或一年前我写代码时的想法了。也许你的记忆比我的好得多,但是因为我记录了我的意图,我可以很快地从我离开的地方开始,并且在不需要先弄清楚我写它时在想什么的情况下做出改变。

    这就是为什么我记录得很好的原因——不是因为我觉得自己有一个高尚的使命来生成适合显示的代码,也不是因为我是一个纯粹主义者,而是因为端到端的代码让我可以在更短的时间内发布高质量的软件。


    学校教育破坏了创造力*

    *"废墟"是指"潜在的废墟"

    当然,需要上学!每个人在使用之前都需要学习一些东西——然而,如果我们不小心的话,你关于如何为特定的商业领域制定特定战略的所有伟大想法都很容易被抛入我们的大脑深处。

    当你学习新事物和获得新技能时,你也在把你的思维定格在这些新事物和技能上,因为它们显然是"完成它的方法"。作为人类,我们倾向于听取权威的意见——成为老师、顾问、同事,甚至是你喜欢的网站/论坛。我们应该时刻意识到我们思维方式的"缺陷"。听别人说什么,但不要想当然。对你收到的每一条新信息都要持批评态度。

    而不是想"哇,太聪明了。从现在开始我就用它,我们应该会想"哇,那很聪明。现在,我如何才能在我的个人技能和想法工具箱中使用它"。


    启用多个签出如果我们改进足够多的开发人员规则,我们将通过源代码管理的自动合并从这个设置中获得更高的效率。


    那,呃,人们应该评论他们的代码吗?这里似乎很有争议…

    代码只告诉我它实际上做了什么,而不告诉我它应该做什么。

    我看到一个函数计算一个澳大利亚债券未来的点值的时候,我想看到一些注释,指出编码人员认为计算应该是什么!


    软件不是一门工程学科。

    我们不应该让电脑从数学系逃走。


    不要改变不坏的东西。


    开发80%是关于设计的,20%是关于编码的。

    我相信开发人员应该把80%的时间花在细节的设计上,他们将要构建什么,只有20%的时间实际地对他们设计的东西进行编码。这将产生接近零错误的代码,并在测试修复重新测试周期中节省大量。

    早点接触金属(或IDE)就像是过早的优化,这被认为是万恶之源。深思熟虑的前期设计(我不一定要谈论大量的设计文档,白板上的简单图纸也会起作用)将产生比仅仅编码和修复更好的结果。


    在关系数据库的CLOB中存储XML通常是一种可怕的逃避。它不仅在性能方面是可怕的,而且将正确管理数据结构的责任从数据库架构师转移到应用程序程序员身上。


    宏、预处理器指令和注释都是邪恶的。

    请给每个文件一个语法和语言!

    //不适用于生成文件或插入真正代码的编辑器宏。


    Java是我们这代人的COBOL。

    每个人都学会了编码。在大公司中运行IT代码,这些大公司将努力保持IT运行数十年。与所有其他选择相比,每个人都开始鄙视它,但无论如何都不得不使用它,因为它支付了账单。


    尺寸很重要!修饰代码,使其看起来更大。


    只有一种设计模式:封装

    例如:

    • 工厂方法:您已经封装了对象创建
    • 策略:您封装了不同的可变算法
    • 迭代器:您封装了顺序访问集合中元素的方法。


    在几乎所有情况下,评论都是邪恶的:http://gooddeveloper.wordpress.com/


    如果你曾经让Rentacoder.com的任何人接触过你的项目,那么无论是IT还是你的业务都完全没有价值。


    我有争议的观点可能是约翰·卡马克(ID软件、Quake等)不是一个很好的程序员。

    别误会我,在我看来,他是一个非常聪明的程序员,但当我注意到地震源代码中的"定义私有公共"一行后,我忍不住认为他是一个能完成任务的人,而不是一个优秀的程序员。不过,这一观点使我陷入了许多激烈的讨论之中;)


    匿名函数太糟糕了。

    我在自学jquery,虽然它是一种优雅且非常有用的技术,但大多数人似乎将它视为最大化匿名功能用户的某种竞争。

    函数和过程命名(以及变量命名)是我们在编程中拥有的最大表达能力。将函数作为数据传递是一种很好的技术,但是让它们匿名,因此不进行自我记录是一个错误。这是表达代码含义的一次失败的机会。


    程序员应该不惜一切代价避免通过继承隐藏方法。

    根据我的经验,几乎我所见过的每一个地方,遗传方法隐藏使用它已经造成了问题。方法隐藏会导致通过基类型引用访问对象时的行为与通过派生类型引用访问对象时的行为不同-这通常是一件坏事。虽然许多程序员没有正式意识到这一点,但最直观的期望是对象将遵循Liskov替换原则。当对象违反这个期望时,面向对象系统固有的许多假设可能开始磨损。我看到的最令人震惊的情况是,隐藏方法改变了对象实例的状态。在这些情况下,对象的行为可能会以很难调试和诊断的微妙方式发生变化。

    好吧,有些情况下方法隐藏实际上是有用和有益的,比如模仿不支持它的语言中方法的返回类型协方差。但绝大多数情况下,当开发人员使用隐藏方法时,要么是出于无知(或意外),要么是为了解决一些可能需要更好的设计处理的问题。一般来说,我所看到的方法隐藏的有益案例(不是说没有其他方法)是,当返回某些信息的无副作用方法被计算出更适用于调用上下文的内容的方法隐藏时。

    像C这样的语言通过在隐藏基类方法的方法上要求new关键字来改进一些东西——至少有助于避免非自愿地使用方法隐藏。但是我发现很多人仍然混淆了newoverride的含义,特别是在简单的场景中,他们的行为看起来是相同的。如果像fxcop这样的工具实际上有内置的规则来识别方法隐藏的潜在错误用法,那就太好了。

    顺便说一下,通过继承隐藏的方法不应该与其他类型的隐藏混淆,比如通过嵌套隐藏,我认为这是一个有效和有用的构造,潜在问题更少。


    在为数据访问层创建单元测试时,数据应该直接从数据库中检索,而不是从模拟对象中检索。

    考虑以下事项:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    void IList<Customer> GetCustomers()
    {
      List<Customer> res = new List<Customer>();

      DbCommand cmd = // initialize command
      IDataReader r = cmd.ExecuteQuery();

      while(r.read())
      {
         Customer c = ReadFiledsIntoCustomer(r);
         res.Add(c);
      }

      return res;
    }

    在getCustomers的单元测试中,对cmd.executeQuery()的调用应该实际访问数据库还是模拟数据库的行为?

    我认为,如果以下情况成立,您不应嘲笑对数据库的实际调用:

  • 存在测试服务器和架构。
  • 模式是稳定的(意味着您不希望对其进行重大更改)
  • DAL没有智能逻辑:查询构造得很普通(配置/存储过程)欲望逻辑也很简单。
  • 根据我的经验,这种方法的最大好处是,您可以尽早与数据库进行交互,体验"感觉",而不仅仅是"外观"。之后它可以帮你省去很多头痛,是让自己熟悉模式的最好方法。

    许多人可能会争辩说,一旦执行流程跨越了流程边界,它就会成为一个单元测试。我同意它有它的缺点,特别是当数据库不可用时,您不能运行UT。

    然而,我认为在许多情况下,这应该是一件有效的事情。


    详细的设计是浪费时间,如果一个工程师需要它们来做一个体面的工作,那么就不值得使用它们!

    好吧,这里有几个想法:

    1)瀑布式开发的旧思想是完全浪费时间,在这里您应该提前完成所有的设计,从而产生一些非常详细的类图、序列图等。正如我曾经对一位同事说的,一旦代码完成,我将完成设计。我认为敏捷在一定程度上承认了这一点——代码就是设计,任何优秀的开发人员都在不断地重构。当然,这使得你的类图过时的想法变得可笑——它们永远都是。

    2)管理层经常认为,你可以把一个不称职的工程师当作"代码猴子",换句话说,他们不是特别有天赋,但见鬼,你不能用他们来写一些代码吗?好。。不!如果你不得不花费大量的时间来编写详细的规范,以至于你基本上是在指定代码,那么你自己编写代码会更快。你没有节省任何时间。如果一个开发人员不够聪明,不能运用他们自己的想象力和判断,他们就不值得雇佣。(注意,我不是在说那些有能力学习的初级工程师。很多"高级工程师"都属于这一类。)


    程序员不应该接触Word(或PowerPoint)

    除非您正在开发一个字或文档处理工具,否则您不应该触摸只发出二进制blob的字处理器,并且就此而言:

    生成的XML文件是二进制blob

    程序员应该编写纯文本文档。程序员编写的文档只需要传达意图,而不需要格式化。它必须能通过编程工具链产生:编辑器、版本控制、搜索实用程序、构建系统等。当您已经拥有并知道如何使用该工具链时,其他所有文档生产工具都是对时间和精力的可怕浪费。

    当需要为非程序员生成文档时,应使用轻量级标记语言,例如RestructuredText(如果您正在编写纯文本文件,则可能正在编写自己的轻量级标记),并从中生成HTML、PDF、S5等。


    低级语言不适合大多数问题。


    Delphi很有趣

    是的,我知道它已经过时了,但是Delphi是一个非常有趣的开发工具。


    我有两个:

    设计模式有时是糟糕的程序员编写糟糕代码的一种方式——"当你有锤子的时候——整个世界看起来都像钉子"的心态。如果我不喜欢听到的是两个开发人员按模式创建设计:"我们应该在facade中使用命令…"。

    没有所谓的"过早优化"。当代码变得太痛苦时,您应该在到达这一点之前对其进行分析和优化。


    控制反转并不能消除依赖关系,但它确实能很好地隐藏它们。


    成员变量不应该被声明为私有的(在Java中)

    如果您声明了一些私有的东西,那么您将阻止任何未来的开发人员从您的类中派生并扩展功能。本质上,通过编写"private",您意味着您现在比任何未来的开发人员可能知道的更多关于如何使用类的知识。每当你写"private"时,你应该写"protected"。

    类不应该被声明为最终的(在Java中)

    类似地,如果您声明一个类为final(这会阻止它被扩展——阻止它被用作继承的基类),那么您的意思是,您对使用您的类的正确和正确的方法的了解比任何未来的程序员都要多。这绝对不是个好主意。你什么都不知道。有人可能会想出一个完全适合你的方法来扩展你没有想到的课程。

    爪哇豆是个可怕的主意。

    JavaBean约定——将所有成员声明为私有的,然后为每个成员编写GET()和Stand()方法——迫使程序员编写样板、容易出错、冗长乏味、冗长的代码,其中不需要代码。只需公开成员变量!如果您需要更改实现(提示:99%的时候,您永远不会更改),请相信您以后更改它的能力。


    程序员把他们的(自己的)有限愚蠢的编程语言当作神圣不可侵犯的宗教。

    程序员如何像宗教信徒一样对待这些讨论是如此有趣:不允许批评,(通常)不进行客观的讨论,(非常经常)基于非常有限或缺乏的知识和信息进行争论。为了确认,只需阅读前面的答案,尤其是评论。

    还有一个有趣的和另一个证实:根据问题"给我一个有争议的意见"的定义,任何有争议的意见都不应该有资格获得否定票——事实上相反:争议越多越好。但是我们的程序员如何反应:就像巴甫洛夫的狗一样,对不喜欢的意见投反对票。

    附言:我对其他一些人的公平性投了赞成票。


    如果你只能想一种方法去做,那就别想了。

    无论是界面布局、任务流还是代码块,都只需停止。做一些事情来收集更多的想法,比如问别人他们会怎么做,并且在你至少有三个完全不同的想法和至少一个信心危机之前,不要回去执行。

    一般来说,当我认为某件事情只能通过一种方式来完成,或者认为只有一种方法有任何优点时,这是因为我没有考虑到那些应该对设计产生足够彻底影响的因素。如果我有,他们中的一些人显然会发生冲突,导致混乱,从而成为一个实际的决定,而不是死记硬背的违约。

    成为一名优秀的程序员并不能使你成为一名优秀的界面设计师。

    并且遵循世界上所有的接口指南只会开始有所帮助。如果人类有可能…似乎有一种特殊的嗜好,使事物"可爱"和"聪明"。


    女人比男人能成为更好的程序员。

    与我合作过的女性程序员不像男性那样热衷于"他们的"代码。他们更愿意接受批评和新思想。


    预先设计-不要仅仅因为编写代码而开始编写代码。

    我看到过太多的应用程序设计不好,因为开发人员对代码非常兴奋,以至于他们打开了一个白色页面,开始编写代码。我理解在开发生命周期中事情会发生变化。然而,对于具有不同布局和开发方法的应用程序,从一个窗体到另一个窗体,从一个方法到另一个方法都很难工作。

    如果您没有明确定义任务以及计划如何对其进行编码,那么很难达到应用程序要处理的目标。在开始编码之前,花点时间(而不仅仅是5分钟),确保你已经尽可能多地安排好了时间。这样你就可以避免你的替代者不得不支持的意大利面混乱。


    最新的设计图案往往是蛇油。正如前面在这个问题中所说,过度使用设计模式对设计的危害远远大于对设计的帮助。

    如果我再听到一个人说"每个人都应该使用IOC"(或类似的一堆废话),我想我会被迫追捕他们,并教会他们错误的做法。


    良好的性能与优雅的设计

    它们不是互斥的,但我无法超越完全不了解性能的设计类结构/框架。我不需要有一系列新的这个(new that(new whatever());创建一个对象来告诉我今天早上5点。顺便说一句,离奥巴马生日还有217天,周末还有2天。我只想知道体育馆是否开放。

    在两者之间保持平衡至关重要。当你需要把所有的处理器都抽出来做一些密集的事情,比如读取兆字节的数据时,代码就需要变得糟糕。为那些消耗10%资源(可能超过代码的90%)的地方节省优雅。


    因为HTML/CSS不是编程语言,所以这并不完全是编程语言。

    表格可用于布局

    CSS和Div不能做任何事情,省去麻烦,使用一个简单的表格,然后在上面使用CSS。


    Hibernate是无用的,会损害开发人员的思想。


    扩展方法是魔鬼的工作

    似乎每个人都认为.NET中的扩展方法是自切片面包以来最好的方法。唱赞歌的开发者的数量似乎一分钟比一分钟多,但恐怕我不得不鄙视他们,除非有人能提出一个我还没听说过的绝妙的理由或例子,否则我永远不会写一篇。我最近遇到了这个问题,我必须说,阅读投票最多的扩展的例子让我有点想吐(当然是比喻)。

    其扩展性优点的主要原因是可读性的提高、OO的改进以及方法调用更好的链接能力。

    恐怕我不得不有所不同,我发现事实上,由于它们的核心是谎言,它们明确地降低了可读性和OO。如果你需要一个作用于一个对象的实用方法,那么写一个作用于该对象的实用方法,不要骗我。当我看到Astring.SortMeBackwardSusingKlingonSortOrder时,字符串应该有这个方法,因为它告诉我一些关于字符串对象的信息,而不是关于烦人的nerdReferences.StringUtilities类的信息。

    Linq的设计方式是,必须使用链接方法调用来避免奇怪和不舒服的表达式,而Linq产生的扩展方法是可以理解的,但一般来说,链接方法调用会降低可读性,并导致出现我们在模糊Perl竞争中看到的那种代码。

    因此,简而言之,扩展方法是邪恶的。抛开撒旦的锁链,致力于无扩展代码。


    开发团队应该更经常地通过技术/架构层而不是业务功能进行隔离。

    我来自一个普通的文化,开发人员拥有"从网页到存储过程的一切"。因此,为了在系统/应用程序中实现一个特性,他们将准备数据库表模式,编写存储过程,匹配数据访问代码,实现业务逻辑和Web服务方法,以及Web页面接口。

    你猜怎么着?每个人都有自己的做事方式!每个人都在努力学习ASP.NET Ajax和Telerik或基础设施套件、企业库或其他生产力和数据层和持久性框架、面向方面的框架、日志记录和缓存应用程序块、DB2或Oracle Percurities。你猜怎么着?每个人都要花很长时间来学习如何正确地做事!这意味着,同时会出现很多错误,并且会产生很多缺陷和性能瓶颈!还要花更长的时间来修理它们!跨越每一层!每个人都参与到每个Visual Studio项目中。没有人专门处理和优化一个问题/技术领域。厨师太多,汤变质了。所有的厨师都会产生放射性粘液。

    开发人员可能有跨层/领域的责任,但他们不应该假装自己可以精通所有的学科,并且应该仅限于少数学科。根据我的经验,当一个项目不是一个小项目并且使用了很多技术时,在一个层中覆盖更多的业务功能比覆盖整个体系结构堆栈中的更少的业务功能(这促使开发人员仅通过其UI和不是测试代码)。


    XHTML是邪恶的。写HTML

    无论如何,您必须将mime类型设置为text/html,那么为什么要愚弄自己相信您真正在编写XML呢?不管是谁下载你的网页,都会相信它是HTML,所以把它变成HTML。

    有了它,你就可以自由地不关闭你的

  • 不需要。不要关闭HTML标记,文件已经结束。它是有效的HTML,可以完美地解析。

    它将创建更可读、更少样板代码,并且不会丢失任何东西。HTML解析器工作良好!

    完成后,转到HTML5。这样比较好。


    设计代码:杰克·W·里夫斯的三篇论文

    任何软件的源代码都是其最精确的设计文档。其他一切(规格、文档,有时还有注释)要么是不正确的,要么是过时的,要么是误导性的。

    肯定会让你到处被炒鱿鱼。


    软件重用是优化软件开发的重要途径

    不知何故,软件重用在一段时间内一直流行,但失去了它的魅力,当许多公司发现仅仅用重用标语编写PowerPoint演示文稿实际上没有帮助。他们的理由是,软件重用只是"不够好",不能实现他们的梦想。因此,它已经不再流行了——它被许多新来的项目管理人员(例如敏捷)所取代。

    事实上,任何真正优秀的开发人员都会自己执行某种软件重用。我要说的是任何一个开发者,不做软件重用是一个不好的开发者!

    我自己也经历过,在开发中有多少软件重用可以产生性能和稳定性。但当然,一系列的权力和对管理层的半心半意的忏悔不足以充分发挥其在公司中的潜力。

    我链接了一篇关于软件重用的非常老的文章(参见标题)。这本书最初是用德语写的,后来又翻译过来了——所以请原谅,当它写得不好的时候。


    最佳实践并非如此。


    可以使用短变量名

    但不适用于嵌套循环中的索引。


    80%的错误是在设计阶段引入的。另外80%是在编码阶段引入的。

    (这一观点的灵感来自于阅读迪玛·马林科的回答。"开发是80%关于设计,20%关于编码",是的。这将产生接近零错误的代码",不。"


    2空间缩进。

    没有讨论。只有这样;-)


    每个文件一个类

    谁在乎?我更喜欢一个文件中包含的整个程序,而不是一百万个不同的文件。


    函数式编程并不比命令式编程更直观或更容易学习。

    函数式编程有很多优点,但我经常听到函数式编程人员说,对于没有编程经验的人来说,函数式编程比命令式编程更容易理解。从我所看到的情况来看,恰恰相反,人们发现一些小问题很难解决,因为当你最终进入一个没有状态的世界时,他们无法管理和重用他们的临时结果。


    没有远程调试器,无法编写Web应用程序

    Web应用程序通常将客户机和服务器端的多种语言之间的交互联系在一起,需要用户的交互,并且通常包括第三方代码,这些代码可以是任何东西,从简单的API实现到拜占庭框架。

    当我走进一个复杂的Web应用程序并使用一个相当不错的远程调试器跟踪它的实际情况时,我已经不知道有多少次我让另一个开发人员和我坐在一起,看到它们被吓坏了,惊讶于这些工具的存在。通常,即使在看到这些工具实际运行之后,它们仍然不费吹灰之力安装和设置这些工具。

    您只是不能用print语句调试一个普通的Web应用程序。如果应用程序中的所有代码都不正确,则乘以10。

    如果您的调试器可以单步执行所有正在使用的语言,并向您显示正在发生的HTTP事务,那么就更好了。

    没有Firebug就无法开发Web应用程序

    按照类似的思路,一旦你使用了Firebug(或非常接近的等价物),你就会看到任何一个试图用同情和恐惧的混合体开发Web应用程序的人。特别是对于显示计算样式的Firebug,如果你记得不使用它,花几个小时随机改变各种CSS并添加"!重要的是,"在太多的地方不好笑,你永远不会回去。


    设计模式不好。

    实际上,设计模式不是。

    您可以编写坏代码,并将其隐藏在一堆模式下。使用单例作为全局变量,使用状态作为goto。随便什么。

    设计模式是针对特定问题的标准解决方案,但需要您首先了解问题。如果不这样做,设计模式将成为下一个开发人员问题的一部分。


    信不信由你,我相信,在OO语言中,对类数据进行操作的大多数(业务逻辑)代码应该在类本身中,这在我的团队中是异端的。


    如果你有合适的工具,并且花时间正确地编写它,那么这个软件可以是无缺陷的。


    Tcl/Tk是有史以来最好的GUI语言/工具包组合

    它可能缺少特定的小部件,并且不如块上的新孩子们好看,但是它的模型优雅且易于使用,通过交互地键入命令,可以比使用可视化界面生成器更快地构建工作的GUI。它的表达能力是无与伦比的:其他解决方案(GTK,Java,.NET,MFC…)通常需要十到一百个LOC来获得与TCL/TK一行相同的结果。所有这些都不会牺牲可读性或稳定性。

    1
    pack [label .l -text"Hello world!"] [button .b -text"Quit" -command exit]


    意见:没有函数定义,返回类型会导致代码灵活易读。

    这一观点可能更多地适用于解释性语言,而不是汇编语言。需要一个返回类型和一个函数参数列表,对于像IntelliSense这样的自动记录代码非常有用,但它们也是限制条件。

    现在别误会我,我不是说扔掉返回类型或参数列表。他们有自己的位置。而90%的时间,他们更是一个利益而不是障碍。

    在某些时间和地点,这是有用的。


    在.NET上开发不是编程。只是把别人的密码缝在一起。

    由于来自一个编码背景,在这个背景下,您需要了解硬件,而这在我的行业中仍然是一个重要的需求,所以我认为高级语言只是简单地组装别人的工作。这基本上没有什么问题,但它是"编程"吗?

    微软通过努力工作和向"开发者"展示符号指令语法创造了一笔财富。我现在似乎认识越来越多的开发人员,他们似乎被类的存在或不存在所约束,无法执行某项工作。

    我的观点来自这样一个概念:作为一个程序员,你应该能够在平台允许的最低级别上编程。因此,如果你正在编程.NET,那么你需要能够将你的头伸到引擎盖下,并找出解决方案,而不是依靠别人为你创建一个类。这很懒惰,在我的书中不符合"发展"的条件。


    如果你还没有读过手册页,你就不是一个真正的程序员。


    开发项目必然会失败,除非程序员团队作为一个整体被赋予了作出与所使用的技术相关的所有决策的全部权力。


    我会说,我对编程最具争议的观点是,我真诚地认为您不应该太担心扔掉代码和重写代码。很多时候人们觉得如果你写下了什么,那么改变它就意味着你做错了什么。但是我的大脑工作的方式是让一些非常简单的东西工作,并缓慢地更新代码,同时确保代码和测试继续一起工作。它可能最终会实际创建类、方法、附加参数等,我完全知道,几个小时后就会消失。但我这样做是因为我只想朝着我的目标迈出一小步。最后,我认为比起那些盯着屏幕看的程序员在写一行代码之前,我不会花更多的时间来使用这种技术。

    我得到的好处是,我不必经常处理那些不再工作的软件,因为我碰巧以某种方式破坏了它,并试图弄清楚什么东西停止工作以及为什么。


    我更愿意真正的熟练/有经验地使用一种能有效解决现实世界问题的老技术,而不是那些仍处于青春期的"时髦"新技术。


    不要将任何东西作为单例实现。

    您可以决定不构造多个实例,但始终确保实现可以处理更多。

    我还没有找到任何使用单件的场景实际上是正确的做法。

    在过去的几年里,我对此进行了一些非常热烈的讨论,但最后我总是对的。


    要引起真正的争议:

    你什么都不知道!

    或者换句话说:

    我知道我什么都不知道。

    (这可以用很多种解释,但我想你明白了。)

    从计算机/开发开始,imho有三个阶段每个人都必须经历:

    新手:一无所知(这是事实)

    中间人:认为他知道一些/非常多的东西(全部)(这是自负)

    专业人士:知道他什么都不知道(因为作为一个程序员,大多数时候你必须做一些你以前从未做过的事情)。这不是坏事:我喜欢随时熟悉新事物。

    我认为作为一个程序员,你必须知道如何学习——或者更好:学会学习(因为记住:你什么都不知道!;)


    goto有一些(非常少的)合法用途(特别是在C中,作为异常处理的代理)。


    要成为一名优秀的程序员,真正需要在这个领域的多个方面工作:应用程序开发、系统(内核)工作、用户界面设计、数据库等等。有些方法对所有人都是通用的,有些方法对工作的某一方面是特定的。您需要学习如何像Java编码器那样编程Java,而不是像C++编码器那样编程,反之亦然。用户界面设计确实很难,它使用的是大脑中与编码不同的部分,但是在代码中实现该UI也是另一种技能。这不仅是因为没有"一个"的编码方法,而且不只是一种类型的编码。


    …开发人员不应该独自负责"思想的澄清"…是的,XKCD让我使用了那个特定的短语…

    通常我们会收到psuedo meta sorta中指定的项目,如果您想调用它,它有点特定的"代码"。通常有产品经理为项目起草初始需求,并执行基本逻辑验证的0%左右。

    我不是说技术方法不应该由架构师制定,或者说具体的实现不应该由开发人员负责,而是说它应该是产品经理的要求,以确保他们的需求在逻辑上是可行的。

    就我个人而言,我参与过太多的"简单"项目,这些项目在这里或那里遇到了一点范围渐变,然后遇到了一个"小的"变更或特性添加,这与以前的需求(无论是隐式的还是显式的)相矛盾。在这些情况下,请求边界不可能的变更的人很容易感到愤怒,因为开发人员无法使他们的梦想成为现实。


    MS Access*是一个真正的开发工具,专业程序员可以毫不羞耻地使用它。

    仅仅因为一个特定的平台是吸引那些认为自己是程序员的黑客和秘书的磁铁,就不应该弄脏平台本身。每个平台都有其优点和缺点。

    那些抱怨某些平台或工具或轻视它们为"玩具"的程序员,他们对自己的技术的了解要比自我说服他们的要少得多。对于我来说,听到程序员抨击任何他们个人没有广泛使用而不太了解的环境,这无疑是一种过度自信的迹象。

    *在此插入任何恶意工具(vb、php等)。


    开关盒不是面向对象编程

    我经常看到很多开关盒,或者是非常大的if-else结构。这仅仅是一个不将状态放在其所属位置的标志,并且不使用已经存在的真正有效的switch case结构:方法查找/vtable


    有用和干净的高层抽象比性能更重要

    一个例子:

    我经常看到同龄人花费数小时来编写复杂的存储过程,或者大量的Linq查询,这些查询为了"性能"返回非结构化匿名类型。

    它们可以实现几乎相同的性能,但需要相当干净、直观的代码。


    依赖性管理软件弊大于利

    我研究了Java项目,其中包括一百个不同的库。在大多数情况下,每个库都有自己的依赖项,而这些依赖库也有自己的依赖项。

    像Maven或Ivy这样的软件可以通过自动获取每个库的正确版本,然后递归地获取所有依赖项来"管理"这个问题。

    问题解决了,对吗?

    错了。

    下载库是依赖关系管理的简单部分。最困难的部分是创建一个软件的心理模型,以及它如何与所有这些库交互。

    我不受欢迎的观点是:

    如果你不能用口头解释项目中所有库之间的基本交互,你应该消除依赖关系,直到你能解释为止。

    同样,如果列出直接或间接从某个函数调用的所有库(及其方法)所用的时间超过10秒,则说明您在管理依赖关系方面做得不好。

    您应该能够轻松地回答"我的应用程序的哪些部分实际上依赖于库XYZ?"

    当前大量的依赖关系管理工具弊大于利,因为它们使创建不可能复杂的依赖关系图变得容易,而且它们几乎不提供减少依赖关系或识别问题的功能。

    我见过开发人员包括价值10或20 MB的库,在项目中引入了数千个依赖类,只是为了消除几十行简单的自定义代码。

    使用库和框架可能很好。但总有成本,而掩盖成本的工具本身就是有问题的。

    此外,有时候(注意:当然不总是这样),通过编写一些能够准确实现所需内容的小类来重新发明方向盘比引入对大型通用库的依赖要好。


    我觉得这个问题有趣的是,我刚刚读了第一页的答案,到目前为止,我还没有找到一个有争议的观点。

    也许这比其他任何事情都更能说明stackoverflow产生共识的方式。也许我应该从最底层开始。-)


    自动更新会导致质量较差、安全性较低的软件

    观念

    使用最新的错误修复程序和安全补丁更新用户软件的系统。

    现实

    产品必须在固定的期限内发货,通常以质量保证为代价。然后,软件发布时会出现许多漏洞和安全漏洞,以满足"自动更新"可用于以后解决所有问题的最后期限。

    现在,真正让我想到这个的软件是VS2K5。起初,它是伟大的,但随着更新的安装,软件正在慢慢变得更糟。最大的问题是宏的丢失——我花了很长时间创建了一组有用的VBA宏来自动执行我编写的一些代码——但显然存在安全漏洞,宏系统没有修复它而是被禁用了。Bang有一个非常有用的特性:记录击键并重复重放击键。

    现在,如果我真的是偏执狂,我可以把自动更新看作是一种让人们通过缓慢地安装代码来升级他们的软件的方法,这种代码会更频繁地破坏系统。随着系统变得越来越不可靠,用户倾向于支付下一个版本的费用,并承诺更好的可靠性等等。

    斯基兹


    这是我的:

    "不需要(文本)语法来表示对象及其行为。"

    我赞同乔纳森·爱德华兹和他的潜台词项目——http://alarmingdevelopment.org/


    人们抱怨把"goto"从语言中去掉。我碰巧认为任何一种条件跳转都被高估了,"if"和"switch"以及通用的"for"循环都被高估了,应该谨慎使用。

    每次进行比较和条件跳转时,都会增加一点复杂性,一旦调用堆栈深度达到几百个项目,这种复杂性就会迅速增加。

    我的第一个选择是避免条件,但是如果它不实际,我的下一个选择是在构造函数或工厂方法中保持条件的复杂性。

    很明显,这对于许多项目和算法(比如控制流循环)来说都不实用,但我喜欢推动它。

    -里克


    在彻底考虑这个问题之前,千万不要在这个问题上下决心。任何编程标准都不能证明以糟糕的方式处理问题是正当的。如果标准要求编写一个类,但经过仔细考虑,您认为静态方法更合适,请始终使用静态方法。你自己的判断力总是比任何编写标准的人最好的前瞻性思维强。如果你在一个团队中工作,标准是很好的,但是规则是注定要被打破的(当然,在很好的品味中)。


    你只需要3到5种语言就可以做到这一切。C是确定的。也许是组装,但你应该知道它并能够使用它。可能是JavaScript和/或Java,如果你为Web编写代码。像bash和一个hll这样的shell语言,像lisp,可能会有用。任何其他事情都会让人分心。


    • 很快我们就要在一个没有数据库。

    • AOP和依赖注入是21世纪。

    • 构建软件是一种社交活动,而不是技术活动。

    • 乔尔有一个博客。


    像这里的大多数其他人一样,我试图遵循像dry这样的原则,而不是作为一个人类编译器。

    我想推行的另一个策略是"说,不要问"。我不想让所有的物体都被吸气剂/设置器搞得一团糟,我想告诉他们做些什么。

    这似乎与愚蠢的实体对象和更厚的服务层(这确实需要很多要求)的良好企业实践背道而驰。嗯,想法?


    (未命名)元组是邪恶的

    • 如果您将元组用作具有独特含义的多个对象的容器,请改用类。
    • 如果您使用它们来保存几个应该可以被索引访问的对象,请使用一个列表。
    • 如果要使用它们从一个方法返回多个值,请改用out参数(这要求您的语言支持按引用传递)

    • 如果这是代码模糊策略的一部分,请继续使用它们!

    我看到人们使用元组仅仅是因为他们太懒了,懒得给对象起名字。然后,API的用户被迫基于无意义的索引而不是有用的名称访问元组中的项。


    使用C(C/C++)的人只有2种:那些不懂其他语言的人和懒惰的人。


    程序员和开发人员之间有区别。例如:程序员编写分页逻辑,开发人员在页面上集成分页。


    显然,有争议的是,在浪费时间编译之前,IDE应该检查它们是否可以链接它们创建的代码。

    但是我认为我不应该仅仅为了认识到Windows对我要创建的文件有一个锁而编译无数行代码,因为另一个程序员有一些奇怪的线程问题,这要求他在不应该使用DLL后延迟卸载3分钟。


    无论是VisualBasic还是C都不能胜过另一个。它们几乎是相同的,保存一些语法和格式。


    从长远来看,QA可以做得很好,而无需探索所有形式的测试。

    很多地方似乎都有一种"方法",即"我们如何做到"。这似乎隐含地排除了其他方法。

    从长远来看,这是一个严重的问题,因为QA的主要功能是将错误归档并修复它们。

    如果找不到尽可能多的bug,则无法很好地完成此任务。例如,当您由于太依赖黑盒而排除了方法论时,您就开始忽略所有可发现的编码错误。这意味着,通过暗示,你正在使整个类的编码错误变得不可修复,除非有人偶然发现。

    潜在的问题往往是管理层+员工。有这个问题的经理似乎对计算机科学和/或他们团队的价值主张有狭隘的思考。他们倾向于创建反映其方法的团队,以及测试方法的白名单。

    我不是说你可以或者应该一直做每件事。让我们面对现实吧,对于一个给定的产品,一些测试方法只是在浪费时间。有些方法在产品成熟度的特定水平上更有用。但我认为缺少的是测试组织挑战自己学习新事物的能力,并将其应用到整体性能中。

    下面是一个假设性的对话,总结如下:

    Me: You tested that startup script for 10 years, and you managed to learn NOTHING about shell scripts and how they work?!

    Tester: Yes.

    Me: Permissions?

    Tester: The installer does that

    Me: Platform, release-specific dependencies?

    Tester: We file bugs for that

    Me: Error handling?

    Tester: when errors happen to customer support sends us some info.

    Me: Okay...(starts thinking about writing post in stackoverflow...)


    我认为我们应该远离"C"。太老了!但是,那只老狗还在更大声地叫!!


    在代码被合并到主线之前,拥有一个涉及到代码被批准的流程是一个糟糕的想法。它在开发人员中滋生了不安全感和懒惰,如果他们知道他们可能会搞砸几十个人,他们会非常小心地对他们所做的更改,会陷入一种不必考虑他们可能影响的代码的所有可能客户的感觉。浏览代码的人不太可能像编写代码的人那样考虑过代码,因此实际上会导致签入质量较差的代码…不过,是的,它可能会遵循所有的风格指导方针,并得到很好的评价:)


    我认为使用goto语句是好的,如果您以一种明智的方式(和明智的编程语言)使用它们。它们通常可以使您的代码更容易阅读,并且不会强迫您使用一些扭曲的逻辑来完成一件简单的事情。


    关联数组/散列图/散列表(不管用您最喜欢的语言叫什么)是自切片面包以来最好的东西!

    当然,它们提供了从键到值的快速查找。但是它们也使得在运行中构建结构化数据变得容易。在脚本语言中,它通常是表示结构化数据的唯一(或至少是最常用的)方法。

    imho它们是许多脚本语言成功的一个非常重要的因素。

    甚至在C++ STD::MAP和STD::Tr1::unordeDymap帮助我更快地编写代码。


    C++是未来的杀手语言…

    …动态语言。

    没有人拥有它,拥有越来越多的特性,比如编译时(meta-)编程或类型推断,没有函数调用开销的回调,不会强制使用单一方法(多范式)。posix和ecmascript正则表达式。多个返回值。您可以有命名参数。等

    编程过程中事情进展得很慢。Javascript花了10年的时间才起步(主要是因为性能),而且大多数编程人员仍然没有得到它(JS中的类?拜托!我要说,从现在开始,15-20年后,C++将真正开始闪亮。在我看来,对于C++(语言和编译器供应商)和当今编写动态语言的程序员来说,有足够的时间来收敛。

    C++需要变得更多的程序员友好(在相同的情况下由模板或编译时间生成的编译器错误),程序员需要认识到静态类型是一个福音(它已经在进行中),在这里看到其他的答案,声称用动态类型语言编写的好代码就像语言是ST一样。打字)。


    硬编码很好!

    真的,在很多情况下,效率更高,维护更容易!

    我看到常量放入参数文件的次数你改变了水的冰点还是光速?

    对于C程序,只需将这些类型的值硬编码为头文件,将Java编码为静态类等。

    当这些参数对您的程序行为有很大的影响时,您真的希望对每个更改进行回归测试,这对于硬编码的值来说似乎更自然。当事物存储在参数/属性文件中时,诱惑是认为"这不是一个程序,所以我不需要测试它"。

    另一个好处是它可以阻止人们在参数/属性文件中乱弄重要值,因为没有任何重要值!


    简单与优化

    我认为编写既简单又最佳的代码非常困难。


    我不认为任何与优化相关的问题都应该被错误的引用所淹没:"过早的优化是万恶之源,因为被优化为模糊的代码才是使编码变得有趣的原因。"


    • XahLee:事实上,如果你能过滤掉所有的谩骂,合理地评估陈述,而不只是基于陈述背后的个性而同意(或不同意),那么你就有一些非常值得注意和合法的观点。他和其他臭名昭著的"怪人",也经常批评我使用的语言或工具。

    • [文档生成器](http://en.wikipedia.or/wiki/comparison_documentation_generators):…创建者发明了一些定制的,特别是用来记录源代码的那种,滚动您自己的语法(包括但不限于javadoc),完全是多余的,而且浪费时间,因为:

      • (一)使用量最大的人使用不足;
      • 2)所有这些小文档语言都可以很容易地用yaml替换。


    python在一半的开发时间内完成了其他编程语言所做的一切…谷歌也是!!!!如果你不同意的话,看看空腹燕子。

    等等,这是事实。它仍然可以作为这个问题的答案吗?


    XML和HTML是Web的"汇编语言"。为什么还要黑呢?

    很明显,现在很少有开发人员学习/使用汇编语言编写代码,因为它是原始的,并且使您远离必须在高层解决的问题。因此,我们发明了高级语言来封装这些级别的实体,通过我们可以在更高级别上与之关联的语言元素来提高我们的生产力。就像我们可以用计算机做更多的事情,而不仅仅是它的组成主板或CPU。

    对于Web,开发人员似乎仍然在读/写HTML、CSS、XML、模式等,并对其进行黑客攻击。

    我认为这些相当于网络或其底层的"汇编语言"。我们应该结束它吗?当然,有时候出了问题,我们就得把它砍掉。当然,这是个例外。我断言我们正在用它在Web级别的等价物替换机器级别的低级汇编语言。


    意见:发展领域的持续时间并不总是意味着与经验相同。

    许多行业都在研究一种语言的"多年经验"。是的,5年的学习经验是有意义的,因为你可能会学到新的技巧。但是,如果你在公司工作并在几年内保持相同的代码基础,我觉得作为一个在不同情况和客户需求下工作的人,你在不同情况下的曝光量并不大。

    我曾经采访过一个人,他为自己拥有10年的编程经验而自豪,并且在同一家公司工作过vb5、6和vb.net……。经过更深入的研究,我发现当他使用所有这些版本的vb时,他只是在升级和不断维护他原来的vb5应用程序。永远不要修改架构,让升级向导做他们的事情。我采访了那些在该领域只有2年经验,但从事过多个项目的人,这些项目比他更有"经验"。


    如果语言暴露了实际类型,则不要对基本类型使用关键字。在C中,这表示bool(布尔值)、int(int32)、float(single)、long(int64)。int、bool等不是语言的实际部分,而是实际类型的"快捷方式"或"别名"。不要使用不存在的东西!在我看来,Int16、Int32、Int64、Boolean等比"short"、"long"、"int"更有意义。


    删除类。.NET框架中隐式处理异常的类(类方法)数。和一个傻子一起工作很困难。


    还没有对其进行测试以备争议,但可能存在以下可能性:

    最好的代码行是你从未写过的代码行。


    编程是如此简单,一个五岁的孩子可以做到。

    编程本身并不难,这是常识。你只是在告诉电脑该怎么做。你不是天才,请不要自寻烦恼。


    被认为有害的例外情况。


    软件工程师不应该和计算机科学的人一起工作

    它们的区别:SES关心代码的可重用性,而CSS则只负责提取代码SES关心性能,而CSS只想现在就完成任务SES关心整个结构,而CSS则不在乎…


    德米特定律,在聚合和组合的背景下,是一种反模式。


    我认为有太多的人在做编程决策,不应该担心实现。


    "否则"是有害的。


    经理们什么都知道

    我的经验是,经理们通常不通过了解代码来达到目的。不管你告诉他们什么,都太长了,不对,或者太贵了。

    另一个从第一个开始:

    从来没有时间做正确的事,但总有时间再做一次。

    一位好的工程师朋友曾经说,在愤怒中描述一种情况,管理层将他的估计减半,得到了他一半同意的版本,然后给了他两倍的时间来修改,因为它失败了。这在商业软件界是很正常的事情。

    今天,当我们试图配置一个只有网络接口的路由器时,我们想到了一个问题:

    网络接口是为吸盘

    固件的早期版本上的cli非常好。这个版本有一个Web界面,它试图将网络的所有复杂性隐藏起来,使其不被毫无头绪的IT机器人发现,甚至无法正确地获取VLAN。


    我相信,"让我们重写过去,假装什么都没用去修复那个bug"是一个在绝望的情况下很有价值的调试咒语:

    https://stackoverflow.com/questions/978904/do-you-use-the-orwellian-pass-rewriting-debugging-physical-closed


    你永远不会使用足够多的语言,仅仅因为每种语言都是最适合仅有一小类问题的语言,而且很难混合语言。

    PET示例:只有当规范被很好地考虑(因为大量的相互依赖关系意味着重构地狱),以及当使用具体概念时,Java才应该被使用。Perl只能用于文本处理。C应该只在速度胜过一切时使用,包括灵活性和安全性。键值对应该用于一维数据,csv用于二维数据,xml用于分层数据,db用于更复杂的数据。


    敏捷吸吮。


    乔恩·本特利的《编程珍珠》不再是一本有用的书了。

    http://tinyurl.com/nom56r


    我认为Java应该通过瘦本地库包装来支持系统特定的特性。

    换句话说,我认为Sun决定要求Java只支持便携式功能是一个很大的错误,从几乎每个人的角度来看。

    几年后,SWT出现并解决了编写一个便携本地WIDGUI UI的基本问题,但到那时微软被迫将Java移植到C语言中,大量的C++被写入了,否则在文明Java中就可以完成。现在世界运行在C语言、VB、Java、C++、露比、Python和Perl的混合中。除了SWT之外,所有的Java程序仍然看起来和动作都很好。

    如果Java已经在本地图书馆周围使用了薄的包装器,人们就可以完全用Java编写SWT,并且我们可以根据事物的发展,在Java中制作便携的显然是本地的应用程序。我完全支持可移植的应用程序,但如果在中间件UI(和其他功能)库的开放市场中实现可移植性,而不是简单地将用户菜单减少为垃圾或用Swing伪造UI,那就更好了。

    我想Sun认为ISV会受到Java的限制,然后世界上所有新的PC应用程序都会在Sun上神奇地运行。很好的尝试。他们最终没有得到应用程序,也没有让语言起飞,直到我们可以将它用于仅逻辑的服务器后端代码。

    如果事情做得不一样,本地应用程序可能不会死。


    至少在初始设计期间,每个数据库表(好吧,几乎每个表)都应该被清楚地定义为包含一些清晰易懂的业务实体或系统级域抽象,并且无论您是否将它用作主键,还是作为其他依赖表、表的某些列(属性)或子集中的外键。应明确定义属性,以表示该表(实体/抽象)的唯一键。这是确保整个表结构表示完整系统数据结构的逻辑一致性表示的唯一方法,没有重叠或错误地分解扁平化。我坚信使用pks和fks的无意义代理键和连接功能(性能、易用性和其他原因),但我相信朝着这个方向发展的趋势使数据库社区远离了原来的COBB原则,我们失去了很多好处(数据库一致性)。提供自然键。

    那为什么不同时使用呢?


    当许多新技术出现在现场时,我对它们的了解只足以决定我现在是否需要它们。

    如果没有,我把它们放在一边,直到粗糙的边缘被"早期采用者"去掉,然后每隔几个月/年再检查一次。


    有一次我从一个同事那里看到了以下情况:

    等于a.比较(b)=0;

    我说他不能假定在一般情况下,但他只是笑了。


    显然,我的是哈斯克尔有变量。这两个问题都是"微不足道的"(根据至少8个这样的用户的说法)(尽管似乎没有人能就哪一个微不足道的答案是正确的达成一致),甚至是一个不好的问题(根据至少5个下选者和4个投票结束该问题的人的说法)。哦,我(以及计算科学派和数学家)是错的,尽管没人能详细解释为什么。


    设计模式和文档的使用

    在网络开发中,这些东西的使用从来没有感觉到它的任何使用。


    人脑是所有锁的万能钥匙。

    在这个世界上,没有什么东西能使你的大脑移动得更快。相信我,这不是哲学上的,而是实际的。就意见而言,他们是

    1)永远不要超出编程语言指定的边界,一个简单的例子是C和C++中的指针。不要滥用它们,因为你很可能会犯该死的分割错误。

    2)始终遵循编码标准,是的,你所读的内容是正确的,编码标准与你的程序无关,毕竟你的程序是为机器执行而编写的,但要被其他人理解:)


    system.data.dataset岩石!

    在我看来,对于大多数业务应用程序,强类型数据集比自定义DDD对象更好。

    理由:我们正在努力找出定制对象、LINQ到SQL、实体框架的工作单元,这增加了复杂性。从某个地方使用一个好的代码生成器来生成数据层,工作单元位于对象集合(数据表和数据集)上——这不神秘。


    并非所有的东西都需要封装到它自己的方法中。有时,让一个方法做更多的事情是可以的。


    对自己有争议,因为有些事情最好不说,所以别人不会把你描绘成太自负的人。但是,这里是:

    如果是的话,就从我开始


    你必须知道C才能称你自己为程序员!


    C++ STL库是通用的,它对于任何人来说都是最优的。


    日志配置是浪费时间。如果这意味着学习一种新的语法,尤其是一种无声失败的语法,为什么还要使用它们呢?别误会我,我喜欢好伐木。我喜欢记录器继承并向记录器的处理程序添加格式化程序。但是为什么要在配置文件中这样做呢?

    是否要在不重新编译的情况下更改日志代码?为什么?如果您将日志代码放在一个单独的类、文件中,那么它会有什么区别呢?

    是否要将产品的可配置日志分发给客户端?这不就是提供了太多的信息吗?

    最令人沮丧的是,用流行语言编写的流行实用程序倾向于用语言指定的格式编写好的API。编写一个Java日志记录实用程序,我知道您已经生成了JavaDoc,我知道如何导航。为您的记录器配置编写一种特定于域的语言,我们有什么?也许有文件,但到底在哪里?你决定了一种组织方式,而我对你的思路不感兴趣。


    不要太担心要学习什么语言,使用像c或python这样的行业重量级。像Ruby这样的语言在卧室里很有趣,但在工作场合不需要蹲着。C语言和Java语言可以处理非常小的大型软件项目。如果有人不这么说,那么你说的是脚本语言。时期!

    在开始一个项目之前,考虑网络上有多少支持和代码示例可用。再者,选择一个像Ruby这样的语言,在Java上与Java相比,只有很少的代码示例,这只会让你在遇到问题时更痛苦。

    当你的老板问你编码进展如何的时候,你不能在论坛上发布信息并期望得到回复。你要说什么?"我正在等待有人在这个论坛上帮助我。"

    学一门语言,学好它。学习多种语言可能会带来技能和实践,但你甚至只会在所有这些方面都很好。擅长一个。在Java中有完整的线程专门用于线程,当你想到它时,只有超过100的一个命名空间。

    掌握其中一个或多点都好。


    "不要从构造函数调用虚拟方法"。这有时只是一个pita,但只是因为在c中,我不能决定构造函数中的哪一点调用我的基类的构造函数。为什么不?.NET框架允许这样做,那么C_不允许这样做有什么好的理由呢?

    该死!


    C必须死。

    当另一种语言(如d)可用时,在C语言中自动编程应该因疏忽而受到惩罚。


    复制/粘贴不是反模式,事实上它有助于避免产生更多的错误。

    我的经验法则-只键入不能复制/粘贴的内容。如果创建类似的方法、类或文件,请复制现有的方法、类或文件并更改所需的内容。(我不是说要复制一个本应放入单一方法中的代码)。

    我通常从不输入变量名——要么复制粘贴它们,要么使用IDE自动完成。如果需要一些DAO方法-复制类似的方法并更改所需的方法(即使90%将被更改)。对于某些人来说,可能看起来非常懒惰或缺乏知识,但我几乎从不需要处理导致我拼写错误的问题,这些问题通常很难捕捉(如果在编译级别上没有检测到)。

    每当我离开复制粘贴规则,开始输入一些东西时,我总是拼写错误(这只是一个统计数字,没有人能写出完美的文本),然后花更多的时间试图找出哪里。


    引用已故的E.W.Dijsktra:

    编程是应用数学中最困难的分支之一;较差的数学家最好还是纯粹的数学家。

    计算机科学与计算机无关,天文学与望远镜无关。

    我不明白一个人怎么能声称自己是一个合适的程序员而不能够解决像这个这样简单的数学问题。也许是一只积垢猴子,但不是程序员。


    WordPress是一个CMS(从技术上讲,确实如此)。

    https://stackoverflow.com/questions/105648/wordpress-is-it-a-cms


    一个真正的程序员喜欢开源就像一个灵魂伴侣,喜欢微软像一个肮脏但令人满意的妓女。


    "优秀的代码编写者和优秀的代码编写者可以重用它",这种情况正在发生,但"优秀的代码编写者"是唯一一个喜欢这种代码的人。而"伟大的程序员"仅仅是为了找出其中的缺陷,因为他们没有时间思考和编码。但是他们有时间在代码中找到错误。

    所以不要批评!!!!!!!!!!!

    根据需要创建自己的代码。


    由于缺乏多样性,软件很差劲。不冒犯任何种族,但当一个职业由不同的种族和性别组成时,事情会很好地工作。看看过度使用不可再生能源。很好,因为每个人都在贡献,而不仅仅是"老一套的人"


    开发人员应该能够在没有得到任何人许可的情况下修改生产代码,只要他们记录他们的更改并通知适当的各方。


    我有争议的观点是,"while"结构应该从所有编程语言中删除。

    在使用"repeat"和布尔标记时,您可以轻松地进行复制,我只是不相信使用这两个结构是有用的。事实上,我认为在一种语言中同时使用"repeat…until"和"while…endwhile"会混淆新的程序员。

    更新-附加说明

    新程序员在while中犯的一个常见错误是,他们假设一旦测试条件标记为false,代码就会中断。所以-如果while测试在代码的中途标记为false,那么它们假定while循环中断。重复的话,这个错误就不会那么严重了。

    实际上,只要只有一个循环类型,我就不必担心保留哪一种循环类型。我选择"重复而不是同时"的另一个原因是,使用"重复"编写"同时"功能比使用其他方法更有意义。

    第二次更新:我猜我是目前唯一一个得分为负的人,这意味着这是一个有争议的观点。(不像你们其他人。哈!


    如果它不是本地的,就不是真正的编程

    根据定义,程序是由计算机运行的实体。它直接与CPU和操作系统通信。不直接与CPU和OS对话,而是由其他直接与CPU和OS对话的程序运行的代码不是程序,而是脚本。

    在Java出现之前,这只是简单的常识,完全没有争议。突然间,出现了一种脚本语言,它具有足够大的功能集,可以完成以前专门属于程序领域的任务。作为回应,微软开发了.NET框架和一些在其上运行的脚本语言,并通过缓慢减少对开发工具中真正编程的支持而有利于.NET脚本的支持,使情况进一步恶化。

    尽管它可以完成许多您以前必须为之编写程序的事情,但任何类型的托管代码仍然是脚本,而不是编程,并且用它编写的"程序"可以并且总是共享脚本的性能特征:它们运行得更慢,并且使用的RAM比实际(本机)程序要多得多。重复同样的任务。

    人们称之为IT编程,通过简化定义对每个人都是一种伤害。这会导致整体质量下降。如果你试图让编程变得如此简单以至于任何一个白痴都能做到,那么你最终得到的就是很多白痴,他们认为他们可以编程。


    两行代码太多。

    如果一个方法有第二行代码,那就是代码味道。重构。