当前位置: 首页 > 编程日记 > 正文

了解 C# “.NET研究”4 中的 Dynamic 关键字

  dynamic 关键字和动态语言运行时 (DLR) 是 C# 4 和 Microsoft .NET Framework 4 中的重大新增功能。 这些功能在宣布时就引起了人们的极大兴趣,并伴随着许多疑问。 同时人们也给出了很多答案,但这些答案现在已散布于各种文档以及各种技术博客和文章之中。 这样,人们在各种论坛和会议上总是一遍又一遍地提出相同的问题。

  本文全面概述了 C# 4 中新增的动态功能,并且深入探讨了这些功能如何同其他语言和框架功能(例如反射或隐式类型化变量)一起使用。 鉴于已有大量信息可用,我有时会重新使用一些经典示例,并提供指向原始源的链接。 我还将提供指向相关内容的大量链接,供您进一步阅读。

  什么是“动态”?

  编程语言有时可划分为静态类型化语言和动态类型化语言。 C# 和 Java 经常被认为是静态类型化语言的例子,而 Python、Ruby 和 JavaScript 是动态类型化语言的例子。

  一般而言,动态语言不执行编译时类型检查,仅在运行时识别对象的类型。 这种方法有利有弊:代码编写起来往往更快、更容易,但同时,由于您不会获得编译器错误,只能通过单元测试和其他方法来确保应用程序正常运行。

  C# 最初是作为纯静态语言创建的,但 C# 4 添加了一些动态元素,用以改进与动态语言和框架之间的互操作性。 C# 团队考虑了多种设计选项,但最终确定添加一个新关键字来支持这些功能:dynamic。

  dynamic 关键字可充当 C# 类型系统中的静态类型声明。 这样,C# 就获得了动态功能,同时仍然作为静态类型化语言而存在。 若要了解为何以及如何做出了这样的决定,请参考 PDC09 (microsoftpdc.com/2009/FT31) 上由Mads Torgersen 撰写的演示文稿“C# 4 中的动态绑定”。 尤其是,动态对象被认定是 C# 语言中的“一等公民”,因此没有用于打开或关闭动态功能的选项,并且没有向 C# 添加过类似于 Visual Basic 中的 Option Strict On/Off 之类的功能。

  当您使用 dynamic 关键字时,您就告诉编译器关闭编译时检查。 网上以及 MSDN 文档中 (msdn.microsoft.com/library/dd264736) 有大量关于如何使用该关键字的示例。 下面是一个常见示例:

dynamic d = "test";
Console.WriteLine(d.GetType());
// Prints "System.String".
d = 100;
Console.WriteLine(d.GetType());
// Prints "System.Int32".

  如您所见,可以将不同类型的对象分配给已声明为 dynamic 的变量。 这段代码会通过编译,并在运行时确定对象的类型。 不过,下面的代码也会通过编译,但在运行时会引发异常:

dynamic d = "test";
// The following line throws an exception at run time.
d++;

  原因是相同的:编译器不知道该对象的运行时类型,因此无法告诉您递增操作在此情况下不受支持。

  缺少编译时类型检查也会导致 IntelliSense 功能无效。 由于 C# 编译器不知道对象的类型,因此它无法枚举该对象的属性和方法。 正如在用于 Visual Studio 的 IronPython 工具中那样,通过附加的类型推断可能会解决此问题,但目前 C# 不提供这种类型推断。

  但是,在许多可能获益于动态功能的方案中,由于代码使用了字符串文本而导致 IntelliSense 还是不可用。 本文在后面将对这一问题进行更详细的讨论。

  Dynamic、Object 还是 Var?

  那么,dynamic、object 和 var 之间的实际区别是什么?何时应使用它们? 下面是每个关键字的简短定义和一些示例。

  关键字 object 表示 System.Object 类型,它是 C# 类层次结构中的根类型。 此关键字经常在编译时无法确定对象类型时使用,而这种情况经常在各种互操作性情形中发生。

  您需要使用显式转换将已声明为 object 的变量转换为特定类型:

