晚上又去面了一次搜狐,另一个职位的一面,照旧也写写总结吧。
题跟上一次的差不多,选择题稍微多了几道。这一次跟面试官聊起来才发现上一次做错了几道。
一、一个算错的问题。
union U { int i; char ch[2]; }; int _tmain(int argc, _TCHAR* argv[]) { U u; u.i = 0; u.ch[0] = 10; u.ch[1] = 1; printf("%d", u.i); return 0; }我算出的答案是0x1A,坑啊,这是个char,后面的A应该写成0A,也就是说结果是0x10A = 266。
中间考虑了大小端模式。拿一个int指针来说,指针指向的都是元素的低地址。 大端是高位在低地址,小端是低位在低地址。 也就是说,这个指针所指向的第一个字节是数字的高有效位那么它就是大端,如果是低有效位它就是小端。
一般的电脑都是小端模式,所以,这个数字应该反过来读0x010A。
二、指针定义的问题
struct TEST { int b; }; int _tmain(int argc, _TCHAR* argv[]) { TEST *a, b; a = NULL; b = a; printf("%d", b->b); return 0; }这一题有个陷阱,是在定义变量的地方,第一个是指针a,第二个不是指针。所以,这段代码会编译报错,而不是运行报错。
三、实现strcpy,考虑内存区重叠的问题。
其实,它如果重叠了,就算覆盖了,可能导致源字符串被破坏。不过,我在实现的时候没有想那么多。
贴上一段wine里面memmove的代码,这段代码可以做为参考吧。
void *memmove( void *dest, const void *source, size_t len ) { register char *dst = dest; register const char *src = source; /* Use memcpy if not overlapping */ if ((dst + len <= src) || (src + len <= dst)) { memcpy( dst, src, len ); } /* Otherwise do it the hard way (FIXME: could do better than this) */ else if (dst < src) { while (len--) *dst++ = *src++; } else { dst += len - 1; src += len - 1; while (len--) *dst-- = *src--; } return dest; }如果二者不重叠,简单的调用memcpy。重叠的情况下,dst如果在前,正向拷贝;dst如果在后,反向拷贝。
四、内核对象和进程间通信可以用哪些对象
内核对象包含访问令牌、事件、文件、文件映射、IO完成端口、作业对象、邮槽、互斥体、管道、进程、线程、可等待计时器和线程池。
用户态线程同步方式:Interlocked函数、临界区、Slim读写锁、条件变量。
内核态线程同步方式:事件、可等待计时器、信号量、互斥体。
今天就写这么多吧,看来还需要再补补Windows核心编程。