几道最基础面试题

几道最基础面试题

  • 一、方法的参数传递
    •    1、值传递与引用传递的理解
    •    2、方法传参是否会修改值
  • 二、== 与 equals
    •    1、== 与 equals 的使用要求
    •    2、== 与 equals 的对比
  • 三、String 的各类比较
    •    1、String 的存放
    •    2、String 的 intern 方法
    •    3、String 的各类比较
  • 四、代码块与构造方法的执行顺序
    •    1、普通代码块的概念与执行顺序
    •    2、构造代码块与构造方法的执行顺序
    •    3、静态代码块、构造代码块、构造方法的优先级
  • 五、linux的常用命令
    •    1、top:查看整体机器性能
    •    2、uptime:简化版的查看整体机器性能
    •    3、free -m:查看内存情况
    •    4、df -h:查看硬盘情况
    •    5、vmstat -n 2 3:查看CPU情况,每2秒一次,显示3条记录
    •    6、iostat - xdk 2 3:查看磁盘io情况
    •    7、chmod:权限命令
    •    8、ifconfig:查看ip
  • 六、Spring 的 bean作用域
  • 七、Spring支持的常用数据库事务传播行为与隔离级别
    •    1、传播行为
    •    2、数据库事务并发可能出现的问题
    •    3、隔离级别
  • 八、SpringMVC 大概的工作流程
  • 九、Mybatis 中实体类属性名和数据表字段名不一致的解决办法
    •    1、sql 语句中对字段名进行起别名
    •    2、在 Mybatis 的全局配置文件中开启驼峰形式
    •    3、在 Mapper 映射文件中使用 resultMap 来自定义映射规则
  • 十、Redis持久化的基础
    •    1、RDB 持久化
    •    2、AOF 持久化
  • 十一、Mysql 的索引创建时机
    •    1、索引的本质
    •    2、哪些情况需要创建索引
    •    3、哪些情况不要创建索引
  • 十二、JVM 垃圾回收机制的基础
    •    1、发生在哪个部分:堆
    •    2、gc 有几种:minor gc;full gc
    •    3、gc 的算法:
  • 十三、Redis在项目中的使用场景

一、方法的参数传递

   1、值传递与引用传递的理解

     个人认为:不存在引用传递,均是值传递

   2、方法传参是否会修改值

     如下图所示代码:
几道最基础面试题_第1张图片
     对应的输出结果是:
