软件工程

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

13
OOP中的对象是否必须代表实体?
对象是否必须代表实体? 由一个实体我的意思是这样一个Product,Motor中,ParkingLot等,物理,或甚至一个明确的非物理概念对象-这被很好地定义,其中一些核心数据清楚地属于对象的东西,以及一些功能/方法显然对核心数据起作用。 例如,我可以有一个对象,Demon它本身是一个实体,一个虚构的对象,也许不是物理的,但仍然是一个实体 一个对象可以仅仅是方法的集合,一组与一个共同目标相联系的通用过程吗? 示例:可以在没有实体的情况下调用MotorOperations或的类MotorActions,但是该类内部的方法可以执行以下操作 getMotorDataFromHTMLForm() getMotorManufacturers() selectMotorFromUserRequirements($ requirements) canMotorCanHandleOperatingConditions($ conditions) computePowerConsumptionForMotor($ id) 通常将类定义为对象的中心数据+数据操作。因此,Motor对于可能存在一些与电动机规格有关的电动机变量,并且可能存在将这些数据组合以产生某些结果的操作。 就我而言,这更像是我有一个对数据+ 通过该类传递数据的操作的类,除了临时传递类数据之外,没有任何以“ Motor Operations”为中心的数据。 题 类可以表示无实体的对象吗?如果不是,为什么它们不好/不完整/不以OOP为中心?有什么方法需要在概念上进行更改/改进以符合OOP?

23
每个程序员都必须学习正则表达式吗?[关闭]
我是编程新手,在一次采访中我遇到了一个关于正则表达式的问题;不用说我无法回答。所以我想知道我是否应该学习正则表达式?所有领域的每个程序员都必须这样做吗?还是对某些特定领域进行编程是必须的? 相关问题: 为什么正则表达式如此令人着迷? 什么时候不应该使用正则表达式?

19
在两个程序员之间进行选择:经验还是热情?
我的职位是必须雇用一名程序员,并可以选择2名候选人,第一个有经验,但是他对编码没有热情,他说,第二个没有经验,但是他有出于热情,他在面试中表现出色,并获得了认证。 我们有资源来培训某个人,但是我真的不想浪费这个过程并雇用一个会让您失望的人。有人可以帮助我解决这种情况吗?

11
Java开发人员是否有意识地放弃了RAII?
作为一个长期的C#程序员,我最近来了解有关资源获取即初始化(RAII)的优点的更多信息。特别是,我发现了C#习惯用法: using (var dbConn = new DbConnection(connStr)) { // do stuff with dbConn } 具有C ++等效项: { DbConnection dbConn(connStr); // do stuff with dbConn } 这意味着记住以包围资源的使用像DbConnection在一个using块是在C ++不必要!这似乎是C ++的一大优势。当您考虑一个类的实例成员类型为时,这甚至更令人信服DbConnection。 class Foo { DbConnection dbConn; // ... } 在C#中,我需要IDisposable像这样实现Foo : class Foo : IDisposable { DbConnection dbConn; public void Dispose() { dbConn.Dispose(); …
82 java  c#  c++  language-design 

15
我不明白反对运算符重载的论点
我刚刚读过Joel的其中一篇文章,他说: 通常,我必须承认我有点害怕隐藏事物的语言功能。当您看到代码时 i = j * 5; …至少在C中,您知道j被乘以5,结果存储在i中。 但是,如果您在C ++中看到相同的代码片段,则您一无所知。没有。知道C ++中真正发生的事情的唯一方法是找出i和j是什么类型,这些类型可能在其他地方完全声明。这是因为j可能属于operator*重载类型,并且在您尝试将其乘以乘法时会表现出极大的机智。 (强调我。)害怕隐藏事物的语言功能吗?你怎么会害怕呢?隐藏事物(也称为抽象)不是面向对象编程的关键思想之一吗?每次调用方法时a.foo(b),您都不知道该怎么做。您必须找出什么类型a和b是什么,然后才可能在其他地方声明它们。那么我们应该放弃面向对象的编程,因为它对程序员隐藏了太多的东西吗? 与可能有j * 5什么不同j.multiply(5),您可能必须使用不支持运算符重载的语言编写?再次,您将必须找出方法j内部的类型和peek multiply,因为lo和bekeeper j可能是具有某种multiply方法的类型,该方法执行某些非常机智的操作。 “ Muahaha,我是一个邪恶的程序员,只为一个方法命名multiply,但实际上它是完全晦涩且不直观的,并且与加乘运算绝对无关。” 设计编程语言时是否必须考虑这种情况?然后,我们不得不放弃编程语言中的标识符,理由是它们可能会误导人! 如果您想知道方法的作用,则可以浏览文档或浏览实现内部。运算符重载只是语法糖,我完全不知道它如何改变游戏。 请赐教。

