计算机科学中的数学探索

8
我在软件行业工作了两年。以下是我困惑的一些事情:
1. 当前软件行业缺乏数学应用。 例如:当机械工程师设计电力杆时,他使用应力分析技术(阅读数学方程式)计算基础上的应力,以确定应使用何种类型和等级的钢材。但是,当软件开发人员部署Web服务器应用程序时,他只是猜测服务器上的估计负载,并将其余的留给运气和上帝,没有任何他可以用来模拟数学上回答他的问题的东西(我的观察)。
2. 有很多优秀的软件(如风洞模拟器等)和计算程序(如MATLAB等),可以模拟现实世界中的问题(因为它们有它们的数学方程式),但我们在软件行业仍然不知道我们的服务器端应用程序实际部署时需要多少实际资源,例如内存、计算资源、时钟速度、RAM等等。我们只是继续猜测解决方案,并通过更多或更少的“试错”来解决这些问题(我的观察)。
3. 编程是在API上完成的,无论是在C、C#、Java等语言中。我们永远无法准确检查我们的代码复杂性和效率,因为我们在某个地方使用了由其他人编写的抽象层,其源代码要么没有,要么我们没有时间去检查它。 例如,如果我在C#或Java中编写一个简单的客户端服务器应用程序,我永远无法预先计算出这段代码的效率和复杂性将是多少,或者整个客户端服务器应用程序将需要的最低要求是什么(我的观察)。
4. 负载平衡和可扩展性分析过于模糊,仅通过添加更多节点来解决服务器上的请求增加问题(我的观察)。
请回答我上述令人困惑的观察。请附上相关参考资料。
如果有人证明我错了并展示了正确的方法,我会很高兴。
提前致谢,
Ashish

应该是社区维基。 - Paul Sasik
3
这是一个真正的问题,非常合理。 - Eric J.
2
Eric J.,这涉及编程且可能适合社区Wiki,但是没有明确的问题。我不喜欢纠缠于语义,但它们在了解如何回答问题方面起着重要作用。"我困了"和"我怎么才能不那么困?"或者"为什么我经常感到困倦?"或者"人们通常如何预防瞌睡?"是不同的问题。 - Drew Dormann
1
我认为这是一个值得讨论的合理话题,尽管有些宽泛和模糊。它可能应该是社区维基,因为它不是一个具有明确定义正确答案的问题。 - Brian Campbell
12个回答

6
我认为有几个原因。其中一个是在许多情况下,只需完成工作比尽可能使其性能更好更重要。我编写的许多软件只会在小数据集上偶尔运行,或者对性能影响相当微不足道(它是一个循环,在每个元素上执行固定计算,因此它是微不足道的O(n))。对于大多数此类软件,花费时间详细分析运行时间是愚蠢的。
另一个原因是软件非常容易以后更改。一旦建立了一座桥梁,任何修复都可能非常昂贵,因此在进行设计之前最好非常确定。在软件中,除非您早期做出了可怕的架构选择,否则通常可以找到并优化性能热点,一旦您拥有一些更多关于其性能的真实世界数据。为了避免这些可怕的架构选择,通常可以进行近似的口袋计算(确保您没有在大数据集上使用O(2^n)算法,并估计您需要多少资源来处理您预期的最重载荷,大约估计10倍)。这些确实需要一些分析,但通常可以很快地进行。

有时你确实需要挤出系统的最终性能。在这些情况下,人们通常会坐下来,分析他们正在使用的系统的性能特征,并进行非常详细的分析。例如,可以查看 Ulrich Drepper 的非常出色的论文 《程序员应了解的有关内存的一切》(pdf)


2
思考工程科学,它们都有非常明确的定律适用于物理项目的设计和建造,例如重力、材料强度等。而在计算机科学中,当涉及到应用程序构建时,并没有太多明确定义的法则。
我可以想到很多编写简单的“hello world”程序的方法来满足需求。然而,如果我必须建造一个电力杆,我会受制于物理世界和杆的要求。

2

逐点解析

  1. 一个电力杆必须经受住天气、负载、腐蚀等因素的考验,这些可以被量化和建模。但我不能量化我的网站发布成功率或我的数据库将如何增长。

  2. 过早优化?好的就是好的,需要时再修复。如果你是供应商,你不知道真实环境中会运行你的代码,也不知道它如何配置。同样,你无法量化它。

  3. 见第1点。我可以根据需要添加。

  4. 继续...即使工程师也会出错。桥梁坍塌、停电、汽车安全召回、"错误的雪"等等。我们是否应该把问题改为“为什么工程师不使用更多经验观察?”


1
大多数情况下,为了获得有意义的测量结果(以及被接受的等式、限制、容差等),就像在现实工程中一样,你首先需要一种测量你所关注的对象的方法。
其中的大多数事物都不能轻易地进行测量——软件复杂性是一个经典问题,什么是“复杂”?如何查看源代码并确定它是否复杂?McCabe的圆形复杂度是我们目前拥有的最接近于标准的方式,但它基本上只是计算方法中的分支指令数。

