-
Notifications
You must be signed in to change notification settings - Fork 0
/
atom.xml
532 lines (281 loc) · 206 KB
/
atom.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
526
527
528
529
530
531
532
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title>GCFBlog</title>
<icon>https://www.gravatar.com/avatar/9f02cd45ebf24371e1b64ae0b644732f</icon>
<subtitle>This is GCF's blog</subtitle>
<link href="http://yoursite-url/atom.xml" rel="self"/>
<link href="http://yoursite-url/"/>
<updated>2022-12-20T09:10:43.000Z</updated>
<id>http://yoursite-url/</id>
<author>
<name>Gu</name>
<email>[email protected]</email>
</author>
<generator uri="https://hexo.io/">Hexo</generator>
<entry>
<title>高可用策略</title>
<link href="http://yoursite-url/%E9%AB%98%E5%8F%AF%E7%94%A8%E7%AD%96%E7%95%A5/%E9%AB%98%E5%8F%AF%E7%94%A8%E7%AD%96%E7%95%A5/"/>
<id>http://yoursite-url/%E9%AB%98%E5%8F%AF%E7%94%A8%E7%AD%96%E7%95%A5/%E9%AB%98%E5%8F%AF%E7%94%A8%E7%AD%96%E7%95%A5/</id>
<published>2022-12-20T09:10:43.000Z</published>
<updated>2022-12-20T09:10:43.000Z</updated>
<content type="html"><![CDATA[<h1>高可用策略</h1><blockquote><p>可用性是CAP(Consistency,Availability,Partial tolerance)理论中的一个,表示每次请求都能获得响应,不会返回错误。</p><p>高可用是指通过设计减少系统不能提供服务的时间。比如100个系统时间,有1个时间不能提供服务,则可用性为99%。</p></blockquote><p>用户发送的请求通常会被拆分成各项服务的调用,服务之间有依赖调用,上游的服务处理完调用下游的服务。</p><h2 id="熔断">熔断</h2><blockquote><p>在服务的依赖调用中,被调用方出现故障时,出于自我保护的目的,调用方会主动停止调用,并根据业务需要进行相应处理。调用方这种主动停止调用的行为我们称之为熔断。</p></blockquote><p><img src="%E7%86%94%E6%96%AD.png" alt="熔断"></p><p>假设服务A依赖服务B,当B处于正常状态,则调用可以完成;</p><p>当B出现故障、处理慢或者响应超时,由于A在等待B,故而A的响应时间也会延长。换句话说<strong>B的故障传递到A</strong>,<strong>使得A也不可用</strong>。</p><h2 id="限流">限流</h2><blockquote><p>限流是针对服务请求数量的一种自我保护机制,当请求数量超出服务的处理能力时,会自动丢弃新来的请求。</p></blockquote><p><img src="%E9%99%90%E6%B5%81.png" alt="限流"></p><p>任何一个服务的处理能力都是有极限的。</p><p>假设<strong>服务B</strong>的处理能力为<code>QPS=100</code>,当<code>QPS<100</code>时服务B可以提供正常的服务。</p><p>当<code>QPS>100</code>时,由于请求量增大,会出现争抢服务资源的情况(数据库连接、CPU、内存等),导致<strong>服务B</strong>处理缓慢;</p><p>当<code>QPS</code>继续增大时,可能会造成<strong>服务B</strong>响应更加缓慢甚至奔溃。</p><p><strong>如果不进行限流控制</strong>,<strong>服务B始终会面临着被大流量冲击的风险</strong>。做好系统请求流量的评估,制定合理的限流策略,是我们进行系统高可用保护的第一步。</p><h2 id="降级">降级</h2><blockquote><p>降级是通过开关配置将某些不重要的业务功能屏蔽掉,以提高服务处理能力。</p><p>在大促场景中经常会对某些服务进行降级处理,大促结束之后再进行复原。</p></blockquote><p><img src="%E9%99%8D%E7%BA%A7.png" alt="降级"></p><p>在不影响业务核心链路的情况下,<strong>屏蔽某些不重要的业务功能</strong>,可以节省系统的处理时间,提供系统的响应能力,在服务器资源固定的前提下处理更多的请求。</p><blockquote><p><strong>熔断</strong>是减少由于下游服务故障对自己的影响;</p><p>而<strong>降级</strong>则是在整个系统的角度上,考虑业务整体流量,保护核心业务稳定。</p></blockquote>]]></content>
<summary type="html"><h1>高可用策略</h1>
<blockquote>
<p>可用性是CAP(Consistency,Availability,Partial tolerance)理论中的一个,表示每次请求都能获得响应,不会返回错误。</p>
<p>高可用是指通过设计减少系统不能提供服务的时间。</summary>
<category term="分布式" scheme="http://yoursite-url/categories/%E5%88%86%E5%B8%83%E5%BC%8F/"/>
<category term="分布式" scheme="http://yoursite-url/tags/%E5%88%86%E5%B8%83%E5%BC%8F/"/>
</entry>
<entry>
<title>网络编程API</title>
<link href="http://yoursite-url/%E7%BD%91%E7%BB%9C%E7%BC%96%E7%A8%8BAPI/%E7%BD%91%E7%BB%9C%E7%BC%96%E7%A8%8BAPI/"/>
<id>http://yoursite-url/%E7%BD%91%E7%BB%9C%E7%BC%96%E7%A8%8BAPI/%E7%BD%91%E7%BB%9C%E7%BC%96%E7%A8%8BAPI/</id>
<published>2022-12-01T04:02:03.000Z</published>
<updated>2022-12-01T04:02:03.000Z</updated>
<content type="html"><![CDATA[<h1>网络编程API</h1><h2 id="套接字">套接字</h2><blockquote><p>#include <sys/socket.h></p></blockquote><p><em><strong>iovec结构体</strong></em></p><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">iovec</span> {</span></span><br><span class="line"><span class="keyword">void</span>* iov_base;<span class="comment">//缓冲地址</span></span><br><span class="line"><span class="keyword">size_t</span> iov_len; <span class="comment">//缓冲大小</span></span><br><span class="line">}</span><br></pre></td></tr></table></figure><h3 id="TCP">TCP</h3><table><thead><tr><th>函数</th><th>功能</th></tr></thead><tbody><tr><td>int socket(int domain, int type, int protocol);</td><td>创建套接字,成功返回文件描述符,失败返回-1</td></tr><tr><td>int bind(int sockfd , struct sockaddr *myaddr, socklen addrlen);</td><td>绑定套接字ip与端口,成功返回0,失败返回-1</td></tr><tr><td>int listen(int sockfd , int backlog);</td><td>设置监听,成功返回0,失败返回-1</td></tr><tr><td>int accept(int sockfd, struct sockaddr *addr… socklen_t *addrlen);</td><td>接收连接,成功返回文件描述符,失败返回-1</td></tr><tr><td>int connect(int sockfdJ struct sockaddr *serv_addr, socklen_t addrlen);</td><td>发起连接,成功返回0,失败返回-1</td></tr><tr><td>sslze_t send(int sockfd, const void * buf, size_t nbytes, int flags);</td><td>发送数据,成功返回发送字节数,失败返回-1</td></tr><tr><td>ssize_t recv(int sock void * buf, size_t nbytes, int flags);</td><td>接受数据,成功返回接受字节数,失败返回-1</td></tr><tr><td>#include <sys/uio.h><br />ssize_t writev(int filedes const struct iovec * iov, int iovcnt);</td><td>多个地方整合发送数据,成功返回发送字节数,失败返回-1</td></tr><tr><td>#include <sys/unio.h><br />ssize_t readv(int filedes, const struct iovec * iov, int iovcnt);</td><td>多个地方整合接收数据,成功返回发送字节数,失败返回-1</td></tr><tr><td>#include <sys/sendfile.h><br />ssize_t sendfile(int out_fd, int in_fd, off_t* offset, size_t count);</td><td>在两个文件描述符间零拷贝发送数据,只在内核有拷贝</td></tr></tbody></table><blockquote><p>Nagle算法开启后,TCP收到ACK后才会发送下一个数据包,可以减少网络中因为发送小数据产生的数据包数量。</p><p>大文件数据传输禁用Nagle算法,因为会在装满缓冲时传输数据包,并不会增加数据包的数量,还会连续传输,提高传输速度。</p><p>TCP_NODELAY可以设置是否开启Nagle算法。</p></blockquote><h3 id="UDP">UDP</h3><table><thead><tr><th>函数</th><th>功能</th></tr></thead><tbody><tr><td>ssize_t sendto(int sock, void *buff, size_t nbytes, int flags, struct sockaddr *to, socklen_t addrlen);</td><td>发送消息给指定地址的主机,成功返回传输的字节数,失败返回-1</td></tr><tr><td>ssize-t ecvfrom(int sock, void *buff, size_t nbytes, int flags, struct sockaddr * from, socklen_t *addrlen);</td><td>接受指消息,将主机地址保存在from,成功返回接收的字节数,失败返回-1</td></tr></tbody></table><blockquote><ul><li>UDP套接字调用connect并不意味着要和对方UDP套接字连接,只是向UDP套接字注册目标IP和端口信息。这样UDP套接字也可以使用read和write来发送和接收数据。</li><li>UDP存在数据边界,TCP不存在。因此UDP调用多少次sendto发送,就要调用多少次recvfrom。</li></ul></blockquote><h3 id="套接字设置">套接字设置</h3><table><thead><tr><th>函数</th><th>功能</th></tr></thead><tbody><tr><td>int getsockopt(int sock, int level, int optname, void *optval, socklen_t *optlen);</td><td>获取套接字属性,成功返回0,失败返回-1</td></tr><tr><td>int setsockopt(int sock, int level, int optname, const void *optval, socklen_t optlen);</td><td>设置套接字属性,成功返回0,失败返回-1</td></tr></tbody></table><h2 id="文件操作">文件操作</h2><table><thead><tr><th>函数</th><th>功能</th></tr></thead><tbody><tr><td>#include <sys/types.h><br />#include <sys/stat.h><br />#inlcude <fcntl.h><br />int open(const char *path int flag);</td><td>打开文件,成功返回文件描述符,失败返回-1</td></tr><tr><td>#include <unistd.h><br />int close(int fd);</td><td>关闭文件,成功返回0,失败返回-1</td></tr><tr><td>#include <unistd.h><br />ssize_t write(int fd, const void* buf, size_t nbytes);</td><td>成功返回写入的字节数,失败返回-1</td></tr><tr><td>#include <unistd.h><br />ssize_t read(int fd, void* buf, size_t nbytes);</td><td>成功返回接受的字节数(遇到文件尾返回0),失败返回-1</td></tr></tbody></table><h2 id="字节序转换">字节序转换</h2><blockquote><p>#include <arpa/inet.h></p></blockquote><table><thead><tr><th>函数</th><th>功能</th></tr></thead><tbody><tr><td>unsigned short htons(unsigned short);</td><td>(端口转换)short类型主机序转换为网络序</td></tr><tr><td>unsigned short ntohs(unsîgned short);</td><td>(端口转换)short类型网络序转换为主机序</td></tr><tr><td>unsigned long hton1(unsigned long);</td><td>(ip转换)long类型主机序转换为网络序</td></tr><tr><td>unsigned long ntohl(unsigned long);</td><td>(ip转换)long类型网络序转换为主机序</td></tr><tr><td>in_addr_ t inet_addr(const char * string);</td><td>将字符串ip地址转换为网络序,成功返回32位大端序整数型值,失败返回INADDR_NONE</td></tr><tr><td>int inet_aton(const char * string) struct in_addr * addr);</td><td>将字符串ip地址转换为网络序,成功返回1,失败返回0</td></tr><tr><td>char* inet_ntoa(struct in_addr adr) ;</td><td>将网络序ip转换为字符串,成功返回字符串地址,失败返回-1</td></tr></tbody></table><blockquote><ul><li>inet_addr得到的结果仍需要手动设置到in_addr结构体里面;而inet_aton直接就转换完设置进去。</li><li>INADDR_ANY表示任意ip地址,这样内核会在连接时候选择ip地址。</li></ul></blockquote><h2 id="ip与域名之间的转换">ip与域名之间的转换</h2><blockquote><p>#include <netdb.h></p></blockquote><p><em><strong>hostent结构体</strong></em></p><figure class="highlight arduino"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">hostent</span> {</span></span><br><span class="line">cha r * h_name; <span class="comment">//official name </span></span><br><span class="line"><span class="keyword">char</span> ** h_aliases; <span class="comment">//alias list </span></span><br><span class="line"><span class="keyword">int</span> h_addrtype;<span class="comment">// host address type </span></span><br><span class="line"><span class="keyword">int</span> h_length; <span class="comment">// address length </span></span><br><span class="line"><span class="keyword">char</span> ** h_addr_list; <span class="comment">// address list </span></span><br><span class="line">}</span><br></pre></td></tr></table></figure><table><thead><tr><th>函数</th><th>功能</th></tr></thead><tbody><tr><td>struct hostent * gethostbyname(const char* hostname);</td><td>域名转换为ip,成功返回结构体指针,失败返回NULL</td></tr><tr><td>struct hostent * gethostbyaddr(const char * addr, socklen_t len, int family);</td><td>ip转换为域名,成功返回结构体指针,失败返回NULL</td></tr></tbody></table><h2 id="进程操作">进程操作</h2><h3 id="僵尸子进程">僵尸子进程</h3><table><thead><tr><th>函数</th><th>功能</th></tr></thead><tbody><tr><td>#include <unistd.h><br/>pid_t fork(void);</td><td>创建子进程,成功返回进程id(父进程返回子进程id,子进程返回0),失败返回-1</td></tr><tr><td>#include <sys/wait.h><br />pid_t wait(int * statloc);</td><td>等待回收子进程资源,成功返回子进程pid,失败返回-1。<br />可以使用WIFEXITED(*statloc)判断子进程是否异常退出,true表示正常终止。<br />WEXITSTATUS(*statloc)返回子进程的返回值。</td></tr><tr><td>#include <sys/wait.h><br />pid_t waitpid(pid_t pid, int * statloc, int options);</td><td>等待回收指定子进程资源,成功返回子进程pid,失败返回-1。<br />pid表示想要回收的子进程,为-1时同wait函数一样,回收任意子进程。<br />若将options设置为WNOHANG,则没有终止的子进程也不会陷入阻塞。</td></tr></tbody></table><h3 id="信号处理">信号处理</h3><blockquote><p>发生信号时候,将唤醒由于调用sleep函数而进入阻塞转台的进程。进程一旦唤醒,就不会进入阻塞。</p></blockquote><p><em><strong>sigaction结构体</strong></em></p><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">sigaction</span> {</span></span><br><span class="line"><span class="built_in"><span class="keyword">void</span></span> (*sa_handler)(<span class="keyword">int</span>);</span><br><span class="line"><span class="keyword">sigset_t</span> sa_mask;</span><br><span class="line"><span class="keyword">int</span> sa_flags;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><table><thead><tr><th>函数</th><th>功能</th></tr></thead><tbody><tr><td>#include <signal.h><br />void (*signal(int signo, void (*func)(int)))(int);<br />这样写好理解点:<br />void (*)(int) signal(int signo, void (*func)(int));</td><td>设置信号处理函数;<br />第一个参数是所要处理的信号,第二个参数是处理该信号的函数指针。<br />返回类型是函数指针。</td></tr><tr><td>#include <unistd.h><br />unsigned int alarm(unsigned int seconds);</td><td>设置定时发生SIGALRM;<br />返回0或者以秒为单位的距SIGALRM信号发生所剩时间。<br />如果参数传递为0,则取消之前的所有定时;<br />如果添加处理函数,则会终止进程。</td></tr><tr><td>#include <signal.h><br />int sigaction(int signo, const struct sigaction * act, struct sigaction * oldact) ;</td><td>设置信号集,成功返回0,失败返回-1</td></tr></tbody></table><h3 id="管道通信">管道通信</h3><blockquote><p>管道使用pipe函数,fork出进程以后,关闭对应读端和写端即可对管道进行读写,若不关闭对应的端,则有可能自己写的自己读;</p><p>管道是单向的。</p></blockquote><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><unistd.h></span></span></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">pipe</span><span class="params">(<span class="keyword">int</span> filedes[<span class="number">2</span>])</span></span>;</span><br></pre></td></tr></table></figure><blockquote><p>f[0] 是读端,f[1] 是写端。</p></blockquote><h2 id="多线程操作">多线程操作</h2><blockquote><p>#include <pthread.h></p></blockquote><table><thead><tr><th>函数</th><th>功能</th></tr></thead><tbody><tr><td>int pthread_create( pthread_t * thread, const pthread_attr_t * attr, void * (* start_routine)(void * ), void *arg);</td><td>创建线程,成功返回0,失败返回错误码</td></tr><tr><td>int pthread_join(pthread_t thread, void ** retval);</td><td>阻塞等待指定线程终止,参数是线程退出的信息,成功返回0,失败返回错误码</td></tr><tr><td>void pthread_exit(void* retval);</td><td>线程退出,不会失败</td></tr><tr><td>int pthread_cancel(pthread_t thread)</td><td>异常终止某个线程,成功返回0,失败返回错误码;<br /></td></tr><tr><td>int pthread_setcancelstate(int state, int* oldstate);<br />int pthread_setcanceltype(int type, int* oldtype);</td><td>接收到取消请求的目标线程可以通过设置取消状态和类型来决定是否被取消以及如何取消。</td></tr></tbody></table><h2 id="线程锁与信号量">线程锁与信号量</h2><h3 id="信号量">信号量</h3><blockquote><p>#include <semaphore.h></p><p>以下函数成功返回0,失败返回-1,并设置errno错误码。</p></blockquote><table><thead><tr><th>函数</th><th>功能</th></tr></thead><tbody><tr><td>int sem_init(sem_t* sem, int pshred, unsigned int value);</td><td>初始化信号量,value是信号量初始值</td></tr><tr><td>int sem_destroy(sem_t* sem);</td><td>销毁信号量</td></tr><tr><td>int sem_wait(sem_t* sem);</td><td>P操作,将信号量值-1</td></tr><tr><td>int sem_trywait(sem_t* sem);</td><td>不阻塞的P操作,成功返回0,失败返回-1,并设置errno为EAGAIN</td></tr><tr><td>int sem_post(sem_t* sem);</td><td>V操作,将信号量+1,若有线程阻塞在该信号量,则唤醒一个</td></tr></tbody></table><h3 id="互斥锁">互斥锁</h3><blockquote><p>#include <pthread.h></p><p>以下函数成功返回0,失败返回错误码。</p></blockquote><table><thead><tr><th>函数</th><th>功能</th></tr></thead><tbody><tr><td>int pthread_mutex_init(pthread_mutex_t* mutex, const pthread_mutexaddr_t* mutex_attr);</td><td>初始化互斥锁</td></tr><tr><td>int pthread_mutex_destroy(pthread_mutex_t* mutex);</td><td>销毁互斥锁</td></tr><tr><td>int pthread_mutex_lock(pthread_mutex_t* mutex);</td><td>加锁</td></tr><tr><td>int pthread_mutex_trylock(pthread_mutex_t* mutex);</td><td>尝试解锁</td></tr><tr><td>int pthread_mutex_unlock(pthread_mutex_t* mutex);</td><td>释放锁</td></tr></tbody></table><h3 id="条件变量">条件变量</h3><blockquote><p>#include <pthread.h></p><p>以下函数成功返回0,失败返回错误码。</p></blockquote><table><thead><tr><th>函数</th><th>功能</th></tr></thead><tbody><tr><td>int pthread_cond_init(pthread_cond_t* cond, const pthread_condattr_t* cond_attr);</td><td>初始化条件变量</td></tr><tr><td>int pthread_cond_destroy(pthread_cond_t* cond);</td><td>销毁条件变量,销毁一个正在被等待的条件变量将失败并返回EBUSY</td></tr><tr><td>int pthread_cond_broadcast(pthread_cond_t* cond);</td><td>广播唤醒所有等待该条件变量的线程</td></tr><tr><td>int pthread_cond_signal(pthread_cond_t* cond);</td><td>唤醒一个等待该条件变量的线程</td></tr><tr><td>int pthread_cond_wait(pthread_cond_t* cond, pthread_mutex_t* mutex);</td><td>用于等待目标条件变量,mutex参数用于保护条件变量的互斥锁</td></tr></tbody></table><blockquote><p>pthread_cond_wait简称为wait,方便以下书写:</p><p>wait调用前,必须保证mutex已经加锁,wait函数执行时,将线程放入条件变量的等待队列中,然后解锁mutex,此时wait函数未返回。</p><p>当wait函数返回时候,会将mutex再次加锁。</p></blockquote>]]></content>
<summary type="html"><h1>网络编程API</h1>
<h2 id="套接字">套接字</h2>
<blockquote>
<p>#include &lt;sys/socket.h&gt;</p>
</blockquote>
<p><em><strong>iovec结构体</strong></em></summary>
<category term="网络编程" scheme="http://yoursite-url/categories/%E7%BD%91%E7%BB%9C%E7%BC%96%E7%A8%8B/"/>
<category term="网络编程" scheme="http://yoursite-url/tags/%E7%BD%91%E7%BB%9C%E7%BC%96%E7%A8%8B/"/>
</entry>
<entry>
<title>Git命令</title>
<link href="http://yoursite-url/Git%E5%91%BD%E4%BB%A4/Git%E5%91%BD%E4%BB%A4/"/>
<id>http://yoursite-url/Git%E5%91%BD%E4%BB%A4/Git%E5%91%BD%E4%BB%A4/</id>
<published>2022-08-05T02:01:13.000Z</published>
<updated>2022-08-05T02:01:13.000Z</updated>
<content type="html"><![CDATA[<h1>Git常用命令</h1><h2 id="git-init">git init</h2><blockquote><p>初始化项目所在目录,初始化后会在当前目录下出现一个名为 .git 的目录。</p></blockquote><figure class="highlight csharp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta"># 初始化本地仓库,在当前目录下生成 .git 文件夹</span></span><br><span class="line">$ git <span class="keyword">init</span></span><br></pre></td></tr></table></figure><h2 id="git-clone">git clone</h2><blockquote><p>将存储库克隆到新创建的目录中,为克隆的存储库中的每个分支创建远程跟踪分支(使用 <code>git branch -r</code> 可见),并从克隆检出的存储库作为当前活动分支的初始分支。</p></blockquote><figure class="highlight crmsh"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 默认在当前目录下创建和版本库名相同的文件夹并下载版本到该文件夹下</span></span><br><span class="line">$ git <span class="keyword">clone</span> <span class="title"><远程仓库的网址></span></span><br><span class="line"><span class="title"></span></span><br><span class="line"><span class="title"># 指定本地仓库的目录</span></span><br><span class="line"><span class="title">$</span> git <span class="keyword">clone</span> <span class="title"><远程仓库的网址> <本地目录></span></span><br><span class="line"><span class="title"></span></span><br><span class="line"><span class="title"># -b</span> 指定要克隆的分支,默认是<span class="literal">master</span>分支</span><br><span class="line">$ git <span class="keyword">clone</span> <span class="title"><远程仓库的网址> -b</span> <span class="tag"><分支名称></span> <span class="tag"><本地目录></span></span><br></pre></td></tr></table></figure><h2 id="git-add">git add</h2><blockquote><p>把要提交的文件的信息添加到暂存区中。当使用 git commit 时,将依据暂存区中的内容来进行文件的提交。</p><p>该命令可以在提交之前多次执行。它只在运行 <code>git add</code> 命令时添加指定文件的内容; 如果希望随后的更改包含在下一个提交中,那么必须再次运行 <code>git add</code> 将新的内容添加到索引。</p></blockquote><figure class="highlight fsharp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"># 把指定的文件添加到暂存区中</span><br><span class="line">$ git add <文件路径></span><br><span class="line"></span><br><span class="line"># 添加所有修改、已删除的文件到暂存区中</span><br><span class="line">$ git add -u <span class="meta">[<文件路径>]</span></span><br><span class="line">$ git add --update <span class="meta">[<文件路径>]</span></span><br><span class="line"></span><br><span class="line"># 添加所有修改、已删除、新增的文件到暂存区中,省略 <文件路径> 即为当前目录</span><br><span class="line">$ git add -A <span class="meta">[<文件路径>]</span></span><br><span class="line">$ git add --all <span class="meta">[<文件路径>]</span></span><br><span class="line"></span><br><span class="line"># 查看所有修改、已删除但没有提交的文件,进入一个子命令系统</span><br><span class="line">$ git add -i <span class="meta">[<文件路径>]</span></span><br><span class="line">$ git add --interactive <span class="meta">[<文件路径>]</span></span><br></pre></td></tr></table></figure><h2 id="git-commit">git commit</h2><blockquote><p>将索引(暂存区)的当前内容与描述更改的用户和日志消息一起存储在新的提交中。</p></blockquote><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#</span><span class="bash"> 把暂存区中的文件提交到本地仓库,调用文本编辑器输入该次提交的描述信息</span></span><br><span class="line"><span class="meta">$</span><span class="bash"> git commit</span></span><br><span class="line"></span><br><span class="line"><span class="meta">#</span><span class="bash"> 把暂存区中的文件提交到本地仓库中并添加描述信息</span></span><br><span class="line"><span class="meta">$</span><span class="bash"> git commit -m <span class="string">"<提交的描述信息>"</span></span></span><br><span class="line"></span><br><span class="line"><span class="meta">#</span><span class="bash"> 把所有修改、已删除的文件提交到本地仓库中</span></span><br><span class="line"><span class="meta">#</span><span class="bash"> 不包括未被版本库跟踪的文件,等同于先调用了 <span class="string">"git add -u"</span></span></span><br><span class="line"><span class="meta">$</span><span class="bash"> git commit -a -m <span class="string">"<提交的描述信息>"</span></span></span><br><span class="line"></span><br><span class="line"><span class="meta">#</span><span class="bash"> 修改上次提交的描述信息</span></span><br><span class="line"><span class="meta">$</span><span class="bash"> git commit --amend</span></span><br></pre></td></tr></table></figure><h2 id="git-config">git config</h2><blockquote><p>配置命令,主要是用来配置 Git 的相关参数。</p><p>Git共有3个配置文件:</p><ul><li>仓库配置文件:.git/.gitconfig;</li><li>全局配置文件:~/.gitconfig;</li><li>系统配置文件:Git安装目录下的etc文件夹中gitconfig。</li></ul></blockquote><figure class="highlight jboss-cli"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 查看配置信息</span></span><br><span class="line"><span class="comment"># --local:仓库级,--global:全局级,--system:系统级</span></span><br><span class="line">$ git config <<span class="params">--local</span> | <span class="params">--global</span> | <span class="params">--system</span>> -l</span><br><span class="line"></span><br><span class="line"><span class="comment"># 查看当前生效的配置信息</span></span><br><span class="line">$ git config -l</span><br><span class="line"></span><br><span class="line"><span class="comment"># 编辑配置文件</span></span><br><span class="line"><span class="comment"># --local:仓库级,--global:全局级,--system:系统级</span></span><br><span class="line">$ git config <<span class="params">--local</span> | <span class="params">--global</span> | <span class="params">--system</span>> -e</span><br><span class="line"></span><br><span class="line"><span class="comment"># 添加配置项</span></span><br><span class="line"><span class="comment"># --local:仓库级,--global:全局级,--system:系统级</span></span><br><span class="line">$ git config <<span class="params">--local</span> | <span class="params">--global</span> | <span class="params">--system</span>> <span class="params">--add</span> <name> <value></span><br><span class="line"></span><br><span class="line"><span class="comment"># 获取配置项</span></span><br><span class="line">$ git config <<span class="params">--local</span> | <span class="params">--global</span> | <span class="params">--system</span>> <span class="params">--get</span> <name></span><br><span class="line"></span><br><span class="line"><span class="comment"># 删除配置项</span></span><br><span class="line">$ git config <<span class="params">--local</span> | <span class="params">--global</span> | <span class="params">--system</span>> <span class="params">--unset</span> <name></span><br><span class="line"></span><br><span class="line"><span class="comment"># 配置提交记录中的用户信息</span></span><br><span class="line">$ git config <span class="params">--global</span> user.name <用户名></span><br><span class="line">$ git config <span class="params">--global</span> user.email <邮箱地址></span><br><span class="line"></span><br><span class="line"><span class="comment"># 更改Git缓存区的大小</span></span><br><span class="line"><span class="comment"># 如果提交的内容较大,默认缓存较小,提交会失败</span></span><br><span class="line"><span class="comment"># 缓存大小单位:B,例如:524288000(500MB)</span></span><br><span class="line">$ git config <span class="params">--global</span> http.postBuffer <缓存大小></span><br><span class="line"></span><br><span class="line"><span class="comment"># 调用 git status/git diff 命令时以高亮或彩色方式显示改动状态</span></span><br><span class="line">$ git config <span class="params">--global</span> color.ui <span class="literal">true</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 配置可以缓存密码,默认缓存时间15分钟</span></span><br><span class="line">$ git config <span class="params">--global</span> credential.helper cache</span><br><span class="line"></span><br><span class="line"><span class="comment"># 配置密码的缓存时间</span></span><br><span class="line"><span class="comment"># 缓存时间单位:秒</span></span><br><span class="line">$ git config <span class="params">--global</span> credential.helper 'cache <span class="params">--timeout=</span><缓存时间>'</span><br><span class="line"></span><br><span class="line"><span class="comment"># 配置长期存储密码</span></span><br><span class="line">$ git config <span class="params">--global</span> credential.helper store</span><br></pre></td></tr></table></figure><h2 id="git-branch">git branch</h2><blockquote><p>操作 Git 的分支命令。</p></blockquote><figure class="highlight fsharp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"># 列出本地的所有分支,当前所在分支以 <span class="string">"*"</span> 标出</span><br><span class="line">$ git branch</span><br><span class="line"></span><br><span class="line"># 列出本地的所有分支并显示最后一次提交,当前所在分支以 <span class="string">"*"</span> 标出</span><br><span class="line">$ git branch -v</span><br><span class="line"></span><br><span class="line"># 创建新分支,新的分支基于上一次提交建立</span><br><span class="line">$ git branch <分支名></span><br><span class="line"></span><br><span class="line"># 修改分支名称</span><br><span class="line"># 如果不指定原分支名称则为当前所在分支</span><br><span class="line">$ git branch -m <span class="meta">[<原分支名称>]</span> <新的分支名称></span><br><span class="line"># 强制修改分支名称</span><br><span class="line">$ git branch -M <span class="meta">[<原分支名称>]</span> <新的分支名称></span><br><span class="line"></span><br><span class="line"># 删除指定的本地分支</span><br><span class="line">$ git branch -d <分支名称></span><br><span class="line"></span><br><span class="line"># 强制删除指定的本地分支</span><br><span class="line">$ git branch -D <分支名称></span><br></pre></td></tr></table></figure><h2 id="git-checkout">git checkout</h2><blockquote><p>切换分支。</p></blockquote><figure class="highlight dts"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta"># 切换到已存在的指定分支</span></span><br><span class="line">$ git checkout <span class="params"><分支名称></span></span><br><span class="line"></span><br><span class="line"><span class="meta"># 创建并切换到指定的分支,保留所有的提交记录</span></span><br><span class="line"><span class="meta"># 等同于 <span class="string">"git branch"</span> 和 <span class="string">"git checkout"</span> 两个命令合并</span></span><br><span class="line">$ git checkout -b <span class="params"><分支名称></span></span><br><span class="line"></span><br><span class="line"><span class="meta"># 创建并切换到指定的分支,删除所有的提交记录</span></span><br><span class="line">$ git checkout --orphan <span class="params"><分支名称></span></span><br><span class="line"></span><br><span class="line"><span class="meta"># 替换掉本地的改动,新增的文件和已经添加到暂存区的内容不受影响</span></span><br><span class="line">$ git checkout <span class="params"><文件路径></span></span><br></pre></td></tr></table></figure><h2 id="git-fetch">git fetch</h2><blockquote><p>从远程仓库获取最新的版本到本地的 tmp 分支上。</p></blockquote><figure class="highlight dts"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta"># 将远程仓库所有分支的最新版本全部取回到本地</span></span><br><span class="line">$ git fetch <span class="params"><远程仓库的别名></span></span><br><span class="line"></span><br><span class="line"><span class="meta"># 将远程仓库指定分支的最新版本取回到本地</span></span><br><span class="line">$ git fetch <span class="params"><远程主机名></span> <span class="params"><分支名></span></span><br></pre></td></tr></table></figure><h2 id="git-merge">git merge</h2><blockquote><p>用于将两个或两个以上的开发历史加入(合并)一起,会在合并分支处产生新的提交。</p><p>例如分支A合并到B,将A分支的最后一次提交版本合并到B并在B分支提交。</p></blockquote><figure class="highlight livecodeserver"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 把指定的分支合并到当前所在的分支下,并自动进行新的提交</span></span><br><span class="line">$ git <span class="built_in">merge</span> <分支名称></span><br><span class="line"></span><br><span class="line"><span class="comment"># 把指定的分支合并到当前所在的分支下,不进行新的提交</span></span><br><span class="line">$ git <span class="built_in">merge</span> <span class="comment">--no-commit <分支名称></span></span><br></pre></td></tr></table></figure><h2 id="git-rebase">git rebase</h2><blockquote><p>用于将两个或两个以上的开发历史加入(合并)一起,例如分支A合并到B,则在B分支提交的开头处,将A分支的最后一次提交版本合并进来。</p></blockquote><figure class="highlight dts"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta"># 把指定的分支合并到当前所在的分支下</span></span><br><span class="line">$ git rebase <span class="params"><分支名称></span></span><br></pre></td></tr></table></figure><h2 id="git-pull">git pull</h2><blockquote><p>从远程仓库获取最新版本并合并到本地。 首先会执行 <code>git fetch</code>,然后执行 <code>git merge</code>,把获取的分支的 HEAD 合并到当前分支。</p></blockquote><figure class="highlight dts"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta"># 从远程仓库获取最新版本。</span></span><br><span class="line">$ git pull <span class="params"><远程主机名></span> <span class="params"><远程分支名></span>:<span class="params"><本地分支名></span></span><br><span class="line"><span class="meta"># 拉取到当前分支可省略冒号后面内容</span></span><br><span class="line">$ git pull <span class="params"><远程主机名></span> <span class="params"><远程分支名></span></span><br></pre></td></tr></table></figure><h2 id="git-push">git push</h2><blockquote><p>把本地仓库的提交推送到远程仓库。</p></blockquote><figure class="highlight dts"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta"># 把本地仓库的分支推送到远程仓库的指定分支</span></span><br><span class="line">$ git push <span class="params"><远程仓库的别名></span> <span class="params"><本地分支名></span>:<span class="params"><远程分支名></span></span><br><span class="line"></span><br><span class="line"><span class="meta"># 删除指定的远程仓库的分支</span></span><br><span class="line">$ git push <span class="params"><远程仓库的别名></span> :<span class="params"><远程分支名></span></span><br><span class="line">$ git push <span class="params"><远程仓库的别名></span> --delete <span class="params"><远程分支名></span></span><br></pre></td></tr></table></figure><h2 id="git-remote">git remote</h2><blockquote><p>操作远程库</p></blockquote><figure class="highlight dsconfig"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 列出已经存在的远程仓库</span></span><br><span class="line">$ <span class="string">git</span> <span class="string">remote</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string"></span><span class="comment"># 列出远程仓库的详细信息,在别名后面列出URL地址</span></span><br><span class="line">$ <span class="string">git</span> <span class="string">remote</span> -<span class="string">v</span></span><br><span class="line"><span class="string"></span>$ <span class="string">git</span> <span class="string">remote</span> <span class="built_in">--verbose</span></span><br><span class="line"><span class="built_in"></span></span><br><span class="line"><span class="built_in">#</span> 添加远程仓库</span><br><span class="line">$ <span class="string">git</span> <span class="string">remote</span> <span class="string">add</span> <远程仓库的别名> <远程仓库的<span class="string">URL</span>地址></span><br><span class="line"></span><br><span class="line"><span class="comment"># 修改远程仓库的别名</span></span><br><span class="line">$ <span class="string">git</span> <span class="string">remote</span> <span class="string">rename</span> <原远程仓库的别名> <新的别名></span><br><span class="line"></span><br><span class="line"><span class="comment"># 删除指定名称的远程仓库</span></span><br><span class="line">$ <span class="string">git</span> <span class="string">remote</span> <span class="string">remove</span> <远程仓库的别名></span><br><span class="line"></span><br><span class="line"><span class="comment"># 修改远程仓库的 URL 地址</span></span><br><span class="line">$ <span class="string">git</span> <span class="string">remote</span> <span class="built_in">set-url</span> <远程仓库的别名> <新的远程仓库<span class="string">URL</span>地址></span><br></pre></td></tr></table></figure><h2 id="git-status">git status</h2><blockquote><p>用于显示工作目录和暂存区的状态。使用此命令能看到那些修改被暂存到了,哪些文件没有被 Git tracked 到。</p><p>该命令不显示已经提交到历史中的信息;</p><p>查看项目历史信息使用<code>git log</code>。</p></blockquote><figure class="highlight elixir"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 查看本地仓库的状态</span></span><br><span class="line"><span class="variable">$ </span>git status</span><br></pre></td></tr></table></figure><h2 id="git-log">git log</h2><blockquote><p>查看项目历史信息</p></blockquote><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#</span><span class="bash"> 打印所有的提交记录</span></span><br><span class="line"><span class="meta">$</span><span class="bash"> git <span class="built_in">log</span></span></span><br><span class="line"></span><br><span class="line"><span class="meta">#</span><span class="bash"> 打印从第一次提交到指定的提交的记录</span></span><br><span class="line"><span class="meta">$</span><span class="bash"> git <span class="built_in">log</span> <commit ID></span></span><br><span class="line"></span><br><span class="line"><span class="meta">#</span><span class="bash"> 打印指定数量的最新提交的记录</span></span><br><span class="line"><span class="meta">$</span><span class="bash"> git <span class="built_in">log</span> -<指定的数量></span></span><br></pre></td></tr></table></figure><h2 id="git-tag">git tag</h2><blockquote><p>操作标签。</p></blockquote><figure class="highlight pf"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 打印所有的标签</span></span><br><span class="line">$ git <span class="keyword">tag</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 添加轻量标签,指向提交对象的引用,可以指定之前的提交记录</span></span><br><span class="line">$ git <span class="keyword">tag</span> <span class="variable"><标签名称></span> [<span class="variable"><commit ID></span>]</span><br><span class="line"></span><br><span class="line"><span class="comment"># 添加带有描述信息的附注标签,可以指定之前的提交记录</span></span><br><span class="line">$ git <span class="keyword">tag</span> -a <span class="variable"><标签名称></span> -m <span class="variable"><标签描述信息></span> [<span class="variable"><commit ID></span>]</span><br><span class="line"></span><br><span class="line"><span class="comment"># 切换到指定的标签</span></span><br><span class="line">$ git checkout <span class="variable"><标签名称></span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 查看标签的信息</span></span><br><span class="line">$ git show <span class="variable"><标签名称></span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 删除指定的标签</span></span><br><span class="line">$ git <span class="keyword">tag</span> -d <span class="variable"><标签名称></span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 将指定的标签提交到远程仓库</span></span><br><span class="line">$ git push <span class="variable"><远程仓库的别名></span> <span class="variable"><标签名称></span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 将本地所有的标签全部提交到远程仓库</span></span><br><span class="line">$ git push <span class="variable"><远程仓库的别名></span> –tags</span><br></pre></td></tr></table></figure><h2 id="git-mv">git mv</h2><blockquote><p>重命名文件或者文件夹。</p></blockquote><figure class="highlight awk"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 重命名指定的文件或者文件夹</span></span><br><span class="line">$ git mv <源文件<span class="regexp">/文件夹> <目标文件/</span>文件夹></span><br></pre></td></tr></table></figure><h2 id="git-rm">git rm</h2><blockquote><p>删除文件或者文件夹。</p></blockquote><figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 移除跟踪指定的文件,并从本地仓库的文件夹中删除</span></span><br><span class="line"><span class="variable">$</span> git <span class="built_in">rm</span> <文件路径></span><br><span class="line"></span><br><span class="line"><span class="comment"># 移除跟踪指定的文件夹,并从本地仓库的文件夹中删除</span></span><br><span class="line"><span class="variable">$</span> git <span class="built_in">rm</span> <span class="literal">-r</span> <文件夹路径></span><br><span class="line"></span><br><span class="line"><span class="comment"># 移除跟踪指定的文件,在本地仓库的文件夹中保留该文件</span></span><br><span class="line"><span class="variable">$</span> git <span class="built_in">rm</span> -<span class="literal">-cached</span></span><br></pre></td></tr></table></figure><h2 id="git-revert">git revert</h2><blockquote><p>生成一个新的提交来撤销某次提交,此次提交之前的所有提交都会被保留。</p></blockquote><figure class="highlight dts"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta"># 生成一个新的提交来撤销某次提交</span></span><br><span class="line">$ git revert <span class="params"><commit ID></span></span><br></pre></td></tr></table></figure><h2 id="git-reset">git reset</h2><blockquote><p>还原提交记录。</p></blockquote><figure class="highlight fsharp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"># 重置暂存区,但文件不受影响</span><br><span class="line"># 相当于将用 <span class="string">"git add"</span> 命令更新到暂存区的内容撤出暂存区,可以指定文件</span><br><span class="line"># 没有指定 commit ID 则默认为当前 HEAD</span><br><span class="line">$ git reset <span class="meta">[<文件路径>]</span></span><br><span class="line">$ git reset --mixed <span class="meta">[<文件路径>]</span></span><br><span class="line"></span><br><span class="line"># 将 HEAD 的指向改变,撤销到指定的提交记录,文件未修改</span><br><span class="line">$ git reset <commit ID></span><br><span class="line">$ git reset --mixed <commit ID></span><br><span class="line"></span><br><span class="line"># 将 HEAD 的指向改变,撤销到指定的提交记录,文件未修改</span><br><span class="line"># 相当于调用 <span class="string">"git reset --mixed"</span> 命令后又做了一次 <span class="string">"git add"</span></span><br><span class="line">$ git reset --soft <commit ID></span><br><span class="line"></span><br><span class="line"># 将 HEAD 的指向改变,撤销到指定的提交记录,文件也修改了</span><br><span class="line">$ git reset --hard <commit ID></span><br></pre></td></tr></table></figure><h2 id="git-diff">git diff</h2><blockquote><p>用于显示提交和工作树等之间的更改。</p><p>此命令比较的是工作目录中当前文件和暂存区域快照之间的差异,也就是修改之后还没有暂存起来的变化内容。</p></blockquote><figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 比较当前文件和暂存区中文件的差异,显示没有暂存起来的更改</span></span><br><span class="line"><span class="variable">$</span> git <span class="built_in">diff</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 比较暂存区中的文件和上次提交时的差异</span></span><br><span class="line"><span class="variable">$</span> git <span class="built_in">diff</span> -<span class="literal">-cached</span></span><br><span class="line"><span class="variable">$</span> git <span class="built_in">diff</span> -<span class="literal">-staged</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 比较当前文件和上次提交时的差异</span></span><br><span class="line"><span class="variable">$</span> git <span class="built_in">diff</span> HEAD</span><br><span class="line"></span><br><span class="line"><span class="comment"># 查看从指定的版本之后改动的内容</span></span><br><span class="line"><span class="variable">$</span> git <span class="built_in">diff</span> <commit ID></span><br><span class="line"></span><br><span class="line"><span class="comment"># 比较两个分支之间的差异</span></span><br><span class="line"><span class="variable">$</span> git <span class="built_in">diff</span> <分支名称> <分支名称></span><br><span class="line"></span><br><span class="line"><span class="comment"># 查看两个分支分开后各自的改动内容</span></span><br><span class="line"><span class="variable">$</span> git <span class="built_in">diff</span> <分支名称>...<分支名称></span><br></pre></td></tr></table></figure>]]></content>
<summary type="html"><h1>Git常用命令</h1>
<h2 id="git-init">git init</h2>
<blockquote>
<p>初始化项目所在目录,初始化后会在当前目录下出现一个名为 .git 的目录。</p>
</blockquote>
<figure class="high</summary>
<category term="c++" scheme="http://yoursite-url/categories/c/"/>
<category term="c++" scheme="http://yoursite-url/tags/c/"/>
</entry>
<entry>
<title>GDB调试命令</title>
<link href="http://yoursite-url/GDB%E8%B0%83%E8%AF%95%E5%91%BD%E4%BB%A4/GDB%E8%B0%83%E8%AF%95%E5%91%BD%E4%BB%A4/"/>
<id>http://yoursite-url/GDB%E8%B0%83%E8%AF%95%E5%91%BD%E4%BB%A4/GDB%E8%B0%83%E8%AF%95%E5%91%BD%E4%BB%A4/</id>
<published>2022-08-02T03:00:03.000Z</published>
<updated>2022-08-02T03:00:03.000Z</updated>
<content type="html"><![CDATA[<h1>GDB</h1><blockquote><ul><li>要使用GDB调试某个程序,该程序编译时必须加上编译选项 <strong><code>-g</code></strong>,否则该程序是不包含调试信息的;</li><li>GCC编译器支持 <strong><code>-O</code></strong> 和 <strong><code>-g</code></strong> 一起参与编译,<code>-O</code>表示优化,如氧气优化(<code>-O2</code>),臭氧优化(<code>-O3</code>)。</li></ul></blockquote><h2 id="常用命令">常用命令</h2><table><thead><tr><th>命令名称</th><th>命令缩写</th><th>命令说明</th></tr></thead><tbody><tr><td><strong>run</strong></td><td><strong>r</strong></td><td>运行一个待调试的程序</td></tr><tr><td><strong>continue</strong></td><td><strong>c</strong></td><td>让暂停的程序继续运行</td></tr><tr><td><strong>next</strong></td><td><strong>n</strong></td><td>运行到下一行</td></tr><tr><td><strong>step</strong></td><td><strong>s</strong></td><td>单步执行,遇到函数会进入</td></tr><tr><td>until</td><td>u</td><td>运行到指定行停下来</td></tr><tr><td>finish</td><td>fi</td><td>结束当前调用函数,回到上一层调用函数处</td></tr><tr><td>return</td><td>return</td><td>结束当前调用函数并返回指定值,到上一层函数调用处</td></tr><tr><td>jump</td><td>j</td><td>将当前程序执行流跳转到指定行或地址</td></tr><tr><td><strong>print</strong></td><td><strong>p</strong></td><td>打印变量或寄存器值</td></tr><tr><td><strong>backtrace</strong></td><td><strong>bt</strong></td><td>查看当前线程的调用堆栈</td></tr><tr><td>frame</td><td>f</td><td>切换到当前调用线程的指定堆栈</td></tr><tr><td>thread</td><td>thread</td><td>切换到指定线程</td></tr><tr><td><strong>break</strong></td><td><strong>b</strong></td><td>添加断点</td></tr><tr><td>tbreak</td><td>tb</td><td>添加临时断点</td></tr><tr><td><strong>delete</strong></td><td><strong>d</strong></td><td>删除断点</td></tr><tr><td><strong>enable</strong></td><td><strong>enable</strong></td><td>启用某个断点,根据编号</td></tr><tr><td><strong>disable</strong></td><td><strong>disable</strong></td><td>禁用某个断点,根据编号</td></tr><tr><td>watch</td><td>watch</td><td>监视某一个变量或内存地址的值是否发生变化</td></tr><tr><td><strong>list</strong></td><td><strong>l</strong></td><td>显示源码</td></tr><tr><td><strong>info</strong></td><td><strong>i</strong></td><td>查看断点<code>i b</code> / 线程<code> i thread</code>等信息</td></tr><tr><td>ptype</td><td>ptype</td><td>查看变量类型</td></tr><tr><td>disassemble</td><td>dis</td><td>查看汇编代码</td></tr><tr><td>set args</td><td>set args</td><td>设置程序启动命令行参数</td></tr><tr><td>show args</td><td>show args</td><td>查看设置的命令行参数</td></tr></tbody></table><h2 id="调试core文件">调试core文件</h2><ul><li><code>gdb 执行文件 core文件</code>进入调试core文件;</li><li><code>bt</code>查看堆栈信息。</li></ul>]]></content>
<summary type="html"><h1>GDB</h1>
<blockquote>
<ul>
<li>要使用GDB调试某个程序,该程序编译时必须加上编译选项 <strong><code>-g</code></strong>,否则该程序是不包含调试信息的;</li>
<li>GCC编译器支持 <strong><c</summary>
<category term="c++" scheme="http://yoursite-url/categories/c/"/>
<category term="c++" scheme="http://yoursite-url/tags/c/"/>
</entry>
<entry>
<title>SQL语法概述</title>
<link href="http://yoursite-url/SQL%E8%AF%AD%E6%B3%95%E7%AE%80%E4%BB%8B/SQL/"/>
<id>http://yoursite-url/SQL%E8%AF%AD%E6%B3%95%E7%AE%80%E4%BB%8B/SQL/</id>
<published>2022-07-05T04:05:05.000Z</published>
<updated>2022-07-05T04:05:05.000Z</updated>
<content type="html"><![CDATA[<h2 id="SQL概述">SQL概述</h2><h3 id="SQL简介">SQL简介</h3><p>SQL(Structured Query Language):结构化查询语言。</p><p>一种对关系型数据库进行操作的语言,可以应用到所有关系型数据库中,例如:MySQL、ORacle、SQL Server 等。SQL 标准(ANSI/ISO)有:</p><ul><li>SQL-92:1992 年发布的 SQL 语言标准;</li><li>SQL:1999:1999 年发布的 SQL 语言标准;</li><li>SQL:2003:2003 年发布的 SQL 语言标准;</li></ul><p>SQL 可以用在所有关系型数据库中,许多关系型数据库除了实现语言标准外,还都有标准之后的一些语法。例如 MySQL 中的 LIMIT 语句就是 MySQL 独有的,其它数据库都不支持!</p><h3 id="语法要求">语法要求</h3><ul><li>SQL语句可以单行/多行书写,以分号分割语句;</li><li>可以用空格和缩进来增强语句的可读性;</li><li>语句不区分大小写,对于标准的关键字建议大写,自定义的如表名,数据库名等可以小写。</li></ul><h2 id="SQL分类">SQL分类</h2><h3 id="DDL(Data-DefINitiON-Language):">DDL(Data DefINitiON Language):</h3><p>数据定义语言,用来定义数据库对象:库、表、列等;</p><h3 id="DML(Data-ManipulatiON-Language):">DML(Data ManipulatiON Language):</h3><p>数据操作语言,用来定义数据库记录(数据);</p><h3 id="DCL(Data-CONtrol-Language):">DCL(Data CONtrol Language):</h3><p>数据控制语言,用来定义访问权限和安全级别;</p><h3 id="DQL(Data-Query-Language):">DQL(Data Query Language):</h3><p>数据查询语言,用来查询记录(数据)</p><h2 id="DDL(Data-DefINitiON-Lanuage-:-数据定义语言">DDL(Data DefINitiON Lanuage) : 数据定义语言</h2><h3 id="操作数据库">操作数据库</h3><h4 id="基本操作"><strong>基本操作</strong></h4><p><strong>查看所有数据库:</strong><code>SHOW DATABASES;</code><br><strong>切换数据库:</strong><code>USE 数据库名;</code></p><h4 id="创建数据库:">创建数据库:</h4><p><code>CREATE DATABASE [IF NOT EXISTS] 数据库名;</code></p><h4 id="删除数据库:">删除数据库:</h4><p><code>DROP DATABASE [IF EXISTS] 数据库名 [DEFAUlT CHARSET 字符集] [COLLATE 排序规则];</code></p><blockquote><p>如果没有加入<code>IF EXISTS</code>删除不存在的数据库,会报错。</p></blockquote><h4 id="修改数据库:">修改数据库:</h4><p><code>ALTER DATABASE 数据库名 CHARACTER SET utf8; #修改数据库字符集</code></p><blockquote><p>在 MySQL 中所有的 UTF-8 编码都不能使用中间的<code>"-"</code>,即 <strong>UTF-8 要书写为 UTF8</strong>。</p></blockquote><h3 id="操作表">操作表</h3><h4 id="基本操作-2"><strong>基本操作</strong></h4><p><strong>查看所有表:</strong><code>SHOW TABLES;</code><br><strong>切换表:</strong><code>USE 表名;</code><br><strong>查看表结构:</strong><code>DESC 表名;</code><br><strong>查看建表语句:</strong><code>SHOW CREATE TABLE 表名;</code></p><h4 id="数据类型:">数据类型:</h4><p><strong>INT:</strong> 整型;(除了INT之外整型还有TINYINT、SMALLINT、MEDIUMINT)<br><strong>double:</strong> 浮点型,例如 double(5,2)表示最多 5 位,其中必须有 2 位小数,即最大值为 999.99;<br><strong>decimal:</strong> 泛型型,在表单线方面使用该类型,因为不会出现精度缺失问题;<br><strong>char:</strong> 固定长度字符串类型;(当输入的字符不够长度时会补空格)<br><strong>varchar:</strong> 固定长度字符串类型;<br><strong>text:</strong> 字符串类型;<br><strong>blob:</strong> 字节类型;<br><strong>date:</strong> 日期类型,格式为:yyyy-MM-dd;<br><strong>time:</strong> 时间类型,格式为:hh:mm:ss<br><strong>timestamp:</strong> 时间戳类型;</p><h4 id="创建表">创建表</h4><figure class="highlight n1ql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">CREATE</span> TABLE 表名{</span><br><span class="line">字段<span class="number">1</span> 字段<span class="number">1</span>类型[COMMENT 字段<span class="number">1</span>注释],</span><br><span class="line">字段<span class="number">2</span> 字段<span class="number">2</span>类型[COMMENT 字段<span class="number">2</span>注释],</span><br><span class="line">... ...</span><br><span class="line">}[COMMENT 表注释];</span><br><span class="line"></span><br><span class="line">## 例子</span><br><span class="line"><span class="keyword">CREATE</span> TABLE <span class="keyword">user</span> (</span><br><span class="line"><span class="symbol">`id`</span> INt(<span class="number">11</span>) COMMENT <span class="string">'编号'</span>,</span><br><span class="line"><span class="symbol">`name`</span> varchar(<span class="number">50</span>) COMMENT <span class="string">'姓名'</span>,</span><br><span class="line"><span class="symbol">`age`</span> INt(<span class="number">11</span>) COMMENT <span class="string">'年龄'</span>,</span><br><span class="line"><span class="symbol">`gender`</span> varchar(<span class="number">1</span>) COMMENT <span class="string">'性别'</span></span><br><span class="line">) COMMENT=<span class="string">'用户表'</span></span><br><span class="line"></span><br></pre></td></tr></table></figure><h4 id="常见约束">常见约束</h4><p><img src="%E7%BA%A6%E6%9D%9F.jpg" alt="image-20230223213339630"></p><h4 id="删除表">删除表</h4><figure class="highlight pgsql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">DROP</span> <span class="keyword">TABLE</span> [<span class="keyword">IF</span> <span class="keyword">EXISTS</span>] 表名;#删除表</span><br><span class="line"><span class="keyword">TRUNCATE</span> <span class="keyword">TABLE</span> 表名;#删除表,并重新创建该表(清空表中数据)</span><br></pre></td></tr></table></figure><h4 id="修改表">修改表</h4><figure class="highlight pgsql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line">#添加字段</span><br><span class="line"><span class="keyword">ALTER</span> <span class="keyword">TABLE</span> 表名 <span class="keyword">ADD</span> 字段名 类型(长度) [<span class="keyword">COMMENT</span> 注释] [约束];</span><br><span class="line"></span><br><span class="line">#修改数据类型</span><br><span class="line"><span class="keyword">ALTER</span> <span class="keyword">TABLE</span> 表名 MODIFY 字段名 新数据类型(长度);</span><br><span class="line"></span><br><span class="line">#修改字段名和字段类型</span><br><span class="line"><span class="keyword">ALTER</span> <span class="keyword">TABLE</span> 表名 CHANGE 旧字段名 新字段名 类型(长度) [<span class="keyword">COMMENT</span> 注释] [约束];</span><br><span class="line"></span><br><span class="line">#删除字段名</span><br><span class="line"><span class="keyword">ALTER</span> <span class="keyword">TABLE</span> 表名 <span class="keyword">DROP</span> 字段名 </span><br><span class="line"></span><br><span class="line">#修改表名,可以不加<span class="keyword">to</span>也能修改</span><br><span class="line"><span class="keyword">ALTER</span> <span class="keyword">TABLE</span> 表名 <span class="keyword">RENAME</span> [<span class="keyword">TO</span>] 新表名 </span><br></pre></td></tr></table></figure><h4 id="复制表">复制表</h4><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"># 复制表结构及数据</span><br><span class="line"><span class="keyword">CREATE</span> <span class="keyword">TABLE</span> 新表名 <span class="keyword">SELECT</span> <span class="operator">*</span> <span class="keyword">FROM</span> 旧表名; </span><br><span class="line"></span><br><span class="line">#复制表结构到新表,不复制数据(下面两个都行)</span><br><span class="line"><span class="keyword">CREATE</span> <span class="keyword">TABLE</span> 新表名 <span class="keyword">SELECT</span> <span class="operator">*</span> <span class="keyword">FROM</span> 旧表名 <span class="keyword">WHERE</span> <span class="number">1</span> <span class="operator">=</span> <span class="number">2</span>;</span><br><span class="line"><span class="keyword">CREATE</span> <span class="keyword">TABLE</span> 新表名 <span class="keyword">LIKE</span> 旧表名;</span><br></pre></td></tr></table></figure><h2 id="DML-(Data-ManipulatiON-Language)-:-数据操作语言">DML (Data ManipulatiON Language) : 数据操作语言</h2><h3 id="插入数据">插入数据</h3><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line">#给指定字段添加数据</span><br><span class="line"><span class="keyword">INSERT</span> <span class="keyword">INTO</span> 表名(字段名<span class="number">1</span>, 字段名<span class="number">2</span>, ......) <span class="keyword">VALUES</span> (值<span class="number">1</span>, 值<span class="number">2</span>, ......);</span><br><span class="line">## 例子</span><br><span class="line"><span class="keyword">INSERT</span> <span class="keyword">INTO</span> employee</span><br><span class="line">(id, wORkno, name, gender, age, idcard,entrydate)</span><br><span class="line"><span class="keyword">VALUES</span> </span><br><span class="line">(<span class="number">1</span>, <span class="string">'1'</span>, <span class="string">'Itcast'</span>, <span class="string">'男'</span>, <span class="number">10</span>, <span class="string">'123412341234123412'</span>, <span class="string">'2022-09-18'</span>);</span><br><span class="line"></span><br><span class="line">#未指定字段名,则是给全部字段添加数据</span><br><span class="line"><span class="keyword">INSERT</span> <span class="keyword">INTO</span> 表名 <span class="keyword">VALUES</span>(值<span class="number">1</span>,值<span class="number">2</span>,...);</span><br><span class="line">## 例子</span><br><span class="line"><span class="keyword">INSERT</span> <span class="keyword">INTO</span> employee </span><br><span class="line"><span class="keyword">VALUES</span> </span><br><span class="line">(<span class="number">2</span>, <span class="string">'2'</span>, <span class="string">'Itcast'</span>, <span class="string">'男'</span>, <span class="number">10</span>,<span class="string">'123412348234123412'</span>, <span class="string">'2022-09-17'</span>);</span><br><span class="line"></span><br><span class="line">#批量添加数据(下面两种方式都可以)</span><br><span class="line"><span class="keyword">INSERT</span> <span class="keyword">INTO</span> 表名(字段<span class="number">1</span>,字段<span class="number">2</span>,......) </span><br><span class="line"><span class="keyword">VALUES</span>(值<span class="number">1</span>,值<span class="number">2</span>,...),(值<span class="number">1</span>,值<span class="number">2</span>,...),(值<span class="number">1</span>,值<span class="number">2</span>,...);</span><br><span class="line"></span><br><span class="line"><span class="keyword">INSERT</span> <span class="keyword">INTO</span> 表名 </span><br><span class="line"><span class="keyword">VALUES</span>(值<span class="number">1</span>,值<span class="number">2</span>,...),(值<span class="number">1</span>,值<span class="number">2</span>,...),(值<span class="number">1</span>,值<span class="number">2</span>,...);</span><br><span class="line"></span><br><span class="line">#复制旧表的数据到新表</span><br><span class="line"><span class="keyword">INSERT</span> <span class="keyword">INTO</span> 新表名(字段<span class="number">1</span>,字段<span class="number">2</span>,......) </span><br><span class="line"><span class="keyword">SELECT</span> 字段<span class="number">1</span>,字段<span class="number">2</span>,......</span><br><span class="line"><span class="keyword">FROM</span> 旧表名</span><br></pre></td></tr></table></figure><h3 id="修改数据">修改数据</h3><figure class="highlight apache"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 修改记录,如果没有条件,则会修改整张表的记录</span></span><br><span class="line"><span class="attribute">UPDATE</span> 表名 SET 字段<span class="number">1</span>=值<span class="number">1</span>,字段<span class="number">2</span>=值<span class="number">2</span>,...[WHERE 条件];</span><br><span class="line"><span class="comment">## 例子</span></span><br><span class="line"><span class="attribute">UPDATE</span> employee SET name='itheima' WHERE id = <span class="number">1</span>;</span><br><span class="line"><span class="attribute">UPDATE</span> employee SET entrydate = '<span class="number">2008</span>-<span class="number">01</span>-<span class="number">01</span>'; //修改所有数据的日期</span><br></pre></td></tr></table></figure><h3 id="删除数据">删除数据</h3><figure class="highlight n1ql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"># 删除记录,如果没有条件会删除整张表的记录</span><br><span class="line"><span class="keyword">DELETE</span> <span class="keyword">FROM</span> 表名 [<span class="keyword">WHERE</span> 条件]</span><br><span class="line">## 例子</span><br><span class="line"><span class="keyword">DELETE</span> <span class="keyword">FROM</span> employee <span class="keyword">WHERE</span> gender = <span class="string">'女'</span>;</span><br><span class="line"><span class="keyword">DELETE</span> <span class="keyword">FROM</span> employee;#删除该表所有数据</span><br></pre></td></tr></table></figure><h2 id="DCL(Data-CONtrol-Language):数据控制语言">DCL(Data CONtrol Language):数据控制语言</h2><h3 id=""></h3><h3 id="查询用户:">查询用户:</h3><figure class="highlight n1ql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">USE mysql;</span><br><span class="line"><span class="keyword">SELECT</span> * <span class="keyword">FROM</span> <span class="keyword">user</span>;</span><br></pre></td></tr></table></figure><h3 id="创建用户">创建用户</h3><figure class="highlight n1ql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"># 创建用户</span><br><span class="line"><span class="keyword">CREATE</span> <span class="keyword">USER</span> <span class="string">'用户名'</span>@<span class="string">'主机名'</span> IDENTIFIED <span class="keyword">BY</span> <span class="string">'密码'</span>;</span><br><span class="line">## 例子</span><br><span class="line"><span class="keyword">CREATE</span> <span class="keyword">USER</span> <span class="string">'xiaomi'</span>@<span class="string">'localhost'</span> IDENTIFIED <span class="keyword">BY</span> <span class="string">'123456asd...'</span>;</span><br><span class="line"></span><br><span class="line"># 创建任意主机都可以访问的用户 ‘%’代表任意主机</span><br><span class="line"><span class="keyword">CREATE</span> <span class="keyword">USER</span> <span class="string">'heima'</span>@<span class="string">'%'</span> IDENTIFIED <span class="keyword">BY</span> <span class="string">'qiu11.29'</span>;</span><br></pre></td></tr></table></figure><h3 id="修改用户密码(以root身份)">修改用户密码(以root身份)</h3><figure class="highlight pgsql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"># 修改用户密码</span><br><span class="line"><span class="keyword">ALTER</span> <span class="keyword">USER</span> <span class="string">'用户名'</span>@<span class="string">'主机名'</span> IDENTIFIED <span class="keyword">WITH</span> mysql_native_passwORd <span class="keyword">BY</span> <span class="string">'新密码'</span>;</span><br><span class="line">## 例子</span><br><span class="line"><span class="keyword">ALTER</span> <span class="keyword">USER</span> <span class="string">'xiaomi'</span>@<span class="string">'localhost'</span> IDENTIFIED <span class="keyword">WITH</span> mysql_native_passwORd <span class="keyword">by</span><span class="string">'123456Asd1231...'</span>;</span><br></pre></td></tr></table></figure><h3 id="删除用户">删除用户</h3><figure class="highlight dockerfile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 删除用户</span></span><br><span class="line">DROP <span class="keyword">USER</span> <span class="string">'用户名'</span>@<span class="string">'主机名'</span>;</span><br><span class="line"><span class="comment">## 例子</span></span><br><span class="line">DROP <span class="keyword">USER</span> <span class="string">'xiaomi'</span>@<span class="string">'localhost'</span>;</span><br></pre></td></tr></table></figure><h3 id="授权用户">授权用户</h3><h4 id="用户权限">用户权限</h4><p><img src="%E7%94%A8%E6%88%B7%E6%9D%83%E9%99%90.jpg" alt="image-20230223205048498"></p><figure class="highlight pgsql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"># 授予权限</span><br><span class="line"><span class="keyword">GRANT</span> 权限列表 <span class="keyword">ON</span> 数据库名.表名 <span class="keyword">TO</span> <span class="string">'用户名'</span>@<span class="string">'主机名'</span>;</span><br><span class="line"></span><br><span class="line"># 授予用户访问itcast数据库所有表的权限</span><br><span class="line"><span class="keyword">GRANT</span> <span class="keyword">ALL</span> <span class="keyword">ON</span> itcast.* <span class="keyword">TO</span> <span class="string">'xiaomi'</span>@<span class="string">'localhost'</span>; </span><br></pre></td></tr></table></figure><h3 id="撤销授权">撤销授权</h3><figure class="highlight pgsql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"># 撤销权限</span><br><span class="line"><span class="keyword">REVOKE</span> 权限列表 <span class="keyword">ON</span> 数据库名.表名 <span class="keyword">FROM</span> <span class="string">'用户名'</span>@<span class="string">'主机名'</span>;</span><br><span class="line"></span><br><span class="line"># 撤销用户的所有权限</span><br><span class="line"><span class="keyword">REVOKE</span> <span class="keyword">ALL</span> <span class="keyword">ON</span> itcast.* <span class="keyword">FROM</span> <span class="string">'xiaomi'</span>@<span class="string">'localhost'</span>;</span><br></pre></td></tr></table></figure><h3 id="查看用户权限">查看用户权限</h3><figure class="highlight nginx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 查询权限</span></span><br><span class="line"><span class="attribute">SHOW</span> GRANTS FOR <span class="string">'用户名'</span>@<span class="string">'主机名'</span>;</span><br><span class="line"><span class="comment">## 例子</span></span><br><span class="line"><span class="attribute">SHOW</span> GRANTS FOR <span class="string">'xiaomi'</span>@<span class="string">'localhost'</span>;</span><br></pre></td></tr></table></figure><h2 id="DQL(Data-Query-Language):数据查询语言">DQL(Data Query Language):数据查询语言</h2><h3 id="基础查询">基础查询</h3><h4 id="基础格式">基础格式</h4><figure class="highlight n1ql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"># 查询语句格式</span><br><span class="line"><span class="keyword">SELECT</span>字段列表</span><br><span class="line"></span><br><span class="line"><span class="keyword">FROM</span>表名列表</span><br><span class="line"></span><br><span class="line"><span class="keyword">WHERE</span>条件列表</span><br><span class="line"></span><br><span class="line"><span class="keyword">GROUP</span> <span class="keyword">BY</span>分组字段列表</span><br><span class="line"></span><br><span class="line"><span class="keyword">HAVING</span>分组后条件列表</span><br><span class="line"></span><br><span class="line"><span class="keyword">ORDER</span> <span class="keyword">BY</span>排序字段列表</span><br><span class="line"></span><br><span class="line"><span class="keyword">LIMIT</span>分页参数</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"># 基本使用</span><br><span class="line"><span class="keyword">SELECT</span> 字段<span class="number">1</span>,字段<span class="number">2</span>,... <span class="keyword">FROM</span> 表名;</span><br><span class="line">## 例子</span><br><span class="line"><span class="keyword">SELECT</span> * <span class="keyword">FROM</span> employees;</span><br><span class="line"><span class="keyword">SELECT</span> employee_id, last_name, salary <span class="keyword">FROM</span> employees;</span><br><span class="line"></span><br></pre></td></tr></table></figure><blockquote><p><em>1、空值参与运算也为NULL;</em></p><p><em>2、着重号在与关键词重名时候使用</em></p></blockquote><h4 id="执行顺序">执行顺序</h4><figure class="highlight pgsql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">FROM</span> 表名(列表)</span><br><span class="line"><span class="keyword">WHERE</span> 条件(列表)</span><br><span class="line"><span class="keyword">GROUP</span> <span class="keyword">BY</span> 分组字段(列表)</span><br><span class="line"><span class="keyword">HAVING</span> 分组后的条件(列表)</span><br><span class="line"><span class="keyword">SELECT</span> 字段(列表)</span><br><span class="line"><span class="keyword">ORDER</span> <span class="keyword">BY</span> 排序字段(列表)</span><br><span class="line"><span class="keyword">LIMIT</span> 分页参数</span><br><span class="line"></span><br><span class="line"># 列的别名只能在<span class="keyword">ORDER</span> <span class="keyword">BY</span>中使用,不能在<span class="keyword">WHERE</span>中使用,与<span class="keyword">SQL</span>执行原理有关</span><br><span class="line"><span class="keyword">SELECT</span> employee_id, salary, salary * <span class="number">12</span> annual_sal <span class="keyword">FROM</span> employees <span class="keyword">WHERE</span></span><br><span class="line">annual_sal > <span class="number">81600</span>;#错误语法</span><br><span class="line"></span><br><span class="line"># <span class="keyword">WHERE</span> 需要声明在<span class="keyword">FROM</span>后,<span class="keyword">ORDER</span> <span class="keyword">BY</span>前</span><br><span class="line"><span class="keyword">SELECT</span> employee_id, salary # 再执行这句</span><br><span class="line"><span class="keyword">FROM</span> employees <span class="keyword">WHERE</span> department_id <span class="keyword">IN</span> (<span class="number">50</span>, <span class="number">60</span>, <span class="number">70</span>) # 先执行这句</span><br><span class="line"><span class="keyword">ORDER</span> <span class="keyword">BY</span> department_id <span class="keyword">DESC</span>; # 最后执行这句</span><br></pre></td></tr></table></figure><h3 id="条件查询">条件查询</h3><p>条件查询就是在查询时给出 WHERE 子句,在 WHERE 子句中可以使用如下运算符及关键字:</p><ul><li>=、!=、<>、<、<=、>、>=;</li><li>BETWEEN…AND;</li><li>IN(set);</li><li>IS NULL;</li><li>AND;</li><li>OR;</li><li>NOT;</li></ul><figure class="highlight pgsql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br></pre></td><td class="code"><pre><span class="line"># 查询性别为女,并且年龄小于 <span class="number">50</span> 的记录</span><br><span class="line"><span class="keyword">SELECT</span> * <span class="keyword">FROM</span> stu</span><br><span class="line"><span class="keyword">WHERE</span> gender=<span class="string">'female'</span> <span class="keyword">AND</span> age<<span class="number">50</span>;</span><br><span class="line"></span><br><span class="line"># 查询学号为 S_1001,或者姓名为 liSi 的记录</span><br><span class="line"><span class="keyword">SELECT</span> * <span class="keyword">FROM</span> stu</span><br><span class="line"><span class="keyword">WHERE</span> sid =<span class="string">'S_1001'</span> <span class="keyword">OR</span> sname=<span class="string">'liSi'</span>;</span><br><span class="line"></span><br><span class="line"># 查询学号为 S_1001,S_1002,S_1003 的记录</span><br><span class="line"><span class="keyword">SELECT</span> * <span class="keyword">FROM</span> stu</span><br><span class="line"><span class="keyword">WHERE</span> sid <span class="keyword">IN</span> (<span class="string">'S_1001'</span>,<span class="string">'S_1002'</span>,<span class="string">'S_1003'</span>)</span><br><span class="line"></span><br><span class="line"># 查询学号不是 S_1001,S_1002,S_1003 的记录</span><br><span class="line"><span class="keyword">SELECT</span> * <span class="keyword">FROM</span> stu</span><br><span class="line"><span class="keyword">WHERE</span> sid <span class="keyword">NOT</span> <span class="keyword">IN</span> (<span class="string">'S_1001'</span>,<span class="string">'S_1002'</span>,<span class="string">'S_1003'</span>);</span><br><span class="line"></span><br><span class="line"># 查询年龄为 <span class="keyword">NULL</span> 的记录</span><br><span class="line"><span class="keyword">SELECT</span> * <span class="keyword">FROM</span> stu</span><br><span class="line"><span class="keyword">WHERE</span> age <span class="keyword">IS</span> <span class="keyword">NULL</span>;</span><br><span class="line"></span><br><span class="line"># 查询年龄在 <span class="number">20</span> 到 <span class="number">40</span> 之间的学生记录</span><br><span class="line"><span class="keyword">SELECT</span> * <span class="keyword">FROM</span> stu</span><br><span class="line"><span class="keyword">WHERE</span> age>=<span class="number">20</span> <span class="keyword">AND</span> age<=<span class="number">40</span>;</span><br><span class="line"># 或者</span><br><span class="line"><span class="keyword">SELECT</span> * <span class="keyword">FROM</span> stu</span><br><span class="line"><span class="keyword">WHERE</span> age <span class="keyword">BETWEEN</span> <span class="number">20</span> <span class="keyword">AND</span> <span class="number">40</span>;</span><br><span class="line"></span><br><span class="line"># 查询性别非男的学生记录</span><br><span class="line"><span class="keyword">SELECT</span> * <span class="keyword">FROM</span> stu</span><br><span class="line"><span class="keyword">WHERE</span> gender!=<span class="string">'male'</span>;</span><br><span class="line"># 或者</span><br><span class="line"><span class="keyword">SELECT</span> * <span class="keyword">FROM</span> stu</span><br><span class="line"><span class="keyword">WHERE</span> gender<><span class="string">'male'</span>;</span><br><span class="line"># 或者</span><br><span class="line"><span class="keyword">SELECT</span> * <span class="keyword">FROM</span> stu</span><br><span class="line"><span class="keyword">WHERE</span> <span class="keyword">NOT</span> gender=<span class="string">'male'</span>;</span><br><span class="line"></span><br><span class="line"># 查询姓名不为 <span class="keyword">NULL</span> 的学生记录</span><br><span class="line"><span class="keyword">SELECT</span> * <span class="keyword">FROM</span> stu</span><br><span class="line"><span class="keyword">WHERE</span> <span class="keyword">NOT</span> sname <span class="keyword">IS</span> <span class="keyword">NULL</span>;</span><br><span class="line"># 或者</span><br><span class="line"><span class="keyword">SELECT</span> * <span class="keyword">FROM</span> stu</span><br><span class="line"><span class="keyword">WHERE</span> sname <span class="keyword">IS</span> <span class="keyword">NOT</span> <span class="keyword">NULL</span>;</span><br><span class="line"></span><br></pre></td></tr></table></figure><h3 id="模糊查询">模糊查询</h3><h4 id="LIKE匹配">LIKE匹配</h4><figure class="highlight pgsql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"># 模糊查询 <span class="keyword">LIKE</span> 格式</span><br><span class="line"><span class="keyword">SELECT</span> 字段 <span class="keyword">FROM</span> 表 <span class="keyword">WHERE</span> 某字段 <span class="keyword">LIKE</span> 条件</span><br></pre></td></tr></table></figure><p><strong>其中关于LIKE条件,SQL 提供了两种匹配模式:</strong></p><ul><li><p><code>%</code> :表示任意 0 个或多个字符。可匹配任意类型和长度的字符,有些情况下若是中文,请使用两个百分号(%%)表示。</p></li><li><p><code>_</code>: 表示任意单个字符。匹配单个任意字符,它常用来限制表达式的字 符长度语句。</p></li></ul><figure class="highlight n1ql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">## 例子</span><br><span class="line"># 查询姓名由 5 个字母构成的学生记录</span><br><span class="line"><span class="keyword">SELECT</span> * <span class="keyword">FROM</span> stu</span><br><span class="line"><span class="keyword">WHERE</span> sname <span class="keyword">LIKE</span> <span class="string">'_ _ _ _ _'</span>;</span><br><span class="line"></span><br><span class="line"># 查询姓名以“z”开头的学生记录</span><br><span class="line"><span class="keyword">SELECT</span> * <span class="keyword">FROM</span> stu</span><br><span class="line"><span class="keyword">WHERE</span> sname <span class="keyword">LIKE</span> <span class="string">'z%'</span>;</span><br></pre></td></tr></table></figure><h4 id="正则表达式匹配">正则表达式匹配</h4><figure class="highlight vala"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta"># 正则表达式匹配</span></span><br><span class="line"><span class="meta"># ^表示以一些字符开头</span></span><br><span class="line"><span class="meta"># $表示以一些字符结尾</span></span><br><span class="line">SELECT <span class="string">'shkstart'</span> REGEXP <span class="string">'^shk'</span>, <span class="string">'shkstart'</span> REGEXP <span class="string">'t$'</span>, <span class="string">'shkstart'</span> REGEXP <span class="string">'hk'</span> FROM DUAL;</span><br></pre></td></tr></table></figure><h3 id="字段控制查询">字段控制查询</h3><figure class="highlight pgsql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"># 别名(<span class="keyword">AS</span>)使用</span><br><span class="line"># <span class="keyword">AS</span>-><span class="keyword">alias</span>,可以省略</span><br><span class="line"># 列的别名可以使用一对<span class="string">''</span></span><br><span class="line">## 例子</span><br><span class="line"><span class="keyword">SELECT</span> wORkaddress [<span class="keyword">AS</span>] <span class="string">'工作地址'</span> <span class="keyword">FROM</span> emp;</span><br><span class="line"></span><br><span class="line"><span class="keyword">SELECT</span> employee_id [<span class="keyword">AS</span>] emp_id, last_name lname, department_id "dept_id",salary * <span class="number">12</span> annual_sal</span><br><span class="line"><span class="keyword">FROM</span> employees;</span><br><span class="line"></span><br><span class="line"># 去除重复行,使用<span class="keyword">DISTINCT</span></span><br><span class="line">## 例子</span><br><span class="line"><span class="keyword">SELECT</span> <span class="keyword">DISTINCT</span> department_id <span class="keyword">FROM</span> employees</span><br></pre></td></tr></table></figure><h3 id="排序">排序</h3><figure class="highlight oxygene"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"># <span class="keyword">ASC</span> 升序(默认) <span class="keyword">DESC</span> 降序</span><br><span class="line">## 例子</span><br><span class="line"># 按照年龄升序</span><br><span class="line"><span class="keyword">SELECT</span> * <span class="keyword">FROM</span> stu</span><br><span class="line"><span class="keyword">ORDER</span> <span class="keyword">BY</span> age <span class="keyword">ASC</span>;</span><br><span class="line"># 或</span><br><span class="line"><span class="keyword">SELECT</span> * <span class="keyword">FROM</span> stu <span class="keyword">ORDER</span> <span class="keyword">BY</span> age;</span><br><span class="line"></span><br><span class="line"># 按照年龄降序</span><br><span class="line"><span class="keyword">SELECT</span> * <span class="keyword">FROM</span> stu</span><br><span class="line"><span class="keyword">ORDER</span> <span class="keyword">BY</span> age <span class="keyword">DESC</span>;</span><br><span class="line"></span><br><span class="line"># 查询所有雇员,按月薪降序,月薪相同时,按编号升序排序</span><br><span class="line"><span class="keyword">SELECT</span> * <span class="keyword">FROM</span> emp</span><br><span class="line"><span class="keyword">ORDER</span> <span class="keyword">BY</span> sal <span class="keyword">DESC</span> ,empno <span class="keyword">ASC</span>;</span><br></pre></td></tr></table></figure><blockquote><p><em>如果没有使用排序操作,默认情况下查询返回的数据是按照添加数据顺序显示的</em></p></blockquote><h3 id="聚合函数">聚合函数</h3><p>聚合函数是用来做纵向运算的函数:</p><pre><code>COUNT():统计指定列不为 NULL 的记录行数;## 例子# 查询 emp 表中记录数:SELECT COUNT(*) AS cnt FROM emp;MAX():计算指定列的最大值,如果指定列是字符串类型,那么使用字符串排序运算;MIN():计算指定列的最小值,如果指定列是字符串类型,那么使用字符串排序运算;## 例子# 查询最高工资和最低工资:SELECT MAX(sal), MIN(sal) FROM emp;SUM():计算指定列的数值和,如果指定列类型不是数值类型,那么计算结果为 0;## 例子#查询所有雇员月薪和:SELECT SUM(sal) FROM emp;AVG():计算指定列的平均值,如果指定列类型不是数值类型,那么计算结果为 0;## 例子# 统计员工平均薪资 SELECT AVG(sal) FROM emp;</code></pre><h3 id="分组查询">分组查询</h3><figure class="highlight pgsql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"># 语句格式</span><br><span class="line"><span class="keyword">SELECT</span> 字段列表 <span class="keyword">FROM</span> 表名[<span class="keyword">WHERE</span> 条件] <span class="keyword">GROUP</span> <span class="keyword">BY</span> 分组字段名 [<span class="keyword">HAVING</span> 分组后过滤条件];</span><br><span class="line"></span><br><span class="line">## 例子</span><br><span class="line"># 查询每个部门的部门编号以及每个部门工资大于 <span class="number">1500</span> 的人数</span><br><span class="line"><span class="keyword">SELECT</span> deptno ,COUNT(*)</span><br><span class="line"><span class="keyword">FROM</span> emp</span><br><span class="line"><span class="keyword">WHERE</span> sal><span class="number">1500</span>`</span><br><span class="line"><span class="keyword">GROUP</span> <span class="keyword">BY</span> deptno;</span><br><span class="line"></span><br><span class="line"># 查询工资总和大于 <span class="number">9000</span> 的部门编号以及工资和</span><br><span class="line"><span class="keyword">SELECT</span> deptno, SUM(sal)</span><br><span class="line"><span class="keyword">FROM</span> emp</span><br><span class="line"><span class="keyword">GROUP</span> <span class="keyword">BY</span> deptno</span><br><span class="line"><span class="keyword">HAVING</span> SUM(sal) > <span class="number">9000</span>;</span><br><span class="line"></span><br></pre></td></tr></table></figure><blockquote><ol><li>执行时机:where是分组之前过滤,不满足就不参与分组;havINg是分组之后进行过滤。</li><li>判断条件:where不能对聚合函数判断,havINg可以。</li><li>执行顺序 where > 聚合函数 > havINg 分组之后。</li><li>查询的字段为聚合函数和分组字段,查询其他字段无意义</li><li></li></ol></blockquote><h3 id="限定查询">限定查询</h3><figure class="highlight pgsql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"># <span class="keyword">LIMIT</span> 格式,起始索引默认从<span class="number">0</span>开始</span><br><span class="line"><span class="keyword">SELECT</span> 字段列表 <span class="keyword">FROM</span> 表名 <span class="keyword">LIMIT</span> [起始索引,]查询记录数;</span><br></pre></td></tr></table></figure><blockquote><ol><li><em>起始索引从0开始,每一页的起始索引 = (页码 - 1)× 查询记录数。 分</em></li><li><em>页查询是数据库的方言,不同的数据库有不同的实现。<code>LIMIT</code> 可以在Mysql,PGSQL, MariaDB,SQLite等数据库中使用,表示分页。不能使用在SQL Server,DB2,ORacle。</em></li><li><em>如果查询的是第一页数据,起始索引可以省略,简写为limit 10。</em></li></ol></blockquote><h3 id="连接查询">连接查询</h3><h4 id="内连接:">内连接:</h4><blockquote><p>查询的是两个表交集的部分</p></blockquote><ul><li>隐式内连接</li></ul><figure class="highlight n1ql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"># 语法</span><br><span class="line"><span class="keyword">SELECT</span> 字段列表 <span class="keyword">FROM</span> 表<span class="number">1</span>,表<span class="number">2</span> <span class="keyword">WHERE</span> 条件...;</span><br><span class="line"></span><br><span class="line">## 例子</span><br><span class="line"># 查询员工姓名,关联的部门的名称</span><br><span class="line"><span class="keyword">SELECT</span> emp.name, dept.name <span class="keyword">FROM</span> emp, dept <span class="keyword">WHERE</span> emp.dept_id = dept.id;</span><br><span class="line"></span><br><span class="line"># 为表起别名,简化查询语句 先执行FROM</span><br><span class="line"><span class="keyword">SELECT</span> <span class="built_in">e</span>.name, d.name <span class="keyword">FROM</span> emp <span class="built_in">e</span>, dept d <span class="keyword">WHERE</span> <span class="built_in">e</span>.dept_id = d.id;</span><br></pre></td></tr></table></figure><ul><li>显示内连接(带有JOIN等关键字)</li></ul><figure class="highlight n1ql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"># 语法</span><br><span class="line"><span class="keyword">SELECT</span> 字段列表 <span class="keyword">FROM</span> 表<span class="number">1</span> [<span class="keyword">INNER</span>] <span class="keyword">JOIN</span> 表<span class="number">2</span> <span class="keyword">ON</span> 连接条件...;</span><br><span class="line"></span><br><span class="line">## 例子</span><br><span class="line"><span class="keyword">SELECT</span> * <span class="keyword">FROM</span> emp <span class="built_in">e</span> <span class="keyword">INNER</span> <span class="keyword">JOIN</span> dept d <span class="keyword">ON</span> <span class="built_in">e</span>.dept_id = d.id;</span><br><span class="line"><span class="keyword">SELECT</span> * <span class="keyword">FROM</span> emp <span class="built_in">e</span> <span class="keyword">JOIN</span> dept d <span class="keyword">ON</span> <span class="built_in">e</span>.dept_id = d.id;</span><br></pre></td></tr></table></figure><h4 id="外连接:">外连接:</h4><ul><li>左外连接</li></ul><blockquote><p>除了求两表的交集,还包含左表剩余的不能匹配右表的记录</p></blockquote><figure class="highlight n1ql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"># 语法</span><br><span class="line"><span class="keyword">SELECT</span> 字段列表 <span class="keyword">FROM</span> 表<span class="number">1</span> <span class="keyword">LEFT</span> [<span class="keyword">OUTER</span>] <span class="keyword">JOIN</span> 表<span class="number">2</span> <span class="keyword">ON</span> 条件...;</span><br><span class="line"></span><br><span class="line">## 例子</span><br><span class="line"># 查询emp表的所有数据,包含其对应的部门信息, 哪怕员工没有部门也会显示</span><br><span class="line"><span class="keyword">SELECT</span> <span class="built_in">e</span>.*, d.name <span class="keyword">FROM</span> emp <span class="built_in">e</span> <span class="keyword">LEFT</span> <span class="keyword">OUTER</span> <span class="keyword">JOIN</span> dept d <span class="keyword">ON</span> <span class="built_in">e</span>.dept_id = d.id;</span><br><span class="line"># 或</span><br><span class="line"><span class="keyword">SELECT</span> <span class="built_in">e</span>.*, d.name <span class="keyword">FROM</span> emp <span class="built_in">e</span> <span class="keyword">LEFT</span> <span class="keyword">JOIN</span> dept d <span class="keyword">ON</span> <span class="built_in">e</span>.dept_id = d.id;</span><br></pre></td></tr></table></figure><ul><li>右外连接</li></ul><blockquote><p>除了求两表的交集,还包含右表剩余的不能匹配左表的记录</p></blockquote><figure class="highlight n1ql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"># 格式</span><br><span class="line"><span class="keyword">SELECT</span> 字段列表 <span class="keyword">FROM</span> 表<span class="number">1</span> <span class="keyword">RIGHT</span> [<span class="keyword">outer</span>] <span class="keyword">JOIN</span> 表<span class="number">2</span> <span class="keyword">ON</span> 条件...;</span><br><span class="line"></span><br><span class="line">## 例子</span><br><span class="line"># 查询dept表的全部数据,包括对应的员工信息</span><br><span class="line"><span class="keyword">SELECT</span> d.*, <span class="built_in">e</span>.* <span class="keyword">FROM</span> emp <span class="built_in">e</span> <span class="keyword">RIGHT</span> <span class="keyword">JOIN</span> dept d <span class="keyword">ON</span> <span class="built_in">e</span>.dept_id = d.id;</span><br><span class="line"></span><br><span class="line"># 右外可以改成左外,把表的顺序掉个个</span><br><span class="line"><span class="keyword">SELECT</span> d.*, <span class="built_in">e</span>.* <span class="keyword">FROM</span> dept d <span class="keyword">LEFT</span> <span class="keyword">JOIN</span> emp <span class="built_in">e</span> <span class="keyword">ON</span> <span class="built_in">e</span>.dept_id = d.id;</span><br><span class="line"></span><br></pre></td></tr></table></figure><ul><li>自连接</li></ul><blockquote><p>自连接可以是内连接也可以是外连接,只要把一个表起两个别名当两个表用即可</p></blockquote><figure class="highlight n1ql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"># 格式</span><br><span class="line"><span class="keyword">SELECT</span> 字段列表 <span class="keyword">FROM</span> 表A 别名A <span class="keyword">JOIN</span> 表A 别名B <span class="keyword">ON</span> 条件...;</span><br><span class="line"></span><br><span class="line">## 例子</span><br><span class="line"># 查询员工 及其 所属领导 的名字,员工的managerid是其领导的id</span><br><span class="line"><span class="keyword">SELECT</span> a.name, b.name <span class="keyword">FROM</span> emp a, emp b <span class="keyword">WHERE</span> a.managerid = b.id;</span><br><span class="line"># 哪怕没有领导也要显示</span><br><span class="line"><span class="keyword">SELECT</span> a.name <span class="string">'员工'</span>, b.name <span class="string">'领导'</span> <span class="keyword">FROM</span> emp a <span class="keyword">LEFT</span> <span class="keyword">JOIN</span> emp b <span class="keyword">ON</span> a.managerid = b.id;</span><br></pre></td></tr></table></figure><h3 id="联合查询">联合查询</h3><blockquote><p>把多张表查询的结果合并起来,形成一个新的结果集。</p><p>每张表的查询结果字段数必须保持一致。</p></blockquote><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"># 语法</span><br><span class="line"><span class="keyword">SELECT</span> 字段列表 <span class="keyword">FROM</span> 表A...</span><br><span class="line"><span class="keyword">UNION</span> [<span class="keyword">all</span>]</span><br><span class="line"><span class="keyword">SELECT</span> 字段列表 <span class="keyword">FROM</span> 表B...;</span><br><span class="line"></span><br><span class="line">## 例子</span><br><span class="line"># 薪资低于<span class="number">5000</span>和年龄大于<span class="number">50</span>的(可能重复)</span><br><span class="line"><span class="keyword">SELECT</span> <span class="operator">*</span> <span class="keyword">FROM</span> <span class="keyword">WHERE</span> salary <span class="operator"><</span> <span class="number">5000</span>;</span><br><span class="line"><span class="keyword">UNION</span> <span class="keyword">all</span></span><br><span class="line"><span class="keyword">SELECT</span> <span class="operator">*</span> <span class="keyword">FROM</span> <span class="keyword">WHERE</span> age <span class="operator">></span> <span class="number">50</span>;</span><br><span class="line"></span><br><span class="line"># 薪资低于<span class="number">5000</span>和年龄大于<span class="number">50</span>的(合并后会去重,不会重复)</span><br><span class="line"><span class="keyword">SELECT</span> <span class="operator">*</span> <span class="keyword">FROM</span> <span class="keyword">WHERE</span> salary <span class="operator"><</span> <span class="number">5000</span>;</span><br><span class="line"><span class="keyword">UNION</span></span><br><span class="line"><span class="keyword">SELECT</span> <span class="operator">*</span> <span class="keyword">FROM</span> <span class="keyword">WHERE</span> age <span class="operator">></span> <span class="number">50</span>;</span><br></pre></td></tr></table></figure><blockquote><p>UNION 与 UNION ALL的区别在于UNION ALL不会去除结果集中的重复记录,而UNION会去除重复记录。</p></blockquote><h3 id="子查询">子查询</h3><blockquote><p>根据结果划分:</p><ul><li>标量子查询:子查询结果为单值</li><li>行子查询:子查询结果为单行(单记录)</li><li>列子查询:子查询结果为一列</li><li>表子查询:子查询结果为多行多列</li></ul><p>根据位置划分:</p><ul><li>WHERE之后</li><li>FROM之后</li><li>SELECT之后</li></ul><p>根据相关性划分:</p><ul><li><p>相关子查询</p></li><li><p>无关子查询</p></li></ul><p>子查询外部语句可以是INSERT / UPDATE / DELETE / SELECT 的任何一个</p></blockquote><h4 id="结果划分示例">结果划分示例</h4><ul><li><strong>标量子查询</strong></li></ul><figure class="highlight pgsql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"># 查询销售部的所有员工信息</span><br><span class="line"><span class="comment">-- step 1: 查询销售部的部门ID 4</span></span><br><span class="line"><span class="keyword">SELECT</span> id <span class="keyword">FROM</span> dept <span class="keyword">WHERE</span> <span class="type">name</span> = <span class="string">'销售部'</span>;</span><br><span class="line"><span class="comment">-- step 2: 根据ID,查询员工信息</span></span><br><span class="line"><span class="keyword">SELECT</span> * <span class="keyword">FROM</span> emp <span class="keyword">WHERE</span> dept_id = <span class="number">4</span>;</span><br><span class="line"></span><br><span class="line"># 化为子查询</span><br><span class="line"><span class="keyword">SELECT</span> * <span class="keyword">FROM</span> emp <span class="keyword">WHERE</span> dept_id = (<span class="keyword">SELECT</span> id <span class="keyword">FROM</span> dept <span class="keyword">WHERE</span> <span class="type">name</span> = <span class="string">'销售</span></span><br><span class="line"><span class="string">部'</span>);</span><br></pre></td></tr></table></figure><ul><li><strong>列子查询</strong></li></ul><p>常用操作符:</p><p><img src="%E6%93%8D%E4%BD%9C%E7%AC%A6.jpg" alt="image-20230223220117735"></p><figure class="highlight pgsql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"># 查询 "销售部" 和 "市场部" 的所有员工信息</span><br><span class="line"><span class="comment">-- step 1: 查询 "销售部" 和 "市场部" 的部门ID</span></span><br><span class="line"><span class="keyword">SELECT</span> id <span class="keyword">FROM</span> dept <span class="keyword">WHERE</span> <span class="type">name</span> = <span class="string">'销售部'</span> <span class="keyword">OR</span> <span class="type">name</span> = <span class="string">'市场部'</span>;</span><br><span class="line"><span class="comment">-- step 2: 根据部门ID, 查询员工信息</span></span><br><span class="line"><span class="keyword">SELECT</span> * <span class="keyword">FROM</span> emp <span class="keyword">WHERE</span> dept_id <span class="keyword">IN</span> (<span class="number">2</span>, <span class="number">4</span>);</span><br><span class="line"></span><br><span class="line"># 化为子查询</span><br><span class="line"><span class="keyword">SELECT</span> * <span class="keyword">FROM</span> emp <span class="keyword">WHERE</span> dept_id <span class="keyword">IN</span> (<span class="keyword">SELECT</span> id <span class="keyword">FROM</span> dept <span class="keyword">WHERE</span> <span class="type">name</span> = <span class="string">'销售部'</span></span><br><span class="line"><span class="keyword">OR</span> <span class="type">name</span> = <span class="string">'市场部'</span>);</span><br></pre></td></tr></table></figure><ul><li><strong>行子查询</strong></li></ul><blockquote><p>常见操作符:=,<, >, IN, NOT IN;</p></blockquote><figure class="highlight pgsql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"># 查询与‘张无忌’的薪资及领导相同的员工信息</span><br><span class="line"># 化为子查询</span><br><span class="line"><span class="keyword">SELECT</span> * <span class="keyword">FROM</span> emp <span class="keyword">WHERE</span> (salary, managerid) = </span><br><span class="line">(<span class="keyword">SELECT</span> salary, managerid <span class="keyword">FROM</span> emp <span class="keyword">WHERE</span> <span class="type">name</span> = <span class="string">'张无忌'</span>);</span><br></pre></td></tr></table></figure><ul><li>表子查询</li></ul><blockquote><p>常见操作符:IN;</p></blockquote><figure class="highlight pgsql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"># 查询与 "鹿杖客" , "宋远桥" 的职位和薪资相同的员工信息</span><br><span class="line"># 化为子查询</span><br><span class="line"><span class="keyword">SELECT</span> job, salary <span class="keyword">FROM</span> emp <span class="keyword">WHERE</span> <span class="type">name</span> = <span class="string">'鹿杖客'</span> <span class="keyword">OR</span> <span class="type">name</span> = <span class="string">'宋远桥'</span>;</span><br><span class="line"><span class="keyword">SELECT</span> * <span class="keyword">FROM</span> emp <span class="keyword">WHERE</span> (job,salary) <span class="keyword">IN</span> (<span class="keyword">SELECT</span> job, salary <span class="keyword">FROM</span> emp <span class="keyword">WHERE</span></span><br><span class="line"><span class="type">name</span> = <span class="string">'鹿杖客'</span> <span class="keyword">OR</span> <span class="type">name</span> = <span class="string">'宋远桥'</span>);</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html"><h2 id="SQL概述">SQL概述</h2>
<h3 id="SQL简介">SQL简介</h3>
<p>SQL(Structured Query Language):结构化查询语言。</p>
<p>一种对关系型数据库进行操作的语言,可以应用到所有关系型数据库中,例如:MyS</summary>
<category term="数据库" scheme="http://yoursite-url/categories/%E6%95%B0%E6%8D%AE%E5%BA%93/"/>
<category term="数据库" scheme="http://yoursite-url/tags/%E6%95%B0%E6%8D%AE%E5%BA%93/"/>
</entry>
<entry>
<title>c++函数调用压栈过程</title>
<link href="http://yoursite-url/%E5%87%BD%E6%95%B0%E8%B0%83%E7%94%A8%E5%8E%8B%E6%A0%88%E8%BF%87%E7%A8%8B/%E5%87%BD%E6%95%B0%E8%B0%83%E7%94%A8%E5%8E%8B%E6%A0%88%E8%BF%87%E7%A8%8B/"/>
<id>http://yoursite-url/%E5%87%BD%E6%95%B0%E8%B0%83%E7%94%A8%E5%8E%8B%E6%A0%88%E8%BF%87%E7%A8%8B/%E5%87%BD%E6%95%B0%E8%B0%83%E7%94%A8%E5%8E%8B%E6%A0%88%E8%BF%87%E7%A8%8B/</id>
<published>2022-07-02T23:01:03.000Z</published>
<updated>2022-07-02T23:01:03.000Z</updated>
<content type="html"><![CDATA[<h1>c++函数调用压栈过程</h1><blockquote><p>函数调用的过程实际上是一个中断的过程,涉及到函数参数入栈、函数跳转、保存现场、函数执行、恢复现场(函数返回)等。</p></blockquote><p>这里介绍六个下文要用到的寄存器:</p><p><strong>三个重点:</strong></p><ul><li>EIP:指令指针,指向下一条待执行的指令的地址;</li><li>EBP:基址指针,指向栈底;</li><li>ESP:栈顶指针;</li></ul><p><strong>三个次要:</strong></p><ul><li>EBX:基址寄存器;</li><li>ESI:源变址寄存器;</li><li>EDI:目的变址寄存器。</li></ul><p><strong>三个汇编指令:</strong></p><ul><li><p>pop指令:出栈并将该值存入指定寄存器;</p></li><li><p>push指令:将指定寄存器的数据入栈;</p></li><li><p>mov a, b指令:将寄存器b的值赋给a,方向是b->a。</p></li></ul><p><strong>代码例子:</strong></p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><iostream></span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"> </span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">g_func</span><span class="params">(<span class="keyword">int</span> a, <span class="keyword">int</span> b, <span class="keyword">int</span> c)</span> </span>{</span><br><span class="line"> <span class="keyword">int</span> x = <span class="number">0x11111111</span>;</span><br><span class="line"> <span class="keyword">int</span> y = <span class="number">0x22222222</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line"> <span class="built_in">g_func</span>(<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>);</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h3 id="函数参数入栈">函数参数入栈</h3><p>调用函数<code>g_func</code>的时候,会先将参数从右到左压入栈,即<code>c->b->a</code>的顺序入栈,此时栈顶指针ESP指向<code>a</code>。</p><blockquote><p>压入的参数即为函数形参,后续用通用寄存器取值进行计算。</p></blockquote><p>下图是<code>g_func</code>调用的汇编代码:</p><p><img src="%E5%87%BD%E6%95%B0%E8%B0%83%E7%94%A8-1.jpg" alt="image-20230304003657668"><br>$$<br>图1<br>$$</p><p><img src="%E5%87%BD%E6%95%B0%E8%B0%83%E7%94%A8-2.jpg" alt="image-20230304003821798"><br>$$<br>图2<br>$$</p><p><strong>图1</strong>有三条push指令,将<code>3->2->1</code>压入栈,此时<strong>图2</strong>ESP值为<code>0012FEF0</code>(注意栈地址是由内存高地址往低地址扩张的),ESP的值正是<code>a</code>,也就是<code>1</code>的地址。</p><h3 id="函数跳转">函数跳转</h3><p>函数参数压栈之后,将会跳转至<code>g_func</code>函数的执行地址。</p><p><strong>图1</strong>中执行<code>call</code>指令跳转至地址<code>00401005</code>,这个地址在下图:</p><p><img src="%E5%87%BD%E6%95%B0%E8%B0%83%E7%94%A8-3.jpg" alt="image-20230304004519784"><br>$$<br>图3<br>$$<br>而<code>00401005</code>地址处是一条<code>jmp</code>指令,跳转至地址<code>00401030</code>,这个地址正是<code>g_func</code>函数的入口,见下图:</p><p><img src="%E5%87%BD%E6%95%B0%E8%B0%83%E7%94%A8-4.jpg" alt="image-20230304082659817"><br>$$<br>图4<br>$$</p><h3 id="保存现场">保存现场</h3><p>在执行<code>call</code>指令之后,<strong>系统默认往栈中压入了执行<code>call</code>指令之前的EIP</strong>,即隐含执行了一条<code>push</code>指令。</p><p>下图中ESP的值(栈顶)为<code>0x0012FEEC</code>,内存中在该地址的值为<code>0x00401093</code>,这值恰好是<strong>图2</strong>中下一条待执行的<code>add</code>指令的地址,所以这里保存的就是<strong>函数的返回地址</strong>。</p><p>函数调用结束后,弹出该返回地址,然后跳转到该地址继续执行。</p><blockquote><p>这一过程是编译器隐含完成的。</p></blockquote><p><img src="%E5%87%BD%E6%95%B0%E8%B0%83%E7%94%A8-5.jpg" alt="image-20230304083054086"><br>$$<br>图5<br>$$</p><blockquote><p>也有一部分保护现场在下面阐述,因为这些指令位于g_func函数起始地址下方,所以将其放在函数执行中说明。</p></blockquote><h3 id="函数执行">函数执行</h3><p>进入函数体后,开始执行<strong>图5</strong>中的指令。</p><p>1、将EBP压入栈,每个函数都有独立的栈区域,由于函数执行过程也需要用的EBP寄存器,所以需要将此前<code>main</code>的EBP保存在栈中。</p><p>2、<code>mov ebp esp</code>指令将此时的栈顶地址作为函数的栈基址EBP,从而确定了<code>g_func</code>函数的栈区域(EBP为栈底/栈基址,ESP为栈顶)。</p><p>3、<code>sub esp 48h</code>指令将ESP向低地址移动<code>48h</code>字节(<code>72</code>字节),移动的区域包含两个部分:<code>g_func</code>函数的局部变量区域<code>8</code>字节(<code>x</code>4字节 + <code>y</code>4字节)、安全的间隔区域<code>64</code>字节。</p><p>间隔区域为了将不同函数的栈区域隔离开,防止相互影响。</p><p>4、接下来几行指令是将刚才预留出的<code>48h</code>字节的内存区域赋值为<code>0CCCCCCCCh</code>。</p><figure class="highlight basic"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="symbol">00401039 </span>lea edi,[ebp-<span class="number">48</span>h]</span><br><span class="line"><span class="number">0040103</span>C mov ecx,<span class="number">12</span>h</span><br><span class="line"><span class="symbol">00401041 </span>mov eax,<span class="number">0</span>CCCCCCCCh</span><br><span class="line"><span class="symbol">00401046 </span>rep stos dword ptr [edi] </span><br></pre></td></tr></table></figure><p><img src="%E5%87%BD%E6%95%B0%E8%B0%83%E7%94%A8-6.jpg" alt="image-20230304084855508"><br>$$<br>图6<br>$$</p><blockquote><p>上述几个操作也可以归纳为保护现场,真正执行具体函数体内容的在下面。</p></blockquote><p>5、开始执行两条<code>mov</code>指令,用来对变量<code>x</code>和<code>y</code>赋值。由于栈是向低地址扩张的,所以<code>x</code>和<code>y</code>的地址分别为<code>EBP-4</code>和<code>EBP-8</code>,查看内存表可发现相应内存区域已经存入<code>0x11111111</code>和<code>0x22222222</code>。</p><p><img src="%E5%87%BD%E6%95%B0%E8%B0%83%E7%94%A8-7.jpg" alt="image-20230304090226022"></p><p>$$<br>图7<br>$$</p><p><img src="%E5%87%BD%E6%95%B0%E8%B0%83%E7%94%A8-8.jpg" alt="image-20230304090301872"><br>$$<br>图8<br>$$</p><h3 id="恢复现场">恢复现场</h3><p>函数体执行完以后,在返回之前,如下图需要做一些善后的工作。</p><p>1、将EDI、ESI、EBX出栈,即三条<code>pop</code>指令,这样就能恢复调用前的EDI、ESI、EBX的值。<br>2、恢复ESP的值,即<code>mov</code>指令,将EBP的值赋给ESP,这样EBP就跳过了<code>64</code>字节间隔区域和<code>8</code>字节局部数据区域,因为函数已经执行完毕,两个区域无用。<br>3、将EBP出栈,即<code>pop</code>指令,这样就可以恢复调用前的EBP值。</p><p><img src="%E5%87%BD%E6%95%B0%E8%B0%83%E7%94%A8-10.jpg" alt="image-20230304091451068"><br>$$<br>图9<br>$$</p><p>4、执行<code>ret</code>指令之前,隐式将ESP值减小,令其指向存储前EIP值的地址。这样程序就能跳转至中断前的地方,即<strong>恢复断点</strong>。</p><p><img src="%E5%87%BD%E6%95%B0%E8%B0%83%E7%94%A8-9.jpg" alt="image-20230304090637069"><br>$$<br>图10<br>$$</p><p>5、<strong>图10</strong>最后执行函数返回地址中<code>add esp, 0Ch</code>指令,该指令ESP往栈底移动<code>12</code>字节,相当于将原先压入栈的<code>c->b->a</code>弹出栈,因为函数已经执行完,没有用了。这样所有的寄存器值都恢复到了函数调用前的值。</p>]]></content>
<summary type="html"><h1>c++函数调用压栈过程</h1>
<blockquote>
<p>函数调用的过程实际上是一个中断的过程,涉及到函数参数入栈、函数跳转、保存现场、函数执行、恢复现场(函数返回)等。</p>
</blockquote>
<p>这里介绍六个下文要用到的寄存器:</p>
<p><</summary>
<category term="c++" scheme="http://yoursite-url/categories/c/"/>
<category term="c++" scheme="http://yoursite-url/tags/c/"/>
</entry>
<entry>
<title>虚拟内存寻址</title>
<link href="http://yoursite-url/virtual_memory_addressing/%E8%99%9A%E6%8B%9F%E5%86%85%E5%AD%98%E5%AF%BB%E5%9D%80/"/>
<id>http://yoursite-url/virtual_memory_addressing/%E8%99%9A%E6%8B%9F%E5%86%85%E5%AD%98%E5%AF%BB%E5%9D%80/</id>
<published>2022-07-01T02:10:03.000Z</published>
<updated>2022-07-01T02:10:03.000Z</updated>
<content type="html"><![CDATA[<p>在计算机早期阶段时候(比如使用DOS系统甚至更早),内存很小一般以KB为单位。那时候程序并不大,内存可以容纳。工程师对内存直接进行物理寻址,即程序中所用的地址是可以直接送进地址总线进行内存寻址的,地址与内存单元对应。</p><p>后来程序的规模不断增加,程序对内存的需求超过了内存的实际容量,例如4KB的内存,但是程序的大小为8KB。工程师将程序分段,先将需要运行的一段载入内存,等到需要另一段的时候,再将另一段换入。早期采取覆盖的方式,需要工程师手动分割程序。后来,操作系统完成这一任务,将程序分段,并在需要的时候,将内存中的段换出,再将新的段换入内存。后来,这种超过内存实际寻址空间的虚拟地址空间得以广泛使用。<strong>工程师抽象出虚拟内存,每个程序都有其独有的虚拟地址空间。</strong></p><blockquote><p>例子:在一个CPU位数为32位、内存为256MB的机器上,采用按字节寻址,可寻址地址范围为:0x00000000~0xFFFFFFFF(<em><strong>4GB</strong></em>),但其实际内存却只有<em><strong>256MB</strong></em>。因此需要将可寻址的地址(虚拟地址)转换为内存中实际的地址(物理地址),这一任务由<strong>MMU</strong>(内存管理单元)完成,内存管理单元接收虚拟地址,并转换成物理地址,送入地址总线,以待读写内存数据。</p></blockquote><h3 id="物理地址">物理地址</h3><p>CPU地址总线传来的地址,可对内存寻址。物理地址空间中绝大部分是映射到内存条中的内存的,但也常被映射到其他存储器上(如显存、BIOS、设备控制器的端口)。在没有使用虚拟存储器的机器上,虚拟地址被直接送到内存总线上,使具有相同地址的物理存储器被读写;而在使用了虚拟存储器的情况下,虚拟地址不是被直接送到内存地址总线上,而是送到存储器管理单元MMU,把虚拟地址映射为物理地址。</p><h3 id="虚拟地址">虚拟地址</h3><p>操作系统加载可执行文件后,创建了一个进程,这个进程就有了自己的虚拟地址空间,每个进程的虚拟地址空间都一样,如下图所示:</p><p><img src="%E8%BF%9B%E7%A8%8B%E8%99%9A%E6%8B%9F%E5%9C%B0%E5%9D%80%E7%A9%BA%E9%97%B4.png" alt="image-20221204194130578"></p><p>在采用段页机制的系统中,由逻辑地址转换得到的线性地址不是物理地址,而是虚拟地址,需要进一步的查找页表,最终生成物理地址。</p><h3 id="逻辑地址">逻辑地址</h3><p>逻辑是在指有地址变换功能的计算机中,访内指令给出的地址 (操作数) ,也叫相对地址。要经过寻址方式的计算或变换才得到映射内存中的物理地址。</p><p>一个逻辑地址由两部份组成,<strong>段标识符: 段内偏移量</strong>(段内偏移量在采取段页机制的机器中,由<strong>页号:页内偏移量</strong>组成)。段标识符是由一个16位长的字段组成,称为段选择符。其中前13位是个索引号,后面3位包含一些硬件细节 。<br><img src="%E5%AF%BB%E5%9D%801.png" alt="image-20221204192726380"></p><h3 id="线性地址">线性地址</h3><p>线性地址,是逻辑地址到物理地址变换之间的中间层。**在分段部件中逻辑地址包含段中的偏移地址,然后加上基地址就是线性地址(若采用段页机制,则该线性地址为虚拟地址,需进一步转换)。**线性地址通常用十六进制数字表示,程序代码会产生逻辑地址,通过逻辑地址变换就可以生成一个线性地址。如果启用了分页机制(见上图),那么线性地址可以再经过变换以产生一个物理地址。如果没有启用分页机制,那么线性地址直接就是物理地址。<br><img src="%E6%AE%B51.png" alt="image-20221204192410070"></p>]]></content>
<summary type="html"><p> 在计算机早期阶段时候(比如使用DOS系统甚至更早),内存很小一般以KB为单位。那时候程序并不大,内存可以容纳。工程师对内存直接进行物理寻址,即程序中所用的地址是可以直接送进地址总线进行内存寻址的,地址与内存单元对应。</p>
<p> 后来程序的规模不断增加,程序对</summary>
<category term="操作系统" scheme="http://yoursite-url/categories/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/"/>
<category term="操作系统" scheme="http://yoursite-url/tags/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/"/>
</entry>
<entry>
<title>c++位运算-lowbit</title>
<link href="http://yoursite-url/c++%E4%BD%8D%E8%BF%90%E7%AE%97-lowbit/c++%E4%BD%8D%E8%BF%90%E7%AE%97-lowbit/"/>
<id>http://yoursite-url/c++%E4%BD%8D%E8%BF%90%E7%AE%97-lowbit/c++%E4%BD%8D%E8%BF%90%E7%AE%97-lowbit/</id>
<published>2022-06-04T02:01:00.000Z</published>
<updated>2022-06-04T02:01:00.000Z</updated>
<content type="html"><![CDATA[<h3 id="Lowbit运算">Lowbit运算</h3><p><strong>用途:</strong><br>用于取非负整数<code>N</code>最低位的<code>1</code>以及后面所有的<code>0</code>构成的数值。</p><p><strong>例子:</strong></p><p><code>N = 1011000</code>, <code>lowbit(N) = 1000</code>。</p><p><strong>实现方式:</strong></p><p><code>lowbit(N) = N & -N</code></p><p>主要操作是将<code>N</code>取反再加一,然后和<code>N</code>做与位运算。</p><p>在补码中,<code>-N</code> = ~<code>N + 1</code>,故而得到上述方式。</p><h3 id="Attention">Attention</h3><p>1、<code>lowbit</code>可用于求一个数字二进制中所有<code>1</code>的个数,只需要将<code>N</code>的值不断更新为: <code>N - lowbit(N)</code>。</p><p>2、<code>lowbit</code>可用于求一个数字是否是<code>2</code>的幂。</p>]]></content>
<summary type="html"><h3 id="Lowbit运算">Lowbit运算</h3>
<p><strong>用途:</strong><br>
用于取非负整数<code>N</code>最低位的<code>1</code>以及后面所有的<code>0</code>构成的数值。</p>
<p><stron</summary>
<category term="c++" scheme="http://yoursite-url/categories/c/"/>
<category term="c++" scheme="http://yoursite-url/tags/c/"/>
</entry>
<entry>
<title>c++解除流同步与绑定</title>
<link href="http://yoursite-url/c++%E8%A7%A3%E9%99%A4%E6%B5%81%E5%90%8C%E6%AD%A5%E4%B8%8E%E7%BB%91%E5%AE%9A/c++%E8%A7%A3%E9%99%A4%E6%B5%81%E5%90%8C%E6%AD%A5%E4%B8%8E%E7%BB%91%E5%AE%9A/"/>
<id>http://yoursite-url/c++%E8%A7%A3%E9%99%A4%E6%B5%81%E5%90%8C%E6%AD%A5%E4%B8%8E%E7%BB%91%E5%AE%9A/c++%E8%A7%A3%E9%99%A4%E6%B5%81%E5%90%8C%E6%AD%A5%E4%B8%8E%E7%BB%91%E5%AE%9A/</id>
<published>2022-06-03T04:10:43.000Z</published>
<updated>2022-06-03T04:10:43.000Z</updated>
<content type="html"><![CDATA[<h1>c++解除流同步与绑定</h1><h3 id="关闭同步">关闭同步</h3><blockquote><p>If the streams are synchronized, a program can mix iostream operations with stdio operations, and their observable effects are guaranteed to follow the same order as used in the thread.</p></blockquote><p><code>ios::sync_with_stdio = false;(默认true)</code></p><p>默认情况下,c++为了兼容c,将iostream与stdio绑定,为了避免混用printf和cout而造成的输出顺序和代码语句不一致的问题。如果解除同步,输出的结果无法预测,但是可以提升执行效率。建议解除同步后,不要混用iostream与stdio。</p><h3 id="解除cin与cout绑定">解除cin与cout绑定</h3><blockquote><p>cin is tied to the standard output stream cout (see ios::tie), which indicates that cout’s buffer is flushed (see ostream::flush) before each i/o operation performed on cin.</p></blockquote><p><code>cin.tie(NULL)</code>、<code> cout.tie(NULL) ;</code></p><p>默认情况下,cin与cout绑定至同一个标准流,在cin读取数据之前都需要调用<code>flush()</code>函数,将cout流的缓冲刷新至输出文件中。</p><p>解除cin与cout绑定可减少flush次数,提升执行效率。</p>]]></content>
<summary type="html"><h1>c++解除流同步与绑定</h1>
<h3 id="关闭同步">关闭同步</h3>
<blockquote>
<p>If the streams are synchronized, a program can mix iostream operations with std</summary>
<category term="c++" scheme="http://yoursite-url/categories/c/"/>
<category term="c++" scheme="http://yoursite-url/tags/c/"/>
</entry>
<entry>
<title>MARCH:MAze Routing Under a Concurrent and Hierarchical Scheme for Buses</title>
<link href="http://yoursite-url/2019_DAC_Chunk_March/2019_DAC_Chunk_March/"/>
<id>http://yoursite-url/2019_DAC_Chunk_March/2019_DAC_Chunk_March/</id>
<published>2022-05-29T18:10:43.000Z</published>
<updated>2022-05-29T18:10:43.000Z</updated>
<content type="html"><![CDATA[<h1><strong>MARCH</strong>: MAze Routing Under a Concurrent and Hierarchical Scheme for Buses</h1><h2 id="前言:">前言:</h2><p>该篇文献与pcb上的总线布线有关,是基于总线并行与分层方案下的迷宫布线。</p><h2 id="开篇几问:">开篇几问:</h2><h3 id="1-该文主要讲述了什么?">1.该文主要讲述了什么?</h3><h3 id="2-提出了何种解决方案">2.提出了何种解决方案?</h3><h2 id="参考链接:">参考链接:</h2><p><a href="https://dl.acm.org/doi/abs/10.1145/3316781.3317860">MARCH:MAze Routing Under a Concurrent and Hierarchical Scheme for Buses</a></p><h2 id="一-论文简介">一. 论文简介</h2><h3 id="1-作者:陈劲松-刘金伟-陈庚杰-郑丹-伊万杰琳">1. 作者:陈劲松 刘金伟 陈庚杰 郑丹 伊万杰琳</h3><h3 id="2-期刊杂志:">2. 期刊杂志:/</h3><h3 id="3-引用数:4">3. 引用数:4</h3><h3 id="4-论文背景">4. 论文背景</h3><p>现代超大规模集成电路技术的不断发展给片上互连带来了新的挑战。与经典的逐网布线不同,总线布线除了考虑线长、过孔数和其他设计规则外,还要求同一总线中的所有网络(位)共享相似甚至相同的拓扑。</p><h3 id="5-应用场景">5. 应用场景</h3><p>总线布线</p><h2 id="二-创新点和贡献:">二. 创新点和贡献:</h2><p>在该文中,为实现总线布线中的相同拓扑,采用了所有位同时布线的方式。<br>算法思想:粗粒度的拓扑感知路径规划、细粒度的位轨道分配、撕裂重布的方法<br>结果:比2018 IC/CAD的第一名在质量与时间上都更优。</p><h2 id="三-相关领域的概述-related-work">三. 相关领域的概述(related work)</h2><p>布线已经被许多以前的工作很好地研究过,包括全局布线(例如ARCHER [1]、NCTU-GR[2]和NTHURoute [3])和详细布线(例如TritonRoute [4]和 Dr. CU[5] )。然而,由于难以保持拓扑一致性,这些工作的技术很难直接应用于总线布线。如果总线是逐位处理的,则后面的位可能缺少可用于布线的轨道段,尤其是当布线轨道配置不均匀且复杂的。在最坏的情况下,在找到可行的拓扑之前需要进行大量的试错。</p><p>以前有一些工作处理与印刷电路板(PCB)设计上的逃逸布线相关的问题,例如引脚分配保证可布线性[6],层分配以最小化使用的层数[7],以及基于ILP的解决方案[8]来解决整个公交规划问题。然而,对于PCB设计上的典型逃逸布线,尽管总线位通常一起布线,但同一总线的不同位之间不需要具有相同的拓扑结构。</p><p>为了观察拓扑约束,Streak [9]使用一个代表位来生成一组拓扑候选,然后应用ILP来选择一个好的拓扑。总线中的所有其他位都尝试跟随选定的位。但是,由于缺乏布线资源可能无法实现所选拓扑。为了解决这个问题,Streak中有一个后细化阶段,将原始总线划分为多个子总线,不同的子总线将具有不同的拓扑。因此,Streak中的技术对这个问题没有用处,因为总线不能被分成不同拓扑的子总线。除了Streak,以前很少有针对具有拓扑约束的布线总线的工作。</p><h2 id="四-作者的方案">四. 作者的方案</h2><p>MARCH:它同时路由总线中的所有位,而不是逐位处理。这种并发性直接以构造正确的方式捕获拓扑一致性约束以及其他目标(例如线长)和约束(例如间距)。<br>为提高MARCH的效率而设计了一个分层框架,由拓扑感知路径规划(TAP)和比特轨道分配(TAB)组成。TAP是有效的,因为它可以工作<br>得到粗粒度的解空间 。TAB生成细粒度的布线解决方案,但它也通过仅搜索TAB提供的区域来提高效率 。<br>最后提供了一个有效的撕毁和改道方案(RR),以进一步提高布线解决方案的质量。</p><p><img src="process1.png" alt="流程图"></p><h2 id="五-主要的信息流(approach)">五. 主要的信息流(approach)</h2><h3 id="BGG">BGG:</h3><p>基于总线的网格图,根据输入的信息进行初始化,作为后续TAP、TAB、RR的数据结构。<br>边缘容量:边缘上满足总线宽度的可布线轨道数。<br>历史成本:h<em>new</em>=a*N<em>space</em>+b*h<em>old</em></p><h3 id="TAP">TAP:</h3><p>拓扑感知路径规划,目的是生成粗粒度的可布线路径区域。<br>front line:由前排的G cell构成,仅在RR阶段会更新。<br>交换节点:判断层交换安全的节点,由4*4 G cell构成。涉及位顺序交换与翻转位顺序交换。为求得翻转顺序下的最大位数算法步骤大致如下图:</p><p><img src="alg1.png" alt="算法步骤"></p><p>费用成本:线长成本+线段计数成本+间距违规成本</p><h3 id="TAB">TAB:</h3><p>位轨道分配,目的是生成细粒度的轨道分配方案,由四个部分构成:<br>粗轨道选择、轨道段范围估计、精确轨道选择、精确轨道段范围分配</p><h3 id="RR">RR:</h3><p>撕毁和重布线,目的是优化方案,这里包括两个部分:<br>(1)将历史成本添加到BGG的边缘中 (2)无违规路线资源不足,扩大front line</p><h2 id="六-总结:">六. 总结:</h2><p>该文中作者提出了基于总线并行与分配方案的迷宫布线方法,目的是为解决总线各位同时布线的一致拓扑问题,并取得了比2018 IC/CAD第一名更为优秀的质量与速度。<br>其中大致由三部分构成:拓扑路径规划(TAP)、位轨道分配(TAB)、撕裂与重布线(RR),TAP是为取得粗粒度的布线路径空间,TAB则是为取得细粒度的布线方案,RR通过改良front line的大小,来提升布线方案。</p>]]></content>
<summary type="html"><h1><strong>MARCH</strong>: MAze Routing Under a Concurrent and Hierarchical Scheme for Buses</h1>
<h2 id="前言:">前言:</h2>
<p>该篇文献与pcb上的总线布线有关</summary>
<category term="pcb" scheme="http://yoursite-url/categories/pcb/"/>
<category term="pcb route" scheme="http://yoursite-url/tags/pcb-route/"/>
</entry>
<entry>
<title>LeetCode 剑指offer26</title>
<link href="http://yoursite-url/lc_offer_26/lc_offer_26/"/>
<id>http://yoursite-url/lc_offer_26/lc_offer_26/</id>
<published>2022-05-28T18:10:43.000Z</published>
<updated>2022-05-28T18:10:43.000Z</updated>
<content type="html"><![CDATA[<h2 id="LeetCode-剑指offer26">LeetCode 剑指offer26</h2><h3 id="题目">题目</h3><blockquote><p>输入两棵二叉树A和B,判断B是不是A的子结构。(约定空树不是任意一个树的子结构)<br>B是A的子结构, 即 A中有出现和B相同的结构和节点值。</p></blockquote><p>例如:<br>给定的树 A:</p><blockquote><blockquote><p>例如:<br>给定二叉树: [3,9,20,null,null,15,7],<br><img src="q1.png" alt="树结构"><br>给定的树B:<br><img src="q2.png" alt="结果"><br>结果:返回 true,因为 B 与 A 的一个子树拥有相同的结构和节点值。</p></blockquote></blockquote><p>示例:<br><img src="r1.png" alt="special"></p><h3 id="算法思想">算法思想</h3><p>1.先利用先序遍历,遍历A树中的每一个节点。<br>2.访问到节点a时,利用层序遍历判断当前a为根节点的子树是否匹配B树的结构。若匹配返回true,反之false。<br>3.若节点a为根节点的子树无法匹配,则继续搜索a的左右子树是否能够匹配。回到2,直到A中找到匹配树B的子树,或者遍历A中每个节点,无法找到并返回false;</p><h3 id="代码">代码</h3><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Definition for a binary tree node.</span></span><br><span class="line"><span class="comment"> * struct TreeNode {</span></span><br><span class="line"><span class="comment"> * int val;</span></span><br><span class="line"><span class="comment"> * TreeNode *left;</span></span><br><span class="line"><span class="comment"> * TreeNode *right;</span></span><br><span class="line"><span class="comment"> * TreeNode(int x) : val(x), left(NULL), right(NULL) {}</span></span><br><span class="line"><span class="comment"> * };</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> {</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line"> <span class="function"><span class="keyword">bool</span> <span class="title">isSubStructure</span><span class="params">(TreeNode* A, TreeNode* B)</span> </span>{</span><br><span class="line"></span><br><span class="line"> <span class="keyword">return</span> (A!=<span class="literal">nullptr</span> && B!=<span class="literal">nullptr</span>)</span><br><span class="line"> &&(<span class="built_in">isMatchedSubStructure</span>(A,B)</span><br><span class="line"> ||<span class="built_in">isSubStructure</span>(A->left,B)</span><br><span class="line"> ||<span class="built_in">isSubStructure</span>(A->right,B));</span><br><span class="line"> </span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">bool</span> <span class="title">isMatchedSubStructure</span><span class="params">(TreeNode* A, TreeNode* B)</span></span>{</span><br><span class="line"> <span class="keyword">if</span>(A->val!=B->val) <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line"> queue<TreeNode*> qTreeA;</span><br><span class="line"> queue<TreeNode*> qTreeB;</span><br><span class="line"> qTreeA.<span class="built_in">push</span>(A);</span><br><span class="line"> qTreeB.<span class="built_in">push</span>(B);</span><br><span class="line"> <span class="keyword">while</span>(!qTreeB.<span class="built_in">empty</span>()){</span><br><span class="line"> TreeNode* tnodeA = qTreeA.<span class="built_in">front</span>();</span><br><span class="line"> TreeNode* tnodeB = qTreeB.<span class="built_in">front</span>();</span><br><span class="line"> <span class="keyword">if</span>(tnodeA->val!=tnodeB->val) <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line"> <span class="keyword">if</span>(tnodeA->left&& tnodeB->left){</span><br><span class="line"> qTreeA.<span class="built_in">push</span>(tnodeA->left);</span><br><span class="line"> qTreeB.<span class="built_in">push</span>(tnodeB->left);</span><br><span class="line"> </span><br><span class="line"> }<span class="keyword">else</span>{</span><br><span class="line"> <span class="keyword">if</span>(tnodeB->left) <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span>(tnodeA->right && tnodeB->right){</span><br><span class="line"> qTreeA.<span class="built_in">push</span>(tnodeA->right);</span><br><span class="line"> qTreeB.<span class="built_in">push</span>(tnodeB->right);</span><br><span class="line"> }<span class="keyword">else</span>{</span><br><span class="line"> <span class="keyword">if</span>(tnodeB->right) <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line"> }</span><br><span class="line"> qTreeA.<span class="built_in">pop</span>();</span><br><span class="line"> qTreeB.<span class="built_in">pop</span>();</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line"> }</span><br><span class="line">};</span><br></pre></td></tr></table></figure><h3 id="复杂度分析">复杂度分析</h3><p>m为A树大小,n为B树大小。<br>时间复杂度:最坏情况下对A的每个节点只访问一次,访问到根节点相同的需要进行匹配,匹配的复杂度为O(n)。故最坏情况下,时间复杂度为O(mn)。</p><p>空间复杂度:O(m)。</p>]]></content>
<summary type="html"><h2 id="LeetCode-剑指offer26">LeetCode 剑指offer26</h2>
<h3 id="题目">题目</h3>
<blockquote>
<p>输入两棵二叉树A和B,判断B是不是A的子结构。(约定空树不是任意一个树的子结构)<br>
B是A的子结构</summary>
<category term="LeetCode" scheme="http://yoursite-url/categories/LeetCode/"/>
<category term="LeetCode" scheme="http://yoursite-url/tags/LeetCode/"/>
</entry>
<entry>
<title>LeetCode 剑指offer32-1</title>
<link href="http://yoursite-url/lc_offer_32-1/lc_offer_32-1/"/>
<id>http://yoursite-url/lc_offer_32-1/lc_offer_32-1/</id>
<published>2022-05-28T18:10:43.000Z</published>
<updated>2022-05-28T18:10:43.000Z</updated>
<content type="html"><![CDATA[<h2 id="LeetCode-剑指offer32-1">LeetCode 剑指offer32-1</h2><h3 id="题目">题目</h3><blockquote><p>从上到下打印出二叉树的每个节点,同一层的节点按照从左到右的顺序打印。</p><blockquote><p>例如:<br>给定二叉树: [3,9,20,null,null,15,7],<br><img src="question1.png" alt="树结构"><br>返回:<br><img src="question2.png" alt="结果"></p></blockquote></blockquote><h3 id="算法思想">算法思想</h3><p>经典的层序遍历,可使用队列实现。从根节点开始,队首每弹出一个节点,就访问这个节点的值,并将其子节点入队。<br>循环操作,直到队内没有节点,即结束。</p><h3 id="代码">代码</h3><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Definition for a binary tree node.</span></span><br><span class="line"><span class="comment"> * struct TreeNode {</span></span><br><span class="line"><span class="comment"> * int val;</span></span><br><span class="line"><span class="comment"> * TreeNode *left;</span></span><br><span class="line"><span class="comment"> * TreeNode *right;</span></span><br><span class="line"><span class="comment"> * TreeNode(int x) : val(x), left(NULL), right(NULL) {}</span></span><br><span class="line"><span class="comment"> * };</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> {</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line"> <span class="function">vector<<span class="keyword">int</span>> <span class="title">levelOrder</span><span class="params">(TreeNode* root)</span> </span>{</span><br><span class="line"> </span><br><span class="line"> <span class="comment">//变量声明</span></span><br><span class="line"> queue<TreeNode*> qNode;<span class="comment">//node队列,存储当前未遍历的部分节点</span></span><br><span class="line"> vector<<span class="keyword">int</span>> result;<span class="comment">//数组存储结果</span></span><br><span class="line"> <span class="comment">//判空条件</span></span><br><span class="line"> <span class="keyword">if</span>(root == <span class="literal">nullptr</span>) <span class="keyword">return</span> result;</span><br><span class="line"> <span class="comment">//算法步骤</span></span><br><span class="line"> qNode.<span class="built_in">push</span>(root);</span><br><span class="line"> <span class="keyword">while</span>(!qNode.<span class="built_in">empty</span>()){</span><br><span class="line"> TreeNode* curNode = qNode.<span class="built_in">front</span>();</span><br><span class="line"> result.<span class="built_in">push_back</span>(curNode->val);</span><br><span class="line"> <span class="keyword">if</span>(curNode->left) qNode.<span class="built_in">push</span>(curNode->left);</span><br><span class="line"> <span class="keyword">if</span>(curNode->right) qNode.<span class="built_in">push</span>(curNode->right);</span><br><span class="line"> qNode.<span class="built_in">pop</span>();</span><br><span class="line"> }</span><br><span class="line"> <span class="comment">//处理结果</span></span><br><span class="line"> <span class="keyword">return</span> result;</span><br><span class="line"> }</span><br><span class="line">};</span><br></pre></td></tr></table></figure><h3 id="复杂度分析">复杂度分析</h3><p>时间复杂度:对每个节点只访问一次,复杂度为O(n)。</p><p>空间复杂度:最差情况下,即当树为平衡二叉树时,最多有 N/2个树节点同时在 queue 中,使用 O(N) 大小的额外空间。</p>]]></content>
<summary type="html"><h2 id="LeetCode-剑指offer32-1">LeetCode 剑指offer32-1</h2>
<h3 id="题目">题目</h3>
<blockquote>
<p>从上到下打印出二叉树的每个节点,同一层的节点按照从左到右的顺序打印。</p>
<blockquo</summary>
<category term="LeetCode" scheme="http://yoursite-url/categories/LeetCode/"/>
<category term="LeetCode" scheme="http://yoursite-url/tags/LeetCode/"/>
</entry>
<entry>
<title>LeetCode 剑指offer32-3</title>
<link href="http://yoursite-url/lc_offer_32-3/lc_offer_32-3/"/>
<id>http://yoursite-url/lc_offer_32-3/lc_offer_32-3/</id>
<published>2022-05-28T18:10:43.000Z</published>
<updated>2022-05-28T18:10:43.000Z</updated>
<content type="html"><![CDATA[<h2 id="LeetCode-剑指offer32-3">LeetCode 剑指offer32-3</h2><h3 id="题目">题目</h3><blockquote><p>请实现一个函数按照之字形顺序打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右到左的顺序打印,第三行再按照从左到右的顺序打印,其他行以此类推。</p><blockquote><p>例如:<br>给定二叉树: [3,9,20,null,null,15,7],<br><img src="question1.png" alt="树结构"><br>返回:<br><img src="question2.png" alt="结果"></p></blockquote></blockquote><h3 id="算法思想">算法思想</h3><p>层序遍历,采用队列。先输入根节点到队列中,此后每次循环都取出当前队列大小的节点数,并将取出节点的子节点插入队列中。设置参数direction表示当前层的奇偶性,每取一层,根据当前层奇偶性输入到结果数组,循环直至队列为空,输出结果。</p><h3 id="代码">代码</h3><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Definition for a binary tree node.</span></span><br><span class="line"><span class="comment"> * struct TreeNode {</span></span><br><span class="line"><span class="comment"> * int val;</span></span><br><span class="line"><span class="comment"> * TreeNode *left;</span></span><br><span class="line"><span class="comment"> * TreeNode *right;</span></span><br><span class="line"><span class="comment"> * TreeNode(int x) : val(x), left(NULL), right(NULL) {}</span></span><br><span class="line"><span class="comment"> * };</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> {</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line"> vector<vector<<span class="keyword">int</span>>> <span class="built_in">levelOrder</span>(TreeNode* root) {</span><br><span class="line"> <span class="comment">//变量声明</span></span><br><span class="line"> queue<TreeNode*> qNode;</span><br><span class="line"> <span class="keyword">bool</span> direction = <span class="literal">true</span>;</span><br><span class="line"> vector<vector<<span class="keyword">int</span>>> ret;</span><br><span class="line"> <span class="comment">//判空条件</span></span><br><span class="line"> <span class="keyword">if</span>(root == <span class="literal">nullptr</span>) <span class="keyword">return</span> ret;</span><br><span class="line"> <span class="comment">//算法步骤</span></span><br><span class="line"> qNode.<span class="built_in">push</span>(root);</span><br><span class="line"> <span class="keyword">while</span>(!qNode.<span class="built_in">empty</span>()){</span><br><span class="line"> <span class="keyword">int</span> current_layer_size = qNode.<span class="built_in">size</span>();</span><br><span class="line"> vector<<span class="keyword">int</span>> layer_ret;</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i = <span class="number">0</span>;i<current_layer_size;i++){</span><br><span class="line"> TreeNode* node = qNode.<span class="built_in">front</span>();</span><br><span class="line"> <span class="keyword">if</span>(direction) layer_ret.<span class="built_in">push_back</span>(node->val);</span><br><span class="line"> <span class="keyword">else</span> layer_ret.<span class="built_in">emplace</span>(layer_ret.<span class="built_in">begin</span>(),node->val);</span><br><span class="line"> <span class="keyword">if</span>(node->left) qNode.<span class="built_in">push</span>(node->left);</span><br><span class="line"> <span class="keyword">if</span>(node->right) qNode.<span class="built_in">push</span>(node->right);</span><br><span class="line"> qNode.<span class="built_in">pop</span>();</span><br><span class="line"> }</span><br><span class="line"> direction = !direction;</span><br><span class="line"> ret.<span class="built_in">push_back</span>(layer_ret);</span><br><span class="line"> }</span><br><span class="line"> <span class="comment">//处理结果</span></span><br><span class="line"> <span class="keyword">return</span> ret;</span><br><span class="line"> }</span><br><span class="line">};</span><br></pre></td></tr></table></figure><h3 id="复杂度分析">复杂度分析</h3><p>时间复杂度:对每个节点只访问一次,复杂度为O(n)。</p><p>空间复杂度:O(1)。</p>]]></content>
<summary type="html"><h2 id="LeetCode-剑指offer32-3">LeetCode 剑指offer32-3</h2>
<h3 id="题目">题目</h3>
<blockquote>
<p>请实现一个函数按照之字形顺序打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右到左的顺序</summary>
<category term="LeetCode" scheme="http://yoursite-url/categories/LeetCode/"/>
<category term="LeetCode" scheme="http://yoursite-url/tags/LeetCode/"/>
</entry>
<entry>
<title>计算机自顶向下Wireshark实验ARP部分</title>
<link href="http://yoursite-url/ethernet/ethernet/"/>
<id>http://yoursite-url/ethernet/ethernet/</id>
<published>2022-05-08T00:05:00.000Z</published>
<updated>2022-05-08T00:05:00.000Z</updated>
<content type="html"><![CDATA[<h3 id="实验1">实验1</h3><p><img src="lab1.png" alt="image-20221121170604169"></p><p><strong>第一个http get报文</strong></p><blockquote><p><strong>1.What is the 48-bit Ethernet address of your computer?</strong></p></blockquote><p>本机MAC: b4 : 0e : de : 6b : 1a : b1</p><p><img src="lab1-QA-1.png" alt="image-20221121170747646"></p><blockquote><p><strong>2.What is the 48-bit destination address in the Ethernet frame? Is this the Ethernet</strong><br><strong>address of <a href="http://gaia.cs.umass.edu">gaia.cs.umass.edu</a>? (Hint: the answer is no). What device has this as its</strong><br><strong>Ethernet address? [Note: this is an important question, and one that students</strong><br><strong>sometimes get wrong. Re-read pages 468-469 in the text and make sure you</strong><br><strong>understand the answer here.]</strong></p></blockquote><p>见题1上图</p><p>目的MAC: 4c : 77 : 66 : ab : 85 : bc;</p><p>这是路由器MAC地址。</p><blockquote><p><strong>3.Give the hexadecimal value for the two-byte Frame type field. What upper layer</strong><br><strong>protocol does this correspond to?</strong></p></blockquote><p>ipv4 (0x0800)</p><blockquote><p><strong>4.How many bytes from the very start of the Ethernet frame does the ASCII “G” in</strong><br><strong>“GET” appear in the Ethernet frame?</strong></p></blockquote><p>前面的字节数 = ethernet首部14字节+ipv4首部20字节+TCP首部32字节 = 66字节</p><p><img src="lab1-QA-4.png" alt="image-20221121171717711"></p><p><strong>第一个http response报文</strong></p><p><img src="lab1-1.png" alt="image-20221121171811862"></p><blockquote><p><strong>5.What is the value of the Ethernet source address? Is this the address of your</strong><br><strong>computer, or of <a href="http://gaia.cs.umass.edu">gaia.cs.umass.edu</a> (Hint: the answer is no). What device has this</strong><br><strong>as its Ethernet address?</strong></p></blockquote><p>源MAC:4c : 77 : 66 : ab : 85 : bc</p><p>该MAC地址是第一跳路由器的MAC地址</p><p><img src="lab1-QA-5.png" alt="image-20221121172114465"></p><blockquote><p><strong>6.What is the destination address in the Ethernet frame? Is this the Ethernet address</strong><br><strong>of your computer?</strong></p></blockquote><p>见上题图</p><p>目的MAC:b4 : 0e : de : 6b : 1a : b1,是本机MAC地址。</p><blockquote><p><strong>7.Give the hexadecimal value for the two-byte Frame type field. What upper layer</strong><br><strong>protocol does this correspond to?</strong></p></blockquote><p>IPv4(0x0800)</p><blockquote><p><strong>8.How many bytes from the very start of the Ethernet frame does the ASCII “O” in</strong><br><strong>“OK” (i.e., the HTTP response code) appear in the Ethernet frame?</strong></p></blockquote><p>由于http报文太大,被分为多个报文段传送,下图是第一个报文段,携带含有http首部的一些信息,</p><p>O前面字节数 = ethernet首部14字节+ipv4首部20字节+TCP首部32字节 + http报文偏移量13字节 = 79字节</p><p><img src="lab1-QA-8.png" alt="image-20221121172803825"></p><h3 id="实验2">实验2</h3><p><img src="lab2.png" alt="lab2"></p><blockquote><p><strong>9.Write down the contents of your computer’s ARP cache. What is the meaning of</strong><br><strong>each column value?</strong></p></blockquote><p>接口代表不同的网卡;</p><p>ip地址MAC地址类型</p><p>ff-ff-ff-ff-ff-ff 为广播地址</p><p><strong>由于电脑上其他应用一直在发送数据报,导致本机发出的arp数据报经常捕捉不到,故采用官方数据进行分析。</strong></p><p><strong>该实验以官方提供的Wireshark捕获文件为基础分析。</strong></p><p><strong>请访问官网获取文件:[课件地址]( <a href="http://gaia.cs.umass.edu/wireshark-labs/wireshark-">http://gaia.cs.umass.edu/wireshark-labs/wireshark-</a><br>traces.zip)</strong></p><p><img src="lab2-1.png" alt="image-20221121182243732"></p><blockquote><p><strong>10.What are the hexadecimal values for the source and destination addresses in the</strong><br><strong>Ethernet frame containing the ARP request message?</strong></p></blockquote><p>源MAC: 00-d0-59-a9-3d-68</p><p>目的MAC: ff-ff-ff-ff-ff-ff</p><blockquote><p><strong>11.Give the hexadecimal value for the two-byte Ethernet Frame type field. What</strong><br><strong>upper layer protocol does this correspond to?</strong></p></blockquote><p>类型: ARP(0x0806)</p><blockquote><p><strong>12.Download the ARP specification from</strong><br><strong><a href="ftp://ftp.rfc-editor.org/in-notes/std/std37.txt">ftp://ftp.rfc-editor.org/in-notes/std/std37.txt</a>. A readable, detailed discussion of</strong><br><strong>ARP is also at <a href="http://www.erg.abdn.ac.uk/users/gorry/course/inet-pages/arp.html">http://www.erg.abdn.ac.uk/users/gorry/course/inet-pages/arp.html</a>.</strong><br><strong>a) How many bytes from the very beginning of the Ethernet frame does the</strong><br><strong>ARP opcode field begin?</strong><br><strong>b) What is the value of the opcode field within the ARP-payload part of the</strong><br><strong>Ethernet frame in which an ARP request is made?</strong><br><strong>c) Does the ARP message contain the IP address of the sender?</strong><br><strong>d) Where in the ARP request does the “question” appear – the Ethernet</strong><br><strong>address of the machine whose corresponding IP address is being queried?</strong></p></blockquote><p><img src="lab2-QA-12-1.png" alt="image-20221121183935405"></p><p><img src="lab2-QA-12.png" alt="image-20221121183550507"></p><p>a) 20 字节 = ethernet首部14字节+硬件类型2字节+协议类型2字节+硬件地址大小1字节+协议地址大小1字节</p><p>b) opcode val: 1(request)</p><p>c) 包含发送方ip地址</p><p>d) 在target字段。</p><blockquote><p><strong>13.Now find the ARP reply that was sent in response to the ARP request.</strong><br><strong>a) How many bytes from the very beginning of the Ethernet frame does the</strong><br><strong>ARP opcode field begin?</strong><br><strong>b) What is the value of the opcode field within the ARP-payload part of the</strong><br><strong>Ethernet frame in which an ARP response is made?</strong><br><strong>c) Where in the ARP message does the “answer” to the earlier ARP request</strong><br><strong>appear – the IP address of the machine having the Ethernet address whose</strong><br><strong>corresponding IP address is being queried?</strong></p></blockquote><p><img src="lab2-QA-13.png" alt="image-20221121185746473"></p><p>a) 20 字节 = ethernet首部14字节+硬件类型2字节+协议类型2字节+硬件地址大小1字节+协议地址大小1字节</p><p>b) opcode val: 2(reply)</p><p>c) sender的MAC 与IP地址字段</p><blockquote><p><strong>14.What are the hexadecimal values for the source and destination addresses in the</strong><br><strong>Ethernet frame containing the ARP reply message?</strong></p></blockquote><p>源MAC: 00-06-25-da-af-73</p><p>目的MAC: 00-d0-59-a9-68</p><blockquote><p><strong>15.Open the ethernet-ethereal-trace-1 trace file in</strong><br><strong><a href="http://gaia.cs.umass.edu/wireshark-labs/wireshark-traces.zip">http://gaia.cs.umass.edu/wireshark-labs/wireshark-traces.zip</a>. The first and second</strong><br><strong>ARP packets in this trace correspond to an ARP request sent by the computer</strong><br><strong>running Wireshark, and the ARP reply sent to the computer running Wireshark by</strong><br><strong>the computer with the ARP-requested Ethernet address. But there is yet another</strong><br><strong>computer on this network, as indicated by packet 6 – another ARP request. Why</strong><br><strong>is there no ARP reply (sent in response to the ARP request in packet 6) in the</strong><br><strong>packet trace?</strong></p></blockquote><p>arp reply数据报是单播,故本机没有收到。</p>]]></content>
<summary type="html"><h3 id="实验1">实验1</h3>
<p><img src="lab1.png" alt="image-20221121170604169"></p>
<p><strong>第一个http get报文</strong></p>
<blockquote>
<p><stron</summary>
<category term="计算机网络" scheme="http://yoursite-url/categories/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/"/>
<category term="计算机自顶向下Wireshark实验" scheme="http://yoursite-url/tags/%E8%AE%A1%E7%AE%97%E6%9C%BA%E8%87%AA%E9%A1%B6%E5%90%91%E4%B8%8BWireshark%E5%AE%9E%E9%AA%8C/"/>
</entry>
<entry>
<title>计算机自顶向下Wireshark实验ICMP部分</title>
<link href="http://yoursite-url/icmp/icmp/"/>
<id>http://yoursite-url/icmp/icmp/</id>
<published>2022-05-07T00:00:00.000Z</published>
<updated>2022-05-07T00:00:00.000Z</updated>
<content type="html"><![CDATA[<h3 id="实验1-PING">实验1 PING</h3><p><img src="lab1.png" alt="image-20221121004131492"></p><p><img src="lab1-2.png" alt="image-20221121004252897"></p><blockquote><p><strong>1.What is the IP address of your host? What is the IP address of the destination</strong><br><strong>host?</strong></p></blockquote><p>本地ip:192.168.1.103</p><p>目的ip:143.89.12.134</p><blockquote><p><strong>2.Why is it that an ICMP packet does not have source and destination port</strong><br><strong>numbers?</strong></p></blockquote><p>ICMP报文是直接封装进ip数据报的,没有涉及到传输层,所以没有端口。</p><blockquote><p><strong>3.Examine one of the ping request packets sent by your host. What are the ICMP type and code numbers? What other fields does this ICMP packet have? How many bytes are the checksum, sequence number and identifier fields?</strong></p></blockquote><p>ICMP 类型:8</p><p>code number: 0</p><p><img src="lab1-QA-3.png" alt="image-20221121005430367"></p><blockquote><p><strong>4.Examine the corresponding ping reply packet. What are the ICMP type and code numbers? What other fields does this ICMP packet have? How many bytes are the checksum, sequence number and identifier fields?</strong></p></blockquote><p>ICMP 类型:0</p><p>code number:0</p><p>checksum: 0x3wa1 2字节</p><p>Identifier : 2字节</p><blockquote><p>Identifier(BE): 1 2字节</p><p>Identifier(LE): 256 2字节</p></blockquote><p>Sequence number: 2字节</p><blockquote><p>Sequence number(BE): 5818 字节</p><p>Sequence number(LE): 47638 字节</p></blockquote><p><img src="lab1-QA-4.png" alt="image-20221121010152845"></p><h3 id="实验2-Tracert">实验2 Tracert</h3><p><img src="lab2.png" alt="lab2"></p><p><img src="lab2-2.png" alt="image-20221121013650972"></p><blockquote><p><strong>5.What is the IP address of your host? What is the IP address of the target</strong><br><strong>destination host?</strong></p></blockquote><p>本机ip:192.168.1.103</p><p>目标ip:128.93.162.83</p><blockquote><p><strong>6.If ICMP sent UDP packets instead (as in Unix/Linux), would the IP protocol</strong><br><strong>number still be 01 for the probe packets? If not, what would it be?</strong></p></blockquote><p>采用UDP发送的ICMP报文,协议号是17。</p><blockquote><p><strong>7.Examine the ICMP echo packet in your screenshot. Is this different from the ICMP ping query packets in the first half of this lab? If yes, how so?</strong></p></blockquote><p>echo报文包括echo request和echo reply。</p><p>此题本意是指这里的echo报文和先前的ping query是否一样,因为tracert每轮都是使用ping来发送报文的。</p><p>所以发出的echo requet就是先前的ping query,不过序列号可不一样。</p><p>不过注意,echo (ping) reply 类型号为0,</p><p>echo (ping) request类型号为8 。</p><blockquote><p><strong>8.Examine the ICMP error packet in your screenshot. It has more fields than the ICMP echo packet. What is included in those fields?</strong></p></blockquote><p>ICMP error类型号是11,code是0,并包含ICMP请求报文的ip数据报。</p><p>与ICMP echo request报文相比多了echo请求报文的ip数据报字段;</p><p>与ICMP echo reply倒是没有多了什么。</p><blockquote><p><strong>9.Examine the last three ICMP packets received by the source host. How are these packets different from the ICMP error packets? Why are they different?</strong></p></blockquote><p>最后三个ICMP报文是已访问到的主机返回的,不是路由器返回的错误报文,所以是ICMP echo (ping) reply报文。</p><blockquote><p><strong>10.Within the tracert measurements, is there a link whose delay is significantly longer than others? Refer to the screenshot in Figure 4, is there a link whose delay is significantly longer than others? On the basis of the router names, can you guess the location of the two routers on the end of this link?</strong></p></blockquote><p><img src="lab-QA-10-1.png" alt="image-20221121021544255"></p><p>有,第8个路由器显著比其他时延高,该路由器不在本土,本机在中国大陆。</p><p>经查询,该ip位于北美。</p><p><img src="lab-QA-10.png" alt="image-20221121021454272"></p>]]></content>
<summary type="html"><h3 id="实验1-PING">实验1 PING</h3>
<p><img src="lab1.png" alt="image-20221121004131492"></p>
<p><img src="lab1-2.png" alt="image-20221121004252</summary>
<category term="计算机网络" scheme="http://yoursite-url/categories/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/"/>
<category term="计算机自顶向下Wireshark实验" scheme="http://yoursite-url/tags/%E8%AE%A1%E7%AE%97%E6%9C%BA%E8%87%AA%E9%A1%B6%E5%90%91%E4%B8%8BWireshark%E5%AE%9E%E9%AA%8C/"/>
</entry>
<entry>
<title>计算机自顶向下Wireshark实验IP部分</title>
<link href="http://yoursite-url/ip/ip/"/>
<id>http://yoursite-url/ip/ip/</id>
<published>2022-05-06T04:00:01.000Z</published>
<updated>2022-05-06T04:00:01.000Z</updated>
<content type="html"><![CDATA[<p>该实验以官方提供的Wireshark捕获文件为基础分析。</p><p>请访问官网获取文件:[课件地址]( <a href="http://gaia.cs.umass.edu/wireshark-labs/wireshark-">http://gaia.cs.umass.edu/wireshark-labs/wireshark-</a><br>traces.zip)</p><p><img src="lab.png" alt="image-20221120204332069"></p><blockquote><p><strong>1.选择计算器发送的第一个ICMP Echo Request消息,然后在packet details window中展开数据包的Internet协议部分。您的计算机的IP地址是多少?</strong></p></blockquote><p>本地IP:192.168.1.102</p><blockquote><p><strong>2.在ip header中,上层协议字段的值是多少?</strong></p></blockquote><p>协议字段:1</p><p><img src="lab_QA_1.png" alt="image-20221120204701255"></p><blockquote><p><strong>3.IP header有多少bytes ? IP datagram的有效负载中有多少bytes ?说明如何确定payload bytes的数。</strong></p></blockquote><p>IP Header: 20 字节</p><p>Payload:64字节 = 总长度84字节 - 首部20字节</p><p><img src="lab_QA_3.png" alt="QA3"></p><blockquote><p><strong>4.此IP数据报是否已被分段(fragmented)?解释您如何确定数据报是否已被分段(fragmented)。</strong></p></blockquote><p>没有被分段,有哪位MF标志位为0 。</p><blockquote><p><strong>5.在您的计算机发送的这一系列ICMP消息中,IP数据报中的哪些字段一直改变?</strong></p></blockquote><p>TTL字段,从1 慢慢增加;</p><p>首部检验和字段,因为首部有变化;</p><p>Identification字段也有变化。</p><p>ICMP报文的序号和校验码checksum也会变化。</p><blockquote><p><strong>6.哪些字段保持不变?哪个字段必须保持不变﹖哪些字段必须更改?为什么?</strong></p></blockquote><p><em><strong>保持不变:</strong></em></p><p>源和目的ip地址保持不变;</p><p>协议和版本字段,首部长度保持不变;</p><p><strong>必须保持不变:</strong></p><p>源和目的ip地址;</p><p>协议和版本字段;</p><p><em><strong>必须改变:</strong></em></p><p>TTL字段必须更改,否则返回的都是同一个路由器的ICMP报文;</p><p>Identification必须改变;</p><p>首部检验和也随之改变;</p><p>ICMP报文的序号和校验码checksum也会变化。</p><blockquote><p><strong>7.描述你在IP datagram的Identification field中的值所看到的。</strong></p></blockquote><p>Identification随着数据报的发送慢慢增长。</p><blockquote><p><strong>8.Identification字段和TTL字段的值?</strong></p></blockquote><p>Identification:0x9d7c(40316)</p><p>TTL:255</p><p><img src="lab_QA_8.png" alt="image-20221120212411743"></p><blockquote><p><strong>9.对于最近(第一跳)路由器发送到你电脑的所有ICMP TTL超出的回复,这些值是否保持不变? 为什么?</strong></p></blockquote><p>值发生了变化;</p><p>identification由于不同的路由器发送故而不同;</p><p>TTL变化是因为ICMP经由不同数量的路由器发送给主机,每经过1个路由器,值就减1.</p><blockquote><p><strong>10.在将pingplotter 中的数据包大小更改为2000后﹐查找计算机发送的第一个ICMP Echo Request消息。该消息是否已碎片化为多个IP数据报﹖【注意:如果你发现你的数据包没有被分割﹐你应该下载zip文件http://gaia.cs.umass.edu/wireshark-labs/wireshark-traces.zip并提取ip-ethereal-trace-1packet跟踪。如果您的计算机具有以太网接口﹐则数据包大小为2000会导致碎片。】</strong></p></blockquote><p>已碎片化成2个数据报:</p><p><img src="lab_QA_10.png" alt="image-20221120213743265"></p><blockquote><p><strong>11.打印出碎片IP数据报的第一个片段。IP头中的哪些信息表明数据报已碎片化?IP头中的哪些信息表明这是第一个片段还是后一个片段?这个IP数据报有多长?</strong></p></blockquote><p>MF标志位为:1,且偏移量为0,表明后面还有分片;</p><p>MF标志位为0,且偏移量不为0,表明是最后一个分片。</p><p>第一个数据报长度为:1500 = 20+1480</p><p>最后一个数据报长度:548 = 20+528</p><p>下图为最后一个分片。</p><p><img src="lab_QA_11.png" alt="image-20221120214132431"></p><p>两个分片数据报的标识符是一样的,都是0x32f9(13049)</p><p>见上图。</p><blockquote><p><strong>12.打印出碎片IP数据报的第二个片段。IP标头中的哪些信息表明这不是第一个数据报片段?是否还有更多的片段?你是如何知道的?</strong></p></blockquote><p>11题中已答。</p><blockquote><p><strong>13.在第一个和第二个片段中﹐IP标头中哪些字段发生了变化?</strong></p></blockquote><p>数据报长度;</p><p>MF标志;</p><p>偏移量;</p><p>首部检验和;</p><p><strong>Now find the first ICMP Echo Request message that was sent by your computer after you</strong><br><strong>changed the Packet Size in pingplotter to be 3500</strong></p><blockquote><p><strong>14.从原始数据包创建了多少个分片?</strong></p></blockquote><p>3个分片。</p><p><img src="lab_QA_14.png" alt="image-20221120220858507"></p><blockquote><p><strong>15.片段中IP首部中的哪些字段发生了变化?</strong></p></blockquote><p>数据包长度;</p><p>MF标志位;</p><p>偏移量;</p><p>首部检验和;</p>]]></content>
<summary type="html"><p>该实验以官方提供的Wireshark捕获文件为基础分析。</p>
<p>请访问官网获取文件:[课件地址]( <a href="http://gaia.cs.umass.edu/wireshark-labs/wireshark-">http://gaia.cs.umass.e</summary>
<category term="计算机网络" scheme="http://yoursite-url/categories/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/"/>
<category term="计算机自顶向下Wireshark实验" scheme="http://yoursite-url/tags/%E8%AE%A1%E7%AE%97%E6%9C%BA%E8%87%AA%E9%A1%B6%E5%90%91%E4%B8%8BWireshark%E5%AE%9E%E9%AA%8C/"/>
</entry>
<entry>
<title>计算机自顶向下Wireshark实验TCP部分</title>
<link href="http://yoursite-url/tcp/%E8%AE%A1%E7%AE%97%E6%9C%BA%E8%87%AA%E9%A1%B6%E5%90%91%E4%B8%8BWIreshark%E5%AE%9E%E9%AA%8CTCP%E9%83%A8%E5%88%86/"/>
<id>http://yoursite-url/tcp/%E8%AE%A1%E7%AE%97%E6%9C%BA%E8%87%AA%E9%A1%B6%E5%90%91%E4%B8%8BWIreshark%E5%AE%9E%E9%AA%8CTCP%E9%83%A8%E5%88%86/</id>
<published>2022-05-05T03:10:43.000Z</published>
<updated>2022-05-05T03:10:43.000Z</updated>
<content type="html"><![CDATA[<p>该实验以官方提供的Wireshark捕获文件为基础分析。</p><p>请访问官网获取文件:[课件地址]( <a href="http://gaia.cs.umass.edu/wireshark-labs/wireshark-">http://gaia.cs.umass.edu/wireshark-labs/wireshark-</a><br>traces.zip)</p><h3 id="实验1">实验1</h3><p>操作部分</p><h3 id="实验2">实验2</h3><p><img src="lab2.png" alt="实验2"></p><p><strong>1.将文件传输到gaia.cs.umass.edu的客户端计算机使用的ip地址和tcp端口号是什么?</strong></p><p>源ip:192.168.1.102;</p><p>tcp端口号:1161</p><p><strong>2.gaia.cs.umass.edu的ip地址是什么?在那个端口号上发送和接受此链接的tcp却段?</strong></p><p>ip:128.119.245.12;</p><p>在端口号:80</p><p><strong>3.客户端计算机将文件传输到gaia.cs.umass.edu所使用的ip地址和tcp端口号是多少?</strong></p><p>ip:192.168.1.102;</p><p>端口号:1161</p><h3 id="实验3">实验3</h3><p><strong>4.用于在客户端计算机和gaia.cs.umass.edu之间启动TCP链接和TCP SYN区段的序列号是什么?将区段表示为SYN区段的区段有什么功能?</strong></p><p><img src="lab3-1.png" alt="实验3-1"></p><p>序列号:232129012;</p><p>SYN区段表明客户端发起连接,是三次握手中的第一次握手。</p><p><strong><a href="http://5.gaia.cs.umass.edu">5.gaia.cs.umass.edu</a> 发送给客户端计算机以回复SYN的SYNACK区段的序列号是多少?SYNACK区段中的Acknowledgement栏位的值是多少?gaia.cs.umass.edu是如何确定此Acknowledgement的数值的?在将区段标识为SYNACK区段的区段在连线中有什么功能?</strong></p><p>发给客户端计算机以回复SYN的SYNACK序列号:883061785,见题4图;</p><p>flag中看到ack栏位值为:1;</p><p><img src="lab3-2.png" alt="image-20221111161635664"></p><p>SYNACK区段在连线中表示服务器接受客户端发起的TCP连接,并为之设置接手缓存及变量;</p><p>服务器根据客户端发送的SYN区段的序列号确定acknowledgement的值,为客户sequence+1;</p><p>SYNACK区段是TCP三次握手中的第二次握手,表明服务器接受连接。</p><p><strong>6.包含HTTP POST命令的TCP区段的序列号是多少?</strong></p><p><strong>请注意,为了找到POST命令,您需要深入了解Wireshark窗口底部的数据包内容子段,在其DATA栏位中查找带有“POST”的区段。</strong></p><p>序列号:232129013。</p><p><img src="lab3-3.png" alt="image-20221111164014907"></p><p><strong>7.将包含HTTP POST的TCP区段视为TCP连接中的第一个区段。</strong></p><p><strong>在这个TCP连线中前六个TCP区段的序列号是什么(包括包含HTTP POST 的段)?</strong></p><p><strong>每区段发送的时间是什么时候?</strong></p><p><strong>收到的每个区段的ACK是什么时候?鉴于发送每个TCP区段的时间与收到确认的时间之间的差异,六个区段中每个区段的RTT值是多少?</strong></p><p><strong>收到每个ACK后,EstimatedRTT值(参见本节中的第3.5.3节,第242页)是什么?</strong></p><p><strong>假设第一个EstimatedRTT 的值等于第一个区段的测量RTT,然后使用课本第242页的EstimatedRTT公式计算所有后续区段。(译注:中译本的页数可能不同)。</strong></p><p><img src="lab3-4.png" alt="image-20221111165035919"></p><p>(SEQ:序列号SendTime:发出时间LEN:长度)</p><p>以第一个为例计算:</p><p>(1)SEQ:232129013SendTime:0.026477LEN:565</p><p>ACK-SEQ:883061786ACK-Time:0.053937RTT:0.053937-0.026477= 0.0274600</p><p>RTT可通过查看ack包,也可以自己手动计算</p><p><img src="lab3-5.png" alt="image-20221111173241699"></p><p><strong>结果:</strong></p><p><img src="lab3-6.png" alt="image-20221111175801218"></p><p>第一个E-RTT取RTT值,后面TCP段的E-RTT如上计算</p><table><thead><tr><th>No</th><th>SEQ</th><th>SendTime</th><th>ACK-Time</th><th>RTT</th><th>Estimated RTT</th><th>LEN</th></tr></thead><tbody><tr><td>1</td><td>232129013</td><td>0.026477</td><td>0.053937</td><td>0.02746</td><td>0.02764</td><td>565</td></tr><tr><td>2</td><td>232129578</td><td>0.041737</td><td>0.077294</td><td>0.035557</td><td>0.028472125</td><td>1460</td></tr><tr><td>3</td><td>232131038</td><td>0.054026</td><td>0.124085</td><td>0.070059</td><td>0.033670484375</td><td>1460</td></tr><tr><td>4</td><td>232132498</td><td>0.054690</td><td>0.169118</td><td>0.114428</td><td>0.043765173828125</td><td>1460</td></tr><tr><td>5</td><td>232133958</td><td>0.077405</td><td>0.217299</td><td>0.139894</td><td>0.05578127709960937</td><td>1460</td></tr><tr><td>6</td><td>232135418</td><td>0.078157</td><td>0.267802</td><td>0.189645</td><td>0.07251424246215821</td><td>1460</td></tr></tbody></table><p><strong>8.前六个TCP区段的长度是多少</strong></p><p>上题回答给出</p><p><strong>9.对于整个跟踪包,收到的最小可用缓冲区空间量是多少?缺少接收器缓冲区空间是否会限制发送方传送TCP区段?</strong></p><p>接收窗口最小为5840,缺少接收器缓冲会限制发送方传送TCP区段,发送方的发送收拥塞控制中的拥塞窗口以及接收方的缓冲接收窗口的影响;但包中实际的接收窗口远大于发送的报文数量,故而不会影响。</p><p><img src="lab3-8.png" alt="image-20221111181011840"></p><p><strong>10.在跟踪文件中是否有重传的区段?为了回答这个问题,您检查了什么(在跟踪包中)?</strong></p><p>使用ip.src==192.168.1.102查看客户端发出的所有保温,发现序号一直在增加,因此没有重传报文。</p><p><img src="lab3-7.png" alt="image-20221111180804291"></p><p><img src="lab3-9.png" alt="image-20221111181508135"></p><p><strong>11.接收器通常在ACK中确认多少数据?您是否可以识别接收方每隔一个接收到的区段才发送确认的情况?</strong></p><p>经对比接收方ACK与发送方的SEQ,接收方接收一个报文即发送一个ACK,没有累计确认。</p><p><img src="lab3-10.png" alt="image-20221111181814665"></p><p><strong>12.TCP连接的吞吐量(每单位时间传输的字节数)是多少?解释你如何计算这个值。</strong></p><p>![image-20221111182317428](tcp_imgs\</p><p>吞吐量=实际收到的字节数 = 传输数据大小/所用时间</p><p>看Wireshark抓包的http-post发送时间与第一个TCP发送时间可得所用时间,然后将所有TCP包大小统计,可得吞吐量。</p><p><img src="lab3-12.png" alt="image-20221111183017348"></p><p>数据大小 = 164090Bite</p><p>第一个包发送时间:0.026477</p><p>HTTP-POST时间:5.297341</p><p>吞吐量 = 164090B/(5.297341 - 0.026477) 约等于31.13151847590831KB/s</p><p>13.使用时序图(Stevens)绘图工具查看从客户端发送到服务器的区段的序列号与时间关系图。您能确定TCP慢启动阶段的开始和结束位置,以及拥塞避免开始的位置?评论测量数据与我们在文本中研究的TCP的理想化行为的不同之处。</p><p><img src="lab3-13.png" alt="image-20221111185558033"></p><p>感觉0-0.1秒区间是慢启动,0.1后是拥塞避免开始的位置,但是拥塞避免的窗口没有增大。</p><p>我们在文本中研究的TCP的理想化行为中拥塞避免的窗口是有增大的</p>]]></content>
<summary type="html"><p>该实验以官方提供的Wireshark捕获文件为基础分析。</p>
<p>请访问官网获取文件:[课件地址]( <a href="http://gaia.cs.umass.edu/wireshark-labs/wireshark-">http://gaia.cs.umass.e</summary>
<category term="计算机网络" scheme="http://yoursite-url/categories/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/"/>
<category term="计算机自顶向下Wireshark实验" scheme="http://yoursite-url/tags/%E8%AE%A1%E7%AE%97%E6%9C%BA%E8%87%AA%E9%A1%B6%E5%90%91%E4%B8%8BWireshark%E5%AE%9E%E9%AA%8C/"/>
</entry>
<entry>
<title>计算机自顶向下Wireshark实验UDP部分</title>
<link href="http://yoursite-url/udp/%E8%AE%A1%E7%AE%97%E6%9C%BA%E8%87%AA%E9%A1%B6%E5%90%91%E4%B8%8BWIreshark%E5%AE%9E%E9%AA%8CUDP%E9%83%A8%E5%88%86/"/>
<id>http://yoursite-url/udp/%E8%AE%A1%E7%AE%97%E6%9C%BA%E8%87%AA%E9%A1%B6%E5%90%91%E4%B8%8BWIreshark%E5%AE%9E%E9%AA%8CUDP%E9%83%A8%E5%88%86/</id>
<published>2022-05-05T03:10:43.000Z</published>
<updated>2022-05-05T03:10:43.000Z</updated>
<content type="html"><![CDATA[<h3 id="实验">实验</h3><p><img src="lab.png" alt="image-20221111193308530"></p><p><strong>1.从跟踪中选择一个UDP数据包。从此数据包中,确定UDP头部中有多少字段。(建议不要查看课本,直接根据您的数据包跟踪结果回答),并为这些字段命名。</strong></p><p>选择第一个DNS的报文,在传输层采用UDP协议。</p><p>UDP头部有4个字段:</p><p>源端口、目的端口、UDP长度、检验和</p><p><strong>2.通过查询Wircshark的数据包内容字段中显示的信息,确定每个UDP报头字段的长度(以字节为单位)。</strong></p><p>每个字段的长度为2B,共4个字段,故首部长度为8B。</p><p><strong>3.长度字段中的值是指的是什么?(此问题您可以参考课本)。使用捕获的UDP数据包验证您的声明。</strong></p><p>指的是用户数据报的长度,即首部加上数据部分。</p><p>取第一个UDP段:</p><p><img src="lab-1.png" alt="image-20221111193950006"></p><p>UDP长度为51B = 8B首部+43B数据部分</p><p><strong>4.UDP有效负载中可包含的最大字节数是多少?(提示:这个问题的答案可以通过你对上述2的回答来确定)</strong></p><p>最大字节数为:最大长度-首部长度 = 2^16-1B-8B = 65535B - 8B = 65527B</p><p><strong>5.最大可能的源端口号是多少?(提示:见4中的提示)</strong></p><p>最大源端口后为:2^16-1 = 65535</p><p><strong>6.UDP的协议号是什么?以十六进制和十进制表示法给出答案。要回答这个问题,您需要查看包含此UDP段的IP数据包的Protocol字段。(参见书中的图4.13和IP头字段的讨论)</strong></p><p>UDP的协议号:17,16进制为0x11.</p><p><img src="lab-2.png" alt="image-20221111194843642"></p><p><strong>7.观察发送UDP数据包后接收响应的UDP数据包,这是对发送的UDP数据包的回复,请描述两个数据包中端口号之间的关系。(提示:对于响应UDP目的地应该为发送UDP包的地址)</strong></p><p>发送UDP目的端口号=响应UDP源端口号</p><p>响应UDP目的端口好 = 发送UDP源端口号</p>]]></content>
<summary type="html"><h3 id="实验">实验</h3>
<p><img src="lab.png" alt="image-20221111193308530"></p>
<p><strong>1.从跟踪中选择一个UDP数据包。从此数据包中,确定UDP头部中有多少字段。(建议不要查看课本,直接根据</summary>
<category term="计算机网络" scheme="http://yoursite-url/categories/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/"/>
<category term="计算机自顶向下Wireshark实验" scheme="http://yoursite-url/tags/%E8%AE%A1%E7%AE%97%E6%9C%BA%E8%87%AA%E9%A1%B6%E5%90%91%E4%B8%8BWireshark%E5%AE%9E%E9%AA%8C/"/>
</entry>
<entry>
<title>VSCode-Installation</title>
<link href="http://yoursite-url/VSCode/VSCode-Installation/"/>
<id>http://yoursite-url/VSCode/VSCode-Installation/</id>
<published>2022-03-04T17:10:43.000Z</published>
<updated>2022-03-04T17:10:43.000Z</updated>
<content type="html"><![CDATA[<blockquote><p>VS Code(全称:Visual Studio Code)是一款由微软开发且跨平台的免费源代码编辑器。<br>该软件支持语法高亮、代码自动补全(又称 IntelliSense)、代码重构、查看定义功能,并且内置了命令行工具和 Git 版本控制系统。</p></blockquote><h2 id="下载">下载</h2><p>VScode 官网地址:<a href="https://code.visualstudio.com/">https://code.visualstudio.com/</a></p><p>VScode 官方文档地址:<a href="https://code.visualstudio.com/docs">https://code.visualstudio.com/docs</a></p><p>找到自己的系统,并安装相应版本</p><p><img src="1-VCSWeb.png" alt="VSCode-Installation"></p><p><img src="2-VSCDownload.png" alt="VSCode-Installation"></p><h2 id="安装">安装</h2><blockquote><p>zip压缩包直接解压可以使用,本次安装是演示exe安装</p></blockquote><h3 id="1-开始同意协议,默认next">1.开始同意协议,默认next</h3><p><img src="3-AcceptRules.png" alt="VSCode-Installation"></p><h3 id="2-选择安装目录,并next">2.选择安装目录,并next</h3><p><img src="4-chooseMenu.png" alt="VSCode-Installation"></p><p><img src="5-next.png" alt="VSCode-Installation"></p><h3 id="3-注意安装路径设置、环境变量默认自动添加到系统中">3.注意安装路径设置、环境变量默认自动添加到系统中</h3><p><img src="6-SelectAT.png" alt="VSCode-Installation"></p><h3 id="4-点击install安装完成并finish">4.点击install安装完成并finish</h3><p><img src="7-install.png" alt="VSCode-Installation"></p><p><img src="8-finish.png" alt="VSCode-Installation"></p><h2 id="界面介绍">界面介绍</h2><p><img src="10-someFunction.png" alt="VSCode-Installation"></p><h2 id="安装中文">安装中文</h2><p>首次打开VS Code可以在左下角安装中文包</p><p><img src="9-chineseInstall.png" alt="VSCode-Installation"></p><p>也可以在扩展中搜索中文安装包</p><p><img src="10-chineseInstall2.png" alt="VSCode-Installation"></p>]]></content>
<summary type="html"><blockquote>
<p>VS Code(全称:Visual Studio Code)是一款由微软开发且跨平台的免费源代码编辑器。<br>
该软件支持语法高亮、代码自动补全(又称 IntelliSense)、代码重构、查看定义功能,并且内置了命令行工具和 Git 版本控制系</summary>
<category term="VSCode" scheme="http://yoursite-url/categories/VSCode/"/>
<category term="VSCode" scheme="http://yoursite-url/tags/VSCode/"/>
</entry>
</feed>