软件工程

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

5
将参数作为const传递时是否过早优化?
“过早的优化是万恶之源” 我认为我们都可以同意。我尽力避免这样做。 但是最近我一直想知道通过const Reference而不是Value传递参数的做法。我已经被教导/了解到,非平凡的函数参数(即大多数非原始类型)最好通过const引用传递-我读过的很多书都将其推荐为“最佳实践”。 我仍然不禁感到奇怪:现代的编译器和新的语言功能可以解决奇迹,因此我所学的知识可能已经过时了,而且如果两者之间存在任何性能差异,我实际上也不会费心去剖析。 void fooByValue(SomeDataStruct data); 和 void fooByReference(const SomeDataStruct& data); 我所学的做法是-传递const引用(对于非平凡类型默认为)-过早优化吗?

8
发布版本中应该有断言
assertC ++中的默认行为是在发行版本中不执行任何操作。我认为这样做是出于性能原因,也许是为了防止用户看到讨厌的错误消息。 但是,我认为,那些assert将被触发但被禁用的情况更加麻烦,因为应用程序可能因为某些不变式被破坏而以更糟糕的方式崩溃。 另外,对我而言,性能参数仅在可衡量的问题时才有效。assert我代码中的大多数不会比复杂得多 assert(ptr != nullptr); 这将对大多数代码产生很小的影响。 这使我想到一个问题:断言(意味着概念,而不是特定的实现)是否应该在发布版本中有效?为什么不)? 请注意,此问题不是关于如何在发布版本中启用断言(例如#undef _NDEBUG或使用自定义断言实现)。此外,这不是在第三方/标准库代码中启用断言,而是在我控制的代码中启用断言。

1
所有大写常量的命名历史是什么?
用大写字母命名常量的惯例背后的历史是什么? 我的直觉是从C预处理程序开始的,在C预处理程序中,人们开发了一种做法,以所有大写形式命名预处理程序宏,以便它们可以有效地存在于单独的命名空间中,并避免名称冲突。我的信念是,这种做法后来被误解并混为一谈,也适用于非预处理程序常量(enums,const变量)。 在所有大写字母中命名预处理器宏对我来说确实有用。用这种方式命名通用常量不是那么多(如果它与宏名称产生冲突,则会适得其反)。 我在基地外吗?大写常量的惯例是否早于C?

3
包装器在包装同一对象时是否应该使用==运算符比较相等?
我正在为XML元素编写包装器,使开发人员可以轻松地解析XML中的属性。包装器除了被包装的对象外没有其他状态。 我正在考虑以下实现(此示例已简化),其中包括==操作员的重载。 class XmlWrapper { protected readonly XElement _element; public XmlWrapper(XElement element) { _element = element; } public string NameAttribute { get { //Get the value of the name attribute } set { //Set the value of the name attribute } } public override bool Equals(object other) { var o …
19 c#  .net  operators 

5
使用仅包含静态方法的*** Helper或*** Util类是AntiPattern
我经常遇到Java或任何类型的语言中的helper或util类。因此,我问自己这是否是某种反模式,而此类类的存在只是软件设计和体系结构中缺少一些缺失。 通常,这些类仅使用静态方法进行限制,该方法可以完成很多工作。但大多数情况下,确实是上下文相关的并且是全状态的。 我的问题是,您对此类静态辅助程序/ util类有何看法,因为其优势当然是仅使用类名进行快速调用。 在哪种抽象级别上,您将避免使用此类? 我认为关键字“ static”应该只允许在类(Java)的声明中使用,而不能用于方法。我认为以这种方式使用它,是在Java中结合过程式和OO-范式并避免滥用关键字的一种很好的选择,也是中间的选择。 由于答案而增加的内容: 起初,我认为能够组合不同的范例甚至在机器或vm编译的代码中使用运行时解释的脚本语言是完全合法的。 我的经验是,在项目的开发过程中,此类帮助器和utils或其他名称正在不断增长,并在最初被设计为模块化和灵活的代码库的每个被遗忘的角落使用。而且由于缺乏时间进行重构或重新考虑设计,随着时间的推移,您的情况只会变得更糟。 我认为static应该从Java中删除。尤其是在现在可以使用更复杂的功能语言元素的地方。

6
当您更改函数的Big O执行时间时,该怎么称呼?
已关闭。这个问题是基于观点的。它当前不接受答案。 想改善这个问题吗?更新问题,以便通过编辑此帖子以事实和引用的形式回答。 去年关闭。 假设我有一个可以O(n^2)及时对数据库进行排序的函数。我想对其进行重构,以使其能够O(n log(n))及时运行,并且这样做,我将更改操作的基本运行方式,同时保持返回值和输入相等。 我怎么称呼这种重构活动? “加速优化”似乎不太正确,因为您可以在不改变算法执行速度的情况下使算法运行得更快。 “简化”似乎也不对。 我怎么称呼这项活动? 更新资料 我能找到的最佳答案是减少渐近时间的复杂度。
19 complexity  big-o 

8
有没有比TryGetValue使用C#词典更好的方法?
我发现自己经常在网上查找问题,许多解决方案都包括字典。但是,每当我尝试实现它们时,我的代码都会令人讨厌。例如,每次我想使用一个值时: int x; if (dict.TryGetValue("key", out x)) { DoSomethingWith(x); } 这是4行代码,基本上可以执行以下操作: DoSomethingWith(dict["key"]) 我听说使用out关键字是一种反模式,因为它会使函数改变其参数。 另外,我发现自己经常需要“反向”字典,在其中翻转键和值。 同样,我经常想遍历字典中的各项,发现自己将键或值转换为列表等以更好地做到这一点。 我觉得几乎总是有一种更好,更优雅的字典使用方式,但是我很茫然。

10
在开发的开始或结束时,什么时候更好地优化软件以获得更好的性能?
我是一名初级软件开发人员,我想知道什么时候是优化软件以提高性能(速度)的最佳时机。 假设该软件不是非常庞大且难以管理,是花更多的时间在开始对其进行优化上还是我应该只是开发能够正确执行所有功能的软件,然后继续对其进行优化以获得更好的性能?

4
为什么协程又回来了?[关闭]
已关闭。这个问题是基于观点的。它当前不接受答案。 想改善这个问题吗?更新问题,以便通过编辑此帖子以事实和引用的形式回答。 2年前关闭。 协程的大部分基础工作都发生在60年代/​​ 70年代,然后停下来,取而代之的是其他选择(例如线程) 对以Python和其他语言出现的协程产生新兴趣的实质是什么?

4
python块中的冒号在技术上是必要的吗?
这实际上只是想要了解更多信息的python新手的理论问题。 在python中的块初始语句之后,我一直忘了冒号。这些就是我的意思: for <variable> in <sequence>: if <blah blah>: 我的想法是,我一直忘记的一个原因是它们实际上是隐式的:不管是否冒号,该语句都以该行结尾。 我的问题-为了学习python语法如何工作而问-是冒号是否真的不必要?我是否要更改python语法,以便不再需要冒号,是否会中断?这会使某些陈述模棱两可或不可能吗?
19 python  syntax  theory 

4
哪些UML图仍在广泛使用?[关闭]
已关闭。这个问题是基于观点的。它当前不接受答案。 想改善这个问题吗?更新问题,以便通过编辑此帖子以事实和引用的形式回答。 2年前关闭。 我在大学阶段教授软件工程,对UML从业者有疑问。 大多数软件工程教科书在覆盖UML图方面都进行了认真的工作。但是,另一方面,我从许多毕业生那里听说,UML似乎不再被使用。 哪些UML图仍在专业实践中广泛使用,为什么?是否存在不再使用的图,为什么? 注意:为了避免基于观点的辩论和讨论,请使用事实和客观因素(如果可能,可验证)或对个人经验的中性观察来说明您的答案

1
测量Java 8代码的条件覆盖范围是否有意义?
我想知道自Java 8出现以来,当前使用Java的工具来衡量条件代码覆盖率是否还没有过时。使用Java 8 Optional,Stream我们通常可以避免代码分支/循环,这使得在不测试所有可能的执行路径的情况下轻松获得很高的条件覆盖率。让我们将旧的Java代码与Java 8代码进行比较: 在Java 8之前: public String getName(User user) { if (user != null) { if (user.getName() != null) { return user.getName(); } } return "unknown"; } 以上方法有3条可能的执行路径。为了获得100%的条件覆盖率,我们需要创建3个单元测试。 Java 8: public String getName(User user) { return Optional.ofNullable(user) .map(User::getName) .orElse("unknown"); } 在这种情况下,分支是隐藏的,我们只需要进行一次测试即可获得100%的覆盖率,无论哪种情况我们都将进行测试。我相信,尽管仍然存在相同的三个逻辑分支。我认为这使有条件覆盖范围统计这些天完全不可信。 测量Java 8代码的条件覆盖范围是否有意义?还有其他工具可以发现未经测试的代码吗?

7
将某些值存储为字符串是不好的做法吗?
那是一个非常模糊的标题,但我想不出一种更好的措词。但是,作为一个示例,请考虑游戏中角色的前进方向。先使用字符串然后再执行类似操作,这是一种错误if(character.direction == "left")。在我看来,它为愚蠢的错误留了太多的空间,例如不小心使用Left或l或而不是left。我的怀疑正确吗?如果是这样,实现这种目标的首选方式是什么?

8
C#-为什么不鼓励在字段上使用前缀?
过去,我们使用匈牙利符号。现在将其视为passé,并且在大多数情况下,我不再使用它,但是我仍然发现该m_前缀用于表示成员字段。 对我来说,如果我正在阅读别人的代码,就会看到以下内容: count = 3; 我假设这count是该函数的局部变量,并且我正在做将在该函数的其他地方使用的操作。如果我看到这个: m_count = 3; 我立即意识到我正在更新对象的状态。 Microsoft风格指南说这是做事的错误方法。我应该像在函数中定义的临时变量一样命名我的非公共字段。不m_,甚至没有简单的下划线。 是的,我们可以定义自己的编码样式,但是接下来我必须努力使用各种静态代码分析工具,以使他们相信我们的处事方式还可以。 我很高兴能够更改为Microsoft风格,但是我想知道为什么事情是这样。 为什么现在不能分辨一个变量是函数本地变量还是成员变量,这为什么认为很糟糕? PS这非常类似于c#领域和方法前面关于“ this”关键字的当前最佳实践是什么?,但我问的m_不是this. PPS另请参见Microsoft为什么使参数,局部变量和私有字段具有相同的名称命名约定?

5
“深度合成层次结构”也不难吗?
抱歉,“合成层次结构”不是问题,但我将在问题中解释我的意思。 没有任何OO程序员没有遇到过“保持继承层次结构平坦”或“优先考虑继承而不是继承”等变体。但是,深层次的组合层次结构似乎也存在问题。 假设我们需要一组详细说明实验结果的报告: class Model { // ... interface Array<Result> m_results; } 每个结果都有某些属性。其中包括实验时间以及实验各个阶段的一些元数据: enum Stage { Pre = 1, Post }; class Result { // ... interface Epoch m_epoch; Map<Stage, ExperimentModules> m_modules; } 好,很好。现在,每个实验模块都有一个描述实验结果的字符串,以及对实验样本集的引用的集合: class ExperimentalModules { // ... interface String m_reportText; Array<Sample> m_entities; } 然后每个样本都有...好,您得到了图片。 问题是,如果我要在应用程序域中对对象建模,这似乎是很自然的选择,但是最终,a Result只是一个愚蠢的数据容器!为它创建大量的类似乎并不值得。 假设上面显示的数据结构和类正确地对应用程序域中的关系建模,是否有更好的方法可以对这种“结果”进行建模,而无需求助于深层次的构成层次结构?是否有任何外部环境可以帮助您确定这种设计是否是好的?

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.