  
- UID
- 1
- 帖子
- 738
- 精华
- 28
- 积分
- 14197
- 金币
- 2389
- 威望
- 1647
- 贡献
- 1337
|
[Zend权威认证试题讲解]第十二章 -调试与性能管理
作为一个开发者,无论你经验多么丰富,或者无论你多么努力,你的程序中总会有bug。这是生命中一个必然的部分,如同死亡与缴税(尽管并没有后面两个那么严重)。
9 P) I9 t9 ?$ C1 S/ t" w; {2 p; i要想解决bug,首先要能找到bug。事实上,许多开发者花费了无数小时茫然得盯着代码,只是因为他们没有把程序的容错能力摆在首位。忽略了这个部分,那么期望一个没有bug的程序就是——不可能的。" t( A, ?9 U" @' B3 `
本章测试题将考察你对调试和性能管理相关知识的了解,以及如何用PHP做好这两件事。
& V- d' h7 T* Z0 V7 n1 c7 Z/ e ?4 M, a, o* K! n
3 W) O% Q# K& D) a. i# o$ X0 b% Z
问题; H) |* x2 ^5 ^. H! `4 J# F" K
. T" V5 @* p R* t _6 S& e/ ]
1.以下脚本如何用三元操作替代? 6 \$ n2 U/ ^, \! _
-
- <?php
- if ($a < 10) {
- if ($b > 11) {
- if ($c == 10 && $d != $c) {
- $x = 0;
- } else {
- $x = 1;
- }
- }
- }
- ?>
复制代码
7 r) U+ U3 F# V3 P1 l2 A+ c) \! yA.$x = ($a A. < 10 || $b > 11 || $c == 1 && $d != $c) ? 0 : 1;6 b9 Q" O; V3 G6 e( O v
B.$x = ($a < 10 || $b > 11 || ($c == 1 && $d != $c)) ? 0 : 1;3 E5 V9 H- \) G% z3 W9 U
C.$x = (($a < 10 && $b > 11) || ($c == 1 && $d != $c)) ? 0 : 1;2 X+ q5 |( f; k' w2 |; F! q1 q4 d
D.$x = ($a < 10 && $b > 11 && $c == 1 && $d != $c) ? 1 : 0;, h& ~! ~* {7 n8 e# _
E.以上都不对* I8 s) Z; O' v% X5 h% Q
3 D m# M+ H7 a( |2 u. z, ^" i
" M7 O- S% x5 ?3 W, L$ z2.有一个脚本由于要从远程获取数据,因而运行速度很慢,以下那种方法能对其进行优化?(双选)
2 v" D9 B1 v4 Y
! c9 D( |+ P# Y i1 ^A.安装操作码缓存(opcode cache)* l! @. |, h+ h6 H& r/ Y
B.优化或者升级你的网络连接! j0 U* Q" o @1 w Z- E* w
C.添置更多的硬件. i( W* x! X8 [! v& f
D.增加服务器的可用RAM7 ^! d# ]$ r4 u U6 B$ l, b v7 m
E.使用连接缓存. B0 ~1 t! l6 | r8 L$ ~
: P2 t$ C: w) @0 d6 {
+ H8 i* @4 ?8 b- M6 l5 X3.架设生产环境下的服务器时,需要做哪些步骤?(双选)
+ a6 p- d6 c {4 @
5 o% g% u. H( v7 L5 i% vA.关闭错误报告
$ _! ?% g# C2 m6 gB.打开错误日志( r% O* T3 e. |4 y0 l1 h
C.关闭错误日志
2 D# a& ^" s }8 r; [# kD.关闭错误显示. {' S' x1 a" r
E.使用@抑错符
7 t4 L p6 |, k) B9 g8 T; g& D* G
" N! _2 y5 z5 H: P
% g; Z4 i7 U, h+ K* ~4.______操作符能对操作数的数据类型进行严格的比较?
9 q* A' j, Q, q4 l3 o( Q% d$ k' G! X! p& W2 @5 `- h, o
答案:____________
. o4 K4 a! @6 m1 w- L4 M* B5 i1 B
# O4 m. p7 f8 }+ r$ n: h
5.操作码缓存(opcode cache)能做什么?
( S* w/ L7 [) D; J; Y+ o* O
/ `4 g" ~# D+ i' ?7 fA.把脚本编译成二进制对象,使它运行得更快( E/ L2 l# |' s8 d- ]& {
B.代替Zend引擎加快解释器的运行
2 M' y( k3 U$ y, p" |" RC.缓存脚本输出以提高执行效率# {. ~& q+ a6 n( O8 H
D.缓存解析器产生的中间码,以提高运行效率1 C4 ?" Z4 G& Q) S9 ~4 q0 y
E.在内存中缓存脚本,减少从硬盘中读取的次数% `% J) Y/ D, i6 H! [
$ x( z$ o# O; w- p2 x) f& W8 [! s8 e; Q3 }8 `( L
6.以下哪些情况容易造成系统资源枯竭?(双选)# }( B3 ]9 c1 q, N% U
# ` B; O7 M( i( F! nA.RAM太小8 ~! i* j, b* ]6 P0 { f! V
B.使用了低带宽的连接6 C& s& |- n n0 l0 R l0 P
C.虚拟内存超过2GB. Q) R9 O, n8 H
D.允许同时运行太多的服务器进程
% Y0 f9 p+ `) J+ S! ^E.以上都不对4 \9 i- o+ d d" J; W7 M" L
- @3 b' _. k% ^; F% ~- E* `, n6 F8 M* F" X
7.以下脚本缺了些什么?(双选)
2 s# j& X( f: T% V7 @. g5 C-
- <?php
- $rs = database_query ("select * from mytable where id = " .
- $my_id);
- while ($a = database_get_data ($rs)) {
- var_dump ($a);
- }
- ?>
复制代码
! v( [& b* G/ _. _5 HA.参数出口(Parameter escapement)$ n. _, J6 z1 @5 ?
B.输出格式化" R7 D. N$ C' j; M9 z# I9 y
C.错误检查7 d0 w5 k: k# Y% b, v$ x. K* X
D.一个SQL查询0 Z5 H! N! h0 r+ \7 w4 r
E.以上都不对
$ E$ r6 Z1 Q! M& F7 @8 W& j- [+ x4 i# w1 Z/ M
7 w/ Z' r1 j' j2 G& b2 {4 P" p( N8.以下那种错误类型无法被自定义的错误处理器捕捉到?(双选)" ]5 B" r6 z; ] l3 ]& A
: a0 k) p7 J" ^6 CA.E_WARNING
4 r4 c; c% k6 x& yB.E_ERROR! c# m& |) I& X( b* B: q
C.E_USER_ERROR" d7 ^8 Z" m$ e2 o; E. C
D.E_PARSE1 m8 C' v b9 j: e) V! h7 n
E.E_NOTICE
7 }& c! q4 n [; x0 v" ?2 u: Y# i- R8 @7 d- |* m$ c8 G9 N3 ?# O
; O7 W$ F7 L* |% D3 h; c
9.当需要比较一个常量和一个变量时,如何才能保证不会错弄成赋值?
8 ^. a4 v; E0 R4 S3 ^+ |, k5 t' v; |7 A5 Z
A.把变量转换成int
r# I# ?: B0 h4 H' _B.使用全等比较符(===). x5 N5 e7 z* \ _- e! N
C.确保常量是第一个操作数3 M9 m5 O* y, o& x9 }) n( `! V+ U
D.使用三元运算符& \& w& B h: M
E.用括号把操作包起来
1 A/ C* y# W! B3 i3 f6 \% r0 ^4 E1 Z8 W% |6 j' @
5 {" l5 y1 @) G' q
10.要通过邮件给系统管理员发送错误信息,以下那种方法最简便?. K% t* r P( |. M. _
( ] L- R) X# q3 T2 k' F) A
A.创建一个连接远程SMTP服务器的函数4 d- J# q2 G: ~8 O; j- I" D
B.使用mail函数
/ b1 G& d! R% O# A Y/ k! V- Y; V$ \$ wC.使用error_log函数- _9 ~& @- Y2 d/ @0 ?. o
D.调用sendmial程序5 y3 ^* ]1 F. E
E.使用webservice$ s' Y$ B: O" E' v A
. z+ d' R1 |/ y% i. R; P
4 ]1 V0 v: _$ s; }
11.能否仅调用一个函数就关闭脚本内所有的错误报告?
4 w* z# G. r! n' e8 Y( M3 A6 X9 R
A.能7 B9 g# K. ^) z+ W5 U/ M, t0 ?
B.不能% Z, K u6 ^' b& t2 a, w
" G+ ~2 }/ y* M0 B6 J9 F+ p& z: r; r3 z: k, t
12.概要分析器(profiler)是做什么的?
5 }" I! X" U! a+ k/ `3 t
0 E' t1 I5 x9 Q. ~* f4 ^- VA.创建关于脚本结构的档案
0 |7 X% W/ c% l2 U' N9 yB.把脚本转化成UML图* T7 y) z% H9 O/ x* S- `, C
C.精确测算脚本不同部分的运行时间
U/ S! V6 r2 q# ]" t8 JD.计算脚本通过web服务器执行时的维度0 V9 x2 E5 x8 p5 V B
E.扫描脚本,识别由常见错误导致的bug
9 [* b- k _- }1 ]
# z9 I* Q: c V {9 [9 H3 P" u/ x
13.______能帮助识别和解决bug。
9 B+ i$ d6 w2 a8 r$ ]0 y+ \0 w: N
2 n+ k1 I2 v2 \ W6 w! a0 G* d答案:____________
" |& f$ O/ q2 |4 Q/ D! x/ [; V. [
0 C* m4 G: y: k2 g
- ]1 L5 X) i" a+ \14.trigger_error()和user_error()有什么区别?
7 e) D( S- v& d: |9 N
8 d% J2 D" Q1 l3 j5 J% h/ TA.trigger_error()允许脚本抛出系统级的错误8 e1 f8 `8 e& h. O, U9 U7 _+ a: _5 `
B.user_error()允许脚本抛出系统级的错误! P9 [# I; N4 m0 M1 F) ?! N0 y6 P
C.user_error()不能被用在错误管理器中5 k9 o4 Y6 N3 m! O2 u! k+ N/ s8 w. |0 z. ?
D.trigger_error只在PHP5中可用2 h X2 E# u( S! h. ]/ V* @9 [/ v+ t6 b
E.没有区别
, j& {$ [8 Z3 n! l2 G$ ?
* T6 R, F" M. m* x ?+ k/ |" K* R# K& G+ S
15.______函数能返回脚本里任意行中调用的函数的名称。该函数同时还经常被用在调试中,用来判断错误是如何发生的。1 F# E! O9 }5 \ `
# R6 t8 M/ E2 `; `3 O cA.print_r
. X$ A) t( W( j7 a/ h0 z& y% rB.var_dump4 z" Z6 R5 ^: A1 g* r
C.stack_dump
3 X% \& x9 U. D- x7 A" xD.debug_backtrace
2 K6 m' C' P2 CE.以上都不对! Z4 P* Y% D0 A
" \+ P- R) G4 {
答案
- J8 G, u1 ]% C' i. |' p
/ L6 X# {: T5 v$ r/ X% m+ N1.答案是E。三元操作符把每个if语句连到一起,作为&&操作的一部分。然而本题中,$x=1这个赋值只在第三个if为false时发生。如果第一个和第二个条件都不成立,$x=1就不会执行。这题对三元操作的应用有些极端,实际应用时,需要根据可读性来决定是否需要用三元运算符(本题这种情况就最好不要用)。
) r9 G# l n- x1 X& c
, `# T3 n3 `' z" I* g2.问题是由第三方数据源传输缓慢导致的,而你无法控制这个数据源。你也许能在网络连通性上做些工作(假设问题出在你这一边)。还可以对接收到的内容进行缓存,这样能减少获取重复数据的时间。因此,答案是B和E。0 N0 F( J n) l' ]7 m$ r) V
: [+ h3 m- P! i3.正确的选择是B和D。如果关闭错误报告、使用@抑错符和关闭错误日志,那么在你交付给客户的网站出现问题时,你将很难进行分析和调试。
% Q: m1 a) i$ o) c: J
6 c, x; q# i1 ?! Z4.这是在描述===操作符。% ?' [; {, u1 |. f" i' b
* Z' ~- U, x- O0 [* b1 \, }
5.正确答案是D。PHP脚本在执行时,将首先被解析成“中间”码(也叫opcode,操作码),然后解释器执行。操作码缓存出现在这两个步骤之间,对解析器的输出进行缓存。下次执行该脚本时,将缓存的输出直接送入解释器。这样就就不需要再解析一次了。
7 G$ ^& ?) _8 ~0 T0 j) y& @0 w5 E4 k& H
7 y( l5 E6 ~5 t6.正确答案是A和D。如果RAM太小,进程间将出现资源竞争,服务器将大量使用硬盘交换。同样的,如果允许过多进程同时执行,也会使服务器频繁进行交换,导致速度下降。
% o2 g4 _8 d. v7 W9 U6 q
5 v3 U+ V7 D; n& h7.正确答案是A和C。脚本不检验datebase_query()的调用是否成功,因此将持续执行下去,最终产生错误。此外,$my_id参数没有转义——可能导致代码注入(详见第11章)。
8 z. w. `$ ]3 }, e' A0 c0 B; X$ [* E+ u' i, I
8.答案B和D正确。出现解析错误往往表示脚本中有语法错误,自定义的错误管理器无法捕捉到它们的原因很明显:错误管理器在脚本里,而现在无法解析脚本,管理器也就无法执行。类似的,E_ERROR表示有致命的运行错误出现,比如内存耗尽。因此脚本会立刻被中断,因为解释器无法执行后面的代码。
$ u0 p) J+ }, \0 B% B9 M4 @# y% l: w) i- A
9.答案是C。比较操作是一个可交换的操作(就是说结果独立于操作数之外),而赋值不是。因此,比如说,$a==10和10==$a是等效的,而$a=10和10=$a却不是,而且后者会导致一个错误,因为这不是一个合法的操作。确保常量在操作符前面,能保证你不会错误得将比较变成赋值。, |8 Q0 \+ Q/ t. F# |
3 u4 p; o* r" z1 v1 n" o
10.答案是C。error_log函数能将信息送往一个指定的地址。尽管mail()也可以用,但error_log能自动给邮件添加标题,因此这才是最简单的方法。
! _3 p7 l+ O, c* g* L4 I
0 J! z) I, ~/ }$ f. L2 K" b11.答案是不能。error_reporting函数能关闭所有运行时的错误报告,但对解析时的错误无效,因为解析错误发生在脚本执行之前。
* x1 T3 g* H; Y# b6 M. s5 s) M- Z& ~
i5 e# }" m' `, G12.显然,答案是C。概要分析器(profiler)能监视脚本的运行,并记录单个部分的运行时间。它可以用来找出和解决瓶颈。( S9 s# k. r- ~( n
5 K" G( B7 R* S. x- y. ^. Y/ Y* |
13.这是对调试器的完美定义!你可以用调试软件监视脚本运行,同时分析系统资源消耗,从而发现和解决程序缺陷。
' R3 Y2 c% H. t( m& w4 p( c8 t. ~ G& n
14.trigger_error()和user_error()之间没有区别。后者其实是前者的别名。
( Y9 { S/ H$ E: }9 h( h3 m; k- z6 j% A( P" O- l
15.答案是D。题目是在描述debug_backtrace函数,它返回一个由所有在代码的特定位置调用过的函数名组成的数组。 |
|