返回列表 发帖

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

作为一个开发者,无论你经验多么丰富,或者无论你多么努力,你的程序中总会有bug。这是生命中一个必然的部分,如同死亡与缴税(尽管并没有后面两个那么严重)。
1 ~' f/ E$ z9 r9 l6 N% B& g; k( `, g要想解决bug,首先要能找到bug。事实上,许多开发者花费了无数小时茫然得盯着代码,只是因为他们没有把程序的容错能力摆在首位。忽略了这个部分,那么期望一个没有bug的程序就是——不可能的。9 ^3 x' Z* ]& B6 A: y+ {0 `7 t. t
本章测试题将考察你对调试和性能管理相关知识的了解,以及如何用PHP做好这两件事。  T/ [3 F# O7 l$ G8 ]$ `3 ^

% c+ d7 Y+ S0 _! A2 i
' g+ e# n5 o! M% a问题
# F, d+ h1 t/ U. c* p4 K: s$ T; A! t; b1 t2 m2 [
1.以下脚本如何用三元操作替代? + ]# I# i% i, T

  1. <?php
  2. if ($a < 10) {
  3.     if ($b > 11) {
  4.         if ($c == 10 && $d != $c) {
  5.             $x = 0;
  6.         } else {
  7.             $x = 1;
  8.         }
  9.     }
  10. }
  11. ?>
复制代码

. s5 q. S3 O6 f* p5 KA.$x = ($a A. < 10 || $b > 11 || $c == 1 && $d != $c) ? 0 : 1;- P- i. ?" j, y  G4 M  E
B.$x = ($a < 10 || $b > 11 || ($c == 1 && $d != $c)) ? 0 : 1;
( ?3 A0 f# F- IC.$x = (($a < 10 && $b > 11) || ($c == 1 && $d != $c)) ? 0 : 1;# e' S' r! Y, E7 q5 }$ s" E
D.$x = ($a < 10 && $b > 11 && $c == 1 && $d != $c) ? 1 : 0;
. Y' V  Y$ w* F! H2 s& Q) mE.以上都不对
# Q% M) G0 A' L, T# g5 I, z* B9 c2 f
4 u+ O+ L& m& U0 d8 ^% a2 m
2.有一个脚本由于要从远程获取数据,因而运行速度很慢,以下那种方法能对其进行优化?(双选)
! [1 L  l1 K& w* \1 }# i4 M. `! ~9 y4 R; v$ H
A.安装操作码缓存(opcode cache)+ l" R0 K1 |, a! K
B.优化或者升级你的网络连接
% S* r- L( R8 F7 S4 z& vC.添置更多的硬件
: d% L/ G: A0 R$ |4 dD.增加服务器的可用RAM4 n- X6 T  c9 w( ~2 m% S- \8 X
E.使用连接缓存6 n" u: A: F/ @

5 ]7 \. @. @6 a- }, y: [/ }. p+ P8 {& K$ L
3.架设生产环境下的服务器时,需要做哪些步骤?(双选)
3 K- U& L+ J1 }- `3 ^. b" e7 n
6 i  ]6 w5 D4 D+ t, ?* \$ mA.关闭错误报告
/ F4 Y4 @2 ^6 y) g9 o( TB.打开错误日志
3 h5 j. i! Q4 N- n, ^C.关闭错误日志% H2 H& r' B; {; C* s
D.关闭错误显示
7 Z; k. X4 D5 V+ V/ d7 DE.使用@抑错符1 J  w! w6 v1 o  ?! `
) e" W6 u1 k- \) K- X3 G

