Anders Hejlsberg 谈C#设计过程 [转载]

60岁还在写代码的程序员大师,Delphi、C#、TypeScript之父Anders Hejlsberg(安德斯·海尔斯伯格):编程符合10000小时定律 【转载】Delphi、C#之父Anders Hejlsberg 近日首次访华,并在10月24日和27日参加了两场见面会,分享了他目前领导开发的TypeScript项目,并与国内前端开发者近距离交流。本文就为读者描述一下近距离接触编程语言大师的印象,以及Anders对TypeScript的设计理念和想法。 Anders Hejlsberg(安德斯·海尔斯伯格)于1960年出生于丹麦,在Borland公司开发出Turbo Pascal和Delphi之后加入微软,主持微软下一代开发工具的研发。 他为微软... 阅读详情

原版英文:http://msdn.microsoft.com/vcsharp/headlines/hejlsberg/default.aspx

原译中文:http://blog.youkuaiyun.com/lxpbuaa/archive/2003/09/26/8750.aspx

Anders Hejlsberg 谈 C# 设计过程

  Anders Hejlsberg 为 Borland 工作13个春秋后,于1996年加盟微软,最初参与设计 Visual J++ 和 WFC(Windows Foundation Classes)。然后,担任C#首席设计师和 Microsoft .NET Framework 设计小组核心成员。目前,他还将继续领导C#语言后续版本的设计工作。

  2003年7月30日,Hejlsberg 在他微软的办公室会见了 Bruce Eckel(《Thinking in C++》和《Thinking in Java》的作者)、Bill Venners(Artima.com主编)。谈话内容主要分为三个部分:

  • 一、C#设计过程、语言可用性研究和语言美学。
  • 二、Checked Exceptions 特征的版本相关性和扩展性。
  • 三、委托的概念、组件概念在C#中的至高地位。


一、C#设计过程、语言可用性研究和语言美学

1、C#设计过程

Bruce Eckel:     我听说C#是一个工程师小组在一个屋子里设计出来的?

Anders Hejlsberg:是的。4年来,我们一直呆在这个屋子里。现在,每周一、三、五,我们仍然在这里会面。

Bruce Eckel:     我很想了解一些关于C#设计过程的情况。我直接或间接参与过几种语言的设计工作,如Python。在Python设计过程中,Guido van Rossum被我们戏称为“仁慈的独裁者”。

Anders Hejlsberg:哦,Guido van Rossum就相当于我的位置。

Bruce Eckel:     那么你是C#小组“仁慈的独裁者”么?

Anders Hejlsberg:我一般扮演最后拍板者的角色。比如,我们被一个问题困扰多时,到了非解决不可、只能作不二选择的时候,是由我来作最后决定的。当然大多数这样的情况下,正确的选择是显而易见的。

Bruce Eckel:     C#的设计过程是不是和 Turbo Pascal、Delphi 十分相似?

Anders Hejlsberg:后面两者的设计过程不是那么规范的。因为 Turbo Pascal 主要由我一个人设计,而 Delphi 也是我和 Chuck Jazdzewski、Gary Whizin 等几个为数不多的人来完成,所以没有必要引入非常规范的设计过程。相反的,C#的设计过程则十分规范,每周一、三、五从 1:00 到 3:00,我们都会召开一个正式会议,会议议程也相当灵活,所有的问题都会拿到桌面上公开讨论、仔细推敲。我们还在互联网上建立了一个Wiki,这些问题及其解决方案,以及其他一些相关的东西都被发布在上面。

Bruce Eckel:     那你们是如何发现这些的问题呢?

Anders Hejlsberg:呵呵,我们有一套行之有效的方法。我们可以通过很多途径来得到用户对语言设计的反馈意见——如软件设计咨询会、网络新闻组。这些反馈意见包括:疑问、软件Bugs、不一致、不规范问题等。这样我们就能有的放矢了。最后我们将这些问题整理成表,并一一重现它们。对于每个问题,我们都会认真对待,询问自己:“我们对这个问题有新的想法吗?真的没有吗?这个问题已经搁置好几个星期了,我们立即花30分钟集中精力研究一下,看这次是否能有所斩获。”

Bruce Eckel:     那可能一个问题长期没有解决,都臭不可闻了……

Anders Hejlsberg:也许有些臭问题只有放到下一个版本才能解决了。但是我认为这样一个过程可以保证不会遗漏任何问题,因为它们都被登记在册。有时候,你面对这些问题呆坐了很长时间,可能也没什么结果。但问题毕竟是被我们逮住了,总有一天会再去“拜访”它的。也可能不会再去“拜访”了,但问题终归是不会被弄丢的。

