  
- UID
- 1
- 帖子
- 738
- 精华
- 28
- 积分
- 14197
- 金币
- 2389
- 威望
- 1647
- 贡献
- 1337
|
[Zend权威认证试题讲解]第十二章 -调试与性能管理
作为一个开发者,无论你经验多么丰富,或者无论你多么努力,你的程序中总会有bug。这是生命中一个必然的部分,如同死亡与缴税(尽管并没有后面两个那么严重)。: i2 _9 |, C& P$ R2 `3 Z( o
要想解决bug,首先要能找到bug。事实上,许多开发者花费了无数小时茫然得盯着代码,只是因为他们没有把程序的容错能力摆在首位。忽略了这个部分,那么期望一个没有bug的程序就是——不可能的。
5 [$ q& H( r1 B本章测试题将考察你对调试和性能管理相关知识的了解,以及如何用PHP做好这两件事。
8 h A- g) Q4 m1 N- Q) u2 |6 E4 v+ W
% }, ]. U8 Y1 N6 j
问题4 w5 I2 k: a! @* k5 k7 C+ Z8 _
; p" l3 f8 ^8 G% U9 Q$ l! {
1.以下脚本如何用三元操作替代?
) {0 {: J2 I* k4 J& a7 g-
- <?php
- if ($a < 10) {
- if ($b > 11) {
- if ($c == 10 && $d != $c) {
- $x = 0;
- } else {
- $x = 1;
- }
- }
- }
- ?>
复制代码 ) @1 }, B& V: b& |, P; V
A.$x = ($a A. < 10 || $b > 11 || $c == 1 && $d != $c) ? 0 : 1;! g- B! c$ l' n8 x
B.$x = ($a < 10 || $b > 11 || ($c == 1 && $d != $c)) ? 0 : 1;
! Z# ]2 v- L( C. }) h5 FC.$x = (($a < 10 && $b > 11) || ($c == 1 && $d != $c)) ? 0 : 1;0 o. Z& U1 ~. A; c# t% f B9 t
D.$x = ($a < 10 && $b > 11 && $c == 1 && $d != $c) ? 1 : 0;* Q, I5 L/ Q% {5 U
E.以上都不对
% H. a% b5 G. S( b: [# J* g5 v& Q+ m2 e4 ~6 c/ n
$ ^2 j0 v z5 f6 _0 V: I* _; W7 u
2.有一个脚本由于要从远程获取数据,因而运行速度很慢,以下那种方法能对其进行优化?(双选)
6 k$ H- j% ~) n6 \9 L6 w: g) [& ?+ b- B5 K' J
A.安装操作码缓存(opcode cache)
6 N; P' Z* ]7 } X/ M( bB.优化或者升级你的网络连接
7 O* L; e1 p& V$ p9 Z8 pC.添置更多的硬件3 r* j& ^& H' ^$ V
D.增加服务器的可用RAM
# V& T( X5 F; d$ s* M A& Q/ iE.使用连接缓存
/ O; y% K% ` r5 @6 N
% S) h6 C- I# U: E& P6 T# l4 W
3 |- J' h, y( i2 k( _3.架设生产环境下的服务器时,需要做哪些步骤?(双选) Y4 `& V$ Z. p# k' b
' D; Q/ e: w0 }4 O9 V X
A.关闭错误报告
) F. O" Z' n4 K$ jB.打开错误日志
7 m( C- D3 L* D6 z+ d3 M4 NC.关闭错误日志7 X* F' u& G% N9 I1 Q
D.关闭错误显示* B5 a2 ]- y/ r7 a4 C
E.使用@抑错符: ]/ U: N9 u6 M3 ^4 T9 |
0 S, ^7 T: N6 [' b# ]% [8 J$ ~4 f; b# m
4.______操作符能对操作数的数据类型进行严格的比较?
1 n" W; T+ A y: a7 S
& q3 B2 v! C' ^" F答案:____________: ^7 {: h# F: \* N" l5 \# N
, F& }+ k* E" x
- b& ]) ]4 n( c1 H, V
5.操作码缓存(opcode cache)能做什么?0 ]4 |; L5 { k" B" B7 C( n
! {) J" C# e4 T9 y) m3 aA.把脚本编译成二进制对象,使它运行得更快0 K- V+ y8 b% G8 ~' z2 c; a# \
B.代替Zend引擎加快解释器的运行
, i3 i& p) t7 @% u" I1 @; j tC.缓存脚本输出以提高执行效率
; Q- j/ \3 s& G$ Y. \# v8 B, eD.缓存解析器产生的中间码,以提高运行效率 ?4 S* ?& R5 J3 c/ i
E.在内存中缓存脚本,减少从硬盘中读取的次数; A% o0 N# D/ M: D" A" s: H$ a
1 ]/ s* [7 K8 ^1 U
$ M: c1 E4 X; ]' o- l6.以下哪些情况容易造成系统资源枯竭?(双选)% B% T% L% z8 x+ C7 _
7 p, t0 m6 G$ F# s6 X! EA.RAM太小5 G# ~( e& X5 J9 q
B.使用了低带宽的连接
& E( \6 I3 P* l$ @. h/ t% fC.虚拟内存超过2GB
+ f! }/ Q' z1 r4 z2 K8 z; uD.允许同时运行太多的服务器进程9 D7 D( s- c- [6 n/ Z5 D
E.以上都不对: R7 H" [! C9 F
# }$ ^+ l: u5 f$ j6 [$ ^0 q. }% }: c% C5 S* [6 l
7.以下脚本缺了些什么?(双选) 5 _% q7 S M7 ?4 o* j) U9 A
-
- <?php
- $rs = database_query ("select * from mytable where id = " .
- $my_id);
- while ($a = database_get_data ($rs)) {
- var_dump ($a);
- }
- ?>
复制代码
{( } s, }' s0 b# ~A.参数出口(Parameter escapement)
, I( a3 c7 `2 F1 q5 ^, L VB.输出格式化
: E" v$ W/ u" KC.错误检查 I/ f( }. ]8 @. O, u
D.一个SQL查询
$ z1 f# g4 F7 ~' V2 e2 Q- J2 w+ p# FE.以上都不对
2 [- _7 i7 m4 A8 T( [% t/ z
( w* t+ e; E4 n e6 J% x! Y4 w
5 C W, R9 J7 s8.以下那种错误类型无法被自定义的错误处理器捕捉到?(双选)2 Z9 ~! j( u r6 n; S
- y& S$ \- a. e
A.E_WARNING
: H$ _) d. p) r& B& [B.E_ERROR
- q6 h7 [$ A( a- H$ D5 d1 e' sC.E_USER_ERROR
/ g1 x% k9 p5 B/ l+ uD.E_PARSE
- z7 S* Q' u q% {E.E_NOTICE
7 e1 N `: \( D/ J: S4 y% V3 o- S/ M; w* L4 q$ W. s, a: m
9 P. C2 |- @9 U+ d& L# e; n) \% O9 O9.当需要比较一个常量和一个变量时,如何才能保证不会错弄成赋值?/ M) e6 v% f2 w) z/ P% i
' f5 z6 ~+ N F9 [% P0 g d- l) xA.把变量转换成int" m5 R6 F& ^4 s
B.使用全等比较符(===)5 G# ?6 e) m& j: j* w5 t
C.确保常量是第一个操作数
/ ^3 x4 m$ E& T. P$ _D.使用三元运算符
+ Y$ O8 D" o# L5 p: m+ L6 xE.用括号把操作包起来5 d; e: d+ t8 k5 @
! |+ {5 A O# E! S- u1 @6 J0 e3 v3 c3 Q7 G7 Y9 c" N* b' s
10.要通过邮件给系统管理员发送错误信息,以下那种方法最简便?
6 h$ u6 _- d# J3 {3 N/ u6 v, R$ z$ b5 q
A.创建一个连接远程SMTP服务器的函数
+ u' y, c% a z5 FB.使用mail函数
( i9 T' m) U0 O; ]* e2 PC.使用error_log函数
" ~0 T: L$ ?" y6 eD.调用sendmial程序3 ]- c" U* J& n5 i& Z
E.使用webservice
) h/ ~9 X" Q' A* F/ D# y) j% u
1 y1 F+ L+ p9 i, i) x4 u
4 M! Z R7 L8 t; l$ p) ^2 h+ [+ [11.能否仅调用一个函数就关闭脚本内所有的错误报告?0 U! W8 D4 I- Q0 `8 ^
( K! O& z& }/ A6 c' q1 W: M
A.能
& B8 s% y& n0 s: ]3 OB.不能
" [- K" ^1 e2 D/ L6 W+ x0 f$ g
! T- z$ C8 o6 \& N+ w% n, f/ b) R- J& |" z& n, ~0 d: K2 H3 z
12.概要分析器(profiler)是做什么的?
$ b: o2 Z& c m2 |, U$ W4 d- [. a5 V; c) w, V3 x
A.创建关于脚本结构的档案
4 Z8 k$ R( |4 w! y9 {5 ~$ WB.把脚本转化成UML图+ o+ a9 n: z3 D! @
C.精确测算脚本不同部分的运行时间
% j- G9 m, F+ L& q% p6 PD.计算脚本通过web服务器执行时的维度$ g4 ?% C0 l" K7 {$ H9 m
E.扫描脚本,识别由常见错误导致的bug
) l ^2 n3 p. i! x5 R; T4 G! o, P5 Y
& e/ g R7 K; M0 S, v# Z' E' y7 v13.______能帮助识别和解决bug。
# n4 J/ c$ Q) H, q' n( h% F8 T' z6 t6 _% y K7 ?
答案:____________
3 |9 _& {. X0 }. @5 F1 U7 N& J E) a. J# C( j) G, ~% e
9 P! k% G( f3 B9 v6 T" T14.trigger_error()和user_error()有什么区别?
2 f; N. |- G+ l, W* h
. s0 j9 X @! q6 R3 A8 @6 sA.trigger_error()允许脚本抛出系统级的错误7 H* d- p; w& N4 t
B.user_error()允许脚本抛出系统级的错误
9 g! r( T+ U; g- P1 `1 wC.user_error()不能被用在错误管理器中5 P5 B) C v: Q/ N- O8 p. h! u
D.trigger_error只在PHP5中可用
& M! m; M4 e$ r0 E8 s1 k8 y' ^E.没有区别
. }, v O2 k3 [3 d8 l& B
' f- Y& A8 Q& M8 d8 s5 ]
' ~/ W/ _" |+ M6 Y3 ~# u15.______函数能返回脚本里任意行中调用的函数的名称。该函数同时还经常被用在调试中,用来判断错误是如何发生的。" {5 i+ r5 g9 E9 V; R
# y9 [7 K& ]* CA.print_r
5 A2 r" q5 [3 r; P1 gB.var_dump
6 \$ l/ G3 R- N$ |( I" U* ZC.stack_dump
7 W& |' \0 a% h6 vD.debug_backtrace
- x1 [) s4 R( M- \8 c. K. NE.以上都不对
* L5 p" e7 F+ A2 J0 j: u2 `% b+ }& d) |' t/ N1 M
答案6 M5 {9 M5 g) {8 ~8 C. M
. C3 [% |* R) w: J1.答案是E。三元操作符把每个if语句连到一起,作为&&操作的一部分。然而本题中,$x=1这个赋值只在第三个if为false时发生。如果第一个和第二个条件都不成立,$x=1就不会执行。这题对三元操作的应用有些极端,实际应用时,需要根据可读性来决定是否需要用三元运算符(本题这种情况就最好不要用)。! a; i+ P: j7 @
& T( \ N, n! C5 m8 M' }4 V3 t
2.问题是由第三方数据源传输缓慢导致的,而你无法控制这个数据源。你也许能在网络连通性上做些工作(假设问题出在你这一边)。还可以对接收到的内容进行缓存,这样能减少获取重复数据的时间。因此,答案是B和E。5 M, p7 K6 G/ N
/ D) {- j* i M) O$ e
3.正确的选择是B和D。如果关闭错误报告、使用@抑错符和关闭错误日志,那么在你交付给客户的网站出现问题时,你将很难进行分析和调试。. Q/ z0 \; ~. Q; H
+ [% D5 n) U3 N. T/ J4.这是在描述===操作符。
% ?, b5 j. d7 ]/ ^/ S5 _, N+ ?# ^* B
5.正确答案是D。PHP脚本在执行时,将首先被解析成“中间”码(也叫opcode,操作码),然后解释器执行。操作码缓存出现在这两个步骤之间,对解析器的输出进行缓存。下次执行该脚本时,将缓存的输出直接送入解释器。这样就就不需要再解析一次了。3 V5 I1 J6 U3 P# [
. n+ |6 `' ?/ \0 m( ?5 D6 }! P7 |3 J
6.正确答案是A和D。如果RAM太小,进程间将出现资源竞争,服务器将大量使用硬盘交换。同样的,如果允许过多进程同时执行,也会使服务器频繁进行交换,导致速度下降。
_$ w) F1 y4 K' s6 @% Y! [; Q0 w
9 ?& Q5 b$ v( D% i7.正确答案是A和C。脚本不检验datebase_query()的调用是否成功,因此将持续执行下去,最终产生错误。此外,$my_id参数没有转义——可能导致代码注入(详见第11章)。- a4 [' S' e, L! h/ m4 S
: d+ v8 R& O+ X+ J+ {$ t- @
8.答案B和D正确。出现解析错误往往表示脚本中有语法错误,自定义的错误管理器无法捕捉到它们的原因很明显:错误管理器在脚本里,而现在无法解析脚本,管理器也就无法执行。类似的,E_ERROR表示有致命的运行错误出现,比如内存耗尽。因此脚本会立刻被中断,因为解释器无法执行后面的代码。1 @8 j6 h' ~4 M* H* O# T6 W* w
* C0 |, Z$ J) w9.答案是C。比较操作是一个可交换的操作(就是说结果独立于操作数之外),而赋值不是。因此,比如说,$a==10和10==$a是等效的,而$a=10和10=$a却不是,而且后者会导致一个错误,因为这不是一个合法的操作。确保常量在操作符前面,能保证你不会错误得将比较变成赋值。6 l" f8 u$ ]( z$ f
& K# p6 k4 I5 Z8 z. c0 j) S10.答案是C。error_log函数能将信息送往一个指定的地址。尽管mail()也可以用,但error_log能自动给邮件添加标题,因此这才是最简单的方法。
) \1 } P" L% u
" V: f+ \# J% ?- ]; P% i0 X/ G11.答案是不能。error_reporting函数能关闭所有运行时的错误报告,但对解析时的错误无效,因为解析错误发生在脚本执行之前。( I! k, a% j4 T" P0 y
+ W- f1 @9 Y, W12.显然,答案是C。概要分析器(profiler)能监视脚本的运行,并记录单个部分的运行时间。它可以用来找出和解决瓶颈。
. n- y+ Q+ O b) k2 k2 M% t6 n: R
13.这是对调试器的完美定义!你可以用调试软件监视脚本运行,同时分析系统资源消耗,从而发现和解决程序缺陷。" d0 \5 F0 p6 R( x
0 D1 }% V3 k& ?1 n1 T
14.trigger_error()和user_error()之间没有区别。后者其实是前者的别名。0 M+ D) k$ L) ?2 p H9 A/ _5 B
! r2 p" }2 v8 ?7 H; M) {& X15.答案是D。题目是在描述debug_backtrace函数,它返回一个由所有在代码的特定位置调用过的函数名组成的数组。 |
|