软件工程

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

6
类使用其自己的公共方法可以吗?
背景 我目前遇到一种情况,即我有一个设备同时发送和接收的对象。该消息具有以下几种构造: public void ReverseData() public void ScheduleTransmission() 该ScheduleTransmission方法需要调用ReverseData时,它被称为方法。但是,有时我需要从应用程序中实例化对象的地方进行ReverseData外部调用(并且应该完全在命名空间之外添加)。 至于“接收”,我的意思是ReverseData将在object_received事件处理程序中从外部调用该请求以撤消数据。 题 对象调用其自己的公共方法通常可以接受吗?

8
在什么时候禁忌在循环中循环?
只是好奇。我曾经遇到过的最多的是for循环中的for循环,因为从Linus Torvalds读取以下内容后: 制表符是8个字符,因此缩进也是8个字符。有些异端运动试图使缩进量增加4个(甚至2个!)字符,这类似于试图将PI的值定义为3。 原理:缩进的整个思想是明确定义控制块的开始和结束位置。尤其是当您连续20个小时查看屏幕时,如果压痕较大,则发现压痕的工作原理要容易得多。 现在,有些人会声称具有8个字符的缩进会使代码向右移得太远,并使得在80个字符的终端屏幕上难以阅读。 答案是,如果您需要三个以上的缩进级别,那么无论如何您都会被搞砸,应该修复程序。 https://www.kernel.org/doc/Documentation/CodingStyle 我认为进入第三层循环对我来说是不可接受的做法,并且会重组我的代码(Primally Qt)。 莱纳斯在开玩笑吗? 是否取决于语言或应用程序? 是否有某些事情绝对需要三级或更多级循环?

3
分散数据管理-将数据库封装到微服务中
已关闭。这个问题需要更加集中。它当前不接受答案。 想改善这个问题吗?更新问题,使其仅通过编辑此帖子来关注一个问题。 4年前关闭。 我最近参加了一门软件设计课程,并且最近对使用“微服务”模型进行了讨论/推荐,在该模型中,服务的各个组成部分被分成了尽可能独立的微服务子组件。 提到的一部分是,不是遵循一种常见的模型,即所有微服务都与之通信的单个数据库,而是为每个微服务运行一个单独的数据库。 可以在此处找到措辞更好且更详细的解释:http : //martinfowler.com/articles/microservices.html在“分散数据管理”部分下 最突出的部分是这样说的: 微服务更喜欢让每个服务管理自己的数据库,或者是相同数据库技术的不同实例,或者是完全不同的数据库系统-一种称为Polyglot Persistence的方法。您可以在整体中使用多语种持久性,但是在微服务中它的出现频率更高。 图4 我喜欢这个概念,除其他外,我认为这是对维护的一项重大改进,并且有多个人在其中进行项目。也就是说,我绝不是经验丰富的软件架构师。有没有人尝试实现它?您遇到了哪些好处和障碍?

7
我可以暂时使用GPL库进行原型制作,并使以后的代码封闭源吗?
我正在开发一个软件系统的原型,该原型(至少在开始时)将是封闭源代码。 为了节省时间,我正在考虑使用(即静态链接)在GPLv3下获得许可的库,因此我可以快速测试设计。如果在此阶段分发软件,则必须随同分发源代码。 如果我不这样做,但是让自己确信我的系统可以运行,然后在分发之前用我自己的代码替换GPL库,该怎么办?结果会被GPL“污染”吗? 我感觉是否在我的Git历史记录中保留GPL库可能会有所作为。

3
服务层是否应该捕获所有dao异常并将其包装为服务异常?
我有三层Spring Web应用程序:dao,服务和控制器。控制器从不直接调用dao,而是通过服务层进行调用。现在,大多数情况下,如果存在未处理的dao异常(运行时),则JSP将捕获该异常,并向最终用户显示错误消息。服务层是否应该捕获所有dao异常并将其包装为服务异常? try { daoInstance.someDaoMethod(); } catch(DataAccessException dae) { throw new ServiceException("message", dae); } 假设ServiceException也是运行时,并且也未处理。仅抛出DataAccessException而不是ServiceException有什么区别吗?我只是以为表示层不应该知道数据访问异常。但是我不认为捕获不可恢复的异常只是为了包装它们。

