2019-05-20

找工作一个月没找到工作,面临人生的挑战感到迷茫与无力感,开始质疑自己的能力开始想换行?生活并有没给你压力,而是你自己给自己压力,其实并不是你能力不行,而是因为你没有充分准备,即使机会在你面前也抓不住,下面的面试题希望能帮到自己,也能帮到你们:

1、基础方面


1、什么是composer?以及composer是干什么用的?Composer是PHP的一个依赖管理工具。

2、PHP如何实现静态化
PHP伪静态:是利用Apache mod_rewite实现url重写的方法。
局部静态化:在完全静态化的基础上,通过ajax处理局部页面
完全静态化:
    就是将整个页面进行静态化,可以使用php缓冲区函数,将缓冲区内容输入到静态文件中。并设置过期时间,若静态文件超出过期时间,则重新进行静态化。 
< ?php
//页面静态页,一般在MVC框架的控制器中实现。
//譬如:www.test.php/news/view?id=2
//静态化为 www.test.php/news/view_2.html
//静态化页面路径
$id = isset($_GET['id']) ? $_GET['id'] : 0;

$filePath = "./news/view_".$id.".html";

//过期时间10s
$expire = 10;

if (file_exists($filePath)) {
    $ctime = filectime($filePath);
    if (time() - $ctime > 10) {
        //已过期,删除原有文件,并生成新的静态页
        unlink($filePath);

        ob_start();
        include("./view2.html"); //加载信息页
        $content = ob_get_contents();
        file_put_contents($filePath, $content); //将缓冲区内容输出到静态页                                  
        ob_end_flush(); //刷出缓冲区内容并结束缓冲
    } else {

        include($filePath);

    }
} else {
    ob_start();
    include("./view2.html"); //加载信息页
    $content = ob_get_contents();
    file_put_contents($filePath, $content); //将缓冲区内容输出到静态页            
    ob_end_flush(); //刷出缓冲区内容并结束缓冲
}

3、说下你最常用的设计模式
策略模式:策略模式是对象的行为模式,用意是对一组算法的封装。动态的选择需要的算法并使用。比如说购物车系统,在给商品计算总价的时候,普通会员肯定是商品单价乘以数量,但是对中级会员提供8者折扣,对高级会员提供7折折扣,这种场景就可以使用策略模式实现。 
< ?php
//抽象策略角色《为接口或者抽象类,给具体策略类继承》
interface Strategy 
{

    public function computePrice($price);

} 
//具体策略角色-普通会员策略类
class GenernalMember implements Strategy
{
    public function computePrice($price)
    {

        return $price;  

    }
}
//具体策略角色-中级会员策略类
class MiddleMember implements Strategy
{
    public function computePrice($price)
    {

        return $price *0.8;  

    }
}
//具体策略角色-高级会员策略类
class HignMember implements Strategy
{
    public function computePrice($price)
    {

        return $price *0.7;  

    }
}
//环境角色实现类
class Price
{
    //具体策略对象
    private $strategyInstance;
    //构造函数
    public function __construct($instance)
    {

      $this->strategyInstance = $instance;  
        
    }
    public function compute($price)
    {

      return $this->strategyInstance->computePrice($price);  

    }
}
//客户端使用
$p = new Price(new HignMember());
$totalPrice = $p->compute(100);
echo $totalPrice;//70
?>
单例模式:又称为职责模式,它用来在程序中创建一个单一功能的访问点,通俗地说就是实例化出来的对象是唯一的。
所有的单例模式至少拥有以下三种公共元素:
1.它们必须拥有一个构造函数,并且必须被标记为private
2.它们拥有一个保存类的实例的静态成员变量
3.它们拥有一个访问这个实例的公共的静态方法
单例类不能再其它类中直接实例化,只能被其自身实例化。它不会创建实例副本,而是会向单例类内部存储的实例返回一个引用。
class Single {
    private $name;//声明一个私有的实例变量      
    private function __construct(){//声明私有构造方法为了防止外部代码使用new来创建对象。

    }
    static public $instance;//声明一个静态变量(保存在类中唯一的一个实例)
    static public function getinstance(){//声明一个getinstance()静态方法,用于检测是否有实例对象        
        if(!self::$instance) self::$instance = new self();
        return self::$instance;    
    }
    public function setname($n){ $this->name = $n; }
    publicfunctiongetname(){ return$this->name; }
}
$oa = Single::getinstance();
$ob = Single::getinstance();
$oa->setname('hello world');
$ob->setname('good morning');
echo $oa->getname();//good morning
echo $ob->getname();//good morning

工厂模式:使用工厂模式的好处是,如果你想要更改所实例化的类名等,则只需更改该工厂方法内容即可,不需逐一寻找代码中具体实例化的地方(new处)修改了。为系统结构提供灵活的动态扩展机制,减少了耦合。
class Factory{//创建一个基本的工厂类    
    static public function fac($id){//创建一个返回对象实例的静态方法
          if(1 == $id) return new A();                       
          elseif(2==$id) return new B();
          elseif(3==$id) return new C();
          return new D();    
    }
}
interface FetchName{//创建一个接口    
    public function getname();//
}
class A implements FetchName{
    private $name ="AAAAA";
    public function getname(){return $this->name; }
}
class C implements FetchName{
    private $name ="CCCCC";
    public function getname(){return $this->name; }
}
class B implements FetchName{
    private $name ="BBBBB";
    public function getname(){return $this->name; }
}
class D implements FetchName{
    private $name ="DDDDD";
    public function getname(){return $this->name; }
}
$o = Factory::fac(6);//调用工厂类中的方法
if($o instanceof FetchName){
    echo $o->getname();//DDDDD
}
 $p = Factory::fac(3);
echo $p->getname();//CCCCC

注册模式:注册模式,解决全局共享和交换对象。已经创建好的对象,挂在到某个全局可以使用的数组上,在需要使用的时候,直接从该数组上获取即可。将对象注册到全局的树上。任何地方直接去访问。
class Register{
    protected static $objects;
    public static functionset($alias,$object){
        self::$objects[$alias]=$object;    
    }
    public static functionget($alias){
        return self::$objects[$alias];    
    }
    public static function_unset($alias){
        unset(self::$objects[$alias]);    
    }
}

适配器模式:将各种截然不同的函数接口封装成统一的API。PHP中的数据库操作有MySQL,MySQLi,PDO三种,可以用适配器模式统一成一致,使不同的数据库操作,统一成一样的API。类似的场景还有cache适配器,可以将memcache,redis,file,apc等不同的缓存函数,统一成一致。

观察者模式(Observer):当一个对象的状态发生改变时,依赖他的对象会全部收到通知,并自动更新。

4、PHP的优化方案

