返回列表 发帖

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

作为一个开发者,无论你经验多么丰富,或者无论你多么努力,你的程序中总会有bug。这是生命中一个必然的部分,如同死亡与缴税(尽管并没有后面两个那么严重)。
0 f6 ^$ Y5 L/ j3 o. f7 F( Z要想解决bug,首先要能找到bug。事实上,许多开发者花费了无数小时茫然得盯着代码,只是因为他们没有把程序的容错能力摆在首位。忽略了这个部分,那么期望一个没有bug的程序就是——不可能的。
( [$ I. n& b  K, D+ ?本章测试题将考察你对调试和性能管理相关知识的了解,以及如何用PHP做好这两件事。, A7 Q$ p4 _7 E/ B9 Y* D, m
! E3 u& @' y; v) a  c, F9 ~

, b* E$ G7 Z3 O* C8 ^" o* N: e问题- o0 J/ [, O  U+ Y5 z  a' R
/ W2 V+ u" Z! T' C. Y- }* j
1.以下脚本如何用三元操作替代? 2 l: B; y' o. {5 d& o' w' o+ I

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

0 A, Q% [, ^$ v8 CA.$x = ($a A. < 10 || $b > 11 || $c == 1 && $d != $c) ? 0 : 1;
* o9 d- r0 ]3 k; Y# _* I" wB.$x = ($a < 10 || $b > 11 || ($c == 1 && $d != $c)) ? 0 : 1;
2 o/ P1 u6 u( w+ T; b5 ~1 i8 S. qC.$x = (($a < 10 && $b > 11) || ($c == 1 && $d != $c)) ? 0 : 1;* ?$ g5 W& U* }1 y# S- T$ w- Q
D.$x = ($a < 10 && $b > 11 && $c == 1 && $d != $c) ? 1 : 0;
$ g' U( g1 a" l2 ]+ Y$ RE.以上都不对
5 j- ^' T4 \: C( R) L' F$ d/ G
& |( t6 @* [! |& W. F1 [
6 S6 C7 O! G( h5 |4 _% f  K2.有一个脚本由于要从远程获取数据,因而运行速度很慢,以下那种方法能对其进行优化?(双选)* p$ W) z4 h6 C. k$ }

; C$ q7 \- D# w- @: t6 w) O) \A.安装操作码缓存(opcode cache)* \6 O- L( W4 N9 z
B.优化或者升级你的网络连接% |/ x) v" a0 d  {. J" W+ y- P
C.添置更多的硬件2 X! y  k1 \, a- e
D.增加服务器的可用RAM
. U! ^% n, n6 ^# `1 G3 JE.使用连接缓存
3 S$ |3 g! G' o& C; F' A( G5 L3 x& O5 T* B$ P$ B0 J  I& }
7 v# w+ q7 L) |9 i" v" i* E- v
3.架设生产环境下的服务器时,需要做哪些步骤?(双选)
$ v+ F5 O( F3 w2 O) V
# ?, b8 {+ F' C4 P0 n' rA.关闭错误报告
, ]5 O5 E1 ?4 f, ]B.打开错误日志0 R' [9 d% l  L. w7 V$ l
C.关闭错误日志
; }; G) ?+ h  S9 D1 ?  KD.关闭错误显示' \$ l  @5 x& H# T) ?  w- e* b' W
E.使用@抑错符
' j8 a& b% o% N4 y8 N9 T6 k& x9 d7 F1 H! B1 h) n4 b: u

