|
  
- UID
- 1
- 帖子
- 738
- 精华
- 28
- 积分
- 14321
- 金币
- 2446
- 威望
- 1647
- 贡献
- 1394
|
[Zend权威认证试题讲解]第十二章 -调试与性能管理
作为一个开发者,无论你经验多么丰富,或者无论你多么努力,你的程序中总会有bug。这是生命中一个必然的部分,如同死亡与缴税(尽管并没有后面两个那么严重)。
+ V4 H: I- H3 G8 I$ y要想解决bug,首先要能找到bug。事实上,许多开发者花费了无数小时茫然得盯着代码,只是因为他们没有把程序的容错能力摆在首位。忽略了这个部分,那么期望一个没有bug的程序就是——不可能的。
! B& Y0 R( D9 H- e$ n- X本章测试题将考察你对调试和性能管理相关知识的了解,以及如何用PHP做好这两件事。0 C& L0 `1 y) Y9 H# F
; \3 t3 w6 t2 i0 q( z, }! P- Y% C$ j' p6 g5 j
问题
5 p ^5 L' V6 w8 W# R
+ A3 a" k) p, [3 ]1.以下脚本如何用三元操作替代?
8 x4 @" \0 I- ~5 j-
- <?php
- if ($a < 10) {
- if ($b > 11) {
- if ($c == 10 && $d != $c) {
- $x = 0;
- } else {
- $x = 1;
- }
- }
- }
- ?>
复制代码
0 |$ W2 p/ ?8 G9 N, s- ]: {& mA.$x = ($a A. < 10 || $b > 11 || $c == 1 && $d != $c) ? 0 : 1;3 u& Y' k$ P. ?: r9 N
B.$x = ($a < 10 || $b > 11 || ($c == 1 && $d != $c)) ? 0 : 1;
@8 h X: E, a3 p! gC.$x = (($a < 10 && $b > 11) || ($c == 1 && $d != $c)) ? 0 : 1;! r3 W/ i y5 X$ ? v
D.$x = ($a < 10 && $b > 11 && $c == 1 && $d != $c) ? 1 : 0;
: V0 o0 j8 C9 wE.以上都不对2 Z1 @/ F, D& x9 C4 l" z0 H
+ G A, w4 O+ W" C( X+ i1 H5 x4 G0 \# K. C g; d
2.有一个脚本由于要从远程获取数据,因而运行速度很慢,以下那种方法能对其进行优化?(双选)
# d w1 s' d5 F
& R" o3 v% n5 Z) {, e3 N9 dA.安装操作码缓存(opcode cache)9 Y% u" ^+ E2 w$ G4 s
B.优化或者升级你的网络连接- l! w6 p0 E) y( J
C.添置更多的硬件
3 T) c2 e* ^$ f( P9 ], |- dD.增加服务器的可用RAM
* |* b4 ~0 r( xE.使用连接缓存/ P* M7 j( T {& O
6 y/ |% u$ |: l
9 ~" C: A" X/ R- m7 L y! l3.架设生产环境下的服务器时,需要做哪些步骤?(双选)
" w" K- O# c* Q. {( A- d3 q: `0 q/ x- m+ o! k }+ [
A.关闭错误报告
' U) N$ Y) J$ L' g0 k: KB.打开错误日志
( i& @- C- E) |# D q e- @+ _C.关闭错误日志
6 y- b I" d3 I( v0 ?: x) A) P% KD.关闭错误显示
. {: k" w; x2 R& S- y& v. D: WE.使用@抑错符+ |0 X2 U+ F0 c2 o+ R0 U! ?
3 U; s8 y, {% Z5 ?, K. F$ E/ L2 a* w, Y9 j# a
4.______操作符能对操作数的数据类型进行严格的比较?
8 c+ B' [$ n& \( S+ m# P
2 T, V+ Z! k" Z4 ?2 s答案:____________
2 w- [0 \/ ` ?3 l5 a {/ y; E; X8 X8 N: ]8 H
, a6 n* j, l' y) }) b
5.操作码缓存(opcode cache)能做什么?, u6 ?( _! N d( s
& Z4 }- m( y( v* l2 tA.把脚本编译成二进制对象,使它运行得更快
* p8 E. X3 {0 {9 b2 hB.代替Zend引擎加快解释器的运行/ O) u9 O% q2 F) Y
C.缓存脚本输出以提高执行效率
0 C) W; U( O6 X) z( g. L7 @& f1 VD.缓存解析器产生的中间码,以提高运行效率1 |+ l3 G. ^& X8 M: K1 X
E.在内存中缓存脚本,减少从硬盘中读取的次数
0 {( C8 Z) F$ Q0 H5 J- h: X
* z: j- \1 C6 b ` Q$ t% x( n$ x7 g* n0 g
6.以下哪些情况容易造成系统资源枯竭?(双选)
; I! \: x! |7 l& k# C: P. x
# Q" x' a8 M$ m/ a# X( U8 LA.RAM太小
/ J. S) V- Z* @ e8 b: w4 X' PB.使用了低带宽的连接
3 M1 c$ X" A, Y. G/ P5 bC.虚拟内存超过2GB
# U/ ]9 I4 e* RD.允许同时运行太多的服务器进程/ V) K& d" B0 a* N7 t/ g5 A
E.以上都不对' o' z# Q, a: A) U; d
# {: b- n# H0 n' t% Q4 C
' T; x3 _8 J) j3 J: W7.以下脚本缺了些什么?(双选) ! e1 U) k! x q- P
-
- <?php
- $rs = database_query ("select * from mytable where id = " .
- $my_id);
- while ($a = database_get_data ($rs)) {
- var_dump ($a);
- }
- ?>
复制代码 ) g: z! r: b' P$ ?7 U. x
A.参数出口(Parameter escapement)
3 O. k* z4 a; b5 qB.输出格式化
* ~! r# ^* H1 \' o7 nC.错误检查
$ I5 P0 A# m; _1 v1 Z$ H2 c+ LD.一个SQL查询
( {1 u# ^; R# T% k2 PE.以上都不对
+ x, w& ^! Z+ Y j, `% \6 o# N# S8 d/ ~$ K. [/ H* {
* Y& N/ ?+ P) W3 L) A" l, y
8.以下那种错误类型无法被自定义的错误处理器捕捉到?(双选)
( X* D' d1 x- G: d. V
! A) m7 k' J6 Y/ kA.E_WARNING
. l4 t$ d4 }. _$ MB.E_ERROR3 g! H2 N! {7 z3 w* N1 [ Q
C.E_USER_ERROR
4 M$ a) v) `& r+ B |. GD.E_PARSE
9 X! d& d* S/ S7 e) DE.E_NOTICE& o9 j6 e8 J1 S' _; Q x; x" x/ m h
9 X7 G! f/ ~; v: c- j0 E" z# f/ M6 A9 b3 q' ^
9.当需要比较一个常量和一个变量时,如何才能保证不会错弄成赋值?8 P2 F. _! W; N$ S0 `/ A
1 u4 Y7 F7 u) N. ? g" _, A
A.把变量转换成int1 ]5 v7 Z! P- M& C
B.使用全等比较符(===)
1 J* z2 E0 m6 _, y( JC.确保常量是第一个操作数) g8 p9 B( p) w5 m
D.使用三元运算符3 l- T/ \! K# S8 E
E.用括号把操作包起来
! L) d3 n1 z4 v: n5 e
2 H) `. k: r6 o4 T& P
* ~7 T0 w+ T$ ]- Q3 P# T10.要通过邮件给系统管理员发送错误信息,以下那种方法最简便?: p6 F. x% I$ P) f- p) Z+ o8 F
6 u$ T/ K7 ?0 i" UA.创建一个连接远程SMTP服务器的函数
$ N0 V- _2 b/ Z" F2 M9 k& L$ E9 }B.使用mail函数. t- X. U& Q. W O" ^( S
C.使用error_log函数. D% ?% {) |# _, o
D.调用sendmial程序! Z" ?6 |& H e+ O9 x% v( r
E.使用webservice5 E* X. U9 A0 k% T# l
2 j; B' O% v3 N) o( ~2 }
' L3 w* K2 {: P11.能否仅调用一个函数就关闭脚本内所有的错误报告?* c) G& d/ A( d
8 [' j2 V2 p; d) ~9 W% M
A.能
. s8 k2 n& @ ?# P) @) Y; |B.不能
# R! p; T% E8 d P2 n3 @: N g- l' @, d+ j/ y6 {; A. c! k' G7 o
" `: [- q. I+ Y12.概要分析器(profiler)是做什么的?$ l& c/ x/ {' a# G2 _- r
2 T9 W; T4 P- M1 s/ x" n4 v/ ^
A.创建关于脚本结构的档案
$ z3 V* c, d. m* LB.把脚本转化成UML图8 p% r% _& g( G/ _& V$ s* e, [
C.精确测算脚本不同部分的运行时间8 Y" Z3 ^) T% r% s" G) v$ C
D.计算脚本通过web服务器执行时的维度
/ K7 y8 K5 t- A& p' F$ i% P6 ?E.扫描脚本,识别由常见错误导致的bug
/ c4 a7 F$ m+ X' Y# p- Q$ h3 i
# v- V* R( \ b+ Y0 `# x0 F, Q: w. e$ R( w: B
13.______能帮助识别和解决bug。 ^* q" `( s8 T1 S
3 Q3 w) W% w9 ^+ M( {答案:____________. a: f' w" ^( u6 T7 ?
! j" I1 w% V/ b+ Z$ w
& C2 k! K2 q2 R; Q6 O: y14.trigger_error()和user_error()有什么区别?5 I8 d- E d2 X- t" l& P
8 N$ M; B: r1 o+ jA.trigger_error()允许脚本抛出系统级的错误
- r7 `- }* d6 E b# t: y9 @; Y( tB.user_error()允许脚本抛出系统级的错误: o; M' k: V8 M
C.user_error()不能被用在错误管理器中0 o/ K; }4 a4 I6 Z/ B
D.trigger_error只在PHP5中可用
! x/ N" C6 t! Z1 QE.没有区别# Y- A7 T; S- i) M+ O9 M0 n+ }
5 ]- |, u9 R! i( A& ~* ?! i% |1 T* ]& \9 w$ p: D3 ?( m* F
15.______函数能返回脚本里任意行中调用的函数的名称。该函数同时还经常被用在调试中,用来判断错误是如何发生的。, k) t$ \* R1 Z
R7 Y$ P' `+ d! F3 u0 ?
A.print_r$ ?7 v# M [% C# |* x' `6 d9 Z
B.var_dump
! S* i3 `" A, l7 n( _/ O9 z/ EC.stack_dump. Q9 I( T- }' K# ] b# x# n
D.debug_backtrace9 c$ N) R) t" l& k8 w, K
E.以上都不对& Q+ v# K: e. L6 f
( H9 u& K' v% } G
答案
1 h3 [. ?6 N- f" o+ a- l6 @! Q9 r- o* B) v X: A4 o
1.答案是E。三元操作符把每个if语句连到一起,作为&&操作的一部分。然而本题中,$x=1这个赋值只在第三个if为false时发生。如果第一个和第二个条件都不成立,$x=1就不会执行。这题对三元操作的应用有些极端,实际应用时,需要根据可读性来决定是否需要用三元运算符(本题这种情况就最好不要用)。" O/ x. w: q8 @- `, j. }
( E& \, M/ x, [( Y# X2 e
2.问题是由第三方数据源传输缓慢导致的,而你无法控制这个数据源。你也许能在网络连通性上做些工作(假设问题出在你这一边)。还可以对接收到的内容进行缓存,这样能减少获取重复数据的时间。因此,答案是B和E。6 n k+ K1 E5 @+ E3 g8 K# {4 X0 b
3 f6 L" O* X' r4 S+ u3.正确的选择是B和D。如果关闭错误报告、使用@抑错符和关闭错误日志,那么在你交付给客户的网站出现问题时,你将很难进行分析和调试。$ }& Q5 `. }) i
- Z* ^: u$ t4 Y1 c8 n; W4.这是在描述===操作符。
6 y0 |7 k3 V5 w5 X6 B. ]8 s' p& k7 X% `+ l- ~0 V, ?
5.正确答案是D。PHP脚本在执行时,将首先被解析成“中间”码(也叫opcode,操作码),然后解释器执行。操作码缓存出现在这两个步骤之间,对解析器的输出进行缓存。下次执行该脚本时,将缓存的输出直接送入解释器。这样就就不需要再解析一次了。) M8 P8 w4 k$ n+ z, @& `- D2 r6 D
& u8 b; n, X( h2 I- P) S$ p
6.正确答案是A和D。如果RAM太小,进程间将出现资源竞争,服务器将大量使用硬盘交换。同样的,如果允许过多进程同时执行,也会使服务器频繁进行交换,导致速度下降。
( o5 G) u8 r2 Y9 M6 ~8 r: ?+ h+ A: j# s3 ~; b2 C
7.正确答案是A和C。脚本不检验datebase_query()的调用是否成功,因此将持续执行下去,最终产生错误。此外,$my_id参数没有转义——可能导致代码注入(详见第11章)。
' m! f* z# l6 x `: |9 U, V4 L/ \; B* k4 j) ?7 @6 H; ]
8.答案B和D正确。出现解析错误往往表示脚本中有语法错误,自定义的错误管理器无法捕捉到它们的原因很明显:错误管理器在脚本里,而现在无法解析脚本,管理器也就无法执行。类似的,E_ERROR表示有致命的运行错误出现,比如内存耗尽。因此脚本会立刻被中断,因为解释器无法执行后面的代码。
2 U$ \5 \$ @# e) j: E7 L' z3 r% b, Y7 C' }4 m
9.答案是C。比较操作是一个可交换的操作(就是说结果独立于操作数之外),而赋值不是。因此,比如说,$a==10和10==$a是等效的,而$a=10和10=$a却不是,而且后者会导致一个错误,因为这不是一个合法的操作。确保常量在操作符前面,能保证你不会错误得将比较变成赋值。# Y) k" L" w2 V* {0 I/ P
& a! J0 y" j: h5 e; M% u10.答案是C。error_log函数能将信息送往一个指定的地址。尽管mail()也可以用,但error_log能自动给邮件添加标题,因此这才是最简单的方法。
! u3 _6 b) L6 y! Y: B9 ^6 i q- w5 R2 k3 N) y
11.答案是不能。error_reporting函数能关闭所有运行时的错误报告,但对解析时的错误无效,因为解析错误发生在脚本执行之前。0 r6 z6 C v! K: h9 c
7 V$ q1 ^- Q$ g) ^
12.显然,答案是C。概要分析器(profiler)能监视脚本的运行,并记录单个部分的运行时间。它可以用来找出和解决瓶颈。" i9 h1 @$ ~9 x; V( ?( y8 [
2 m7 e3 M* O* ^6 j8 x13.这是对调试器的完美定义!你可以用调试软件监视脚本运行,同时分析系统资源消耗,从而发现和解决程序缺陷。
" M$ }0 u$ H6 D
" {& ]5 a( I3 E6 Z; C& v* I; j14.trigger_error()和user_error()之间没有区别。后者其实是前者的别名。
- W X9 P; j* e6 y, v( k6 g# h, J( d
15.答案是D。题目是在描述debug_backtrace函数,它返回一个由所有在代码的特定位置调用过的函数名组成的数组。 |
|