1.hashmap,hashmap扩容是需要重新哈希吗?如果二次哈希后还是哈希冲突呢?
2.integer和int的自动装箱和拆箱以及为什么要用integer类
1.答案:https://www.cnblogs.com/aishangtaxuefeihong/p/4886997.html
2.答案:
如果返回字段值为null,int类型会报错,Integer不会报错。因为int类型声明的是变量,而null是对象所以会报错。Integer是包装类,包装类符合对象的特征并提供了一些必要的属性和方法。
int类型的默认值为0,Integer类型的默认值为null。
详解:https://blog.csdn.net/myme95/article/details/81703216
3.Java的线程都有哪几种状态
java线程状态在Thread中定义,源码中能看到有个枚举State,总共定义了六种状态:
NEW: 新建状态,线程对象已经创建,但尚未启动
RUNNABLE:就绪状态,可运行状态,调用了线程的start方法,已经在java虚拟机中执行,等待获取操作系统资源如CPU,操作系统调度运行。
BLOCKED:堵塞状态。线程等待锁的状态,等待获取锁进入同步块/方法或调用wait后重新进入需要竞争锁
WAITING:等待状态。等待另一个线程以执行特定的操作。调用以下方法进入等待状态。 Object.wait(), Thread.join(),LockSupport.park
TIMED_WAITING: 线程等待一段时间。调用带参数的Thread.sleep, objct.wait,Thread.join,LockSupport.parkNanos,LockSupport.parkUntil
TERMINATED:进程结束状态。
状态之间的转换状态图,总结了下,如下:
其中,Thread.sleep(long)使线程暂停一段时间,进入TIMED_WAITING时间,并不会释放锁,在设定时间到或被interrupt后抛出InterruptedException后进入RUNNABLE状态; Thread.join是等待调用join方法的线程执行一段时间(join(long))或结束后再往后执行,被interrupt后也会抛出异常,join内部也是wait方式实现的。
wait方法是object的方法,线程释放锁,进入WAITING或TIMED_WAITING状态。等待时间到了或被notify/notifyall唤醒后,回去竞争锁,如果获得锁,进入RUNNABLE,否则进步BLOCKED状态等待获取锁。
下面是一个小例子,主线程中调用多线程,等待超时后如果子线程还未结束,则中断子线程(interrupt)。
4.Java堆中有哪些GC算法
最全的:https://blog.csdn.net/xinlingchengbao/article/details/88369528
5.Java有哪些引用类型,分别是什么特点
答案:https://blog.csdn.net/qq_19704045/article/details/80646437
6.JMM模型,内存可见性介绍下
答案:https://blog.csdn.net/bryce123phy/article/details/52260168
7.JVM内存模型分为哪几个区域
CSDN:https://blog.csdn.net/qq_24499615/article/details/80012470
博客园:https://www.cnblogs.com/mengchunchen/p/7819370.html
8.static final修饰的一个int 进行修改后是否需要进行重新编译
博客园:https://www.cnblogs.com/AceIsSunshineRain/p/5058279.html
CSDN:https://blog.csdn.net/stormwy/article/details/8435136
9.synchronized和volatile区别
1.volatile本质是在告诉jvm当前变量在寄存器(工作内存)中的值是不确定的,需要从主存中读取;
synchronized则是锁定当前变量,只有当前线程可以访问该变量,其他线程被阻塞住。
2.volatile仅能使用在变量级别;
synchronized则可以使用在变量、方法、和类级别的
3.volatile仅能实现变量的修改可见性,不能保证原子性;
而synchronized则可以保证变量的修改可见性和原子性
4.volatile不会造成线程的阻塞;
synchronized可能会造成线程的阻塞。
5.volatile标记的变量不会被编译器优化;
synchronized标记的变量可以被编译器优化
详解:https://blog.csdn.net/suchahaerkang/article/details/80456085
10.wait()和sleep()有什么区别
1、每个对象都有一个锁来控制同步访问,Synchronized关键字可以和对象的锁交互,来实现同步方法或同步块。sleep()方法正在执行的线程主动让出CPU(然后CPU就可以去执行其他任务),在sleep指定时间后CPU再回到该线程继续往下执行(注意:sleep方法只让出了CPU,而并不会释放同步资源锁!!!)。
wait()方法则是指当前线程让自己暂时退让出同步资源锁,以便其他正在等待该资源的线程得到该资源进而运行,只有调用了notify()方法,之前调用wait()的线程才会解除wait状态,可以去参与竞争同步资源锁,进而得到执行。(注意:notify的作用相当于叫醒睡着的人,而并不会给他分配任务,就是说notify只是让之前调用wait的线程有权利重新参与线程的调度);
2、sleep()方法可以在任何地方使用;wait()方法则只能在同步方法或同步块中使用;
3、sleep()是线程线程类(Thread)的方法,调用会暂停此线程指定的时间,但监控依然保持,不会释放对象锁,到时间自动恢复;wait()是Object的方法,调用会放弃对象锁,进入等待队列,待调用notify()/notifyAll()唤醒指定的线程或者所有线程,才会进入锁池,不再次获得对象锁才会进入运行状态;
详解:https://blog.csdn.net/weixin_39843989/article/details/90294825
11.并发中的方法
处理高并发的六种方法
1:系统拆分,将一个系统拆分为多个子系统,用dubbo来搞。然后每个系统连一个数据库,这样本来就一个库,现在多个数据库,这样就可以抗高并发。
2:缓存,必须得用缓存。大部分的高并发场景,都是读多写少,那你完全可以在数据库和缓存里都写一份,然后读的时候大量走缓存不就得了。毕竟人家redis轻轻松松单机几万的并发啊。没问题的。所以你可以考的虑考虑你的项目里,那些承载主要请求读场景,怎么用缓存来抗高并发。
3:MQ(消息队列),必须得用MQ。可能你还是会出现高并发写的场景,比如说一个业务操作里要频繁搞数据库几十次,增删改增删改,疯了。那高并发绝对搞挂你的系统,人家是缓存你要是用redis来承载写那肯定不行,数据随时就被LRU(淘汰掉最不经常使用的)了,数据格式还无比简单,没有事务支持。所以该用mysql还得用mysql啊。那你咋办?用MQ吧,大量的写请求灌入MQ里,排队慢慢玩儿,后边系统消费后慢慢写,控制在mysql承载范围之内。所以你得考虑考虑你的项目里,那些承载复杂写业务逻辑的场景里,如何用MQ来异步写,提升并发性。MQ单机抗几万并发也是ok的。
4:分库分表,可能到了最后数据库层面还是免不了抗高并发的要求,好吧,那么就将一个数据库拆分为多个库,多个库来抗更高的并发;然后将一个表拆分为多个表,每个表的数据量保持少一点,提高sql跑的性能。
5:读写分离,这个就是说大部分时候数据库可能也是读多写少,没必要所有请求都集中在一个库上吧,可以搞个主从架构,主库写入,从库读取,搞一个读写分离。读流量太多的时候,还可以加更多的从库。
6:solrCloud:
SolrCloud(solr 云)是Solr提供的分布式搜索方案,可以解决海量数据的 分布式全文检索,因为搭建了集群,因此具备高可用的特性,同时对数据进行主从备份,避免了单点故障问题。可以做到数据的快速恢复。并且可以动态的添加新的节点,再对数据进行平衡,可以做到负载均衡:
12.抽象类和接口的区别,什么时候用抽象类什么时候用接口
CSDN:https://blog.csdn.net/wb_snail/article/details/78862533
简书:https://www.jianshu.com/p/914e8e1a320a
博客园:https://www.cnblogs.com/qf-dd/p/10109916.html
13.问题:反转链表按k,最长重复子串
答案;面向对象和面向过程、jvm垃圾回收
14.介绍2个设计模式
答案:https://www.cnblogs.com/aspirant/p/8979340.html
15.Java堆中有哪些GC算法
答案:https://blog.csdn.net/samniwu/article/details/90613989
16.内存泄漏是什么,怎么检测
CSDN:https://blog.csdn.net/xiaodu655/article/details/81153020
简书:https://www.jianshu.com/p/fd741fb87dc5
17.什么是线程池
CSDN:https://blog.csdn.net/weixin_40271838/article/details/79998327
博客园:https://www.cnblogs.com/victorwux/p/9004564.html
18.算法题
1.给一个链表1->2->3->4->5->6->7 和 一个数字n;每n个反转一次链表。
如 n = 2时,2->1->4->3->6->5->7;n = 3时,3->2->1>6->5->4->7
public class NodeReverse {
public static void main(String[] args) {
int a[] = { 1, 2, 3, 4, 5, 6, 7 };
Node root = new Node(a[0]);
Node head = root;
for (int i = 1; i < a.length; i++) {
Node node = new Node(a[i]);
head.next = node;
head = node;
}
root = reverseAdjacentNode(root);
System.out.print("相邻元素翻转后:");
while (root != null) {
System.out.print(root.data);
root = root.next;
if(root != null) {
System.out.print("->");
}
}
}
private static Node reverseAdjacentNode(Node root) {
Node head = root;
Node p, q = null;
if (root.next != null) {
root = root.next; //根结点为第二个结点
} else {
return root;
}
int flag = 0; //判断P是否为第一个结点
p = head;
q = head.next;
while(p!= null) {
if(flag == 0) { //p为第一个结点
p.next = q.next;
q.next = p;
flag = 1;
} else {
if(p.next == null) {
break;
}
head.next = q;
p.next = q.next;
q.next = p;
}
head = p; //保留下一个p前面的结点
p = p.next;
q = p.next;
}
return root;
}
}
class Node {
public int data;
public Node next;
public Node(int data) {
this.data = data;
this.next = null;
}
}
</span>
2.罗马数字转整数 leetcode13
详解:https://www.cnblogs.com/ariel-dreamland/p/9128055.html
19.算法题: 反转链表,删除排好序数组中重复元素,第一题秒了,第二题用两根指针卡了可能1分钟在左指针的移动上。
参考:https://blog.csdn.net/SoulOH/article/details/81630807
20.推荐系统,考虑过分布式系统嘛,QPS怎么测试出来
参考:https://blog.csdn.net/silyvin/article/details/79143761
21.消费者生产者,写写伪代码
答案:https://blog.csdn.net/yongf2014/article/details/46493129
22.写一个list删除目标元素的函数,然后写个测试用例测试一下能不能通,为什么不能正向遍历
参考:https://blog.csdn.net/qinaye/article/details/81875199