面试造核弹,工作拧螺丝?


最近在工作中遇到这么一个问题。

一个使用机器学习算法的框架,在特征处理模块,往往需要对原始特征进行特征交叉。对于简单的单值特征来说,只需要将需要交叉的特征组合起来即可;但是对于多值特征之间的交叉,则需要穷举多值特征每一个值的组合。例如,如果一个包含2个值的特征和一个包含3个值的特征组合,那么将会产生出6个组合。

一般的,我们可以把这些多值特征描述为

1
vector<vector<Feature>>

那么给定这样的一个数据结构,如何输出所有的特征组合呢?


直观想法,这好像是直接遍历就可以解决,但是稍微细想一下,简单的N重for循环,无法解决这个问题。

在纸上画了一会儿之后,突然发现,这不就是一个输出全排列的问题吗?

把问题抽象出来之后,我先是按照手工枚举全排列的思路,写了一个非递归的循环版本,但是可读性不好。然后又实现了一个可读性更好的递归版本。


上面这个问题,只是一个引子。

我相信,程序员在大学毕业找工作的时候,一定刷过各种各样的算法题、数据结构题,什么贪心算法、动态规划、快排、二分查找,现在算法工程师们还要手推SVM、反向传播算法等等,面试时也是历尽千辛万苦;然而工作后却发现,正是应了题目那句话:面试造核弹,工作拧螺丝。

作为面试官也是一样,考察了基础知识、算法题、智力题一大圈,结果招来的人入职后,发现怎么干活还是不靠谱?


话分两头说。

对于上面的特征交叉问题,完全可以限定只支持2个特征交叉。那么直接

1
2
3
4
5
f1 = features[0]
f2 = features[1]
for i in f1:
for j in f2:
cross(i, j)

就直接解决了~皆大欢喜,完全不用想什么全排列不全排列的事情。

如果事事都这样简而化之,那么确实,大部分的工作都是拧螺丝。

但是,时代发展这么快,万一将来,拧螺丝的工种直接被AI取代了呢?这么说吧,不涉及深入思考的工作,都将会慢慢边缘化。千万不要用战术上的勤奋,掩盖了战略上的懒惰。

另一方面,面试官在面试时,是要考察什么能力?是不是算法题写的滴水不漏就行了?

抛开对人的相关素质的考察(责任心、合作能力、态度等),我觉得不管是出算法题,还是出智力题,其实最主要的,是考察一个人抽象问题的能力。

所以,直接让人默写一个快排,或者手推SVM,基本和问他“中国面积最大的计划单列市是哪一个”没什么区别。正确的做法,应该是从一个实际问题出发,在对话中,了解应聘者的能力。

在万事搜索一下便知的时代,同样遇到一个陌生的问题,有的人就能很快的从搜索引擎上得到答案,有的人在搜索引擎上乱翻一天也解决不了。为什么?这就是抽象问题能力的差异。

还是以上面我遇到的问题为例。有的人遇到这样的问题,可能会去直接搜索“特征交叉”,这样得到的结果中,噪音是非常多的;而有的人直接搜索“全排列算法”,基本上前三条就可以找到答案。


最后说一句。脑子这个搜索引擎是最快的,所以知识、经验还是要尽量记在脑子中;而抽象能力+搜索引擎,可以极大的扩展你的知识边界。

最后,祝大家中秋节都能造核弹~



推荐阅读:
使用双buffer无锁化
不要拷贝
crontab为何自动中断

转载请注明出处: http://blog.guoyb.com/2018/09/22/interview/

欢迎使用微信扫描下方二维码,关注我的微信公众号TechTalking,技术·生活·思考:
后端技术小黑屋

Comments