精华内容
下载资源
问答
  • 概念的内涵和外延

    2019-09-29 10:55:47
    在逻辑学的学术范围内,概念的逻辑结构分为“内涵“外延”。内涵是指一个概念所反映的思维对象本质特有的属性的总和;概念的外延是指具有该概念所反映的本质属性的一切对象。例如“国家”这一概念的内涵包括:他...

    概念的内涵和外延

    任何一个概念都有内涵和外延,这是概念的基本特征。外延指所反应对象的具体范围、具体事物。内涵指概念所反应的特征和本质属性。在逻辑学的学术范围内,概念的逻辑结构分为“内涵”与“外延”。内涵是指一个概念所反映的思维对象本质特有的属性的总和;概念的外延是指具有该概念所反映的本质属性的一切对象。例如“国家”这一概念的内涵包括:他是阶级社会中所特有的政治实体,是阶级矛盾不可调和的产物,是统治阶级统治、压迫被统治阶级的工具,是由军队、警察、监狱、法庭、立法机构和行政机构组成的暴力统治机器,等等。外延是指一个概念所概括的思维对象的数量或范围。例如,“国家“的外延就是指古今中外的一切国家。

    内涵是对一切外延特征的概括,外延是内涵表述的具体化。如等腰三角形,这一概念的内涵是有且只有两条边长度相同的三角形,其外延则是等腰锐角三角形、等腰钝角三角形、正三角形。

     内涵越大,外延就越小;内涵越小,外延就越大。比如,人这个概念,内涵是"有理性的动物",外延就是所有的人类。但是概念如果是"男人",那么内涵就比"有理性的动物"多了一点,就是"雄性的有理性的动物",而其外延就不是全部的人类了,就要排除其中的女人。如果概念是"老男人",那么内涵又要再加入年龄的因素,进一步扩大,而其外延就要在排除了女人和年轻的男人之后,才能符合要求。换句话说,你对一个事物的规定越多,符合规定的事物就越少;你对一个事物的规定越少,符合规定的事物就越多。

     但是,在文学作品中有例外。由于形象是普遍的特殊显现,在其内涵以及各个要素之间的相互联系上给读者的想象留下了广阔的空间,也就是说它是要求这个“特殊”的积极参与的构成过程,因而其外延就无法用概念确切的概括出来。越特殊的形象其外延越难以穷尽,其原因就在于它越能容纳诸多的读者的构成,唯其如此,越是独特的就越是普遍的,即内涵越大其外延就越大。之所以每个读者都能在典型形象上看到自己的影子,内涵的众多组成部分,即特殊是其根本的保证,否则普遍的抽象就与特殊的读者无关,没有特殊的,即读者的积极参与,概念也就是确定的,其意义也就因而是可以穷尽的了。

    任何一个概念都有内涵和外延,这是概念的基本特征.外延指所反应对象的具体范围,内涵指概念所反应的特征和本质属性.如果对话语概念的内涵和外延理解错误就会发生笑话:一天法国作家雨果出国旅行,走到了边境,宪兵问他:"姓名?""雨果.""干什么的?""写东西的.""以什么谋生?""笔杆子."于是宪兵在登记本上写道:"姓名:雨果.职业:笔杆贩子."雨果和宪兵对"以笔杆子谋生"这个概念的内涵和外延理解不同:雨果理解的内涵是"以写作获得稿费维持生计"外延所指作家,宪兵对其内涵的理解是"以贩卖笔杆子谋生"外延所指"笔杆贩子".

     概念从外延上可分为相容关系和不相容关系;在相容关系中,又可分为同一关系、属种关系、交叉关系;在不相容关系中,又可分为矛盾关系和反对关系,所谓同一关系就是外延完全重合的两个概念之间的关系。在鲁迅先生的《孔乙己》中老书生孔乙己,偷了别人的书不承认,只说自己是窃书,不算偷。他的回答使众人哄堂大笑。为什么会这样呢?是因为“偷”和“窃”两个概念的外延是同一关系,而孔乙己把他当成了非同一关系,所以让人发笑。

     我们把一个概念的外延包含着另一概念的全部外延的两个概念间的关系,称为属种关系,在此关系中外延大的称为属概念,小的称为种概念,如果不分清属种关系会导致出现荒谈谬论:

    脊椎动物分成哺乳、鸟、爬行、两栖和鱼五个小类;

    哺乳动物是脊椎动物;

    所以,哺乳动物分成哺乳、鸟、爬行、两栖和鱼五个小类。

    结论荒谬。因为大前提里的“脊椎动物”特指类的集合,不能真包含小前提里的“哺乳动物”;两个“中项”一是总称,一是泛指,也不是同一个概念。

    辑学交叉关系是针对概念的外延而言的。外向即概念所指事物的集合,这与数学中集合之间的交叉关系是一致的。所以用集合来定义交叉关系是指两个有共同元素,也有非共同元素的集合之间的关系。两种概念间的交叉关系就是指这两种概念的外延有且只有部分重合。在英国有一位德高望重的绅士,走到那里都有人起身向他问候一天他来到了一家旅馆,吃早餐时坐在他对面的人站了起来,绅士说:“坐下,不必客气。”那人说:“难道我去拿盐也不许吗?”这使绅士十分尴尬。

    这是一场误会,顾客要去取盐,他确认为是要向他表示尊重,绅士把交叉关系当成了同一关系所以发生了误会。

    概念间不相容关系之一。在同一个属概念下的两个种概念的外延互相排斥,其相加之和等于该属概念的外延。具有这种关系的两个种概念,其内涵互相否定,一个概念以否定另一个概念的内涵作为自身的内涵。如在“颜色”这个属概念下的“白”和“非白”两个属概念就具有矛盾关系。具有矛盾关系的两个概念称为“矛盾概念”。

    古时候一个地方有一种习俗,凡是犯了死罪的人,临死前可从两长分别写着“生”“死”的纸片中抽一张,抽到“生”就放,“死”就杀。

    有一个农夫被陷害,被捕。次日,开始抽纸片,农夫把一张纸使劲的吞了下去,虽然一张纸被毁,但还有一张,于是另一张纸被翻开写着“死”,法官就宣布:释放农夫。

    农夫借着矛盾关系,巧妙的脱了险。

    当两个种概念是同一属概念下的不相容关系时,两者的外延之和小于属概念的外延,就称之为反对关系,也叫对立关系。

    在实数范围内,正数和非正数、负数之间都是不相容关系,正数和负数之间是反对关系。

    转载于:https://www.cnblogs.com/byfei/p/6389825.html

    展开全文
  • 视频 码率控制类型和内涵

    千次阅读 2018-10-09 17:18:36
    x264的码率控制分为帧间级帧内级,本文介绍帧间级各种码率控制类型,其内涵和使用方法。 1 目的意义: 码率控制有两个目的 兼容传输、播放条件 更高的视频质量 1.1 兼容传输、播放条件 视频编码中,越高的...

    在做视频编码时,当我们给编码器设定一个目标码率的时候,编码器内部是怎么达到码率要求的呢 ?

    编码器如何合理分配码率,以获得更高的视频质量 ?

    这都是码率控制的问题。

    x264的码率控制分为帧间级和帧内级,本文介绍帧间级各种码率控制类型,其内涵和使用方法。

    1 目的和意义:

    码率控制有两个目的

    • 兼容传输、播放条件
    • 更高的视频质量

    1.1 兼容传输、播放条件

    视频编码中,越高的码率通常可以产生更高的质量。同时,保持一定质量的情况下,不同复杂度场景需要的码率是不一样的。

    如果不进行码率控制,视频的码率会不可控制。下图是对一段40s的视频,采用固定量化参数(也就是没有码率控制)编码后的瞬时码率分布。

    可以看到,码率的波动很大。这对于传输是不利的。码率控制通过调节编码参数,控制单位时间内的编码视频流的数据量,以使产生的比特流符合各种应用的需求。

    bitrate, fixed QP

     

    【图1】固定量化参数,码率分布

    1.2 更高的视频质量

    在满足码率要求的前提下,码率控制的另一个目标是更高的视频质量。

    如何通过在帧间以及帧内合理分配比特,实现率失真性能优化,是码率控制研究的问题。

     

    2. 分类

    码率控制可以分为两类:

    • CBR :  constant bit rate, 固定码率
    • VBR:   variable bit rate, 可变码率

    2.2 恒定码率模式

    图2是第一节中同样视频用CBR模式编码得到的码率分布图。

    可以看到它的码率波动比图1小。

    恒定码率不代表每个瞬间的码率都一样,实际上那是不可能的。恒定码率模式究竟是什么原理,我们在下文会详细展开。

     

    constant bitrate

    【图2】恒定码率

    使用固定码率会损害视频质量,但对传输有好处。

    2.3 可变码率模式

    可变码率是一类码率控制算法的统称,它们的特点是局部的码率是可变的。 常用的可变码率子类包括:

    • abr : average bit rate, 平均码率。
      局部码率是可变的,限制整个文件的的评价码率。
    • crf: constant refactor, 恒定质量
      把某个恒定的“质量”作为目标,灵活分配码率,最终的码率大小是不确定的。
    • cqp: constant qp: 恒定量化参数
      采用固定的qp, 相当于没有码率控制

    3. 恒定码率 CBR 的内涵

    恒定码率模式有点tricky,容易导致误解。

    • 它不代表每个瞬间码率相同。这是不可能的,由于I帧,P帧和B帧体积相差巨大。
    • 它也不代表每一秒(或者某个时间窗口)码率相同。实际上,如图2所见,每一秒的数据量是不同的。
    • CBR 的 “固定码率”, 指的是固定 “信道容量”。 码率控制的目标是,在用恒定的速率传输码流,播放器的接收缓存不会上溢,也不会下溢。

    3.1 vbv 模型

    CBR 码率控制算法是针对缓冲区校验模型的。

    区校验模型是视频编码标准的重要组成部分,是用来验证编码码流是否符合标准的重要工具。

    在 MPEG系列标准中缓冲区模型常称 VBV ( Video Bu Verifier ) , 即视频缓冲区校验器,在 H.26x系列标准中,该部分称 HRD ( Hypothetical Reference Decoder) ,即假想参考解码器。

    vbv 模型假想编码码率通过一个容量受限的信道传输到解码设备,解码设备在解码前有一个缓存。解码器实时从缓存区取数据解码。vbv必须保证缓存区不上溢,也不下溢。

    解码器的缓存可以理解成一个水池,如下图所示。水池的输入速度是恒定的,也就是设定的码率。水池的输出的不恒定的,是视频的实际瞬时码率。

    vbv model

     

    缓存区的存在使得视频的瞬时码率可以在一定范围内波动。

    但是,如果视频实际瞬时码率过大,从缓存区取数据的速度就会大于填数据的速度,这是缓冲区有可能就被取空了,这叫做缓冲区的下溢。

    相反,如果视频实际瞬时码率过小,从缓存区取数据的速度就会小于填数据的速度,这是缓冲区有可能就会溢出,这叫做缓冲区的上溢。

    不难理解,vbv 能容忍的最大码率波动和缓冲区的大小,以及缓冲区初始充盈程度有关。

    3.2 vbv 参数的设置方法

    在x264中, vbv 有两个参数可以设置,分别是:

    ---vbv-maxrate, 设置缓冲区最大填入速度。

    ---vbv-bufsize , 设置缓冲区大小。

    例子:

    假设设置maxrate= 1M, bufsize = 2M,  缓冲区初始是充盈的。假设某时峰值率是2M, 那么能容忍的峰值的最大长度为 2M/(2M-1M) = 2s

    假设某时峰值率是3M, 那么能容忍的峰值的最大长度为 2M/(3M-1M) = 2s

    假设某时峰值率是11M, 那么能容忍的峰值的最大长度为 2M/(11M-1M) =0.1s

    也就是说,计算设置最大码率为1M, 也能容忍很高的码率峰值。越高的峰值,能容忍的时长越短。

    效果:

    bufsize 越大,码率波动空间越大 → 视频质量越好。

    bufsize 越大,播放延时越大。 延时 delay = bufsize / maxrate。 (假设需要等缓冲区填满才开始播放)

    bufsize设置的大小取决于容忍的延时以及播放器的硬件内存限制。

    足够长的时间里,总码率 约等于  maxrate * 时间。  

     

    4. 可变码率 VBR 的类型和内涵

    • abr   平均码率,控制的目标是整个文件的平均码率
      2 pass : 两趟编码,根据第一趟的实际码率,估计每一帧复杂度
      1 pass : 一趟编码, 根据已编码的邻近帧,估计正在编的帧的复杂度
    • crf 
      恒定质量: 控制一个恒定的“质量”,总码率不可控。 
    • cqp
      恒定qp: 恒定量化参数,关闭一切码率控制算法。cqp 和crf 的区别是,crf 允许x264对每一帧,每一宏块灵活选取qp, 通过对视觉感知特点的运用,产生一个恒定的“质量”。
    展开全文
  • 算法设计方法:递归的内涵与经典应用

    万次阅读 多人点赞 2017-05-13 10:54:45
    对一些简单的递归问题,我们总是惊叹于递归描述问题编写代码的简洁,但要想真正领悟递归的精髓、灵活地运用递归思想来解决问题却并不是一件容易的事情。本文剖析了递归的思想内涵并分析了阶乘、斐波那契数列、汉诺...

    摘要:

      大师 L. Peter Deutsch 说过:To Iterate is Human, to Recurse, Divine.中文译为:人理解迭代,神理解递归。毋庸置疑地,递归确实是一个奇妙的思维方式。对一些简单的递归问题,我们总是惊叹于递归描述问题的能力和编写代码的简洁,但要想真正领悟递归的精髓、灵活地运用递归思想来解决问题却并不是一件容易的事情。本文剖析了递归的思想内涵,分析了递归与循环的联系与区别,给出了递归的应用场景和一些典型应用,并利用递归和非递归的方式解决了包括阶乘、斐波那契数列、汉诺塔、杨辉三角的存取、字符串回文判断、字符串全排列、二分查找、树的深度求解在内的八个经典问题。


    版权声明:

      本文原创作者:书呆子Rico
      作者博客地址:http://blog.csdn.net/justloveyou_/


    友情提示:

      若读者需要本博文相关完整代码,请移步我的Github自行获取,项目名为 SwordtoOffer,链接地址为:https://github.com/githubofrico/SwordtoOffer


    一. 引子

       大师 L. Peter Deutsch 说过:To Iterate is Human, to Recurse, Divine.中文译为:人理解迭代,神理解递归。毋庸置疑地,递归确实是一个奇妙的思维方式。对一些简单的递归问题,我们总是惊叹于递归描述问题的能力和编写代码的简洁,但要想真正领悟递归的精髓、灵活地运用递归思想来解决问题却并不是一件容易的事情。在正式介绍递归之前,我们首先引用知乎用户李继刚(https://www.zhihu.com/question/20507130/answer/15551917)对递归和循环的生动解释:

       递归:你打开面前这扇门,看到屋里面还有一扇门。你走过去,发现手中的钥匙还可以打开它,你推开门,发现里面还有一扇门,你继续打开它。若干次之后,你打开面前的门后,发现只有一间屋子,没有门了。然后,你开始原路返回,每走回一间屋子,你数一次,走到入口的时候,你可以回答出你到底用这你把钥匙打开了几扇门。

       循环:你打开面前这扇门,看到屋里面还有一扇门。你走过去,发现手中的钥匙还可以打开它,你推开门,发现里面还有一扇门(若前面两扇门都一样,那么这扇门和前两扇门也一样;如果第二扇门比第一扇门小,那么这扇门也比第二扇门小,你继续打开这扇门,一直这样继续下去直到打开所有的门。但是,入口处的人始终等不到你回去告诉他答案。

       上面的比喻形象地阐述了递归与循环的内涵,那么我们来思考以下几个问题:

    • 什么是递归呢?
    • 递归的精髓(思想)是什么?
    • 递归和循环的区别是什么?
    • 什么时候该用递归?
    • 使用递归需要注意哪些问题?
    • 递归思想解决了哪些经典的问题?

    这些问题正是笔者准备在本文中详细阐述的问题。


    二. 递归的内涵

    1、定义 (什么是递归?)

       在数学与计算机科学中,递归(Recursion)是指在函数的定义中使用函数自身的方法。实际上,递归,顾名思义,其包含了两个意思:,这正是递归思想的精华所在。


    2、递归思想的内涵(递归的精髓是什么?)

       正如上面所描述的场景,递归就是有去(递去)有回(归来),如下图所示。“有去”是指:递归问题必须可以分解为若干个规模较小,与原问题形式相同的子问题,这些子问题可以用相同的解题思路来解决,就像上面例子中的钥匙可以打开后面所有门上的锁一样;“有回”是指 : 这些问题的演化过程是一个从大到小,由近及远的过程,并且会有一个明确的终点(临界点),一旦到达了这个临界点,就不用再往更小、更远的地方走下去。最后,从这个临界点开始,原路返回到原点,原问题解决。  

                         这里写图片描述

      
       更直接地说,递归的基本思想就是把规模大的问题转化为规模小的相似的子问题来解决。特别地,在函数实现时,因为解决大问题的方法和解决小问题的方法往往是同一个方法,所以就产生了函数调用它自身的情况,这也正是递归的定义所在。格外重要的是,这个解决问题的函数必须有明确的结束条件,否则就会导致无限递归的情况。


    3、用归纳法来理解递归

       数学都不差的我们,第一反应就是递归在数学上的模型是什么,毕竟我们对于问题进行数学建模比起代码建模拿手多了。观察递归,我们会发现,递归的数学模型其实就是 数学归纳法,这个在高中的数列里面是最常用的了,下面回忆一下数学归纳法。

       数学归纳法适用于将解决的原问题转化为解决它的子问题,而它的子问题又变成子问题的子问题,而且我们发现这些问题其实都是一个模型,也就是说存在相同的逻辑归纳处理项。当然有一个是例外的,也就是归纳结束的那一个处理方法不适用于我们的归纳处理项,当然也不能适用,否则我们就无穷归纳了。总的来说,归纳法主要包含以下三个关键要素:

    • 步进表达式:问题蜕变成子问题的表达式
    • 结束条件:什么时候可以不再使用步进表达式
    • 直接求解表达式:在结束条件下能够直接计算返回值的表达式

    事实上,这也正是某些数学中的数列问题在利用编程的方式去解决时可以使用递归的原因,比如著名的斐波那契数列问题。


    4、递归的三要素

       在我们了解了递归的基本思想及其数学模型之后,我们如何才能写出一个漂亮的递归程序呢?笔者认为主要是把握好如下三个方面:

    • 明确递归终止条件;

    • 给出递归终止时的处理办法;

    • 提取重复的逻辑,缩小问题规模。


    1). 明确递归终止条件

       我们知道,递归就是有去有回,既然这样,那么必然应该有一个明确的临界点,程序一旦到达了这个临界点,就不用继续往下递去而是开始实实在在的归来。换句话说,该临界点就是一种简单情境,可以防止无限递归。


    2). 给出递归终止时的处理办法

       我们刚刚说到,在递归的临界点存在一种简单情境,在这种简单情境下,我们应该直接给出问题的解决方案。一般地,在这种情境下,问题的解决方案是直观的、容易的。


    3). 提取重复的逻辑,缩小问题规模*

       我们在阐述递归思想内涵时谈到,递归问题必须可以分解为若干个规模较小、与原问题形式相同的子问题,这些子问题可以用相同的解题思路来解决。从程序实现的角度而言,我们需要抽象出一个干净利落的重复的逻辑,以便使用相同的方式解决子问题。


    5、递归算法的编程模型

       在我们明确递归算法设计三要素后,接下来就需要着手开始编写具体的算法了。在编写算法时,不失一般性,我们给出两种典型的递归算法设计模型,如下所示。


    模型一: 在递去的过程中解决问题

    function recursion(大规模){
        if (end_condition){      // 明确的递归终止条件
            end;   // 简单情景
        }else{            // 在将问题转换为子问题的每一步,解决该步中剩余部分的问题
            solve;                // 递去
            recursion(小规模);     // 递到最深处后,不断地归来
        }
    }

    模型二: 在归来的过程中解决问题

    function recursion(大规模){
        if (end_condition){      // 明确的递归终止条件
            end;   // 简单情景
        }else{            // 先将问题全部描述展开,再由尽头“返回”依次解决每步中剩余部分的问题
            recursion(小规模);     // 递去
            solve;                // 归来
        }
    }

    6、递归的应用场景

       在我们实际学习工作中,递归算法一般用于解决三类问题:

       (1). 问题的定义是按递归定义的(Fibonacci函数,阶乘,…);

       (2). 问题的解法是递归的(有些问题只能使用递归方法来解决,例如,汉诺塔问题,…);

       (3). 数据结构是递归的(链表、树等的操作,包括树的遍历,树的深度,…)。

      在下文我们将给出递归算法的一些经典应用案例,这些案例基本都属于第三种类型问题的范畴。


    三. 递归与循环

       递归与循环是两种不同的解决问题的典型思路。递归通常很直白地描述了一个问题的求解过程,因此也是最容易被想到解决方式。循环其实和递归具有相同的特性,即做重复任务,但有时使用循环的算法并不会那么清晰地描述解决问题步骤。单从算法设计上看,递归和循环并无优劣之别。然而,在实际开发中,因为函数调用的开销,递归常常会带来性能问题,特别是在求解规模不确定的情况下;而循环因为没有函数调用开销,所以效率会比递归高。递归求解方式和循环求解方式往往可以互换,也就是说,如果用到递归的地方可以很方便使用循环替换,而不影响程序的阅读,那么替换成循环往往是好的。问题的递归实现转换成非递归实现一般需要两步工作:

       (1). 自己建立“堆栈(一些局部变量)”来保存这些内容以便代替系统栈,比如树的三种非递归遍历方式;

       (2). 把对递归的调用转变为对循环处理。

       特别地,在下文中我们将给出递归算法的一些经典应用案例,对于这些案例的实现,我们一般会给出递归和非递归两种解决方案,以便读者体会。


    四. 经典递归问题实战

    1. 第一类问题:问题的定义是按递归定义的

    (1). 阶乘

    /**
     * Title: 阶乘的实现 
     * Description:
     *      递归解法
     *      非递归解法
     * @author rico
     */
    public class Factorial {
        /**     
         * @description 阶乘的递归实现
         * @author rico       
         * @created 2017年5月10日 下午8:45:48     
         * @param n
         * @return     
         */
        public static long f(int n){
            if(n == 1)   // 递归终止条件 
                return 1;    // 简单情景
    
            return n*f(n-1);  // 相同重复逻辑,缩小问题的规模
        }
    
    --------------------------------我是分割线-------------------------------------
    
        /**     
         * @description 阶乘的非递归实现
         * @author rico       
         * @created 2017年5月10日 下午8:46:43     
         * @param n
         * @return     
         */
        public static long f_loop(int n) {
            long result = n;
            while (n > 1) {
                n--;
                result = result * n;
            }
            return result;
        }
    }

    (2). 斐波纳契数列

    /**
     * Title: 斐波纳契数列
     * 
     * Description: 斐波纳契数列,又称黄金分割数列,指的是这样一个数列:1、1、2、3、5、8、13、21、……
     * 在数学上,斐波纳契数列以如下被以递归的方法定义:F0=0,F1=1,Fn=F(n-1)+F(n-2)(n>=2,n∈N*)。
     * 
     * 两种递归解法:经典解法和优化解法
     * 两种非递归解法:递推法和数组法
     * 
     * @author rico
     */
    public class FibonacciSequence {
    
        /**
         * @description 经典递归法求解
         * 
         * 斐波那契数列如下:
         * 
         *  1,1,2,3,5,8,13,21,34,...
         * 
         * 那么,计算fib(5)时,需要计算1次fib(4),3次fib(3),3次fib(2)和两次fib(1),即:
         * 
         *  fib(5) = fib(4) + fib(3)
         *  
         *  fib(4) = fib(3) + fib(2) ;fib(3) = fib(2) + fib(1)
         *  
         *  fib(3) = fib(2) + fib(1)
         *  
         * 这里面包含了许多重复计算,而实际上我们只需计算fib(4)、fib(3)、fib(2)和fib(1)各一次即可,
         * 后面的optimizeFibonacci函数进行了优化,使时间复杂度降到了O(n).
         * 
         * @author rico
         * @created 2017年5月10日 下午12:00:42
         * @param n
         * @return
         */
        public static int fibonacci(int n) {
            if (n == 1 || n == 2) {     // 递归终止条件
                return 1;       // 简单情景
            }
            return fibonacci(n - 1) + fibonacci(n - 2); // 相同重复逻辑,缩小问题的规模
        }
    
    --------------------------------我是分割线-------------------------------------
    
        /**     
         * @description 对经典递归法的优化
         * 
         * 斐波那契数列如下:
         * 
         *  1,1,2,3,5,8,13,21,34,...
         * 
         * 那么,我们可以这样看:fib(1,1,5) = fib(1,2,4) = fib(2,3,3) = 5
         * 
         * 也就是说,以1,1开头的斐波那契数列的第五项正是以1,2开头的斐波那契数列的第四项,
         * 而以1,2开头的斐波那契数列的第四项也正是以2,3开头的斐波那契数列的第三项,
         * 更直接地,我们就可以一步到位:fib(2,3,3) = 2 + 3 = 5,计算结束。 
         * 
         * 注意,前两个参数是数列的开头两项,第三个参数是我们想求的以前两个参数开头的数列的第几项。
         * 
         * 时间复杂度:O(n)
         * 
         * @author rico       
         * @param first 数列的第一项
         * @param second 数列的第二项
         * @param n 目标项
         * @return     
         */
        public static int optimizeFibonacci(int first, int second, int n) {
            if (n > 0) {
                if(n == 1){    // 递归终止条件
                    return first;       // 简单情景
                }else if(n == 2){            // 递归终止条件
                    return second;      // 简单情景
                }else if (n == 3) {         // 递归终止条件
                    return first + second;      // 简单情景
                }
                return optimizeFibonacci(second, first + second, n - 1);  // 相同重复逻辑,缩小问题规模
            }
            return -1;
        }
    
    --------------------------------我是分割线-------------------------------------
    
        /**
         * @description 非递归解法:有去无回
         * @author rico
         * @created 2017年5月10日 下午12:03:04
         * @param n
         * @return
         */
        public static int fibonacci_loop(int n) {
    
            if (n == 1 || n == 2) {   
                return 1;
            }
    
            int result = -1;
            int first = 1;      // 自己维护的"栈",以便状态回溯
            int second = 1;     // 自己维护的"栈",以便状态回溯
    
            for (int i = 3; i <= n; i++) { // 循环
                result = first + second;
                first = second;
                second = result;
            }
            return result;
        }
    
    --------------------------------我是分割线-------------------------------------
    
    /**     
         * @description 使用数组存储斐波那契数列
         * @author rico       
         * @param n
         * @return     
         */
        public static int fibonacci_array(int n) {
            if (n > 0) {
                int[] arr = new int[n];   // 使用临时数组存储斐波纳契数列
                arr[0] = arr[1] = 1;
    
                for (int i = 2; i < n; i++) {   // 为临时数组赋值
                    arr[i] = arr[i-1] + arr[i-2];
                }
                return arr[n - 1];
            }
            return -1;
        }
    }

    (3). 杨辉三角的取值

        /**     
         * @description 递归获取杨辉三角指定行、列(从0开始)的值
         *              注意:与是否创建杨辉三角无关
         * @author rico 
         * @x  指定行
         * @y  指定列    
         */
      /**
        * Title: 杨辉三角形又称Pascal三角形,它的第i+1行是(a+b)i的展开式的系数。
        * 它的一个重要性质是:三角形中的每个数字等于它两肩上的数字相加。
        * 
        * 例如,下面给出了杨辉三角形的前4行: 
        *    1 
        *   1 1
        *  1 2 1
        * 1 3 3 1
        * @description 递归获取杨辉三角指定行、列(从0开始)的值
        *              注意:与是否创建杨辉三角无关
        * @author rico 
        * @x  指定行
        * @y  指定列  
        */
        public static int getValue(int x, int y) {
            if(y <= x && y >= 0){
                if(y == 0 || x == y){   // 递归终止条件
                    return 1; 
                }else{ 
                    // 递归调用,缩小问题的规模
                    return getValue(x-1, y-1) + getValue(x-1, y); 
                }
            }
            return -1;
        } 
    }

    (4). 回文字符串的判断

    /**        
     * Title: 回文字符串的判断    
     * Description: 回文字符串就是正读倒读都一样的字符串。如"98789", "abccba"都是回文字符串
     * 
     * 两种解法:
     *      递归判断;
     *      循环判断;
     * 
     * @author rico       
     */      
    public class PalindromeString {
    
        /**     
         * @description 递归判断一个字符串是否是回文字符串
         * @author rico       
         * @created 2017年5月10日 下午5:45:50     
         * @param s
         * @return     
         */
        public static boolean isPalindromeString_recursive(String s){
            int start = 0;
            int end = s.length()-1;
            if(end > start){   // 递归终止条件:两个指针相向移动,当start超过end时,完成判断
                if(s.charAt(start) != s.charAt(end)){
                    return false;
                }else{
                    // 递归调用,缩小问题的规模
                    return isPalindromeString_recursive(s.substring(start+1).substring(0, end-1));
                }
            }
            return true;
        }
    
    --------------------------------我是分割线-------------------------------------
    
        /**     
         * @description 循环判断回文字符串
         * @author rico       
         * @param s
         * @return     
         */
        public static boolean isPalindromeString_loop(String s){
            char[] str = s.toCharArray();
            int start = 0;
            int end = str.length-1;
            while(end > start){  // 循环终止条件:两个指针相向移动,当start超过end时,完成判断
                if(str[end] != str[start]){
                    return false;
                }else{
                    end --;
                    start ++;
                }
            }
            return true;
        }
    }

    (5). 字符串全排列

    • 递归解法
    /**
         * @description 从字符串数组中每次选取一个元素,作为结果中的第一个元素;然后,对剩余的元素全排列
         * @author rico
         * @param s
         *            字符数组
         * @param from
         *            起始下标
         * @param to
         *            终止下标
         */
        public static void getStringPermutations3(char[] s, int from, int to) {
            if (s != null && to >= from && to < s.length && from >= 0) { // 边界条件检查
                if (from == to) { // 递归终止条件
                    System.out.println(s); // 打印结果
                } else {
                    for (int i = from; i <= to; i++) {
                        swap(s, i, from); // 交换前缀,作为结果中的第一个元素,然后对剩余的元素全排列
                        getStringPermutations3(s, from + 1, to); // 递归调用,缩小问题的规模
                        swap(s, from, i); // 换回前缀,复原字符数组
                    }
                }
            }
        }
    
        /**
         * @description 对字符数组中的制定字符进行交换
         * @author rico
         * @param s
         * @param from
         * @param to
         */
        public static void swap(char[] s, int from, int to) {
            char temp = s[from];
            s[from] = s[to];
            s[to] = temp;
        }
    • 非递归解法(字典序全排列)
    /**
     * Title: 字符串全排列非递归算法(字典序全排列)
     * Description: 字典序全排列,其基本思想是:
     * 先对需要求排列的字符串进行字典排序,即得到全排列中最小的排列.
     * 然后,找到一个比它大的最小的全排列,一直重复这一步直到找到最大值,即字典排序的逆序列.
     * 
     * 不需要关心字符串长度
     * 
     * @author rico
     */
    public class StringPermutationsLoop {
    
        /**
         * @description 字典序全排列
         * 
         * 设一个字符串(字符数组)的全排列有n个,分别是A1,A2,A3,...,An
         * 
         * 1. 找到最小的排列 Ai
         * 2. 找到一个比Ai大的最小的后继排列Ai+1
         * 3. 重复上一步直到没有这样的后继
         * 
         * 重点就是如何找到一个排列的直接后继:
         * 对于字符串(字符数组)a0a1a2……an,
         * 1. 从an到a0寻找第一次出现的升序排列的两个字符(即ai < ai+1),那么ai+1是一个极值,因为ai+1之后的字符为降序排列,记 top=i+1;
         * 2. 从top处(包括top)开始查找比ai大的最小的值aj,记 minMax = j;
         * 3. 交换minMax处和top-1处的字符;
         * 4. 翻转top之后的字符(包括top),即得到一个排列的直接后继排列
         * 
         * @author rico
         * @param s
         *            字符数组
         * @param from
         *            起始下标
         * @param to
         *            终止下标
         */
        public static void getStringPermutations4(char[] s, int from, int to) {
    
            Arrays.sort(s,from,to+1);  // 对字符数组的所有元素进行升序排列,即得到最小排列 
            System.out.println(s);    
    
            char[] descendArr = getMaxPermutation(s, from, to); // 得到最大排列,即最小排列的逆序列
    
            while (!Arrays.equals(s, descendArr)) {  // 循环终止条件:迭代至最大排列
                if (s != null && to >= from && to < s.length && from >= 0) { // 边界条件检查
                    int top = getExtremum(s, from, to); // 找到序列的极值
                    int minMax = getMinMax(s, top, to);  // 从top处(包括top)查找比s[top-1]大的最小值所在的位置
                    swap(s, top - 1, minMax);  // 交换minMax处和top-1处的字符
                    s = reverse(s, top, to);   // 翻转top之后的字符
                    System.out.println(s);
                }
            }
        }
    
        /**
         * @description 对字符数组中的制定字符进行交换
         * @author rico
         * @param s
         * @param from
         * @param to
         */
        public static void swap(char[] s, int from, int to) {
            char temp = s[from];
            s[from] = s[to];
            s[to] = temp;
        }
    
        /**     
         * @description 获取序列的极值
         * @author rico       
         * @param s 序列
         * @param from 起始下标
         * @param to 终止下标
         * @return     
         */
        public static int getExtremum(char[] s, int from, int to) {
            int index = 0;
            for (int i = to; i > from; i--) {
                if (s[i] > s[i - 1]) {
                    index = i;
                    break;
                }
            }
            return index;
        }
    
        /**     
         * @description 从top处查找比s[top-1]大的最小值所在的位置
         * @author rico       
         * @created 2017年5月10日 上午9:21:13     
         * @param s
         * @param top 极大值所在位置
         * @param to
         * @return     
         */
        public static int getMinMax(char[] s, int top, int to) {
            int index = top;
            char base = s[top-1];
            char temp = s[top];
            for (int i = top + 1; i <= to; i++) {
                if (s[i] > base && s[i] < temp) {
                    temp = s[i];
                    index = i;
                }
                continue;
            }
            return index;
        }
    
        /**     
         * @description 翻转top(包括top)后的序列
         * @author rico       
         * @param s
         * @param from
         * @param to
         * @return     
         */
        public static char[] reverse(char[] s, int top, int to) {
            char temp;
            while(top < to){
                temp = s[top];
                s[top] = s[to];
                s[to] = temp;
                top ++;
                to --;
            }
            return s;
        }
    
        /**     
         * @description 根据最小排列得到最大排列
         * @author rico       
         * @param s 最小排列
         * @param from 起始下标
         * @param to 终止下标
         * @return     
         */
        public static char[] getMaxPermutation(char[] s, int from, int to) {
            //将最小排列复制到一个新的数组中
            char[] dsc = Arrays.copyOfRange(s, 0, s.length);
            int first = from;
            int end = to;
            while(end > first){  // 循环终止条件
                char temp = dsc[first];
                dsc[first] = dsc[end];
                dsc[end] = temp;
                first ++;
                end --;
            }
            return dsc;
        }

    (6). 二分查找

    /**  
         * @description 二分查找的递归实现
         * @author rico       
         * @param array 目标数组
         * @param low 左边界
         * @param high 右边界
         * @param target 目标值
         * @return 目标值所在位置
         */
    public static int binarySearch(int[] array, int low, int high, int target) {
    
            //递归终止条件
            if(low <= high){
                int mid = (low + high) >> 1;
                if(array[mid] == target){
                    return mid + 1;  // 返回目标值的位置,从1开始
                }else if(array[mid] > target){
                    // 由于array[mid]不是目标值,因此再次递归搜索时,可以将其排除
                    binarySearch(array, low, mid-1, target);
                }else{
                    // 由于array[mid]不是目标值,因此再次递归搜索时,可以将其排除
                    binarySearch(array, mid+1, high, target);
                }
            }
            return -1;   //表示没有搜索到
        }
    
    --------------------------------我是分割线-------------------------------------
    
    /**     
         * @description 二分查找的非递归实现
         * @author rico       
         * @param array 目标数组
         * @param low 左边界
         * @param high 右边界
         * @param target 目标值
         * @return 目标值所在位置
         */
    public static int binarySearchNoRecursive(int[] array, int low, int high, int target) {
    
            // 循环
            while (low <= high) {
                int mid = (low + high) >> 1;
                if (array[mid] == target) {
                    return mid + 1; // 返回目标值的位置,从1开始
                } else if (array[mid] > target) {
                    // 由于array[mid]不是目标值,因此再次递归搜索时,可以将其排除
                    high = mid -1;
                } else {
                    // 由于array[mid]不是目标值,因此再次递归搜索时,可以将其排除
                    low = mid + 1;
                }
            }
            return -1;  //表示没有搜索到
        }

    2. 第二类问题:问题解法按递归算法实现

    (1). 汉诺塔问题

    /**
     * Title: 汉诺塔问题 
     * Description:古代有一个梵塔,塔内有三个座A、B、C,A座上有64个盘子,盘子大小不等,大的在下,小的在上。
     * 有一个和尚想把这64个盘子从A座移到C座,但每次只能允许移动一个盘子,并且在移动过程中,3个座上的盘子始终保持大盘在下,
     * 小盘在上。在移动过程中可以利用B座。要求输入层数,运算后输出每步是如何移动的。
     * 
     * @author rico
     */
    public class HanoiTower {
    
        /**     
         * @description 在程序中,我们把最上面的盘子称为第一个盘子,把最下面的盘子称为第N个盘子
         * @author rico       
         * @param level:盘子的个数
         * @param from 盘子的初始地址
         * @param inter 转移盘子时用于中转
         * @param to 盘子的目的地址
         */
        public static void moveDish(int level, char from, char inter, char to) {
    
            if (level == 1) { // 递归终止条件
                System.out.println("从" + from + " 移动盘子" + level + " 号到" + to);
            } else {
                // 递归调用:将level-1个盘子从from移到inter(不是一次性移动,每次只能移动一个盘子,其中to用于周转)
                moveDish(level - 1, from, to, inter); // 递归调用,缩小问题的规模
                // 将第level个盘子从A座移到C座
                System.out.println("从" + from + " 移动盘子" + level + " 号到" + to); 
                // 递归调用:将level-1个盘子从inter移到to,from 用于周转
                moveDish(level - 1, inter, from, to); // 递归调用,缩小问题的规模
            }
        }
    
        public static void main(String[] args) {
            int nDisks = 30;
            moveDish(nDisks, 'A', 'B', 'C');
        }
    }
    

    3. 第三类问题:数据的结构是按递归定义的

    (1). 二叉树深度

    /**        
     * Title: 递归求解二叉树的深度   
     * Description: 
     * @author rico       
     * @created 2017年5月8日 下午6:34:50    
     */      
    public class BinaryTreeDepth {
    
        /**     
         * @description 返回二叉数的深度
         * @author rico       
         * @param t
         * @return     
         */
        public static int getTreeDepth(Tree t) {
    
            // 树为空
            if (t == null) // 递归终止条件
                return 0;
    
            int left = getTreeDepth(t.left); // 递归求左子树深度,缩小问题的规模
            int right = getTreeDepth(t.left); // 递归求右子树深度,缩小问题的规模
    
            return left > right ? left + 1 : right + 1;
        }
    }

    (2). 二叉树深度

        /**
         * @description 前序遍历(递归)
         * @author rico
         * @created 2017年5月22日 下午3:06:11
         * @param root
         * @return
         */
        public String preOrder(Node<E> root) {
            StringBuilder sb = new StringBuilder(); // 存到递归调用栈
            if (root == null) {   // 递归终止条件
                return "";     // ji 
            }else { // 递归终止条件
                sb.append(root.data + " "); // 前序遍历当前结点
                sb.append(preOrder(root.left)); // 前序遍历左子树
                sb.append(preOrder(root.right)); // 前序遍历右子树
                return sb.toString();
            }       
        }

    引用

    算法–方法递归
    递归算法的要素总结
    算法设计之五大常用算法设计方法总结
    怎么更好地终极理解递归算法
    漫谈递归:递归的思想
    递归比喻
    递归算法
    递归的应用,输出字符串的所有排列(java)

    展开全文
  • 一、前言在看内涵段子的时候,总是发现一些广告,瞬间就到几千的赞,这引起了我的注意,于是开始了探索之路。首先是预判,为什么可以瞬间这么多,我猜的原因有以下 1 、广告狗有几千个小号,轮流点赞 2 、点赞有bug...

    一、前言

    在看内涵段子的时候,总是发现一些广告,瞬间就到几千的赞,这引起了我的注意,于是开始了探索之路。

    首先是预判,为什么可以瞬间这么多,我猜的原因有以下

    • 1 、广告狗有几千个小号,轮流点赞
    • 2 、点赞有bug,同一个帐号可重复点赞
    • 3 、内部员工直接修改数据库

    就根据可能性来说,最大的可能排序为 2 > 1 > 3 ,第二个可能性是最大的。我们先来分析。

    二、分析

    2.1 开始抓包

    抓包是利用Fiddler2这个工具,使用方法请百度,这里不讲述。

    手机打开到随便一条段子的评论界面,然后打开Fiddler,对某条评论进行点赞,可以看到fiddler已经拦截到了请求。Fiddler左边是请求的链接信息,在右边的 Inspectors -> WebForms 下面可以看到请求的数据。

    这里写图片描述

    完整的Url为(还有隐藏的post参数):
    http://iu.snssdk.com/2/data/comment_action/?iid=16539392360&device_id=34695026312&ac=wifi&channel=xiaomi&aid=7&app_name=joke_essay&version_code=661&version_name=6.6.1&device_platform=android&ssmix=a&device_type=MI+2SC&device_brand=Xiaomi&os_api=19&os_version=4.4.4&uuid=860670023013591&openudid=704c458a9904e206&manifest_version_code=661&resolution=720*1280&dpi=320&update_version_code=6613

    返回的json内容为:

    bury_count=0
    comment_id=1582210742671533
    digg_count=1
    errno=0
    message=success
    stable=True
    user_bury=0
    user_digg=0

    根据返回的json内容,可以看到几个有用的数据:

    • comment_id: 点赞的评论id
    • digg_count: 这个评论已经有多少个赞了
    • message: 文本信息
    • errno: 错误代码,为0就是成功了,说明不为0就是失败了。

    2.2 分析头信息

    在Fiddler Inspectors -> Headers 可以看到头信息:

    这里写图片描述

    可以看到有cookie数据,然后里面有sessionid等等其他参数,这就有点懵逼,感觉有做身份验证的样子,不怕,继续探究下去。

    2.3 分析拼接参数

    从链接可以看到存在直接字符串拼接的参数:

    iid=16539392360&
    device_id=34695026312&
    ac=wifi&
    channel=xiaomi&
    aid=7&
    app_name=joke_essay&
    version_code=661&
    version_name=6.6.1&
    device_platform=android&
    ssmix=a&device_type=MI+2SC&
    device_brand=Xiaomi&
    os_api=19&
    os_version=4.4.4&
    uuid=860670023013591&
    openudid=704c458a9904e206&
    manifest_version_code=661&
    resolution=720*1280&
    dpi=320&
    update_version_code=6613

    可以看到拼接提交的参数有这么多,根据参数名可以猜测是提交的手机相关信息和app的信息,例如app_name,version_code,os_api等等,都是一些基础信息,这些忽略,对我们的重点评论完全没有关系。

    2.4 分析Post参数

    在Fiddler的WebForm的body下面,看到post提交的参数:

    参数名
    comment_id 1582210742671533
    action digg
    group_id 71854834345
    item_id 71854834345
    iid 16539392360
    device_id 34695026312
    ac wifi
    channel xiaomi
    aid 7
    app_name joke_essay
    version_code 661
    version_name 6.6.1
    device_platform android
    ssmix a
    device_type MI 2SC
    device_brand Xiaomi
    os_api 19
    os_version 4.4.4
    uuid 860670023013591
    openudid 704c458a9904e206
    manifest_version_code 661
    resolution 720*1280
    dpi 320
    update_version_code 6613

    好,又是一堆的参数,我们利用猜测法去掉无相关的参数,剩下有用的参数:

    参数
    comment_id
    action
    device_id
    group_id
    item_id
    iid
    uuid
    openudid

    为什么我留下的是这些参数呢,因为这些参数都是一些id数字,是比较敏感的。

    看完了参数之后,得出观点,如果是有用户身份验证的话,那么参数里面并没有看到用户的身份信息,头信息可能有用户信息,我们先不管头信息,就直接分析参数。

    • comment_id: 评论的id,这个很容易理解
    • action: 动作,点赞动作
    • device_id: 设备id,这个感觉有用,记录手机的id
    • group_id: 组id,这个估计没用
    • item_id: 项id,感觉也没用
    • iid:这个猜不出来
    • uuid:随机数
    • openidid:开放的udid,设备的标识

    2.5 筛选参数

    在确定了参数之后,接下来进行验证,回到Fiddler。我们先直接重复提交一遍请求,看看行不行,右键刚刚点赞请求 -> Replay -> Reissue Requests

    结果肯定不行的。。。。

    接下来进行参数的修改:右键刚刚点赞请求 -> Replay -> Reissue and Edit(编辑并且发送请求)。
    这里写图片描述

    然后会看到右边的WebForm会显示为一个编辑状态,修改我们最有可能的参数,我首先修改device_id,为什么呢,因为这是设备id,有可能是根据设备id来点赞的。

    把device_id的值随便修改一个数字,然后点击Run to Completion进行提交。
    这里写图片描述

    这时候,奇迹来了,可以看到,返回的json数据digg_count比上次大了1,然后重新看看评论的点赞数量,可以看到是增加了1。 到这里,我们就可以确定了,评论的点赞数量是根据设备id来进行区分的,所以,我们可以搞事情了。

    接下来,我们把其他参数都去掉,只留下comment_id和device_id,然后修改device_id进行提交看看能不能成功。

    这里写图片描述

    提交之后发现digg_count又增加了1,完美。

    三、 编写App

    根据上面的分析,我们即可编写刷赞的App

    App编写中…,下班,明天在搞

    四、已GG

    已经被修复了,现在已经有做session验证身份了,

    展开全文
  • ATDDTDD的哲学内涵

    千次阅读 2012-09-29 18:58:54
    ATDD (Acceptance Test-Driven Development)验收测试驱动开发是基于“用户需求实现”层面的测试驱动,TDD (Test-Driven Development)测试驱动...ATDDTDD都实现了孔子所倡导的“君子欲讷于言而敏于行”,如果开发人
  • 如何用一句话介绍synchronize的内涵

    千次阅读 2018-01-23 11:14:35
    内涵与表象 关于synchronize,一个非常通俗易懂,很容易记住的解释是: Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码。 这个解释很好,它...
  • Java的in.nextInt()in.nextLine()方法的具体内涵

    万次阅读 多人点赞 2019-02-28 21:56:20
    nextInt()方法在扫描到空白符的时候会将前面的数据读取走,但会丢下空白符“\r”在缓冲区中,但是,nextLine()方法在扫描的时候会将扫描到的空白符一清理掉。 了解了这两个方法特性区别,就知道了上边的代码...
  • 洞悉产品的深度内涵

    千次阅读 2017-09-24 21:24:01
    作为一名产品经理,应该像孩子一样呵护自己的产品。更应该了解产品的每个细节,熟悉产品诞生的每个过程。...如何匹配强化产品用户心智模型的连接? 第二,掌握用户核心需求的把控能力。 一旦获得每一...
  • 内涵的句子

    千次阅读 2010-11-12 19:30:00
    我曾经一个人无数次擦肩而过,衣服都擦破了,也没擦出火花。 <br />  3.厌倦,就是一个人吃完盘子里的食物后对盘子的感情。 <br />  4.通往成功的路,总是在施工中。 <br /> ...
  • 逻辑斯谛回归(Logistic Regression)【又名逻辑回归,对率回归,对数几率回归】:函数、模型及其理论内涵 逻辑斯谛函数(logistic function)【即sigmoid函数】:函数形式的来源 逻辑斯谛函数的形式为: h(z...
  • ERP的内涵(转)

    2008-03-16 16:43:00
    ERP的内涵 概括起来主要有三方面特点,也是ERPMRPⅡ的主要区别: 1. ERP是一个面向供需链管理(Supply Chain Management)的管理信息集成。ERP除了传统MRPⅡ系统的制造、供销、财务功能外,在功能上还增加了...
  • 讲真,灾备的内涵其实很丰富

    千次阅读 2019-05-14 21:30:01
    讲真,灾备的内涵其实很丰富 深证云 今天 如果你愿意一层一层一层地剥开它的心, 你会发现,你会讶异, 灾备的内涵其实很丰富。 譬如下面这些问题,你能说出个123吗? Question 灾备全称是什么?跟容灾一样吗? CDP...
  • TCP/IP模型背后的内涵(二)

    千次阅读 2013-04-29 22:20:17
    1.TCP/IP模型OSI模型TCP/IP模型从一开始就是从实践走出来的,因此它能更好地迎合实际的应用而不单单停留在纸面上。从TCP/IP的发展史来看,它将IP从TCP独立出来的一部分原因是旨在将复杂度压缩在最少的位置,即主机...
  • 网易云音乐喊话酷狗,内涵后者疑似抄袭部分功能

    千次阅读 多人点赞 2021-02-02 13:45:04
    2月2日上午消息,网易云音乐今日通过官方微博喊话酷狗音乐,疑似内涵后者疑似抄袭部分功能。网易云音乐称,“ 酷狗音乐‘山寨办’成立以来,一直以将网易云音乐新功能酷狗化(简称“狗化”)。” 网易云音乐表示,...
  • ...从官方介绍来看,皮皮虾的定位和内涵段子一样,都是搞笑神评论社区。里面的内容也很相似——搞笑视频、神评论、搞笑图片、段子等。以前内涵段子的用户,被称为段友,皮皮虾的用户,也被称为...
  • 随着web新兴框架Rails的崛起,国内同行也逐渐意识到了更新自己知识的必要性,对于是web程序员的我来说,也是如此。于是利用工作之余,我翻阅了很多相关书籍,来补充Ruby/Rails方面的知识,例如《Programming Ruby...
  • 编辑需要发布的文章,如图: 第五步:发布文章,返回首页或者进入【素材管理】栏目进行发布,如图: 【素材管理】栏目   所有已经编辑完成的文章历史发布的文章在【素材管理】栏目都可以集中统一管理;...
  • 最近产品组接到项任务,公司想做新产品(互联网产品),需要对行业进行调研,并写出可实施方案。方案可能会给到北京的CEO参考,作为互联网界人人知晓的大佬,有机会看到我的调研报告,想想也是相当鸡冻啊。评估该...
  • String的replaceAll Matcher.replaceAll. 如下是String的repalceAll的源码实现。 public String repalceAll (String expr,String substitute){ return Pattern.compile(expr).matcher( this ).replaceAll...
  • 它能让你将运行环境配置放在代码汇总然后部署, 一个Docker的配置可以在不同的环境环境中使用, 这样就降低了硬件要求应用环境之间耦合度 2、代码流水线管理 代码从开发者的机器到最终在生产环境上的部署, ...
  • 来源:《企业文明》 标签:大内 匠人 德国 2016-02-19 17:10:14 评论: 0 ...德国,不仅是诗人、思想家作曲家的国度,更盛产科学家、工程师、技师,并以其...这是一个理性浪漫举并重的民族。 曾经
  • 事实上,除了外观优势,这些年韩国汽车厂商在配置内外饰设计上都有了成熟发展。今天我们就用起亚的新凯尊来验证一番。  虎啸式”前脸设计 增加更多豪华元素 在越来越多的汽车厂家开始强调家族式设计的今天,...
  • 是一套微信原生视觉体验一致的基础样式库,由微信官方设计团队为微信 Web 开发量身设计,可以令用户的使用感知更加统一。包含 button 、 cell 、 dialog 、 progress 、 toast 、 article 、 actionsheet 、 ...
  • 矩阵的内涵! 对于逆矩阵的物理含义有帮助!

    千次阅读 多人点赞 2013-11-20 19:23:29
    如果不熟悉线性代数的概念,要去学习自然科学,现在看来就文盲差不多。”,然而“按照现行的国际标准,线性代数是通过公理化来表述的,它是第二代数学模型,这就带来了教学上的困难。” * 矩阵究竟是什么东西?...
  • 环比的区别

    千次阅读 2019-03-31 23:42:40
    1、环比,这两者所反映的虽然都是变化速度,但由于采用基期的不同,其反映的内涵是完全不同的; 一般来说,环比可以环比相比较,而不能拿环比相比较;而对于一个地方,考虑时间纵向上发展趋势的...
  • 它支持标准ANSI SQL,包括复杂查询,聚合,连接窗口函数。 Cassandra以前缺少交互式即席查询功能,甚至在CQL中不支持聚合函数。因为这个原因,Cassandra在作为数据库使用时经常被混淆。分析Cassandra中的数据有...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 25,307
精华内容 10,122
关键字:

和与同的内涵