  
- UID
- 1
- 帖子
- 738
- 精华
- 28
- 积分
- 14221
- 金币
- 2401
- 威望
- 1647
- 贡献
- 1349
|
[Zend权威认证试题讲解]第十二章 -调试与性能管理
作为一个开发者,无论你经验多么丰富,或者无论你多么努力,你的程序中总会有bug。这是生命中一个必然的部分,如同死亡与缴税(尽管并没有后面两个那么严重)。
6 H# Z# P1 K6 K; W+ U' O要想解决bug,首先要能找到bug。事实上,许多开发者花费了无数小时茫然得盯着代码,只是因为他们没有把程序的容错能力摆在首位。忽略了这个部分,那么期望一个没有bug的程序就是——不可能的。) E, v- q# P. [* W6 u1 e* [! m% Z
本章测试题将考察你对调试和性能管理相关知识的了解,以及如何用PHP做好这两件事。
1 a0 o& R& q4 K/ W, ~' B7 @; X6 L: M
0 s1 d% a) q, h* Q问题9 Q1 _/ q2 U! t, ]2 t
* w2 x. w2 U% U4 @
1.以下脚本如何用三元操作替代?
4 N" C% u E; V/ ?2 G/ \& m-
- <?php
- if ($a < 10) {
- if ($b > 11) {
- if ($c == 10 && $d != $c) {
- $x = 0;
- } else {
- $x = 1;
- }
- }
- }
- ?>
复制代码 ! W/ W7 ?) a6 n
A.$x = ($a A. < 10 || $b > 11 || $c == 1 && $d != $c) ? 0 : 1;
' H& u) Z' A1 C1 uB.$x = ($a < 10 || $b > 11 || ($c == 1 && $d != $c)) ? 0 : 1;# f+ |$ C, d8 m# c- {
C.$x = (($a < 10 && $b > 11) || ($c == 1 && $d != $c)) ? 0 : 1;% C# c1 c; R: K) p6 ]" c! m" G
D.$x = ($a < 10 && $b > 11 && $c == 1 && $d != $c) ? 1 : 0;
& u/ k. h& B4 }- E4 s! dE.以上都不对 e- T! b! s* l7 F
, e1 X9 b8 d; {
! p: N% K5 ?; x6 D6 ^7 U) e2.有一个脚本由于要从远程获取数据,因而运行速度很慢,以下那种方法能对其进行优化?(双选)
+ G' ~+ I6 M y+ _% S F
/ v' Y% M8 u4 e, h& EA.安装操作码缓存(opcode cache)
! \& \* u1 X) J. F) qB.优化或者升级你的网络连接& ]$ M9 h% d0 a3 p
C.添置更多的硬件# {- g3 Y1 k% K* s! j
D.增加服务器的可用RAM' B+ O' x/ z/ l( Y) `5 {5 h9 w" \
E.使用连接缓存
$ S! V$ \% W* n) z5 `
# q4 X/ _# [- D0 z) Q/ A l: N( d
! U6 X; R: L8 m3.架设生产环境下的服务器时,需要做哪些步骤?(双选)
4 o% g0 a7 y: G+ S& a5 Q
0 x1 x/ s4 o' k' u3 XA.关闭错误报告
4 D% N3 i3 J' \+ `) U( U$ N: A2 aB.打开错误日志
9 P- p3 c/ N$ V+ [C.关闭错误日志
' G3 I# {4 I& x( T$ t( f4 RD.关闭错误显示1 k4 P( G& Y5 e1 @, N
E.使用@抑错符
5 J) K: L% W2 S$ Q- u5 C/ O( _" @0 D) t/ T* v
. M" O0 O4 c: a0 I+ @! I& ]
4.______操作符能对操作数的数据类型进行严格的比较?9 d. d( b$ |# w, K
- [7 w$ Q7 i1 f1 U* X" ]9 T% ?' m答案:____________
5 x4 Z: p$ g6 ^ _) I- v+ w, K9 J- g! T0 {( C0 v
2 c" Y. \6 |6 Q$ c: v1 g( E! D5.操作码缓存(opcode cache)能做什么?9 t. t) J. s. W1 S* _
/ {; |7 K, F( J; R2 {A.把脚本编译成二进制对象,使它运行得更快
& X- U8 E$ x# [* M# T1 y3 DB.代替Zend引擎加快解释器的运行: s, ?1 w7 v0 g- _4 V+ J
C.缓存脚本输出以提高执行效率
, ?9 S2 b4 F/ q- y6 UD.缓存解析器产生的中间码,以提高运行效率
5 ?3 w1 ?% u9 Z A/ i* \E.在内存中缓存脚本,减少从硬盘中读取的次数
9 o2 E/ g I9 j8 c1 m- Z; j$ c7 _
2 X5 k( ~3 d6 X
6.以下哪些情况容易造成系统资源枯竭?(双选)
! I, ~$ v2 h' M4 `, Z+ o. w& H* y7 d# b5 @5 ^0 f
A.RAM太小0 g5 m7 Y8 {. o1 }' O! N
B.使用了低带宽的连接
# t1 I# ~ T& K) SC.虚拟内存超过2GB
( W+ _& `4 i$ r/ b5 t+ mD.允许同时运行太多的服务器进程
* y- v# L: h+ b1 k! vE.以上都不对4 L0 q9 w( G$ ]$ P3 \
6 t- [# W9 r8 P# g
9 p# H- l! w( j# ^4 @
7.以下脚本缺了些什么?(双选) 0 T: @; v8 S7 O/ x r$ K
-
- <?php
- $rs = database_query ("select * from mytable where id = " .
- $my_id);
- while ($a = database_get_data ($rs)) {
- var_dump ($a);
- }
- ?>
复制代码 - X" S, u- ?6 Q8 ^( g5 I2 O& m: z+ C
A.参数出口(Parameter escapement) J2 h6 t0 y0 `2 H
B.输出格式化
0 w9 W. ?! T. kC.错误检查
" Z) E4 e8 ^. h! E" K* SD.一个SQL查询9 ~! t* P0 g6 M# W2 P
E.以上都不对( @$ {" y7 Z# @" s4 R
% m2 g0 K9 U% q- B! D3 \- v& B* x! h& U4 z' D
8.以下那种错误类型无法被自定义的错误处理器捕捉到?(双选)
* |7 ^& l" M' `$ T) m% v5 M# o. e$ l% y* b( ]9 ?
A.E_WARNING3 M4 w" r% t/ S
B.E_ERROR* m4 q- J& u; p9 P
C.E_USER_ERROR
/ {, A2 o! n% K( B DD.E_PARSE
! O, W u! ]! g3 \E.E_NOTICE
; l+ _1 x: U3 _- o5 b) s& Q7 x
% q2 O+ ^. }/ L0 U4 p
. h& L2 r& s; R! W9.当需要比较一个常量和一个变量时,如何才能保证不会错弄成赋值?8 B( U' K. p6 F2 f2 A1 ^
( L8 o6 a; D1 N; o x9 a: F
A.把变量转换成int* `9 ^6 Y. ^0 L( e' Z, G9 Q$ T- y
B.使用全等比较符(===)
2 M8 h% o+ ?2 P# i( r7 y* V% ^C.确保常量是第一个操作数1 [. `0 [& [) W4 s/ d9 q- b
D.使用三元运算符
2 B+ S4 c6 d! f" K# r5 P, x# pE.用括号把操作包起来
7 D, @) Y' U/ W- h9 n
- C; s0 k4 e+ V. ]
X. {( \% K+ A7 F10.要通过邮件给系统管理员发送错误信息,以下那种方法最简便?% O5 w9 c9 x9 L) b/ ~3 p* T
' q Y6 X6 i- b: F! M7 M* rA.创建一个连接远程SMTP服务器的函数
& s7 L+ ?3 e& g6 J' g1 TB.使用mail函数3 Y0 E) r8 U3 U/ Y5 z) \; w0 c' Q6 E
C.使用error_log函数
1 x, Y1 W$ U0 q/ g/ w" ^1 @* \D.调用sendmial程序
: m& J' m* Z( Y, F5 ?- {! ME.使用webservice+ E9 f- u* ?1 B$ j) X
3 B, `, E& X7 L2 i% m" ~. C
8 @. j& D+ O7 C; z: W
11.能否仅调用一个函数就关闭脚本内所有的错误报告?1 u/ U5 @' h7 g7 n' I& U, s/ C B
* c# |/ _, p( Q: d2 ]A.能
& U' C4 A$ q. }7 F. iB.不能5 _ t0 P2 J3 G+ v o8 `
4 r7 x7 H; Q8 R$ W5 T* `5 O0 |4 ~( j( m% z
12.概要分析器(profiler)是做什么的?
w0 b C9 m0 P2 i% d- I' r
+ |$ k* v+ i$ p% S$ E& U% uA.创建关于脚本结构的档案9 p" e4 V3 Z8 I P/ ?' B/ ~
B.把脚本转化成UML图, j$ r ~3 N; T j _7 g0 u+ D/ R
C.精确测算脚本不同部分的运行时间
7 m0 j% P4 R8 V8 WD.计算脚本通过web服务器执行时的维度5 W% [: C. {) A/ x( k& W- J
E.扫描脚本,识别由常见错误导致的bug
" {4 L8 p6 Z. J9 S1 G9 @/ I- P
3 d. m' S! o2 N' m: M4 h6 R
4 y+ o3 b7 D1 D/ v8 R1 D13.______能帮助识别和解决bug。$ C, f1 n4 v% J* b
$ A) v1 y8 V* Z9 g) T0 z. N8 f8 O' `答案:____________
( z( f" Q; l0 R0 u) V N! O1 F$ }# f: _9 P* n4 y, ^1 g- O7 x- Q
# {- V! q- v4 h& U4 x14.trigger_error()和user_error()有什么区别?
6 b# ?. d4 N* B1 _6 x: t" m! N$ c0 p1 Y
A.trigger_error()允许脚本抛出系统级的错误
# r# m) {5 E; kB.user_error()允许脚本抛出系统级的错误
- M. k& ^$ v" G5 a* tC.user_error()不能被用在错误管理器中
8 ^4 i0 v- `+ aD.trigger_error只在PHP5中可用/ r- c- c& W2 e! t0 Q& u; H
E.没有区别5 Q# H8 g7 O7 m' {" x1 l7 _5 q
, S5 @+ ~8 @& }2 [
4 Q( N0 |6 z7 r( K
15.______函数能返回脚本里任意行中调用的函数的名称。该函数同时还经常被用在调试中,用来判断错误是如何发生的。. D- t; g, M4 |$ N1 E4 C
6 K4 w7 Z3 m& J b8 J6 d% P/ W+ r
A.print_r' Q! A5 {- O+ a) v) D: R1 G9 s
B.var_dump+ x8 s' [ p! G; d' u2 x6 B" q7 v- i
C.stack_dump6 B: u+ H( ^+ ], H- ?
D.debug_backtrace) ~( P' E, M( H, {
E.以上都不对
% b& V/ U6 v$ x- y+ _1 p, Q0 \' Z
答案
; [5 d9 A* @, \# h& n! S7 C. ]( } F* X: x8 i+ ~/ u
1.答案是E。三元操作符把每个if语句连到一起,作为&&操作的一部分。然而本题中,$x=1这个赋值只在第三个if为false时发生。如果第一个和第二个条件都不成立,$x=1就不会执行。这题对三元操作的应用有些极端,实际应用时,需要根据可读性来决定是否需要用三元运算符(本题这种情况就最好不要用)。
+ R: R4 z" {& Y) k* r& `$ {4 ]0 m
2.问题是由第三方数据源传输缓慢导致的,而你无法控制这个数据源。你也许能在网络连通性上做些工作(假设问题出在你这一边)。还可以对接收到的内容进行缓存,这样能减少获取重复数据的时间。因此,答案是B和E。
% g* |* L- a) \& L" z5 k' y: f. K8 `7 `& q: e" I! @- T0 `. D& s ]
3.正确的选择是B和D。如果关闭错误报告、使用@抑错符和关闭错误日志,那么在你交付给客户的网站出现问题时,你将很难进行分析和调试。
1 P1 n: [0 g' n0 x* d
- v( t u- K7 ~; g2 ?/ n4.这是在描述===操作符。 {2 w5 u4 h) T: @
& U' [! s, V6 e/ m( l7 l5.正确答案是D。PHP脚本在执行时,将首先被解析成“中间”码(也叫opcode,操作码),然后解释器执行。操作码缓存出现在这两个步骤之间,对解析器的输出进行缓存。下次执行该脚本时,将缓存的输出直接送入解释器。这样就就不需要再解析一次了。
% Y; O4 l" U, d1 ~1 K& ]' a$ x s' G1 @" [
6.正确答案是A和D。如果RAM太小,进程间将出现资源竞争,服务器将大量使用硬盘交换。同样的,如果允许过多进程同时执行,也会使服务器频繁进行交换,导致速度下降。
" j( J7 [ T* N" T) Y, I4 S
7 |* ^+ l5 c1 Y! h6 Z8 ~7.正确答案是A和C。脚本不检验datebase_query()的调用是否成功,因此将持续执行下去,最终产生错误。此外,$my_id参数没有转义——可能导致代码注入(详见第11章)。
" B5 b- `% {! R4 {! {5 h9 I. J% Z) Z) ~ K! \$ F
8.答案B和D正确。出现解析错误往往表示脚本中有语法错误,自定义的错误管理器无法捕捉到它们的原因很明显:错误管理器在脚本里,而现在无法解析脚本,管理器也就无法执行。类似的,E_ERROR表示有致命的运行错误出现,比如内存耗尽。因此脚本会立刻被中断,因为解释器无法执行后面的代码。
0 R( T1 C2 F, u ?3 D/ @4 ^$ K0 s
, g* K9 L& H: D8 y; i9.答案是C。比较操作是一个可交换的操作(就是说结果独立于操作数之外),而赋值不是。因此,比如说,$a==10和10==$a是等效的,而$a=10和10=$a却不是,而且后者会导致一个错误,因为这不是一个合法的操作。确保常量在操作符前面,能保证你不会错误得将比较变成赋值。: o+ ~% a0 W" F/ G' _; }
2 M9 n# {5 O) I5 P5 h10.答案是C。error_log函数能将信息送往一个指定的地址。尽管mail()也可以用,但error_log能自动给邮件添加标题,因此这才是最简单的方法。
/ o( t/ z% B3 j# P& L, K% a
+ ^ d1 N \1 R2 B3 p6 W2 b. R( I11.答案是不能。error_reporting函数能关闭所有运行时的错误报告,但对解析时的错误无效,因为解析错误发生在脚本执行之前。
1 ^7 @2 h# X5 u! ?: c% ]+ X6 `. ]" l- ~, T& ?
12.显然,答案是C。概要分析器(profiler)能监视脚本的运行,并记录单个部分的运行时间。它可以用来找出和解决瓶颈。. {2 c) e$ W! G$ H5 V! T; N
2 ~5 ]& @2 n Y0 o* Q13.这是对调试器的完美定义!你可以用调试软件监视脚本运行,同时分析系统资源消耗,从而发现和解决程序缺陷。
3 i6 r) T3 O2 h+ B9 Y$ T9 d. ]/ M r R6 e
14.trigger_error()和user_error()之间没有区别。后者其实是前者的别名。$ h" N+ G* a" a0 G1 R
0 l% H# l( ~6 Q7 G
15.答案是D。题目是在描述debug_backtrace函数,它返回一个由所有在代码的特定位置调用过的函数名组成的数组。 |
|