面向对象设计原则(了解)线程和线程池

本文深入探讨了面向对象设计的六大原则:单一职责原则、开闭原则、里氏替换原则、依赖注入原则、接口分离原则和迪米特原则。同时,介绍了设计模式的概念,如创建型模式、结构型模式和行为型模式,以及常见的设计模式如工厂模式、单例模式等。强调了设计模式在软件开发中的重要性,以提高代码的可复用性和可维护性。此外,还讨论了线程安全、多线程实现方式、线程池和Java中的等待唤醒机制等并发编程相关知识点。
面向对象思想设计原则
在实际的开发中,我们要想更深入的了解面向对象思想,就必须熟悉前人总结过的面向对象的思想的设计原则
单一职责原则
开闭原则
里氏替换原则
依赖注入原则
接口分离原则
迪米特原则
1 单一职责原则:
其实就是开发人员经常说的高内聚,低耦合
也就是说,每个类应该只有一个职责,对外只能提供一种功能,而引起类变化的原因应该只有一个。在设计模式中,所
有的设计模式都遵循这一原则

开闭原则

核心思想是:一个对象对扩展开放,对修改关闭。
其实开闭原则的意思就是:对类的改动是通过增加代码进行的,而不是修改现有代码。
也就是说软件开发人员一旦写出了可以运行的代码,就不应该去改动它,而是要保证它能一直运行下去,如何能够做到
这一点呢?这就需要借助于抽象和多态,即把可能变化的内容抽象出来,从而使抽象的部分是相对稳定的,而具体的实现则
是可以改变和扩展的。
里氏替换原则
核心思想:在任何父类出现的地方都可以用它的子类来替代。
其实就是说:同一个继承体系中的对象应该有共同的行为特征。
依赖注入原则
核心思想:要依赖于抽象,不要依赖于具体实现。
其实就是说:在应用程序中,所有的类如果使用或依赖于其他的类,则应该依赖这些其他类的抽象类,而不是这些其他
类的具体类。为了实现这一原则,就要求我们在编程的时候针对抽象类或者接口编程,而不是针对具体实现编程。
接口分离原则
核心思想:不应该强迫程序依赖它们不需要使用的方法。
其实就是说:一个接口不需要提供太多的行为,一个接口应该只提供一种对外的功能,不应该把所有的操作都封装到一
个接口中。
迪米特原则
核心思想:一个对象应当对其他对象尽可能少的了解
其实就是说:降低各个对象之间的耦合,提高系统的可维护性。在模块之间应该只通过接口编程,而不理会模块的内部
工作原理,它可以使各个模块耦合度降到最低,促进软件的复用
设计模式概述
设计模式(Design pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式
是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。
设计模式不是一种方法和技术,而是一种思想
设计模式和具体的语言无关,学习设计模式就是要建立面向对象的思想,尽可能的面向接口编程,低耦合,高内聚,使设
计的程序可复用
学习设计模式能够促进对面向对象思想的理解,反之亦然。它们相辅相成
设计模式的几个要素
名字 必须有一个简单,有意义的名字
问题 描述在何时使用模式
解决方案 描述设计的组成部分以及如何解决问题
效果 描述模式的效果以及优缺点
设计模式的分类
创建型模式 对象的创建
结构型模式 对象的组成(结构)
行为型模式 对象的行为
创建型模式:简单工厂模式,工厂方法模式,抽象工厂模式,建造者模式,原型模式,单例模式。(6)
结构型模式:外观模式、适配器模式、代理模式、装饰模式、桥接模式、组合模式、享元模式。(7)\
行为型模式:模版方法模式、观察者模式、状态模式、职责链模式、命令模式、访问者模式、策略模式、备
忘录模式、迭代器模式、解释器模式。(10)
简单工厂模式概述
又叫静态工厂方法模式,它定义一个具体的工厂类负责创建一些类的实例
优点
客户端不需要在负责对象的创建,从而明确了各个类的职责
缺点
这个静态工厂类负责所有对象的创建,如果有新的对象增加,或者某些对象的创建方式不同,就需要不断的修改工厂
类,不利于后期的维护
工厂方法模式概述
工厂方法模式中抽象工厂类负责定义创建对象的接口,具体对象的创建工作由继承抽象工厂的具体类实现。
优点
客户端不需要在负责对象的创建,从而明确了各个类的职责,如果有新的对象增加,只需要增加一个具体的类和具体的
工厂类即可,不影响已有的代码,后期维护容易,增强了系统的扩展性
缺点
需要额外的编写代码,增加了工作量
单例设计模式概述
单例模式就是要确保类在内存中只有一个对象,该实例必须自动创建,并且对外提供。
优点
在系统内存中只存在一个对象,因此可以节约系统资源,对于一些需要频繁创建和销毁的对象单例模式无疑可以提高系
统的性能。
缺点
没有抽象层,因此扩展很难。
职责过重,在一定程序上违背了单一职责
* 如何保证类在内存中只有一个对象呢?
* A:把构造方法私有
* B:在成员位置自己创建一个对象
* C:通过一个公共的方法提供访问
* 单例模式:
* 饿汉式:类一加载就创建对象
* 懒汉式:用的时候,才去创建对象
*
* 面试题:单例模式的思想是什么?请写一个代码体现。
*
* 开发:饿汉式(是不会出问题的单例模式)
* 面试:懒汉式(可能会出问题的单例模式)
* A:懒加载(延迟加载)
* B:线程安全问题
* a:是否多线程环境 是
* b:是否有共享数据 是
* c:是否有多条语句操作共享数据 是
Runtime:每个 Java 应用程序都有一个 Runtime 类实例,使应用程序能够与其运行的环境相连接。
* exec(String command)

线程的状态有几种?


    6中
        Thread类枚举类State
            NEW  新建状态
            RUNNABLE 运行状态
            BLOCKED阻塞状态通过sleep(),wait()
            WAITTING等待 死等状态
            TIMED_WAITTING超时等待状态有一个时间毫秒值
            TERMINATED 线程死亡状态
什么是静态代理?请描述   
            静态代理:就是代理类和真实角色都需要实现同一个接口
                    代理类:帮助真实角色完成业务功能的增强
                    真实角色:专注于自己的事情
.如何解决线程安全问题?
        同步机制:悲观锁(synchronized)                
                使用同步代码解决线程安全问题: 加了同步锁,其他线程不能更改它数据(针对频繁写入操作)
                synchronized(锁对象){
                        多条语句对共享数据操作;
                }
                
                同步方法
                public synchronized 返回值类型 方法名(形参列表){  //锁对象:this
                    ...
                }
        
        Mybatis框架---->Mybatis-Plus (插件可以使用乐观锁)

什么是Java中的等待唤醒机制?

        等待唤醒机制---称为"等待通知",习惯于叫等待唤醒
        当前多个线程出现循环等待-----死锁
        使用notify() notifyAll()  将阻塞状态中线程进行唤醒,来操作业务数据!
        多个线程必须使用的是同一个资源对象!

创建多线程的方式有几种


    三种
        1)继承关系:
            自定一个类继承自Thread类
            重写Thread类的run方法
            在main中创建当前类对象,启动线程调用start()
        2)实现Runnable接口
            自定义一个类 实现Runnable接口
            重写Runnable接口的run方法
            在main中将自定义的类作为资源共享类---创建当前类对象 
            创建线程类Thread类对象,将资源共享类作为参数传递
            分别启动线程调用start()
            
        3)线程池    

