zoukankan      html  css  js  c++  java
  • 【暑期实习】计算机视觉岗问题整理-腾讯

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

    第一次面试

    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的发放也会在三天左右完成。

    总结

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

  • 相关阅读:
    (Java实现) 洛谷 P1106 删数问题
    (Java实现) 洛谷 P1603 斯诺登的密码
    (Java实现) 洛谷 P1036 选数
    (Java实现) 洛谷 P1012 拼数
    (Java实现) 洛谷 P1028 数的计算
    (Java实现) 洛谷 P1553 数字反转(升级版)
    (Java实现) 洛谷 P1051 谁拿了最多奖学金
    (Java实现) 洛谷 P1051 谁拿了最多奖学金
    (Java实现) 洛谷 P1106 删数问题
    目测ZIP的压缩率
  • 原文地址:https://www.cnblogs.com/nomornings/p/13836867.html
Copyright © 2011-2022 走看看