2011-03-31

史上最强大的PHP Web面试题(会做就能进百度)

Views: 71826 | 58 Comments

注: 只要你会做了这道题目, 你的能力已经可以进入百度了! 如果别的部门不要你, 请你给我发邮件, 我一定尽我所能强烈推荐你! 如果你不想加入百度, 而别的公司又不要你, 只能说明那家公司瞎眼了.

题目: 见图片, 该图是某网页的一个区域的截图, 用于显示商品或者其它信息的分类. 该分类的每一项可以折叠和收起(展开和收缩, 如果有子分类的话). 分类的级数不固定. 现有一个PHP变量:

$cats = array(
    array(
        'id' => 1,
        'name' => '学术和教育',
        'children' => array(
            array(
                'id' => 2,
                'name' => '自然科学',
                'children' => null,
            ),
            // ...
        ),
    ),
    // ...
);

请写一段PHP代码, 将该数组所包含的分类数据生成一段能实现如图片所示功能的HTML/JavaScript代码, 可不考虑CSS样式.

----------

注解: 这道题目考察的范围非常广, 包括PHP, HTML, JavaScript, CSS, 递归, 只有真正掌握了如上几种全部技能, 才能实现完整的功能, 否则必须依赖分工. 应聘者所能实现的程度越大, 得分就越高.

如果应聘者的应聘职位不包括HTML/JS/CSS, 那么题目可改为: 把上面的PHP数据用缩进换行文本的形式保存到文件, 并读取文件生成一个同样的PHP数组.(自定义格式的序列化和反序列化)

看到这篇日志的读者, 如果已经做了出来, 并且个人想加入百度, 请在评论中回复URL并说明你的意愿, 我会主动联系你. 或者你可以把程序打包发给我.


----------

你想加入百度吗?

  查看结果

Loading ... Loading ...

Related posts:

  1. 史上最强大的PHP MySQL操作类
  2. 最简单的JavaScript两级联动示例
  3. 程序员薪水调查 – 80%月薪不超过10K
  4. JavaScript+jQuery两栏选择控件
  5. 如何让 PHP json_encode 函数不转义中文?
Posted by ideawu at 2011-03-31 16:57:24 Tags:

58 Responses to "史上最强大的PHP Web面试题(会做就能进百度)"

  • 就这题,就能加入百度? Reply
    @illegaluid: 首先,你要看清楚,这个题目是2011年的 Reply
  • function getTree($cats){
    $str.="<ul>";
    foreach($cats as $item){
    $str.="<li><span>".$item['name']."</span>";
    if($item['children'])
    $str.=getTree($item['children']);
    $str.='</li>';
    }
    $str.="</ul>";
    return $str;
    }

    如果要实现点击隐藏和显示字内容,加入一下两行jquery代码即可
    $("span").click(function(){
    $(this).siblings(‘ul’).toggle();
    }); Reply
  • <?php
    /**
    * 无限级(受尾节点描述算法限制, 详见tree_parse注释)递归菜单
    * author: selfimpr
    * blog: http://blog.csdn.net/lgg201
    * mail: lgg860911@yahoo.com.cn
    */

    define(‘MAX_NODES’, 3); /* 最大子节点数 */
    define(‘MAX_NODE_INDEX’, MAX_NODES – 1); /* 子节点最大索引值 */
    define(‘NAME_FMT’, ‘name-%08d’); /* 节点内容输出格式串 */

    /* 树节点数据结构 */
    define(‘K_ID’, ‘id’);
    define(‘K_NAME’, ‘name’);
    define(‘K_CHILD’, ‘children’);

    /* 输出构造时使用的拼装字符 */
    define(‘PREFIX_TOP’, ‘┏’); /* 第一层第一个节点的标识符 */
    define(‘PREFIX_BOTTOM’, ‘┗’); /* 每一个父节点的最后一个子节点的标识符 */
    define(‘PREFIX_MIDDLE’, ‘┠’); /* 所有非上面两种情况的节点的标识符 */
    define(‘PREFIX_LINE’, ‘┇’); /* 祖先节点的连线符 */
    define(‘SPACE’, ‘ ‘); /* 空白占位(所有尾节点不显示连线符) */
    define(‘WIDE_SPACE’, str_repeat(SPACE, 4)); /* 宽的空白占位, 为了让树的层次清晰 */


    /**
    * data_build
    * 构造一个节点
    * @param mixed $id 节点id
    * @param mixed $is_leaf 是否叶子
    * @access public
    * @return void
    */
    function node_build($id, $is_leaf = FALSE) {
    return array(
    K_ID => $id,
    K_NAME => sprintf(NAME_FMT, $id),
    K_CHILD => $is_leaf ? NULL : array(),
    );
    }
    /**
    * tree_build
    * 构造一棵树(树中每个节点的子节点数由MAX_NODES确定)
    * @param mixed $datas 要返回的树引用
    * @param mixed $id 起始ID
    * @param mixed $level 树的层级
    * @access public
    * @return void
    */
    function tree_build(&$datas, &$id, $level) {
    if ( $level < 1 ) return ;
    $is_leaf = $level == 1;
    $i = -1;
    $next_level = $level – 1;
    while ( ++ $i < MAX_NODES ) {
    $data = node_build($id ++, $is_leaf);
    if ( !$is_leaf )
    tree_build($data[K_CHILD], $id, $next_level);
    array_push($datas, $data);
    }
    }

    /**
    * node_str
    * 输出一个节点自身的信息
    * @param mixed $string 返回结果的字符串(引用传值)
    * @param mixed $data 节点数据
    * @access public
    * @return void
    */
    function node_str(&$string, $data) {
    $string .= sprintf(‘ %s[%d]‘, $data[K_NAME], $data[K_ID]);
    }
    /**
    * node_sign
    * 输出一个节点的标志符号
    * @param mixed $string 返回结果的字符串(引用传值)
    * @param mixed $level 当前深度
    * @param mixed $i 当前节点在父节点中的索引(下标)
    * @access public
    * @return void
    */
    function node_sign(&$string, $level, $i) {
    switch ( $i ) {
    case 0:
    $string .= $level == 0 ? PREFIX_TOP : PREFIX_MIDDLE;
    break;
    case MAX_NODE_INDEX:
    $string .= PREFIX_BOTTOM;
    break;
    default:
    $string .= PREFIX_MIDDLE;
    break;
    }
    }
    /**
    * node_prefix
    * 输出一个节点的前缀
    * @param mixed $string 返回结果的字符串(引用传值)
    * @param mixed $level 当前深度
    * @param mixed $is_last 当前节点(含)所有祖先节点是否尾节点标记
    * @access public
    * @return void
    */
    function node_prefix(&$string, $level, $is_last) {
    if ( $level > 0 ) {
    $i = 0;
    /* 前缀格式: "父级连线" ["宽空白符" "父级连线" ...] "宽空白符" */
    $string .= ($is_last & 1 << ($level – $i) ? SPACE : PREFIX_LINE);
    while ( ++ $i < $level )
    $string .= WIDE_SPACE . ($is_last & 1 << ($level – $i) ? SPACE : PREFIX_LINE);
    $string .= WIDE_SPACE;
    }
    }
    /**
    * node_out
    * 输出一个节点
    * @param mixed $string 返回结果的字符串(引用传值)
    * @param mixed $data 要处理的节点数据
    * @param mixed $level 节点深度
    * @param mixed $i 节点在父节点中的索引(下标)
    * @param mixed $is_last 当前节点(含)所有祖先节点是否尾节点标记
    * @access public
    * @return void
    */
    function node_out(&$string, $data, $level, $i, $is_last) {
    /* 处理前缀字符串: 祖先的连接符及空白 */
    node_prefix($string, $level, $is_last);
    /* 处理本节点的标识符号 */
    node_sign($string, $level, $i);
    /* 处理本节点数据信息 */
    node_str($string, $data);
    /* 追加换行 */
    $string .= "\n";
    }
    /**
    * tree_parse
    * 输出一棵树
    * 1. 由于使用了整型的$is_last作为祖先是否尾节点的标记, 所以最多支持PHP_INT_MAX的深度
    * 2. 如果需要扩展, 修正$is_last的数据类型及校验方法即可
    * @param mixed $string 返回结果的字符串(引用传值)
    * @param mixed $datas 要处理的树数据
    * @param int $level 当前处理的深度
    * @param int $is_last 当前深度所有祖先是否尾节点标记
    * @access public
    * @return void
    */
    function tree_parse(&$string, $datas, $level = 0, $is_last = 0) {
    if ( !is_array($datas) || count($datas) < 1 ) return ;
    $max_index = count($datas) – 1;
    /* 处理本层的所有节点 */
    foreach ( $datas as $i => $data ) {
    /* 当前节点及所有祖先是否尾节点标记 */
    $tmp_is_last = $is_last << 1 | 1 & $i == $max_index;
    /* 输出当前节点 */
    node_out($string, $data, $level, $i, $tmp_is_last);
    /* 如果有子节点, 递归子节点 */
    if ( is_array($data[K_CHILD]) && !empty($data[K_CHILD]) )
    tree_parse($string, $data[K_CHILD], $level + 1, $tmp_is_last);
    }
    }

    /* 计算实际节点数 */
    function n_node($n, $s) {
    $sum = 0;
    while ( $n > 0 )
    $sum += pow($s, $n –);
    return $sum;
    }
    /* 计算ruage时间 */
    function ru_time($info, $type) {
    return floatval(sprintf(‘%d.%d’, $info[$type . '.tv_sec'], $info[$type . '.tv_usec']));
    }
    /* 输出资源使用情况 */
    function resource_usage($lv, $nodes, $cb, $ce, $mb, $me, $rb, $re) {
    printf("\nresource usage[level: %d, node number: %d]: \n%20s%0.6fs\n%20s%0.6fs\n%20s%0.6fs\n%20s%d byte\n",
    $lv, $nodes,
    ‘clock time: ‘, $ce – $cb,
    ‘system cpu: ‘, ru_time($re, ‘ru_stime’) – ru_time($rb, ‘ru_stime’),
    ‘user cpu: ‘, ru_time($re, ‘ru_utime’) – ru_time($rb, ‘ru_utime’),
    ‘memory usage: ‘, $me – $mb);
    }
    /* 用法 */
    function usage($cmd) {
    printf("usage: \n%s <tree deepth>\n", $cmd);
    exit;
    }

    /* 测试入口函数 */
    function run() {
    global $argc, $argv;

    if ( $argc != 2 || intval($argv[1]) < 1 )
    usage($argv[0]);


    $datas = array();
    $id = 1;
    $string = ”;
    $level = intval($argv[1]);

    /* 初始构造测试树 */
    tree_build($datas, $id, $level);

    $clock_begin = microtime(TRUE);
    $memory_begin = memory_get_usage();
    $rusage_begin = getrusage();
    /* 解析树 */
    tree_parse($string, $datas);
    $rusage_end = getrusage();
    $memory_end = memory_get_usage();
    $clock_end = microtime(TRUE);

    /* 输出结果 */
    echo $string . "\n";

    resource_usage($level, n_node($level, MAX_NODES),
    $clock_begin, $clock_end,
    $memory_begin, $memory_end,
    $rusage_begin, $rusage_end);
    }

    /* 执行入口函数 */
    run();
    /*
    * Local variables:
    * tab-width: 4
    * c-basic-offset: 4
    * indent-tabs-mode: t
    * End:
    */ Reply
    @selfimpr: 我勒个去,这是个what Reply
  • 现在连php和js哪个运行在浏览器哪个运行在服务器端都分不清的人都能被招进client-be了, 服了。 Reply
  • <?php
    header(‘content-type:text/html;charset=utf-8;’);
    $cats = array(
    array(
    ‘id’ => 1,
    ‘name’ => ‘学术和教育11′,
    ‘children’ => array(
    array(
    ‘id’ => 11,
    ‘name’ => ‘自然科学11′,
    ‘children’ => array(
    array(
    ‘id’ => 111,
    ‘name’ => ‘自然科学111′,
    ‘children’ => null,
    )
    ),
    ),
    array(
    ‘id’ => 12,
    ‘name’ => ‘自然科学12′,
    ‘children’ => null,
    ),

    ),
    ),
    array(
    ‘id’ => 2,
    ‘name’ => ‘学术和教育222′,
    ‘children’ => array(
    array(
    ‘id’ => 21,
    ‘name’ => ‘自然科学21′,
    ‘children’ => null,
    ),
    array(
    ‘id’ => 22,
    ‘name’ => ‘自然科学22′,
    ‘children’ => null,
    ),

    ),
    ),
    array(
    ‘id’ => 3,
    ‘name’ => ‘学术和教育33′,
    ‘children’ => array(
    array(
    ‘id’ => 31,
    ‘name’ => ‘自然科学31′,
    ‘children’ => array(
    array(
    ‘id’ => 331,
    ‘name’ => ‘自然科学331′,
    ‘children’ => null,
    ),
    ),
    ),
    array(
    ‘id’ => 32,
    ‘name’ => ‘自然科学32′,
    ‘children’ => null,
    ),

    ),
    ),
    );
    menu($cats);


    function menu($cats,$id=NULL)
    {
    if(!empty($id))
    {
    $class="class=’children’";
    }


    echo"<ul $class>";
    foreach($cats as $k=>$v)
    {
    echo "<li>$v[name]";

    if($v['children']!=NULL)
    {
    menu($v['children'],$v['id']);
    }

    echo "</li>";
    }
    echo "</ul>";
    }
    ?>

    <style>
    <!–
    ul{ list-style-type:none; }
    ul li{cursor :pointer; background: url("img/1.png") no-repeat 0px 6px; padding-left:10px;}
    ul li.click{ background: url("img/2.png") no-repeat 0px 6px;}
    –>
    </style>
    <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js"></script&gt;
    <script type="text/javascript">
    $(document).ready(function(){
    $("ul.children").hide();
    $("li").click(function(){
    $(this).addClass(‘click’).children(‘ul’).show();
    });
    });
    </script> Reply
  • $html = ”;
    function treat($cats, &$html){
    // if(!is_array($cats))
    // return;
    if(!array_key_exists(‘id’, $cats)){ //root
    $html .= "<ul>";
    foreach($cats as $item){
    $html .= "<li>";
    treat($item, $html);
    $html .= "</li>";
    }
    $html .= "</ul>";
    }else{
    $html .= "<p id='{$cats["id"]}’>{$cats['name']}</p>";
    if(count($cats['children']) > 0){
    $html .= "<ul>";
    foreach($cats['children'] as $child){
    $html .= "<li>";
    treat($child, $html);
    $html .= "</li>";
    }
    $html .= "</ul>";
    }
    }
    }

    treat($cats, $html);
    echo $html; Reply
  • 不知道刚才邮箱有没有写错,刚才cookie里面有值,我直接选的!后来发现存的号有个是错的。
    我的邮箱是:421034509@qq.com Reply
  • 这个现在还算数吗?小弟是12届的本科生,现在大四,没课了,想到百度工作,因为家里有事,百度第一轮笔试错过了!最近学php已经2个月了,在网上搜题做的时候刚看到这个,自己做了一下!您看我能进百度吗?
    下面是代码~
    ————————————————————————————
    <?php
    $cats = array(
    array(
    ‘id’ => 1,
    ‘name’ => ‘学术和教育’,
    ‘children’ => array(
    array(
    ‘id’ => 2,
    ‘name’ => ‘自然科学’,
    ‘children’ => array(
    array(
    ‘id’ => 3,
    ‘name’ => ‘生物’,
    ‘children’ => null
    )
    )
    ),
    array(
    ‘id’ => 4,
    ‘name’ => ‘人文社科’,
    ‘children’ => null
    )
    )
    ),
    array(
    ‘id’ => 5,
    ‘name’ => ‘生活’,
    ‘children’ => null
    )
    );
    class treemenue{
    private $tree=array();
    private $treeinfo=array();
    public function __construct($arr){
    $this->tree=$arr;
    }

    private function gettree($arr,$position){
    foreach($arr as $key=>$value){
    $tmp=$position;
    $position.=$key;//记录当前的节点位置

    $this->treeinfo["$position"]=array(‘id’=>$value['id'],’name’=>$value['name']);
    if($value['children']!=null){
    $this->gettree($value['children'],$position);
    }
    $position=$tmp;
    }
    }
    public function creattree(){
    $this->gettree($this->tree,null);
    return $this->treeinfo;
    }
    public function countitem(){
    return count($this->treeinfo);
    }
    public function getdepth(){
    $maxdepth=0;
    foreach($this->treeinfo as $key=>$value){
    $maxdepth=$maxdepth>strlen($key)?$maxdepth:strlen($key);
    }
    return $maxdepth;
    }
    }
    $t=new treemenue($cats);
    $trinfo=$t->creattree();
    $max=$t->getdepth();
    ?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
    <html xmlns="http://www.w3.org/1999/xhtml"&gt;
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>树形菜单</title>
    <script>
    var a=new Array();
    var n=<?php echo $t->countitem(); ?>;
    <?php
    $j=0;
    foreach($trinfo as $key=>$value){
    ?>
    a[<?php echo $j;?>]="<?php echo $key; ?>"+"-";
    <?php
    $j++;
    }
    ?>
    // alert(a[0]+","+a[1]+","+","+a[2]+","+a[3]+","+a[4]);

    function rollmenue(id){//伸缩菜单的函数
    for(var i=0;i<n;i++){
    if(a[i].substr(0,a[i].length-1)==id){
    if(a[i].substr(a[i].length-1,1)=="+")
    a[i]=id+"-";
    else
    a[i]=id+"+";
    break;
    }
    }

    var clmenue="";
    for(var q=0;q<n;q++){
    if(a[q].substr(a[q].length-1,1)=="-"){//展开的菜单
    for(var k=q+1;k<n;k++){
    if(a[k].length>a[q].length)
    document.getElementById(a[k].substr(0,a[k].length-1)).style.display="inline-table";
    else
    break;
    }
    }
    else{//缩起的菜单
    for(var k=q+1;k<n;k++){
    if(a[k].length>a[q].length)
    document.getElementById(a[k].substr(0,a[k].length-1)).style.display="none";
    else{
    q=k-1;
    break;
    }
    }
    }
    }
    }
    </script>
    <style type="text/css">
    #tree{
    float:left;
    }
    <?php
    for($i=0;$i<=$max;$i++){
    $pos=20*$i;
    $color=220*$i;
    echo ".n".$i."{margin-left:{$pos}px;}";
    echo ".n".$i." a{text-decoration:none;color:#ff8000;}";
    echo ".m".$i."{" .
    "font-weight:bold;" .
    "background-color:#".$color.";".
    "}";
    }
    ?>
    </style>

    </head>
    <body>
    <div id="tree">
    <?php foreach($trinfo as $key=>$value){ ?>
    <div class="<?php echo "m".strlen($key);?>" id="<?php echo $key;?>" onclick="rollmenue(‘<?php echo $key;?>’);">
    <div class="<?php echo "n".strlen($key);?>">
    <a href="#?id=<?php echo $value['id']; ?>"><?php echo $value['name'];?> </a>
    </div>
    </div>
    <?php } ?>
    </div>
    </body>
    </html> Reply
  • 貌似简单,但估计我做不出来,主要是不认真,和无限级分类差不多,转成JSON,加上CSS DOM技术,用JQUERY实现这个动作非常简单 外带点PS美工,应该差不多了,哪天写个过来 Reply
  • 如果考虑性能
    php只输出第一层级的数据,其他数据通过ajax实现 Reply

« [1][2][3][4][5][6] » 1/6

Leave a Comment