软件工程

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

4
当客户的需求完全不变时,使用敏捷是错误的吗?
我最近看到很多帖子说,使用敏捷的主要原因之一是因为客户经常更改需求。 但是,假设客户不会经常更改需求。实际上,客户的要求虽然严格,但可能有些含糊(但没有任何不合理的含糊),但无论如何,我还是使用敏捷。 我之所以选择敏捷,是因为该软件足够复杂,以至于存在一些细节和问题,直到我真正面对这些问题时我才意识到。我可以像瀑布一样进行全面的繁重计划,但是要花上几个月才能完成所有高级设计和低级代码签名。但是,系统有一个非常具体的固定体系结构设计。 我的问题是:这会被认为是不好的,牛仔编码,反模式等吗?在需求稳定时开始编码之前,我们是否必须采用瀑布式计划并尽可能详细地计划,而不是敏捷中的这种“让我们去做”的心态? 编辑:这里的主要观点是:我们不能责怪客户改变需求。假设客户向我们指出了一个非常具体的问题,给我们一个非常合理的细节的愿望清单,然后让我们独自一人(即客户有自己的生产性工作要做,别再烦他们了。只向他们演示当您有最低限度的工作原型时结束)。在这种情况下使用敏捷会错吗?

2
为什么不能在C中将数组作为函数参数传递?
继此评论,我试图谷歌为什么,但我的谷歌福失败。 来自链接的评论: [...]但重要的是,数组和指针在C中是不同的东西。 假设您没有使用任何编译器扩展,通常就不能将数组本身传递给函数,但是可以传递指针,并像建立数组一样对指针进行索引。 您实际上在抱怨指针没有附加长度。您应该抱怨数组不能作为函数参数传递,或者数组隐式降级为指针。
12 c  history 


6
如何避免垂头丧气?
我的问题是关于超类Animal的特殊情况。 我Animal可以moveForward()和eat()。 Seal延伸Animal。 Dog延伸Animal。 还有一个特殊的生物也Animal被称为Human。 Human还实现了方法speak()(不是由实现Animal)。 在接受抽象方法的实现中,Animal我想使用该speak()方法。如果不进行低调,这似乎是不可能的。杰里米·米勒(Jeremy Miller)在他的文章中写道,沮丧的气味。 在这种情况下,如何避免垂头丧气呢?

5
通过简单的替换将Windows文件路径转换为Unix文件路径是否安全?
因此,例如说我拥有它,这样我的所有文件都将从Windows机器转移到Unix机器,例如:C:\test\myFile.txtto {somewhere}/test/myFile.txt(此时驱动器号无关)。 当前,我们自己编写的实用程序库提供了一种方法,可以用正斜杠简单地替换所有反斜杠: public String normalizePath(String path) { return path.replaceAll("\\", "/"); } 斜杠是保留的,不能成为文件名的一部分,因此应保留目录结构。但是,我不确定Windows和Unix路径之间是否还有其他可能需要担心的麻烦(例如:非ASCII名称等)

2
在GitLab的同一服务器上运行CI?
我在公司中设置了一个GitLab服务器,现在向它添加了GitLab CI。 在开始此任务之前,我想了解在GitLab和GitLab CI使用的同一服务器上运行运行程序是否有任何不利之处。 我读过有安全性问题,但我们仅在内部使用它,因此我认为这可能不是问题。 我想念什么吗?

1
Clojure与Scala中的模式匹配
这两种语言的模式匹配之间的主要区别是什么?我不是在指语法,而是功能,实现细节,用例范围和必要性。 Scala应用程序(例如Lift和Play)自豪地谈到了语言模式匹配能力。另一方面,Clojure具有一个库core.match,并内置了解构功能,该功能似乎也很强大。 *注:之所以被问到这个问题,是因为我看到了一篇博客文章,其中的一个程序员作为实验,使用Scala和Clojure构建了一个Lisp解释器。他说,克洛瑞尔(Clojure)比赛在经过一定长度后就中断了,但无法解释原因,但我真的很想知道。您可以在以下位置找到此帖子:http : //www.janvsmachine.net/2013/09/writing-simple-lisp-interpreter-in-clojure.html

