返回列表 发帖

[Zend权威认证试题讲解]第十二章 -调试与性能管理

作为一个开发者,无论你经验多么丰富,或者无论你多么努力,你的程序中总会有bug。这是生命中一个必然的部分,如同死亡与缴税(尽管并没有后面两个那么严重)。8 j6 b/ c# B8 T
要想解决bug,首先要能找到bug。事实上,许多开发者花费了无数小时茫然得盯着代码,只是因为他们没有把程序的容错能力摆在首位。忽略了这个部分,那么期望一个没有bug的程序就是——不可能的。% q( P0 n$ R9 L; N
本章测试题将考察你对调试和性能管理相关知识的了解,以及如何用PHP做好这两件事。
" z; C7 S! s% y/ |/ |& i3 l1 E
5 i. t, J& r1 X$ E" O9 D" v) D; ]
7 ]( @7 p1 x9 a# x; \. s" _问题
- ~+ z0 e) q5 l4 c
3 Y7 t* Y6 U6 n- p8 E0 L' g1.以下脚本如何用三元操作替代? . u. L* _, D6 B6 }8 G& U

  1. <?php
  2. if ($a < 10) {
  3.     if ($b > 11) {
  4.         if ($c == 10 && $d != $c) {
  5.             $x = 0;
  6.         } else {
  7.             $x = 1;
  8.         }
  9.     }
  10. }
  11. ?>
复制代码

