2022年java3到4年面试题,分享一下我遇到的面试题

2022java面试题,分享一下我遇到的面试题 未更完

  • 一,基础知识
    • 1.怎么理解虚拟机?
      • 1.1 怎么理解虚拟机的堆栈呢?
      • 1.2 栈、队列中“先进先出”,“后进先出”的含义
    • 2.集合的一些知识
      • 2.1 用过哪些集合,他们的区别是什么
      • 2.2 线程安全的List
      • 2.3线程安全的Map
      • 2.4 hashMap和hashtable的区别
      • 2.5 hashMap底层实现原理

一,基础知识

大概就是一些java基础这样的,我把我最近遇到的都列举一下吧

1.怎么理解虚拟机?

List item

Java虚拟机(JVM)是可运行Java代码的假想计算机。只要根据JVM规格描述将解释器移植到特定的计算机上,就能保证经过编译的任何Java代码能够在该系统上运行.

Java虚拟机是一个想象中的机器,在实际的计算机上通过软件模拟来实现。Java虚拟机有自己想象中的硬件,如处理器、堆栈、寄存器等,还具有相应的指令系统。

Java虚拟机规范定义了一个抽象的——而非实际的——机器或处理器。这个规范描述了一个指令集,一组寄存器,一个堆栈,一个“垃圾堆”,和一个方法区。一旦一个Java虚拟机在给定的平台上运行,任何Java程序(编译之后的程序,称作字节码)都能在这个平台上运行。Java虚拟机(JVM)可以以一次一条指令的方式来解释字节码(把它映射到实际的处理器指令),或者字节码也可以由实际处理器中称作just-in-time的编译器进行进一步的编译。

1.1 怎么理解虚拟机的堆栈呢?

堆是堆(heap),栈是栈(stack) 栈中分配的是基本类型和自定义对象的引用。

堆中分配的是对象,也就是new出来的东西。 被所有线程共享。 方法区/静态区 存放的是类信息和static变量、常量。 被所有线程共享。
也可以这么理解:堆是用来存放对象的,栈是用来运行程序的。

堆:java的垃圾回收器会自动的回收这些不用的数据。缺点是由于要动态的分配内存,存储效率会比较的慢。

栈:栈的优势是存取效率比较快,仅次于寄存器,栈数据可以共享。但缺点是栈中的数据大小和生存期的固定的,缺乏灵活性。

一般每个方法的调用都会独立有一个栈来保存对象的引用变量,在方法返回后,栈会清空,当在一段代码块定义一个变量时,Java就在栈中为这个变量分配内存空间,当超过变量的作用域后,Java会自动释放掉为该变量所分配的内存空间,该内存空间可以立即被另作他用。

1.2 栈、队列中“先进先出”,“后进先出”的含义

栈和队列都是线性表,并且都是特殊的线性表:
特殊在于限制了插入和删除点。栈是在线性表的某固定一端插入和删除,因此特性为后进先出队列是在线性表的一端插入,另外一端删除,因此特性为先进先出。

相同之处:

n个(同类)
数据元素的有限序列称为线性表。线性表的特点是数据元素之间存在“一对一”的关系,栈和队列都是操作受限制的线性表,他们和线性表一样,数据元素之间都存在“一对一”的关系

不同之处:

栈只允许在一段进行插入或删除操作的线性表,其最大的特点是“后进后出”;
对列是只允许在一端进行插入,另一端进行删除操作的线性表,其最大的特点是“先进后出”

2.集合的一些知识

大概就是list map set 这些集合一些必备的知识

2.1 用过哪些集合,他们的区别是什么

List:元素有序、可重复

  1. ArrayList:底层是数组;查询快,增删慢;线程不安全,效率高
  2. Vector:(现在基本不用了) 底层是数组;查询快,增删慢;线程安全(方法都是synchronized),效率低
  3. LinkedList:底层是链表;查询慢,增删快;线程不安全;效率高

