SQL Server

使用 C# 进行单元测试 SQL Server OLAP 多维数据集

Mark Nadelson

下载代码示例

我感觉有点像托马斯 · 杰斐逊,当我说,"我们认为这些真理是不言而喻的所有代码都具有某些不可剥夺的权利,这些权利之一是,能够将彻底单元测试简单和简明的方式,以便可以轻松地标识 bug 和最小化的生产中断."是的有些戏剧性,但它获取我的观点。

当然,大多数开发人员认为他们的代码应该是单元测试,但在"代码"的定义模糊时,会发生什么呢? 这是我发现自己在最近,当提出一个复杂的问题和任务是找到解决办法的情况。 一组开发人员被参与编写复杂的联机分析处理 (OLAP) 多维数据集使用 SQL 服务器分析服务 (SSAS)。 此多维数据集有许多维度都绑在极其复杂的事实数据表。 因为开发商是很善于发展的多维数据集,所以他们能够拼凑出多维数据集,但验证其多维表达式 (MDX) 查询的结果,是一个艰巨的任务。 困难被雪上加霜的若干因素,包括的数据量在维度和事实数据表,以及时间和计算生成多维数据集所需的资源。 一旦该多维数据集被修造了,结果 (产生的 MDX 查询) 被发送给用户。 如果用户发现数据的问题,它会花很长的时间来追踪问题。 此外,一旦基本的问题是发现和固定,该多维数据集将需要重新生成。 使事情更糟,如果维度添加、 更新的基础事实数据表或生成多维数据集是使用不同的聚合,没有办法确定这些更改的完整效果。 看似无辜的更改可能影响深远和级联对产生影响对多维数据集的查询。

用于多维数据集的难题的解决方案是架构的创建一个环境和过程,其中你可以阶段多维数据集的维度和事实使用有限的数量的数据,并执行针对使用多维数据集的生产版本的多维数据集的查询。 理想的情况是多维数据集的测试版本会从头开始创建每次运行单元测试,消除副作用发生从预现有项目的机会。 单元测试框架的其他要求 (和真的这些适用于大多数的单元测试框架的目标应用程序无关),以确保测试验证可重复,并快速、 轻松地到发生故障时查明测试失败 (有说"失败,因为数据不匹配"是不甚理想的测试用例) 的原因。

在本文中,我将介绍一种框架,使您可以创建一套的单元测试,以验证 OLAP 多维数据集的 MDX 基于输出。 所述的体系结构允许使用现有的架构中,每次运行该测试套件时重新创建它自己的单元测试数据库内的多维数据集的创建。 它还允许您提供执行针对新组成的单元测试版本的多维数据集的 MDX 查询。 进一步,它将验证结果与预先存在的模板,然后将它们提供简单的 HTML 格式。 这一模式的测试用例验证针对模板可以扩展为数据结果在大型和复杂的单元测试的框架。

多维数据集概述

在深入多维数据集测试问题的解决方案之前, 我会简要地去的概念和组件,包括一个多维数据集。 多维数据集是数据在数据仓库内举行快速访问的一种手段。 多维数据集组织和汇总的数据到多维结构。 多维数据集是 OLAP 技术的主要组件,提供易于使用的机制,以快速和可预测的响应时间数据查询。 多维数据集的维度数据和措施 (数值事实) 组成。 在多维数据集中的核心表被称为事实表,和它是源多维数据集的措施。 维度表所引用的事实表,和它们包含层次结构级别的可以查询的信息。 维度层次结构可以让用户在高级别上提问。 然后,使用该维度的层次结构,用户可以获得更多详细信息。

多维数据集包含在一个数据库内。 使给定数据库的多维数据集结构的对象如下:

  • 数据源:这些都是信息的要加载到该多维数据集的来源。
  • 采取的措施:这些都是代表在多维数据集的数字值。 他们可以是日期,但它们通常是数字具有不同级别的聚合 (如 Sum、 Max、 Min 和计数)。
  • 尺寸:这些措施与关联的属性。 业务数据、 客户名称和地理区域是维度的常见示例。
  • 分区:分区定义事实数据加载到一个度量值组的一部分。 通过创建多个分区,该多维数据集可以并行处理和存储,并质疑分开,从而提高性能。 你也可以重新单独的分区处理而不会影响其他分区。
  • 多维数据集角色:每个多维数据集应该有至少一个多维数据集角色以允许最终用户访问。 角色可以允许访问所有数据或基于单个的用户 ID 或 Active Directory 组的多维数据集内存储的数据的一个子集。

