跳槽者、应届生必看JAVA面试题系列 - 基础类知识篇(一)

简介: 跳槽者、应届生必看JAVA面试题系列 - 基础类知识篇(一)

文章标题

一: 前言

二: 面试挑战

三: 类基础信息(一)

一: 类加载后会存在在哪里

二: Hotspot和JRockit的关系

三: JDK8为什么要使用元空间取代永久代

四: 类加载的最终产物是什么

五: 字符串常量、静态变量存放在哪里

六: String为什么定义成final

七: String、StringBuffer、StringBuilder的区别

八: s1 = new String(“hello”)和s1 = “hello”有什么区别

九: s1 = “a” + “b”和s1 = a1 + a2 (注:a1 = “a”,a2=”b”)有什么区别

十: 字符串常量池和String.intern()方法在jdk1.6、1.7、1.8的变化

十一: Comparable和Comparator的区别

四: 总结

五: 热门推荐

一: 前言

image.png

二: 面试挑战

 在文章开始前,首先安利下"面试挑战": 凡是满足下面的挑战条件的,如果一个月内没有拿到一个Offer的,免费提供简历封装建议和相关面试题目解答。


 如果面试通过的,可以截图分享领取奖励,让大家一起见证,具体条件如下:


 1、持续学习本人《面试大全》至少两个月且对其中的内容基本掌握的。


  2、计算机相关专业或者经过计算机相关专业的培训(不少于3个月,正常来说培训机构培训时间不会少于三个月),准备从事JAVA开发人员。


  3、 打算从事的工作是JAVA开发,年限是1-3年(大神的话就忽略我说的,可以直接退出了)或者是符合计算机相关专业,准备从学校出来就业的。


 4、需要提供相关面试证据或者是面试题目。


 如果大家对这个感兴趣的,可以关注【IT学习日记】回复【面试挑战】即可参与,现在参与还免费赠送一份面试资料。



三: 类基础信息(一)


一: 类加载后会存在在哪里


 回答: 存放在方法区中。



 详情如下:



 静态成员变量(类变量) 存放于 方法区的静态部分



 静态方法 存放于 方法区的静态部分



 非静态方法(包括构造函数) 存放于 方法区的非静态部分



 静态代码块 存放于 方法区的静态部分



 构造代码块 存放于 方法区的静态部分



 加载细节:



 类文件加载时,静态方法和非静态方法都会加载到方法区中,只不过要调用到非静态方法时需要先实例化一个对象,对象才能调用非静态方法。如果让类中所有的非静态方法都随着对象的实例化而建立一次,那么会大量消耗内存资源,所以才会让所有对象共享这些非静态方法,然后用this关键字指向调用非静态方法的对象。



二: Hotspot和JRockit的关系


 1、两者都是JVM规范的实现,JRockit最初由Appeal和BEA Systems开发,然后被Oracle收购以运行服务器软件。 它旨在针对需要长时间运行任务,大量内存和大量内存的大型应用程序进行优化一个可扩展的环境。



 2、自Oracle收购Sun Microsystems以来,Oracle已经在使JRockit和HotSpot JVM融合的具体计划和路线图是"两全其美"的实现,主要建立在HotSpot上但是集成了JRockit最受欢迎的功能。



 3、永久代只存在Hotspot虚拟机中,其他实现了JVM的虚拟器并没有这个说法



