PHP 经典

php 专栏收录该内容
52 篇文章 0 订阅

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

get 请求一般用于向服务端获取数据,post 一般向服务端提交数据

get 传输的参数在 url 中,传递参数大小有限制

get 不安全,post 安全性比get高

get是显式的,数据从url中可以看到,传输的数据量小,安全性低;

post是隐式的,传送的数据量较大,安全性较高

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

echo是PHP语句, print和print_r是函数,语句没有返回值,函数可以有返回值

print() 只能打印出简单类型变量的值(如int,string)

print_r() 可以打印出复杂类型变量的值(如数组,对象)

echo 输出一个或者多个字符串

3、数组内置的排序方法

sort($array); //数组升序排序

rsort($array); //数组降序排序

asort($array); //根据值,以升序对关联数组进行排序

ksort($array); //根据建,以升序对关联数组进行排序

arsort($array); //根据值,以降序对关联数组进行排序

krsort($array); // 根据键,以降序对关联数组进行排序

4、sql语句应该考虑哪些安全性

(1)防止sql注入,对特殊字符进行转义,过滤或者使用预编译sql语句绑定

(2)使用最小权限原则,特别是不要使用root账户,微不同的动作或者操作建立不同的账户

(3)当sql出错时,不要把数据库出错的信息暴露到客户端

5、优化mysql 数据库方法

(1)选取适当的字段,打字段设置为NOT NULL,在查询的时候数据库不用比较NULL;

(2)使用链接(join)代替子查询;

(3)使用联合(UNION)查询代替手动创建临时表;

(4)尽量减少使用(LIKE)关键字和通配符

(5)使用事务和外健

6、对于大流量的网站,你会采用什么方法来解决访问量?

(1)首先确认服务器硬件是否满足支持当前的流量;

(2)优化数据库的访问;

(3)禁止外部盗链;

(4)控制大文件下载;

(5)使用不同的主机分流;

(6)使用流量分析统计;

(7)尽量使用静态页,缓存

7、MySQL的几个概念:主键,外键,索引,唯一索引

主键(primary key) 能够唯一标识表中某一行的属性或属性组。一个表只能有一个主键,但可以有多个候选索引。主键常常与外键构成参照完整性约束,防止出现数据不一致。主键可以保证记录的唯一和主键域非空,数据库管理系统对于主键自动生成唯一索引,所以主键也是一个特殊的索引。

外键(foreign key) 是用于建立和加强两个表数据之间的链接的一列或多列。外键约束主要用来维护两个表之间数据的一致性。简言之,表的外键就是另一表的主键,外键将两表联系起来。一般情况下,要删除一张表中的主键必须首先要确保其它表中的没有相同外键(即该表中的主键没有一个外键和它相关联)。

索引(index) 是用来快速地寻找那些具有特定值的记录。主要是为了检索的方便,是为了加快访问速度, 按一定的规则创建的,一般起到排序作用。所谓唯一性索引,这种索引和前面的“普通索引”基本相同,但有一个区别:索引列的所有值都只能出现一次,即必须唯一。

总结:

主键一定是唯一性索引,唯一性索引并不一定就是主键。

一个表中可以有多个唯一性索引,但只能有一个主键。

主键列不允许空值,而唯一性索引列允许空值。

主键可以被其他字段作外键引用,而索引不能作为外键引用。

8、 mysql 引擎中的MyISAM与InnoDB的区别

以下是一些细节和具体实现的差别:

MyISAM与InnoDB的区别是什么?

8.1、存储结构

MyISAM:每个MyISAM在磁盘上存储成三个文件。第一个文件的名字以表的名字开始,扩展名指出文件类型。.frm文件存储表定义。数据文件的扩展名为.MYD (MYData)。索引文件的扩展名是.MYI (MYIndex)。

InnoDB:所有的表都保存在同一个数据文件中(也可能是多个文件,或者是独立的表空间文件),InnoDB表的大小只受限于操作系统文件的大小,一般为2GB。

8.2、 存储空间

MyISAM:可被压缩,存储空间较小。支持三种不同的存储格式:静态表(默认,但是注意数据末尾不能有空格,会被去掉)、动态表、压缩表。

InnoDB:需要更多的内存和存储,它会在主内存中建立其专用的缓冲池用于高速缓冲数据和索引。

8.3、 可移植性、备份及恢复

MyISAM:数据是以文件的形式存储,所以在跨平台的数据转移中会很方便。在备份和恢复时可单独针对某个表进行操作。

InnoDB:免费的方案可以是拷贝数据文件、备份 binlog,或者用 mysqldump,在数据量达到几十G的时候就相对痛苦了。

8.4、 事务支持

MyISAM:强调的是性能,每次查询具有原子性,其执行数度比InnoDB类型更快,但是不提供事务支持。

InnoDB:提供事务支持事务,外部键等高级数据库功能。 具有事务(commit)、回滚(rollback)和崩溃修复能力(crash recovery capabilities)的事务安全(transaction-safe (ACID compliant))型表。

8.5、 AUTO_INCREMENT

MyISAM:可以和其他字段一起建立联合索引。引擎的自动增长列必须是索引,如果是组合索引,自动增长可以不是第一列,他可以根据前面几列进行排序后递增。

InnoDB:InnoDB中必须包含只有该字段的索引。引擎的自动增长列必须是索引,如果是组合索引也必须是组合索引的第一列。

8.6、 表锁差异

MyISAM:只支持表级锁,用户在操作myisam表时,select,update,delete,insert语句都会给表自动加锁,如果加锁以后的表满足insert并发的情况下,可以在表的尾部插入新的数据。

InnoDB:支持事务和行级锁,是innodb的最大特色。行锁大幅度提高了多用户并发操作的新能。但是InnoDB的行锁,只是在WHERE的主键是有效的,非主键的WHERE都会锁全表的。

8.7、 全文索引

MyISAM:支持 FULLTEXT类型的全文索引

InnoDB:不支持FULLTEXT类型的全文索引,但是innodb可以使用sphinx插件支持全文索引,并且效果更好。

8.8、 表主键

MyISAM:允许没有任何索引和主键的表存在,索引都是保存行的地址。

InnoDB:如果没有设定主键或者非空唯一索引,就会自动生成一个6字节的主键(用户不可见),数据是主索引的一部分,附加索引保存的是主索引的值。

8.9、 表的具体行数

MyISAM:保存有表的总行数,如果select count(*) from table;会直接取出出该值。

InnoDB:没有保存表的总行数,如果使用select count(*) from table;就会遍历整个表,消耗相当大,但是在加了wehre条件后,myisam和innodb处理的方式都一样。

8.10、 CURD操作

MyISAM:如果执行大量的SELECT,MyISAM是更好的选择。

InnoDB:如果你的数据执行大量的INSERT或UPDATE,出于性能方面的考虑,应该使用InnoDB表。DELETE 从性能上InnoDB更优,但DELETE FROM table时,InnoDB不会重新建立表,而是一行一行的删除,在innodb上如果要清空保存有大量数据的表,最好使用truncate table这个命令。

8.11、 外键

MyISAM:不支持

InnoDB:支持

通过上述的分析,基本上可以考虑使用InnoDB来替代MyISAM引擎了,原因是InnoDB自身很多良好的特点,比如事务支持、存储 过程、视图、行级锁定等等,在并发很多的情况下,相信InnoDB的表现肯定要比MyISAM强很多。另外,任何一种表都不是万能的,只用恰当的针对业务类型来选择合适的表类型,才能最大的发挥MySQL的性能优势。如果不是很复杂的Web应用,非关键应用,还是可以继续考虑MyISAM的,这个具体情况可以自己斟酌。

9、redis 和 memache 缓存的区别

总结一:

1.数据类型

Redis数据类型丰富,支持set list等类型

memcache支持简单数据类型,需要客户端自己处理复杂对象

2.持久性

redis支持数据落地持久化存储

memcache不支持数据持久存储

3.分布式存储

redis支持master-slave复制模式

memcache可以使用一致性hash做分布式

value大小不同

memcache是一个内存缓存,key的长度小于250字符,单个item存储要小于1M,不适合虚拟机使用

4.数据一致性不同

redis使用的是单线程模型,保证了数据按顺序提交。

memcache需要使用cas保证数据一致性。CAS(Check and Set)是一个确保并发一致性的机制,属于“乐观锁”范畴;原理很简单:拿版本号,操作,对比版本号,如果一致就操作,不一致就放弃任何操作

5.cpu利用

redis单线程模型只能使用一个cpu,可以开启多个redis进程

总结二:

1.Redis中,并不是所有的数据都一直存储在内存中的,这是和Memcached相比一个最大的区别。

2.Redis不仅仅支持简单的k/v类型的数据,同时还提供list,set,hash等数据结构的存储。

3.Redis支持数据的备份,即master-slave模式的数据备份。

4.Redis支持数据的持久化,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用。

我个人认为最本质的不同是Redis在很多方面具备数据库的特征,或者说就是一个数据库系统,而Memcached只是简单的K/V缓存

总结三:

redis和memecache的不同在于:

1、存储方式:

memecache 把数据全部存在内存之中,断电后会挂掉,数据不能超过内存大小

redis有部份存在硬盘上,这样能保证数据的持久性。

2、数据支持类型:

redis在数据支持上要比memecache多的多。

3、使用底层模型不同:

新版本的redis直接自己构建了VM 机制 ,因为一般的系统调用系统函数的话,会浪费一定的时间去移动和请求。

4、运行环境不同:

redis目前官方只支持Linux 上去行,从而省去了对于其它系统的支持,这样的话可以更好的把精力用于本系统 环境上的优化,虽然后来微软有一个小组为其写了补丁。但是没有放到主干上

memcache只能当做缓存,cache

redis的内容是可以落地的,就是说跟MongoDB有些类似,然后redis也可以作为缓存,并且可以设置master-slave

11、heredoc结构及用法

echo <<<EOT

   <html>

   <head><title>主页</title></head>

   <body>主页内容</body>

   </html>

EOT;

注意:结束标识符所在的行不能包含任何其它字符除";"

12、nowdoc结构及用法

$str = <<<'EOD'

       Example of string

       spanning multiple lines

       using nowdoc syntax.

EOD;

13、数据库中的事务是什么?

事务就是一系列的操作,这些操作完成一项任务。只要这些操作里有一个操作没有成功,事务就操作失败,发生回滚事件。即撤消前面的操作,这样可以保证数据的一致性。而且可以把操作暂时放在缓存里,等所有操作都成功有提交数据库,这样保证费时的操作都是有效操作

14、apche 和 nginx 的优缺

nginx轻量级,比apache占用更少的内存及资源,抗并发,nginx处理请求是异步非阻塞的,而apache 则是阻塞型的,在高并发下nginx 能保持低资源低消耗高性能。apache 相对于nginx 的优点:rewrite比nginx 的rewrite 强大,少bug,稳定。(需要性能用nginx,求稳定就apache)。

15、php 的垃圾回收机制

PHP 可以自动进行内存管理,清除不需要的对象。

PHP 使用了引用计数 (reference counting) GC 机制。

16、session 与 cookie 的区别和联系

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

16.1、存放位置:Session 保存在服务器,Cookie 保存在客户端。

16.2、存放的形式:Session 是以对象的形式保存在服务器,Cookie 以字符串的形式保存在客户端。

16.3、 用途:Cookies 适合做保存用户的个人设置,爱好等,Session 适合做客户的身份验证

16.4、路径:Session 不能区分路径,同一个用户在访问一个网站期间,所有的 Session 在任何一个地方都可以访问到。而 Cookie 中如果设置了路径参数,那么同一个网站中不同路径下的 Cookie 互相是访问不到的。

16.5、安全性:Cookie 不是很安全,别人可以分析存放在本地的 COOKIE 并进行 COOKIE 欺骗,考虑到安全应当使用 session

16.6、大小以及数量限制:每个域名所包含的 cookie 数:IE7/8,FireFox:50 个,Opera30 个; Cookie 总大小:Firefox 和 Safari 允许 cookie 多达 4097 个字节,Opera 允许 cookie 多达 4096 个字 节,InternetExplorer 允许 cookie 多达 4095 个字节;一般认为 Session 没有大小和数量限制。

关系:

Session 需要借助 Cookie 才能正常工作。如果客户端完全禁止 Cookie,Session 将失效!因为 Session 是由应用服务器维持的一个 服务器端的存储空间,用户在连接服务器时,会由服务器生成一个唯一的 SessionID, 用该 SessionID 为标识符来存取服务器端的 Session 存储空间。而 SessionID 这一数据则是保存到客户端,用 Cookie 保存的,用户提交页面时,会将这一 SessionID 提交到服务器端,来存取 Session 数据。这一过程,是不用开发人员干预的。所以一旦客户端禁用 Cookie,那么 Session 也会失效。

17、 PHP 页面重定向的方法

方法一:使用header

header('Location: http://www.baidu.com/') ;

方法二:利用meta

echo"<meta http-equiv=refresh content='0;url=网址'>";

18、长连接、短连接的区别和使用

长连接:client 方与 server 方先建立连接,连接建立后不断开,然后再进行报文发送和接收。这种方式下由于通讯连接一直存在。此种方式常用于 P2P 通信。

短连接:Client 方与 server 每进行一次报文收发交易时才进行通讯连接,交易完毕后立即断开连接。此方式常用于一点对多点通讯。C/S 通信。

长连接与短连接的使用时机:

长连接:

短连接多用于操作频繁,点对点的通讯,而且连接数不能太多的情况。每个 TCP 连 接的建立都需要三次握手,每个 TCP 连接的断开要四次握手。如果每次操作都要建立连接然后再操作的话处理速度会降低,所以每次操作下次操作时直接发送数据 就可以了,不用再建立 TCP 连接。例如:数据库的连接用长连接,如果用短连接频繁的通信会造成 socket 错误,频繁的 socket 创建也是对资源的浪 费。

短连接:

web 网站的 http 服务一般都用短连接。因为长连接对于服务器来说要耗费一定 的资源。像 web 网站这么频繁的成千上万甚至上亿客户端的连接用短连接更省一些资源。试想如果都用长连接,而且同时用成千上万的用户,每个用户都占有一个 连接的话,可想而知服务器的压力有多大。所以并发量大,但是每个用户又不需频繁操作的情况下需要短连接。

19、HTTP 协议详解、应用

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

参考 https://blog.csdn.net/gueter/article/details/1524447

20、预定义变量(超级全局变量)

$GLOBALS

$_SERVER

$_GET

$_POST

$_COOKIE

$_SESSION

$_REQUEST

$_ENV

21、魔术变量

LINE

FILE

DIR

CLASS

FUNCTION

METHOD

NAMESPACE

22、常见的 web 攻击方式

常见攻击

XSS (Cross Site Script) ,跨站脚本攻击。它指的是恶意攻击者往 Web 页面里插入恶意 html 代码,当用户浏览该页之时,嵌入的恶意 html 代码会被执行,从而达到恶意用户的特殊 目的。XSS 属于被动式的攻击,因为其被动且不好利用,所以许多人常呼略其危害性。但是随着前端技术的不断进步富客户端的应用越来越多,这方面的问题越来 越受关注。举个简单例子 : 假如你现在是 sns 站点上一个用户,发布信息的功能存在漏洞可以执行 js 你在 此刻输入一个 恶意脚本,那么当前所有看到你新信息的人的浏览器都会执行这个脚本弹出提示框 (很爽吧 弹出广告 :)),如果你做一些更为激进行为呢 后果难以想象。

CSRF (Cross Site Request Forgery),跨站点伪造请求。顾名思义就是 通过伪造连接请求在用户不知情的情况下,让用户以自己的身份来完成攻击者需要达到的一些目的。csrf 的攻击不同于 xss csrf 需要被攻击者的主动行为触发。这样听来似乎是有 “被钓鱼” 的嫌疑。

多窗口浏览器这这方面似乎是有助纣为虐的嫌疑,因为打开的新窗口是具有当前所有 会话的,如果是单浏览器窗口类似 ie6 就不会存在这样的问题,因为每个窗口都是一个独立的进程。举个简单例子 : 你正在玩白社会, 看到有人发了一个连接,你点击过去,然后这个连接里面伪造了一个送礼物的表单,这仅仅是一个简单的例子,问题可见一般。

cookie 劫持。通过获取页面的权限,在页面中写一个简单的到恶意站点的请 求,并携带用户的 cookie 获取 cookie 后通过 cookie 就可以直以被盗用户的身份登录站点。这就是 cookie 劫持。举个简单例子: 某人写了一篇很有意思的日志,然后分享给大家,很多人都点击查看并且分享了该日志,一切似乎都很正常,然而写日志的人却另有用心,在日志中偷偷隐藏了一个 对站外的请求,那么所有看过这片日志的人都会在不知情的情况下把自己的 cookie 发送给了 某人,那么他可以通过任意一个人的 cookie 来登录这个人的账户。

SQL 注入攻击

在 SQL 注入攻击 中,用户通过操纵表单或 GET 查询字符串,将信息添加到数据库查询中。

DNS 攻击

拒绝服务攻击

拒绝服务攻击即攻击者想办法让目标机器停止提供服务,是黑客常用的攻击手段之。

攻击者进行拒绝服务攻击,实际上让服务器实现两种效果:一是迫使服务器的缓冲区满,不接收新的请求;二是使用 IP 欺骗,迫使服务器把合法用户的连接复位,影响合法用户的连接

23、数据库设计经验,为什么进行分表?分库?一般多少数据量开始分表?分库?分库分表的目的?什么是数据库垂直拆分?水平拆分?分区等等

一:为什么要分表

当一张表的数据达到几百万时,你查询一次所花的时间会变多,如果有联合查询的话,有可能会死在那儿了。分表的目的就在于此,减小数据库的负担,缩短查询时间。日常开发中我们经常会遇到大表的情况,所谓的大表是指存储了百万级乃至千万级条记录的表。这样的表过于庞大,导致数据库在查询和插入的时候耗时太长,性能低下,如果涉及联合查询的情况,性能会更加糟糕。分表和表分区的目的就是减少数据库的负担,提高数据库的效率,通常点来讲就是提高表的增删改查效率。数据库中的数据量不一定是可控的,在未进行分库分表的情况下,随着时间和业务的发展,库中的表会越来越多,表中的数据量也会越来越大,相应地,数据操作,增删改查的开销也会越来越大;另外,由于无法进行分布式式部署,而一台服务器的资源(CPU、磁盘、内存、IO 等)是有限的,最终数据库所能承载的数据量、数据处理能力都将遭遇瓶颈。

二:分表的方案

23.1、做 mysql 集群,有人会问 mysql 集群,根分表有什么关系吗?虽然它不是实际意义上的分表,但是它启到了分表的作用,做集群的意义是什么呢?为一个数据库减轻负担,说白了就是减少 sql 排队队列中的 sql 的数量,举个例子:有 10 个 sql 请求,如果放在一个数据库服务器的排队队列中,他要等很长时间,如果把这 10 个 sql 请求,分配到 5 个数据库服务器的排队队列中,一个数据库服务器的队列中只有 2 个,这样等待时间是不是大大的缩短了呢?

linux mysql proxy 的安装,配置,以及读写分离

mysql replication 互为主从的安装及配置,以及数据同步

优点:扩展性好,没有多个分表后的复杂操作(php 代码)

缺点:单个表的数据量还是没有变,一次操作所花的时间还是那么多,硬件开销大。

23.2、垂直分割就是按字段分。水平分割。就是按记录分

24、数据库优化

24.1、检查优化索引的使用

24.2、避免出现 SELECT * FROM table 语句,要明确查出的字段。

24.3、应绝对避免在 order by 子句中使用表达式。

24.4、小心使用 IN 和 OR,需要注意 In 集合中的数据量。建议集合中的数据不超过 200 个。

24.5、<> 用 < 、> 代替,> 用 >= 代替,< 用 <= 代替,这样可以有效的利用索引

24.6、在查询时尽量减少对多余数据的读取包括多余的列与多余的行

24.7、多表关联查询时,写法必须遵循以下原则,这样做有利于建立索引,提高查询效率。格式如下

select sum(table1.je) from table1 table1, table2 table2, table3 table3 where (table1的等值条件(=)) and(table1的非等值条件) and (table2与table1的关联条件) and (table2的等值条件) and (table2的非等值条件) and(table3与table2的关联条件) and (table3的等值条件) and (table3的非等值条件)。

24.8、如果在语句中有 not in(in)操作,应考虑用 not exists(exists)来重写,最好的办法是使用外连接实现。

24.9、选取最适用的字段属性 ,MySQL 可以很好的支持大数据量的存取,但是一般说来,数据库中的表越小,在它上面执行的查询也就会越快。因此,在创建表的时候,为了获得更好的性能,我们可以将表中字段的宽度设得尽可能小。

25、如何设计一个高并发的系统

① 数据库的优化,包括合理的事务隔离级别、SQL 语句优化、索引的优化

② 使用缓存,尽量减少数据库 IO

③ 分布式数据库、分布式缓存

④ 服务器的负载均衡

26、mySQL 里有 2000w 数据,redis 中只存 20w 的数据,如何保证 redis 中的数据都是热点数据

相关知识:redis 内存数据集大小上升到一定大小的时候,就会施行数据淘汰策略(回收策略)。redis 提供 6 种数据淘汰策略:

volatile-lru:从已设置过期时间的数据集(server.db [i].expires)中挑选最近最少使用的数据淘汰

volatile-ttl:从已设置过期时间的数据集(server.db [i].expires)中挑选将要过期的数据淘汰

volatile-random:从已设置过期时间的数据集(server.db [i].expires)中任意选择数据淘汰

allkeys-lru:从数据集(server.db [i].dict)中挑选最近最少使用的数据淘汰

allkeys-random:从数据集(server.db [i].dict)中任意选择数据淘汰

no-enviction(驱逐):禁止驱逐数据

27、写出一个能创建多级目录的PHP函数(新浪网技术部)

<?php

    /**

     * 创建多级目录

     * @param $path string 要创建的目录

     * @param $mode int 创建目录的模式,在windows下可忽略

     */

    function create_dir($path,$mode = 0777)

    {

        if (is_dir($path)) {

            # 如果目录已经存在,则不创建

            echo "该目录已经存在";

        } else {

            # 不存在,创建

            if (mkdir($path,$mode,true)) {

                echo "创建目录成功";

            } else {

                echo "创建目录失败";

            }

        }

    }

?>

28、抓取远程图片到本地