object objExample = 10;
Console.WriteLine(objExample.GetType());

  显然,这将输出 System.Int32。 但是,因为静态类型为 System.Object,所以您在这里需要一个显式转换:

objExample = (int)objExample + 10;

  您可以赋予不同类型的值,因为它们都是从 System.Object 继承的:

objExample = "test" 

  从 C# 3.0 起,关键字 var 开始用于隐式类型化局部变量以及匿名类型。 此关键字经常与 LINQ 结合使用。 当使用 var 关键字声明变量时,将在编译时根据初始化字符串推断该变量的类型。 在运行时无法更改该变量的类型。 如果编译器不能推断类型,它会生成一个编译错误:

var varExample = 10;
Console.WriteLine(varExample.GetType());

  这段代码会输出 System.Int32,与静态类型相同。

  在下面的示例中,因为 varExample 的静态类型为 System.Int32,所以不需要转换:

varExample = varExample + 10;

  下面一行不进行编译,因为只能将整数赋给 varExample:

varExample = "test";

  C# 4 中引入的 dynamic 关键字可使某些传统上依赖于 object 关键字的情形更容易编写和维护。 实际上,动态类型在后台使用 System.Object 类型。但与 object 不同的是,动态类型不需要在编译时执行显式转换操作,因为它仅在运行时识别类型:

dynamic dynamicExample = 10;
Console.WriteLine(dynamicExample.GetType());

  此段代码会输出 System.Int32。

  在下面这一行中不需要转换,因为仅在运行时识别类型:

dynamicExample = dynamicExample + 10;  

  可以将不同类型的值赋给 dynamicExample:

dynamicExample = "test";

在 C# 常见问题解答博客 (bit.ly/c95hpl) 上,提供了关于关键字 object 和 dynamic 之间差别的详细博客文章。

  有时会引起混淆的是,所有这些关键字可以一起使用,即它们不是互相排斥的。 例如,我们来看一看下面的代码:

dynamic dynamicObject = new Object();
var anotherObject
= dynamicObject;

  anotherObject 的类型是什么? 我的回答是:dynamic。 请记住,在 C# 类型系统中,dynamic 实际上是一个静态类型,因此,编译器将为 anotherObject 推断此类型。 务必要知道,var 关键字不过是一个指令,它让编译器根据变量的初始化表达式推断类型;var 不是类型。

  动态语言运行时

  说起 C# 语言环境中的“dynamic”这一术语,它通常指下面两个概念之一:C# 4 中的 dynamic 关键字或 DLR。 虽然这两个概念是相关的,但也务必要了解它们之间的差别。

  DLR 有两个主要目的。 首先,它实现动态语言和 .NET Framework 之间的互操作。 其次,它将动态行为引入 C# 和 Visual Basic 之中。

  DLR 的创建吸取了构建 IronPython (ironpython.net) 时的经验教训(IronPython 是在 .NET Framework 上实现的第一种动态语言)。 在构建 IronPython 时,工作团队发现他们可以针对多种语言重复使用他们的实现,因此,他们为 .NET 动态语言创建了一个公共基础平台。 与 IronPython 一上海徐汇企业网站设计与制作样,DLR 已成为一个开源项目,其源代码目前在 dlr.codeplex.com 上提供。

  后来,.NET Framework 4 中也纳入了 DLR,以支持 C# 和 Visual Basic 中的动态功能。 如果您只需要 C# 4 中的 dynamic 关键字,那么使用 .NET Framework 就可以了。在大多数情况下,仅凭 .NET Framework 即可处理与 DLR 之间的所有交互。 但是,如果您希望实现新的动态语言或将其迁移到 .NET,则可以获益于开源项目中额外的帮助程序类,该开源项目为语言实现人员提供了更多功能和服务。

  在静态类型化语言中使用 Dynamic

  我们并不期待每个人都尽可能使用动态而不是静态类型声明。 编译时检查是一个强大的工具,对它的使用多多益善。 而且,再次指出,C# 中的动态对象不支持 IntelliSense,这对总体工作效率可能会有些影响。

  同时,在出现 dynamic 关键字和 DLR 之前,有一些方案在 C# 中曾经难以实现。 在以前的大多数情况下,开发人员使用 System.Object 类型和显上海闵行企业网站制作式转换,同样不能很好地利用编译时检查和 IntelliSense。 下面是一些例子。

  人们最熟知的一个情况是,有时必须使用 object 关键字来实现与其他语言或框架的互操作性。 通常,您必须依靠反射来获取对象的类型以及访问其属性和方法。 语法有时难以阅读,因此代码难以维护。 此时使用动态功能可能比使用反射更加容易和方便。

  Anders Hejlsberg 在 PDC08 (channel9.msdn.com/pdc2008/TL16) 上提供了一个极好的例子,如下所示:

