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次。
编程题:
我的思路:
先将链表中间切开拆成2个链表,将后半部分反转。然后两个半截链表交叉合并。
如图是奇数个元素和偶数个元素的2种情况,而实际代码中这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; }