腾讯php面试题之 - PHP开发工程师笔试试卷

一、PHP开发部分

1.合并两个数组有几种方式,试比较它们的异同

答:

1、array_merge()

2、’+’

3、array_merge_recursive

array_merge 简单的合并数组

array_merge_recursive 合并两个数组,如果数组中有完全一样的数据,将它们递归合并

array_combine 和 ‘+’ :合并两个数组,前者的值作为新数组的键

2.请写一个函数来检查用户提交的数据是否为整数(不区分数据类型,可以为二进制、八进制、十进制、十六进制数字)

答:其实主要还是is_int和 floor 这个方法


if(!is_numeric($jp_total)||strpos($jp_total,".")!==false){  

    echo "不是整数";  

}else{  

    echo "是整数";  

}

3.PHP的strtolower()和strtoupper()函数在安装非中文系统的服务器下可能会导致将汉字转换为乱码,请写两个替代的函数实现兼容Unicode文字的字符串大小写转换

答:原因是:中文是由多字节组成的,而只有英文系统的单个英文字符只有一个字节,所以该系统把中文的每一个字节都做了strtolower()处理,改变后的中文字节拼接在一起就成了乱码(新生成的编码映射对应的字符可能就不是中文了)

手动解决:用str_split(string string,intstring,intsplit_length = 1)按每个字节切割,像中文能切割成三个字节。对识别到的字节若是英文字母则进行转换。

<?php  

function mystrtoupper($a){  

    $b = str_split($a, 1);  

    $r = '';  

    foreach($b as $v){  

        $v = ord($v);  

        if($v >= 97 && $v<= 122){  

            $v -= 32;  

        }  

        $r .= chr($v);  

    }  

    return $r;  

}  


$a = 'a中你继续F@#$%^&*(BMDJFDoalsdkfjasl';  

echo 'origin string:'.$a."\n";  

echo 'result string:';  

$r = mystrtoupper($a);  

var_dump($r);

4.PHP的is_writeable()函数存在Bug,无法准确判断一个目录/文件是否可写,请写一个函数来判断目录/文件是否绝对可写

答:其中bug存在两个方面,

  • 1、在windowns中,当文件只有只读属性时,is_writeable()函数才返回false,当返回true时,该文件不一定是可写的。

如果是目录,在目录中新建文件并通过打开文件来判断;

如果是文件,可以通过打开文件(fopen),来测试文件是否可写。

  • 2、在Unix中,当php配置文件中开启safe_mode时(safe_mode=on),is_writeable()同样不可用。

读取配置文件是否safe_mode是否开启。

/**

* Tests for file writability

*

* is_writable() returns TRUE on Windows servers when you really can't write to

* the file, based on the read-only attribute. is_writable() is also unreliable

* on Unix servers if safe_mode is on.

*

* @access   private

* @return   void

*/

if ( ! function_exists('is_really_writable'))

{

    function is_really_writable($file)

    {

    // If we're on a Unix server with safe_mode off we call is_writable

    if (DIRECTORY_SEPARATOR == '/' AND @ini_get("safe_mode") == FALSE)

    {

        return is_writable($file);

    }



    // For windows servers and safe_mode "on" installations we'll actually

    // write a file then read it. Bah...

    if (is_dir($file))

    {

        $file = rtrim($file, '/').'/'.md5(mt_rand(1,100).mt_rand(1,100));



        if (($fp = @fopen($file, FOPEN_WRITE_CREATE)) === FALSE)

        {

            return FALSE;

        }



        fclose($fp);

        @chmod($file, DIR_WRITE_MODE);

        @unlink($file);

        return TRUE;

    } elseif ( ! is_file($file) OR ($fp = @fopen($file, FOPEN_WRITE_CREATE)) === FALSE) {

        return FALSE;

    }



    fclose($fp);

    return TRUE;

    }

}

5.PHP的chmod()函数存在Bug,无法保证设置成功,请写一个函数在指定路径下创建一个目录/文件并确保可以正确设置权限掩码

答:我也找不到答案

6.PHP处理上传文件信息数组中的文件类型$_FILES[‘type’]由客户端浏览器提供,有可能是黑客伪造的信息,请写一个函数来确保用户上传的图像文件类型真实可靠

答:用getimagesize来判断上传图片的类型比$_FILES函数的type更可靠

同一个文件,使用不同的浏览器php返回的type类型是不一样的,由浏览器提供type类型的话,

就有可能被黑客利用向服务器提交一个伪装撑图片后缀的可执行文件。

可以通过getimagesize()函数来判断上传的文件类型,如果是头像文件 会返回这样的一个数组

