Ping.Po
学而不思则罔,思而不学则殆。
posts - 3,  comments - 1,  trackbacks - 0

1.软件开发过程有哪些。(软件工程学中最基本的问题,上次去面试,吞吞吐吐的居然答不全)
answer:
   1.需求分析阶段
               这个阶段主要是收集并分析用户的需求,并且根据软件的需求建立完整而明确的
   2.概要设计阶段
               针对用户需求的软件结构将会被设计,并确定软件内部各个部分的相关联系。
   3.详细设计阶段
               软件各个部件的执行功能将被设计。
   4.编码与单元测试阶段
               将对软件的各个部件进行编码,并且进行单元测试以确定各个部分确定执行了详细设计阶段锁制定的目标。
   5.软件集成阶段
               被测试过的各个部件被逐渐集成起来测试直到构成一个完整的软件
   6.系统集成阶段
               这个阶段将软件程序集成起来,构成一个成品。
   7.验证测试阶段
               这个阶段进行测试以验证软件确实完整的执行了用户的需求分析。

  2.写一个函数使用字符串逆序存储。BOOL ReverseString(char * str);

bool ReverseString(char * str)
{
    
if (str == NULL)
    
{
        printf(
"str is null.dont't reverse!\n");
        
return false;
    }

    
int i=0,j=0;
    
char temp;
    
int len =strlen(str);

    
for (i=0,j=len-1;i!=len/2;i++,j--)
    
{
        temp 
= str[i];
        str[i] 
= str[j];
        str [j] 
=temp;
    }

    
return true;
}

              // 这个还有没有更好的方法?(递归是一种) 这样的代码什么地方写的不好,怎么优化?  
3.请简述描述WINDOW内存管理方法

// 1.虚拟内存 2.内存管理方式
当程序运行时需要从内存中读出这段程序的代码。代码的位置必须在物理内存中才能被运行,由于现在的操作系统中有非常多的程序运行着,内存中不能够完全放下,所以引出了虚拟内存的概念。把哪些不常用的程序片断就放入虚拟内
存,当需要用到它的时候在load入主存(物理内存)中。这个就是内存管理所要做的事。

内存管理还有另外一件事需要做:计算程序片段在主存中的物理位置,以便CPU调度。
内存管理有块式管理,页式管理,段式和段页式管理。现在常用段页式管理
块式管理:把主存分为一大块、一大块的,当所需的程序片断不在主存时就分配一块主存空间,把程 序片断load入主存,就算所需的程序片度只有几个字节也只能把这一块分配给它。这样会造成很大的浪费,平均浪费了50%的内存空间,但时易于管理。

页式管理:把主存分为一页一页的,每一页的空间要比一块一块的空间小很多,显然这种方法的空间利用率要比块式管理高很多。

段式管理:把主存分为一段一段的,每一段的空间又要比一页一页的空间小很多,这种方法在空间利用率上又比页式管理高很多,但是也有另外一个缺点。一个程序片断可能会被分为几十段,这样很多时间就会被浪费在计算每一段的物理地址上(计算机最耗时间的大家都知道是I
/O吧)。

段页式管理:结合了段式管理和页式管理的优点。把主存分为若干页,每一页又分为若干段。好处就很明显,不用我多说了吧。
各种内存管理都有它自己的方法来计算出程序片断在主存中的物理地址,其实都很相似。


 4.堆区 和 栈区的区别

堆(heap)和栈(stack)有什么区别??   
    
  简单的可以理解为:     
  heap:是由malloc之类函数分配的空间所在地。地址是由低向高增长的。     
  stack:是自动分配变量,以及函数调用的时候所使用的一些空间。地址是由高向低减少的。   
    
  预备知识—程序的内存分配   
    
  一个由c
/C++编译的程序占用的内存分为以下几个部分   
  
1、栈区(stack)—   由编译器自动分配释放   ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。   
  
2、堆区(heap)   —   一般由程序员分配释放,   若程序员不释放,程序结束时可能由OS回收   。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表,呵呵。   
  
3、全局区(静态区)(static)—,全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域,   未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。   -   程序结束后有系统释放   
  
4、文字常量区   —常量字符串就是放在这里的。   程序结束后由系统释放   
  
5、程序代码区—存放函数体的二进制代码。   
    
  二、例子程序   
  这是一个前辈写的,非常详细   
  
//main.cpp   
  int   a   =   0;   全局初始化区   
  
char   *p1;   全局未初始化区   
  main()   
  
{   
  
int   b;   栈   
  
char   s[]   =   "abc";   栈   
  
char   *p2;   栈   
  
char   *p3   =   "123456";   123456在常量区,p3在栈上。   
  
static   int   c   =0;   全局(静态)初始化区   
  p1   
=   (char   *)malloc(10);   
  p2   
=   (char   *)malloc(20);   
  分配得来得10和20字节的区域就在堆区。   
  strcpy(p1,   
"123456");   123456放在常量区,编译器可能会将它与p3所指向的"123456"优化成一个地方。   
  }
     
  二、栈的理论知识   
  
2.1申请方式   
  stack:   
  由系统自动分配。   例如,声明在函数中一个局部变量   
int   b;   系统自动在栈中为b开辟空间   
  heap:   
  需要程序员自己申请,并指明大小,在c中malloc函数   
  如p1   
=   (char   *)malloc(10);   
  在C
++中用new运算符   
  如p2   
=   (char   *)malloc(10);   
  但是注意p1、p2本身是在栈中的。   
  
