软件工程

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

2
双向数据同步的最佳实践/模式
在我的工作中,经常会出现数据库系统之间的2路数据同步的想法。经典示例是两个稍微不同的CRM系统(例如,Raiser's Edge和Salesforce),并且需要在它们之间进行双向联系人数据同步。 撇开API的考虑,假设您有一个要同步的共享密钥,并且纯粹考虑要使用的算法/模式,这是非技术人员经常低估的一项任务。 例如,您必须当心: 您可以轻松地检测到两个系统中的哪些记录已更改(或者您必须比较两个系统之间的所有记录以检测更改) 如果要进行每N小时一次的同步,那么在两个系统中相同记录或多或少同时发生更改的情况下,如何处理冲突 如果您要进行实时同步(例如,一个系统中的更新会立即触发另一个系统的更新),如何处理由于错误或系统崩溃而导致的时间差异。 我个人可以考虑解决所有问题的方法,但是我想知道是否可以参考任何众所周知的模式,文献或最佳实践。

20
开发人员必须了解业务领域,还是该规范足够?
我在一家公司领域工作,因为该领域是电子领域的高科技,因此很难理解,但是它适用于复杂领域中的任何软件开发。 我工作的应用程序显示了很多信息,图表和度量标准,如果没有该领域的经验,这些信息,图表和度量标准将很难理解。开发人员使用规范来描述软件必须执行的操作,例如指定特定的图表必须显示此类指标,并且该指标是以下算术公式。 这样,开发人员并不真正了解业务以及他/为什么要执行此任务。如果规范确实很详细,那么可以这样做,但是当规范不是很详细时,或者当作者忘记了用例时,开发人员很难找到解决方案。 另一方面,对每个开发人员进行所有业务方面的培训可能会非常漫长且困难。 我们应该更加重视详细的规范(但众所周知,不存在完善的规范),还是应该培训所有开发人员以了解业务领域? 编辑:请记住您的回答,即该公司可以使用外部开发人员,并且对所有域的组建大约需要2周的时间

9
您是否应该防止来自外部API的意外值?
可以说,您正在编码一个从外部API接收输入的函数MyAPI。 该外部API MyAPI的合同规定其将返回string或number。 它是推荐的防范之类的东西null,undefined,boolean等即使它不属于API的一部分MyAPI?特别是,由于您无法控制该API,因此无法通过诸如静态类型分析之类的方法来做出保证,因此,安全起来总比对不起好。 我在考虑稳健性原则。



7
项目经理选择了一个过于复杂的设置,没有人有经验
最近,我启动了一个看起来并不难做的项目,这个概念是一个相当简单的应用程序,它必须不时地(也许一天10次)接受输入,并尝试对其执行一些操作并收集所有结果在末尾。然后,该应用程序将获得一个前端Web门户,供客户用来查看结果,而不是精确地了解火箭科学。 为此,我最初巧妙地使用了Python的内置并发库(ThreadPoolExecutor),并为前端使用了易于使用的库(我选择Flask是因为它对于初学者来说很容易,并且相对易于维护和测试)。 一旦我们完成了项目,项目经理表示我们必须使用第三方消息队列功能而不是线程,并且必须实现负载平衡,最终发生的事情是,我们最终开始与Celery,Redis,RabbitMQ,Nginx,uWSGI合作以及其他很多没有任何实际经验的大型第三方服务。 最终,这导致了许多意大利面条式代码,无法测试的任务(由于第三方库的复杂性,对代码进行修补甚至无法正常工作)和许多麻烦,因为没人知道这些服务的附加价值是什么。 。 在您说“是的,您应该使用那些服务”之前,请记住,除了引入竞争条件困扰的代码之外,没有人知道如何使用这些服务,甚至不知道他们的工作。 我该怎么办?在这一点上,即使现在最终产品的状况比开始时要差,恢复到原来的状态也太昂贵了,并且PM陷入了使用这些服务的僵局。与他讨论这件事还有什么用吗?我需要更多时间吗?还是苛刻的答案,我对工作太傻了吗?

3
SOAP的当前意义是什么
上一次我在2013年在一家金融公司实习期间遇到了一个基于SOAP的服务。那是我开始从事IT事业的时候。我记得在我的一个工程课程中有一些关于SOAP的学习资料。除此之外,我在职业生涯中没有使用过太多SOAP。 我问这个问题是因为“ SOAP和REST之间的差异”这个问题是我最近的一次采访中出现的。据我所知(以及我在Google上所发现的),SOAP是一种在客户端和服务器之间具有紧密耦合的协议,用于信息交换,该协议与业务逻辑密切相关。REST是用于数据传输的更灵活的无状态架构。 如果我对SOAP和REST之间的区别有误,可以请我纠正我吗?另外,SOAP在当今的意义是什么?人们仍在开发新的基于SOAP的API,还是现在已经成为传统?
51 rest  api  web-services  soap 

7
有期限的待办事项?
背景 我正在一个团队中实施零停机时间部署。为了实现此目标,我们正计划使用蓝/绿部署策略。我在进行研究时意识到的一件事是进行数据库更改变得多么复杂。重命名列之类的简单操作可能需要3个完整的发布周期,直到完成! 在我看来,全面实施变更需要多个发布周期,这会带来很多潜在的人为错误。在链接的文章中,它表明2个发行版需要更改代码,而3个发行版需要数据库迁移。 我在寻找什么 当前,如果我们想记住要做的事情,可以在我们的问题管理系统中创建票证,这会造成混乱,并且还可能被管理层转移到以后的冲刺或待办事项中;或者我们可以创建一个TODO注释,它可能会完全被遗忘。 我正在寻找的方式是TODO注释可以有一个截止日期,并且,如果该截止日期已过期,我们的持续集成系统(当前将使用的未定)将拒绝该构建。 例如,如果我们重命名列,则可以为其创建初始迁移,然后创建两个TODO注释以确保创建其余的两个迁移: // TODO by v55: Create migration to move constraints to new column, remove references to old column in app // TODO by v56: Create migration to drop old column 这似乎很容易实现,但是我想知道是否已经存在类似的东西,因为我不想重新发明轮子。 其他想法 考虑到滚动部署和蓝/绿部署被认为是最佳实践,我觉得自己可能在这里遇到了XY问题,但我找不到能够减轻数据库更新麻烦的解决方案,这似乎很奇怪。如果您认为我正在完全研究错误的内容,请在评论中告诉我!就是说,我给出的数据库示例只是一个示例,我认为带有到期日期的TODO注释在其他情况下也将很有用,因此即使我正在接近这种特定情况,我还是很想回答我的问题也是实际问题。谢谢! 编辑:我只是想这可能会有所帮助的另一种情况。如果在准备就绪时使用Feature Toggles来打开应用程序的某些部分,则必须小心清理它们,否则最终可能会出现Toggle Debt。带有截止日期的评论可能是记住这一点的好方法。

5
吃豆人游戏中的“ 256级错误”可以被视为未处理的段错误吗?
我试图向某人解释分段错误,并且我正在考虑吃豆子中的256级杀伤屏幕,整数溢出是如何触发的,以及该行为与分段中经常描述的“未知状态”有多相似故障。 我想说的是这是我所谓的“未处理的段错误”的一个很好的例子,但是在我可能散布错误信息之前,我宁愿先获得第二意见。 我尝试查找它,但我得到的只是有关错误本身的文档,以及Hipster Whale和Namco之间的协作。 因此,您是否认为Pacman级别256中的行为是未处理的细分违规的示例?
51 memory  errors 

8
进行多线程JavaScript运行时实现的缺点是什么?[关闭]
在过去的一周中,我一直在研究多线程JavaScript运行时实现。我有一个使用JavaScriptCore和boost的C ++概念证明。 该体系结构很简单:当运行时完成对主脚本的评估后,它将启动并加入线程池,该线程池开始从共享优先级队列中选择任务,如果两个任务尝试同时访问变量,它将被标记为atomic,并且争夺访问权限。 问题是,当我向JavaScript程序员展示此设计时,我得到了非常负面的反馈,我也不知道为什么。即使是私下里,他们都说JavaScript是单线程的,必须重写现有的库,而如果我继续从事这一工作,gremlins将产生并吞噬一切生物。 我最初也有一个本地协程实现(使用boost上下文),但是我不得不放弃它(JavaScriptCore对于堆栈是很古怪的),并且我不想冒险,所以我决定不提它。 你怎么看?JavaScript是单线程的吗,应该单独使用吗?为什么每个人都反对并发JavaScript运行时的想法? 编辑:该项目现在位于GitHub上,您可以自己尝试一下,让我知道您的想法。 以下是无争用地在所有CPU内核上并行运行的承诺的图片:

8
对于需要按内容搜索的大型数据集,使用NoSQL数据库是否不切实际?
我已经学习NoSQL数据库已有一个星期了。 我真的了解NoSQL数据库的优势以及它们非常适合的许多用例。 但是人们通常会在撰写文章时就好像NoSQL可以代替关系数据库一样。还有一点我无法理解: NoSQL数据库是(通常)键值存储。 当然,可以将所有内容存储到键值存储中(通过将数据编码为JSON,XML等),但是我看到的问题是,在许多情况下,您需要获取一些与特定条件匹配的数据用例。在NoSQL数据库中,只有一个可以有效搜索的条件-密钥。关系数据库经过优化,可以有效地搜索数据行中的任何值。 因此,NoSQL数据库并不是持久存储需要按其内容搜索的数据的真正选择。还是我误会了什么? 一个例子: 您需要存储网上商店的用户数据。 在关系数据库中,您将每个用户存储为users表中的一行,并带有ID,名称,他的国家等。 在NoSQL数据库中,您将以ID为密钥存储每个用户,并将其所有数据(以JSON等编码)存储为值。 因此,如果您需要从某个特定国家/地区获取所有用户(出于某种原因,营销人员需要了解他们的某些信息),那么在Relational Database中这样做很容易,但是在NoSQL Database中却不是很有效,因为您必须获取每个用户,解析所有数据并进行过滤。 我并不是说这是不可能的,但是它变得更加棘手,如果您要搜索NoSQL条目的数据,我想那不是那么有效。 您可以为每个国家/地区创建一个密钥,以存储该国家/地区中每个用户的密钥,并通过获取存放在该国家/地区的密钥中的所有密钥来获取特定国家/地区的用户。但是我认为这种技术使复杂的数据集变得更加复杂-难以实现且不如查询SQL数据库有效。因此,我认为这不是您在生产中使用的方式。还是? 我不确定我是否会误解或忽略了一些概念或最佳实践来处理此类用例。也许您可以纠正我的陈述并回答我的问题。

2
实际上,Git分支是否是“映射Hilbert空间子流形的同胚内爆函数”?
众所周知: 一旦您了解分支是映射希尔伯特空间子流形的同胚endofunctors,Git就变得更容易 这似乎是行话,但另一方面, 总而言之,X中的单子仅是X的终结符类别中的一个单义词,乘积×由终结符的组成替换,单位由身份终结符设置。 之所以有趣是因为它是真的。 我可以通过阅读以下简单的文字来避免合并错误吗?
51 git 

13
与其他可能有害的特征相比,为什么将类似eval的特征视为邪恶?
大多数现代语言(以某种方式解释)都具有某种评估功能。这样的函数执行任意语言代码,大部分时间作为字符串作为主要参数传递(不同的语言可能会向eval函数添加更多功能)。 我知道不应允许用户执行此功能(编辑,即直接或间接地从任意用户获取任意输入以传递给eval),尤其是对于服务器端软件,因为它们可能会迫使进程执行恶意代码。这样,教程和社区会告诉我们不要使用评估。但是,在很多情况下eval都是有用的和被使用的: 对软件元素的自定义访问规则(IIRC OpenERP有一个ir.rule可以使用动态python代码的对象)。 自定义计算和/或条件(OpenERP具有允许自定义代码计算的字段)。 OpenERP报表解析器(是的,我知道我对OpenERP的东西很感兴趣……但这是我的主要示例)。 在某些RPG游戏中编码法术效果。 因此,只要正确使用它们,它们就有很好的用途。主要优点是该功能允许管理员编写自定义代码,而无需创建更多文件并包含它们(尽管大多数使用eval功能的框架也可以指定要读取的文件,模块,程序包...)。 但是,在流行文化中,评估是邪恶的。就像闯入您的系统一样。 但是,如果用户以某种方式访问​​其他功能,这些功能可能会有害:取消链接,读取,写入(文件语义),内存分配和指针算术,数据库模型访问(即使不考虑SQL可注入的情况)。 因此,基本上,在大多数情况下,任何代码编写不正确或未正确监视(资源,用户,环境等)时,代码都是邪恶的,甚至可能导致经济影响。 但是eval函数有一些特殊之处(与语言无关)。 问题:这种恐惧成为流行文化的一部分,是否有任何历史事实,而不是同样关注其他可能危险的特征?

4
PHP中变量的主要命名约定是什么:驼峰或下划线?[关闭]
人们的共识似乎是,应该遵循他们所开发平台的惯例。看到: 下划线还是驼峰式? 命名约定:camelCase与underscore_case? 然而,PHP似乎没有遵循任何的约定内部(没有惊喜出现),甚至方法和功能(例如mysqli::set_local_infile_default, PDOStatement::debugDumpParams); 但是,下划线似乎在函数名称中占主导地位。 但是,我找不到的是:PHP中变量的主要命名约定是什么?

5
IOC容器违反了OOP原则
IOC容器的目的是什么?合并的原因可以简化为以下内容: 当使用OOP / SOLID开发原则时,依赖注入会变得混乱。您可能具有顶层入口点,这些入口点管理着位于其自身下方的多个级别的依赖关系,并通过构造递归传递依赖关系,或者您在工厂/构建器模式和接口中有一些重复的代码,可以根据需要构建依赖关系。 没有OOP / SOLID方式可以执行此操作并拥有超级漂亮的代码。 如果上述陈述是正确的,那么IOC容器该如何做?据我所知,他们没有采用手动DI无法完成的未知技术,因此唯一的解释是IOC容器通过使用静态对象私有访问器来打破OOP / SOLID原则。 IOC容器是否在幕后打破了以下原则?这是真正的问题,因为我有很好的理解,但是感觉到其他人有更好的理解: 范围控制。范围是我对代码设计做出几乎所有决定的原因。块,本地,模块,静态/全局。范围应该非常明确,在块级别尽可能多,而在静态级别则尽可能少。您应该看到声明,实例化和生命周期的结尾。只要我明确指出,我相信该语言和GC可以管理范围。在我的研究中,我发现IOC容器将大多数或所有依赖项设置为静态,并通过幕后的一些AOP实现对其进行控制。所以没有什么是透明的。 封装。封装的目的是什么?我们为什么要保留私人会员呢?出于实际原因,因此我们的API的实现者无法通过更改状态(应由所有者类管理)来破坏实现。但是,出于安全原因,也不会发生注入超过我们的成员国并绕过验证和类控制的情况。因此,在编译之前以某种方式注入代码以允许外部访问私有成员的任何东西(模拟框架或IOC框架)都非常庞大。 单一责任原则。从表面上看,IOC容器似乎使事情更清洁。但是想象一下,如果没有帮助程序框架,您将如何完成相同的任务。您将传递带有十几个依赖项的构造函数。这并不意味着用IOC容器将其掩盖,这是一件好事!这是重构代码并遵循SRP的标志。 打开/关闭。就像SRP并非仅是类一样(我将SRP应用于单一职责范围,更不用说方法了)。打开/关闭不仅是不更改类代码的高级理论。这是一种了解程序配置并控制要更改和扩展的内容的实践。IOC容器可以部分地完全更改类的工作方式,因为: 一种。主要代码没有确定切换出依赖项,而是框架配置。 b。范围可以在不受调用成员控制的时间进行更改,而是由静态框架在外部确定。 因此,该类的配置不是真正封闭的,它会根据第三方工具的配置自行更改。 这是一个问题,是因为我不一定是所有IOC容器的大师。尽管IOC容器的想法不错,但它们似乎只是掩盖了糟糕的实现的外观。但是,为了完成外部Scope控制,私有成员访问和延迟加载,必须进行许多非平凡的可疑事情。AOP很棒,但是通过IOC容器完成AOP的方式也值得怀疑。 我可以相信C#和.NET GC可以完成我期望的工作。但是我不能再信任第三方工具来改变我的已编译代码,以执行我无法手动执行的操作的变通办法。 EG:实体框架和其他ORM创建强类型对象并将其映射到数据库实体,并提供样板功能来执行CRUD。任何人都可以建立自己的ORM,并继续手动遵循OOP / SOLID原则。但是这些框架对我们有帮助,因此我们不必每次都重新发明轮子。看来,IOC容器可以帮助我们有目的地围绕OOP / SOLID原则开展工作并加以掩盖。

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.