2.获取一个类的字节码文件有几种方式?


        三种
            1)Object类的getClass()方法
            2)任意Java类型的class属性
            3)反射:Class.forName("包名.类名") ;

3.wait方法和sleep方法的区别(经常会的)


    1)是否释放锁
        当锁对象调用wait方法,立即释放锁;
        而sleep(xx):被调用的时候,线程一直处于阻塞状态,不会释放锁
    
    2)来源不同
        wait()来源于Object类----- >跟锁对象关系!
                为什么将wait():线程等待  ;notify()  notifyAll() 线程唤醒,定义Object类中?
                因为这些方法和锁有关系,而锁对象可以是任意Java对象!
        sleep():来源于Thread类---->只是属于一种状态,跟锁无关
    
    3)他们都会抛出interruptedException:当前状态被中断,都会抛出异常!

多线程实现方式1:   继承关系
     SellTicket st1 = new SellTicket() ;
            SellTicket st2 = new SellTicket() ;
            SellTicket st3 = new SellTicket() ;

            //设置线程名称
            st1.setName("窗口1") ;
            st2.setName("窗口2") ;
            st3.setName("窗口3") ;

            //启动线程
            st1.start() ;
            st2.start() ;
            st3.start();

            三个栈指向三个堆:分别在出售100张票 "没有数据共享"
