|
  
- UID
- 1
- 帖子
- 738
- 精华
- 28
- 积分
- 14443
- 金币
- 2507
- 威望
- 1647
- 贡献
- 1455
|
[Zend权威认证试题讲解]第十二章 -调试与性能管理
作为一个开发者,无论你经验多么丰富,或者无论你多么努力,你的程序中总会有bug。这是生命中一个必然的部分,如同死亡与缴税(尽管并没有后面两个那么严重)。
& y7 Z4 y) U! k- u/ a6 z+ |要想解决bug,首先要能找到bug。事实上,许多开发者花费了无数小时茫然得盯着代码,只是因为他们没有把程序的容错能力摆在首位。忽略了这个部分,那么期望一个没有bug的程序就是——不可能的。
$ T' t; N; q2 m8 Y本章测试题将考察你对调试和性能管理相关知识的了解,以及如何用PHP做好这两件事。% { d" I; |3 G P, \, ]* d
" @/ V3 r; ~" I* [6 Z
; I! r* P8 S3 L8 L问题0 R/ m5 p* m8 c9 M* C# g" N
, y0 N' G: L& p1.以下脚本如何用三元操作替代?
" j8 f0 L( t% t- R-
- <?php
- if ($a < 10) {
- if ($b > 11) {
- if ($c == 10 && $d != $c) {
- $x = 0;
- } else {
- $x = 1;
- }
- }
- }
- ?>
复制代码
9 M- \' p/ r2 ^A.$x = ($a A. < 10 || $b > 11 || $c == 1 && $d != $c) ? 0 : 1;4 ?1 M& Y/ s# P% k V2 t
B.$x = ($a < 10 || $b > 11 || ($c == 1 && $d != $c)) ? 0 : 1;
7 y I3 y( f; \: P; }' l' P) z% LC.$x = (($a < 10 && $b > 11) || ($c == 1 && $d != $c)) ? 0 : 1;
+ x) U' r% |" j! @D.$x = ($a < 10 && $b > 11 && $c == 1 && $d != $c) ? 1 : 0;
' f5 M4 ^" e* w8 l. Z. zE.以上都不对
3 V; C V+ ?6 @0 d. s* b/ e) L" Y2 w" z* ]! K; r
3 Q4 g. j) J: `
2.有一个脚本由于要从远程获取数据,因而运行速度很慢,以下那种方法能对其进行优化?(双选)
( H2 k. H1 k4 G+ e* ]( ^2 M Q# L7 c1 v. r
A.安装操作码缓存(opcode cache)
9 t- I1 \" K. M4 b9 B( ~% mB.优化或者升级你的网络连接7 X! U- f1 z) n3 D4 @" p7 q
C.添置更多的硬件2 j8 ^& D4 Y4 N9 q9 u
D.增加服务器的可用RAM
- E) ^$ f1 o6 j! @. WE.使用连接缓存, W! f' r, d/ V z2 a2 X* q" c3 w5 s
8 e$ H) C' f9 q& s) E/ p$ H# ~
: L3 G: l: O( h& f; ?3.架设生产环境下的服务器时,需要做哪些步骤?(双选)1 f, M' Z' S i' P; W
1 `0 T1 Y% [* GA.关闭错误报告5 i6 B- Y+ ]4 d0 `4 k) \0 b3 W
B.打开错误日志
, h$ V# Q( {/ cC.关闭错误日志9 H* |- `- q. ]7 t( f; V9 D2 ~* s
D.关闭错误显示
' h" |5 K/ A, e3 P% IE.使用@抑错符5 N0 Z# o* ~4 Q! `# I1 \2 n! E
; I7 j0 _1 r9 M( o( O1 h
# a/ @: @7 e3 \9 z6 g* } r$ `
4.______操作符能对操作数的数据类型进行严格的比较?
& H o8 u7 ]" W) M7 w7 i" [9 |- e1 b. R6 L C6 ?- T# H
答案:____________6 H5 t, b1 R [, o
! T/ T5 t4 q* X5 y' F, A: Z
' ` S% \; Y6 Z. X7 B7 R z
5.操作码缓存(opcode cache)能做什么? M( {8 W5 R+ q+ G. i2 X/ X
/ |3 T+ g. I) Y' [; E
A.把脚本编译成二进制对象,使它运行得更快5 K- {4 n6 Y9 S3 a9 J
B.代替Zend引擎加快解释器的运行$ H: L" T. o, K5 ~
C.缓存脚本输出以提高执行效率
6 i2 q# v: a5 [* x2 Y" LD.缓存解析器产生的中间码,以提高运行效率, t! y. q3 i& ?0 @' u+ W. S
E.在内存中缓存脚本,减少从硬盘中读取的次数3 k( ?2 m, _7 Q
! q2 |2 W- N8 d1 H' W5 P8 j4 p5 \. F' W% b
6.以下哪些情况容易造成系统资源枯竭?(双选)
; B0 f/ M4 Q/ ^
9 F' J; P$ o+ f; u& \2 _A.RAM太小7 P5 J3 r6 S" O& M
B.使用了低带宽的连接
, Y! I# ^( l; ]/ G: d* N9 oC.虚拟内存超过2GB
$ ?2 Z2 I6 j9 v$ a. m* K+ ^. mD.允许同时运行太多的服务器进程) m) T! c. N9 m8 N( S1 U
E.以上都不对+ e f* V+ }, R$ e
! }/ [% W" I1 G5 L+ @% H& f8 u/ S) E7 h1 k; r* E
7.以下脚本缺了些什么?(双选)
) I3 f& z+ x, I0 j: `2 u7 @- b-
- <?php
- $rs = database_query ("select * from mytable where id = " .
- $my_id);
- while ($a = database_get_data ($rs)) {
- var_dump ($a);
- }
- ?>
复制代码 * E* A$ t* k; z7 l1 t* I' ~5 x
A.参数出口(Parameter escapement)
4 I2 o3 | D6 U; b, i# lB.输出格式化# k$ V" z% N# @# y
C.错误检查
! [ G$ T% A" [) n `9 SD.一个SQL查询
2 |% a; Q+ j. C& f7 Z( k; w1 ]/ cE.以上都不对
8 x" a4 ?9 d6 N1 ^
8 k3 Z' C* R8 K) b- g8 P$ k( Y# ^6 a N6 F; Y' A; G- ]
8.以下那种错误类型无法被自定义的错误处理器捕捉到?(双选)
: P7 J7 c; M6 ^6 j: S$ [5 K9 r' Y& q# ^: N
A.E_WARNING) `/ ?2 A l7 Q; S" q7 z
B.E_ERROR( ?; d! N) ^7 n* J- O
C.E_USER_ERROR
9 H, _4 l/ {# K+ u! MD.E_PARSE
( P; X, _, I6 B! P# dE.E_NOTICE) N! e* \ a+ w
/ X2 R% |1 D% b8 X7 l$ y: o D- n$ m9 O8 G' l% G+ W3 D% v
9.当需要比较一个常量和一个变量时,如何才能保证不会错弄成赋值?
- Y3 ?7 E4 K% t
' L- e& X& t8 d* L( {A.把变量转换成int& \& G# v! L- K) X
B.使用全等比较符(===)
. h3 Z! l6 P9 n1 Y! v6 j/ eC.确保常量是第一个操作数
7 E9 T8 ?& p6 o- F7 Q0 a# W/ hD.使用三元运算符2 B: |# A# I2 a7 B* V( S$ \
E.用括号把操作包起来
" ^& i' e: F/ w4 D- E5 z: V, d& G9 x" l) }2 c
& x/ I. C6 [/ g8 V" w10.要通过邮件给系统管理员发送错误信息,以下那种方法最简便?
: B, [7 I/ |4 p5 e3 [- J# ^2 ?4 N# d6 L* I/ j* ]
A.创建一个连接远程SMTP服务器的函数4 X3 h9 Y6 w/ _4 ^2 z! B% \
B.使用mail函数 A9 ~+ I o' y$ b0 X
C.使用error_log函数
; `7 ]) l: u0 A6 JD.调用sendmial程序" x0 x- }0 F6 q$ o% [
E.使用webservice& d, X( V4 c2 s7 G3 `
" f- \( @+ H1 a/ s
% c% t |( l3 N9 a- |11.能否仅调用一个函数就关闭脚本内所有的错误报告?% M) [2 i \: s8 V- r7 Y
- `) n3 | h) e8 q8 [A.能$ A; F8 U, k; I
B.不能
: v! C/ ^ \6 g+ O3 ?
9 `$ y& K- Y% f4 I9 D
% a7 Z- R0 g2 Z3 U) {1 B/ m12.概要分析器(profiler)是做什么的?) E3 ?5 }0 V- V+ x6 g! a6 `3 G
" I% H1 @* s9 g$ n# QA.创建关于脚本结构的档案
! s5 g9 B3 p) O! N) R! oB.把脚本转化成UML图
9 b4 u! `8 _. n& E3 @7 H' V/ `C.精确测算脚本不同部分的运行时间8 F( `3 ^( q+ G7 k) O$ i: J
D.计算脚本通过web服务器执行时的维度
i6 Q2 o- |! Y4 @E.扫描脚本,识别由常见错误导致的bug
% d% q1 h8 R F; |; e0 h# X% P' q7 x: }
* E1 H. N x: ^6 l# M% D4 _& b
13.______能帮助识别和解决bug。7 ^: v( d* y" K8 _; D2 u& P' c
0 G- q! f1 W) k6 N# t: A1 L+ M
答案:____________
2 E l/ ]& ?1 @% J; y* G# h/ J1 ]7 C8 m* k, `1 D3 Q
2 B9 @" O/ n7 M L$ D14.trigger_error()和user_error()有什么区别?9 m" T/ z7 {- W1 g- l
& I, Z$ c3 m! N. n1 F
A.trigger_error()允许脚本抛出系统级的错误
" j( x" ~* A, wB.user_error()允许脚本抛出系统级的错误
8 q6 @, D. g3 }; dC.user_error()不能被用在错误管理器中+ `& |3 M, c8 T* j
D.trigger_error只在PHP5中可用& |' I2 Z, \/ _5 J
E.没有区别
2 t) Y8 u# L4 T I# T- M& Y* O/ N3 R: q
6 n# e( a9 E+ p0 A9 |$ M/ s) K15.______函数能返回脚本里任意行中调用的函数的名称。该函数同时还经常被用在调试中,用来判断错误是如何发生的。7 r4 ~1 D0 M7 n4 b. j7 b% ^
) P2 N! q. }5 s/ @/ AA.print_r6 l: e2 E. b$ w J
B.var_dump1 _# j1 {& C* N
C.stack_dump
3 t; y7 O, G) m, O& S$ }1 z$ ^! tD.debug_backtrace" I. j* l/ V7 c4 c
E.以上都不对
( f* Q3 K9 l% ]0 d ?2 |7 X5 O
. _- H4 G2 X) C0 F8 t, Q8 u答案. D! r1 `7 _; ?( H7 f
, P0 c% `& O/ N$ P2 q1.答案是E。三元操作符把每个if语句连到一起,作为&&操作的一部分。然而本题中,$x=1这个赋值只在第三个if为false时发生。如果第一个和第二个条件都不成立,$x=1就不会执行。这题对三元操作的应用有些极端,实际应用时,需要根据可读性来决定是否需要用三元运算符(本题这种情况就最好不要用)。
. _# \ n: b v5 F9 ?: u4 s" O, n# M# H5 H
2.问题是由第三方数据源传输缓慢导致的,而你无法控制这个数据源。你也许能在网络连通性上做些工作(假设问题出在你这一边)。还可以对接收到的内容进行缓存,这样能减少获取重复数据的时间。因此,答案是B和E。/ g- `( f, u: Y3 I
9 i+ x$ A& Y( c& |2 S
3.正确的选择是B和D。如果关闭错误报告、使用@抑错符和关闭错误日志,那么在你交付给客户的网站出现问题时,你将很难进行分析和调试。 U# Q4 j/ Z+ V, }1 Y0 K' e
* S) O9 ?4 P U4 X/ u) e) Y; i2 S; ~
4.这是在描述===操作符。- o. _3 `# I" a: l: c" |1 z$ W; K5 b
+ Y' r: Q& j8 ]' {# M5.正确答案是D。PHP脚本在执行时,将首先被解析成“中间”码(也叫opcode,操作码),然后解释器执行。操作码缓存出现在这两个步骤之间,对解析器的输出进行缓存。下次执行该脚本时,将缓存的输出直接送入解释器。这样就就不需要再解析一次了。: V7 Z& _( s0 r& l: `" e4 \* G7 ?1 ?
4 e% n, F$ U) o$ }) ]2 P+ x3 l
6.正确答案是A和D。如果RAM太小,进程间将出现资源竞争,服务器将大量使用硬盘交换。同样的,如果允许过多进程同时执行,也会使服务器频繁进行交换,导致速度下降。
. S; I) D8 c5 e A
" z! A( q# J2 M5 { L7.正确答案是A和C。脚本不检验datebase_query()的调用是否成功,因此将持续执行下去,最终产生错误。此外,$my_id参数没有转义——可能导致代码注入(详见第11章)。& Q; P7 _" R' Q/ J/ |) c* M
: D& Y" i) S5 k! n) t$ V8 z6 n1 E$ P
8.答案B和D正确。出现解析错误往往表示脚本中有语法错误,自定义的错误管理器无法捕捉到它们的原因很明显:错误管理器在脚本里,而现在无法解析脚本,管理器也就无法执行。类似的,E_ERROR表示有致命的运行错误出现,比如内存耗尽。因此脚本会立刻被中断,因为解释器无法执行后面的代码。
& ^ l5 t7 e4 ?5 L' G" z4 d5 I( `$ {* C7 ?- n0 \$ }3 e
9.答案是C。比较操作是一个可交换的操作(就是说结果独立于操作数之外),而赋值不是。因此,比如说,$a==10和10==$a是等效的,而$a=10和10=$a却不是,而且后者会导致一个错误,因为这不是一个合法的操作。确保常量在操作符前面,能保证你不会错误得将比较变成赋值。
/ @* h& {- y: ~' j" R6 Y
: w6 V* f- g" l# w/ ?2 ^7 t8 u10.答案是C。error_log函数能将信息送往一个指定的地址。尽管mail()也可以用,但error_log能自动给邮件添加标题,因此这才是最简单的方法。9 T3 K: u( @7 l3 ?5 {& s" Q
9 j. c# |' k, ^% H: y6 ~4 l0 G6 V
11.答案是不能。error_reporting函数能关闭所有运行时的错误报告,但对解析时的错误无效,因为解析错误发生在脚本执行之前。! m( Y j0 I" S& B- ~0 K
; k' |5 g4 n/ O% a$ g: q
12.显然,答案是C。概要分析器(profiler)能监视脚本的运行,并记录单个部分的运行时间。它可以用来找出和解决瓶颈。0 ~, h/ ?, }7 T% u/ W% Q Q8 J
1 i! k/ W: ]$ w9 k; N# k. q# X
13.这是对调试器的完美定义!你可以用调试软件监视脚本运行,同时分析系统资源消耗,从而发现和解决程序缺陷。9 K$ t# V- S( q; S& Q9 Q: |
" g$ Q, Z4 [" Z! R0 w9 n. b
14.trigger_error()和user_error()之间没有区别。后者其实是前者的别名。
4 {' F* h3 t; K- m" X8 ]2 r" z- r" x
* {: Z' ~& ^) m! \* s5 o15.答案是D。题目是在描述debug_backtrace函数,它返回一个由所有在代码的特定位置调用过的函数名组成的数组。 |
|