2
具有在线功能的单元测试课程
当类的单元测试功能具有需要在线功能的私有功能时。人们将如何进行测试? 例如: public class Foo { public int methodA() { int val = goOnlineToGetVal(); return val; } private int goOnlineToGetVal() { CloudService c = new CloudService(); int oval = c.getValueFromService(); return oval; } } 如果我要测试功能:“ methodA()”,它将尝试使用“ goOnlineToGetVal()”,但是如果此测试在没有功能的情况下,它将尝试联机。不上网怎么办100%的课堂覆盖率?

4
为什么许多鸭子式动态编程语言会使用基于类的方法而不是基于原型的OOP?
由于许多动态编程语言都具有鸭类输入法的功能,并且它们还可以随时打开和修改类或实例方法(例如Ruby和Python),因此…… 问题1)动态语言课程的需求是什么?为什么要用这种方式设计语言,以将类用作某种“模板”,而不是以原型方式使用而只是使用对象? 另外的JavaScript是原型为基础,但CoffeeScript的(JavaScript的加强版),选择基于类的方式。它也适用于相同的Lua(原型为基础)和MoonScript(类为主)。此外,ES 6中还有一门课。所以…… 问题2)是否暗示着,如果您尝试改进基于原型的语言,则应将其更改为基于类的语言?如果没有,为什么要这样设计?

6
在TDD中,我必须首先编写“测试”还是“接口”?
我正在使用c#学习TDD,据我所知测试应该驱动开发,即在编写最基本的代码以通过测试之后再进行重构,然后首先编写一个失败的测试。 但是也有人说“ 程序到接口,而不是实现 ”,因此请首先编写一个接口。这是我开始困惑的地方,如果我先写接口,那将违反两件事 为接口编写的代码不受test的驱动。 这显然不是最低要求,我可以用一个简单的类编写它。 我也应该从编写接口测试开始吗?没有任何实现,我要测试什么? 如果这个问题听起来很傻,对此我感到非常困惑。可能是我从字面上讲。
23 c#  unit-testing  tdd 

2
DDD聚合序列化的最佳做法
根据DDD,域逻辑不应被序列化,对象关系映射等技术问题所污染。 那么,如何在不通过getter和setter公开公开状态的情况下序列化或映射聚合状态?我已经看到了很多示例,例如存储库实现,但是实际上所有示例都依赖于实体上的公共访问器和用于映射的值对象。 我们可以使用反射来避免公共访问器,但是IMO这些域对象仍将隐式依赖于序列化问题。例如,在不调整序列化/映射配置的情况下,您无法重命名或删除私有字段。因此,您必须考虑序列化,而应将重点放在域逻辑上。 那么,要遵循的最佳妥协是什么?与公共访问器一起生活,但要避免将它们用于映射代码以外的其他用途?还是我只是想念一些明显的东西? 我对序列化DDD域对象(由实体和值对象组成的聚合)的状态特别感兴趣。这与无状态服务在简单数据容器对象上运行的常规脚本或事务脚本场景中的序列化无关。

2
数据验证的设计模式
解决此问题的最佳设计模式是什么: 我有一个对象A。可以根据用户请求在数据库中注册或删除对象A。 在注册或删除对象之前执行数据验证。在注册对象之前,有一组规则需要检查,而另一组规则则是删除。这些规则中的一些对于这两种操作都是通用的。 到目前为止,我认为“ 责任链”设计模式最合适,但我在实施它时遇到了麻烦。