object calc = GetCalculator();
Type calcType
= calc.GetType();
object res = calcType.InvokeMember(
"Add", BindingFlags.InvokeMethod,
null, new object[] { 10, 20 });
int sum = Convert.ToInt32(res);

  该函数返回一个计算器,但系统在编译时不知道此计算器对象的精确类型。 代码所依赖的唯一事情是此对象应具有 Add 方法。 请注意,此方法无法使用 IntelliSense,因为您以字符串文本的形式提供了方法名称。

  使用 dynamic 关键字,代码就很简单了:

dynamic calc = GetCalculator();
int sum = calc.Add(10, 20);

假设情况没有变化:存在某种我们希望其具有 Add 方法的未知类型的对象。 与上一个示例一样,此方法也不能使用 IntelliSense。 但语法阅读和使用起来要容易很多,看上去就像在调用一个普通的 .NET 方法。

  动态方法包

  可以利用动态功能的另外一个例子是创建动态方法包,动态方法包就是可在运行时添加和删除属性及方法的对象。

  .NET Framework 4 有一个新的命名空间:System.Dynamic。 此命名空间实际上是 DLR 的一部分。 System.Dynamic.ExpandoObject 和 System.Expando.DynamicObject 类与新的 dynamic 关键字相结合,有助于以清晰和易于阅读的方式来创建动态结构和层次结构。

  例如,下面说明了如何使用 ExpandoObject 类来添加属性和方法:

dynamic expando = new ExpandoObject();
expando.SampleProperty
= "This property was added at run time";
expando.SampleMethod
= (Action)(() => Console.WriteLine(expando.SampleProperty));
expando.SampleMethod();

  要了解更加深入的方案,您一定要看看关于 ExpandoObject 和 DynamicObject 类的 MSDN 文档。 同时,还有一些值得一看的文章,比如由 Bill Wagner 撰写的文章“动态方法包”(msdn.microsoft.com/library/ee658247) 以及 C# 常见问题解答博客文章“C# 4.0 中的 Dynamic:ExpandoObject 简介”(bit.ly/amRYRw)。

  类包装

  您可以为自己的库提供更好的语法,或为现有库创建包装。 与前两个方案相比,这是一个更高级的方案,并且需要对 DLR 具体内容有更深入的了解。

  对于简单情况,可以使用 DynamicObject 类。 在这个类中,可以将方法和属性的静态声明与动态调度进行混合。 这样,您就可以在一个类属性中存储一个要为其提供更佳语法的对象,但通过动态调度来处理针对该对象的所有操作。

  例如,请看一下图 1 中的 DynamicString 类,该类包装了一个字符串,并在通过反射实际调用所有方法之前显示这些方法的名称。