1、如果能将类的方法定义成static,就尽量定义成static,它的速度会提升将近4倍。
2、$row[’id’]的速度是$row[id]的7倍。
3、注销那些不用的变量尤其是大数组,以便释放内存。
4、尽量避免使用__get,__set,__autoload。
5、require_once()代价昂贵。
6、include文件时尽量使用绝对路径,因为它避免了PHP去include_path里查找文件的速度,解析操作系统路径所需的时间会更少。
7、如果你想知道脚本开始执行 (译注:即服务器端收到客户端请求)的时刻,使用$_SERVER[‘REQUEST_TIME’]要好于time() 8、函数代替正则表达式完成相同功能。
9、str_replace函数比preg_replace函数快,但strtr函数的效率是str_replace函数的四倍。
10、如果一个字符串替换函数,可接受数组或字符作为参数,并且参数长度不太长,那么可以考虑额外写一段替换代码,使得每次传递参数是一个字符,而不是只写一行代码接受数组作为查询和替换的参数。
11、使用选择分支语句 (译注:即switchcase)好于使用多个
if,elseif语句。
12、用@屏蔽错误消息的做法非常低效,极其低效。
13、打开apache的mod_deflate模块,可以提高网页的浏览速度。
14、数据库连接当使用完毕时应关掉,不要用长连接。
15、在方法中递增局部变量,速度是最快的。几乎与在函数中调用局部变量的速度相当。递增一个全局变量要比递增一个局部变量慢2倍。递增一个对象属性 (如:$this - >prop++)要比递增一个局部变量慢3倍。递增一个未预定义的局部变量要比递增一个预定义的局部变量慢9至10倍。
16、仅定义一个局部变量而没在函数中调用它,同样会减慢速度 (其程度相当于递增一个局部变量)。PHP大概会检查看是否存在全局变量。
17、方法调用看来与类中定义的方法的数量无关,因为我 (在测试方法之前和之后都)添加了10个方法,但性能上没有变化。18、派生类中的方法运行起来要快于在基类中定义的同样的方法。
19、调用带有一个参数的空函数,其花费的时间相当于执行7至8次的局部变量递增操作。类似的方法调用所花费的时间接近于15次的局部变量递增操作。
20、Apache解析一个PHP脚本的时间要比解析一个静态HTML页面慢2至10倍。尽量多用静态HTML页面,少用脚本。
21、除非脚本可以缓存,否则每次调用时都会重新编译一次。引入一套PHP缓存机制通常可以提升25 % 至100 % 的性能,以免除编译开销。
22、尽量做缓存,可使用memcached。memcached是一款高性能的内存对象缓存系统,可用来加速动态Web应用程序,减轻数据库负载。对运算码 (OP code)的缓存很有用,使得脚本不必为每个请求做重新编译。
23、当操作字符串并需要检验其长度是否满足某种要求时,你想当然地会使用strlen()函数。此函数执行起来相当快,因为它不做任何计算,只返回在zval结构 (C的内置数据结构,用于存储PHP变量)中存储的已知字符串长度。但是,由于strlen()是函数,多多少少会有些慢,因为函数调用会经过诸多步骤,如字母小写化 (译注:指函数名小写化,PHP不区分函数名大小写)、哈希查找,会跟随被调用的函数一起执行。在某些情况下,你可以使用isset()技巧加速执行你的代码。
24、当执行变量$i的递增或递减时,$i++会比++$i慢一些。这种差异是PHP特有的,并不适用于其他语言,所以请不要修改你的C或Java代码并指望它们能立即变快,没用的。++$i更快是因为它只需要3条指令 (opcodes),$i++则需要4条指令。后置递增实际上会产生一个临时变量,这个临时变量随后被递增。而前置递增直接在原值上递增。这是最优化处理的一种,正如Zend的PHP优化器所作的那样。牢记这个优化处理不失为一个好主意,因为并不是所有的指令优化器都会做同样的优化处理,并且存在大量没有装配指令优化器的互联网服务提供商 (ISPs)和服务器。
25、并不是事必面向对象 (OOP),面向对象往往开销很大,每个方法和对象调用都会消耗很多内存。
26、并非要用类实现所有的数据结构,数组也很有用。
27、尽量采用大量的PHP内置函数。
28、如果在代码中存在大量耗时的函数,你可以考虑用C扩展的方式实现它们。
29、评估检验 (profile)你的代码。检验器会告诉你,代码的哪些部分消耗了多少时间。Xdebug调试器包含了检验程序,评估检验总体上可以显示出代码的瓶颈。
30、mod_zip可作为Apache模块,用来即时压缩你的数据,并可让数据传输量降低80 % 。
31、在可以用file_get_contents替代file、fopen、feof、fgets等系列方法的情况下,尽量用file_get_contents,因为他的效率高得多 ! 但是要注意file_get_contents在打开一个URL文件时候的PHP版本问题;
32、尽量的少进行文件操作,虽然PHP的文件操作效率也不低的;
33、优化Select SQL语句,在可能的情况下尽量少的进行Insert、Update操作 (在update上,我被恶批过);
34、循环内部不要声明变量,尤其是大变量:对象 (这好像不只是PHP里面要注意的问题吧 ? );
35、多维数组尽量不要循环嵌套赋值;
36、在可以用PHP内部字符串操作函数的情况下,不要用正则表达式;
37、foreach效率更高,尽量用foreach代替
while和
for循环;
38、用单引号替代双引号引用字符串;
39、“用i += 1代替i = i + 1。符合c / c++的习惯,效率还高”;
40、对global变量,应该用完就unset()掉;

5、说下你了解的session和cookie
cookie数据存放在客户的浏览器上,不是很安全。
session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能。

关闭cookie,使用session的方法
       1. 设置php.ini配置文件中的“session.use_trans_sid = 1”

6、如何实现不基于session和cookie的用户认证。
将用户信息加密放到http的header部分,每次拿到http的时候,,验证获取header的信息

7、什么是CSRF攻击,XSS攻击,SQL注入攻击?如何防范

CSRF攻击:跨站请求伪造解决方法:向表单添加字段标记
XSS攻击:原则是将一段JavaScript代码注入网页。然后当其他用户访问该页面时,他们将运行黑客编写的JS代码来实现一些帐户控制。解决方案:关键字判断当有一个关键字如脚本、src来代替损坏;返回内容时进行转码,转码尖括号采用Unicode编码格式。
SQL注入攻击:在提交表单时输入sql语句解决方案:在业务逻辑层中执行关键字检查。
如果包含SQL的关键字,例如 * 、or、select、delete等等关键字就进行替换;最有效的仍然是使用SQL变量进行查询,避免使用字符串来拼接SQL字符串。