定义的多维数据集的架构可以从 SSAS 中的 XML 形式的分析 (XMLA) 提取。 XMLA 是一种基于 SOAP 的 XML 协议,通过 HTTP 访问该多维数据集。 XMLA 定义前面所述的五个多维数据集对象的每个包含的所有详细信息。 XMLA 允许您快速、 轻松地重新创建不同的数据库或服务器上的多维数据集。 它是由其创建单元测试的多维数据集的基石。

一旦创建和处理多维数据集,可以使用一个混合和匹配的维度用于创建它的各种查询数据的措施。 与上述 MDX 语法查询的多维数据集。 像 SQL 查询,MDX 查询中包含一个数据请求 (使用的 SELECT 语句)、 (使用 FROM 语句) 的数据点和一个可选的数据筛选器 (使用 WHERE 子句)。 这里是一个基本示例:

    SELECT {[<axis specification using Measures>]...} ON AXIS(0),
           {[<axis specification using a dimension hierarchy>]...} ON AXIS(1)
    FROM [<cube>]
    WHERE (<filter specification>)

示例销售多维数据集

我的示例多维数据集,使您可以快速创建查询各门店的销售数据的各类客户的不同日期 (见图 1)。

Example Sales Cube Database Diagram
图 1 示例销售多维数据集数据库关系图

多维数据集是连接到一个事实表的四个维度表组成。 为简单起见,事实数据表包含调用数量,表示给定项目向客户销售某给定在存储区的位置在一个给定的购买日期上的量的一项措施。 使用此多维数据集配置,用户可以快速查询使用各种尺寸的各种事实。 例如,公司高管在哪个商店,可以弄的清楚其中的产品销售或他们可以深入的细节如哪些项目最好卖在特定年份或月份期间。 有一大批尺寸允许执行查看中以各种方式,提供更深入的存储性能的销售数据。

创建多维数据集的单元测试版本

如所述,可以从 SSAS XMLA 文档的窗体中提取的多维数据集定义。 此 XMLA 文档用于创建多维数据集的单元测试版本。 使用多维数据集的生产定义可确保测试将准确行使问题的多维数据集的所有功能。 你接口用 SSAS 引擎使用 Microsoft.AnalysisServices.dll,可以发现在 SQL 服务器 SDK 程序集。

用于生成多维数据集的对象是 XMLAtoCube。 构造函数采用在 XMLA 存储基本配置目录。 我选择了房子 XMLA 多维数据集的目录结构是 < 基目录 > \ < 生产服务器名称 > \­< 生产数据库名称 >。

XMLAtoCube 包含一个公共方法,CreateCubeFromXMLA,参数如下 (请参阅中的该方法的代码上市 1 中附带的代码下载中的 Listings.zip 文件):

  • SourceServerName:生产服务器,其中包含该多维数据集的名称。
  • TargetServerName:将房子该多维数据集的单元测试版本的服务器的名称。
  • SourceDatabaseName:生产数据库,其中包含该多维数据集的名称。
  • TargetDatabaseName:将房子该多维数据集的单元测试版本的数据库的名称。
  • DataSourceProviderDefinition:多维数据集的单元测试版本指向其源维度和事实数据表的位置的 URL 连接字符串。 这将是该单元测试的缩减数据源。

CreateCubeFromXMLA 首先建立一个到单元测试分析服务器的版本的连接和滴眼液的多维数据集数据库单元测试版本,如果它已经存在。 数据库的滴很重要,因为它可确保在一个清洁的环境,没有任何残留文物 contam 上进行测试的­inating 成果。 在 ConnectToServer 方法中使用的 Microsoft.AnalysisServices.Server 实例执行到分析服务器的连接。 Server.Connect (< 连接字符串 >) 使用单元测试服务器名称传递在呼吁建立的连接 (请参阅上市 2 代码下载中)。 一旦成功地建立服务器连接,如果它存在,则被删除的多维数据集数据库单元测试版本。 此删除已完成的 DropDatabase 方法,传递给已连接的服务器实例和要除去 (TargetServerName) 的单元测试数据库的名称。 DropDatabase 可确保服务器实例连接、 查找 Microsoft.Analysis­Services.Database 使用单元测试的数据库名称传递中和,如果不存在数据库 (数据库实例不是 null),数据库删除 (见上市 3 代码下载中)。