file_get_contents或者curl

29、请写一段PHP代码,确保多个进程同时写入同一个文件成功

<?php

    $fp = fopen("lock.txt","w+");

    if (flock($fp,LOCK_EX)) {

        //获得写锁,写数据

        fwrite($fp, "write something");

  

        // 解除锁定

        flock($fp, LOCK_UN);

    } else {

        echo "file is locking...";

    }

    fclose($fp);

?>

30、写一个函数,尽可能高效的,从一个标准url里取出文件的扩展名

// 方案一

    function getExt1($url){

        $arr = parse_url($url);

        //Array ( [scheme] => http [host] => www.sina.com.cn [path] => /abc/de/fg.php [query] => id=1 )

  

        $file = basename($arr['path']);

        $ext = explode('.', $file);

        return $ext[count($ext)-1];

    }

31、编写一个函数,递归遍历,实现无限分类

<?php

    function tree($arr,$pid=0,$level=0){

        static $list = array();

        foreach ($arr as $v) {

            //如果是顶级分类,则将其存到$list中,并以此节点为根节点,遍历其子节点

            if ($v['parent_id'] == $pid) {

                $v['level'] = $level;

                $list[] = $v;

                tree($arr,$v['cat_id'],$level+1);

            }

        }

        return $list;

    }

?>

32、有一个网页地址,比如PHP开发资源网主页:http://www.phpres.com/index.html,如何得到它的内容?

方法1(对于PHP5及更高版本):

$readcontents=fopen("http://www.phpres.com/index.html","rb");

$contents=stream_get_contents($readcontents);

fclose($readcontents);

echo $contents;

方法2:

echo file_get_contents("http://www.phpres.com/index.html");

33、请写一个函数验证电子邮件的格式是否正确(使用正则)

preg_match('/^[\w\-\.]+@[\w\-]+(\.\w+)+$/',$email);

34、请写出并说明如何在命令行下运行PHP脚本(写出两种方式)同时向PHP脚本传递参数?

首先进入php安装目录
php -f d:/wamp/www/1.php 其中-f参数指定要执行的php文件
php -r phpinfo(); 其中-r表示直接执行php代码,无需写开始结束标记

35、PHP中,如何获得一个数组的键值

使用key()可以获得数组中当前元素的键名,使用current()则可以返回当前元素的值。
使用array_keys()则可以得到数组中所有的键名。
使用foreach结构foreach($arr as value)可以通过value分别获取键名和值。

36、在url中用get传值的时候,若中文出现乱码,应该用哪个函数对中文进行编码?

urlencode()

37、写出五种以上你使用过的PHP的扩展的名称(提示:常用的PHP扩展)

mb_sring、iconv、curl、GD、XML、socket、MySQL、PDO等

38、什么是面向对象?主要特征是什么?

注:面向对象

面向对象是程序的一种设计方式,它利于提高程序的重用性,使程序结构更加清晰。主要特征:封装、继承、多态。优点:灵活性、重用性、拓展性。

39、HTTP 状态中302、403、 500代码含义?

一二三四五原则: 一. 消息系列 二 成功系列 三. 重定向系列 四. 请求错误系列 五. 服务器端错误系列

302:临时转移成功,请求的内容已转移到新位置 403:禁止访问 500:服务器内部错误 401代表未授权。

40、Linux 下建立压缩包,解压缩包的命令

Tar.gz:

打包: tar czf file.tar.gz file.txt

解压: tar xzf file.tar.gz

Bz2:

打包: bzip2 [-k] 文件

解压: bunzip2 [-k] 文件

Gzip(只对文件,不保留原文件)

打包: gzip file1.txt

解压: gunzip file1.txt.gz

Zip: -r 对目录

打包: zip file1.zip file1.txt

解压: unzip file1.zip

41、isset() 和 empty() 区别

Isset判断变量是否存在,可以传入多个变量,若其中一个变量不存在则返回假,empty判断变量是否为空为假,只可传一个变量,如果为空为假则返回真。

42、对于缓存技术的了解

缓存技术是将动态内容缓存到文件中,在一定时间内访问动态页面直接调用缓存文件,而不必重新访问数据库。

43、设置COOKIE的值:

Setcookie(名称,值,保存时间,有效域);

44、面向对象中接口和抽象类的区别及应用场景?

44.1、有抽象方法的类叫做抽象类,抽象类中不一定只有抽象方法,抽象方法必须使用abstract关键字定义。

44.2、接口中全部是抽象方法,方法不用使用abstract定义。

44.3、当多个同类的类要设计一个上层,通常设计为抽象类,当多个异构的类要设计一个上层,通常设计为接口。

45、什么是模板技术、能够使HTML和PHP分离开使用的模板?

模板技术就是使程序的逻辑代码和界面分开的技术。

能够使HTML和PHP分开的模板有:Smarty、Template、PHPlib Template、FastTemplate

46、魔术方法并说明作用

__call()当调用不存在的方法时会自动调用的方法

__autoload()在实例化一个尚未被定义的类是会自动调用次方法来加载类文件

__set()当给未定义的变量赋值时会自动调用的方法

__get()当获取未定义变量的值时会自动调用的方法

__construct()构造方法,实例化类时自动调用的方法

__destroy()销毁对象时自动调用的方法

__unset()当对一个未定义变量调用unset()时自动调用的方法

__isset()当对一个未定义变量调用isset()方法时自动调用的方法

__clone()克隆一个对象

__tostring()当输出一个对象时自动调用的方法

__callStatic()

__sleep()

__wakeup()

__toString()

__set_state()

47、预定义变量

$_REQUEST用来获取post或get方式提交的值

$_POST用来获取post方式提交的值

$_GET用来获取get方式提交的值

$_COOKIE用来获取cookie存储的值

$_SESSION用来获取session存储的值

$_FILES用来获取上传文件表单的值

48、框架中什么是单一入口和多入口,单一入口的优缺点

1、多入口就是通过访问不同的文件来完成用户请求。

单一入口指web程序所有的请求都指向一个脚本文件的。

2、单一入口更容易控制权限,方便对http请求可以进行安全性检查。

缺点:URL看起来不那么美观,特别是对搜索引擎来说不友好。

49、索引的目的

1、快速访问数据表中的特定信息,提高检索速度

2、创建唯一性索引,保证数据库表中每一行数据的唯一性

3、加速表和表之间的连接

4、使用分组和排序子句进行数据检索时,可以显著减少查询中分组和排序的时间

使用索引负面影响:创建索引和维护索引需要耗费时间,这个时间随着数据量的增加而增加;索引需要占用物理空间,不光是表需要占用数据空间,每个索引也需要占用物理空间;当对表进行增、删、改的时候索引也要动态维护,这样就降低了数据的维护速度。

50、防御攻击

50.1、XSS是跨站脚本攻击,首先是利用跨站脚本漏洞以一个特权模式去执行攻击者构造的脚本,然后利用不安全的Activex控件执行恶意的行为。

使用htmlspecialchars()函数对提交的内容进行过滤,使字符串里面的特殊符号实体化。

50.2、SQL注入产生的原因:程序开发过程中不注意规范书写sql语句和对特殊字符进行过滤,导致客户端可以通过全局变量POST和GET提交一些sql语句正常执行。

防止SQL注入:

	1、开启配置文件中的magic_quotes_gpc和magic_quotes_runtime设置

	2、执行sql语句时使用addslashes进行sql语句转换

	3、Sql语句书写尽量不要省略小引号和单引号

	4、过滤掉sql语句中的一些关键字:update、insert、delete、select、*

	5、提高数据库表和字段的命名技巧,对一些重要的字段根据程序的特点命名,取不易被猜到的。

	6、Php配置文件中设置register_globals为off,关闭全局变量注册

	7、控制错误信息,不要再浏览器上输出错误信息,将错误信息写到日志文件中。

51、冒泡排序,面试前一定要记住哦!

function maopao($arr)

{

    $len = count($arr);

    $n = count($arr) - 1;

    for ($i = 0; $i < $len; $i++) {

        for ($j = 0; $j < $n; $j++) {

            if ($arr[$j] > $arr[$j + 1]) {

                $tmp = $arr[$j];

                $arr[$j] = $arr[$j + 1];

                $arr[$j + 1] = $tmp;

            }

        }

    }

    return $arr;

}

52、快速排序,面试前一定要记住哦!

function quick_sort($array) {

    if (count($array) <= 1) return $array;

    $key = $array[0];

    $left_arr = array();

    $right_arr = array();

    for ($i=1; $i
        if ($array[$i] <= $key)

            $left_arr[] = $array[$i];

        else

            $right_arr[] = $array[$i];

    }

    $left_arr = quick_sort($left_arr);

    $right_arr = quick_sort($right_arr);

    return array_merge($left_arr, array($key), $right_arr);

}

53、MySQL数据库的常用存储引擎以及它们的区别?

MyISAM:不支持事务,表锁,易产生碎片,要经常优化,读写速度较快,支持全文索引。

InnoDB:支持事务,行锁,有崩溃恢复能力。读写速度比MyISAM慢,5.6之后支持全文索引。
存储引擎是基于表的,而不是数据库

54、PHP的基本变量类型

四种标量类型:boolean (布尔型)、integer (整型)、float (浮点型, 也称作 double)、string (字符串)

两种复合类型:array (数组)、object (对象)

最后是两种特殊类型:resource(资源)、NULL(NULL)

55、静态化如何实现的?伪静态如何实现?

1、 静态化指的是页面静态化,也即生成实实在在的静态文件,也即不需要查询数据库就可以直接从文件中获取数据,指的是真静态。
实现方式主要有两种:

一种是我们在添加信息入库的时候就生成的静态文件,也称为模板替换技术。

一种是用户在访问我们的页面时先判断是否有对应的缓存文件存在,如果存在就读缓存,不存在就读数据库,同时生成缓存文件。

2、伪静态不是真正意义上的静态化,之所以使用伪静态,主要是为了SEO推广,搜索引擎对动态的文件获取难度大,不利于网站的推广。实习原理是基于Apache或Nginx的rewrite机智
主要有两种方式:

一种是直接在配置虚拟机的位置配置伪静态,这个每次修改完成后需要重启web服务器。

另一种采用分布式的,可以在网站的根目录上创建.htaccess的文件,在里面配置相应的重写规则来实现伪静态,这种每次重写时不需要重启web服务器,且结构上比较清晰。

56、如何处理负载,高并发?

1、HTML静态化
效率最高、消耗最小的就是纯静态化的html页面,所以我们尽可能使我们的 网站上的页面采用静态页面来实现,这个最简单的方法其实也是最有效的方法。

2、图片服务器分离
把图片单独存储,尽量减少图片等大流量的开销,可以放在一些相关的平台上,如七牛等

3、数据库集群和库表散列及缓存
数据库的并发连接为100,一台数据库远远不够,可以从读写分离、主从复制,数据库集群方面来着手。另外尽量减少数据库的访问,可以使用缓存数据库如memcache、redis。

4、镜像:
尽量减少下载,可以把不同的请求分发到多个镜像端。

5、负载均衡:
Apache的最大并发连接为1500,只能增加服务器,可以从硬件上着手,如F5服务器。当然硬件的成本比较高,我们往往从软件方面着手。

57、MySQL主从备份的原理?

mysql支持单向、异步复制,复制过程中一个服务器充当主服务器,而一个或多个其它服务器充当从服务器

58、常见的 PHP 安全性攻击

1.SQL注入:用户利用在表单字段输入SQL语句的方式来影响正常的SQL执行。
防止:

使用mysql_real_escape_string()过滤数据

手动检查每一数据是否为正确的数据类型

使用预处理语句并绑定变量

参数化SQL:是指在设计与数据库链接并访问数据时,在需要填入数值或数据的地方,使用参数 (Parameter) 来给值,用@或?来表示参数。

2.XSS攻击 :跨站点脚本攻击,由用户输入一些数据到你的网站,其中包括客户端脚本(通常JavaScript)。如果你没有过滤就输出数据到另一个web页面,这个脚本将被执行。
防止:为了防止XSS攻击,使用PHP的htmlentities()函数过滤再输出到浏览器。

3.CSRF:跨站点请求伪造,是指一个页面发出的请求,看起来就像是网站的信任用户,但是是伪造的
防止:一般来说,确保用户来自你的表单,并且匹配每一个你发送出去的表单。有两点一定要记住:

对用户会话采用适当的安全措施,例如:给每一个会话更新id和用户使用SSL。

生成另一个一次性的令牌并将其嵌入表单,保存在会话中(一个会话变量),在提交时检查它。 如laravel中的 _token

代码注入:代码注入是利用计算机漏洞通过处理无效数据造成的。问题出在,当你不小心执行任意代码,通常通过文件包含。写得很糟糕的代码可以允许一个远程文件包含并执行。如许多PHP函数,如require可以包含URL或文件名。
防止代码注入

过滤用户输入

在php.ini中设置禁用allow_url_fopen和allow_url_include。这将禁用require/include/fopen的远程文件

59、TP框架的优点与特性

优点:TP框架是我们中国人自己开发的框架,各种资料比较齐全,国内用的比较多,比较简单和方便,而且是免费开源的

特性:
1.多表查询非常方便,在model中几句代码就可以完成对多表的关联操作

2.融合了smarty模板,使前后台分离

3.支持多种缓存技术,尤其对memcache技术支持非常好

4.命名规范,模型,视图,控制器严格遵循命名规则,通过命名一一对应

5.支持多种url模式

6.内置ajax返回方法,包括xml,json,html等

7.支持应用扩展,类库扩展,驱动扩展等

60、如何解决异常处理

答: 抛出异常:使用try…catch,异常的代码放在try代码块内,如果没有触发异常,则代码继续执行,如果异常被触发,就会 抛出一个异常。Catch代码块捕获异常,并创建一个包含异常信息的对象。$e->getMessage(),输出异常的错误信息。

解决异常:使用set_error_handler函数获取异常(也可以使用try()和catch()函数),然后使用set_exception_handler()函数设置默认的异常处理程序,register_shutdown_function()函数来执行,执行机制是,php要把调入的函数调入到内存,当页面所有的php语句都执行完成时,再调用此函数

61、怎么保证促销商品不会超卖?

答:这个问题是我们当时开发时遇到的一个难点,超卖的原因主要是下的订单的数目和我们要促销的商品的数目不一致导致的,每次总是订单的数比我们的促销商品的数目要多,当时我们的小组讨论了好久,给出了好几个方案来实现:

第一种方案:在每次下订单前我们判断促销商品的数量够不够,不够不允许下订单,更改库存量时加上一个条件,只更改商品库存大于0的商品的库存,当时我们使用ab进行压力测试,当并发超过500,访问量超过2000时,还是会出现超卖现象。所以被我们否定了。

第二种方案:使用mysql的事务加排他锁来解决,首先我们选择数据库的存储引擎为innoDB,使用的是排他锁实现的,刚开始的时候我们测试了下共享锁,发现还是会出现超卖的现象。有个问题是,当我们进行高并发测试时,对数据库的性能影响很大,导致数据库的压力很大,最终也被我们否定了。

第三种方案:使用文件锁实现。当用户抢到一件促销商品后先触发文件锁,防止其他用户进入,该用户抢到促销品后再解开文件锁,放其他用户进行操作。这样可以解决超卖的问题,但是会导致文件得I/O开销很大。

最后我们使用了redis的队列来实现。将要促销的商品数量以队列的方式存入redis中,每当用户抢到一件促销商品则从队列中删除一个数据,确保商品不会超卖。这个操作起来很方便,而且效率极高,最终我们采取这种方式来实现

62、商城秒杀的实现?

抢购、秒杀是如今很常见的一个应用场景,主要需要解决的问题有两个:

1、高并发对数据库产生的压力

2、竞争状态下如何解决库存的正确减少("超卖"问题)

对于第一个问题,已经很容易想到用缓存来处理抢购,避免直接操作数据库,例如使用Redis。第二个问题,我们可以使用redis队列来完成,把要秒杀的商品放入到队列中,因为pop操作是原子的,即使有很多用户同时到达,也是依次执行,文件锁和事务在高并发下性能下降很快,当然还要考虑其他方面的东西,比如抢购页面做成静态的,通过ajax调用接口,其中也可能会出现一个用户抢多次的情况,这时候需要再加上一个排队队列和抢购结果队列及库存队列。高并发情况下,将用户进入排队队列,用一个线程循环处理从排队队列取出一个用户,判断用户是否已在抢购结果队列,如果在,则已抢购,否则未抢购,库存减1,写数据库,将用户入结果队列。

63、redis消息队列先进先出需要注意什么?

通常使用一个list来实现队列操作,这样有一个小限制,所以的任务统一都是先进先出,如果想优先处理某个任务就不太好处理了,这就需要让队列有优先级的概念,我们就可以优先处理高级别的任务,实现方式有以下几种方式:

1)单一列表实现:队列正常的操作是 左进右出(lpush,rpop)为了先处理高优先级任务,在遇到高级别任务时,可以直接插队,直接放入队列头部(rpush),这样,从队列头部(右侧)获取任务时,取到的就是高优先级的任务(rpop)

2)使用两个队列,一个普通队列,一个高级队列,针对任务的级别放入不同的队列,获取任务时也很简单,redis的BRPOP命令可以按顺序从多个队列中取值,BRPOP会按照给出的 key 顺序查看,并在找到的第一个非空 list 的尾部弹出一个元素,redis> BRPOP list1 list2 0

list1 做为高优先级任务队列

list2 做为普通任务队列

这样就实现了先处理高优先级任务,当没有高优先级任务时,就去获取普通任务

方式1最简单,但实际应用比较局限,方式3可以实现复杂优先级,但实现比较复杂,不利于维护

方式2是推荐用法,实际应用最为合适

64、你负责的模块有哪些难题

第一:谈具体遇到的问题

第二(看法):我觉得在开发过程中,遇到的难题无非是两个,一个是技术层次的,我认为,只要你有恒心,有热心,没有觉得不了的难题。另一个就是沟通问题,在任何地方任何时候沟通都是最重要的,尤其是我们做开发的,不沟通好,会影响整个项目的进度,我本人也非常乐于沟通,所以这点上也没多大问题

65、电商的登录是怎么实现的?

分为普通登录和第三方登录 这边主要说一下第三方登录吧,第三方登陆主要使用的是author协议,我就以QQ的第三方登陆为例来进行说明:当用户在我们的站点请求QQ的第三方登陆时,我们站点会引导用户跳转到QQ的登陆授权界面, 当用户输入QQ和密码成功登录以后会自动跳回到我们站点设置好的回调页面,并附带一个code参数,接着你使用code再次去请求QQ的授权页面,就可以从中获取到一个access token(访问令牌),通过这个access_token,我们可以调用QQ提供给我们的接口,比如获取open_id,可以获取用户的基本信息。获取到之后,我们需要拿用户的授权信息和open_id和我们平台的普通用户进行绑定。这样不管是普通用户登陆还是第三方登陆用户,都可以实现登陆。

66、订单、库存两个表 如何保证数据的一致性?

答:在一个电子商务系统中,正常的应该是订单生成成功后,相应的库存进行减少必须要保证两者的一致性,但有时候因为某些原因,比如程序逻辑问题,并发等问题,导致下单成功而库存没有减少的情况。这种情况我们是不允许发生的,MySQL的中的事务刚好可以解决这一问题,首先得选择数据库的存储引擎为InnoDB的,事务规定了只有下订单完成了,并且相应的库存减少了才允许提交事务,否则就事务回滚,确保数据一致性。

67、做秒杀用什么数据库,怎么实现的?

答:因为秒杀的一瞬间,并发非常大,如果同时请求数据库,会导致数据库的压力非常大,导致数据库的性能急剧下降,更严重的可能会导致数据库服务器宕机。这时候一般采用内存高速缓存数据库redis来实现的,redis是非关系型数据库,redis是单线程的,通过redis的队列可以完成秒杀过程。

68、什么是单点登录?

答:单点登录SSO(Single Sign On)说得简单点就是在一个多系统共存的环境下,用户在一处登录后,就不用在其他系统中登录,也就是用户的一次登录能得到其他所有系统的信任。

69、谈谈对MVC的认识

Model(模型),是程序的主体部分,主要包含业务数据和业务逻辑。在模型层,还会涉及到用户发布的服务,在服务中会根据不同的业务需求,更新业务模型中的数据。

View(视图),是程序呈现给用户的部分,是用户和程序交互的接口,用户会根据具体的业务需求,在View视图层输入自己特定的业务数据,并通过界面的事件交互,将对应的输入参数提交给后台控制器进行处理。

Contorller(控制器),Contorller是用来处理用户 输入数据,已经更新业务模型的部分。控制器中接收了用户与界面交互时传递过来的数据,并根据数据业务逻辑来执行服务的调用和更新业务模型的数据和状态。

70、索引的优缺点

优点:

a)可以保证数据库表中每一行的数据的唯一性

b)可以大大加快数据的索引速度

c)加速表与表之间的连接,物别是在实现数据的参考完事性方面特别有意义

d)在使用分组和排序子句进行数据检索时,同样可以显著减少查询中分组和排序的时间

f)通过使用索引,可以在时间查询的过程中,使用优化隐藏器,提高系统的性能

缺点:

a)  创建索引和维护索引要耗费时间,这种时间随着数据量的增加而增加

b)  索引需要占物理空间,除了数据表占用数据空间之外,每一个索引还要占用一定的物理空间,如果需要建立聚簇索引,那么需要占用的空间会更大

c)  以表中的数据进行增、删、改的时候,索引也要动态的维护,这就降低了整数的维护速度

d)  建立索引的原则

e)  在经常需要搜索的列上,可以加快搜索的速度

f)  在作为主键的列上,强制该列的唯一性和组织表中数据的排列结构

g)  在经常用在连接的列上,这些列主要是一外键,可以加快连接的速度

h)  在经经常需要根据范围进行搜索的列上创建索引,国为索引已经排序,其指定的范围是连续的

i)  在经常需要排序的列上,国为索引已经排序,这样井底可以利用索引的排序,加快排序井底时间

j)  在经常使用在where子句中的列上,加快条件的判断速度

71、写出将一个数组里的空值去掉的语句

$arr = array(‘’,1,2,3,’’,19);

第一种方法:

$array1 = array('  ',1,'',2,3);

print_r(array_filter($array1, "del"));

function del($var)

{
       return(trim($var));
}

第二种方法:

$arr=array("",1,2,3,"");

$ptn="/\S+/i";