* ?1 a! p+ v) r6 m% l5 D3 w4.______操作符能对操作数的数据类型进行严格的比较?& M/ v: i; {2 v+ v8 S; t1 W
9 j7 w$ h: L  `8 E* N0 M# |0 U7 C
答案:____________9 Y# n* h$ G. O; T
7 L4 D( a; y3 x) {2 {4 B6 o
( D2 @( _- c8 I( g
5.操作码缓存(opcode cache)能做什么?
8 l. l) R7 |$ K- M: v0 u, F0 Q1 z# E6 K: }
A.把脚本编译成二进制对象,使它运行得更快
8 P, O! Q5 e! H& z( N, h7 S. ^& pB.代替Zend引擎加快解释器的运行" y! C: y1 a3 M+ v3 |' J
C.缓存脚本输出以提高执行效率
2 [! z. @( Q! i8 @) A! y6 XD.缓存解析器产生的中间码,以提高运行效率
! F% r7 r  f' E0 o& W+ Q- gE.在内存中缓存脚本,减少从硬盘中读取的次数
! D& q" `2 i) P: ^. K  Z4 e
' E2 m$ Z& Z+ K5 F3 [$ O' b8 z  l% A1 J4 j* U! c) h$ s
6.以下哪些情况容易造成系统资源枯竭?(双选)
/ g  T$ A: ~$ L2 k& r% B, L" R" Q" z) t' ?) Q% }
A.RAM太小( K5 c/ x9 v$ D2 W$ j
B.使用了低带宽的连接0 Y0 q5 B0 u+ H+ S% y) ?
C.虚拟内存超过2GB
/ T9 w4 Y1 s8 k, CD.允许同时运行太多的服务器进程3 e. I# }4 M0 q# \  r4 v
E.以上都不对
; _6 G; b! k- q- b" k1 z. X) |' f3 T8 V( p- k) j  c4 Y( E5 U. w/ X
2 d6 t# x" J  r% N0 ?7 V
7.以下脚本缺了些什么?(双选)
, S% m% g" ~5 ?2 X

  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 y! b- l2 q% J: `+ {A.参数出口(Parameter escapement)
" e* d5 t  }* T1 \7 D/ {B.输出格式化+ \4 q! F/ d/ `- |/ C" |5 t
C.错误检查
9 {$ i4 L1 q: |' o) ^; W  t+ rD.一个SQL查询- M! s1 `. t* _2 z) W
E.以上都不对
2 I1 s  w" ]- p% @
6 [4 c( v  H" m1 n8 @
3 M+ B- N' q0 \& i) _7 i8.以下那种错误类型无法被自定义的错误处理器捕捉到?(双选)
- w! O% w% V  M/ ~4 ^, |
) X' Z& k& [' b- p0 BA.E_WARNING
$ b0 N6 j& X/ n5 {* B" RB.E_ERROR" H6 i3 }5 H( U  f# n5 g9 D
C.E_USER_ERROR
& P7 H! e5 m3 @D.E_PARSE
/ |# c! Z' `+ |2 c' zE.E_NOTICE. N  n; {: o9 p% u/ S" L
/ E9 E: b- Z$ V9 i5 Q6 h

6 f" A" p: w! y$ |1 J, x9.当需要比较一个常量和一个变量时,如何才能保证不会错弄成赋值?7 z' n1 o4 r& u. @( Q8 ~
7 E& m' u3 `/ R$ t0 l
A.把变量转换成int
! B7 o" j8 N# mB.使用全等比较符(===)
4 r' L! ~8 k* N: n9 J1 oC.确保常量是第一个操作数
$ B! Y, O5 m* K9 jD.使用三元运算符
" d; p# R, |/ }E.用括号把操作包起来
6 e- F# P5 `9 T) `( l( v5 s; y. q6 ~1 C$ i! O$ Q1 P: z, q
8 R& A' k& g! E7 y: w! |; |) B
10.要通过邮件给系统管理员发送错误信息,以下那种方法最简便?/ U" l3 Y$ B6 ~/ p$ ^

8 B  f4 V) M" b- C$ p* B/ sA.创建一个连接远程SMTP服务器的函数
# t1 W0 i, a: }. kB.使用mail函数
. d4 z8 W: |2 N. b2 \C.使用error_log函数" y; V0 W" u+ p
D.调用sendmial程序
4 m( h5 }+ o6 v# qE.使用webservice
1 ^% A7 |' a: T; L6 A6 L- ~# j% z8 m
* ~( X# X9 l8 h- O) h
. x( I$ f) W' R" N1 G8 _  E11.能否仅调用一个函数就关闭脚本内所有的错误报告?
  N3 F3 U6 W* R' f, L# r6 Y6 N( O$ S
A.能
5 \) a2 t8 e" @! [  oB.不能9 @, D, Q' _0 |  v% G; t

; b' h4 G& F# Z8 J
2 {" D9 O6 h! k$ _) t- a12.概要分析器(profiler)是做什么的?
% T% |) V8 a- _0 q1 Z
- r8 O2 ^8 K; v5 u2 ~A.创建关于脚本结构的档案4 Z+ @- k4 Z1 m, b+ A3 D3 L1 [
B.把脚本转化成UML图2 X; ]  b4 O0 H0 R
C.精确测算脚本不同部分的运行时间
3 r0 H( R, S0 Z# ]4 B1 o- ~+ z& vD.计算脚本通过web服务器执行时的维度- V2 [: A# U: Q& y" @/ A7 S2 H
E.扫描脚本,识别由常见错误导致的bug
$ b( ]7 [8 y9 F, J
/ f5 \( b* q8 ^
" g9 \/ H: s) v" E9 Y13.______能帮助识别和解决bug。* s* M9 _/ e7 G4 [6 d
$ K& p3 _$ \" q/ n/ p
答案:____________5 l1 K# g4 C* @7 C) m% t

( L* a9 l! h$ o; u: |- k/ e# [7 c' _7 U* |: k
14.trigger_error()和user_error()有什么区别?
4 x% V5 g5 Q$ T9 J9 m& ~; _) D6 A) J: M  u8 S# l
A.trigger_error()允许脚本抛出系统级的错误) r7 G: i$ l/ G8 A' m! I
B.user_error()允许脚本抛出系统级的错误$ c/ Q1 t+ ?8 F2 M6 i: @: \" ]
C.user_error()不能被用在错误管理器中
3 B6 W1 D2 d/ J) H( y% q2 MD.trigger_error只在PHP5中可用
! D2 E3 f: |# o  D$ q7 gE.没有区别; R( L; t3 D0 `
8 M" K, F7 V4 }, y) l
, a' B4 ]3 \# k' w3 c4 Q1 R
15.______函数能返回脚本里任意行中调用的函数的名称。该函数同时还经常被用在调试中,用来判断错误是如何发生的。7 {) I* i. V$ Q- A9 r
% l2 l# \. T7 h# c& e4 k+ c
A.print_r$ A% Y/ A4 g& I- h: s# f
B.var_dump
/ J. z. s/ e  W8 cC.stack_dump
8 E- a( {& }. b& N% W) x% ]3 F# QD.debug_backtrace6 |/ r, n4 W1 ^$ W  r3 f6 ]4 q
E.以上都不对
2 w) ^' @' j/ g3 O% G5 |; Z5 ]' G1 m( m2 g/ V& }9 X4 K8 z  |
答案
% M1 y0 L3 v# O& K; a0 }- B& H" t! P. z6 u+ M: B% A- I
1.答案是E。三元操作符把每个if语句连到一起,作为&&操作的一部分。然而本题中,$x=1这个赋值只在第三个if为false时发生。如果第一个和第二个条件都不成立,$x=1就不会执行。这题对三元操作的应用有些极端,实际应用时,需要根据可读性来决定是否需要用三元运算符(本题这种情况就最好不要用)。
$ V, N1 y4 l# a9 O5 [1 {, o6 \& s) Y* p7 |; `8 p6 z
2.问题是由第三方数据源传输缓慢导致的,而你无法控制这个数据源。你也许能在网络连通性上做些工作(假设问题出在你这一边)。还可以对接收到的内容进行缓存,这样能减少获取重复数据的时间。因此,答案是B和E。
3 p% d- Y8 v! J& S( _7 Q
. k3 `* w8 L" i& Z3.正确的选择是B和D。如果关闭错误报告、使用@抑错符和关闭错误日志,那么在你交付给客户的网站出现问题时,你将很难进行分析和调试。
' h1 w, Z+ m' y5 j/ i5 C8 A& z# h
4.这是在描述===操作符。
/ Y0 H& {. k& R* F: A$ R" F0 ^2 w
1 ?) s" K: W0 g( V8 h5.正确答案是D。PHP脚本在执行时,将首先被解析成“中间”码(也叫opcode,操作码),然后解释器执行。操作码缓存出现在这两个步骤之间,对解析器的输出进行缓存。下次执行该脚本时,将缓存的输出直接送入解释器。这样就就不需要再解析一次了。2 E. X/ j" R0 f8 E. |: z9 B' X
, ?3 z4 x4 }% T# h7 `" B
6.正确答案是A和D。如果RAM太小,进程间将出现资源竞争,服务器将大量使用硬盘交换。同样的,如果允许过多进程同时执行,也会使服务器频繁进行交换,导致速度下降。
# e$ O+ T9 _; u- |( p) e% Y, _  u; C4 y8 x4 m1 K7 ^
7.正确答案是A和C。脚本不检验datebase_query()的调用是否成功,因此将持续执行下去,最终产生错误。此外,$my_id参数没有转义——可能导致代码注入(详见第11章)。
/ K1 B1 F0 D. m5 ?- c: G2 Q# H- w0 E. _
8.答案B和D正确。出现解析错误往往表示脚本中有语法错误,自定义的错误管理器无法捕捉到它们的原因很明显:错误管理器在脚本里,而现在无法解析脚本,管理器也就无法执行。类似的,E_ERROR表示有致命的运行错误出现,比如内存耗尽。因此脚本会立刻被中断,因为解释器无法执行后面的代码。+ [3 \1 ]( k1 j: p3 H: \

  D# D, \5 h: f8 O9 \9.答案是C。比较操作是一个可交换的操作(就是说结果独立于操作数之外),而赋值不是。因此,比如说,$a==10和10==$a是等效的,而$a=10和10=$a却不是,而且后者会导致一个错误,因为这不是一个合法的操作。确保常量在操作符前面,能保证你不会错误得将比较变成赋值。; A1 d% C/ Z! \2 ?
0 t  j. t/ ?! o+ ]
10.答案是C。error_log函数能将信息送往一个指定的地址。尽管mail()也可以用,但error_log能自动给邮件添加标题,因此这才是最简单的方法。7 U" v% h- W7 p
2 H' y' }$ o3 u
11.答案是不能。error_reporting函数能关闭所有运行时的错误报告,但对解析时的错误无效,因为解析错误发生在脚本执行之前。
) p! w" u5 l0 I$ w3 P: `* x4 n7 V+ @; s. i7 y0 m8 S
12.显然,答案是C。概要分析器(profiler)能监视脚本的运行,并记录单个部分的运行时间。它可以用来找出和解决瓶颈。
; f' Z+ K$ {! w! ^- L7 V( j
( X1 o+ M( f! a( _9 r5 Z13.这是对调试器的完美定义!你可以用调试软件监视脚本运行,同时分析系统资源消耗,从而发现和解决程序缺陷。7 c9 g; L. }3 h& v+ D. K% U6 i
2 q. f( l0 ~9 C
14.trigger_error()和user_error()之间没有区别。后者其实是前者的别名。/ U! J. K0 k5 m3 h

' R( @1 l. E: L  |  a4 `15.答案是D。题目是在描述debug_backtrace函数,它返回一个由所有在代码的特定位置调用过的函数名组成的数组。

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