9
理论上无错误的程序
我读过很多文章,其中指出代码不可能没有错误,并且他们在谈论这些定理: 停止问题 哥德尔不完备定理 赖斯定理 实际上,赖斯定理看起来像是中止问题的一个暗示,而中止问题与哥德尔的不完备性定理密切相关。 这是否意味着每个程序都会有至少一个意外行为?还是意味着无法编写代码进行验证?递归检查呢?假设我有两个程序。他们两个都有错误,但是没有共享相同的错误。如果同时运行它们会发生什么? 当然,大多数讨论都涉及图灵机。线性有界自动化(真实计算机)如何?
12 bug  theory 

2
解决仅在特定设备上发生的错误的策略
作为Android开发人员,我为其创建应用的目标市场非常分散。虽然我可以指定某些要求-例如,我的应用仅支持xx或更高版本的Android,但有时可能会发生错误,这些错误仅在一种特定的手机型号上才明显。 是否有任何策略可以解决特定于设备的错误,而无需购买相关手机?我们维护了一套用于测试的手机,但是当2或3个用户报告只存在于其手机型号中的错误时,便无力外出购买新手机。 我敢肯定其他Android开发人员过去也遇到过类似的问题,并且很好奇可以使用哪些经济有效的策略来解决特定于设备的错误。 更新以添加一些细节: 我使用Bugsense捕获错误报告,因此,每当引发异常时,我都将知道电话的型号,堆栈跟踪,用户经历的次数以及其他一些细节。 这些用户可能位于不同的国家/地区,所以我无法假设自己可以借用他们的手机。 想象这样的情况: 100个用户已经安装了该应用程序,但是三个人抱怨按下按钮时按钮无法正常工作。我要测试的所有手机型号均未遇到该问题。问题电话型号似乎没有仿真器。

1
灵活实施DIFF的启发式方法
我创建了一个DIFF实现,以比较工作中的文档修订。它基于O(ND)差分算法及其变体。 变得很重要的一件事是获取更改列表并将其解释为人类可读的文本。尽管当前算法非常有效,但它是如此之大,以至于难以扩展。 简短问题 我当时正在考虑尝试使用A *和一种启发式方法,该方法会增加“转弯”的惩罚。想法是消除不必要的“添加,删除,添加,删除,添加,删除”,以便更轻松地解析为人类可以阅读的内容。基本上,将我的最短路径问题变成最简单的路径问题。 当然,不要创建始终为“删除所有内容,添加所有内容 ”的输出 听起来合理吗? 在DIFF实现中使用启发式算法是否有优先权?什么是启发式? 问题: 如果删除了一个长句子,又删除了另一个长句子,但它们确实共享至少一个单词,请说“与”。不理会常见单词(不要同时添加和删除它)将创建最短路径。但是,这实际上只是使尝试混淆更改打印内容的人感到困惑。 当前DIFF的示例: 旧文本: 清洁:用力洗净并用车间空气吹干。 新文本: 清洁:用丙酮和无绒布擦拭。 变更单清单: 将“强力清洗并吹干”更改为“用丙酮擦拭” 将“商店空气”更改为“丙酮和无绒布” 注意:使用“更改”代替 “删除'购买空气',添加'丙酮'” 如您所见,第二个注释失去了所有上下文,并且在没有查看完整的旧文本和新文本集的情况下,您无法理解其含义。 关于标点符号的注意事项: 我将标点符号分隔为单独的“单词”,这样我就可以 添加“(” 代替 将“修复”更改为“((修复) 因为这令人讨厌。但是,这意味着如果两个文本中甚至有一个逗号(与前面示例中的单词“ with”相对),就会发生相同的情况。 可能的解决方案: 我认为我可以使用不同的路径查找算法,从而使我能够灵活地为可能对人更有意义的不同更改“路径”增加权重。也许,我什至可以使旅行到包含标点符号的节点的权重很小(不确定这将如何影响其他事情)。 然后,我可以得到前面的示例以列出以下内容: 变更单清单: 将“ Powerwash并用商店空气吹干”更改为“用丙酮和不起毛的布擦拭” 看到!更清晰! 我知道我会在性能上受到打击,并且可能必须对程序进行大刀阔斧的检修,但是获得所需的最终结果更为重要。 底线: 同样,在DIFF实现中使用启发式方法是否有优先次序,这是什么? 其他想法?合理的时间投入?还有其他想法吗?其他算法? 提前致谢! 编辑: 我试图澄清/巩固我的问题,并推广我的问题,以在我的算法中添加启发式方法,而不是使用A *。在这种情况下,基本上是相同的事情,但是我现在仍然认为更准确。 这篇文章很有见地。

1
红色区域的目的是什么?
红色区域是内存中超出“未分配”堆栈指针的固定大小区域。编译器确实会生成汇编程序,以通过简单的叶函数访问该区域。 但是我看不出红色区域有任何真正的优势。在堆栈指针之外访问内存确实很危险,并且很容易导致数据损坏。为什么还要这样做?保存2条处理器指令(push ebp; mov ebp esp)不会真正提高速度。
12 assembly  stack 

4
数学运算符的成员函数与非成员函数
我正在编写一个线性代数库(长话短说,这是一个学校作业),它涉及矩阵,向量等。在创建该库的过程中,我将创建对对象执行数学运算的函数。例如,转置矩阵,反矩阵,归一化向量等。 我很好奇这种函数的“最佳实践”是什么...也就是说,我应该将该函数设为成员函数还是非成员函数?(为清楚起见/图书馆使用) 例: //Member function way: B = A.transpose(); C = A.inverse(); //Non-member function way: B = linalg::transpose(A); //Non-member transpose function in linear algebra namespace C = linalg::inverse(A); 关于这类操作是否有一些标准?或者至少,人们有一种通用的方式吗?我倾向于第一种选择,但我想知道是否建议这样做。
12 c++  libraries  methods 

5
谁应该进行代码审查?
在我公司中,大多数架构师都会进行代码审查。他是一个非常有经验和聪明的软件专家,因此他非常擅长。当开发人员进行代码审查时,他们不会做一半。我们试图让开发人员进行更多的代码审查,但是代码审查的质量并不理想。我们使用Scrum作为开发方法。 但是,对于当前系统,存在两个问题: 建筑师成为瓶颈 开发人员不对代码和体系结构的质量负责(这会导致各种问题)。 我们如何解决这些问题?我们应该更改代码审查的对象吗?

2
在源代码中隐藏API密钥的最佳方法
我需要一些有关如何保护应用程序(尤其是ac#.NET应用程序)中的私有API密钥的想法。 首先,我了解到从理论上讲不可能在源代码中隐藏任何内容,因此我想出了另一个想法,但是我不确定它的合理性。无论如何,是否有可能以某种方式与Web服务器通信以验证私钥,然后再与应用程序对话以确认它是合法的握手? 我有两个密钥可以使用:一个公共密钥(顾名思义,不必像对待私有密钥一样小心对待),以及一个私有密钥,它需要与他人保持安全。 我将如何做到这一点的任何想法将不胜感激。
12 c#  api  authentication 

1
哪些中间表示可用于推理并发?
我试图更好地理解编译器能够代表程序员对并发做出明智选择的要求。我意识到例如这个问题有很多困难的方面: 确保没有比赛条件 确保要同时运行的代码不会产生影响代码语义的副作用 给定代码中可用的并行度,确定是否有必要分散线程的开销 我的理解是,现代编译器中使用的两个主要中间表示形式是面向过程和面向对象语言的静态单一分配,以及面向功能语言的延续传递样式。使用这些中间形式似乎很难对上面列出的任何问题进行推理。即使是理论上应该在自动并行化方面机会最大的语言(诸如Haskell这样的纯功能语言,也没有副作用)在这方面也取得了有限的进展。 所以我的问题是,实际上使用了哪些中间表示来尝试解决该问题?我还不知道还有其他一些学术研究中使用的表示形式更适合此任务吗?这个问题是否是编译器前端必须从根本上通过在编译到达中间表示之前操纵抽象语法树来解决的问题?

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.