1 R: C# ~/ H* vA.$x = ($a A. < 10 || $b > 11 || $c == 1 && $d != $c) ? 0 : 1;, O: `; \9 ?+ h( \3 B) I. w- c
B.$x = ($a < 10 || $b > 11 || ($c == 1 && $d != $c)) ? 0 : 1;! j) {) B, w4 M' N3 h
C.$x = (($a < 10 && $b > 11) || ($c == 1 && $d != $c)) ? 0 : 1;
; n4 k; m5 g, A( pD.$x = ($a < 10 && $b > 11 && $c == 1 && $d != $c) ? 1 : 0;1 L: K5 v6 i3 j! `
E.以上都不对
) L( G2 z4 v; c* z0 R) ?% i" t( g+ J7 ]1 ~9 n. J6 j1 [

* J6 S+ ]- B6 M) X# @2 \2.有一个脚本由于要从远程获取数据,因而运行速度很慢,以下那种方法能对其进行优化?(双选)
! D1 O  h3 I8 y1 d
1 V$ @- y1 P+ L1 n) B, Y  CA.安装操作码缓存(opcode cache)( I/ t5 A0 u# A& [, {
B.优化或者升级你的网络连接" F- U( l- Z3 R$ A5 s9 m9 l
C.添置更多的硬件. V" C# V: C; V7 S4 P+ m
D.增加服务器的可用RAM6 o* Z; ~; `4 o" Y9 q9 N: s
E.使用连接缓存
5 G' P* ]) H( w8 q2 ]) Z# F$ t: C0 v5 Y# w/ ?- n
# v5 _( y: p  ~7 c4 C( v  N+ I5 X2 d( W
3.架设生产环境下的服务器时,需要做哪些步骤?(双选)
4 a( `( a* X: l5 g. M
* g) `: A0 d; [; X! {A.关闭错误报告
& L+ z" V7 j" s+ C: U1 w# kB.打开错误日志
( P$ x3 g' o6 O, e0 xC.关闭错误日志! O) y. L9 }7 m7 W* P4 @
D.关闭错误显示$ g; M/ e/ {% K$ g0 i" ?8 G
E.使用@抑错符) P. m4 b, G! F* u3 F
/ F" v. F) L4 W3 C

" m# a9 R+ h- q4 {3 _4.______操作符能对操作数的数据类型进行严格的比较?( V. A/ p# ?$ O
1 r5 x  l8 X* h) a( O
答案:____________; x$ }$ c. g: g9 j
- U4 a- d. U; N4 A2 y5 Z

) r7 D1 j. U. U2 g& M1 X5.操作码缓存(opcode cache)能做什么?) s% y, v3 k7 s- e$ k* c& b7 Z& [! [7 Q
6 O5 P- |1 e7 g
A.把脚本编译成二进制对象,使它运行得更快2 R, [& y7 R& q; {
B.代替Zend引擎加快解释器的运行
- A: Y; V5 v- i) b- M  T, z1 F9 JC.缓存脚本输出以提高执行效率( @) V7 ?' n# i
D.缓存解析器产生的中间码,以提高运行效率
0 D6 Y; ~9 b% n, u- ?- [4 rE.在内存中缓存脚本,减少从硬盘中读取的次数! K, Y" D6 v$ E* T! A0 u  a. e4 K
2 t$ q, Q/ L& N
) l# @- \: p) C4 l# a
6.以下哪些情况容易造成系统资源枯竭?(双选)
- k* @; @! t- V  ]* i3 a
( s/ S( j5 c1 G6 EA.RAM太小
# o  j+ K$ Z' u) n, ZB.使用了低带宽的连接- p+ O3 q1 ^/ M# U8 ]* E
C.虚拟内存超过2GB; M4 n" k! V# X. j# H
D.允许同时运行太多的服务器进程
+ L. X5 k) [. y$ a; H/ mE.以上都不对5 B2 I3 U0 a( t; ?6 S% |
' {! F  W1 D) E. r! r5 D; K0 N

6 {' ?, [6 F, f( n7.以下脚本缺了些什么?(双选) 6 B* o3 y  l/ a4 x% f: t1 j

  1. <?php
  2. $rs = database_query ("select * from mytable where id = " .
  3. $my_id);
  4. while ($a = database_get_data ($rs)) {
  5.     var_dump ($a);
  6. }
  7. ?>
复制代码

* d9 k( M5 L5 @0 F( t( l! L% z; \A.参数出口(Parameter escapement)
  R3 V! |, x. t2 n/ ~3 ?1 K! mB.输出格式化
( ?. ^" T2 ~8 n0 x) m- {# C+ @5 tC.错误检查
: Z) I! y( C' ^5 L: [8 ]8 {D.一个SQL查询" K& `2 y$ Q( T, \
E.以上都不对0 @; x0 a, [8 b) G, D2 J
, o& }) x9 T5 k) N

" E# d9 t5 i+ o  a4 x8.以下那种错误类型无法被自定义的错误处理器捕捉到?(双选)% f! j8 Y0 p: X% g$ `
% F6 H7 ~0 C" g, ?: S; L0 y
A.E_WARNING: o& `/ m9 g! P6 c2 t( n7 A4 R- w
B.E_ERROR4 \: s8 ~, F- R
C.E_USER_ERROR7 D: M! F/ P7 [# _5 |! L
D.E_PARSE% m1 z# d, a, P% ~) D" m2 D/ G
E.E_NOTICE+ A; S0 N. d+ x! J( n; v* j- k, P

3 R7 p2 _2 R* P: {& E
9 Q( N) C2 e0 t9.当需要比较一个常量和一个变量时,如何才能保证不会错弄成赋值?
. r7 @8 \2 N0 J0 }: G, m: u- ^" W" B. n$ w" j0 D
A.把变量转换成int
+ Q7 A- o: a4 D, p0 o. X4 eB.使用全等比较符(===)
. t$ w% E6 t3 {/ XC.确保常量是第一个操作数) M# C( I/ }) k/ J# N1 P
D.使用三元运算符
. s) k* v+ f; d1 CE.用括号把操作包起来
4 G# F- f  w3 F3 U* O
9 n0 F$ x; R- j3 E+ O' T
$ ^. [3 H) ~% t% F! v4 L4 h" d6 V+ l10.要通过邮件给系统管理员发送错误信息,以下那种方法最简便?
$ B5 m( z: R4 _& [! e2 J8 c; P% }* X. ^/ ?8 |& k: C7 y& Z5 x0 V
A.创建一个连接远程SMTP服务器的函数; b/ b1 x9 B5 |) y* r  U
B.使用mail函数0 D6 M* C( M7 a- J5 L
C.使用error_log函数
# ~( N3 S+ F; |$ B" ?: A6 i' TD.调用sendmial程序& }3 c8 ]6 D( L% I3 u2 ?
E.使用webservice
' F# a% f/ ~0 y3 b5 w/ a2 H  C* V3 l! `+ l

+ ]3 G$ I5 x) F5 S) h11.能否仅调用一个函数就关闭脚本内所有的错误报告?1 O& y+ P& t! T1 {. a" e- }/ S; V+ w1 E& P
% J/ n9 [* }8 L& C
A.能0 P- X9 e% w  G+ k
B.不能
) G" W8 x9 a( t: w' D2 ^
1 |. |$ p3 _6 k  T5 Z
. Y) s% s1 p" x  N$ ~12.概要分析器(profiler)是做什么的?
2 e6 z7 p0 \% L! Y2 e$ i
% g, L$ y) t' L8 `9 ZA.创建关于脚本结构的档案' k8 S2 `. y) H$ c& t8 X' R8 C
B.把脚本转化成UML图# y  a/ E7 ^5 B; m4 N4 A' \
C.精确测算脚本不同部分的运行时间( t! A5 B4 N7 w* H% @! Z
D.计算脚本通过web服务器执行时的维度1 o3 \9 J$ [4 w
E.扫描脚本,识别由常见错误导致的bug, r! V+ s! b4 P4 Z9 h+ W# U9 S

# f! X% @6 Q" ?% R. d
! g; L  x& k) B2 `7 G4 v13.______能帮助识别和解决bug。; T% M, Q5 c1 ]8 u
8 v/ D4 j  k1 D5 y6 g
答案:____________5 b/ l+ a+ m! \7 d) f9 u

- N& y9 r# f, F2 E0 D
% w' i& \% H9 z7 J2 o% W+ n) J14.trigger_error()和user_error()有什么区别?
1 |% K/ A" H" J4 q6 L% u# o8 a
4 T5 G/ J' ^" d& Q( b1 ~0 q& Z, MA.trigger_error()允许脚本抛出系统级的错误
/ @- m2 d' [: P; q: J& q) i% [6 cB.user_error()允许脚本抛出系统级的错误. A  f7 X0 ]- s3 B1 X' L, ?6 P
C.user_error()不能被用在错误管理器中/ J* Z7 w) x7 o8 g' u
D.trigger_error只在PHP5中可用
8 g$ X! w  y5 N3 jE.没有区别
7 j) u' s/ u; A5 U. R' Z. I9 d+ P  B" p  \8 h5 o3 b/ ~

