精华内容
下载资源
问答
  • 设计模式在实际开发应用

    万次阅读 2018-11-06 10:44:06
    我相信有些人学了设计模式,依然不知道设计模式的应用场景,感觉我们日常开发,仅仅写些逻辑,调下接口,连接下数据库就完事儿了。...目的:本文将讲诉自己在实际开发所用到的设计模式,让更多朋友体会到...

    我相信有些人学了设计模式,依然不知道设计模式的应用场景,感觉我们日常开发中,仅仅写些逻辑,调下接口,连接下数据库就完事儿了。感觉设计模式都被框架运用的淋淋尽致,似乎没有我们可发挥的余地了。设计模式到底有什么用?在什么场景下用?它的优势是什么?似乎我们感受不到,讲真的,那学了也是一脸懵逼。不知道有没有人像我最开始学习设计模式一样。

    目的:本文将讲诉自己在实际开发中所用到的设计模式,让更多朋友体会到实际开发中很多时候也可以用设计模式。给个借鉴,打开思路。学习别人的开发思路,并运用到自己的开发中。

    说明:本文会陆续更新,可能不会一次性分享完所有设计模式,关注我,以后会更多!

    正文:

    一:设计模式之策略模式

    关于策略模式的理论在这里就不累赘,相信看到此文章的朋友都是看过很多有关文章,已经有大概了解了。欲在这里寻得策略模式的实际应用。

    (1)字符串截取方法。

    在实际项目中主要是根据配置文件中的连接数据库的url截取出数据库名字。因为暂时可能用的是mysql,但以后可能会用oracle。postgresql等等 也说不定。但是每个url的格式不同,截取方法也就不同,不可能每次修改源码。采用策略模式,想要扩展截取其它字符串时,需语言添加一个截取类,就行了。主要作用易于扩展,容易维护,解耦。

    关于细节,可查看我另一篇文章: https://blog.csdn.net/weixin_40841731/article/details/82985777

    (2)校验类的未知扩展

    业务场景:在开发公司框架时,由于该框架省去了实体类,mapper,mapper.xml、部分service类和controller类,都用统一执行sql方法和统一返回结果。让开发人员只专注于写sql。 这样一来,关于参数的校验,校验方式,校验类型,校验结果,都得存于数据库,然后在统一执行sql的controller层,根据sql,及替换sql内的参数值,实现参数校验。

    关于细节,可查看我另一篇文章:https://blog.csdn.net/weixin_40841731/article/details/82995908

     

    二:设计模式之单例模式

    在整个应用生命周期内,对某个类,只实例化一次,应用场景为:连接数据库,记录日志,使用单例模式可以避免不必要的资源消耗

     

    三:设计模式之简单工厂模式

    简单工厂模式:在本人实际开发中所用到的地方,在策略模式实现起来不太优雅的情况下,改为简单工厂模式

    简单工厂模式和策略模式,一个是创建型,另一个是行为型,然而两种不同类型的模式,在某些地方也有一丝的相似之处,同时在某种场景下结合使用,能起到特别好的效果。

    两者对比:

    1、策略模式:

    策略模式是行为型模式,它定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换。策略模式让算法独立于使用它的客户而独立变化。

      在一段代码里,使用了逻辑控制(if-else,swich-case)来决定算法,算法有相似的方法和函数,就可以选择策略模式。

      那么也就是说:

      1、某方法里有多个条件语句,条件语句代码块里有许多行为过程。

      2、其算法能封装到策略类

      2、算法随意切换

      3、算法与客户端隔离

       这样一来,通过选择对应的策略类,作为参数传到Content类里,在运行时配置对应的算法。

     

    2、简单工厂模式:

    简单工厂模式是创建型模式,创建型模式顾名思义,也就是说在创建对象的时候,遇到了瓶颈才会选择的设计模式。那么该什么情况使用呢。

       简单工厂模式的实质是由一个工厂类根据传入的参数,动态决定应该创建并且返回哪一个产品类(这些产品类继承自一个父类或接口)的实例。

       那么也就是说:

       1、有已知的产品类

       2、你无法准确的知道编译哪个产品类

       3、需要在运行时决定创建哪个产品类

       4、产品类不多

       很明显看出,在创建对象上的灵活性高,但是工厂类只能创建可能会使用到的产品类,假如新添了产品类就得修改工厂类,这样就会违反开闭原则。

       

    总结:   

            简单工厂模式和策略模式很相似。怎么相似?都是三个业务子类继承抽象父类,通过传入参数到容器类(工厂模式的factory类,策略模式的Content类),选择对应的类进行行为操作。

           从上面的描述总结出,在运行时,两者都是通过传入参数进行配置,简单工厂模式则是选择创建出需要的对象,而策略模式则是配置出需要的行为算法。一个是对象创建,另一个是行为算法的替换。

          其实,UML图的确从外形上看没多大区别,但是,本质却是大大不同。

     

    关于简单工厂在项目中的实际应用,可查看我另一篇文章:https://blog.csdn.net/weixin_40841731/article/details/83861285

     

    四、设计模式之建造者模式

    关于建造者模式的应用,由于篇幅问题,可见我另一篇博文:  点击我

    五、设计模式之装饰器模式

    关于建造者模式的应用,由于篇幅问题,可见我另一篇博文:  点击我

     

     

     

     

    展开全文
  • python3之数字(在实际应用中的数字--十六进制、八进制和二进制记数) ---------- python整数能够以十六进制、八进制和二进制记数法来编写,作为一般的十进制记数法的补充。如例: >>>0o1,0o20,0o377 #八进制 (1,16...
    python3之数字(在实际应用中的数字--十六进制、八进制和二进制记数)
    
    ----------

    python整数能够以十六进制、八进制和二进制记数法来编写,作为一般的十进制记数法的补充。如例:

    >>>0o1,0o20,0o377   #八进制
    (1,16,255)
    >>>0x01,0x10,0xFF   #十六进制
    (1,16,255)
    >>>0b1,0b10000,0b11111111  #二进制
    (1, 16, 255)
    python默认地用十进制值显示,但它提供了内置的函数,允许我们把整数转换为其他进制的数字字符串:

    >>> oct(64),hex(64),bin(64)
    ('0o100', '0x40', '0b1000000')
    oct函数会将十进制数转换为八进制数,hex函数会将十进制转换为十六进制数,而bin函数会将十进制数转换为二进制。另一种方式, 内置int函数会将一个数字的字符串转换为一个整数,并可以通过定义的第二个参数来确定第一个数字字符串参数的进制

    >>>int('64'),int('100',8),int('40',16),int('1000000',2)
    (64, 64, 64, 64)

    在继续学习之前,有两点需要注意。 首先,python2.6的用户应该记住在编写八进制之前,直接用一个0开头,python中最初的八进制格式如下:

    >>>0o1,0o20,0o377   #python2.6与python3.0中都可用
    (1, 16, 255)
    >>>01,020,0377      #只用于python2.6中
    (1, 16, 255)
    在python3.0中,上例中的第二组语法将会产生错误。即便它在python2.6中不是一个错误,还是要小心,不要用0开始一个数字字符串,除非你真的是想要表示一个八进制的值。python2.6会将其当作是八进制数,但可能不像你所期待的那样工作,010在python2.6中总是八进制数,而不是十进制数。也就是说, 为了保持与十六进制和二进制的形式对称,python3.0修改了八进制的形式,在python3.0中必须使用0o010,并且, 在python2.6中,也应该尽可能使用0o010
    其次,注意这些常量可以产生任意长度的整数。例如,下面的例子创建了十六进制形式的一个整数,然后先用十进制形式显示它,再将其转换为八进制和二进制的形式:
    >>> X=0xFFFFFFFFFFFFFF
    >>> X
    72057594037927935
    >>> oct(X)
    '0o3777777777777777777'
    >>> bin(X)
    '0b11111111111111111111111111111111111111111111111111111111'
    >>>




    展开全文
  • k-means算法实际应用

    万次阅读 2018-03-11 17:41:29
    原文链接:http://www.cnblogs.com/leoo2sk/archive/2010/09/20/k-means.html4.1、摘要 前面的文章,...但是很多时候上述条件得不到满足,尤其是处理海量数据的时候,如果通过预处理使得数据满足分类算法的...

    原文链接:http://www.cnblogs.com/leoo2sk/archive/2010/09/20/k-means.html

    4.1、摘要

          在前面的文章中,介绍了三种常见的分类算法。分类作为一种监督学习方法,要求必须事先明确知道各个类别的信息,并且断言所有待分类项都有一个类别与之对应。但是很多时候上述条件得不到满足,尤其是在处理海量数据的时候,如果通过预处理使得数据满足分类算法的要求,则代价非常大,这时候可以考虑使用聚类算法。聚类属于无监督学习,相比于分类,聚类不依赖预定义的类和类标号的训练实例。本文首先介绍聚类的基础——距离与相异度,然后介绍一种常见的聚类算法——k均值和k中心点聚类,最后会举一个实例:应用聚类方法试图解决一个在体育界大家颇具争议的问题——中国男足近几年在亚洲到底处于几流水平。

    4.2、相异度计算

          在正式讨论聚类前,我们要先弄清楚一个问题:如何定量计算两个可比较元素间的相异度。用通俗的话说,相异度就是两个东西差别有多大,例如人类与章鱼的相异度明显大于人类与黑猩猩的相异度,这是能我们直观感受到的。但是,计算机没有这种直观感受能力,我们必须对相异度在数学上进行定量定义。

          ,其中X,Y是两个元素项,各自具有n个可度量特征属性,那么X和Y的相异度定义为:,其中R为实数域。也就是说相异度是两个元素对实数域的一个映射,所映射的实数定量表示两个元素的相异度。

          下面介绍不同类型变量相异度计算方法。

    4.2.1、标量

          标量也就是无方向意义的数字,也叫标度变量。现在先考虑元素的所有特征属性都是标量的情况。例如,计算X={2,1,102}和Y={1,3,2}的相异度。一种很自然的想法是用两者的欧几里得距离来作为相异度,欧几里得距离的定义如下:

          

          其意义就是两个元素在欧氏空间中的集合距离,因为其直观易懂且可解释性强,被广泛用于标识两个标量元素的相异度。将上面两个示例数据代入公式,可得两者的欧氏距离为:

          

          除欧氏距离外,常用作度量标量相异度的还有曼哈顿距离和闵可夫斯基距离,两者定义如下:

          曼哈顿距离:

          闵可夫斯基距离:

          欧氏距离和曼哈顿距离可以看做是闵可夫斯基距离在p=2和p=1下的特例。另外这三种距离都可以加权,这个很容易理解,不再赘述。

          下面要说一下标量的规格化问题。上面这样计算相异度的方式有一点问题,就是取值范围大的属性对距离的影响高于取值范围小的属性。例如上述例子中第三个属性的取值跨度远大于前两个,这样不利于真实反映真实的相异度,为了解决这个问题,一般要对属性值进行规格化。所谓规格化就是将各个属性值按比例映射到相同的取值区间,这样是为了平衡各个属性对距离的影响。通常将各个属性均映射到[0,1]区间,映射公式为:

          

          其中max(ai)和min(ai)表示所有元素项中第i个属性的最大值和最小值。例如,将示例中的元素规格化到[0,1]区间后,就变成了X’={1,0,1},Y’={0,1,0},重新计算欧氏距离约为1.732。

    4.2.2、二元变量

          所谓二元变量是只能取0和1两种值变量,有点类似布尔值,通常用来标识是或不是这种二值属性。对于二元变量,上一节提到的距离不能很好标识其相异度,我们需要一种更适合的标识。一种常用的方法是用元素相同序位同值属性的比例来标识其相异度。

          设有X={1,0,0,0,1,0,1,1},Y={0,0,0,1,1,1,1,1},可以看到,两个元素第2、3、5、7和8个属性取值相同,而第1、4和6个取值不同,那么相异度可以标识为3/8=0.375。一般的,对于二元变量,相异度可用“取值不同的同位属性数/单个元素的属性位数”标识。

          上面所说的相异度应该叫做对称二元相异度。现实中还有一种情况,就是我们只关心两者都取1的情况,而认为两者都取0的属性并不意味着两者更相似。例如在根据病情对病人聚类时,如果两个人都患有肺癌,我们认为两个人增强了相似度,但如果两个人都没患肺癌,并不觉得这加强了两人的相似性,在这种情况下,改用“取值不同的同位属性数/(单个元素的属性位数-同取0的位数)”来标识相异度,这叫做非对称二元相异度。如果用1减去非对称二元相异度,则得到非对称二元相似度,也叫Jaccard系数,是一个非常重要的概念。

    4.2.3、分类变量

          分类变量是二元变量的推广,类似于程序中的枚举变量,但各个值没有数字或序数意义,如颜色、民族等等,对于分类变量,用“取值不同的同位属性数/单个元素的全部属性数”来标识其相异度。

    4.2.4、序数变量

          序数变量是具有序数意义的分类变量,通常可以按照一定顺序意义排列,如冠军、亚军和季军。对于序数变量,一般为每个值分配一个数,叫做这个值的秩,然后以秩代替原值当做标量属性计算相异度。

    4.2.5、向量

          对于向量,由于它不仅有大小而且有方向,所以闵可夫斯基距离不是度量其相异度的好办法,一种流行的做法是用两个向量的余弦度量,其度量公式为:

          

          其中||X||表示X的欧几里得范数。要注意,余弦度量度量的不是两者的相异度,而是相似度!

    4.3、聚类问题

          在讨论完了相异度计算的问题,就可以正式定义聚类问题了。

          所谓聚类问题,就是给定一个元素集合D,其中每个元素具有n个可观察属性,使用某种算法将D划分成k个子集,要求每个子集内部的元素之间相异度尽可能低,而不同子集的元素相异度尽可能高。其中每个子集叫做一个簇。

          与分类不同,分类是示例式学习,要求分类前明确各个类别,并断言每个元素映射到一个类别,而聚类是观察式学习,在聚类前可以不知道类别甚至不给定类别数量,是无监督学习的一种。目前聚类广泛应用于统计学、生物学、数据库技术和市场营销等领域,相应的算法也非常的多。本文仅介绍一种最简单的聚类算法——k均值(k-means)算法。

    4.4、K-means算法及其示例

          k均值算法的计算过程非常直观:

          1、从D中随机取k个元素,作为k个簇的各自的中心。

          2、分别计算剩下的元素到k个簇中心的相异度,将这些元素分别划归到相异度最低的簇。

          3、根据聚类结果,重新计算k个簇各自的中心,计算方法是取簇中所有元素各自维度的算术平均数。

          4、将D中全部元素按照新的中心重新聚类。

          5、重复第4步,直到聚类结果不再变化。

          6、将结果输出。

          由于算法比较直观,没有什么可以过多讲解的。下面,我们来看看k-means算法一个有趣的应用示例:中国男足近几年到底在亚洲处于几流水平?

          今年中国男足可算是杯具到家了,几乎到了过街老鼠人人喊打的地步。对于目前中国男足在亚洲的地位,各方也是各执一词,有人说中国男足亚洲二流,有人说三流,还有人说根本不入流,更有人说其实不比日韩差多少,是亚洲一流。既然争论不能解决问题,我们就让数据告诉我们结果吧。

          下图是我采集的亚洲15只球队在2005年-2010年间大型杯赛的战绩(由于澳大利亚是后来加入亚足联的,所以这里没有收录)。

          其中包括两次世界杯和一次亚洲杯。我提前对数据做了如下预处理:对于世界杯,进入决赛圈则取其最终排名,没有进入决赛圈的,打入预选赛十强赛赋予40,预选赛小组未出线的赋予50。对于亚洲杯,前四名取其排名,八强赋予5,十六强赋予9,预选赛没出现的赋予17。这样做是为了使得所有数据变为标量,便于后续聚类。

          下面先对数据进行[0,1]规格化,下面是规格化后的数据:

          接着用k-means算法进行聚类。设k=3,即将这15支球队分成三个集团。

          现抽取日本、巴林和泰国的值作为三个簇的种子,即初始化三个簇的中心为A:{0.3, 0, 0.19},B:{0.7, 0.76, 0.5}和C:{1, 1, 0.5}。下面,计算所有球队分别对三个中心点的相异度,这里以欧氏距离度量。下面是我用程序求取的结果:

          从做到右依次表示各支球队到当前中心点的欧氏距离,将每支球队分到最近的簇,可对各支球队做如下聚类:

          中国C,日本A,韩国A,伊朗A,沙特A,伊拉克C,卡塔尔C,阿联酋C,乌兹别克斯坦B,泰国C,越南C,阿曼C,巴林B,朝鲜B,印尼C。

          第一次聚类结果:

          A:日本,韩国,伊朗,沙特;

          B:乌兹别克斯坦,巴林,朝鲜;

          C:中国,伊拉克,卡塔尔,阿联酋,泰国,越南,阿曼,印尼。

          下面根据第一次聚类结果,调整各个簇的中心点。

          A簇的新中心点为:{(0.3+0+0.24+0.3)/4=0.21, (0+0.15+0.76+0.76)/4=0.4175, (0.19+0.13+0.25+0.06)/4=0.1575} = {0.21, 0.4175, 0.1575}

          用同样的方法计算得到B和C簇的新中心点分别为{0.7, 0.7333, 0.4167},{1, 0.94, 0.40625}。

          用调整后的中心点再次进行聚类,得到:

          第二次迭代后的结果为:

          中国C,日本A,韩国A,伊朗A,沙特A,伊拉克C,卡塔尔C,阿联酋C,乌兹别克斯坦B,泰国C,越南C,阿曼C,巴林B,朝鲜B,印尼C。

          结果无变化,说明结果已收敛,于是给出最终聚类结果:

          亚洲一流:日本,韩国,伊朗,沙特

          亚洲二流:乌兹别克斯坦,巴林,朝鲜

          亚洲三流:中国,伊拉克,卡塔尔,阿联酋,泰国,越南,阿曼,印尼

          看来数据告诉我们,说国足近几年处在亚洲三流水平真的是没有冤枉他们,至少从国际杯赛战绩是这样的。

          其实上面的分析数据不仅告诉了我们聚类信息,还提供了一些其它有趣的信息,例如从中可以定量分析出各个球队之间的差距,例如,在亚洲一流队伍中,日本与沙特水平最接近,而伊朗则相距他们较远,这也和近几年伊朗没落的实际相符。另外,乌兹别克斯坦和巴林虽然没有打进近两届世界杯,不过凭借预算赛和亚洲杯上的出色表现占据B组一席之地,而朝鲜由于打入了2010世界杯决赛圈而有幸进入B组,可是同样奇迹般夺得2007年亚洲杯的伊拉克却被分在三流,看来亚洲杯冠军的分量还不如打进世界杯决赛圈重啊。其它有趣的信息,有兴趣的朋友可以进一步挖掘。


    展开全文
  • 消息队列中间件是分布式系统重要的组件,主要解决应用解耦,异步消息,流量削锋等问题,实现高性能,高可用,可伸缩和最终一致性架构。目前使用较多的消息队列有ActiveMQ,RabbitMQ,ZeroMQ,Kafka,MetaMQ,...

    消息队列中间件是分布式系统中重要的组件,主要解决应用解耦,异步消息,流量削锋等问题,实现高性能,高可用,可伸缩和最终一致性架构。目前使用较多的消息队列有ActiveMQ,RabbitMQ,ZeroMQ,Kafka,MetaMQ,RocketMQ。消息中间件到底该如何使用,何时使用这是一个问题,胡乱地使用消息中间件增加了系统的复杂度,如果用不好消息中间件还不如不用。

    0.消息队列通讯模式


    1)点对点通讯:点对点方式是最为传统和常见的通讯方式,它支持一对一、一对多、多对多、多对一等多种配置方式,支持树状、网状等多种拓扑结构。

    2)多点广播:MQ适用于不同类型的应用。其中重要的,也是正在发展中的是"多点广播"应用,即能够将消息发送到多个目标站点(DestinationList)。可以使用一条MQ指令将单一消息发送到多个目标站点,并确保为每一站点可靠地提供信息。MQ不仅提供了多点广播的功能,而且还拥有智能消息分发功能,在将一条消息发送到同一系统上的多个用户时,MQ将消息的一个复制版本和该系统上接收者的名单发送到目标MQ系统。目标MQ系统在本地复制这些消息,并将它们发送到名单上的队列,从而尽可能减少网络的传输量。

    3)发布/订阅(Publish/Subscribe)模式:发布/订阅功能使消息的分发可以突破目的队列地理指向的限制,使消息按照特定的主题甚至内容进行分发,用户或应用程序可以根据主题或内容接收到所需要的消息。发布/订阅功能使得发送者和接收者之间的耦合关系变得更为松散,发送者不必关心接收者的目的地址,而接收者也不必关心消息的发送地址,而只是根据消息的主题进行消息的收发。在MQ家族产品中,MQEventBroker是专门用于使用发布/订阅技术进行数据通讯的产品,它支持基于队列和直接基于TCP/IP两种方式的发布和订阅。

    4)群集(Cluster):为了简化点对点通讯模式中的系统配置,MQ提供Cluster(群集)的解决方案。群集类似于一个域(Domain),群集内部的队列管理器之间通讯时,不需要两两之间建立消息通道,而是采用群集(Cluster)通道与其它成员通讯,从而大大简化了系统配置。此外,群集中的队列管理器之间能够自动进行负载均衡,当某一队列管理器出现故障时,其它队列管理器可以接管它的工作,从而大大提高系统的高可靠性。

    1.使用消息队列的理由

    过去几年中,我们一直在使用、构建和宣传消息队列,我们认为它们是很令人敬畏的,这也不是什么秘密。我们相信对任何架构或应用来说,消息队列都是一个至关重要的组件,下面是十个理由:

    1. 1解耦

    在项目启动之初来预测将来项目会碰到什么需求,是极其困难的。消息队列在处理过程中间插入了一个隐含的、基于数据的接口层,两边的处理过程都要实现这一接口。这允许你独立的扩展或修改两边的处理过程,只要确保它们遵守同样的接口约束。

    1.2 冗余

    有时在处理数据的时候处理过程会失败。除非数据被持久化,否则将永远丢失。消息队列把数据进行持久化直到它们已经被完全处理,通过这一方式规避了数据丢失风险。在被许多消息队列所采用的"插入-获取-删除"范式中,在把一个消息从队列中删除之前,需要你的处理过程明确的指出该消息已经被处理完毕,确保你的数据被安全的保存直到你使用完毕。

    1.3 扩展性

    因为消息队列解耦了你的处理过程,所以增大消息入队和处理的频率是很容易的;只要另外增加处理过程即可。不需要改变代码、不需要调节参数。扩展就像调大电力按钮一样简单。

    1.4 灵活性 & 峰值处理能力

    当你的应用上了Hacker News的首页,你将发现访问流量攀升到一个不同寻常的水平。在访问量剧增的情况下,你的应用仍然需要继续发挥作用,但是这样的突发流量并不常见;如果为以能处理这类峰值访问为标准来投入资源随时待命无疑是巨大的浪费。使用消息队列能够使关键组件顶住增长的访问压力,而不是因为超出负荷的请求而完全崩溃。请查看我们关于峰值处理能力的博客文章了解更多此方面的信息。

    1.5可恢复性

    当体系的一部分组件失效,不会影响到整个系统。消息队列降低了进程间的耦合度,所以即使一个处理消息的进程挂掉,加入队列中的消息仍然可以在系统恢复后被处理。而这种允许重试或者延后处理请求的能力通常是造就一个略感不便的用户和一个沮丧透顶的用户之间的区别。

    1.6送达保证

    消息队列提供的冗余机制保证了消息能被实际的处理,只要一个进程读取了该队列即可。在此基础上,IronMQ提供了一个"只送达一次"保证。无论有多少进程在从队列中领取数据,每一个消息只能被处理一次。这之所以成为可能,是因为获取一个消息只是"预定"了这个消息,暂时把它移出了队列。除非客户端明确的表示已经处理完了这个消息,否则这个消息会被放回队列中去,在一段可配置的时间之后可再次被处理。

    1.7排序保证

    在许多情况下,数据处理的顺序都很重要。消息队列本来就是排序的,并且能保证数据会按照特定的顺序来处理。IronMO保证消息浆糊通过FIFO(先进先出)的顺序来处理,因此消息在队列中的位置就是从队列中检索他们的位置。

    1.8缓冲

    在任何重要的系统中,都会有需要不同的处理时间的元素。例如,加载一张图片比应用过滤器花费更少的时间。消息队列通过一个缓冲层来帮助任务最高效率的执行--写入队列的处理会尽可能的快速,而不受从队列读的预备处理的约束。该缓冲有助于控制和优化数据流经过系统的速度。

    1.9 理解数据流

    在一个分布式系统里,要得到一个关于用户操作会用多长时间及其原因的总体印象,是个巨大的挑战。消息系列通过消息被处理的频率,来方便的辅助确定那些表现不佳的处理过程或领域,这些地方的数据流都不够优化。

    1.10 异步通信

    很多时候,你不想也不需要立即处理消息。消息队列提供了异步处理机制,允许你把一个消息放入队列,但并不立即处理它。你想向队列中放入多少消息就放多少,然后在你乐意的时候再去处理它们。


    2.消息队列应用场景

    以下介绍消息队列在实际应用中常用的使用场景。异步处理,应用解耦,流量削锋和消息通讯四个场景。

    2.1异步处理

    场景说明:用户注册后,需要发注册邮件和注册短信。传统的做法有两种 1.串行的方式;2.并行方式
    a、串行方式:将注册信息写入数据库成功后,发送注册邮件,再发送注册短信。以上三个任务全部完成后,返回给客户端。

    b、并行方式:将注册信息写入数据库成功后,发送注册邮件的同时,发送注册短信。以上三个任务完成后,返回给客户端。与串行的差别是,并行的方式可以提高处理的时间

    假设三个业务节点每个使用50毫秒钟,不考虑网络等其他开销,则串行方式的时间是150毫秒,并行的时间可能是100毫秒。
    因为CPU在单位时间内处理的请求数是一定的,假设CPU1秒内吞吐量是100次。则串行方式1秒内CPU可处理的请求量是7次(1000/150)。并行方式处理的请求量是10次(1000/100)
    小结:如以上案例描述,传统的方式系统的性能(并发量,吞吐量,响应时间)会有瓶颈。如何解决这个问题呢?

    引入消息队列,将不是必须的业务逻辑,异步处理。改造后的架构如下:

    按照以上约定,用户的响应时间相当于是注册信息写入数据库的时间,也就是50毫秒。注册邮件,发送短信写入消息队列后,直接返回,因此写入消息队列的速度很快,基本可以忽略,因此用户的响应时间可能是50毫秒。因此架构改变后,系统的吞吐量提高到每秒20 QPS。比串行提高了3倍,比并行提高了两倍。

    2.2应用解耦

    场景说明:用户下单后,订单系统需要通知库存系统。传统的做法是,订单系统调用库存系统的接口。如下图:

    传统模式的缺点:假如库存系统无法访问,则订单减库存将失败,从而导致订单失败,订单系统与库存系统耦合

    如何解决以上问题呢?引入应用消息队列后的方案,如下图:

    订单系统:用户下单后,订单系统完成持久化处理,将消息写入消息队列,返回用户订单下单成功
    库存系统:订阅下单的消息,采用拉/推的方式,获取下单信息,库存系统根据下单信息,进行库存操作
    假如:在下单时库存系统不能正常使用。也不影响正常下单,因为下单后,订单系统写入消息队列就不再关心其他的后续操作了。实现订单系统与库存系统的应用解耦

    2.3流量削锋

    流量削锋也是消息队列中的常用场景,一般在秒杀或团抢活动中使用广泛
    应用场景:秒杀活动,一般会因为流量过大,导致流量暴增,应用挂掉。为解决这个问题,一般需要在应用前端加入消息队列。
    a、可以控制活动的人数
    b、可以缓解短时间内高流量压垮应用

    用户的请求,服务器接收后,首先写入消息队列。假如消息队列长度超过最大数量,则直接抛弃用户请求或跳转到错误页面。
    秒杀业务根据消息队列中的请求信息,再做后续处理

    2.4日志处理

    日志处理是指将消息队列用在日志处理中,比如Kafka的应用,解决大量日志传输的问题。架构简化如下

    日志采集客户端,负责日志数据采集,定时写受写入Kafka队列
    Kafka消息队列,负责日志数据的接收,存储和转发
    日志处理应用:订阅并消费kafka队列中的日志数据 

    2.5消息通讯

    消息通讯是指,消息队列一般都内置了高效的通信机制,因此也可以用在纯的消息通讯。比如实现点对点消息队列,或者聊天室等
    点对点通讯:

    客户端A和客户端B使用同一队列,进行消息通讯。

    聊天室通讯:

    客户端A,客户端B,客户端N订阅同一主题,进行消息发布和接收。实现类似聊天室效果。

    以上实际是消息队列的两种消息模式,点对点或发布订阅模式。模型为示意图,供参考。

    3.消息中间件示例

    3.1电商系统


    消息队列采用高可用,可持久化的消息中间件。比如Active MQ,Rabbit MQ,Rocket Mq。
    (1)应用将主干逻辑处理完成后,写入消息队列。消息发送是否成功可以开启消息的确认模式。(消息队列返回消息接收成功状态后,应用再返回,这样保障消息的完整性)
    (2)扩展流程(发短信,配送处理)订阅队列消息。采用推或拉的方式获取消息并处理。
    (3)消息将应用解耦的同时,带来了数据一致性问题,可以采用最终一致性方式解决。比如主数据写入数据库,扩展应用根据消息队列,并结合数据库方式实现基于消息队列的后续处理。

    3.2日志收集系统


    分为Zookeeper注册中心,日志收集客户端,Kafka集群和Storm集群(OtherApp)四部分组成。
    Zookeeper注册中心,提出负载均衡和地址查找服务
    日志收集客户端,用于采集应用系统的日志,并将数据推送到kafka队列
    Kafka集群:接收,路由,存储,转发等消息处理
    Storm集群:与OtherApp处于同一级别,采用拉的方式消费队列中的数据

    以下是新浪kafka日志处理应用案例:转自(http://cloud.51cto.com/art/201507/484338.htm)

     

    (1)Kafka:接收用户日志的消息队列

    (2)Logstash:做日志解析,统一成JSON输出给Elasticsearch

    (3)Elasticsearch:实时日志分析服务的核心技术,一个schemaless,实时的数据存储服务,通过index组织数据,兼具强大的搜索和统计功能

    (4)Kibana:基于Elasticsearch的数据可视化组件,超强的数据可视化能力是众多公司选择ELK stack的重要原因


    4.JMS消息服务

    讲消息队列就不得不提JMS 。JMS(JAVA Message Service,java消息服务)API是一个消息服务的标准/规范,允许应用程序组件基于JavaEE平台创建、发送、接收和读取消息。它使分布式通信耦合度更低,消息服务更加可靠以及异步性。
    在EJB架构中,有消息bean可以无缝的与JM消息服务集成。在J2EE架构模式中,有消息服务者模式,用于实现消息与应用直接的解耦。

    4.1消息模型

    在JMS标准中,有两种消息模型P2P(Point to Point),Publish/Subscribe(Pub/Sub)。

    4.1.1 P2P模式


    P2P模式包含三个角色:消息队列(Queue),发送者(Sender),接收者(Receiver)。每个消息都被发送到一个特定的队列,接收者从队列中获取消息。队列保留着消息,直到他们被消费或超时。

    P2P的特点
    每个消息只有一个消费者(Consumer)(即一旦被消费,消息就不再在消息队列中)
    发送者和接收者之间在时间上没有依赖性,也就是说当发送者发送了消息之后,不管接收者有没有正在运行,它不会影响到消息被发送到队列
    接收者在成功接收消息之后需向队列应答成功
    如果希望发送的每个消息都会被成功处理的话,那么需要P2P模式。

    4.1.2 Pub/Sub模式


    包含三个角色主题(Topic),发布者(Publisher),订阅者(Subscriber) 多个发布者将消息发送到Topic,系统将这些消息传递给多个订阅者。

    Pub/Sub的特点
    每个消息可以有多个消费者
    发布者和订阅者之间有时间上的依赖性。针对某个主题(Topic)的订阅者,它必须创建一个订阅者之后,才能消费发布者的消息
    为了消费消息,订阅者必须保持运行的状态
    为了缓和这样严格的时间相关性,JMS允许订阅者创建一个可持久化的订阅。这样,即使订阅者没有被激活(运行),它也能接收到发布者的消息。
    如果希望发送的消息可以不被做任何处理、或者只被一个消息者处理、或者可以被多个消费者处理的话,那么可以采用Pub/Sub模型。

    4.2消息消费

    在JMS中,消息的产生和消费都是异步的。对于消费来说,JMS的消息者可以通过两种方式来消费消息。
    (1)同步
    订阅者或接收者通过receive方法来接收消息,receive方法在接收到消息之前(或超时之前)将一直阻塞;

    (2)异步
    订阅者或接收者可以注册为一个消息监听器。当消息到达之后,系统自动调用监听器的onMessage方法。

    JNDI:Java命名和目录接口,是一种标准的Java命名系统接口。可以在网络上查找和访问服务。通过指定一个资源名称,该名称对应于数据库或命名服务中的一个记录,同时返回资源连接建立所必须的信息。
    JNDI在JMS中起到查找和访问发送目标或消息来源的作用。

    5.常用消息队列

    一般商用的容器,比如WebLogic,JBoss,都支持JMS标准,开发上很方便。但免费的比如Tomcat,Jetty等则需要使用第三方的消息中间件。本部分内容介绍常用的消息中间件(Active MQ,Rabbit MQ,Zero MQ,Kafka)以及他们的特点。

    5.1 ActiveMQ

    ActiveMQ 是Apache出品,最流行的,能力强劲的开源消息总线。ActiveMQ 是一个完全支持JMS1.1和J2EE 1.4规范的 JMS Provider实现,尽管JMS规范出台已经是很久的事情了,但是JMS在当今的J2EE应用中间仍然扮演着特殊的地位。

    ActiveMQ特性如下:

    • 多种语言和协议编写客户端。语言: Java,C,C++,C#,Ruby,Perl,Python,PHP。应用协议: OpenWire,Stomp REST,WS Notification,XMPP,AMQP
    • 完全支持JMS1.1和J2EE 1.4规范 (持久化,XA消息,事务)
    •  对Spring的支持,ActiveMQ可以很容易内嵌到使用Spring的系统里面去,而且也支持Spring2.0的特性
    •  通过了常见J2EE服务器(如 Geronimo,JBoss 4,GlassFish,WebLogic)的测试,其中通过JCA 1.5 resource adaptors的配置,可以让ActiveMQ可以自动的部署到任何兼容J2EE 1.4 商业服务器上
    •  支持多种传送协议:in-VM,TCP,SSL,NIO,UDP,JGroups,JXTA
    • 支持通过JDBC和journal提供高速的消息持久化
    • 从设计上保证了高性能的集群,客户端-服务器,点对点
    • 支持Ajax
    • 支持与Axis的整合
    • 可以很容易得调用内嵌JMS provider,进行测试

    5.2 RabbitMQ

    RabbitMQ是流行的开源消息队列系统,用erlang语言开发。RabbitMQ是AMQP(高级消息队列协议)的标准实现。支持多种客户端,如:Python、Ruby、.NET、Java、JMS、C、PHP、ActionScript、XMPP、STOMP等,支持AJAX,持久化。用于在分布式系统中存储转发消息,在易用性、扩展性、高可用性等方面表现不俗。结构图如下:

    几个重要概念:

    • Broker:简单来说就是消息队列服务器实体。
    • Exchange:消息交换机,它指定消息按什么规则,路由到哪个队列。
    • Queue:消息队列载体,每个消息都会被投入到一个或多个队列。
    • Binding:绑定,它的作用就是把exchange和queue按照路由规则绑定起来。
    • Routing Key:路由关键字,exchange根据这个关键字进行消息投递。
    • vhost:虚拟主机,一个broker里可以开设多个vhost,用作不同用户的权限分离。
    • producer:消息生产者,就是投递消息的程序。
    • consumer:消息消费者,就是接受消息的程序。
    • channel:消息通道,在客户端的每个连接里,可建立多个channel,每个channel代表一个会话任务。

    消息队列的使用过程,如下:

    • 客户端连接到消息队列服务器,打开一个channel。
    • 客户端声明一个exchange,并设置相关属性。
    • 客户端声明一个queue,并设置相关属性。
    • 客户端使用routing key,在exchange和queue之间建立好绑定关系。
    • 客户端投递消息到exchange。

    exchange接收到消息后,就根据消息的key和已经设置的binding,进行消息路由,将消息投递到一个或多个队列里。

    5.3 ZeroMQ

    号称史上最快的消息队列,它实际类似于Socket的一系列接口,他跟Socket的区别是:普通的socket是端到端的(1:1的关系),而ZMQ却是可以N:M 的关系,人们对BSD套接字的了解较多的是点对点的连接,点对点连接需要显式地建立连接、销毁连接、选择协议(TCP/UDP)和处理错误等,而ZMQ屏蔽了这些细节,让你的网络编程更为简单。ZMQ用于node与node间的通信,node可以是主机或者是进程。

    引用官方的说法: “ZMQ(以下ZeroMQ简称ZMQ)是一个简单好用的传输层,像框架一样的一个socket library,他使得Socket编程更加简单、简洁和性能更高。是一个消息处理队列库,可在多个线程、内核和主机盒之间弹性伸缩。ZMQ的明确目标是“成为标准网络协议栈的一部分,之后进入Linux内核”。现在还未看到它们的成功。但是,它无疑是极具前景的、并且是人们更加需要的“传统”BSD套接字之上的一 层封装。ZMQ让编写高性能网络应用程序极为简单和有趣。”

    特点是:

    • 高性能,非持久化

    • 跨平台:支持Linux、Windows、OS X等

    • 多语言支持; C、C++、Java、.NET、Python等30多种开发语言

    • 可单独部署或集成到应用中使用

    • 可作为Socket通信库使用

    与RabbitMQ相比,ZMQ并不像是一个传统意义上的消息队列服务器,事实上,它也根本不是一个服务器,更像一个底层的网络通讯库,在Socket API之上做了一层封装,将网络通讯、进程通讯和线程通讯抽象为统一的API接口。支持“Request-Reply “,”Publisher-Subscriber“,”Parallel Pipeline”三种基本模型和扩展模型。

    ZeroMQ高性能设计要点:

    1、无锁的队列模型

       对于跨线程间的交互(用户端和session)之间的数据交换通道pipe,采用无锁的队列算法CAS;在pipe两端注册有异步事件,在读或者写消息到pipe的时,会自动触发读写事件。

    2、批量处理的算法

       对于传统的消息处理,每个消息在发送和接收的时候,都需要系统的调用,这样对于大量的消息,系统的开销比较大,zeroMQ对于批量的消息,进行了适应性的优化,可以批量的接收和发送消息。

    3、多核下的线程绑定,无须CPU切换

       区别于传统的多线程并发模式,信号量或者临界区, zeroMQ充分利用多核的优势,每个核绑定运行一个工作者线程,避免多线程之间的CPU切换开销。


    5.4 Kafka

    Kafka是一种高吞吐量的分布式发布订阅消息系统,它可以处理消费者规模的网站中的所有动作流数据。 这种动作(网页浏览,搜索和其他用户的行动)是在现代网络上的许多社会功能的一个关键因素。 这些数据通常是由于吞吐量的要求而通过处理日志和日志聚合来解决。 对于像Hadoop的一样的日志数据和离线分析系统,但又要求实时处理的限制,这是一个可行的解决方案。Kafka的目的是通过Hadoop的并行加载机制来统一线上和离线的消息处理,也是为了通过集群机来提供实时的消费。

    Kafka是一种高吞吐量的分布式发布订阅消息系统,有如下特性:

    • 通过O(1)的磁盘数据结构提供消息的持久化,这种结构对于即使数以TB的消息存储也能够保持长时间的稳定性能。(文件追加的方式写入数据,过期的数据定期删除)
    • 高吞吐量:即使是非常普通的硬件Kafka也可以支持每秒数百万的消息
    • 支持通过Kafka服务器和消费机集群来分区消息
    • 支持Hadoop并行数据加载

    Kafka相关概念

    • Broker:Kafka集群包含一个或多个服务器,这种服务器被称为broker[5]
    • Topic:每条发布到Kafka集群的消息都有一个类别,这个类别被称为Topic。(物理上不同Topic的消息分开存储,逻辑上一个Topic的消息虽然保存于一个或多个broker上但用户只需指定消息的Topic即可生产或消费数据而不必关心数据存于何处)
    • Partition:Parition是物理上的概念,每个Topic包含一个或多个Partition.
    • Producer:负责发布消息到Kafka broker
    • Consumer:消息消费者,向Kafka broker读取消息的客户端。
    • Consumer Group:每个Consumer属于一个特定的Consumer Group(可为每个Consumer指定group name,若不指定group name则属于默认的group)。

    一般应用在大数据日志处理或对实时性(少量延迟),可靠性(少量丢数据)要求稍低的场景使用。

    6.使用消息队列需要考虑的问题

    6.1你也许并不需要消息队列

    消息队列是一个能让你获得容错性,分布式,解耦等架构能力的系统。纸上谈兵的话,它看起来还不错。

    或许消息列队在你的应用中有不少适用的场景。你可以看下这篇关于消息队列优点的文章,看看到底有哪些合适的场景。但可不要因为说"能解耦那太好了”就轻易使用它。我们来看一个例子——你希望你的邮件发送和订单处理互相解耦。

    因此你发送一个消息到消息队列里,然后邮件处理系统取出这个消息并发送邮件。那你在一个独立的单classpath的应用中怎么实现呢?让你的订单处理服务依赖于一个邮件服务,然后调用sendEmail()方法,而不是sendToMQ()方法。如果你使用了消息队列,你需要定义一个两个系统都能识别的消息格式 ;如果你不使用消息队列,那么你得定义一个方法签名。它们有什么本质的区别吗?其实没有。

    不过你可能还有别的消费者想要对某个指定的消息进行额外的处理?这的确是可能发生的,而并不只是针对我们这里说到的这个项目而已。尽管确有可能,但相比添加另一个方法调用而言,它可能并不值当。耦合?是的。不过这个耦合并没有什么不方便的。

    那我应该如何处理峰值流量?你可以通过消息队列将请求放到一个持久化队列中,然后再一并处理它们。这是一个非常有用的特性,不过它也受限于几个 因素——你的请求是在UI后台处理,还是需要即时响应?serlvet容器的线程池某种程度上可以当作是一个队列,用户最终会拿到响应,但是得需要等待(如果线程的超时时间过短的话,请求可能会丢失)。

    你可以使用一个内存队列来存储那些较重的请求(得在UI后台进行处理)。不过注意了,你的队列并不是默认高可用的。比如说,如果一个消息队列节点挂掉了,你的消息就丢失了。因此,不去使用应用节点内的内存队列,而是去使用一个消息队列,这可能并没有什么优势。

    消息队列使得我们可以进行异步处理——这的确是个有用的特性。你不希望在用户等待的时候做一些很重的操作。不过你也可以使用一个内存队列,或者简单地启动一个新的线程(比如Spring的@Async注解)。这样又有另一个问题——如果消息丢失的话是否有问题?如果你应用处理请求的节点挂了,你可以进行恢复吗?你会发现这事会经常发生,如果不保证所有消息都处理到的话,很难保证功能的正确性。因此,仅将较重的调用进行异步处理是比较可取的。

    把消息放到队列以便让另一个组件来进行处理,对于这个场景,如果消息丢失是无法接受的 ,这也有一个很简单的解决方案——数据库。你可以把一条processed=false的数据存储到数据库中。然后再运行一个调度作业,将所有未处理的记录挑选出来,异步地进行处理。当处理完成的时候,将标记设为true。我经常用这个方法,包括在一些大型的线上系统中,它也工作得挺好的。

    这样你还能不断地对你的应用节点进行扩展,只要它们的内存中没有任何的持久化状态的话。不管你是否使用了消息队列都可以(临时的内存处理队列并不属于持久化状态)。

    为什么我要给经常用到的消息队列提供一些备选方案?因为如果你由于不恰当的原因选择了它,那么消息队列可能会成为一个负担。它们并非如想像中那样容易使用。首先,它有一个学习曲线。一般来说,你集成的组件切分得越多,就越容易出现问题。其次,还有一个设置及配置的成本。比如说,当消息队列需要在一个集群中运行的话,比如说多个数据中心,那么这就变得复杂了。

    高可用性并不是上来就有的——默认它是不会打开的。还有就是你的应用节点如何连接到消息队列?通过一个刷新的连接池,或者使用短生命周期的DNS记录,还是通过一个负载均衡器?你的队列可能还有许多配置项,大小是多少,行为是怎样的(消费者需不需要确认接受,要不要通知处理失败,多个消费者能够取到同一个消息吗,消息有没有TTL,等等)同时还有网络及消息传递的开销,尤其是现在大家都喜欢用XML或者JSON来传输消息。如果你过度地使用了消息队列,那么它会增加你系统的延时。

    最后一点,但并不是最次要的——如果出现问题的话,使用消息队列会让问题跟踪变得异常困难。你没法在IDE中看到所谓的调用层次,因为一旦你发送消息到队列里了,你就得自己去查找它在哪里处理的了。这可不是听起来那么简单的。你看到了吧,它会给你增加许多的复杂性,以及许多需要注意的东西。

    通常而言,在某些上下文中,消息队列还是非常有用的。当它们的确适合的话,我也会在项目中使用它们——比方说,我们不想丢失消息,但又希望能快速地进行处理。我也见过它在一些不太常见的场景中使用的情况,比如说只有一个应用节点来进行消费,不管是哪个节点投递过来的消息。你还可以看下stackoverflow上的这个问题。还有一些使用场景就是,或许你的确需要进行多语言间的通信,又或者你的数据流已经过于复杂了,不使用新的消息消费者而是增加新方法调用的话代价会很大。

    我想说的是那句老掉牙的真理“杀鸡焉用牛刀”。如果你不是很确定已经没有别的更容易管理和维护的方法,一定要使用消息队列的话,最好不要使用它。不要因为”万一它有用呢“而去用它——只有你确实觉得需要的话再去使用。因为很有可能,就像这里说到的这个项目一样,消息队列其实是没有必要的。

    6.2如何避免消息丢失

    选择能够支持消息持久化的MQ方案。如:ActiveMQ、RabbitMQ等,给消息一个处理状态如:process=false。

    还可以使用缓存方案做:如Redis,它本身也是支持持久化的。


    7.本文参考资料来源


    消息队列MQ的原理及实现方法:http://blog.csdn.net/lzq_csdn_th/article/details/51945408


    关于消息队列的使用:http://www.cnblogs.com/linjiqin/p/5720865.html


    消息队列使用的四种场景介绍:http://blog.csdn.net/cws1214/article/details/52922267


    使用消息队列的十个理由:http://www.oschina.net/translate/top-10-uses-for-message-queue?p=2


    国外的一款消息队列IronMQ:http://iron.io/products/mq?rc=blog_mq_t10


    你可能并不需要消息队列:http://kb.cnblogs.com/page/212710/


    展开全文
  • 作者:华为云开发者社区 ...来源:知乎 ...· 1945艾伦图灵论文《计算机器不智能》提出了著名的图灵测试,给人工智能的収展产生了深远的影响。 · 1951年,马文·明斯基(Marvin Minsky)和迪恩..
  • 但是,新冠大流行只是医学界普遍挑战的一个明显例子。PubMed是生物医学研究论文的标准存储库,每天增加4,000篇新论文,每年增加一百万篇。   仅靠人工就不可能跟踪如此迅速的进展。大数据和精密医学时代,...
  • 大页内存(HugePages)通用程序优化应用

    万次阅读 多人点赞 2014-12-13 20:04:04
    这方面的资料比较贫乏,而且网上绝大多数资料都是介绍它Oracle数据库应用,这会让人产生一种错觉:这种技术只能Oracle数据库中应用。但其实,大页内存可以算是一种非常通用的优化技术,应用范围很广,针对...
  • 引言数据分析,我们常常想将看上去相似或者行为形似的数据聚合一起。例如,对一个营销组织来说,将不同客户根据他们的特点进行分组,从而有针对性地定制营销活动,这很重要。又比如,对学校老师来说,将学生...
  • 1.前言 深度学习已经图像分类、检测、分割、高分辨率图像生成等诸多...而实际上这两者存在一定的偏差,比如测试数据上的预测准确率就通常比训练数据上的要低,这就是过度拟合的问题。 另一个问题是深度学习
  • 应用系统的可维护性: 整体组织;逻辑分割;细粒度措施;技术决策; 一致处理;有效隔离;消除重复; 对维护敏感
  • 然而,作为内容安全检测的一个重要技术手段,文本分类在实际业务还是有不少的挑战。 首先,内容安全场景对分类的准确度要求极高,不但要求较低的误判率,任何一个漏判都有可能给产品方带来严重的后果。其次,...
  • [Hadoop] 实际应用场景之 - 阿里

    千次阅读 2013-06-22 17:16:02
    Hadoop淘宝和支付宝的应用从09年开始,用于对海量数据的离线处理,例如对日志的分析,也涉及内容部分,结构化数据等。使用Hadoop主要基于可扩展性的考虑,规模从当初的3-4百节点增长到今天单一集群3000节点以上,2...
  • MQTT 是一个理想的协议,它物联网与 M2M 通信应用是无限的。如果你需要轻量级的消息传输系统,那么它会是很好的选择,而且未来几年可能会流行起来。希望本文能帮助读者对 MQTT 做以了解。 参考阅读:...
  • 通过loosejar清理应用中冗余的jar包

    千次阅读 2014-08-10 19:23:36
    随着应用规模的逐渐增大,依赖的jar包数量也大幅增加,其中不乏多余...因为应用在运行的时候,用到哪个类,classloader就会把这个类的.class文件加载到jvm,然后生成一个class对象,然后再利用反射就可以执行这个类的
  • java多线程有哪些实际应用场景?

    万次阅读 多人点赞 2017-10-17 10:10:33
    简单的说,可能就是一个请求一个线程。或多个请求一个线程。如果是单线程,那同时只能处理一个用户的请求。 2、伸缩性:也就是说,你可以通过增加CPU核数来提升性能。如果是单线程,那程序执行到死也就利用了单核,...
  • PMOS和NMOS开关应用中高侧和低侧驱动的对比

    万次阅读 多人点赞 2016-07-14 13:40:26
    区别于这类常见的机械开关,我们电子电路常用的还有各类半导体开关,例如三极管开关、使用三极管级联的达林顿管开关、MOS管开关、晶闸管开关等等。我们可以看到普通机械开关与半导体开关最大的差异就在于开关...
  • 人工智能无人驾驶应用

    万次阅读 多人点赞 2019-08-19 10:22:03
    引用自:人工智能自动驾驶领域的应用及启示 吴 琦,于海靖,谢 勇,刘 贝 1 引言 ​         人们越来越期望通过无人系统代替人类进行一些活动。小到帮助人们自动清扫地面的扫地机器人,大...
  • 本文主人公 英特 是一名传统的软件工程师,让我们与英特一起来研究如何实现自己的Lookalike算法,并尝试着新浪微博上应用这一算法。  当2012 年Facebook 广告领域开始应用定制化受众(Facebook CustomAudiences...
  • 前言这是一篇拖了很久的总结,项目引入了redis的bitmap的用法,感觉挺高大上的,刨根问底,故留下总结一篇当作纪念。...5.使用bitmap过程中可能会遇到的坑。 6.bitmap进阶用法(思考)。bitmap的原理、用法原理8b
  • 状态机思路程序设计应用

    万次阅读 多人点赞 2013-01-18 16:37:29
    状态机思路单片机程序设计应用 状态机的概念 状态机是软件编程的一个重要概念。比这个概念更重要的是对它的灵活应用一个思路清晰而且高效的程序,必然有状态机的身影浮现。 比如说一个按键...
  • 人工智能医学影像的研究与应用

    万次阅读 多人点赞 2019-03-26 15:34:04
    人工智能医学影像的研究与应用韩冬, 李其花, 蔡巍, 夏雨薇, 宁佳, 黄峰沈阳东软医疗系统有限公司,辽宁 沈阳 110167慧影医疗科技(北京)有限公司,北京 10...
  • code93作为code39的改进,复杂程居中,到目前还没在实际中见到应用。而code128就比较复杂,除了有A、B、C三个子编码方案外,还有一个自动组合三者的Auto方案,自动方案的目的是组合ABC三方案使用某一字符串编码为...
  • 图像处理就是对图像信息进行加工处理,以满足人的视觉心理和实际应用的要求。图像去噪是图像处理研究的一个永恒主题。大多数图像去噪的方法,尤其是高斯白噪声的去噪方法,从本质上来说,都是低通滤波的方法. 低通滤波...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 374,074
精华内容 149,629
关键字:

在实际应用中尽可能不要通过