软件工程

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

5
如何进行一项测试取决于另一项测试的结果?
假设有一个实用程序类,提供了许多其他类在代码中各处使用的一些常见静态方法。 您将如何为实用程序的使用者设计单元测试,以便在任何一项实用程序测试未通过的情况下使他们的测试失败?您可以这样做还是必须自己检查实用程序类测试是否全部为绿色? 例如,我有一个消息拆分器实用程序,它由消息解析器使用(或更确切地说,它的输出)。我想确保在测试邮件解析器之前,邮件拆分器能够正常工作。 我已经为它们两个编写了测试,但是有没有办法链接它们并使一个测试依赖于其他测试的结果? 我找不到适合的标签,但是我使用的是Visual Studio的单元测试引擎。

3
如何使参数保持低计数并仍保持第三方依存关系独立?
我使用第三方图书馆。他们向我传递了一个POJO,出于我们的意图和目的,可能是这样实现的: public class OurData { private String foo; private String bar; private String baz; private String quux; // A lot more than this // IMPORTANT: NOTE THAT THIS IS A PACKAGE PRIVATE CONSTRUCTOR OurData(/* I don't know what they do */) { // some stuff } public String getFoo() { …

7
是否有一种模式可以更自然地向收藏夹添加项目?[关闭]
已关闭。这个问题是基于观点的。它当前不接受答案。 想改善这个问题吗?更新问题,以便通过编辑此帖子以事实和引用的形式回答。 5年前关闭。 我认为向集合中添加某些内容的最常见方法是使用Add集合提供的某种方法: class Item {} var items = new List<Item>(); items.Add(new Item()); 实际上,这没有什么不寻常的。 我不知道为什么我们不这样做: var item = new Item(); item.AddTo(items); 它似乎比第一种方法更自然。当Item类具有类似Parent以下属性时,将具有andvantange : class Item { public object Parent { get; private set; } } 您可以将二传手设为私人。在这种情况下,您当然不能使用扩展方法。 但是也许我错了,我以前从未见过这种模式,因为它是如此罕见?你知道有没有这种模式? 在C#扩展方法中将对此有用 public static T AddTo(this T item, IList<T> list) { list.Add(item); return …

4
通过这种方式,我编写此代码是可测试的,但是我缺少它吗?
我有一个名为的界面IContext。出于此目的,除了以下内容外,它的作用并不重要: T GetService<T>(); 该方法的作用是查看应用程序的当前DI容器,并尝试解决依赖关系。我认为还算标准。 在我的ASP.NET MVC应用程序中,我的构造函数如下所示。 protected MyControllerBase(IContext ctx) { TheContext = ctx; SomeService = ctx.GetService<ISomeService>(); AnotherService = ctx.GetService<IAnotherService>(); } 因此,我不是在为每个服务的构造函数中添加多个参数(因为这对于扩展应用程序的开发人员来说确实很烦人和耗时),而是使用此方法来获取服务。 现在,感觉不对。但是,我目前在脑海中证明它的方式是这样- 我可以嘲笑它。 我可以。模拟IContext测试控制器并不难。无论如何,我必须: public class MyMockContext : IContext { public T GetService<T>() { if (typeof(T) == typeof(ISomeService)) { // return another mock, or concrete etc etc } // etc …

3
在标准类型和用户定义类型之间进行语法区分的目的是什么?
尽管在这里我将特别提及C ++和Bjarne Stroustrup的命名约定,但原则上,我已经看到人们在这里和那里对其他语言使用一些相似的规则。 因此,基本思想是在阅读代码时应该能够将标准类型与用户定义的类型区分开。例如,Bjarne Stroustrup建议使用 类型(例如Square和Graph)的首字母大写 考虑到 C ++语言和标准库不使用大写字母 可以实现上述目标。 但是,为什么我们需要这样做呢?区分标准类型和用户定义类型的目的是什么? 在这件事上,我找不到Bjarne Stroustrup的任何推理,而且,我自己以截然相反的方式思考。:DI知道,我知道,“我要和谁争论Stroustrup?” 但是,听着,许多C ++语言功能(例如,运算符重载)用于允许用户定义类型的语法支持水平与标准类型相似。然后所有这一切都被另一个命名规则所困扰... PS更不用说一个单词常常不足以命名一个班级,而以大写字母开头的下划线分隔的单词看起来太陌生了。

2
在有效负载中包含资源ID或从URI派生
在设计API时,我们遇到了一个问题,即PUT有效负载是否应包含要更新的资源的ID。 这是我们目前拥有的: PUT /users/123 Payload: {name: "Adrian"} 我们的路由代码从URI中提取ID,然后继续进行更新。 API的第一批用户在质疑为什么我们在有效负载中不允许使用ID: PUT /users/123 Payload: {id: 123, name: "Adrian"} 我们不允许这样做的原因是因为ID在有效负载和URI中重复。 再考虑一下,我们正在将资源耦合到URI。 如果URI没有ID,则需要修改有效负载: PUT /no/id/here Payload: {name: "Adrian"} < What user??? 有什么理由不这样做吗?
13 rest  resources 

2
如何有效地计算图形旋转?
我有一个通过字节矩阵(类似位图的矩阵)表示的图形。示例图显示在上Picture 1。 目的是找到给定图形的最佳旋转角度。当图形旋转最佳角度时,与X和Y轴平行并刻有图形的矩形的面积最小。 刻有图形的矩形在图片上显示为浅灰色。在中Picture 2,您可以看到图形的理想旋转方向为顺时针大约30度。 现在,我知道算法如何找到该角度,但是在我看来这是非常低效的。它是这样的: 循环从0到45度的角度。 对于当前角度,为每个图形点计算新的旋转位置 查找包含图形(最小和最大x,y)的矩形的边界,如果到目前为止最匹配,则对其进行注册 下一个角度 这是一种蛮力方法,对于小人物来说效果很好且相当快。但是,我需要处理包含多达1000万点的图形,并且算法变得缓慢。 什么是解决这个问题的好算法?

2
lambda演算与编程语言之间是什么关系?[关闭]
已关闭。这个问题需要更加集中。它当前不接受答案。 想改善这个问题吗?更新问题,使其仅通过编辑此帖子来关注一个问题。 5年前关闭。 我明年要开始(大学)计算机科学专业的第一年,而我主要用C语言写作(如果有关系的话)。我曾尝试搜索,但发现的大部分内容都是关于lambda演算的知识。为什么lambda演算在编程中比单变量演算有用得多?lambda表达式与功能程序之间是否存在关系?阿隆佐·丘奇(Alonzo Church)在lambda微积分上的工作是否影响了编程语言的发展? 校外的每个人都在忙着讨论它,即使我渴望学习它,并看到它与我的编程和对编程语言的理解直接相关,我也不知道他们会谈论什么。

2
如果事务永远不会跨越多个对象,那么每个对象的乐观并发性是否意味着可串行化?
给定一个提供以下功能的系统: 每个对象的乐观并发控制/版本控制(使用CAS-Check-and-Set) 不需要跨多个对象的事务。 快照隔离 该系统是否可序列化? 从快照隔离 在写偏斜异常中,两个事务(T1和T2)同时读取重叠的数据集(例如值V1和V2),并发进行不相交的更新(例如T1更新V1,T2更新V2),最后并发提交,都没有看到对方执行的更新。如果系统可序列化,那么这种异常将是不可能的,因为T1或T2都必须“首先”发生,而另一个则可见。相反,快照隔离允许写偏斜异常。 举一个具体的例子,假设V1和V2是一个人Phil持有的两个天平。银行将允许V1或V2出现赤字,前提是两者中所持的总和决不为负(即V1 + V2≥0)。目前两个余额均为$ 100。Phil同时发起了两个交易,T1从V1提取200美元,T2从V2提取200美元。 基于此,似乎存在写偏斜的可能性是保证快照隔离不可序列化的系统的唯一原因。 但是,在不允许事务跨越多个对象的系统中(在上面的示例V1和V2中),似乎不可能发生写偏斜。 因此,上述系统是可序列化的。它是否正确?

2
什么是“表示逻辑”,视图中可接受多少?
在我的Web应用程序中,我必须提供用于创建和编辑的表单。创建和编辑的形式存在细微差别,因此我认为在我看来是这样的: <form> // a lot of htnl goes here @if (editing) { // some more fields shown in edit mode } @if(!editing) { // some stuff shown in create mode } 我一直试图不在if视图中放置任何语句,但是这次我看不到任何其他选择,只是在两个地方复制了很大一部分HTML,我不想这样做。这是正确的“表示逻辑”吗,还有其他选择吗?

1
游戏测试策略
我继承了一个基于网络的教育游戏。在过去的一年中,我一直致力于稳定代码和添加新功能。大多数逻辑都在前端,因此后端单元测试虽然很有用,但只覆盖了一小部分代码。 游戏已经到了开始变得复杂的地步。每个游戏有两种不同的模式,并且游戏的行为取决于模式。还有各种影响游戏玩法的标志。 我担任应用程序开发人员已有10多年了,这使我感到困惑。在企业界,算法始终以相同的方式起作用。我将为算法编写一个单元测试,我期望值42,如果我没有得到该值,它将出错。 说到游戏,我迷路了。我该如何测试?我有可用的测试仪。我可以花时间编写单元测试。 测试人员...不可靠。他们不是最能根除问题的人,我也没有给他们最好的方向。在每个发行周期花大量时间测试游戏的每个排列和组合时,我应该如何将它们用作资源? 单元测试似乎很有限。由于大多数逻辑是javascript(并且我继承了意大利面条代码),因此我可以使用诸如Cucumber或selenium之类的前端套件来确保某些功能正常工作。 那是最好的策略吗?游戏公司如何测试游戏? 我已经读过“ 复杂游戏的测试驱动开发 ”(以及网站上的其他问题)的问题,但是它没有解决我所寻找的问题。我要的是策略,而不是具体的测试示例。

2
尽早尝试删除Python GIL会导致性能下降:为什么?
Python创造者Guido Van Rossum的这篇文章提到了从Python中删除GIL的早期尝试: 以前曾尝试过这种方法,但结果令人失望,这就是为什么我自己不愿意为此付出很多努力的原因。在1999年,Greg Stein(与Mark Hammond合作)生产了Python的一个fork(我相信是1.5),它删除了GIL,并用所有可变数据结构上的细粒度锁代替了它。他还提交了补丁,删除了许多我对全局可变数据结构的依赖。但是,在进行基准测试后,结果表明,即使在具有最快锁定原语的平台(当时为Windows)上,单线程执行的速度也降低了近两倍,这意味着在两个CPU上,您可以多做一点工作在没有GIL的情况下比在具有GIL的单个CPU上完成。这还不够,格雷格的补丁消失了。(请参阅格雷格关于演出的文章。) 我很难与实际结果争论,但我真的很奇怪为什么会这样。大概,从CPython中删除GIL如此困难的主要原因是由于引用计数内存管理系统。一个典型的Python程序将调用Py_INCREF和Py_DECREF数千或数百万次,使其成为一个关键的竞争点,如果我们要环绕它锁。 但是,我不明白为什么添加原子基元会降低单个线程程序的速度。假设我们刚刚修改了CPython,以便每个Python对象中的refcount变量是一个原子基元。然后,当我们需要增加引用计数时,我们只是执行原子增加(获取和添加指令)。这将使Python参考计数线程安全,并且在单线程应用程序上不应有任何性能损失,因为不会发生锁争用。 但是,a,许多比我聪明的人都尝试过并且失败了,所以显然我在这里缺少任何东西。我看这个问题的方式有什么问题?
13 python 

6
为什么C数组的长度不能为0?
C11标准说,大小和可变长度的数组“都应具有大于零的值”。不允许长度为0的理由是什么? 特别是对于可变长度的数组,每隔一段时间具有零的大小是很有意义的。当静态数组的大小来自宏或构建配置选项时,它也很有用。 有趣的是,GCC(和clang)提供了允许零长度数组的扩展。Java还允许长度为零的数组。
13 c  array 

6
质疑依赖关系注入框架的论点之一:为什么创建对象图很难?
像Google Guice这样的依赖注入框架为其使用(来源)提供了以下动机: 要构造一个对象,首先要建立它的依赖关系。但是要构建每个依赖项,您需要其依赖项,依此类推。因此,在构建对象时,确实需要构建对象图。 手工构建对象图是劳动密集型(...),并且使测试变得困难。 但是我不赞成这种观点:即使没有依赖注入框架,我也可以编写易于实例化且易于测试的类。例如,Guice动机页面中的示例可以用以下方式重写: class BillingService { private final CreditCardProcessor processor; private final TransactionLog transactionLog; // constructor for tests, taking all collaborators as parameters BillingService(CreditCardProcessor processor, TransactionLog transactionLog) { this.processor = processor; this.transactionLog = transactionLog; } // constructor for production, calling the (productive) constructors of the collaborators public BillingService() …

3
依赖注入框架会带来依赖风险吗?
我一直在重构现有系统以使用依赖项注入,并且该工作进展顺利。 一段时间后,我注意到大量内部库变得依赖于我使用的DI框架。结果,整个项目现在都依赖于此第三方框架。 在使所有依赖项依赖于共享库来解耦所有依赖项时,我感到讽刺。 我的第一个反应是围绕依赖关系框架创建包装器库。因此,如果需要,我可以替换此框架。在估计了所涉及的工作之后,我意识到最终的API将类似于现有框架,因此使替换它变得更加困难。所以我放弃了这个主意。 我担心的是,我正在使用的DI框架已过时或需要替换。 使用DI时是否存在减少项目和DI框架之间耦合的开发模式?

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.