public class DynamicString : DynamicObject {
string str;

public DynamicString(string str) {
this.str = str;
}

public override bool TryInvokeMember(
InvokeMemberBinder binder,
object[] args,
out object result) {
Console.WriteLine(
"Calling method: {0}", binder.Name);
try {
result
= typeof(string).InvokeMember(
binder.Name,
BindingFlags.InvokeMethod
|
BindingFlags.Public
|
BindingFlags.Instance,
null, str, args);
return true;
}
catch {
result
= 上海闵行企业网站设计与制作pan>null;
return false;
}
}
}
 

  若要实例化该类,应使用 dynamic 关键字:

dynamic dStr = new DynamicString("Test");
Console.WriteLine(dStr.ToUpper());
Console.ReadLine();

  当然,这个特定示例出于演示目的而设计,不具有实际效率。 但是,如果您拥有已严重依赖于反射的 API,就可以如此处所示将所有通过反射进行的调用打包,以便针对 API 的最终用户隐藏这些调用。

  有关更多示例,请参见 MSDN 文档 (msdn.microsoft.com/library/system.dynamic.dynamicobject) 以及 C# 常见问题解答博客文章“C# 4.0 中的 Dynamic:通过 DynamicObject 创建包装”(bit.ly/dgS3od)。

  如前所述,DynamicObject 类是由 DLR 提供的。 生成动态对象所需要的仅仅是 DynamicObject 或 ExpandoObject。 但是,某些动态对象具有用于访问成员和调用方法的复杂绑定逻辑。 这种对象需要实现 IDynamicMetaObjectProvider 接口并提供其自己的动态调度。 这是一种高级方案,感兴趣的读者可以读一下由 Bill Wagner 撰写的文章“实现动态接口”(msdn.microsoft.com/vcsharp/ff800651),以及由 Alex Turner 及 Bill Chiles 撰写的文章“库创作者 DLR 入门”(dlr.codeplex.com)。

  可编写脚本的应用程序

  脚本是向应用程序提供可扩展性的一种强大方法。 Microsoft Office 可作为这方面的一个好例子:由于 Vis上海企业网站设计与制作ual Basic for Applications (VBA) 的存在,可以使用大量的宏、加载项和插件。 现在,DLR 提供了一组公用的语言宿主 API,因此可让您创建可编写脚本的应用程序。

  例如,您可以创建一个应用程序,使用户能够自己在其中添加功能而不需要主产品提供新功能,例如向游戏中添加新的字符和映射,或向业务应用程序添加新的图表。

  您必须使用来自 dlr.codeplex.com 的开源版 DLR 而不是由 .NET Framework 4 使用的 DLR,因为 DLR 脚本编写和宿主 API 现在仅在开源版中提供。 另外,假定的情况是您不是使用 C# 编写脚本,而是使用一种 .NET 动态语言(如 IronPython 或 IronRuby)来编写。 然而,实际上任何语言都可以支持这些 API,包括不是在 DLR 之上实现的语言。

  有关使用此功能的详细信息,请观看 PDC09 (microsoftpdc.com/2009/FT30) 上由 Dino Viehland 所做的演示“使用动态语言生成可编写脚本的应用程序”。

  识别动态对象

  如何区分动态对象与其他对象? 一个简便方法是使用内置的 IDE 功能。 您可以将鼠标光标悬停在对象上以查看其声明类型,或检查 IntelliSense 是否可用。

  然而在运行时,情况会变得更加复杂。 您无法检查变量是否是通过 dynamic 关键字声明的 — 动态对象的运行时类型是它所存储的值的类型,您无法获取其静态类型声明。 这种情况与将变量声明为 object 时的情况相同:在运行时,您只能获取变量所存储的值的类型;无法判断此变量最初是否声明为 object。

  运行时所能确定的是对象是否来自 DLR。 知道这种情况可能十分重要,因为像 ExpandoObject 和 DynamicObject 类型的对象可在运行时改变其行为,例如,添加和删除属性及方法。

  此外,也无法使用标准反射方法来获取有关这些对象的信息。 如果向 ExpandoObject 类的实例添加属性,则无法通过反射获取该属性:

