  
- UID
- 1
- 帖子
- 738
- 精华
- 28
- 积分
- 14247
- 金币
- 2414
- 威望
- 1647
- 贡献
- 1362
|
[Zend权威认证试题讲解]第十二章 -调试与性能管理
作为一个开发者,无论你经验多么丰富,或者无论你多么努力,你的程序中总会有bug。这是生命中一个必然的部分,如同死亡与缴税(尽管并没有后面两个那么严重)。, }6 E) W9 @) h. _0 H6 q; N; j1 E# ^
要想解决bug,首先要能找到bug。事实上,许多开发者花费了无数小时茫然得盯着代码,只是因为他们没有把程序的容错能力摆在首位。忽略了这个部分,那么期望一个没有bug的程序就是——不可能的。0 ?( ^6 G3 _* V6 u' R% S
本章测试题将考察你对调试和性能管理相关知识的了解,以及如何用PHP做好这两件事。5 j# r% P; [ r8 I5 m
/ Z* O, M8 j) r4 e D( Y$ F# h
2 U) c3 X* R; m问题. `$ [$ {2 a8 L( t* L: h. a6 C
7 W$ ?; o' j" w$ M9 }, A* @
1.以下脚本如何用三元操作替代?
- Q5 Y k! A$ b-
- <?php
- if ($a < 10) {
- if ($b > 11) {
- if ($c == 10 && $d != $c) {
- $x = 0;
- } else {
- $x = 1;
- }
- }
- }
- ?>
复制代码
; _4 w( e) p. Y. m/ ^A.$x = ($a A. < 10 || $b > 11 || $c == 1 && $d != $c) ? 0 : 1;
7 B! u7 R. f9 o7 I$ B5 N8 SB.$x = ($a < 10 || $b > 11 || ($c == 1 && $d != $c)) ? 0 : 1;
( X' z# H! y$ ?C.$x = (($a < 10 && $b > 11) || ($c == 1 && $d != $c)) ? 0 : 1;) p8 d6 U% ~/ |! c2 |: Y8 n( e* g
D.$x = ($a < 10 && $b > 11 && $c == 1 && $d != $c) ? 1 : 0;) d7 v( X7 X/ b; h; ~, Y# Q2 c" }
E.以上都不对1 k- i& [) P8 E; B+ ]
' q. V' [* a& R' t5 n1 M. a" E) B2 Y W4 z. S
2.有一个脚本由于要从远程获取数据,因而运行速度很慢,以下那种方法能对其进行优化?(双选). ?" a- C( R; Q; P) v% ~
/ O) \$ l, m' p; A) K6 w/ ~0 IA.安装操作码缓存(opcode cache). i% H( _' u) R. _1 D) W
B.优化或者升级你的网络连接( h3 k; ]+ X: U, `. m) _
C.添置更多的硬件
' W3 R3 e! K8 l- \; _4 `' _' _D.增加服务器的可用RAM
r1 n t( H* q% EE.使用连接缓存2 G9 u/ X% [- p
. g5 K: |; W0 j. z
- x6 f; D; `- u; Z2 { b
3.架设生产环境下的服务器时,需要做哪些步骤?(双选)2 k1 d- x5 V( o$ B3 D* I5 L
! c) Z- c. z* O H& HA.关闭错误报告- \% j" x; W4 v& D [1 i. K
B.打开错误日志
6 N" a G y/ q6 ~% e( t3 K" ~4 z" Y, AC.关闭错误日志
% e( ]3 g- C dD.关闭错误显示9 p9 S2 r* v2 Y$ f# S$ X+ `2 u4 _
E.使用@抑错符
9 P0 r1 e5 G9 W* Y
5 E; Z- T9 k/ @6 a! F2 ]# ~1 K* M) n/ A& V5 C4 e$ c4 h2 b
4.______操作符能对操作数的数据类型进行严格的比较?: ?8 ^, k/ }- u: t0 i8 i' n5 v
}/ q, j+ X2 `* }9 L& n答案:____________: `) L; j, _2 o2 P
6 W* U. s6 [) Y) [
8 u% r8 h' n/ Q5 h; X# I5.操作码缓存(opcode cache)能做什么?
3 d" x' J: k+ L( O5 W$ r8 D4 E( m: F7 D
A.把脚本编译成二进制对象,使它运行得更快
5 h9 E8 b3 _ @# H, O: Y% WB.代替Zend引擎加快解释器的运行
/ ~: m) G9 j0 {, E9 q1 qC.缓存脚本输出以提高执行效率# f: J7 {! m, |- J
D.缓存解析器产生的中间码,以提高运行效率
- }0 j5 Y+ r; g" V7 AE.在内存中缓存脚本,减少从硬盘中读取的次数
4 R/ K: o" |9 J; b' r
1 M6 E2 i4 a5 v( `5 |7 f) Z+ a5 @
& d( o0 D P3 G8 L7 M. Q" D8 u3 |6.以下哪些情况容易造成系统资源枯竭?(双选)6 i- k {/ g S. g# E" C _
' W5 c; m, P, c! e+ w+ T/ `
A.RAM太小: O$ B$ n U% Z$ b
B.使用了低带宽的连接7 l ]4 X; ^1 k& }$ }
C.虚拟内存超过2GB
: h5 s+ v9 \" KD.允许同时运行太多的服务器进程' W7 x6 T" F6 s8 d$ T
E.以上都不对
# l6 M- f. B& T4 A0 G, Z) V
}4 X& U3 d: @9 K5 b0 ~; k
. P" Q j) T. g. ^" w7.以下脚本缺了些什么?(双选) 6 Y# a4 n: ?$ f; g0 H
-
- <?php
- $rs = database_query ("select * from mytable where id = " .
- $my_id);
- while ($a = database_get_data ($rs)) {
- var_dump ($a);
- }
- ?>
复制代码 ( [( U4 m% D/ W7 A6 \
A.参数出口(Parameter escapement)
) s6 q7 m) T) g7 z! j ?B.输出格式化
5 r: ?( y2 X' E# e- J# w) t1 IC.错误检查
& n% G6 |1 @2 d* I+ b8 FD.一个SQL查询) M2 G: T/ m( r' [* c+ N
E.以上都不对
8 m+ o8 s7 t" M( a# s% E' z3 w3 j# t! a& I& t, a
+ s, F% ^9 k: T+ t1 `2 x4 K; c7 I
8.以下那种错误类型无法被自定义的错误处理器捕捉到?(双选)
6 x6 }3 D3 l- X; ~& A5 G: N0 ^( K
A.E_WARNING
0 Y. B) n: O4 S' W9 dB.E_ERROR
' X, g/ n. y* S1 ]4 m5 i! t$ uC.E_USER_ERROR
/ |# i# p9 i1 h4 H. \D.E_PARSE- g% ?" Y" ?$ n) Z1 b" e
E.E_NOTICE
' C# L0 t2 U Z& C- Q8 X; e8 d/ L1 f p3 ~* Q
4 c$ r9 I/ ~/ V7 @9.当需要比较一个常量和一个变量时,如何才能保证不会错弄成赋值?' W6 i- Z8 s: X+ b6 }/ N
' t+ z, y1 w. T: nA.把变量转换成int
. C1 c( k+ n7 u9 HB.使用全等比较符(===)
* s' ~6 n- F+ ^/ m( X5 [1 AC.确保常量是第一个操作数8 @* {- ^+ i- f) Q W# U5 E* O( H
D.使用三元运算符
) K# Q9 @( c0 u0 X3 y5 _E.用括号把操作包起来3 L) L3 ^3 j" M( l- ^$ j# X
3 c% ?. O. o" @' K1 ]
8 a$ g2 Q* u8 ]4 `% e/ X10.要通过邮件给系统管理员发送错误信息,以下那种方法最简便?3 V6 @( |: Y4 ?+ _, J0 r
8 Q& J* a. j+ Z$ k3 B# ]
A.创建一个连接远程SMTP服务器的函数4 s9 C( L7 Q, Q0 c% N0 b. P. J
B.使用mail函数
1 x2 ^8 b9 Y$ S B( ?# ]C.使用error_log函数/ O3 V5 Q/ f2 R/ R1 l* c; G" B: y
D.调用sendmial程序1 |5 X( {" B* Y
E.使用webservice3 @* C) @$ p' Y$ P7 }, e- P
( @1 R L9 P$ @5 `/ F& N9 o- N/ ?0 q0 N: U, j
11.能否仅调用一个函数就关闭脚本内所有的错误报告?
5 C2 [8 S# h) q3 x
) H1 ~2 U$ b' j; S( h9 u5 l' jA.能2 R8 g2 W# N, I0 n1 \0 j% @
B.不能+ h5 ?: L8 ^# b+ `; n# |( X1 j$ G
/ o0 E- I$ ]' I9 A; _8 q+ [. M ]& c) M0 h) d K
12.概要分析器(profiler)是做什么的?$ h6 `; w" s, K+ I. u2 N& W. U
3 \' I3 e6 }" B3 l3 I9 p
A.创建关于脚本结构的档案6 w4 G4 ~5 I) p& }' e7 z- S
B.把脚本转化成UML图
; R' C* p. u: h( V5 G$ ?C.精确测算脚本不同部分的运行时间
, h/ o! @- |$ r+ @% q \9 dD.计算脚本通过web服务器执行时的维度5 k7 G$ i, I" G M
E.扫描脚本,识别由常见错误导致的bug
( r S7 N9 W5 t5 W, W8 }( B" O' C5 i$ T
7 H6 V: _- ^/ x4 Q1 U13.______能帮助识别和解决bug。
* z5 i. q _ V# b8 Y& i1 h- j6 q
% [: O, \4 Q8 S答案:____________# N: |* v) z* F& [ C+ k
: J7 ?8 O/ N2 R. D" p( @! T3 a q
4 k( ?% Z4 u/ J+ z! T9 R1 ?/ I
14.trigger_error()和user_error()有什么区别?
4 N9 s( u5 y+ n7 x
+ k% e: G9 R8 {1 _% ^ m6 L( EA.trigger_error()允许脚本抛出系统级的错误) q# f: t V) Z/ J8 w( g
B.user_error()允许脚本抛出系统级的错误, y9 Y( S7 W/ i
C.user_error()不能被用在错误管理器中
3 h) u& L! x# B( TD.trigger_error只在PHP5中可用
) j8 o. _+ o0 b1 O$ r0 aE.没有区别% q8 A- r5 c+ j, D7 |& Q
, |. j( w. D% v) R& l
8 W ]- @. V# J! M7 o) z" f8 T+ e15.______函数能返回脚本里任意行中调用的函数的名称。该函数同时还经常被用在调试中,用来判断错误是如何发生的。
, y" V6 l8 H$ F! L: O! v7 z9 O% X6 D* K" X5 ?1 t6 z2 l
A.print_r
; H# J @0 _$ o2 @B.var_dump
8 z; K) k; J' S$ Z, Y& hC.stack_dump& K- o0 J1 c5 H
D.debug_backtrace
8 P; V2 s, d) w$ bE.以上都不对
3 ~/ M7 ]- g. [, @& S
' G% h. e- n9 p8 d' n _答案
7 x8 }; p; p8 f8 }8 P* ]) n+ d, w) f2 i& p3 p
1.答案是E。三元操作符把每个if语句连到一起,作为&&操作的一部分。然而本题中,$x=1这个赋值只在第三个if为false时发生。如果第一个和第二个条件都不成立,$x=1就不会执行。这题对三元操作的应用有些极端,实际应用时,需要根据可读性来决定是否需要用三元运算符(本题这种情况就最好不要用)。
5 W& F" a6 D& P( v( m4 j Z+ {" r( X1 i' Q0 ^, U
2.问题是由第三方数据源传输缓慢导致的,而你无法控制这个数据源。你也许能在网络连通性上做些工作(假设问题出在你这一边)。还可以对接收到的内容进行缓存,这样能减少获取重复数据的时间。因此,答案是B和E。/ x9 I2 n6 H; q
Q" e# U$ Y; C- e [$ H" @* F3.正确的选择是B和D。如果关闭错误报告、使用@抑错符和关闭错误日志,那么在你交付给客户的网站出现问题时,你将很难进行分析和调试。 |% @5 ^9 a- H: W8 ^
1 K( }- T3 l0 I5 o7 f3 _' [3 ^
4.这是在描述===操作符。
, ?$ U% }' ^& b3 ^/ c- l( L& M; }0 g& r+ y9 S
5.正确答案是D。PHP脚本在执行时,将首先被解析成“中间”码(也叫opcode,操作码),然后解释器执行。操作码缓存出现在这两个步骤之间,对解析器的输出进行缓存。下次执行该脚本时,将缓存的输出直接送入解释器。这样就就不需要再解析一次了。
! w& e% W3 u! F, y6 T. Q O1 S# R6 D1 s3 G( n
6.正确答案是A和D。如果RAM太小,进程间将出现资源竞争,服务器将大量使用硬盘交换。同样的,如果允许过多进程同时执行,也会使服务器频繁进行交换,导致速度下降。
% n! _: [0 n* A/ D. t$ O, p9 s( i4 j* j: `! A" x1 | Z
7.正确答案是A和C。脚本不检验datebase_query()的调用是否成功,因此将持续执行下去,最终产生错误。此外,$my_id参数没有转义——可能导致代码注入(详见第11章)。
& h) w8 w! o$ H9 I1 N1 z- R$ u3 S9 Z2 t3 C
8.答案B和D正确。出现解析错误往往表示脚本中有语法错误,自定义的错误管理器无法捕捉到它们的原因很明显:错误管理器在脚本里,而现在无法解析脚本,管理器也就无法执行。类似的,E_ERROR表示有致命的运行错误出现,比如内存耗尽。因此脚本会立刻被中断,因为解释器无法执行后面的代码。; U& u" n; A+ C% j
: N1 P/ L0 _3 c9.答案是C。比较操作是一个可交换的操作(就是说结果独立于操作数之外),而赋值不是。因此,比如说,$a==10和10==$a是等效的,而$a=10和10=$a却不是,而且后者会导致一个错误,因为这不是一个合法的操作。确保常量在操作符前面,能保证你不会错误得将比较变成赋值。
`0 b. D8 Y3 B/ x
+ W: P3 ^. r" R) {. P10.答案是C。error_log函数能将信息送往一个指定的地址。尽管mail()也可以用,但error_log能自动给邮件添加标题,因此这才是最简单的方法。+ k+ q: D1 H9 ^ u- Q+ k! p/ K
2 @ K7 g* q2 {4 s) ^11.答案是不能。error_reporting函数能关闭所有运行时的错误报告,但对解析时的错误无效,因为解析错误发生在脚本执行之前。
) E0 W+ [/ O. Y2 w* G/ z) j, l8 ^: d- u
12.显然,答案是C。概要分析器(profiler)能监视脚本的运行,并记录单个部分的运行时间。它可以用来找出和解决瓶颈。* ]* e9 h2 [' m( x$ V/ d- @
O8 E# q/ k( W# Z! h3 r3 J r$ L% ]13.这是对调试器的完美定义!你可以用调试软件监视脚本运行,同时分析系统资源消耗,从而发现和解决程序缺陷。
- v) `% d/ O. i `6 N2 G0 y6 {6 i; ~- p/ i8 I( K1 E
14.trigger_error()和user_error()之间没有区别。后者其实是前者的别名。
0 c" V/ F; g! r% X9 ? j) c Q% p C& `, E! H1 _# l
15.答案是D。题目是在描述debug_backtrace函数,它返回一个由所有在代码的特定位置调用过的函数名组成的数组。 |
|