面试题专题-决战2022

本文是针对Java面试的专题,涵盖了Java基础,如面向对象特性、集合、多线程、JVM内存模型,以及Spring、MyBatis、SpringBoot等框架的深入讲解,包括类加载机制、设计模式、数据库相关知识,还涉及了RabbitMQ和Kafka的消息处理和特性。文章旨在帮助读者巩固基础知识,为面试做好准备。
摘要由CSDN通过智能技术生成

天上飘来4个字,offer不是事!!

  • java基础

  • spring & springMVC

  • mybatis、mybatisplus

  • springboot & springcloudAlibaba

  • redis & mongodb & mysql

  • rabbitmq & kafka

  • docker & linux

一:java基础

1.1:java 面向对象三大特性(封装,继承,多态)?

封装:隐藏对象的属性和实现细节,仅对外公开接口,增强安全性和简化编程,使用者不必了解具体的实现细节,而只是要通过外部接口,一特定的访问权限来使用类的成员

继承:实现代码的复用,但特别注意的是,父类的私有属性和构造方法并不能被继承。另外子类可以写自己特有的属性和方法,目的是实现功能的扩展,子类也可以复写父类的方法即方法的重写。子类不能继承父类中访问权限为private的成员变量和方法

多态:相同的事物,调用其相同的方法,参数也相同时,但表现的行为却不同,例如方法重写重载。

1.2:抽象类和接口的区别?

1、接口可以多实现,而抽象类只能单继承
2、抽象类可以有非抽象的方法和构造方法、变量,但是接口只能有抽象方法,静态常量。
3、抽象类和子类具有父子关系,子类能拥有父类中一些属性。接口虽然某个类实现一个接口,但是由于接口中的变量都为静态常量,

​ 不存在继承关系。

1.3: 重写和重载?

重载: 在同一个类中,方法名必须相同,参数类型、个数、顺序不同,与返回值类型,访问修饰符无关,发生在编译时。

重写: 发生在父子类中,方法名、参数列表必须相同,返回值范围小于等于父类,抛出的异常范围小于等于父类,访问修饰符范围大于等于父类;如果父类方法访问修饰符为 private 则子类就不能重写该方法。

1.4 :String、StringBuffer、StringBuilder的区别?

可变性:三个都是处理字符串的方法,String底层使用final修饰了,所以是不可变的;StringBuilder 与 StringBuffer是可变的字符串;

安全性:String 中的对象是不可变的,也就可以理解为常量,线程安全。StringBuffer 对方法加了同步锁,所以是线程安全的。StringBuilder 并没有对方法进行加同步锁,所以是不线程安全

性能:每次对 String 类型进行改变的时候,都会生成一个新的 String 对象,然后将指针指向新的String 对象,修改内容时性能低。StringBuffer、StringBuilder 每次都会对对象本身进行操作,而不是生成新的对象并改变对象引用;StirngBuilder的效率会高一些,而StringBuffer的底层加了同步的关键字,性能会有所下降

所以呢,一般我们操作少量的字符串的时候用String ,在单线程环境下操作大量数据时使用StringBuilder,在多线程操作大量数据使用StringBuffer。

1.5:java中的集合?

java 中的集合分为单列集合和双列集合,单列集合顶级接口为 Collection,双列集合顶级接口为 Map。

Collection 的子接口有两个:List 和 Set。

Ø List 接口的特点:元素可重复,有序(存取顺序)。 list 接口的实现类如下:

​ Ø ArrayList:底层实现是数组,查询快,增删慢,线程不安全,效率高;

​ Ø Vector:底层实现是数组,查询快,增删慢,线程安全,效率低;【废弃】

​ Ø LinkedList:底层实现是链表,增删快,查询慢,线程不安全,效率高;

Ø Set 接口的特点:元素唯一,不可重复,无序。 Set 接口实现类如下:

​ Ø HashSet:底层实现 hashMap,数组+链表实现,不允许元素重复,无序。

​ Ø TreeSet:底层实现红黑二叉树,实现元素排序

Ø Map 接口的特点:key-value 键值对形式存储数据 Map 接口实现类如下:

​ Ø HashMap:底层数组+链表实现,线程不安全效率高;

​ Ø TreeMap:底层红黑二叉树实现,可实现元素的排序;

​ Ø LinkedHashMap:底层hashmap+linkedList 实现,通过 hashmap 实现 key-value 键值对存储,通过链表实现元素有序。

1.6:ArrayList和Linkedlist区别?

相同点:

1、二者都是 List 接口的实现类,具有元素可重复,有序(存取顺序)特点;

2、二者都是线程不安全,效率高;

不同点:

1、数据结构:ArrayList底层数据结构是动态数组,LinkedList底层数据结构是双向链表;

2、随机访问效率:ArrayList比 LinkedList 在随机访问的时候效率要高,因为LinkedList 是线性的数据存储方式,所以需要移动指针从前往后依次查找。

3、增加和删除效率:在非首尾的增加和删除操作,LinkedList 要比ArrayList 效率要高,因为ArrayList 增删操作要影响数组内的其他数据的下标。