0

软件程序中很少涉及数学,因为程序本身就是方程式。在实际运行之前,不可能计算出方程式。工程师使用简单(和非常复杂)的程序来模拟现实世界中发生的事情。模拟一个模拟器非常困难。此外,计算机科学中许多问题甚至没有数学答案:例如旅行推销员问题。

许多数学知识也内置于编程语言和库中。如果您使用哈希表来存储数据,则可以在常数时间O(1)内找到任何元素,无论哈希表中有多少元素。如果您将其存储在二叉树中,则需要更长的时间,具体取决于元素数量[如果我记得正确,则为0(n^2)]。


1
旅行推销员问题确实有答案,只是它属于一类我们无法高效获得答案(而且我们也相当怀疑我们能否)的大型问题之一。停机问题被证明是无法回答的。 - David Thornley
TSP肯定有答案,但是在假设P!=NP的情况下,它不能由确定性图灵机在多项式时间内计算出来。也许你想到的是停机问题?http://en.wikipedia.org/wiki/Halting_problem - jakber

0
问题在于软件与其他由人类编写的软件进行交流。您所描述的工程示例涉及恒定的物理现象。如果我开发了一个电气模拟器,全世界的人都可以使用它。如果我为我的服务器开发协议X模拟器,这将对我有所帮助,但可能不值得这样做。
没有人能够从零开始设计系统,编写半常见库的人通常有很多增强和扩展工作要做,而不是为其库编写模拟器。
如果您想要一个网络流量模拟器,您可以找到一个,但它不会告诉您关于服务器负载的信息,因为流量不会使用您的服务器理解的协议。每个服务器将看到完全不同的流量集。

0
当前软件行业缺乏数学应用。例如:当机械工程师设计电力杆时,他使用应力分析技术(即数学方程)计算基础的应力,以确定应该使用何种和何级别的钢材。但是,当软件开发人员部署Web服务器应用程序时,他只是猜测服务器的预估负载,并将其余部分留给运气和上帝,没有任何东西可以在数学上模拟来回答他的问题(这是我的观察)。
我不会说运气或上帝总是负载估计的基础。通常可以获得现实数据。
也不是说没有数学技术来回答这个问题。运营研究和排队理论可以被很好地应用。
真正的问题是,机械工程基于物理定律和几千年的经验和科学研究基础。计算机科学只有我这么老。到你的孩子和孙子应用当今最佳实践时,计算机科学将会更加先进。

0

1) 大多数业务逻辑通常被分解成决策树。这是应该通过单元测试进行验证的“方程式”。如果输入x,则应该得到y,我在这里看不到任何问题。

2,3) 分析可以提供一些关于性能问题所在的见解。在大多数情况下,您不能说软件将需要x个周期,因为随着时间的推移(即数据库变得更大,操作系统开始出现故障等),这将发生变化。例如,桥梁需要不断维护,您不能只是建造一个并期望它在不花费时间和金钱的情况下持续50年。使用库就像不必每次想要找到圆的周长时都要计算π一样。它已经被证明是有效的(并且具有成本效益),因此没有必要重新发明轮子。

4) 对于大多数Web应用程序,水平扩展(多台机器)很好。垂直(多线程/多进程)扩展往往更加复杂。添加机器通常相对容易且具有成本效益,并避免一些很容易受限制的瓶颈(磁盘I/O)。此外,负载均衡可以消除一个机器成为中心故障点的可能性。

这并不是什么高深的科学,因为你永远不知道有多少消费者会来到服务线。通常情况下,拥有过多的容量总比出现错误、激怒顾客以及被某人(通常是你的老板)责备要好。


0
一个麻省理工学院电子工程专业的毕业生不会有这个问题 ;)

0

我的想法:

1. 有些人确实会应用数学来估算服务器负载。对于许多应用程序而言,方程非常复杂,许多人都会采用经验法则、猜测和调整或类似的策略。一些应用程序(实时应用程序,失败的惩罚很高...例如武器系统、发电厂控制应用程序、航空电子学)会仔细计算所需的资源,并确保在运行时可用。 2. 同1. 3. 工程师还使用其他人提供的具有公开接口的组件。想想电气工程学。通常你不关心晶体管的内部情况,只需要关注其接口和操作规格。如果您想要检查您使用的每个组件及其所有复杂性,则将受到一个人能够完成的限制。 4. 我编写了相当复杂的算法,根据各种因素(如内存消耗、CPU负载和IO)确定何时进行扩展。然而,最有效的解决方案有时是测量和调整。特别是当应用程序复杂且随时间演变时,这点尤其正确。数学建模(并随时间更新该模型)所投入的努力可能超过了通过尝试和纠正方法损失效率的成本。最终,我可以设想对代码与其执行环境之间的相关性有更好的理解会导致能够提前预测资源使用的系统。由于我们今天还没有这样的系统,许多组织在广泛的情况下对代码进行负载测试以经验性地收集信息。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接