面试题笔记(java基础篇)

1 ArrayList和LinkList的区别

  1. 首先,他们的底层数据结构不同,ArrayList底层是基于数组实现的,LinkedList底层是基于链表实现的
  2. 由于底层数据结构不同,他们所使用的场景也不同,ArraryList更适合随机查找,LinkedList更适合删除和添加,查询添加删除的时间复杂度不同.
  3. 由于ArraryList和LinkedList都实现了List接口,但是LinkedList还额外实现了Deque接口,所以LinkedList还可以当作队列来使用

2 HashMap的Put方法

JDK8中:

  • 首先Put方法接受到key和value时,会利用key进行哈希算法得到这个key对应的哈希值.
  • 再通过这个哈希值与数组长度-1进行操作得到一个数组下标
  • 再判断数组下标位置是不是空着,如果空着,则直接把key和value封装为一个Node对象,并存入此数组位置
  • 如果此下标位置上非空,表示此位置上存在Node对象,那么则判断该Node对象是不是一个红黑树节点,如果是则将key和value封装为一个红黑树节点并添加到红黑树中去,在这个过程中会判断红黑树中是否存在当前key,如果存在则更新value
  • 如果此位置上的Node对象是链表节点,则将Key和value封装为一个链表Node并插入到链表中去
  • 插入到链表中后,会判断链表的节点个数是否超过8个,如果超过则把当前位置的链表转化为红黑树
  • 插入链表使用的是尾插法,所以需要便利链表,而这个过程中也会去判断key是否存在,如果存在则更新value.

3 JDK. JRE. JVM的关系

  • JDK(Java Development
    Kit)java开发工具包,JDK是整个java开发的核心,它集成了JRE和一些好用的小工具,比如java.exe,javac.exe,jar.exe.
  • JRE(Java Runtime
    Environment)Java运行时环境,它主要包括JVM的标准实现和Java类库,它相对于JVM来说主要多了Java的类库.
  • JVM(Java Virtual
    Machine)Java虚拟机,它只认识xx.class字节码文件,能根据文件中的字节码指令进行识别,并调用操作系统中向上的API完成动作.所以说,JVM时Java跨平台的核心.
  • 显然,这三者的关系是:一层层的嵌套关系。JDK>JRE>JVM。

4 两个对象的 hashCode()相同,则 equals()也一定为 true,对吗?

两个对象equals相等,则它们的hashcode必须相等,反之则不一定。
两个对象==相等,则其hashcode一定相等,反之不一定成立。

5 深拷贝和浅拷贝的区别?

假设B复制了A,修改A的时候,看B是否发生变化:
如果B跟着也变了,说明是浅拷贝,拿人手短!(修改堆内存中的同一个值)
如果B没有改变,说明是深拷贝,自食其力!(修改堆内存中的不同的值)
浅拷贝(shallowCopy)只是增加了一个指针指向已存在的内存地址,
深拷贝(deepCopy)是增加了一个指针并且申请了一个新的内存,使这个增加的指针指向这个新的内存,
使用深拷贝的情况下,释放内存的时候不会因为出现浅拷贝时释放同一个内存的错误。
浅复制:仅仅是指向被复制的内存地址,如果原地址发生改变,那么浅复制出来的对象也会相应的改变。
深复制:在计算机中开辟一块新的内存地址用于存放复制的对象。

6 什么是 java 序列化与反序列化?什么情况下需要序列化与反序列化?

  • Java 序列化是指:将对象转化成一个字节序列(二进制数据)的过程。
  • 将序列化对象写入文件之后,可以从文件中读取出来,并且对它进行反序列化。
  • Java 反序列化是指:将一个对象的字节序列恢复成 Java 对象的过程。
  • 一个平台中序列化的对象,可以在另一个平台中进行反序列化,因为这个过程是在 JVM 中独立完成的,可以依赖于 Java 的可移植性。

