我参加的是2023届的微软暑期实习提前批,投的部门是苏州的STCA,有一个简历筛选。然后过了会通知有面试时间。它的形式是一面和二面过一个就可以进入终面,一面不过就会通知你二面。
我的记录纯口水话,下面的问题的答案就是我当时面试时的回答,内容不准确的,所以大家看看就好,只是记录这个过程。
总体而言,我遇到的算法题和问题都不难,主要是我太菜,居然第一题都卡那么久,无语了,而且面试官人也很好,很耐心,只不过因为我前面耗时太长, 以至于我后面都没有反问的环节。
一面:
面试环境:
实现邮箱通知了一个面试链接,到点后点进去就行,当然需要提前下载他们的面试软件teams。
进入会议后我这边单方面开视频,面试官没有开视频。
有的面试官是外国人,所以还需要准备一个英文自我介绍,我准备了但是没用上,我这个是中国人,面试的时长是45分钟。
正式开始:
面试官:你先自我介绍一下吧
先让自我介绍,面试官您好,我是XX大学。。。。。做了XX项目(Java 的)。这里我介绍完了发现面试官掉线了。。。然后自己愣在那不知所措,过一会他重连上来,让我重新再自我介绍一下。到这里心态有点崩。
面试官:好的,做到题吧,你打开ide,我给你念题目。从2开始,找出仅仅由2,3,5,7四个数相乘得到的第n个数。
我打开idea,开始写,有些紧张,写的过程自己也知道这题很简单,但是这么简单的卡住了,当时想都想挂了,放弃了。整整耗了快30分钟才写对。而这个面试也才45分钟。。
中间面试官友好的提示了我一下,允许我写测试用例。
这里放下我面试过时写的代码,毫无修改。
public class demo {
//2,3,4,5,6,7,8,9,10,12,14,15,16
// 2,3,5,7
static int []nums={2,3,5,7};
/**
*
* @param n
* @return
*/
public static int get(int n){
int count=0,start=2;
while(count<n){
if(check(start)){
count++;
}
if(count==n)return start;
start++;
}
return start;
}
// 2,3,5,7
public static boolean check(int k){
//
while(k>0){
boolean flag=false;
for(int num:nums){
if(k==num)return true;
if(k%num==0){
flag=true;
k/=num;
}
}
if(!flag)return false;
}
return true;
}
public static void main(String[] args) {
// System.out.println(check(10));
System.out.println(get(13));
}
}
写完后,面试官给了几个例子,让我试一下对不对,确定正确之后问我是不是可以改进。
我说是,可以缓存已经判断的结果,比如添加个HashMap来缓存之前已经判断位符合的数字,这样当前数字除以2,3,5,7中的一个数之后,如果结果出现在HashMap中,就可以直接确认他是符合条件的数。
面试官:为什么用HashMap呢
哦哦,应该用个Set就可以了,如果某个数符合就直接添加道Set中,判断时判断set中是否有就行。
面试官:好的,问你一些问题吧,你是Java 的,那你有看过源码吗,举个例子呢?
有的,比如XX,它的核心是XX,然后我自己仿照实现了一个XX,功能有XX,原理是XX,流程XX。
面试官:明白,那你了解HashMap底层吗?
了解的,HashMap底层的数据结构是数组加链表+红黑树,。。。
面试官:那Concurrent包下的你了解吗
了解的,如ConcurrentHashMap,它是HashMap的高并发实现,XXX。
面试官:再问你一个算法题啊,如果让你合并n个有序链表,你有什么思路
这里应该是我第一道题托的太久了,然后表现太菜,所又再出了一个问题。
我说我会用归边排序,分治的思想,先两两合并,然后剩下的也两两合并,这样效率高些,空间复杂度占用会比较少。
面试官:具体呢,比如有个100个链表
那就是每两个合并,这样有50个,再每两个合并,这样有25个,然后前24个两两合并有12个,最后一个直接进入下一轮,就是有13个,然后按这样的思路,最后只剩下两个,然后合并得到结果。
面试官:那时间复杂度呢,比如有n个链表,所有链表长度加起来是m个。
我说所有链表长度m个好像不太好计算,如果平均每个链表长度是m个,那应该是O(mlogn)
面试官:你知道原子操作吗,x++,x=y这些哪些是原子的
x++不是原子的,它的内部是x先加以,然后再赋值给x,这样如果中间有其他线程对x做了修改,结果就会不一致。
x=y,不可拆分,是原子的。
面试官:什么是原子操作
原子操作就是要么失败要么成功, 类似事务,只有失败和成功两种状态,然后不可中断。(我在乱讲)
面试官:好吧,时间已经到了,那就这样吧。
好的,谢谢。
面试官:拜拜
这就是一面的环节了,挂了之后我很想锤自己,这么简单的第一道题弄了那么久。。。
估计一面要挂,挂了就后面来更新二面的,没挂就最后更新终面的。哎,气。。。
----------------------------------------分割线-------------------------
我一面过了,然后今天21参加了leader面,内容大致如下。
先中文自我介绍,然后问项目,我写了个有个目标检测的项目,然后逮住我问,问具体做了什么?然后模型结构是怎样的?检测效果怎么样?具体指标呢?也就是没有具体指标?那你讲一下你的模型(YoLo系列),你改了什么?你讲一下原理呢,为什么这样能够训练出来呢?每个像素是否用到了?
然后就是做题了:
第一道:岛屿数量的,比较简单
https://leetcode-cn.com/problems/number-of-islands/
class Solution {
int [][]dir =new int[][]{{1,0},{0,1},{-1,0},{0,-1}};
int m,n;
public int numIslands(char[][] grid) {
m = grid.length;
n = grid[0].length;
int count =0;
for(int i=0;i<grid.length;i++){
for(int j=0;j<grid[0].length;j++)
if(grid[i][j]=='1'){
count++;
dfs(grid,i,j);
}
}
return count;
}
private void dfs(char[][]grid, int i, int j){
grid[i][j]='0';
for(int [] d:dir){
int ni=i+d[0];
int nj=j+d[1];
if(ni<0||nj<0||ni>=m||nj>=n||grid[ni][nj]=='0')continue;
dfs(grid,ni,nj);
}
}
}
几分钟写了之后没让我跑,让我讲一下代码就行。然后说你的遍历是从左到右,从上到下的,如果dir只有向右和下的方向行不行。
我想着大佬这样说了,应该行,然后我说应该可以,我没有想到。
他说不行。。。。。然后让我想一个反例。
我举了一个
0100
1101
0000
如果按照向右和向下的话,第一个1dfs的时候就会出现这种情况。
0000
1001
0000
所以不行。
然后第二题
给你一个字符,判断是否能够由一个字符串的列表里面的字符串组成。
如"abcde",能由{“ab”,“cd”,“de”,“e”}里面的{“ab”,“cd”,“e”}组成,所以返回true。
让我先说一下思路再写。
我说应该是动态规划,向前匹配,如果匹配了,而且起始位置为true,那么这个位置也为true。
然后说那你先写,结果我没写出来,一直熬到了结束。
他说你思路差不多对的,就是细节好好想想。
然后说差不多就这样吧。(我心都凉了)
然后问了我一句我是投的哪里的base。
然后,就没有然后了,就谢谢,挂了。
后面再更吧,过没过都过来发个后续,如果有大佬做了第二题,麻烦评论下,我今天脑袋秀逗了,实在没做出来,感觉应该是中等题。去玩游戏了。
2022.1.25
收到感谢信了。。。
哎,总结一下:算法很重要,刷题时要和面试官多沟通,确认好面试官的问题之后再做题,写前跟他说下思路。