返回列表 发帖

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

作为一个开发者,无论你经验多么丰富,或者无论你多么努力,你的程序中总会有bug。这是生命中一个必然的部分,如同死亡与缴税(尽管并没有后面两个那么严重)。
( x4 K2 Q6 a; ?  ]要想解决bug,首先要能找到bug。事实上,许多开发者花费了无数小时茫然得盯着代码,只是因为他们没有把程序的容错能力摆在首位。忽略了这个部分,那么期望一个没有bug的程序就是——不可能的。! c' E* ^" k$ }
本章测试题将考察你对调试和性能管理相关知识的了解,以及如何用PHP做好这两件事。
, r1 U' j- N4 u: ~$ }  r2 E: W( c4 S$ ]# A. r: s1 J0 Q
7 w( y0 _% Z/ b$ f$ s
问题
2 `; g! g- Q' z  C! ^  Z) w
9 W; d: q( e6 o, Y. p1.以下脚本如何用三元操作替代? . Y) B, _+ b# @2 @

  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. ?>
复制代码
3 J" I' K! e2 ~# k9 S
A.$x = ($a A. < 10 || $b > 11 || $c == 1 && $d != $c) ? 0 : 1;7 G9 |4 [6 |% D& c* d
B.$x = ($a < 10 || $b > 11 || ($c == 1 && $d != $c)) ? 0 : 1;) R" }, p- B" a) T; p7 Z( X. W# f
C.$x = (($a < 10 && $b > 11) || ($c == 1 && $d != $c)) ? 0 : 1;: o* T. C$ ~9 P% J
D.$x = ($a < 10 && $b > 11 && $c == 1 && $d != $c) ? 1 : 0;
; O: a" E2 }5 kE.以上都不对) x" F% s7 O2 T
" J5 {" w5 C; O5 {& c* H
8 o- ?, H1 x' @
2.有一个脚本由于要从远程获取数据,因而运行速度很慢,以下那种方法能对其进行优化?(双选); r2 q( Q& [. @2 X: b1 Y$ y# G) m

3 B4 {( |* O* wA.安装操作码缓存(opcode cache)
/ O# P! s2 T, ~4 oB.优化或者升级你的网络连接
: Z0 Z/ \/ z& _1 j. i, J. S- ~1 T6 S+ \C.添置更多的硬件
+ a( o8 [- i0 a2 O8 {7 ND.增加服务器的可用RAM
( M, I4 c2 R( S! r1 [- Y' TE.使用连接缓存
/ W# i2 X; e" d6 |
' h" g5 q. X  V) R. p4 s8 z
: }3 C% ~; A# y3.架设生产环境下的服务器时,需要做哪些步骤?(双选)
! Q5 Y* h  Y" m3 P. O
. g9 I- P' s; J- f" R( \A.关闭错误报告
' @% [- L9 d5 l" v6 K$ N! rB.打开错误日志, _( ^  R2 G* d. w8 `6 z4 G, ]
C.关闭错误日志3 r& F4 r9 b" ]+ d. j( h- G
D.关闭错误显示0 Q; j1 d' R8 K+ h
E.使用@抑错符
' M3 f+ u0 x) F- ^* a' w1 C
+ d& c  d5 _" D1 R/ W
+ _6 b6 z4 G# Q# B2 l9 W5 b4.______操作符能对操作数的数据类型进行严格的比较?
! V! J: O5 [8 T9 |( A5 w5 G1 a( ]5 |# H* r# Y: H, ^
答案:____________
: f2 p- A) @$ T! t+ _, t( C* E6 M9 w: I4 L6 y6 o: z" i

' L2 Q5 R3 [/ ~' ?* s) R' Q5.操作码缓存(opcode cache)能做什么?6 B. Z6 K$ f4 }" H. O, `
( o% e+ N1 i- B/ Z0 w3 W6 D
A.把脚本编译成二进制对象,使它运行得更快
; Q, P* \) d" v6 JB.代替Zend引擎加快解释器的运行/ u5 Q) u" _, I" }: ]0 b. _4 Q8 U
C.缓存脚本输出以提高执行效率2 l7 n# p0 @! P
D.缓存解析器产生的中间码,以提高运行效率
; C; K" x) \+ Q7 x& Y2 ]3 g; ZE.在内存中缓存脚本,减少从硬盘中读取的次数6 @% D7 @5 y- o# \: ^

( a% M. K$ k, }& R0 K! h
3 c: h- y2 x$ C; U8 U6.以下哪些情况容易造成系统资源枯竭?(双选)1 L7 l9 m& h+ c$ q, M

  w& [1 q: [7 XA.RAM太小
4 I+ u' R; p( S; lB.使用了低带宽的连接& \' K/ B8 x3 y4 V1 w% Z* ~
C.虚拟内存超过2GB3 a3 P- b8 j+ a
D.允许同时运行太多的服务器进程% m5 ^/ ?  x9 L; h8 q
E.以上都不对% r7 |4 `$ ?2 c6 n' `8 g

3 i0 g2 }3 f) ~. w5 K6 y% G& y; C
7.以下脚本缺了些什么?(双选) 0 N: }4 F& W, b4 y" O- i0 E% Q

  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. ?>
复制代码

$ i" Q# U! k. U- m  m$ PA.参数出口(Parameter escapement)
& j8 j- u  C% ]$ I2 U8 S4 p" f; @B.输出格式化
2 z* r" y/ O8 [: _6 X3 S& lC.错误检查: d7 t1 H5 \# _0 m& T' L
D.一个SQL查询
. Y' w4 a7 y0 v, u0 d4 m9 \4 hE.以上都不对4 j& _8 G* F! i) {

$ A; ~9 Y' `2 G9 }1 U- E" V, c+ i+ {- S
8.以下那种错误类型无法被自定义的错误处理器捕捉到?(双选)+ \! J3 N9 m7 A! H, m

8 T. [9 O4 Q. u7 H) jA.E_WARNING
! ?& c& x$ [! ?! L) }2 s8 M2 MB.E_ERROR: a" Y2 n4 h8 a3 [; y' h' D9 J
C.E_USER_ERROR- L6 k, C  ~; x7 g  C) M1 }
D.E_PARSE# |5 P& Y1 h" u8 w$ l# d2 U$ v
E.E_NOTICE- D3 Y" V+ A. i4 Q- x& D, K, \
) W& }4 X: z% L8 b0 N( M
$ p/ i4 I/ C+ ^& c$ t: v
9.当需要比较一个常量和一个变量时,如何才能保证不会错弄成赋值?/ j! c  R! L, w: v$ x. x