几道最基础面试题_第2张图片
    值传递: 传的是值的副本
    局部变量的作用域: 局部变量随着方法而产生,也随着方法而销毁
    引用类型的修改: 修改的是堆中的数据值
    String类型的存放: 存放于字符串常量池被final修饰
    String类型的修改: 先判断字符串常量池中,有没有修改后的值?有的话,直接指向原有的值;没有的话,再创建一个,指过去(其实就是修改了地址值

    基础类型的包装类: 方法传参中,具有不可变性

     解析代码:
       main方法中: age变量的 值是20
              personName变量的 值是地址值(“abc”在堆中的地址值)
              str变量的 值是地址值(“abc”在堆中的地址值)
       changeValue1方法中: age变量只是一个副本,原值是20,修改后是30 (基本类型)
                  但是在方法销毁后,这个age变量也被销毁,也就是这个副本被销毁
                  而main方法中的原件变量值并没有被修改
       changeValue2方法中: personName变量只是一个副本,修改时是修改了地址值所指向堆中的数据值 (引用类型)
                  堆中的原值是“abc”,修改后是“xxx”,但是其地址值没变
                  但是在方法销毁后,这个personName变量也被销毁,也就是这个副本被销毁
                  而main方法中的原件变量值并没有被修改,还是原来的地址值,此时该地址值指向的堆中数据却被修改了
       changeValue3方法中: str变量只是一个副本,修改时是修改了地址值 (String类型)
                  原值是“abc”在字符串常量池中的地址值,修改后是“xxx”在字符串常量池中的地址值
                  但是在方法销毁后,这个str变量也被销毁,也就是这个副本被销毁
                  而main方法中的原件变量值未被修改,还是那个地址值,此时该地址值指向字符串常量池中的数据未被修改

二、== 与 equals

   1、== 与 equals 的使用要求

     == : 可使用于基本类型,也能使用于引用类型
     equals : 只能使用于引用类型

   2、== 与 equals 的对比

     如图所示代码:
几道最基础面试题_第3张图片
     对应的结果为:
几道最基础面试题_第4张图片
    解析代码:
     == : 比较的就是 栈中变量的值 ;如果是 基本类型 ,就是比较数据值;如果是 引用类型 ,就是比较地址值
        凡是 new出来的对象栈中变量的值都是地址值;而 不同的new对象地址值是不一样的,所以 == 比较百分百是false
     equals: 属于Object类的方法;Object类中对其的实现就是用了 ==
          所以只要一个类 没有重写equals方法 ,那么就等同于 ==
          String类, 重写了equals方法 ,而且是 比较数据值的hashCode值
          String类,重写了hashCode方法只要数据值一样,hashCode值就一样
          所以String变量中,只要 数据值一样 ,用equals方法比较就肯定是true
     HashSet : 根据hashCode值比较是否是同一个值new出来的对象,hashCode值都不一样除非重写了hashCode方法
           String类,重写了hashCode方法只要数据值一样,hashCode值就一样

     所以上述代码中,结果如图所示

三、String 的各类比较

   1、String 的存放

     在 jdk1.8 之前,字符串常量池在方法区中;为了减小方法区内存溢出风险,在 jdk1.8 之后 就把常量池移到java 堆中

     String s = "abc":创建的对象,存储在字符串常量池中;在创建字符串对象之前,会先在 常量池中检查是否存在 abc 对象 ;存在,则直接返回常量池中 abc 对象的引用;不存在,会在常量池中创建该对象并将常量池中该对象的引用返回给对象 s
       简单来说,就是String s = ""创建的局部变量 s,其值是字符串常量池的地址值

     String s = new String("abc"):实际上 abc 本身就是字符串常量池中的一个对象,在运行 new String() 时,把常量池中的字符串 abc 复制到堆中;因此该方式 会在堆和常量池中都创建 abc 字符串对象最后把 java 堆中对象的引用返回给 s
       简单来说,就是String s = new String("")创建的局部变量 s,其值是堆的地址值

   2、String 的 intern 方法

     调用 String 的 intern 方法 时,先 判断字符串常量池中是否已经有对应的字符串(通过 String 的 equals 方法比较);有的话,则直接返回常量池中对应的地址值;没有的话,就先在常量池中创建,再返回常量池中对应的地址值
     所以:对于任意两个字符串 s 和 t ,s.intern() == t.intern()比较;仅当s.equals(t)为true时,才为true
       简单来说,就是String s = s.intern()创建的局部变量 s,其值是字符串常量池的地址值

   3、String 的各类比较

     如图所示代码:
几道最基础面试题_第5张图片
几道最基础面试题_第6张图片
     对应的结果为:
几道最基础面试题_第7张图片
     解析: 上述代码中,栈中局部变量
       s1的值是 字符串常量池 的地址值,s2的值是 的地址值;所以两个地址值不一样
       s1和s5的 字符串值都不一样 了,字符串常量池中的地址值肯定也不一样
       s1和s6的 字符串值都不一样 了,字符串常量池中的地址值肯定也不一样
       s1和s6.intern()的 字符串值都不一样 了,字符串常量池中的地址值肯定也不一样
       s2的值是 的地址值,s2.intern()的值是 字符串常量池 的地址值;所以两个地址值不一样

四、代码块与构造方法的执行顺序

   1、普通代码块的概念与执行顺序

     如图所示代码:
几道最基础面试题_第8张图片
     对应的结果为:
几道最基础面试题_第9张图片
     普通代码块: 在方法或语句中出现的{...};就称为普通代码块;普通代码块可以多次执行

     普通代码块的执行顺序: 两部分普通代码块,执行顺序是“先出先执行”

   2、构造代码块与构造方法的执行顺序

     1)构造代码块的 概念
       直接在类中定义且 没有用static修饰、没有名字{...}代码块;称为构造代码块;构造代码块可以 多次执行

     2)构造代码块的 执行顺序
       两部分构造代码块,执行顺序是“先出先执行”

     3)构造代码块的 执行时机
       构造代码块在每次创建对象时都会被调用;是在构造方法方法中的隐式调用在隐式调用父类构造方法之后

     4)构造代码块与构造方法的优先级
       如图所示代码:
几道最基础面试题_第10张图片
       对应的结果为:
