面试复盘|度小满一面二面+吐槽
连着面的,但是没有通知,全靠牛客自动发的消息提醒
先说感受吧,面试感受并不好。
一面(1h)
上来面试官就说,因为时间有限,我1面主要考察java基础,然后提问的问题,尽量以简洁的语言回答。我说ok
1、Integer.valueOf()和new的区别?
下面很多问题是根据这个展开问的。
真的很基础的问题,哈哈哈。直接看源码吧
涉及的知识点是Integer缓冲区。
如果是对象的话,是new ,每个地址不同
public static Integer valueOf(int i) { if (i >= IntegerCache.low && i <= IntegerCache.high) return IntegerCache.cache[i + (-IntegerCache.low)]; return new Integer(i); }
2、String是线程安全的吗?
底层是final 修饰的的
3、不同版本的String设计改变过吗?
不了解,我用的是1.8的
(JDK9 带来了字符串两大改善,更小的内存空间和改善表现)
4、你刚刚有提到一个StringBuilder和StringBuffer?
没有被final修饰,一个线程安全,一个线程不安全
5、不可变带来的好处?
线程安全,只要一个不可变对象正确被创建,那么他一定是线程安全的。
6、除了线程安全其他呢?
嗯,然后想到了final修饰方法的时候,在早期Java版本中,将方法转为内嵌调用,提升性能,但在最近的版本中,不需要使用final这些优化了。
https://www.zhihu.com/question/31345592
这里面试官想问,final和常量池之间的一个关系,我没答出来
设计成final的话,为常量池节省空间
7、Object类里面有哪些常用的方法
说了wait notifyAll notify这些
补充(getClass hashcode equals clone toString finalize)
8、HashCode和equals
==:1、基本数据类型,比较的是值,2、引用类型,比较的是内存地址是否相等
equals 如果没有重写,比较的是内存地址,重写的话,一般是比较对象字段的内容,就是按照重写的规则,比如String类就是重写了,String的equals是比较值是否相等。
9、Java里面的异常类了解吗?
Exception 和Error都是继承于Throwable 类,在Java中只有Throwable类型的实例才能被程序抛出(throw)或者捕获(catch),它是异常处理机制的基本类型
其次:
Exception 和Error它是体现java平台针对不同异常情况的分类。
Exception 是程序正常运行过程中可以预料到的意外情况,应该被捕获并进行处理。
Error正常情况下不大可能发生的情况,绝大部分Error都会导致程序状态的不正常,且不可恢复,既然非正常情况,所以我们不便也不需要进行处理,例如OutOFMemoryError之类的都是Error的子类。
再次: Exception 分为检查型异常和非检查型异常。检查型异常必须在源码处进行捕获处理,这是编译检查的一部分。除了RuntimeException以外全部都是检查型异常。
非检查型异常就是所谓的RuntimeException、类似NullPointerException和ArrayIndexOfBoundException就是我们的非检查型异常,通常可以编码避免的逻辑错误,具体可以根据需要进行捕获,编译时不检查,如果抛出非检查型异常就是代码逻辑问题,需要解决
10、当发生Error异常的时候,程序还能继续跑吗?
不能
11、Exception出现的话呢?
不同情况不同讨论吧,看业务上是否有影响。
12、Java集合
ArrayList
HashMap
HashSet
LinkedList
ConcurrentHashMap
13、为什么是8的阈值
时间复杂度上分析,也算是个经验值吧,HashMap源码里面写了,出现的概率不足千万分之一,为了在极端的情况下保证性能。
14、能讲一下put方法的大概流程吗?
首先会判断数组有没有进行初始化,没有的话,先执行初始化操作,resize()方法 (n - 1) & hash用来定位到数组中具体的位置,如果数组中的该位置为空,直接在该位置添加值 如果数组当前位置有值的话,如果是链表,采用的是尾插发,并且当链表长度大于等于8时,会进行树化操作;如果是红黑树的话,则会调用红黑树的插入值的方法;添加完成后,会判断size是否大于threshold,是否需要扩容,若扩容的话,数组大小为之前的2倍大小,扩容完成后,将原数组上的节点移动到新数组上。
15、头插法和尾插法区别?
头插法,引用改变,链表成环
16、ConcurrentHashMap怎么解决线程安全
底层基于CAS + synchronized实现,所有操作都是线程安全的,允许多个线程同时进行put、remove等操作
在JDK1.7采用的是Segment分段锁,默认并发度为16
改变的原因:竞争同一个锁的概率低,浪费内存空间,容易造成长时间等待,1.8对synchronized做了很多的优化。
table数组被volatile修饰。
如果再问的细一点,就是put方法了,没值CAS添加,有值synchronized加锁。
17、CopyOnWriteArrayList了解过吗?
知道的不多,就说不了解了。
(它主要避免对集合的iterator方法加锁遍历)
18、Java一个线程执行另一个等待有几种方式?
其实就是问线程同步
1、通过Object的wait和notify
2、通过Condition的awiat和signal
3、volatile和synchronized
4、通过ArrayBlockingQueue 阻塞队列(生产者消费者)
19、线程原生的方法还有吗?
面试官提醒了join,然后让我说了下join的过程。(join里面不就是wait吗?)
首先join() 是一个synchronized方法, 里面调用了wait(),这个过程的目的是让持有这个同步锁的线程进入等待,那么谁持有了这个同步锁呢?答案是主线程,因为主线程调用了threadA.join()方法,相当于在threadA.join()代码这块写了一个同步代码块,谁去执行了这段代码呢,是主线程,所以主线程被wait()了。然后在子线程threadA执行完毕之后,JVM会调用lock.notify_all(thread);唤醒持有threadA这个对象锁的线程,也就是主线程,会继续执行。
20、wait和sleep区别?
sleep不释放锁
21、Synchronize和lock的区别?
1、Synchronized 是内置的Java关键字,Lock是一个Java类。
2、Synchronized 无法判断获取锁的状态,Lock可以判断是否获取到了锁。
3、Synchronized 会自动释放锁,Lock必须要手动释放锁,如果不释放锁会造成死锁。
4、Synchronized 线程1(获得锁,阻塞)线程2(等待,傻傻的等)Lock锁不会一直等待下去。
5、Synchronized 可重入锁,不可中断,非公平,Lock可重入锁,可以中断锁,可以自己设置非公平。
6、Synchronized 适合锁少量代码同步问题,Lock 适合锁大量的同步代码!
(我这里包括前面说集合的时候一直在说synchronized1.8做了很多升级,面试官就是不问)
22、Lock底层原理
AQS,+state变量,我简单的说了一下。
23、你对可重入怎么理解?
重新进入,自己不会把自己锁死
24、Java内存模型了解吗?
JMM, 有工作内存+主内存
25、volatile是怎么让其他线程感知到修改过了的
内存屏障?lock指令?
不知道回答的对不对
26、happen-before了解过吗?
先行发生,也是JMM的,定义了一套规则,太多,没记住。简单说了下。
27、手撕了一道算法题
类似链表反转,但是是1->n->2->n->1->3->n->3这种,题目说让原地。
后来想了会原地没想出来。面试官说那先按照非原地的写,非原地简单了,HashMap映射index value,根据规律重新构建。
反问
问的问题果然是偏基础的,特别考察基本功
面试官说感觉我答的还蛮好的,然后问我是不是参加过很多次面试了,我说是,他说他能感觉到😂
一面感觉还不错,问的很广。
二面
1、介绍项目
2、Redis数据类型
String(字符串) List(列表) Set(集合) Hash(哈希) ZSet(有序集合)
geospatioal(地理位置) Hyperloglog(基数 ) Bitmaps(位存储)
String:SDS
List:ziplist linkedlist
ZSet:ziplist skiplist(跳表)->zskiplist和zskiplistNode
3、数据库大了考虑怎么优化?
分库、分表、优化sql
4、解决高并发
redis
随机算法redis分库
5、影响一个系统的高并发有哪些?
数据量?业务上的逻辑处理速度吧?
(网络、带宽、操作系统进程管理)这里没说好
6、RabbitMQ和Kafak了解吗?
简单说了下RabbitMQ
7、RabbitMQ高可用了解吗?
说了持久化ACK
没做过集群,不了解。
8、避免重复消费?
不清楚,刚刚不是说过ACK了吗
9、手撕算法
二叉树前序遍历
我说可以写递归也可以写迭代,先写递归吧,3行代码的事,然后面试官说直接写迭代吧。
后面又问了写git,设计模式
然后说了单例模式,代理模式,问知道决策链模式吗?
我说不知道
后面手写了单例模式,我写了最简单的枚举
枚举能防止被反射破坏,反射会抛出异常,序列化也无法破坏,枚举类型的序列化根据name生成的还是原来对象。
然后说我还可以手写DCL的,问用写吗,面试官说不用了。
后面收到面试结束的通知,应该是挂了。
总结+吐槽
其实二面感觉并不太好,面试官并没有很深入挖掘的那种,比如数据库方面,索引这些都没涉及到,如果说前面问我数据大了怎么优化,我现在复盘的时候想,那个是让聊索引的吗?可面试官抛的问题太大了,我能想到的就是业务上的优化,sql的优化,其实也就是索引这些,在然后就是分库分表了,但面试官可能想要其他答案我不知道吧。包括JVM这些,synchronized这些,全部都没有涉及,我往那方面引,但都没有问到,然后就挂了。
如果说深挖项目的话,那应该也要对项目里面具体细节包括实现的原理问一问,然后再根据项目所用到的技术去考察相应的知识点吧,而不是一味的很发散的问一些问题。
二面的时候,面试官大多数时间是不正脸看你的,总体感觉来说,很多知识点,没涉及到,如果按照简历来说的话,jvm不可能一点也不问吧,也可能是我太菜了吧。但我感觉还是可以的,至少自己会的说都能说出来。
面试是一个双向的选择,一家公司面试官的水平一定程度上代表了这家公司的水平,面试官的态度也反应了一家公司的态度,面试的多了的话,每家的面试官给人的印象是很不一样的,有的面试官给人很有活力的样子,很希望去挖掘你身上的闪光点,认真的在和你探讨问题,有的就显得你爱来不来的样子。
大家都是应届生,除了少数的很优秀的人外,其实大家水平都是差不多的(应该是这样吧,瞎说的😂),不同就在于你是否认真去准备,认真对待每场面试了,面试是双向选择的过程,也看点运气吧,也可能是我太菜了🤣🤣🤣
感觉自己吐槽好多呀,主要是因为很多知识点没问到,反而挂了,而且中途面试官还问我base是那里的?唉,还是那句话,面试是双向选择的过程。别看面试官在面咱们。咱们也挑公司的。😂
最后希望大家秋招上岸,offer+++