返回列表 发帖

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

作为一个开发者,无论你经验多么丰富,或者无论你多么努力,你的程序中总会有bug。这是生命中一个必然的部分,如同死亡与缴税(尽管并没有后面两个那么严重)。5 \9 f3 u7 H9 z: q/ K/ P, y6 }
要想解决bug,首先要能找到bug。事实上,许多开发者花费了无数小时茫然得盯着代码,只是因为他们没有把程序的容错能力摆在首位。忽略了这个部分,那么期望一个没有bug的程序就是——不可能的。
, R: f* s5 K2 r0 _本章测试题将考察你对调试和性能管理相关知识的了解,以及如何用PHP做好这两件事。( n0 ~! ?' |' v7 R

/ t  {' @- ^# h* s5 x( I8 X8 ]/ p! z$ {, o- @) Z0 ?& D
问题
. V- C' r! C. T6 `( D% r
3 V& d- s  M0 a, d: L" j1.以下脚本如何用三元操作替代? ! X+ @, ~- L( D$ e- |

  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. ?>
复制代码
! Z2 q) W: W7 [6 _3 `6 _0 R
A.$x = ($a A. < 10 || $b > 11 || $c == 1 && $d != $c) ? 0 : 1;) g) Y+ C: X# F
B.$x = ($a < 10 || $b > 11 || ($c == 1 && $d != $c)) ? 0 : 1;
5 `( L+ f9 x, W5 ZC.$x = (($a < 10 && $b > 11) || ($c == 1 && $d != $c)) ? 0 : 1;- x9 V7 {1 x" o' c9 X+ g1 Q! w
D.$x = ($a < 10 && $b > 11 && $c == 1 && $d != $c) ? 1 : 0;
% C! Y& S9 {: f& |5 {- uE.以上都不对3 O* v  {8 Q. D6 e  s
9 d% K7 h+ N6 E" S

, z2 {7 G9 U. v! |2.有一个脚本由于要从远程获取数据,因而运行速度很慢,以下那种方法能对其进行优化?(双选)
8 L. [8 o/ |( l' P8 j
5 I& F2 b/ h% C$ c* _A.安装操作码缓存(opcode cache)
1 a- V  P2 R% u- _4 G9 dB.优化或者升级你的网络连接
* J8 t9 Z- }+ f% B  p  {. K) x+ lC.添置更多的硬件
  t& P9 t* ]0 F4 bD.增加服务器的可用RAM
' T/ d4 m) i2 R2 z/ M) SE.使用连接缓存
" o( h' T2 W0 A3 k# y! J- u: @" `
2 J/ u  E1 H$ W$ H$ t% ]5 ]: |7 D9 g: l  v7 k0 `  z/ m
3.架设生产环境下的服务器时,需要做哪些步骤?(双选)) |$ C# s* X/ Y! H
  [  Q. j& a! R% ^
A.关闭错误报告- z" k; Z4 {  b
B.打开错误日志
5 `& j3 X* {9 e0 @3 v5 z* S- MC.关闭错误日志
1 F9 s6 O8 H9 J% `4 qD.关闭错误显示6 L: q+ F# o: U2 ]
E.使用@抑错符
) P* t6 [/ H% E% l% j
) u, l3 C: x' W. E' T  }, ~/ K% G/ m% E
4.______操作符能对操作数的数据类型进行严格的比较?
' W) V" t" w6 e6 p& b
- n+ P; n# n0 O3 c答案:____________
7 Z+ `: G) D5 [5 @: y8 i- H. h% d1 r$ F
! ^( J) N7 ~( y5 C7 ]! Z: b% e
5.操作码缓存(opcode cache)能做什么?, V- n* q: |2 X. Z% j9 q5 w

3 F* E& }0 t" }: {& P% @: n$ ?+ AA.把脚本编译成二进制对象,使它运行得更快$ \# K) _8 o7 f- K* e% I
B.代替Zend引擎加快解释器的运行
  l* l: w; v! j/ EC.缓存脚本输出以提高执行效率
1 m% W  l4 [; {9 f/ QD.缓存解析器产生的中间码,以提高运行效率
' [$ G0 Q( \7 l( x  GE.在内存中缓存脚本,减少从硬盘中读取的次数! L( k# i# b9 k/ e  ^4 w
7 J- m; r9 [8 O$ _6 }+ Y
* n9 a1 F; B: c8 }
6.以下哪些情况容易造成系统资源枯竭?(双选), Q; b* @" v# d( z! Q; w

( K9 G# Y( E4 o% @8 E2 S5 q: n" X! DA.RAM太小$ m" I: ?' ]( K- j* X. J9 L
B.使用了低带宽的连接
% Q* y0 M9 J# y6 qC.虚拟内存超过2GB( h' ~8 Z/ H; Q
D.允许同时运行太多的服务器进程: @3 x, Z) E% O
E.以上都不对
4 N2 ^# |8 m  y0 F
- S8 @) V7 F4 \' J" y$ w. k6 ?. Y, q
7.以下脚本缺了些什么?(双选)   h+ N$ p/ q: A& k, ]' K. z7 `5 k

  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. ?>
复制代码

4 H2 d1 O- H/ g6 G2 dA.参数出口(Parameter escapement)
7 d, T' v, g  k. h7 B- x& aB.输出格式化
4 ?" y$ r  Z+ I% b/ |C.错误检查% ?: j* P, _7 U9 j/ v' @
D.一个SQL查询
* [9 k) F5 {# u! r* k* t8 GE.以上都不对& \" `- N0 j' J: X& d% k6 Y
, v+ V+ T! D2 D
* R- P& ]( ^* O0 e, u8 x. F
8.以下那种错误类型无法被自定义的错误处理器捕捉到?(双选)
4 W" s9 M9 T) K. n3 o0 v. E  ^+ K- V8 M$ A# b
A.E_WARNING' j. J" n' W1 Y" C# V
B.E_ERROR4 _% b) Y! |  L' i
C.E_USER_ERROR8 G0 D5 y1 E" e
D.E_PARSE
/ s7 t& ~+ B% l6 s! G2 GE.E_NOTICE9 b) F4 p" g7 T/ ^

# F3 N" A5 J8 W+ _+ H6 W6 H% p6 v) q* j+ A/ F# h! |
9.当需要比较一个常量和一个变量时,如何才能保证不会错弄成赋值?4 |' i' [" M6 O3 x' W% g3 Q. T

8 x. K! I7 Z3 @$ b* `$ {) l# K6 yA.把变量转换成int
4 P+ |4 [2 K9 `, x! o/ LB.使用全等比较符(===)) T. ~3 Q. }8 f9 w; k6 v/ o+ J
C.确保常量是第一个操作数
/ v0 ?& m+ `; dD.使用三元运算符4 F5 g" x; p" z
E.用括号把操作包起来
" ^; W# M$ N# U2 c
! x6 G' ~) y( t, O  i6 ]7 z5 [  m  x2 t5 X0 @3 a
10.要通过邮件给系统管理员发送错误信息,以下那种方法最简便?
' A# E2 [% n$ K
2 o5 J0 U( C) Q+ ?+ nA.创建一个连接远程SMTP服务器的函数6 z) m! T" L2 G3 p9 [  G9 P
B.使用mail函数
* V6 X" ]2 }3 @" P8 d0 ]5 w7 k) uC.使用error_log函数
% }2 n- a) g6 N* F+ D+ _D.调用sendmial程序
! s% ~( B6 ^: t; Q( ^" cE.使用webservice4 k5 c4 j: ^6 F
5 T7 l  Q9 |' |. q
$ s$ B' S8 T  o8 ?3 M, |8 A/ G
11.能否仅调用一个函数就关闭脚本内所有的错误报告?9 k- i) X; K8 Q. q0 C
6 L0 n/ G3 J9 S$ A/ L3 F
A.能
: m9 Z$ e7 N8 B" K- xB.不能
6 t9 K3 ?6 L( z. x* U& y
4 a5 D# t2 W6 V* z- X4 M* p
& H* s& @* x3 f. V12.概要分析器(profiler)是做什么的?
+ S, ]/ ?' U$ S3 p  N1 ?5 w& _0 _9 K# b1 x/ Q
A.创建关于脚本结构的档案
, [4 L: W: t4 V# Z: ^1 QB.把脚本转化成UML图
/ k/ o' y' w" j! D! A9 U, l' ]C.精确测算脚本不同部分的运行时间
. _, S) m5 d' X- R5 s- Z. R. _D.计算脚本通过web服务器执行时的维度
- ~& U5 d6 u0 ~- \5 sE.扫描脚本,识别由常见错误导致的bug+ X6 y4 B, x$ K( l8 n$ T
, G+ n) s) U& |2 ~
8 D& G% Q8 g4 i% ]/ v; i8 ?. X
13.______能帮助识别和解决bug。" y% H7 K; t7 l4 _
' h1 Y$ Y! @& ^+ @5 Y% |' b
答案:____________
( I4 W! T$ g6 I4 ?% |; S7 a
7 H) p- D* R6 r9 d  p& A# j
( r; P! \; e3 V6 l; n; Y) u14.trigger_error()和user_error()有什么区别?
5 B* e- C( u. G5 u7 o  W$ w
, c7 }) q* R: [/ K0 }) C3 hA.trigger_error()允许脚本抛出系统级的错误$ N( h% X1 v( |$ s) v" P$ Q0 P
B.user_error()允许脚本抛出系统级的错误+ w) d" L7 c4 J7 R  _  T& a
C.user_error()不能被用在错误管理器中
+ |. G# ]$ v1 T; ]/ z+ VD.trigger_error只在PHP5中可用* _/ h- s" I5 v/ M4 @5 z- v+ H
E.没有区别
  g9 u6 K. `; Z+ Y  g! `& D4 o4 l, v9 O
; }6 J" ^8 |: A* r- n# {0 G
15.______函数能返回脚本里任意行中调用的函数的名称。该函数同时还经常被用在调试中,用来判断错误是如何发生的。( U( |/ E2 d. e5 @- l. W
, F2 L4 w) N- k+ H4 h
A.print_r( |' M$ p$ _% q* N0 e$ k
B.var_dump
+ ]6 h9 ^) c3 V5 RC.stack_dump
1 e8 C8 ^3 i2 z2 V6 K* T: N: r# ]D.debug_backtrace
1 j( V" A- ^8 g$ mE.以上都不对8 B% l1 V, X6 q9 _+ h

+ M3 B0 t/ t, f# O答案5 g2 n) U! M  d' S

; x/ B+ d: q! ?8 P1 t$ A1.答案是E。三元操作符把每个if语句连到一起,作为&&操作的一部分。然而本题中,$x=1这个赋值只在第三个if为false时发生。如果第一个和第二个条件都不成立,$x=1就不会执行。这题对三元操作的应用有些极端,实际应用时,需要根据可读性来决定是否需要用三元运算符(本题这种情况就最好不要用)。
# R# J& c+ o% o4 J+ r0 t
! t+ R0 [3 f. n* ^% H& {2.问题是由第三方数据源传输缓慢导致的,而你无法控制这个数据源。你也许能在网络连通性上做些工作(假设问题出在你这一边)。还可以对接收到的内容进行缓存,这样能减少获取重复数据的时间。因此,答案是B和E。
+ E/ o, K. g9 I1 ~1 j2 ^7 Y" u  p& k  ?
3.正确的选择是B和D。如果关闭错误报告、使用@抑错符和关闭错误日志,那么在你交付给客户的网站出现问题时,你将很难进行分析和调试。
! D7 d- {( O8 k
# h% G0 }7 q/ s; |1 Q. V4 C4.这是在描述===操作符。. J, f3 G: S. }9 [

7 f. o' a. O& |& S; p5.正确答案是D。PHP脚本在执行时,将首先被解析成“中间”码(也叫opcode,操作码),然后解释器执行。操作码缓存出现在这两个步骤之间,对解析器的输出进行缓存。下次执行该脚本时,将缓存的输出直接送入解释器。这样就就不需要再解析一次了。- Q/ E1 S2 l+ o( j% D; v0 u
" G6 s) d4 {  t3 D3 O; Q1 ^% V" j
6.正确答案是A和D。如果RAM太小,进程间将出现资源竞争,服务器将大量使用硬盘交换。同样的,如果允许过多进程同时执行,也会使服务器频繁进行交换,导致速度下降。; M4 I. t$ b+ [  I) R7 t! w
2 n5 _# m1 s; V6 l) p
7.正确答案是A和C。脚本不检验datebase_query()的调用是否成功,因此将持续执行下去,最终产生错误。此外,$my_id参数没有转义——可能导致代码注入(详见第11章)。
3 t" _+ B% f) p0 E' n( u
6 p/ P# `3 n4 R; A- y6 U8.答案B和D正确。出现解析错误往往表示脚本中有语法错误,自定义的错误管理器无法捕捉到它们的原因很明显:错误管理器在脚本里,而现在无法解析脚本,管理器也就无法执行。类似的,E_ERROR表示有致命的运行错误出现,比如内存耗尽。因此脚本会立刻被中断,因为解释器无法执行后面的代码。5 U; ?, M$ n% e* N" x( j3 K
7 V! k3 U  B0 w7 T" k+ v6 w
9.答案是C。比较操作是一个可交换的操作(就是说结果独立于操作数之外),而赋值不是。因此,比如说,$a==10和10==$a是等效的,而$a=10和10=$a却不是,而且后者会导致一个错误,因为这不是一个合法的操作。确保常量在操作符前面,能保证你不会错误得将比较变成赋值。  F& a; e4 @, q
( c: c5 s7 B( \  y- Q  f
10.答案是C。error_log函数能将信息送往一个指定的地址。尽管mail()也可以用,但error_log能自动给邮件添加标题,因此这才是最简单的方法。/ c0 \' f9 ~" C9 ]- K
; r) D6 h$ F. A5 n; ^4 f6 _
11.答案是不能。error_reporting函数能关闭所有运行时的错误报告,但对解析时的错误无效,因为解析错误发生在脚本执行之前。# R$ S" t/ Q+ ?$ t" B
. d' p, u! b' t" v) w# f
12.显然,答案是C。概要分析器(profiler)能监视脚本的运行,并记录单个部分的运行时间。它可以用来找出和解决瓶颈。2 B5 l8 M2 S. A0 ^

+ W/ L) g# z* w13.这是对调试器的完美定义!你可以用调试软件监视脚本运行,同时分析系统资源消耗,从而发现和解决程序缺陷。
& J# A( A+ i$ z/ p1 |8 N7 h+ P4 N( @& ^& @: n
14.trigger_error()和user_error()之间没有区别。后者其实是前者的别名。
! q) _( n  V, b8 V5 j, M) b& g' P2 i5 R3 Y! G5 W, E$ q
15.答案是D。题目是在描述debug_backtrace函数,它返回一个由所有在代码的特定位置调用过的函数名组成的数组。

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