php面试总结

持续更新。。。。

php

1. 简述 php 中的 autoload

Autoload 的加载机制,
当通过 new 来实例化一个类时,PHP 会通过定义的 autoload 函数加载相应的文件,如果这个类文件使用了 extends 或者 implements 需要用到其他的类文件,php 会重新运行 autoload 去进行类文件的查找和加载,如果发生了两次对同一类文件的请求,就会报错。

2. 静态变量及有什么优缺点?

静态局部变量的特点:

1.不会随着函数的调用和退出而发生变化。

2.静态局部变量只会初始化一次。

3.静态属性只能被初始化为一个字符值或一个常量,不能使用表达式。

4.当多次调用一个函数且要求在调用之间保留某些变量的值时,可考虑采用静态局部变量。

3. strtrstr_replace 有什么区别,两者分别用在什么场景下?

  • str_replace() 以其他字符替换字符串中的一些字符(区分大小写)
  • strtr() 转换字符串中特定的字符。

5.6版本 str_replace 比 strtr 效率高10+倍, 7.0 版本效率基本相同, 但 5.6 的 str_replace 竟比 7.0 高 3倍

4. 魔术方法

  • __construct():类的默认构造方法,如果 __construct() 和与类同名的方法共同出现时,默认调用__construct()而不是同类名方法。
  • __call():当调用不存在或者不可访问的方法时,会调用 __call ( $name, $arguments )方法。
  • __toString():当打印对象时会被直接调用。
  • __clone():当对象被拷贝时直接调用。
  • __isset():对不存在或者不可访问的属性使用 isset() 或者 empty() 时,__isset() 会被调用;
  • __destruct():类的析构函数,当该对象的所有引用都被删除,或者对象被显式销毁时执行。
  • __sleep()执行 serialize() 函数时会调用

5. 如下所示,会输出什么结果?

foreach ($array as $key => $item) {
            $array[$key + 1] = $item + 2;
            echo "$item";
        }
        print_r($array);

结果示例: $array = [3,6,7,8];

3678 //echo 输出数组内元素的值
Array
(
    [0] => 3  //$key 保持不变
    [1] => 5 //每次的$eky + 1,对应的值加2,
    [2] => 8
    [3] => 9
    [4] => 10
)

6. 递归的次数限制

递归是一种
函数调用自身(直接或间接)的一种机制,这种强大的思想可以把某些复杂的概念变得极为简单。逻辑上的递归可以无次数限制, 但语言执行器或者程序堆栈会限制递归的次数.

php 手册注解:但是要避免递归函数/方法调用超过 100-200 层,因为可能会使堆栈崩溃从而使当前脚本终止。 无限递归可视为编程错误。

  • 递归的两个基本条件

    • 递归的退出条件,这是递归能够正常执行的必要条件,也是保证递归能够正确返回的必要条件。缺乏这个条件,递归就会无限进行,直到系统给予的资源耗尽。如果碰到“max nest level of 100 reached”(php 中,超出递归限制)是没有正确的退出条件,导致了递归深度过大或者无限递归。
    • 递推过程。由一层函数调用进入下一层函数调用的递推。

7. 单引号和双引号的区别

  • 双引号内部变量会解析,单引号则不解析.
  • 双引号中特殊字符( \r\n 之类)会被转义,单引号中的内容不会被转义。
  • 执行效率:单引号串中的内容总被认为是普通字符,因此单引号中的内容不会被转义从而效率更高。

8. array 数组排序并去重;

如:$arr = [10,4,6,4,19,3,5];

  • 1、 array_multisort可以用来一次对多个数组进行排序,或者根据某一维或多维对多维数组进行排序。
  • 2、思路:想到的是排序算法(如冒泡) + 去重函数 array_unique

代码:

function bubbleSort(array $arr){
        $count = count($arr); //数组长度
        for($i = 1;$i < $count;$i++){
            for ($k = 0;$k < $count - $i;$k++){
                if ($arr[$k] > $arr[$k+1]){
                    $temp = $arr[$k];
                    $arr[$k] = $arr[$k+1];
                    $arr[$k+1] = $temp;
                }
            }
        }
        return array_unique($arr);
        
    }
    
 bubbleSort($arr);

9. 面向对象是什么?

是一种程序设计范型,同时也是一种程序开发方法。它将对象作为程序的基本单元,将程序和数据封装其中,以提高软件的重用性、灵活性和可扩展性。

10. 类和对象的区别及关系

  1. 类是定义一系列属性和操作的模板,而对象则把属性进行具体化,然后交给类处理。
  2. 对象就是数据,对象本身不包含方法。但是对象有一个“指针”指向一个类,这个类里可以有方法。
  3. 类和对象是不可分割的,有对象就必定有一个类和其对应,否则这个对象也就成了没有亲人的孩子(有一个特殊情况存在,就是由标量进行强制类型转换的 object,没有一个类和它对象。此时,PHP 中的一个称为“孤儿”的 stdClass 类就会收留这个对象)。

11、for 和 foreach 的区别

1、foreach 也叫增强 for 循环,foreach 其实是 for 循环的一个特殊简化版。
2、foreach 适用于只进行集合或数组遍历, for 则在较复杂的循环中效率更高。
3、foreach 不能对数组或集合进行修改(添加删除操作),如果想要修改就要用 for 循环。
所以相比较下来 for 循环更为灵活。

12、语句 include 和 require 的区别是什么?

  • include 和 require 都是引入指定的文件。加上 _once 表示只引入一次,已经引入过的不再引入。
  • include 在引入不存文件时产生一个警告且脚本还会继续执行,require 则会导致一个致命性错误且脚本停止执行。
  • include 有返回值,而 require 没有。

两者的使用不同:

  • require 这个函数通常放在 PHP 程序的最前面,PHP 程序在执行前,就会先读入 require 所指定引入的文件,使它变成 PHP 程序网页的一部份。常用的函数,亦可以这个方法将它引入网页中。
  • include 这个函数一般是放在流程控制的处理部分中。PHP 程序网页在读到 include 的文件时,才将它读进来。这种方式,可以把程序执行时的流程简单化。

13、isset()、empty()、is_null() 的区别?

  • 当变量未定义时,is_null() 是不允许作为参数判断的,会报 Notice 警告错误;
  • empty ,isset 首先都会检查变量是否存在,然后对变量值进行检测。而 is_null 只是直接检查变量值是否为 null,因此如果变量未定义就会出现错误!
  • isset():仅当 null 和未定义,返回 false;
  • empty():””、0、”0″、NULL、FALSE、array(),未定义,均返回 false ;
  • is_null():仅判断是否为 null,未定义报警告;
  • 变量本身作为参数,与 empty() 一致,但接受未定义变量时,报警告;
  • “”、0、”0″、NULL、FALSE、array() 这几个中,empty() 和“变量本身作为参数”结果一致,均作为“空”来处理,而 isset() 和 is_null() 仅当是 null 时,才作为“空”来处理(注意 false 并不会被认为是空)

14、常用的 php 数组函数及其作用

array_values($arr):获得数组的值
array_keys($arr):获得数组的键名
array_flip($arr):数组中的值与键名互换(如果有重复前面的会被后面的覆盖)
in_array(“apple”,$arr): 在数组中检索apple
array_search(“apple”,$arr): 在数组中检索apple ,如果存在返回键名
array_push($arr,”apple”,”pear”):将一个或多个元素压入数组栈的末尾(入栈),返回入栈元素的个数
array_pop($arr):将数组栈的最后一个元素弹出(出栈)
array_shift($arr):数组中的第一个元素移出并作为结果返回(数组长度减1,其他元素向前移动一位,数字键名改为从零技术,文字键名不变)
array_unshift($arr,”a”,array(1,2)):在数组的开头插入一个或多个元素

15、php 打印前一天的日期,(格式:2015-01-01 11:11:00)

 echo date('Y-m-d H:i:s',strtotime('-1 day',time()));

16、php 中 error_reporting 函数的作用

error_reporting() 设置 PHP 的报错级别并返回当前级别。

17、写一个函数、尽可能高效的从一个标准 url 中取出文件的扩展名,如 http://www.abcs.com/abc/de/fg… 中的 php 和 .php

function getExt2($url)
{
   $urlinfo = pathinfo($url);

  if(isset($urlinfo['extension']))
  {
    if(strpos($urlinfo['extension'],'?') !== false)
      return explode('?',$urlinfo['extension'])[0];
    else
      return $urlinfo['extension'];
  }
  return 'no extension';
}

18、实现一个字符串反转函数

public function strrev($str)
{
    $newstr = '';
    $len = strlen($str); //获取字符串长度
    
    for($i = $len; $i >= 0; $i--)
    {
        $newstr .= $str{$i}; //从最大下标拼接至最小即是反转了
    }
    return $newst;
}

19、写出常用的 http 状态码及其作用

NameAcademyscore
200OK 请求成功,服务器成功返回网页
301Moved Permanently 永久跳转,请求的网页已永久跳转到新位置。
403Forbidden 禁止访问,服务器拒绝请求
404Not Found服务器找不到请求的页面
500Internal Server Error服务器内部错误
502Bad Gateway 坏的网关,一般是网关服务器请求后端服务时,后端服务没有按照 http 协议正确返回结果。
503Service Unavailable 服务当前不可用,可能因为超载或停机维护。
504Gateway Timeout 网关超时,一般是网关服务器请求后端服务时,后端服务没有在特定的时间内完成服务。

20、写一个验证电子邮箱格式是否正确的函数

   function check_email($email){

        $preg = "/^\w+([-_.]\w+)*@\w+([-_.]\w+)*(\.\w+){0,3}$/i";
        
        preg_match($preg,$email,$res);
        
        return $res;//匹配成功返回1,匹配失败返回0
    }

21、mvc 的理解

MVC 是模型( model ) -视图( view )-控制器( controller )的缩写,一种软件设计典范,用一种业务逻辑、数据、界面显示分离的方法组织代码,将业务逻辑聚集到一个部件里面,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑。

22、 post 和 patch 的区别

23、php内存回收机制

php的内存管理机制是:预先给出一块空间,用来存储变量,当空间不够时,再申请一块新的空间。

  • 1.存储变量名,存在符号表。
  • 2.变量值存储在内存空间。
  • 3.在删除变量的时候,会将变量值存储的空间释放,而变量名所在的符号表不会减小。

虽然删除后内存变小了,但还是比没定义变量之前时大,这是因为虽然删除了变量的值,但变量名没有被删除。

