PHP工程师面试题+笔试题

最近在广州找工作,大四狗,读着三本前两年刚升二本的学校,文科生,好像一切条件都非常不利,但我还是毅然选择这条路——拍黄片,人不能固步自封,还是要拓展一下自己的知识面,不能只学php而不拓展视野,还是要学学python、java、前端这些
面试得有点心塞,各种因为学历被刷,校招只投了几个,不是被刷了简历就是没勇气投,默默告诉自己,以后一定要叫自己的儿子多考几分!
她说我最近看起来很疲惫。
对啊因为找工作很多天睡不好了
他说还好,我们现在唯一的目标是找工作,不用考虑其他的。
是啊,就像高考那会一样。
话不多说,下面写一下最近所经历的一些面试题,以后会继续补充的

一、PHP基础

1.对于0,空值,'=','=='等的考察

以下代码输出什么

<?php
    function judge(){
        $num = 0;
        if($num = ''){
            echo 'a';
        }else{
            echo 'b';
        }
    }
?>

输出b,if中的空值赋值给$num,因此if条件必定为false,还有其他一些大同小异的题目,用=和==判断for循环的,只要把握好基本的概念就行了

2.对于emptyisset概念的考察

isset()empty()函数的区别在于,前者只验证一个值是否存在,后者在此基础上还会检验它的值是否非空和非0
注:empty()只检测变量,检测任何非变量的东西都将导致解析错误
isset() 判断一个变量是否已经设置
当设置一个变量值为0,empty() 认为这个变量同等于空,即相当于没有设置

可以定义一个变量,设置值为'',0,null,'aaa'几种不同情况下,用if判断empty、isset看看结果

3.预定义变量

如:php中输出当前脚本文件名的预定义变量是$_SERVER['PHP_SELF']
DOCUMENT_ROOT有关。如:地址为http://baidu.com/test/kkk.php...$_SERVER['PHP_SELF']='/test/kkk.php'
还有一些重要的如$_SERVER['DOCUMENT_ROOT'],输出网站所在的根目录,如'D:/work/www'
$_SERVER['SCRIPT_FILENAME'],输出'D:/work/www//kkk.php'
$_SERVER['HTTP_USER_AGENT'],获取客户端浏览器,操作系统等等
其他一些可以通过print_r($_SERVER)测试获得,当然不止这些,还有其他一些预定义变量,系统常量如__FILE__也是需要稍微去看一下

4.函数、算法考察

主要考察php的原生函数,暂时分为数组函数、字符串处理函数、时间函数、文件操作函数、数据库函数,后面再看看需不需要扩展。注意这些函数一定都要去过一遍。

(1.1)遍历指定文件夹下的所有文件夹及所有子文件夹

确定是文件夹 —— 打开文件夹(产生dh句柄) —— 循环读取文件夹内容(读取句柄的内容,即为file/folder) —— 递归读取上一步判断为folder且文件夹不为'.'或者'..'的文件夹内容

<?php

$dir = "D:/www/project/";
 function readDirectory($dir){
    if(is_dir($dir)){        //
         if ($dh = opendir($dir)) {
             while (($file = readdir($dh)) != false) {
                 if (is_dir($dir.$file) && $file!="." && $file!="..") {
                     echo $dir.$file."<br/>";
                     readDirectory($dir.$file."/");
                 }
             }
             closedir($dh);
         }
     }
} 
readDirectory($dir);

?>

(1.2)遍历指定文件夹下的所有文件及其子文件夹中的所有文件
<?php
    $dir = "D:/www/project/";
    function readDirectory($dir){
        if(is_dir($dir)){        //
             if ($dh = opendir($dir)) {
                 while (($file = readdir($dh)) != false) {
                     if (is_file($dir.$file)) {
                         echo "filename:".$file."<br/>";
                         // echo $dir.$file."<br/>";
                         echo "filetype:".filetype($dir.$file)."<br/>";
                     } 
                     if (is_dir($dir.$file) && $file!="." && $file!="..") {
                         readDirectory($dir.$file."/");
                     }
                 }
                 closedir($dh);
             }
         }
    }
    readDirectory($dir);

