软件工程

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

5
让所有开发人员进行代码审查
我是7-8个开发人员团队中的软件开发人员。我们已经进行了一段时间的代码审查,并且随着时间的推移,代码质量也有所提高。 但是我最近注意到,与其他开发人员相比,一些开发人员被要求进行更多的代码审查。恐怕是因为他们态度灵活。 在我看来,这不是应该执行代码审查的方式:所有团队都应对此负责,并且不应因为愿意接受更改而选择代码审查者。 您如何处理团队中的这个问题? 您是否建立了选择代码审查者的规则? 您认为代码审查者应该花时间进行(良好)代码审查而获得报酬吗?以及如何获得奖励? 感谢您的回答/想法。


3
使用静态类型检查来防止业务错误
我非常喜欢静态类型检查。它可以防止您犯以下愚蠢的错误: // java code Adult a = new Adult(); a.setAge("Roger"); //static type checker would complain a.setName(42); //and here too 但这并不能阻止您做出如下愚蠢的错误: Adult a = new Adult(); // obviously you've mixed up these fields, but type checker won't complain a.setAge(150); // nobody's ever lived this old a.setWeight(42); // a 42lb adult would …

4
您如何才能对只能修复的bug进行TDD测试?
这是一个示例:我的Web应用程序包含可拖动元素。拖动元素时,浏览器会生成“重影”。我想在拖动时删除“重影”,并为此测试编写了一个测试。 我的问题是,我最初不知道如何解决此错误,而编写测试的唯一方法是在修复它之后。 在诸如之类的简单函数中let sum = (a, b) => a - b,您可以在编写任何代码之前编写一个关于为什么sum(1, 2)不相等的测试3。 在我描述的情况下,我无法测试,因为我不知道验证是什么(我不知道断言应该是什么)。 所描述问题的解决方案是: let dataTransfer = e.dataTransfer let canvas = document.createElement('canvas'); canvas.style.opacity = '0'; canvas.style.position = 'absolute'; canvas.style.top = '-1000px'; dataTransfer.effectAllowed = 'none'; document.body.appendChild(canvas); dataTransfer.setDragImage(canvas, 0, 0); 我不知道这是解决方案。在网上找到解决方案后,我什至无法编写测试,因为我唯一可以知道它是否真正有效的方法就是将这段代码添加到我的代码库中,并通过浏览器进行验证是否达到预期的效果。测试必须在代码之后编写,这与TDD背道而驰。 TDD如何解决此问题?在代码之前编写测试是强制性还是可选的?

2
堆栈扩展LinkedList。是否违反了Liskov替代原则?
存在具有诸如add_first(),add_last(),add_after(),remove_first(),remove_last()和remove()之类的函数的LinkedList类。 现在有一个Stack类,提供了push(),pop(),peek()或top()等功能,并且为了实现这些方法,它扩展了LinkedList类方法。这是否违反了《里斯科夫替代原则》? 例如,考虑在add_after()情况下将节点添加到链接列表的第n个位置的情况。这可以在基类中完成,但不能在Stack类中完成。此处的后置条件是否已减弱,或者您是否修改add_after()方法以将其添加到堆栈顶部? 另外,如果不违反,这是不好的设计吗?以及如何使用LinkedList类实现Stack功能?

1
微服务应该是用户吗?
我们正在尝试确定授权微服务体系结构中用户的最佳方法,同时确保微服务的权限受到限制。我们的体系结构使用中央授权服务来处理JWT令牌的发行。 我们有以下要求: 应该限制​​用户执行某些角色。例如,用户只能创建/修改/读取他拥有的内容。 微服务应仅限于其所需的权限。例如,应该明确禁止只需要从另一个服务读取数据的微服务将数据写入该服务。 例如,假设我们有一个系统,用户可以在其中将图片上传到图像存储服务。我们有一个标记服务,可以自动标记带有位置的图片。用户只能CRUD他们自己的照片。标记服务可以从图像存储服务读取任何图像,但是不能修改/删除。 使用JWT令牌实现上述目标的好方法是什么?我们讨论过的一些解决方案是: 图像存储服务公开了2个API,一个在外部可用(给用户CRUD访问),另一个在内部可用(给内部只读访问)。似乎不灵活-如果另一项内部服务需要对所有图像进行读/写访问(例如,自动删除显式图像的访问),该怎么办? 我们在用户的JWT中设置了两个权限,一个权限是CRUD_OwnImages,另一个权限是READ_ForAnalysis。标记服务可以查看用户是否具有READ_ForAnalysis权限,如果有,则发出适当的请求。我们还有另一个微服务,用于检查用户是否具有CRUD_OwnImages以便对用户自己的映像执行CRUD操作。这使每个微服务都有责任确保用户受限于他需要的操作。图像存储无法用这种方法来限制每个微服务,因此它可能容易出错和出错。 我们给标签微服务自己的用户,并以READ_ForAnalysis作为权限。然后,当加标签服务从图像存储请求图像时,将授予它们访问这些图像的权限,但禁止对其进行修改。用户的用户仅具有CRUD_OwnImages权限,因此他只能从前端检索和访问其图像。如果另一个服务需要对所有数据使用CRUD,则可以给它CRUD_AllData或类似的名称。我们喜欢这种方法,因为每个服务现在都负责其自己的数据(而不是在多个服务之间重复该逻辑),但是如果该服务同时需要用户权限和微服务权限怎么办?我们可以安全地发送两个JWT令牌(用户的和微服务的)吗?有没有一种方法可以安全地组合权限并通过发送?例如 如果更下游(需要2或3个微服务)需要用户信息,则会使问题更加严重。我们是否只是假设将单个微服务限制在它们自己需要的动作上,而不是将其明确化,这取决于单个微服务?