Array(

    [0] => 331

    [1] => 234

    [2] => 3

    [3] => width="331" height="234"

    [bits] => 8

    [mime] => image/png

);

如果通过getimagesize()函数返回的是这样的一个数组 说明上传的是头像文件。其中索引为2的表示类型

1 = GIF,2 = JPG,3 = PNG,4 = SWF,5 = PSD,6 = BMP,7 = TIFF(intel byte

order),8 = TIFF(motorola byte order),9 = JPC,10 = JP2,11 = JPX,12 =

JB2,13 = SWC,14 = IFF,15 = WBMP,16 = XBM,

你可以通过这个再去限制上传的头像类型

<?php

    $file=$_FILES['file'];

    if(!empty($file))

    {

        var_dump($file);

        var_dump(getimagesize($file["tmp_name"]));

    }   

?>

7.PHP通过对数据的URL编码来实现与Javascript的数据交互,但是对于部分特殊字符的编解码与Javascript的规则不尽相同,请具体说明这种差异,并针对UTF-8字符集的数据,写出PHP的编解码函数和Javascript的编解码函数,确保PHP编码数据可以被Javascript正确解码 、Javascript编码的数据可以被PHP正确解码

答:

<?php

 $str = '思源博客siyuantlw/tlw/sy/俺只是一个打酱油的';

 $str = iconv("GB2312",'UTF-8',$str);

 $str = urlencode($str); 

?>
//js  decodeURIComponent   貌似对GB2312编码的格式不识别,必须转为utf-8才可以,然后,如果字符串中有空格的  就转为 +  号了

<html>

 <script>

  var ds = '<?php echo $str;?>';

  var dddd= decodeURIComponent (ds);

  alert(dddd);

 </script>

</html>

8.试阐述Memcache的key多节点分布的算法?当任一节点出现故障时PHP的Memcache客户端将如何处置?如何确保Memcache数据读写操作的原子性?

答:

原理:一致性hash

原子性

原子性会导致的问题:简单的说就是A,B都想操作key1,然后都在key1上增加自己的信息,就会有问题

memcached是原子的吗?

宏观

所有的被发送到memcached的单个命令是完全原子的。如果您针对同一份数据同时发送了一个set命令和一个get命令,它们不会影响对方。它们将被串行化、先后执行。即使在多线程模式,所有的命令都是原子的;命令序列不是原子的。如果您通过get命令获取了一个item,修改了它,然后想把它set回memcached,我们不保证这个item没有被其他进程(process,未必是操作系统中的进程)操作过。在并发的情况下,您也可能覆写了一个被其他进程set的item。

memcached 1.2.5以及更高版本,提供了gets和cas命令,它们可以解决上面的问题。如果您使用gets命令查询某个key的item,memcached会 给您返回该item当前值的唯一标识。如果您覆写了这个item并想把它写回到memcached中,您可以通过cas命令把那个唯一标识一起发送给 memcached。如果该item存放在memcached中的唯一标识与您提供的一致,您的写操作将会成功。如果另一个进程在这期间也修改了这个 item,那么该item存放在memcached中的唯一标识将会改变,您的写操作就会失败。

9.如何实现PHP的安全最大化?怎样避免SQL注入漏洞和XSS跨站脚本攻击漏洞?

答:基本原则:不对外界展示服务器或程序设计细节(屏蔽错误),不相信任何用户提交的数据(过滤用户提交)

1、1 屏蔽错误,将display_errors 设置为off

2、 过滤用户提交参数,这里需要注意的是不能仅仅通过浏览器端的验证,还需要经过服务器端的过滤

这里是需要注意最多的地方,因为所有用户提交的数据入口都在这里,这是过滤数据的第一步。

  • 1 考虑是否过滤select,insert,update,delete,drop,create等直接操作数据的命令语句

  • 2 使用addslashes 将所有特殊字符过滤

  • 3 打开magic_quotes_gpc,开启该参数数后自动将sql语句转换,将 ' 转换成 '

3、 可以考虑设置统一入口,只允许用户通过指定的入口访问,不能访问未经许可的文件等内容

4、可以考虑对安全性要求高的文件进行来源验证,比如要想执行b.php必须先执行a.php,可以在b.php中判断来自a.php的referer,避免用户直接执行b.php

10.请设计一个数据结构可以实现无限级子菜单的树型菜单功能并提供菜单生成算法,用UML描述设计并写出相关PHP代码

答:还没找到答案

试题二:

1、请列举你能想到的UNIX信号,并说明信号用途。

答:

Unix信号量也可以在文件/usr/include/sys/signal.h中查看

SIGHUP 进程由於控制终端死去或者控制终端发出起命令

