1. 当前计算机系统一般会采用层次结构来存储数据,请介绍下典型的计算机存储系统一般分为哪几个层次,为什么采用分层存储数据能有效提高程序的执行效率?(10分)
(1)典型计算机存储系统一般分为:高速缓存(Cache),主存,辅存;三者速度递减,价格递减,容量递增。
(2)原因:最基本的原理是程序的局部性,即某一指令(数据)一旦被执行(访问),那么不久之后很可能再次被执行 (访问) 。
高速缓存(Cache),主存,辅存;三者速度递减,价格递减,容量递增。
Cache<-->主存:解决速度问题;
主存<-->辅存:解决容量问题。
http://hi.baidu.com/wlzqi/item/3b0fbd2cb384fc0a42634acd
2、Unix/Linux系统中僵尸进程是如何产生的?有什么危害?如何避免?
(1)产生
一般是 子进程结束后,是它的内核栈 (特别是进程描述符)依然驻留在内存中,这时需要父进程在wait 系统调用中,取得子进程的退出信息,然后内核就能释放那个进程描述符。如果父进程没有这样做的话,子进程就沦为僵死进程。
(2)危害
Linux系统对运行的进程数量有限制,如果产生过多的僵尸进程占用了可用的进程号,将会 导致新的进程无法生成。 这就是僵尸进程对系统的最大危害。
(3)避免
3. 简述Unix/Linux系统中使用socket库编写服务器端程序的流程,请分别用对应的socket通信函数表示(10分)1》signal(SIGCHLD,SIG_IGN);
2》fork 2次,让孙子进程由 init(1) 进程接管
3》用waitpid等待子进程返回
服务器端流程如下:
1.创建serverSocket
2.初始化 serverAddr(服务器地址)
3.将socket和serverAddr 绑定 bind
4.开始监听 listen
5.进入while循环,不断的accept接入的客户端socket,进行读写操作write和read
6.关闭serverSocket
客户端流程:
1.创建clientSocket
2.初始化 serverAddr
3.链接到服务器 connect
4.利用write和read 进行读写操作
5.关闭clientSocket
这个列表是一个Berkeley套接字API库提供的函数或者方法的概要:
socket() 创建一个新的确定类型的套接字,类型用一个整型数值标识,并为它分配系统资源。
bind() 一般用于服务器端,将一个套接字与一个套接字地址结构相关联,比如,一个指定的本地端口和IP地址。
listen() 用于服务器端,使一个绑定的TCP套接字进入监听状态。
connect() 用于客户端,为一个套接字分配一个自由的本地端口号。 如果是TCP套接字的话,它会试图获得一个新的TCP连接。
accept() 用于服务器端。 它接受一个从远端客户端发出的创建一个新的TCP连接的接入请求,创建一个新的套接字,与该连接相应的套接字地址相关联。
send()和recv(),或者write()和read(),或者recvfrom()和sendto(), 用于往/从远程套接字发送和接受数据。
close() 用于系统释放分配给一个套接字的资源。 如果是TCP,连接会被中断。
gethostbyname()和gethostbyaddr() 用于解析主机名和地址。
select() 用于修整有如下情况的套接字列表: 准备读,准备写或者是有错误。
poll() 用于检查套接字的状态。 套接字可以被测试,看是否可以写入、读取或是有错误。
getsockopt() 用于查询指定的套接字一个特定的套接字选项的当前值。
setsockopt() 用于为指定的套接字设定一个特定的套接字选项。
4、使用C/C++编写函数,实现字符串反转,要求不使用任何系统函数,且时间复杂度最小,函数原型:char* reverse_str(char* str)。(15分)
char* reverse_str( char* str ) { if(str == NULL) return NULL; char *st = str; char *ed = str; while( *ed != '\0' ) ed++; ed--; char tmp; while( st != ed ) { tmp = *st; *st++ = *ed; *ed-- = tmp; } return str; }
5、给定一个如下格式的字符串(1,(2,3),(4,(5,6),7))括号内的元素可以是数字,也可以是另一个括号,请实现一个算法消除嵌套的括号,比如把上面的表达式变成:(1,2,3,4,5,6,7),如果表达式有误请报错。(15分)
int reg_str( char *src, char *dest ) { int stack_num = 0; *(dest++) = '('; while( *src!= '\0' ) { if( *src == '(' ) stack_num++; else if( *src == ')' && stack_num >0 ) stack_num--; else if( *src == ',' ) { src++; continue; } else if ( '0' <= *src && *src <= '9' ) *(dest++) = *src; else { printf( "Expression ERROR!\n" ); return -1; } src++; } *(dest++) = ')'; *(dest++) = '\0'; return 0; }
7、动态链接库和静态链接库分别有什么优缺点?
静态库在程序编译时会被连接到目标代码中,程序运行时将不再需要该静态库。
动态库在程序编译时并不会被连接到目标代码中,而是在程序运行是才被载入,因此在程序运行时还需要动态库存在
静态链接库与动态链接库都是共享代码的方式,如果采用静态链接库,则无论你愿不愿意,lib 中的指令都全部被直接包含在最终生成的 EXE 文件中了。但是若使用 DLL,该 DLL 不必被包含在最终 EXE 文件中,EXE 文件执行时可以“动态”地引用和卸载这个与 EXE 独立的 DLL 文件。静态链接库和动态链接库的另外一个区别在于静态链接库中不能再包含其他的动态链接库或者静态库,而在动态链接库中还可以再包含其他的动态或静态链接 库。
采用动态链接库的优点:(1)更加节省内存;(2)DLL文件与EXE文件独立,只要输出接口不变,更换DLL文件不会对EXE文件造成任何影响,因而极大地提高了可维护性和可扩展性。
http://chriszeng87.iteye.com/blog/1186094http://blog.csdn.net/zhaojinjia/article/details/12170223
8、轮询任务调度和抢占式任务调度的区别?
10、数轴上从左到右有n各点a[0], a[1], ……,a[n -1],给定一根长度为L的绳子,求绳子最多能覆盖其中的几个点。(15分)
http://blog.csdn.net/u010590166/article/details/17125691
11、长度为N(N很大)的字符串,求这个字符串里的最长回文子串。(15分)
http://blog.csdn.net/u010590166/article/details/17125043
12、给定任意一个正整数,求比这个数大且最小的“不重复数”,“不重复数”的含义是相邻两位不相同,例如1101是重复数,而1201是不重复数。(15分)
http://blog.csdn.net/u010590166/article/details/17126083