2024年最新Java基础面试题-可能读了个假书?,2024年最新贼好用的C C++学习路线集合

img
img

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 当类没有覆盖equals()方法时,则通过equals()比较的是该类的两个对象,这种情况等价于==。
  • 当类有覆盖equals()方法时,一般我们会通过比较两个对象的内容来判断是否相等。
public class Car {
    public static void main(String[] args) {
        String a="一键三连";//常量池中
        String b="一键三连";
        String c=new String("一键三连");//引用
        String d=new String("一键三连");
        System.out.println(a==b);//true,指向常量池同一个地址
        System.out.println(c==d);//false,两个不同的引用地址
        System.out.println(a.equals(b));//true,判断内容
        System.out.println(c.equals(d));//true
    }
}

注意:

  1. String中的equals()方法是被重写过的,因为object中的equals()方法比较的是对象的内存地址,而String中的equals()方法是比较对象的值。
  2. 当创建String类型的对象时,虚拟机会再常量池中查找是否有已存在的值相同对象,若有则把它赋给当前引用,没有的话则重新创建一个。

hashcode()和equals()


你知道为什么重写equals()方法必须重写hashcode()方法吗?

先介绍下hashcodehashcode()的作用是获取一个int整数即哈希码,也称为散列码。哈希码是确定对象在哈希表中的索引位置,Java中的所有类都包含该函数。

哈希码在HashSet中应用:当把对象加入HashSet时,HashSet会先计算对象的hashcode来判断对象加入的位置,同时也会与该位置其他加入对象的hashcode作比较,若没有相符的hashcode则会假设对象没有重复出现,否则会调用equals()方法来检查哈希码相同的对象内容是否相同,若内容也相同,HashSet就不会让其成功加入;否则的话就会重写散列到其他位置。通过hashcode大大减少了equals的调用次数,提高执行效率。这也回答了开头的问题。

hashcode()equals()相关规定:

  • 若两个对象相等,则hashcode一定是相同的,调用equals()也都是返回true
  • 两个对象有相同的hashcode,但它们不一定相等
  • 因此equals()覆盖的地方,hashcode()方法也必须覆盖。
  • hashcode()默认是对堆上的对象产生独特值,如果没有重写hashcode(),则该class的两个对象无论如何都不会相等。

transient关键字


对于不想进行序列化的变量,使用transient关键字修饰。当对象被反序列化时,被transient关键字修饰的变量值不会被持久化和恢复。transient只能修饰变量,不能修饰方法和类。

BIO、NIO和AIO


  • BIO(Blocking I/O,同步阻塞I/O模式),数据的读取写入必须阻塞在一个线程内等待其完成。让每个连接专注于自己的I/O并且编程模式简单,不用过多考虑系统加载、限流等问题,但是连接数非常大时就无能为力了。
  • NIO(Non-blocking/New I/O,同步非阻塞I/O模式),支持面向缓冲的,基于通道的I/O操作方法。阻塞模式使用就像传统中的支持一样,较为简单,但是性能和可靠性不好,而非阻塞模式正好与之相反,对于高负载、高并发的应用程序,应使用NIO模式开发。
  • AIO(Asynchronous I/O,异步非阻塞模式),异步I/O是基于回调机制实现的,也就是应用操作之后会直接返回,而不是阻塞在那里,当后台处理完成后,操作系统会通知相应的线程进行后续的操作。

Java集合

ArrayList和LinkedList


  1. 线程安全
    ArrayListLinkedList都是不同步的,也就是线程不安全,vector是同步的,线程安全。
  2. 底层数据结构
    ArrayList底层使用的是Object数组,LinkedList底层使用的是双向链表。
  3. 插入和删除元素
    ArrayList采用数组存储,所以插入和删除受元素位置影响;LinkedList采用链表存储,所以插入和删除元素时受到元素位置影响。
  4. 快速随机访问
    快速随机访问是通过元素的序号快速获取元素对象,通过底层数据就够就知道了,ArrayList支持,LinkedList不支持。
  5. 内存空间占用
    ArrayList的空间主要浪费在了list列表的结尾会预留一定的容量空间,而LinkedList主要花费在每一个元素都要比ArrayList更多的空间,因为存前驱后继节点及数据等。

HashMap和HashTable


  1. 线程安全
    HashMap是线程不安全的,而HashTable是线程安全的,因为HashTable的内部实现都加了synchronized修饰。
  2. 效率
    因为上述线程安全的问题,HashMap效率也就更高一点。
  3. Null
    HashMap中可以把null作为键或值,而HashTable不支持。
  4. 扩容
    若创建时未指定容量,HashMap初始为

16

16

16,每次扩容为2倍,HashTable初始为

11

11

11,并且每次扩容为

2

n

1

2n+1

2n+1。
若创建时指定了容量,HashMap会将其扩充至

2

2

2的幂次方大小,HashTable会直接使用给定的容量。
5. 底层数据结构
HashMapjdk1.8以后,当链表长度超过阈值(默认8)时,会转换为红黑树,以减少搜索时间,而HashTable没有这样的机制。

插播反爬信息 )博主CSDN地址:https://wzlodq.blog.csdn.net/

HashMap的长度为什么是2的幂次方?
为了能让HashMap减少碰撞高效存储,要尽量把数据分配均匀。首先哈希值的取值范围很大,有将近40亿的空间,内存时放不下的,换言之,哈希值并不能直接使用,需要对数组的长度进行取模,得到的余数就是对应的数组下标。
而设计成2的幂次就是因为如果取余操作中除数是2的幂次的话,就等价于与其除数减一的与操作,也就是说

h

a

s

h

%

l

e

n

g

t

h

=

(

l

e

n

g

t

h

1

)

&

h

a

s

h

hash%length=(length-1)&hash

hash%length=(length−1)&hash,而采用二进制位运算可以大大提高效率,这也就是为什么HashMap的长度是2的幂次方。

HashMap底层实现


JDK1.8之前:
JDK1.8之前HashMap底层是数组和链表结合在一起使用也就是链表散列,HashMap通过key的hashcode经过扰动函数处理后得到hash值,然后通过

(

n

1

)

&

h

a

s

h

(n-1)&hash

(n−1)&hash判断当前元素存放的位置,如果当前位置存在元素的话,就判断该元素与要存入的元素的hash值以及是否相同,若相同则直接覆盖,否则通过拉链法来解决冲突。所谓扰动函数指的就是HashMap的hash方法。使用hash方法之后可以减少碰撞。
在这里插入图片描述

JDK1.8之后:
优化了哈希冲突的解决方法,当链表长度大于阈值(默认为8)时,会将链表转换为红黑树,以减少搜索时间。
在这里插入图片描述

comparable和comparator

img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以戳这里获取

olor_FFFFFF,t_70#pic_center)

comparable和comparator

[外链图片转存中…(img-Sx9dcWad-1715659167629)]
[外链图片转存中…(img-u576AsUC-1715659167629)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以戳这里获取

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值