58同城 后端

1、HashMap的实现原理,什么时候数组需要扩容,HashMap怎么确定要把数据放到节点的哪个位置,计算哈希值比较高效的哈希函数有哪些,HashMap是否线程安全,有哪些线程安全的Map,ConcurrentHashMap的实现方式(不同Java版本)
2、Synchronized关键字的实现方式,原理
3、用栈实现队列
4、项目深挖,技术选型,数据库表的设计,分库分表相关问题
自己也知道面试官对自己的回答不满意,后面感觉就是在强行凑够半小时哈哈哈
全部评论
栈实现队列,队列实现栈,网上挺多答案的,你可以搜一搜,这个算法题比较麻,它非常多,建议你刷够 leetcode 的前 200 道题。如果你有时间的话,没时间你就看看面经看要去的公司可能会有哪些常见的算法题,记下来思路就行。后面的项目我建议你自己列一个文档,里面说明自己项目用了哪些技术,以及遇到的难点/亮点是什么,怎么解决的。表设计为什么怎么设计等待和项目相关的。然后通读几遍记在脑子里,这样面试这种项目的时候你就得心应手了。分库分表的话我觉得以一个大学毕业生的角度最少要知道有几种分库分表的方式,要答出来垂直/水平 分库分表的做法,以及分库分表之后会发生什么问题以及如何解决的?-跨库 join 的问题啊、数据存放在哪个分库、分表以及如何存放?读取时怎么从不同数据库读取?另外还要知道一下常规分库分表的中间件比如 mycat、sharding-jdbc 等等,大致了解一下,问到你怎么用的时候你就说以你目前的数据量暂时不需要进行分库分表,但是个人对这方面还比较感兴趣,了解了一下怎么分库分表,说一下垂直分库分表、水平分库分表,在讲一讲可能会遇到的数据问题。差不多这个问题你拿个 80 没问题。好了,偶然刷到,给你解解惑,希望你下次面试有好结果,也希望我有好结果。😁共勉。(来自 4年老鸟的)
5
送花
回复 分享
发布于 04-27 15:17 安徽
hashmap的实现原理可以分成两个版本,比如 1.7 怎么怎么样,1.8 怎么怎么样,这么说:hashmap 在 jdk1.8 以前底层数据结构采用数组+链表的方式,之后需要介绍插入的逻辑:在插入元素时,首先会计算key 的 hashcode 并且通过 hashcode&n-1 来计算出 key 在数组中的位置,如果当前数组位置为空,则直接进行赋值,如果当前位置有数据存储了,那就看当前的 key 与我要传入的 key 是否相同,如果相同则进行值覆盖,如果不相同,则表示当前出现了哈希冲突,那么就看当前节点是否有链表,如果有链表则遍历链表查看是否有相同的 key,如果有则进行值覆盖,如果没有就采用头插法的方式将数据写入到链表中。而在 jdk1.8 之后,hashmap 低层数据结构变成了数组+链表+红黑树的方式,在链表个数超过 8 个时就会发生树化。然后介绍一下 1.8 与 1.7 的区别,1.8采用尾插法解决多线程并发 put 时可能导致的环状结构,1.8 的扩容机制是先插入后进行判断数组是否需要进行扩容。这个问题说完了。面试官看你这么吊可能会继续深入问你:为什么 hashmap 的容量必须为 2 的 n 次方?为什么 hashmap 是非线程安全的?为什么 hashmap链表转红黑树的个数为 8 个不为其他个数?怎么解决 hashmap 的线程安全问题?
3
送花
回复 分享
发布于 04-27 14:47 安徽
国泰君安
校招火热招聘中
官网直投
concurrentHashMap 跟 hashmap 也是一个套路,1.7 以前版本是什么样,1.8 版本是什么样。为什么能做到线程安全的?插入、读取元素时的过程(1.7、1.8 的优化)。 在 1.7 之前,ConcurrentHashMap 使用的是 segment数组+分段锁的方法,在插入元素时首先会计算这个 key 的 hashcode,然后找到 指定位置的segment数组,如果指定的数组为空,则进行初始化并插入元素,如果不为空,则先获取锁,然后计算 key 值存放的位置,再进行插入元素,获取不到锁的会进行自旋等待获取锁。 1.7 之后,concurrentHashMap 取消了 segment 数组,使用跟 hashMap 一致的结构,在插入元素时会采用 CAS尝试写入数据,失败之后再用synchronized 锁的方式来保证一定能写入,来实现线程安全。 那么如何做到其他线程可以知道当前线程的数据修改呢?通过利用 volatile 关键字修饰,保证修改可见性,并且写操作时会进行 cas+重试以及 synchronized写入数据,就能保证写操作的并发安全。这两个 点解决了 ConcurrentHashmap 的读写并发安全性。
1
送花
回复 分享
发布于 04-27 14:56 安徽
synchronized 关键字就略微复杂了,也需要你回答不同版本下的实现原理(1.6与1.6 之后)1.6 之前采用重量级锁的方式,实际是利用操作系统的 mutex lock 指令,在对应代码块出入口位置添加monitor enter 和 monitor exit 来进行加锁解锁,而修饰方法时添加 ACC_synchronized 标志表明当前方法为同步方法。然后就说这个重量级锁可能引起的性能上面的问题,频繁的切换用户态和内核态会引起性能下降。所以 1.6 之后做了锁升级的优化。然后再介绍一下说一下锁的四种状态-无锁、偏向锁、轻量级锁、重量级锁,锁升级的流程。这个问题基本你就拿下了。
1
送花
回复 分享
发布于 04-27 15:01 安徽
oc了么
点赞
送花
回复 分享
发布于 05-13 16:33 上海

相关推荐

5.14一面 40min0.面试官介绍部门和业务,让我放轻松1.java内存介绍一下(讲了jmm和jvm,还有cpu多级缓存机制)2.单例模式的实现方式介绍一下(饿汉,懒汉,双重检测锁,枚举类,静态内部类)3.聚簇索引和非聚簇索引,b+树,b树4.快速排序复杂度为什么是nlogn5.什么场景下你会用redis手撕10min lc22 括号生成(以前没做过,现场想到用回溯写出来了,竟然一次跑通)让我说一下复杂度5.20二面40min0.面试官自我介绍1.讲讲你的爬虫项目,有没有遇到什么困难,怎么解决的,如果爬多了会怎么样,数据怎么保证不出错,代码有没有开源,有没有跑得通的项目。2.缓存穿透,击穿,一致性哈希算法3.假如key很多一个redis放不下怎么办4.你说分片集群,那假如有一个分片宕机了怎么办?5.除了加机器给每个分片搭建集群之外还有什么办法?从算法层面讲一讲6.除了redis还有什么缓存(讲了下Nginx静态资源,客户端setstorage,jvm缓存)7.虎溪生活项目做了什么优化8.你说你学校别的学长也做过类似的,有想过他们为什么成功吗?9.平常有什么爱好(提前偷看了面试官的朋友圈,发现面试官喜欢踢足球,man!what can i say!)你知道的,我一直都是足球爱好者,我热爱这项运动m3,我超喜欢football,man。10.反问手撕反转链表5.21hr面 5.22offer审批 许愿审批顺利另外附上我搜罗的最近几年58同城的面经垃圾回收器,G1执行流程如何理解RPC,它解决了什么问题对socket编程有没有了解?(不了解)DNS是什么?具体流程是什么样的?线程池底层实现原理了解吗手撕前缀树(trie树实现和类实现b+为什么会产生大量碎片? lsm说一个稳定且时间复杂度较低的排序算法快排为什么是不稳定的ConcurrentHashMap1.7和1.8的区别分段锁是可重入的吗你怎么理解可重入锁滑动窗口 流量控制过程   接收窗口如果收到无序的包怎么解决?Linux top命令常用的linux网络命令Mysql数据库死锁两个线程交替打印奇偶数字Linux基本命令排序:链表排序讲一下Hashtable,KV的添加流程,
58同城泡池子1人在聊 查看13道真题和解析
点赞 评论 收藏
分享
5 50 评论
分享
牛客网
牛客企业服务