7 BIO、NIO、AIO有什么区别

  • BIO:线程发起IO请求,不管内核是否准备好IO操作,从发起请求起,线程一直阻塞,直到操作完成。

  • NIO:线程发起IO请求,立即返回;内核在做好IO操作的准备之后,通过调用注册的回调函数通知线程做IO操作,线程开始阻塞,直到操作完成。

  • AIO:线程发起IO请求,立即返回;内存做好IO操作的准备之后,做IO操作,直到操作完成或者失败,通过调用注册的回调函数通知线程做IO操作完成或者失败

  • BIO:同步并阻塞,服务器实现模式为一个连接一个线程,即客户端有连接请求时服务器端就需要启动一个线程进行处理,如果这个连接不做任何事情会造成不必要的线程开销,当然可以通过线程池机制改善。

  • NIO:同步非阻塞,服务器实现模式为一个请求一个线程,即客户端发送的连接请求都会注册到多路复用器上,多路复用器轮询到连接有I/O请求时才启动一个线程进行处理。

  • AIO:异步非阻塞,服务器实现模式为一个有效请求一个线程,客户端的I/O请求都是由OS先完成了再通知服务器应用去启动线程进行处理。
    适用场景分析

  • BIO方式适用于连接数目比较小且固定的架构,这种方式对服务器资源要求比较高,并发局限于应用中,JDK1.4以前的唯一选择,但程序直观简单易理解。

  • NIO方式适用于连接数目多且连接比较短(轻操作)的架构,比如聊天服务器,并发局限于应用中,编程比较复杂,JDK1.4开始支持。

  • AIO方式使用于连接数目多且连接比较长(重操作)的架构,比如相册服务器,充分调用OS参与并发操作,编程比较复杂,JDK7开始支持。

8 常见的异常类都有哪些,并简要说明

在这里插入图片描述

9 List、Set、Map的区别

List:
1.可以允许重复的对象。
2.可以插入多个null元素。
3.是一个有序容器,保持了每个元素的插入顺序,输出的顺序就是插入的顺序。
4.常用的实现类有 ArrayList、LinkedList 和 Vector。ArrayList 最为流行,它提供了使用索引的随意访问,而 LinkedList 则对于经常需要从 List 中添加或删除元素的场合更为合适。

Set:
1.不允许重复对象
2. 无序容器,你无法保证每个元素的存储顺序,TreeSet通过 Comparator 或者 Comparable 维护了一个排序顺序。
3. 只允许一个 null 元素
4.Set 接口最流行的几个实现类是 HashSet、LinkedHashSet 以及 TreeSet。最流行的是基于 HashMap 实现的 HashSet;TreeSet 还实现了 SortedSet 接口,因此 TreeSet 是一个根据其 compare() 和 compareTo() 的定义进行排序的有序容器。而且可以重复

Map:
1.Map不是collection的子接口或者实现类。Map是一个接口。
2.Map 的 每个 Entry 都持有两个对象,也就是一个键一个值,Map 可能会持有相同的值对象但键对象必须是唯一的。
3. TreeMap 也通过 Comparator 或者 Comparable 维护了一个排序顺序。
4. Map 里你可以拥有随意个 null 值但最多只能有一个 null 键。
5.Map 接口最流行的几个实现类是 HashMap、LinkedHashMap、Hashtable 和 TreeMap。(HashMap、TreeMap最常用)

10 Java容器(集合框架)都有哪些?

在这里插入图片描述

11 多线程run方法和start方法的区别?

  • run()方法只是一个类的普通方法,调用后自动压栈执行,执行完后弹栈便可.
  • start()方法作用开启一个分支线程,在JVM中开辟一块新的栈空间,代码执行完,自动结束,也就是说我们的start方法作用只是开辟空间,完成后就这行代码结束,我们的分支线程会自动调用run方法,也就是说我们的主线程在执行完.
    start方法后,剩下的主线程中的代码会和分支线程中的run方法共同抢夺CPU资源,进行抢占时间片执行代码!

12 HashMap的红黑树是什么?