+ [2 X5 g( s% S8 b" Z! T. k! Y+ `4.______操作符能对操作数的数据类型进行严格的比较?
  c8 e. ?* Y% K) h# g: w3 s7 {. Z4 |6 n5 z
答案:____________
% P6 E9 J* C) \5 C; ~
, p6 ]( [3 e* M1 y& T1 U. n$ a3 W2 u9 W* f& n4 m2 R- d" A) w9 X
5.操作码缓存(opcode cache)能做什么?( M% V# a: M% h7 `$ N5 s4 y
! I1 ?  t% t, f& w
A.把脚本编译成二进制对象,使它运行得更快2 b" z6 k7 a$ d# \5 }! o0 F' x
B.代替Zend引擎加快解释器的运行
+ c2 J( O. W' PC.缓存脚本输出以提高执行效率
# }0 m! T) w0 T; sD.缓存解析器产生的中间码,以提高运行效率4 G4 ^% J" K: C+ s
E.在内存中缓存脚本,减少从硬盘中读取的次数
( a2 a. `$ S9 U4 |: z4 r& y; m
2 U) N6 m3 O4 f3 x
9 z% `2 G  P( f/ Q! }7 j' P6.以下哪些情况容易造成系统资源枯竭?(双选)
1 W  N: L! i$ _0 W. Z7 I
" @# p" R6 G' {5 x3 E6 oA.RAM太小
( x0 k, K, Z- b% c  K5 }7 mB.使用了低带宽的连接; p/ ?, z1 R& e- c/ s: M# [
C.虚拟内存超过2GB0 V# Z8 |+ r* p
D.允许同时运行太多的服务器进程$ K( Q) `6 i9 q3 e6 C' `
E.以上都不对
3 ]& t  c' T& g0 `' x% o" L; D( H  G+ ?! ?6 x
& W6 }8 A" S/ t( o; O' e* L) j
7.以下脚本缺了些什么?(双选)
$ ]( S$ l/ @" R$ S& w( ?

  1. <?php
  2. $rs = database_query ("select * from mytable where id = " .
  3. $my_id);
  4. while ($a = database_get_data ($rs)) {
  5.     var_dump ($a);
  6. }
  7. ?>
复制代码

; W' V$ ?' n8 [8 k. H1 F7 xA.参数出口(Parameter escapement)
# s, j7 a. k' {; ~B.输出格式化
' h& U  J, [/ |. k2 GC.错误检查
' n2 ~7 |' l% l6 a" _7 nD.一个SQL查询6 ?) e1 O& i. I8 E) L0 e
E.以上都不对
: f4 \' Z6 e% L  {
2 E+ v* L& s% Q' ^( g0 |6 g: l% h
1 [3 U5 ?2 b3 P4 s& f- V9 |8.以下那种错误类型无法被自定义的错误处理器捕捉到?(双选)+ D8 }5 n5 b- b& y
6 l. ~6 W- y+ N( d. r" C
A.E_WARNING
+ j* s6 I5 U' U& r7 HB.E_ERROR
  K* V7 F5 L' ~1 C% O4 ?C.E_USER_ERROR  N( b/ d; @9 T5 A6 z, g
D.E_PARSE
& d, O# k3 {) gE.E_NOTICE
- D" D/ L! R$ W  W
: G- e' Z& v+ V# F) R$ n
; W, S5 r9 }( a1 `8 l/ o; e9.当需要比较一个常量和一个变量时,如何才能保证不会错弄成赋值?* a6 j% C5 L& k, j. ~1 i
0 @; ?) B5 `. q7 R6 J
A.把变量转换成int. p" G  Q: n- d# I6 l
B.使用全等比较符(===)
2 J* {4 ?* ^+ m6 R" [9 J, eC.确保常量是第一个操作数
: W/ Y5 R/ r0 Z- y5 C' j' M% ID.使用三元运算符
. ?8 b9 Z5 F* e& B1 P, a0 PE.用括号把操作包起来
8 k4 Z( ?/ e  x2 Q% p- ^/ G1 g8 E0 L* _2 w3 L) R- `

6 B7 y) c7 J4 O( |, K+ b10.要通过邮件给系统管理员发送错误信息,以下那种方法最简便?
- ?2 [( Z' m  ~; N8 h3 k, g, ?" Q( E4 C4 H
A.创建一个连接远程SMTP服务器的函数& K8 m& z3 S3 b1 }/ u, F) D
B.使用mail函数- n1 b. c/ |: k2 ]2 K, h
C.使用error_log函数/ [2 u6 C" i$ W/ }+ h; R) L
D.调用sendmial程序6 N$ U  f7 j) M8 F4 W
E.使用webservice% x7 S; K& ~. Y6 w) Y% f

. E: w2 W0 t; o" Y% i& N8 R
8 Q5 b0 l- r: S, f11.能否仅调用一个函数就关闭脚本内所有的错误报告?
* A4 ~  ~$ N* {% q9 f: ?, X/ O  A$ c2 }& C( \1 N
A.能
" \5 V" i1 J0 X0 o* Z0 ~# ?: fB.不能8 [: O; e' ^2 K: W. B! ^' m

6 G/ u0 _% A/ Q. B- f3 y0 n* J! ]3 t/ }' p% g1 B; ^/ j" Q
12.概要分析器(profiler)是做什么的?$ ~+ v9 T/ Q  y9 D/ x! `

  [  o7 e1 n) E9 f2 [. X6 JA.创建关于脚本结构的档案
9 q/ O4 H( w) R& I4 b- r; LB.把脚本转化成UML图
  g7 u5 V+ ?  TC.精确测算脚本不同部分的运行时间
( g$ u4 u( J3 Y' dD.计算脚本通过web服务器执行时的维度
  H: u2 w' |' I& G6 aE.扫描脚本,识别由常见错误导致的bug0 |8 x) r# A/ s' W8 E
( n9 {  a, v, z
4 p3 H* u9 w7 W: g1 |4 C9 {* w
13.______能帮助识别和解决bug。
( s8 w/ S  E. N: E8 n* T: P! `. [8 q  @8 E: n8 S4 \6 [
答案:____________$ ^" U0 J* }) E* u
3 a: i; k: U( |5 D- R

; A; \5 x* M4 ]) _14.trigger_error()和user_error()有什么区别?6 }* I& a6 K+ i4 m9 p

% S' c& O5 ]5 g( M0 Z( v( lA.trigger_error()允许脚本抛出系统级的错误
9 @! o5 W: d/ ~! |* o. v/ xB.user_error()允许脚本抛出系统级的错误
/ D5 s4 e9 c1 t4 sC.user_error()不能被用在错误管理器中
' L( P* Q& i4 s& vD.trigger_error只在PHP5中可用$ B' _$ O, N& O
E.没有区别! |. O( J! L' I' U
6 x4 H- i+ K  G' }: f

# S/ D" r6 G) z2 W$ ]5 ^3 [+ i15.______函数能返回脚本里任意行中调用的函数的名称。该函数同时还经常被用在调试中,用来判断错误是如何发生的。
/ x# [, r5 O8 Z. [) R" O$ C
. N: u0 X+ W8 p' U# t8 }8 zA.print_r/ ^7 l! ~5 K2 M4 O& v9 T% k
B.var_dump- z% J4 ]/ L4 G3 |" Z! @, s
C.stack_dump
' x6 [% S8 t; P1 iD.debug_backtrace
% t3 _4 {/ l! TE.以上都不对
& H' [1 `7 K  v  \
& c& w0 r5 V0 @答案! I- V" X- v4 ~! s$ A/ N- _# L
" Y! ~$ B' J, n2 G8 z" U+ x/ C7 e
1.答案是E。三元操作符把每个if语句连到一起,作为&&操作的一部分。然而本题中,$x=1这个赋值只在第三个if为false时发生。如果第一个和第二个条件都不成立,$x=1就不会执行。这题对三元操作的应用有些极端,实际应用时,需要根据可读性来决定是否需要用三元运算符(本题这种情况就最好不要用)。% s. g1 z4 @1 L5 x3 S  ]6 g

% T: |; v0 ]0 K! B8 C& [; W; x+ g2.问题是由第三方数据源传输缓慢导致的,而你无法控制这个数据源。你也许能在网络连通性上做些工作(假设问题出在你这一边)。还可以对接收到的内容进行缓存,这样能减少获取重复数据的时间。因此,答案是B和E。1 x( o. F2 D3 @
6 `( e( h' j7 F2 m0 I
3.正确的选择是B和D。如果关闭错误报告、使用@抑错符和关闭错误日志,那么在你交付给客户的网站出现问题时,你将很难进行分析和调试。/ L) `% L6 ]+ A0 e  L
9 R: e. t4 d; B0 L8 ]2 D4 J6 T
4.这是在描述===操作符。0 I. I  [/ s( R
  J+ U, |( w( _6 p# ]9 S9 j
5.正确答案是D。PHP脚本在执行时,将首先被解析成“中间”码(也叫opcode,操作码),然后解释器执行。操作码缓存出现在这两个步骤之间,对解析器的输出进行缓存。下次执行该脚本时,将缓存的输出直接送入解释器。这样就就不需要再解析一次了。+ O: u2 t& R* h
- K- V1 y  G0 Z9 y# L% ^
6.正确答案是A和D。如果RAM太小,进程间将出现资源竞争,服务器将大量使用硬盘交换。同样的,如果允许过多进程同时执行,也会使服务器频繁进行交换,导致速度下降。
* }0 w: A. e8 C+ v& D" P) |1 [' v* Y
7.正确答案是A和C。脚本不检验datebase_query()的调用是否成功,因此将持续执行下去,最终产生错误。此外,$my_id参数没有转义——可能导致代码注入(详见第11章)。# k, p. z( R" a/ M9 p# v3 I
- M; b$ f! X9 \' l/ E9 f! d
8.答案B和D正确。出现解析错误往往表示脚本中有语法错误,自定义的错误管理器无法捕捉到它们的原因很明显:错误管理器在脚本里,而现在无法解析脚本,管理器也就无法执行。类似的,E_ERROR表示有致命的运行错误出现,比如内存耗尽。因此脚本会立刻被中断,因为解释器无法执行后面的代码。
  n- I( Q6 o( N7 T. D9 b- Z. g! r; q0 v: K8 F8 L
9.答案是C。比较操作是一个可交换的操作(就是说结果独立于操作数之外),而赋值不是。因此,比如说,$a==10和10==$a是等效的,而$a=10和10=$a却不是,而且后者会导致一个错误,因为这不是一个合法的操作。确保常量在操作符前面,能保证你不会错误得将比较变成赋值。
. L5 A* B+ K) B; R! p8 r5 G" J$ h8 I- D
10.答案是C。error_log函数能将信息送往一个指定的地址。尽管mail()也可以用,但error_log能自动给邮件添加标题,因此这才是最简单的方法。" H6 n) ~3 f# |3 {
: g+ t# G) }, z# k, b# c6 @3 M& B. M+ e
11.答案是不能。error_reporting函数能关闭所有运行时的错误报告,但对解析时的错误无效,因为解析错误发生在脚本执行之前。' v+ b/ d8 M3 M) S4 T

0 W" G2 D) |2 D# O12.显然,答案是C。概要分析器(profiler)能监视脚本的运行,并记录单个部分的运行时间。它可以用来找出和解决瓶颈。  D9 D3 F1 x3 }) P

( ^+ @( O% b: f. r& a: a13.这是对调试器的完美定义!你可以用调试软件监视脚本运行,同时分析系统资源消耗,从而发现和解决程序缺陷。; G1 w6 N( ~8 A, d
: e% o: A  g$ ]
14.trigger_error()和user_error()之间没有区别。后者其实是前者的别名。2 f8 b" T- f( t( N

  f& U, `% e" M% t: T! o& E15.答案是D。题目是在描述debug_backtrace函数,它返回一个由所有在代码的特定位置调用过的函数名组成的数组。

返回列表
【捌玖网络】已经运行: