2022 微软暑期实习研发提前批面经(全)

总体流程

【投递信息来源】校招丨微软2022暑期实习研发提前批正式启动!

2021.12.17        投递

2022.01.06        简历筛选通过

2022.01.17        一面

2022.01.19        平行二面

2022.01.21        leader终面

2022.01.26        信息采集

2022.01.27        意向书

一面

【时间】2022.01.17

【时长】约60分钟

【面试前流程】微软招聘推送显示,提前批的筛选时间为1.4到1.10,我是1月6日收到邮件通知简历通过,随后在1月10日接到面试安排电话,然后收到17号的一面邀请。

【求职进程】博主的第(3)场实习面试,总第(3)场面试

1、自我介绍(英语)

2、介绍论文

3、论文(项目)中用了哪些技术,论文数据是怎么收集的

我做的内容是和网络协议、网络体系结构和SDN相关的,主要讲了一下结合机器学习模型在SDN中检测网络攻击的相关论文工作,面试官对如何获取网络数据感兴趣,回答是基于SDN控制器实现数据采集应用模块。

4、TCP拥塞控制,还知道哪些拥塞控制机制

这里回答了TCP Tahoe和Reno的详细机制,其他的讲了New Reno、Cubic、BBR等。

5、C++ vector扩容的工作原理

每次扩容2倍,并且新开一块内存把原来vector的东西拷贝过去(然而事实在visual studio里面测试,扩容的倍率大概是1.5倍上下)

6、考虑vector扩容,求push_back的复杂度期望(均摊复杂度)

常数复杂度,参考:​​​​​动态数组(vector)-详解均摊复杂度分析和避免避免复杂度的震荡(C++实现)_结构设计软件开发-CSDN博客_vector的空间复杂度

这个题我之前没有见过,答得不是很好。我在面试的时候按照每次扩容2倍计算,那么N个元素就要扩容logN次(以2为底的log),但是我是在电脑的记事本上面打了草稿,草稿上写的都是logN,一直忘记了这个玩意是以2为底的,所以有一步计算2的logN次方,那个地方面试官一直提醒我化简,我卡了很久才反应过来(化简结果就是N,因为同底)。

7、算法题:二叉树的直径(Leetcode 543)力扣

【评价】这场面试的题目都比较基础。项目部分,只要是自己做的,能说出总体概况和清楚一些亮点细节基本上没问题,但是由于后续进入了平行二面,也就是这一次面试实际在面试官那里表现得并不算太好,考虑在计算复杂度的时候的那个对数(第6题)卡壳太久,也从一个侧面反映了题目越简单其实容错率也是越低的。

平行二面

【时间】2022.01.19

【时长】约55分钟

【面试前流程】17号一面结束以后接到电话约平行二面时间,当晚收到平行二面会议链接邮件。

【求职进程】博主的第(4)场实习面试,总第(4)场面试

1、自我介绍(中文)

2、介绍论文,论文中的难点,怎么解决的

回答大概是,论文中的难点在于论文所提出的系统各个部分的集成和协同,讲了一些论文提出的系统的框架,以及一个核心的队列式的实时网络流量序列窗口的设计。

3、算法题:剑指54:二叉搜索树最大的第K个结点(要求使用非递归方法遍历)力扣

以下贴出我面试时写的代码(可读比较差,因为是面试共享屏幕写的),非递归方法采用栈实现,找最大的第K结点,基于右子树→根→左子树的“反中序”遍历,生成降序序列,统计遍历过的结点数量,等于K则返回。

有一个点要注意,就是我的代码中函数返回值是TreeNode(树结点),因为考虑到二叉搜索树可能出现结点数量还不到K个的情况,此时int的返回值不知道返回什么才合适,因此返回树结点类型,在主函数里面判空,再提取值。

TreeNode* KBiggestNode(TreeNode *root, int k)
{
	if(root == NULL)
	return;
	stack Nodes;
	int curVisitedNodeCount = 0;
	while(!Nodes.empty() || root)
	{
		if(root)
		{
			Nodes.push(root);
			root = root->right;
		}
		// Find the leftmost node where inorder starts.
		else
		{
			root = Nodes.top();
			Nodes.pop();
			// cout< val<<" ";
			curVisitedNodeCount ++;
			if(curVisitedNodeCount == k)
			return root;
			if(root->left)
			root = root -> left;
		}
	}
	return NULL;
}

