应对无法解决的无尽项目


10

我们有一个大型的(1200多个小时)网站,其中包含很多技术债务。这主要是由以下(通常)原因引起的。

  1. 在开发过程中来来往往的多个程序员。
  2. 在开发过程中更改规格。
  3. (在短时间内)添加了许多附加功能。

客户需要大量新功能,这基本上归结为每周进行10多个小时的项目开发。

由于技术债务,我们花费大量时间来修复或调查问题,这些问题通常是由以下原因之一引起的:

  1. 一个无耻,愚蠢的虫子,让人哭泣。
  2. 以上是产生新功能的原因,因为我们并未预见到新功能会在所有地方产生影响。
  3. 我们面临的其他一些问题(服务器迁移,升级)

我们每天都有问题,我们试图采取以下措施来阻止这种情况:

  1. 创建有关网站导入,付款和一般工作的技术文档。
  2. 一周开始时开会-讨论当前的问题或改进以及应如何解决。
  3. 有一个测试计划。程序员A测试B,B测试C和C测试A。然后我们的项目经理将进行一些测试。关于此功能的影响,我们将其投入到临时环境中,并让客户自行检查。

问题在于问题一直在发生……而我们却无法控制它。新功能仍然会导致错误,而旧错误会一直打招呼。不知何故-也许由于项目的规模-我们似乎无法控制这个项目。

我假设有很多程序员正在从事更大的项目。这就是为什么我要问我的问题:

在大型项目中,我们应该怎么做,或者如何避免这些问题?

较小的修改,更多信息:

  1. 我们使用版本控制(SVN)。
  2. 我们有DTAP开发过程。

2
除了“开发和维护大型Web应用程序的正确方法是什么?”之外,我不确定这里是否有足够具体的问题?
JeffO 2011年

我试图使其尽可能具体。我想听听人们对我们的处境,改进之处的看法,或者分享他们自己的经验以及他们如何解决此问题。
韦斯利·范·奥普多普

您有构建引擎吗?哪些构建可交付成果?每次有人检查东西吗?


3
太糟糕了,卡夫卡为时过早,无法撰写有关软件系统的文章。
David Thornley,

Answers:


11

我会扮演恶魔的拥护者,经常看到结果如何:您无法应对。我保证您是唯一真正看到系统实际问题的人,否则您将不必问如何应对它,因为公司文化将是消除错误并修复代码的人只要有可能,即操作真正的专业人员的工作方式。

我敢打赌,开始编写单元测试太大了,因为它没有任何人比您更早地知道如何进行单元测试(幸运的是,您团队中的其他人),而且不可能知道从哪里开始,甚至不可能测试,因为它依赖于确切的实现和具体的数据,因此将所有内容剥离到接口,模拟,存根等之类的时间太长,以至于无法对其进行测试。我还敢打赌,您不能只是重构需要重构的内容,因为它耦合得太紧了,并且由于没有测试,谁知道修复错误代码会破坏什么。简而言之,它可能变得过于癌化而无法认真修复,但是当然不能仅仅将其切掉并重新开始。

我的朋友,你在打一场失败的战斗。要么您会因沮丧而精疲力尽,然后最终退出或疯了,或者如果您抱怨它足够长的时间,试图让其他人意识到问题,他们会认为唯一的问题就是您,并且您会看到门。


1
+1为先知。我觉得你在我最后的工作地点跟随我,开始做笔记。我确实想发表评论,并说它不必像您描述的那样可怕。当一个有干劲的A型性格能够理解问题的人陷入根深蒂固的办公室政治中而变得有效时,我就会看到糟糕的管理会带来真正的改变。很多时候,就像操纵大船一样,庞大的旧车转180度需要很长时间。
maple_shaft

1
可悲的是,我所说的基本上就是我的发展生涯的故事。我不能从事办公室政治工作,所以人们和那些做事的人根本不是“ A型”人物(或者他们是但不了解问题),所以除了我以外,什么都没有改变。
韦恩·莫利纳

1
等一下 我不会说它会变得更好,只是它会变得更好。我的职业生涯大部分时间都是这样的有毒环境。大约一半的软件开发商店都在某种程度上存在此问题,这似乎比实际情况更普遍,因为这些地方总是在招聘,营业额往往很差。假设薪水和福利是可比的,人们往往不会离开使用行业标准最佳实践的商店。我会更好地在面试中发现这些功能失调的工作环境,相信您的直觉,如果感觉不对,就会使您烦恼。
maple_shaft

2
继续...例如,听一些关键短语,例如“我们正在迈向敏捷”,这表明发展正在推动它,但是文化拒绝了它。询问您的前任或您要更换的人发生了什么,他在该项目或公司工作了多长时间,并询问了团队以及他们在公司工作了多长时间。如果面试官对透露此信息有任何犹豫,那就是一个危险信号。在接受要约之前,请查看glassdoor.com,对公司进行一些研究。我现在工作出色,这并非偶然。
maple_shaft

看来我的悲观观点与某人不合。
韦恩·莫利纳

4

如果您不进行任何单元测试,则是一个很好的起点。至少在修复旧错误时,它们将保护您免于添加新错误。

源代码控制也有帮助,除非您不使用它。尤其是,责备和日志功能可以很好地查明错误代码是如何/为什么提交的。

在客户方面,我发现在请求更改/附加功能后立即讨论价格和(冗长的)延迟是合理的,并且花费在讨论/设计这些时间上的费用也是如此。通常,客户会再三考虑是否可以等待。

(通过对比,如果您立即和他一起研究规格和实现想法,他们通常会为您设置“哦,我以为我们已经同意您仍然可以这样做”,或者(更糟的是,经过几天的回复, ”)“但是,看,它已经设计好了,我们讨论的内容听起来并不那么难!”。)

最后但并非最不重要的一点是,我发现预先准备好,每天只阅读一次电子邮件(上班后才去看),并且拥有一部能处理任何紧急情况的电话,从而大大提高了生产率。


3

我建议您添加一些基于CI的测试,主要是在最频繁出现故障的区域。这将帮助您在项目上完成工作时提高质量。

哪些区域/功能更频繁地中断也变得更加明显,因此更容易确定哪些零件需要重构,或者至少需要增加测试。

在增加每个功能所需的时间和时间方面,增加了更多的手动测试风险会使项目走错了路。

进行一些代码审查非常有用,但这也许是A-> B-> C-> A测试方案的一部分。(也许代码朝另一个方向审查?)


1

让我向你寓言。当天早些时候,您正和一个人一起散步,然后到达目的地。与您同行的人很快发现他在途中某处丢失了戒指,因此您俩都决定回溯并继续寻找它。与您同行的人很快停在路灯柱上,开始疯狂地看着。您说:“当我认为当我们切入小巷时您可能已经失去了灯柱时,为什么要在那儿看灯柱?”。他回答说:“我知道,但是这里的光线更好。”

我在这种情况下已经经历了多次,并且注意到了一些共同点。这些类型的维护噩梦项目通常在过程繁重的环境中运行,需要管理层进行严格的监督和过程改进。我并不是说流程改进不是一件坏事,但管理人员通常希望实施的流程改进类型通常有两个关键点。

1)他们通常不会破坏办公室的政治和权力平衡。2)他们成功地创造了管理控制的错觉,而不是触及问题的核心。

管理层认为“这里更好”,通常是说:“每个新功能都必须有详细的技术规格”,或者“让我们每天召开一次每小时一次的状态会议,讨论问题以及如何解决这些问题。”

这些事情都不是问题的核心,它们可能只是降低生产率,但它们肯定证实了管理层对控制的幻想。

您可以帮助推动的唯一真正的变化就是那些会动摇一切的变化。我怀疑您目前对网站的厌恶程度可能无法修复,因此您将在重新架构和重写方面走得更远。但是,对于将来,您可以记住敏捷方法,持续集成,测试驱动的开发,代码审查和业务需求规范的重要性,这些方法在严格的变更控制程序下进行管理,以帮助在不进行计划调整的情况下最大程度地减少范围蔓延。

这些变化确实需要在管理级别上改变思维方式,而在我的整个专业经验中,如果没有某种中层管理级别的调整,我从未遇到过这种变化。我希望这不会太令人沮丧,因为无论您是否在艰苦的战斗中,都应该尝试正确的方法,因为您可能会遇到热爱现状的人强烈抵抗。


1

我前一段时间去过同一地点。我不再感谢两个简单的规则:

  • 每周花费一两天的时间来修复/重写应用程序的大部分毛发部分。没有漏洞寻找,没有新功能开发。
  • 在实施新功能时,即使我们花费的时间比客户预期的时间长,我们也会努力做到正确。

唯一的问题是要让其他人尊重他们。容易的部分令人惊讶地是客户。不能真正解释原因,但是以某种方式我们说服了他,当我们使用某个功能更长的时间时,对每个人都更好。尊重第一条规则会带来更多问题,但是我们也认为这对我们有很大帮助。随着应用程序不同部分的不断完善,它保证了稳定的进展。


1
+1,但这通常是最难获得的东西,因为通常“客户”并不关心质量,而是将修复应用程序的毛茸茸的部分视为可以花费在设计新功能上的时间。我希望我能在工作中做这样的事情,但是每当我提起它时,它都是“不,他们希望看到添加的新功能,而不是修复行之有效的东西”
Wayne Molina

@WayneM是的,直到今天,由于某些人的态度,我惊讶的是它确实有效。这一定是因为管理层用尽了减少“错误计数”的想法,并决定尝试我们的方法。
Jacek Prucia,2011年

0

代码审查。单元测试。真正的质量检查测试。规范收集过程和增量开发-这些应该可以解决大多数问题。

也不要让客户直接对您的开发人员执行ping操作-这通常是解决问题的最无效的方法。雇用一名优秀的计划经理,他将构成您的客户和开发人员之间的接口。他的工作将是了解产品的端到端,当前状态,未来方向等。每当客户想要另一个新功能时,他就应该能够给出当前的项目列表,并向客户展示如果要接受这个新请求将会发生什么。

如果使用量太少或太多,则处理不好。我认为您处于以前的状态。


0

正如Deni所提到的,如果您能够将单元测试添加到项目中,那么这将对您有所帮助。有一个测试将覆盖您要更改/修复的系统的一部分,因此在重构代码时,请以该测试为指导,以确保您没有破坏任何东西。

另外,对代码中最损坏的部分进行分类。尝试将受影响最严重的人员归入风险列表,并独立管理这些风险。通过查询错误最常发生的位置来尝试了解代码库中有多少损坏的代码。然后,您可以按错误计数(或报告的问题,无论对您有用)列出受影响的区域。

修补和清理代码将花费一些时间,但是如果团队中的每个开发人员都可以将代码清理得更干净一点,那么在他们开始编写代码之前,代码库就会随着时间的推移而不断完善。如果您正在寻找一种快速的军用风格,请立即获得解决方案,我怀疑是否有任何实用(或推荐)的方法会有所帮助。

干杯。贾斯


0

写下清晰的功能规格;因此,如果您愿意的话,请定期进行审查。开发人员对他应该开发的东西的想法越少,就越不可能成为开发者的想法。

在开始编写代码之前,请先进行一些前期设计工作。这不需要是完美的,庞大的或包含UML的,但是它应该为需要解决的问题提供一个相当扎实的解决方案。据我所知,计划的软件越少,情况就越糟。在开始设计之前,先讨论一下设计。

当您开始处理代码的某个区域时,该区域显然很差并且确实在阻碍您的进度;停止添加它,从问题中退后一步,研究如何重新设计体系结构,以免障碍不再存在,以便将来更加适应。在解决技术债务之前,您将其保留的时间越长,在没有完全重写的情况下解决它的难度就越大。我会说这是指数级的事情。

设计测试可以测试行为,并且不会与您的体系结构紧密耦合。它不是很时髦,但是我想说,直到您的代码的真正目的明确之后再开始测试。明确地说,在您真正知道要测试的内容之前,不要开始测试。IMO一项经过深思熟虑的测试比没有测试更糟糕。测试越多,内部更改代码就越难。像对待生产代码一样对待测试代码;它需要进行计划并写得很好。

进行定期/每日的代码审查:这更多地是关于健全性检查,以确保开发人员的工作进展顺利。使用这些会议来计划接下来的工作日。有时可能需要5分钟或1个小时;关键是要保持对话开放,并为开发人员提供与其他开发人员讨论其工作并寻求建议的机会。在代码的困难部分进行一些配对会议,或对想法进行原型制作,但让人们有自己的时间工作。

使构建和部署代码变得容易。尽量缩短构建时间。构建越容易,构建的内容就越多,构建得越快,构建的内容就越多。

采用编码标准并严格执行。这应该涵盖从项目应该在文件系统中驻留的位置到私有const框的所有内容。这似乎毫无意义,令人讨厌,但是良好的习惯是开发过程的基石。

从根本上讲,我认为您使用的过程并不那么重要,时尚来来往往。真正重要的是,您对软件开发的方式非常专业,并且在实践中受到纪律处分。


1
-1:写清楚功能规格;徒劳的 -我非常不同意,因为花时间和精力来编写“花哨的,功能性的规范”(很快就会过时)就是您不能花费时间和精力来编写在每个自动构建周期中验证代码的功能单元测试。
Jim G.

1
“将很快变得过时”是整个软件管理中最大的谬误。如果它们过时了,请更新FS,以免更新。如果您没有合适的FS,那么您究竟会知道要编写什么测试,或者您的软件是否实际完成了想要的工作。对我来说,这就是敏捷的所有问题(而且有很多):让我们开始编写代码,测试就是一切。文档是浪费时间,使事情清晰明了是浪费时间...

1
你们都提出了有效的观点。强大的功能要求对于扎实的测试实践必不可少,但是,如果项目已经受到错误管理,那么这将无济于事。
maple_shaft

2
我同意你的观点,但是根据我的经验,不知道正在开发什么是管理不善的根源。

@B泰勒:...根据我的经验,不知道正在开发什么是管理不善的根源。-100%同意。我们只是不同意补救措施。
Jim G.

0

首先,我将设计和自动化烟雾测试,然后将其放入CI环境中。这些应该起作用。当客户告诉您某事应该某某某事起作用时,请写下来,以便您稍后参考。当您在软件中看到某个解决方案时,请提出问题,并在收到答案后立即将其纳入知识库并使其可追溯。

确保肯定案例的基本功能正常。然后开始为错误的数据处理构建增量测试,并在必要时放置缺陷。对优先级进行了长期而深入的讨论,并使测试经理知道了这些优先级,因此他可以相应地分配测试时间。不要试图使所有内容自动化,但是,一旦某些测试用例对自动化变得有意义,请立即不要犹豫。

通常,使用测试来增加对产品的信任,而不是将其用作立即提高质量的工具。保持冷静,但要有主见:)。也许尝试敏捷,但是只有当您绝对肯定地积极参与时,才能聘请一位认证的PM。由不了解敏捷的人介绍敏捷,很可能会扼杀该项目。

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.