软件工程

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

7
如何快速搜索数据库中非常大的字符串/记录列表
我有以下问题:我的数据库包含超过200万条记录。每个记录都有一个字符串字段X,我想显示一个记录列表,其中字段X包含某个字符串。每条记录的大小约为500字节。 更具体地说:在我的应用程序的GUI中,我有一个文本字段,可以在其中输入字符串。在文本字段上方,我有一个表,显示与文本字段中的字符串匹配的(前N个,例如100个)记录。当我在文本字段中键入或删除一个字符时,表内容必须即时更新。 我想知道是否存在使用适当的索引结构和/或缓存的有效方法。如上所述,我只想显示与查询匹配的前N个项目。因此,对于足够小的N来说,从数据库中加载匹配项应该不是大问题。此外,在主存储器中缓存项目可以使检索更快。 我认为主要问题是在给定模式字符串的情况下如何快速找到匹配项。我可以依靠某些DBMS工具,还是必须自己构建一些内存索引?有任何想法吗? 编辑 我已经进行了第一次实验。我已将记录分为不同的文本文件(每个文件最多200条记录),并将文件放在不同的目录中(我使用一个数据字段的内容来确定目录树)。我最终得到大约40000个目录中的大约50000个文件。然后,我运行Lucene来索引文件。使用Lucene演示程序搜索字符串非常快。拆分和建立索引花费了几分钟:对于我来说这完全可以接受,因为它是我要查询的静态数据集。 下一步是将Lucene集成到主程序中,并使用Lucene返回的命中将相关记录加载到主存储器中。

19
现实世界中的应用程序是否需要128位平面地址空间?
这有点“一个兆字节对于任何人都足够”,但是... 64位平面地址空间所提供的空间比32位地址空间多出多达43亿十亿倍。那是17,179,869,184 GiB。 显然,从8位到16位的转换非常快(我以80年代少年时期的方式查看事物,而忽略了所有那些大型机和小型机,因为它们无法运行Elite端口)。从16位到32位的转换花费了更长的时间,而32位实际上持续了一段时间。 现在我们有64位,是否愚蠢地说“ 17,179,869,184 GiB对任何人都足够”? 这是一个程序员的问题,因为我确实牢记编程观点。即使某天的计算机上看似无限的工作内存,也并不意味着应用程序将需要看似无限的平面地址空间。 基本上,我们程序员可以松一口气说:“好吧,不管整数或浮点数可以做什么,至少我不必担心指针会增长吗?”。

5
Javascript模块化,基于服务器的MVC和业务现实
我知道这是一个非常广泛的问题,但是我已经分别处理了该问题的各个方面,并且正在努力将所有概念和技术结合在一起。 我想指定答案应包括以下技术: C# 带剃刀的MVC 3 带有jQuery的Javascript 如果这些内容有助于回答以下问题,则欢迎将其视为超越建议的建议(例如Backbone.js,Entity Framework等): 使用上面列出的技术,在组织代码和逻辑,同时保持可伸缩性和创建丰富,快速,干净的UI的能力方面,什么是最佳策略? 理想情况下,应将重点放在部署在企业/企业环境中的解决方案上。请注意,上面的技术列表不会更改,因此请不要提供“您应该使用xxx而不是现在使用的yyy ”的解决方案。 背景 我每天都使用jQuery,已经采用ASP.NET的MVC,并且已经使用C#很长时间了。因此,您可以假设这些技术的中高级知识来提出解决方案。 我将问题分成较小的部分,以使其更易于回答: 1.项目结构 鉴于我正在使用ASP.NET MVC(在Visual Studio 2010中),我想要一个目录结构解决方案,该解决方案可以接受这种类型的应用程序的主要布局。我猜想像早午餐一样,但是每个文件夹将包含什么以及它如何与应用程序的其他区域一起工作的更多细节。 2.数据访问 我想使用一种API类型的结构来尽可能地模块化我的数据访问。你可以假设很多POCO对象(的User,UserGroup,Customer,OrderHeader,OrderDetails,等),但也会有一些复杂的报表需要数据密集型的SQL和精心UI渲染。 EF + LINQ对于前者而言非常出色,但对于后者则不那么理想。在没有过于复杂或过于简单的情况下,我找不到适合两种情况的东西。 3.客户端代码组织和UI渲染 像大多数开发人员最先使用jQuery一样,我陷入了将代码混在一起的陷阱,但是很快发现它堆积并变得丑陋。尽管从那时起我就突飞猛进,但我仍在努力使代码模块化以及在不重复代码的情况下使用UI的各个部分。 举例来说,我可能会编写的典型代码看起来像这样,我评论了困扰我的东西(请注意,此后我已更改为使用延迟的AJAX调用,并从DOM操作中分离了实际的数据请求): $('#doSomethingDangerous').click(function () { // maybe confirm something first if (confirm('Are you sure you want to do this?')) { // show a spinner? something …