Bill Venners:     C#设计小组包含哪些成员,他们都担当什么角色?

Anders Hejlsberg:参与最初的C#设计的有 Scott Wiltamuth、Peter Golde、Peter Sollich、Eric Gunnerson 和我。C#2.0设计小组包括:Peter Hallam、Shon Katzenberger、Todd Proebsting,以及我自己。微软研究院的 Don Syme 和 Andrew Kennedy 承担了大部分一般性研究工作。

2、语言可用性研究和语言美学

Bill Venners:    在C#的设计中,可用性研究、市场策略和语言美学的侧重是如何权衡的?

Anders Hejlsberg:一般而言,好的语言设计过程体现了对设计小组成员的美学品味取向的综合,也就是你刚才所说的语言美学观。美学品味带有极大的主观性,很难定论,只有产品出来后,你才能仔细体味它。我认为任何程度的可用性研究都不能取代语言美学的价值,因为可用性研究是极有针对性、非常具体的。可能有人问你:“你认为这部分功能如何?”这个问题很难回答。“你对这个语言有什么看法?”你从何谈起呢?你怎么可能花两个小时就解决掉所有可用性问题?绝无可能。

Bruce Eckel:     人们必须深入理解这个问题。

Anders Hejlsberg:使用一种编程语言会经历一个感觉微妙变化的过程。只有使用几个月之后用户才能真正喜欢上它。他们会逐渐发现:“哦,它给人的感觉很舒服嘛。”你不能急于求成。开始说过,我们在可用性研究上也做了大量工作,但主要是针对特定的功能。

Bill Venners:    可以举个例子么?

Anders Hejlsberg:我们将可用性研究的重点放在了IDE功能实现上。我们会问自己:“用户是否知道在这里点击右键会有什么结果?”在纯语言功能部分,我们也考虑了一些可用性问题——例如在一些属性和事件上——不过没什么必要,真的。

  我想在可用性研究上,语言特性不可能带来和IDE特性一样高的收益。你可以看到用户点击一个菜单项立即得到正确的反馈信息。而对语言来说,问题要复杂一些。例如:“它的概念容易理解么?”我们通过用户咨询会、留言板,比较好的解决了这些问题。用户需要有个说话的地方,“对于这个新特性,我有这样一些想法,你们是如何考虑的呢?”这样的问题提得越多、尖锐越好,因为你肯定是最希望在产品出来以前就能知道用户的想法,而不是产品推出以后。在一个语言特性被完全敲定前,我们通常都会考虑用户的建议和意见的。

二、Checked Exceptions 特征的版本相关性和扩展性。

1、对Checked Exceptions特性持保留态度

  译者注:在写一段程序时,如果没有用try-catch捕捉异常或者显式的抛出异常,而希望程序自动抛出,一些语言的编译器不会允许编译通过,如Java就是这样。这就是Checked Exceptions最基本的意思。该特性的目的是保证程序的安全性和健壮性。Zee&Snakey(MVP)对此有一段很形象的话,可以参见:http://www.blogcn.com/user2/zee/main.asp
  Bruce Eckel 也有相关的一篇文章(《Does Java need Checked Exceptions》),参见:http://www.mindview.net/Etc/Discussions/CheckedExceptions

Bruce Eckel:     C#没有 Checked Exceptions,你是怎么决定是否在C#中放置这种特性的么?

Anders Hejlsberg:我发现 Checked Exceptions 在两个方面有比较大的问题:扩展性和版本控制。我知道你也写了一些关于 Checked Exceptions 的东西,并且倾向于我们对这个问题的看法。

Bruce Eckel:     我一直认为 Checked Exceptions 是非常重要的。

Anders Hejlsberg:是的,老实说,它看起来的确相当重要,这个观点并没有错。我也十分赞许 Checked Exceptions 特性的美妙。但它某些方面的实现会带来一些问题。例如,从 Java 中 Checked Exceptions 的实现途径来看,我认为它在解决一系列既有问题的同时,付出了带来一系列新问题的代价。这样一来,我就搞不清楚 Checked Exceptions 特性是否可以真的让我们的生活变得更美妙一些。对此你或许有不同看法。

Bruce Eckel:     C#设计小组对 Checked Exceptions 特性是否有过大量的争论?

