2013.9.28微软笔试题-真题分析 链表大题 mircosoft

1.多进程,多线程。

程下,每个进程都有自己的独立地址空间,进程间的数据空间也相互独立。

线程下,同一进程内的线程共享进程的地址空间,一个线程的数据可以直接提供给其他线程使用。

多进程和多线程都可能发生死锁。线程之间通信可以直接进行,进程之间通信需要一定的通信方式。


2. TCP要进行握手,不能组播, 广播,多播只适用于非连接的UDP。


3. DLL动态链接库

当进程在载入DLL时,操作系统自动把DLL地址映射到该进程的私有空间,也就是进程的虚拟地址空间,而且也复制该DLL的全局数据一份拷贝到该进程空间。(其实在物理内存中,多进程载入DLL时,DLL的代码段实际上是只加载了一次,只是将物理地址映射到了各个调用它的进程的虚拟地址空间中,而全局数据会在每个进程都分别加载)。也就是说每个进程所拥有的相同的DLL的全局数据,它们的名称相同,但其值却并不一定是相同的,而且是互不干涉的


4. 程序的段分布

BSS段(bss segment)通常是指用来存放程序中未初始化的全局变量的一块内存区域。BSS是英文Block Started by Symbol的简称。BSS段属于静态内存分配。

数据段(data segment)通常是指用来存放程序中已初始化的全局变量的一块内存区域。数据段属于静态内存分配。

代码段(code segment/text segment)通常是指用来存放程序执行代码的一块内存区域。这部分区域的大小在程序运行前就已经确定,并且内存区域通常属于只读。在代码段中,也有可能包含一些只读的常数变量,例如字符串常量等。

堆(Heap)是用于存放进程运行中被动态分配的内存段,malloc/free。

栈(Stack), 是用户存放程序临时创建的局部变量,也就是说我们函数括弧“{}”中定义的变量(但不包括static声明的变量,static意味着在数据段中存放变量)。除此以外,在函数被调用时,其参数也会被压入发起调用的进程栈中,并且待到调用结束后,函数的返回值也会被存放回栈中。


5. 数据库连接

内连接:把两个表中数据对应的数据查出来 
外连接:以某个表为基础把对应数据查出来
全连接是以多个表为基础


6. 循环展开,Loop unwinding或loop unrolling,是一种牺牲程序的尺寸来加快程序的执行速度的优化方法。循环展开用来降低循环开销,为具有多个功能单元的处理器提供指令级并行。也有利于指令流水线的调度。


7.正则表达式符号

^匹配输入字符串的开始位置。$匹配输入字符串的结束位置。

\w匹配可包含下划线的任意单词。

+表示可匹配1次或多次,*表示匹配0次或多次。

{n,m}最少匹配n次,最多匹配m次。


编程题:

2013.9.28微软笔试题-真题分析 链表大题 mircosoft_第1张图片


我的思路:

先将链表中间切开拆成2个链表,将后半部分反转。然后两个半截链表交叉合并。

如图是奇数个元素和偶数个元素的2种情况,而实际代码中这2种情况是一样的。

2013.9.28微软笔试题-真题分析 链表大题 mircosoft_第2张图片
本算法的性能:

空间复杂度O(1)。
时间复杂度O(n),遍历了两遍。将链表元素个数为奇数偶数两种情况结合为一起。


#include <iostream>
#include <malloc.h>
using namespace std;

typedef struct node
{
	int val;
	node* next;
}node,*list;

void displaylist(list s)
{
	while(s!=NULL)
	{
		cout<<s->val<<" ";
		s = s->next;
	}
	cout<<endl;
}

int main()
{  
	int a[] = {9,8,7,6,5,4,3,2,1};
	//创建原始链表
	list L=NULL;
	for(int i=0;i<sizeof(a)/sizeof(int);i++)
	{
		node *p = (node*)malloc(sizeof(node));
		p->val = a[i];
		p->next = L;
		L = p;
	}
	//非常重要的边界特殊情况检查
	if(L==NULL)
		return -1;

	displaylist(L);

	//寻找中间结点位置
	node *fast=L,*slow=L;
	while(fast->next!=NULL && fast->next->next!=NULL)
	{
		fast = fast->next->next;
		slow = slow->next;
	}
	node *mid = slow->next;
	slow->next = NULL; //正式将原链表一切为二

	//将后半部分链表反转
	list s2 = NULL;
	node *tmp;
	while(mid!=NULL)
	{
		tmp = mid->next;
		mid->next = s2;
		s2 = mid;
		mid = tmp;
	}
	//displaylist(L);
	//displaylist(s2);
	
	//交叉合并两个链表
	list s1 = L;
	while(s2!=NULL)
	{
		tmp = s2->next;
		s2->next = s1->next;
		s1->next = s2;	
		s1 = s1->next->next;
		s2 = tmp;
	}
	displaylist(L);
	return 1;
}


你可能感兴趣的:(2013.9.28微软笔试题-真题分析 链表大题 mircosoft)