Java常见面试题
1.flag1和flag2的值是什么,为什么
Integer a=100;Integer b=100;boolean flag1 = a==b;
Integer a=130;Integer b=130;boolean flag2 = a==b;
结果:
flag1=true
flag2=false
考点:常量池
- 首先"=="是对比的对象地址
- 当 Integer a=100;Integer a=130; 这样赋值的时候会默认调用
valueOf()方法 - 查看源码后会发现当 -128<=x<127 时,直接从常量数据中取,是同一个对象所有相等,而这个范围外的是新建的对象所以不相等
// 赋值方法
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
// 默认值
static final int low = -128;
static final int high = h = 127;
static final Integer cache[]
// 常量数组
cache = new Integer[(high - low) + 1];
int j = low;
for(int k = 0; k < cache.length; k++)
cache[k] = new Integer(j++);
总结:
- 两个Integer值对比,-128~127时,是true,否则是false
- 两个int对比,使用"=="对比的是值
- 一个Integer与一个int对比,Integer会默认拆箱,对比的是数值不是地址了,所以会相等
- jvm对基础类型存储的是数值,对引用类型存储的是引用地址
- Integer对比可以转为int使用"==",或者直接使用equals
- Long和Short类型也做了相同的处理
2.ArrayList,LinkedList的区别,并说下他们的扩容机制
区别:
类型 | ArrayList | LinkedList |
---|---|---|
底层 | 数组 | 双向链表 |
内存 | 连续内存 | 无需连续内存 |
表尾插入 | 时间复杂度O(1) | 时间复杂度O(1) |
表头插入 | 时间复杂度为O(n) | 时间复杂度为O(1) |
表中插入 | 时间复杂度平均为O(n/2) | 时间复杂度平均为O(n/4),最慢的是中间O(n/2) |
删除 | 平均时间复杂度为O(n/2) | 平均时间复杂度为O(n/4),最慢的是中间O(n/2) |
修改 | 平均时间复杂度为O(1) | 平均时间复杂度为O(n/4),最慢的是中间O(n/2) |
查询 | 平均时间复杂度为O(1) | 平均时间复杂度为O(n/4),最慢的是中间O(n/2) |
线程安全 | 不安全 | 不安全 |
总结:
- ArrayList综合性能较高,建议多使用,适合情形:不须要频繁插入和删除数据到数组头部和前面部分,查询效率比LinkedList高
- 频繁增减头部适合LinkedList
扩容:
LinkedList大小不固定,无扩容
ArrayList扩容
- 默认10
- 扩容实在add时发生的,扩大到之前的1.5倍
- 旧数组移到新数组
- 扩容后的值与需要的值对比,使用较大的值
- 扩容后不能超过MAX_ARRAY_SIZE 2的31次方减1
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1);
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
// minCapacity is usually close to size, so this is a win:
elementData = Arrays.copyOf(elementData, newCapacity);
}
3.阻塞队列的实现,ArrayBlockingQueue的底层实现
4.HashMap的get和put原理,在使用的时候怎么优化HashMap
5.JAVA8的ConcurrentHashMap为什么放弃了分段锁,有什么问题吗,如果你来设计,你如何设计。
6.ThreadLocal的实现原理,有什么缺点?跟线程池结合使用要注意什么,怎么解决需要注意的这些问题
7.AQS实现公平锁和非公平锁的原理
8.说一说Fork/Join框架是什么
9.为什么等待和通知是在 Object 类而不是 Thread 中声明的
10.手写使用双重检查锁定在 Java 中创建线程安全的单例
11.如果你的Serializable类包含一个不可序列化的成员,会发生什么?你是如何解决的
12.CAS 实现的原理,是阻塞还是非阻塞方式?使用CAS有啥优缺点
13.原子 *** 作类底层实现机制?自增 *** 作是怎么保证原子性的
14.有三个线程 T1,T2,T3,怎么确保它们按顺序执行
15.如何在两个线程上共享数据?在两个进程上共享数据呢
16.一条 SQL 执行过长的时间,你如何优化,从哪些方面
17.MySQL 索引的原理
18.怎么设计分库分表,可以做到多维度查找
19.mysql索引在哪些情况下不起作用?
20.性别字段是否需要加索引,怎么优化这种类型的sql
21.mysql的存储引擎有哪些,分别有哪些区别
22.mysql悲观锁和乐观锁的区别,怎么实现
23.Mysql和redis数据一致性都有哪些方案,并说出每一种方案的优缺点
24.哨兵如何判断redis主从节点是否正常
25.怎么解决缓存雪崩、缓存穿透、缓存击穿
26.redis的持久化方式有哪些,推荐的是采用哪种,为什么
27.Redis的淘汰策略有哪些?具体的应用场景是啥
28.说一说Zookeeper的zab协议,工作中Zookeeper用在哪些业务场景下
29.说下Zookeeper的选举流程
30.分布式事务模型之XA和TCC的区别和联系
31.MQ集群宕机:怎么保证消息不丢失
32.简单说下spring的Ioc流程,它是如何解决循环依赖的问题,为什么这么解决
33.springmvc的核心是什么,请求的流程是怎么处理的
34.说下springboot的启动流程
35.Spring和Mybatis都使用了哪些设计模式,分别应用在哪些地方
36.mongodb和es有哪些异同点
37.new 一个对象的过程发生了什么(类加载、变量初始化、内存分配)
38.JVM 可能会抛出哪些 OOM
39.介绍JVM中7个区域,然后把每个区域可能造成内存的溢出的情况说明
40.CMS 和 G1 的垃圾回收步骤是?G1 相对于 CMS 的优缺点
41.内存泄漏时,如何实时跟踪内存变化情况,及如何定位问题代码
42.日常项目中,如果你接手,你准备从哪些方面调优
43.如何判断一个正整数是否存在于一个10亿个不重复正整数的集合中
44.(手写代码)假设有一个数组 A ,int[] A = { 1 , 3 , -1 ,0 , 2 , 1 , -4 , 2 , 0 ,1 … N}; 原来是需要查出大于 0 的数组,但是由于传参错误或者其他原因,导致查出 0 和负数了,现在要求在不使用新数组和新集合的情况下(即只使用这个 A 数组,因数组数据比较大,且只能用一次循环) 实现正数放到数组的前面,小于等于 0 的数放到数组的末尾
45.有一个单向链表,删除其中的偶数节点,并返回删除后的链表,用代码写下实现
例如: 输入:1->2->4->5->6 返回:1->4-> 6
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)