常用算法、问答、设计模式

PHP试题:
https://mp.weixin.qq.com/s/ilEVTX6M7BtWapA...
PHP相关知识
https://www.cnblogs.com/jackieron/p/650476...

冒泡排序:
常用算法
二分查找:递归方式
$array = [1,3,6,9,13,18,19,29,38,47,51,56,58,59,60,63,65,69,70,71,73,75,76,77,79,89];
$target = 73;
$low = 0;
$high = count($array)-1;
function bin_search($array, $low, $high, $target){
if ( $low <= $high){
var_dump($low, $high);echo “\n”;
$mid = intval(($low+$high)/2 );
if ($array[$mid] == $target){
return true;
}elseif ( $target < $array[$mid]){
return bin_search($array, $low, $mid-1, $target);
}else{
return bin_search($array, $mid+ 1, $high, $target);
}
}
return false;
}
$find = bin_search($array, $low, $high, $target);
var_dump($find);

分布式解决方案-分布式session一致性问题?
https://www.jianshu.com/p/b889f9a49fec

1.Cookie禁用了,Session还能用吗?
对应的服务器Session,Session ID是通过Cookie来传递的,禁用Cookie相当于失去了Session ID,就得不到Session
php.ini文件中的”session.use_trans_sid = 1“,或者编译时打开打开了”–enable-trans-sid选项”
a.$sn=session_id();
session_id($_GET–>url传过来的参数)
b.fopen w+ 写入session_id()
fread 取出sesson_id

session与cookie的区别?
session:储存用户访问的全局唯一变量,存储在服务器上的php指定的目录中的(session_dir)的位置进行的存放
cookie:用来存储连续訪問一个頁面时所使用,是存储在客户端,对于Cookie来说是存储在用户WIN的Temp目录中的。

如何实现session的共享?
  为什么要实现共享,如果网站是存放在一个机器上,那么是不存在这个问题的,因为会话数据就在这台机器,但是如果使用了负载均衡把请求分发到不同的机器呢?这个时候会话id在客户端是没有问题的,但是如果用户的两次请求到了两台不同的机器,而它的session数据可能存在其中一台机器,这个时候就会出现取不到session数据的情况,于是session的共享就成了一个问题。
  php支持把会话数据存储到某台memcache服务器,你也可以手工把session文件存放的目录改为nfs网络文件系统,从而实现文件的跨机器共享。
一般的解决方案是存入数据库,memcache或者redis这种缓存服务器,当然用默认的文件存储方式也可以,用NFS统一存储。

2.GET、POST传输最大容量是多少?
GET发送http协议通过url方式传递,受浏览器或者服务器的设置限制
POST实体数据,表单传送,通过php.conf的post_max_size可以设置传输大小
3.抓取远程图片到本地,会用什么函数?
file_get_contents() file_put_contents()
4.CGI是什么?什么是FastCGI?php-fpm、FastCGI、Nginx之间是什么关系?
server收到一个php的请求时,会启动一个程序去处理当前的请求,而这个程序就是CGI
通用网关接口(返回标准html数据的服务)
FastCGI 是一个协议,是应用程序和 WEB 服务器连接的桥梁。Nginx 并不能直接与 PHP-FPM 通信,而是将请求通过 FastCGI 交给 PHP-FPM 处理。
php-fpm是fastcgi进程的管理器,用来管理fastcgi进程的。
5.函数内部static和global关键字的作用?
stattic(静态局部变量)作用于函数内,不能用在函数外
global(静态全局变量)可以作用任何地方
6.memcache和Redis的区别及优缺点?
memcache把数据存到内存中,读取速度快。
Redis支持的数据类型更多,数据也可以存到硬盘,断电不会挂掉,数据持久化,memcache一旦断电数据就没了。
都可以一主多从。
7.Include require include_once require_once 的区别?
处理失败方式不同:
require 失败时会产生一个致命级别错误,并停止程序运行。
include 失败时只产生一个警告级别错误,程序继续运行。

include_once/require_once和include/require 处理错误方式一样,
唯一区别在于当所包含的文件代码已经存在时候,不在包含。

8.php魔幻(术)方法及预定义变量;
__construct() 实例化类时自动调用。
__destruct() 类对象使用结束时自动调用。
__set() 在给未定义的属性赋值的时候调用。
__get() 调用未定义的属性时候调用。
__isset() 使用isset()或empty()函数时候会调用。
__unset() 使用unset()时候会调用。
__sleep() 使用serialize序列化时候调用。
__wakeup() 使用unserialize反序列化的时候调用。
__call() 调用一个不存在的方法的时候调用。
__callStatic()调用一个不存在的静态方法是调用。
__toString() 把对象转换成字符串的时候会调用。比如 echo。
__invoke() 当尝试把对象当方法调用时调用。
__set_state() 当使用var_export()函数时候调用。接受一个数组参数。
__clone() 当使用clone复制一个对象时候调用。

