手游开发 面试什么题目

2018-10-22 23:32:34 weixin_42602730 阅读数 14541

现在正是十月底,差不多进入了秋季招聘的尾声。从九月份开学初到现在的1个多月的时间中,在学校里平均每天有6场大大小小的校园招聘会。其实,我在自己开始参加秋招的时候,就准备以后写一些面试经验留给学弟学妹。通过一个多月的集中笔试面试,现在自己陆续拿到了一些满意的offer,有成果才有说服力。而且这段时间相对比较空,于是整理总结了一些面试经历,如果能对后面的求职者有所帮助,那么我牺牲其它时间来码这么多的字也值了。

我是学电子专业的,大学前几年除了刷绩点以外就是参加技术型的社团,后来由于热爱技术并能管点事情,还过社团的会长,因此对于做技术的同学比较了解。大多数理工科同学们,特别是做技术的,一般都比较内向,参加应聘可能技术上完全没问题,但在面试中不太擅长表现自己优秀的地方,尤其是面对HR某些犀利刁难的提问,有时候根本不知道如何作答。面试没有发挥出实际的水平,导致错过心仪的公司和岗位,那真是太可惜了。

成功之前往往都会经历失败,我先讲一讲在"浙江大华技术股份有限公司"的失败经历。

收到大华的面试通知,是在校园宣讲会过后几天的晚上。大华的第一面的面试地点就在学校里的学生活动中心,可以说对应聘生非常照顾,不用奔波赶路。

因为面试地点在学校,宿舍过去非常近,只提前半小时,对着镜子整理一下仪容,带着简历和资料出发了。

一面是技术面,首先是常规的自我介绍。我介绍了成绩和专业技能两方面。然后面试官看我简历,对我做的GUI上位机很感兴趣,让我详细地介绍了这个项目,把涉及的技术要点通通讲了。

介绍完项目,面试官出了三个C语言的题目。第一个是const 关键词的作用,以及const 定义的指针。第二个是出了一个函数,让我写一个指向那个函数的指针。第三个是问sizeof的问题,定义了 int 型数组 a[100],问 sizeof(a) 等于多少,又定义了一个指针 int *p,问 sizeof(p) 等于多少。这些都是C语言基础的内容,感觉答的都还可以,毕竟当年C语言满绩点,并且写单片机一直在使用C。当时指向函数的指针有点忘记了,实际写代码很少用到,凭感觉临时编了一个。就这样,一面顺利通过。

第二面开始,又是自我介绍。介绍过后面试官看了我简历,看到我有个 GitHub,就在他随身带的笔记本电脑上打开看了看,看到我写过很多 Python 代码,似乎不太感兴趣。其实我写过的 C 代码比 Python 代码多十几倍,只不过没有放在GitHub上。看了一会,面试官又瞄了一下简历,突然说你是电子专业的?这个时候他就拽了起来,似乎找到我的弱点了,追着问了很多我不熟悉的计算机专业课程的问题。现代PC机的架构是怎样的?写个HelloWorld程序输出到显示屏,在计算机内部是怎么跑的?TCP/IP四层网络模型每一层的具体功能是什么?我有很多没答上来,然后面试官直接告诉我说不合适这个岗位。面对这样直接的打击,我先是虎躯一震,然后很快淡定,问面试官以他看来我还可以在技术上如何提升。大华的面试至此结束。

有时候,面试看缘分,你跟面试官聊的来,就会很顺。

讲了失败的经历后,接着讲在中兴成功的面试经历。

中兴的面试过程,给人非常正规严肃的感觉,虽然今年4月份遭受了美国的制裁,但毕竟是个国际化的大公司,越是大公司越是有规范的流程。一般推荐应届生工作第一年去大公司,因为可以学习到规范的东西。

中兴一共有两轮面试,分别是专业技术面试和综合能力面试,安排在不同的两天进行。有一次收到面试通知是在午夜00:01。在这里告诉大家,求职应聘过程中一定要相信自己,坚持到最后一刻。HR处理简历的工作量非常大,发通知有先后很正常,有时候跟你一起去面试的同学收到了短信你还没收到,不用慌,耐心等。

 

距离两轮面试结束一共过了20多天,收到中兴的面试通过的短信。去看了下招聘官网的状态,目前仍显示处于综合面试状态,应该是还没来得及更新,实际上已经到了发offer的阶段,主要是谈拢最终的价钱。

以下是我当时面试经历的回忆,有些细节已经忘记,我尽了最大努力回忆。

收到第一条面邀短信是在深夜,按短信内容整理了一下要带的证件资料。发现还缺一份中兴官网填写的简历需要打印,我了个去,这个时候才告诉我要打印官网填的简历,大晚上的,宿舍门都快关闭了。明天早上去打印吧,然后就睡了。

第二天早上六点半醒来,准备和同学一起去。面试地点在西湖西边的一个酒店里,从学校过去还是挺远的,4个人打车可以均摊一下路费。

在学校一餐吃完早饭,就按计划去打印中兴官网的简历。这时才发现7点钟还没有打印店营业。机智的我在 Amap (某国内地图软件的英文版)上查到了那个面试的酒店,打了个电话过去,问他们有没有文件打印的服务,得到肯定答复后我就放心了。

于是,我到达了和同学约定等车的地点。过了一会儿他们来了,他们还要去图书馆打印成绩单,不过我几个月前就打印过了(我们学校里有两个地方可以自助打印成绩单,师生办事大厅和图书馆,本来是找教务处老师打印并手动盖章的,不过技术进步的好处之一就是可以使人偷懒)。一行四人去图书馆,发现那边的机器要八点后才开。但我们中最早的面试在9点半,时间不允许。于是,三个人缺成绩单,一个人缺官方简历,就这样奔赴战场了。

到了酒店,打印了简历,签了个到,就等安排面试。

中兴第一面是技术面试,面试官有两个,一个负责问问题,另一个全程不发言但一直盯着我看,估计是在观察我的仪容和反应。所以说去面试的时候,自己的衣着和形象是很重要的。

面试官让我自我介绍,我介绍了在校成绩和参加过的比赛。他接着问了项目,我介绍了其中一个。我项目中有用到 I2C 通信的器件,他仔细问了 I2C 协议的通信过程。我把 I2C 从起始条件开始通信到结束条件的过程都说了一遍。最后问我是IO模拟实现的还是硬件控制器的,我说我用的芯片没有 I2C 控制器,是 IO 模拟的,不知道这问题有没有藏着什么坑。

接着又问我C语言学的怎样,我说还不错。于是他让我说内存里面堆和栈的区别,我说栈是一段连续的空间,堆是不连续的。他又问堆为什么是不连续的,他一连追问,好像抓到了我的弱点。直到我说不熟悉为止。事后想起来,这个问题我感觉没有答好。

最后面试官问我还有什么问题吗?之前听说过这个套路,最好不要说没有问题了。我让他给我技术上的提升建议,以及问了技术岗位的职业上升通道。至此,我在中兴的一面结束了。

出乎意料,第二天早上起床收到了综合面的短信。看时间是凌晨发过来的,也就是说昨天的第一面技术面通过了。

赶到昨天面试过的酒店,参加了中兴的综合面。综合面等候室遇到了一些学校的熟人。

等候区叫到我名字了。进入面试房间时,门是开着的,我习惯性先敲了敲门,然后坐到了两个面试官前面。

递上自己的简历和成绩单后,面试官要求我用英文作个自我介绍。还好稍微准备了一下,之前听说中兴面试有英文环节不是虚传。我简单地介绍了一下自己名字,来自哪个学校,读什么专业,通过了四六级,参加过社团和志愿者活动等,没有说太多,怕说多了容易出差错。事后想起来,就凭大学里教的那点哑巴英语,自己如果没有准备,不敢大胆开口讲英语,那么面试的英语环节可以刷掉很多人。

然后一个面试官问我,你刚刚说喜欢旅游,你去过哪些地方。我一脸懵逼,我根本没说过喜欢旅游呀。我就如实说了我没讲过。然后他说不好意思,听错了(可能之前面试的有人说过喜欢旅游的吧)。后来我觉得也有可能是个小测试,万一我进了这个坑,那就是有点那啥意思了。面试过程中搬弄虚假信息,不懂装懂是很低级的行为。

接着问在大学参加过什么活动,我介绍了参加过的一些志愿者活动。面试官又看着我简历问我担任过社团的会长,当初为什么选我担任。我就说我非常喜欢技术,这是个技术型的社团,而且我比大多数搞技术的人外向一点,能管点事,于是我就担任了会长。

然后面试官说,我看你的C语言课程分数挺高,我给你两个C语言的题目做一下。他拿出了事先出好题目的两张小纸条给我看。第一个是定义了一个函数指针,问输出结果。第二个是定义了一个宏和数组,问代码哪里有错误。这两个题目都不难,只要不过于紧张一般都能答上来。平均每个题目我看了差不多几十秒,都快速答出来了。回想起来,那时候我似乎在面试官的脸上看到了一抹微笑。常常说面试官的笑绵里藏针,因此不敢掉以轻心,继续沉着应对面试。

接着,面试官问工作地点的意向,家是哪里的。我就一一回答。这时,旁边一直沉默在电脑上记录东西的另一个面试官,突然问我有没有女朋友。我如实回答以前有过,现在没有。之前有听说过这个套路,问意向工作地点是考察稳定性,要是干了几个月不干了,公司投入的招聘资源就会有损失。问有没有女朋友的用意差不多,毕竟异地恋的话,往往其中一方会为另一方作牺牲。 

中兴的综合面大概就这样,最后我问了一下职业发展的上升通道是怎样的。听面试官说如果做技术一步步晋升,做到技术专家,薪资会超过高层管理。中兴的两轮面试结束。

面试完后,有部分细节还是忘记了。有些是跟一起去参加面试的同学事后聊天,一点点回忆起来的。综合面,也就是HR面,我印象深刻的还有这么一些问题。你为什么面试这个岗位?你目前有其他offer吗?做过的项目中,当时有没有遇到特别困难的事,然后如何攻克的?嵌入式软件跟普通软件的区别是什么?你一天的时间,除去上课学习,其它时间是怎么安排的?你期望的薪资是多少?如果你要的有点高,还可能会追问底线薪资是多少?关于谈薪资的问题,我事先专门请教过做 HR 的朋友,大致是要得高一点没关系,如果你特别匹配这个岗位,确实是 HR 看中的人,HR 将替你找研发部门去谈薪资,尽可能达到你的期望。 

先写到这吧,关于面试经历和技巧,还有挺多可以写的,之后有时间再补充。

欢迎关注公众号:

2016-09-22 15:16:52 patkritLee 阅读数 8071

原贴地址:http://www.zhihu.com/question/30034222

·●    inline关键字是做什么用的?inline关键字在什么情况下会展开失败?

      代码长度过大,会导致展开失败。inline类似于将代码直接替换,但是又不是。省去了调用函数的开销。增快了代码的执行效率。

  • sizeof一个空类是多大?为什么?编译器为什么这么做?
  • 1个字节,任何一个实例在内存中都有一个独一无二的地址,为了达到这个目的,编译器往往会给一个空类隐含的加一个字节,这样空类在实例化后在内存得到了独一无二的地址
  • 在这个类中添加一个virtual函数后再sizeof,这时是多大?为什么?
  • 4个字节,有virtual函数,就会对应一个指向虚函数表的vptr指针,指针的大小在32位系统中是4个字节.
  • 将这个类再virtual继承一个其它的空类,这是多大?为什么?
  • 12个字节,这个类本身大小为4个字节,空类的大小为1个字节,加上虚基类偏移量表指针4个指针,又因为要指针对齐(4个字节),故一起12个字节
  • 类有哪几种权限,分别说明?
  • private,protected,public
  • class A :class B{},A是私有继承还是? 私有继承是做什么用的?
  • 默认是私有继承,私有继承后,基类所有成员在派生类中为private成员。私有基类的public成员和protected成员在私有派生类中的访问属性相当于派生类中的私有成员,即派生类的成员函数能访问它们,而在派生类外不能访问它们。私有基类的私有成员在派生类中称为不可访问的成员,只有基类的成员函数可以引用它们。
  • struct S{
  • char a;
  •    int b;
  •    static long c;
  • }
  • 请问sizeof(S)是多少?为什么,有什么好处?
  • 32位系统上,是8个字节,字节对齐,方便寻址操作。
  • 子类的虚函数中能不能调用父类的虚函数,为什么?
  • 有纯虚函数的类能不能实例化?
  • 不能,有纯虚函数的类是抽象类,只能被继承,不能实例化。包含纯虚函是的类派生出来的类都必须重写这个纯虚函数,举个例子,动物可以派生出狗,猫,牛等,动物本身是不可以被实例化的。
  • C++多态有哪几种?
  • 静态多态(函数重载和运算符重载),是在编译的时候,就确定调用函数的类型;动态多态(虚函数实现),在运行的时候,才能确定调用的是哪个函数,动态绑定。运行基类指针指向派生类的对象,并调用派生类的函数。
  • 应用形式上:静多态是发散式的,让相同的实现代码应用于不同的场合。动多态是收敛式的,让不同的实现代码应用于相同的场合。
  • 思维方式上:静多态是泛型式编程风格,它看重的是算法的普适性;动多态是对象式编程风格,它看重的是接口和实现的分离度。
  • C++是怎么实现动态多态的?
  • 虚函数表和指向虚函数表的vptr指针。这个需要注意vptr指针的分布初始化问题,是在构造函数之后,初始化列表和函数体之前完成的。
  • 对象中的VPTR指针什么时候被初始化?

    Vptr指针初始化的过程: 
    1.对象在创建的时,由编译器对VPTR指针进行初始化 
    2.只有当对象的构造完全结束后VPTR的指向才最终确定 
    3.父类对象的VPTR指向父类虚函数表 
    4.子类对象的VPTR指向子类虚函数表

    当定义一个子类对象的时候比较麻烦,因为构造子类对象的时候会首先调用父类的构造函数然后再调用子类的构造函数。当调用父类的构造函数的时候,此时会创建Vptr指针(也可以认为Vptr指针是属于父类的成员,所以在子类中重写虚函数的时候virtual关键字可以省略,因为编译器会识别父类有虚函数,然后就会生成Vptr指针变量),该指针会指向父类的虚函数表;然后再调用子类的构造函数,此时Vptr又被赋值指向子类的虚函数表。 
    (执行父类的构造函数的时候Vptr指针指向的是父类的虚函数表,所以只能执行父类的虚函数) 
    上面的过程是Vptr指针初始化的过程。 
    这是因为这个原因,在构造函数中调用虚函数不能实现多态。

  • 简要说说C++的静态多态?
  • 函数重载和运算符重载,见上上题。
  • C++编译后的函数符号和C语言编译后的函数符号有哪些区别?为什么
  • C++语言支持函数重载,C语言不支持函数重载。函数被C++编译后在库中的名字与C语言的不同。假设某个函数的原型为void func(int x,int y)。该函数被C编译器编译后在库中的名字为_foo,而C++编译器则会产生像_foo_int_int之类的名字。 C++中提供了C连接交换指定符号 extern "C" 解决名字匹配问题。
  • C++智能指针有哪些?auto_ptr和share_ptr有什么区别?他们有什么作用?
  • STL一共给我们提供了四种智能指针:auto_ptr,unique_ptr,shared_ptr和weak_ptr
  • auto_ptr的初衷是用来实现智能指针的,实现内存的自动回收。那么如何实现智能的呢?智能指针最基本的概念是引用计数,也就是智能指针内部有一个计数器,记录了当前内存资源到底有多少指针在引用(可以引用这个资源),当新增加一个可以访问这个资源的引用时,计数器会加1,反之会减去1,当计数器为0时,智能指针会自动释放它所管理的资源。手动申请,自动释放,就是智能的体现。RF:http://www.zhihu.com/question/20368881
  • 有序vector和list二分查找的时间复杂度分别是多少?
  • vector的二分相当于数组的二分,时间复杂度是O(logn),list没办法二分,只能每次从头到尾找,时间复杂度为O(n)。
  • vector自动扩容是按什么大小进行的?
  • 缺省的情况下vector的扩展机制是按2倍大小进行扩展的。在整个大小扩展的过程中,主要的步骤是:1.为需要的新容量分配足够的内存;2.将元素从原来的内存拷贝到新内存中去;3.销毁原来内存中的元素;4.归还原来的内存。
  • 图的搜索有哪几种方式?广搜要怎么做?需要什么额外空间吗
  • DFS和BFS,其中BFS需要开辟内存。
  • 给定一个迷宫,部分坐标是无法通过的,求某两点间最短路径?
  • 广搜+并查集
  • 简述Dijkstra算法的过程,描述一下A Star算法
  • 找出一个无序数组中大小后K个数据?
  • 类似于快速排序的思想,随机选取一个元素,把所有小于等于这个元素的数据移到左边,所有大于这个元素的数据移动到右边。
  • 如果这个元素成了第K个数,直接返回这个数。如果左边的个数大于K,不管右边的数了,在左边重复上面的过程。如果左边的个数等于T<K,不管左边的数了,重复上面的过程,只是K=K-T-1。平均情况下,第一次划分的时间复杂度是O(N),第二次就是O(N/2),总共是O(n+n/2+n/4+...)=O(n)
  • Set的底层实现是什么?红黑树是做什么用的?额外开销是多少?
  • set的底层实现是红黑树。红黑树是一种平衡二叉查找树。结点是红色或黑色。根节点是黑色,每个叶子结点都是黑色,每个红色结点的两个孩子结点都是黑色。从每个叶子到根的所有路径上不能有两个连续的红色结点。从任一结点到其每个叶子的所有路径都包含相同数目的黑色结点。
  • 红海色书和AVL树一样都对插入时间和删除时间以及查找时间提供了最好可能的最坏保障。时间复杂度是O(logn),需要额外的空间也是O(logn)
  • 程序有哪几种链接方式?分别说明区别?哪种效率高?如果一个动态库没有.lib和头文件,要怎么使用里面的函数?
  • 静态链接、装入时动态链接、运行时动态链接。
  • 1.静态链接:在程序运行之前,先将各个目标模块及它们所需的库函数,链接成一个完整的装配模块,以后不再拆开。我们把这种事先进行链接的方式称为静态链接方式。
  • 2.装入时动态链接:这是指将用户源程序编译后所得到的一组目标模块,在装入内存时,采用边装入边链接的链接方式。
  • 3.运行时动态链接:这是指对某些目标模块的链接,是在程序执行中需要该目标模块时,才对它进行的链接。
  • 第三种方式效率较高。还可以节省大量的内存空间。
  • 线程和进程的区别?
  • 线程使用共享资源会出现什么问题?需要怎么做?
  • 如何进行线程同步?在Windows下举例?分用户模式下同步和内核模式下同步 讨论?
  • 用户模式下的方法有:原子操作(例如一个单一的全局变量),临界区。

    内核模式下的方法有:事件,信号量,互斥量。


  • 堆和栈的区别?
  • 线程死锁的几个条件是什么?
  • (1)互斥条件:指线程对所分配的资源进行排他性使用,即在一段时间内某资源只由一个线程占用。
  • (2)请求和保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。
  • (3)不可剥夺条件:进程已获得的资源,在未使用之前,不能强行剥夺。
  • (4)环路等待条件:指在发生死锁时,必然存在一个线程-资源的环形链,即线程集合{P0,P1,,P2,P3,...,Pn}中的P0正在等待P1占用的资源;P1正在等待P2占用的资源,...,Pn正在等待已被P0占用的资源。
  • 给定两个线程,A,B两个锁,举个造成死锁的例子?
  • 多个进程同时占有对方需要的资源而同时请求对方的资源,而它们在得到请求之前不会释放所占有的资源
  • TCP和UDP的区别?分别举例它们的上层协议?
  • TCP是基于连接的,可靠的,偏向于传输大量数据,速度慢,http,ftp,smtp,telnet使用了tcp;UDP是无连接的,不可靠的,偏向于传输少量数据,速度快,dns,tftp,rip,snmp,nfs等使用了udp。
  • 你用过哪些设计模式?
  • 工厂方法和抽象工厂有哪些区别?
  • 工厂方法模式属于对象创建型模式,它定义一个用户创建对象的接口,让子类决定实例化哪一个类。工厂方法模式使一个类的实例化延迟到其子类。具体来说就是一个一个抽象产品类,派生出很多个具体产品类;同时,一个抽象工厂类,派生出多个具体工厂类。而每个具体工厂类只能创建一个具体产品类的实例。
  • 抽象工厂模式也属于对象创建型模式,它提供了一个创建一系列相关或相互依赖对象的接口,而无须制定它们具体的类。具体来说就是在多个抽象产品类中,每个抽象产品类可以派生出多个具体产品类。一个抽象工厂类,可以派生出多个具体工厂类。每个具体工厂类可以创建多个具体产品类的实例。
  • 区别:工厂方法模式只有一个抽象产品类,而抽象工厂模式有多个。工厂方法模式的具体工厂类只能创建一个具体产品类的实例,而抽象工厂模式可以创建多个。
  • 工厂方法:说白了就是一个方法,这个方法是创建具体的产品的,它要求所有的工厂都具有同一个签名的方法,必要时重写该方法;
  • 抽象工厂:不能直接创建产品,只能创建工厂,即抽象工厂创建的产品是工厂。
  • 进程间通信有哪几种方式?在特定环境(比如两个程序需要共享一个文本)下哪种效率最高?Windows下如何进行内存共享?
  • 无名管道,有名管道,信号量,信号,高级管道,消息队列,共享内存,sokect等,共享内存的效率最高,因为它可以直接读写内存,而不需要任何的数据拷贝。windows下主要通过映射机制实现的。共享内存的方式原理就是将一份物理内存映射到不同进程各自的虚拟地址空间中,这样每个进程都可以读取同一份数据,从而实现进程通信。因为是通过内存操作实现通信,因此是一种最搞笑的数据交换方法。
  • 给定1000亿个数据,要找出其中最大的一个值,内存只有1G?
  • 大文件变小文件,然后每个文件里hash_map统计最大的值,然后再归并排序。
  • 给定1000亿个数据,里边有的数据有重复,要求设计一个算法删除重复数据?要求尽量快。
  • 先取模分成小文件,然后每个文件使用hash_map或者trie树。
2018-10-12 19:36:24 xunixianshi123 阅读数 533

一、C++部分

1.1 malloc和new之前的区别以及底层实现

 

 相关文章:

https://blog.csdn.net/nie19940803/article/details/76358673

https://blog.csdn.net/seamanj/article/details/81019920

https://www.cnblogs.com/sinaxyz/archive/2012/08/20/2647631.html

 

1.2 什么是多态

C++多态方式:

(1)静态多态(重载,模板)

是在编译的时候,就确定调用函数的类型。

(2)动态多态(覆盖,虚函数实现)

运行的时候,才确定调用的是哪个函数,动态绑定。运行基类指针指向派生类的对象,并调用派生类的函数。

虚函数实现原理:虚函数表和虚函数指针。

纯虚函数: virtual int fun() = 0;

相关文章:

https://www.cnblogs.com/Allen-rg/p/6927129.html

https://www.cnblogs.com/dormant/p/5223215.html

http://blog.jobbole.com/107432/

https://blog.csdn.net/haoel/article/details/1948051/

 

1.3 虚析构函数的作用

基类定义了虚函数,子类可以重写该函数,当子类重新定义了父类的虚函数后,父类指针根据赋给它的不同的子类指针,动态地调用属于子类的该函数,且这样的函数调用是无法在编译器期间确认的,而是在运行期确认,也叫做迟绑定。

定义一个函数为虚函数,不代表函数为不被实现的函数。

定义他为虚函数是为了允许用基类的指针来调用子类的这个函数。

定义一个函数为纯虚函数,才代表函数没有被实现。

定义纯虚函数是为了实现一个接口,起到一个规范的作用,规范继承这个类的程序员必须实现这个函数。

(1)当派生类的对象从内存中撤销时,一般先调用派生类的析构函数释放该对象中的派生类部分,再调用基类的析构函数释放该对象中的基类部分,从而能够完整的释放该对象内存。

(2)但是,当用基类指针指向了一个派生类对象,即 base *bptr = new child;此时用delete bptr;来撤销bptr 指向的动态存储空间时,只会执行基类的析构函数来释放该堆内存中的基类部分,但是并不会执行派生类的析构函数来释放该堆内存中的派生类部分。此时,就会造成内存泄漏现象。

(3)为了避免此类现象发生,我们将基类的析构函数声明为虚析构函数,这样就解决了上述问题(即先调用派生类的析构函数释放该动态空间中的派生类部分,再调用基类的析构函数释放该动态空间中的基类部分,从而能够完整的释放该堆内存)。

(4)如果将基类的析构函数声明为虚析构函数,那么该基类的所有派生类的析构函数都自动成为虚析构函数。

相关文章:

https://www.cnblogs.com/milanleon/p/6479697.html

https://www.zhihu.com/question/23971699

 

1.4 虚函数的底层的实现

实现原理:虚函数表+虚表指针

关键字:虚函数底层实现机制;虚函数表;虚表指针

编译器处理虚函数的方法是:为每个类对象添加一个隐藏成员,隐藏成员中保存了一个指向函数地址数组的指针,称为虚表指针(vptr),这种数组成为虚函数表(virtual function table, vtbl),即,每个类使用一个虚函数表,每个类对象用一个虚表指针

举个例子:基类对象包含一个虚表指针,指向基类中所有虚函数的地址表。派生类对象也将包含一个虚表指针,指向派生类虚函数表。看下面两种情况:

  • 如果派生类重写了基类的虚方法,该派生类虚函数表将保存重写的虚函数的地址,而不是基类的虚函数地址。
  • 如果基类中的虚方法没有在派生类中重写,那么派生类将继承基类中的虚方法,而且派生类中虚函数表将保存基类中未被重写的虚函数的地址。注意,如果派生类中定义了新的虚方法,则该虚函数的地址也将被添加到派生类虚函数表中。

相关文章:

https://blog.csdn.net/wanghaobo920/article/details/7674631

https://blog.csdn.net/chenchong_219/article/details/41967321

https://www.cnblogs.com/Allen-rg/p/6927319.html

https://blog.csdn.net/m0_37316917/article/details/70143151

https://blog.csdn.net/f1033774377/article/details/80488867

 

1.5 数组和链表的区别

  • 数组静态分配内存,链表动态分配内存;
  • 数组在内存中连续,链表不连续;
  • 数组元素在栈区,链表元素在堆区;
  • 数组利用下标定位,时间复杂度为O(1),链表定位元素时间复杂度O(n);
  • 数组插入或删除元素的时间复杂度O(n),链表的时间复杂度O(1);

相关文章:

https://www.cnblogs.com/janneystory/p/5758958.html

https://blog.csdn.net/snow_wu/article/details/53172721

https://blog.csdn.net/hao10119/article/details/80412472

 

1.6 C++容器迭代器失效

vector迭代器的失效情况: 

1.当插入(push_back)一个元素后,end操作返回的迭代器肯定失效。

2.当插入(push_back)一个元素后,capacity返回值与没有插入元素之前相比有改变,则需要重新加载整个容器,此时begin和end操作返回的迭代器都会失效。 
3.当进行删除操作(erase,pop_back)后,指向删除点的迭代器全部失效;指向删除点后面的元素的迭代器也将全部失效。 
deque迭代器的失效情况: 
1.在deque容器首部或者尾部插入元素不会使得任何迭代器失效。 
2.在其首部或尾部删除元素则只会使指向被删除元素的迭代器失效。 
3.在deque容器的任何其他位置的插入和删除操作将使指向该容器元素的所有迭代器失效。 

List/set/map迭代器的失效情况: 

删除时,指向该删除节点的迭代器失效

list<int> intList; 
list<int>::iterator it = intList.begin(); 
while(it != intList.end()) 

    it = intList.erase(it); 
    …… 

相关文章:

https://www.cnblogs.com/blueoverflow/p/4923523.html

https://blog.csdn.net/lujiandong1/article/details/49872763

https://www.cnblogs.com/Commence/p/7526421.html

https://blog.csdn.net/mr_chenping/article/details/30548507

 

1.7 指针和引用的区别

为了进一步加深大家对指针和引用的区别,下面我从编译的角度来阐述它们之间的区别:

程序在编译时分别将指针和引用添加到符号表上,符号表上记录的是变量名及变量所对应地址。指针变量在符号表上对应的地址值为指针变量的地址值,而引用在符号表上对应的地址值为引用对象的地址值。符号表生成后就不会再改,因此指针可以改变其指向的对象(指针变量中的值可以改),而引用对象则不能修改。

引用与指针的区别

1、指针是一个实体,需要分配内存空间。引用只是变量的别名,不需要分配内存空间。

2、引用在定义的时候必须进行初始化,并且不能够改变。指针在定义的时候不一定要初始化,并且指向的空间可变。(注:不能有引用的值不能为NULL)

3、有多级指针,但是没有多级引用,只能有一级引用。

4、指针和引用的自增运算结果不一样。(指针是指向下一个空间,引用时引用的变量值加1)

5、sizeof 引用得到的是所指向的变量(对象)的大小,而sizeof 指针得到的是指针本身的大小。

6、引用访问一个变量是直接访问,而指针访问一个变量是间接访问。

参考答案:

(1)当引用被创建时,它必须被初始化。而指针则可以在任何时候被初始化。

(2)一旦一个引用被初始化为指向一个对象,它就不能被改变为对另一个对象的引用。而指针则可以在任何时候指向另一个对象。

(3)不可能有NULL引用。必须确保引用是和一块合法的存储单元关联。

进一步解析:

指针和引用都是C++中的基本语法成份,它们既有联系,也有不同之处。

它们都是地址的概念,其中指针指向一块内存,它的内容是所指内存的地址;而引用是某块内存的别名,具体来说,指针是一个变量的地址,引用是一个变量的别名。

但它们的不同之处也很明显,体现在以下方面:

  • 指针是一个实体,而引用仅是个别名;
  • 引用必须被初始化,指针不必;
  • 引用只能在定义时被初始化一次,之后不可变;指针可以改变所指的对象;
  • 可以有const指针,但是没有const引用;
  • 不存在指向空值的引用,但是存在指向空值的指针,即引用不能为空,指针可以为空;
  • “sizeof 引用”得到的是所指向的变量(对象)的大小,而“sizeof 指针”得到的是指针本身(所指向的变量或对象的地址)的大小;
  • 指针和引用的自增(++)运算意义不一样;
  • 程序为指针变量分配内存区域,而引用不需要分配内存区域;
  • 指针可以有多级,但是引用只能是一级,例如int **p是合法的,而 int &&a;是不合法的;
  • 指针和引用作为函数参数进行传递时也不同。用指针传递参数,可以实现对实参进行改变的目的;在将引用作为函数参数进行传递时,实质上传递的是实参本身,而不是实参的一个拷贝,因此对形参的修改其实是对实参的修改。

相关文章:

https://www.cnblogs.com/x_wukong/p/5712345.html

https://blog.csdn.net/zhengqijun_/article/details/54980769

http://chuansong.me/n/2850726

 

1.8 C++中std::function模板和std::bind函数的使用

std::function

它是函数、函数对象、函数指针、和成员函数的包装器,可以容纳任何类型的函数对象,函数指针,引用函数,成员函数的指针。
以统一的方式处理函数、函数对象、函数指针、和成员函数。
允许保存和延迟执行函数。

std::bind绑定器

  • 将函数、成员函数和闭包转成function函数对象
  • 将多元(n>1)函数转成一元函数或者(n-1)元函数。

 

1、定义

bind(F f, T1 t1, T2 t2, ..., TN tN);

具体为:

bind(&要调用的函数,&对象, 要调用函数的参数1,要调用函数的参数2...,_1(bind函数的参数1),_2(bind函数的参数2)...)

注:如果bind的是一个非静态成员函数,第二个参数一定是一个该成员的一个指针,后面才是正常的参数。

2、bind使用形式

(1)bind(&f)()  假设f是一个全局函数,绑定全局函数并调用;

(2)bind (&A::f, A())()  假设A是一个构造函数为空的类,这个形式绑定了类的成员函数,故第二个参数需要传入一个成员(成员静态函数除外);

(3)bind (&A::f, _1)(new A()) 同上,效果是一样的,但是使用了占位符,使得没有固定的的对象,推荐。

注:使用的时候一定要注意指向的是没有this指针的函数(全局函数或静态成员函数),还是有this指针的函数。后面一种必须要用bind()函数,而且要多一个参数,因为静态成员函数与非静态成员函数的参 数表不一样,原型相同的非静态函数比静态成员函数多一个参数,即第一个参数this指针,指向所属的对象,任何非静态成员函数的第一个参数都是this指针。

核心理解绑定类的成员函数。

相关文章:

https://blog.csdn.net/cr2066/article/details/52145719

https://www.cnblogs.com/bencai/p/9124654.html

https://blog.csdn.net/u011602557/article/details/70162609

https://blog.csdn.net/hanzhenling/article/details/45483913

https://blog.csdn.net/yusiguyuan/article/details/37102283

 

1.9 Lambda表达式

声明Lambda表达式

Lambda表达式完整的声明格式如下:

[capture list] (params list) mutable exception-> return type { function body }

各项具体含义如下

  1. capture list:捕获外部变量列表
  2. params list:形参列表
  3. mutable指示符:用来说用是否可以修改捕获的变量
  4. exception:异常设定
  5. return type:返回类型
  6. function body:函数体

相关文章:

https://www.cnblogs.com/DswCnblog/p/5629165.html

https://www.cnblogs.com/langzou/p/5962033.html

 

1.10 C++仿函数(functor)

1 仿函数的概念

仿函数,又名函数对象,是一个定义了operator ()的对象。仿函数的主要功能代码在仿函数类的operator ()体内完成。仿函数的妙处:

(1) 仿函数比一般函数更灵巧,可以用有状态,对于仿函数可以同时拥有两个状态的不同实体。

(2) 每个仿函数都有其型别,通过传递不同型别的仿函数当作template参数给容器,可以构造出型别不同的容器。

(3) 执行速度上,仿函数通常比函数指针快。

很多stl算法有一个函数参数,例如remove_if,for_each等,这个函数可以是普通的全局函数,仿函数,类的成员函数(非static,static可以作为全局函数使用),类的成员函数比较特殊,需要使用适配器函数mem_fun/mem_fun_ref包装才可以。

相关文章:

https://blog.csdn.net/raito__/article/details/51612690

https://www.cnblogs.com/landy126/archive/2013/03/09/2951227.html

 

1.11 static_cast与dynamic_cast

用法:static_cast < type-id > ( exdivssion ) 
该运算符把exdivssion转换为type-id类型,但没有运行时类型检查来保证转换的安全性。它主要有如下几种用法:
①用于类层次结构中基类和子类之间指针或引用的转换。
  进行上行转换(把子类的指针或引用转换成基类表示)是安全的;
  进行下行转换(把基类指针或引用转换成子类表示)时,由于没有动态类型检查,所以是不安全的。
②用于基本数据类型之间的转换,如把int转换成char,把int转换成enum。这种转换的安全性也要开发人员来保证。
③把空指针转换成目标类型的空指针。
④把任何类型的表达式转换成void类型。

注意:static_cast不能转换掉exdivssion的const、volitale、或者__unaligned属性。


3.2 dynamic_cast
用法:dynamic_cast < type-id > ( exdivssion )
该运算符把exdivssion转换成type-id类型的对象。Type-id必须是类的指针、类的引用或者void *;
如果type-id是类指针类型,那么exdivssion也必须是一个指针,如果type-id是一个引用,那么exdivssion也必须是一个引用。

dynamic_cast主要用于类层次间的上行转换和下行转换,还可以用于类之间的交叉转换。
在类层次间进行上行转换时,dynamic_cast和static_cast的效果是一样的;
在进行下行转换时,dynamic_cast具有类型检查的功能,比static_cast更安全。

一、static_cast关键字(编译时类型检查)

用法:static_cast < type-id > ( expression ),该运算符把expression转换为type-id类型,但没有运行时类型检查来保证转换的安全性,它主要有如下几种用法:

(1)用于基本数据类型之间的转换,如把int转换为char,把int转换成enum,但这种转换的安全性需要开发者自己保证(这可以理解为保证数据的精度,即程序员能不能保证自己想要的程序安全),如在把int转换为char时,如果char没有足够的比特位来存放int的值(int>127或int<-127时),那么static_cast所做的只是简单的截断,及简单地把int的低8位复制到char的8位中,并直接抛弃高位。

(2)把空指针转换成目标类型的空指针

(3)把任何类型的表达式类型转换成void类型

(4)用于类层次结构中父类和子类之间指针和引用的转换。

对于以上第(4)点,存在两种形式的转换,即上行转换(子类到父类)和下行转换(父类到子类)。对于static_cast,上行转换时安全的,而下行转换时不安全的,为什么呢?因为static_cast的转换时粗暴的,它仅根据类型转换语句中提供的信息(尖括号中的类型)来进行转换,这种转换方式对于上行转换,由于子类总是包含父类的所有数据成员和函数成员,因此从子类转换到父类的指针对象可以没有任何顾虑的访问其(指父类)的成员。而对于下行转换为什么不安全,是因为static_cast只是在编译时进行类型坚持,没有运行时的类型检查,具体原理在dynamic_cast中说明。

二、dynamic_cast关键字(运行时类型检查)

用法:同static_cast

dynamic_cast主要用于类层次结构中父类和子类之间指针和引用的转换,由于具有运行时类型检查,因此可以保证下行转换的安全性,何为安全性?即转换成功就返回转换后的正确类型指针,如果转换失败,则返回NULL,之所以说static_cast在下行转换时不安全,是因为即使转换失败,它也不返回NULL。

对于上行转换,dynamic_cast和static_cast是一样的。

对于下行转换,说到下行转换,有一点需要了解的是在C++中,一般是可以用父类指针指向一个子类对象,如parent* P1 = new Children(); 但这个指针只能访问父类定义的数据成员和函数,这是C++中的静态联翩,但一般不定义指向父类对象的子类类型指针,如Children* P1 = new parent;这种定义方法不符合生活习惯,在程序设计上也很麻烦。这就解释了也说明了,在上行转换中,static_cast和dynamic_cast效果是一样的,而且都比较安全,因为向上转换的对象一般是指向子类对象的子类类型指针;而在下行转换中,由于可以定义就不同了指向子类对象的父类类型指针,同时static_cast只在编译时进行类型检查,而dynamic_cast是运行时类型检查,则需要视情况而定。

相关文章:

https://blog.csdn.net/hahaha_val/article/details/79384723

https://blog.csdn.net/qq_26849233/article/details/62218385

https://www.cnblogs.com/rednodel/p/5800142.html

http://www.cnblogs.com/jerry19880126/archive/2012/08/14/2638192.html

 

1.12 STL标准库六大组件

STL提供六大组件,彼此可以组合套用:

  1. 容器(Containers):各种数据结构,如:vector、list、deque、set、map。用来存放数据。从实现的角度来看,STL容器是一种class template。
    1. https://www.cnblogs.com/geekpaul/tag/STL/
    2. https://blog.csdn.net/caojunhao123/article/details/11907857
  2. 算法(algorithms):各种常用算法,如:sort、search、copy、erase。从实现的角度来看,STL算法是一种 function template。
  3. 迭代器(iterators):容器与算法之间的胶合剂,是所谓的“泛型指针”。共有五种类型,以及其他衍生变化。从实现的角度来看,迭代器是一种将 operator*、operator->、operator++、operator- - 等指针相关操作进行重载的class template。所有STL容器都有自己专属的迭代器,只有容器本身才知道如何遍历自己的元素。原生指针(native pointer)也是一种迭代器。
    1. https://www.cnblogs.com/wxquare/p/4699429.html
    2. https://www.cnblogs.com/maluning/p/8570717.html
    3. https://www.cnblogs.com/bhlsheji/p/4842539.html

4、 仿函数(functors):行为类似函数,可作为算法的某种策略(policy)。从实现的角度来看,仿函数是一种重载了operator()的class或class template。一般的函数指针也可视为狭义的仿函数。

5、 配接器(adapters);一种用来修饰容器、仿函数、迭代器接口的东西。例如:STL提供的queue 和 stack,虽然看似容器,但其实只能算是一种容器配接器,因为它们的底部完全借助deque,所有操作都由底层的deque供应。改变 functors接口者,称为function adapter;改变 container 接口者,称为container adapter;改变iterator接口者,称为iterator adapter。

  1. https://blog.csdn.net/jakemiao/article/details/24815713
  2. https://www.cnblogs.com/yongpan/p/7966865.html

6、 配置器(allocators):负责空间配置与管理。从实现的角度来看,配置器是一个实现了动态空间配置、空间管理、空间释放的class template。

这六大组件的交互关系:container(容器) 通过 allocator(配置器) 取得数据储存空间,algorithm(算法)通过 iterator(迭代器)存取 container(容器) 内容,functor(仿函数) 可以协助 algorithm(算法) 完成不同的策略变化,adapter(配接器) 可以修饰或套接 functor(仿函数)。

 

二、cocos2dx部分

2.1 Cocos2d-x内存管理机制之release和autorelease

·  autorelease内部是成对的retain()和release();

·  retain对++m_uReference,release对--m_uReference,在retain和release中间++m_uAutoReleaseCount。

·  autorelease自动释放对象资源(自动回收池通常在游戏每一帧的结束时开始release清理),此时对应m_uReference为1,m_uAutoReleaseCount为1,release释放资源。

·  release释放资源,此时如果--m_uReference为0,就释放对象资源,且m_uAutoReleaseCount大于0,就再清自动回收池中占位信息。

相关文章:

https://www.cnblogs.com/steven66/p/5235790.html

https://blog.csdn.net/liaohongwei/article/details/21552785

https://blog.csdn.net/asforasiare/article/details/48667079

https://www.cnblogs.com/gongjiangzhixin/p/5391225.html

https://www.cnblogs.com/sniperHW/p/3789837.html

https://www.cnblogs.com/sniperHW/p/3789837.html

https://www.cnblogs.com/gongjiangzhixin/p/5391225.html

 

三、Python部分

3.1 Python中__get__、__getattr__、__getitem__、__getattribute__之间的差异与联系

相关文章:

https://blog.csdn.net/qianguozheng/article/details/50396776

https://blog.csdn.net/yiifaa/article/details/78068962

 

3.2 Python中 dict.items() dict.iteritems()区别

Python 文档解释:

  • dict.items(): Return a copy of the dictionary’s list of (key, value) pairs.
  • dict.iteritems(): Return an iterator over the dictionary’s (key, value) pairs.

dict.items()返回的是一个完整的列表,而dict.iteritems()返回的是一个生成器(迭代器)。

dict.items()返回列表list的所有列表项,形如这样的二元组list:[(key,value),(key,value),...],dict.iteritems()是generator, yield 2-tuple。相对来说,前者需要花费更多内存空间和时间,但访问某一项的时间较快(KEY)。后者花费很少的空间,通过next()不断取下一个值,但是将花费稍微多的时间来生成下一item。

相关文章:

https://blog.csdn.net/u012542422/article/details/52052877

 

3.3Python中range和xrange的区别

相关文章:

https://www.cnblogs.com/wswang/p/5501565.html

 

3.4 python中继承的作用以及多重继承的执行顺序

相关文章:

https://blog.csdn.net/aydfzmb/article/details/53287780

https://www.jianshu.com/p/71c14e73c9d9

 

3.5  @classmethod 和 @staticmethod的区别

相关文章:

https://www.jb51.net/article/126598.htm

 

3.6 Python迭代对象、迭代器、生成器

  • 容器是一系列元素的集合,str、list、set、dict、file、sockets对象都可以看作是容器,容器都可以被迭代(用在for,while等语句中),因此他们被称为可迭代对象。
  • 可迭代对象实现了__iter__方法,该方法返回一个迭代器对象。
  • 迭代器持有一个内部状态的字段,用于记录下次迭代返回值,它实现了__next__和__iter__方法,迭代器不会一次性把所有元素加载到内存,而是需要的时候才生成返回结果。
  • 生成器是一种特殊的迭代器,它的返回值不是通过return而是用yield。

相关文章:

https://blog.csdn.net/u014745194/article/details/70176117

https://foofish.net/iterators-vs-generators.html

https://www.jb51.net/article/73939.htm

 

 

 

 

【注】:本文主要是将相关的比较有含金量的文章进行筛选并进行归纳以飨大家,版权归各原作者所有。

 

 

 

2020-03-09 18:11:22 qq_37788419 阅读数 446

(2020春招补招,已拿到offer)
抱着投着试试看的心态去的
自己还是不太了解游戏开发,开始面试的时候才知道游戏开发是客户端的JAVA开发,自己做的基本都是服务器向的,人都傻了
框架啊这些都没怎么问
比较重视基础知识,面的也基本都是基础知识
所以面完才发现自己太基础的知识反而一问三不知,回头真得看看- -。

笔试 3.3 具体内容忘记了,比较特别的是没有编程题,全是选择题

一面 3.9 时长27min
没自我介绍也没挖很久项目,就随便问了问
面试官人很好态度也很好,看到是女孩子还开心了一下终于有女孩子来开发岗了了哈哈哈
1.JAVA三大特性
2.final修饰class会有什么效果,能不能被继承
3.有用过static静态关键字吗
4.接口和抽象类有什么区别
5.怎么判断一个对象是否相等
判断相等的三大原则
(提示了一下我对称性,我还是没想起来,现在百度也没查到,不知道是什么
6.有用过位运算吗,提了提但是没有细问
7.有用过集合吗
treemap用过吗,什么特点
arraylist和linkedlist的区别,list排序的方法
8.线程相关
线程有几个状态
一个线程创建完后会进入什么样的状态
线程调用wait()方法进入什么状态
线程调用yeild()方法进入什么状态
9.用过什么线程安全的集合
10.有用过线程池吗,有什么关键的构造参数
11.TCP和UDP的区别
12.有玩过什么游戏
我玩游戏比较广,估计公司应该是做手游的比较多,比较关注手游方面
问了阴阳师这类的游戏是用TCP还是UDP
13.看项目,问了项目里两个自己做的小游戏,负责什么项目,用什么做的
14.提问环节
问了是不是比较重视基础,面试官说JAVA游戏开发比较偏向基础一点,不像服务端
问了平常都用JAVA开发什么类型的游戏
面试官:就是那种一刀9999的游戏
我:?
面试官:开玩笑的哈哈哈平常都开发手游
然后瞎聊了一会,问我为什么不投服务端,因为我投错了还不敢说话哈哈,只好说了半天对客户端特别有兴趣想试试

二面 3.12 时长34min
二面的面试官也是人很好态度也很好,上来还关心了一下我家这边的疫情问题,基本压力不大,一边聊技术一边聊聊天
1.项目,说我的项目做的很多,是否对编程感兴趣
2.为什么选择游戏行业,平常玩什么游戏
(面试官:“哇你玩的可比我多多了”,聊网易游戏,“太肝了我都在上班怎么玩”,哈哈哈哈)
3.在学校的主要课程内容
4.平常有看什么技术书籍
推荐了《JAVA并发实践》,说是必看书
设计模式,网络方面的书籍
java.util包里面的源码
并发容器,线程池方面
推荐我在学校时候多看技术书籍,比较系统化一点
5.Linux使用,会不会写shell脚本
6.项目里使用的框架
7.是否可以提前过来实习
8.离毕业前的时间,学习工作方面的规划,毕业设计的题目和涉及的技术和难点
9.提问环节
提问环节问到的内容好像是面试官很喜欢点,抓着我多讲了十几分钟,不知道的好像是我在面试他(
问了会用JAVA开发什么类型的游戏,会用到什么JAVA技术
回答,分三层,网络层,逻辑层,数据层
先说网络层,于是根据上一面面试官问我的问题现学现卖,问比如TCP、UDP用在什么类型的游戏上
也记录一下自己get到一些还挺好玩的知识:
moba发包频率高,对移动位置精确度要求高,响应快,还要考虑网络情况不太稳定时候的表现,这种用UDP,还要是有序的UDP,保证不丢包
棋牌,比如阴阳师类,操作频率低,选择性比较大,要求低可以用HTTP,TCP的socket连接保持强连接
动作游戏,介于这两种类型之间的,TCP,保证长时间的稳定性
说用的比较多的框架是Netty,可以回去学习一下
再说逻辑层,框架用的不多,但Spring大法还是肯定会用的,比较方便管理一些类,主要考验架构设计能力,模块间的解耦
最后数据层,数据库MySQL,使用hibernate、mybatis自动反射
moba可能用分布式的Redis
还问了数据量大的时候数据库的管理
还是moba可能用分布式的Redis+MySQL
索引用的不多,不便于数据的更新
分库分表,读写分离
面试官:游戏行业比较辛苦一些,要有心理准备。网上那么多人在贴吧骂策划骂程序,不是不想做,是真的做不完,开发难度也不是很低(哈哈哈哈哈

HR面 3.17 时长16min
HR的面试官没有特别多态度表露,
1.毕业以后想来广州发展吗
2.看我项目做了很多,项目参加了比赛还是个人做的,项目里做的游戏相关
为什么项目会选择做游戏类的,项目钟实际上遇到的困难,怎么解决的
3.面试通过的话的到岗时间
4.为什么选择这家公司
5.平时玩什么游戏
6.投递其他公司,有没有拿到offer
7.为什么放弃读研究生
8.对加班的看法
HR说加班很重,有些项目一开始可能前一两年会加班到11点(…
9.对薪资的期望
10.提问环节
提了两个不该对HR问的问题,HR都没做什么回答
问了公司氛围
人傻了问了技术栈,HR叫我去问前面两轮面试官;问福利,HR说通过之后会谈

3.25收到offer,之后沟通offer详情

2019-08-02 13:55:24 shirln 阅读数 12330

推荐阅读:

一。广福地铁站附近某公司

该公司是由VR转型成游戏行业的公司,公司正在研发的是一款二次元卡牌养成游戏,目前有10+人,使用Unity,C#,uLua开发。
公司有8道笔试题:
1.是否熟悉UGUI,Dotween
2.animator是什么
状态机
3.animation动画怎么制作
Animation和Animator 虽然都是控制动画的播放,但是它们的用法和相关语法都是大有不同的。Animation 控制一个动画的播放,而Animator是多个动画之间相互切换,并且Animator 有一个动画控制器,俗称动画状态机。
(一) Animation模块
(1)新建一个对象,并且在对象上附加Animation组件;
(2)选中对象,按快捷键:ctrl+6 打开动画编辑器,新建动画。
(3)播放动画

void Start ()
{
	_anim = GetComponent<Animation>();
	if (_anim != null)
	_anim.Play("Test");

}

(二) Animator模块
(1)新建一个对象,在Unity 编辑器中Window -> Animation 弹出Animation 编辑页面,新建一个动画保存。
(2)双击.controller这个文件打开Aniamtor 编辑器。
(3)直接运行查看效果
4.协程的实现

StartCoroutine(协程的方法名());//调用方法一
StartCoroutine("协程的方法名");//调用方法二
IEnumerator 方法名()
{
	...
    yield return new WaitForSeconds();
}

5.对x个1-100不重复的整数进行排序
6.static,const,readonly getonly的区别
7.接口和抽象类的区别?
8.如何优化代码
(1)for循环得到结果记得break或return;
(2)乘法和除法使用移位操作

二。软件园某公司

笔试题:5页A4纸,但是题目都不是很难,题量也不多,全是简单编程题
C#笔试题(必答题)
1.请简述类和结构体的区别是什么?
2.请简述抽象类和接口的区别是什么?
3.了解设计模式么?请列出您所知道的设计模式的名字。
4.请简述什么是反射?
反射提供了封装程序集、模块和类型的对象(Type 类型)。可以使用反射动态创建类型的实例,将类型绑定到现有对象,或从现有对象获取类型并调用其方法或访问其字段和属性。如果代码中使用了属性,可以利用反射对它们进行访问。
在这里插入图片描述
5.C#中的委托是什么?事件是不是一种委托?
委托可以把一个方法作为参数代入另一个方法。 委托可以理解为指向一个函数的引用。事件是一种特殊的委托
6.try{}里面有一个return语句,那么紧跟在try后的finally{}里的code会不会被执行,如果会,请问在什么时候被执行,在return前还是后?
在这里插入图片描述
7.下面代码什么错?

short sl=1;
sl=sl+1;

下面代码游什么错?

short sl=1;
sl+=1;

没错,会自动强行转换
在这里插入图片描述
8.一列数的规则如下:1,1,2,3,5,8,13,21,34…,求第30位数是多少,用递归算法实现(C#)

public static int Foo(int i)//即定义一个公共静态函数体,输入一个整数(第X位数),返回值;
{
	if (i <= 0) return 0;//预防输入0或负数,输入则返回“0”;
	else if (i > 0 && i <= 2) return 1//如果输入第1位或第2位,则返回“1”(如题);
	else return Foo(i - 1) + Foo(i - 2);//输入其它的数则返回前两个数的值。注意:因为求数列中每一个值都是调用该函数,所以求前两个数的值就又要调用2个这个函数。这就是递归(调用自身)。
}

Foo(30);

在这里插入图片描述
Unity笔试题(必答题)
1.Unity3D从唤醒到销毁有一段生命周期,请列出系统自己调用的几个重要方法。
2.请简述Unity3D项目中预制组件上出现数据丢失的原因可能有哪些?
3.Unity3D中的协程(coroutine)和C#线程之间的区别是什么?
4.编辑器运行时,资源加载的方式有哪些?
(1)通过Resources模块,调用它的load函数:可以直接load并返回某个类型的Object,前提是要把这个资源放在Resource命名的文件夹下,Unity不关有没有场景引用,都会将其全部打入到安装包中。
(2)通过bundle的形式:即将资源打成 asset bundle 放在服务器或本地磁盘,然后使用WWW模块get 下来,然后从这个bundle中load某个object。
(3)通过AssetDatabase.loadasset :这种方式只在editor范围内有效,游戏运行时没有这个函数,它通常是在开发中调试用的
在这里插入图片描述
5.分别解释这几个目录的作用

Plugins:扩展unity功能的插件
Editor:主要用来扩展unity编辑器的功能
Resources:动态加载游戏资源到场景中
StreamingAssets:存放需要保留原格式的资源

6.写出Unity释放资源/内存有关的几个方法
在这里插入图片描述
Lua笔试题(选答题)
1.有一个table t,请简述t.x和t[x]的区别是什么?
在这里插入图片描述
在这里插入图片描述
面试的几个问题:
1.内存优化
参考文章:内存优化之资源管理
2.关闭一个界面的方法:隐藏,销毁,移到屏幕在,设置摄像机的渲染层级
3.卡顿怎么解决,比如背包系统有3000个物品,用户操作会很卡,怎么解决

三。高新世贸中心某公司

这是一家19年成立的公司,一个老板开了几种类型的公司,但都在一个地方上班,里面有两个棋牌项目,一个momo游戏,一个物联网项目,还有人工智能项目。
笔试题大概10道左右,都很基础,只回忆出两道题:
1.OneEnable,Awake,Start,Ppdate,FixedUpdate,LateUpdate的执行顺序,作用,执行次数。
2.移动/旋转的快捷键:W/E

三。环球中心某公司

这是一家2018成立的公司,工作时间:朝九晚九
线上笔试·
1、 OnEnable、Awake、Start运行时的发生顺序?哪些可能在同一个对象周期中反复的发生
      Awake——OnEnable——Start;OnEnable
2、 MeshRender中material和sharedmaterial的区别?
      Sharedmaterial改了材质,使用了sharedmaterial的都会同步改变,但material不会随着同步改变
3、 LOD是什么,优缺点是什么?
      多层次细节,根据模型位置等决定渲染。优点:可以根据需要选择渲染模型;缺点:需要美术提供模型的不同细节。加重了包体负担。
4、 ref参数和out参数是什么?有什么区别?
      Ref使用前必须初始化,但是out不需要。
5、 Unity3d的物理引擎中,有几种施加力的方式,分别描述出来
      Rigibod.AddFoce;Rigibod.AddFoceAtPosition
6、 Ugui,NGUI的渲染方式,如何在两个UI之间插入3d特效
      添加一个专门渲染3d特效的摄像机,或设置sortingOrder。
7、 简述List(vector)与LinkedList(list)的区别
      List(vector):数据结构是数组,查询快,增删快;LinkedList(list):数据结构是链表,查询慢,增删快
8、 C#内存分配原理,垃圾回收函数是什么,如何减少垃圾回收触发?
      GC;用StringBullder代替String。
9、 列举3d渲染管线流程
      顶点着色器——裁剪——片元着色器——显示
10、算法锐角处理
      汽车从a出发,经过中心点o,到达b,当角∠aob为锐角时,需要在程序上插入两个点(偏移为1),从新连接使得每次转弯都不那么尖锐,如图虚线。请分别列举a,b位置的不同情况下偏移点计算
在这里插入图片描述
现场笔试
1.二叉树中序排序算法
2.快速排序算法
面试题
面试
1.连连看连线算法
2.洗牌算法
在这里插入图片描述

四。复城国际某公司

笔试无
面试主要针对你做过的项目提问,问你如何实现,以及该功能的优化
例如·:
1.五粮液活动怎么实现的
2.连连看关卡实现
3.连连看地图生成算法,如果每种出现有一定的权重,又该怎么实现
4.拍一拍成就系统实现,如果有个类实现,类里应该包含哪些。
5.儿童游戏关卡界面实现

四。软件园游戏工厂某公司

笔试无
面试

1.热更新以及框架
tolua
2.代码管理以及差异
svn是直接与服务器进行交互,git是将项目缓存在本地再推送到服务器
3.UDP,TCP区别
(1)基于连接(TCP)与无连接(UDP);
(2)对系统资源的要求(TCP较多,UDP少);
(3)UDP程序结构较简单;
(4)流模式与数据报模式 ;
(5)TCP保证数据正确性,UDP可能丢包,TCP保证数据顺序,UDP不保证。

五。箐蓉汇某创业公司

这个公司来得比较干脆,差不对就是一个上机题,给你一个他们实现的界面效果,让你照着实现。大致是一个滑动列表,实现列表元素的动态生成,初始化相关;然后需要对列表中的元素按等级排列,按品质和等级排列;最后需要实现选中一个元素,显示此元素的相关信息。上机时间(30分钟)
最后会根据你的成品问你一些问题,例如:
1.按品质和等级排列怎么实现?
品质*100+等级进行排列
2.排序算法你知道哪些?冒泡法如何实现?直接上机写
3.如何实现选中一个物体,显示详细信息?
将列表中的元素信息用一个list存储,点击某个元素时传入点击元素的id对应去取list中的信息.

六。天府二街领地环球金融中心A座

直接面试,没问什么技术问题,就稍微打听了一下上家公司的相关情况。

七。川师旁有点学院某3D仿真公司

这个公司主要是做3D仿真课件的,当时看了下岗位需求写的是做过VR或者游戏的优先,就尝试着投了下,其实与想象中差距挺大的。
1.单例模式的作用?
2.抽象是什么?
在继承关系的前提下, 实例化出不同的对象, 这些对象调用相同的方法, 但是却表现出不同的行为, 这就叫做多态
虚方法,抽象类,接口是三种实现多态的手段
3.给你一段C++代码,问你用C#如何实现?
4.大学自己最擅长的科目是什么?