php面试题
算法 多刷leetcode 1、给你四个坐标点,判断它们能不能组成一个矩形,如判断([0,0],[0,1],[1,1],[1,0])能组成一个矩形。 设四点(x0, y0), (x1, y1), (x2, y2), (x3, y3) 只要计算三个内角都是直角就可以推导出这四点组成一个矩形 也就是判断相邻的边正交,即相邻边的边矢量点积为0 (x3-x0)(x1-x0)+(y3-y0)(y1-y0) == 0 (以(x0, y0)为顶点的角) 且 (x0-x1)(x2-x1)+(y0-y1)(y2-y1) == 0 (以(x1, y1)为顶点的角) 且 (x1-x2)(x3-x2)+(y1-y2)(y3-y2) == 0 (以(x2, y2)为顶点的角)
点积的值 u的大小、v的大小、u,v夹角的余弦。在u,v非零的前提下,点积如果为负,则u,v形成的角大于90度;如果为零,那么u,v垂直;如果为正,那么u,v形成的角为锐角。
@lzylyd提供了通过斜率求两条边是否垂直的方式(https://baike.baidu.com/item/%E6%96%9C%E7%8E%87) k1 * k2 = (y1-y2)/(x1-x2) * (y2-y3)/(x2-x3) = -1 2、写一段代码判断单向链表中有没有形成环,如果形成环,请找出环的入口处,即P点
class Node{
public $data=null;
public $next=null;
}
function eatList(Node $node) {
$fast = $slow = $node;
$first_target = null;
if($node->data == null) {
return false;
}
while (true) {
if($fast->next != null && $fast->next->next != null) {
$fast = $fast->next->next; //快指针一次走两步
$slow = $slow->next; //慢指针一次走一步
} else {
return false;
}
if($fast == $slow) { //慢指针追上快指针,说明有环
$p1 = $node; //p1指针指向head节点,p2指针指向它们第一次相交的点,然后两个指针每次移动一步,当它们再次相交,即为环的入口
$p2 = $fast;
while($p1 != $p2) {
$p1 = $p1->next;
$p2 = $p2->next;
}
return $p1; //环的入口节点
}
}
}
3、写一个函数,获取一篇文章内容中的全部图片,并下载
function downImagesFromTargetUrl($url, $target_dir = null) {
if(!filter_var($url, FILTER_VALIDATE_URL)){
return false;
}
if(!$target_dir) {
$target_dir = './download';
}
$root_url = pathinfo($url);
$html = file_get_contents($url); //主要
preg_match_all('/<img[^>]*src="([^"]*)"[^>]*>/i',$html, $matchs); //主要
$images = $matchs[1];
foreach ($images as $img) {
$img_url = parse_url($img);
if(! array_key_exists('host', $img_url)) {
$img_url = $root_url['dirname'] . DIRECTORY_SEPARATOR . $img;
} else {
$img_url = $img;
}
$img_path = array_key_exists('path', $img_url) ? $img_url['path'] : $img;
$save = $target_dir . DIRECTORY_SEPARATOR . $img_path;
$save_path = pathinfo($save);
if(!is_dir($save_path['dirname'])) {
mkdir($save_path['dirname'], 0777, true);
}
file_put_contents($save,file_get_contents($img_url)); //主要
}
}
4、获取当前客户端的IP地址,并判断是否在(1.1.1.1,255.255.255.254)
function getip()
{
$unknown = 'unknown';
if (isset($_SERVER['HTTP_X_FORWARDED_FOR']) && $_SERVER['HTTP_X_FORWARDED_FOR'] && strcasecmp($_SERVER['HTTP_X_FORWARDED_FOR'], $unknown)) {
$ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
} elseif (isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'], $unknown)) {
$ip = $_SERVER['REMOTE_ADDR'];
}
/*
处理多层代理的情况
或者使用正则方式:$ip = preg_match("/[\d\.]{7,15}/", $ip, $matches) ? $matches[0] : $unknown;
*/
if (false !== strpos($ip, ','))
$ip = reset(explode(',', $ip));
return $ip;
}
$client_ip = getip();
$client_ip = sprintf('%u', ip2long($client_ip)); //64位系统无压力
/**
* plan A
*/
$range_min = sprintf('%u', ip2long('1.1.1.1'));
$range_max = sprintf('%u', ip2long('255.255.255.255'));
/**
* plan B
*/
$range_min = bindec(decbin(ip2long('1.1.1.1')));
$range_max = bindec(decbin(ip2long('255.255.255.255')));
if ($client_ip >= $range_min and $client_ip <= $range_max) {
echo 'true';
} else {
echo 'false';
}
5、nginx的log_format配置如下:
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$upstream_response_time '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
从今天的nginx log文件 access.log中:
a、列出"request_time"最大的20行?
b、列出早上10点访问量做多的20个url地址?
a: cat /usr/local/var/log/nginx/access.log|sort -nrk9|head -2
b: grep "07/May/2018:10:" /usr/local/var/log/nginx/access.log|awk '{print $12}'|sort -rn|uniq -c|head -20
6、什么是CSRF攻击?XSS攻击?如何防范?
CSRF:https://baike.baidu.com/item/CSRF/2735433
防范方式: CSRF TOKEN, 即提交表单时同时提交一段由服务端渲染表单时生成的token,通过校验token来防范csrf攻击
XSS:https://baike.baidu.com/item/xss/917356
简单来说,XSS就是正常页面执行了用户或黑客提交的前端代码,比如你用了eval('这里执行了用户提交的代码'),
或者你的页面正常解析了用户提交的html代码,如用户提交的个人信息是:<img src="广告连接"><script>window.href="