模型驱动开发的幻象与现实_软件模型与现实世界相悖-程序员宅基地

技术标签: uml  开发工具  企业应用  工具  编程  MDA相关  图形  

转自http://www.kcomsoft.com/Article49.asp

[编者按] “十年内,没有任何单独的软件工程进展可以使软件生产率有数量级的提高”,Frederick Brooks在1986年做出的这一论断被广泛称为“银弹定律”。Brooks给了这一定律一个10年的期限。然而事实证明他过于谨慎了,在他做出这个论断之后接近20年,银弹定律仍然像魔咒一样紧紧束缚住软件工业。尽管专业人士尝试了大量的新技术和新方法,但是效果令人失望。面向对象被证明有负众望,软件工程更是陷入泥潭,魔咒丝毫没有松绑的意思。我们应当像敬畏“没有永动机”的理论那样敬畏“银弹定律”呢,还是应当去挑战它、突破它?

事实上,软件理论家和实践者一刻都没有停止过突破“银弹定律”的尝试。“模型驱动开发”可能是最新的一次尝试。一般人提到“模型驱动开发”或者Model Driven时,会自然联想到OMG提出的MDA。然而OMG的MDA还处于定义的初级阶段,而一个“纯正”的中国软件企业已经基本实现了模型驱动的软件开发,初步领略了“银弹”的威力。带着浓厚的兴趣,我们采访了凯科思特(北京)科技有限公司。

1.实践中的模型驱动开发

记者:我知道你们把自己这个实践“模型驱动开发”的产品命名为“KCOM商业工程”,你们不觉得这是个很奇怪的名字吗?从任何角度都看不出跟模型驱动开发有什么关系。你们给大家解释解释,什么叫KCOM商业工程?为什么要这么命名?

凯科思特:

“KCOM商业工程”这个名称早在2001年就已经定下来了,刚开始并没有明确到要开发一个“模型驱动开发”工具平台,因为当时还没有“模型驱动开发”这一个概念,OMG也才刚刚开始要定义MDA。因此可以说是完全自发的一种想法,现在看来是殊途同归了,我们猜想即便在国内也有很多人有类似的想法,只不过我们很早想到并付诸实现。

“KCOM商业工程”这个名称其实反映了我们前后两个不同时期的主要技术方向。拆分开来分别是“KCOM”和“商业工程”。这两个名称合在一起,其实也就有“模型驱动开发”的意思。为什么这么说呢?可以这么看,“KCOM”代表的是以代码为核心的产品技术,它的目标是提高代码编写效率;而“商业工程”代表的是以模型为核心的产品技术,它的目标是更好地设计模型。我们把代码开发工具和模型设计工具集成在一起,并想办法让设计出来的模型能自动转换为代码,这就是“KCOM商业工程”的主旨,也就是现在大家所熟知的“模型驱动开发”。

“KCOM”这个词是由‘K’和‘COM’组成的。‘COM’大家都很熟悉,是微软提出并成为标准的组件模型。‘K’是英文Knowledge的首字母,意思是知识和智能。拼在一起意思就是我们要定义一种智能的组件模型,有别于COM组件模型。我们知道,面向对象技术的最直接的发展就是组件技术。组件技术在很大程度上提高了代码的复用程度,也成为RAD(快速应用开发)的基础。但是组件本身的编写仍然具有很大的难度,并且组件是以二进制代码的形式存在的,一旦编译产生,就不能对它进行任何改动。我们可以用COM组件技术来打造软件组件,但是用COM组件来构建业务组件就不大适合了。为什么这么说呢?这是因为企业的业务是动态的,变化的,我们根本无法固化业务组件。如果说组件模型的产生是为了真实地反应现实世界,那么COM组件模型适合描述的是那种无生命的组件。而在我们这个世界里,除了无生命的物质,还有丰富多彩的生命,还有复杂多变的人类社会。从某种意义来说,企业也是有生命的组件。所以,有必要建立一种智能的组件模型用于表达有生命的组件,这样的组件是动态的,并且具有自适应性。什么是自适应性呢?计算机软件组件是由程序代码编写出来的,因此这里“自适应性”的意思就是要求软件组件能自我编写程序代码以响应变化的需求,也就是通常所说的“自动编程”。最初发展KCOM时,首先是出于对技术的狂热,希望将我们认为的这些具有独特并且领先的想法付诸实现,后来这些想法也都实现了。早在2000的时候KCOM组件模型就已经成熟了,而且也完全具备自动编程的功能,只不过当时这种功能还没有在实际的应用开发中使用到。

