首页 > 程序人生 > 程序员面试技艺 > 淘宝PHP笔试题及答案解析
2014
11-11

淘宝PHP笔试题及答案解析

问题一:新浪微博首页你和他共同关注的人功能实现,用于存储人这个信息的方法是什么?

1)可以使用redis的set方式存储,使用sinter命令返回交集。
2)可以使用PHP的array_intersect函数实现。

问题二:PHP静态类的特性?

1)被声明为静态类的类不允许包含任何非静态成员
2)抽象静态类中的静态方法不允许调用,它必须先被继承。
3)在静态类中,允许抽象的静态方法。(莫名其妙?)
4)静态类不允许含有 构造函数、析构函数、动态拦截函数(本人理解为魔术函数)以及 __toString()。
5)静态类不允许继承自非静态类。
6)为了向下兼容,目前含有静态成员的抽象类/非静态类的行为不会被改变。
7)在抽象类中添加 __setStatic() 以及 __getStatic() 以代替 __get() 、 __set()。
8)静态类不能被实例化
9)静态类可以实现自只包含静态方法的接口

扫盲:所谓静态类指的是无需实例化成对象,直接通过静态方式调用的类。代码如下:

<?php
class Math
{
    public static function ceil($value)
    {
        return ceil($value);
    }
    public static function floor($value)
    {
        return floor($value);
    }
}
?>

此时类所扮演的角色更像是命名空间,这或许是很多人喜欢使用静态类最直接的原因。

问题三:用PHP以及shell或者perl写出从access_log中查找出最多访问IP的方法。

PHP代码如下

function new_sort($a,$b){
    if ($a == $b) return 0;
    return ($a>$b) ?-1:1;
}
$pattern='/[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}/';
if($file = file_get_contents("/var/log/httpd/access_log"))
{
    if(preg_match_all($pattern, $file, $matches))
    {
        $result = array_count_vaules($matches[0]);
        uasort($result,"new_sort");
        print_r($result);
    }else{
        echo "match failed!"
    }
}else{
    echo "open file failed!!";
}

Perl代码如下:

#!/usr/bin/perl -w
open(ACCESS,'/var/log/httpd/access_log');
@log = <ACCESS>;
foreach $word (@log){
    $word =~ /\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/;
    $match = $&;
    $matchlist{$match} +=1;
}
@sorted = map {{($_=>$matchlist{$_})}}
sort {$matchlist{$a} cmp $match{$b} or $a cmp $b} keys %matchlist;
foreach $cap (keys(%matchlist)){
    ($key,$value) = each %$cap;
    print("$key => $value\n");
}
close(ACCESS);

直接命令实现:

awk -F' ' '{print $1}' /var/log/httpd/access_log | uniq -c | sort -nr

问题四:PHP获取网页内容的方法

1)file_get_contents: 将整个文件读入一个字符串。
2)curl:流程为curl_init();curl_setopt();curl_exec();curl_close();

<?php
    $url = "http://www.jb51.net";
    $ch = curl_init();
    $timeout = 5;
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
    //在需要用户检测的网页里需要增加下面两行
    //curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
    //curl_setopt($ch, CURLOPT_USERPWD, US_NAME.":".US_PWD);
    $contents = curl_exec($ch);
    curl_close($ch);
    echo $contents;

3)fopen->fread->fclose:实现类似file_get_contents,通过打开远程文件并读取

其中 fopen和file_get_contents需要开启php.ini中的allow_url_fopen选项,Curl需要开启curl选项。

4)经rtxbc提醒,知道了其实常用的是socket方法抓取网页内容

找到了一段示例代码如下:

{
    $fp = fsockopen($host, 80) or die("Open ". $url ." failed");
    $header = "GET /".$url ." HTTP/1.1\r\n";
    $header .= "Accept: */*\r\n";
    $header .= "Accept-Language: zh-cn\r\n";
    $header .= "Accept-Encoding: gzip, deflate\r\n";
    $header .= "User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; Maxthon; InfoPath.1; .NET CLR 2.0.50727)\r\n";
    $header .= "Host: ". $host ."\r\n";
    $header .= "Connection: Keep-Alive\r\n";
    //$header .= "Cookie: cnzz02=2; rtime=1; ltime=1148456424859; cnzz_eid=56601755-\r\n\r\n";

问题五:Memcache和memcached的区别,缓存的时间应该怎么设置?

memcached中有getmulti和setmulti,很实用,而且还有很多方法是memcache没有的,因此可以理解为memcache的升级版。

问题六:Redis有哪些存储类型,各有什么特点

具体类型包括strings, list, set, sorted set, hash

问题七:Node.js的特性,什么是异步?

异步,事件驱动,非阻塞。

异步的特点就是一个调用者发出一个请求之后不需要马上得到结果,而是等待处理者得出结果集之后返回给调用者,和同步的你说完我再说概念不同。

事件驱动是javascript的特性,当一个动作触发之后驱动一个事件,可以是多对多的关系,也就是说多个动作驱动多个事件。

非阻塞是node.js的一个新特性,传统编程语言是面向过程的流程,也就是上面的操作没完成,下面的操作会阻塞在那里等待操作完成。而node.js的特点就是非阻塞,用下面的例子来说明

$file = fopen("/etc/file",r+);
$contents = fread($file,filesize("/etc/file"));
fclose();
echo "this will not display";

文件读写没完成的时候,echo不会输出,但是在node.js的特性中就不一样了,看下面的代码:

require("fs")

fs.readFile('/etc/filename','UTF-8',function(err,date){
    if(err) throw err;
    console.log(date);
});

console.log("running");

这个程序中,读取文件的操作没有影响console.log输出running,而date需要文件读取完毕再输出,两者不阻塞。

编程技巧