" Y. ?; d8 X- X0 O+ f" UA.把变量转换成int  t& \* G  g4 Q8 ^4 T
B.使用全等比较符(===)
" O5 \6 T# c# \; h/ p* @C.确保常量是第一个操作数9 e- a" K5 h# L" x4 g$ B
D.使用三元运算符
7 y& C: \. b* j0 EE.用括号把操作包起来
* G5 l: `% U# m5 z% @$ L6 W0 q8 _0 P; M! E" }$ h

1 Q$ y- G7 r) P" {& [9 f10.要通过邮件给系统管理员发送错误信息,以下那种方法最简便?, }0 s% i$ z- D+ A# g4 T
2 [0 h1 f- b! J0 t7 N- a$ q
A.创建一个连接远程SMTP服务器的函数8 K/ N1 M7 j/ E, F$ |+ j8 w( z3 H# a
B.使用mail函数
% Y6 I$ i% L7 {C.使用error_log函数
* r" {, N' O) @/ U. o( jD.调用sendmial程序
: }. N4 n# Z# @E.使用webservice
1 l9 H0 J2 t, w/ {9 z/ x6 V3 {9 z: B8 C( R

) g- u4 ]# j; A7 B7 Z1 Y11.能否仅调用一个函数就关闭脚本内所有的错误报告?
) g& ]( Z7 n/ ^+ m) q6 ]
: m! F4 b5 t7 f% K7 j% G8 b0 BA.能5 Q9 B5 y" m: E6 z3 a7 V- g3 S  ~
B.不能
3 N* ?- Y; k; g) ~& R- W' r( l  c8 L4 |6 p

  l! l9 e8 G5 O# m9 h. \12.概要分析器(profiler)是做什么的?
0 ?! h0 Z+ V$ x, t8 w0 k  B$ r
! {0 f6 T3 _3 H, ]9 G9 H: GA.创建关于脚本结构的档案8 K$ c) W: I5 J2 g. A8 J
B.把脚本转化成UML图
+ }# F7 v  Y& @! x. E- GC.精确测算脚本不同部分的运行时间
! N! Z0 i2 {/ o( iD.计算脚本通过web服务器执行时的维度4 ~4 C. \$ |8 q; Q* U+ _1 B
E.扫描脚本,识别由常见错误导致的bug; O* j* S; z' N. G" M
6 B9 W% R9 o, Q

( b, ~$ N/ j$ g- e* ]6 I13.______能帮助识别和解决bug。) F  y) ^5 u% b
. v: T# |2 T/ M6 d, n
答案:____________
$ E5 Z" |, S/ z" Z* N1 W: g/ [; u  b6 [6 E( d6 O# \# x

$ G, M; z5 A. ^( t2 d  d14.trigger_error()和user_error()有什么区别?
% d* X) }( t- I" F) U' T
- Q3 ^' V; e3 y* }! U& L, }A.trigger_error()允许脚本抛出系统级的错误
' \; S* ?/ Z% \  t+ T5 kB.user_error()允许脚本抛出系统级的错误
5 U: ~! S1 g1 a4 |* H! \C.user_error()不能被用在错误管理器中0 E+ ?- B# u8 G: Q& x
D.trigger_error只在PHP5中可用
/ x, y5 `8 z6 L3 t; Z9 d4 iE.没有区别
3 D( W4 U" A  R3 B$ B$ @$ W9 G3 h
% q" d, m  R* c# X9 p0 A3 J2 j& j: G/ L2 U6 N
15.______函数能返回脚本里任意行中调用的函数的名称。该函数同时还经常被用在调试中,用来判断错误是如何发生的。1 L8 [& P( M2 k$ @7 V
% H' [1 E4 |+ X# i- ]( n
A.print_r- B7 Q# W+ U1 @' X
B.var_dump
' ^% x1 X& C- N( |1 ?' r3 DC.stack_dump8 i2 X5 T6 t/ b! Y
D.debug_backtrace
% w  p" }8 m6 j8 [E.以上都不对
: E9 Y. F' X8 P0 f
  m, c6 t& ]2 N) ]& `答案
" e) o! z0 H4 d9 w/ [' E
) d2 K, ~! P- y1 b3 ?5 {9 A! V1.答案是E。三元操作符把每个if语句连到一起,作为&&操作的一部分。然而本题中,$x=1这个赋值只在第三个if为false时发生。如果第一个和第二个条件都不成立,$x=1就不会执行。这题对三元操作的应用有些极端,实际应用时,需要根据可读性来决定是否需要用三元运算符(本题这种情况就最好不要用)。
; |! Y5 S1 U3 i5 x* f2 f7 f  R9 v8 Z* j+ U4 Q( Z+ m
2.问题是由第三方数据源传输缓慢导致的,而你无法控制这个数据源。你也许能在网络连通性上做些工作(假设问题出在你这一边)。还可以对接收到的内容进行缓存,这样能减少获取重复数据的时间。因此,答案是B和E。
# a7 e) m1 K/ p8 e$ j* K9 X; C" I; n) s& V, K( h
3.正确的选择是B和D。如果关闭错误报告、使用@抑错符和关闭错误日志,那么在你交付给客户的网站出现问题时,你将很难进行分析和调试。
- ~" o1 a- l4 V% J  v( x: n" C5 F4 R
" H8 c0 @& K$ g* c( L- Y4.这是在描述===操作符。" u2 g% T! F! z

4 N  K5 p/ L* v) b0 g' N5.正确答案是D。PHP脚本在执行时,将首先被解析成“中间”码(也叫opcode,操作码),然后解释器执行。操作码缓存出现在这两个步骤之间,对解析器的输出进行缓存。下次执行该脚本时,将缓存的输出直接送入解释器。这样就就不需要再解析一次了。; s4 C- z* M4 K. q3 p8 x* n

0 t* v' A2 N% g6.正确答案是A和D。如果RAM太小,进程间将出现资源竞争,服务器将大量使用硬盘交换。同样的,如果允许过多进程同时执行,也会使服务器频繁进行交换,导致速度下降。' j1 O, u0 U5 A7 @8 C& i) _& y

& N4 L8 K6 l1 F9 y7.正确答案是A和C。脚本不检验datebase_query()的调用是否成功,因此将持续执行下去,最终产生错误。此外,$my_id参数没有转义——可能导致代码注入(详见第11章)。
& v9 x. O" l; @) Q5 l. F* s. K& p. @
6 L+ V% i8 T2 |2 c* c3 }8.答案B和D正确。出现解析错误往往表示脚本中有语法错误,自定义的错误管理器无法捕捉到它们的原因很明显:错误管理器在脚本里,而现在无法解析脚本,管理器也就无法执行。类似的,E_ERROR表示有致命的运行错误出现,比如内存耗尽。因此脚本会立刻被中断,因为解释器无法执行后面的代码。3 d) T8 q4 I) `& Z/ U) M( }% N
4 W. i1 _3 i1 k: U! ]
9.答案是C。比较操作是一个可交换的操作(就是说结果独立于操作数之外),而赋值不是。因此,比如说,$a==10和10==$a是等效的,而$a=10和10=$a却不是,而且后者会导致一个错误,因为这不是一个合法的操作。确保常量在操作符前面,能保证你不会错误得将比较变成赋值。" J1 q" V  d4 W' X- Y

5 q- g4 d5 }% E, [* e% ]$ l10.答案是C。error_log函数能将信息送往一个指定的地址。尽管mail()也可以用,但error_log能自动给邮件添加标题,因此这才是最简单的方法。
; T! z5 x* R& \4 \. }* }3 b" u
11.答案是不能。error_reporting函数能关闭所有运行时的错误报告,但对解析时的错误无效,因为解析错误发生在脚本执行之前。
0 m6 g) z: `( ?, H; ~
* @! I" |! A$ ?" N4 Z! T/ m# C12.显然,答案是C。概要分析器(profiler)能监视脚本的运行,并记录单个部分的运行时间。它可以用来找出和解决瓶颈。
; ?$ T9 Q1 P* g7 S8 a8 p
, ~) G2 L. ^( e, E13.这是对调试器的完美定义!你可以用调试软件监视脚本运行,同时分析系统资源消耗,从而发现和解决程序缺陷。; z, C1 F3 a7 B, T. A" K

: E0 r) d' ]6 b" B: X14.trigger_error()和user_error()之间没有区别。后者其实是前者的别名。
* s. D9 ?- J3 ?% y$ y, x! j
3 C( k5 d0 P( c( z; y9 g- H15.答案是D。题目是在描述debug_backtrace函数,它返回一个由所有在代码的特定位置调用过的函数名组成的数组。

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