?>
(2)写一个方法获取url中的文件类型

如$url = 'http://www.qq.com/test.php?a=...'; 取出'php'

function getFileName($url){
    $a = explode('?', $url);
    $b = strrpos($a[0], '.');   //strrpos(被搜索字符串,要查找字符串,[查找开始的位置])  查找字符串最后一次出现的位置: 找到则返回最后一次出现的位置;未找到则返回false
    $c = substr($a[0], $b+1, 3);  //substr(被操作字符串,开始位置,[结束位置])  返回字符串的一部分
    return $c;
}
(3)接口知识的考察

eg.
用户登录认证,请求地址为http://www.aa.com/user.php,后...,验证是否正确
请求参数:时间戳 Time 什么鬼参数忘了,即为param 还有一个是token,token值是Time+param的MD5加密,中间有加号
返回参数:
成功:res['ret'] = 0; res['msg'] = 'success';
失败:res['ret'] = 1; res['msg'] = 'fail';
返回数据格式:json
下面是我的思路:

function valid(){
    $data = $_GET['data'];
    if(!$data){
        $res['ret'] = 1;
        $res['msg'] = 'fail';
        echo json_encode($res);
    }
    $str = $data['Time'] . '+' . $data['param'];
    if($data['token'] != md5($str)){
        $res['ret'] = 1;
        $res['msg'] = 'fail';
        echo json_encode($res);
    }else{
        $res['ret'] = 0;
        $res['msg'] = 'success';
        echo json_encode($res);
    }
}

其实今天笔试的时候做这道题忘了怎么返回json格式的数据了,就直接用了Thinkphp的ajaxReturn,后来回来的时候查了一下才知道原来直接echo,这么简单,框架还是为辅吧,要多写原生。今天笔试的是一家手游公司,对数据库操作和原生要求比较多。

5.对缓存的了解

这个是我的薄弱环节,实际项目没操作过,打算来了解一下再跟你们说

二、数据库知识

1.数据库的基本增删查改

基本的增删改查语句,关联语句,函数等过一遍就行,可以过一下imooc的教程
慕课网——与MySQL的零距离接触

2.谈谈数据库优化的方法

我暂时还没有实践过mysql的优化方式,自己在百度上看了一些方法,大概有以下的一些方法:
(1)创建表的时候避免使用NULL默认值,因为NULL对于大多数数据库都需要进行特殊处理和索引逻辑等等。所以大多数时候不用NOT NULL,可以用特殊值01代替
(2)尽可能使用更小的字段类型,因为mysql从磁盘读取数据之后是存到内存当中,这意味着更小的数据类型使得从磁盘读取或者打包到内存效率会更好
(3)字符集的转换:客户端或者应用程序使用的字符集可能和数据库使用的字符集不一致,需要在mysql运行过程中隐含转化
(4)创建索引,如果一张表很大然后符合条件的值很多,那么创建索引就能带来性能的提升。但是如果像性别,只有两个值,就没必要建索引,而是用enum。一张表的索引最好不超过6个,太多的话会影响Insert和Update的效率,因此要考虑删除使用不频繁的索引
(5)先考虑在where和order by这两列上建立索引。尽量少在where子句中进行表达式操作、函数操作等等
(6)尽量避免使用select * ,只查询需要用到的字段。尽量用betwwen and 代替in 和not in,也要避免在大量数据的where子句中使用or
(7)模糊查询优化:
使用FULLTEXT全文搜索(注意前提是MyISAM存储引擎)
FULLTEXT解析器用“ ”(空格)、“,”(逗号)“.”(点号)作为默认的单词分隔符,因此对于不使用这些分隔符的语言如汉语来说,FULLTEXT解析器不能正确的识别单词,对于这种情况需做额外处理。

(8)尽量满足范式(有的情况下要用反范式)下面是三大范式的区别,也要去看一下
第一范式:数据库表的每一列都是不可分割的原子数据项,而不能是集合,数组,记录等非原子数据项。如果实体中的某个属性有多个值时,必须拆分为不同的属性