“商业工程”这个名称来源于对企业管理软件项目开发过程的思考,我们首先考虑到的是工具平台要服务的对象是商业企业,其次考虑到的是要将商业企业应用开发作为一个软件工程来看待。考查一下一个企业应用软件项目的开发,它已经不仅仅是软件开发人员的事了,软件开发商内部就需要有业务专家、系统设计师、软件开发工程师、软件测试工程师、技术支持工程师,此外,企业管理者和业务人员也是企业管理软件项目开发必不可缺的角色。一个成功的企业管理软件项目开发需要不同领域、不同层次的众多人员的紧密合作,任何一个环节有问题,都可能导致软件项目的失败。因此企业应用软件开发更需要软件工程。应用软件开发过程基本上包括需求分析、系统设计、代码编写、测试运行等阶段。KCOM组件模型及其相关的开发工具KCOM Space能很好地用于编程,但是不能用于前两个阶段。当我们用KCOM Space来开发应用项目时,我们发现还需要借助于其它的分析和设计工具。一方面这些来自不同软件厂商的工具很难整合在一起;另一方面采用这些工具加起来会是一笔很大的支出。作为一个开发工具厂商,我们不希望我们的用户在购买使用我们的工具软件时,还需要购买许多其它的软件工具。所以,当KCOM走向成熟时,我们自己开发分析和设计工具的心情就变得很迫切了。目标很明确,我们要为一个完整的企业应用软件开发过程的各个阶段提供相应的工具,并且把这些工具集成在一起,共同来表达一个完整的企业应用。有过KCOM的开发经验,我们信心十足,事实上我们也很快实现了,在不到一年的时间,我们实现了工作流、组织机构、数据模型、UML等图形建模工具。这样第一版本的KCOM商业工程在2002年就开发完成了,看看当时的状况:有工作流程图、组织机构图、数据模型图、UML图的建模工具用于分析设计,有高效的快速应用开发工具KCOM用于编写代码。我们能使软件工程的每个阶段的效率都得到了提高,但是整体效率仍旧没有多大改善,究其根本原因就是模型和代码之间的脱节。


记者:你们能否介绍一下,KCOM商业工程目前在模型驱动开发这个方向上达到了什么程度?有没有什么实际的成功案例?

凯科思特:

2002至今三年的时间里,我们的主要精力都花在积累应用模板上,也就是说从模型到代码的自动转换上。可以这么比喻,第一版本的KCOM商业工程好比是婴儿时期的人,已经具有智能的基础,但他对这个世界还一无所知。从婴儿到成人,也是一个不断的学习的过程,只有通过学习,才能成为真正的有聪明智慧的人。类似的,第一版本的KCOM商业工程已经具有自动编程的功能,但还没有任何积累,也就不能‘理解’模型。第一版本的KCOM商业工程可以用来建模,但是模型设计的结果需要开发人员来理解并转换为程序代码。这几年我们积累应用模板的过程就相当于教师将知识灌输给学生一样,我们根据以往的应用开发经验,并且分析了许多应用软件,从中抽取可重用的部分,形成软件工厂模板。随着积累的增多,工具平台自身就能理解越来越多的模型并自动转换为程序代码。而对于那些工具平台不能理解的模型,就手工转换为程序代码,之后我们会抽取这些手写的程序代码的共性部分并转换成为模板。

用KCOM商业工程开发应用软件就是定义数据模型、组织机构、业务过程以及业务规则。首先我们会先大致描述一下企业的组织架构以及业务流程,然后分析要实现企业的业务运转需要什么样的数据。这样我们能很快地搭出一个应用系统的原型,之后我们再来详细定义业务规则。一旦业务规则定义完成,一个符合企业应用需求的软件系统就可以自动加工生成了,最后我们再请美工对生成的系统做些美化处理就可以提交给用户使用了。

在企业应用软件开发方面,目前KCOM商业工程已经有相当丰富的积累。企业应用软件常见的基础数据、业务单据、统计报表、数据分析等等都可以在KCOM商业工程里用模型来表达并转换生成全部的程序代码。此外,KCOM商业工程还包含了大量的功能组件,如邮件、日程表、门户、文档、甘特图等等。只要是KCOM商业工程已经归纳的业务类型,都可以很轻松地用模型来表达并在几分种内自动转换生成程序代码。

下面这几张图是模型和转换生成的应用模块之间的对照。所有这些应用模块都是从模型自动转换生成的,没有经过任何的修改就可以实际发布运行。

1、基础数据

2、业务单据



3、统计报表




4、数据分析




5、任务甘特图






2. 模型驱动的概念和意义


记者:你们怎么理解和定义模型驱动开发呢?这里的“模型”是什么意思?“驱动”又是什么意思?

凯科思特:

人类理解和表达一种事物时通常用的就是“模型”。很容易理解,当你们要介绍一种新的事物给大家时,首先会给出一个参照物,告诉大家它像什么,之后再说明有什么独特的地方,这样大家才容易理解。这个参照物就是用来理解新事物的模型。汽车制造商在设计一款新的汽车是都会先建立一个汽车模型,过去是造一辆实实在在的模型汽车,现在是用计算机进行仿真。我们开发企业应用软件,目的就是要服务于企业的日常业务。而要正确表达企业的业务,最好的办法是首先建立企业的业务模型,让这个模型作为企业业务的参照物。紧接着我们就会来分析这个模型是否正确表达了企业的业务,如果不是,那么我们就修改模型,逐步雕凿,最终使我们的模型尽可能地符合企业的业务。

企业的业务模型可以有很多种表达方式。我们可以用纯粹的文字来表达,也可以用图形来表达。什么样的模型能最容易、最自然地表达企业的业务,那么我们就采用这种模型。如果用文字表达的模型最贴切企业业务,那么我们也会采用文字来建模。但实际情况是用图形化的模型会更容易表达企业的业务。做个类比,建筑是用图形来设计的,我们很难想像还会有哪位工程师能完全用文字描述来做建筑设计。我们会用组织机构图来描述企业的组织架构,用流程图来表描述企业的业务流程,用E-R模型图来描述企业数据,用业务规则来表达企业的业务逻辑。当然业务规则不是用图形表述,而是沿用了If…Then…的表述方式。

在应用软件开发的需求分析和系统设计阶段,我们为应用软件建立模型,在代码编写阶段理解模型并将模型转换为程序代码,测试运行阶段则验证程序代码是否准确地反映了分析设计模型。分析设计模型一旦有变化,就需要重新编码测试。所以模型在软件开发过程应该起着主导作用。在传统的软件开发过程中,代码编写是软件开发的主要工作,模型实际上只是开发人员的辅助工具,建模的结果仅仅是形成软件开发文档,对程序代码的编写只起到参考的作用。而在模型驱动开发中,代码编写交由工具平台自动完成,模型真正起到软件开发的主导和驱动作用,建模的结果就是最终可发布运行的应用软件。


记者:模型驱动开发能给我们带来什么好处?

凯科思特:

模型驱动开发对软件开发的各个方面都将产生深远影响。它改变了软件开发过程,将软件开发过程改变为需求分析、系统设计、代码生成、发布运行。分析设计不再只产生泛泛的文档,而是精确的应用模型。程序代码完全由模型转换工具自动从精确的模型转换而成。由于代码是自动转换生成的,所以针对代码的测试已经不再需要。模型的自动转换使软件开发效率有了一个量级以上的提升,并且将软件开发的重心转到了分析设计,确保了软件开发的低成本、高质量,进而赢得的是高客户满意度以及高回报。

记者:根据你们的经验,使用模型驱动开发的话,一个项目的开发效率能够提高多少?

凯科思特:

早些年,有软件开发商采用我们的KCOM Space软件开发工具来开发一个公安综合管理信息系统,开发团队中有2个人负责需求分析和系统设计,5个人负责程序开发,2个人负责代码测试,花了半年时间才开发完成。这样的系统,如果放在现在用KCOM商业工程来开发的话,也就只需要4个人一个月的时间就可以了,其中2个人做分析设计,1个人编写额外的代码,1个人做测试。按人月来算的话开发效率提高了十几倍。

记者:也就是说,在最好的情况下,模型驱动开发能够达到“银弹”的要求——效率提高一个数量级。你们认为为什么模型驱动开发会有如此大的威力?

凯科思特:

之所以模型驱动开发会有如此大的威力,首先是因为它跨越了一个传统开发过程所不可避免的鸿沟,也就是代码编写阶段。代码编写的效率是由程序开发人员决定的。再熟练的开发人员,他的代码编写效率也会有一个极限,并且会有很多干扰因素影响代码的质量,进而导致需要很多的人力物力来测试代码。在这一点上,人和计算机是不能比拟的,计算机不会出错,并且可以24小时不间断运转,而不知疲倦。如果只比较代码编写效率,模型驱动开发自动生成程序代码的效率会比开发人员手工书写程序代码的效率提高两到三个数量级。而如果以完整的软件开发过程来衡量,假定我们能做到95%~100%的代码生成,那么模型驱动开发也能够达到“银弹”的要求——效率提高一个数量级。

其次,模型驱动开发把软件开发的重心放在了对应用的建模上,提供精确的建模工具用于快速、准确地描述应用需求。同样的问题用不同的方法来解决,它的复杂程度是不一样的,往往是一个复杂的问题,在找到了合适的解决方法后,就变得不再复杂了。为应用提供合适的抽象模型及建模工具,会使得应用软件的开发不再是那么的复杂。对企业应用来说,建立在图形上的模型远比用文字书写的代码来得直观和简洁。

记者:软件效率无法得到提高、质量无法保证的情况被人称为所谓的“软件危机”,且不论这种危机是否真的存在,你们认为其原因何在?人们普遍认为,需求的难以把握和反复变动是导致商业软件项目开发困难的本质原因,模型驱动开发何以能解决这一问题?

凯科思特:

需求的难以把握主要表现在一方面用户在刚开始也不清楚自己的需求到底是什么,用户也需要在具体的项目开发过程中逐步理清自己的需求;另一方面,我们也不能苛求用户把需求固定下来,因为用户的业务是在变化的,决定了需求也是在不断变化。需求的难以把握和反复变动是导致商业软件项目开发困难的因素,但不能说是本质原因。本质原因还是在于传统软件开发方法自身。也就是说传统软件开发方法不能响应需求的变化。传统的软件工程方法中,需求的任何微小变动,都需要程序开发人员重新理解和修改已有代码,添加新的代码。理解和修改已有代码的难度往往不亚于重新开发,因此当需求变化频繁时,代码是很难同步的,结果就是项目进度的延期。此外,因为代码是开发人员手工编写的,即便是开发高手,也无法完全保证代码的质量,更不用说团队开发了,需求频繁变动也使得软件的质量很难保证,结果是软件得不到用户的认可。所以,追究“软件危机”的根源,就在于手工编写代码这一瓶颈上,而模型驱动开发将程序代码交由软件工具自动生成,由软件工具来保证编码的效率和质量,“软件危机”的根源也就不复存在。

记者:但是也有很多人认为,模型驱动开发实际上是把难点转移而非降低了。过去人们用代码对应用建模,代码不直观,但表现力强。而你们提倡用图形的来建模,很直观,但是表现力天生不足,可能会产生极其复杂的图形,乱作一团的关系,使得修改和调整起来同样困难。对这种看法你们是否赞成?

凯科思特:

在很多方面代码表现力强,这点我们非常同意。但是代码沿袭了文字表达的一个主要特点,就是说代码是一维的,代码所基于的基本语法是以前后顺序为基础的,适合表达命令及顺序过程。代码可以来为某些问题建模,但由于它本质上是一维的线性的,所以用代码来表示二维或多维的问题时,就显得力不从心了。举个简单的例子,在为自己的家居装璜时,我们不会也很难用文字来准确地表达家居布局吧。最好的方法是在计算机上用3D仿真技术,来设计我们的家居布局。企业应用是多维的,所以用一维的代码来表述企业应用,企业应用就是一个非常复杂的问题。但是,如果我们为企业应用建立多维的、多方面的模型,那么问题就变得简单了。一般人初次看到用图形及关系表达的企业模型会觉得很复杂,其实并不是那么回事。就好比非建筑设计专业人员看建筑设计图纸一样,开始难免有很多困惑,一旦了解了各种图形元素所表示的含义,图形化的模型就会很直观明了。另外优秀图形建模工具还会做很多的工作使建模更加简单,比如说实时的模型校验就可以避免定义无效的模型。

记者:模型驱动的方法能否100%满足千变万化的需求?你们的KCOM能够达到多少的自动代码生成率?