下一步是把原始多维数据集的 XMLA 定义和生成的单元测试版本。 单元测试版本包含相同的维度、 维度层次结构、 措施、 分区、 等作为原始多维数据集角色。 不同的是它生成在新数据库中指向其源数据的不同位置。 AddCubeToDatabase 方法创建测试多维数据集 (请参见上市 4 代码下载中)。 AddCubeToDatabase 从使用前面提到的命名约定的文件系统中读取的 XMLA 定义。 XMLA 文件名传递给 XmlTextReader 的实例在施工。 XMLA 是阅读使用 Microsoft.AnalysisServices.Utils.Deserialize 方法,通过 XmlTextReader 和 Microsoft.AnalysisServices.Database 的一个新创建的实例。 数据库对象实例现在包含完整定义的多维数据集,但这一定义仍有原始多维数据集的数据库的名称和数据源。 只需指向单元测试数据库涉及设置的名称和 ID 属性的"数据库单元测试的数据库名称"(targetDatabaseName) 参数。 此数据库然后可以通过调用 Server.Databases.Add (< 单元测试数据库 >) 其次是 Database.Update 方法添加到单元测试分析服务器的实例。

创建了数据库之后,您需要更新多维数据集的数据源为外部的单元测试的数据集合。 数据库实例都有一个数据源实例 (通常只是一个数据源是与多维数据集相关联的) 列表和单元测试的连接字符串用来替换 XMLA 定义范围内所包含的连接字符串。 连接字符串将被替换后,调用 DataSource.Update 方法更新它在 SSAS 服务器内。 此时,完成 XMLA 定义的自定义,并且更新和处理该多维数据集 (DataSourceView、 维度和多维数据集) 的其余部分。

对 AddCubeToDatabase 的调用完成后,在指定的服务器使用的空房的单元测试数据库内已经创建的多维数据集单元测试版本。 它指向一组自定义的源数据。 虽然已创建了多维数据集,但却仍然为空。 以填充与源数据的尺寸,尺寸必须进行处理。 调用 ProcessDimensions 方法并将其传递到数据库实例。 在数据库中的所有维度都处理使用 Dimension.Process(ProcessType.ProcessFull) 方法。 一旦成功处理后尺寸,使用 ProcessCube 方法处理的多维数据集内的单元测试数据库。 像 ProcessDimensions,ProcessCube 需要的数据库实例,在数据库中的所有多维数据集进行循环并调用 Cube.Process(ProcessType.ProcessFull) (见上市 5 代码下载中)。 此时,已创造和有针对性的测试数据填充多维数据集中的单元测试。 下一步是运行测试,以确保多维数据集的行为与预期相同。

验证该多维数据集

虽然用于验证的解决方案针对多维数据集,正在使用的设计模式可以适用于其他无单元测试框架。 采用的模式使用模板验证测试。 简单地说:当测试运行时,包含结果的数据结构的创建和验证针对以前存储的版本的被认为是正确的数据结构。 因为它很难验证的二进制数据结构,结构的 HTML 表示形式被提交给单元测试工具。 测试人员使用的 HTML 表示形式来验证的单元测试 (以确保结果匹配什么预期) 最初的测试结果,并审查是什么导致单元测试在后续运行失败。 出现故障,在 HTML 显示的原始数据结构作为结构以及哪种数据验证失败,为什么。 这是帮助调试问题的关键。

测试大多数情况下的最佳方法使用"黑箱"的测试方法。 黑箱测试传递的输入,并验证输出。 因为多维数据集的输出是一个查询结果,输入的是查询。 您可以使用 MDX 语句来查询多维数据集。 将解释 MDX 查询的多维数据集后,它会返回一个结果。 其结果是以行和列的尺寸为运行 MDX 查询选择的表示形式。 MDX 查询结果可能非常复杂,因为该查询可以涉及多个维度,造成各式各样的行和列在输出中。 数据结构选择要保存多维数据集数据是 CubeRow 实例的多维数据集行的名称由键控的字典。 CubeRow 类包含两个替代数据结构 — 使用取决于形势。 一个数据结构是列的一个 CubeTuple 实例的多维数据集的名称由键控的字典。 CubeTuple 是只是一个对象,其中包含多维数据集的列的名称和给定的列的值。 当给定多维数据集的列包含的值,使用字典的 CubeTuble 对象。 第二个数据结构是另一个字典,将行名称映射到一个 CubeRow 实例。 因为 MDX 查询可以有很多级别的行尺寸,CubeRow 包含它自己的行名称和 CubeRow 实例的字典。

