软件工程

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


3
处理库中可见性的常用方法是什么?
这个问题何时使用私人和当类使用受保护的让我去思考。(由于与之相关,我还将这个问题扩展到最终的类和方法。我使用Java编程,但是我认为这与每种OOP语言都相关) 接受的答案是: 一个好的经验法则是:使所有内容尽可能私密。 还有一个: 除非您需要立即对它们进行子类化,否则将所有类定为最终类。 使所有方法最终化,除非您需要立即子类化并覆盖它们。 除非需要在方法主体中进行更改,否则将所有方法参数都设置为最终值,这在大多数情况下还是很尴尬的。 这非常简单明了,但是如果我主要是编写库(GitHub上的开源)而不是应用程序怎么办? 我可以说很多图书馆和情况, 库以开发人员从未想过的方式扩展 由于可见性限制,必须使用“类加载器魔术”和其他技巧来完成此操作 库的使用方式不是为它们而建,而是以所需的功能“入侵” 由于存在小问题(错误,功能缺失,“错误”行为),无法使用库,原因是可见度降低,无法更改 无法解决的问题导致了巨大的,丑陋的和错误的解决方法,在这些解决方法中,覆盖简单的功能(私有或最终的)可能会有所帮助 实际上,我开始命名它们,直到问题过长,然后我决定将其删除。 我喜欢这样的想法,即没有多余的代码,比可见性更多的可见性,比需求更多的抽象性。当为最终用户编写应用程序时,这可能会起作用,因为最终代码仅由编写该应用程序的人员使用。但是,如果代码打算供其他开发人员使用,而原始开发人员则不可能事先考虑到每种可能的用例,并且很难/不可能进行更改/重构,那么这将如何保持呢? 既然大型开源库不是什么新鲜事物,那么在使用面向对象语言的此类项目中处理可见性的最常用方法是什么?


5
如何将敏捷应用于涉及复杂处理的应用程序?
关于敏捷的大多数文献似乎偏向于CRUD类型的业务应用程序,在该应用程序中,用户非常了解幕后情况。(这很好,因为所编写的大多数代码可能都属于此类。) 对于这种类型的应用程序,用户故事(需求)和开发任务之间的关系通常很简单:只需将用户故事分成几个任务即可。 但是还有另一种类型的应用程序,其中大多数代码必须处理用户不直接可见的复杂处理。例如: 编译器 自动驾驶汽车图像分析系统 流体模拟系统 在这里,将任务和用户案例联系起来确实非常困难。是否有克服这一问题的技术,或者仅仅是我们必须接受并充分利用的技术?

2
文件系统是否将存储设备视为(非常大的)字节数组?
我想知道文件系统如何写入和读取存储设备。 我认为这是这样的: 文件系统不会直接访问存储设备,而是(通过存储设备的设备驱动程序)将存储设备作为(很大)字节数组呈现给文件系统。 例如,如果文件系统要访问硬盘,它将仅访问代表硬盘的字节数组。 这样,文件系统可以与任何类型的存储设备(传统硬盘,SSD,USB闪存驱动器等)一起使用,并且仅更改存储设备的设备驱动程序。 此图显示了我刚刚解释的内容: 我的理解正确吗?

4
在以“功能”风格进行编程时,您是否在应用程序逻辑中编织了一个应用程序状态?
如何构建具有以下所有功能的系统: 对不可变对象使用纯函数。 只传递给它所需功能的数据,不再传递(即没有大的应用程序状态对象) 避免对函数使用过多的参数。 避免仅出于将参数打包和拆包到函数的目的而构造新对象的方法,只是避免将过多的参数传递给函数。如果我要将多个项目作为一个对象打包到一个函数中,则我希望该对象成为该数据的所有者,而不是临时构造的东西 在我看来,State monad违反了规则2,虽然它并不明显,因为它是通过monad编织而成的。 我觉得我需要以某种方式使用Lenses,但是关于非功能语言的文章很少。 背景 作为练习,我将现有的应用程序之一从面向对象的样式转换为功能样式。我要尝试做的第一件事是尽可能多地利用应用程序的内核。 我听到的一件事是,如何用一种纯函数式的语言来管理“状态”,而我相信这是由State monad完成的,从逻辑上讲,您称一个纯函数为“传递状态”。世界原样”,那么当函数返回时,它会返回给您变化后的世界状态。 为了说明这一点,您可以用一种纯粹的功能性方式来创建“ hello world”的方式有点像,您将程序的屏幕状态传递给程序,然后返回印有“ hello world”状态的屏幕状态。因此,从技术上讲,您要调用一个纯函数,并且没有副作用。 基于此,我遍历了我的应用程序,并且:1.首先将我的所有应用程序状态放入单个全局对象(GameState)中。2.其次,使GameState不可变。您无法更改。如果需要更改,则必须构造一个新的。我通过添加一个复制构造函数来做到这一点,该复制构造函数可以选择接受一个或多个已更改的字段。3.对于每个应用程序,我都将GameState作为参数传递。在函数内,在完成将要执行的操作后,它将创建一个新的GameState并返回它。 我如何拥有纯功能核心,以及外部的循环,该循环将GameState馈入应用程序的主工作流程循环。 我的问题: 现在,我的问题是,GameState有大约15个不同的不可变对象。最低级别的许多功能仅对其中一些对象起作用,例如保持得分。因此,假设我有一个计算得分的函数。今天,GameState传递给此函数,该函数通过使用新分数创建新的GameState来修改分数。 似乎有些错误。该功能不需要完整的GameState。它只需要Score对象。所以我更新了它以传递分数,并仅返回分数。 这似乎很有意义,所以我进一步介绍了其他功能。有些功能需要我从GameState传入2、3或4个参数,但是随着我一直在应用程序的外部核心中使用该模式,我传入了越来越多的应用程序状态。就像在工作流循环的顶部,我将调用一个方法,该方法将调用将调用一个方法的方法,依此类推,一直到计算分数为止。这意味着当前分数会通过所有这些层,只是因为最底层的函数将要计算分数。 所以现在我有了带有数十个参数的函数。我可以将这些参数放入一个对象中以减少参数数量,但是然后我希望该类成为状态应用程序状态的主位置,而不是在调用时简单地构造以避免重复传递的对象输入多个参数,然后解压缩它们。 所以现在我想知道我的问题是否是我的函数嵌套得太深了。这是因为希望具有较小的功能,所以我在一个功能变大时进行重构,然后将其拆分为多个较小的功能。但是这样做会产生更深的层次结构,即使外部函数未直接在这些对象上运行,传递给内部函数的所有内容也都必须传递给外部函数。 似乎只是在避免这种问题的过程中传入了GameState。但是我回到了原来的问题,即向函数传递比函数所需更多的信息。

2
如何测试和测试互斥量实现
如标题所述:如何正确测试和基准化c ++中互斥锁的不同实现? 本质上,我为在2核,armv7上运行的项目编写了自己的std :: mutex类似类,目的是在无争议的情况下最大程度地减少开销。现在,我正在考虑在更多地方以及不同的体系结构中使用所说的互斥锁,但是在执行此操作之前,我想确保 这实际上是正确的 没有任何病理情况比标准的std :: mutex表现差很多。 显然,我写了一些基本的单元测试和微基准测试,一切似乎都可以用,但是在多线程代码中,“似乎可以使用”并不能给我带来很大的安慰。 那么,是否有已建立的静态或动态分析技术? 为互斥类编写单元测试时,常见的陷阱有哪些? 在性能方面应该注意哪些典型的极端情况? 我仅将标准库类型用于实现,其中包括对原子的非顺序一致的加载和存储操作。但是,我主要对实现不可知的建议感兴趣,因为我也想对其他实现使用相同的测试工具。
12 c++  testing  mutex 

3
分层数据的平面或嵌套JSON?
我已经来回切换了约5次。这个REST端点/api/tags/仅供内部使用(没有第三方客户端),我是唯一使用它的人。 我要在这两种表示形式之间做出决定: 平面 { "types":[ { "id":1, "text":"Utility" }, { "id":7, "text":"Lease Terms" }, ], "tags":[ { "id":8, "text":"Water", "type":1 }, { "id":9, "text":"Electricity", "type":1 }, { "id":5, "text":"Minimum 12 month lease", "type":7 }, { "id":17, "text":"lease negotiable/flexible", "type":7 }, ] } 它有点模块化。可以添加另一个顶层,例如“国家/地区”而不会破坏兼容性。 巢状 { "1":{ "text":"Utility", "tags":{ "8":{ "text":"Water" …
12 rest  api-design  json 

4
将标志用于“分组”枚举是否错误?
我的理解是,[Flag]枚举通常用于可以组合的事物,其中各个值并不相互排斥。 例如: [Flags] public enum SomeAttributes { Foo = 1 << 0, Bar = 1 << 1, Baz = 1 << 2, } 凡SomeAttributes值可以是一个组合Foo,Bar和Baz。 在更复杂的现实场景中,我使用一个枚举来描述DeclarationType: [Flags] public enum DeclarationType { Project = 1 << 0, Module = 1 << 1, ProceduralModule = 1 << 2 | Module, ClassModule = 1 …
12 c#  .net  readability  enum 

2
如何真正找出面向对象设计中必须要做的事情?
首先免责声明:我真的不知道这个问题是否适合该网站,但是我仍然发现它不仅对我而且对其他初学者都是一个相关的问题。如果可以改善问题以使其适合此处,请指出int注释。如果不合适,也让我知道,如果可能的话,让我知道可以在哪里讨论,因为我没有找到任何好的论坛。 我在2009年学习PHP时就学会了编程。2012年晚些时候,我转到了C#和.NET。无论如何,编码不是问题,写下算法不是我的问题。我的实际问题是要知道必须编码什么才能达到要求,必须在哪里编码。 网络上提供的大多数课程都讨论了如何 -如何用某种语言编写代码,如何使用一些API集等。这不是我的意思。 这些年来,我读了很多有关一堆东西的信息:面向对象的分析和设计,设计模式,领域驱动的设计等等。例如,我了解SOLID原则,DDD的一些主要思想,例如聘请领域专家的必要性,开发无处不在的语言等。我敢说我的理论背景至少合理。 但是,当谈到练习时,我觉得自己是一场灾难。前一段时间,我需要继续开发已经由其他人开发的金融系统。这就是用C#和WinForms开发的那种“旧系统”。这是我第一次选择一个具有实际领域复杂性,业务规则等等的项目。 我承认,当我大多数时候收到要求时,我认为“这到底是怎么做的?” -我什至不知道如何开始着手研究需求以弄清楚必须做什么。我认为我的主要困惑是我必须编写什么代码,什么类,接口以及每条逻辑的去向,每件事必须在哪个类上。问题是我不知道从哪里开始。 大多数时候,经过很多思考,我最终想到了一些主意,但是我却永远不知道如何判断我的主意是否正确。 我的意思是我不认为这是一种理论上的不足,因为我说我已经阅读了有关软件体系结构和面向对象的一堆建议,但对确定实践中必须做的工作并没有多大帮助。 所以,我怎么能学会真正 做到面向对象的设计?我要学习的是:给定的需求知道如何开始在一个过程中进行工作,从而找出必须完成的工作以及每个代码所属的位置。我还如何学习判断我的想法是否正确? 我相信在这里不可能完全解释这一点作为答案。但是,我所寻找的可能是根据网站样式而定的答案,只是给出概述并指出一些参考资料(书籍,在线课程等),这些参考资料可用于扩展思想并真正学习这些知识。

1
共享部分monorepo
当前,我们有一个复杂而效率低下的构建系统,其中包含许多SVN和Git存储库(每个约50%),其中包括一个git子模块存储库。我们也有自制脚本,可以或多或少地管理整个事情。 我们的(封闭源代码)代码库的一个主要要点是紧密耦合,并且每个项目都在同一版本下同时发布。 我们希望将其迁移到更简单的系统和单个VCS,并正在考虑几个选项,包括:git子模块,google repo和monorepos。最终的VCS尚未定义(强制使用的选项除外),并且如果更适合我们的情况,则可以是svn,git甚至其他名称。 我们试图列出每种解决方案的优缺点,而monorepos当前面临的主要问题之一是,这似乎并不容易,甚至可能只与外部实体共享某些模块。我们希望这些人员能够检出并在这些模块上正常工作,但不能访问回购其余部分的代码或历史记录。目前,这不是我们经常或广泛进行的事情,但将来可能会发生,并且我们不希望这成为噩梦,因为我们在这里做出了错误的决定。 VCS系统中是否存在这样的特权管理系统? 还是有什么办法可以减轻这个问题?

6
用于描述修改其调用对象的功能/方法的术语是什么?
对不起,通用问题。我到处搜索,发现了很多与此类似的线程,但是没有一个可以回答我的特定问题-也许是因为我要查找的术语甚至不存在。 我的一个朋友正在学习编程,特别是JavaScript,他问我为什么这样做不起作用: var a = "Hello World"; a.replace("Hello", "Goodbye"); console.log(a) // Logs "Hello World" 原因是因为replace不修改a,因为字符串在JavaSript中是不可变的。因为它返回一个字符串,所以您需要执行以下操作... var a = "Hello World"; a = a.replace("Hello", "Goodbye"); console.log(a); // Logs "Goodbye World" 但是,替代方法是类似JavaScript的函数reverse(),因为它会修改任何调用它的函数。例如: var fruits = ["Apples", "Oranges", "Bananas"]; fruits.reverse(); console.log(fruits) // ["Bananas", "Oranges", "Apples"] 当我的朋友问我为什么他replace不工作时,我意识到我在说一个我不知道的词(据我所知)... “您必须将字符串设置为“字符串点替换”,因为替换功能是________。” 您无需将数组设置为等于“数组点反向”,因为反向是________。 我不熟悉原型函数,但我不相信这是我要找的单词。谁能帮我填补这些空白?

4
是否有适用于所有货币(甚至包括不同于美元,欧元和英镑的货币)的单一数据表示形式?
我可以找到许多有关用于以某种货币表示金额的库的问题。关于为什么不应该将货币存储为IEEE 754浮点数的古老问题。但我似乎找不到更多。当然,在现实世界中,有关货币的知识还有很多。我对您需要了解以物理方式表示它的内容特别感兴趣(例如,对于美元,您永远不会低于0.01美元的精度,允许以整数美分表示)。 但是,当您知道的唯一的货币是西方流行的货币(例如美元,欧元和英镑)时,就很难对程序的通用性做出假设。从纯粹的程序设计角度来看,还有哪些相关知识?我不关心转换主题。 特别是,我们需要知道什么才能能够以某种货币存储值并打印出来?


5
寻找最适合圈子的人
下面是一个示例图像,如果我在中间有一个白点,并且我想找到所有可能存在的红色圆圈,则该蓝色圆圈的位置可能最近(显然是我放置它的位置) 。如何找到该位置? 对我来说,性能并不是此应用程序的主要问题。

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.