凯科思特:

模型驱动的方法能应用在任何领域的软件开发过程,但是即便从长远来看,模型驱动的方法也不能100%满足千变万化的需求。我们能希望的是模型驱动的方法至少在特定的应用领域针对一定时期和范围内的应用需求做到接近100%的模型自动生成代码。

目前KCOM商业工程定位在企业应用软件的开发。选择企业应用开发领域作为入口,首先是因为企业应用软件的开发从技术上来讲没有什么难度,其次,企业应用软件的各业务模块之间存在大量的重复成份。KCOM商业工程在企业应用软件开发这一领域已经有了相当程度的积累,可以开发的应用包括供应链管理、分销管理、客户关系管理、办公自动化、项目管理等等。针对某个小的范围的应用,如进销存系统,KCOM商业工程已经可以做到接近100%的自动生成。用户可以在已有的模型上添加自定义的基础数据、业务单据,定义符合自己业务逻辑的业务规则,然后重新由工具平台自动加工,生成的程序代码不需要做任何修改就可以直接使用。可以这么说,只要是企业应用软件的开发,KCOM商业工程都可以达到80-95%的自动生成。

记者:这已经是一个相当高的比例了,你们是否觉得,其实只要做到这一步就不错了,或许不能够也不应该100%自动生成?

凯科思特:

还是希望能够达到100%的代码自动生成。根据我们自己的实际应用经验,在一个应用开发中,即使只有5%的代码需要手工来书写,开发效率就会大打折扣。为什么呢?这是因为任何一个应用系统开发都需要多次迭代的。假定我们第一次迭代过程花了10天的时间,其中7天用来做需求分析和系统设计,3天用来编写这5%的代码;第二次迭代过程需要花3天时间,其中1天用来修正需求分析和系统设计,仍旧需要用2天时间来重写这5%的代码;第三次迭代过程需要花2天的时间,其中半天的时间用来调整需求设计,一天半的时间还用来重写那5%的代码;依次类推。根据实际应用开发的经验,需求变化了,设计通常只需要做少许的改动,而为这一点改动去修改已有代码所花的时间常常不亚于重写代码所花的时间。所以,随着迭代的继续,用于需求分析和系统设计的时间大大变少了,而用于编写代码的时间基本上很少变化。

 

迭代次数

用于分析设计的时间

用于代码编写的时间

代码编写所占的比例

一次迭代

7

3

43%

二次迭代

8

5

63%

三次迭代

85

6.5

76%


从上面的表格数据可以看出,随着迭代次数的增加,代码编写阶段所占的比例会很快放大,再多几次迭代的话,会使得我们花大部分时间在编写代码上。
如果我们能够100%的代码自动生成,那么任何分析设计的变动,我们只需要花1小时左右的时间就能够重新生成代码。这样我们再来看看表格数据的变化。

 

迭代次数

用于分析设计的时间

用于代码编写的时间

代码编写所占的比例

一次迭代

7

1/24

0.6%

二次迭代

8

2/24

1%

三次迭代

85

3/24

1.5%


从上面的表格数据可以看出,虽然随着迭代次数的增加,代码生产阶段所占的比例也会逐步放大。但是这个比例在很多次迭代后依然是很小的,几乎可以忽略不计。


记者:我怀疑目前发明的图形化模型描述方式不能够完全彻底地表达一个复杂的应用系统。你们觉得呢?

凯科思特:

同意。应用领域是多样的,我们想很难有一种万能的模型语言来描述任何领域的复杂应用系统。针对某一个领域的具体的应用系统,会有适合这一领域的模型。说到万能的模型语言,不能不提到UML(统一建模语言),UML这个名称会引起很多人的误解,以为所有的模型都能归入UML,或者换句话来说,会误以为UML能够为任何应用开发建模。事实上,在实际应用中,我们发现UML并不很适合企业应用软件的开发。KCOM商业工程支持UML的建模,但在做模型转换的过程中,我们发现很多在企业应用开发中所需要的模型元素及属性在UML的标准定义里并没有,但是UML已经成为国际标准,我们就不好自行定义,另外UML里的很多重要成份如类图并不适合用来开发企业应用。所以在做了一段时间的尝试后,我们就放弃了,KCOM商业工程只保留了对UML的图形化建模功能,并没有在模型转换中起作用。根据以往做项目的经验,做企业应用开发涉及到最多的就是组织机构图、流程图、E-R模型图,所以我们就为这三种模型图添加模型转换所需要的属性,直到应用程序代码能够完全从这三个模型的定义自动生成。