预定义变量(超级全局变量)
$GLOBALS
$_SERVER
$_GET
$_POST
$_COOKIE
$_SESSION
$_REQUEST
$_ENV

魔术变量
LINE
FILE
DIR
CLASS
FUNCTION
METHOD
NAMESPACE

9.一些编译php时的configure 参数
–prefix=/usr/local/php php安装目录
–with-config-file-path=/usr/local/php/etc 指定php.ini位置
–with-mysql=/usr/local/mysql mysql安装目录,对mysql的支持
–with-mysqli=/usr/local/mysql/bin/mysql_config mysqli文件目录,优化支持
–enable-safe-mode 打开安全模式
–enable-ftp 打开ftp的支持
–enable-zip 打开对zip的支持
–with-bz2 打开对bz2文件的支持
–with-jpeg-dir 打开对jpeg图片的支持
–with-png-dir 打开对png图片的支持
–with-freetype-dir 打开对freetype字体库的支持
–without-iconv关闭iconv函数,种字符集间的转换
–with-libxml-dir 打开libxml2库的支持
–with-xmlrpc 打开xml-rpc的c语言
–with-zlib-dir 打开zlib库的支持
–with-gd 打开gd库的支持
更多可以使用 ./configure help 查看

10.写代码来解决多进程/线程同时读写一个文件的问题。
PHP是不支持多线程的,可以使用php的flock加锁函数实现。
$fp = fopen(“/tmp/lock.txt”, “w+”);
if (flock($fp, LOCK_EX)) { // 进行排它型锁定
fwrite($fp, “Write something here\n”);
flock($fp, LOCK_UN); // 释放锁定
} else {
echo “Couldn’t lock the file !”;
}
fclose($fp);

11.Mysql 的存储引擎,myisam和innodb的区别。
a. MyISAM类型不支持事务处理等高级处理,而InnoDB类型支持.
b. MyISAM类型的表强调的是性能,其执行数度比InnoDB类型更快.
c. InnoDB不支持FULLTEXT类型的索引.
d. InnoDB 中不保存表的具体行数,也就是说,
执行select count(*) from table时,InnoDB要扫描一遍整个表来计算有多少行,
但是MyISAM只要简单的读出保存好的行数即可.
e. 对于AUTO_INCREMENT类型的字段,InnoDB中必须包含只有该字段的索引,但是在MyISAM表中,可以和其他字段一起建立联合索引。
f. DELETE FROM table时,InnoDB不会重新建立表,而是一行一行的删除。
g. LOAD TABLE FROM MASTER操作对InnoDB是不起作用的,解决方法是首先把InnoDB表改成MyISAM表,导入数据后再改成InnoDB表,
但是对于使用的额外的InnoDB特性(例如外键)的表不适用.
h. MyISAM支持表锁,InnoDB支持行锁。

MyIsam 的存储文件有三个,后缀名分别是 .frm、.MYD、MYI,其中 .frm 是表的定义文件,.MYD 是数据文件,.MYI 是索引文件。
InnoDB 的存储文件有两个,后缀名分别是 .frm 和 .idb,其中 .frm 是表的定义文件,而 idb 是数据文件。
InnoDB 支持事务,且支持四种隔离级别(读未提交、读已提交、可重复读、串行化),默认的为可重复读。

12.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.

13.对于大流量的网站,您采用什么样的方法来解决各页面访问量统计问题
a. 确认服务器是否能支撑当前访问量。
b. 优化数据库访问。
c. 禁止外部访问链接(盗链), 比如图片盗链。
d. 控制文件下载。
e. 使用不同主机分流。
f. 使用浏览统计软件,了解访问量,有针对性的进行优化。

14.是否用过模板引擎? 如果有您用的模板引擎的名字是?
Smarty

15.PHP中this和self的区别
this:对象
self:类

16.如何防止SQL注入,XSS攻击和CSRF攻击
SQL注入:mysqli_real_escape_string()转义关键字符;
XSS攻击:alert把一些cookie信息打印出来;过滤掉<>等关键字符串
CSRF攻击:跨站攻击。防止:token,验证码

17.Nosql 数据库 MemCache、Redis、MongoDB 的区别
1.memcached:单一键值对内存缓存的,做对象缓存无可替代的分布式缓存;
2.redis:是算法和数据结构的集合,快速的数据结构操作是他最大的特点,支持数据持久化;
3.mongodb是bson结构、介于rdb和nosql之间的,更松散更灵活的,但是不支持事务,只用作非重要数据存储。

