跳至主要內容

(2)2019友金所Java面试题


友金所是一家位于深圳南山科技园的P2P网贷公司。公司面试过程采用渐进式的问答面试,没有笔试题。比如面试者说熟悉多线程,面试官就问哪些方式解决并发;面试者说采用Synchronized或者ReentrantLock,面试官便会追问Synchronized的实现原理,以及两种方式运用的场景和优劣,逐渐靠近底层原理,直至面试者答不上来才转换话题。

1 解释一下HashMap的实现原理

HashMap 的底层数据结构实际上是一个 entry 数组,当往 map 里面 put 一个数据的时候,会根据 key 的 hash 值计算下标,如果没有发生碰撞,就会直接放进数组里。如果碰撞了,就以链表的方式链接到链表上,在 jdk1.7 是使用的头插法在多线程的情况会导致 map 扩容的时候让链表成环,如果这个时候刚好有 get 操作到了此链表上,就会发生死循环,1.8 的时候就改用尾插法了。

当链表的长度超过阈值 6 的时候,就会把链表转换成红黑树,以此提高查找数据的性能。如果链表里面存着相同的 key,则会替换旧值。当 map 里面的数据超过容量的百分之七十五,就会调用 resize 、rehash 方法,将 map 扩容两倍之后重排。这里的 resize 方法会对整个 map 的元素进行遍历,极其耗费性能。因此我们在实际开发过程中,当我们明确知道 map 要用的容量的时候,尽量使用指定初始化容量的构造函数,避免频率的扩容重排带来的性能损耗。

当我们在 map 里面 get 一个数据的时候,会根据 key 的 hash 值计算下标,在这里 jdk 对 hashmap 的寻址算法做了一个优化,就是规定数组的长度必须是 2 的幂次方。当数组的长度是 2 的幂次方的时候, (n-1)&hash 数组的长度减一跟 hash 值作与运算,就跟直接用数组长度跟 hash 值取模是一样的,这里就用了与运算代替取模,提升性能。但是这里也会带来一个问题, HashMap 的容量可以达到 2 的三十二次方,但是在业务系统实际开发过程中,我们可能并不会在内存中存放大量的数据,那么这时候我们用数组的长度减一跟 hash 值作与运算的时候,因为高位都是 0 ,这样就相当于高位的差异都丢失了。所以这里 jdk 又对 hash 算法作了一个优化,将 key 原始的 hash 值的高十六位与第十六位作一个异或运算。因为异或运算里,相等的等于1,不相等的等于0,做异或运算就相当于将高位跟低位的特征都集中在了低位,这样当我们往 HashMap 里面put数据的时候就能降低 hash 碰撞的几率,以此提高 HashMap 的性能。

HashMap 是线程不安全,如果需要同步请使用guava的类库或者是 ConcurrentHashMap ,并且 resize 方法极其耗费性能。因此我们在实际开发过程中,当我们明确知道 map 要用的容量的时候,尽量使用指定初始化容量的构造函数,避免频率的扩容重排带来的性能损耗。

2 解释一下Spring事务传播机制

https://www.jianshu.com/p/aa76625d3715open in new window

https://www.jianshu.com/p/25c8e5a35eceopen in new window

3 解释一下Spring的IOC和AOP实现原理

https://www.cnblogs.com/best/p/5679656.htmlopen in new window

https://www.cnblogs.com/gaopeng527/p/5290997.htmlopen in new window

AOP(Aspect Oriented Programming)意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。

4 Java并发包用到了哪些,以及Synchronized,ReentrantLock的区别,两者的使用场景分别是什么

Java多线程相关类的实现都在Java的并发包concurrent,concurrent包主要包含3部分内容,第一个是atomic包,里面主要是一些原子类,比如AtomicInteger、AtomicIntegerArray等;第二个是locks包,里面主要是锁相关的类,比如ReentrantLock、Condition等;第三个就是属于concurrent包的内容,主要包括线程池相关类(Executors)、阻塞集合类(BlockingQueue)、并发Map类(ConcurrentHashMap)、线程相关类(Thread、Runnable、Callable)等。

https://www.cnblogs.com/luoxn28/p/6059881.htmlopen in new window

http://www.cnblogs.com/paddix/p/5367116.htmlopen in new window

https://www.cnblogs.com/cxzdgs/p/5746895.htmlopen in new window

5 说一说Java提供了哪些线程池以及它们的原理

http://ifeve.com/java-threadpoolexecutor/open in new window

6 解释一下Java深浅拷贝的区别

https://blog.csdn.net/baiye_xing/article/details/71788741open in new window

7 用过ActiveMQ和RabbitMQ吗?说一下ActiveMQ和RabbitMQ 的区别

https://blog.csdn.net/lifaming15/article/details/79942793open in new window

8 让你独立开发一个项目,你会用到哪些技术或中间件

9 如何处理MySql的海量数据翻页查询性能问题

http://blog.csdn.net/u011225629/article/details/46775815open in new window

10 有没有在业务中对Mysql分表分库,遇到过什么问题怎么解决的?

https://www.jianshu.com/p/7aec260ca1a2open in new window

上次编辑于: