Java进阶面试-高频面试题详解(一)

一、Java必知必会

1.1 静态变量与实例变量的区别

Java进阶面试-高频面试题详解(一)_第1张图片

1.3 请介绍==、equals、hashCode的区别

        ==用于比较两个内存的地址

        equals用于比较两个对象的值

        hashCode用于在Hash集合中快速定位对象 

Java进阶面试-高频面试题详解(一)_第2张图片

        针对某一对象的编码被称为hashCode。典型作用:在hashMap中进行对象的快速定位。

        hashMap会在内存中开辟一系列的小存储空间,这个小存储空间被称为slot槽。

        hashCode和slot如何对应呢?最简单的做法就是将hashMap按slot的总量取模%,得到的结果就是slot的号。

        hashMap中查询数据步骤:首先针对key计算出hashCode,接着对hashCode按slot总量取模%,得到slot号位,再使用equals方法来按key进行比对,最终提取出数据。

Java进阶面试-高频面试题详解(一)_第3张图片

1.5 请介绍浅复制与深复制的区别

        基础篇中记过

Java进阶面试-高频面试题详解(一)_第4张图片

1.6 this和super关键字的异同

Java进阶面试-高频面试题详解(一)_第5张图片

 1.7 静态块、实例块、构造方法代码题

Java进阶面试-高频面试题详解(一)_第6张图片

1.8 请说明在精确计算时为什么不能使用浮点型

        计算机本身是二进制的,而浮点数实际上只是个近似值,所以从二进制转化为十进制浮点数时,精度容易丢失,导致精度下降。

Java进阶面试-高频面试题详解(一)_第7张图片

Java进阶面试-高频面试题详解(一)_第8张图片

1.10 请说明JVM的组成

        jvm主要工作就是在操作系统之上构建出一个独立运行的体系。封闭生态,和外界沟通非常少。

        jvm核心组成:类加载子系统、运行时数据区、执行引擎(用于计算,和CPU交互)、本地方法接口(很少用到,也不推荐)。

Java进阶面试-高频面试题详解(一)_第9张图片

1.11 请简述Java的垃圾标记算法

        GC负责3项任务:分配内存、确保引用、回收内存。

        GC回收的依据:某个对象没有任何引用,则可以被回收。

计数器法(已弃用)

可达性分析算法:

Java进阶面试-高频面试题详解(一)_第10张图片

        最主要一个对象GC Roots集合。

        可作为GC Roots:方法的入参、局部变量;方法执行过程中的引用对象;静态变量引用的对象;常量引用的对象;JNI本地方法引用的对象;

1.12 你了解有哪些Java内存泄漏的场景

        静态集合类:通过static描述的list、map等数据结构。

        各种连接/IO未释放

        不合理的变量作用域

        缓存未设置过期时效与淘汰算法

        出现交叉引用(死锁)

        单例模式使用集合

二、高阶面试考点-Spring

2.1 IOC与DI的理解

        基础篇记过

        IOC控制反转,设计理念,由第三方来管理与控制对象(运行时中)。

        DI依赖注入,具体实现,由对象容器在运行时动态注入对象(反射方式,工厂模式方式)。

2.2 请介绍Spring框架BeanFactory与ApplicationContext有何区别

Java进阶面试-高频面试题详解(一)_第11张图片

Java进阶面试-高频面试题详解(一)_第12张图片

        web应用环境,比如SpringMVC:可以使用扩展接口WebApplicationContext,扩展了web应用能力。

2.6 请说明Spring中使用了哪些设计模式

        IOC容器-工厂方法模式

        Bean对象-单例模式

        AOP-代理模式

        (面向切面编程的含义就是:在调用者和服务提供者之间,增加一个代理类,利用代理类为原有的系统功能提供扩展。同时让调用者和真正的服务提供者之间增加代理进行解耦工作)

        (代理模式在Spring中又分成两种情况:目标类如果有接口则使用JDK动态代理来实现;目标类如果没有接口则需要使用Cglib进行扩展实现。这是AOP代理模式的底层实现。)

        AOP-适配器模式

        对象监听-观察者模式

        JdbcTemplate-模板方法(提供给用户统一接口)

