尚硅谷经典Java面试题一二三季

尚硅谷经典Java面试题一二三季,第1张

尚硅谷经典Java面试题一二三季

文章目录
  • 一、尚硅谷模块
    • 1.1、第一季大佬总结
    • 1.1.2、我的一些补充
      • 1.1.2.1、 单例设计模式
      • 1.1.1.2、基本数据类型和引用类型
    • 1.2.3、 5、递归与迭代
    • 1.2.4、Spring Bean 的作用域之间有什么区别?
  • 二、其他大佬总结

一、尚硅谷模块 1.1、第一季大佬总结

经典Java面试题(第1季)

1.1.2、我的一些补充 1.1.2.1、 单例设计模式

饿汉式


public class Singleton1 {
    // final 一旦赋值这个变量就不能再修改
    //static 用法 https://blog.csdn.net/LIAO_7053/article/details/81408139?spm=1001.2101.3001.6650.1&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-1.no_search_link&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-1.no_search_link
    //static final全局常量
    public static final Singleton1 INSTANCE = new Singleton1();
    public Singleton1() {
    }
}

测试

import com.atguigu.single.Singleton1;


public class TestSingleton1 {
    public static void main(String[] args) {
        Singleton1 s = Singleton1.INSTANCE;
    }

}

枚举类型



public enum Singleton2 {
    INSTANCE;
}

测试

import com.atguigu.single.Singleton2;


public class TestSingleton2 {
    public static void main(String[] args) {
        Singleton2 s = Singleton2.INSTANCE;
        System.out.println(s);
    }

}

静态代码块饿汉式(适合复杂实例化)

package com.atguigu.single;

import java.io.IOException;
import java.util.Properties;



public class Singleton3 {

    //第一种方法在这个地方直接new
//    public static final Singleton3 INSTANCE = new Singleton3();
    //第二种方法
    //static 用法 https://blog.csdn.net/LIAO_7053/article/details/81408139?spm=1001.2101.3001.6650.1&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-1.no_search_link&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-1.no_search_link

    public static final  Singleton3 INSTANCE;
    private String info;
    static {
        Properties pro = new Properties();
        try {
            pro.load(Singleton3.class.getClassLoader().getResourceAsStream("single.properties"));
            INSTANCE = new Singleton3(pro.getProperty("info"));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }


    }
    public Singleton3(String info) {
        this.info = info;
    }

    public static Singleton3 getINSTANCE() {
        return INSTANCE;
    }

    public String getInfo() {
        return info;
    }

    public void setInfo(String info) {
        this.info = info;
    }