print_r(preg_grep($ptn,$arr));

72、PHP实现页面跳转

方法一:php函数跳转,缺点,header头之前不能有输出,跳转后的程序继续执行,可用exit中断执行后面的程序。
header(“Location:网址”);//直接跳转
header(“refresh:3;url=http://axgle.za.NET”);//三秒后跳转

73、双引号和单引号的区别

a)双引号解释变量,单引号不解释变量

b)双引号里插入单引号,其中单引号里如果有变量的话,变量解释

c)双引号的变量名后面必须要有一个非数字、字母、下划线的特殊字符,或者用{}讲变量括起来,否则会将变量名后面的部分当做一个整体,引起语法错误

d)双引号解释转义字符,单引号不解释转义字符,但是解释'\和\\

e)能使单引号字符尽量使用单引号,单引号的效率比双引号要高(因为双引号要先遍历一遍,判断里面有没有变量,然后再进行操作,而单引号则不需要判断)

74、写一个email的正则表达式

/^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/

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

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

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

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

$str=‘aAbB’;

echo strpos($str,"A");

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

function F($n){   

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

 }
 var_dump(F(5));

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

$_SERVER["REMOTE_ADDR"]

$_SERVER["SERVER_ADDR"]

79、匹配中国居民身份证号码的正则表达式

(^d{15}$)|(^\d{18}$)|(^d{17}(d|X|x)$)

80、什么是异常处理与错误处理

当运行的程序发生异常被抛出时,程序不会继续执行异常处后面的代码,PHP 会尝试查找匹配的“catch”代码块。如果异常没有被捕获,那么将会发生严重的错误,程序会终止或者不受控制地执行。

示例代码如下:

<?php
    function GetNum($num)

    {

        if($num > 10)

        {

            throw new Exception("Exception ocur");

        }

        return true;

    }

    GetNum(100);

?>

程序的运行结果为
Uncaught exception ‘Exception’ with message ‘Exception ocur’

从这个例子可以看出,如果不对异常进行处理,那么当程序有异常抛出的时候就会结束执行。而对于对象方法的异常处理,还有另外一种处理方法,下面介绍在PHP中当调用一些不存在的对象方法时的异常处理,从而保证程序正常运行。这主要是通过__call方法来实现的。
方法声明为__call( f u n n a m e , funname, funname,arr_value),当被调用方法不存在的时候会默认调用这个方法。
示例代码如下:

class My {

    function __call($n,$v) {

        echo "错误的方法名:".$n;

        echo "错误的参数:".$v;

    }

}

81、什么是内存管理?

内存管理主要是指程序运行时对计算机内存资源的分配、使用和释放等技术,内存管理的目标是高效、快速地分配内存同时及时地释放和回收内存资源。内存管理主要包括是否有足够的内存供程序使用,从内存池中获取可用内存,使用后及时销毁并重新分配给其他程序使用。

在PHP开发过程中,如果遇到大数组等操作,那么可能会造成内存溢出等问题。一些常见的处理方法如下:

1)通过ini_set(‘memory_limit’,‘64M’)方法重置php可以使用的内存大小,一般在远程主机上是不能修改php.ini文件的,只能通过程序设置。注:在safe_mode(安全模式)下,ini_set会失效。

2)另一方面可以对数组进行分批处理,及时销毁无用的变量,尽量减少静态变量的使用,在需要数据重用时,可以考虑使用引用(&)。同时对于数据库、文件操作完要及时关闭,对象使用完要及时调用析构函数等。

3)及时使用unset()函数释放变量,使用时需要注意以下两点:
① unset()函数只能在变量值占用内存空间超过256字节时才会释放内存空间。
② 只有当指向该变量的所有变量都销毁后,才能成功释放内存。

82、字符串翻转

function strrev($str)   {  

    if ($str == '') return 0;  

    for ($i=(strlen($str)-1); $i>=0; $i--){  

        $rev_str .= $str[$i];  

    }  

    return $rev_str;

}

83、字符串比较

function strcmp($s1, $s2)   {

    if (strlen($s1) < strlen($s2)) return -1;

    if (strlen($s1) > strlen($s2)) return 1;

    for ($i=0; $i
        if ($s1[$i] == $s2[$i]){

            continue;

        }else{         

            return false;

        }  

    }  

    return 0;

}

84、查找字符串

function strstr($str, $substr)  {

    $m = strlen($str);

    $n = strlen($substr);

    if ($m < $n) return false;

    for ($i=0; $i<=($m-$n+1); $i++){

        $sub = substr($str, $i, $n);

        if (strcmp($sub, $substr) == 0) return $i;

    }

    return false;

}

85、字符串替换

function str_replace($substr, $newsubstr, $str) {

    $m = strlen($str);

    $n = strlen($substr);

    $x = strlen($newsubstr);

    if (strchr($str, $substr) == false) return false;

    for ($i=0; $i<=($m-$n+1); $i++){

        $i = strchr($str, $substr);

        $str = str_delete($str, $i, $n);

        $str = str_insert($str, $i, $newstr);

    }

    return $str;

}

86、什么事面向对象?主要特征是什么?

面向对象是程序的一种设计方式,它利于提高程序的重用性灵活性拓展性,使程序结构更加清晰。主要特征:封装、继承、多态

87、非贪婪匹配符

字符描述
?当该字符紧跟在任何一个其他限制符 (*, +, ?, {n}, {n,}, {n,m}) 后面时,匹配模式是非贪婪的。非贪婪模式尽可能少的匹配所搜索的字符串,而默认的贪婪模式则尽可能多的匹配所搜索的字符串。例如,对于字符串 “oooo”,‘o+?’ 将匹配单个 “o”,而 ‘o+’ 将匹配所有 ‘o’。

88、MySQL数据库作发布系统的存储,一天五万条以上的增量,预计运维三年,怎么优化

a. 设计良好的数据库结构,允许部分数据冗余,尽量避免join查询,提高效率。
b. 选择合适的表字段数据类型和存储引擎,适当的添加索引。
c. mysql库主从读写分离。
d. 找规律分表,减少单表中的数据量提高查询速度。
e。添加缓存机制,比如memcached,apc等。
f. 不经常改动的页面,生成静态页面。
g. 书写高效率的SQL。比如 SELECT * FROM TABEL 改为 SELECT field_1, field_2, field_3 FROM TABLE.

89、php中字符串处理函数列举3-6个

strlen() 函数返回字符串的长度

strpos() 函数用于检索字符串内指定的字符或文本

strtolower — 将字符串转变为小写

strtoupper –将字符串转变为大写

strtr — 对字符串比较替换

substr — 对字符串进行截取

explode — 将一个字符串用分割符转变为一数组形式

implode — 将数组用特定的分割符转变为字符串

90、Reids的特点

Redis本质上是一个Key-Value类型的内存数据库,很像memcached,整个数据库统统加载在内存当中进行操作,定期通过异步操作把数据库数据flush到硬盘上进行保存。因为是纯内存操作,Redis的性能非常出色,每秒可以处理超过 10万次读写操作,是已知性能最快的Key-Value DB。

Redis的出色之处不仅仅是性能,Redis最大的魅力是支持保存多种数据结构,此外单个value的最大限制是1GB,不像 memcached只能保存1MB的数据,因此Redis可以用来实现很多有用的功能,比方说用他的List来做FIFO双向链表,实现一个轻量级的高性 能消息队列服务,用他的Set可以做高性能的tag系统等等。另外Redis也可以对存入的Key-Value设置expire时间,因此也可以被当作一 个功能加强版的memcached来用。

Redis的主要缺点是数据库容量受到物理内存的限制,不能用作海量数据的高性能读写,因此Redis适合的场景主要局限在较小数据量的高性能操作和运算上。

91、使用redis有哪些好处?

(1) 速度快,因为数据存在内存中,类似于HashMap,HashMap的优势就是查找和操作的时间复杂度都是O(1)

(2) 支持丰富数据类型,支持string,list,set,sorted set,hash

(3) 支持事务,操作都是原子性,所谓的原子性就是对数据的更改要么全部执行,要么全部不执行

(4) 丰富的特性:可用于缓存,消息,按key设置过期时间,过期后将会自动删除

92、redis相比memcached有哪些优势?

(1) memcached所有的值均是简单的字符串,redis作为其替代者,支持更为丰富的数据类型

(2) redis的速度比memcached快很多 (3) redis可以持久化其数据

93、Memcache与Redis的区别都有哪些?

1)、存储方式 Memecache把数据全部存在内存之中,断电后会挂掉,数据不能超过内存大小。 Redis有部份存在硬盘上,这样能保证数据的持久性。

2)、数据支持类型 Memcache对数据类型支持相对简单。 Redis有复杂的数据类型。

3)、使用底层模型不同 它们之间底层实现方式 以及与客户端之间通信的应用协议不一样。 Redis直接自己构建了VM 机制 ,因为一般的系统调用系统函数的话,会浪费一定的时间去移动和请求。

94、redis常见性能问题和解决方案:

1).Master写内存快照,save命令调度rdbSave函数,会阻塞主线程的工作,当快照比较大时对性能影响是非常大的,会间断性暂停服务,所以Master最好不要写内存快照。

2).Master AOF持久化,如果不重写AOF文件,这个持久化方式对性能的影响是最小的,但是AOF文件会不断增大,AOF文件过大会影响Master重启的恢复速度。Master最好不要做任何持久化工作,包括内存快照和AOF日志文件,特别是不要启用内存快照做持久化,如果数据比较关键,某个Slave开启AOF备份数据,策略为每秒同步一次。

3).Master调用BGREWRITEAOF重写AOF文件,AOF在重写的时候会占大量的CPU和内存资源,导致服务load过高,出现短暂服务暂停现象。

4). Redis主从复制的性能问题,为了主从复制的速度和连接的稳定性,Slave和Master最好在同一个局域网内

95、mySQL里有2000w数据,redis中只存20w的数据,如何保证redis中的数据都是热点数据

相关知识:redis 内存数据集大小上升到一定大小的时候,就会施行数据淘汰策略(回收策略)。redis 提供 6种数据淘汰策略:

volatile-lru:从已设置过期时间的数据集(server.db[i].expires)中挑选最近最少使用的数据淘汰

volatile-ttl:从已设置过期时间的数据集(server.db[i].expires)中挑选将要过期的数据淘汰

volatile-random:从已设置过期时间的数据集(server.db[i].expires)中任意选择数据淘汰

allkeys-lru:从数据集(server.db[i].dict)中挑选最近最少使用的数据淘汰

allkeys-random:从数据集(server.db[i].dict)中任意选择数据淘汰

no-enviction(驱逐):禁止驱逐数据

96、为什么redis需要把所有数据放到内存中?

Redis为了达到最快的读写速度将数据都读到内存中,并通过异步的方式将数据写入磁盘。所以redis具有快速和数据持久化的特征。如果不将数据放在内存中,磁盘I/O速度为严重影响redis的性能。

97、redis的并发竞争问题如何解决?

Redis为单进程单线程模式,采用队列模式将并发访问变为串行访问。Redis本身没有锁的概念,Redis对于多个客户端连接并不存在竞争,但是在Jedis客户端对Redis进行并发访问时会发生连接超时、数据转换错误、阻塞、客户端关闭连接等问题,这些问题均是

由于客户端连接混乱造成。对此有2种解决方法:

1.客户端角度,为保证每个客户端间正常有序与Redis进行通信,对连接进行池化,同时对客户端读写Redis操作采用内部锁synchronized。

2.服务器角度,利用setnx实现锁。

注:对于第一种,需要应用程序自己处理资源的同步,可以使用的方法比较通俗,可以使用synchronized也可以使用lock;第二种需要用到Redis的setnx命令,但是需要注意一些问题。

98、redis 最适合的场景

(1)、会话缓存(Session Cache)

(2)、全页缓存(FPC)

(3)、队列

(4),排行榜/计数器

(5)、发布/订阅

99、防护

1, XSS 跨站脚本攻击
2, DDOS 流量攻击
3, CSRF 跨站请求伪造攻击
4, SQL注入

100、微信支付具体实现流程

  1. H5页面发起支付请求,请求生成支付订单
  2. 调用统一下单API,生成预付单
  3. 生成JSAPI页面调用的支付参数并签名
  4. 微信浏览器自动调起支付 JSAPI接口支付
  5. 确认支付
  6. 异步通 知商户支付结果,商户收到通知返回确认信息
  7. 返回支付结果,展 示支付信息给用户

101、事务有哪几个特性

原子性、一致性、隔离性、持久性

102、事务的隔离级别

未提交读、已提交读、可重复读、可串行化

103、PHP的意思

答:PHP是一个基于服务端来创建动态网站的脚本语言,您可以用PHP和HTML生成网站主页

104、对json数据格式的理解

JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,json数据格式固定,可以被多种语言用作数据的传递

105、TP的特性有哪些

1.多表查询非常方便,在model中几句代码就可以完成对多表的关联操作

2.融合了smarty模板,使前后台分离

3.支持多种缓存技术,尤其对memcache技术支持非常好

4.命名规范,模型,视图,控制器严格遵循命名规则,通过命名一一对应

5.支持多种url模式

6.内置ajax返回方法,包括xml,json,html等

7.支持应用扩展,类库扩展,驱动扩展等

106、简述数据库的优化

数据库的优化可以从四个方面来优化:

1.从结构层: web服务器采用负载均衡服务器,mysql服务器采用主从复制,读写分离

2.从储存层: 采用合适的存储引擎,采用三范式

3.从设计层: 采用分区分表,索引,表的字段采用合适的字段属性,适当的采用逆范式,开启mysql缓存

4.sql语句层:结果一样的情况下,采用效率高,速度快节省资源的sql语句执行

107、获取URL后缀名

pathinfo()解析文件路径,返回其组成部分;

返回关联数组

dirname    文件路径

basename   文件名+扩展名

extension   最后一个扩展名

filename   文件名

实例:

print_r( pathinfo('/ab/cd/e.php') );

Array(

  [dirname] => /ab/cd

  [basename] => e.php

  [extension] => php

  [filename] => e

)

扩展:

打印解析路径    var_dump( pathinfo($path) );

打印路径的父级路径    var_dump( pathinfo($path, PATHINFO_DIRNAME) );

打印路径的尾名    var_dump( pathinfo($path, PATHINFO_BASENAME) );

打印路径的最后的扩展名   var_dump( pathinfo($path, PATHINFO_EXTENSION) );

打印路径的文件的名字   var_dump( pathinfo($path, PATHINFO_FILENAME) );

108、数据库主从复制,读写分离

  • 什么是主从复制

主从复制,是用来建立一个和主数据库完全一样的数据库环境,称为从数据库;

  • 主从复制的原理:

1.数据库有个bin-log二进制文件,记录了所有的sql语句。

2.只需要把主数据库的bin-log文件中的sql语句复制。

3.让其从数据的relay-log重做日志文件中在执行一次这些sql语句即可。

  • 主从复制的作用

1.做数据的热备份,作为后备数据库,主数据库服务器故障后,可切换到从数据库继续工作,避免数据丢失。

2.架构的扩展。业务量越来越大,I/O访问频率过高,单机无法满足,此时做多库的存储,降低磁盘I/O访问频率,提高单机的I/O性能

3.主从复制是读写分离的基础,使数据库能制成更大 的并发。例如子报表中,由于部署报表的sql语句十分慢,导致锁表,影响前台的服务。如果前台服务使用master,报表使用slave,那么报表sql将不会造成前台所,保证了前台的访问速度。

  • 主从复制的几种方式:

1.同步复制:所谓的同步复制,意思是master的变化,必须等待slave-1,slave-2,…,slave-n完成后才能返回。

2.异步复制:如同AJAX请求一样。master只需要完成自己的数据库操作即可。至于slaves是否收到二进制日志,是否完成操作,不用关心。MYSQL的默认设置。

3.半同步复制:master只保证slaves中的一个操作成功,就返回,其他slave不管。

这个功能,是由google为MYSQL引入的。

  • 关于读写分离

在完成主从复制时,由于slave是需要同步master的。所以对于insert/delete/update这些更新数据库的操作,应该在master中完成。而select的查询操作,则落下到slave中。

109、数据库索引

什么是索引

索引是对数据库表中一列或多列的值进行排序的一种结构,使用索引可快速访问数据库表中的特定信息。(摘自百度百科)

索引类型

1.FULLTEXT 全文索引

全文索引,仅MyISAM引擎支持。其可以在CREATE TABLE ,ALTER TABLE ,CREATE INDEX 使用,不过目前只有 CHAR、VARCHAR ,TEXT 列上可以创建全文索引。

2.HASH 哈希索引

HASH索引的唯一性及类似键值对的形式十分适合作为索引,HASH索引可以一次定位,不需要像树形索引那样逐层参照,因此具有极高的效率。但是这种高效是有条件的。即只在“=”和“in”条件下高效,对于范围查询,排序及组合索引仍然效率不高。

3.BTREE 树形索引

BTREE所以是一种将索引按一定算法,存入一个树形的数据结构中(二叉树),每次查询都是从树的入口root开始,一次遍历node,获取leaf。这是MySQL中默认也是最常用的索引类型。

4.RTREE

RTREE在MySQL中很少使用,仅支持geometry数据类型,支持该存储引擎只有MyISAM、BDb、InnoDb、NDb、Archive几种。相对于BTREE,RTREE的优势在于范围查找。

索引种类

普通索引:仅加速查询

唯一索引:加速查询+列值唯一(可以有null)

主键索引:加速查询+列值唯一(不可以有null)+表中只有一个

组合索引:多列值组成一个索引,专门用于组合搜索,其效率大于索引合并

全文索引:对文本内容进行分词,进行搜索

外键索引:与主键索引形成联系,保证数据的完整性。

索引使用的注意事项

1.符合索引遵循前缀原则

2.like查询%不能再前,否则索引失效。如有需要,使用全文索引

3.column is null可以使用索引

4.如果MySQL估计使用索引比全表扫描慢,则放弃使用索引

5.如果or前的条件中列有索引,后面的没有,索引不会生效。

6.列类型是字符串,查询时,一定要给值加引号,否则索引失效。

7.确定order by 和 group by 中只有一个表的列,这样才能使用索引

110、高并发的解决方案

web服务器优化 :负载均衡

流量优化:防盗链处理 将恶意请求屏蔽,

前端优化:减少http请求、添加异步请求、启用浏览器缓存和文件压缩、cdn加速、建立独立的图片服务器、

服务端优化: 页面静态化、并发处理、队列处理、

数据库优化: 数据库缓存、分库分表、分区操作 、读写分离、负载均衡

111、常见的负载均衡方案

1.基于DNS的负载均衡

2.基于四层交换技术的负载均衡

3.基于七层交换技术的负载均衡

4.四层+七层负载结合方案

112、分析MySQL查询慢的原因

1.查看慢查询日志

2.通过pt-query-digest工具分析

3.设置set profiling = 1;开启服务,执行show profile。查看所有语句会监测消耗时间存到临时表

4.找到消耗时间大的ID,执行show profile for query 临时表ID

5.使用show status,show processlist 等命令查看

6.使用explain分析单条SQL语句

113、线程和进程

进程:是并发执行的程序在执行过程中分配和管理资源的基本单位,是一个动态概念,竞争计算机系统资源的基本单位。

线程:是进程的一个执行单元,是进程内科调度实体。比进程更小的独立运行的基本单位。线程也被称为轻量级进程。一个程序至少一个进程,一个进程至少一个线程。

进程线程的区别:

  • 地址空间:同一进程的线程共享本进程的地址空间,而进程之间则是独立的地址空间。

  • 资源拥有:同一进程内的线程共享本进程的资源如内存、I/O、cpu等,但是进程之间的资源是独立的。

一个进程崩溃后,在保护模式下不会对其他进程产生影响,但是一个线程崩溃整个进程都死掉。所以多进程要比多线程健壮。

进程切换时,消耗的资源大,效率高。所以涉及到频繁的切换时,使用线程要好于进程。同样如果要求同时进行并且又要共享某些变量的并发操作,只能用线程不能用进程

  • 执行过程:每个独立的进程程有一个程序运行的入口、顺序执行序列和程序入口。但是线程不能独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制。

  • 线程是处理器调度的基本单位,但是进程不是。

  • 两者均可并发执行。

优缺点:

线程执行开销小,但是不利于资源的管理和保护。线程适合在SMP机器(双CPU系统)上运行。

进程执行开销大,但是能够很好的进行资源管理和保护。进程可以跨机器前移。

何时使用多进程,何时使用多线程?

对资源的管理和保护要求高,不限制开销和效率时,使用多进程。

要求效率高,频繁切换时,资源的保护管理要求不是很高时,使用多线程。

114、PHP处理数组的常用函数?

(1)array() 创建数组

(2)in_array() 判断元素是否在数组中

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

(4)array_merge() 将多个数组合并成一个数组

(5)array_diff() 比较两个或两个以上数组的差异

(6)array_intersect() 获取两个或两个数组以上的交集

(7)array_keys() 获取数组的key列表

(8)array_values() 获取数组的值列表

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

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

(11)array_pop() 弹出并返回 array 数组的最后一个单元(出栈)

(12)array_walk() 使用用户自定义函数对数组中的每个元素做回调处理

115、PHP处理字符串的常用函数?

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

(2)strlen() 获取字符串的长度

(3)mb_strlen() 获取字符串长度(可指定字符编码,对中文字符串计算长度)

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

(5)str_replace() 子字符串替换

(6)str_repeat () 重复一个字符串

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

(8)str_shuffle () 随机打乱一个字符串

(9)sprintf() 返回根据格式化字符串生成的字符串(通常用于获取分表后的数据表名)

(10)strstr() 查找字符串的首次出现

(11)addslashes 使用反斜线引用字符串

116、SQL语句优化的方法

(1)Where子句中:where表之间的连接必须写在其他Where条件之前,那些可以过滤掉最大数量记录的条件必须写在Where子句的末尾.HAVING最后。

(2)用EXISTS替代IN、用NOT EXISTS替代NOT IN。

(3) 避免在索引列上使用计算

(4)避免在索引列上使用IS NULL和IS NOT NULL

(5)对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引。

(6)应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描

(7)应尽量避免在 where 子句中对字段进行表达式操作,这将导致引擎放弃使用索引而进行全表扫描

117、堆和栈的区别

栈是编译期间就分配好的内存空间,因此你的代码中必须就栈的大小有明确的定义;

堆是程序运行期间动态分配的内存空间,你可以根据程序的运行情况确定要分配的堆内存的大小。

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

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

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

区别:

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

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

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

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

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

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

119、$this和self、parent这三个关键词分别代表什么?在哪些场合下使用?

$this 当前对象

self 当前类

parent 当前类的父类

$this在当前类中使用,使用->调用属性和方法。

self也在当前类中使用,不过需要使用::调用。

parent在类中使用。

120、作用域操作符::如何使用?都在哪些场合下使用?

(1)调用类常量

(2)调用静态方法(使用static修饰的类方法)

121、Nginx 怎么实现负载均衡

1.轮询

这种是默认的策略,把每个请求按顺序逐一分配到不同的 server,如果 server 挂掉,能自动剔除。

upstream  fengzp.com {  

    server   192.168.99.100:42000;

    server   192.168.99.100:42001; 

}

2.最少连接

把请求分配到连接数最少的 server

upstream  fengzp.com {  

    least_conn;

    server   192.168.99.100:42000;

    server   192.168.99.100:42001; 

}

3.权重

使用 weight 来指定 server 访问比率,weight 默认是 1。以下配置会是 server2 访问的比例是 server1 的两倍。

upstream  fengzp.com {  

    server   192.168.99.100:42000 weight=1;

    server   192.168.99.100:42001 weight=2; 

}

4.ip_hash

每个请求会按照访问 ip 的 hash 值分配,这样同一客户端连续的 Web 请求都会被分发到同一 server 进行处理,可以解决 session 的问题。如果 server 挂掉,能自动剔除。

upstream  fengzp.com {  

    ip_hash;

    server   192.168.99.100:42000;

    server   192.168.99.100:42001; 

}

122、假设现在有人操作数据库,不小心执行错了语句,误删除了很多数据,这时候能恢复吗?怎么恢复。

首先,一定要开启 bin-log ,如果没有开启的话,可能就恢复不了。要看具体的文件系统是否能恢复。开启了 bin-log ,类型设置要设置成 row 或者 mixed ,不能设置 statement 。然后,如果是误删行的话,就可以把里面对应的删除事件换成插入事件,在备用库上执行。如果是误删表的话,可以先获取最近的一次全量备份,放到备库,然后拿出 bin-log , 除了不执行删除的事件,其他事件依次重放。

123、为什么需要三次握手?

主要是为了确认客户端和服务端双方接收是否正常。

第一次:客户端什么都不能确认。服务端能确认客户端的发送正常,自己的接收正常

第二次:客户端能确认自己的发送和接收正常,服务端的发送和接收正常。服务端能确认自己接收正常,客户端的发送正常。

第三次:全部都能确认了。

124、获取一个文件的扩展名

function get_ext1 ($file_name) {

    return strrchr($file_name, '.');                     // .jpg

}

 

function get_ext2 ($file_name) {

    return substr($file_name, strrpos($file_name, '.')); // .jpg

}

 

function get_ext3 ($file_name) {

    $tmp = explode('.', $file_name);

    return array_pop($tmp);                              // jpg

}

 

function get_ext4 ($file_name) {

    return pathinfo($file_name, PATHINFO_EXTENSION);    // jpg

}

125、GD库是做什么用的?

GD库提供了一系列用来处理图片的功能,使用GD库可以处理图片,或者生成图片。在网站上GD库通常用来生成缩略图或者用来对图片加水印或者对网站数据生成报表

126、写出五种以上你使用过的PHP的扩展的名称(提示:常用的PHP扩展)

mb_sring
iconv
curl	//抓取远程图片到本地
GD
XML
socket
MySQL
PDO			//PHP 数据对象 (PDO) 扩展为PHP访问数据库定义了一个轻量级的一致接口。

127、避免跨站攻击

要完成一次CSRF攻击,受害者必须依次完成两个步骤:

1.登录受信任网站A,并在本地生成Cookie。

2.在不登出A的情况下,访问危险网站B。

服务端进行CSRF防御

1.Cookie Hashing(所有表单都包含同一个伪随机值)。因为攻击者不能获得第三方的Cookie(理论上),所以表单中的数据也就构造失败了

2.验证码。每次的用户提交都需要用户在表单中填写一个图片上的随机字符串。

3.One-Time Tokens(不同的表单包含一个不同的伪随机值)

128、写一个判断手机号码(号段为130-139,150-159,170-179,180-189)是否正确的正则表达式。

/^(((13[0-9]{1})|(15[0-9]{1})|(17[0-9]{1})|(18[0-9]{1}))+\d{8})&/

/^(13[0-9]|14[5|7]|15[0|1|2|3|5|6|7|8|9]|18[0|1|2|3|5|6|7|8|9])\d{8}$ /

129、字符串转数组,数组转字符串,字符串截取,字符串替换,字符串查找的函数

字符串转数组
str_split($str)
explode()

数组元素组合为字符串
implode('',$arr)
join(" ",$arr)

字符串截取
substr($str,1,10);

函数替换字符串中的一些字符(区分大小写)
str_replace() 

preg_replace 函数执行一个正则表达式的搜索和替换
preg_replace('/\s+/', '', $str);
$string = 'google 123, 456';
$pattern = '/(\w+) (\d+), (\d+)/i';
$replacement = 'runoob ${2},$3';
echo preg_replace($pattern, $replacement, $string);

正则匹配
//模式分隔符后的"i"标记这是一个大小写不敏感的搜索
if (preg_match("/php/i", "PHP is the web scripting language of choice.")) {
	echo "查找到匹配的字符串 php。";
} else {
	echo "未发现匹配的字符串 php。";
}

查找 "Shanghai" 在 "I love Shanghai!" 中的第一次出现,并返回字符串的剩余部分:
echo strstr("I love Shanghai!","Shanghai");

查找 "php" 在字符串中第一次出现的位置
echo strpos("You love php, I love php too!","php");

查找 "php" 在字符串中最后一次出现的位置
echo strrpos("You love php, I love php too!","php");

130、描述一下大流量高并发量网站的解决方案

1)lvs或nginx负载均衡器 

2)squid缓存或nginx web cache缓存 

3)web服务器选型(nginx代替apache) 

4)php代码静态化(smarty或框架) 

5)sphinx 

6)memcache 

7)sql语句一定要注意索引使用 

8)主从分流 

9)分库分表或分区 

10)磁盘分布(raid0+raid1)

131、防止盗链

1.服务器上防止 

Apache和nginx做rewrite基于源来做判断阻止盗链 

2.代码防止 

$_SERVER[HTTP_REFERER] 

132、用PHP写出一个安全的用户登录系统需要注意哪些方面

1.服务器 

https://www.baidu.com   443   ssl  安全套接字层   服务器证书 

2.用户注册 

注册验证尽量交给php,而不交给js 

3.用户登录 

验证码(图片+语音) 

4.以post提交给后端php程序 

133、什么事面向对象?主要特征是什么?

1)  面向对象是程序的一种设计方式,它利于提高程序的重用性,是程序结构更加清晰。 

2)  主要特征:封装、继承、多态 

134、谈谈你对 MVC 的认识,介绍几种目前比较流行的 MVC 框架?

MVC 是一种设计模式中: 

M 是 model 模型,业务逻辑层 

V 是视图 view  主要负责用户交互层 

C 是控制器  是连接视图和模型的桥梁,就比如一个工厂,C 是老板 M 是工厂,V 是显示给用户的产品,mvc 很好的 

Mvc 优点: 

1)  低耦合性 

2)  高重用性和可使用行 

3)  快速的部署 

4)  可维护性 

135、修改权限

Chmod 777 showme.sh 

136、服务器在运行的过程中,随着用户访问数量的增长,如何通过优化,保证性能?如果

数据库已经达到最优化,请设计出继续升级的解决方案 

squid->lvs|集群->shpinx|memcache->php 静态化(缓存)->分区|主从|一主多从(读写分离) 

首先可以通过 

分库分表缓解一些负担, 

应用缓存服务器,如 MemCache 服务器,
 
增加主从服务器和负载均衡服务器提高网站读取速度,
 
添加静态资源服务器,存放一些静态资源,如 CSS,Js,图片等,
 
提高检索速度可以架设内容检索服务器如 Shpinx,Xapian, 

消息队列服务器,架设数据库集群,  

也可以考虑 NoSQL,如谷歌的 BigTable,DB 连接池,使数据库读写分离

137、试写出 mysql 数据库优化的一些方法

1)选取最适用的字段属性,尽可能减少定义字段长度,尽量把字段设置 NOT  NULL,例如’省份,性别’,最好设置为 ENUM 

(2)使用连接(JOIN)来代替子查询: 

(3)建立索引: 

(4)使用扩展库 PDO /或者 mysqli  使用预处理 stmt  缓存字段 

(5)优化查询语句最好在相同字段进行比较操作  ,select  查询的时候尽量少用*,用到什么字段查什么字段在 sql 语句中尽量少用 mysql 的函数,我们在 PHP 端处理好后再交给mysql 

(6)不要用 like 来查询  这样很不效率,用 Sphinx 全文检索 

(7)分区技术 

(8)主从数据库 

(9)结合 memcache 

(10)结合 sphinx 全文检索 

1.sql 语句优化(索引优化) 

2.表优化 

表复制 

视图表 

分库分表 

分区 

3.数据库优化和服务器优化 

字符集 

Mysql 主从 

Mysql 集群 

138、Include 与 require的区别,require和require_once的效率哪个高?

1)require只会解析一次,include遇到多少次就解析多少次。所以require的速度比include快

2)require出现语法错误,php终止执行并提示错误。include文件出现错误发出警告,不影响程序的执行

Require的效率比require_once的效率更高,因为require_once在包含文件时要进行判断文件是否已经被包含

139、怎么防止sql注入?

1、过滤掉一些常见的数据库操作关键字:select,insert,update,delete,and,*等或者通过系统函数:addslashes(需要被过滤的内容)来进行过滤。

2、在PHP配置文件中Register_globals=off;设置为关闭状态 //作用将注册全局变量关闭。比如:接收POST表单的值使用$_POST['user'],如果将
register_globals=on;直接使用$user可以接收表单的值。

3、SQL语句书写的时候尽量不要省略小引号(tab键上面那个)和单引号

4、提高数据库命名技巧,对于一些重要的字段根据程序的特点命名,取不易被猜到的

5、对于常用的方法加以封装,避免直接暴漏SQL语句

6、开启PHP安全模式

Safe_mode=on;

7、打开magic_quotes_gpc来防止SQL注入

Magic_quotes_gpc=off;默认是关闭的,它打开后将自动把用户提交的sql语句的查询进行转换,把'转为\',这对防止sql注入有重大作用。

因此开启:magic_quotes_gpc=on;

8、控制错误信息

关闭错误提示信息,将错误信息写到系统日志。

9、使用mysqli或pdo预处理

140、分表分库

1、分库分表的方法

一般就是垂直切分和水平切分,这是一种结果集描述的切分方式,是物理空间上的切分

2、阐述:

首先是用户请求量太大,我们就堆机器搞定(这不是本文重点)

然后是单个库太大,这时我们要看是因为表多而导致数据多,还是因为单张表里面的数据多。

如果是因为表多而数据多,使用垂直切分,根据业务切分成不同的库。

如果是因为单张表的数据量太大,这时要用水平切分,即把表的数据按某种规则切分成多张表,甚至多个库上的多张表。

