【Interview】Java 高频面试题(一)

时间:2021-05-03 12:58:12   收藏:0   阅读:0

Java 高频面试题(一)

自增变量

如下代码的运算结果:

package java_one;

/**
 * @author parzulpan
 * @version 1.0
 * @date 2021-04
 * @project JavaInterview
 * @package java_one
 * @desc 自增变量
 * i = 1
 * i = 2 j = 1
 * i = 4 k = 11
 * i = 4 k = 1 k = 11
 */

public class IncreasingVariable {
    public static void main(String[] args) {
        int i = 1;
        i = i++;
        int j = i++;
        int k = i + ++i * i++;
        System.out.println("i = " + i);
        System.out.println("j = " + j);
        System.out.println("k = " + k);
    }
}

总结:

单例设计模式

饿汉式1

实现如下:

package java_one;

/**
 * @author parzulpan
 * @version 1.0
 * @date 2021-04
 * @project JavaInterview
 * @package java_one
 * @desc 2.单例设计模式
 * 饿汉式 - 直接实例化
 * 在类初始化时直接创建实例对象,不管是否需要这个对象都会创建
 * 1. 构造器私有化
 * 2. 自行创建,并用公有静态变量保存
 * 3. 向外提供这个实例
 */

public class Singleton1 {
    public static final Singleton1 INSTANCE = new Singleton1();

    private Singleton1() { }
}

测试代码:

class Singleton1Test {
    public static void main(String[] args) {
        Singleton1 s1 = Singleton1.INSTANCE;
        Singleton1 s2 = Singleton1.INSTANCE;
        System.out.println(s1 == s2);
        System.out.println(s1);
        System.out.println(s2);
    }
}

饿汉式2

实现如下:

package java_one;

/**
 * @author parzulpan
 * @version 1.0
 * @date 2021-04
 * @project JavaInterview
 * @package java_one
 * @desc 2.单例设计模式
 * 饿汉式 - 枚举式
 * 枚举类型表示该类型的对象是有限的几个,可以限定为一个,就成了单例
 */

public enum Singleton2 {
    INSTANCE
}

测试代码:

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

饿汉式3

实现如下:

package java_one;

/**
 * @author parzulpan
 * @version 1.0
 * @date 2021-04
 * @project JavaInterview
 * @package java_one
 * @desc 2.单例设计模式
 * 饿汉式 - 静态代码块
 * 这种方式通常适用于复杂的实例化
 */

public class Singleton3 {
    public static final Singleton3 INSTANCE;
    static {
        // ...
        INSTANCE = new Singleton3();
    }
}

测试代码:

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

懒汉式1

实现如下:

package java_one;

/**
 * @author parzulpan
 * @version 1.0
 * @date 2021-04
 * @project JavaInterview
 * @package java_one
 * @desc 2.单例设计模式
 * 懒汉式 - 线程不安全,适用于单线程
 * 延迟创建实例对象
 * 1. 构造器私有化
 * 2. 用一个私有静态变量保存这个唯一的实例
 * 3. 提供一个静态方法,获取这个实例对象
 */

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

测试代码:

class Singleton4Test {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        Callable<Singleton4> callable = new Callable<Singleton4>() {

            @Override
            public Singleton4 call() throws Exception {
                return Singleton4.getInstance();
            }
        };
        ExecutorService executorService = Executors.newFixedThreadPool(2);
        Future<Singleton4> future1 = executorService.submit(callable);
        Future<Singleton4> future2 = executorService.submit(callable);
        Singleton4 s1 = future1.get();
        Singleton4 s2 = future2.get();
        System.out.println(s1 == s2);
        System.out.println(s1);
        System.out.println(s2);
        executorService.shutdown();
    }
}

懒汉式2

实现如下:

package java_one;

/**
 * @author parzulpan
 * @version 1.0
 * @date 2021-04
 * @project JavaInterview
 * @package java_one
 * @desc 2.单例设计模式
 * 懒汉式 - 线程安全,适用于多线程
 */

public class Singleton5 {
    /** 为了避免初始化操作的指令重排序,给 instance 加上了 volatile */
    private static volatile Singleton5 instance;
    private Singleton5() { }
    public static Singleton5 getInstance() {
        if (instance == null) {
            synchronized(Singleton5.class) {
                if (instance == null) {
                    // ...
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    instance = new Singleton5();
                }
            }
        }
        return instance;
    }
}

测试代码:

class Singleton5Test {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        Callable<Singleton5> callable = Singleton5::getInstance;
        ExecutorService executorService = Executors.newFixedThreadPool(2);
        Future<Singleton5> future1 = executorService.submit(callable);
        Future<Singleton5> future2 = executorService.submit(callable);
        Singleton5 s1 = future1.get();
        Singleton5 s2 = future2.get();
        System.out.println(s1 == s2);
        System.out.println(s1);
        System.out.println(s2);
        executorService.shutdown();
    }
}

懒汉式3

实现如下:

package java_one;

/**
 * @author parzulpan
 * @version 1.0
 * @date 2021-04
 * @project JavaInterview
 * @package java_one
 * @desc 2.单例设计模式
 * 懒汉式 - 静态内部类,线程安全,适用于多线程
 * 当内部类被加载和初始化时,才会创建实例对象
 */

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

测试代码:

class Singleton6Test {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        Callable<Singleton6> callable = Singleton6::getInstance;
        ExecutorService executorService = Executors.newFixedThreadPool(2);
        Future<Singleton6> future1 = executorService.submit(callable);
        Future<Singleton6> future2 = executorService.submit(callable);
        Singleton6 s1 = future1.get();
        Singleton6 s2 = future2.get();
        System.out.println(s1 == s2);
        System.out.println(s1);
        System.out.println(s2);
        executorService.shutdown();
    }
}

总结:

推荐阅读:

类初始化和实例初始化

如下代码的运算结果:

public class Father {
    private int i = test();
    private static int j = method();

    static {
        System.out.print("(1)");
    }
    Father() {
        System.out.print("(2)");
    }
    {
        System.out.print("(3)");
    }
    public int test() {
        System.out.print("(4)");
        return 1;
    }
    public static int method() {

        System.out.print("(5)");
        return 1;
    }
}

public class Son extends Father{
    private int i = test();
    private static int j = method();

    static {
        System.out.print("(6)");
    }
    Son() {
        // super(); 写不写都存在,在子类构造器中一定会调用父类的构造器
        System.out.print("(7)");
    }
    {
        System.out.print("(8)");
    }
    @Override
    public int test() {
        System.out.print("(9)");
        return 1;
    }
    public static int method() {

        System.out.print("(10)");
        return 1;
    }
}

package java_one.three;

/**
 * @author parzulpan
 * @version 1.0
 * @date 2021-04
 * @project JavaInterview
 * @package java_one.three
 * @desc 3. 类初始化和实例初始化
 */

public class Test {
    public static void main(String[] args) {
        // 正确输出 5 1 10 6 9 3 2 9 8 7
        Son s1 = new Son();
        System.out.println();
        // 正确输出 9 3 2 9 8 7
        Son s2 = new Son();
    }
}

总结:

推荐阅读:

方法的参数传递机制

如下代码的运算结果:

package java_one.four;

import java.util.Arrays;

/**
 * @author parzulpan
 * @version 1.0
 * @date 2021-04
 * @project JavaInterview
 * @package java_one.four
 * @desc 4. 方法的参数传递机制
 * i = 1
 * str = hello
 * num = 2
 * arr = [2, 2, 3, 4, 5]
 * myData.a = 11
 */

public class ParameterPassing {
    public static void main(String[] args) {
        int i = 1;
        String str = "hello";
        Integer num = 2;
        int[] arr = {1, 2, 3, 4, 5};
        MyData myData = new MyData();

        change(i, str, num, arr, myData);

        System.out.println("i = " + i);
        System.out.println("str = " + str);
        System.out.println("num = " + num);
        System.out.println("arr = " + Arrays.toString(arr));
        System.out.println("myData.a = " + myData.a);
    }

    public static void change(int j, String s, Integer n, int[] a, MyData m) {
        j += 1;
        s += "world";
        n += 1;
        a[0] += 1;
        m.a += 1;
    }
}

class MyData {
    int a = 10;
}

总结:

推荐阅读:

递归和迭代

有 n 步台阶,一次只能上 1 步或 2 步,共有多少种走法?

package java_one.five;

/**
 * @author parzulpan
 * @version 1.0
 * @date 2021-04
 * @project JavaInterview
 * @package java_one.five
 * @desc 5. 递归和迭代
 */

public class Fibonacci {
    private final int CONSTANT = 1000000007;

    public int numWaysByRecursion(int n) {
        if (n < 3) {
            return n;
        }
        return (numWaysByRecursion(n - 1) % CONSTANT + numWaysByRecursion(n - 2) % CONSTANT) % CONSTANT;
    }

    public int numWaysByIteration(int n) {
        int first = 0, second = 1, sum;
        for (int i = 0; i < n; ++i) {
            sum = (first + second) % CONSTANT;
            first = second;
            second = sum;
        }
        return second;
    }