几道最基础面试题_第11张图片
       解析: 构造代码块优先于构造方法

   3、静态代码块、构造代码块、构造方法的优先级

     1)静态代码块、构造代码块、构造方法的 优先级
       静态代码块 > 构造代码块 > 构造方法
       静态代码块只执行一次;构造代码块和构造方法可多次执行

     2)无继承情况例子说明
       如图所示代码:
几道最基础面试题_第12张图片
在这里插入图片描述
       对应的结果为:
几道最基础面试题_第13张图片
       解析:
         (1)在运行CodeBlock03的 main方法前,生成CodeBlock03的模板,此时运行了CodeBlock03的静态代码块
         (2)之后运行CodeBlock03的main方法
         (3)调用Code的构造方法,需要 先生成Code的模板,才能调用构造方法;此时优先运行了Code的静态代码块
         (4)运行完Code的静态代码块之后,需要先运行Code的构造代码块
         (5)运行完Code的构造代码块之后,才能运行Code的构造方法

         之后的调用,由于 静态代码块只执行一次 ,所以在原本的顺序下,踢出静态代码块即可

     3)有继承情况例子说明
       如图所示代码:
几道最基础面试题_第14张图片
几道最基础面试题_第15张图片
       对应的结果为:
几道最基础面试题_第16张图片
       解析:
         (1)运行TestStaticSeq的main方法
         (2)调用子类的构造方法,需要 先生成父类的模板,才能生成子类的模板;此时优先运行了父类的静态代码块
         (3)生成父类的模板后,要先生成子类的模板;才能运行子类的构造方法,此时优先运行了子类的静态代码块
         (4)运行子类构造方法,先 调用父类构造方法(隐式);调用父类构造方法,需先运行父类构造代码块
         (5)运行了父类构造代码块之后,才会运行父类的构造方法
         (6)在子类构造方法中,调用完父类构造方法后(隐式),会调用子类的构造代码块
         (7)运行完子类的构造代码块之后,才会运行子类的构造方法

         之后的调用,由于 静态代码块只执行一次 ,所以在原本的顺序下,踢出静态代码块即可

     4)构造方法的 隐式三步
       在 调用一个类的构造方法时(无论是无参还是有参) ,都会有一个隐式三步
         (1)调用父类的构造方法(无参调无参,有参调有参)
         (2)给非静态成员变量赋予显示值
         (3)调用自身的构造代码块

       具体如下:下面代码中,1、2、3步就是隐式3步最后还有一个隐式 return 返回

     注意: 隐式三步的第二步和第三步是不固定的,哪个写前面就先哪个

public class Father{

    private int id = 007;
    private String name = "零零发";
    private int age = 98;
    private float height = 1.78F;

    public Teacher() {
        // 1、super();  调用父类的构造方法(无参调无参,有参调有参)

		// 2、id = 007;  给非静态成员变量赋予显示值(在JVM内存程度上,真正的关联变量名和变量值)
			.
			.
			.
			
		// 3、{...}  调用自身的构造代码块

		...  // 自己手写的代码

		// return;  隐式返回
    }

五、linux的常用命令

   1、top:查看整体机器性能

     进程和程序,看看哪个进程占比较高
     %CPU:CPU使用占比
     %MEM:内存使用占比
     %Cpu(s):Cpu使用情况(在多核机器时,可通过连按6次1键;来查看每个CPU的使用情况
       id:idle,空闲率(越大越好)
     load average:负载的平均数;如果有三个数,就是 1分钟、5分钟、15分钟的系统平均负载量
       三个数相加,除以3,乘以百分百;如果高于60%,说明系统负载严重
     按键 q,退出

   2、uptime:简化版的查看整体机器性能

     一样有 load average

   3、free -m:查看内存情况

     free: 按字节展示,自己的换算
     free -g: 以 g 为单位展示,没小数;所以误差比较大
     所以:建议使用free -m

   4、df -h:查看硬盘情况

     df: 按字节展示,自己的换算
     所以:建议使用df -h

   5、vmstat -n 2 3:查看CPU情况,每2秒一次,显示3条记录

     看头的进程数,看尾的CPU使用情况

   6、iostat - xdk 2 3:查看磁盘io情况

     看最后的 %util ,说明磁盘IO高,可能需要进行SQL语句优化

   7、chmod:权限命令

   8、ifconfig:查看ip

六、Spring 的 bean作用域

   Spring 的 bean 有 4种 作用域,分别是:singleton、prototype、request、session
     1、singleton: 单例的作用域,默认值;在 初始化 IOC 容器时 创建对应的唯一的bean,之后再也不创建

     2、prototype: 原型的作用域;这里的原型指的是每一个 getBean() 方法都会创建自己的bean

     3、request: 每一次请求都会实例化一个bean

     4、session: 每一个会话都会实例化一个bean
   通过 scope 属性进行指定

七、Spring支持的常用数据库事务传播行为与隔离级别

   1、传播行为

     1)传播行为的理解: 当一个方法调用另一个方法时,两个方法均有事务时,对多个事务的处理机制