Anders Hejlsberg:不,在这个问题上,我们有着广泛的共识。C#目前在 Checked Exceptions 上是保持缄默的。一旦有公认的更好的解决方案,我们会重新考虑,并在适当的地方采用的。我有一个人生信条,那就是——如果你对该问题不具有发言权,也没办法推进其解决进程,那么最好保持沉默和中立,而不应该摆出一个非此即彼的架势。

  假设你让一个新手去编一个日历控件,他们通常会这样想:“哦,我会写出世界上最好的日历控件!我要让它有各种各样的日历外观。它有显示部分,有这个,有那个……”他们将所有这些构想都放到控件中去,然后花两天时间写了一个很蹩脚的日历程序。他们想:“在程序的下一个版本中,我将实现更多更好的功能。”

  但是,一旦他们开始考虑如何将脑海中那么多抽象的念头具体实现出来时,就会发现他们原来的设计是完全错误的。现在,他们正蹲在一个角落里痛苦万状呢,他们发现必须将原来的设计全盘抛弃。这种情况我不是看到一次两次了。我是一个最低纲领主义者。对于影响全局的问题,在没有实际解决方案前,千万不要将它带入到整个框架中去,否则你将不知道这个框架在将来会变成什么样子。

Bruce Eckel:     极限编程(The Extreme Programmers)上说:“用最简单的办法来完成工作。”

Anders Hejlsberg:对呀,爱因斯坦也说过:“尽可能简单行事。”对于 Checked Excpetions 特性,我最关心的是它可能给程序员带来哪些问题。试想一下,当程序员调用一些新编写的有自己特定的异常抛出句法的API时,程序将变得多么纷乱和冗长。这时候你会明白 Checked Exceptions 不是在帮助程序员,反而是在添麻烦。正确的做法是,API的设计者告诉你如何去处理异常而不是让你自己想破脑袋。

2、Checked Exceptions 的版本相关性

Bill Venners:    你提到过 Checked Exceptions 的扩展性和版本相关性这两个问题。现在能具体解释一下它们的意思么?

Anders Hejlsberg:让我首先谈谈版本相关性,这个问题更容易理解。假设我创建了一个方法foo,并声明它可能抛出A、B、C三个异常。在新版的foo中,我要增加一些功能,由此可能需要抛出异常D。这将产生了一个极具破坏性的改变,因为原来调用此方法时几乎不可能处理过D异常。

  也就是说,在新版本中增加抛出的异常时,给用户的代码带来了破坏。在接口中使用方法时也有类似的问题。一个实现特定功能的接口一经发布,就是不可改变的,新功能只能在新版的接口中增加。换句话说,就是只能创建新的接口。在新版本中,你只有两种选择,要么建立一个新的方法foo2,foo2可以抛出更多的异常,要么在新的foo中捕获异常D,并转化为原来的异常A、B或者C。

Bill Venners:    但即使在没有 Checked Exceptions 特性的语言中,(增加新的异常)不是同样会对程序造成破坏么?假如新版foo抛出了需要用户处理的新的异常,难道仅仅因为用户不希望这个异常发生,他写代码时就可以置之不理吗?

Anders Hejlsberg:不,因为在很多情况下,用户根本就不关心(异常)。他们不会处理任何异常。其实消息循环中存在一个最终的异常处理者,它会显示一个对话框提示你程序运行出错。程序员在任何地方都可以使用try finally来保护自己的代码,即使运行时发生了异常,程序依然可以正确运行。对于异常本身的处理,事实上,程序员是不关心的。

  很多语言的throws语法(如Java),没必要地强迫你去处理异常,也就是逼迫你搞清楚每一个异常的来源。它们要求你要么捕获声明的异常,要么将它们放入throws语句。程序员为了达到这个要求,做了很多荒谬可笑的事情。例如他们在声明每个方法时,都必须加上修饰语:“throws Exception”。这完全是在搧这个特性的耳光,它不过是要求程序员多作些官样文章,对谁都没有好处。

Bill Venners:    如此说来,你认为不要求程序员明确的处理每个异常的做法,在现实中要适用得多了?

Anders Hejlsberg:人们为什么认为(显式的)异常处理非常重要呢?这太可笑了。它根本就不重要。在我印象中,一个写得非常好的程序里,try finally和try catch语句数目大概是10:1。在C#中,也可以使用和类似try finally的using语句(来处理异常)。

Bill Venners:    finally 到底干了些什么?

Anders Hejlsberg:finally 保证你不被异常干扰,但它不直接处理异常。异常处理应该放在别的什么地方。实际上,在任何一个事件驱动的(如现代图形界面)程序中,在主消息循环里,都有一个缺省的异常处理过程,程序员只需要处理那些没被缺省处理的异常。但你必须确保任何异常情况下,原来分配的资源都能被销毁。这样一来,你的程序就是可持续运行的。你肯定不希望写程序时,在100个地方都要处理异常并弹出对话框吧。如果那样的话,你作修改时就要倒大霉了。异常应该集中处理,并在异常来临处保护好你的代码。

3、Checked Exceptions 的扩展性