继承关系具有局限性--->重写run方法----->Thread类的run---->通过实现Runnable接口的run 方法
    不仅仅继承run方法,还将其他无关方法继承过来,不利于功能的扩展! (体现不出来:面向接口编程)

多线程实现方式2: (推荐)
            "资源共享"
            每一个线程都在使用同一个对象 st(SellTicket对象的引用) 体现出 "面向接口编程"
            静态代理 模式
                    最大特点:真实角色和代理类都必须实现同一个接口!
                    代理类 对真实角色的功能进行方法增强!
            代理类
            真实角色

            SellTicket 实现Runnable接口 完成run方法重写
            Thread类 本身实现Runnable接口 完成run方法重写

                 SellTicket st = new SellTicket() ;
                //创建多个线程类对象,将资源共享类作为参数传递
                Thread t1 = new Thread(st,"窗口1") ;
                Thread t2 = new Thread(st,"窗口2") ;
                Thread t3 = new Thread(st,"窗口3") ;

                //启动线程
                t1.start();
                t2.start();
                t3.start();

创建型设计模式:对象的创建
 * Java提供:简单工厂模式 ---静态工厂方法模式
 * 优点:不需要具体类创建具体实例,通过工厂类创建
 *
 * 弊端:一旦有一个新的类型增,修改工厂类!
 *
 * 需要提供一个工厂类,负责具体的实例的创建

动物工厂类

public class AnimalFactory {
    //构造方法私有化
    private AnimalFactory(){ //外界不能创建当前类对象

    }

    //静态方法
    //创建猫的实例
 /*   public static Cat createCat(){

        return new Cat() ;
    }

    //创建狗的实例
    public static Dog createDog(){
        return new Dog() ;
    }




    //创建猪的实例
    public static Pig createPig(){
        return new Pig() ;
    }*/

 //优化:利用多态:提供功能扩展
    public static Animal createAnimal(String type){
        if(type.equals("dog")){
            return new Dog() ;
        }else if(type.equals("cat")){
            return new Cat() ;
        }else if(type.equals("pig")){
            return new Pig() ;
        }else{
            System.out.println("对不起,工厂类没有提供者动物的实例创建!");
        }
        return null ;
    }

}
Animal animal = AnimalFactory.createAnimal("dog"); //父类引用指向子类对象
        animal.eat();
        animal.sleep();
        animal = AnimalFactory.createAnimal("cat") ;
        animal.eat();
        animal.sleep();

 标准单例模式之饿汉式:Runtime
 * 个 Java 应用程序都有一个 Runtime 类实例,使应用程序能够与其运行的环境相连接

public class RuntTimeDemo {

    public static void main(String[] args) throws IOException {

        Runtime runtime = Runtime.getRuntime();
      //  Runtime runtime2 = Runtime.getRuntime();
        //System.out.println(runtime==runtime2);
        int cpuSize = runtime.availableProcessors();
        System.out.println(cpuSize);
        runtime.exec("notepad") ;
        runtime.exec("mspaint") ;
        runtime.exec("calc") ;
    }
}
public class Student {

    //创建该类实例---(类的实例变量)
//    public static Student s = new Student() ;
    private static Student s = new Student() ;
    private Student(){} //外界不能创建对象

    //提供对外的公共访问方法:静态的
    public static Student getStudent(){
        return s ;
    }
}
public class Tests {

    public static void main(String[] args) {
        /*Student s  =new Student() ;
        Student s2 = new Student() ;
        System.out.println(s==s2) ;//false
        System.out.println(s.getClass()==s2.getClass());//true*/
        //getClass()---->class 包名.类名

       // Student.s = null ; //被外界更改掉

        Student s1 = Student.getStudent();
        Student s2 = Student.getStudent();
        System.out.println(s1==s2);

        System.out.println("-----------------");
        Programmer p1 = Programmer.getPro();
        Programmer p2 = Programmer.getPro();
        Programmer p3 = Programmer.getPro();

        System.out.println(p1==p2);
        System.out.println(p1==p3);

    }
}
public class Programmer {

    private static Programmer pro = null ;

    private Programmer(){}


    //p1,p2,p3
    //对外公共访问方法
    /*public static Programmer getPro(){
        synchronized (Programmer.class){
            if(pro ==null){
                pro = new Programmer() ;
            }
            return pro ;
        }

    }*/
    public synchronized static Programmer getPro(){//静态同步方法:锁对象:当前类名.class属性
            if(pro ==null){
                pro = new Programmer() ;
            }
            return pro ;

    }


}

龟兔赛跑

public class Race  implements Runnable{

    //当类一加载的时候,定义静态变量
    //胜利者
    private  static String winner = null ;