dynamic expando = new ExpandoObject();
expando.SampleProperty
= "This property was added at run time";
PropertyInfo dynamicProperty
= expando.GetType().GetProperty("SampleProperty");
// dynamicProperty is null.

  有利的方面是,在 .NET Framework 4 中,所有可动态添加和删除成员的对象都必须实现一个特定接口:System.Dynamic.IDynamicMetaObjectProvider。 DynamicObject 和 ExpandoObject 类也实现了这个接口。 不过,这并不表示任何使用 dynamic 关键字声明的对象都实现此接口:

dynamic expando = new ExpandoObject();
Console.WriteLine(expando
is IDynamicMetaObjectProvider);
// True
dynamic test = "test";
Console.WriteLine(test
is IDynamicMetaObjectProvider);
// False

因此,如果将动态功能与反射一起使用,则请记住,反射不适用于动态添加的属性和方法,并且最好检查正在反射的对象是否实现了 IDynamicMetaObjectProvider 接口。

  动态功能与 COM 互操作

  C# 团队在 C# 4 版本中专门考虑的 COM 互操作方案是针对 Microsoft Office 应用程序(如 Word 和 Excel)进行编程。 他们的目的是让这一任务在 C# 中变得像在 Visual Basic 中那样容易和自然。 这也是 Visual Basic 和 C# 共同发展策略的一部分,这个策略旨在实现两种语言的功能对等,并相互借鉴最佳、最具效率的解决方案。

  若需了解详细信息,请参阅 Scott Wiltamuth 的 Visual Studio 博客文章“C# 和 VB 共同发展”(bit.ly/bFUpxG)。

  显示了一段 C# 4 代码,该代码向 Excel 工作表的第一个单元格中添加一个值,然后向第一列应用 AutoFit 方法。 每行下面的注释显示了 C# 3.0 及更早版本的中的等效代码。

// Add this line to the beginning of the file:
// using Excel = Microsoft.Office.Interop.Excel;

var excelApp
= new Excel.Application();

excelApp.Workbooks.Add();
// excelApp.Workbooks.Add(Type.Missing);

excelApp.Visible
= true;

Excel.Range targetRange
= excelApp.Range["A1"];
// Excel.Range targetRange = excelApp.get_Range("A1", Type.Missing);

targetRange.Value
= "Name";
// targetRange.set_Value(Type.Missing, "Name");

targetRange.Columns[
1].AutoFit();
//上海徐汇企业网站制作pan> ((Excel.Range)targetRange.Columns[1, Type.Missing]).AutoFit();

  此示例有趣的地方是,您在代码中的任何位置都看不到 dynamic 关键字。实际上,该关键字仅在下面一行中用到:

targetRange.Columns[1].AutoFit();
// ((Excel.Range)targetRange.Columns[1, Type.Missing]).AutoFit();

  在 C# 3.0 版中,targetRange.Columns[1, Type.Missing] 返回 object,这便是需要向 Excel.Range 转换的原因。 但在 C# 4 和 Visual Studio 2010 中,这样的调用将以静默方式转换为动态调用。 因此,C# 4 中 targetRange.Columns[1] 的类型实际上是 dynamic。

  另一个突出特点是,C# 4 中的 COM 互操作改进不仅限于 dynamic。 由于其他一些新增功能(例如索引属性以及命名参数和可选参数),其他所有行中的代码也有所改进。 由 Chris Burrows 撰写的 MSDN 杂志 文章“.NET Framework 4 中的新增 C# 功能”(msdn.microsoft.com/magazine/ff796223) 中对这些新增功能做了很好的概述。

  从哪里可以获取更多信息?

  希望本文已涵盖您对 C# 4 中的 dynamic 关键字可能有的大部分疑问,但我确信本文并非面面俱到。 如果您有意见、问题或建议,敬请光临 dlr.codeplex.com/discussions 提出。 其他人可能已经提过您关心的问题,或者您可以发起新的讨论。 我们拥有一个活跃的社区,欢迎新成员加入。