Bill Venners:    那么 Checked Exceptions 的扩展性又是如何呢?

Anders Hejlsberg:扩展性有时候和版本性是相关的。 在一个小程序里,Checked Exceptions 显得蛮迷人的。你可以捕捉 FileNotFoundException 异常并显示出来,是不是很有趣?这在调用单个的API时也挺美妙的。但是在开发大系统时,灾难就降临了。你计划包含4、5个子系统,每个子系统抛出4到10个异常。但是(实际开发时),你每在系统集成的梯子上爬一级,必须被处理的新异常都将呈指数增长。最后,可能每个子系统需要抛出40个异常。将两个子系统集成时,你将必须写80个throw语句。最后,可能你都无法控制了。

  很多时候, Checked Exceptions 都会激怒程序员,于是程序员就想办法绕过这个特性。他要么在到处都是写“throws Exception”,要么——我都不知道自己看到多少回了——写“try, da da da da da(译者注:意思是飞快的写一段代码), catch curly curly(译者注:即‘{ }’)”,然后说:“哦,我会回头来处理这些空的异常处理语句的。”实际上,理所当然的没有任何人会回头干这些事情。这时候,Checked Exceptions 已经造成系统质量的极大下降。

  所以,你可能很重视这些问题,但是在我们决定是否将 Checked Exceptions 的一些机制放入C#时,却是颇费了一番思量的。当然,知道什么异常可能在程序中抛出还是有相当价值的,有一些工具也可以作这方面的检查。我不认为我们可以建立一套足够严格而严谨的规则(来完成异常检查),因为(异常)还可能是编译器的错误引起的呢。但是我认为可以在(程序)分析工具上下些功夫,检测是否有可疑代码,是否有未捕获的异常,并将这些隐藏的漏洞给你指出来。

三、委托的概念、组件概念在C#中的至高地位。

1、Simplicity 和 Simplexity

Bill Venners:    C#和Java传递对象事件的方式有所不同。Java使用类(通常是内部类(inner classes),它实现监听接口(listener interfaces)。C#使用了委托(delegates。译者注:VJ++6.0就引入了delegates),它有点儿类似函数指针。为什么要采用委托方式呢?

Anders Hejlsberg:请允许我首先谈谈对于一般意义上的Simplicity的看法。没有任何人怀疑简单的正确性,但是在如何实现简单的问题上则千差万别。有一种简单,我想称之为Simplexity。你做了一个很实际上复杂的东西,当你将它包装为一个简单的东西时,通常是将它的复杂性隐藏起来。所以实际上,你并不是在设计一个真正简单的系统。这样的一个包装过程,从某些角度上看,系统可能被你搞得更复杂了,因为用户有时候需要知道被隐藏地东西。这就是我说的Simplexity。
  对我而言,简单必须是真正的简单,也就是说,当你将来某个时候需要钻研系统内部结构时,它应该显得更加简单,而不是比它表面那个样子更复杂。

2、委托和接口

Anders Hejlsberg:委托提供了与类和接口无关的实现方式,这是我认为最重要的地方。过去的很多编程语言已经认识到了这种方式的重要性。这种方式有很多名字,如:函数指针、成员函数指针,在Lisp语言中,被称为closures, 它是非常有用处的。

Bill Venners:    那么这是如何实现的呢?

Anders Hejlsberg:使用接口的确可以完成委托具有的所有功能,但是你会被迫面对烦杂的“家务管理”。我们可以对比一下Java和.NET处理事件的过程。因为在Java中没有委托,所以最终必须使用接口。

  接口是对应于事件的,一个接口可以定义1、2、3、4个甚至更多的方法。这点就已经产生了问题,因为这个“对应”没有明确的规范。到底应该定义多少个接口来处理事件呢?是每个事件对应一个接口还是所有的事件用一个接口?让你难以取舍。好了,先胡乱选择其一去处理组件的事件。接下来,你必须实现这些接口。理所当然的,如果处理两个组件的同样的事件,你就必须将接口实现两次——你当然不愿意这么干,所以在这种情况下,你还需要创建一个适配器。这样,烦杂的“家务管理”就跑到你面前来了。

  内部类在处理家务事上能帮点小忙,但最终,有些问题你是逃避不了的——事件接收者必须知道它什么时候接收事件。这样你又必须明确的实现一个监听接口。与此相反,如果你使用委托,只要信息是兼容的,你就可以将所有事件放在一起处理。这家伙并不关心自己是怎么被调用的,它仅仅是一个(处理事件的)方法。

Bruce Eckel:     看来,委托是非常精瘦的。

Anders Hejlsberg:对,的确如此。

