java基础面试题整理-2021

(一).什么是面向对象,谈谈你对面向对象的理解?
1.面向对象是一种思想,简单来说就是将数据和操作数据的方法封装在对象中。举个例子来说:比如洗衣机洗衣服。
我们通常会把这个拆分成两个对象----人和洗衣机。
人需要干的就是:打开洗衣机—放入衣服—放入洗衣液—按下各种开关
洗衣机则负责:清洗—烘干
2.面向对象拥有三大特性其实也可以说四大特性:封装–继承–多态–抽象
(1)相等于封装来说,就是把一切内部信息隐藏起来,对外不透明,只提供最简单的调用。
(2)继承是从已有的一个类得到信息并创建新类的过程,一般我们称这个提供信息的类为父类,得到信息的的类为子类。子类可以扩展自己的信息,按我自己的理解,继承就是一种信息复用,也是信息延申的一个手段。
(3)多态存在的必要三个条件就是继承,方法的重写,父类引用指向子类对象。就是多个子类继承一个父类,但是重新修改了分享信息的内容,然后通过同样的对象引用调用同样的方法,但是得出不同的信息。多态性其实还分为编译时多态性和运行时多态性,方法重载实现的是编译时多态性(也称为前绑定),方法重写实现的是运行时多态性(也成为后绑定)。
(4)我还在思考抽象算不算特性!!!!有人说仁者见仁,智者见智。可以是三种也可以是四种。

(二).==和equals的区别
1.首先,==是等于比较运算符,而equals是object里面的一个方法
2.==对于基本数据类型来说,比较的是值,对于引用数据类型来书,比较的是内存地址
3.equals默认情况下也是比较内存地址,但是我们一般会重写equals使其变为内容比较,即值比较。

(三) final 在 java 中有什么作用?
1.final修饰的类叫最终类,该类不能被继承
2.final修饰的方法不能被重写
3.final修饰的变量叫常量,常量必须初始化,知识化之后的值不能被修改。

package java_interviewtopic_01.stage01;

import java.util.ArrayList;
import java.util.List;

/**
 * 3.final
 */
public class Interview03 {
    // 使用final修饰的静态类变量需要再声明的时候就赋值或者在静态代码块赋值
    final static String i = "I";  // 声明时赋值
//    static {
//        i = "I";   // 在静态代码块中赋值
//    }

    // 使用final修饰的类变量需要再声明的时候就赋值或者在代码块赋值和构造函数的赋值
    final String j = "J";
//    {
//        j = "J";  // 在代码块中赋值
//    }

//    public Interview03(String j) {
//        this.j = j;  // 在构造函数中赋值
//    }

    public static void main(String[] args) {
        // 局部变量可以先声明后赋值,但是赋值之后也不能再更改了
        final String a;
        a = "abc";
        
        final List<Integer> list = new ArrayList<>();
        list.add(2);
        list.add(3);
        list.add(4);
        list.add(5);   // 可以看出内容可以变
        // list会爆红
        list = new ArrayList<>();   // 可以看出地址不能变了
    }
}


PS:当final修饰的变量是一个基本数据类型的时候,这个变量初始化之后的值不能再被更改。但是当final修饰的是一个引用数据类型的时候,该引用的内存地址不能再更改,但是该地址的内容可以改变
在这里插入图片描述

(四)java 中操作字符串都有哪些类?它们之间有什么区别?
1.String StringBuffer StringBuilder
2.三者共同之处:都是final类,不能被继承
3.StringBuffer与StringBuilder两者共同之处:可以通过append、indert进行字符串的操作。
4.再说这三个类的主要区别:其主要区别在两个方面,即运行速度和线程安全两个方面

1)先说运行速度,在这方面运行速度快慢为:StringBuilder > StringBuffer > String。String慢的原因:因为Stirng为字符常量,
而另外两个均为字符串变量。

2)String的课外补充:写个例子:Stirng a = "123"   再将a = a + "45"  这时打印出a = “12345”这个例子看似这个a被更改了。
其实不是,这只是一个假象而已。JVM对于这几行代码是这样处理的,首先创建一个String对象a。并把123赋值给a其实在a = a + "45"的时候,
JVM又创建了一个新的对象也名为a。然后再把原来的a的值和"45"加起来再赋值给新的a。而原来的a就会被回收机制给回收掉。所以,
a实际上并没有被更改,也就是前面说的String对象一旦创建之后不可更改了。

3)Java中对String对象进行的操作实际上是一个不断创建新的对象并且将旧的对象回收的一个过程,所以执行速度很慢。
而StringBuilder和StringBuffer的对象是变量,对变量进行操作就是直接对该对象进行更改,而不进行创建和回收的操作,
所以速度要比String快很多。

