软件工程

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

4
编译器如何从类型错误中恢复?
我已经阅读了几篇论文,文章和《编译器:原理,技巧和工具(第二版)》(第2版)(又称“龙书”)第4章第4.1.4节,它们都讨论了语法编译器错误恢复的主题。但是,在尝试了几种现代编译器之后,我发现它们还可以从语义错误以及语法错误中恢复。 我非常了解编译器从句法相关的错误中恢复的算法和技术,但是我并不完全理解编译器如何从语义错误中恢复。 我目前使用的访问者模式略有变化,以从我的抽象语法树生成代码。考虑我的编译器编译以下表达式: 1 / (2 * (3 + "4")) 编译器将生成以下抽象语法树: op(/) | ------- / \ int(1) op(*) | ------- / \ int(2) op(+) | ------- / \ int(3) str(4) 然后,代码生成阶段将使用访问者模式来递归地遍历抽象语法树并执行类型检查。将遍历抽象语法树,直到编译器到达表达式的最内层为止。(3 + "4")。然后,编译器会检查表达式的每一面,并发现它们在语义上不相等。编译器引发类型错误。这就是问题所在。编译器现在应该做什么? 为了使编译器能够从此错误中恢复并继续对表达式的外部部分进行类型检查,它必须从评估表达式的最内部部分到表达式的下一个内部部分返回某种类型(int或str)。但是它根本没有返回的类型。由于发生类型错误,因此没有推断出任何类型。 我提出的一种可能的解决方案是,如果确实发生类型错误,则应该引发错误,并且应该将一个特殊值(表示发生类型错误)返回给以前的抽象语法树遍历调用。如果先前的遍历调用遇到此值,则他们知道在抽象语法树中更深处发生类型错误,因此应避免尝试推断类型。尽管此方法确实有效,但效率似乎很低。如果表达式的最内层部分位于抽象语法树的深处,则编译器将不得不进行许多递归调用,而仅是意识到无法完成任何实际工作,而只需从每个返回即可。 我是否使用了上述方法(我对此表示怀疑)。如果是这样,效率不高吗?如果不是,那么编译器从语义错误中恢复时将使用什么方法?

4
当您无法添加唯一索引时,有哪些可能的方法来避免重复
我陷入了并发问题。 用户发送2 o 3事务来保留某些不应在数据库中重复的数据是一个典型的问题,如果有重复的记录,您应该返回一个错误。 当您仅可以向存储哈希的列添加索引(唯一)时,此问题就很容易。 但是在这种情况下,我有一个巨大的表(可能有数百万条记录),而我不能只修改该表。 实际上,我们有一列存储数据的散列,该散列不应重复但未设置唯一索引。 我正在尝试在我的Java代码上检查是否在刷新之前存在,仍然会重复。 我对此可能的解决方案是: 创建一个触发器,以检查我要插入的哈希表上是否已经存在。 创建另一个表来存储该表的唯一索引,并将外键添加到主表。 坐在胎位上哭

2
如何设计总体边界?
我想编写一个类似电子商务的应用程序。 您知道,在类似的应用程序中,产品可能具有不同的属性和功能。为了模拟这种机会,我创建了以下域模型实体: 类别 -这类似于“电子产品>计算机”,即产品类型。分类包含属性列表(List <属性>)。 属性 -包含名称,度量单位,数据类型的独立实体。例如“名称”,“重量”,“屏幕尺寸”。同一属性可以具有不同的产品。 产品 -仅包含名称和与属性有关的值列表。值是一个仅包含值字段和属性的字段ID的对象。 我最初决定在此方案中使Category像单个聚合一样,因为例如当我添加新产品时,我需要知道与当前类别有关的所有数据,包括与当前类别有关的属性(category.AddNewProduct(product))。但是,当我只需要添加不属于任何类别的新属性时该怎么办。例如,我不能执行此category.AddNewProperty(property),因为它明确表示我们将属性添加到特定类别。 好的,下一步我决定将Property划分为单独的聚合,但是它将是一个包含简单实体的列表。 当然,我可以创建诸如PropertyAggregate之类的内容以保留在属性和业务规则列表中,但是当我添加产品时,我需要在类别内具有属于该类别的属性的整个列表,以检查不变量。但是我也意识到,将链接内的链接保留在其他聚合上是一种不好的做法。 设计此业务案例有哪些选择?

2
无服务器架构如何管理数据库连接?
据说无服务器体系结构的主要优点是,此类程序不需要专用服务器即可连续运行。然后在请求上被调用,并在退出函数时停止。 这意味着无服务器程序必须快速启动才能响应。然后,它如何处理耗时的操作,例如数据库连接?它是否每次都连接到数据库,还是单独管理数据库连接以像服务器应用程序中那样进行功能调用?

1
为什么Null-Safe运算符(例如“ Elvis运算符”)被Java 7的“项目代币”拒绝?
Java 7的“项目硬币”的建议功能之一是“猫王运算符”。一个2009年的JavaOne大会上演示的报告对项目硬币将其形容为这样的: 本演示文稿介绍的“小功能”之一是所谓的“猫王运算符”,这是三元运算符的更简洁版本。我发现自己在使用传统Java时缺少了Groovy的某些功能,如果添加了它,这将是我可以同时使用两种语言的一种运算符。“ Elvis”运算符可方便地指定默认值,该默认值可在评估表达式为null时使用。像Groovy的安全导航运算符一样,这​​是一种指定如何避免不必要的null的简洁方法。我以前在博客中写过关于如何避免NullPointerException的博文。 尽管最终实现了Project Coin的其他方面,但这一方面并未实现。尽管猫王运算符在JavaOne上被提出可能被纳入,但为什么最终还是被拒绝了? 明确地说,我要特别询问该运算符,以及它被拒绝作为Java 7“ Project Coin”的一部分的原因,因为当时已对其进行了认真考虑。我怀疑在讨论了拒绝邮件的原因的邮件列表或此类邮件列表,但找不到任何东西。如果有更多关于为什么它不包含在Java的任何版本中的一般信息,则可以接受,但不是首选。
10 java  api-design 

5
如何解决我的C ++代码中的类相互依赖性?
在我的C ++项目中,我有两个类,Particle和Contact。在Particle该类中,我有一个成员变量std::vector<Contact> contacts,其中包含Particle对象的所有触点以及相应的成员函数getContacts()和addContact(Contact cont)。因此,在“ Particle.h”中,我包括“ Contact.h”。 在Contact该类中,我想将代码添加到构造函数中Contact,以调用Particle::addContact(Contact cont),以便contacts针对Particle在其间Contact添加对象的两个对象进行更新。因此,我必须在“ Contact.cpp”中包含“ Particle.h”。 我的问题是这是否可接受/良好的编码习惯,如果不能,那么哪种更好的方式来实现我要实现的目标(简单地说,每当有新联系人时,自动更新特定粒子的联系人列表)被建造)。 这些类别将由Network具有N个粒子(std::vector<Particle> particles)和Nc个接触(std::vector<Contact> contacts)的类别联系在一起。但是我希望能够拥有类似的功能particles[0].getContacts()– Particle在这种情况下可以在类中使用这样的功能,还是为此目的在C ++中有更好的关联“结构”(在另一个类中使用两个相关类) 。 在此方面,我可能需要转变看法。由于这两个类是由一个Network类对象连接的,因此典型的代码/类组织是具有完全由该Network对象控制的连接信息(因为Particle对象不应知道其联系,因此,它不应具有getContacts()成员)功能)。然后,为了知道特定粒子具有什么接触,我将需要通过Network对象(例如使用network.getContacts(Particle particle))获得该信息。 具有粒子粒子知识的C ++类设计是否也不太典型(也许甚至不鼓励),也就是(具有通过网络对象或粒子粒子访问信息的多种方式),无论哪种方式看起来更方便)?