Bruce Eckel:     它也更加灵活。

Anders Hejlsberg:的确是这样。它仅仅依赖于信息的兼容性,如参数是否一致。如果是兼容的,你就可以将多个事件放在一起处理。从概念上说,这也完全满足了用户对一个回调的结果期望,对吧?只要给我一些参数,我就可以编写程序了。听起来很像一个方法吧,那么我给定该方法的一个引用,这个引用就是我所说的委托了。

Bruce Eckel:     最后你也不会丢掉类型检查。类型检查是在运行时进行的么?

Anders Hejlsberg:不,大多数都是在编译时进行。你创建一个委托的实例后,它就和程序员在C++中使用的成员函数指针差不多。委托指向了某对象的一个方法。如果是虚拟的方法,你也能准确地判断委托的指向。所以从某种意义上说说,你可以在实例化委托时就解决虚拟问题。通过委托实现的调用可以看作一个间接的(方法)调用指令。

Bruce Eckel:     除此之外,就不再需要其他的间接支持了。

Anders Hejlsberg:是的,构造一个委托的时候,你就可以一次性解决虚拟函数表(VTBL)和委托的指向问题;通过委托实现的调用都可以直接准确的得到它对应的方法。所以,委托比接口派遣更有效率,即使和标准的方法派遣相比,它的效率也要高一些。

Bruce Eckel:     C#中也有Multicast类型的委托(译者注:Multicast即多点传送。是指一个委托可以对应多个方法;委托被调用时,就可以引起多个方法的调用。更详细的说明可以参考:http://msdn.microsoft.com/vjsharp/productinfo/visualj/visualj6/technical/articles/general/delegates/), 它能够使多个函数被调用。 这是一个orthogonal特性吗?

