面试题(程序01)

1.给定一个字符串和一个数字n,如果字符串的长度m小于n,那么在字符串的左侧补上  n-m 个0。

//字符串拼接
// function str($str,$n){
//     $len = strlen($str);
//     if($len<$n){
//         $m = $n-$len;
//         for($i=0;$i<$m;$i++){
//             $str = '0'.$str;   //0必须是字符串的形式
//         }
//     }    
//     return $str;
// }
View Code
function pad_str($string,$n=0,$char=null)
{
    $len = strlen($string);
    $lchar = strlen($char);
    //判断传进的n是不是大于原字符串的长度
    if($n>$len){
        $m = $n-$len; //需要补齐几个字符
        for($i=0;$i<$m;$i++){
            for($j=0;$j<$lchar;$j++){  //如果传入的是字符串,那么把字符串拆分,以一个字符为单位填充,而不是以一个字符串为单位填充
                $string = $char{$j}.$string;  //填充字符
                if(strlen($string) == $n){
                    break 2;                   //填充字符后的长度如果满足要求,则不再填充,跳出循环
                }
            }
        }
    }
    return $string;
}
echo pad_str('aaa',6,'bvvv');    //输出vvbaaa  如果想要输出bvvaaa怎么办?
View Code

2.IP转换

//IP转换
// $ip = '192.168.1.1';
// $a = ip2long($ip);
// echo $a;
// echo '<br>'.long2ip($a);
View Code

3.找出数组中值出现次数大于n的

//数组中某个值出现次数>n的
// function search($arr,$n){
//     $len = count($arr);
//     $b = [];
//     for($i=0;$i<$len;$i++){
//         if(!in_array($arr[$i], array_keys($b))){
//             $b[$arr[$i]] = 1;        
//         }else{
//             $b[$arr[$i]] += 1;
//         }
//     }
//     $c = [];
//     foreach($b as $k=>$v){
//         if($v>=$n){
//             $c[] = $k;
//         }
//     }
//     return $c;
// }

// $arr = [1,1,2,2,3,2,2,6];
// print_r(search($arr,3));
View Code

4.找出数组中最大值,不能用系统函数max等

//找出数组中最大的值
// function getmax($arr){
//     $len = count($arr);
//     $tmp = $arr[0];
//     foreach($arr as $v){
//         if($v>$tmp){
//             $tmp = $v;
//         }
//     }
//     return $tmp;
// }
// $arr = [-1,-2,-3,-44,-6,-9];
//  echo getmax($arr);
View Code

5.求日期差

//求日期差
// $m = '1995-06-27';
// $n = '2019-03-5';
// $a = strtotime($m);
// $b = strtotime($n);
// $k = ceil(abs($b-$a)/(3600*24));
// echo $k;
View Code

 6.给定一个数列[1,2,……1000],执行以下计算:截取前六个数求和并把结果放在数列末尾,直到此数列元素不足6个,求最终数列结果,请编写php代码实现。自己把这道题目扩展了一下,就是数列可以随意给,截取前6个数改成截取前n个数,直到不足n个。

找到规律:以1000个数截取6个为例,1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17········
可以发现6个数能加1次,11个数能加2次,16个数能加3次,在6个数的基础上每多5个数就可以在加1次,那么6其实是在1的基础上多5个数,也就可以发现规律在1的基础上每增加5个数就可以在计算一次。

意思就是:(6-1)/5 次  (11-1)/5 次  (16-1)/5次,假设$len是数列的长度,那么也就是需要循环计算  ($len-1)/5 次,以题目为例就是(1000-1)/5=199次(向下取整)。代码如下

$r = range(1,1000);           ///这是原题目的答案
// var_dump($r);
for($i=0;$i<199;$i++){
    $sum = 0;
    for($j=0;$j<6;$j++){
        $sum+=$r[0];    
        array_shift($r);
    }
    array_push($r,$sum);
}
var_dump($r);

现在循环次数计算出来了,接下来是找截取前m个数的规律,还是举例子来看看:假设现在截取前3个数,那么3个数加1次,5个数加2次,在1的基础上增加2个数就可以在计算一次,和截取前6个数对比,可以发现 如果是截取前m个数,就是在1的基础上每增加 (m-1) 个数都可以再计算一次。推而广之:给定一个数列,其长度是n,截取前m个数,那么就需要循环 (n-1)/(m-1)  次。代码如下

//$arr就是那个数列
function jieQu($arr,$m){
    $len = count($arr);
    $n = floor(($len-1)/($m-1)); //floor是向下取整函数
    for($i=0;$i<$n;$i++){
        $sum = 0;
        for($j=0;$j<$m;$j++){
            $sum += $arr[0];
            array_shift($arr); //把前6个数依次移出
        }
        array_push($arr,$sum);  //前6个数加完之后插入数组最后面
    }
    return $arr;
}
$arr = range(1,1000);
$res = jieQu($arr,6);    //试验1000个数列,截取前6个数,和上面答案一样,OK!!!
print_r($res);
$arr = range(1,1000);
// echo array_sum($arr);
function arr_chop($arr, $n) {
    $len = count($arr);
    if($len<$n) return $arr;
    $m = floor(($len-1)/($n-1));
    for($i=0; $i<$m; $i++){
        $slice_num = array_splice($arr, 0, $n);
        $slice_sum = array_sum($slice_num);
        array_push($arr, $slice_sum);
    }
    return $arr;
}
print_r(arr_chop($arr, 6));
代码更简洁比上面的

 7.给定字符串,大小写互换,其他字符不变

//给定字符串,大小写互换
$str = 'i LOVE yOU';
// chr ord
function btos($str)
{
    $len = strlen($str);
    $newstr = '';
    for($i=0;$i<$len;$i++){
        //把字符转换成ASCII码
        $ord = ord($str{$i});
        //限制转换的字符只能是字母,其他的不转换
        if($ord>=65 && $ord<=90){
            //在这范围内的是大写字母
            $ord += 32;
        }elseif($ord>=97 && $ord<=122){
            //小写字母
            $ord -= 32;
        }
        //转换回字符
        $chr = chr($ord);
        //把转换后的字符拼接起来
        $newstr .= $chr;
    }
    return $newstr;
}
echo  btos($str);
View Code

 8.洗牌

function wash_cards($card_num){
    $tmp = [];
    $b = [];
    //先把牌按顺序存在数组中
    for($i=0;$i<$card_num;$i++){
        $tmp[] = $i+1; 
    }
    for($i=0;$i<$card_num;$i++){
        $j = rand(0,$card_num-$i-1);
        $b[] = $tmp[$j];
        unset($tmp[$j]);  //
        $tmp = array_values($tmp);   //
    }
    return $b;
}

echo '<pre>';
print_r(wash_cards(54));
View Code

 9. 给定一个路径,统计他里面目录和文件的个数(目前好像只能给相对路径,实现不了绝对路径)

 1 //统计目录和文件个数
 2 function total($path)
 3 {    
 4     static $dirnum=0;
 5     static $filenum=0;
 6     //打开要统计的目录
 7     $dir = opendir($path);
 8     //readdir每次只能读一个,需要循环读取
 9     while($dirname = readdir($dir)){
10         //每次读取都会有.和..所以需要过滤, .会形成死循环
11         if($dirname!='.' && $dirname!='..'){
12             //拼接完整路径,,,试验过如果不拼接直接使用$dirname来判断,是不行的,$dirname只是一个单词,不会当做路径
13             $newPath = $path.'/'.$dirname;
14             //判断读到的是目录还是文件,是目录继续读
15             if(is_dir($newPath)){
16                 // var_dump($newPath);
17                 total($newPath);
18                 //目录数加1
19                 $dirnum++;
20             }else{
21                 //读到的是文件
22                 $filenum++;
23                 // echo 111;
24             }
25         }
26     }
27 
28     //关闭资源
29     closedir($dir);
30     return 'dirnum:'.$dirnum.'filenum:'.$filenum ;
31 }
32 
33 $res = total('../blog');
34 echo $res;
View Code

 10. 移动目录

 1 //移动目录
 2 function renameDir($dirSrc,$dirTo)
 3 {
 4     //移动前先判断目标路径是否存在
 5     if(!file_exists($dirTo)){
 6         //不存在则创建一个
 7         mkdir($dirTo);
 8     }
 9     //判断给出的目标路径是不是目录,确保不是文件
10     if(is_file($dirTo)){
11         return '不能将'.$dirSrc.'移动到文件'.$dirTo;
12     }
13     //判断移动的源文件或目录是否存在
14     if(!file_exists($dirSrc)){
15         return '<font color="red">请确认您要移动的目录或文件是否存在';
16     }
17 
18     $dir = opendir($dirSrc);
19     //开始读取
20     while($dirname = readdir($dir)){
21         //还是过滤.和..
22         if($dirname!='.' && $dirname!='..'){
23             //先拼接路径才能去判断
24             $newSrcPath = $dirSrc.'/'.$dirname;
25             $newToPath = $dirTo.'/'.$dirname;
26             if(is_dir($newSrcPath)){
27                 renameDir($newSrcPath,$newToPath);
28             }else{
29                 //rename移动文件
30                 rename($newSrcPath,$newToPath);
31             }
32         }
33     }
34 
35     //关闭资源
36     closedir($dir);
37     return '<font color="green">'.$dirSrc.'成功移动到'.$dirTo.'</font>';
38 }
39 
40 $res = renameDir('./vvv','./test');
41 var_dump($res);
View Code

 11.字符串反转(中文也可以反转)

 1 //可以讲中文反转的函数
 2 function reserver($str)
 3 {
 4     $len = mb_strlen($str);
 5     $newstr = '';
 6     for($i=$len-1;$i>=0;$i--){
 7         $newstr .= mb_substr($str,$i,1,'utf-8');
 8     }
 9     return $newstr;
10 }
11 
12 echo reserver('这种文化分');

 12.输入起始站和终点站,返回票价

 1 function sell($qi,$zh)
 2     {
 3         //相邻的两站之间,把起始站和票价关联起来,也就是说输入起始站就对应这一站到下一站的票价
 4         $station = ['盘锦','西柳','石桥','营口','熊','大连'];
 5         $ticketPrice = [10,5,5,10,7];
 6         //判断输入的起始站是否合法
 7         if(!in_array($qi, $station)){
 8             return '输入的起始站不合法';
 9         }else{
10             //输入的起始站点合法,需要判断输入的终点站是否合法,判断终点站在数组中是否存在
11             //方法是先找到起始站和终点站的索引,比较索引,如果终点站的索引大于起始站的索引,则终点站合法
12             if(!in_array($zh, $station)){
13                 return '终点站不合法,请重新输入';
14             }else{
15                 //判断终点站是不是在起始站之后
16                 $qiIndex = array_search($qi,$station);
17                 $zhIndex = array_search($zh, $station);
18                 if($zhIndex > $qiIndex){
19                     //计算价格
20                     //因为站点数组元素的索引是和票价数组的索引一一对应的,所以可以使用站点索引去截取票价数组
21                     $len = $zhIndex-$qiIndex;
22                     $_price = array_slice($ticketPrice, $qiIndex, $len);
23                     $total = 0;
24                     foreach($_price as $v){
25                         //计算价格
26                         $total += $v;
27                     }
28                     return '您的票价为'.$total.'元';
29                 }else{
30                     return '起始站为'.$qi.',终点站不能是'.$qi.'站之前的站点';
31                 }
32             }
33         }
34     }
35 
36 echo sell('石桥','大连');
View Code

 13.1024的阶乘末尾有多少个0

末尾0的个数取决于乘法中因子2和5的个数。显然乘法中因子2的个数大于5的个数,所以我们只需统计因子5的个数。
是5的倍数的数有: 1024 / 5 = 204个
是25的倍数的数有:1024 / 25 = 40个
是125的倍数的数有:1024 / 125 = 8个
是625的倍数的数有:1024 / 625 = 1个
所以1024! 中总共有204+40+8+1=253个因子5。
也就是说1024! 末尾有253个0。

再看一下25这个是不是有点特殊呢?25 * 4 = 100,能产生两个0,这是为什么呢?因为25 = 5 * 5;因为能产生多余0的个数是和包含因子5的个数相关的。
25 * 4 = 100,有两个0,100无论在和任何非10倍数的数相乘都不可能产生多余两个0的数。同理(75 = 25 * 3 = 5 * 5 3) 4 = 300;(125 = 5 * 5 * 5 )* 8 = 1000;

14.PHP合并数组有几种方式?https://www.cnblogs.com/lcss/p/7757784.html

15.如何实现多个线程安全写入一个文件数据

header("content-type:text/html;charset=utf-8");

$fp = fopen("lock.txt","w+");

if(flock($fp, LOCK_EX)){// 进行排它型锁定

      fwrite($fp,"Write something here
");

      flock($fp, LOCK_UN);// 释放锁定

}else{

     echo "Couldn't lock the file !";

}

 fclose($fp); 
View Code

 测试flock代码:

$fp = fopen('./form.html','r');
if(flock($fp, LOCK_EX)){
    while(!feof($fp)){
        $file = fread($fp, 10);
    }
}

echo $file;
sleep(5);
echo 6666;
flock($fp, LOCK_UN);
fclose($fp);

//测试独占锁,打开两个浏览器窗口测试,OK的。
View Code

 LOCK_SH 共享锁, LOCK_EX  独占锁,  LOCK_UN  释放锁,   LOCK_NB  非阻塞,不加这个则是阻塞

原文地址:https://www.cnblogs.com/bneglect/p/10480296.html