软件工程

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

4
为什么将MySQL用于字典网站是个坏主意?
我打算设计和建立一个数据库,以存储词典条目(通常是单个单词)及其在另一种语言中的含义。因此,例如,表Glossary必须具有条目和定义,并且每个表记录都具有对存储在其中的记录的ID的引用Tag(每个条目必须具有标签或类别)。 由于我的数据具有结构,因此我认为使用SQL数据库(如MySQL)并不是一个坏主意;但是人们说MongoDB的性能要好得多。 在客户端,应用程序必须能够提供一个具有自动完成功能的搜索框,该框使用后端提供的REST API。在这种情况下使用MySQL是否安全?还是应该为此使用MongoDB或任何其他解决方案的ElasticSearch?应该以这种方式存储和访问数十万条记录。

9
重构前如何编写单元测试?
我已经阅读了类似问题的一些答案,例如“重构时如何保持单元测试正常工作?”。就我而言,情况略有不同,因为我得到了一个项目进行审查并符合我们已有的一些标准,目前该项目根本没有测试! 我已经确定了许多我认为可以做得更好的事情,例如不要在服务层中混合DAO类型的代码。 在重构之前,为现有代码编写测试似乎是一个好主意。在我看来,问题是当我进行重构时,这些测试将随着我改变执行某些逻辑的位置而中断,并且这些测试将牢记先前的结构(模拟的依赖关系等)编写。 就我而言,最好的前进方法是什么?我很想围绕重构的代码编写测试,但是我知道我可能会错误地重构事物,从而可能改变期望的行为。 无论是重构还是重新设计,我都很高兴能理解要更正的术语,目前我正在为重构进行以下定义:“按照定义,重构不会改变软件的功能,您将更改其操作方式。”。因此,我不会更改软件的功能,而是会更改软件的方式/位置。 同样,我可以看到这样一种论点,即如果我更改了可以视为重新设计的方法的签名。 这是一个简单的例子 MyDocumentService.java (当前) public class MyDocumentService { ... public List<Document> findAllDocuments() { DataResultSet rs = documentDAO.findAllDocuments(); List<Document> documents = new ArrayList<>(); for(DataObject do: rs.getRows()) { //get row data create new document add it to //documents list } return documents; } } MyDocumentService.java (无论如何都经过重构/重新设计) public …

6
如果getter对象的状态无效,是否应该抛出异常?
我经常遇到这个问题,特别是在Java中,即使我认为这是一个普遍的OOP问题。即:引发异常会揭示设计问题。 假设我有一个包含一个String name字段和一个String surname字段的类。 然后,它使用这些字段来组成一个人的全名,以便将其显示在某种文件上,例如发票。 public void String name; public void String surname; public String getCompleteName() {return name + " " + surname;} public void displayCompleteNameOnInvoice() { String completeName = getCompleteName(); //do something with it.... } 现在,我想通过displayCompleteNameOnInvoice在分配名称之前调用引发错误来增强类的行为。似乎是个好主意,不是吗? 我可以在getCompleteName方法中添加引发异常的代码。但是以这种方式,我违反了与类用户的“隐式”合同。通常,如果未设置获取方法的值,则不应将其抛出异常。好的,这不是标准的获取方法,因为它不会返回单个字段,但是从用户的角度来看,区分可能太微妙了,无法考虑它。 或者,我可以从中抛出异常displayCompleteNameOnInvoice。但是,这样做我应该直接测试name或surname字段,这样做会违反表示的抽象getCompleteName。检查并创建完整名称是此方法的责任。根据其他数据,它甚至可以决定在某些情况下足够了surname。 因此,唯一的可能性似乎是将方法的语义更改getCompleteName为composeCompleteName,这表明行为更“活跃”,并且具有抛出异常的能力。 这是更好的设计解决方案吗?我一直在寻找简单性和正确性之间的最佳平衡。有针对此问题的设计参考吗?

12
为什么程序需要特定数量的最小CPU内核?
当在内核数少于N的CPU上运行时,是否可以编写无法正常工作的代码(或完整的软件,而不是一段代码)?没有显式检查并故意失败: 如果(noOfCores <4)则没有故意运行 我正在查看游戏的最低系统要求(Dragon Age:Inquisition),它规定了至少四核CPU。许多玩家表示,它不能在两核CPU上运行,甚至不能在具有两个物理核和两个逻辑核的Intel Core i3上运行。而且这不是计算能力的问题。 据我了解,操作系统无法将线程与CPU完全隔离开来。 只是为了清除事情: 我不是在问:“我可以从代码中找出CPU内核的数量,并故意失败吗?” ...这样的代码是不正确的(迫使您购买更昂贵的CPU来运行程序-无需计算能力)。我要问的是,您的代码具有四个线程,并且当两个线程在同一物理核心上运行时会失败(而无需显式检查系统信息并有意地失败)。 简而言之,是否可以有需要多个核的软件,而又不需要来自多个核的额外计算能力?它仅需要N个单独的物理核心。

5
“无上下文语法”在术语“无上下文语法”中是什么意思?
鉴于试图解释什么是上下文无关文法(CFG)的材料数量众多,我发现令人惊讶的是,很少有人(在我的示例中,少于20个样本中有1份)对为何将这种语法称为“上下文文法”进行了解释。自由”。而且,在我看来,没有人能成功做到这一点。 我的问题是,为什么无上下文语法称为无上下文语法?什么是“上下文”?我有一种直觉,即上下文可以是围绕当前分析的构造的其他语言构造,但事实并非如此。谁能提供准确的解释?

6
事件循环是否只是具有优化轮询的for / while循环?
我试图了解什么是事件循环。通常的解释是,在事件循环中,您会做一些事情,直到收到事件发生的通知。然后,您可以处理事件并继续做之前的工作。 用示例映射以上定义。我有一台在事件循环中“侦听”的服务器,当检测到套接字连接时,将读取并显示其中的数据,此后服务器将像以前一样继续/开始监听。 但是,此事件正在发生,而我们收到的通知“就像那样”对我来说就很大了。您可以说:“注册事件侦听器不只是那样而已”。但是什么是事件侦听器,但由于某种原因没有返回的函数。它是否在自己的循环中,等待事件发生时得到通知?事件监听器是否还应该注册一个事件监听器?它在哪里结束? 事件是可以使用的很好的抽象,但是仅仅是一个抽象。我认为,最后不可避免地要进行投票。也许我们没有在代码中执行此操作,但是较低级别(编程语言实现或OS)正在为我们执行此操作。 它基本上可以归结为以下伪代码,这些伪代码在足够低的位置运行,因此不会导致繁忙的等待: while(True): do stuff check if event has happened (poll) do other stuff 这是我对整个想法的理解,我想听听这是否正确。我乐于接受整个想法从根本上是错误的,在这种情况下,我希望有正确的解释。

12
通过代码审查调和童子军规则和机会主义重构
我坚信童子军规则: 始终要比在检出时检查模块中的清洁剂。”不管原始作者是谁,如果我们总是花点力气,不管大小如何,以改进模块。结果是什么?我想所有人都遵循这个简单的规则,我们将会看到软件系统不断恶化的终结,相反,随着系统的发展,我们的系统将逐渐变得越来越好。我们还将看到团队关心整个系统,而不是整个系统。不仅仅是个人照顾自己的一小部分。 我也是机会重构相关思想的坚定信奉者: 尽管在某些地方可以进行一些计划内的重构工作,但我还是鼓励将重构作为一种机会主义活动,它需要在任何时候,任何地方需要清理代码的人(无论谁)进行。这意味着在任何时候,只要有人看到一些不尽如人意的代码,他们都应趁此机会立即将其修复,或者至少在几分钟内 特别注意以下来自重构文章的摘录: 我对任何可能导致机会重构产生冲突的开发实践都保持警惕。我的感觉是,大多数团队都没有进行足够的重构,因此,请注意任何阻碍人们进行重构的事情,这一点很重要。为了避免这种情况的发生,请注意任何时候您都不愿意进行小规模的重构,您肯定只需要一两分钟。任何此类障碍都是应该引起对话的气味。因此,请记下该挫折并与团队联系。至少应该在下一次回顾中讨论它。 在我工作的地方,有一种开发实践会引起严重的摩擦-代码审查(CR)。每当我更改不在“任务”范围内的任何内容时,我的审核员都会对我感到bu异,因为我正在使更改难以审核。当涉及到重构时,尤其如此,因为这使得“逐行”差异比较变得困难。这种方法是这里的标准,这意味着很少进行机会性重构,并且只会进行“计划的”重构(通常太少,太晚)。 我声称这样做的好处是值得的,并且3名审阅者会更加努力(实际上要前后理解代码,而不是仅仅关注变更范围的狭窄范围,因此,审阅本身会更好一些) ),以便接下来的100个阅读和维护代码的开发人员将受益。当我向审阅者提出这个论点时,他们说只要我不在同一CR中,他们的重构就不会有问题。但是我声称这是一个神话: (1)大多数时候,您只有在从事作业时才意识到要重构的内容和方式。正如马丁·福勒(Martin Fowler)所说: 在添加功能时,您意识到要添加的某些代码与某些现有代码包含某些重复项,因此您需要重构现有代码以清理问题……您可能会工作,但意识到如果更改了与现有类的交互,则更好。在您认为自己已完成之前,抓住这个机会。 (2)没有人会喜欢您发布您不应该做的“重构” CR。CR有一定的开销,您的经理不希望您在重构上“浪费时间”。当它与您应做的更改捆绑在一起时,此问题被最小化。 Resharper加剧了这个问题,因为我添加到更改中的每个新文件(而且我事先无法确切知道哪些文件最终会更改),通常充满错误和建议-其中大多数都是应有的且应有的定影。 最终结果是我看到了可怕的代码,然后就把它留在那里了。具有讽刺意味的是,我觉得修复这样的代码不仅不会提高我的声誉,而且实际上降低了我的声誉,并将我描绘成一个“无专心的”家伙,他浪费时间去修复那些没人关心的事情而不是去干他的工作。我对此感到难过,因为我确实鄙视错误的代码,无法忍受观看,更不用说从我的方法中调用它了! 关于如何纠正这种情况有什么想法?


10
这是什么意思?“用户不应该决定它是否是管理员。特权或安全系统应如此。”
问题中使用的示例将最少的数据传递给函数,以确定是否用户是管理员的最佳方法。一个常见的答案是: user.isAdmin() 这引起了评论,该评论被重复了多次并被多次投票: 用户不应该确定它是否是管理员。特权或安全系统应该。与课程紧密联系并不意味着将其纳入课程是一个好主意。 我回答, 用户没有决定什么。用户对象/表存储有关每个用户的数据。实际用户不会改变自己的一切。 但这没有效果。显然,存在潜在的视角差异,这导致沟通困难。有人可以向我解释为什么user.isAdmin()不好,并绘制一个简短的草图来“完成”吗? 确实,我看不到将安全与受保护系统分开的优势。任何安全性文字都将要求从一开始就将安全性设计到系统中,并在开发,部署,维护乃至报废的每个阶段都要加以考虑。它不是可以固定在侧面的东西。但到目前为止,此评论有17票赞成票,表明我错过了一些重要的内容。

6
错误重新打开与新
错误已被打开,修复,验证和关闭。一个月后,它经过几次迭代,没有任何回归,再次出现在后续版本中。 如果错误特征相同,您将重新打开现有的错误ID还是使用链接到已关闭错误的链接打开一个新 ID ?

3
递归和核心递归之间有什么区别?
这些有什么区别? 递归 核心递归 在Wikipedia上,几乎没有信息,也没有清晰的代码来解释这些术语。 有哪些非常简单的示例可以解释这些术语? corecursion如何实现递归的对偶? 有没有经典的corecusive算法?

5
程序员的有声读物?[关闭]
我是一名程序员,每天有两个小时的往返路程。我想在这段时间里写一些有关软件开发的有声读物。任何能帮助我成为更好的程序员的有声读物将不胜感激。我认为有关设计模式的书籍和有关计算历史的非小说类书籍在这里可能不错,但我乐于接受。 请记住,我将在汽车中聆听,我能听的最好的有声读物是什么? 编辑:许多人还建议播客。这是可以理解的,但是由于播客到达的是不断到达的数据流,而不是有限数量的数据,所以也应理解杂耍所有这些不同内容流的方法。 更具体地讲,我的通勤车有一个MP3 CD播放器,一个用于MP3文件的USB输入和一个AUX输入。我拥有可以插入AUX输入的Android和webOS设备。
55 books 

8
为什么要打扰正确地和语义地标记?
请注意,我(尝试)尽可能地在语义上进行标记,因为我喜欢它们的外观和感觉,但不是因为我意识到任何其他惊人的优点。我的问题的重点是能够教育他人 好吧,我看过很多文章和教程,这些文章和教程经常说“让我们以最可能的语义方式进行标记”。 但是我想到了一个奇怪的想法,为什么? 为什么一个人需要(或想要)去打扰那些传达正确语义的特定元素?具体地讲,我指的是新的HTML5元素,如<time>,<output>,或<address>。特别是,如果页面“有效”(在所有浏览器中都能很好地呈现)。 为什么我要使用诸如<time>或元素<address>,而根本没有任何元素(或在最坏的情况下,泛型<span>)表现得那么好呢? 我之所以这样问,是因为我看到许多(非常受欢迎的)网站(包括此网站)没有遵循这些所谓的最佳实践。
55 html  html5  semantics  markup 



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.