题目来自于网络,答案是笔者整理的。仅供参考,欢迎指正
来源: https://mp.weixin.qq.com/s?__biz=MzI1NDQ3MjQxNA==&mid=2247485723&idx=1&sn=f5c3bfbfab9fe01e6d4979e4f315f024&chksm=e9c5f0aadeb279bcff0b81842f09adc1bbf0f4d2b7bb74c5b1c4749bd1bc837e76330c81cc08&scene=21&key=f02705432716b525abb21bf4b72b95d535c372bcd26a437e05deeec7eb0c79966fd85e831802f94d715c009e49871cafb21d20ca7710a496de84350b78db9317b8b4cc6562a9eed840776d9510a4b819&ascene=7&uin=MjM2OTQ3MDkzOQ%3D%3D&devicetype=Windows+7&version=6206021b&lang=zh_CN&pass_ticket=h97v%2FevjbeMS22Cec6mLcTFMVU17Iq0u%2FWtXpCY668m3AU7lLNOkKa9JdWj%2B8omE&winzoom=1
一、基础题
怎么解决Hash冲突;(开放地址法、链地址法、再哈希法、建立公共溢出区等)
写出一个必然会产生死锁的伪代码;
Spring IoC涉及到的设计模式;(工厂模式、单利模式。。)
toString()方法什么情况下需要重写;
判断对象相等时,什么情况下只需要重写 equals(),什么情况下需要重写 equals(),hashcode()?
Set内存放的元素为什么不可以重复,内部是如何保证和实现的?
如何保证分布式缓存的一致性(分布式缓存一致性hash算法?)?分布式session实现?
Java 8流式迭代的好处?
项目中用到的JDK的哪些特性?
说一下TreeMap的实现原理?红黑树的性质?红黑树遍历方式有哪些?如果key冲突如何解决?setColor()方法在什么时候用?什么时候会进行旋转和颜色转换?
Spring的bean的创建时机?依赖注入的时机?
ArrayList和LinkList的删除一个元素的时间复杂度;(ArrayList是O(N),LinkList是O(1));
CopyOnWriteArrayList是什么;
序列化和反序列化底层如何实现的(ObjectOutputStream 、ObjectInputStream、 readObject writeObject);
如何调试多线程的程序;
一个线程连着调用start两次会出现什么情况?(由于状态只有就绪、阻塞、执行,状态是无法由执行转化为执行的,所以会报不合法的状态!)
HashMap在什么时候时间复杂度是O(1),什么时候是O(n),什么时候又是O(logn);
wait方法能不能被重写?(wait是final类型的,不可以被重写,不仅如此,notify和notifyall都是final类型的),wait能不能被中断;
一个Controller调用两个Service,这两Service又都分别调用两个Dao,问其中用到了几个数据库连接池的连接?
二、网络基础
HTTP、TCP、UDP的区别和联系;
TCP和UDP各自的优势,知道哪些使用UDP协议的成功案例;
TCP和UDP各用了底层什么协议;
单个UDP报文最大容量;
单个TCP报文最大容量;
TCP报头格式、UDP报头格式;
Server遭遇SYN Flood应当怎么处理;
Web开发中如何防范XSS?
拆包和粘包的问题,如何解决,如果我们的包没有固定长度的话,我们的应用程序应该如何解决;
三、操作系统
为什么要内存对齐;
为什么会有大端小端,htol这一类函数的作用;
top显示出来的系统信息都是什么含义;(重要!)
Linux地址空间,怎么样进行寻址的;
Linux如何查找目录或者文件的;
四、分布式其他
分库与分表带来的分布式困境与应对之策;
Solr如何实现全天24小时索引更新;
五、Redis
Redis插槽的分配(key的有效部分使用CRC16算法计算出哈希值,再将哈希值对16384取余,得到插槽值);
Redis主从是怎么选取的(一种是主动切换,另一种是使用sentinel自动方式);
Redis复制的过程;
Redis队列应用场景;
Redis主节点宕机了怎么办,还有没有同步的数据怎么办;
六、系统设计开放性题目
秒杀系统设计,超卖怎么搞;
你们的图片时怎么存储的,对应在数据库中时如何保存图片的信息的?
假如成都没有一座消防站,现在问你要建立几座消防站,每个消防站要配多少名消防官兵,多少辆消防车,请你拿出一个方案;
基于数组实现一个循环阻塞队列;
常见的ipv4地址的展现形式如“168.0.0.1”,请实现ip地址和int类型的相互转换。(使用位移的方式)
现网某个服务部署在多台Liunx服务器上,其中一台突然出现CPU 100%的情况,而其他服务器正常,请列举可能导致这种情况发生的原因?如果您遇到这样的情况,应如何定位?内存?CPU?发布?debug?请求量?
七、大数据量问题(后边会有专题单独讨论)
给定a、b两个文件,各存放50亿个url,每个url各占64字节,内存限制是4G,让你找出a、b文件共同的url?
海量日志数据,提取出某日访问百度次数最多的那个IP;
一个文本文件,大约有一万行,每行一个词,要求统计出其中最频繁出现的前10个词,请给出思想,给出时间复杂度分析。
此话题后边会有专门的文章探讨,如果有等不及的小伙伴,可以移步参考:
1、https://blog.csdn.net/v_july_v/article/details/6279498
2、https://blog.csdn.net/v_july_v/article/details/7382693
八、逻辑思维题
有两根粗细均匀的香(烧香拜佛的香),每一根烧完都花一个小时,怎么样能够得到15min?
假定你有8个撞球,其中有1个球比其他的球稍重,如果只能利用天平来断定哪一个球重,要找到较重的球,要称几次?(2次);
实验室里有1000个一模一样的瓶子,但是其中的一瓶有毒。可以用实验室的小白鼠来测试哪一瓶是毒药。如果小白鼠喝掉毒药的话,会在一个星期的时候死去,其他瓶子里的药水没有任何副作用。请问最少用多少只小白鼠可以在一个星期以内查出哪瓶是毒药;(答案是10只)
假设有一个池塘,里面有无穷多的水。现有2个空水壶,容积分别为5升和6升。问题是如何只用这2个水壶从池塘里取得3升的水;
参考答案
一、基础题
1.怎么解决Hash冲突
* 开放定址法(也称为再散列法,基本思想是:当关键字key的哈希地址p出现冲突时,以p为基础,产生另一个地址p1,如果p1仍然冲突,则再以p为基础,产生另一个地址p2..直到不再冲突)。主要有以下三种方法:
* 线性探测再散列(发生冲突时,顺序查看下一个单元,直到出现空单元)
* 二次探测再散列(发生冲突时,在表的左右跳跃式探测)
* 伪随机探测
* 再哈希法(同时构造多个不同的哈希函数,当某一个函数构造的哈希地址发生冲突时,再计算别的函数)
* 链地址法(将所有哈希地址为i的元素构成一个称为同义词链的单链表)适用于经常添加和删除的操作
* 建立公共溢出区(将哈希表分为基本表和溢出表,凡是和基本表冲突的,一律填入溢出区)
更多请参考:https://www.cnblogs.com/wuchaodzxx/p/7396599.html
2.写出一个必然会产生死锁的伪代码
private static final Object a = new Object();
private static final Object b = new Object();
public void handleA(){
synchronized(a){
// doSomething...
synchronized(b){
// doSomething...
}
}
}
public void handleB(){
synchronized(b){
// doSomething...
synchronized(a){
// doSomething...
}
}
}
3.Spring IoC涉及到的设计模式
简单工厂模式、单例模式
4.toString()方法什么情况下需要重写
默认使用的是Object.toString()方法,具体内容如下:
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
不需要使用类的具体信息的时候就不需要重写
5.判断对象相等时,什么情况下只需要重写 equals(),什么情况下需要重写 equals(),hashcode()
两个对象比较,调用equals方法进行比较时,默认比较的是两个对象是否指向同一块内存地址,如果是则相等,否则不相等。
如果想修改这种规则,即只比较对象的某些属性是否相等的时候,那么则需要重写equals方法。
一般来说,重写equals方法必须也重写hashcode方法
6.Set内存放的元素为什么不可以重复,内部是如何保证和实现的
我们以hashSet为例,hashSet实际是使用hashmap来实现的,hashSet的值作为hashmap的key,value为定值。我们可以通过分析hashMap的put过程来分析hashSet是如何不重复的。
我们知道hashMap是哈希表+链表的方式来实现的。通过key的hashCode来确定在哈希表中的index,相同的key会定位到同一个index,下面就是存放Entry,entry包含key和value,会将当前key与链表中的元素的key逐个比较,如果都不相等则放置到链表头;如果存在相等的,则重置entry的value值为当前value
通过上面的过程分析可知,由于hashSet使用hashMap实现时,value值都是定值,所以不会存在相同元素
7.如何保证分布式缓存的一致性
分布式一致性hash算法
8.Java 8流式迭代的好处
* 代码更简洁
* 提供并行流式计算,在处理集合较大时,parallelStream()极大提高效率
...
9.项目中用到的JDK的哪些特性
项目中使用jdk8,回答jdk8的一些新特性
Lambda 表达式 − Lambda允许把函数作为一个方法的参数(函数作为参数传递进方法中。
方法引用 − 方法引用提供了非常有用的语法,可以直接引用已有Java类或对象(实例)的方法或构造器。与lambda联合使用,方法引用可以使语言的构造更紧凑简洁,减少冗余代码。
默认方法 − 默认方法就是一个在接口里面有了一个实现的方法。
新工具 − 新的编译工具,如:Nashorn引擎 jjs、 类依赖分析器jdeps。
Stream API −新添加的Stream API(java.util.stream) 把真正的函数式编程风格引入到Java中。
Date Time API − 加强对日期与时间的处理。
Optional 类 − Optional 类已经成为 Java 8 类库的一部分,用来解决空指针异常。
Nashorn, JavaScript 引擎 − Java 8提供了一个新的Nashorn javascript引擎,它允许我们在JVM上运行特定的javascript应用。
10.说一下TreeMap的实现原理?红黑树的性质?红黑树遍历方式有哪些?如果key冲突如何解决?setColor()方法在什么时候用?什么时候会进行旋转和颜色转换?
// TODO
11.Spring的bean的创建时机?依赖注入的时机?
在默认情况下,启动spring容器的时候创建对象,同时对所依赖的对象进行注入
如果配置bean的lazy-init属性为true,在context.getBean()时才创建对象
12.ArrayList和LinkList的删除一个元素的时间复杂度
* ArrayList O(N)
* LinkedList O(1)
13.CopyOnWriteArrayList是什么
并发安全版本的ArrayList
14.序列化和反序列化底层如何实现的
序列化:把java对象转换为字节序列的过程(对象序列化最主要的作用就是在传递和保存对象的时候,保证对象的完整性和可传递性。序列化后的字节流保存了java对象的转状态以及相关的描述信息)
反序列化:将字节序列恢复为java对象的过程(客户端从文件或网络上获取序列化后的对象字节流后,根据字节流中保存的对象状态和描述信息,通过反序列化重建对象)
序列化算法的操作步骤:
* 将对象的类元数据输出
* 递归输出类的超类描述直到不再有超类
* 类元数据完成以后,开始从最顶层的超类输出对象实例的实际值
* 从上到下递归输出实例的数据
延伸:为什么要主动定义serialVersionUID,其作用是什么?
需要序列化的对象需要主动实现Serializable接口,这个接口是一个标记接口,IDE会提示我们需要主动生成一个serialVersionUID,如果我们不主动生成的话,那么IDE会在我们序列化对象的时候主动帮我们生成一个。
那么其作用是什么呢?我们先看一个示例
// 1.写一个Account类
public class Account implements Serializable {
private int id;
private String name;
}
// 2.使用ObjectOutputStream将Account实例保存到一个文件
ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream(new File("C:/Users/Administrator/Desktop/test1.txt")));
objectOutputStream.writeObject(new Account(1,"jack"));
// 3.修改Account类,添加一个属性
private int age;
// 4.这时再使用ObjectInputStream将test1.txt文件反序列化成Account对象
// 报错信息如下:
java.io.InvalidClassException: cache.Account; local class incompatible: stream classdesc serialVersionUID = -3122741699590248598, local class serialVersionUID = -8634529858385187253
将上述过程重复一遍,不同点就是创建Account类的时候主动生成一个serialVersionUID,如下所示:
public class Account implements Serializable {
private static final long serialVersionUID = 1L;
private int id;
private String name;
此时保存后再反序列化成Account对象,可以发现,没有报错,Account对象成功打印
总结:当我们修改了我们的类的时候,那么当前类的默认的serialVersionUID就会改变,和以前序列化到本地的serialVersionUID不同,那么这时候反序列文件的时候就会报错
15.如何调试多线程的程序
可使用JDI来调试
具体用法可参考:https://m.vipcn.com/a/332165/
16.一个线程连着调用start两次会出现什么情况?
第二次线程会报错,报错内容如下:
Exception in thread "main" java.lang.IllegalThreadStateException
at java.lang.Thread.start(Thread.java:708)
at javacore.mulit.MyThread.main(MyThread.java:40)
第一次调用start之后,threadStatus会改变(非0,0代表新建),所以第二次在调用会报错
17.HashMap在什么时候时间复杂度是O(1),什么时候是O(n),什么时候又是O(logn)
O(1):当map中的元素哈希码都不冲突的时候,会均匀分配在数组中
O(n):当map中的元素哈希码都冲突的时候,实际上就变成了一个链表结构的数据
O(logn):map中的元素有部分冲突
18.wait方法能不能被重写?
wait方法属于Object类,是final类型的,所以不能重写,源码如下:
public final void wait() throws InterruptedException {
wait(0);
}
19.一个Controller调用两个Service,这两Service又都分别调用两个Dao,问其中用到了几个数据库连接池的连接?
// TODO
未完待续...