1 |
|
You can't specify target table for update in FROM clause
1 | 今天通过命令行想删除一些重复的数据结果执行命令的时候报错了: |
字符串朴素的模式匹配算法
1 | <?php |
PostMan工具之tests项设置
1,获取API返回参数:
1
var jsonData =JSON.parse(responseBody);//获取body中返回的所有参数
2,设置全局变量1
postman.setGlobalVariable("Auth",jsonData.data.authToken);//把返回参数中的keys设置为环境变量
4,获取全局变量1
postman.getGlobalVariable("Auth");
4,设置环境变量1
postman.setEnvironmentVariable("key", "value");
5,获取环境变量1
postman.getEnvironmentVariable("key");
6,获取URL请求的cookie,并且设置到环境变量里1
2
3
4pm.environment.set(
"XSRF-TOKEN",
decodeURIComponent(pm.cookies.get("XSRF-TOKEN"))
)
int(1)和int(10)的区别
我们知道char(10),varchar(10)这种都是指占用多少个字节,比如用char(10)存储‘1234567890ab’,会被截断成’1234567890’,因为超过了指定长度10。
但是整形跟char、varchar不同,整形分为tinyint,smallint,mediumint,bigint
类型 | 字节 | 有符号最小值 | 有符号最大值 | 无符号最小值 | 无符号最大值 |
---|---|---|---|---|---|
tinyint | 1 | -128 | 127 | 0 | 255 |
smallint | 2 | -32768 | 32767 | 0 | 65535 |
mediumint | 3 | -8388608 | 8388607 | 0 | 16777215 |
int | 4 | -2147483648 | 2147483647 | 0 | 16777215 |
bigint | 8 | -9223372036854775808 | 9223372036854775807 | 0 | 18446744073709551615 |
既然已经根据长度不同,内置了整形的不同类型,那么int(1)和int(11)有什么区别了?
$\color{red}{int(M)}$我们先来拆分,int是代表整型数据那么中间的M应该是代表多少位了,后来查mysql手册也得知了我的理解是正确的,下面我来举例说明。
MySQL 数据类型中的 integer types 有点奇怪。你可能会见到诸如:int(3)、int(4)、int(8) 之类的 int 数据类型。刚接触 MySQL 的时候,我还以为 int(3) 占用的存储空间比 int(4) 要小, int(4) 占用的存储空间比 int(8) 小。
后来,参看 MySQL 手册,发现自己理解错了。
int(M): M indicates the maximum display width for integer types.1
在 integer 数据类型中,M 表示最大显示宽度。
原来,在 int(M) 中,M 的值跟 int(M) 所占多少存储空间并无任何关系。 int(3)、int(4)、int(8) 在磁盘上都是占用 4 btyes 的存储空间。说白了,除了显示给用户的方式有点不同外,int(M) 跟 int 数据类型是相同的。
另外,int(M) 只有跟 zerofill 结合起来,才能使我们清楚的看到不同之处。
1 | mysql> drop table if exists t; |
从上面的测试可以看出,“(M)”指定了 int 型数值显示的宽度,如果字段数据类型是 int(4),则:当显示数值 10 时,在左边要补上 “00”;当显示数值 100 是,在左边要补上“0”;当显示数值 1000000 时,已经超过了指定宽度“(4)”,因此按原样输出。 在使用 MySQL 数据类型中的整数类型(tinyint、smallint、 mediumint、 int/integer、bigint)时,非特殊需求下,在数据类型后加个“(M)”,是没有任何意义的。
int(1)和int(11)在实际使用中,如果不使用 zerofill 是没有任何区别的,而且int型最大只能存储4294967295这个整数,我们可以发现其实只有10位。
综上所述,当我们需要用整形来存储一个字段类型的时候,应该尽量估算出该字段所需要的实际长度,比如tinyint可存储无符号最大值是255(1个字节长度,即2的8次方),smallint可存储无符号最大值是65535(2个字节长度,即2的16次方),mediumint可存储无符号最大值是16777215(3个字节长度,即2的24次方),而int型最大可存储4294967295(3个字节长度,即2的32次方)
C语言实现单向链表详解
一,单向链表的简单示意
1 | 头指针-》头节点-》节点-》节点-》NULL |
二,实现单向链表的重要几个步骤:1
2
3
4
5
6
7
8
9(1)创建节点,并且给当前节点数据结构配置定量的空间大小
malloc反回的是指向该内存地址的指针,其中node 就是我们说的头指针
ep : struct list *node = malloc(sizeof(struct list));
(2)清节点数据(由于结构体变量在未初始化的时候,数据是脏的)
ep : memset(node,0,sizeof(struct list));
(3)给节点初始化数据
ep : node->id = data ;
(4)将该节点的指针域设置为NULL。这里说明我创建了一个头结点,即同时运用了头指针和头结点。
ep : node->next = NULL ;
三,具体实现代码如下: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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct slist
{
int id ; //数据区域
struct slist *next ; //指针区域
}L; //定义的链表结构体从命名为 L
//创建一个节点
L *create_node(int data)
{
//给每个节点分配结构体一样的空间大小
//用malloc向计算机申请一块内存,
//并定义一个指向与头节点数据类型相同的指针则定义LinkList L;时,L为链表的头指针。
L *p = (L *)malloc(sizeof(L));
if(NULL == p)
{
printf("malloc error!\n");
return NULL ;
}
//由于结构体在未初始化的时候一样是脏数据,所以要清
memset(p,0,sizeof(L));
//初始化第一个节点
p->id = data ;
//将节点的后继指针设置为NULL
p->next = NULL ;
}
//链表的尾插 *pH 为链表的最后一个指针,*newData 要插入的指针数据
void tail_insert(L *pH, L *newData)
{
//获取当前的位置
L *p = pH ;
//如果当前位置的下一个节点不为空
while(NULL != p->next)
{
//移动到下一个节点
p = p->next ;
}
//如果跳出以上循环,所以已经到了NULL的这个位置
//此时直接把新插入的节点赋值给NULL这个位置
p->next = newData ;
}
//链表的头插
void top_insert(L *pH , L *newData)
{
L *p = pH ;
newData->next = p->next ;
p->next = newData ;
}
//链表的遍历
void Print_node(L *pH)
{
//获取当前的位置
L *p = pH ;
//获取第一个节点的位置
p = p->next ;
//如果当前位置的下一个节点不为空
while(NULL != p->next)
{
//(1)打印节点的数据
printf("id:%d\n",p->id);
//(2)移动到下一个节点,如果条件仍为真,则重复(1),再(2)
p = p->next ;
}
//如果当前位置的下一个节点为空,则打印数据
//说明只有一个节点
printf("id:%d\n",p->id);
}
//删除链表中的节点
int detele_list_node(L * pH , int data)
{
//获取当前头节点的位置
L *p = pH ;
L *prev = NULL;
while(NULL != p->next)
{
//保存当前节点的前一个节点的指针
prev = p ;
//然后让当前的指针继续往后移动
p = p->next ;
//判断,找到了要删除的数据
if(p->id == data)
{
//两种情况,一种是普通节点,还有一种是尾节点
if(p->next != NULL) //普通节点的情况
{
prev->next = p->next ;
free(p);
}
else //尾节点的情况
{
prev->next = NULL ; //将这个尾节点的上一个节点的指针域指向空
free(p);
}
return 0 ;
}
}
printf("没有要删除的节点\n");
return -1 ;
}
int main(int argc , char **argv)
{
//创建第一个节点
int i ;
L *header = create_node(0);
for(i = 1 ; i < 10 ; i++)
{
top_insert(header,create_node(i));
}
Print_node(header);
detele_list_node(header,5);
putchar('\n');
Print_node(header);
return 0 ;
}
//打印的结果:
/*
id:9
id:8
id:7
id:6
id:5
id:4
id:3
id:2
id:1
id:9
id:8
id:7
id:6
id:4
id:3
id:2
id:1
*/
参考:https://blog.csdn.net/morixinguan/article/details/68951912
结构之美:http://www.nowamagic.net/librarys/veda/detail/1805
PHP的后期静态绑定static
自 PHP 5.3.0 起,PHP 增加了一个叫做后期静态绑定的功能,用于在继承范围内引用静态调用的类。准确说,后期静态绑定工作原理是存储了在上一个“非转发调用”(non-forwarding call)的类名。
当进行静态方法调用时,该类名即为明确指定的那个(通常在 :: 运算符左侧部分);当进行非静态方法调用时,即为该对象所属的类。
所谓的“转发调用”(forwarding call)指的是通过以下几种方式进行的静态调用:self::,parent::,static:: 以及 forward_static_call()。可用 get_called_class() 函数来得到被调用的方法所在的类名,static:: 则指出了其范围。该功能从语言内部角度考虑被命名为“后期静态绑定”。
“后期绑定”的意思是说,static:: 不再被解析为定义当前方法所在的类,而是在实际运行时计算的。也可以称之为“静态绑定”,因为它可以用于(但不限于)静态方法的调用。
上面是PHP文档里对后期静态绑定的解释里面有几个重点:
1,后期静态绑定原理是存储了在上一个”非转发调用”的类名。
2,转发调用是通过self::,parent::,static:: 以及 forward_static_call()实现的
3,static::不再被解析为方法的当前类,而是通过实际运算计算出来的。
4,当进行静态方法调用时,该类名即为明确指定的那个 如(C::getName)类名就是C
5,;当进行非静态方法调用时,即为该对象所属的类 如($this->getName)类 这时候指的应该是$this所属的实例化对象。
转发调用 :
指的是通过以下几种方式进行的静态调用:self::,parent::,static:: 以及 forward_static_call()。
非转发调用 :
明确指定类名的静态调用(例如A::test())
非静态调用(例如$A->test())
场景一:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17class A {
public static function who() {
echo __CLASS__;
}
public static function test() {
static::who(); // 后期静态绑定从这里开始
}
}
class B extends A {
public static function who() {
echo __CLASS__;
}
}
B::test(); //B
分析:B::test时A类的test方法会通过 static::who 进修转发调用,这时候static::指向的是B类而不是A类
场景二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
33class A {
private function foo() {
echo "success!\n";
}
public function test() {
$this->foo();
static::foo();
}
}
class B extends A {
/* foo() will be copied to B, hence its scope will still be A and
* the call be successful */
}
class C extends A {
private function foo() {
/* original method is replaced; the scope of the new one is C */
}
}
$b = new B();
$b->test();
输出:
success!
success!
$c = new C();
$c->test(); //fails
输出:
success!
Fatal error: Call to private method C::foo() from context 'A' in /tmp/test.php on line 9
总结:在非静态环境下,所调用的类即为该对象实例所属的类。由于 $this-> 会在同一作用范围内尝试调用私有方法(即A类中的foo方法),而 static:: 则可能给出不同结果会转发调用(这时候会调用到C中的foo方法,由于它是私有的于是报错)。另一个区别是 static:: 只能用于静态属性。
场景三: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
28class A {
public static function foo() {
static::who();
}
public static function who() {
echo __CLASS__."\n";
}
}
class B extends A {
public static function test() {
A::foo();
parent::foo();
self::foo();
}
public static function who() {
echo __CLASS__."\n";
}
}
class C extends B {
public static function who() {
echo __CLASS__."\n";
}
}
C::test();//A C C
总结:后期静态绑定的解析会一直到取得一个完全解析了的静态调用为止。另一方面,如果静态调用使用 parent:: 或者 self:: 将转发调用信息,如上面场景三,他最终实际上转发给了C这个类。static关键字最终先会转发到他第一个调用的类(如这里的C),然后再一层层的往上找,假如这时候把C中的who方法注释,这时候结果就会变成(ABB)。
获取实例化对象的使用self和static的对比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<?php
class Base
{
private static $instance;
public $name;
public static function getInstance()
{
$class = get_called_class(); //动态获取调用类
if (!isset(self::$instance[$class]))
{
self::$instance[$class] = new self(); //获取的当前类即base类
}
return self::$instance[$class];
}
}
class A extends Base
{
public function who()
{
return __class__;
}
}
class B extends Base
{
public function who()
{
return __class__;
}
}
var_dump(A::getInstance()); //
// D:\www\my_project\test\a.php:34:
// object(Base)[1]
// public 'name' => null
var_dump(B::getInstance());
// D:\www\my_project\test\a.php:34:
// object(Base)[1]
// public 'name' => null
1 | <?php |
上面可以发现当我们使用self的时候永远获取的都是Base这个类,而使用static的时候就可以动态的获取调用对象了。
PSR-2编码规范在Phpstorm中的使用
目的:项目中使用PSR-2 的编码风格规范,来提升团队整体代码的可读性。
PhpStorm版本:2018.3
####让编辑器使用 PSR-2 标准
1,打开PhpStorm的设置页(File->Setting或者Ctrl+Alt+s),到Code Style页PHP中选择风格为 PSR1/2
2、到Code Sniffer页,路径是Setting->Languages and Frameworks->PHP->Quality Tools->Code Sniffer,设置phpcs的路径
3、到Inspections页,路径Setting->Editor->Inspections,右侧的 PHP,勾选下面的两个 PHP,选择使用 PSR2
4、效果这样设置完毕代码风格基本符合PSR-2的代码规范了,如果不符合编辑器会自动提示
####编辑器集成php-cs和php-cdf
######一、集成php-cdf
######二、集成php-cs
配置说明(直接可以用):
1 | Program是你的 PHP 根目录下的文件,windows 是.bat文件 |
三、插件配置好以后,到Keymap中设置快捷键
####四、使用效果
4.1 按刚刚设置的快捷键,这时候php-cs会检测你当前页的代码风格,有问题会输出来。
4.2 php-cdf修复结果。
大功告成~~~~
参考:https://qq52o.me/2460.html
windown连接上vpn后,内网不能访问的解决方案
最近连接上公司的vpn后,发现内网的服务都访问不了,当断开的时候缺又都可以访问了,后来发现当本机连接上vpn后,系统会走vpn的网关去寻址,这时候当然反问不了了,这是只需要在路由哪里配置一个寻址的网关即可:
如我本地的网关是红色表示那个:
假设我需要反问的内网地址段是:10.10.0.0
配置的命令:1
2route -p add 10.10.0.0 mask 255.255.0.0 192.168.254.100 metric 1
ok
查看路由表命令:route PRINT -41
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24===========================================================================
Interface List
12...........................Flipwires
11...88 d7 f6 7d 6f 8d ......Realtek PCIe GbE Family Controller
1...........................Software Loopback Interface 1
16...00 00 00 00 00 00 00 e0 Microsoft ISATAP Adapter #4
17...00 00 00 00 00 00 00 e0 Microsoft ISATAP Adapter #5
===========================================================================
IPv4 Route Table
===========================================================================
Active Routes:
Network Destination Netmask Gateway Interface Metric
0.0.0.0 0.0.0.0 192.168.254.100 192.168.112.100 286
0.0.0.0 0.0.0.0 On-link 172.31.185.182 16
10.10.0.0 255.255.0.0 192.168.254.100 192.168.112.100 31
===========================================================================
Persistent Routes:
Network Address Netmask Gateway Address Metric
0.0.0.0 0.0.0.0 192.168.254.100 Default
0.0.0.0 0.0.0.0 192.168.254.100 Default
10.10.0.0 255.255.0.0 192.168.254.100 1
===========================================================================
可以看到我们刚刚新增的那个路由关系
这段话的意思是:10.10.0.0这个网段的网络都通过192.168.254.100这网关去寻找,这命令是永久路由,重启电脑命令不会丢失
不出意外这个时候你就可以在连接上vpn的同时又可以访问内网啦啦啦。