PHP面试题

一面(技术基础)

表单提交中的Get和Post的异同点

get 请求一般用于向服务端获取数据,post 一般向服务端提交数据 get 传输的参数在 url 中,传递参数大小有限制,post 没有大小限制, get 不安全,post 安全性比get高 get请求在服务端用Request.queryString 接受 ,post 请求在服务端用Requset.form 接受

echo(),print(),print_r()的区别

数组[‘a’, ‘b’, ‘c’] 转换成字符串 ‘abc’ 获取字符串’aAbB’中A首次出现的位置

编写一段用最小代价实现将字符串完全反序, e.g. 将 “1234567890” 转换成 “0987654321”.

请用递归实现一个阶乘求值算法 F(n): n=5;F(## n)=5!=54321=120

将字符长fang-zhi-gang 转化为驼峰法的形式:FangZhiGang 数组内置的排序方法有哪些?

用PHP写出显示客户端IP与服务器IP的代码

语句include和require的区别是什么?为避免多次包含同一文件,可用(?)语句代替它们?

PHP 不使用第三个变量实现交换两个变量的值写一个方法获取文件的扩展名

用PHP打印出前一天的时间格式是2017-3-22 22:21:21

PHP 如何接口调用?

用PHP header()函数实现页面404错误提示功能

composer是什么?Composer和PHP有什么关系?

composer团队协作怎么保证版本统一?

OOP思想,特征和其意义

OOP的七大设计原则是什么?

mvc框架的生命周期说一下

session与cookie的区别是什么?

为什么session的安全性大于cookie?

session与cookie的应用场景有哪些?

php7新特性

php8新特性

手写一个单例模式吧

php垃圾回收机制php-fpm是什么?

php-fpm的运行模型?

cgi,php-cgi,php-fpm,fastcgi的区别? php-fpm如何完成平滑重启?

php-fpm和nginx的通信机制是怎么样的?

怎么选定用tcp还是套接字的方式和nginx通信? php-fpm在请求链路的体现,画出来?

php-fpm有几种工作模式?

怎么选定php-fpm的worker进程数? php-fpm如何优化?

说下你最常用的php框架(laravel框架)的生命周期? 怎么理解 依赖注入(DI)与控制反转(Ioc)?

php的弱类型是怎么实现的?

简单说下对php 底层变量(zval)数据结构的理解

PHP基础

表单提交中的Get和Post的异同点

  • get 请求一般用于向服务端获取数据,post 一般向服务端提交数据
  • get 传输的参数在 url 中,传递参数大小有限制,post 没有大小限制,
  • get 不安全,post 安全性比get高
  • get请求在服务端用Request.queryString 接受 ,post 请求在服务端用Requset.form 接受

echo(),print(),print_r()的区别

  • echo: 输出一个或多个参数

  • print: 输出一个参数

  • print_r: 打印简单信息

  • var_dump: 打印带类型的变量(类型,长度,值)

构造函数和析构函数

  • 构造函数:__construct :会在每次创建新对象时先调用此方法

  • 析构函数:__destruct :会在到某个对象的所有引用都被删除或者当对象被显式销毁时执行

析构函数即使在使用 exit() 终止脚本运行时也会被调用。在析构函数中调用 exit() 将会中止其余关闭操作的运行。

析构函数在脚本关闭时调用,此时所有的 HTTP 头信息已经发出。脚本关闭时的工作目录有可能和在 SAPI(如 apache)中时不同。

试图在析构函数(在脚本终止时被调用)中抛出一个异常会导致致命错误。

数组[‘a’, ‘b’, ‘c’] 转换成字符串 ‘abc’

echo implode(‘’,[‘a’, ‘b’, ‘c’]);
echo join([‘a’, ‘b’, ‘c’],'');

获取字符串’aAbB’中A首次出现的位置

$str=‘aAbB’;
echo strpos($str,"A");

编写一段用最小代价实现将字符串完全反序, e.g. 将 “1234567890” 转换成 “0987654321”.

1、使用函数
echo strrev("Hello World!");

2、不使用函数
$s = '1234567890';
$o = '';
$i = 0;
while(isset($s[$i]) && $s[$i] != null) {
    $o = $s[$i++].$o;
}

echo $o;

数组处理函数

PHP数组处理函数大全

字符串处理函数

PHP字符串处理函数大全

public、protected、private、final 区别

PHP 5 新增了一个 final 关键字。如果父类中的方法被声明为 final,则子类无法覆盖该方法。如果一个类被声明为 final,则不能被继承

类的静态调用和实例化调用

  • 静态调用不需要实例化即可调用

  • 静态方法不能调用非静态属性,因为非静态属性需要实例化后,存放在对象里

  • 静态方法可以调用非静态方法,使用 self 关键字。php 里,一个方法被 self:: 后,自动转变为静态方法

  • 调用类的静态函数时不会自动调用类的构造函数

PHP 不实例化调用方法

静态调用、使用 PHP 的反射

面向对象

  • 封装:能降低依赖,实现松耦合
  • 继承:子类自动继承父类的属性和方法,并可以重写,增加代码重用性,PHP不支持多继承
  • 多态:多个子类虽然都继承父类的同一个方法,但是可以得到不同的结果,增加了代码的灵活性

请用递归实现一个阶乘求值算法 F(n): n=5;F(# n)=5!=54321=120

function F($n)
{
    if ($n == 0) {
        return 1;
    } else {
        return $n * F($n - 1);
    }
}

将字符长fang-zhi-gang 转化为驼峰法的形式

// 方法一:
function Fun($str)
{
    if (isset($str) && !empty($str)) {
        $newStr = '';
        if (strpos($str, '-') > 0) {
            $strArray = explode('-', $str);
            $len      = count($strArray);
            for ($i = 0; $i < $len; $i++) {
                $newStr .= ucfirst($strArray[$i]);
            }
        }
        return $newStr;
    }
}

// 方法二:
function Fun($str)
{
    $arr1 = explode('_', $str);
    $str  = implode(' ', $arr1);
    return ucwords($str);
}

数组内置的排序方法有哪些?

sort($array);   //数组升序排序
rsort($array);  //数组降序排序
asort($array);  //根据值,以升序对关联数组进行排序
ksort($array);  //根据建,以升序对关联数组进行排序
arsort($array); //根据值,以降序对关联数组进行排序
krsort($array); // 根据键,以降序对关联数组进行排序

用PHP写出显示客户端IP与服务器IP的代码

$_SERVER["REMOTE_ADDR"]

语句include和require的区别是什么?为避免多次包含同一文件,可用(?)语句代替它们?

1、加载失败的处理方式不同
include与require除了在处理引入文件的方式不同外,最大的区别就是:
include在引入不存在的文件时,产生一个警告且脚本还会继续执行,
require则会导致一个致命性错误且脚本停止执行。
如果hello.php不存在,echo ‘world’这句是可以继续执行的。
如果hello.php不存在,echo ‘hello’这句是不会执行的,到require时就停止了。

2、include()是有条件包含函数,而 require()则是无条件包含函数。
3、文件引用方式
include有返回值,而require没有
可以用include_once,require_once代替,表示文件只引入一次,引入之后则不在引入,作为优化点

PHP 不使用第三个变量实现交换两个变量的值

list($b,$a)=array($a,$b);
var_dump($a,$b);

写一个方法获取文件的扩展名

//方法一
function get_extension($file){
    return substr(strrchr($file,'.'), 1);
}

//方法二
function get_extension($file){ 
    return end(explode('.', $file));
}

echo get_extension('fangzhigang.png'); //png

用PHP打印出前一天的时间格式是2017-3-22 22:21:21

$a = date("Y-m-d H:i:s", strtotime("-1 days"));

PHP 如何接口调用?

CURL

用PHP header()函数实现页面404错误提示功能

Header("HTTP/1.1 404 Not Found");

全局变量

变量名 说明
$GLOBALS 引用全局作用域中可用的全部变量
$_SERVER 服务器和执行环境信息
$_GET HTTP GET 变量
$_POST HTTP POST 变量
$_FILES HTTP 文件上传变量
$_REQUEST HTTP Request 变量
$_SESSION Session 变量
$_ENV 环境变量
$_COOKIE HTTP Cookies

魔术方法

方法名 说明
__get() 当调用一个未定义的属性时访问此方法
__set() 给一个未定义的属性赋值时调用
__isset() 当在一个未定义的属性上调用isset()函数时调用此方法
__unset() 当在一个未定义的属性上调用unset()函数时调用此方法
__call() 当调用一个未定义(包括没有权限访问)的方法时调用此方法
__autoload() 使用尚未被定义的类时自动调用
__construct() 构造函数,见上
__destruct() 析构函数,见上
__clone() 使用clone方法复制一个对象时,对象会自动调用__clone魔术方法
__toString() 将一个对象转化成字符串时自动调用
__sleep() 串行化的时候用
__wakeup() 反串行化的时候调用
__set_state() 当调用var_export()时,这个静态 方法会被调用(自PHP 5.1.0起有效)
__invoke() 当尝试以调用函数的方式调用一个对象时,__invoke 方法会被自动调用

魔术常量

附录1:运算符优先级

附录2:HTTP状态码

一般记住以下几个就可以了:

  • 200 :成功
  • 302 :重定向
  • 404 :没找到页面
  • 500 :服务器内部错误
  • 502 :从远程服务器接收到了一个无效的响应
  • 503 :超载暂时无法处理请求
  • 504 :超时,未从远端服务器获取请求

composer是什么?Composer和PHP有什么关系?

Composer 是PHP的一个依赖(dependency)管理工具,在我们的项目中声明所依赖的外部工具库(libraries),Composer 可以帮助我们安装这些依赖的库文件。Composer可以全局安装也可以局部安装,默认不是全局安装的,是基于指定项目的某个目录进行安装的。

composer团队协作怎么保证版本统一?

  • 安装组件使用composer install 而不是composer update,
  • .lock文件加入版本控制当中。

OOP思想,特征和其意义

  • 抽象、封装、继承和多态是面向对象的基础。

  • 抽象:提取现实世界中某事物的关键特性,为该事物构建模型的过程。对同一事物在不同的需求下,需要提取的特性可能不一样。得到的抽象模型中一般包含:属性(数据)和操作(行为)。这个抽象模型我们称之为类。对 类进行实例化得到对象。

  • 封装:封装可以使类具有独立性和隔离性;保证类的高内聚。只暴露给类外部或者子类必须的属性和操作。类封装的实现依赖类的修饰符(public、protected和private等)

  • 继承:对现有类的一种复用机制。一个类如果继承现有的类,则这个类将拥有被继承类的所有非私有特性(属性和操作)。这里指的继承包含:类的继承和接口的实现。

  • 多态:多态是在继承的基础上实现的。多态的三个要素:继承、重写和父类引用指向子类对象。父类引用指向不 同的子类对象时,调用相同的方法,呈现出不同的行为;就是类多态特性。多态可以分成编译时多态和运行时多态。

  • 帮助理解: https://www.cnblogs.com/waj6511988/p/6974291.html

OOP的七大设计原则是什么?

  • 开闭原则:对扩展开放,对修改关闭

  • 里氏替换原则:继承 必须保证 父类中的性质在子类中仍然成立

  • 依赖倒置原则:面向接口编程,而不面向实现类

  • 单一职责原则:控制 类的 粒度的大小 ,增强内聚性,减少耦合

  • 接口隔离原则:要为各个类提供所需的专用接口

  • 迪米特法则:迪米特法则(Law of Demeter)又叫作最少知识原则(The Least Knowledge Principle),一个类对于其他类知道的越少越好,就是说一个对象应当对其他对象有尽可能少的了解,只和朋友通信,不和 陌生人说话。英文简写为: LOD。

  • 合成复用原则:尽可能使用组合或者聚合等关系来关联类,其次才考虑使用继承。

前五个合称 SOLID原则(单一职责原则、开放关闭原则、里氏替换原则、接口隔离原则和依赖倒置原则)

mvc框架的生命周期说一下

session与cookie的区别是什么?

为什么session的安全性大于cookie?

session与cookie的应用场景有哪些?

php7新特性

标量类型声明
返回值类型声明
语法糖:null合并运算符,太空船操作符
define允许定义常量数组
匿名类,
新增了一些函数intdiv(),随机函数,

1、php7.0相比于php5.6的新特性 参考:http://php.net/manual/zh/migration70.new-features.php

2、php7.1相对于php7.0的新特性 参考:http://php.net/manual/zh/migration71.new-features.php

3、php7.2相对于php7.1的新特性 参考:http://php.net/manual/zh/migration72.new-features.php

php8新特性

新增联合类型(Union Types);
添加了 WeakMap;
添加了 ValueError 类;
新增的特性大多是语法糖,主要是JIT。
JIT是一种编译器策略,它将代码表述为一种中间状态,在运行时将其转换为依赖于体系结构的机器码,并即时执行,在PHP8中,Zend VM不需要解释某些操作码,并且这些指令将直接作为CPU级指令执行。
IT和opcache区别
要说明opcode cache与JIT的区别,得先明白,字节码,又叫中间码与机器码的区别。简答的说,提升php执行效率,更快了。

参考:鸟哥博客

手写一个单例模式吧

所谓单例模式,即在应用程序中最多只有该类的一个实例存在,一旦创建,就会一直存在于内存中!

单例设计模式常应用于数据库类设计,采用单例模式,只连接一次数据库,防止打开多个数据库连接。

单例模式的编写遵循三私一公,代码如下

<?php

class Database
{
    private $instance;

    private function __construct()
    {
        // Do nothing.
    }

    public static function getInstance()
    {
        if (!(self::$instance instanceof self)) {
            self::$instance = new self();
        }
        return self::$instance;
    }

    private function __clone()
    {
        // Do nothing.
    }
}

$a = Database::getInstance();
$b = Database::getInstance();
// true var_dump($a === $b);

php垃圾回收机制

关键词:使用了引用计数器

  • PHP可以自动进行内存管理,清除不需要的对象,主要使用了引用计数。

  • 在zval结构体中定义了ref_countis_ref , ref_count是引用计数 ,标识此zval被多少个变量引用 , 为0时会被销毁 。is_ref标识是否使用的 &取地址符强制引用。

  • 为了解决循环引用内存泄露问题 , 使用同步周期回收算法。

  • 当数组或对象循环的引用自身 , unset掉数组的时候 , 当refcount-1后还大于0的 , 就会被当成疑似垃圾 , 会进行遍历 ,并且模拟的删除一次refcount-1如果是0就删除 ,如果不是0就恢复。

参考:https://www.php.net/manual/zh/features.gc.php

php-fpm是什么?

重点:php-fpm是fastcgi的实现。

PHP5.3.3开始集成了php-fpm模块,不再是第三方的包了。

PHP-FPM提供了更好的PHP进程管理方式,可以有效控制内存和进程、可以平滑重载PHP配置。

php-fpm的运行模型?

重点:多进程同步阻塞模式

  • php-fpm是一种master(主)/worker(子)多进程架构模型。

  • 当PHP-FPM启动时,会读取配置文件,然后创建一个Master进程和若干个Worker进程(具体是几个Worker进 程是由php-fpm.conf中配置的个数决定)

  • Worker进程是由Master进程fork出来的。

  • master进程主要负责CGI及PHP环境初始化、事件监听、Worker进程状态等等,worker进程负责处理php请 求。

  • master进程负责创建和管理woker进程,同时负责监听listen连接,master进程是多路复用的;

  • woker进程负责accept请求连接,同时处理请求,一个woker进程可以处理多个请求(复用,不需要每次都创建销毁woker进 程,而是达到处理一定请求数后销毁重新fork创建worker进程),但一个woker进程一次只能处理一个请求。

cgi,php-cgi,php-fpm,fastcgi的区别?

cgi

cgi是一个web server与cgi程序(这里可以理解为是php解释器)之间进行数据传输的协议,保证了传递的是标准数据。

php-cgi

php-cgi是php解释器。他自己本身只能解析请求,返回结果,不会管理进程。php-fpm是调度管理php-cgi进 程的程序。

Fastcgi

Fastcgi是用来提高cgi程序(php-cgi)性能的方案/协议。

cgi程序的性能问题在哪呢?"PHP解析器会解析php.ini文件,初始化执行环境",就是这里了。 标准的CGI对每个请求都会执行这些步骤,所以处理的时间会比较长。

Fastcgi会先启一个master,解析配置文件,初始化执行环境,然后再启动多个worker。当请求过来时,master会传递给一个worker,然后立即可以接受下一个请求。这样就避免了重复劳动,效率自然提高。而且当worker 不够用时,master可以根据配置预先启动几个worker等着;当然空闲worker太多时,也会停掉一些,这样就提 高了性能,也节约了资源。这就是Fastcgi的对进程的管理。

php-fpm

fastcgi是一个方案或者协议,php-fpm就是FastCGI的后端实现,也就是说,进程分配和管理是FPM来做的。官 方对FPM的解释:【Fastcgi Process Manager】【Fastcgi 进程管理器】。 php-fpm的管理对象是php-cgi,他负责管理一个进程池,来处理来自Web服务器的请求。 对于php.ini文件的修改,php-cgi进程是没办法平滑重启的,有了php-fpm后,就把平滑重启成为了一种可能, php-fpm对此的处理机制是新的worker用新的配置,已经存在的worker处理完手上的活就可以歇着了,通过这 种机制来平滑过度的。

php-fpm如何完成平滑重启?

修改php.ini之后,php-cgi进程的确是没办法平滑重启的。

php-fpm对此的处理机制是新的worker用新的配置,

已经存在的worker处理完手上的活就可以歇着了,通过这种机制来平滑过度。

php-fpm和nginx的通信机制是怎么样的?

怎么选定用tcp还是套接字的方式和nginx通信?

tcp方式是面向链接的协议,更稳定。

套接字效率更高,但是限制nginx和php-fpm都在一台服务器。

php-fpm在请求链路的体现,画出来?

php-fpm有几种工作模式?

PHP-FPM进程管理方式有动态(Dynamic)、静态(Static)、按需分配(Ondemand)三种。

动态

会初始化创建一部分worker,在运行过程中,动态调整worker数量,最大worker数受pm.max_children和process.max

  1. 当空闲进程数小于min_spare_servers时,创建新的子进程,总子进程数小于等于pm.max_children,小于 等于process.max
  2. 当空闲进程数大于max_spare_servers,会杀死启动时间最长的子进程
  3. 如果子进程(idle状态)数大于max_children,会打印warning日志,结束处理
  4. process小于 max_children ,计算一个num,启动num个worker
  5. 优点:动态扩容,不浪费系统资源
  6. 缺点:所有worker都在工作,新的请求到来需要等待创建worker进程,最长等待1s(内部存在一个1s的定时 器,去查看,创建进程),频繁启停进程消耗cpu,请求数稳定,不需要频繁销毁

静态

启动固定大小数量的worker,也有1s的定时器,用于统计进程的一些状态信息,例如空闲worker个数,活动 worker个数

  1. 优点:不用动态判断负载,提升性能
  2. 缺点:如果配置成static,只需要考虑max_children数量,数量取决于cpu的个数和应用的响应时间,一次启 动固定大小进程浪费系统资源

按需分配

php-fpm启动的时候不会启动worker进程,按需启动worker,有链接进来后,才会启动

连接到来时(只有链接,不没有数据也会创建,telnet也会创建),创建新worker进程,worker进程数的创建收 max_children设置限制,也受限于全局的process.max设置(三种模式都受限此,下文中有全局配置项讲解), 如果空闲时间超过了process_idle_timeout的设置就会销毁worker进程

优点:按流量需求创建,不浪费系统资源, 缺点:因为php-fpm是短连接的,如果每次请求都先建立连接,大流量场景下会使得master进程变得繁忙,浪费cpu,不适合大流量模式

不推荐使用此模式

工作模式 特点
动态 均衡优先,适合小内存服务器,2g左右
静态 性能优先, 适合大内存机器
按需分配 内存优先,适合微小的内存,2g以下

怎么选定php-fpm的worker进程数?

动态建立进程个数

  • N+20% 到 M/m之间

  • N是cpu核数,M是内存,m是每个php进程内存数

静态进程个数

  • M/(m*1.2)
  • pm.max_requests, 设置最大请求数,达到这个数量以后,会自动长期worker进程,繁殖内存意外增长

cpu密集型的pm.max_children不能超过cpu内核数,但是web服务属于IO密集型的,可以将pm.max_children的值设置大于cpu核数。

注意:PHP程序在执行完成后,或多或少会有内存泄露的问题。这也是为什么开始的时候一个php-fpm进程只占 用3M左右内存,运行一段时间后就会上升到20-30M。所以需要每个worker进程处理完一定的请求后,销毁重 新创建。

php-fpm如何优化?

  • 避免程序跑死(hang) 在负载较高的服务器上定时重载php-fpm,reload可以平滑重启而不影响生产系统的php脚本运行,每15分钟reload一次,定时任务如下:

0-59/15 * * * * /usr/local/php/sbin/php-fpm reload

  • 合理增加单个worker进程最大处理请求数,减少内存消耗 最大处理请求数是指一个php-fpm的worker进程在处理多少个请求后就终止掉,master进程会重新respawn新 的。该配置可以避免php解释器自身或程序引起的memory leaks。默认值是500,可以修改为如下配置:

pm.max_requests = 1024

  • 开启静态模式,指定数量的php-fpm进程,减少内存消耗

说下你最常用的php框架(laravel框架)的生命周期?

怎么理解 依赖注入(DI)与控制反转(Ioc)?

这让我想起了怎么理解nginx正向代理和反向代理...

IOC(inversion of control)控制反转模式;控制反转是将组件间的依赖关系从程序内部提到外部来管理;

DI(dependency injection)依赖注入模式;依赖注入是指将组件的依赖通过外部以参数或其他形式注入;

依赖注入和控制反转说的实际上是同一个东西,它们是一种设计模式,这种设计模式用来减少程序间的耦合。

依赖注入和控制反转是对同一件事情的不同描述,从某个方面讲,就是它们描述的角度不同。

  • 依赖注入是从应用程序的角度在描述,可以把依赖注入,即:应用程序依赖容器创建并注入它所需要的外部 资源;

  • 而控制反转是从容器的角度在描述,即:容器控制应用程序,由容器反向的向应用程序注入应用程序所需要 的外部资源

laravel的控制反转

是通过反射和递归实现的容器,容器作为全局注册表,使用容器的依赖注入做为一种桥梁来解决依赖,使类之间 耦合度更低。

php的弱类型是怎么实现的?

php是通过c语言进行实现,但是c语言为强类型,那php的弱语言类型是通过PHP底层设计了一个zval(“Zend value”的缩写)的数据结构,可以用来表示任意类型的PHP值。通过共同体实现弱类型变量声明。

简单说下对php 底层变量(zval)数据结构的理解

  • 变量存储结构 变量的值存储到以下所示zval结构体中。 zval结构体定义在Zend/zend.h文件,其结构如下:
typedef struct _zval_struct zval;
...
struct _zval_struct {
    /* Variable information */
    zvalue_value value; /* value */
    zend_uint refcount__gc;
    zend_uchar type; /* active type */
    zend_uchar is_ref__gc;
};

PHP使用这个结构来存储变量的所有数据。和其他编译性静态语言不同,PHP在存储变量时将PHP用户空间的变量类型也保存在同一个结构体中。这样我们就能通过这些信息获取到变量的类型。

zval结构体中有四个字段,其含义分别为:

属性名 含义 默认值
refcount_gc 表示引用计数 1
is_ref_gc 表示是否为引用 0
value 存储变量的值
type 变量具体的类型
  • 变量类型

zval结构体的type字段就是实现弱类型最关键的字段了,

type的值可以为: IS_NULL、IS_BOOL、IS_LONG、IS_DOUBLE、IS_STRING、IS_ARRAY、IS_OBJECT和IS_RESOURCE 之一。

从字面上就很好理解,他们只是类型的唯一标示,根据类型的不同将不同的值存储到value字段。

除此之外,和他们定义在一起的类型还有 IS_CONSTANT和IS_CONSTANT_ARRAY。

这和我们设计数据库时的做法类似,为了避免重复设计类似的表,使用一个标示字段来记录不同类型的数据。

常见的设计模式有哪些?

简单说下单例模式,注册树模式,适配模式,策略模式,观察者模式。

单例

//简单工厂模式
//适用场景:创建对象比较少,业务逻辑不太复杂
<?php

//产品
class bike
{
    public function product($destination)
    {
        print_r($destination);
    }
}

class car
{
    public function product($destination)
    {
        print_r($destination);
    }
}

//工厂
class simpleFactory
{
    public function createBike($obj)
    {
        return new $obj();
    }
}

$factory = new simpleFactory();
$bike    = $factory->createBike("bike");
$bike->product("hello,bike");
$car = $factory->createBike("car");
$car->product("hello,car");
?>

观察者模式

//观察者模式 //适用场景:订阅者通知 //自己对观察者模式对理解: 需求:有事情变化你要通知我 实现: 1、要通知对人必须在我这里注册,否则我不知道要通知谁。 2、想要获取通知的人必须遵守我的规则,实现我指定的通知事件,不然我没办法统一通知,(比如高考 查分数,只支持电话查询,你非要微信查我肯定通知不到你) 3、事件发生的时候我会逐一通知你们。

<?php

//定义一个事件产生接口
interface obServer
{
    public function update($event_info = null);
}

//定义观察者接口

abstract class genEvent
{
    private $ob_servers = [];

    //增加观察者
    public function addObs($ob_server)
    {
        $this->ob_servers[] = $ob_server;
    }

    //通知
    public function notify()
    {
        if (!empty($this->ob_servers)) {
            foreach ($this->ob_servers as $ob_server) {
                $ob_server->update();
            }
        }
    }
}

class obServer1 implements obServer
{
    public function update($event_info = null)
    {
        echo "观察者1 收到执行通知\n";
    }
}

class obServer2 implements obServer
{
    public function update($event_info = null)
    {
        echo "观察者2 收到执行通知\n";
    }
}

class event extends genEvent
{
    //事件触发
    public function trigger()
    {
        $this->notify();
    }
}

//实现
$event = new event();
$event->addObs(new obServer1());
$event->addObs(new obServer2());
$event->trigger();
?>

适配器模式

<?php

//定义抽象类
abstract class Toy
{
    public abstract function openMouth();

    public abstract function closeMouth();
}

//定义dog
class dog extends Toy
{
    public function openMouth()
    {
        echo "Dog open Mouth\n";
    }

    public function closeMouth()
    {
        echo "Dog close Mouth\n";
    }
}

//cat
class cat extends Toy
{
    public function openMouth()
    {
        echo "Cat open Mouth\n";
    }
    public function closeMouth()
    {
        echo "Cat close Mouth\n";
    }
}

//红枣狗可以自己判断开关
interface redTarget
{
    public function doMouthOpen();
    public function doMouthClose();
}

interface greenTarget
{
    public function operateMouth($type=0);
}

//组成适配器
class redAdapter implements redTarget
{
    private $adaptee;

    //初始化对象
    public function __construct(Toy $adaptee)
    {
        $this->adaptee = $adaptee;
    }

    //委派调用Adaptee的sampleMethod1方法
    public function doMouthOpen()
    {
        $this->adaptee->openMouth();
    }

    public function doMouthClose()
    {
        $this->adaptee->closeMouth();
    }
}

//组成绿色遥控
class greenAdapter implements greenTarget
{
    private $adapter;
    //初始化对象
    public function __contruct(Toy $adapter)
    {
        $this->adapter = $adapter;
    }
    public function operateMouth($type = 0)
    {
        $type ? $this->adapter->openMouth() : $this->adapter->closeMouth();
    }
}

//测试
class testDriver
{
    public function run()
    {
        //实例化玩具狗
        $dog         = new dog();
        $adapter_dog = new redAdapter($dog);
        $adapter_dog->doMouthOpen();
        $adapter_dog->doMouthClose();
    }
}

$test = new testDriver();
$test->run();

注册树模式

<?php
//创建单例
class Single
{
    public           $hash;
    static protected $ins = null;

    final protected function __construct()
    {
        $this->hash = rand(1, 9999);
    }

    static public function getInstance()
    {
        if (self::$ins instanceof self) {
            return self::$ins;
        }
        self::$ins = new self();
        return self::$ins;
    }
}

//工厂模式
class RandFactory
{
    public static function factory()
    {
        return Single::getInstance();
    }
}

//注册树
class Register
{
    protected static $objects;

    public static function set($alias, $object)
    {
        self::$objects[$alias] = $object;
    }

    public static function get($alias)
    {
        return self::$objects[$alias];
    }

    public static function _unset($alias)
    {
        unset(self::$objects[$alias]);
    }
}

//调用
Register::set('rand', RandFactory::factory());
$object = Register::get('rand');
print_r($object);

MySQL基础

基本操作

  • 连接数据库: mysqld -uroot -p -h127.0.0.1 -p3306

  • 查看所有库: show databases;

  • 选择库: use laravel_dev;

  • 创建库: create database sxy_blog;

  • 删除库: drop database sxy_blog;

  • 查看所有表: show tables;

  • 查看表结构: show create table sxy_users;desc sxy_users;

  • 创建表:

create table shuxiaoyuan (
	`id` int unsigned not null auto_increment,
	`username` VARCHAR(255) NOT NULL,
	PRIMARY KEY (`id`)
);
  • 清空表数据:TRUNCATE shuxiaoyuan;

  • 删除表: drop table shuxiaoyuan;

  • 添加字段: bbb ,默认为 null,在字段 username 后面

 ALTER TABLE `shuxiaoyuan` add COLUMN `bbbb` CHAR(50) NULL DEFAULT NULL AFTER `username`;
  • 删除字段: ALTER TABLE 表名 DROP COLUMN 字段名;

  • 修改字段

# 修改字段长度:
ALTER TABLE 表名 MODIFY COLUMN 字段名  数据类型(修改后的长度)

# 修改字段名称
alter table <表名> change <字段名> <字段新名称> <字段的类型>

drop、truncate和delete的区别

先放一个链接吧:点击此处

CURD(核心,哈哈哈)

insert、select、update、delete

insert into shuxiaoyuan (aaa,bbb,ccc) value('1','2','3');
select * from shuxiaoyuan where aaa = '1';
update shuxiaoyuan set bbb = 'bbbbbb' where id = 1;
delete from shuxiaoyuan where id  = 1;

三范式

  • 属性具有原子性,不可再分
  • 唯一性约束,每条记录有唯一标识,非主键必须依赖主键
  • 冗余性约束,非主键之间不能相互依赖

乐观、悲观锁

说明:查询时 select for update,然后再提交 update 操作

实际中更严谨一点,带上更新前的状态,例如:

update order_table set status = '更新为已付款' where order_id = 001 and status = '更新前为待支付' and ...

乐观锁

我们在使用乐观锁时会假设在极大多数情况下不会形成冲突,只有在数据提交的时候,才会对数据是否产生冲突进行检验。如果数据产生冲突了,则返回错误信息,进行相应的处理。

实现:MySql最经常使用的乐观锁时进行 版本控制时间戳,也就是在数据库表中增加一列,记为version,当我们将数据读出时,将版本号一并读出,当数据进行更新时,会对这个版本号进行加 1,当我们提交数据时,会判断数据库表中当前的version列值和当时读出的version是否相同,若相同说明没有进行更新的操作,不然,则取消这次的操作。

悲观锁

MySql的悲观锁就是打开事务,当启动事务时,如果事务中的sql语句涉及到索引并用索引进行了条件判断,那么会使用行级锁锁定所要修改的行,否则使用表锁锁住整张表。

事务

ACID 特性:原子性(atomicity)、一致性(consistency)、隔离性(isolation)、持久性(durability)

深入了解:事务隔离级别

存储引擎

请直接点击此处

索引

请直接点击此处

聚族索引与非聚族索引的区别

  • 聚簇索引的叶子节点就是数据节点,而非聚簇索引的叶子节点仍然是索引节点,只不过有指向对应数据块的指针

如何优化数据库

范围太管,针对几个点回答一下就行

索引的正确使用和设计

mysql认知

三大范式是什么?

怎么区分三大范式?

数据库五大约束是什么?

主键是什么,怎么设置主键?

数据库的外键是什么?

innodb和myisam有什么区别?

什么是索引?

索引是个什么样的数据结构呢?

innodb索引的实现原理是什么?

btree和hash类型的索引有什么不同?

什么是覆盖索引?

B+树在满足聚簇索引和覆盖索引的时候不需要回表查询数据,什么是聚簇索引?

在建立索引的时候,都有哪些需要考虑的因素呢?

联合索引/多列索引的注意事项是什么?

导致索引失效的原因有哪些?

Explain 怎么用来做sql优化?

主键使用自增ID还是UUID?

字段为什么要求定义为not null?

drop、delete与truncate分别在什么场景之下使用?

MySQL中的varchar和char有什么区别?

varchar(10)和int(10)代表什么含义?

超大分页怎么处理?

关心过业务系统里面的sql耗时吗?统计过慢查询吗?

对慢查询都怎么优化过?

上面提到横向分表和纵向分表,可以分别举一个适合他们的例子吗?

LEFT JOIN 、RIGHT JOIN、INNER JOIN 区别?

UNION、UNION ALL区别?

说一说常用 的MySQL 函数

你的sql优化常用技巧有哪些?

同一个字段,用 int 还是 char 查询效率高?

SQL编写题,一些实例,考察一下

1、查询每个学生的学号、姓名和每门课的成绩;

2、查询都学过2号同学(sid=2)学习过的课程的同学的学号

3、查询“语文(cid=1)”课程比“数学(cid=2)”课程成绩高的所有学生的学号;

4、查询平均成绩大于60分的同学的学号和平均成绩;

5、查询所有同学的学号、姓名、选课数、总成绩;

6、查询姓“周”的老师的个数;

7、查询没学过“叶平”老师课的同学的学号、姓名;

8、查询学过“语文(cid=1)”并且也学过“数学(cid=2)”课程的同学的学号、姓名;

9、查询学过“叶平”老师所教的所有课的同学的学号、姓名;

10、查询课程编号“数学(cid=2)”的成绩比课程编号“语文(cid=1)”课程低的所有同学的学 号、姓名;

11、查询所有课程成绩小于60分的同学的学号、姓名;

12、查询没有学全所有课的同学的学号、姓名;

13、按平均成绩从高到低显示所有学生的“语文“、“数学”、“英语”三门的课程成绩,按如下形式显示: 学生ID,语文,数学,英语,有效课程数,有效平均分

14、查询各科成绩最高和最低的分:以如下形式显示:课程ID,最高分,最低分

15、查询男生、女生人数 :以如下形式显示:男生人数,女生人数

16、查询课程名称为“数学”,且分数低于60的学生姓名和分数

17、查询两门及两门以上不及格课程的同学的学号及其平均成绩

18、检索“cid=4”课程分数小于60,按分数降序排列的同学学号

hash索引的实现原理是什么?

讲一下你理解的B+树索引是怎么实现的?

索引是如何存储在磁盘上的?

什么是事务?

事务的四大特性?

没有隔离级别的话,多事务并发进行会造成什么问题?

事务的隔离级别和各自解决的问题是什么?

InnoDB使用的是哪种隔离级别呢?

数据库事务的使用的规范有哪些?

InnoDB怎么实现的事务ACID特性?

InnoDB的事务为什么是原子性的?

InnoDB是如何保证隔离性的?

事务的持久性如何保证?

事务的一致性,指的是什么?

MVCC是什么,如何实现?

InnoDB的MVCC实现原理是什么?

可重复读(repeatable read)级别如何避免幻读?

mysql的锁了解么,如何分类?

乐观锁和悲观锁是什么,如何实现?

锁的粒度有哪几种?

锁的兼容性对比

Nginx基础

什么是Nginx?

nginx的四大功能是什么?

nginx和apache的区别?

Nginx常用命令有哪些?

nginx报500、502、503、504 有什么区别?

Nginx的负载均衡算法都有哪些?

Nginx的反向代理和正向代理怎么理解?

为什么Nginx性能这么高?

为什么不使用多线程? 什么是C10K问题?

使用反向代理的优点是什么?

Nginx应用场景有哪些?

Nginx怎么处理请求的?

nginx的目录结构了解么?

Nginx配置文件nginx.conf有哪些属性模块?

虚拟主机是什么意思?

location的作用是什么?

location的语法能说出来吗?

Nginx 压缩了解吗,如何开启压缩?

nginx是如何实现高并发的?

Nginx的master和worker是如何工作的?

nginx怎么结合php处理动态请求?

nginx中fastcgi有什么优化点?

nginx的常用优化方案有哪些?

作为负载均衡,lvs和nginx有什么区别?

nginx如何实现限流?

nginx可以实现限速么?

Redis基础

什么是redis?

redis有哪些优缺点?

redis为什么快?

redis 和 memcached 的区别?

Redis有哪些数据类型?

Redis的应用场景有哪些?

redis的缓存使用会出现什么问题,对应解决方案有什么?

redis的数据持久化方式有哪些?

RDB的触发机制有几种?

AOF的运行机制是什么? 怎么开启AOF?

AOF的三种同步数据的选项是什么意思?

AOF和RDB比较?

如何选择合适的持久化方式?

怎么设置键的有效期?

缓存的常见删除策略有哪些?

redis中使用的过期删除策略是什么?

redis的内存淘汰策略是什么?

怎么解释过期键删除策略和内存淘汰机制之间的关系?

FIFO了解么?

redis支持的内存淘汰策略有哪些?

什么是LRU(高频问题)?

LRU在Redis中的实现?

如何php实现一个lru策略的缓存系统?

什么是LFU算法?

关于redis,一面和二面的区别

网络基础

说一下常见状态码和代表的意义

403可能出现的原因是什么,怎么解决?

500 一般是什么问题,如何解决?

503出现一般是什么问题?

nginx返回502,504各是什么问题,怎么解决?

说下网络分层和各层有啥协议

tcp和udp有啥区别?

UDP、TCP适用场景简述 TCP 三次握手?

简述TCP 四次挥手?

建立 TCP 连接为什么最后还要发送确认?

TIME-WAIT 是什么,为什么必须等待 2MLS?

为什么TCP建立连接握手是3次,挥手需要4次?

如果已经建立了连接,但是客户端突然出现故障了怎么办?

DNS 主要作用是什么?

http处于网络分层模型的哪一层?

HTTP 请求头部信息有哪些?

HTTP 报文的组成是怎么样的?

HTTP请求报文是怎样的?

HTTP响应报文是怎样的?

HTTP 2.0的特点有啥?

WebSocket是什么?

IPv6 与 IPv4 有什么变化?

什么是心跳机制?

简述IP协议?

同源策略是什么?

怎么允许跨域访问?

一个网页从输入地址回车,到完整展示网页内容这段时间里,做了哪些工作?

http和https的区别是什么?

https有什么缺点?

客户端在使用HTTPS方式与Web服务器是怎么通信的?

https协议的密钥生成过程是怎么样的(细节)?

二面(技术进阶)

PHP进阶

比较一下php和go的区别?

什么是守护进程?

如何实现守护进程?

如何理解框架?

框架常用的主要设计模式有哪些?

类的静态调用和实例化调用

接口和抽象的区别

PHP不实例化调用方法

有哪些常见的 php.ini 配置选项

MySQL、MySQLi、PDO 区别

php代码执行过程是怎样的?

怎么评价对象关系映射/ORM?

有哪些 PHP 支持回调的函数,如何实现?

PHP数组底层怎么实现的?

PHP内存管理机制与垃圾回收机制

MySQL进阶

为什么使用B+树,而不是用B*树

除了主键索引,还用过什么

主键索引和唯一索引的区别

最左匹配原则案例

order by 能用上索引么?

mysql索引的底层B+树,说说为什么使用B+树,跟红黑树有什么区别,B树和B+树的区别?

MYSQL分页limit速度太慢,如何优化?

为什么要对数据库进行主从分离?

索引查找在Linux的磁盘上是怎么操作的

innodb为什么必须要有主键索引?

使用InnoDB引擎,数据在硬盘上是如何存放的?

聚族索引与非聚族索引的区别

数据库主从复制 M-S 是怎么同步的?是推还是拉?会不会不同步?怎么办?

如何保障数据的可用性,即使被删库了也能恢复到分钟级别。你会怎么做?

数据库连接过多,超过最大值,如何优化架构。从哪些方便处理?

int 占多少字节?

bigint 呢?int (3) 和 int (11) 有区别吗?

可以往 int (3) 里存 1 亿吗?

varchar 最长多少?

drop delete truncate的区别?

where in (几个) where in (几万个) 有什么区别

innodb 的索引组织方式?

数量级在多少适合分表?

BTree 与 BTree-/BTree+ 索引原理是什么?

JOIN和UNION区别

mysql常见问题和解决思路?

死锁产生原因是什么?

什么是mysql的锁机制,以及什么是死锁,以及发生死锁的场景?

出现死锁的问题并不可怕,解决死锁通常有什么办法?

InnoDB的锁锁的类型

如何实现 MySQL 的读写分离?

MySQL 主从复制原理的是啥?

MySQL 主从同步延时问题

一个大表(数据有1000w)该怎么加索引?

Nginx进阶

如何修改worker进程数?

Nginx基本命令有哪些?

Nginx进程模型

Nginx抢占机制

怎么修改nginx打印的日志格式?

简单的说下nginx优化的点

keepalived是什么?

keepalived高可用故障转移原理是什么?

Redis进阶

缓存不一致怎么办?

ROB的原理是什么?

除了五种常见数据类型,还有其他的数据类型么?

分布式锁如何实现?

简述Redlock算法

主从同步是怎么实现的?

说一说你对redis集群架构的理解

redis的Sentinal哨兵模式是什么?

说一说数据类型的底层实现

redis的事件模型是什么?

keys读取命令为什么禁用?

redis禁用危险命令有哪些?

Redis连接时的connect与pconnect的区别是什么?

lua 脚本的作用是什么?

redis队列解决抢购高并发?

集合命令的实现方法

有序集合命令的实现方法脑裂问题是啥?

redis set 和get为什么这么快?

redis如何实现ACID?

跳跃表的时间复杂度是什么?

一致性哈希是什么?

哈希槽是什么?

集群情况下,节点较少时数据分布不均匀怎么办?

Linux

Linux 基础

Linux 目录结构文件描述符

命令与文件查找有哪些命令?

数据流怎么分类?

计划任务

I/O模型

Linux常用指令有哪些?

虚拟地址和物理地址是什么?

vim使用方式?

linux进程间通信(IPC)有什么方式?

信号机制是什么?

多线程和多进程的区别是什么?

硬链接与软链接的区别是什么?

如何查看某个进程中的线程?

查看某个文件夹中每个文件夹的大小

CPU负载的含义

怎么查看Linux服务器的负载,及判断哪些操作引起的负载过高?

如何统计日志文件中访问次数最多的十个ip地址?

在当前目录下,如何查找包含keyword文件?

docker了解么,说下你在工作中有没有使用?

cgroup在linux的具体实现?

网络

DNS是什么,怎么工作的?

TCP如何实现可靠交付?

TCP连接的三次握手讲一下

为什么建立连接是三次握手,关闭连接确是四次挥手?

为什么客户端最后在TIME_WAIT还要等待2MSL(最大报文存活时间)?

TCP流量控制是什么?

TCP拥塞控制是什么?

HTTP请求headers参数有哪些? 简述下tcp滑动窗口

算法

冒泡排序是什么,用php实现下?

快速排序是什么,用php实现下?

选择排序?

快速排序有什么优化点?

单向链表反转

无序链表如何查找中位数

判断一个数是不是质数

怎么计算时间复杂度?

递归

乘法口诀

二分查找

寻相同元素

寻最小的n个数抽奖

数组反转

随机打乱数组

寻找最小元素

背包算法

电梯算法

股票算法

找一个无序数组的中位数

用 PHP 的方式实现的各类算法合集

扩展学习:https://github.com/m9rco/algorithm-php

操作系统

什么是进程和线程?

进程和线程的关系是什么?

进程与线程的区别是什么?

进程的状态,各个状态之间如何切换?

怎么选择多进程还是多线程?

为什么进程上下文切换比线程上下文切换代价高?

什么是进程(线程)同步?

进程同步的任务和原则是什么?

协程是什么?

协程相比线程的优势是什么?

进程、线程、协程的堆栈区别是什么?

进程间通信的意义是什么?

进程间高级通信机制如何分类?

进程的调度

什么是共享内存,好处是什么?

共享内存是怎么实现的?

共享内存的特点是什么?

一个程序从开始运行到结束的完整过程(四个过程)是什么?

数据结构

布隆过滤器是什么,有什么特性?

布隆过滤器的优缺点?

布隆过滤器的原理是什么?

布隆过滤器的使用场景有哪些?

网络安全

cdn如何防劫持?

XSS攻击如何防御?

如何防御CSRF攻击?

如何防御中间人攻击?

如何有效防御DDOS攻击?

客户端http请求从服务器server到nginx到php响应返回整个流程?

分布式和微服务

什么是分布式,解决了什么问题?

怎么理解分布式的拆分?

什么是微服务,解决了什么问题?

微服务和soa的区别?

zk的分布式协调是什么?

zk如何实现分布式锁?

zk的元数据/配置信息管理

zk如何保证HA高可用性?

分布式系统中的CAP理论,了解么?

服务容错的保护措施有哪些?

微服务的API网关是什么?

API网关功能是什么?

服务发现是什么?

说一下你对中台的理解比较有价值的扩展学习

线上故障处理经验

架构

通用型业务解决方案

高并发下如何保持一致性?

软件测试的阶段和方法有哪些

雪崩效应解决方案

两个海量数据的同构表,如何查询数据差异?

怎么设计一套通信接口的标准?

工作中有用到ES么

如何设计SKU表结构

如何设计RBAC表结构

如何设计防超卖的架构

如何设计高并发的架构

怎么理解SaaS,如何设计SaaS项目的架构

如何设计新浪关注feed流的架构

怎么设计短url服务

如何实现接口幂等性?

如何设计高可用的订单业务架构

如何设计单点登录的架构

如何应对大流量高并发?

团队开发中,git分支管理怎么设定策略?

项目设计

如何设计秒杀架构?

有哪些方式生成唯一ID?

三面(技术终面)

四面(hr&hrbp)

Linux基础知识

说明:最开始的功能是为了应付面试的,有时间的话慢慢完善

基本命令

高频:面试喜欢问的

chmod

语法:chmod [-cfvR] [--help] [--version] mode file...

mode : 权限设定字串,格式如下 :[ugoa...][[+-=][rwxX]...][,...]

  • u 表示该文件的拥有者,g 表示与该文件的拥有者属于同一个群体(group)者,o 表示其他以外的人,a 表示这三者皆是。

  • + 表示增加权限、- 表示取消权限、= 表示唯一设定权限。

  • r 表示可读取,w 表示可写入,x 表示可执行,X 表示只有当该文件是个子目录或者该文件已经被设定过为可执行。

其他参数说明:

  • -c : 若该文件权限确实已经更改,才显示其更改动作
  • -f : 若该文件权限无法被更改也不要显示错误讯息
  • -v : 显示权限变更的详细资料
  • -R : 对目前目录下的所有文件与子目录进行相同的权限变更(即以递回的方式逐个变更)
  • --help : 显示辅助说明
  • --version : 显示版本

chown

目录解释

  • /bin:bin 是 Binary 的缩写, 这个目录存放着最经常使用的命令。

  • /boot:这里存放的是启动Linux时使用的一些核心文件,包括一些连接文件以及镜像文件。

  • /dev:dev 是 Device (设备)的缩写, 该目录下存放的是 Linux 的外部设备,在 Linux 中访问设备的方式和访问文件的方式是相同的。

  • /etc:这个目录用来存放所有的系统管理所需要的配置文件和子目录。

  • /home:用户的主目录,在Linux中,每个用户都有一个自己的目录,一般该目录名是以用户的账号命名的。

  • /lib:这个目录里存放着系统最基本的动态连接共享库,其作用类似于Windows里的DLL文件。几乎所有的应用程序都需要用到这些共享库。

  • /lost+found:这个目录一般情况下是空的,当系统非法关机后,这里就存放了一些文件。

  • /media:linux系统会自动识别一些设备,例如U盘、光驱等等,当识别后,linux会把识别的设备挂载到这个目录下。

  • /mnt:系统提供该目录是为了让用户临时挂载别的文件系统的,我们可以将光驱挂载在/mnt/上,然后进入该目录就可以查光驱里的内容了。

  • /opt: 这是给主机额外安装软件所摆放的目录。比如你安装一个ORACLE数据库则就可以放到这个目录下。默认是空的。

  • /proc:这个目录是一个虚拟的目录,它是系统内存的映射,我们可以通过直接访问这个目录来获取系统信息。 这个目录的内容不在硬盘上而是在内存里,我们也可以直接修改里面的某些文件,比如可以通过下面的命令来屏蔽主机的ping命令,使别人无法ping你的机器:

echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_all
  • /root:该目录为系统管理员,也称作超级权限者的用户主目录。

  • /sbin:s就是Super User的意思,这里存放的是系统管理员使用的系统管理程序。

  • /selinux: 这个目录是Redhat/CentOS所特有的目录,Selinux是一个安全机制,类似于 windows 的防火墙,但是这套机制比较复杂,这个目录就是存放selinux相关的文件的。

  • /srv: 该目录存放一些服务启动之后需要提取的数据。

  • /sys: 这是linux2.6内核的一个很大的变化。该目录下安装了2.6内核中新出现的一个文件系统 sysfs 。 sysfs文件系统集成了下面3种文件系统的信息:针对进程信息的proc文件系统、针对设备的devfs文件系统以及针对伪终端的devpts文件系统。 该文件系统是内核设备树的一个直观反映。 当一个内核对象被创建的时候,对应的文件和目录也在内核对象子系统中被创建。

  • /tmp:这个目录是用来存放一些临时文件的。

  • /usr: 这是一个非常重要的目录,用户的很多应用程序和文件都放在这个目录下,类似于windows下的program files目录。

  • /usr/bin:系统用户使用的应用程序。

  • /usr/sbin:超级用户使用的比较高级的管理程序和系统守护程序。

  • /usr/src:内核源代码默认的放置目录。

  • /var:这个目录中存放着在不断扩充着的东西,我们习惯将那些经常被修改的目录放在这个目录下。包括各种日志文件。

  • /run:是一个临时文件系统,存储系统启动以来的信息。当系统重启时,这个目录下的文件应该被删掉或清除。如果你的系统上有 /var/run目录,应该让它指向 run。

注意安全

跨站脚本攻击(XSS)

就是在URL上带一段 JavaScript 代码 防止就是将html标识符转换成实体,在PHP中可以用 htmlspecialchars函数来操作

跨站点请求伪造(CSRF)

就是拿到你正常网站的cookie了,然后用冒充正常请求 预防方法

  • 检查请求来源
  • 增加随机token
  • 增加验证码等

DDOS攻击(无解)

控制肉鸡,合法请求,基本无解,可以利用云服务商提供的服务

SQL注入

对传递的参数没做检查,导致拼接的查询语句不是实际想要的

例如:

# 原本相查询的语句
select * from users where username = 'shuxiaoyuan';

# 经过伪造
select * from users where username='shuxiaoyuan' or 1=1#' and password=md5('');

# 等价于
select* from users where username='shuxiaoyuan' or 1=1

防护也很简单

  • 参数绑定,不要做字符串拼接
  • 用PDO,ORM等
  • 转移字符,mysql_real_escape_string

PHP安全

文件包含漏洞

包含上传文件,上传图片

代码执行漏洞

危险函数 execshell_execsystem可以直接执行系统命令。eval 函数可以执行 PHP 代码

缓存机制

Redis相关知识点

十大经典排序算法

十大经典排序算法

PHP实现十大经典算法

冒泡排序

选择排序

插入排序

希尔排序

归并排序

快速排序

堆排序

计数排序

桶排序

基数排序

PHP常见经典算法

猴子选大王

一群猴子排成一圈,按1,2,…,n依次编号。然后从第1只开始数,数到第m只,把它踢出圈,从它后面再开始数,再数到第m只,在把它踢出去…,如此不停的进行下去,直到最后只剩下一只猴子为止,那只猴子就叫做大王。要求编程模拟此过程,输入m、n, 输出最后那个大王的编号。

    private function monkey($n, $m) {
        $monkeys = range(1, $n);
        $i = 0;

        while (count($monkeys) > 1) {
            if (($i + 1) % $m == 0) {
                unset($monkeys[$i]);    // 如果是第 m 个,则踢出去
            } else {
                array_push($monkeys, $monkeys[$i]); // 如果不是第 m 个,则把这个插入数组尾部
                unset($monkeys[$i]);
            }

            $i++;
        }

        return current($monkeys);
    }

遍历文件夹

	/**
	 * 遍历文件夹
	 *
	 * @param $dir
	 * @return array
	 */
	public function my_dir($dir) {
		$files = array();
		if (@$handle = opendir($dir)) { //注意这里要加一个@,不然会有warning错误提示:)
			while (($file = readdir($handle)) !== false) {
				if ($file != ".." && $file != ".") { //排除根目录;
					if (is_dir($dir . "/" . $file)) { //如果是子文件夹,就进行递归
						$files[$file] = $this->my_dir($dir . "/" . $file);
					} else { //不然就将文件的名字存入数组;
						$files[] = $file;
					}
				}
			}
			closedir($handle);
			return $files;
		}
	}

杨辉三角

斐波那契数列,兔子繁殖

    private function tuzi($n) {
        $arr = [1, 1];
        if ($n < 2) {
            return $arr;
        }

        for ($i = 2; $i <= $n + 1; $i++) {
            $arr[$i] = $arr[$i - 1] + $arr[$i - 2];
        }

        return $arr;
    }

水仙花数

水仙花数:是指一个 3 位数,它的每个位上的数字的 3 次幂之和等于它本身(例如:1^3 + 5^3+ 3^3 = 153)。

    private function shuixianhua() {
        $arr = [];
        for ($i = 100; $i < 1000; $i++) {
            $hundreds = floor($i / 100);//分解出百位
            $tens = floor($i / 10) % 10;//分解出十位
            $ones = floor($i % 10);//分解出个位

            if (pow($hundreds, 3) + pow($tens, 3) + pow($ones, 3) == $i) {
                $arr[] = $i;
            }
        }

        return $arr;
    }

PHP奇异算法

PHP7以下的版本返回的是 6,PHP7版本返回5

<?php
function test(){
 $a=1;
 $b=&$a;
 echo (++$a)+(++$a);
}
test();

字符集合

输入一个字符串,求出该字符串包含的字符集合,并按顺序排序(英文)

多进程同时写文件

无限级分类

16

现在有一个字符串,你要对这个字符串进行 n 次操作,每次操作给出两个数字:(p, l) 表示当前字符串中从下标为 p 的字符开始的长度为 l 的一个子串。你要将这个子串左右翻转后插在这个子串原来位置的正后方,求最后得到的字符串是什么。字符串的下标是从 0 开始的,你可以从样例中得到更多信息。

每组测试用例仅包含一组数据,每组数据第一行为原字符串,长度不超过 10 ,仅包含大小写字符与数字。接下来会有一个数字 n 表示有 n 个操作,再接下来有 n 行,每行两个整数,表示每次操作的(p , l)。

保证输入的操作一定合法,最后得到的字符串长度不超过 1000。

17

你作为一名出道的歌手终于要出自己的第一份专辑了,你计划收录 n 首歌而且每首歌的长度都是 s 秒,每首歌必须完整地收录于一张 CD 当中。每张 CD 的容量长度都是 L 秒,而且你至少得保证同一张 CD 内相邻两首歌中间至少要隔 1 秒。为了辟邪,你决定任意一张 CD 内的歌数不能被 13 这个数字整除,那么请问你出这张专辑至少需要多少张 CD ?

每组测试用例仅包含一组数据,每组数据第一行为三个正整数 n, s, L。 保证 n ≤ 100 , s ≤ L ≤ 10000

获取上个月第一天 和 最后一天

随机输入一个数字能查询到对应的数据区间

用PHP实现一个双向队列

洗牌算法

输出101-200之间的所有素数

输入某年某月某日,判断这一天是这一年的第几天?

算年龄

有5个人坐在一起,问第五个人多少岁?他说比第4个人大2岁。问第4个人岁数,他说比第3个人大2岁。问第三个人,又说比第2人大两岁。问第2个人,说比第一个人大两岁。最后问第一个人,他说是10岁。请问第五个人多大?

1.程序分析:利用递归的方法,递归分为回推和递推两个阶段。要想知道第五个人岁数,需知道第四人的岁数,依次类推,推到第一人(10岁),再往回推。

回文数

回文数,个位与万位相同,十位与千位相同,例如:12321是回文数。

参考链接 https://www.cnblogs.com/clubs/p/10373814.html

设计模式

单例模式

工厂模式

注册模式

适配器模式

策略模式

观察者模式

原型模式

参考链接 https://learnku.com/docs/php-design-patterns/2018/translation-instructions/1486

架构方向

  • 登陆认证 OAuth 2.0
  • 单点登陆
  • REST
  • API版本兼容问题
  • JWT
  • Nginx
  • 微服务
  • 分布式事务
  • ID生成器
  • Redis集群
  • 穿透、雪崩
  • 限流(木桶、令牌桶)

面试问到的

PHP

PHP接口类和抽象类

如果一个方法,参数太多,比如10个以上,怎么优化或者封装

PHP的链式调用 设计模式

composer自动加载

laravel的生命周期、如何理解依赖注入和控制反转

PHP 不实例化调用方法

MySQL

mysql的索引

mysql的索引优化 精确到为什么这么做 举几个例子

如果数据量非常大的分页怎么处理的

redis的主从

mysql的主从,如何解决数据对不上

mysql主从同步原理

mysql的 表锁 行锁 间隙锁,怎么解决这些锁

如何构建高性能mysql

如何使用覆盖索引

请说下 mysql的 脏读 幻读

分库分表

锁、乐观锁、悲观锁

where in (几个) where in (几万个) 有什么区别

Redis

redis的淘汰规则 LRU和LFU请举例说明

缓存雪崩

redis的完整原子性怎么保证

redis数据类型

各个类型的使用场景

redis的布隆

redis的bitmaps

list和set和sortset的区别

是否手动实现过队列

redis的哨兵 集群

nginx的负载均衡

秒杀超卖

redis同步原理