java面试题目汇总01

ArrayList的底层原理,和LinkedList的区别

① 数据结构不同

ArrayList是Array(动态数据数组)的数据结构,LinkedList是Link(链表)的数据结构。

② 效率不同

随机访问时List时,ArrayList比LinkedList的效率要高,因为LinkedList是线性的数据存储,需要移动指针从前往后依次查找。

HashMap的底层原理,和HashTable的区别,和HashSet的区别

HashMap底层原理:HashMap的数据结构为 数组+(链表或红黑树)

put的实现原理:

通过key的hashcode()方法得到hash值,通过hash值和数组长度得到数组的下标。

如果下标的位置上没有任何元素,就把Node添加到这个位置上。

如果下标的位置上有链表,就会拿着key和链表上每个节点的k进行equals。

如果所有的equals方法都是返回false,那么这个新节点将被添加到链表的末尾。

如果其中一个equals返回了true,那么这个节点的value就会被覆盖。

get的实现原理:

先调用k的hashcode()方法得到hash值,通过hash值和数组长度得到数组下标。

如果这个位置上什么都没有,返回null。

如果这个位置上有单向链表,拿着k和单向链表中的每一个节点的k进行equals,如果equals方法都返回了false,返回null;如果其中一个节点的k和节点参数的k进行equals为true,那么返回该节点的value值。

hashmap和hashtable的区别:

① hashmap线程不安全,hashtable是线程安全的(方法都加上了synchronized)

② hashmap可以支持null(key为null or value为null),hashtable都不支持。

public V put(K key, V value) {
       if (table == EMPTY_TABLE) {
           inflateTable(threshold);
       }
       if (key == null)
           return putForNullKey(value);
       int hash = hash(key);
       int i = indexFor(hash, table.length);
       for (Entry<K,V> e = table[i]; e != null; e = e.next) {
           Object k;
           if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
               V oldValue = e.value;
               e.value = value;
               e.recordAccess(this);
               return oldValue;
           }
       }

       modCount++;
       addEntry(hash, key, value, i);
       return null;
   }

hashmap和hashset的区别:

① hashset使用add()方法添加元素,实际上还是调用hashmap的put方法,添加的元素放在key中,value都是统一的一个固定对象。

② add元素时,会判断key是否存在,如果key存在则修改Entry节点value的值,如果key不存在,则插入。

private static final Object PRESENT = new Object(); 

public boolean add(E var1) {
       return this.map.put(var1, PRESENT) == null;
   }
ConcurrentHashMap的底层原理,和HashTable的区别

concurrentHashMap特性and原理:

特性:

concurrentHashMap是不允许key/value为空

原理:

使用segment继承了ReetrantLock,使用了分段锁技术来保证线程安全

将数据分成一段一段的储存,然后给每一段数据配一把锁,多线程访问不同段的数据时,就不会存在锁竞争。

jdk1.8之前:(Segments数组+ HashEntry数组 + 链表)

每一个segment就是一个HashEntry<K,V>[] table,table中的每一个元素本质上都是一个HashEntry的单向队列(原理和hashMap一样)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dJWxKKTF-1631955380285)(C:\Users\50470\AppData\Roaming\Typora\typora-user-images\image-20210802160651351.png)]

put元素:

​ concurrentHashMap不允许key/value为空,通过key的hashcode()方法获取hash值,通过segmentShift 和 segmentMask去定位segment数组的下标。

​ 同时因为segments是一个数组,然后每个元素里面又嵌套一个数组,每次put元素的时候,需求计算两次hash值,第一次计算segment[]数组下标,第二次计算HashEnter数组下标。

get元素:

​ get方法无需加锁,涉及到的共享变量都使用volatile修饰,volatitle可以保证内存的可见性,切防止了指令重新排序,不会读取到过期数据。

jdk1.8之后:(数组 + 链表 + 红黑树 + cas + synchronized)

抛弃了segments数组,去掉了分段锁的方案,改用了和HashMap一样的结构操作,也就是数组+ 链表 + 红黑树,在并发方面,使用cas + synchronized的方式保证数据的一致性。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xjLrd1Tw-1631955380288)(C:\Users\50470\AppData\Roaming\Typora\typora-user-images\image-20210802161950364.png)]

链表转为红黑树的条件:

​ ① 数组中任意一个链表长度超过8个

​ ② 数组长度大于64个

jdk1.7和1.8中hashMap的区别

① 数据插入方式不同

​ jdk1.7用的头插法,jdk1.8用的是尾插法

头插法容易出现逆序且环形链表死循环问题;尾插法能够避免。

② 数据结构不同

​ jdk1.7的时候使用的是数组 + 单向链表数据结构;jdk1.8使用的是数组 + 链表 + 红黑树(当链表长度达到8的时候,自动的转变为红黑树)

③ 扩容方式不一样

④ 下标计算不一样

volatile、synchronized、Lock,ReenTrantLock的底层原理和区别

volatile 与 synchronized

① volatile仅能在变量级别使用,synchronized可以在变量和方法。

② volatile本质上是告诉jvm当前变量是不确定的,需要从主内存中取;synchronized则是锁定当前变量,只有当前线程可以访问该变量,其他线程被阻塞。

③volatile仅能实现变量的可见性,synchronized可以保证变量的可见性和原子性。

④volatile不会造成线程阻塞,synchronized可能回造成线程阻塞。

synchronized 与 lock

① Lock是一个接口,synchronized 是java中的关键字。

②synchronized 在发生异常时回自动释放线程占用的锁。lock在发生异常时,如果没有手动调用unlock(),很可能造成死锁,因此使用lock需要在finnally中释放锁。