Anders Hejlsberg:Multicast是一个彻头彻尾的orthogonal特性。老实说,在Multicast是否重要这个问题,我也是持保留态度的。我承认它有它的用处,但保守地讲的话,我认为所有的委托都是single cast的。有些人觉得Multicast十分重要,使用它有很多优点,但是在大多数情况下委托恰恰都是single cast的。事实上,我们构造的(C#)系统是使用single cast的,只要你(在这个系统里)不使用Multicast,就不会为它付出什么代价的。

Bill Venners:    委托是怎么来体现你前面所说的 Simplicity和 Simplexity的呢?它们都体现在哪些地方?

Anders Hejlsberg:如果你仿效接口来实现委托,那么你最终无可避免地要面对“家务管理”和适配器问题。其实,我们可以观察任何一个捆绑了JavaBeans的开发工具,它们都会生成一些适配器并告诉你:“你不要修改下面的代码,我会分发一些非常瘦小的帮助类给你。”这对于我来说就太复杂了。它并不是一个真正简单的系统,它实际上非常复杂,不过是貌似简单而已。

3、组件概念在C#中的至高地位

Bill Venners:    O'Reilly网站发布过对于你的一次采访,当时你这么评价C#对于属性和事件的支持:“现在,程序员人员每天都在开发大量的软件组件。他们不是在开发彼此孤立的应用程序和类库。每个人都在开发继承自环境提供的组件的新组件。这些新组件覆盖了父组件的一些方法、属性,处理一些事件,然后将这些新组件放回去(到组件库)。这是一个首先要树立的概念。”
  我希望能更好理解你的谈话精神,因为我一直认为我是在开发类而不是组件。你是说很多人都在为别人开发在Delphi、VB和Java中使用的组件么?你说的“组件”到底是什么呢?

Anders Hejlsberg:“组件”一词包含的最重要的意思是组件可以很好的移植。这听起来十分美妙,但我们可能对此有不同的理解。在一个最简单的form中,一个组件可能就等同于一个附加了一些数据的类。组件是一个独立的软件部件,并不仅仅包含代码和数据。它是一个通过属性、方法和事件来实现自我暴露的类;是一个包含了元数据、命名模式等很多附加特征的类。这些特征可以给特定的开发环境提供动态信息,如:组件怎么使用,组件如何持久化自己的数据。开发环境使用组件的元数据就能够实现组件功能的智能解释并给出相应的说明文档。“组件”包含了如上所述的全部(内容)。

Bill Venners:    我使用Java作开发时想到的是,我是在开发类库而不是组件库,可能是因为我觉得get/set太笨重了。在激发事件的时候,我也使用get/set,但我没有打算将这些类拿到集成开发环境中去使用,我一直想象这些类就是给那些那些纯编码的人们使用的。所以我很想知道现在到底有多少人在开发类似JavaBean那样的组件,面向组件开发是否是未来的趋势,因为在我的职业生涯中,和组件打的交道太少了。

Anders Hejlsberg:当今,主流的面向对象编程语言实际上都是混血儿。其中有大量的结构化编程,对象基本上也不过是一个包含了一系列方法和一个this指针的结构体。当你想到一个对象或者组件时,我想,从概念来说,你应该意识到它是有属性和事件的。如果编程语言能给予这些概念头等待遇的话,理解它就要容易一些。

  有人可能说,C#对于属性和事件的支持不过就是个“甜果”(译者注:原文为syntactic sugar。Peter Landin发明的一个术语,意思是“增加到语言中、让人们感觉更舒服的特性”)而已。其实它的确就是个甜果,对不对?哼,对象本来就是个甜果嘛。我们不过就是在那些虚拟函数表(VTBL)上打转,你用C语言的宏也能实现,对吧?真的,你可以用C语言来面向对象编程,不过它的纷繁复杂能让你坠入地狱。同样的,你可以在C++或者Java里编写组件,但是因为这些语言没有给予组件概念足够重要的地位,所以要痛苦得多。还得说明一下的是,属性,并不是真的是一个属性,而是getBla和setBla(两个方法)。在属性观察器中,你看到的是Bla,但你应该知道它内部映射到了get/set。

  很明显,组件导向是大势所趋。我们就是通过组件来使用我们的类的,但是在大多数语言中,组件并没有成为最重要的概念。我想强调的是,组件应该拥有头等地位。对于PME编程模式——属性、方法、事件——的谈论已经持续了很长的时间,我们也都在日复一日的使用这些东西来编程,那为什么不在编程语言中给予它应有的至高待遇呢?


附注:Anders Hejlsberg 简历

  Anders Hejlsberg 是 Microsoft 公司卓越的软件工程师,领导设计了C#(发音为“C Sharp”)编程语言。Hejlsberg 于上个世纪80年代初投身软件事业,为 MS-DOS 和 CP/M 平台开发了 Pascal 编译器。成立不久的一家小公司 Borland ——很快聘用了 Hejlsberg 并收购了他的编译器,然后改名为 Turbo Pascal。Hejlsberg 接下来领导开发了 Turbo Pascal 的替代产品:Delphi。1996年,Hejlsberg 在为 Borland 工作13个春秋后,加盟 Microsoft 公司(译者注:因为 Borland 公司内部矛盾和 Microsoft 的殷勤)。

用C#描述数据结构4:模拟冒泡排序过程,比较次数分析 先生成一堆乱序的集合。在.NET中通过Random,生成随机数,模拟了排序的过程,分析了两两比较大于1次的比较! 立即下载

相关推荐

实战解析:利用Wireshark解密QQ通信协议

本文提供了一份利用Wireshark工具分析QQ通信协议的实战指南。文章详细介绍了从环境准备、捕获数据包到解析协议层的完整流程,重点演示了如何识别QQ号码字段、观察加密数据特征以及区分不同通信类型(如文本、文件传输)。通过此实践,读者可以深入理解网络分层模型和现代应用加密通信机制,提升网络协议分析与安全诊断能力。

weixin_29210727的博客 407

Anders Hejlsberg谈C#设计过程

Anders Hejlsberg谈C#设计过程 原文:http://msdn.microsoft.com/vcsharp/headlines/hejlsberg/default.aspx Anders Hejlsberg为Borland工作13个春秋后,于1996年加盟微软,最初参与设计Visual J++和WFC(Windows Foundation Classes)。然后,担任C...

javasee 197

IS-IS协议深度解析(二):LSDB同步机制与骨干网实战部署

本文深度解析IS-IS协议的LSDB同步机制与骨干网实战部署。详细阐述了DIS角色如何通过CSNP/PSNP报文高效管理链路状态数据库同步,并与OSPF DR机制进行对比。重点介绍了Level-2骨干网作为逻辑高速公路系统的工作原理,以及通过ATT比特位实现跨区域路由的自动化。最后提供了高可靠性骨干网的实战配置要点与验证方法。

kite3的博客 644

C#之父 Anders Hejlsberg

Anders Hejlsberg,丹麦人,曾在丹麦科技大学学习工程学。      Anders Hejlsberg第一次登上软件界历史舞台是在80年代早期,因为他为MS-DOS和CP/M设计了一个Pascal编译器。当时,还是一个小公司的Borland很快雇用了他,并买下了他的编译器,改称Turbo Pascal。在Borland,Hejlsberg继续开发Turbo Pascal,并最终...

weixin_34074740的博客 293

数控弯管机xyz转换ybc的算法_数控弯管机技术的更新和应用.pdf

您所在位置:网站首页 > 海量文档&nbsp>&nbsp汽车/机械/制造&nbsp>&nbsp机械/模具设计数控弯管机技术的更新和应用.pdf3页本文档一共被下载:次,您可全文免费在线阅读后下载本文档。 下载提示1.本站不保证该用户上传的文档完整性,不预览、不比对内容而直接下载产生的反悔问题本站不予受理。2.该文档所...

weixin_31493101的博客 1521

C# 与欧姆龙 PLC 实战:通过 Ethernet/IP 协议进行设备控制与监控

本文介绍了如何通过C#和Ethernet/IP协议实现与欧姆龙PLC的通信。Ethernet/IP是基于以太网的工业协议,适用于工业设备间的实时数据交换。文章详细讲解了使用EthernetIPSharp库建立连接、读写数据的步骤,并提供了示例代码。此外,还探讨了实时监控、报警系统等高级功能,为工业自动化控制系统开发提供了实用指导。该方法简化了PLC通信开发,提高了系统可靠性和智能化程度。

这里只有干货:从 Modbus 通信到 MES 对接,从 YOLO 训练到工控机部署,带你搞定工业软件开发全流程。 811

编程语言大趋势

JDK1.6.0+Tomcat6.0的安装配置 JDK1.6.0+Tomcat6.0是经典的编程搭配,那么本文就将向你介绍JDK1.6.0+Tomcat6.0的安装配置,图文并茂希望可以帮助初学者搭建平台。 JDK1.6.0+Tomcat6.0的安装配置是如何进行的呢?我们按照下面几个步骤来:1.安装JDK 这是进行JSP开发的重要一步,也是安装JSP引擎(Tomcat、Resin、Weblogic等)的前提,一般的JSP引擎是由Java语言编写的。本人使用的JDK版本是1.6.0,平台是Windows

fighter_hua的专栏 729

52-Halcon-- smooth_object_model_3d函数功能(滑处理3D对象模型)

Halcon中smooth_object_model_3d算子详解 该算子用于3D模型平滑处理,提供三种算法:'laplacian'(快速去噪)、'taubin'(高质量防收缩)和'low_pass'(频域滤波)。核心参数包括迭代次数(默认5)、平滑强度(0-1)和边缘保护选项。典型应用包括扫描数据去噪、CAD模型光顺和逆向工程优化。支持自适应平滑、结合模型简化等高级技巧,并可通过分块处理优化大型模型性能。参数组合需根据具体场景选择,如快速去噪推荐拉普拉斯方法(5次迭代,强度0.3),特征保持推荐低通滤波(

weixin_45590420的博客 873

C# 多线程编程 经典模型 哲学家进餐问题

语言:C#   总起: 今天的哲学家进餐问题是最后多线程模型,讨论的是在有限的资源里线程竞争导致死锁、饥饿等问题。   没有接触过多线程编程的同学,可以先看一下第一章。   哲学家进餐问题: 该问题说的是,有5个哲学家围在一个圆桌前进餐,每个哲学家两旁有两把叉子,一共5把叉子。每个哲学家进行进餐需要拿起左右两把叉子,吃完之后将两把叉子放回供其他人使用。   这个是wiki上的图

暗光之痕的博客 2843

RK3568平台开发系列讲解(音频篇)配置声卡

📢本篇文章介绍如何配置声卡。

内核笔记 2448

OsgEarth开发笔记(三):Osg3.6.3+OsgEarth3.1+vs2019x64开发环境搭建(下)

上一篇编译了proj6.2.0、gdal3.2.1,本篇继续。 OsgEarth的编译,是基于Osg和OsgEarth结合在一起的,先要编译Osg,然后编译OsgEarth。OsgEarth的依赖库较多,分为上、中、下三篇,然后单独有一篇如何将编译好的osgEarth集成到Qt中。

长沙红胖子 Qt・西安|省级科研团队从业背景,深耕双一流体系高精尖技术配套研发|剥离高精尖机理,沉淀高端特种行业领域 Qt 工程化落地经验|博文仅分享通用技术总结,输出公开普适工程思路。 4万+

Anders Hejlsberg访谈:C#的设计过程

本访谈系列的翻译已经征得原作者的同意,转载请保留原作者和译者的链接。Copyright © 1996-2005 Artima Software, Inc. All rights reservedThe C# Design ProcessA Conversation with Anders Hejlsberg, Part Iby Bill Venners with Bruce Eckel

7962

ZYNQ USB按键读写操作详解:从裸机到Linux系统的完整实现

USB接口在现代嵌入式系统中扮演着至关重要的角色,而按键作为最基础的人机交互设备,其与USB的结合能够实现丰富的应用场景。这种实现不仅适用于简单的键盘应用,还可以扩展为游戏控制器、专业输入设备或工业控制面板,展现了ZYNQ在嵌入式USB应用中的强大灵活性。:USB控制器需要准确的时钟源,通常使用外部33MHz晶振,并在Vivado中正确配置。结合ZYNQ的PL(可编程逻辑)和PS(处理系统)优势,可以创建创新的USB按键应用。本文详细介绍了在ZYNQ平台上实现USB按键读写的完整方案,涵盖了从。

QQ_778132974的博客 377

Anders Hejlsberg访谈:版本,虚函数和覆写

本访谈系列的翻译已经征得原作者的同意,转载请保留原作者和译者的链接。Copyright © 1996-2005 Artima Software, Inc. All rights reservedVersioning, Virtual, and OverrideA Conversation with Anders Hejlsberg, Part IVby Bill Venners with

5828

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

软件界的传奇—Anders Hejlsberg

推荐看一下《Borland 传奇》,以下是转载正文: Anders虽然没有显赫的学历,无法获得TurningAwards。但Anders的实力和贡献绝不输于任何一位TurningAwards获得者。       对于成千上万的使用Borland TurboPascal和Delphi进行编程的软件开发者来说,AndersHejlsberg,这位丹麦的软件大师让他们肃然起敬,是他创制了上述

malei0311 的专栏 1100

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

语言大师 Anders Hejlsberg

语言大师Anders Hejlsberg介绍  1.Anders图片     Anders Hejlsberg,是丹麦人,曾在丹麦科技大学学习工程学。1981年前,Anders Hejlsberg 在丹麦有个公司叫Poly Data,他编写了Pascal编译器核心,最初叫Compass Pascal,后来叫Poly Pascal。1981年,Anders把该编译器核心授权给了Borland。And

大白(奋斗)的专栏 2817

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

Anders Hejlsberg访谈:Checked Exceptions的问题

本访谈系列的翻译已经征得原作者的同意,转载请保留原作者和译者的链接。Copyright © 1996-2005 Artima Software, Inc. All rights reservedThe Trouble with Checked ExceptionsA Conversation with Anders Hejlsberg, Part IIby Bill Venners wit

6510

Anders Hejlsberg 谈 c# 3.0

在采访中Anders Hejlsberg提在C# 3.0中提供一种新的通用的数据库访问方式,一个真正面向对象的访问方式。http://channel9.msdn.com/ShowPost.aspx?PostID=10276 转载于:https://www.cnblogs.com/Hush/archive/2004/09/23/46092.html...

weixin_30347335的博客 159

Anders Hejlsberg访谈:委托、组件以及表面上的简单性

本访谈系列的翻译已经征得原作者的同意,转载请保留原作者和译者的链接。Copyright © 1996-2005 Artima Software, Inc. All rights reservedDelegates, Components, and SimplexityA Conversation with Anders Hejlsberg, Part IIIby Bill Venners

5835

C#、TypeScript之父Anders Hejlsberg:“会用Excel就是程序员 ”

【优快云 编者按】近日,C#和TypeScript等编程语言的创造者Hejlsberg与TNS新闻编辑Darryl K.Taft进行了一场线上对话,围绕微软低代码/无代码、Web3等话题...

优快云资讯 1392

Anders Hejlsberg

虽然Anders没有显赫的学历,无法获得Turning Awards(即图灵奖,信息科学界最高 荣誉的奖项,等同于诺贝尔奖)。但是我认为Anders的实力和贡献绝不输于任何一位 Turning Awards的得奖人。Anders是最好的信息实践型人物,在...

chuifuhuo6864的博客 193

Anders Hejlsberg 访谈 .-转载

楔子:       我是从DELPHI一直走进.NET的,我对工程和实用性比算法看的重要的多,我认为工程更加可以产生出没敢; 我见过很多年纪比较大的程序员,埋头苦干,很少思考美学,可能是没有站到软件工程领域思考我们的程序; 站在市场的角度如何,JAVA的精髓学了多少,不是语

蓝叶菱的专栏 1082

(PDC2008)Anders Hejlsberg: The Future of C#

Anders Hejlsberg 在PDC上的视频,绝对不能错过! The Future of C# http://channel9.msdn.com/pdc2008/TL16/ 视频下载地址:http://mschnlnine.vo.llnwd.net/d1/pdc08/WMV-HQ/TL16.wmv PPT下载:http://mschnlnine.vo.llnwd.net/d1/...

weixin_33907511的博客 95
上一篇: 开源的 BugTracker.net 错误跟踪管理系统
下一篇: 开源还是不开,难道是个问题? [转载]
SW515
博客等级 码龄26年 12粉丝 56原创
评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值