var _gaq = _gaq || []; _gaq.push(['_setAccount', 'UA-333696-1']); _gaq.push(['_trackPageview']); _gaq.push(['_trackPageLoadTime']); (function() { var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true; ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js'; var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s); })();
  • 2007年08月16日

    华为若干有趣的笔试题

    分类:

    用预处理指令#define 声明一个常数,用以表明1年中有多少秒(忽略闰年问题)

    A#define SECONDS_PER_YEAR (60 * 60 * 24 * 365) UL

     

    写一个“标准”宏MIN ,这个宏输入两个参数并返回较小的一个。

    A#define MIN(A,B) ((A <= (B) ? (A): (B))

     

    预处理器标识#error的目的是什么?

    A:保证程序是按照你所设想的那样进行编译。

     

    关键字static的作用是什么?

    A:在C语言中,关键字static有三个作用:在函数体,一个被声明为静态的变量在这一函数被调用过程中维持其值不变;在模块内(但在函数体外),一个被声明为静态的变量可以被模块内所用函数访问,但不能被模块外其它函数访问。它是一个本地的全局变量;在模块内,一个被声明为静态的函数只可被这一模块内的其它函数调用,这就是这个函数被限制在声明它的模块的本地范围内使用。

     

    关键字volatile有什么含意?并给出三个不同的例子。

    A:一个定义为volatile的变量是说这变量可能会被意想不到地改变,这样,编译器就不会去

    假设这个变量的值了。精确地说就是,优化器在用到这个变量时必须每次都小心地重新读

    取这个变量的值,而不是使用保存在寄存器里的备份。下面是volatile变量的几个例子:并行设备的硬件寄存器(如:状态寄存器);一个中断服务子程序中会访问到的非自动变量(Non-automatic variables);多线程应用中被几个任务共享的变量。

     

    进程间的通讯方式-interprocess communication (IPC)

    A

    a.   管道(Pipe(包括命名管道(named pipe)、匿名管道(anonymous pipe):管道可用于具有亲缘关系进程间的通信,有名管道克服了管道没有名字的限制,因此,除具有管道所具有的功能外,它还允许无亲缘关系进程间的通信;  

    b.   信号(Signal):信号是比较复杂的通信方式,用于通知接受进程有某种事件发生,除了用于进程间通信外,进程还可以发送信号给进程本身;Linux除了支持Unix早期信号语义函数signal外,还支持语义符合Posix.1标准的信号函数sigaction(实际上,该函数是基于BSD的,BSD为了实现可靠信号机制,又能够统一对外接口,用sigaction函数重新实现了signal   函数);  

    c.   消息队列(Message Queue):消息队列是消息的链接表,包括Posix消息队列system   V消息队列。有足够权限的进程可以向队列中添加消息,被赋予读权限的进程则可以读走队列中的消息。消息队列克服了信号承载信息量少,管道只能承载无格式字节流以及缓冲区大小受限等缺点。  

    d.   共享内存(Shared memory):使得多个进程可以访问同一块内存空间,是最快的可用IPC形式。是针对其他通信机制运行效率较低而设计的。往往与其它通信机制,如信号量结合使用,来达到进程间的同步及互斥。  

    e.   信号量(semaphore):主要作为进程间以及同一进程不同线程之间的同步手段。  

    f.   套接字(Socket):更为一般的进程间通信机制,可用于不同机器之间的进程间通信。起初是由Unix系统的BSD分支开发出来的,但现在一般可以移植到其它类Unix系统上:LinuxSystem V的变种都支持套接字。

    g.   内存映射文件(memory-mapped file):在多个进程之间共享数据。

    h.   广播式通信(Mailslots):Server进程可以产生Mailslots,任何Client进程可以写数据进去,但是只有Server进程可以取数据。

    i.   信箱通信(Mailbox):当一个进程希望与另一进程通信时,就创建一个链接两个进程的信箱,发送进程把信件投入信箱,而接收进程可以在任何时刻取走信件。

    j.   远程过程调用(Remote Procedure Calls,RPC):为组件提供一种相互通信的方式,使这些组件之间能够相互发出请求并传递这些请求的结果。

     

    线程同步的几种方法?线程间通讯的几种方法?
    A:常用的同步方法有:临界区(CriticalSection)、互斥器(Mutex)、信号量(Semaphore)、事件(Event)、Interlocked Variable。常用的通讯方法有:使用全局变量进行通信,用volatile 修饰符,它告诉编译器无需对该变量作任何的优化,即无需将它放到一个寄存器中,并且该值可被外部改变;使用自定义消息,在一个线程的执行函数中向另一个线程发送自定义的消息来达到通信的目的,利用Windows操作系统的消息驱动机制,当一个线程发出一条消息时,操作系统首先接收到该消息,然后把该消息转发给目标线程,接收消息的线程必须已经建立了消息循环。

     

    C++的类和C里面的struct有什么区别?

    A:默认的访问权限不同,C++privateCpublic

     

    全局变量和局部变量有什么区别?实怎么实现的?操作系统和编译器是怎么知道的?

    A:全局变量和局部变量的区别主要在于生存周期不同,全局变量在整个程序生成期间可见,局部变量在自己的作用域内可见。全局变量的内存分配是静态的,位于PE文件在数据区,在main()前由CC++运行期函数初始化,如果没有初值,会被初始化为0。局部变量的内存分配是动态的,位于线程堆栈中。如果没有初始化的,初始值视当前内存内的值而定。全局变量在程序运行期间长驻内存,直到程序运行结束,而局部变量动态分配内存。

     

    析构函数和虚函数的用法和作用?

    A:析构函数是在对象生存期结束时系统自动调用的函数,用来释放在构造函数分配的内存;虚函数是指被关键字virtual说明的函数,作用是使用C++语言的多态特性,为防止父类和子类中的相同函数名而完成不同(或相似)功能的函数造成调用时的二义性。

     

    交换机和路由器各自的实现原理是什么?分别在哪个层次上面实现的?

    A:交换机属于OSI第二层即数据链路层设备。它根据MAC地址寻址,通过站表选择路由,站表的建立和维护由交换机自动进行。路由器属于OSI第三层即网络层设备,它根据IP地址进行寻址,通过路由表路由协议产生。交换机最大的好处是快速,路由器最大的好处是控制能力强。

     

    140的整数,选取其中四个作为天平的砝码重量,这四个砝码的组合可以称出140的任意整数重量,这四个数字是什么?

    A:把砝码放在一端的话,至少需要6个砝码:12481632

    砝码允许放在两端的话,至少需要4个砝码:13927

    情况类似的原因,只解释一下第二种情况:

    称出1克需要一个1个的砝码,同样2克也需要一个2克的砝码,1克、2克的砝码则可以称出123,同样1克、3克可以称出1克、(3-1)克(放在两端)、3克、(3+1)克,再添加一个9克的则可以称出1克到13克的任意整数克,推广的话:用133^2,……3^n-1克可以称出从1克到(1+3+3^2+……+3^n-1)1/23^n-1)克中的任意一切整数克。

    当量程给定时,要确定最少必备的砝码,只需把最大的克数化为进位数,在求各位数码时余数只许是10-1即可。

    更为准确的表达是:

    要称出1克到n克中的任意整数克数,再只允许放在一端情况下的关键是把:1+x+x^2+……+x^n分解成1+x^a+x^2a+……+x^ma的形式;

    同样在两端允许放砝码的情况下则是把:x^-n+x^(-n+1)+……+x^-1+x+x^2+……+x^n分解成x^-(ma)+……+x^-a+1+x^a+……+x^(ma),其中n为要求的最大克数,a就是所需的砝码克数。

    比如上个例子(放在两端的情况下)共有8种可能,给出的组合是用砝码最少同时也是唯一没有重复用砝码。

     

    下载:华为笔试题目

    分享到: