|
  
- UID
- 1
- 帖子
- 738
- 精华
- 28
- 积分
- 14443
- 金币
- 2507
- 威望
- 1647
- 贡献
- 1455
|
[Zend权威认证试题讲解]第十二章 -调试与性能管理
作为一个开发者,无论你经验多么丰富,或者无论你多么努力,你的程序中总会有bug。这是生命中一个必然的部分,如同死亡与缴税(尽管并没有后面两个那么严重)。5 J4 C& C0 a* }* {
要想解决bug,首先要能找到bug。事实上,许多开发者花费了无数小时茫然得盯着代码,只是因为他们没有把程序的容错能力摆在首位。忽略了这个部分,那么期望一个没有bug的程序就是——不可能的。
! _- C' q5 i% T6 W( ` C% M本章测试题将考察你对调试和性能管理相关知识的了解,以及如何用PHP做好这两件事。 \& Y/ X% j+ l. h
5 z' ?# d& _! G5 U
3 _0 X) {8 X! \+ k' e! ?问题
2 k. _* Z; g4 |. y# m' [
- P Q5 J4 F- t* O9 h: n1.以下脚本如何用三元操作替代? . d" R' A2 ^; U9 `+ B
-
- <?php
- if ($a < 10) {
- if ($b > 11) {
- if ($c == 10 && $d != $c) {
- $x = 0;
- } else {
- $x = 1;
- }
- }
- }
- ?>
复制代码
9 [3 A0 g8 E8 [A.$x = ($a A. < 10 || $b > 11 || $c == 1 && $d != $c) ? 0 : 1;
F- w: a0 p: B/ vB.$x = ($a < 10 || $b > 11 || ($c == 1 && $d != $c)) ? 0 : 1;! h: k3 e h% Z9 \ ]! b; _8 k5 o
C.$x = (($a < 10 && $b > 11) || ($c == 1 && $d != $c)) ? 0 : 1;% C4 E$ n2 X8 _ l. S g
D.$x = ($a < 10 && $b > 11 && $c == 1 && $d != $c) ? 1 : 0;
. i! [4 Z% A/ ?% @E.以上都不对
) m( ^3 ?, i; E* W% Z# h6 _
; u$ n( J3 u! E" J- s5 B: v1 o. I; U* X0 N' `2 T0 x
2.有一个脚本由于要从远程获取数据,因而运行速度很慢,以下那种方法能对其进行优化?(双选)0 N6 z& `4 z! I! G" _" [, {
! d6 w+ I2 U m8 KA.安装操作码缓存(opcode cache)% }4 d, U9 B( _0 I4 t
B.优化或者升级你的网络连接4 l$ g3 n3 p" V& @+ N
C.添置更多的硬件
$ _- t1 ~( v1 a5 C7 v& l0 o# mD.增加服务器的可用RAM- Q3 t- F( w8 {' G; F6 C
E.使用连接缓存
. [. l% ^ @6 G
2 E* z+ j! X* m
" y2 N! p0 Y7 c; R! h* K+ M' E5 t3.架设生产环境下的服务器时,需要做哪些步骤?(双选)& T6 s6 Q2 O; r7 y$ Y
- J0 x4 L5 r5 [ X/ e1 R4 ZA.关闭错误报告; r; i+ O# n* ]* z4 N
B.打开错误日志
- \+ G+ `! m, c/ WC.关闭错误日志
9 V" ^, |0 \( l) ED.关闭错误显示
. M$ V! F% l9 r1 F# L6 w' jE.使用@抑错符) g$ T! [: M/ ^% P# I7 H. ~1 k, w2 D
/ J6 `0 v! E4 W6 I3 d" b7 R3 z/ X+ l. R* \, D* w
4.______操作符能对操作数的数据类型进行严格的比较?1 f5 Z- }7 A6 G, Z3 C
; C+ i! P5 M+ h
答案:____________
: q! Y, I2 a8 v1 d4 n; ^- Q0 q7 e4 C
+ @+ D" k! {9 b& v) M
! V, Q; o/ z) C4 X- V9 z5.操作码缓存(opcode cache)能做什么?
# L: x" M/ v' \% ?/ L# N/ f* n1 z; p4 f& E: A
A.把脚本编译成二进制对象,使它运行得更快, N9 ^/ G/ f2 a# s
B.代替Zend引擎加快解释器的运行& x. A; Y+ ]3 A* j* b7 X
C.缓存脚本输出以提高执行效率7 J' D& S' O% E/ k2 w
D.缓存解析器产生的中间码,以提高运行效率/ ?0 n0 X% J% k" D! a- ~+ M' Y4 x
E.在内存中缓存脚本,减少从硬盘中读取的次数
5 t5 M3 C; Z. Z9 m
0 F. K- r2 t2 J0 R! Q
6 S) V: N( }$ d& ]4 I& `+ U7 K6.以下哪些情况容易造成系统资源枯竭?(双选): L! q" V: T) t( c
# E `9 @ e. D3 \$ l& N! |A.RAM太小
8 \; k$ b; Y* YB.使用了低带宽的连接' Z [# a5 T1 B- k3 |
C.虚拟内存超过2GB
4 t7 t% J0 j5 _2 D- }' _/ \D.允许同时运行太多的服务器进程
+ K1 P5 A* d: J5 TE.以上都不对) _2 s0 F. _% n
; [- `) p% o) X+ P7 ]& v( ^1 V
8 I" m0 [ t$ C7.以下脚本缺了些什么?(双选)
( E. ]' e- ~! p2 R! [/ s& i v-
- <?php
- $rs = database_query ("select * from mytable where id = " .
- $my_id);
- while ($a = database_get_data ($rs)) {
- var_dump ($a);
- }
- ?>
复制代码
# M0 G2 ]7 l: K9 h) `4 P! k7 qA.参数出口(Parameter escapement)
- C' v. b: x5 Z+ ^4 XB.输出格式化
; r% K4 \+ \1 ?+ YC.错误检查: V5 E' p" \# i/ c
D.一个SQL查询
1 M! G( H( W! tE.以上都不对
3 I* y2 ?9 [& t/ z
4 |6 Q6 j3 \; j
5 m! b4 X# r/ u8 W4 d$ W. {! R8.以下那种错误类型无法被自定义的错误处理器捕捉到?(双选) ?# m' x5 t! x9 c
# a( A% c' D. h: a* V' q
A.E_WARNING
$ @: Y: y$ A9 j* l& R+ gB.E_ERROR
5 {8 x1 h* Q0 XC.E_USER_ERROR4 N) R. M; d; Z2 P
D.E_PARSE! m* [& N0 {7 ^2 E, j7 V4 O
E.E_NOTICE' F1 P, o# U2 ]) O
' l; q1 K4 g. @( r _2 m4 `2 ]. h5 {9 k5 K% z
9.当需要比较一个常量和一个变量时,如何才能保证不会错弄成赋值?' j0 W" j' C0 Z N
4 {4 n( l) I9 z# RA.把变量转换成int
" l% N/ Z( W0 MB.使用全等比较符(===)5 [4 j5 J0 i5 e# b+ l+ J
C.确保常量是第一个操作数
) T( i$ C0 v4 a9 p3 H1 \& k" x" Z( }D.使用三元运算符/ b* u. V7 F& W, J6 f+ C1 E
E.用括号把操作包起来
- D- w' z+ P/ K4 j9 P! e, r+ v h1 {! G, c
' ^ C9 C8 P9 _10.要通过邮件给系统管理员发送错误信息,以下那种方法最简便?
2 B7 \! W/ @: k7 M& W
! l( a" p2 A r$ A- oA.创建一个连接远程SMTP服务器的函数
+ x. b3 f8 w" \! _B.使用mail函数& V3 O; n; ?0 @6 f$ ]# P- a
C.使用error_log函数% k0 A& ~! h7 | g
D.调用sendmial程序5 B L; l) ~, _7 a, o; i$ G* C
E.使用webservice
* \4 h2 w, e1 p* l, w* J$ U6 ^& g5 r; N" f5 A
5 d; Z+ N6 e! B11.能否仅调用一个函数就关闭脚本内所有的错误报告?, p$ e, J I- p) C
. B8 B* u* X& FA.能4 H n% C, |7 H
B.不能- K! X1 m& C# H2 {) E3 }0 M- f, o
. I7 U5 ]7 m* u4 b' d. _( H+ y
' r* w# c9 B* C* `12.概要分析器(profiler)是做什么的?% z* y! d, v# Q1 \* m$ t
( q2 ~2 ^& c! S" F* h
A.创建关于脚本结构的档案7 {; ?: ~) @9 G7 C$ s
B.把脚本转化成UML图
- [7 G; P' ^0 X7 ]1 B4 {0 LC.精确测算脚本不同部分的运行时间& A: `+ d' _2 X/ Q
D.计算脚本通过web服务器执行时的维度, {* s, d# {/ \' v1 V
E.扫描脚本,识别由常见错误导致的bug
4 }# S( g) |) x9 r+ k. k
9 U" {, t& l2 k& T4 `, j4 ~! I) S0 ?. i, j4 |
13.______能帮助识别和解决bug。, X5 D! b/ m1 H5 Q6 j! W, P U4 e
1 [! g3 {6 [. e% i
答案:____________
* x5 L1 ?+ w5 Y) b* B# T8 g: s' T" m) K7 B) _$ H6 S7 ?
# T7 Y: l; r5 z3 R: x; C14.trigger_error()和user_error()有什么区别?
+ c& V7 j7 O4 m8 Z3 d- H1 f+ \/ K* \/ T, A
A.trigger_error()允许脚本抛出系统级的错误
/ t. E8 ]9 v7 AB.user_error()允许脚本抛出系统级的错误" ~! C1 l, R. e+ J0 y
C.user_error()不能被用在错误管理器中
0 f7 Y. n0 R. [) c; O S9 q- @D.trigger_error只在PHP5中可用7 C1 l( c9 X/ Q3 w
E.没有区别
$ l/ ] T6 e8 ^9 p* L1 s% S6 u+ ]$ m$ Q% z2 I0 P6 R. h
' \# w! E" a9 d) H" @
15.______函数能返回脚本里任意行中调用的函数的名称。该函数同时还经常被用在调试中,用来判断错误是如何发生的。6 S* `+ o) S; v
: z( x1 |9 K5 D, e- K/ K
A.print_r
* t3 C& g) _" f1 X' f* EB.var_dump3 C5 {8 r) R8 _% ?) V' ?+ G
C.stack_dump7 s# q! n# x: K" R2 b+ v5 r
D.debug_backtrace* i# z6 A2 ~- O: T: d$ y; t$ y9 R1 G
E.以上都不对+ c+ P; F3 b v$ y4 b0 x0 m6 z" o2 p
( Z" j+ `) L, g- X4 ~+ U. m答案
) S8 F% | ^4 L. w( X3 i+ _" u" U# ]4 D6 t% w/ O$ B
1.答案是E。三元操作符把每个if语句连到一起,作为&&操作的一部分。然而本题中,$x=1这个赋值只在第三个if为false时发生。如果第一个和第二个条件都不成立,$x=1就不会执行。这题对三元操作的应用有些极端,实际应用时,需要根据可读性来决定是否需要用三元运算符(本题这种情况就最好不要用)。
0 |! Y3 N) `2 w
9 d( D9 v. @9 B5 I$ x- m! f2.问题是由第三方数据源传输缓慢导致的,而你无法控制这个数据源。你也许能在网络连通性上做些工作(假设问题出在你这一边)。还可以对接收到的内容进行缓存,这样能减少获取重复数据的时间。因此,答案是B和E。
5 f* s& V* U8 P; ^! S S( u6 h& T- Z. z# h! l
3.正确的选择是B和D。如果关闭错误报告、使用@抑错符和关闭错误日志,那么在你交付给客户的网站出现问题时,你将很难进行分析和调试。
" w; u1 D- {' r( a6 p
/ J; b# |9 r1 Y: t& h4.这是在描述===操作符。' A* j( w0 Z* p; W9 L3 q/ V
2 R8 a, x8 s6 |2 H- F* A4 y
5.正确答案是D。PHP脚本在执行时,将首先被解析成“中间”码(也叫opcode,操作码),然后解释器执行。操作码缓存出现在这两个步骤之间,对解析器的输出进行缓存。下次执行该脚本时,将缓存的输出直接送入解释器。这样就就不需要再解析一次了。
- y' J/ H# |# }0 y" f5 B. M' X U4 ~3 e$ W- D# a" w
6.正确答案是A和D。如果RAM太小,进程间将出现资源竞争,服务器将大量使用硬盘交换。同样的,如果允许过多进程同时执行,也会使服务器频繁进行交换,导致速度下降。6 d1 P; w% x& K) G, c7 v/ C
# _ G: g( }3 {! w9 X
7.正确答案是A和C。脚本不检验datebase_query()的调用是否成功,因此将持续执行下去,最终产生错误。此外,$my_id参数没有转义——可能导致代码注入(详见第11章)。& a7 M9 t5 e( s+ Q5 a6 V7 m
, I2 g$ o8 e7 d( W3 N+ X; \/ `8.答案B和D正确。出现解析错误往往表示脚本中有语法错误,自定义的错误管理器无法捕捉到它们的原因很明显:错误管理器在脚本里,而现在无法解析脚本,管理器也就无法执行。类似的,E_ERROR表示有致命的运行错误出现,比如内存耗尽。因此脚本会立刻被中断,因为解释器无法执行后面的代码。, d* G; X, t: |8 R! h/ Q0 g
+ r9 k" n; C4 A& z4 w9.答案是C。比较操作是一个可交换的操作(就是说结果独立于操作数之外),而赋值不是。因此,比如说,$a==10和10==$a是等效的,而$a=10和10=$a却不是,而且后者会导致一个错误,因为这不是一个合法的操作。确保常量在操作符前面,能保证你不会错误得将比较变成赋值。3 n5 }) X3 p# L; O; Y; o
0 O' N( R( v! Z) Z0 ^2 V
10.答案是C。error_log函数能将信息送往一个指定的地址。尽管mail()也可以用,但error_log能自动给邮件添加标题,因此这才是最简单的方法。) v3 n$ @% w `
; e. k+ q ~6 E" S# |' I11.答案是不能。error_reporting函数能关闭所有运行时的错误报告,但对解析时的错误无效,因为解析错误发生在脚本执行之前。. `1 _( n* {. M e! b: V
/ j) |/ }, k5 Z% t/ g
12.显然,答案是C。概要分析器(profiler)能监视脚本的运行,并记录单个部分的运行时间。它可以用来找出和解决瓶颈。
7 \8 |; H* J2 J: y: s
% M# V' S4 p- N6 M4 q) X! f13.这是对调试器的完美定义!你可以用调试软件监视脚本运行,同时分析系统资源消耗,从而发现和解决程序缺陷。
$ P4 P8 c' `. q5 f g
. M* L. j! @, r( z: Q! H; a% r; r14.trigger_error()和user_error()之间没有区别。后者其实是前者的别名。2 A* M. p+ z' ~. U# b; l, G
; d& Z: [- B @! c& |" @& m
15.答案是D。题目是在描述debug_backtrace函数,它返回一个由所有在代码的特定位置调用过的函数名组成的数组。 |
|