软件工程

针对在系统开发生命周期中工作的专业人士,学者和学生的问答

9
无需客户参与就能实现敏捷吗?
我无法写有关敏捷的书。我曾在几家称为敏捷流程的商店工作过。敏捷开发的要点之一是定期的客户参与。经过冲刺,可以将作品演示给客户以获取他们的反馈。冲洗并重复。 我遇到的问题是,许多客户不想参与其中。他们将更喜欢瀑布方法。预先收集需求,然后在完成后再回来。以我的经验,瀑布不起作用。客户直到看到他们才知道他们想要什么。瀑布式的困境由希望提前满足所有要求的大量开发人员进一步传播。这样,他们便知道要构建的内容,可以相应地进行架构设计,而客户应对此负责,因为他们“拒绝”了上述要求。 我不正确吗?无需客户参与就能敏捷工作吗?如果是这样,您如何以及如何克服我所讨论的问题?
23 agile  waterfall 


1
拆分一个大项目以创建一个多模块Maven项目
我正在开发一个Spring-MVC应用程序,其中我们使用Maven进行依赖项管理。由于项目规模很大,我们正在考虑将项目分为几个部分。我有一些疑问,希望能在这里得到答案。 当前,我们正在ROOT.war服务器上的Apache tomcat上部署单个WAR文件。由于项目规模很大,因此Web应用程序中包括通知和电子邮件,第三方服务,PUSH(Cometd),REST API等组件。目前,它们都是相互依存的,相互依赖。例如,Notification对象也取决于Person对象,因为通知是为用户量身定制的。 拆分大项目的主要目的是能够在单个模块上工作,进行错误修复,添加功能,进行测试等。如果满意,则只能在服务器上替换此模块,而不是整个应用程序。这可能吗? 如前所述,对象之间存在依赖关系和映射。如何在不同的子模块之间进行管理,或者只是将import语句更改为包括其他项目? 如我所说,其目的是在单个模块上工作并能够部署它们(最好是热的)。目前,我们只有一个WAR文件,如ROOT.war。拆分会创建多个war文件,然后将其称为URL domain-name.com/module_name/some_mapping吗? 我目前正在检查文档,但这是我们要使用Maven提供的多模块要实现的主要目标,并且想知道这是否可行。如果需要更多信息,请告诉我。 目前,我正在使用Spring的父POM,如下所示: <parent> <groupId>io.spring.platform</groupId> <artifactId>platform-bom</artifactId> <version>1.1.3.RELEASE</version> <relativePath /> </parent>

4
键值对使用哪种JSON结构?
对于键值对,哪种JSON格式是更好的选择,为什么? [{"key1": "value1"}, {"key2": "value2"}] 要么: [{"Name": "key1", "Value": "value1"}, {"Name": "key2", "Value": "value2"}] 要么: {"key1": "value1", "key2": "value2"} 第一个变体看起来更紧凑,更“有意义”。第二个变体看起来结构更均匀,可能有助于处理它。第三个变体似乎更具语义。 键值对将用于将任意数据附加到其他项目。数据必须序列化为JSON才能在系统中四舍五入。
23 json 