clipboard.png

第二范式:满足第一范式前提,当存在多个主键的时候,才会发生不符合第二范式的情况。比如有两个主键,不能存在这样的属性,它只依赖于其中一个主键,这就是不符合第二范式

clipboard.png

第三范式:满足第二范式前提,如果某一属性依赖于其他非主键属性,而其他非主键属性又依赖于主键,那么这个属性就是间接依赖于主键,这被称作传递依赖于主属性。

clipboard.png

3.谈谈Myisam和Innodb存储引擎

(1)MyISAM强调性能,其执行速度比InnoDB类型更快,但不支持事务,而InnoDB提供事务支持以及外部键、行级锁等高级数据库功能
(2)如果增删改操作比较多,或者需要事务支持,则使用Innodb,如果是读的操作比较多,则使用Myisam
(3)MyISAM表锁,Innodb行锁

4.谈谈memcached和redis的异同

(1)memcached只能使用简单的key-value形式进行存储,而redis还支持hash,list,set等等。因此需要其他的数据类型支持的时候用redis更方便
(2)memcached是多核,redis是单核,所以在存储小数据上redis性能更高,反之大数据上memcached的性能比redis要高
(3)memcached不支持持久化操作,数据不能备份,只能用于缓存使用,重启后数据全部丢失。
redis支持持久化操作可以数据备份和数据恢复
(4)redis只能使用单线程,性能受限于cpu性能,memecached是多线程

5.有没有接触过事务

三、算法

1.写一个函数判断数组的深度

function getDepth($arr){


$max_depth = 1;
foreach($arr as $key=>$val){
    if(is_array($val)){
        $depth = getDepth($val) + 1;
        if($depth > $max_depth){
            $max_depth = $depth;
        }
    }
    
}
return $max_depth;

}

四、计算机网络

1.说一下常见的HTTP状态码

(1)消息(临时响应):1字头。
这一类型的状态码,代表请求已被接受,需要继续处理。这类响应是临时响应,只包含状态行和某些可选的响应头信息,并以空行结束。由于 HTTP/1.0 协议中没有定义任何 1xx 状态码,所以除非在某些试验条件下,服务器禁止向此类客户端发送 1xx 响应。
eg.
100: 服务器仅接收到部分请求
101: 服务器已经理解了客户端的请求,并将通过Upgrade 消息头通知客户端采用不同的协议来完成这个请求。
(2)成功:2字头。
代表请求已经被服务器所接收、理解、并接受
eg.
200: 请求成功(其后是对GET和POST请求的应答文档。)
201: 请求被创建完成,同时新的资源被创建。
(3)重定向:3字头。
表示要完成请求,需要进一步操作。 通常,这些状态代码用来重定向。
eg.
300: 多重选择。链接列表。用户可以选择某链接到达目的地。
301: 页面永久重定向
302: 页面临时重定向
304: 资源未被修改,服务器告诉客户,原来缓冲的文档还可以继续使用
(4)请求错误:4字头。
这些状态代码表示请求可能出错,妨碍了服务器的处理
eg.
400: 服务器未能理解请求
401: 被请求的页面需要用户名和密码。
403: 对请求页面的访问被禁止。(通常为没有读权限)
404: 服务器无法找到被请求的页面。
408: 超出服务器等待时间
413: 由于所请求的实体的太大,服务器不会接受请求。
414: 由于url太长,服务器不会接受请求。当post请求被转换为带有很长的查询信息的get请求时,就会发生这种情况。
(5)服务器错误:5字头。
这些状态代码表示服务器在尝试处理请求时发生内部错误。这些错误可能是服务器本身的错误,而不是请求出错
eg.
500: 请求未完成。服务器遇到不可预知的情况。
502: 作为网关或者代理工作的服务器尝试执行请求时,从上游服务器接收到无效的响应。
503: 服务器临时过载或当机。
504: 网关超时。

五、前端

1.考察函数

