|
  
- UID
- 1
- 帖子
- 738
- 精华
- 28
- 积分
- 14321
- 金币
- 2446
- 威望
- 1647
- 贡献
- 1394
|
[Zend权威认证试题讲解]第十二章 -调试与性能管理
作为一个开发者,无论你经验多么丰富,或者无论你多么努力,你的程序中总会有bug。这是生命中一个必然的部分,如同死亡与缴税(尽管并没有后面两个那么严重)。
5 G) F3 b0 E2 R4 M要想解决bug,首先要能找到bug。事实上,许多开发者花费了无数小时茫然得盯着代码,只是因为他们没有把程序的容错能力摆在首位。忽略了这个部分,那么期望一个没有bug的程序就是——不可能的。
1 i( Z! ~' D K4 `% w+ I3 }本章测试题将考察你对调试和性能管理相关知识的了解,以及如何用PHP做好这两件事。
% }" \6 f$ v- t4 Z1 A' G# X0 Y+ j4 j3 K! h! n! Q) f1 I, a1 ~1 ]
7 m7 o% w0 q3 e! L& W$ p& i. A问题
- X: e' s! P1 [: T7 G c
- {6 S, y- L- `9 h3 `' C1.以下脚本如何用三元操作替代?
* j4 p* n% K) n1 m! k4 b& D1 c6 [-
- <?php
- if ($a < 10) {
- if ($b > 11) {
- if ($c == 10 && $d != $c) {
- $x = 0;
- } else {
- $x = 1;
- }
- }
- }
- ?>
复制代码
. o( B1 |8 i; }& }A.$x = ($a A. < 10 || $b > 11 || $c == 1 && $d != $c) ? 0 : 1;
7 [/ E: u5 T5 K- KB.$x = ($a < 10 || $b > 11 || ($c == 1 && $d != $c)) ? 0 : 1;
7 o: ~5 J1 Y2 g# j& S; zC.$x = (($a < 10 && $b > 11) || ($c == 1 && $d != $c)) ? 0 : 1;6 r- x% @# `/ r8 z
D.$x = ($a < 10 && $b > 11 && $c == 1 && $d != $c) ? 1 : 0;
& p: L8 [8 t8 U2 V% }E.以上都不对
2 L4 ^2 A" ^% z5 l9 h8 u; \- G4 t; y7 }
! C, t: P- F! u- E2.有一个脚本由于要从远程获取数据,因而运行速度很慢,以下那种方法能对其进行优化?(双选)
- D+ a, p0 v- p! z# y
4 x3 u1 C3 a. B1 p$ b! oA.安装操作码缓存(opcode cache)
& N2 k2 h, L( w2 q2 YB.优化或者升级你的网络连接
' o( {- o- f! o1 {1 {) C# _/ M3 OC.添置更多的硬件
+ @+ c" E8 ?, |& A- K0 G9 BD.增加服务器的可用RAM
+ ?8 Y$ h1 O$ J' S+ m0 g8 k: aE.使用连接缓存0 Q( q" j- { v6 {
- r } L6 _+ H2 N8 v
$ ?/ n! Z# h* d) w; |9 J! q3.架设生产环境下的服务器时,需要做哪些步骤?(双选)9 k: G7 i! k2 A3 a
7 g: u$ ]; C: }# ^1 P+ m0 B* Q
A.关闭错误报告6 X3 O) U6 F1 e- u3 V9 R
B.打开错误日志
* R* W5 w! j2 Y! C: E1 eC.关闭错误日志( p5 V1 N' `6 a# c1 ]8 W5 _: g
D.关闭错误显示6 N+ ~1 X0 z7 ]
E.使用@抑错符+ d5 e9 N" I) t4 ~
8 e& ]) L/ g' s9 [
4 z9 z }, u2 C. R) ^8 M
4.______操作符能对操作数的数据类型进行严格的比较? f1 ~+ h1 j) q* f3 G- ~
4 L5 r; T4 ` v4 C9 J B
答案:____________# ?' J- b' m" A$ m
: ~ _6 T1 W( x3 ] F- q# X9 l7 G/ z# q4 M% L, K$ M( l
5.操作码缓存(opcode cache)能做什么?
6 Z1 Y1 f. z3 L, x, v: @- O& l! o0 T; @$ e3 z
A.把脚本编译成二进制对象,使它运行得更快 z2 r8 u4 X4 R3 n8 p5 l( V, g$ L
B.代替Zend引擎加快解释器的运行/ }. v% f8 r! f& b+ @
C.缓存脚本输出以提高执行效率
6 w5 H9 c5 U# m: v( YD.缓存解析器产生的中间码,以提高运行效率
+ X8 M0 B& h1 g; k- b0 B" K+ QE.在内存中缓存脚本,减少从硬盘中读取的次数
1 w( `; K* b) w. U/ F0 c. Y, X6 X7 m* {" ~7 H
* O; q* R# H! g* s6 t9 R
6.以下哪些情况容易造成系统资源枯竭?(双选)% f9 E: b6 m/ ^! I
% Z3 G- N1 ~/ P2 L3 d/ uA.RAM太小
- E T+ T3 l- k6 u1 \% L! wB.使用了低带宽的连接
; |) \ @6 g: b8 g* JC.虚拟内存超过2GB6 b$ w) R, \7 K& U. M* \% P9 J
D.允许同时运行太多的服务器进程
% V3 n- e7 d2 G- g, g: `2 NE.以上都不对! }, z" E- ?4 b- N7 V
3 |8 m% d( u# @
; O, o# ~8 F* q. P7.以下脚本缺了些什么?(双选)
6 i- e6 Q) W) f5 N-
- <?php
- $rs = database_query ("select * from mytable where id = " .
- $my_id);
- while ($a = database_get_data ($rs)) {
- var_dump ($a);
- }
- ?>
复制代码
2 ~/ _ p9 u1 k1 R [: h- r. w; BA.参数出口(Parameter escapement)
! [) R2 h4 y( l& r+ ~B.输出格式化3 n d2 m; y. }- a2 x$ e6 @2 M" G
C.错误检查: A( J8 Z* u9 H) R& k
D.一个SQL查询
' z' R4 c0 W2 \E.以上都不对2 ?$ v+ ^& j: S2 C5 P' R
1 s! `6 A6 m$ Z0 h' V' X1 ^! a+ |9 c5 Y9 [, n
8.以下那种错误类型无法被自定义的错误处理器捕捉到?(双选); x) k: v4 R1 d/ k0 B1 Z
3 x& C. `" P/ [- G( xA.E_WARNING1 i) W( E- U( [5 k9 j7 s s) [
B.E_ERROR
8 b$ t F0 w2 g; C. t9 ]$ n5 ]% VC.E_USER_ERROR
+ d* p+ ^1 n/ a5 Y) S3 M% ID.E_PARSE0 }% L6 A W" T# K
E.E_NOTICE) v' w$ `$ A/ C( _7 t) l; `0 x
+ x0 ~- I0 d: A
! w' Y; A: g& x) e8 b( x9 h
9.当需要比较一个常量和一个变量时,如何才能保证不会错弄成赋值?
4 A$ f0 K5 y% K* s F
: u# Q& l' q5 v: H UA.把变量转换成int
, G9 x P2 k" NB.使用全等比较符(===)% { v* r: p/ V7 B9 M' A, x! G
C.确保常量是第一个操作数
3 j' p4 |8 @3 y" g( L" hD.使用三元运算符5 Y5 s& |! S& W% p* g/ X( O! C
E.用括号把操作包起来1 D3 u& U4 m6 d$ c1 Q/ ~% s
/ Y/ }6 S9 M) F
q5 Y, X2 g2 ]8 ?
10.要通过邮件给系统管理员发送错误信息,以下那种方法最简便?
" W% _* C1 Y/ k% ]6 V0 g. q; r2 F
A.创建一个连接远程SMTP服务器的函数
7 W- T3 ^( j7 l* q3 ~$ _B.使用mail函数$ g/ m/ U; e9 X: a" Z E
C.使用error_log函数9 |$ z5 n4 F. D
D.调用sendmial程序
6 Y' R8 |$ y) w3 KE.使用webservice
. M* h* z" r- J, Y, {, y
% G3 ^: g8 U) k' ?2 Z; D$ X8 K' ]; B9 b s2 G' F/ u0 F$ c
11.能否仅调用一个函数就关闭脚本内所有的错误报告?3 K t$ |0 C1 c! B& ]/ Y- f9 g8 K
7 R. z* _) v( n; e9 K0 PA.能/ V; R' r3 u# j6 J6 T1 S( G
B.不能
- s q$ @' I; P! \$ E2 d1 G+ Q0 R9 s" E$ G) N, \% p/ |
7 J3 m* y; `; I5 X: m. m( F
12.概要分析器(profiler)是做什么的?
" U" L9 ^; K( e; b+ Z6 G/ A, z# _; H, M+ x; e3 y6 j
A.创建关于脚本结构的档案
3 T( S ^1 Z4 |$ s' k9 IB.把脚本转化成UML图5 n7 t. B3 z u3 F6 f* V4 N* V
C.精确测算脚本不同部分的运行时间9 x, K6 y0 \4 {, S
D.计算脚本通过web服务器执行时的维度( c! u0 ^' x2 c: H
E.扫描脚本,识别由常见错误导致的bug/ R4 X5 @ f$ D }% L
4 c6 _% b; Q2 o- \ ?8 {8 g) ^
) y& s/ C Q7 d6 Q# n! g+ q) |13.______能帮助识别和解决bug。( N( ^$ T( M4 q& S" V
: ~. }1 p9 x+ @* e9 {
答案:____________4 r6 x( K$ _" S# Z
, x: J3 U3 z1 ]1 F6 N
0 f7 K+ l) D4 W4 I$ z R( k
14.trigger_error()和user_error()有什么区别?) @$ g$ y4 F0 v' m9 O5 N4 z% u
! Y6 Q/ D+ G9 V9 e S; L
A.trigger_error()允许脚本抛出系统级的错误! @$ x. e K$ _
B.user_error()允许脚本抛出系统级的错误4 x+ x. w5 G* Q0 I- g6 M" N
C.user_error()不能被用在错误管理器中
+ D7 H3 u" n4 v" C$ T- yD.trigger_error只在PHP5中可用; A7 w% F5 _8 A
E.没有区别
* e8 C6 F E; H5 a2 Z0 Y( d& K% q$ Y$ k0 z" f! o- s/ |8 U7 h2 P
$ I; U V5 }' M5 E15.______函数能返回脚本里任意行中调用的函数的名称。该函数同时还经常被用在调试中,用来判断错误是如何发生的。
s3 O: J8 h* c
! [. @: {. M( A- G" f. B. J+ n0 |A.print_r
- c9 D2 z* q, X- _B.var_dump( z" S( j, F( l L* B' O2 g' G
C.stack_dump9 Z0 ^' E6 }0 O2 _; a1 b2 }+ s1 S
D.debug_backtrace
! v) u: m9 S9 B* vE.以上都不对% i h3 A2 ?* c6 x4 m
`0 o3 n+ w% V答案7 \* y' L/ S$ x! {) X' a6 v
5 M) h' d5 q- T! j# q! @! G( g5 s1.答案是E。三元操作符把每个if语句连到一起,作为&&操作的一部分。然而本题中,$x=1这个赋值只在第三个if为false时发生。如果第一个和第二个条件都不成立,$x=1就不会执行。这题对三元操作的应用有些极端,实际应用时,需要根据可读性来决定是否需要用三元运算符(本题这种情况就最好不要用)。0 e! G/ ?+ T* \0 X& A
4 n H% [' C$ `/ w: _2.问题是由第三方数据源传输缓慢导致的,而你无法控制这个数据源。你也许能在网络连通性上做些工作(假设问题出在你这一边)。还可以对接收到的内容进行缓存,这样能减少获取重复数据的时间。因此,答案是B和E。
* q6 t: r4 a) V, g* }: s3 F1 \- j0 f w2 {, D V2 \
3.正确的选择是B和D。如果关闭错误报告、使用@抑错符和关闭错误日志,那么在你交付给客户的网站出现问题时,你将很难进行分析和调试。
% o X2 P& l5 A& u
; F: \ y9 p: z M3 h, t d4.这是在描述===操作符。' X5 v* X- u W2 |5 H- r% z
7 I) l( {+ v/ ^, G0 T1 [& ^
5.正确答案是D。PHP脚本在执行时,将首先被解析成“中间”码(也叫opcode,操作码),然后解释器执行。操作码缓存出现在这两个步骤之间,对解析器的输出进行缓存。下次执行该脚本时,将缓存的输出直接送入解释器。这样就就不需要再解析一次了。2 v0 `) P3 {8 Y) ]
5 j( R. |' X6 X) v$ G4 p( S6.正确答案是A和D。如果RAM太小,进程间将出现资源竞争,服务器将大量使用硬盘交换。同样的,如果允许过多进程同时执行,也会使服务器频繁进行交换,导致速度下降。
$ Z E- P! N- H# F" J
; ^% n" x: W2 J3 ]3 u* _* u7.正确答案是A和C。脚本不检验datebase_query()的调用是否成功,因此将持续执行下去,最终产生错误。此外,$my_id参数没有转义——可能导致代码注入(详见第11章)。
' l; t! Q- L! {0 b B& _, v. i# z" ^
8.答案B和D正确。出现解析错误往往表示脚本中有语法错误,自定义的错误管理器无法捕捉到它们的原因很明显:错误管理器在脚本里,而现在无法解析脚本,管理器也就无法执行。类似的,E_ERROR表示有致命的运行错误出现,比如内存耗尽。因此脚本会立刻被中断,因为解释器无法执行后面的代码。
4 W5 N) c9 y$ z- s. ?" i( Z
/ q: V% f; \% m- G0 k! L3 F: m7 V9.答案是C。比较操作是一个可交换的操作(就是说结果独立于操作数之外),而赋值不是。因此,比如说,$a==10和10==$a是等效的,而$a=10和10=$a却不是,而且后者会导致一个错误,因为这不是一个合法的操作。确保常量在操作符前面,能保证你不会错误得将比较变成赋值。
; o( H* u) \4 M8 }/ I+ O k; H4 O9 @1 p( h! R
10.答案是C。error_log函数能将信息送往一个指定的地址。尽管mail()也可以用,但error_log能自动给邮件添加标题,因此这才是最简单的方法。
' R' e) s+ \* F8 ~( Y a V; G+ m1 j* t4 p& F; L) J
11.答案是不能。error_reporting函数能关闭所有运行时的错误报告,但对解析时的错误无效,因为解析错误发生在脚本执行之前。( \; `& E: m1 e* _+ f0 N1 v9 e
1 d, m5 V, G, }( ]7 n12.显然,答案是C。概要分析器(profiler)能监视脚本的运行,并记录单个部分的运行时间。它可以用来找出和解决瓶颈。6 q" l4 }0 p( z0 \( W2 a
9 f# B" o) v2 ?8 o13.这是对调试器的完美定义!你可以用调试软件监视脚本运行,同时分析系统资源消耗,从而发现和解决程序缺陷。
1 o$ a7 E `. o2 U1 j& n
, j, W; R1 V: D, W4 ^ c7 g14.trigger_error()和user_error()之间没有区别。后者其实是前者的别名。
% e8 F- e' f2 d. n0 p+ ]+ z& d4 g" m$ {2 b9 }- b! ^
15.答案是D。题目是在描述debug_backtrace函数,它返回一个由所有在代码的特定位置调用过的函数名组成的数组。 |
|