forked from zyb0408/zyb0408.github.io
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsearch.xml
525 lines (525 loc) · 391 KB
/
search.xml
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
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
<?xml version="1.0" encoding="utf-8"?>
<search>
<entry>
<title><![CDATA[C++模板]]></title>
<url>%2F2019-01-17-C%2B%2B%E6%A8%A1%E6%9D%BF.html</url>
<content type="text"><![CDATA[函数模板以前的重载,是函数名字相同,函数体不同,返回值类型不同,参数类型不同,参数个数不同,参数顺序不同。 函数模板是一个统一的函数,它可以适应一定范围内的不同类型的对象操作。函数模板将代表着不同类型的一组函数,他们都使用相同的代码。 定义12345template <参数化类型名列表>返回值类型 函数名(参数列表){ 函数体} 其中:template是定义模板的关键字, <参数化类型名列表>是模板参数列表,多个表项用逗号隔开。格式如下:1234class 标识符1,class 标识符2//这里的标识符1,标识符2是模板参数,class是修饰符,表示后面其后面的标识符是参数化的类型名,即模板参数。//例如template <class T1, class T2> 例子:12345678template <class T>void swap(T &a,T &b){ T t; t = a; a = b; b = t;} 函数模板与模板函数函数模板是模板函数的一个样板,它可以生成多个重载的模板函数,这些模板函数重用函数体代码。模板函数是函数模板的一个实例。 函数模板的实验例子:12345678910111213#include <iostream.h>template <class T>T max(T a, Tb){ return a>b?a:b;}void main(){ int n1 = 8, n2 = 9; double m1 = 3.14, m2 = 3.15; char c1 = 'm', m2 = 'n'; cout<<"max(n1,n2)="<<max(n1,n2)<<endl; cout<<"max(m1,m2)="<<max(m1,m2)<<endl; cout<<"max(c1,c2)="<<max(c1,c2)<<endl;} 执行结果为:123max(n1,n2)=9max(m1,m2)=3.15max(c1,c2)=n 说明:定义了一个函数模板,名字是max,有一个模板参数T。主函数中使用int,char,double代替了模板参数T。 冒泡排序(使用函数模板)12345678910111213141516171819#include <iostream.h>#include <string.h>template <class stype>void bubble(stype * item,int count);template <class stype>void bubble(stype *item,int count){ register i,j; stype t; for(i=1;i<count;i++) for(j=count-1;j>=i;j--){ if(item[j-1]>item[j]){ t = item[j-1]; item[j-1] = item[j]; item[j] = t; } }}]]></content>
<categories>
<category>C++</category>
</categories>
<tags>
<tag>C++模板</tag>
</tags>
</entry>
<entry>
<title><![CDATA[C++成员函数的特性之【内外联函数】]]></title>
<url>%2F2019-01-13-C%2B%2B%E6%88%90%E5%91%98%E5%87%BD%E6%95%B0%E7%9A%84%E7%89%B9%E6%80%A7.html</url>
<content type="text"><![CDATA[类的成员函数分为内联函数和外联函数。 内联函数指的是定义带类体内的成员函数,即函数体放在类体内。内联函数与带参数的宏定义比较,效率是一样的。 外联函数说明放在类体内,定义放在类体外的成员函数叫外联函数。外联函数的函数体在类的实现部分。外联函数编程内联函数的方法很简单,只要在函数头的前面加上关键字inline即可。 例子12345678910111213141516171819202122232425262728293031class A{ public: A(int x, int y){ X = x; Y = y; } int a(){ return X; } int b(){ return Y; } int c(); int d(); private: int X,Y;};inline int A::c(){ return a() + b();}inline int A::d(){ return c();}#include <iostream.h>void main(){ A m(3,5); int i = m.d(); cout<<"d() return: <<i<<endl;} 执行结果为:d() return: 8说明:类A中,直接定义了3个内联函数,又使用inline关键字定义了两个内联函数。内联函数一定要在调用之前进行定义,且不能递归调用。]]></content>
<categories>
<category>C++</category>
</categories>
<tags>
<tag>内联函数</tag>
<tag>外联函数</tag>
</tags>
</entry>
<entry>
<title><![CDATA[C++类与对象]]></title>
<url>%2F2019-01-12-C%2B%2B%E7%B1%BB%E4%B8%8E%E5%AF%B9%E8%B1%A1.html</url>
<content type="text"><![CDATA[类定义1234567class 类名{ private: //数据成员或者成员函数的声明 public: //成员函数或者数据成员的说明}; 例子:日期类的说明:123456789class TDate{ public: void SetDate(int y, int m, int d); int IsLeapYear(); void Print(); private: int year,month,day;}; 日期类的实现部分如下:1234567891011121314void TDate::SetDate(int y, int m, int d){ year = y; month = m; day = d;}int TDate::IsLeapYear(){ return (year%4 == 0 && year%100 != 0) || (year%400 == 0);}void TDate::Print(){ cout<<year<<"."<<month<<"."<<day<<endl;} 注意事项 类体中不允许对所定义的数据成员进行初始化 类中的数据成员的类型可以是任意的,包含int,float,char,数组,指针和引用等,也可以是对象。另一个类的对象可以作为该类的成员,但是自身类的对象是不可以的,而自身类的指针或者引用是可以的。当一个类的对象作为这个类的成员时,如果另一个类定义在后面,则需要提前说明,这种说明称为引用性说明。 1234567891011121314class N;class M{ public: ... private: N n;//n是N的对象};class N{ public: ... private: ...}; 一般在类体中先说明公有成员,这是用户所关心的;后说明私有成员。一般按照类型的大小从小到大说明,这样可以提高空间利用效率。 通常习惯将类定义的说明部分放到一个头文件中。 对象对象定义1类名 对象名的列表; 例子:1TDate data1, date2, *Pdate, date[10]; 对象成员的表示方法123456//一般对象的成员表示对象名.成员名对象名.成员名(参数列表)//指针对象的指针成员表示对象指针名->成员名对象指针名->成员名(参数列表) 例子:1234567date1.year,date1.monthdate1.SetDate(int y, int m,int d)//指针Pdate->year,Pdate->month(* Pdate).yearPdate->SetDate(y,m,d)(* Pdate).SetDate(y,m,d) 对象初始化与回收对象定义完了之后就是对象的初始化了。 初始化主要是通过类中的初始化函数完成的。这个初始化函数叫构造函数。 对象用完之后的回收用的是类定义中的反初始化函数,叫做析构函数。 构造函数特点 构造函数是成员函数,函数体可以写在类体内,也可以写在类体外 构造函数是一个特殊的成员函数,该函数的名字与类名相同,函数不指定返回值类型。它有返回值,该值由系统内部使用。该函数可以没有参数,也可以有参数。 构造函数可以重载,即可以定义多个参数个数不同的函数。 程序中一般不直接调用构造函数,在创建对象时系统自动调用构造函数。 析构函数的特点 析构函数是成员函数,函数体可以写在类体内,也可以写在类体外 也是一个特殊的成员函数,名字与类名相同,并在前面加一个~字符。用于与构造函数加以区别。不指定数据类型,并且没有参数 一个类中只能有一个析构函数 通常由系统自动调用。下面两种情况下,析构会自动调用 如果一个对象呗定义在一个函数体内,则当这个函数结束时,即该对象结束生存,系统调用析构释放该对象 如果一个对象是使用new运算符被动创建的,则在使用delete运算释放它时,delete将会调用析构 默认构造函数与默认析构函数没有参数的构造函数成为默认构造函数。 一种是系统默认的 一种是程序员自己定义的 创建对象时都要调用构造函数进行对象初始化。 复制构造函数复制构造函数是用一个已知的对象来创造另一个对象,而新对象与已知的对象的数据成员的值可以相同,也可以不同。复制构造函数除了具有之前讲过的带参构造函数的特性外,它只有一个参数,并且是对象引用。格式如下:1234类名::复制构造函数名(类名 &引用名){ 函数体}; 如果一个类中没有定义复制构造函数,系统会自动提供一个默认的复制构造函数,作为该类的公有成员,用来根据已知对象创建与其相同的新对象。以下3中情况会调用复制构造函数来由一个对象初始化另一个对象。 1.明确表示由一个对象初始化另一个对象时 2.当对象作为函数实参传递给函数形参时 3.当一个自动存储类对象作为函数返回时123456//1.TPoint P2(P1);//2.P=f(N);//3.return R;]]></content>
<categories>
<category>C++</category>
</categories>
<tags>
<tag>C++</tag>
</tags>
</entry>
<entry>
<title><![CDATA[Linux学习]]></title>
<url>%2F2019-01-11-Linux%E5%AD%A6%E4%B9%A0.html</url>
<content type="text"><![CDATA[经过以往的学习,现在对Linux的学习进行一次总结。记录一下自己在Linux使用的感悟。 by Marvin.Zhao 我的Linux哲学Linux有自己的一套的哲学理论,我在学习Linux的过程中也被Linux的设计哲学所惊艳到。 我的Linux学习哲学是: 我是谁?第一个对应的是英文中的WHO。在Linux系统中,我们首先要做的就是确认自己的角色。确认角色的主要目的就是为了明确自己的权限。我是普通用户还是管理员,这是非常重要的。我所在的组是什么,我能进行哪些操作,都是跟角色有关的。 角色就涉及到权限,权限约束这用户能够对哪些文件进行操作,能够使用哪些命令。 主要分辨出两点: 普通用户 管理员用户 这是需要十分明确的。使用如下命令: 1whoami 是的,你没有看错。就是这样一条命令,系统就能告诉你,你是谁。当然除了这条命令之外还可以使用其他命令查看有哪些用户(在什么时间)登陆了该系统。 123456789101112131415161718#下面的命令是查看有哪些用户登陆了该系统users#示例输出:[hexo@dhu021 ~]$ usershexo root#下面的命令列出登陆该系统所有用户的登陆时间等who#示例输出:[hexo@dhu021 ~]$ whoroot pts/0 2018-07-30 14:31 (202.121.144.19)hexo pts/1 2018-07-30 14:33 (202.121.144.19)#下面的命令查看自己的用户ID,组ID,以及所处的组id#示例输出:[hexo@dhu021 ~]$ iduid=1000(hexo) gid=1000(hexo) groups=1000(hexo) 经过上面的操作,你就明白自己是什么角色了。其中id,这个命令的结果如果大于1000,那么就是普通用户。如果小于1000,可能是系统用户或者管理员或者普通用户。 小补充这里补充一下系统用户的知识。什么是系统用户? 在Linux系统的/etc/passwd文件中按照行存储了一些用户以及其他的信息。 12345678[hexo@dhu021 ~]$ cat /etc/passwdroot:x:0:0:root:/root:/bin/bashbin:x:1:1:bin:/bin:/sbin/nologindaemon:x:2:2:daemon:/sbin:/sbin/nologinadm:x:3:4:adm:/var/adm:/sbin/nologin····(部分省略)hexo:x:1000:1000::/home/hexo:/bin/bashnginx:x:997:995:Nginx web server:/var/lib/nginx:/sbin/nologin 可以看到每一行都是按照冒号分隔了7个字段。这些字段代表了不同的意思。 字段 含义 1 用户名 2 用户的密码原来直接存储在第二字段,但是为了安全,最后专门有了/etc/shadow文件,现在默认用x替代 3 用户的uid,一般情况下root为0,1-499默认为系统账号,有的更大些到1000,500-65535为用户的可登录账号,有的系统从1000开始。 4 用户的gid,linux的用户都会有两个ID,一个是用户uid,一个是用户组id,在我们登录的时候,输入用户名和密码,其实会先到/etc/passwd查看是否有你输入的账号或者用户名,有的话将该账号与对应的UID和GID(在/etc/group中)读出来。然后读出主文件夹与shell的设置,然后再去检验密码是否正确,正确的话正常登录。 5 用户的账号说明解释 6 用户的家目录文件夹 7 用户使用的shell,如果换成/sbin/nologin/就是默认没有登录环境的。 情况就是这样。这里3、4字段的含义就指出了哪些是系统用户了,哪些是普通用户。 我在哪儿?第二需要明确的是WHERE。就是要知道自己所处的位置。Linux系统那么多目录,一条命令: 1234pwd#示例输出[hexo@dhu021 ~]$ pwd/home/hexo 找到自己所处的位置,不会迷路。自己也能做到心中有数。 我要干什么?第三步,就是抛开一切的想法。脑子里只要高速自己,我在XXX目录下,我要干嘛。我的任务(TASK)是要复制一个文件还是重命名一个文件还是编辑一个文件等等。这一步讲的就是不要在Linux中迷失自我,要做到目标明确,不要做无头苍蝇。 我要怎么干?最后一步也是通常人们常要做的。就是,我该怎么做才能达到在第三步提出的问题。我要怎么干?这就是涉及到Linux的哲学问题了。化大为小,化繁为简,分而治之。将一个大问题化简成多个小问题,把一个繁杂的问题分解成许多个简单问题。这样就可以理清楚自己需要怎么做了。 命令集合这里我都不想写了。很多常用的我就步介绍了。这里会更新一些不常用的,而且很有用的命令。 scp mount ln 后记在学习Linux的过程中,我们每次打开命令行只要要反问自己前三个问题,尤其是强两个问题,必须要明确。]]></content>
<categories>
<category>Linux</category>
</categories>
<tags>
<tag>Linux</tag>
</tags>
</entry>
<entry>
<title><![CDATA[线性表]]></title>
<url>%2F2019-01-10-%E7%BA%BF%E6%80%A7%E8%A1%A8.html</url>
<content type="text"><![CDATA[头结点线性链表的结点类型定义1234typedef struct Lnode{ ElemType data; Struct Lnode *next;}Lnode *linklist; 说明:LNode:结构类型名;LNode:类型结构变量有两个域:data:存放线性表的数据元素,next:存放元素直接后继结点的地址;该类型结构变量用于表示线性链表中的一个结点;LNODE *p;:p为指向结点(结构)的指针变量;p是LNODE类型的指针变量 建表头插法建立单链表L123456789101112131415Linklist CreateFromHead(){ L = (Linklist)malloc(sizeof(LNode)); L->next = NULL; while(flag){ c = getchar(); if(c!='$'){ s = (LNode*)malloc(sizeof(LNode)); s->data = c; s->next = L->next; L->next = s; }else flag = 0; } return L;} 插入插入的主要内容如下:1234q=(LNode*)malloc(sizeof(LNode));q->data = 'a';q->next = p->next;p->next = q; 删除123q = p->next;p->next = q->next;free(q); 插入、删除算法中的循环条件为何不同?删除算法中的循环条件(p->next! =NULL && k<i-1)与前面插入算法中的循环条件(p! =NULL && k<i-1)不同,因为前面插入算法时的插入位置有m+1个(m为当前单链表中数据元素的个数)。i=m+1是指在第m+1个位置前插入,即在单链表的末尾插入。而删除操作中删除的合法位只有m个,若使用与前面插入操作相同的循环条件,则会出现指针指空的情况, 使删除操作失败。 循环链表的定义将线性链表的最后一个结点的指针指向链表的第一个结点(是一个首尾相连的单链表)循环链表与线性链表操作的主要差别?循环链表与线性链表操作的主要差别是算法中循环结束的条件不是p或p->next是否为NULL,而是它们是否等于头指针;双向链表的定义双向链表中,每个结点有两个指针域,一个指向直接后继元素结点,另一个指向直接前趋元素结点。1234typedef struct DNode{ ElemType data; struct DNode *prior,*next; }DNode,*DoubleList;]]></content>
<categories>
<category>线性表</category>
</categories>
<tags>
<tag>线性表</tag>
</tags>
</entry>
<entry>
<title><![CDATA[电脑开启虚拟化支持]]></title>
<url>%2F2019-01-10-%E7%94%B5%E8%84%91%E5%BC%80%E5%90%AF%E8%99%9A%E6%8B%9F%E5%8C%96%E6%94%AF%E6%8C%81.html</url>
<content type="text"><![CDATA[参考:http://virtual.51cto.com/art/201412/460343.htmhttp://www.udaxia.com/upqd/5254.htmlhttp://jingyan.baidu.com/article/335530daa55d7e19cb41c3c2.html 虚拟化技术目前主要依赖于您电脑的CPU型号及BIOS,某些CPU或者BIOS暂时还不能支持虚拟化技术。支持虚拟化技术的可以在BIOS中开启 开启方法如下: 1、进入BIOS。开机时按F2或F12或DEL或ESC等键(各电脑有所不同)。 2、进入BIOS后,找到Configuration选项, 选择Intel Virtual Technology并回车, 将光标移至Enabled, 然后再回车, 最后按F10保存并退出。 如果找不到Configuration选项,可以试试下面的方法: (1)某些HP(惠普)电脑进入BIOS后,需要选择SystemConfiguration(系统配置)菜单, 然后选择Device Configuration(设备配置), 找到Virtualization Technology, 设置为Enabled。 (2)某些联想Thinkpad电脑进入BIOS后,需要选择Security菜单, 然后选择Virtualization, 设置为Enabled。 (3)某些DELL(戴尔)电脑进入BIOS后,需要选择Processor Settings菜单, 然后选择VirtualizationTechnology, 设置为Enabled。]]></content>
<categories>
<category>Linux 虚拟化</category>
</categories>
<tags>
<tag>Linux 虚拟化</tag>
</tags>
</entry>
<entry>
<title><![CDATA[Linux下安装Oracle]]></title>
<url>%2F2019-01-09-Linux%E4%B8%8B%E5%AE%89%E8%A3%85Oracle.html</url>
<content type="text"><![CDATA[Oracle install12345678910111213141516171819202122232425262728293031323334353637383940414243444546groupadd -g 6000 asmadmingroupadd -g 6001 asmdbagroupadd -g 6002 asmopergroupadd -g 8000 oinstallgroupadd -g 8001 dbagroupadd -g 8002 operyum install unzip -yyum install -y xdpyinfoyum install -y vimuseradd -u 8000 -g oinstall -G dba,asmdba odsz11gmkdir /data/palogcd /data/palogcat > /etc/sysctl.conf <<EOFnet.ipv4.ip_forward = 0fs.aio-max-nr = 1048576fs.file-max = 6815744net.ipv4.conf.default.rp_filter = 1net.ipv4.conf.default.accept_source_route = 0net.core.rmem_default = 262144net.core.rmem_max = 4194304net.core.wmem_default = 262144net.core.wmem_max = 1048576kernel.sysrq = 1kernel.core_uses_pid = 1net.ipv4.tcp_syncookies = 1net.ipv4.ip_local_port_range = 9000 65500kernel.msgmnb = 65536kernel.msgmax = 65536kernel.shmmax = 68719476736kernel.shmall = 4294967296EOFcat >> /etc/security/limits.conf << EOFodsz11g soft nproc 2047odsz11g hard nproc 16384odsz11g soft nofile 1024odsz11g hard nofile 65536odsz11g hard stack 10240EOF /sbin/sysctl -pprintf "Paic1234\nPaic1234" | passwd odsz11g 切换到odsz11g12345678910111213su - odsz11gcd /data/palogwget http://10.25.27.90/medias/oracle/p13390677_112040_Linux-x86-64_1of7.zipwget http://10.25.27.90/medias/oracle/p13390677_112040_Linux-x86-64_2of7.zipmkdir -p s01/oraclechown -R odsz11g:oinstall s01mkdir -p u01/oraInventorychown -R odsz11g:oinstall u01chown -R odsz11g:oinstall /data/unzip p13390677_112040_Linux-x86-64_1of7.zipunzip p13390677_112040_Linux-x86-64_2of7.ziprm -rf *.zip 切换到root12345678910yum install compat-*rpm -ivh libnet-1.1.2.1-2.2.el4.rf.i386.rpmrpm -ivh libstdc++-3.4.6-11.i386.rpmrpm -ivh pdksh-5.2.14-1.i386.rpmrpm -ivh libaio-0.3.105-2.i386.rpmrpm -ivh libaio-devel-0.3.105-2.i386.rpm rpm -ivh libgcc-3.4.6-3.1.i386.rpm rpm -ivh unixODBC-2.2.11-7.1.i386.rpm#rpm -ivh unixODBC-devel-2.2.11-7.1.x86_64.rpm 切换到odsz11g配置oracle安装用户(odsz11g)的环境变量12345678910111213141516su - odsz11gcp .bash_profile .bash_profile.bakcat >> .bash_profile << EOF PATH=$PATH:$HOME/binexport PATHexport ORACLE_BASE=/data/palog/s01/oracleexport ORACLE_HOME=/product/11.2.0/dbhome_1export LD_LIBRARY_PATH=$ORACLE_HOME/lib:/usr/lib/lib:/lib32export ORACLE_SID=orcl#这里的IP改成你电脑的IPexport DISPLAY=192.168.1.100:0.0export PATH=/bin:/OPatch:/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin:/home/odsz11g/bin:/home/odsz11g/binexport LANG=en_US.UTF-8EOF 使用oracle配置文件1. .bash_profile 使用xpassive1DISPLAY=192.168.0.100:0.0]]></content>
<categories>
<category>SQL</category>
<category>Oracle</category>
</categories>
<tags>
<tag>SQL</tag>
</tags>
</entry>
<entry>
<title><![CDATA[数据库系统]]></title>
<url>%2F2019-01-09-%E6%95%B0%E6%8D%AE%E5%BA%93%E7%B3%BB%E7%BB%9F.html</url>
<content type="text"><![CDATA[数据是数据库管理系统管理的对象。元数据是有关数据结构的信息–描述数据的数据。在关系型数据库管理系统中,数据是用户填加到表中的数据值,元数据是描述有关表的表名、列名、数据类型等数据库对象的数据。 连接管理查询、更新和模式修改: 对数据库管理系统的输入操作 查询、更新: 普通的查询界面( ORACLE 用SQL*PLUS执行各种查询语句) 。 应用程序界面。 模式修改 是对元数据的修改。操作有严格的限制,只有经过授权的人或DBA才能执行模式修改。查询处理器负责处理查询、修改和模式修改请求。查询处理器 编译器负责对查询或修改语句进行优化并且转换成可以执行的底层命令。 解释器负责编译或解释模式修改,并且把它记录在数据字典中。 预编译器把嵌入在宿主语言中的语句处理成规范的过程调用。 查询优化是查询处理器的关键,查询处理器主要的任务是找到查询语句的查询规划,既最优的一系列执行查询语句的步骤。 存储管理器是根据获得的请求信息,从数据存储中获得信息或修改数据存储中的信息。 存储管理器由两个组件组成: 文件管理器负责磁盘空间的合理分配,管理物理文件的存储结构和存取方式。 缓冲区管理器负责内存的管理。它通过文件管理器从磁盘上获取数据块,并且在内存中选择用于存储这些数据块的内存位置。 事务管理器负责系统的一致性和并发操作的正确执行。 事务管理器与查询处理器互相影响: 事务管理器必须知道当前语句所操作的数据以避免操作之间产生冲突。事务管理器与存储管理器互相影响: 以便写日志,保护数据。 事务具有的基本属性? 事务管理器具有ACID属性 A原子性(Atomicity):事务的执行,要么全部完成,要么全部不完成C一致性(Consistency):无论系统处于何种状态,都能保证数据库中的数据处于一致状态。I独立性(Isolation):两个或多个事务可以同时运行而不互相影响。D持久性(Durability):事务完成之后,这些工作的结果会永远保存。 权限和完整性管理器:检查用户访问的合法性和测试完整性约束。DBMS功能: 定义功能:定义三级模式结构(?)、 完整性(?) 、安全性(?)操纵功能:查询、插入、删除、修改控制功能:并发控制、安全性控制、完整性约束的控制维护功能:数据装入、 转储、 DB恢复、性 能监控、 DB重组与重构 定义三级模式结构:外模式、 模式和内模式 完整性:实体完整性约束、参照完整性约束 、用户定义的完整性约束。安全性:防止非法用户入侵数据库系统保正系统DOWNTIME时、存储介质 坏时、用户误操作时数据库系统的信息不致于丢失.]]></content>
<categories>
<category>SQL</category>
</categories>
<tags>
<tag>数据库 SQL</tag>
</tags>
</entry>
<entry>
<title><![CDATA[Hello World]]></title>
<url>%2F2019-01-09-hello-world.html</url>
<content type="text"><![CDATA[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 StartCreate a new post1$ hexo new "My New Post" More info: Writing Run server1$ hexo server More info: Server Generate static files1$ hexo generate More info: Generating Deploy to remote sites1$ hexo deploy More info: Deployment]]></content>
</entry>
<entry>
<title><![CDATA[Hexo使用说明]]></title>
<url>%2F2019-01-08-Hexo%E4%BD%BF%E7%94%A8%E8%AF%B4%E6%98%8E.html</url>
<content type="text"><![CDATA[第一步1hexo n "文章名字" 第二步找到文件目录,默认是在F:\githubprojects\zyb0408.github.io\blog\source\_posts下。 第三步打开文件,编辑内容,需要添加的内容有:tags,categories。然后编辑内容。 第四步1hexo g -d 将修改后的内容推送到github上。 完毕。 附录:hexo配置文件123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384#文件名:blog\_config.yml# Hexo Configuration## Docs: https://hexo.io/docs/configuration.html## Source: https://github.com/hexojs/hexo/# Sitetitle: 小蜜蜂subtitle: Don't Hack Medescription: 小蜜蜂学计算机keywords: TensorFlow OpenCVauthor: 小蜜蜂language: zh-Hanstimezone:# URL## If your site is put in a subdirectory, set url as 'http://yoursite.com/child' and root as '/child/'url: https://zyb0408.github.ioroot: /permalink: :year/:month/:day/:title/permalink_defaults:# Directorysource_dir: sourcepublic_dir: publictag_dir: tagsarchive_dir: archivescategory_dir: categoriescode_dir: downloads/codei18n_dir: :langskip_render:# Writingnew_post_name: :title.md # File name of new postsdefault_layout: posttitlecase: false # Transform title into titlecaseexternal_link: true # Open external links in new tabfilename_case: 0render_drafts: falsepost_asset_folder: falserelative_link: falsefuture: truehighlight: enable: true line_number: true auto_detect: true tab_replace: # Home page setting# path: Root path for your blogs index page. (default = '')# per_page: Posts displayed per page. (0 = disable pagination)# order_by: Posts order. (Order by date descending by default)index_generator: path: '' per_page: 5 order_by: -date # Category & Tagdefault_category: uncategorizedcategory_map:tag_map:# Date / Time format## Hexo uses Moment.js to parse and display date## You can customize the date format as defined in## http://momentjs.com/docs/#/displaying/format/date_format: YYYY-MM-DDtime_format: HH:mm:ss# Pagination## Set per_page to 0 to disable paginationper_page: 5pagination_dir: page# Extensions## Plugins: https://hexo.io/plugins/## Themes: https://hexo.io/themes/#theme: landscapetheme: next# Deployment## Docs: https://hexo.io/docs/deployment.htmldeploy: type: git repository: [email protected]:zyb0408/zyb0408.github.io.git 主题Next配置文件123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818#文件名:blog\themes\next\_config.yml# ===============================================================# ========================= ATTENTION! ==========================# ===============================================================# NexT repository is moving here: https://github.com/theme-next# ===============================================================# It's rebase to v6.0.0 and future maintenance will resume there# ===============================================================# ---------------------------------------------------------------# Theme Core Configuration Settings# ---------------------------------------------------------------# Set to true, if you want to fully override the default configuration.# Useful if you don't want to inherit the theme _config.yml configurations.override: false# ---------------------------------------------------------------# Site Information Settings# ---------------------------------------------------------------# To get or check favicons visit: https://realfavicongenerator.net# Put your favicons into `hexo-site/source/` (recommend) or `hexo-site/themes/next/source/images/` directory.# Default NexT favicons placed in `hexo-site/themes/next/source/images/` directory.# And if you want to place your icons in `hexo-site/source/` root directory, you must remove `/images` prefix from pathes.# For example, you put your favicons into `hexo-site/source/images` directory.# Then need to rename & redefine they on any other names, otherwise icons from Next will rewrite your custom icons in Hexo.favicon: #small: /images/favicon-32x32-next.png medium: /images/favicon-32x32-next.png #apple_touch_icon: /images/apple-touch-icon-next.png #safari_pinned_tab: /images/logo.svg #android_manifest: /images/manifest.json #ms_browserconfig: /images/browserconfig.xml# Set default keywords (Use a comma to separate)keywords: "Computer Siencise, OpenCV, TensorFlow"# Set rss to false to disable feed link.# Leave rss as empty to use site's feed link.# Set rss to specific value if you have burned your feed already.rss:footer: # Specify the date when the site was setup. # If not defined, current year will be used. since: 2017 # Icon between year and copyright info. icon: user # If not defined, will be used `author` from Hexo main config. copyright: # ------------------------------------------------------------- # Hexo link (Powered by Hexo). powered: false theme: # Theme & scheme info link (Theme - NexT.scheme). enable: false # Version info of NexT after scheme info (vX.X.X). version: false # ------------------------------------------------------------- # Any custom text can be defined here. #custom_text: Hosted by <a target="_blank" href="https://pages.github.com">GitHub Pages</a># ---------------------------------------------------------------# SEO Settings# ---------------------------------------------------------------# Canonical, set a canonical link tag in your hexo, you could use it for your SEO of blog.# See: https://support.google.com/webmasters/answer/139066# Tips: Before you open this tag, remember set up your URL in hexo _config.yml ( ex. url: http://yourdomain.com )canonical: true# Change headers hierarchy on site-subtitle (will be main site description) and on all post/pages titles for better SEO-optimization.seo: false# If true, will add site-subtitle to index page, added in main hexo config.# subtitle: Subtitleindex_with_subtitle: false# ---------------------------------------------------------------# Menu Settings# ---------------------------------------------------------------# When running the site in a subdirectory (e.g. domain.tld/blog), remove the leading slash from link value (/archives -> archives).# Usage: `Key: /link/ || icon`# Key is the name of menu item. If translate for this menu will find in languages - this translate will be loaded; if not - Key name will be used. Key is case-senstive.# Value before `||` delimeter is the target link.# Value after `||` delimeter is the name of FontAwesome icon. If icon (with or without delimeter) is not specified, question icon will be loaded.menu: home: / || home about: /about/ || user tags: /tags/ || tags categories: /categories/ || th archives: /archives/ || archive #schedule: /schedule/ || calendar #sitemap: /sitemap.xml || sitemap #commonweal: /404/ || heartbeat #search: /search# Enable/Disable menu icons.menu_icons: enable: true# ---------------------------------------------------------------# Scheme Settings# ---------------------------------------------------------------# Schemes#scheme: Muse#scheme: Mistscheme: Pisces#scheme: Gemini# ---------------------------------------------------------------# Sidebar Settings# ---------------------------------------------------------------# Social Links.# Usage: `Key: permalink || icon`# Key is the link label showing to end users.# Value before `||` delimeter is the target permalink.# Value after `||` delimeter is the name of FontAwesome icon. If icon (with or without delimeter) is not specified, globe icon will be loaded.#social: #GitHub: https://github.com/yourname || github #E-Mail: mailto:[email protected] || envelope #Google: https://plus.google.com/yourname || google #Twitter: https://twitter.com/yourname || twitter #FB Page: https://www.facebook.com/yourname || facebook #VK Group: https://vk.com/yourname || vk #StackOverflow: https://stackoverflow.com/yourname || stack-overflow #YouTube: https://youtube.com/yourname || youtube #Instagram: https://instagram.com/yourname || instagram #Skype: skype:yourname?call|chat || skypesocial_icons: enable: false icons_only: false transition: false# Blog rollslinks_icon: linklinks_title: Linkslinks_layout: block#links_layout: inline#links: #Title: http://example.com/# Sidebar Avatar# in theme directory(source/images): /images/avatar.gif# in site directory(source/uploads): /uploads/avatar.gif#avatar: /images/avatar.gifavatar: /images/favicon-32x32-next.png# Table Of Contents in the Sidebartoc: enable: true # Automatically add list number to toc. number: true # If true, all words will placed on next lines if header width longer then sidebar width. wrap: true# Creative Commons 4.0 International License.# http://creativecommons.org/# Available: by | by-nc | by-nc-nd | by-nc-sa | by-nd | by-sa | zero#creative_commons: by-nc-sa#creative_commons:sidebar: # Sidebar Position, available value: left | right (only for Pisces | Gemini). position: left #position: right # Sidebar Display, available value (only for Muse | Mist): # - post expand on posts automatically. Default. # - always expand for all pages automatically # - hide expand only when click on the sidebar toggle icon. # - remove Totally remove sidebar including sidebar toggle. display: post #display: always #display: hide #display: remove # Sidebar offset from top menubar in pixels (only for Pisces | Gemini). offset: 12 # Back to top in sidebar (only for Pisces | Gemini). b2t: false # Scroll percent label in b2t button. scrollpercent: true # Enable sidebar on narrow view (only for Muse | Mist). onmobile: false# ---------------------------------------------------------------# Post Settings# ---------------------------------------------------------------# Automatically scroll page to section which is under <!-- more --> mark.scroll_to_more: true# Automatically saving scroll position on each post/page in cookies.save_scroll: true# Automatically excerpt description in homepage as preamble text.excerpt_description: true# Automatically Excerpt. Not recommend.# Please use <!-- more --> in the post to control excerpt accurately.auto_excerpt: enable: true length: 150# Post meta display settingspost_meta: item_text: true created_at: true updated_at: true categories: true# Post wordcount display settings# Dependencies: https://github.com/willin/hexo-wordcountpost_wordcount: item_text: true wordcount: true min2read: true totalcount: true separated_meta: false# Wechat Subscriber#wechat_subscriber: #enabled: true #qcode: /path/to/your/wechatqcode ex. /uploads/wechat-qcode.jpg #description: ex. subscribe to my blog by scanning my public wechat account# Reward#reward_comment: Donate comment here#wechatpay: /images/wechatpay.jpg#alipay: /images/alipay.jpg#bitcoin: /images/bitcoin.png# Declare license on postspost_copyright: enable: true license: CC BY-NC-SA 3.0 license_url: https://creativecommons.org/licenses/by-nc-sa/3.0/# ---------------------------------------------------------------# Misc Theme Settings# ---------------------------------------------------------------# Reduce padding / margin indents on devices with narrow width.mobile_layout_economy: false# Android Chrome header panel color ($black-deep).android_chrome_color: "#222"# Custom Logo.# !!Only available for Default Scheme currently.# Options:# enabled: [true/false] - Replace with specific image# image: url-of-image - Images's urlcustom_logo: enabled: true image: /images/favicon-32x32-next.png# Code Highlight theme# Available value:# normal | night | night eighties | night blue | night bright# https://github.com/chriskempson/tomorrow-themehighlight_theme: night# ---------------------------------------------------------------# Font Settings# - Find fonts on Google Fonts (https://www.google.com/fonts)# - All fonts set here will have the following styles:# light, light italic, normal, normal italic, bold, bold italic# - Be aware that setting too much fonts will cause site running slowly# - Introduce in 5.0.1# ---------------------------------------------------------------# CAUTION! Safari Version 10.1.2 bug: https://github.com/iissnan/hexo-theme-next/issues/1844# To avoid space between header and sidebar in Pisces / Gemini themes recommended to use Web Safe fonts for `global` (and `logo`):# Arial | Tahoma | Helvetica | Times New Roman | Courier New | Verdana | Georgia | Palatino | Garamond | Comic Sans MS | Trebuchet MS# ---------------------------------------------------------------font: enable: false # Uri of fonts host. E.g. //fonts.googleapis.com (Default). host: # Font options: # `external: true` will load this font family from `host` above. # `family: Times New Roman`. Without any quotes. # `size: xx`. Use `px` as unit. # Global font settings used on <body> element. global: external: true family: Lato size: # Font settings for Headlines (h1, h2, h3, h4, h5, h6). # Fallback to `global` font settings. headings: external: true family: size: # Font settings for posts. # Fallback to `global` font settings. posts: external: true family: # Font settings for Logo. # Fallback to `global` font settings. logo: external: true family: size: # Font settings for <code> and code blocks. codes: external: true family: size:# ---------------------------------------------------------------# Third Party Services Settings# ---------------------------------------------------------------# MathJax Supportmathjax: enable: true per_page: true cdn: //cdn.bootcss.com/mathjax/2.7.1/latest.js?config=TeX-AMS-MML_HTMLorMML# Han Support docs: https://hanzi.pro/han: false# Swiftype Search API Key#swiftype_key:# Baidu Analytics ID#baidu_analytics:# Duoshuo ShortName#duoshuo_shortname:# Disqusdisqus: enable: false shortname: count: true# Hypercomments#hypercomments_id:# changyanchangyan: enable: false appid: appkey:# Valine.# You can get your appid and appkey from https://leancloud.cn# more info please open https://valine.js.orgvaline: enable: false appid: # your leancloud application appid appkey: # your leancloud application appkey notify: false # mail notifier , https://github.com/xCss/Valine/wiki verify: false # Verification code placeholder: Just go go # comment box placeholder avatar: mm # gravatar style guest_info: nick,mail,link # custom comment header pageSize: 10 # pagination size# Support for youyan comments system.# You can get your uid from http://www.uyan.cc#youyan_uid: your uid# Support for LiveRe comments system.# You can get your uid from https://livere.com/insight/myCode (General web site)#livere_uid: your uid# Gitment# Introduction: https://imsun.net/posts/gitment-introduction/# You can get your Github ID from https://api.github.com/users/<Github username>gitment: enable: false mint: true # RECOMMEND, A mint on Gitment, to support count, language and proxy_gateway count: true # Show comments count in post meta area lazy: false # Comments lazy loading with a button cleanly: false # Hide 'Powered by ...' on footer, and more language: # Force language, or auto switch by theme github_user: # MUST HAVE, Your Github ID github_repo: # MUST HAVE, The repo you use to store Gitment comments client_id: # MUST HAVE, Github client id for the Gitment client_secret: # EITHER this or proxy_gateway, Github access secret token for the Gitment proxy_gateway: # Address of api proxy, See: https://github.com/aimingoo/intersect redirect_protocol: # Protocol of redirect_uri with force_redirect_protocol when mint enabled# Baidu Share# Available value:# button | slide# Warning: Baidu Share does not support https.#baidushare:## type: button# Share# This plugin is more useful in China, make sure you known how to use it.# And you can find the use guide at official webiste: http://www.jiathis.com/.# Warning: JiaThis does not support https.#jiathis: ##uid: Get this uid from http://www.jiathis.com/#add_this_id:# Share#duoshuo_share: true# NeedMoreShare2# This plugin is a pure javascript sharing lib which is useful in China.# See: https://github.com/revir/need-more-share2# Also see: https://github.com/DzmVasileusky/needShareButton# iconStyle: default | box# boxForm: horizontal | vertical# position: top / middle / bottom + Left / Center / Right# networks: Weibo,Wechat,Douban,QQZone,Twitter,Linkedin,Mailto,Reddit,# Delicious,StumbleUpon,Pinterest,Facebook,GooglePlus,Slashdot,# Technorati,Posterous,Tumblr,GoogleBookmarks,Newsvine,# Evernote,Friendfeed,Vkontakte,Odnoklassniki,Mailruneedmoreshare2: enable: false postbottom: enable: false options: iconStyle: box boxForm: horizontal position: bottomCenter networks: Weibo,Wechat,Douban,QQZone,Twitter,Facebook float: enable: false options: iconStyle: box boxForm: horizontal position: middleRight networks: Weibo,Wechat,Douban,QQZone,Twitter,Facebook# Google Webmaster tools verification setting# See: https://www.google.com/webmasters/#google_site_verification:# Google Analytics#google_analytics:# Bing Webmaster tools verification setting# See: https://www.bing.com/webmaster/#bing_site_verification:# Yandex Webmaster tools verification setting# See: https://webmaster.yandex.ru/#yandex_site_verification:# CNZZ count#cnzz_siteid:# Application Insights# See https://azure.microsoft.com/en-us/services/application-insights/# application_insights:# Make duoshuo show UA# user_id must NOT be null when admin_enable is true!# you can visit http://dev.duoshuo.com get duoshuo user id.duoshuo_info: ua_enable: true admin_enable: false user_id: 0 #admin_nickname: Author# Post widgets & FB/VK comments settings.# ---------------------------------------------------------------# Facebook SDK Support.# https://github.com/iissnan/hexo-theme-next/pull/410facebook_sdk: enable: false app_id: #<app_id> fb_admin: #<user_id> like_button: #true webmaster: #true# Facebook comments plugin# This plugin depends on Facebook SDK.# If facebook_sdk.enable is false, Facebook comments plugin is unavailable.facebook_comments_plugin: enable: false num_of_posts: 10 # min posts num is 1 width: 100% # default width is 550px scheme: light # default scheme is light (light or dark)# VKontakte API Support.# To get your AppID visit https://vk.com/editapp?act=createvkontakte_api: enable: false app_id: #<app_id> like: true comments: true num_of_posts: 10# Star rating support to each article.# To get your ID visit https://widgetpack.comrating: enable: false id: #<app_id> color: fc6423# ---------------------------------------------------------------# Show number of visitors to each article.# You can visit https://leancloud.cn get AppID and AppKey.leancloud_visitors: enable: false app_id: #<app_id> app_key: #<app_key># Another tool to show number of visitors to each article.# visit https://console.firebase.google.com/u/0/ to get apiKey and projectId# visit https://firebase.google.com/docs/firestore/ to get more information about firestorefirestore: enable: false collection: articles #required, a string collection name to access firestore database apiKey: #required projectId: #required bluebird: false #enable this if you want to include bluebird 3.5.1(core version) Promise polyfill# Show PV/UV of the website/page with busuanzi.# Get more information on http://ibruce.info/2015/04/04/busuanzi/busuanzi_count: # count values only if the other configs are false enable: false # custom uv span for the whole site site_uv: true site_uv_header: <i class="fa fa-user"></i> site_uv_footer: # custom pv span for the whole site site_pv: true site_pv_header: <i class="fa fa-eye"></i> site_pv_footer: # custom pv span for one page only page_pv: true page_pv_header: <i class="fa fa-file-o"></i> page_pv_footer:# Tencent analytics ID# tencent_analytics:# Tencent MTA ID# tencent_mta:# Enable baidu push so that the blog will push the url to baidu automatically which is very helpful for SEObaidu_push: false# Google Calendar# Share your recent schedule to others via calendar page## API Documentation:# https://developers.google.com/google-apps/calendar/v3/reference/events/listcalendar: enable: false calendar_id: <required> api_key: <required> orderBy: startTime offsetMax: 24 offsetMin: 4 timeZone: showDeleted: false singleEvents: true maxResults: 250# Algolia Searchalgolia_search: enable: false hits: per_page: 10 labels: input_placeholder: Search for Posts hits_empty: "We didn't find any results for the search: ${query}" hits_stats: "${hits} results found in ${time} ms"# Local search# Dependencies: https://github.com/flashlab/hexo-generator-searchlocal_search: enable: true # if auto, trigger search by changing input # if manual, trigger search by pressing enter key or search button trigger: auto # show top n results per article, show all results by setting to -1 top_n_per_article: 100# ---------------------------------------------------------------# Tags Settings# ---------------------------------------------------------------# External URL with BASE64 encrypt & decrypt.# Usage: {% exturl text url "title" %}# Alias: {% extlink text url "title" %}exturl: true# Note tag (bs-callout).note: # Note tag style values: # - simple bs-callout old alert style. Default. # - modern bs-callout new (v2-v3) alert style. # - flat flat callout style with background, like on Mozilla or StackOverflow. # - disabled disable all CSS styles import of note tag. style: simple icons: false border_radius: 3 # Offset lighter of background in % for modern and flat styles (modern: -12 | 12; flat: -18 | 6). # Offset also applied to label tag variables. This option can work with disabled note tag. light_bg_offset: 0# Label tag.label: true# Tabs tag.tabs: enable: true transition: tabs: false labels: true border_radius: 0#! ---------------------------------------------------------------#! DO NOT EDIT THE FOLLOWING SETTINGS#! UNLESS YOU KNOW WHAT YOU ARE DOING#! ---------------------------------------------------------------# Use velocity to animate everything.motion: enable: true async: false transition: # Transition variants: # fadeIn | fadeOut | flipXIn | flipXOut | flipYIn | flipYOut | flipBounceXIn | flipBounceXOut | flipBounceYIn | flipBounceYOut # swoopIn | swoopOut | whirlIn | whirlOut | shrinkIn | shrinkOut | expandIn | expandOut # bounceIn | bounceOut | bounceUpIn | bounceUpOut | bounceDownIn | bounceDownOut | bounceLeftIn | bounceLeftOut | bounceRightIn | bounceRightOut # slideUpIn | slideUpOut | slideDownIn | slideDownOut | slideLeftIn | slideLeftOut | slideRightIn | slideRightOut # slideUpBigIn | slideUpBigOut | slideDownBigIn | slideDownBigOut | slideLeftBigIn | slideLeftBigOut | slideRightBigIn | slideRightBigOut # perspectiveUpIn | perspectiveUpOut | perspectiveDownIn | perspectiveDownOut | perspectiveLeftIn | perspectiveLeftOut | perspectiveRightIn | perspectiveRightOut post_block: fadeIn post_header: slideDownIn post_body: slideDownIn coll_header: slideLeftIn # Only for Pisces | Gemini. sidebar: slideUpIn# Fancyboxfancybox: true# Progress bar in the top during page loading.pace: false# Themes list:#pace-theme-big-counter#pace-theme-bounce#pace-theme-barber-shop#pace-theme-center-atom#pace-theme-center-circle#pace-theme-center-radar#pace-theme-center-simple#pace-theme-corner-indicator#pace-theme-fill-left#pace-theme-flash#pace-theme-loading-bar#pace-theme-mac-osx#pace-theme-minimal# For example# pace_theme: pace-theme-center-simplepace_theme: pace-theme-minimal# Canvas-nestcanvas_nest: true# three_wavesthree_waves: false# canvas_linescanvas_lines: false# canvas_spherecanvas_sphere: false# Only fit scheme Pisces# Canvas-ribbon# size: The width of the ribbon.# alpha: The transparency of the ribbon.# zIndex: The display level of the ribbon.canvas_ribbon: enable: false size: 300 alpha: 0.6 zIndex: -1# Script Vendors.# Set a CDN address for the vendor you want to customize.# For example# jquery: https://ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js# Be aware that you should use the same version as internal ones to avoid potential problems.# Please use the https protocol of CDN files when you enable https on your site.vendors: # Internal path prefix. Please do not edit it. _internal: lib # Internal version: 2.1.3 jquery: # Internal version: 2.1.5 # See: http://fancyapps.com/fancybox/ fancybox: fancybox_css: # Internal version: 1.0.6 # See: https://github.com/ftlabs/fastclick fastclick: # Internal version: 1.9.7 # See: https://github.com/tuupola/jquery_lazyload lazyload: # Internal version: 1.2.1 # See: http://VelocityJS.org velocity: # Internal version: 1.2.1 # See: http://VelocityJS.org velocity_ui: # Internal version: 0.7.9 # See: https://faisalman.github.io/ua-parser-js/ ua_parser: # Internal version: 4.6.2 # See: http://fontawesome.io/ fontawesome: # Internal version: 1 # https://www.algolia.com algolia_instant_js: algolia_instant_css: # Internal version: 1.0.2 # See: https://github.com/HubSpot/pace # Or use direct links below: # pace: //cdn.bootcss.com/pace/1.0.2/pace.min.js # pace_css: //cdn.bootcss.com/pace/1.0.2/themes/blue/pace-theme-flash.min.css pace: pace_css: # Internal version: 1.0.0 # https://github.com/hustcc/canvas-nest.js canvas_nest: # three three: # three_waves # https://github.com/jjandxa/three_waves three_waves: # three_waves # https://github.com/jjandxa/canvas_lines canvas_lines: # three_waves # https://github.com/jjandxa/canvas_sphere canvas_sphere: # Internal version: 1.0.0 # https://github.com/zproo/canvas-ribbon canvas_ribbon: # Internal version: 3.3.0 # https://github.com/ethantw/Han han: # needMoreShare2 # https://github.com/revir/need-more-share2 needMoreShare2:# Assetscss: cssjs: jsimages: imagespassage_end_tag: enabled: true# Theme versionversion: 5.1.4]]></content>
<categories>
<category>Hexo</category>
</categories>
<tags>
<tag>基础</tag>
</tags>
</entry>
<entry>
<title><![CDATA[讲讲指针]]></title>
<url>%2F2019-01-08-%E8%AE%B2%E8%AE%B2%E6%8C%87%E9%92%88.html</url>
<content type="text"><![CDATA[指针是什么?百度百科说:在计算机科学中,指针(Pointer)是编程语言中的一个对象,利用地址,它的值直接指向(points to)存在电脑存储器中另一个地方的值。由于通过地址能找到所需的变量单元,可以说,地址指向该变量单元。因此,将地址形象化的称为“指针”。意思是通过它能找到以它为地址的内存单元。 指针其实就是存有地址的变量,就和其他变量一样,他也有着自己的类型,唯一的区别就是,他在定义时需要加一个*号,就比如这样,int *p, 在32位的编译器下,指针都是4个字节。指针身为变量,当然也可以进行正常的加减,但是它与普通变量的运算不同的是,指针的加减所加所减的是指针所指向的类型。123// 关于指针类型的加减:// pa + n = pa + sizeof(指针所指向的类型)*n//指针所指向的类型可以是int char float这样的也可以是结构体类型的。 指针怎么用?指针定义12int a; int *pa = &a; 这里可以看到,先定义了一个整型变量a,然后又定义了一个整型的指针pa。在pa的前面有个 * ,这个* 就是特指这个变量是一个新类型的变量是个指针变量。这个指针变量pa将指向的内容不是一个整型数字,而是一个地址。在这个地址上存的一个“东西”。而这个“东西”是一个整型数(a)。 从目前来看,我们的数据类型中增加了一个新的成员。从最开始学习的int ,然后加入了float,后来又来了double,char,还有long int,long long int。我们都能够接受他们是数据类型。现在我们就要接受一种新的数据类型int * 。对这种数据类型的规范形式比较不一样。就是在原来的int,float,char的基础上在后面加了一个*。 这个就比较难受了。因为以前都在在前面加long的。这次是在后面加*。但是我们还是要接受啊。慢慢看习惯就ok。所以我们现在看代码的时候,在定义的时候,在int等基础数据类型后面带*的时候,就知道后面的这个变量其实是一个指向了某个地址的变量。 我们在定义指针的时候,通常会这么写1int *pointer =NULL; 这里的重点在=前面,就是这个*是直接贴着变量名的。这样做的效果和int* pointer 和 int * pointer没有区别。 采用int *pointer的写法是为了看清pointer其实是一个指针变量。这样方便理解。 另外其他的定义方式如下:12int a;int *pa=&a; 这里解释说明一下:我们在脑子里过一下。一个指针变量,其实是一个变量,他里面的内容是一个地址。这个地址不是别的,正是物理内存上的物理地址。而我们并步知道这个地址是个什么玩意。所以我们不能想当然觉得地址是个整数或者是字母什么的。 那么我们这个变量在声明初始化的时候,肯定要指向一个地址的。那么这个指针变量指向的那个地址类型要和这个指针变量类型一样。不然就驴唇不对马嘴了。故而,一个整型的指针变量,就只能指向一个整型的变量地址。 那么问题来了,该怎么获得那个整数的地址呢?以前学过int a;就声明并且初始化了一个整型变量。我们知道int是整型数据类型。那么我们就可以事先给他安排一个初始化的数。我们就给他安排为0。而我们这样声明的时候:int b=9;这个时候,我们系统底部(编译器)的操作是先初始化为0,然后把0替换为9。好了,现在我们的目标就是获得这个9的地址。然后把这个地址赋值给pa。 明确了这个问题,c语言的设计者也是很头疼啊。该怎么办呢?智慧的人就是智慧的人。引入指针必然会涉及到地址,涉及到地址必然会涉及到获取地址的操作。所以设计者就涉及了一个操作来获取地址。这个操作使用一个符号来运算,就是&符号。以前我们学过+-*/。今天再学一个新的运算符,那就是&。&就是取地址符。 这个符号的使用很简单,你要取哪个变量的地址直接在前面加上&就可以了。比如为想取刚刚声明的变量int b=9;中的b的地址,那么就写&b。这样就取到了b的地址。同样的道理&a;就取到了a的地址了。 现在问题解决了。我们有了a的地址,也有了指针变量。所以我们就可以使用int *pa=&a;来初始化这个变量pa了。 好了,我们再来讲讲这个pa。一定要看请逻辑关系和类比关系。 以前我们学了int a=0;,现在我们学了int *pa=&a;。这里,看清楚,我们的变量名是a ,是pa。所以你应该想到变量名的命名规则了吧。所以我们的指针变量啊,他是pa。不是*pa。这个*是和int是一伙的。我们把*和pa写在一起是为了我们理解pa的意思。pa是个指针变量。仅此而已。故而,在非声明变量的代码里看到pa,要知道这个时候pa是指向地址的,不是指向整型数字的。 指针运算指针是什么?指针是地址,指针变量指向的是一个地址。这里的指向,其实就是=的意思,就是存储的意思,就是代表的意思。 指针的运算,翻译过来就是地址的运算。那么能有哪些运算呢? + -运算 地址是物理内存的地址,进入到计算机中就被转化成一串数字(这个数字没有什么意义,就表示当时内存的位置)。计算机是二进制的,那么就会形成1和0。而在某些时候计算机使用八进制和十六进制还是有好处的,所以地址也会被表示成八进制或者十六进制。本质上还是一个数字(或许很长的数字)。 讲完了这些,我们来说说,地址的加减运算是个什么玩意。 就像在桌子上把扑克整整齐齐的摆开,一张接一张的。我们有个打火机就站在第一章牌上。这个打火机就是我们的指针。每一张扑克就代表一个地址。现在我们要使指针加1,那么就将打火机向前移动一张扑克,站在了第二张扑克上。所以我们很明白这个指针+1和-1是什么意思了。就是移动了其本身这个类型的长度。 在这个例子中,打火机这个指针是指向扑克这中类型的。所以每次打火机只能移动扑克大小的N 倍。这里打火机相当于int *,扑克相当于int。每次int *移动的大小只能是int的N倍。不能只移动半个int。]]></content>
<categories>
<category>C/C++</category>
</categories>
<tags>
<tag>基础</tag>
</tags>
</entry>
<entry>
<title><![CDATA[TensorFlow使用]]></title>
<url>%2F2019-01-07-tensorflow%E4%BD%BF%E7%94%A8.html</url>
<content type="text"><![CDATA[来自官方程序 基本概念使用 TensorFlow, 你必须明白 TensorFlow: 使用图 (graph) 来表示计算任务. 在被称之为 会话 (Session) 的上下文 (context) 中执行图. 使用 tensor 表示数据. 通过 变量 (Variable) 维护状态. 使用 feed 和 fetch 可以为任意的操作(arbitrary operation) 赋值或者从其中获取数据. 使用常量import tensorflow as tf # 创建一个常量 op, 产生一个 1x2 矩阵. 这个 op 被作为一个节点 # 加到默认图中. # # 构造器的返回值代表该常量 op 的返回值. matrix1 = tf.constant([[3., 3.]]) # 创建另外一个常量 op, 产生一个 2x1 矩阵. matrix2 = tf.constant([[2.],[2.]]) # 创建一个矩阵乘法 matmul op , 把 'matrix1' 和 'matrix2' 作为输入. # 返回值 'product' 代表矩阵乘法的结果. product = tf.matmul(matrix1, matrix2) 使用session#默认图现在有三个节点, 两个 constant() op, 和一个matmul() op. 为了真正进行矩阵相乘运算, 并得到矩阵乘法的 结果, 你必须在会话里启动这个图. # 启动默认图. sess = tf.Session() # 调用 sess 的 'run()' 方法来执行矩阵乘法 op, 传入 'product' 作为该方法的参数. # 上面提到, 'product' 代表了矩阵乘法 op 的输出, 传入它是向方法表明, 我们希望取回 # 矩阵乘法 op 的输出. # # 整个执行过程是自动化的, 会话负责传递 op 所需的全部输入. op 通常是并发执行的. # # 函数调用 'run(product)' 触发了图中三个 op (两个常量 op 和一个矩阵乘法 op) 的执行. # # 返回值 'result' 是一个 numpy `ndarray` 对象. result = sess.run(product) print(result) # ==> [[ 12.]] # 任务完成, 关闭会话. sess.close() Session 对象在使用完后需要关闭以释放资源. 除了显式调用 close 外, 也可以使用 “with” 代码块 来自动完成关闭动作. with tf.Session() as sess: result = sess.run([product]) print(result) 推荐使用with。 指定计算设备如果机器上有超过一个可用的 GPU, 除第一个外的其它 GPU 默认是不参与计算的. 为了让 TensorFlow 使用这些 GPU, 你必须将 op 明确指派给它们执行. with...Device 语句用来指派特定的 CPU 或 GPU 执行操作: with tf.Session() as sess: with tf.device("/gpu:1"): matrix1 = tf.constant([[3., 3.]]) matrix2 = tf.constant([[2.],[2.]]) product = tf.matmul(matrix1, matrix2) 设备用字符串进行标识. 目前支持的设备包括: "/cpu:0": 机器的 CPU. "/gpu:0": 机器的第一个 GPU, 如果有的话. "/gpu:1": 机器的第二个 GPU, 以此类推. 使用GPU设备 交互式使用session为了便于使用诸如 IPython 之类的 Python 交互环境, 可以使用 InteractiveSession 代替 Session 类, 使用 Tensor.eval() 和 Operation.run() 方法代替 Session.run(). 这样可以避免使用一个变量来持有会话. # 进入一个交互式 TensorFlow 会话. import tensorflow as tf sess = tf.InteractiveSession() x = tf.Variable([1.0, 2.0]) a = tf.constant([3.0, 3.0]) # 使用初始化器 initializer op 的 run() 方法初始化 'x' x.initializer.run() # 增加一个减法 sub op, 从 'x' 减去 'a'. 运行减法 op, 输出结果 sub = tf.sub(x, a) print(sub.eval()) # ==> [-2. -1.] 使用变量# 创建一个变量, 初始化为标量 0. state = tf.Variable(0, name="counter") # 创建一个 op, 其作用是使 state 增加 1 one = tf.constant(1) new_value = tf.add(state, one) update = tf.assign(state, new_value) # 启动图后, 变量必须先经过`初始化` (init) op 初始化, # 首先必须增加一个`初始化` op 到图中.]]></content>
<categories>
<category>TensorFlow</category>
</categories>
<tags>
<tag>深度学习</tag>
</tags>
</entry>
<entry>
<title><![CDATA[Linux下Makefile中动态链接库和静态链接库的生成与调用]]></title>
<url>%2F2018-12-17-Linux%E4%B8%8BMakefile%E4%B8%AD%E5%8A%A8%E6%80%81%E9%93%BE%E6%8E%A5%E5%BA%93%E5%92%8C%E9%9D%99%E6%80%81%E9%93%BE%E6%8E%A5%E5%BA%93%E7%9A%84%E7%94%9F%E6%88%90%E4%B8%8E%E8%B0%83%E7%94%A8.html</url>
<content type="text"><![CDATA[https://blog.csdn.net/u011964923/article/details/73297443]]></content>
<categories>
<category>Linux</category>
</categories>
</entry>
<entry>
<title><![CDATA[使用hyperlpr识别车牌]]></title>
<url>%2F2018-11-30-%E4%BD%BF%E7%94%A8hyperlpr%E8%AF%86%E5%88%AB%E8%BD%A6%E7%89%8C.html</url>
<content type="text"><![CDATA[安装库===1pip install hyperlpr 代码== #导入包 from hyperlpr import * #导入OpenCV库 import cv2 #读入图片 image = cv2.imread("demo.jpg") #识别结果 print(HyperLPR_PlateRecogntion(image)) 输出结果如下: >>> print(HyperLPR_PlateRecogntion(image)) [['宁AFD3333', 0.9661077931523323, [71, 215, 339, 285]]] git库地址====== https://github.com/zeusees/HyperLPR]]></content>
<categories>
<category>Python</category>
</categories>
<tags>
<tag>OpenCV</tag>
</tags>
</entry>
<entry>
<title><![CDATA[安装opencv3.4.4]]></title>
<url>%2F2018-11-25-%E5%AE%89%E8%A3%85opencv3.4.4.html</url>
<content type="text"><![CDATA[Ubuntu16.04安装OpenCV 3.4.4========================= 参考官方英文安装教程准备– 下载:https://sourceforge.net/projects/opencvlibrary/ 必须的包: GCC 4.4.x or later CMake 2.8.7 or higher Git GTK+2.x or higher, including headers (libgtk2.0-dev) pkg-config Python 2.6 or later and Numpy 1.5 or later with developer packages (python-dev, python-numpy) ffmpeg or libav development packages: libavcodec-dev, libavformat-dev, libswscale-dev [optional] libtbb2 libtbb-dev [optional] libdc1394 2.x [optional] libjpeg-dev, libpng-dev, libtiff-dev, libjasper-dev, libdc1394-22-dev [optional] CUDA Toolkit 6.5 or higher * 代码:123[compiler] sudo apt-get install build-essential[required] sudo apt-get install cmake git libgtk2.0-dev pkg-config libavcodec-dev libavformat-dev libswscale-dev[optional] sudo apt-get install python-dev python-numpy libtbb2 libtbb-dev libjpeg-dev libpng-dev libtiff-dev libjasper-dev libdc1394-22-dev 如果需要安装OpenCV的额外库那么就做下面的操作 进入到opencv的主目录下1git clone https://github.com/opencv/opencv_contrib.git 下载完了之后,开始编译操作。 编译–123cd ~/opencvmkdir buildcd build 编译release版本,并且加入了额外的库(全部都加了)1cmake -D CMAKE_BUILD_TYPE=Release -DOPENCV_EXTRA_MODULES_PATH=../opencv_contrib/modules -D CMAKE_INSTALL_PREFIX=/usr/local .. 如果要编译自带的例子,那么在上一句中加入1-DBUILD_EXAMPLES=ON 如果要编译Debug版本,那么下面选项的参数二选一。所以如果想两个都要的话,就要编译两次。1CMAKE_BUILD_TYPE=Release\Debug 其他比如python支持什么的可选项我就没加入。 最后完用的语句是:这里建议目录更改成/usr/local/opencv3.4.41cmake -D CMAKE_BUILD_TYPE=Release -D CMAKE_INSTALL_PREFIX=/usr/local .. 执行的过程中需要联网下载一个文件1IPPICV: Download: ippicv_2019_lnx_intel64_general_20180723.tgz 我这边瞪了一会就下载完了。如果你网速慢的话,可以先去下载,然后放在指定的地方。具体方法去谷歌一下。 结果如下:123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116-- General configuration for OpenCV 3.4.4 =====================================-- Version control: unknown-- -- Platform:-- Timestamp: 2018-11-25T03:27:54Z-- Host: Linux 4.4.0-21-generic x86_64-- CMake: 3.5.1-- CMake generator: Unix Makefiles-- CMake build tool: /usr/bin/make-- Configuration: Release-- -- CPU/HW features:-- Baseline: SSE SSE2 SSE3-- requested: SSE3-- Dispatched code generation: SSE4_1 SSE4_2 FP16 AVX AVX2 AVX512_SKX-- requested: SSE4_1 SSE4_2 AVX FP16 AVX2 AVX512_SKX-- SSE4_1 (6 files): + SSSE3 SSE4_1-- SSE4_2 (2 files): + SSSE3 SSE4_1 POPCNT SSE4_2-- FP16 (1 files): + SSSE3 SSE4_1 POPCNT SSE4_2 FP16 AVX-- AVX (6 files): + SSSE3 SSE4_1 POPCNT SSE4_2 AVX-- AVX2 (12 files): + SSSE3 SSE4_1 POPCNT SSE4_2 FP16 FMA3 AVX AVX2-- AVX512_SKX (1 files): + SSSE3 SSE4_1 POPCNT SSE4_2 FP16 FMA3 AVX AVX2 AVX_512F AVX512_SKX-- -- C/C++:-- Built as dynamic libs?: YES-- C++ Compiler: /usr/bin/c++ (ver 5.4.0)-- C++ flags (Release): -fsigned-char -W -Wall -Werror=return-type -Werror=non-virtual-dtor -Werror=address -Werror=sequence-point -Wformat -Werror=format-security -Wmissing-declarations -Wundef -Winit-self -Wpointer-arith -Wshadow -Wsign-promo -Wuninitialized -Winit-self -Wno-narrowing -Wno-delete-non-virtual-dtor -Wno-comment -fdiagnostics-show-option -Wno-long-long -pthread -fomit-frame-pointer -ffunction-sections -fdata-sections -msse -msse2 -msse3 -fvisibility=hidden -fvisibility-inlines-hidden -O3 -DNDEBUG -DNDEBUG-- C++ flags (Debug): -fsigned-char -W -Wall -Werror=return-type -Werror=non-virtual-dtor -Werror=address -Werror=sequence-point -Wformat -Werror=format-security -Wmissing-declarations -Wundef -Winit-self -Wpointer-arith -Wshadow -Wsign-promo -Wuninitialized -Winit-self -Wno-narrowing -Wno-delete-non-virtual-dtor -Wno-comment -fdiagnostics-show-option -Wno-long-long -pthread -fomit-frame-pointer -ffunction-sections -fdata-sections -msse -msse2 -msse3 -fvisibility=hidden -fvisibility-inlines-hidden -g -O0 -DDEBUG -D_DEBUG-- C Compiler: /usr/bin/cc-- C flags (Release): -fsigned-char -W -Wall -Werror=return-type -Werror=non-virtual-dtor -Werror=address -Werror=sequence-point -Wformat -Werror=format-security -Wmissing-declarations -Wmissing-prototypes -Wstrict-prototypes -Wundef -Winit-self -Wpointer-arith -Wshadow -Wuninitialized -Winit-self -Wno-narrowing -Wno-comment -fdiagnostics-show-option -Wno-long-long -pthread -fomit-frame-pointer -ffunction-sections -fdata-sections -msse -msse2 -msse3 -fvisibility=hidden -O3 -DNDEBUG -DNDEBUG-- C flags (Debug): -fsigned-char -W -Wall -Werror=return-type -Werror=non-virtual-dtor -Werror=address -Werror=sequence-point -Wformat -Werror=format-security -Wmissing-declarations -Wmissing-prototypes -Wstrict-prototypes -Wundef -Winit-self -Wpointer-arith -Wshadow -Wuninitialized -Winit-self -Wno-narrowing -Wno-comment -fdiagnostics-show-option -Wno-long-long -pthread -fomit-frame-pointer -ffunction-sections -fdata-sections -msse -msse2 -msse3 -fvisibility=hidden -g -O0 -DDEBUG -D_DEBUG-- Linker flags (Release): -- Linker flags (Debug): -- ccache: NO-- Precompiled headers: YES-- Extra dependencies: dl m pthread rt-- 3rdparty dependencies:-- -- OpenCV modules:-- To be built: calib3d core dnn features2d flann highgui imgcodecs imgproc java_bindings_generator ml objdetect photo python2 python_bindings_generator shape stitching superres ts video videoio videostab-- Disabled: world-- Disabled by dependency: --- Unavailable: cudaarithm cudabgsegm cudacodec cudafeatures2d cudafilters cudaimgproc cudalegacy cudaobjdetect cudaoptflow cudastereo cudawarping cudev java js python3 viz-- Applications: tests perf_tests examples apps-- Documentation: NO-- Non-free algorithms: NO-- -- GUI: -- GTK+: YES (ver 2.24.30)-- GThread : YES (ver 2.48.2)-- GtkGlExt: NO-- VTK support: NO-- -- Media I/O: -- ZLib: /home/tf/anaconda3/lib/libz.so (ver 1.2.11)-- JPEG: /home/tf/anaconda3/lib/libjpeg.so (ver 90)-- WEBP: build (ver encoder: 0x020e)-- PNG: /home/tf/anaconda3/lib/libpng.so (ver 1.6.34)-- TIFF: /home/tf/anaconda3/lib/libtiff.so (ver 42 / 4.0.9)-- JPEG 2000: /usr/lib/x86_64-linux-gnu/libjasper.so (ver 1.900.1)-- OpenEXR: build (ver 1.7.1)-- HDR: YES-- SUNRASTER: YES-- PXM: YES-- -- Video I/O:-- DC1394: YES (ver 2.2.4)-- FFMPEG: YES-- avcodec: YES (ver 56.60.100)-- avformat: YES (ver 56.40.101)-- avutil: YES (ver 54.31.100)-- swscale: YES (ver 3.1.101)-- avresample: NO-- GStreamer: NO-- libv4l/libv4l2: NO-- v4l/v4l2: linux/videodev2.h-- -- Parallel framework: pthreads-- -- Trace: YES (with Intel ITT)-- -- Other third-party libraries:-- Intel IPP: 2019.0.0 Gold [2019.0.0]-- at: /home/tf/opencv3.4.4/build/3rdparty/ippicv/ippicv_lnx/icv-- Intel IPP IW: sources (2019.0.0)-- at: /home/tf/opencv3.4.4/build/3rdparty/ippicv/ippicv_lnx/iw-- Lapack: NO-- Eigen: NO-- Custom HAL: NO-- Protobuf: build (3.5.1)-- -- OpenCL: YES (no extra features)-- Include path: /home/tf/opencv3.4.4/3rdparty/include/opencl/1.2-- Link libraries: Dynamic load-- -- Python 2:-- Interpreter: /usr/bin/python2.7 (ver 2.7.12)-- Libraries: /usr/lib/x86_64-linux-gnu/libpython2.7.so (ver 2.7.12)-- numpy: /usr/local/lib/python2.7/dist-packages/numpy-1.16.0.dev0+983bbb5-py2.7-linux-x86_64.egg/numpy/core/include (ver 1.16.0.dev0+983bbb5)-- packages path: lib/python2.7/dist-packages-- -- Python (for build): /usr/bin/python2.7-- Pylint: /home/tf/anaconda3/bin/pylint (ver: 3.7.0, checks: 162)-- -- Java: -- ant: NO-- JNI: NO-- Java wrappers: NO-- Java tests: NO-- -- Install to: /usr/local-- ------------------------------------------------------------------- -- Configuring done-- Generating done-- Build files have been written to: /home/tf/opencv3.4.4/build 接下来开始编译了1make -j7 # runs 7 jobs in parallel 我实际使用的语句是:1make -j24 #我电脑比较好,哈哈哈,全程不到10分钟 开始安装1sudo make install #大概1分钟就完事,最后贴出了安装的文件。 测试验证 下载测试数据,这个测试数据集有点大啊。。。。1git clone https://github.com/opencv/opencv_extra.git 设置测试数据的环境变量1export OPENCV_TEST_DATA_PATH=/home/tf/opencv_extra/testdata 使环境变量生效1source ~/.bashrc 进入build目录执行测试程序。 这个测试程序使编译安装完了之后才有的。123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381sh /home/tf/opencv3.4.4/build/bin/opencv_test_core-- Install configuration: "Release"-- Installing: /usr/local/share/OpenCV/licenses/ippicv-readme.htm-- Installing: /usr/local/share/OpenCV/licenses/ippicv-EULA.txt-- Installing: /usr/local/share/OpenCV/licenses/ippiw-EULA.txt-- Installing: /usr/local/share/OpenCV/licenses/ippiw-support.txt-- Installing: /usr/local/share/OpenCV/licenses/ippiw-third-party-programs.txt-- Installing: /usr/local/share/OpenCV/licenses/opencl-headers-LICENSE.txt-- Installing: /usr/local/include/opencv2/cvconfig.h-- Installing: /usr/local/include/opencv2/opencv_modules.hpp-- Installing: /usr/local/lib/pkgconfig/opencv.pc-- Old export file "/usr/local/share/OpenCV/OpenCVModules.cmake" will be replaced. Removing files [/usr/local/share/OpenCV/OpenCVModules-release.cmake].-- Installing: /usr/local/share/OpenCV/OpenCVModules.cmake-- Installing: /usr/local/share/OpenCV/OpenCVModules-release.cmake-- Installing: /usr/local/share/OpenCV/OpenCVConfig-version.cmake-- Installing: /usr/local/share/OpenCV/OpenCVConfig.cmake-- Installing: /usr/local/bin/setup_vars_opencv3.sh-- Installing: /usr/local/share/OpenCV/valgrind.supp-- Installing: /usr/local/share/OpenCV/valgrind_3rdparty.supp-- Installing: /usr/local/share/OpenCV/licenses/openexr-LICENSE-- Installing: /usr/local/share/OpenCV/licenses/openexr-AUTHORS.ilmbase-- Installing: /usr/local/share/OpenCV/licenses/openexr-AUTHORS.openexr-- Installing: /usr/local/share/OpenCV/licenses/openexr-fix_msvc2013_errors.patch-- Installing: /usr/local/share/OpenCV/licenses/protobuf-LICENSE-- Installing: /usr/local/share/OpenCV/licenses/protobuf-README.md-- Installing: /usr/local/share/OpenCV/licenses/quirc-LICENSE-- Installing: /usr/local/share/OpenCV/licenses/ittnotify-LICENSE.BSD-- Installing: /usr/local/share/OpenCV/licenses/ittnotify-LICENSE.GPL-- Installing: /usr/local/include/opencv/cvaux.h-- Installing: /usr/local/include/opencv/cv.h-- Installing: /usr/local/include/opencv/cvwimage.h-- Installing: /usr/local/include/opencv/highgui.h-- Installing: /usr/local/include/opencv/cxcore.h-- Installing: /usr/local/include/opencv/cxeigen.hpp-- Installing: /usr/local/include/opencv/cxcore.hpp-- Installing: /usr/local/include/opencv/cxmisc.h-- Installing: /usr/local/include/opencv/ml.h-- Installing: /usr/local/include/opencv/cv.hpp-- Installing: /usr/local/include/opencv/cvaux.hpp-- Installing: /usr/local/include/opencv2/opencv.hpp-- Installing: /usr/local/python/setup.py-- Installing: /usr/local/python/cv2/__init__.py-- Installing: /usr/local/python/cv2/load_config_py2.py-- Installing: /usr/local/python/cv2/load_config_py3.py-- Installing: /usr/local/python/cv2/config.py-- Installing: /usr/local/lib/libopencv_core.so.3.4.4-- Installing: /usr/local/lib/libopencv_core.so.3.4-- Set runtime path of "/usr/local/lib/libopencv_core.so.3.4.4" to "/usr/local/lib:/home/tf/anaconda3/lib"-- Installing: /usr/local/lib/libopencv_core.so-- Installing: /usr/local/include/opencv2/core/opencl/opencl_svm.hpp-- Installing: /usr/local/include/opencv2/core/opencl/ocl_defs.hpp-- Installing: /usr/local/include/opencv2/core/opencl/opencl_info.hpp-- Installing: /usr/local/include/opencv2/core/opencl/runtime/opencl_svm_20.hpp-- Installing: /usr/local/include/opencv2/core/opencl/runtime/opencl_gl.hpp-- Installing: /usr/local/include/opencv2/core/opencl/runtime/opencl_svm_definitions.hpp-- Installing: /usr/local/include/opencv2/core/opencl/runtime/autogenerated/opencl_gl.hpp-- Installing: /usr/local/include/opencv2/core/opencl/runtime/autogenerated/opencl_clamdfft.hpp-- Installing: /usr/local/include/opencv2/core/opencl/runtime/autogenerated/opencl_gl_wrappers.hpp-- Installing: /usr/local/include/opencv2/core/opencl/runtime/autogenerated/opencl_core.hpp-- Installing: /usr/local/include/opencv2/core/opencl/runtime/autogenerated/opencl_core_wrappers.hpp-- Installing: /usr/local/include/opencv2/core/opencl/runtime/autogenerated/opencl_clamdblas.hpp-- Installing: /usr/local/include/opencv2/core/opencl/runtime/opencl_clamdfft.hpp-- Installing: /usr/local/include/opencv2/core/opencl/runtime/opencl_gl_wrappers.hpp-- Installing: /usr/local/include/opencv2/core/opencl/runtime/opencl_svm_hsa_extension.hpp-- Installing: /usr/local/include/opencv2/core/opencl/runtime/opencl_core.hpp-- Installing: /usr/local/include/opencv2/core/opencl/runtime/opencl_core_wrappers.hpp-- Installing: /usr/local/include/opencv2/core/opencl/runtime/opencl_clamdblas.hpp-- Installing: /usr/local/include/opencv2/core/cuda/warp_reduce.hpp-- Installing: /usr/local/include/opencv2/core/cuda/dynamic_smem.hpp-- Installing: /usr/local/include/opencv2/core/cuda/datamov_utils.hpp-- Installing: /usr/local/include/opencv2/core/cuda/emulation.hpp-- Installing: /usr/local/include/opencv2/core/cuda/limits.hpp-- Installing: /usr/local/include/opencv2/core/cuda/warp_shuffle.hpp-- Installing: /usr/local/include/opencv2/core/cuda/saturate_cast.hpp-- Installing: /usr/local/include/opencv2/core/cuda/transform.hpp-- Installing: /usr/local/include/opencv2/core/cuda/scan.hpp-- Installing: /usr/local/include/opencv2/core/cuda/reduce.hpp-- Installing: /usr/local/include/opencv2/core/cuda/border_interpolate.hpp-- Installing: /usr/local/include/opencv2/core/cuda/filters.hpp-- Installing: /usr/local/include/opencv2/core/cuda/utility.hpp-- Installing: /usr/local/include/opencv2/core/cuda/functional.hpp-- Installing: /usr/local/include/opencv2/core/cuda/type_traits.hpp-- Installing: /usr/local/include/opencv2/core/cuda/vec_distance.hpp-- Installing: /usr/local/include/opencv2/core/cuda/color.hpp-- Installing: /usr/local/include/opencv2/core/cuda/funcattrib.hpp-- Installing: /usr/local/include/opencv2/core/cuda/block.hpp-- Installing: /usr/local/include/opencv2/core/cuda/warp.hpp-- Installing: /usr/local/include/opencv2/core/cuda/common.hpp-- Installing: /usr/local/include/opencv2/core/cuda/simd_functions.hpp-- Installing: /usr/local/include/opencv2/core/cuda/vec_traits.hpp-- Installing: /usr/local/include/opencv2/core/cuda/vec_math.hpp-- Installing: /usr/local/include/opencv2/core/cuda/detail/type_traits_detail.hpp-- Installing: /usr/local/include/opencv2/core/cuda/detail/reduce_key_val.hpp-- Installing: /usr/local/include/opencv2/core/cuda/detail/reduce.hpp-- Installing: /usr/local/include/opencv2/core/cuda/detail/vec_distance_detail.hpp-- Installing: /usr/local/include/opencv2/core/cuda/detail/color_detail.hpp-- Installing: /usr/local/include/opencv2/core/cuda/detail/transform_detail.hpp-- Installing: /usr/local/include/opencv2/core.hpp-- Installing: /usr/local/include/opencv2/core/cuda_types.hpp-- Installing: /usr/local/include/opencv2/core/base.hpp-- Installing: /usr/local/include/opencv2/core/core.hpp-- Installing: /usr/local/include/opencv2/core/cuda_stream_accessor.hpp-- Installing: /usr/local/include/opencv2/core/opengl.hpp-- Installing: /usr/local/include/opencv2/core/ocl.hpp-- Installing: /usr/local/include/opencv2/core/cuda.inl.hpp-- Installing: /usr/local/include/opencv2/core/persistence.hpp-- Installing: /usr/local/include/opencv2/core/ippasync.hpp-- Installing: /usr/local/include/opencv2/core/ocl_genbase.hpp-- Installing: /usr/local/include/opencv2/core/cuda.hpp-- Installing: /usr/local/include/opencv2/core/vsx_utils.hpp-- Installing: /usr/local/include/opencv2/core/matx.hpp-- Installing: /usr/local/include/opencv2/core/fast_math.hpp-- Installing: /usr/local/include/opencv2/core/ptr.inl.hpp-- Installing: /usr/local/include/opencv2/core/optim.hpp-- Installing: /usr/local/include/opencv2/core/mat.inl.hpp-- Installing: /usr/local/include/opencv2/core/saturate.hpp-- Installing: /usr/local/include/opencv2/core/eigen.hpp-- Installing: /usr/local/include/opencv2/core/directx.hpp-- Installing: /usr/local/include/opencv2/core/sse_utils.hpp-- Installing: /usr/local/include/opencv2/core/cvstd.inl.hpp-- Installing: /usr/local/include/opencv2/core/utility.hpp-- Installing: /usr/local/include/opencv2/core/bufferpool.hpp-- Installing: /usr/local/include/opencv2/core/va_intel.hpp-- Installing: /usr/local/include/opencv2/core/operations.hpp-- Installing: /usr/local/include/opencv2/core/cvstd.hpp-- Installing: /usr/local/include/opencv2/core/mat.hpp-- Installing: /usr/local/include/opencv2/core/wimage.hpp-- Installing: /usr/local/include/opencv2/core/softfloat.hpp-- Installing: /usr/local/include/opencv2/core/check.hpp-- Installing: /usr/local/include/opencv2/core/types.hpp-- Installing: /usr/local/include/opencv2/core/affine.hpp-- Installing: /usr/local/include/opencv2/core/ovx.hpp-- Installing: /usr/local/include/opencv2/core/traits.hpp-- Installing: /usr/local/include/opencv2/core/bindings_utils.hpp-- Installing: /usr/local/include/opencv2/core/version.hpp-- Installing: /usr/local/include/opencv2/core/neon_utils.hpp-- Installing: /usr/local/include/opencv2/core/types_c.h-- Installing: /usr/local/include/opencv2/core/cv_cpu_dispatch.h-- Installing: /usr/local/include/opencv2/core/cvdef.h-- Installing: /usr/local/include/opencv2/core/cv_cpu_helper.h-- Installing: /usr/local/include/opencv2/core/core_c.h-- Installing: /usr/local/include/opencv2/core/hal/intrin_neon.hpp-- Installing: /usr/local/include/opencv2/core/hal/intrin_forward.hpp-- Installing: /usr/local/include/opencv2/core/hal/intrin.hpp-- Installing: /usr/local/include/opencv2/core/hal/intrin_vsx.hpp-- Installing: /usr/local/include/opencv2/core/hal/intrin_sse_em.hpp-- Installing: /usr/local/include/opencv2/core/hal/intrin_cpp.hpp-- Installing: /usr/local/include/opencv2/core/hal/hal.hpp-- Installing: /usr/local/include/opencv2/core/hal/intrin_sse.hpp-- Installing: /usr/local/include/opencv2/core/hal/intrin_avx.hpp-- Installing: /usr/local/include/opencv2/core/hal/interface.h-- Installing: /usr/local/include/opencv2/core/utils/logger.hpp-- Installing: /usr/local/include/opencv2/core/utils/trace.hpp-- Installing: /usr/local/include/opencv2/core/utils/filesystem.hpp-- Installing: /usr/local/include/opencv2/core/utils/logger.defines.hpp-- Installing: /usr/local/share/OpenCV/licenses/SoftFloat-COPYING.txt-- Installing: /usr/local/lib/libopencv_flann.so.3.4.4-- Installing: /usr/local/lib/libopencv_flann.so.3.4-- Set runtime path of "/usr/local/lib/libopencv_flann.so.3.4.4" to "/usr/local/lib"-- Installing: /usr/local/lib/libopencv_flann.so-- Installing: /usr/local/include/opencv2/flann.hpp-- Installing: /usr/local/include/opencv2/flann/miniflann.hpp-- Installing: /usr/local/include/opencv2/flann/flann_base.hpp-- Installing: /usr/local/include/opencv2/flann/flann.hpp-- Installing: /usr/local/include/opencv2/flann/timer.h-- Installing: /usr/local/include/opencv2/flann/hierarchical_clustering_index.h-- Installing: /usr/local/include/opencv2/flann/saving.h-- Installing: /usr/local/include/opencv2/flann/kmeans_index.h-- Installing: /usr/local/include/opencv2/flann/heap.h-- Installing: /usr/local/include/opencv2/flann/hdf5.h-- Installing: /usr/local/include/opencv2/flann/kdtree_index.h-- Installing: /usr/local/include/opencv2/flann/dist.h-- Installing: /usr/local/include/opencv2/flann/result_set.h-- Installing: /usr/local/include/opencv2/flann/sampling.h-- Installing: /usr/local/include/opencv2/flann/config.h-- Installing: /usr/local/include/opencv2/flann/any.h-- Installing: /usr/local/include/opencv2/flann/general.h-- Installing: /usr/local/include/opencv2/flann/linear_index.h-- Installing: /usr/local/include/opencv2/flann/nn_index.h-- Installing: /usr/local/include/opencv2/flann/matrix.h-- Installing: /usr/local/include/opencv2/flann/object_factory.h-- Installing: /usr/local/include/opencv2/flann/index_testing.h-- Installing: /usr/local/include/opencv2/flann/dynamic_bitset.h-- Installing: /usr/local/include/opencv2/flann/autotuned_index.h-- Installing: /usr/local/include/opencv2/flann/dummy.h-- Installing: /usr/local/include/opencv2/flann/defines.h-- Installing: /usr/local/include/opencv2/flann/ground_truth.h-- Installing: /usr/local/include/opencv2/flann/simplex_downhill.h-- Installing: /usr/local/include/opencv2/flann/lsh_index.h-- Installing: /usr/local/include/opencv2/flann/all_indices.h-- Installing: /usr/local/include/opencv2/flann/composite_index.h-- Installing: /usr/local/include/opencv2/flann/params.h-- Installing: /usr/local/include/opencv2/flann/random.h-- Installing: /usr/local/include/opencv2/flann/kdtree_single_index.h-- Installing: /usr/local/include/opencv2/flann/logger.h-- Installing: /usr/local/include/opencv2/flann/allocator.h-- Installing: /usr/local/include/opencv2/flann/lsh_table.h-- Installing: /usr/local/lib/libopencv_imgproc.so.3.4.4-- Installing: /usr/local/lib/libopencv_imgproc.so.3.4-- Set runtime path of "/usr/local/lib/libopencv_imgproc.so.3.4.4" to "/usr/local/lib"-- Installing: /usr/local/lib/libopencv_imgproc.so-- Installing: /usr/local/include/opencv2/imgproc.hpp-- Installing: /usr/local/include/opencv2/imgproc/imgproc.hpp-- Installing: /usr/local/include/opencv2/imgproc/types_c.h-- Installing: /usr/local/include/opencv2/imgproc/imgproc_c.h-- Installing: /usr/local/include/opencv2/imgproc/hal/hal.hpp-- Installing: /usr/local/include/opencv2/imgproc/hal/interface.h-- Installing: /usr/local/include/opencv2/imgproc/detail/distortion_model.hpp-- Installing: /usr/local/lib/libopencv_ml.so.3.4.4-- Installing: /usr/local/lib/libopencv_ml.so.3.4-- Set runtime path of "/usr/local/lib/libopencv_ml.so.3.4.4" to "/usr/local/lib"-- Installing: /usr/local/lib/libopencv_ml.so-- Installing: /usr/local/include/opencv2/ml.hpp-- Installing: /usr/local/include/opencv2/ml/ml.hpp-- Installing: /usr/local/include/opencv2/ml/ml.inl.hpp-- Installing: /usr/local/lib/libopencv_photo.so.3.4.4-- Installing: /usr/local/lib/libopencv_photo.so.3.4-- Set runtime path of "/usr/local/lib/libopencv_photo.so.3.4.4" to "/usr/local/lib"-- Installing: /usr/local/lib/libopencv_photo.so-- Installing: /usr/local/include/opencv2/photo.hpp-- Installing: /usr/local/include/opencv2/photo/cuda.hpp-- Installing: /usr/local/include/opencv2/photo/photo.hpp-- Installing: /usr/local/include/opencv2/photo/photo_c.h-- Installing: /usr/local/lib/libopencv_video.so.3.4.4-- Installing: /usr/local/lib/libopencv_video.so.3.4-- Set runtime path of "/usr/local/lib/libopencv_video.so.3.4.4" to "/usr/local/lib"-- Installing: /usr/local/lib/libopencv_video.so-- Installing: /usr/local/include/opencv2/video.hpp-- Installing: /usr/local/include/opencv2/video/tracking.hpp-- Installing: /usr/local/include/opencv2/video/video.hpp-- Installing: /usr/local/include/opencv2/video/background_segm.hpp-- Installing: /usr/local/include/opencv2/video/tracking_c.h-- Installing: /usr/local/lib/libopencv_dnn.so.3.4.4-- Installing: /usr/local/lib/libopencv_dnn.so.3.4-- Set runtime path of "/usr/local/lib/libopencv_dnn.so.3.4.4" to "/usr/local/lib"-- Installing: /usr/local/lib/libopencv_dnn.so-- Installing: /usr/local/include/opencv2/dnn.hpp-- Installing: /usr/local/include/opencv2/dnn/layer.hpp-- Installing: /usr/local/include/opencv2/dnn/shape_utils.hpp-- Installing: /usr/local/include/opencv2/dnn/dnn.hpp-- Installing: /usr/local/include/opencv2/dnn/dict.hpp-- Installing: /usr/local/include/opencv2/dnn/all_layers.hpp-- Installing: /usr/local/include/opencv2/dnn/layer.details.hpp-- Installing: /usr/local/include/opencv2/dnn/dnn.inl.hpp-- Installing: /usr/local/lib/libopencv_imgcodecs.so.3.4.4-- Installing: /usr/local/lib/libopencv_imgcodecs.so.3.4-- Set runtime path of "/usr/local/lib/libopencv_imgcodecs.so.3.4.4" to "/usr/local/lib:/home/tf/anaconda3/lib"-- Installing: /usr/local/lib/libopencv_imgcodecs.so-- Installing: /usr/local/include/opencv2/imgcodecs.hpp-- Installing: /usr/local/include/opencv2/imgcodecs/imgcodecs.hpp-- Installing: /usr/local/include/opencv2/imgcodecs/imgcodecs_c.h-- Installing: /usr/local/include/opencv2/imgcodecs/ios.h-- Installing: /usr/local/lib/libopencv_shape.so.3.4.4-- Installing: /usr/local/lib/libopencv_shape.so.3.4-- Set runtime path of "/usr/local/lib/libopencv_shape.so.3.4.4" to "/usr/local/lib"-- Installing: /usr/local/lib/libopencv_shape.so-- Installing: /usr/local/include/opencv2/shape.hpp-- Installing: /usr/local/include/opencv2/shape/hist_cost.hpp-- Installing: /usr/local/include/opencv2/shape/shape.hpp-- Installing: /usr/local/include/opencv2/shape/shape_transformer.hpp-- Installing: /usr/local/include/opencv2/shape/shape_distance.hpp-- Installing: /usr/local/include/opencv2/shape/emdL1.hpp-- Installing: /usr/local/lib/libopencv_videoio.so.3.4.4-- Installing: /usr/local/lib/libopencv_videoio.so.3.4-- Set runtime path of "/usr/local/lib/libopencv_videoio.so.3.4.4" to "/usr/local/lib"-- Installing: /usr/local/lib/libopencv_videoio.so-- Installing: /usr/local/include/opencv2/videoio.hpp-- Installing: /usr/local/include/opencv2/videoio/videoio.hpp-- Installing: /usr/local/include/opencv2/videoio/registry.hpp-- Installing: /usr/local/include/opencv2/videoio/cap_ios.h-- Installing: /usr/local/include/opencv2/videoio/videoio_c.h-- Installing: /usr/local/lib/libopencv_highgui.so.3.4.4-- Installing: /usr/local/lib/libopencv_highgui.so.3.4-- Set runtime path of "/usr/local/lib/libopencv_highgui.so.3.4.4" to "/usr/local/lib"-- Installing: /usr/local/lib/libopencv_highgui.so-- Installing: /usr/local/include/opencv2/highgui.hpp-- Installing: /usr/local/include/opencv2/highgui/highgui.hpp-- Installing: /usr/local/include/opencv2/highgui/highgui_c.h-- Installing: /usr/local/lib/libopencv_superres.so.3.4.4-- Installing: /usr/local/lib/libopencv_superres.so.3.4-- Set runtime path of "/usr/local/lib/libopencv_superres.so.3.4.4" to "/usr/local/lib"-- Installing: /usr/local/lib/libopencv_superres.so-- Installing: /usr/local/include/opencv2/superres.hpp-- Installing: /usr/local/include/opencv2/superres/optical_flow.hpp-- Installing: /usr/local/lib/libopencv_features2d.so.3.4.4-- Installing: /usr/local/lib/libopencv_features2d.so.3.4-- Set runtime path of "/usr/local/lib/libopencv_features2d.so.3.4.4" to "/usr/local/lib"-- Installing: /usr/local/lib/libopencv_features2d.so-- Installing: /usr/local/include/opencv2/features2d.hpp-- Installing: /usr/local/include/opencv2/features2d/features2d.hpp-- Installing: /usr/local/include/opencv2/features2d/hal/interface.h-- Installing: /usr/local/lib/libopencv_calib3d.so.3.4.4-- Installing: /usr/local/lib/libopencv_calib3d.so.3.4-- Set runtime path of "/usr/local/lib/libopencv_calib3d.so.3.4.4" to "/usr/local/lib"-- Installing: /usr/local/lib/libopencv_calib3d.so-- Installing: /usr/local/include/opencv2/calib3d.hpp-- Installing: /usr/local/include/opencv2/calib3d/calib3d.hpp-- Installing: /usr/local/include/opencv2/calib3d/calib3d_c.h-- Installing: /usr/local/lib/libopencv_objdetect.so.3.4.4-- Installing: /usr/local/lib/libopencv_objdetect.so.3.4-- Set runtime path of "/usr/local/lib/libopencv_objdetect.so.3.4.4" to "/usr/local/lib"-- Installing: /usr/local/lib/libopencv_objdetect.so-- Installing: /usr/local/include/opencv2/objdetect.hpp-- Installing: /usr/local/include/opencv2/objdetect/objdetect.hpp-- Installing: /usr/local/include/opencv2/objdetect/detection_based_tracker.hpp-- Installing: /usr/local/include/opencv2/objdetect/objdetect_c.h-- Installing: /usr/local/lib/libopencv_stitching.so.3.4.4-- Installing: /usr/local/lib/libopencv_stitching.so.3.4-- Set runtime path of "/usr/local/lib/libopencv_stitching.so.3.4.4" to "/usr/local/lib"-- Installing: /usr/local/lib/libopencv_stitching.so-- Installing: /usr/local/include/opencv2/stitching.hpp-- Installing: /usr/local/include/opencv2/stitching/warpers.hpp-- Installing: /usr/local/include/opencv2/stitching/detail/matchers.hpp-- Installing: /usr/local/include/opencv2/stitching/detail/warpers.hpp-- Installing: /usr/local/include/opencv2/stitching/detail/seam_finders.hpp-- Installing: /usr/local/include/opencv2/stitching/detail/util.hpp-- Installing: /usr/local/include/opencv2/stitching/detail/util_inl.hpp-- Installing: /usr/local/include/opencv2/stitching/detail/timelapsers.hpp-- Installing: /usr/local/include/opencv2/stitching/detail/camera.hpp-- Installing: /usr/local/include/opencv2/stitching/detail/autocalib.hpp-- Installing: /usr/local/include/opencv2/stitching/detail/exposure_compensate.hpp-- Installing: /usr/local/include/opencv2/stitching/detail/warpers_inl.hpp-- Installing: /usr/local/include/opencv2/stitching/detail/motion_estimators.hpp-- Installing: /usr/local/include/opencv2/stitching/detail/blenders.hpp-- Installing: /usr/local/lib/libopencv_videostab.so.3.4.4-- Installing: /usr/local/lib/libopencv_videostab.so.3.4-- Set runtime path of "/usr/local/lib/libopencv_videostab.so.3.4.4" to "/usr/local/lib"-- Installing: /usr/local/lib/libopencv_videostab.so-- Installing: /usr/local/include/opencv2/videostab.hpp-- Installing: /usr/local/include/opencv2/videostab/motion_core.hpp-- Installing: /usr/local/include/opencv2/videostab/frame_source.hpp-- Installing: /usr/local/include/opencv2/videostab/optical_flow.hpp-- Installing: /usr/local/include/opencv2/videostab/outlier_rejection.hpp-- Installing: /usr/local/include/opencv2/videostab/deblurring.hpp-- Installing: /usr/local/include/opencv2/videostab/fast_marching.hpp-- Installing: /usr/local/include/opencv2/videostab/ring_buffer.hpp-- Installing: /usr/local/include/opencv2/videostab/stabilizer.hpp-- Installing: /usr/local/include/opencv2/videostab/wobble_suppression.hpp-- Installing: /usr/local/include/opencv2/videostab/inpainting.hpp-- Installing: /usr/local/include/opencv2/videostab/motion_stabilizing.hpp-- Installing: /usr/local/include/opencv2/videostab/fast_marching_inl.hpp-- Installing: /usr/local/include/opencv2/videostab/global_motion.hpp-- Installing: /usr/local/include/opencv2/videostab/log.hpp-- Installing: /usr/local/python/cv2/python-2.7/cv2.so-- Set runtime path of "/usr/local/python/cv2/python-2.7/cv2.so" to "/usr/local/lib"-- Installing: /usr/local/python/cv2/config-2.7.py-- Installing: /usr/local/share/OpenCV/haarcascades/haarcascade_frontalface_alt.xml-- Installing: /usr/local/share/OpenCV/haarcascades/haarcascade_frontalcatface.xml-- Installing: /usr/local/share/OpenCV/haarcascades/haarcascade_frontalface_alt2.xml-- Installing: /usr/local/share/OpenCV/haarcascades/haarcascade_fullbody.xml-- Installing: /usr/local/share/OpenCV/haarcascades/haarcascade_eye.xml-- Installing: /usr/local/share/OpenCV/haarcascades/haarcascade_lefteye_2splits.xml-- Installing: /usr/local/share/OpenCV/haarcascades/haarcascade_frontalcatface_extended.xml-- Installing: /usr/local/share/OpenCV/haarcascades/haarcascade_frontalface_alt_tree.xml-- Installing: /usr/local/share/OpenCV/haarcascades/haarcascade_righteye_2splits.xml-- Installing: /usr/local/share/OpenCV/haarcascades/haarcascade_profileface.xml-- Installing: /usr/local/share/OpenCV/haarcascades/haarcascade_smile.xml-- Installing: /usr/local/share/OpenCV/haarcascades/haarcascade_russian_plate_number.xml-- Installing: /usr/local/share/OpenCV/haarcascades/haarcascade_upperbody.xml-- Installing: /usr/local/share/OpenCV/haarcascades/haarcascade_frontalface_default.xml-- Installing: /usr/local/share/OpenCV/haarcascades/haarcascade_licence_plate_rus_16stages.xml-- Installing: /usr/local/share/OpenCV/haarcascades/haarcascade_lowerbody.xml-- Installing: /usr/local/share/OpenCV/haarcascades/haarcascade_eye_tree_eyeglasses.xml-- Installing: /usr/local/share/OpenCV/lbpcascades/lbpcascade_profileface.xml-- Installing: /usr/local/share/OpenCV/lbpcascades/lbpcascade_frontalface_improved.xml-- Installing: /usr/local/share/OpenCV/lbpcascades/lbpcascade_frontalface.xml-- Installing: /usr/local/share/OpenCV/lbpcascades/lbpcascade_silverware.xml-- Installing: /usr/local/share/OpenCV/lbpcascades/lbpcascade_frontalcatface.xml-- Installing: /usr/local/bin/opencv_traincascade-- Set runtime path of "/usr/local/bin/opencv_traincascade" to "/usr/local/lib"-- Installing: /usr/local/bin/opencv_createsamples-- Set runtime path of "/usr/local/bin/opencv_createsamples" to "/usr/local/lib"-- Installing: /usr/local/bin/opencv_annotation-- Set runtime path of "/usr/local/bin/opencv_annotation" to "/usr/local/lib"-- Installing: /usr/local/bin/opencv_visualisation-- Set runtime path of "/usr/local/bin/opencv_visualisation" to "/usr/local/lib"-- Installing: /usr/local/bin/opencv_interactive-calibration-- Set runtime path of "/usr/local/bin/opencv_interactive-calibration" to "/usr/local/lib"-- Installing: /usr/local/bin/opencv_version-- Set runtime path of "/usr/local/bin/opencv_version" to "/usr/local/lib"]]></content>
<categories>
<category>图像处理</category>
</categories>
<tags>
<tag>OpenCV</tag>
</tags>
</entry>
<entry>
<title><![CDATA[安装TensorFlow-GPU]]></title>
<url>%2F2018-11-19-%E5%AE%89%E8%A3%85TensorFlow-GPU.html</url>
<content type="text"><![CDATA[安装GPU版本TensorFlow准备– 干净的系统,没有安装过Python,有的话就卸载了。 另外我的系统安装了VS2015 VS2017(这里我不知道是不是必备的)。现在TensorFlow和cuda以及cuDNN品名升级,所以这里采用了几乎是最新版的了(2018年11月19日) Anaconda——清华tuna下载 显卡驱动——点我去英伟达官网自行下载对应驱动 cuda9.0安装包——点我去百度云下载 cuDNN7.x安装包——点我去百度云下载 安装– 1、安装Anaconda 这里省略。注意一点,安装的选项加入path,都勾选。2、安装显卡驱动 默认安装。3、安装cuda9.0 默认安装。4、安装cuDNN 7.x 将压缩包解压,放在C:\ProgramData\NVIDIA GPU Computing Toolkit\v9.0这个目录下。然后将目录C:\ProgramData\NVIDIA GPU Computing Toolkit\v9.0\bin添加到环境变量PATH里。 验证– 1、启动Anaconda Prompt 输入conda env list 显示只有一个base或者root的环境。表示只有一个环境。 2、修改Anaconda的软件源 执行123conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main/conda config --set show_channel_urls yes 表示将anaconda的软件下载源修改成清华Tuna的了。 3、创建用于TensorFlow的Python环境1234 conda create -n tf-gpu-py3.5 python=3.5``` 例子: D:\Users\zyb>conda create -n tf-gpu-py3.5 python=3.5 Solving environment: done ## Package Plan ## environment location: C:\anaconda35\envs\tf-gpu-py3.5 added / updated specs: - python=3.5 The following NEW packages will be INSTALLED: certifi: 2018.8.24-py35_1001 https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge pip: 18.0-py35_1001 https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge python: 3.5.5-he025d50_2 https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge setuptools: 40.4.3-py35_0 https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge vc: 14.1-h21ff451_1 https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/peterjc123 vs2017_runtime: 15.4.27004.2010-1 https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/peterjc123 wheel: 0.32.0-py35_1000 https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge wincertstore: 0.2-py35_1002 https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge Proceed ([y]/n)? y Preparing transaction: done Verifying transaction: done Executing transaction: done # # To activate this environment, use # # $ conda activate tf-gpu-py3.5 # # To deactivate an active environment, use # # $ conda deactivate 14、激活刚刚创建的环境 conda activate tf-gpu-py3.5 15、安装TensorFlow GPU版 conda install tensorflow-gpu 16、代码验证 启动python 输入如下代码 import tensorflow as tf 1查看是否报错。 如果报错,就使用conda install 包名(比如numpy) 如果不报错,接着执行 a = tf.constant([1.0,2.0,3.0,4.0,5.0,6.0],shape=[2,3],name='a') b = tf.constant([1.0,2.0,3.0,4.0,5.0,6.0],shape=[3,2],name='b') c = tf.matmul(a,b) sess = tf.Session(config=tf.ConfigProto(log_device_placement=True)) #这步结束之后,会出现一个警告: #Device mapping: no known devices. #2018-11-19 22:18:15.899459: I T:\src\github\tensorflow\tensorflow\core\common_runtime\direct_session.cc:288] Device mapping: #不用管,执行下一步 print(sess.run(c)) #输出如下: MatMul: (MatMul): /job:localhost/replica:0/task:0/device:CPU:0 2018-11-19 22:18:23.059234: I T:\src\github\tensorflow\tensorflow\core\common_runtime\placer.cc:935] MatMul: (MatMul)/job:localhost/replica:0/task:0/device:CPU:0 a: (Const): /job:localhost/replica:0/task:0/device:CPU:0 2018-11-19 22:18:23.064109: I T:\src\github\tensorflow\tensorflow\core\common_runtime\placer.cc:935] a: (Const)/job:localhost/replica:0/task:0/device:CPU:0 b: (Const): /job:localhost/replica:0/task:0/device:CPU:0 2018-11-19 22:18:23.069134: I T:\src\github\tensorflow\tensorflow\core\common_runtime\placer.cc:935] b: (Const)/job:localhost/replica:0/task:0/device:CPU:0 [[22. 28.] [49. 64.]] 1234567891011121314151617验证成功。## Ubuntu下安装GPU版TensorFlow=======================### 准备--> 1、Anaconda-Linux版本的——去清华tuna自行下载 > 2、显卡驱动——去官网自行下载 [点我去百度云下载3、4需要的文件](https://pan.baidu.com/s/1MjSKSkMKHjfqoY5nGuIXTQ) > 3、cuda9.0——去官网自行下载Linux版本的 > 4、cuDNN7.x——去官网下载Linux版本的(需要注册并且join)### 安装--1、Anaconda安装 这里需要注意,直接把软件安装在自己的家目录下即可。 安装完anaconda之后,需要去刷新你的环境变量。 source ~/home/tf/.bashrc 1232、安装显卡驱动 官网下载驱动,然后使用sudo安装。 安装的过程中,第一步需要你阅读安装协议。使用q退出。 3、安装cuda9.0 默认安装。 安装的过程中,第一步需要你阅读安装协议。使用q退出。 9.0有一个base安装包还有4个升级包。都是有序号的。 使用`sudo chmod +x *.run`给这5个文件加上可执行权限 然后一个个安装。 tf@lolita-ThinkStation-P318:~$ ls anaconda3 cuda_9.0.176.1_linux-1.run cuda_9.0.176_384.81_linux-base.run cuda_9.0.176.4_linux-4.run Anaconda3-5.3.0-Linux-x86_64.sh cuda_9.0.176.2_linux-2.run cuda_9.0.176.3_linux-3.run examples.desktop tf@lolita-ThinkStation-P318:~$ ./cuda_9.0.176_384.81_linux-base.run Logging to /tmp/cuda_install_6527.log Using more to view the EULA. End User License Agreement -------------------------- Preface ------- The Software License Agreement in Chapter 1 and the Supplement in Chapter 2 contain license terms and conditions that govern the use of NVIDIA software. By accepting this agreement, you agree to comply with all the terms and conditions applicable to the product(s) included herein. NVIDIA Driver Description This package contains the operating system driver and fundamental system software components for NVIDIA GPUs. NVIDIA CUDA Toolkit Description The NVIDIA CUDA Toolkit provides command-line and graphical tools for building, debugging and optimizing the performance of applications accelerated by NVIDIA GPUs, runtime and math libraries, and documentation including programming guides, user manuals, and API references. Do you accept the previously read EULA? accept/decline/quit: accept Install NVIDIA Accelerated Graphics Driver for Linux-x86_64 384.81? (y)es/(n)o/(q)uit: n Install the CUDA 9.0 Toolkit? (y)es/(n)o/(q)uit: y Enter Toolkit Location [ default is /usr/local/cuda-9.0 ]: /usr/local/cuda-9.0 is not writable. Do you wish to run the installation with 'sudo'? (y)es/(n)o: y Please enter your password: Do you want to install a symbolic link at /usr/local/cuda? (y)es/(n)o/(q)uit: n Install the CUDA 9.0 Samples? (y)es/(n)o/(q)uit: y Enter CUDA Samples Location [ default is /home/tf ]: Installing the CUDA Toolkit in /usr/local/cuda-9.0 ... Installing the CUDA Samples in /home/tf ... Copying samples to /home/tf/NVIDIA_CUDA-9.0_Samples now... Finished copying samples. =========== = Summary = =========== Driver: Not Selected Toolkit: Installed in /usr/local/cuda-9.0 Samples: Installed in /home/tf Please make sure that - PATH includes /usr/local/cuda-9.0/bin - LD_LIBRARY_PATH includes /usr/local/cuda-9.0/lib64, or, add /usr/local/cuda-9.0/lib64 to /etc/ld.so.conf and run ldconfig as root To uninstall the CUDA Toolkit, run the uninstall script in /usr/local/cuda-9.0/bin Please see CUDA_Installation_Guide_Linux.pdf in /usr/local/cuda-9.0/doc/pdf for detailed information on setting up CUDA. ***WARNING: Incomplete installation! This installation did not install the CUDA Driver. A driver of version at least 384.00 is required for CUDA 9.0 functionality to work. To install the driver using this installer, run the following command, replacing <CudaInstaller> with the name of this run file: sudo <CudaInstaller>.run -silent -driver Logfile is /tmp/cuda_install_6527.log tf@lolita-ThinkStation-P318:~$ ./cuda_9.0.176.1_linux-1.run Logging to /tmp/cuda_patch_7307.log Welcome to the CUDA Patcher. Detected pager as 'more'. End User License Agreement -------------------------- Preface ------- The Software License Agreement in Chapter 1 and the Supplement in Chapter 2 contain license terms and conditions that govern the use of NVIDIA software. By accepting this agreement, you agree to comply with all the terms and conditions applicable to the product(s) included herein. NVIDIA Driver Description This package contains the operating system driver and fundamental system software components for NVIDIA GPUs. NVIDIA CUDA Toolkit Description The NVIDIA CUDA Toolkit provides command-line and graphical tools for building, debugging and optimizing the performance of applications accelerated by NVIDIA GPUs, runtime and math libraries, and documentation including programming guides, user manuals, and API references. Do you accept the previously read EULA? accept/decline/quit: accept Enter CUDA Toolkit installation directory [ default is /usr/local/cuda-9.0 ]: Installation directory '/usr/local/cuda-9.0' is not writable! Ensure you are running with the correct permissions. Options: --silent : Specify a command-line, silent installation --installdir=dir : Customize installation directory --accept-eula : Implies acceptance of the EULA --help : Print help message Specifying a silent installation also initiates a command-line installation. tf@lolita-ThinkStation-P318:~$ ./cuda_9.0.176.2_linux-2.run Logging to /tmp/cuda_patch_7348.log Welcome to the CUDA Patcher. Detected pager as 'more'. End User License Agreement -------------------------- Preface ------- The Software License Agreement in Chapter 1 and the Supplement in Chapter 2 contain license terms and conditions that govern the use of NVIDIA software. By accepting this agreement, you agree to comply with all the terms and conditions applicable to the product(s) included herein. NVIDIA Driver Description This package contains the operating system driver and fundamental system software components for NVIDIA GPUs. NVIDIA CUDA Toolkit Description The NVIDIA CUDA Toolkit provides command-line and graphical tools for building, debugging and optimizing the performance of applications accelerated by NVIDIA GPUs, runtime and math libraries, and documentation including programming guides, user manuals, and API references. Do you accept the previously read EULA? accept/decline/quit: accept Enter CUDA Toolkit installation directory [ default is /usr/local/cuda-9.0 ]: Installation directory '/usr/local/cuda-9.0' is not writable! Ensure you are running with the correct permissions. Options: --silent : Specify a command-line, silent installation --installdir=dir : Customize installation directory --accept-eula : Implies acceptance of the EULA --help : Print help message Specifying a silent installation also initiates a command-line installation. tf@lolita-ThinkStation-P318:~$ ./cuda_9.0.176.3_linux-3.run Logging to /tmp/cuda_patch_7387.log Welcome to the CUDA Patcher. Detected pager as 'more'. End User License Agreement -------------------------- Preface ------- The Software License Agreement in Chapter 1 and the Supplement in Chapter 2 contain license terms and conditions that govern the use of NVIDIA software. By accepting this agreement, you agree to comply with all the terms and conditions applicable to the product(s) included herein. NVIDIA Driver Description This package contains the operating system driver and fundamental system software components for NVIDIA GPUs. NVIDIA CUDA Toolkit Description The NVIDIA CUDA Toolkit provides command-line and graphical tools for building, debugging and optimizing the performance of applications accelerated by NVIDIA GPUs, runtime and math libraries, and documentation including programming guides, user manuals, and API references. Do you accept the previously read EULA? accept/decline/quit: accept Enter CUDA Toolkit installation directory [ default is /usr/local/cuda-9.0 ]: Installation directory '/usr/local/cuda-9.0' is not writable! Ensure you are running with the correct permissions. Options: --silent : Specify a command-line, silent installation --installdir=dir : Customize installation directory --accept-eula : Implies acceptance of the EULA --help : Print help message Specifying a silent installation also initiates a command-line installation. tf@lolita-ThinkStation-P318:~$ ./cuda_9.0.176.4_linux-4.run Logging to /tmp/cuda_patch_7428.log Welcome to the CUDA Patcher. Detected pager as 'more'. End User License Agreement -------------------------- Preface ------- The Software License Agreement in Chapter 1 and the Supplement in Chapter 2 contain license terms and conditions that govern the use of NVIDIA software. By accepting this agreement, you agree to comply with all the terms and conditions applicable to the product(s) included herein. NVIDIA Driver Description This package contains the operating system driver and fundamental system software components for NVIDIA GPUs. NVIDIA CUDA Toolkit Description The NVIDIA CUDA Toolkit provides command-line and graphical tools for building, debugging and optimizing the performance of applications accelerated by NVIDIA GPUs, runtime and math libraries, and documentation including programming guides, user manuals, and API references. Do you accept the previously read EULA? accept/decline/quit: accept Enter CUDA Toolkit installation directory [ default is /usr/local/cuda-9.0 ]: Installation directory '/usr/local/cuda-9.0' is not writable! Ensure you are running with the correct permissions. Options: --silent : Specify a command-line, silent installation --installdir=dir : Customize installation directory --accept-eula : Implies acceptance of the EULA --help : Print help message Specifying a silent installation also initiates a command-line installation. 12然后将安装完后的路径加入PATH环境变量。 export PATH=/usr/local/cuda-9.0/bin:/usr/local/cuda-9.0/lib64:$PATH export LD_LIBRARY_PATH=/usr/local/cuda-9.0/lib64:$LD_LIBRARY_PATH #使环境变量生效 source ~/home/tf/.bashrc 14、安装cuDNN 解压出来两个文件夹一个是include 一个是lib64 tf@lolita-ThinkStation-P318:~$ tar zxvf cudnn-9.0-linux-x64-v7.3.1.20.tar.gz cuda/include/cudnn.h cuda/NVIDIA_SLA_cuDNN_Support.txt cuda/lib64/libcudnn.so cuda/lib64/libcudnn.so.7 cuda/lib64/libcudnn.so.7.3.1 cuda/lib64/libcudnn_static.a tf@lolita-ThinkStation-P318:~$ ls anaconda3 cuda_9.0.176.1_linux-1.run cuda_9.0.176.3_linux-3.run examples.desktop Anaconda3-5.3.0-Linux-x86_64.sh cuda_9.0.176.2_linux-2.run cuda_9.0.176.4_linux-4.run NVIDIA_CUDA-9.0_Samples cuda cuda_9.0.176_384.81_linux-base.run cudnn-9.0-linux-x64-v7.3.1.20.tar.gz tf@lolita-ThinkStation-P318:~$ sudo mv cuda/include/cudnn.h /usr/local/cuda-9.0/include/ tf@lolita-ThinkStation-P318:~$ sudo mv cuda/lib64/* /usr/local/cuda-9.0/lib64/ 12345## 验证--0、cuda验证 #进入样本目录 cd ~/home/tf/NVIDIA_CUDA-9.0_Samples #编译样本 make -j8 #进入生成可执行文件的目录 cd bin/x86_64/linux/release #执行设备测试程序 ./deviceQuery #输出如下 ./deviceQuery Starting... CUDA Device Query (Runtime API) version (CUDART static linking) Detected 1 CUDA Capable device(s) Device 0: "GeForce GTX 1070" CUDA Driver Version / Runtime Version 10.0 / 9.0 CUDA Capability Major/Minor version number: 6.1 Total amount of global memory: 8116 MBytes (8510701568 bytes) (15) Multiprocessors, (128) CUDA Cores/MP: 1920 CUDA Cores GPU Max Clock rate: 1683 MHz (1.68 GHz) Memory Clock rate: 4004 Mhz Memory Bus Width: 256-bit L2 Cache Size: 2097152 bytes Maximum Texture Dimension Size (x,y,z) 1D=(131072), 2D=(131072, 65536), 3D=(16384, 16384, 16384) Maximum Layered 1D Texture Size, (num) layers 1D=(32768), 2048 layers Maximum Layered 2D Texture Size, (num) layers 2D=(32768, 32768), 2048 layers Total amount of constant memory: 65536 bytes Total amount of shared memory per block: 49152 bytes Total number of registers available per block: 65536 Warp size: 32 Maximum number of threads per multiprocessor: 2048 Maximum number of threads per block: 1024 Max dimension size of a thread block (x,y,z): (1024, 1024, 64) Max dimension size of a grid size (x,y,z): (2147483647, 65535, 65535) Maximum memory pitch: 2147483647 bytes Texture alignment: 512 bytes Concurrent copy and kernel execution: Yes with 2 copy engine(s) Run time limit on kernels: Yes Integrated GPU sharing Host Memory: No Support host page-locked memory mapping: Yes Alignment requirement for Surfaces: Yes Device has ECC support: Disabled Device supports Unified Addressing (UVA): Yes Supports Cooperative Kernel Launch: Yes Supports MultiDevice Co-op Kernel Launch: Yes Device PCI Domain ID / Bus ID / location ID: 0 / 1 / 0 Compute Mode: < Default (multiple host threads can use ::cudaSetDevice() with device simultaneously) > deviceQuery, CUDA Driver = CUDART, CUDA Driver Version = 10.0, CUDA Runtime Version = 9.0, NumDevs = 1 Result = PASS #看到PASS后执行带宽测试 ./bandwidthTest #输出如下: [CUDA Bandwidth Test] - Starting... Running on... Device 0: GeForce GTX 1070 Quick Mode Host to Device Bandwidth, 1 Device(s) PINNED Memory Transfers Transfer Size (Bytes) Bandwidth(MB/s) 33554432 12758.2 Device to Host Bandwidth, 1 Device(s) PINNED Memory Transfers Transfer Size (Bytes) Bandwidth(MB/s) 33554432 12867.2 Device to Device Bandwidth, 1 Device(s) PINNED Memory Transfers Transfer Size (Bytes) Bandwidth(MB/s) 33554432 191582.5 Result = PASS NOTE: The CUDA Samples are not meant for performance measurements. Results may vary when GPU Boost is enabled. #看到PASS表示测试通过,如果FAIL,重启然后重新执行即可。 121、创建anaconda环境(和Windows一样) conda create -n tf-gpu-py3.5 python=3.5 # # To activate this environment, use # # $ conda activate tf-gpu-py3.5 # # To deactivate an active environment, use # # $ conda deactivate 12、激活`tf-gpu-py3.5` conda activate tf-py-3.5-cpu 13、安装`tensorflow-gpu` conda install tensorflow-gpu 14、代码验证 (tf-gpu-py3.5) tf@lolita-ThinkStation-P318:~/anaconda3/envs$ python Python 3.5.6 |Anaconda, Inc.| (default, Aug 26 2018, 21:41:56) [GCC 7.3.0] on linux Type "help", "copyright", "credits" or "license" for more information. >>> import tensorflow as tf >>> a = tf.constant([1.0,2.0,3.0,4.0,5.0,6.0],shape=[2,3],name='a') >>> b = tf.constant([1.0,2.0,3.0,4.0,5.0,6.0],shape=[3,2],name='b') >>> c = tf.matmul(a,b) >>> sess = tf.Session(config=tf.ConfigProto(log_device_placement=True)) 2018-11-19 22:43:27.732910: I tensorflow/core/platform/cpu_feature_guard.cc:141] Your CPU supports instructions that this TensorFlow binary was not compiled to use: SSE4.1 SSE4.2 AVX AVX2 FMA 2018-11-19 22:43:27.824810: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:897] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero 2018-11-19 22:43:27.825419: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1405] Found device 0 with properties: name: GeForce GTX 1070 major: 6 minor: 1 memoryClockRate(GHz): 1.683 pciBusID: 0000:01:00.0 totalMemory: 7.93GiB freeMemory: 7.64GiB 2018-11-19 22:43:27.825445: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1484] Adding visible gpu devices: 0 2018-11-19 22:43:27.995777: I tensorflow/core/common_runtime/gpu/gpu_device.cc:965] Device interconnect StreamExecutor with strength 1 edge matrix: 2018-11-19 22:43:27.995806: I tensorflow/core/common_runtime/gpu/gpu_device.cc:971] 0 2018-11-19 22:43:27.995826: I tensorflow/core/common_runtime/gpu/gpu_device.cc:984] 0: N 2018-11-19 22:43:27.996035: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1097] Created TensorFlow device (/job:localhost/replica:0/task:0/device:GPU:0 with 7377 MB memory) -> physical GPU (device: 0, name: GeForce GTX 1070, pci bus id: 0000:01:00.0, compute capability: 6.1) Device mapping: /job:localhost/replica:0/task:0/device:GPU:0 -> device: 0, name: GeForce GTX 1070, pci bus id: 0000:01:00.0, compute capability: 6.1 2018-11-19 22:43:28.026839: I tensorflow/core/common_runtime/direct_session.cc:288] Device mapping: /job:localhost/replica:0/task:0/device:GPU:0 -> device: 0, name: GeForce GTX 1070, pci bus id: 0000:01:00.0, compute capability: 6.1 >>> print(sess.run(c)) MatMul: (MatMul): /job:localhost/replica:0/task:0/device:GPU:0 2018-11-19 22:44:23.662448: I tensorflow/core/common_runtime/placer.cc:935] MatMul: (MatMul)/job:localhost/replica:0/task:0/device:GPU:0 a: (Const): /job:localhost/replica:0/task:0/device:GPU:0 2018-11-19 22:44:23.662561: I tensorflow/core/common_runtime/placer.cc:935] a: (Const)/job:localhost/replica:0/task:0/device:GPU:0 b: (Const): /job:localhost/replica:0/task:0/device:GPU:0 2018-11-19 22:44:23.662589: I tensorflow/core/common_runtime/placer.cc:935] b: (Const)/job:localhost/replica:0/task:0/device:GPU:0 [[22. 28.] [49. 64.]] `验证完毕。]]></content>
<categories>
<category>Python</category>
<category>TensorFlow</category>
</categories>
<tags>
<tag>深度学习</tag>
</tags>
</entry>
<entry>
<title><![CDATA[Linux知识点]]></title>
<url>%2F2018-11-14-Linux%E7%9F%A5%E8%AF%86%E7%82%B9.html</url>
<content type="text"><![CDATA[环境变量 env查询所有环境变量 [root@dhu021 home]# env HOSTNAME=dhu021 TERM=xterm SHELL=/bin/bash HISTSIZE=1000 SSH_CLIENT=202.121.144.19 8577 22 SSH_TTY=/dev/pts/0 USER=root LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=01;05;37;41:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arj=01;31:*.taz=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lz=01;31:*.xz=01;31:*.bz2=01;31:*.tbz=01;31:*.tbz2=01;31:*.bz=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.rar=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.axv=01;35:*.anx=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=01;36:*.au=01;36:*.flac=01;36:*.mid=01;36:*.midi=01;36:*.mka=01;36:*.mp3=01;36:*.mpc=01;36:*.ogg=01;36:*.ra=01;36:*.wav=01;36:*.axa=01;36:*.oga=01;36:*.spx=01;36:*.xspf=01;36: MAIL=/var/spool/mail/root PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin PWD=/home LANG=en_US.UTF-8 HISTCONTROL=ignoredups SHLVL=1 HOME=/root LOGNAME=root CVS_RSH=ssh SSH_CONNECTION=202.**.**.** 8577 172.1**.**.** 22 LESSOPEN=||/usr/bin/lesspipe.sh %s LE_WORKING_DIR=/root/.acme.sh G_BROKEN_FILENAMES=1 _=/bin/env OLDPWD=/root [root@dhu021 home]# env | grep PATH PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin]]></content>
<categories>
<category>Linux</category>
</categories>
<tags>
<tag>Linux</tag>
</tags>
</entry>
<entry>
<title><![CDATA[Java虚拟机]]></title>
<url>%2F2018-11-14-Java%E8%99%9A%E6%8B%9F%E6%9C%BA.html</url>
<content type="text"><![CDATA[JAVA工作方式源程序(myProgram.java) – > 编译(javac myProgram.java) -> JAVA字节码(myProgram.class) ->运行(java myProgram) JAVA的程序结构源文件>类>方法>语句(source file > class > method > statement) JDK、JRE、JVM的区别 JVM(Java Virtual Machine):JAVA虚拟机 JDK(Java Developer’s Kit):Java开发工具包 JRE(Java runtime environment):Java 运行环境 JVM主要包括四个部分1.类加载器(ClassLoader):在JVM启动时或者在类运行时将需要的class加载到JVM中。 2.执行引擎:负责执行class文件中包含的字节码指令 3.内存区(也叫运行时数据区):是在JVM运行的时候操作所分配的内存区。运行时内存区主要可以划分为5个区域,如图: 方法区(Method Area):用于存储类结构信息的地方,包括常量池、静态变量、构造函数等。虽然JVM规范把方法区描述为堆的一个逻辑部分, 但它却有个别名non-heap(非堆),所以大家不要搞混淆了。方法区还包含一个运行时常量池。 java堆(Heap):存储java实例或者对象的地方。这块是GC的主要区域(后面解释)。从存储的内容我们可以很容易知道,方法区和堆是被所有java线程共享的。 java栈(Stack):java栈总是和线程关联在一起,每当创建一个线程时,JVM就会为这个线程创建一个对应的java栈。在这个java栈中又会包含多个栈帧,每运行一个方法就创建一个栈帧,用于存储局部变量表、操作栈、方法返回值等。每一个方法从调用直至执行完成的过程,就对应一个栈帧在java栈中入栈到出栈的过程。所以java栈是现成私有的。 程序计数器(PC Register):用于保存当前线程执行的内存地址。由于JVM程序是多线程执行的(线程轮流切换),所以为了保证线程切换回来后,还能恢复到原先状态,就需要一个独立的计数器,记录之前中断的地方,可见程序计数器也是线程私有的。 本地方法栈(Native Method Stack):和java栈的作用差不多,只不过是为JVM使用到的native方法服务的 4.本地方法接口:主要是调用C或C++实现的本地方法及返回结果。 JVM在整个JDK中处于最底层,负责与操作系统的交互,用来屏蔽操作系统环境,提供一个王正的Java运行环境,因此也称为虚拟计算机。操作系统装入JVM是通过JDK中的java.exe来实现,主要以下几步: 1.创建jvm装载环境和配置 2.装载jvm.dll 3.初始化jvm.dll 4.调用JNIEnv实例装载并处理class类 5.运行java程序 JVM初识及工作原理 1)类加载子系统负责从文件系统或者网络中加载Class信息,加载的类信息存放于一块称为方法区的内存空间。除了类的信息外,方法区中可能还会存放运行时常量池信息,包括字符串字面量和数字常量(这部分常量信息是Class文件中常量池部分的内存映射)。 2)java堆在虚拟机启动的时候建立,它是java程序最主要的内存工作区域。几乎所有的java对象实例都存放在java堆中。堆空间是所有线程共享的,这是一块与java应用密切相关的内存空间。 3)java的NIO库允许java程序使用直接内存。直接内存是在java堆外的、直接向系统申请的内存空间。通常访问直接内存的速度会优于java堆。因此出于性能的考虑,读写频繁的场合可能会考虑使用直接内存。由于直接内存在java堆外,因此它的大小不会直接受限于Xmx指定的最大堆大小,但是系统内存是有限的,java堆和直接内存的总和依然受限于操作系统能给出的最大内存。 4)垃圾回收系统是java虚拟机的重要组成部分,垃圾回收器可以对方法区、java堆和直接内存进行回收。其中,java堆是垃圾收集器的工作重点。和C/C++不同,java中所有的对象空间释放都是隐式的,也就是说,java中没有类似free()或者delete()这样的函数释放指定的内存区域。对于不再使用的垃圾对象,垃圾回收系统会在后台默默工作,默默查找、标识并释放垃圾对象,完成包括java堆、方法区和直接内存中的全自动化管理。 5)每一个java虚拟机线程都有一个私有的java栈,一个线程的java栈在线程创建的时候被创建,java栈中保存着帧信息,java栈中保存着局部变量、方法参数,同时和java方法的调用、返回密切相关。 6)本地方法栈和java栈非常类似,最大的不同在于java栈用于方法的调用,而本地方法栈则用于本地方法的调用,作为对java虚拟机的重要扩展,java虚拟机允许java直接调用本地方法(通常使用C编写) 7)PC(Program Counter)寄存器也是每一个线程私有的空间,java虚拟机会为每一个java线程创建PC寄存器。在任意时刻,一个java线程总是在执行一个方法,这个正在被执行的方法称为当前方法。如果当前方法不是本地方法,PC寄存器就会指向当前正在被执行的指令。如果当前方法是本地方法,那么PC寄存器的值就是undefined 8)执行引擎是java虚拟机的最核心组件之一,它负责执行虚拟机的字节码,现代虚拟机为了提高执行效率,会使用即时编译技术将方法编译成机器码后再执行。 java堆java堆是和应用程序关系最为密切的内存空间,几乎所有的对象都存放在堆上。并且java堆是完全自动化管理的,通过垃圾回收机制,垃圾对象会被自动清理,而不需要显示的释放。 根据java回收机制的不同,java堆有可能拥有不同的结构。最为常见的一种构成是将整个java堆分为新生代和老年代。其中新生代存放新生对象或者年龄不大的对象,老年代则存放老年对象。新生代有可能分为eden区、s0区、s1区,s0区和s1区也被称为from和to区,他们是两块大小相同、可以互换角色的内存空间。 如下图:显示了一个堆空间的一般结构: 在绝大多数情况下,对象首先分配在eden区,在一次新生代回收之后,如果对象还存活,则进入s0或者s1,每经过一次新生代回收,对象如果存活,它的年龄就会加1。当对象的年龄达到一定条件后,就会被认为是老年对象,从而进入老年代。 public class SimpleHeap { private int id; public SimpleHeap(int id){ this.id = id; } public void show(){ System.out.println("My id is "+id); } public static void main(String[] args) { SimpleHeap s1 = new SimpleHeap(1); SimpleHeap s2 = new SimpleHeap(2); s1.show(); s2.show(); } } 该代码声明了一个类,并在main函数中创建了两个SimpleHeap实例。此时,各对象和局部变量的存放情况如图: SimpleHeap实例本身分配在堆中,描述SimpleHeap类的信息存放在方法区,main函数中的s1 s2局部变量存放在java栈上,并指向堆中两个实例。 java栈java栈是一块线程私有的内存空间。如果说,java堆和程序数据密切相关,那么java栈就是和线程执行密切相关。线程执行的基本行为是函数调用,每次函数调用的数据都是通过java栈传递的。 java栈与数据结构上的栈有着类似的含义,它是一块先进后出的数据结构,只支持出栈和进栈两种操作,在java栈中保存的主要内容为栈帧。每一次函数调用,都会有一个对应的栈帧被压入java栈,每一个函数调用结束,都会有一个栈帧被弹出java栈。如下图:栈帧和函数调用。函数1对应栈帧1,函数2对应栈帧2,依次类推。函数1中调用函数2,函数2中调用函数3,函数3调用函数4.当函数1被调用时,栈帧1入栈,当函数2调用时,栈帧2入栈,当函数3被调用时,栈帧3入栈,当函数4被调用时,栈帧4入栈。当前正在执行的函数所对应的帧就是当前帧(位于栈顶),它保存着当前函数的局部变量、中间计算结果等数据。 当函数返回时,栈帧从java栈中被弹出,java方法区有两种返回函数的方式,一种是正常的函数返回,使用return指令,另一种是抛出异常。不管使用哪种方式,都会导致栈帧被弹出。 在一个栈帧中,至少包含局部变量表、操作数栈和帧数据区几个部分。 由于每次函数调用都会产生对应的栈帧,从而占用一定的栈空间,因此,如果栈空间不足,那么函数调用自然无法继续进行下去。当请求的栈深度大于最大可用栈深度时,系统会抛出StackOverflowError栈溢出错误。 使用递归,由于递归没有出口,这段代码可能会抛出栈溢出错误,在抛出栈溢出错误时,打印最大的调用深度。 使用参数-Xss128K执行下面代码(在eclipse中右键选择Run As–>run Configurations….设置Vm arguments) 发生了栈溢出错误,通过增大-Xss的值,可以获得更深的层次调用,尝试使用参数-Xss256K执行下述代码 public class TestStackDeep { private static int count =0; public static void recursion(){ count ++; recursion(); } public static void main(String[] args) { try{ recursion(); }catch(Throwable e){ System.out.println("deep of calling ="+count); e.printStackTrace(); } } } 函数嵌套调用的层次在很大程度上由栈的大小决定,栈越大,函数支持的嵌套调用次数就越多。 栈帧组成之局部变量表局部变量表是栈帧的重要组成部分之一。它用于保存函数的参数以及局部变量,局部变量表中的变量只在当前函数调用中有效,当函数调用结束,随着函数栈帧的弹出销毁,局部变量表也会随之销毁。 由于局部变量表在栈帧之中,因此,如果函数的参数和局部变量很多,会使得局部变量表膨胀,从而每一次函数调用就会占用更多的栈空间,最终导致函数的嵌套调用次数减少。 一个recursion函数含有3个参数和10个局部变量,因此,其局部变量表含有13个变量,而第二个recursion函数不再含有任何参数和局部变量,当这两个函数被嵌套调用时,第二个recursion函数可以拥有更深的调用层次。 public class TestStackDeep2 { private static int count = 0; public static void recursion(long a,long b,long c){ long e=1,f=2,g=3,h=4,i=5,k=6,q=7,x=8,y=9,z=10; count ++; recursion(a,b,c); } public static void recursion(){ count++; recursion(); } public static void main(String[] args) { try{ recursion(0L,0L,0L); //recursion(); }catch(Throwable e){ System.out.println("deep of calling = "+count); e.printStackTrace(); } } } 使用参数-Xss128K执行上述代码中的第一个带参recursion(long a,long b,long c)函数。可以知道输出调用次数后抛出异常。 使用虚拟机参数-Xss128K执行上述代码中第二个不带参数的recursion()函数(当然需要把第一个函数注释掉)。可以看出,在相同的栈容量下,局部变量少的函数可以支持更深的函数调用。即输出次数比上次增加。 第一个带参recursion(long a,long b,long c)的最大局部变量表的大小为26个字,因为该函数包含总共13个参数和局部变量,且都为long型,long和double在局部变量表中需要占用2个字,其他如int short byte 对象引用等占用一个字。 说明:字(word)指的是计算机内存中占据一个单独的内存单元编号的一组二进制串,一般32位计算机上一个字为4个字节长度。 栈帧中局部变量表中的槽位是可以重用的,如果一个局部变量过了其作用域,那么在其作用域之后申明的新的局部变量就很有可能会复用过期局部变量的槽位,从而达到节省资源的目的。 垃圾回收目前为止,jvm**已经发展处三种比较成熟的垃圾收集算法:1.标记-清除算法;2.复制算法;3.标记-整理算法;4.分代收集算法** 1.**标记-**清除算法这种垃圾回收一次回收分为两个阶段:标记、清除。首先标记所有需要回收的对象,在标记完成后回收所有被标记的对象。这种回收算法会产生大量不连续的内存碎片,当要频繁分配一个大对象时,jvm在新生代中找不到足够大的连续的内存块,会导致jvm频繁进行内存回收(目前有机制,对大对象,直接分配到老年代中) 2.**复制算法**这种算法会将内存划分为两个相等的块,每次只使用其中一块。当这块内存不够使用时,就将还存活的对象复制到另一块内存中,然后把这块内存一次清理掉。这样做的效率比较高,也避免了内存碎片。但是这样内存的可使用空间减半,是个不小的损失。 3.**标记-**整理算法这是标记-清除算法的升级版。在完成标记阶段后,不是直接对可回收对象进行清理,而是让存活对象向着一端移动,然后清理掉边界以外的内存 4.**分代收集算法**当前商业虚拟机都采用这种算法。首先根据对象存活周期的不同将内存分为几块即新生代、老年代,然后根据不同年代的特点,采用不同的收集算法。在新生代中,每次垃圾收集时都有大量对象死去,只有少量存活,所以选择了复制算法。而老年代中因为对象存活率比较高,所以采用标记-整理算法(或者标记-清除算法) GC**的执行机制**由于对象进行了分代处理,因此垃圾回收区域、时间也不一样。GC有两种类型:Scavenge GC和Full GC。 Minor **GC 一般情况下,当新对象生成,并且在Eden申请空间失败时,就会触发MinorGC,对Eden区域进行GC,清除非存活对象,并且把尚且存活的对象移动到Survivor区。然后整理Survivor的两个区。这种方式的GC是对年轻代的Eden区进行,不会影响到年老代。因为大部分对象都是从Eden区开始的,同时Eden区不会分配的很大,所以Eden区的GC会频繁进行。因而,一般在这里需要使用速度快、效率高的算法,使Eden去能尽快空闲出来。 Full GC** 对整个堆进行整理,包括Young、Tenured和Perm。Full GC因为需要对整个堆进行回收,所以比MinorGC要慢,因此应该尽可能减少Full GC的次数。在对JVM调优的过程中,很大一部分工作就是对于FullGC的调节。有如下原因可能导致Full GC: 1.年老代(Tenured)被写满 2.持久代(Perm)被写满 3.System.gc()被显示调用 4.上一次GC之后Heap的各域分配策略动态变化 为什么要运用分代垃圾回收策略?在java程序运行的过程中,会产生大量的对象,因每个对象所能承担的职责不同所具有的功能不同所以也有着不一样的生命周期,有的对象生命周期较长,比如Http请求中的Session对象,线程,Socket连接等;有的对象生命周期较短,比如String对象,由于其不变类的特性,有的在使用一次后即可回收。试想,在不进行对象存活时间区分的情况下,每次垃圾回收都是对整个堆空间进行回收,那么消耗的时间相对会很长,而且对于存活时间较长的对象进行的扫描工作等都是徒劳。因此就需要引入分治的思想,所谓分治的思想就是因地制宜,将对象进行代的划分,把不同生命周期的对象放在不同的代上使用不同的垃圾回收方式。 通过一个简单示例,展示局部变量对垃圾回收的影响。1234567891011121314151617181920212223242526272829303132public class LocalvarGC { public void localvarGc1(){ byte[] a = new byte[6*1024*1024];//6M System.gc(); } public void localvarGc2(){ byte[] a = new byte[6*1024*1024]; a = null; System.gc(); } public void localvarGc3(){ { byte[] a = new byte[6*1024*1024]; } System.gc(); } public void localvarGc4(){ { byte[] a = new byte[6*1024*1024]; } int c = 10; System.gc(); } public void localvarGc5(){ localvarGc1(); System.gc(); } public static void main(String[] args) { LocalvarGC ins = new LocalvarGC(); ins.localvarGc1(); }} 每一个localvarGcN()函数都分配了一块6M的堆内存,并使用局部变量引用这块空间。 在localvarGc1()中,在申请空间后,立即进行垃圾回收,很明显由于byte数组被变量a引用,因此无法回收这块空间。 在localvarGc2()中,在垃圾回收前,先将变量a置为null,使得byte数组失去强引用,故垃圾回收可以顺利回收byte数组。 在localvarGc3()中,在进行垃圾回收前,先使局部变量a失效,虽然变量a已经离开了作用域,但是变量a依然存在于局部变量表中,并且也指向这块byte数组,故byte数组依然无法被回收。 对于localvarGc4(),在垃圾回收之前,不仅使变量a失效,更是声明了变量c,使变量c复用了变量a的字,由于变量a此时被销毁,故垃圾回收器可以顺利回收数组byte 对于localvarGc5(),它首先调用了localvarGc1(),很明显,在localvarGc1()中并没有释放byte数组,但在localvarGc1()返回后,它的栈帧被销毁,自然也包含了栈帧中的所有局部变量,故byte数组失去了引用,在localvarGc5()的垃圾回收中被回收。 可以使用-XX:+printGC执行上述几个函数,在输出日志里,可以看到垃圾回收前后堆的大小,进而推断出byte数组是否被回收。 下面的输出是函数localvarGc4()的运行结果: [GC (System.gc()) 7618K->624K(94208K), 0.0015613 secs] [Full GC (System.gc()) 624K->526K(94208K), 0.0070718 secs] 从日志中可以看出,堆空间从回收前的7618K变为回收后的624K,释放了>6M的空间,byte数组已经被回收释放。 类加载过程分三步,细化为五步。 类加载的五个过程: 加载 验证 准备 解析 初始化 类从被加载到虚拟机内存中开始,到卸载出内存为止,它的生命周期包括了:加载(Loading)、验证(Verification)、准备(Preparation)、解析(Resolution)、初始化(Initialization)、使用(Using)、卸载(Unloading)七个阶段,其中验证、准备、解析三个部分统称链接。 加载:完成三件事 通过类的全限定名来获取定义此类的二进制字节流 将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构 在内存中生成一个代表这个类的java.lang.Class对象,作为方法区这个类的各种数据的访问入口。 简单来说,加载指的是把class字节码文件从各个来源通过类加载器装载入内存中。 这里有两个重点: 1. 字节码来源。一般的加载来源包括从本地路径下编译生成的.class文件,从jar包中的.class文件,从远程网络,以及动态代理实时编译 2. 类加载器。一般包括启动类加载器,扩展类加载器,应用类加载器,以及用户的自定义类加载器。 注:为什么会有自定义类加载器? 一方面是由于java代码很容易被反编译,如果需要对自己的代码加密的话,可以对编译后的代码进行加密,然后再通过实现自己的自定义类加载器进行解密,最后再加载。 另一方面也有可能从非标准的来源加载代码,比如从网络来源,那就需要自己实现一个类加载器,从指定源进行加载。 验证:四个阶段的检验动作 文件格式验证 元数据验证 字节码验证 符号引用验证 验证是连接阶段的第一步,这一阶段目的是为了确保Class文件的字节流中包含的信息符合当前虚拟机的要求,并且不会危害虚拟机自身安全。 虚拟机规范对这个阶段的限制和指导非常笼统,仅仅说了一句如果验证到输入的字节流不符合Class文件的存储格式,就抛出一个java.lang.VerifyError异常或者其子类异常。具体应当检查哪些方面,如何检查,何时检查,都没有强制要求或明确说明,所以不同的虚拟机对验证的实现可能会有所不同,但大致上都会完场下面四个阶段的检验过程:文件格式验证、元数据验证、字节码验证和符号引用验证。 1.文件格式验证第一阶段要验证字节流是否符合Class文件格式的规范否,并且能被当前版本的虚拟机处理。该验证阶段的主要目的是保证输入的字节流能正确的解析并存储于方法区之内,格式上符合描述一个Java类型的信息的要求。这阶段的验证是基于字节流进行的,经过这个就饿段的验证之后,字节流才会进入内存的方法区进行存储,所以后面三个验证阶段全部是基于方法区的存储结构进行的。 2.元数据验证第二阶段是对字节码描述的信息进行语义分析,以保证其描述的信息符合Java语言的规范要求,这个阶段可能包括的验证点如下: 这个类是否有父类(除了java.lang.Object之外,所有的类应当有父类) 这个类的父类是否继承了不允许被继承的类(被final修饰) 如果这个类不是抽象类,是否实现了其父类或接口之中要求实现的所有方法。 类中的字段、方法是否与父类产生了矛盾 。。。。。 3.字节码验证第三个阶段是验证过程中最复杂的一个,其主要工作是进行数据流和控制流分析。第二阶段对元数据信息中的数据类型做完校验后,这阶段将对类的方法体进行校验分析。这阶段的任务是保证被校验类的方法在运行时不会做出危害虚拟机安全的行为,例如: 保证任意时刻操作数栈的数据类型与指令代码序列都能配合工作,例如不会出现类似这种情况:在操作栈中放置了一个int类型的数据,使用时却按long类型来加载入本地变量表中。 保证跳转指令不会跳转到方法体以外的字节码指令上。 保证方法体中的类型转换是有效的,例如可以把一个子类对象赋值给父类数据类型,这是安全的,反之不合法。 。。。。。。 如果一个类的方法体的字节码没有通过字节码验证,那肯定是有问题的;如果一个方法体通过了字节码验证,也不能说明其一定就是安全的。即使字节码验证之中进行了大量的检查,也不能保证这一点。这里涉及了离散数学中一个很著名的问题“Halting Problem“:通俗一点的说法就是,通过程序去校验程序逻辑是无法做到绝对准确的–不能通过程序准确地检查出程序是否能在有限的时间之内结束运行。 为避免将过多时间消耗在字节码验证阶段,1.6之后给方法体的Code属性的属性表中增加了一项名为“StackMapTable”的属性,这项属性描述了方法体重所有的基本块开始时本地变量表和操作栈应有的状态,这可以将字节码验证的类型推导转变为类型检查从而节省一些时间。使用-XX:-UseSplitVerifier选项来关闭掉这项优化,或者使用参数-XX:+FailOverToOldVerifier要求在类型校验失败的时候瑞回到旧的类型推导方式进行校验(1.7之后不允许)。 4.符号引用验证最后一个阶段的校验发生在虚拟机将符号引用转化为直接引用的时候,这个转化动作将在连接的第三个阶段——解析阶段中发生。符号引用验证可以看做是对类自身以外的信息进行匹配性的校验,通常需要校验以下内容: 符号引用中通过字符串描述的全限定名是否能找到对应的类。 在指定类中是否存在符合方法的字段描述符以及简单名称所描述的方法和字段。 符号引用中的类、字段和方法的访问性(private、protected、public、default)是否可被当前类访问。 。。。。。。 符号引用验证的目的是确保解析动作能正常执行,如果无法通过符号引用验证,将会抛出一个java.lang.IncompatibleClassChangeError异常的子类,如java.lang.IllegalAccessError、java.lang.NoSuchFieldError、java.lang.NoSuchMethodError等。 验证阶段对于虚拟机的类加载机制来说,是一个非常重要、但不一定是必要的阶段。如果所运行的全部代码都已经被反复使用和验证过,在实施阶段就可以考虑使用-Xverify:none参数来关闭大部分的类验证措施,以锁单虚拟机类加载的时间。 准备:为类变量(static)分配内存并设置类变量的初始值。准备阶段是正式为类变量分配内存并设置类变量初始值的阶段,这些内存都将在方法区中进行分配。这个阶段中有两个容易产生混淆的知识点,首先是这时候进行内存分配的仅包括类变量(static 修饰的变量),而不包括实例变量,实例变量将会在对象实例化时随着对象一起分配在java堆中。其次是这里所说的初始值“通常情况”下是数据类型的零值,假设一个类变量定义为: public static int value = 12; 那么变量value在准备阶段过后的初始值为0而不是12,因为这时候尚未开始执行任何java方法,而把value赋值为123的putstatic指令是程序被编译后,存放于类构造器()方法之中,所以把value赋值为12的动作将在初始化阶段才会被执行。 上面所说的“通常情况”下初始值是零值,那相对于一些特殊的情况,如果类字段的字段属性表中存在ConstantValue属性,那在准备阶段变量value就会被初始化为ConstantValue属性所指定的值,建设上面类变量value定义为: public static final int value = 123; 注意,实例变量并不在这个阶段分配内存。为类变量设置初始值并不是定义的值。比如static int value = 123;那么变量value在准备阶段过后初始值为0,而不是123。值123是在<clinit>()方法中赋予。 解析:将常量池内的符号引用替换为直接引用的过程。解析的动作主要针对类或接口、字段、类方法、接口方法四类符号引用进行。分别对应编译后常量池内的CONSTANT_Class_Info、CONSTANT_Fieldref_Info、CONSTANT_Methodef_Info、CONSTANT_InterfaceMethoder_Info四种常量类型。 1.类、接口的解析 2.字段解析 3.类方法解析 4.接口方法解析 两个重点: 1. 符号引用。即一个字符串,但是这个字符串给出了一些能够唯一性识别一个方法,一个变量,一个类的相关信息。 2. 直接引用。可以理解为一个内存地址,或者一个偏移量。比如类方法,类变量的直接引用是指向方法区的指针;而实例方法,实例变量的直接引用则是从实例的头指针开始算起到这个实例变量位置的偏移量。 举个例子来说,现在调用方法helloWorld(),这个方法的地址是1234567,那么helloWorld就是符号引用,1234567就是直接引用。 在解析阶段,虚拟机会把所有的类名,方法名,字段名这些符号引用替换为具体的内存地址或偏移量,也就是直接引用。 初始化按照static块和static变量在文件中的出现顺序,合并到<clinit>()方法中。实例变量由<init>()函数赋值。 将一个类中所有被static关键字标识的代码统一执行一遍,如果执行的是静态变量,那么就会使用用户指定的值覆盖之前在准备阶段设置的初始值;如果执行的是static代码块,那么在初始化阶段,JVM就会执行static代码块中定义的所有操作。 所有类变量初始化语句和静态代码块都会在编译时被前端编译器放在收集器里头,存放到一个特殊的方法中,这个方法就是方法,即类/接口初始化方法。该方法的作用就是初始化一个中的变量,使用用户指定的值覆盖之前在准备阶段里设定的初始值。任何invoke之类的字节码都无法调用方法,因为该方法只能在类加载的过程中由JVM调用。 如果父类还没有被初始化,那么优先对父类初始化,但在方法内部不会显示调用父类的方法,由JVM负责保证一个类的方法执行之前,它的父类方法已经被执行。 JVM必须确保一个类在初始化的过程中,如果是多线程需要同时初始化它,仅仅只能允许其中一个线程对其执行初始化操作,其余线程必须等待,只有在活动线程执行完对类的初始化操作之后,才会通知正在等待的其他线程。 参考: http://www.importnew.com/23035.html https://www.cnblogs.com/BRE49/p/java-1.html https://www.cnblogs.com/cherish010/p/8341611.html https://www.cnblogs.com/fengbs/p/7082262.html https://www.cnblogs.com/xiaoxian1369/p/5498817.html http://www.darylliu.top/2018/01/31/144/]]></content>
<categories>
<category>Java</category>
</categories>
</entry>
<entry>
<title><![CDATA[matplotlib使用]]></title>
<url>%2F2018-11-12-matplotlib%E4%BD%BF%E7%94%A8.html</url>
<content type="text"><![CDATA[基本绘图import matplotlib as mpl import matplotlib.pyplot as plt x = np.linspace(start=-3, stop=3, num=1001, dtype=np.float) x1=x.reshape(1,1001) zero= np.zeros((1,1001)) y_relu=np.max(np.vstack((x1,zero)),axis=0) y_logit=1/(1+np.exp(-x)) y_tanh=(np.exp(x)-np.exp(-x))/(np.exp(x)+np.exp(-x)) plt.figure(figsize=(8,6)) plt.ylim((-1, 1)) plt.plot(x,y_logit,'r-',label='LogisticLoss',linewidth=2) plt.plot(x,y_tanh,'g-',label='TanhLoss',linewidth=2) plt.plot(x,y_relu,'b-',label='ReluLoss',linewidth=2) plt.title("Lossfunction",fontsize=18) plt.grid() plt.legend(loc='upperright') plt.show() plt.savefig('1.png') 直方图、箱图import seaborn data=pd.read_csv('student-por.csv',delimiter=";") df=pd.DataFrame(data) plt.hist(df.loc[:,"G1"],bins=19) plt.xlabel('Performance',fontsize=18) plt.ylabel('Num of Students',fontsize=18) plt.title('Histogram of {0}'.format('G1'),fontsize=18) plt.show() df.boxplot(column=["G1"],by="Medu") plt.show() 条形图、核密度估计图s=pd.Series(df.loc[:,'sex']) s=s.value_counts() s=s.sort_index(axis=0) s.plot(kind='barh') plt.ylabel('SEX') plt.show() df.loc[:,['G1','G2','G3']].plot(kind='kde') plt.show() #kind= line 线图 pie 饼图 bar 垂直条形图 barh 水平条形图 kde 核密度估计 hist 直方图 box 箱图 scikit**-learn**: 预处理 http://scikit-learn.org/stable/ import sklearn #正则化/二值化 preprocessing.normalize(X, norm='l2') preprocessing.Binarizer(copy=True, threshold=0.0).fit(X) preprocessing.OneHotEncoder() #缺失值处理 imp = Imputer(missing_values='NaN', strategy='mean', axis=0) imp.fit(X) #from (X1, X2) to (1, X1, X2, X1^2, X1X2, X2^2) poly = PolynomialFeatures(2) poly.fit_transform(X) http://scikit-learn.org/stable/ #分隔数据集 X_train, X_test, y_train, y_test = \ train_test_split(X, y, test_size=0.4) clf=LogisticRegression() clf.fit(X_train, y_train) #预测 clf.predict(X_train) clf.predict_proba(X_test) #各种分类器 KNeighborsClassifier(3) SVC(kernel="linear", C=0.025) DecisionTreeClassifier(max_depth=5) RandomForestClassifier(max_depth=5, n_estimators=10, max_features=1) AdaBoostClassifier() MLPClassifier(solver='lbfgs',activation='relu', alpha=1e-5,hidden_layer_sizes=(5, 2))]]></content>
<categories>
<category>Python</category>
</categories>
<tags>
<tag>Python matplotlib</tag>
</tags>
</entry>
<entry>
<title><![CDATA[panda使用]]></title>
<url>%2F2018-11-12-panda%E4%BD%BF%E7%94%A8.html</url>
<content type="text"><![CDATA[数据结构之Series123456789101112131415161718192021222324252627282930313233343536373839404142import pandas as pdfrom import Series,DataFrame Series是类似于一维数组的对象,由一组数据以及索引组成#Series 1-给定了索引a= Series([4,7,-5,3],index=['d','b','a','c'])b= pd.Series([4,7,-5,3],index=['d','b','a','c'])#2-未给定索引,索引为[0,N-1]ser1 = Series([1,2,3,4])#给index指定一个listser2 = Series(range(4),index = ["a","b","c","d"])#3-也可以通过字典来创建Series对象sdata = {'Ohio': 35000, 'Texas': 71000, 'Oregon': 16000, 'Utah': 5000}ser3 = Series(sdata)#可以发现,用字典创建的Series是按index有序的#在用字典生成Series的时候,也可以指定索引,#当索引中值对应的字典中的值不存在的时候,则此索引的值标记为Missing,NA,#并且可以通过函数(pandas.isnull,pandas.notnull)来确定哪些索引对应的值是没有的。states = ['California', 'Ohio', 'Oregon', 'Texas']ser3 = Series(sdata,index = states)In [50]: ser3Out[50]: California NaNOhio 35000.0Oregon 16000.0Texas 71000.0dtype: float64# 判断哪些值为空In [51]: pd.isnull(ser3)Out[51]: California TrueOhio FalseOregon FalseTexas Falsedtype: boolIn [52]: pd.notnull(ser3)Out[52]: California FalseOhio TrueOregon TrueTexas Truedtype: bool 访问Series中的元素和索引12345678910111213141516171819202122se2Out[159]: a 0b 1c 2d 3dtype: int64# 访问索引为"a","c"的元素se2[["a","c"]]Out[160]: a 0c 2dtype: int64# 访问索引为"a"的元素se2["a"]Out[161]: 0# 获取所有的值se2.valuesOut[162]: array([0, 1, 2, 3], dtype=int64)# 获取所有的索引se2.indexOut[163]: Index(['a', 'b', 'c', 'd'], dtype='object') 简单运算在pandas的Series中,会保留NumPy的数组操作(用布尔数组过滤数据,标量乘法,以及使用数学函数),并同时保持引用的使用.12345678910111213141516171819se2[se2>2]Out[165]: d 3dtype: int64se2*2Out[166]: a 0b 2c 4d 6dtype: int64np.exp(se2)Out[167]: a 1.000000b 2.718282c 7.389056d 20.085537dtype: float64 DataFrameDataFrame是一个表格型的数据结构 它含有一组有序的列,每列可以是不同的值类型(数值/字符串/布尔型值) 它有行/列索引,可看做由Series组成的字典(共同用一个索引)1234567#DataFramed = {'state':['1','2'],'year':['a','b'],'pop':['x','y']}frame = pd.DataFrame(d)frame state year pop0 1 a x1 2 b y DataFrame基本用法追加数据1234567frame2 =pd.DataFrame([['z','3','c'],['x','4','d']],columns=['pop','state','year'])frame pop state year0 x 1 a1 y 2 b2 z 3 c3 x 4 d 拼接数据1234567pd.concat([frame,frame2])frame pop state year0 x 1 a1 y 2 b0 z 3 c1 x 4 d 从csv导入数据123456789data = pd.read_excel('D:\\Users\\zyb\\Desktop\\plan.xlsx',header=5)dataOut[189]: 5 FR接入数据库测试 1 Unnamed: 30 6.0 整体测试 1 NaN1 NaN 总计 8 NaNtype(data)Out[190]: pandas.core.frame.DataFrame 显示头尾几行12data.head()data.tail() 显示列名/值1234567data.columnsOut[6]: Index([5, 'FR接入数据库测试', 1, 'Unnamed: 3'], dtype='object')data.valuesOut[7]: array([[6.0, '整体测试', 1, nan], [nan, '总计', 8, nan]], dtype=object) 筛选、缺失值处理123456789101112#筛选行/列data.iloc[3:6]data.iloc[:,3:6]data.loc[:,["school", "age"]]#条件筛选data[data["G1"]<10]#缺失值处理data.fillna(value=0)data.dropna(how="any")data.isnull() 排序1234567#排序data.sort_values("G1", ascending=False)#统计并排序s=pd.Series(data2.loc[:,"Medu"])s=s.value_counts()s=s.sort_index(axis=0) 算术运算1count 非NA值的数量 1describe 针对Series或各DataFrame列计算汇总统计 1min,max 计算最小值、最大值 1argmin, argmax 计算能够获取到最小值和最大值的索引位置(整数) 1idxmin, idxmax 计算能够获取到最小值和最大值的索引值 1quantile 计算样本的分位数(0到1) 1sum 值的总和 1mean 值的平均数 1media 值的算术中位数(50%分位数) 1mad 根据平均值计算平均绝对离差 1var, std 样本值的方差、标准差 1skew, kurt 样本值的偏度(三阶矩)、峰度(四阶矩) 1cumsum, cumprod 样本值的累计和/累计积 1cummin, cummax 样本值的累计最小、最大值 1diff 计算一阶差分(对时间序列很有用) 1pct_change 计算百分数变化 groupby**统计、数据透视表**12345678#groupbydata.groupby(['sex', 'studytime'])['G1'].mean()group1 = data.groupby('sex')group1['G1','G2'].agg(['mean','sum'])#数据透视表pd.pivot_table(data, values='G1', index=['sex'],columns=['age'], aggfunc=np.mean) 类别转换1234567#类别转换medu=data["Medu"].astype("category")medu.cat.categories=["None","<4th grade","5th to 9th grade","secondary education","higher education"]#转换成哑元sex_dummies = pd.get_dummies(X_train['sex'], prefix='sex')X_train=X_train.join(sex_dummies)]]></content>
<categories>
<category>Python</category>
</categories>
</entry>
<entry>
<title><![CDATA[numpy使用]]></title>
<url>%2F2018-11-12-numpy%E4%BD%BF%E7%94%A8.html</url>
<content type="text"><![CDATA[使用array创建矩阵1234567891011121314151617import numpy as np#创建向量/矩阵a=np.array([5,10,15,20])b=np.array([[1,2,3,4],[5,6,7,8],[9,10,11,12]])#输出行列数a.shapeb.shapeb.shape[0]#修改行列数b.shape=4,3 c=b.reshape((2,-1)) #此处b和c共享内存#转置b.T#指定数据类型d=np.array([[1,2,3,4],[5,6,7,8],[9,10,11,12]],dtype=np.float)#转换数据类型f=d.astype(np.int) #np.bool/np.complex 使用函数创建矩阵**123456789#等差(指定公差)a=np.arange(1,5,0.5)#等差(指定个数)b=np.linspace(1,10,10)b=np.linspace(1,10,10, endpoint=False) #endpoint指定是否包括终值#等比c=np.logspace(1,4,4,endpoint=True,base=2) 存取、切片**1234567891011121314151617#选取指定行/列a=np.arange(1,10)print('a=',a)#获取某个元素print('a[3]=',a[3])#获取第3-6个元素,左必右开print('a[3:6]=',a[3:6])#省略开始下标,表示从0开始print('a[:]=',a[:5])#步长为2print('a[1:9:2]=',a[1:9:2])#步长为-1,即翻转print('a[::-1]=',a[::-1])#切片数据是原数组的一个视图,与原数组共享内容空间b = a[2:5]b[0] = 200print(a) 随机生成**1234567891011121314151617#均匀分布的随机数a=np.random.rand(10)#指定shapeb = np.random.rand(3,2)print('a= ',a)print('b= \n',b)#正态分布的随机数, eg.N(3, 6.25)c = 2.5 * np.random.randn(2, 4) + 3print('c= ',c)#0-4整数d = np.random.randint(5, size=(2, 4))print('d= \n',d)#洗牌e= np.arange(10)print('e= ',e)np.random.shuffle(e)print('e= ',e) 使用bool数组存取**12345678910111213#大于0.5的元素索引print (a > 0.5)#大于0.5的元素b = a[a > 0.5]print('b= ',b)#将数组b中大于0.5的元素截取成0.5b[b > 0.5] = 0.5print('b= ',b)#a不受影响,此处a和b不共享内存print('a= ',a) 计算(点乘、求和…)**123456789101112131415#创建矩阵A和BA=np.array([[1,1],[0,1]])B=np.array([[2,0],[3,4]])#元素相乘element-wiseproductA*B#点乘A.dot(B)np.dot(A,B)#求和B.sum(axis=1)B.sum(axis=1,keepdims=True)#max,min,sqrt,exp... meshgrid**1234567891011121314151617181920212223import mathimport matplotlib as mplimport matplotlib.pyplot as pltfrom matplotlib import cmfrom mpl_toolkits.mplot3d import Axes3D#meshgrid用于从数组a和b产生网格u = np.linspace(-3, 3, 101)x, y = np.meshgrid(u, u)z = x*y*np.exp(-(x**2 + y**2)/2) / math.sqrt(2*math.pi)fig = plt.figure()ax = fig.add_subplot(111, projection='3d')ax.plot_surface(x, y, z, cmap=cm.coolwarm, linewidth=0.1) #egnp.arange(0,60,10).reshape((-1,1))+np.arange(6)array([[ 0, 1, 2, 3, 4, 5], [10, 11, 12, 13, 14, 15], [20, 21, 22, 23, 24, 25], [30, 31, 32, 33, 34, 35], [40, 41, 42, 43, 44, 45], [50, 51, 52, 53, 54, 55]])]]></content>
<categories>
<category>Python</category>
</categories>
</entry>
<entry>
<title><![CDATA[eclispe快捷键与自动补全]]></title>
<url>%2F2018-11-08-eclispe%E5%BF%AB%E6%8D%B7%E9%94%AE%E4%B8%8E%E8%87%AA%E5%8A%A8%E8%A1%A5%E5%85%A8.html</url>
<content type="text"><![CDATA[设置== 自动补全原装的eclipse只有在.之后才会自动补全一些方法名或者类名等。现在修改使之能够在输入任何一个字母都可以自动跳出补全信息。 window–>preferences–>Java–>Editor–>Content Assist 复制下面的字符串1.abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ 粘贴到Auto activation triggers for Java这个后面的文本框中。然后Apply。 快捷键]]></content>
<categories>
<category>Java</category>
</categories>
<tags>
<tag>Java</tag>
</tags>
</entry>
<entry>
<title><![CDATA[激活JetBrains]]></title>
<url>%2F2018-11-07-%E6%BF%80%E6%B4%BBJetBrains.html</url>
<content type="text"><![CDATA[Crack License Server for JetBrains(PhpStorm,WebStorm,IntelliJ IDEA,PyCharm)https://licensez.com/ Activation code License for PyCharm、WebStorm 2018.2+ Step 1: IMPORTANT: Add 0.0.0.0 account.jetbrains.com to your host file. Step 2: Then click the copy button to copy the key. Step 3: Help> Register…> Activation code, Support: 1. PyCharm 2018.2.3 (Professional Edition) GoLand 2018.2.2 Intellij IDEA 2018.2.4 4. Jetbrains product from 2018.2+]]></content>
<categories>
<category>Python</category>
</categories>
<tags>
<tag>Python</tag>
</tags>
</entry>
<entry>
<title><![CDATA[环境配置]]></title>
<url>%2F2018-11-03-%E7%8E%AF%E5%A2%83%E9%85%8D%E7%BD%AE.html</url>
<content type="text"><![CDATA[前言软件开发领域真的是广阔无垠啊。 开始编程的第一步是要配置开发环境。 这是十分头疼的一件事。这里纪录自己的一些配置过程。 环境基础操作系统Linux发行版: Ubuntu RedHat CentOS 自己玩用Ubuntu,软件开发与线上生产用RedHat或者CentOS(常用) 位数: 32位 64位 目前来看系统几乎都支持64位了。两者之间的区别,可以自行百度。软件支持上也会对位数有所要求。 所以为了以后的麻烦少一些,统一选用64位操作系统。 Windows对于Windows一般用Window7和10。 这里主要的两点有: 会用CMD——Windows键+R,输入cmd,回车。在cmd窗口中输入命令。这里的命令都是从环境变量里包含的。 设置环境变量——环境变量是将一些常用的系统或者软件命令集中的管理起来。环境变量的设置主要是通过变量与值对应的关系确定下来。命令存在某个目录下,这个目录被当作值赋值给变量。这些目录可以用;(分号)进行隔离追加。有一种使用%%包裹起来的参数。这个表示引用的意思。比如%JAVA_HOME%=C:\JAVA。下次在PATH中设置Java的路径的时候可以这样设置PATH=%JAVA_HOME%\bin;…(后面的省略)。 JDKJDK也是分版本的: 32位 64位 没有什么特殊的要求,统一使用64位。 D:\Users\zyb>java -version java version "1.8.0_131" Java(TM) SE Runtime Environment (build 1.8.0_131-b11) Java HotSpot(TM) 64-Bit Server VM (build 25.131-b11, mixed mode) #这里可以看到Java的版本与位数h虚拟机类型是HotSpot Java常用参数: #在cmd命令行模式下输入: java 参数 -d32 使用 32 位数据模型 (如果可用) -d64 使用 64 位数据模型 (如果可用) -version 输出产品版本并退出 安装: Windows直接去官网下载64位的exe安装包。双击安装。 安装的过程中有两个目录。一个是JDK一个是JRE。两个目录可以位于同一个目录下。这样方便管理。 Eclipse不废话。软件直接下载64位的。 下载地址https://mirrors.tuna.tsinghua.edu.cn/eclipse/technology/epp/downloads/release/ 这里说一下: 32位JDK对应32位的Eclispe 63位JDK对应64位的Eclipse Eclipse是绿色版本,下载后直接解压到你制定的目录。然后再eclipse.exe上右键发送快捷方式到桌面。 修改Eclipse软件源。eclipse有很多插件,下载安装插件比较困难,所以选用国内的安装镜像源。如果是校园网用户推荐使用清华源tuna。如果是普通用户使用中科大的。 如何成国内软件源配置?https://lug.ustc.edu.cn/wiki/mirrors/help/eclipse 参考中科大的配置方式。也可以参考这个方式设置成tuna的。 下面设置tuna位eclipse的镜像源。 就配置好了。]]></content>
<categories>
<category>运维</category>
</categories>
</entry>
<entry>
<title><![CDATA[抽象类和抽象方法]]></title>
<url>%2F2018-11-02-%E6%8A%BD%E8%B1%A1%E7%B1%BB%E5%92%8C%E6%8A%BD%E8%B1%A1%E6%96%B9%E6%B3%95.html</url>
<content type="text"><![CDATA[抽象类**是专门设计来让子类继承的类。抽象类一般包括一个或多个抽象方法。 抽象方法**是必须被子类覆盖的方法。 声明抽象类和方法格式:123456789abstract class <类名>{ 成员变量; 方法(){ 方法体 }; //定义一般方法 abstract 方法( ); //定义抽象方法} 抽象方法不用实现代码,而是在子类中实现所有的抽象方法。 对于成员方法,不能同时用static**和**abstract说明。对于类,不能同时用**final和abstract**说明。]]></content>
<categories>
<category>Java</category>
</categories>
</entry>
<entry>
<title><![CDATA[“null”,“This”,"final"关键字]]></title>
<url>%2F2018-11-02-null-This-final%E5%85%B3%E9%94%AE%E5%AD%97.html</url>
<content type="text"><![CDATA[null关键字 数据类型 缺省值 int 0 Double 0.0 boolean false 类的实例即对象被声明时,它先被初始化为一个特殊的值“null”。这表示它是一个空对象。 This关键字 在类定义中的方法中需要引用正在使用该方法的对象时,可以用“this”表示。 public void setStartPt(int x,int y){ this.startX = x; //the this can be omitted here this.startY = y; } Line line1 = new Line(); line1.setStartPt(10,20); “final”关键字 出于安全性方面的考虑,要避免子类继承超类的某个方法,可以使用“final”关键字来使继承终止。这样使此方法不会在子类中被覆盖(即子类中不能有和此方法同名的方法)。 Ø不能被继承的类称为最终类。如:final class Last; Ø用final说明的成员方法为最终方法。 如:public final void printsuper( )]]></content>
<categories>
<category>Java</category>
</categories>
</entry>
<entry>
<title><![CDATA[构造方法的继承]]></title>
<url>%2F2018-11-02-%E6%9E%84%E9%80%A0%E6%96%B9%E6%B3%95%E7%9A%84%E7%BB%A7%E6%89%BF.html</url>
<content type="text"><![CDATA[如果子类没有构造方法,则它继承超类无参数的构造方法; 如果子类有构造方法,那么在创建子类的对象时,则将先执行继承下来的超类的构造方法,然后再执行自己的构造方法。 对于超类中包含有参数的构造方法,子类可以通过在自己的构造方法中使用super关键字来引用,而且必须是子类构造方法中的第一条语句。 用super调用超类的构造方法:super([参数列表])]]></content>
<categories>
<category>Java</category>
</categories>
</entry>
<entry>
<title><![CDATA[“super”关键字]]></title>
<url>%2F2018-11-02-%E2%80%9Csuper%E2%80%9D%E5%85%B3%E9%94%AE%E5%AD%97.html</url>
<content type="text"><![CDATA[super**表示对某个类的超类的引用。 如子类和超类有同名的成员变量或方法,则: super.<**成员变量名> super.<**成员方法名> 表示引用超类的成员(如无super则表示子类中的同名成员)**]]></content>
<categories>
<category>Java</category>
</categories>
<tags>
<tag>Java</tag>
</tags>
</entry>
<entry>
<title><![CDATA[类的继承小结]]></title>
<url>%2F2018-11-02-%E7%B1%BB%E7%9A%84%E7%BB%A7%E6%89%BF%E5%B0%8F%E7%BB%93.html</url>
<content type="text"><![CDATA[被继承的类称为**超类(父类)。从超类派生出来(继承超类)的新类称子类。** 只支持单重继承,不支持多重继承,所以一个类只能有一个超类。 继承的层次结构。一个子类成为另一个子类的超类。 如果类**Sub是类Super的子类,则类Sub继承了超类Super**的变量和方法。 子类**Sub中,包括两部分的内容:从超类Super**中继承下来的变量和方法,自己新增加的变量和方法。 子类继承超类的成员变量和方法继承原则子类只继承超类中非**private**的成员变量和方法。 用访问器方法访问类的私有成员:例: double getWidth(){return width;} double getHeight(){return height;} void setWidth(double w){ width=w;} void setHeight(double h){ height=h;} 什么时候应该把实例变量声明为private?一般坚持两个基本原则:如果一个实例变量只被它所在类中的方法使用,那么应该将其声明为private。如果一个实例变量必须应用在某一个范围内,那么就应该将其声明为private,而且只能通过访问器方法来访问它。这样可以防止把无效的值附给它。 变量的**隐藏原则**子类的成员变量和超类的成员变量同名时,超类的成员变量被隐藏(不能继承)。 方法的**覆盖原则**子类的成员方法和超类的成员方法同名时,超类的成员方法被子类的成员方法覆盖(不能继承)。]]></content>
<categories>
<category>Java</category>
</categories>
</entry>
<entry>
<title><![CDATA[类的访问权限的设置]]></title>
<url>%2F2018-11-02-%E7%B1%BB%E7%9A%84%E8%AE%BF%E9%97%AE%E6%9D%83%E9%99%90%E7%9A%84%E8%AE%BE%E7%BD%AE.html</url>
<content type="text"><![CDATA[类的访问权限的设置 类的权限有两种:默认和**public**。 如果在一个源程序文件中,声明了若干个类的话,只能有一个类的权限关键字是**public。这个类的名字应该和程序文件同名,main**方法也应该在这个类中。 public class Date{ … public static void main(String args[]) { } } class time { … } 类的成员的访问权限设置用权限关键字设置类的成员的权限,以此决定是否允许其类外部的代码访问这些成员。 public 被修饰为public的类是公共类,它可供所在包的其他类使用,也可供其他包中的类使用,在程序中可以用import语句引入其他包中的public类。被public定义的类中成员变量或方法可以供其他类访问。 例: 使用import引入其他包中的public类:Useraccount.java private 设置private访问权限,则该类的成员只能被同一类中的成员访问,而不让其他类进行访问。 例:Samp2.java Samp3.java protected 该类的成员可以被同一包中的类或其它包中的该类的子类访问。 默认 默认的权限,该类的成员能被同一包中的类访问。 例: GetNum.java]]></content>
<categories>
<category>Java</category>
</categories>
</entry>
<entry>
<title><![CDATA[Ping命令原理]]></title>
<url>%2F2018-10-26-Ping%E5%91%BD%E4%BB%A4%E5%8E%9F%E7%90%86.html</url>
<content type="text"><![CDATA[ping命令是用来确定本地主机与网络中其他主机的网络通信情况,或者查看是否是为有效IP。 ping的工作原理:网络另一主机发送ICMP报文,通过返回信息判断网络连接状况。没有通过传输层的TCP或者UDP。 ping的返回信息中有一个值为TTL(time to live)表示ping程序发送的ICMP数据包的生存周期,每经过一个网段,TTL减1,当其值被减到0时,改数据包将被丢弃,该数据包的源地址被告知的情况下,以重新发送数据包。 ping命令 背后涉及网络层的ARP->ICMP->IP协议。 ping的流程 创建通信套接字 将地址、端口信息于套接字绑定 构建IP包头与ICMP包头 发送构建数据包 接收对方主机回应 给出程序反馈信息 ICMP协议即网际控制报文协议,可在网络中实现主机探测,路由维护、路由选择和流量控制。 由于IP协议没有机制来获取网络错误信息以及对错误进行处理,所以需要一个协议—ICMP协议来解决这个问题,ICMP是IP层的一部分,用于传输差错报文及控制报文,遇到错误时能把错误报告给源发送方,ICMP报文是封装在IP数据报内部。 ICMP包头格式ICMP报文分为两种,一是差错报告报文,二是查询报文。每个ICMP报头均包含类型(8B)、编码(8B)、校验(16B)三项内容。其余选项岁ICMP功能不同而不同。 ping命令只适用众多ICMP报文中的两种:“回送请求(ICMP_ECHO)”和“回送回答报文(ICMP_ECHOREPLY)”,往返的ICMP报文中都有时间戳。 ICMP是(Internet Control Message Protocol)Internet控制报文协议。它是TCP/IP协议族的一个子协议,用于在IP主机、路由器之间传递控制消息。控制消息是指网络通不通、主机是否可达、路由是否可用等网络本身的消息。这些控制消息虽然并不传输用户数据,但是对于用户数据的传递起着重要的作用。 ping的两情况下ARP的过程一种是同一网段内,一种是跨网段的ping。 1.同一网段内ping首先,如果主机A,要去ping主机B,那么主机A,就要封装二层报文,他会先查自己的MAC地址表,如果没有B的MAC地址,就会向外发送一个ARP广播包,如图: 其中ARP报文格式如下: 其中OP : 1:表示ARP请求 2:表示ARP应答 3:表示RARP请求 4:表示RARP应答 首先,交换机会收到这个报文后,交换机有学习MAC地址的功能,所以他会检索自己有没有保存主机B的MAC地址,如果有,就返回给主机A,如果没有,就会向所有端口发送ARP广播,其它主机收到后,发现不是在找自己,就纷纷丢弃了该报文,不去理会。直到主机B收到了报文后,就立即响应,我的MAC地址是多少,同时学到主机A的MAC地址,并按同样的ARP报文格式返回给主机A。如图: ARP报文格式为: 这时候主机A学到了主机B的MAC地址,就把这个MAC地址封装到ICMP协议的二层报文中向主机B发送,报文格式如下: 当主机B收到了这个报文后,发现是主机A 的ICPM回显请求,就按同样的格式,返回一个值给主机A,这样就完成了同一网段内的ping过程。 在这里,讲了这么久的局域网内的PING,实际过程的发生不到1毫秒。 2.不同网段内ping如果主机A要ping主机C,那么主机A发现主机C的IP和自己不是同一网段,他就去找网关转发,但是他也不知道网关的MAC地址情况下呢?他就会向之前那个步骤一样先发送一个ARP广播,学到网关的MAC地址,再发封装ICMP报文给网关路由器.。报文格式如下: 当路由器收到主机A发过来的ICMP报文,发现自己的目的地址是其本身MAC地址,根据目的的IP2.1.1.1,查路由表,发现2.1.1.1/24的路由表项,得到一个出口指针,去掉原来的MAC头部,加上自己的MAC地址向主机C转发。(如果网关也没有主机C的MAC地址,还是要向前面一个步骤一样,ARP广播一下即可相互学到。路由器2端口能学到主机D的MAC地址,主机D也能学到路由器2端口的MAC地址。)报文格式如下: 最后,在主机C已学到路由器2端口MAC地址,路由器2端口转发给路由器1端口,路由1端口学到主机A的MAC地址的情况下,他们就不需要再做ARP解析,就将ICMP的回显请求回复过来。报文格式大致如下: ping过程总结1.相同网段 主机A要去Ping主机B, 主机A会封装两层报文,主机A先检查自己MAC地址中是否有B的MAC地址,如果没有就向外发送一个ARP广播包。 交换机收到这个ARP后,会检查在交换机中是否包含B的MAC地址,如果有就直接返回给A;如果没有就向所有端口发送ARP,该网段的主机的MAC如果与B的MAC地址不同就丢弃,如果主机B收到了该ARP就马上返回相同格式的ARP。 这时主机A已经有了B的MAC地址,就把B的MAC地址封装到ICMP报中,向主机B发送一个回显请求。 主机B收到该报文后,知道是主机A的一个回显请求,就会返回一个相同格式的报文。这样就完成了同一个网段的Ping的过程。 2.ping某个域名的过程 首先本机发送域名请求数据到PC设置的DNS ip PC通过子网掩码判断DNS ip是本网段还是跨网段(这里只考虑跨网段) 由于是跨网段,PC发送DNS域名解析数据包到PC设置的网关ip上。(此时先要进行二层的mac转发,PC查看本机arp缓存表,如果表中有网关的mac地址,直接转发,如果没有,使用arp解析协议解析到网关的mac地址。之后封装成数据帧发送到三层网络层)此时PC发送三层数据到网关,源地址为PC内网地址,目的地址为DNS ip地址。而在二层源mac地址为PC mac地址,目的mac地址为网关mac地址。 路由内网网关收到数据包,根据数据包的目的地址,查看路由表。根据路由表发送数据到下一跳上。(发送前,数据到达路由外网端口,会根据nat地址转换配置。形成一条内网ip+port与外网ip+port的一一对应关系。) 发送到下一跳和内网通信都是一样的,查看路由arp缓存表,如果有下一跳mac地址,就直接发送,没有的话需要arp协议解析一下。 对端路由收到数据包,再接着根据路由表判断下一跳。这样一跳一跳地,最后到达DNS服务器。服务器将查询结果返回。 返回的数据包在ISP的网络里最后寻址到你的路由器上,你的路由器收到数据包后,会查询路由nat连接表,寻找ip+port关系对应的内网ip。拆分数据包,封装成帧,最后PC收到域名对应的ip地址。 【到这里,域名解析过程完成,接下来ping对方ip,过程与上面几乎一样】 再发起一次PC到目的域名ip地址的一次ping请求信息 PC通过子网掩码判断对方ip是本网段还是跨网段(这里只考虑跨网段) 由于是跨网段,PC发送数据包到网关ip上。 路由内网网关收到数据包,根据数据包的目的地址,查看路由表。根据路由表发送数据到下一跳上。(发送前,数据到达路由外网端口,会根据nat地址转换配置。形成一条内网IP+port与外网ip+port的一一对应关系。) 发送到下一跳和内网通信都是一样的,查看路由arp缓存表,如果有下一跳mac地址,就直接发送,没有的话就是要arp协议解析一下。 服务器收到数据包后,会重新构建一个ICMP应答包,然后返回。 返回的数据包在ISP的网络里最后寻址到你的路由器上,你的路由器收到数据包后,会查询路由nat连接表,寻找ip+port关系对应的内网ip。拆分数据包,封装成帧,最后PC收到ICMP应答数据包。 整个过程到此结束。在整个这个过程中,源ip地址和目的ip地址是不变的(内网到路由器段不算在内)而mac地址是变的。 ping用法D:\Users\***>ping /? 用法: ping [-t] [-a] [-n count] [-l size] [-f] [-i TTL] [-v TOS] [-r count] [-s count] [[-j host-list] | [-k host-list]] [-w timeout] [-R] [-S srcaddr] [-c compartment] [-p] [-4] [-6] target_name 选项: -t Ping 指定的主机,直到停止。 若要查看统计信息并继续操作,请键入 Ctrl+Break; 若要停止,请键入 Ctrl+C。 -a 将地址解析为主机名。 -n count 要发送的回显请求数。 -l size 发送缓冲区大小。 -f 在数据包中设置“不分段”标记(仅适用于 IPv4)。 -i TTL 生存时间。 -v TOS 服务类型(仅适用于 IPv4。该设置已被弃用, 对 IP 标头中的服务类型字段没有任何 影响)。 -r count 记录计数跃点的路由(仅适用于 IPv4)。 -s count 计数跃点的时间戳(仅适用于 IPv4)。 -j host-list 与主机列表一起使用的松散源路由(仅适用于 IPv4)。 -k host-list 与主机列表一起使用的严格源路由(仅适用于 IPv4)。 -w timeout 等待每次回复的超时时间(毫秒)。 -R 同样使用路由标头测试反向路由(仅适用于 IPv6)。 根据 RFC 5095,已弃用此路由标头。 如果使用此标头,某些系统可能丢弃 回显请求。 -S srcaddr 要使用的源地址。 -c compartment 路由隔离舱标识符。 -p Ping Hyper-V 网络虚拟化提供程序地址。 -4 强制使用 IPv4。 -6 强制使用 IPv6。 ping使用步骤一般我们直接使用第e步,用来测试本机与外网是否连通。 a.使用ipconfig /all观察本地网络设置是否正确; b.Ping 127.0.0.1,127.0.0.1 回送地址Ping回送地址是为了检查本地的TCP/IP协议有没有设置好; c.Ping本机IP地址,这样是为了检查本机的IP地址是否设置有误; d.Ping本网网关或本网IP地址,这样的是为了检查硬件设备是否有问题,也可以检查本机与本地网络连接是否正常;(在非局域网中这一步骤可以忽略) e.Ping远程IP地址,这主要是检查本网或本机与外部的连接是否正常。 判断一条链路好坏Ping这个命令除了可以检查网络的连通和检测故障以外,还有一个比较有趣的用途,那就是可以利用它的一些返回数据,来估算你跟某台主机之间的速度是多少字节每秒。 我们先来看看它有那些返回数据。 D:\Users\zyb>ping www.baidu.com 正在 www.a.shifen.com [115.239.211.112] 具有 32 字节的数据: 来自 115.239.211.112 的回复: 字节=32 时间=4ms TTL=119 来自 115.239.211.112 的回复: 字节=32 时间=4ms TTL=119 来自 115.239.211.112 的回复: 字节=32 时间=4ms TTL=119 来自 115.239.211.112 的回复: 字节=32 时间=4ms TTL=119 115.239.211.112 的 Ping 统计信息: 数据包: 已发送 = 4,已接收 = 4,丢失 = 0 (0% 丢失), 往返行程的估计时间(以毫秒为单位): 最短 = 4ms,最长 = 4ms,平均 = 4ms 在例子中”bytes=32”表示ICMP报文中有32个字节的测试数据,”time=4ms”是往返时间。 Sent 发送多个秒包、Received 收到多个回应包、Lost 丢弃了多少个Minmum 最小值 、MAXimun 最大值、Average 平均值。所在图上来看,来回只用了4MS 时间,lost =0 即是丢包数为0,网络状态相当良好。 (更详细可以使用-n参数 “ping –n 100 IP地址” ping 100次。查看 Sent Received Lost Minmum MAXimun Average 这些值的变化。) 对Ping后返回信息的分析1.Request timed out这是大家经常碰到的提示信息,很多文章中说这是对方机器置了过滤ICMP数据包,从上面工作过程来看,这是不完全正确的,至少有下几种情况。 (1) 对方已关机,或者网络上根本没有这个地址:比如在上图中主机A中PING 192.168.0.7 ,或者主机B关机了,在主机A中PING 192.168.0.5 都会得到超时的信息。 (2)对方与自己不在同一网段内,通过路由也无法找到对方,但有时对方确实是存在的,当然不存在也是返回超时的信息。 (3)对方确实存在,但设置了ICMP数据包过滤(比如防火墙设置)。 怎样知道对方是存在,还是不存在呢,可以用带参数 -a 的Ping命令探测对方,如果能得到对方的NETBIOS名称,则说明对方是存在的,是有防火墙设置,如果得不到,多半是对方不存在或关机,或不在同一网段内。 (4)错误设置IP地址 正常情况下,一台主机应该有一个网卡,一个IP地址,或多个网卡,多个IP地址(这些地址一定要处于不同的IP子网)。但如果一台电脑的“拨号网络适配器”(相当于一块软网卡)的TCP/IP设置中,设置了一个与网卡IP地址处于同一子网的IP地址,这样,在IP层协议看来,这台主机就有两个不同的接口处于同一网段内。当从这台主机Ping其他的机器时,会存在这样的问题: A.主机不知道将数据包发到哪个网络接口,因为有两个网络接口都连接在同一网段。 B.主机不知道用哪个地址作为数据包的源地址。因此,从这台主机去Ping其他机器,IP层协议会无法处理,超时后,Ping 就会给出一个“超时无应答”的错误信息提示。但从其他主机Ping这台主机时,请求包从特定的网卡来,ICMP只须简单地将目的、源地址互换,并更改一些标志即可,ICMP应答包能顺利发出,其他主机也就能成功Ping通这台机器了。 2.Destination host Unreachable(1) 对方与自己不在同一网段内,而自己又未设置默认的路由,比如上例中A机中不设定默认的路由,运行Ping 192.168.0.1.4就会出现“Destination host Unreachable”。 (2)网线出了故障 这里要说明一下“destination host unreachable”和 “time out”的区别,如果所经过的路由器的路由表中具有到达目标的路由,而目标因为其他原因不可到达,这时候会出现“time out”,如果路由表中连到达目标的路由都没有,那就会出现“destination host unreachable”。 3.Bad IP address这个信息表示您可能没有连接到DNS服务器,所以无法解析这个IP地址,也可能是IP地址不存在。 4.Source quench received这个信息比较特殊,它出现的机率很少。它表示对方或中途的服务器繁忙无法回应。 5.Unknown host——不知名主机这种出错信息的意思是,该远程主机的名字不能被域名服务器(DNS)转换成IP地址。故障原因可能是域名服务器有故障,或者其名字不正确,或者网络管理员的系统与远程主机之间的通信线路有故障。 6.No answer——无响应这种故障说明本地系统有一条通向中心主机的路由,但却接收不到它发给该中心主机的任何信息。故障原因可能是下列之一:中心主机没有工作;本地或中心主机网络配置不正确;本地或中心的路由器没有工作;通信线路有故障;中心主机存在路由选择问题。 7.Ping 127.0.0.1127.0.0.1是本地循环地址 如果本地址无法Ping通,则表明本地机TCP/IP协议不能正常工作。 8.no rout to host网卡工作不正常。 9.transmit failed,error code10043网卡驱动不正常。 10.unknown host nameDNS配置不正确。]]></content>
<categories>
<category>Linux</category>
</categories>
<tags>
<tag>Linux</tag>
</tags>
</entry>
<entry>
<title><![CDATA[进程和线程的区别]]></title>
<url>%2F2018-10-26-%E8%BF%9B%E7%A8%8B%E5%92%8C%E7%BA%BF%E7%A8%8B%E7%9A%84%E5%8C%BA%E5%88%AB.html</url>
<content type="text"><![CDATA[进程和线程的区别 在理解进程和线程概念之前首先要对并发有一定的感性认识,如果服务器同一时间内只能服务于一个客户端,其他客户端都再那里傻等的话,可见其性能的低下估计会被客户骂出翔来,因此并发编程应运而生,并发是网络编程中必须考虑的问题。实现并发的方式有多种:比如多进程、多线程、IO多路复用。 进程== 进程:是并发执行的程序在执行过程中分配和管理资源(CPU、内存等)的基本单位,是一个动态概念,竞争计算机系统资源的基本单位。程序运行时系统就会创建一个进程,并为它分配资源,然后把该进程放入进程就绪队列,进程调度器选中它的时候就会为它分配CPU时间,程序开始真正运行。 Linux系统函数fork()可以在父进程中创建一个子进程,这样的话,在一个进程接到来自客户端新的请求时就可以复制出一个子进程让其来处理,父进程只需负责监控请求的到来,然后创建子进程让其去处理,这样就能做到并发处理。fork函数会返回两次结果,因为操作系统会把当前进程的数据复制一遍,然后程序就分两个进程继续运行后面的代码,fork分别在父进程和子进程中返回,在子进程返回的值pid永远是0,在父进程返回的是子进程的进程id。 线程== 线程:是进程的一个执行单元,是进程内科调度实体。比进程更小的独立运行的基本单位。线程也被称为轻量级进程。线程是程序执行时的最小单位,它是进程的一个执行流,是CPU调度和分派的基本单位,一个进程可以由很多个线程组成,线程间共享进程的所有资源,每个线程有自己的堆栈和局部变量。线程由CPU独立调度执行,在多CPU环境下就允许多个线程同时运行。同样多线程也可以实现并发操作,每个请求分配一个线程来处理。 每个进程都有自己的地址空间,即进程空间,在网络或多用户换机下,一个服务器通常需要接收大量不确定数量用户的并发请求,为每一个请求都创建一个进程显然行不通(系统开销大响应用户请求效率低),因此操作系统中线程概念被引进。 线程的执行过程是线性的,尽管中间会发生中断或者暂停,但是进程所拥有的资源只为改线状执行过程服务,一旦发生线程切换,这些资源需要被保护起来。 进程分为单线程进程和多线程进程,单线程进程宏观来看也是线性执行过程,微观上只有单一的执行过程。多线程进程宏观是线性的,微观上多个执行操作。 线程的改变只代表CPU的执行过程的改变,而没有发生进程所拥有的资源的变化。 * 区别== 1、进程有自己的独立地址空间,每启动一个进程,系统就会为它分配地址空间,建立数据表来维护代码段、堆栈段和数据段,这种操作非常昂贵。而线程是共享进程中的数据的,使用相同的地址空间,包括文件描述符。因此CPU切换一个线程的花费远比进程要小很多,同时创建一个线程的开销也比进程要小很多。 地址空间:同一进程的线程共享本进程的地址空间,而进程之间则是独立的地址空间。 资源拥有:同一进程内的线程共享本进程的资源如内存、I/O、cpu等,但是进程之间的资源是独立的。 执行过程:每个独立的进程程有一个程序运行的入口、顺序执行序列和程序入口。但是线程不能独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制。 线程是处理器调度的基本单位,但是进程不是。 两者均可并发执行。* 2、一个进程崩溃后,在保护模式下不会对其他进程产生影响,但是一个线程崩溃整个进程都死掉。所以多进程要比多线程健壮。 3、进程切换时,消耗的资源大,效率高。所以涉及到频繁的切换时,使用线程要好于进程。同样如果要求同时进行并且又要共享某些变量的并发操作,只能用线程不能用进程。 4、线程之间的通信更方便,同一进程下的线程共享全局变量、静态变量等数据,而进程之间的通信需要以通信的方式(IPC)进行。不过如何处理好同步与互斥是编写多线程程序的难点。 总结== 一个程序至少一个进程,一个进程至少一个线程。 进程是指程序执行时的一个实例。 线程是进程的一个实体。 进程——资源分配的最小单位,线程——程序执行的最小单位。 进程与线程的选择取决以下几点: 1、需要频繁创建销毁的优先使用线程;因为对进程来说创建和销毁一个进程代价是很大的。 2、线程的切换速度快,所以在需要大量计算,切换频繁时用线程,还有耗时的操作使用线程可提高应用程序的响应 3、因为对CPU系统的效率使用上线程更占优,所以可能要发展到多机分布的用进程,多核分布用线程; 4、并行操作时使用线程,如C/S架构的服务器端并发线程响应用户的请求; 5、需要更稳定安全时,适合选择进程;需要速度时,选择线程更好。 优缺点: 线程执行开销小,但是不利于资源的管理和保护。线程适合在SMP机器(双CPU系统)上运行。 进程执行开销大,但是能够很好的进行资源管理和保护。进程可以跨机器前移。 对资源的管理和保护要求高,不限制开销和效率时,使用多进程。 要求效率高,频繁切换时,资源的保护管理要求不是很高时,使用多线程。]]></content>
<categories>
<category>C/C++</category>
</categories>
<tags>
<tag>C/C++</tag>
</tags>
</entry>
<entry>
<title><![CDATA[Java虚拟机——学习博客]]></title>
<url>%2F2018-10-24-Java%E8%99%9A%E6%8B%9F%E6%9C%BA%E2%80%94%E2%80%94%E5%AD%A6%E4%B9%A0%E5%8D%9A%E5%AE%A2.html</url>
<content type="text"><![CDATA[网上前辈总结的热门的博文28篇干货,不分先后: 最好在第二阶段(精读期间)饭前饭后咀嚼一下。 www.cnblogs.com/jilodream/p/6147791.html JVM内存结构—《深入理解Java虚拟机》学习总结 - 王若伊_恩赐解脱 - 博客园 bxtnicholas.iteye.com/blog/2147553 JVM虚拟机深入学习 - - ITeye博客 www.imooc.com/article/44436?block\_id=tuijian\_wz Java虚拟机知识总结_慕课手记 www.cnblogs.com/smyhvae/p/4810168.html Java虚拟机详解—-JVM常见问题总结 - 千古壹号 - 博客园 www.cnblogs.com/cxzdy/p/5388509.html Java虚拟机(JVM)体系结构概述及各种性能参数优化总结 - 五三中 - 博客园 sukangqing123.iteye.com/blog/2171547 java虚拟机内存管理机制(一):JVM内存管理总结 - - ITeye博客 blog.csdn.net/u011109589/article/details/80427142 《深入理解JVM虚拟机》读书总结 - CSDN博客 blog.csdn.net/u012208784/article/details/79551135 《深入理解JVM虚拟机》读书笔记(一) - CSDN博客 www.jianshu.com/p/2c99e6df2e75 《深入理解Java虚拟机-JVM高级特性与最佳实践》学习总结(第七章) - 简书 www.cnblogs.com/wrong5566/p/6531832.html 《深入理解Java虚拟机》读书笔记 - 吴容 - 博客园 www.jianshu.com/p/355ae3bcec41 《深入理解Java虚拟机》读书笔记 - 简书 yq.aliyun.com/articles/54440 《深入理解Java虚拟机》读书笔记-博客-云栖社区-阿里云 blog.csdn.net/aubdiy/article/details/51511130 《深入理解Java虚拟机》读后总结 (一)JVM内存模型 - CSDN博客 aub.iteye.com/blog/1872868 《深入理解Java虚拟机》读后总结(一)JVM内存模型 - AUB - ITeye博客 blog.csdn.net/hzy38324/article/details/76405201 一起走进Java虚拟机的世界 —— 为什么要弄懂虚拟机 - CSDN博客 blog.csdn.net/qq_30436259/article/details/72773002 关于JVM虚拟机 - 学习总结/笔记(浅入) - CSDN博客 ask.csdn.net/questions/183532 学习JVM虚拟机有什么实践意义?-CSDN问答 blog.csdn.net/u010814766/article/details/46785425 深入理解JVM(我的总结) - CSDN博客 blog.csdn.net/maydaysar/article/details/56839617 深入理解Java虚拟机 精华总结(面试) - CSDN博客 bestcbooks.com/B00D2ID4PK/ 深入理解Java虚拟机 JVM高级特性与最佳实践(第2版) - 全本 - 免费下载 - 计算机书籍控 www.cnblogs.com/bigbigheart/p/6009565.html 深入理解Java虚拟机–个人总结 - Jugen - 博客园 blog.csdn.net/weixin_36273478/article/details/72614982 深入理解Java虚拟机之虚拟机执行子系统(读书笔记) - CSDN博客 blog.csdn.net/demonwang1025/article/details/73435517 深入理解Java虚拟机总结 - CSDN博客 www.cnblogs.com/jiangxiulian/p/7277960.html 深入理解java虚拟机 精华总结(面试)(转) - 菜鸟宝宝 - 博客园 www.cnblogs.com/JamesWang1993/archive/2018/09/03/8548763.html 深入理解java虚拟机读后总结 - 王菜鸟1993 - 博客园 blog.csdn.net/hupoling/article/details/62887251 深入理解java虚拟机读后总结(个人总结记录) - CSDN博客 www.cnblogs.com/zzt-lovelinlin/p/9087062.html 深入理解java虚拟机读后总结(个人总结记录) - 和风细雨汪汪 - 博客园 www.jianshu.com/p/248e0b949673 深入理解jvm虚拟机读书笔记]]></content>
<categories>
<category>Java</category>
</categories>
</entry>
<entry>
<title><![CDATA[【第一节OpenCV基础】]]></title>
<url>%2F2018-10-20-%E7%AC%AC%E4%B8%80%E8%8A%82OpenCV%E5%9F%BA%E7%A1%80.html</url>
<content type="text"><![CDATA[推荐书籍:【计算机视觉—算法与应用】 安装== 免安装 打开VS,创建好项目后,使用VS2013或者VS2017里面的Tools–>Nuget Pakage Manager–>Manager NuGet pakages for solution直接搜索OpenCV安装即可。 手动安装 下载与配置官网下载,解压,配置环境变量。 …opencv\build\x86\vc10\bin …opencv\build\x64\vc10\bin 上面是OpenCV里面的路径,把这个路径配置到path里。 x86表示你的应用是在32位平台下编译的,x64表示应用是64位的。和系统位数没有关系。一般是32位系统不能编译64位的程序。64位可以编译32位的程序。 上面只是告诉了系统我计算机中有OpenCV了。还需要在应用中配置对应的OpenCV。 VS工程“属性管理器”中添加 1、【通用属性】 ->【VC++目录】 ->【包含目录】 把下面这三个的全路径添加到include directory中。 …build\include …build\include\opencv …build\include\opencv2 2、【通用属性】 ->【VC++目录】 ->【库目录】 …opencv\build\x86\vc12\lib 3、【通用属性】 ->【链接器】->【输入】->【附加的依赖项】 opencv_nonfree2411d.lib opencv_nonfree2411.lib… opencv_ts300d.lib opencv_world300d.lib 这里注意下,opencv_world300d.lib与opencv_world300.lib的区别。带d表示是debug版本,能够调试;不带d表示release版本,不带调试功能。 插件Image Watch1、Image Watch 的下载与安装。 2、使用view –>other windows –>Image watch 程序模板1234#include <iostream> #include "opencv2/opencv.hpp" using namespace std; using namespace cv; 模块1234Model-----Core-->opencv\_core.lib Imgproc -->opencv\_imgproc.lib Highgui-->opencv_highgui.lib 图像分类二值图像 灰度图像 彩色图像 多种颜色空间 常用构造函数12345678910Mat::Mat() Mat::Mat(int rows, int cols, int type) Mat::Mat(Size size, int type) Mat::Mat(int rows, int cols, int type, const Scalar& s) Mat::Mat(Size size, int type, const Scalar& s) Mat::Mat(const Mat& m) Mat::Mat(int rows, int cols, int type, void* data, size_t step=AUTO_STEP) Mat::Mat(Size size, int type, void* data, size_t step=AUTO_STEP)Mat::Mat(const Mat& m, const Range& rowRange, const Range& colRange) Mat::Mat(const Mat& m, const Rect& roi) Mat的赋值和拷贝问题浅拷贝lll 深拷贝像素值的读写方法11234567891011121314uchar value = grayim.at<uchar>(i,j); for( int i = 0; i < grayim.rows; ++i) for( int j = 0; j < grayim.cols; ++j ) grayim.at<uchar>(i,j) = (i+j)%255; for( int i = 0; i < colorim.rows; ++i) for( int j = 0; j < colorim.cols; ++j ) { Vec3b pixel; pixel[0] = i%255; //Blue pixel[1] = j%255; //Green pixel[2] = 0; //Red colorim.at<Vec3b>(i,j) = pixel; } 方法21234567891011cv::Mat Iterator_<uchar> grayit, grayend; for( grayit = grayim.begin<uchar>(), grayend = grayim.end<uchar>(); grayit != grayend; ++grayit) *grayit = rand()%255; MatIterator_<Vec3b> colorit,colorend;for(colorit = colorim.begin<Vec3b>(),colorend = colorim.end<Vec3b>();colorit != colorend;++colorit){ (*colorit)[0] = rand()%255;//蓝色blue (*colorit)[1] = rand()%255;//绿色green (*colorit)[2] = rand()%255;//红色red} 方法3123456789for( int i = 0; i < grayim.rows; ++i) { //获取第 i 行首像素指针 uchar * p = grayim.ptr<uchar>(i); //对第 i 行的每个像素(byte)操作 for( int j = 0; j < grayim.cols; ++j ) p[j] = (i+j)%255; }]]></content>
<categories>
<category>OpenCV</category>
</categories>
</entry>
<entry>
<title><![CDATA[图像处理与计算机视觉基础【2012年】]]></title>
<url>%2F2018-10-19-%E5%9B%BE%E5%83%8F%E5%A4%84%E7%90%86%E4%B8%8E%E8%AE%A1%E7%AE%97%E6%9C%BA%E8%A7%86%E8%A7%89%E5%9F%BA%E7%A1%80%E3%80%902012%E5%B9%B4%E3%80%91.html</url>
<content type="text"><![CDATA[图像处理与计算机视觉基础,经典以及最近发展 By xdyang(杨晓冬[email protected]) 文末附上word版本。 一、 绪论 为什么要写这篇文章 从2002年到现在,接触图像快十年了。虽然没有做出什么很出色的工作,不过在这个领域摸爬滚打了十年之后,发现自己对图像处理和计算机视觉的感情越来越深厚。下班之后看看相关的书籍和文献是一件很惬意的事情。平常的一大业余爱好就是收集一些相关的文章,尤其是经典的文章,到现在我的电脑里面已经有了几十G的文章。写这个文档的想法源于我前一段时间整理文献时的一个突发奇想,既然有这个多文献,何不整理出其中的经典,抓住重点来阅读,同时也可以共享给大家。于是当时即兴写了一个《图像处理与计算机视觉中的经典论文》。现在来看,那个文档写得很一般,所共享的论文也非常之有限。就算如此,还是得到了一些网友的夸奖,心里感激不尽。因此,一直想下定决心把这个工作给完善,力求做到尽量全面。 本文是对现有的图像处理和计算机视觉的经典书籍(后面会有推荐)的一个补充。一般的图像处理书籍都是介绍性的介绍某个方法,在每个领域内都会引用几十上百篇参考文献。有时候想深入研究这个领域的时候却发现文献太多,不知如何选择。但实际上在每个领域都有那么三五篇抑或更多是非读不可的经典文献。这些文献除了提出了很经典的算法,同时他们的Introduction和Related work也是对所在的领域很好的总结。读通了这几篇文献也就等于深入了解了这个领域,比单纯的看书收获要多很多。写本文的目的就是想把自己所了解到的各个领域的经典文章整理出来,不用迷失在参考文献的汪洋大海里。 图像处理和计算机视觉的分类 按照当前流行的分类方法,可以分为以下三部分: A.图像处理:对输入的图像做某种变换,输出仍然是图像,基本不涉及或者很少涉及图像内容的分析。比较典型的有图像变换,图像增强,图像去噪,图像压缩,图像恢复,二值图像处理等等。基于阈值的图像分割也属于图像处理的范畴。一般处理的是单幅图像。 B.图像分析:对图像的内容进行分析,提取有意义的特征,以便于后续的处理。处理的仍然是单幅图像。 C.计算机视觉:对图像分析得到的特征进行分析,提取场景的语义表示,让计算机具有人眼和人脑的能力。这时处理的是多幅图像或者序列图像,当然也包括部分单幅图像。 关于图像处理,图像分析和计算机视觉的划分并没有一个很统一的标准。一般的来说,图像处理的书籍总会或多或少的介绍一些图像分析和计算机视觉的知识,比如冈萨雷斯的数字图像处理。而计算机视觉的书籍基本上都会包括图像处理和图像分析,只是不会介绍的太详细。其实图像处理,图像分析和计算机视觉都可以纳入到计算机视觉的范畴:图像处理**->低层视觉(low level vision),图像分析->中间层视觉(middle level vision),计算机视觉->高层视觉(high level vision**)。这是一般的计算机视觉或者机器视觉的划分方法。在本文中,仍然按照传统的方法把这个领域划分为图像处理,图像分析和计算机视觉。 图像处理和计算机视觉开源库以及编程语言选择 目前在图像处理中有两种最重要的语言:c/c++和matlab。它们各有优点:c/c++比较适合大型的工程,效率较高,而且容易转成硬件语言,是工业界的默认语言之一。而matlab实现起来比较方便,适用于算法的快速验证,而且matlab有成熟的工具箱可以使用,比如图像处理工具箱,信号处理工具箱。它们有一个共同的特点:开源的资源非常多。在学术界matlab使用的非常多,很多作者给出的源代码都是matlab版本。最近由于OpenCV的兴起和不断完善,c/c++在图像处理中的作用越来越大。总的来说,c/c++和matlab都必须掌握,最好是精通,当然侧重在c/c++上对找工作会有很大帮助。 计算机视觉/图像算法/模式识别 工程师们使用的主流编程语言 1) 重中之重:编程语言之C/C++公司面试除了考查应聘者的图像处理基础知识、思维逻辑和个人品性之外,在个人能力之中最重要的一条就是C/C 的功底,很多学生朋友们在学校求学阶段并不重视C/C++的学习,导致找工作时处处碰壁(不过对于来参加面试的朋友,如果有较强的逻辑思维或图像理论功底,即使C/C++ 功底弱些,企业还是会偏爱的,毕竟C/C++ 只是一个工具,只要给些时间去钻研还是可以调高的,但是逻辑思维能力和图像理论功底却不是短时期就能提高的。不过一般逻辑思维和图像理论比较强的人,其C/C 水平也是不错的)。 为啥要这么重视C/C++ 呢?答案很简单,与绝大多数其它开发语言相比:C/C++ 的应用领域无法被超越、程序运行效率无法匹敌(当然汇编语言除外),是使用人数最多、跨平台最广的语言工具(适用于windows/linux/dsp/arm/单片机,当然还有其它一些平台)。简单的说,对于多数应用,其它语言能做的事情C/C++ 几乎都能做,其它语言不能做的事情C/C++ 也可以做。 2) 辅助工具之:MATLAB百度百科中是这么说的:“MATLAB是美国MathWorks公司出品的商业数学软件,用于算法开发、数据可视化、数据分析以及数值计算的高级技术计算语言和交互式环境,主要包括MATLAB和Simulink两大部分。” MATLAB本身是一个不错的仿真、建模工具,但不适用于应用级项目的开发,原因很简单:效率与C/C++ 无法匹敌、不夸平台。(虽然后来出来了codegen可以将MATLAB部分代码转换为C++,但自动生成的还是无法与我们自己写的并优化的C++代码相比;还有MATLAB 的mex接口能够将C++与MABLAB接口对接,既然使用了MATLAB编程,那在应用级的领域还是无法与纯C++相比) 简短说说多年前做学生时的部分学习经历: 记得多年前上大学阶段大嘴起初只跟着学校的课程学习了MATLAB的图像处理相关模块(后来才学的C/C++ ),一开始觉得很兴奋,因为只需要编写很少量的代码就可以实现很强大的效果。后来大嘴进一家计算机视觉类的公司实习,发现公司主要用的是C/C++ ,因为MATLAB效率比起C/C++ 相差几倍、十几倍、甚至几十倍,而且要命的是不跨平台,只能用于windows上,后来逼的自己去学了C/C++ ,也正因如此那以后一直到现在特别是当初找工作的时候让我受益匪浅。 对于企业,特别是私企,公司除非给你充足的时间先使用MATLAB做完算法功能,然后再用C/C++ 慢慢改写,而且了解的朋友们都知道,MATLAB的精度与封装的函数标准与C/C++ 有很多不一样,改写起来相对麻烦一些,这样太慢太慢太慢了,项目不等人啊。试问人家成手能够用短时间写出C/C++ 做图像算法并马上可以投入应用,而自己却在那边慢慢磨MATLAB,然后再费老大劲改成纯C(比如需要警觉MATLAB与C++精度不一样的问题、图像处理基础函数标准不一样的问题),那么老板会比较喜欢谁呢? 如果大家从最初就使用C/C++ ,虽然一开始不数量会写的很慢,但是随着知识量和自各种库(比如图像处理库)的积累,那么总有一天开发速度会快起来的,量的积累,质的飞跃。 说了不少,本人并不否认MATLAB,MATLAB做为建模、仿真以及一些验证的工作(比如图形分析和处理、图表显示、图像仿真、语音仿真等)还是不错的,这方面大嘴绝对力挺MATLAB,目前本人也还在使用中。 一句话:对于多数普通人来讲,如果你的目标是想进企业做为一个实力派工程师,那么大嘴建议您以C/C++ 为主、MATLAB为辅助工具做开发。 3) 辅助工具之:OPENCV随着opencv的问世,图像算法/计算机视觉/模式识别行业的门槛儿变低了,原因有以下几点:(1)opencv是以C/C ++为基础开发出来的,适用性强,windows下适用opencv开发的图像算法应用效率足够快(2)封装了很多基础图像处理函数和视觉算法,可谓“拿来即可用”。 (3)与嵌入式接口的统一趋势,如前几年大牛们人物搞出来的EMCV(基于C/C++ ),其基础架构和接口与opencv基本一致,但个人认为EMCV很多函数功能尚不完善,目前暂时无法与opencv相比。今后很多人在windows下基于opencv开发后,可以较为轻松的移植到DSP上,这种开发模式会是一种趋势。 说了opencv几条优点,但本人并不赞同只依赖opencv做开发,无论是图像算法行业还是其它很多行业,最重要的不是用什么工具,而是自己的基础知识和逻辑思维方式,opencv封装了很多基础函数,如果朋友们未搞懂其基础原理便加以使用,这种方式并不利于锻炼自己,抽空自己实现一下opencv和MATLAB的封装好的那些基础函数吧,久而久之,你会发现自己站的高度会越来越高的。 说到这里,改写一下评述MATLAB时的一句话:”对于多数普通人来讲,如果你的目标是想进企业做为一个实力派工程师,那么大嘴建议您以C/C ++为主、OPENCV和MATLAB为辅助工具做开发。” 4) 简单说说其它语言其它开发语言,比如:C#,JAVA等(还有很多很多语言,不一一举例了)都是不错的开发语言,各自有各自的主应用领域和优势,也有很多很多牛人在使用,不过做图像处理嘛,如果不偏向企业级应用(如嵌入式中),虽然也可以用,但是了解的朋友做出来的算法效率实在不敢恭维…,又无法夸平台,在一些不要求效率的场合还是可以用的,所以请学生朋友们慎重选择开发语言,因为这与自己以后的择业以及职位方向有很大关系。 本文的特点和结构,以及适合的对象 在本文面向的对象是即将进入或者刚刚进入图像处理和计算机视觉领域的童鞋,可以在阅读书籍的同时参阅这些文献,能对书中提到的算法有比较深刻的理解。由于本文涉及到的范围比较广,如果能对计算机视觉的资深从业者也有一定的帮助,我将倍感欣慰。为了不至太误人子弟,每一篇文章都或多或少的看了一下,最不济也看了摘要(这句话实在整理之前写的,实际上由于精力有限,好多文献都只是大概扫了一眼,然后看了看google的引用数,一般在1000以上就放上来了,把这些文章细细品味一遍也是我近一两年之内的目标)。在成文的过程中,我本人也受益匪浅,希望能对大家也有所帮助。 由于个人精力和视野的关系,有一些我未涉足过的领域不敢斗胆推荐,只是列出了一些引用率比较高的文章,比如摄像机标定和立体视觉。不过将来,由于工作或者其他原因,这些领域也会接触到,我会逐步增减这些领域的文章。尽管如此,仍然会有疏漏,忘见谅。同时文章的挑选也夹带了一些个人的喜好,比如我个人比较喜欢low level方向的,尤其是IJCV和PAMI上面的文章,因此这方面也稍微多点,希望不要引起您的反感。如果有什么意见或者建议,欢迎mail我。文章和资源我都会在我的csdn blog和sina ishare同步更新。 本文的安排如下。第一部分是绪论。第二部分是图像处理中所需要用到的理论基础,主要是这个领域所涉及到的一些比较好的参考书籍。第三部分是计算机视觉中所涉及到的信号处理和模式识别文章。由于图像处理与图像分析太难区分了,第四部分集中讨论了它们。第五部分是计算机视觉部分。最后是小结。 二、 图像处理与计算机视觉相关的书籍 数学 我们所说的图像处理实际上就是数字图像处理,是把真实世界中的连续三维随机信号投影到传感器的二维平面上,采样并量化后得到二维矩阵。数字图像处理就是二维矩阵的处理,而从二维图像中恢复出三维场景就是计算机视觉的主要任务之一。这里面就涉及到了图像处理所涉及到的三个重要属性:连续性,二维矩阵,随机性。所对应的数学知识是高等数学(微积分),线性代数(矩阵论),概率论和随机过程。这三门课也是考研数学的三个组成部分,构成了图像处理和计算机视觉最基础的数学基础。如果想要更进一步,就要到网上搜搜林达华推荐的数学书目了。 信号处理 图像处理其实就是二维和三维信号处理,而处理的信号又有一定的随机性,因此经典信号处理和随机信号处理都是图像处理和计算机视觉中必备的理论基础。 2.1**经典信号处理**信号与系统(第2版) Alan V.Oppenheim等著 刘树棠译 离散时间信号处理(第2版) A.V.奥本海姆等著 刘树棠译 数字信号处理:理论算法与实现 胡广书 (编者) 2.2**随机信号处理**现代信号处理 张贤达著 统计信号处理基础:估计与检测理论 Steven M.Kay等著 罗鹏飞等译 自适应滤波器原理(第4版) Simon Haykin著 郑宝玉等译 2.3 小波变换信号处理的小波导引:稀疏方法(原书第3版) tephane Malla著, 戴道清等译 2.4 信息论信息论基础(原书第2版) Thomas M.Cover等著 阮吉寿等译 模式识别 Pattern Recognition and Machine Learning Bishop, Christopher M. Springer 模式识别(英文版)(第4版) 西奥多里德斯著 Pattern Classification (2nd Edition) Richard O. Duda等著 Statistical Pattern Recognition, 3rd Edition Andrew R. Webb等著 模式识别(第3版) 张学工著 图像处理与计算机视觉的书籍推荐 图像处理,分析与机器视觉 第三版 Sonka等著 艾海舟等译 Image Processing, Analysis and Machine Vision (附:这本书是图像处理与计算机视觉里面比较全的一本书了,几乎涵盖了图像视觉领域的各个方面。中文版的个人感觉也还可以,值得一看。) 数字图像处理 第三版 冈萨雷斯等著 Digital Image Processing (附:数字图像处理永远的经典,现在已经出到了第三版,相当给力。我的导师曾经说过,这本书写的很优美,对写英文论文也很有帮助,建议购买英文版的。) 计算机视觉:理论与算法 Richard Szeliski著 Computer Vision: Theory and Algorithm (附:微软的Szeliski写的一本最新的计算机视觉著作。内容非常丰富,尤其包括了作者的研究兴趣,比如一般的书里面都没有的Image Stitching和 Image Matting等。这也从另一个侧面说明这本书的通用性不如Sonka的那本。不过作者开放了这本书的电子版,可以有选择性的阅读。 计算机视觉:一种现代方法 DA Forsyth等著 Computer Vision: A Modern Approach MIT的经典教材。虽然已经过去十年了,还是值得一读。期待第二版 Machine vision: theory, algorithms, practicalities 第三版 Davies著 (附:为数不多的英国人写的书,偏向于工业应用。) 数字图像处理 第四版 Pratt著 Digital Image Processing (附:写作风格独树一帜,也是图像处理领域很不错的一本书。网上也可以找到非常清晰的电子版。) 小结 罗嗦了这么多,实际上就是几个建议: (1)基础书千万不可以扔,也不能低价处理给同学或者师弟师妹。不然到时候还得一本本从书店再买回来的。钱是一方面的问题,对着全新的书看完全没有看自己当年上过的课本有感觉。 (2)遇到有相关的课,果断选修或者蹭之,比如随机过程,小波分析,模式识别,机器学习,数据挖掘,现代信号处理甚至泛函。多一些理论积累对将来科研和工作都有好处。 (3)资金允许的话可以多囤一些经典的书,有的时候从牙缝里面省一点都可以买一本好书。不过千万不要像我一样只囤不看。 三、 计算机视觉中的信号处理与模式识别从本章开始,进入本文的核心章节。一共分三章,分别讲述信号处理与模式识别,图像处理与分析以及计算机视觉。与其说是讲述,不如说是一些经典文章的罗列以及自己的简单点评。与前一个版本不同的是,这次把所有的文章按类别归了类,并且增加了很多文献。分类的时候并没有按照传统的分类方法,而是划分成了一个个小的门类,比如SIFT,Harris都作为了单独的一类,虽然它们都可以划分到特征提取里面去。这样做的目的是希望能突出这些比较实用且比较流行的方法。为了以后维护的方便,按照字母顺序排的序。 Boosting Boosting是最近十来年来最成功的一种模式识别方法之一,个人认为可以和SVM并称为模式识别双子星。它真正实现了“三个臭皮匠,赛过诸葛亮”。只要保证每个基本分类器的正确率超过50%,就可以实现组合成任意精度的分类器。这样就可以使用最简单的线性分类器。Boosting在计算机视觉中的最成功的应用无疑就是Viola-Jones提出的基于Haar特征的人脸检测方案。听起来似乎不可思议,但Haar+Adaboost确实在人脸检测上取得了巨大的成功,已经成了工业界的事实标准,并且逐步推广到其他物体的检测。 Rainer Lienhart在2002 ICIP发表的这篇文章是Haar+Adaboost的最好的扩展,他把原始的两个方向的Haar特征扩展到了四个方向,他本人是OpenCV积极的参与者。现在OpenCV的库里面实现的Cascade Classification就包含了他的方法。这也说明了盛会(如ICIP,ICPR,ICASSP)也有好文章啊,只要用心去发掘。 [1997] A Decision-Theoretic Generalization of on-Line Learning and an Application to Boosting [1998] Boosting the margin A new explanation for the effectiveness of voting methods [2002 ICIP TR] Empirical Analysis of Detection Cascades of Boosted Classifiers for Rapid Object Detection [2003] The Boosting Approach to Machine Learning An Overview [2004 IJCV] Robust Real-time Face Detection Clustering 聚类主要有K均值聚类,谱聚类和模糊聚类。在聚类的时候如果自动确定聚类中心的数目是一个一直没有解决的问题。不过这也很正常,评价标准不同,得到的聚类中心数目也不一样。不过这方面还是有一些可以参考的文献,在使用的时候可以基于这些方法设计自己的准则。关于聚类,一般的模式识别书籍都介绍的比较详细,不过关于cluster validity讲的比较少,可以参考下面的文章看看。 [1989 PAMI] Unsupervised Optimal Fuzzy Clustering [1991 PAMI] A validity measure for fuzzy clustering [1995 PAMI] On cluster validity for the fuzzy c-means model [1998] Some New Indexes of Cluster Validity [1999 ACM] Data Clustering A Review [1999 JIIS] On Clustering Validation Techniques [2001] Estimating the number of clusters in a dataset via the Gap statistic [2001 NIPS] On Spectral Clustering [2002] A stability based method for discovering structure in clustered data [2007] A tutorial on spectral clustering Compressive Sensing 最近大红大紫的压缩感知理论。 [2006 TIT] Compressed Sensing [2008 SPM] An Introduction to Compressive Sampling [2011 TSP] Structured Compressed Sensing From Theory to Applications Decision Trees 对决策树感兴趣的同学这篇文章是非看不可的了。 [1986] Introduction to Decision Trees Dynamical Programming 动态规划也是一个比较使用的方法,这里挑选了一篇PAMI的文章以及一篇Book Chapter [1990 PAMI] using dynamic programming for solving variational problems in vision [Book Chapter] Dynamic Programming Expectation Maximization EM是计算机视觉中非常常见的一种方法,尤其是对参数的估计和拟合,比如高斯混合模型。EM和GMM在Bishop的PRML里单独的作为一章,讲的很不错。关于EM的tutorial,网上也可以搜到很多。 [1977] Maximum likelihood from incomplete data via the EM algorithm [1996 SPM] The Expectation-Maximzation Algorithm Graphical Models 伯克利的乔丹大师的Graphical Model,可以配合这Bishop的PRML一起看。 [1999 ML] An Introduction to Variational Methods for Graphical Models Hidden Markov Model HMM在语音识别中发挥着巨大的作用。在信号处理和图像处理中也有一定的应用。最早接触它是跟小波和检索相关的,用HMM来描述小波系数之间的相互关系,并用来做检索。这里提供一篇1989年的经典综述,几篇HMM在小波,分割,检索和纹理上的应用以及一本比较早的中文电子书,现在也不知道作者是谁,在这里对作者表示感谢。 [1989 ] A tutorial on hidden markov models and selected applications in speech recognition [1998 TSP] Wavelet-based statistical signal processing using hidden Markov models [2001 TIP] Multiscale image segmentation using wavelet-domain hidden Markov models [2002 TMM] Rotation invariant texture characterization and retrieval using steerable wavelet-domain hidden Markov models [2003 TIP] Wavelet-based texture analysis and synthesis using hidden Markov models Hmm Chinese book.pdf Independent Component Analysis 同PCA一样,独立成分分析在计算机视觉中也发挥着重要的作用。这里介绍两篇综述性的文章,最后一篇是第二篇的TR版本,内容差不多,但比较清楚一些。 [1999] Independent Component Analysis A Tutorial [2000 NN] Independent component analysis algorithms and applications [2000] Independent Component Analysis Algorithms and Applications Information Theory 计算机视觉中的信息论。这方面有一本很不错的书Information Theory in Computer Vision and Pattern Recognition。这本书有电子版,如果需要用到的话,也可以参考这本书。 [1995 NC] An Information-Maximization Approach to Blind Separation and Blind Deconvolution [2010] An information theory perspective on computational vision Kalman Filter 这个话题在张贤达老师的现代信号处理里面讲的比较深入,还给出了一个有趣的例子。这里列出了Kalman的最早的论文以及几篇综述,还有Unscented Kalman Filter。同时也有一篇Kalman Filter在跟踪中的应用以及两本电子书。 [1960 Kalman] A New Approach to Linear Filtering and Prediction Problems Kalman [1970] Least-squares estimation_from Gauss to Kalman [1997 SPIE] A New Extension of the Kalman Filter to Nonlinear System [2000] The Unscented Kalman Filter for Nonlinear Estimation [2001 Siggraph] An Introduction to the Kalman Filter_full [2003] A Study of the Kalman Filter applied to Visual Tracking Pattern Recognition and Machine Learning 模式识别名气比较大的几篇综述 [2000 PAMI] Statistical pattern recognition a review [2004 CSVT] An Introduction to Biometric Recognition [2010 SPM] Machine Learning in Medical Imaging Principal Component Analysis 著名的PCA,在特征的表示和特征降维上非常有用。 [2001 PAMI] PCA versus LDA [2001] Nonlinear component analysis as a kernel eigenvalue problem [2002] A Tutorial on Principal Component Analysis [2009] A Tutorial on Principal Component Analysis [2011] Robust Principal Component Analysis [Book Chapter] Singular Value Decomposition and Principal Component Analysis Random Forest 随机森林 [2001 ML] Random Forests RANSAC 随机抽样一致性方法,与传统的最小均方误差等完全是两个路子。在Sonka的书里面也有提到。 [2009 BMVC] Performance Evaluation of RANSAC Family Singular Value Decomposition 对于非方阵来说,就是SVD发挥作用的时刻了。一般的模式识别书都会介绍到SVD。这里列出了K-SVD以及一篇Book Chapter [2006 TSP] K-SVD An Algorithm for Designing Overcomplete Dictionaries for Sparse Representation [Book Chapter] Singular Value Decomposition and Principal Component Analysis Sparse Representation 这里主要是Proceeding of IEEE上的几篇文章 [2009 PAMI] Robust Face Recognition via Sparse Representation [2009 PIEEE] Image Decomposition and Separation Using Sparse Representations An Overview [2010 PIEEE] Dictionaries for Sparse Representation Modeling [2010 PIEEE] It’s All About the Data [2010 PIEEE] Matrix Completion With Noise [2010 PIEEE] On the Role of Sparse and Redundant Representations in Image Processing [2010 PIEEE] Sparse Representation for Computer Vision and Pattern Recognition [2011 SPM] Directionary Learning Support Vector Machines [1998] A Tutorial on Support Vector Machines for Pattern Recognition [2004] LIBSVM A Library for Support Vector Machines Wavelet 在小波变换之前,时频分析的工具只有傅立叶变换。众所周知,傅立叶变换在时域没有分辨率,不能捕捉局部频域信息。虽然短时傅立叶变换克服了这个缺点,但只能刻画恒定窗口的频率特性,并且不能很好的扩展到二维。小波变换的出现很好的解决了时频分析的问题,作为一种多分辨率分析工具,在图像处理中得到了极大的发展和应用。在小波变换的发展过程中,有几个人是不得不提的,Mallat, Daubechies,Vetteri, M.N.Do, Swelden,Donoho。Mallat和Daubechies奠定了第一代小波的框架,他们的著作更是小波变换的必读之作,相对来说,小波十讲太偏数学了,比较难懂。而Mallat的信号处理的小波导引更偏应用一点。Swelden提出了第二代小波,使小波变换能够快速方便的实现,他的功劳有点类似于FFT。而Donoho,Vetteri,Mallat及其学生们提出了Ridgelet, Curvelet, Bandelet,Contourlet等几何小波变换,让小波变换有了方向性,更便于压缩,去噪等任务。尤其要提的是M.N.Do,他是一个越南人,得过IMO的银牌,在这个领域著作颇丰。我们国家每年都有5个左右的IMO金牌,希望也有一两个进入这个领域,能够也让我等也敬仰一下。而不是一股脑的都进入金融,管理这种跟数学没有多大关系的行业,呵呵。很希望能看到中国的陶哲轩,中国的M.N.Do。 说到小波,就不得不提JPEG2000。在JPEG2000中使用了Swelden和Daubechies提出的用提升算法实现的9/7小波和5/3小波。如果对比JPEG和JPEG2000,就会发现JPEG2000比JPEG在性能方面有太多的提升。本来我以为JPEG2000的普及只是时间的问题。但现在看来,这个想法太Naive了。现在已经过去十几年了,JPEG2000依然没有任何出头的迹象。不得不说,工业界的惯性力量太强大了。如果以前的东西没有什么硬伤的话,想改变太难了。不巧的是,JPEG2000的种种优点在最近的硬件上已经有了很大的提升。压缩率?现在动辄1T,2T的硬盘,没人太在意压缩率。渐进传输?现在的网速包括无线传输的速度已经相当快了,渐进传输也不是什么优势。感觉现在做图像压缩越来越没有前途了,从最近的会议和期刊文档也可以看出这个趋势。不管怎么说,JPEG2000的Overview还是可以看看的。 [1989 PAMI] A theory for multiresolution signal decomposition__the wavelet representation [1996 PAMI] Image Representation using 2D Gabor Wavelet [1998 ] FACTORING WAVELET TRANSFORMS INTO LIFTING STEPS [1998] The Lifting Scheme_ A Construction Of Second Generation Wavelets [2000 TCE] The JPEG2000 still image coding system_ an overview [2002 TIP] The curvelet transform for image denoising [2003 TIP] Gray and color image contrast enhancement by the curvelet transform [2003 TIP] Mathematical Properties of the jpeg2000 wavelet filters [2003 TIP] The finite ridgelet transform for image representation [2005 TIP] Sparse Geometric Image Representations With Bandelets [2005 TIP] The Contourlet Transform_ An Efficient Directional Multiresolution Image Representation [2010 SPM] The Curvelet Transform 四、 图像处理与分析本章主要讨论图像处理与分析。虽然后面计算机视觉部分的有些内容比如特征提取等也可以归结到图像分析中来,但鉴于它们与计算机视觉的紧密联系,以及它们的出处,没有把它们纳入到图像处理与分析中来。同样,这里面也有一些也可以划归到计算机视觉中去。这都不重要,只要知道有这么个方法,能为自己所用,或者从中得到灵感,这就够了。 Bilateral Filter Bilateral Filter俗称双边滤波器是一种简单实用的具有保持边缘作用的平缓滤波器,由Tomasi等在1998年提出。它现在已经发挥着重大作用,尤其是在HDR领域。 [1998 ICCV] Bilateral Filtering for Gray and Color Images [2008 TIP] Adaptive Bilateral Filter for Sharpness Enhancement and Noise Removal Color 如果对颜色的形成有一定的了解,能比较深刻的理解一些算法。这方面推荐冈萨雷斯的数字图像处理中的相关章节以及Sharma在Digital Color Imaging Handbook中的第一章“Color fundamentals for digital imaging”。跟颜色相关的知识包括Gamma,颜色空间转换,颜色索引以及肤色模型等,这其中也包括著名的EMD。 [1991 IJCV] Color Indexing [2000 IJCV] The Earth Mover’s Distance as a Metric for Image Retrieval [2001 PAMI] Color invariance [2002 IJCV] Statistical Color Models with Application to Skin Detection [2003] A review of RGB color spaces [2007 PR]A survey of skin-color modeling and detection methods Gamma.pdf GammaFAQ.pdf Compression and Encoding 个人以为图像压缩编码并不是当前很热的一个话题,原因前面已经提到过。这里可以看看一篇对编码方面的展望文章 [2005 IEEE] Trends and perspectives in image and video coding Contrast Enhancement 对比度增强一直是图像处理中的一个恒久话题,一般来说都是基于直方图的,比如直方图均衡化。冈萨雷斯的书里面对这个话题讲的比较透彻。这里推荐几篇个人认为不错的文章。 [2002 IJCV] Vision and the Atmosphere [2003 TIP] Gray and color image contrast enhancement by the curvelet transform [2006 TIP] Gray-level grouping (GLG) an automatic method for optimized image contrast enhancement-part II [2006 TIP] Gray-level grouping (GLG) an automatic method for optimized image contrast Enhancement-part I [2007 TIP] Transform Coefficient Histogram-Based Image Enhancement Algorithms Using Contrast Entropy [2009 TIP] A Histogram Modification Framework and Its Application for Image Contrast Enhancement Deblur (Restoration) 图像恢复或者图像去模糊一直是一个非常难的问题,尤其是盲图像恢复。港中文的jiaya jia老师在这方面做的不错,他在主页也给出了可执行文件。这方面的内容也建议看冈萨雷斯的书。这里列出了几篇口碑比较好的文献,包括古老的Richardson-Lucy方法,几篇盲图像恢复的综述以及最近的几篇文章,尤以Fergus和Jiaya Jia的为经典。 [1972] Bayesian-Based Iterative Method of Image Restoration [1974] an iterative technique for the rectification of observed distributions [1990 IEEE] Iterative methods for image deblurring [1996 SPM] Blind Image Deconvolution [1997 SPM] Digital image restoration [2005] Digital Image Reconstruction - Deblurring and Denoising [2006 Siggraph] Removing Camera Shake from a Single Photograph [2008 Siggraph] High-quality Motion Deblurring from a Single Image [2011 PAMI] Richardson-Lucy Deblurring for Scenes under a Projective Motion Path Dehazing and Defog 严格来说去雾化也算是图像对比度增强的一种。这方面最近比较好的工作就是He kaiming等提出的Dark Channel方法。这篇论文也获得了2009的CVPR 最佳论文奖。2这位003年的广东高考状元已经于2011年从港中文博士毕业加入MSRA(估计当时也就二十五六岁吧),相当了不起。 [2008 Siggraph] Single Image Dehazing [2009 CVPR] Single Image Haze Removal Using Dark Channel Prior [2011 PAMI] Single Image Haze Removal Using Dark Channel Prior Denoising 图像去噪也是图像处理中的一个经典问题,在数码摄影中尤其重要。主要的方法有基于小波的方法和基于偏微分方程的方法。 [1992 SIAM] Image selective smoothing and edge detection by nonlinear diffusion. II [1992 SIAM] Image selective smoothing and edge detection by nonlinear diffusion [1992] Nonlinear total variation based noise removal algorithms [1994 SIAM] Signal and image restoration using shock filters and anisotropic diffusion [1995 TIT] De-noising by soft-thresholding [1998 TIP] Orientation diffusions [2000 TIP] Adaptive wavelet thresholding for image denoising and compression [2000 TIP] Fourth-order partial differential equations for noise removal [2001] Denoising through wavelet shrinkage [2002 TIP] The Curvelet Transform for Image Denoising [2003 TIP] Noise removal using fourth-order partial differential equation with applications to medical magnetic resonance images in space and time [2008 PAMI] Automatic Estimation and Removal of Noise from a Single Image [2009 TIP] Is Denoising Dead Edge Detection 边缘检测也是图像处理中的一个基本任务。传统的边缘检测方法有基于梯度算子,尤其是Sobel算子,以及经典的Canny边缘检测。到现在,Canny边缘检测及其思想仍在广泛使用。关于Canny算法的具体细节可以在Sonka的书以及canny自己的论文中找到,网上也可以搜到。最快最直接的方法就是看OpenCV的源代码,非常好懂。在边缘检测方面,Berkeley的大牛J Malik和他的学生在2004年的PAMI提出的方法效果非常好,当然也比较复杂。在复杂度要求不高的情况下,还是值得一试的。MIT的Bill Freeman早期的代表作Steerable Filter在边缘检测方面效果也非常好,并且便于实现。这里给出了几篇比较好的文献,包括一篇最新的综述。边缘检测是图像处理和计算机视觉中任何方向都无法逃避的一个问题,这方面研究多深都不为过。 [1980] theory of edge detection [1983 Canny Thesis] find edge [1986 PAMI] A Computational Approach to Edge Detection [1990 PAMI] Scale-space and edge detection using anisotropic diffusion [1991 PAMI] The design and use of steerable filters [1995 PR] Multiresolution edge detection techniques [1996 TIP] Optimal edge detection in two-dimensional images [1998 PAMI] Local Scale Control for Edge Detection and Blur Estimation [2003 PAMI] Statistical edge detection_ learning and evaluating edge cues [2004 IEEE] Edge Detection Revisited [2004 PAMI] Design of steerable filters for feature detection using canny-like criteria [2004 PAMI] Learning to Detect Natural Image Boundaries Using Local Brightness, Color, and Texture Cues [2011 IVC] Edge and line oriented contour detection State of the art Graph Cut 基于图割的图像分割算法。在这方面没有研究,仅仅列出几篇引用比较高的文献。这里又见J Malik,当然还有华人杰出学者Jianbo Shi,他的主页非常搞笑,在醒目的位置标注Do not fly China Eastern Airlines … 看来是被坑过,而且坑的比较厉害。这个领域,俄罗斯人比较厉害。 [2000 PAMI] Normalized cuts and image segmentation [2001 PAMI] Fast approximate energy minimization via graph cuts [2004 PAMI] What energy functions can be minimized via graph cuts Hough Transform 虽然霍夫变换可以扩展到广义霍夫变换,但最常用的还是检测圆和直线。这方面同样推荐看OpenCV的源代码,一目了然。Matas在2000年提出的PPHT已经集成到OpenCV中去了。 [1986 CVGIU] A Survey of the Hough Transform [1989] A Comparative study of Hough transform methods for circle finding [1992 PAMI] Shapes recognition using the straight line Hough transform_ theory and generalization [1997 PR] Extraction of line features in a noisy image [2000 CVIU] Robust Detection of Lines Using the Progressive Probabilistic Hough Transform Image Interpolation 图像插值,偶尔也用得上。一般来说,双三次也就够了 [2000 TMI] Interpolation revisited Image Matting 也就是最近,我才知道这个词翻译成中文是抠图,比较难听,不知道是谁开始这么翻译的。没有研究,请看文章以及Richard Szeliski的相关章节。以色列美女Levin在这方面有两篇PAMI。 [2008 Fnd] Image and Video Matting A Survey [2008 PAMI] A Closed-Form Solution to Natural Image Matting [2008 PAMI] Spectral Matting Image Modeling 图像的统计模型。这方面有一本专门的著作Natural Image Statistics [1994] The statistics of natural images [2003 JMIV] On Advances in Statistical Modeling of Natural Images [2009 IJCV] Fields of Experts [2009 PAMI] Modeling multiscale subbands of photographic images with fields of Gaussian scale mixtures Image Quality Assessment 在图像质量评价方面,Bovik是首屈一指的。这位老师也很有意思,作为编辑出版了很多书。他也是IEEE的Fellow [2004 TIP] Image quality assessment from error visibility to structural similarity [2011 TIP] blind image quality assessment From Natural Scene Statistics to Perceptual Quality Image Registration 图像配准最早的应用在医学图像上,在图像融合之前需要对图像进行配准。在现在的计算机视觉中,配准也是一个需要理解的概念,比如跟踪,拼接等。在KLT中,也会涉及到配准。这里主要是综述文献。 [1992 MIA] Image matching as a diffusion process [1992 PAMI] A Method for Registration of 3-D shapes [1992] a survey of image registration techniques [1998 MIA] A survey of medical image registration [2003 IVC] Image registration methods a survey [2003 TMI] Mutual-Information-Based Registration of Medical Survey [2011 TIP] Hairis registration Image Retrieval 图像检索曾经很热,在2000年之后似乎消停了一段时间。最近各种图像的不变性特征提出来之后,再加上互联网搜索的商业需求,这个方向似乎又要火起来了,尤其是在商业界,比如淘淘搜。这仍然是一个非常值得关注的方面。而且图像检索与目标识别具有相通之处,比如特征提取和特征降维。这方面的文章值得一读。在最后给出了两篇Book chapter,其中一篇还是中文的。 [2000 PAMI] Content-based image retrieval at the end of the early years [2000 TIP] PicToSeek Combining Color and Shape Invariant Features for Image Retrieval [2002] Content-Based Image Retrieval Systems A Survey [2008] Content-Based Image Retrieval-Literature Survey [2010] Plant Image Retrieval Using Color,Shape and Texture Features [2012 PAMI] A Multimedia Retrieval Framework Based on Semi-Supervised Ranking and Relevance Feedback CBIR Chinese fundament of cbir Image Segmentation 图像分割,非常基本但又非常难的一个问题。建议看Sonka和冈萨雷斯的书。这里给出几篇比较好的文章,再次看到了J Malik。他们给出了源代码和测试集,有兴趣的话可以试试。 [2004 IJCV] Efficient Graph-Based Image Segmentation [2008 CVIU] Image segmentation evaluation A survey of unsupervised methods [2011 PAMI] Contour Detection and Hierarchical Image Segmentation Level Set 大名鼎鼎的水平集,解决了Snake固有的缺点。Level set的两位提出者Sethian和Osher最后反目,实在让人遗憾。个人以为,这种方法除了迭代比较费时,在真实场景中的表现让人生疑。不过,2008年ECCV上的PWP方法在结果上很吸引人。在重初始化方面,Chunming Li给出了比较好的解决方案 [1995 PAMI] Shape modeling with front propagation_ a level set approach [2001 JCP] Level Set Methods_ An Overview and Some Recent Results [2005 CVIU] Geodesic active regions and level set methods for motion estimation and tracking [2007 IJCV] A Review of Statistical Approaches to Level Set Segmentation [2008 ECCV] Robust Real-Time Visual Tracking using Pixel-Wise Posteriors [2010 TIP] Distance Regularized Level Set Evolution and its Application to Image Segmentation Pyramid 其实小波变换就是一种金字塔分解算法,而且具有无失真重构和非冗余的优点。Adelson在1983年提出的Pyramid优点是比较简单,实现起来比较方便。 [1983] The Laplacian Pyramid as a Compact Image Code Radon Transform Radon变换也是一种很重要的变换,它构成了图像重建的基础。关于图像重建和radon变换,可以参考章毓晋老师的书,讲的比较清楚。 [1993 PAMI] Image representation via a finite Radon transform [1993 TIP] The fast discrete radon transform I theory [2007 IVC] Generalised finite radon transform for N×N images Scale Space 尺度空间滤波在现代不变特征中是一个非常重要的概念,有人说SIFT的提出者Lowe是不变特征之父,而Linderburg是不变特征之母。虽然尺度空间滤波是Witkin最早提出的,但其理论体系的完善和应用还是Linderburg的功劳。其在1998年IJCV上的两篇文章值得一读,不管是特征提取方面还是边缘检测方面。 [1987] Scale-space filtering [1990 PAMI] Scale-Space for Discrete Signals [1994] Scale-space theory A basic tool for analysing structures at different scales [1998 IJCV] Edge Detection and Ridge Detection with Automatic Scale Selection [1998 IJCV] Feature Detection with Automatic Scale Selection Snake 活动轮廓模型,改变了传统的图像分割的方法,用能量收缩的方法得到一个统计意义上的能量最小(最大)的边缘。 [1987 IJCV] Snakes Active Contour Models [1996 ] deformable model in medical image A Survey [1997 IJCV] geodesic active contour [1998 TIP] Snakes, shapes, and gradient vector flow [2000 PAMI] Geodesic active contours and level sets for the detection and tracking of moving objects [2001 TIP] Active contours without edges Super Resolution 超分辨率分析。对这个方向没有研究,简单列几篇文章。其中Yang Jianchao的那篇在IEEE上的下载率一直居高不下。 [2002] Example-Based Super-Resolution [2009 ICCV] Super-Resolution from a Single Image [2010 TIP] Image Super-Resolution Via Sparse Representation Thresholding 阈值分割是一种简单有效的图像分割算法。这个topic在冈萨雷斯的书里面讲的比较多。这里列出OTSU的原始文章以及一篇不错的综述。 [1979 IEEE] OTSU A threshold selection method from gray-level histograms [2001 JISE] A Fast Algorithm for Multilevel Thresholding [2004 JEI] Survey over image thresholding techniques and quantitative performance evaluation Watershed 分水岭算法是一种非常有效的图像分割算法,它克服了传统的阈值分割方法的缺点,尤其是Marker-Controlled Watershed,值得关注。Watershed在冈萨雷斯的书里面讲的比较详细。 [1991 PAMI] Watersheds in digital spaces an efficient algorithm based on immersion simulations [2001]The Watershed Transform Definitions, Algorithms and Parallelizat on Strategies 五、 计算机视觉这一章是计算机视觉部分,主要侧重在底层特征提取,视频分析,跟踪,目标检测和识别方面等方面。对于自己不太熟悉的领域比如摄像机标定和立体视觉,仅仅列出上google上引用次数比较多的文献。有一些刚刚出版的文章,个人非常喜欢,也列出来了。 Active Appearance Models 活动表观模型和活动轮廓模型基本思想来源Snake,现在在人脸三维建模方面得到了很成功的应用,这里列出了三篇最早最经典的文章。对这个领域有兴趣的可以从这三篇文章开始入手。 [1998 ECCV] Active Appearance Models [2001 PAMI] Active Appearance Models Active Shape Models [1995 CVIU]Active Shape Models-Their Training and Application Background modeling and subtraction 背景建模一直是视频分析尤其是目标检测中的一项关键技术。虽然最近一直有一些新技术的产生,demo效果也很好,比如基于dynamical texture的方法。但最经典的还是Stauffer等在1999年和2000年提出的GMM方法,他们最大的贡献在于不用EM去做高斯拟合,而是采用了一种迭代的算法,这样就不需要保存很多帧的数据,节省了buffer。Zivkovic在2004年的ICPR和PAMI上提出了动态确定高斯数目的方法,把混合高斯模型做到了极致。这种方法效果也很好,而且易于实现。在OpenCV中有现成的函数可以调用。在背景建模大家族里,无参数方法(2000 ECCV)和Vibe方法也值得关注。 [1997 PAMI] Pfinder Real-Time Tracking of the Human Body [1999 CVPR] Adaptive background mixture models for real-time tracking [1999 ICCV] Wallflower Principles and Practice of Background Maintenance [2000 ECCV] Non-parametric Model for Background Subtraction [2000 PAMI] Learning Patterns of Activity Using Real-Time Tracking [2002 PIEEE] Background and foreground modeling using nonparametric kernel density estimation for visual surveillance [2004 ICPR] Improved adaptive Gaussian mixture model for background subtraction [2004 PAMI] Recursive unsupervised learning of finite mixture models [2006 PRL] Efficient adaptive density estimation per image pixel for the task of background subtraction [2011 TIP] ViBe A Universal Background Subtraction Algorithm for Video Sequences Bag of Words 词袋,在这方面暂时没有什么研究。列出三篇引用率很高的文章,以后逐步解剖之。 [2003 ICCV] Video Google A Text Retrieval Approach to Object Matching in Videos [2004 ECCV] Visual Categorization with Bags of Keypoints [2006 CVPR] Beyond bags of features Spatial pyramid matching for recognizing natural scene categories BRIEF BRIEF是Binary Robust Independent Elementary Features的简称,是近年来比较受关注的特征描述的方法。ORB也是基于BRIEF的。 [2010 ECCV] BRIEF Binary Robust Independent Elementary Features [2011 ICCV] ORB an efficient alternative to SIFT or SURF [2012 PAMI] BRIEF Computing a Local Binary Descriptor Very Fast Camera Calibration and Stereo Vision 非常不熟悉的领域。仅仅列出了十来篇重要的文献,供以后学习。 [1979 Marr] A Computational Theory of Human Stereo Vision [1985] Computational vision and regularization theory [1987 IEEE] A versatile camera calibration technique for high-accuracy 3D machine vision metrology using off-the-shelf TV cameras and lenses [1987] Probabilistic Solution of Ill-Posed Problems in Computational Vision [1988 PIEEE] Ill-Posed Problems in Early Vision [1989 IJCV] Kalman Filter-based Algorithms for Estimating Depth from Image Sequences [1990 IJCV] Relative Orientation [1990 IJCV] Using vanishing points for camera calibration [1992 ECCV] Camera self-calibration Theory and experiments [1992 IJCV] A theory of self-calibration of a moving camera [1992 PAMI] Camera calibration with distortion models and accuracy evaluation [1994 IJCV] The Fundamental Matrix Theory, Algorithms, and Stability Analysis [1994 PAMI] a stereo matching algorithm with an adaptive window theory and experiment [1999 ICCV] Flexible camera calibration by viewing a plane from unknown orientations [1999 IWAR] Marker tracking and hmd calibration for a video-based augmented reality conferencing system [2000 PAMI] A flexible new technique for camera calibration Color and Histogram Feature 这里面主要来源于图像检索,早期的图像检测基本基于全局的特征,其中最显著的就是颜色特征。这一部分可以和前面的Color知识放在一起的。 [1995 SPIE] Similarity of color images [1996 PR] IMAGE RETRIEVAL USING COLOR AND SHAPE [1996] comparing images using color coherence vectors [1997 ] Image Indexing Using Color Correlograms [2001 TIP] An Efficient Color Representation for Image Retrieval [2009 CVIU] Performance evaluation of local colour invariants Deformable Part Model 大红大热的DPM,在OpenCV中有一个专门的topic讲DPM和latent svm [2008 CVPR] A Discriminatively Trained, Multiscale, Deformable Part Model [2010 CVPR] Cascade Object Detection with Deformable Part Models [2010 PAMI] Object Detection with Discriminatively Trained Part-Based Models Distance Transformations 距离变换,在OpenCV中也有实现。用来在二值图像中寻找种子点非常方便。 [1986 CVGIP] Distance Transformations in Digital Images [2008 ACM] 2D Euclidean Distance Transform Algorithms A Comparative Survey Face Detection 最成熟最有名的当属Haar+Adaboost [1998 PAMI] Neural Network-Based Face Detection [2002 PAMI] Detecting faces in images a survey [2002 PAMI] Face Detection in Color Images [2004 IJCV] Robust Real-Time Face Detection Face Recognition 不熟悉,简单罗列之。 [1991] Face Recognition Using Eigenfaces [2000 PAMI] Automatic Analysis of Facial Expressions The State of the Art [2000] Face Recognition A Literature Survey [2006 PR] Face recognition from a single image per person A survey [2009 PAMI] Robust Face Recognition via Sparse Representation FAST 用机器学习的方法来提取角点,号称很快很好。 [2006 ECCV] Machine learning for high-speed corner detection [2010 PAMI] Faster and Better A Machine Learning Approach to Corner Detection Feature Extraction 这里的特征主要都是各种不变性特征,SIFT,Harris,MSER等也属于这一类。把它们单独列出来是因为这些方法更流行一点。关于不变性特征,王永明与王贵锦合著的《图像局部不变性特征与描述》写的还不错。Mikolajczyk在2005年的PAMI上的文章以及2007年的综述是不错的学习材料。 [1989 PAMI] On the detection of dominant points on digital curves [1997 IJCV] SUSAN—A New Approach to Low Level Image Processing [2004 IJCV] Matching Widely Separated Views Based on Affine Invariant Regions [2004 IJCV] Scale & Affine Invariant Interest Point Detectors [2005 PAMI] A performance evaluation of local descriptors [2006 IJCV] A Comparison of Affine Region Detectors [2007 FAT] Local Invariant Feature Detectors - A Survey [2011 IJCV] Evaluation of Interest Point Detectors and Feature Descriptors Feature Matching Fua课题组在今年PAMI上的一篇文章,感觉还不错 [2012 PAMI] LDAHash Improved Matching with Smaller Descriptors Harris 虽然过去了很多年,Harris角点检测仍然广泛使用,而且基于它有很多变形。如果仔细看了这种方法,从直观也可以感觉到这是一种很稳健的方法。 [1988 Harris] A combined corner and edge detector Histograms of Oriented Gradients HoG方法也在OpenCV中实现了:HOGDescriptor。 [2005 CVPR] Histograms of Oriented Gradients for Human Detection NavneetDalalThesis.pdf Image Distance [1993 PAMI] Comparing Images Using the Hausdorff Distance Image Stitching 图像拼接,另一个相关的词是Panoramic。在Computer Vision: Algorithms and Applications一书中,有专门一章是讨论这个问题。这里的两面文章一篇是综述,一篇是这方面很经典的文章。 [2006 Fnd] Image Alignment and Stitching A Tutorial [2007 IJCV] Automatic Panoramic Image Stitching using Invariant Features KLT KLT跟踪算法,基于Lucas-Kanade提出的配准算法。除了三篇很经典的文章,最后一篇给出了OpenCV实现KLT的细节。 [1981] An Iterative Image Registration Technique with an Application to Stereo Vision full version [1994 CVPR] Good Features to Track [2004 IJCV] Lucas-Kanade 20 Years On A Unifying Framework Pyramidal Implementation of the Lucas Kanade Feature Tracker OpenCV Local Binary Pattern LBP。OpenCV的Cascade分类器也支持LBP,用来取代Haar特征。 [2002 PAMI] Multiresolution gray-scale and rotation Invariant Texture Classification with Local Binary Patterns [2004 ECCV] Face Recognition with Local Binary Patterns [2006 PAMI] Face Description with Local Binary Patterns [2011 TIP] Rotation-Invariant Image and Video Description With Local Binary Pattern Features Low-Level Vision 关于Low level vision的两篇很不错的文章 [1998 TIP] A general framework for low level vision [2000 IJCV] Learning Low-Level Vision Mean Shift 均值漂移算法,在跟踪中非常流行的方法。Comaniciu在这个方面做出了重要的贡献。最后三篇,一篇是CVIU上的top download文章,一篇是最新的PAMI上关于Mean Shift的文章,一篇是OpenCV实现的文章。 [1995 PAMI] Mean shift, mode seeking, and clustering [2002 PAMI] Mean shift a robust approach toward feature space analysis [2003 CVPR] Mean-shift blob tracking through scale space [2009 CVIU] Object tracking using SIFT features and mean shift [2012 PAMI] Mean Shift Trackers with Cross-Bin Metrics OpenCV Computer Vision Face Tracking For Use in a Perceptual User Interface MSER 这篇文章发表在2002年的BMVC上,后来直接录用到2004年的IVC上,内容差不多。MSER在Sonka的书里面也有提到。 [2002 BMVC] Robust Wide Baseline Stereo from Maximally Stable Extremal Regions [2003] MSER Author Presentation [2004 IVC] Robust wide-baseline stereo from maximally stable extremal regions [2011 PAMI] Are MSER Features Really Interesting Object Detection 首先要说的是第一篇文章的作者,Kah-Kay Sung。他是MIT的博士,后来到新加坡国立任教,极具潜力的一个老师。不幸的是,他和他的妻子都在2000年的新加坡空难中遇难,让人唏嘘不已。 http://en.wikipedia.org/wiki/Singapore\_Airlines\_Flight_006 最后一篇文章也是Fua课题组的,作者给出的demo效果相当好。 [1998 PAMI] Example-based learning for view-based human face detection [2003 IJCV] Learning the Statistics of People in Images and Video [2011 PAMI] Learning to Detect a Salient Object [2012 PAMI] A Real-Time Deformable Detector Object Tracking 跟踪也是计算机视觉中的经典问题。粒子滤波,卡尔曼滤波,KLT,mean shift,光流都跟它有关系。这里列出的是传统意义上的跟踪,尤其值得一看的是2008的Survey和2003年的Kernel based tracking。 [2003 PAMI] Kernel-based object tracking [2007 PAMI] Tracking People by Learning Their Appearance [2008 ACM] Object Tracking A Survey [2008 PAMI] Segmentation and Tracking of Multiple Humans in Crowded Environments [2011 PAMI] Hough Forests for Object Detection, Tracking, and Action Recognition [2011 PAMI] Robust Object Tracking with Online Multiple Instance Learning [2012 IJCV] PWP3D Real-Time Segmentation and Tracking of 3D Objects OCR 一个非常成熟的领域,已经很好的商业化了。 [1992 IEEE] Historical review of OCR research and development Video OCR A Survey and Practitioner’s Guide Optical Flow 光流法,视频分析所必需掌握的一种算法。 [1981 AI] Determine Optical Flow [1994 IJCV] Performance of optical flow techniques [1995 ACM] The Computation of Optical Flow [2004 TR] Tutorial Computing 2D and 3D Optical Flow [2005 BOOK] Optical Flow Estimation [2008 ECCV] Learning Optical Flow [2011 IJCV] A Database and Evaluation Methodology for Optical Flow Particle Filter 粒子滤波,主要给出的是综述以及1998 IJCV上的关于粒子滤波发展早期的经典文章。 [1998 IJCV] CONDENSATION—Conditional Density Propagation for Visual Tracking [2002 TSP] A tutorial on particle filters for online nonlinear non-Gaussian Bayesian tracking [2002 TSP] Particle filters for positioning, navigation, and tracking [2003 SPM] particle filter Pedestrian and Human detection 仍然是综述类,关于行人和人体的运动检测和动作识别。 [1999 CVIU] Visual analysis of human movement_ A survey [2001 CVIU] A Survey of Computer Vision-Based Human Motion Capture [2005 TIP] Image change detection algorithms a systematic survey [2006 CVIU] a survey of avdances in vision based human motion capture [2007 CVIU] Vision-based human motion analysis An overview [2007 IJCV] Pedestrian Detection via Periodic Motion Analysis [2007 PR] A survey of skin-color modeling and detection methods [2010 IVC] A survey on vision-based human action recognition [2012 PAMI] Pedestrian Detection An Evaluation of the State of the Art Scene Classification 当相机越来越傻瓜化的时候,自动场景识别就非常重要。这是比拼谁家的Auto功能做的比较好的时候了。 [2001 IJCV] Modeling the Shape of the Scene A Holistic Representation of the Spatial Envelope [2001 PAMI] Visual Word Ambiguity [2007 PAMI] A Thousand Words in a Scene [2010 PAMI] Evaluating Color Descriptors for Object and Scene Recognition [2011 PAMI] CENTRIST A Visual Descriptor for Scene Categorization Shadow Detection [2003 PAMI] Detecting moving shadows– algorithms and evaluation Shape 关于形状,主要是两个方面:形状的表示和形状的识别。形状的表示主要是从边缘或者区域当中提取不变性特征,用来做检索或者识别。这方面Sonka的书讲的比较系统。2008年的那篇综述在这方面也讲的不错。至于形状识别,最牛的当属J Malik等提出的Shape Context。 [1993 PR] IMPROVED MOMENT INVARIANTS FOR SHAPE DISCRIMINATION [1993 PR] Pattern Recognition by Affine Moment Invariants [1996 PR] IMAGE RETRIEVAL USING COLOR AND SHAPE [2001 SMI] Shape matching similarity measures and algorithms [2002 PAMI] Shape matching and object recognition using shape contexts [2004 PR] Review of shape representation and description techniques [2006 PAMI] Integral Invariants for Shape Matching [2008] A Survey of Shape Feature Extraction Techniques SIFT 关于SIFT,实在不需要介绍太多,一万多次的引用已经说明问题了。SURF和PCA-SIFT也是属于这个系列。后面列出了几篇跟SIFT有关的问题。 [1999 ICCV] Object recognition from local scale-invariant features [2000 IJCV] Evaluation of Interest Point Detectors [2003 CVIU] Speeded-Up Robust Features (SURF) [2004 CVPR] PCA-SIFT A More Distinctive Representation for Local Image Descriptors [2004 IJCV] Distinctive Image Features from Scale-Invariant Keypoints [2010 IJCV] Improving Bag-of-Features for Large Scale Image Search [2011 PAMI] SIFTflow Dense Correspondence across Scenes and its Applications SLAM Simultaneous Localization and Mapping, 同步定位与建图。 SLAM问题可以描述为: 机器人在未知环境中从一个未知位置开始移动,在移动过程中根据位置估计和地图进行自身定位,同时在自身定位的基础上建造增量式地图,实现机器人的自主定位和导航。 [2002 PAMI] Simultaneous Localization and Map-Building Using Active Vision [2007 PAMI] MonoSLAM Real-Time Single Camera SLAM Texture Feature 纹理特征也是物体识别和检索的一个重要特征集。 [1973] Textural features for image classification [1979 ] Statistical and structural approaches to texture [1996 PAMI] Texture features for browsing and retrieval of image data [2002 PR] Brief review of invariant texture analysis methods [2012 TIP] Color Local Texture Features for Color Face Recognition TLD Kadal创立了TLD,跟踪学习检测同步进行,达到稳健跟踪的目的。他的两个导师也是大名鼎鼎,一个是发明MSER的Matas,一个是Mikolajczyk。他还创立了一个公司TLD Vision s.r.o. 这里给出了他的系列文章,最后一篇是刚出来的PAMI。 [2009] Online learning of robust object detectors during unstable tracking [2010 CVPR] P-N Learning Bootstrapping Binary Classifiers by Structural Constraints [2010 ICIP] FACE-TLD TRACKING-LEARNING-DETECTION APPLIED TO FACES [2012 PAMI] Tracking-Learning-Detection Video Surveillance 前两篇是两个很有名的视频监控系统,里面包含了很丰富的信息量,比如CMU的那个系统里面的背景建模算法也是相当简单有效的。最后一篇是比较近的综述。 [2000 CMU TR] A System for Video Surveillance and Monitoring [2000 PAMI] W4– real-time surveillance of people and their activities [2008 MVA] The evolution of video surveillance an overview Viola-Jones Haar+Adaboost的弱弱联手,组成了最强大的利器。在OpenCV里面有它的实现,也可以选择用LBP来代替Haar特征。 [2001 CVPR] Rapid object detection using a boosted cascade of simple features [2004 IJCV] Robust Real-time Face Detection 六、 结束语历时一个多月,终于用业余时间把这些资料整理出来了,总算了却了一块心病,也不至于再看着一堆资料发愁了。以后可能会有些小修小补,但不会有太大的变化了。万里长征走完了第一步,剩下的就是理解和消化了。借新浪ishare共享出来,希望能够对你的科研也有一定的帮助。最后简单统计一下各个年份出现的频率。 文章总数:372 2012年: 10 2011年: 20 2010年: 20 2009年: 14 2008年: 18 2007年: 13 2006年: 14 2005年: 9 2004年: 24 2003年: 22 2002年: 21 2001年: 21 2000年: 23 1999年: 10 1998年: 22 1997年: 8 1996年: 9 1995年: 9 1994年: 7 1993年: 5 1992年: 11 1991年: 5 1990年: 6 1980-1989: 22 1960-1979: 9 截至2012年-图像处理与计算机视觉基础总结]]></content>
</entry>
<entry>
<title><![CDATA[C++中的多重继承]]></title>
<url>%2F2018-10-16-C%2B%2B%E4%B8%AD%E7%9A%84%E5%A4%9A%E9%87%8D%E7%BB%A7%E6%89%BF.html</url>
<content type="text"><![CDATA[尽管大多数应用程序都使用单个基类的公用继承,但有些时候单继承是不够用的,因为可能无法为问题域建模或对模型带来不必要的复杂性。在这种情况下,多重继承可以更直接地为应用程序建模。 一、基本概念========== 多重继承是从多于一个直接基类派生类的能力,多重继承的派生类继承其父类的属性。12345678class ZooAnimal{};class Bear : public ZooAnimal{};class Endangered{};class Panda : public Bear, public Endangered{}; 注意: (1)与单继承一样,只有在定义之后,类才可以用作多重继承的基类。 (2)对于类可以继承的基类的数目,没有语言强加的限制,但在一个给定派生列表中,一个基类只能出现一次。 1、多重继承的派生类从每个基类中继承状态1Panda ying_yang("ying_yang"); 对象ying_yang包含一个Bear子类对象、一个Endangered子类对象以及Panda类中声明的非static数据成员。如下图所示: 2、派生类构造函数初始化所有基类派生类构造函数可以早构造函数初始化式中给零个或多个基类传递值。123Panda::Panda(string name, bool onExhibit) : Bear(name, onExhibit, "Panda"), Endangered(Endangered::critical){} 构造函数初始化式只能控制用于初始化基类的值,不能控制基类的构造次序。基类构造函数按照基类构造函数在类派生列表中的出现次序调用。对于Panda,基类初始化次序是: (1)ZooAnimal。 (2)Bear,第一个直接基类。 (3)Endangered,第二个直接基类,它本身没有基类。 (4)Panda,初始化本身成员,然后运行它的构造函数的函数体。 注意:构造函数调用次序既不受构造函数初始化列表中出现的基类的影响,也不受基类在构造函数初始化列表中的出现次序的影响。例如:1Panda::Panda() : Endangered(Endangered::critical){} 这个构造函数将隐式调用Bear的默认构造函数,尽管它不出现在构造函数初始化列表中,但仍然在Endangered类构造函数之前调用。 3、析构的次序按照构造函数运行的逆序调用析构函数。Panda、Endangered、Bear,ZooAnimal。 二、转换与多个基类单个基类情况下,派生类的指针或引用可自动转换为基类的指针或引用。对于多重继承,派生类的指针或引用可以转换为其任意基类的指针或引用。 注意:在多重继承情况下,遇到二义性转换的可能性更大。编译器不会试图根据派生类转换来区别基类间的转换,转换到每个基类都一样好。例如:12void print(const Bear&);void print(const Endangered&); 通过Panda对象调用print时,会导致一个编译时错误。 1、基于指针或引用类型的查找与单继承一样,用基类的指针或引用只能访问基类中定义(或继承)的成员,不能访问派生类中引入的成员。当一个类派生于多个基类的时候,那些基类之间没有隐含的关系,不允许使用一个基类的指针访问其他基类的成员。例如:12345678910111213141516171819202122232425262728293031323334353637383940414243class ZooAnimal{public: virtual void print(){} virtual ~ZooAnimal(){}};class Bear : public ZooAnimal{public: virtual void print() { cout << "I am Bear" << endl; } virtual void toes(){}};class Endangered{public: virtual void print(){} virtual void highlight() { cout << "I am Endangered.highlight" << endl; } virtual ~Endangered(){}};class Panda : public Bear, public Endangered{public: virtual void print() { cout << "I am Panda" << endl; } virtual void highlight() { cout << "I am Panda.highlight" << endl; } virtual void toes(){} virtual void cuddle(){} virtual ~Panda() { cout << "Goodby Panda" << endl; }}; 当有如下调用发生时:1234567891011121314151617int main(){ Bear *pb = new Panda(); pb->print(); //ok: Panda::print// pb->cuddle(); //error: not part of Bear interface// pb->highlight(); //error: not part of Bear interface delete pb; //Panda::~Panda Endangered *pe = new Panda(); pe->print(); //ok: Panda::print// pe->toes(); //error: not part of Endangered interface// pe->cuddle(); //error: not part of Endangered interface pe->highlight(); //ok: Panda::highlight delete pe; //Panda::~Panda return 0;} 2、确定使用哪个虚析构函数我们假定所有根基类都将它们的析构函数定义为虚函数,那么通过下面几种删除指针方法,虚析构函数处理都是一致的。1234delete pz; //pz is a ZooAnimal*delete pb; //pb is a Bear*delete pp; //pp is a Panda*delete pe; //pe is a Endangered* 假定上面四个指针都指向Panda对象,则每种情况发生完全相同的析构函数调用次序,即与构造次序是逆序的:通过虚机制调用Panda析构函数,再依次调用Endangered、Bear,ZooAnimal的析构函数。 三、多重继承派生类的复制控制多重继承的派生类使用基类自己的复制构造函数、赋值操作符,析构函数隐式构造、赋值或撤销每个基类。下面我们做几个小实验:12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788class ZooAnimal{public: ZooAnimal() { cout << "I am ZooAnimal default constructor" << endl; } ZooAnimal(const ZooAnimal&) { cout << "I am ZooAnimal copy constructor" << endl; } virtual ~ZooAnimal() { cout << "I am ZooAnimal destructor" << endl; } ZooAnimal& operator=(const ZooAnimal&) { cout << "I am ZooAnimal copy operator=" << endl; return *this; }};class Bear : public ZooAnimal{public: Bear() { cout << "I am Bear default constructor" << endl; } Bear(const Bear&) { cout << "I am Bear copy constructor" << endl; } virtual ~Bear() { cout << "I am Bear destructor" << endl; } Bear& operator=(const Bear&) { cout << "I am Bear copy operator=" << endl; return *this; }};class Endangered{public: Endangered() { cout << "I am Endangered default constructor" << endl; } Endangered(const Endangered&) { cout << "I am Endangered copy constructor" << endl; } virtual ~Endangered() { cout << "I am Endangered destructor" << endl; } Endangered& operator=(const Endangered&) { cout << "I am Endangered copy operator=" << endl; return *this; }};class Panda : public Bear, public Endangered{public: Panda() { cout << "I am Panda default constructor" << endl; } Panda(const Panda&) { cout << "I am Panda copy constructor" << endl; } virtual ~Panda() { cout << "I am Panda destructor" << endl; } Panda& operator=(const Panda&) { cout << "I am Panda copy operator=" << endl; return *this; }}; 还是前面的类,只不过我将没有必要的虚函数去掉了。下面我执行以下操作:12345678910111213141516int main(){ cout << "TEST 1" << endl; Panda ying_ying; cout << endl << endl; cout << "TEST 2" << endl; Panda zing_zing = ying_ying; cout << endl << endl; cout << "TEST 3" << endl; zing_zing = ying_ying; cout << endl << endl; return 0;} 下面我们先来看TEST1的结果: 这个结果是毫无疑问的,先调用基类构造函数,再调用派生类。 接着,我们来看TEST2的结果: 首先调用默认构造函数构造一个zing_zing对象,然后调用拷贝构造函数,将ying_ying拷贝至zing_zing。注意:这里用的是拷贝构造函数,而不是赋值操作符,那什么时候用赋值操作符呢?我们接着看TEST3的结果: 这种情况才调用赋值操作符:就是两个对象都已经分配内存后,再进行赋值。这里有个疑问,基类也定义了operator=了,为什么不调用基类的operator=呢?我们将Panda类的operator=注释掉,重新来做TEST3,好玩的结果出现了: Panda的合成赋值操作符调用了两个基类的operator=。 我们得出以下结论:如果派生类定义了自己的复制构造函数或赋值操作符,则负责复制(赋值)所有的基类子部分,而不再调用基类相应函数。只有派生类使用合成版本的复制构造函数或赋值操作符,才自动调用基类部分相应的函数。 最后我们来看一下析构函数的表现: 析构函数的行为是符合我们预期的,这里有一点我没有体现出来就是zing_zing是ying_ying之后定义的对象,所以zing_zing的构造函数先执行(前4行),后4行代表ying_ying构造函数的执行。如果具有多个基类的类定义了自己的析构函数,则该析构函数只负责清除派生类。 四、多重继承下的类作用域在多重继承下,多个基类作用域可以包围派生类作用域。查找时,同时检查所有基类继承子树,例如:并行查找Endangered和Bear/ ZooAnimal子树。如果在多个子树上找到该名字,那个名字必须显式指定使用哪个基类。否则,该名字的使用是二义性的。 例如:Endangered类和Bear类都有print函数,则ying_ying.print()将导致编译时错误。 注意: (1)Panda类的派生导致有两个名为print的成员是合法的。派生只是导致潜在的二义性,如果没有Panda对象调用print,就可避免这个二义性。你可以Bear::print或Endangered::print来调用。 (2)当然,如果只在一个基类子树上找到声明是不会出错的。 下面仍然有个小实验要做:12345678910111213141516171819class ZooAnimal{public: //void print(int x){}};class Bear : public ZooAnimal{public: void print(int x){}};class Endangered{public: void print(){}};class Panda : public Bear, public Endangered{public:}; TEST1:将两个基类Bear和Endangered两个print的形参表设为不同。 TEST2:将Bear中的print去掉,在ZooAnimal中增加print。 TEST3:将Endangered中print设置为private访问。 以上三种情况下,当我这样调用ying_ying.print()或ying_ying.print(1)时,都显示编译时错误(二义性)。 我们的得出这样的结论:名字查找的过程是这样的,首先编译器找到一个匹配的声明(找到两个匹配的声明,这导致二义性),然后编译器才确定所找到的声明是否合法。 所以说,当我们调用这样的函数时,应该这样ying_ying.Bear::print()。 main.cpp123456789#include <iostream>#include "CircleWithText.h"using namespace std;int main(){ CircleWithText cm(1,2,3,"Hello!"); return 0;} Point.h1234567891011121314151617181920212223 #ifndef POINT_H_INCLUDED #define POINT_H_INCLUDED #include<iostream> #include<string> using namespace std; class Point { int x,y; public: Point(int x1=0,int y1=0):x(x1),y(y1) { cout<<"调用Point类对象成员的构造函数!"<<endl; } ~Point() { cout<<"调用Point类对象成员的析构函数!"<<endl; } }; #endif // POINT_H_INCLUDED ``` `Text.h` #ifndef TEXT_H_INCLUDED #define TEXT_H_INCLUDED #include<iostream> #include<string> #include <string.h> using namespace std; class Text { char text[100]; public: Text(char *str) { strcpy(text,str); cout<<"调用基类Text的构造函数!"<<endl; } ~Text() { cout<<"调用基类Text的析构函数!"<<endl; } }; #endif // TEXT_H_INCLUDED 1`Circle.h` #ifndef CIRCLE_H_INCLUDED #define CIRCLE_H_INCLUDED #include"Point.h" class Circle { Point center; int radius; public : Circle(int cx,int cy,int r):center(cx,cy),radius(r) { cout<<"调用基类Circle的构造函数!"<<endl; } ~Circle() { cout<<"调用基类Circle的析构函数!"<<endl; } }; #endif // CIRCLE_H_INCLUDED 12`CircleWithText.h` #ifndef CIRCLEWITHTEXT_H_INCLUDED #define CIRCLEWITHTEXT_H_INCLUDED #include "Text.h" #include "Circle.h" class CircleWithText:public Text,public Circle { Point textPosition; public: CircleWithText(int cx,int cy,int r,char *msg):Circle(cx,cy,r),Text(msg) { cout<<"调用派生类CircleWithText的构造函数!"<<endl; } ~CircleWithText() { cout<<"调用CircleWithText的析构函数!"<<endl; } }; #endif // CIRCLEWITHTEXT_H_INCLUDED `打印如下: 调用基类Text的构造函数! 调用Point类对象成员的构造函数! 调用基类Circle的构造函数! 调用Point类对象成员的构造函数! 调用派生类CircleWithText的构造函数! 调用CircleWithText的析构函数! 调用Point类对象成员的析构函数! 调用基类Circle的析构函数! 调用Point类对象成员的析构函数! 调用基类Text的析构函数!]]></content>
<categories>
<category>C++</category>
</categories>
</entry>
<entry>
<title><![CDATA[C++函数重载]]></title>
<url>%2F2018-10-15-C%2B%2B%E5%87%BD%E6%95%B0%E9%87%8D%E8%BD%BD.html</url>
<content type="text"><![CDATA[C++中的函数声明比C有更多的功能。为了更清楚描述清楚影响的不同,我们先来看看C和C++中函数最主要的差异是什么。 很多C库包含至少一组的命名非常接近的函数。每个函数除了参数或返回值不同,功能在本质上是相同的。 标准C库也包含若干这样的组。例如,有一组“abs”函数专门用来计算一个数值的绝对值。组里包含:12345678 int abs(int i); long int labs(long int li); float fabsf(float f); double fabs(double d); long double fabsl(long double ld);``` 函数fabsf和fabsl不属于早期C标准,却存在于修订后的C9X标准中。 标准C库还有一个“put”函数组: int fputc(int c, FILE *f); int fputs(char const *s, FILE *f); int putchar(int c); int puts(char const *s); 123456这些函数都用来往文件里写入,尽管,写的内容的类型不同,文件的指定方式也有差异。 函数fputc和putchar每次写一个字节(传入的其实是int),而puts和fputs每次写从null结尾字符串中得到的所有字节。函数fputc和fputs写入的文件是由参数传入的,而putchar和puts总是往标准输出中写。 尽管组中的函数名字不同,但程序员还是把它们当做只有一个名字的函数。例如,从来没听过程序员说fputd一个字符或fputs一个字符串,而是说put一个字符或put一个字符串。" 我们通常把函数fputc和fputs当做一个put函数。我们也通常把函数abs。当我们已经明了组里的每一个函数实际上都是不同的函数,那么没有理由再啰嗦下去了。### 重载声明让函数名字跟描述程序行为的名字保持一致是一个良好的编程习惯。每种负责输出的函数最好是都叫做put。不幸的是,C不允许程序中有同名的函数。 C中独一无二函数名的限定对函数库的使用者和作者都是一种负担。作者需要想象出相近但差异又不能太大的函数名,而使用者需要学会这些不同。一个认真的作者会浪费数小时来设计一组函数名前缀或后缀,以便减少使用者的负担。 C++通过重载函数名来避免这类麻烦。你可以在同一个程序里使用同名的两个或多个函数。函数名重载可以让函数使用起来更“自然”。使用了重载的程序也更容易读和写。(当然,过犹不及,过多的重载也并非好事) C++中声明重载的函数跟声明其它函数没什么不同。只不过它跟其它的某个函数重名。重载函数必须使用不同的变量,否则编译器没法区分它们。 例如,可以定义如下的重载函数put: int put(int c); // putchar int put(int c, FILE *f); // fputc int put(char const *s); // puts int put(char const *s, FILE *f); // fputs 12345678910### 函数的重载的规则* 函数名称必须相同。* 参数列表必须不同(个数不同、类型不同、参数排列顺序不同等)。* 函数的返回类型可以相同也可以不相同。* 仅仅返回类型不同不足以成为函数的重载。### 重载决策当编译器遇到对函数put的调用,它会选择函数参数完全匹配的函数声明进行调用。这个过程叫做重载决策。例如: ` put('a', stdout);` 调用如下的函数声明: ` int put(int c, FILE *f);` 而: `put("Hello\n");` 调用: `int put(char const *s);` 如果编译器没法找到参数匹配的函数,会报错。例如,调用: ` put("Error #", n, stderr);` 会报错,因为没有函数声明了三个变量。 尽管调用的函数的参数个数必须跟匹配的声明函数一致,但参数类型却不必完全一致。C++允许进行一些参数的隐式类型转换。 例如,函数声明如下: int put(int c); int put(int c, FILE *f); 12往一个文件中写入单个字符。在两个函数中,参数c的类型是int而不是char,标准C库使用整型的EOF来表示文件结尾和I/O错误。一个char没办法表示EOF。一个int可以表示所有的char值和EOF。 尽管函数声明了int型参数,但你可以使用char参数来调用。例如: char c; ... put(c); 12重载决策选择了: int put(int c); 12作为匹配函数。这里,编译器把char隐式转换为int。 最佳匹配和歧义Best matches and ambiguities 有可能会有多个重载函数能够匹配一个函数调用。例如,下面的四个函数: void f(int i); void f(long int li); void f(char *p); void f(double d, int i); 12开头的三个函数可以匹配函数调用f(0)。0可以被看做int,long int或`char*`类的空指针。第四个函数没法匹配,因为它需要两个参数。 当面对多个可选函数时,重载决策根据函数参数类型的隐式转换来排序,找出最匹配的那个。例如,在调用f(0)时,参数0位int类型,当调用: void f(char *p); 12需要把int转换为`char*`。当调用: void f(long int li); 12需要把int转换为long int。而: void f(int i); 12是非常准确的匹配。准确的匹配永远是最佳选择。 那么,假设: void f(int i); 1没有被声明。这种情况下,重载决策必须在下面二者中选一个: void f(long int li); void f(char *p); ` 但它们两个不分仲伯,都需要进行类型转换。当重载决策没有办法选出一个最优匹配,那么调用就是不明确的,这会产生一个编译错误。函数重载仅仅是语法层面的,本质上它们还是不同的函数,占用不同的内存,入口地址也不一样。 这就是函数名重载的基本知识。]]></content>
<categories>
<category>C/C++</category>
</categories>
<tags>
<tag>C/C++</tag>
</tags>
</entry>
<entry>
<title><![CDATA[浏览器中输入 URL 回车后...]]></title>
<url>%2F2018-10-15-%E6%B5%8F%E8%A7%88%E5%99%A8%E4%B8%AD%E8%BE%93%E5%85%A5%20URL%20%E5%9B%9E%E8%BD%A6%E5%90%8E.html</url>
<content type="text"><![CDATA[本文摘要:1.DNS域名解析;2.建立TCP连接;3.发送HTTP请求;4.服务器处理请求;5.返回响应结果;6.关闭TCP连接;7.浏览器解析HTML;8.浏览器布局渲染;总结 当我们在浏览器输入网址并回车后,一切从这里开始。 一、DNS域名解析我们在浏览器输入网址,其实就是要向服务器请求我们想要的页面内容,所有浏览器首先要确认的是域名所对应的服务器在哪里。将域名解析成对应的服务器IP地址这项工作,是由DNS服务器来完成的。 客户端收到你输入的域名地址后,它首先去找本地的hosts文件,检查在该文件中是否有相应的域名、IP对应关系,如果有,则向其IP地址发送请求,如果没有,再去找DNS服务器。一般用户很少去编辑修改hosts文件。 DNS服务器层次结构 浏览器客户端向本地DNS服务器发送一个含有域名www.cnblogs.com的DNS查询报文。本地DNS服务器把查询报文转发到根DNS服务器,根DNS服务器注意到其com后缀,于是向本地DNS服务器返回comDNS服务器的IP地址。本地DNS服务器再次向comDNS服务器发送查询请求,comDNS服务器注意到其www.cnblogs.com后缀并用负责该域名的权威DNS服务器的IP地址作为回应。最后,本地DNS服务器将含有www.cnblogs.com的IP地址的响应报文发送给客户端。 从客户端到本地服务器属于递归查询,而DNS服务器之间的交互属于迭代查询。 正常情况下,本地DNS服务器的缓存中已有comDNS服务器的地址,因此请求根域名服务器这一步不是必需的。 二、建立TCP链接费了一顿周折终于拿到服务器IP了,下一步自然就是链接到该服务器。对于客户端与服务器的TCP链接,必然要说的就是『三次握手』。 三次握手 客户端发送一个带有SYN标志的数据包给服务端,服务端收到后,回传一个带有SYN/ACK标志的数据包以示传达确认信息,最后客户端再回传一个带ACK标志的数据包,代表握手结束,连接成功。 上图也可以这么理解: 客户端:“你好,在家不,有你快递。” 服务端:“在的,送来就行。” 客户端:“好嘞。” 三、发送HTTP请求与服务器建立了连接后,就可以向服务器发起请求了。这里我们先看下请求报文的结构(如下图): 请求报文 在浏览器中查看报文首部(以google浏览器为例): 请求行包括请求方法、URI、HTTP版本。首部字段传递重要信息,包括请求首部字段、通用首部字段和实体首部字段。我们可以从报文中看到发出的请求的具体信息。具体每个首部字段的作用,这里不做过多阐述。 四、服务器处理请求服务器端收到请求后的由web服务器(准确说应该是http服务器)处理请求,诸如Apache、Ngnix、IIS等。web服务器解析用户请求,知道了需要调度哪些资源文件,再通过相应的这些资源文件处理用户请求和参数,并调用数据库信息,最后将结果通过web服务器返回给浏览器客户端。 服务器处理请求 五、返回响应结果在HTTP里,有请求就会有响应,哪怕是错误信息。这里我们同样看下响应报文的组成结构: 响应报文 在响应结果中都会有个一个HTTP状态码,比如我们熟知的200、301、404、500等。通过这个状态码我们可以知道服务器端的处理是否正常,并能了解具体的错误。 状态码由3位数字和原因短语组成。根据首位数字,状态码可以分为五类: 状态码类别 六、关闭TCP连接为了避免服务器与客户端双方的资源占用和损耗,当双方没有请求或响应传递时,任意一方都可以发起关闭请求。与创建TCP连接的3次握手类似,关闭TCP连接,需要4次握手。 4次握手 上图可以这么理解: 客户端:“兄弟,我这边没数据要传了,咱关闭连接吧。” 服务端:“收到,我看看我这边有木有数据了。” 服务端:“兄弟,我这边也没数据要传你了,咱可以关闭连接了。” 客户端:“好嘞。” 七、浏览器解析HTML准确地说,浏览器需要加载解析的不仅仅是HTML,还包括CSS、JS。以及还要加载图片、视频等其他媒体资源。 浏览器通过解析HTML,生成DOM树,解析CSS,生成CSS规则树,然后通过DOM树和CSS规则树生成渲染树。渲染树与DOM树不同,渲染树中并没有head、display为none等不必显示的节点。 要注意的是,浏览器的解析过程并非是串连进行的,比如在解析CSS的同时,可以继续加载解析HTML,但在解析执行JS脚本时,会停止解析后续HTML,这就会出现阻塞问题,关于JS阻塞相关问题,这里不过多阐述,后面会单独开篇讲解。 八、浏览器布局渲染根据渲染树布局,计算CSS样式,即每个节点在页面中的大小和位置等几何信息。HTML默认是流式布局的,CSS和js会打破这种布局,改变DOM的外观样式以及大小和位置。这时就要提到两个重要概念:repaint和reflow。 repaint:屏幕的一部分重画,不影响整体布局,比如某个CSS的背景色变了,但元素的几何尺寸和位置不变。 reflow: 意味着元件的几何尺寸变了,我们需要重新验证并计算渲染树。是渲染树的一部分或全部发生了变化。这就是Reflow,或是Layout。 所以我们应该尽量减少reflow和repaint,我想这也是为什么现在很少有用table布局的原因之一。 最后浏览器绘制各个节点,将页面展示给用户。 总结本文系统地讲述从浏览器从输入域名到最终页面展示的整体流程。篇幅所限,本文的每一步讲述其实并不全面,所以后面我会单独就域名解析、HTTP请求/响应、浏览器的解析、渲染等内容单独开篇讲解。 http://www.xuecaijie.com/]]></content>
<categories>
<category>计算机网络</category>
</categories>
<tags>
<tag>计算机网络</tag>
</tags>
</entry>
<entry>
<title><![CDATA[正规的运维工作是什么的?]]></title>
<url>%2F2018-10-15-%E6%AD%A3%E8%A7%84%E7%9A%84%E8%BF%90%E7%BB%B4%E5%B7%A5%E4%BD%9C%E6%98%AF%E4%BB%80%E4%B9%88%E7%9A%84.html</url>
<content type="text"><![CDATA[互联网运维工作,以服务为中心,以稳定、安全、高效为三个基本点,确保公司的互联网业务能够 7×24 小时为用户提供高质量的服务。 运维人员对公司互联网业务所依赖的基础设施、基础服务、线上业务进行稳定性加强,进行日常巡检发现服务可能存在的隐患,对整体架构进行优化以屏蔽常见的运行故障,多数据中接入提高业务的容灾能力。通过监控、日志分析等技术手段,及时发现和响应服务故障,减少服务中断的时间,使公司的互联网业务符合预期的可用性要求,持续稳定地为用户提供务。 在安全方面,运维人员需要关注业务运行所涉及的各个层面,确保用户能够安全、完整地访问在线业务。 从网络边界划分、ACL 管理、流量分析、DDoS 防御,到操作系统、开源软件的漏洞扫描和修补,再到应用服务的XSS、SQL注入防护; 从安全流程梳、代码白盒黑盒扫描、权限审计,到入侵行为检测、业务风险控制等。 运维人员需要保障公司提供的互联网业 运行在安全、可控的状态下,确保公司业务数据和用户隐私数据的安全,同时还需要具备抵御各种恶意攻击的能力。 在确保业务稳定、安全的前提下,还需保障业务高效的运转,公司内快速的产出。运维工作需要对业务进行各方面优化。 比如,IO 优化提升数据库性能,图片压缩降低带宽使用量等,提供的互联网业务以较小的资源投入带来最大的用户价值和体验。同时,还需要通过各种工具平台提升内部产品发布交付的效率,提升公司内运维相关的工作效率。 工作分类运维 运维的工作方向比较多,随着业务规模的不断发展,越成熟的互联网公司,运维岗位会划分得越细。当前很多大型的互联网公司,在初创时期只有系统运维,随着服务规模、服务质量的 要求,也逐渐进行了工作细分。 一般情况下运维团队的工作分类(见图1-1)和职责如下。 图1-1 运维团队的工作分类 系统运维 系统运维负责IDC、网络、CDN和基础服务的建设(LVS、NTP、DNS);负责资产管理,服务器选型、交付和维修。详细的工作职责如下: 1.IDC数据中心建设 收集业务需求,预估未来数据中心的发展规模,从骨干网的分布,数据中心建筑,以及Internet接入、网络攻击防御能力、扩容能力、空间预留、外接专线能力、现场服务支撑能力等方面评估选型数据中心。负责数据中心的建设、现场维护工作。 2.网络建设 设计及规划生产网络架构,这里面包括:数据中心网络架构、传输网架构、CDN网络架构等,以及网络调优等日常运维工作。 3.LVS 负载均衡和 SNAT 建设 LVS 是整个站点架构中的流量入口,根据网络规模和业务需求,构建负载均衡集群。 完成网络与业务服务器的衔接,提供高性能、高可用的负载调度能力,以及统一的网络层防攻击能力。 SNAT .集中提供数据中心的公网访问服务,通过集群化部署,保证出网服务的高性能与高可用。 4.CDN 规划和建设 CDN 工作划分为第三方和自建两部分。 建立第三方 CDN 的选型和调度控制;根据业务发展趋势,规划CDN新节点建设布局;完善CDN业务及监控,保障CDN 系统稳定、高效运行。 分析业务加速频道的文件特性和数量,制定最优的加速策略和资源匹配;负责用户劫持等CDN日常故障排查工作。 5.服务器选型、交付和维护 负责服务器的测试选型,包含服务器整机、部件的基础性测试和业务测试,降低整机功率,提升机架部署密度等。 结合对公司业务的了解,推广新硬件、新方案减少业务的服务器投入规模。负责服务器硬件故障的诊断定位,服务器硬件监控、健康检查工具的开发和维护。 6.OS、内核选型和 OS 相关维护工作 负责整体平台的 OS 选型、定制和内核优化,以及 Patch 的更新和内部版本发布;建立基础的YUM包管理和分发中心,提供常用包版本库;跟进日常各类 OS 相关故障;针对不同的业务类型,提供定向的优化支持。 7.资产管理 记录和管理运维相关的基础物理信息,包括数据中心、网络、机柜、服务器、ACL、IP等各种资源信息,制定有效的流程,确保信息的准确性;开放API接口,为自动化运维提供数据支持。 8.基础服务建设 业务对 DNS、NTP、SYSLOG 等基础服务的依赖非常高,需要设计高可用架构避免单点,提供稳定的基础服务。 应用运维 应用运维负责线上服务的变更、服务状态监控、服务容灾和数据备份等工作,对服务进行例行排查、故障应急处理等工作。详细的工作职责如下所述。 1.设计评审 在产品研发阶段,参与产品设计评审,从运维的角度提出评审意见,使服务满足运维准入的高可用要求。 2.服务管理 负责制定线上业务升级变更及回滚方案,并进行变更实施。掌握所负责的服务及服务间关联关系、服务依赖的各种资源。能够发现服务上的缺陷,及时通报并推进解决。 制定服务稳定性指标及准入标准,同时不断完善和优化程序和系统的功能、效率,提高运行质量。完善监控内容,提高报警准确度。 在线上服务出现故障时,第一时间响应,对已知线上故障能按流程进行通报并按预案执行,未知故障组织相关人员联合排障。 3.资源管理 对各服务的服务器资产进行管理,梳理服务器资源状况、数据中心分布情况、网络专线及带宽情况,能够合理使用服务器资源,根据不同服务的需求,分配不同配置的服务器,确保服务器资源的充分利用。 4.例行检查 制定服务例行排查点,并不断完善。根据制定的服务排查点,对服务进行定期检查。对排查过程中发现的问题,及时进行追查,排除可能存在的隐患。 5.预案管理 确定服务所需的各项监控、系统指标的阈值或临界点,以及出现该情况后的处理预案。建立和更新服务预案文档,并根据日常故障情况不断补充完善,提高预案完备性。能够制定和评审各类预案,周期性进行预案演练,确保预案的可执行性。 6.数据备份 制定数据备份策略,按规范进行数据备份工作。保证数据备份的可用性和完整性,定期开展数据恢复性测试。 数据库运维 数据库运维负责数据存储方案设计、数据库表设计、索引设计和SQL优化,对数据库进行变更、监控、备份、高可用设计等工作。详细的工作职责如下所述。 1.设计评审 在产品研发初始阶段,参与设计方案评审,从DBA的角度提出数据存储方案、库表设计方案、SQL开发标准、索引设计方案等,使服务满足数据库使用的高可用、高性能要求。 2.容量规划 掌握所负责服务的数据库的容量上限,清楚地了解当前瓶颈点,当服务还未到达容量上限时,及时进行优化、分拆或者扩容。 3.数据备份与灾备 制定数据备份与灾备策略,定期完成数据恢复性测试,保证数据备份的可用性和完整性。 4.数据库监控 完善数据库存活和性能监控,及时了解数据库运行状态及故障。 数据库安全 建设数据库账号体系,严格控制账号权限与开放范围,降低误操作和数据泄露的风险;加强离线备份数据的管理,降低数据泄露的风险。 5.数据库高可用和性能优化 对数据库单点风险和故障设计相应的切换方案,降低故障对数据库服务的影响;不断对数据库整体性能进行优化,包括新存储方案引进、硬件优化、文件系统优化、数据库优化、SQL优化等,在保障成本不增加或者少量增加的情况下,数据库可以支撑更多的业务请求。 6.自动化系统建设 设计开发数据库自动化运维系统,包括数据库部署、自动扩容、分库分表、权限管理、备份恢复、SQL审核和上线、故障切换等功能。 7.运维研发 运维研发负责通用的运维平台设计和研发工作,如:资产管理、监控系统、运维平台、数据权限管理系统等。提供各种API供运维或研发人员使用,封装更高层的自动化运维系统。详细的工作职责如下所述。 8.运维平台 记录和管理服务及其关联关系,协助运维人员自动化、流程化地完成日常运维操作,包括机器管理、重启、改名、初始化、域名管理、流量切换和故障预案实施等。 9.监控系统 负责监控系统的设计、开发工作,完成公司服务器和各种网络设备的资源指标、线上业务运行指标的收集、告警、存储、分析、展示和数据挖掘等工作,持续提高告警的及时性、准确性和智能性,促进公司服务器资源的合理化调配。 10.自动化部署系统 参与部署自动化系统的开发,负责自动化部署系统所需要的基础数据和信息,负责权限管理、API开发、Web端开发。结合云计算,研发和提供PaaS相关高可用平台,进一步提高服务的部署速度和用户体验,提升资源利用率。 运维安全 运维安全负责网络、系统和业务等方面的安全加固工作,进行常规的安全扫描、渗透测试,进行安全工具和系统研发以及安全事件应急处理。详细的工作职责如下所述。 1.安全制度建立 根据公司内部的具体流程,制定切实可行,且行之有效的安全制度。 2.安全培训 定期向员工提供具有针对性的安全培训和考核,在全公司内建立安全负责人制度。 3.风险评估 通过黑白盒测试和检查机制,定期产生对物理网络、服务器、业务应用、用户数据等方面的总体风险评估结果。 4.安全建设 根据风险评估结果,加固最薄弱的环节,包括设计安全防线、部署安全设备、及时更新补丁、防御病毒、源代码自动扫描和业务产品安全咨询等。为了降低可能泄露数据的价值,通过加密、匿名化、混淆数据,乃至定期删除等技术手段和流程来达到目的。 5.安全合规 为了满足例如支付牌照等合规性要求,安全团队承担着安全合规的对外接口人工作。 6.应急响应 建立安全报警系统,通过安全中心收集第三方发现的安全问题,组织各部门对已经发现的安全问题进行修复、影响面评估、事后安全原因追查。 运维工作发展过程 早期的运维团队在人员较少的情况下,主要是进行数据中心建设、基础网络建设、服务器采购和服务器安装交付工作。几乎很少涉及线上服务的变更、监控、管理等工作。 这个时候的运维团队更多的属于基础建设的角色,提供一个简单、可用的网络环境和系统环境即可。 随着业务产品的逐渐成熟,对于服务质量方面就有了更高的要求。这个时候的运维团队还会承担一些服务器监控的工作,同时会负责 LVS、Nginx 等与业务逻辑无关的 4/7 层运维工作。 这个时候服务变更更多的是逐台的手工操作,或者有一些简单批量脚本的出现。监控的焦点更多的在服务器状态和资源使用情况上,对服务应用状态的监控几乎很少,监控更多的使用各种开源系统如Nagios、Cacti等。 由于业务规模和复杂度的持续增加,运维团队会逐渐划分为应用运维和系统运维两大块。应用运维开始接手线上业务,逐步开展服务监控梳理、数据备份以及服务变更的工作。 随着对服务的深入,应用运维工程师有能力开始对服务进行一些简单的优化。同时,为了应对每天大量的服务变更,我们也开始编写各类运维工具,针对某些特定的服务能够很方便的批量变更。 随着业务规模的增大,基础设施由于容量规划不足或抵御风险能力较弱导致的故障也越来越多,迫使运维人员开始将更多的精力投入到多数据中心容灾、预案管理的方向上。 业务规模达到一定程度后,开源的监控系统在性能和功能方面,已经无法满足业务需求;大量的服务变更、复杂的服务关系,以前靠人工记录、工具变更的方式不管在效率还是准确性方面也都无法满足业务需求。 在安全方面也出现了各种大大小小的事件,迫使我们投入更多的精力在安全防御上。逐渐的,运维团队形成之前提到的5个大的工作分类,每个分类都需要有专精的人才。 这个时候系统运维更专注于基础设施的建设和运维,提供稳定、高效的网络环境,交付服务器等资源给应用运维工程师。应用运维更专注于服务运行状态和效率。 数据库运维属于应用运维工作的细化,更专注于数据库领域的自动化、性能优化和安全防御。运维研发和运维安全提供各类平台、工具,进一步提升运维工程师的工作效率,使业务服务运行得更加稳定、高效和安全。 我们将运维发展过程划分为4个阶段,如图1-2所示。 图1-2运维发展过程 手工管理阶段:业务流量不大,服务器数量相对较少,系统复杂度不高。对于日常的业务管理操作,大家更多的是逐台登录服务器进行手工操作,属于各自为战,每个人都有自己的操作方式,缺少必要的操作标准、流程机制,比如业务目录环境都是各式各样的。 工具批量操作阶段:随着服务器规模、系统复杂度的增加,全人工的操作方式已经不能满足业务的快速发展需要。因此,运维人员逐渐开始使用批量化的操作工具,针对不同操作类型出现了不同的脚本程序。 但各团队都有自己的工具,每次操作需求发生变化时都需要调整工具。这主要是因为对于环境、操作的规范不够,导致可程序化处理能力较弱。此时,虽然效率提升了一部分,但很快又遇到了瓶颈。 操作的质量并没有太多的提升,甚至可能因为批量执行而导致更大规模的问题出现。我们开始建立大量的流程规范,比如复查机制,先上线一台服务器观察10分钟后再继续后面的操作,一次升级完成后至少要观察20分钟等。 这些主要还是靠人来监督和执行,但在实际过程中执行往往不到位,反而降低了工作效率。 平台管理阶段:在这个阶段,对于运维效率和误操作率有了更高的要求,我们决定开始建设运维平台,通过平台承载标准、流程,进而解放人力和提高质量。 这个时候对服务的变更动作进行了抽象,形成了操作方法、服务目录环境、服务运行方式等统一的标准,如程序的启停接口必须包括启动、停止、重载等。通过平台来约束操作流程,如上面提到的上线一台服务器观察10分钟。 在平台中强制设定暂停检查点,在第一台服务器操作完成后,需要运维人员填写相应的检查项,然后才可以继续执行后续的部署动作。 系统自调度阶段:更大规模的服务数量、更复杂的服务关联关系、各个运维平台的林立,原有的将批量操作转化成平台操作的方式已经不再适合,需要对服务变更进行更高一层的抽象。 将每一台服务器抽象成一个容器,由调度系统根据资源使用情况,将服务调度、部署到合适的服务器上,自动化完成与周边各个运维系统的联动,比如监控系统、日志系统、备份系统等。 通过自调度系统,根据服务运行情况动态伸缩容量,能够自动化处理常见的服务故障。运维人员的工作也会前置到产品设计阶段,协助研发人员改造服务使其可以接入到自调度系统中。 在整个运维的发展过程中,希望所有的工作都自动化起来,减少人的重复工作,降低知识传递的成本,使我们的运维交付更高效、更安全,使产品运行更稳定。对于故障的处理,也希望由事后处理变成提前发现,由人工处理变成系统自动容灾。]]></content>
<categories>
<category>运维</category>
</categories>
<tags>
<tag>运维</tag>
</tags>
</entry>
<entry>
<title><![CDATA[tomcat基础2]]></title>
<url>%2F2018-10-13-tomcat%E5%9F%BA%E7%A1%802.html</url>
<content type="text"><![CDATA[一、Tomcat的缺省是多少,怎么修改Tomcat的缺省端口号是8080. 修改Tomcat端口号: 1.找到Tomcat目录下的conf文件夹 2.进入conf文件夹里面找到server.xml文件 3.打开server.xml文件 4.在server.xml文件里面找到下列信息 maxThreads=”150″ minSpareThreads=”25″ maxSpareThreads=”75″ enableLookups=”false” redirectPort=”8443″ acceptCount=”100″ connectionTimeout=”20000″ disableUploadTimeout=”true” /> 5.把port=”8080″改成port=”8888″,并且保存 6.启动Tomcat,并且在IE浏览器里面的地址栏输入http://127.0.0.1:8888/ 7、tomcat默认采用的BIO模型,在几百并发下性能会有很严重的下降。tomcat自带还有NIO的模型,另外也可以调用APR的库来实现操作系统级别控制。 NIO模型是内置的,调用很方便,只需要将上面配置文件中protocol修改成 org.apache.coyote.http11.Http11NioProtocol,重启即可生效。如下面的参数配置,默认的是HTTP/1.1。 <Connector port=”8080″ protocol=”org.apache.coyote.http11.Http11NioProtocol” connectionTimeout=”20000″ redirectPort=”8443″ maxThreads=”500″ minSpareThreads=”20″ acceptCount=”100″ disableUploadTimeout=”true” enableLookups=”false” URIEncoding=”UTF-8″ /> 二、tomcat 如何优化?1、优化连接配置.这里以tomcat7的参数配置为例,需要修改conf/server.xml文件,修改连接数,关闭客户端dns查询。 参数解释: URIEncoding=”UTF-8″ :使得tomcat可以解析含有中文名的文件的url,真方便,不像apache里还有搞个mod_encoding,还要手工编译 maxSpareThreads : 如果空闲状态的线程数多于设置的数目,则将这些线程中止,减少这个池中的线程总数。 minSpareThreads : 最小备用线程数,tomcat启动时的初始化的线程数。 enableLookups : 这个功效和Apache中的HostnameLookups一样,设为关闭。 connectionTimeout : connectionTimeout为网络连接超时时间毫秒数。 maxThreads : maxThreads Tomcat使用线程来处理接收的每个请求。这个值表示Tomcat可创建的最大的线程数,即最大并发数。 acceptCount : acceptCount是当线程数达到maxThreads后,后续请求会被放入一个等待队列,这个acceptCount是这个队列的大小,如果这个队列也满了,就直接refuse connection maxProcessors与minProcessors : 在 Java中线程是程序运行时的路径,是在一个程序中与其它控制线程无关的、能够独立运行的代码段。它们共享相同的地址空间。多线程帮助程序员写出CPU最 大利用率的高效程序,使空闲时间保持最低,从而接受更多的请求。 通常Windows是1000个左右,Linux是2000个左右。 useURIValidationHack: 我们来看一下tomcat中的一段源码: 【security】 if (connector.getUseURIValidationHack()) { String uri = validate(request.getRequestURI()); if (uri == null) { res.setStatus(400); res.setMessage(“Invalid URI”); throw new IOException(“Invalid URI”); } else { req.requestURI().setString(uri); // Redoing the URI decoding req.decodedURI().duplicate(req.requestURI()); req.getURLDecoder().convert(req.decodedURI(), true); 可以看到如果把useURIValidationHack设成”false”,可以减少它对一些url的不必要的检查从而减省开销。 enableLookups=”false” : 为了消除DNS查询对性能的影响我们可以关闭DNS查询,方式是修改server.xml文件中的enableLookups参数值。 disableUploadTimeout :类似于Apache中的keeyalive一样 给Tomcat配置gzip压缩(HTTP压缩)功能 compression=”on” compressionMinSize=”2048″ compressableMimeType=”text/html,text/xml,text/javascript,text/css,text/plain” HTTP 压缩可以大大提高浏览网站的速度,它的原理是,在客户端请求网页后,从服务器端将网页文件压缩,再下载到客户端,由客户端的浏览器负责解压缩并浏览。相对于普通的浏览过程HTML,CSS,Javascript , Text ,它可以节省40%左右的流量。更为重要的是,它可以对动态生成的,包括CGI、PHP , JSP , ASP , Servlet,SHTML等输出的网页也能进行压缩,压缩效率惊人。 1)compression=”on” 打开压缩功能 2)compressionMinSize=”2048″ 启用压缩的输出内容大小,这里面默认为2KB 3)noCompressionUserAgents=”gozilla, traviata” 对于以下的浏览器,不启用压缩 4)compressableMimeType=”text/html,text/xml” 压缩类型 最后不要忘了把8443端口的地方也加上同样的配置,因为如果我们走https协议的话,我们将会用到8443端口这个段的配置,对吧 <!–enable tomcat ssl–> <Connector port=”8443″ protocol=”HTTP/1.1″ URIEncoding=”UTF-8″ minSpareThreads=”25″ maxSpareThreads=”75″ enableLookups=”false” disableUploadTimeout=”true” connectionTimeout=”20000″ acceptCount=”300″ maxThreads=”300″ maxProcessors=”1000″ minProcessors=”5″ useURIValidationHack=”false” compression=”on” compressionMinSize=”2048″ compressableMimeType=”text/html,text/xml,text/javascript,text/css,text/plain” SSLEnabled=”true” scheme=”https” secure=”true” clientAuth=”false” sslProtocol=”TLS” keystoreFile=”d:/tomcat2/conf/shnlap93.jks” keystorePass=”aaaaaa” /> 好了,所有的Tomcat优化的地方都加上了。 2、优化JDKTomcat默认可以使用的内存为128MB,Windows下,在文件{tomcat_home}/bin/catalina.bat,Unix下,在文件$CATALINA_HOME/bin/catalina.sh的前面,增加如下设置: JAVA_OPTS=”‘$JAVA_OPTS” -Xms[初始化内存大小] -Xmx[可以使用的最大内存] 或 设置环境变量:export JAVA_OPTS=””$JAVA_OPTS” -Xms[初始化内存大小] -Xmx[可以使用的最大内存]” 一般说来,你应该使用物理内存的 80% 作为堆大小。如果本机上有Apache服务器,可以先折算Apache需要的内存,然后修改堆大小。建议设置为70%;建议设置[[初始化内存大小]等于[可以使用的最大内存],这样可以减少平凡分配堆而降低性能。 本例使用加入环境变量的方式: # vi /etc/profile 加入:export JAVA_OPTS=””$JAVA_OPTS” -Xms700 —Xmx700 # source /etc/profile 【参数说明】 -Xms 是指设定程序启动时占用内存大小。一般来讲,大点,程序会启动的 快一点,但是也可能会导致机器暂时间变慢。 -Xmx 是指设定程序运行期间最大可占用的内存大小。如果程序运行需要占 用更多的内存,超出了这个设置值,就会抛出OutOfMemory 异常。 -Xss 是指设定每个线程的堆栈大小。这个就要依据你的程序,看一个线程 大约需要占用多少内存,可能会有多少线程同时运行等。 -XX:PermSize设置非堆内存初始值,默认是物理内存的1/64 。 -XX:MaxPermSize设置最大非堆内存的大小,默认是物理内存的1/4。 三、tomcat 有那几种Connector 运行模式?tomcat的运行模式有3种.修改他们的运行模式.3种模式的运行是否成功,可以看他的启动控制台,或者启动日志.或者登录他们的默认页面http://localhost:8080/查看其中的服务器状态。 1)bio 默认的模式,性能非常低下,没有经过任何优化处理和支持. 2)nio 利用java的异步io护理技术,no blocking IO技术. 想运行在该模式下,直接修改server.xml里的Connector节点,修改protocol为 <Connector port=”80″ protocol=”org.apache.coyote.http11.Http11NioProtocol” connectionTimeout=”20000″ URIEncoding=”UTF-8″ useBodyEncodingForURI=”true” enableLookups=”false” redirectPort=”8443″ /> 启动后,就可以生效。 3)apr 安装起来最困难,但是从操作系统级别来解决异步的IO问题,大幅度的提高性能. 必须要安装apr和native,直接启动就支持apr。下面的修改纯属多余,仅供大家扩充知识,但仍然需要安装apr和native 如nio修改模式,修改protocol为org.apache.coyote.http11.Http11AprProtocol]]></content>
<categories>
<category>运维</category>
</categories>
<tags>
<tag>tomcat</tag>
</tags>
</entry>
<entry>
<title><![CDATA[在浏览器中输入网址,按下回车之后——记2019校招面试]]></title>
<url>%2F2018-10-09-%E5%9C%A8%E6%B5%8F%E8%A7%88%E5%99%A8%E4%B8%AD%E8%BE%93%E5%85%A5%E7%BD%91%E5%9D%80%EF%BC%8C%E6%8C%89%E4%B8%8B%E5%9B%9E%E8%BD%A6%E4%B9%8B%E5%90%8E%E2%80%94%E2%80%94%E8%AE%B02019%E6%A0%A1%E6%8B%9B%E9%9D%A2%E8%AF%95.html</url>
<content type="text"><![CDATA[这个问题真的是烂大街了。。 在浏览器中输入网址,按下回车之后。。。。。 既然是烂大街了,那么你会么??? 今天咱们就来捋一捋,输入网址,按下回车的那一刹那,计算机到底去做了什么。 你知道当我们在浏览器中输入 URL 后到获得我们需要的网页资源,这中间需要经历怎样的流程吗?客户端(浏览器)是如何找到目标服务器并从服务器获得所需要的资源的? 如果你从未思考或了解过上述的问题,那么我相信本文会对你在日常的项目实践中有一定的帮助,在本文中我将尽可能详细地介绍浏览器中输入 URL 回车后与服务器进行通信的流程。 当我们在浏览器中输入 URL 并且回车后,主要发生四个过程:查找 IP 、建立连接、相互通信、断开连接。主要流程概述如下: 客户端根据域名查找对应的 IP 地址; 客户端根据 IP 地址与服务器建立连接; 客户端与服务器通信; 客户端与服务器断开连接。 在详细介绍各个流程前,让我们先来了解一下接下来需要接触到的一些名词概念。 IP 地址:指互联网协议地址。是 IP 协议提供的一种统一的地址格式,它为互联网上的每一个网络和每一台主机分配一个逻辑地址,以此来屏蔽物理地址的差异。互联网上每一个网络和每一台主机都会被分配的一个 IP 地址。我们可以把 IP 地址当成具体到门牌号码的地址,只有通过 IP 地址才能确定一台主机的位置。 域名:是由一串用点分隔的名字组成的 Internet上某一台计算机或计算机组的名称,用于在数据传输时标识计算机的电子方位(有时也指地理位置)。由于纯数字的 IP 地址难以被记忆,所以使用有代表意义的字符(域名)来代替纯数字的 IP 地址,但最终仍需要通过域名来查找其对应的 IP 地址才能够找到相应主机的位置。 DNS :域名系统,是互联网的一项服务。它作为将域名和 IP 地址相互映射的一个分布式数据库,能够使人更方便地访问互联网。 URL :统一资源定位符,有时也被俗称为网页地址(网址)。指的是因特网上各种资源的地址。 这里需要区分一下域名(或者 IP 地址)与 URL 的区别,域名确定的是因特网中某台主机的位置;而 URL 则要更为具体,指某台主机中某个资源的具体位置。如 ttsy.com 是一个域名,通过这个域名可以找到其相对应 IP 地址的主机,而 ttsy.com/a/b.jpg 是一个 URL,通过这个 URL 可以找到这台主机上的路径为 /a 的 b.jpg 图片资源。 那么接下来详细介绍上述四个流程~ 查找 IP在我们输入 URL 并且按下回车时,浏览器首先要做的便是通过域名查找对应的 IP 地址,这个过程也称作 DNS 解析。具体的查找过程如下: 浏览器搜索自己的 DNS 缓存,查找成功返回其对应 IP 地址,失败则进行下一步; 搜索系统中的 DNS 缓存,查找成功返回其对应 IP 地址,失败则进行下一步; 搜索系统中的 hosts 文件,查找成功返回其对应 IP 地址,失败则进行下一步; 系统发送一个请求到路由器上,路由器查找其缓存,查找成功返回其对应 IP 地址,失败则进行下一步; 系统将域名发送至 LDNS(本地域名服务器),查找成功返回其对应 IP 地址,失败则 LDNS 向 Root Name Server(根域名服务器)发起请求获得域的顶级域名服务器地址,然后依次请求获得各级域名服务器地址,最后获得域名对应 IP 地址; LDNS 将 IP 地址返回给操作系统并缓存起来; 系统将 IP 地址返回给浏览器并缓存起来; 浏览器获得 IP 地址,发起建立连接的请求。 建立连接–三次握手浏览器获得 IP 地址后,就会对目标服务器发起建立 TCP 连接的请求,建立连接主要有三个步骤,一般称为客户端与服务器端的三次握手: 浏览器向服务器发送想建立连接的请求「你好,可以认识一下吗」; 服务器向浏览器发送同意建立连接的响应「你好,当然可以啊」; 浏览器向服务器发送确认收到响应的请求,客户端和服务器建立连接「非常高兴认识你」。 相互通信客户端与服务器建立连接后,便会开始进行通信,这里以客户端向服务器请求网页资源的过程为例: 浏览器向服务器发起一个请求网页资源的请求; 服务器返回对应网页资源; 浏览器渲染、构建网页,在构建网页的过程中,可能会继续请求 CSS、JavaScript 等资源。 断开连接–四次挥手客户端与服务器的相互通信完成后,便会断开连接,断开连接主要有四个步骤,一般称为客户端与服务器端的四次挥手: 浏览器向服务器发送想断开连接的请求「我要走啦」; 服务器向浏览器发送收到请求的响应「我知道啦」; 服务器向浏览器发送断开连接的请求「可以了」; 浏览器断开连接并向服务器发送一个反馈请求,服务器收到后断开连接「好的,拜拜」。 为什么客户端与服务器断开连接是四次挥手呢?主要是因为当客户端告诉服务器想断开连接的时候,服务器的数据不一定已处理完毕,所以服务器是先告诉客户端说已经收到了它想断开连接的请求,然后当服务器中数据处理完毕时,便通知客户端并请求断开连接,客户端收到后便断开连接并通知服务器,服务器收到后才断开连接。 作者:淘淘笙悦 链接:https://juejin.im/post/59e2e928f265da430c10d996 来源:掘金 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。]]></content>
<categories>
<category>计算机网络</category>
</categories>
<tags>
<tag>TCP/IP</tag>
<tag>计算机网络</tag>
</tags>
</entry>
<entry>
<title><![CDATA[C语言中常用数学函数]]></title>
<url>%2F2018-10-09-C%E8%AF%AD%E8%A8%80%E4%B8%AD%E5%B8%B8%E7%94%A8%E6%95%B0%E5%AD%A6%E5%87%BD%E6%95%B0.html</url>
<content type="text"><![CDATA[C语言中常用Math函数。 第一步的操作是 #include <math.h> 1、fabs(double x) 对于double类型的x取绝对值。2、floor(double x) ceil(double x) 对于double的x向下取整和向上取整,返回值为double型。3、pow(double x,double p) 返回r的p次方。4、sqrt(double x) 返回x的算术平方根。5、log(double x) 返回x的以自然对数为底的对数。就是ln。如果想求log以a为底b的对数,需要用到换底公式。就是拆成除法。 比如loga\b=log(a)/log(b)。6、sin(double x)、cos(double x)、tan(double x) 这三个函数要求参数为弧度制。举个栗子:doubel db1 = sin(pi*45/180);所以要搞清楚弧度换算。7、asin(double x)、acos(double x)、atan(double x) 反三角函数。举个例子 double db2 = asin(1);8、round(double x) 将x四舍五入,返回值也是double型,需进行取整。举个例子:12double db3 = round(3.40); printf("%d",(int)db3);]]></content>
<categories>
<category>C/C++</category>
</categories>
</entry>
<entry>
<title><![CDATA[Tomcat基础1]]></title>
<url>%2F2018-09-24-Tomcat%E5%9F%BA%E7%A1%801.html</url>
<content type="text"><![CDATA[Web服务器根据对javaEE支持的能力分为两大类 1,JavaEE服务器(应用服务器) 1) IBM公司 WebSphere 2) BEA公司 WebLogic 3) JBoss 公司 JBoss 4) Apache组织 Geronimo(免费WebSphere社区版) 2,Web容器(servlet/jsp容器) 1) Apache组织 Tomcat 2) Webtide 公司 jetty Tomcat版本======== Tomcat JDK JavaEE Servlet JSP 9.x 8及更高的版本 JavaEE8 4.0 2.4? 8.x 7及更高的版本 JavaEE7 3.1 2.3 7.x 6及更高的版本 JavaEE6 3.0 2.2 6.x 5及更高的版本 JavaEE5 2.5 2.1 5.x 1.4及更高的版本 JavaEE1.4 2.4 2.0 4.x 1.3及更高的版本 JavaEE1.3 2.3 1.2 3.x 1.1及更高的版本 JavaEE1.3 2.2 1.1 Tomcat安装======== 下载,解压,然后配置环境变量,即可 启动方式1:bin目录下的startup.sh(linux下),startup.bat(Windows下) 方式2:bin目录下,命令行中输入 a.Linux: catalina.sh start/stop b.Windows: catalina.bat start/stop Tomcat目录结构1、bin目录这个目录只要是存放了一些bat文件或者sh文件。比如说我们需要启动tomcat的bat就在这个目录下 启动tomcat的方式: 1).点击 startup.bat可以启动tomcat 2).在黑窗口下运行 catalina.bat 后面需要跟命令:start启动 stop关闭 3).关闭容器 shutdonw.bat或者是直接关闭黑窗口。 2、conf这个目录中存放的都是一些配置文件 xml 3、lib这个目录中存放的是一些jar文件。 这里的jar文件重要有两大类: 1)tomcat自身的jar, 2)实现javaEE平台下部分标准的实现类(比如:jsp servlet…) 4、log存放的都是tomcat的日志文件。如果我们想了解黑窗口在启动时的打印信息,可以进到这个目录下找到cataline.log文件在这个文件中可以看到相关记录。 5、temp在这个目录中存放的是tomcat在运行时所产生的一些临时文件。这些文件是否存在并不影响tomcat的运行,所以这个目录下的内容可以被删除掉。但是:temp文件夹不能删。 6、webapps这个目录主要是存放需要让tomcat去管理的资源的目录。 7、work这个目录主要存放的是tomcat对jsp编译完后得原文件以及class文件。 8、doc存放Tomcat文档; Server.xml配置文件简介server: 1、port 指定一个端口,这个端口负责监听关闭tomcat的请求 2、shutdown 指定向端口发送的命令字符串 service: 1、name 指定service的名字 Connector (表示客户端和service之间的连接): 1、port 指定服务器端要创建的端口号,并在这个断口监听来自客户端的请求 2、minProcessors 服务器启动时创建的处理请求的线程数 3、maxProcessors 最大可以创建的处理请求的线程数 4、enableLookups 如果为true,则可以通过调用request.getRemoteHost()进行DNS查询来得到远程客户端的实际主机名,若为false则不进行DNS查询,而是返回其ip地址 5、redirectPort 指定服务器正在处理http请求时收到了一个SSL传输请求后重定向的端口号 6、acceptCount 指定当所有可以使用的处理请求的线程数都被使用时,可以放到处理队列中的请求数,超过这个数的请求将不予处理 7、connectionTimeout 指定超时的时间数(以毫秒为单位) Engine(表示指定service中的请求处理机,接收和处理来自Connector的请求): 1、defaultHost 指定缺省的处理请求的主机名,它至少与其中的一个host元素的name属性值是一样的 Context (表示一个web应用程序): 1、docBase 应用程序的路径或者是WAR文件存放的路径 2、path 表示此web应用程序的url的前缀,这样请求的url为http://localhost:8080/path/**** 3、reloadable 这个属性非常重要,如果为true,则tomcat会自动检测应用程序的/WEB-INF/lib 和/WEB-INF/classes目录的变化,自动装载新的应用程序,我们可以在不重起tomcat的情况下改变应用程序 host (表示一个虚拟主机): 1、name 指定主机名 2、appBase 应用程序基本目录,即存放应用程序的目录 3、unpackWARs 如果为true,则tomcat会自动将WAR文件解压,否则不解压,直接从WAR文件中运行应用程序 Logger (表示日志,调试和错误信息): 1、className 指定logger使用的类名,此类必须实现org.apache.catalina.Logger 接口 2、prefix 指定log文件的前缀 3、suffix 指定log文件的后缀 4、timestamp 如果为true,则log文件名中要加入时间,如下例:localhost_log.2001-10-04.txt Realm (表示存放用户名,密码及role的数据库): 1、className 指定Realm使用的类名,此类必须实现org.apache.catalina.Realm接口 Valve (功能与Logger差不多,其prefix和suffix属性解释和Logger 中的一样): 1、className 指定Valve使用的类名,如用org.apache.catalina.valves.AccessLogValve类可以记录应用程序的访问信息 directory(指定log文件存放的位置): 1、pattern 有两个值,common方式记录远程主机名或ip地址,用户名,日期,第一行请求的字符串,HTTP响应代码,发送的字节数。combined方式比common方式记录的值更多。 tomcat的部署项目的方式1、静态部署 tomcat部署项目三种方式:1.1 放到webapps目录下。直接将web项目文件件拷贝到webapps 目录中Tomcat的Webapps目录是Tomcat默认的应用目录,当服务器启动时,会加载所有这个目录下的应用。所以可以将web项目打包成一个 war包放在目录下,服务器会自动解开这个war包,并在这个目录下生成一个同名的文件夹。一个war包就是有特性格式的jar包,它是将一个web程序的所有内容进行压缩得到。具体如何打包,可以使用许多开发工具的IDE环境,如Eclipse等。也可以用 cmd 命令:jar -cvf mywar.war myweb webapps这个默认的应用目录也是可以改变。打开Tomcat的conf目录下的server.xml文件,找到下面内容: <Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true" xmlValidation="false" xmlNamespaceAware="false"> 1.2 修改server.xm 的host节点。将appBase修改即可。 添加 在server.xml中指定。在Tomcat的配置文件中,一个Web应用就是一个特定的Context,可以通过在server.xml中新建Context里部署一个web应用程序。打开server.xml文件,在Host标签内建一个Context,内容如下。 在tomcat中的conf目录中,在server.xml中的,节点中添加: <Context path="/hello" docBase="D:\ workspace\hello\WebRoot" debug="0" privileged="true"> </Context> 或者 <Context path="/myapp" reloadable="true" docBase="D:\myapp" workDir="D:\myapp\work"/> 或者 <Context path="/sms4" docBase="D:\workspace\sms4\WebRoot"/> 说明: path是虚拟路径; docBase 是应用程序的物理路径; workDir 是这个应用的工作目录,存放运行时生成的与这个应用相关的文件; debug 则是设定debug level, 0表示提供最少的信息,9表示提供最多的信息 privileged设置为true的时候,才允许Tomcat的Web应用使用容器内的Servlet reloadable 如果为true,则tomcat会自动检测应用程序的/WEB-INF/lib 和/WEB-INF/classes目录的变化,自动装载新的应用程序,可以在不重起tomcat的情况下改变应用程序,实现热部署 antiResourceLocking 和antiJARLocking 热部署是需要配置的参数,默认false避免更新了某个webapp,有时候Tomcat并不能把旧的webapp完全删除,通常会留下WEB-INF/lib下的某个jar包,必须关闭Tomcat才能删除,这就导致自动部署失败。设置为true,Tomcat在运行对应的webapp时,会把相应的源文件和jar文件复制到一个临时目录里。 1.3 在conf目录下找到或者是新建文件夹(Catalina—->localhost—–>访问资源的 xml—–><Context……/>) 在该目录中新建一个xml文件,名字不可以随意取,要和path后的那个名字一致,按照下边这个path的配置,xml的名字应该就应该是hello(hello.xml),该xml文件的内容为: <Context path="/hello" docBase="E:\workspace\hello\WebRoot" debug="0" privileged="true"> </Context> 2、动态部署也称之为热部署2.1 登陆tomcat管理控制台http://localhost:8080/ ,输入用户名和密码后便可管理应用并动态发布。 在Context Path(option):中输入/yourwebname ,这代表你的应用的访问地址。 XML Configration file URL中要指定一个xml文件,比如我们在F:\下建立一个hmcx.xml文件,内容如下: 其中docBase不用写了,因为在下一个文本框中填入。或者更简单点,这个文本框什么都不填,在WAR or Directory URL:中键入F:\hmcx即可,然后点击Deploy按钮,上面就可以看到了web应用程序,名字就Context Path(option):中的名字。 2.2 如果部署.war文件还有更加简单的方式,下面还有个Select WAR file uploae点击浏览选择.war文件,然后点击Deploy即可。]]></content>
<categories>
<category>运维</category>
</categories>
<tags>
<tag>tomcat</tag>
</tags>
</entry>
<entry>
<title><![CDATA[骚海一聚]]></title>
<url>%2F2018-07-25-%E9%AA%9A%E6%B5%B7%E4%B8%80%E8%81%9A.html</url>
<content type="text"><![CDATA[今日(2018年7月25日),下午骚海给我发来定位:上海站。 话说毕业三年了,这是第二次相聚。第一次是骚海婚后今年3月份在上海相聚。这次算是第二次了。今天聊了很多。最多的还是聊到了房子。 果然毕业了,谈的最多的还是房子车子孩子。福州的房价涨的是有些离谱,骚海还是在没有房子的情况下结了婚。而我还是单身狗。班级里的其他同学们都差不多不是单身了。上周华仔来松江面试,中午也一起吃了饭,谈的最多的是工作。华仔算是我劝说第一个转行的人,也希望他能在互联网行业找到自己的位置。 怎么说呢,骚海的工作,骚海的房子,到我这想的最多的也是这个吧。年龄到了,很多事情都跟着来了。我的爱情呢,我的婚姻呢,我的房子呢,我的车子呢。答案可能在于好好学习吧。 今天的骚海感觉还是很熟悉的。还是大学时候的样子。]]></content>
<categories>
<category>Linux</category>
</categories>
<tags>
<tag>Linux</tag>
</tags>
</entry>
<entry>
<title><![CDATA[Linux网络介绍]]></title>
<url>%2F2017-03-27-Linux%E7%BD%91%E7%BB%9C%E4%BB%8B%E7%BB%8D.html</url>
<content type="text"><![CDATA[Linux网络介绍 在介绍网络模式之前,关于网络的几个简单命令的使用 ifup eth0 //启动网卡eth0 ifdown eth0 //关闭网卡eth0 /etc/network/interfaces //网络配置文件 /etc/init.d/networking //网络服务位置 /etc/init.d/networking restart //重启网络 /etc/resolv.conf //DNS配置文件 ifconfig eth0 192.168.5.111 //重新配置网卡eth0的ip 一、三种模式的简单介绍 VMWare提供了三种工作模式,它们是bridged(桥接模式)、NAT(网络地址转换模式)和host-only(主机模式)。要想在网络管理和维护中合理应用它们,你就应该先了解一下这三种工作模式。 1、bridged(桥接模式) 在这种模式下,VMWare虚拟出来的操作系统就像是局域网中的一台独立的主机,它可以访问网内任何一台机器。在桥接模式下,你需要手工为虚拟 系统配置IP地址、子网掩码,而且还要和宿主机器处于同一网段,这样虚拟系统才能和宿主机器进行通信。同时,由于这个虚拟系统是局域网中的一个独立的主机 系统,那么就可以手工配置它的TCP/IP配置信息,以实现通过局域网的网关或路由器访问互联网。 使用桥接模式的虚拟系统和宿主机器的关系,就像连接在同一个Hub上的两台电脑。想让它们相互通讯,你就需要为虚拟系统配置IP地址和子网掩码,否则就无法通信。 如果你想利用VMWare在局域网内新建一个虚拟服务器,为局域网用户提供网络服务,就应该选择桥接模式。 2、host-only(主机模式) 在某些特殊的网络调试环境中,要求将真实环境和虚拟环境隔离开,这时你就可采用host-only模式。在host-only模式中,所有的虚拟系统是可以相互通信的,但虚拟系统和真实的网络是被隔离开的。 提示:在host-only模式下,虚拟系统和宿主机器系统是可以相互通信的,相当于这两台机器通过双绞线互连。 在host-only模式下,虚拟系统的TCP/IP配置信息(如IP地址、网关地址、DNS服务器等),都是由VMnet1(host-only)虚拟网络的DHCP服务器来动态分配的。 如果你想利用VMWare创建一个与网内其他机器相隔离的虚拟系统,进行某些特殊的网络调试工作,可以选择host-only模式。 3、NAT(网络地址转换模式) 在NAT网络中,会使用到VMnet8虚拟交换机,Host上的VMware Network Adapter VMnet8虚拟网卡被连接到VMnet8交换机上,来与Guest进行通信,但是VMware Network Adapter VMnet8虚拟网卡仅仅是用于和VMnet8网段通信用的,它并不为VMnet8网段提供路由功能,处于虚拟NAT网络下的Guest是使用虚拟的NAT服务器连接的Internet的。 这时候,你的Guest和Host就可以实现互访了,并且如果你的Host此时已经连接到了Internet,那么你的Guest也就可以连上Internet了。那么VMware Network Adapter VMnet8虚拟网卡在这里扮演了一个什么角色呢?它仅仅是为Host和NAT虚拟网络下的Guest通信提供一个接口,所以,即便Disable掉这块虚拟网卡,Guest仍然是可以上网的,只是Host无法再访问VMnet8网段而已。 这种方式的时候,主机需要开启vmdhcp和vmnat服务。 使用NAT模式,就是让虚拟系统借助NAT(网络地址转换)功能,通过宿主机器所在的网络来访问公网。也就是说,使用NAT模式可以实现在虚拟 系统里访问互联网。NAT模式下的虚拟系统的TCP/IP配置信息是由VMnet8(NAT)虚拟网络的DHCP服务器提供的,无法进行手工修改,因此虚 拟系统也就无法和本局域网中的其他真实主机进行通讯。采用NAT模式最大的优势是虚拟系统接入互联网非常简单,你不需要进行任何其他的配置,只需要宿主机 器能访问互联网即可。 如果你想利用VMWare安装一个新的虚拟系统,在虚拟系统中不用进行任何手工配置就能直接访问互联网,建议你采用NAT模式。 提示:以上所提到的NAT模式下的VMnet8虚拟网络,host-only模式下的VMnet1虚拟网络,以及bridged模式下的 VMnet0虚拟网络,都是由VMWare虚拟机自动配置而生成的,不需要用户自行设置。VMnet8和VMnet1提供DHCP服务,VMnet0虚拟 网络则不提供 二、三种模式的本质区别 网络模式 我们首先说一下VMware的几个虚拟设备 VMnet0:用于虚拟桥接网络下的虚拟交换机 VMnet1:用于虚拟Host-Only网络下的虚拟交换机 VMnet8:用于虚拟NAT网络下的虚拟交换机 VMware Network Adepter VMnet1:Host用于与Host-Only虚拟网络进行通信的虚拟网卡 VMware Network Adepter VMnet8:Host用于与NAT虚拟网络进行通信的虚拟网卡 安装了VMware虚拟机后,会在网络连接对话框中多出两个虚拟网卡。 1)桥接网络模式 桥接网络是指本地物理网卡和虚拟网卡通过VMnet0虚拟交换机进行桥接,物理网卡和虚拟网卡在拓扑图上处于同等地位(虚拟网卡既不是Adepter VMnet1也不是Adepter VMnet8)。 这里的VMnet0相当于一个交换机,最终通过这个虚拟交换机使其两端在一个网段中。 那么物理网卡和虚拟网卡就相当于处于同一个网段,虚拟交换机就相当于一台现实网络中的交换机。所以两个网卡的IP地址也要设置为同一网段。 如果使虚拟机使用桥接模式连接网络,在运行cmd命令后产看两个IP,可以发现IPv4的IP 和虚拟机处于一个网段。 物理网卡和虚拟网卡的IP地址处于同一个网段,子网掩码、网关、DNS等参数都相同。两个网卡在拓扑结构中是相对独立的。 桥接网络模式是VMware虚拟机中最简单直接的模式。安装虚拟机时它为默认选项。 在桥接模式下,虚拟机和宿主计算机处于同等地位,虚拟机就像是一台真实主机一样存在于局域网中。因此在桥接模式下,我们就要像对待其他真实计算机一样为其配置IP、网关、子网掩码等等。 当我们可以自由分配局域网IP时,使用桥接模式就可以虚拟出一台真实存在的主机。 2)NAT模式 在NAT网络中,会用到VMware Network Adepter VMnet8虚拟网卡,主机上的VMware Network Adepter VMnet8虚拟网卡被直接连接到VMnet8虚拟交换机上与虚拟网卡进行通信。 VMware Network Adepter VMnet8虚拟网卡的作用仅限于和VMnet8网段进行通信,它不给VMnet8网段提供路由功能,所以虚拟机虚拟一个NAT服务器,使虚拟网卡可以连接到Internet。在这种情况下,我们就可以使用端口映射功能,让访问主机80端口的请求映射到虚拟机的80端口上。 VMware Network Adepter VMnet8虚拟网卡的IP地址是在安装VMware时由系统指定生成的,我们不要修改这个数值,否则会使主机和虚拟机无法通信。 虚拟出来的网段和NAT模式虚拟网卡的网段是一样的,都为192.168.111.X,包括NAT服务器的IP地址也是这个网段。在安装VMware之后同样会生成一个虚拟DHCP服务器,为NAT服务器分配IP地址。 当主机和虚拟机进行通信的时候就会调用VMware Network Adepter VMnet8虚拟网卡,因为他们都在一个网段,所以通信就不成问题了。 实际上,VMware Network Adepter VMnet8虚拟网卡的作用就是为主机和虚拟机的通信提供一个接口,即使主机的物理网卡被关闭,虚拟机仍然可以连接到Internet,但是主机和虚拟机之间就不能互访了。 在NAT模式下,宿主计算机相当于一台开启了DHCP功能的路由器,而虚拟机则是内网中的一台真实主机,通过路由器(宿主计算机)DHCP动态获得网络参数。因此在NAT模式下,虚拟机可以访问外部网络,反之则不行,因为虚拟机属于内网。 使用NAT模式的方便之处在于,我们不需要做任何网络设置,只要宿主计算机可以连接到外部网络,虚拟机也可以。 NAT模式通常也是大学校园网Vmware最普遍采用的连接模式,因为我们一般只能拥有一个外部IP。很显然,在这种情况下,非常适合使用NAT模式。 3)host-only模式 在Host-Only模式下,虚拟网络是一个全封闭的网络,它唯一能够访问的就是主机。其实Host-Only网络和NAT网络很相似,不同的地方就是 Host-Only网络没有NAT服务,所以虚拟网络不能连接到Internet。主机和虚拟机之间的通信是通过VMware Network Adepter VMnet1虚拟网卡来实现的。 同NAT一样,VMware Network Adepter VMnet1虚拟网卡的IP地址也是VMware系统指定的,同时生成的虚拟DHCP服务器和虚拟网卡的IP地址位于同一网段,但和物理网卡的IP地址不在同一网段。 Host-Only的宗旨就是建立一个与外界隔绝的内部网络,来提高内网的安全性。这个功能或许对普通用户来说没有多大意义,但大型服务商会常常利用这个功能。如果你想为VMnet1网段提供路由功能,那就需要使用RRAS,而不能使用XP或2000的ICS,因为ICS会把内网的IP地址改为 192.168.0.1,但虚拟机是不会给VMnet1虚拟网卡分配这个地址的,那么主机和虚拟机之间就不能通信了。 在Host-only模式下,相当于虚拟机通过双绞线和宿主计算机直连,而宿主计算机不提供任何路由服务。因此在Host-only模式下,虚拟机可以和宿主计算机互相访问,但是虚拟机无法访问外部网络。 当我们要组成一个与物理网络相隔离的虚拟网络时,无疑非常适合使用Host-only模式。]]></content>
<categories>
<category>Linux</category>
</categories>
<tags>
<tag>Linux</tag>
</tags>
</entry>
<entry>
<title><![CDATA[Ubuntu上使用virtualenv]]></title>
<url>%2F2017-03-18-Ubuntu%E4%B8%8A%E4%BD%BF%E7%94%A8virtualenv.html</url>
<content type="text"><![CDATA[打开Windows10里面的Ubuntu 略。 在win10里的Ubuntu安装virtualenv 1234567891011121314151617sudo apt install python-pippip install virtualenvsudo apt install python-virtualenv#创建虚拟环境virtualenv -p /usr/bin/python3 文件夹名#下面这个是创建python2版本的环境virtualenv -p /usr/bin/python2 py2env#激活虚拟环境source 文件夹名 /bin/activate#退出虚拟环境deactivate#下次想进入虚拟环境开发之前,记得先激活虚拟环境即可。 在virtualenv中安装python包 使用pip install python包名,即可。这里不需要使用sudo。]]></content>
<categories>
<category>Python</category>
</categories>
<tags>
<tag>Python</tag>
</tags>
</entry>
<entry>
<title><![CDATA[CentOS安装Docker]]></title>
<url>%2F2017-01-10-CentOS%E5%AE%89%E8%A3%85Docker.html</url>
<content type="text"><![CDATA[CentOS安装DockerDocker 已经存在 EPEL 源中。这些指令支持 Redhat 和 CentOS。它可能会与其它的 EL6 二进制发行版本兼容良好,但是他们并没有被测试。 请记住这个包是 Extra Packages for Enterprise Linux (EPEL) 的一个额外包,社区中正在努力创建和维护这个包。 注意由于 Docker 的局限性,Docker 只能运行在64位的系统中。 你需要 CentOS6 或更高的版本,RHEL 的内核版本是 2.6.32-431 或者更高,为了让 Docker 工作需要特定的内核补丁。 安装首先,你需要安装 EPEL 镜像源,请查看 EPEL installation instructions. 在 EPEL 中已经提供了 docker-io 包 如果你安装了(不相关)的 Docker 包,它将与 docker-io 冲突。在安装 docker-io 之前,请先卸载 Docker 下一步,我们将要在我们的主机中安装 Docker,也就是 docker-io 包1$ sudo yum -y install docker-io 现在,它已经安装好了,让我们来启动 Docker 守护进程1$ sudo service docker start 如果我们需要开机自启动,如下:1$ sudo chkconfig docker on 现在我们确认 Docker 是否正常工作,首先我们需要获取最新的 CentOS 镜像1$ sudo docker pull centos:latest 下一步,我们要确保通过如下命令可以看到镜像:1$ sudo docker images centos 它将会输出如下的信息:123$ sudo docker images centosREPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZEcentos latest 0b443ba03958 2 hours ago 297.6 MB 运行简单的 bash shell 来测试这个镜像1$ sudo docker run -i -t centos /bin/bash 如果正常,你会获得一个简单的 bash 提示,输入 exit 退出。]]></content>
<categories>
<category>docker</category>
</categories>
<tags>
<tag>docker</tag>
</tags>
</entry>
<entry>
<title><![CDATA[Microsoft Windows 安装docker]]></title>
<url>%2F2017-01-10-Microsoft-Windows-%E5%AE%89%E8%A3%85docker.html</url>
<content type="text"><![CDATA[Microsoft Windows 安装docker我的感言 docker越做越好,用户的体验度和操作的便利性也是越来越好,这点可以看我以前写的docker教程,http://www.widuu.com/docker/,由于正式版出来之后,许多新的特性和安装方式都有所改变,我决定花时间重写docker中文文档。慢慢来,有时间久翻译一点。 windows 注意:docker已经在windows7.1和windows 8上通过测试,也支持运行老的版本,你的处理器必须支持硬件虚拟化。 docker引擎使用的是Linux内核的特性,所以在OSX上运行docker我们就待使用轻量级的虚拟机(VM),你使用windows上的Docker客户端来管理Docker容器和控制docker引擎的构建、运行、管理。 为了简化这个过程,我们设计了一个应用程序叫Boot2Docker安装虚拟机和运行docker进程。 安装1.下载最新版本的Docker for Windows Installer(由于S3可能被墙了,所以国内有时候下载不了,但是我把它放到国内七牛上了,大家可以下载试试http://qiniu.widuu.com/docker-install.exe”<版本1.11>) 2.运行安装文件,它将会安装virtualbox、MSYS-git boot2docker Linux镜像和Boot2Docker的管理工具。 3.从你的桌面上或者从你的应用程序文件夹中找到应用的快捷方式,运行Boot2Docker Start,启动脚本会让你输入一个ssh秘钥密码(简单点但最起码安全) Boot2Docker Start启动脚本将连接你到虚拟机的shell会话,如果需要的话,它会初始化一个新的VM并且启动它。 如果提示错误,找不到主机等信息,大家可以在安装目录执行123boot2docker.exe initboot2docker.exe startboot2docker.exe ssh 升级 下载最新的 Docker for OS X Installer 运行安装程序,这将升级VirtualBox和Boot2Docker管理工具 升级现有的虚拟机,打开终端并运行123$ boot2docker stop$ boot2docker download$ boot2docker start 运行Docker通过终端,你可以运行docker输出“hello word”的例子1$ docker run ubuntu echo hello world 这将下载Ubuntu镜像和打印hello word Docker测试 这个不是官方的,因为我们大家知道下载docker从国外是灰常慢的,而且不一定什么时候就被墙了,所以在这里我就提供几个测试的,让大家下载来使用。 12345678910wget qiniu.widuu.com/busybox.tardocker load -i busybox.tar//如果没有tag或者namedocker tag id name:tag//或者大家使用docker中文社区提供的,这里非常感谢docker中文社区docker pull index.dockboard.org/widuucom/busyboxdocker run index.dockboard.org/widuucom/busybox echo hello word 容器端口重定向最新版本的boot2docker可以设置网络适配器提供容器访问的端口 如果你运行容器给定一个指定的端口1$ docker run --rm -i -t -p 80:80 ngin 然后你应该能够使用IP地址访问Nginx服务器:1$ boot2docker ip 通常,是192.168.59.103,但是可以通过virtualbox的dhcp改变。 进一步的细节如果你有求知欲,boot2docker的默认用户名是docker密码是tcuser Boot2Docker管理工具提供了一些默认命令:123$ ./boot2dockerUsage: ./boot2docker [<options>]{help|init|up|ssh|save|down|poweroff|reset|restart|config|status|info|ip|delete|download|version} [<args>]]]></content>
<categories>
<category>docker</category>
</categories>
<tags>
<tag>docker</tag>
</tags>
</entry>
<entry>
<title><![CDATA[Docker-Nginx]]></title>
<url>%2F2016-03-28-Docker-Nginx.html</url>
<content type="text"><![CDATA[学习步骤如下: 1. 建立docker容器运行程序 2. 用上面建立的docker容器加上Nginx实现简单的负载均衡(与docker本身无关) 3. 建立基础仓库到阿里云 4. 梳理宿主机与容器间的两个Nginx关系 简单说下docker docker 是一种新兴的虚拟化方式,跟传统的虚拟化方式相比具有众多优势 更高效的利用系统资源,容器不需要进行硬件虚拟化已经运行完整的操作系统等额外开销,所以对系统资源的利用率比较高; 启动速度更快,原因和上面差不多; 一致的运行环境,一般称需要经过开发环境、测试环境、生产环境,但是无法确保所有的环境都是一致的, 所有就会出现同一段代码在不同环境输出的结果不一致,docker镜像提供了相同的运行环境(出内核外),可以避免上述问题的发生; 在程序交付的运维时,只需要提供Dockerfile文件即可实现快速部署 方便迁移,由于每个容器都是一个独立运行环境,和宿主机没有直接关系; docker包含三个概念: 1. 镜像(image) 2. 容器(container) 3. 仓库(repository) 这三个概念后面用到在说,方便理解 一、建立docker容器运行程序 这是我做的第一个比较简单,首先建立的一个简单的express项目,在项目的根目录建立了一个Dockerfile文件(注意第一个字母大写),后面调用run指令的时候docker会默认寻找这个文件,当然这个文件名也可以修改,但是需要得修改相应配置,在Dockerfile 中写入下面代码:1234567FROM node:slimENV HTTP_PORT 8000COPY . /appWORKDIR /appRUN npm install --registry=https://registry.npm.taobao.orgEXPOSE 8000CMD [ "npm", "start" ] FROM: 后面跟的是镜像来源,也就是基于那个镜像建立的镜像, 其中node是镜像名称,slim 是镜像版本号,这个node是官方给的基础版本,官网的基础镜像还有很多,点击这里查看更多, 当然还有其他人自定义的优质镜像这里就罗列了, ENV 指的是运行环境,一般程序都会分为development、production 等,我这里直接指定了端口号 COPY 复制,中间有个点 指的是当前目录,复制到/app目录,注意这里不是复制到真实的目录而已复制到容器的目录,所以在真实目录是看不到这个文件夹的 WORKDIR 指定工作目录 RUN npm 安装依赖包 并切换至淘宝源 EPOSE 容器输出端口 CMD 执行启动命令 在根项目根目录下(也是Dockerfile 所在目录)执行 下面代码建立自己的镜像 docker build -t myexpress . build 是建立镜像指令,-t 是添加镜像标签 注意后面有个空格和点,这里的点指的是当前目录,执行完上面命令之后再执行 docker images 就可以看到当前的拥有的镜像了,在你自定义myexpress的镜像之外 还多出了node的镜像,这是因为我们的镜像是建立在node镜像基础之上的,下次在建立依赖node镜像时,就不需要再次下载node镜像了,因为重复利用了,节省的资源 建立完镜像后 ,我们就开始生成容器了,镜像和容器的关系就像是 类和实例的关系,一个镜像可以生成多个容器,执行下方指令生成容器: docker run –name mycontainername -d -p 80:8000 myexpress name 是给当前容器命名 d 是后端运行 p 80是容器端口 8000是映射到主机的端口 myexpress 是前面建立的进行名称 项目已经运行起来,直接访问宿主机ip 即可看到项目主页 二、用上面建立的docker容器加上Nginx实现简单的负载均衡 这个部分的出现纯属意外和docker没有直接关系,我只是刚好看到这里就记录下来 在Nginx的配置文件 http下添加 upstream 代码如下:1234upstream zmb { server 127.0.0.1:8080; server 127.0.0.1:8081;} zmb随便取的只是个代号,后面可以添加weight属性标识权重 然后在server 下location去添加配置 如下:123location / {proxy_pass http://zmb;} 注意这里的两个zmb 必须保持一致 这样在每次请求sever端口是都会循环访问8080和8081端口,若有一个失败则直接访问下一个 三、建立基础仓库到阿里云 这里前提是必须要有一个阿里云账号,将代码托管到阿里云自己仓库 https://code.aliyun.com, 我们建立一个 空项目 项目里面只有一个Dockerfile 文件并把这个项目同步到自己的仓库,Dockerfile的配置如下:12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758#version 1.0#Base imageFROM centos#MAINTAINERMAINTAINER zybWORKDIR /usr/local/src#download softRUN yum install -y gcc make gcc-c++ openssl-devel wget zlib* perl perl-devel#pcreWORKDIR /usr/local/srcRUN wget https://ncu.dl.sourceforge.net/project/pcre/pcre/8.41/pcre-8.41.tar.gzRUN tar -zxf pcre-8.41.tar.gzWORKDIR pcre-8.41RUN ./configureRUN make && make install#zib-1.2.11WORKDIR /usr/local/srcRUN wget http://www.zlib.net/zlib-1.2.11.tar.gzRUN tar -zxf zlib-1.2.11.tar.gzWORKDIR zlib-1.2.11RUN ./configureRUN make && make install#OpensslWORKDIR /usr/local/srcRUN wget https://www.openssl.org/source/openssl-1.0.2l.tar.gzRUN tar -zxf openssl-1.0.2l.tar.gzWORKDIR openssl-1.0.2lRUN ./config -fPIC --prefix=/usr/local/openssl/ enable-sharedRUN make dependRUN make && make install#nginxWORKDIR /usr/local/srcRUN wget http://nginx.org/download/nginx-1.13.6.tar.gzRUN tar -zxf nginx-1.13.6.tar.gzWORKDIR nginx-1.13.6RUN ./configure --sbin-path=/usr/local/nginx/nginx \--conf-path=/usr/local/nginx/nginx.conf \--pid-path=/usr/local/nginx/nginx.pid \--with-http_ssl_module \--with-pcre=/usr/local/src/pcre-8.41 \--with-zlib=/usr/local/src/zlib-1.2.11 \--with-openssl=/usr/local/src/openssl-1.0.2l \--with-streamRUN make && make install#nodejsWORKDIR /usr/local/srcRUN wget https://nodejs.org/dist/v8.8.1/node-v8.8.1.tar.gzRUN tar -zxf node-v8.8.1.tar.gzWORKDIR node-v8.8.1RUN ./configureRUN make installRUN npm config set registry https://registry.npm.taobao.orgRUN rm -rf /usr/local/src/* 主要是在centos镜像基础上添加了Nginx和node 同步上去之后再 去阿里云上点击 容器镜像服务 功能, 添加镜像仓库,代码源设置为阿里云code,选取命名空间,选择刚才同步的代码仓库等,构建设置 勾选 在代码更新时自动构建, 添加完成之后,列表也点击设置–> 构建–> 立即构建,第一次构建需要编译时间比较长,到此一个基础的centos+Nginx+node的镜像已经构建完成了,列表页有个仓库地址 后面引用项目就FROM该地址即可。 四、梳理宿主机与容器间的两个Nginx关系 上面示例中容器中有个Nginx,一般容器外也会有个Nginx,那么他们两个之间有什么关系或者说怎么个运行步骤呢? 在一个宿主机中一般会有多个容器,容器外的Nginx根据端口号分发给各个容器的,容器Dockerfile文件中espose 可以设置暴露多个端口号,容器在构建时一般会映射端口号(-p 容器端口号和主机端口号),这里容器的端口号应该是上面expose 中的一个,主机端口号应该和内部Nginx接受端口相对应,内部的Nginx再讲端口映射到我们项目程序的端口,这样看来内部的Nginx好像没有多大作用(容器可以直接访问主程序的),我是这样认为的,因为在这个示例中外部是有配置Nginx的,如果外部要是什么都没有配置,也可以直接构建项目,因为我们镜像内部包含有Nginx做映射; 也就是说流程应该是这样的 client 访问宿主机 经过外部的Nginx的映射,到相应的容器(若espose没有匹配到则无法访问),容器接受到请求根据端口号经过内部Nginx的映射到我们的主程序中。]]></content>
<categories>
<category>运维</category>
</categories>
<tags>
<tag>docker</tag>
</tags>
</entry>
<entry>
<title><![CDATA[docker入门实战笔记]]></title>
<url>%2F2016-03-13-docker%E5%85%A5%E9%97%A8%E5%AE%9E%E6%88%98%E7%AC%94%E8%AE%B0.html</url>
<content type="text"><![CDATA[什么是docker?========== docker翻译为搬运工,在这里应该可以理解为搬运应用的工具,也就是云.先了解其运用场景之后更容易对他形成深刻理解. Docker提供了一种可移植的配置标准化机制,允许你一致性地在不同的机器上运行同一个Container;而LXC本身可能因为不同机器的不同配置而无法方便地移植运行; Docker以App为中心,为应用的部署做了很多优化,而LXC的帮助脚本主要是聚焦于如何机器启动地更快和耗更少的内存; Docker为App提供了一种自动化构建机制(Dockerfile),包括打包,基础设施依赖管理和安装等等; Docker提供了一种类似git的Container版本化的机制,允许你对你创建过的容器进行版本管理,依靠这种机制,你还可以下载别人创建的Container,甚至像git那样进行合并; Docker Container是可重用的,依赖于版本化机制,你很容易重用别人的Container(叫Image),作为基础版本进行扩展; Docker Container是可共享的,有点类似github一样,Docker有自己的INDEX,你可以创建自己的Docker用户并上传和下载Docker Image; Docker提供了很多的工具链,形成了一个生态系统;这些工具的目标是自动化、个性化和集成化,包括对PAAS平台的支持等; docker运用场景: web应用的自动化打包和发布; 自动化测试和持续集成、发布; 在服务型环境中部署和调整数据库或其他的后台应用; 从头编译或者扩展现有的OpenShift或Cloud Foundry平台来搭建自己的PaaS环境。 可以看出来docker其实就是使得部署,发布变得更加快捷,更加自动化,且适应云平台环境.再看定义: Docker是一个开源的引擎,可以轻松的为任何应用创建一个轻量级的、可移植的、自给自足的容器。开发者在笔记本上编译测试通过的容器可以批量地在生产环境中部署,包括VMs(虚拟机)、bare metal、 OpenStack 集群和其他的基础应用平台。 意思很明显了.按照我的理解,先不考虑docker的实现方式,其实docker就是一个包含运行环境的应用,由于自身带有所有需要的运行环境促成了他的可移植性和快速部署. docker应用环境的集成是通过一层一层的镜像叠加实现的,这种方式可以使得底层镜像多次复用,结构清晰.这里不赘述docker的具体实现原理,实战过后想来都会有一些理解. docker安装======== 不同的linux系统安装docker会有些许不同,新版的redhat和centos7自带有docker包,直接安装即可.具体参考:docker安装 ubuntu14.04 docker:1$ sudo apt-get update 安装所有必须和可选的包1$ sudo apt-get install linux-image-generic-lts-trusty 重启系统1$ sudo reboot 查看你是否安装了wget1$ which wget 如果wget没有安装,先升级包管理器,然后再安装它。1$ sudo apt-get update $ sudo apt-get install wget 获取最新版本的 Docker 安装包1$ wget -qO- https://get.docker.com/ | sh 系统会提示你输入sudo密码,输入完成之后,就会下载脚本并且安装Docker及依赖包。 验证 Docker 是否被正确的安装1$ sudo docker run hello-world 上边的命令会下载一个测试镜像,并在容器内运行这个镜像。 正常情况下以下内容可以不看 Ubuntu Docker可选配置 这部分主要介绍了 Docker 的可选配置项,使用这些配置能够让 Docker 在 Ubuntu 上更好的工作。 创建 Docker 用户组 调整内存和交换空间(swap accounting) 启用防火墙的端口转发(UFW) 为 Docker 配置DNS服务 创建 Docker 用户组 docker 进程通过监听一个 Unix Socket 来替代 TCP 端口。在默认情况下,docker 的 Unix Socket属于root用户,当然其他用户可以使用sudo方式来访问。因为这个原因, docker 进程就一直是root用户运行的。 为了在使用 docker 命令的时候前边不再加sudo,我们需要创建一个叫 docker 的用户组,并且为用户组添加用户。然后在 docker 进程启动的时候,我们的 docker 群组有了 Unix Socket 的所有权,可以对 Socket 文件进行读写。 注意:docker 群组就相当于root用户。有关系统安全影响的细节,请查看 Docker 进程表面攻击细节 创建 docker 用户组并添加用户 使用具有sudo权限的用户来登录你的Ubuntu。 在这过程中,我们假设你已经登录了Ubuntu。 创建 docker 用户组并添加用户。1$ sudo usermod -aG docker ubuntu 注销登录并重新登录 这里要确保你运行用户的权限。 验证 docker 用户不使用 sudo 命令开执行 Docker1$ docker run hello-world 调整内存和交换空间(swap accounting) 当我们使用 Docker 运行一个镜像的时候,我们可能会看到如下的信息提示:12WARNING: Your kernel does not support cgroup swap limit. WARNING: Yourkernel does not support swap limit capabilities. Limitation discarded. 为了防止以上错误信息提示的出现,我们需要在系统中启用内存和交换空间。我们需要修改系统的 GUN GRUB (GNU GRand Unified Bootloader) 来启用内存和交换空间。开启方法如下: 使用具有sudo权限的用户来登录你的Ubuntu。 编辑 /etc/default/grub 文件 设置 GRUB_CMDLINE_LINUX 的值如下:1GRUB\_CMDLINE\_LINUX="cgroup_enable=memory swapaccount=1" 保存和关闭文件 更新 GRUB1$ sudo update-grub 重启你的系统。 允许UFW端口转发 当你在运行 docker 的宿主主机上使用UFW(简单的防火墙)。你需要做一些额外的配置。Docker 使用桥接的方式来管理网络。默认情况下,UFW 过滤所有的端口转发策略。因此,当在UFW启用的情况下使用 docker ,你必须适当的设置UFW的端口转发策略。 默认情况下UFW是过滤掉所有的入站规则。如果其他的主机能够访问你的容器。你需要允许Docker的默认端口(2375)的所有连接。 设置 UFW 允许Docker 端口的入站规则: 使用具有sudo权限的用户来登录你的Ubuntu。 验证UFW的安装和启用状态1$ sudo ufw status 打开和编辑/etc/default/ufw文件1$ sudo nano /etc/default/ufw 设置 DEFAULT_FORWARD_POLICY 如下:1DEFAULT\_FORWARD\_POLICY="ACCEPT" 保存关闭文件。 重新加载UFW来使新规则生效。1$ sudo ufw reload 允许 Docker 端口的入站规则1$ sudo ufw allow 2375/tcp Docker 配置 DNS 服务================ 无论是Ubuntu还是Ubuntu 桌面繁衍版在系统运行的时候都是使用/etc/resolv.conf配置文件中的127.0.0.1作为域名服务器(nameserver)。NetworkManager设置dnsmasq使用真实的dns服务器连接,并且设置 /etc/resolv.conf的域名服务为127.0.0.1。 在桌面环境下使用这些配置来运行 docker 容器的时候, Docker 用户会看到如下的警告:12WARNING: Local (127.0.0.1) DNS resolver found in resolv.conf and containerscan't use it. Using default external servers : \[8.8.8.8 8.8.4.4\] 该警告是因为 Docker 容器不能使用本地的DNS服务。相反 Docker 使用一个默认的外部域名服务器。 为了避免此警告,你可以给 Docker 容器指定一个DNS服务器。或者你可以禁用 NetworkManager 的 dnsmasq。不过当禁止 dnsmasq 可能使某些网络的DNS解析速度变慢。 为 Docker 指定一个DNS服务器 使用具有sudo权限的用户来登录你的Ubuntu。 打开并编辑 /etc/default/docker1$ sudo nano /etc/default/docker 添加设置1DOCKER_OPTS="--dns 8.8.8.8" 使用8.8.8.8替换如192.168.1.1的本地DNS服务器。你可以指定多个DNS服务器,多个DNS服务器使用空格分割例如1--dns 8.8.8.8 --dns 192.168.1.1 警告:如果你正在使用的电脑需要连接到不同的网络,一定要选择一个公共DNS服务器。 保存关闭文件。 重启 Docker 进程1$ sudo restart docker 或者,作为替代先前的操作过程,禁止NetworkManager中的dnsmasq(这样会使你的网络变慢) 打开和编辑 /etc/default/docker1$ sudo nano /etc/NetworkManager/NetworkManager.conf 注释掉 dns = dsnmasq: 保存关闭文件 重启NetworkManager 和 Docker1$ sudo restart network-manager $ sudo restart docker 升级Docker======== 在wget的时候使用-N参数来安装最新版本的Docker:1$ wget -N https://get.docker.com/ | sh 正常情况下以上内容可以不看 安装镜像方法一 下载镜像首先,访问 Docker 中文网,在首页中搜索名为“centos”的镜像,在搜索的结果中,有一个“官方镜像”,它就是我们所需的。 然后,进入 CentOS 官方镜像页面,在“Pull this repository”输入框中,有一段命令,把它复制下来,在自己的命令行上运行该命令,随后将立即下载该镜像。 查看本地所有的镜像:1docker images 当下载完成后,您应该会看到:12REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZEdocker.cn/docker/centos centos6 25c5298b1a36 7 weeks ago 215.8 MB 如果看到以上输出,说明您可以使用“docker.cn/docker/centos”这个镜像了,或将其称为仓库(Repository),该镜像有一个名为“centos6”的标签(Tag),此外还有一个名为“25c5298b1a36 ”的镜像 ID(可能您所看到的镜像 ID 与此处的不一致,那是正常现象,因为这个数字是随机生成的)。此外,我们可以看到该镜像只有 215.8 MB,非常小巧,而不像虚拟机的镜像文件那样庞大。 现在镜像已经有了,我们下面就需要使用该镜像,来启动容器。 启动容器只需使用以下命令即可启动容器:1docker run -i -t -v /root/software/:/mnt/software/ 25c5298b1a36 /bin/bash 这条命令比较长,我们稍微分解一下,其实包含以下三个部分: docker run <相关参数> <镜像 ID> <初始命令> 其中,相关参数包括: -i:表示以“交互模式”运行容器 -t:表示容器启动后会进入其命令行 -v:表示需要将本地哪个目录挂载到容器中,格式:-v <宿主机目录>:<容器目录> 假设我们的所有安装程序都放在了宿主机的/root/software/目录下,现在需要将其挂载到容器的/mnt/software/目录下。 需要说明的是,不一定要使用“镜像 ID”,也可以使用“仓库名:标签名”,例如:docker.cn/docker/centos:centos6。 初始命令表示一旦容器启动,需要运行的命令,此时使用“/bin/bash”,表示什么也不做,只需进入命令行即可。 安装相关软件为了搭建 Java Web 运行环境,我们需要安装 JDK 与 Tomcat,下面的过程均在容器内部进行。我们不妨选择/opt/目录作为安装目录,首先需要通过cd /opt/命令进入该目录 安装 JDK首先,解压 JDK 程序包:1tar -zxf /mnt/software/jdk-7u67-linux-x64.tar.gz -C . 然后,重命名 JDK 目录:1mv jdk1.7.0_67/ jdk/ 安装 Tomcat首先,解压 Tomcat 程序包:1tar -zxf /mnt/software/apache-tomcat-7.0.55.tar.gz -C . 然后,重命名 Tomcat 目录:1mv apache-tomcat-7.0.55/ tomcat/ 设置环境变量首先,编辑.bashrc文件1vi ~/.bashrc 然后,在该文件末尾添加如下配置:12export JAVA_HOME=/opt/jdkexport PATH=$PATH:$JAVA_HOME 最后,需要使用source命令,让环境变量生效:1source ~/.bashrc 编写运行脚本我们需要编写一个运行脚本,当启动容器时,运行该脚本,启动 Tomcat,具体过程如下: 首先,创建运行脚本:1vi /root/run.sh 然后,编辑脚本内容如下:123#!/bin/bashsource ~/.bashrcsh /opt/tomcat/bin/catalina.sh run 注意:这里必须先加载环境变量,然后使用 Tomcat 的运行脚本来启动 Tomcat 服务。 最后,为运行脚本添加执行权限:1chmod u+x /root/run.sh 退出容器 当以上步骤全部完成后,可使用exit命令,退出容器。 随后,可使用如下命令查看正在运行的容器:1docker ps 此时,您应该看不到任何正在运行的程序,因为刚才已经使用exit命令退出的容器,此时容器处于停止状态,可使用如下命令查看所有容器:1docker ps -a 输出如下内容:12CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES57c312bbaad1 docker.cn/docker/centos:centos6 "/bin/bash" 27 minutes ago Exited (0) 19 seconds ago naughty_goldstine 记住以上CONTAINER ID(容器 ID),随后我们将通过该容器,创建一个可运行 Java Web 的镜像。 创建 Java Web 镜像 使用以下命令,根据某个“容器 ID”来创建一个新的“镜像”:1docker commit 57c312bbaad1 javaweb:0.1 该容器的 ID 是“57c312bbaad1”,所创建的镜像名是“javaweb:0.1”,随后可使用镜像来启动 Java Web 容器。 启动 Java Web 容器 有必要首先使用docker images命令,查看当前所有的镜像:123REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZEjavaweb 0.1 fc826a4706af 38 seconds ago 562.8 MBdocker.cn/docker/centos centos6 25c5298b1a36 7 weeks ago 215.8 MB 可见,此时已经看到了最新创建的镜像“javaweb:0.1”,其镜像 ID 是“fc826a4706af”。正如上面所描述的那样,我们可以通过“镜像名”或“镜像 ID”来启动容器,与上次启动容器不同的是,我们现在不再进入容器的命令行,而是直接启动容器内部的 Tomcat 服务。此时,需要使用以下命令:1docker run -d -p 58080:8080 --name javaweb javaweb:0.1 /root/run.sh 稍作解释: -d:表示以“守护模式”执行/root/run.sh脚本,此时 Tomcat 控制台不会出现在输出终端上。 -p:表示宿主机与容器的端口映射,此时将容器内部的 8080 端口映射为宿主机的 58080 端口,这样就向外界暴露了 58080 端口,可通过 Docker 网桥来访问容器内部的 8080 端口了。 –name:表示容器名称,用一个有意义的名称命名即可。 关于 Docker 网桥的内容,需要补充说明一下。实际上 Docker 在宿主机与容器之间,搭建了一座网络通信的桥梁,我们可通过宿主机 IP 地址与端口号来映射容器内部的 IP 地址与端口号, 当运行以上命令后,会立即输出一长串“容器 ID”,我们可通过docker ps命令来查看当前正在运行的容器。12CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES82f47923f926 javaweb:0.1 "/root/run.sh" 4 seconds ago Up 3 seconds 0.0.0.0:58080->8080/tcp javaweb 在浏览器中,输入以下地址,即可访问 Tomcat 首页: http://192.168.65.132:58080/ 注意:这里使用的是宿主机的 IP 地址,与对外暴露的端口号 58080,它映射容器内部的端口号 8080。 由于我测试的虚拟机采用nat映射连接,如果采用这种方法测试则需要重新将58080端口映射到宿主主机才能够访问 安装镜像方法二 导入镜像centos7: docker load -i centos7 导入本地仓库 编写安装jdk的Dockerfile dockerfile语法 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677Dockerfile关键字\# CommentINSTRUCTION argumentsFROM基于哪个镜像RUN安装软件用MAINTAINER镜像创建者CMDcontainer启动时执行的命令,但是一个Dockerfile中只能有一条CMD命令,多条则只执行最后一条CMD.CMD主要用于container时启动指定的服务,当docker run command的命令匹配到CMD command时,会替换CMD执行的命令。如:Dockerfile:CMD echo hello world运行一下试试:edwardsbean@ed-pc:~/software/docker-image/centos-add-test$ docker run centos-cmdhello world一旦命令匹配:edwardsbean@ed-pc:~/software/docker-image/centos-add-test$ docker run centos-cmd echo hello edwardsbeanhello edwardsbeanENTRYPOINTcontainer启动时执行的命令,但是一个Dockerfile中只能有一条ENTRYPOINT命令,如果多条,则只执行最后一条ENTRYPOINT没有CMD的可替换特性USER使用哪个用户跑container如:ENTRYPOINT \["memcached"\]USER daemonEXPOSEcontainer内部服务开启的端口。主机上要用还得在启动container时,做host-container的端口映射:docker run -d -p 127.0.0.1:33301:22 centos6-sshcontainer ssh服务的22端口被映射到主机的33301端口ENV用来设置环境变量,比如:ENV LANG en\_US.UTF-8 ENV LC\_ALL en_US.UTF-8ADD将文件<src>拷贝到container的文件系统对应的路径<dest>所有拷贝到container中的文件和文件夹权限为0755,uid和gid为0如果文件是可识别的压缩格式,则docker会帮忙解压缩如果要ADD本地文件,则本地文件必须在 docker build <PATH>,指定的<PATH>目录下如果要ADD远程文件,则远程文件必须在 docker build <PATH>,指定的<PATH>目录下。比如:docker build github.com/creack/docker-firefoxdocker-firefox目录下必须有Dockerfile和要ADD的文件注意:使用docker build - < somefile方式进行build,是不能直接将本地文件ADD到container中。只能ADD url file.ADD只有在build镜像的时候运行一次,后面运行container的时候不会再重新加载了。VOLUME可以将本地文件夹或者其他container的文件夹挂载到container中。WORKDIR切换目录用,可以多次切换(相当于cd命令),对RUN,CMD,ENTRYPOINT生效ONBUILDONBUILD 指定的命令在构建镜像时并不执行,而是在它的子镜像中执行 dockerfile语法============ 脚本11234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253\# Version: 1.0.0\# Create Time: 2015-10-16 09:04\# Author: baibai\# Description: 在最新版本的ubuntu系统中安装jdk,构建可执行java的环境FROM index.tenxcloud.com/tenxcloud/ubuntu:latest MAINTAINER Li Siqi "[email protected]"\# 将jdk安装压缩包解压到/home/jdk1.8.0_51ADD jdk-8u51-linux-x64.tar.gz /home/\# 安装中文语言包#RUN locale-gen zh_CN.UTF-8\# 设置java环境变量ENV JAVA\_HOME /home/jdk1.8.0\_51ENV CLASSPATH .:$JAVA\_HOME/lib/dt.jar:$JAVA\_HOME/lib/tools.jarENV PATH $PATH:$JAVA_HOME/bin\# 设置语言环境变量ENV LANG zh_CN.UTF-8ENV LANGUAGE zh_CN:zh###########脚本###########################运行命令docker build -t 自定义名称 路径生成一个镜像docker images 查看当前所有镜像接下来用同样的方式运行tomcat###########脚本###########################\# Version: 1.0.0\# Create Time: 2015-12-25 11:04\# Author: Lin Nan\# 基于已经配置好的jdk1.8版本进行操作FROM jdk:latestMAINTAINER Li Nan <[email protected]>\# 创建目录#RUN mkdir -p -m 777 /home\# 将context中的压缩包迁移到容器中并解压ADD tomcat8.tar.gz /home/tomcat8/\# 暴露文件目录#VOLUME \["/home/docker/file/distfirstout", "/home/docker/file/input/D001"\]#VOLUME \["/app/tomcat8/webapps/"\]\# 暴露网络端口EXPOSE 8881\# 启动服务ENTRYPOINT \["/home/tomcat8/apache-tomcat-8.0.24/bin/catalina.sh", "run"\] 脚本2 1234执行命令 docker build --no-cache=true -t tomcat8 路径docker run -d -p 8881:8080 --name=tomcat8 tomcat8 安装镜像方法二结束 完 常用命令 123456789101112docker images 查看镜像docker ps 查看容器docker ps -a 查看所有容器,包括没有运行的docker rm 删除容器docker rmi 删除镜像docker build 新建镜像docker run 运行容器docker stop 停止容器docker logs 查看日志docker load 导入镜像docker save 导出镜像docker commit 容器生成镜像 用一行命令大扫除:123docker kill $(docker ps -q) ; docker rm $(docker ps -a -q) ; docker rmi $(docker images -q -a)]]></content>
<categories>
<category>运维</category>
</categories>
<tags>
<tag>docker</tag>
</tags>
</entry>
<entry>
<title><![CDATA[Nginx负载均衡]]></title>
<url>%2F2016-03-02-Nginx%E8%B4%9F%E8%BD%BD%E5%9D%87%E8%A1%A1.html</url>
<content type="text"><![CDATA[正向代理==== 场景:在国内是无法正常使用google.com。如果想要访问google.com,可以购买一台国外的服务器A,此时你和服务器A的网络是相通的。而服务器A又跟google.com相通, 此时可以由服务器A代理你(客户端),去访问google.com。这个过程称之为正向代理,服务端(google.com)只需要知道代理服务器的ip,不需要知道客户端的ip。 结论:正向代理,是用于代理客户端的。 反向代理==== 场景:当一个服务器接受过多来自客户端的请求时,服务器难以处理和响应这些请求,会使得整个系统性能下降。为了解决这个难题,可以提供多台部署相同应用的服务器,让客户端的请求分别发送到不同的服务器上,这样单机服务器的压力就会降低很多,整体性能便会提升。但是有一个问题,每个服务器ip都是不同的,也就是说客户端的请求要发送到多个不同的ip上。让客户手动指定ip进行请求,这种方式很不明智。首先是客户的随机性,不知道会访问哪台服务器,其次,会造成一部分服务器压力大,一部分服务器几乎没有使用,浪费资源。因此,这里就需要一个角色去代理服务器,让客户端的请求直接发送到这个角色上,由这个角色去分发请求到不同的服务器上。 这个角色就是反向代理服务器。 结论:反向代理,是用于代理服务端的。 负载均衡==== 场景:反向代理过程中,每台服务器处理来自客户端的请求都应该是均衡的。 原理:使用一个反向代理服务器指向多台部署相同应用的服务器,客户端请求直接向反向代理服务器发起,反向代理服务器根据负载均衡机制,将请求转发到不同的应用服务器上。 负载均衡机制: Nginx负载均衡方法=========== Nginx负载均衡(工作在七层“应用层”)功能主要是通过upstream模块实现,Nginx负载均衡默认对后端服务器有健康检测的能力,仅限于端口检测,在后端服务器比较少的情况下负载均衡能力表现突出。 1、轮询(默认) 每个请求按时间顺序逐一分配到不同的后端服务器,如果后端某台服务器宕机,则自动剔除故障机器,使用户访问不受影响。 2、weight 指定轮询权重,weight值越大,分配到的几率就越高,主要用于后端每台服务器性能不均衡的情况。 3、ip_hash 每个请求按访问IP的哈希结果分配,这样每个访客固定访问一个后端服务器,可以有效的解决动态网页存在的session共享问题。 4、fair(第三方) 更智能的一个负载均衡算法,此算法可以根据页面大小和加载时间长短智能地进行负载均衡,也就是根据后端服务器的响应时间来分配请求,响应时间短的优先分配。如果想要使用此调度算法,需要Nginx的upstream_fair模块。 5、url_hash(第三方) 按访问URL的哈希结果来分配请求,使每个URL定向到同一台后端服务器,可以进一步提高后端缓存服务器的效率。如果想要使用此调度算法,需要Nginx的hash软件包。 在upstream模块中,可以通过server命令指定后端服务器的IP地址和端口,同时还可以设置每台后端服务器在负载均衡调度中的状态,常用的状态有以下几种: 1、down 表示当前server暂时不参与负载均衡。 2、backup 预留的备份机,当其他所有非backup机器出现故障或者繁忙的时候,才会请求backup机器,这台机器的访问压力最轻。 3、max_fails 允许请求的失败次数,默认为1,配合fail_timeout一起使用 4、fail_timeout 经历max_fails次失败后,暂停服务的时间,默认为10s(某个server连接失败了max_fails次,则nginx会认为该server不工作了。同时,在接下来的 fail_timeout时间内,nginx不再将请求分发给失效的server。)12345678910111213141516171819202122http{ upstream whsirserver { server 192.168.0.120:80 weight=5 max_fails=3 fail_timeout=20s; server 192.168.0.121:80 weight=1 max_fails=3 fail_timeout=20s; server 192.168.0.122:80 weight=3 max_fails=3 fail_timeout=20s; server 192.168.0.123:80 weight=4 max_fails=3 fail_timeout=20s; } server { listen 80; server_name blog.whsir.com; index index.html index.htm; root /data/www; location / { proxy_pass http://whsirserver; proxy_next_upstream http_500 http_502 error timeout invalid_header; } }} upstream负载均衡开始,通过upstream指定了一个负载均衡器的名称为whsirserver,这个名称可以自己定义,在后面proxy_pass直接调用即可。 proxy_next_upstream参数用来定义故障转移策略,当后端服务器节点返回500、502和执行超时等错误时,自动将请求转发到upstream负载均衡器中的另一台服务器,实现故障转移。 nginx提供了以下三种方法: 1)round-robin:请求以循环、轮转的方式分发到服务器 2)least-connected:下一个请求被分配到拥有最少活动连接数的服务器 3)ip-hash:使用一个哈希函数,基于客户端ip地址判断下一个请求应该被分发到哪台服务器 相关配置说明 1)循环、轮转负载均衡 round-robin:默认情况下,使用循环、轮转的方式分发请求到服务器。 当不指定负载均衡方式时,默认以round-robin方式实现。所有请求都会被代理到myapp服务器,根据负载均衡机制分发请求。 配置示例:12345678910111213http{ upstream myapp{ server srv1.example.com; server srv2.example.com; server srv3.example.com; } server{ listen 80; location / { proxy_pass http://myapp; } }} 2)最少连接负载均衡 least-connected:当一些请求处理的时间比较长时,最少连接负载均衡能够争取到更大的公平。 配置示例:123456upstream myapp{ least-conn; server srv1.example.com; server srv2.example.com; server srv3.example.com;} 3)基于ip地址的负载均衡 ip-hash:采用目标地址散列调度(Destination Hashing Scheduling)算法,根据请求的目标ip地址,作为散列键(Hash Key)从静态分配的散列表找出对应的服务器,若该服务器可用且未超载,则将请求发送带服务器,否则返回空。123456upstream myapp{ ip-hash; server srv1.example.com; server srv2.example.com; server srv3.example.com;} 1.单纯使用Nginx,会造成配置维护成本变高。 2.单点故障率增加,因为热点服务的访问量很高,如果这个服务的负载均衡服务出现问题,整个服务都会挂掉。 Nginx配置说明=========1234567891011121314151617181920212223242526#user nobody;worker_processes 4;events { # 最大并发数 worker_connections 1024;}http{ # 待选服务器列表 upstream myproject{ # ip_hash指令,将同一用户引入同一服务器。 ip_hash; server 125.219.42.4 fail_timeout=60s; server 172.31.2.183; } server{ # 监听端口 listen 80; # 根目录下 location / { # 选择哪个服务器列表 proxy_pass http://myproject; } }}]]></content>
<categories>
<category>运维</category>
</categories>
<tags>
<tag>Nginx</tag>
</tags>
</entry>
<entry>
<title><![CDATA[Nginx学习]]></title>
<url>%2F2016-03-02-Nginx%E5%AD%A6%E4%B9%A0.html</url>
<content type="text"><![CDATA[一、nginx常用命令=========== 1.Nginx启动 1234567 nginx -c /etc/nginx/nginx.conf``` 其中参数-c指定nginx启动时加载的配置文件,当然也可以不指定配置文件,省略-c,也可以启动,表示使用默认的配置文件。### 2.nginx停止--------- nginx -s stop 或者 nginx -s quit 或者 pkill -9 nginx 12例如在我们的编辑环境中已经安装好了nginx,并且已启动,在命令提示符下直接输入 nginx -s stop 12345就可以停止了。### 3.nginx重载配置----------- nginx -s reload 123### 4.检查配置文件是否正确------------ nginx -t 123456789## 二、配置文件结构========Nginx的核心模块为**Main**和**Events**,此外还包括**标准HTTP模块、可选HTTP模块和邮件模块**,其还可以支持诸多第三方模块。Main用于配置错误日志、进程及权限等相关的参数,Events用于配置IO模型,如epoll、kqueue、select或poll等,它们是必备模块,HTTP模块用于控制Nginx的HTTP进程。Nginx的主配置文件由几个段组成,这个段通常也被称为nginx的上下文,每个段的定义格式如下所示。需要注意的是,其每一个指令都必须使用分号(;)结束,否则为语法错误。主要结构(所有配置以分号结尾)如下: ##Main段,定义全局属性 events { ##定义不同IO模型下的工作机制; } http { ##定义作为web服务器的相关属性(还可以反向代理mail) server { ##定义一个虚拟主机的属性,所有web服务必须定义成一个虚拟主机,与httpd不同 location [option] uri { ##定义一个URI的特性 ##location中可以嵌套location的 location [option] uri { #嵌套location } if (condition) { ##定义URL重写 } } } upstream <Name> { ##将多个server结合在一起,实现负载均衡 } } 12345## 三、配置指令======定义Nginx运行的用户和用户组用user指令。 user www-data; 12定义nginx进程数,用worker_processes指令,建议设置为等于CPU总核心数。 worker_processes 8; 12全局错误日志定义类型,**\[ debug | info | notice | warn | error | crit\]**用error_log指令。另外日志还可以定义在http、server及location上下文中,语法格式一样。 error_log /var/log/nginx/error.log info; 12定义进程文件用pid指令 pid /var/run/nginx.pid; 12用worker\_rlimit\_nofile指令描述nginx进程打开的最多文件描述符的数目,建议设置为默认值。 worker_rlimit_nofile 65535; 12参考事件模型指令:use \[ kqueue | rtsig | epoll | /dev/poll | select | poll \]; use epoll; 1234注:epoll模型是Linux 2.6以上版本内核中的高性能网络I/O模型,如果跑在FreeBSD上面,就用kqueue模型。设置单个进程最大连接数用指令:worker_connections(`最大连接数=连接数*进程数`) worker_connections 65535; 12设定mime类型,类型由mime.type文件定义 用include指令. include /etc/nginx/mime.types; default_type application/octet-stream; 12开启gzip压缩指令 gzip on; gzip_disable "MSIE [1-6]\.(?!.*SV1)"; 12设定负载均衡的服务器列表用指令upstream。 upstream mysvr { #weigth参数表示权值,权值越高被分配到的几率越大 #本机上的Squid开启3128端口 server 192.168.8.1:3128 weight=5; server 192.168.8.2:80 weight=1; server 192.168.8.3:80 weight=6; } 1设定虚拟主机用指令server,其中包括端口,主机名称,默认请求等设置。 server { #侦听80端口 listen 80; #定义使用www.xx.com访问 server_name www.xx.com; #设定本虚拟主机的访问日志 access_log logs/www.xx.com.access.log main; #默认请求 location / { root /root; #定义服务器的默认网站根目录位置 index index.php index.html index.htm; #定义首页索引文件的名称 fastcgi_pass www.xx.com; fastcgi_param SCRIPT_FILENAME $document_root/$fastcgi_script_name; include /etc/nginx/fastcgi_params; } # 定义错误提示页面 error_page 500 502 503 504 /50x.html; location = /50x.html { root /root; } } 12请求转向指令proxy_pass proxy_pass http://www.hubwiz.com; 123456789101112131415161718192021222324252627## 四、负载均衡======负载均衡(又称为负载分担),英文名称为Load Balance,其意思就是将负载(工作任务)进行平衡、分摊到多个操作单元上进行执行,例如Web服务器、FTP服务器、企业关键应用服务器和其它关键任务服务器等,从而共同完成工作任务。nginx的upstream目前支持4种方式的分配1)、轮询(默认)---------每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除。2)、weight---------指定轮询几率,weight和访问比率成正比,用于后端服务器性能不均的情况。3)、ip_hash----------每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决session的问题。4)、fair(第三方)------------按后端服务器的响应时间来分配请求,响应时间短的优先分配。 upstream ixdba.net{ ip_hash; server 192.168.12.133:80; server 192.168.12.134:80 down; server 192.168.12.135:8009 max_fails=3 fail_timeout=20s; server 192.168.12.136:8080; } 1234567891011121314151617181920212223242526272829303132333435363738394041upstream是Nginx的HTTP Upstream模块,这个模块通过一个简单的调度算法来实现客户端IP到后端服务器的负载均衡。在上面的设定中,通过upstream指令指定了一个负载均衡器的名称 [ixdba.net](http://ixdba.net)。这个名称可以任意指定,在后面需要的地方直接调用即可。## 五、Location配置============语法规则: `location \[=||*|^~\] /uri/ { … }`通配符说明=开头表示精确匹配^~开头表示uri以某个常规字符串开头,理解为匹配 url路径即可~开头表示区分大小写的正则匹配!~区分大小写不匹配!~*不区分大小写不匹配~*开头表示不区分大小写的正则匹配/通用匹配,任何请求都会匹配到首先匹配 =,其次匹配^~, 其次是按文件中顺序的正则匹配,最后是交给 / 通用匹配。当有匹配成功时候,停止匹配,按当前匹配规则处理请求。 location = / { #规则A } location = /login { #规则B } location ^~ /static/ { #规则C } location ~ \.(gif|jpg|png|js|css)$ { #规则D } 1234567891011121314那么产生的效果如下:访问根目录/, 比如http://localhost/ 将匹配规则A;访问 [http://localhost/login](http://localhost/login) 将匹配规则B;访问 [http://localhost/static/a.html](http://localhost/static/a.html) 将匹配规则C;访问 [http://localhost/a.gif](http://localhost/a.gif), [http://localhost/b.jpg](http://localhost/b.jpg) 将匹配规则D。## 六、Rewrite规则===========Nginx Rewrite 规则相关指令有if,rewrite,set,return,break等,其中最关键的就是rewrite。一个简单的Nginx Rewrite规则语法如下: rewrite ^/b/(.\*)\.html /play.php?video=$1 break; 1234567891011121314151617181920212223242526272829303132333435**正则表达式匹配**,其中:1、~ 为区分大小写匹配;2、~* 为不区分大小写匹配;3、!和!*分别为区分大小写不匹配及不区分大小写不匹配。**文件及目录匹配**,其中:-f和!-f用来判断是否存在文件;-d和!-d用来判断是否存在目录;-e和!-e用来判断是否存在文件或目录;-x和!-x用来判断文件是否可执行。**flag标记有**:last 相当于Apache里的\[L\]标记,表示完成rewrite;break 终止匹配, 不再匹配后面的规则;redirect 返回302临时重定向 地址栏会显示跳转后的地址;permanent 返回301永久重定向 地址栏会显示跳转后的地址。当然除了这些以外,Rewrite规则中还会用到一些相应的全局变量,如$args,$url等等## 七、配置自己的文件=========前面几节中我们已经学过了nginx配置文件中的各个段的配置指令,下面我们就来写一个自己配置文件。如下代码: worker_processes 1; events { worker_connections 1024; } http { server { location / { #root html; #定义服务器的默认网站根目录位置 #index index.php index.html index.htm; #定义首页索引文件的名称 proxy_pass http://www.hubwiz.com; } error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } } } 1234这样我们自己的配置文件就完成了,先将nginx的服务停止,然后我们用nginx -c *.conf 命令来重新启动nginx,*.conf为我们自己的配置文件所在的路径,nginx启动以后,然后点击【访问测试】,看看会出现什么情况,是不是已经转到我们所配置的站点了。我自己的配置文件名为Mynginx.conf,其中的内容就是以上面代码的内容,保存在/etc/nginx目录下,完成以后我们做如下操作: nginx -s stop nginx -c /etc/nginx/Mynginx.conf 123456789然后测试。## 八、反向代理示例========反向代理(Reverse Proxy) 是指代理服务器来接收来自Internet上的连接请求,并将请求转发给内部网络上的服务器,并从服务器上得到的结果返回给Internet上请求连接的客户端。比如要配置后端跑 apache 服务的 ip 和端口,也就是说,我们的目标是实现通过 [http://ip](http://ip):port 能访问到你的网站。配置文件可以修改以下内容,reload nginx就可以了。 ## Basic reverse proxy server ## upstream apachephp { server ip:8080; #Apache } ## Start www.nowamagic.net ## server { listen 80; server_name www.nowamagic.net; access_log logs/quancha.access.log main; error_log logs/quancha.error.log; root html; index index.html index.htm index.php; ## send request back to apache ## location / { proxy_pass http://apachephp; #…………………… } } 1234567## 九、虚拟主机示例========Nginx做虚拟主机,尤其是仅仅支持纯静态-html,这是最简单的应用了,可以理解为一个仅支持静态页面的最简单的Web服务器。例子,同时支持两个虚拟主机(纯静态-html支持)的配置,我们只需要理改server段,如下: server { listen 80; server_name www.hubwiz.com; #charset koi8-r; #access_log logs/host.access.log main; location / { root /root; index index.php index.html index.htm; } error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } } server { listen 80; server_name www.baidu.com; #charset koi8-r; #access_log logs/host.access.log main; location / { root /root; index index.php index.html index.htm; } error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } } 12345## 十、正向代理示例========Nginx正向代理配置如下: server { listen 8080; server_name www.hubwiz.com; index index.html index.htm index.php; root /home/wwwroot; location / { resolver 192.168.8.88; proxy_pass $scheme://$http_host$request_uri; proxy_buffers 256 4k; } access_log off; } 12345678910111213以上配置的注意事项:1,不能有hostname。2,必须有resolver, 即dns,即上面的x.x.x.x,换成当前机器的DNS服务器ip即可(查看dns方法 cat /etc/resolv.conf 代理使用)。3,$http\_host和$request\_uri是nginx系统变量,保持原样即可。检测配置文件无误后,重启nginx,在浏览器中添加代理服务器的IP地址,就可以使用该Nginx正向代理了。## 十一、负载均衡示例========= upstream backend{ #定义负载均衡设备的Ip及设备状态 server 127.0.0.1:9090 down; server 192.168.1.12:8080 weight=2 ; server 192.168.1.13:6060 max_fails=3 fail_timeout=30s; server 1192.168.1.14:7070 backup; } server{ #………………………… location /{ proxy_pass http://backend; #………………………… } } 1234567891011121314151617以上代码就是对负载均衡应用的示例。Upstream可对后端服务器进行健康检查。a) down表示当前的server暂时不参与负载。b) weight默认为1.weight越大,负载的权重就越大。c) max_fails :在fail_timeout时间内对后台服务器请求失败的次数。d) fail_timeout:max_fails次失败后,暂停的时间。e) backup:其它所有的非backup机器down或者忙的时候,请求backup机器。所以这台机器压力会最轻。## 十二、Rewrite简单示例============== worker_processes 1; events { worker_connections 1024; } http { server { location /hubwiz { rewrite (.*) http://www.hubwiz.com; } location /baidu { rewrite (.*) http://www.baidu.com; } error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } } } ` 修改我们自己的配置文件,保存,重新加载nginx,然后测试,在地址栏给出的地址后面分别输入“/hubwiz”、“/baidu”,是不是会和我的结果一样呢? 输入“/hubwiz”转到汇智网,输入“/baidu”是不是转到百度了呢?]]></content>
<categories>
<category>运维</category>
</categories>
<tags>
<tag>Nginx</tag>
</tags>
</entry>
</search>