2019 PHP 社招面经

以下先是自己复习的知识点:

   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不同的类和代码进行功能实现。

  适配器模式核心思想:把对某些相似的类的操作转化为一个统一的“接口”(这里是比喻的说话)--适配器,或者比喻为一个“界面”,统一或屏蔽了那些类的细节。适配器模式还构造了一种“机制”,使“适配”的类可以很容易的增减,而不用修改与适配器交互的代码,符合“减少代码间耦合”的设计原则。

简单工厂模式   --------   通过入参不同的名字 或者 类型 调用或new不同的类和代码进行功能实现。

工厂模式 引用博客

策略模式   

3. 

		$b = 1 ;

		$c = &$b;
		$c = 2;

		echo "$b";

4.请说明 PHP 中传值与传引用的区别,什么时候传值什么时候传引用?

函数参数若用传值则首先需要赋值一个值进行入参,而且在函数内的所有修改在函数外无效, 而引用则是对入参这个内容进行传递,不需要创建新内存进行赋值,并且函数内修改在函数外有效,           在针对大字符串或者变量时,为避免创建新的临时内存消耗,使用引用,一般情况下使用传值。

5.语句include和require的区别是什么?

       require是无条件包含,也就是如果一个流程里加入require,无论条件成立与否都会先执行require,当文件不存在或者无法打开的时候,会提示错误,并且会终止程序执行

       include有返回值,require没有(可能因为如此require的速度比include快),include如果被包含的文件不存在的化,那么会提示一个错误,但是程序会继续执行下去

6.PHP的基本变量类型

              四种标量类型:boolean (布尔型)、integer (整型)、float (浮点型, 也称作 double)、string (字符串)

    两种复合类型:array (数组)、object (对象)

    最后是两种特殊类型:resource(资源)、NULL(NULL)

7. 单双引号 

单引号对于内部的变量不会解析,而解析的速度较快,只能解析部分特殊符号

双引号对于内部的变量会进行解析,所以解析的速度较单引号慢,可以解析所有特殊符号

8. 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存在则最下面覆盖上面的方法以及属性。

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);
?>

 

18. Yaf框架的特点

  1. 用C语言开发的PHP框架, 相比原生的PHP, 几乎不会带来额外的性能开销.
  2. 所有的框架类, 不需要编译, 在PHP启动的时候加载, 并常驻内存.
  3. 更短的内存周转周期, 提高内存利用率, 降低内存占用率.
  4. 灵巧的自动加载. 支持全局和局部两种加载规则, 方便类库共享.
  5. 高性能的视图引擎.
  6. 高度灵活可扩展的框架, 支持自定义视图引擎, 支持插件, 支持自定义路由等等.
  7. 内建多种路由, 可以兼容目前常见的各种路由协议.
  8. 强大而又高度灵活的配置文件支持. 并支持缓存配置文件, 避免复杂的配置结构带来的性能损失.
  9. 在框架本身,对危险的操作习惯做了禁止.
  10. 更快的执行速度, 更少的内存占用.

 

 

算法:

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);
} 

//引申题 
//旋转数组找最小值(剑指offer)
<?php

function minNumberInRotateArray($rotateArray)
{
    // write code here
    $len = count($rotateArray);
  
    $high = $len - 1;
    $low = 0;
    while ($high >= $low) {
        $mid = $low + intval((($high - $low )) / 2);
        if ($rotateArray[$mid] > $rotateArray[$high]) {
            $low = $mid + 1;
            continue;
        }
        if ($rotateArray[$mid] == $rotateArray[$high]) {
            $high = $high- 1;
            continue;
        }
        $high = $mid;
        continue;
    }
    return $rotateArray[$low];
}

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支持数据的持久化,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用。

 

Nosql:

1.redis和memcached区别

1、数据类型支持不同

2、内存管理机制不同(redis淘汰机制)

3、数据持久化支持(机器宕机数据丢失)

redis和memcached的区别

web:

1.常见的web安全问题,以及预防

SQL注入------描述: 由于程序中对用户输入检查不严格,用户可以提交一段数据库查询代码,根据程序返回的结果,获得某些他想得知的数据,这就是所谓的SQL Injection,即SQL注入。对于输入检查不充分,导致SQL语句将用户提交的非法数据当作语句的一部分来执行。预防:做参数验证,

XSS ------- 描述:跨站脚本攻击,攻击者往网页中插入恶意脚本文件,在用户打开网页时执行,从而盗取用户信息以及其他隐私信息,可以分为持久型和非持久型XSS攻击

            · 持久型将例如评论中插入恶意脚本文件,通过插入数据库后下次查找该数据后再前端渲染执行恶意脚本,从而达到攻击的目的 ,      ·  持久型成功条件是:1> 后端没有入库筛选,直接入库,2>后端将数据查出没有转义直接返回前端  3>前端没有转义直接渲染   预防:

            · 非持久型是通过用户进入正常网页接收到攻击者发送来的url进入后,获取到用户的信息,从而攻击者可以盗取访问者的信息或者隐私   · 非持久型成功条件是: 1> 即时性,不经过服务器存储,直接通过 HTTP 的 GET 和 POST 请求就能完成一次攻击,拿到用户隐私数据    2>  攻击者需要诱骗点击   3> 反馈率低,所以较难发现和响应修复

CSRF------描述:跨站请求伪造攻击,攻击者将用户访问未关闭的网页cookie身份伪装进入敏感网页如银行进行转账操作

2.web请求流程

https://zhuanlan.zhihu.com/p/61927945

    1. 浏览器通过 DNS 把域名解析成对应的IP地址;
    2. 根据这个 IP 地址在互联网上找到对应的服务器,建立 Socket 连接;
    3. 客户端向服务器发送HTTP协议请求包,请求服务器里的资源文档;
    4. 在服务器端,实际上还有复杂的业务逻辑:服务器可能有多台,到底指定哪台服务器处理请求,这需要一个负载均衡设备来平均分配所有用户的请求;
    5. 还有请求的数据是存储在分布式缓存里还是一个静态文件中,或是在数据库里;
    6. 当数据返回浏览器时,浏览器解析数据发现还有一些静态资源(如:css,js或者图片)时又会发起另外的请求,而这些请求可能会在CDN上,那么CDN服务器又会处理这个用户的请求。
    7. 客户端与服务器断开。由客户端解释HTML文档,在客户端屏幕上渲染图形结果。

3. http状态码   (之前有面试或者工作用到的常用状态码)

   200 请求正常    

   3xx  重定向   304(NOT MODIFY) 自上次请求网页未修改过。 服务器返回此响应时,不会返回网页内容。

   4xx  客户端请求错误    400 服务器不理解的请求  404 未找到请求的页面  

   5xx  服务器错误    500 服务器内部错误(代码ERROR。。) 503  服务器暂时不可用  504 服务器请求超时

4.SESSION 与 COOKIE的区别是什么?

session存储于服务端, cookie存储于客户端,session比较安全,cookie可以修改,不安全。Session依赖于cookie进行传递。禁用cookie后,session还可以使用,在存储session的文件中,生成sessionID,通过get传参的方式将sessionID传到要实现session共享的页面,读取sessionID,从而从session中获取数据。

5.表单中get和post提交方式的区别?

在下列情况下使用get提交:1.内容较少,2.安全要求较低  3 只涉及到数据的查询,未涉及修改操作,

在下列情况下使用post提交:1.内容较长,2. 安全要求较高  3 涉及到数据的修改操作

还有其他提交方式,例如option   head  delete  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值