面试题记录
2012年6月13日杭州某网络技术公司
1,空指针自加
int *p; int *pa=NULL; p=pa; p++; 求p的值
这道题考的貌似指针的加法,因为对于空指针比较敏感直接感觉有问题,所以填写出错.
到底如何呢?直接反汇编之
int *p; int *pa=NULL; 010D14F1 mov dword ptr [pa],0 ;指向0x000000000地址 p=pa; 010D14F8 mov eax,dword ptr [pa] ;将pa赋予eax寄存器 010D14FB mov dword ptr [p],eax ;将eax寄存器赋予p指针p=0x00000000 p++; 010D14FE mov eax,dword ptr [p];将p指针赋予eax指针 010D1501 add eax,4 ;对eax寄存器+4(32位操作系统指针大小为4字节)=0x00000004 010D1504 mov dword ptr [p],eax ;所以p=0x00000004
所以最后的结果是p=4
2,逗号运算符的使用
int i,a =1,*b=&a; i=0,a==*b; 求i的值
这里疑惑在于i=0,a==*b;
使用逗号运算符理论上讲是没有问题,不过感觉不会那么简单就回答出错.
i=0,a==*b; 010D14EA mov dword ptr [i],0
发现因为后面的a==*b没有任何意义被编译器优化.而仅对i赋值.
3,逆序bit转换,int bit0与bit31互换,bit1与bit30互换
void ReverseInt(int* pValInt) { int Val = *pValInt; int iLow = 0x0000001; for(int i =0;i<16;i++) { int iValHigh = Val<<i & 0x80000000 ;//获取高位值 int iValLow = Val<<(31-i) &0x80000000; //获取地位移动后的值 if(iValHigh!=iValLow)//相同则不需要互换 { int iMoveLen = i; if(iValHigh !=0x80000000)//如果高位为1,则低位为0,将1左移31-i位,如果高位为0则低位为1左移i位 { iMoveLen = 31-i; } int iMoved = (iLow<<iMoveLen); *pValInt |= iMoved;//或上低位移动后的值 iMoved = iLow<<(31-iMoveLen); *pValInt &=~iMoved;//异或高位移动后的值 } } }
4,一个三位数被9除余7,被7除余5,被5除余3,被3除余2,列出所有三位数
9*7*5 =315(最小公倍数) 313,628,943
面试中经常遇到的关于继承的题
问:构造函数调用虚函数,调用的是本身的虚函数还是基类的虚函数?
答:调用的是自身的虚函数,因为在该阶段已经初始化完成,反汇编如下:
//Drived class Constructor 00C518B5 push eax 00C518B6 lea eax,[ebp-0Ch] 00C518B9 mov dword ptr fs:[00000000h],eax 00C518BF mov dword ptr [ebp-14h],ecx 00C518C2 mov ecx,dword ptr [ebp-14h] 00C518C5 call VirtualConstructor::VirtualConstructor (0C51073h) 00C518CA mov dword ptr [ebp-4],0 00C518D1 mov eax,dword ptr [ebp-14h] 00C518D4 mov dword ptr [eax],offset VirtualDrivedConstructor::`vftable' (0C5677Ch) ;已经获取到继承类的虚表,相应的就可以找到对应的虚函数地址 Init(); 00C518DA mov ecx,dword ptr [ebp-14h] 00C518DD call VirtualDrivedConstructor::Init (0C5103Ch)