  
- UID
- 1
- 帖子
- 738
- 精华
- 28
- 积分
- 14247
- 金币
- 2414
- 威望
- 1647
- 贡献
- 1362
|
[Zend权威认证试题讲解]第十二章 -调试与性能管理
作为一个开发者,无论你经验多么丰富,或者无论你多么努力,你的程序中总会有bug。这是生命中一个必然的部分,如同死亡与缴税(尽管并没有后面两个那么严重)。
c/ B6 q9 \% O4 p7 ?要想解决bug,首先要能找到bug。事实上,许多开发者花费了无数小时茫然得盯着代码,只是因为他们没有把程序的容错能力摆在首位。忽略了这个部分,那么期望一个没有bug的程序就是——不可能的。
2 b. s" b% o5 s) T: [+ {/ z本章测试题将考察你对调试和性能管理相关知识的了解,以及如何用PHP做好这两件事。. ~6 a) z, {" p- z9 p& x2 ?4 f
* k3 U+ O A k7 b& i7 ^
% {6 a8 X @/ e1 A
问题
$ U+ W2 \. k& {2 W N" C/ R7 A
3 R8 ~3 j/ f/ k. h7 Y+ Q0 r1.以下脚本如何用三元操作替代? * H) _8 S* b* d! p. l4 m
-
- <?php
- if ($a < 10) {
- if ($b > 11) {
- if ($c == 10 && $d != $c) {
- $x = 0;
- } else {
- $x = 1;
- }
- }
- }
- ?>
复制代码
# W; ?5 V" z' e. c! R+ NA.$x = ($a A. < 10 || $b > 11 || $c == 1 && $d != $c) ? 0 : 1;4 S( E8 ~8 d% H2 m" J
B.$x = ($a < 10 || $b > 11 || ($c == 1 && $d != $c)) ? 0 : 1;
; ~1 F: j% s9 i% t- J+ i+ pC.$x = (($a < 10 && $b > 11) || ($c == 1 && $d != $c)) ? 0 : 1;
, [) i+ Q, }/ D* \# ^% _- ND.$x = ($a < 10 && $b > 11 && $c == 1 && $d != $c) ? 1 : 0;
2 J% S! {3 y2 [/ kE.以上都不对) |- s0 D4 ]: N0 E1 w' ~
- j& b6 u. J) E9 f( l! U7 P
) P* ~! x: C( i/ F/ ?2.有一个脚本由于要从远程获取数据,因而运行速度很慢,以下那种方法能对其进行优化?(双选)
2 L9 f, B% ~7 h: |9 O$ z
" C% g. z; h3 g. }+ }A.安装操作码缓存(opcode cache)2 v- O- s# r1 {+ F; ~
B.优化或者升级你的网络连接( n, p# m9 m! M! `2 ^
C.添置更多的硬件
% S9 v, |" j% u. Y: q9 x% T+ A8 ID.增加服务器的可用RAM
+ g, E! j5 O: k4 k# [! @E.使用连接缓存
* y; f+ I3 ?. H" L* O" _2 L' c" q2 w J0 e/ ]* q
6 R# v' {, S4 d3 j8 r1 ]
3.架设生产环境下的服务器时,需要做哪些步骤?(双选); g- {2 C* V0 N- F3 P |
7 ^% ]0 v2 @/ c2 a# ~* Q6 e/ ~A.关闭错误报告
. c4 F3 V |7 }1 _# oB.打开错误日志6 n& M1 I" f, k. \, ?
C.关闭错误日志1 W, M+ V7 {6 W8 M9 h0 G- M
D.关闭错误显示
. j ]- m5 Y: f& y, ]1 v$ e! ME.使用@抑错符& @8 A& s- Z' ]) S. W9 \+ ]0 e8 F
3 g! n; J$ B9 o) v' v
' r/ t+ O! H) n+ R( U! q4.______操作符能对操作数的数据类型进行严格的比较?- t; I# z' b6 I( \0 [
8 F$ J1 Z) }. d2 [答案:____________0 n" `9 f% y8 O: l$ _
# C& }' l, i$ ^ h6 h& i( Z. [4 a7 \5 Y# _8 e! N2 L
5.操作码缓存(opcode cache)能做什么?
: o+ S& T d- u; z: h) _3 h' |4 t; b- ]( f9 q8 m8 j9 t
A.把脚本编译成二进制对象,使它运行得更快
, \) C' T o( PB.代替Zend引擎加快解释器的运行
" L5 T* z3 T m, Q( N3 [# CC.缓存脚本输出以提高执行效率
& q$ s, U& P i6 j7 |7 dD.缓存解析器产生的中间码,以提高运行效率
8 Z7 r; X3 p2 L/ y( sE.在内存中缓存脚本,减少从硬盘中读取的次数
* \3 `' U4 V3 ~5 X* S. C. x0 g( `* G9 z- v G8 R7 J" Z
: T4 @: c* z; n$ p' {( @/ @
6.以下哪些情况容易造成系统资源枯竭?(双选)
+ P* A8 |0 x |1 X8 T- S2 C& t7 g% X) M9 Z( K$ r. H, z
A.RAM太小
! j# n' s8 d0 F- K& X G. p& lB.使用了低带宽的连接
8 y8 Z! F* ]# v9 r4 A1 {C.虚拟内存超过2GB0 `5 w6 T, D! M' b. v
D.允许同时运行太多的服务器进程
! D1 v3 g" K. }' G# p0 U7 |- yE.以上都不对
/ R: h) ~$ p5 t; _
2 N1 W; z$ F/ i6 o
1 n' r1 V1 L _+ z+ \6 o7.以下脚本缺了些什么?(双选)
) S7 v; h4 E" Z9 z4 N( L-
- <?php
- $rs = database_query ("select * from mytable where id = " .
- $my_id);
- while ($a = database_get_data ($rs)) {
- var_dump ($a);
- }
- ?>
复制代码
0 s$ A/ Z' ~/ n1 l; L6 {A.参数出口(Parameter escapement)
( ]( ?7 ]- k' [0 J9 }/ pB.输出格式化1 d$ c; }4 e! {2 {- B6 X; {
C.错误检查4 O T3 W! d/ {/ `( W" G) p
D.一个SQL查询
/ b* K: I& x/ c7 {: \2 O" iE.以上都不对6 N9 M$ ~8 b; X8 U/ t- S4 g- D
6 }& G7 E0 B' n/ k6 R
- O; |% m1 X. w. p8.以下那种错误类型无法被自定义的错误处理器捕捉到?(双选)
1 Q3 Z0 r' f- `: O, z- h8 ~$ o( A- t* {" \: ?; `7 T
A.E_WARNING
7 t+ A1 [2 J: X% S; Y" H/ I1 k0 X" o7 IB.E_ERROR9 Q3 a$ M1 H5 X! J* e+ O4 V
C.E_USER_ERROR* g% ^* {( z( q4 z1 I3 v. x
D.E_PARSE9 I9 b: {( ?1 ?
E.E_NOTICE
" W* ~) I$ G8 n B. _$ k) N5 i; }+ h9 @! i& R( a9 f
- [( W' K) @4 [8 ^6 U5 ~9.当需要比较一个常量和一个变量时,如何才能保证不会错弄成赋值?4 }/ f9 ?$ s9 }$ p
4 E: J' s+ w$ s5 S8 i0 k4 t3 qA.把变量转换成int3 R! y% \! I4 Z9 J- e- u3 L3 c# w
B.使用全等比较符(===)
$ R5 W5 q) H- p0 |" ^C.确保常量是第一个操作数
% \; K" M* x/ [4 j$ VD.使用三元运算符
5 i3 X0 d# G# v2 c% BE.用括号把操作包起来
, e# T& @/ f; [
) f ~; l/ ^( S( |' u; k W$ E% r1 }( [4 U6 v
10.要通过邮件给系统管理员发送错误信息,以下那种方法最简便?
6 a$ v0 {7 N# i& O$ W8 d+ o) g6 ]+ q
4 N- q9 I, k+ rA.创建一个连接远程SMTP服务器的函数
, Q6 Q0 y- o+ z# S# SB.使用mail函数# Z% q2 p7 h' [
C.使用error_log函数
1 l$ V8 P8 W L" @ U. h# aD.调用sendmial程序
4 L; E3 v/ q! k. H: sE.使用webservice- U/ r& s4 M4 X4 X. A6 m! B. Q
6 M5 F5 V& X t7 [2 R
- _4 u! k4 j9 D" O9 ]11.能否仅调用一个函数就关闭脚本内所有的错误报告?. R2 D! p$ m7 e: }: f
3 k# \6 P+ K0 n% kA.能% H+ i# q1 Z. k; }) h8 V
B.不能* P$ B5 C( `1 Y
2 y: e& y6 i& H/ w7 X, V+ w
* \$ l9 M( Y( ?: v- M- v, {12.概要分析器(profiler)是做什么的?
# u* w9 Q# F' R9 L
0 i9 d3 @4 q8 u' w7 @, HA.创建关于脚本结构的档案! M2 k8 z6 d$ y$ L& M
B.把脚本转化成UML图( h4 w: z1 I r; [
C.精确测算脚本不同部分的运行时间
( y/ P( K. f- `5 }D.计算脚本通过web服务器执行时的维度) D& o2 Y v; ?* t
E.扫描脚本,识别由常见错误导致的bug
* U+ s) L O/ B4 q. i
) M- t ^1 |% B* q# \- D! A7 Z
+ z) P' @; h( R5 ]0 Q13.______能帮助识别和解决bug。
$ O! P P3 u$ a4 A# Y4 T5 j
% c9 Z- G$ M% Q" R$ S$ L答案:____________# O1 r4 H! E# A
) `2 }! s* q; B r' ~4 p
( Y _$ z+ M9 {" @5 c14.trigger_error()和user_error()有什么区别?
/ X( d+ ~& m7 S
3 B+ S9 R" ^2 O8 O8 z7 \/ sA.trigger_error()允许脚本抛出系统级的错误
9 y1 S8 U. ]& _) ~B.user_error()允许脚本抛出系统级的错误
5 c. m" @& E3 U0 Q2 wC.user_error()不能被用在错误管理器中
- a! o9 s* \/ w- N% V& pD.trigger_error只在PHP5中可用
6 _9 A( j' A' t5 CE.没有区别# {( f x1 q& {" }' V# y
0 L6 j8 ]$ ~" |$ E7 t9 P: E
9 M5 I+ v8 G- g, s
15.______函数能返回脚本里任意行中调用的函数的名称。该函数同时还经常被用在调试中,用来判断错误是如何发生的。
5 f* x2 A3 |0 C1 a B" W9 {( I/ _3 b; T! O _9 S
A.print_r* B: p1 d9 W& V0 w5 \* C
B.var_dump
4 Y% |8 f5 f7 YC.stack_dump
# b5 C4 a o% Z' E# YD.debug_backtrace+ u, [# c7 x4 R! {
E.以上都不对
6 `2 n- ?2 E& \/ K4 C7 \6 |
5 Q' L( x4 }$ B, {4 O% v! T4 \答案
+ U% z8 Z p6 z ?) ~$ F( \
! s5 t) [% X) L) y' t1.答案是E。三元操作符把每个if语句连到一起,作为&&操作的一部分。然而本题中,$x=1这个赋值只在第三个if为false时发生。如果第一个和第二个条件都不成立,$x=1就不会执行。这题对三元操作的应用有些极端,实际应用时,需要根据可读性来决定是否需要用三元运算符(本题这种情况就最好不要用)。& x3 \+ q' y8 b }4 ?. m9 N4 @+ p
. y. i \0 j' g+ M7 E2.问题是由第三方数据源传输缓慢导致的,而你无法控制这个数据源。你也许能在网络连通性上做些工作(假设问题出在你这一边)。还可以对接收到的内容进行缓存,这样能减少获取重复数据的时间。因此,答案是B和E。 v( R3 S1 k% F2 X
4 S0 F# j; k6 i% X7 A" V
3.正确的选择是B和D。如果关闭错误报告、使用@抑错符和关闭错误日志,那么在你交付给客户的网站出现问题时,你将很难进行分析和调试。% b- k& g. q: m8 T" N# h
5 T8 n& ^. h- D- @4.这是在描述===操作符。
! ~& v4 E: T, d: ]% N W4 o% {1 X* n9 |' d8 C, i; N
5.正确答案是D。PHP脚本在执行时,将首先被解析成“中间”码(也叫opcode,操作码),然后解释器执行。操作码缓存出现在这两个步骤之间,对解析器的输出进行缓存。下次执行该脚本时,将缓存的输出直接送入解释器。这样就就不需要再解析一次了。, w8 K* t$ H( b* q
; J% b$ W0 o" g2 J8 y4 i
6.正确答案是A和D。如果RAM太小,进程间将出现资源竞争,服务器将大量使用硬盘交换。同样的,如果允许过多进程同时执行,也会使服务器频繁进行交换,导致速度下降。
; M+ `$ B$ j* S6 }
* O& c% Y$ Q& m3 e7.正确答案是A和C。脚本不检验datebase_query()的调用是否成功,因此将持续执行下去,最终产生错误。此外,$my_id参数没有转义——可能导致代码注入(详见第11章)。. ?% G* P% @# V
& G/ B( L0 o3 J% _% x7 ]3 b8.答案B和D正确。出现解析错误往往表示脚本中有语法错误,自定义的错误管理器无法捕捉到它们的原因很明显:错误管理器在脚本里,而现在无法解析脚本,管理器也就无法执行。类似的,E_ERROR表示有致命的运行错误出现,比如内存耗尽。因此脚本会立刻被中断,因为解释器无法执行后面的代码。7 S& H) F: d9 c& V% c: [
, C4 J& l1 k& ]- |9.答案是C。比较操作是一个可交换的操作(就是说结果独立于操作数之外),而赋值不是。因此,比如说,$a==10和10==$a是等效的,而$a=10和10=$a却不是,而且后者会导致一个错误,因为这不是一个合法的操作。确保常量在操作符前面,能保证你不会错误得将比较变成赋值。
0 K2 q+ o$ P8 C( g* a) r6 Y/ V" {* I9 d; V1 |
10.答案是C。error_log函数能将信息送往一个指定的地址。尽管mail()也可以用,但error_log能自动给邮件添加标题,因此这才是最简单的方法。6 T7 G$ x0 n' Q$ U/ e2 Z& Q {
0 U# `' Q1 L0 l* [4 ?
11.答案是不能。error_reporting函数能关闭所有运行时的错误报告,但对解析时的错误无效,因为解析错误发生在脚本执行之前。6 N1 h/ U8 n" a
+ v) Z: m4 L9 a12.显然,答案是C。概要分析器(profiler)能监视脚本的运行,并记录单个部分的运行时间。它可以用来找出和解决瓶颈。3 W+ @# j% H' P1 `' i0 ~1 f
. _5 D4 Y' n( @* f% c2 P! {/ Q" q
13.这是对调试器的完美定义!你可以用调试软件监视脚本运行,同时分析系统资源消耗,从而发现和解决程序缺陷。
; |: n. q1 ?1 U9 o
, m2 B* ?9 v( N5 U+ L4 w" d/ J14.trigger_error()和user_error()之间没有区别。后者其实是前者的别名。. b6 R6 p0 b$ R3 B& I" ^
, j) b& ?. q& r, _2 ^
15.答案是D。题目是在描述debug_backtrace函数,它返回一个由所有在代码的特定位置调用过的函数名组成的数组。 |
|