7

您知道代码中对项目至关重要但可能需要大量时间才能完成的特定部分吗?您是否曾经觉得您宁愿从事其他事情(可能不太重要)或根本不编写代码而不是从事那部分工作?你那么努力避免并使用你知道的每一个懒惰的技巧来延迟它不可避免的实施?

现在,我可能只是懒惰,但我总是不得不处理这样的代码。写一些我不想写的东西(如果你是为了好玩而没有得到报酬,那就更糟了!)。一个大型系统需要花费大量时间才能进入一个阶段,在该阶段您可以获得任何有用的结果或表明它正在工作的迹象。你如何开始编写这样的代码?大多数人可能会建议分而治之和类似的架构技术,但这与您如何做无关;这是关于你如何让自己开始做这件事的。你会采取的第一步是什么?

4

9 回答 9

16

我将讲述一个发生在我身上的案例。

我想为使用前向动态编程(维特比算法)的 x264 实现一种新的帧类型决策算法。但它会变得复杂、凌乱、丑陋等等。我真的不想这样做。我试图将这个项目抵押到 Google Summer of Code 上,但由于某种糟糕的运气,我们让一个学生简单地放弃了他的项目……就是选择那个项目的学生。

所以经过两个月的抱怨和回避之后,我终于开始研究算法了。这就是我的做法。

首先,我与另一位开发人员进行了交谈,他显然已经对如何做到这一点有了一些想法。我们讨论过,他向我解释,直到我从算法的角度完全理解了这个过程。这是任何此类项目的第一步:充分了解其背后的算法,以便您可以对整个事物进行伪代码。

然后,我和我的另一位同事交谈。我们走到一块白板上,我把它画出来,直到也理解为止。通过向别人解释它,我获得了自己的理解。这是第二步:向其他人解释算法,以便他们可以对其进行伪编码。这是对编程过程的模拟,因为编程是向计算机“解释”算法的一种形式。

然后,我编写了一个简单的 Java 原型,它使用任意假值作为成本函数,并且仅用于测试 Viterbi 搜索。我完成了它,并通过详尽的搜索检查了它——它完全匹配。我的动态编程是正确的。这是第三步:在最简单的环境中编写最简单的算法形式。

然后我将它移植到 x264 的母语 C。它再次起作用了。这是第四步:将算法的简单形式移植到完整的环境中。

然后,最后,我用真实的成本函数替换了假成本函数。经过一些错误搜索和修复后,它起作用了。这是最后一步:将算法与环境完全集成。

这个过程只用了一周时间,但从项目开始时的我的角度来看,这完全是令人生畏的,我什至无法开始——然而把它分解成这样一个循序渐进的过程,我不仅能够完成它,而且比我预期的要快得多。

好处远远超出了 x264;我现在对维特比了解得如此透彻,以至于我现在可以向其他人解释……其他人也可以从中受益匪浅。例如,一个 ffmpeg 开发人员正在使用我的算法和代码的改编来优化解决一个稍微不同的问题:音频文件中的最佳标题放置。

于 2008-09-28T11:30:37.540 回答
3

一般来说,我喜欢大而复杂的部分。它们是真正扩展挑战并迫使我仔细考虑我在做什么的部分。这是我不喜欢的所有小而乏味的部分。然而,当谈到做任何我一直在拖延的事情时,我发现一个简单的建议很重要:做

它!

说真的,一旦开始,完成就容易多了。我总是发现我把事情推迟到开始之前,然后突然发现,现在我开始了,它并没有我想象的那么糟糕,你看,它已经快完成了!

于 2008-09-28T11:30:40.117 回答
3

分而治之不仅仅是构建代码,它还可以作为一种使项目在概念上易于管理的方法。如果我很难开始一个项目,那几乎总是因为它又大又可怕。通过划分成概念上可管理的部分,它变得不那么可怕了。

我也相信务实的程序员所描述的“追踪子弹”。项目简化为核心部分的最简单的“概念证明”,例如没有 UI、特殊情况、错误处理等。也许它只是一些带有相关单元测试的核心例程。有了这个,你已经征服了可怕的部分,并且可以从核心开始构建。

基本上开始的技巧(至少对我来说)是:不要从整个项目开始。从一个小的(最好是核心)部分开始,然后从那里开始构建。如果我还是很难入手,那是因为我决定的那个小部分还很大,所以我必须进一步划分和减少它。

于 2008-09-28T11:31:19.770 回答
0

我同意你的观点,软件的许多大而重要的部分编写起来并不有趣。我通常从一些较小的事情开始我的开发日,比如在这里添加一个功能,或者在那里修复一个错误。时间到了,我会从大部分开始,但是当我再也看不到东西时,我会做一些不同的事情。如果您仍然按时完成所有工作,那很好。记住,如果你在做之前、做的时候和做完之后和其他人谈论那个大型野兽,这可能会让事情变得更容易。这不仅可以解放你的思想,还可以从不那么主观的角度获得其他人的意见。一起计划这些事情也有帮助。

于 2008-09-28T11:27:34.990 回答
0

有趣的是,我恰恰相反。当我开始解决问题时,我会先解决大问题。问题的核心通常是我感兴趣的。

如果我正在为自己做一个项目,我通常不会费心去实现边缘周围的所有模糊位,所以它们永远不会完成。如果我真的在做某事,我最终会得到所有模糊的部分,但这不是我最喜欢的部分。

于 2008-09-28T11:29:39.477 回答
0

我认为这里有两个问题。

首先实际上是开始。正如你所说,这可能非常棘手。就我个人而言,我只是从任何一点开始,只是为了在纸/屏幕上得到一些东西。它可能是错误的,需要编辑,但总的来说,批评比创造更容易,即使是在你自己的工作上。

然后是解决难题的实际过程。有一本很棒的书叫做“概念大片”,它讨论了解决问题的各种方法。我学到了很多关于如何解决问题和使用那本书的盲点。强烈推荐。

于 2008-09-28T11:30:17.993 回答
0

我试图为系统试图做的事情建立一个隐喻。当我可以用隐喻来描述行为时,我总是会感觉更舒服。

然后我从测试驱动开发的角度来处理它,即通过设置将验证正确行为的测试来开始描述系统需要做什么。

HTH。

干杯,

于 2008-09-28T11:35:12.633 回答
0

该项目最困难的部分是从无所事事到第一线。只要把任何东西写在纸上,这个过程就开始了,令人惊讶的是,其余的东西可以如此迅速地从这里流出。

我自己是“分而治之”型方法的粉丝。

当系统中有一项特别大的任务悬在我头上时,我会离开计算机,拿起笔和纸,将任务分解为所有逻辑组件和工作流程。

然后完成这些任务中的每一个,并将其分解为所需的最基本功能/调用。

然后我可以放入我认为我需要的存根方法。并将它们一一充实。在这一点上,这些“子任务”中的每一个都不比围绕同一个项目的较小的开发任务大,所以感觉就像一个不那么繁重的任务悬在我头上。

于 2008-09-28T12:10:08.570 回答
0

我通常在家里用一支笔和一张纸来解决这类问题。我想象算法和/或逻辑流程,然后存根(在纸上!)类和方法存根,当我遇到一个/计算机我可以更轻松地做到这一点......可能只是我......

于 2008-10-05T19:38:18.837 回答