UT斯达康笔试面试经验
一篇来自网友的UT斯达康笔试面试经验,看完后受益良多……
7月17号去的UTS软件部门面试,至今已半月,很想把心得写出来大家共享,今天终于抽出空来了。
一.compile和link哪个先哪个后,生成文件的格式分别是什么?.
二.字符串比较是哪个函数,两个串比较后大于和小于的返回值分别是什么?
原型:extern int strcmp(char *s1,char * s2);
用法:#include
功能:比较字符串s1和s2。
说明: 当s1 当s1=s2时,返回值=0
当s1>s2时,返回值>0
举例: // strcmp.c
#include
#include
main()
{
char *s1="Hello, Programmers!";
char *s2="Hello, programmers!";
int r;
clrscr();
r=strcmp(s1,s2);
if(!r)
printf("s1 and s2 are identical");
else
if(r<0)
printf("s1 less than s2");
else
printf("s1 greater than s2");
getchar();
return 0;
}
三.在用VC编译时debug和release两种编译指令有啥区别?
relese版和debug不同在于:
debug版使用于调试的,它关闭了大多数代码优化,并回自动初始化开辟出来的内存(置为0xcc),并携带调试信息,但是执行起来比较慢。
release版是最终给客户的,开启了代码优化,不会自动初始化内存,一般不携带调试信息执行比较快。
debug和release还有一个区别,呵呵,编译成的exe,dll,lib文件的大小差太多了。
如果debug下正确,release版本出错,原因可能很多,毕竟debug多做了很多事。建议你用写log到文件的方法除错。
常见问题:
1.变量未初始化。
下面的程序在debug中运行的很好。
thing *search(thing , *something)
{
BOOL found;
for(int i = 0; i < whatever.GetSize(); i++)
{
if(whatever->field == something->field)
{ /* found it */
found = TRUE;
break;
} /* found it */
}
if(found)
return whatever;
else
return NULL;
}
而在release中却不行,因为debug中会自动给变量初始化found=FALSE,而在release版中则不会。所以尽可能的给变量、类或结构初始化。
2. 数据溢出的问题
如:char buffer[10];
int counter;
lstrcpy(buffer, "abcdefghik");
在debug版中buffer的NULL覆盖了counter的高位,但是除非counter>16M,什么问题也没有。但是在release版中,counter可能被放在寄存器中,这样NULL就覆盖了buffer下面的空间,可能就是函数的返回地址,这将导致ACCESS ERROR。
3. DEBUG版和RELEASE版的内存分配方式是不同的。
如果你在DEBUG版中申请 ele为 6*sizeof(DWORD)=24bytes,实际上分配给你的是32bytes(debug版以32bytes为单位分配),而在release版,分配给你的就是24bytes(release版以8bytes为单位),所以在debug版中如果你写ele[6],可能不会有什么问题,而在release版中,就有ACCESS VIOLATE。
四.野指针的问题:
在指针P用完后执行了一句free(p);为什么还要加一句 p=null; ?
“野指针”不是NULL指针,是指向“垃圾”内存的指针。人们一般不会错用NULL指针,因为用if语句很容易判断。但是“野指针”是很危险的,if语句对它不起作用。野指针的成因主要有两种:
1、指针变量没有被初始化。任何指针变量刚被创建时不会自动成为NULL指针,它的缺省值是随机的,它会乱指一气。所以,指针变量在创建的同时应当被初始化,要么将指针设置为NULL,要么让它指向合法的内存。
2、指针p被free或者delete之后,没有置为NULL,让人误以为p是个合法的指针。别看free和delete的名字恶狠狠的(尤其是delete),它们只是把指针所指的内存给释放掉,但并没有把指针本身干掉。
通常避免野指针的办法是正确的使用指针:
1.声明一个pointer的时候注意初始化为null
int* pInt = NULL;
2.分配完内存以后注意ASSERT
pInt = new int[num];
ASSERT(pInt != NULL);
3.删除时候注意用对操作符
对于new int类型的,用delete
对于new int[]类型的,用delete []
4.删除完毕以后记得给他null地址
delete [] pInt;
pInt = NULL;
5.记住,谁分配的谁回收,不要再一个函数里面分配local pointer,送到另外一个函数去delete
6.返回local address是非常危险的,如必须这样做,请写注释到程序里面,免得忘记
五.最后一个问题,也是压死我这个骆驼的最后一根稻草:二分查找法的程序能不能上机写出来?
看到题目我第一反应是:太简单了吧,这样子搞那我岂不是想不留在这里做事都很难了,简直不给我选择的机会嘛,于是我很爽快的答应了,2分钟之内写出程序,要知道我面试前做了三天的准备,这个程序可是谭浩强的书中最经典的程序之一,我背都背下来了。
bool binary_search(int* arr, int key, int n)
{
int low = 0;
int high = n - 1;
int mid;
while (low <= high)
{
mid = (high + low) / 2;
if (arr[mid] > k)
high = mid - 1;
else if (arr[mid] < k)
low = mid + 1;
else
return ture;
}
return false;
}
面试经历:
写完程序后,我匆匆的试着执行了一下,看着屏幕上显示的OK,心中揣着的那块大石头也就提前登陆了。 我叫来面官,原以为他应该看两眼就完事了,没想到那家伙居然郑重其事的坐下来一板一眼的输入一长串代码去执行,看着屏幕上显示的一行又一行"No Found!",我感觉有点不妙。
面官很和蔼的让我再调试下,就起身忙他的去了,而我在调试了3,4分钟后还是没有找到问题的情况下彻底傻眼了,我根本就没做这个预案,而且我敢对天发誓,我写的程序绝对和书上就差几个字符不一样。
就在这万分危急的时刻,那家伙居然跑过来站在我的身后假惺惺的做指点。他的一句:“你的“TURE”写错了!”基本上是扒掉了我身上的最后一块遮羞布。我在把函数的返回值和变量定义改了几个回合之后彻底缴械了。
但是我的缴械不是迫于他的淫威,而是出于我的过分自信。在我看来我已经表现的很好了(当时确实是这么认为的),因为我以往写的代码,一调试往往都是几十行的错误信息,今天写的这段从第一遍调试起就一直没有语法错误,我已经创造了历史,更何况结果已经出来了,只是有那么一点点小小的错误嘛,表现太完美了也不太好吧??
然而我得到的却是完全出乎意料的答复,而且这个答复来的那么快。“很遗憾,我们不能录用你!”,面官还是那么和蔼,而且还在后面加了一句我怀疑是出于安慰才说的话。“要是你这个程序调出来了可能我们就会录用你了,但是我们毕竟有个标准。”
他在最后还是给了我一个理由,这个理由成了我此行最大的收获,这个理由让我至今都觉得我那次面试有重大意义。“其实程序是调出来的,不是写出来的。我刚刚看了你调试的过程,你没有使用断点,也没有使用单步运行,这些是程序调试最重要的手段。”
这个理由让我输的'心服口服,让我至今任仍有很多感触。今天我愿把我的感触拿出来与大家分享:
1.学校和公司对我们的要求不一样,评价的标准也不一样。在学校,我上面的那段代码可能是满分,我也有过很多次这样的经历。纸上写个程序,拿眼睛看看,没有问题,交上去就完成任务了。但是在公司,他们只看你代码执行的结果和执行效率,根本不关心你用多久写出来,你写的过程是一帆风顺还是错误累累,只要结果和预期值不一样,哪怕你的代码和标准答案只差一个字符,也是白搭。其实,在哪以后的代码编写中我也很多次发现,程序没法得到正确结果经常就是一个非常非常小的错误,小的可以忽略。
2.“纸上得来终须浅”,软件学习,其实书看不看,看多少,根本没那么重要,重要的是自己能动手写出来而且正确执行。在程序的调试过程中最好不要忽略任何一个细小的错误,一切以能否得到正确的执行结果为唯一判断准则。所谓的经典著作上的经典程序,很多时候执行起来是通不过的,不是我贬低那些个大师,而是程序是要结合一定的环境才能谈论结果和效率的,不同的编译工具对于代码的执行影响很大。
3.要重视基础,在斯达康之后,我还去过阿里巴巴和诺基亚西门子杭州研发中心(NSN)做笔试题,一个共同的特点都是很注重基础,我事先着重准备过的链表的操作以及析构函数等等很多东西根本没涉及到。都是基础题目,只不过选取的考点都很独特,都是平时容易被我们忽略的细节,所以不容小觑。很多人做完都觉得很简单,知道面试名单里面没有自己时才清醒,因为这种大公司笔试名单基本上都是完全按照笔试分数高低来确定的。