4)再说这个线程安全:StringBuilder是线程不安全的,而StringBuffer是线程安全的

5)如果一个StringBuffer对象在字符串缓冲区被多个线程使用时,StringBuffer中很多方法可以带有synchronized关键字,
所以可以保证线程是安全的,但StringBuilder的方法则没有该关键字,所以不能保证线程安全,有可能会出现一些错误的操作。
所以如果要进行的操作是多线程的,那么就要使用StringBuffer,但是在单线程的情况下,还是建议使用速度比较快的StringBuilder。

PS:总结一下:
1)String:适用于少量的字符串操作的情况
2)StringBuilder:适用于单线程下在字符缓冲区进行大量操作的情况
3)StringBuffer:适用多线程下在字符缓冲区进行大量操作的情况

(五) 重载(Overload)和重写(Override)的区别。重载的方法能否根据返回类型进行区分?

1.区别:方法的重载和重写都是实现多态的方式,区别在于前者实现的是编译时的多态性,而后者实现的是运行时的多态性
具体回答:重载发生在同一个类中,方法名一样,但是参数类型不一样,个数不一样,方法返回值和访问修饰符可以不同。
重写发生在父子类中,方法名,参数必须相同,返回值范围小于等于父类,抛出的异常范围小于等于父类,访问修饰符范围大于等于父类。

2.不能根据返回值类型来区分:这个时候如果出现这种情况:
float max ( int a , int b );
int max ( int a , int b );
编译器就不知道该调用哪个了。

(6)接口和抽象类有什么区别?
1抽象类和接口都不能直接实例化
2抽象类要被子类继承,接口要被类实现
3接口只能做方法申明,抽象类中可以做方法申明,也可以做方法实现
4接口里定义的变量只能是公共的静态的常量,抽象类中的变量是普通变量
5抽象类中有构造方法,接口类中没有
6接口和接口之间支持多继承,类和类之间只能单继承
7接口中只能有抽象方法,而抽象类里可以有方法体方法
8接口是设计的结果,抽象类是重构的结果。
9抽象类可以有具体的方法和属性,接口只能有抽象方法和不可变常量
10抽象类主要用来抽象类别,接口主要用来抽象功能。
11抽象类可以有 main 方法,并且我们能运行它;接口不能有 main 方法。
12接口中的方法默认使用 public 修饰;抽象类中的方法可以是任意访问修饰符。(private除外)
13它们的设计目的不一样,接口的设计目的:是对类的行为进行约束。它只约束行为的有无,不约束你如何去实现行为。抽象类的设计目的是代码的复用。
(7)List、Set之间的区别是什么?
1.list集合有序可重复,set无序不可重复,Map以键值对的形式对元素进行存储
2.List允许任意数量的空值,Set最多允许一个空值的出现,Map只允许出现一个空键,但允许出现任意数量的空值
3.List 支持for循环,也就是通过下标来遍历,也可以用迭代器,但是set只能用迭代,因为他无序,无法用下标来取得想要的值。
4.Set:检索元素效率低下,删除和插入效率高,插入和删除不会引起元素位置改变。
5.List:和数组类似,List可以动态增长,查找元素效率高,插入删除元素效率低,因为会引起其他元素位置改变

8)两个对象的 hashCode()相同,则 equals()也一定为 true,对吗?
1.不对
2.因为hashcode方法一般用作于哈希表数据结构,在集合中要存入一个元素的时候,首先调用hashcode方法得出hash值,然后将hash值转换为数组下标,然后拿着该下标去对应的位置,如果该位置没有任何的元素,那么就直接将值存入。如果已经存在改值,那么则进行equals比较,如果返回为false,那么将其存入进去,如果返回为true,则覆盖元素。

3.结论:hashCode()相等的两个对象他们的equal()不一定相等,也就是hashCode()不是绝对可靠的。equals相等的两个对象它们的hashcode一定相等,也就是equals对比是绝对可靠的。
PS:hashCode()相等即两个键值对的哈希值相等,然而哈希值相等。并不一定能得出键值对相等

(9) java 中的 Math.round(-5.5) 等于多少?
1.等于-5,在java中,四舍五入的原理是在原参数上加0.5再做向下取整。

(10) String str="i"与 String str=new String(“i”)一样吗?
1.不一样,两个内存分配的方式不一样
2.String str = “i” 的方式java会把它分配到常量池
3.String str = new String(“i”) 会分配到堆内存中

(11)String s = new String(“xyz”);创建了几个String对象?
1.这个要看情况,当常量池中没有"xyz"的时候,他会先在常量池中创建这个字符串对象,然后再创建这个字符串的引用对象,所以这时候是两个对象。当常量池中有这个"xyz"的时候,就只会创建这个字符串的引用对象,即一个对象