应用场景:
Memcached:动态系统中减轻数据库负载,提升性能;做缓存,适合多读少写,大数据量的情况(如人人网大量查询用户信息、好友信息、文章信息等)。
Redis:适用于对读写效率要求都很高,数据处理业务复杂和对安全性要求较高的系统(如新浪微博的计数和微博发布部分系统,对数据安全性、读写要求都很高)。
  MongoDB:主要解决海量数据的访问效率问题。

18.PHP 内存回收机制

19.MySQL的只读模式
设置命令:
mysql> set global read_only=1; #1是只读,0是读写
mysql> show global variables like “%read_only%”;
1、对于数据库读写状态,主要靠 “read_only”全局参数来设定;
2、默认情况下,数据库是用于读写操作的,所以read_only参数也是0或faluse状态,这时候不论是本地用户还是远程访问数据库的用户,都可以进行读写操作;
3、如需设置为只读状态,将该read_only参数设置为1或TRUE状态,但设置 read_only=1 状态有两个需要注意的地方:
1)read_only=1只读模式,不会影响slave同步复制的功能,所以在MySQL slave库中设定了read_only=1后,通过 show slave status\G ,命令查看salve状态,可以看到salve仍然会读取master上的日志,并且在slave库中应用日志,保证主从数据库同步一致;
2)read_only=1只读模式,可以限定普通用户进行数据修改的操作,但不会限定具有super权限的用户的数据修改操作;在MySQL中设置read_only=1后,普通的应用用户进行insert、update、delete等会产生数据变化的DML操作时,都会报出数据库处于只读模式不能发生数据变化的错误,但具有super权限的用户,例如在本地或远程通过root用户登录到数据库,还是可以进行数据变化的DML操作;

20.谈谈对闭包的理解。
使用闭包来解决如何访问函数内部变量的问题。
function foo() {
var num = 123;
function fn() {
return num;//
}
return fn;
}
var m=foo();
var f=m();
console.log(f);//输出的值为123,这样就可以访问到函数内部变量num。

21.如何解决 PHP 内存溢出问题?
1.上传excel文件时,出现内存溢出的情况,在文件中分配大点的内存设置内存治标不治本,而且服务器php.ini(memory_limit =128M)有时候是很难改的。所以在文件中设置。但是只有php.ini中的安全模式safe_mode开启时才可以设置。
2.使用sql查询数据,查出来很多,导致内存溢出
sql语句在mysql中可以查询,但是使用php程序查询就报php内存溢出
(1)这个问题在php的官方网站叫缓冲查询和非缓冲查询。php的查询缺省模式是缓冲模式。也就是,查询数据结果一次全部提取到内存里供php程序额外的功能,比如说,计算行数,将指针指向某一行等。更重要的是程序对数据集反复进行二次查询和过滤操作。但这种缓冲查询模式的缺陷是消耗内存,也就是用空间换速度。
(2)另外一种查询模式是非缓冲查询,数据库服务器会一条一条的返回数据,而不是一次全部返回,这样的结果是php程序消耗较少的内存,但却增加了数据库服务器的压力,因为数据库会一直等待php来取数据,一直到数据全部取完。
1.首先查询数据库需要进行limit进行分页查询
2.如果不使用limit,使用非缓冲查询
3.处理数组时出现内存溢出
(1)使用迭代生成器,可以通过继承Iterator接口实现
(2)使用关键词yield

22.如何处理 MySQL 死锁?
https://www.jb51.net/article/159737.htm

foreach 中 &的用法

laravel:
laravel的生命周期(框架运行原理)
Laravel 的生命周期从public\index.php开始,从public\index.php结束。
composer自动加载需要的类:
第一步:Laravel框架所有请求入口统一进入/public/index.php文件,请求通过Ngxin/Apache指向该文件。
index.php文件是加载其他文件入口,本身代码不多。index.php文件载入通过Composer生产的自动加载配置,然后从bootstrap/app.php获取应用实例,创建服务容器。
第二步:Http/Console内核
HTTP内核 继承自Illuminate\Foundation\Http\Kernel类,该类定义了一个bootstrappers数组,该数组中的类在请求被执行前运行,bootstrappers配置了错误处理、日志、检测应用环境、其他在请求被处理前需要处理的任务。
HTTP内核还定义请求处理前需要经过HTTP中间件,该中间件处理HTTP会话的读写、判断应用是否处于维护模式,验证CSRF令牌(防止CSRF攻击)等。
HTTP内核标签方法handle:获取一个Request,返回一个Response,输入HTTP请求,返回HTTP响应。
第三步:内核启动会为应用载入服务提供者,服务提供者都被配置在config/app.php配置文件的providers数组中。服务提供者被注册后,boot方法被调用。
服务提供者负责启动框架的所有组件,如数据库、队列、验证器、路由组件等。因他们启动并配置框架提供的所有特性,服务提供者是整个Laravel启动过程中最重要部分。
第四步:将请求传递给路由(一旦应用被启动且所有服务提供者被注册,Request将会被交给路由器进行分发,路由器将会分发请求到路由或控制器,同时运行所有路由指定的中间件)。