php垃圾回收机制

  • PHP 变量存储是存储在一个 zval 容器里面的
  • 1.类型 2.值 3. is_ref 代表是否有地址引用 4.refcount 指向该值的变量数量

垃圾回收:

  • 1.在 5.2 版本或之前版本,PHP会根据 refcount 值来判断是不是垃圾。如果 refcount 值为 0,PHP 会当做垃圾释放掉。这种回收机制有缺陷,对于环状引用的变量无法回收
  • 2.在 5.3 之后版本改进了垃圾回收机制。如果发现一个zval容器中的refcount在增加,说明不是垃圾。如果发现一个zval容器中的refcount在减少,如果减到了 0,直接当做垃圾回收。如果发现一个 zval 容器中的 refcount 在减少,并没有减到 0,PHP 会把该值放到缓冲区,当做有可能是垃圾的怀疑对象。当缓冲区达到了临界值,PHP 会自动调用一个方法去遍历每一个值,如果发现是垃圾就清理

24、

laravel

1. laravel 和其他框架对比的优缺点

  • laravel

    • 优点: 使用人数全球第一,文档齐全,框架结构组织清晰,大量第三方扩展包供引用,适合大型网站协同开发,提供的 artisan 开发工具开发效率高。composer 扩展自动加载,中间件
    • 缺点:稍复杂,上手比一般框架要慢;大量引用第三方包,但某些场景下我们只使用类中的部分方法,代码显得有些冗余
  • ThinkPHP

    • 优点:轻量级 PHP 开发框架,易于上手,有丰富的中文文档;框架的兼容性较强,PHP4和PHP5完全兼容;适合中小项目的开发,学习成本低,社区活跃度高
    • 缺点:对Ajax的支持不是很好;缺少面向对象的设计,5的版本基本面向对象,框架社区相关的辅助工具少;目录结构混乱,需要花时间整理;
  • Yaf

    • 优点:用C语言开发的PHP框架, 相比原生的PHP, 几乎不会带来额外的性能开销.不需要编译, 在PHP启动的时候加载, 并常驻内存.更快的执行速度, 更少的内存占用.
    • 缺点:C的扩展,如果程序有漏洞,作者未及时更新,使用者在不懂C的情况下,只能看着网站受辱或者祈祷,或者关闭网站.

2、 laravel 依赖注入

依赖注入,实质是通过构造函数或者某些情况下
通过 setter 方法将类依赖注入到类中。通俗的讲就是一个类中要多次引入某个 model 的时候,可以在构造函数中一次引入,类中的方法直接调用即可。

3、依赖注入的原理

  • 依赖注入原理利用类方法反射,取得参数类型,然后利用容器构造好实例。然后再使用回调函数调起。
  • 注入对象构造函数不能有参数。否则会报错。Missing argument 1
  • 依赖注入故然好,但它必须要由 Router 类调起,否则直接用 new 方式是无法实现注入的。所以这就为什么只有 Controller 、Job 类才能用这个特性了。

4、 Composer

Composer 是一款跨平台的 PHP 依赖管理工具。让
组件式编程 成为可能,编写软件时,就如拼接乐高玩具一样。极大的提高了开发的效率和代码的可复用性,解放了生产力。

Laravel 使用 Composer 来作为扩展包的管理工具。

5. laravel 生命周期

  • Laravel 应用的所有请求入口都是 public/index.php 文件。index.php 文件载入 Composer 生成的自动加载设置,然后从 bootstrap/app.php 脚本获取 Laravel 应用实例,Laravel 的第一个动作就是创建服务容器实例
  • 请求被发送到 HTTP 内核或 Console 内核(分别用于处理 Web 请求和 Artisan 命令),这取决于进入应用的请求类型。
  • 内核启动过程中最重要的动作之一就是为应用载入服务提供者,应用的所有服务提供者都被配置在 config/app.php 配置文件的 providers 数组中。首先,所有提供者的 register 方法被调用,然后,所有提供者被注册之后,boot 方法被调用。
  • 一旦应用被启动并且所有的服务提供者被注册,Request 将会被交给路由器进行分发,路由器将会分发请求到路由或控制器,同时运行所有路由指定的中间件。

服务提供者是启动 Laravel 应用中最关键的部分,应用实例被创建后,服务提供者被注册,请求被交给启动后的应用进行处理,整个过程就是这么简单!

Mysql

1. Mysql 中,int(1) 和 int(10) 的区别

int(M) M 指示最大显示宽度,在数据库里面存储的都是4个字节的长度。最大有效显示宽度是255。该可选显示宽度规定用于显示宽度小于指定的列宽度的值时从左侧填满宽度。显示宽度并不限制可以在列内保存的值的范围,也不限制超过列的指定宽度的值的显示。

2.索引左原则:

  • like,匹配字符串时,不以通配符开头,左侧必须固定,该字段索引才会起作用
  • 复合索引,左侧的字段固定时,在索引匹配时,右侧的索引才有效。因为复合索引关键字排序,按照左边字段进行排序,如果左边字段相同,才依据右边字段。

3.索引创建的优缺点:

  • 优点:

    • 创建索引可提高系统性能
    • 通过唯一性索引,可以保证数据库表中每一行数据的唯一性
    • 加快检索速度
    • 加速表与表之间的连接
    • 使用分组和排序子句进行数据检索时,减少查询中分组和排序的时间
    • 通过使用索引,可以在查询过程中,使用优化隐藏器,提高系统性能
  • 缺点:

    • 创建索引和维护索引要耗费时间,随数据量的增加而增加
    • 索引占用物理空间
    • 对表中的数据进行增删改的时候,索引需动态维护,降低了数据的维护速度

