PHP面试题目汇总(1)

PHP Code

MySQL

MySQL数据优化

  • 为查询缓存优化查询
  • explain命令查看查询优化
  • 已知查询结果为单条数据,使用limit 1
  • 为搜索字段(where条件中的字段)建立索引
1
2
3
字段重复值过多不适宜索引
索引会降低写入(insert/update)效率,因为写操作会重建索引
单表索引最好不要超过六个
  • join的字段是经过索引的、并且类型相同的
  • 避免order by rand()
  • 避免select *
  • 每张表都应该有一个ID作为主键(最好使用unsigned),不推荐使用email唯一作为索引
  • 有限枚举类型建议使用enum,而非varchar。enum在底层保存的是tinyint
  • 使用PROCEDURE ANALYSE()分析数据库(数据量大的时候更准确)
1
2
3
select id,name,level from `district` procedure analyse();

PROCEDURE ANALYSE([max_elements,[max_memory]])
  • null 取值占用空间,需要谨慎使用;not null的效率比null要高;(虽然oracle对null和empty的处理是一样的,但是mysql中并不一样)
  • 使用Prepared Statements
1
Prepared Statements可以进行参数绑定,使用参数绑定的方式效率会比一般的sql效率要高,同时安全性也在一定程度上变得更好
  • 无缓冲查询 mysql_unbuffered_query() 函数
  • IP地址存成unsigned int
1
2

$r = "UPDATE users SET ip = INET_ATON('{$_SERVER['REMOTE_ADDR']}') WHERE user_id = $user_id";
  • 固定长度的表速度会更快
1
2
查询速度更快,因为它可以更快的找到下一条数据
固定长度的表更容易缓存和重建,但是占的空间更大
  • 垂直分割数据表(垂直分割表示将数据表的字段按照列分成不同的数据表)
1
需要遵循原则是,分出去的表最好不要有join查询,否则性能会下降
  • delete和insert操作会锁表,大量数据的操作可以考虑分割执行
1
2
3
4
5
6
7
8
9
10
while (1) {
//每次只做1000条
mysql_query("DELETE FROM logs WHERE log_date <= '2009-11-01' LIMIT 1000");
if (mysql_affected_rows() == 0) {
// 没得可删了,退出!
break;
}
// 每次都要休息一会儿
usleep(50000);
}
  • 越小的列,速度会越快。比如能使用tinyint可以不使用int,但是需要注意扩展
  • 选择正确的数据库存储引擎
  • 使用ORM(object relational mapper对象关系映射器)(propel)
1
2
ORM(Data mapper)
AR(activite)
  • 谨慎使用持久链接mysql_pconnect()
  • PHP当中mysql和mysqli的区别
1
2
3
4
5
6
7
8
9
10
11
12
13
mysqli扩展有一系列的优势,相对于mysql扩展的提升主要有:

面向对象接口

prepared语句支持(译注:关于prepare请参阅mysql相关文档)

多语句执行支持

事务支持

增强的调试能力

嵌入式服务支持
  • PHP连接mysql使用的方式有:
1
2
3
4
5
6
7
mysql

mysqli

pdo

adodb
  • 水平拆分
1
2
3
4
5
均等的表:哈希方式分表。负载平均分布;扩容不方便(需要重新分表)、主键难以处理

递增分表:根据数据条目分表,需要配合代码逻辑处理。

时间分表:使用OLAP应用
  • 分页优化(Sphinx、Lucence)
  • 谨慎开启Query Cache(Query Cache有性能消耗)
  • 使用exists代替in
1
2
select num from a where num in(select num from b)
select num from a where exists(select 1 from b where num=a.num)
  • 尽量使用表变量代替临时表。如果表表变量包含大量数据,索引有限
  • 减少临时表的创建和删除
1
2
3
4
5
6
7
扩展阅读

https://segmentfault.com/a/1190000006158186

http://coolshell.cn/articles/1846.html

http://www.imooc.com/article/1204
  • 查询语句执行的时间
1
2
3
4
5
6
7
8
9
10
11
12
13
1、开启和关闭
mysql> set profiling=1;
mysql> set profiling=0;
information_schema 的 database 会建立一个PROFILING 的 table 记录.
2、执行一些语句
mysql>show databases;
mysql>use information_schema;
3、查询语句执行时间
mysql>show profiles;
mysql>help show profiles 获得更多提示

扩展阅读
http://blog.csdn.net/ustczyy/article/details/13001353

MySQL引擎

1
2
3
参考阅读

http://www.cnblogs.com/0201zcr/p/5296843.html

数据库主从同步

1
2
3
4
5
参考阅读

http://blog.csdn.net/mycwq/article/details/17136001

https://yq.aliyun.com/articles/24255

MySQL集群

1
2
3
4
参考阅读

http://www.mysqlab.net/tool/mysql-cluster/config.generator/computers/10/cpus/4/memory/16/replica/4

MySQL分表,分区,分库

1
2
3
4
5
6
7
8
分库
http://blog.51yip.com/mysql/1013.html

分区的优点
1,分区可以分在多个磁盘,存储更大一点
2,根据查找条件,也就是where后面的条件,查找只查找相应的分区不用全部查找了
3,进行大数据搜索时可以进行并行处理。
4,跨多个磁盘来分散数据查询,来获得更大的查询吞吐量

PHP

分布式PHP

LVS+keeplived+nginx+apache

更改PHPsession存储路径和引擎

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#php.ini
session.save_handler = files/memcache/redis
session.save_path = ""/"tcp://127.0.0.88:11211"/"tcp://10.133.14.9:6379?auth=yourverycomplexpasswordhere"/
// session.save_path = "session.save_path = "tcp://host1:6379?weight=1&database=2, tcp://host2:6379?weight=2&timeout=2.5, tcp://host3:6379?weight=2""