     2)传播行为的类型:7种 传播行为,但是 常用的就两种required、requires_new

     3)传播行为的设置: 通过 propagation 属性进行指定

   2、数据库事务并发可能出现的问题

     1)脏读: 线程A在修改数据库,线程B读取了修改后的值进行后续操作;线程A却发生了 回滚 ,线程B读取的数据就是脏读

     2)不可重复读: 线程A读取了一次数据,线程B修改了这个数据,线程A再次读取时,出现两次读取不一致

     3)幻读: 线程A读取了数据行,线程B增加或删除了n行,线程A再次读取数据行时,出现两次读取行数不一致

   3、隔离级别

     1)隔离级别的理解: 针对 第2点的三种问题 的处理级别

     2)隔离级别的类型:4种 传播行为
       (1)read uncommitted:读未提交
       (2)read committed:读已提交
       (3)repeatable read:可重复读
       (4)serializable:串行化
     由于 隔离级别越高数据一致性越好,但并发性越差
     所以 常用的就两种read committed、repeatable read

     3)隔离级别的设置: 通过 isolation 属性进行指定

     4)Oracle 和 Mysql 对隔离级别的支持情况:
几道最基础面试题_第17张图片

八、SpringMVC 大概的工作流程

几道最基础面试题_第18张图片

九、Mybatis 中实体类属性名和数据表字段名不一致的解决办法

   1、sql 语句中对字段名进行起别名

   2、在 Mybatis 的全局配置文件中开启驼峰形式

   3、在 Mapper 映射文件中使用 resultMap 来自定义映射规则

十、Redis持久化的基础

   1、RDB 持久化

     在 指定的时间间隔 内,将内存中的数据集快照写入磁盘
     恢复时,直接将快照文件读到内存中
几道最基础面试题_第19张图片
     优点: 节省磁盘空间;恢复速度快
     缺点: 数据庞大时比较消耗性能;有可能会丢失最后一次快照之后的数据

   2、AOF 持久化

     以日志的方式来记录每个写操作,只追加文件不改写文件
     Redis启动之初会读取该文件重新构建数据;也就是Redis重启时,根据日志文件内容从前至后执行一次,已完成恢复工作
     优点: 备份机制更稳健;丢失数据概率更低;可以处理误操作
     缺点: 比RDB占用更多的磁盘空间;恢复速度慢;每次读写都同步的话,有一定性能压力;存在个别bug,没办法恢复

十一、Mysql 的索引创建时机

   1、索引的本质

几道最基础面试题_第20张图片

   2、哪些情况需要创建索引

     1)主键自动创建唯一索引

     2)频繁作为查询条件的字段

     3)与其他表关联的字段(外键关系)

     4)查询中需要统计或者分组的字段

     5)查询中需要排序的字段

     6)单键索引和组合索引,组合索引的性价比更高

   3、哪些情况不要创建索引

     1)表记录太少

     2)经常增删改的表或者字段

     3)查询条件中用不到的字段

     4)过滤性不好的字段

十二、JVM 垃圾回收机制的基础

   1、发生在哪个部分:堆

   2、gc 有几种:minor gc;full gc

   3、gc 的算法:

     1)引用计数算法:
几道最基础面试题_第21张图片

     2)复制算法: 主要是 minor gc 在使用
几道最基础面试题_第22张图片

     3)标记清除算法: 主要是 full gc 在使用
几道最基础面试题_第23张图片

     4)标记压缩算法: 主要是 full gc 在使用
几道最基础面试题_第24张图片

     5)标记清除压缩算法: 主要是 full gc 在使用; 3)和4)的结合 ;先标记、后清除;等到内存碎片较多时,进行压缩

十三、Redis在项目中的使用场景

几道最基础面试题_第25张图片

你可能感兴趣的:(面试题,方法传参,比较方法,面试题,方法传参,比较方法,优先级,linux常用命令)