  
- UID
- 1
- 帖子
- 738
- 精华
- 28
- 积分
- 14247
- 金币
- 2414
- 威望
- 1647
- 贡献
- 1362
|
[Zend权威认证试题讲解]第十二章 -调试与性能管理
作为一个开发者,无论你经验多么丰富,或者无论你多么努力,你的程序中总会有bug。这是生命中一个必然的部分,如同死亡与缴税(尽管并没有后面两个那么严重)。# C& G$ `9 E3 p* Y) ~/ _* v0 x [
要想解决bug,首先要能找到bug。事实上,许多开发者花费了无数小时茫然得盯着代码,只是因为他们没有把程序的容错能力摆在首位。忽略了这个部分,那么期望一个没有bug的程序就是——不可能的。
H9 S) l! }" o9 ?1 C; h本章测试题将考察你对调试和性能管理相关知识的了解,以及如何用PHP做好这两件事。3 q5 o) s$ L# r. W! X
$ C; r2 |9 V5 C5 n$ h s
- F$ p7 T6 C( h' |$ ?问题7 A6 W2 n5 C# X( d, W
5 \7 e4 d- l' ]5 W. Y" q
1.以下脚本如何用三元操作替代?
% ]" u: K2 k; D$ n. D-
- <?php
- if ($a < 10) {
- if ($b > 11) {
- if ($c == 10 && $d != $c) {
- $x = 0;
- } else {
- $x = 1;
- }
- }
- }
- ?>
复制代码
' T7 I: s2 r' _: zA.$x = ($a A. < 10 || $b > 11 || $c == 1 && $d != $c) ? 0 : 1;
% Z6 }0 X5 O( E# M, tB.$x = ($a < 10 || $b > 11 || ($c == 1 && $d != $c)) ? 0 : 1;& S8 q, q5 I; N1 Z6 d& m6 p
C.$x = (($a < 10 && $b > 11) || ($c == 1 && $d != $c)) ? 0 : 1;
) J& L3 U% h( P4 N S2 hD.$x = ($a < 10 && $b > 11 && $c == 1 && $d != $c) ? 1 : 0;
$ J/ e* a2 M. w# @E.以上都不对7 K$ r8 z/ o0 `( Q
8 U* \/ ]( \8 B& M. F" }$ J
; B; L" |9 Y2 @: d. Z! j5 g3 k8 O2.有一个脚本由于要从远程获取数据,因而运行速度很慢,以下那种方法能对其进行优化?(双选)8 h6 ^2 V3 |# e3 A
: L u# P. X( U/ g3 a, O
A.安装操作码缓存(opcode cache)
: w+ q& K2 e% K3 @9 }) o+ CB.优化或者升级你的网络连接
: c( x7 i! u, R' R/ V% nC.添置更多的硬件
2 U6 K; T0 Q+ U0 a& W+ q5 FD.增加服务器的可用RAM+ G7 @6 \) f" d0 S" t4 n+ B4 z
E.使用连接缓存
# [/ @9 z) w! @
' |% G7 @# ]( Z1 N, A0 D% `5 a4 i, E' ^- b# d+ e
3.架设生产环境下的服务器时,需要做哪些步骤?(双选)
& N3 Q+ b" A9 o1 M7 h
+ x5 Y" k0 E! zA.关闭错误报告+ E8 x9 z( b& J* @5 B% S5 c4 F) L
B.打开错误日志
V7 L0 C4 s5 P9 G$ Y& wC.关闭错误日志0 f, w& J# E8 O* t% w7 @3 O. m" N
D.关闭错误显示" q( Q: @( l- R2 H! m2 h* K
E.使用@抑错符
' o% l! J# B5 D; {) C/ D/ ~9 W# @& n+ p& `0 c) b' J
* V1 W V$ Q% ]1 Q7 r4 X; @' y$ W4.______操作符能对操作数的数据类型进行严格的比较?# U( ?( Y% y9 \; P" u( d8 g
3 ~) u; P- W, ~( e8 ^9 q* L答案:____________. J& G0 q: b- i- ^- h: C
! k- `6 }+ |8 X; M
9 n$ e& O1 u B) |) _& [5.操作码缓存(opcode cache)能做什么?, F; R1 Q# A8 }- N) U& d
4 f% e. ?% `9 @( x" i7 y% _1 T
A.把脚本编译成二进制对象,使它运行得更快0 T0 I# ?$ K# w. F
B.代替Zend引擎加快解释器的运行+ \% i1 \3 f( O" S( @
C.缓存脚本输出以提高执行效率8 v3 z' C7 H$ f) i5 }: [* F/ h
D.缓存解析器产生的中间码,以提高运行效率+ h0 x7 g0 t/ k( ?1 A
E.在内存中缓存脚本,减少从硬盘中读取的次数
) M5 l1 v* J7 \' A2 o8 d
( }+ Q$ |* G: r" A) x0 D# j: Z
0 O* N: ]. p m! W0 F2 z' D: ~6.以下哪些情况容易造成系统资源枯竭?(双选)
% e- e4 K4 H% u- K9 \
7 {+ @7 [4 ^& ]" t3 `1 d ~A.RAM太小( _1 B" r. E: { Z" s5 q5 P d
B.使用了低带宽的连接
, m: _' C' U' Y3 YC.虚拟内存超过2GB, m F8 D9 }. d( S; _
D.允许同时运行太多的服务器进程
0 a2 M( t$ U, ?% X8 S4 fE.以上都不对
; F3 R3 m9 z2 Q- a9 p: P6 c% M& \# s5 e) Z5 E6 D+ b
& h4 G# X1 J$ p ^7.以下脚本缺了些什么?(双选)
! ^% ^0 ^6 o4 ]4 z# r- I- Z8 a& I( y-
- <?php
- $rs = database_query ("select * from mytable where id = " .
- $my_id);
- while ($a = database_get_data ($rs)) {
- var_dump ($a);
- }
- ?>
复制代码 / ~5 y( \8 X: e- p% `
A.参数出口(Parameter escapement)
6 i: {1 e$ T/ L0 ~; PB.输出格式化7 r- m$ ~) f- U) Q! Z6 a
C.错误检查3 i" `( _/ [, H
D.一个SQL查询
1 L7 q* O7 g q5 {4 j& nE.以上都不对 W* N2 ]2 ?3 H9 Y) i
I( B3 V! U# W. y4 S5 @2 Z
" `( x0 f0 M8 ~8.以下那种错误类型无法被自定义的错误处理器捕捉到?(双选)
# J; }1 [ W9 y1 j' Y0 U) x+ |5 |1 u* {4 J# Z/ |
A.E_WARNING* |* M# R) l7 E. g3 x
B.E_ERROR: d' G4 q! I- N+ S; q! f( F/ _
C.E_USER_ERROR
$ }3 Y$ X- [, r VD.E_PARSE
% v! h! s Z; Q/ x% Q j& OE.E_NOTICE
, ~* ]1 r# o' S8 B3 u( s! }5 a- `0 N* h% b* M) S6 j
3 M, a; @) n' ~& z9 m* h9 k: H
9.当需要比较一个常量和一个变量时,如何才能保证不会错弄成赋值?9 D9 |3 x6 j# E' J4 J) P" N! w8 o
0 M$ E7 ~4 o( @0 h
A.把变量转换成int
& u; S5 B" R3 y6 [& P9 Z5 [5 q: TB.使用全等比较符(===)
5 U- \) p$ S) D2 i% `0 dC.确保常量是第一个操作数
5 J7 p3 q$ E" H- p7 T/ b( ID.使用三元运算符
7 x$ Q" K8 x" P5 q/ S$ G, N& ME.用括号把操作包起来
; ^% w$ q. x( U& O" B( j! n7 ~' L; j! P0 A' M1 A- K' _; R A" K
# P+ ^' w+ e6 m, _5 y- |3 b10.要通过邮件给系统管理员发送错误信息,以下那种方法最简便? d( X, D* _. B* q
) q) l: {! r" t: u# [/ y, QA.创建一个连接远程SMTP服务器的函数2 Y" G+ L0 h9 N# Q
B.使用mail函数
2 \4 ~8 k, e. G2 y, m' T( zC.使用error_log函数
/ w3 C1 i' `8 T1 D) G0 PD.调用sendmial程序( k4 \2 m5 h8 z
E.使用webservice
' `: j$ ~4 x. _4 Y A9 n% L3 l6 o7 I! ]! o7 G7 y* {
! P. e" t ]) J! g6 r11.能否仅调用一个函数就关闭脚本内所有的错误报告?
" X) P; r& |9 |9 x
# a! ~' B1 n- n3 NA.能
9 ^0 \. B! Y0 y; h2 IB.不能
, {$ {) I$ V. g9 [8 S4 T7 w4 P. B9 @4 S( ~; @
' N% b; s( |8 r$ W% S9 A; R m# z& O3 a
12.概要分析器(profiler)是做什么的?
3 S! J$ X& Q' p. ` }0 k$ B; o
; i- s/ `6 I# d* q" _) ?" zA.创建关于脚本结构的档案
( s& P8 T) t$ m% [) o; i: ZB.把脚本转化成UML图
' j% r" w+ F/ [* Y3 eC.精确测算脚本不同部分的运行时间5 {4 ^; f$ y- O. n4 {" e/ W
D.计算脚本通过web服务器执行时的维度
! E ~1 Z5 Y9 L3 @4 t1 XE.扫描脚本,识别由常见错误导致的bug
: b. l/ {, M1 {5 p6 ~# z$ W; A2 C. R) y2 ? R' F
4 _/ j+ b3 N, n# a2 @& F9 K4 B13.______能帮助识别和解决bug。
" {9 L. Z0 ]) `) C7 k) P) O% V8 |
" D2 |: ]5 V! y8 E答案:____________: U8 X3 i3 g7 `" M& N
& s. p8 i# \/ P( s6 d
' @. X L+ x" h' D* R" a
14.trigger_error()和user_error()有什么区别?8 [1 f$ s! S9 Y3 p/ J
4 y ~7 I" t3 j( _( p& ^& _A.trigger_error()允许脚本抛出系统级的错误
^, r/ G9 x3 WB.user_error()允许脚本抛出系统级的错误. d2 W. K: c0 `1 E5 |1 J
C.user_error()不能被用在错误管理器中
& o! |, ^. y" w9 \" }D.trigger_error只在PHP5中可用! u6 ?. x/ P% O X' }5 l
E.没有区别
! |" j" K. X0 Z. ]5 H7 K
& [9 T2 G, ^" v) h& f# P7 G
" i) c* Q+ B$ e" p9 X4 |' d" d15.______函数能返回脚本里任意行中调用的函数的名称。该函数同时还经常被用在调试中,用来判断错误是如何发生的。
" v8 ]3 {( Z) J# E/ ?( d* n% G2 J+ b& R# L1 b" @" L% C
A.print_r2 {+ F8 w; J0 x2 D
B.var_dump
# K% ~; _. \6 Z3 qC.stack_dump
6 |" b! @0 p" X+ wD.debug_backtrace/ q( f) I0 Q& v$ Q
E.以上都不对
, C( U: n0 q6 V- t8 O& M2 V$ a% h# v5 d Z9 T3 \
答案
2 ] b; g% I/ Q3 u; G8 D. j6 D$ o" S6 A' s# {' z( G# w
1.答案是E。三元操作符把每个if语句连到一起,作为&&操作的一部分。然而本题中,$x=1这个赋值只在第三个if为false时发生。如果第一个和第二个条件都不成立,$x=1就不会执行。这题对三元操作的应用有些极端,实际应用时,需要根据可读性来决定是否需要用三元运算符(本题这种情况就最好不要用)。
) M; j0 D6 F0 \* V F9 j: c! z) A6 _' E5 t
2.问题是由第三方数据源传输缓慢导致的,而你无法控制这个数据源。你也许能在网络连通性上做些工作(假设问题出在你这一边)。还可以对接收到的内容进行缓存,这样能减少获取重复数据的时间。因此,答案是B和E。9 x' k8 R( _1 u+ o/ u5 N$ _
" `% U" I+ t9 N3.正确的选择是B和D。如果关闭错误报告、使用@抑错符和关闭错误日志,那么在你交付给客户的网站出现问题时,你将很难进行分析和调试。# e5 P6 M8 A8 {! q0 @! y
; y! Y! Q- x/ K9 O3 X* m7 x' R
4.这是在描述===操作符。
$ H3 M) V9 O! {4 [( t# n- @8 y
4 d( p# Y7 _9 P1 V. l5.正确答案是D。PHP脚本在执行时,将首先被解析成“中间”码(也叫opcode,操作码),然后解释器执行。操作码缓存出现在这两个步骤之间,对解析器的输出进行缓存。下次执行该脚本时,将缓存的输出直接送入解释器。这样就就不需要再解析一次了。 F ]; j) M8 A
8 i3 c! C- `1 @7 C. e+ e; }6.正确答案是A和D。如果RAM太小,进程间将出现资源竞争,服务器将大量使用硬盘交换。同样的,如果允许过多进程同时执行,也会使服务器频繁进行交换,导致速度下降。
: e* H9 V% ~/ Z5 o7 G$ o6 B) H, R( Y
7.正确答案是A和C。脚本不检验datebase_query()的调用是否成功,因此将持续执行下去,最终产生错误。此外,$my_id参数没有转义——可能导致代码注入(详见第11章)。) F5 n0 I5 v: p7 \+ J' K, t5 L5 Z
[/ @( B# f/ p& d8.答案B和D正确。出现解析错误往往表示脚本中有语法错误,自定义的错误管理器无法捕捉到它们的原因很明显:错误管理器在脚本里,而现在无法解析脚本,管理器也就无法执行。类似的,E_ERROR表示有致命的运行错误出现,比如内存耗尽。因此脚本会立刻被中断,因为解释器无法执行后面的代码。) l9 `5 J$ j4 Q
1 a7 o( u* `/ n5 r8 ~ H, `
9.答案是C。比较操作是一个可交换的操作(就是说结果独立于操作数之外),而赋值不是。因此,比如说,$a==10和10==$a是等效的,而$a=10和10=$a却不是,而且后者会导致一个错误,因为这不是一个合法的操作。确保常量在操作符前面,能保证你不会错误得将比较变成赋值。
6 G/ b* M0 M! V! u$ J: \
8 a1 W+ q9 G5 w/ t6 w/ f& l10.答案是C。error_log函数能将信息送往一个指定的地址。尽管mail()也可以用,但error_log能自动给邮件添加标题,因此这才是最简单的方法。9 e/ N" w* ]3 a, S
9 Y7 |* M9 o9 K6 `: V
11.答案是不能。error_reporting函数能关闭所有运行时的错误报告,但对解析时的错误无效,因为解析错误发生在脚本执行之前。
$ B; {' |* W% ~$ n* M; e" O% H9 k7 H: n. }
12.显然,答案是C。概要分析器(profiler)能监视脚本的运行,并记录单个部分的运行时间。它可以用来找出和解决瓶颈。. F- W3 ~% P8 S
- H0 c5 |& X: `( u+ j5 x
13.这是对调试器的完美定义!你可以用调试软件监视脚本运行,同时分析系统资源消耗,从而发现和解决程序缺陷。
8 f" B! G" c, M; t
5 R3 z5 K& @2 u0 @ @5 o$ V0 F: z14.trigger_error()和user_error()之间没有区别。后者其实是前者的别名。
# s r/ i& p; C. ~1 [9 [
# {/ x* d; @! \2 _8 J5 l15.答案是D。题目是在描述debug_backtrace函数,它返回一个由所有在代码的特定位置调用过的函数名组成的数组。 |
|