ipv4 地址转整数

IPV4 地址长度为:32为,即 4个字节,以分号十进制组成的4段表示:10.10.10.10,每段数值范围:0 ~ 255 (2^8 - 1)

PHP 内置函数

ip2long() — 将 IPV4 的字符串互联网协议转换成长整型数字
long2ip() — 将长整型转化为字符串形式带点的互联网标准格式地址(IPV4)

地址转整数

32位二进制转十进制,如:10.10.10.10,对应二进制为:00001010 00001010 00001010 00001010,转换十进制:168430090
原理:第一段:向左移 24 位,第二段:向左移 16 位,第三段:向左移 8 位,最后一段:保留原值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
function ip2int(string $ip)
{
$out = 0;
$ex = explode('.', $ip);
if(count($ex) < 3){
return false;
}

for($i = 0; $i <= 3; ++$i){
$str_size = strlen($ex[$i]);
if($str_size == 0 || $str_size > 3){
return false;
}

$out += $ex[$i] << 8 * (3 - $i);
}

return $out;
}

整数转IP

反向处理即可

1
2
3
4
5
6
7
8
9
10
11
12
function int2ip(int $ipint)
{
if(0 > $ipint){
return false;
}
$out = $ipint >> 24;
$out .= '.' . (($ipint & 0x00FFFFFF) >> 16);
$out .= '.' . (($ipint & 0x0000FFFF) >> 8);
$out .= '.' . ($ipint & 0x000000FF);

return $out;
}

IP 转整数应用场景

通过 IP 查找归属地:可利用二分查找算法。

PHP的strtolower()和strtoupper()函数在安装非中文系统的服务器下可能会导致将汉字转换为乱码,请写两个替代的函数实现兼容Unicode文字的字符串大小写转换

面试遇到的题:

PHP的strtolower()和strtoupper()函数在安装非中文系统的服务器下可能会导致将汉字转换为乱码,请写两个自定义函数实现兼容带 Unicode 文字的字符串大小写转换代替 strtolower() 、 strtoupper();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
<?php

/**
ascii 码:A (65) Z(90) a(97) z(122)
a A 相差 32
*/
function user_mb_strtolower(string $str)
{
$strarr = str_split($str, 1);
$res = '';
foreach($strarr as $row){
$charascii = ord($row);
if($charascii >= 65 && $charascii < 97){
$charascii += 32;
}

$res .= chr($charascii);
}

return $res;
}

echo user_mb_strtolower("。你好");

function user_mb_strtoupper(string $str)
{
$strarr = str_split($str, 1);
$res = '';
foreach($strarr as $row){
$charascii = ord($row);
if($charascii >= 97 && $charascii < 123){
$charascii -= 32;
}

$res .= chr($charascii);
}

return $res;
}

echo user_mb_strtoupper("a你好");

php mbstring 库

  • mb_strtolower(字符串)
  • mb_strtoupper(字符串)
  • mb_convert_case(字符串,模式,字符集): 转换大、小写

php-fpm 默认连接数

pm 进程管理子进程方式:pm = dynamic

  • static:子进程的数量是固定的

  • dynamic(默认):子进程的数量在下面配置的基础上动态设置:pm.max_children,pm.start_servers,pm.min_spare_servers,pm.max_spare_servers

  • ondemand:进程在有需求时才产生,请求时才会启用子进程处理


pm.max_children (默认 5)

pm 设置为 static 时表示创建的子进程的数量,pm 设置为 dynamic 时表示最大可创建的子进程的数量。
  • 值的设置与内存、php-cgi 单个进程占用的空间大小有关,例如单个 php-cgi 进程占用 20M内存, 服务器总内存为1G,用一半内存分配给 php-cgi,计算公式:500m / 20m = 25个 php-cgi 进程

pm.start_servers (默认 2)

php-fpm 启动时创建的子进程数目,仅在 pm 设置为 dynamic 时使用。
  • 计算公式:pm.min_spare_servers + (pm.max_spare_servers - pm.min_spare_servers) / 2

pm.min_spare_servers 最小空闲进程数

设置空闲服务进程的最低数目,仅在 pm 设置为 dynamic 时使用
  • 默认值 1

  • 最大值 pm.max_children


pm.max_spare_servers 最大空间进程数

设置空闲服务进程的最大数目,仅在 pm 设置为 dynamic 时使用。必须设置。
  • 默认值 3

  • 最大值 pm.max_children


pm.max_requests 最大请求数

设置每个子进程重生之前服务的请求数。用来避免可能存在内存泄漏的第三方模块
  • 默认 0 ;表示 一直接受请求

mysql 外连接(左left join、右 right join)、内连接(inner join)、自连接(table1 t1 table1 t2)

内联(inner join):返回两表的集合
1
2
3
4
5
SELECT t1.name, t2.salary
FROM employee AS t1 INNER JOIN info AS t2 ON t1.name = t2.name;

SELECT t1.name, t2.salary
FROM employee t1 INNER JOIN info t2 ON t1.name = t2.name;
左外连接(left join):以左表为基准,如果 ON 或 USING 中的右表没有匹配的行,则将 LEFT JOIN 所有列设置为的行,右表则是 NULL
1
2
SELECT left_tbl.* FROM left_tbl LEFT JOIN right_tbl ON left_tbl.id = right_tbl.id
WHERE right_tbl.id IS NULL;
右外连接(right join):以右表为基准,如果 ON 或 USING 中的左表没有匹配的行,则将 right JOIN 所有列设置为的行,左表则是 NULL
1
2
SELECT left_tbl.* FROM left_tbl RIGHT JOIN right_tbl ON left_tbl.id = right_tbl.id
WHERE right_tbl.id IS NULL;

