阿里巴巴2017实习生笔试题(含答案)

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

答案: D

内联函数:

Tip :只有当函数只有10 行甚至更少时才将其定义为内联函数.

定义 :当函数被声明为内联函数之后, 编译器会将其内联展开, 而不是按通常的函数调用

机制进行调用 .

优点 :当函数体比较小的时候 , 内联该函数可以令目标代码更加高效. 对于存取函数以及

其它函数体比较短 , 性能关键的函数 , 鼓励使用内联 .

缺点 :滥用内联将导致程序变慢 .内联可能使目标代码量或增或减, 这取决于内联函数的

大小 .内联非常短小的存取函数通常会减少代码大小,但内联一个相当大的函数将戏剧性

的增加代码大小 . 现代处理器由于更好的利用了指令缓存,小巧的代码往往执行更快。

结论 :一个较为合理的经验准则是,不要内联超过 10行的函数 .谨慎对待析构函数 ,析构函数往往比其表面看起来要更长,因为有隐含的成员和基类析构函数被调用!

另一个实用的经验准则: 内联那些包含循环或 switch语句的函数常常是得不偿失( 除非在大多数情况下 , 这些循环或 switch语句从不被执行 ).

注意:有些函数即使声明为内联的也不一定会被编译器内联,这点很重要 ;比如虚函数和递归函数就不会被正常内联. 通常,递归函数不应该声明成内联函数.( 递归调用堆栈的展开

并不像循环那么简单 ,比如递归层数在编译时可能是未知的, 大多数编译器都不支持内联

递归函数 ). 虚函数内联的主要原因则是想把它的函数体放在类定义内, 为了图个方便 ,抑或是当作文档描述其行为, 比如精短的存取函数 .

-inl.h文件:

Tip :复杂的内联函数的定义,内联函数的定义必须放在头文件中理论上应该放在.cc文件中,能上有明显优势.

应放在后缀名为 -inl.h 的头文件中 ,

编译器才能在调用点内联展开定义我们

不希望 .h 文件中有太多实现代码

.

,

.然而, 实现代码

除非在可读性和性

如果内联函数的定义比较短小 , 逻辑比较简单 , 比如 , 存取函数的实现理所当然都应该放在类定义内实现代码放在.h文件里没有任何问题.出于编写者和调用者的方便,

.

较复

杂的内联函数也可以放到.h文件中,如果你觉得这样会使头文件显得笨重,也可以把它萃取到单独的-inl.h中.这样把实现和类定义分离开来,当需要时包含对应的-inl.h

即可。

A项错误,因为使用inline关键字的函数只是用户希望它成为内联函数,但编译器有权忽略这个请求,比如:若此函数体太大,则不会把它作为内联函数展开的。

B项错误,头文件中不仅要包含inline函数的声明,而且必须包含定义,且在定义时必须加上inline。【关键字inline必须与函数定义体放在一起才能使函数成为

内联,仅将inline放在函数声明前面不起任何作用】

C项错误,inline函数可以定义在源文件中,但多个源文件中的同名inline函数的实现必须相同。一般把inline函数的定义放在头文件中更加合适。

D项正确,类内的成员函数,默认都是inline的。【定义在类声明之中的成员函数将自动地成为内联函数】

EF项无意思,不管是class声明中定义的inline函数,还是class实现中定义的inline函数,不存在优先不优先的问题,因为class的成员函数都

是inline的,加了关键字inline也没什么特殊的

答案: D 插入排序

改良的冒泡最优也是n

答案: A

答案: A 答案: B

答案: D 先序遍历中左右中序遍历左中右后序遍历左右中

答案: D

TCP建立连接

首先客户端和服务器处于close 状态。

然后客户端发送SYN同步位,此时客户端处于SYN-SEND状态,服务器处于lISTEN 状态,当服务器收到SYN以后,向客户端发送同步位SYN和确认码 ACK,

然后服务器变为SYN-RCVD,

客户端收到服务器发来的SYN和 ACK后,客户端的状态变成 ESTABLISHED(已建立连接 ) ,客户端再向服务器发送ACK确认码,

服务器接收到以后也变成ESTABLISHED

然后服务器客户端开始数据传输

答案: F

假设为 n 进值则 [2*(n^2)+4*(n^1)+0] * [1*n+2]=2*(n^3)+8*(n^2)+8*(n^1)

化简后居然为很等式,n 为任意值

答案: B

用户空间与系统空间所在的内存区间不一样,同样,对于这两种区间,CPU的运行状态也不一样。在用户空间中,CPU处于 " 用户态 " ;在系统空间中,CPU处于 " 系统态 " 。

答案: C

select

select能监控的描述符个数由内核中的FD_SETSIZE限制,仅为 1024,这也是 select最大的缺点,因为现在的服务器并发量远远不止1024。即使能重新编译内核改变FD_SETSIZE的值,但这并不能提高select的性能。

每次调用select都会线性扫描所有描述符的状态,在select结束后,用户也要线性扫描fd_set数组才知道哪些描述符准备就绪,等于说每次调用复杂度都是O( n)的,在并发量大的

情况下,每次扫描都是相当耗时的,很有可能有未处理的连接等待超时。

每次调用 select 都要在用户空间和内核空间里进行内存复制fd描述符等信息。

poll

poll使用与 select pollfd结构来存储

的后两点类似, poll

fd ,突破了

仍然需要将

select

pollfd

中描述符数目的限制。

数组拷贝到内核空间,之后依次扫描fd

的状态,整体复杂度依然是O(n)的,在并发量大的情况下服务器性能会快速下降。

epoll

epoll维护的描述符数目不受到限制,而且性能不会随着描述符数目的增加而下降。

服务器的特点是经常维护着大量连接,但其中某一时刻读写的操作符数量却不多。epoll 先通过epoll_ctl注册一个描述符到内核中,并一直维护着而不像poll每次操作都将所有要监控的描述符传递给内核;在描述符读写就绪时,通过回掉函数将自己加入就绪队列中,之后

epoll_wait返回该就绪队列。也就是说,epoll基本不做无用的操作,时间复杂度仅与活跃的

客户端数有关,而不会随着描述符数目的增加而下降。

epoll在传递内核与用户空间的消息时使用了内存共享,而不是内存拷贝,这也使得epoll 的效率比poll和select更高。

答案: F

相关文档
最新文档