综合来说,在需要频繁读取集合中的元素时,更推荐使用 ArrayList,而在插入和删除操作较多时,更推荐使用LinkedList。

1.7:HashMap底层原理?

HashMap 底层是数组+链表(LinkedList)实现,hashMap 默认初始化容量为 16,也就 是说数组索引值为0-15,每个数组中存储一个链表。jdk1.8后当hash表的单一链表长度超过 8 个的时候,链表结构就会转为红黑树结构;当 hashmap 空间使用达到 0.75 后,会对数组进行扩容,新建数组,然后将元素拷 贝到新的数组中,每次扩容翻倍;在存储元素时有可能发生 hash 碰撞现象(即两个元素不相同,却有一样的 hash 值),这样的话,就将元素在数组中存入链表中,以链表的形式进行元素的存储,第一个entry 存在链表顶端,再有hash 值一致的entry 存入,则链接在第一个元素之后。

1.8:Java 到底是值传递还是引用传递?

Java 只支持值传递。
Java 程序员之所以容易搞混值传递和引用传递,主要是因为 Java 有两种数据类型,一种是基本类型,比如说 int,另外一种是引用类型,比如说 String或对象。
基本类型的变量存储的都是实际的值,而引用类型的变量存储的是对象的引用——指向了对象在内存中的地址。值和引用存储在 stack(栈)中,而对象存储在 heap(堆)中。

1.9:== 和equals有什么区别?

:判断两个对象是不是内存中同一个对象。但如果有基本数据类型参与比较,无论是基本数据类型相互比较,还是基本数据和他们的封装类比较,都比较的是值,引用数据类型之间比较的是内存地址。

equals():作用也是判断两个对象是否相等。但它一般有两种使用情况,一种这个类没有重写equals() 方法。则通过 equals() 比较该类的两个对象时,等价于通过“==”比较这两个对象。

另一种就是类重写了 equals() 方法,重写了之后就按照重写的逻辑来判断了。

一般,我们都覆盖 equals() 方法来比较两个对象的内容相等;若它们的内容相等,就认为两个对象是相等的。

1.10:java的类加载机制?

加载
ClassLoader通过一个类的完全限定名查找此类字节码文件,并利用字节码文件创建一个class对象。

验证
目的在于确保class文件的字节流中包含信息符合当前虚拟机要求,不会危害虚拟机自身的安全,主要包括四种验证:文件格式的验证,元数据的验证,字节码验证,符号引用验证。

准备
为类变量(static修饰的字段变量)分配内存并且设置该类变量的初始值,(如static int i = 5 这里只是将 i 赋值为0,在初始化的阶段再把 i 赋值为5),这里不包含final修饰的static ,因为final在编译的时候就已经分配了。这里不会为实例变量分配初始化,类变量会分配在方法区中,实例变量会随着对象分配到Java堆中。

解析
这里主要的任务是把常量池中的符号引用替换成直接引用

初始化
这里是类记载的最后阶段,如果该类具有父类就进行对父类进行初始化,执行其静态初始化器(静态代码块)和静态初始化成员变量。(前面已经对static 初始化了默认值,这里我们对它进行赋值,成员变量也将被初始化)

1.11:java的类加载顺序?

1:所有的类都会优先加载基类;
2:静态成员的初始化优先;
3:成员初始化后,才会执行构造方法;

4:静态成员的初始化与静态块的执行,发生在类加载的时候;成员加载在对象创建时;类对象的以及静态块的访问,都会触发类的加载。

1.12: 手写排序算法?

//冒泡排序
public void bubbleSort(int []a){
   
           int len=a.length;
           for(int i=0;i<len;i++){
   
               for(int j=0;j<len-i-1;j++){
   
                   if(a[j]>a[j+1]){
   
                       int temp=a[j];
                       a[j]=a[j+1];
                       a[j+1]=temp;
                   }
               }
           }
       }

//选择排序
public void selectSort(int[]a){
   
        int len=a.length;
        for(int i=0;i<len;i++){
   //循环次数
            int value=a[i];
            int position=i;
            for(int j=i+1;j<len;j++){
   //找到最小的值和位置
                if(a[j]<value){
   
                    value=a[j];
                    position=j;
                }
            }
            a[position]=a[i];//进行交换
            a[i]=value;
        }
    }

1.13:设计模式

单例模式是保证一个类仅有一个实例,并自行提供访问该实例全局访问点的创建型模式。

//懒汉式(线程安全)
public class Singleton {
     
     private static Singleton instance;     
     private Singleton (){
   }         
     public static synchronized Singleton getInstance() {
   //加线程锁
        if (instance == null) {
                    //判断如果没有实例              
            instance = new Singleton();         //新建一个实例
        }  
         return instance;                   //返回实例
     }  
}

工厂模式是为创建对象提供过渡接口,根据用户需求动态创建实例的设计模式。我们项目中接入短信服务是接入的是厂家或第三方的短信渠道ÿ

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

天天向上的雨辰

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值