Java面试题全集(一)
JDK、JRE、JVM之间的区别
- JDK(Java SE Development Kit),Java标准开发包,它提供了编译、运⾏Java程序所需的各种⼯具和资源,包括Java编译器、Java运⾏时环境,以及常⽤的Java类库等
- JRE( Java Runtime Environment) ,Java运⾏环境,⽤于运⾏Java的字节码⽂件。JRE中包括了JVM以及JVM⼯作所需要的类库,普通⽤户⽽只需要安装JRE来运⾏Java程序,⽽程序开发者必须安装JDK来编译、调试程序
- JVM(Java Virtual Machine),Java虚拟机,是JRE的⼀部分,它是整个java实现跨平台的最核⼼的部分,负责运⾏字节码⽂件。
我们写Java代码,⽤txt就可以写,但是写出来的Java代码,想要运⾏,需要先编译成字节码,那就需要编译器,⽽JDK中就包含了编译器javac,编译之后的字节码,想要运⾏,就需要⼀个可以执⾏字节码的程序,这个程序就是JVM(Java虚拟机),专⻔⽤来执⾏Java字节码的。
如果我们要开发Java程序,那就需要JDK,因为要编译Java源⽂件。
如果我们只想运⾏已经编译好的Java字节码⽂件,也就是*.class⽂件,那么就只需要JRE。JDK中包含了JRE,JRE中包含了JVM。
另外,JVM在执⾏Java字节码时,需要把字节码解释为机器指令,⽽不同操作系统的机器指令是有可能不⼀样的,所以就导致不同操作系统上的JVM是不⼀样的,所以我们在安装JDK时需要选择操作系统。 另外,JVM是⽤来执⾏Java字节码的,所以凡是某个代码编译之后是Java字节码,那就都能在JVM上运⾏,⽐如Apache Groovy, Scala and Kotlin 等等。
hashCode()与equals()之间的关系
在Java中,每个对象都可以调⽤⾃⼰的hashCode()⽅法得到⾃⼰的哈希值(hashCode),相当于对象的指纹信息,通常来说世界上没有完全相同的两个指纹,但是在Java中做不到这么绝对,但是我们仍然可以利⽤hashCode来做⼀些提前的判断,⽐如:
- 如果两个对象的hashCode不相同,那么这两个对象肯定不同的两个对象
- 如果两个对象的hashCode相同,不代表这两个对象⼀定是同⼀个对象,也可能是两个对象
- 如果两个对象相等,那么他们的hashCode就⼀定相同
在Java的⼀些集合类的实现中,在⽐较两个对象是否相等时,会根据上⾯的原则,会先调⽤对象的hashCode()⽅法得到hashCode进⾏⽐较,如果hashCode不相同,就可以直接认为这两个对象不相同,如果hashCode相同,那么就会进⼀步调⽤equals()⽅法进⾏⽐较。⽽equals()⽅法,就是⽤来最终确定两个对象是不是相等的,通常equals⽅法的实现会⽐较重,逻辑⽐较多,⽽hashCode()主要就是得 到⼀个哈希值,实际上就⼀个数字,相对⽽⾔⽐较轻,所以在⽐较两个对象时,通常都会先根据hashCode想⽐较⼀下所以我们就需要注意,如果我们重写了equals()⽅法,那么就要注意hashCode()⽅法,⼀定要保证能遵守上述规则.
String、StringBuffer、StringBuilder的区别
1. String是不可变的,如果尝试去修改,会新⽣成⼀个字符串对象,StringBuffer和StringBuilder是
可变的
2. StringBuffer是线程安全的,StringBuilder是线程不安全的,所以在单线程环境下StringBuilder效
率会更⾼
泛型中extends和super的区别
1. <? extends T>表示包括T在内的任何T的⼦类
2. <? super T>表示包括T在内的任何T的⽗类
==和equals⽅法的区别
==:如果是基本数据类型,⽐较是值,如果是引⽤类型,⽐较的是引⽤地址
equals:具体看各个类重写equals⽅法之后的⽐较逻辑,⽐如String类,虽然是引⽤类型,但是String类中重写了equals⽅法,⽅法内部⽐较的是字符串中的各个字符是否全部相等。
重载和重写的区别
重载(Overload): 在⼀个类中,同名的⽅法如果有不同的参数列表(⽐如参数类型不同、参数个数不同)则视为重载。
重写(Override): 从字⾯上看,重写就是 重新写⼀遍的意思。其实就是在⼦类中把⽗类本身有的⽅法重新写⼀遍。⼦类继承了⽗类的⽅法,但有时⼦类并不想原封不动的继承⽗类中的某个⽅法,所以在⽅法名,参数列表,返回类型都相同(⼦类中⽅法的返回值可以是⽗类中⽅法返回值的⼦类)的情况下, 对⽅法体进⾏修改,这就是重写。但要注意⼦类⽅法的访问修饰权限不能⼩于⽗类的
List和Set的区别
List:有序,按对象插⼊的顺序保存对象,可重复,允许多个Null元素对象,可以使⽤Iterator取出
所有元素,在逐⼀遍历,还可以使⽤get(int index)获取指定下标的元素
Set:⽆序,不可重复,最多允许有⼀个Null元素对象,取元素时只能⽤Iterator接⼝取得所有元
素,在逐⼀遍历各个元素
ArrayList和LinkedList区别
1. ⾸先,他们的底层数据结构不同,ArrayList底层是基于数组实现的,LinkedList底层是基于链表实现的
2. 由于底层数据结构不同,他们所适⽤的场景也不同,ArrayList更适合随机查找,LinkedList更适合删除和添加,查询、添加、删除的时间复杂度不同
3. 另外ArrayList和LinkedList都实现了List接⼝,但是LinkedList还额外实现了Deque接⼝,所以LinkedList还可以当做队列来使⽤
谈谈ConcurrentHashMap的扩容机制
1.7版本
1. 1.7版本的ConcurrentHashMap是基于Segment分段实现的
2. 每个Segment相对于⼀个⼩型的HashMap
3. 每个Segment内部会进⾏扩容,和HashMap的扩容逻辑类似
4. 先⽣成新的数组,然后转移元素到新数组中
5. 扩容的判断也是每个Segment内部单独判断的,判断是否超过阈值
1.8版本
1. 1.8版本的ConcurrentHashMap不再基于Segment实现
2. 当某个线程进⾏put时,如果发现ConcurrentHashMap正在进⾏扩容那么该线程⼀起进⾏扩容
3. 如果某个线程put时,发现没有正在进⾏扩容,则将key-value添加到ConcurrentHashMap中,然后判断是否超过阈值,超过了则进⾏扩容
4. ConcurrentHashMap是⽀持多个线程同时扩容的
5. 扩容之前也先⽣成⼀个新的数组
6. 在转移元素时,先将原数组分组,将每组分给不同的线程来进⾏元素的转移,每个线程负责⼀组或多组的元素转移⼯作
Jdk1.7到Jdk1.8 HashMap 发⽣了什么变化(底层)
1. 1.7中底层是数组+链表,1.8中底层是数组+链表+红⿊树,加红⿊树的⽬的是提⾼HashMap插⼊和查询整体效率
2. 1.7中链表插⼊使⽤的是头插法,1.8中链表插⼊使⽤的是尾插法,因为1.8中插⼊key和value时需要判断链表元素个数,所以需要遍历链表统计链表元素个数,所以正好就直接使⽤尾插法
3. 1.7中哈希算法⽐较复杂,存在各种右移与异或运算,1.8中进⾏了简化,因为复杂的哈希算法的⽬的就是提⾼散列性,来提供HashMap的整体效率,⽽1.8中新增了红⿊树,所以可以适当的简化哈希算法,节省CPU资源
说⼀下HashMap的Put⽅法
先说HashMap的Put⽅法的⼤体流程:
1. 根据Key通过哈希算法与与运算得出数组下标
2. 如果数组下标位置元素为空,则将key和value封装为Entry对象(JDK1.7中是Entry对象,JDK1.8中是Node对象)并放⼊该位置
3. 如果数组下标位置元素不为空,则要分情况讨论
a. 如果是JDK1.7,则先判断是否需要扩容,如果要扩容就进⾏扩容,如果不⽤扩容就⽣成Entry对象,并使⽤头插法添加到当前位置的链表中
b. 如果是JDK1.8,则会先判断当前位置上的Node的类型,看是红⿊树Node,还是链表Node
i. 如果是红⿊树Node,则将key和value封装为⼀个红⿊树节点并添加到红⿊树中去,在这个过程中会判断红⿊树中是否存在当前key,如果存在则更新value
ii.如果此位置上的Node对象是链表节点,则将key和value封装为⼀个链表Node并通过尾插法插⼊到链表的最后位置去,因为是尾插法,所以需要遍历链表,在遍历链表的过程中会判断是否存在当前key,
如果存在则更新value,当遍历完链表后,将新链表Node插⼊到链表中,插⼊到链表后,会看当前链表的节点个数,如果⼤于等于8,那么则会将该链表转成红⿊树
ⅲ.将key和value封装为Node插⼊到链表或红⿊树中后,再判断是否需要进⾏扩容,如果需要就扩容,如果不需要就结束PUT⽅法
深拷⻉和浅拷⻉
深拷⻉和浅拷⻉就是指对象的拷⻉,⼀个对象中存在两种类型的属性,⼀种是基本数据类型,⼀种是实例对象的引⽤
1. 浅拷⻉是指,只会拷⻉基本数据类型的值,以及实例对象的引⽤地址,并不会复制⼀份引⽤地址所
指向的对象,也就是浅拷⻉出来的对象,内部的类属性指向的是同⼀个对象
2. 深拷⻉是指,既会拷⻉基本数据类型的值,也会针对实例对象的引⽤地址所指向的对象进⾏复制,
深拷⻉出来的对象,内部的属性指向的不是同⼀个对象
HashMap的扩容机制原理
1.7版本
1. 先⽣成新数组
2. 遍历⽼数组中的每个位置上的链表上的每个元素
3. 取每个元素的key,并基于新数组⻓度,计算出每个元素在新数组中的下标
4. 将元素添加到新数组中去
5. 所有元素转移完了之后,将新数组赋值给HashMap对象的table属性
1.8版本
1. 先⽣成新数组
2. 遍历⽼数组中的每个位置上的链表或红⿊树
3. 如果是链表,则直接将链表中的每个元素重新计算下标,并添加到新数组中去
4. 如果是红⿊树,则先遍历红⿊树,先计算出红⿊树中每个元素对应在新数组中的下标位置
a. 统计每个下标位置的元素个数
b. 如果该位置下的元素个数超过了6,则⽣成⼀个新的红⿊树,并将根节点的添加到新数组的对深拷⻉和浅拷⻉
c. 如果该位置下的元素个数没有超过6,那么则⽣成⼀个链表,并将链表的头节点添加到新数组的对应位置
5. 所有元素转移完了之后,将新数组赋值给HashMap对象的table属性
Java面试题全集(一)的更多相关文章
- Java面试题全集(上-中-下)及Java面试题集(1-50/51-70)
阅读量超百万级的文章,收藏并分享一下.感谢原创作者的总结 对初中级java开发人员有特别大的帮助,不论是技术点面试还是知识点总结上. Java面试题全集(上): https://blog.cs ...
- 整理+学习《骆昊-Java面试题全集(上)》
★可以关注微信公众号,了解更多技术和行业信息 2013年年底的时候,我看到了网上流传的一个叫做<Java面试题大全>的东西,认真的阅读了以后发现里面的很多题目是重复且没有价值的题目,还有不 ...
- Java面试题全集(下)转载
Java面试题全集(下) 这部分主要是开源Java EE框架方面的内容,包括hibernate.MyBatis.spring.Spring MVC等,由于Struts 2已经是明日黄花,在这里就不 ...
- Java面试题全集(上)转载
Java面试题全集(上) 2013年年底的时候,我看到了网上流传的一个叫做<Java面试题大全>的东西,认真的阅读了以后发现里面的很多题目是重复且没有价值的题目,还有不少的参考答案也是 ...
- Java面试题全集
Java面试题全集(上) Java面试题全集(中) Java面试题全集(下) http://www.importnew.com/21445.html
- Java面试题全集(上)
2013年年底的时候,我看到了网上流传的一个叫做<Java面试题大全>的东西,认真的阅读了以后发现里面的很多题目是重复且没有价值的题目,还有不少的参考答案也是错误的,于是我花了半个月时间对 ...
- 【转】Java面试题全集(上)
准备从C#转java,在找工作之前准备看看面试题,有幸看到大神的作品,mark一下,以后慢慢看... 2013年年底的时候,我看到了网上流传的一个叫做<Java面试题大全>的东西,认真的阅 ...
- Java面试题全集(上)(中)(下) (转)+自己总结
Java面试题 自己总总结 https://www.cnblogs.com/songanwei/p/9366427.html Java面试题全集(上) https://blog.csdn.net/ja ...
- java面试题全集(中)
这部分主要是与Java Web和Web Service相关的面试题. 96.阐述Servlet和CGI的区别? 答:Servlet与CGI的区别在于Servlet处于服务器进程中,它通过多线程方式运行 ...
- Java面试题全集(中)
这部分主要是与Java Web和Web Service相关的面试题. 96.阐述Servlet和CGI的区别? 答:Servlet与CGI的区别在于Servlet处于服务器进程中,它通过多线程方式运行 ...
随机推荐
- JUC中常见的集合
Map: HashMap ===> ConcurrentHashMap List: ArrayList ===> CopyOnWriteArrayList Set: HashSet === ...
- 快速上手Linux核心命令(七):Linux系统信息相关命令
目录 前言 uname 显示系统信息 hostname 显示或设置系统主机名 du 统计磁盘空间使用情况 echo 显示一行文本 watch 监视命令执行情况 stat whereis 显示命令及其相 ...
- 推荐两个AI神器:ChatGPT只需1个标题,2分钟全自动生成PPT!
今天给大家分享两个工具,帮助你全自动生成PPT,接下来以自动化测试为主题,教大家如何2分钟生成好PPT. 1.第一个工具:ChatGPT 1.打开ChatGPT页面,输入prompt,告诉它,让它帮你 ...
- PaddleDetection 快速上手
PaddleDetection 快速上手 本项目以路标数据集roadsign为例,详细说明了如何使用PaddleDetection训练一个目标检测模型,并对模型进行评估和预测. 本项目提供voc格式的 ...
- 使用Jmeter进行CPU、内存等监控
一.需要的准备 1.jp@gc - PerfMon Metrics Collector插件(安装方法就不过多介绍啦!) 2.ServerAgent服务器(下载:https://github.com/u ...
- intellij IDEA安装JDBC报错 No suitable driver found for jdbc:mysql://localhost:3306
项目场景: 本地尝试使用intellij IDEA加载JDBC连接MySQL,尝试实现增删改查,本来想做一个小Demo. 问题描述 报错: java.lang.ClassNotFoundExcepti ...
- std::cin 和 std::getline 混用的问题
如果存在如下的输入, 11 is a prime 考虑如下的程序, std::cin>>number; std::getline(std::cin,input) std::cin 在读取数 ...
- map和multimap
map相对于set区别,map具有键值和实值,所有元素根据键值自动排序,pair的第一个值被称为键值key,pair的第二个值被称为实值value.map也是以红黑树为底层实现机制,根据key进行排序 ...
- 2021-12-08:扑克牌中的红桃J和梅花Q找不到了,为了利用剩下的牌做游戏,小明设计了新的游戏规则: 1) A,2,3,4....10,J,Q,K分别对应1到13这些数字,大小王对应0; 2) 游
2021-12-08:扑克牌中的红桃J和梅花Q找不到了,为了利用剩下的牌做游戏,小明设计了新的游戏规则: A,2,3,4-10,J,Q,K分别对应1到13这些数字,大小王对应0; 游戏人数为2人,轮流 ...
- Golang接收者方法语法糖
1.概述 在<Golang常用语法糖>这篇博文中我们讲解Golang中常用的12种语法糖,在本文我们主要讲解下接收者方法语法糖. 在介绍Golang接收者方法语法糖前,先简单说下Go 语言 ...