Java 面试 相关问题

JMM、老年代在什么情况下会触发GC、对老年代的GC会不会导致程序卡顿?(最优吞吐量和最短停顿时间)
1、JMM详解
2、老年代:这是HOTSPOT中的垃圾回收机制中的一个名称,在堆进行回收时,如果实行复制回收,那么则会将堆划分为Eden和老年代,以及持久代
3、GC有两种情况,一种是Young GC(MinorGC),一种是FullGC,如果是触发FullGC,一般有以下几种方式:

老年代空间不足:
如果创建一个大对象,Eden区域当中放不下这个大对象,会直接保存在老年代当中,如果老年代空间也不足,就会触发Full GC。为了避免这种情况,最好就是不要创建太大的对象。

持久代空间不足:
如果有持久代空间的话,系统当中需要加载的类,调用的方法很多,同时持久代当中没有足够的空间,就出触发一次Full GC

YGC出现promotion failure:
promotion failure发生在Young GC, 如果Survivor区当中存活对象的年龄达到了设定值,会就将Survivor区当中的对象拷贝到老年代,如果老年代的空间不足,就会发生promotion failure, 接下去就会发生Full GC.
统计YGC发生时晋升到老年代的平均总大小大于老年代的空闲空间:
在发生YGC是会判断,是否安全,这里的安全指的是,当前老年代空间可以容纳YGC晋升的对象的平均大小,如果不安全,就不会执行YGC,转而执行Full
GC。

显示调用System.gc

谈谈你所掌握的数据结构
在这里插入图片描述

讲一讲红黑树
红黑树是一种含有红黑结点并能自平衡的二叉查找树。它必须满足下面性质:

性质1:每个节点要么是黑色,要么是红色。
性质2:根节点是黑色。
性质3:每个叶子节点(NIL)是黑色。
性质4:每个红色结点的两个子结点一定都是黑色。
性质5:任意一结点到每个叶子结点的路径都包含数量相同的黑结点。

红黑树插入一个结点的时间复杂度
O(logn)
红黑树面试题目

你所知道的算法的时间复杂度有哪些?快排的复杂度是多少?为什么?
在这里插入图片描述

HashMap的实现,为什么结点插在链表的头部容易导致死锁
实现:HashMap简单来说就是 数组+链表,或者说数据+链表+红黑树,
死锁:由于HashMap线程不安全,在多并发的情况下容易造成死锁,主要是HashMap在扩容的时候会进行rehash,此时如果出现多并发情况就会导致链表出现循环,导致死锁。
HashMap之原理及死锁

HashMap扩容
hashmap默认初始化大小为16,当实际存储元素个数>负载因子(load factor)*数组长度时候,就会进行扩容,每次都是直接翻倍。调用的是resize函数。

HashMap为什么初始值为16
主要原因是16位2的幂次方,而且之后扩张大小也需要是2的幂次方,为什么需要这样规定呢,是因为在计算hashcode的时候是按照与运算来计算的,所以需要是2的幂次方。说的有点不详细,得再参考点资料

手撕代码:字符串a和b,假设只由26种小写字母组成,且a比b长,判断b中字符是否在a中都有出现
暴力解法 – 两次遍历 – 再通过查找规律 – 优化算法
两次遍历-- 考虑到每次不重复运算
放火烧 – 相近算法 --进行修改

堆栈和线程的关系
栈是线程私有的,每个线程都是自己的栈,每个线程中的每个方法在执行的同时会创建一个栈帧用于存局部变量表、操作数栈、动态链接、方法返回地址等信息。每一个方法从调用到执行完毕的过程,就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程。其中局部变量表,存放基本类型(boolean、byte、char、short、int、float)、对象的引用等等,对象的引用不是对象实例本身,而是指向对象实例的一个指针。而堆是线程共享的,所有的对象的实例和数组都存放在堆中,任何线程都可以访问。Java的垃圾自动回收机制就是运用这个区域的。
方法区也是线程共享的,用于存放类信息(包括类的名称、方法信息、字段信息)、常量、静态变量以及即时编译器编译后的代码等等。
在这里插入图片描述
当程序执行到箭头指向那一个行代码的时候,
入参i和局部变量j都是基本类型,直接存放在栈中。
入参str和oneMoreStudy是对象类型,在栈中只存放对象的引用。
如下图:
在这里插入图片描述