③lock可以知道有没有成功的获取到锁,synchronized 无法判断。

ReenTrantLock 与 synchronized

① ReenTrantLock 和synchronized都是独占锁,synchronized加锁解锁是隐式的,操作简单,但不够灵活。

ReenTrantLock 需要手动加锁解锁,且解锁尽量放在finally中,确保能正确的释放锁。

② synchronized 和 ReenTrantLock 都是可重入锁,ReentrantLock可重入要确保获取锁的获取次数和锁的释放次数要一样。

③ synchronized默认为非公平锁,ReenTrantLock 可实现非公平锁和公平锁。

CAS和AQS的底层原理和区别

CAS:比较和交换,CAS是一个原子性操作,要么成功要么失败,CAS不需要加锁,是一种乐观锁的方式,如果CAS操作失败,会不断重试直到成功。

CAS无法保证代码块的原子性,CAS只能保证单个变量的原子性操作,如果要保证多个变量的原子性操作就要使用悲观锁。

AQS:抽象的队列同步器,是一个同步器框架。

乐观锁和悲观锁的区别

乐观锁:每次拿数据的时候都认为别人不会修改,不会上锁,但是在更新的时候会判断一下再次期间别人有没有取更新数据,可以使用版本号等机制。

乐观锁多适用于多读的场景。

悲观锁:每次拿数据的时候都认为别人会修改,所以每次拿数据的时候都会上锁,其他人想拿到这个数据就会block直到获取到锁,在操作之前先上锁。

悲观锁多使用与多写的场景。

JVM与Java的内存模型
String的常用方法,以及为什么不能修改,继承

indexOf(),length(),String被final修饰,无法继承和修改。String中的方法,都会重新返回一个new String()的对象,不会对原本的数据进行改变。

对事物的传播行为和理解

Spring七种事物传播行为:

​ ① required,必须,默认值,A如果有事务,B将使用该事务;如果A没有事务,B将创建一个新的事务。

​ ② supports,支持,A如果有事务,B将使用该事务;如果A没有事务,B将以非事务执行。

​ ③ mandatory,强制,A如果有事务,B将使用该事务;如果A没有事务,B将抛异常。

​ ④ requires_new,必须新的,如果A有事务,将A的事务挂起,B创建一个新的事务;如果A没有事务,B创建一个新的事务。

​ ⑤ not_supported ,不支持,如果A有事务,将A的事务挂起,B将以非事务执行;如果A没有事务,B将以非事务执行。

​ ⑥ never,从不,如果A有事务,B将抛异常;如果A没有事务,B将以非事务执行。

​ ⑦ nested ,嵌套,如果A当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与PROPAGATION_REQUIRED类似的操作。

ThreadLocal的理解和应用

ThreadLocal 为每个使用该变量的线程提供独立的变量副本,所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本。

ThreadLocal 的经典使用场景是数据库连接和 session 管理等。

接口开发的相关问题

① 规范接口文档,请求参数以及返回数据要详细说明。

② 接口的安全性

反射的原理

① 对于任意一个类,都能知道这个类的所有属性和方法,对于任意一个对象,都能调用它的任意一个方法。

spring初始化bean的流程
SpringAOP的实现方式
Spring如何解决循环依赖
SpringCache的原理优点和缺点
Spring的常用注解
SpringMVC的流程
@RequestBody如果不加会有什么后果
SpringBoot是什么
SpringCloud常用组件

redis的作用
redis持久化策略(RDF和AOF各自特点)
redis为什么单线程这么快?其他应用为什么不采用单线程?
NIO和BIO的特点
redis过期key的处理策略

mysql的索引结构
hash索引的特点
B+树索引的特点
select xx for update 会导致行锁还是表锁,为什么?
业务主键和逻辑主键的区别
慢查询怎么排查
怎么优化SQL
单表的数据量过大怎么处理
索引失效的场景有哪些,怎么解决like导致索引失效
1in和extis的区别
in使用场景和带来的问题
对事物的理解
哪几种存储引擎,各有什么特点
给出具体场景,这个SQL如何编写(主要是关联查询、分组、分页)
表与表之间是多对多的关系,如何解决

rockmq、kafka、rabbitmq的特点
怎么保证消息的可靠性
万一挂了咋办?
如何保证顺序消费

linux
1.linux常用命令有哪些(每次都是我刚开始说面试官就喊停,只有1个面试官让我说了半个小时,口都说干了,老师讲课带水杯是有原因的)
2.线上出了问题,会用到哪些linux命令排查
3.解压缩相关的命令
4.常用的加密算法
5.对称加密和非对称加密的特点
6.md5的加密是可逆的吗?

其他
1.k8s的作用
2.jenkins的流程
3.docker的作用
4.docker的常用命令
6.对于出差的看法
7.对于加班的看法
如何解决**

rockmq、kafka、rabbitmq的特点
怎么保证消息的可靠性
万一挂了咋办?
如何保证顺序消费

linux
1.linux常用命令有哪些(每次都是我刚开始说面试官就喊停,只有1个面试官让我说了半个小时,口都说干了,老师讲课带水杯是有原因的)
2.线上出了问题,会用到哪些linux命令排查
3.解压缩相关的命令
4.常用的加密算法
5.对称加密和非对称加密的特点
6.md5的加密是可逆的吗?

其他
1.k8s的作用
2.jenkins的流程
3.docker的作用
4.docker的常用命令
6.对于出差的看法
7.对于加班的看法
8.对瀑布开发,敏捷开发,迭代开发的看法(对比一下优缺点)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值