<input type="text" good="" />
获取input标签中的good属性值所用的函数是getAttribute("good")

2.考察jquery

<div id='table'></div>

用ajax方法,把请求返回的参数(格式是json)填充到table中,以表格形式列出
21号下午一道笔试题,因为需要联系上文有点麻烦,大概讲一下思路吧,主要是考察对jq的ajax函数还有其他一些jq函数的熟悉程度,我直接上代码

var html = '';
$(function(){
    $.ajax({
        type:'post',
        url:'.....',
        data:(忘了发送的参数是什么了,随便写一下){
            a:111,
            b:222
        },
        dataType:json,
        success:function(data){
            var res = jQuery.parseJSON(data);
            for(var i=0;i<res.length;i++){
                html += '<tr><td>' + res[i].Time + '</td><td>' + res[i].num + '</td></tr>'; 
            }
            $('#table').html('<table>' + html + '</table>');
        },
        error:function(){
        }
    })
})

六、其他

1.遇到问题时怎么解决(错误日志)

我回答的时候举了做项目的时候的例子,先缕一下思路。因为后台这一块,只要思路缕清了,在纸上写出来,接下来一步一步去debug,不断var_dump、print_r、echo,最后exit()一下,其实很好debug
后来发现面试官想问的其实不是这个,而是错误日志,今天特意去搜了一下,研究了一个下午终于会一点点

首先开启错误日志,配置php.ini
error_reporting = E_ALL ;将会向PHP报告发生的每个错误,包括ERROR、NOTICE、WARNING等等
display_errors = Off ;本地测试开启,项目上线要关闭,防止服务器重要信息泄露
log_errors = On ;开启错误日志
log_errors_max_len = 1024 ;设置每个日志项的最大长度
error_log = /www/phpernote/error.log ;指定产生的错误报告写入的日志文件位置

配置完之后重启服务器即可,参考了php的异常和处理文章的一小段代码,自己另外做了测试

<?php
set_error_handler('myErrorHandler');
function myErrorHandler($errno,$errmsg,$file,$line){
    echo "<b>错误代码:</b>[{$errno}] {$errmsg} <br/>".PHP_EOL;
    echo "<b>错误行号:</b>{$file}文件中的第 {$line} 行<br/>".PHP_EOL;
    echo "<b>PHP版本:</b>".PHP_VERSION."(".PHP_OS.") <br/>".PHP_EOL;
    $datetime = date('Y-m-d H:i:s',time()); 
    error_log('时间:' . $datetime  . '错误的信息:' . $errmsg . '错误文件所在位置:' . $_SERVER['SCRIPT_FILENAME']);
 }

echo $test;
test();
 echo 'good';
?>

下面是error.log输出的内容
clipboard.png

网页输出的内容:

clipboard.png


手动分割线
在上面提到的内容,其实有一些可以自己去拓展看一下的,比如提到innodb和myisam,前者是使用行锁,后者是使用表锁,那可以去拓展一下,什么是表锁什么事行锁,逐渐增大自己的知识面

先更新到这,明天还得去招聘会碰壁...
2017/03/18

先写到这里。前两天跑了广工招聘会,今天有一家联系明天面试了 ,继续去撞壁...
2017/03/20

今天基本确定offer,去一家手游公司,实习期一天100,转正后6K,包三餐,单双休,上午九点上班,周五周六6点下班,平时都是到8点,8~8.5小时的工作时间,上班时间有点大,不过应届毕业生嘛,学历也一般,其实这样的工作强度加上薪资我觉得已经是可以接受了。hr姐姐今天跟我说其实我笔试成绩一般,面试不错。希望实习期之间表现好一点,争取能够转正吧,希望各位应届毕业生也能有一份好的offer,多去尝试,学历高的固然好,学历低的也不要怕,多去跑一下招聘会宣讲会,还是感谢一直鼓励我去投其他公司的黑妹(男的),多尝试,总会有机会的!昨天刚过完22岁生日,今天确定offer,明天五月天演唱会,一切来得刚刚好。切骄切燥,加油!
2017/03/24

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值