面试题(一)

目录

1.JDK、JRE、JVM之间的区别 

 2.hashcode()和equals()的区别

3.String、StringBuffer、StringBuilder的区别

4.泛型中extends和super的区别

5.==和equals()的区别

6.重写和重载的区别

7.List和Set的区别

8.ArrayList和LinkedList区别

9.谈谈ConcurrentHashMap的原理

10.谈谈 concurrentHashMap的扩容机制

11.Jdk1.7到Jdk1.8 HashMap 发⽣了什么变化(底层)?

12.说⼀下HashMap的Put⽅法

13.深拷⻉和浅拷⻉

14.HashMap的扩容机制原理

15.CopyOnWriteArrayList的底层原理是怎样的

16.什么是字节码?采⽤字节码的好处是什么?

17.Java中的异常体系是怎样的       

18.在Java的异常处理机制中,什么时候应该抛出异常,什么时候捕 获异常?

19.Java中有哪些类加载器

20.说说类加载器双亲委派模型


1.JDK、JRE、JVM之间的区别 

  1. JDK(Jav  aSE Development Kit): 提供了Java编译、运行的开发工具以及资源,包括了Java编译期,Java运行时环境和Java的类库
  2. JRE(Java Runtime Enviroment): 就是所谓的java运行时环境,用于运行class文件。其中包括了JVM和JVM所需的类库,普通人员只需要安装JRE就可以跑一个java项目,开发人员必须安装Jdk进行编写java程序。
  3. JVM(Java Virtual Mechinal):java虚拟机,也是JRE的一部分。其作用就是Java想要跨平台运行,就要用到JVM来运行class字节码文件。
  4. 举例:  如果你想写java程序,就可以用txt来编写,最后把txt文件通过javac 编译一下,编译成字节码文件,JVM可以执行字节码文件,这样就可以运行一个java程序。

 2.hashcode()和equals()的区别

   hashcode():  意思就是就是当对象调用hashcode()方法时,会计算出一个hash值,其实就行相当于那个对象的指纹信息,但是Java中不能保证每个对象的指纹信息(hash值)唯一,就是不能完全保证不相同,也是会有相同的可能性,比如:

                   1.如果这两个对象的hashcode不相同,则这两个对象肯定不会是同一个。

                    2.如果这两个对象的hashcode相同,并不能说是同一对象,也有可能是两个对象

                    3.如果两个对象相同,则hashcode一定相同

   当java中的集合类比较两个对象是否相等,就跟上面一样,先调用对象的hashcode()方法,先进行比较,如果不相同,则两个对象一定不相同,如果说相同的话,就要在调用equals()方法再次进行比较,用来判断这两个对象到底是否相等。equals()方法是比较重的比较方法,hashcode()方法是较轻的,就需要计算出哈希值,就是所谓的数字进行比较,所以会先调用hashcode()方法。

3.String、StringBuffer、StringBuilder的区别

   String 是一个不可变字符串,源码是一个final修饰的char数组,private final char value[];如果要修改这个字符串的话,就是又创建了一个String对象,StringBuffer和StringBuilder是可变字符串。可以通过他们的append()改变。

  StringBuffer是线程安全的,StringBulider是线程不安全的,单线程效率下使用StringBuilder效率更高

StringBuffer 的append()方法源码:通过加锁来实现线程安全的

StringBulider的append()源码:

4.泛型中extends和super的区别

1.< ? extends T > 表示包括T在内的任何T的子类

2.< ? super T >表示包括T在内的任何T的父类

5.==和equals()的区别

  ==:如果是基本数据用==比较的就是值,如果是引用数据类型用==比较的就是地址。

  equals(): 比较的是两个之间的内容是否相等

6.重写和重载的区别

  1. 重载(Overload):  在一个类中,同名的方法(参数类型不同,参数个数不同,参数顺序不同)则视为重载。
  2. 重写(Override): 重写的意思就是重写一遍,发生在子类继承父类的时候,方法重写方法名,参数类型,返回值必须相同,且访问权限必须大于父类,抛出的异常也必须小于父类。