(12)ArrayList 和 LinkedList 的区别是什么?
1.ArrayList底层采用动态数组的数据结构,用连续的内存存储,LinkedList是链表的数据结构,可以存储在分散的内存中。
2.ArrayList查询快,插入和删除慢。LinkedList查询慢,插入、删除快
3.随机访问效率不同,

(13)HashMap 的实现原理?
1.hashMap的底层采用数组和链表的数据结构。当我们往HashMap里面put元素的时候,底层调用k的hashcode方法得到hash值,然后通过哈希算法将hash值转换为数组的下标,当下标上没有任何元素的时候,就把这个节点放在这个位置上,如果下标对应的位置上有链表,此时会拿着k和链表上的k进行equals比较,如果和所有链表上的k进行equals比较都是返回false,则将其存入末尾,如果有一个返回为true,则将它的值覆盖,如果添加时发现容量不够,就开始扩容。
2.在jdk8版本的时候haspMap在第一次添加数据时,默认构造函数构建的初始容量是16,当达到它的临界值(0.75)的时候,数组就会扩容,如果有一条链表的元素个数到达8,且数组的大小到达64时。就会进化成红黑树,当数组的长度重新低于6的时候,又会将红黑树重新转换为链表。
PS:题外补充—hashMap的get(k)原理:
3.先调用k的hashcode方法得出hash值,通过哈希算法将hash值转换为数组下标,通过数组下标快速定位,如果该位置上什么都没有,则返回null。如果该位置有链表,那么拿着该k和链表上的所有k进行equals比较,如果所有equals都返回false则返回null,但是只要其中一个节点返回true,则将其value返回。

(14)说一下 HashSet 的实现原理?
1.HashSet底层由HashMap实现,扩容机制一样。它封装了一个HashMap来存储所有的集合元素。但是它不一样的是,它的所有集合元素由HashMap的key来保存,而HashMap的value则存储了一个PRESENT。它是一个静态的 Object 对象。
2.HashSet的其它操作原理都是基于HashMap的

(15)HashMap 和 Hashtable 有什么区别?
1.HashMap不是线程安全的,而HashTable是线程安全的
2.继承的父类不同
3.HashMap允许null值,key和value都允许,但是hashTable不允许null值,key和value都不允许。
4.两个的遍历方法不同,前者采用Iterator,后者采用Enumeration
5.初始容量和扩容机制不同,Hashtable初始值为11,扩容机制为2n + 1,HashMap初始为16,扩容机制为2n
6.创建时,如果给定了容量初始值,那么Hashtable会直接使用你给定的大小,而HashMap会将其扩充为2的幂次方大小
7.hashMap去掉了HashTable 的contains方法,但是加上了containsValue()和containsKey()方法

(16)HashSet与HashMap的区别?
1.HshMap存储键值对,HashSet存储对象
2.HashMap使用put添加元素值Map,HshSet使用add方法
3.计算hashCode值不一样。HashMap使用键对象计算。HashSet使用成员对象来计算
4.效率不一样,HashSet要慢

(17)&和&&的区别?
1.&和&&都表示与的意思,既表达式俩边都成立,结果才成立
2.&做逻辑运算符时,左边为假时,它还会计算右边,而&&(短路与)不会,当左边为假时后面则不会计算了
3.&做位运算符时,&的左右俩边可以是布尔类型,也可以是数值,而&&只能是布尔类型

(18)字符串连接用+和StringBuilder的append的区别?
1.一般情况下没什么区别,因为一般情况下用+连接,系统内部会进行优化,它用的也是StringBuilder的append来实现的
2.但是在循环拼接的时候,用的如果是+拼接的话,就是一直在循环内部创建StringBuilder对象,这样会造成空间浪费。但是我们直接用StringBuilder的话,可以定义在循环外面。减少内存消耗
在这里插入图片描述
(19)String有哪些特性?
1.不可变,为什么不可变可以查看第四题的课外补充
2.常量池优化:String 对象创建之后,会在字符串常量池中进行缓存,如果下次创建同样的对象时,会直接返回缓存的引用
3.使用 final 来定义 String 类,表示 String 类不能被继承,提高了系统的安全性

(20)Integer a= 127 与 Integer b = 127相等吗?那Integer a1 = 128 与 Integer b1 = 128 呢?
1.前者相等,后者不相等
2.因为如果整型字面量的值在-128到127之间,那么自动装箱时不会new新的Integer对象,而是直接引用常量池中的Integer对象,超过这个范围 则会new 新的Integer对象,即a1==b1的结果是比较内存地址,所以不相等

(21)

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值