6
敏捷与XP有何不同?
我在网上阅读了几篇文章,以了解敏捷,XP,Scrum,结对编程之间的区别/彼此之间的相互关系,并得出以下结论: Scrum和XP几乎相同。XP的发布时间比Scrum短 敏捷和XP方法中都采用了结对编程 但是我无法确定敏捷与XP有何不同。 除了提供URL,我将很高兴阅读您对此的经验和想法。

11
是什么使项目变大?[关闭]
出于好奇,小型,中型和大型项目有什么区别?它是通过代码行或复杂性来衡量的还是什么? 我正在建立一个物物交换系统,到目前为止,大约有1000行代码用于登录/注册。即使有很多LOC,我也不会认为这是一个大项目,因为它不是那么复杂,尽管这是我的第一个项目,所以我不确定。如何测量?
32 project 

2
为什么软件使用Win32名称?
如果软件/库对Windows平台有某种支持,则它们几乎总是将其目录和变量命名为win32。这在C / C ++项目中最为普遍。甚至MinGW项目的目标是三重用途win32。是否有一个原因?为什么不使用Windows或Microsoft Windows这样的专有名称?命名选择是否存在法律障碍? 这个问题不是关于API的,而是正在使用的命名约定。当一个库支持其他操作系统时,它们通常使用适当的名称,例如linux,freebsd或需要的任何特殊支持。但是当涉及到Windows时,它通常被缩写为win32,与其他语言相比显得有些奇怪。

1
“ StringBuilder”是Builder设计模式的应用程序吗?
是“构建器”模式仅限于解决“ telescoping构造函数”反模式,还是可以说也解决了复杂的不可变对象创建这一更普遍的问题? 该StringBuilder班在其名称中的“建设者”,但它没有任何可伸缩的构造函数,它只是帮助我们收集了所有我们需要传递给一个不可变对象的构造函数的数据。 在我看来,答案似乎是非常明确的“是”,但是在该主题上似乎存在一些分歧,因此我希望有人可以对此进行澄清。 我在回答这个问题:程序员SE:在构造函数中合法的“实际工作”?OP想要创建一个包含复杂树的(可能是不可变的)对象,然后弹出“ builder”模式的想法,在研究它时,我发现了这个问答,似乎是在说“ StringBuilder”风格的对象创建是不是 “建设者”模式的应用,这是我不明白原因:#1 - StringBuilder的和Builder模式。(据我所知,回答该问题的人未能提出令人信服的观点。)

2
用全栈javascript分离前端和后端的方法?
假设我有一个前端,该前端主要是一个单页面的应用程序,它是使用angular,grunt和bower编写的。假设我有一个后端,主要是一个坐在ORM之上的REST API,它使用grunt,express和sequelize之类的东西从数据库中存储/检索对象。 角度应用程序执行用户看到的所有可视化内容,但是它是通过后端提供的服务上的GUI来完成的。 希望将它们分成两个不同的代码库,以允许独立开发,版本控制,持续集成,推送到开发等。 我的问题是,有什么方法可以干净地进行此操作?是否有针对全栈javascript的推荐最佳实践? 选项#1似乎是一个整体,即“不要将它们分开”。优点是构建链很简单,而且一切都集中在一个地方-但似乎有很多弊端。很难独立版本化,正面折断意味着背面无法展开,依此类推。 选项#2似乎是一个准整体,其中前端构建链导致将一堆文件写入后端。dist前端的目录将引用后端的某个目录,因此从本质上讲,当前端最小化,丑化等等时,它最终将发布到后端,后端将运行所有内容。 选项#3似乎是完全分开的:前端和后端各自在不同的端口上运行各自的服务器,并且它们是完全独立的项目。缺点似乎是需要将它们配置为了解彼此的端口。后端必须允许来自前端的CORS,并且前端需要知道所有这些端点的预期位置。 选项#4可能是使用docker-compose之类的东西将整个东西装配在一起。 我确定还有其他选择。建议的最佳做法是什么?