4
npm中的可选依赖项?
我对此有类似的问题,但不完全相同。 我想让我的应用程序用户以其想要使用它的方式安装所需的任何依赖项。因此,例如,如果他们要保留到MongoDB,则仅安装与Mongo相关的库,但是如果他们要保留到Redis,则仅安装与Redis相关的库。我不想让他们下载并安装他们不会使用的库。 我知道我可以使用进行开发devDependencies,但这远不止于此。就像以上问题的答案所说,这与Python setuptools extras_require和Clojure的leiningen配置文件更紧密相关。在npm中有类似的内容吗?我真的觉得devDependencies应该是dev一种更加广泛的指定依赖项的方式。

6
多线程:我做错了吗?
我正在开发一个播放音乐的应用程序。 在回放期间,通常情况需要在单独的线程上发生,因为它们需要同时发生。例如,一个和弦需要的音符一起被听到,所以每个人都分配了其自己的线程中进行播放(编辑澄清:调用note.play()冻结线程,直到音符播放完毕,这就是为什么我需要三个独立线程以同时听到三个音符。) 这种行为在播放音乐时会创建许多线程。 例如,考虑一段音乐,该音乐具有短旋律和较短的伴随和弦进行。整个旋律可以在单个线程上弹奏,但是该进程需要三个线程才能弹奏,因为其每个和弦都包含三个音符。 因此,用于播放进度的伪代码如下所示: void playProgression(Progression prog){ for(Chord chord : prog) for(Note note : chord) runOnNewThread( func(){ note.play(); } ); } 因此,假设进程有4个和弦,并且我们演奏了两次,则我们打开3 notes * 4 chords * 2 times= 24个线程。这只是播放一次。 实际上,它在实践中效果很好。我没有注意到任何明显的延迟或由此导致的错误。 但是我想问一下这是正确的做法,还是我做的事情根本上是错误的。每次用户按下按钮时创建这么多线程是否合理?如果没有,我该怎么做?

4
这种简单的XOR加密通信绝对安全吗?
说爱丽丝和彼得每个人都有一个4GB的USB闪存棒。它们相遇并保存在两个记忆棒上,两个文件名为alice_to_peter.key(2GB)和peter_to_alice.key(2GB),其中包含随机生成的位。他们再也见不到面,而是通过电子方式进行交流。爱丽丝还维护一个名为的变量,alice_pointer而彼得维护一个名为的变量peter_pointer,这两个变量最初都设置为零。 当爱丽丝需要向彼得发送消息时,她会这样做(n消息的第n个字节在哪里): encrypted_message_to_peter[n] = message_to_peter[n] XOR alice_to_peter.key[alice_pointer + n] encrypted_payload_to_peter = alice_pointer + encrypted_message_to_peter alice_pointer += length(encrypted_message_to_peter) (为了获得最大的安全性,可以删除密钥的使用部分) 彼得接收encrypted_payload_to_peter,读取alice_pointer存储在消息开头的内容,然后执行以下操作: message_to_peter[n] = encrypted_message_to_peter[n] XOR alice_to_peter.key[alice_pointer + n] 为了获得最大的安全性,在读取消息后还要擦除密钥的已用部分。 编辑:实际上,使用此简单算法(无完整性检查和身份验证)的这一步骤会降低安全性,请参阅下面的PaŭloEbermann帖子。 当彼得需要向爱丽丝发送消息时,他们用peter_to_alice.key和进行相反的操作peter_pointer。 通过这种简单的模式,他们可以在未来50年中每天在两个方向上发送2GB /(50 * 365)=〜115kB的加密数据。如果他们需要发送更多的数据,则可以使用更大的密钥,例如,使用当今的2TB HD(1TB密钥),则可以在未来50年内每天交换60MB!实践中有很多数据。例如,使用压缩技术可以进行一个多小时的高质量语音通信。 在我看来,攻击者无法在没有密钥的情况下读取加密的消息,因为即使他们拥有一台速度非常快的计算机,用蛮力他们也可以在限制之下获取所有可能的消息,但这是一个天文数字消息,攻击者不知道是实际消息。 我对吗?这个通信方案真的绝对安全吗?如果它是安全的,它是否有自己的名称?XOR加密是众所周知的,但是我正在使用两侧都使用大密钥来寻找这个具体的实际应用程序的名称吗?我很期待这个应用程序是我之前发明的。:-) 注意:如果绝对安全,那就太神奇了,因为使用当今低成本的大型存储设备,进行安全通信要比使用昂贵的量子密码学便宜得多,并且具有同等的安全性! 编辑: 随着存储成本的降低,我认为这在将来会更加实用。它可以永远解决安全通信。今天,您不确定是否有人会在一年后成功地攻击现有密码,并使通常昂贵的实现变得不安全。在沟通发生之前的许多情况下,当双方亲自见面时,就该生成密钥了。我认为这非常适合军事通信,例如,潜艇之间可以具有带有大钥匙的HD,而军事中心可以为每个潜艇配备HD。在日常生活中也很实用,例如控制您的银行帐户,因为创建帐户时会遇到银行等。