面试之PHP数组引用

  1. 赋值引用
    数组引用赋值给变量并不会将左边转换为引用,例:

  • 变量赋值
1
2
3
4
5
6
<?php
$a = 0;
$b = &$a;
$c = $b;
$c = 90;
echo $a . '------' . $b . PHP_EOL; //输出 $a =0 ; $b = 0; $c并不参与引用
  • 数组引用赋值给变量
1
2
3
4
5
6
7
8
9
10
11
12
<?php
$arr = [
'fi' => 1,
'ti' => 45
];

$b = &$arr['ti']; //保留数组内部元素引用
$c = $arr; //$c 不参与引用
$c['fi'] = 67; //不会改变 $arr元素值
$c['ti'] = 56; //$arr['ti'] 在上方有引用,故此处会改变 $arr['ti'] 值

var_export($arr); //$arr = ['fi' => 1, 'ti' => 56];
  1. foreach :每次循环中,当前单元的值被赋给 $value 并且数组内部的指针向前移一步
  • 当 foreach 开始执行时,数组内部的指针会自动指向第一个单元。这意味着不需要在 foreach 循环之前调用 reset()。
    由于 foreach 依赖内部数组指针,在循环中修改其值将可能导致意外的行为。

数组最后一个元素的 $value 引用在 foreach 循环之后仍会保留。建议使用 unset() 来将其销毁。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?php
//正例
$arr = [1, 2, 3, 4];
foreach ($arr as &$value) {
$value = $value * 2;
}
//[ 2, 4, 6, 8]
unset($value); // 最后取消掉引用

// 反例
$arr2 = [1, 3, 7];
$arr3 = [4, 6, 10, 12];
foreach($arr2 as &$row){}
foreach($arr3 as $row){}

var_export($arr2); //[1, 3, 12],没将 $row unset,一直处于引用赋值
var_export($arr3); //[4, 6, 10, 12]

使用 gitolite 搭建 git 服务管理工具

gitolite

gitolite是一款Perl语言开发的Git服务管理工具,通过公钥对用户进行认证。其允许通过存储库指定权限,还可以通过每个存储库中的分支或标记名称指定权限。也就是说,您可以指定某些人(或一组人)只能推送某些“refs”(分支或标签)而不能推送其他人
gitolite 源码地址


安装 gitolite

  1. 创建 gitolite(随意)用户
    1
    sudo adduser --system --group --shell /bin/bash --disabled-password gitolite
  2. 在 /home/gitolite(创建用户)/ 创建 .ssh 目录
    1
    sudo mkdir -p /home/gitolite/.ssh
  3. 生成公钥 ssh-keygen
    1
    2
    3
    ssh-keygen -t rsa -C "邮箱"
    sudo cp .ssh/id_rsa.pub /home/gitolite/.ssh/
    sudo chown -R gitolite:gitolite /home/gitolite/
  4. 源码安装
    1
    2
    3
    4
    5
    6
    7
    sudo su - gitolite
    git clone https://github.com/sitaramc/gitolite
    mkdir ~/bin && gitolite/install -to ~/bin
    exit //退出当前用户
    sudo su - gitolite
    gitolite setup -pk ~/.ssh/id_rsa.pub
    exit //退出当前用户
  5. 克隆 gitolite-admin
    如果公钥是在本地生成,则只能在本地克隆 gitolite-admin 仓库
    1
    git clone [email protected](本地地址):gitolite-admin && cd gitolite-admin
  6. gitolite-admin 目录下有两目录: conf(权限控制配置) 、keydir(放置公钥)

添加一个只有开发机有权限的 test 项目

  1. 将开发机的公钥添加到 gitolite-admin/keydir 目录

  2. 创建 test 项目且只有开发机有权限

    1
    2
    3
    4
    vim conf/gitolite.conf
    //在原有内容下方增加下面配置
    repo test
    RW+ = test

1
2
3
git add --all
git commit -m 'test'
git push

在开发机 clone test 项目

1
git clone [email protected]服务器:test.git

NPM 异常

执行 NPM 出现以下错误:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
internal/modules/cjs/loader.js:550
throw err;
^

Error: Cannot find module '../lib/utils/unsupported.js'
at Function.Module._resolveFilename (internal/modules/cjs/loader.js:548:15)
at Function.Module._load (internal/modules/cjs/loader.js:475:25)
at Module.require (internal/modules/cjs/loader.js:598:17)
at require (internal/modules/cjs/helpers.js:11:18)
at /usr/local/lib/node_modules/npm/bin/npm-cli.js:19:21
at Object.<anonymous> (/usr/local/lib/node_modules/npm/bin/npm-cli.js:92:3)
at Module._compile (internal/modules/cjs/loader.js:654:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:665:10)
at Module.load (internal/modules/cjs/loader.js:566:32)
at tryModuleLoad (internal/modules/cjs/loader.js:506:12)

解决:

1、卸载 NODE 
    brew uninstall --force node

2、删除 node_modules 目录:
    sudo rm -rf /usr/local/lib/node_modules/
    
3、安装 n node 版本管理
    brew install n
    
4、安装 node 版本
    n ls //查看 node 版本列表
    n <version>

Hello World

Welcome to Hexo! This is your very first post. Check documentation for more info. If you get any problems when using Hexo, you can find the answer in troubleshooting or you can ask me on GitHub.

Quick Start

Create a new post

1
$ hexo new "My New Post"

More info: Writing

Run server

1
$ hexo server

More info: Server

Generate static files

1
$ hexo generate

More info: Generating

Deploy to remote sites

1
$ hexo deploy

More info: Deployment