' O! ]" \( ~, w/ F2 s' l15.______函数能返回脚本里任意行中调用的函数的名称。该函数同时还经常被用在调试中,用来判断错误是如何发生的。  r: `$ o* W3 y2 ]
  g, p) U% K2 q
A.print_r1 @  Y# `% C' N) R
B.var_dump
1 b8 D0 E3 k$ Q3 S. A9 jC.stack_dump# y  X6 Q, a+ u4 m
D.debug_backtrace
4 U8 a5 H9 D/ F% s5 ME.以上都不对) ?4 J6 [( [# j$ n7 ]
( P2 g7 E$ b" I3 w1 D
答案
0 ?1 k# m8 E) `9 T( h/ @" p  z  N7 `# |# N0 j$ k; G6 E  N) x
1.答案是E。三元操作符把每个if语句连到一起,作为&&操作的一部分。然而本题中,$x=1这个赋值只在第三个if为false时发生。如果第一个和第二个条件都不成立,$x=1就不会执行。这题对三元操作的应用有些极端,实际应用时,需要根据可读性来决定是否需要用三元运算符(本题这种情况就最好不要用)。) v1 J  k( @( D
8 ]- n, j, T& v, b
2.问题是由第三方数据源传输缓慢导致的,而你无法控制这个数据源。你也许能在网络连通性上做些工作(假设问题出在你这一边)。还可以对接收到的内容进行缓存,这样能减少获取重复数据的时间。因此,答案是B和E。9 y7 W9 V0 ?% {5 C
  u, k2 @. t: J7 \/ C
3.正确的选择是B和D。如果关闭错误报告、使用@抑错符和关闭错误日志,那么在你交付给客户的网站出现问题时,你将很难进行分析和调试。" a" Y* I% e) M+ o9 @( n

0 V& F; ^/ |( K* _$ i. R' s) n' b4.这是在描述===操作符。
4 G) p) Y, Y5 }! j! W& J  n0 M( T5 z/ x# d5 A" K. Q' N
5.正确答案是D。PHP脚本在执行时,将首先被解析成“中间”码(也叫opcode,操作码),然后解释器执行。操作码缓存出现在这两个步骤之间,对解析器的输出进行缓存。下次执行该脚本时,将缓存的输出直接送入解释器。这样就就不需要再解析一次了。: S* y  ?# @$ x& H$ b

) v, d3 b& v+ I+ Z3 l6.正确答案是A和D。如果RAM太小,进程间将出现资源竞争,服务器将大量使用硬盘交换。同样的,如果允许过多进程同时执行,也会使服务器频繁进行交换,导致速度下降。
6 l1 n# h; h: R% W# _6 D) D+ u6 E5 X' g* @" F' n+ R. w: L+ Q
7.正确答案是A和C。脚本不检验datebase_query()的调用是否成功,因此将持续执行下去,最终产生错误。此外,$my_id参数没有转义——可能导致代码注入(详见第11章)。
. k2 Z* R) ~4 M+ |. \/ s4 |, {; f) E9 O, W# b
8.答案B和D正确。出现解析错误往往表示脚本中有语法错误,自定义的错误管理器无法捕捉到它们的原因很明显:错误管理器在脚本里,而现在无法解析脚本,管理器也就无法执行。类似的,E_ERROR表示有致命的运行错误出现,比如内存耗尽。因此脚本会立刻被中断,因为解释器无法执行后面的代码。- |3 s; R" E8 _( V/ y- K6 {; k

" f3 A+ {. U+ y7 K6 I9.答案是C。比较操作是一个可交换的操作(就是说结果独立于操作数之外),而赋值不是。因此,比如说,$a==10和10==$a是等效的,而$a=10和10=$a却不是,而且后者会导致一个错误,因为这不是一个合法的操作。确保常量在操作符前面,能保证你不会错误得将比较变成赋值。+ ?. d- b8 J& u9 m- Y

' v/ R- ^5 v& G: Q3 J) i2 j2 b! I10.答案是C。error_log函数能将信息送往一个指定的地址。尽管mail()也可以用,但error_log能自动给邮件添加标题,因此这才是最简单的方法。
* z# `! j5 m0 [0 t) ~0 q+ S# B
1 s# U, e. Q/ x11.答案是不能。error_reporting函数能关闭所有运行时的错误报告,但对解析时的错误无效,因为解析错误发生在脚本执行之前。6 j! f, I! o8 \# C! `* O  R
1 N& E- a2 ]. O) T% b! b
12.显然,答案是C。概要分析器(profiler)能监视脚本的运行,并记录单个部分的运行时间。它可以用来找出和解决瓶颈。; ]/ K- t3 t% L( m9 d

/ g( g9 X& t  a- Z% A9 M; l13.这是对调试器的完美定义!你可以用调试软件监视脚本运行,同时分析系统资源消耗,从而发现和解决程序缺陷。. f4 b- d) R0 t( R0 Y( q

$ u. F5 P0 N2 c0 ]8 v; s/ h2 a; f$ |% h14.trigger_error()和user_error()之间没有区别。后者其实是前者的别名。
5 j# ~3 @7 l5 H  s/ [& C6 A
7 k/ N) X: X- O' ?, @15.答案是D。题目是在描述debug_backtrace函数,它返回一个由所有在代码的特定位置调用过的函数名组成的数组。

返回列表
【捌玖网络】已经运行: