软件工程

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

3
为什么Option /也许被认为是一个好主意,而检查异常却不是?
一些编程语言(例如Scala)具有Option类型(也称为Maybe)的概念,可以包含值也可以不包含值。 根据我对它们的了解,与相比null,它们被广泛认为是处理此问题的一种更好的方法,因为它们明确地迫使程序员考虑可能没有值的情况,而不仅仅是在运行时崩溃。 另一方面,Java中的Checked Exception似乎被认为是一个坏主意,Java似乎是实现它们的唯一被广泛使用的语言。但是它们背后的想法似乎与该Option类型有些相似,以明确地迫使程序员处理可能引发异常的事实。 Option类型所没有的Checked Exception还有其他问题吗?还是这些想法与我想的不一样,并且有充分的理由强制对Option而不是对Exception进行显式处理?
23 exceptions 

7
避免过于复杂的方法-循环复杂性
不确定如何使用这种方法来降低环复杂性。声纳报告为13,而预期为10。我敢肯定,保持这种方法不会造成任何危害,不过,这只是挑战我如何遵循Sonar的法则。任何想法将不胜感激。 public static long parseTimeValue(String sValue) { if (sValue == null) { return 0; } try { long millis; if (sValue.endsWith("S")) { millis = new ExtractSecond(sValue).invoke(); } else if (sValue.endsWith("ms")) { millis = new ExtractMillisecond(sValue).invoke(); } else if (sValue.endsWith("s")) { millis = new ExtractInSecond(sValue).invoke(); } else if (sValue.endsWith("m")) { millis …

5
端到端测试与单元测试之间,应该将测试解耦吗?
在我们公司,我们通常会确保为我们的网站/ Web应用程序编写一个端到端测试。这意味着我们访问一个URL,填写一个表单,将该表单提交到另一个URL并检查页面结果。我们这样做是为了测试表单验证,测试HTML模板是否具有正确的上下文变量等。 我们还使用它间接测试基础逻辑。 一位同事告诉我,这样做的原因是,只要端到端测试通过,我们就可以随时淘汰和更改基础实现。 我想知道这种解耦是否有意义,或者这仅仅是避免编写针对较小代码单元的测试的方法?

12
面向对象设计
假设您具有以下条件: +--------+ +------+ | Animal | | Food | +-+------+ +----+-+ ^ ^ | | | | +------+ +-------+ | Deer | | Grass | +------+ +-------+ Deer从继承Animal和Grass继承Food。 到目前为止,一切都很好。Animal物体可以吃Food物体。 现在,让它混合一点。让我们添加一个Lion继承自的Animal。 +--------+ +------+ | Animal | | Food | +-+-----++ +----+-+ ^ ^ ^ | | | | | | +------+ …

3
为抽象语法树实现访问者模式
我正在创建自己的编程语言,出于学习目的。我已经为我的语言的一部分编写了词法分析器和递归下降解析器(我目前支持数学表达式,例如+ - * /和括号)。解析器将我交给一个抽象语法树,在该语法树上我调用该Evaluate方法以获取表达式的结果。一切正常。这大约是我目前的情况(C#代码示例,尽管这在很大程度上与语言无关): public abstract class Node { public abstract Double Evaluate(); } public class OperationNode : Node { public Node Left { get; set; } private String Operator { get; set; } private Node Right { get; set; } public Double Evaluate() { if (Operator == "+") return …

2
提供执行相同操作的不同功能签名是一个好主意吗?
这是一个用三个值构造的C ++类。 class Foo{ //Constructor Foo(std::string, int, char); private: std::string foo; char bar; int baz; }; 所有参数类型都不同。 我可以重载构造函数,因此顺序无关紧要。 class Foo{ //Constructors Foo(std::string, char, int); Foo(std::string, int, char); Foo(char, int, std::string); Foo(char, std::string, int); Foo(int, std::string, char); Foo(int, char, std::string); private: std::string foo; char bar; int baz; }; 但这是个好主意吗? 我开始这样做是因为我知道一个类/函数需要什么东西。 我并不总是记得他们接受了什么命令。 …

2
C#是否可以与本机C ++编译器合并?[关闭]
按照目前的情况,这个问题不适合我们的问答形式。我们希望答案会得到事实,参考或专业知识的支持,但是这个问题可能会引起辩论,争论,民意调查或扩展讨论。如果您认为此问题可以解决并且可以重新提出,请访问帮助中心以获取指导。 7年前关闭。 根据这篇文章: http://channel9.msdn.com/Forums/Coffeehouse/MS-working-on-a-same-compiler-for-C-AND-C--Not-in-incubation-but-for-production- 这个帖子有多少真相?硬核C ++程序员(游戏开发者等)应该认真对待吗? 编辑:这个问题还有另一个目的... C#是否可以与C ++向后兼容?
23 c#  c++ 

5
在“无人问津”的世界中进行单元测试
我不认为自己是DDD专家,但作为解决方案架构师,请尽可能尝试应用最佳实践。我知道围绕DDD中的(公共)二传手“样式”的赞成和反对有很多讨论,我可以看到论点的两面。我的问题是,我在一个拥有各种技能,知识和经验的团队中工作,这意味着我不能相信每个开发人员都会以“正确”的方式做事。例如,如果我们设计域对象以便通过一种方法来执行对对象内部状态的更改,但提供公共属性设置器,则有人将不可避免地设置该属性而不是调用该方法。使用此示例: public class MyClass { public Boolean IsPublished { get { return PublishDate != null; } } public DateTime? PublishDate { get; set; } public void Publish() { if (IsPublished) throw new InvalidOperationException("Already published."); PublishDate = DateTime.Today; Raise(new PublishedEvent()); } } 我的解决方案是将属性设置器设为私有,这是可能的,因为我们用来为对象水合的ORM使用反射,因此它能够访问私有设置器。但是,这在尝试编写单元测试时会出现问题。例如,当我想编写一个单元测试来验证我们不能重新发布的要求时,我需要指出该对象已经发布。我当然可以通过两次调用Publish来做到这一点,但是我的测试假设第一次调用正确实现了Publish。好像有点臭。 让我们使用以下代码使场景更真实一些: public class Document { public Document(String title) …



3
为什么通常首选多线程来提高性能?
此问题是从Stack Overflow 迁移而来的,因为可以在Software Engineering Stack Exchange上回答。 迁移 6年前。 我有一个问题,那就是为什么程序员似乎总体上喜欢并发和多线程程序。 我在这里考虑2种主要方法: 一种基本上基于信号的异步方法,或者只是许多论文和语言(例如,新的C#5.0)所调用的一种异步方法,以及一个用于管理管道策略的“伴侣线程” 并发方法或多线程方法 我只是说,我正在考虑这里的硬件和最坏的情况,并且我自己已经测试了这两种范例,异步范例是赢家,因为我不明白为什么人们有90%的情况当他们想要加快工作速度或充分利用他们的资源时,谈论多线程。 我已经在一台旧计算机上使用Intel四核测试了多线程程序和异步程序,该英特尔四核在CPU内不提供内存控制器,内存完全由主板管理,在这种情况下,性能令人震惊。多线程应用程序,即使是数量相对较少的线程(例如3-4-5)也可能是一个问题,该应用程序没有响应,并且运行缓慢且令人不快。 另一方面,一种好的异步方法可能不会更快,但也并不坏,我的应用程序只是等待结果并且不会挂起,它具有响应能力,并且伸缩性更好。 我还发现,线程世界中的上下文更改在现实世界中并不是那么便宜,实际上它相当昂贵,尤其是当您有两个以上的线程需要循环和相互交换来计算时。 在现代CPU上,集成的内存控制器的情况并没有什么不同,但我的观点是x86 CPU基本上是一台串行计算机,并且该内存控制器的工作方式与在主板上带有外部内存控制器的旧计算机的工作方式相同。 。上下文切换仍然是我应用程序中的一个相关成本,并且集成了内存控制器或较新的CPU具有2个以上内核的事实对我来说并不便宜。 因为我所经历的并发方法在理论上是好的,但在实践中却不是那么好,由于硬件强加了内存模型,很难很好地利用这种范式,而且还引入了很多问题,从使用到使用我的数据结构连接到多个线程。 同样,这两种范式都不能提供任何安全性,而只是在某个时间点完成任务或工作时,从功能的角度来看,它们确实非常相似。 根据X86内存模型,为什么大多数人建议对C ++使用并发,而不仅仅是异步方法?另外,为什么不考虑环境切换可能比计算本身更昂贵的计算机的最坏情况呢?

3
清单以避免供应商锁定?
是否有一套行业认可的规则来避免供应商锁定? 我的意思是,可以向经理或其他决策者展示的东西易于理解且易于验证。 是否有任何一套普遍接受的规则,清单或条件集可以帮助以客观,可衡量的方式检测和防止供应商锁定? 你们中的任何人是否曾就项目初期阶​​段供应商锁定的风险警告过经理?

1
seq在Haskell生产代码中多久使用一次?
我在使用Haskell编写小型工具方面有一些经验,我发现使用起来非常直观,尤其是对于编写过滤器(使用interact)来处理其标准输入并将其通过管道传输到标准输出。 最近,我尝试在比通常大10倍的文件上使用这样的过滤器,但出现Stack space overflow错误。 在阅读了一些内容之后(例如,在这里和这里),我确定了两个节省堆栈空间的准则(有经验的Haskellers,如果我写的东西不正确,请纠正我): 避免使用非尾递归的递归函数调用(这对所有支持尾调用优化的功能语言均有效)。 引入seq强制对子表达式进行早期评估,以使表达式在被缩减之前不会变得太大(这是Haskell所特有的,或者至少是使用惰性评估的语言所特有的)。 seq在我的代码中引入了五到六个调用之后,我的工具再次运行平稳(也适用于较大的数据)。但是,我发现原始代码更具可读性。 由于我不是一位经验丰富的Haskell程序员,所以我想问一下seq以这种方式进行介绍是否是一种常见的做法,以及通常seq在Haskell生产代码中看到该代码的频率。还是有什么技术可以避免使用seq太频繁而仍然只使用很少的堆栈空间?

3
命名“必要时执行X”方法
命名检查X是否需要完成的方法的好方法是什么?如果需要X可以这样做吗? 例如,如何命名新用户登录后更新用户列表的方法?UpdateListIfNeeded似乎太长了,虽然简单UpdateList意味着每次都可能进行昂贵且不必要的操作。EnsureListUpdated也是一个变体。 C#有一个bool TryXXX(args, out result)模式(例如int.TryParse(str, out num))来检查X是否可能并且可以这样做,但这是稍有不同的。

5
如何实施安全的密码历史记录
出于明显的安全原因,不应以纯文本形式存储密码:您必须存储散列,并且还应谨慎生成散列,以避免彩虹表攻击。 但是,通常您需要存储最后的n个密码,并在不同密码之间进行最小的复杂度和最小的更改(以防止用户使用诸​​如Password_1,Password_2,...,Password_ n之类的序列)。使用纯文本密码将是微不足道的,但是如何仅存储散列呢? 换句话说:如何实现安全的密码历史记录机制?

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.