`
ooaer
  • 浏览: 137465 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

动态语言之三:语言的动态性

 
阅读更多
http://blog.csdn.net/hongbomin/article/details/6979314
3.1  语言的动态特性

介绍动态语言之前,首先介绍一下语言的动态特性,并引出动态语言的定义。

语言的动态特性表示语言具有在运行时确定绑定关系的性质。实际上,“静态”是一个相对的概念,任何程序设计语言都可以看作具有某种程度的动态特性。一个变量能够在运行时改变自身的值,可以说它具有动态特性,比如最简单的赋值语句:

char ch;int  m;
ch = cin.get();//从输入流中接收一个字符
m  =  func();  //将func的返回结果赋给m

对字符型变量ch与值的绑定关系要推迟到程序运行时检测到标准I/O流的输入数据才能确定下来,整型变量m的值也要到程序运行时执行了函数func后才能确定。在运行时进行的动态类型检查、动态内存分配都是语言的动态特性的具体表现。变量的寻址方式也是一个动态的过程。程序经编译后,获得了变量的相对于程序代码段(CS)或数据段(DS)的偏移量信息,在程序执行时,操作系统首先将程序装载到内存中足够大小的某个单元中,这个单元的首地址加上变量的偏移量就形成了变量的存储单元地址。此外,面向对象语言中运行时多态性是一个重要的动态特性。从这个意义上说,早期Fortran语言、C、Pascal都具备一定程度的动态特性,但比较弱,而Smalltalk、Lisp、Python等语言在运行时可以改变变量的类型甚至时自身的程序结构,我们就认为这样的语言具有更强的动态特性。

不同的语言具有不同程度的动态特性。纵观程序设计语言的发展史,如果将Fortran和Lisp语言看作是语言在动态特性上的两个极端的话,那么现代大多数语言都是介于二者之间的折中,综合考虑了开发效率和执行效率以及其他众多因素。各种语言也在相互借鉴,不断演变。下图是以Fortran和Lisp为两头,比较了几种语言的动态性程度:


在上图中,从左到右语言的动态特性逐渐加强。处于最左端的Fortran语言不支持堆栈,所有的变量和子程序都是在编译时分配好内存的,不能进行动态内存分配,因而不能进行函数递归调用,许多问题的解决方式受到极大的限制。这主要是由早期Fortran语言的设计目标决定的,早期Fortran语言主要是为了解决科学和工程中的计算问题,优先考虑的是语言的执行效率。虽然Fortran语言被无数次认定为过时,然而它仍然继续发展着。 Fortran90大大扩展了传统Fortran的功能,增加了现代高级语言的数据和控制特征,允许内存的动态分配,使得它具有和C和Pascal语言相当的能力。

比Fortran动态性更强的C/C++语言提供了指针,支持堆栈,提供了malloc/new和free/delete操作,运行时可以动态分配和释放内存,可以比较灵活地动态生成对象并分配存储空间。此外,C++语言中的RTTI(RunTime Type Identification)机制可以在只有指向某个对象的基类指针的情况下,根据驻留在虚函数表中的类型信息,在运行时确定该对象的准确类型。然而,C/C++程序中的变量类型仍然需要在编译时确定下来,大部分类型检查也是在编译时完成的,执行前完成了大部分的绑定工作。

现在流行的 Java和C#语言的动态特性之所以要比C/C++强,是因为Java/C#提供了更强的反射Reflection机制,可以在运行时通过 Reflection APIs取得任何一个已知名称的class的内部信息,包括其modifiers(诸如public, static 等等)、superclass(例如Object)、实现的interfaces(例如Cloneable),也包括fields和methods的所有信息,并可于运行时改变fields内容或唤醒methods。如在C#中,可以通过System.Type类在运行时获取任何给定数据的类型信息,包括构造函数、属性、方法和事件,也可以唤醒(Invoke)相关的方法(具体的使用可参考Microsoft出版的《Inside C#》的“Querying Metadata with Reflection”一章)。

而Smalltalk以右的语言,变量的类型绑定和类型检查都是在运行时进行的。Perl、Python和Ruby语言可以在运行时修改类的结构或定义,变量的类型可以按需改变,编写程序时无须声明变量类型。Lisp语言甚至可以在运行时动态地改变自身的代码, Lisp语言对程序代码和数据一视同仁,都看作是存储在内存中的对象,这样数据结构既可作为程序执行,程序也可作为数据进行修改。

上面介绍的几种语言都具备一定程度的动态特性,那么应该如何定义动态语言呢?目前在许多开发社群中,提及“动态语言”,一种普遍的观点是认为“动态语言是指能够在运行时改变程序结构和变量类型的语言”,有时也称作“动态类型语言”(Dynamic Type Language),本文采用的就是这种观点,在下文中的动态语言都是指具有这种性质的语言,与之相对的概念“静态语言”指的是在编译阶段确定变量或数据对象类型的语言。按照这种说法,上图中Smalltalk/Perl以左的为静态语言,以右的语言都为动态语言。这里需要说明的是,许多技术文章和语言研究中都涉及到“脚本语言”的概念,实际上脚本语言就是动态语言,因为脚本语言也具备在运行时动态改变类型的性质,符合动态语言的定义,本文不区分这两个概念,一律使用“动态语言”,强调该类语言的最明显的特征。另外,有的人也将“静态语言”称之为“系统程序设计语言”,因为大多数静态语言都是系统程序设计语言,这两个概念只是从不同的角度描述了同一类语言,各自的侧重点不同,“静态语言”的“静态”是基于绑定时间的,强调了语言中大部分绑定关系是发生在运行前,而“系统程序设计语言”强调语言所能完成的功能是侧重于编写系统程序。

3.2  动态语言的特点

近几十年来,传统的软件开发模式和工具、编程语言已难以适应软件需求的变化,软件的混合式开发逐渐增加。随着动态语言的兴起,人们的编程方式和观念发生了转变。在诸如C/C++、 Java、C#之类的静态语言中,语法规则迫使程序员在使用一个变量前首先要声明它的类型,变量的类型一旦确定下来,那么在整个程序中都不能改变,只能是一种类型。而在象Smalltalk、Python、Perl、Tcl、Ruby、Visual Basic和Unix Shells的动态语言中,无类型化定义使程序员从庞大的类型系统解脱出来,变量不经声明就可以直接使用,变量的类型可以按需改变,编写程序变得轻松自由。本节主要介绍动态语言的特点和编程方式,以及与静态语言的主要区别和联系。

动态语言,顾名思义,最显著的特点就是在于它的“动态性”,即运行时可以按需改变程序结构和变量类型、函数的定义等,这也是与静态语言的根本区别。除此之外,动态语言还有许多特点,这些特点深受开发人员的喜爱,使得动态语言渐入人心。

3.2.1 动态类型

类型系统影响了语言的诸多特性。在静态语言中,声明的目的是为了告诉编译器所使用的变量“是什么”,使类型检查可以在编译阶段静态地进行,尽量减少执行时的类型检查,提高执行效率,但缺乏灵活性。而在动态语言中,没有声明语句,赋值语句将名称绑定在数据对象上,如果名称赋予数据对象一种类型,稍后也可以给对象赋予另外一种类型。变量被设计成无类型的,变量的类型可以按需改变,同一个变量既可作为整型的,也可作为字符串,还可用来定义函数。

我们知道,程序中定义的操作一般需要特定类型的参数作为操作的输入,操作只有在接收到类型正确的参数时才能正确无误的执行,最典型的实例就是函数的定义,函数的原型包括函数的参数列表和返回值类型,参数列表提供输入参数的全部信息,执行函数前首先要进行参数类型的检查。在动态语言中,变量是无类型的,那么如何保证所执行的操作是否接收到类型正确的参数呢?在运行时进行动态类型检查机制解决了类型安全这一问题。动态类型检查通过在每个数据对象中保存一个类型标签表明该数据对象的类型,比如在表达式C=A+B中,A和B的类型在程序运行时确定,也可以在运行时改变,所以每次执行 + 操作时都要根据类型标签对A和B的类型进行检查,只有在类型正确的情况下才能执行,否则发出错误信号。操作正确执行后,确定了变量C的类型,并记下C的类型标签以备随后可能的操作进行类型检查。

显然,动态类型检查不能静态地检测到程序代码中类型不匹配的错误,并不意味着动态类型容易在程序中引入类型安全的错误。事实上,在诸如C++、Java之类的静态类型语言中虽然能够在编译时尽可能多的检测到程序中类型失配的错误,但类型仅仅是数据的一小部分信息,类型正确并不能保证程序中不存在其他的错误。在大规模的程序中,要为类型上编写大量的语句,这就使得程序员专注于程序中的类型正确性而容易忽视程序其他部分的正确性。有些问题用静态类型很难实现,例如对于一个不支持泛型编程的语言来说实现一个可以支持多种类型的容器类就比较困难,假如编写了一个可以存放objects的容器类,在具体应用时要通过向上或向上转换成所需的类型,而这种转换往往是不安全的。而动态类型语言不需要这种转换,它所实现的容器类完全是泛型的,在语言一级就提供了良好的支持[3]。裘宗燕教授则认为“很多人之所以在最初使用具有丰富动态特征的语言编程时容易犯错误,主要是因为他们习惯了诸如C、Pascal等语言,不了解用这些动态特征丰富的语言中编程的一些必要的风格和习惯。如果熟悉了这些风格和习惯,犯错误这件事情同样是可能很好地避免的。使用弱类型的语言同样可以开发很好的系统,而且实际上已经开发了很多很好的系统。”[6]。

动态类型检查的主要优点在于程序设计的灵活性,不需要声明语句,一个变量名绑定的数据对象的类型可以在程序执行时按需改变,使程序员从数据类型摆脱出来,同时也可以编写更少的程序代码行完成同样的功能。动态类型是动态语言的最显著的优点,但也是动态语言的弱点根源所在。运行时进行的类型检查也存在几点重大不足:

a. 程序难以调试。因为动态类型检查只在程序运行到某一条操作时才对其进行类型检查,而ü 从来不ü 检查没有被执行的执行路径上的操作。在软件测试时是不ü 能遍历程序中所有的执行路径,ü 这样没有被执行的路径仍有可能存在bugs。这一点可能是动态语言致命的缺点,它导致了动态语言对开发大型软件项目支持力度不够。

b. 保存大量的类型信息。运行时需要相当大的额外存储空间。

c. 执行效率低。动态类型检查要靠软件模拟实现,主要是在运行时完成的,所以在执行速度上降低了不少。 

静态类型和动态类型都有各自的优点和缺点,不能简单地认为静态类型比动态类型要好或者动态类型比静态类型要好[3],关键要看具体应用的场合。

3.2.2 开发效率高

在动态语言社区里,值得开发人员津津乐道的是动态语言具有比静态语言高数倍的开发效率。虽然静态语言在执行效率上比动态语言略胜一筹,但在开发效率上只能甘拜下风。正如前文所提到,程序设计语言逐步从面向机器到面向人过渡,以牺牲运行效率来换取开发效率。如今,计算机硬件性能的大大提升,我们能够承受起动态语言在执行效率上的损失,实际上,只有很少的应用才需要尽可能的利用机器的性能。目前,普遍认为Python的开发效率要比Java高出5-10倍。那么动态语言为什么会在开发效率方面具有天独厚的优势?下面就从几个方面进行说明:
 
a. 易学易用,编程人员可快速上手

Python、 Perl、Ruby等动态语言具有简洁的语法规则,交互式的编程环境,比C++、Java等静态语言更容易学习和掌握。比如Python语言,语言的语法结构、控制结构和C/C++十分类似,对于一个熟悉C、C++语言的编程人员来说,花3-5个小时完全可以掌握Python的语法特性。软件的复杂性在于整合了千丝万缕的关系,交互式环境把程序分解成一块块,对于不熟悉的语言特性,可以方便输入交互式命令进行测试。动态语言不需要声明语句的编程方式使得动态语言更加接近于自然语言,简单明了,易学易读,许多优秀的语言特性都是语言大师深思熟虑之后的产物。对于一个软件项目来说,项目经理更愿意选择一门易于上手又同样可以完成任务的编程语言作为软件的开发语言,一则可以减少员工的学习成本,二则有利于缩短项目完工的时间。
动态语言的易学易用性最终导致了编程群体的改变。二十年前大多数编程者是大型项目的专业编程人员.那个时代的编程人员需要花几个月的时间掌握一门语言和它的编程环境,系统程序设计语言(静态语言)就是为这些人设计的.然而,自从个人电脑出现以后,越来越多的非专业编程者加入到编程者的行列.对这些人来说,编程不是他们的主要工作,而只是他们偶尔用来帮助他们工作的工具。偶尔编程的例子是编写简单的数据库查询或者是电子数据表的宏.非专业编程者不希望花几个月的时间学习一门专为系统程序而设计的静态语言,但他们可以花几个小时的时间学到足够的动态语言知识来写出有用的脚本代码。由于动态语言有简单的句法并且省略了诸如对象和线程的复杂特性,因而它比静态语言要更容易学习和掌握。例如,非专业编程人员很少会选择Visual C++,而大部分会用Visual Basic编写有用的应用程序[1]。

b. 内置丰富的数据结构和操作

实际上,动态语言是建立系统程序设计语言之上的语言,大多数动态语言解释器的内核都是用某种静态语言实现的,Python是用C实现的,JVM上的Jython是用纯Java实现的,.Net CLR上的IronPython是用C# 实现的。动态语言将灵活性作为其设计的目标,优先考虑了语言的灵活性。因此,动态语言在语言层次上集成了许多操作方便、性能良好、高度抽象的数据类型,为编程人员提供了高效的数据结构实现,有助于提高开发效率。以Python语言为例。Python语言提供了强大的数学运算,可以处理超大的整数和浮点数,支持复数的基本运算。Python内置了功能强大、使用方便的数组类型,程序员不需要预先声明使用数组的大小就可以直接使用数组,也不必担心数组大小不够,这些解释器会自动根据具体地操作动态地分配数组的存储空间,不象C/C++中使用数组首先必须声明数组的大小,这就使得很多人在使用数组时不知道究竟应将大小设置成多少,大了觉得浪费,小了又担心不够,想改成指针方式动态分配又有可能给程序带来新的问题。对数组类型还有一系列灵活的操作,比如可以在数组任何位置插入元素,可以对数组分片,可以将数组的某一片作为参数传递给某个函数而并不需要将数组从头到尾的都传递。在Python的具体应用中使用可能最广当属字典类型(Dictionary Type)。字典类型是Python内置的高效强大的数据类型,是一种类似于关联表和哈希表的结构,Python的实现者花费了大量的时间对字典类型做了优化,以尽可能保证语言的高效性。Python内部实现也使用了大量的字典类型。如果没有提供这些内置的数据类型,开发人员可能需要独立开发出支持所需的数据类型的库程序,而开发这样库不但费时,而且在性能优化和接口通用性方面欠佳。正是因为动态语言内置了丰富的数据类型,节省了开发人员独立实现这些数据类型的时间,从而提高了程序的开发效率[4]。

c. 无类型化,用更少的代码可完成同样的工作

动态语言的动态类型使得编写程序时不需要声明变量的类型,变量无类型化省去了程序代码中大量的编译器编译时所需的类型信息语句,使程序看上去简洁明了。
比如在Tcl语言中,如命令:

button .b -text Hello! -font {Times 16} -command {puts hello} 

创建了一个新的按钮来显示16点Times字体,当用户敲击控制键时显示一段小信息。它把六种不同事件类型混合成一条语句:一个命令名(button)、一个按钮控制(.b)、所有权名字(-text, -font, 和-command),简单字符串(Hello! 和hello),包含字样名(Times)及字点大小(16)的字体名(Times 16)和Tcl脚本(puts hello)。Tcl统一用字符串表示了这些类型。

上述例子在Java中要调用两个方法完成,需要7行代码。用C++和微软基本类(MFC)需要三个过程,25行代码,在微软基本类中仅仅设置字体就需要几行代码: 
CFont *fontPtr = new CFont();
fontPtr->CreateFont(16, 0, 0,0,700, 0, 0, 0, ANSI_CHARSET,
OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
DEFAULT_PITCH|FF_DONTCARE, Times New Roman);
buttonPtr->SetFont(fontPtr);  

   大部分代码是由静态类型造成的。为了设置按钮字体,必须运用SetFont方法,但这个方法必须通过指针传给CFont对象,这反过来需要声明和初始化一个新的对象.为了初始化CFont对象必须唤醒它的CreateFont 方法,但CreateFont有一个需要14个特殊化引数的固定接口。在Tcl中字体(Times铅字,16点)的基本特征不用声明或转换就可以立即使用。另外,Tcl允许在创建按钮的命令中直接包含按钮行为,而C++和Java中需要把它放在单独声明的方法中。
高级程序设计语言的高级性在于它的每一条代码可以完成更多的工作,完成同样的工作,使用的代码愈少,表明语言的等级愈高。每行汇编代码平均可以翻译成1-3条机器指令,与此相比,每行 C/C++代码平均翻译成5条机器指令,而对于Python、Perl、Tcl这样的动态语言,每行代码可翻译成100-1000行机器指令。汇编程序中,基本上是没有类型,所有的数据看起来都是一样,机器的每个细节都暴露在代码中,程序员必须显式地管理寄存器和内存分配、栈调用等等,所有的操作都涉及到最底层的设备操作,对程序员的专业素质要求高,用汇编语言开发程序效率低下,因此难以编写和维护大型程序。到高级语言出现后,编译器隐藏了机器的底层细节,能够自动管理存储分配、目标代码生成和优化、过程调用顺序等操作,有了抽象数据类型,将程序员从面向机器的复杂中解脱出来,提高了程序的开发效率。
动态语言把许多工作都交给解释器去完成,程序员专注于自己需要解决的问题,建立问题解决方案的逻辑就够了,因此更接近于自然语言。比起静态语言,动态语言的一条语句可以完成更多的功能。从这个意义上说,动态语言是一种更高级的语言。因此,动态语言具有更高的开发效率。

3.2.3 支持动态重构

随着软件应用面临的问题多样化和复杂化,有些应用领域中逐渐出现这样一类需求:要求软件在运行时还能够改变,即动态重构。比如在一个银行系统中,要求软件一旦运行,就不能停下来,否则会对银行造成灾难性的损失,那么这样的系统中如果在运行时发现某个错误怎样修正呢?显然,用静态语言很难实现,因为静态语言在运行时不能修改自身代码,用静态语言实现的系统执行的是经过翻译处理后的可执行代码,要修正软件必须要经过修改源代码->编译->连接 ->生成可执行程序的步骤。而动态语言比较容易实现,动态语言是解释执行的,运行时还能够修改自身的代码。国外有人用Smalltalk实现了这样一个分布式的银行系统,银行系统留有一个接口,开发好的系统发现bug后,维护人员可以通过该接口远程登录后,可以在系统不停止运行的情况下把bug消除掉。

3.2.4 胶水语言(Glue Language)

动态语言一个广泛的应用就是作为“胶水语言”胶合用静态语言编写的组件,从而整合成一个应用程序,这种应用称之为混合式应用。RedHat Linux的安装程序就是通过Python胶合各个组件模块实现的。静态语言开发的程序运行速度快,但开发周期较长,而动态语言灵活简洁,开发效率可提高 5-10倍,但程序运行慢,混合式应用合理结合各自的优点,充分利用不同语言的各自优势,取长补短,可以快速高效地构建应用程序并具有相当的性能。[8]

这里介绍动态语言具有静态语言所没有的优点并不是意味着动态语言要替代或推翻静态语言,而是作为静态语言有力的补充。当然,动态语言不能回避的就是它与生俱来的缺陷,比如执行效率低下、对大型软件开发的支持力度不够等等,使得动态语言难以成为主流的开发语言。现代软件面临的问题越来越复杂,软件工程领域中没有“银弹”可用,同样,也没有一种语言可以成为软件开发的“万金油”,可以很好地解决各类问题,每种语言都各有所长,也各有所短。动态语言和静态语言相互补充,相得益彰,扬长避短,才能充分发挥不同语言的优势,在软件开发中做到“动中有静,静中有动,动静结合,各司其职”。

3.3  动态语言的发展

近几年来,动态语言的发展势头良好,受到越来越多的关注,开发社区显得十分活跃。尤其是Internet的发展,为动态语言提供一个良好的展现个性的活动舞台。Perl因为编写CGI而变得流行,VBScript和JavaScript因为能编写网页而在互联网上广泛使用。
目前,动态语言已经进军当前主流的Java VM/.Net平台。Jython是Python语言在Java VM上的完全实现,是用纯Java语言编写的,可以轻松的访问所有的Java类库。Groovy也是Java VM上一款非常流行的动态语言,并作为JSR草案正式提交给标准化组织审议。IronPython是.Net平台上Python的高效实现。
动态语言的应用已经深入到系统脚本、服务器程序、游戏开发、数据库引擎和CAD系统的开发中,我们有理由相信,随着Internet的发展趋势和混合式应用的扩展,计算机硬件的快速发展,动态语言将会展现蓬勃的生命力,与静态语言一同构建强劲的编程环境,在软件开发中扮演越来越重要的角色。
分享到:
评论

相关推荐

    Java语言的动态性支持(二)

    NULL 博文链接:https://uuhorse.iteye.com/blog/1706466

    Ruby动态编程语言v2.6.3

    Ruby是一种跨平台、面向对象的动态类型编程语言。Ruby 体现了表达的一致性和简单性,它不仅是一门编程语言,更是表达想法的一种简练方式。 Ruby 是一个注重均衡的语言,它的发明者松本行弘(Yukihiro “Matz” ...

    go语言圣经 .pdf

     Go语言保证了既能到达静态编译语言的安全和性能,又达到了动态语言开发速度和易维护性,有人形容Go语言:Go = C + Python , 说明Go语言既有C静态语言程序的运行速度,又能达到Python动态语言的快速开发。...

    go语言中文教程及手册.pdf

    它是快速的、静态类型编译语言,但是感觉上是动态类型的,解释型语言。 《go语言中文教程及手册》包含了语言结构、基础语法、数据类型、语言变量、语言常量以及运算符等内容的介绍,可以让你快速进阶为go语言编程...

    Python 简介 Python 是一个高层次的结合了解释性、编译性、互动性和面向对象的脚本语言.rar

    1.扩建的语言,是为了缩短传统的编写-编译-链接-运行(edit-compile-link-run)过程而创建的计算机编程语言或者动态语言,用来控制软件应用程序,脚本通常以文本(如ASCII)保 存;例如php,js,asp,Python,ruby等 ...

    Go语言圣经,golang学习入门到精通

    Go语言有时候被描述为“C类似语言”,或者是“21世纪的C语言”... Go语言有足够的类型系统以避免动态语言中那些粗心的类型错误,但是Go语言的类型系统相比传统的强 类型语言又要简洁很多。虽然有时候这会导致一个“无类

    Java程序设计基础:Java语言概述.pptx

    Java语言概述 Java开发基础--Java语言概述 Java语言概述 了解Java语言历史和特点 ...动态特性(dynamic) Java语言特点 跨平台:Java引进虚拟机(JVM)原理。 Java虚拟机是Java语言的运行环境,用来运

    多语言融合网络工程课设:KNN用户评分协同过滤算法实现源码

    项目名称:多语言融合网络工程课设 - KNN用户评分协同过滤算法实现 项目概述: 本项目采用多种编程语言共同实现了一套基于KNN(K-近邻)算法的用户评分协同过滤系统。该系统主要用于预测用户对未评分项目的评分,...

    java jdk1.7windows免安装版下载

    4、对动态语言的支持:JDK 7增强了对动态语言的支持,并提供了一个新的字节码指令invokedynamic,以提高动态语言的性能。 5、改进的JVM:JDK 7提供了许多新的JVM特性,包括增强的垃圾回收器,更好的性能监视和分析...

    理想周行:旅游出行之约拍摄影平台(微信小程序)DreamTravel.zip

    JavaScript:用于在网页上实现交互性和动态效果的脚本语言。 React:一个流行的JavaScript库,用于构建用户界面。 Angular:一个用于构建Web应用的前端框架。 Vue.js:一个渐进式JavaScript框架,用于构建交互式界面...

    C# 语言规范 版本5.0中文.pdf

    C# 提供的语言构造直接支持这些概念,这使得 C# 语言自然而然成为创建和使用软件组件之选。 有助于构造健壮、持久的应用程序的若干 C# 特性:垃圾回收 (Garbage collection) 将自动回收不再使用 的对象所占用的内存...

    华农Linux系统及程序设计实验全部代码+4种动态网页语言完成综合性实验

    老师给的参考资料,免责声明,分享大家一起参考和学习,希望能帮助大家

    R语言分析了一个在线社区的活动和语言

    分析分为三个主要任务:分析活动趋势,分析语言使用情况以及探索社区内的社交网络动态。以下是关键发现和任务的总结: 任务A:分析活动和语言随时间的变化 在这个任务中,分析着重于了解在线论坛多年来的活动水平和...

    基于SSM和SpringBoot的毕业设计<动态旅游网站>tripweb.zip

    JavaScript:用于在网页上实现交互性和动态效果的脚本语言。 React:一个流行的JavaScript库,用于构建用户界面。 Angular:一个用于构建Web应用的前端框架。 Vue.js:一个渐进式JavaScript框架,用于构建交互式界面...

    基于Java语言实现一次性动态口令算法.pdf

    基于Java语言实现一次性动态口令算法.pdf

    论文研究-基于动态P-模糊语言算子的VIKOR决策方法.pdf

    针对直觉模糊信息解决动态多属性决策问题时存在的不足,将Pythagorean模糊语言信息引入到动态多属性决策问题,提出一种基于Pythagorean模糊语言...通过第三方逆向物流服务商的选择实例,表明该方法的可行性和有效性。

    Spring MVC+mybatis 入门项目:旅游网站introduction-project.zip

    JavaScript:用于在网页上实现交互性和动态效果的脚本语言。 React:一个流行的JavaScript库,用于构建用户界面。 Angular:一个用于构建Web应用的前端框架。 Vue.js:一个渐进式JavaScript框架,用于构建交互式界面...

    基于Java语言对动态连通性算法的研究.pdf

    基于Java语言对动态连通性算法的研究.pdf

    基于SSM框架的旅游门户网站:包括前台模块、后台模块.zip

    JavaScript:用于在网页上实现交互性和动态效果的脚本语言。 React:一个流行的JavaScript库,用于构建用户界面。 Angular:一个用于构建Web应用的前端框架。 Vue.js:一个渐进式JavaScript框架,用于构建交互式界面...

    使用vrml语言创作的桌子,仅供学习参考

    是一种用于建立真实世界的场景模型或人们虚构的三维世界的场景建模语言,也具有平台无关性。 本质上是一种面向web,面向对象的三维造型语言,而且它是一种解释性语言。VRML的对象称为结点,子结点的集合可以构成复杂...

Global site tag (gtag.js) - Google Analytics