15
在变量名中使用Unicode字符是否不好?[关闭]
我最近尝试对Python 3实现排名算法AllegSkill。 这是数学的样子: 不完全是。 这就是我写的: t = (µw-µl)/c # those are used in e = ε/c # multiple places. σw_new = (σw**2 * (1 - (σw**2)/(c**2)*Wwin(t, e)) + γ**2)**.5 我实际上以为Python 3不幸的是不接受√或²作为变量名。 >>> √ = lambda x: x**.5 File "<stdin>", line 1 √ = lambda x: x**.5 ^ SyntaxError: invalid character …
82 naming  unicode 

18
在工作面试中辨别优秀程序员的最佳方法是什么?
在面试中:可靠地确定某人何时是优秀的程序员的最佳方法是什么。我的意思是,他是效率低下的同龄人的10/15倍,比同龄人的效率高/快/好。 我们中的许多人都听说过FizzBu​​zz问题,以淘汰弱者。当然,花5到10分钟来解决这个问题是一个很明显的指标,表明申请人是一个薄弱的候选人。我认为一个好的指标能够尽快解决这个问题。但是,这似乎还不够。 可能是像给他一个中等复杂的越野车程序,看看他能以多快的速度完成它并找出所有问题所在?

10
如果null不好,为什么现代语言会实现它呢?[关闭]
我确定像Java或C#这样的语言的设计师都知道与空引用存在有关的问题(请参阅空引用真的是一件坏事吗?)。另外,实现选项类型实际上并不比空引用复杂得多。 他们为什么仍然决定将其包括在内?我确信缺少空引用会鼓励(甚至强迫)语言创建者和用户使用质量更高的代码(尤其是更好的库设计)。 仅仅是因为保守主义吗?“其他语言也有,我们也必须有……”?

6
为什么存在TRACE级别,何时应该使用它而不是DEBUG?
在Log4J,Slf4J和Java中的其他几个日志记录框架中,您有两个“开发人员”级别用于记录日志: 调试 跟踪 我了解DEBUG的作用,因为解释很清楚: 调试级别指定细粒度的信息事件,这些事件对于调试应用程序最有用。 但是TRACE级别对其用例不是很明确: 与调试相比,TRACE级别指定的信息事件更详细 (来源:log4J JavaDoc) 这没有告诉我如何或何时使用TRACE。有趣的是,这不是syslog标准中定义的严重性级别。搜寻TRACE和DEBUG之间的区别似乎只是返回“使用DEBUG,哦,也有TRACE”。我找不到TRACE级别的特定用例。我能找到的最好的东西是这个古老的Wiki页面,讨论了该级别存在的优点。 作为一名建筑师,这在我脑海中引发了许多旗帜和问题。如果一个年轻的开发人员要求我将TRACE添加到我的体系结构中,我会用以下问题轰炸他: 应该使用TRACE而不是DEBUG记录的一些信息示例是什么? 通过记录该信息可以解决什么具体问题? 在这些示例中,已记录信息的属性有哪些可清楚地区分TRACE级别而不是DEBUG级别的记录? 为什么该信息必须通过日志基础结构? 将这些信息保留在日志日志中而不只是使用这些日志有什么好处System.out.println? 为什么最好为此使用日志而不是调试器? 在TRACE级别进行日志记录的典型示例是什么? 在示例中,通过以TRACE级别而不是DEBUG进行记录获得了哪些具体收益? 为什么这些收益很重要? 相反:通过将其记录在TRACE而不是DEBUG上可以避免什么问题? 我还能如何解决这些问题?为什么在TRACE级别上进行日志记录比其他解决方案更好? TRACE级别的日志语句是否应保留在生产代码中?为什么? 但是考虑到它存在于大多数主要框架中,我猜它对某些事情有用吗?那么... TRACE的用途是什么,它与DEBUG有何区别?
82 java  logging 

