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

    总结

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

  • 相关阅读:
    is as运算符
    继承,多态
    封装等
    面向对象
    在JDBC中使用带参数的SQL语句
    我的程序库:HiCSDB
    我的程序库:HiCSUtil
    Java中,将ResultSet映射为对象和队列及其他辅助函数
    Java版的对象关系映射实现
    Java中的基本数据类型转换
  • 原文地址:https://www.cnblogs.com/nomornings/p/13836867.html
Copyright © 2011-2022 走看看