不只是存储在字典 < 字符串、 CubeRow > 中的多维数据集的结果 实例,结果还存储在 HTML 字符串中。 HTML 字符串允许测试人员具有可视化表示形式的多维数据集的结果。 HTML 表中包含多个级别的列和行标题,和 HTML 表格单元格包含 MDX 值。 图 2 显示 MDX 查询结果的 HTML 表示形式的布局。

图 2 的 MDX 查询结果的 HTML 表示形式的布局

   

列维度

标题 1 (值 1)

列维度

标题 1 (值 1)

列维度

标题 1 (值 2)

列维度

标题 1 (值 2)

   

列维度

标题 2 (值 1)

列维度

标题 2 (值 2)

列维度

标题 2 (值 1)

列维度

标题 2 (值 2)

行维度

标题 1 (值 1)

行维度

标题 2 (值 1)

MDX 结果值 MDX 结果值 MDX 结果值 MDX 结果值

行维度

标题 1 (值 1)

行维度

标题 2 (值 2)

MDX 结果值 MDX 结果值 MDX 结果值 MDX 结果值

行维度

标题 1 (值 2)

行维度

标题 2 (值 1)

MDX 结果值 MDX 结果值 MDX 结果值 MDX 结果值

行维度

标题 1 (值 2)

行维度

标题 2 (值 2)

MDX 结果值 MDX 结果值 MDX 结果值 MDX 结果值

BaseMDXTest 包含用于执行 MDX 查询和生成 MDX 结果的数据结构,以及代表 XML 代码。 BaseMDXTest 使用 Microsoft.Analysis­Services.AdomdClient.dll,在 SQL 服务器 SDK 程序集,若要连接到的 SSAS 多维数据集和执行的 MDX 查询中找到。 BuildTemplate 是运行 MDX 查询的方法,生成 MDX 导致词典,以及 HTML 表示形式。 第一,建立多维数据集的连接。 为了建立和打开的连接,连接字符串传递给 MicrosoftAnalysisServices.AdomdClient.AdomdConnection 的一个实例。 调用 Open 方法,是然后在新创建的连接实例上,并连接实例返回给调用方。 一旦创建一个连接,一个实例 MicrosoftAnalysis­Services.AdomdClient.AdomdCommand 方法设立和 MDX 查询字符串和 AdomdConnection 实例传递。 对 AdomdCommand.ExecuteCellSet 方法的调用执行针对的单元测试版本的多维数据集的 MDX 查询,并返回一个 MicrosoftAnalysisServices.AdomdClient.CellSet 实例 (请参见上市 6 代码下载中)。

检索单元格集实例后,进行检查,以确保结果集具有两个轴。 轴 0 包含的列和轴 1 包含的行。 每个轴包含位置对象的集合。 位置表示给定的轴上的元组,并包含一个或多个成员对象中。 成员表示的行或列的标头的给定位置 (请参见上市 7 代码下载中)。

下一步,计算行和 MDX 查询所返回的列的数目。 这是通过采取的行 (对象的计数的位置上轴 1) 数加上的列尺寸 (CellSet.Axes[0]。[0] 的立场。Members.Count)。 因为当以二维表的形式表示的 MDX 结果,列的一组行中包含的列数被添加到行。 同样,通过考虑在 0 轴上的位置对象的数目加行维度数目计算的列数 (见上市 8 代码下载中)。

鉴于的行和列数,可以生成 CubeRow 字典对象以及 MDX 输出的 HTML 表示形式。 清单 9 下载的代码中包含的代码遍历 MDX 结果集、 创建 HTML 并将结果存储在 CubeRow Dictionary 中。 第一,被遍历的行数。 如果行数大于列维度数目,它是已知新行的 MDX 结果是可用。 换句话说中的列标题行已获得通过,MDX 数据时可用。 此时,创建一个新的 CubeRow 对象。

下一步是要依次通过每个行中的列。 如果当前行数比列的维数低,当前行是实际上的列标题的行。 字典,标题的标题被连接的每个列的位置,用冒号分隔。 这意味着如果一个标头的多个维度组成,每个列将其连接起来与给定维度按降序排列的决议。 HTML 代为列标题是更为直截了当。 维度标题简单地包围着 HTML 表格标题标记 (< th >< 裤子 >)。 对于每个情况下,当前的维度标题检索通过获取标头轴 (CellSet.Axis[0]) 和访问的列位置 (当前列数减去当前行维度计数) 和在该位置 (当前行计数) 内的当前成员。

