面试常问集锦——Java基础部分

18 篇文章 12 订阅

java基础部分

《我想进大厂》之Java基础夺命连环16问

https://mp.weixin.qq.com/s?__biz=MzkzNTEwOTAxMA==&mid=2247485644&idx=1&sn=db46ab83196031d8f563585b72a7b511&chksm=c2b24031f5c5c927bd125e219d4c2c810254f49ddc28988591978d27fe10a07eac85247bf89e&scene=178&cur_album_id=1512519209967271939#rd


工作10年,分享50个让你代码更好的小建议

https://mp.weixin.qq.com/s/vJXcR3TyfcUsWb3KzBSxEw


一个HashMap跟面试官扯了半个小时

https://mp.weixin.qq.com/s/oRx-8XXbgage9Hf97WrDQQ

HashMap 面试二十一问!

https://mp.weixin.qq.com/s/oWiaWsBCxwCMiwHnmA6iKA

HashMap原理

(1)解决冲突的方法有哪些

(2)长度为什么是2的次方  为什么长度总是2的整数次方

(3)put过程  HashMap夺命连环问.put过程是怎么样的

(4)rehash过程  

(5)1.7与1.8的区别  

(6)树化与链化的转变临界点

根据泊松分布,在负载因子默认为0.75的时候,单个hash槽内元素个数为8的概率小于百万分之一,所以将7作为一个分水岭,等于7的时候不转换,大于等于8的时候才进行转换,小于等于6的时候就化为链表。

(7)加载因子为什么是0.75  为什么 HashMap 的加载因子是0.75

(8)与TreeMap的区别

-----------------------------------------------------------------------------------------------

【对象面试官】Map

https://mp.weixin.qq.com/s?__biz=MzU4NzA3MTc5Mg==&mid=2247484280&idx=1&sn=87cfede653dabc26c909823a1dafd615&chksm=fdf0eb27ca876231095ff99f0b3e30acd7b2ee4cdc7ddb16da0bb6a3b02f531e27324059cf58&scene=178&cur_album_id=1657204970858872832#rd

HashMap的31连环炮

https://mp.weixin.qq.com/s/7I-5RL0Py-g8mP7lJol3Yg

Java 8系列之重新认识HashMap

https://tech.meituan.com/2016/06/24/java-hashmap.html

Java源码分析:HashMap 1.8 相对于1.7 到底更新了什么?

https://www.jianshu.com/p/8324a34577a0?utm_source=oschina-app

Java Map 中那些巧妙的设计

https://www.toutiao.com/i6943799935875777028


ConcurrentHashMap

(1)与HashMap的区别

(2)1.7与1.8的区别

分段锁到CAS+synchronized改变

(3)为什么放弃分段锁

漫画:什么是ConcurrentHashMap?

https://mp.weixin.qq.com/s?__biz=MzIxMjE5MTE1Nw==&mid=2653192083&idx=1&sn=5c4becd5724dd72ad489b9ed466329f5&chksm=8c990d49bbee845f69345e4121888ec967df27988bc66afd984a25331d2f6464a61dc0335a54&scene=21#wechat_redirect

我就知道面试官接下来要问我 ConcurrentHashMap 底层原理了

https://mp.weixin.qq.com/s/My4P_BBXDnAGX1gh630ZKw

让ConcurrentHashMap成为你的面试加分点

https://juejin.cn/post/6844904136937308168

ConcurrentHashMap中有十个提升性能的细节,你都知道吗?

https://mp.weixin.qq.com/s/vZZQeWaKQ2pbUDyyqpzunQ

ConcurrentHashMap核心原理,这次彻底给整明白了

https://mp.weixin.qq.com/s/5n_rBx9bTig3To94Tcsr8w


【对线面试官】List

https://mp.weixin.qq.com/s?__biz=MzU4NzA3MTc5Mg==&mid=2247484253&idx=1&sn=532db3941f47502582295cbb003f753d&chksm=fdf0eb02ca8762145c66b33bbb429399f1f0f27b31c22f7cf6c693c235e9a7cffdafb6ce2fdc&scene=178&cur_album_id=1657204970858872832#rd