8
即使我没有发生舍入错误,比较浮点数的相等性是否也会误导初级开发人员?
例如,我想显示一个从0,0.5,... 5开始的按钮列表,每0.5跳一次。我使用for循环来做到这一点,并在按钮STANDARD_LINE上使用了不同的颜色: var MAX=5.0; var DIFF=0.5 var STANDARD_LINE=1.5; for(var i=0;i<=MAX;i=i+DIFF){ button.text=i+''; if(i==STANDARD_LINE){ button.color='red'; } } 在这种情况下,应该没有舍入错误,因为每个值在IEEE 754中都是准确的。 var MAX=10; var STANDARD_LINE=3; for(var i=0;i<=MAX;i++){ button.text=i/2.0+''; if(i==STANDARD_LINE/2.0){ button.color='red'; } } 一方面,原始代码更加简单并转发给我。但是我正在考虑一件事:i == STANDARD_LINE是否误导了初级队友?它是否掩盖了浮点数可能具有舍入误差的事实?阅读这篇文章的评论后: https://stackoverflow.com/questions/33646148/is-hardcode-float-precise-if-it-can-be-represented-by-binary-format-in-ieee-754 似乎有很多开发人员不知道某些浮点数是准确的。即使在我的情况下有效,我是否应该避免浮点数相等性比较?还是我在考虑这个问题?

7
版本控制如何在80年代和90年代的当今微型计算机上工作?
我很好奇,程序员团队通常是如何在80年代和90年代初期管理软件开发的。是将所有源代码简单地存储在每个人都在使用的计算机上,还是将源代码通过软盘传递并手动复制并手动合并,还是像我们那样通过网络(例如CVS)实际使用版本控制系统?现在?还是正在使用离线CVS之类的东西? 如今,每个人都依赖于源代码管理。但是在80年代,计算机网络并不是那么容易设置,并且诸如最佳实践之类的东西仍在研究中…… 我确实知道在70年代和60年代编程非常不同,因此不需要版本控制。但是到了80年代和90年代,人们开始使用计算机编写代码,并且应用程序的大小和范围开始扩大,所以我想知道那时人们是如何管理所有这些的。 此外,这在平台之间有何不同?说Apple vs Commodore 64 vs Amiga vs MS-DOS vs Windows vs Atari 注意:我主要是在谈论当今微型计算机上的编程,而不是大型UNIX 计算机上的编程。

