  
- UID
- 1
- 帖子
- 738
- 精华
- 28
- 积分
- 14189
- 金币
- 2385
- 威望
- 1647
- 贡献
- 1333
|
[Zend权威认证试题讲解]第十二章 -调试与性能管理
作为一个开发者,无论你经验多么丰富,或者无论你多么努力,你的程序中总会有bug。这是生命中一个必然的部分,如同死亡与缴税(尽管并没有后面两个那么严重)。5 o Y; A3 h* R& L: P& M& j7 N
要想解决bug,首先要能找到bug。事实上,许多开发者花费了无数小时茫然得盯着代码,只是因为他们没有把程序的容错能力摆在首位。忽略了这个部分,那么期望一个没有bug的程序就是——不可能的。 w4 v& ]9 C# b' B3 u6 \$ l
本章测试题将考察你对调试和性能管理相关知识的了解,以及如何用PHP做好这两件事。4 e) W, U/ |7 q( b+ B, i
% m& Z1 c3 }3 }8 Y* b& }
3 ]% T3 L& ^7 r1 A
问题
( o7 w" o% X: C1 O- g& O
% Q6 f4 U/ O7 V4 t- e1.以下脚本如何用三元操作替代?
5 K) v8 Q0 t& o# `' i/ W. L-
- <?php
- if ($a < 10) {
- if ($b > 11) {
- if ($c == 10 && $d != $c) {
- $x = 0;
- } else {
- $x = 1;
- }
- }
- }
- ?>
复制代码
" @3 J: ]5 q; R8 F9 UA.$x = ($a A. < 10 || $b > 11 || $c == 1 && $d != $c) ? 0 : 1;" s/ L0 ?4 m+ G' C' r: f, I
B.$x = ($a < 10 || $b > 11 || ($c == 1 && $d != $c)) ? 0 : 1;
9 _# q. G. o n2 } UC.$x = (($a < 10 && $b > 11) || ($c == 1 && $d != $c)) ? 0 : 1;- b- I4 e! W4 W( B9 L* M
D.$x = ($a < 10 && $b > 11 && $c == 1 && $d != $c) ? 1 : 0;
# c* h3 `) M# b3 p2 c) Z" i8 SE.以上都不对
8 u& }4 z; ~& }1 m3 @$ Z, c& y4 @/ {1 ~: H
' J: K6 C1 ]6 o# N5 k# _2 F
2.有一个脚本由于要从远程获取数据,因而运行速度很慢,以下那种方法能对其进行优化?(双选)
& z: o" l+ m7 m. X" V, Q) N- D2 _
) y* [4 S1 V/ D5 k% n5 wA.安装操作码缓存(opcode cache)
. {5 r4 a3 G0 }3 C6 CB.优化或者升级你的网络连接0 h/ A- m& O$ d ]
C.添置更多的硬件. z4 ]( J( u& \1 e+ U! v; }4 l
D.增加服务器的可用RAM( A1 N$ X: e# _* K
E.使用连接缓存
9 [% B: e3 i0 Z" n% s
[5 s. _; m9 H" m
$ P( m/ L9 Y& I/ b3.架设生产环境下的服务器时,需要做哪些步骤?(双选)
( d, m, S- V+ U! o R
9 c( T6 p+ g( ~" G5 X CA.关闭错误报告
$ Y8 S0 Y, k# s3 P9 p: |! a5 ^B.打开错误日志5 D! p- p: M9 C# ?
C.关闭错误日志
$ u! u& ]0 s0 S9 |9 a! [D.关闭错误显示
5 ~# F; `. A" s" l% mE.使用@抑错符/ v. ~7 s8 k5 C
6 P8 ]" i* r, X9 a" `
' d+ ?9 H, G' a4.______操作符能对操作数的数据类型进行严格的比较?9 x; ?) V( e+ @0 ]
2 ?9 t) g3 r- f3 P' Y
答案:____________
% Q' `$ i, _, G' t- L: F/ S% K" ~9 r. C+ Q! i1 E
3 l @" [% c+ }8 r
5.操作码缓存(opcode cache)能做什么?$ @- E0 M2 Y8 {9 x" z
2 c' z' Z4 A, Z% _3 c) z$ mA.把脚本编译成二进制对象,使它运行得更快: V* P K8 {2 W. i1 W
B.代替Zend引擎加快解释器的运行
' |# h- T7 Z% j1 {+ Y# p- iC.缓存脚本输出以提高执行效率3 Q" R0 \9 k1 G" ]! {4 }
D.缓存解析器产生的中间码,以提高运行效率4 s5 W- J) J5 Y3 K9 T
E.在内存中缓存脚本,减少从硬盘中读取的次数3 o! Y f# I6 H/ f9 D. y
# Y1 D3 {9 F. Y7 c) f
4 k2 E) y0 Q/ A
6.以下哪些情况容易造成系统资源枯竭?(双选)
* H3 M/ V1 `2 Y( \* f
. ~$ ^4 f# r+ T1 dA.RAM太小6 Z8 y/ m; B6 c) x
B.使用了低带宽的连接
4 @7 r3 P0 ]0 E5 ?+ N5 k# ?C.虚拟内存超过2GB
, D9 ~. u- U( y- h& D$ H. lD.允许同时运行太多的服务器进程
% S9 @% {6 o5 mE.以上都不对
5 q' c& D% K9 f' j @ C$ Y% }# `6 O, V8 U
a' C8 d8 \5 ]9 N x; ^7.以下脚本缺了些什么?(双选)
# r) E2 ^( `# t8 B& E: J; j4 l' t-
- <?php
- $rs = database_query ("select * from mytable where id = " .
- $my_id);
- while ($a = database_get_data ($rs)) {
- var_dump ($a);
- }
- ?>
复制代码
9 d5 o8 a- P4 MA.参数出口(Parameter escapement)+ H# I( L6 d. X- T! O5 P* l
B.输出格式化1 @' S& F8 ]# X- w* s2 P. A
C.错误检查
/ o6 ?+ e/ K# V* m# tD.一个SQL查询
! j) F* u. N5 \! W' y# u' h6 cE.以上都不对
+ I6 z: E2 S' o6 U* _, W2 a0 v6 H2 _& X5 `3 U; t
7 M& ^6 ]# G0 Q4 k. T* `4 ~
8.以下那种错误类型无法被自定义的错误处理器捕捉到?(双选)0 g9 `! L' s) ^5 a" `
# e3 j0 `! X) s$ M
A.E_WARNING
- s7 B3 o5 Q5 U& AB.E_ERROR
7 _) e; C! `/ ~C.E_USER_ERROR1 J" D0 _5 m# A6 n. c0 \* M
D.E_PARSE
# E8 b8 z+ h" jE.E_NOTICE: l' G! Q" s. Q" {
" a; E( e, w6 M0 o$ _: M0 R$ R
0 N$ y& v6 ]7 [; _9 K9.当需要比较一个常量和一个变量时,如何才能保证不会错弄成赋值?
9 h' c4 j3 {0 s! d( V5 {: O
4 s* Y, a1 J( j1 Z7 d1 DA.把变量转换成int
* k, [) v9 z! s# q: I& s) QB.使用全等比较符(===)
7 {- `6 b: |3 O4 R' g I9 FC.确保常量是第一个操作数
7 x$ V& N/ _8 i, j" v* KD.使用三元运算符% d& F, e W d
E.用括号把操作包起来
& G) r9 E$ U; W: @) a6 s: ?' m5 y; a: E/ ~$ r: z
- t7 L$ h6 U6 c7 H" L9 |/ }3 `4 n7 M
10.要通过邮件给系统管理员发送错误信息,以下那种方法最简便?" Y5 }7 a4 s' r( U9 R
! z' f" f$ ]$ m4 F$ ?A.创建一个连接远程SMTP服务器的函数5 w: E" I B g; T A
B.使用mail函数
9 Z/ m% B- E* p3 W. i4 aC.使用error_log函数
4 d( [* H. A- t2 w. o& B8 dD.调用sendmial程序" n7 ? p1 W6 a8 P, H6 c+ W
E.使用webservice
9 ] Q8 W( a6 d. g! m# v! L$ Z1 j& J- A7 p! v' S
e% h& {4 ?" \6 r! t- m: V7 k
11.能否仅调用一个函数就关闭脚本内所有的错误报告?
! v- x5 L0 X0 |9 F1 H& r
( N; ^0 T7 b, ~A.能; y& `" S1 H" h: w6 f m' B9 X/ R/ R/ Y7 o
B.不能 O) J! X/ ~" \" P! L
" f8 w/ J- p7 C/ i# j& o1 [
1 m( q3 E) B4 K- s* i1 A6 V12.概要分析器(profiler)是做什么的?
, z7 V: B" W8 E6 r1 _ W: A! z g
- w8 w3 M- k+ w* U9 I/ u, ?A.创建关于脚本结构的档案
i( A* f0 w" N. o4 i& J( g& P0 rB.把脚本转化成UML图- i8 @9 X) u& r2 z$ b* z$ B0 m
C.精确测算脚本不同部分的运行时间
' J: d( d) K- x- `3 U9 wD.计算脚本通过web服务器执行时的维度" s0 q2 \3 }6 ]* O9 V* K
E.扫描脚本,识别由常见错误导致的bug
" K3 S# A* n, @ x" l. h2 s/ Y: O5 o
: n1 j2 |% d# T
2 E5 w0 ?' ?# [0 r- ~$ |13.______能帮助识别和解决bug。! @% i2 z% _) N( b# v: o; q7 Z0 x9 P
3 l/ X2 @7 N3 o5 M# U5 z: f答案:____________
# x1 d; T/ e# R9 n# c& F& ^$ R5 [6 i
) t4 U. K- G/ ?& A3 P+ t
% m5 ` B; s% V1 x: v14.trigger_error()和user_error()有什么区别?& T+ C( _2 l, R7 C7 B: Z, P
7 T/ s+ f: c. D. A7 t% J
A.trigger_error()允许脚本抛出系统级的错误" J3 |! x# h* G2 c# H
B.user_error()允许脚本抛出系统级的错误1 W; s3 F6 L! Z1 U2 X" h
C.user_error()不能被用在错误管理器中7 j- v1 |: L0 n2 P3 q
D.trigger_error只在PHP5中可用
z2 f7 F6 z0 p) u0 j' }E.没有区别
7 H4 N$ v3 ^& B. a* f5 n# U' R$ O. _
, W$ D, h) F! G: }# |15.______函数能返回脚本里任意行中调用的函数的名称。该函数同时还经常被用在调试中,用来判断错误是如何发生的。# |! P7 X! c2 h! V9 C4 d6 W
( q/ h# U0 y& V; ]+ e
A.print_r
3 ?5 g( @, |2 g8 tB.var_dump
3 U5 Y6 x6 K, `4 L% o" ^C.stack_dump, Q5 e/ Z0 F1 x. m5 Q, d
D.debug_backtrace
) G( ]! P( g3 y, r, j+ p+ ^E.以上都不对
" `5 T$ q1 j7 p# U h
. L$ Q0 x$ e3 S答案+ I0 {: v8 \- b& Y# }) S
4 s" N; |4 `) G- l
1.答案是E。三元操作符把每个if语句连到一起,作为&&操作的一部分。然而本题中,$x=1这个赋值只在第三个if为false时发生。如果第一个和第二个条件都不成立,$x=1就不会执行。这题对三元操作的应用有些极端,实际应用时,需要根据可读性来决定是否需要用三元运算符(本题这种情况就最好不要用)。( d6 z3 T3 r) {2 M) V2 R
! i+ s+ G6 o0 m4 M* m# q7 `
2.问题是由第三方数据源传输缓慢导致的,而你无法控制这个数据源。你也许能在网络连通性上做些工作(假设问题出在你这一边)。还可以对接收到的内容进行缓存,这样能减少获取重复数据的时间。因此,答案是B和E。0 ?/ p# c$ T8 _0 V; W
2 h" f+ j- g6 `0 W
3.正确的选择是B和D。如果关闭错误报告、使用@抑错符和关闭错误日志,那么在你交付给客户的网站出现问题时,你将很难进行分析和调试。6 E! a: M# S4 S, q
1 `/ P0 E, S7 w
4.这是在描述===操作符。
+ k. }( x5 w& w; n7 r( x9 n1 K0 ^3 W& q% n& [
5.正确答案是D。PHP脚本在执行时,将首先被解析成“中间”码(也叫opcode,操作码),然后解释器执行。操作码缓存出现在这两个步骤之间,对解析器的输出进行缓存。下次执行该脚本时,将缓存的输出直接送入解释器。这样就就不需要再解析一次了。, t. k ]5 d+ A( K5 J
+ u; ?) W4 z+ k2 r2 b1 o9 C6.正确答案是A和D。如果RAM太小,进程间将出现资源竞争,服务器将大量使用硬盘交换。同样的,如果允许过多进程同时执行,也会使服务器频繁进行交换,导致速度下降。
) i- d8 ^# @" f. Q; ]1 f- a8 J; J/ ~6 _- |) k4 V4 p3 S4 B
7.正确答案是A和C。脚本不检验datebase_query()的调用是否成功,因此将持续执行下去,最终产生错误。此外,$my_id参数没有转义——可能导致代码注入(详见第11章)。
3 O& f6 I, ~ ~) t- L" K) {: m" c, G7 J
8.答案B和D正确。出现解析错误往往表示脚本中有语法错误,自定义的错误管理器无法捕捉到它们的原因很明显:错误管理器在脚本里,而现在无法解析脚本,管理器也就无法执行。类似的,E_ERROR表示有致命的运行错误出现,比如内存耗尽。因此脚本会立刻被中断,因为解释器无法执行后面的代码。
9 q4 `% O* u- N# |6 C. y8 F- f0 Z$ F: Z: s/ {4 \: j9 S! q
9.答案是C。比较操作是一个可交换的操作(就是说结果独立于操作数之外),而赋值不是。因此,比如说,$a==10和10==$a是等效的,而$a=10和10=$a却不是,而且后者会导致一个错误,因为这不是一个合法的操作。确保常量在操作符前面,能保证你不会错误得将比较变成赋值。
* @! P1 V8 \4 k" }+ _4 T7 ~1 ~
' |1 V7 K- _5 m% b3 ]10.答案是C。error_log函数能将信息送往一个指定的地址。尽管mail()也可以用,但error_log能自动给邮件添加标题,因此这才是最简单的方法。- J8 s3 e1 B) ~* v
% C% K2 L! Y6 e* _! I
11.答案是不能。error_reporting函数能关闭所有运行时的错误报告,但对解析时的错误无效,因为解析错误发生在脚本执行之前。
$ I( O$ u A* e' O9 ~6 n: f% q1 U% I$ Q' Y, w9 e. n: t
12.显然,答案是C。概要分析器(profiler)能监视脚本的运行,并记录单个部分的运行时间。它可以用来找出和解决瓶颈。" k( s+ v5 f M* V6 c j( L
$ F1 f% ]- ^8 v+ k+ [13.这是对调试器的完美定义!你可以用调试软件监视脚本运行,同时分析系统资源消耗,从而发现和解决程序缺陷。9 A& I4 Z# k! I+ B' X
1 Q1 c& k, y4 {* p( Q' _14.trigger_error()和user_error()之间没有区别。后者其实是前者的别名。( i+ O7 e# ?3 G2 B; G( n3 B
1 N3 c4 L' g: i0 h; ^" z) z
15.答案是D。题目是在描述debug_backtrace函数,它返回一个由所有在代码的特定位置调用过的函数名组成的数组。 |
|