笔试面试题一

1、要对绝对地址0x100000赋值,我们可以用(unsigned int*)0x100000 = 1234;那么要是想让程序跳转到绝对地址是0x100000去执行,应该怎么做?

       答案:*((void (*)( ))0x100000 ) ( );

        首先要将0x100000强制转换成函数指针,:(void (*)())0x100000

        然后再调用它:*((void (*)())0x100000)();

        用typedef可以看得更直观些typedef void(*)() voidFuncPtr;  *((voidFuncPtr)0x100000)();

2、下面的输出结果

        unsigned short A = 10;

        printf("~A = %u\n", ~A);  // 0xfffa = 4294967285 (无符号)     -11(有符号)

        char c=128;

        printf("c=%d\n",c);           // 0x80 = -128

3、指针加法

struct BBB
{
	long num;
	char *name;
	short int data;
	char ha;
	short ba[5];
}*p;


int main(int argc, char* argv[])
{
	p=(struct BBB*)0x1000000;                     //sizeof(struct BBB)=24
	cout<<hex<<p+0x200<<endl;                     //p+0x200*24 = 0x01003000  p指向的是结构体类型
	cout<<hex<<(unsigned long)p+0x200<<endl;      //p+0x200    =    1000200  p被强制转换为长整型
	cout<<hex<<(unsigned long*)p+0x200<<endl;;    //p+0x200*4  = 0x01000800  p指向的是指针类型

	return 0;
}

4、什么是预编译,何时需要预编译?

        答:预编译就是指程序执行之前的一些预处理工作,预编译头文件的作用是提高编译速度,有了它你没有必要每次都编译那些不需要经常改变的代码,编译性能当然就提高了。

       何时需要预编译:

       1)、总是使用不经常改动的大型代码体。

       2)、程序由多个模块组成,所有模块都使用一组标准的包含文件和相同的编译选项。在这种情况下,可以将所有包含文件预编译为一个预编译头。

5、编写一个病毒

       while (1) { int *p = new int[10000000]; }

6、int x=35; char str[10]; 问:strlen(str)和 sizeof(str)的值分别是多少?

       答:strlen(str) 值不确定,strlen 根据'\0'确定字符串是否结束。sizeof(str)=10

    如进行下列操作:strcpy(str,"www.it315.org"/*共 13个字母*/),问:此时 x 和 strlen(str)的值分别是多少?

       进行strcpy操作,出现内存越界访问,x 值变为未知数,strlen(str)=13。

7、关键字volatile有什么含意?

        答案:Volatile关键字表明,即使程序代码没有对内存单元进行修改,其值也可能发生变化。下面是volatile变量的几个例子:

   1)并行设备的硬件寄存器(如:状态寄存器)

   2) 一个中断服务子程序中会访问到的非自动变量

   3) 多线程应用中被几个任务共享的变量

8、列举几种进程的同步机制。

        答案:原子操作 信号量机制 自旋锁  管程,会合,分布式系统

9、进程之间通信的途径。

        答案:共享内存,消息,管道。

10、进程死锁的原因。

        答案:资源竞争及进程推进顺序非法。

11、死锁的4个必要条件。

        答案:互斥、请求保持、不可剥夺、环路。

12、死锁的处理方法有哪些?

        答案:鸵鸟策略、预防策略、避免策略、检测与解除死锁。

13、操作系统中进程调度策略有哪几种?

        答案:FCFS(先来先服务),优先级,时间片轮转,多级反馈 。

14、数组和链表的区别。

        答案:数组:数据顺序存储,固定大小,查找复杂度为O(1);链表:数据随机存储,大小可动态改变,插入删除复杂度为O(1) 。

15、C++类 A 类B,在哪几种情况下B能隐式转化为A

          a. class B : public A { ……}    // B公有继承自A,可以是间接继承的

          b. class B { operator A( ); }     // B实现了隐式转化为A的转化

          c. class A { A( const B& ); }     // A实现了non-explicit的参数为B构造函数

          d. class A { A& operator= ( const B& ); } // 赋值操作

16、下面代码输出什么

struct CLS
{
    int m_i;
    CLS(int i) : m_i(i) {}   //含参构造函数
    CLS()
    {
        CLS(0); //默认构造函数,调用含参构造函数创建了一个CLS的对象CLS(0),这个对象与obj不一样
    }
};

CLS obj;                  //调用默认构造函数创建了CLS的一个对象obj
cout << obj.m_i << endl;  //所有输出为未知数

17、编写一个函数,完成内存之间的拷贝,注意有重叠内存区域时的拷贝。

//将起始地址为src处的count大小的内存拷贝到起始地址为dest处
void* mymemcpy( void *dest, const void *src, size_t count )  //void指针
{
    char* pdest = static_cast<char*>( dest );           	 //类型强制转换
    const char* psrc = static_cast<const char*>( src );      //类型强制转换
	if( pdest>psrc && pdest<psrc+count )          //判断拷贝的内存是否有重叠区
    {
        for( size_t i=count-1; i!=-1; --i)
			pdest[i] = psrc[i];                  //反向拷贝,防止元素重叠
    }
    else
    {
        for( size_t i=0; i<count; ++i )          //不存在重叠区域时,直接拷贝
            pdest[i] = psrc[i];
    }
    
	return dest;
}

 

你可能感兴趣的:(笔试面试题一)