记者:你们认为模型驱动技术与其他的当前热门技术,比如SOA、AOP以及软件工程等是什么关系?是竞争关系还是合作关系?是不是说一旦到了模型驱动软件开发时代,那些东西都不重要甚至根本就消失了呢?

凯科思特:

模型驱动开发和SOA、AOP这些热门技术是相辅相成的,因为一方面模型驱动开发自动生成的代码很可能就是这些热门技术的实现代码,另一方面,SOA、AOP以及OOP等等其实也都是用各自不同的模型方法来试图解决软件编程的复杂度和相关度问题,也完全可以采用模型驱动开发。

模型驱动开发自身就是一种软件工程方法,它继承和发展了瀑布式模型、快速原型法、螺旋模型、极限编程、统一过程等传统软件工程方法,很彻底地解决了以往各种软件工程方法想解决而未能解决的“软件危机”问题。

记者:请总结一下你们对于模型驱动的观点,以及你们从KCOM实践中得到的经验。

凯科思特:

对于模型驱动开发,我们亲身体验了两个过程:实现一个模型驱动开发工具,培训和支持软件开发团队模型驱动开发应用项目。

要真正实现模型驱动开发工具,有三个必要的前提:一是要有合适的建模工具,二是要有能自动编程的开发工具,三是要积累足够多的应用模板。总结KCOM商业工程的开发经验,我们奉行的是一条实用为本、结果导向的原则,而不是拘泥于标准的模型。标准在一个产业成熟期起到规范作用,但在产业的初创及发展时期,过早地尊崇所谓的标准,往往会起到制约发展的反作用。首先我们以自己对应用软件开发的经验积累来选择和扩展模型。其次在已具备自动编程功能的KCOM组件开发工具上实现模型到代码的转换,而不是盲目地去实现模型到多平台、多语言的转换。最后,以极大的耐心和细心来抽取应用软件的共性并转换成应用模板。

根据我们在培训和支持软件开发团队中得到的反馈以及我们自己开发应用项目的经验,我们总结出以下几点:
1、 采用模型驱动开发应用项目,首先要选择一种适合自己应用领域的模型驱动开发工具,然后要清楚应用项目中哪些部分是可以用模型来定义并自动转换的,哪些还需要手工编写代码。
2、 掌握一门编程语言我们要了解语言的语法、关键字、常量、变量、语句、函数等等。而掌握一种建模语言我们需要了解的是模型元素及其属性所代表的含义,并且对这些属性值影响转换生成的应用系统的哪些部分了然于胸。
3、 图形建模的自由度相比程序代码要大很多,并不是所有的定义方式都能正确地转换为程序代码,所以一方面要使用工具所提供的模型检查功能,另一方面,在工具的模型检查功能不是十分全面时,要以规范的方法建模。
4、 对于不能从模型自动转换生成而需要手工编写的程序代码,要么自己采用模型驱动开发工具提供的方法抽取并转换成为模板,要么让工具提供商来抽取,目标是在下次碰到类型的问题时能用模型来表达,避免重复编写代码。
 

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/wsimei/article/details/5841127

智能推荐

while循环&CPU占用率高问题深入分析与解决方案_main函数使用while(1)循环cpu占用99-程序员宅基地

文章浏览阅读3.8k次,点赞9次,收藏28次。直接上一个工作中碰到的问题,另外一个系统开启多线程调用我这边的接口,然后我这边会开启多线程批量查询第三方接口并且返回给调用方。使用的是两三年前别人遗留下来的方法,放到线上后发现确实是可以正常取到结果,但是一旦调用,CPU占用就直接100%(部署环境是win server服务器)。因此查看了下相关的老代码并使用JProfiler查看发现是在某个while循环的时候有问题。具体项目代码就不贴了,类似于下面这段代码。​​​​​​while(flag) {//your code;}这里的flag._main函数使用while(1)循环cpu占用99

【无标题】jetbrains idea shift f6不生效_idea shift +f6快捷键不生效-程序员宅基地

文章浏览阅读347次。idea shift f6 快捷键无效_idea shift +f6快捷键不生效

node.js学习笔记之Node中的核心模块_node模块中有很多核心模块,以下不属于核心模块,使用时需下载的是-程序员宅基地

文章浏览阅读135次。Ecmacript 中没有DOM 和 BOM核心模块Node为JavaScript提供了很多服务器级别,这些API绝大多数都被包装到了一个具名和核心模块中了,例如文件操作的 fs 核心模块 ,http服务构建的http 模块 path 路径操作模块 os 操作系统信息模块// 用来获取机器信息的var os = require('os')// 用来操作路径的var path = require('path')// 获取当前机器的 CPU 信息console.log(os.cpus._node模块中有很多核心模块,以下不属于核心模块,使用时需下载的是

数学建模【SPSS 下载-安装、方差分析与回归分析的SPSS实现(软件概述、方差分析、回归分析)】_化工数学模型数据回归软件-程序员宅基地

文章浏览阅读10w+次,点赞435次,收藏3.4k次。SPSS 22 下载安装过程7.6 方差分析与回归分析的SPSS实现7.6.1 SPSS软件概述1 SPSS版本与安装2 SPSS界面3 SPSS特点4 SPSS数据7.6.2 SPSS与方差分析1 单因素方差分析2 双因素方差分析7.6.3 SPSS与回归分析SPSS回归分析过程牙膏价格问题的回归分析_化工数学模型数据回归软件

利用hutool实现邮件发送功能_hutool发送邮件-程序员宅基地

文章浏览阅读7.5k次。如何利用hutool工具包实现邮件发送功能呢?1、首先引入hutool依赖<dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>5.7.19</version></dependency>2、编写邮件发送工具类package com.pc.c..._hutool发送邮件

docker安装elasticsearch,elasticsearch-head,kibana,ik分词器_docker安装kibana连接elasticsearch并且elasticsearch有密码-程序员宅基地

文章浏览阅读867次,点赞2次,收藏2次。docker安装elasticsearch,elasticsearch-head,kibana,ik分词器安装方式基本有两种,一种是pull的方式,一种是Dockerfile的方式,由于pull的方式pull下来后还需配置许多东西且不便于复用,个人比较喜欢使用Dockerfile的方式所有docker支持的镜像基本都在https://hub.docker.com/docker的官网上能找到合..._docker安装kibana连接elasticsearch并且elasticsearch有密码

随便推点

Python 攻克移动开发失败!_beeware-程序员宅基地

文章浏览阅读1.3w次,点赞57次,收藏92次。整理 | 郑丽媛出品 | CSDN(ID:CSDNnews)近年来,随着机器学习的兴起,有一门编程语言逐渐变得火热——Python。得益于其针对机器学习提供了大量开源框架和第三方模块,内置..._beeware

Swift4.0_Timer 的基本使用_swift timer 暂停-程序员宅基地

文章浏览阅读7.9k次。//// ViewController.swift// Day_10_Timer//// Created by dongqiangfei on 2018/10/15.// Copyright 2018年 飞飞. All rights reserved.//import UIKitclass ViewController: UIViewController { ..._swift timer 暂停

元素三大等待-程序员宅基地

文章浏览阅读986次,点赞2次,收藏2次。1.硬性等待让当前线程暂停执行,应用场景:代码执行速度太快了,但是UI元素没有立马加载出来,造成两者不同步,这时候就可以让代码等待一下,再去执行找元素的动作线程休眠,强制等待 Thread.sleep(long mills)package com.example.demo;import org.junit.jupiter.api.Test;import org.openqa.selenium.By;import org.openqa.selenium.firefox.Firefox.._元素三大等待

Java软件工程师职位分析_java岗位分析-程序员宅基地

文章浏览阅读3k次,点赞4次,收藏14次。Java软件工程师职位分析_java岗位分析

Java:Unreachable code的解决方法_java unreachable code-程序员宅基地

文章浏览阅读2k次。Java:Unreachable code的解决方法_java unreachable code

标签data-*自定义属性值和根据data属性值查找对应标签_如何根据data-*属性获取对应的标签对象-程序员宅基地

文章浏览阅读1w次。1、html中设置标签data-*的值 标题 11111 222222、点击获取当前标签的data-url的值$('dd').on('click', function() { var urlVal = $(this).data('ur_如何根据data-*属性获取对应的标签对象

推荐文章

热门文章

相关标签