ArrayList源码+扩容机制分析

https://github.com/Snailclimb/JavaGuide/blob/master/docs/java/collection/ArrayList%E6%BA%90%E7%A0%81+%E6%89%A9%E5%AE%B9%E6%9C%BA%E5%88%B6%E5%88%86%E6%9E%90.md


Object 源码解析

https://juejin.cn/post/6844903910214205448

Object的十二个知识点

https://mp.weixin.qq.com/s/-2TCWWypvFHznIZklbH0rw


【对线面试官】Java反射 && 动态代理

https://mp.weixin.qq.com/s?__biz=MzU4NzA3MTc5Mg==&mid=2247483893&idx=1&sn=af51e626f2c2baec8cae4f4a15425957&chksm=fdf0e9aaca8760bcd384a290608ecb220adfb7d4615d8418e16c07d3e371970598d3d2f54c4a&scene=178&cur_album_id=1657204970858872832#rd

你不得不知道的反射(非常重要)

https://mp.weixin.qq.com/s/emvj2YBNhBbVAhn77K6K1w

如何利用缓存机制实现JAVA类反射性能提升30倍

https://mp.weixin.qq.com/s/FbOqMo1AUoxPFT6pSLdnrw


内存溢出与内存泄漏

(1)内存溢出,即OOM

(2)内存泄漏

引起内存泄漏的对象的特点:

  1. 这些对象是可达的,即在有向图中,存在通路可以与其相连;

  2. 这些对象是无用的,即程序以后不会再使用这些对象,也不能被回收掉。

什么会导致内存泄露:

长生命周期的对象一直持有短生命周期的对象的引用

例如单例对象持有外部的一个普通类,静态集合持有短生命周期的元素

非静态内部类会持有外部类的强引用,导致外部类一直回收不掉。但静态内部类则会持有外部类的弱引用。

此时要么将非静态内部类改为静态内部类,要么手动在非静态内部类里面加上WeakReference<OuterClass>

为什么非静态内部类会持有外部类的一个强引用

因为需要在内部类中调用外部类的属性,因此内部类的创建依赖外部类的创建,也需要外部类的一个引用。

jvm在创建内部类时,会自动向内部类构造方法中传入外部类的引用。我们只需要抢先一步形成对外部类的弱引用,则会避免内存泄漏。

聊聊7种内存泄露场景和13种解决方案

https://mp.weixin.qq.com/s/l97a577bYCza7YLKRWdQ_w

Java 中 7 个潜在的内存泄露风险

https://mp.weixin.qq.com/s/aoRdNyUq4Qc9uvb04yW9WA


谈谈序列化与反序列化

序列化:序列化是把对象转换成有序字节流,以便在网络上传输或者保存在本地文件中。序列化后的字节流保存了Java对象的状态以及相关的描述信息。

反序列化:客户端从文件中或网络上获得序列化后的对象字节流后,根据字节流中所保存的对象状态及描述信息,通过反序列化重建对象。

代码如下:

    static class User implements Serializable {
        int id;
        String name;

        User(int id, String name) {
            this.id = id;
            this.name = name;
        }
    }

    public static void main(String[] args) throws IOException, ClassNotFoundException {
        //序列化
        User user = new User(1, "tom");
        FileOutputStream fos = new FileOutputStream("a.txt");
        ObjectOutputStream oos = new ObjectOutputStream(fos);
        oos.writeObject(user);

        //反序列化
        FileInputStream fis = new FileInputStream("a.txt");
        ObjectInputStream ois = new ObjectInputStream(fis);
        User tom = (User) ois.readObject();
        System.out.println(tom.name);
    }

要序列化的类为什么要实现Serializable接口?

打开writeObject方法的源码看一下,发现方法中有这么一个逻辑,当要写入的对象是StringArrayEnumSerializable类型的对象则可以正常序列化,否则会抛出NotSerializableException异常。

哪些类型的变量不可以被序列化?

transient修饰的变量,属于对象的临时变量

