返回列表 发帖

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

作为一个开发者,无论你经验多么丰富,或者无论你多么努力,你的程序中总会有bug。这是生命中一个必然的部分,如同死亡与缴税(尽管并没有后面两个那么严重)。' n& \/ [' _, J9 [' w
要想解决bug,首先要能找到bug。事实上,许多开发者花费了无数小时茫然得盯着代码,只是因为他们没有把程序的容错能力摆在首位。忽略了这个部分,那么期望一个没有bug的程序就是——不可能的。
3 a- H! l9 H, A- I, o本章测试题将考察你对调试和性能管理相关知识的了解,以及如何用PHP做好这两件事。* e! S- d- n- u! E4 u" O2 a% a
- }5 \6 l- j3 l7 U8 i6 V! Z# h
1 I( b$ ~, x! n  n
问题. s3 \4 f/ A! N! Y$ g+ z

9 \- L2 E% ?$ o7 m9 c1.以下脚本如何用三元操作替代?
: D# o5 v/ [. D5 m7 l' D5 x

  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. ?>
复制代码
8 z4 n6 y. F! u! e1 t8 _( ?! f( V" P
A.$x = ($a A. < 10 || $b > 11 || $c == 1 && $d != $c) ? 0 : 1;6 j+ @* [' U& e1 E: }
B.$x = ($a < 10 || $b > 11 || ($c == 1 && $d != $c)) ? 0 : 1;* s. X- Q+ Y- x
C.$x = (($a < 10 && $b > 11) || ($c == 1 && $d != $c)) ? 0 : 1;% ]. Q0 k! X) \- n
D.$x = ($a < 10 && $b > 11 && $c == 1 && $d != $c) ? 1 : 0;
: n" C+ }3 o% ^; UE.以上都不对0 C. r8 `% I1 s6 e! o

& L1 _1 P% m5 v% k( Q% }" h
/ M9 Q9 X) g& n! C" b) n2.有一个脚本由于要从远程获取数据,因而运行速度很慢,以下那种方法能对其进行优化?(双选)
+ ]1 l6 P( K/ Y' |) w
3 ^4 m7 D1 {, w9 r) C8 d  iA.安装操作码缓存(opcode cache)
! _( q6 `9 @; HB.优化或者升级你的网络连接
! S1 W8 m: l( M- j& oC.添置更多的硬件" p( T& C! L. ^1 N3 O. u* u4 c
D.增加服务器的可用RAM
  Q6 [" a9 I7 t0 V& u* _4 iE.使用连接缓存
5 C5 R  Q9 r8 [3 E
7 t: B  \* s5 j; Y+ M, L5 \/ z" U  K. \, b
3.架设生产环境下的服务器时,需要做哪些步骤?(双选)
- m1 n3 _$ x; r# f
7 A- ^4 r+ O! SA.关闭错误报告
/ x' R! e) m' b8 M5 F; B# @  iB.打开错误日志8 X* F$ E# [- ]: J) F
C.关闭错误日志& u6 k& U$ H9 `
D.关闭错误显示
! d- T) L; _% S$ D! uE.使用@抑错符6 Y6 H+ N9 P+ W, s/ Z" v

) Z) ?  [  e- r) c5 u7 D
8 ]0 z* k9 c  ~$ ^; Y4.______操作符能对操作数的数据类型进行严格的比较?, V7 M. F/ E4 Q! m4 S

; X5 U+ j& F1 M7 r# k答案:____________
  Z+ T8 `, i. X" S6 O; v- w) u& ]
; Q2 T$ f  c" {% ~( f5 A, U
5.操作码缓存(opcode cache)能做什么?3 v# o5 B9 T3 }6 g2 }& S

& V+ p' U4 i$ S, V+ }  ]A.把脚本编译成二进制对象,使它运行得更快( I# c% {, |) A4 {
B.代替Zend引擎加快解释器的运行
2 l) R/ E7 O/ GC.缓存脚本输出以提高执行效率
2 k0 T- }0 D! W9 `D.缓存解析器产生的中间码,以提高运行效率, h; x3 r9 p0 z
E.在内存中缓存脚本,减少从硬盘中读取的次数) u$ c% V" `3 [  ~

5 ]0 \( Q( G6 W8 ~) {1 j4 @! P/ N  q+ Z& }
6.以下哪些情况容易造成系统资源枯竭?(双选)2 s! |! `) B2 h# E: n" U3 l2 R
- |2 P. K7 |6 F! G
A.RAM太小
% z2 G: H5 p. l1 v* GB.使用了低带宽的连接1 L# h+ e5 |6 Q  G) c' F4 h6 z
C.虚拟内存超过2GB" L) p# Y, x% i# M6 \! B9 ]( p
D.允许同时运行太多的服务器进程
; W* |% p7 [) B4 }" ^E.以上都不对' O4 F0 c0 I( D+ G

8 |& |, t* A  Y1 t' j) t# f
9 F: ~9 ]4 p" K+ E& t( s) C3 a7.以下脚本缺了些什么?(双选)
8 _% g4 l" H7 ~2 I

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

6 j6 Y, q  K, S- s1 ]A.参数出口(Parameter escapement)
( t" J% N' `1 V. L  q( SB.输出格式化
2 \/ A) a* L$ v2 xC.错误检查
) e* C. x2 w& _( Y& V3 BD.一个SQL查询
5 q/ \" m' j1 l, i; t2 bE.以上都不对* {# E3 v5 `$ R& v

- b5 G2 g9 d3 @% D( V
1 G8 ~: g5 _+ O" L8.以下那种错误类型无法被自定义的错误处理器捕捉到?(双选)
/ I7 q& s- j& j" I+ o& J( x. j0 K1 l7 j
A.E_WARNING, @0 e# p# {  w9 {4 K0 _2 l( [0 B
B.E_ERROR: ]. g4 \# d9 @1 ^1 {6 B
C.E_USER_ERROR
8 i. o' ^4 J6 Q5 B0 jD.E_PARSE4 Q8 b. u. I% u4 Z$ I" P
E.E_NOTICE  o8 L/ ~( `8 _  T6 f0 J/ z
0 g* E2 o1 {3 a0 s

! g5 z+ T& v# t: I2 D5 {, o" |9.当需要比较一个常量和一个变量时,如何才能保证不会错弄成赋值?
9 a8 u" |' t$ ~! w
3 l+ p8 L8 I- OA.把变量转换成int
; {2 S1 x2 K- L% ?; i. a9 EB.使用全等比较符(===)
- e8 A8 \+ Q) }6 WC.确保常量是第一个操作数
$ `; `: w+ a( ~! u* ^! fD.使用三元运算符
* M+ X' I6 H! Z9 gE.用括号把操作包起来
4 i! Q- ^8 y& N& z3 ^: a- b9 k. h+ I5 Q

! P- X+ M% r! m3 A. S10.要通过邮件给系统管理员发送错误信息,以下那种方法最简便?* g2 _  ~9 M, A( j: k0 J7 @

4 \$ O$ T1 Z+ P+ n; J3 Q& aA.创建一个连接远程SMTP服务器的函数" ^# q3 L( a( c' t) q: r" N
B.使用mail函数( |- o% Z) Z; Q6 Z
C.使用error_log函数9 b  ]0 n* M; Y: A3 B" i2 M
D.调用sendmial程序
% C7 m, Q7 k# WE.使用webservice
8 C; k; m6 A/ M9 s% L6 q" F2 x+ y8 }8 K- M
9 G5 D+ ]% q* e( O$ F- e
11.能否仅调用一个函数就关闭脚本内所有的错误报告?
, O3 K8 @3 m  O; n0 |
" P$ D  K9 o" q) B/ t3 c4 IA.能" u' @# x* f4 q3 e2 o1 S
B.不能
$ y9 X# v4 J/ Q2 P3 r
9 {6 {/ q" m9 ^5 s0 J
9 w6 E' }0 @" z12.概要分析器(profiler)是做什么的?/ G( o7 S  ~2 T1 L
" x& k# J1 M+ ?2 O6 g
A.创建关于脚本结构的档案
8 H$ w) ^9 I5 ~% k7 \' YB.把脚本转化成UML图" i) A' n4 s4 U" Q
C.精确测算脚本不同部分的运行时间
/ y8 E1 X  o) f% W7 D( G# sD.计算脚本通过web服务器执行时的维度$ Z5 q$ }1 _) ]9 d. y& q
E.扫描脚本,识别由常见错误导致的bug7 T9 j; g& [) m+ d

: R2 |! C  U( r8 y7 B% r; b! O4 H" ]8 |
13.______能帮助识别和解决bug。
) D; o+ y. P* g) D/ i5 t
' ]& |9 p: B$ X7 ?' l- z; w8 W答案:____________
1 W% }) Y( `! a- J" z2 r/ s2 ~# P  r9 N% o% H& |
3 h0 A/ a* S, q( k  Y
14.trigger_error()和user_error()有什么区别?
" n! Y* U( T/ Y1 X- ?4 ?7 i" U
: m9 Y' ^. M1 u- ?* R# G, w* d' k) hA.trigger_error()允许脚本抛出系统级的错误
& j9 j1 y/ Q3 s6 pB.user_error()允许脚本抛出系统级的错误
& Z1 C# L5 t" U' Y, j. GC.user_error()不能被用在错误管理器中# @2 H8 Y3 p: O  }4 p! f' n# v" _3 Y4 G
D.trigger_error只在PHP5中可用
8 [, q% z2 D& F, RE.没有区别
/ V9 b( Z5 O( [* Q' l7 `7 J9 F" \0 s5 ?5 P

2 O. u8 P" M2 N6 T4 z15.______函数能返回脚本里任意行中调用的函数的名称。该函数同时还经常被用在调试中,用来判断错误是如何发生的。$ n3 W- t" a$ Q# Q& V; |+ L. B

2 U& H+ h; F( N7 F) X5 ^$ sA.print_r9 J# D3 Y+ b9 [' y
B.var_dump
) f# @+ a4 F! T; j" TC.stack_dump  g) V. f+ M0 F. n# u8 v
D.debug_backtrace' Q; E; s, [/ T: d/ Q7 ?' N
E.以上都不对
: J. p' h  F1 C3 u
/ ~; x9 e0 [; ^: K$ A2 s; L: N1 H1 l& J答案4 t7 [5 p; ]# P. R% `5 @8 W
4 b* s2 e6 e' p
1.答案是E。三元操作符把每个if语句连到一起,作为&&操作的一部分。然而本题中,$x=1这个赋值只在第三个if为false时发生。如果第一个和第二个条件都不成立,$x=1就不会执行。这题对三元操作的应用有些极端,实际应用时,需要根据可读性来决定是否需要用三元运算符(本题这种情况就最好不要用)。
2 I; o5 e$ H2 e. w* v4 V7 `/ w" V6 i3 ~9 b9 L! E# i
2.问题是由第三方数据源传输缓慢导致的,而你无法控制这个数据源。你也许能在网络连通性上做些工作(假设问题出在你这一边)。还可以对接收到的内容进行缓存,这样能减少获取重复数据的时间。因此,答案是B和E。
9 U6 ~1 [6 {) Z) e) T& O$ }' H1 _& L
3.正确的选择是B和D。如果关闭错误报告、使用@抑错符和关闭错误日志,那么在你交付给客户的网站出现问题时,你将很难进行分析和调试。$ g- s/ A1 f$ }  R

0 f$ H  M" x& V0 b8 i4.这是在描述===操作符。
: S( B' x9 k4 L  [* ^" t" l, I2 |; o9 E$ U
5.正确答案是D。PHP脚本在执行时,将首先被解析成“中间”码(也叫opcode,操作码),然后解释器执行。操作码缓存出现在这两个步骤之间,对解析器的输出进行缓存。下次执行该脚本时,将缓存的输出直接送入解释器。这样就就不需要再解析一次了。/ \2 V9 z  T7 T0 M( K, j
, e  Y- w3 q, j' H4 Z7 s
6.正确答案是A和D。如果RAM太小,进程间将出现资源竞争,服务器将大量使用硬盘交换。同样的,如果允许过多进程同时执行,也会使服务器频繁进行交换,导致速度下降。
+ l" o" r. n5 f( \. ~0 M( z4 t) X- N: N: \6 O
7.正确答案是A和C。脚本不检验datebase_query()的调用是否成功,因此将持续执行下去,最终产生错误。此外,$my_id参数没有转义——可能导致代码注入(详见第11章)。
$ y5 ^1 c0 X% |* b& Q5 t) k2 b6 s
; Z' v; l+ ]2 ?8 B( y7 _$ g8.答案B和D正确。出现解析错误往往表示脚本中有语法错误,自定义的错误管理器无法捕捉到它们的原因很明显:错误管理器在脚本里,而现在无法解析脚本,管理器也就无法执行。类似的,E_ERROR表示有致命的运行错误出现,比如内存耗尽。因此脚本会立刻被中断,因为解释器无法执行后面的代码。
. T4 @3 q( Q1 D9 Y$ v
( ^# J6 q, t: H! U# ]. K  F% `9.答案是C。比较操作是一个可交换的操作(就是说结果独立于操作数之外),而赋值不是。因此,比如说,$a==10和10==$a是等效的,而$a=10和10=$a却不是,而且后者会导致一个错误,因为这不是一个合法的操作。确保常量在操作符前面,能保证你不会错误得将比较变成赋值。
/ y3 D0 z# T. i3 J: k/ \& c) m( L8 w% y( Z" K# J1 i( \& g. d
10.答案是C。error_log函数能将信息送往一个指定的地址。尽管mail()也可以用,但error_log能自动给邮件添加标题,因此这才是最简单的方法。% T* N9 d' \! Y6 {

2 h9 Q. Z$ b0 F3 z11.答案是不能。error_reporting函数能关闭所有运行时的错误报告,但对解析时的错误无效,因为解析错误发生在脚本执行之前。
% a$ q5 [# C# s# b0 A: a5 O
% [$ Z5 {! ?& f12.显然,答案是C。概要分析器(profiler)能监视脚本的运行,并记录单个部分的运行时间。它可以用来找出和解决瓶颈。0 s" b. L4 b: q' r# L, @
, N' T( L) g0 M/ ]1 E
13.这是对调试器的完美定义!你可以用调试软件监视脚本运行,同时分析系统资源消耗,从而发现和解决程序缺陷。
, p  K* D+ ?; K/ c
- ~% a+ x# ], v14.trigger_error()和user_error()之间没有区别。后者其实是前者的别名。
+ t  u8 m! G) e7 M
* Y% D4 k2 {/ Z, |15.答案是D。题目是在描述debug_backtrace函数,它返回一个由所有在代码的特定位置调用过的函数名组成的数组。

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