Java类加载过程
从类的生命周期的角度进行切入,一共有七个过程,加载(load)-校验(verify)-准备(prepare)-解析(resolve)-初始化(initalize)-使用(use)-卸载(unload)

加载:Class的二进制内容加载到虚拟机的方法区
准备阶段:虚拟机会在方法区中为Class分配内存,并设置static成员变量的初始值为默认值。注意这里仅仅会为static变量分配内存(static变量在方法区中),并且初始化static变量的值为其所属类型的默认值。如:int类型初始化为0,引用类型初始化为null。即使声明了这样一个static变量:

java public static int a = 123;

在准备阶段后,a在内存中的值仍然是0,
赋值123这个操作会在中初始化阶段执行,因此在初始化阶段产生了对应的Class对象之后a的值才是123 。
初始化:初始化阶段即开始在内存中构造一个Class对象来表示该类,

手撕代码:双向有序链表,去除有重复值的所有结点
1、先定义双向有序链表的结构
2、再根据数据结构 实现去重
3、去重的具体方式就是修改指针了

说你熟悉的几种设计模式,手写单例设计模式
单例模式详解
常见六种设计模式
简单来说,单例模式,就是如果一个类只能有对应的一个对象,那么可以使用单例模型,单例模式分为几种,常见的有饿汉模式,就是类在加载的时候就创建,还有懒汉模式,是在单例第一次使用的时候再创建对象。
其他的还有 工厂模式、观察者模式、迭代器模式、代理模式、适配器模式

ConcurrentHashMap的实现有了解吗
类似于hashmap 应该,不过ConcurrentHashMap是线程安全的,而如果要提到ConcurrentHashMap,那么也要提到hashtable。
对于hashmap,因为是非线程安全的,因此如果想要保证线程安全,提出了hashtebel,但是HashTable效率非常低下,HashTable容器使用synchronized来保证线程安全,当一个线程访问HashTable的同步方法时,其他线程访问HashTable的同步方法时,可能会进入阻塞或轮询状态。如线程1使用put进行添加元素,线程2不但不能使用put方法添加元素,并且也不能使用get方法来获取元素,所以竞争越激烈效率越低。
ConcurrentHashMap主要就是为了应对hashmap在并发环境下不安全而诞生的,ConcurrentHashMap的设计与实现非常精巧,大量的利用了volatile,final,CAS等lock-free技术来减少锁竞争对于性能的影响。
ConcurrentHashMap避免了对全局加锁改成了局部加锁操作,这样就极大地提高了并发环境下的操作速度,由于ConcurrentHashMap在JDK1.7和1.8中的实现非常不同,接下来我们谈谈JDK在1.7和1.8中的区别。
ConcurrentHashMap的实现原理(JDK1.7和JDK1.8)
ConcurrentHashMap实现原理以及源码解析

画B+树的底层框图,B+树的叶子结点是什么结构
B+树,可以称之为多路平衡查找树,而且值都放在叶子结点,且叶子结点是有序链接的。
在这里插入图片描述

给已经存有0-99的索引的B+树,查询3-30的索引对应的记录

手撕代码:给定整型数组,构造搜索二叉树
整型数组–搜索二叉树
搜索二叉树 是怎么个结构,定义一个二叉树?是的
简单?顺序遍历整型数组,将每个值构造一个二叉树就行,只不过限定条件是搜索二叉树
问题–先抽象–再具象

Java 容器
JAVA常见容器
比较顶级的接口就是Iterator、collection、map三个接口,实现类主要有vector,stack、arraylist、linkedlist、hashset、treeset、hashmap、hashtable等
在这里插入图片描述
待补充:大致解释一下各个容器

参考博客:
https://www.nowcoder.com/discuss/129446?type=2
https://www.cnblogs.com/williamjie/p/9516367.html
https://www.cnblogs.com/williamjie/p/9358291.html
https://www.cnblogs.com/heihaozi/p/11741733.html
https://www.cnblogs.com/williamjie/p/11167902.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值