2019 PHP 社招面经
本文来源于网络作者:djxnsiwbfk
以下先是自己复习的知识点:
1.php的垃圾回收机制
------ 底层用c语言声明的结构体来标志对应的变量值和引用计数, 例如a=‘111’,这时这个结构体会有引用计数=1 sting value = 111 下面又有一个代码 b = a; 这时 引用计数会变为2 同理,如果引用计数为0时 会用c语言中的free进行内存释放 这里也可以说下php的类型转换, 有一个结构体来存储对应的值内容
zval { string "a" //变量的名字是a value zend_value //变量的值 type string //变量是字符串类型 } zend_value { string "hello916" //值的内容 refcount 1 //引用计数 }
2. php设计模式
单例模式
单例模式在php中的作用:避免new对象进行内存开辟或者数据库的连接从而消耗大量资源
PHP的单例模式:让类的一个对象成为系统中的唯一实例,避免大量的 new 操作消耗的资源。典型应用:数据库连接 * PHP的单例模式实现要求:
* 1、一个private的__construct是必须的,单例类不能在其它类中实例化,只能被自身实例化;
* 2、拥有一个保存类的实例的静态成员变量;
* 3、一个静态的公共方法用于实例化这个类,并访问这个类的实例;
//单例测试 class Test { private static $ins; //保存new对象后的属性 private function __construct() { //构造方法私有化 } public static function getInstance() { if (!(self::$ins instanceof self)) { echo '实例化<br>'; self::$ins = new self; } return self::$ins; } public function demo() { echo "单例测试"; } } $temp = Test::getInstance(); //获取到类的实例 //也可以通过getInstance()直接调用这个对应类中的方法 Test::getInstance()->demo();
适配器模式:通过入参不同的名字 或者 类型 调用或new不同的类和代码进行功能实现。
适配器模式核心思想:把对某些相似的类的操作转化为一个统一的“接口”(这里是比喻的说话)--适配器,或者比喻为一个“界面”,统一或屏蔽了那些类的细节。适配器模式还构造了一种“机制”,使“适配”的类可以很容易的增减,而不用修改与适配器交互的代码,符合“减少代码间耦合”的设计原则。
策略模式
3. http状态码 (之前有面试或者工作用到的常用状态码)
200 请求正常
3xx 重定向 304(NOT MODIFY) 自上次请求网页未修改过。 服务器返回此响应时,不会返回网页内容。
4xx 客户端请求错误 400 服务器不理解的请求 404 未找到请求的页面
5xx 服务器错误 500 服务器内部错误(代码ERROR。。) 503 服务器暂时不可用 504 服务器请求超时
4.
$b = 1 ; $c = &$b; $c = 2; echo "$b";
5.请说明 PHP 中传值与传引用的区别,什么时候传值什么时候传引用?
函数参数若用传值则首先需要赋值一个值进行入参,而且在函数内的所有修改在函数外无效, 而引用则是对入参这个内容进行传递,不需要创建新内存进行赋值,并且函数内修改在函数外有效, 在针对大字符串或者变量时,为避免创建新的临时内存消耗,使用引用,一般情况下使用传值。
6.SESSION 与 COOKIE的区别是什么?
session存储于服务端, cookie存储于客户端,session比较安全,cookie可以修改,不安全。Session依赖于cookie进行传递。禁用cookie后,session还可以使用,在存储session的文件中,生成sessionID,通过get传参的方式将sessionID传到要实现session共享的页面,读取sessionID,从而从session中获取数据。
7.表单中get和post提交方式的区别?
在下列情况下使用get提交:1.内容较少,2.安全要求较低 3 只涉及到数据的查询,未涉及修改操作,
在下列情况下使用post提交:1.内容较长,2. 安全要求较高 3 涉及到数据的修改操作
还有其他提交方式,例如option head delete
8.语句include和require的区别是什么?
require是无条件包含,也就是如果一个流程里加入require,无论条件成立与否都会先执行require,当文件不存在或者无法打开的时候,会提示错误,并且会终止程序执行
include有返回值,require没有(可能因为如此require的速度比include快),include如果被包含的文件不存在的化,那么会提示一个错误,但是程序会继续执行下去
9.PHP的基本变量类型
四种标量类型:boolean (布尔型)、integer (整型)、float (浮点型, 也称作 double)、string (字符串)
两种复合类型:array (数组)、object (对象)
最后是两种特殊类型:resource(资源)、NULL(NULL)
10. 单双引号
单引号对于内部的变量不会解析,而解析的速度较快,只能解析部分特殊符号
双引号对于内部的变量会进行解析,所以解析的速度较单引号慢,可以解析所有特殊符号
11. PHP7的新特性?重点
性能提升 ----
1、变量存储字节减小,减少内存占用,提升变量操作速度
2、改善数组结构,数组元素和hash映射表被分配在同一块内存里,降低了内存占用、提升了 cpu 缓存命中率
3、改进了函数的调用机制,通过优化参数传递的环节,减少了一些指令,提高执行效率
三元运算符 NULL判断赋值优化 -----
$sit = null; $test = $sit ?? 'wow'; print($test); //wow
还有一些变化 匿名类,常量数组,use,以及session定义数组的变化。
12. PHP支持多继承吗?如果不支持如何而实现多继承呢?
不支持。PHP中只允许单继承,父类可以被一个子类用关键字“extends”继承。
可以使用interface或者trait进行实现。1.interface的类不能实例化,内部不能有方法体 2. trait类不能实例化,由use引入,会覆盖当前类中的相同方法以及属性,多个use存在则最下面覆盖上面的方法以及属性。
13. 常见的 PHP 安全性攻击
SQL注入 ----- 无效或者错误sql语句操作额外消耗资源, 措施 : 保证进入sql的语句都是正确的,需要在代码层进行字段判断和筛选,在代码层判断。
CSRF:跨站点请求伪造,是指一个页面发出的请求,看起来就像是网站的信任用户,但是是伪造的
防止:一般来说,确保用户来自你的表单,并且匹配每一个你发送出去的表单。有两点一定要记住:
对用户会话采用适当的安全措施,例如:给每一个会话更新id和用户使用SSL。
生成另一个一次性的令牌并将其嵌入表单,保存在会话中(一个会话变量),在提交时检查它。 如laravel中的 _token
14.php操作函数
数组:array_values($arr); 获得数组的值
array_keys($arr); 获得数组的键名
array_flip($arr); 数组中的值与键名互换(如果有重复前面的会被后面的覆盖)
in_array("apple",$arr); 在数组中检索apple
array_search("apple",$arr); 在数组中检索apple ,如果存在返回键名
array_key_exists("apple",$arr); 检索给定的键名是否存在数组中
isset($arr[apple]): 检索给定的键名是否存在数组中
array_chunk($arr,3,TRUE); 可以将一个数组分割成多个,TRUE为保留原数组的键名
array_unique 数组去重
array_merge 数组合并
array_shift($arr);数组中的第一个元素移出并作为结果返回(数组长度减1,其他元素向前移动一位,数字键名改为从零技术,文字键名不变)
array_unshift($arr,"a",array(1,2));在数组的开头插入一个或多个元素
字符串: trim($str)删除两端空格
str_replace(' ', '', $str) 替换字符串中所有的空格
strlen($arr) substr(string str,int start[,int length])start截取字符串开始位置(参数为负从末尾开始截取),指定截取字符串的个数(length为负,取到倒数第length个字符)
int strcmp(string str1,string str2)区分字符大小写 相等返回0,str1大于str2返回值大于0,反之返回值小于0
int strcasecmp(string str1,string str2)不区分字符大小写
array explode(string separator,string str[,int limit]) $arrFields = explode(',', self::ALL_FIELDS);
string implode(string glue,array pieces) 合成字符串
15. PHP连接MySQL
<?php $con = mysql_connect("localhost","peter","abc123"); if (!$con) { die('Could not connect: ' . mysql_error()); } mysql_select_db("my_db", $con); $result = mysql_query("SELECT * FROM Persons"); while($row = mysql_fetch_array($result)) { echo $row['FirstName'] . " " . $row['LastName']; echo "<br />"; } mysql_close($con); ?>
17. 常见的web安全问题,以及预防
文件上传
SQL注入------描述: 由于程序中对用户输入检查不严格,用户可以提交一段数据库查询代码,根据程序返回的结果,获得某些他想得知的数据,这就是所谓的SQL Injection,即SQL注入。对于输入检查不充分,导致SQL语句将用户提交的非法数据当作语句的一部分来执行。预防:做参数验证,
XSS ------- 描述:跨站脚本攻击,攻击者往网页中插入恶意脚本文件,在用户打开网页时执行,从而盗取用户信息以及其他隐私信息,可以分为持久型和非持久型XSS攻击,
· 持久型将例如评论中插入恶意脚本文件,通过插入数据库后下次查找该数据后再前端渲染执行恶意脚本,从而达到攻击的目的 , · 持久型成功条件是:1> 后端没有入库筛选,直接入库,2>后端将数据查出没有转义直接返回前端 3>前端没有转义直接渲染 预防:
· 非持久型是通过用户进入正常网页接收到攻击者发送来的url进入后,获取到用户的信息,从而攻击者可以盗取访问者的信息或者隐私 · 非持久型成功条件是: 1> 即时性,不经过服务器存储,直接通过 HTTP 的 GET 和 POST 请求就能完成一次攻击,拿到用户隐私数据 2> 攻击者需要诱骗点击 3> 反馈率低,所以较难发现和响应修复
CSRF------描述:跨站请求伪造攻击,攻击者将用户访问未关闭的网页cookie身份伪装进入敏感网页如银行进行转账操作
18. Yaf框架的特点
用C语言开发的PHP框架, 相比原生的PHP, 几乎不会带来额外的性能开销.
所有的框架类, 不需要编译, 在PHP启动的时候加载, 并常驻内存.
更短的内存周转周期, 提高内存利用率, 降低内存占用率.
灵巧的自动加载. 支持全局和局部两种加载规则, 方便类库共享.
高性能的视图引擎.
高度灵活可扩展的框架, 支持自定义视图引擎, 支持插件, 支持自定义路由等等.
内建多种路由, 可以兼容目前常见的各种路由协议.
强大而又高度灵活的配置文件支持. 并支持缓存配置文件, 避免复杂的配置结构带来的性能损失.
在框架本身,对危险的操作习惯做了禁止.
更快的执行速度, 更少的内存占用.
算法:
1.冒泡算法:时间复杂度 O(n^2)
function sort() { $arr = [11,5,6,9,2,3,7,4,8]; $len = count($arr); for ($i = 0; $i < $len; $i++) { for ($j = $i+1; $j < $len; $j++) { if ($arr[$i] > $arr[$j]) { $temp = $arr[$i]; $arr[$i] = $arr[$j]; $arr[$j] = $temp; } } } var_dump($arr); }
2. 快排 时间复杂度O(nlogn)
function quick_sort($array) { $len = count($array); if ($len <= 1) return $array; $key = $array[0]; $left_arr = array(); $right_arr = array(); for ($cur = 1; $cur < $len; $cur++) { if ($array[$cur] < $key) { array_push($left_arr, $array[$cur]); } else { array_push($right_arr, $array[$cur]); } } $left_arr = $this->quick_sort($left_arr); $right_arr = $this->quick_sort($right_arr); $retArr = array_merge($left_arr, array($key), $right_arr); return $retArr; }
3.折半查找
<?php //非递归 function binarySort($arr, $low, $high, $key) { while( $low <= $high) { $mid = $low + intval(($high - $low) / 2); if ($arr[$mid] == $key) return $mid; if ($arr[$mid] < $key) { $low = $mid + 1; continue; } // arr[$mid] > $key $high = $mid - 1; continue; } return -1; } //递归 function binarySort($arr, $low, $high, $key) { if ($low > $high) return -1; $mid = $low + intval(($high - $low) / 2); if ($arr[$mid] == $key) return $mid; if ($arr[$mid] < $key) return binarySort($arr, $mid+1, $high, $key); return binarySort($arr, $low, $mid-1, $key); }
4.堆排序
MySQL:
1.MySQL数据库中的字段类型varchar和char的主要区别是什么?
char在内存中是存储的是固定长度字节,而varchar存储的是可变长的字节,长度为 字符长度L +1 这个1在内存中表示这个字符的总长度
2.对于大流量的网站,采用什么样的方法来解决访问量问题?
1.读写分离 2.静态页面 3. 加缓存 4,负载均衡,分流 5.图片服务器分离
1、HTML静态化
效率最高、消耗最小的就是纯静态化的html页面,所以我们尽可能使我们的 网站上的页面采用静态页面来实现,这个最简单的方法其实也是最有效的方法。
2、图片服务器分离
把图片单独存储,尽量减少图片等大流量的开销,可以放在一些相关的平台上,如七牛等
3、数据库集群和库表散列及缓存
数据库的并发连接为100,一台数据库远远不够,可以从读写分离、主从复制,数据库集群方面来着手。另外尽量减少数据库的访问,可以使用缓存数据库如memcache、redis。
4、镜像:
尽量减少下载,可以把不同的请求分发到多个镜像端。
5、负载均衡:
Apache的最大并发连接为1500,只能增加服务器,可以从硬件上着手,如F5服务器。当然硬件的成本比较高,我们往往从软件方面着手。
3.优化mysql数据库的方法
1.从结构层: web服务器采用负载均衡服务器,mysql服务器采用主从复制,读写分离
2.从储存层: 采用合适的存储引擎,采用三范式
3.从设计层: 采用分区分表,索引,表的字段采用合适的字段属性,适当的采用逆范式,开启mysql缓存
4.sql语句层:结果一样的情况下,采用效率高,速度快节省资源的sql语句执行
4.redis 和 memcache区别
1>Redis不仅仅支持简单的k/v类型的数据,同时还提供list,set,zset,hash,string等数据结构的存储。
2>Redis支持数据的备份,即master-slave模式的数据备份。
3>Redis支持数据的持久化,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用。
#社招##面经##PHP工程师#