|
  
- UID
- 1
- 帖子
- 738
- 精华
- 28
- 积分
- 14347
- 金币
- 2459
- 威望
- 1647
- 贡献
- 1407
|
[Zend权威认证试题讲解]第十二章 -调试与性能管理
作为一个开发者,无论你经验多么丰富,或者无论你多么努力,你的程序中总会有bug。这是生命中一个必然的部分,如同死亡与缴税(尽管并没有后面两个那么严重)。1 W: K: E2 t! o' X( F6 e# M( P' C+ V4 c
要想解决bug,首先要能找到bug。事实上,许多开发者花费了无数小时茫然得盯着代码,只是因为他们没有把程序的容错能力摆在首位。忽略了这个部分,那么期望一个没有bug的程序就是——不可能的。( k1 y- B7 f8 H: B4 M1 |# ^) G- f$ G
本章测试题将考察你对调试和性能管理相关知识的了解,以及如何用PHP做好这两件事。
0 Y( ~! k* R' p/ Y$ Q. ~3 @; Y
6 B0 J2 I$ ?( d+ B% f0 V" g" D& s; i, ~, S
问题
4 q# a" Y* ` M6 C+ l) R% U3 Y s; A* Z& k. j* z+ \ p
1.以下脚本如何用三元操作替代? 3 O7 y; G/ X; u3 X5 B
-
- <?php
- if ($a < 10) {
- if ($b > 11) {
- if ($c == 10 && $d != $c) {
- $x = 0;
- } else {
- $x = 1;
- }
- }
- }
- ?>
复制代码
0 e3 P: S8 p' kA.$x = ($a A. < 10 || $b > 11 || $c == 1 && $d != $c) ? 0 : 1;
2 |* P3 Y, Q3 D6 s% O$ `4 XB.$x = ($a < 10 || $b > 11 || ($c == 1 && $d != $c)) ? 0 : 1;9 }7 f1 g2 s+ L# W
C.$x = (($a < 10 && $b > 11) || ($c == 1 && $d != $c)) ? 0 : 1;
' B$ |, Y: U# `2 w+ Y: |: D4 r4 pD.$x = ($a < 10 && $b > 11 && $c == 1 && $d != $c) ? 1 : 0;
( X0 q) E- U/ L9 D6 K4 Q: g( t5 z/ tE.以上都不对5 V- C0 u+ @* y' K, N
+ X& V' e1 Y9 h4 ~
( C0 x+ A! \! [* @% U' f
2.有一个脚本由于要从远程获取数据,因而运行速度很慢,以下那种方法能对其进行优化?(双选): }/ I% o+ X7 y# e. ]
- A& ^7 A- T* B$ i4 L% f: B$ a6 ?A.安装操作码缓存(opcode cache)5 |7 ^( S# ]3 H+ l3 S
B.优化或者升级你的网络连接
" L) @% e9 l8 i ^- s* B5 M2 }C.添置更多的硬件
& k0 u% J: P0 ~1 m# W! R K. j; a' PD.增加服务器的可用RAM
8 }- @: U. o C; ?- T0 p) YE.使用连接缓存
9 D4 j- V5 {0 c5 J( W
/ ? _6 k D& ~/ [ B, {; b) O; B% d* T( y, P& ?( w9 J% M7 a
3.架设生产环境下的服务器时,需要做哪些步骤?(双选)
: G$ p, e# N" {( R9 x6 {- C& F1 G0 z& B4 I& z- U/ H. o
A.关闭错误报告; Q3 E$ `+ N5 } ?1 @9 B; H" ?
B.打开错误日志; b' q3 W+ p- c1 J( f( t
C.关闭错误日志
/ z# @. K8 H) x/ I! w8 B2 d9 AD.关闭错误显示
2 H4 q7 {; j$ H8 r \, DE.使用@抑错符
: g! F9 i3 A- g0 e5 r
* M- v; m0 x3 m; Q- J3 a) J3 O$ w
- s' |4 n9 y1 @9 `; P* Z4.______操作符能对操作数的数据类型进行严格的比较?
% U* A2 H3 ]8 ^" O! {, E4 r) e1 x6 r! ^5 R2 v
答案:____________- [6 e& ?, U/ x) A2 f# `+ B0 p
0 [& t5 t, q1 R3 f4 z, A
: O0 x4 z2 o: z, S" T- T
5.操作码缓存(opcode cache)能做什么?$ L7 n" X8 q$ u& F5 a
- d5 g% D5 `, M9 [' L
A.把脚本编译成二进制对象,使它运行得更快
- o8 P# @# n0 L) j2 iB.代替Zend引擎加快解释器的运行0 [4 `, y) {& `* U
C.缓存脚本输出以提高执行效率# ]; k1 W8 }! U8 f1 B
D.缓存解析器产生的中间码,以提高运行效率5 [! e q0 {; w( C, P
E.在内存中缓存脚本,减少从硬盘中读取的次数
* Z q% J! [# a4 Y# H, Q. a2 Z/ x6 e( {! X/ W8 |
, H& [9 Y" m: e8 b+ X1 ~
6.以下哪些情况容易造成系统资源枯竭?(双选)
1 C' T# f. X5 {
. S3 ?2 i* v. I* \4 o( P6 C! lA.RAM太小* ` B: R' j) `0 t4 {9 Z- V
B.使用了低带宽的连接
. t3 `- l: H- ]0 }6 H, L5 TC.虚拟内存超过2GB9 j1 }7 Q$ B% w! u. E$ |8 p, V K
D.允许同时运行太多的服务器进程 V" c6 R# ~' j$ p6 s
E.以上都不对
4 g1 F4 h3 H8 E6 F3 U4 X4 N" ?# b& [4 N1 v7 @
0 P5 W0 {: y. G }% `' B7.以下脚本缺了些什么?(双选) # C1 u1 ]! @9 ^; t+ R( a7 P, s
-
- <?php
- $rs = database_query ("select * from mytable where id = " .
- $my_id);
- while ($a = database_get_data ($rs)) {
- var_dump ($a);
- }
- ?>
复制代码 7 ?- M+ ^0 F1 ]+ Y
A.参数出口(Parameter escapement)& m5 Y# T4 x/ X/ }! ~% X
B.输出格式化
/ f/ v( H( K1 J! l( Q- n4 c/ R- aC.错误检查) N |- ~0 V5 ^1 T
D.一个SQL查询
9 K$ M5 `; ?( y6 N0 U$ l5 eE.以上都不对& ^1 C6 ` v7 ]: j9 \3 ^5 F, L! _
- o2 E) g/ y0 q; l5 B% {, t3 _; R4 i5 J8 k# f! l3 u
8.以下那种错误类型无法被自定义的错误处理器捕捉到?(双选)
! k. |3 K( }( _2 p+ v# f1 A
" \3 s7 H& X+ H7 y% a& Y( F9 I4 |* ?. hA.E_WARNING a+ A1 J- k2 `: a5 ]% [* X
B.E_ERROR7 f2 @( a2 c3 y, D
C.E_USER_ERROR
5 {3 t# g% o9 fD.E_PARSE% p. H- a% }; z& p$ T& V
E.E_NOTICE, c0 v# M" `; |& p4 N! |9 j4 h
# E6 W, }; G: ]( D9 ^0 u
& x: k1 s9 ^; ^5 ?* W- w
9.当需要比较一个常量和一个变量时,如何才能保证不会错弄成赋值?
7 W/ O* L' ] S0 s1 H
5 s; t& B# k/ Y# s* ?A.把变量转换成int
& R/ f6 x3 H# t" @B.使用全等比较符(===)
4 @- \0 T h! G1 Y! g2 HC.确保常量是第一个操作数
: b& h w% p; {8 qD.使用三元运算符
* d; N( ~! b2 \& _E.用括号把操作包起来 F& {9 U/ ^6 }) X
/ _: r7 K1 l/ K9 l
' i4 D; i7 o% @; P10.要通过邮件给系统管理员发送错误信息,以下那种方法最简便?
. k. T- N3 S2 U* F5 [8 F: N, V: O! W) V4 ~
A.创建一个连接远程SMTP服务器的函数1 Y# E: g+ [4 d9 i4 q% l
B.使用mail函数( v* Y! S, N( P4 i/ U. y0 H
C.使用error_log函数
9 r8 x a7 D* v; \ bD.调用sendmial程序1 o% f5 P( f, x
E.使用webservice
0 h% P- g3 V" {* E0 O& t5 | n6 Q9 K" W# I) E
2 X3 E* z- T5 c" a# I- P' V& g11.能否仅调用一个函数就关闭脚本内所有的错误报告?( u& o$ t! M9 E1 Z5 f/ P
* `" |3 Y, E4 c
A.能
& Q) L+ ~8 B4 K( W6 |2 SB.不能
( z' m8 F( m: n b1 o6 R7 ^; x: `- s# E# l: O& z2 r3 X% D ?2 ?
: E8 S5 X6 p+ M7 I12.概要分析器(profiler)是做什么的?) @, J1 `2 j5 g2 r
' @% p0 Q$ b$ \% w) t: j
A.创建关于脚本结构的档案
- t8 I! }. O% H; {2 p3 @B.把脚本转化成UML图- K5 d* L1 ~5 s' P3 N, X
C.精确测算脚本不同部分的运行时间
8 d* N/ T0 W! v# Q C3 w- Z( b, t1 AD.计算脚本通过web服务器执行时的维度) \% d: S# O, O3 {
E.扫描脚本,识别由常见错误导致的bug$ ]) P1 {% c* s, v d
' z' @. S( i/ d R6 @
8 a }1 Q3 Z: A( Y, X13.______能帮助识别和解决bug。
- F5 a! X! h2 i3 k4 o% W" R) d
7 n! G8 f7 }7 G7 o, O+ ~答案:____________8 F7 i- C, J1 x/ H8 Z# A
6 |* O) X- e" \. a- }
1 d4 A. L2 Q' L14.trigger_error()和user_error()有什么区别?: P( C4 C! g( n% ~) ~$ H/ [
9 g: c7 w7 Q9 [3 cA.trigger_error()允许脚本抛出系统级的错误
0 I3 y7 O p: X7 f7 e" t2 bB.user_error()允许脚本抛出系统级的错误
/ R/ g" @5 [. b$ {" XC.user_error()不能被用在错误管理器中) ~( \4 x- e# P- Q- v. n) I, Q
D.trigger_error只在PHP5中可用, X' }( B7 b, Z7 h
E.没有区别
$ ^2 c0 ?6 y! @8 V; g3 C% [! t% L; G
9 [3 U8 W# a* n' `. a5 J15.______函数能返回脚本里任意行中调用的函数的名称。该函数同时还经常被用在调试中,用来判断错误是如何发生的。
, r8 r7 B' E4 k' r- L% ]
- p6 N) e) y, w! O* BA.print_r, ? V3 E: y+ j) K( |1 G& N
B.var_dump
5 X1 g0 k+ k" @& b9 F jC.stack_dump, F4 {, k& w. ~; |* c/ b
D.debug_backtrace
) }5 J8 T2 l1 M* ^& r8 W kE.以上都不对
/ t, j: h8 U+ J& a7 C/ @* o/ N% k( q6 b' Q$ I! k: N
答案
6 z* I2 [+ O( v/ j( }7 j, W4 J+ n* E1 ]* I0 j
1.答案是E。三元操作符把每个if语句连到一起,作为&&操作的一部分。然而本题中,$x=1这个赋值只在第三个if为false时发生。如果第一个和第二个条件都不成立,$x=1就不会执行。这题对三元操作的应用有些极端,实际应用时,需要根据可读性来决定是否需要用三元运算符(本题这种情况就最好不要用)。
8 U& s' C6 k% z* ~" T2 _; Q; {% S- H
2.问题是由第三方数据源传输缓慢导致的,而你无法控制这个数据源。你也许能在网络连通性上做些工作(假设问题出在你这一边)。还可以对接收到的内容进行缓存,这样能减少获取重复数据的时间。因此,答案是B和E。4 [' V0 u1 x8 k# i1 q) ?
& J( N t# N1 b* J$ `3.正确的选择是B和D。如果关闭错误报告、使用@抑错符和关闭错误日志,那么在你交付给客户的网站出现问题时,你将很难进行分析和调试。
5 j4 M' g: Q5 w) Q* e; Q! {) W
6 |/ t v/ ~9 r P: D; \* C( X4.这是在描述===操作符。
* s- k" f7 K- V* s6 s% V4 b8 }3 J8 G. b$ ^" J
5.正确答案是D。PHP脚本在执行时,将首先被解析成“中间”码(也叫opcode,操作码),然后解释器执行。操作码缓存出现在这两个步骤之间,对解析器的输出进行缓存。下次执行该脚本时,将缓存的输出直接送入解释器。这样就就不需要再解析一次了。+ A7 F$ ^( v V7 k3 M
! d. U+ c& j4 B* x& W6.正确答案是A和D。如果RAM太小,进程间将出现资源竞争,服务器将大量使用硬盘交换。同样的,如果允许过多进程同时执行,也会使服务器频繁进行交换,导致速度下降。: w8 [* x% g8 \# u6 d* F
& T9 T2 E& m; b+ A; g
7.正确答案是A和C。脚本不检验datebase_query()的调用是否成功,因此将持续执行下去,最终产生错误。此外,$my_id参数没有转义——可能导致代码注入(详见第11章)。! \& _+ n! V+ b7 o4 c
3 I1 W: q9 @! t) l/ L- W9 ]" O
8.答案B和D正确。出现解析错误往往表示脚本中有语法错误,自定义的错误管理器无法捕捉到它们的原因很明显:错误管理器在脚本里,而现在无法解析脚本,管理器也就无法执行。类似的,E_ERROR表示有致命的运行错误出现,比如内存耗尽。因此脚本会立刻被中断,因为解释器无法执行后面的代码。
. N& e; h" L% j1 e1 V" t0 o1 b+ U6 Z9 D. B R h- j
9.答案是C。比较操作是一个可交换的操作(就是说结果独立于操作数之外),而赋值不是。因此,比如说,$a==10和10==$a是等效的,而$a=10和10=$a却不是,而且后者会导致一个错误,因为这不是一个合法的操作。确保常量在操作符前面,能保证你不会错误得将比较变成赋值。 B; T( B! R! f8 M y
: M& f# D. P8 ]9 @3 b10.答案是C。error_log函数能将信息送往一个指定的地址。尽管mail()也可以用,但error_log能自动给邮件添加标题,因此这才是最简单的方法。
# r$ N/ `8 h. q, c9 u5 `& D: O+ F% [3 u4 l# F
11.答案是不能。error_reporting函数能关闭所有运行时的错误报告,但对解析时的错误无效,因为解析错误发生在脚本执行之前。) n: B6 Q6 E2 H: T9 W
3 \; a5 {# Q9 A12.显然,答案是C。概要分析器(profiler)能监视脚本的运行,并记录单个部分的运行时间。它可以用来找出和解决瓶颈。
5 J+ P4 I# G% q6 M' J* ~& K6 n
6 |9 E# L1 r$ A& F13.这是对调试器的完美定义!你可以用调试软件监视脚本运行,同时分析系统资源消耗,从而发现和解决程序缺陷。. b, b9 G# @3 z% Z; p
1 V" M6 C7 j/ ~7 e! ?14.trigger_error()和user_error()之间没有区别。后者其实是前者的别名。6 J9 Y2 ]4 B8 p7 S0 B
5 G8 j9 o0 U+ z1 q8 k+ o& j6 W9 x7 s; L
15.答案是D。题目是在描述debug_backtrace函数,它返回一个由所有在代码的特定位置调用过的函数名组成的数组。 |
|