zoukankan      html  css  js  c++  java
  • java面试(五)

    1  六大原则

    详情参考:设计模式六大原则(转载)。

    2  UML类之间关系有几种?聚合和组合区别?

      类之间可能存在以下几种关系:关联(association)、依赖(dependency)、聚合(Aggregation,也有的称聚集)、组合(Composition)、泛化(generalization,也有的称继承)、实现(Realization)。

      关联是指两个类之间存在某种特定的对应关系,例如客户和订单,一个订单只能属于某个客户,一个客户可能会有多张订单。根据方向,分为单向和双向。根据对应的数量分为一对一、一对多、多对多等。对应的UML图如下所示:

    class Customer {
      private Integer id;
      private String name;
      private Set<Order> orders;
      public Set<Order> getOrders() {
       return orders;
      }
      public void setOrders(Set<Order> orders) {
       this.orders = orders;
      }
     }
     class Order {
      private Integer id;
      private float money;
      private Customer customer;
      public Customer getCustomer() {
       return customer;
      }
      public void setCustomer(Customer customer) {
       this.customer = customer;
      }
     }

    Customer和Order是双向一对多关联关系,那么在Customer中应该有Order的集合,在Order中应该Customer的属性。

      依赖指的是类之间的调用关系。类A访问类B的属性或方法,或者类A负责实例化类B,那么就说类A依赖于类B。和关联关系不同的是,无需在类A中定义类B类型的属性。例如自行车和打气筒,自行车通过打气筒来充气,那么就需要调用打气筒的充气方法。对应的UML图如下所示:

    依赖关系用虚线+箭头表示。上图显示Bicycle和Pump是依赖关系,Bicycle依赖于Pump。对应的Java代码如下所示:

    class Bicycle {
      public void expand(Pump pump) {
       pump.blow();
      }
     }
     class Pump {
      public void blow() {
       System.out.println("正在充气......");
      }
     }

      打气筒并不属于某个特定的自行车,一个打气筒可以为多个自行车提供充气的服务。在Bicycle中不需要定义Pump类型的属性,而是将传递了一个Pump类型的参数到Bicycle的方法中。

      聚合是整体与部分之间的关系。例如计算机和主板,计算机是一个整体,主板是其中的一部分,主板、显卡、显示器等部件组成了计算机。对应的UML图如下所示:

    聚合使用空心菱形+实线表示。上图显示Computer是由MainBoard和DisplayCard等组成的。对应的Java代码如下所示:

    class Computer {
      private MainBoard mainBoard;
      private DisplayCard displayCard;
      
      public void on() {
       System.out.println("开启计算机......");
      }
      public void close() {
       System.out.println("关闭计算机......");
      }
      public void run() {
       System.out.println("计算机正在运行......");
      }
     }
     class MainBoard {
      public void control() {
       System.out.println("控制计算机......");
      }
     }
     class DisplayCard {
      public void display() {
       System.out.println("计算显示数据......");
      }
     }
      计算机由主板、显卡等部件组成,所以在Computer中定义了MainBoard和DisplayCard类型的属性。
      聚合中类之间可以独立出来,比如一块主板可以状态A计算机上,也可以装在B计算机上。也就是说这块主板离开A计算机之后仍然是有意义的。
      组合中的类也是整体与部分的关系,与聚合不同的而是,其中的类不能对立出来。例如一个人由头、手、腿和躯干等组成,如果这个头离开了这个人,那么这个头就没有任何意义了。对应的UML图如下所示:

    组合使用实心菱形和实线表示。上图表示People是由Head、Hand、Leg等组成。对应的Java代码如下所示:

    class People {
      private Head head;
      private Hand hand;
      private Leg leg;
      public void think() {
       head.think();
      }
      public void holdThing() {
       hand.holdThing();
      }
      public void walk() {
       leg.walk();
      }
     }
     class Head {
      public void think() {
       System.out.println("思考......");
      }
     }
     class Hand {
      public void holdThing() {
       System.out.println("拿东西......");
      }
     }
     class Leg {
      public void walk() {
       System.out.println("走路......");
      }
     }

    People和Head、Hand、Leg是不可分割的,Head、Hand、Leg离开了People没有任何实际意义。在People中定义了Head、Hand、Leg类型的属性,组合也可以看成是聚合的一种特殊形式。

      聚合和组合的代码几乎相同,单凭代码是无法区分两个类之间是聚合还是组合的关系的。所以就需要结合实际的业务环境来区分。例如汽车和轮胎,车主买了一辆汽车,上边肯定是由轮胎的,在这个业务中,轮胎和汽车是组合关系,它们分开就没有实际意义了。在汽车修理店,汽车可以更换轮胎,所以在汽修店的业务环境中,汽车和轮胎就是聚合的关系,轮胎离开汽车是有业务意义的。

      泛化比较好理解,就是两个类之间具有继承关系。例如人和学生,学生继承了人,除过具有人的一般的属性和方法之外,他还要有学习的方法。对应的UML图如下所示:

     泛化用空心三角形+实线表示。上图表示Student继承People。对应的Java代码如下所示:

    class People {
      protected String name;
      protected String sex;
      protected Date birthday;
      public void eat() {
       System.out.println(name + "正在吃饭......");
      }
      public void drink() {
       System.out.println(name + "正在喝水......");
      }
      public void sleep() {
       System.out.println(name + "正在休息......");
      }
     }
     class Student extends People {
      public void study() {
       System.out.println(name + "正在学习......");
      }
     }

    实现即一个类实现了某个接口。对应的UML图如下所示:

       实现用三角形箭头和虚线表示。上图表示类CarDriver和PlaneDriver都实现了Driver接口。对应的Java代码如下所示:

    public interface Driver {
     void drive();
    }
     class CarDriver implements Driver {
      public void drive() {
       System.out.println("驾驶汽车......");
      }
     }
     class PlaneDriver implements Driver {
      public void drive() {
       System.out.println("驾驶飞机......");
      }
     }
      值得注意的是,关联、依赖、聚合、组合的关系很容易搞混。当对象A和对象B之间存在关联、依赖、聚合或者组合关系时,对象A都有可能调用对象B的方法。这是它们的相同之处。另外它们还有自己的特征:
      对于两个相对独立的对象A和B,当一个对象A的实例与B的实例存在固定的对应关系时,这两个对象之间为关联关系。代码中表现为在A中定义了B类型的属性。
      对于两个相对独立的对象A和B,当一个对象A负责构造对象B的实例,或者调用对象B提供的服务时,这两个对象之间主要体现为依赖关系。代码中的表现即将B类型的参数传入A的方法中,而不是在A中定义B类型的属性。
      聚合、组合与关联在代码中并没有明显的区别,主要看实际的业务环境,根据代码所处的实际业务环境来判断它们之间的关系。同样的两个类,处在不同的业务环境中,可能它们的关系也不相同。
     
      聚合:他们可以具有各自的生命周期,部分可以属于多个整体对象,也可以为多个整体对象共享。
      组合:他同样体现整体与部分间的关系,但此时整体与部分是不可分的,整体的生命周期结束也就意味着部分的生命周期结束。
      组合跟聚合几乎相同,唯一的区别就是“部分”不能脱离“整体”单独存在,就是说, “部分”的生命期不能比“整体”还要长。

    3 AOP原理

    4 事物隔离级别

    5 ORM如何实现事物

    6 线程池源码

    7 类加载过程

    12 jvm classloder

    13 ORM 事务实现, 事务隔离级别

    14 lambda表达式原理。

    15 JAVA 1.8 新特性

  • 相关阅读:
    leetcode701. Insert into a Binary Search Tree
    leetcode 958. Check Completeness of a Binary Tree 判断是否是完全二叉树 、222. Count Complete Tree Nodes
    leetcode 110. Balanced Binary Tree
    leetcode 104. Maximum Depth of Binary Tree 111. Minimum Depth of Binary Tree
    二叉树
    leetcode 124. Binary Tree Maximum Path Sum 、543. Diameter of Binary Tree(直径)
    5. Longest Palindromic Substring
    128. Longest Consecutive Sequence
    Mac OS下Android Studio的Java not found问题,androidfound
    安卓 AsyncHttpClient
  • 原文地址:https://www.cnblogs.com/liufei1983/p/7228344.html
Copyright © 2011-2022 走看看