4. 请描述一下 mysql 主从服务器之间是如何同步数据的,什么样的 sql 会造成主从无法正确同步?

  • 网络的延迟

由于 mysql
主从复制是基于 binlog 的一种异步复制,通过网络传送 binlog 文件,理所当然网络延迟是主从不同步的绝大多数的原因,特别是跨机房的数据同步出现这种几率非常的大,所以做读写分离,注意从业务层进行前期设计。

  • 主从两台机器的负载不一致

由于 mysql 主从复制是主数据库上面启动1个 io 线程,而从上面启动1个 sql 线程和1个 io 线程,当中任何一台机器的负载很高,忙不过来,导致其中的任何一个线程出现资源不足,都将出现主从不一致的情况。

  • max_allowed_packet 设置不一致

主数据库上面设置的
max_allowed_packet 比从数据库大,当一个大的 sql 语句,能在主数据库上面执行完毕,从数据库上面设置过小,无法执行,导致的主从不一致。

  • key 自增键开始的键值跟自增步长设置不一致引起的主从不一致。
  • mysql 异常宕机情况下,如果未设置 sync_binlog=1 或者 innodb_flush_log_at_trx_commit=1 很有可能出现 binlog 或者 relaylog 文件出现损坏,导致主从不一致。
  • mysq l本身的 bug 引起的主从不同步。
  • 版本不一致,特别是高版本是主,低版本为从的情况下,主数据库上面支持的功能,从数据库上面不支持该功能

5.有一个order表,如下,求购买次数最多的两个用户

order_iduser_idgoods
100000100苹果
100001100苹果
100002101橘子
100003102苹果
100004102香蕉

sql

SELECT order_id,user_id,COUNT(order_id) AS count FROM order GROUP BY user_id ORDER BY  count DESC  limit 2

6.事务的特性

  • 原子性(Atomicity)

原子性是指事务包含的所有操作要么全部成功,要么全部失败回滚。

  • 一致性(Consistency)

一致性是指事务执行之前和执行之后都必须处于一致性状态。

  • 隔离性(Isolation)

隔离性是当
多个用户并发访问数据库时,比如操作同一张表时,
数据库为每一个用户开启的事务,不能被其他事务的操作所干扰,多个并发事务之间要相互隔离

  • 持久性(Durability)

持久性是指一个事务一旦被提交,对数据库中的数据的改变就是永久性的

7.事务的隔离级别和高并发

  • 如果不考虑事务的隔离性,会发生的几种问题:

    • 脏读 (dirty read) :指在一个事务处理过程里读取了另一个未提交的事务中的数据。
    • 不可重复读 (unrepeated read):指在对于数据库中的某个数据,一个事务范围内多次查询却返回了不同的数据值,这是由于在查询间隔,被另一个事务修改并提交了。
    • 幻读(phantom read):一个事务执行两次查询,第二次查询比第一次多出或少一些数据,造成两次结果不一致。只是另一个事务在这两次查询中间插入或者 删除了数据造成的。
    • 第一类丢失更新(lost update): 在完全未隔离事务的情况下,两个事物更新同一条数据资源,某一事物异常终止,回滚造成第一个完成的更新也同时丢失 。
    • 第二类丢失更新(second lost updates):是不可重复读的特殊情况,如果两个事务都读取同一行,然后两个都进行写操作,并提交,第一个事务所做的改变就会丢失。
  • 四种事务隔离级别:

  1. Serializable 串行化
  2. Repeatable Read 可重复读
  3. Read Commited 可读已提交
  4. Read Uncommited 可读未提交

  • 并发控制:

    1. 数据库系统采用不同的锁类型来实现以上四种隔离级别,具体的实现过程对用户是透明的。用户关心的是如何选择隔离级别。
    2. 对于多数应用程序,可以优先考虑把数据库系统的隔离级别设为 Read Committed,它能够避免脏读,而且具有较好的并发性能。
    3. 每个数据库连接都有一个全局变量 @@tx_isolation ,表示当前的事务隔离级别。JDBC 数据库连接使用数据库系统默认的隔离级别。
    4. 在 Hibernate 的配置文件中可以显示地设置隔离级别。每一种隔离级别对应着一个正整数。
    5. 需要注意的是,在受管理环境中,如果 Hibernate 使用的数据库连接来自于应用服务器提供的数据源,Hibernate不会改变这些连接的事务隔离级别。在这种情况下,应该通过修改应用服务器的数据源配置来修改隔离级别。
    6. 当数据库系统采用 Red Committed 隔离级别时,会导致不可重复读和第二类丢失更新的并发问题,在可能出现这种问题的场合。可以在应用程序中采用悲观锁或乐观锁来避免这类问题。

mysql查看当前事务隔离级别:
select @@tx_isolation

设置事务隔离级别:
set [glogal | session] transaction isolation level 隔离级别名称;
set tx_isolation=’隔离级别名称;’

