返回列表 发帖

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

作为一个开发者,无论你经验多么丰富,或者无论你多么努力,你的程序中总会有bug。这是生命中一个必然的部分,如同死亡与缴税(尽管并没有后面两个那么严重)。0 D9 Y  A# M: N' G: p# n
要想解决bug,首先要能找到bug。事实上,许多开发者花费了无数小时茫然得盯着代码,只是因为他们没有把程序的容错能力摆在首位。忽略了这个部分,那么期望一个没有bug的程序就是——不可能的。. q9 c' v( W3 u0 s% u
本章测试题将考察你对调试和性能管理相关知识的了解,以及如何用PHP做好这两件事。
% h0 {9 m5 p$ ?  m9 G: N- i! w$ `6 p4 d8 {6 _

* U3 J$ ]/ l8 d- C# O8 w" Q问题5 Z! C* }6 u% s" W" t7 g6 w

* ?) d: u. _4 k5 b0 a1.以下脚本如何用三元操作替代? % E% [: W1 |' m  o2 w' V

  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. ?>
复制代码
# J+ M7 C! A0 s
A.$x = ($a A. < 10 || $b > 11 || $c == 1 && $d != $c) ? 0 : 1;: z4 @0 U! A3 e( W. W
B.$x = ($a < 10 || $b > 11 || ($c == 1 && $d != $c)) ? 0 : 1;1 u4 B5 Q4 i2 i. e1 }8 T$ U
C.$x = (($a < 10 && $b > 11) || ($c == 1 && $d != $c)) ? 0 : 1;
6 _7 ?& f! |+ C! V, qD.$x = ($a < 10 && $b > 11 && $c == 1 && $d != $c) ? 1 : 0;
2 P9 }3 q% J, r; d5 d$ {E.以上都不对
$ p" t% _. t. c. h+ n$ }
9 ^1 i( x- Z6 B2 ^9 B
) y2 D, [) L2 z+ N( B. y2.有一个脚本由于要从远程获取数据,因而运行速度很慢,以下那种方法能对其进行优化?(双选)
' g; Z4 m  `' B6 X; D
# U+ @4 Y6 R) r# X3 a4 ^8 t5 y3 _( S+ XA.安装操作码缓存(opcode cache)
' N) w6 `! b0 dB.优化或者升级你的网络连接
  B' K% T) B! e/ m) g5 AC.添置更多的硬件
" G# x8 }" b& J# A; D- w! i% mD.增加服务器的可用RAM
- J7 u8 S: Q) B3 ^E.使用连接缓存9 S0 h4 ~2 v' Z3 ]
: K* ~5 D* E# R+ T& V; i+ w
. ]# |) m4 w$ C. o& P! `! B: [8 H
3.架设生产环境下的服务器时,需要做哪些步骤?(双选)" F* S9 c8 O& D4 q, d
) j& C+ r( K( u7 A  G9 I6 c
A.关闭错误报告+ H2 v6 V3 D/ Z! n( ^8 K
B.打开错误日志4 E" q1 Q; ^7 J0 w! @& c: g- N
C.关闭错误日志
, V- b& m8 y1 R) w3 Y( f) {D.关闭错误显示* L  \$ A  ~$ Q, g" n& i1 A
E.使用@抑错符0 e0 ^+ S/ I3 ]# |/ o0 j
) y$ N+ [7 n6 [8 W

/ e6 Q/ g' r) v$ j- |6 b4.______操作符能对操作数的数据类型进行严格的比较?+ X* |* ]" |* T" e5 @& o
& H! M9 [5 _* z
答案:____________
$ Y8 ^$ S. c0 u8 ?  w9 p
" M7 q7 F+ g; C
4 w4 j: c; |; B5.操作码缓存(opcode cache)能做什么?  z9 d# z/ ]( I! J$ Z8 C- e
+ B' S% K, {" q
A.把脚本编译成二进制对象,使它运行得更快
/ Q9 n8 {4 m" f) m8 k  Q- oB.代替Zend引擎加快解释器的运行5 y" g# @% Y9 V+ _
C.缓存脚本输出以提高执行效率
5 m3 T+ B0 m% p, }& D; I- uD.缓存解析器产生的中间码,以提高运行效率
: u9 b; x+ M$ ?0 \0 a' ?: z: RE.在内存中缓存脚本,减少从硬盘中读取的次数
- c1 k) I/ d) K( N/ q+ n9 u' L" H, i$ b

$ O2 x+ w& b; b' L$ X6.以下哪些情况容易造成系统资源枯竭?(双选)7 \  g6 `- ^, W. h1 _  t

9 K3 `8 X6 C) F# n* R) {% aA.RAM太小
- Z: A. a) C" F! R: W9 _$ g0 VB.使用了低带宽的连接
3 ^+ Y" N6 X$ B$ ~C.虚拟内存超过2GB
; J1 U6 r) h6 i$ D7 ND.允许同时运行太多的服务器进程! T9 b$ W  H3 h8 K1 r5 X
E.以上都不对( D2 n; [. [; N: e, x  s
: Q+ M& S  x9 u! D
& W2 G/ }7 A+ R! p$ B) i( u
7.以下脚本缺了些什么?(双选)
7 o' \+ w2 J* s5 [  ]5 D/ T6 s

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

9 W, `; \7 P0 R8 sA.参数出口(Parameter escapement). @& [4 l5 B; h& X
B.输出格式化
0 l5 n2 S! V8 I# |$ I1 E+ }, zC.错误检查- u/ A6 S3 G! |  \! L) f" F
D.一个SQL查询2 D3 u' z8 h- H7 Z8 `, O
E.以上都不对' P4 Q6 Z, U: T, J( S

4 @, S7 i2 N: ~; f$ R7 A$ Y$ J3 z; R, U. c: [
8.以下那种错误类型无法被自定义的错误处理器捕捉到?(双选)/ X9 G7 E/ U6 u1 {/ b

0 E$ c" P0 R" b4 K3 m3 A+ ~9 fA.E_WARNING) R4 d, f4 k/ r) c. r0 O
B.E_ERROR
4 ^& Z, \) }) ]) \$ U) o' h, \C.E_USER_ERROR
9 G0 o9 {7 e% L1 |6 OD.E_PARSE2 l2 @. K# @8 B7 N: x* g" W
E.E_NOTICE+ N  ^) J* u* |' }
: Q7 M  ?) }$ M# C