3
如何使自动化测试流行?[关闭]
已关闭。这个问题是基于观点的。它当前不接受答案。 想改善这个问题吗?更新问题,以便通过编辑此帖子以事实和引用的形式回答。 2年前关闭。 我们的代码库已经增长了20年。我们大约有10位开发者+平方英尺与500kloc合作。不久前,我们的一个小团队(2个开发人员,一个来自sqa)开始着手进行自动化测试程序。目前,一次运行需要11小时,并且某种程度上是一项集成测试。我们正在努力解决这个问题,减少误报,并在此方面取得了良好的进展。但是细节并不重要。 一切正常,我们将继续对其进行改进。我们(小团队)非常喜欢。如果我们弄坏了东西,我们会在一天后而不是两个月后注意到sqa。此外,我们的经理(开发人员+平方英尺)也很喜欢这个想法。但是团队中的其他人只是忽略了测试结果。在他们看来,如果在签入后测试失败,这是测试的问题,而不是代码更改的问题,这只是我们的玩具项目。如果失败的测试是真正的错误,我们进行了几次讨论。大多数时候是这样。 我们不能也不想强制执行某些事情。我们如何证明自动化测试是一回事?

3
一个人应该如何管理多种语言的常量?
我遇到的情况是我在功能上支持多种语言的同一库。这些常量之间通常需要共享常量(例如,json字段名称键或错误代码)。 我目前这样做的方式是让代码定义每种语言的常量。 问题来自维护。如果添加新的错误代码,则需要在每个库中手动更新它。虽然这对几个人来说很好,但是如果我说要更新5个SDK,就变得很乏味。也有一个单一的真理来源真是太好了。 我已经考虑过某种类似config的文件,但是它需要包含在每个已部署的软件包中,这会增加我们的构建/发布过程的复杂性。 有没有更好的方法来处理在多种语言之间共享的常量的维护?
13 design  packages 

4
关于我的数据库日期数据类型讨论:有效吗?值得吗?还有其他人感觉到吗?
我花了很多时间在SO上回答SQL问题。我经常遇到这样的问题: SELECT * FROM person WHERE birthdate BETWEEN '01/01/2017' AND '01/03/2017' SELECT * FROM person WHERE birthdate BETWEEN '2017-01-01' AND '2017-03-01' SELECT * FROM person WHERE birthdate BETWEEN 'some string' AND 'other string' 即要么依赖给定参数从字符串到日期的隐式转换(错误),要么依赖数据库将x百万个数据库行值转换为字符串并进行字符串比较(更糟糕) 我偶尔会发表评论,尤其是如果这是一个非常有名的用户,他们编写了一个明智的答案,但是我认为,他们的数据类型确实应该少一些草率/字符串式输入 注释通常采用以下形式:如果他们使用to_date(Oracle),str_to_date(MySQL),convert(SQLSERVER)或类似的机制将字符串显式转换为日期,可能会更好: --oracle SELECT * FROM person WHERE birthdate BETWEEN TO_DATE('20170101', 'YYYYMMDD') AND TO_DATE('20170301', 'YYYYMMDD') --mysql …

7
如何避免重写应用程序的各个部分
我在一家公司的销售部门项目中工作。这是我的第一份专业编程工作,但是我一直在自己编码并学习多年。该项目的一部分涉及获取一些数据,并将其与输入相结合以生成图形。然后保存数据……依此类推。因此,我花了不到一天的时间为此编写了代码。第二天,我展示了我的项目主管,他喜欢它,但是“如果有的话”,并希望我在图表中添加一些内容。这对程序的外观或功能没有太大的改变,但是它极大地改变了我存储数据,处理数据等的方式。 再次,我花了一天的时间来重新组织数据库表,并基本上从头开始重写代码以支持此新请求。我又把它还给了他,同样的事情发生了。他提出了其他要求,这些要求极大地改变了我处理数据的方式。因此,我不得不再次重写它。最终,他签署了该协议,希望我不必再次重写它。 请清楚,我不是在殴打我的经理或类似的人。他是一个伟大的人,他所要求的东西并没有超出这个世界,它们与我以前所做的不相容。 我只是想知道将来是否可以做些什么来避免完全重写。我了解制作灵活的代码并且正在尝试这样做,但是我想知道我可以做些不同的做法或事情来简化此工作,因此,将来,我不会花3天时间去做一些应该吃1。