8. 悲观锁和乐观锁

  • 悲观锁

  正如其名,它指的是对数据被外界(包括本系统当前的其他事务,以及来自外部系统的事务处理)修改持保守态度,在整个数据处理过程中,将数据处于锁定状态基于数据库的锁机制实现(也只有数据库层提供的锁机制才能真正保证数据访问的排他性,否则,即使在本系统中实现了加锁机制,也无法保证外部系统不会修改数据)。
  在Hibernate使用悲观锁十分容易,但实际应用中悲观锁是很少被使用的,因为它每次发送的SQL语句都会加上”for update”用于告诉数据库锁定相关数据,大大限制了并发性,数据库性能的大量开销

  • 乐观锁

  乐观锁,大多是基于数据版本( Version )记录机制实现。何谓数据版本?即为数据增加一个版本标识,在基于数据库表的版本解决方案中,一般是通过为数据库表增加一个 "version" 字段来实现
  乐观锁的工作原理:读取出数据时,将此版本号一同读出,之后更新时,对此版本号加一。此时,将提交数据的版本数据与数据库表对应记录的当前版本信息进行比对,如果提交的数据版本号大于数据库表当前版本号,则予以更新,否则认为是过期数据。

9.复合索引

概念:用户可以在
多个列上建立索引,这种索引叫做复合索引(组合索引);

复合索引在数据库操作期间所需的开销更小,可以代替多个单一索引;
窄索引是指索引列为1-2列的索引,宽索引也就是索引列超过2列的索引;
设计索引的一个重要原则就是能用窄索引不用宽索引,因为窄索引往往比组合索引更有效;

10. like 的优化

like写法一般为
select cat from animal where name like '%猫%'


explain 解释来看 sql 语句并没有运用索引(name 已经创建索引),而是全表扫描。

  • 尽量不要使用 like '%..%'
  • 对于 like '..%..' (不以 % 开头), 对于 like '%...' 的 (不以 % 结尾),加个 reverse 函数,又可以用上索引了'(需要反向索引的支持)SQL> select * from test_like where reverse(object_name)like reverse('%AS');
  • 使用locate函数代替like

    • 语法一 LOCATE(substr,str)返回字符串substr中第一次出现子字符串的位置 str
    • 语法二:LOCATE(substr,str,pos)返回 substrstr 中第一次出现的位置,如果 substrstr 中不存在,返回值为 0 。如果pos存在,返回 substrstrpos个位置后第一次出现的位置,如果 substrstr 中不存在,返回值为0

mysql 优化

  • sql 语句优化
  • 索引优化
  • 选择合适的存储引擎
  • 字段选择合适的数据类型
  • 对表进行水平或者垂直拆分
  • 针对存储引擎的优化
  • 磁盘 I/O 优化
  • 负载均衡
  • 主从复制

Linux

1. 如何检测 web 服务慢

  • top:查看系统性能
  • Nginx:最后一个字段加入$request_time

列出 php 页面请求时间超过3秒的页面,并统计其出现的次数,显示前100条

cat access.log|awk '($NF > 1 && $7~/\.php/){print $7}'|sort -n|uniq -c|sort -nr|head -100

  • 代码中实现,开头写入时间,结尾写入时间

2. 自动脚本

crond 是 linux 下用来周期性的执行某种任务或等待处理某些事件的一个守护进程。

  • 系统任务调度:系统周期性所要执行的工作,比如写缓存数据到硬盘、日志清理等。在/etc目录下有一个 crontab 文件,这个就是系统任务调度的配置文件。

* 用户任务调度:用户定期要执行的工作,比如用户数据备份、定时邮件提醒等。用户可以使用 crontab 工具来定制自己的计划任务。所有用户定义的 crontab 文件都被保存在 /var/spool/cron目录中。其文件名与用户名一致。
语法:
minute hour day month week command
还可以使用以下特殊字符:

  • 星号(*):代表所有可能的值,例如 month 字段如果是星号,则表示在满足其它字段的制约条件后每月都执行该命令操作。
  • 逗号(,):可以用逗号隔开的值指定一个列表范围,例如,“1,2,5,7,8,9”
  • 中杠(-):可以用整数之间的中杠表示一个整数范围,例如“2-6”表示“2,3,4,5,6”
  • 正斜线(/):可以用正斜线指定时间的间隔频率,例如“0-23/2”表示每两小时执行一次。同时正斜线可以和星号一起使用,例如*/10,如果用在 minute 字段,表示每十分钟执行一次。

3.Nginx负载均衡方案

常用的几种方式:

  • 轮询 (Round Robin)

根据Nginx配置文件中的顺序,
每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器 down 掉,能自动剔除。

upstream web { 
    server server1; 
    server server2; 
  } 
  • 最少连接

Web 请求会被转发到
连接数最少的服务器上。least_conn 算法很简单,首选遍历后端集群,比较每个后端的 conns/weight,选取该值最小的后端。如果有多个后端的 conns/weight 值同为最小的,那么对它们采用加权轮询算法。

 upstream web { 
     least_conn; 
     server server1; 
     server server2; 
 } 
  • IP地址哈希

同一客户端连续的 Web 请求可能会被分发到不同的后端服务器进行处理,因此如果涉及到会话 Session,可以使用基于 IP 地址哈希的负载均衡方案。这样的话,
同一客户端连续的 Web 请求都会被分发到同一服务器进行处理(每个请求按访问 ip 的 hash 结果分配,这样每个访客固定访问一个后端服务器,可以解决 session 的问题)。

