|
  
- UID
- 1
- 帖子
- 738
- 精华
- 28
- 积分
- 14443
- 金币
- 2507
- 威望
- 1647
- 贡献
- 1455
|
[Zend权威认证试题讲解]第十二章 -调试与性能管理
作为一个开发者,无论你经验多么丰富,或者无论你多么努力,你的程序中总会有bug。这是生命中一个必然的部分,如同死亡与缴税(尽管并没有后面两个那么严重)。
7 l+ q/ j2 F+ W3 H. ~要想解决bug,首先要能找到bug。事实上,许多开发者花费了无数小时茫然得盯着代码,只是因为他们没有把程序的容错能力摆在首位。忽略了这个部分,那么期望一个没有bug的程序就是——不可能的。, W' d! z. G9 w$ g+ w
本章测试题将考察你对调试和性能管理相关知识的了解,以及如何用PHP做好这两件事。7 C+ u2 U* l" Y3 D, `
% h% ?. Z3 s1 m2 r+ D3 W
1 H/ w: T. Q& z
问题
* z4 L$ v: }6 W% {) A. U+ m8 P4 b/ n7 l z: |1 Y5 e
1.以下脚本如何用三元操作替代?
0 `: b l8 |% B6 |* H-
- <?php
- if ($a < 10) {
- if ($b > 11) {
- if ($c == 10 && $d != $c) {
- $x = 0;
- } else {
- $x = 1;
- }
- }
- }
- ?>
复制代码
0 l* B. |2 T1 y; d; ZA.$x = ($a A. < 10 || $b > 11 || $c == 1 && $d != $c) ? 0 : 1;: A% e$ z& [0 K3 R
B.$x = ($a < 10 || $b > 11 || ($c == 1 && $d != $c)) ? 0 : 1;
5 ^+ K8 P3 C! T6 rC.$x = (($a < 10 && $b > 11) || ($c == 1 && $d != $c)) ? 0 : 1;: B6 J$ G' j2 r8 Y ^! e) l
D.$x = ($a < 10 && $b > 11 && $c == 1 && $d != $c) ? 1 : 0;1 }: ~, `: L6 X. X: _4 Q' z
E.以上都不对, g9 [4 i6 `5 N$ c3 ?
. M r4 j1 I4 W' s+ T0 Z% k
0 g( r3 Q) z3 y" u2.有一个脚本由于要从远程获取数据,因而运行速度很慢,以下那种方法能对其进行优化?(双选)
) q% `$ O! S+ n6 G; |3 K E. L4 ~' F4 |! t
A.安装操作码缓存(opcode cache)
2 i* J5 s! }" X! ]* F) ~B.优化或者升级你的网络连接+ k. o" L" P2 _$ _3 W/ @
C.添置更多的硬件2 t* J Y: q# f! g' m
D.增加服务器的可用RAM
# n8 v4 k; D/ J9 _( r9 t5 L0 yE.使用连接缓存8 @0 _( f& N1 T+ e4 @1 Q8 S
9 X+ A d# K' f
6 N- _# u' F1 b/ r* b# O
3.架设生产环境下的服务器时,需要做哪些步骤?(双选)! r8 X* Z9 U2 d: |* a
6 T6 {% t! f! i4 u* E' P
A.关闭错误报告
2 F; l% n4 N% uB.打开错误日志' K; [) Y+ F' d, c8 b% O
C.关闭错误日志8 S5 ^2 y5 z6 @1 G
D.关闭错误显示
1 I8 G# f* n0 h/ [/ O) s( ?4 _9 JE.使用@抑错符
8 h% X! d/ W8 M, b a9 N, L) A. @1 H3 X. D/ W
1 G; `" T, ~: G# T' T: R7 F
4.______操作符能对操作数的数据类型进行严格的比较?( i( u: @3 f8 P/ f8 b5 c3 B
$ Z( p2 l- E7 q4 u8 l# `4 `& K答案:____________; t: e8 f; u; C+ X9 b/ D' o8 c
S/ s3 `( e, J1 n
: S6 z; j" k+ ]# q5 N+ H
5.操作码缓存(opcode cache)能做什么?8 k% O5 K {2 K+ |5 T+ i
# h# R$ V! Y, t( p# a: `A.把脚本编译成二进制对象,使它运行得更快9 H7 J0 V. D' n6 t
B.代替Zend引擎加快解释器的运行
5 t* t: b0 ^5 Y1 ~! i& pC.缓存脚本输出以提高执行效率4 b; N) ~4 _, t. u
D.缓存解析器产生的中间码,以提高运行效率) C7 G, \" Q3 d. X9 n' A
E.在内存中缓存脚本,减少从硬盘中读取的次数
: K1 @' m" f) P( X7 G% p" S: J2 [* z- L3 l& y
- _9 c' g" x! K! V8 t, b. [" V% b6.以下哪些情况容易造成系统资源枯竭?(双选)' i& H9 @2 y: q' @; F
) \% e( ?' b+ iA.RAM太小
Z+ h/ Z" P0 ?/ ZB.使用了低带宽的连接
' S7 Z# E/ s' bC.虚拟内存超过2GB
2 f8 h- H8 x7 AD.允许同时运行太多的服务器进程4 c# Z+ }* m1 k: P
E.以上都不对: E+ p$ ]1 i; a% e
) T; G8 r" V ?
* S+ Y% Z8 K2 J6 \; X7.以下脚本缺了些什么?(双选) - o' L* z6 ^, e; j. d: h- {
-
- <?php
- $rs = database_query ("select * from mytable where id = " .
- $my_id);
- while ($a = database_get_data ($rs)) {
- var_dump ($a);
- }
- ?>
复制代码
, v8 f# @* a& n) s- aA.参数出口(Parameter escapement)+ p, L- ]( r: S5 X8 R. Z
B.输出格式化( Y3 E) |. p( E/ b3 J
C.错误检查. P6 r( }8 o6 t, R( }: p3 [
D.一个SQL查询8 d4 V. x; m8 \ z6 j
E.以上都不对
$ U: u& j" s; [0 h) F2 O; v9 y, I1 v7 v# b. h. }
5 |. {% T* N: T! A" o: {/ y8.以下那种错误类型无法被自定义的错误处理器捕捉到?(双选)& }# G5 Z$ n! U. Z% M
7 P$ K8 s) P' X( T' I
A.E_WARNING
! Z+ y) z P1 d9 @. c0 ~: RB.E_ERROR
/ W" G2 W7 G1 d* n0 l2 C5 F2 ZC.E_USER_ERROR
: o; L7 [% z. W) x- JD.E_PARSE
2 p7 {- O7 S6 X# D1 oE.E_NOTICE. w8 {+ ~/ l( G# w3 }9 z# @
9 r5 a$ D+ L% Z7 s& y) M7 n
4 |3 N7 w+ |$ D7 I9.当需要比较一个常量和一个变量时,如何才能保证不会错弄成赋值?
$ y$ O% o/ P! S7 y% u
( _( s; a* u7 } m! X. @& b( x2 `A.把变量转换成int
% f3 g/ P" Y% x1 t& WB.使用全等比较符(===)
0 i: ~ Z- S6 ^, C, Y1 e, q+ w' VC.确保常量是第一个操作数6 }+ m. G% E: f! D3 g K6 ~
D.使用三元运算符
& c' p$ P' X* s0 J1 E1 pE.用括号把操作包起来
# L4 X/ D9 p2 j. ~ u9 Q
- K# }) G& v; T+ F# {/ y1 e5 f- b# ]/ G
10.要通过邮件给系统管理员发送错误信息,以下那种方法最简便?5 w' E/ A4 H! A3 H% |
+ |; B* g, z+ ]A.创建一个连接远程SMTP服务器的函数. y2 P7 k: h) f3 ?' ?+ |
B.使用mail函数
* Z- Z, ]/ }: J2 K" \C.使用error_log函数
) O" \" \! A1 o4 y, KD.调用sendmial程序 v2 b$ ]) m8 z7 O
E.使用webservice. ?; l. J4 N* b; E V1 }# k
7 c: p$ Q5 _) m' y0 e% m* Y
L }3 s7 w8 u- t
11.能否仅调用一个函数就关闭脚本内所有的错误报告?
, C3 R2 R" I- O* v
$ f4 F. y6 V/ C! GA.能
& W' m+ U/ S6 k Y4 C5 F# FB.不能. o5 y- v% U0 b
" K3 x- |( h8 }: q# y8 i& E) x, R4 ~
12.概要分析器(profiler)是做什么的? s9 ~. }7 a6 ^# {8 d7 ]
7 }9 Q% V2 S# v7 M& O! EA.创建关于脚本结构的档案1 K6 s: O0 V" `4 X- r2 z- O' D- f0 C7 |
B.把脚本转化成UML图9 g4 m. G- W3 M" o/ _9 N
C.精确测算脚本不同部分的运行时间% g6 w: t5 |3 w" ^' [( }' b+ H
D.计算脚本通过web服务器执行时的维度* r0 b+ ^8 L; f
E.扫描脚本,识别由常见错误导致的bug0 W& q, X* ^ j
v9 O* @4 {$ B" j6 c- u" ~% {: l" v9 l1 \/ e2 `
13.______能帮助识别和解决bug。4 u" E$ V8 L, I/ K6 T7 R3 j
. \" @6 \( i. B1 I答案:____________
. @ M! M! Q% x6 O2 }) @3 w' s' ]; n. D& {* B4 b, a6 e4 W% K$ p* L1 a
+ ]8 _9 J: C2 G6 F& @& r; }3 P. w
14.trigger_error()和user_error()有什么区别?
4 q% z+ E" l+ j s
3 {3 Q7 c" \& SA.trigger_error()允许脚本抛出系统级的错误0 H2 i2 Q& k+ L
B.user_error()允许脚本抛出系统级的错误% L/ T0 {! U$ a' _! v4 V% v
C.user_error()不能被用在错误管理器中" e/ S7 c4 r7 g! k) H0 ^" a
D.trigger_error只在PHP5中可用- q, J' Z m3 a: ^1 t
E.没有区别. m3 X3 b% c2 M0 t
' v7 N# i( L, U8 C+ R+ }3 T# U6 p% F* }9 X% L
15.______函数能返回脚本里任意行中调用的函数的名称。该函数同时还经常被用在调试中,用来判断错误是如何发生的。! l5 L( V2 x# [8 t& I* N0 { ?
6 `" {. v( [8 t' }# L' {% k3 b
A.print_r% K# K0 K1 t4 c$ B+ A
B.var_dump
" V2 s" f0 d# ~: ~9 xC.stack_dump. \5 v8 F: i0 }1 r: S
D.debug_backtrace
/ w/ X" U. J6 H8 X$ W8 ^E.以上都不对& ]+ Z& k) z) j0 {$ [9 I
. s9 ~+ N$ O5 ~1 ?
答案# i. [' b! K% {3 T- l9 Z( g( p
; K$ M" g# k) r6 \" V) x9 ?
1.答案是E。三元操作符把每个if语句连到一起,作为&&操作的一部分。然而本题中,$x=1这个赋值只在第三个if为false时发生。如果第一个和第二个条件都不成立,$x=1就不会执行。这题对三元操作的应用有些极端,实际应用时,需要根据可读性来决定是否需要用三元运算符(本题这种情况就最好不要用)。7 D# e' ^: c6 r- L8 X
* j8 A8 s, j0 U2 C# C- g% N
2.问题是由第三方数据源传输缓慢导致的,而你无法控制这个数据源。你也许能在网络连通性上做些工作(假设问题出在你这一边)。还可以对接收到的内容进行缓存,这样能减少获取重复数据的时间。因此,答案是B和E。
! L: D8 o/ ]. v. t) }% Q$ s! p0 t
3.正确的选择是B和D。如果关闭错误报告、使用@抑错符和关闭错误日志,那么在你交付给客户的网站出现问题时,你将很难进行分析和调试。) @& m3 m1 b* N9 V. y" y/ Y! y7 s
5 c" X# G8 H6 g
4.这是在描述===操作符。
, L) E7 z! w5 j& V( @- W) e. G6 i( v4 n
5.正确答案是D。PHP脚本在执行时,将首先被解析成“中间”码(也叫opcode,操作码),然后解释器执行。操作码缓存出现在这两个步骤之间,对解析器的输出进行缓存。下次执行该脚本时,将缓存的输出直接送入解释器。这样就就不需要再解析一次了。
8 p* W' M+ G( ~0 ?, f1 ^, U. ~$ t' e. @0 ~) e4 j; P( V
6.正确答案是A和D。如果RAM太小,进程间将出现资源竞争,服务器将大量使用硬盘交换。同样的,如果允许过多进程同时执行,也会使服务器频繁进行交换,导致速度下降。3 s/ j9 r, I; G2 W4 p8 j
, y7 c4 t6 i2 K9 j ]5 J7 r1 f
7.正确答案是A和C。脚本不检验datebase_query()的调用是否成功,因此将持续执行下去,最终产生错误。此外,$my_id参数没有转义——可能导致代码注入(详见第11章)。1 ] @5 l/ q! Y4 w* {
5 I. X& t5 E; d. p# O5 @2 B
8.答案B和D正确。出现解析错误往往表示脚本中有语法错误,自定义的错误管理器无法捕捉到它们的原因很明显:错误管理器在脚本里,而现在无法解析脚本,管理器也就无法执行。类似的,E_ERROR表示有致命的运行错误出现,比如内存耗尽。因此脚本会立刻被中断,因为解释器无法执行后面的代码。" y: v; `7 x$ @, N4 X8 g4 l+ Q
* u S3 W+ T k; w; k9.答案是C。比较操作是一个可交换的操作(就是说结果独立于操作数之外),而赋值不是。因此,比如说,$a==10和10==$a是等效的,而$a=10和10=$a却不是,而且后者会导致一个错误,因为这不是一个合法的操作。确保常量在操作符前面,能保证你不会错误得将比较变成赋值。! c/ O0 c# x% b% e0 m& k
+ T ~* n6 l$ K: O
10.答案是C。error_log函数能将信息送往一个指定的地址。尽管mail()也可以用,但error_log能自动给邮件添加标题,因此这才是最简单的方法。
) R' Z8 R3 x2 p, N" B. ?0 D0 e' F: T. P: X
11.答案是不能。error_reporting函数能关闭所有运行时的错误报告,但对解析时的错误无效,因为解析错误发生在脚本执行之前。
" x: d1 ^ C1 Z' y: m E; D( P+ V! ?% f" [7 y" V
12.显然,答案是C。概要分析器(profiler)能监视脚本的运行,并记录单个部分的运行时间。它可以用来找出和解决瓶颈。5 [0 u1 x! ^0 x; E6 b
* Y, N8 x1 z1 b" l" U8 g/ m13.这是对调试器的完美定义!你可以用调试软件监视脚本运行,同时分析系统资源消耗,从而发现和解决程序缺陷。
: k$ j, j+ J! j
0 D. n, h: d# C! G, r14.trigger_error()和user_error()之间没有区别。后者其实是前者的别名。
. A* Q8 K7 [, \" k/ c) U$ l6 h N
. P+ F) y9 B) k' C5 E15.答案是D。题目是在描述debug_backtrace函数,它返回一个由所有在代码的特定位置调用过的函数名组成的数组。 |
|