2.2   
  申请后系统的响应   
  栈:只要栈的剩余空间大于所申请空间,系统将为程序提供内存,否则将报异常提示栈溢出。   
  堆:首先应该知道操作系统有一个记录空闲内存地址的链表,当系统收到程序的申请时,   
  会遍历该链表,寻找第一个空间大于所申请空间的堆结点,然后将该结点从空闲结点链表中删除,并将该结点的空间分配给程序,另外,对于大多数系统,会在这块内存空间中的首地址处记录本次分配的大小,这样,代码中的delete语句才能正确的释放本内存空间。另外,由于找到的堆结点的大小不一定正好等于申请的大小,系统会自动的将多余的那部分重新放入空闲链表中。   
  
2.3申请大小的限制   
  栈:在Windows下,栈是向低地址扩展的数据结构,是一块连续的内存的区域。这句话的意思是栈顶的地址和栈的最大容量是系统预先规定好的,在   WINDOWS下,栈的大小是2M(也有的说是1M,总之是一个编译时就确定的常数),如果申请的空间超过栈的剩余空间时,将提示overflow。因此,能从栈获得的空间较小。   
  堆:堆是向高地址扩展的数据结构,是不连续的内存区域。这是由于系统是用链表来存储的空闲内存地址的,自然是不连续的,而链表的遍历方向是由低地址向高地址。堆的大小受限于计算机系统中有效的虚拟内存。由此可见,堆获得的空间比较灵活,也比较大。   
  
2.4申请效率的比较:   
  栈由系统自动分配,速度较快。但程序员是无法控制的。   
  堆是由new分配的内存,一般速度比较慢,而且容易产生内存碎片,不过用起来最方便.   
  另外,在WINDOWS下,最好的方式是用VirtualAlloc分配内存,他不是在堆,也不是在栈是直接在进程的地址空间中保留一快内存,虽然用起来最不方便。但是速度   
    
  也最灵活   
  
2.5堆和栈中的存储内容   
  栈:   在函数调用时,第一个进栈的是主函数中后的下一条指令(函数调用语句的下一条可执行语句)的地址,然后是函数的各个参数,在大多数的C编译器中,参数是由右往左入栈的,然后是函数中的局部变量。注意静态变量是不入栈的。   
  当本次函数调用结束后,局部变量先出栈,然后是参数,最后栈顶指针指向最开始存的地址,也就是主函数中的下一条指令,程序由该点继续运行。   
  堆:一般是在堆的头部用一个字节存放堆的大小。堆中的具体内容有程序员安排。   
  
2.6存取效率的比较   
    
  
char   s1[]   =   "aaaaaaaaaaaaaaa";   
  
char   *s2   =   "bbbbbbbbbbbbbbbbb";   
  aaaaaaaaaaa是在运行时刻赋值的;   
  而bbbbbbbbbbb是在编译时就确定的;   
  但是,在以后的存取中,在栈上的数组比指针所指向的字符串(例如堆)快。   
  比如:   
  #include     
  
void   main()   
  
{   
  
char   a   =   1;   
  
char   c[]   =   "1234567890";   
  
char   *p   ="1234567890";   
  a   
=   c[1];   
  a   
=   p[1];   
  
return;   
  }
   
  对应的汇编代码   
  
10:   a   =   c[1];   
  
00401067   8A   4D   F1   mov   cl,byte   ptr   [ebp-0Fh]   
  0040106A   
88   4D   FC   mov   byte   ptr   [ebp-4],cl   
  
11:   a   =   p[1];   
  0040106D   8B   
55   EC   mov   edx,dword   ptr   [ebp-14h]   
  
00401070   8A   42   01   mov   al,byte   ptr   [edx+1]   
  
00401073   88   45   FC   mov   byte   ptr   [ebp-4],al   
  第一种在读取时直接就把字符串中的元素读到寄存器cl中,而第二种则要先把指针值读   
    
  edx中,在根据edx读取字符,显然慢了。   
    
      
    
  
2.7小结:   
  堆和栈的区别可以用如下的比喻来看出:   
  使用栈就象我们去饭馆里吃饭,只管点菜(发出申请)、付钱、和吃(使用),吃饱了就走,不必理会切菜、洗菜等准备工作和洗碗、刷锅等扫尾工作,他的好处是快捷,但是自由度小。   
  使用堆就象是自己动手做喜欢吃的菜肴,比较麻烦,但是比较符合自己的口味,而且自由度大。   
    
  堆和栈的区别主要分:   
  操作系统方面的堆和栈,如上面说的那些,不多说了。   
  还有就是数据结构方面的堆和栈,这些都是不同的概念。这里的堆实际上指的就是(满足堆性质的)优先队列的一种数据结构,第1个元素有最高的优先权;栈实际上就是满足先进后出的性质的数学或数据结构。   
  虽然堆栈,堆栈的说法是连起来叫,但是他们还是有很大区别的,连着叫只是由于历史的原因。   

 // 这是非常常见的题目,自己也被问到,上次自己回答得很不系统。

posted on 2008-12-22 23:56 PingPo 阅读(246) 评论(1)  编辑 收藏 引用

FeedBack:
# re: 面试笔试题(1)

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理



<2008年12月>
30123456
78910111213
14151617181920
21222324252627
28293031123
45678910

常用链接

留言簿(1)

随笔分类

随笔档案

文章档案

搜索

  •  

最新评论

阅读排行榜

评论排行榜