9
动态打字的生产率预期提高了多少?[关闭]
我经常听到这样的说法:动态类型的语言比静态类型的语言更具生产力。提出索赔的原因是什么?难道不只是使用现代概念进行工具处理,例如约定优于配置,使用功能编程,高级编程模型以及使用一致的抽象吗?公认的是,由于不需要(例如在Java中)通常多余的类型声明,因此混乱程度较小,但是您也可以在使用类型推断的静态类型语言中省略大多数类型声明,而不会失去静态类型的其他优点。所有这些都可用于现代静态类型的语言,例如Scala。 那么:对于动态类型的生产力来说,这到底是类型模型本身的优势呢? 澄清:我对大型/中型项目比对快速黑客更感兴趣。:-)

14
为什么大多数日志文件使用纯文本而不是二进制格式?
日志记录是必需的,但(相对)很少使用。这样,就存储而言可以使其更加紧凑。 例如,最常记录的数据(例如ip,日期,时间)以及其他可以表示为整数的数据将存储为文本。 如果将日志记录存储为二进制数据,则可以保留很多空间,从而需要较少的旋转并增加磁盘寿命,尤其是对于写受到限制的SSD。 有人可能说这是一个很小的问题,实际上并不重要,但是考虑到建立这种机制所需的努力,这是没有道理的。任何人都可以在业余时间里做两天左右的工作,为什么人们不这样做呢?
81 logging  storage 

9
在这种情况下,是否应始终将所需的最少数据传递给函数
假设我有一个IsAdmin检查用户是否为管理员的函数。我们还要说,管理员检查是通过将用户ID,名称和密码与某种规则(不重要)进行匹配来完成的。 在我的脑海中,为此有两个可能的函数签名: public bool IsAdmin(User user); public bool IsAdmin(int id, string name, string password); 我通常会寻求第二种签名,以为: 函数签名为读者提供了更多信息 函数内部包含的逻辑不必了解User类 通常会导致函数内部的代码少一点 但是我有时会质疑这种方法,并且意识到在某些时候它将变得笨拙。例如,如果某个函数将在十个不同的对象字段之间映射成一个结果布尔值,那么我显然会发送整个对象。但是除了这样一个鲜明的例子,我看不到传递实际对象的理由。 对于任何一种风格的论点,以及您可能提供的任何一般性意见,我将不胜感激。 我以面向对象和功能两种风格进行编程,因此应将问题视为关于任何和所有习惯用法。

7
我应该使用依赖注入还是静态工厂?
在设计系统时,我经常面临使其他模块使用大量模块(日志记录,数据库访问等)的问题。问题是,如何将这些组件提供给其他组件。似乎有两个答案可能是依赖注入或使用工厂模式。但是,两者似乎都错了: 工厂使测试变得痛苦,并且不允许轻易交换实现。它们也不会使依赖关系变得明显(例如,您正在检查一个方法,而忽略了它调用的方法会调用使用数据库的方法的事实)。 Dependecy注入使构造函数的参数列表大量膨胀,并且在代码的所有部分涂上了污点。典型情况是一半以上类的构造函数如下所示(....., LoggingProvider l, DbSessionProvider db, ExceptionFactory d, UserSession sess, Descriptions d) 这是我遇到的一个典型情况:我有异常类,这些异常类使用从用户数据库中加载的错误描述,并使用在用户会话对象中具有用户语言设置参数的查询。因此,要创建一个新的异常,我需要一个描述,它需要一个数据库会话和一个用户会话。因此,我注定要在所有方法中拖动所有这些对象,以防万一我可能需要引发异常。 我该如何解决这个问题?


15
为什么干很重要?
非常简单,当我需要做的就是重复几次相同的过程并做一些细微调整后,为什么还要编写适用于所有情况和可伸缩数据的代码? 我不太可能需要在不久的将来再次进行编辑。 看起来要减少很多工作... function doStuff1(){/*.a.*/} function doStuff2(){/*.b.*/} function doStuff3(){/*.c.*/} 如果我需要添加一些内容... function doStuff4(){/*.d.*/} 如果我需要将其删除,则可以将其删除。 很难弄清楚如何将所有这些都变成一个简单的模式,以便我可以将数据输入并处理所有情况,并进行很多我不希望拥有的更改去做。 当看起来像快速剪切+粘贴会减少工作量时,为什么要干呢?
81 code-quality  dry 

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.