PHP面试题收集整理

一、oop是面向对象编程。面向对象编程是一种计算机编程架构,OOP 的一条基本原则是计算机程序是由单个可以起到子程序做用的单元或对象组合而成。php

封装性:也称为信息隐藏,就是将一个类的使用和实现分开,只保留部分接口和方法与外部联系,或者说只公开了一些供开发人员使用的方法。因而开发人员只须要关注这个类如何使用,而不用去关心其具体的实现过程,这样就能实现MVC分工合做,也能有效避免程序间相互依赖,实现代码模块间松藕合。css

继承性:就是子类自动继承其父级类中的属性和方法,并能够添加新的属性和方法或者对部分属性和方法进行重写。继承增长了代码的可重用性。PHP只支持单继承,也就是说一个子类只能有一个父类。html

多态性:子类继承了来自父级类中的属性和方法,并对其中部分方法进行重写。因而多个子类中虽然都具备同一个方法,可是这些子类实例化的对象调用这些相同的方法后却能够得到彻底不一样的结果,这种技术就是多态性。多态性加强了软件的灵活性。前端

易维护 、质量高 、效率高 、易扩展 因为继承、封装、多态的特性,天然设计出高内聚、低耦合的系统结构,使得系统更灵活、更容易扩展,并且成本较低。node

二、各框架
ThinkPHP
优势:mysql

1.简化开发、提升效率、易于扩展、易于上手,有丰富的中文文档;nginx

2.框架的兼容性较强,PHP4和PHP5彻底兼容、彻底支持UTF8等。laravel

3.适合用于中小项目的开发web

缺点:面试

1.对Ajax的支持不是很好;

2.目录结构混乱,须要花时间整理;

3.上手容易,可是深刻学习较难。

YII
优势

1.纯OOP

2.用于大规模Web应用

3.模型使用方便

4.开发速度快,运行速度也快。性能优异且功能丰富

5.使用命令行工具。

缺点:

1.对Model层的指导和考虑较少

2.文档实例较少

3.英文太多

4.要求PHP技术精通,OOP编程要熟练!

5.View并非理想view,理想中的view可能只是html代码,不会涉及PHP代码。

CodeIgniter
优势:
推崇简单,配置简单,所有的配置使用PHP脚原本配置,执行效率高,快速简洁,代码很少,执行性能高,框架简单,容易上手,学习成本低,文档详细;自带了不少简单好用的library,框架适合小型应用。
缺点:
内部结构过于混乱,虽然简单易用,但缺少扩展能力。 把Model层简单的理解为数据库操做. 框架略显简单,只可以知足小型应用,略微不太可以知足中型应用须要.

laravel框架的设计思想比较先进,很是适合应用各类开发模式,做为一个框架,它为你准备好了一切。 laravel框架最大的特色和优秀之处就是集合了php比较新的特色,以及各类各样的设计模式,Ioc模式,依赖注入等。

  • 强大的rest router:用简单的回调函数就能够调用,快速绑定controller和router
  • artisan:命令行工具,不少手动的工做都自动化
  • 可继承的模板,简化view的开发和管理
  • blade模板:渲染速度更快
  • ORM操做数据库
  • migration管理数据库和版本控制
  • composer也是亮点
  • 测试功能也很强大
    缺点:
    基于组件式的框架,因此比较臃肿

三、数据库优化

从结构层: web服务器采用负载均衡服务器,mysql服务器采用主从复制,读写分离
从储存层: 采用合适的存储引擎,采用三范式
从设计层: 采用分区分表,索引,表的字段采用合适的字段属性,适当的采用逆范式,开启mysql缓存
从sql语句层:结果同样的状况下,采用效率高、速度快节省资源的sql语句执行
负载均衡:

MySQL之间数据复制的基础是二进制日志文件(binary log file)。
Master 将改变记录到二进制日志中。
Slave 将 Master 的二进制日志拷贝到它的中继日志( Relay_log )
Slave 重作中继日志中的事件,将改变反映它本身的数据

mysql主从复制用途
实时灾备,用于故障切换
读写分离,提供查询服务
备份,避免影响业务

主从部署必要条件:
主库开启binlog日志(设置log-bin参数)
主从server-id不一样
从库服务器能连通主库

原理:
主:log dump线程传binlog;
从:i/o线程接受读取binlog,并写入relay log文件
sql线程从relay log 文件中读取binlog并持久化

主从复制连接:blog.csdn.net/wangyuanjun…

四、如何处理负载、高并发

  • HTML静态化
  • 图片服务器分离
  • 数据库集群和库表散列及缓存: 数据库的并发链接为100,一台数据库远远不够,能够从读写分离、主从复制,数据库集群方面来着手。另外尽可能减小数据库的访问,可使用缓存数据库如memcache、redis。
  • 负载均衡: Apache的最大并发链接为1500,只能增长服务器,能够从硬件上着手,如F5服务器。固然硬件的成本比较高,咱们每每从软件方面着手。

一、流量优化

(1) 防盗链处理(去除恶意请求)

(2) 控制大文件的下载。

(3) 确认服务器硬件是否足够支持当前的流量

(4) 使用流量分析统计软件

(5) 尽可能使用静态页,缓存

二、前端优化

(1) 减小HTTP请求[将css,js等合并]

(2) 添加异步请求(先不将全部数据都展现给用户,用户触发某个事件,才会异步请求数据)

(3) 启用浏览器缓存和文件压缩

(4) CDN加速

(5) 创建独立的图片服务器(减小I/O)

三、服务端优化

(1) 页面静态化

(2) 并发处理

(3) 队列处理

四、数据库优化

(1) 数据库缓存

(2) 分库分表,分区

(3) 读写分离

(4) 负载均衡

五、web服务器优化

(1) nginx反向代理实现负载均衡

(2) lvs实现负载均衡
原文:blog.csdn.net/m_nanle_xia…

悲观锁:
一般所说的“一锁二查三更新”即指的是使用悲观锁。须要数据库自己提供支持,即经过经常使用的select … for update操做来实现悲观锁。不一样的数据库对select for update的实现和支持都是有所区别的,select for update语句执行中全部扫描过的行都会被锁上,这一点很容易形成问题。所以若是在mysql中用悲观锁务必要肯定走了索引,而不是全表扫描。

乐观锁:
在进行完业务操做须要实际更新数据的最后一步再去拿一下锁就好。不须要数据库提供特殊的支持。通常的作法是在须要锁的数据上增长一个版本号或者时间戳:

1. SELECT data AS old_data, version AS old_version FROM …;
2. 根据获取的数据进行业务操做,获得new_data和new_version
3. UPDATE SET data = new_data, version = new_version WHERE version = old_version
if (updated row > 0) {
    // 乐观锁获取成功,操做完成
} else {
    // 乐观锁获取失败,回滚并重试
}
复制代码

高并发:www.cnblogs.com/phpper/p/67…

五、
mysql的默认端口

3306  
复制代码

获取IP地址

客户端 — $_SERVER['REMOTE_ADDR'];  

服务器端 — $_SERVER["SERVER_ADDR"];

gethostname — 获取主机名

ip2long — 将 IPV4 的字符串互联网协议转换成长整型数字

long2ip — 将长整型转化为字符串形式带点的互联网标准格式地址(IPV4)

例子:
$ip = gethostbyname('www.baidu.com'); //14.215.177.39
$ip2long = ip2long($ip); // 249016615

复制代码

编码转换的函数

Iconv('utf-8', 'gb2312', $str);
复制代码

六、架构类的东西
数据库的读写分离、主从复制及集群。

Nginx负载均衡

redis集群及主从

七、session与cookie的区别
cookie数据存放在第三方应用的浏览器上,session数据放在服务器上。

cookie不是很安全,别人能够分析存放在本地的COOKIE,进行COOKIE欺骗,考虑到安全应当使用session。

session会在必定时间内保存在服务器上。session用新的机制保持与客户端的同步,不依赖于客户端设置;会占用服务器资源,加大服务器端的负载,尤为当并发用户不少时,会生成大量的session,影响服务器的性能,考虑到减轻服务器性能方面,应当使用COOKIE。session存储的信息更敏感,并且是以文件形式保存在服务器中,所以仍然存在着安全隐患。

单个cookie保存的数据不能超过4K,不少浏览器都限制一个站点最多保存20个cookie。

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

关闭cookie,使用session的方法

  1. 设置php.ini配置文件中的“session.use_trans_sid = 1”,或者编译时打开打开了“--enable-trans-sid”选项,让PHP自动跨页传递Session ID。
  2. 手动经过URL传值、隐藏表单传递Session ID。
  3. 用文件、数据库等形式保存Session ID,在跨页过程当中手动调用。

总结一下,上面的方法有一个共同点,就是在前一页取得Session ID,而后想办法传递到下一页,在下一页的session_start();代码以前加代码Session ID(传过来的Session ID)。

因此我的建议:
将登录信息等重要信息存放为SESSION
其余信息若是须要保留,能够放在COOKIE

八、抽象类是一种不能被实例化的类,只能做为其余类的父类来使用。抽象类是经过关键字abstract来声明的。
抽象类与普通类类似,都包含成员变量和成员方法,二者的区别在于,抽象类中至少要包含一个抽象方法,抽象方法没有方法体,该方法天生就是要被子类重写的。 抽象方法的格式为:abstract function abstractMethod()

接口是经过 interface 关键字来声明的,接口中的成员常量和方法都是 public 的,方法能够不写关键字public,接口中的方法也是没有方法体。接口中的方法也天生就是要被子类实现的。

抽象类和接口实现的功能十分类似,最大的不一样是接口能实现多继承。在应用中选择抽象类仍是接口要看具体实现。 子类继承抽象类使用 extends,子类实现接口使用implements。

接口中不能够声明变量,但能够声明类常量。抽象类中能够声明各类变量

接口没有构造函数,抽象类能够有

接口中的方法默认为public,抽象类中的方法能够用public、protected、private修饰

一个类能够继承多个接口,但只能继承一个抽象类

含有抽象方法的类不必定是抽象类

抽象类

<?php
abstract class Animal {
  public $name;
  abstract public function eat($food);
}
?>

<?php
class Whale extends Animal {
  public function __construct() {
    $this->name = "Whale";
  }
  public function eat($food) {
    echo $this->name . " eat " . $food . ".\n";
  }
}
?>

<?php
  $whale = new Whale();
  $whale->eat("fish");
?>
复制代码

接口

<?php
interface IAction {
  public function eat($food);
  public function swim();
}
?>

<?php
class Whale implements IAction {
  public function eat($food) {
    echo "Whale eat " . $food . "\n.";
  }
  public swim() {
    echo "Whale is swimming.\n";
  }
}
?>

<?php
  $whale = new Whale();
  $whale->eat("fish");
?>
复制代码
interface Eat
{
    public function eat();
}

class Pig implements Eat
{
    public function eat()
    {
        echo 'pig eat ...';
    }
}

class Cat implements Eat
{
    public function eat()
    {
        echo 'cat eat ....';
    }
}

class Test
{
    function aa(Eat $animal)
    {
        $animal->eat();
    }
}
$test = new Test();
$pig = new Pig();
$cat = new Cat();
$test->aa($pig);
$test->aa($cat);
复制代码