int main()
{
	TreeNode* root = new TreeNode;
	TreeNode* result = KBiggestNode(root, k);
	if(result)
	return result -> val;
	else
	cout<<"BST中的结点数小于K"<

4、算法题:括号生成(Leetcode 22)力扣

先贴我面试时写的代码:

vector result;

void generate(string currentString, int size, int left, int right)
{
	if(currentString.length() == size*2)
	{
		result.push_back(currentString);
		return;
	}
	if(left < size)
	{
		currentString += "(";
		// 下一步递归即可以插入左括号也可以右括号
		generate(currentString, size, left+1, right);
		currentString.erase(currentString.end()-1);	// currentString.pop_back() 
	}
	if(right < left) // 用当前层的左括号数量限制右括号 
	{
		currentString += ")";
		// 下一步递归即可以插入左括号也可以右括号
		generate(currentString, size, left, right+1);
		currentString.erase(currentString.end()-1); // currentString.pop_back() 
	}
} 

int main()
{
	int k = // 输入 
	string currentString = "";
	generate(currentString, k, 0, 0);
}

写完以后面试官问我如何优化这个代码的性能,我确实不太清楚,我回答了把递归调用返回后的状态复原,即erase string的最后一个括号的操作改成pop_back(),是否能减少STL的调用次数?面试官说其实这两操作是一样的。然后面试就结束了。

事实上确实应该从减少STL调用次数上考虑,但是不是修改erase,而是根本不用频繁的STL操作,把当前的【括号串 + 新加入的括号】作为参数传入下一轮递归(无需在本层递归操作括号串)就可以了,优化的代码应该长这样:

class Solution {
public:
    vector generateParenthesis(int n) {
        vector res;
        func(res, "", 0, 0, n);
        return res;
    }
    
    void func(vector &res, string str, int l, int r, int n){
        if(l > n || r > n || r > l) return ;
        if(l == n && r == n) {res.push_back(str); return;}
        func(res, str + '(', l+1, r, n);
        func(res, str + ')', l, r+1, n);
        return;
    }
};

三面(leader终面)

【时间】2022.01.21

【时长】约55分钟

【面试前流程】19号二面结束以后,当天下午5点收到leader面邀请。

【求职进程】博主的第(5)场实习面试,总第(5)场面试,该场面试后取得了offer

1、自我介绍(中文)

2、介绍研究方向

回答时将我研究的SDN数据平面、控制平面和控制通道的体系结构,及其存在的低速率网络攻击的安全威胁(三篇论文)串起来讲了一遍,约20分钟。

3、算法题:剑指42:连续子数组的最大和(要求:考虑非法输入和int溢出)力扣

这道题本身太基础了,动态规划直接解决,这里就不贴代码了(其实是在一个在线网站上写的代码,我没有保存)

写完追问:

一、怎么考虑非法输入(输入vector为空),回答:抛出异常,或enum类型:为空或不合法时返回特殊全局变量;

二、怎么考虑int类型溢出(我后来把这个代码重构了一遍,数字写成字符串,写了一个字符串相加函数,字符串从后往前相加,结果正序存储在另一个字符串中,最后reverse)

三、怎么考虑负数问题(未实现,仅讲述了思路,回答:首先,看字符串首个元素,判断正负性;第二,比较字符串长度判断绝对值大小;第三,如果字符串数字部分长度一样,逐位比对大小,判断计算结果的正负性;第四:计算出的结果位数可能减小,去除先导零)

4、反问

目前主要是熟悉C++,如果接受实习,语言栈会不会影响我被分配到的产品业务分组(未得到明确回答)。

Offer

2022.01.26        10:46        实习信息补充(学校名称、学校所在地点、入职时间)

2022.01.27        16:49        意向书

2022.01.27        21:59        接受意向书

至此拿下实习的第一个Offer,共计面试5场。

通关配置为:力扣201题(简单106,中等83,困难12)

你可能感兴趣的:(烤面筋,microsoft,面试)