应聘准备资料(逐步更新)

1.交换两个值的大小

A.  a=a+b ;  b = a-b;  a = a-b;      B. a = a*b;  b = a/b;  a = a/b     C. a = a^b;   b = a^b;  a = a^b

 

2.int func(x)
{
    int countx = 0;
    while(x)
    {
          countx ++;
          x = x&(x-1);
     }
    return countx;
}

假定x = 9999. 答案:8思路:将x转化为2进制,看含有的1的个数。

3.

 const int* c=new int;
 int * e = c ;  出错,指针不能指向一个常量,在这里c所指向的值不能改变

 int* const c=new int;
 int * e = c ; 正确

 

4.

#include <stdio.h>
union
{
int i;
char x[2];
}a;
void main()
{
a.x[0] = 10;
a.x[1] = 1;
printf("%d",a.i);
}

答案:266 (低位低地址,高位高地址,内存占用情况是Ox010A)

 

5.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 ;
}

 

6.操作系统的组成(一道让我误解的题目)

(1)对CPU的使用进行管理的进程调度程序
(2)对内存分配进行管理的内存管理程序
(3)对输入输出设备进行管理的设备驱动程序
(4)对外存中信息进行管理的文件系统


 

 7.ping是否可以查看端口21是否可用,为什么?

不能,ping只能pingIP,不能ping端口.

 

8.说出A、B、C类网络的子网号有几位?

注意,这里的子网号是等于网络号的,我一时没有反应过来,晕。

A: 0   网络号7位  主机号24位

B:10    网络号16位  主机号16位

C:110 网络号23位  主机号8位  

  

10.函数压栈的方式(只列举常考的)

                               函数名                 参数压栈              清栈                             备注

(1)_cdcel            _function               右到左          调用者清栈         可变参数列表的定义方式

(2)_fastcall       @function@8         右到左          函数内部清栈     利用了寄存器ecx、eax、edx

(3)_stdcall        _function@8           右到左         函数内部清栈      

 

11.多线程同步的方式及比较

主要有下面几种:

1)如果同步的是一个32位或者64位的数,我们用原子方式实现同步,旋转锁就是用原子函数实现的,通过不停地调用原子函数对一个变量赋值,并返回变量的原值,如下:

      while(InterlockedExchange(&g,true) == true);

      由于返回的是原值,会不断循环,直至在别的地方改变为止。这种方式非常消耗CPU资源,在单处理器上不能使用,会一直占用着,多处理器上也不建议使用。也可以用一

      个volatile的变量实现同步,但效率不高。

2)如果同步的是一段代码,我们用关键代码段。在我们运行函数时,会以原子方式运行,也就是说在函数调用时会对资源进行原子方式处理,别的线程只能等待,并从用户模

      式切换到内核模式,进入等待状态,由于此过程开销很大,所以微软出了一个与关键代码段相结合的旋转锁,在一段很小的周期内不断询问是否可以调用资源,在里面有一

      个计数,记录着旋转次数,当次数转为0时也是会进入内核模式。关键段速度快,非内对象, 只能用于同一进程之中,且容易处于死锁状态。

3)有另一种方式跟关键代码段差不多,就是Slim读写锁。它也是对资源以原子的形式保护起来,不过,在进行读操作时,允许别的线程读取该资源,只是在写操作时独占资源

      而已。

4)利用事件内核对象。让一个事件处于触发或者非触发状态,当事件处于触发时,等待的事件就变成可调度状态了。这里有一点值得注意,事件分为两种,手动重置和自动重

      置。手动重置是事件触发时,所有等待的线程变为可调度状态,而自动的话就只有一个。事件对象属于内核对象,系统耗费大量资源,但是可用于多进程间。

5)信号量内核对象。对某一资源设置一个访问上限值,只允许上限值的个数访问,当计数等于0时,信号量就变成未触发状态。信号量属于内核对象,耗费大量资源,但可用

      于多进程间。

6)互斥量内核对象。独占对一个资源的访问,里面有一个线程ID,为0时表示该对象可触发。信号量属于内核对象,耗费大量资源,但可用于多进程间。

 

12、线程终止运行时系统的处理

1)释放线程栈对象       2)返回退出代码       3)线程的内核对象减一,并置为触发状态(互斥量或者事件对象时有用)       4)倘若结束线程为进程最后线程则结束进程

 

13.PostMessage 与SendMessage区别

相同点:参数相同,函数作用相同

不同点:1)返回值不同

                2)前者是异步的,把消息放在消息循环队列里面后就返回,不管有无处理。而后者是同步的,等待消息被处理后再返回

                3)同一线程时, SendMessage不把消息放进循环队列,而是调用目标窗体的消息处理程序进行处理,之后等待结果返回。而PostMessage 就直接放在消息循环队 

                       列,然后通过循环分配到相应的窗口。

                4)不同线程时,SendMessage把消息放进消息循环队列,然后在目标窗体的消息处理程序里面监视消息的处理,等待返回,而PostMessage 一样。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值