PHP 设计模式
工厂模式:
建立一个工厂(一个函数或一个类方法)来制造新的对象。
工厂模式 是一种类,它具有为您创建对象的某些方法。您可以使用工厂类创建对象,而不直接使用 new。这样,如果您想要更改所创建的对象类型,只需更改该工厂即可。使用该工厂的所有代码会自动更改。

单例模式:
某些应用程序资源是独占的,因为有且只有一个此类型的资源。例如,通过数据库句柄到数据库的连接是独占的。您希望在应用程序中共享数据库句柄,因为在保持连接打开或关闭时,它是一种开销,在获取单个页面的过程中更是如此。
单元素模式可以满足此要求。
PHP 中的单例模式(singleton pattern):指的是在 PHP 的应用程序的范围内只对指定的类创建一个实例。

在 PHP 中使用单例模式的类通常拥有一个私有构造函数和一个私有克隆函数,以防 止用户通过创建对象或者克隆对其进行实例化。还有一个静态私有成员变量 $instance 与静态方法 getInstance。getInstance 负责对其本身实例化,然后将这个对象存储在 $instance 静态成员变量中,以确保只有一个实例被创建。

观察者模式
命令链模式
策略模式

单例模式:
class SingleInstance
{
private function _construct(){
}
private static $instance;
private function _clone(){
}
public static function getInstance(){
self::$instance instanceof SingleInstance){
self::$instance=new SingleInstance();
}
return self ::$instance;
}
}

短连接:例如普通的web请求,在三次握手之后建立连接,发送数据包并得到服务器返回的结果之后,通过客户端和服务端的四次握手进行关闭断开。

长连接:区别于短连接,由于三次握手链接及四次握手断开,在请求频繁的情况下,链接请求和断开请求的开销较大,影响效率。采用长连接方式,执行三次握手链接后,不断开链接,保持客户端和服务端通信,直到服务器超时自动断开链接,或者客户端主动断开链接。

适用场景:
短连接:适用于网页浏览等数据刷新频度较低的场景。
长连接:适用于客户端和服务端通信频繁的场景,例如聊天室,实时游戏等。

PHP向第三方服务器发送post请求
function post($url, $post_data, $timeout=10)
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, 1);
if ($post_data != ‘’) {
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
}
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, ‘POST’);

curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
curl_setopt($ch, CURLOPT_HEADER, false);
$file_contents = curl_exec($ch);
curl_close($ch);
return $file_contents;
}

php获取字节流接口数据
$body_str = @file_get_contents(‘php://input’);
$body = json_decode($body_str, true);
php发送字节流数据
function HttpPost($url, $data)
{
$ch = curl_init();
curl_setopt($ch,CURLOPT_URL,$url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
$res = curl_exec($ch);
curl_close($ch);

return $res;
}

获取access_token,并缓存
// 获取基本access_token,并且缓存(基本access_token每天只能调用2000次)
function get_access_token($APPID, $APPSECRET){
$URL = “https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=".$APPID."&secret=".$APPSECRET;
$result = get($URL);
session(array(‘cache_name’=>’access_token’,’expire’=>7200));
$_SESSION[‘token_expire’] = time() + 7200;
$_SESSION[‘access_token’] = $result[‘access_token’];
$ACCESS_TOKEN = $result[‘access_token’];
return $ACCESS_TOKEN;
}

// 判断基本access_token是否还有效
function token($APPID, $APPSECRET){
if (time() < $_SESSION[‘token_expire’]) {
// if (!empty($_SESSION[‘access_token’])) {
$TOKEN = $_SESSION[‘access_token’];
}else{
$TOKEN = get_access_token($APPID,$APPSECRET);
}
// dump($TOKEN);
return $TOKEN;
}

//获取票据凭证
function get_ticket($ACCESS_TOKEN){
// 获取ticket
$url = “https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=jsapi&access_token=".$ACCESS_TOKEN;
$res = get($url);
session(array(‘name’=>’ticket’,’expire’=>7200));
$_SESSION[‘ticket_expire’] = time() + 7200;
$_SESSION[‘ticket’] = $res[‘ticket’];
$TICKET = $_SESSION[‘ticket’];
return $TICKET;
}
//判断票据是否有效
function ticket($ACCESS_TOKEN){
if (time() < $_SESSION[‘ticket_expire’]) {
// if (!empty($_SESSION[‘ticket’])) {
$TICKET = $_SESSION[‘ticket’];
}else{
$TICKET = get_ticket($ACCESS_TOKEN);
}
// dump($TICKET);
return $TICKET;
}

本作品采用《CC 协议》,转载必须注明作者和本文链接
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!