5
违反LSP可以吗?
我正在跟进这个问题,但是我将重点从代码转换为原则。 根据我对Liskov替换原理(LSP)的理解,无论我的基类中有什么方法,它们都必须在我的子类中实现,并且根据此页面,如果您在基类中重写了一个方法,则它什么也不做或抛出一个错误。例外,您违反了该原则。 现在,我的问题可以这样总结:我有一个abstract Weapon class,两个类,Sword和Reloadable。如果Reloadable包含一个特定的method,称为Reload(),我将不得不向下访问以访问该method,并且理想情况下,您希望避免这种情况。 然后,我想到了使用Strategy Pattern。这样,每把武器都只知道它能够执行的动作,因此,例如,一种Reloadable武器显然可以重新装弹,但是Sword不能,甚至不知道Reload class/method。正如我在Stack Overflow帖子中所说的那样,我不必沮丧,也可以维护List<Weapon>收藏集。 在另一个论坛上,第一个答案建议让其Sword意识到Reload,只是什么也不要做。我在上面链接到的“堆栈溢出”页面上也给出了相同的答案。 我不完全明白为什么。为什么要违反该原则并让Sword知道Reload并保留为空?正如我在Stack Overflow帖子中所说,SP几乎解决了我的问题。 为什么它不是可行的解决方案? public final Weapon{ private final String name; private final int damage; private final List<AttackStrategy> validactions; private final List<Actions> standardActions; private Weapon(String name, int damage, List<AttackStrategy> standardActions, List<Actions> attacks) { this.name = name; this.damage = damage; standardActions = …

1
避免依赖版本冲突?
几乎可以肯定,使用我的jar的任何Java项目都将对另一个jar附加依赖,我的jar也将其作为依赖项。 问题是,其他jar有多个版本。 在您项目的第二个jar版本与第二个jar版本不同的情况下,如何避免出现任何问题? 我不希望我的用户有多余的麻烦来做一些花哨的类加载技巧来添加我的jar。 我是否应该为该通用依赖项的每个可能版本制作一堆不同版本的jar?然后,您只需选择使用与您刚碰到的第二个jar版本相同的jar版本即可? 有没有更聪明的方式来处理此问题,并使人们更轻松地使用我的jar,而不会发生冲突?

1
难以掌握现实生活中的干净代码
我目前正在阅读和阅读Robert C. Martin撰写的“清洁代码:敏捷软件工艺手册”。作者讨论了一个函数应该如何仅做一件事情,因此比较简短。马丁特别写道: 这意味着if语句,else语句,while语句等中的块应为一行。该行可能是函数调用。这不仅使封闭函数保持较小状态,而且还增加了文档价值,因为在块中调用的函数可以具有很好的描述性名称。 这也意味着函数不应足够大以容纳嵌套结构。因此,函数的缩进级别不应大于一或两个。当然,这使功能更易于阅读和理解 这是有道理的,但似乎与我认为干净的代码示例存在冲突。以以下方法为例: public static boolean millerRabinPrimeTest(final int n) { final int nMinus1 = n - 1; final int s = Integer.numberOfTrailingZeros(nMinus1); final int r = nMinus1 >> s; //r must be odd, it is not checked here int t = 1; if (n >= 2047) { …
10 clean-code 

7
为什么要为内部应用程序开发内部库?
我很难理解为什么您应该开发内部库以专门用于开发内部应用程序。我很感激,如果我想使用组织外部某人编写的软件,那么他们可以向我发送其头文件以及.a或.so文件,并且我可以将其链接到我的项目(假设它们在同一环境中编译) 。 但是,为什么当我可以访问头文件和实现文件并将它们仅包含在我的源代码树中并一起编译时,为什么要开发一个内部库以链接到内部应用程序呢? 换句话说:如果编写了一些源代码,您如何决定应将其编译为二进制库并链接到您的应用程序,还是仅将其包含在项目的源文件中并定期进行编译? 当我在每个项目中说“包含”文件时,并不是要复制每个文件并将其粘贴到当前正在开发的项目的源代码树中。我的意思是开发一些包含公共源代码的目录/库(与任何项目分开),这些源代码可以以通常的方式包含在项目文件中,即#include。 ps我在这里谈论的是针对多个桌面应用程序的c / c ++开发。
10 libraries 

4
在错误消息中包括指向相关文档的链接?
我们创建了一个供外部开发人员使用的商业库和代码示例。我们有(封闭的,可供注册用户使用)文档,其中广泛解释了如何使用该库。 许多开发人员是首次使用,因此会遇到很多基本错误。 在错误日志中包含指向文档的链接是否合适?可能的不利之处是什么?我可以预见一些,但似乎有可能克服以下问题 文档URL已过期 最新文档中未反映的特定于版本的错误 还有其他问题,我们通过将开发人员发送给无关的文档来浪费开发人员的时间 在我的意思示例下面,添加粗体字是个好主意吗? [错误]无法在独立项目上执行目标org.apache.maven.plugins:maven-archetype-plugin:1.2.3:generate(default-cli):所需的原型不存在(com.example.library。 archetypes:library-archetype-blank:1.2.3.0)->请参阅http://example.com/docs/setting-up-an-archetype了解更多信息和可能的故障排除


4
重做一个返回代表许多不同状态的整数代码的函数
我继承了一些糟糕的代码,其中包括以下简短示例。 这个特殊的反模式有名称吗? 有哪些重构建议? // 0=Need to log in / present username and password // 2=Already logged in // 3=Inactive User found // 4=Valid User found-establish their session // 5=Valid User found with password change needed-establish their session // 6=Invalid User based on app login // 7=Invalid User based on network …

2
解决二元函数assertEquals(预期的,实际的)带来的问题
经过多年的牛仔编码,我决定拿起一本有关如何编写高质量代码的书。我正在阅读Robert Cecil Martin撰写的Clean Code。在第3章(函数)中,有关于二进位函数的部分。这是这本书的摘录。 甚至明显的二进位函数assertEquals(expected, actual)也有问题。您已将实际次数放置在预期的位置几次?这两个参数没有自然顺序。预期的实际排序是需要实践学习的惯例。 作者提出了一个令人信服的观点。我从事机器学习工作,并一直遇到这种情况。例如,sklearn库(可能是该领域中最常用的python库)中的所有度量标准函数都要求您注意输入的顺序。作为一个例子sklearn.metrics.homogeneity_score需要作为输入labels_true和labels_pred。该函数的作用不太相关,相关的是,如果您切换输入的顺序,则不会引发任何错误。实际上,切换输入等效于使用库中的另一个函数。 然而,这本书并没有继续提到诸如assertEquals。我想不出一种assertEquals针对上述功能的固定解决方案。有什么好的做法可以解决此问题?
10 functions 

3
接口隔离原则是否适用于具体方法?
由于接口隔离原则表明,不应强迫任何客户端依赖其不使用的方法,因此客户端不应为其接口方法实现空方法,否则应将此接口方法放入另一个接口。 但是具体方法呢?我应该分开不是每个客户都会使用的方法吗?考虑以下类别: public class Car{ .... public boolean isQualityPass(){ ... } public int getTax(){ ... } public int getCost(){ ... } } public class CarShop{ ... public int getCarPrice(int carId){ Car car=carList[carId]; int price=car.getTax() + car.getCost()... (some formula); return price; } } 在上面的代码中,CarShop根本不在Car中使用方法isQualityPass(),我应该将isQualityPass()分离到一个新类中: public class CheckCarQualityPass{ public boolean isQualityPass(Car car){ …

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.