HashMap 预期以链表数组的形式存储数据,即以 key 键的散列码计算索引,然后将元素插入到作为数组项的链表中(每个数组项称为桶)。为了提升查询的效率,HashMap 中存在一个阈值,当桶中的元素量超过这个阈值时,桶的数据结构就会从链表转变成红黑树。与红宝书中基于 2-3 树实现的红黑树不同,HashMap 中的红黑树基于 2-3-4 树实现。

HashMap 中的红黑树节点通过 TreeNode 类构造,并按照按 key 键的散列码由大到小排列,这样就保证了红黑树的有序性。在链表中,相同的散列码只能存储一个元素;在红黑树中却能存储多个元素。当散列码相同时,HashMap 会通过 compareComparables 比较 key 键乃至 tieBreakOrder 实例方法比较内存地址的散列码,以决定元素在红黑树中的位置。因此,HashMap 以静态方法形式实现了两个辅助函数:comparableClassFor 用于判断 key 键的构造器是否实现了 Comparable 接口;compareComparables 静态方法用于比较 key 键。

HashMap 中的红黑树需要解决以下问题:查询节点、插入节点、删除节点、以及红黑树和链表数据结构的相互转换。为了保证红黑树和链表数据结构的高效转换,TreeNode 实例包含 prev, next 属性指向上一个或下一个节点,因此 TreeNode 既携带着红黑树的结构信息,又携带着双向链表的结构信息。

  1. 插入节点:HashMap 首先会通过 putTreeVal 方法根据散列码顺序插入节点,然后通过 balanceInsertion
    调整红黑树的平衡性。当树中存在相同的 key 键时,putTreeVal 方法会返回已插入的节点。

  2. 删除节点:HashMap 首先会通过 removeTreeNode 方法删除节点;特定情况下,删除节点后需要
    balanceDeletion 调整红黑树的平衡性。

  3. 查询节点:依次通过比较 key 键的散列码、key 键、key 键内存地址的散列码在左右子树中查找节点。

  4. 红黑树和链表转换:在转换之前,无论红黑树和链表都保证了 key 键的唯一性。因此,当链表转换成红黑树时,只需根据 key 键的散列码或 key 键内存地址的散列码将链表节点插入到红黑树中的特定位置,然后使用 balanceInsertion调整树的平衡性。红黑树转换成链表时,只需顺序遍历 treeNode 节点的 next 属性即可。

13 CurrentHashMap,HashMap1.8有那些改动的?

14 说一下HashMap的底层原理,1.8和1.7有什么区别?

15 java的引用类型(强引用,弱引用,虚引用)简述

  • 强引用:
    java中最常见的就是强引用,把一个对象赋给一个引用变量,这个引用变量就是强引用,当一个对象被强引用变量引用时,就处于可达状态,他是不能被垃圾回收机制回收的.即便该对象永远都不会被用到也不会被回收.因此强引用时造成内存泄露的主要原因之一.
  • 软引用:
    软引用需要用SoftReference类来实现,对于软引用的对象来说,只要系统内存足够,他就不会被回收.当系统内存不足时,才会被回收.因此软引用对象一般存在于对内存敏感的程序中.软引用用来描述一些还有用,但非必须的对象。对于软引用关联的对象,在系统将要发生内存溢出异常之前,将会把这些对象列进回收范围之中并进行第二次回收。如果这次回收还没有足够的内存,才会抛出内存溢出异常。
  • 弱引用:
    弱引用需要WeakReference类来实现,它比软引用对象的存在时间更短,被弱引用关联的的对象只能存在垃圾回收器下一次回收之前,无论内存是否足够,都会被回收.
  • 虚引用:
    虚引用需要PhantomReference类来使用,它不能单独使用,必须和引用队列联合使用。虚 引用的主要作用是跟踪对象被垃圾回收的状态。
    虚引用被称为幽灵引用和幻影引用,他是最弱的一种引用关系,一个对象是否有虚引用的存在,完全不会对其生存时间产生影响,叶无法通过虚引用来取得一个实例对象.为一个对象设置虚引用关联的唯一作用就是希望这个对象被垃圾回收装置回收时产生一个系统通知.