如果当前行数大于列尺寸,然后列标题的数量不再正在处理中。 相反,MDX 结果集的行元组下一步都在排队等待处理。 类似于列,有标头,MDX 结果集的行也可能有标题。 如果正在处理的列编号小于行维度数目,然后行标题正在处理。 为每个行标题,一本新字典 < 字符串,CubeRow > 创建、 添加到当前词典并设置为当前 MDX 结果字典。 这意味着对于每个行标题,存在的行包含更多颗粒状的 MDX 结果数据的字典。

提取的行标题标题是类似于提取的列标题标题。 行标题从检索当前列位置从 CellSet.Axis[1 中的当前行的位置上的成员对象]。 行标题是向 CubeRows 字典的键,如果当前 CubeRow 字典没有提取的行标题,CubeRow 对象添加到由行标题键控的词典。 如果行标题不存在当前 CubeRow Dictionary 内,CubeRow 对象检索,并将设置为 currentCubeRow。

后行标题成员已经用尽 (就是当前的列数大于行的维数) 和列标题行都被遍历 (就是当前的行计数大于列维度数目),它是将 MDX 单元格的值添加到当前的 CubeRow 对象的时间。 每个列标题与列的值的组合被认为组成 CubeTuple 的单个实例。 每个 CubeRow 包含列标题由键控的 CubeTuple 对象的字典。 从以前建造的列标头的数组中检索的列标题 (记得一个列标题是结肠-­分隔字符串串联在一起的所有列标题)。 列标题的索引是当前的列数减去行维度 (总列数包括行维度) 的数量。 MDX 单元集的当前值检索通过访问相应的二维 (列、 行) 点。 这基于当前的列数 (减去行维度的数量) 和 (减去列尺寸的数目) 的当前行计数。 此值被添加到使用 AddTuple 方法,传递给它的列标题和列的值的 CubeRow 对象。 同时,通过添加在 HTML 表维度 (< td ><: 次 >) 标记 MDX 单元格的值更新的 HTML 表示形式。 请参阅图 3 < 字符串,CubeRow > 字典的图形表示形式。

模板的字典和 HTML 表示保留到以前定义的文件位置,使用 BaseMDXTest.PersistTemplate 方法。 因为模板需要手动验证由单元测试开发人员、 测试被认为已经失败了,这就是为什么 BaseMDXTest.TestMDXQuery 方法返回 false 的成功。

A Graphical Representation of the CubeRow Dictionary
图 3 CubeRow 字典的图形表示

一旦创建了模板,随后再运行相同的测试将验证以前存储的模板。 当调用 TestMDXQuery 方法时,检查第一次,以查看是否存在一个具有给定名称的测试。 如果它不会和创建新的模板不请求 (请求重新创建模板时可能会出现当前的模板不正确),然后测试结果模板加载到内存。 该模板包含的对象表示形式和 MDX 结果集的 HTML 表示形式。 BaseMDXTest.RunComparison 方法执行 MDX 查询,并对已存储的模板结果进行比较。 因为他们是在模板的创建过程相同的方式遍历 MDX 查询结果。 原始模板的创建和验证对该模板的主要区别是而不是创建 < 字符串,CubeRow > 词典,查找这样的是针对模板字典,检查以查看是否存在相同的 MDX 查询结果。 当循环的行和列,HTML 表创建相同的方式在模板的创建,期间除了现在上色的 HTML 表中的单元格。 绿色的单元格指示单元格匹配原始模板 ; 红色单元格显示不匹配。 通过着色单元格并提出它们在一个 HTML 表,单元测试仪已测试用例通过或未通过为什么立即查看。 随时找到不匹配时,一个布尔值 (testPass) 设置为 false,指示该测试用例失败。

同时遍历 MDX 查询的结果和验证他们反对模板字典,每个 CubeTuple (包含列的维度、 串联的名称和列的值的对象) 发现从当前 CubeRow Dictionary 的 CubeTuple 对象中删除。 因此,通过整个 MDX 查询结果后,原始模板词典应具有 CubeRow 对象与空字典的 CubeTuple 对象,如果 MDX 结果是一个完整的匹配。 否则新的 MDX 查询结果了,包含在原始的结果内的数据丢失。 BaseMDXTest.CheckForExtraDataInTemplate 方法为剩余的 CubeTuple 对象,执行以递归方式,检查的模板词典和如果 CubeTuple 对象仍然存在,则返回值为 true。 TestPass 在 RunComparison 方法中的布尔值设置为 false 如果发现额外的数据,并且该测试用例失败。

