PHP初级程序员能力测试及参考答案

PHP初级程序员能力测试及参考答案
PHP初级程序员能力测试及参考答案

PHP初级程序员能力测试参考答案[闭卷]

注:①本测试满分100分,80分及格,形式为闭卷,不得翻阅任何手册和参考书籍。本试卷使用的PHP版本为5.2.6+,WEB服务器使用APACHE2+,开发平台为WINDOWS xp+

②本测试时间为3小时,若题后标明不限语言平台,则你可以使用PHP,C/C++,JAVA等任意一门语

言完成。

1.已知三点A,B,C的坐标为A(20,20),B(15,40),C(50,30),三点构成一个三角形,求判断点D(30,18)是否在此三角形内。【本题主要考察基本算法,解答不限语言平台5分】

连接AD,BD,CD,可以计算ABD+ACD+BCD的面积,如果三者之和等于ABC,那么点D在三角形内。海伦公式可以求三角形面积。S=SQRT(p*(p-a)*(p-b)*(p-c));p=1/2(a+b+c)

也可以用向量叉积的办法来判断。也就是余弦公式的变形

ad×ab 代表矢量ad与ab的叉积,其坐标表达式为

ad×ab = (xd-xa)*(yb-ya)-(yd-ya)*(xb-xa)

于是判别过程如下:若三个叉积大于等于0,则则可判定d在△abc内(上)。原理是点在三角行内,必在每条边的同一侧

2.求1~50万以内的素数。【本题主要考察基本算法,解答不限语言平台5分】

要点:首先从3开始,偶数一定不是素数,所以循环条件是i+2,而不是我们习惯了的i++ 一旦能被从2~N/2间的任何一个数整除,则一定不是素数,跳出

还可以再加上一个筛子,把3,5,7,11,13,17,19的倍数踢出。

另外还有许多技巧,主要是减少循环次数,固定循环次数等方式。

筛法求素数:

$t1=microtime(TRUE);

define('MAX_NUM', 100000);

$all = array_fill(0,MAX_NUM,0);

for ($i = 2; $i < MAX_NUM; $i++) {

if ($all[$i] == 0) {

//echo $i,"\n";

for ($j = $i; $j < MAX_NUM; $j+=$i) {

$all[$j] = 1;

}

}

}

echo microtime(TRUE)-$t1;

PHP生成的话,应控制在0.8秒内。C的话应该在20MS以内。(普通PC机1G 内存,1.8GHZ)

附加题:用PHP求出1亿以内的素数并保存在文件中;求出100亿以内的素数的大概个数。【+4分】

第一问需要用到glob函数以及JS定时刷新来完成,第二问的答案是434294481,涉及数论和密码学的知识。

$time = microtime(true);

$fp = fopen("prime_number.txt", "w+");

//定义10亿,目前测试1000万

$number = 10000000;

//寻找31623以内的质数

$array = array(5);

for($i=7;$i<=31623;$i+=6){

$sqrt = sqrt($i);

foreach($array as $value){

if($i%$value===0){

break;

}

if($value>$sqrt){

$array[] = $i;

break;

}

}

$j=$i+4;

$sqrt = sqrt($j);

foreach($array as $value){

if($j%$value===0){

break;

}

if($value>$sqrt){

$array[] = $j;

break;

}

}

}

//将2,3,$array写入文件

fwrite($fp,'2'.PHP_EOL.'3'.PHP_EOL.implode(PHP_EOL,$array).PHP_EOL); //寻找$number以内的质数

for($k=31621;$k<=$number;$k+=60000){

$n=min($k+60000,$number)-6;

$s = '';

for($i=$k;$i<=$n;$i+=6){

$sqrt = sqrt($i);

foreach($array as $value){

if($i%$value===0){

break;

}

if($value>$sqrt){

//写入串

$s .= $i.PHP_EOL;

break;

}

}

$j=$i+4;

$sqrt = sqrt($j);

foreach($array as $value){

if($j%$value===0){

break;

}

if($value>$sqrt){

//写入串

$s .= $j.PHP_EOL;

break;

}

}

}

//将串写入文件

fwrite($fp,$s);

}

fclose($fp);

echo microtime(true)-$time;

?>

lim π(x)/(x/Ln x)=1

3.请问$_GET,$_POST,$_REQUEST变量的作用是什么?区别是什么?【考察点:php 的变量机制本小步骤:3分】

$_GET,$_POST都用于从表单中取值,$_GET取到的值会显示在浏览器中,而$_POST不会,并且$_GET取值有大小限制(2K),所以同等要求下优先使用$_POST。$_REQUEST=$_GET+$_POST+$_COOKIE

已知现在有一个表单定义如下:

那么$_GET['na.me']和$_POST['na.me']的值是什么?为什么?【本小步骤:2分】

:得不到任何值。因为点是非法字符,将会自动转换为下划线。可用$_POST['na_me']访问。

然而某衰哥在某次测试中总是打印不出POST过来的值,问题可能出在什么地方?【本小步骤:1分】

:可能是PHP.INI文件里variables_order选项屏蔽了P

为了解决上面涉及的部分问题,我们需要了解PHP的变量机制。

在每个请求到来以后,apache处理到response阶段的时候,会将控制权交给PHP模块,

PHP模块会在处理请求之前首先间接调用php_request_startup (具体调用序列是

send_php -> apache_php_module_main -> php_request_startup).

通过这位衰哥的分析,在php_request_startup中,找到了初始化请求相关的变量的函数。其部分代码如下:

PHPAPI void php_register_variable_ex(char *var, zval *val, zval *track_vars_array TSRMLS_DC){

char *p = NULL;

char *ip; /* index pointer */

char *index, *escaped_index = NULL;

int var_len, index_len;

zval *gpc_element, **gpc_element_p;

zend_bool is_array = 0;

HashT able *symtable1 = NULL;

assert(var != NULL);

if (track_vars_array) {

symtable1 = Z_ARRVAL_P(track_vars_array);

} else if (PG(register_globals)) {

symtable1 = EG(active_symbol_table);

}

if (!symtable1) {

/* Nothing to do */

zval_dtor(val);

return;

}

while (*var && *var==' ') {

var++;

}

for (p = var; *p; p++) {

if (*p == ' ' || *p == '.') {

*p='_';

} else if (*p == '[') {

is_array = 1;

ip = p;

*p = 0;

break;

}

....以下省略

好了,请详细阅读上面的代码,回答这段代码主要是干什么的?为什么要这么处理?【本小步骤:3分】

:处理点号和数组型外部变量。处理点号是为了二进制安全,处理数组是为了能正确处理如checkbox等数组。

4.定义一个类,使对象可以像数组一样进行foreach循环,要求属性必须是私有。【考察点:PHP5中SPL 的定义和OO高级特性5分】

class sample implements Iterator

{

private $_items = array(1,2,3,4,5,6,7);

public function __construct() {}

public function rewind() { reset($this->_items); }

public function current() { return current($this->_items); }

public function key() { return key($this->_items); }

public function next() { return next($this->_items); }

public function valid() { return ( $this->current() !== false ); }

}

$sa = new sample();

foreach($sa as $key => $val){

print $key . "=>" .$val;

}

?>

或者直接把对象转为数组

5.PHP语言细节【考察点:PHP基础语法知识和杂类】

(1)有下面一段不够优雅的代码,也许还存在BUG:

$fruit[apple]='苹果';$fruit[banana]='香蕉';$fruit[pear]='梨';

for($i=0;$i

print "水果名字".$fruit[i];

}

for($i=1;$i<8;$i++){array_push($week,$i);}

试优化本代码。【2分】

$fruit['apple']='苹果';$fruit['banana']='香蕉';$fruit['pear']='梨';

$len=count($fruit);

for($i=0;$i<$len;$i++){

echo '水果名字',$fruit[$i];

}

$week=range(1,7);

(2)我们都知道PHP4的面向对象是不完善的,比如说PHP4的类没有析构函数,那如果我要在PHP4中实现析构函数的功能,该如何实现?【2分】

:register_shutdown_function — Register a function for execution on shutdown。利用这个函数可以模拟PHP5中的虚构函数。

函数原型如下:void register_shutdown_function ( callback $function [, mixed $parameter [, mixed $... ]] )

(3)include()和require()函数有什么区别?可以在一个文件里多次include同一个文件吗?【2分】

:这两种结构除了在如何处理失败之外完全一样。include() 产生一个警告而require() 则导致一个致命错误。可以在一个文件里多次include同一个文件,但是会造成变量和函数重复定义的错误,后者是一个致命错误。

(4)在C语言的循环判断条件中,为了实现计数器的累加,可以有三种形式,也就是:i++,++i,i+=1.试给这三种形式计数器的速度快慢排序并解释。【假设编译器不进行自动优化3分】

1.++i要比i++快一些因为i++要在stack里面保存自增之前的i值而++i可以不用

2.i++比i+=1要快。++ 就是一个inc命令,如果编译器不优化的话,+=1 就是add eax,1

(5)已知一个MYSQL数据库中有100万条用户资料数据,现在需要随机取出10条不重复的记录,应该如何做最快最简单?【4分】

:答案一:用程序来产生10个随机数,

这10个随机数可以用在Limit中定位, 生成10条SQL

如果ID是连续(没有删除)的话, 也可以生成一条SQL, 里面有10个OR ID=随机数(4分)答案二:SELECT * FROM __TABLE__ AS t1

JOIN

(SELECT ROUND(RAND() * ((SELECT MAX(id) FROM __TABLE__)-(SELECT MIN(id) FROM __TABLE__))+(SELECT MIN(id) FROM __TABLE__)) AS id) AS t2

WHERE t1.id >= t2.id ORDER BY t1.id LIMIT 1;");

把这条语句执行10次,但有潜在问题(3分)

答案三:select * from __TABLE__ order by rand() desc limit 1 (0分)

(6)试述COOKIE和SESSION的用法和区别,以及它们之间的联系。如果浏览器关闭了,SESSION还在吗?COOKIE还在吗?【3分】

:COOKIE存储在客服端,由浏览器托管,而SESSION存储服务器端,有应用程序托管,二者都用来标记状态,是一个全局变量,但是SESSION通常需要依靠COOKIE,SESSION在第一次访问后把SESSIONID存储在了客服端,所以禁用了浏览器的COOKIE,SESSION也会影响。当然有其他办法解决这个问题。注意SESSION是不会随浏览器关闭而删除的,COOKIE也不会。

(7)定义一个抽象类student,然后由子类us继承并实现它的一个抽象方法do_homework()。【3分】abstract Class student{

Abstract function do_homework();

}

Class us extends atudent{

Public function do_homework(){

Echo ‘finished!’;

} }

(8)怎样将一个数组对象存储到数据表中的一个字段内?怎样判断传入一个函数的参数是否完整?【2分】:将数组序列化为一个字符串就可以了,serialize($array);

::func_num_args — Returns the number of arguments passed to the function

(9)不用任何函数获取文件的扩展名。【3分】

提示:字符串本身也是一个数组,配合while可以完成。

$a = 'abc.0.g/d.e.ff0.jpg';

$b = '';

$i = $k = 0;

while($a[$i] != '') {

if($a[$i++] == '.')

$k = $i;

}

// 判断该文件是否含有扩展名

if($k != 0) {

while($a[$k] != '')

$b .= $a[$k++];

}

echo "得到扩展名:".$b;

?>(10)if(strpos($str, 'a') == false) {}这个语句有什么bug?【1分】

:如果第一个字符就是a,那么函数或取得结果就是0,0==FALSE。应该使用全等判断=== (11)写出发贴数最多的十个人名字的SQL,利用下表:members(id,username,posts,pass,email)【2分】

答案略。

6.WEB页面相关技术。【考察点:HTML,CSS,JS的基础知识】

(1)利用CSS技术实现横向菜单。【兼容性要求:IE6+,FIREFOX 3+。3分】

效果图如下:

CSS:

.test ul{list-style:none;}

.test li{float:left;width:100px;background:#CCC;margin-left:3px;line-height:30px;}

.test{width:350px;}

.test a{display:block;text-align:center;height:30px;}

(2).现在有一个表格,第一列是选择框,选中需要删除的行后(要求有全选/反选功能),点击页面底部的删除按钮,则将所在行首先进行客户端无刷新删除,返回一个字符串,包含要删除的所有行的字段名(形如&del=1,3,5..)来供AJAX调用。【不要求完成AJAX部分代码,仅需要完成DOM操作和参数组合代码。兼容性要求:IE6+,FIREFOX 3+。6分】

效果图如下

核心代码如下:

(3)试说明class和id的区别。【2分】

:Class是类选择符,可以被多个元素引用,而ID是唯一的,只能被一个元素引用。在CSS中,class 的描述是.class,而ID的描述是#id.

(4)请真实实现下面的表单。【3分】

最冷的网络“流星雨”





交通

(5)现有一个表格,每行记录了一些数据,最上端有一下拉框,值为单位,现在要求按下拉框中选择的单位进行数值的转换过程。【兼容性要求:IE6+ 6分】

效果图如下:

核心函数如下:

function get_flow_unit(obj)

{

var obj=document.getElementsByName(obj)[0];

var oo=document.getElementsByName("flow_unit")[0];

if(obj== undefined) obj=oo;

for(var i=0;i

if(obj.options[i].selected == true)

{ new_flow_unit_ = obj.options[i].value;

break;

}

}

var arr =new Array();

var Table = document.getElementById("oT able")

var rows = Table.rows;

var rowCount =Table.rows.length;

for(var i=0;i

arr[i]=new Array();

for(var j=0,len=rows[i].cells.length;j

//记录原来的值,防止多次换算引起误差

rows[i].cells[j]._defaultValue = arr[i][j] = rows[i].cells[j]._defaultValue || rows[i].cells[j].innerHTML;

if(isNumber(arr[i][j])) {

rows[i].cells[j].innerHTML = (arr[i][j] * Math.pow(1024, 3 - new_flow_unit_)).toFixed(2); //保留两小数位

}

}

}

function isNumber(s)

{

var patrn=/^[-,+]{0,1}[0-9]{0,}[.]{0,1}[0-9]{0,}$/;

if (!patrn.exec(s))

return false;

return true;

}

7.算法。【本大题下所有小题不限制所用语言平台,主要考察算法技巧】

(1)组合算法【8分】

有一个数组a,有N个元素,现在要求从中找出含有m(m

本题解法较多,现在提供几个JS的实现,其他语言类似。

function quick_combine(a, m) {

var n = a.length, s = "", e = "", r = [], i, t, p, reg = /(0*)(1*)/;

for(i = 0; i < n; i++) {

s += (i < m ? 1 : 0);

e += (i < n - m ? 0 : 1);

}

r[0] = t = s;

do {

p = t.indexOf("10");

t = t.slice(0, p).replace(reg, "$2$1") + "01" + t.slice(p + 2);

r.push(t);

} while(t !== e);

return r;

}

/**

* 快速组合- 纯位移

*/

function bit_quick_combine(n, m) {

var t = (1 << n + 1) - (1 << n - m), // 故意多留一个1,免得补零

r = [], o, p1, p2;

while((o = t.toString(2).slice(1), r.push(o), p1 = o.indexOf("1"), p2 = o.indexOf("10")) >= 0){

t ^= ((p1 ? ((1 << p2) - (1 << p1) ^ (1 << p2 - p1) - 1) << 2 : 0) | 3) << n - p2 - 2;

}

return r;

}

(2)约瑟夫环(Josephus)问题。【6分】

答案一:function yuesefu($n,$m) {

$r=0;

for($i=2; $i<=$n; $i++) {

$r=($r+$m)%$i;

}

return $r+1;

}

print_r(yuesefu(3,3));

?>

也可以完全仿真模拟,代码比较长,但思路清晰。答案如下:

function getKingMokey($n, $m)

{

$monkey[0] = 0;

//将1-n只猴子顺序编号入数组中

for($i= 1; $i<= $n; $i++)

{

$monkey[$i] = $i;

}

$len = count($monkey);

//循环遍历数组元素(猴子编号)

for($i= 0; $i< $len; $i= $i)

{

$num = 0;

/*

* 遍历$monkey数组,计算数组中值不为0的元素个数(剩余猴子的个数)

* 赋值为$num,并获取值不为0的元素的元素值

*/

foreach($monkey as $key => $value)

{

if($value == 0) continue;

$num++;

$values = $value;

}

//若只剩一只猴子则输出该猴子编号(数组元素值) 并退出循环

if($num == 1)

{

echo $values;

exit;

}

/*

* 若剩余猴子数大于1($num > 1)

* 继续程序

*/

//将第$i只猴子踢出队伍(相应数组位置元素值设为0)

$monkey[$i] = 0;

//打印该猴子位置

echo $i."";

/*

* 获取下一只需要踢出队伍的猴子编号

* 在$m值范围内遍历猴子并设置$m的计数器

* 依次取下一猴子编号

* 若元素值为0,则该位置的猴子已被踢出队伍

* 若不为0,继续获取下一猴子编号,且计数器加1

* 若取得的猴子编号大于数组个数

* 则从第0只猴子开始遍历(数组指针归零) 步骤同上

* 直到计数器到达$m值* 最后获取的$i值即为下一只需要踢出队伍的猴子编号*/

//设置计数器

for($j= 1; $j<= $m; $j++)

{

//猴子编号加一,遍历下一只猴子

$i++;

//若该猴子未被踢出队伍,获取下一只猴子编号

if($monkey[$i] > 0) continue;

//若元素值为0,则猴子已被踢出队伍,进而循环取下一只猴子编号

if($monkey[$i] == 0)

{

//取下一只猴子编号

for($k= $i; $k< $len; $k++)

{

//值为0,编号加1

if($monkey[$k] == 0) $i++;

//否则,编号已取得,退出

if($monkey[$k] > 0) break;

}

}

//若编号大于猴子个数,则从第0只猴子开始遍历(数组指针归零) 步骤同上

if($i == $len) $i = 0;

//同上步骤,获取下一只猴子编号

if($monkey[$i] == 0)

{

for($k= $i; $k< $len; $k++)

{

if($monkey[$k] == 0) $i++;

if($monkey[$k] > 0) break;

}

}

}

}

}

//猴子个数

$n = 10;

//踢出队伍的编号间隔值

$m = 3;

//调用猴王获取函数

getKingMokey($n, $m);

8.其他【考察点:E文和综合分析能力】。

(1)翻译下面的英文。【2分】

Note the missing concatenation operator between the two strings leads to the whitespace error that is so named above. The concatenation operator instructs PHP to ignore the whitespace between the two code tokens (the so named "encapsed" data"), rather than parse it as a token itself.

中英文翻译小意思我就不动手了

(2)翻译下面的中文。【2分】

大多数函数都带有自己的属性以便于明确说明或者修改他们的行为,smarty函数的属性很像HTML中的属性. 静态数值不需要加引号,但是字符串建议使用引号. 如果用变量作属性,它们也不能加引号.

中英文翻译小意思我就不动手了

(3)名词解释。【每个1分】

--Comet:

这个大家都会的,不说了。

--Curl:

--Pdo:

--Factory:

--依赖注入:

--Opcode

--CURD:

(4)农民养一头猪,需要花费半年时间,每天都耗费大量的精力,实际上算上劳动力的话,不赚反亏,可农民朋友们为什么还要坚持养猪?【4分】

(1)猪对于农民就是个银行的功能,把平时的零散积蓄起来。

(2)养猪可以消化剩饭剩菜,不至于浪费。

(3)猪的粪便可以作为农家肥,这也是个重要原因。

(4)农民本身的成本意识就不够强。

(5)自由发挥…..

相关主题
相关文档
最新文档