一些典型的笔试面试题

关于C/C++基础知识的面试题 http://blog.chinaunix.net/uid-25132162-id-362698.html

已知String类定义如下,尝试写出类的成员函数实现。

class String

{

public:

    String(const char *str = NULL); // 通用构造函数

    String(const String &another); // 拷贝构造函数

    ~ String(); // 析构函数

    String & operater =(const String &rhs);// 赋值函数

private:

    char *m_data;// 用于保存字符串

};

答:

String::String(const char *str)

{

    if ( str== NULL ) //strlen在参数为NULL时会抛异常才会有这步判断

    {

       m_data = new char[1] ;

       m_data[0] = '\0' ;

    }

    else

    {

       m_data = new char[strlen(str) +1];

       strcpy(m_data,str);

    }

}

String::String(const String &another)

{

    m_data = new char[strlen(another.m_data) + 1];

    strcpy(m_data,other.m_data);

}

String& String::operator =(const String &rhs)

{

    if ( this== &rhs)

       return *this ;

    delete []m_data;//删除原来的数据,新开一块内存

    m_data = new char[strlen(rhs.m_data) + 1];

    strcpy(m_data,rhs.m_data);

    return *this;

}

String::~String()

{

    delete []m_data;

}


交换变量a和b的值#defineswap(a,b) a=a+b;b=a-b;a=a-b;


变量a和b,不用if、?:、switch或其它判断语句,找出最大的一个变量。

答:( ( a + b) + abs( a- b ) ) / 2


static全局变量与普通的全局变量有什么区别?static局部变量和普通局部变量有什么区别?static函数与普通函数有什么区别?(20分)

static全局变量与普通全局变量的区别:前者在主函数之前就要被初始化,(2分)后者无要求。(2分)

static局部变量和普通局部变量的区别:static全句变量是所有函数共享的变量,在一个函数使用完它后它的值会保持到下一个函数来改变它(2分)。后者,本函数所声明的局部变量在本函数运行完之后会被销毁。(2分)

 static函数与普通函数的区别:static的可以用类来访问(就是不用初始化一个类就直接使用这个类的这个static方法);(2分)非static的只能通过对象来访问(2分)。static的定义里不能用到类内部非static变量值。(3分)static在循环中定义并赋值时,定义过程只进行一次,而不是每个循环1次。(3分)


堆:由malloc系列函数或new操作符分配的内存。其生命周期由free或delete决定。在没有释放之前一直存在,知道程序结束。其特点是使用灵活,空间比较大,但容易出错。

栈:保存局部变量。栈上的内容只在函数的范围内存在,当函数运行结束,这些内容也会自动被销毁。其特点是效率高,但空间大小有限。

静态区:保存自动全局变量和static变量(包括static全局和局部变量)。静态区的内容在整个程序的生命周期内都存在,由编译器在编译的时候分配。


描述内存分配方式以及它们的区别?

答:1)从静态区分配:内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。例如全局变量,static 变量。

2)在栈上创建:在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集。

3) 从堆上分配,亦称动态内存分配。程序在运行的时候用malloc或new 申请任意多少的内存,程序员自己负责在何时用free 或delete 释放内存。动态内存的生存期由程序员决定,使用非常灵活,但问题也最多。

更详细的讲解:http://www.cnblogs.com/daocaoren/archive/2011/06/29/2092957.html


free释放内存后需要做什么?下一行代码应该怎样写?

被free()掉的指针,我们通常叫野指针,野指针是非常危险的哦,可能导致多次释放内存或者对野指针进行访问,

这两种情况都可能导致严重的安全风险。

最好的也是最简单的解决办法就是在释放后,把指针设置为NULL或者指向另一个合法的对象。

就像这样:

free(ptr);
ptr = NULL;

链表题:一个链表的结点结构。

struct Node

{

    int data;

    Node *next;

};

typedef struct Node Node;

 

(1)已知链表的头结点head,写一个函数把这个链表逆序 ( Intel)

Node * ReverseList(Node *head) //链表逆序

{

    if ( head== NULL || head->next == NULL )

       return head;

    Node *p1= head ;

    Node *p2= p1->next;

    Node *p3= p2->next;

    p1->next = NULL ;

    while ( p3!= NULL )

    {

       p2->next = p1 ;

       p1 = p2 ;

       p2 = p3 ;

       p3 = p3->next ;

    }

    p2->next = p1 ;

    head = p2 ;

    return head;

}

(2)已知两个链表head1 和head2 各自有序,请把它们合并成一个链表依然有序。(保留所有结点,即便大小相同)

Node * Merge(Node *head1 , Node *head2)

{

    if ( head1== NULL)

       return head2 ;

    if ( head2== NULL)

       return head1 ;

    Node *head= NULL ;

    Node *p1= NULL;

    Node *p2= NULL;

    if ( head1->data < head2->data )

    {

       head = head1 ;

       p1 = head1->next;

       p2 = head2 ;

    }

    else

    {

       head = head2 ;

       p2 = head2->next;

       p1 = head1 ;

    }

    Node *pcurrent= head ;

    while ( p1!= NULL && p2!= NULL)

    {

       if ( p1->data <= p2->data )

       {

           pcurrent->next = p1 ;

           pcurrent = p1 ;

           p1 = p1->next ;

       }

       else

       {

           pcurrent->next = p2 ;

           pcurrent = p2 ;

           p2 = p2->next ;

       }

    }

    if ( p1!= NULL )

       pcurrent->next = p1 ;

    if ( p2!= NULL )

       pcurrent->next = p2 ;

    return head;

}

(3)已知两个链表head1 和head2 各自有序,请把它们合并成一个链表依然有序,这次要求用递归方法进行。 (Autodesk)

答案:

Node * MergeRecursive(Node *head1 , Node *head2)

{

    if ( head1== NULL )

       return head2 ;

    if ( head2== NULL)

       return head1 ;

    Node *head= NULL ;

    if ( head1->data < head2->data )

    {

       head = head1 ;

       head->next = MergeRecursive(head1->next,head2);

    }

    else

    {

       head = head2 ;

       head->next = MergeRecursive(head1,head2->next);

    }

    return head;

}

delete与delete []的区别

答: delete只会调用一次析构函数,而delete[]会调用每一个成员的析构函数。在More Effective  C++中有更为详细的解释:“当delete操作符用于数组时,它为每个数组元素调用析构函数,然后调用operator delete来释放内存。”delete与New配套,delete []与new []配套。


下面哪种排序法对12354最快。

quick sort

buble sort(正确)

merge sort

当数据规模较小时,应选择直接插入排序或冒泡排序。任何排序算法在数据量小时基本体现不出来差距。我们说快排好,是指大量随机数据下,快排效果最理想。而不是所有情况。

 

哪种结构,平均来讲,获取一个值最快。

binary tree

hash table(正确)

stack


死锁产生的原因及四个必要条件

产生死锁的原因主要是:
(1) 因为系统资源不足。
(2) 进程运行推进的顺序不合适。
(3) 资源分配不当等。
如果系统资源充足,进程的资源请求都能够得到满足,死锁出现的可能性就很低,否则
就会因争夺有限的资源而陷入死锁。其次,进程运行推进顺序与速度不同,也可能产生死锁。
产生死锁的四个必要条件
(1) 互斥条件:一个资源每次只能被一个进程使用。
(2) 请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。
(3) 不剥夺条件:进程已获得的资源,在末使用完之前,不能强行剥夺。
(4) 循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。
这四个条件是死锁的必要条件,只要系统发生死锁,这些条件必然成立,而只要上述条件之
一不满足,就不会发生死锁。

【持续更新   10-7】


你可能感兴趣的:(面试,笔试,2014)