1.用PHP实现一个双向队列(使用deque)

deque,全名double-ended queue,是一种具有队列和栈的性质的数据结构。双端队列中的元素可以从两端弹出,其限定插入和删除操作在表的两端进行。

双向队列(双端队列)就像是一 个队列,但是你可以在任何一端添加或移除元素。而双端队列是一种数据结构,定义如下:

双端队列(deque)是由一些项的表组成的数据结构,对该数据结构可以进行下列操作:

  • push(D,X) 将项X 插入到双端队列D的前端
  • pop(D) 从双端队列D中删除前端项并将其返回
  • inject(D,X) 将项X插入到双端队列D的尾端
  • eject(D) 从双端队列D中删除尾端项并将其返回

编写支持双端队伍的例程,每种操作均花费O(1)时间

<?php 

class deque

{

    public $queue  = array();

    public $length = 0;

   

    public function frontAdd($node){

        array_unshift($this->queue,$node);

        $this->countqueue();

    }

    public function frontRemove(){

        $node = array_shift($this->queue);

        $this->countqueue();

        return $node;

    }

      

    public function rearAdd($node){

        array_push($this->queue,$node);

        $this->countqueue();

    }

     

    public function rearRemove(){

        $node = array_pop($this->queue);

        $this->countqueue();

        return $node;

    }

     

    public function countqueue(){

        $this->length = count($this->queue);    

    }

}

$fruit = new deque();

echo $fruit -> length;

$fruit -> frontAdd("Apple");

$fruit -> rearAdd("Watermelon");

echo '<pre>';

print_r($fruit);

echo '</pre>';

?>

 

2.php+redis实现消息队列

消息队列:是在消息的传输过程中保存消息的容器。消息队列管理器在将消息从它的源中继到它的目标时充当中间人。队列的主要目的是提供路由并保证消息的传递;如果发送消息时接收者不可用,消息队列会保留消息,直到可以成功地传递它

应用场景:异步处理,应用解耦,流量削锋和消息通讯四个场景

①异步处理

场景说明:用户注册后,需要发注册邮件和注册短信。

注解:自行考虑ajax中的异步。

②应用解耦

一般订单系统和库存系统是一体的,但是如果一方出现问题,那么这个订单就失败了。

订单系统:用户下单后,订单系统完成持久化处理,将消息写入消息队列,返回用户订单下单成功。

库存系统:订阅下单的消息,采用拉/推的方式,获取下单信息,库存系统根据下单信息,进行库存操作。

假如:在下单时库存系统不能正常使用。也不影响正常下单,因为下单后,订单系统写入消息队列就不再关心其他的后续操作了。实现订单系统与库存系统的应用解耦。

注解:感觉特别像行为驱动,消息队列中存储的就是每个行为

 

③流量消锋(一般在秒杀或团抢活动中使用广泛)

注解:一般秒杀时订单会特别的多,但是数据库无法一次性的处理这么多,所以可以先存在消息队列中,无论我进的速度多快,出的速度都是一定的。不知道算不算属于漏斗模型的一部分

php的redis扩展:https://github.com/phpredis/phpredis

1)redis函数rpush,lpop

2)Linux的crontab

创建demo.php和index.ph

<?php

$redis = new Redis();

$redis->connect('127.0.0.1',6379);

$password = '123456';

$redis->auth($password);

$arr = array('h','e','l','l','o','w','o','r','l','d');

foreach($arr as $k=>$v){

$redis->rpush("mylist",$v);

<?php

$redis = new Redis();

$redis->connect('127.0.0.1',6379);

$password = '123456';

$redis->auth($password);

//list类型出队操作

$value = $redis->lpop('mylist');

if($value){

 echo "出队的值".$value;

}else{

  echo "出队完成";

}

?>

 

3.建立定时任务

1.用php打印前一天的时间,格式是2018-01-01 08:00:00?

答:

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

2.echo、print_r、print、var_dump、的区别?

答:

echo、print是php语句,var_dump和print_r是函数

echo输出一个或多个字符串,中间以逗号隔开,没有返回值是语言结构而不是真正的函数,因此不能作为表达式的一部分使用print也是php的一个关键字,有返回值 只能打印出简单类型变量的值(如int,string),如果字符串显示成功则返回true,否则返回false。print_r 可以打印出复杂类型变量的值(如数组、对象)以列表的形式显示,并以array、object开头,但print_r输出布尔值和NULL的结果没有意义,因为都是打印"\n",因此var_dump()函数更适合调试var_dump() 判断一个变量的类型和长度,并输出变量的数值。

 

4.include和require的区别是什么?

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

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

注意:包含文件不存在或者语法错误的时候require是致命的,而include不是require_once表示了只包含一次,避免了重复包含。

 

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

答:

变量默认总是传值赋值,那也就是说,当将一个表达式的值赋予一个变量时,整个表达式的值被赋值到目标变量,这意味着:当一个变量的赋予另外一个变量时,改变其中一个变量的值,将不会影响到另外一个变量。

php也提供了另外一种方式给变量赋值:引用赋值。这意味着新的变量简单的__引用__(换言之,成为了其别名或者指向)了原始变量。改动的新的变量将影响到原始变量,反之亦然。使用引用赋值,简单地将一个&符号加到将要赋值的变量前(源变量)

对象默认是传引用

对于较大是的数据,传引用比较好,这样可以节省内存的开销

 

5.session和cookie有哪些区别?请从协议,产生原因与作用说明?

答:

http无状态协议,不能区分用户是否是从同一个网站上来的,同一个用户请求不同的页面不能看做是同一个用户。

SESSION存储在服务器端,COOKIE保存在客户端。Session比较安全,cookie用某些手段可以修改,不安全。Session依赖于cookie进行传递。

禁用cookie后,session不能正常使用。Session的缺点:保存在服务器端,每次读取都从服务器进行读取,对服务器有资源消耗。Session保存在服务器端的文件或数据库中,默认保存在文件中,文件路径由php配置文件的session.save_path指定。Session文件是公有的。

 

6.WEB开发中数据提交方式有几种?有什么区别?百度使用哪种方式?

Get与post两种方式

区别:

1. Get从服务器获取数据,post向服务器传送数据

2. Get传值在url中可见,post在url中不可见

3. Get传值一般在2KB以内,post传值大小可以在php.ini中进行设置

4. get安全性非低,post安全性较高,执行效率却比Post高

建议:

get式安全性较Post式要差些包含机密信息建议用Post数据提交式;

做数据查询建议用Get式;做数据添加、修改或删除建议用Post方式;

 

7、安全对一套程序来说至关重要,请说说在开发中应该注意哪些安全机制?

①防远程提交;

②防SQL注入,对特殊代码进行过滤;

③防止注册机灌水,使用验证码;

 

8、在程序的开发中,如何提高程序的运行效率?

①优化SQL语句,查询语句中尽量不使用select *,用哪个字段查哪个字段;少用子查询可用表连接代替;少用模糊查询;

②数据表中创建索引;

③对程序中经常用到的数据生成缓存;

 

9、现在编程中经常采取MVC三层结构,请问MVC分别指哪三层,有什么优点?

MVC三层分别指:业务模型、视图、控制器。

由控制器层调用模型处理数据,然后将数据映射到视图层进行显示,优点是:

①可以实现代码的重用性,避免产生代码冗余;

②M和V的实现代码分离,从而使同一个程序可以使用不同的表现形式

 

10、PHP处理数组的常用函数?(重点看函数的‘参数’和‘返回值’)

①array()创建数组;

②count()返回数组中元素的数目;

③array_push()将一个或多个元素插入数组的末尾(入栈);

④array_column()返回输入数组中某个单一列的值;

⑤array_combine()通过合并两个数组来创建一个新数组;

⑥array_reverse()以相反的顺序返回数组;

⑦array_unique()删除数组中的重复值;

⑧in_array()检查数组中是否存在指定的值;

 

11、PHP处理字符串的常用函数?(重点看函数的‘参数’和‘返回值’)

①trim()移除字符串两侧的空白字符和其他字符;

②substr_replace()把字符串的一部分替换为另一个字符串;

③substr_count()计算子串在字符串中出现的次数;

④substr()返回字符串的一部分;

⑤strtolower()把字符串转换为小写字母;

⑥strtoupper()把字符串转换为大写字母;

⑦strtr()转换字符串中特定的字符;

⑧strrchr()查找字符串在另一个字符串中最后一次出现;

⑨strstr()查找字符串在另一字符串中的第一次出现(对大小写敏感);

strrev()反转字符串;

strlen()返回字符串的长度;

str_replace()替换字符串中的一些字符(对大小写敏感);

print()输出一个或多个字符串;

explode()把字符串打散为数组;

is_string()检测变量是否是字符串;

strip_tags()从一个字符串中去除HTML标签;

mb_substr()用来截中文与英文的函数

 

12、PHP处理时间的常用函数?(重点看函数的‘参数’和‘返回值’)

date_default_timezone_get()返回默认时区。

date_default_timezone_set()设置默认时区。

date()格式化本地时间/日期。

getdate()返回日期/时间信息。

gettimeofday()返回当前时间信息。

microtime()返回当前时间的微秒数。

mktime()返回一个日期的 Unix时间戳。

strtotime()将任何英文文本的日期或时间描述解析为 Unix时间戳。

time()返回当前时间的 Unix时间戳。

 

13、PHP操作目录(文件夹)的常用函数?(重点看函数的‘参数’和‘返回值’)

①打开目录;②删除目录;③读取目录;④创建目录;⑤修改目录;⑥关闭目录等等,此项非常重要,在工作中经常用来创建或者删除上传文件的目录,创建或者删除缓存、静态页面的目录,请参照php手册,认真查看。

 

14、什么是面向对象?(理解着回答)

答:面向对象OO = 面向对象的分析OOA + 面向对象的设计OOD + 面向对象的编程OOP;通俗的解释就是“万物皆对象”,把所有的事物都看作一个个可以独立的对象(单元),它们可以自己完成自己的功能,而不是像C那样分成一个个函数。

 

15、简述 private、 protected、 public修饰符的访问权限。

答:private : 私有成员, 在类的内部才可以访问。

protected : 保护成员,该类内部和继承类中可以访问。

public : 公共成员,完全公开,没有访问限制。

 

16、堆和栈的区别?

答:栈是编译期间就分配好的内存空间,因此你的代码中必须就栈的大小有明确的定义;堆是程序运行期间动态分配的内存空间,你可以根据程序的运行情况确定要分配的堆内存的大小。

 

17、XML 与 HTML 的主要区别

答:(1) XML是区分大小写字母的,HTML不区分。

(2) 在HTML中,如果上下文清楚地显示出段落或者列表键在何处结尾,那么你可以省略

或者之类的结束 标记。在XML中,绝对不能省略掉结束标记。

(3) 在XML中,拥有单个标记而没有匹配的结束标记的元素必须用一个 / 字符作为结尾。这样分析器就知道不用 查找结束标记了。

(4) 在XML中,属性值必须分装在引号中。在HTML中,引号是可用可不用的。

(5) 在HTML中,可以拥有不带值的属性名。在XML中,所有的属性都必须带有相应的值。

 

18、面向对象的特征有哪些方面?

答:主要有封装,继承,多态。如果是4个方面则加上:抽象。

下面的解释为理解:

封装:

封装是保证软件部件具有优良的模块性的基础,封装的目标就是要实现软件部件的高内聚,低耦合,防止程序相互依赖性而带来的变动影响.

继承:

在定义和实现一个类的时候,可以在一个已经存在的类的基础之上来进行,把这个已经存在的类所定义的内容作为自己的内容,并可以加入若干新的内容,或修改原来的方法使之更适合特殊的需要,这就是继承。继承是子类自动共享父类数据和方法的机制,这是类之间的一种关系,提高了软件的可重用性和可扩展性。

多态:

多态是指程序中定义的引用变量所指向的具体类型和通过该引用变量发出的方法调用在编程时并不确定,而是在程序运行期间才确定,即一个引用变量倒底会指向哪个类的实例对象,该引用变量发出的方法调用到底是哪个类中实现的方法,必须在由程序运行期间才能决定。

抽象:

抽象就是找出一些事物的相似和共性之处,然后将这些事物归为一个类,这个类只考虑这些事物的相似和共性之处,并且会忽略与当前主题和目标无关的那些方面,将注意力集中在与当前目标有关的方面。例如,看到一只蚂蚁和大象,你能够想象出它们的相同之处,那就是抽象。

 

19、抽象类和接口的概念以及区别?

答:抽象类:它是一种特殊的,不能被实例化的类,只能作为其他类的父类使用。使用abstract关键字声明。

它是一种特殊的抽象类,也是一个特殊的类,使用interface声明。

(1)抽象类的操作通过继承关键字extends实现,而接口的使用是通过implements关键字来实现。

(2)抽象类中有数据成员,可以实现数据的封装,但是接口没有数据成员。

(3)抽象类中可以有构造方法,但是接口没有构造方法。

(4)抽象类的方法可以通过private、protected、public关键字修饰(抽象方法不能是private),而接口中的方法只能使用public关键字修饰。

(5)一个类只能继承于一个抽象类,而一个类可以同时实现多个接口。

(6)抽象类中可以有成员方法的实现代码,而接口中不可以有成员方法的实现代码。

 

20、什么是构造函数,什么是析构函数,作用是什么?

答:构造函数(方法)是对象创建完成后第一个被对象自动调用的方法。它存在于每个声明的类中,是一个特殊的成员方法。作用是执行一些初始化的任务。Php中使用__construct()声明构造方法,并且只能声明一个。

析构函数(方法)作用和构造方法正好相反,是对象被销毁之前最后一个被对象自动调用的方法。是PHP5中新添加的内容作用是用于实现在销毁一个对象之前执行一些特定的操作,诸如关闭文件和释放内存等。