    //兔子和乌龟都要执行这个run
    @Override
    public void run() {

        //for循环:表示步数1-100步
        for(int x = 1 ; x <= 100 ; x ++){

            //真实故事中:兔子要睡觉的,模拟兔子睡觉
            if(Thread.currentThread().getName().equals("兔子") && (x % 10 ==0 )){
                try {
                    Thread.sleep(50);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            //定义一个定义比赛结束的方法
            boolean flag = gameOver(x) ;
            if(flag){
                break ;
            }
            System.out.println(Thread.currentThread().getName()+"跑了====>"+x+"步");

        }

    }

    //比赛结束的方法
    private boolean gameOver(int step) {//步数  x
        //情况1:如果当前winner不等于null,存在胜利者,比赛结束
        if(winner!=null){
            return true ;
        }{
           //情况2: 判断如果当前step>=100 比赛也要结束
            if(step>=100){
                winner = Thread.currentThread().getName() ;
                System.out.println("winner is:"+winner);
                return true ;
            }
        }
        return false ;
    }


    //用户线程
    public static void main(String[] args) {

        //创建一个资源共享类
        Race race = new Race() ;
        //创建线程类对象
        Thread t1 = new Thread(race,"兔子") ;
        Thread t2 = new Thread(race,"乌龟") ;


        t1.start();
        t2.start();

    }
}

Java中等待唤醒机制
 *
 * SetThread:生产者资源类
 * GetThrread:消费者资源类
 * Student:学生

public class ThreadDemo {
    public static void main(String[] args) {

        //创建学生对象
        Student s = new Student() ;

        //生产者资源类/消费者资源类对象
        SetThread st = new SetThread(s) ;
        GetThread gt = new GetThread(s) ;

        //创建线程了对象
        Thread t1 = new Thread(st) ;
        Thread t2 = new Thread(gt) ;
        t1.start();
        t2.start();
    }
}
public class GetThread implements Runnable {

    private Student s ;
    public GetThread(Student s ){
        this.s  = s ;
    }
    @Override
    public void run() {
        //模拟消费者不断使用数据
        while(true){
            s.get();

        }
    }
}
public class Student {

  private   String name ;
  private  int age ;
  private   boolean flag ;


  //定义一个功能:给学生赋值(产生数据)
    public synchronized void set(String name,int age){ //同步方法  锁对象:this


            //如果生产者有数据,等待消费者使用数据
            if(this.flag){
                try {
                    this.wait(); //立即释放锁
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

        this.name = name ;
        this.age = age ;

            //如果存在数据
            this.flag = true ;
            //唤醒阻塞中的线程:消费者线程
            this.notify();
    }


    //获取学生的方法
    public synchronized void get(){
            //判断如果当前没有数据了,等待生产者生产数据
            if(!this.flag){
                try {
                    this.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

            System.out.println(this.name+"---"+this.age);
            //判断如果当前没有数据类,唤醒生产者线程,产生数据
            this.flag = false ;
            this.notify();
    }
}
public class SetThread implements  Runnable {
    private Student s ;
    public SetThread(Student s){
        this.s = s ;
    }

    int x  = 0 ;

    @Override
    public void run() {
        //模拟生产者不断产生数据
        while(true){


            if(x % 2 ==0){
                /*s.name = "高圆圆" ;
                s.age = 41 ;*/
                s.set("高圆圆",41);
            }else{
             /*   s.name ="赵又廷";
                s.age = 45 ;*/
                s.set("耿明刚",26);
            }
            x ++;

        }

    }
}

线程组 ThreadGroup 线程组表示一个线程的集合
 *
 * Thread类中方法:
 * public final ThreadGroup getThreadGroup():获取当前所有线程的默认线程组
 * ThreadGroup
 *         public final String getName() :获取默认的线程组名称: (默认就是main)
 *
 *
 *     构造方法:
 *         ThreadGroup(String name):构造一个新的名称的线程组
 *
 *         所有的线程默认的线程组就是main线程(用户线程)

public class ThreadGroupDemo {
    public static void main(String[] args) {
        //method() ;
        method2() ;
    }

    //设置线程组名称
    private static void method2() {
//        ThreadGroup(String name):构造一个新的名称的线程组
          ThreadGroup tg = new ThreadGroup("myMain") ;
          //创建线程类对象:可以将线程组对象作为参数传递
        //public Thread(ThreadGroup group,String name)
        Thread t1 = new Thread(tg,"线程1") ;
        Thread t2 = new Thread(tg,"线程2") ;


        System.out.println(t1.getThreadGroup().getName());
        System.out.println(t2.getThreadGroup().getName());


    }

    private static void method() {
        //创建两个线程类对象

        MyThread my1 = new MyThread() ;
        MyThread my2 = new MyThread() ;

        //获取对应的线程组名称
        ThreadGroup tg1 = my1.getThreadGroup();
        String name = tg1.getName();
        ThreadGroup tg2 = my2.getThreadGroup();
        String name2 = tg2.getName();
        System.out.println(name);
        System.out.println(name2);
    }
}

 MyCallabe:等待需要被线程池提交的异步任务

public class MyCallable implements Callable<Object> {

    //call方法:本身要计算的结果
    @Override
    public Object call() throws Exception {
        for(int x = 0 ; x <100 ; x ++ ){
            System.out.println(Thread.currentThread().getName()+":"+x);
        }
        return null;
    }
}

 线程池的使用:
 *  1)接口:ExecutorService :跟踪一个或者多个异步任务
 *  2)如何实例化---->Executors.newFixedThreadPool(int) 工厂方法:
 *
 *  Executors:工厂类
 *              提供创建线程池对象的方法
 *              public static ExecutorService newFixedThreadPool(int nThreads)
 *
 *  ExecutorService
 *          方法:
 *                  Future<?> submit(Runnable task) :通过线程池提交异步任务
 *                  <T> Future<T> submit(Callable<T> task):提交异步任务
 *
 *                  Future:异步任务计算的结果!
 *
 *
 * 第三种方式:线程池实现---->还是自定义一个类 实现Runnable接口

public class ThreadDemo {
    public static void main(String[] args) {


       /* new Thread(){
            @Override
            public void run() {

            }
        }.start();*/
        //创建一个线程池:静态工厂模式
        ExecutorService pool = Executors.newFixedThreadPool(2);

        //提交异步任务
        // Future<?> submit(Runnable task) :通过线程池提交异步任务
       /* pool.submit(new MyRunnable()) ;
        pool.submit(new MyRunnable()) ;*/
       //Callable要比Runnable接口更好
        //可以跟踪具体的异常错误(如果执行过程中,线程出现异常,可以跟踪异常信息!)
       pool.submit(new MyCallable()) ;
       pool.submit(new MyCallable()) ;

        //使用完毕,关闭线程池--将底层产生的线程归还线程池中
        pool.shutdown();

    }
}
public class MyRunnable implements  Runnable{
    @Override
    public void run() {

        for(int x = 0 ; x < 100 ; x ++){
            System.out.println(Thread.currentThread().getName()+":"+x);
        }
    }
}
public class MyCallable implements Callable<Object> {

    //call方法:本身要计算的结果
    @Override
    public Object call() throws Exception {
        for(int x = 0 ; x <100 ; x ++ ){
            System.out.println(Thread.currentThread().getName()+":"+x);
        }
        return null;
    }
}
public class ThreadDemo {

    public static void main(String[] args) throws ExecutionException, InterruptedException {

        //创建存有2条线程的线程池
        ExecutorService executorService = Executors.newFixedThreadPool(2);


        //Future:接口:异步计算的结果
        Future<Integer> f1 = executorService.submit(new MyCallable(100));
        Future<Integer> f2 = executorService.submit(new MyCallable(200));
        //V get():获取结果值
        Integer i1 = f1.get();
        Integer i2 = f2.get();
        System.out.println(i1);
        System.out.println(i2);

    }
}

j ava.util.Timer:定时器  :有线程安排执行务执行一次,或者定期重复执行。
 *      构造方法:
 *              public Timer() 无参构造方法
 *
 *      成员方法
*              public void cancel():取消定时器
*              public void schedule(TimerTask task,Date time) :在指定日期时间内执行这个任务
*              public void schedule(TimerTask task,long delay):在指定的延迟时间后执行task任务(时间:毫秒)
 *
 *            public void schedule(TimerTask task,
 *                      long delay,
 *                      long period) :在指定的delay延迟时间后开始重复时间间隔period来执行task任务
 *
 *   需求:
 *          在某天的18点将 d://demo文件夹  中的所有的带后缀为.java文件删除掉!  (Timer+io流+递归:综合使用)

public class TimerDemo {

    public static void main(String[] args) {
        //创建一个定时器
        Timer timer  = new Timer() ;
        //   public void cancel():取消定时器

        //参数1:定时任务:抽象类,定义子类继承自TimerTask
       // timer.schedule(new MyTask(timer),3000); :3秒后执行一次这个任务

      /*  public void schedule(TimerTask task,
                     long delay,
                       long period) :在指定的delay延迟时间后开始重复时间间隔period来执行task任务*/

      timer.schedule(new MyTask(timer),2000,3000);
    }
}

//定时任务
class MyTask extends TimerTask{ //TimerTask实现Runnable接口         ---会使用同步机制
    private Timer t ;
    public MyTask(Timer t){
        this.t = t ;
    }

    @Override
    public void run() {

        System.out.println("bom...");
        //关闭定时器
        //t.cancel() ;

    }
}

1.多线程创建方式有几种,列举
            
    1)继承自Thread类 重写run方法,然后创建当前类对象 启动线程
    2)实现Runnable接口 重写run方法,然后将当前资源类作为参数传递 到Thread类中 然后启动线程
    
                new Thread(new Runnable(){
                        public void run(){
                            ...
                        }
                
                }).start ;
    3)线程池
          工厂类:Executors 
                        public static ExecutorService newFixedThreadPool(int nThreads)
                        
                                    通过它的子实现对象:ThreadPoolExecutor
                                            7个参数:
                                            
                                            corePoolSize
                                            maxmiumPoolSize
                                            handler:自动启用拒绝策略
                                            TimeUnit:计时器
                                            ThreadFactory---创建新的线程对象
                                                    DefaultThreadFactory
                                            keepAliveTime:保存存活时间
                                            BlockingQueue queue  阻塞队列(Collection)
                ExecutorService
                        Future submit(Callable<E> call) :提交异步任务                        
2.什么是单例模式,请列举两种情况
     创建对象时候,始终保证内存只有一个对象!
     单例模式:
        饿汉式:不会出现安全的单例模式 :Runtime
            当前类一加载的时候,就立即创建一个对象(只有这一个对象)
            1)当前类是一个具体类
            2)类的成员位置:创建的当前静态实例变量并且私有化 
            3)无参构造方法私有化
            4)提供对外的公共访问方法:静态方法,并且返回值是当前类本身
            
            
            public class Student{
                private static Student s = new Student() ;
                
                private Student(){}
                
                public static Student getStudent(){
                    return s ; 
                }
            }
            
        懒汉式:可能出现安全问题的单例模式  (实际开发中:懒加载  / 延迟加载!)
            1)当前类是一个具体类
            2)不会立即创建一个当前类对象:而是声明当类型的成员变量 
            3)无参构造方法私有化
            4)提供对外的静态的公共访问方法:返回值也是当前类本身
                        先判断当前是否存在类对象,如果为null,新创建一个对象
                        返回当前类对象;
                        
            class Teacher{
                private static Teacher t = null ;
                private Teacher(){}
                
                
                //t对象被共用
                //并发的线程 访问公共变量:就会出现冲突
                
                //使用同步机制:synchronized
                public synchronized static Teacher getTeacher(){
                    if(t==null){ //需要使用的时候,才创建对象!
                        t = new Teacher() ; //新建一个对象
                    }
                    
                    return t ;
                }
                
            }        
                    
                    
                    Teacher t1 = Teacher.getTeacher() ;
                    Teacher t2 = Teacher.getTeacher() ;
        

