• 网易互娱 游戏研发 暑期实习面试面经


    前言

    昨天面了网易互娱的游戏研发工程师,回想下似乎问的问题并不多,整体也就 5 个问题,但每个问题展开之后里面的量好像也不少,现在整理一下,顺便解决下面试中没答上来的地方。

    面试题

    先是自我介绍。。。。。面试官了解到我对 Python 更加熟悉一些,于是问了比较多的 Python 相关的问题。

    Python 中如何实现类成员的 public、private、protected

    面试官:在 C++、Java中,定义一个类,其成员可以申明为 public、private、protected, 那么在Python 中如何实现类成员的 public、private、protected
    答:Python 语言并不存在控制访问,所以无法直接定义类成员的 pubilc、private等属性,一般情况下是通过命名规约来达到这个效果,对于 private 的成员,一般命名以 _ 开头,而 public 的则正常命名即可。

    面试官:那对于双下划线__开头的成员呢?

    答:双下划线开头的成员感觉主要是用在类的继承的时候,如果不想子类直接访问到父类的这个成员,则可以以双下滑线开头。(修正,不仅仅是继承的时候,在该类中定义了双下划线开头的成员,实例化的对象也无法直接访问该成员)

    面试官:如果我访问了这个双下划线开头的成员,会报什么错误?

    这里我突然就愣住了,因为之前都没去尝试过,愣了一会儿之后,面试官给了些提示,如果你访问一个变量,但这个变量没有定义的话,那会报什么错误?

    答:应该是变量不存在吧

    面试官:那上面那个问题是报什么错误呢?

    答:这么一说感觉应该是变量不存在

    面试官:那再问问如果我非要访问这个双下滑线开头的成员,要怎么做?

    这里真就不会了 orz

    现在来补一下

    '''
    @Description: 
    @Author: 妄想
    @Date: 2020-05-29 15:28:30
    @LastEditTime: 2020-05-29 15:32:52
    @LastEditors: 妄想
    '''
    class base:
        def __init__(self):
            self.public = 1
            self._internal = 2
            self.__private = 3
        
        def public_method(self):
            print('public method')
        
        def _internal_method(self):
            print('internal method')
        
        def __private_method(self):
            print('private method')
    
    b = base()
    print(b.public)
    print(b._internal)
    print(b.__private)
    

    运行一下

    那我该如何访问它呢?查了下资料,发现双下划线开头的成员,会被重命名,变成 _类名 + 成员名,在这里就是b._base__private

    print(b.public)
    print(b._internal)
    print(b._base__private)
    

    函数也是类似

    python 修饰器

    面试官:了解过修饰器吗?

    答:了解过

    面试官:介绍下 Python 中修饰器(问题大概就是这个意思吧)

    答:balabalabala。。。。(大致意思就是减少代码重复,封装成装饰器方便使用,类似于函数)

    面试官:那一个装饰器的输入和输出是什么呢?

    答:输入?可以是任意的参数吧,这个不是根据实际定义的吗?(这里我理解错了面试官的意思了- - ,因为之前在做 web 后端的时候,用了修饰器来做 token 验证,当时将 token 作为一个参数使用了)后面在面试官的引导下,反应过来了,输入和输出都是函数。

    面试官:如果我不采用 @修饰器名称 的方式来调用修饰器,那该怎么做?

    答:我印象中是直接当做函数调用就好了,但是好像并没成功 orz 。。

    先来个一般写法

    def foo(f):
        def inner():
            print('inner')
            return f
        return inner
    
    @foo
    def bar():
        pass
    
    bar()
    

    会发现输出了 inner,然后我当时写了这样的调用

    def foo(f):
        def inner():
            print('inner')
            return f
        return inner
    
    def bar():
        pass
    
    foo(bar)
    

    发现没输出 orz, 然后就过去了,后来仔细想想,虽说返回的是函数,但只是这个函数名啊,我并没有调用它哪来的输出啊,菜哭。。

    改成这样就好了

    bar = foo(bar)
    bar()
    # 或
    foo(bar)()
    

    python 迭代器

    面试官:了解过迭代器吗?可以介绍下吗?

    答:迭代器一般是用在对 Python 中的数据结构进行遍历,比如我现在有一个名为 li 的 List,我想对里面每个元素进行修改,那就需要遍历每个元素,这时通过 for number in li: 这条语句,便会生成一个迭代器,然后 number 为当前所在位置的元素。

    面试官:那这跟直接索引遍历相比的好处是什么?

    答:(这里凭感觉答的,也不清楚对不对)1. 按索引遍历的话首先需要知道这个数据结构的长度。2. 每次遍历的时候都需要通过索引来获取这个数据,而通过迭代器可直接获取到数据。

    面试官:那有没有什么情况下是不能使用迭代器的呢?

    答:这里我觉得存在删除操作的时候应该是不能使用迭代器的,如下面这段代码, 我想删除列表中大于 3 的元素

    li = [1, 2, 3, 4, 5, 1, 4]
    for i in li:
        if i > 3:
            li.remove(i)
    print(li)
    

    输出一下发现结果为 [1, 2, 3, 5, 1]

    面试官:那添加的时候呢?

    答:添加的情况没遇到过,不太清楚,但感觉应该也不太行。(个人感觉,一般来说添加是需要满足某种情况才进行添加,但是在迭代过程中进行添加,会导致迭代器需迭代的元素不断增加,如果操作不当可能会陷入死循环)。

    C++ 结构体对齐

    本以为结构体对齐很简单的,然而。。我天真了 - -

    面试官:那接下来问问 C++ 方面的内容,了解过结构体的对齐吗?

    答:了解过, balabalabala。。。。

    面试官:那来算一下这个结构体的大小吧

    struct Node
    {
        short a;
        long b;
        char c;
        char d;
        int e;
        int f;
        short i;
        short j;
        long k;
    };
    

    答:(算就算吧),算了一会儿,算出来一个 34 字节

    面试官:怎么得出来的

    答:首先 short 占 2 字节, 然后 long 占 8 字节, 后面加起来总共是 22 字节,对齐一下就是 24 字节,加起来总共 34 字节。(后来验证了下,发现自己错了 orz)

    面试官:你确定这里第一个 short 只占 2 字节吗?

    答:balabalabala。。。(我还觉得自己很对,后来下来验证了下发现自己打错了 orz)

    面试官:这里操作系统是怎么读取数据的?一次能读两个字节吗?

    答:(这里我已经懵逼了)emmmmm。。。不太清楚。。我记得这里应该是读取一个起始位置 + 偏移量来获取这个数据。

    面试官:下去之后有兴趣再去了解了解吧

    这里开始补充,发现 mingw64 long只占 4 个字节???

    /*
     * @Description: 
     * @Author: 妄想
     * @Date: 2020-05-29 16:42:59
     * @LastEditTime: 2020-05-29 16:54:49
     * @LastEditors: 妄想
     */ 
    #include<iostream>
    #include<stdio.h>
    using namespace std;
    
    struct Node
    {
        short a;
        long long b;
        char c;
        char d;
        int e;
        int f;
        short i;
        short j;
        long long k;
    };
    
    // 2 + 8 + 22
    // 34
    
    int main(){
        printf("%d
    ", sizeof(Node));
        printf("%d %d %d %d %d %d %d %d %d
    ", 
            &Node::a, &Node::b, &Node::c, &Node::d, &Node::e, &Node::f, &Node::i, &Node::j, &Node::k);
        printf("char:%d, short:%d, int:%d, long:%d, long long:%d
    ", sizeof(char), sizeof(short), sizeof(int), sizeof(long), sizeof(long long));
        return 0;
    }
    

    看一下输出

    这个 long 只占 4 字节有点迷,没办法,就先改成 long long 吧。

    可以发现,变量 b 的起始位置是 8 而不是 2,e 的起始位置是 20 而不是 18。

    查了下相关博客

    1. 结构体中元素需被放置在自身对齐大小的整数倍的位置上
    2. 如果结构体的大小不是所有元素中最大对齐大小的整数倍,则结构体对齐到最大元素对齐大小的整数倍,填充空间放置到结构体末尾

    排序算法

    面试官:接下来问问算法方面的东西吧,说一说快排的流程。

    答:(很尴尬。。。已经很久没有接触过排序算法了,近期准备面试也没看过排序方面的东西,所以想了一段时间,好歹还是想起来了) balabalabala。。。。

    面试官:那时间复杂度呢?

    答:最差 (O(n^2)) ,平均 (O(nlog n))

    面试官:什么情况下最差呢?

    答:数组完全逆序排序的时候

    面试官:那怎么选取主元能使得快排的性能最好呢?

    答:(这个之前在算法导论上看到过,然而已经忘了。。。想了想,如果说每次划分正好在数组的正中间,那么可达一个较优的情况所以就答了中位数)

    面试官:那再问问其他问题,有了解过其他最差情况不会像快排这样的排序算法吗?

    答:(这里感觉面试官问的应该是稳定的排序算法有哪些,当时能想起来的就是归并排序结果一不小心答成分治排序 - -)

    补充:从别的地方拿来的图

    算法题

    写了道链表翻转,结果很尴尬,忘了将翻转后的链表最后一个元素的 next 设置为空,导致一直超时 orz 。。。。。过程中边 debug 边跟面试官讨论,最后改出来了。。害,太久没手写过数据结构了,这么一道简单的题还写出 bug。。。哭了

    提问

    问了下想到网易做游戏开发需要学些什么(毕竟当年是想做游戏开发才选的计算机,而且大一刚入学的目标就是网易游戏,虽然后来搞了近两年机器学习。。),面试官说是并没有太指望应届生有游戏开发相关的知识,要求就是基础要扎实,能够做到他们交给我们的东西我们能学会。(不说了,接着补基础去了。。。)

    小节

    一次体验极好的面试,总共面了一个小时多一点,过程中有答不上来的地方面试官会慢慢引导自己,结束之后感觉好像答的还不错,梳理一下发现问题还是有点多 orz。。面试之前看了不少网易游戏研发的面经,照着面经准备了几天,发现被问到的面经上都没出现,真就全靠平时积累。。。看来还有好多地方需要补一补。。说是一周内会出结果,只能看命了。。

    从三月份开始投算法岗,一直到之前改投开发岗,挂了无数次,看着周围一些同学都拿了不少 offer,压力有点大。。

  • 相关阅读:
    c# 暴力破解中文编码方式
    vs调试 不能进入断点
    shell-的bash内部命令变量介绍与shift等
    shell-的特殊变量-难点理论
    shell-的特殊变量-进程状态变量$$ $! $? $_详解
    shell-的特殊变量-位置变量$0 $n $* $# $@详解
    shell-的变量-局部变量
    shell-的变量-全局变量
    shell-脚本开发基本规范及习惯
    shell-脚本的执行
  • 原文地址:https://www.cnblogs.com/csu-lmw/p/12988803.html
Copyright © 2020-2023  润新知