SIGINT 键盘中断所产生的信号

SIGQUIT 键盘终止

2、请列举、你能想到的所有的字符串查找算法,并加注释简单说明。

答:

1 顺序查找

2 二分查找

3 分块查找

4 哈希表查找

3、有一个IP地址(192.168.0.1),请写出其32位无符号整数形式。

答:此题是将十进制转换成二进制 采用取余法即可很简单 答案是:11000000.10101000.00000000.00000001 千万不能只记答案哦

4、写出、你能想到的所有HTTP返回状态值,并说明用途(比如:返回404表示找不到页面)

答:

200 (成功) 服务器已成功处理了请求。 通常,这表示服务器提供了请求的网页。

301 (永久移动) 请求的网页已永久移动到新位置。 服务器返回此响应(对 GET 或 HEAD 请求的响应)时,会自动将请求者转到新位置。

302 (临时移动) 服务器目前从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求。

401 (未授权) 请求要求身份验证。 对于需要登录的网页,服务器可能返回此响应。

403 (禁止) 服务器拒绝请求。

404 (未找到) 服务器找不到请求的网页。

500 (服务器内部错误) 服务器遇到错误,无法完成请求。

501 (尚未实施) 服务器不具备完成请求的功能。 例如,服务器无法识别请求方法时可能会返回此代码。

502 (错误网关) 服务器作为网关或代理,从上游服务器收到无效响应。

503 (服务不可用) 服务器目前无法使用(由于超载或停机维护)。 通常,这只是暂时状态。

504 (网关超时) 服务器作为网关或代理,但是没有及时从上游服务器收到请求。

505 (HTTP 版本不受支持) 服务器不支持请求中所用的 HTTP 协议版本。

基础任务-选作(会得到额外分数):

1、画几个你最熟悉的SERVER端模型出来(格式不重要,尽量将图画清楚,说明思路即可)

进阶任务:

1、PHP的垃圾收集机制是怎样的?

说明:

1)如果,你熟悉PHP源码,那么请从源码入手,回答些问题,会获得额外加分

2)如果,你不熟悉PHP源码,那么尽你所能,多写点东西,包括利用自己的编程直觉得到的信息,都可以。

3)对,则有分,错误不扣,不写无分。

答:PHP可以自动进行内存管理,清除不再需要的对象。PHP使用了引用计数(referencecounting)这种单纯的垃圾回收(garbagecollection)机制。每个对象都内含一个引用计数器,每个reference连接到对象,计数器加1。当reference离开生存空间或被设为NULL,计数器减1。当某个对象的引用计数器为零时,PHP知道你将不再需要使用这个对象,释放其所占的内存空间。

2、请写出HTTP头,并符合以下要求:

1)这是一个post请求

2)目标:http://www.example.com:8080/test

3)POST变量:

username: test

pwd: test2

intro: Hello world!

4)包含以下COOKIE信息:

cur_query: you&me

说明:

1)如果,你记不得某个HTTP协议中的指令字了,那么,无奈这举是用“汉字”代替。

2)如果,你能记住更多的HTTP协议指令字,那么多写几句,总是没坏处,对吧?

3)最关键的,只需要画出正确的“轮廓”(还记得httpwatch等工具打印出来的头部吗?那就是“轮廓”的含义),也会有分数,但如果,连“轮廓”都写错了,那么就很遗憾了。

答:

Accept: text/html 可以接受的数据类型

Accept-Encoding: gzip 接受的压缩类型

Accept-Language: zh-CN 接受语言

Cache-Control: no-cache 是否有缓存

Connection : keep-alive 是否保持链接

Host:http://www.example.com:8080/test

Cookie:intro=Hello world!

Content-Disposition: form-data; username=”test”&pwd=”test2”&intro=”hello world!”

User-Agent: 浏览器信息

Referer: 前一个页面地址

设计任务:

1、最近总有人骚扰我们的投票模块,需要你来设计一个投票限制的东东

要求如下:

1)要求每个QQ号码(假设此QQ号码在UNIT32内可以表示)10分钟这内只能投5票。

2)我们的用户很踊跃,平均每天要有2000万人左右通过此程序投票。

说明:

1)无需写代码,只需要图跟文字即可。

2)对于关键逻辑,请用图加代码表示出来,这也是对你文字表达能力的一个考验。

3)对你能想到的所有的边界条件列出来,这是对你逻辑思维全面与敏捷性的考验。

4)存储部分,尽你所能吧。如果,你需要一个自己设计的存储层,那么把这个存储层的实现,用文字+图片方式描述清楚,要是设计合理,你会获得华丽的奖分。

答:找了好久终于找到个大神的回答:打字太累了 就截图了