软件工程

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

10
状态机与线程
艾伦·考克斯(Alan Cox)曾说过: “计算机是状态机。线程是为无法对状态机进行编程的人的。” 由于直接询问Alan并不是让我谦虚的选择,所以我想在这里问:一个人如何仅使用一个线程和状态机来实现高级语言(例如Java)的多线程功能?例如,如果要执行2个活动(进行计算和执行I / O)并且一个活动可以阻止该怎么办? 使用“仅状态机”方式是否可以替代高级语言中的多线程?

4
每个单元测试是否应该能够独立于其他测试运行?
假设您有针对类的两种方法的测试。第一种方法从另一层收集数据,并将其放入独立于运行时的某种存储中(例如SQL表),因此,此测试处理的所有数据都被硬编码到测试中。第二种方法负责从第一种方法保留的位置获取数据并以某种方式进行转换(计算,将某些零件移动到其他位置等)。 现在,第二种方法可以像第一种方法那样对输入进行硬编码,或者可以假设这两个测试将按顺序运行,并且可以从第一个测试中断的位置开始,获取第一个测试真正存储的数据。 如果您选择了第二个选项,那么您确实会很好地认为这两种方法可以很好地协同工作,但是,如果第一个测试失败了,则所有测试都将失败,从而失去了帮助更快地隔离错误的测试优势。 如果选择第一种方法,则每种方法都将被隔离和独立测试,但是您永远不会真正知道它们是否可以真正正常地协同工作。 这里哪个更好?是否存在某种替代方法,例如对每个隔离的方法都使用硬编码进行一次测试,然后将两个方法合而为一的更大的测试?

9
我的同事是一个好人,但他的表现不及标准。我要告诉老板吗?[关闭]
已关闭。这个问题是基于观点的。它当前不接受答案。 想改善这个问题吗?更新问题,以便通过编辑此帖子以事实和引用的形式回答。 4年前关闭。 大约三个月前,我被安排在一个项目上,该项目直到那时才由一个新雇用的开发人员进行开发,因为它落后了。公平地讲,该项目是医疗设备的接口,具有很多细微之处,并且相对复杂,因此从管理的角度来看,让一个没有公司经验的人加入该项目可能是一个错误的决定。 无论如何,一旦我开始研究它,我就意识到……好吧,它根本没有用。UI看起来不错,但是实际上并没有执行任何操作,它所做的只是做错了。再次,公平地讲,这很大程度上是由于该开发人员没有适当准备为我们的设备编写接口的事实。但是,我也很快意识到所使用的代码很脆弱,并且很难维护。 现在,我不声称自己是世界上最好的程序员。我与很多非常聪明的人一起工作,他们比我更好。开发人员但是我非常努力地编写尽可能简单且健壮的代码。我测试我的签到。如果我发现我的代码变得凌乱并且难以在早期使用,则可以对其进行更改。我与同事进行了几次交谈,以帮助他编写更好的代码。这有点棘手,因为a)他在该领域有20多年的经验,而我只有5年,b)他被聘为所谓的“ UX专家”,而其他人则将他视为经验丰富的人。 就是说,我只是看不到。他是一个非常好人,并且很理性,但是他一次又一次地检查脆弱的代码,仅在最乐观的情况下才能工作,并且十分之九的错误导致我修复了他的工作中的错误。他的代码似乎只是业余的,显然他没有他被录用时所拥有的经验水平。到现在,我花费大量的时间重构他的代码并修复他的错误使我付出了代价。我的看法有两种选择: 不执行任何操作,破坏我的屁股,以确保该产品按时推出且坚固耐用,并等待他将来失败(在初始发行后,我将不再与他合作进行此项目)。 告诉我老板他的表现。我的老板是个有理智的人,但是我只是觉得尴尬。我不喜欢抨击我的同事(因为缺乏更好的称呼),我也不知道他会怎么接受。 就是这样。我试图通过解释为什么他的实现无法正常工作或如何使他的代码更易于维护来与同事合作,以解决这个问题,但他仍然犯同样的错误。我非常想知道其他人如何处理类似的情况,尤其是目前在管理人员。预先感谢您可以提供给我的任何建议。

6
一旦整个团队都习惯了,TDD的真正开销是多少?
TDD可节省多少时间并计算成本。 我认为在项目生命周期中成本和报酬变化的百分比是多少。 我以为初始阶段的成本更高,但回报却很少。进一步(在重构期间),您将从测试中受益。 我听说您有30-50%的时间在编写单元测试。但是,这并未考虑编写这些测试所节省的时间。 大家对此有何经验? 韦斯 编辑节省了多少时间以及时间成本?在错误修复和重构中?
24 productivity  tdd 

2
集成测试是否使用模拟?
我目前在软件测试课程中,对于我们的学期项目,我们必须对其执行多种类型的测试,例如单元测试和集成测试。教授说,对于集成测试,在我们的集成测试中使用了模拟和模拟库(例如EasyMock和Mockito)。不过我有点困惑。集成测试是在类,模块,服务等外部进行测试。如果要测试多个类和服务,为什么在集成测试中应适当使用模拟和存根?

3
授权在分层体系结构中适合什么地方?
通常,我将授权决策放置在服务器端控制器中。这些最近是RESTful端点,但我认为MVC类型架构也是如此。为了争论起见,假设它是基于角色的授权。将对受保护的方法进行注释,或者进行检查并在必要时返回403s。 现在,考虑到授权实际上是一条业务规则-例如,“只有管理员可以列出X”,我认为应该将它们推到下一层。当控制器要求业务层执行操作时,服务或业务层会通知控制器未经授权。 这是合理的方法吗?这有缺点吗? 我不愿意拥有一个AuthorizationService,该服务本质上包含一堆静态过程编码规则来执行此操作,但是将所有访问逻辑都放在一个地方也许很有意义。是否应该将跨领域关注点分开? 因此,我想问是否有人做到这一点,以及他们如何以一种干净的方式实现它,或者是否有我可以阅读的好资源。我正在使用Java fwiw,但这是一个与语言无关的问题。 我已经在这里检查了相关的问题,它们在地面和答案上都很薄。例如:域模型中的验证和授权,并将其通过服务层传送到MVC 我正在阅读Spring安全文档,这些文档将其作为一个跨领域的关注点,因此提出了很好的论据,但是我担心这只是“春天的方式”,并且希望有更广阔的视野。它还将您的应用程序绑定到特定框架。

2
为什么构建器应该是内部类而不是其自己的类文件中?
许多Builder Pattern示例都将Builder其构建为对象的内部类。 这有一定道理,因为它表明了Builder构建的内容。但是,使用静态类型的语言,我们知道Builder构建的内容。 另一方面,如果Builder是内部类,则应了解Builder构建的类,而无需查看内部Builder。 而且,将构建器作为内部类可以减少导入的次数,因为外部类可以引用该构建器(如果您对此很在意)。 然后是一些实际的示例,其中Builder放在同一包中,而不是内部类(如)StringBuilder。您知道Builder 应该建立一个,String因为它名为so。 话虽这么说,我能想到的制作Builder内部类的唯一好理由是,您Builder无需知道类的名称或依赖命名约定就可以知道类的含义。例如,如果我StringBuilder是一个内部类,String我可能会知道它比我(推测性)早存在。 是否有其他原因可以使Builder内部类成为阶级,或者只是归结为偏好和仪式?

