二、填空题2. 如果使用appserv环境包,那么发布PHP的文件夹在______。
WampServer/www文件夹。
[解析] 因为系统默认保存在WampServer/www文件夹里。
3. 访问类中静态成员或函数应通过特殊类______或______进行访问。
4. ______提供了一个高性能的解决面向对象中重复出现的问题的方案?
面向对象。
[解析] 面向对象提高了代码的重用性和灵活性,使代码的结构更加清晰。
5. ______操作符在两个操作数中有一个(不是全部)为true时返回true。
逻辑异或(xor)运算符。
[解析] 如果$a或$b任一为true,另一为false时,那么返回true。
三、简答题1. 面向对象的开发方式有什么优点?
采用面向对象的开发方式有诸多的优点,下面主要介绍其中三个优点:
1)较高的开发效率(灵活性)。采用面向对象的开发方式,可以对现实的事物进行抽象,把现实的事物直接映射为开发的对象,与人类的思维过程相似。例如,可以设计一个Car类来表示现实中的汽车,这种方式非常直观明了,也非常接近人们的正常思维。同时,由面向对象的开发方式可以通过继承或者组合的方式来实现代码的重用,因此可以大大地提高软件的开发效率。
2)保证软件的鲁棒性(重用性)。正是由于面向对象的开发方法有很高的重用性,在开发的过程中可以重用已有的而且在相关领域经过长期测试的代码,所以,自然而然地对软件的鲁棒性起到了良好的促进作用。
3)保证软件的高可维护性(扩展性)。采用面向对象的开发方式,使得代码的可读性非常好,同时面向对象的设计模式也使得代码结构更加清晰明了。同时针对面向对象的开发方式,已有许多非常成熟的设计模式,这些设计模式可以使程序在面对需求的变更时,只需要修改部分的模块就可以满足需求,因此维护起来非常方便。
2. HTTP的Keep-Alive作用是什么?
HTTP的Keep-Alive作用如下:Keep-Alive使客户端到服务器端的连接持续有效,当出现对服务器的后继请求时,Keep-Alive功能避免了建立或者重新建立连接。Web服务器基本上都支持HTTP Keep-Alive。
缺点:对于提供静态内容的网站来说,这个功能通常很有用。但是,对于负担较重的网站来说,虽然为客户保留打开的连接有一定的好处,但它同样影响了性能,因为在暂停使用的期间,本来可以释放的资源仍旧被占用。所以当Web服务器和应用服务器在同一台机器上运行时,Keep-Alive功能对资源利用的影响尤其突出。
解决:Keep-Alive:timeout=5,max=100
timeout:过期时间5s(对应httpd.conf里的参数是KeepAliveTimeout),max是最多请求100次,强制断掉连接。在timeout时间内又有新的连接过来时,max会自动减1,直到为0时,强制断掉。
3. PHP缓存技术有哪些?框架ThinkPHP是局部缓存还是完全缓存?
PHP的缓存技术主要有以下几种:
1)全页面静态化缓存技术。即将页面全部生成为HTML静态页面,当用户访问时直接访问静态页面,而不用去执行PHP服务器解析。
2)页面部分缓存技术。即在一个页面中把不经常变化的部分进行静态缓存,而经常变化的模块不缓存,然后将它们组装在一起,可以提高页面的访问速度。
3)数据缓存技术。通过ID请求的数据,先将数据缓存到一个文件中,然后将ID和文件进行对应,可以通过这个ID请求直接读这个文件,进而提高数据的加载速度。
4)查询缓存技术。它和数据缓存类似,主要根据查询语句的数据内容进行缓存存储,当再次查询相同内容时,可以直接读取对应的存储数据。
除了PHP自身存在的以上4种缓存技术外,开发中常用的缓存工具主要有。Memcache和Redis。
框架ThinkPHP主要使用完全缓存技术,当把框架中每一个方法取出的数据分配到视图中使用时,将自动在缓存文件夹中生成一个缓存文件,当页面再次请求这个方法时,会直接加载缓存文件,如果有数据变化,那么会重新读取方法再次更新缓存文件。
4. 什么是抽象类和接口?抽象类和接口有什么不同和相似的地方?
被关键字abstract修饰的类叫作抽象类,抽象类是不能被实例化的。被abstract修饰的方法为抽象方法,一个类只要有一个抽象方法,这个类一定是抽象类。
接口是通过关键字interface来定义的,可以指定某个类必须实现哪些方法,但不需要定义这些方法的具体实现。PHP类只支持单重继承,但通过接口可以实现PHP类的多重继承。
抽象类和接口的不同和相似的地方如下:
1)抽象类是一种不能被实例化的类,只能作为其他类的父类来使用。
2)抽象类是通过关键字abstract来声明的。
3)抽象类与普通类相似,都包含成员变量和成员方法,两者的区别在于,抽象类中至少要包含一个抽象方法。
4)抽象方法没有方法体,该方法天生就是要被子类重写的。
5)抽象方法的格式为abstract function abstractMethod();。
6)因为PHP中只支持单重继承,所以如果想实现多重继承,那么就要使用接口。也就是说,子类可以实现多个接口。
7)接口类是通过interface关键字来声明的,接口类中的成员变量和方法都是public的,可以不用显式地使用public来修饰。
8)接口中的方法没有方法体。接口中的方法天生就是要被子类继承实现的。
9)子类继承抽象类使用extends关键字,子类实现接口使用implements关键字。
5. 请描述出OSI七层网络模型的名称。
OSI参考模型将复杂的协议分成了7层(见下表),每一层各司其职,并且能独立使用,这相当于软件中的模块化开发,有较强的扩展性和灵活性。分层是一种管理哲学,将同一类功能的网络协议分到一层中,使协议变得灵活可控。
层
|
功 能
|
应用层
|
为应用程序提供服务并管理应用程序之间的通信,常用的协议有SMTP、FTP、HTTP等
|
表示层
|
负责数据的格式转换、加密与解密、压缩与解压
|
会话层
|
负责建立、管理和断开通信连接,实现数据同步
|
传输层
|
为数据提供可靠的或不可靠的端到端传输,同时处理传输错误、控制流量,TCP和UDP协议就属于该层
|
网络层
|
负责地址管理、路由选择和拥塞控制,该层最知名的是IP协议
|
数据链路层
|
将数据分割成帧,并负责MAC寻址、差错检验和信息纠正,以太网属于这一层
|
物理层
|
管理最基础的传送通道,建立物理连接,并提供物理链路所需的机械、电气、功能和过程等特性
|
四、编程题1. 写出创建一个数组变量$add的程序代码,其中有三个值分别为“中国”“黑龙江”“哈尔滨”。
1)请写出在数组变量$add中添加“江北”“学院路”两个值的程序代码。
2)请写出统计数组变量$add中条数的程序代码。
3)请写出遍历数组变量$add的程序代码,要求输出数组中的键名和键值。
根据题意$add数组代码为$add=array('中国','黑龙江','哈尔滨')。
1)添加题目中的两个值的代码为array_push($add,"江北","学院路")。
2)可以使用count()函数统计数组中的条数。
代码为
<?php
$len=count($add);
echo $len;
?>
程序的运行结果为5。
3)可以使用foreach()函数对$add数组进行遍历。
代码为
<?php
foreach($add as $k=>$val){
echo $k."=>".$val.",";
}
?>
程序的运行结果为0=>中国,1=>黑龙江,2=>哈尔滨,3=>江北路,4=>学院路。
2. 请编写一个方法,计算数组中最大数和最小数的差。
计算数组中最大数与最小数的差有以下两种方法。
1)使用max()和min()函数求最大值和最小值,再求差值。
代码实现为
<?php
function maximum($arr){
$result=max($arr)-min($arr);
return $result;
}
$arr=array(100,80,10);
echo maximum($arr);
?>
程序的运行结果为90。
2)对数组进行排序后,再对首尾值求差。
①使用sort()函数把数组按升序排序,然后求差。
代码实现为
<?php
function maximum($arr){
sort($arr);
$len=count($arr)-1;
$result=$arr[$len]-$arr[0];
echo $result;
}
$arr=array(100,20,10);
echo maximum($arr);
?>
程序的运行结果为90。
需要注意,数组的长度为3,但是下标是从0开始的,所以取数组最后一位需要数组长度减1。
②使用rsort()函数把数组按降序排序,然后求差。
代码实现为
<?php
function maximum($arr){
rsort($arr);
$len=count($arr)-1;
$resutt=$arr[0]-$arr[$len];
return $result;
}
$arr=array(100,20,10);
echo maximum($arr);
?>
程序的运行结果为90。
对以上的每个程序使用microtime()函数来判断执行效率,1)的执行效率最高,其次是2),而①、②的执行效率相同。因为1)中max()函数和min()函数是PHP内置函数,可以快速求解出最大、最小值(求最大值和最小值最差的时间复杂度为O(n)),而方法2)使用了排序算法,最好的排序算法的时间复杂度为O(nlogn),所以1)的执行效率最高。
3. 假设某人有100000元现金。每经过一次路口需要进行一次交费。交费规则为当他现金大于50000元时每次需要交5%,如果现金小于等于50000元时每次交5000。请编写一程序计算此人可以经过多少次这个路口。
初始条件为某人拥有的总现金为100000元,初始过桥次数为0,当金额条件不满足5000元时,则停止过桥。所以可以通过循环求过桥次数,当现金大于50000元时,剩余金额为总金额*(1-5%),当现金小于50000元时则剩余金额为总金额-5000,依次循环累加过桥次数,直到不符合条件退出循环。
实现代码为
<?php
for($sum=100000,$num=0;$sum>=5000;){
if($sum>=50000){
$sum=0.95*$sum;
}else{
$sum=$sum-5000;
}
$num++;
}
echo $num;
?>
程序的运行结果为
23
4. 一群猴子排成一圈,按1,2,…,n依次编号。然后从第1只开始数,数到第m只,把它踢出圈,从它后面再开始数,再数到第m只,再把它踢出去,…,如此不停地进行下去,直到最后只剩下一只猴子为止,那只猴子就称为大王。要求编程模拟此过程,输入m、n后输出最后那个大王的编号。
首先将猴子从1到n编号存放在数组中,对猴子的总个数进行循环,循环时将数到编号的猴子从数组删除,将没有数到编号的猴子从原位置移到数组末尾,移动后需将原位置的编号删除。只要判断该编号数组个数大于1就继续循环,直到数组最后只剩下一个编号,那么这个编号就是当大王的猴子。
实现代码为
<?php
function monkeyKing($n,$m){
$monkeys=range(1,$n);
$i=0;
$k=$n;
while(count($monkeys)>1){
if(($i+1)%$m==0){
unset($monkeys[$i]);
}else{
array_push($monkeys,$monkeys[$i]);
unset($monkeys[$i]);
}
$i++;
}
return current($monkeys);
}
$monkey=monkeyKing(5,2);
echo"最后当王的猴子编号是:".$monkey;
?>
程序的运行结果为
最后当王的猴子编号是:3