Set:元素无序、不可重复

  1. HashSet(无序):底层是哈希表,依赖hashCode()和equals()保证元素唯一性
  2. TreeSet(有序):底层是链表和哈希表,链表保证有序,哈希表保证唯一
  3. LinkedHashSet:基于LinkedHashMap 实现

Map:键值对,键唯一,值不唯一

  1. HashMap:JDK8之前HashMap由数组+链表组成的,数组是HashMap的主体,链表则是主要为了解决哈希冲突而存在的(“拉链法”解决冲突)。JDK8以后在解决哈希冲突时有了较大的变化,当链表长度大于阈值(默认为8)时,将链表转化为红黑树,以减少搜索时间
  2. LinkedHashMap: 继承自 HashMap,所以它的底层仍然是基于拉链式散列结构即由数组和链表或红黑树组成。另外,LinkedHashMap
    在上面结构的基础上,增加了一条双向链表,使得上面的结构可以保持键值对的插入顺序。同时通过对链表进行相应的操作,实现了访问顺序相关逻辑
  3. TreeMap:红黑树(自平衡的排序二叉树)
  4. Hashtable: 数组+链表组成的,数组是 HashMap 的主体,链表则是主要为了解决哈希冲突而存在的

2.2 线程安全的List

Vector
这是一个比较老旧的集合类,它与ArrayList 非常相似,都是基于数组实现。但是现在基本很少用了,面试时候知道原理就好,

SynchronizedList和SynchronizedRandomAccessList
它比Vector更为强大,它可以把所有的List接口实现类(包括ArrayList LinkedList等),都转为线程安全的list。


他有两种类型,都为Collections的静态内部类

  • SynchronizedList : (LinkedList等) :
  • SynchronizedRandomAccessList 实现了RandomAccess的list(ArrayList,Vector等)

2.3线程安全的Map

1,HashTable
HashTable的get/put方法都被synchronized关键字修饰,说明它们是方法级别阻塞的,它们占用共享资源锁,所以导致同时只能一个线程操作get或者put,而且get/put操作不能同时执行,所以这种同步的集合效率非常低,一般不建议使用这个集合。

2,SynchronizedMap
这个同步方式实现也比较简单,SynchronizedMap的实现方式是加了个对象锁,每次对HashMap的操作都要先获取这个mutex的对象锁才能进入,所以性能也不会比HashTable好到哪里去,也不建议使用。

3,ConcurrentHashMap (推荐使用)
这个是最推荐使用的线程安全的Map,是实现方式最复杂的一个集合,每个版本的实现方式也不一样,在jdk8之前是使用分段加锁的一个方式,分成16个桶,每次只加锁其中一个桶,而在jdk8又加入了红黑树和CAS算法来实现。

2.4 hashMap和hashtable的区别

HashMap 不是线程安全的
HashMap 是 map 接口的实现类,是将键映射到值的对象,其中键和值都是对象,并且不能包含重复键,但可以包含重复值。HashMap 允许 null key 和null value,而 HashTable 不允许。

HashTable 是线程安全 Collection(但是现在基本都推荐使用ConcurrentHashMap )
HashMap 是 HashTable 的轻量级实现,他们都完成了Map接口,主要区别在于 HashMap 允许 null key 和 null value,由于非线程安全,效率上可能高于 Hashtable。

Hashtable比HashMap多提供了elments() 和contains() 两个方法。
elments() 方法继承自Hashtable的父类Dictionnary。elements() 方法用于返回此Hashtable中的value的枚举。

contains()方法判断该Hashtable是否包含传入的value。它的作用与containsValue()一致。事实上contansValue() 就只是调用了一下contains() 方法。

2.5 hashMap底层实现原理

在JDK1.6,JDK1.7中,HashMap采用数组+链表实现,即使用链表处理冲突,同一hash值的链表都存储在一个链表里。但是当位于一个数组中的元素较多,即hash值相等的元素较多时,通过key值依次查找的效率较低。而JDK1.8中,HashMap采用数组+链表+红黑树实现,当链表长度超过阈值(8)时,将链表转换为红黑树,这样大大减少了查找时间。

你可能感兴趣的:(java,jvm,面试)