    @Override
    public String toString() {
        return "Singleton3{" +
                "info='" + info + ''' +
                '}';
    }
}

测试


import com.atguigu.single.Singleton3;


public class TestSingleton3 {
    public static void main(String[] args) {
        Singleton3 s = Singleton3.INSTANCE;
        System.out.println(s);
    }

}

src/main/resources/single.properties

info=atguigu

懒汉式:延迟创建对象
线程不安全(适用于单线程)

package com.atguigu.single;




public class Singleton4 {
    private static Singleton4 instance;
    private Singleton4() {

    }
    public static Singleton4 getInstance() {
        if (instance == null) {
//            try {
//                Thread.sleep(200);
//            } catch (InterruptedException e) {
//                e.printStackTrace();
//            }
            instance = new Singleton4();
        }
        return instance;
    }
}

测试
修改懒汉式代码

package com.atguigu.single;




public class Singleton4 {
    private static Singleton4 instance;
    private Singleton4() {

    }
    public static Singleton4 getInstance() {
        if (instance == null) {
            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            instance = new Singleton4();
        }
        return instance;
    }
}

import com.atguigu.single.Singleton4;

import java.util.concurrent.*;


public class TestSingleton4 {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
//        Singleton4 s1 = Singleton4.getInstance();
//        Singleton4 s12 = Singleton4.getInstance();
//        System.out.println(s1 == s12);
//        System.out.println(s1);
//        System.out.println(s12);

        //Callable用法
        //https://ghsau.blog.csdn.net/article/details/7451464?spm=1001.2101.3001.6650.13&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EOPENSEARCH%7Edefault-13.no_search_link&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EOPENSEARCH%7Edefault-13.no_search_link
        // call 方法可以有返回值,run方法没有
        Callable c = new Callable() {
            public Singleton4 call() throws Exception {
                return Singleton4.getInstance();
            }
        };

        //创建两个线程的线程池
        ExecutorService executor = Executors.newFixedThreadPool(2);
        Future f1 = executor.submit(c);
        Future f2 = executor.submit(c);

        Singleton4 s1 = f1.get();
        Singleton4 s2 = f2.get();

        //是有概率问题的一会true一会false
        System.out.println(s1 == s2);
        System.out.println(s1);
        System.out.println(s2);

        executor.shutdown();




    }
}

不同线程遇到延迟会产生阻塞,这样会从造成一会true一会false的情况,不同线程遇到休眠会产生阻塞,可能会出现线程由于时间不同造成创建两个不同对象的情况。

线程安全适用于多线程

package com.atguigu.single;




public class Singleton5 {
    private static Singleton5 instance;
    private Singleton5() {

    }
    public static Singleton5 getInstance() {
        //https://blog.csdn.net/luoweifu/article/details/46613015  synchronized用法
        //安全问题已经解决但是我需要解决效率问题加个null判断
        if(instance == null) {
            synchronized(Singleton5.class){
                if (instance == null) {
                    try {
                        Thread.sleep(200);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    instance = new Singleton5();
                }
            }

        }


        return instance;
    }
}

测试

import com.atguigu.single.Singleton4;
import com.atguigu.single.Singleton5;

import java.util.concurrent.*;


public class TestSingleton5 {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
//        Singleton4 s1 = Singleton4.getInstance();
//        Singleton4 s12 = Singleton4.getInstance();
//        System.out.println(s1 == s12);
//        System.out.println(s1);
//        System.out.println(s12);

        //Callable用法
        //https://ghsau.blog.csdn.net/article/details/7451464?spm=1001.2101.3001.6650.13&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EOPENSEARCH%7Edefault-13.no_search_link&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EOPENSEARCH%7Edefault-13.no_search_link
        // call 方法可以有返回值,run方法没有
        Callable c = new Callable() {
            public Singleton5 call() throws Exception {
                return Singleton5.getInstance();
            }
        };

        //创建两个线程的线程池
        ExecutorService executor = Executors.newFixedThreadPool(2);
        Future f1 = executor.submit(c);
        Future f2 = executor.submit(c);

        Singleton5 s1 = f1.get();
        Singleton5 s2 = f2.get();

        //是有概率问题的一会true一会false
        System.out.println(s1 == s2);
        System.out.println(s1);
        System.out.println(s2);

        executor.shutdown();




    }
}

无论如何修改延迟时间我们发现都是true

静态内部类形式(适用于多线程)

package com.atguigu.single;


public class Singleton6 {

    private Singleton6(){

    }
    private static class Inner{
        private static final  Singleton6 INSTANCE = new Singleton6();
    }
    public static Singleton6 getInstance() {
        return Inner.INSTANCE;
    }
}

1.1.1.2、基本数据类型和引用类型

对应尚硅谷第一季的4、方法参数传递机制章节

Java基本类型共有八种,基本类型可以分为三类,字符类型char,布尔类型boolean以及数值类型byte、short、int、long、float、double。数值类型又可以分为整数类型byte、short、int、long和浮点数类型float、double。

引用类型包括三种:
类 Class
接口 Interface
数组 Array
方法的参数传递机制

1、形参是基本数据类型

传递数据值

2、实参是引用数据类型​

传递地址值

​ 特殊的类型:String、包装类等对象的不可变性

1.2.3、 5、递归与迭代

首先看一道编程题如下:
有 n 步台阶,一次只能上 1 步或者 2 步,共有多少种走法?

1、递归fen

分析如图,当n等于1或者2时,走法就等于n,从第三层台阶开始,每一层台阶为前两层台阶走法之和。

2、迭代

用 one、two 这两个变量来存储 n 的最后走一步和最后走两步,从第三层开始走,用 sum 来保存前两次的走法的次数,sum = two + one; 然后 two 移到 one,one 移到 sum 循环迭代。

代码如下:

public class Code_05_StepProblem {

    @Test
    public void test() {
        // 时间复杂度 ...
//        long start = System.currentTimeMillis();
//        System.out.println(recursion(40)); // 165580141
//        long end = System.currentTimeMillis(); // 537
//        System.out.println(end - start);

        // 时间复杂度 O(n)
        long start = System.currentTimeMillis();
        System.out.println(iteration(40)); // 165580141
        long end = System.currentTimeMillis(); // 0
        System.out.println(end - start);
    }

    // 递归实现
    public int recursion(int n) {
      if(n < 1) {
          return 0;
      }
      if(n == 1 || n == 2) {
          return n;
      }
      return recursion(n - 2) + recursion( n - 1);
    }

    // 迭代实现
    public int iteration(int n) {
        if(n < 1) {
            return 0;
        }
        if(n == 1 || n == 2) {
            return n;
        }
        int two = 1; // 一层台阶,有 1 走法, n 的前两层台阶的走法
        int one = 2; // 二层台阶,有 2 走法, n 的前一层台阶的走法
        int sum = 0; // 记录一共有多少中走法
        for(int i = 3; i <= n; i++) {
                sum = two + one;
                two = one;
                one = sum;
        }
        return sum;
    }
}

总结:

1)方法调用自身称为递归,利用变量的原值推出新值称为迭代。

2)递归

优点:大问题转为小问题,可以减少代码量,同时代码精简,可读性好;

缺点:递归调用浪费了空间,而且递归太深容易造成堆栈的溢出。

3)迭代

优点:代码运行效率好,因为时间复杂度为0(n),而且没有额外空间的开销;

1.2.4、Spring Bean 的作用域之间有什么区别?

默认情况下,Spring只为每个在I0C容器里声明的bean创建唯一一个实例,整个IOC容器范围内都能共享该实例:所有后续的getBean()调用和bean引用都将返回这个唯一的bean实例。该作用域被称为singleton,它是所有bean的默认作用域。
在Spring的配置文件中,给bean加上scope属性来指定bean的作用域如下:

singleton:唯一 bean 实例,Spring 中的 bean 默认都是单例的。

prototype:每次请求调用getBean()都会创建一个新的 bean 实例。

request: 每一次 HTTP 请求都会产生一个新的 bean,该 bean 仅在当前WebApplicationContext内有效。

session:每一次 HTTP 请求都会产生一个新的 bean,不同的HTTP session 使用不用的bean,该 bean 仅在当前WebApplicationContext内有效。

global-session:全局session作用域,仅仅在基于portlet的web应用中才有意义,Spring5已经没有了。Portlet是能够生成语义代码(例如:HTML)片段的小型Java Web插件。它们基于portlet容器,可以像servlet一样处理HTTP请求。但是,与 servlet 不同,每个 portlet 都有不同的会话。

二、其他大佬总结

Spring常见面试题总结(超详细回答)

15个经典的Spring面试常见问题

MyBatis+Spring+SpringMVC框架面试题整理(一)

JAVA关于Spring 面试题汇总

Spring的几个经典常见面试题

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/4015601.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-10-22
下一篇 2022-10-22

发表评论

登录后才能评论

评论列表(0条)

保存