7.List和Set的区别

  1. List: 有序,可重复,可以add多个null,可以通过迭代器来取出各个元素,也可以通过get(index)来取出指定下标元素。
  2. Set: 无序,不重复,最多只能有与一个null对象,只能通过迭代器(iterator)取出所有元素。

8.ArrayList和LinkedList区别

  1. ArrayList: 基于动态数组实现,是一个有序集合,比较适合查询操作效率更高,通过add()方法添加集合中,如果指定下标add(index)添加的效率比较慢,因为涉及到元素的移动,后面的元素会向后移动,就涉及到数组的扩容机制,所以效率比较慢。
  2. LinkedList: 基于链表实现,更适合元素的添加、删除,不适合查询,查询要遍历所有元素,实现了Deque,可以用来当做队列。添加元素时添加到集合的首尾速率较快。
  3. 两个集合都实现了List接口。

9.谈谈ConcurrentHashMap的原理

谈到ConcurrentHashMap就要讲一讲jdk 1.7 和 jdk 1.8 的区别

jdk1.7版本:ReentrantLock + Segment + Entry

        1.通过分段式锁Segment来实现,其实就是一个Segment数组,一个Segment对象里面包含了一个HashEntry.

        2.调用put(key,value) 方法时,根据源码分析,先是调用hashcode()方法计算出哈希值,再把算出来的(hash值和Segment数组.length-1)进行与运算,计算出相对应Segment下标(index),在多线程并发下,线程回去竞争lock()锁,调用Segment.lock();意思就是如果线程1加锁,就执行线程1,线程2就要等待。线程1执行后还要进行(hash值和entry.length-1)的与运算,计算出Segment[index]对象中Entry的数组下标,找到之后记性插入,如果没有元素直接插入,如果有的话就插入在后面,就行成了一个链表。

jdk1.8版本: Synchronized + Node + CAS + 红黑树

数组有多长,锁的量就有多大,因为每一个锁是锁Node 的首节点,多线程环境下操作时,操作同一个Node时,会排队等待,多个元素插入变成一个链表,大数据涌入时每次都要调用.next()方法性能比较慢,所以就要引用红黑树,当链表的长度大于8时,就变成一颗红黑树来提升效率。
 

10.谈谈 concurrentHashMap的扩容机制

jdk1.7版本: 

        1.concurrentHashMap是由Segment实现

        2.Segment内部相当于一个HasMap

        3.每个Segment会自动扩容,也就跟HashMap扩容类似

        4.先生成新的数组,然后转移元素到新的数组上去

        5.是否需要扩容是Segment内部判断的,每个Segment单独判断

jdk1.8版本:

        1.不在有Segment实现

        2.当某个线程进行put时,如果发现ConcurrentHashMap正在进行扩容,那么就加入一起进行扩容。

        3.当某个线程进行put时,发现没有正在扩容,那么就将key-value添加到ConcurrentHashMap中,然后判断阈值,是否需要扩容

        4. ConcurrentHashMap支持多线程进行扩容

        5.扩容之前生成一个新的数组

        6.在转移元素时,先将原数组分组,然后交给不同的线程来进行元素的转移,每个线程分组一组或者多组

11.Jdk1.7到Jdk1.8 HashMap 发⽣了什么变化(底层)?

  • JDK1.7 用的是数组+链表实现的,JDK1.8用得是数组+链表+红黑树,加入红黑树的原因就是加快查询和修改的效率
  • 1.7中链表采用的是头插法,1.8采用的就是尾插法,因为1.8中插入key和value时需要判断练链表元素个数,所有需要遍历整个链表,所有正好采用尾插法。
  • 1.7哈希算法比较复杂,存在各种右移与异或运算,1.8中进行了简化,因为复杂的哈希算法就是为了提高散列性,来提供整个HashMap的效率,而1.8中提供了红黑树,所以可以适当的简化哈希算法,节省CPU资源。

12.说⼀下HashMap的Put⽅法

