某度大厂面试,来学习下?

惯例:自我介绍和近期深刻的项目介绍。

1. HashMap 的底层数据结构是怎样的 ?

底层是用数组实现,hash冲突使用拉链法解决,节点超过8转换成红黑树

2.HashMap哈希算法是怎么实现的,为什么很实现?

key的hashcode高16位不变,然后高16位与低16位与或运算,在只有低位参与索引位置的情况下,为了防止高位不同,低位相同的冲突

3. 有哪几种哈希算法,都有什么特点?

拉链法(冲突对象形成一条链表);在hash法(有多个不同的hash函数,直到找到空位);寻址法(一个hash函数,会hash结果上以某种规律变化,知道找到空位)

4. HashMap1.7并发死循环能通俗的讲下吗?具体在哪里为什么会成环

由于7在扩容是,链表是头插的方式进行,假如有两个node始终冲突,在执行node.next方法时,恰好有另外一个线程也进行了扩容,扩容一个节点,切回一线程,这时一线程next是新map的节点,当下个循环时会在插入这个节点,结果产生死循环

5.G1和CMS有什么区别

G1是整堆收集器,cms只是老年代收集器

G1整体是标记整理,局部标记复制,cms是标记清除

G1不会产生垃圾碎片,cms会有碎片

G1是目标是降低停顿时间,cms目标是提高吞吐量

6.G1的停顿时间判断怎么确定的?

和用户设置的最大停顿时间作为标准,然后决定回收哪些region,时间长回收region多

7.G1是以什么方式什么时候判断regin上的垃圾回收成本

是以可达性分析方式标记垃圾,在重新标记阶段会计算每个region的回收成本,

8.线程池的核心数和最大数有什么区别

核心可以空闲不销毁,最大需要销毁

9.核心数怎么确定,最大数怎么确定

具体和业务和机器性能相关,我总结可以这样计算 预期QPS/(1000/接口性能) 例如 10000/(1000/200)     10000是预期QPS,1000是一秒,200是接口性能。以这个结论作为初始设置,然后根据压测进行调整

10.队列使用有界还是无界,阻塞还是非阻塞,为什么

基本都是有界阻塞队列

阻塞使用锁控制并发,并发度高比较适合,阻塞线程,释放CPU,

非阻塞并发高的浪费CPU,并发低阻塞队列的syn自旋也能提高,只是有时间限制,所有使用场景比较苛刻,并发低比较适合

有界队列可以控制等待线程的上限,底层是Array,初始占用空间比较多,数组初始化就确定空间大小

无界队列使用的前置条件是请求有上限限制,没有限制会OOM,按需产生节点,不会浪费空间,但是会 额外封装node节点形成链表

11.淘汰策略有几种,分别用在什么场景

简单说几个;丢弃最新的和丢弃最老的,适合收集info日志这类无关紧要的场景

抛异常,适合对任务进行二次处理,比如路由到异步MQ中

调用节点执行,适合重要并快速响应的场景(但是有坑)

12.线上使用线程池,线上有遇到问题吗

核心设置不够队列太大导致超时

队列选择不对导致OOM(无界队列),CP飙高(非阻塞队列),

淘汰策略是调用节点执行,导致服务不可用,占用过多线程,突破线程池隔离

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容