5
调试内存损坏
首先,我确实意识到这不是一个具有绝对答案的完美的问与答风格的问题,但是我想不出任何措辞来使它更好地工作。我认为没有绝对的解决方案,这就是为什么我将其发布在此处而不是Stack Overflow的原因之一。 在过去的一个月中,我一直在重写相当旧的服务器代码(mmorpg),以使其更加现代,并且易于扩展/修改。我从网络部分开始,并实现了一个第三方库(libevent)来为我处理事务。通过所有的重构和代码更改,我在某个地方引入了内存损坏,而我一直在努力寻找发生错误的地方。 我似乎无法在我的开发/测试环境中可靠地重现它,即使实现原始机器人来模拟某些负载时,我也不会再崩溃(我修复了会导致某些问题的libevent问题) 到目前为止,我已经尝试过: 摆脱困境-直到事情崩溃(可能需要1天以上的生产时间或仅仅一个小时)崩溃之前,我才真正感到困惑,这之前肯定没有无效的写入,肯定在某个时候它将访问无效的内存并且不会覆盖内容机会?(是否可以“扩展”地址范围?) 代码分析工具,即coverage和cppcheck。尽管他们确实指出了代码中的一些.nastiness和边缘情况,但没有什么严重的。 记录该过程,直到它与gdb崩溃(通过undodb),然后以反向方式工作。/ sounds /这样的声音应该是可行的,但是我要么通过使用自动完成功能最终导致gdb崩溃,要么由于一些可能的分支(一个损坏导致另一个损坏,因此导致内部迷失)在内部libevent结构中丢失上)。我想如果能看到指针最初属于/分配指针的地方,那将消除大多数分支问题,那就太好了。但是我无法使用undodb运行valgrind,而且我正常的gdb记录的速度实在太慢了(如果甚至可以与valgrind结合使用)。 代码审查!我自己(彻底)并让一些朋友来检查我的代码,尽管我怀疑它是否足够彻底。我当时在考虑也许要雇用一名开发人员与我一起进行一些代码审查/调试,但是我付不起太多钱,而且我也不知道该去哪里寻找愿意为小工作而工作的人-如果他没有找到问题或根本没有资格,那就不要钱。 我还应该指出:我通常会得到一致的回溯。在某些地方发生崩溃,主要与套接字类以某种方式损坏有关。它是指向不是套接字的东西的无效指针,还是套接字类本身被乱码覆盖(部分?)。尽管我怀疑它在那里崩溃最多,因为那是最常用的部分之一,因此它是第一个被使用的损坏的内存。 总而言之,这个问题使我忙了将近2个月(无论是开还是关,都是一个业余项目),这确实让我感到沮丧,以至于我变得脾气暴躁,并想放弃。我只是想不出我应该怎么做才能发现问题。 我错过了任何有用的技术吗?你怎么处理那件事呢?(这可能不那么普遍,因为没有太多相关信息。或者我真的是盲人?) 编辑: 一些重要的规格: 通过gcc 4.7使用c ++(11)(版本由debian wheezy提供) 代码库大约有15万行 编辑以回复david.pfx帖子:(抱歉响应缓慢) 您是否在仔细记录崩溃情况以寻找模式? 是的,我仍然遗漏了最近发生的崩溃事件 几个地方真的很相似吗?用什么方式? 好吧,在最新版本中(每当我添加/删除代码或更改相关结构时,它们似乎都会改变),它总是会陷入项目计时器方法中。基本上,一个项目有一个特定的时间,在该时间之后,它会过期,并将更新的信息发送给客户端。无效的套接字指针将在Player类中(据我所知仍然有效),大部分与此有关。在正常关闭后,我还将在清理阶段遇到大量崩溃,该崩溃将破坏所有未明确破坏的静态类(__run_exit_handlers在回溯中)。大多数情况下只涉及std::map一个类,但猜测这只是第一件事。 损坏的数据是什么样的?零?Ascii?模式? 我还没有找到任何模式,对我来说似乎有点随机。很难说,因为我不知道腐败从哪里开始。 它与堆有关吗? 这完全与堆有关(我启用了gcc的堆栈保护,但没有捕获任何东西)。 腐败发生在a之后free()吗? 您将不得不对此进行详细说明。您是说要让已经释放的对象指向周围吗?一旦对象被销毁,我会将每个引用都设置为null,所以除非我在某处错过了东西,否则不行。那应该在valgrind中显示出来,但是没有。 网络流量是否有与众不同的东西(缓冲区大小,恢复周期)? 网络流量由原始数据组成。因此,对于更复杂的事物,使用char数组,(u)intX_t或packed(以除去填充)结构,每个数据包都有一个标头,该标头由id和数据包大小本身组成,并针对预期大小进行了验证。它们大约为10-60字节,最大的(内部“启动”数据包,在启动时触发一次)大小为几Mb。 大量的生产断言。在损坏蔓延之前及早地发生崩溃。 我曾经有一次与std::map腐败相关的崩溃,每个实体都有其“视图”的地图,每个实体都可以看到它,反之亦然。我在前面和后面添加了200byte的缓冲区,将其填充为0x33,并在每次访问之前对其进行了检查。腐败刚刚消失了,我必须搬走一些东西使它腐败了。 战略性日志记录,因此您可以准确地知道之前发生了什么。当您更接近答案时,将其添加到日志记录中。 它的工作..扩展。 无奈之下,您可以保存状态并自动重启吗?我可以想到一些实现此目的的生产软件。 我有点做。该软件由一个主要的“高速缓存”进程和一些其他工作进程组成,它们均访问高速缓存以获取并保存内容。因此,每次崩溃我都不会失去太多进展,它仍然会断开所有用户的连接,依此类推,这绝对不是解决方案。 并发:线程,竞争条件等 有一个mysql线程可以执行“异步”查询,尽管这一切都未曾动过,并且仅通过具有所有锁定功能的函数才与数据库类共享信息。 中断 有一个中断计时器可以阻止它锁定,如果它在30秒内没有完成一个周期,它只会中止运行,但是该代码应该是安全的: if (!tics) { abort(); } else …
23 c++  debugging  memory 


6
随机数生成器如何工作?
此问题是从Stack Overflow 迁移而来的,因为可以在Software Engineering Stack Exchange上回答。 迁移 8年前。 我只是在考虑php rand()函数,并思考如何重新制作它,于是我完全呆呆了。 随机数生成器如何工作?
23 random  numbers 

