精华内容
下载资源
问答
  • 1、对象概念

    千次阅读 2020-03-01 09:49:02
    面向对象编程(Object-Oriented Programming OOP)是一种编程思维方式和编码架构。 等你具备一定编程基础后,请务必再回头看。只有这样你才能深刻理解面向对象编程的重要性及设计方式。 1、抽象 从某种程度上来说,...

    编程语言就是创建应用程序的思想结构。

    面向对象编程(Object-Oriented Programming OOP)是一种编程思维方式和编码架构。

    等你具备一定编程基础后,请务必再回头看。只有这样你才能深刻理解面向对象编程的重要性及设计方式。

    1、抽象

    从某种程度上来说,问题的复杂度直接取决于抽象的类型和质量。这里的“类型”意思是:抽象的内容是什么?
    汇编语言是对底层机器的轻微抽象。接着出现的“命令式”语言(如 FORTRAN,BASIC 和 C)是对汇编语言的抽象。

    程序员必须要在机器模型(“解决方案空间”)和实际解决的问题模型(“问题空间”)之间建立起一种关联。

    为机器建模的另一个方法是为要解决的问题制作模型。

    对一些早期语言来说,如 LISP 和 APL,它们的做法是“从不同的角度观察世界”——“所有问题都归纳为列表”或“所有问题都归纳为算法”。PROLOG 则将所有 问题都归纳为决策链。对于这些语言,我们认为它们一部分是“基于约束”的编程,另一部分则是专为 处理图形符号设计的(后者被证明限制性太强)。每种方法都有自己特殊的用途,适合解决某一类的问题。只要超出了它们力所能及的范围,就会显得非常笨拙。

    面向对象的程序设计在此基础上跨出了一大步,程序员可利用一些工具表达“问题空间”内的元素。由于这种表达非常具有普遍性,所以不必受限于特定类型的问题。我们将问题空间中的元素以及它们在解决方案空间的表示称作“对象”(Object)。 当然,还有一些在问题空间没有对应的对象体。通过添加新的对象类型,程序可进行灵活的调整,以便与特定的问题配合。总之,OOP 允许我们根据问题来描述问题,而不是根据运行解决方案的计算机

    通过这些特征,我们可理解“纯粹”的面向对象程序设计方法是什么样的:

    1. 万物皆对象。你可以将对象想象成一种特殊的变量。它存储数据,但可以在你对其“发出请求”时执行本身的操作。理论上讲,你总是可以从要解决的问题身上抽象出概念性的组件,然后在程序中将其表示为一个对象。
    2. 程序是一组对象,通过消息传递来告知彼此该做什么。要请求调用一个对象的方法,你需要向该对象发送消息。
    3. 每个对象都有自己的存储空间,可容纳其他对象。或者说,通过封装现有对象,可制作出新型对象。所以,尽管对象的概念非常简单,但在程序中却可达到任意高的复杂程度。
    4. 每个对象都有一种类型。根据语法,每个对象都是某个“类”的一个“实例”。其中,“类”(Class)是“类型”(Type)的同义词。一个类最重要的特征就是“能将什么消息发给它?”。
    5. 同一类所有对象都能接收相同的消息。这实际是别有含义的一种说法,大家不久便能理解。由于类型为“圆”(Circle)的一个对象也属于类型为“形状”(Shape)的一个对象,所以一个圆完全能接收发送给"形状”的消息。这意味着可让程序代码统一指挥“形状”,令其自动控制所有符合“形状”描述的对象,其中自然包括“圆”。这一特性称为对象的“可替换性”,是OOP最重要的概念之一。

    一个对象具有自己的状态,行为和标识。这意味着对象有自己的内部数据(提供状态)、方法 (产生行为),并彼此区分(每个对象在内存中都有唯一的地址)

    2、接口

    所有对象都是唯一的,但同时也是具有相同的特性和行为的对象所归属的类的一部分。

    创建好一个类后,可根据情况生成许多对象。随后,可将那些对象作为要解决问题中存在的元素进行处理。事实上,当我们进行面向对象的程序设计时,面临的最大一项挑战性就是:如何在“问题空间”(问题实际存在的地方)的元素与“方案空间”(对实际问题进行建模的地方,如计算机)的元素之间建立理想的“一对一”的映射关系

    那么如何利用对象完成真正有用的工作呢?必须有一种办法能向对象发出请求,令其解决一些实际的问题。每个对象仅能接受特定的请求。我们向对象发出的请求是通过它的“接口”(Interface)定义的,对象的“类型”或“类”则规定了它的接口形式。“类型”与“接口”的对应关系是面向对象程序设计的基础
    在这里插入图片描述

    Light lt = new Light();
    lt.on();
    

    3、服务提供

    在开发或理解程序设计时,我们可以将对象看成是“服务提供者”。你的程序本身将为用户提供服务,并且它能通过调用其他对象提供的服务来实现这一点。我们的最终目标是开发或调用工具库中已有的一些对象,提供理想的服务来解决问题。

    • 我们该选择哪个对象来解决问题呢?
    • 对于还没有的对象,我们该设计成什么样呢?
    • 这些对象需要提供哪些服务,以及还需要调用其他哪些对象?

    我们可以将这些问题一一分解,抽象成一组服务。软件设计的基本原则是高内聚:每个组件的内部作用明确,功能紧密相关。在良好的面向对象设计中,每个对象功能单一且高效。这样的程序设计可以提高我们代码的复用性,同时也方便别人阅读和理解我们的代码。只有让人知道你提供什么服务,别人才能更好地将其应用到其他模块或程序中。

    4、封装

    可以把编程的侧重领域划分为研发和应用。应用程序员调用研发程序员构建的基础工具类来做快速开发。
    研发程序员开发一个工具类,该工具类仅向应用程序员公开必要的内容,并隐藏内部实现的细节。这样可以有效地避免该工具类被错误的使用和更改,从而减少程序出错的可能。彼此职责划分清晰,相互协作。当应用程序员调用研发程序员开发的工具类时,双方建立了关系。应用程序员通过使用现成的工具类组装应用程序或者构建更大的工具库。
    如果工具类的创建者将类的内部所有信息都公开给调用者,那么有些使用规则就不容易被遵守。因为前者无法保证后者是否会按照正确的规则来使用,甚至是改变该工具类。只有设定访问控制,才能从根本上阻止这种情况的发生
    因此,使用访问控制的原因有以下两点:

    1. 让应用程序员不要触摸他们不应该触摸的部分。(请注意,这也是一个哲学决策。部分编程语言认为如果程序员有需要,则应该让他们访问细节部分。)
    2. 使类库的创建者(研发程序员)在不影响后者使用的情况下完善更新工具库。例如,我们开发了一个功能简单的工具类,后来发现可以通过优化代码来提高执行速度。假如工具类的接口和实现部分明确分开并受到保护,那我们就可以轻松地完成改造。

    Java 有三个显式关键字来设置类中的访问权限:public(公开),private(私有)和protected(受保护)。这些访问修饰符决定了谁能使用它们修饰的方法、变量或类。

    1. public(公开) 表示任何人都可以访问和使用该元素;
    2. private(私有) 除了类本身和类内部的方法,外界无法直接访问该元素。private 是类和调用者之间的屏障。任何试图访问私有成员的行为都会报编译时错误;
    3. protected(受保护) 类似于 private,区别是子类(下一节就会引入继承的概念)可以访问 protected 的成员,但不能访问 private 成员;
    4. default(默认) 如果你不使用前面的三者,默认就是 default 访问权限。default 被称为包访问,因为该权限下的资源可以被**同一包(库组件)**中其他类的成员访问。

    5、复用

    一个类经创建和测试后,理应是可复用的。

    代码和设计方案的复用性是面向对象程序设计的优点之一。我们可以通过重复使用某个类的对象来达到这种复用性。同时,我们也可以将一个类的对象作为另一个类的成员变量使用。新的类可以是由任意数量和任意类型的其他对象构成。这里涉及到“组合”和“聚合”的概念:

    • 组合(Composition) 经常用来表示“拥有”关系(has-a relationship)。例如,“汽车拥有引擎”。组合关系中,整件拥有部件的生命周期,所以整件删除时,部件一定会跟着删除。实心箭头表示
    • 聚合(Aggregation) 动态的组合。聚合关系中,整件不会拥有部件的生命周期,所以整件删除时,部件不会被删除。空心箭头表示
      组合UML示意图
      新建的类中,成员对象会使用 private 访问权限,这样应用程序员则无法对其直接访问。我们就可以在不影响客户代码的前提下,从容地修改那些成员。也可以在“运行时"改变成员对象从而动态地改变程序的行为,这进一步增大了灵活性。

    在创建新类时首先要考虑“组合”,因为它更简单灵活,而且设计更加清晰。

    6、继承

    “继承”给面向对象编程带来极大的便利。它在概念上允许我们将各式各样的数据和功能封装到一起,这样便可恰当表达“问题空间”的概念,而不用受制于必须使用底层机器语言。

    在创建了一个类之后,即使另一个新类与其具有相似的功能,你还是得重新创建一个新类。但我们若能利用现成的数据类型,对其进行“克隆”,再根据情况进行添加和修改,情况就显得理想多了。“继承”正是针对这个目标而设计的。
    在继承过程中,若原始类(正式名称叫作基类、超类或父类)发生了变化,修改过的“克隆”类(正式名称叫作继承类或者子类)也会反映出这种变化
    继承UML示意图两种类型可以具有共同的特征和行为,但是一种类型可能包含比另一种类型更多的特征,并且还可以处理更多的消息(或者以不同的方式处理它们)。继承通过基类和派生类的概念来表达这种相似性。基类包含派生自它的类型之间共享的所有特征和行为。创建基类以表示思想的核心。从基类中派生出其他类型来表示实现该核心的不同方式。

    继承的类型等价性是理解面向对象编程含义的基本门槛之一。因为基类和派生类都具有相同的基本接口,所以伴随此接口的必定有某些具体实现。也就是说,当对象接收到特定消息时,必须有可执行代码。**如果继承一个类而不做其他任何事,则来自基类接口的方法直接进入派生类。**这意味着派生类和基类不仅具有相同的类型,而且具有相同的行为。

    区分新的派生类与原始的基类:

    • 在派生类中添加新方法。这些新方法不是基类接口的一部分。要仔细考虑是否在基类中也要有这些额外的方法。这种设计的发现与迭代过程在面向对象程序设计中会经常发生。
    • 改变现有基类方法的行为。这被称为覆盖 (overriding),要想覆盖一个方法,只需要在派生类中重新定义这个方法即可。(更重要)

    6.1、“是一个” 与 “像是一个”

    • 是一个(is-a)关系:继承只覆盖基类的方法(不添加基类中没有的方法)
    • 像是一个(is-like-a)关系:在派生类添加了新的接口元素,从而扩展接口。虽然新类型仍然可以替代基类,但是这种替代不完美,原因在于基类无法访问新添加的方法。不能说新旧类型完全相同。

    7、多态

    在处理类的层次结构时,通常把一个对象看成是它所属的基类,而不是把它当成具体类。通过这种方式,我们可以编写出不局限于特定类型的代码。
    这样的代码不会受添加的新类型影响,并且添加新类型是扩展面向对象程序以处理新情况的常用方法。

    这就是关键所在:当程序接收这种消息时,程序员并不想知道哪段代码会被执行。如果不需要知道执行了哪部分代码,那我们就能添加一个新的不同执行方式的子类而不需要更改调用它的方法。

    那么编译器在不确定该执行哪部分代码时是怎么做的呢?

    • 早期绑定:编译器生成对特定函数名的调用,该调用会被解析为将执行的代码的绝对地址。
    • 后期绑定:程序直到运行时才能确定代码的地址。当向对象发送信息时,被调用的代码直到运行时才确定。编译器确保方法存在,并对参数和返回值执行类型检查,但是它不知道要执行的确切代码。

    为了执行后期绑定,Java 使用一个特殊的代码位来代替绝对调用。这段代码使用对象中存储的信息来计算方法主体的地址(此过程在多态性章节中有详细介绍)。因此,每个对象的行为根据特定代码位的内容而不同。

    Java 中,动态绑定是默认行为,不需要额外的关键字来实现多态性。

    void doSomething(Shape shape) {
        shape.erase();
        // ...
        shape.draw();
    }
    
        Circle circle = new Circle();
        Triangle triangle = new Triangle();
        Line line = new Line();
        doSomething(circle);
        doSomething(triangle);
        doSomething(line);
    
    

    在这里插入图片描述
    这种把子类当成其基类来处理的过程叫做“向上转型”(upcasting)。在面向对象的编程里,经常利用这种方法来给程序解耦。

    发送消息给对象时,如果程序不知道接收的具体类型是什么,但最终执行是正确的,这就是对象的“多态性”(Polymorphism)。
    面向对象的程序设计语言是通过“动态绑定”的方式来实现对象的多态性的。

    7.1、单继承结构

    是否所有的类都应该默认从一个基类继承呢?

    单继承的结构使得垃圾收集器的实现更为容易。由于运行期的类型信息会存在于所有对象中,所以我们永远不会遇到判断不了对象类型的情况。这对于系统级操作尤其重要,例如异常处理。同时,这也让我们的编程具有更大的灵活性。

    8、集合

    通常,我们并不知道解决某个具体问题需要的对象数量和持续时间,以及对象的存储方式。那么我们如何知悉程序在运行时需要分配的内存空间呢?

    在面向对象的设计中,问题的解决方案有些过于轻率:创建一个新类型的对象来引用、容纳其他的对象。
    “集合”这种类型的对象可以存储任意类型、数量的其他对象。它能根据需要自动扩容,我们不用关心过程是如何实现的。

    • List,常用于保存序列。List 的两种基本类型:ArrayList 和 LinkedList。在 ArrayList 中随机查找元素是很高效的,在 LinkedList 中插入元素的效率要比在 ArrayList 中高。
    • Map,也称为关联数组,常用于将对象与其他对象关联
    • Set,只能保存非重复的值
    • 队列(Queue)
    • 树(Tree)
    • 栈(Stack)
    • 堆(Heap)

    选择集合有以下两个原因:

    • 集合可以提供不同类型的接口和外部行为。堆栈、队列的应用场景和集合、列表不同,它们中的一种提供的解决方案可能比其他灵活得多。
    • 不同的集合对某些操作有不同的效率。由于底层数据结构的不同,每种集合类型在执行相同的操作时会表现出效率上的差异。

    在 Java 5 泛型出来之前,集合中保存的是通用类型 Object。由于 Java 5 版本前的集合只保存 Object,当我们往集合中添加元素时,元素便向上转型成了 Object,从而丢失自己原有的类型特性。这时我们再从集合中取出该元素时,元素的类型变成了 Object。
    那么我们该怎么将其转回原先具体的类型呢?使用强制类型转换将其转为更具体的类型,这个过程称为对象的“向下转型”。除非我们能确定元素的具体类型信息,否则“向下转型”就是不安全的。另外,每次取出元素都要做额外的“向下转型”对程序和程序员都是一种开销。

    以某种方式创建集合,以确认保存元素的具体类型,减少集合元素“向下转型”的开销和可能出现的错误。这种解决方案就是:参数化类型机制(Parameterized Type Mechanism)。 参数化类型机制,称之为“泛型”(Generic)。

        ArrayList<Shape> shapes = new ArrayList<>();
    

    9、对象创建与生命周期

    关键问题:对象的创建和销毁方式
    每个对象的生存都需要资源,尤其是内存。为了资源的重复利用,当对象不再被使用时,应该及时释放资源,清理内存。

    对象的数据在哪?它的生命周期是怎么被控制的?

    • 将对象放在栈(Stack,有时称为自动变量或作用域变量)或静态存储区域(static storage area)。为了获得最大的运行时速度,程序员可以在编写程序时,通过将对象放在栈(Stack,有时称为自动变量或作用域变量)或静态存储区域(static storage area)中来确定内存占用和生存时间。这些区域的对象会被优先分配内存和释放。这种控制在某些情况下非常有用。在编写代码时,我们必须要弄清楚对象的数量、生存时间还有类型。
    • 在**堆内存(Heap)**中动态地创建对象。在这种方式下,直到程序运行我们才能确定需要创建的对象数量、生存时间和类型。什么时候需要,什么时候在堆内存中创建。因为内存的占用是动态管理的,所以在运行时,在堆内存上开辟空间所需的时间可能比在栈内存上要长(但也不一定)。

    在栈内存开辟和释放空间通常是一条将栈指针向下移动和一条将栈指针向上移动的汇编指令。
    开辟堆内存空间的时间取决于内存机制的设计。
    较之堆内存,在栈内存中创建对象,编译器能够确定该对象的生命周期并自动销毁它;然而如果你在堆内存创建对象的话,编译器是不知道它的生命周期的。

    在 C++ 设计中采用的观点是效率第一,因此它将选择权交给了程序员。在 C++ 中你必须以编程方式确定何时销毁对象,否则可能导致内存泄漏。Java 的内存管理是建立在垃圾收集器上的,它能自动发现对象不再被使用并释放内存。Java 的垃圾收集器被设计用来解决内存释放的问题(虽然这不包括对象清理的其他方面)。垃圾收集器知道对象什么时候不再被使用并且自动释放内存。

    JAVA:单继承,仅在堆中创建数据。
    堆栈概念的区别

    10、异常处理

    异常处理机制将程序错误直接交给编程语言甚至是操作系统。“异常”(Exception)是一个从出错点“抛出”(thrown)后能被特定类型的异常处理程序捕获(catch)的一个对象

    1. 它不会干扰程序的正常运行,仅当程序出错的时候才被执行。这让我们的编码更简单:不用再反复检查错误了。
    2. 异常不像方法返回的错误值和方法设置用来表示发生错误的标志位那样可以被忽略。异常的发生是不会被忽略的,它终究会在某一时刻被处理。
    3. 提供了一种可靠地从错误状况中恢复的方法,使得我们可以编写出更健壮的程序。有时你只要处理好抛出的异常情况并恢复程序的运行即可,无需退出。
    4. Java 语言唯一接受的错误报告方法。

    对象的概念,这些概念是站在“问题空间”的(而不是站在计算机角度的“解决方案空间”)。

    如果你依然选择 Java 作为你的开发语言,希望你至少应该清楚你选择的是什么,以及为什么选择这个方向。

    On Java 8 中文翻译
    英文书籍:《On Java 8》 作者:Bruce Eckel

    展开全文
  • I . K-Means 算法在实际应用中的缺陷 II . K-Means 初始中心点选择不恰当 III . K-Means 优点 与 弊端 IV . 基于密度的聚类方法 V ....VI ....VII . 核心对象 VIII . 直接密度可达 IX . 密度可达 X . 密度连接



    I . K-Means 算法在实际应用中的缺陷



    1 . K-Means 算法中中心点选择是随机的 : 随机地选择聚类分组的中心点 ;


    ① 选择实点 : 可以选择实点 ( 当前现有的样本值 ) 作为聚类中心点 ;

    ② 生成虚点 : 也可以选择生成虚点 ( 任意位置模拟出一个样本点 ) 作为中心点 ;


    2 . 必须事先设置聚类分组个数 K K K 值 : 开始的时候并不知道将数据集分成几组能达到最佳的分组效果 ;


    ① 学习出 K K K 值 : 使用其它聚类方法 , 先将数据集学习一遍 , 确定聚类分组个数 ;

    ② 多次聚类 : 选取不同的 K K K 聚类分组个数 , 然后看取什么值可以达到最好的聚类分组效果 ;


    3 . 最佳实践 : 运行多次 K-Means 方法 , 选取不同的 K K K 值 , 以及不同的聚类分组个数 ;



    II . K-Means 初始中心点选择不恰当



    下面的数据集 , 如果使用肉眼观察 , 选择的中心点是如下绿色的点 , 但是如果随机选择中心点 , 加入选择的很差 , 如下图中的红色点作为中心点 , 那么迭代之后的聚类分组如下图所示 , 明显该聚类分组不是最佳分组 ;


    ① 肉眼观察 3-NN 聚类分组 比较合适的中心点距离 :

    在这里插入图片描述


    ② 随机选择中心点后的聚类分组 : 这是随机选择的分组 , 显然这不是最佳分组 ;
    在这里插入图片描述


    选择的初始的中心点太垃圾 , 会导致多次迭代 , 即使算法收敛 , 多次迭代计算的聚类分组不再改变 , 得到结果也可能是不准确的 ;


    这是基于距离 ( 划分 ) 的聚类方法的固有缺陷 ;



    III . K-Means 优点 与 弊端



    1 . K-Means 好处是 : 简单 , 容易理解 , 性能较高 , 能很快计算出聚类结果 ;


    2 . K-Means 弊端 : 只能找出球形的聚类分组 , 对异常点 和 噪音 非常敏感 , 如果有一个异常点 , 就会导致聚类分组不准确 , 鲁棒性差 ;


    3 . K-Means 无法处理的情况 : 如下面的聚类 , 将不同形状的样本分开 , 需要识别出凹形的模式 , K-Means 无法完成该聚类操作 ;


    在这里插入图片描述



    IV . 基于密度的聚类方法



    1 . 基于密度的聚类方法 :


    ① 方法迭代原理 : 相邻区域的密度 , 即 单位空间内 数据样本 点的个数 , 超过用户定义的某个阈值 , 那么该区域需要进行聚类 , 如果低于某个阈值 , 聚类停止 , 算法终止 ;

    ② 聚类分组前提 : 如果想要将多个 数据样本 划分到一个聚类分组中 , 那么这些样本的分布必须达到一定的密度 , 即在某个范围大小区域内 , 该样本点必须达到一定的数目 ; 具体的数量个数 根据空间大小 , 和 密度计算出来 ;


    2 . 示例 : 如 , 先定义好 , 如果进行聚类 , 必须在 1 × 1 1 \times 1 1×1 平面内至少有 16 16 16 个样本 , 给定一个区域内的点 , 如果该区域的样本密度值大于 16 16 16 , 就划分到一个聚类中 ; 如果该区域是 0.5 × 0.5 0.5\times 0.5 0.5×0.5 大小 , 那么只需要有 4 4 4 个就能进行聚类 , 如果这个区域是 2 × 2 2 \times 2 2×2 , 必须有 64 64 64 个样本才能聚类成一组 ;


    3 . 基于密度聚类好处 : 该方法可以排除 异常点 , 噪音数据 , 鲁棒性很好 ;


    4 . 基于密度的聚类方法涉及到的参数 : 密度阈值 , 聚类区域范围 ;



    V . 基于密度的聚类方法 DBSCAN 方法



    DBSCAN 方法 :


    ① 全称 : Density Based Spatial Clustering of Application with Noise , 基于密度兼容噪音的空间聚类应用 算法 ;

    ② 聚类分组原理 : 数据样本 p p p q q q 存在 密度连接 关系 , 那么 p p p q q q 这两个样本应该划分到同一个聚类中 ;

    ③ 噪音识别原理 : 数据样本 n n n 与 任何样本 不存在 密度连接 关系 , 那么 n n n样本 就是噪音数据 ;



    VI . ε \varepsilon ε-邻域



    1 . ε \varepsilon ε-邻域 : 这是一个范围定义 , 给定一个数据样本对象 , 以该样本为中心 , 指定一个半径 ε \varepsilon ε , 形成一个范围区域 , 组成了该样本的 ε \varepsilon ε-邻域 ;


    2 . ε \varepsilon ε-邻域示例 : 如果是二维平面该范围区域是一个圆 , 如果是三维平该范围区域是一个球 ;


    3 . ε \varepsilon ε-邻域图示 : 下面的红点就是样本点 , 以红点为圆心 , 以 ε \varepsilon ε 为半径的 浅绿色区域 , 就是 ε \varepsilon ε-邻域 ;

    在这里插入图片描述



    VII . 核心对象



    1 . 核心对象 : 在一个样本对象 C C C ε \varepsilon ε-邻域 中 , 有超过一定 阈值 ( 最小数量 ) 的 样本对象分布 , 那么该样本对象 C C C 就是核心对象 ;


    2 . 核心对象 图示 : 如果该阈值 ( 最小数量 ) 设置成 5 5 5 , 那么该 ε \varepsilon ε-邻域 中有 6 6 6 个点 , 超过了最小阈值 , 红色 的 中心点 数据样本 是 核心对象 ;
    在这里插入图片描述



    VIII . 直接密度可达



    1 . 直接密度可达 : Directly Density Reachable ( DDR ) ;


    ① 概念 : 样本 p p p 是核心对象 ( 以 p p p 为中心 ε \varepsilon ε-邻域 中超过阈值个数的样本 ) , 样本 q q q 在其 ε \varepsilon ε-邻域 中 , 那么 称为 p p p 直接密度可达 q q q ; 注意方向 p → q p \rightarrow q pq , p p p 出发直接密度可达 q q q ;

    ② 直接密度可达有两个条件 : ① 起点必须是核心对象 , ② 终点必须在起点的 ε \varepsilon ε-邻域 中 ;


    2 . 直接密度可达的注意点 :


    ① 单向概念 : 注意该概念是单向的概念 , p p p 样本出发 , 可以 直接密度可达 q q q , 反过来是不行的 ; q q q 出发不一定能到 p p p ;

    ② 直接密度可达 起点 : 只有 核心对象 才有资格 发起密度可达 概念 , 不是核心对象 , 没有资格作为起点 ;

    ③ 直接密度可达 性质 : 如果 p p p 是核心对象 , 那么从 p p p 出发 , 可以直接密度可达其 ε \varepsilon ε-邻域 中所有的样本点 ;

    ④ 如果 p p p 不是核心对象 , 那么没有直接密度可达的概念 ;


    3 . 图示 : 红色点 p p p 是核心对象 , q q q 在其 ε \varepsilon ε-邻域 中 , p p p 直接密度可达 q q q ;

    在这里插入图片描述



    IX . 密度可达



    1 . 密度可达 : p p p 密度可达 q q q , 存在一个 由 核心对象 组成的链 , p p p 直接密度可达 p 1 p_1 p1 , p 1 p_1 p1 直接密度可达 p 2 p_2 p2 , ⋯ \cdots , p n − 1 p_{n-1} pn1 直接密度可达 p n p_n pn , 此时称为 p p p 密度可达 q q q ;


    2 . 链 上的核心对象要求 : 链的起点 , 和经过的点 , 必须是核心对象 , 链的最后一个点 , 可以是任意对象 ;


    3 . 密度可达 与 直接密度可达区别 : 密度可达 与 直接密度可达 的概念在于 是直接可达 , 还是 间接可达 ;


    4 . 密度可达图示 : p p p 直接密度可达 q q q , q q q 直接密度可达 t t t , p p p 密度可达 t t t ;

    在这里插入图片描述



    X . 密度连接



    1 . 密度连接 : p p p q q q 两个样本 , 存在一个中间样本对象 O O O , O O O p p p密度可达 的 , O O O q q q密度可达 的 ;


    2 . 密度连接方向 : O O O 可以密度连接 p p p q q q 样本 , 但是 p p p q q q 不一定能走到 O O O , 它们可能不是核心对象 ;


    3 . 核心对象要求 : O O O 以及到 样本 p p p 或者 样本 q q q 中间的样本都必须是核心对象 , 但是 p p p q q q 两个对象不要求是核心对象, 它们可以是普通的样本点 ;


    4 . 密度连接图示 : 下图中 , 样本点 O O O 密度可达 p p p q q q , 那么 p p p q q q 是密度连接的 ; 其中 p , q p, q p,q 不是核心对象 , O , p 1 , p 2 , q 1 , q 2 O , p_1 , p_2 , q_1 , q_2 O,p1,p2,q1,q2 是核心对象 ;

    在这里插入图片描述

    展开全文
  • 什么是IPC对象 IPC:inter-process communication,进程间通信对象;包括如下组件: 管道通信 :FIFO,PIPE,流式数据 消息队列:message queue 信号量:semaphore 共享内存:share memory … IPC分类 System V IPC ...

    什么是IPC对象

    IPC:inter-process communication,进程间通信对象;包括如下组件:

    • 管道通信 :FIFO,PIPE,流式数据
    • 消息队列:message queue
    • 信号量:semaphore
    • 共享内存:share memory

    IPC分类

    System V IPC

    当前系统调用版本主要是类unix和linux操作系统之中包含,它是在linux操作系统出现之前发布的标准

    • 消息队列:system V message queue
    • 信号量:system V semphore
    • 共享内存:system V share memory

    POSIX IPC

    该版本为linux操作系统发布的系统调用接口标准,同时该标准还兼容了system V 的标准

    • 消息队列:POSIX message queue
    • 信号量:POSIX semphore
    • 共享内存:POSIX share memory

    IPC对象的基本概念

    -支持不同的进程通过ipc对象通信,IPC对象是存储在内核之中,且全局可见。

    • 每个IPC对象在内核之中有自己的数据结构,定义在各自头文件
    • 如何引用IPC对象
      类似于普通文件是通过文件名(文件描述符)进行读写操作,通过IPC对象:IPC key和 IPC标识符进行IPC对象的读写操作。

    IPC标识符

    • 类似于文件描述符,可以用一个IPC标示符来引用一个IPC对象
    • IPC对象描述符类似于文件描述符,是一个整数,是IPC对象的内部名字
    • 当多个进程引用同一个IPC对象时,需要一个统一的外部名
    • 类似于文件名,每个IPC对象与一个key相关联

    IPC key

    IPC key,ipc对象的外部名,是一个独一无二的整数,用来确保ipc对象的唯一性

    • 该整数类型为key_t,在sys/types.h中被定义为长整型
    • 普通文件是通过open打开一个文件名,获得文件描述符;IPC队形是通过get可根据给定的key 去创建一个IPC对象,并返回IPC标识符
    IPC key的创建方法
    • 随机选取一个整数作为key值
      所有整数放到一个头文件,使用IPC对象的程序包含这个头文件
      一般随机取整数用在自己电脑上,如果是服务器,多用户并发使用则又可能冲突。
    • 在get系统调用中将IPC_PRIVATE常量作为key值
      每个调用都会创建一个全新的IPC对象,保证来每个对象拥有唯一的key
    • 使用ftok系统调用生成一个接近唯一的key

    IPC对象的引用

    使用的基本流程

    • 通过get系统调用创建或打开一个IPC对象
      给定一个整数key,get调用会返回一个整数标识,即IPC标识符

    • 通过这个标识符来引用IPC对象并进行各种操作

    • 通过ctl系统调用获或设置IPC对象的属性、或者删除一个对象

    • IPC对象具有的权限定义在ipc.h头文件中

      下表为system V 各个IPC对象之间的差异

      接口消息队列信号量共享内存
      头文件<sys/msg.h><sys/sem.h><sys/shm.h>
      关联数据结构msqid_dssemid_dsshmid_ds
      创建/打开对象msgget()semget()shmget()+shmat()
      关闭对象(无)(无)shmdt()
      控制操作msgctl()semctl()shmctl()
      执行IPCmsgsnd()—写入消息semop()—测试/调整信号量访问共享区中的内存

    POSIX 和 system V 的对比

    • 编程接口: POSIX接口更简单,使用类似于文件IO的open,write,unlink等;system V接口则比较复杂,不同等ipc对象实际操作都不一样,msgsnd,msgrcv,shmat,shmdt,semop等
      同时POSIX 接口支持异步通信方式,而system V 的通信只能是以阻塞式消耗CPU资源进行通信
    • ipc对象命名:POSIX使用名字来标识IPC对象,system V使用键来管理。
    • 移植性:system V拥有更优的移植性,几乎所有的unix/linux系统都支持system V;POSIX仅仅是unix系统中的一个可选组件,有一些unix系统并不支持,同时linux 2.6之后的系统才开始支持POSIX

    POSIX 编程注意事项

    • 使用POSIX 消息队列和共享内存时,需要实时库librt的链接,编译时需要指定-lrt
    • 使用POSIX 信号量时,需要和线程库 libpthread链接起来,编译时需要指定lpthread
    展开全文
  • DDD-领域对象与领域服务

    千次阅读 2019-02-20 21:31:05
    什么是领域对象 什么是领域服务 领域对象的行为,与领域服务的行为区别 原因 为什么把这么小的点拿出来讲,最开始在讨论中领域对象与领域服务时,觉得行为放在service/entity中区别不大,只是一个放置位置的问题,...

    问题

    1. 什么是领域对象
    2. 什么是领域服务
    3. 领域对象的行为,与领域服务的行为区别

    原因

    为什么把这么小的点拿出来讲,最开始在讨论中领域对象与领域服务时,觉得行为放在service/entity中区别不大,只是一个放置位置的问题,并不影响到代码的抽象和复用,所以没有实行。但是最近在推动产品进行DDD业务建模,发现这个问题非常重要,关系到代码是否清晰表达了业务,这个也是我们进行DDD的初衷。

    定义

    领域对象
    聚合根,实体,值对象
    领域的数据与行为,
    数据和行为应该与业务产品上的行为关联。领域对象通常是有状态的,理想情况下,我们的领域对象行为应该和产品业务定义意义映射

    几个阻抗

    • 觉得行为放在领域服务还是领域对象中区别不大,只是一个放置位置的问题,并不影响到代码的抽象和复用
    • 领域对象中还是只有属性,和对象之间的转换
    • 业务逻辑没有与代码映射
    • manager(持久化操作)放在领域对象中需要进行一个转换(ApplicationContext)或者其他方式
    • 我们的业务很单薄,放在领域对象中的内容后,领域服务就很单薄了。滥用了领域服务导致了领域对象的贫血
    • 领域对象的集合操作

    观点

    首先需要对概念明确定义,因为DDD其实是做了一个问题的分治,所以必然会导致在某些情况下,会有单薄这个说法。就像垂直架构中dao/manager/service层区分一样。在初期我们可以明确按照概念来放置代码,当大家达成共识,深刻理解了这些概念时,没有其中一层也无所谓了。

    举个例子
    eg. 一个bad case
    三个模型:A,B,C,他们之间存在状态变更流动。

    整理出来的状态变更图
    在这里插入图片描述
    AService.updateXXStatus

    AService.cancelBy

    AService.changeStatus()

    这些方法都在处理状态,反应不了业务的情况

    领域对象:

    一般包含以下逻辑

    • 领域对象的限制

      // 如什么样的设计师是不存在的,对于领域外的内容不关心你是不是软删,还是硬删

      public  void checkDesignerExist() throws BizzException {
            // 清退的也是不存在的
            if (this == null || this.getStatus().equals(DesignerStatusEnum.DELETE)) {
                throw DdgCoreResponseCode.convertBizzException(DdgCoreResponseCode.DESIGNER_NOT_EXIST);
            }
        }
      
    • 领域行为与事件
      // 如商品对象的删除,以及事件的publish(不限于CRUD)
      // 抽奖业务中从奖池中选取奖品

        public RoulettePrize executeRoulette(final List<RoulettePrize> prizes,
                    final Integer dailyFreeRouletteCount,
                    final int rouletteCountToday, final UserDTO userDTO) throws BizzException {
                final List<RoulettePrize> validPrize =  prizes.stream().filter(p -> checkPrizeValid(p))
                        // 排除掉中奖概率不合法和概率为0的奖品
                        .filter(p -> ArithUtil.checkIntegerRange(p.getRate(), 0, Integer.MAX_VALUE))
                        // 校验中奖次数限制
                        .filter(p -> checkPrizeLimit(p))
                        // 校验vip奖品限制
                        .filter(p -> checkPrizeVip(p, userDTO))
                        .filter(p -> checkFreePrize(p,dailyFreeRouletteCount, rouletteCountToday)).collect(
                                Collectors.toList());
                final int totalRate = validPrize.stream().mapToInt(p -> p.getRate()).sum();
                // 排除无效奖品,计算有效奖品概率之和
                if (CollectionUtils.isEmpty(validPrize)) {
                    throw RouletteResponseCode.convertBizzException(RouletteResponseCode.PRIZE_EMPTY);
                }
                return chooseResultPrize(validPrize, totalRate == 0 ? 1 : totalRate);
            }
      
    • 状态的流转

    不应该做的事

    领域对象不应该与其他的模型有交互,如manager(资源层管理),不应该持久化数据
    如何持久化不应该是领域对象关心的。

    领域服务

    • 构造(复杂的)领域对象
      调用防腐层方法,做支撑域和通用域对象的转换与组合

    • 与dao层打交道

    • 调用其他限界上下文的内容

    • 提供领域方法给其他限界上下文/应用程序调用

    领域服务与领域对象的关系

    领域服务通常是领域对象的调用方,是微服务架构下,领域对象对外提供的方式。

    AService

       // 构建领域对象
        final List<AAggr> aggr = mAManager.listByUserIds(userVal);
        final AEntity entity = CollectionUtils.isEmpty(aggr) ? null : aggr.get(0)
                .getA();	
       // 调用领域对象方法
        entity.checkDesignerExist();
        entity.checkUpdate();
    

    在这里插入图片描述

    展开全文
  • 面向对象分析与设计1

    2009-07-07 22:18:51
    国外计算机科学经典教材-面向对象分析与设计(UML 2.0版) 简介:本书详细介绍了面向对象的分析与设计,全面探讨了面向对象概念、软件开发过程、UML和多层技术。 本书使用最常见的技术和方法,通过一个贯穿全书的...
  • 【知识图谱】知识图谱的基础概念与构建流程

    千次阅读 多人点赞 2019-11-09 18:46:49
    概念主要指集合、类别、对象类型、事物的种类,例如人物、地理等。 内容: 通常作为实体和语义类的名字、描述、解释等,可以由文本、图像、音视频等来表达。 属性(值): 从一个实体指向它的属性值。不同的属性...
  • 1、概念 是动态HTML,将网页实现动态化 作用: -动态概念页面元素 -与用户进行交互 -对象模型分为BOM和DOM DHTML = HTML + CSS + js 2、BOM和DOM BOM:浏览器对象模型,用来访问和操作浏览器窗口,使js有能力与...
  • 数据库建模-概念模型建模(E-R图)

    千次阅读 2019-11-16 22:06:02
    目录数据库建模-概念模型建立面向对象模型与数据库关系模型两种模型的关系中间件概念数据模型(CDM)实体及属性实体属性联系一对一双向关系一对一单向关系一对多(等效多对一)多对多域(Domain )PowerDesigner建立概念...
  • 聊一聊分布式对象存储

    千次阅读 2018-11-12 15:20:41
    今天来聊聊我正在读的一本分布式对象存储的书籍。 前天11月10号,想着京东有满200-100的活动,就买了一些书,准备沉淀一下。自己打算在分布式系统上搞几年,所以买的书基本上都是关于分布式存储的。本身也没想着买...
  • 基于Chopra解决逆转现象的方法提出了最优目标控制参数概念,阐述了最优目标控制参数的理论意义和选取原则.以某上海长江大桥高桩承台体系为研究对象,实施了选取最优目标控制参数分析过程,并对该高桩承台体系进行...
  • 面向对象的开发方法(总结)

    万次阅读 2016-05-04 16:39:22
    面向对象分为面向对象的分析(OOA),面向对象的设计(OOD)和面向对象的程序设计(OOP)。 OOA的是利用抽象构造问题的对象模型 OOD是设计对象对象之间的关系,如层次和集成;对象之间的通信方式,例如消息。对...
  • 对C++面向对象的编程的理解

    千次阅读 2019-01-16 18:05:06
    本节主要介绍面向对象方法的优点以及它的一些基本概念。 2.3.1面向对象方法的优点(1)与人类习惯的思维方法一致。 长期以来,人与计算机之间仍存在着较大的隔阂,人认识问题时的认识空间和计算机处理问题时的方法...
  • 深度学习之候选框的选取

    千次阅读 2020-02-08 17:56:53
    ,该边界框对应于图像中最有可能是对象的所有 patches 。这些 BoundingBox 可能存在噪声、重叠,也可能偏离了目标,但是大多数候选区域应该与图像中的目标非常接近。这样,我们在后面直接对这些 BoundingBox 进行...
  • 最优参数选取

    千次阅读 2018-07-25 17:23:23
    首先先说一个概念,叫做奇异样本数据,所谓奇异样本数据数据指的是相对于其他输入样本特别大或特别小的样本矢量。下面举例: m=[0.11 0.15 0.32 0.45 30;  0.13 0.24 0.27 0.25 45]; 其中的第五列数据相对于其他...
  • 面向对象复习总结

    千次阅读 2016-12-07 21:11:27
    面向对象基本概念和原理 UML( UnifiedModeling Language )基础 面向对象设计原则 面向对象设计模式 什么是面向对象 面向对象的方法是一种分析方法、设计方法和思维方法。 面向对象方法学的出发...
  • 字节码解释器工作时就是通过改变这个计数器的值来选取下一条需要执行的字节码指令,分支、循环、跳转、异常处理、线程恢复登记处功能都需要依赖这个计数器的值来完成。 为了线程切换后能恢复到正确的执行位置,每个...
  • 面向对象软件测试综述

    千次阅读 2016-02-04 10:30:42
    面向对象软件测试综述 摘要:面向对象的软件测试是面向对象软件开发的不可缺少的一环,是保证软件质量、提高软件可靠性的关键。结合传统软件测试的方法和技术,并针对面向对象软件所具有的特征,将面向对象软件测试...
  • 目标检测有大量的算法,这篇文章对其中正负样本的选取方法进行了总结。对于正样本,是回归与分类都进行,而负样本由于没有回归的对象,不进行回归,只进行分类(分类为背景)。 二、正文 1.Fast R-CNN 构造如下:...
  • OpenStack对象存储(Swift)要领(译)-目录

    千次阅读 2017-01-22 14:54:35
    简化的TCO无限的可扩展性可扩展的按需分配通用访问多租户模式数据耐久性和可用性云存储的局限性能新的API对象存储开源的重要性OpenStack Swift总结第二章:OpenStack Swift体系结构对象的逻辑结构Swift的实现和架构...
  • 多媒体技术基本概念汇总

    千次阅读 2015-07-28 00:05:20
    下面的资料是我在大学阶段整理的多媒体技术的基本概念,希望对大家有所帮助。 多媒体技术期末知识点汇总 多媒体技术的主要特性有:(1)(2)(3) //该题可以为选择题、填空题、简答题 多样性 集成性 交互性 可...
  • 面向对象需求分析方法实践

    万次阅读 多人点赞 2016-11-17 17:03:05
     目前原型设计工具以Axure为主流,但原型工具归根结底还是工具,关键还是使用的人,因此根据个人习惯选取即可,不用太纠结。但是在开展原型设计之前更建议使用纸和笔先构思功能原型及交互,再通过工具实现,因为...
  • JavaScript基础之对象与内置对象(三)

    千次阅读 多人点赞 2021-07-30 16:07:54
    在 JavaScript 中,对象是一组无序的相关属性和方法的集合,所有的事物都是对象,例如字符串、数值、数组、函数等。 对象是由属性和方法组成的: 属性:事物的特征,在对象中用属性来表示(常用名词) 方法:事物的...
  • 机器学习基本概念: 3.1回归: 经过算法预测的结果是一个连续的值,我们称这样的问题为回归问题。 从数学上看,回归的本质是数据拟合。 3.2 低拟合与过拟合: 第一个模型是一个线性模型,低度拟合,不能很好地适应...
  • python数据分析——数据查看与选取(一)

    万次阅读 多人点赞 2018-08-08 21:49:33
    前面已经讲了如何用pandas导入数据,这篇文章就来讲一些常用的数据查看、数据选取。做到了这一步,就可以进行一些快速的描述性分析了! 要查看数据与选取数据,我们首先得了解python里数据存储的方式,然后才能...
  • 本章主要讲解聚类的基本概念和方法对聚类的浅要分析聚类是什么意思,很好理解,这里不说了。 需要注意的是一下这几点 1、在相同的数据集上,不同的聚类方法可能产生不同的聚类 。 2、聚类可以作为其他算法的...
  • JVM之内存和对象创建过程

    千次阅读 2018-08-29 14:32:10
    1.5.3多核并行 Lambda支持会极大改善目前Java语言不适合函数式编程的现状.函数式编程的一个重要...字节码解释器工作时就是通过改变这个计数器的值来选取下一条需要执行的字节码指令,分支 循环 跳转 异常处理 线...
  • Range对象

    千次阅读 2016-09-29 09:43:37
    一、Range对象属性 属性值 说明 Range.collapsed 用于判断Range对象所代表的区域的开始点与结束点是否处于相同的位置,如果相同该属性值返回true Range.commonAncestorContainer 用于返回Range对象所代表的区域...
  • 第三章 概念模型设计(一)

    千次阅读 2020-04-16 23:01:55
    面向对象:这种方法采用面向对象概念,构造对象模型,再将对象模型转换为数据库结构。目前,面向对象的数据库管理系统尚无成熟的产品。 二,数据库设计的基本步骤 1.需求分析阶段 需求分析阶段的任务是通过详细的...
  • HTML5——Range对象(1)

    千次阅读 2016-05-04 09:41:36
    2016-04-27 15:22:55 星期三 1、Range对象 (1)selectNode、SelectNodeContents、deleteContents方法 setStart、setEND、setStartBefore、...(2)基本概念:一个Range对象代表页面上的一段连续区域。通过Rang

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 61,652
精华内容 24,660
关键字:

对象选取概念