【暑期实习】计算机视觉岗问题整理-腾讯

一边面试一边整理学习,希望自己早日上岸。

第一次面试

Q:

python解释器与伪多线程?

A:

关于Python解释器,可以参考廖雪峰这篇文章:

当我们编写Python代码时,我们得到的是一个包含Python代码的以.py为扩展名的文本文件。要运行代码,就需要Python解释器去执行.py文件。

由于整个Python语言从规范到解释器都是开源的,所以理论上,只要水平够高,任何人都可以编写Python解释器来执行Python代码(当然难度很大)。事实上,确实存在多种Python解释器。

CPython

当我们从Python官方网站下载并安装好Python 2.7后,我们就直接获得了一个官方版本的解释器:CPython。这个解释器是用C语言开发的,所以叫CPython。在命令行下运行python就是启动CPython解释器。

CPython是使用最广的Python解释器。教程的所有代码也都在CPython下执行。

IPython

IPython是基于CPython之上的一个交互式解释器,也就是说,IPython只是在交互方式上有所增强,但是执行Python代码的功能和CPython是完全一样的。好比很多国产浏览器虽然外观不同,但内核其实都是调用了IE。

CPython用>>>作为提示符,而IPython用In [序号]:作为提示符。

PyPy

PyPy是另一个Python解释器,它的目标是执行速度。PyPy采用JIT技术,对Python代码进行动态编译(注意不是解释),所以可以显著提高Python代码的执行速度。

绝大部分Python代码都可以在PyPy下运行,但是PyPy和CPython有一些是不同的,这就导致相同的Python代码在两种解释器下执行可能会有不同的结果。如果你的代码要放到PyPy下执行,就需要了解PyPy和CPython的不同点

Jython

Jython是运行在Java平台上的Python解释器,可以直接把Python代码编译成Java字节码执行。

IronPython

IronPython和Jython类似,只不过IronPython是运行在微软.Net平台上的Python解释器,可以直接把Python代码编译成.Net的字节码。

小结

Python的解释器很多,但使用最广泛的还是CPython。如果要和Java或.Net平台交互,最好的办法不是用Jython或IronPython,而是通过网络调用来交互,确保各程序之间的独立性。

本教程的所有代码只确保在CPython 2.7版本下运行。请务必在本地安装CPython(也就是从Python官方网站下载的安装程序)。

关于python的伪多线程可以参考这篇文章

在于 GIL ,在 Cpython 解释器(Python语言的主流解释器)中,有一把全局解释锁(Global Interpreter Lock)。在解释器解释执行 Python 代码时,先要得到这把锁,意味着,任何时候只可能有一个线程在执行代码,其它线程要想获得 CPU执行代码指令,就必须先获得这把锁,如果锁被其它线程占用了,那么该线程就只能等待**,直到占有该锁的线程释放锁才有执行代码指令的可能。

Q:

池化层的作用是什么?

A:

  1. invariance(不变性),这种不变性包括translation(平移),rotation(旋转),scale(尺度)

  2. 保留主要的特征同时减少参数(降维,效果类似PCA)和计算量,防止过拟合,提高模型泛化能力

平均池化:倾向于保留突出背景特征

最大池化:倾向于保留突出纹理特征

参考:

池化层作用

CNN中池化的作用?为什么要选择池化

Q:

一道算法题,类似于350. 两个数组的交集 II,但是要解决的是包括进阶问题的所有问题:

给定两个数组,编写一个函数来计算它们的交集。

示例 1:

输入: nums1 = [1,2,2,1], nums2 = [2,2]
输出: [2,2]
示例 2:

输入: nums1 = [4,9,5], nums2 = [9,4,9,8,4]
输出: [4,9]
说明:

输出结果中每个元素出现的次数,应与元素在两个数组中出现的次数一致。
我们可以不考虑输出结果的顺序。
进阶:

如果给定的数组已经排好序呢?你将如何优化你的算法?
如果 nums1 的大小比 nums2 小很多,哪种方法更优?
如果 nums2 的元素存储在磁盘上,磁盘内存是有限的,并且你不能一次加载所有的元素到内存中,你该怎么办?

A:

我回答的跟LeetCode中题解基本类似,就复制一下LeetCode当中讲述的比较条理的题解:

解法一:排序双指针
将两个数组进行排序,随后用双指针顺序查找相同的元素
时间复杂度O(max(nlogn, mlogm, n+m)),空间复杂度O(1) (n,m分别为两个数组的长度)

如果是进阶问题一中已排序的数组,则只需O(n)的时间复杂度

class Solution:
    def intersect(self, nums1: [int], nums2: [int]) -> [int]:
        nums1.sort()
        nums2.sort()
        r = []
        left, right = 0, 0
        while left < len(nums1) and right < len(nums2):
            if nums1[left] < nums2[right]:
                left += 1
            elif nums1[left] == nums2[right]:
                r.append(nums1[left])
                left += 1
                right += 1    
            else:
                right += 1
        return r