8
确保函数永远不会两次返回相同的值[关闭]
已关闭。这个问题需要更加集中。它当前不接受答案。 想改善这个问题吗?更新问题,使其仅通过编辑此帖子来关注一个问题。 5年前关闭。 这是我在求职面试中被问到的一个问题,我无法弄清楚他们正在寻找的答案,所以我希望这里的人可能有一些想法。目的是编写一个保证永远不会两次返回相同值的函数。假设该功能将被多台机器同时访问。 我的想法是为每台机器分配一个唯一的ID,并将该值传递到唯一的值生成器函数中: var i = 0; function uniq(process_id, machine_id) { return (i += 1).toString() + machine_id + "-" + process_id; } 这将避免竞争条件带来的影响,因为即使两个或多个进程读取的相同值i,每个返回值都被标记为进程ID和计算机ID的唯一组合。但是,我的面试官不喜欢这个答案,因为使另一台计算机联机需要为其分配ID。 因此,有人能想到另一种解决此问题的方法,而不涉及将每台机器配置为具有唯一的ID吗?如果这个问题再次出现,我想得到一个答案。谢谢。

2
Mozilla公共许可证(MPL 2.0)与较小的GNU通用公共许可证(LGPL 3.0)
我想在基于Web的源代码托管服务上发布用基于类,面向对象的编程语言(Java)编写的软件库,该软件库允许将项目的分支合并到主项目(通过pull 合并到 GitHub中)要求)。我已经在网络上进行了研究,并对如何许可该软件给予了很多思考。在以下假设中(从IANAL角度来看)我是否正确? LGPL和MPL都促进共享对在其他软件项目中使用的LGPL / MPL许可软件的修改。我可以不要求修改后的库的用户托管库的单独分支,而可以促进对原始库的贡献(例如,通过拉取请求)。 主要区别在于必须如何将MPL / LGPL许可代码链接到项目中。MPL源代码文件可以直接复制到(可能是)专有软件项目(静态链接)中,而LGPL许可代码必须动态链接(宽松地链接到可能是专有软件项目的链接),以便最终用户可以切换出许可软件许可软件库的另一个版本的库)。 动态链接(因此LGPL)在打包专有软件产品时增加了额外的障碍,而不是通过静态链接(以及MPL)来促进对开源软件库的更多贡献。有一个修改LGPL允许静态链接。 还有没有其他相关的差异(从IANAL角度)。 在旧的许可证版本不适合我的需要不如最新的。 如您所见,我的主要要求是对软件库的修改(可能对公众有用)保持开放源代码,而不会限制在专有产品中使用软件库。 没有许可证还要求将与原始作品相关的软件库扩展作为开源发布,因为相关术语的范围可以很小/很大,因此最终不能作为GPL用于专有产品(不发布全部源代码)。 我很想使用修改后的LPGL,但是另一方面,它不受欢迎。基于以上几点,我更喜欢MPL。 问题:我的上述说法正确吗?考虑到我的要求,我应该选择哪个许可证? 解决方案:在受欢迎的讨论中,我选择坚持使用MPL是因为它受欢迎,链接自由并且它是未经修改的正式许可。

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.