3
质量检查团队应该在哪里进行Gitflow分支模型的测试
我们是一个庞大的团队(10-12个开发人员和4个质量保证团队),他们使用同一个git存储库处理多个项目。它是一个基于Spring Boot的后端Web服务。我们正在寻找一个好的git分支和部署策略。我们还有一个质量保证团队,可以确保我们的功能能够按预期运行(一定程度上没有错误)。 看了几篇文章后,我感到Gitflow模型对我们来说很好用。我的问题来了。 我们的质量检查团队应该在哪里测试我们的功能? 如果他们在功能分支上进行测试,他们将在这里提出错误,开发人员将对其进行修复,一旦通过质量检查,我们将合并以进行开发。然后质量检查人员将再次在开发分支中进行整数测试。 我们是否应该合并所有功能(在经过单元测试和开发人员的基本测试之后)以开发分支,然后从那里进行质量检查。修复和测试也将在开发中进行。 我很想知道哪种方法对其他人有效。
23 testing  git  branching  qa  gitflow 


5
Bob Martin的“ Clean Architecture”是所有架构的经验法则还是只是其中之一?
我非常喜欢Bob Martin叔叔的视频“清洁建筑的原理”中的概念。但是我觉得这种模式就像是抽象工厂和生成器模式的组合核心。 这是编写好的程序的一种方法,但不是唯一的方法。 Rails和reactjs是想到的两个框架,它们不会促进这种干净的体系结构。Rails希望您的业务逻辑出现在模型中(FatModels和SkinnyControllers),并在组件内部做出反应。两种方法都将业务逻辑和框架代码紧密结合在一起。 我没有发现这3种方式中的任何错误。这是一个选择任何人的判断电话。 但是在视频中,我觉得他建议干净的架构应该在业务逻辑和框架之间有明确的界限。框架(网页,Android等)应该是插件,插件中的业务逻辑。他甚至在视频中巧妙地嘲弄了轨道。 那么,鲍勃·马丁(Bob Martin)的“清洁架构”是否是所有架构的经验法则,还是只是其中一种选择?

19
使用盗版/破解软件进行开发[关闭]
按照目前的情况,这个问题不适合我们的问答形式。我们希望答案会得到事实,参考或专业知识的支持,但是这个问题可能会引起辩论,争论,民意调查或扩展讨论。如果您认为此问题可以解决并且可以重新提出,请访问帮助中心以获取指导。 8年前关闭。 已锁定。该问题及其答案被锁定,因为该问题是题外话,但具有历史意义。它目前不接受新的答案或互动。 免责声明:我绝不纵容使用盗版软件。 您是否曾经目睹过将盗版软件用于开发目的?可能是一家公司没有足够的钱来购买一款软件,并且没有免费的替代品吗?可能是一家公司想在购买前试用一下,而该产品没有试用许可证。无论何种情况,您是否曾在一家接受使用盗版/破解软件的公司工作过?这样做有什么后果吗?
22 security  ethics 

1
处理PR来解决公共回购中的安全漏洞的最佳实践是什么?
具有公共存储库的开源项目应如何最好地处理安全报告但尚未公开披露的安全漏洞的拉取请求(PR)? 我参与了一个有数百位贡献者的开源项目。作为定期计划的每月发布的一部分,我们每年发布几次安全公告和漏洞。在发布修补程序版本之前,我们不会发布有关漏洞的信息。我们能够在项目管理系统(JIRA)中安全地管理安全问题。但是,在将安全漏洞提交给GitHub时,我们没有一个很好的流程来掩盖可修复安全漏洞的PR。我们担心人们会在发布这些修补程序之前找到这些修补程序,并创建零日漏洞利用。 我们已经考虑过使用私有存储库来派生主存储库,但是我们当前的大部分审查和质量检查工作流都在PR上进行。如果我们将工作流仅移交给安全团队的私人仓库,则可以将修补程序公开时的时间减少到生成压缩包并将其发布到sourceforge所需的时间,这将是一个很大的改进。我们还可能需要避免将PR合并到我们的公开Beta中。 在朝这个方向发展之前,我想知道在具有开放存储库的开源项目中处理预发行安全性漏洞修复补丁的最佳实践是什么?如果可以通过使用不同于GitHub的平台来更好地解决问题,那么我应该提到我们正在评估迁移到GitLab的过程。