6
从SQL迁移到NoSQL会以什么大小的数据受益?
作为关系数据库程序员(大部分时间),我阅读了有关关系数据库如何不扩展以及MongoDB等NoSQL解决方案如何扩展的文章。由于到目前为止我开发的大多数数据库都是中小型的,所以我从来没有遇到过一些索引,查询优化或模式重新设计尚未解决的问题。 我希望看到MySQL会遇到什么样的大小。多少行? (我知道这将取决于应用程序和存储的数据类型。让我知道的一个东西基本上是遗传学数据库,因此将有一个主表,带有3或4个查找表。主表将在其中包含其他内容,例如染色体参考和位置坐标。很可能会查询到染色体上两个药水之间的许多条目,以查看其中存储了什么。

8
为什么通常认为使用字符串键是一个坏主意?
这一直困扰着我一段时间。大多数时候,在将数据存储在诸如哈希表之类的结构中时,程序员,书籍和文章都坚持认为用String值对所述结构中的元素进行索引是不正确的做法。然而,到目前为止,我还没有找到一个单一的资料来源来解释为什么这被认为是不好的作法。是否取决于编程语言?在底层框架上?在执行上? 举两个简单的例子,如果有帮助的话: 类似于SQL的表,其中的行由String主键索引。 .NET字典,其中的键是字符串。

5
封装ORM逻辑的存储库模式的替代方案?
我只需要切换一个ORM,这是一个相对艰巨的任务,因为查询逻辑到处都有泄漏。如果我不得不开发一个新的应用程序,我个人的喜好是封装所有查询逻辑(使用ORM)以对它进行将来的更改。存储库模式很难编码和维护,因此我想知道是否还有其他模式可以解决问题? 我可以预见到有关在实际需要时不增加额外复杂性,敏捷性等方面的帖子,但是我只对以更简单的方式解决类似问题的现有模式感兴趣。 我的第一个想法是拥有一个通用类型存储库,通过扩展方法,我可以根据需要向特定类型存储库类添加方法,但是对静态方法进行单元测试非常痛苦。IE浏览器: public static class PersonExtensions { public static IEnumerable<Person> GetRetiredPeople(this IRepository<Person> personRep) { // logic } }

6
如果只使用一次,是否应该定义一个字符串常量?
我们正在为Jaxen(Java的XPath库)实现一个适配器,该适配器允许我们使用XPath来访问应用程序的数据模型。 这是通过实现将字符串(从Jaxen传递给我们的)映射到数据模型的元素的类来完成的。我们估计我们将需要大约100个类,总共超过1000个字符串比较。 我认为,执行此操作的最佳方法是将字符串直接写入代码的简单if / else语句-而不是将每个字符串都定义为常量。例如: public Object getNode(String name) { if ("name".equals(name)) { return contact.getFullName(); } else if ("title".equals(name)) { return contact.getTitle(); } else if ("first_name".equals(name)) { return contact.getFirstName(); } else if ("last_name".equals(name)) { return contact.getLastName(); ... 但是,总是有人告诉我,我们不应该将字符串值直接嵌入代码中,而应该创建字符串常量。看起来像这样: private static final String NAME = "name"; private static final String TITLE …

5
REST API如何适合基于命令/操作的域?
在本文中,作者声称 有时,需要公开API中固有的非RESTful操作。 然后 如果一个API有太多的动作,则表明它是使用RPC观点设计的,而不是使用RESTful原理设计的,或者所讨论的API自然更适合RPC类型模型。 这也反映了我在其他地方阅读和听到的内容。 但是,我觉得这很令人困惑,我希望对此事有更好的了解。 示例I:通过REST接口关闭VM 我认为,有两种根本不同的方法来对虚拟机关闭建模。每种方式可能会有一些变化,但现在让我们集中讨论最基本的差异。 1.修补资源的状态属性 PATCH /api/virtualmachines/42 Content-Type:application/json { "state": "shutting down" } (或者,PUT在子资源上/api/virtualmachines/42/state。) VM将在后台关闭,并且在稍后的某个时间点(取决于关闭的成功与否)将成功,否则状态可能不会通过“关闭电源”在内部进行更新。 2.在资源的actions属性上进行PUT或POST PUT /api/virtualmachines/42/actions Content-Type:application/json { "type": "shutdown" } 结果与第一个示例完全相同。该状态将立即更新为“关闭”,并可能最终更新为“关闭电源”。 两种设计都是RESTful的吗? 哪个设计更好? 示例II:CQRS 如果我们有一个CQRS域,其中包含许多这样的“操作”(又称命令),它们可能潜在地导致多个聚合的更新,或者无法映射到具体资源和子资源上的CRUD操作? 我们是否应该在可能的情况下尝试建模尽可能多的命令,具体取决于在具体资源上创建或更新的具体资源(遵循示例I的第一种方法),其余部分使用“动作端点”? 还是应该将所有命令映射到动作端点(如示例I的第二种方法)? 我们应该在哪里划界线?设计何时变得不那么RESTful? CQRS模型是否更适合RPC之类的API? 据我了解,根据上面引用的文字。 从我的许多问题中可以看出,我对该主题有些困惑。您能帮我更好地了解它吗?

6
初学者:为什么输出命令中不包含操作?
我正在阅读一本编程入门书,其中列出了一个伪代码中的简单示例: Start input myNumber set myAnswer = myNumber * 2 output myAnswer Stop 我们为什么不能省略创建另一个名为的变量,myAnswer而只是将操作放入输出命令中,如下所示: Start input myNumber output myNumber * 2 Stop 为什么前者正确而后者不正确?

8
是否存在用于“真”,“假”和切换布尔值的术语?[关闭]
已关闭。这个问题是基于观点的。它当前不接受答案。 想改善这个问题吗?更新问题,以便通过编辑此帖子以事实和引用的形式回答。 去年关闭。 可以说我试图在一次技术会议上描述我的代码。 首先,我将布尔值设置foobar为true 和 其次,我将布尔值设置foobar为false 似乎有点罗word。如果foobar被拨动,我可能会说, 第三,我切换 foobar 通过这里的含义,您知道它是布尔值。所以我不应该能够: 第四,我对 foob​​ar进行了真实化 和 第五,我伪造 foob​​ar 通过暗示,哪个还会告诉我的听众我们正在处理布尔变量?有合适的术语吗?谢谢。


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.