面试小结(持续更)

前言:天将降大任于斯人也,必先苦其心志,劳其筋骨,饿其体肤,空乏其身,行拂乱其所为,所以动心忍性,曾益其所不能。

1.作业帮(算法/数据挖掘实习生)

(1)从海量数据中找出前1000个最大数

解决方案:先选出1000个数来建立一个小根堆(时间复杂度为o(m),m为堆的大小),然后遍历剩下的元素,如果当前元素比堆顶元素(最小的数)小,则丢弃;反之则替换堆顶元素,进行堆调整即可(时间复杂度为n*log(m),n为数据的规模),所以总时间复杂度为o(n+n*logm) , 由于m相对于n而言非常小,所以总时间复杂度为O(n)。如果进一步优化的话,可以把这些海量数据分组进行查找前1000个最大数,最后进行归并。

(2)如何给决策树进行剪枝?

C4.5剪枝策略:如果剪枝前的损失函数为C(A),剪枝后的损失函数为C(B),如果C(B)≤C(A)则进行剪枝,直到无法剪枝才结束;

CART剪枝策略:计算所有节点的g(t) = c(t)-C(Tt) / |Tt| - 1, 选择g(t)最小的节点进行剪枝(可以进行局部剪枝),周而复始,直到只剩下一个根结点和两个叶子结点为止,最后通过交叉验证法来选择最优的决策树。

感受:感觉作业帮这次面试还是比较简单的,但是我还是挂了,其他同学当场就拿到offer了。


2. 瓜子网(算法/数据挖掘实习生)

(1)用两个队列模拟实现一个栈(队列相关方法自己定义)

(2)谈谈对SVM核函数的认识?我们可以自定义核函数吗?如果可以需要满足什么条件?

(3)假如有一个样例既出现在正样本中,又出现在负样本中,对最终的训练有何影响?

(4)谈谈GBDT与xgboost的区别。

感受:比较注重基础,一共两面,最后拿到了offer。


3. momo(算法/数据挖掘实习生)

陌陌我是找人内推的,一轮技术面,一轮hr面。技术面和面试官聊得很愉快,主要是聊简历上的项目,以及项目中用到的一些模型gbdt、xgboost等,另外还问了一些基础的数据结构知识,很简单。后来我就问面试官我过去了能干啥?之后面试官就谈了他们目前的工作,我也是非常感兴趣。

感受:氛围非常好,无论是面试官还是hr,都给人一种“好想和他做同事啊的感觉",哈哈。offer下来是推荐研发实习生。


4.腾讯

之前感觉进腾讯算法岗很难,于是3月份就内推了个数据分析岗。一面写了个判断当前有向图是否有环的代码,个人觉得还不错,而且面试官还说让等接下来的面试,之后一直没消息,再后来室友让上微信公众号查询进度才发现挂了。。然后就赶紧把岗位改成算法—机器学习岗,等待4月份的网申。

一面是个很和善的面试官(搜索引擎方向),我们聊得很开心,没有自我介绍,也没有介绍项目,全程在聊机器学习的模型,很过瘾。

二面的面试官(文本处理方向)很不和善,由于要面很多同学,就让我简单说了一个项目,然后让我写代码(全排列)。可能是面试官觉得我写不出来,所以就开始给我写评价。。结果我说可以用vector吗?他说可以,然后说时间来不及了,你给我说下大致思路吧!然后我balabala把思路说了一下(当时不是很确定,但是感觉和之前的题目很类似)。从进门到结束,前后20分钟不到。

感受:挂了!挂了倒没什么,就感觉二面的面试官很敷衍。查到面试结果的时候我还在想是不是那个全排列说错了,然后用代码实现了下,是那个思路没错。代码如下:

#include<iostream>
using namespace std;
#include<vector>

bool IsAccessible(int n, vector<int >array ) // 定义一个bool函数来判断当前数字是否可以加入当前数组中
{
	for(int i=0;i<array.size();i++)
		if(array[i]==n) // 如果当前数字已在数组中存在,则返回false表明当前数字不允许加入数组中
			return false;
	return true; // 之前没存在过,可以加进去
}

int count = 0; // 统计一共有多少种组合

void Print(vector<int >array, int N)
{
	if(array.size()==N) // 当数组中的元素个数达到N,则表明存在一种合理组合,输出即可
	{
		for(int j=0;j<N;j++)
			cout<<array[j]<<ends;
		cout<<endl;
		count++;
		return;
	}
	// 程序执行到这一步,表明仍然需要进一步组合,而每个位置的可能性选择都为1~N
	for(int i=1;i<=N;i++)
	{
		if(IsAccessible(i,array)) // 当前元素允许加入数组中
		{
			array.push_back(i);
			Print(array,N); // 递归调用
			array.pop_back(); // 当前选择打印完毕则把该元素删除(for循环指定的元素都是同一位置上的元素)
		}
	}

}

int main()
{
	vector<int >array; // 定义一个vector用来存放当前可能的组合
	int N;
	cout<<"请输入一个正整数:";
	cin>>N;
	Print(array,N); // 递归调用进行数的组合
	cout<<"共有组合数:"<<count<<endl; // 输出一共可能的组数
	return 0;
}

5. 阿里巴巴

       阿里我是从3月份就开始找师兄内推,5月7号才结束,前后时间跨度蛮大。一面的面试官很好,主要是手撕代码,一共问了两道编程题,第一道是如何从一个无序数组中快速找到第k大的数(借助快排的思想,时间复杂度为O(n)),第二道是判断把一个数组划分成两个和相同的子数组的划分种数(之前只遇到过把一个数组划分成两个和相同的子数组,采用动态规划的思想,这种求多少种情况的第一次见,当时就一直往动态规划上扯,,至今还是没想明白怎么做。。),二面面试官是位女士,简单了解了项目之后问我会不会深度学习和强化学习,当时只学了点深度学习,于是大概说了下神经网络的反向传播过程,然后就直接给我个场景让我现场建模(由于项目中有个新闻推荐,就让我建模解决推荐丰富度问题),回答的不好。三面面试官打电话过来说愿不愿意转算法测试(后来才知道就是测开),,接着就按照测试岗进行的接下来的面试,三面、四面、五面(这几面主要都是聊简历和项目)。

感受:面试体验挺好,最后也拿到了测试的offer。整个面试流程下来确实挺难熬的,但基本上过了一面,下面的面试都不会太难,毕竟手撕代码真的很难啊啊。


猜你喜欢

转载自blog.csdn.net/jingyi130705008/article/details/79599218