8、设计的原则
单一职责原则:类的职责要单一,不能将太多的职责放在一个类中
开闭原则:
软件实体对扩展是开放的,但对修改是关闭的,即在不修改一个软件实体的基础上去扩展其功能
里氏替换原则:
在软件系统中,一个可以接受基类对象的地方必然可以接受一个子类对象
依赖倒转原则:
要针对抽象层编程,而不要针对具体类编程接口隔离原则:
使用多个专门的接口来取代一个统一的接口组合 / 聚合复用原则:
在系统中应该尽量使用组合和聚合关联关系,尽量少使用甚至不使用继承关系
迪米特法则:
一个软件实体对其他实体的引用越少越好,或者说如果两个类不必彼此直接通信,那么这两个类就不应当发生直接的相互作用,而是通过引入一个第三者发生间接交互

9、什么是mvc?相互间有什么关系MVC是一种开发模式,主要分为三部分:M(模型),也就是模型,负责数据的操作;
V(视图),也就是视图,负责前后台的显示;
C(控制器),也就是控制器,负责业务逻辑;客户端请求项目的控制器,
如果执行过程中需要用到数据,
控制器就会到模型中获取数据,
再将获取到的数据通过视图显示出来;

10、php错误异常处理
Exception抛出异常

全局:php.ini中设置display_error = on/off;

局部:ini_set("display_error", true/false);

11、抽象类和接口的区别以及使用场景
1.interface需要实现,要用implements,而abstract class需要继承,要用extends。

2.一个类可以实现多个interface,但一个类只能继承一个abstract class。

3.interface强调特定功能的实现,而abstract class强调所属关系。

使用场景
1.如果要创建一个模型,这个模型将由一些紧密相关的对象采用,就可以使用抽象类。如果要创建将由一些不相关对象采用的功能,就使用接口。
2.如果必须从多个来源继承行为,就使用接口。
3.如果知道所有类都会共享一个公共的行为实现,就使用抽象类,并在其中实现该行为。

12、HTTPS和HTTP的区别主要如下:

1、https协议需要到ca申请证书,一般免费证书较少,因而需要一定费用。

2、http是超文本传输协议,信息是明文传输,https则是具有安全性的ssl加密传输协议。

3、http和https使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443。

4、http的连接很简单,是无状态的;HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,比http协议安全。

2、数据库方面


1、你知道nosql吗?你用的nosql都有哪些?

非关系型的数据库,redis,memcache,MongodDB

2、mysql索引优化

使用 explain 具体分析

3、mysql的优化方案

1.mysql开启查询缓存
(当有很多相同的查询被执行了多次的时候,这些查询结果会被放到一个缓存中)
2.使用 explain 具体分析
3.搜索字段建索引,%s%会失效
4.选择正确的存储引擎

4、mysql的事务
5、mysql的读写分离
6、消息队列如何实现
7、查询优化
8、msyql的存储引擎,以及各自的区别
9、redis和memcache有什么区别
10、索引有哪些,你是如何做索引的?
11、如何分表
12、简述一下数据库的优化 ? 
数据库的优化可以从四个方面来优化: 
1.从结构层: 
web服务器采用负载均衡服务器,
mysql服务器采用主从复制,
读写分离
2.从储存层: 
采用合适的存储引擎,
采用三范式
3.从设计层: 
采用分区分表,
索引,
表的字段采用合适的字段属性,
适当的采用逆范式,
开启mysql缓存
4.sql语句层: 
结果一样的情况下,
采用效率高,
速度快节省资源的sql语句执行

13.PDO
PDO扩展为PHP访问数据库定义了一个轻量级的、一致性的接口,它提供了一个数据访问抽象层,这样,无论使用什么数据库,都可以通过一致的函数执行查询和获取数据

14.redis和memcache
redis 支持复杂的数据结构
redis 相比 memcached 来说,拥有更多的数据结构,能支持更丰富的数据操作

15.面向对象编程
抽象:把现实中需要处理的事物通过数据的方法表达出来就是抽象
封装:把事物的数据和方法用类的方式集合起来就是封装
继承:封装的数据和方法通过继承来实现重用
多态:同一个方法通过方法的重载实现不同的逻辑即多态

16.http协议
http请求由三部分组成,分别是:请求行、消息报头、请求正文

HTTP(超文本传输协议)是一个基于请求与响应模式的、无状态的、应用层的协议,常基于TCP的连接方式

3、服务器方面


1、说下一些你常用的linux命令

top(cpu使用),df(磁盘使用),vim

2、Linux如何搭建LAMP环境

其实就是把Apache, MySQL以及PHP安装在Linux系统上,组成一个环境来运行php的[脚本语言]

3、你们平常工作的系统环境是在哪里?

4、你了解Docker吗?

5、你说下常用的服务端口号

最后祝大家找到一份诚心如意的工作

你可能感兴趣的:(2019-05-20)