一个静态变量不管是否被transient修饰,均不能被序列化。 因为static修饰的属性是属于类,而非对象。

serialVersionUID作用 是什么?举个例子说明

Java的序列化机制是通过判断类的serialVersionUID来验证版本一致性的。在进行反序列化时,JVM会把传来的字节流中的serialVersionUID与本地相应实体类的serialVersionUID进行比较,如果相同就认为是一致的,可以进行反序列化,否则就会出现序列化版本不一致的异常,即是InvalidCastException。

当实现java.io.Serializable接口的类没有显式地定义一个serialVersionUID变量时候,Java序列化机制会根据编译的Class自动生成一个serialVersionUID作序列化版本比较用,这种情况下,如果Class文件(类名,方法明等)没有发生变化(增加空格,换行,增加注释等等),就算再编译多次,serialVersionUID也不会变化的。

如果我们不希望通过编译来强制划分软件版本,即实现序列化接口的实体能够兼容先前版本,就需要显式地定义一个名为serialVersionUID,类型为long的变量,不修改这个变量值的序列化实体都可以相互进行串行化和反串行化。

子类实现了 Serializable 接口,它的父类都没有实现 Serializable 接口,序列化该子类对象,然后反序列化后输出父类定义的某变量的数值,与期望不符。

要想将父类对象也序列化,就需要让父类也实现Serializable 接口。如果父类不实现的话的,就 需要有默认的无参的构造函数。在父类没有实现 Serializable 接口时,虚拟机是不会序列化父对象的,而一个 Java 对象的构造必须先有父对象,才有子对象,反序列化也不例外。所以反序列化时,为了构造父对象,只能调用父类的无参构造函数作为默认的父对象。因此当我们取父对象的变量值时,它的值是调用父类无参构造函数后的值。如果你考虑到这种序列化的情况,在父类无参构造函数中对变量进行初始化,否则的话,父类变量值都是默认声明的值,如 int 型的默认是 0,string 型的默认是 null。

扩展:单例模式中如何保证反序列化安全性?

在单例类中重写readObject方法,返回当前单例对象。


泛型解析

https://juejin.cn/post/6844904050673057799

你必须知道的Java泛型

https://mp.weixin.qq.com/s/zu3fv0DofsaiGeVMO0fojA

泛型擦除和运行时泛型信息获取

https://blog.csdn.net/qq_33217349/article/details/89178683

Java泛型类型擦除以及类型擦除带来的问题

https://www.cnblogs.com/wuqinglong/p/9456193.html

还不懂Java的泛型?只用这一篇文章,保证你面试对答如流

https://mp.weixin.qq.com/s/WXtdb1Rp5FO1JTI4_MKOCQ

【对线面试官】今天来聊聊Java泛型

https://mp.weixin.qq.com/s?__biz=MzU4NzA3MTc5Mg==&mid=2247483823&idx=1&sn=cc887dc2c7e68a69e8d4d141c2ca9b5e&chksm=fdf0e9f0ca8760e69c7c002ba07110852f7e1c3f199ffde54dc2674a896cdc02fe44ee1189a4&scene=178&cur_album_id=1657204970858872832#rd


重写equals方法为什么通常会重写hashcode方法?

面试题:重写equals方法为什么通常会重写hashcode方法?


深拷贝与浅拷贝的区别

  1. 浅拷贝:对基本数据类型进行值传递,对引用数据类型进行引用传递般的拷贝,此为浅拷贝。

  2. 深拷贝:对基本数据类型进行值传递,对引用数据类型,创建一个新的对象,并复制其内容,此为深拷贝。

图片


【对线面试官】今天来聊聊Java注解

https://mp.weixin.qq.com/s?__biz=MzU4NzA3MTc5Mg==&mid=2247483821&idx=1&sn=e9003410a8d3c8a092de0c4d2002bedd&chksm=fdf0e9f2ca8760e455ddf557ebb0bde3c7c295ecfb47e6759490fed36ee1bdaa54f6a46ae602&scene=178&cur_album_id=1657204970858872832#rd

谈谈JAVA注解机制

https://mp.weixin.qq.com/s/-aWg4pA1f1rsTNlNd2s3uQ


fail-fast与fail-safe

在遍历Java中的集合过程中,如果有其他线程对当前集合进行了修文,那么就有可能会出现线程安全问题所以给出两种解决这种问题的手段:

快速失败、 fail - fast

在HashMap、LinkedList'等非安全容器中,都会有一个modCount 值,每次对容器进行修改操作( put、 delete^等),都会增加这个值。

在对这些容器进行遍历时,会将其modCount'保存起来。在遍历过程中,如果发现expect edModCount不是缓存中的值,就会直接抛出Concur rentModificationException。也就是快速失败,结束遍历。

 HashMap的迭代器采用的是Iterator, Iterator是快速失败(Fail-Fast) ,在遍历过程中若有其他线程对该HashMap进行增加或者删除元素,

则会抛出ConcurrentModificationException,因为快速失败的迭代器是操作的集合本身。

安全失败、fail - safe 

如果采用安全失败机制,在开始遍历的时候,会将当前集合中的内容拷贝一份出来再进行遍历。其他线程如果对该集合进行了修改,也不会改变遍历过程。

java .util. concurrent 包下的并发容器都是基于*安全失败模型*的。

HashTab le的迭代器是Enumerat ion, Enumeration是安全失败(Fail-Safe) ,在遍历过程中若有其他线程对该集合进行增加或则删除元素,不会抛出ConcurentModif icationException,因为安全失败的迭代器操作的是原集合的一个拷贝。


最常见的10种Java异常问题

https://mp.weixin.qq.com/s/6CsMwohLGMqQtVgZ6exSSQ


面试官:String长度有限制吗?是多少?

https://mp.weixin.qq.com/s/W-dJ0WCLaOUstRW1gkk5fg

答:首先字符串的内容是由一个字符数组 char[] 来存储的,由于数组的长度及索引是整数,且String类中返回字符串长度的方法length() 的返回值也是int ,所以通过查看java源码中的类Integer我们可以看到Integer的最大范围是2^31 -1,由于数组是从0开始的,所以数组的最大长度可以使【0~2^31】通过计算是大概4GB。

但是通过翻阅java虚拟机手册对class文件格式的定义以及常量池中对String类型的结构体定义我们可以知道对于索引定义了u2,就是无符号占2个字节,2个字节可以表示的最大范围是2^16 -1 = 65535。

其实是65535,但是由于JVM需要1个字节表示结束指令,所以这个范围就为65534了。超出这个范围在编译时期是会报错的,但是运行时拼接或者赋值的话范围是在整形的最大范围。


说说String与StringTable

https://zhuanlan.zhihu.com/p/260939453

String为什么不可变

https://www.cnblogs.com/leskang/p/6110631.html

String为什么是不可变的? -- String源码分析

https://blog.csdn.net/zhangjg_blog/article/details/18319521


深入解析String#intern

https://tech.meituan.com/2014/03/06/in-depth-understanding-string-intern.html


JDK9对String字符串的新一轮优化,不可不知 

https://mp.weixin.qq.com/s/p1Q5AZWETUtajqtY2GUMtA


【对线面试官】 Java NIO

https://mp.weixin.qq.com/s?__biz=MzU4NzA3MTc5Mg==&mid=2247483854&idx=1&sn=aa450a03ac0d6e8cf12cf13d4719ede3&chksm=fdf0e991ca87608769b9aca208b9c8646c13434b880ac74a9fe335a3f77b28377d1598635dd7&scene=178&cur_album_id=1657204970858872832#rd

为什么一个还没毕业的大学生能够把 IO 讲的这么好?

https://mp.weixin.qq.com/s/4sHsGAnU28gBc3OcacvirQ


方法调用:一看就懂,一问就懵?

https://mp.weixin.qq.com/s/9OdLAar3M4DbsJHXwDToXQ


探讨缓存行与伪共享 

探讨缓存行与伪共享



总结

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

SunAlwaysOnline

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

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

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

打赏作者

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

抵扣说明:

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

余额充值