分库分表的顺序应该是先垂直分,后水平分。因为垂直分更简单,更符合我们处理现实世界问题的方式。

3、分表,能够解决单表数据量过大带来的查询效率下降的问题;

4、分库,面对高并发的读写访问,当数据库master服务器无法承载写操作压力时,不管如何扩展slave服务器,此时都没有意义。此时,则需要通过数据分库策略,提高数据库并发访问能力。

5、优点,分库、分表技术优化了数据存储方式,有效减小数据库服务器的负担、缩短查询响应时间。

6、数据分库、分表存储场景条件

	关系型数据库
	
	主从架构(master-slave)
	
	单表数据量在百万、千万级别
	
	数据库面临极高的并发访问
	
7、分库、分表实现策略

	关键字取模,实现对数据访问进行路由
	
更多查看:[更多查看](https://my.oschina.net/u/4097256/blog/4870102)

更多查看:[更多查看](https://blog.csdn.net/qq_24452475/article/details/79859930)

141、设计模式

设计模式:[设计模式](https://www.jb51.net/article/73446.htm)

142、数据库千万级别的数据操作和表设计

查看更多:[查看更多](https://blog.csdn.net/weixin_28737603/article/details/113637295)

143、php面试题之memcache和redis的区别

区别:

1、存储方式不同

memecache 把数据全部存在内存之中,断电后会挂掉,数据不能超过内存大小;redis有部份存在硬盘上,这样能保证数据的持久性,支持数据的持久化(笔者注:有快照和AOF日志两种持久化方式,在实际应用的时候,要特别注意配置文件快照参数,要不就很有可能服务器频繁满载做dump)。

2、数据支持类型不同

redis在数据支持上要比memecache多的多。

3、memcache更加快速,在读取性能上比 Redis 快,缺点是仅支持字符串。

4、Redis支持丰富的数据结构类型,字符串,散列(哈希),集合,有序集合,还支持订阅发布,地理位置等等。

5、持久性

redis支持数据落地持久化存储

memcache不支持数据持久存储

6、分布式存储

redis支持master-slave复制模式

memcache可以使用一致性hash做分布式

查看更多:查看更多
查看更多:查看更多
查看更多:查看更多

144、Redis常见七种使用场景(PHP实战)

查看更多:查看更多

查看更多:查看更多

145、理解阻塞非阻塞与同步异步的区别?

阻塞”与"非阻塞"与"同步"与“异步"不能简单的从字面理解,提供一个从分布式系统角度的回答。1.同步与异步同步和异步关注的是消息通信机制 (synchronous communication/ asynchronous communication)所谓同步,就是在发出一个调用时,在没有得到结果之前,该调用就不返回。但是一旦调用返回,就得到返回值了。换句话说,就是由调用者主动等待这个调用的结果。而异步则是相反,调用在发出之后,这个调用就直接返回了,所以没有返回结果。换句话说,当一个异步过程调用发出后,调用者不会立刻得到结果。而是在调用发出后,被调用者通过状态、通知来通知调用者,或通过回调函数处理这个调用。典型的异步编程模型比如Node.js举个通俗的例子:你打电话问书店老板有没有《分布式系统》这本书,如果是同步通信机制,书店老板会说,你稍等,”我查一下",然后开始查啊查,等查好了(可能是5秒,也可能是一天)告诉你结果(返回结果)。而异步通信机制,书店老板直接告诉你我查一下啊,查好了打电话给你,然后直接挂电话了(不返回结果)。然后查好了,他会主动打电话给你。在这里老板通过“回电”这种方式来回调。2. 阻塞与非阻塞阻塞和非阻塞关注的是程序在等待调用结果(消息,返回值)时的状态.阻塞调用是指调用结果返回之前,当前线程会被挂起。调用线程只有在得到结果之后才会返回。非阻塞调用指在不能立刻得到结果之前,该调用不会阻塞当前线程。还是上面的例子,你打电话问书店老板有没有《分布式系统》这本书,你如果是阻塞式调用,你会一直把自己“挂起”,直到得到这本书有没有的结果,如果是非阻塞式调用,你不管老板有没有告诉你,你自己先一边去玩了, 当然你也要偶尔过几分钟check一下老板有没有返回结果。在这里阻塞与非阻塞与是否同步异步无关。跟老板通过什么方式回答你结果无关。

查看更多:查看更多

146、常用的10个数组方法

in_array(判断数组中是否有某个元素)

implode(将数组按照一定规律分解)

json_encode(将数组转化成json)

sort(排序,有很多排序的函数这里就说一个)

array_push(将一个活多个单元压入数组的末尾)

array_merge(合并数组)

array_key_exists(检查键名是否存在于数组中)

array_unique(去除数组中重复的值,只能对一位数组起作用)

array_shift(移除数组中第一个单元)

147、常用的操作字符串的方法

substr(截取字符串)

strlen(获取字符串长度)

strpos(查找字符串首次出现的位置)

str_replace(字符串替换)

explode(将字符串按照规律转化成数组)

strtoupper(将所有字母变成大写)

strtolower

ucfirst(将字符串的首字母变成大写)

ucwords(将字符串中每个单词的首字母变成大写)

strrev(反转字符串,其实不是很常用)

substr_replace(替换字符串的子串,注意与str_replace的区别)

strip_tags(去除html和php标记,可以选择保留想要的标签)

trim(去除空格)

explode(分割成数组)

148、PHP的基本变量类型

四种标量类型:boolean (布尔型)、integer (整型)、float (浮点型, 也称作 double)、string (字符串)

两种复合类型:array (数组)、object (对象)

最后是两种特殊类型:resource(资源)、NULL(NULL)

149、如何处理负载,高并发?

1、HTML静态化

效率最高、消耗最小的就是纯静态化的html页面,所以我们尽可能使我们的 网站上的页面采用静态页面来实现,这个最简单的方法其实也是最有效的方法。

2、图片服务器分离

把图片单独存储,尽量减少图片等大流量的开销,可以放在一些相关的平台上,如七牛等

3、数据库集群和库表散列及缓存

数据库的并发连接为100,一台数据库远远不够,可以从读写分离、主从复制,数据库集群方面来着手。另外尽量减少数据库的访问,可以使用缓存数据库如memcache、redis。

4、镜像:

尽量减少下载,可以把不同的请求分发到多个镜像端。

5、负载均衡:

Apache的最大并发连接为1500,只能增加服务器,可以从硬件上着手,如F5服务器。当然硬件的成本比较高,我们往往从软件方面着手。

150、HTTP协议中几个状态码的含义:503 500 401 403 404 200 301 302

2XX 成功
200 : 请求成功,请求的数据随之返回。
3XX 重定向
301 : 永久性重定向。
302 : 暂时行重定向。
304 :未修改
305 :使用代理
307 :临时重定向
4XX 请求错误
401 : (未授权)当前请求需要用户验证。
403 : (禁止) 服务器拒绝请求。
404 : (未找到)请求失败,请求的数据在服务器上未发现。
405 :(方法禁用) 禁用请求中指定的方法。
407 :(需要代理授权) 此状态代码与 401(未授权)类似,但指定请求者应当授权使用代理。
5xx 服务器错误
500 : 服务器错误。一般服务器端程序执行错误。
501 :(尚未实施) 服务器不具备完成请求的功能
502 :(错误网关) 服务器作为网关或代理,从上游服务器收到无效响应。
503 : (服务不可用)服务器临时维护或过载。这个状态时临时性的。
504 :(网关超时) 服务器作为网关或代理,但是没有及时从上游服务器收到请求。
505 :(HTTP 版本不受支持) 服务器不支持请求中所用的 HTTP 协议版本。

151、PHP缓存技术有哪些?

(a)全页面静态化缓存

(b)页面部分缓存

(c)数据缓存

(d)查询缓存

(e)按内容变更进行缓存

(f)内存式缓存

(g)apache缓存模块

152、如何避免跨站攻击

要完成一次CSRF攻击,受害者必须依次完成两个步骤:

1.登录受信任网站A,并在本地生成Cookie。

2.在不登出A的情况下,访问危险网站B。

服务端进行CSRF防御

1.Cookie Hashing(所有表单都包含同一个伪随机值)。因为攻击者不能获得第三方的Cookie(理论上),所以表单中的数据也就构造失败了

2.验证码。每次的用户提交都需要用户在表单中填写一个图片上的随机字符串。

3.One-Time Tokens(不同的表单包含一个不同的伪随机值)

153、HTTP 状态中 302、403、 500 代码含义?

302 重定向、403 服务器拒绝访问、500 服务器内部错误

153、服务器在运行的过程中,随着用户访问数量的增长,如何通过优化,保证性能?如果数据库已经达到最优化,请设计出继续升级的解决方案

squid->lvs|集群->shpinx|memcache->php 静态化(缓存)->分区|主从|一主多从(读写分离) 

首先可以通过 

分库分表缓解一些负担, 

应用缓存服务器,如 MemCache 服务器, 

增加主从服务器和负载均衡服务器提高网站读取速度, 

添加静态资源服务器,存放一些静态资源,如 CSS,Js,图片等, 

提高检索速度可以架设内容检索服务器如 Shpinx,Xapian, 

消息队列服务器,架设数据库集群,
  
也可以考虑 NoSQL,如谷歌的 BigTable,DB 连接池,使数据库读写分离

154、试写出 mysql 数据库优化的一些方法

1)选取最适用的字段属性,尽可能减少定义字段长度,尽量把字段设置 NOT NULL,例如’省份,性别’,最好设置为 ENUM

(2)使用连接(JOIN)来代替子查询:

(3)建立索引:

(4)使用扩展库 PDO /或者 mysqli 使用预处理 stmt 缓存字段

(5)优化查询语句最好在相同字段进行比较操作 ,select 查询的时候尽量少用*,用到什么字段查什么字段在 sql 语句中尽量少用 mysql 的函数,我们在 PHP 端处理好后再交给mysql

(6)不要用 like 来查询 这样很不效率,用 Sphinx 全文检索

(7)分区技术

(8)主从数据库

(9)结合 memcache

(10)结合 sphinx 全文检索

1.sql 语句优化(索引优化)

2.表优化

表复制

视图表

分库分表

分区

3.数据库优化和服务器优化

字符集

Mysql 主从

Mysql 集群

155、Include 与 require的区别,require和require_once的效率哪个高?

1)require只会解析一次,include遇到多少次就解析多少次。所以require的速度比include快

2)require出现语法错误,php终止执行并提示错误。include文件出现错误发出警告,不影响程序的执行

Require的效率比require_once的效率更高,因为require_once在包含文件时要进行判断文件是否已经被包含。

其他:

redis:https://zhuanlan.zhihu.com/p/97336560

面试问题:https://zhuanlan.zhihu.com/p/98354084

面试问题:https://www.php.cn/php-weizijiaocheng-424862.html

面试问题:https://www.php.cn/php-weizijiaocheng-437864.html

更多:https://www.php.cn/toutiao-415599.html

主从服务器的搭建:主从服务器的搭建

推荐:推荐

推荐:推荐

  • 0
    点赞
  • 0
    评论
  • 0
    收藏
  • 打赏
    打赏
  • 扫一扫,分享海报

©️2022 CSDN 皮肤主题:游动-白 设计师:我叫白小胖 返回首页

打赏作者

原克技术

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值