|
|
腾讯笔试题
]- q2 ~+ w- m! k" F0 g3 f9 v# w$ c( v0 w" R! z9 N
/ {3 t6 p4 @$ O+ Q- Q0 Y1. 写出判断ABCD四个表达式的是否正确, 若正确, 写出经过表达式中 a的值(3分)
! \9 B. Q" r$ x jint a = 4;
; J7 F8 y! K8 @(A)a += (a++); (B) a += (++a) ;(C) (a++) += a;(D) (++a) += (a++);9 u& D- W: {: x5 u- f
a = ?
" P& k7 N9 b$ Q1 o8 L3 o答:C错误,左侧不是一个有效变量,不能赋值,可改为(++a) += a;1 J* T% W6 M5 ?: W5 m6 g, i( ]
改后答案依次为9,10,10,116 v& U1 {. H4 e k- g
# R& Z0 b5 |6 E& f3 T2.某32位系统下, C++程序,请计算sizeof 的值(5分).
) \1 T+ ]$ W8 ?2 X; U$ [5 N1 f) ?char str[] = "http://www.xxxxx.com"
0 w! Y$ p& i# g- B, N$ Cchar *p = str ;/ `) o! O8 Q& M# P) K' I
int n = 10;
# t% \2 W3 N4 o' R6 }9 v! x- G$ W, @' T请计算" U2 ]8 v0 I3 ^" v R" ~# k9 t$ v: h
sizeof (str ) = ?(1) x, v+ a" m% I' O: l2 C' P
sizeof ( p ) = ?(2)2 s% ~- J% U# r1 G# J8 x* N
sizeof ( n ) = ?(3)
( i7 w; }7 d1 E# b' ]! Jvoid Foo ( char str[100]){3 F8 D" F" [+ N% T! [5 V* ]
请计算9 p8 Z+ o2 g& w
sizeof( str ) = ?(4)
; z: g( y/ c) f7 Y* g}* A E4 O) Q( _2 {
void *p = malloc( 100 );
/ v, {/ ~) T6 L6 [$ t请计算+ \- B" K" K4 X. D! x
sizeof ( p ) = ?(5)
/ o/ J3 b9 h, t' A7 m答:(1)17 (2)4 (3) 4 (4)4 (5)4& l. P! ?. Q! c2 m O
3 N! y* h& D, K3. 回答下面的问题. (4分)) S4 s; \% e( z) {( K5 ^
(1).头文件中的 ifndef/define/endif 干什么用?预处理" y: B8 t; c8 y( X
答:防止头文件被重复引用
* L3 F3 u1 I+ J2 }' r4 _" v) Q; j(2). #include <filename.h> 和 #include "filename.h" 有什么区别?
8 g8 A0 h* _+ M7 l答:前者用来包含开发环境提供的库头文件,后者用来包含自己编写的头文件。/ S# I! l' n6 d( \
(3).在C++ 程序中调用被 C 编译器编译后的函数,为什么要加 extern “C”声明?
9 M* C% o6 u7 p W' t- L2 L$ u7 Y答:函数和变量被C++编译后在符号库中的名字与C语言的不同,被extern "C"修饰的变4 H! `* K) |: G+ w l7 o1 g$ |! C
量和函数是按照C语言方式编译和连接的。由于编译后的名字不同,C++程序不能直接调" P* `2 B5 L2 t7 {
用C 函数。C++提供了一个C 连接交换指定符号extern“C”来解决这个问题。
0 F/ V, h# I' l* y1 ~& L(4). switch()中不允许的数据类型是?% o# Z0 Z- t j
答:实型
- d9 ^1 S! l* x5 l5 q$ `* y
! T' ?( N; O& Y1 ^6 l0 B% L/ ?, Q4 g4. 回答下面的问题(6分)
4 A1 }8 F* k% Y3 ]6 p(1).Void GetMemory(char **p, int num){
! L& ]$ B- w6 P# m+ z$ h*p = (char *)malloc(num);
6 H2 {6 t' i( f}
5 V$ `+ ~( ?( @: c& a* Fvoid Test(void){
' @- J/ j. A% \3 o" rchar *str = NULL;
5 ~ w( t3 O) e& N/ M! E1 Q: iGetMemory(&str, 100);% b8 X; o2 T! f4 x/ y
strcpy(str, "hello");
) C' Y0 z, q; gprintf(str);
3 N7 i! H4 p. D7 H}
0 w w1 F7 ~8 R0 o请问运行Test 函数会有什么样的结果?. p9 S! F4 T. d" J- ?! x! f2 m
答:输出“hello”
( V/ e; X7 t) s(2). void Test(void){/ U G, H; s7 l$ q: {& D! d7 p
char *str = (char *) malloc(100);
# e6 G" u7 A1 g4 ?' h, @* [ }strcpy(str, “hello”);# O- P$ \! j# R0 p! {/ w( {$ k
free(str);
+ E' v w+ {1 X4 |if(str != NULL){
+ |0 n6 ^# j0 \1 Istrcpy(str, “world”);9 Y' @% S" W' B8 {+ W3 u* i
printf(str);( K( k, d! t$ }9 P$ d+ f) w
}9 o& [: p5 X' n0 n
}* Y4 J, P j' x5 l0 S* J
请问运行Test 函数会有什么样的结果?3 Z4 C4 Y G9 f6 Z! y9 R) f3 _( Y u
答:输出“world”
3 n: M* S- q- M% Q(3). char *GetMemory(void){6 j/ Z9 r3 V4 w" |3 Z
char p[] = "hello world";# Y* D4 H9 x U. i0 F0 n
return p;' D3 g* D) H( l4 }7 X
}
( R, R1 c9 L5 x3 o Cvoid Test(void){
- b8 J' j% _9 S! n8 d* ]# l7 y: S+ I6 hchar *str = NULL;
# c( \: Z% T( ?( w& K: S) |str = GetMemory();8 w; d' t1 G, v- G3 z# M" ?
printf(str);- B7 m# u' l# m# M& S% o6 k
}( F$ [) n/ c1 G% K. K6 ~
请问运行Test 函数会有什么样的结果?, K+ p% Z2 @9 U0 E* `5 n
答:无效的指针,输出不确定
5 Q/ i( N3 Z& Y% Y0 n
) { \5 N/ c6 l! Z0 Y9 i5. 编写strcat函数(6分)
# r; \) M+ Y# N# L已知strcat函数的原型是char *strcat (char *strDest, const char *strSrc);& m0 @. \: O* [9 b
其中strDest 是目的字符串,strSrc 是源字符串。
3 L3 p5 e3 W N" |/ j% d(1)不调用C++/C 的字符串库函数,请编写函数 strcat5 ]0 m- o( f/ P
答:
, X4 R' N5 a# H1 `3 ?VC源码:
3 z. V) U3 N+ h: v1 f/ N% Schar * __cdecl strcat (char * dst, const char * src)+ l. i" H; c$ @: C4 i9 R# D! G# |
{
0 f+ z$ a' r/ ]2 }3 c T, ychar * cp = dst;% G0 {9 r' m* i2 u; w- W
while( *cp )
. d* A, }0 k: Lcp++; /* find end of dst */
. ~) e/ |6 B+ n( {6 u4 [* Xwhile( *cp++ = *src++ ) ; /* Copy src to end of dst */
! ?- X1 Z2 I6 |* k* }+ l+ [; Mreturn( dst ); /* return dst */$ h# R- Q' X' \
}6 F& a0 k$ q1 a8 I0 _3 }( p
(2)strcat能把strSrc 的内容连接到strDest,为什么还要char * 类型的返回值?
) J" O: P+ g2 {- x/ ^答:方便赋值给其他变量
- ] f. O* ^9 ?/ S/ g, L3 X
4 K& |4 X" u; Q9 ^6.MFC中CString是类型安全类么?" B5 k& o" V2 F4 q. j, E
答:不是,其它数据类型转换到CString可以使用CString的成员函数Format来转换+ B' R: x* ~- c$ u8 m
5 a8 l4 y% _6 e O
7.C++中为什么用模板类。
, _; N$ g8 u" J$ W答:(1)可用来创建动态增长和减小的数据结构
5 t7 o# ~6 D4 }& l# `3 f(2)它是类型无关的,因此具有很高的可复用性。
* _/ f; D1 p$ r% k5 x(3)它在编译时而不是运行时检查数据类型,保证了类型安全
/ z3 n/ A1 W& R+ I' U" C: o" k, G(4)它是平台无关的,可移植性
: X9 z. s; E9 j6 j8 _8 o# w(5)可用于基本数据类型% q& o/ F; ]1 V+ A) \
& A. ~/ y# Z8 o2 E7 ~8.CSingleLock是干什么的。
) e6 W0 d! F7 U1 z% S6 l7 M答:同步多个线程对一个数据类的同时访问# s3 X9 x% x$ y. b/ P- H' K
: @ @% y& `' s/ v" y
9.NEWTEXTMETRIC 是什么。
- l% x2 |" U, N1 l6 _3 E答:物理字体结构,用来设置字体的高宽大小
: i2 D& N$ |0 O6 t) o6 @# d* @! x8 R$ e) }7 a/ m2 y) {& i
10.程序什么时候应该使用线程,什么时候单线程效率高。
) ~$ \! K9 n+ {1 ^, n# m8 u答:1.耗时的操作使用线程,提高应用程序响应
# V* y8 c: h, e/ G2.并行操作时使用线程,如C/S架构的服务器端并发线程响应用户的请求。
3 }0 h" I! w; B8 R. d3.多CPU系统中,使用线程提高CPU利用率
w1 [5 s/ O; t. s4 J2 I) ~ B2 Z4.改善程序结构。一个既长又复杂的进程可以考虑分为多个线程,成为几个独立或半独
5 M3 {) {) ~7 U! [( ^立的运行部分,这样的程序会利于理解和修改。$ x# y8 X: [6 q
其他情况都使用单线程。! B* m: H Z% k) J! p1 r
5 k/ [! J' \$ Q11.Windows是内核级线程么。
% c: R3 e, c7 M/ V) b答:见下一题9 C" L% }6 h! [
9 M6 R9 b. _+ R" `* p: i7 A
12.Linux有内核级线程么。
- j% K& E0 M- y答:线程通常被定义为一个进程中代码的不同执行路线。从实现方式上划分,线程有两 c4 @/ I* b9 [4 a- \5 h
种类型:“用户级线程”和“内核级线程”。 用户线程指不需要内核支持而在用户程序
6 R- {1 m: q* X1 _5 e0 V中实现的线程,其不依赖于操作系统核心,应用进程利用线程库提供创建、同步、调度8 f! o- v1 B4 P6 e
和管理线程的函数来控制用户线程。这种线程甚至在象 DOS 这样的操作系统中也可实现
5 Q% ^; [ n5 x1 f. h7 T,但线程的调度需要用户程序完成,这有些类似 Windows 3.x 的协作式多任务。另外一
8 b; X! U7 Q6 ?" t% s种则需要内核的参与,由内核完成线程的调度。其依赖于操作系统核心,由内核的内部
7 t8 a+ y, _! b7 d: ?1 y需求进行创建和撤销,这两种模型各有其好处和缺点。用户线程不需要额外的内核开支$ P. A0 D. j$ i+ P8 y6 ~) k
,并且用户态线程的实现方式可以被定制或修改以适应特殊应用的要求,但是当一个线* ]4 ?2 O/ k" w- f0 J2 h9 K" l5 u
程因 I/O 而处于等待状态时,整个进程就会被调度程序切换为等待状态,其他线程得不& n- ^6 F- j" h: \- c! d, A. X$ A
到运行的机会;而内核线程则没有各个限制,有利于发挥多处理器的并发优势,但却占
4 G) i- g) M& v! d: L2 N' u用了更多的系统开支。
. W, q* J X* Q, ~5 n2 O2 @' c) IWindows NT和OS/2支持内核线程。Linux 支持内核级的多线程
9 \( N! f, h* s2 ?" z; O2 M6 ^$ S% Z
7 v0 w7 Q; G# C' [. H13.C++中什么数据分配在栈或堆中,New分配数据是在近堆还是远堆中?
5 g) |- m; h6 P/ u答:栈: 存放局部变量,函数调用参数,函数返回值,函数返回地址。由系统管理0 A& O+ H- ?1 ^, \
堆: 程序运行时动态申请,new 和 malloc申请的内存就在堆上
( R- H4 W: _, k
8 M: S) K8 v+ e$ R3 T14.使用线程是如何防止出现大的波峰。: b& E: k% ^0 I7 A; Z ^' ~
答:意思是如何防止同时产生大量的线程,方法是使用线程池,线程池具有可以同时提6 E9 N& j9 _9 x
高调度效率和限制资源使用的好处,线程池中的线程达到最大数时,其他线程就会排队' s `! W- U$ [$ \9 I. U
等候。1 |5 f6 t) P( W' f
; p! ` u4 M& l' K! U7 c15函数模板与类模板有什么区别?1 N- `) W6 ?7 Z% ?8 G4 A
答:函数模板的实例化是由编译程序在处理函数调用时自动完成的,而类模板的实例化
- k) P. O' W6 A; E$ R) i必须由程序员在程序中显式地指定。7 E' p' e E. c( e) R. s1 D. ^
1 h7 A7 ^" y# u+ g/ \. P
16一般数据库若出现日志满了,会出现什么情况,是否还能使用?' E( N( c8 f7 B+ C* o
答:只能执行查询等读操作,不能执行更改,备份等写操作,原因是任何写操作都要记
8 ]8 L F& p" c! g, G+ U+ @ Q录日志。也就是说基本上处于不能使用的状态。8 h: J$ e+ L0 s+ Z5 ^7 B- C9 q
' f A7 A9 T! ^ J' q: x! Q( L1 S17 SQL Server是否支持行级锁,有什么好处?5 u( a# t& w/ G- k" d ^
答:支持,设立封锁机制主要是为了对并发操作进行控制,对干扰进行封锁,保证数据
! B9 ]7 ]; g( B/ ?0 y( f的一致性和准确性,行级封锁确保在用户取得被更新的行到该行进行更新这段时间内不. Y6 Q2 v& p: ~# V+ G* N# m
被其它用户所修改。因而行级锁即可保证数据的一致性又能提高数据操作的迸发性。
* B% E) G. ?7 [6 S! M% }/ S
* C ~' u! o4 Z2 C; [/ J18如果数据库满了会出现什么情况,是否还能使用?
" t: Z# V Q: C' D+ m, K答:见16
, g- S* k4 E K$ }5 H3 Q( L/ t3 b
+ E7 f$ V, ^0 Z19 关于内存对齐的问题以及sizof()的输出
4 a# E$ }' D% f C答:编译器自动对齐的原因:为了提高程序的性能,数据结构(尤其是栈)应该尽可能/ c2 B8 e9 s, {4 ]0 }
地在自然边界上对齐。原因在于,为了访问未对齐的内存,处理器需要作两次内存访问
% D/ I6 i1 O+ \( M2 R! |# p% G;然而,对齐的内存访问仅需要一次访问。; q3 U4 I" T) M& P {% c# F5 C
, c* u: A( p, H1 N* p, @
20 int i=10, j=10, k=3; k*=i+j; k最后的值是?
' w$ u# R# E5 x1 X答:60,此题考察优先级,实际写成: k*=(i+j);,赋值运算符优先级最低
! Z" `% }9 f) B2 n) |% g……( ?9 \6 |! m) N
! U4 Z. X7 @) J, x! s5 Q
; d6 y* _4 H) L
7 ]" i2 @# ^: J) d0 A/ i7 B( {3 T+ N; j( l
$ Z4 t+ I# M5 C4 P! d- @7 y1 i9 w2 H
一些笔试题目和整理的答案 - 腾讯(Tencent)
6 l+ a$ t. n6 O% Y9 P/ k* {1 k7 k7 n
' p `# `+ {/ V/ T6 H* t2 U: G
NO1/ U% X0 C0 G; _+ O0 ^
Below is usual way we find one element in an array
1 v( f0 N8 u8 a$ o5 oconst int *find1(const int* array, int n, int x)) o3 q" b z c0 f9 ]
{# }. f& S1 p% A! j* [
const int* p = array;
' c4 U6 h9 q9 P- ~- E; a for(int i = 0; i < n; i++)
6 E0 V2 T& H9 X+ `5 D1 u+ x/ | {
( ^! g8 u! Q" c4 n/ a: d if(*p == x)% p+ e. i, ]- T* @0 a" Z3 P
{' }3 [) j% N5 E" n, E) x; N/ Y* A
return p;
5 B3 H3 R+ I# a5 U1 {0 @5 x0 i }4 g, ? w( I: i% F! W$ x7 I, l# D8 l
++p;
% j( y: k+ Q, O9 M6 k$ s, { }
c r! q- P0 r, \+ D/ N* k1 a return 0; }( C6 I+ L I# a' t0 k1 s
In this case we have to bear the knowledge of value type "int", the size of array, even the existence of an array. Would you re-write it using template to eliminate all these dependencies?7 z/ u' k V( U {, e) D
) V2 |4 d9 k9 M7 B
template <class T>/ E! ?5 T9 N" r% @
const T *find1(const T* array, int n, T x)
" z- ^4 t1 Z: \1 y U( h. J1 n{
: K ~- [5 j) n" ~9 x const T* p = array; o' q$ P9 C$ G; m
for(int i = 0; i < n; i++)" U3 y. I9 T2 X$ m; W+ W8 Z, c
{; S+ D; R; J8 Y3 c! n9 |
if(*p == x)4 o; `& ~( Z. g
{
: n, y( y8 |/ R, q" X3 v2 Z return p;) _1 K' N# b6 z5 M
}
e, N. P" I- O' T( z ++p;+ ?# l" C0 J# L& s1 l
}/ E$ N. ^0 |+ g/ R; l
return 0; }
3 T% r" @* m, ]! S/ e, A9 v, r* n- N ^
NO2
1 C; F% D, P- J" e; h( H" N! S6 o
Give an example of implementing a Stack in the template way(only template class declaration without detail definition and realization)$ M6 I8 u& L$ ]& H# n2 F
template <class T>, q" f2 T% [- r( ]% ?# }
class Stack5 R. w. U* A% Z$ x- _7 s+ U8 a
{
7 y% o6 B2 n$ H' m8 q& Spublic:, j3 b% S$ T" B. T
Stack(int = 10) ;
" B% z" o, t- Q& @3 m! O ~Stack() { delete [] stackPtr ; }! j6 H5 U# _: D8 k5 T# {
int push(const T&);
/ C( J" X$ @7 b0 R2 F int pop(T&) ; z* m5 T0 w% ?$ M' [, n" P8 v- a4 J
int isEmpty()const { return top == -1 ; } ' q4 H* y# U$ e9 T
int isFull() const { return top == size - 1 ; }
! X% ~# z# @" W: xprivate:
: {9 W H3 X7 f! t2 j9 e: ] int size ; // number of elements on Stack., b: [1 x: K) ]9 i- a
int top ; - @) @2 h2 L$ n
T* stackPtr ; 0 w' R: r- w3 [% W2 g; ~5 f2 c
} ;5 U9 M% e1 g. `# m5 K8 @1 O
/ |/ L) m$ h: H- g% r& d9 o' I0 `- a" M* `
NO3
& q7 R& w: q) w& Q# Q9 `3 U$ }: \4 ~: y
Implement the simplest singleton pattern(initialize if necessary).
* l9 }3 W$ \* b" M/ }class Singleton {
b( p# K# `' s% v7 u: {public: 6 z' N5 ]( s. u
static Singleton* Instance();
3 ^0 \/ T( ?' @: |5 o' l) lprotected:
' c8 O2 A, P+ W Singleton();, c6 L3 Z7 b# y9 A
private:
) M. `0 B" C- G7 j" t7 ^ static Singleton* _instance;4 J7 a- E. t/ W" P. F- V# k: Y! X
}* q( \/ v' o$ ?: k- j0 Z0 A% U
7 P4 G3 A7 C! ]* h& v* A+ L5 U9 E; x/ V
// Implementation
. Q! H. U( a7 `( M+ e$ @Singleton* Singleton::_instance = 0;
0 z* n7 l2 ?1 U- O- t8 f7 b9 U
) z4 P- P2 D1 h X, ~3 {Singleton* Singleton::Instance() {& j+ r7 j/ Q/ @3 o
if (_instance == 0) {- z0 s- F z. W& G9 Q) b/ e" J
_instance = new Singleton;# Z% r9 A& f$ g0 o) V( @! x, v
}' p4 R6 F1 a# J, S7 N$ F5 l
return _instance;
* b' g' ?5 ]: r/ r}
+ q- ~* \0 R8 t: u$ {4 [9 O
& d, I5 m: V! _' `* j
7 y" H' p4 R' n' S) R2 j
6 X+ S7 B* {4 h( ?9 l+ SNO4
0 u7 d) _* C6 F- i1 |
3 I4 q1 f- D& W7 w1.Jeff and Diamond like playing game of coins, One day they designed a new set of rules:. o5 w9 @" o7 ~3 B2 t( z1 r
1)Totally 10 coins
* O0 T) r# z$ v8 c2)One can take away 1,2or 4 coins at one time by turns9 o# X4 n+ R6 [ p6 x# E
3)Who takes the last loses.
7 K: g3 |9 i" CGiven these rules Whether the winning status is pre-determined or not
4 C6 k* Y2 }6 L- q) t
! y5 x) y6 \) G9 V* j, n
' Q' h1 k2 J% ~* U1:从后面开始考虑,最后肯定要留1个才能保证自己赢 d9 U7 }/ Z8 j3 L
2:所以要设法让对方留下2,3,5个& _% j* F) Y. }: D
3:也就是要自己取后留下1,4,6,7,8,9; j) b' G) g# Q( p4 ?
4:如果自己取后留下6,对方取2个,与(3)矛盾,所以排除6
! W) v" y1 S$ n# _# a3 x5 }5:如果自己取后留下8,对方取4个,与(3)一样情况,所以也排除8" t) T1 w) U( R) t
6:同样,9也不行,如果我抽后剩下9,对方抽2个,就反过来成对方抽剩成7个了,也与3)矛盾,所以也排除
' i2 V+ S; b: f7 P& C7:所以很显然,我只能抽剩1,4,7- T$ S' c* i1 Y' W K3 L1 C
8:因为只能抽后剩1,4,7才能赢,我先抽得话不可能达到这几个数,很显然,只能让对) z& Z. V% L7 x- k k) g( U9 G
方先抽,也即是先抽的人输
& f9 v9 k- B0 Y1 [ h
+ }6 w; H4 i1 s& ^5 @" G7 o+ Y腾讯2010实习生招聘笔试题(全套):http://bbs.aftjob.com/thread-606605-1-1.html
6 A* m! ^6 ~; b, u/ K2011年名企薪酬信息专版:http://bbs.aftjob.com/forum-37-1.html
4 h- D R2 v. m* Q f8 n+ H6 O9 A腾讯求职俱乐部:http://bbs.aftjob.com/group-47-1.html |
|