程序员专业技能评比测试
说明:
本试卷分为两部分。第一部分为基本必答题目,所有程序员要求尽力回答。第二部分为选答题目,根据能力和职位进行选择回答即可。
本试卷题目请提供详细解题思路,仅有答案,即使正确也将视为未答。
本试卷题目答案请写在专用答题纸上。
本试卷内除特殊说明外,硬件环境均为Inter Core2 E5200 2.5G/2M/双核,Nvidia 9800GT。客户端软件环境为 MS DX9.0C 2005Oct. 平台环境为 WindowsXP SP2,服务器软件环境为MS SQLServer2003企业版,平台环境为WindowsServer2000, IDE编译环境均为VC++2003.
答题时间: 180分钟(建议基础题目100分钟 + 选答题 80 分钟)请注意时间控制。
答题人姓名:_________________ 职位:_________________ 答题日期:_________________
----------------------------------------------------------------------------------------------------------------------------------------
一:基础题目
1:现有2000个橘子,11个包装箱,现应当如何对橘子进行分配装箱,才能使客户要购买1-2000内随意个橘子,都能按多个整箱顺利卖给他?(不是智力急转弯,假设橘子装箱后不可以再拆箱)
2:用变量a给出下面的定义:(前两题给出例子)
1) 一个整数 (答案例如: int a; )
2) 一个指向整形的指针 (答案例如: int* a; )
3) 一个指向指针的指针,它指向的指针是指向一个整形。
4)一个有10个整形的数组。
5)一个10个指针的数组,该指针是指向一个整形数的。
6)一个指向有10个整形数数组的指针。
7)一个指向函数的指针,该函数有一个整形的参数,并且返回一个整形。
8)一个有10个指针的数组,该指针指向一个函数,该函数有一个整形的参数,并且返回一个整形。
3:请查看下列代码段:(假设包含库,头文件,命名空间均正确)
int main() { char cArray[128]; char c = 128; printf("%d/n", c); printf("%d/n", sizeof(cArray)); printf("%d/n", strlen(cArray)); return 0; } |
这段代码会输出什么?
4:请看下列代码段:(假设包含库,头文件,命名空间均正确)
这段代码会输出什么?
struct SFKStruct1 { char a:1; int b:5; char c; short d; int e; }; struct SFKStruct2 { int a:1; char c; int b:5; short d; int e; }; int main() { cout << sizeof(SFKStruct1) << endl; cout << sizeof(SFKStruct2) << endl;
return 0; } |
5:请查看下列代码段,(假设包含库,头文件,命名空间均正确)
class CFKTest { public: CFKTest ( void ) { ++ ms_nNum; } ~ CFKTest ( void ) { -- ms_nNum; }
int GetNum( void ) const { return ms_nNum; } private: static int ms_nNum; };
int main( int argc,char *argv[] ) { CFKTest *tmp = new CFKTest (); delete tmp; std::cout << tmp->GetNum() << std::endl;
CFKTest* tmp2 = (CFKTest*)malloc( sizeof(CFKTest) ); tmp2 = new CFKTest(); free( tmp2 ); std::cout << tmp2->GetNum() << std::endl;
CFKTest* tmp3 = (CFKTest*)malloc( sizeof(CFKTest) ); tmp3 = new CFKTest(); free( tmp3 ); std::cout << tmp3->GetNum() << std::endl;
return 0; } |
假设包含库正确,请:
1:添加代码使 ms_nNum 初始化为0。
2:若正确初始化 ms_nNum 为0,该程序是否可以正常运行?若崩溃,原因为什么?若正确执行,则输出什么?
6:请查看下列代码段。(假设包含库,头文件,命名空间均正确,假设main函数正确)
class FKTest1 { public: int GetInt( void ) const { return 0; } }; class FKTest2 : public FKTest1 { public: static int GetInt( void ) const { return 1; } }; |
这段代码是否可通过编译?是否可通过链接?若不行,请说明原因。
7:现在需要实现一个可变参数的函数,该函数应声明为哪种调用规范。(提示:__stdcall,
__cdecl, __fastcall )为什么?
8:请谈一下你对编译阶段的静态断言的理解,它的原理和意义是?若有可能,请编写一份静态断言代码?(若有余力,可考虑编写一份有正确错误提示的静态断言代码。提示:可考虑模板特化)
9:请查看下列代码段
class CFKEmptyClientApp { CFKEmptyClientApp() : m_bWakeFlag( false ){} ~CFKEmptyClientApp(){} public: void Wait() { while( !m_bWakeFlag ) { Sleep( 1000 ); } Break; } void WakeUp() { m_bWakeFlag = true; } private: bool m_bWakeFlag; }; |
该段代码设计意图是,主线程持续Wait,每一秒进行一次检查,若flag被其他线程唤醒,则继续执行其他,否则继续每一秒一次的检查。其中WakeUp()函数是提供给其他线程调用的。
问题:1:当前代码是否有安全隐患?若有,则隐患是?
2:如何最小性能代价避免该隐患?(提示:考虑C++关键字)
10:请查看下段代码:(假设包含库,头文件,命名空间均正确)
int main(void) { int i; int name[10]; for(i=0;i<=12;i++) name[i]=0; printf("done!"); return 0; } |
不考虑多线程的情况下,若上述代码在VC2003下,VC2005下分别执行,结果会是什么情况?原因为什么?
11:请回答下列问题
1) STL内deque是否是大段的连续内存空间存储?若是,请说明它与STL的vector区别。若不是,请额外讲述其内存空间存储原理。
2)STL中set 和 map 区别是? set 和 multiset 区别不同点是?
3)STL中,已知一个数据,需要对set, vector, list 三个容器进行查找它是否存在,哪个最快?为什么?(容器大小均为10000元素)
4) 这段代码是否正确?若错误,请指明错误原因并给出修改建议。
vector<bool> v;
bool *pb = &v[0];
12:请回答下列问题:
1) 二叉树中深度优先搜索和广度优先搜索原理是?若进行非递归遍历,则通常进行搜索时辅助使用的数据结构为?
2) 二叉树先序遍历,后序遍历,层次遍历的概念区别为?
13:请说明你所了解的内部排序方式有几种,分别描述其基本原理,稳定性,平均时间复杂度。(基本原理说明,可使用伪代码)
对一个100个数据单元有序的数组,在不要求稳定性的前提下,仅考虑时间复杂度,不考虑空间代价的前提下,哪种排序最合适?
对一个10000个数据单元无序的数组,在不要求稳定性的前提下,仅考虑时间复杂度,不考虑空间代价的前提下,哪种排序最合适?
14:请回答下列问题:
1) 临界区和互斥量的区别有哪些?各自优缺点和适用情况是?
2) 自旋锁和信号量的区别是什么?各自优缺点和适用情况是?
3) 多线程下,Singleton单件模式和静态变量是否有不安全性,可能引发的结果是?如何解决该安全问题?
4) WaitForSingleObject和WaitForMultipleObjects函数对Windows特定内核对象有副作用,其副作用是?其中,WaitForMultipleObjects函数中的bWaitAll参数的意义是?
15:请回答下列问题:(均是在WindowsNT系统下)
1) C++中内存管理的三种方式?C++中内存的五种分区为?各自主要功能?
2) VC7.1, DEBUG模式下,请问什么情况时,内存监视发现栈内存均为以下值,0xfdfdfdfd…, 0xcdcdcdcd…, 0xdddddddd….(注,分别是三种情况,请逐个说明)
3) Windows内存碎片是如何产生的?如何减少内存碎片?
4) VC7.1,DEBUG模式下,编写的一个程序运行时IDE输出窗口输出下段提示,你从提示中可以得到哪些讯息?
c:/FKTest/FKTestCRTMemory20101125.cpp(552) : {44} normal block at 0x00441BD0, 33 bytes long.
Data: < C > 00 43 00 CD CD CD CD CD CD CD CD CD CD CD CD CD
5) 内存池,对象池,线程池各自的基本实现方式和意义是?
16:设计模式根据功能分为哪三大类?下面三段话分别说明的是哪三种模式,分别属于哪类?
1)_____该模式注重统一接口,将“一对多”的关系转化为“一对一”的关系,屏蔽对象容器内部实现结构,实现对象和对象容器使用的一致性。将对象组合成树形结构以表示部分整体的关系,该模式使得用户对单个对象和组合对象的使用具有一致性。
2)_____该模式用原型实例指定创建对象的种类,并且通过拷贝这些原型来创建新的对象。它不需要实例化对象。
3)_____该模式将一个请求封装为一个对象,从而使你可以用不同的请求对客户进行参数化,对请求排队和记录请求日志,以及支持可撤销的操作。 注重将请求封装为对象,支持请求的变化,通过将一组行为抽象为对象,实现行为请求者和行为实现者之间的解耦。
二:选做题网络部分
1:请回答下列问题:
1) OSI的7层网络模型中,IOCP/Epoll等I/O网络模型属于哪一层?将消息包分割为微小的数据帧的操作在哪一层?TCP协议是哪一层的协议服务?
2) 服务器网络开发中基于TCP协议的服务器应用程序经常使用到环形缓冲区,请问它的优势是什么?若你使用过环形缓冲,那么你认为他是FIFO还是FILO?
2:请回答下列问题:
1) WindowsI/O模型分为几种,请简述它的实现特点,优势和不足。
2) 阻塞模式和非阻塞模式的概念,优势,不足。
3) 对于常规MMORPG客户端和服务器建议使用哪种I/O模型,为什么?
三:选做题数据库部分
1:
有位数据库工程师在抱怨他的游戏数据库压力很大,说了以下一段话:“我们游戏啊,用的是SQLServer2000的数据库,所有GameServer就一个DB,偏偏策划又很复杂,一个角色记录平均都达到了50K大小,光是任务信息这个varchar类型字段就占了10K,我们为提高并行效率,GameServer为每个用户创建了一个DB的链接,上次测试时候,几十个GS都爆满,算起来一起能有30W人在线,你想啊,30W乘以50K那就是15G内存占用啦!DB服务器压力好大啊!”
现假设,带下划线的话均为真,请从技术上分析他说谎和错误分析有几处?请指出错误原因。另外,作为数据库工程师,他少考虑了什么问题?
2:
若现有一个需求,“一个帮会允许有大量玩家,但是,由于玩法需求,又允许一个玩家加入大量帮会。通过玩家查找他所在的帮会列表以及通过帮会查找其容纳的成员列表 这两个操作都是很频繁的”这样的需求情况下,你需要定几张表?各自关系和主键如何?为什么?
3:请比较说明ODBC和ADO的优缺点。
四:选做题Lua脚本部分
1:请查看下列代码
max_i=200 function loopme(i) print(loopme(0)) ----------------------------------------------------- max_i=20000 function loopme(i) print(loopme(0)) |
已知第一段代码执行消耗时间为287ms,而第二段代码执行消耗时间为4.92ms。请问为什么?
2:请查看下列代码
-- 文件名:FKLua.lua -- 说明:对称协程 FKLua = {} FKLua.main = function() end FKLua.current = FKLua.main -- 创建一个新的协程 function FKLua.create(f) return coroutine.wrap ( function(val) return nil,f(val) end ) end -- 把控制权及指定的数据val传给协程k function FKLua.transfer(k,val) if FKLua.current ~= FKLua.main then return coroutine.yield(k,val) else -- 控制权分派循环 while k do FKLua.current = k if k == FKLua.main then return val end k,val = k(val) end error("分派控制权失败!") end end | require("FKLua.lua")
function foo1(n) print("1: foo1 接收到数据"..n) n = FKLua.transfer(foo2,n + 10) print("2: foo1 接收到数据"..n) n = FKLua.transfer(FKLua.main,n + 10) print("3: foo1 接收到数据"..n) FKLua.transfer(FKLua.main,n + 10) end
function foo2(n) print("1: foo2 接收到数据"..n) n = FKLua.transfer(FKLua.main,n + 10) print("2: foo2 接收到数据"..n) FKLua.transfer(foo1,n + 10) end
function main() foo1 = FKLua.create(foo1) foo2 = FKLua.create(foo2) local n = FKLua.transfer(foo1,0) print("1: 主线程接受到数据"..n) n = FKLua.transfer(foo2,n + 10) print("2: 主线程接收到数据 "..n) n = FKLua.transfer(foo1,n + 10) print("3: 主线程接收到数据 "..n) end
--把main设为主函数(协程) FKLua.main = main --将FKLua.main设为当前协程 FKLua.current = FKLua.main --开始执行主函数(协程) FKLua.main() |
请问,会输出什么?简述协程和线程最大的不同有哪些?
五:选做题客户端引擎凌杂题部分
1:现需要开发一款即时性很高的游戏,玩家每秒DPS可达200次,此时你会选择Dinput还是Windows消息机制做为键盘鼠标响应?为什么?Windows里双击事件是WM_DBLCLK, Dinput里鼠标左键双击的消息是?
2:包围盒碰撞判断中经常使用OBB和AABB,他们分别的优缺点和实现方式为?
3:A*算法中,核心估价函数表示为 f(n) = g(n) + h(n),请简单解释其中 f(n), g(n), h(n) 的意义?为提高性能,其中哪个函数是可以省略的?
六:选作题逻辑模块部分
1:你所经历的MMORPG项目中,服务器是基于四叉树管理还是基于地图格子管理?你认为为什么不基于BSP或者OctTree进行管理?若为四叉树管理,则最小单元是多大?若为地图格子管理,则最小单元格为多大?请说明为什么选择这样的Size。客户端静态场景可视范围为多大,动态对象可视范围为多大,同样,请说明为什么选择这样的一个Size。
2:你是否编写过角色的行为状态机,现在请你设计一个可扩展的高性能的角色行为状态机。
请用图示表示核心类的静态关系,要求:类内有核心函数,函数名意义明确。
请用伪代码表示核心函数动态调用关系。
补充说明:
1) 英文不好的同学可用中文定义类名和函数名。不要求必须规范使用UML图规则。
2) 建议先明确 行为 和 状态 之间的定义和关系。
3) 客户端程序员请设计客户端的主角行为状态机,要求:角色有移动,攻击,死亡,闲置的状态。假设引擎提供接口为OnPlayAct( char* p_szActName ); 播放完毕后有回调函数OnActEnd();有查询接口bool IsPlayingAct( const char* p_szActName );
4) 服务器程序员请设计一个怪物AI状态机,有限状态机即可,要求怪物可以有以下行为功能:移动,攻击,死亡,闲置。
七:选作题图形渲染模块部分
1:D3D9中创建资源时,我们可指定下列存储标志D3DPOOL_DEFAULT,D3DPOOL_MANAGED, D3DPOOL_SYSTEMMEM, D3DPOOL_SCRATCH ,各自意义和区别是什么,请简要概述。提示:D3D RunningTime的内存分为几种,各自由谁管理。
2:请按照顺序说明D3D固定渲染流水线管道9个步骤和基本功能。
3:我们知道大部分常规渲染引擎同时最多支持8个动态光源,并且,即使在8个光源内,光源数量越多,效率也会很大幅度的下降,你认为是为什么原因?使用延迟光照技术可以非常完美的解决这个问题,请简述该技术的实现方式。
4:通常我们游戏中生成阴影的方式有哪两种?它们各自的实现方式,优缺点,效率影响因素是?动态软阴影的实现使用的是哪种阴影实现方式?它额外做了什么?
5:下面的Shader实现了什么功能?
// PixelShaderCode //---------------------------------------------------------- sampler m_pTerrainTexture0; sampler m_pTerrainTexture1; struct PS_INPUT { loat4 color : COLOR0; float3 tex0 : TEXCOORD0; float3 tex1 : TEXCOORD1; }; struct PS_OUTPUT { vector diffuse : COLOR0; }; PS_OUTPUT Main(PS_INPUT input) { PS_OUTPUT output = (PS_OUTPUT)0; vector b = tex2D(m_pTerrainTexture0, input.tex0.xy); vector s = tex2D(m_pTerrainTexture1, input.tex1.xy); vector c = input.tex0.z * b + input.tex1.z * s; c= c * input.color; output.diffuse = c; return output; }
| // VerterShaderCode //------------------------------------------ matrix ViewMatrix; matrix ViewProjMatrix; vector AmbientMtrl; vector DiffuseMtrl; vector LightDirection; vector DiffuseLightIntensity = {1.0f, 1.0f, 1.0f, 1.0f}; vector AmbientLightIntensity = {1.0f, 1.0f, 1.0f, 1.0f}; struct VS_INPUT { vector position : POSITION; vector normal : NORMAL; float3 tex0 : TEXCOORD0; float3 tex1 : TEXCOORD1; }; struct VS_OUTPUT { vector position : POSITION; vector diffuse : COLOR; float3 tex0 : TEXCOORD0; float3 tex1 : TEXCOORD1; }; VS_OUTPUT Main(VS_INPUT input) { VS_OUTPUT output = (VS_OUTPUT)0; output.position = mul(input.position, ViewProjMatrix); float3 LightDir = mul(LightDirection, ViewMatrix); float3 normal = mul(input.normal.xyz, iewMatrix); float s = dot(LightDir, normal); if( s < 0.0f ) s = 0.0f; output.diffuse = (AmbientMtrl * AmbientLightIntensity) + (s * (DiffuseLightIntensity * DiffuseMtrl)); output.tex0 = input.tex0; output.tex1 = input.tex1; return output; }
|