16 转发和重定向的区别

  • 转发:
    用request的getRequestDispatcher()方法得到ReuqestDispatcher对象,调用forward()方法
request.getRequestDispatcher("other.jsp").forward(request,response);

转发地址栏不变,只提交一次请求,对request对象的信息不会丢失,因此可以在多个页面交互过程中实现请求数据的共享,转发是在服务器内部控制权的转移,是由服务器区请求,客户端并不知道是怎样转移的,因此客户端浏览器的地址不会显示出转向的地址。

  • 重定向:
    重定向:调用response的sendRedirect()方法
response.sendRedirect("other.jsp");

总结:

  • 转发使用的是getRequestDispatcher()方法;重定向使用的是sendRedirect();
  • 转发:浏览器URL的地址栏不变。重定向:浏览器URL的地址栏改变;
  • 转发是服务器行为,重定向是客户端行为;
  • 转发是浏览器只做了一次访问请求。重定向是浏览器做了至少两次的访问请求;
  • 转发2次跳转之间传输的信息不会丢失,重定向2次跳转之间传输的信息会丢失(request范围)

转发和重定向的选择:

1、重定向的速度比转发慢,因为浏览器还得发出一个新的请求,如果在使用转发和重定向都无所谓的时候建议使用转发。
2、因为转发只能访问当前WEB的应用程序,所以不同WEB应用程序之间的访问,特别是要访问到另外一个WEB站点上的资源的情况,这个时候就只能使用重定向了。
3.一般项目的增删改需要跳转到其他页面,所以用重定向。
而查询信息,一般只在当前页面,所以常用转发方式。
总之:通常情况下转发更快,而且能保持request内的对象,所以他是第一选择。但是由于在转发之后,浏览器中URL仍然指向开始页面,此时如果重载当前页面,开始页面将会被重新调用。如果你不想看到这样的情况,则选择重定向。

17 重写和重载的区别

重写和重载没有任何关系.重写时父类的方法不能满足子类得到需求而重写,与参数列表,方法名,返回值没有任何关系.重载值得是方法名相同,返回值类型不同,列表参数不同.

18 垃圾回收原理

在 JVM 进行垃圾回收之前,首先就是判断哪些对象是垃圾,也就是说,要判断哪些对象是可以被销毁的,其占有的空间是可以被回收的。根据 JVM 的架构划分,我们知道, 在 Java 世界中,几乎所有的对象实例都在堆中存放,所以垃圾回收也主要是针对堆来进行的。

在 JVM 的眼中,垃圾就是指那些在堆中存在的,已经“死亡”的对象。而对于“死亡”的定义,我们可以简单的将其理解为“不可能再被任何途径使用的对象”。那怎样才能确定一个对象是存活还是死亡呢?这就涉及到了垃圾判断算法,其主要包括引用计数法可达性分析法

在JVM确定了那些事是垃圾后,有四种算法进行回收:
1.Mark-Sweep(标记-清除)算法
2.Copying(复制)算法
3.Mark-Compact(标记-整理)算法(压缩法)
4.Generational Collection(分代收集)算法

19 谈谈你对面向对象的理解

封装,继承,多态是面向对象的三大特征:
封装:封装性就是尽可能的隐藏对象内部细节,对外形成一道边界,只保留有限的接口和方法与外界进行交互。封装的原则是使对象以外的部分不能随意的访问和操作对象的内部属性,从而避免了外界对对象内部属性的破坏。可以通过对类的成员设置一定的访问权限,实现类中成员的信息隐藏。
继承:子类的对象拥有父类的全部属性与方法,称作子类对父类的继承
多态:对象的多态性是指在父类中定义的属性或方法被子类继承之后,可以具有不同的数据类型或表现出不同的行为。这使得同一个属性或方法在父类及其各个子类中具有不同的语义。例如:"几何图形"的"绘图"方法,"椭圆"和"多边形"都是"几何图"的子类,其"绘图"方法功能不同。