在 MDX 后结果已完全遍历和针对模板词典,该多维数据集的一个实例验证­ComparisonResult 对象返回。 它是由 testPass 的布尔值和显示结果的 HTML 表构造。 BaseMDXTest.TestMDXQuery 方法使用 CubeComparisonResult 来生成一个 HTML 页面,显示原始的 MDX 查询的结果 HTML 表和比较 HTML 表。 HTML 保存到文件系统通过执行调用 BaseMDXTest.PersistTestReport 方法,创建 TestReport.html 摘要列出网页所有测试运行和他们的 HTML 的链接会导致页面,以及通过和未通过的测试用例数目的摘要。

测试采购多维数据集

使用多维数据集测试框架的两个部分 — 多维数据集创建代码 (XMLAtoCube) 和 MDX 查询结果模板 (BaseMDXTest) — 您可以创建验证该多维数据集的单元测试用例。 尽管为框架的代码是广泛的创建测试用例是简单和直接。 清单 10 下载在代码中包含示例验证采购多维数据集的单元测试。 这些测试用例使用 Microsoft 测试框架,但可以纳入任何测试框架。

从 BaseMDXTest 继承的单元测试对象 (在该示例中的 PurchaseCubeTest)。 PurchaseCubeTest 的默认构造函数构造 BaseMDXTest 与多维数据集所在的 SSAS 服务器和要在其中存储的 MDX 查询结果模板和后续的测试结果的基目录的 URL。

[TestInitialize] 的一种方法用于创建采购多维数据集的单元测试版本。 它使用 XMLA 原始多维数据集的定义和使用单元测试数据库 (targetDatabaseName) 在单元测试 SSAS 服务器 (targetServerName) 上创建它。 它还指向源数据 URL 到测试维度和事实数据的位置。 [TestInitialize] 只运行一次为给定的 [TestClass],仅在测试开始时,确保该多维数据集创建。

测试用例本身是执行 [TestMethod] 内的附加说明的方法。 每个测试用例是简单的。 MDX 查询定义,然后使用继承的 BaseMDXTest.TestMDXQuery 方法,命名该测试用例和传递给它的 MDX 查询执行。 TestMDXQuery 返回如果测试通过,则 true 或 false,如果不是,并使用 Assert.IsTrue 方法通过或失败的单元测试。 已运行的所有测试后,可以打开生成的 HTML 测试文档,可以检查故障测试用例。 图 4 包含一个示例 HTML 输出的测试之一。

The HTML Output of an Example Test
图 4 的示例测试 HTML 输出

正确测试过的代码

虽然它不是简单,甚至一个 OLAP 多维数据集可以是单元测试使用的 C#。 列入 Microsoft.AnalysisServices.dll 和 SQL Server 程序集内的 Microsoft.AnalysisServicesAdomdClient.dll 文件为您提供了创建和查询 SSAS 多维数据集的 Api。 提出的体系结构允许您添加一组丰富的单元测试生成可读的格式输出,所以可以快速确定测试用例失败。 测试用例验证由模板的方法可以应用于其他输出验证不是简单的单元测试体系结构。 这些范围从依赖传统的关系数据库持久性在该模板中包含数据的应用程序示例预期将存储在数据库中以后运行的应用程序 UI 的应用程序 UI 的状态存储在一个数据结构,并在 HTML 表单中显示用户界面。

我不相信如果托马斯 · 杰斐逊或我们的国父会比较自由的一个国家权利的正确测试的代码,但我敢肯定您的用户和监事会高兴地知道您的应用程序正确穿其步。

Mark Nadelson 是一个专业的软件开发者 22 年的电信、 互联网和金融行业的经验。在他的职业生涯他已使用了大量的编程语言,包括程序集、 C、 c + +、 Java 和 C#。Nadelson 也是作者的两本书和大量的技术文章。

衷心感谢以下技术专家对本文的审阅:David Neigler (SAC 资本顾问 LP) 和乔 Sampino(SAC Capital Advisors LP)
David Neigler 是发展金融服务公司的经理,在 SAC 资本顾问 LP 工作。他的工作重点是解决大数据所做的交易量很大的金融公司面临的问题的系统的发展。

Joe Sampino 在 SAC 资本顾问 LP,发展中国家企业商务智能平台的大型银行和投资公司工作。他创建和管理数据仓库、 多维数据集 SQL 服务器分析服务,以及数据分析/报告系统、 内部、 外部监管和法规遵从性的需求."