|
  
- UID
- 1
- 帖子
- 738
- 精华
- 28
- 积分
- 14443
- 金币
- 2507
- 威望
- 1647
- 贡献
- 1455
|
[Zend权威认证试题讲解]第十二章 -调试与性能管理
作为一个开发者,无论你经验多么丰富,或者无论你多么努力,你的程序中总会有bug。这是生命中一个必然的部分,如同死亡与缴税(尽管并没有后面两个那么严重)。
2 _1 \- s4 l* v. l; W* n4 {6 H要想解决bug,首先要能找到bug。事实上,许多开发者花费了无数小时茫然得盯着代码,只是因为他们没有把程序的容错能力摆在首位。忽略了这个部分,那么期望一个没有bug的程序就是——不可能的。
0 ]' K$ C. ?8 r6 `$ j本章测试题将考察你对调试和性能管理相关知识的了解,以及如何用PHP做好这两件事。0 d8 Y8 m* b+ i; D5 F4 f* H
/ I; p3 c0 z# a) Z1 p; p+ @! |) o! q- `3 u* p
问题
! [% s8 X! t' v' `. Y: T# w+ P" T$ R1 o5 l% n D
1.以下脚本如何用三元操作替代?
, m! v, Z+ J1 i/ {( r' ^9 [% C-
- <?php
- if ($a < 10) {
- if ($b > 11) {
- if ($c == 10 && $d != $c) {
- $x = 0;
- } else {
- $x = 1;
- }
- }
- }
- ?>
复制代码
. C5 F# N4 M1 e( P8 \! _A.$x = ($a A. < 10 || $b > 11 || $c == 1 && $d != $c) ? 0 : 1;. ]& K5 K0 B' J+ @
B.$x = ($a < 10 || $b > 11 || ($c == 1 && $d != $c)) ? 0 : 1;
" S. O8 v5 [) U- nC.$x = (($a < 10 && $b > 11) || ($c == 1 && $d != $c)) ? 0 : 1;( N/ a, [: P" d( x6 l
D.$x = ($a < 10 && $b > 11 && $c == 1 && $d != $c) ? 1 : 0;
5 n+ H4 x' n5 a5 A( y5 k, G/ S JE.以上都不对
4 k# X: j, u& f) g. u3 V
1 z3 p+ M2 E9 Y1 T" W( c3 I4 A
e# O% K- n R0 F2.有一个脚本由于要从远程获取数据,因而运行速度很慢,以下那种方法能对其进行优化?(双选)7 `0 Q1 x6 Y# Y- f1 P7 b: @
- J6 p8 \9 \ G- i& i# k& N8 l
A.安装操作码缓存(opcode cache)- r) h5 y# F( U. z+ H
B.优化或者升级你的网络连接" H/ e, ]/ ^4 E
C.添置更多的硬件
3 d9 S8 B! V; Q b$ JD.增加服务器的可用RAM
- j+ b: @: c- k r: LE.使用连接缓存
* h! X D6 m; y5 e, A& e" s% C. y9 a& O+ n6 v, n
9 {& U- h: e* m2 F, m/ u8 m5 A3.架设生产环境下的服务器时,需要做哪些步骤?(双选)# d- b. ~+ E4 Y; Q/ a
+ i$ ~9 w; r# R6 |! ^
A.关闭错误报告 i' J. s5 P/ _5 i% e1 J9 Z
B.打开错误日志
7 l7 h Y: j; D* M. |; B1 I! a" m- cC.关闭错误日志6 {3 y8 M- S1 ~/ s( l
D.关闭错误显示0 M8 M( f3 M. B& w& l) H5 ~" q
E.使用@抑错符
; g! l( b9 ` ?& o
9 n9 R& O+ @4 v9 ]5 E6 S* w; q6 i$ }& K* e
4.______操作符能对操作数的数据类型进行严格的比较?
" a2 h1 I* }: {2 {: a+ {2 p5 f) L& V
答案:____________
4 M; t, R6 H3 _# k! G) `
) O% E7 q. Y3 d5 u; S9 O1 c) k
) u F+ r+ i$ Y5.操作码缓存(opcode cache)能做什么?
: S$ M, H# p7 x
# V3 {0 R5 f" ?! bA.把脚本编译成二进制对象,使它运行得更快
9 ?& I( B4 Z% Y3 Q- r) Q+ ^B.代替Zend引擎加快解释器的运行
+ C- m+ J. m- [- K/ O, m4 vC.缓存脚本输出以提高执行效率
6 ^8 A8 u' w- R5 |: ~# v6 qD.缓存解析器产生的中间码,以提高运行效率
8 K8 D7 \( ^0 y _ s3 rE.在内存中缓存脚本,减少从硬盘中读取的次数1 L$ e& [4 q, ~! Z
% t0 a5 @) ^2 G! E0 K- ]
/ _: I! u# y& G ~, V% O6.以下哪些情况容易造成系统资源枯竭?(双选)
X( J3 R, E+ P y* H, c" k
8 L1 `2 T F8 y/ w0 ] \! g" OA.RAM太小
' k' e4 U% b# }; t2 m; bB.使用了低带宽的连接! X# W- J4 |" g% j% |& z
C.虚拟内存超过2GB0 P$ j5 E" h6 w: c6 s
D.允许同时运行太多的服务器进程9 k5 T1 s4 R2 W; K' l
E.以上都不对
2 }) J5 V" k, ?# O! r) |# L; [, w6 l8 @! t- e2 Z
8 i" {1 L2 S0 x8 p7.以下脚本缺了些什么?(双选) ) I( [& Q- K$ R5 t- Q
-
- <?php
- $rs = database_query ("select * from mytable where id = " .
- $my_id);
- while ($a = database_get_data ($rs)) {
- var_dump ($a);
- }
- ?>
复制代码 / P8 T4 ]7 N+ z$ `$ t+ }1 M" K3 E
A.参数出口(Parameter escapement)/ q1 i1 a0 z. B" m- A. C# t3 Y
B.输出格式化
! U$ u/ x. N6 r& u7 F6 M' g- Z3 cC.错误检查% q8 k3 s) n, v! Q# X; ]8 W
D.一个SQL查询) v! x5 u f7 G# {
E.以上都不对" d4 V" x/ w% @) f H
9 _# g9 f$ O1 Y9 g$ U
9 b. W/ G9 Y! U+ u) E% L
8.以下那种错误类型无法被自定义的错误处理器捕捉到?(双选)
# ^2 R8 [3 ~, [( z5 a7 u+ u u3 w6 e3 F* N$ O' Z- U& C
A.E_WARNING) C7 @+ e, P: ~1 D! d' S0 i
B.E_ERROR- F0 L$ q% D8 Q) S9 S
C.E_USER_ERROR
3 h/ l' o) G6 U7 t. U fD.E_PARSE
! X( w" K- M: sE.E_NOTICE
) W' q1 p5 X; h! Q/ B. \
2 S! M7 D# A4 p ~6 R! ]8 `& Y8 Y8 P, H) a& i2 H0 k
9.当需要比较一个常量和一个变量时,如何才能保证不会错弄成赋值?7 S! Y# `/ n7 i
$ s* I7 n" b' h$ s x* ?A.把变量转换成int
# x% y. q4 C/ p1 {6 w0 d: Z4 nB.使用全等比较符(===)
% T# W+ S6 b- q, k1 c; d9 AC.确保常量是第一个操作数
+ M' e2 N% M( R( L% K8 H! R: \3 CD.使用三元运算符
. L" S: ^1 e& I/ X( K' xE.用括号把操作包起来( A! B- h# s; x
; U i0 o# y7 }" W4 P; o$ x8 c1 ]. `1 H" M% b( ^& T1 ]8 m! h8 K
10.要通过邮件给系统管理员发送错误信息,以下那种方法最简便?$ f$ S) h! p% w' G
7 w d1 k# N0 v6 Y8 A# J; W7 \" ~6 QA.创建一个连接远程SMTP服务器的函数
6 j5 p3 L6 W7 q/ M' UB.使用mail函数* }& {2 n- O% ^5 m. [. Q
C.使用error_log函数' A" X0 m! g9 R1 T
D.调用sendmial程序3 {0 \6 a- B G4 ^9 U, E6 @
E.使用webservice: F9 t. w2 U# t8 S
* d- @/ ?" T6 g
1 @ Z) n7 B# g1 L0 B11.能否仅调用一个函数就关闭脚本内所有的错误报告?
' d; {4 N1 M7 `2 A! P8 W8 T( B; d7 a, o/ x! f
A.能2 D- z+ [$ T1 u# k" t* d
B.不能
5 H4 b! _7 A1 R/ d4 d3 [1 X
- I8 @. \; r; m% g$ T
7 d, P9 n" _7 N+ u' \7 M: k12.概要分析器(profiler)是做什么的?
, `+ Y0 H" P6 ?$ \8 _: K& F: G4 [5 s9 k" f1 S3 X
A.创建关于脚本结构的档案1 X) G z$ x9 [/ r) Q. w. n ^- N
B.把脚本转化成UML图
* E0 r, x7 O9 d) z. c1 GC.精确测算脚本不同部分的运行时间
# T/ ?- _7 q' }$ i& i% U! QD.计算脚本通过web服务器执行时的维度- Y" o3 m- h( \% A* C9 V
E.扫描脚本,识别由常见错误导致的bug+ [' s9 g9 _" ~
$ z" C! b8 Y7 q1 d
! u: a3 e9 N( u& G: _+ H
13.______能帮助识别和解决bug。3 L$ b! Q: c( D* p0 l: u; s
# c# m) }& H, p3 `6 t \$ W4 {答案:____________, h5 P6 M9 k5 j s; B0 G
+ w. G, j q4 p, N
4 a" \0 ?$ {4 ?, \( E+ y
14.trigger_error()和user_error()有什么区别?" O( j/ h; b2 m# i+ ^
* G9 T. I/ d" e, c7 j2 }6 I c/ [A.trigger_error()允许脚本抛出系统级的错误 U5 `6 t3 N$ Q: f# J% x6 |
B.user_error()允许脚本抛出系统级的错误4 |4 ^. E0 [) \
C.user_error()不能被用在错误管理器中
# x7 N# v: w/ w RD.trigger_error只在PHP5中可用
; W/ e1 P( Q$ K- WE.没有区别
' n' ^: @* {& V3 v* G0 U
. o6 \0 C5 K n8 r6 N# x1 R! {) g' h1 G$ E# P( B. T/ ^! ]
15.______函数能返回脚本里任意行中调用的函数的名称。该函数同时还经常被用在调试中,用来判断错误是如何发生的。
9 a$ Y4 |2 _* t! L( w& V
( m2 e& I2 q3 PA.print_r, }- s' h/ N$ r# T
B.var_dump% G2 `& j7 t4 W; [
C.stack_dump
. v/ ~/ i6 s& ^( Q8 CD.debug_backtrace& X5 R& u- F5 s- v& I: G( h
E.以上都不对
, ^3 F; s0 t+ E5 ], f
7 S6 I- ~: N/ @ X* ~0 c答案. F) l+ a% U# A
) F7 }. a# ~8 K6 e2 I1.答案是E。三元操作符把每个if语句连到一起,作为&&操作的一部分。然而本题中,$x=1这个赋值只在第三个if为false时发生。如果第一个和第二个条件都不成立,$x=1就不会执行。这题对三元操作的应用有些极端,实际应用时,需要根据可读性来决定是否需要用三元运算符(本题这种情况就最好不要用)。0 Y5 J1 [& \5 I2 I
: W2 |# I5 Y4 d [2.问题是由第三方数据源传输缓慢导致的,而你无法控制这个数据源。你也许能在网络连通性上做些工作(假设问题出在你这一边)。还可以对接收到的内容进行缓存,这样能减少获取重复数据的时间。因此,答案是B和E。
0 E0 ?' f6 I* ]7 O) k1 H
9 d5 j, @& l+ b1 D3.正确的选择是B和D。如果关闭错误报告、使用@抑错符和关闭错误日志,那么在你交付给客户的网站出现问题时,你将很难进行分析和调试。: D3 k3 J L" {, l' t, J2 O- d
' T% w$ J5 X* B$ h: s4.这是在描述===操作符。( o( t) Z, l% L+ E3 `$ o0 w
- V) y# u! v( e1 M
5.正确答案是D。PHP脚本在执行时,将首先被解析成“中间”码(也叫opcode,操作码),然后解释器执行。操作码缓存出现在这两个步骤之间,对解析器的输出进行缓存。下次执行该脚本时,将缓存的输出直接送入解释器。这样就就不需要再解析一次了。
* U; T% u+ J, L5 p6 [* b9 f& u' H" y9 A7 V
6.正确答案是A和D。如果RAM太小,进程间将出现资源竞争,服务器将大量使用硬盘交换。同样的,如果允许过多进程同时执行,也会使服务器频繁进行交换,导致速度下降。& y- h' J! U+ N* T: e/ U
& W6 @9 o0 B" l) Q9 t& t/ }" \7.正确答案是A和C。脚本不检验datebase_query()的调用是否成功,因此将持续执行下去,最终产生错误。此外,$my_id参数没有转义——可能导致代码注入(详见第11章)。
) B2 M X( R1 d! G) V
! k9 @& k9 G# z8.答案B和D正确。出现解析错误往往表示脚本中有语法错误,自定义的错误管理器无法捕捉到它们的原因很明显:错误管理器在脚本里,而现在无法解析脚本,管理器也就无法执行。类似的,E_ERROR表示有致命的运行错误出现,比如内存耗尽。因此脚本会立刻被中断,因为解释器无法执行后面的代码。
, z- \- V+ X5 Q3 y2 I. l2 m
& I1 g" j& o4 l& s. D9.答案是C。比较操作是一个可交换的操作(就是说结果独立于操作数之外),而赋值不是。因此,比如说,$a==10和10==$a是等效的,而$a=10和10=$a却不是,而且后者会导致一个错误,因为这不是一个合法的操作。确保常量在操作符前面,能保证你不会错误得将比较变成赋值。' N' f* j2 J" w0 ^/ g8 U. ?
9 [* V# Q3 J5 H% ?) x10.答案是C。error_log函数能将信息送往一个指定的地址。尽管mail()也可以用,但error_log能自动给邮件添加标题,因此这才是最简单的方法。2 [7 D$ ]* Z0 a% y' }" `
! J9 W" B; \9 `' l
11.答案是不能。error_reporting函数能关闭所有运行时的错误报告,但对解析时的错误无效,因为解析错误发生在脚本执行之前。# b: ?1 u2 I7 u Z
. c- o* e( ~* P3 c4 v' O- J+ S+ a
12.显然,答案是C。概要分析器(profiler)能监视脚本的运行,并记录单个部分的运行时间。它可以用来找出和解决瓶颈。
/ {, L& u1 v, e' `' v; y8 X1 Z8 ^; b5 E
13.这是对调试器的完美定义!你可以用调试软件监视脚本运行,同时分析系统资源消耗,从而发现和解决程序缺陷。
" j; T5 h9 z; b! h ^% b2 C# f3 |
1 `0 N8 m9 C" }2 P8 c* O6 Q14.trigger_error()和user_error()之间没有区别。后者其实是前者的别名。
) C: @3 s+ x% ~; ?/ l( f% n
% z& Q' D. E. X9 Q5 L6 U. ]15.答案是D。题目是在描述debug_backtrace函数,它返回一个由所有在代码的特定位置调用过的函数名组成的数组。 |
|