20 selevt的访问流程(八个步骤)

  1. 用户输入一个网页地址
  2. tomcat会截取网页地址的后缀内容(除去根路径: http://IP 地址+端口)
  3. tomcat会默认到web.xml文件中查找所有的servlet-mapping,检查其中的url-pattern是否匹配.
  4. 如果检查到匹配项,则获取当前servlet-mapping中的servlet-name双标签中的值
  5. 通过第4步的值查找所有的servlet标签,搜索哪一个servlet标签的servlet-name是对应的值
  6. 如果匹配到对应的值,则调用对应的servlet标签中的servlet-class双标签中的值,并进行反射机制加载
  7. tomcat会把此servlet类对象初始化并且加载到内存中.
  8. 根据用户的请求模式,进行对应的方法调用,比如用户是get请求

21 堆和栈的区别

栈是一种运算受限的线性表,其限制是指只仅允许在表的一端进行插入和删除操作,这一端被称为栈顶(Top),相对地,把另一端称为栈底(Bottom)。把新元素放到栈顶元素的上面,使之成为新的栈顶元素称作进栈、入栈或压栈(Push);把栈顶元素删除,使其相邻的元素成为新的栈顶元素称作出栈或退栈(Pop)。这种受限的运算使栈拥有“先进后出”的特性(First In Last Out),简称FILO.

堆是一种常用的树形结构,是一种特殊的完全二叉树,当且仅当满足所有节点的值总是不大于或不小于其父节点的值的完全二叉树被称之为堆。堆的这一特性称之为堆序性。因此,在一个堆中,根节点是最大(或最小)节点。如果根节点最小,称之为小顶堆(或小根堆),如果根节点最大,称之为大顶堆(或大根堆)。堆的左右子节点没有大小的顺序。

22 java四种线程池

1.newSingleThreadExecutor
单个线程的线程池,即线程池中每次只有一个线程工作,单线程串行执行任务
2.newFixedThreadExecutor(n)
固定数量的线程池,没提交一个任务就是一个线程,直到达到线程池的最大数量,然后后面进入等待队列直到前面的任务完成才继续执行
3.newCacheThreadExecutor(推荐使用)
可缓存线程池, 当线程池大小超过了处理任务所需的线程,那么就会回收部分空闲(一般是60秒无执行)的线程,当有任务来时,又智能的添加新线程来执行。
4.newScheduleThreadExecutor
大小无限制的线程池,支持定时和周期性的执行线程

23 springboot自动装配原理

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java面试真题60道笔记是一本针对Java开发岗位的面试题集合。本书分为六个部分:基础知识与语法、面向对象、集合类、IO流与多线程、网络编程和数据库基础。每个部分都包括了该领域的常见问题和解答,以及一些实际场景中的应用题目。 在基础知识与语法部分,包括Java的数据类型、算术运算符、流程控制和异常处理等基本语法知识的问题。这些问题有助于检验应聘者对Java语言的熟悉程度。 面向对象部分则关注于类、对象、继承、多态和接口等面向对象的概念。这些问题旨在考察应聘者对面向对象编程的理解和实践经验。 集合类部分包括了常用的集合类容器,如List、Set和Map等,以及它们的特点和应用场景。这些问题可以考察应聘者对Java集合类的熟练掌握程度。 在IO流与多线程部分,问题主要涉及Java中的输入输出流和多线程编程。这些问题可以考察应聘者对Java的并发编程和IO操作的理解和应用能力。 网络编程部分主要涉及Java中的网络通信和Socket编程等知识。这些问题可以考察应聘者对网络编程的了解和实践经验。 最后,数据库基础部分主要涉及Java与数据库交互的知识,包括连接数据库、执行SQL语句和事务管理等内容。这些问题可以考察应聘者对数据库操作和数据持久化的了解和应用能力。 总之,Java面试真题60道笔记是一本综合性的Java面试题集,涵盖了基础知识、面向对象、集合类、IO流与多线程、网络编程和数据库基础等方面的内容,有助于应聘者在面试中更好地展示自己的技能和经验。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值