    public static void main(String[] args) {
        Fibonacci fibonacci = new Fibonacci();
        System.out.println(fibonacci.numWaysByRecursion(0));
        System.out.println(fibonacci.numWaysByRecursion(1));
        System.out.println(fibonacci.numWaysByRecursion(2));
        System.out.println(fibonacci.numWaysByRecursion(10));
        System.out.println();
        System.out.println(fibonacci.numWaysByIteration(0));
        System.out.println(fibonacci.numWaysByIteration(1));
        System.out.println(fibonacci.numWaysByIteration(2));
        System.out.println(fibonacci.numWaysByIteration(10));
    }
}

总结:

推荐阅读:

成员变量和局部变量

如下代码的运算结果:

package java_one.six;

/**
 * @author parzulpan
 * @version 1.0
 * @date 2021-04
 * @project JavaInterview
 * @package java_one.six
 * @desc 6. 成员变量和局部变量
 * 抓住:
 * 局部变量存在栈中,它每次调用都是新的生命周期
 * 实例变量存在堆中,它随着对象的创建而初始化,随着对象的回收而消亡,每一个对象的实例变量是独立的
 * 类变量存在方法区中,它随着类的初始化而初始化,随着类的卸载而消亡,该类的所有对象的类变量是共享的
 */

public class MembersLocalVariables {
    static int s;
    int i;
    int j;

    {
        int i = 1;
        i++;
        j++;
        s++;
    }

    public void test(int j) {
        j++;
        i++;
        s++;
    }

    public static void main(String[] args) {
        MembersLocalVariables m1 = new MembersLocalVariables();
        MembersLocalVariables m2 = new MembersLocalVariables();
        m1.test(10);
        m1.test(20);
        m2.test(30);
        // 2 1 5
        System.out.println(m1.i + " " + m1.j + " " + m1.s);
        // 1 1 5
        System.out.println(m2.i + " " + m2.j + " " + m2.s);
    }
}

总结:

推荐阅读:

Spring Bean 的作用域和生命周期

Spring Bean 有五个作用域,比较基础的有:

如果是 Web 容器,还支持:

Spring Bean 的生命周期分为创建和销毁两个过程:

创建

销毁

总结:

推荐阅读:

Spring 支持的常用数据库事务传播属性(行为)和事务隔离级别

事务的传播行为:

事务的隔离级别:

总结:

推荐阅读:

SpringMVC 中如何个解决 POST 请求中文乱码问题,GET 请求又如何处理

对于 Post 请求(form 标签 method=post:解决的方法是在 web.xml 中配置一个编码过滤器

<web-app>

  <!-- 配置解决中文乱码的过滤器 -->
  <filter>
    <filter-name>characterEncodingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <!-- 设置过滤器中的属性值 -->
    <init-param>
      <param-name>encoding</param-name>
      <param-value>UTF-8</param-value>
    </init-param>
  </filter>
  <!-- 过滤所有请求 -->
  <filter-mapping>
    <filter-name>characterEncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

</web-app>

对于 Get 请求:解决的方法是修改 Tomcat 的 server.xml 配置文件,添加 <Connector URIEncoding="UTF-8" useBodyEncodingForURI="true"/>

推荐阅读:

SpringMVC 的工作流程

技术图片

总结:

参考阅读:

MyBatis 中当实体类中的属性名和表中的字段名不一样时该如何处理

例如:

属性名:实体类 id name password

字段名:数据库 id name pwd

mybatis 会根据数据库的字段名去找对应的实体类的属性名,它会将所有列名转换为小写,然后去找实体类中对应的 set 方法 ,set 方法后面的字段就对应数据库的字段名;如果不一样就会返回 null。

基本上有三种方式解决:

Linux 常用的服务类相关命令

对于 CentOS6

对于 CentOS7

Git 常用的分支相关命令

Redis 持久化

RDB 和 AOF 的优缺点,以及使用建议。

总结:

推荐阅读:

MySQL 什么时候适合创建索引

总结:

推荐阅读:

JVM 的垃圾回收机制

Redis 在项目中的常见使用场景

MQ 在项目中的常见使用场景

推荐阅读:

ES 和 Solr 的异同

总结:

设计实现单点登录功能

单点登录:分布式系统中,一处登录多处使用。

设计实现购物车功能

至少需要考虑以下两个问题:

总结

评论(0
© 2014 mamicode.com 版权所有 京ICP备13008772号-2  联系我们:gaon5@hotmail.com
迷上了代码!