三、高阶面试考点-Mybatis

3.1 请介绍MyBatis中的二级缓存特性

        把查询结果保存在内存中

        一级缓存默认开启,缓存范围SqlSession会话

        二级缓存手动开启,缓存范围更大,属于Mapper Namespace级别

二级缓存运行规则:

        二级开启后默认所有查询操作均使用缓存

        写操作commit提交时对该namespace缓存强制清空(一张表频繁写入的话,不建议开启二级缓存)

        配置useCache=false可以不用缓存(SQL语句标签中)

        配置flushCache=true代表强制清空缓存(SQL语句标签中)

3.2 请介绍MyBatis支持哪些缓存淘汰策略

        FIFO-先进先出

        LRU-最近最少使用(推荐)

        SOFT-软引用(基于GC)

        WEAK-弱引用(基于GC)

3.4 请介绍MyBatis获取新纪录自增主键的措施

Java进阶面试-高频面试题详解(一)_第13张图片

         useGeneratedKeys会执行 select last_insert_id()获取最新主键。

        last_insert_id()与连接绑定,每个线程一个连接,不会出现线程安全问题。

Oracle不支持自增主键的做法:

Java进阶面试-高频面试题详解(一)_第14张图片

四、高阶面试考点-设计模式

4.1 请介绍简单工厂与工厂模式的区别

简单工厂通过一个工厂类实现对象创建

public class I18NFactory {
    public static Language getI18NObject(String area) {
        if(area.equals("china")) {
            return new Chinese();
        } else if(area.equals("spain")) {
            return new Spanish();
        } else if(area.equals("italy")) {
            return new Italian();
        } else {
            return null;
        }
    }
}

        与之对应的,工厂模式中的产品它有一个顶层接口Language,Language提供了对应的方法。

public interface Language {
    public String getTitle();
}

        每个具体产品都要实现接口,来完成里面的逻辑。再由简单工厂来完成对这个对象的创建工作。

public class Chinese implements Language {
    @Override
    public String getTitle() {
        return "人事管理系统";
    }
}

        可直接通过 I8NFactory.getI18NObject() 得到对应的语言对象。

工厂方法通过抽象出工厂接口,为每一种产品提供对应工厂 

//把工厂也抽象出接口的使用形式,就称为工厂方法。
public interface I18NFactory {
    public Language getI18NObject();
}

        工厂方法解决了扩展性问题。xx语言对象 Spainish、xx语言工厂 SpainishFactory。

        可直接通过 new SpainishFactory().getI18NObject() 得到对应的语言对象。 

        利用工厂模式隐藏类创建细节,修改类的细节不会影响其他人对类的使用。

简单工厂变通:

        把相应的判断条件和字符串保存在配置文件中,再通过反射的形式,动态的进行对象实例化。这样即便使用简单工厂配合反射机制,未来新增新的业务或分支,只需要在配置文件中修改就可以。也可以达到不用修改简单工厂源代码的前提。Spring IOC容器的核心原理(工厂模式+配置文件)。

4.2 请介绍观察者模式以及它的使用场景

Java进阶面试-高频面试题详解(一)_第15张图片

Java进阶面试-高频面试题详解(一)_第16张图片

Java进阶面试-高频面试题详解(一)_第17张图片

Java进阶面试-高频面试题详解(一)_第18张图片

Java进阶面试-高频面试题详解(一)_第19张图片  

Java进阶面试-高频面试题详解(一)_第20张图片  

Java进阶面试-高频面试题详解(一)_第21张图片

4.3 请介绍静态代理和动态代理的区别

代理模式:

        通过生成代理对象对原始对象实现无侵入的功能扩展。

Java进阶面试-高频面试题详解(一)_第22张图片

        静态代理需要Java工程师手动的创建代理类。而动态代理则使用Java的反射机制或Cglib这种技术来动态的生成代理类。

静态代理

Java进阶面试-高频面试题详解(一)_第23张图片

        这里有个非常巧妙的设计,因为所有的代理类和实现类都实现了UserService接口,所以在静态代理类实例化的时候,传入的userService对象,既可以是目标对象,也可以是其他的代理类。基于这种特性,我们就可以在当前的系统中增加多级代理,来分门别类的提供前置或者后置的功能。

        静态代理的使用

动态代理 

        Java引入反射机制以后,同样提供了自动生成代理类的机制。

        动态代理典型特点:根据目标的接口来自动的利用反射技术生成代理类,然后通过InvocationHandler中的invoke方法来对目标方法进行代理和扩展。 

        好处:只要某一个类有相应的接口,自动就可以利用动态代理完成这个任务的扩展。

package com.imooc.spring.aop.service;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * InvocationHandler是JDK提供的反射类,用于在JDK动态代理中对目标方法进行增强
 * InvocationHandler实现类与切面类的环绕通知类似
 */
public class ProxyInvocationHandler implements InvocationHandler {
    private Object target;//目标对象
    private ProxyInvocationHandler(Object target){
        this.target = target;
    }
    /**
     * 在invoke()方法对目标方法进行增强
     * @param proxy 代理类对象
     * @param method 目标方法对象
     * @param args 目标方法实参
     * @return 目标方法运行后返回值
     * @throws Throwable 目标方法抛出的异常
     */
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("=====" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS").format(new Date()) +"=========");
        Object ret = method.invoke(target, args);//调用目标方法,ProceedingJoinPoint.proceed()
        return ret;
    }

    public static void main(String[] args) {
        UserService userService = new UserServiceImpl();
        ProxyInvocationHandler invocationHandler = new ProxyInvocationHandler(userService);
        //动态创建代理类
        UserService userServiceProxy = (UserService)Proxy.newProxyInstance(userService.getClass().getClassLoader(),
                userService.getClass().getInterfaces(),
                invocationHandler);
        userServiceProxy.createUser();

        //动态代理,必须实现接口才可以运行
        EmployeeService employeeService = new EmployeeServiceImpl();
        EmployeeService employeeServiceProxy = (EmployeeService)Proxy.newProxyInstance(employeeService.getClass().getClassLoader(),
                employeeService.getClass().getInterfaces(),
                new ProxyInvocationHandler(employeeService));
        employeeServiceProxy.createEmployee();
    }
}

 CGLib实现代理类

        CGLib是运行时字节码增强技术

        SpringAOP扩展无接口类使用CGLib

        AOP会使用在运行时生成 目标继承类 字节码的方式进行行为扩展

Java进阶面试-高频面试题详解(一)_第24张图片

 4.4 请说明适配器模式的作用

Java进阶面试-高频面试题详解(一)_第25张图片

//适配器典型特征
//实现与目标类相同的接口
public class JsonAdapter implements DataSource {
    //通过构造方法内部持有目标对象
    private DataSource dataSource;
    public JsonAdapter(DataSource dataSource) {
        this.dataSource = dataSource;
    }
    //重写接口方法,完成接口转换的业务逻辑
    @Override
    public String searchUser() {
        String xml = dataSource.searchUser();
        //XML转换为JSON的代码省略
        String json = "......"
        return json;
    }
}

六、高阶面试考点-网络通信

6.1 请说明OSI七层与TCP四层网络模型

Java进阶面试-高频面试题详解(一)_第26张图片Java进阶面试-高频面试题详解(一)_第27张图片

 6.2 请说明TCP三次握手过程

Java进阶面试-高频面试题详解(一)_第28张图片

6.3 请简述HTTP与HTTPS的区别

Java进阶面试-高频面试题详解(一)_第29张图片

6.4 请简述HTTP2.0新特性

        二进制分帧

        首部压缩

        流量控制

        多路复用

        请求优先级

        服务器推送

你可能感兴趣的:(Java工程师技术栈,java)