发新话题
打印

[Zend权威认证试题讲解]第十二章 -调试与性能管理



[Zend权威认证试题讲解]第十二章 -调试与性能管理

作为一个开发者,无论你经验多么丰富,或者无论你多么努力,你的程序中总会有bug。这是生命中一个必然的部分,如同死亡与缴税(尽管并没有后面两个那么严重)。; ]8 Q+ ^! f% x+ g
要想解决bug,首先要能找到bug。事实上,许多开发者花费了无数小时茫然得盯着代码,只是因为他们没有把程序的容错能力摆在首位。忽略了这个部分,那么期望一个没有bug的程序就是——不可能的。
! y# @* g7 v/ x5 |% |5 a本章测试题将考察你对调试和性能管理相关知识的了解,以及如何用PHP做好这两件事。7 l" A* ^) y0 p5 i- W1 W
) _' a$ a* f' \

! c% h5 P" _- m问题. j5 P  H- ?2 F3 b

0 {+ ^6 G) G7 @) C1.以下脚本如何用三元操作替代?
复制内容到剪贴板
代码:

<?php
if ($a < 10) {
    if ($b > 11) {
        if ($c == 10 && $d != $c) {
            $x = 0;
        } else {
            $x = 1;
        }
    }
}
?>
A.$x = ($a A. < 10 || $b > 11 || $c == 1 && $d != $c) ? 0 : 1;+ U7 G# Y4 ]  Q7 E" c1 {
B.$x = ($a < 10 || $b > 11 || ($c == 1 && $d != $c)) ? 0 : 1;
7 _( E$ S! \) r$ UC.$x = (($a < 10 && $b > 11) || ($c == 1 && $d != $c)) ? 0 : 1;- K( i! y0 h3 a! _& K
D.$x = ($a < 10 && $b > 11 && $c == 1 && $d != $c) ? 1 : 0;
, A- ?, ?* o$ ~- h+ o) H% KE.以上都不对
! `7 v4 f3 e6 u% ?1 O
: X6 p1 l& r* v9 s
2 w8 y" q8 K+ T) z# ]2.有一个脚本由于要从远程获取数据,因而运行速度很慢,以下那种方法能对其进行优化?(双选), Z8 F8 \6 l; z/ A+ M/ Z  P
' G( l: w+ o# g5 t# ?
A.安装操作码缓存(opcode cache)
  m/ O6 P& A+ i3 s0 OB.优化或者升级你的网络连接
8 g( Q3 Z0 k& ^" J5 A5 o0 l$ wC.添置更多的硬件
% K$ D* w# s' n8 F2 w& X6 G6 h! E% TD.增加服务器的可用RAM
  q* i# u# h. T! C) yE.使用连接缓存
: \) ^* p6 n# @1 a9 n
2 w& h3 ]* `+ T" H9 J- O5 k$ V
, {3 M! L/ {- n' D3.架设生产环境下的服务器时,需要做哪些步骤?(双选)3 A8 _8 ?- D% D2 v& o2 u' v
7 B( u8 U: R! V% a! P6 E* \
A.关闭错误报告
& H+ J9 ]* d2 @+ _" H% }B.打开错误日志4 |. U6 r; c4 E0 m3 |: O- [
C.关闭错误日志& a) M8 {0 I" l% n; y& p5 g% [3 j
D.关闭错误显示
$ S) x: I$ A/ nE.使用@抑错符
2 q: S( v' `% B! d
, G+ D! _: F; Z& m  @2 p% C2 r5 S; L3 x2 L. l
4.______操作符能对操作数的数据类型进行严格的比较?7 `( ?1 ?$ B+ y

& V. {0 [. U8 o: R2 g2 E答案:____________
9 v2 |0 |" U; e, F" l' K, [. p+ O( z
5 @$ Z& i2 C5 j1 l5 u
5.操作码缓存(opcode cache)能做什么?
6 s& s7 F' g1 L0 Y% i$ m2 A1 ~, G# K" r& y& s- Z
A.把脚本编译成二进制对象,使它运行得更快. F# X9 {: s) s$ }# Z
B.代替Zend引擎加快解释器的运行
- }: e; }) O6 [C.缓存脚本输出以提高执行效率
' @6 p* x( B" ~+ YD.缓存解析器产生的中间码,以提高运行效率
( |6 z+ V- L/ \/ S$ z7 ~E.在内存中缓存脚本,减少从硬盘中读取的次数
- A8 C" @9 W7 Z. u: |/ E7 q7 A+ e

. _5 m+ B9 N3 r  G$ L6.以下哪些情况容易造成系统资源枯竭?(双选)
/ x- Z/ s8 f# g6 R4 U, |, @+ T0 c  v, N: Q6 k- n3 ^
A.RAM太小
) n) l" p% a; i' ?: P* Q0 AB.使用了低带宽的连接
+ f; g1 Q; B2 o' a: {' JC.虚拟内存超过2GB
0 P# j) H# k" u2 Y4 R! _1 BD.允许同时运行太多的服务器进程
7 _2 I8 A, j( L+ ~E.以上都不对4 B6 [4 S* S; \  j, B. ?" a3 ]

/ ~2 ^  g9 F4 ?# w1 n7 l, z! X( g! @# O- P  r: o
7.以下脚本缺了些什么?(双选)
复制内容到剪贴板
代码:

<?php
$rs = database_query ("select * from mytable where id = " .
$my_id);
while ($a = database_get_data ($rs)) {
    var_dump ($a);
}
?>
A.参数出口(Parameter escapement)* q. u$ `1 l* O/ V3 x; l
B.输出格式化4 i$ g; c1 x+ k5 K& R& @5 y
C.错误检查
7 I; ^; V: u& ?! N) X$ M: TD.一个SQL查询
# w  L) X6 [  m/ X) lE.以上都不对9 i( C1 x6 N# ^' g: O% m8 O

0 [3 N, A1 k& p/ b! [' B, f. I) X# |
8.以下那种错误类型无法被自定义的错误处理器捕捉到?(双选)
  N" F! v9 @- b
# W, v& f1 p% k5 r6 ]/ h  u* yA.E_WARNING
% d- A1 L% y3 g- O' NB.E_ERROR4 S4 C: K6 h! f' `. Q0 U, u
C.E_USER_ERROR
; {$ N" b4 I. Z4 W. A; _" mD.E_PARSE; F' U# R! \6 R& v1 t
E.E_NOTICE; P. y' C" z6 T6 K* ?1 R
6 `5 C) y- ^, y4 X( \- f9 l
; j8 y* D! C& F0 R! ~7 ]
9.当需要比较一个常量和一个变量时,如何才能保证不会错弄成赋值?
" D! ]) u  P9 a% v8 q/ t  H) o- v
/ e  I$ N4 ?. w; y) y" XA.把变量转换成int5 R( [% k# b% R/ P  F3 c  N
B.使用全等比较符(===)+ m; V. b0 [6 u' T6 x1 y$ x
C.确保常量是第一个操作数
7 |2 P8 B& ]2 W' A) o# U* KD.使用三元运算符! g  @' Z/ w2 h6 x4 q5 t1 g" t
E.用括号把操作包起来: M+ o$ u9 Q. T' e
  g- N; o$ }) l* J# l- N8 g* A/ R

/ O8 `! J6 C" R) m10.要通过邮件给系统管理员发送错误信息,以下那种方法最简便?2 J3 ]8 l. i) r( w/ K0 u& {, ]

+ S* ^2 W  F/ ?" @A.创建一个连接远程SMTP服务器的函数
! g$ y& x2 T/ j  ?  _4 W2 K% Q6 T4 [B.使用mail函数9 y' ?5 {  S& t
C.使用error_log函数
$ U4 e. b+ f) q1 B% v" Y9 BD.调用sendmial程序
% `- R+ X' [3 \6 M" i- HE.使用webservice
. T5 ~. C" H$ d
9 `) C- c0 r& J* O+ F" E" m8 P' `- ~2 ]6 J7 N- j6 \
11.能否仅调用一个函数就关闭脚本内所有的错误报告?
4 u, y, K1 C- ?0 }" e3 h# F4 e0 v5 ]% T3 C0 O1 E; X- I4 ~
A.能$ Q4 N0 Y! v, V9 Z- M: T
B.不能
, S3 X6 _- N- l5 Q1 U# U) v7 b
! m0 s2 z+ y2 S' O3 b. V- p& |! v6 X) ]) f$ h& |
12.概要分析器(profiler)是做什么的?1 W4 c. G# G# V# I' o/ }/ f