抽象用于不一样的事物,而接口用于事物的行为。 如:水生生物是鲸鱼的抽象概念,可是水生生物并非鲸鱼的行为,吃东西才是鲸鱼的行为。 对于大型项目来讲,对象都是由基本的抽象类继承实现,而这些类的方法一般都由接口来定义。 此外,对于事物属性的更改,建议使用接口,而不是直接赋值或者别的方式,

九、MySQL设计之三范式
第一范式(1NF):字段具备原子性,不可再分。 全部关系型数据库系统都知足第一范式, 数据库表中的字段都是单一属性的, 不可再分。 例如, 姓名字段, 其中的姓和名必须做为一个总体, 没法区分哪部分是姓, 哪部分是名, 若是要区分出姓和名, 必须设计成两个独立的字段。

第二范式(2NF):要求数据库表中的每一个实例或行必须能够被惟一区分。 一般须要为表加上一个列, 以存储各个实例的唯一标识。 这个唯一属性列被称为主关键字或主键。

第三范式(3NF):要求一个数据库表中不包含已在其它表中已包含的非主关键字信息。

总结
一、 每一列只有一个值(字段不可分)
二、 每一行都能区分。(有主键,非主键字段依赖主键)
三、 每个表都不包含其余表已经包含的非主关键字信息。

反三范式
没有冗余的数据库未必是最好的数据库,有时为了提升运行效率,提升读性能,就必须下降范式标准,适当保留冗余数据。 在概念数据模型设计时遵照第三范式,下降范式标准的工做放到物理数据模型设计时考虑。下降范式就是增长字段,减小了查询时的关联,提升查询效率,由于在数据库的操做中查询的比例要远远大于DML的比例。可是反范式化必定要适度,而且在本来已知足三范式的基础上再作调整的。

十、一种是表锁定(myisam存储引擎),一个是行锁定(innodb存储引擎)
一、存储引擎的使用不一样,冷数据使用MyIsam 能够有更好的查询数据。活跃数据,可使用Innodb ,能够有更好的更新速度。
二、对冷数据进行更多的从库配置,由于更多的操做是查询,这样来加快查询速度。对热数据,能够相对有更多的主库的横向分表处理。
三、对于一些特殊的活跃数据,也能够考虑使用memcache 、redis之类的缓存,等累计到必定量再去更新数据库.

十一、数据库引擎

InnoDB:支持事务处理,支持外键,支持崩溃修复能力和并发控制。若是须要对事务的完整性要求比较高(好比银行),要求实现并发控制(好比售票),那选择InnoDB有很大的优点。若是须要频繁的更新、删除操做的数据库,也能够选择InnoDB,由于支持事务的提交(commit)和回滚(rollback)。

MyISAM:插入数据快,空间和内存使用比较低。若是表主要是用于插入新记录和读出记录,那么选择MyISAM能实现处理高效率。若是应用的完整性、并发性要求比较低,也可使用。

MEMORY:全部的数据都在内存中,数据的处理速度快,可是安全性不高。若是须要很快的读写速度,对数据的安全性要求较低,能够选择MEMOEY。它对表的大小有要求,不能创建太大的表。因此,这类数据库只使用在相对较小的数据库表。

merge:用于日志和数据仓库

archive:用于日志,只有select和insert,不支持索引。

注意,同一个数据库也可使用多种存储引擎的表。若是一个表要求比较高的事务处理,能够选择InnoDB。这个数据库中能够将查询要求比较高的表选择MyISAM存储。若是该数据库须要一个用于查询的临时表,能够选择MEMORY存储引擎。

InnoDB表的行锁也不是绝对的,假如在执行一个SQL语句时MySQL不能肯定要扫描的范围,InnoDB表一样会锁全表,例如update table set num=1 where name like “a%”

就是说在不肯定的范围时,InnoDB仍是会锁表的。

如下两点必须使用InnoDB:

1)可靠性高或者要求事务处理,则使用InnoDB。这个是必须的。

2)表更新和查询都至关的频繁,而且表锁定的机会比较大的状况指定InnoDB数据引擎的建立。

对比之下,MyISAM的使用场景:

1)作不少count的计算的。如一些日志,调查的业务表。

2)插入修改不频繁,查询很是频繁的。

十二、数据库事务
事务是指做为单个逻辑工做单元执行的一系列操做,能够被看做一个单元的一系列SQL语句的集合。要么彻底地执行,要么彻底地不执行。 若是不进行并发控制,可能会产生脏读、非重复读、幻像读、丢失修改的异常状况。
事务的特性(ACID):
A、atomacity 原子性(全部过程要么都执行,要么都不执行。若是异常了那么回滚)
C、consistency 一致性(例如转帐前转帐后的总额度不变)
I、isolation 隔离性(只要事务尚未提交,数据都不会有变化)
D、durability 持久性(事务提交,必定发生变化)

1三、事物隔离是基于锁实现的。
在DBMS中,能够把数据库锁分为行级锁(INNODB引擎)表级锁(MYISAM引擎)页级锁(BDB引擎)

行级锁是Mysql中锁定粒度最细的一种锁,表示只针对当前操做的行进行加锁。行级锁能大大减小数据库操做的冲突。其加锁粒度最小,但加锁的开销也最大。行级锁分为共享锁和排他锁。特色是开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的几率最低,并发度也最高。

表级锁是MySQL中锁定粒度最大的一种锁,表示对当前操做的整张表加锁,实现简单,资源消耗较少,被大部分MySQL引擎支持。MYISAM与INNODB都支持表级锁定。表级锁定分为表共享读锁(共享锁)与表独占写锁(排他锁)。特色是开销小,加锁快;不会出现死锁;锁定粒度大,发出锁冲突的几率最高,并发度最低。

