技术饭
PHP面试的知识点
PHP面试之一:PHP基础知识点
PHP引用变量
- 什么是引用变量?如何定义引用变量?
引用意味着用不同的名字访问同一个内容
定义引用变量:使用&
- 引用变量的工作原理
普通变量的工作原理
$a = range(0,10000);
var_dump(memory_get_usage()); //int(742072)$b = $a;
var_dump(memory_get_usage()); //int(742096)$a = range(0,30000);
var_dump(memory_get_usage()); //int(1532648)
引用变量的工作原理
$a = range(0,10000);
var_dump(memory_get_usage()); //int(742072)$b = &$a;
var_dump(memory_get_usage()); //int(742096)$a = range(0,30000);
var_dump(memory_get_usage()); //int(1135312)
注意:
1、引用变量一旦定义,此变量永远是引用变量,不可能再变回普通变量
2、引用变量可以修改引用的值,例如:$a = 'a';$c = 'c';$b = &$a;$b = &$c; //修改引用
常量及数据类型
- 字符串的定义方式及各自区别
单引号、双引号、heredoc、newdoc
单引号:不能解析变量,只能解析单引号(\')和反斜线(\\)转义字符,比双引号效率高
双引号:解析变量(可使用{}括起来),能解析所有转义字符
heredoc:功能类似双引号(用于大字符串)
newdoc: 功能类似单引号
//heredoc定义$str = <<<EOT
xxxxxxxxxxxxEOT;//newdoc定义$str = <<<'EOT'
xxxxxxxxxxxxxxxxEOT;
- 数据类型
浮点数:不能用于运算/比较运算,因为浮点数不是精确的
FALSE七种情况:0、0.0、'0'、''、NULL、false、array()
超全局数组(九种):
$GLOBALS、$_GET、$_POST、$_SERVER、$_SESSION、$_COOKIE、$_FILES、$_ENV、$_REQUEST
//$GLOBALS包含其他8种
//$_REQUEST包含
$_GET、$_POST和$_COOKIE$_SERVER['REQUESR_URI']与$_SERVER['PATH_INFO']区别
http://localhost/aaa/index.php/foo/bar.html?p=222&q=333
$_SERVER['QUERY_STRING'] = "p=222&q=333";
$_SERVER['REQUEST_URI'] = "/aaa/index.php/foo/bar.html?p=222&q=333";
$_SERVER['SCRIPT_NAME'] = "/aaa/index.php";
$_SERVER['PHP_SELF'] = "/aaa/index.php";
$_SERVER['PATH_INFO'] = ‘/foo/bar.html’
- 常量
2种定义方式:define()与const
define()函数
const是语言结构
区别define()不可以定义类常量
预定义常量
__FILE__、__LINE__
运算符
- PHP错误运算符
@
当将其放置在一个PHP表达式之前,该表达式可能产生的任何错误信息
都将被忽略掉
- 运算符的优先级
递增/递减 > ! > 算术运算符 > 大小比较 > (不)相等比较 > 引用 > ^ > | > 逻辑与&& > 逻辑或|| > 三目 > 赋值 > and > xor > or
<?php
if($a = 3 > 0 && $b = 3 > 0){
echo 'true';
}else{
echo 'false';
}?>
// 相当于if($a = ((3 > 0) && ($b = 3 > 0)))
- 比较运算符
==与===区别
等值判断(FALSE七种情况)
- 逻辑运算符
短路作用: 逻辑与&& > 逻辑或|| > 三目 > 赋值 > and > xor > or
- 递增/递减运算符
1、递增/递减不影响布尔值2、递减NULL值没有效果3、递增NULL值为14、递增/递减位置不同效果不同
流程控制
PHP遍历数组的三种方式及各自区别
1.for循环(while/do...while)
2.foreach循环
3.while、each()、list()组合
区别:
for循环:只能遍历索引数组
foreach循环:能遍历关联数组和索引数组
while、each()、list()组合:能遍历关联数组和索引数组
foreach循环遍历数组前,会对数组进行reset()操作
while、each()、list()组合则不会进行reset()操作
PHP分支结构
if...elseif...
原则:可能性大的放在前面switch...case...
与 if 区别: 判断参数的数据类型只能是整形、浮点、字符串
switch...case...中,如果使用continue与break等价
如果switch...case...外层还有for,那么使用continue2才可以跳出循环
一般switch要比if性能高
自定义函数及内部函数
- 变量作用域
大部分变量只有一个单独的范围,这个单独范围跨度包含了include与requires的文件
如果在非类中引入文件,该文件内部可以使用全局变量和函数
如果在类中引入文件,该文件内部可以使用函数、类的方法、类的属性
- 函数/方法传参
传参分2种:
1、值传递
2、引用传递(函数修改该值,传递的参数必须是变量
)
//引用传递函数定义
$a = 1;
function fn(&$a){
return ++$a;
}
echo fn($a); //2
- 函数返回值
可以返回任意数据类型的值
省略return 默认返回NULL,如果要返回多个值请使用数组
函数2种方式返回
1、普通返回
2、引用返回
function &fn(){
$a = 5;
return $a;
}
$b = &fn();
让函数内部修改外部变量的值
,使用引用传参
让外部变量修改函数内部变量的值
,使用引用返回
- 引入外部文件
引入的代码将继承引入位置的作用域,即使用include或require位置可以使用的变量
include与require区别
- 系统内置函数
时间日期函数
date()、strtotime()、mktime()、time()、microtime()、date_default_timezone_set()
IP处理函数
ip2long()、long2ip()
打印处理函数
print()、printf()、print_r()、echo、sprintf()、var_dump()、var_export()
序列化及反序列化函数
serialize()、unserialize()
字符串处理函数
trim()、
数组处理函数
array_rande()、
正则表达式
- 正则表达式作用(四种)
分割、查找、匹配、替换
作用对象:字符串、字符串、字符串
(重要的事情记3遍)
- 正则表达式的组成部分
分隔符:正斜线(/)、hash符(#)、取反符号(~)
通用原子:\d(匹配数字)、\D、\w(匹配数字、字母、下划线)、\W、\s(匹配空格)、\S元字符:
量词 ?、+、*、{n}、{n,}、{n,m}
通配符 .
范围匹配 []、[-]、[^]
模式修正符:i、m、u、U
- 向后引用
题目:把字符串 '<b>abc</b>' 替换为 'abc' 如何使用正则做到?
$str = '<b>abc</b>';
$pattern = '/<b>(.*)<\/b>/';
preg_replace($pattern, '\\1', $str);
- 贪婪模式
题目:把字符串 '<b>abc</b><b>def</b>' 替换为 'abcdef' 如何使用正则做到?
$str = '<b>abc</b><b>def</b>';
$pattern = '/<b>(.*?)<\/b>/';
$pattern = '/<b>(.*)<\/b>/U';
preg_replace($pattern, '\\1', $str);
注意:默认是贪婪模式
- 正则表达式PHP函数
preg_match()、preg_match_all()、preg_replace()、preg_split()
- 中文匹配问题
中文分utf-8与gbk两种编码,他们正则表达式不同
utf-8: 0x4e00 - 0x9fa5
模式修正符需要使用u
文件及目录处理
- 打开文件函数:
fopen()
用于打开一个文件,打开时需要指定一个打开模式打开模式:r/r+、w/w+、x/x+、a/a+、b、t
r+ 追加写 w 覆盖写
- 读取文件函数:
fread()/fgets()/fgetc()
fgets()
读取一行fgetc()
读取字符
- 写入文件函数:
fwrite()/fputs()
- 关闭文件函数:
fclose()
- 不需要fopen()都能操作文件
file_put_contents()
file_get_contents()
- 访问远程文件(不推荐开启)
开启allow_url_fopen() ,http协议只能使用只读,ftp协议可以只能只读或只写
- 目录操作函数
目录名称:basename()
、dirname()
、pathinfo()
目录读取:opendir()
、readdir()
、closedir()
、rewinddir()
目录删除:rmdir()
目录创建:mkdir()
- 目录遍历
//遍历
function loopDir($dir){
if(is_dir($dir)){
if($handle = opendir($dir)){
while (false !== ($file = readdir($handle))) {
if ($file != "." && $file != "..") {
echo $file.'\n';
if(filetype($dir.DIRECTORY_SEPARATOR.$file === 'dir')){
loopDir($dir.DIRECTORY_SEPARATOR.$file);
}
}
}
}
}else{
echo basename($file).'\n';
}
}
会话控制
- 会话控制的三种实现
1、使用URL带参数的方式(不安全,不推荐)
2、cookie
3、session
- 如果禁用cookie后,该如何实现会话控制?
只能通过URL把SessionID传过去
<a href="next.php?<?php echo session_name().'='.session_id(); ?>">下一页</a>
简化:<a href="next.php?<?php echo SID; ?>">下一页</a>
面向对象
- 访问控制符
public、protected、private
网络协议
- GET与POST区别
1、GET可以收藏成浏览器书签,而POST不行
2、GET可以保存在浏览器历史记录里,而POST不行
3、GET安全性相比POST差
4、GET请求数据编码:application/x-www-form-urlencoded,而POST则除了application/x-www-form-urlencoded编码,还可以是multipart/form-data或者application/json或者text/xml
5、GET请求参数是有长度限制的,url最多2048个字节,而POST没有限制
开发环境及PHP配置
- 版本控制软件
- PHP运行原理
主要了解 CGI、FastCGI、PHP-FPM
CGI:是一种通讯协议(已经过时,性能低下)
FastCGI:也是一种通讯协议,是CGI的升级版(现在推荐使用)
PHP-FPM:是FastCGI进程管理器
php-cgi.exe:是PHP脚本解析器,不是FastCGI进程管理器
PHP 有5种PHP运行模式
:链接
1、以CGI模式运行PHP
LoadModule cgi_module modules/mod_cgi.so //要加载apache自带模块
<Files ~ "\.php$">
Options FollowSymLinks ExecCGI
AddHandler cgi-script .php
FcgidWrapper "D:/BtSoft/WebSoft/php/7.1/php-cgi.exe" .php
</Files>
//如果同时打开多个则会有很多php-cgi.exe,并且在执行完成之后消失:
2、以FastCGI模式运行PHP
FastCGI模式根据进程管理器的不同可以分为:Apache内置进程管理器,PHP-FPM进程管理器
Apache内置进程管理器:
LoadModule fcgid_module modules/mod_fcgid.so //要加载apache模块,该模块要单独下载
<IfModule fastcgi_module>
FastCgiServer /home/weiyanyan/local/apache/cgi-bin/php-cgi -processes 20
AddType application/x-httpd-php .php
AddHandler php-fastcgi .php
Action php-fastcgi /cgi-bin/php-cgi
</IfModule>
PHP-FPM进程管理器:LoadModule fastcgi_module modules/mod_fcgid.so
<IfModule fastcgi_module>
FastCgiExternalServer /home/weiyanyan/local/apache/cgi-bin/php-cgi -host 127.0.0.1:9000
AddType application/x-httpd-php .php
AddHandler php-fastcgi .php
Action php-fastcgi /cgi-bin/php-cgi
</IfModule>
php54是之前是一种关系,php54之后另一种关系。
php54之前,php-fpm(第三方编译)是管理器,php-cgi是解释器
php54之后,php-fpm(官方自带),master 与 pool 模式。php-fpm 和 php-cgi 没有关系了。php-fpm又是解释器,又是管理器
3、以Apache模块模式运行PHP
LoadModule php5_module "C:/php5/php5apache2_2.dll" AddType application/x-httpd-php .php
- PHP常见配置
PHP 数组排序
PHP面试之二:高并发与大数据
web资源防盗链
- 盗链是什么? 为什么要防?
在自己页面上显示一些不是自己服务器的资源
(图片、音频、视频、css、js等)由于别人盗链你的资源会加重你的服务器负担,所以我们需要防止
可能会影响统计
- 防盗链是什么? 有哪几种方式?
防止别人通过一些技术手段绕过本站的资源展示页,盗用本站资源,让绕开本站资源展示页面的资源链接失效
大大减轻服务器压力
1、Referer (易伪造referer,安全性低)
2、加密签名 (安全性高)
- 防盗链的工作原理
通过Referer,服务器可以检测到访问目标资源的来源网站,如果是资源文件,则可以跟踪到显示它的网页地址。一旦检测到来源网站不是本站进行阻止
通过签名,根据计算签名的方式,判断请求是否合法,如果合法则显示,否则返回错误信息
- Referer实现
以Nginx为例,前提加载
ngx_http_referer_module模块
//指令valid_referers 全局invalid_referer
location ~* \.(gif|jpg|png|webp)$ {
valid_referers none blocked domain.com *.domain.com
if ($invalid_referer) {
return 403;
#rewrite ^/ http://www.domain.com/403.jpg;
}
}
注意:为什么要none呢?因为如果通过浏览器直接访问资源,referer就是为空,所以这种方式不能彻底阻挡住盗链。
- 加密签名
以Nginx为例,前提加载第三方模块
HttpAccessKeyModule
实现防盗链
location ~* \.(gif|jpg|png|webp)$ {
accesskey on;
accesskey_hashmethod md5;
accesskey_arg key;
accesskey_signature "mysrc$remote_addr";
}
减少HTTP请求次数
- 发现问题
80~90%是花费在页面引用控件的加载上,只有10~20%是花费在文档的加载上
HTTP/1.1协议规定请求只能串行发送,换句话就是100个请求,只能一个一个发送,上一个请求完成才能进行下一个请求
- 如何改善?
减少引用控件数量,从而达到减少HTTP请求次数
- 如何实现减少请求?
1、图片地图
原理
:把多张图片合成一张,再使用<map>标签来实现对图片上不同区域的链接
<img src="img/planets.gif" width="145" height="126" alt="Planets" usemap="#planetmap">
<map name="planetmap">
<area shape="rect" coords="0,0,82,126" alt="Sun" href="sun.htm">
<area shape="circle" coords="90,58,3" alt="Mercury" href="mercur.htm">
<area shape="circle" coords="124,58,8" alt="Venus" href="venus.htm">
</map>
2、CSS Sprites(雪碧图)
原理
:合拼图片,再使用css的background-image和background-position来指定显示元素
CSS Sprites与图片地图性能差不多,但CSS Sprites更加简单灵活
3、合并JS与CSS文件
加载一个JS文件比加载多个JS文件要快
一般会使用前端自动构建工具打包合并
4、图片使用base64编码
注意:图片base64除了可以使用在<img>中,还可以使用在css的background-image中
CDN加速
- 什么是CDN加速?
CDN 就是
内容分发网络
,在各处放置服务器
来构成一层智能虚拟网络,此处服务器称之为节点服务器。所谓智能就是会自动根据用户请求信息把请求重新分配到离客户端最近的服务器。
CDN的作用: 解决由于服务端与客户端所在区域的不同,导致影响数据传输速度和稳定性问题,一句话总结就是
让数据传输更快更稳定
。
- CDN有什么优势?
1、
智能Cache加速
,提高企业站点的访问速度(含大量图片或静态页面最适合,因为CDN相当于是服务器的一个镜像)
2、跨运营商的网络加速
,保证不同网络的用户都能得到很好的访问速度
3、加速用户远程访问服务器
,根据DNS负载均衡技术自动智能选择Catch服务器
4、自动生成远程服务器的镜像(Catch服务器)
,加速访问速度,减轻Web服务器的负担,分担流量
- CDN的工作原理是什么?
- CDN适用场景有哪些?
1、网站或应用中大量静态资源的加速分发
(例如:css/js/图片等)2、大文件下载
3、直播网站
- CDN如何实现?
浏览器缓存
高并发下只能通过提高服务器负载来解决?
NO,流量、前端、服务器、数据库
缓存只能是数据库缓存吗?NO,还有浏览器缓存
- HTTP缓存分类(2种)
1.
200 OK (from memory cache)
直接从本地缓存中获取响应,最快速、最省流量,因为没有向服务器发送请求
2.
304 Not Modified
协商缓存,浏览器在本地没有命中的情况下,请求头中会发送一定的校验数据到服务器。如果服务端数据没有改变,服务端直接响应(通知浏览器从本地缓存获取),返回304(快速、发送数据很少,只返回最基本的响应头,不发送响应体)
PS: 以上两种缓存全部失败,服务器返回完整响应体(
200 OK
),没有用到缓存,速度最慢
- 与
浏览器本地缓存
相关的header
Pragma
Cache-Control
Expires
前端代码和资源压缩优化
让资源文件更小,加快文件在网络中传输,让网页更快的展示,降低流量和宽带开销
- 压缩方式
JS、CSS、HTML、图片压缩和Gzip压缩
- JS代码压缩
去除一些多余的空格和回车,替换长变量名,简化一些代码写法
压缩工具:在线版和安装版
- CSS代码压缩
与JS压缩原理一样,去除空白符、注释和优化一下语义化
- HTML代码压缩
(不推荐,镇用)
不推荐使用,因为会破坏代码结构。
- 图片(JPG、PNG)压缩
压缩工具:tinypng/JpegMini/ImageOptim
- Gzip压缩
Gzip压缩
是Web服务器对纯文本文件(JS/CSS/XML/HTML)
进行压缩注意:千万不要对图片进行Gzip压缩
//以Nginx为例
# 开启
gzipgzip on;
# 启用gzip压缩的最小文件,小于设置值的文件将不会压缩
gzip_min_length 1k;
# gzip 压缩级别,1-10,数字越大压缩的越好,也越占用CPU时间,后面会有详细说明,推荐6
gzip_comp_level 6;
# 进行压缩的文件类型。javascript有多种形式。其中的值可以在 mime.types 文件中找到。
gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php;
# 是否在http header中添加Vary: Accept-Encoding,建议开启
gzip_vary on;
# 禁用IE 6
gzipgzip_disable "MSIE [1-6]\.";
# 压缩存储的缓冲
gzip_buffers 16 64k;
# 开启压缩的http版本
gzip_http_version 1.1;
动态语言静态化
将现代动态语言的逻辑代码生成为静态HTML文件(静态化实际作用:缓存成一个html文件),再次访问时就会重定向到静态文件
- 适用场景
对实时性要求不高的页面
- 为什么要使用静态化?
解决高并发,减轻Web服务器和数据库服务器压力
- 静态化实现方式有几种?
1、使用Smarty模板引擎
2、使用ob系列函数
- 使用Smarty模板引擎
//缓存存放目录
$smarty->cache_dir=$ROOT.'/cache';
//开启缓存
$smarty->caching=true;
//缓存过期时间
$smarty->cache_lifetime=3600;
//加载模板
$smarty->display();
//清除所有缓存文件
$smarty->clearAllCache();
//清除特定模板的缓存
$smarty->clearCache('index.tpl');
- 使用ob系列函数(重点,实现静态化基础)
//开启输出缓冲区
ob_start();
//获取输出缓冲区内容
ob_get_contents();
//清空(擦掉)输出缓冲区
ob_clean();
//送出输出缓冲区内容并关闭缓冲
ob_end_flush();
//得到当前缓冲区的内容并删除输出缓冲区
ob_get_clean();
动态语言的并发处理
- 什么是进程?什么是线程?什么是协程?
进程
:是一个“执行中的程序”,程序不执行就不会产生进程。一个执行中的程序至少会产生一个进程,当进程获得了处理机时才会从就绪状态变为运行状态,处理机不断切换地分配到每个进程中。决定同时有多少个进程处于运行状态的是处理器数量(CPU核数)
进程的三态模型:多个程序在系统中运行时,进程在处理机中交替运行,状态在不断切换。
三态分别是:就绪、运行、阻塞
进程的五态模型(在三态的基础上发展而来):新建态、运行态、终止态、就绪态、等待态
线程
:称之为轻量级的进程
,程序执行流的最小单元。线程依赖于进程(一个进程可以有多个线程),线程不拥有系统资源。与同属一个进程的其他线程共享进程拥有的全部资源
;一个线程可以创建和撤销另一个线程,同一个进程中的多个线程可以并发执行
。一个进程下有多个线程来完成不同的工作称之为多线程。(一个进程下至少会有一个线程)
线程由来:由于用户并发请求,为每个请求都创建一个进程显然太浪费系统资源和影响响应用户请求的效率,所以引进线程的概念。
协程
:是一种用户态轻量级
的线程。
//协程与线程的区别1、协程是由用户自己调度,而线程是用系统调度2、协程是异步的,而进程线程是同步的3、一个线程可以有多个协程,一个进程也可以单独拥有多个协程4、协程会保留上一次调用的状态
- 什么是多线程?什么是多进程?
多进程:2个或2个以上的进程处于运行状态,进程间通信不方便
多线程:把一个进程分为很多片,每一片都是一个独立的流程,线程间可以互相通讯
- 同步阻塞模型
- 异步非阻塞模型
- PHP并发编程实战
1.使用
swoole扩展
2.使用
消息队列
3.接口的并发请求
curl_multi_init()
数据缓存
- 什么是数据缓存?
传统关系型数据库都是把数据存储到硬盘中,在高并发情况下,对数据库服务器会造成巨大压力(巨大IO操作),为了解决此问题,数据缓存由此而生!
作用:
1、极大地缓解
数据库服务器的压力
2、提高数据的响应速度
缓存形式有:内存缓存、文件缓存
推荐使用内存缓存
- 为什么要使用数据缓存?(答案如上)
第一次访问:
再次访问:
- 如何使用Mysql查询缓存?
- 如何使用Memcache缓存?
- 如何使用redis缓存?
Web服务器负载均衡
- 实现方式
1、
七层负载均衡(Nginx)
2、四层负载均衡(LVS/硬件设备)
- 七层负载均衡
基于URL等应用层信息
实现负载均衡
// 一般使用Nginx来实现功能强大、性能卓越、运行稳定
配置简单灵活
上传文件使用异步模式
多种分发策略
自动剔除不正常工作设备
- Nginx负载均衡策略
内置
加权轮询、IP Hash
外置
fair策略、通用Hash、一致性Hash
- Nginx配置负载均衡
http{
upstream cluster{ server srv1; server srv2; server srv3;
} server{
listen 80;
location / {
proxy_pass http://cluster;
}
}
}
- 四层负载均衡
有2种方式实现:
1、LVS
2、硬件设备
LVS负载均衡的三种方式:NAT、DR和TUN
硬件设备:通过报文中的目标地址和端口,再加上负载均衡设备的服务器选择方式,决定最终选择的内部服务器
MySQL数据库优化
- 优化方向
字段数据类型优化
tinyint/smallint/int/bigint的选择
char/varcharenum 固定分类IP地址数据如何存?
答案:把IP地址转整型类型存储
索引
SQL语句优化
存储引擎优化
表结构设计优化
数据库服务器架构优化
PHP面试之三:MySQL数据库
基础考点
MySQL 数据类型
整型:tinyint、smallint、mediumint、int、bigint
小数型:float、double、decimal
字符串型:varchar、char、text、blob
时间日期型:time、date、datetime、timestamp
枚举类型:enum
在定义
整型数据类型
时,经常看到 int(4) 括号里指定的是显示长度
,不限制值合法范围,这个显示长度要配合zerofill
这个属性才有意义。
1、 VARCHAR 比 CHAR 更节约空间
2、 CHAR 比 VARCHAR 存储效率更好
3、 VARCHAR 与 CHAR 的长度,如果存储内容超出指定长度,会被截断
4、 存储经常改变的数据,CHAR 不容易产生碎片
尽量避免使用 BLOB/TEXT 类型,导致严重的性能开销
1、 有时可以使用枚举类型代替字符串类型
2、 枚举类型内部存储成整型(节省空间)
3、 避免使用数字作为 enum枚举 的常量,易混乱
1、 尽量使用 TIMESTAMP 来保存时间日期数据
2、 如果需要存储微秒, 可以使用 BIGINT 类型
MySQL 基础操作
连接与关闭:
mysql -u -p -h -P
MySQL 存储引擎(数据表)
MyISAM与InnoDB的区别
1、 InnoDB支持事务,MyISAM不支持事务
2、 InnoDB支持行级锁,MyISAM支持表锁
3、 InnoDB数据存储在共享表空间,MyISAM数据存储在MyD文件和MyI文件
4、 InnoDB支持奔溃后的安全恢复,MyISAM不支持
5、 InnoDB对主键查询的性能高于其他存储引擎
6、 MyISAM拥有全文索引、压缩、空间函数
MySQL 锁机制
由于并发操作的产生,所以需要
使用锁进行并发控制
锁分为2种:共享锁
和排他锁
,就是读锁
和写锁
共享锁(读锁),不堵塞,多个用户可以同时读同一资源,互不干扰
排他锁(写锁),一个写锁会阻塞其他读锁和写锁,这样只允许一个人进行写入操作,防止其他人进行读取或者写入
注意:InnoDB支持行级锁,MyISAM支持表锁
MySQL 事务处理
注意:使用事务的前提是
表必须是InnoDB引擎
安全性考点
SQL注入
使用
预处理
来防止SQL注入
特殊字符转义
写入数据库的数据必须经过
特殊字符转义
操作,此操作在应用层进行
错误记录
当发生查询错误时,不能把
错误信息
返回给用户,把错误记录到日志
索引考察点
使用索引的优缺点
优点:
1、减少服务器扫描的数据量
2、避免排序和临时表3、随机I/O变顺序I/O4、提高查询速度
缺点:
1、降低写的速度
2、占用磁盘
索引使用场景
非常小的表(1~1000) 不使用索引
中型(1000~100W) 使用索引
大型(100W~1000W) 使用索引
超大(1000W以上) 索引 + 分区技术
索引类型
1、普通索引
2、唯一索引 (在普通索引的基础上,加上唯一约束)
3、主键索引 (在唯一索引的基础上,加上不能为Null)
4、组合索引
5、全文索引 (少用,只适合英文)
6、外键索引 (少用,使用业务逻辑进行数据关联)
索引创建原则
1、最适合索引的列是出现在where子句中的列,或连接子句中的列,而不是出现在SELECT关键字后的列
2、索引列基数越大,效果越好
3、对字符串进行索引,应该制定一个前缀长度,可以节省大量索引空间
4、根据情况创建复合索引,复合索引能提高查询效率
5、避免创建过多的索引
6、主键尽量选择较短的数据类型
索引注意事项
1、复合索引遵循前缀原则(重要,按顺序)
2、like查询,%不能在前面(在前面索引会失效,如果要在前面请使用第三方全文索引)
3、列is Null也是可以使用索引
4、如果OR条件想用到索引,必须or前后的字段都需要是索引字段
5、列是字符串类型时,查询时一定要使用引号(单或双),索引才会生效
SQL语句关联考察点
关联操作
1、关联更新2、关联查询
连接方式
1、交叉连接 Cross join (无条件)
select * from A CROSS JOIN B CROSS JOIN C;
2、内连接 INNER JOIN (有条件的交叉连接) 简写 JOIN
select * from A INNER JOIN B INNER JOIN C ON A.id = B.id;
select * from A,B where A.id = B.id;
select * from A T1 INNER JOIN A T2 ON T1.id = T2.id;
3、外连接
左外连接 LEFT JOIN
右外连接 RIGHT JOIN
4、联合连接 (UNION重复的合并,UNION ALL重复的不合并)
SELECT * FROM position UNION SELECT * FROM team;
SELECT * FROM position UNION ALL SELECT * FROM team;
**UNION ALL性能高于UNION**
5、全连接(MySQL不支持)
MySQL高扩展与高可用
分库
分表(水平与垂直)
读写分离
主从复制
负载均衡
PHP面试之四:逻辑与算法
数据结构
常见数据结构
Array
数组是 最简单 而且 应用最广泛 的数据结构
特征:
1、使用连续内存空间来存储
2、存放相同类型或着衍生类型的元素(PHP数组比较特别,可以存放八种数据类型)
3、通过下标来访问
Set
集合
特征:1、保存不重复的元素
Map
字典
特征:1、就是PHP关联数组,以Key/Value形式存储
Stack
栈,与队列相似
特征:1、存储数据是先进先出,栈只有一个出口,只能从栈顶部添加和删除元素
Heap
堆,与二叉树的数据结构相似
特性:1、子节点的键值和索引总小于他的父节点
list
线性表,由零个或多个数据元素组成的有序序列
特性:1、线性表是一个序列,在PHP中就是索引数组
Queue
队列
特性:1、先进先出,并发中使用,可以安全地将对象从一个任务传给另一个任务,可以使用PHP数组模拟
如何模拟双向链表?
使用数组Array来实现array_shift() / array_unshift()array_pop() / array_push()
其它逻辑算法
重点:
找出算法的规律,再用代码来实现
模拟PHP内置函数来实现某些功能
不使用PHP内置函数的前提下,实现字符串翻转
function str_rev($str){
for($i=0;true;$i++){
if(!isset($str[$i])){
break;
}
}
$return = '';
for($j=$i-1;$j>=0;$j--){
$return .= $str[$j];
}
return $return;
}
常见算法考点
算法是什么?
是一种解决问题的计算方法
,一个问题有多种算法
来解决,每种算法效率都不同,根据需求选择最优算法
时间复杂度和空间复杂度
作用:用于
评定
某算法 是否合适?是否高效?
时间复杂度
:执行算法所需要的时间空间复杂度
:执行算法所需要的内存空间
常见时间复杂度 例如:常数阶O(1)、线性阶O(n)、平方阶O(n^2)、立方阶O(n^3)、对数阶O(log2n)、nlog2n阶O(nlog2n)、指数阶O(n^n)
效率从大到小:O(1) > O(log2n) > O(n) > O(nlog2n) > O(n^2) > O(n^3) > O(2^n) > O(n!) > O(n^n)
时间复杂度计算方式:得出算法的计算次数(空间复杂度与之类似)
用1来取代说有确定次数的加法
常见排序算法
冒泡排序、直接插入排序、希尔排序、选择排序、快速排序、归并排序、堆排序
冒泡排序
最坏情况 平均情况
时间复杂度 O(n^2) O(n^2)
空间复杂度 O(1)
直接插入排序
最坏情况 平均情况
时间复杂度 O(n^2) O(n^2)
空间复杂度 O(1)
希尔排序
最坏情况 平均情况
时间复杂度 O(n^2) O(nlog2n)
空间复杂度 O(1)
选择排序
最坏情况 平均情况
时间复杂度 O(n^2) O(n^2)
空间复杂度 O(1)
快速排序
最坏情况 平均情况
时间复杂度 O(n^2) O(nlog2n)
空间复杂度 O(n) O(log2n)
归并排序
最坏情况 平均情况
时间复杂度 O(nlog2n) O(nlog2n)
空间复杂度 O(n)
堆排序
最坏情况 平均情况
时间复杂度 O(nlog2n) O(nlog2n)
空间复杂度 O(1)
常见查找算法
二分查找、顺序查找
二分查找 最坏情况 平均情况
时间复杂度 O(log2n) O(log2n)
空间复杂度 迭代O(1) 递归O(log2n)
顺序查找 最坏情况 平均情况
时间复杂度 O(n) O(n)
空间复杂度 O(1)
参考资料:
https://segmentfault.com/u/104828720_582bfbf471440
https://segmentfault.com/a/1190000011335262
https://segmentfault.com/a/1190000011532769
文明上网理性发言!