6 L" P0 s2 q' j  w% ?, IA.创建关于脚本结构的档案, V; v; P5 O' H2 a1 \0 e
B.把脚本转化成UML图
4 P: J: h0 ?0 i( tC.精确测算脚本不同部分的运行时间
$ t+ s+ Z# L% [D.计算脚本通过web服务器执行时的维度" q8 }7 }; r0 l- V9 O3 h. P; \
E.扫描脚本,识别由常见错误导致的bug( J0 g! l2 p- |* a. I3 @
2 n+ \" B( k+ [8 ~) f8 f

; O0 a1 l4 b. L  ^" P) V0 G13.______能帮助识别和解决bug。3 ?: A" y( c/ O

* D* n; r" |* [- E答案:____________0 y! }) ^3 e+ J/ |5 f, K8 e2 b( ^
8 u5 P# l% S% N$ Q# U: q* ~3 P
) t" K2 {- |( [! C0 f" g
14.trigger_error()和user_error()有什么区别?* o& f6 I2 |* s2 O, i9 u

% t& m* C5 d4 k# D1 N# ]3 j  d' yA.trigger_error()允许脚本抛出系统级的错误
- S6 f) Y+ `2 }; K" v9 tB.user_error()允许脚本抛出系统级的错误6 b, r  F/ ?0 o# h6 W5 I. h9 g8 ]
C.user_error()不能被用在错误管理器中7 J0 _$ t* t/ o$ J
D.trigger_error只在PHP5中可用8 x2 ^# M8 N/ @3 H7 q( b
E.没有区别
5 S  c# R' H2 W& J% Z& ]) l$ G
8 R& n6 b- K/ S2 Y' P  C) e3 C4 |" ^- L2 g( Q- V4 N
15.______函数能返回脚本里任意行中调用的函数的名称。该函数同时还经常被用在调试中,用来判断错误是如何发生的。* b$ ^5 V3 w7 U: {4 B- I) q
" s  w% {- Q: l# S: u
A.print_r
7 O  n# l& Z) K3 l  PB.var_dump/ Z4 n/ R: }9 @* \
C.stack_dump
. T- w* {" M7 O. S' e" {; T5 k& QD.debug_backtrace
* E. l% P" G' a! Z  X* r2 Q7 G. ]! [E.以上都不对
6 J, b( A) `+ \4 c
% B3 W9 _. ]% m, R' @答案
* x* `* D3 m, u$ U. L' F  S. Q3 f; [" R
1.答案是E。三元操作符把每个if语句连到一起,作为&&操作的一部分。然而本题中,$x=1这个赋值只在第三个if为false时发生。如果第一个和第二个条件都不成立,$x=1就不会执行。这题对三元操作的应用有些极端,实际应用时,需要根据可读性来决定是否需要用三元运算符(本题这种情况就最好不要用)。+ Z* y9 l7 g# A2 }0 k- j; p) Z

: A4 d6 Z- e3 @+ }2.问题是由第三方数据源传输缓慢导致的,而你无法控制这个数据源。你也许能在网络连通性上做些工作(假设问题出在你这一边)。还可以对接收到的内容进行缓存,这样能减少获取重复数据的时间。因此,答案是B和E。
! _! G7 }6 n/ P( S4 s
& M0 j$ ?6 j. [) o+ s5 q" _1 s7 M3.正确的选择是B和D。如果关闭错误报告、使用@抑错符和关闭错误日志,那么在你交付给客户的网站出现问题时,你将很难进行分析和调试。
/ k1 e+ Q+ b1 ~& w5 H1 W/ h7 Y/ E* P
4.这是在描述===操作符。; e+ l, `8 A% ?  _0 z