3.什么是简单工厂以及工厂方法模式
            简单工厂:静态工厂方法模式
            优点:不需要具体类 new 具体类,而是需要通过工厂类 
            工厂类的职责:就是负责具体类的对象的创建!
            弊端:
                    当有新的类型增加,需要频繁的修改工厂类代码! (可以使用多态!)
                    
            工厂方法:
                需要有工厂接口,工厂接口中的方法 返回值某个抽象类型
                抽象类还需要有具体的子类,而具体类对象的创建工作:由工厂接口的 的子实现类(具体类的工厂类)
                    
                    interface Factory{
                        public abstract Animal  createAnimal() ;
                    }
                    
                    //狗的工厂类
                    class DogFactory implements Factory(){
                        public Animal createAnimal(){
                            return new Dog() ;
                        }
                    }
                    
                    
                    
                优点:面向接口编程而且使用接口多态,提供功能扩展性
                弊端:代码量大:一个新的类型增加,需要提供工厂类
                    
                    
            

4.集合和数组的区别

    长度区别
            集合:可变
            数组:固定
    存储元素
            集合:可以存储任意类型的元素 :引用类型
            数组:既可以存储引用类型,也可以存储基本类型 (元素类型必须统一)
    
    存储的数据类型区别
            数组:数据类型:必须统一 
            集合:只能引用类型

5.多线程的同步机制是什么
            
            解决:        
                    并发线程中针对公共变量访问冲突变量
                    
                同步机制:四种
                    1)ThreadLocal ----->  数据库连接池会使用! (创建Connection:连接对象)
                    2)同步代码块/同步方法 synchronized
                    3)wait()或者 notify()
                    4)volatile

MES系统

URL是URI的子集

URI
        /dianshang/login
        URI指定的具体的访问的路径:
        协议
            ftp协议
            迅雷协议
            邮件协议
            jdbc:
            http协议

URL:
        网络协议: http/ https:加密协议 更安全
        http://www.baidu.com:80/index.html
        
        http://localhost:8080/dianshang/login

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值