软件工程

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


6
方法是否应该原谅传入的参数?[关闭]
已关闭。这个问题需要更加集中。它当前不接受答案。 想改善这个问题吗?更新问题,使其仅通过编辑此帖子来关注一个问题。 4年前关闭。 假设我们有一个foo(String bar)仅对满足特定条件的字符串进行操作的方法;例如,它必须为小写字母,不能为空或只有空格,并且必须与pattern匹配[a-z0-9-_./@]+。该方法的文档说明了这些条件。 该方法应该拒绝任何和所有与该标准的偏差,还是该方法对某些标准更为宽容?例如,如果初始方法是 public void foo(String bar) { if (bar == null) { throw new IllegalArgumentException("bar must not be null"); } if (!bar.matches(BAR_PATTERN_STRING)) { throw new IllegalArgumentException("bar must match pattern: " + BAR_PATTERN_STRING); } this.bar = bar; } 第二种宽容方法是 public void foo(String bar) { if (bar == …
21 java  parameters 

4
为什么Git .git / objects /文件夹又细分为许多SHA前缀文件夹?
Git在内部将对象(斑点,树)存储在.git/objects/文件夹中。每个对象都可以由从对象内容计算得出的SHA1哈希引用。 但是,对象并不.git/objects/直接存储在文件夹中。而是,每个对象都存储在一个文件夹中,该文件夹以其SHA1哈希的前缀开头。因此带有哈希值的对象b7e23ec29af22b0b4e41da31e868d57226121c84将存储在.git/objects/b7/e23ec29af22b0b4e41da31e868d57226121c84 为什么Git用这种方式细分其对象存储? 我可以找到的资源(例如git-scm 上有关Git内部的页面)仅说明了方法,而不是原因。

2
在现代C语言中,可变宽度类型是否已由固定类型取代?
今天,在对Code Review的回顾中遇到了一个有趣的观点。@Veedrac在recommened 此答案该可变大小类型(例如int和long)具有固定尺寸类型等来代替uint64_t和uint32_t。从该答案的评论中引用: int和long的大小(以及它们可以容纳的值)取决于平台。另一方面,int32_t始终为32位长。使用int只是意味着您的代码在不同平台上的工作方式不同,这通常不是您想要的。 @supercat 在此处部分解释了标准不固定常见类型的背后原因。与当时通常用于系统编程的汇编相反,C被编写为可跨体系结构移植。 我认为最初的设计意图是,除int之外的每种类型都是可以处理各种大小数字的最小事物,而int是可以处理+/- 32767的最实用的“通用”大小。 对于我来说,我一直在使用int,并不真正担心其他选择。我一直认为这是性能最好的大多数类型,故事结束了。我认为固定宽度唯一有用的地方是在对数据进行编码以进行存储或通过网络传输时。我也很少见过其他人编写的代码中的固定宽度类型。 我是停留在70年代还是int在C99及以后的时代实际上有使用的理由?

6
科学代码是一个足以忽略普通编码标准的领域吗?
最近,我一直在努力思考以下事实。 一方面,对于所谓的“健康”,“干净”,“编写良好”等代码,有大量的编码准则和标准。参见似乎也在此处广泛讨论的“清洁代码”。规则示例:7行长方法和1或2级缩进。不遵循的代码将因可维护性差而死亡。 另一方面,我可以使用OpenCV,OpenCascade,VTK等。这是科学代码。他们有2页长的方法(我自己说),OpenCascade的方法或类分为10个文件(这里没有笑话),VTK有时也很混乱。然而,这些项目繁荣起来,得到了维护和广泛使用! 哪里有收获?我们是否被允许以一种可以正常工作的方式编写科学的,繁重的代码,并且我们可以对其进行维护?您是否为此类项目制定了一套单独的标准? 也许这是一个幼稚的问题,但是我似乎在一个编程空白中试图建立一套规则,该如何做和不做某事,这就是我在高中时被教导要工作的方式。自从我毕业以来,我对所要做的事情(主要是编程)几乎没有指导性的支持-没人会教。

3
“加号”和“减号”是否合适?
的Java SE 8自带的日期,引入了新的机制LocalDate,LocalTime以及LocalDateTime类来表示的时刻。为了操纵这些瞬间,给出了一组方法:LocalDate.plusDays(...),LocalDate.minusDays(...)依此类推。 我一直认为,好的做法是在动词后描述方法的目的来命名方法,因为方法实际上是要执行的操作,它们会执行某种动作。刚才说了,如果你考虑类,比如StringBuilder,例如,方法的名字是append,insert,delete... 这就是为什么我不健全的权利命名的方法plusDays来代替sumDays,minusDays而不是subtractDays。只是我觉得很烦吗?你怎么看? 我能想到的唯一原因是日期是不可变的对象,因此通过调用plusDays您不是在原始对象上添加日期,而是创建具有新属性的新对象,但这非常微妙。

4
有什么方法可以避免域类和SQL查询之间的逻辑重复?
下面的示例完全是人为的,其唯一目的是使我理解我的观点。 假设我有一个SQL表: CREATE TABLE rectangles ( width int, height int ); 域类: public class Rectangle { private int width; private int height; /* My business logic */ public int area() { return width * height; } } 现在假设我有一个要求向用户显示数据库中所有矩形的总面积。我可以通过获取表的所有行,将它们变成对象并对其进行迭代来做到这一点。但这看起来很愚蠢,因为我的桌子上有很多矩形。 所以我这样做: SELECT sum(r.width * r.height) FROM rectangles r 这很容易,快速并且利用了数据库的优势。但是,它引入了重复的逻辑,因为我的域类中的计算也相同。 当然,对于这个例子,逻辑的重复根本不是致命的。但是,我的其他域类也面临同样的问题,它们更为复杂。

5
用于计算目标最大子弹路径的算法。2 ricochets
对不起,标题很抱歉,但我没有更好的措辞... 因此,任天堂在Wii上开发了一款名为WiiPlay的出色游戏(是!)。里面有9个迷你游戏,而我最喜欢的一个叫做《坦克》!。这是关于销毁COM敌方坦克而又不致使自己遭到破坏的事情。这是一个关卡的屏幕截图: 摧毁坦克的一种方法是发射子弹。有一个石灰绿色的敌方坦克,可以发射高速子弹,两次弹跳(对着墙壁和方块)。您会看到,如果玩家的坦克停在现在的位置,如何立即将其摧毁,因为位于中央的石灰坦克可以按照我在图像上绘制的绿色路径发射子弹。 作为一名业余程序员,我一直想知道石灰罐如何确定朝哪个方向射击以击打玩家罐。 我自己考虑过,但是没有提出任何可能的算法。如果他们启发了某人,我将解释我的结论。为了简单起见,我假设一堵墙是子弹可以弹到的任何表面。因此,一个孤立的矩形块形成了四个墙。 我得出的结论是,子弹跳线始终位于平行四边形的一侧或变成平行四边形的相反顶点的两个点。它瞄准的射击敌方坦克和玩家坦克不一定是其他两个顶点,而是肯定位于与平行四边形的四个边中的任何一个共线的直线上。这是形成平行四边形的4种可能方式的说明: HOR-VER意味着子弹首先撞击水平的墙壁,然后撞击垂直的墙壁。 然后我被卡住了。我曾考虑过绕一条连接敌方坦克和玩家坦克的地图绕线移动,以查看它是否与任何墙面的任何两个击打形成平行四边形,但这并不总是可行的,因为敌方坦克和玩家坦克不是必须与平行四边形的顶点重合。 另外,我不确定算法的一般流程。该算法是否采用以下两种结构中的任何一种,或者我对这两种结构都错了? 不断找出可能的路径,并始终将其标记为最佳路径(可以是最短,最模糊,最不可避免的路径,或者是基于多个标准的组合加权评估),而忽略了其余的路径。毕竟,剩下的一个是最好的选择。 首先确定首先由子弹到达的所有墙壁(子弹不需要弹跳到任何其他墙壁即可到达这些墙壁中的每一个),然后确定这些墙壁中的每个墙壁上的所有可到达范围(有时不可能到达目标上的遥远点)如果您附近还有一堵墙,则没有弹跳的墙),然后再次确定所有带有弹跳的可到达​​墙,以及在这些墙上可到达的所有范围。这4个过程可以通过类似于光线跟踪的方法来完成。在每个过程中,如果玩家的坦克被任何射线击中,请根据该射线找出子弹路径。 我认为该算法很难弄清楚,原因是: 子弹可以向任何方向发射;和 在数学上,每堵墙上都有无数个点,在线上有无数个点。 但是任天堂的人还是成功了,所以...有人有主意吗?

2
为什么C使用星号作为指针?[关闭]
已关闭。这个问题是基于观点的。它当前不接受答案。 想改善这个问题吗?更新问题,以便通过编辑此帖子以事实和引用的形式回答。 4年前关闭。 我现在正在学习C。 我感到奇怪的是,创建者选择星号(*)作为指针的符号,而不是实际上看起来像指针(->)的符号。 考虑到取消引用和函数指针可能会造成混淆,使用星号是否有历史或什至实际的原因?
21 c  history  syntax 

4
函数式编程是否可以替代依赖项注入模式?
我最近读了一本书,名为《用C#进行函数式编程》,我发现函数式编程的不可变和无状态本质可以实现与依赖注入模式相似的结果,并且可能甚至是更好的方法,尤其是在单元测试方面。 如果对这两种方法都有经验的人可以分享他们的思想和经验以回答主要问题,我将不胜感激:函数式编程是否可以替代依赖项注入模式?

9
您如何扩展集成测试?
我正在研究用于扩展我们当前产品上不断增加的集成测试数量的技术和策略,以便使它们(人类)能够成为我们开发和CI流程的一部分。 在大约200多个集成测试中,我们已经达到1小时的标准以完成完整的测试运行(在台式机上运行),这对开发人员在常规推送过程中容忍运行整个套件的能力产生了负面影响。这正影响着积极地去管教他们创造良好的动机。我们只对关键的场景进行前后集成测试,并且我们使用的环境可以反映生产,该环境是在每次测试运行时从头开始构建的。 由于运行需要时间,因此无论测试运行有多集中,都会造成严重的反馈循环和许多浪费的周期,等待机器完成测试运行。别介意对流程和进度,理智和可持续性造成更大的负面影响。 我们希望在该产品开始变慢之前进行10倍以上的集成测试(虽然还不知道,但似乎还没有开始使用功能)。我认为在某些时候,我们必须合理地期望要进行几百或几千个集成测试。 明确地说,要防止这种情况成为关于单元测试和集成测试的讨论(永远不要交易)。我们正在使用TDD进行单元测试,并在该产品中进行集成测试。实际上,我们在服务体系结构的各个层进行集成测试,这对我们有意义,因为我们需要验证在将体系结构中的模式更改为其他领域时,我们在何处引入重大更改。系统。 关于我们的技术栈的一些知识。我们目前正在(CPU和内存密集型)仿真环境上进行测试,以从头到尾运行我们的测试。由组成noSql后端(ATS)的Azure REST Web服务组成。我们通过在Azure桌面模拟器+ IISExpress中运行来模拟生产环境。每台开发机仅限于一个模拟器和一个本地后端存储库。 我们也有一个基于云的CI,它可以在相同的仿真环境中运行相同的测试,并且与我们当前的CI提供程序一起在云中进行测试所花费的时间是其两倍(2小时以上)。就硬件性能而言,我们已经达到了云CI提供程序SLA的极限,并且超出了他们在测试运行时间上的允许范围。为了公平起见,他们的规格还不错,但显然是内部脏台式机的一半。 我们正在使用一种测试策略,为每个逻辑测试组重建数据存储,并预加载测试数据。在全面确保数据完整性的同时,这对每个测试增加了5-15%的影响。因此,我们认为在产品开发的这一点上优化该测试策略几乎无济于事。 总而言之,它的缺点是:尽管我们可以优化每个测试的吞吐量(即使每个测试的吞吐量提高多达30%-50%),但在不久的将来,我们仍然无法通过数百个测试有效地扩展规模。现在1小时甚至还远远超出了人类可以忍受的范围,我们需要在整个过程中进行一定程度的改进以使其可持续。 因此,我正在研究可以采用哪些技术和策略来大大减少测试时间。 编写更少的测试不是一种选择。让我们不要在这个线程中争论那个。 尽管价格昂贵,但绝对可以选择使用更快的硬件。 无疑,在并行环境中在单独的硬件上运行测试/方案组也是肯定的选择。 围绕正在开发的功能和场景创建测试分组是合理的,但最终无法证明完整的覆盖范围或对系统不受更改影响的信心。 从技术上讲,可以在云规模的暂存环境中运行而不是在台式机模拟器中运行,尽管我们开始将部署时间添加到测试运行中(在测试运行开始时每个部署时间大约20分钟以部署内容)。 将系统的组件分成独立的逻辑部分在一定程度上是合理的,但是由于组件之间的干扰预计会随着时间而增加,因此我们认为在此方面的里程有限。(即,更改是无效的,可能会以意想不到的方式影响其他人,这在系统逐步开发时经常发生) 我想看看其他人在这个领域使用什么策略(和工具)。 (我必须相信其他人在使用某些技术集时可能会遇到这种困难。) [更新:2016年12月16日:我们最终在CI并行测试上投入了更多资金,以讨论结果:http://www.mindkin.co.nz/blog/2015/12/16/16-jobs]

3
如何在敏捷方法论中进行创新[关闭]
已关闭。这个问题需要更加集中。它当前不接受答案。 想改善这个问题吗?更新问题,使其仅通过编辑此帖子来关注一个问题。 5年前关闭。 可以说一句话,敏捷方法在对需求了解甚少或涉及新颖性的环境中很好。但是,应将其应用于需要彻底创新的地方吗?如果是,怎么办? 如果您要考虑的事情在行业中是未知的,或者甚至被认为是不可能的,那么可能很难想象用户故事和相关任务。例如,通过将广义相对论分解为史诗,冲刺和任务来设计广义相对论,是否会使艾伯特·爱因斯坦(或他向之报告的假设雇主)受益?如果答案是“是”,那么应该采用哪些特殊的措施来帮助敏捷方法与爱因斯坦获得革命性见解的方法一起发挥最佳作用? 举一个特定的软件示例,假设年份为2008,并且您想使用WCF提供COMET或“ 长轮询 ”类型的功能。您对“以前的工作”的所有研究都没有结果,甚至您还读过一个MSDN博客说这是不可能的。 再者,可以为用户故事和任务带来什么调整或“风味”,以适应此Endeaver的发明性(或胆大?)?还是可以断定这项工作具有创新性(在2008年),最好还是将其作为无方向的智囊团活动,这会更好吗? 在两个星期的冲刺状态下工作的创新者当然不希望每次放弃一个死胡同的任务而开始从事新的任务,而该任务是在定义冲刺时未曾设想的,因此他不想被击落。同样,当冲刺结束并且没有交付任何工作代码或工作方法时,创新者也不应被管理层击倒。即使在这些情况下,也需要一种将努力标记为“成功”的方法。在这种“死胡同”的追求中,创新者可能再经过一三个冲刺,最终找到可行的方法。 敏捷如何让管理层知道,尽管有一些挫折,每个冲刺还是“不错”的?如何进行管理,以使燃尽图看起来并不荒谬?
21 agile 


5
开发人员之间应该共享用户故事吗?[关闭]
已关闭。这个问题是基于观点的。它当前不接受答案。 想改善这个问题吗?更新问题,以便通过编辑此帖子以事实和引用的形式回答。 5年前关闭。 我通常会看到具有后端和前端开发功能的故事。例如,考虑一个带有几个表和一些动态控件的大对话框。我们将制作几个故事(也许每个表一个,而动态控制系统一个)。 然后,开发团队将在后端拆分一个人,在前端拆分另一个人。这使后端人员可以轻松担心SQL层的结构,而前端人员则可以专注于布局之类的工作。在后端和前端之间的初始接口达成协议后,两个开发人员可以集中精力在sprint结束时完成自己的任务。 然后是混乱。谁“拥有”哪个故事?“进行中”是什么意思?我们应该为后端和前端分别制作两个故事吗?如果是这样,这是否会打破基于功能的用户故事的观念?我们的系统具有“子任务”的概念,可以缓解其中的一些问题。但是子任务增加了额外的复杂性。有没有更好的办法?这是使用Scrum的“坏”方式吗? 过去几年中,我在一些地方一直在使用某种形式的敏捷。我尚未接受官方培训,因此请原谅任何错误的术语或意识形态。我只是想学习实用的方法来改善我们的流程。
21 agile  scrum 

4
那么,LISP如何使宏系统的实现变得更容易呢?
我正在从SICP学习Scheme,给人的印象是,使Scheme以及LISP特别与众不同的很大一部分是宏系统。但是,由于宏是在编译时扩展的,所以人们为什么不为C / Python / Java /任何东西制作等效的宏系统?例如,可以将python命令绑定到expand-macros | python或任何其他内容。该代码对于不使用宏系统的人仍然可以移植,只是在发布代码之前扩展宏即可。但是除了C ++ / Haskell中的模板之外,我不知道其他类似的东西,我收集的模板并不完全相同。那么,LISP又如何使实现宏系统更容易呢?

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.