zoukankan      html  css  js  c++  java
  • 面试笔记

    一、java基础

    1. java类初始化顺序

    • clinit 方法由静态类变量显示赋值代码和静态代码块组成
    • 类变量显示赋值代码和静态代码块代码从上到下执行
    • clinit 方法只调用一次

    父类静态属性(成员变量)>父类静态代码块>子类静态属性>子类静态代码块

    2. java实例初始化属性

    • init () 方法可能重载有多个,有几个构造器就有几个 init() 方法
    • init() 方法由非静态实例变量显示赋值代码和非静态代码块,对应构造器代码组成
    • 非静态实例变量显示赋值代码和非静态代码块从上到下顺序执行,而对应构造器的代码最后执行
    • 每次创建实例对象,调用对应构造器,执行的就是对应的 ini方法
    • init 方法的首行是super()和super(实参列表) ,即对应父类的 init 方法

    父类非静态属性>父类非静态代码块>父类构造器>子类非静态属性>子类非静态代码块>子类构造器

    整个步骤

    父类静态属性(成员变量)>父类静态代码块>子类静态属性>子类静态代码块>父类非静态属性>父类非静态代码块>父类构造器>子类非静态属性>子类非静态代码块>子类构造器

    3. 重载和重写

    ① 哪些方法不可以被重写

    • final方法
    • 静态方法
    • private等子类中不可见方法

    ②对象的多态性

    • 子类如果重写了父类的方法,通过子类对象调用的一定是子类重写过的代码
    • 非静态方法默认的调用对象是this
    • this对象在构造器或者说方法中就是正在创建的对象

    示例代码:
    Father.java

    package com.atguigu.classLoader;
    
    /**
     * 父类初始化<clinit>
     * 1、j = method()
     * 2、 父类的静态代码块
     *
     * 父类实例化方法:
     * 1、super()(最前)
     * 2、i = test() (9)
     * 3、子类的非静态代码块 (3)
     * 4、子类的无参构造(最后)(2)
     *
     *
     * 非静态方法前面其实有一个默认的对象this
     * this在构造器或<init> 他表示的是正在创建的对象,因为咱们这里是正在创建Son对象,所以
     * test()执行的就是子类重写的代码(面向对象多态)
     *
     * 这里i=test() 执行的就是子类重写的test()方法
     * @author gcq
     * @Create 2020-09-25
     */
    public class Father {
        private int i = test();
        private static int j = method();
    
        static{
            System.out.println("(1)");
        }
        Father() {
            System.out.println("(2)");
        }
        {
            System.out.println("(3)");
        }
        public int test(){
            System.out.println("(4)");
            return 1;
        }
        public static int method() {
            System.out.println("(5)");
            return 1;
        }
    }
    

    Son.java

    package com.atguigu.classLoader;
    
    /**
     * 子类的初始化<clinit>
     * 1、j = method()
     * 2、子类的静态代码块
     *
     * 先初始化父类 (5)(1)
     * 初始化子类 (10) (6)
     *
     * 子类实例化方法:
     * 1、super()(最前
     * 2、i = test() (9)
     * 3、子类的非静态代码块 (8)
     * 4、子类的无参构造(最后)(7)
     * @author gcq
     * @Create 2020-09-25
     */
    public class Son extends Father {
        private int i = test();
        private static int j = method();
        static {
            System.out.println("(6)");
        }
        Son() {
            super();
            System.out.println("(7)");
        }
        {
            System.out.println("(8)");
        }
        public int test(){
            System.out.println("(9)");
            return 1;
        }
        public static int method() {
            System.out.println("(10)");
            return 1;
        }
    
        public static void main(String[] args) {
            Son son = new Son();
            System.out.println();
            Son son1 = new Son();
        }
    }
    

    执行结果

    (5)(1)(10)(6)(9)(3)(2)(9)(8)(7)
    
    (9)(3)(2)(9)(8)(7)
    

    4. 方法参数传递机制

    package com.atguigu.methodParam;
    
    import java.util.Arrays;
    
    /**
     * @author gcq
     * @Create 2020-09-28
     */
    public class Exam4 {
        public static void main(String[] args) {
            int i = 1;
            String str = "hello";
            Integer num = 200;
            int[] arr = {1,2,3,4,5};
            MyData my = new MyData();
    		//arr和my变了
            change(i,str,num,arr,my);
    
            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("my.a= " + my.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;
    
    }
    

    结果

    i= 1
    str= hello
    num= 200
    arr= [2, 2, 3, 4, 5]
    my.a= 11
    

    考点?
    方法的参数传递机制

    String、包装类等对象的不可变性
    在这里插入图片描述

    方法的参数传递机制
    1、形参是基本数据类型

    • 传递数据值
      2、实参是引用数据类型​
    • 传递地址值

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

    5. 成员变量与局部变量

    在这里插入图片描述
    ​ 局部变量:栈

    ​ 实例变量:堆

    ​ 类变量:方法区
    在这里插入图片描述
    堆(Heap) ,此内存区域的唯一目的就是存放对象实例,几乎所有的对象实例都在这里分配内存。这一点在Java虚拟机规范中的描述是:所有的对象实例以及数组都要在堆上分配。

    通常所说的栈(Stack) ,是指虚拟机栈。虚拟机栈用于存储局部变量表等。局部变量
    表存放了编译期可知长度的各种基本数据类型(boolean、byte、 char、short、 int、 float、long、double) 、对象引用(reference 类型,它不等同于对象本身,是对象在堆内存的首地址)。方法执行完, 自动释放。
    方法区(Method Area)用于存储已被虛拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。

    二、SSM面试题

    1. spring

    1. 事物的传播行为

    事务的传播行为
    当事务方法被另一个事务方法调用时,必须指定事务应该如何传播,列如方法可能继续在现有事务中运行,也可能开启一个新事务,并在自己的事务中运行,事务传播的行为有传播属性指定,Spring定义了7中类传播行为

    传播属性描述
    REQUIRED如果有事务在运行,当前的方法就在这个事务内运行,否则就启动一个新的事务,并在自己的事务内运行
    REQUIRED_NEW当前方法必须启动事务,并在它自己的事务内运行,如果有事务正在运行,应该将他挂起
    SUPPORTS如果有事务在运行,REQUIRED_NEW当前的方法就在这个事务内运行,否则他可以不运行在事务中
    NOT_SUPPORTS当前的方法不应该运行在事务中,如果有运行的事务,将他挂起
    MANDATORY当前的方法必须运行在事务内部,如果没有正在运行的事务,就抛出异常
    NEVER当前方法不应该运行在事务中,如果有运行的事务,就抛出异常
    NESTED如果有事务在运行,当前的方法就应该在这个事物的嵌套事务内运行,否则,就启动一个新的事务,并在它自己的事务内运行

    事务传播属性可以在@Transactional注解的propagation属性中定义

    2. 事物的隔离级别

    2.1 数据库事务并发问题

    假设现在有两个事务:Transaction01和Transaction02并发执行。

    1) 脏读

    ①Transaction01将某条记录的AGE值从20修改为30。

    ②Transaction02读取了Transaction01更新后的值:30。

    ③Transaction01回滚,AGE值恢复到了20。

    ④Transaction02读取到的30就是一个无效的值。

    2) 不可重复读

    ①Transaction01读取了AGE值为20。

    ②Transaction02将AGE值修改为30。

    ③Transaction01再次读取AGE值为30,和第一次读取不一致。

    3) 幻读

    ①Transaction01读取了STUDENT表中的一部分数据。

    ②Transaction02向STUDENT表中插入了新的行。

    ③Transaction01读取了STUDENT表时,多出了一些行。

    2.2 隔离级别

    数据库系统必须具有隔离并发运行各个事务的能力,使它们不会相互影响,避免各种并发问题。一个事务与其他事务隔离的程度称为隔离级别。SQL标准中规定了多种事务隔离级别,不同隔离级别对应不同的干扰程度,隔离级别越高,数据一致性就越好,但并发性越弱。

    1. 读未提交:READ UNCOMMITTED

    允许Transaction01读取Transaction02未提交的修改。

    1. 读已提交:READ COMMITTED

    要求Transaction01只能读取Transaction02已提交的修改。

    1. 可重复读:REPEATABLE READ

    确保Transaction01可以多次从一个字段中读取到相同的值,即Transaction01执行期间禁止其它事务对这个字段进行更新。

    1. 串行化:SERIALIZABLE

    确保Transaction01可以多次从一个表中读取到相同的行,在Transaction01执行期间,禁止其它事务对这个表进行添加、更新、删除操作。可以避免任何并发问题,但性能十分低下。

    1. 各个隔离级别解决并发问题的能力见下表

    在这里插入图片描述

    SpringMvc

    整体流程

    SpringMVC框架是一个基于请求驱动的Web框架,并且使用了‘前端控制器’模型来进行设计,再根据‘请求映射规则’分发给相应的页面控制器进行处理。在这里插入图片描述
    具体步骤:

    1、 首先用户发送请求到前端控制器,前端控制器根据请求信息(如 URL)来决定选择哪一个页面控制器进行处理并把请求委托给它,即以前的控制器的控制逻辑部分;图中的 1、2 步骤;

    2、 页面控制器接收到请求后,进行功能处理,首先需要收集和绑定请求参数到一个对象,这个对象在 Spring Web MVC 中叫命令对象,并进行验证,然后将命令对象委托给业务对象进行处理;处理完毕后返回一个 ModelAndView(模型数据和逻辑视图名);图中的 3、4、5 步骤;

    3、 前端控制器收回控制权,然后根据返回的逻辑视图名,选择相应的视图进行渲染,并把模型数据传入以便视图渲染;图中的步骤 6、7;

    4、 前端控制器再次收回控制权,将响应返回给用户,图中的步骤 8;至此整个结束。
    在这里插入图片描述
    具体步骤:

    第一步:发起请求到前端控制器(DispatcherServlet)

    第二步:前端控制器请求HandlerMapping查找 Handler (可以根据xml配置、注解进行查找)

    第三步:处理器映射器HandlerMapping向前端控制器返回Handler,HandlerMapping会把请求映射为HandlerExecutionChain对象(包含一个Handler处理器(页面控制器)对象,多个HandlerInterceptor拦截器对象),通过这种策略模式,很容易添加新的映射策略

    第四步:前端控制器调用处理器适配器去执行Handler

    第五步:处理器适配器HandlerAdapter将会根据适配的结果去执行Handler

    第六步:Handler执行完成给适配器返回ModelAndView

    第七步:处理器适配器向前端控制器返回ModelAndView (ModelAndView是springmvc框架的一个底层对象,包括 Model和view)

    第八步:前端控制器请求视图解析器去进行视图解析 (根据逻辑视图名解析成真正的视图(jsp)),通过这种策略很容易更换其他视图技术,只需要更改视图解析器即可

    第九步:视图解析器向前端控制器返回View

    第十步:前端控制器进行视图渲染 (视图渲染将模型数据(在ModelAndView对象中)填充到request域)

    第十一步:前端控制器向用户响应结果

    总结核心开发步骤
    1、 DispatcherServlet 在 web.xml 中的部署描述,从而拦截请求到 Spring Web MVC

    2、 HandlerMapping 的配置,从而将请求映射到处理器

    3、 HandlerAdapter 的配置,从而支持多种类型的处理器

    注:处理器映射求和适配器使用纾解的话包含在了注解驱动中,不需要在单独配置

    4、 ViewResolver 的配置,从而将逻辑视图名解析为具体视图技术

    5、 处理器(页面控制器)的配置,从而进行功能处理

    View是一个接口,实现类支持不同的View类型(jsp、freemarker、pdf…)
    在这里插入图片描述

    Mybatis

    实体类中的属性名和表中的字段不一样,怎么办
    解决方案:

    1、写 SQL 语句的时候 写别名

    2、在MyBatis的全局配置文件中开启驼峰命名规则

    <!-- 开启驼峰命名规则,可以将数据库中下划线映射为驼峰命名
    	列如 last_name 可以映射为 lastName
    -->
    <setting name="mapUnderscoreToCameLCase" value="true" />
    
  • 相关阅读:
    程序界真正的高帅富团体:Valve
    How Unreal Engine 4 Will Change The Next Games You Play【纯搬运】
    互联网“百年老店”是彻头彻尾的扯淡!
    如何关闭VS10中的IntelliSense
    发人深省周鸿祎:少功利多学习 做力所能及的事情
    FlashCS4 快捷键大全
    《1万小时成功定律——解构成功》
    通过AutoExpand调试Unreal内置数据类型
    14 Ways to Motivate Yourself
    关于C++ 动态定义数组
  • 原文地址:https://www.cnblogs.com/idcode/p/14551355.html
Copyright © 2011-2022 走看看