返回列表 发帖

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

作为一个开发者,无论你经验多么丰富,或者无论你多么努力,你的程序中总会有bug。这是生命中一个必然的部分,如同死亡与缴税(尽管并没有后面两个那么严重)。7 C9 W! {' n4 \! S$ z5 L
要想解决bug,首先要能找到bug。事实上,许多开发者花费了无数小时茫然得盯着代码,只是因为他们没有把程序的容错能力摆在首位。忽略了这个部分,那么期望一个没有bug的程序就是——不可能的。3 R( d. z& V8 ^$ }
本章测试题将考察你对调试和性能管理相关知识的了解,以及如何用PHP做好这两件事。5 f- q& _& p3 b/ r/ u- F( Z

1 N/ _# ^8 S& j* M5 n
& Q  s0 A. Y$ A! |问题
! v4 \! B+ w0 P/ n8 J" F
6 Z7 L1 `( X7 {& \; M1.以下脚本如何用三元操作替代? ! w, \; K+ Y; M5 B9 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. ?>
复制代码
9 j# E# ?" B$ e* Y
A.$x = ($a A. < 10 || $b > 11 || $c == 1 && $d != $c) ? 0 : 1;  f/ C. E: I4 s2 h; d
B.$x = ($a < 10 || $b > 11 || ($c == 1 && $d != $c)) ? 0 : 1;8 n9 }6 V9 \. O1 U( n5 ?
C.$x = (($a < 10 && $b > 11) || ($c == 1 && $d != $c)) ? 0 : 1;
6 N: \; Q5 R( s; t- yD.$x = ($a < 10 && $b > 11 && $c == 1 && $d != $c) ? 1 : 0;" L4 o( t- N/ j' F4 N2 Y( M4 y
E.以上都不对4 q2 H3 E( N* o9 x/ M
9 x9 v# W! m  L6 ?0 f  s

9 |! {0 ~# p# A: J1 {/ L2.有一个脚本由于要从远程获取数据,因而运行速度很慢,以下那种方法能对其进行优化?(双选)) o8 F1 a; k; N; X9 L! P; _7 k0 i
4 {" Q2 W# q" J8 C: W4 u( M
A.安装操作码缓存(opcode cache)( j: w6 L# J! H* e5 x
B.优化或者升级你的网络连接
% S6 i' i/ B+ Q% `( G- O7 [C.添置更多的硬件0 Z) D. y8 m; T7 O
D.增加服务器的可用RAM8 j. G7 W6 d( o- d: e
E.使用连接缓存9 r' z4 U, _6 l: d7 A" O% h) _
  u( T- q( p0 a: t! \' F* E
$ x1 I- Y0 c1 b2 q5 u+ ~
3.架设生产环境下的服务器时,需要做哪些步骤?(双选), H7 e" P7 [9 m# P/ N
& W; Q( e7 _- V4 }! d
A.关闭错误报告
7 j2 [) z1 e8 Z  `) kB.打开错误日志  ~% s+ P  z. @+ S- {! U
C.关闭错误日志
* a5 K$ o' P. V" ^! `( x8 \D.关闭错误显示- X6 _4 c. u# [; |% w" m. K
E.使用@抑错符$ E3 U7 R  e$ D! h4 l

  @+ @# T* M1 q" f
' X- k1 {+ h3 \7 c( @- `5 N4.______操作符能对操作数的数据类型进行严格的比较?% r5 j- B  t) |9 S) y

" C9 t4 J. a% K4 V1 s  d答案:____________
4 _4 K0 V, b4 o0 r. _4 R% \0 x. [9 q
6 M' H& Z6 Z, W8 k/ r+ @. _
0 ?8 |+ p) {& g7 @5.操作码缓存(opcode cache)能做什么?  u# c4 s+ H* f. e$ z

8 Z/ N# |- d- \. p. ]A.把脚本编译成二进制对象,使它运行得更快9 J) l8 T, }4 @" E. I3 B
B.代替Zend引擎加快解释器的运行
- n4 H7 m0 S8 s- b/ Z9 HC.缓存脚本输出以提高执行效率! t$ w2 L% X. N" Y) Y/ t
D.缓存解析器产生的中间码,以提高运行效率" H: d1 l6 h4 W" H0 v0 ?
E.在内存中缓存脚本,减少从硬盘中读取的次数5 t* J) u1 e0 Z2 C/ J6 R. Z! ^) }
# }9 i9 ~3 o8 q" X- F( U: _2 i% Z( ~2 @

6 Q6 Y$ D, Y0 h/ N) C1 n6.以下哪些情况容易造成系统资源枯竭?(双选)0 A4 D  c3 o  w! ~
( F8 g$ q5 y. G3 o& G. E# ]$ D5 Q
A.RAM太小" {, g. `' D9 M, D& O" S# R: q
B.使用了低带宽的连接) T' i. P) b8 V9 r: C5 x8 u
C.虚拟内存超过2GB
' H( `2 O- ?0 pD.允许同时运行太多的服务器进程! [% j. Z7 q# F" Q1 ^! \/ j
E.以上都不对5 d) {% `& s. l; E2 ?) J

- \+ O1 [9 o5 I! a6 L+ i# f4 P* z( ~# P# h/ Z4 m" i5 ]: P" i
7.以下脚本缺了些什么?(双选)
. ?$ v. h& y# P" Q; u% E: V4 f9 _1 p

  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. ?>
复制代码
3 b# _3 a# P" N$ X( L2 Q
A.参数出口(Parameter escapement)
3 u; P. ~' G6 u) }' k, kB.输出格式化/ T9 V/ ]( V& y! F
C.错误检查
* m' c& t* f" |$ n; KD.一个SQL查询+ ]" y1 j8 Z6 X. q/ J* w
E.以上都不对
1 E* M4 T4 U/ n$ e; g$ D& e
; \  c7 ]  {( i6 y/ W6 e/ d" R
2 P/ X: N0 {- v# P% H/ d8.以下那种错误类型无法被自定义的错误处理器捕捉到?(双选)# z' @: i- |% Y, {/ g, R6 j; }

' t( i( d2 L' X3 GA.E_WARNING
. D1 m; w  S) L  F* c; W% X5 tB.E_ERROR
/ s/ L1 Z- u, p" d( F* A: UC.E_USER_ERROR
& Z$ e$ A5 j& t& b7 g2 c- @  aD.E_PARSE# d1 K5 [: d( X3 P: m0 |
E.E_NOTICE
& e8 `# l' e+ \- ]0 ~
6 T8 l: e5 |+ B3 R3 G7 B& L
8 g3 `* b4 Q5 a+ L" T; [9.当需要比较一个常量和一个变量时,如何才能保证不会错弄成赋值?" e1 Z8 v! }: a$ R% Y. ?1 }
; g' H' L) e$ \$ V
A.把变量转换成int9 x' N# f9 L) j% X; @- F5 r7 y
B.使用全等比较符(===)
) Z3 Z# }0 N0 @$ ?9 @! ?0 mC.确保常量是第一个操作数# {8 R5 G0 K0 T+ [5 N+ O( N. a2 I
D.使用三元运算符
* B; Y: P5 V4 m% G- W" y5 Y8 _E.用括号把操作包起来7 q0 b, u% A6 @+ e. e

, q8 S0 l0 A4 O1 u6 a. Q
# i) C9 Y  e4 \3 R1 p10.要通过邮件给系统管理员发送错误信息,以下那种方法最简便?) |; m: A6 I2 Y8 e0 F5 ]

# y, _9 j: G0 a7 QA.创建一个连接远程SMTP服务器的函数1 P) i0 W6 B8 \( ]
B.使用mail函数3 j% e& M2 ]0 f2 P
C.使用error_log函数" q4 ?: S; H5 ]. M* \
D.调用sendmial程序
3 R: |2 t7 |7 }9 }4 b0 SE.使用webservice
9 j( F- Z& z" R; q
( l5 w: @! ^3 s( G- y+ D; b4 F) v! @. t  f
11.能否仅调用一个函数就关闭脚本内所有的错误报告?) d$ z, w1 ^, T& I5 t% l9 @
8 B' h: L  K0 k
A.能
; P1 U7 k% m9 \6 l, i! f1 D' J. M9 iB.不能! B. s' ]8 m8 ^- F# I& s
2 \3 P& F' o" H; {4 p/ A

5 ]2 M1 g' f$ E* Q' ?12.概要分析器(profiler)是做什么的?& ^9 o( A: a  l9 b- d

, ^4 c* r# r8 S) CA.创建关于脚本结构的档案
& [5 {; Y* F/ ?3 V9 MB.把脚本转化成UML图
- |2 }! n! _% }4 {0 R! z( GC.精确测算脚本不同部分的运行时间; H) E5 _; d! f- |8 W1 _4 S
D.计算脚本通过web服务器执行时的维度
4 _& A' }1 d% ?- [) b" IE.扫描脚本,识别由常见错误导致的bug4 n% V9 b6 ~% v% \

2 ?% C; w8 @; n
  F' n1 ~7 |2 \7 I% v13.______能帮助识别和解决bug。
" ~' `) G7 E# {, F1 n5 t$ G) C7 H" |, O6 @0 }1 S* Y9 _
答案:____________9 V0 K4 d6 s9 y

8 t/ l+ ?7 o* d4 W
6 F5 F  f, K, `8 ~% q! U/ T5 I14.trigger_error()和user_error()有什么区别?; ^- }. M/ n) z5 j+ ]2 o/ T3 ^

1 u5 q: r# S3 N( {; V6 IA.trigger_error()允许脚本抛出系统级的错误
; q8 m+ g6 m; d4 x, G% ZB.user_error()允许脚本抛出系统级的错误
" @% X/ O. X. M( ?7 ]' O) ]/ p( ]C.user_error()不能被用在错误管理器中
1 t8 U7 x1 I6 _D.trigger_error只在PHP5中可用) B1 Z# }+ C! G
E.没有区别
# a5 }1 P  L& u; q/ O5 M  w- q
) N* C' I" ~8 D* O% g: W
, a! H' l) u. u9 J- |15.______函数能返回脚本里任意行中调用的函数的名称。该函数同时还经常被用在调试中,用来判断错误是如何发生的。
! `# b! e0 v  |; s8 @" s$ j- E
# l$ x. L. o- C- s) G- F* ^A.print_r
8 t  ^* k. u% ]! IB.var_dump, q$ |2 Y# ?& W2 D" r
C.stack_dump
- X- @; B: r. ID.debug_backtrace
& C) Y& ^& [0 @( |0 iE.以上都不对
2 t  H7 d5 G$ l' u- I( J2 N! q% d& o8 Y- l0 D+ b7 b  A7 x
答案$ w+ A3 ^8 v: p
4 a- L( k  i6 g$ f% S
1.答案是E。三元操作符把每个if语句连到一起,作为&&操作的一部分。然而本题中,$x=1这个赋值只在第三个if为false时发生。如果第一个和第二个条件都不成立,$x=1就不会执行。这题对三元操作的应用有些极端,实际应用时,需要根据可读性来决定是否需要用三元运算符(本题这种情况就最好不要用)。0 i( u% a  @7 i7 F
9 F* y9 |  t! T
2.问题是由第三方数据源传输缓慢导致的,而你无法控制这个数据源。你也许能在网络连通性上做些工作(假设问题出在你这一边)。还可以对接收到的内容进行缓存,这样能减少获取重复数据的时间。因此,答案是B和E。
; \8 Z, I, i' }& Z! X6 I( Q
) \. h5 ?- u$ k) Q, W0 x3.正确的选择是B和D。如果关闭错误报告、使用@抑错符和关闭错误日志,那么在你交付给客户的网站出现问题时,你将很难进行分析和调试。
: O# H; `& y3 ]4 o/ N. K3 {7 C: q5 K* \
4.这是在描述===操作符。
7 X+ I& X" g# K8 J( t4 S# L0 f- R6 w, b3 |5 l- C) m
5.正确答案是D。PHP脚本在执行时,将首先被解析成“中间”码(也叫opcode,操作码),然后解释器执行。操作码缓存出现在这两个步骤之间,对解析器的输出进行缓存。下次执行该脚本时,将缓存的输出直接送入解释器。这样就就不需要再解析一次了。
1 ?; c" V7 }" v) B& L
  t& g& a' e9 c) c! e. I! X/ e  r; j6.正确答案是A和D。如果RAM太小,进程间将出现资源竞争,服务器将大量使用硬盘交换。同样的,如果允许过多进程同时执行,也会使服务器频繁进行交换,导致速度下降。
- d; N1 N- M  j- m# y; o' ]0 W* \8 x6 y& Z; M8 S* d! J
7.正确答案是A和C。脚本不检验datebase_query()的调用是否成功,因此将持续执行下去,最终产生错误。此外,$my_id参数没有转义——可能导致代码注入(详见第11章)。% d8 u4 J& ]- h* _+ H2 x" h4 y( s
* f# G$ ^5 F. D) E- A; _
8.答案B和D正确。出现解析错误往往表示脚本中有语法错误,自定义的错误管理器无法捕捉到它们的原因很明显:错误管理器在脚本里,而现在无法解析脚本,管理器也就无法执行。类似的,E_ERROR表示有致命的运行错误出现,比如内存耗尽。因此脚本会立刻被中断,因为解释器无法执行后面的代码。" N9 M( H! C& f# F3 b' h

& ^6 N; I/ e* x* ~7 J' g9.答案是C。比较操作是一个可交换的操作(就是说结果独立于操作数之外),而赋值不是。因此,比如说,$a==10和10==$a是等效的,而$a=10和10=$a却不是,而且后者会导致一个错误,因为这不是一个合法的操作。确保常量在操作符前面,能保证你不会错误得将比较变成赋值。/ T8 T7 s1 G4 V; Y$ s

, {% \4 \7 X7 h10.答案是C。error_log函数能将信息送往一个指定的地址。尽管mail()也可以用,但error_log能自动给邮件添加标题,因此这才是最简单的方法。
- @7 _: X. ]2 z: r* c% T, k+ Q# X6 y- Y7 M" z2 Q
11.答案是不能。error_reporting函数能关闭所有运行时的错误报告,但对解析时的错误无效,因为解析错误发生在脚本执行之前。
; ?8 j# {% E! _5 ~. B5 P3 b
& d" l+ _4 D! l. |12.显然,答案是C。概要分析器(profiler)能监视脚本的运行,并记录单个部分的运行时间。它可以用来找出和解决瓶颈。
, J8 D0 [# D- F  S; k" Y! U, `) [) w- l6 ~
13.这是对调试器的完美定义!你可以用调试软件监视脚本运行,同时分析系统资源消耗,从而发现和解决程序缺陷。
3 `3 @! o* f4 W, y6 Y% a. f
5 \+ `2 s7 ^. D6 ~1 ]14.trigger_error()和user_error()之间没有区别。后者其实是前者的别名。
* I% G0 w3 b% n1 i& V& v
' @/ Z! c* u  ^( v( f  j15.答案是D。题目是在描述debug_backtrace函数,它返回一个由所有在代码的特定位置调用过的函数名组成的数组。

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