  
- UID
- 1
- 帖子
- 738
- 精华
- 28
- 积分
- 14197
- 金币
- 2389
- 威望
- 1647
- 贡献
- 1337
|
[Zend权威认证试题讲解]第十二章 -调试与性能管理
作为一个开发者,无论你经验多么丰富,或者无论你多么努力,你的程序中总会有bug。这是生命中一个必然的部分,如同死亡与缴税(尽管并没有后面两个那么严重)。. K9 g3 n: l$ D3 T( u# r; c' J
要想解决bug,首先要能找到bug。事实上,许多开发者花费了无数小时茫然得盯着代码,只是因为他们没有把程序的容错能力摆在首位。忽略了这个部分,那么期望一个没有bug的程序就是——不可能的。: [; o( n, V/ n2 D2 |
本章测试题将考察你对调试和性能管理相关知识的了解,以及如何用PHP做好这两件事。
$ V- w7 o5 C7 _# Y, H% M9 t! x9 A$ i/ q& k. T& v* [" G* r
) J- g* I- o) T1 x: i, i: e
问题( ~% Z5 f: ~+ |! s+ A
# H' ~& l1 E) J7 G, [( p1 j1.以下脚本如何用三元操作替代?
: X+ h7 A5 u/ `$ A* F-
- <?php
- if ($a < 10) {
- if ($b > 11) {
- if ($c == 10 && $d != $c) {
- $x = 0;
- } else {
- $x = 1;
- }
- }
- }
- ?>
复制代码 - ~/ B8 w# w6 m' L8 ?! f
A.$x = ($a A. < 10 || $b > 11 || $c == 1 && $d != $c) ? 0 : 1;/ g$ b# r" B" `6 `% [
B.$x = ($a < 10 || $b > 11 || ($c == 1 && $d != $c)) ? 0 : 1;0 d% x5 q8 n' |) G% i+ t
C.$x = (($a < 10 && $b > 11) || ($c == 1 && $d != $c)) ? 0 : 1;0 ~4 B. R! }! n1 P- L3 A
D.$x = ($a < 10 && $b > 11 && $c == 1 && $d != $c) ? 1 : 0;
' v. T5 t& k" D) S$ UE.以上都不对
3 q; Q3 W5 G/ A1 p0 Q+ k- ~" k) v3 p4 g7 F5 U) j4 ?: [
0 Y# d1 g( q8 T8 ?/ W! T1 T0 V7 m2.有一个脚本由于要从远程获取数据,因而运行速度很慢,以下那种方法能对其进行优化?(双选)
9 F$ P( n1 q& @7 G
3 K2 ^' Y9 E* M/ y9 |4 IA.安装操作码缓存(opcode cache)8 {0 m1 b$ D) e3 J, V
B.优化或者升级你的网络连接: V; d& |- V" ~, q h2 }+ c
C.添置更多的硬件+ y0 F; Y6 r' N5 I3 w
D.增加服务器的可用RAM
- p% h) g0 ?- Y; A8 a. |E.使用连接缓存" f' _% N9 B# u$ e; F" |, S# V/ u
" L8 ]2 ^6 `. S; z* l
3 }: f0 y/ F2 M) l f/ v
3.架设生产环境下的服务器时,需要做哪些步骤?(双选)
0 h- E( I! B' q5 p& g' M8 G; z$ V# s
A.关闭错误报告, ?: F+ v- @, R# V
B.打开错误日志
m2 p1 c9 b, IC.关闭错误日志+ ~9 ~/ R; T% c S
D.关闭错误显示5 k. M3 L/ t; L5 a6 X
E.使用@抑错符2 d; ], v5 J: W3 ~5 X e
5 i& _. X; u8 x2 M& K3 }" ?3 U$ \: F1 A& H$ R W! W
4.______操作符能对操作数的数据类型进行严格的比较?& |, A+ B: _0 _+ l4 t* M: q
; d0 G. m* z' |! G
答案:____________9 x$ U9 [- ^$ D# m
( ^9 x* P8 W1 y [* S! [- l* J/ ]/ Y7 B
5.操作码缓存(opcode cache)能做什么?
, i( {" ?( u: v' x: e5 j1 s" H1 h& {9 O5 y' x- h
A.把脚本编译成二进制对象,使它运行得更快% m; D8 A' S* v8 d0 V; Q* ~# v
B.代替Zend引擎加快解释器的运行
1 f% o6 l( [$ d4 b6 v' S4 ?, [C.缓存脚本输出以提高执行效率
* j( Z: u9 w, l- O* @7 LD.缓存解析器产生的中间码,以提高运行效率
1 B, b' [: {. j. Z9 PE.在内存中缓存脚本,减少从硬盘中读取的次数
2 O @0 H" K) S- v
5 k$ W1 R: I H6 m* @9 l+ S* a
; T( ?! i% {. e4 X e. Q! ~6.以下哪些情况容易造成系统资源枯竭?(双选)
, ]0 r; e3 D+ d2 |+ R9 i
, p6 |( l( J) mA.RAM太小
' Y6 s4 k" l. J7 R4 ~B.使用了低带宽的连接$ J7 G6 [3 k) E8 A; P5 t1 t. y. [
C.虚拟内存超过2GB! ], |6 I0 `4 w; h2 t$ y# O* X
D.允许同时运行太多的服务器进程2 \5 a; R! T3 e; T! G
E.以上都不对3 X2 ~. ^5 F% _: ]" A6 O
/ @ j0 G" l1 l* |- F$ P2 y
( Y% Y* i; v. m: u0 |
7.以下脚本缺了些什么?(双选) . h* w% [1 G+ R( V6 g% ^
-
- <?php
- $rs = database_query ("select * from mytable where id = " .
- $my_id);
- while ($a = database_get_data ($rs)) {
- var_dump ($a);
- }
- ?>
复制代码 9 s6 r9 q3 ~( m; j8 h4 e2 `
A.参数出口(Parameter escapement)
4 A4 ^6 S' k" Z, D5 PB.输出格式化. w: `# u# N' z; g# h
C.错误检查& {, X" R! r+ x4 B; C
D.一个SQL查询
3 ^6 T& C4 b! ~% Z) l( QE.以上都不对) h6 v1 L8 z W: g( M( { n( O
4 x/ f5 K0 S$ C6 o% J0 i
) E6 X/ P: ]$ V. t Q6 E. [0 v9 y8.以下那种错误类型无法被自定义的错误处理器捕捉到?(双选)) ]9 I6 |' D" X' J3 z
/ ^! z, t5 M- D' ZA.E_WARNING
6 o2 F5 E0 ^, W( eB.E_ERROR
" h, d0 y+ s. `C.E_USER_ERROR+ u# t9 S6 u: {& R
D.E_PARSE/ q/ K7 s" T3 V+ W, F
E.E_NOTICE
0 j. U! h, U) S( K6 F( Q) h* i" Z* m! ~1 }
+ f0 z* r C4 ]5 l" ? _( ~9.当需要比较一个常量和一个变量时,如何才能保证不会错弄成赋值?
- m$ s0 h( d$ L$ }' u/ T* J
$ g* T% l: N& w3 y$ gA.把变量转换成int
" n4 C7 _3 Z M4 kB.使用全等比较符(===)
9 A0 U1 q9 _; o$ s/ _; qC.确保常量是第一个操作数: F* _% a- u3 E2 ^
D.使用三元运算符
8 m" h9 q" A: r0 u4 ^: M) o! J$ S' fE.用括号把操作包起来
+ ~) t$ Z6 H. l5 e/ G$ O& b. U$ ?7 t: n: Y Y g5 y9 m5 K
9 Y( U% V" R0 \& p7 Z7 n& q' v10.要通过邮件给系统管理员发送错误信息,以下那种方法最简便?
5 H) ?; S& p1 _- G) f; O$ i
8 c3 E, W% F# z5 ]A.创建一个连接远程SMTP服务器的函数
9 M* `% |0 w! p# i$ ]' \6 @6 cB.使用mail函数
[: `( o& E p+ J- r6 I+ b0 ]1 TC.使用error_log函数, r$ J3 C" g' L
D.调用sendmial程序
- c" ?% z! m% g7 D( G$ h9 c5 C$ AE.使用webservice' N+ u% ^9 } j% [1 f; R P. ]
9 u: y8 f2 _/ `' S
" S; E7 E" s" \) `* v* y
11.能否仅调用一个函数就关闭脚本内所有的错误报告?
8 p4 a+ `) ^: Q$ d$ p
0 D" p! q, T A5 N+ n* cA.能9 t& J4 ?6 {( p/ y
B.不能' q1 ]9 v1 F7 ^! V& t( u- y. D
% L; v4 Q, O$ [1 z' f) @
* m4 T C7 T2 ^% K2 C
12.概要分析器(profiler)是做什么的?' W/ z8 n6 u0 P5 H6 p) o
z" w. [( |. l& h/ |- @, V$ T% r
A.创建关于脚本结构的档案/ d4 F% f6 Q- x% y( L/ Y
B.把脚本转化成UML图" {& F* T7 ~# x0 z6 l6 l
C.精确测算脚本不同部分的运行时间
/ ~) R9 T. a3 y- kD.计算脚本通过web服务器执行时的维度6 Q! y% q6 C J6 R' @9 C
E.扫描脚本,识别由常见错误导致的bug* y" d7 w7 l0 o; ~
% h! h4 H+ q8 \! W8 D4 L
/ N' q( K0 Y9 m- ]/ v, v' ^# k2 M
13.______能帮助识别和解决bug。
1 b: F' o7 ~5 b5 r- a% V6 u/ B; B* W5 c
答案:____________
7 n# l5 b! B- X2 }
' q5 ^$ A! I& `+ b
4 q1 X7 I5 n- t4 { F6 `14.trigger_error()和user_error()有什么区别?
+ N3 o# _, y0 Q/ [
! Q0 x8 U7 L8 o# q4 w3 E0 nA.trigger_error()允许脚本抛出系统级的错误
/ H- Y& S2 J) A( d" i$ dB.user_error()允许脚本抛出系统级的错误
. h* y0 P u1 }% I! ~6 J* q) U5 GC.user_error()不能被用在错误管理器中
2 G- z- ? W6 _D.trigger_error只在PHP5中可用
) \( v, Q' v5 p; e# cE.没有区别
( Z/ ^. P- _! q4 G
8 k; l8 v( Q/ B$ d0 H" B+ j0 c" P1 ]9 y5 ?: Y7 a
15.______函数能返回脚本里任意行中调用的函数的名称。该函数同时还经常被用在调试中,用来判断错误是如何发生的。$ O6 c6 U$ @% q( I' l
7 w# P/ H0 f& C1 x1 V) N
A.print_r
. p0 f/ M$ F% l$ }B.var_dump0 [+ e# T$ C' G; ?
C.stack_dump
! @0 T( L% p8 q. B4 FD.debug_backtrace* m$ f+ D5 I! ?( s! m
E.以上都不对2 X! t5 N6 s0 `$ ?6 s& V
2 n) I/ u4 v" q0 {1 s* }* K
答案
& i, @$ S1 V: z
6 o0 u' H) o& c7 L1.答案是E。三元操作符把每个if语句连到一起,作为&&操作的一部分。然而本题中,$x=1这个赋值只在第三个if为false时发生。如果第一个和第二个条件都不成立,$x=1就不会执行。这题对三元操作的应用有些极端,实际应用时,需要根据可读性来决定是否需要用三元运算符(本题这种情况就最好不要用)。3 q7 v: e& J0 y/ T6 x# n
4 F' o6 K' G3 `) I* D" L0 Z9 |8 k
2.问题是由第三方数据源传输缓慢导致的,而你无法控制这个数据源。你也许能在网络连通性上做些工作(假设问题出在你这一边)。还可以对接收到的内容进行缓存,这样能减少获取重复数据的时间。因此,答案是B和E。
$ k# ^$ C' a( R& c$ V) t4 K2 D7 e- \: F# Y1 O+ W2 g4 h
3.正确的选择是B和D。如果关闭错误报告、使用@抑错符和关闭错误日志,那么在你交付给客户的网站出现问题时,你将很难进行分析和调试。
9 x( w+ B" S) s) l% P3 z
w& p5 ]8 i' ?+ D+ f4.这是在描述===操作符。1 D1 q/ n# ^% a/ H8 A
W M( c9 e* V s) M# ^( q* \
5.正确答案是D。PHP脚本在执行时,将首先被解析成“中间”码(也叫opcode,操作码),然后解释器执行。操作码缓存出现在这两个步骤之间,对解析器的输出进行缓存。下次执行该脚本时,将缓存的输出直接送入解释器。这样就就不需要再解析一次了。* c1 ~1 N0 G) M' {# _+ Q6 M2 o
0 c$ R' A3 B3 @% d
6.正确答案是A和D。如果RAM太小,进程间将出现资源竞争,服务器将大量使用硬盘交换。同样的,如果允许过多进程同时执行,也会使服务器频繁进行交换,导致速度下降。% W- y, l% h( S) D- K) o/ |" Z3 m
0 w: w7 D& o+ ]' W h
7.正确答案是A和C。脚本不检验datebase_query()的调用是否成功,因此将持续执行下去,最终产生错误。此外,$my_id参数没有转义——可能导致代码注入(详见第11章)。: A+ d- `0 f5 u
3 e& A0 T* h& t( H% S: d8.答案B和D正确。出现解析错误往往表示脚本中有语法错误,自定义的错误管理器无法捕捉到它们的原因很明显:错误管理器在脚本里,而现在无法解析脚本,管理器也就无法执行。类似的,E_ERROR表示有致命的运行错误出现,比如内存耗尽。因此脚本会立刻被中断,因为解释器无法执行后面的代码。
% [6 s' k0 C8 L
: a: s ?8 ?9 R* d9.答案是C。比较操作是一个可交换的操作(就是说结果独立于操作数之外),而赋值不是。因此,比如说,$a==10和10==$a是等效的,而$a=10和10=$a却不是,而且后者会导致一个错误,因为这不是一个合法的操作。确保常量在操作符前面,能保证你不会错误得将比较变成赋值。
% G" v- X* V' u9 t8 h; k7 A' k& Q. `/ s- h
10.答案是C。error_log函数能将信息送往一个指定的地址。尽管mail()也可以用,但error_log能自动给邮件添加标题,因此这才是最简单的方法。
( F; R c |- a; @! e
; g5 M( D, K; |, X$ f5 i3 v' |11.答案是不能。error_reporting函数能关闭所有运行时的错误报告,但对解析时的错误无效,因为解析错误发生在脚本执行之前。
& S- n* @. J. n+ R; i2 s# j1 i
12.显然,答案是C。概要分析器(profiler)能监视脚本的运行,并记录单个部分的运行时间。它可以用来找出和解决瓶颈。5 X8 c7 l" A ?- L/ E
9 V$ i) P% u) Z: ]. l( n13.这是对调试器的完美定义!你可以用调试软件监视脚本运行,同时分析系统资源消耗,从而发现和解决程序缺陷。9 Q A) S! Q. ~; e$ l2 m
7 P/ T; q' Y- a1 Z( _5 L6 b
14.trigger_error()和user_error()之间没有区别。后者其实是前者的别名。% N* W8 @8 @( k" _
! h' I, R6 k! ^! [8 W4 e( ^- {15.答案是D。题目是在描述debug_backtrace函数,它返回一个由所有在代码的特定位置调用过的函数名组成的数组。 |
|