upstream web { 
    ip_hash;
    server server1; 
    server server2; 
  } 
  • 权重 (Weighted Load Balancing)

可以根据服务器的性能状况有选择的分发 web 请求。指定轮询几率,weight 越高、访问比率越大。weight=2,意味着每接收到3个请求,前2个请求会被分发到第一个服务器,第3个请求会分发到第二个服务器,其它的配置同轮询配置。

upstream web { 
    server server1 weight=2; 
    server server2; 
  } 

基于权重的负载均衡和基于 IP 地址哈希的负载均衡可以组合在一起使用。

  • fair(第三方)

按后端服务器的响应时间来分配请求,响应时间短的优先分配。

upstream web {
    server server1;
    server server2;
    fair;
}
  • url_hash(第三方)

按访问 url 的 hash 结果来分配请求,使每个 url 定向到同一个后端服务器,后端服务器为缓存时比较有效。 hash_method 是使用的 hash 算法

upstream web {

server server1:3128;
server server1:3128;
hash $request_uri;
hash_method crc32;

}

每个设备的状态设置为:

1.down 表示单前的 server 暂时不参与负载

2.weight 默认为1.weight 越大,负载的权重就越大。

3.max_fails:允许请求失败的次数默认为1.当超过最大次数时,返回 proxy_next_upstream 模块定义的错误

4.fail_timeout:max_fails 次失败后,暂停的时间。

5.backup: 其它所有的非 backup 机器 down 或者忙的时候,请求 backup 机器。所以这台机器压力会最轻。sorry server 提供非业务功能。

4. Keepalived

Keepalived是通过VRRP(虚拟路由器冗余协议)协议实现
高可用功能的。VRRP 出现的目的就是为了解决静态路由单点故障问题的,它能够保证当个别节点宕机时,整个网络可以不间断地运行。

5.vi 和 vim 的区别

它们都是
多模式编辑器,不同的是 vim 是 vi 的升级版本,它不仅兼容 vi 的所有指令,而且还有一些新的特性在里面。vim 的这些优势主要体现在以下几个方面:

  • 1、多级撤消

我们知道在 vi 里,按 u 只能撤消上次命令,而在 vim 里可以无限制的撤消。

  • 2、易用性

vi只能运行于 unix 中,而 vim 不仅可以运行于 unix,windows ,mac 等多操作平台。

  • 3、语法加亮

vim 可以用不同的颜色来加亮你的代码。

  • 4、可视化操作

就是说 vim 不仅可以在终端运行,也可以运行于 x window、 mac os、 windows。

  • 5、对 vi 的完全兼容

某些情况下,你可以把 vim 当成 vi 来使用。vi 和 vim 都是 Linux 中的编辑器,不同的是 vim 比较高级,可以视为 vi 的升级版本。vi 使用于文本编辑,但是 vim 更适用于 coding。

6. awk 命令

AWK是一种
处理文本文件的语言,是一个强大的文本分析工具。通常,awk 是以文件的一
行为处理单位的。awk 每接收文件的一行,然后执行相应的命令,来处理文本。

语法:
awk '{pattern + action}' {filenames}

pattern 表示 AWK 在数据中查找的内容,而
action 是在找到匹配内容时所执行的一系列命令。花括号(
{})不需要在程序中始终出现,但它们用于根据特定的模式对一系列指令进行分组。
pattern就是要表示的正则表达式,用斜杠括起来。

综合

1. AES 和 RSA 的区别:

  • RSA 是非对称加密,公钥加密,私钥解密, 反之亦然。缺点:运行速度慢,不易于硬件实现。常私钥长度有512bit,1024bit,2048bit,4096bit,长度越长,越安全,但是生成密钥越慢,加解密也越耗时。
  • AES 对称加密,密钥最长只有256个 bit,执行速度快,易于硬件实现。由于是对称加密,密钥需要在传输前通讯双方获知。
  • AES加密数据块分组长度必须为128比特,密钥长度可以是128比特、192比特、256比特中的任意一个(如果数据块及密钥 长度不足时,会补齐)

总结
采用非对称加密算法管理对称算法的密钥,然后用对称加密算法加密数据,这样我们就集成了两类加密算法的优点,既实现了加密速度快的优点,又实现了安全方便管理密钥的优点。

2. 一次完整的 http 请求详解

  1. 客户端输入 URL 。
  2. 客户端检测缓存(有缓存且较新,客户端直接读取本地缓存进行资源展示,有缓存但是不新,准备 http 请求包,发送至服务端进行缓存校验)。
  3. 提取请求首部 HOST通过 DNS 域名解析获取服务 IP(DNS 缓存递归等)。
  4. 通过 IP 与默认端口创建 TCP 连接,进行 http 请求报文数据发送,其中重点就三次握手进行描述(客户端向服务端发送 syn,服务端向客户端发送 syn、ack,客户端向服务端发送 syn,ack,data)。
  5. 服务端程序接受请求,定向到请求路径处理程序,准备http响应。
  6. 通过建立的 tcp 连接来返回相关的 http 响应报文及 http 状态信息,然后根据实际情况看是否关闭连接( Connection的keep-alive )。
  7. TCP 连接关闭经历 4 次握手。
  8. 客户端拿到 http 响应的报文信息,经过一系列前端处理过程最终将请求的资源进行展示

3. cookie 和 session 的区别和用法。session 锁

  1. cookie 数据存放在客户的浏览器上,session数据放在服务器上.
  2. cookie 不是很安全,别人可以分析存放在本地的 COOKIE 并进行 COOKIE 欺骗,考虑到安全应当使用 session。
  3. session 会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能考虑到减轻服务器性能方面,应当使用 COOKIE。
  4. 单个 cookie 保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个 cookie。(Session 对象没有对存储的数据量的限制,其中可以保存更为复杂的数据类型)
  • session 锁

php 的 session 默认用文件存储,当请求一个需要操作 session 的 php 文件(session_start())时,这个文件是会被第一个操作 session 的进程锁定,导致其他请求阻塞。其他请求会挂起在 session_start() 直到s ession文件解锁。这样保证了读取-写入,读取-写入的顺序。对数据流来说很理想,但是,对于目前这种页面大量应用ajax的情况,所有请求排队处理,将大大加大页面展现的耗时,甚至出现请求超时等不可用故障。

解决:由于锁定的 session 文件直到脚本执行结束或者 session 正常关闭才会解锁,为了防止大量的 php 请求(需要使用 $_SESSION 数据)被锁定,可以在写完 session 后马上关闭(使用
session_write_close()),这样就释放了锁;

Memcache 或者 Redis 做 session 的存储,是能解决“锁定”的问题,但处理不好会导致连接数飙高(在 session 操作后如果有耗时操作,连接是不回收的,可以主动在 session 写操作完成后做 session_write_close() 操作);

4. XSS、CSRF、SSRF、SQL 注入原理

  • XSS跨站脚本一种网站应用程序的安全漏洞攻击,是代码注入的一种。它允许恶意用户将代码注入到网页上。通常包含了 HTML 以及用户端脚本语言。防御页面上直接输出的所有不确定(用户输入)内容都进行 html 转义;对用户输入内容格式做校验;script 脚本中不要使用不确定的内容;
  • CSRF:跨站请求伪造是一种挟制用户在当前已登录的 Web 应用程序上执行非本意的操作的攻击方法;防御:验证 HTTP Referer 字段;在请求地址中(或 HTTP 头中)添加 token 并验证;
  • SSRF模拟服务器对其他服务器资源进行请求,没有做合法性验证。构造恶意内网IP做探测,或者使用其余所支持的协议对其余服务进行攻击。防御:禁止跳转,限制协议,内外网限制,URL 限制。绕过:使用不同协议,针对IP,IP 格式的绕过,针对 URL,恶意 URL 增添其他字符,@之类的。301跳转 + dns rebindding。
  • SQL注入:是通过把 SQL 命令插入到Web表单提交或输入域名或页面请求的查询字符串,欺骗服务器执行恶意的 SQL 命令。防御过滤特殊符号特殊符号过滤或转义处理(addslashes函数);绑定变量,使用预编译语句;

5. NPM 、Yarn 概念

NPM 是 Node.js(一个基于 Google V8 引擎的 JavaScript 运行环境)的包管理和分发工具。

Yarn 是 Facebook 在 2016 年 10 月开源的一个新的包管理器,用于替代现有的 NPM 客户端或者其他兼容 NPM 仓库的包管理工具。Yarn 在保留 NPM 原有工作流特性的基础上,使之变得更快、更安全、更可靠。

MongoDB

MongoDB 数据类型:

  • String(字符串): mongodb 中的字符串是 UTF-8 有效的。
  • Integer(整数): 存储数值。整数可以是 32 位或 64 位,具体取决于您的服务器。

* Boolean(布尔): 存储布尔( true/false )值。

  • Arrays(数组): 将数组或列表或多个值存储到一个键中。
  • Timestamp(时间戳): 存储时间戳。
  • Object(对象): 嵌入式文档。
  • Null (空值): 存储 Null 值。
  • Date(日期): 以 UNIX 时间格式存储当前日期或时间。

算法

1. 排序算法

* 快速排序

快速排序:我先选一个标尺,用它把整个队列过一遍筛选,以保证其左边的元素都不大于它,其右边的元素都不小与它

function quickSort($arr){
  // 获取数组长度
  $length = count($arr);
  // 判断长度是否需要继续二分比较
  if($length <= 1){
    return $arr;
  }
  // 定义基准元素
  $base = $arr[0];
  // 定义两个空数组,用于存放和基准元素的比较后的结果
  $left = [];
  $right = [];
  // 遍历数组
  for ($i=1; $i < $length; $i++) 
    // 和基准元素作比较
    if ($arr[$i] > $base) {
      $right[] = $arr[$i];
    }else {
      $left[] = $arr[$i];
    }
  }
  // 然后递归分别处理 left 和 right
  $left = quickSort($left);
  $right = quickSort($right);
  // 合并
  return array_merge($left,[$base],$right);
  
}

  • 冒泡排序

思路:法如其名,就像冒泡一样,每次从数组中冒出一个最大的数

比如:2,4,1

第一次冒出4:2,1,4

第二次冒出2:1,2,4