: n% ^; w, H- T5.正确答案是D。PHP脚本在执行时,将首先被解析成“中间”码(也叫opcode,操作码),然后解释器执行。操作码缓存出现在这两个步骤之间,对解析器的输出进行缓存。下次执行该脚本时,将缓存的输出直接送入解释器。这样就就不需要再解析一次了。4 o) M0 e, V: C
; ~0 M" U; n1 }7 N" e
6.正确答案是A和D。如果RAM太小,进程间将出现资源竞争,服务器将大量使用硬盘交换。同样的,如果允许过多进程同时执行,也会使服务器频繁进行交换,导致速度下降。3 _0 _. O+ M* w$ d4 |3 Z

( a8 Z- \0 H3 s, k" A: \! R7.正确答案是A和C。脚本不检验datebase_query()的调用是否成功,因此将持续执行下去,最终产生错误。此外,$my_id参数没有转义——可能导致代码注入(详见第11章)。
9 T' }8 i0 d5 a% _* j& z( P; f2 ]5 O  L
8.答案B和D正确。出现解析错误往往表示脚本中有语法错误,自定义的错误管理器无法捕捉到它们的原因很明显:错误管理器在脚本里,而现在无法解析脚本,管理器也就无法执行。类似的,E_ERROR表示有致命的运行错误出现,比如内存耗尽。因此脚本会立刻被中断,因为解释器无法执行后面的代码。+ C9 W. C( C+ |1 y9 ~( E

8 F1 B% I0 g* @% P) _* Y9.答案是C。比较操作是一个可交换的操作(就是说结果独立于操作数之外),而赋值不是。因此,比如说,$a==10和10==$a是等效的,而$a=10和10=$a却不是,而且后者会导致一个错误,因为这不是一个合法的操作。确保常量在操作符前面,能保证你不会错误得将比较变成赋值。: o; u4 y* {+ J  g
5 F& X  ~  S& n; N0 m9 _! \2 O4 ]; T
10.答案是C。error_log函数能将信息送往一个指定的地址。尽管mail()也可以用,但error_log能自动给邮件添加标题,因此这才是最简单的方法。& ~) @" D6 E% f% Z6 R* ^" |/ w
3 N/ r! w. D/ H/ b7 I
11.答案是不能。error_reporting函数能关闭所有运行时的错误报告,但对解析时的错误无效,因为解析错误发生在脚本执行之前。8 X% ~6 J9 V- t; L# z

9 J4 D# W" s" F& |- C5 a; E9 f+ i12.显然,答案是C。概要分析器(profiler)能监视脚本的运行,并记录单个部分的运行时间。它可以用来找出和解决瓶颈。
& i4 K3 h+ r, ?
3 }; R+ L0 o$ k  `# _) ~! q5 |13.这是对调试器的完美定义!你可以用调试软件监视脚本运行,同时分析系统资源消耗,从而发现和解决程序缺陷。
  C; o6 y8 p4 Q7 v! ]. ^
# X! X# l7 V7 p  \! ?+ `14.trigger_error()和user_error()之间没有区别。后者其实是前者的别名。5 @' J1 W4 `1 ^- x/ U

1 Q+ U4 c7 K+ y' U4 q$ I15.答案是D。题目是在描述debug_backtrace函数,它返回一个由所有在代码的特定位置调用过的函数名组成的数组。

TOP

发新话题