3
错误处理注意事项
问题: 长期以来,我对这种exceptions机制感到担心,因为我觉得它并不能真正解决应有的问题。 要求:关于该主题的争论很长时间,而且大多数人都在努力比较exceptions和返回错误代码。这绝对不是这里的主题。 尝试定义错误,我同意Bjarne Stroustrup和Herb Sutter的CppCoreGuidelines 错误表示该功能无法实现其广告目的 要求:该exception机制是用于处理错误的语言语义。 要求:对我来说,没有“没有借口”的功能不能完成任务:要么我们错误地定义了前后条件,所以该功能无法确保结果,或者某些特殊情况对于花时间在开发上没有足够重要的意义。一个办法。考虑到IMO,常规代码和错误代码处理之间的区别(在实施之前)是非常主观的。 要求:使用异常指示何时不保留前置条件或后置条件是该exception机制的另一个目的,主要是用于调试目的。我的目标不是这里的用法exceptions。 在许多书籍,教程和其他资料中,它们倾向于将错误处理显示为一门相当客观的科学,可以解决这一问题,exceptions而您只需要catch它们具有强大的软件就可以从任何情况下恢复。但是,作为开发人员的几年时间使我从另一种方法来看问题: 程序员倾向于通过抛出异常来简化他们的任务,而这种特殊情况似乎太少而无法仔细实现。典型的情况是:内存不足问题,磁盘已满问题,文件损坏等,这可能就足够了,但并不总是从体系结构级别决定。 程序员往往不会仔细阅读有关库中异常的文档,并且通常不知道函数何时何地抛出。而且,即使他们知道了,他们也并没有真正管理它们。 程序员往往没有足够早地捕获异常,当他们捕获异常时,主要是记录并抛出更多异常。(请参阅第一点)。 这有两个结果: 经常发生的错误可以在开发的早期发现并进行调试(很好)。 罕见的异常无法管理,并且会使系统在用户家崩溃(带有一条漂亮的日志消息)。有时会报告错误,甚至不会报告。 考虑到这一点,海事组织错误机制的主要目的应该是: 在不管理某些特定情况的代码中使可见。 发生这种情况时,将问题运行时与相关代码(至少是调用方)进行通信。 提供恢复机制 exception语义作为错误处理机制的主要缺陷是IMO:很容易看到a throw在源代码中的位置,但是绝对不明显,通过查看声明来知道特定功能是否会抛出。这带来了我上面介绍的所有问题。 该语言不会像对语言的其他方面(例如强类型的变量)那样严格执行和检查错误代码 尝试解决方案 为了改善这一点,我开发了一个非常简单的错误处理系统,该系统试图使错误处理的重要性与普通代码相同。 这个想法是: 每个(相关)功能都接收到对success非常轻的对象的引用,并可能将其设置为错误状态。在保存文本错误之前,该对象非常轻。 如果提供的对象已经包含错误,则鼓励函数跳过其任务。 绝对不能覆盖错误。 完整的设计显然会全面考虑每个方面(约10页),以及如何将其应用于OOP。 Success该类的示例: class Success { public: enum SuccessStatus { ok = 0, // All is fine error = 1, // …

5
通常如何解析注释?
一般如何用编程语言和标记来处理注释?我正在为某些自定义标记语言编写解析器,并希望遵循最少惊喜的原则,因此我试图确定一般约定。 例如,注释是否应嵌入令牌中,从而“干扰”令牌?通常,是这样的: Sys/* comment */tem.out.println() 有效? 另外,如果语言对新行敏感,并且注释跨越新行,是否应考虑新行? stuff stuff /* this is comment this is still comment */more stuff 被视为 stuff stuff more stuff 要么 stuff stuff more stuff ? 我知道几种特定的语言在做什么,我也没有在寻求意见,而是在寻找是否:是否普遍达成共识,标记对代币和新行的一般期望是什么? 我的特定上下文是类似Wiki的标记。
31 parsing  comments 

6
在REST API调用中输入密码
假设我有一个REST API,该API也用于设置/重置密码。我们还假设它可以通过HTTPS连接工作。是否有充分的理由不将该密码放在调用路径中,也可以说我将在BASE64中对它进行编码? 一个示例是重设这样的密码: http://www.example.com/user/joe/resetpassword/OLDPASSWD/NEWPASSWD 我知道BASE64没有加密,但是在这种情况下,我只想保护密码以进行网上冲浪。
31 rest  passwords 

9
为什么在实现Builder模式时我们需要一个Builder类?
我已经看到了Builder模式的许多实现(主要是Java)。它们都有一个实体类(假设是一个Person类)和一个构建器类PersonBuilder。构建器“堆叠”各种字段,并返回new Person带有传递的参数的。为什么我们显式需要一个构建器类,而不是将所有构建器方法放在Person类本身中? 例如: class Person { private String name; private Integer age; public Person() { } Person withName(String name) { this.name = name; return this; } Person withAge(int age) { this.age = age; return this; } } 我可以简单地说 Person john = new Person().withName("John"); 为什么需要PersonBuilder上课? 我看到的唯一好处是,我们可以将Person字段声明为final,从而确保了不变性。

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.