第一次遇到这么阴间的面试时间,这就是鹅厂的作息吗?
一开始面试官给我发了一个晚上八点的面试,然后立刻打电话来说八点不合适,调到了晚上九点半。很明显面试官有更好的人选,并且排在我前面,不过没关系,能给我这个机会就行!
上来先做自我介绍,我先介绍了lottery的抽奖项目。
介绍完项目后,面试官画风一转,直接开始问八股。
- 介绍一下Java中常用的容器,比如HashMap。我顺着面试官的提示,介绍了Java中HashMap的实现。
- 追问,你知道在HashMap中怎么实现锁机制吗?回答可以在业务中加锁,或者用ConcurrentHashMap。
- 介绍下CAS算法。提到了CAS的实现,可能会有ABA问题和解决方案。
- 你知道Java的GC跟Go的GC之间的区别吗?
数据结构
- 快速排序和堆排序的区别,时间复杂度怎么样?
画风一转,开始问网络
- 你知道三次握手中的,半连接队列吗?
- 上一个问题没有很好的回答,追问请你介绍下三次握手?那握手中的状态会存储在server还是client?这时候面试官感觉到了我对这方面的知识掌握的不太扎实,说我可能有背八股的嫌疑,没有理解。
- 问四次挥手中的time_wait,为什么要设置time_wait时间?
- 追问,如果短时间内多次出现time_wait,是因为什么?回答可能是服务器发起了四次挥手,然后服务器宕机了,或者发生了信道拥趸,服务器压力过大,可能需要用DNS或者本地的nginx实现负载均衡。这时候面试官可能发现我实操能力很强,开始改变了面试的策略。
- 介绍一下流量控制和拥塞控制。
操作系统
- 为什么进程调度比线程调度开销要大?
- 问你知道epoll吗?提到了socket创建过程,并且比较了select和epoll的实现,讲了epoll的优势。
- 追问,在一台多核的机器上,可以多个核心一起实现epoll机制吗?答,可以,因为内存是共享的,继续回答了使用一致性哈希的调度的实现方案。
- 你知道协程吗?回答了 go的协程相关。
DB
- 问Mysql索引的底层实现。
- 追问主键索引和唯一索引的区别。
回到了项目
- 场景题:问如果在直播环境下,有一个福袋抽奖,时间是从10:00-10:30,请问怎么设计一个公平的抽奖策略?提到了先记录所有的id,然后随机数去取出两名幸运观众。
- 追问:如果数据量很大的情况呢?使用堆,每次点击抽奖都回复一个随机数,然后动态维护size为2的堆,实现抽取。面试官又提出了一个更好的方案,蓄水池算法(随机算法)。
- 缓存双写一致性,问你在项目里有遇到redis和mysql数据一致性问题吗?是怎么解决的?回答,保证mysql的最终一致性。
- 问你用到了mq,那么你在分发到时候怎么保证消息不丢失?回答了使用tcc的分布式事务的方式。面试官说这个方案比较复杂,可以使用华为提出的saga方式,也就是写扩散/读扩散。
做了一道题,一开始尝试用bfs,发现好麻烦,转用dfs,5分钟A了。
import java.util.*;
/*
* public class TreeNode {
* int val = 0;
* TreeNode left = null;
* TreeNode right = null;
* public TreeNode(int val) {
* this.val = val;
* }
* }
*/
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param n int整型
* @return TreeNode类
*/
public TreeNode create (int n) {
// write code here
int temp = 1;
// int[] sizes = new int[n];
// sizes[0] = 1;
for(int i = 1; i < n; i++) {
temp*=2;
// sizes[i]=temp+sizes[i-1];
}
TreeNode root = new TreeNode(0);
// Queue<TreeNode> q= new LinkedList<>();
// q.add(root);
// int size = 1;
// while(q.size()>0) {
// TreeNode now = q.poll();
// now.val = temp;
// }
dfs(root, 1, temp, n);
return root;
}
public TreeNode dfs(TreeNode root, int deep, int temp, int maxd) {
if(deep > maxd) return null;
root.val = temp;
root.left = dfs(new TreeNode(0), deep+1, temp/2, maxd);
root.right = dfs(new TreeNode(0), deep+1, temp/2, maxd);
return root;
}
}
反问阶段
- 问了公司的业务
- 为什么更改面试时间到21:30了
当晚 2024-04-11 22:51 就通过了初试,到了复试阶段