BitMap算法

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
<?php
$redisHost = '127.0.0.1';
$redisPassWord = '';
$redisPort = 6379;


$redis = new \Redis();
$redis->connect($redisHost, $redisPort);
$redis->setOption(\Redis::OPT_READ_TIMEOUT, -1);
$redisPassWord && $redis->auth($redisPassWord);
$cacheKey = 'asdhasdhsjahdjahdjkahs';
$maxOffSet = 4294967296;
$redis->setBit($cacheKey, 7, 0);

// 高危。。。 如果值很小调用get 没有问题,如果值很大,则会出现没有反应的情况
$result = $redis->get($cacheKey);
$result = $redis->getbit($cacheKey, 13000);

$start = microtime(true);
sleep(1);

echo (microtime(true) - $start) . PHP_EOL;
$start = microtime(true);
$result = $redis->bitCount($cacheKey);
echo (microtime(true) - $start) . PHP_EOL;

rabbitMq

exchange

type 作用
fanout 绑定即 接收
direct 绑定并匹配符合时 接收
topic 绑定并模糊匹配符合时接收
headers 绑定并匹配headers规则时接收

exchange 和 exchange 是多对多的关系

exchange 和 queue 也是多对多的关系

树挪死,人挪活

mq 的具体使用还是看场景,从业务严格的程度来说 direct 和 headers 都是比较不错的交换机类型,尽管书本上说 headers 比 topic 慢,但是 headers 的扩展性和可读性在某些业务场景下比 topic 要好很多。

毕竟一天 8000 订单 ,按照一个订单的生命周期可以发送 create,pay,confirm,waitcheckin,checkin 这些事件,且每个单子都可以发出这些事件,一天不过 8000*5 = 40000。是一个比较可控的范围

用 headers 表示一个订单的 bookfrom 和 lodgeUnitType 是比较容易的

1
2
3
4
5
$headers = [
'actionType'=>'xxx',
'bookFrom'=>'xxxxx',
'lodgeUnit'=>'xxx',
];
如果用 topic 表示的话,就变得丑陋很多
1
2
<?php
$topoc = "actionType:{$actionType};bookFrom:{$bookFrom};lodgeUnitType:{$lodgeUnitType}";
并且规则的书写也不如 headers 来的直接,明确。

1

由于使用环境为 windows(虽然子系统安装了,但是是为了安装基于 python 的进程管理工具,并非使用 python 在 linux 下开发),所以很简单的啦~,这里略过 需要注意的是 pip 的使用

1
2
3
pip install NumPy 
pip install Pandas
pip install Matplotlib

迁移模块

1
2
pip freeze > requirement.txt
pip install -r requirement.txt

这个迁移方式不是很习惯

python闭包写法

1
2
3
4
5
6
7
8
9
10
def func()
return
def func1():
def func():
return 1
return func

func2 = func1()
print(func2)

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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
<?php

class Event
{
protected static $listens = array();

public static function listen($event, $callback, $once = false)
{
if (!is_callable($callback)) return false;
self::$listens[$event][] = array('callback' => $callback, 'once' => $once);
return true;
}

public static function one($event, $callback)
{
return self::listen($event, $callback, true);
}

public static function remove($event, $index = null)
{
if (is_null($index))
unset(self::$listens[$event]);
else
unset(self::$listens[$event][$index]);
}

public static function trigger()
{
if (!func_num_args()) return;
$args = func_get_args();
$event = array_shift($args);
if (!isset(self::$listens[$event])) return false;
foreach ((array)self::$listens[$event] as $index => $listen) {
$callback = $listen['callback'];
$listen['once'] && self::remove($event, $index);
call_user_func_array($callback, $args);
}
}
}


// 增加监听walk事件
Event::listen('walk', function () {
echo "I am walking...n";
});
// 增加监听walk一次性事件
Event::listen('walk', function () {
echo "I am listening...n";
}, true);
// 触发walk事件
Event::trigger('walk');
/*
I am walking...
I am listening...
*/
Event::trigger('walk');
/*
I am walking...
*/

Event::one('say', function ($name = '') {
echo "I am {$name}n";
});

Event::trigger('say', 'deeka'); // 输出 I am deeka
Event::trigger('say', 'deeka'); // not run

class Foo
{
public function bar()
{
echo "Foo::bar() is calledn";
}

public function test()
{
echo "Foo::foo() is called, agrs:" . json_encode(func_get_args()) . "n";
}
}

$foo = new Foo;

Event::listen('bar', array($foo, 'bar'));
Event::trigger('bar');

Event::listen('test', array($foo, 'test'));
Event::trigger('test', 1, 2, 3);

class Bar
{
public static function foo()
{
echo "Bar::foo() is calledn";
}
}

Event::listen('bar1', array('Bar', 'foo'));
Event::trigger('bar1');

Event::listen('bar2', 'Bar::foo');
Event::trigger('bar2');

function bar()
{
echo "bar() is calledn";
}

Event::listen('bar3', 'bar');
Event::trigger('bar3');

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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
<?php

class Container implements ArrayAccess
{
private $className = '';

private $s = array();

public function __construct($className)
{
if (!class_exists($className)) {
throw new Exception('class is not found');
}
$this->className = $className;
}

public function offsetExists($key)
{
echo "you're trying to check if something exist" . PHP_EOL;
return array_key_exists($key, $this->s);
}

public function offsetGet($key)
{
echo "you're trying to get something" . PHP_EOL;
return isset($this->s[$key]) ? $this->s[$key] : '';
}

public function offsetSet($key, $value)
{
echo "you're trying to set something" . PHP_EOL;
var_dump($value,$this->className);
if ($value instanceof $this->className) {
$this->s[$key] = $value;
} else {
throw new Exception('非法类型');
}
}

public function offsetUnset($key)
{
echo "you're trying to unset something" . PHP_EOL;
unset($this->s[$key]);
}
}


class cat
{
public $name = 'nihao';
}

$c = new Container(Cat::class);
$nihao = new Cat();



try {
$c['asda'] = $nihao;
$c['name'] = 'ben';
// echo $c['name'] . PHP_EOL;
// echo empty($c['age']) . PHP_EOL;
// unset($c['name']);
// echo empty($c['name']);
} catch (Exception $E) {
echo $E->getMessage();
echo $E->getLine();

}
var_dump($c);

function f(array $peole){

}

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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
<?php

abstract class Enum
{
protected $value;

protected static $enumList = [];

public function __construct($enum)
{
$enumClassName = get_called_class();
if (isset(self::$enumList[$enumClassName])) {
$enumList = self::$enumList[$enumClassName];
} else {
$objClass = new \ReflectionClass($enumClassName);
$enumList = $objClass->getConstants();
self::$enumList[$enumClassName] = $enumList;
}
if (!in_array($enum, $enumList, true)) {
throw new Exception('Error Type');
}
$this->value = $enum;
}

public function __set($name, $value)
{
if ($name === 'value') {
$enumClassName = get_called_class();
if (!in_array($value, self::$enumList[$enumClassName], true)) {
throw new Exception('Error Value');
}
$this->value = $value;
} else {
throw new Exception('Error Type');
}
}

public function __get($name)
{
if ($name === 'value') {
return $this->value;
} else {
throw new Exception('Error Type');
}
}

public function __invoke($enum)
{
$enumClassName = get_called_class();
if (!in_array($enum, self::$enumList[$enumClassName], true)) {
throw new Exception('Error Value');
}
$this->value = $enum;
}
}

class Day extends Enum
{
const MON = 'MON';
const TUE = 'TUE';
const WED = 'WED';
const THU = 'THU';
const FRI = 'FRI';
const SAT = 'SAT';
const SUN = 'SUN ';
}

$day = new Day(Day::FRI);


echo $day->value;

try{
$day->value = Day::MON;
} catch(Exception $e){
var_dump($e);
}


try{
$day->value = 'nihao';
} catch(Exception $e){
var_dump($e->getMessage());
}


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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
<?php

/**
* @author
* ioc
*/
class Container
{
protected $binds;

protected $instances;

public function bind($abstract, $concrete)
{
if ($concrete instanceof Closure) {
$this->binds[$abstract] = $concrete;
} else {
$this->instances[$abstract] = $concrete;
}
}

public function make($abstract, $parameters = [])
{
if (isset($this->instances[$abstract])) {
return $this->instances[$abstract];
}

array_unshift($parameters, $this);

return call_user_func_array($this->binds[$abstract], $parameters);
}
}

class Superman
{
protected $module;

public function __construct(SuperModuleInterface $module)
{
$this->module = $module;
}
}

class man
{
public $age;
public function __construct()
{
$this->age = 10;
}
}

interface SuperModuleInterface
{
/**
* 超能力激活方法
*
* 任何一个超能力都得有该方法,并拥有一个参数
*@param array $target 针对目标,可以是一个或多个,自己或他人
*/
public function activate(array $target);
}


/**
* X-超能量
*/
class XPower implements SuperModuleInterface
{
public function activate(array $target)
{
// 这只是个例子。。具体自行脑补
}
}

/**
* 终极炸弹 (就这么俗)
*/
class UltraBomb implements SuperModuleInterface
{
public function activate(array $target)
{
// 这只是个例子。。具体自行脑补
}
}

// 创建一个容器(后面称作超级工厂)
$container = new Container();

// 向该 超级工厂 添加 超人 的生产脚本
$container->bind('superman', function ($container, $moduleName) {
return new Superman($container->make($moduleName));
});

// 向该 超级工厂 添加 超能力模组 的生产脚本
$container->bind('xpower', function ($container) {
return new XPower;
});

// 同上
$container->bind('ultrabomb', function ($container) {
return new UltraBomb;
});

$container->bind('man', null);

var_dump($container);

// ****************** 华丽丽的分割线 **********************
// 开始启动生产
$superman_1 = $container->make('superman', ['xpower']);
$superman_2 = $container->make('superman', ['ultrabomb']);
$superman_3 = $container->make('superman', ['xpower']);
$superman_4 = $concrete->make('man');
// ...随意添加

var_dump($superman_1, $superman_2, $superman_3);

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?php
function add(...$ints)
{
return $func = function (...$int) use (&$func, &$ints) {
if (count($int) === 0) {
return array_sum($ints);
} else {
$ints = array_merge($int, $ints);
return $func;
}
};
}

$r = add(1, 2, 3)(4)(5)(1, 2, 3, 4, 5)();

echo '结果:' . $r;

wsl2 后可以配合docker desktop在本地环境快速搭建 redis/mongodb/mysql/nginx/php 等环境的部署。

docker

dockerhubformysql

1
docker search mysql

拉取 docker images

1
docker pull mysql:latest

查看本地镜像

1
docker images

docker-compose

docker-compose up -d

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
43
44
45
46
47
48
49
50
version: '3'
services: #表示这是一组服务
redis:
image: redis
container_name: redis
restart: always #docker服务重启后nginx的docker容器也重启
ports:
- "6379:6379" #映射的端口,redis容器的6379端口映射到本地的6379端口,可以通过ip:6379访问容器
networks:
db_local: #应用docker网络的名称
ipv4_address: 192.170.129.111 #分配的局域网ip
volumes:
# 挂载数据目录
- D:\WorkSpace\work-docker\docker-data\redis\data:/data
# links:
# - php # 连接php的docker容器 会在host文件生成 php 192.170.1.101(php 容器的局域网ip)
mysql:
image: mysql #应用的mysql的镜像名称
container_name: mysql #应用的mysql的镜像名称
restart: always #docker服务重启后nginx的docker容器也重启
ports:
- "3306:3306" #映射的端口,redis容器的6379端口映射到本地的6379端口,可以通过ip:6379访问容器
environment:
MYSQL_ROOT_PASSWORD: root_password # root用户的密码
MYSQL_USER: user # 创建新用户
MYSQL_PASSWORD: user_password # 新用户的密码
volumes:
# - D:\WorkSpace\work-docker\docker-data\mysql-conf:/etc/mysql #本地mysql映射到docker
- D:\WorkSpace\work-docker\docker-data\mysql\data:/var/lib/mysql #本地mysql映射到docker
networks:
db_local: #应用docker网络的名称
ipv4_address: 192.170.129.112 #分配的局域网ip
mongo:
image: mongo
container_name: mongo
restart: always #docker服务重启后nginx的docker容器也重启
ports:
- "27017:27017" #映射的端口,redis容器的6379端口映射到本地的6379端口,可以通过ip:6379访问容器
volumes:
# 挂载数据目录
- D:\WorkSpace\work-docker\docker-data\mongodb\db:/data/db
networks:
db_local: #应用docker网络的名称
ipv4_address: 192.170.129.113 #分配的局域网ip
networks:
db_local:
driver: bridge #网络类型
ipam:
config:
- subnet: 192.170.129.0/17 #区域网ip

关于php容器内在不关联 mysql 情况下连接mysql

可以将本机局域网ip让php容器内连接

Docker容器后台运行,就必须有一个前台进程。主线程结束,容器会退出。

直接运行docker命令,路径为work_dir

1
docker exec -it php-80  php -version

1
2
3
4
5
6
7
8
#匹配出所有的codecept_debug代码,包括已经注释掉的
(//)?codecept_debug\(.*\)(;)?
# 匹配单行sql
^select (.)*;$
# 阻止贪婪
^select \* (.|\n)*?;$
# 匹配单行换行
^\n$
0%