积加科技后端开发实习面经
背景
4.16 号投递,渠道忘记,4.21 号下午接到 HR 电话约时间,4.22 号下午 3:30 开始的面试。
内容
- 自我介绍,顺便介绍一下项目吧。
- 你的第一个项目是在网上学的吗?看到用到了 ElasticSearch ,能讲讲你在项目中是怎么使用的吗?
- 讲讲你的项目实现了哪些功能,用了哪些技术,怎么实现的?
- 你对 Java 的数据结构了解吗?能说说吗?
- ConcurrentHashMap 的底层实现知道吗?
- CAS 是怎么实现的你知道吗?
- 算法题:合并区间
- 有啥想问我的吗?
分析
- 自我介绍的时候需要心平气和地、不急不慢地介绍,别像机关枪一样嘟嘟嘟嘟嘟,慢一点,注意说话的语速。
- 坦诚交代是在网上自己学的。ElasticSearch 是用了,但是复习的时候想了想,这就是个搜索引擎(主要还是因为项目里实际上没写多少这方面的代码),所以没复习,直接 GG。 elasticsearchRestTemplate.queryForList是查询一个列表,用的就是ElasticsearchRestTemplate的一个对象实例; NativeSearchQuery :是springdata中的查询条件; NativeSearchQueryBuilder :用于建造一个NativeSearchQuery查询对象; QueryBuilders :设置查询条件,是ES中的类; SortBuilders :设置排序条件; HighlightBuilder :设置高亮显示 这个我还得再看看,怎么都感觉说的逻辑很奇怪。
- 项目实现了的功能,我挑 Redis 的点赞和关注说了一说,然后说使用其中的 HyperLogLog 和 Bitmap 分别实现访问量和日活。不知道具体该怎么说,于是说了一下实现的大概。
- 回答的是 HashMap ,主要从底层实现原理、HashMap 和 Hashtable 的区别、HashMap想要实现线程安全的方式来介绍。
- ConcurrentHashMap 这个实际上是从第 4 个问题衍生出来的(HashMap想要实现线程安全的方式),主要也是从 JDK 1.7 和 JDK 1.8 之间的实现来分别说明。
- CAS 是我的盲区,之前看了很多遍,但还是不记得了。写一下。 以下内容摘自简书上的某篇文章:
- synchronized 是悲观锁,这种线程一旦得到锁,其他需要锁的线程就挂起的情况就是悲观锁。
- CAS 操作的就是乐观锁,每次不加锁而是假设没有冲突而去完成某项操作,如果因为冲突失败就重试,直到成功为止。
- CAS 是英文单词 Compare And Swap 的缩写,比较并替换。 CAS 机制当中使用了 3 个基本操作数:内存地址 V,旧的预期值 A,要修改的新值 B。更新一个变量的时候,只有当变量的预期值 A 和内存地址 V 当中的实际值相同时,才会将内存地址 V 对应的值修改为 B。
CAS 的缺点:
- CPU 开销较大:在并发量比较高的情况下,如果许多线程反复尝试更新某一个变量,却又一直更新不成功,循环往复,会给 CPU 带来很大的压力。
- 不能保证代码块的原子性:CAS 机制所保证的只是一个变量的原子性操作,而不能保证整个代码块的原子性。比如需要保证 3 个变量共同进行原子性的更新,就不得不使用 Synchronized 了。
- 区间合并 啊太羞耻了这题居然没写出来......分析了下原因主要有三: 首先是我太紧张了;然后是因为从来没用过 codeInterview 那个平台,一上来就是个基本的 C++ 标准程序框架把我整懵了;最后是因为好久没刷题手生了。 痛定思痛,贴一下代码,以下代码来自ikaruga哥
vector<vector<int>> merge(vector<vector<int>>& intervals) {
sort(intervals.begin(), intervals.end());
vector<vector<int>> ans;
for (int i = 0; i < intervals.size();) {
int t = intervals[i][1];
int j = i + 1;
while (j < intervals.size() && intervals[j][0] <= t) {
t = max(t, intervals[j][1]);
j++;
}
ans.push_back({ intervals[i][0], t });
i = j;
}
return ans;
}
不,我仔细比了比,我当时写的代码的意思就是这个啊,为啥当时报错了我好想骂人啊啊啊啊啊。 除此之外,暴露出来的问题是明显的手生,连建vector都不会了。得赶紧做题了。