转载于:https://www.cnblogs.com/waw/archive/2011/10/15/2213527.html

相关文章:

“我,懂数据,不怕被裁”:这项核心能力到底有多香?

我见过市面上很多的 Python 讲解教程和书籍,他们大都这样讲 Python 的:先从 Python 的发展历史开始,介绍 Python 的基本语法规则,Python 的 list, dict, tuple 等数据结构,然后再介绍字符串处理和正则表达式&#xff0…

使请求管线内的所有模块尽可能高效

请求管线内的所有模块在每次请求中都有机会被运行。因此,当请求进入和离开模块时快速地触发代码至关重要,特别是在不使用模块功能的代码路径里。分别在使用及不使用模块和配置文件时执行吞吐量测试,对确定这些方法的执行速度非常有用。

PHP smarty缓存

缓存一个页面 test.php <?php//定义该页面缓存文件存放的路径 $filename "../cache/cachetest.html";//定义缓存有效期 $cachetime 5;//判断缓存文件是否存在 if(!file_exists($filename) || filemtime($filename)$cachetime<time()) {//开启内存缓存ob_sta…

在 Visual Basic .NET 或 JScript 代码中使用早期绑定

以往&#xff0c;开发人员喜欢使用 Visual Basic、VBScript 和 JScript 的原因之一就是它们所谓“无类型”的性质。变量不需要显式类型声明&#xff0c;并能够简单地通过使用来创建它们。当从一个类型到另一个类型进行分配时&#xff0c;转换将自动执行。不过&#xff0c;这种便…

Use MVS Dsbame convensions. windows下ftp.exe客户端上传错误

环境:主机 220-FTPD1 IBM FTP CS V1R11 at BT11 windows下的ftp.exe客户端 现象:windows下ftp.exe命令上传文件,报"Use MVS Dsbame convensions." 错误 原因: 主要是IBM FTP Server 文件系统的命名规范造成的: 8个基本字符 解决: 通过 cd 根目录.目录1.目录2----…

算法对建筑业的影响,不仅仅是画图

拿什么来拯救&#xff0c;这些奇葩的设计&#xff1f;奇葩造型位于英国伦敦芬乔奇街 20 号的一座摩天大楼&#xff0c;由于造型像「对讲机」&#xff0c;被取外号「对讲机大楼」。其实造型奇葩倒没什么&#xff0c;也有一些人觉得还挺好看。但问题是&#xff0c;建成之后&#…

如何参与团队合作?

现在&#xff0c;团队合作就是竞争力。随着市场竞争的日益激烈&#xff0c;企业更加强调团队精神&#xff0c;建立群体共识&#xff0c;以达到更高的工作效率。特别是有遇到大型项目时&#xff0c;想凭借一己之力去取得卓越的成果&#xff0c;可能非常困难。想必你也意识到&…

200 个工具分析机器学习十年:开源是大势,工程师是核心

【编者按】人工智能和机器学习经过十年多的发展&#xff0c;在过去的几年间&#xff0c;各类工具数量迎来了持续的爆发式的增长&#xff0c;机器学习也正式由科研走进工业生产阶段。本文作者 —— 来自硅谷一家初创公司的计算机科学家 Chip Huyen 梳理挖掘出 202 个机器学习工具…

将调用密集型的 COM 组件迁移到托管代码

.NET Framework 提供了一个简单的方法与传统的 COM 组件进行交互。其优点是可以在保留现有投资的同时利用新的平台。但是在某些情况下&#xff0c;保留旧组件的性能开销使得将组件迁移到托管代码是值得的。每一情况都是不一样的&#xff0c;决定是否需要迁移组件的最好方法是对…

性能优化工具 MVC Mini Profiler

MVC MiniProfiler是Stack Overflow团队设计的一款对ASP.NET MVC、WebForm 以及WCF 的性能分析的小程序。可以对一个页面本身&#xff0c;及该页面通过直接引用、Ajax、Iframe形式访问的其它页面进行监控,监控内容包括数据库内容&#xff0c;并可以显示数据库访问的SQL&#xff…

刷新UITableView

【from】http://www.superqq.com/blog/2015/08/18/ios-development-refresh-uitableview/ UITableView对于iOS开发者来说一定不会陌生&#xff0c;很有可能你的APP很多界面都用到它。关于UITableView的文章&#xff0c;想必已经不计其数&#xff0c;没事可以多看看。特别是UITa…

算术运算中隐式类型转换

转载于:https://www.cnblogs.com/strider/articles/2220313.html

高文、张钹、杨强隔空论道:AI精度与隐私的博弈

出品 | AI科技大本营&#xff08;ID:rgznai100&#xff09;AI时代&#xff0c;如何保护大众的隐私&#xff1f;以联邦学习为代表的AI技术能否实现AI协作&#xff0c;提升模型精度的同时&#xff0c;实现数据隐私的保护&#xff1f;中国如何抢占人工智能安全发展的制高点&#x…

避免单线程单元 (STA) COM 组件

默认情况下&#xff0c;ASP.NET 不允许任何 STA COM 组件在页面内运行。若要运行它们&#xff0c;必须在 .aspx 文件内将 ASPCompattrue 属性包含在 Page 指令中。这样就将执行用的线程池切换到 STA 线程池&#xff0c;而且使 HttpContext 和其他内置对象可用于 COM 对象。前者…

将 SQL Server 存储过程用于数据访问

在 .NET Framework 提供的所有数据访问方法中&#xff0c;基于 SQL Server 的数据访问是生成高性能、可缩放 Web 应用程序的推荐选择。使用托管 SQL Server 提供程序时&#xff0c;可通过使用编译的存储过程而不是特殊查询获得额外的性能提高。

centos下安装apache + subversion(转)

目录&#xff1a; 一.安装apr跟apr-util 二.安装apache服务器 三. 安装subversion 四. 配置subversion 五. 配置apache的httpd.conf 六. 验证安装 七.导入数据到资料库八.版本库服务器的同步&#xff08;新加入的&#xff09; 附&#xff1a;安装过程中遇到的问题 一.安装apr、…

真香!3个月0基础转型大厂数据分析师,他做对了什么?

年初的黑天鹅打乱了我的求职阵脚&#xff0c;专业不对口&#xff0c;无实习经验&#xff0c;在求职路上的竞争优势几乎为0&#xff0c;然而&#xff0c;开启自救模式后&#xff0c;我顺利成为了头条数据分析师&#xff0c;下面我就讲讲人生是怎么开挂的。随着人工智能普及&…

OpenStack快速入门

OpenStack云计算快速入门&#xff08;1&#xff09;该教程基于Ubuntu12.04版&#xff0c;它将帮助读者建立起一份OpenStack最小化安装。我是五岳之巅&#xff0c;翻译中多采用意译法&#xff0c;所以个别词与原版有出入&#xff0c;请大家谅解。我不是英语专业&#xff0c;我觉…

将 SqlDataReader 类用于快速只进数据游标

SqlDataReader 类提供了一种读取从 SQL Server 数据库检索的只进数据流的方法。如果当创建 ASP.NET 应用程序时出现允许您使用它的情况&#xff0c;则 SqlDataReader 类提供比 DataSet 类更高的性能。情况之所以这样&#xff0c;是因为 SqlDataReader 使用 SQL Server 的本机网…

微软小冰从上海音乐学院音工系毕业,师从于阳、陈世哲

6月29日&#xff0c;经上海音乐学院音乐工程系评定&#xff0c;人工智能微软小冰和她的人类同学——上音音乐工程系音乐科技专业毕业生一起毕业&#xff0c;并授予微软小冰上海音乐学院音乐工程系2020届“荣誉毕业生”称号。微软小冰和上海音乐学院的毕业生们一起参加了于6月29…

