返回列表 发帖

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

作为一个开发者,无论你经验多么丰富,或者无论你多么努力,你的程序中总会有bug。这是生命中一个必然的部分,如同死亡与缴税(尽管并没有后面两个那么严重)。
6 o; X4 y4 V+ {- B3 T$ q8 h: N要想解决bug,首先要能找到bug。事实上,许多开发者花费了无数小时茫然得盯着代码,只是因为他们没有把程序的容错能力摆在首位。忽略了这个部分,那么期望一个没有bug的程序就是——不可能的。# }) I) |/ D( R: M- w! Y( s. ^
本章测试题将考察你对调试和性能管理相关知识的了解,以及如何用PHP做好这两件事。) n, n& x' Y! x' |  W. o

. g, {* w' \& `9 B- _' _/ R" g% K0 v0 R' c$ l
问题
7 U! s- K+ v' f4 r; J% R$ b$ c; X9 i5 ]: }: v. a
1.以下脚本如何用三元操作替代? 9 x7 v# j% ]& g/ G4 f

  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 r% s7 ?' n5 X3 i4 ~- _+ z" tA.$x = ($a A. < 10 || $b > 11 || $c == 1 && $d != $c) ? 0 : 1;# l9 D- e4 I8 }
B.$x = ($a < 10 || $b > 11 || ($c == 1 && $d != $c)) ? 0 : 1;
! h0 m4 P3 j0 O! t% p/ bC.$x = (($a < 10 && $b > 11) || ($c == 1 && $d != $c)) ? 0 : 1;
( j) z+ z  p( e( pD.$x = ($a < 10 && $b > 11 && $c == 1 && $d != $c) ? 1 : 0;  t1 s2 x5 _6 O0 m3 @
E.以上都不对6 U; y4 o4 Z' A0 k' g) y! `
' t3 s+ R; }2 H; r
, Y! o8 M9 e0 Z8 e( r# j& d
2.有一个脚本由于要从远程获取数据,因而运行速度很慢,以下那种方法能对其进行优化?(双选)
2 P2 h5 L" H* O+ ]. u. ?" V4 c1 l3 Q! C
A.安装操作码缓存(opcode cache)% e4 J, G8 @7 o- F
B.优化或者升级你的网络连接
* \% Y+ c) x% ^+ `4 ^: mC.添置更多的硬件+ n- O; Z  K! ?
D.增加服务器的可用RAM& l5 \2 {7 ]2 g& k2 T8 T
E.使用连接缓存1 m; b+ `3 `- G" I# y7 j. ~

& e" O% D& H' y: R( d: X$ k% [
+ m* W5 ~; l- q$ ]2 H* h) B3.架设生产环境下的服务器时,需要做哪些步骤?(双选)( v" F* m1 S. }/ `' [: U; W
. ]/ |6 R" {- K& X- ?! Z8 N
A.关闭错误报告
. w3 V( t2 |9 {3 t# X  zB.打开错误日志
7 {" D8 p0 D+ _6 O. z& ~8 RC.关闭错误日志6 ^4 ^; m$ M2 G
D.关闭错误显示/ a. m2 t( y: O, @* C3 c
E.使用@抑错符5 U) `' m( G0 o
8 {4 z2 g: X" v

& v  z. W7 N0 I2 A! j  X4 \4.______操作符能对操作数的数据类型进行严格的比较?3 W7 ~  Z0 [1 n4 _

: C) T" A; k# Z7 f% E6 n0 i8 k答案:____________
* `; v$ U% Q. |* ^  _
9 X" Q/ w% X3 J
6 q/ B3 I/ G& ]2 k6 G8 j2 P5.操作码缓存(opcode cache)能做什么?
6 G9 p4 J  u: S. [) E2 d% M6 U1 a( _2 l6 o! u
A.把脚本编译成二进制对象,使它运行得更快" D9 F" k. y" O
B.代替Zend引擎加快解释器的运行% r- M+ A: F# U" j( I' j$ n
C.缓存脚本输出以提高执行效率/ I5 U2 o! e0 F* A
D.缓存解析器产生的中间码,以提高运行效率
$ t3 d; x$ E* `5 r4 t; f1 QE.在内存中缓存脚本,减少从硬盘中读取的次数7 o8 |/ y1 W2 u, A

8 R8 U* ^8 y/ ~* f2 ^  {* K
: L! a: k6 D7 H" l& j2 r5 Q6.以下哪些情况容易造成系统资源枯竭?(双选)3 x$ @" Q! n5 m9 y% H4 C0 N

' w$ Y$ Y+ k/ Z5 b) z: ?4 IA.RAM太小3 w. z1 y  x) f1 M) Z
B.使用了低带宽的连接7 C7 X: p) t% U! k0 ?
C.虚拟内存超过2GB1 f" y" e( }7 f2 \3 s3 f% O
D.允许同时运行太多的服务器进程
# ?0 B( Z& U. _+ z) r3 n; ^" _  c' q0 b7 hE.以上都不对
* K' Z* ~: a0 H; V* X; {9 J& o
* A" i# i9 k& B9 d( ?4 F6 ^3 o- f! S6 i+ c" a; {0 N
7.以下脚本缺了些什么?(双选)
% c; q- F, E; Q+ M  X

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

' T# Z* Z( _4 u3 r( F+ lA.参数出口(Parameter escapement)
. Q2 o3 d- ^7 z  c1 {2 XB.输出格式化
1 J! E( P. u/ G. ^" ?C.错误检查
7 ~9 E. g0 E1 `D.一个SQL查询
5 h3 x5 R7 I8 T& H% hE.以上都不对
; `3 o/ V  ?5 P  D# H- X, }% J( n6 S3 q0 ^
6 Z; l+ K9 i6 o- V, I" P
8.以下那种错误类型无法被自定义的错误处理器捕捉到?(双选)
4 Q* e; _1 _3 J& R/ v
' \+ E2 C; I1 o' e( \A.E_WARNING! n  R1 Y0 H' v2 m$ M. {& S
B.E_ERROR
0 z# V0 W6 ~$ L! J9 `, ZC.E_USER_ERROR* W1 p7 t! v5 z
D.E_PARSE
% \5 u4 b. D- ^  r. K+ u. sE.E_NOTICE
5 g0 T+ |& Q& j/ B, r, j  w
0 R9 O1 q& T: }% j& K% O5 ?4 [3 S2 a9 z. i6 R6 ?
9.当需要比较一个常量和一个变量时,如何才能保证不会错弄成赋值?2 c* ~) _  |/ K
& B. N& G5 ^( p
A.把变量转换成int
- d+ b( p; h7 {" I  s; m  k7 J' KB.使用全等比较符(===)2 ^5 {7 Q$ ]- q$ A
C.确保常量是第一个操作数! L$ W! ^0 b9 M/ w, \
D.使用三元运算符3 q; I( Q- h0 }. y& o8 [, u
E.用括号把操作包起来  d; y8 p& s6 b, j, |
3 J8 T% U" g+ e& N& D" }7 C
9 V- s8 h. g# y" g( {& W
10.要通过邮件给系统管理员发送错误信息,以下那种方法最简便?$ w$ b2 ]) n$ ~. o
7 ^  ~- y+ s' W2 e' H7 l
A.创建一个连接远程SMTP服务器的函数
' G* r" z( e; I* W" vB.使用mail函数3 Y0 K7 P( t7 o5 b/ u7 ~+ I
C.使用error_log函数4 F/ P  p9 u/ D" @
D.调用sendmial程序
% `. o$ j! |/ YE.使用webservice
1 J3 A+ u- U% t7 M7 }. F) `8 X' i, R: {$ z: W" a

& {4 r' w1 F9 a4 K. G4 B' B; y11.能否仅调用一个函数就关闭脚本内所有的错误报告?
% ]; g( s4 d/ U  t: x( \! q: H/ h/ U8 n1 p+ P3 U( y
A.能
1 M& _( |/ F+ z! D7 V. I/ xB.不能
: ^( e3 D5 m% A4 i# h3 e& ], ^) L

" y1 l+ u0 j" S- E9 U12.概要分析器(profiler)是做什么的?2 W  V+ O6 D+ O9 i

$ W. G8 [! j- BA.创建关于脚本结构的档案
/ r% t: Q! l1 b3 o2 XB.把脚本转化成UML图
$ B. `: W) x2 B# K7 A  M: jC.精确测算脚本不同部分的运行时间; i; b( w8 U- J9 l6 @
D.计算脚本通过web服务器执行时的维度- b2 C2 v; f# C9 q5 f% D5 o1 O, B
E.扫描脚本,识别由常见错误导致的bug. t7 I! X: T: ?

6 C' z0 v- j6 Y" K" D0 D5 g: U  K% F5 B7 i# I. K) i2 p: v& _
13.______能帮助识别和解决bug。
: X. }/ C$ ~& E/ U9 _. ]3 c" ~# \/ U/ B. j1 a- c
答案:____________$ S* X  H5 E8 E
; b$ i2 h5 S1 B2 ^
- F7 r" |9 T/ i  k% Q9 ~1 q
14.trigger_error()和user_error()有什么区别?5 \0 g! Y+ u- s

- v, y$ O. D' q& xA.trigger_error()允许脚本抛出系统级的错误5 c' }2 s: }4 f9 u, J$ X
B.user_error()允许脚本抛出系统级的错误
6 u) S3 V3 [3 n; QC.user_error()不能被用在错误管理器中
/ s2 Q$ ^3 N) q: u% [6 @5 h2 mD.trigger_error只在PHP5中可用! }! h4 `, l6 v$ m
E.没有区别
( M# Y; f' a& p( M' ~
7 T( i: v0 _6 f5 ?+ W; X" }8 f' L5 k$ n: g# k; A" W3 {' E# N" q) _
15.______函数能返回脚本里任意行中调用的函数的名称。该函数同时还经常被用在调试中,用来判断错误是如何发生的。6 H$ ^. ]( G) Q9 @6 S9 |' X

3 D) \- j3 D6 {1 |A.print_r; A: C* M- r+ i4 H9 \* i
B.var_dump" ^8 }' R5 Q9 ?! L
C.stack_dump$ w/ c% _" x7 x. k, k
D.debug_backtrace
2 B; p4 x8 y" @9 n7 FE.以上都不对# u( V# v0 u$ a% l* m  J1 K; `6 T
7 u% v* k7 @2 Q  B, d& ]
答案
- h% i  G5 x# g% v6 c$ Z3 c+ M6 w( E0 U+ B8 a
1.答案是E。三元操作符把每个if语句连到一起,作为&&操作的一部分。然而本题中,$x=1这个赋值只在第三个if为false时发生。如果第一个和第二个条件都不成立,$x=1就不会执行。这题对三元操作的应用有些极端,实际应用时,需要根据可读性来决定是否需要用三元运算符(本题这种情况就最好不要用)。4 y$ U- C& [# _- ~3 l3 Q8 i1 n
$ q( e2 f. i: y4 l- h
2.问题是由第三方数据源传输缓慢导致的,而你无法控制这个数据源。你也许能在网络连通性上做些工作(假设问题出在你这一边)。还可以对接收到的内容进行缓存,这样能减少获取重复数据的时间。因此,答案是B和E。0 _+ \0 c( n7 a
4 }8 k$ A" N3 F# c' f4 F
3.正确的选择是B和D。如果关闭错误报告、使用@抑错符和关闭错误日志,那么在你交付给客户的网站出现问题时,你将很难进行分析和调试。
; D8 A, d$ R* U& G; i% Q
# |; R- P: P' w9 b4.这是在描述===操作符。
) o4 d+ S# W" E. Z9 L) ^- B
. p% g: ~; D- Q/ x* ^: I5.正确答案是D。PHP脚本在执行时,将首先被解析成“中间”码(也叫opcode,操作码),然后解释器执行。操作码缓存出现在这两个步骤之间,对解析器的输出进行缓存。下次执行该脚本时,将缓存的输出直接送入解释器。这样就就不需要再解析一次了。
+ \+ V) w- w+ L- |8 e: H
7 R- Q0 b0 h$ r3 n6.正确答案是A和D。如果RAM太小,进程间将出现资源竞争,服务器将大量使用硬盘交换。同样的,如果允许过多进程同时执行,也会使服务器频繁进行交换,导致速度下降。
' L. j' G5 ^+ B  G5 f8 D) T0 S
( j" N/ i* L. K* [8 E: Y7.正确答案是A和C。脚本不检验datebase_query()的调用是否成功,因此将持续执行下去,最终产生错误。此外,$my_id参数没有转义——可能导致代码注入(详见第11章)。
3 {; k" l9 L: @5 z" @
& C7 e4 k/ P3 r9 Y: }. S8.答案B和D正确。出现解析错误往往表示脚本中有语法错误,自定义的错误管理器无法捕捉到它们的原因很明显:错误管理器在脚本里,而现在无法解析脚本,管理器也就无法执行。类似的,E_ERROR表示有致命的运行错误出现,比如内存耗尽。因此脚本会立刻被中断,因为解释器无法执行后面的代码。
. g, _; K* {, p  B: @
5 f) y' \2 _+ h$ [2 j9.答案是C。比较操作是一个可交换的操作(就是说结果独立于操作数之外),而赋值不是。因此,比如说,$a==10和10==$a是等效的,而$a=10和10=$a却不是,而且后者会导致一个错误,因为这不是一个合法的操作。确保常量在操作符前面,能保证你不会错误得将比较变成赋值。3 l8 D6 S. [0 r" }& L3 B* g6 g
: Y4 d* K+ Q5 s6 \
10.答案是C。error_log函数能将信息送往一个指定的地址。尽管mail()也可以用,但error_log能自动给邮件添加标题,因此这才是最简单的方法。
8 h- c; e( g3 s+ A# P9 P2 f8 j
# d; C' p5 E5 n* q, Q# R$ }6 D11.答案是不能。error_reporting函数能关闭所有运行时的错误报告,但对解析时的错误无效,因为解析错误发生在脚本执行之前。0 U8 u: s' e; `1 l5 M8 S
# t" I2 H4 G2 c& p
12.显然,答案是C。概要分析器(profiler)能监视脚本的运行,并记录单个部分的运行时间。它可以用来找出和解决瓶颈。. W: I  e1 P% A4 @  {
- Y$ ?+ A. c: r& w
13.这是对调试器的完美定义!你可以用调试软件监视脚本运行,同时分析系统资源消耗,从而发现和解决程序缺陷。8 V& G8 f6 d: e) N8 ?9 Z1 c# W
4 |& _7 j3 l3 Y* h2 B0 V
14.trigger_error()和user_error()之间没有区别。后者其实是前者的别名。" K4 z+ c) w% x6 ?
# N6 f* K1 y. p& c
15.答案是D。题目是在描述debug_backtrace函数,它返回一个由所有在代码的特定位置调用过的函数名组成的数组。

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