先说HashMap的Put⽅法的⼤体流程:
  • 根据Key通过哈希算法与与运算得出数组下标
  •  如果数组下标位置元素为空,则将key和value封装为Entry对象(JDK1.7中是Entry对象,JDK1.8中 是Node对象)并放⼊该位置
  • 如果数组下标位置元素不为空,则要分情况讨论
  •  如果是JDK1.7,则先判断是否需要扩容,如果要扩容就进⾏扩容,如果不⽤扩容就⽣成Entry对 象,并使⽤头插法添加到当前位置的链表中
  • 如果是JDK1.8,则会先判断当前位置上的Node的类型,看是红⿊树Node,还是链表Node
  •  如果是红⿊树Node,则将key和value封装为⼀个红⿊树节点并添加到红⿊树中去,在这个 过程中会判断红⿊树中是否存在当前key,如果存在则更新value
  • 如果此位置上的Node对象是链表节点,则将key和value封装为⼀个链表Node并通过尾插 法插⼊到链表的最后位置去,因为是尾插法,所以需要遍历链表,在遍历链表的过程中会 判断是否存在当前key,如果存在则更新value,当遍历完链表后,将新链表Node插⼊到链 表中,插⼊到链表后,会看当前链表的节点个数,如果⼤于等于8,那么则会将该链表转成 红⿊树
  •  将key和value封装为Node插⼊到链表或红⿊树中后,再判断是否需要进⾏扩容,如果需要 就扩容,如果不需要就结束PUT⽅法

13.深拷⻉和浅拷⻉

  • 深拷贝与浅拷贝都是指对象的拷贝,一个对象中存在两种属性,一种是基本数据类型,一种是实例对象的引用
  • 浅拷贝: 只会拷贝基本数据类型的值,以及实例对象的引用地址,并不会拷贝引用地址所指向的对象,也就是拷贝出来的对象,内部的类属性指向的是同一个对象
  • 深拷贝: 既会拷贝基本数据类型的值也会拷贝引用地址所指向的对象进行复制,深拷贝出来的对象,内部的属性指向的不是同一个对象

14.HashMap的扩容机制原理

1.7版本
        1. 先⽣成新数组
        2. 遍历⽼数组中的每个位置上的链表上的每个元素
        3. 取每个元素的key,并基于新数组⻓度,计算出每个元素在新数组中的下标
        4. 将元素添加到新数组中去
        5. 所有元素转移完了之后,将新数组赋值给HashMap对象的table属性
1.8版本
        1. 先⽣成新数组
        2. 遍历⽼数组中的每个位置上的链表或红⿊树
        3. 如果是链表,则直接将链表中的每个元素重新计算下标,并添加到新数组中去
        4. 如果是红⿊树,则先遍历红⿊树,先计算出红⿊树中每个元素对应在新数组中的下标位置
                a. 统计每个下标位置的元素个数
                b. 如果该位置下的元素个数超过了8,则⽣成⼀个新的红⿊树,并将根节点的添加到新数组的对应位置       
                  c. 如果该位置下的元素个数没有超过8,那么则⽣成⼀个链表,并将链表的头节点添加到新组的对应位置
        5. 所有元素转移完了之后,将新数组赋值给HashMap对象的table属性

15.CopyOnWriteArrayList的底层原理是怎样的

1. ⾸先CopyOnWriteArrayList内部也是⽤过数组来实现的,在向CopyOnWriteArrayList添加元素
时,会复制⼀个新的数组,写操作在新数组上进⾏,读操作在原数组上进⾏
2. 并且,写操作会加锁,防⽌出现并发写⼊丢失数据的问题
3. 写操作结束之后会把原数组指向新数组
4. CopyOnWriteArrayList允许在写操作时来读取数据,⼤⼤提⾼了读的性能,因此适合读多写少的应 ⽤场景,但是CopyOnWriteArrayList会⽐较占内存,同时可能读到的数据不是实时最新的数据,所 以不适合实时性要求很⾼的场景

16.什么是字节码?采⽤字节码的好处是什么?

编译器(javac)将Java源⽂件(*.java)⽂件编译成为字节码⽂件(*.class),可以做到⼀次编译到处运⾏, windows上编译好的class⽂件,可以直接在linux上运⾏,通过这种⽅式做到跨平台,不过Java的跨平 台有⼀个前提条件,就是不同的操作系统上安装的JDK或JRE是不⼀样的,虽然字节码是通⽤的,但是 需要把字节码解释成各个操作系统的机器码是需要不同的解释器的,所以针对各个操作系统需要有各⾃ 的JDK或JRE。
采⽤字节码的好处,⼀⽅⾯实现了跨平台,另外⼀⽅⾯也提⾼了代码执⾏的性能,编译器在编译源代码 时可以做⼀些编译期的优化,⽐如锁消除、标量替换、⽅法内联等

17.Java中的异常体系是怎样的       

  • Java中的所有异常都来⾃顶级⽗类Throwable。
  • Throwable下有两个⼦类Exception和Error。
  • Error表示⾮常严重的错误,⽐如java.lang.StackOverFlowErrorJava.lang.OutOfMemoryError,
  • 通常这些错误出现时,仅仅想靠程序⾃⼰是解决不了的,可能是虚拟机、磁盘、操作系统层⾯出现
  • 的问题了,所以通常也不建议在代码中去捕获这些Error,因为捕获的意义不⼤,因为程序可能已经 根本运⾏不了了。
  • Exception表示异常,表示程序出现Exception时,是可以靠程序⾃⼰来解决的,⽐如
  • NullPointerException、IllegalAccessException等,我们可以捕获这些异常来做特殊处理。
  • Exception的⼦类通常⼜可以分为RuntimeException和⾮RuntimeException两类
  • RunTimeException表示运⾏期异常,表示这个异常是在代码运⾏过程中抛出的,这些异常是⾮检查 异常,程序中可以选择捕获处理,也可以不处理。这些异常⼀般是由程序逻辑错误引起的,程序应该从逻 辑⻆度尽可能避免这类异常的发⽣,⽐如NullPointerException、IndexOutOfBoundsException等。
  • ⾮RuntimeException表示⾮运⾏期异常,也就是我们常说的检查异常,是必须进⾏处理的异常,如果 不处理,程序就不能检查异常通过。如IOException、SQLException等以及⽤户⾃定Exception异常。

18.在Java的异常处理机制中,什么时候应该抛出异常,什么时候捕 获异常?

  • 异常相当于⼀种提示,如果我们抛出异常,就相当于告诉上层⽅法,我抛了⼀个异常,我处理不了这个 异常,交给你来处理,⽽对于上层⽅法来说,它也需要决定⾃⼰能不能处理这个异常,是否也需要交给 它的上层。
  • 所以我们在写⼀个⽅法时,我们需要考虑的就是,本⽅法能否合理的处理该异常,如果处理不了就继续 向上抛出异常,包括本⽅法中在调⽤另外⼀个⽅法时,发现出现了异常,如果这个异常应该由⾃⼰来处理,那就捕获该异常并进⾏处理。

19.Java中有哪些类加载器

  • JDK⾃带有三个类加载器:bootstrap ClassLoader、ExtClassLoader、AppClassLoader。
  • BootStrapClassLoader是ExtClassLoader的⽗类加载器,默认负责加载%JAVA_HOME%lib下的 jar包和class⽂件。
  • ExtClassLoader是AppClassLoader的⽗类加载器,负责加载%JAVA_HOME%/lib/ext⽂件夹下的 jar包和class类。
  • AppClassLoader是⾃定义类加载器的⽗类,负责加载classpath下的类⽂件。

20.说说类加载器双亲委派模型

  • JVM中存在三个默认的类加载器:1. BootstrapClassLoader 2. ExtClassLoader 3.AppClassLoader
  • AppClassLoader的⽗加载器是ExtClassLoader,ExtClassLoader的⽗加载器是 BootstrapClassLoader。 JVM在加载⼀个类时,会调⽤AppClassLoader的loadClass⽅法来加载这个类,不过在这个⽅法中,会 先使⽤ExtClassLoader的loadClass⽅法来加载类,同样ExtClassLoader的loadClass⽅法中会先使⽤ BootstrapClassLoader来加载类,如果BootstrapClassLoader加载到了就直接成功,如果 BootstrapClassLoader没有加载到,那么ExtClassLoader就会⾃⼰尝试加载该类,如果没有加载到, 那么则会由AppClassLoader来加载这个类。
  • 所以,双亲委派指得是,JVM在加载类时,会委派给Ext和Bootstrap进⾏加载,如果没加载到才由⾃⼰ 进⾏加载。
  • 总结一句话就是,向上委派,向下加载

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/769685.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

LangChain核心模块 Retrieval——文档加载器

Retrieval ​ 许多LLM申请需要用户的特定数据&#xff0c;这些数据不属于模型训练集的一部分&#xff0c;实现这一目标的主要方法是RAG(检索增强生成)&#xff0c;在这个过程中&#xff0c;将检索外部数据&#xff0c;然后在执行生成步骤时将其传递给LLM。 ​ LangChain 提供…

Unsafe的CAS操作及线程park与unpark

如下是一个参照AQS进行的一个加锁及解锁的简单实现&#xff1a; 多线程并发进行同步业务操作&#xff1b;加锁&#xff1a;尝试进行cas 0->1操作&#xff1b;如果加锁成功则进行业务处理&#xff0c;然后进行锁释放 1->0&#xff0c;然后将列头的线程进行唤醒&#xff1…

GDAL中的地理坐标系、投影坐标系及其相互转换

目录 地理坐标系 国内常用地理坐标系 投影坐标系 国内常用投影坐标系&#xff08;不推荐使用&#xff09; 坐标转换 地理坐标转为投影坐标 投影坐标转为地理坐标 地理坐标系 原理参考这篇文章&#xff1a;地理坐标系与投影坐标系区别与联系 https://yunxingluoyun.blog.…

webserver如何从零开始?

我们要做一个项目&#xff0c;过程是怎么样的呢&#xff1f;git clone ...部署&#xff0c;测试&#xff0c;然后开始写么&#xff0c;这样你大概率会“猪脑过载”&#xff0c;对一个项目的每个部分都没有清晰认识&#xff0c;能写出什么来&#xff1f;写之前当然需要测试每个功…

Linux网络协议栈从应用层到内核层③

文章目录 1、write源码剖析2、vfs层进行数据传输3、socket层进行数据传输4、tcp层进行数据传输5、ip层进行数据传输6、网络设备层进行数据传输7、网卡驱动层进行数据传输8、数据传输的整个流程 1、write源码剖析 系统调用原型 ssize_t write(int fildes, const void *buf, si…

Linux 在线yum安装: PostgreSQL 15.6数据库

Linux 在线yum安装&#xff1a; PostgreSQL 15.6数据库 1、PostgreSQL数据库简介2、在线安装PostgreSQL15.63、配置 PostgreSQL的环境变量4、使用默认用户登录PostgreSQL5、配置 PostgreSQL 允许远程登录6、修改 PostgreSQL 默认端口7、创建数据库和表、远程用户zyl8、pgAdmin远…

MATLAB环境下基于离散小波变换和主成分平均的医学图像融合方法

随着计算机技术和生物影像工程的日趋成熟&#xff0c;医学图像为医疗诊断提供的信息越来越丰富。目前&#xff0c;由于医学成像的设备种类繁多&#xff0c;导致医生获得的图像信息差异较大。如何把这些信息进行整合供医生使用成为当务之急。基于此&#xff0c;医学图像融合技术…

vue3+vite配置环境变量

1、创建环境变量文件&#xff1a;首先在vue3项目根目录创建.env.development 和 .env.prodution两个文件&#xff0c;分别为开发和生产环境&#xff08;必须.env.开头&#xff0c;需要额外环境&#xff0c;配置自定义的文件名称即可&#xff09; 2、在环境变量文件分别写对应…

Android内存优化项目经验分享 兼顾效率与性能

背景 项目上线一段时间后,回顾重要页面 保证更好用户体验及生产效率&#xff0c;做了内存优化和下载导出优化&#xff0c;具体效果如最后的一节的表格所示。 下面针对拍摄流程的两个页面 预览页 导出页优化实例进行介绍&#xff1a; 一.拍摄前预览页面优化 预览效果问题 存在…

试试前端自动化测试(基础篇)

众所周知的原因&#xff0c;前端作为一种特殊的 GUI 软件&#xff0c;做自动化测试困难重重。在快速迭代&#xff0c;UI 变动大的业务中&#xff0c;自动化测试想要落地更是男上加男 &#x1f436;。 近期的学习过程中&#xff0c;翻阅了众多前端自动化测试相关的文章&#xf…

【3D reconstruction 学习笔记】

三维重建 3D reconstruction 1. 相机几何针孔相机摄像机几何 2. 相机标定线性方程组的解齐次线性方程组的解非线性方程组的最小二乘解透镜相机标定带畸变的相机标定 3. 单视图重建2D平面上的变换3D空间上的变换单视测量无穷远点 无穷远线 无穷远平面影消点 影消线单视重构 4. 三…

天艺制盖邀您参观2024第七届世界燕窝及天然滋补品博览会

2024第七届世界燕窝及天然滋补品博览会 2024年8月7-9日| 上海新国际博览中心 上海燕博会 世界燕窝及天然滋补品展览会暨世界滋补产业生态发展大会&#xff08;简称上海燕博会&#xff09;&#xff0c;2017年创办于中国上海&#xff0c;是一年一度的世界燕窝滋补品行业盛会。…

运放PSRR与开关电源纹波分析的实际案例分享!

本文来自看海原创视频教程&#xff1a;《运放秘籍》运算放大器基础精讲及应用第一部*开天 微信公众号&#xff1a;工程师看海 【淘宝】https://m.tb.cn/h.5PAjLi7?tkvmMLW43KO7q CZ3457 「运放秘籍_运算放大器Multisim仿真视频教程第一部开天_工程师看海」 点击链接直接打开 …

k8s入门到实战(一)—— kubernetes概述

k8s 概述 k8s github地址&#xff1a;https://github.com/kubernetes/kubernetes 官方文档&#xff1a;https://kubernetes.io/zh-cn/docs/home/ k8s&#xff0c;全程是 kubernetes&#xff0c;这个名字源于希腊语&#xff0c;意为"舵手"或"飞行员” k8s 这…

启动性能优化

一、应用启动慢的原因 1.在主线程执行了太多耗时的操作&#xff0c;比如加载数据&#xff0c;或者初始化三方库等等&#xff0c;导致在Application的oncreate或者Activity的oncreate方法中耗时太久 2.布局嵌套太深&#xff0c;或者一些不会立即使用的布局也在一开始一起加载到…

Offlian RL: Weighted Policy Constraints for Offline Reinforcement Learning

AAAI 2023 paper Intro 分布偏移导致离线RL对于OOD数据存在过估计问题。因此一些方法限制策略靠近行为策略。但是着很大程度受限于数据集的质量。若是数据集存在非专家&#xff0c;一个自然的问题是是否有可能构建一个更合理的策略约束方法&#xff0c;该方法通过识别数据集中…

SpringBoot 3整合Elasticsearch 8

这里写自定义目录标题 版本说明spring boot POM依赖application.yml配置新建模型映射Repository简单测试完整项目文件目录结构windows下elasticsearch安装配置 版本说明 官网说明 本文使用最新的版本 springboot: 3.2.3 spring-data elasticsearch: 5.2.3 elasticsearch: 8.1…

2024年软件测试岗现状?“我“进阶了测试开发,一路狂飙...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 1、测试工程师的现…

SM2098EHD:巴西双电压球泡灯应用

巴西使用的双电压系统主要包括127V和240V。这种双电压系统是为了适应不同的电器设备和需求。在巴西&#xff0c;有些电器设备可能需要127V的电压&#xff0c;而有些则可能需要240V的电压。 因此&#xff0c;如果你在巴西使用电器设备&#xff0c;需要确保设备能够适应巴西的双…

【数据结构】绪论

文章目录 开篇&#xff1a;数据结构的学习之路1、开篇_数据结构在学什么2、数据结构的基本概念数据数据元素、数据项数据结构、数据对象数据类型、抽象数据类型数据结构的三要素逻辑结构数据的物理结构&#xff08;存储结构&#xff09;数据的运算 最后总结内容 3、算法的基本概…