6
持续集成科学软件
我不是软件工程师。我是地球科学领域的博士生。 大约两年前,我开始编写科学软件。我从未使用过持续集成(CI),主要是因为起初我不知道它的存在,而且我是唯一使用此软件的人。 现在,由于该软件的基础正在运行,因此其他人开始对它产生兴趣并希望为该软件做出贡献。计划是其他大学的其他人正在实施核心软件的添加。(我担心他们会引入错误)。此外,该软件变得非常复杂,并且变得越来越难以测试,我也计划继续进行开发。 由于这两个原因,我现在越来越多地考虑使用CI。因为我从未接受过软件工程师的培训,而且周围的人都没有听说过CI(我们是科学家,所以没有程序员),所以我很难开始我的项目。 我有几个问题想向我寻求建议: 首先简要说明该软件的工作方式: 该软件由一个包含所有必需设置的.xml文件控制。您只需通过将路径传递到.xml文件作为输入参数来启动软件,它就会运行并创建带有结果的几个文件。一次运行可能需要30秒钟。 这是一个科学软件。几乎所有的函数都有多个输入参数,它们的类型主要是非常复杂的类。我有多个具有大型目录的.txt文件,用于创建这些类的实例。 现在让我们来问我的问题: 单元测试,集成测试,端到端测试?:我的软件现在大约有30.000行代码,具有数百个功能和约80个类。开始为数百种已经实现的功能编写单元测试对我来说有点奇怪。因此,我考虑过简单地创建一些测试用例。准备10-20个不同的.xml文件,然后运行该软件。我猜这就是所谓的端到端测试?我经常读到您不应该这样做,但是如果您已经拥有可以运行的软件,那么也许可以开始吗?还是尝试将CI添加到已经运行的软件中只是愚蠢的想法。 如果功能参数难以创建,如何编写单元测试? 假设我有一个函数double fun(vector<Class_A> a, vector<Class_B>),通常,我需要首先读取多个文本文件来创建类型为Class_A和的对象Class_B。我考虑过要创建一些虚拟功能,例如Class_A create_dummy_object()不读取文本文件。我还考虑过实现某种序列化。(我不打算测试类对象的创建,因为它们仅依赖于多个文本文件) 如果结果变化很大,如何编写测试?我的软件利用了大型蒙特卡洛模拟并可以迭代地工作。通常,您需要进行约1000次迭代,并且每次迭代都基于Monte Carlo模拟创建约500-20.000个对象实例。如果一次迭代的一个结果只有一点点不同,则整个即将到来的迭代将完全不同。您如何处理这种情况?我认为这对端到端测试来说很重要,因为最终结果变化很大? 对于CI的其他建议,我们深表感谢。

11
在数据库中为某些表创建辅助主键
我想在我的某些表中添加“ second_primary_key”,这将是uuid或一些随机的长键。我需要它,因为对于某些表,我不想向我的Web应用程序公开整数。也就是说,在页面“ / invoices”上,我有一个发票列表和一个指向“ / invoices /:id”的链接,其中:id是整数。我不想让用户知道我的系统中有多少张发票,因此我想使用其“ second_primary_key”代替“ / invoices / 123”,从而使URL为“ / invoices / N_8Zk241vNa” 我要隐藏真实ID的其他表也是如此。 我想知道,这是常见的做法吗?实现此目的的最佳方法是什么? 到底该技术叫什么,以便我对此进行搜索?

8
敏捷-我们做错了什么?
我是敏捷团队的开发人员,我们尝试使用Scrum。 因此,我将在此处提出一个假设问题来说明这种情况。 我们有一个非常老的应用程序,使用了一些凌乱且糟糕的可维护性JQuery代码。我们也有部分使用React的应用程序,这些部分更易于更新/维护。除此之外,公司的目标是在React上开发一个客户端单页应用程序,因此使用JQuery可以使您走得更远。 在进行规划时,我们总是会在开发时间方面寻求简单的解决方案,因此例如,如果我们要创建新对话框或其他内容,我们会使用旧的JQuery,因为它的速度更快,并且我们说我们要回去后来整理并转化为React,但这很少发生。 我们从用户故事中获得了我们必须做的事情的要求(IMO做得很好,虽然很苗条,但是它们可以解释我们在做什么,以及为什么要这样做)。 有时,对新功能的要求非常渺茫,例如,如果某个要求说“创建一个加载大量内容的对话框”却没有说要实现加载功能,那么在大多数情况下,我们不会实现它,尽管我们都知道这对客户会更好,因为这样做可能会损害我们的sprint目标(即使我个人认为不会)。 结果是我们的代码库混乱不堪,可维护性很差,并且新功能有时非常小,需要花很多时间(在良好的代码库中一天就可以实现),这主要是因为此开发策略,快走,做到极简。 在这种情况下,我们做错了什么?我们是否应该以更完整的方式解决解决方案,以便我们不浪费编写糟糕的代码并重写上周刚刚编写的代码?还是应该确保仅重写所有代码,就继续这样做?什么是解决此问题的敏捷方法?
22 agile  scrum 

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.