- 一、尚硅谷模块
- 1.1、第一季大佬总结
- 1.1.2、我的一些补充
- 1.1.2.1、 单例设计模式
- 1.1.1.2、基本数据类型和引用类型
- 1.2.3、 5、递归与迭代
- 1.2.4、Spring Bean 的作用域之间有什么区别?
- 二、其他大佬总结
经典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方法没有 Callablec = 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方法没有 Callablec = 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的几个经典常见面试题
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)