2
这种编程技术叫什么?
我在采访中进行结对编程时遇到了这种编程技术,但在Google上找不到它的名称。 这个想法是,您首先编写使用变量的表达式,然后再编写用于计算变量的代码。 要在此处使用一些示例代码: private bool ValidPolicyNumber(string policyNumber) { var hasExpectedPrefix = policyNumber.Substring(0,5) == "POLIC"; var followedBy7Digits = Regex.IsMatch(policyNumber.Substring(6,7), "^[0-9]{7}$"); var hasLengthOf12 = policyNumber.Length == 12; return hasExpectedPrefix && followedBy7Digits && hasLengthOf12; } 使用我提到的技术编写此函数时,您将首先写最后一行return hasExpectedPrefix && followedBy7Digits && hasLengthOf12;,然后写在它前面的三行。 我能找到的最接近的技术是“如意算盘”,它来自SICP,但是与调用您稍后要实现的函数有关,而不是使用您稍后要初始化的变量。

1
Java默认方法用法
几十年来,它一直是接口那样的话只 只(只)指定的方法签名。我们被告知这是“正确的做事方式™”。 然后Java 8出来并说: 好吧,嗯,现在您可以定义默认方法了。再见,再见。 我对有经验的Java开发人员和最近(过去几年)开始开发它的人如何消化它感到好奇。我也想知道这如何适合Java正统和实践。 我正在构建一些实验代码,并且在进行一些重构时,最终得到了一个接口,该接口简单地扩展了标准接口(Iterable)并添加了两个默认方法。老实说,我对此感到非常好。 我知道这有点开放,但是现在Java 8已在实际项目中使用了一段时间,围绕默认方法的使用是否存在正统观念?在讨论它们时,我最常看到的是关于如何在不破坏现有使用者的情况下向接口添加新方法。但是像我上面给出的示例一样从一开始就使用它。是否有人在其界面中提供实现时遇到任何问题?

8
“优先考虑组成而不是继承”-防御签名变更的唯一理由是吗?
此页面使用以下参数提倡在继承上进行组合(用我的措辞重新表述): 当我们使用继承时,超类方法签名的更改(尚未在子类中重写)会在许多地方引起其他更改。但是,当我们使用Composition时,所需的其他更改仅在单个位置:子类。 难道这真的是偏向于继承而不是继承的唯一理由吗?因为是这样的话,即使子类不更改实现(即在子类中放置虚拟替代),也可以通过强制采用提倡重写超类的所有方法的编码样式来轻松缓解此问题。我在这里想念什么吗?

6
将对象映射到演示者的干净的OOP方法
我正在用Java创建一个棋盘游戏(例如国际象棋),其中每个棋子都是自己的类型(例如Pawn,Rook等等)。对于应用程序的GUI部分,我需要为每个这些部分提供一个图像。既然做的像 rook.image(); 违反了UI和业务逻辑的分离,我将为每个作品创建一个不同的演示者,然后将作品类型映射到其相应的演示者,例如 private HashMap<Class<Piece>, PiecePresenter> presenters = ... public Image getImage(Piece piece) { return presenters.get(piece.getClass()).image(); } 到目前为止,一切都很好。但是,我认为谨慎的OOP专家在调用getClass()方法时会皱眉,并建议像这样使用访客: class Rook extends Piece { @Override public <T> T accept(PieceVisitor<T> visitor) { return visitor.visitRook(this); } } class ImageVisitor implements PieceVisitor<Image> { @Override public Image visitRook(Rook rook) { return rookImage; } } 我喜欢这种解决方案(谢谢您,老师),但是它有一个明显的缺点。每次将新的样片类型添加到应用程序时,都需要使用新的方法来更新PieceVisitor。我想将我的系统用作棋盘游戏框架,可以通过一个简单的过程添加新作品,其中框架的用户只能提供作品及其演示者的实现,并将其插入框架中即可。我的问题:是否有没有等等的干净的OOP解决方案instanceof,getClass()它将允许这种可扩展性?

4
如何为不返回任何内容的纯方法编写测试?
我有一堆处理值验证的类。例如,一个RangeValidator类检查一个值是否在指定范围内。 每个验证器类都包含两个方法:is_valid(value),该方法返回True或False取决于值,并ensure_valid(value)检查指定的值,如果值有效,则不执行任何操作,或者,如果值与预定义的规则不匹配,则抛出特定的异常。 当前有两种与此方法关联的单元测试: 传递无效值并确保引发异常的代码。 def test_outside_range(self): with self.assertRaises(demo.ValidationException): demo.RangeValidator(0, 100).ensure_valid(-5) 传递有效值的那个。 def test_in_range(self): demo.RangeValidator(0, 100).ensure_valid(25) 尽管第二项测试已完成工作-如果抛出异常,则失败,如果ensure_valid没有抛出异常,则成功,但assert内部没有s 的事实看起来很奇怪。读过此类代码的人会立即问自己,为什么要进行似乎无所事事的测试。 当测试不返回值且没有副作用的方法时,这是当前的做法吗?还是应该以其他方式重写测试?或者只是发表评论以解释我在做什么?

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.