三: JDK8为什么要使用元空间取代永久代


 1、JDK7及之前字符串存在永久代中,容易出现性能问题和内存溢出



 2、类及方法的信息等比较难确定其大小,因此对于永久代的大小指定比较困难,太小容易出现永久代溢出,太大则容易导致老年代溢出



 3、永久代会为 GC 带来不必要的复杂度,并且回收效率偏低(永久代的垃圾收集是和老年代捆绑在一起的,因此无论谁满了,都会触发永久代和老年代的垃圾收集。



 4、将 HotSpot 与 JRockit 合二为一,永久代只是在Hotspot中有,JRickit并没有永久代的概念



四: 类加载的最终产物是什么


 类加载(Loading)的最终产物是一个 java.lang.Class 对象,它是我们访问方法区中的类型数据的外部接口,我们需要通过这个对象来访问类的字段、方法、运行时常量池等。



五: 字符串常量、静态变量存放在哪里


 一: 字符串常量



   1.7以前是放在永久代,1.7以后是放在堆中



 二: 静态变量



   1、1.7前字符串常量池和静态变量存储在永久代



   2、JDK7以上,静态变量存储在其对应的Class对象中。而Class对象作为对象,和其他普通对象一样,都是存在java堆中的。



六: String为什么定义成final


 主要是考虑到安全性和效率的两方面。



 1、String类中有需要关于底层的引用,因为final修饰的类是不可以被继承的,所以不会对String类进行修改,避免了因继承而引起的安全隐患。



 2、String类是不可变的,所以在多线程下是线程安全的,无需进行线程同步。



 3、因为String类是不可变的,所以在创建的时候就将对应的Hashcode缓存起来,使用的时候不需要重新计算,这就使得字符串很适合用于Map集合中的key,字符串的处理速度快过其他的键对象。



七: String、StringBuffer、StringBuilder的区别


 1、String对象是不可变的,但是StringBuffer和StringBuilder是可变的



 2、String和StringBuffer(方法使用了synchronize加锁)是线程安全的,StringBuilder是线程不安全的



 3、执行效率: StringBuilder > StringBuffer > String



八: s1 = new String(“hello”)和s1 = “hello”有什么区别


 1、new String(“hello”)是先在堆中创建一个对象,并返回给s1,”hello”是一个常量,会先到字符串常量池中查询是否存在这个字符串,没有则分配一个空间并存放”hello”,并将”hello”在常量池的地址存放在new出来的对象中(所以:如果”hello”字符串在常量池中存在则该语句创建一个对象,不存在则创建两个)



 2、s1 = “hello”则表示直接到常量池中查询,有则返回地址,没有则创建新的再返回地址(所以:如果常量池中存在,则不创建对象,不存在则创建一个对象)



九: s1 = “a” + “b”和s1 = a1 + a2 (注:a1 = “a”,a2=”b”)有什么区别


 1、如果是变量相加如(s1 = a1 + a2 (注:a1 = “a”,a2=”b”)),则先开空间,再拼接(每一个字符串变量在常量池中都有一个地址,如果是多个拼接,则生成新的对象并返回这个对象的地址)。



 2、如果是常量相加如:s1 = “a” + “b”,则是先将字符串拼接好,再到常量池中查找,有则直接返回,没有则创建再返回。



 3、所以,在进行比较的时候,一般判断清除是拼接完再查询还是查询后再拼接,这样使用在进行比较的时候也是不一样的。



十: 字符串常量池和String.intern()方法在jdk1.6、1.7、1.8的变化


 作用:



   intern方法只会保存首次存储的字符串的引用到常量池中,后面再有一样的也不会被覆盖。



 区别:



   JDK1.6: intern方法属于永久区



   JDK1.7及之后,取消了永久代,存在在java堆中



十一: Comparable和Comparator的区别


 一: Comparable特点:



   1、只有一个方法:compareTo,需要拥有比较方法的类去实现它



   2、是一个接口,实现它类就有了比较功能,比较的具体实现由自己定义



 (一): Comparable作用:



   内比较器,可以实现自己和自己比较,也可以实现不同类对象的比较,依赖于compareTo实现逻辑,如果想将类添加到Collection中然后调用sort排序,则添加入Collection的类必须实现这个接口



 (二): Comparable缺点:



   耦合性比较强,必须实现compareTo方法,有代码侵入。



 (三): 返回结果: int类型



    1、比较者大于被比较者(也就是compareTo方法里面的对象),那么返回正整数



    2、比较者等于被比较者,那么返回0



   3、比较者小于被比较者,那么返回负整数



 二: Comparator特点



   1、是外比较器,是一个接口,提供了compare(T1 o1,T2 o2)API用于比较,除此之外还存在其他API如:reversed方法。



 (一): Comparator使用场景:



   1、类没有实现Comparable接口,但是也要两个对象进行比较。



   2、虽然类实现了Comparable接口,但是对compareTo中的比较逻辑不满足



 (二): Comparator缺点:



   比较方法的泛型类T需要指定,所以比较的话就无法实现两个不同对象的比较。



 (二): 返回结果: int类型



   1、比较者大于被比较者(也就是compareTo方法里面的对象),那么返回正整数



   2、比较者等于被比较者,那么返回0



   3、比较者小于被比较者,那么返回负整数



 三: 区别



   1、Comparator位于包java.util下,而Comparable位于包java.lang下



   2、实现Comparable接口的方式比实现Comparator接口的耦合性要强一些,如果要修改比较算法,要修改Comparable接口的实现类,而实现Comparator的类是在外部进行比较的(既:每个需要比较的类定义一个比较器,具体实现在比较器中,不涉及修改类,不需要对实现类有任何修改)



   3、Comparable只有一个接口是函数式接口,Comparator则有多个。



 四: 命名规范:



   "待比较的实体类+Comparator"来命名



四: 总结


 由于文章篇幅的限制,面试大全的第六章暂时到这里就告一段落。如果有意见或者建议,可以在下方或者私信留言,看到会及时回复,也欢迎大家参加面试挑战和面试题投稿,希望大家早日获得心仪的Offer,如果觉得文字对你有帮助,欢迎关注和点赞。



 面试大全系列文章会保持稳定的更新速度,大概每周两更到三更,感兴趣和可以关注我。



 如果想参加面试挑战,可以私信回复【面试挑战】即可,如果想进行面试题目投稿,可以私信回复【面试题目投稿】即可,如果想获取更多面试问题和资料,查看最新的面试题目更新进度,可以关注我,私信【面试资料】即可,谢谢大家的阅读和关注。



五: 热门推荐


 1、跳槽者、应届生必看JAVA面试题系列(一)



 2、跳槽者、应届生必看JAVA面试题系列(二)



 3、跳槽者、应届生必看JAVA面试题系列(三)



 4、跳槽者、应届生必看JAVA面试题系列(四)



 5、跳槽者、应届生必看JAVA面试题系列(四)



 6、面试宝典(一) - 让你不再错过“金九银十“的求职浪潮之简历包装篇


相关文章
|
2天前
|
存储 缓存 安全
java 中操作字符串都有哪些类,它们之间有什么区别
Java中操作字符串的类主要有String、StringBuilder和StringBuffer。String是不可变的,每次操作都会生成新对象;StringBuilder和StringBuffer都是可变的,但StringBuilder是非线程安全的,而StringBuffer是线程安全的,因此性能略低。
|
19天前
|
存储 安全 Java
java.util的Collections类
Collections 类位于 java.util 包下,提供了许多有用的对象和方法,来简化java中集合的创建、处理和多线程管理。掌握此类将非常有助于提升开发效率和维护代码的简洁性,同时对于程序的稳定性和安全性有大有帮助。
41 17
|
11天前
|
安全 Java
Java多线程集合类
本文介绍了Java中线程安全的问题及解决方案。通过示例代码展示了使用`CopyOnWriteArrayList`、`CopyOnWriteArraySet`和`ConcurrentHashMap`来解决多线程环境下集合操作的线程安全问题。这些类通过不同的机制确保了线程安全,提高了并发性能。
|
15天前
|
存储 Java 程序员
Java基础的灵魂——Object类方法详解(社招面试不踩坑)
本文介绍了Java中`Object`类的几个重要方法,包括`toString`、`equals`、`hashCode`、`finalize`、`clone`、`getClass`、`notify`和`wait`。这些方法是面试中的常考点,掌握它们有助于理解Java对象的行为和实现多线程编程。作者通过具体示例和应用场景,详细解析了每个方法的作用和重写技巧,帮助读者更好地应对面试和技术开发。
55 4
|
16天前
|
Java 编译器 开发者
Java异常处理的最佳实践,涵盖理解异常类体系、选择合适的异常类型、提供详细异常信息、合理使用try-catch和finally语句、使用try-with-resources、记录异常信息等方面
本文探讨了Java异常处理的最佳实践,涵盖理解异常类体系、选择合适的异常类型、提供详细异常信息、合理使用try-catch和finally语句、使用try-with-resources、记录异常信息等方面,帮助开发者提高代码质量和程序的健壮性。
34 2
|
5天前
|
Java 开发者
Java多线程编程中的常见误区与最佳实践####
本文深入剖析了Java多线程编程中开发者常遇到的几个典型误区,如对`start()`与`run()`方法的混淆使用、忽视线程安全问题、错误处理未同步的共享变量等,并针对这些问题提出了具体的解决方案和最佳实践。通过实例代码对比,直观展示了正确与错误的实现方式,旨在帮助读者构建更加健壮、高效的多线程应用程序。 ####
|
13天前
|
安全 Java 测试技术
Java并行流陷阱:为什么指定线程池可能是个坏主意
本文探讨了Java并行流的使用陷阱,尤其是指定线程池的问题。文章分析了并行流的设计思想,指出了指定线程池的弊端,并提供了使用CompletableFuture等替代方案。同时,介绍了Parallel Collector库在处理阻塞任务时的优势和特点。
|
4天前
|
安全 Java 开发者
Java 多线程并发控制:深入理解与实战应用
《Java多线程并发控制:深入理解与实战应用》一书详细解析了Java多线程编程的核心概念、并发控制技术及其实战技巧,适合Java开发者深入学习和实践参考。
|
4天前
|
Java 开发者
Java多线程编程的艺术与实践####
本文深入探讨了Java多线程编程的核心概念、应用场景及实践技巧。不同于传统的技术文档,本文以实战为导向,通过生动的实例和详尽的代码解析,引领读者领略多线程编程的魅力,掌握其在提升应用性能、优化资源利用方面的关键作用。无论你是Java初学者还是有一定经验的开发者,本文都将为你打开多线程编程的新视角。 ####
|
3天前
|
存储 安全 Java
Java多线程编程中的并发容器:深入解析与实战应用####
在本文中,我们将探讨Java多线程编程中的一个核心话题——并发容器。不同于传统单一线程环境下的数据结构,并发容器专为多线程场景设计,确保数据访问的线程安全性和高效性。我们将从基础概念出发,逐步深入到`java.util.concurrent`包下的核心并发容器实现,如`ConcurrentHashMap`、`CopyOnWriteArrayList`以及`BlockingQueue`等,通过实例代码演示其使用方法,并分析它们背后的设计原理与适用场景。无论你是Java并发编程的初学者还是希望深化理解的开发者,本文都将为你提供有价值的见解与实践指导。 --- ####
下一篇
无影云桌面