Typedef用法学习

不管实在C还是C代码中&#xff0c;typedef这个词都不少见&#xff0c;当然出现频率较高的还是在C代码中。typedef与#define有些相似&#xff0c;但更多的是不同&#xff0c;特别是在一些复杂的用法上&#xff0c;就完全不同了&#xff0c;看了网上一些C/C的学习者的博客&#x…

开发板tftp:timeout问题

想要从PC上面tftp文件的时候遇到了tftp:timeout的问题&#xff1a; >: tftp -gr gprsapp 192.168.1.38tftp: timeout 检查了网络&#xff0c;可以ping的通PC。PC的tftp服务器也已经打开了&#xff0c;测试从开发板上面向PC上tftp传送数据也是可以的&#xff1a;说明开发板上…

选择适合页面或应用程序的数据查看机制

根据您选择在 Web 窗体页显示数据的方式&#xff0c;在便利和性能之间常常存在着重要的权衡。例如&#xff0c;DataGrid Web 服务器控件可能是一种显示数据的方便快捷的方法&#xff0c;但就性能而言它的开销常常是最大的。在某些简单的情况下&#xff0c;您通过生成适当的 HTM…

Android强制设置横屏或竖屏

全屏 在Activity的onCreate方法中的setContentView(myview)调用之前添加下面代码requestWindowFeature(Window.FEATURE_NO_TITLE);//隐藏标题 getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);//设置全屏 横屏 …

免费直播:1小时带你体验Python车牌识别实战

Python基础学会了&#xff0c;实战又是爬虫&#xff1f;太枯燥&#xff1f;别无聊&#xff0c;CSDN学院邀请章秀淞老师开设技术直播课&#xff1a;1小时带你体验车牌识别实战。让你从众多车中&#xff0c;能用Python技术找到夏树上的那辆叔叔的奔驰车牌&#xff08;玩笑&#x…

centos上tensorflow一键安装脚本

鉴于tensorflow在centos上安装相当麻烦,特地制作了一个脚本方便以后移植到其它机器上,脚本含有其它python常用包: #! /bin/bash sudo yum install -y gcc g gtk-devel libjpeg-devel libtiff-devel jasper-devel libpng-devel zlib-devel cmake unzip sqlite-devel readline-…

谷歌AI专家爆料:90%的人都不知道,写不出好代码,是输在了这点上!

工作压力大、大牛实力碾压&#xff0c;、外行人的偏见......2020年&#xff0c;程序员的心很累&#xff01;而Python和AI的初学者&#xff0c;心更累&#xff01;最近几年&#xff0c;我看过市面上很多 Python和人工智能的教程和书籍&#xff0c;它们大都这样讲&#xff1a;先从…

只要可能,就缓存数据和页输出

ASP.NET 提供了一些简单的机制&#xff0c;它们会在不需要为每个页请求动态计算页输出或数据时缓存这些页输出或数据。另外&#xff0c;通过设计要进行缓存的页和数据请求&#xff08;特别是在站点中预期将有较大通讯量的区域&#xff09;&#xff0c;可以优化这些页的性能。与…

系统基本安全优化

1、删除系统特殊的的用户帐号和组帐号&#xff1a; userdel adm userdel lp userdel sync userdel shutdown userdel halt userdel news userdel uucp userdel operator userdel games userdel gopher groupdel adm groupdel lp groupdel news groupdel uucp groupdel games gr…

VMware12中安装CentOS7.2的详细过程

标签&#xff1a;Linux 虚拟机 CentOS1.什么是虚拟机虚拟机&#xff08;Virtual Machine&#xff09;指通过软件模拟的具有完整硬件系统功能的、运行在一个完全隔离环境中的完整计算机系统。流行的虚拟机软件有VMware(VMWare ACE&#xff09;、Virtual Box和Virtual PC&#xf…