先是通过应聘游戏后台开发实习生进入了企鹅,后来才通过努力让自己留下来的。
首先是笔试,因为武汉的笔试是第二批城市,所以参加笔试之前,就先看了下第一批城市的笔试题,出的既有难度又有广度,涉及了方方面面。但是第二批城市的笔试题却略水,估计这应该就是企鹅简历不怎么刷人,笔试也不怎么刷人的原因。
一面:
面试官是一帅哥,看了下我简历,我简历上写的大大的应聘游戏后台开发几个字,就先让我谈了下对游戏后台开发的理解。我当时也不了解面试官是做SNSGame的还是MMO,所以就谈了下对MMO的理解,client的主循环,server的主循环,网关,逻辑节点,数据服务等等。
然后问了下我的专业主要是干嘛的,我简单的说了下,他说那也就是说主要是做client的,我一听不淡定了,连忙抓起简历指着之前做过的GIS工程项目说了下里面的架构,以及对后台的理解,抽象出了交互层,将交互层描述为client,之后的节点其实都属于后台等等,可以无缝迁移到其他物理节点上去。顺水推舟的就按数据流讲了下整个项目的架构,用到的各种设计模式等等。
接着就开始对简历技能一项项问了。
先是TCP方面的,问了下我读过的TCP相关的书,问了四次握手的详细过程,不过这时对内核理解还不够深入,幸好没有问内核中协议栈的相关实现。只回答了四次发包以及内核buff中的对应状态改变流程。
问了TIME_WAIT状态,答了两个点,又问了下TCP头长度,我就完全凭直觉的说出来20字节。
然后开始问linux内核方面的。
问到了slab层,我讲了下里面对每个kmem_cache维护的相关联的三种链表,最后总结下就是一个稍微复杂点的内存池,在之前提到的项目里也用了比较类似的理念。
问了linux中的线程比传统unix的线程特殊在什么地方。我详细讲了下clone系统调用时根据传参的不同确定的是线程或进程。
问了C进程地址空间的结构。分别讲了下内核空间和用户空间,用户空间从高地址到低地址依次说了下布局,看得出面试官对回答还是挺满意的。
又问了问常见的同步问题,这块因为平时接触的不多,当时挺担心让手写个生产者消费者代码的,所以我就大概说了下常见的几种情境,读写者,扯了扯哲学家问题。
然后开始问socket编程。
先让解释了下非阻塞I/O,怎么设置,设置了之后socket层的缓冲区怎么操作,这块当时理解还不透彻,简单的说了下我的理解就算pass了。
问了send调用返回小整数表示什么,底层机制如何,这个答的我自己都不知在说啥了。
socket缓冲区的大小怎么设置,这个忘记对应的参数了。
问了我一些linux常用的命令和参数。
然后问了个开放性问题,海量用户login_logout数据,统计画出在线人数曲线图,这个挺扯的,不展开说了。
最后写个coding题,写strstr函数。
二面:
面试官一口广东口音,上来先看我演示了下我的某个项目,因为是.Net写的所以也没想多讲,就赶紧关掉演示了。然后面试官开始出题。
先让我设计一个魔方游戏的数据结构。当时状态不佳,没想明白要考察什么,所以就说一个三维数组直接简单粗暴了。
然后给了一个场景,如果某个游戏不允许多个id同时登录,后台应该采取什么策略。这个其实每个id存个session,接到相同id的登录请求时给原先的id对应的socket发个包踢掉即可。
问了下反作弊系统如何实现,说实话问到这里我感觉这个面试官像是client出身,因为client会考虑反作弊多一些,我对这些完全不太了解,只能尝试性的说协议加密做好,client做响应策略blabla。
面试官似乎对答案不太满意,然后又问了外挂的实现方式,我先说了个抓包,解析,然后伪装一下签名发包。然后他问我具体的流程,这我完全不了解,就pass掉了。
然后面试官说看我也了解不少的clientGUI库,讲一下共通之处。我大概讲了下我的理解,包括分层的理念,包括模型的取舍方面。
之后问了一个问题是不能用脚本的情况下,client怎么样可以在运行时动态地执行一段server传来的代码,这种开放性问题我感觉是完全不用考虑逻辑的问题,只要给一个方案就可以。我直接的想法就是client这边直接匿名映射一块可执行虚存,然后在一个虚拟机中直接跑这段字节码。
最后又讲了下项目。
HR面:忽略掉,反正是过了。
满意的地方:
笔试和HR面试都是走过程,真招都在一面和二面。
不满意的地方:
广东口音的人交流起来有些苦难。