页级锁是MySQL中锁定粒度介于行级锁和表级锁中间的一种锁。表级锁速度快,但冲突多,行级冲突少,但速度慢。因此取了折中的页级,一次锁定相邻的一组记录。 特色是开销和加锁时间界于表锁和行锁之间;会出现死锁;锁定粒度界于表锁和行锁之间,并发度通常

1四、分区分表

分区:就是把一个数据表的文件和索引分散存储在不一样的物理文件中。 表分区,是指根据必定规则,将数据库中的一张表分解成多个更小的、容易管理的部分。从逻辑上看,只有一张表,可是底层倒是由多个物理分区组成。

分表:指的是经过必定规则,将一张表分解成多张不一样的表,每个小表都是完正的一张表,都对应三个文件(MyISAM引擎:一个.MYD数据文件,.MYI索引文件,.frm表结构文件)。好比将用户订单记录根据时间成多个表。

分表与分区的区别:
实现方式上:分区从逻辑上来说只有一张表,而分表则是将一张表分解成多张表。

数据处理上:分表后数据都是存放在分表里,总表只是一个外壳,存取数据发生在一个一个的分表里面。分区则不存在分表的概念,分区只不过把存放数据的文件分红了许多小块,分区后的表仍是一张表,数据处理仍是由本身来完成。

提升性能上:分表后,单表的并发能力提升了,磁盘I/O性能也提升了。分区突破了磁盘I/O瓶颈,想提升磁盘的读写能力,来增长mysql性能。
在这一点上,分区和分表的测重点不一样,分表重点是存取数据时,如何提升mysql并发能力上;而分区呢,如何突破磁盘的读写能力,从而达到提升mysql性能的目的。

实现的难易度上:分表的方法有不少,用merge来分表,是最简单的一种方式。这种方式和分区难易度差很少,而且对程序代码来讲能够作到透明的。若是是用其余分表方式就比分区麻烦了。 分区实现是比较简单的,创建分区表,跟建日常的表没什么区别,而且对代码端来讲是透明的。 分区和分表的目的就是减小数据库的执行负担,稳定SQL性能。

分区
mysql支持的分区类型包括Range、List、Hash、Key

CREATE TABLE user (
	id INT NOT NULL auto_increment,
	username VARCHAR (10),
	PRIMARY KEY (id)
) ENGINE = INNODB charset = utf8 PARTITION BY RANGE (id)(
	PARTITION user_1 VALUES less than (10),
	PARTITION user_2 VALUES less than (20),
	PARTITION user_3 VALUES less than MAXVALUE
);
复制代码

表分区好处:
1)分区表的数据能够分布在不一样的物理设备上,从而高效地利用多个硬件设备。
2)和单个磁盘或者文件系统相比,能够存储更多数据
3)优化查询。在where语句中包含分区条件时,能够只扫描一个或多个分区表来提升查询效率;涉及sum和count语句时,也能够在多个分区上并行处理,最后汇总结果。
4)分区表更容易维护。例如:想批量删除大量数据能够清除整个分区。
5)可使用分区表来避免某些特殊的瓶颈,例如InnoDB的单个索引的互斥访问,ext3问价你系统的inode锁竞争等。

分区的限制:

  • 主键或者惟一索引必须包含分区字段,如primary key (id,username),不过innoDB的大组建性能很差。
  • 不少时候,使用分区就不要在使用主键了,不然可能影响性能。
  • 只能经过int类型的字段或者返回int类型的表达式来分区,一般使用year或者to_days等函数(mysql 5.6 对限制开始放开了)。
  • 每一个表最多1024个分区,并且多分区会大量消耗内存。
  • 分区的表不支持外键,相关的逻辑约束须要使用程序来实现。
  • 分区后,可能会形成索引失效,须要验证分区可行性。

分表

// 建立一个完整表存储着全部的成员信息
CREATE TABLE `member` (
`id`  int(10) UNSIGNED NOT NULL AUTO_INCREMENT ,
`name`  varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' ,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET = utf8 AUTO_INCREMENT = 1;

// 插入数据(第2条语句多执行几回就有了不少数据):
insert into member(name) values('a');
insert into member(name) select name from member;

// 建立两个分表tb_member1,tb_member2
DROP TABLE IF EXISTS tb_member1;
CREATE TABLE tb_member1 (
`id` INT (10) UNSIGNED NOT NULL AUTO_INCREMENT,
`name` VARCHAR (20) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '',
  PRIMARY KEY (`id`)
) ENGINE = MyISAM DEFAULT CHARSET = utf8 AUTO_INCREMENT = 1;

DROP TABLE IF EXISTS tb_member2;
CREATE TABLE tb_member2 LIKE tb_member1;

// 建立主表tb_member
DROP TABLE IF EXISTS tb_member;
CREATE TABLE tb_member (
`id` INT (10) UNSIGNED NOT NULL AUTO_INCREMENT,
`name` VARCHAR (20) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '',
  PRIMARY KEY (`id`)
) ENGINE = MERGE UNION = (tb_member1, tb_member2) INSERT_METHOD = LAST CHARSET = utf8 AUTO_INCREMENT = 1;

// 把数据分到两个分表中去
insert into tb_member1(id, name) select id,name from member where id%2=0;
insert into tb_member2(id, name) select id,name from member where id%2=1;
复制代码

分表存在的问题:

  • 跨库跨表的join问题
  • 额外的数据管理负担和数据运算压力(数据的定位问题和数据的增删改查的重复执行问题)

分表的几种常见方法:

  • 预先估计某个大表的数据量,将其均分为固定数量表(自增id取模、自增id两位尾数取模、对某个字段进行hash)
  • 时间增加较快的数据能够按时间拆分(按天、按月、按年等)
  • 按每一个表固定记录行数拆分
  • 将好久以前的数据迁移到一张历史表

分表连接:www.cnblogs.com/johnnyzhang…

1五、MySQL索引:
联合索引(复合索引)由两个或多个列的索引,可只使用索引中的一部分,更准确地说是最左侧部分(最左优先)
前缀索引对于列的值较长,好比BLOB、TEXT、VARCHAR,可创建前缀索引,即将值的前一部分做为索引
覆盖索引查询时只用去读取索引而取得数据,无需进行二次查询相关表,对于一个索引覆盖查询,经过使用explain,extra显示为using index来判断

假设创建有顺序的:c1,c2,c3,c4 这4个索引

  • 在等值查询时,更改索引列顺序,不会影响explain的执行结果,由于mysql底层会进行优化,可是推荐按照索引顺序列编写sql语句。
  • 在使用order by时,注意索引顺序、常量,以及可能会致使Using filesort的状况
  • 范围右边索引列失效,可是范围当前位置的索引是有效的
  • 范围右边索引列失效,是有顺序的:c1,c2,c3,c4,若是c3有范围,则c4失效;若是c4有范围,则没有失效的索引列,从而会使用所有索引。
  • 在最佳左前缀法则中,若是最左前列的索引失效,则后面的索引都失效。
  • 利用最佳左前缀法则:中间不能断,用到了c1和c2索引(查找),c3索引列用在排序过程当中。
  • group by容易产生Using temporary

通俗理解口诀:

全值匹配我最爱,最左前缀要遵照;

带头大哥不能死,中间兄弟不能断;

索引列上少计算范围以后全失效;

LIKE百分写最右,覆盖索引不写星;

不等空值还有or,索引失效要少用。

参见:www.cnblogs.com/morewindows…

索引长度计算:
1.全部的索引字段,若是没有设置not null,则须要加一个字节。
2.定长字段,int占四个字节、date占三个字节、char(n)占n个字符。
3.对于变成字段varchar(n),则有n个字符+两个字节。
4.不一样的字符集,一个字符占用的字节数不一样。latin1编码的,一个字符占用一个字节,gbk编码的,一个字符占用两个字节,utf8编码的,一个字符占用三个字节。

1六、

// 链接
$dbhost = 'localhost';  // mysql服务器主机地址
$dbuser = 'root';            // mysql用户名
$dbpass = '';          // mysql用户名密码
$conn = mysqli_connect($dbhost, $dbuser, $dbpass);
if (!$conn) {
    die('Could not connect: ' . mysqli_error());
}
echo '数据库链接成功!';


// 设置编码,防止中文乱码
mysqli_query($conn , "set names utf8");
 
$sql = 'SELECT id, name FROM user';
 
mysqli_select_db($conn, 'test');
$retval = mysqli_query($conn, $sql);
if(!$retval)
{
    die('没法读取数据: ' . mysqli_error($conn));
}

while($row = mysqli_fetch_array($retval, MYSQLI_ASSOC)) {
    print_r($row);
}

// 释放内存
mysqli_free_result($retval);
mysqli_close($conn);
复制代码

1七、冒泡排序
如数组:$sort = [6,1,2,4,5,3]; 进行冒泡排序(从小到大)

第一轮:
 第一次:1,6,2,4,5,3
 第二次:1,2,6,4,5,3
 第三次:1,2,4,6,5,3
 第四次:1,2,4,5,6,3
 第五次:1,2,4,5,3,6

第二轮:
 第一次:1,2,4,5,3,6
 第二次:1,2,4,5,3,6
 第三次:1,2,4,5,3,6
 第四次:1,2,4,3,5,6

第三轮:
 第一次:1,2,4,3,5,6
 第二次:1,2,4,3,5,6
 第三次:1,2,3,4,5,6

第四轮:
 第一次:1,2,3,4,5,6
 第二次:1,2,3,4,5,6

第五轮:
 第一次:1,2,3,4,5,6

<?php
$arr = [6, 7, 3, 5, 9, 10, 1];
$length = count($arr);
// 轮
for ($i = 1; $i < $length; $i++) {
    // 次
    for ($j = 0; $j < $length - $i; $j++) {
    	if ($arr[$j] > $arr[$j + 1]) {
            $tmp = $arr[$j];
            $arr[$j] = $arr[$j + 1];
            $arr[$j + 1] = $tmp;
    	}
    }
}
echo '<pre>';
print_r($arr);
复制代码

1八、遍历出文件夹和他下面子文件的代码

function getAllFile($dir) {
    $allFileArr = [];
    if (is_dir($dir)) {
        $res = opendir($dir);
        while ($row = readdir($res)) {
            if ($row == '.' || $row == '..') {
                continue;
            }
            if (is_file($dir . '/' . $row)) {
                $allFileArr[] = $row;
            } else if (is_dir($dir . '/' . $row)) {
                $allFileArr[$row] = getAllFile($dir . '/' . $row);
            }
        }
        closedir($res);
    }
    return $allFileArr;
}

$dir = 'E:\ruanjian\wamp64\www\learn';
echo '<pre>';
print_r(getAllFile($dir));
复制代码

1九、如何防止SQL注入,XSS攻击和CSRF攻击

SQL注入:mysqli_real_escape_string()转义关键字符;

CSRF攻击:跨站攻击。防止:token、验证码

XSS攻击:alert把一些cookie信息打印出来;
过滤掉<>等关键字符串;
对数据解码,再过滤掉危险标签、属性和事件等;
DOM XSS的发生主要是在JS中使用eval形成的,因此应当避免使用eval语句
复制代码

XSS危害

  • 经过document.cookie盗取cookie
  • 使用js或css破坏页面正常的结构与样式
  • 流量劫持(经过访问某段具备window.location.href定位到其余页面)
  • Dos攻击:利用合理的客户端请求来占用过多的服务器资源,从而使合法用户没法获得服务器响应。
  • 利用iframe、frame、XMLHttpRequest或上述Flash等方式,以(被攻击)用户的身份执行一些管理动做,或执行一些通常的如发微博、加好友、发私信等操做。
  • 利用可被攻击的域受到其余域信任的特色,以受信任来源的身份请求一些平时不容许的操做,如进行不当的投票活动。

20、PHP程序工做的具体过程

  PHP的运行原理就是Apache、PHP、浏览器之间的协做过程:

  ①当用户在浏览器地址中输入要访问的PHP页面文件名,而后回车就会触发这个PHP请求,并将请求传送化支持PHP的WEB服务器(apache)。

  ②WEB服务器(apache)接受这个请求,并根据其后缀进行判断若是是一个PHP请求,WEB服务器(apache)从硬盘或内存中取出用户要访问的PHP应用程序,并将其发送给PHP引擎程序。

  ③PHP引擎程序将会对WEB服务器(apache)传送过来的文件从头至尾进行扫描并根据命令从后台读取,处理数据,并动态地生成相应的HTML页面。

  ④PHP引擎将生成HTML页面返回给WEB服务器(apache)。WEB服务器(apache)再将HTML页面返回给客户端浏览器,最后一个完整的页面基于经过浏览器展示在咱们眼前。

2一、HTTP协议
HTTP请求由三个部分组成,分别是:请求行、请求头部、空行和请求正文。
HTTP响应由四个部分组成,分别是:状态行、消息报头、空行和响应正文。
第一部分:状态行,由HTTP协议版本号、状态码、状态消息三部分组成。
第一行为状态行,(HTTP/1.1)代表HTTP版本为1.1版本,状态码为200,状态消息为(ok)

第二部分:消息报头,用来讲明客户端要使用的一些附加信息
第二行和第三行为消息报头, Date:生成响应的日期和时间;Content-Type:指定了MIME类型的HTML(text/html),编码类型是UTF-8
第三部分:空行,消息报头后面的空行是必须的
第四部分:响应正文,服务器返回给客户端的文本信息。
空行后面的html部分为响应正文。

请求类型GET、POST、HEAD 1.1版还新增了许多动词方法:PUT、PATCH、HEAD、 OPTIONS、DELETE

HTTP请求报文头属性:
Accept:告诉服务端 客户端接受什么类型的响应。
Cookie:客户端的Cookie就是经过这个报文头属性传给服务端的
Referer:表示这个请求是从哪一个URL过来的,假如你经过google搜索出一个商家的广告页面,你对这个广告页面感兴趣,鼠标一点发送一个请求报文到商家的网站,这个请求报文的Referer报文头属性值就是http://www.google.com。
Cache-Control:对缓存进行控制

HTTP响应报文头属性:
Cache-Control:响应输出到客户端后,服务端经过该报文头属告诉客户端如何控制响应内容的缓存
ETag:一个表明响应服务端资源(如页面)版本的报文头属性,若是某个服务端资源发生变化了,这个ETag就会相应发生变化。它是Cache-Control的有益补充,可让客户端“更智能”地处理何时要从服务端取资源,何时能够直接从缓存中返回响应。
Location:让页面Redirect到一个某个A页面中,实际上是让客户端再发一个请求到A页面,这个须要Redirect到的A页面的URL,其实就是经过响应报文头的Location属性告知客户端的
Set-Cookie:服务端能够设置客户端的Cookie

常见状态码
1xx 消息,通常是告诉客户端,请求已经收到了,正在处理,别急...
2xx 处理成功,通常表示:请求收悉、我明白你要的、请求已受理、已经处理完成等信息.
3xx 重定向到其它地方。它让客户端再发起一个请求以完成整个处理。
4xx 处理发生错误,责任在客户端,如客户端的请求一个不存在的资源,客户端未被受权,禁止访问等。
5xx 处理发生错误,责任在服务端,如服务端抛出异常,路由出错,HTTP版本不支持等。

具体以下:
2XX系列:表明请求已成功被服务器接收、理解、并接受。
200状态码:请求已成功,请求所但愿的响应头或数据体将随此响应返回
201状态码:表示请求成功而且服务器建立了新的资源,且其 URI 已经随Location 头信息返回。假如须要的资源没法及时创建的话,应当返回 '202 Accepted'

4XX系列:表示请求错误。表明了客户端看起来可能发生了错误,妨碍了服务器的处理。
401状态码:请求要求身份验证。对于须要登陆的网页,服务器可能返回此响应。
403状态码:服务器已经理解请求,可是拒绝执行它。与401响应不一样的是,身份验证并不能提供任何帮助,并且这个请求也不该该被重复提交。
404状态码:请求失败,请求所但愿获得的资源未被在服务器上发现。

5xx系列:表明了服务器在处理请求的过程当中有错误或者异常状态发生,也有多是服务器意识到以当前的软硬件资源没法完成对请求的处理。
500状态码:服务器遇到了一个不曾预料的情况,致使了它没法完成对请求的处理。通常来讲,这个问题都会在服务器的程序码出错时出现。
503状态码:因为临时的服务器维护或者过载,服务器当前没法处理请求。

blog.csdn.net/u010256388/… 2二、设计模式
参考连接:www.cnblogs.com/leedaily/p/…

2三、向php脚本传递参数:

  • php -r "var_dump($argv);" -- -h(若是要传递的参数开头为-,那么得使用参数列表分隔符 -- 才能正确传参)
  • test.php 假设该文件在当前目录下,代码:
#!/usr/bin/php 
<?php var_dump($argv);?>    

// 在php文件开头加入#!/usr/bin/php,便可直接传递以-为开头得参数
./test.php -h -- foo  
复制代码

2四、redis和memcached区别

  • redis 系统库有个快照,即忽然断电,数据还会存在,而memached 就没了
  • memcached 是简单的键值对,Key-Value, redis 支持的存储方式(字符串,双向链表,哈希,集合,有序集合)不少,应用场景不少
  • redis 性能比memached 要高
  • Memcached是多线程,非阻塞IO复用的网络模型;Redis使用单线程的多路 IO 复用模型。

2五、SQL注入
SQL注入攻击是黑客对数据库进行攻击的经常使用手段之一。在编写代码的时候,没有对用户输入数据的合法性进行判断,注入者能够在表单中输入一段数据库查询代码并提交,程序将提交的信息拼凑生成一个完整sql语句,服务器被欺骗而执行该条恶意的SQL命令。注入者根据程序返回的结果,成功获取一些敏感数据,甚至控制整个服务器,这就是SQL注入。

2六、HTTP与HTTPS的区别?
HTTP协议传输的数据都是未加密的,也就是明文的,所以使用HTTP协议传输隐私信息很是不安全,为了保证这些隐私数据能加密传输,因而网景公司设计了SSL(Secure Sockets Layer)协议用于对HTTP协议传输的数据进行加密,从而就诞生了HTTPS。简单来讲,HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,要比http协议安全。 HTTPS和HTTP的区别主要以下:

  • https协议须要到ca申请证书,通常免费证书较少,于是须要必定费用。
  • http是超文本传输协议,信息是明文传输,https则是具备安全性的ssl加密传输协议。
  • http和https使用的是彻底不一样的链接方式,用的端口也不同,前者是80,后者是443。
  • http的链接很简单,是无状态的;HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,比http协议安全。

2七、从输入URL到页面加载发生了什么
segmentfault.com/a/119000000…

2八、消息队列
从本质上说消息队列就是一个队列结构的中间件,也就是说消息放入这个中间件以后就能够直接返回,并不须要系统当即处理,而另外会有一个程序读取这些数据,并按顺序进行逐次处理。
也就是说当你遇到一个并发特别大而且耗时特别长同时还不须要当即返回处理结果,使用消息队列能够解决这类问题。

业务系统入队->消息队列出队->队列处理系统
由一个业务系统进行入队,把消息逐次插入到消息队列中,插入成功以后直接返回成功的结果,后续会有一个消息处理系统,这个系统会把消息系统中的记录逐次进行取出并进行处理,完成一个出队的流程。

www.cnblogs.com/dump/p/8243…

2九、定时脚本
blog.csdn.net/xf_come_on/…

30、网络7层协议
7 应用层
6 表示层
5 会话层
4 传输层
3 网络层
2 数据链路层
1 物理层
七、六、五、4层定义了应用程序的功能
三、二、1层主要面向经过网络的端到端的数据流

TCP UDP
是否链接 面向链接 面向非链接
传入可靠性 可靠 不可靠
引用场景 传输大量数据 传输小量数据
速度
举例 银行 windows的ping命令 qq发消息

HTTP协议即超文本传送协议(Hypertext Transfer Protocol ),是Web联网的基础,也是手机联网经常使用的协议之一,HTTP协议是创建在TCP协议之上的一种应用。因为HTTP在每次请求结束后都会主动释放链接,所以HTTP链接是一种“短链接”。
Socket其实并非一个协议,而是为了方便使用TCP或UDP而抽象出来的一层,是位于应用层和传输控制层之间的一组接口。建立Socket链接时,能够指定使用的传输层协议,Socket能够支持不一样的传输层协议(TCP或UDP),当使用TCP协议进行链接时,该Socket链接就是一个TCP链接。

WebSocket同HTTP同样也是应用层的协议,可是它是一种双向通讯协议,是创建在TCP之上的。在WebSocket中,只须要服务器和浏览器经过HTTP协议进行一个握手的动做,而后单独创建一条TCP的通讯通道进行数据的传送。

http和scoket区别:
HTTP是基于应用层,socket是基于传输层(tcp/udp)

HTTP链接使用的是"请求—响应"的方式,不只在请求时须要先创建链接,并且须要客户端向服务器发出请求后,服务器端才能回复数据。在请求结束后,会主动释放链接。
一般状况下Socket链接就是TCP链接,所以Socket链接一旦创建,通讯双方便可开始相互发送数据内容,直到双方链接断开。

视频,图片,断点续传的状况下要用socket,http的协议的无状态性实现不了这个功能。

http不断请求发送的缺点:会致使过多没必要要的请求,浪费流量和服务器资源,每一次请求、应答,都浪费了必定流量在相同的头部信息上

WebSocket与HTTP的相同点:
一、都是同样基于TCP的,都是可靠性传输协议。
二、都是应用层协议
不一样点:
一、WebSocket是双向通讯协议,模拟Socket协议,能够双向发送或接受信息。HTTP是单向的。
二、WebSocket是须要握手进行创建链接的。

3一、 mysql时间
date_sub('2012-05-25',interval 1 day) 表示 2012-05-24
date_sub('2012-05-25',interval 0 day) 表示 2012-05-25
date_sub('2012-05-25',interval -1 day) 表示 2012-05-26
date_sub(curdate(),interval 1 day) 表示 2013-05-19
date_sub(curdate(),interval -1 day) 表示 2013-05-21
date_sub(curdate(),interval 1 month) 表示 2013-04-20
date_sub(curdate(),interval -1 month) 表示 2013-06-20
date_sub(curdate(),interval 1 year) 表示 2012-05-20
date_sub(curdate(),interval -1 year) 表示 2014-05-20

// 获取昨天 跟 今天 00:00:00的 时间戳
select unix_timestamp(DATE_SUB(CURDATE(),INTERVAL 1 day)), unix_timestamp(date_sub(curdate(), interval 0 day));

// 日期转时间戳
SELECT UNIX_TIMESTAMP('2018-10-31');

// 时间戳转日期
select FROM_UNIXTIME(1540915200, '%Y-%m-%d');

3二、

//奇偶数
$a = [6, 7, 8, 9];
$arr = array_filter($a, function ($v) {
    return ($v & 1);
});
返回:
[
  1 => 7
  3 => 9
]

第一种:
$file = 'E:\php1\wamp64\www\test.txt';
$content = file($file);
foreach ($content as $key => $value) {
    $value = mb_convert_encoding($value, 'utf-8', 'gbk');
    $v = explode("\t", $value);
}

第二种:
$handle = fopen($file, 'r');
if ($handle) {
    while (($row = fgets($handle)) !== false) {
        $row = mb_convert_encoding($row, 'utf-8', 'gbk');
        $v = explode("\t", $row);
    }
    fclose($handle);
}

// 当前月份的第一天跟最后一天
$monthFirstDay = date('Y-m-01', strtotime(date("Y-m-d")));
$monthLastDay = date('Y-m-d', strtotime($monthFirstDay . ' +1 month -1 day'));

// 指定日期的上个月的最后一天
$lastDay = date('Y-m-t', strtotime('last month', strtotime('20181116'))); //2018-10-31

$arr = range('a', 'z');
$str = implode($arr);// abcdefghijklmnopqrstuvwxyz

$a = "aa";
$b = "bb";
// 交换两个变量的值
var_dump([$a, $b]); // ['aa', 'bb']
list($a, $b) = [$b, $a];
var_dump([$a, $b]); ['bb', 'aa']

// 反转字符串
function mb_strrev($str)
{
    $r = '';
    for ($i = mb_strlen($str); $i >= 0; $i--) {
        $r .= mb_substr($str, $i, 1);
    }
    return $r;
}
echo mb_strrev("☆❤world我"); 
// 我dlrow❤☆
复制代码
echo mb_internal_encoding(); // UTF-8
$str = "AB. cb 测试的"; 
echo strlen($str);//一个UTF8的中文字符=3个字节,因此为3+1+2+1+9=16
echo mb_strlen($str, "utf-8");//UTF-8会将中文字符当成一个字符,因此为3+1+2+1+3=10
echo mb_strlen($str, "gbk");//gbk,一个中文字符当成1.5个字符,3+1+2+1+4.5=11.5
复制代码
empty() 能够用来断定全部的数据类型是否为空或假,而 is_null 与 isset 基本同样,只能用来判断是否为NULL和未定义。
复制代码
echo count(strlen('https://www.baidu.com/'));
// 结果:1,count(var)是用来统计数组或对象的元素个数的。当var是null或者空数组时,结果为0。若是var是普通变量,则返回1。正常状况下返回var中的元素或属性个数。
复制代码

PHP不鼓励加结束标签
能够避免在 PHP 结束标记以后万一意外加入了空格或者换行符,会致使 PHP 开始输出这些空白
影响最多的时候应该是在使用 include 和 require 的时候,加告终束标签若是又在后面加了空格都有可能会引发多余的输出、php错误、以后的输出没法显示、空白页,由于session_start()之类的函数的缘由(HTTP报文是header在前,body在后。当你在session_start()以前有了body输出,就不能再设定header set-cookie了,而session就是依赖cookie)

CGI 表明为了联系PHP 和 Web Server 的一个桥梁
fastCGI 是CGI的改良版
PHP-FPM 进程管理器

CGI:是 Web Server 与 Web Application 之间数据交换的一种协议。
FastCGI:同 CGI,是一种通讯协议,但比 CGI 在效率上作了一些优化。一样,SCGI 协议与 FastCGI 相似。
PHP-CGI:是 PHP 对 Web Server 提供的 CGI 协议的接口程序。
PHP-FPM:是 PHP 对 Web Server 提供的 FastCGI 协议的接口程序,额外还提供了相对智能一些任务管理。

WEB 中,
Web Server 通常指Apache、Nginx、IIS、Lighttpd、Tomcat等服务器, Web Application 通常指PHP、Java、Asp.net等应用程序。

3四、jsonp

$.ajax({
    type: 'get',
    async: false,
    url: "http://test.com/learn/jsonp.php",
    dataType: 'jsonp',
    jsonp: 'callback', // 传递给请求处理程序或页面的,用以得到jsonp回调函数名的参数名(通常默认为:callback)
    jsonpCallBack: 'callbackFun', // 自定义的jsonp回调函数名称,默认为jQuery自动生成的随机函数名,也能够写"?",jQuery会自动为你处理数据
    success: function (res) {
        console.log(res)
    },
    error: function () {
        console.log('fail')
    }
})


jsonp.php页面

header('Content-type: application/json');
$callback = htmlspecialchars($_REQUEST['callback']);
$jsonData = json_encode(['id' => 1, 'name' => '小猫咪']);
echo $callback . '(' . $jsonData . ')';
exit;
复制代码

依赖注入
ORM
mysql主从复制 读写分离
分布式
单元测试

其余面试题网址:
www.cnblogs.com/gaowei521/p…

相关文章
相关标签/搜索