7 B/ l9 H+ }- A: T9.当需要比较一个常量和一个变量时,如何才能保证不会错弄成赋值?
9 B5 ^* u- W9 t' S! A
* L% p  T- i( c4 n) G: mA.把变量转换成int, |6 H% _  T2 Y! `& b% [8 j' A2 E8 r
B.使用全等比较符(===)+ e) E. Q) ~! d( y; k- g" d
C.确保常量是第一个操作数: ~' v) W8 H9 p; R- J5 w
D.使用三元运算符% M5 S( R% ]0 \' J: ?
E.用括号把操作包起来+ V2 k. Z8 w2 G

* R( c$ v7 Y4 x. N; A8 N7 o/ N' Q  ]1 f* f; u
10.要通过邮件给系统管理员发送错误信息,以下那种方法最简便?# {, B7 h4 g& I0 h0 t& E# \. z

. Z( l$ C3 V; G" B5 l% o1 eA.创建一个连接远程SMTP服务器的函数
' U$ e( N% t4 ?' M8 XB.使用mail函数8 T* ?$ O6 E7 s& C, X0 b
C.使用error_log函数
9 {# v8 ?7 [$ \/ Q8 H/ tD.调用sendmial程序
" R+ Z9 D, e, ^2 |* s9 b) p5 o& AE.使用webservice
% y6 Q/ Y- V" s7 @! N# @9 t9 R# \# ^  r" Q9 H

5 c* m, ]! ]3 ?. ]11.能否仅调用一个函数就关闭脚本内所有的错误报告?
: t: u( p$ I1 g9 k+ k1 H; o7 ~. v$ o
A.能3 U! W; a! @6 |! M
B.不能
+ ?: ~9 T& a& s
6 {. w7 i- h/ `/ N( o3 ?8 r; C* r0 n( y& u
12.概要分析器(profiler)是做什么的?
: a! ^- W7 x7 c8 V, A6 a1 t7 ?
( ?/ G8 i8 T: U' t! p8 t$ aA.创建关于脚本结构的档案
* t3 e% b* U8 u9 |2 y5 jB.把脚本转化成UML图
6 {# L( u# T( |' OC.精确测算脚本不同部分的运行时间# j6 P( C. s; E# o/ \: A* _! B
D.计算脚本通过web服务器执行时的维度1 `& L" h$ k  N* P" A
E.扫描脚本,识别由常见错误导致的bug
/ L8 B) {6 g) F
! q% b0 c+ s% i3 h/ M4 f- s
% R+ N' d0 }. o0 t! I13.______能帮助识别和解决bug。( h4 ]8 Y# \' S/ ^% h( R! p+ c

# p# Q; k& `' R$ V9 d2 T答案:____________
( H& |  c% T" f, t" K( w" f) w  V  o9 O# b1 \! u

3 z1 J- m' _+ V- L7 n2 a2 S14.trigger_error()和user_error()有什么区别?, A/ z) q, t( b% [+ d( d4 O( h5 i
, ^7 ]; Y1 O) [2 I
A.trigger_error()允许脚本抛出系统级的错误" u2 |1 ^6 C$ Z. t0 E6 k; N, w
B.user_error()允许脚本抛出系统级的错误! T! Z5 a$ m( c- T
C.user_error()不能被用在错误管理器中
5 L+ p9 x; W) Y, l5 X( pD.trigger_error只在PHP5中可用  Q( A1 e% H1 f* i" A# A7 K% ]
E.没有区别
; k. O1 [. F; _& q9 q* W: j8 Q4 _% W. J, j8 q3 R. G
0 k2 Z" r2 s" o. ~& D+ t
15.______函数能返回脚本里任意行中调用的函数的名称。该函数同时还经常被用在调试中,用来判断错误是如何发生的。
' i* d5 n2 N# P% F
1 Q0 {7 u: B' NA.print_r
1 B1 f' w+ X+ \2 ZB.var_dump
2 N( A9 B9 }) r0 ~: O1 \C.stack_dump6 h2 P) k( }. X& c4 m
D.debug_backtrace+ ]% |3 J6 S, ]# G+ b2 C6 ]
E.以上都不对1 A1 ~( d: i+ ~$ D5 u. [! M

+ w3 Q4 v, Z( k! T答案
1 R1 S0 t( T; D* ^7 q/ I5 u' X4 r! j, l3 M: u( F. u  T! H9 P
1.答案是E。三元操作符把每个if语句连到一起,作为&&操作的一部分。然而本题中,$x=1这个赋值只在第三个if为false时发生。如果第一个和第二个条件都不成立,$x=1就不会执行。这题对三元操作的应用有些极端,实际应用时,需要根据可读性来决定是否需要用三元运算符(本题这种情况就最好不要用)。
# f9 l) ~) D+ Q( E+ T
  P6 S: X* I9 g/ l1 S- n2.问题是由第三方数据源传输缓慢导致的,而你无法控制这个数据源。你也许能在网络连通性上做些工作(假设问题出在你这一边)。还可以对接收到的内容进行缓存,这样能减少获取重复数据的时间。因此,答案是B和E。; j% y% g% G* B: X
/ O3 o% w- N. w& U, n4 T) e
3.正确的选择是B和D。如果关闭错误报告、使用@抑错符和关闭错误日志,那么在你交付给客户的网站出现问题时,你将很难进行分析和调试。
$ ]' R* g' V4 r" h1 A  @
  t: l7 R0 o' l/ y6 M4.这是在描述===操作符。
: r- r0 R- p  C. }6 B6 i! y) J  D. K1 S% H* P+ W$ j' a
5.正确答案是D。PHP脚本在执行时,将首先被解析成“中间”码(也叫opcode,操作码),然后解释器执行。操作码缓存出现在这两个步骤之间,对解析器的输出进行缓存。下次执行该脚本时,将缓存的输出直接送入解释器。这样就就不需要再解析一次了。
1 j% y$ a! K9 V; U, u* M
  M0 y7 ]) f. G+ D3 [+ }' X6.正确答案是A和D。如果RAM太小,进程间将出现资源竞争,服务器将大量使用硬盘交换。同样的,如果允许过多进程同时执行,也会使服务器频繁进行交换,导致速度下降。
7 N, ^; o, j" A0 d8 |; Z. }3 y
% X. P! V( S8 T7.正确答案是A和C。脚本不检验datebase_query()的调用是否成功,因此将持续执行下去,最终产生错误。此外,$my_id参数没有转义——可能导致代码注入(详见第11章)。9 v! l6 _! Y# X6 N( R

0 {$ z; Z' B8 _9 ]; [8 \8.答案B和D正确。出现解析错误往往表示脚本中有语法错误,自定义的错误管理器无法捕捉到它们的原因很明显:错误管理器在脚本里,而现在无法解析脚本,管理器也就无法执行。类似的,E_ERROR表示有致命的运行错误出现,比如内存耗尽。因此脚本会立刻被中断,因为解释器无法执行后面的代码。
$ a0 P9 z: A/ L, ~- ^' e. Q* N, |& B* x, G- S0 [. T$ q  H
9.答案是C。比较操作是一个可交换的操作(就是说结果独立于操作数之外),而赋值不是。因此,比如说,$a==10和10==$a是等效的,而$a=10和10=$a却不是,而且后者会导致一个错误,因为这不是一个合法的操作。确保常量在操作符前面,能保证你不会错误得将比较变成赋值。. {7 y( D9 S! n3 y: S) f2 V, Z: i+ y

1 ?$ Z% R4 S! N& i  U& N2 r$ _8 y7 t10.答案是C。error_log函数能将信息送往一个指定的地址。尽管mail()也可以用,但error_log能自动给邮件添加标题,因此这才是最简单的方法。
) R" E# r7 t  z  u/ s' H+ E/ c( d
) V" `! e4 U; I6 F$ Y1 _11.答案是不能。error_reporting函数能关闭所有运行时的错误报告,但对解析时的错误无效,因为解析错误发生在脚本执行之前。( m/ @* Z1 X6 b8 ^6 O
' q) J/ S3 C3 f- l7 t
12.显然,答案是C。概要分析器(profiler)能监视脚本的运行,并记录单个部分的运行时间。它可以用来找出和解决瓶颈。
7 N( S+ f& k; h' M+ Z9 |, G' u' U/ u" V6 ~* J' O$ q4 n
13.这是对调试器的完美定义!你可以用调试软件监视脚本运行,同时分析系统资源消耗,从而发现和解决程序缺陷。
0 ~) v* N% F1 J3 x4 _! A1 ^6 V* p
( ]" f7 l6 @9 E" X; u$ `14.trigger_error()和user_error()之间没有区别。后者其实是前者的别名。+ m0 n3 D7 F, f3 H( c
  d% r: E4 s& {: r4 E  ]7 ^7 n
15.答案是D。题目是在描述debug_backtrace函数,它返回一个由所有在代码的特定位置调用过的函数名组成的数组。

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