为什么程序员在开始编写代码之前设计算法更好?


12

合适的算法是否真的有助于提高程序的质量并最终提高程序的效率?

如果没有该算法,我们还能生成高质量的程序吗?

在现代编程中,必须使用合适的算法吗?


5
根据定义,有一些算法,即使它很糟糕也很好

5
我别无选择,只能捣乱代码而不是想太多。大多数时候,没有任何标准的光荣算法。我只是想擦亮一个臭臭的粪便;)
乔布(Job

13
我不敢相信这是一个严重的问题。参见en.wikipedia.org/wiki/Algorithm
Steven A. Lowe

2
标题是合理的,但问题的文本则不太合理。我认为他是在问是否必须先确定算法,然后才能开始编写实际代码。
格雷格,

9
我说不。。。最好总是漫无目的地行驶,直到您偶然发现目的地或汽油耗尽。
2011年

Answers:


29

我认为这个问题有其历史渊源。

回到“过去”(我不是亲眼目睹的人,所以这只是我那个时代的重建-如果您体验不同的话,可以纠正我)。与今天相比,硬件空间和性能都为零。所以人们当时写的所有东西都必须非常高效。因此,他们需要进行大量思考和研究,以发明出最佳算法来实现所需的时空性能以完成工作。另一个因素是,开发人员主要在开发您可以称为基础架构的东西:操作系统,协议栈,编译器,设备驱动程序,编辑器等。所有这些都被很多人使用,因此性能确实会有所不同。

如今,即使是基本的笔记本电脑(甚至在手机中),多核处理器和千兆字节的内存都具有令人难以置信的硬件性能。这自然意味着,在许多情况下,性能(即算法)不再是中心问题,而且提供快速解决方案比提供快速解决方案更为重要。OTOH,我们有大量的框架可帮助我们解决问题,并同时封装大量算法。因此,即使我们不考虑算法,也很可能会在后台使用很多算法。

但是,在某些领域中,性能仍然很重要。在这些领域中,在编写代码之前,您仍然需要考虑很多算法。原因是算法是设计的中心,它决定了周围代码中的许多数据结构和关系。而且,如果您发现算法来不及扩展(例如O(n 3),为时已晚),那么当您在10个项目上对其进行测试时,它看起来既不错又快速,但是在现实生活中您将拥有数百万个),这非常很难在生产代码中替换它,并且容易出错。如果基本算法不适合您,那么微优化将无济于事。


1
真是个答案。我很荣幸有你在这里!
杰维斯

5
而且计算机比编程器贵得多,因此使编程器更加努力是有道理的!

2
没错,我们正在优化的东西已经改变。但是现在我们期望比人们操纵的系统复杂得多。缺乏计划,组织和维护的思想仍然会杀死您。
btilly 2011年

1
@btilly,我同意非常重要的一点是,提前计划(尽可能多,但不要再多)并事先考虑维护。但是,这并不一定意味着要花大量时间在算法设计上。例如,如果一个函数每月运行一次,并且需要一个小时才能完成,那么即使您将其执行时间减少到10分钟,花几天时间进行算法优化也可能是过头了。好处只是不能证明成本。
彼得Török

2
有两件事:首先,算法可以确定程序的扩展能力,这通常很重要。其次,当今许多软件在服务器上并行运行。这意味着,如果将程序Z修改为以两倍的速度运行,那么无论运行多少程序Z的服务器都需要一半。
David Thornley,

14

只是指出一点:

算法本身就是问题的一般逐步解决方案。因此,如果您解决了该问题,则实际上确实使用了一种算法。

这里最重要的一点是,您必须使用一种算法或另一种方法来解决问题。在大多数情况下,最好在跳到编码之前先考虑一下问题-这个阶段通常称为设计。但是,您将执行多少操作以及采用哪种方式取决于您。

另外,您不应将算法的概念与流程图混在一起(我怀疑这是在这里进行)。流程图只是可以使用的一种图形表示形式,在较早的时候用于说明算法。如今,它已经过时了。

编辑:

确实有很多方法可以表示算法,而编程语言代码本身就是其中一种。但是,往往最好不要一次解决整个问题,而只是立即确定轮廓,然后随便填空,这会更好或更容易。

  • 我个人最喜欢的是伪代码,它只是覆盖了所讨论算法的一般抽象轮廓-用伪代码深入研究细节是荒谬的,这才是真正的代码。

  • 但是实际代码可以用于大纲。例如,TDD人们喜欢在编写代码时设计算法,并且由于他们也不能一次解决所有问题,因此他们以真实代码设计程序执行的大纲,并使用模拟对象(或函数,方法)。 。)作为空白,稍后再填写。

  • UML活动图似乎是旧式流程图的现代化形式,并为诸如多态和多线程之类的新事物添加了注释。我真的不能说这有多大用处,因为我并没有真正使用它们-我只是为了完整性而提到它。

  • 另外,如果您将算法基于状态之间的切换,那么状态图会很有帮助。

  • 通常,您只需要 简单地勾勒出某种算法背后的想法就可以了。


呈现算法的方式有很多,您建议采用哪种方式?又为什么呢?
杰维斯

@Jervis:看到我的更新,我列出了其中的一些。
Goran Jovic

链接在哪里?
杰维斯

4

一个很好的类比是,您在开始烹饪之前必须知道一个食谱。好的,您可以随时进行调整,但是在开始之前,您仍然需要知道要做什么。如果我想炖羊肉,那我要做的事情和我要烤一条面包要大不一样。


算法=想法???
杰维斯

算法==配方!!

但是不同的厨师根据相同的食谱有不同的烹饪方式。
杰维斯

当然,当我烤面包时,它和我妻子烤面包时的情况有所不同。但是基本部分是相同的(面粉,水,酵母,盐)
Zachary K

也有店铺在那里你可以去购买的由专业面包师做面包
JK。

3

代码实现算法。在没有设计算法的情况下尝试编写代码就像在建造墙壁之前先油漆房子。自编程开始以来,算法一直是“必须”。


好。画房子就像ABC一样容易,您可以在没有房子的情况下开始计划。
杰维斯

2
@Jervis:同样,您可以计划代码的某些部分,而无需为其他部分指定算法(例如,您可以确定将有一个对数据进行排序的函数,而无需决定数据的工作方式-但您需要在确定时间之前编写排序代码)。
杰里·科芬

1
与画房子相比,我更喜欢画画。如果我所有的编码都像画房子一样,我会找到另一份工作。画一幅画可以是反复的。在我对算法完全了解之前,我经常开始在真实代码中进行原型制作。实际上,大多数情况下。
格雷格,

3

精通您的语言有助于提高质量和生产力。解决小算法问题比重复相同MVC材料100次要有用得多。
虽然,我想还有其他方法可以达到流利程度。

算法将成为现代编程领域中的必备技术吗?
除非您是写“ cool codez”的“ php ninja”,否则它已经是“必须”。所有“最佳”公司(Google,Amazon等)都会在面试中测试您的算法经验,我想他们会无缘无故地这样做。

但是回到原来的观点,如果您想改进,就应该不断挑战自己。而且由于正常的工作(也就是“现在写CRUD管理器来容纳100个以上的对象”)并不总是带来很好的挑战,因此算法可以弥补这一点。


1

我想说,在开始编码之前,至少需要一个算法的初步概念。在基于数据结构等进行编码时,您可能会修改您的想法。

如果分析表明该区域存在性能问题,稍后您可以再次修改代码。


1

原因是在编写错误的代码之前,可以更快地修复错误。

更为平淡的是,通常会测量出不同程序员之间10到1的生产率差异。当您看到生产率是10倍的程序员时,他们实际花费的时间是最小的。输入代码的时间不应成为瓶颈。取而代之的是,他们将大部分时间都花在确保有直截了当的需求,计划,测试等方面。

相反,当您看到不停地潜入代码的程序员时,他们不可避免地不得不一遍又一遍地编写代码,因为他们遇到了完全可预见的问题,而最终的结果则是难以维护且容易出错。(顺便说一句,您确实知道平均80%的软件开发支出是在维护阶段?使事情变得可维护很重要。)


你是绝对正确的。
杰维斯

1

通常,算法和数据结构优先,然后编码。但这在很大程度上取决于编程领域。我曾经做过许多应用数学类型的工作,并真的低头看当时流行的瀑布模型。那是因为低至中等级别的算法很少被认为是理所当然的。在存在未成文子系统的情况下设计一个大型结构,然后在游戏后期发现那些关键子系统之一的数学计算不正确(不稳定或其他原因)。因此,我始终首先考虑最具挑战性的子系统,如果有任何疑问,我会首先编写并进行单元测试。但是,对于某些问题领域,您无需进行大量计划就可以投入工作。


我同意你的看法。
杰维斯

您在这里谈论的是自顶向下和自底向上设计之间的区别,这是一个不同的问题。当您“向前犁”时,您仍在实现某种算法。您可能不会用这些术语来考虑它,可能是因为该算法对您而言似乎很明显,或者因为您已经非常熟悉该问题,但这并不意味着该算法还不存在。
Caleb

0

在各部分中设计一种算法,然后拆分这些部分并分别对每个部分进行编码。这样,您可以混合两种观点:

  1. 使用您的语言能力来使算法起作用
  2. 尝试在代码之前思考,这样您的想法就不会与该语言融合(有一天您需要将算法转移到另一种语言,然后以spagetthi结尾)

没错 我知道算法与语言无关。的确,您可以使用任何现有的编程语言来表达相同的算法。
杰维斯

0

对我来说,几乎所有代码。我认为对于大多数高生产率的程序员来说都是如此。我可以像编写文本一样轻松地编写代码。

我尽可能地将需求捕获为可执行测试(代码)。设计只是高级编码。以目标语言捕获设计比以其他某种形式捕获设计然后翻译它更快,更精确。

我发现大多数用户无法有效地查看文字要求。他们可以使用顺序用例,但是用例不能捕获UI的每个方面。到目前为止,最好的方法是首先切入实现,让用户尝试一下,获取他们的评论,然后相应地修改代码。


0

当您坐下来开始编码时,您会想到一个算法,无论该算法是否“设计”。

如果您坐下来开始编写代码时没有考虑完整的算法,那么您将执行以下操作之一:

1)随机捣碎密钥。这可能会产生编译器错误

2)编写可编译的代码,除了您要执行的操作外,它可能会执行任何操作

3)编写代码来解决问题的一小部分,并以一种聚合的方式在问题上不断发展,但并没有真正地思考-因此最终问题得以解决-但是代码不是非常有效的方式,并且一路上不得不回溯和浪费时间的可能性

因此人们通常会在脑海中编程一个算法。它可能已在纸上或其他某种介质上充血或推理过。

最好考虑用键盘以外的方式思考问题的攻击,特别是在您早期作为程序员的时候。正如其他答案所指出的那样,随着您的经验越来越丰富,您将可以更好地“动态”编写一些可管理的更大问题。但是,对于困难或大问题,可以从键盘上进行思考和设计是很有用的:与代码互动时,您更有可能根据语言的结构以及如何处理语言中最紧迫的任务进行思考。问题。例如,用笔和纸来思考问题,可以使您从代码的语言方面解放更多,并可以从更高的层次进行思考。


0

您需要停止从根本上将软件构建视为有价值的其他事物的构建。它不是。因此,与其他任何事物一样,始终需要经过周密考虑的计划或设计。

合适的算法是否真的有助于提高程序的质量并最终提高程序的效率?

适当的建筑计划/方案是否有助于有效地建造优质房屋?

如果没有该算法,我们还能生成高质量的程序吗?

如果没有适当的建筑计划,您能否有效地建造高质量的房屋?根据《无限猴子定理》,概率上是这样(就像一百万只猴子在永恒中随机打字一样,它们最终会打字出莎士比亚的全部著作。

在现代编程中,必须使用合适的算法吗?

如果您不想成为代码猴子,并且想要确保您不提供外观和工作原理像屎一样的软件,是的,这是必须的。我必须挽救的每个项目(因为代码看起来像是无法忍受的东西)总是以否定的答案开始。

实际上,现代编程已经远离了牛仔编程软件工程师,因为牛仔编程软件工程师必须进行某种规划。

即使您拥有可用的算法和数据结构库(例如,C ++中的Boost或Java集合库),您也必须知道这些东西是如何工作的,以适当地使用它,并将其组合为合理的,级算法。


-2

这不是更好。最好不要“设计”任何东西。那是给那些不写程序的人的。您知道,那些真正有问题经验的人。如果您是数学家,工程师或后勤人员,那么您需要在其他地方进行处理。但这不是“编程”。

首先进行某种测试和基准测试。

然后写点什么。进行refactor-rewrite -loop,直到时间用完或无法再改善为止。

尽管许多人似乎认为一个人可以用计算机做某事而无需实际在计算机上做任何事情,但我认为这是最普遍的神话之一。建筑宇航学。

同样,您无法在编写算法之前对其进行优化。

IOW,“紧贴金属”。

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