#.htaccess
php_value session.save_handler "memcache"
php_value session.save_path "tcp://127.0.0.1:11211"

# php文件
ini_set("session.save_handler", "memcache");
ini_set("session.save_path", "tcp://127.0.0.100:11211");

扩展阅读
http://php.net/manual/zh/function.session-set-save-handler.php
http://culttt.com/2013/02/04/how-to-save-php-sessions-to-a-database/

如何实现PHP的多继承

1
2
3
4
5
# trait

http://php.net/manual/zh/language.oop5.traits.php

# interface

nginx连接PHP

1
2
3
4
5
6
7
8
9
10
11
# php-fpm
listen = 127.0.0.1:9000
listen = /dev/shm/php-cgi.sock

# TCP:
fastcgi_pass 127.0.0.1:9000;

# unix domain socket:
fastcgi_pass unix:/dev/shm/php-cgi.sock;

压力比较大的时候使用unix 套接字效果更好

redis

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Data Types:
Strings
Lists
Sets
Hashs
Sorted sets
Bitmaps and HyperLogLogs

Commands:
http://redis.io/commands

参考阅读:
https://matt.sh/introduction-to-redis-data-types

https://github.com/phpredis/phpredis

redis可以作为PHP session存储引擎

变量交换

1
2
3
4
5
6
7
8
9
10
11
function swap1(&$x,&$y) {
$x ^= $y ^= $x ^= $y;
}
function swap2(&$x,&$y) {
list($x,$y) = array($y,$x);
}
function swap3(&$x,&$y) {
$tmp=$x;
$x=$y;
$y=$tmp;
}

fopen vs fsockopen vs curl

1
2
fopen 可以 打开fsockopen能打开的内容
curl的实现可以使用fopen/fsockopen实现

匿名函数&闭包

1
2
3
4
5
6
7
8
9
10
11
参考阅读
http://www.php-internals.com/book/?p=chapt04/04-04-anonymous-function
http://php.net/manual/zh/functions.anonymous.php
http://php.net/manual/zh/class.closure.php

* PHP当中两个是一个玩意儿,js中是不同的玩意儿
http://www.cnblogs.com/rainman/archive/2009/05/04/1448899.html
http://www.cnblogs.com/simplevoid/archive/2013/01/12/2857533.html
https://zh.wikipedia.org/wiki/%E9%97%AD%E5%8C%85_(%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6)
https://zh.wikipedia.org/wiki/%E5%8C%BF%E5%90%8D%E5%87%BD%E6%95%B0

类的可见性

Java类中成员可见性表:

Modifier Class Package Subclass World
public y y y y
protected y y y n
no modifier y y n n
private y n n n
1
2
3
4
PHP类中成员可见性:
PHP当中有三种可见性:public(var/[无修饰符])、protected、private

正常情况下,成员可见性的范围是不可更改的。

PHP遍历目录

1
2
3
4
5
6
7
8
9
10
11
12
13
# 可以改成递归函数,无限极遍历
function listFiles($dir) {
if(is_dir($dir)) {
if($handle = opendir($dir)){
while(($file = readdir($handle)) !== false) {
if($file != "." && $file != ".." && $file != "Thumbs.db") {
echo ''.$file.''."\n";
}
}
closedir($handle);
}
}
}

HTTP Caching

1
2
3
4
5
6
7
8
9
参考阅读

https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/http-caching?hl=en

http://dev.mobify.com/blog/beginners-guide-to-http-cache-headers/

https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control

https://developer.mozilla.org/en-US/docs/Web/HTTP/Caching

HTTP Status Codes

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
1×× Informational
100 Continue
101 Switching Protocols
102 Processing
2×× Success
200 OK
201 Created
202 Accepted
203 Non-authoritative Information
204 No Content
205 Reset Content
206 Partial Content
207 Multi-Status
208 Already Reported
226 IM Used
3×× Redirection
300 Multiple Choices
301 Moved Permanently
302 Found
303 See Other
304 Not Modified
305 Use Proxy
307 Temporary Redirect
308 Permanent Redirect
4×× Client Error
400 Bad Request
401 Unauthorized
402 Payment Required
403 Forbidden
404 Not Found
405 Method Not Allowed
406 Not Acceptable
407 Proxy Authentication Required
408 Request Timeout
409 Conflict
410 Gone
411 Length Required
412 Precondition Failed
413 Payload Too Large
414 Request-URI Too Long
415 Unsupported Media Type
416 Requested Range Not Satisfiable
417 Expectation Failed
418 I'm a teapot
421 Misdirected Request
422 Unprocessable Entity
423 Locked
424 Failed Dependency
426 Upgrade Required
428 Precondition Required
429 Too Many Requests
431 Request Header Fields Too Large
444 Connection Closed Without Response
451 Unavailable For Legal Reasons
499 Client Closed Request
5×× Server Error
500 Internal Server Error
501 Not Implemented
502 Bad Gateway
503 Service Unavailable
504 Gateway Timeout
505 HTTP Version Not Supported
506 Variant Also Negotiates
507 Insufficient Storage
508 Loop Detected
510 Not Extended
511 Network Authentication Required
599 Network Connect Timeout Error

PHP 读取大文本文件

1
2
3
4
5
6
7
参考阅读
http://www.php100.com/html/php/lei/2013/0905/5379.html

http://www.cnblogs.com/gaocheng/archive/2010/11/12/1875317.html

https://www.ibm.com/developerworks/cn/opensource/os-php-readfiles/

正则表达式

1
2
3
4
5
$str = “jianfeng@126.com”;
regex=“([a−z0−9\.−]+)@([\da−z\.−]+)\.([a−z\.]2,6)” ; //正则
return preg_match(regex,str);

filter_var($string, TYPE);

//