function bubbleSort($arr){
  // 获取数组长度
  $length = count($arr);
  // 第一层循环控制冒泡轮次
  for ($i=0; $i < $length-1; $i++) { 
    // 内层循环控制从第0个键值和后一个键值比较,每次冒出一个最大的数
    for ($k=0; $k < $length-$i; $k++) { 
      if($arr[$k] > $arr[$k+1]){
        $tmp = $arr[$k+1];
        $arr[$k+1] = $arr[$k];
        $arr[$k] = $tmp;
      }
    }
  }
  return $arr;
}
  • 选择排序

思路:每次选择一个相应的元素,然后将其放到指定的位置.使用双重循环完成,外层控制轮数,当前的最小值,内层控制比较次数

function selectSort($arr){
  // 获取长度
  $length = count($arr);
  for ($i=0; $i < $length - 1; $i++) { 
    // 假设最小值的位置
    $p = $i;
    // 使用假设的最小值和其他值比较,找到当前的最小值
    for ($j=$i+1; $j < $length; $j++) { 
      // $arr[$p] 是已知的当前最小值
      // 判断当前循环值和已知最小值的比较,当发下更小的值时记录下键,并进行下一次比较
      if ($arr[$p] > $arr[$j]) {
        $p = $j; // 比假设的值更小
      }
    }
    // 通过内部 for 循环找到了当前最小值的 key,并保存在 $p 中
    // 判断 当前 $p 中的键和假设的最小值的键不一致增将其互换
    if ($p != $i) {
      $tmp = $arr[$p];
      $arr[$p] = $arr[$i];
      $arr[$i] = $tmp;
    }
  }
  // 返回最终结果
  return $arr;
}

正则表达式

缓存及 nosql

1、redis 的优缺点

优点:

1、读写性能优异

2、支持数据持久化,支持 AOFRDB 两种持久化方式

3、支持主从复制,主机会自动将数据同步到从机,可以进行读写分离。

4、数据结构丰富:除了支持 string 类型的 value 外还支持 stringhashsetsortedsetlist等数据结构。

缺点:

1、
Redis 不具备自动容错和恢复功能,主机从机的宕机都会导致前端部分读写请求失败,需要等待机器重启或者手动切换前端的
IP 才能恢复。

2、 主机宕机,宕机前有部分数据未能及时同步到从机,切换IP后还会引入数据不一致的问题,降低了系统的可用性。

3、 redis 的主从复制采用全量复制,复制过程中主机会 fork 出一个子进程对内存做一份快照,并将子进程的内存快照保存为文件发送给从机,这一过程需要确保主机有足够多的空余内存。若快照文件较大,对集群的服务能力会产生较大的影响,而且复制过程是在从机新加入集群或者从机和主机网络断开重连时都会进行,也就是网络波动都会造成主机和从机间的一次全量的数据复制,这对实际的系统运营造成了不小的麻烦。

4、 Redis 较难支持在线扩容,在集群容量达到上限时在线扩容会变得很复杂。为避免这一问题,运维人员在系统上线时必须确保有足够的空间,这对资源造成了很大的浪费。

2、redis 的应用场景

* 缓存——热数据

    • 热点数据(经常会被查询,但是不经常被修改或者删除的数据)
    • 计数器

      • 诸如统计点击数等应用。由于单线程,可以避免并发问题,保证不会出错,而且 100% 毫秒级性能!别忘记持久化,毕竟是 redis 只是存了内存!

     * 命令:INCRBY

    • 队列

      • 相当于消息系统。由于 redis 把数据添加到队列是返回添加元素在队列的第几位,所以可以做判断用户是第几个访问这种业务。队列不仅可以把并发请求变成串行,并且还可以做队列或者栈使用
    • 分布式锁与单线程机制

      • 验证前端的重复请求(可以自由扩展类似情况),可以通过 redis 进行过滤:每次请求将request Ip、参数、接口等 hash 作为 key 存储 redis(幂等性请求),设置多长时间有效期,然后下次请求过来的时候先在 redis 中检索有没有这个 key,进而验证是不是一定时间内过来的重复提交.
      • 秒杀系统,基于 redis 是单线程特征,防止出现数据库“爆破”
      • 全局增量 ID 生成,类似“秒杀”
    • 最新列表

      • 例如新闻列表页面最新的新闻列表,如果总数量很大的情况下,尽量不要使用 select a from A limit 10 这种 low 货,尝试 redis 的 LPUSH命令构建 List,一个个顺序都塞进去就可以啦。不过万一内存清掉了咋办?也简单,查询不到存储 key 的话,用 mysql 查询并且初始化一个 List 到 redis 中就好了。
    • 排行榜

      • 谁得分高谁排名往上。命令:ZADD(有续集,sorted set)

    3、MongoDB 优缺点

    缺点

    1、 不支持事务操作

    2、 占用空间过大

    3、 MongoDB 没有如 MySQL 那样成熟的维护工具

    4、 无法进行关联表查询,不适用于关系多的数据

    5、 复杂聚合操作通过 mapreduce 创建,速度慢

    6、 模式自由,自由灵活的文件存储格式带来的数据错误

    优点
    1、 文档结构的存储方式,能够更便捷的获取数据
    2、 内置 GridFS,支持大容量的存储
    3、 内置 Sharding,分片简单
    4、 海量数据下,性能优越
    5、 支持自动故障恢复(复制集)
    参考:https://www.cnblogs.com/shiji…

    内容为本人收集整理,如有表达错误欢迎指正

        原文作者:Rango
        原文地址: https://segmentfault.com/a/1190000013767067
        本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
    点赞