解法二: 哈希计数
将较小的数组哈希计数,随后在另一个数组中根据哈希来寻找。
时间复杂度(O(max(n, m))) 空间复杂度(O(min(n, m)))

适用于进阶问题二

解法三:通过归并外排将两个数组排序后再使用排序双指针查找
对应进阶问题三,如果内存十分小,不足以将数组全部载入内存,那么必然也不能使用哈希这类费空间的算法,只能选用空间复杂度最小的算法,即解法一。

但是解法一中需要改造,一般说排序算法都是针对于内部排序,一旦涉及到跟磁盘打交道(外部排序),则需要特殊的考虑。归并排序是天然适合外部排序的算法,可以将分割后的子数组写到单个文件中,归并时将小文件合并为更大的文件。当两个数组均排序完成生成两个大文件后,即可使用双指针遍历两个文件,如此可以使空间复杂度最低。

参考LeetCode题解

Q:

算法题 167. 两数之和 II - 输入有序数组

给定一个已按照升序排列 的有序数组,找到两个数使得它们相加之和等于目标数。

函数应该返回这两个下标值 index1 和 index2,其中 index1 必须小于 index2。

说明:

返回的下标值(index1 和 index2)不是从零开始的。
你可以假设每个输入只对应唯一的答案,而且你不可以重复使用相同的元素。
示例:

输入: numbers = [2, 7, 11, 15], target = 9
输出: [1,2]
解释: 2 与 7 之和等于目标数 9 。因此 index1 = 1, index2 = 2 。

A:

这个解答主要是关注如何用空间复杂度为(O(1))与时间复杂度为(O(n))的方法解决。

我们可以使用 两数之和 的解法在$ O(n^2)$ 时间 (O(1)) 空间暴力解决,也可以用哈希表在 (O(n)) 时间和$ O(n)$空间内解决。然而,这两种方法都没有用到输入数组已经排序的性质,我们可以做得更好。

我们使用两个指针,初始分别位于第一个元素和最后一个元素位置,比较这两个元素之和与目标值的大小。如果和等于目标值,我们发现了这个唯一解。如果比目标值小,我们将较小元素指针增加一。如果比目标值大,我们将较大指针减小一。移动指针后重复上述比较知道找到答案。

假设 ([... , a, b, c, ... , d, e, f, …])是已经升序排列的输入数组,并且元素 b, eb,e 是唯一解。因为我们从左到右移动较小指针,从右到左移动较大指针,总有某个时刻存在一个指针移动到 (b)(e) 的位置。不妨假设小指针县移动到了元素(b) ,这是两个元素的和一定比目标值大,根据我们的算法,我们会向左移动较大指针直至获得结果。

class Solution {
public:
    vector<int> twoSum(vector<int>& numbers, int target) {
        int low = 0, high = numbers.size() - 1;
        while (low < high) {
            int sum = numbers[low] + numbers[high];
            if (sum == target)
                return {low + 1, high + 1};
            else if (sum < target)
                ++low;
            else
                --high;
        }
        return {-1, -1};
    }
};

是否需要考虑 (numbers[low] + numbers[high]) 溢出呢?答案是不需要。因为即使两个元素之和溢出了,因为只存在唯一解,所以一定会先访问到答案。

复杂度分析

时间复杂度:(O(n))。每个元素最多被访问一次,共有 nn 个元素。
空间复杂度:(O(1))。只是用了两个指针。

参考LeetCode题解

Q:

DeepFM的相关知识

A:

聊到DeepFM是因为之前做的论文用到了一些类似的方法,也算是殊道同归,主要是一些特征的维度提升等等。具体的可以参考一下知乎的介绍:

CTR论文精读(七)--DeepFM

另外就是因为这个组是和推荐挂钩一些的,附上一些推荐系统快速入门的一些链接:

推荐系统简明教程-概述

推荐系统简明教程-召回

推荐系统简明教程-排序

第二次面试

没有coding,只有聊论文和项目。

第三次面试

同样没有coding,也是聊论文和项目。

HR面试

大概介绍了一下部门目前所做的一些研究方向,聊了一下实习相关的事宜。基本上offer的发放也会在三天左右完成。

总结

总体来说,腾讯的面试体验超级棒,基本上面试官都会和你的简历、项目、论文聊得很深,有一些很周到的建议也会提供给你。几次面试的间隔也很人性化,会提前短信邮件通知你下次面试,不像某宝直接打电话来面试,一点准备都没有。不得不说,这四次的面试真的很愉快。

原文地址:https://www.cnblogs.com/nomornings/p/13836867.html