-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsearch.xml
More file actions
747 lines (359 loc) · 493 KB
/
search.xml
File metadata and controls
747 lines (359 loc) · 493 KB
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
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
<?xml version="1.0" encoding="utf-8"?>
<search>
<entry>
<title>JAVA简易日志工具类</title>
<link href="/7ac.html"/>
<url>/7ac.html</url>
<content type="html"><![CDATA[<h1>JAVA日志输出到文件</h1><div class="note primary no-icon flat"><p>PS :</p><ul><li>你是否遇到过控制台打印了一堆日志,想找到自己想看的日志,翻了半天发现被顶没了😒</li><li>尤其是在多线程环境下,有时候正常使用log日志框架打印的日志还可能被吞掉</li></ul><div class="img-wrap"><div class="img-bg"><img class="img" src="https://up.ctext.top/emoji/%E5%B4%A9%E6%BA%83.jpg" style="width:200px;"/></div></div></div><h2 id="小说明">小说明</h2><ul><li>修改包名即可使用</li><li>代码中判断了路径,所以简易使用的时候直接传入一个文件名称即可(这样无论是window还是打包发布之后,默认都会生成到当前项目或者当前jar的目录下)</li><li>代码中还打印了错误堆栈信息,方便找到错误行</li></ul><h2 id="上码">上码</h2><details class="folding-tag" cyan open><summary> 源代码 </summary> <div class='content'> <figure class="highlight java"><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><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"><span class="keyword">package</span> com.example.demo.util;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> java.io.*;</span><br><span class="line"><span class="keyword">import</span> java.nio.file.Paths;</span><br><span class="line"><span class="keyword">import</span> java.time.LocalDateTime;</span><br><span class="line"><span class="keyword">import</span> java.time.format.DateTimeFormatter;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">LogUtils</span> {</span><br><span class="line"></span><br><span class="line"> <span class="keyword">private</span> <span class="keyword">static</span> <span class="keyword">final</span> <span class="type">DateTimeFormatter</span> <span class="variable">DATE_FORMAT</span> <span class="operator">=</span> DateTimeFormatter.ofPattern(<span class="string">"yyyy-MM-dd HH:mm:ss"</span>);</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"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> filePath 日志文件路径(支持相对路径和绝对路径)</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> message 自定义错误说明</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> throwable 异常对象(可为 null)</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"> <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">appendErrorLog</span><span class="params">(String filePath, String message, Throwable throwable)</span> {</span><br><span class="line"> <span class="comment">// 处理相对路径问题,转化为绝对路径</span></span><br><span class="line"> <span class="type">File</span> <span class="variable">file</span> <span class="operator">=</span> getAbsoluteFile(filePath);</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 保证父目录存在</span></span><br><span class="line"> <span class="keyword">if</span> (!file.getParentFile().exists()) {</span><br><span class="line"> file.getParentFile().mkdirs();</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="keyword">synchronized</span> (LogUtils.class) {</span><br><span class="line"> <span class="keyword">try</span> (<span class="type">BufferedWriter</span> <span class="variable">writer</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">BufferedWriter</span>(<span class="keyword">new</span> <span class="title class_">FileWriter</span>(file, <span class="literal">true</span>))) {</span><br><span class="line"> writer.write(<span class="string">"============================================================"</span>);</span><br><span class="line"> writer.newLine();</span><br><span class="line"> writer.write(<span class="string">"时间: "</span> + DATE_FORMAT.format(LocalDateTime.now()));</span><br><span class="line"> writer.newLine();</span><br><span class="line"> writer.write(<span class="string">"错误信息: "</span> + message);</span><br><span class="line"> writer.newLine();</span><br><span class="line"></span><br><span class="line"> <span class="keyword">if</span> (throwable != <span class="literal">null</span>) {</span><br><span class="line"> writer.write(<span class="string">"异常类型: "</span> + throwable.getClass().getName());</span><br><span class="line"> writer.newLine();</span><br><span class="line"> writer.write(<span class="string">"异常消息: "</span> + throwable.getMessage());</span><br><span class="line"> writer.newLine();</span><br><span class="line"> writer.write(<span class="string">"堆栈信息:"</span>);</span><br><span class="line"> writer.newLine();</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 将完整堆栈输出</span></span><br><span class="line"> <span class="type">StringWriter</span> <span class="variable">sw</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">StringWriter</span>();</span><br><span class="line"> <span class="type">PrintWriter</span> <span class="variable">pw</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">PrintWriter</span>(sw);</span><br><span class="line"> throwable.printStackTrace(pw);</span><br><span class="line"> writer.write(sw.toString());</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> writer.newLine();</span><br><span class="line"> writer.flush();</span><br><span class="line"> } <span class="keyword">catch</span> (IOException e) {</span><br><span class="line"> System.err.println(<span class="string">"写入错误日志失败:"</span> + e.getMessage());</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> }</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"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> filePath 相对路径或绝对路径</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@return</span> 绝对路径的文件</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"> <span class="keyword">private</span> <span class="keyword">static</span> File <span class="title function_">getAbsoluteFile</span><span class="params">(String filePath)</span> {</span><br><span class="line"> <span class="type">File</span> <span class="variable">file</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">File</span>(filePath);</span><br><span class="line"> <span class="comment">// 如果是相对路径,则转换为绝对路径</span></span><br><span class="line"> <span class="keyword">if</span> (!file.isAbsolute()) {</span><br><span class="line"> <span class="comment">// 获取当前工作目录并转换为绝对路径</span></span><br><span class="line"> <span class="type">String</span> <span class="variable">currentDir</span> <span class="operator">=</span> System.getProperty(<span class="string">"user.dir"</span>);</span><br><span class="line"> file = <span class="keyword">new</span> <span class="title class_">File</span>(currentDir, filePath);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> file;</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"></span><br></pre></td></tr></table></figure> </div> </details>]]></content>
<categories>
<category> 技术教程 </category>
</categories>
<tags>
<tag> JAVA </tag>
<tag> 工具类 </tag>
</tags>
</entry>
<entry>
<title>彻底学会@Autowired和@Resource</title>
<link href="/169d.html"/>
<url>/169d.html</url>
<content type="html"><![CDATA[<h1>看完你能学会</h1><div class="note warning no-icon flat"><ul><li>@Resource和@Autowired区别</li><li>IDEA使用@Autowired为什么有警告,</li><li>spring推荐使用那种方式进行注入</li></ul></div><h2 id="1-Autowired作用">1. @Autowired作用</h2><ul><li>来源: Spring 框架自带的注解。</li><li>注入方式: 默认按类型(byType)注入。</li><li>使用场景: 通常用于注入 Spring 管理的 Bean。</li><li>特点:<ul><li><mark class="hl-label orange">默认按类型匹配,如果找到多个相同类型的Bean,会按名称匹配。</mark> </li><li>可以与 <code>@Qualifier</code> 注解结合使用,指定具体的 Bean 名称。</li><li>支持 <code>required</code> 属性,默认为 <code>true</code>,表示必须注入,如果找不到 Bean 会抛出异常。设置为 <code>false</code> 时,允许注入为 <code>null</code>。</li></ul></li></ul><h2 id="2-Resource作用">2. @Resource作用</h2><ul><li>来源: JSR-250 标准注解,属于 Java EE 规范,Spring 也支持。</li><li>注入方式: 默认按名称(byName)注入。</li><li>使用场景: 适用于需要按名称注入 Bean 的场景。</li><li>特点:<ul><li><mark class="hl-label orange">默认按名称匹配,如果找不到指定名称的Bean,会回退到按类型匹配。</mark> </li><li>可以通过 <code>name</code> 属性指定 Bean 的名称。</li><li>不支持 <code>required</code> 属性,如果找不到 Bean 会抛出异常。</li></ul></li></ul><h2 id="3-为什么IDEA使用-Autowried会有警告">3. 为什么IDEA使用@Autowried会有警告</h2><ul><li>首先这个警告只会在字段注入的时候提示</li></ul><details class="folding-tag" green><summary> 查看代码测试 </summary> <div class='content'> <figure class="highlight java"><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></pre></td><td class="code"><pre><span class="line"><span class="comment">//提示警告⚠️</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">OperationController</span> {</span><br><span class="line"> <span class="meta">@Autowired</span></span><br><span class="line"> <span class="keyword">private</span> CmdbProvider cmdbProvider;</span><br><span class="line"> 。。。。</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">//这样就不会有警告(set之所以没有警告,是因为这样有其他应用场景,下面有解释)</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">OperationController</span> {</span><br><span class="line"> <span class="keyword">private</span> CmdbProvider cmdbProvider;</span><br><span class="line"></span><br><span class="line"> <span class="meta">@Autowired</span></span><br><span class="line"> <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">setCmdbProvider</span><span class="params">(CmdbProvider cmdbProvider)</span> {</span><br><span class="line"> <span class="built_in">this</span>.cmdbProvider = cmdbProvider;</span><br><span class="line"> }</span><br><span class="line"> 。。。。</span><br><span class="line">}</span><br></pre></td></tr></table></figure> </div> </details><div class="note success no-icon flat"><ul><li>因为@Autowired是spring提供的注解,而spring其实并不推荐这种注入方式,所以IDEA在检测代码规范时,如果是@Autowired就会使用spring的最佳实践来检查,所以才会有警告</li></ul></div><h2 id="4-Resource为什么没有警告">4. @Resource为什么没有警告</h2><ul><li>因为@Resource是java官方提供的注解,所以IDEA在检查@Resource时会使用java的标准去检查,所以没有警告</li></ul><h2 id="5-最后">5.最后</h2><div class="note success no-icon flat"><p>其实对于spring来说,他们既不推荐使用@Autowired,也不推荐使用@Resource进行字段的注入,而是更推荐使用<mark class="hl-label green">构造方法</mark> 进行注入</p></div><ul><li>构造注入的优点</li></ul><ol><li><mark class="hl-label purple">依赖关系清晰</mark> ,可以在构造方法中看到所有依赖的其他类</li><li><mark class="hl-label purple">方便测试</mark> 可以直接在调用构造方法时传入自己new出来的对象,如果是字段注入,需要启动整个spring容器才能进行代码的测试</li><li><p>构造注入可以将字段用final修饰,可以作为一个常量,不会被恶意修改,<mark class="hl-label purple">更安全</mark> </p></li><li><mark class="hl-label purple">符合单一职责原则</mark> ,如果一个类中构造器参数过多,可能意味着这个类的职责过重,需要拆分</li><li><mark class="hl-label purple">避免循环依赖</mark> ,如果存在循环依赖,项目启动会抛出异常(BeanCurrentlyInCreationException)</li><li><p>spring官方推荐注入方法:<code>构造注入 > set注入(适合可选依赖或需要动态配置的场景) > 字段注入(不推荐)</code></p></li></ol><details class="folding-tag" green><summary> 查看代码测试 </summary> <div class='content'> <figure class="highlight java"><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></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">#⚠️简化版本要求spring版本大于<span class="number">4.2</span>,<span class="number">4.3</span>之后的版本spring增加了新特性,就是当一个类只有一个构造函数时,会自动注入</span><br><span class="line">#⚠️否则需要显示声明<span class="meta">@Autowired</span>注解才会注入</span><br><span class="line">#下面有spring和springboot版本对应关系</span><br><span class="line"></span><br><span class="line">#✅构造注入的简化版本</span><br><span class="line"><span class="meta">@Component</span></span><br><span class="line">#lombok自动生成构造方法</span><br><span class="line"><span class="meta">@RequiredArgsConstructor</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">UserService</span> {</span><br><span class="line"> <span class="keyword">private</span> <span class="keyword">final</span> UserRepository userRepository;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">#构造注入</span><br><span class="line"><span class="meta">@Component</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">UserService</span> {</span><br><span class="line"> <span class="keyword">private</span> <span class="keyword">final</span> UserRepository userRepository;</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 推荐的做法,构造方法注入</span></span><br><span class="line"> <span class="keyword">public</span> <span class="title function_">UserService</span><span class="params">(UserRepository userRepository)</span> {</span><br><span class="line"> <span class="built_in">this</span>.userRepository = userRepository;</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">字段注入</span><br><span class="line"><span class="meta">@Component</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">UserService</span> {</span><br><span class="line"> <span class="meta">@Autowired</span></span><br><span class="line"> <span class="keyword">private</span> UserRepository userRepository;</span><br><span class="line"></span><br><span class="line"> <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">doSomething</span><span class="params">()</span> {</span><br><span class="line"> userRepository.save(<span class="keyword">new</span> <span class="title class_">User</span>());</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">Spring Boot 版本 Spring Framework 版本</span><br><span class="line"><span class="number">1.0</span>.x <span class="number">4.0</span>.x</span><br><span class="line"><span class="number">1.1</span>.x <span class="number">4.0</span>.x</span><br><span class="line"><span class="number">1.2</span>.x <span class="number">4.1</span>.x</span><br><span class="line"><span class="number">1.3</span>.x <span class="number">4.2</span>.x</span><br><span class="line"><span class="number">1.4</span>.x <span class="number">4.3</span>.x</span><br><span class="line"><span class="number">1.5</span>.x <span class="number">4.3</span>.x</span><br><span class="line"><span class="number">2.</span>X <span class="number">5.</span>X</span><br><span class="line"><span class="number">3.</span>x <span class="number">6.</span>x</span><br></pre></td></tr></table></figure> </div> </details>]]></content>
<categories>
<category> 技术教程 </category>
</categories>
<tags>
<tag> JAVA </tag>
<tag> Spring </tag>
</tags>
</entry>
<entry>
<title>mafl魔改——支持vercel部署</title>
<link href="/569c.html"/>
<url>/569c.html</url>
<content type="html"><![CDATA[<h1>魔改mafl</h1><ul><li><mark class="hl-label green">mafl</mark> 是一个简约好看的个人导航站,功能也相对比较完善,适用于少量常用网站的记录,如果记录的网站太多会有点臃肿。</li></ul><div class="btns circle grid5"> <a class="button no-text-decoration" href='https://github.com/hywax/mafl' title='官方仓库'><i class='anzhiyufont anzhiyu-icon-github'></i>官方仓库</a><a class="button no-text-decoration" href='https://mafl.hywax.space/' title='官方文档'><i class='anzhiyufont anzhiyu-icon-book'></i>官方文档</a><a class="button no-text-decoration" href='https://github.com/hywax/mafl/issues/164' title='issues(我提的🫡)'><i class='anzhiyufont anzhiyu-icon-github'></i>issues(我提的🫡)</a> </div><hr><div class="site-card-group"><a class="site-card" href="https://nav.ctext.top/" data-title=这是一段关于这个网站的描述文字><div class="wrapper cover"><img class="cover fadeIn" src="https://up.ctext.top/article/2025/02/mafl-view.png"/></div><div class="info"><img class="flink-avatar" src="https://mafl.hywax.space/favicon.ico"/><span class="site-title">部署成功之后的样子</span></div></a></div><hr><div class="note success no-icon flat"><p>奈何服务器太贵,所以能白嫖就白嫖🤔(官方支持docker部署)</p><p>如果直接讲<mark class="hl-label green">mafl</mark> 部署到Vercel会显示找不到配置文件</p><div class="img-wrap"><div class="img-bg"><img class="img" src="https://up.ctext.top/article/2025/02/notfound.png" style="width:300px;"/></div></div>所以想了一个办法就是通过一个地址去获取配置文件,而不是读取本地配置文件</div><h2 id="1-魔改问题">1.魔改问题</h2><div class="note warning no-icon flat"><ol><li>因为使用Vercel,所以没办法使用后端服务</li><li>部署完成之后偶尔会出现无法访问的情况,刷新一下即可解决</li></ol></div><h2 id="2-下载源码">2.下载源码</h2><ul><li>fork官方仓库,然后克隆到本地</li><li>先install,build,然后run dev测试能否正常运行(<code>这个过程比较慢,耐心等待</code>)</li><li>如果正常启动,访问 <a href="http://localhost:3000/">http://localhost:3000/</a> 会打开页面</li></ul><h2 id="3-修改源码">3.修改源码</h2><ul><li><p>找<mark class="hl-label orange">mafl\src\server\utils\config.ts</mark> 这个文件中的loadConfig方法,remoteConfigUrl就是你要指定的配置文件地址</p></li><li><p>安装axios <strong>yarn global add axios</strong></p></li></ul><details class="folding-tag" ><summary> 修改代码 </summary> <div class='content'> <figure class="highlight ts"><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><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//最上面声明</span></span><br><span class="line"><span class="keyword">import</span> axios <span class="keyword">from</span> <span class="string">'axios'</span> <span class="comment">// 引入 axios 用于发送 HTTP 请求</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">async</span> <span class="keyword">function</span> <span class="title function_">loadConfig</span>(<span class="params"></span>): <span class="title class_">Promise</span><<span class="title class_">CompleteConfig</span>> {</span><br><span class="line"> <span class="keyword">const</span> defaultConfig = <span class="title function_">getDefaultConfig</span>()</span><br><span class="line"></span><br><span class="line"> <span class="keyword">try</span> {</span><br><span class="line"> <span class="keyword">let</span> remoteConfigUrl = <span class="string">`https://main.ctext.top/config-pub.yml`</span></span><br><span class="line"></span><br><span class="line"> <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">"远程配置文件地址: "</span> + remoteConfigUrl)</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 使用 axios 获取远程 YAML 文件</span></span><br><span class="line"> <span class="keyword">const</span> response = <span class="keyword">await</span> axios.<span class="title function_">get</span>(remoteConfigUrl)</span><br><span class="line"> <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">"远程配置文件status: "</span> + response.<span class="property">status</span>)</span><br><span class="line"></span><br><span class="line"> <span class="keyword">const</span> raw = response.<span class="property">data</span></span><br><span class="line"> <span class="keyword">const</span> config = yaml.<span class="title function_">parse</span>(raw) || {}</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 验证配置文件</span></span><br><span class="line"> configSchema.<span class="title function_">parse</span>(config)</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 处理 services</span></span><br><span class="line"> <span class="keyword">const</span> <span class="attr">services</span>: <span class="title class_">CompleteConfig</span>[<span class="string">'services'</span>] = []</span><br><span class="line"> <span class="keyword">const</span> <span class="attr">tags</span>: <span class="title class_">TagMap</span> = <span class="title function_">createTagMap</span>(config.<span class="property">tags</span> || [])</span><br><span class="line"></span><br><span class="line"> <span class="keyword">if</span> (<span class="title class_">Array</span>.<span class="title function_">isArray</span>(config.<span class="property">services</span>)) {</span><br><span class="line"> services.<span class="title function_">push</span>({</span><br><span class="line"> <span class="attr">items</span>: <span class="title function_">determineService</span>(config.<span class="property">services</span>, tags),</span><br><span class="line"> })</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> <span class="keyword">const</span> entries = <span class="title class_">Object</span>.<span class="property">entries</span><<span class="title class_">DraftService</span>[]>(config.<span class="property">services</span> || [])</span><br><span class="line"></span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">const</span> [title, items] <span class="keyword">of</span> entries) {</span><br><span class="line"> services.<span class="title function_">push</span>({</span><br><span class="line"> title,</span><br><span class="line"> <span class="attr">items</span>: <span class="title function_">determineService</span>(items, tags),</span><br><span class="line"> })</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="keyword">return</span> <span class="title function_">defu</span>({ ...config, services }, defaultConfig)</span><br><span class="line"> } <span class="keyword">catch</span> (e) {</span><br><span class="line"> logger.<span class="title function_">error</span>(<span class="string">"远程配置文件获取异常: "</span> + e)</span><br><span class="line"> <span class="variable language_">console</span>.<span class="title function_">error</span>(<span class="string">"远程配置文件获取异常: "</span>, e)</span><br><span class="line"></span><br><span class="line"> <span class="keyword">if</span> (e <span class="keyword">instanceof</span> <span class="title class_">Error</span>) {</span><br><span class="line"> defaultConfig.<span class="property">error</span> = e.<span class="property">message</span></span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="keyword">if</span> (e <span class="keyword">instanceof</span> <span class="title class_">ZodError</span>) {</span><br><span class="line"> defaultConfig.<span class="property">error</span> = <span class="title class_">JSON</span>.<span class="title function_">stringify</span>(</span><br><span class="line"> e.<span class="title function_">format</span>(),</span><br><span class="line"> <span class="function">(<span class="params">key, val</span>) =></span> (key === <span class="string">'_errors'</span> && !val.<span class="property">length</span>) ? <span class="literal">undefined</span> : val,</span><br><span class="line"> <span class="string">' '</span>,</span><br><span class="line"> )</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="keyword">return</span> defaultConfig</span><br><span class="line">}</span><br></pre></td></tr></table></figure> </div> </details><div class="note primary no-icon flat"><ul><li>方案一<br>最简单的方案就是把你的配置文件放到<mark class="hl-label orange">\mafl\src\public</mark> 目录下,然后把你发布所指定的域名+配置文件名称就是你的地址,比如我上面的 <a href="https://nav.ctext.top/config-pub.yml">https://nav.ctext.top/config-pub.yml</a></li><li>方案二<br>还有就是你可以上传到云服务厂商的<mark class="hl-label pink">云存储</mark> 中,优点就是修改文件不需要提交代码,但是因为<mark class="hl-label pink">云存储</mark> 有缓存,所以修改完不会立马同步,可能要等一会儿才会显示最新的配置文件内容</li></ul></div><h2 id="4-关于上传到云存储中">4.关于上传到云存储中</h2><ul><li>因为<mark class="hl-label green">mafl</mark> 项目自带了缓存功能,所以他不会每次都请求你的配置文件,而是通过一个定时任务来定时获取最新配置文件</li><li>所以如果你想让他立马同步你的修改,你首先就是<strong>清除掉云存储的缓存</strong>,还有就是<strong>修改如下代码</strong></li></ul><figure class="highlight ts"><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">//找mafl\src\server\utils\config.ts这个文件中的getConfig方法</span></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">async</span> <span class="keyword">function</span> <span class="title function_">getConfig</span>(<span class="params"></span>): <span class="title class_">Promise</span><<span class="title class_">CompleteConfig</span> | <span class="literal">null</span>> {</span><br><span class="line"> <span class="keyword">const</span> storage = <span class="title function_">useStorage</span>(<span class="string">'main'</span>)</span><br><span class="line"> <span class="keyword">await</span> storage.<span class="title function_">getKeys</span>()</span><br><span class="line"> <span class="comment">//注释掉下面这一行,新增一行</span></span><br><span class="line"> <span class="comment">// return storage.getItem<CompleteConfig>('config')</span></span><br><span class="line"> <span class="keyword">return</span> <span class="title function_">loadConfig</span>();</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h2 id="5-最后就是在Vercel部署你仓库里的mafl即可,比较简单😝">5.最后就是在Vercel部署你仓库里的mafl即可,比较简单😝</h2>]]></content>
<categories>
<category> 前端开发 </category>
</categories>
<tags>
<tag> 魔改 </tag>
<tag> mafl </tag>
</tags>
</entry>
<entry>
<title>WIN MAC 快捷键大全</title>
<link href="/9b1f.html"/>
<url>/9b1f.html</url>
<content type="html"><![CDATA[<div class="note success simple"><p>ctrl+f可以直接搜索</p></div><div class="tabs" id="test4"><ul class="nav-tabs"><button type="button" class="tab active" data-href="test4-1">windows快捷键</button><button type="button" class="tab " data-href="test4-2">浏览器快捷键</button><button type="button" class="tab " data-href="test4-3">mac快捷键</button></ul><div class="tab-contents"><div class="tab-item-content active" id="test4-1"><details class="folding-tag" cyan><summary> 常用快捷键 </summary> <div class='content'> <table><thead><tr><th>快捷键</th><th>功能描述</th></tr></thead><tbody><tr><td><code>Ctrl + A</code></td><td>选择文档或窗口中的所有项目</td></tr><tr><td><code>Ctrl + 箭头键</code></td><td>打开“开始”菜单时调整其大小</td></tr><tr><td><code>Ctrl + C</code> 或 <code>Ctrl + Insert</code></td><td>复制所选项目</td></tr><tr><td><code>Ctrl + D</code> 或 <code>Delete</code></td><td>删除所选项目并将其移动到回收站</td></tr><tr><td><code>Ctrl + E</code></td><td>在大多数应用中打开搜索</td></tr><tr><td><code>Ctrl + Esc</code></td><td>打开“开始”</td></tr><tr><td><code>Ctrl + F4</code></td><td>在全屏应用中关闭活动文档,并允许同时打开多个文档</td></tr><tr><td><code>Ctrl + Shift + V</code></td><td>粘贴为纯文本</td></tr><tr><td><code>Ctrl + Shift + 箭头键</code></td><td>选择文本块</td></tr><tr><td><code>Ctrl + Shift</code></td><td>当有多个键盘布局可用时切换键盘布局</td></tr><tr><td><code>Ctrl + 向上键</code></td><td>将光标移动到上一段的开头</td></tr><tr><td><code>Ctrl + V</code> 或 <code>Shift + Insert</code></td><td>粘贴所选项目</td></tr><tr><td><code>Ctrl + X</code></td><td>剪切所选项目</td></tr><tr><td><code>Ctrl + Y</code></td><td>恢复操作</td></tr><tr><td><code>Ctrl + Z</code></td><td>撤销操作</td></tr><tr><td><code>Esc</code></td><td>停止或离开当前任务</td></tr><tr><td><code>F2</code></td><td>重命名所选项目</td></tr><tr><td><code>F3</code></td><td>在文件资源管理器中搜索文件或文件夹</td></tr><tr><td><code>F4</code></td><td>在文件资源管理器中显示地址栏列表</td></tr><tr><td><code>F5</code></td><td>刷新活动窗口</td></tr><tr><td><code>F6</code></td><td>在窗口或桌面上循环浏览屏幕元素</td></tr><tr><td><code>F10</code></td><td>激活活动应用中的菜单栏</td></tr><tr><td><code>Shift + Delete</code></td><td>删除所选项目,而无需先将其移动到回收站</td></tr><tr><td><code>Shift + 任意箭头键</code></td><td>在窗口或桌面上选择多个项目,或选择文档中的文本</td></tr><tr><td><code>PrtScn</code></td><td>获取整个屏幕的屏幕截图,并将其复制到剪贴板</td></tr></tbody></table> </div> </details><details class="folding-tag" cyan><summary> 桌面快捷键 </summary> <div class='content'> <table><thead><tr><th>快捷键</th><th>功能描述</th></tr></thead><tbody><tr><td><code>Alt + Esc</code></td><td>循环浏览打开的窗口</td></tr><tr><td><code>Alt + F4</code></td><td>关闭活动窗口</td></tr><tr><td><code>Alt + F8</code></td><td>在登录屏幕中显示键入的密码</td></tr><tr><td><code>Alt + 向左键</code></td><td>返回</td></tr><tr><td><code>Alt + Page Down</code></td><td>下移一个屏幕</td></tr><tr><td><code>Alt + Page Up</code></td><td>上移一个屏幕</td></tr><tr><td><code>Alt + 向右键</code></td><td>前进</td></tr><tr><td><code>Alt + 空格键</code></td><td>打开活动窗口的上下文菜单</td></tr><tr><td><code>Alt + Tab</code></td><td>多次按 Tab 键时在打开的应用之间切换</td></tr><tr><td><code>Alt + 带下划线的字母</code></td><td>在应用中对带下划线的字母运行命令</td></tr><tr><td><code>Ctrl + Alt + Tab</code></td><td>查看打开的应用</td></tr><tr><td><code>Ctrl + 箭头键</code></td><td>更改“开始”菜单大小</td></tr><tr><td><code>Ctrl + 箭头键 (选择) + 空格键</code></td><td>选择桌面或文件资源管理器上的多个项目</td></tr><tr><td><code>Ctrl + 单击已分组的应用按钮</code></td><td>从任务栏循环浏览组中的窗口</td></tr><tr><td><code>Ctrl + 向下键</code></td><td>将光标移动到下一段落的开头</td></tr><tr><td><code>Ctrl + F5</code> 或 <code>Ctrl + R</code></td><td>刷新当前窗口</td></tr><tr><td><code>Ctrl + 向左键</code></td><td>将光标移动到上一个单词的开头</td></tr><tr><td><code>Ctrl + 向右键</code></td><td>将光标移动到下一个单词的开头</td></tr><tr><td><code>Ctrl + Shift</code></td><td>切换键盘布局</td></tr><tr><td><code>Ctrl + Shift + 箭头键</code></td><td>选择文本块</td></tr><tr><td><code>Ctrl + Shift + 单击应用按钮</code></td><td>从任务栏以管理员身份运行应用</td></tr><tr><td><code>Ctrl + Shift + Esc</code></td><td>打开任务管理器</td></tr><tr><td><code>Ctrl + 空格键</code></td><td>启用或禁用中文输入法</td></tr><tr><td><code>Ctrl + 向上键</code></td><td>将光标移动到上一段落的开头</td></tr><tr><td><code>Shift + 箭头键</code></td><td>选择多个项</td></tr><tr><td><code>Shift + 单击应用按钮</code></td><td>从任务栏打开应用的另一个实例</td></tr><tr><td><code>Shift + F10</code></td><td>打开选定项的上下文菜单</td></tr><tr><td><code>Shift + 右键单击应用按钮</code></td><td>从任务栏中显示应用的窗口菜单</td></tr><tr><td><code>Shift + 右键单击分组应用按钮</code></td><td>从任务栏中显示组的窗口菜单</td></tr></tbody></table> </div> </details><details class="folding-tag" cyan><summary> 虚拟桌面快捷键 </summary> <div class='content'> <table><thead><tr><th>快捷键</th><th>功能描述</th></tr></thead><tbody><tr><td><code>Windows 键 + Tab</code></td><td>打开“任务”视图</td></tr><tr><td><code>Windows 键 + Ctrl + D</code></td><td>添加虚拟桌面</td></tr><tr><td><code>Windows 键 + Ctrl + 向右键</code></td><td>在右侧创建的虚拟桌面之间切换</td></tr><tr><td><code>Windows 键 + Ctrl + 向左键</code></td><td>在左侧创建的虚拟桌面之间切换</td></tr><tr><td><code>Windows 键 + Ctrl + F4</code></td><td>关闭正在使用的虚拟桌面</td></tr></tbody></table> </div> </details><details class="folding-tag" cyan><summary> 键快捷键 </summary> <div class='content'> <table><thead><tr><th>快捷键</th><th>功能描述</th></tr></thead><tbody><tr><td><code>Windows 键</code></td><td>打开开始菜单</td></tr><tr><td><code>Windows 键 + A</code></td><td>打开操作中心</td></tr><tr><td><code>Windows 键 + Alt + D</code></td><td>在任务栏中打开日期和时间</td></tr><tr><td><code>Windows 键 + Alt + 数字</code></td><td>在任务栏中的数字位置打开应用的跳转列表</td></tr><tr><td><code>Windows 键 + B</code></td><td>在任务栏中设置焦点通知区域</td></tr><tr><td><code>Windows 键 + C</code></td><td>打开/关闭 Copilot</td></tr><tr><td><code>Windows 键 + 逗号 (,)</code></td><td>暂时查看桌面</td></tr><tr><td><code>Windows 键 + Ctrl + Enter</code></td><td>打开“讲述人”</td></tr><tr><td><code>Windows 键 + Ctrl + F</code></td><td>在域网络上打开搜索设备</td></tr><tr><td><code>Windows 键 + Ctrl + F4</code></td><td>关闭活动虚拟桌面</td></tr><tr><td><code>Windows 键 + Ctrl + 向左键</code></td><td>切换到左侧的虚拟桌面</td></tr><tr><td><code>Windows 键 + Ctrl + 数字</code></td><td>切换到任务栏中数字位置中应用的最后一个活动窗口</td></tr><tr><td><code>Windows 键 + Ctrl + Q</code></td><td>打开快速助手</td></tr><tr><td><code>Windows 键 + Ctrl + Shift + 数字</code></td><td>在任务栏中的数字位置以应用管理员身份打开另一个实例</td></tr><tr><td><code>Windows 键 + Ctrl + 空格键</code></td><td>更改以前的选定输入选项</td></tr><tr><td><code>Windows 键 + D</code></td><td>显示和隐藏桌面</td></tr><tr><td><code>Windows 键 + 向下键</code></td><td>最小化应用窗口</td></tr><tr><td><code>Windows 键 + E</code></td><td>打开文件资源管理器</td></tr><tr><td><code>Windows 键 + Esc</code></td><td>退出放大镜</td></tr><tr><td><code>Windows 键 + F</code></td><td>启动反馈中心应用</td></tr><tr><td><code>Windows 键 + 正斜杠 (/)</code></td><td>启动 IME 重新转换</td></tr><tr><td><code>Windows 键 + G</code></td><td>启动游戏栏应用</td></tr><tr><td><code>Windows 键 + H</code></td><td>打开听写功能</td></tr><tr><td><code>Windows 键 + Home</code></td><td>最小化或最大化除活动桌面窗口外的所有窗口</td></tr><tr><td><code>Windows 键 + I</code></td><td>打开设置</td></tr><tr><td><code>Windows 键 + J</code></td><td>在 Windows 10 的提示上设置焦点(如果适用)</td></tr><tr><td><code>Windows 键 + K</code></td><td>打开连接设置</td></tr><tr><td><code>Windows 键 + L</code></td><td>锁定计算机</td></tr><tr><td><code>Windows 键 + 向左键</code></td><td>向左对齐应用或窗口</td></tr><tr><td><code>Windows 键 + M</code></td><td>最小化所有窗口</td></tr><tr><td><code>Windows 键 + 减号 (-)</code></td><td>使用放大镜缩小字体功能</td></tr><tr><td><code>Windows 键 + 数字</code></td><td>在任务栏中的编号位置打开应用</td></tr><tr><td><code>Windows 键 + O</code></td><td>锁定设备方向</td></tr><tr><td><code>Windows 键 + P</code></td><td>打开项目设置</td></tr><tr><td><code>Windows 键 + 暂停</code></td><td>显示系统属性对话框</td></tr><tr><td><code>Windows 键 + 句点 (.) 或分号 (;)</code></td><td>打开表情符号面板</td></tr><tr><td><code>Windows 键 + 加号 (+)</code></td><td>使用放大镜放大</td></tr><tr><td><code>Windows 键 + PrtScn</code></td><td>捕获“屏幕截图”文件夹中的完整屏幕截图</td></tr><tr><td><code>Windows 键 + R</code></td><td>打开“运行”命令</td></tr><tr><td><code>Windows 键 + 向右键</code></td><td>向右贴靠应用或窗口</td></tr><tr><td><code>Windows 键 + S</code> 或 <code>Q</code></td><td>打开搜索</td></tr><tr><td><code>Windows 键 + Shift + 向下键</code></td><td>在保持宽度的同时最大化或最小化活动窗口垂直</td></tr><tr><td><code>Windows 键 + Shift + 向左键</code></td><td>移动活动窗口以在左侧进行监视</td></tr><tr><td><code>Windows 键 + Shift + M</code></td><td>还原桌面上最小化的窗口</td></tr><tr><td><code>Windows 键 + Shift + 数字</code></td><td>在任务栏中的数字位置打开另一个应用实例</td></tr><tr><td><code>Windows 键 + Shift + 向右键</code></td><td>移动活动窗口以在右侧监视</td></tr><tr><td><code>Windows 键 + Shift + S</code></td><td>创建屏幕屏幕截图的一部分</td></tr><tr><td><code>Windows 键 + Shift + 向上键</code></td><td>将桌面窗口拉伸到屏幕顶部和底部</td></tr></tbody></table> </div> </details><details class="folding-tag" cyan><summary> 文件资源管理器快捷键 </summary> <div class='content'> <table><thead><tr><th>快捷键</th><th>功能描述</th></tr></thead><tbody><tr><td><code>Alt + D</code></td><td>选择地址栏</td></tr><tr><td><code>Alt + Enter</code></td><td>打开选定项的属性设置</td></tr><tr><td><code>Alt + 向左键</code> 或 <code>Backspace</code></td><td>查看上一个文件夹</td></tr><tr><td><code>Alt + P</code></td><td>显示预览面板</td></tr><tr><td><code>Alt + 向右键</code></td><td>查看下一个文件夹</td></tr><tr><td><code>Alt + 向上键</code></td><td>在文件夹路径中向上移动级别</td></tr><tr><td><code>Ctrl + E</code> 或 <code>F</code></td><td>选择搜索框</td></tr><tr><td><code>Ctrl + F</code> 或 <code>F3</code></td><td>开始搜索</td></tr><tr><td><code>Ctrl + L</code></td><td>焦点位于地址栏上</td></tr><tr><td><code>Ctrl + 鼠标滚轮</code></td><td>更改视图文件和文件夹</td></tr><tr><td><code>Ctrl + N</code></td><td>打开新窗口</td></tr><tr><td><code>Ctrl + Shift + E</code></td><td>展开导航窗格中树中的所有文件夹</td></tr><tr><td><code>Ctrl + Shift + N</code></td><td>在桌面或文件资源管理器上创建新文件夹</td></tr><tr><td><code>Ctrl + Shift + 数字</code></td><td>更改文件夹视图</td></tr><tr><td><code>Ctrl + W</code></td><td>关闭活动窗口</td></tr><tr><td><code>End</code></td><td>滚动到窗口底部</td></tr><tr><td><code>F11</code></td><td>切换活动窗口全屏模式</td></tr><tr><td><code>F2</code></td><td>重命名所选项目</td></tr><tr><td><code>F4</code></td><td>将焦点切换到地址栏</td></tr><tr><td><code>F5</code></td><td>刷新当前文件资源管理器视图</td></tr><tr><td><code>F6</code></td><td>循环浏览屏幕上的元素</td></tr><tr><td><code>Windows 键 + E</code></td><td>打开文件资源管理器</td></tr></tbody></table> </div> </details><details class="folding-tag" cyan><summary> 设置页快捷键 </summary> <div class='content'> <table><thead><tr><th>快捷键</th><th>功能描述</th></tr></thead><tbody><tr><td><code>Backspace</code></td><td>在“打开”或“另存为”对话框中打开文件夹一级应用</td></tr><tr><td><code>空格键</code></td><td>检查或清除焦点中的选项</td></tr><tr><td><code>Tab</code></td><td>在设置中向前移动</td></tr><tr><td><code>Ctrl + 数字</code></td><td>跳转到选项卡位置</td></tr><tr><td><code>Ctrl + Shift + Tab</code></td><td>循环返回选项卡</td></tr><tr><td><code>Ctrl + Tab</code></td><td>向前循环浏览选项卡</td></tr><tr><td><code>Shift + Tab</code></td><td>在设置中向后移动</td></tr></tbody></table> </div> </details><details class="folding-tag" cyan><summary> 命令提示符快捷键 </summary> <div class='content'> <table><thead><tr><th>快捷键</th><th>功能描述</th></tr></thead><tbody><tr><td><code>Ctrl + A</code></td><td>选择当前行的所有内容</td></tr><tr><td><code>Ctrl + C</code></td><td>将所选项目复制到剪贴板</td></tr><tr><td><code>Ctrl + Insert</code></td><td>将所选项目复制到剪贴板</td></tr><tr><td><code>Ctrl + 向下键</code></td><td>将屏幕向下移动一行</td></tr><tr><td><code>Ctrl + End</code></td><td>滚动到控制台底部</td></tr><tr><td><code>Ctrl + F</code></td><td>打开搜索命令提示符</td></tr><tr><td><code>Ctrl + Home</code></td><td>滚动到主机顶部</td></tr><tr><td><code>Ctrl + M</code></td><td>启动标记模式</td></tr><tr><td><code>Ctrl + 向上键</code></td><td>将屏幕向上移动一行</td></tr><tr><td><code>Ctrl + V</code></td><td>粘贴剪贴板中的内容</td></tr><tr><td><code>Shift + 插入</code></td><td>粘贴剪贴板中的内容</td></tr><tr><td><code>向左或向右键</code></td><td>在当前行中向左或向右移动光标</td></tr><tr><td><code>Page Down</code></td><td>将光标向下移动一页</td></tr><tr><td><code>Page Up</code></td><td>将光标向上移动一页</td></tr><tr><td><code>向上或向下键</code></td><td>循环浏览当前会话的命令历史记录</td></tr></tbody></table> </div> </details><details class="folding-tag" cyan><summary> 任务栏快捷键 </summary> <div class='content'> <table><thead><tr><th>快捷键</th><th>功能描述</th></tr></thead><tbody><tr><td><code>Ctrl + Shift + 单击任务栏按钮</code></td><td>以管理员身份打开应用</td></tr><tr><td><code>Ctrl + 单击分组任务栏按钮</code></td><td>循环浏览组的窗口</td></tr><tr><td><code>Shift + 单击任务栏按钮</code></td><td>打开应用或快速打开另一个应用实例</td></tr><tr><td><code>Shift + 右键单击分组任务栏按钮</code></td><td>显示组的窗口菜单</td></tr><tr><td><code>Shift + 右键单击任务栏按钮</code></td><td>显示应用的窗口菜单</td></tr></tbody></table> </div> </details><details class="folding-tag" cyan><summary> 文本编辑快捷键 </summary> <div class='content'> <table><thead><tr><th>快捷键</th><th>功能描述</th></tr></thead><tbody><tr><td><code>Backspace</code></td><td>删除左侧的字符</td></tr><tr><td><code>Ctrl + =</code></td><td>使所选文本下标</td></tr><tr><td><code>Ctrl + A</code></td><td>选择所有文本</td></tr><tr><td><code>Ctrl + B</code></td><td>将所选文本设为粗体</td></tr><tr><td><code>Ctrl + Backspace</code></td><td>删除左侧的字词</td></tr><tr><td><code>Ctrl + C</code></td><td>复制文本</td></tr><tr><td><code>Ctrl + Del</code></td><td>删除右侧的字词</td></tr><tr><td><code>Ctrl + 向下键</code></td><td>转到换行符的末尾</td></tr><tr><td><code>Ctrl + End</code></td><td>转到文档末尾</td></tr><tr><td><code>Ctrl + F</code></td><td>查找文本</td></tr><tr><td><code>Ctrl + H</code></td><td>查找和替换文本</td></tr><tr><td><code>Ctrl + Home</code></td><td>转到文档的开头</td></tr><tr><td><code>Ctrl + I</code></td><td>使所选文本采用斜体</td></tr><tr><td><code>Ctrl + 向左键</code></td><td>转到上一个单词的开头</td></tr><tr><td><code>Ctrl + 向右键</code></td><td>转到下一个单词的开头</td></tr><tr><td><code>Ctrl + Shift + =</code></td><td>使所选文本上标</td></tr><tr><td><code>Ctrl + U</code></td><td>为所选文本添加下划线</td></tr><tr><td><code>Ctrl + 向上键</code></td><td>转到换行符的开头</td></tr><tr><td><code>Ctrl + V</code></td><td>粘贴文本</td></tr><tr><td><code>Ctrl + X</code></td><td>剪切文本</td></tr><tr><td><code>Ctrl + Y</code></td><td>重做文本</td></tr><tr><td><code>Ctrl + Z</code></td><td>撤消文本</td></tr><tr><td><code>Delete</code></td><td>删除右侧的字符</td></tr><tr><td><code>向下键</code></td><td>向下一行</td></tr><tr><td><code>End</code></td><td>转到当前行的末尾</td></tr><tr><td><code>Home</code></td><td>转到当前行的开头</td></tr><tr><td><code>向左键</code></td><td>向左或上一个换行符的末尾</td></tr><tr><td><code>Page Down</code></td><td>下移一帧</td></tr><tr><td><code>Page Up</code></td><td>上移一个框架</td></tr><tr><td><code>向右键</code></td><td>向右或下一个换行符的开头</td></tr><tr><td><code>Shift + Ctrl + 向下</code></td><td>选择右侧段落</td></tr><tr><td><code>Shift + Ctrl + End</code></td><td>选择光标和文档末尾之间的文本</td></tr><tr><td><code>Shift + Ctrl + Home</code></td><td>选择光标和文档开头之间的文本</td></tr><tr><td><code>Shift + Ctrl + 向左</code></td><td>选择左侧的字词</td></tr><tr><td><code>Shift + Ctrl + 向右</code></td><td>选择右侧的字词</td></tr><tr><td><code>Shift + Ctrl + 向上</code></td><td>选择左侧的段落</td></tr><tr><td><code>Shift + 向下键</code></td><td>向下选择线条</td></tr><tr><td><code>Shift + End</code></td><td>选择光标与当前行末尾之间的文本</td></tr><tr><td><code>Shift + Home</code></td><td>选择光标与当前行开头之间的文本</td></tr><tr><td><code>Shift + 向左键</code></td><td>选择左侧的字符</td></tr><tr><td><code>Shift + Page Down</code></td><td>在光标下方的一次文本中选择一个框架</td></tr><tr><td><code>Shift + Page Up</code></td><td>在光标上方的一次文本中选择一个框架</td></tr><tr><td><code>Shift + 向右键</code></td><td>选择右侧的字符</td></tr><tr><td><code>Shift + Tab</code></td><td>外缩进</td></tr><tr><td><code>Shift + 向上键</code></td><td>向上选择线条</td></tr><tr><td><code>Tab</code></td><td>缩进</td></tr><tr><td><code>向上键</code></td><td>上一行</td></tr></tbody></table> </div> </details></div><div class="tab-item-content" id="test4-2"><details class="folding-tag" green><summary> 常用快捷键 </summary> <div class='content'> <table><thead><tr><th>快捷键</th><th>功能</th></tr></thead><tbody><tr><td><code>Ctrl + D</code></td><td>将当前选项卡另存为收藏夹</td></tr><tr><td><code>F12</code></td><td>打开开发人员工具</td></tr><tr><td><code>Ctrl + U</code></td><td>查看源</td></tr><tr><td><code>Ctrl + Shift + Delete</code></td><td>打开清除浏览数据选项</td></tr><tr><td><code>Ctrl + Shift + R</code></td><td>重新加载当前页,忽略缓存内容</td></tr><tr><td><code>Ctrl + N</code></td><td>打开新窗口</td></tr><tr><td><code>Ctrl + Shift + N</code></td><td>打开新的 InPrivate 窗口</td></tr><tr><td><code>Ctrl + T</code></td><td>打开新标签页并切换到该标签页</td></tr><tr><td><code>Alt + D</code></td><td>选择地址栏中的 URL 以进行编辑</td></tr><tr><td><code>Ctrl + J</code></td><td>打开“下载”文件夹</td></tr></tbody></table> </div> </details><details class="folding-tag" green><summary> 收藏夹快捷键 </summary> <div class='content'> <table><thead><tr><th>快捷键</th><th>功能</th></tr></thead><tbody><tr><td><code>Ctrl + Shift + B</code></td><td>显示或隐藏收藏夹栏</td></tr><tr><td><code>Alt + Shift + B</code></td><td>将焦点放在收藏夹栏中的第一项上</td></tr><tr><td><code>Ctrl + D</code></td><td>将当前选项卡另存为收藏夹</td></tr><tr><td><code>Ctrl + Shift + D</code></td><td>在新文件夹中将所有打开的标签页另存为收藏夹</td></tr><tr><td><code>Ctrl + Shift + O</code></td><td>打开收藏夹</td></tr></tbody></table> </div> </details><details class="folding-tag" green><summary> 历史记录和开发工具快捷键 </summary> <div class='content'> <table><thead><tr><th>快捷键</th><th>功能</th></tr></thead><tbody><tr><td><code>Ctrl + H</code></td><td>打开历史记录</td></tr><tr><td><code>Ctrl + Shift + I</code></td><td>打开开发人员工具</td></tr><tr><td><code>F12</code></td><td>打开开发人员工具</td></tr><tr><td><code>Ctrl + U</code></td><td>查看源</td></tr><tr><td><code>Ctrl + Shift + Delete</code></td><td>打开清除浏览数据选项</td></tr></tbody></table> </div> </details><details class="folding-tag" green><summary> 窗口标签页快捷键 </summary> <div class='content'> <table><thead><tr><th>快捷键</th><th>功能</th></tr></thead><tbody><tr><td><code>Ctrl + N</code></td><td>打开新窗口</td></tr><tr><td><code>Ctrl + Shift + N</code></td><td>打开新的 InPrivate 窗口</td></tr><tr><td><code>Ctrl + T</code></td><td>打开新标签页并切换到该标签页</td></tr><tr><td><code>Ctrl + Shift + T</code></td><td>重新打开上一个关闭的标签页并切换到该标签页</td></tr><tr><td><code>Alt + Shift + T</code></td><td>将焦点放在应用栏工具栏中的第一项上</td></tr><tr><td><code>Ctrl + W</code></td><td>关闭当前标签页</td></tr><tr><td><code>Ctrl + Shift + W</code></td><td>关闭当前窗口</td></tr><tr><td><code>Ctrl + R</code></td><td>重新加载当前页</td></tr><tr><td><code>Ctrl + Shift + R</code></td><td>重新加载当前页,忽略缓存内容</td></tr><tr><td><code>Ctrl + S</code></td><td>保存当前页</td></tr><tr><td><code>Ctrl + M</code></td><td>将当前标签页设为静音(切换)</td></tr><tr><td><code>Ctrl + 0</code></td><td>重置页面缩放级别</td></tr><tr><td><code>Ctrl + 1, 2, ... 8</code></td><td>切换到特定标签页</td></tr><tr><td><code>Ctrl + 9</code></td><td>切换到最后一个标签页</td></tr></tbody></table> </div> </details><details class="folding-tag" green><summary> 地址栏快捷键 </summary> <div class='content'> <table><thead><tr><th>快捷键</th><th>功能</th></tr></thead><tbody><tr><td><code>Alt + D</code></td><td>选择地址栏中的 URL 以进行编辑</td></tr><tr><td><code>Ctrl + E</code></td><td>在地址栏中打开搜索查询</td></tr><tr><td><code>Ctrl + K</code></td><td>在地址栏中打开搜索查询</td></tr><tr><td><code>Ctrl + L</code></td><td>选择地址栏中的 URL 以进行编辑</td></tr><tr><td><code>Ctrl + Enter</code></td><td>将 www. 和 .com 分别添加到在地址栏中键入的文本的开头和末尾</td></tr><tr><td><code>F4</code></td><td>选择地址栏中的 URL</td></tr></tbody></table> </div> </details><details class="folding-tag" green><summary> 帮助设置快捷键 </summary> <div class='content'> <table><thead><tr><th>快捷键</th><th>功能</th></tr></thead><tbody><tr><td><code>F1</code></td><td>打开帮助</td></tr><tr><td><code>Alt + E</code></td><td>打开“设置及更多”菜单</td></tr><tr><td><code>Alt + F</code></td><td>打开“设置及更多”菜单</td></tr></tbody></table> </div> </details><details class="folding-tag" green><summary> 搜索查找快捷键 </summary> <div class='content'> <table><thead><tr><th>快捷键</th><th>功能</th></tr></thead><tbody><tr><td><code>Ctrl + Shift + E</code></td><td>在边栏中打开搜索</td></tr><tr><td><code>Ctrl + F</code></td><td>在页面上打开查找</td></tr><tr><td><code>Ctrl + G</code></td><td>跳转到下一个结果以在页面上查找</td></tr><tr><td><code>Ctrl + Shift + G</code></td><td>跳转到上一个结果以在页面上查找</td></tr><tr><td><code>Ctrl + Shift + L</code></td><td>粘贴并搜索或粘贴并访问(如果它是 URL)</td></tr></tbody></table> </div> </details><details class="folding-tag" green><summary> PDF快捷键 </summary> <div class='content'> <table><thead><tr><th>快捷键</th><th>功能</th></tr></thead><tbody><tr><td><code>Ctrl + \\</code></td><td>在“根据页面调整”与“根据宽度调整”之间切换 PDF</td></tr><tr><td><code>Ctrl + [</code></td><td>将 PDF 逆时针旋转 90 度</td></tr><tr><td><code>Ctrl + ]</code></td><td>将 PDF 顺时针旋转 90 度</td></tr></tbody></table> </div> </details><details class="folding-tag" green><summary> 其他快捷键 </summary> <div class='content'> <table><thead><tr><th>快捷键</th><th>功能</th></tr></thead><tbody><tr><td><code>Alt + Shift + I</code></td><td>打开“发送反馈”对话框</td></tr><tr><td><code>Ctrl + J</code></td><td>打开“下载”文件夹</td></tr><tr><td><code>Ctrl + Shift + M</code></td><td>以其他用户身份登录或以来宾身份浏览</td></tr><tr><td><code>Ctrl + O</code></td><td>在 Microsoft Edge 中打开计算机中的文件</td></tr><tr><td><code>Ctrl + P</code></td><td>打印当前页</td></tr><tr><td><code>Ctrl + Shift + P</code></td><td>使用系统对话框打印</td></tr><tr><td><code>Ctrl + Shift + U</code></td><td>开始或停止“大声朗读”</td></tr><tr><td><code>Ctrl + Shift + V</code></td><td>不带格式粘贴</td></tr><tr><td><code>Ctrl + Shift + Y</code></td><td>打开集合</td></tr><tr><td><code>Alt</code></td><td>将焦点放在“设置及更多”按钮上</td></tr><tr><td><code>F10</code></td><td>将焦点放在“设置及更多”按钮上</td></tr><tr><td><code>F10 + Enter</code></td><td>打开“设置及更多”菜单</td></tr><tr><td><code>Shift + F10</code></td><td>打开上下文菜单</td></tr><tr><td><code>空格键</code></td><td>向下滚动网页,一次滚动一个屏幕</td></tr><tr><td><code>Shift + 空格键</code></td><td>向上滚动网页,一次滚动一个屏幕</td></tr><tr><td><code>PgDn</code></td><td>向下滚动网页,一次滚动一个屏幕</td></tr><tr><td><code>Ctrl + PgDn</code></td><td>切换到下一个标签页</td></tr><tr><td><code>PgUp</code></td><td>向上滚动网页,一次滚动一个屏幕</td></tr><tr><td><code>Ctrl + PgUp</code></td><td>切换到上一个标签页</td></tr><tr><td><code>Home 键</code></td><td>转到页面顶部,将键盘焦点移动到窗格的第一项</td></tr><tr><td><code>End</code></td><td>转到页面底部,将键盘焦点移动到窗格的最后一项</td></tr><tr><td><code>Tab</code></td><td>转到下一个制表位</td></tr><tr><td><code>Shift + Tab</code></td><td>转到上一个制表位</td></tr></tbody></table> </div> </details></div><div class="tab-item-content" id="test4-3"><details class="folding-tag" ><summary> 常用快捷键 </summary> <div class='content'> <table><thead><tr><th>快捷键</th><th>功能描述</th></tr></thead><tbody><tr><td><code>Command-X</code></td><td>剪切所选项目并拷贝到剪贴板</td></tr><tr><td><code>Command-C</code></td><td>将所选项目拷贝到剪贴板,同样适用于“访达”中的文件</td></tr><tr><td><code>Command-V</code></td><td>将剪贴板的内容粘贴到当前文稿或App中,同样适用于“访达”中的文件</td></tr><tr><td><code>Command-Z</code></td><td>撤销上一个命令,随后按<code>Shift-Command-Z</code>来重做</td></tr><tr><td><code>Command-A</code></td><td>选择所有项目</td></tr><tr><td><code>Command-F</code></td><td>查找文稿中的项目或打开“查找”窗口</td></tr><tr><td><code>Command-G</code></td><td>再次查找:查找下一处之前找到的项目</td></tr><tr><td><code>Shift-Command-G</code></td><td>查找上一处之前找到的项目</td></tr><tr><td><code>Command-H</code></td><td>隐藏最前方App的窗口</td></tr><tr><td><code>Option-Command-H</code></td><td>查看最前方的App但隐藏所有其他App</td></tr><tr><td><code>Command-M</code></td><td>将最前方的窗口最小化至程序坞</td></tr><tr><td><code>Option-Command-M</code></td><td>最小化最前方App的所有窗口</td></tr><tr><td><code>Command-O</code></td><td>打开所选项目,或打开一个对话框以选择要打开的文件</td></tr><tr><td><code>Command-P</code></td><td>打印当前文稿</td></tr><tr><td><code>Command-S</code></td><td>存储当前文稿</td></tr><tr><td><code>Command-T</code></td><td>打开新标签页</td></tr><tr><td><code>Command-W</code></td><td>关闭最前方的窗口</td></tr><tr><td><code>Option-Command-W</code></td><td>关闭App的所有窗口</td></tr><tr><td><code>Option-Command-Esc</code></td><td>强制退出App</td></tr><tr><td><code>Command-空格键</code></td><td>显示或隐藏“聚焦”搜索栏</td></tr><tr><td><code>Command–Option–空格键</code></td><td>从“访达”窗口进行“聚焦”搜索</td></tr><tr><td><code>Control-Command-空格键</code></td><td>显示字符检视器,选取表情符号和其他符号</td></tr><tr><td><code>Control-Command-F</code></td><td>以全屏幕模式使用App(如果App支持)</td></tr><tr><td><code>空格键</code></td><td>使用“快速查看”来预览所选项目</td></tr><tr><td><code>Command-Tab</code></td><td>在打开的各个App中切换到下一个最近使用的App</td></tr><tr><td><code>Command-重音符 (\</code>)`</td><td>在当前所用App的各个窗口之间切换</td></tr><tr><td><code>Shift-Command-5</code></td><td>截屏或录屏(macOS Mojave或更高版本)</td></tr><tr><td><code>Shift-Command-3</code> 或 <code>Shift-Command-4</code></td><td>截屏(使用不同方法)</td></tr><tr><td><code>Shift-Command-N</code></td><td>在“访达”中创建一个新文件夹</td></tr><tr><td><code>Command-逗号 (,)</code></td><td>打开最前方App的偏好设置</td></tr></tbody></table> </div> </details><details class="folding-tag" ><summary> 睡眠、退出登录和关机快捷键 </summary> <div class='content'> <table><thead><tr><th>快捷键</th><th>功能描述</th></tr></thead><tbody><tr><td><code>电源按钮</code></td><td>开机或唤醒Mac,按住1.5秒使Mac进入睡眠状态,长按强制关机</td></tr><tr><td><code>Option-Command-电源按钮</code> 或 <code>Option-Command-介质推出键</code></td><td>将Mac置于睡眠状态</td></tr><tr><td><code>Control-Shift-电源按钮</code> 或 <code>Control-Shift-介质推出键</code></td><td>将显示器置于睡眠状态</td></tr><tr><td><code>Control-电源按钮</code> 或 <code>Control-介质推出键</code></td><td>显示对话框,询问重新启动、睡眠还是关机</td></tr><tr><td><code>Control-Command-电源按钮</code></td><td>强制Mac重新启动,不提示存储未存储的文稿</td></tr><tr><td><code>Control-Command-介质推出键</code></td><td>退出所有App,然后重新启动Mac,提示存储未存储的更改</td></tr><tr><td><code>Control-Option-Command-电源按钮</code> 或 <code>Control-Option-Command-介质推出键</code></td><td>退出所有App,然后将Mac关机,提示存储未存储的更改</td></tr><tr><td><code>Control-Command-Q</code></td><td>立即锁定屏幕</td></tr><tr><td><code>Shift-Command-Q</code></td><td>退出登录macOS用户账户,系统将提示确认</td></tr><tr><td><code>Option-Shift-Command-Q</code></td><td>不确认的情况下立即退出登录</td></tr></tbody></table> </div> </details><details class="folding-tag" ><summary> 辅助快捷键 </summary> <div class='content'> <table><thead><tr><th>快捷键</th><th>功能描述</th></tr></thead><tbody><tr><td><code>Control-Option-Command-8</code></td><td>反转颜色</td></tr><tr><td><code>Control-Option-Command-逗号</code></td><td>降低对比度</td></tr><tr><td><code>Control-Option-Command-句点</code></td><td>增强对比度</td></tr><tr><td><code>Control-F2</code></td><td>将焦点移到菜单栏</td></tr><tr><td><code>Fn-Control-F2</code></td><td>将焦点移到菜单栏</td></tr><tr><td><code>Control-F3</code></td><td>将焦点移到程序坞</td></tr><tr><td><code>Fn-Control-F3</code></td><td>将焦点移到程序坞</td></tr><tr><td><code>Control-F4</code></td><td>将焦点移到活跃窗口或下一个窗口</td></tr><tr><td><code>Fn-Control-F4</code></td><td>将焦点移到活跃窗口或下一个窗口</td></tr><tr><td><code>Control-F5</code></td><td>将焦点移到窗口工具栏</td></tr><tr><td><code>Fn-Control-F5</code></td><td>将焦点移到窗口工具栏</td></tr><tr><td><code>Control-F6</code></td><td>将焦点移到浮动窗口</td></tr><tr><td><code>Fn-Control-F6</code></td><td>将焦点移到浮动窗口</td></tr><tr><td><code>Control-Shift-F6</code></td><td>将焦点移到上一个面板</td></tr><tr><td><code>Control-F7</code></td><td>更改 Tab 键移动焦点的方式——浏览屏幕上的所有控制,或仅浏览文本框和列表</td></tr><tr><td><code>Fn-Control-F7</code></td><td>更改 Tab 键移动焦点的方式——浏览屏幕上的所有控制,或仅浏览文本框和列表</td></tr><tr><td><code>Control-F8</code></td><td>将焦点移到菜单栏中的状态菜单</td></tr><tr><td><code>Fn-Control-F8</code></td><td>将焦点移到菜单栏中的状态菜单</td></tr><tr><td><code>Command–重音符</code></td><td>激活最前方 App 中下一个打开的窗口</td></tr><tr><td><code>Shift–Command–重音符</code></td><td>激活最前方 App 中上一个打开的窗口</td></tr><tr><td><code>Option–Command–重音符</code></td><td>将焦点移到窗口抽屉</td></tr><tr><td><code>Tab</code></td><td>移到下一个控制</td></tr><tr><td><code>Shift-Tab</code></td><td>移到上一个控制</td></tr><tr><td><code>Control-Tab</code></td><td>选定文本栏时移到下一个控制</td></tr><tr><td><code>Control-Shift-Tab</code></td><td>移到上一组控制</td></tr><tr><td><code>箭头键</code></td><td>移到列表、标签页组或菜单中的相邻项,或移动滑块和调整器(上箭头可增大值,下箭头可减小值)</td></tr><tr><td><code>Control–箭头键</code></td><td>移到与文本栏相邻的控制</td></tr></tbody></table> </div> </details><details class="folding-tag" ><summary> 系统快捷键 </summary> <div class='content'> <table><thead><tr><th>快捷键</th><th>功能描述</th></tr></thead><tbody><tr><td><code>Command-D</code></td><td>复制所选文件</td></tr><tr><td><code>Command-E</code></td><td>推出所选磁盘或宗卷</td></tr><tr><td><code>Command-F</code></td><td>在“访达”窗口中启动“聚焦”搜索</td></tr><tr><td><code>Command-I</code></td><td>显示所选文件的“显示简介”窗口</td></tr><tr><td><code>Command-R</code></td><td>显示所选替身对应的原始文件/刷新页面/重新检查软件更新</td></tr><tr><td><code>Shift-Command-C</code></td><td>打开“电脑”窗口</td></tr><tr><td><code>Shift-Command-D</code></td><td>打开“桌面”文件夹</td></tr><tr><td><code>Shift-Command-F</code></td><td>打开“最近使用”窗口</td></tr><tr><td><code>Shift-Command-G</code></td><td>打开“前往文件夹”窗口</td></tr><tr><td><code>Shift-Command-H</code></td><td>打开当前 macOS 用户账户的个人文件夹</td></tr><tr><td><code>Shift-Command-I</code></td><td>打开 iCloud 云盘</td></tr><tr><td><code>Shift-Command-K</code></td><td>打开“网络”窗口</td></tr><tr><td><code>Option-Command-L</code></td><td>打开“下载”文件夹</td></tr><tr><td><code>Shift-Command-N</code></td><td>新建文件夹</td></tr><tr><td><code>Shift-Command-O</code></td><td>打开“文稿”文件夹</td></tr><tr><td><code>Shift-Command-P</code></td><td>在“访达”窗口中显示或隐藏预览面板</td></tr><tr><td><code>Shift-Command-R</code></td><td>打开“隔空投送”窗口</td></tr><tr><td><code>Shift-Command-T</code></td><td>显示或隐藏“访达”窗口中的标签页栏</td></tr><tr><td><code>Control-Shift-Command-T</code></td><td>将所选的“访达”项目添加到程序坞</td></tr><tr><td><code>Shift-Command-U</code></td><td>打开“实用工具”文件夹</td></tr><tr><td><code>Option-Command-D</code></td><td>显示或隐藏程序坞</td></tr><tr><td><code>Control-Command-T</code></td><td>将所选项目添加到边栏</td></tr><tr><td><code>Option-Command-P</code></td><td>隐藏或显示“访达”窗口中的路径栏</td></tr><tr><td><code>Option-Command-S</code></td><td>隐藏或显示“访达”窗口中的边栏</td></tr><tr><td><code>Command–斜线 (/)</code></td><td>隐藏或显示“访达”窗口中的状态栏</td></tr><tr><td><code>Command-J</code></td><td>显示“显示”选项</td></tr><tr><td><code>Command-K</code></td><td>打开“连接服务器”窗口</td></tr><tr><td><code>Control-Command-A</code></td><td>为所选项目制作替身</td></tr><tr><td><code>Command-N</code></td><td>打开一个新的“访达”窗口</td></tr><tr><td><code>Option-Command-N</code></td><td>新建一个智能文件夹</td></tr><tr><td><code>Command-T</code></td><td>显示或隐藏标签页栏(当前窗口中只有一个标签页)</td></tr><tr><td><code>Option-Command-T</code></td><td>显示或隐藏工具栏(当前窗口中只有一个标签页)</td></tr><tr><td><code>Option-Command-V</code></td><td>将剪贴板中的文件从原始位置移动到当前位置</td></tr><tr><td><code>Command-Y</code></td><td>使用“快速查看”预览所选文件</td></tr><tr><td><code>Option-Command-Y</code></td><td>快速查看所选文件的幻灯片放映</td></tr><tr><td><code>Command-1</code></td><td>以图标方式显示“访达”窗口中的项目</td></tr><tr><td><code>Command-2</code></td><td>以列表方式显示“访达”窗口中的项目</td></tr><tr><td><code>Command-3</code></td><td>以分栏方式显示“访达”窗口中的项目</td></tr><tr><td><code>Command-4</code></td><td>以画廊方式显示“访达”窗口中的项目</td></tr><tr><td><code>Command-左中括号 ([)</code></td><td>前往上一个文件夹</td></tr><tr><td><code>Command-右中括号 (])</code></td><td>前往下一个文件夹</td></tr><tr><td><code>Command-上箭头</code></td><td>打开包含当前文件夹的文件夹</td></tr><tr><td><code>Command-Control-上箭头</code></td><td>在一个新窗口中打开包含当前文件夹的文件夹</td></tr><tr><td><code>Command-下箭头</code></td><td>打开所选项目</td></tr><tr><td><code>右箭头</code></td><td>打开所选文件夹(列表视图)</td></tr><tr><td><code>左箭头</code></td><td>关闭所选文件夹(列表视图)</td></tr><tr><td><code>Command-Delete</code></td><td>将所选项目移到废纸篓</td></tr><tr><td><code>Shift-Command-Delete</code></td><td>清倒废纸篓</td></tr><tr><td><code>Option-Shift-Command-Delete</code></td><td>清倒废纸篓而不显示确认对话框</td></tr><tr><td><code>Command-调低亮度键</code></td><td>打开或关闭视频镜像功能(多台显示器)</td></tr><tr><td><code>Option-调高亮度键</code></td><td>打开“显示器”偏好设置</td></tr><tr><td><code>Control-调高亮度键</code> 或 <code>Control-调低亮度键</code></td><td>更改外接显示器的亮度(支持的显示器)</td></tr><tr><td><code>Option-Shift-调高亮度键</code> 或 <code>Option-Shift-调低亮度键</code></td><td>以较小幅度调节显示器亮度</td></tr><tr><td><code>Option-调度中心键</code></td><td>打开“调度中心”偏好设置</td></tr><tr><td><code>Command-调度中心键</code></td><td>显示桌面</td></tr><tr><td><code>Control-下箭头</code></td><td>显示最前面的 App 的所有窗口</td></tr><tr><td><code>Option-调高音量键</code></td><td>打开“声音”偏好设置。这个快捷键可与任一音量键搭配使用</td></tr><tr><td><code>Option-Shift-调高音量键</code></td><td>以较小的幅度调节音量</td></tr><tr><td><code>Option-Shift-调低音量键</code></td><td>以较小的幅度调节音量</td></tr><tr><td><code>Option-键盘调高亮度键</code></td><td>打开“键盘”偏好设置。这个快捷键可与任一键盘亮度键搭配使用</td></tr><tr><td><code>Option-Shift-键盘调高亮度键</code></td><td>以较小的幅度调节键盘亮度</td></tr><tr><td><code>Option-Shift-键盘调低亮度键</code></td><td>以较小的幅度调节键盘亮度</td></tr><tr><td><code>按住 Option 键连按</code></td><td>在单独的窗口中打开项目,然后关闭原始窗口</td></tr><tr><td><code>按住 Command 键连按</code></td><td>在单独的标签页或窗口中打开文件夹</td></tr><tr><td><code>按住 Command 键拖移到另一个宗卷</code></td><td>将拖移的项目移到另一个宗卷,而不是拷贝它</td></tr><tr><td><code>按住 Option 键拖移</code></td><td>拷贝拖移的项目。拖移项目时,指针会发生变化</td></tr><tr><td><code>按住 Option-Command 键拖移</code></td><td>为拖移的项目制作替身。拖移项目时,指针会发生变化</td></tr><tr><td><code>按住 Option 键点按开合三角</code></td><td>打开所选文件夹内的所有文件夹。这个快捷键仅在列表视图中有效</td></tr><tr><td><code>按住 Command 键点按窗口标题</code></td><td>查看包含当前文件夹的文件夹</td></tr></tbody></table> </div> </details><details class="folding-tag" ><summary> 文稿快捷键 </summary> <div class='content'> <table><thead><tr><th>快捷键</th><th>功能描述</th></tr></thead><tbody><tr><td><code>Command-B</code></td><td>以粗体显示所选文本,或者打开或关闭粗体显示功能</td></tr><tr><td><code>Command-I</code></td><td>以斜体显示所选文本,或者打开或关闭斜体显示功能</td></tr><tr><td><code>Command-K</code></td><td>添加网页链接</td></tr><tr><td><code>Command-U</code></td><td>对所选文本加下划线,或者打开或关闭加下划线功能</td></tr><tr><td><code>Command-T</code></td><td>显示或隐藏“字体”窗口</td></tr><tr><td><code>Command-D</code></td><td>从“打开”对话框或“存储”对话框内选择“桌面”文件夹</td></tr><tr><td><code>Control-Command-D</code></td><td>显示或隐藏所选字词的定义</td></tr><tr><td><code>Shift-Command-冒号</code></td><td>显示“拼写和语法”窗口</td></tr><tr><td><code>Command-分号</code></td><td>查找文稿中拼写错误的字词</td></tr><tr><td><code>Option-Delete</code></td><td>删除插入点左边的字词</td></tr><tr><td><code>Control-H</code></td><td>删除插入点左边的字符。也可以使用 <code>Delete</code> 键</td></tr><tr><td><code>Control-D</code></td><td>删除插入点右边的字符。也可以使用 <code>Fn-Delete</code></td></tr><tr><td><code>Fn-Delete</code></td><td>在没有向前删除键的键盘上向前删除。也可以使用 <code>Control-D</code></td></tr><tr><td><code>Control-K</code></td><td>删除插入点与行或段落末尾之间的文本</td></tr><tr><td><code>Fn-上箭头</code></td><td>Page Up:向上滚动一页</td></tr><tr><td><code>Fn-下箭头</code></td><td>Page Down:向下滚动一页</td></tr><tr><td><code>Fn-左箭头</code></td><td>Home:滚动到文稿开头</td></tr><tr><td><code>Fn-右箭头</code></td><td>End:滚动到文稿末尾</td></tr><tr><td><code>Command-上箭头</code></td><td>将插入点移至文稿开头</td></tr><tr><td><code>Command-下箭头</code></td><td>将插入点移至文稿末尾</td></tr><tr><td><code>Command-左箭头</code></td><td>将插入点移至当前行的行首</td></tr><tr><td><code>Command-右箭头</code></td><td>将插入点移至当前行的行尾</td></tr><tr><td><code>Option-左箭头</code></td><td>将插入点移至上一字词的词首</td></tr><tr><td><code>Option-右箭头</code></td><td>将插入点移至下一字词的词尾</td></tr><tr><td><code>Shift-Command-上箭头</code></td><td>选中插入点与文稿开头之间的文本</td></tr><tr><td><code>Shift-Command-下箭头</code></td><td>选中插入点与文稿末尾之间的文本</td></tr><tr><td><code>Shift-Command-左箭头</code></td><td>选中插入点与当前行行首之间的文本</td></tr><tr><td><code>Shift-Command-右箭头</code></td><td>选中插入点与当前行行尾之间的文本</td></tr><tr><td><code>Shift-上箭头</code></td><td>将文本选择范围扩展到上一行相同水平位置的最近字符处</td></tr><tr><td><code>Shift-下箭头</code></td><td>将文本选择范围扩展到下一行相同水平位置的最近字符处</td></tr><tr><td><code>Shift-左箭头</code></td><td>将文本选择范围向左扩展一个字符</td></tr><tr><td><code>Shift-右箭头</code></td><td>将文本选择范围向右扩展一个字符</td></tr><tr><td><code>Option-Shift-上箭头</code></td><td>将文本选择范围扩展到当前段落的段首,再按一次则扩展到下一段落的段首</td></tr><tr><td><code>Option-Shift-下箭头</code></td><td>将文本选择范围扩展到当前段落的段尾,再按一次则扩展到下一段落的段尾</td></tr><tr><td><code>Option-Shift-左箭头</code></td><td>将文本选择范围扩展到当前字词的词首,再按一次则扩展到下一字词的词首</td></tr><tr><td><code>Option-Shift-右箭头</code></td><td>将文本选择范围扩展到当前字词的词尾,再按一次则扩展到下一字词的词尾</td></tr><tr><td><code>Control-A</code></td><td>移至行或段落的开头</td></tr><tr><td><code>Control-E</code></td><td>移至行或段落的末尾</td></tr><tr><td><code>Control-F</code></td><td>向前移动一个字符</td></tr><tr><td><code>Control-B</code></td><td>向后移动一个字符</td></tr><tr><td><code>Control-L</code></td><td>将光标或所选内容置于可见区域中央</td></tr><tr><td><code>Control-P</code></td><td>上移一行</td></tr><tr><td><code>Control-N</code></td><td>下移一行</td></tr><tr><td><code>Control-O</code></td><td>在插入点后新插入一行</td></tr><tr><td><code>Control-T</code></td><td>将插入点后面的字符与插入点前面的字符交换</td></tr><tr><td><code>Command-左花括号</code></td><td>左对齐</td></tr><tr><td><code>Command-右花括号</code></td><td>右对齐</td></tr><tr><td><code>Shift-Command-竖线</code></td><td>居中对齐</td></tr><tr><td><code>Option-Command-F</code></td><td>前往搜索栏</td></tr><tr><td><code>Option-Command-T</code></td><td>显示或隐藏 App 中的工具栏</td></tr><tr><td><code>Option-Command-V</code></td><td>粘贴样式:将拷贝的样式应用到所选项目</td></tr><tr><td><code>Option-Shift-Command-V</code></td><td>粘贴并匹配样式:对粘贴在某一内容中的项目应用周围内容的样式</td></tr><tr><td><code>Option-Command-I</code></td><td>显示或隐藏检查器窗口</td></tr><tr><td><code>Shift-Command-P</code></td><td>页面设置:显示用于选择文稿设置的窗口</td></tr><tr><td><code>Shift-Command-S</code></td><td>显示“存储为”对话框或复制当前文稿</td></tr><tr><td><code>Shift-Command-减号</code></td><td>缩小所选项目</td></tr><tr><td><code>Shift-Command-加号</code></td><td>放大所选项目。<code>Command-等号 (=)</code> 可实现相同的功能</td></tr><tr><td><code>Shift-Command-问号</code></td><td>打开“帮助”菜单</td></tr></tbody></table> </div> </details></div></div><div class="tab-to-top"><button type="button" aria-label="scroll to top"><i class="anzhiyufont anzhiyu-icon-arrow-up"></i></button></div></div>]]></content>
<categories>
<category> 工具 </category>
</categories>
<tags>
<tag> windows </tag>
<tag> mac </tag>
</tags>
</entry>
<entry>
<title>索引下推</title>
<link href="/4c2a.html"/>
<url>/4c2a.html</url>
<content type="html"><![CDATA[<h1>什么是索引下推?(index condition pushdown)</h1><p>索引下推是MySQL中的一种查询优化技术,主要用于提高查询效率。它允许MySQL在存储引擎层使用索引来过滤数据,而不是将所有数据从存储引擎传输到服务器层 后再进行过滤。这样可以减少不必要的数据传输,从而提高查询性能。</p><h2 id="前期准备">前期准备</h2><ul><li>创建表</li></ul><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">CREATE</span> <span class="keyword">TABLE</span> orders (</span><br><span class="line"> id <span class="type">INT</span> <span class="keyword">PRIMARY</span> KEY, <span class="comment">-- 主键索引</span></span><br><span class="line"> user_id <span class="type">INT</span>, <span class="comment">-- 用户ID</span></span><br><span class="line"> status <span class="type">VARCHAR</span>(<span class="number">10</span>), <span class="comment">-- 订单状态</span></span><br><span class="line"> created_at DATETIME, <span class="comment">-- 创建时间</span></span><br><span class="line"> amount <span class="type">DECIMAL</span>(<span class="number">10</span>,<span class="number">2</span>), <span class="comment">-- 订单金额</span></span><br><span class="line"> INDEX idx_orders (user_id, status, created_at) <span class="comment">-- 联合索引</span></span><br><span class="line">);</span><br></pre></td></tr></table></figure><ul><li>查询语句</li></ul><figure class="highlight sql"><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">SELECT</span> <span class="operator">*</span> <span class="keyword">FROM</span> orders </span><br><span class="line"><span class="keyword">WHERE</span> user_id <span class="operator">=</span> <span class="number">100</span> <span class="keyword">AND</span> status <span class="operator">=</span> <span class="string">'shipped'</span> <span class="keyword">AND</span> created_at <span class="operator">></span> <span class="string">'2024-01-01'</span>;</span><br></pre></td></tr></table></figure><h2 id="SQL的执行逻辑">SQL的执行逻辑</h2><p>MySQL底层一共分为四层</p><ul><li>连接层(Client Connectors):负责客户端与 MySQL 的通信(如 TCP/IP、Socket 等),处理连接、认证、权限校验等。</li><li>服务层(Server Layer):解析 SQL、优化执行计划、调用存储引擎接口。</li><li>存储引擎层(Storage Engine Layer):负责数据的存储和检索,支持插件式引擎(如 InnoDB、MyISAM)。</li><li>文件系统层(File System):存储数据文件(.ibd、.frm)、日志文件(redo log、binlog)等物理文件。</li></ul><figure class="highlight plaintext"><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><br><span class="line"> ↓ 建立连接、发送 SQL</span><br><span class="line">连接层(认证、权限校验、连接池管理)</span><br><span class="line"> │</span><br><span class="line"> ↓ 传递 SQL</span><br><span class="line">服务层(解析器 → 优化器 → 执行器)</span><br><span class="line"> │</span><br><span class="line"> ↓ 调用存储引擎接口</span><br><span class="line">存储引擎层(InnoDB/MyISAM 读写数据)(回表)</span><br><span class="line"> │</span><br><span class="line"> ↓ 操作磁盘文件</span><br><span class="line">文件系统层(.ibd/.frm 文件、日志文件)</span><br><span class="line"> │</span><br><span class="line"> ↑ 返回数据</span><br><span class="line">存储引擎层 → 服务层 → 连接层 → 客户端</span><br></pre></td></tr></table></figure><p>MySQL 的查询执行过程可以分为 <mark class="hl-label green">解析、优化、执行</mark> 三个阶段。我们主要关注 执行阶段,并结合 索引下推 进行分析。</p><h3 id="1-判断索引的使用">1. 判断索引的使用</h3><p>MySQL 需要决定使用哪个索引,这里 WHERE 条件涉及 (user_id, status, created_at) 这三个列,而 idx_orders 这个索引正好覆盖了 user_id、status 和 created_at,所以 会使用该索引。</p><ul><li>索引匹配规则(最左前缀匹配):</li></ul><blockquote><p>user_id = 100 可用索引 ✅<br>status = ‘shipped’ 可用索引 ✅<br>created_at > ‘2024-01-01’ 也可用索引(但范围查询会影响索引使用)</p></blockquote><p>因此,MySQL 选择 idx_orders 索引,并按以下步骤执行。</p><h3 id="2-具体执行步骤">2. 具体执行步骤</h3><ul><li><p>步骤 1:索引扫描</p><ul><li>MySQL 先利用 B+树索引,找到 user_id = 100 的数据范围。</li><li>然后在这个范围内,再筛选 status = ‘shipped’ 的记录。</li><li>如果<mark class="hl-label red">没有索引下推</mark> ,此时 MySQL 只会基于 user_id 和 status 进行索引扫描,找到符合条件的行,但 created_at > ‘2024-01-01’ 这个条件会在<mark class="hl-label red">回表后</mark> 再筛选。</li></ul></li><li><p>步骤 2:<mark class="hl-label orange">索引下推(如果启用)</mark> </p><ul><li>如果 MySQL 启用了索引下推(ICP),它会在索引扫描阶段就应用 created_at > ‘2024-01-01’ 的过滤条件</li><li>只有满足 user_id = 100、status = ‘shipped’ 且 created_at > ‘2024-01-01’ 的行会进入下一步,避免了不必要的回表操作。</li></ul></li><li><p>步骤 3:回表(如果需要): <em>回表指的是如果索引列不完全包含所查询的字段,就需要回表,补全查询字段,然后返回</em></p><ul><li>由于 SELECT * 需要查询所有列(而索引 idx_orders 只包含 (user_id, status, created_at)),所以 MySQL 需要通过 主键回表 查询完整的行数据。</li><li>但 索引下推减少了不必要的回表,只对满足所有索引列筛选条件的行执行回表,从而提高了查询效率。</li></ul></li><li><p>步骤 4:返回数据</p><ul><li>读取回表数据后,MySQL 生成最终的结果集并返回给客户端。</li></ul></li></ul><h2 id="总结"><code>总结*</code></h2><h3 id="索引下推发生的条件">索引下推发生的条件</h3><ul><li>使用了<mark class="hl-label blue">二级索引</mark> (非主键索引)</li><li>查询条件涉及<mark class="hl-label blue">索引列</mark> </li><li>查询的字段<mark class="hl-label blue">不完全包含在索引中</mark> (可能回表)<ul><li>如果查询字段包含在索引中,是否使用索引下推执行效率都是一样的,因为不需要回表</li></ul></li><li>索引列的筛选条件是<mark class="hl-label blue">范围查询</mark> (>, <, BETWEEN) 或 LIKE ‘xxx%’</li><li>数据库版本大于等于5.7</li></ul><h3 id="如何判断是否使用索引下推">如何判断是否使用索引下推</h3><p>使用EXPLAIN查询分析计划,查看Extra列,如果包含<code>Using index condition</code>说明使用了索引下推</p><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></pre></td><td class="code"><pre><span class="line"><span class="comment">-- 查询</span></span><br><span class="line"><span class="keyword">SHOW</span> VARIABLES <span class="keyword">LIKE</span> <span class="string">'optimizer_switch'</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">-- 开(全局)</span></span><br><span class="line"><span class="keyword">SET</span> <span class="keyword">GLOBAL</span> optimizer_switch <span class="operator">=</span> <span class="string">'index_condition_pushdown=on'</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">-- 关(全局)</span></span><br><span class="line"><span class="keyword">SET</span> <span class="keyword">GLOBAL</span> optimizer_switch <span class="operator">=</span> <span class="string">'index_condition_pushdown=off'</span>;</span><br></pre></td></tr></table></figure>]]></content>
<categories>
<category> 技术教程 </category>
</categories>
<tags>
<tag> MYSQL </tag>
</tags>
</entry>
<entry>
<title>JAVA表达式解析器———EvalEx</title>
<link href="/8a0c.html"/>
<url>/8a0c.html</url>
<content type="html"><![CDATA[<h1>java表达式解析器(支持自定义函数以及操作符)</h1><h2 id="说明">说明</h2><div class="note info no-icon flat"><p>下面的工具类适用于类似这种表达式 <strong>VAR(‘001d’)+VAR(‘test1’)</strong> 的解析,需要自定义函数并且函数还附<strong>带字符串等非数字类型</strong>的参数</p><h3 id="执行逻辑">执行逻辑</h3><ol><li>接受一个需要计算的表达式以及计算表达式所需要的参数信息(参数可空),获取传入参数的方式<mark class="hl-label green">FormalAnalysis.param.get()</mark></li><li>将函数中的字符串参数替换为纯数字参数 <strong>VAR(‘001d’)+VAR(‘test1’)</strong> -> <strong>VAR(1)+VAR(2)</strong>,并且记录改对应关系,在计算是自定替换为原始字符串参数</li><li>创建解析器Expression</li><li>使用SpringBoot的ApplicationContext获取对应的<strong>自定义函数和操作符</strong>,并添加到所创建的解析器中</li></ol><h3 id="优化">优化</h3><ol><li>工具类中使用的都是线程变量ThreadLocal,确保每个线程的参数以及映射信息都是独立的,并且在每次公式计算完毕进行清空</li><li>公式中还定义了搜集异常信息的list变量warnContent,如果想保留异常信息调用<mark class="hl-label green">FormalAnalysis.warnContent.get().add(异常信息)</mark> 进行存储,公式解析完毕会将该异常信息抛出</li><li>使用ApplicationContext自动获取自定义的函数和操作符,添加到表达式解析器中,无需手动添加</li></ol></div><h2 id="注意">注意</h2><div class="note danger no-icon flat"><p>一定要严格按照你自定义函数所配置的函数名称、参数个数以及自定义的操作符来编写表达式,也就是严格控制表达式的内容<br>如果表达式中出现了没有定义的其他函数或操作符,会直接报错</p></div><h2 id="1-引入依赖">1.引入依赖</h2><figure class="highlight java"><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"><dependency></span><br><span class="line"> <groupId>com.udojava</groupId></span><br><span class="line"> <artifactId>EvalEx</artifactId></span><br><span class="line"> <version><span class="number">2.7</span></version></span><br><span class="line"></dependency></span><br></pre></td></tr></table></figure><h2 id="2-关于自定义函数介绍">2.关于自定义函数介绍</h2><div class="note warning no-icon flat"><p>如果你解析的公式函数不包含参数或者你的参数为数字,那么你可以直接继承<mark class="hl-label purple">AbstractFunction</mark><br>如果你的自定义函数中包含的参数是字符串或者其他类型的信息,那么我建议你看下我写的自定义类<mark class="hl-label purple">CustomAbstractFunction</mark></p></div><h3 id="重写自定义函数父类">重写自定义函数父类</h3><figure class="highlight java"><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="keyword">public</span> <span class="keyword">abstract</span> <span class="keyword">class</span> <span class="title class_">CustomAbstractFunction</span> <span class="keyword">extends</span> <span class="title class_">AbstractFunction</span> {</span><br><span class="line"> <span class="meta">@Override</span></span><br><span class="line"> <span class="keyword">public</span> Expression.LazyNumber <span class="title function_">lazyEval</span><span class="params">(List<Expression.LazyNumber> lazyParams)</span> {</span><br><span class="line"> <span class="keyword">return</span> <span class="built_in">super</span>.lazyEval(lazyParams);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="keyword">public</span> String <span class="title function_">restoreOriginalString</span><span class="params">(Integer s)</span> {</span><br><span class="line"> <span class="keyword">return</span> FormalAnalysis.restoreOriginalString(s);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="keyword">protected</span> <span class="title function_">CustomAbstractFunction</span><span class="params">(String name, <span class="type">int</span> numParams)</span> {</span><br><span class="line"> <span class="built_in">super</span>(name, numParams);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="meta">@Override</span></span><br><span class="line"> <span class="keyword">public</span> BigDecimal <span class="title function_">eval</span><span class="params">(List<BigDecimal> parameters)</span> {</span><br><span class="line"> List<String> param = <span class="keyword">new</span> <span class="title class_">ArrayList</span><>();</span><br><span class="line"> <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i < parameters.size(); i++) {</span><br><span class="line"></span><br><span class="line"> <span class="comment">//兼容VAL BEG 和 END</span></span><br><span class="line"> <span class="keyword">if</span> (StrUtil.isEmpty(restoreOriginalString(parameters.get(i).intValue()))) {</span><br><span class="line"> param.add(i, parameters.get(i).toString());</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> <span class="type">String</span> <span class="variable">s</span> <span class="operator">=</span> restoreOriginalString(parameters.get(i).intValue());</span><br><span class="line"> param.add(i, s);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> customEval(param);</span><br><span class="line"> }</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"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> parameters 函数参数信息</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@return</span> 计算值</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"> <span class="keyword">public</span> BigDecimal <span class="title function_">customEval</span><span class="params">(List<String> parameters)</span> {</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">null</span>;</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br></pre></td></tr></table></figure><h3 id="自定义函数示例">自定义函数示例</h3><ul><li>customEval方法会自动将你的函数替换为原始字符串</li><li>创建完类你需要声明你的函数名称以及你的函数参数个数,-1代表参数个数不确定</li></ul><figure class="highlight java"><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="meta">@Component</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">VAR</span> <span class="keyword">extends</span> <span class="title class_">CustomAbstractFunction</span> {</span><br><span class="line"> <span class="keyword">public</span> <span class="title function_">VAR</span><span class="params">()</span> {</span><br><span class="line"> <span class="built_in">super</span>(<span class="string">"VAR"</span>, <span class="number">1</span>);</span><br><span class="line"> }</span><br><span class="line"> <span class="meta">@Override</span></span><br><span class="line"> <span class="keyword">public</span> BigDecimal <span class="title function_">customEval</span><span class="params">(List<String> parameters)</span> {</span><br><span class="line"></span><br><span class="line"> <span class="type">String</span> <span class="variable">p1</span> <span class="operator">=</span> parameters.get(<span class="number">0</span>);</span><br><span class="line"></span><br><span class="line"> <span class="comment">//这里写你自己的函数计算逻辑</span></span><br><span class="line"> </span><br><span class="line"> <span class="keyword">return</span> BigDecimal.ZERO;</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h2 id="3-关于自定义操作符的介绍">3.关于自定义操作符的介绍</h2><div class="note primary no-icon flat"><p>自定义操作符需要继承<mark class="hl-label purple">AbstractOperator</mark></p></div><h3 id="自定义操作符构造方法参数介绍">自定义操作符构造方法参数介绍</h3><table><thead><tr><th style="text-align:center">参数名</th><th style="text-align:center">类型</th><th>含义</th></tr></thead><tbody><tr><td style="text-align:center">oper</td><td style="text-align:center">String</td><td>操作符符号,例如 “+”、“-”、“*”、“/”。</td></tr><tr><td style="text-align:center">precedence</td><td style="text-align:center">int</td><td>操作符优先级,值越高优先级越高。例如 * 的优先级高于 +。</td></tr><tr><td style="text-align:center">leftAssoc</td><td style="text-align:center">boolean</td><td>操作符是否是<strong>左结合性</strong>,例如:+ 和 * 是左结合,^(幂运算)是右结合。</td></tr><tr><td style="text-align:center">booleanOperator</td><td style="text-align:center">boolean</td><td>是否是布尔操作符,布尔操作符处理 true/false 值,例如 && 和</td></tr><tr><td style="text-align:center">unaryOperator</td><td style="text-align:center">boolean</td><td>是否是<strong>一元操作符</strong>(只有一个操作数),例如 -a 中的 - 是一元操作符。</td></tr></tbody></table><h3 id="默认的符号优先级">默认的符号优先级</h3><table><thead><tr><th style="text-align:center">操作符</th><th>描述</th><th style="text-align:center">优先级 (precedence)</th><th style="text-align:center">结合性 (leftAssoc)</th></tr></thead><tbody><tr><td style="text-align:center">+</td><td>加法</td><td style="text-align:center">20</td><td style="text-align:center">true (左结合)</td></tr><tr><td style="text-align:center">-</td><td>减法</td><td style="text-align:center">20</td><td style="text-align:center">true (左结合)</td></tr><tr><td style="text-align:center">*</td><td>乘法</td><td style="text-align:center">30</td><td style="text-align:center">true (左结合)</td></tr><tr><td style="text-align:center">/</td><td>除法</td><td style="text-align:center">30</td><td style="text-align:center">true (左结合)</td></tr><tr><td style="text-align:center">^</td><td>幂运算</td><td style="text-align:center">40</td><td style="text-align:center">false(右结合)</td></tr></tbody></table><h3 id="自定义操作符示例">自定义操作符示例</h3><figure class="highlight java"><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><br><span class="line"><span class="meta">@Component</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">MaxOperator</span> <span class="keyword">extends</span> <span class="title class_">AbstractOperator</span> {</span><br><span class="line"> <span class="keyword">public</span> <span class="title function_">MaxOperator</span><span class="params">()</span> {</span><br><span class="line"> <span class="built_in">super</span>(<span class="string">">>"</span>, <span class="number">30</span>, <span class="literal">true</span>);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="meta">@Override</span></span><br><span class="line"> <span class="keyword">public</span> BigDecimal <span class="title function_">eval</span><span class="params">(BigDecimal v1, BigDecimal v2)</span> {</span><br><span class="line"> <span class="keyword">return</span> v1.max(v2);</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br></pre></td></tr></table></figure><h2 id="4-工具类">4.工具类</h2><h3 id="方法介绍">方法介绍</h3><ul><li>analysisCal<ul><li>公式解析工具类</li></ul></li><li>preprocessExpression<ul><li>用于将表达式函数中参数是<mark class="hl-label pink">字符串的参数替换为数字</mark> ,并且将对应关系存储到<mark class="hl-label pink">mapping</mark> 变量中</li></ul></li><li>restoreOriginalString<ul><li>还原被替换的参数信息</li></ul></li></ul><h3 id="工具类实现">工具类实现</h3><figure class="highlight java"><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><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Component</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">FormalAnalysis</span> {</span><br><span class="line"></span><br><span class="line"> <span class="comment">/**</span></span><br><span class="line"><span class="comment"> * key->id,value->字符串参数</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="keyword">public</span> <span class="keyword">static</span> <span class="keyword">final</span> ThreadLocal<Map<Integer, String>> mapping = ThreadLocal.withInitial(HashMap::<span class="keyword">new</span>);</span><br><span class="line"></span><br><span class="line"> <span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 测量点映射id</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"> <span class="keyword">private</span> <span class="keyword">static</span> <span class="keyword">final</span> ThreadLocal<Integer> placeholderCounter = ThreadLocal.withInitial(() -> <span class="number">0</span>);</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"><span class="comment"> */</span></span><br><span class="line"> <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">final</span> ThreadLocal<Map<String, Object>> param = ThreadLocal.withInitial(HashMap::<span class="keyword">new</span>);</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"><span class="comment"> */</span></span><br><span class="line"> <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">final</span> ThreadLocal<List<String>> warnContent = ThreadLocal.withInitial(ArrayList::<span class="keyword">new</span>);</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"><span class="comment"> */</span></span><br><span class="line"> <span class="meta">@Resource</span></span><br><span class="line"> <span class="keyword">private</span> ApplicationContext applicationContext;</span><br><span class="line"></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"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> formula 公式</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> param 取值所需要的参数</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"> <span class="keyword">public</span> BigDecimal <span class="title function_">analysisCal</span><span class="params">(String formula, Map<String, Object> param)</span> {</span><br><span class="line"> <span class="type">BigDecimal</span> <span class="variable">eval</span> <span class="operator">=</span> <span class="literal">null</span>;</span><br><span class="line"> <span class="keyword">try</span> {</span><br><span class="line"> FormalAnalysis.param.set(param);</span><br><span class="line"></span><br><span class="line"> formula = preprocessExpression(formula);</span><br><span class="line"> <span class="comment">// 创建表达式</span></span><br><span class="line"> <span class="type">Expression</span> <span class="variable">expression</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">Expression</span>(formula);</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"> <span class="comment">//添加自定义函数</span></span><br><span class="line"> Map<String, AbstractFunction> fun = applicationContext.getBeansOfType(AbstractFunction.class);</span><br><span class="line"> <span class="keyword">for</span> (AbstractFunction abstractFunction : fun.values()) {</span><br><span class="line"> expression.addFunction(abstractFunction);</span><br><span class="line"> }</span><br><span class="line"> <span class="comment">//添加自定义操作符</span></span><br><span class="line"> Map<String, AbstractOperator> oper = applicationContext.getBeansOfType(AbstractOperator.class);</span><br><span class="line"> <span class="keyword">for</span> (AbstractOperator abstractFunction : oper.values()) {</span><br><span class="line"> expression.addOperator(abstractFunction);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 计算公式</span></span><br><span class="line"> eval = expression.eval();</span><br><span class="line"> <span class="keyword">if</span> (CollUtil.isNotEmpty(warnContent.get())) {</span><br><span class="line"> <span class="keyword">throw</span> <span class="keyword">new</span> <span class="title class_">RuntimeException</span>(StringUtils.join(warnContent.get().stream().distinct().collect(Collectors.toList()), System.lineSeparator()));</span><br><span class="line"> }</span><br><span class="line"> } <span class="keyword">catch</span> (ArithmeticException e) {<span class="comment">//除零异常</span></span><br><span class="line"> <span class="keyword">if</span> (CollUtil.isNotEmpty(warnContent.get())) {</span><br><span class="line"> <span class="keyword">throw</span> <span class="keyword">new</span> <span class="title class_">RuntimeException</span>(StringUtils.join(warnContent.get().stream().distinct().collect(Collectors.toList()), System.lineSeparator()));</span><br><span class="line"> }</span><br><span class="line"> eval = BigDecimal.ZERO;</span><br><span class="line"> } <span class="keyword">finally</span> {</span><br><span class="line"> <span class="comment">// 计算结束,清空当前线程的局部变量</span></span><br><span class="line"> FormalAnalysis.mapping.remove();</span><br><span class="line"> FormalAnalysis.placeholderCounter.remove();</span><br><span class="line"> FormalAnalysis.warnContent.remove();</span><br><span class="line"> FormalAnalysis.param.remove();</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> eval.setScale(<span class="number">4</span>, RoundingMode.HALF_UP);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"></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"><span class="comment"> */</span></span><br><span class="line"> <span class="keyword">private</span> <span class="keyword">static</span> String <span class="title function_">preprocessExpression</span><span class="params">(String formula)</span> {</span><br><span class="line"></span><br><span class="line"> formula = formula.replace(ValParamEnum.BEG.getName(), ValParamEnum.BEG.getId().toString());</span><br><span class="line"> formula = formula.replace(ValParamEnum.END.getName(), ValParamEnum.END.getId().toString());</span><br><span class="line"></span><br><span class="line"> <span class="type">Pattern</span> <span class="variable">pattern</span> <span class="operator">=</span> Pattern.compile(<span class="string">"'([^']*)'"</span>);</span><br><span class="line"> <span class="type">Matcher</span> <span class="variable">matcher</span> <span class="operator">=</span> pattern.matcher(formula);</span><br><span class="line"> <span class="type">StringBuffer</span> <span class="variable">sb</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">StringBuffer</span>();</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 每找到一个匹配项,就生成一个占位符,并将原始字符串存入映射</span></span><br><span class="line"> <span class="keyword">while</span> (matcher.find()) {</span><br><span class="line"> <span class="type">String</span> <span class="variable">originalString</span> <span class="operator">=</span> matcher.group(<span class="number">1</span>);</span><br><span class="line"> placeholderCounter.set(placeholderCounter.get() + <span class="number">1</span>);</span><br><span class="line"> mapping.get().put(placeholderCounter.get(), originalString);</span><br><span class="line"> matcher.appendReplacement(sb, placeholderCounter.get() + <span class="string">""</span>);</span><br><span class="line"> }</span><br><span class="line"> matcher.appendTail(sb);</span><br><span class="line"> System.out.println(sb);</span><br><span class="line"> <span class="keyword">return</span> sb.toString();</span><br><span class="line"> }</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"><span class="comment"> */</span></span><br><span class="line"> <span class="keyword">public</span> <span class="keyword">static</span> String <span class="title function_">restoreOriginalString</span><span class="params">(Integer placeholder)</span> {</span><br><span class="line"> <span class="keyword">return</span> mapping.get().get(placeholder);</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br></pre></td></tr></table></figure><h2 id="5-使用示例">5.使用示例</h2><figure class="highlight java"><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></pre></td><td class="code"><pre><span class="line"><span class="meta">@RestController</span></span><br><span class="line"><span class="meta">@RequestMapping("formula")</span></span><br><span class="line"><span class="meta">@Api(tags = "公式测试")</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">FormalTestController</span> {</span><br><span class="line"></span><br><span class="line"> <span class="meta">@Resource</span></span><br><span class="line"> FormalAnalysis formalAnalysis;</span><br><span class="line"></span><br><span class="line"> <span class="meta">@GetMapping</span></span><br><span class="line"> <span class="meta">@ApiOperation("test")</span></span><br><span class="line"> <span class="keyword">public</span> ApiResponse <span class="title function_">test</span><span class="params">()</span> {</span><br><span class="line"> <span class="type">String</span> <span class="variable">formal</span> <span class="operator">=</span> <span class="string">"VAR('001d')+VAR('test1')"</span>;</span><br><span class="line"> <span class="type">BigDecimal</span> <span class="variable">bigDecimal</span> <span class="operator">=</span> formalAnalysis.analysisCal(formal, <span class="keyword">new</span> <span class="title class_">HashMap</span><>());</span><br><span class="line"> System.out.println(bigDecimal);</span><br><span class="line"> <span class="keyword">return</span> ApiResponse.succeed(bigDecimal);</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"></span><br></pre></td></tr></table></figure>]]></content>
<categories>
<category> 技术教程 </category>
</categories>
<tags>
<tag> JAVA </tag>
<tag> 工具类 </tag>
</tags>
</entry>
<entry>
<title>IDEA快捷键大全</title>
<link href="/dfd4.html"/>
<url>/dfd4.html</url>
<content type="html"><![CDATA[<h1>IDEA快捷键大全</h1><h2 id="Editing-编辑">Editing/编辑</h2><table><thead><tr><th style="text-align:left">快捷键</th><th style="text-align:left">介绍</th></tr></thead><tbody><tr><td style="text-align:left">Ctrl + Space</td><td style="text-align:left">Basic code completion (the name of any class, method or variable)基础代码补全,默认在 Windows 系统上被输入法占用,需要进行修改,建议修改为 Ctrl + 逗号</td></tr><tr><td style="text-align:left"><strong>Ctrl + Shift + Space</strong></td><td style="text-align:left">Smart code completion (filters the list of methods and variables by expected type)智能代码提示</td></tr><tr><td style="text-align:left">Ctrl + Shift + Enter</td><td style="text-align:left">Complete statement(自动结束代码,行末自动添加分号)</td></tr><tr><td style="text-align:left">Ctrl + P</td><td style="text-align:left">Parameter info (within method call arguments)方法参数提示显示</td></tr><tr><td style="text-align:left">Ctrl + Q</td><td style="text-align:left">Quick documentation lookup(光标所在的变量 / 类名 / 方法名等上面(也可以在提示补充的时候按),显示文档内容)</td></tr><tr><td style="text-align:left">Shift + F1</td><td style="text-align:left">External Doc/如果有外部文档可以连接外部文档</td></tr><tr><td style="text-align:left">Ctrl +光标悬浮</td><td style="text-align:left">Brief Info/按 Ctrl 不要松开,会显示光标所在的类信息摘要</td></tr><tr><td style="text-align:left">Ctrl + F1</td><td style="text-align:left">Show descriptions of error or warning at caret/在光标所在的错误代码出显示错误信息</td></tr><tr><td style="text-align:left"><strong>Alt + Insert</strong></td><td style="text-align:left">Generate code… (Getters, Setters, Constructors, hashCode/equals, toString)代码自动生成,如生成对象的 set / get 方法,构造函数,toString() 等</td></tr><tr><td style="text-align:left">Ctrl + O</td><td style="text-align:left">Override methods/选择可重写的方法</td></tr><tr><td style="text-align:left">Ctrl + I</td><td style="text-align:left">Implement methods/选择可继承的方法</td></tr><tr><td style="text-align:left">Ctrl + Alt + T</td><td style="text-align:left">Surroundwith…(if…else,try…catch, for, synchronized, etc.)对选中的代码弹出环绕选项弹出层</td></tr><tr><td style="text-align:left"><strong>Ctrl + /</strong></td><td style="text-align:left">Comment/uncomment with line comment/注释光标所在行代码,会根据当前不同文件类型使用不同的注释符号</td></tr><tr><td style="text-align:left"><strong>Ctrl + Shift + /</strong></td><td style="text-align:left">Comment/uncomment with block comment/代码块注释</td></tr><tr><td style="text-align:left">Ctrl + W</td><td style="text-align:left">Select successively increasing code blocks/递进式选择代码块。可选中光标所在的单词或段落,连续按会在原有选中的基础上再扩展选中范围</td></tr><tr><td style="text-align:left">Ctrl + Shift + W</td><td style="text-align:left">Decrease current selection to previous state/递进式取消选择代码块。可选中光标所在的单词或段落,连续按会在原有选中的基础上再扩展取消选中范围</td></tr><tr><td style="text-align:left">Alt + Q</td><td style="text-align:left">Context info/弹出一个提示,显示当前类的声明 / 上下文信息</td></tr><tr><td style="text-align:left"><strong>Alt + Enter</strong></td><td style="text-align:left">Show intention actions and quick-fixes/根据光标所在问题,提供快速修复选择,光标放在的位置不同提示的结果也不同</td></tr><tr><td style="text-align:left"><strong>Ctrl + Alt + L</strong></td><td style="text-align:left">Reformat code/格式化代码,可以对当前文件和整个包目录使用</td></tr><tr><td style="text-align:left">Ctrl + Alt + O</td><td style="text-align:left">Optimize imports/优化导入的类,可以对当前文件和整个包目录使用</td></tr><tr><td style="text-align:left">Ctrl + Alt + I</td><td style="text-align:left">Auto-indent line(s)光标所在行 或 选中部分进行自动代码缩进,有点类似格式化</td></tr><tr><td style="text-align:left">Tab / Shift + Tab</td><td style="text-align:left">Indent/unindent selected lines/缩进/取消缩进选定的行</td></tr><tr><td style="text-align:left">Ctrl+X</td><td style="text-align:left">Cut current line or selected block to clipboard/将当前行或选定块剪切到剪贴板</td></tr><tr><td style="text-align:left">Ctrl+C</td><td style="text-align:left">Copy current line or selected block to clipboard/将当前行或选定块复制到剪贴板</td></tr><tr><td style="text-align:left">Ctrl+V</td><td style="text-align:left">Paste from clipboard/从剪贴板粘贴</td></tr><tr><td style="text-align:left">Ctrl+Shift + V</td><td style="text-align:left">Paste from recent bu"ers…/粘贴从最近的但是…</td></tr><tr><td style="text-align:left">Ctrl+D</td><td style="text-align:left">Duplicate current line or selected block/复制光标所在行 或 复制选择内容,并把复制内容插入光标位置下面</td></tr><tr><td style="text-align:left">Ctrl+Y</td><td style="text-align:left">Delete line at caret/删除光标所在行 或 删除选中的行</td></tr><tr><td style="text-align:left">Ctrl+Shift + J</td><td style="text-align:left">Smart line join</td></tr><tr><td style="text-align:left"><strong>Ctrl+Enter</strong></td><td style="text-align:left">Smart line split/智能分隔行</td></tr><tr><td style="text-align:left">Shift + Enter</td><td style="text-align:left">Start new line/开始新一行。光标所在行下空出一行,光标定位到新行位置</td></tr><tr><td style="text-align:left">Ctrl + Shift + U</td><td style="text-align:left">Toggle case for word at caret or selected block/对选中的代码进行大 / 小写轮流转换</td></tr><tr><td style="text-align:left">Ctrl + Shift + ]/[</td><td style="text-align:left">Select till code block end/start(选择直到代码块结束/开始)</td></tr><tr><td style="text-align:left">Ctrl + Delete/Backspace</td><td style="text-align:left">Delete to word end/start(删除到单词结束/开始)</td></tr><tr><td style="text-align:left">Ctrl + NumPad+/-</td><td style="text-align:left">Expand/collapse code block(展开/折叠代码块)</td></tr><tr><td style="text-align:left">Ctrl + Shift+NumPad+</td><td style="text-align:left">Expand all(全部展开)</td></tr><tr><td style="text-align:left">Ctrl + Shift+NumPad-</td><td style="text-align:left">Collapse all(全部折叠)</td></tr><tr><td style="text-align:left">Ctrl + F4</td><td style="text-align:left">Close active editor tab(关闭活动编辑器选项卡)</td></tr></tbody></table><h2 id="Usage-Search-使用搜索">Usage Search/使用搜索</h2><table><thead><tr><th style="text-align:left">快捷键</th><th style="text-align:left">介绍</th></tr></thead><tbody><tr><td style="text-align:left">Alt + F7/Ctrl + F7</td><td style="text-align:left">Find usages/Find usages in file(查找光标所在的方法 / 变量 / 类被调用的地方)</td></tr><tr><td style="text-align:left">Ctrl + Shift + F7</td><td style="text-align:left">Highlight usages in file(高亮显示所有该选中文本,按Esc高亮消失)</td></tr><tr><td style="text-align:left">Ctrl + Alt + F7</td><td style="text-align:left">Show usages(显示使用的地方。寻找被该类或是变量被调用的地方,用弹出框的方式找出来)</td></tr></tbody></table><h2 id="Navigation-导航">Navigation/导航</h2><table><thead><tr><th style="text-align:left">快捷键</th><th style="text-align:left">介绍</th></tr></thead><tbody><tr><td style="text-align:left"><strong>Ctrl + N</strong></td><td style="text-align:left">Go to class(根据输入的 类名 查找类文件)</td></tr><tr><td style="text-align:left">Ctrl + Shift + N</td><td style="text-align:left">Go to file(通过文件名定位 / 打开文件 / 目录,打开目录需要在输入的内容后面多加一个正斜杠)</td></tr><tr><td style="text-align:left">Ctrl + Alt + Shift + N</td><td style="text-align:left">Go to symbol(转到符号)</td></tr><tr><td style="text-align:left">Alt + Right/Left</td><td style="text-align:left">Go to next / previous editor tab(按右方向切换当前已打开的文件视图/按左方向切换当前已打开的文件视图)</td></tr><tr><td style="text-align:left">F12</td><td style="text-align:left">Go back to previous tool window(回到前一个工具窗口)</td></tr><tr><td style="text-align:left">Esc</td><td style="text-align:left">Go to editor (from tool window)从工具窗口进入代码文件窗口</td></tr><tr><td style="text-align:left">Shift + Esc</td><td style="text-align:left">Hide active or last active window(隐藏当前 或 最后一个激活的工具窗口)</td></tr><tr><td style="text-align:left">Ctrl+Shift+F4</td><td style="text-align:left">Close active run messages/find /…tab(关闭活动运行消息/查找/…选项卡)</td></tr><tr><td style="text-align:left">Ctrl+G</td><td style="text-align:left">Go to line(转到行)</td></tr><tr><td style="text-align:left">Ctrl+E</td><td style="text-align:left">Recent files popup(可以显示最近编辑的文件列表)</td></tr><tr><td style="text-align:left">Ctrl+Alt + Left/Right</td><td style="text-align:left">Navigate back/forward(退回到上一个操作的地方/前进到上一个操作的地方)</td></tr><tr><td style="text-align:left">Ctrl+Shift+Backspace</td><td style="text-align:left">Navigate to last edit location(可以跳转到上次编辑的地方)</td></tr><tr><td style="text-align:left">Alt + F1</td><td style="text-align:left">Select current file or symbol in any view(显示当前文件选择目标弹出层,弹出层中有很多目标可以进行选择)</td></tr><tr><td style="text-align:left">Ctrl + B , Ctrl + Click</td><td style="text-align:left">Go to declaration(进入光标所在的方法/变量的接口或是定义出,等效于 Ctrl + 左键单击)</td></tr><tr><td style="text-align:left">Ctrl + Alt + B</td><td style="text-align:left">Go to implementation(s)在某个调用的方法名上使用会跳到具体的实现处,可以跳过接口</td></tr><tr><td style="text-align:left">Ctrl + Shift + I</td><td style="text-align:left">Open quick definition lookup(快速查看光标所在的方法 或 类的定义)</td></tr><tr><td style="text-align:left">Ctrl + Shift + B</td><td style="text-align:left">Go to type declaration(跳转到类型声明处)</td></tr><tr><td style="text-align:left">Ctrl + U</td><td style="text-align:left">Go to super-method super-class(前往当前光标所在的方法的父类的方法 / 接口定义)</td></tr><tr><td style="text-align:left">Alt + Up/Down</td><td style="text-align:left">Go to previous/next method(当前光标跳转到当前文件的前一个方法名位置/当前光标跳转到当前文件的后一个方法名位置)</td></tr><tr><td style="text-align:left">Ctrl + ]/[</td><td style="text-align:left">Move to code block end/start(移动光标到当前所在代码的花括号结束位置/移动光标到当前所在代码的花括号开始位置)</td></tr><tr><td style="text-align:left">Ctrl + F12</td><td style="text-align:left">File structure popup(弹出当前文件结构层,可以在弹出的层上直接输入,进行筛选)</td></tr><tr><td style="text-align:left">Ctrl + H</td><td style="text-align:left">Type hierarchy(显示当前类的层次结构)</td></tr><tr><td style="text-align:left">Ctrl + Shift + H</td><td style="text-align:left">Method hierarchy(显示方法层次结构)</td></tr><tr><td style="text-align:left"><strong>Ctrl + Alt + H</strong></td><td style="text-align:left">Call hierarchy(调用层次)</td></tr><tr><td style="text-align:left"><strong>F2 / Shift + F2</strong></td><td style="text-align:left">Next/previous highlighted error(跳转到上一个高亮错误 或 警告位置)</td></tr><tr><td style="text-align:left">F4 / Ctrl + Enter</td><td style="text-align:left">Edit source View source(编辑源)</td></tr><tr><td style="text-align:left">Alt + Home</td><td style="text-align:left">Show navigation bar(定位 / 显示到当前文件的 Navigation Bar)</td></tr><tr><td style="text-align:left">F11</td><td style="text-align:left">Toggle bookmark(添加书签)</td></tr><tr><td style="text-align:left">Ctrl + F11</td><td style="text-align:left">Toggle bookmark with mnemonic(选中文件 / 文件夹,使用助记符设定 / 取消书签)</td></tr><tr><td style="text-align:left">Ctrl + #[0-9]</td><td style="text-align:left">Go to numbered bookmark(定位到对应数值的书签位置)</td></tr><tr><td style="text-align:left">Shift + F11</td><td style="text-align:left">Show bookmarks(弹出书签显示层)</td></tr></tbody></table><h2 id="Search-Replace-搜索-替换">Search/Replace(搜索/替换)</h2><table><thead><tr><th style="text-align:left">快捷键</th><th style="text-align:left">介绍</th></tr></thead><tbody><tr><td style="text-align:left">Double Shift</td><td style="text-align:left">Search everywhere(弹出 Search Everywhere 弹出层)</td></tr><tr><td style="text-align:left"><strong>Ctrl + F</strong></td><td style="text-align:left">Find(查找)</td></tr><tr><td style="text-align:left"><strong>F3 / Shift + F3</strong></td><td style="text-align:left">Find next / Find previous(查找下一个/查找上一个)</td></tr><tr><td style="text-align:left"><strong>Ctrl + R</strong></td><td style="text-align:left">Replace(替换)</td></tr><tr><td style="text-align:left"><strong>Ctrl + Shift + F</strong></td><td style="text-align:left">Find in path(根据输入内容查找整个项目 或 指定目录内文件)</td></tr><tr><td style="text-align:left"><strong>Ctrl + Shift + R</strong></td><td style="text-align:left">Replace in path(根据输入内容替换对应内容,范围为整个项目 或 指定目录内文件)</td></tr></tbody></table><h2 id="Live-Templates-代码模板">Live Templates/代码模板</h2><table><thead><tr><th style="text-align:left">快捷键</th><th style="text-align:left">介绍</th></tr></thead><tbody><tr><td style="text-align:left">Ctrl + Alt + J</td><td style="text-align:left">Surround with Live Template(弹出模板选择窗口,讲选定的代码加入动态模板中)</td></tr><tr><td style="text-align:left">Ctrl + J</td><td style="text-align:left">Insert Live Template(插入自定义动态代码模板)</td></tr><tr><td style="text-align:left">iter</td><td style="text-align:left">Iteration according to Java SDK 1.5 style(根据Java SDK 1.5风格进行迭代)</td></tr><tr><td style="text-align:left">inst</td><td style="text-align:left">Checkobjecttype with instanceof and downcast it(用instanceof检查objecttype并将其向下转换)</td></tr><tr><td style="text-align:left">itco</td><td style="text-align:left">Iterate elements of java.util.Collection</td></tr><tr><td style="text-align:left">itit</td><td style="text-align:left">Iterate elements of java.util.Iterator</td></tr><tr><td style="text-align:left">itli</td><td style="text-align:left">Iterate elements of java.util.List</td></tr><tr><td style="text-align:left">psf</td><td style="text-align:left">public static final</td></tr><tr><td style="text-align:left">thr</td><td style="text-align:left">throw new</td></tr></tbody></table><h2 id="Refactoring-重构">Refactoring/重构</h2><table><thead><tr><th style="text-align:left">快捷键</th><th style="text-align:left">介绍</th></tr></thead><tbody><tr><td style="text-align:left">F5</td><td style="text-align:left">Copy</td></tr><tr><td style="text-align:left">F6</td><td style="text-align:left">Move</td></tr><tr><td style="text-align:left">Alt + Delete</td><td style="text-align:left">Safe Delete</td></tr><tr><td style="text-align:left"><strong>Shift + F6</strong></td><td style="text-align:left">Rename(重命名)</td></tr><tr><td style="text-align:left">Ctrl + F6</td><td style="text-align:left">Change Signature(更改签名)</td></tr><tr><td style="text-align:left">Ctrl + Alt + N</td><td style="text-align:left">Inline(行内)</td></tr><tr><td style="text-align:left"><strong>Ctrl + Alt + M</strong></td><td style="text-align:left">Extract Method(提取方法)</td></tr><tr><td style="text-align:left">Ctrl + Alt + V</td><td style="text-align:left">Extract Variable(提取变量)</td></tr><tr><td style="text-align:left">Ctrl + Alt + F</td><td style="text-align:left">Extract Field(提取字段)</td></tr><tr><td style="text-align:left">Ctrl + Alt + C</td><td style="text-align:left">Extract Constant(提取常量)</td></tr><tr><td style="text-align:left">Ctrl + Alt + P</td><td style="text-align:left">Extract Parameter(提取参数)</td></tr></tbody></table><h2 id="Debugging-调试">Debugging/调试</h2><table><thead><tr><th style="text-align:left">快捷键</th><th style="text-align:left">介绍</th></tr></thead><tbody><tr><td style="text-align:left"><strong>F8</strong></td><td style="text-align:left">Step over(在 Debug 模式下,进入下一步,如果当前行断点是一个方法,则不进入当前方法体内)</td></tr><tr><td style="text-align:left"><strong>F7</strong></td><td style="text-align:left">Step into(在 Debug 模式下,进入下一步,如果当前行断点是一个方法,则进入当前方法体内,如果该方法体还有方法,则不会进入该内嵌的方法中)</td></tr><tr><td style="text-align:left"><strong>Alt + F9</strong></td><td style="text-align:left">Run to cursor(运行到光标处,你可以将光标定位到你需要查看的行,然后使用这个功能,代码会运行到光标处,不需要打断点)</td></tr><tr><td style="text-align:left"><strong>Alt + F8</strong></td><td style="text-align:left">Evaluate expression(计算表达式的值)</td></tr><tr><td style="text-align:left"><strong>F9</strong></td><td style="text-align:left">Resume program(恢复程序,比如,你在第3行和5行各自都打了断点,当前运行到第3行,按F9,则运行到下一个断点即第5行,再按F9,则运行完整个流程,因为后面已经没有断点了)</td></tr><tr><td style="text-align:left">Ctrl + F8</td><td style="text-align:left">Toggle breakpoint(在 Debug 模式下,设置光标当前行为断点,如果当前已经是断点则去掉断点)</td></tr><tr><td style="text-align:left">Ctrl + Shift + F8</td><td style="text-align:left">View breakpoints(查看设置的所有断点)</td></tr></tbody></table><h2 id="Compile-and-Run-编译和运行">Compile and Run/编译和运行</h2><table><thead><tr><th style="text-align:left">快捷键</th><th style="text-align:left">介绍</th></tr></thead><tbody><tr><td style="text-align:left">Ctrl + F9</td><td style="text-align:left">Make project (compile modifed and dependent)重新编译和引入依赖</td></tr><tr><td style="text-align:left">Ctrl + Shift + F9</td><td style="text-align:left">Compile selected file, package or module(编译选中的文件 / 包 / 模块)</td></tr><tr><td style="text-align:left">Alt + Shift + F10/F9</td><td style="text-align:left">Select configuration and run/and debug(弹出 Run 的可选择菜单/弹出 Debug 的可选择菜单)</td></tr><tr><td style="text-align:left"><strong>Shift + F10/F9</strong></td><td style="text-align:left">Run/Debug(运行/调试)</td></tr><tr><td style="text-align:left">Ctrl + Shift + F10</td><td style="text-align:left">Run context configuration from editor(从编辑器运行上下文配置)</td></tr></tbody></table><h2 id="VCS-Local-History-版本控制-本地历史">VCS/Local History(版本控制/本地历史)</h2><table><thead><tr><th style="text-align:left">快捷键</th><th style="text-align:left">介绍</th></tr></thead><tbody><tr><td style="text-align:left">Ctrl + K / Ctrl + T</td><td style="text-align:left">Commit project to VCS/Update from VCS(版本控制提交项目/版本控制更新项目)</td></tr><tr><td style="text-align:left">Alt + Shift + C</td><td style="text-align:left">View recent changes(查看最近操作项目的变化情况列表)</td></tr><tr><td style="text-align:left">Alt + `</td><td style="text-align:left">VCS Operations Popup(显示版本控制常用操作菜单弹出层)</td></tr></tbody></table><h2 id="General-通用">General/通用</h2><table><thead><tr><th style="text-align:left">快捷键</th><th style="text-align:left">介绍</th></tr></thead><tbody><tr><td style="text-align:left">Alt + #[0-9]</td><td style="text-align:left">Open corresponding tool window(显示对应数值的选项卡,其中 1 是 Project 用得最多)</td></tr><tr><td style="text-align:left">Ctrl + S</td><td style="text-align:left">Save all(全部保存)</td></tr><tr><td style="text-align:left">Ctrl + Alt + Y</td><td style="text-align:left">Synchronize(同步、刷新)</td></tr><tr><td style="text-align:left">Ctrl + Shift + F12</td><td style="text-align:left">Toggle maximizing editor(编辑器最大化)</td></tr><tr><td style="text-align:left">Alt + Shift + F</td><td style="text-align:left">Add to Favorites(添加到收藏夹)</td></tr><tr><td style="text-align:left">Alt + Shift + I</td><td style="text-align:left">Inspect current file with current profile(查看项目当前文件)</td></tr><tr><td style="text-align:left">Ctrl + BackQuote (`)</td><td style="text-align:left">Quick switch current scheme(快捷切换键,可以切换主题、视图模式、快捷键组合)</td></tr><tr><td style="text-align:left">Ctrl + Alt + S</td><td style="text-align:left">Open Settings dialog(打开 IntelliJ IDEA 系统设置)</td></tr><tr><td style="text-align:left">Ctrl + Alt + Shift + S</td><td style="text-align:left">Open Project Structure dialog(打开项目结构面板)</td></tr><tr><td style="text-align:left">Ctrl + Shift + A</td><td style="text-align:left">Find Action(查找动作 / 设置)</td></tr><tr><td style="text-align:left"><strong>Ctrl + Tab</strong></td><td style="text-align:left">Switch between tabs and tool window(编辑窗口切换,如果在切换的过程又加按上delete,则是关闭对应选中的窗口)</td></tr></tbody></table>]]></content>
<categories>
<category> 工具 </category>
</categories>
<tags>
<tag> JAVA </tag>
<tag> IDEA </tag>
</tags>
</entry>
<entry>
<title>java随机数介绍以及生成随机日期</title>
<link href="/51a7.html"/>
<url>/51a7.html</url>
<content type="html"><![CDATA[<h1>生成一个随机日期</h1><figure class="highlight java"><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">static</span> Date <span class="title function_">randomTime</span><span class="params">(Date startTime, Date endTime)</span> {</span><br><span class="line"> <span class="comment">// 获取时间区间的起始毫秒值和结束毫秒值</span></span><br><span class="line"> <span class="type">long</span> <span class="variable">startMillis</span> <span class="operator">=</span> startTime.getTime();</span><br><span class="line"> <span class="type">long</span> <span class="variable">endMillis</span> <span class="operator">=</span> endTime.getTime();</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 使用 ThreadLocalRandom 在区间内生成一个随机的毫秒值</span></span><br><span class="line"> <span class="type">long</span> <span class="variable">randomMillis</span> <span class="operator">=</span> ThreadLocalRandom.current().nextLong(startMillis, endMillis);</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 返回一个新的随机时间</span></span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">Date</span>(randomMillis);</span><br><span class="line">}</span><br></pre></td></tr></table></figure><div class="note info no-icon flat"><p>工具类比较简单,这里就不多介绍了,这篇文章主要介绍一下java生成随机数的API</p></div><h1>JAVA生成随机数API</h1><h2 id="1-java-util-Random">1. java.util.Random</h2><p><strong>Random</strong> 是 Java 中最常用的随机数生成器,属于伪随机数生成器(PRNG)。<strong>Random</strong> 提供了一系列方法来生成不同类型的随机数。</p><figure class="highlight java"><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="type">Random</span> <span class="variable">random</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">Random</span>();</span><br><span class="line"><span class="type">int</span> <span class="variable">randomInt</span> <span class="operator">=</span> random.nextInt(); <span class="comment">// 生成随机整数</span></span><br><span class="line"><span class="type">int</span> <span class="variable">randomIntInRange</span> <span class="operator">=</span> random.nextInt(<span class="number">100</span>); <span class="comment">// 生成 0 到 99 之间的随机整数</span></span><br><span class="line"><span class="type">long</span> <span class="variable">randomLong</span> <span class="operator">=</span> random.nextLong(); <span class="comment">// 生成随机长整数</span></span><br><span class="line"><span class="type">double</span> <span class="variable">randomDouble</span> <span class="operator">=</span> random.nextDouble(); <span class="comment">// 生成 0.0 到 1.0 之间的随机小数</span></span><br><span class="line"></span><br></pre></td></tr></table></figure><h2 id="2-java-util-concurrent-ThreadLocalRandom">2. java.util.concurrent.ThreadLocalRandom</h2><p><strong>ThreadLocalRandom</strong> 是 <strong>Random</strong> 的线程安全版本,适合在多线程环境中使用。它的性能更好,因为它为每个线程创建一个独立的随机数生成器。</p><figure class="highlight java"><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="type">ThreadLocalRandom</span> <span class="variable">random</span> <span class="operator">=</span> ThreadLocalRandom.current();</span><br><span class="line"><span class="type">int</span> <span class="variable">randomInt</span> <span class="operator">=</span> random.nextInt(); <span class="comment">// 生成随机整数</span></span><br><span class="line"><span class="type">int</span> <span class="variable">randomIntInRange</span> <span class="operator">=</span> random.nextInt(<span class="number">100</span>); <span class="comment">// 生成 0 到 99 之间的随机整数</span></span><br><span class="line"><span class="type">long</span> <span class="variable">randomLong</span> <span class="operator">=</span> random.nextLong(); <span class="comment">// 生成随机长整数</span></span><br><span class="line"><span class="type">double</span> <span class="variable">randomDouble</span> <span class="operator">=</span> random.nextDouble(); <span class="comment">// 生成 0.0 到 1.0 之间的随机小数</span></span><br><span class="line"></span><br></pre></td></tr></table></figure><h2 id="3-java-security-SecureRandom">3. java.security.SecureRandom</h2><p><strong>SecureRandom</strong> 是专门设计用于生成加密强度的随机数。它比 Random 更安全,因为它使用的是加密算法生成的随机数,适合需要高安全性的场景,例如生成加密密钥、会话标识符等</p><figure class="highlight java"><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="type">SecureRandom</span> <span class="variable">secureRandom</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">SecureRandom</span>();</span><br><span class="line"><span class="type">int</span> <span class="variable">randomInt</span> <span class="operator">=</span> secureRandom.nextInt(); <span class="comment">// 生成随机整数</span></span><br><span class="line"><span class="type">int</span> <span class="variable">randomIntInRange</span> <span class="operator">=</span> secureRandom.nextInt(<span class="number">100</span>); <span class="comment">// 生成 0 到 99 之间的随机整数</span></span><br><span class="line"><span class="type">byte</span>[] bytes = <span class="keyword">new</span> <span class="title class_">byte</span>[<span class="number">16</span>];</span><br><span class="line">secureRandom.nextBytes(bytes); <span class="comment">// 生成随机字节数组</span></span><br><span class="line"></span><br></pre></td></tr></table></figure><h2 id="4-Math-random">4. Math.random()</h2><p><strong>Math.random()</strong> 是 Java 中生成 0.0 到 1.0 之间的双精度浮点数的简便方法,它是 <strong>Random</strong> 类的一个简化接口。<strong>Math.random()</strong> 内部实际上使用的是 <strong>Random</strong> 类的实例。</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"><span class="type">double</span> <span class="variable">randomDouble</span> <span class="operator">=</span> Math.random(); <span class="comment">// 生成 0.0 到 1.0 之间的随机小数</span></span><br><span class="line"></span><br></pre></td></tr></table></figure><h2 id="5-java-util-Random-ints-Java-8">5. java.util.Random#ints (Java 8+)</h2><p>从 <strong>Java 8</strong> 开始,<strong>Random</strong> 类新增了一些流式 <strong>API</strong>,可以用来生成随机数流,这对于生成一组随机数非常有用。</p><figure class="highlight java"><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="type">Random</span> <span class="variable">random</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">Random</span>();</span><br><span class="line"><span class="comment">// 生成一个包含 5 个随机整数的流</span></span><br><span class="line">random.ints(<span class="number">5</span>).forEach(System.out::println);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 生成指定范围内的随机整数流</span></span><br><span class="line">random.ints(<span class="number">5</span>, <span class="number">0</span>, <span class="number">100</span>).forEach(System.out::println);</span><br><span class="line"></span><br></pre></td></tr></table></figure><h2 id="总结">总结</h2><table><thead><tr><th style="text-align:left">随机数生成器</th><th>特点</th><th>适用场景</th><th>性能</th></tr></thead><tbody><tr><td style="text-align:left"><code>Random</code></td><td>伪随机数生成器,使用线性同余法,支持多种随机数类型生成。</td><td>普通单线程场景</td><td>中</td></tr><tr><td style="text-align:left"><code>ThreadLocalRandom</code></td><td>线程安全,性能优于 <code>Random</code>,适合多线程环境。</td><td>多线程场景</td><td>高</td></tr><tr><td style="text-align:left"><code>SecureRandom</code></td><td>安全性高,难以预测,适合加密、生成密钥等场景。</td><td>安全性要求高的场景(加密、认证等)</td><td>低</td></tr><tr><td style="text-align:left"><code>Math.random()</code></td><td>简单易用,只能生成 <code>0.0 - 1.0</code> 的 <code>double</code> 随机数。</td><td>生成简单的随机小数</td><td>中</td></tr><tr><td style="text-align:left"><code>Random#ints</code> (Java 8+)</td><td>支持流式生成随机数,适合生成多个随机数。</td><td>批量生成随机数</td><td>中</td></tr></tbody></table><h2 id="最后再说一下Hutool中的随机数API">最后再说一下<strong>Hutool</strong>中的随机数API</h2><p><strong>Hutool</strong> 库中的 <strong>RandomUtil</strong> 提供了一系列生成随机数的方法,它基于 <strong>JDK</strong> 的 <strong>ThreadLocalRandom</strong> 实现,因此具备线程安全、性能高效的特性。在性能和使用便捷性上,<strong>RandomUtil</strong> 与 <strong>JDK</strong> 原生的随机数生成工具相比,有一些优势,尤其是简化了常见的随机数生成操作。</p><figure class="highlight java"><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="comment">// 用法很多,这里简单写几个</span></span><br><span class="line"><span class="type">int</span> <span class="variable">randomInt</span> <span class="operator">=</span> RandomUtil.randomInt(); <span class="comment">// 生成一个随机整数</span></span><br><span class="line"><span class="type">int</span> <span class="variable">randomIntInRange</span> <span class="operator">=</span> RandomUtil.randomInt(<span class="number">100</span>); <span class="comment">// 生成 0 到 99 之间的随机整数</span></span><br><span class="line"><span class="type">long</span> <span class="variable">randomLong</span> <span class="operator">=</span> RandomUtil.randomLong(); <span class="comment">// 生成随机长整数</span></span><br><span class="line"><span class="type">String</span> <span class="variable">randomString</span> <span class="operator">=</span> RandomUtil.randomString(<span class="number">10</span>); <span class="comment">// 生成指定长度的随机字符串</span></span><br><span class="line"></span><br></pre></td></tr></table></figure><ul><li>用法很多,基本上我们常用的生成方式它都能提供</li><li>使用简单,无需创建对象,直接调用</li><li>不支持加密强度的随机数生成</li></ul>]]></content>
<categories>
<category> 技术教程 </category>
</categories>
<tags>
<tag> JAVA </tag>
<tag> 工具类 </tag>
</tags>
</entry>
<entry>
<title>JAVA工具类(一)——生成班次排班记录</title>
<link href="/3329.html"/>
<url>/3329.html</url>
<content type="html"><![CDATA[<h1>根据输入的时间以及日期间隔,输出每天的排班记录</h1><div class="note info no-icon flat"><p>假如你有这样一个需求:</p><ul><li>有一个排班信息,比如:白班(08:00:00 - 20:00:00),夜班(20:00:00 - 08:00:00)</li><li>我想获取到某个日期范围内的排班信息</li><li>那么就可以用这个工具类来实现</li></ul></div><h2 id="新建两个实体">新建两个实体</h2><ul><li>ShiftType</li></ul><figure class="highlight java"><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">@Data</span></span><br><span class="line"><span class="meta">@NoArgsConstructor</span></span><br><span class="line"><span class="meta">@AllArgsConstructor</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">ShiftType</span> {</span><br><span class="line"> <span class="keyword">private</span> LocalTime start;</span><br><span class="line"> <span class="keyword">private</span> LocalTime end;</span><br><span class="line"> <span class="keyword">private</span> String shiftName;</span><br><span class="line"></span><br><span class="line"> <span class="meta">@Override</span></span><br><span class="line"> <span class="keyword">public</span> String <span class="title function_">toString</span><span class="params">()</span> {</span><br><span class="line"> <span class="keyword">return</span> shiftName + <span class="string">":"</span> + start.toString() + <span class="string">" - "</span> + end.toString();</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><ul><li>Shift</li></ul><figure class="highlight java"><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">@Data</span></span><br><span class="line"><span class="meta">@NoArgsConstructor</span></span><br><span class="line"><span class="meta">@AllArgsConstructor</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Shift</span> {</span><br><span class="line"> <span class="keyword">private</span> LocalDateTime start;</span><br><span class="line"> <span class="keyword">private</span> LocalDateTime end;</span><br><span class="line"> <span class="keyword">private</span> String shiftName;</span><br><span class="line"></span><br><span class="line"> <span class="meta">@Override</span></span><br><span class="line"> <span class="keyword">public</span> String <span class="title function_">toString</span><span class="params">()</span> {</span><br><span class="line"> <span class="keyword">return</span> shiftName + <span class="string">":"</span> + start.toString() + <span class="string">" - "</span> + end.toString();</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h2 id="工具类实现">工具类实现</h2><figure class="highlight java"><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></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</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="comment"> * <span class="doctag">@param</span> startDate 开始日期</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> endDate 结束日期</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> shiftTypes 班次记录</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">static</span> List<Shift> <span class="title function_">generateShifts</span><span class="params">(LocalDate startDate, LocalDate endDate, List<ShiftType> shiftTypes)</span> {</span><br><span class="line"> List<Shift> shifts = <span class="keyword">new</span> <span class="title class_">ArrayList</span><>();</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 从开始日期到结束日期遍历</span></span><br><span class="line"> <span class="type">LocalDate</span> <span class="variable">currentDate</span> <span class="operator">=</span> startDate;</span><br><span class="line"> <span class="keyword">while</span> (currentDate.isBefore(endDate) || currentDate.isEqual(endDate)) {</span><br><span class="line"> <span class="keyword">for</span> (ShiftType shiftType : shiftTypes) {</span><br><span class="line"> <span class="type">LocalDateTime</span> <span class="variable">shiftStart</span> <span class="operator">=</span> LocalDateTime.of(currentDate, shiftType.getStart());</span><br><span class="line"> <span class="type">LocalDateTime</span> <span class="variable">shiftEnd</span> <span class="operator">=</span> shiftType.getEnd().isBefore(shiftType.getStart()) ?</span><br><span class="line"> LocalDateTime.of(currentDate.plusDays(<span class="number">1</span>), shiftType.getEnd()) :</span><br><span class="line"> LocalDateTime.of(currentDate, shiftType.getEnd());</span><br><span class="line"></span><br><span class="line"> shifts.add(<span class="keyword">new</span> <span class="title class_">Shift</span>(shiftStart, shiftEnd, shiftType.getShiftName()));</span><br><span class="line"> }</span><br><span class="line"> currentDate = currentDate.plusDays(<span class="number">1</span>);</span><br><span class="line"> }</span><br><span class="line"> <span class="comment">//排序</span></span><br><span class="line"> shifts.sort(Comparator.comparing(Shift::getStart));</span><br><span class="line"> <span class="keyword">return</span> shifts;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h2 id="测试">测试</h2><figure class="highlight java"><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 class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> {</span><br><span class="line"> ArrayList<ShiftType> shiftTypes = <span class="keyword">new</span> <span class="title class_">ArrayList</span><>();</span><br><span class="line"></span><br><span class="line"> shiftTypes.add(<span class="keyword">new</span> <span class="title class_">ShiftType</span>(LocalTime.parse(<span class="string">"00:00:00"</span>), LocalTime.parse(<span class="string">"08:00:00"</span>), <span class="string">"班次1"</span>));</span><br><span class="line"> shiftTypes.add(<span class="keyword">new</span> <span class="title class_">ShiftType</span>(LocalTime.parse(<span class="string">"16:00:00"</span>), LocalTime.parse(<span class="string">"00:00:00"</span>), <span class="string">"班次3"</span>));</span><br><span class="line"> shiftTypes.add(<span class="keyword">new</span> <span class="title class_">ShiftType</span>(LocalTime.parse(<span class="string">"08:00:00"</span>), LocalTime.parse(<span class="string">"16:00:00"</span>), <span class="string">"班次2"</span>));</span><br><span class="line"></span><br><span class="line"> List<Shift> shifts = ShiftDateUtils.generateShifts(LocalDate.parse(<span class="string">"2024-08-01"</span>), LocalDate.parse(<span class="string">"2024-08-03"</span>), shiftTypes);</span><br><span class="line"> System.out.println(shifts);</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h2 id="测试结果">测试结果</h2><figure class="highlight text"><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">[班次1:2024-08-01T00:00 - 2024-08-01T08:00, </span><br><span class="line">班次2:2024-08-01T08:00 - 2024-08-01T16:00, </span><br><span class="line">班次3:2024-08-01T16:00 - 2024-08-02T00:00, </span><br><span class="line">班次1:2024-08-02T00:00 - 2024-08-02T08:00, </span><br><span class="line">班次2:2024-08-02T08:00 - 2024-08-02T16:00, </span><br><span class="line">班次3:2024-08-02T16:00 - 2024-08-03T00:00, </span><br><span class="line">班次1:2024-08-03T00:00 - 2024-08-03T08:00, </span><br><span class="line">班次2:2024-08-03T08:00 - 2024-08-03T16:00, </span><br><span class="line">班次3:2024-08-03T16:00 - 2024-08-04T00:00]</span><br></pre></td></tr></table></figure>]]></content>
<categories>
<category> 技术教程 </category>
</categories>
<tags>
<tag> JAVA </tag>
<tag> 工具类 </tag>
</tags>
</entry>
<entry>
<title>Feign调用者如何配置全局Header参数?</title>
<link href="/43a1.html"/>
<url>/43a1.html</url>
<content type="html"><![CDATA[<h1>作为Feign的调用者,如何配置一个全局的Header呢?</h1><div class="note info no-icon flat"><p>前言:</p><ul><li>因为项目遇到了这个问题,就是作为<mark class="hl-label orange">Feign</mark> 的调用者,应该如何传递认证信息,因为是新项目,所以刚开始开发没有考虑这些,之后才发现会有这个问题</li><li>刚开始本来准备直接给每个<mark class="hl-label orange">Feign</mark> 方法添加一个用于认证的参数,但是发现这样改动量太大了,然后就开始查找资料</li><li>功夫不负有心人,还真被我找到了,就是今天要介绍的<mark class="hl-label orange">Feign</mark> 中用于构建和修改HTTP请求的一个核心类<mark class="hl-label green">RequestTemplate</mark></li></ul></div><h2 id="在我项目中的使用">在我项目中的使用</h2><div class="note success no-icon flat"><ul><li>创建一个FeignConfig的配置类,然后把下面的信息复制到类中即可</li><li>因为我目前的项目中只是用于添加一个Header参数,所以用的比较简单,就只是下面的几行代码</li></ul></div><figure class="highlight java"><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></pre></td><td class="code"><pre><span class="line">/</span><br><span class="line"> * feign全局处理器,自动添加header参数,无需手动传递租户信息</span><br><span class="line"> *</span><br><span class="line"> * <span class="meta">@Author</span> bo.chen</span><br><span class="line"> * <span class="meta">@Date</span> <span class="number">2024</span>/<span class="number">8</span>/<span class="number">12</span></span><br><span class="line"> */</span><br><span class="line"><span class="meta">@Configuration</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">FeignConfig</span> {</span><br><span class="line"></span><br><span class="line"> <span class="meta">@Bean</span></span><br><span class="line"> <span class="keyword">public</span> RequestInterceptor <span class="title function_">requestInterceptor</span><span class="params">()</span> {</span><br><span class="line"> <span class="keyword">return</span> requestTemplate -> {</span><br><span class="line"> requestTemplate.header(<span class="string">"tenantCode"</span>, <span class="string">"DEFAULT_GROUP"</span>);</span><br><span class="line"> };</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br></pre></td></tr></table></figure><div class="note no-icon flat"><p>作为Feign服务的提供者获取这个参数就比较简单了,使用<code>SpringBoot的http</code>请求的拦截器(<code>HandlerInterceptorAdapter</code>)即可获取到这个参数</p></div><h2 id="RequestTemplate详细介绍">RequestTemplate详细介绍</h2><h3 id="1-路径和-URI-相关方法">1. 路径和 URI 相关方法</h3><ul><li><p>设置请求的 URI 路径。</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">requestTemplate.uri(<span class="string">"/new-path"</span>);</span><br></pre></td></tr></table></figure></li><li><p>设置请求的方法(GET、POST、PUT 等)。</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">requestTemplate.method(<span class="string">"POST"</span>);</span><br></pre></td></tr></table></figure></li><li><p>添加查询参数(URL 参数)。</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">requestTemplate.query(<span class="string">"key"</span>, <span class="string">"value1"</span>, <span class="string">"value2"</span>);</span><br></pre></td></tr></table></figure></li><li><p>设置是否对 URL 中的斜杠进行解码。</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">requestTemplate.decodeSlash(<span class="literal">false</span>);</span><br></pre></td></tr></table></figure></li><li><p>使用传入的参数解析模板中的占位符。占位符的形式一般是 <code>{name}</code>。</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">requestTemplate.resolve(<span class="keyword">new</span> <span class="title class_">Object</span>[]{<span class="string">"value"</span>});</span><br></pre></td></tr></table></figure></li><li><p>设置请求的目标 URL,通常是基础 URL。</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">requestTemplate.target(<span class="string">"http://example.com"</span>);</span><br></pre></td></tr></table></figure></li></ul><h3 id="2-请求头相关方法">2. 请求头相关方法</h3><ul><li><p>添加或设置请求头。</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">requestTemplate.header(<span class="string">"Authorization"</span>, <span class="string">"Bearer token"</span>);</span><br></pre></td></tr></table></figure></li><li><p>获取当前请求头的 Map 结构。</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">Map<String, Collection<String>> headers = requestTemplate.headers();</span><br></pre></td></tr></table></figure></li><li><p>设置请求的字符集。</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">requestTemplate.requestCharset(StandardCharsets.UTF_8);</span><br></pre></td></tr></table></figure></li></ul><h3 id="3-请求体相关方法">3. 请求体相关方法</h3><ul><li><p>直接设置请求体的内容和字符集。</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">requestTemplate.body(<span class="string">"your request body"</span>.getBytes(), StandardCharsets.UTF_8);</span><br></pre></td></tr></table></figure></li><li><p>以字符串形式设置请求体内容。</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">requestTemplate.body(<span class="string">"your request body"</span>);</span><br></pre></td></tr></table></figure></li><li><p>使用模板字符串设置请求体,可以包括占位符,在 <code>resolve</code> 时替换。</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">requestTemplate.bodyTemplate(<span class="string">"This is a body template with {param}"</span>);</span><br></pre></td></tr></table></figure></li></ul><h3 id="4-请求方法相关">4. 请求方法相关</h3><ul><li><p>获取与当前模板关联的MethodMetadata ,其中包含有关方法的元信息。</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">MethodMetadata</span> <span class="variable">metadata</span> <span class="operator">=</span> requestTemplate.methodMetadata();</span><br></pre></td></tr></table></figure></li></ul><h3 id="5-克隆和复制">5. 克隆和复制</h3><ul><li><p>创建当前模板的副本。</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">RequestTemplate</span> <span class="variable">newTemplate</span> <span class="operator">=</span> requestTemplate.clone();</span><br></pre></td></tr></table></figure></li><li><p>使用另一个<mark class="hl-label green">RequestTemplate</mark> 替换当前模板的内容。</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">requestTemplate.replace(newTemplate);</span><br></pre></td></tr></table></figure></li></ul>]]></content>
<categories>
<category> 技术教程 </category>
</categories>
<tags>
<tag> Feign </tag>
</tags>
</entry>
<entry>
<title>window批量下载文件脚本分享</title>
<link href="/71f9.html"/>
<url>/71f9.html</url>
<content type="html"><![CDATA[<div class="note primary no-icon flat"><p>脚本说明</p><ul><li>将下面代码内容放到一个以<mark class="hl-label pink">bat</mark> 结尾的文件中</li><li>运行之前需要在脚本的同级目录创建一个<mark class="hl-label default">file.txt</mark> 文件,里面放你要下载的文件链接,一行一个</li><li>执行成功之后,文件会被下载到<mark class="hl-label blue">downloaded_file</mark> 文件夹中</li></ul></div><figure class="highlight bat"><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="built_in">echo</span> off</span><br><span class="line"><span class="built_in">setlocal</span> enabledelayedexpansion</span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">REM 设置包含URL列表的文件名</span></span><br><span class="line"><span class="built_in">set</span> "inputFile=file.txt"</span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">REM 设置下载目录</span></span><br><span class="line"><span class="built_in">set</span> "downloadDir=downloaded_file"</span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">REM 检查并创建下载目录</span></span><br><span class="line"><span class="keyword">if</span> <span class="keyword">not</span> <span class="keyword">exist</span> "<span class="variable">%downloadDir%</span>" (</span><br><span class="line"> <span class="built_in">mkdir</span> "<span class="variable">%downloadDir%</span>"</span><br><span class="line">)</span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">REM 读取文件并下载图片</span></span><br><span class="line"><span class="keyword">for</span> /f "delims=" <span class="variable">%%i</span> <span class="keyword">in</span> (<span class="variable">%inputFile%</span>) <span class="keyword">do</span> (</span><br><span class="line"><span class="comment"> REM 获取URL</span></span><br><span class="line"> <span class="built_in">set</span> "url=<span class="variable">%%i</span>"</span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment"> REM 提取文件名</span></span><br><span class="line"> <span class="keyword">for</span> <span class="variable">%%a</span> <span class="keyword">in</span> ("<span class="variable">!url!</span>") <span class="keyword">do</span> (</span><br><span class="line"> <span class="built_in">set</span> "fileName=<span class="variable">%%~</span>nxa"</span><br><span class="line"> )</span><br><span class="line"><span class="comment"> </span></span><br><span class="line"><span class="comment"> REM 使用PowerShell下载图片</span></span><br><span class="line"> powershell -Command "Invoke-WebRequest -Uri <span class="variable">!url!</span> -OutFile \"<span class="variable">%downloadDir%</span>\<span class="variable">!fileName!</span>\""</span><br><span class="line">)</span><br><span class="line"></span><br><span class="line"><span class="built_in">echo</span> 图片下载完成</span><br><span class="line"><span class="built_in">pause</span></span><br><span class="line"></span><br></pre></td></tr></table></figure>]]></content>
<categories>
<category> 技术教程 </category>
</categories>
<tags>
<tag> 脚本 </tag>
<tag> windows </tag>
</tags>
</entry>
<entry>
<title>解决Nacos使用达梦数据库报错问题(包括Nacos源码编译运行)</title>
<link href="/3e6a.html"/>
<url>/3e6a.html</url>
<content type="html"><![CDATA[<h1>nacos使用达梦数据库更新配置时报错问题解决</h1><div class="note no-icon flat"><ul><li><strong>有两个方案</strong></li></ul><ol><li>配置数据库插件</li><li>修改源码</li></ol><p>这篇文章主要介绍第二种,因为第一种没研究明白🐶</p></div><h2 id="报错信息">报错信息</h2><div class="note danger no-icon flat"><p>caused: PreparedStatementCallback;<br>违反表[CONFIG_INFO]唯一性约束条件[UK_CONFIGINFO_DATAGROUPTENANT];<br>nested exception is dm.jdbc.driver.DMException:<br>违反表[CONFIG_INFO]唯一性约束条件[UK_CONFIGINFO_DATAGROUPTENANT];<br>caused: 违反表[CONFIG_INFO]唯一性约束条件[UK_CONFIGINFO_DATAGROUPTENANT];</p></div><h2 id="方案一">方案一</h2><details class="folding-tag" yellow><summary> 方案一(未实现) </summary> <div class='content'> <ul><li>简单说一下方案一</li></ul><p>官方也提供了数据库插件的实现接口,下面是一个达梦数据库的实现插件</p><div calss='anzhiyu-tag-link'><a class="tag-Link" target="_blank" href="https://github.com/pig-mesh/nacos-datasource-plugin-dm8"> <div class="tag-link-tips">引用站外地址</div> <div class="tag-link-bottom"> <div class="tag-link-left" style="background-image: url(https://github.com/favicon.ico)"> <i class="anzhiyufont anzhiyu-icon-link" style="display: none"></i> </div> <div class="tag-link-right"> <div class="tag-link-title">nacos-datasource-plugin-dm8</div> <div class="tag-link-sitename">GitHub仓库地址</div> </div> <i class="anzhiyufont anzhiyu-icon-angle-right"></i> </div> </a></div>但是没研究明白怎么用,后期慢慢研究🤔 </div> </details><h2 id="方案二">方案二</h2><ul><li>这篇文章主要是用<mark class="hl-label blue">nacos-2.2.2</mark> 为例子,如果你使用的nacos配置完达梦数据库也报错,那你可以尝试修改一下,问题应该是一样的</li></ul><h3 id="1-下载nacos源码">1.下载nacos源码</h3><div class="btns rounded grid5"> <a class="button no-text-decoration" href='https://github.com/alibaba/nacos/releases' title='全部版本'><i class='anzhiyufont anzhiyu-icon-bolt'></i>全部版本</a><a class="button no-text-decoration" href='https://github.com/alibaba/nacos/releases/download/2.2.2/nacos-server-2.2.2.zip' title='下载2.2.2版本'><i class='anzhiyufont anzhiyu-icon-bolt'></i>下载2.2.2版本</a> </div><h3 id="2-运行源码">2.运行源码</h3><ul><li><strong>下载依赖</strong><br>这个就不用说了,配置一个国内的maven仓库地址,然后就是漫长的等待,等所有的依赖下载完</li></ul><figure class="highlight xml"><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="comment"><!--放一个阿里云的maven仓库地址--></span></span><br><span class="line"><span class="tag"><<span class="name">mirror</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">id</span>></span>aliyunmaven<span class="tag"></<span class="name">id</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">mirrorOf</span>></span>*<span class="tag"></<span class="name">mirrorOf</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">name</span>></span>阿里云公共仓库<span class="tag"></<span class="name">name</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">url</span>></span>https://maven.aliyun.com/repository/public<span class="tag"></<span class="name">url</span>></span></span><br><span class="line"><span class="tag"></<span class="name">mirror</span>></span></span><br></pre></td></tr></table></figure><h3 id="3-编译">3.编译</h3><p>有一些文件类是需要编译才能生成的,所以先不要着急运行,打开idea的maven菜单,运行<mark class="hl-label orange">compile</mark> ,会在target目录下生成所需的类文件</p><mark class="hl-label green">看到这个说明你编译成功了</mark> <details class="folding-tag" green><summary> 成功日志 </summary> <div class='content'> <figure class="highlight text"><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></pre></td><td class="code"><pre><span class="line">[INFO] Alibaba NACOS 2.2.2 ................................ SUCCESS [ 1.193 s]</span><br><span class="line">[INFO] nacos-api 2.2.2 .................................... SUCCESS [ 3.550 s]</span><br><span class="line">[INFO] nacos-common 2.2.2 ................................. SUCCESS [ 3.564 s]</span><br><span class="line">[INFO] nacos-consistency 2.2.2 ............................ SUCCESS [ 6.453 s]</span><br><span class="line">[INFO] nacos-plugin 2.2.2 ................................. SUCCESS [ 0.037 s]</span><br><span class="line">[INFO] nacos-auth-plugin 2.2.2 ............................ SUCCESS [ 0.436 s]</span><br><span class="line">[INFO] nacos-custom-environment-plugin 2.2.2 .............. SUCCESS [ 0.336 s]</span><br><span class="line">[INFO] nacos-sys 2.2.2 .................................... SUCCESS [ 0.824 s]</span><br><span class="line">[INFO] nacos-auth 2.2.2 ................................... SUCCESS [ 0.751 s]</span><br><span class="line">[INFO] nacos-trace-plugin 2.2.2 ........................... SUCCESS [ 0.324 s]</span><br><span class="line">[INFO] nacos-control-plugin 2.2.2 ......................... SUCCESS [ 0.684 s]</span><br><span class="line">[INFO] nacos-core 2.2.2 ................................... SUCCESS [ 3.467 s]</span><br><span class="line">[INFO] nacos-encryption-plugin 2.2.2 ...................... SUCCESS [ 0.347 s]</span><br><span class="line">[INFO] nacos-datasource-plugin 2.2.2 ...................... SUCCESS [ 0.645 s]</span><br><span class="line">[INFO] nacos-config 2.2.2 ................................. SUCCESS [ 4.616 s]</span><br><span class="line">[INFO] nacos-cmdb 2.2.2 ................................... SUCCESS [ 0.873 s]</span><br><span class="line">[INFO] nacos-naming 2.2.2 ................................. SUCCESS [ 4.033 s]</span><br><span class="line">[INFO] nacos-address 2.2.2 ................................ SUCCESS [ 1.025 s]</span><br><span class="line">[INFO] nacos-client 2.2.2 ................................. SUCCESS [ 2.302 s]</span><br><span class="line">[INFO] nacos-plugin-default-impl 2.2.2 .................... SUCCESS [ 1.639 s]</span><br><span class="line">[INFO] nacos-istio 2.2.2 .................................. SUCCESS [ 8.247 s]</span><br><span class="line">[INFO] nacos-prometheus 2.2.2 ............................. SUCCESS [ 0.965 s]</span><br><span class="line">[INFO] nacos-console 2.2.2 ................................ SUCCESS [ 1.905 s]</span><br><span class="line">[INFO] nacos-test 2.2.2 ................................... SUCCESS [ 0.093 s]</span><br><span class="line">[INFO] nacos-config-test 2.2.2 ............................ SUCCESS [ 0.102 s]</span><br><span class="line">[INFO] nacos-naming-test 2.2.2 ............................ SUCCESS [ 0.112 s]</span><br><span class="line">[INFO] nacos-core-test 2.2.2 .............................. SUCCESS [ 0.134 s]</span><br><span class="line">[INFO] nacos-example 2.2.2 ................................ SUCCESS [ 0.738 s]</span><br><span class="line">[INFO] nacos-distribution 2.2.2 ........................... SUCCESS [ 0.099 s]</span><br><span class="line">[INFO] ------------------------------------------------------------------------</span><br><span class="line">[INFO] BUILD SUCCESS</span><br><span class="line">[INFO] ------------------------------------------------------------------------</span><br><span class="line">[INFO] Total time: 49.896 s</span><br><span class="line">[INFO] Finished at: 2024-07-02T21:35:51+08:00</span><br><span class="line">[INFO] ------------------------------------------------------------------------</span><br><span class="line"></span><br></pre></td></tr></table></figure> </div> </details><h3 id="4-运行">4.运行</h3><p>如果运行还提示以下类找不到,那就刷新一下依赖信息</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> com.alibaba.nacos.consistency.entity.ReadRequest;</span><br><span class="line"><span class="keyword">import</span> com.alibaba.nacos.consistency.entity.Response;</span><br><span class="line"><span class="keyword">import</span> com.alibaba.nacos.consistency.entity.WriteRequest;</span><br></pre></td></tr></table></figure><p>打开<mark class="hl-label default">console</mark> 模块,运行里面的<mark class="hl-label default">main</mark> 方法</p><p>运行之前需要配置一个vm启动参数<mark class="hl-label pink">-Dnacos.standalone=true</mark> ,因为nacos默认是<mark class="hl-label pink">集群</mark> 方式启动,所以我们要指定<mark class="hl-label pink">单机</mark> 模式启动</p><p>如果运行没问题的话,打开<a href="http://127.0.0.1:8848/nacos/index.html">这个地址</a>你可以看到nacos的界面</p><div class="note success no-icon flat"><p>到这里你已经成功一半了U0001fae1</p></div><h3 id="5-修改源码">5.修改源码</h3><p>全局搜索ExternalConfigInfoPersistServiceImpl类,包名是这个</p><mark class="hl-label purple">com.alibaba.nacos.config.server.service.repository.extrnal.ExternalConfigInfoPersistServiceImpl</mark> <p>找到一下两段代码<strong>177行</strong>和<strong>194行</strong></p><figure class="highlight java"><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="meta">@Override</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">insertOrUpdate</span><span class="params">(String srcIp, String srcUser, ConfigInfo configInfo, Timestamp time,</span></span><br><span class="line"><span class="params"> Map<String, Object> configAdvanceInfo, <span class="type">boolean</span> notify)</span> {</span><br><span class="line"> <span class="keyword">try</span> {</span><br><span class="line"> addConfigInfo(srcIp, srcUser, configInfo, time, configAdvanceInfo, notify);</span><br><span class="line"> } <span class="keyword">catch</span> (DuplicateKeyException ive) { <span class="comment">// Unique constraint conflict </span></span><br><span class="line"> updateConfigInfo(configInfo, srcIp, srcUser, time, configAdvanceInfo, notify);</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="keyword">public</span> <span class="type">boolean</span> <span class="title function_">insertOrUpdateCas</span><span class="params">(String srcIp, String srcUser, ConfigInfo configInfo, Timestamp time,</span></span><br><span class="line"><span class="params"> Map<String, Object> configAdvanceInfo, <span class="type">boolean</span> notify)</span> {</span><br><span class="line"> <span class="keyword">try</span> {</span><br><span class="line"> addConfigInfo(srcIp, srcUser, configInfo, time, configAdvanceInfo, notify);</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line"> } <span class="keyword">catch</span> (DuplicateKeyException ignore) { <span class="comment">// Unique constraint conflict </span></span><br><span class="line"> <span class="keyword">return</span> updateConfigInfoCas(configInfo, srcIp, srcUser, time, configAdvanceInfo, notify);</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>把catch捕获的异常修改成<mark class="hl-label purple">DataIntegrityViolationException</mark> </p><div class="note info no-icon flat"><p><strong>解释</strong><br>因为mysql和达梦的驱动实现不一样,所以在插入一条已经存在的数据时,抛出的异常也不一样,所以导致了连接达梦数据库无法更新配置的问题</p><p>这里其实我也没理解为什么要通过异常捕获的方式来判断执行更新还是插入,可能是因为这样可以少执行一次查询吧</p></div><h3 id="6-引入依赖">6.引入依赖</h3><p>找到config模块对应的pom文件,加入达梦的驱动依赖</p><figure class="highlight xml"><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="tag"><<span class="name">dependency</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">groupId</span>></span>com.dameng<span class="tag"></<span class="name">groupId</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">artifactId</span>></span>DmJdbcDriver18<span class="tag"></<span class="name">artifactId</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">version</span>></span>版本号<span class="tag"></<span class="name">version</span>></span></span><br><span class="line"><span class="tag"></<span class="name">dependency</span>></span></span><br></pre></td></tr></table></figure><h3 id="7-修改配置文件">7.修改配置文件</h3><p>打开打开<mark class="hl-label default">console</mark> 模块的配置文件,加入以下配置</p><figure class="highlight properties"><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 class="comment">#这个配置加不加无所谓,不影响结果</span></span><br><span class="line"><span class="attr">spring.sql.init.platform</span>=<span class="string">dameng </span></span><br><span class="line"></span><br><span class="line"><span class="attr">db.num</span>=<span class="string">1</span></span><br><span class="line"><span class="attr">db.url.0</span>=<span class="string">jdbc:dm://localhost:5236</span></span><br><span class="line"><span class="attr">db.user.0</span>=<span class="string">nacos</span></span><br><span class="line"><span class="attr">db.password.0</span>=<span class="string">nacos</span></span><br><span class="line"><span class="comment"># 这里写你达梦驱动类</span></span><br><span class="line"><span class="attr">db.pool.config.driver-class-name</span>=<span class="string">dm.jdbc.driver.DmDriver</span></span><br></pre></td></tr></table></figure><div class="note success no-icon flat"><p>到这里正常情况下,你已经完成了90%,打开本地的nacos页面,报错的问题应该已经解决了</p></div><h3 id="8-打包">8.打包</h3><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></pre></td><td class="code"><pre><span class="line"><span class="meta prompt_"># </span><span class="language-bash">powershell执行</span></span><br><span class="line">mvn -Prelease-nacos -Dmaven.test.skip=true clean install -U</span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">cmd执行</span></span><br><span class="line">mvn -Prelease-nacos -DskipTests clean install -U</span><br></pre></td></tr></table></figure><p>上面两个命令根据窗口类型选择一个来执行,正常情况会在<mark class="hl-label green">distribution</mark> 模块下生成<mark class="hl-label green">nacos-server.jar</mark> ,然后就可以放到你的服务器运行啦🤫</p><details class="folding-tag" green><summary> 成功日志 </summary> <div class='content'> <figure class="highlight text"><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></pre></td><td class="code"><pre><span class="line">[INFO] Copying files to D:\app\java-project\nacos\nacos-2.2.2\distribution\target\nacos-server-2.2.2</span><br><span class="line">[INFO] Building tar: D:\app\java-project\nacos\nacos-2.2.2\distribution\target\nacos-server-2.2.2.tar.gz</span><br><span class="line">[INFO] Building zip: D:\app\java-project\nacos\nacos-2.2.2\distribution\target\nacos-server-2.2.2.zip</span><br><span class="line">[INFO] ------------------------------------------------------------------------</span><br><span class="line">[INFO] Reactor Summary for Alibaba NACOS 2.2.2 2.2.2:</span><br><span class="line">[INFO] </span><br><span class="line">[INFO] Alibaba NACOS 2.2.2 ................................ SUCCESS [ 3.360 s]</span><br><span class="line">[INFO] nacos-api 2.2.2 .................................... SUCCESS [ 8.593 s]</span><br><span class="line">[INFO] nacos-common 2.2.2 ................................. SUCCESS [ 7.564 s]</span><br><span class="line">[INFO] nacos-consistency 2.2.2 ............................ SUCCESS [ 4.365 s]</span><br><span class="line">[INFO] nacos-plugin 2.2.2 ................................. SUCCESS [ 0.146 s]</span><br><span class="line">[INFO] nacos-auth-plugin 2.2.2 ............................ SUCCESS [ 0.745 s]</span><br><span class="line">[INFO] nacos-custom-environment-plugin 2.2.2 .............. SUCCESS [ 0.550 s]</span><br><span class="line">[INFO] nacos-sys 2.2.2 .................................... SUCCESS [ 1.225 s]</span><br><span class="line">[INFO] nacos-auth 2.2.2 ................................... SUCCESS [ 1.134 s]</span><br><span class="line">[INFO] nacos-trace-plugin 2.2.2 ........................... SUCCESS [ 0.434 s]</span><br><span class="line">[INFO] nacos-control-plugin 2.2.2 ......................... SUCCESS [ 1.350 s]</span><br><span class="line">[INFO] nacos-core 2.2.2 ................................... SUCCESS [ 5.630 s]</span><br><span class="line">[INFO] nacos-encryption-plugin 2.2.2 ...................... SUCCESS [ 0.459 s]</span><br><span class="line">[INFO] nacos-datasource-plugin 2.2.2 ...................... SUCCESS [ 0.986 s]</span><br><span class="line">[INFO] nacos-config 2.2.2 ................................. SUCCESS [ 8.554 s]</span><br><span class="line">[INFO] nacos-cmdb 2.2.2 ................................... SUCCESS [ 0.856 s]</span><br><span class="line">[INFO] nacos-naming 2.2.2 ................................. SUCCESS [ 7.299 s]</span><br><span class="line">[INFO] nacos-address 2.2.2 ................................ SUCCESS [ 0.953 s]</span><br><span class="line">[INFO] nacos-client 2.2.2 ................................. SUCCESS [ 15.355 s]</span><br><span class="line">[INFO] nacos-plugin-default-impl 2.2.2 .................... SUCCESS [ 2.429 s]</span><br><span class="line">[INFO] nacos-istio 2.2.2 .................................. SUCCESS [ 10.301 s]</span><br><span class="line">[INFO] nacos-prometheus 2.2.2 ............................. SUCCESS [ 0.812 s]</span><br><span class="line">[INFO] nacos-console 2.2.2 ................................ SUCCESS [ 3.007 s]</span><br><span class="line">[INFO] nacos-test 2.2.2 ................................... SUCCESS [ 0.209 s]</span><br><span class="line">[INFO] nacos-config-test 2.2.2 ............................ SUCCESS [ 0.260 s]</span><br><span class="line">[INFO] nacos-naming-test 2.2.2 ............................ SUCCESS [ 0.238 s]</span><br><span class="line">[INFO] nacos-core-test 2.2.2 .............................. SUCCESS [ 0.226 s]</span><br><span class="line">[INFO] nacos-example 2.2.2 ................................ SUCCESS [ 0.638 s]</span><br><span class="line">[INFO] nacos-distribution 2.2.2 ........................... SUCCESS [ 10.374 s]</span><br><span class="line">[INFO] ------------------------------------------------------------------------</span><br><span class="line">[INFO] BUILD SUCCESS</span><br><span class="line">[INFO] ------------------------------------------------------------------------</span><br><span class="line">[INFO] Total time: 01:38 min</span><br><span class="line">[INFO] Finished at: 2024-07-03T19:48:30+08:00</span><br><span class="line">[INFO] ------------------------------------------------------------------------</span><br></pre></td></tr></table></figure> </div> </details><div class="note danger no-icon flat"><p>如果执行命令之后没有生成对应的jar,检查 idea <mark class="hl-label default">项目结构</mark> -><mark class="hl-label default">SDK和语言级别</mark> 是否对应<br>实测JDK11和JDK17都没有问题,可以打包成功,但是必须两个配置对应上才行</p></div>]]></content>
<categories>
<category> 技术教程 </category>
</categories>
<tags>
<tag> nacos </tag>
<tag> 达梦数据库 </tag>
</tags>
</entry>
<entry>
<title>logback配置示例</title>
<link href="/9d22.html"/>
<url>/9d22.html</url>
<content type="html"><![CDATA[<h1>springboot日志配置示例</h1><h2 id="介绍">介绍</h2><ul><li>springboot默认使用的是logback日志框架,有两种命名方式<ul><li>logback.xml</li><li>logback-spring.xml</li></ul></li></ul><div class="note info no-icon flat"><p>区别就是logback-spring.xml由Spring加载,这意味着它可以使用Spring的环境变量、属性占位符以及一些Spring Boot特有的功能。</p></div><h2 id="示例说明">示例说明</h2><ul><li><p>配置文件说明</p><div class="note primary no-icon flat"><ol><li><strong>配置项</strong><ul><li>APP_NAME不指定默认从配置文件读取</li><li>logger标签的name属性需要你指定你的mapper所在的包名,否则不会打印sql语句</li></ul></li><li>一共配置了四个输出方式<ul><li>控制台:没什么好说的就是输出到控制台</li><li>info.log:和控制台输出的内容一样,只不过是输出到文件</li><li>error.log:只记录error级别的日志</li><li>sql.log:只记录sql语句以及参数信息</li></ul></li><li>日志滚动方式<ul><li>到达00:00:00自动切割,并且新建一个文件夹存储</li><li>一个日志最大10MB</li><li>最长保留一个月(sql日志只保留两天)</li><li>超过10G自动删除(sql日志超过2G自动删除)</li></ul></li></ol></div></li><li><p>知识点</p></li></ul><figure class="highlight yaml"><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="comment"># mybatis-plus的默认日志实现是Slf4jImpl,这个是没有问题的</span></span><br><span class="line"><span class="comment"># 如果你发现你的sql语句只在控制台输出,日志文件中没有,请检查是否将实现类配置成了org.apache.ibatis.logging.stdout.StdOutImpl</span></span><br><span class="line"><span class="comment"># StdOutImpl实现是使用System.out.pringln进行输出,所以不会记录到日志文件中</span></span><br><span class="line"><span class="attr">mybatis-plus:</span></span><br><span class="line"> <span class="attr">configuration:</span></span><br><span class="line"> <span class="attr">log-impl:</span> <span class="string">org.apache.ibatis.logging.slf4j.Slf4jImpl</span></span><br></pre></td></tr></table></figure><h2 id="示例">示例</h2><figure class="highlight xml"><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><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta"><?xml version=<span class="string">"1.0"</span> encoding=<span class="string">"UTF-8"</span>?></span></span><br><span class="line"><span class="tag"><<span class="name">configuration</span> <span class="attr">scan</span>=<span class="string">"true"</span> <span class="attr">scanPeriod</span>=<span class="string">"60 seconds"</span> <span class="attr">debug</span>=<span class="string">"false"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">contextName</span>></span>${APP_NAME:-logback}<span class="tag"></<span class="name">contextName</span>></span></span><br><span class="line"></span><br><span class="line"> <span class="comment"><!-- 定义日志文件的存储地址 --></span></span><br><span class="line"> <span class="tag"><<span class="name">property</span> <span class="attr">name</span>=<span class="string">"LOG_HOME"</span> <span class="attr">value</span>=<span class="string">"${LOG_HOME:-${user.dir}/logs}"</span> /></span></span><br><span class="line"> <span class="tag"><<span class="name">springProperty</span> <span class="attr">scope</span>=<span class="string">"context"</span> <span class="attr">name</span>=<span class="string">"APP_NAME"</span> <span class="attr">source</span>=<span class="string">"spring.application.name"</span>/></span></span><br><span class="line"> <span class="tag"><<span class="name">property</span> <span class="attr">name</span>=<span class="string">"LOG_LEVEL_PATTERN"</span> <span class="attr">value</span>=<span class="string">"${LOG_LEVEL_PATTERN:-%5p}"</span> /></span></span><br><span class="line"> <span class="tag"><<span class="name">property</span> <span class="attr">name</span>=<span class="string">"LOG_PATTERN"</span> <span class="attr">value</span>=<span class="string">"${LOG_PATTERN:-%-20(%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread]) %-5level %logger{80} -%msg%n}"</span> /></span></span><br><span class="line"></span><br><span class="line"> <span class="comment"><!-- 彩色日志 --></span></span><br><span class="line"> <span class="tag"><<span class="name">conversionRule</span> <span class="attr">conversionWord</span>=<span class="string">"clr"</span> <span class="attr">converterClass</span>=<span class="string">"org.springframework.boot.logging.logback.ColorConverter"</span> /></span></span><br><span class="line"> <span class="tag"><<span class="name">conversionRule</span> <span class="attr">conversionWord</span>=<span class="string">"wex"</span> <span class="attr">converterClass</span>=<span class="string">"org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter"</span> /></span></span><br><span class="line"> <span class="tag"><<span class="name">conversionRule</span> <span class="attr">conversionWord</span>=<span class="string">"wEx"</span> <span class="attr">converterClass</span>=<span class="string">"org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter"</span> /></span></span><br><span class="line"></span><br><span class="line"> <span class="comment"><!-- 彩色日志格式 --></span></span><br><span class="line"> <span class="tag"><<span class="name">property</span> <span class="attr">name</span>=<span class="string">"CONSOLE_LOG_PATTERN"</span> <span class="attr">value</span>=<span class="string">"${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN}) %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n}"</span> /></span></span><br><span class="line"></span><br><span class="line"> <span class="comment"><!-- 控制台输出 --></span></span><br><span class="line"> <span class="tag"><<span class="name">appender</span> <span class="attr">name</span>=<span class="string">"STDOUT"</span> <span class="attr">class</span>=<span class="string">"ch.qos.logback.core.ConsoleAppender"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">encoder</span> <span class="attr">class</span>=<span class="string">"ch.qos.logback.classic.encoder.PatternLayoutEncoder"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">pattern</span>></span>${CONSOLE_LOG_PATTERN}<span class="tag"></<span class="name">pattern</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">encoder</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">appender</span>></span></span><br><span class="line"></span><br><span class="line"> <span class="comment"><!-- 文件输出 --></span></span><br><span class="line"> <span class="tag"><<span class="name">appender</span> <span class="attr">name</span>=<span class="string">"FILE"</span> <span class="attr">class</span>=<span class="string">"ch.qos.logback.core.rolling.RollingFileAppender"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">file</span>></span>${LOG_HOME}/${APP_NAME}.log<span class="tag"></<span class="name">file</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">rollingPolicy</span> <span class="attr">class</span>=<span class="string">"ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">fileNamePattern</span>></span>${LOG_HOME}/bak/%d{yyyy-MM-dd}/${APP_NAME}-%i.log<span class="tag"></<span class="name">fileNamePattern</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">maxHistory</span>></span>30<span class="tag"></<span class="name">maxHistory</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">maxFileSize</span>></span>20MB<span class="tag"></<span class="name">maxFileSize</span>></span></span><br><span class="line"> <span class="comment"><!--该滚动策略日志的总大小,超过的日志会被清除--></span></span><br><span class="line"> <span class="tag"><<span class="name">totalSizeCap</span>></span>10GB<span class="tag"></<span class="name">totalSizeCap</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">rollingPolicy</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">encoder</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">pattern</span>></span>${LOG_PATTERN}<span class="tag"></<span class="name">pattern</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">encoder</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">appender</span>></span></span><br><span class="line"></span><br><span class="line"> <span class="comment"><!-- Error 文件输出 --></span></span><br><span class="line"> <span class="tag"><<span class="name">appender</span> <span class="attr">name</span>=<span class="string">"ERROR_FILE"</span> <span class="attr">class</span>=<span class="string">"ch.qos.logback.core.rolling.RollingFileAppender"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">file</span>></span>${LOG_HOME}/${APP_NAME}-error.log<span class="tag"></<span class="name">file</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">rollingPolicy</span> <span class="attr">class</span>=<span class="string">"ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">fileNamePattern</span>></span>${LOG_HOME}/bak/%d{yyyy-MM-dd}/${APP_NAME}-error-%i.log<span class="tag"></<span class="name">fileNamePattern</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">maxHistory</span>></span>30<span class="tag"></<span class="name">maxHistory</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">maxFileSize</span>></span>20MB<span class="tag"></<span class="name">maxFileSize</span>></span></span><br><span class="line"> <span class="comment"><!--该滚动策略日志的总大小,超过的日志会被清除--></span></span><br><span class="line"> <span class="tag"><<span class="name">totalSizeCap</span>></span>10GB<span class="tag"></<span class="name">totalSizeCap</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">rollingPolicy</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">encoder</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">pattern</span>></span>${LOG_PATTERN}<span class="tag"></<span class="name">pattern</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">encoder</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">filter</span> <span class="attr">class</span>=<span class="string">"ch.qos.logback.classic.filter.ThresholdFilter"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">level</span>></span>error<span class="tag"></<span class="name">level</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">filter</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">appender</span>></span></span><br><span class="line"></span><br><span class="line"> <span class="comment"><!-- sql 文件输出 --></span></span><br><span class="line"> <span class="tag"><<span class="name">appender</span> <span class="attr">name</span>=<span class="string">"sql_log"</span> <span class="attr">class</span>=<span class="string">"ch.qos.logback.core.rolling.RollingFileAppender"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">file</span>></span>${LOG_HOME}/${APP_NAME}-sql.log<span class="tag"></<span class="name">file</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">rollingPolicy</span> <span class="attr">class</span>=<span class="string">"ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"</span>></span></span><br><span class="line"> <span class="comment"><!-- 日志文件输出文件名 --></span></span><br><span class="line"> <span class="tag"><<span class="name">fileNamePattern</span>></span>${LOG_HOME}/bak/%d{yyyy-MM-dd}/${APP_NAME}-sql-%i.log<span class="tag"></<span class="name">fileNamePattern</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">maxHistory</span>></span>2<span class="tag"></<span class="name">maxHistory</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">maxFileSize</span>></span>10MB<span class="tag"></<span class="name">maxFileSize</span>></span></span><br><span class="line"> <span class="comment"><!--该滚动策略日志的总大小,超过的日志会被清除--></span></span><br><span class="line"> <span class="tag"><<span class="name">totalSizeCap</span>></span>10GB<span class="tag"></<span class="name">totalSizeCap</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">rollingPolicy</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">encoder</span> <span class="attr">class</span>=<span class="string">"ch.qos.logback.classic.encoder.PatternLayoutEncoder"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">pattern</span>></span>${LOG_PATTERN}<span class="tag"></<span class="name">pattern</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">encoder</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">filter</span> <span class="attr">class</span>=<span class="string">"ch.qos.logback.classic.filter.ThresholdFilter"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">level</span>></span>DEBUG<span class="tag"></<span class="name">level</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">filter</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">appender</span>></span></span><br><span class="line"></span><br><span class="line"> <span class="tag"><<span class="name">logger</span> <span class="attr">name</span>=<span class="string">"mapper随在包名"</span> <span class="attr">level</span>=<span class="string">"DEBUG"</span> <span class="attr">additivity</span>=<span class="string">"false"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">appender-ref</span> <span class="attr">ref</span>=<span class="string">"STDOUT"</span>/></span></span><br><span class="line"> <span class="tag"><<span class="name">appender-ref</span> <span class="attr">ref</span>=<span class="string">"mysql_log"</span> /></span></span><br><span class="line"> <span class="tag"></<span class="name">logger</span>></span></span><br><span class="line"> <span class="comment"><!-- 日志输出级别 --></span></span><br><span class="line"> <span class="tag"><<span class="name">root</span> <span class="attr">level</span>=<span class="string">"info"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">appender-ref</span> <span class="attr">ref</span>=<span class="string">"STDOUT"</span> /></span></span><br><span class="line"> <span class="tag"><<span class="name">appender-ref</span> <span class="attr">ref</span>=<span class="string">"FILE"</span> /></span></span><br><span class="line"> <span class="tag"><<span class="name">appender-ref</span> <span class="attr">ref</span>=<span class="string">"ERROR_FILE"</span> /></span></span><br><span class="line"> <span class="tag"></<span class="name">root</span>></span></span><br><span class="line"></span><br><span class="line"><span class="tag"></<span class="name">configuration</span>></span></span><br><span class="line"></span><br></pre></td></tr></table></figure>]]></content>
<categories>
<category> 技术教程 </category>
</categories>
<tags>
<tag> logback </tag>
</tags>
</entry>
<entry>
<title>将你的网站提交到搜索引擎</title>
<link href="/17dd.html"/>
<url>/17dd.html</url>
<content type="html"><![CDATA[<h1>让搜索引擎收录你的网站</h1><h2 id="谷歌">谷歌</h2><div calss='anzhiyu-tag-link'><a class="tag-Link" target="_blank" href="https://search.google.com/search-console"> <div class="tag-link-tips">引用站外地址</div> <div class="tag-link-bottom"> <div class="tag-link-left" style="background-image: url(https://google.com/favicon.ico)"> <i class="anzhiyufont anzhiyu-icon-link" style="display: none"></i> </div> <div class="tag-link-right"> <div class="tag-link-title">谷歌</div> <div class="tag-link-sitename"> 提交你的网站到谷歌搜索引擎</div> </div> <i class="anzhiyufont anzhiyu-icon-angle-right"></i> </div> </a></div><h2 id="百度">百度</h2><ul><li>近期百度关闭了资源提交的接口,但是还可以添加站点</li></ul><div calss='anzhiyu-tag-link'><a class="tag-Link" target="_blank" href="https://ziyuan.baidu.com/linksubmit/index"> <div class="tag-link-tips">引用站外地址</div> <div class="tag-link-bottom"> <div class="tag-link-left" style="background-image: url(https://ziyuan.baidu.com/favicon.ico)"> <i class="anzhiyufont anzhiyu-icon-link" style="display: none"></i> </div> <div class="tag-link-right"> <div class="tag-link-title">百度</div> <div class="tag-link-sitename"> 提交你的网站到百度搜索引擎</div> </div> <i class="anzhiyufont anzhiyu-icon-angle-right"></i> </div> </a></div><h2 id="必应">必应</h2><div calss='anzhiyu-tag-link'><a class="tag-Link" target="_blank" href="https://www.bing.com/webmasters/usermgmt"> <div class="tag-link-tips">引用站外地址</div> <div class="tag-link-bottom"> <div class="tag-link-left" style="background-image: url(https://www.bing.com/favicon.ico)"> <i class="anzhiyufont anzhiyu-icon-link" style="display: none"></i> </div> <div class="tag-link-right"> <div class="tag-link-title">必应</div> <div class="tag-link-sitename"> 提交你的网站到必应搜索引擎</div> </div> <i class="anzhiyufont anzhiyu-icon-angle-right"></i> </div> </a></div><h2 id="搜狗">搜狗</h2><div calss='anzhiyu-tag-link'><a class="tag-Link" target="_blank" href="https://zhanzhang.so.com/sitetool/site_manage"> <div class="tag-link-tips">引用站外地址</div> <div class="tag-link-bottom"> <div class="tag-link-left" style="background-image: url(https://zhanzhang.so.com/favicon.ico)"> <i class="anzhiyufont anzhiyu-icon-link" style="display: none"></i> </div> <div class="tag-link-right"> <div class="tag-link-title">搜狗</div> <div class="tag-link-sitename"> 提交你的网站到搜狗搜索引擎</div> </div> <i class="anzhiyufont anzhiyu-icon-angle-right"></i> </div> </a></div><div class="note success modern"><p>操作比较简单,打开上面对应的网站,登录注册,然后验证自己的网站就可以</p></div><hr><h2 id="安装插件生成sitemap">安装插件生成sitemap</h2><div class="note primary modern"><p>如果你也是hexo搭建的博客网站,那么你可以使用一个插件来生成自己的sitemap,让搜索引擎更快的收录你的网站</p></div><h3 id="安装插件">安装插件</h3><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm install hexo-generator-sitemap --save</span><br></pre></td></tr></table></figure><h3 id="配置">配置</h3><figure class="highlight yaml"><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="comment">#生成站点地图</span></span><br><span class="line"><span class="attr">sitemap:</span></span><br><span class="line"> <span class="attr">path:</span></span><br><span class="line"> <span class="bullet">-</span> <span class="string">sitemap.xml</span></span><br><span class="line"> <span class="bullet">-</span> <span class="string">sitemap.txt</span></span><br><span class="line"> <span class="attr">template:</span> <span class="string">template/sitemap.xml</span></span><br><span class="line"> <span class="attr">template_txt:</span> <span class="string">template/sitemap.txt</span></span><br><span class="line"> <span class="attr">rel:</span> <span class="literal">false</span></span><br><span class="line"> <span class="attr">tags:</span> <span class="literal">true</span></span><br><span class="line"> <span class="attr">categories:</span> <span class="literal">true</span></span><br><span class="line"></span><br><span class="line"><span class="comment">#如果不想让某个页面生成sitemap,可以在对应md文件的头文件加入如下配置</span></span><br><span class="line"><span class="attr">sitemap:</span> <span class="literal">false</span></span><br></pre></td></tr></table></figure><h3 id="配置模板">配置模板</h3><div class="note info modern"><p>在根目录创建template/sitemap.xml、template/sitemap.txt两个文件<br>将下面两个模板内容放入对应的文件中</p></div><ol><li>xml模板</li></ol><figure class="highlight xml"><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></pre></td><td class="code"><pre><span class="line"><span class="meta"><?xml version=<span class="string">"1.0"</span> encoding=<span class="string">"UTF-8"</span>?></span></span><br><span class="line"><span class="tag"><<span class="name">urlset</span> <span class="attr">xmlns</span>=<span class="string">"http://www.sitemaps.org/schemas/sitemap/0.9"</span>></span></span><br><span class="line"> {% for post in posts %}</span><br><span class="line"> <span class="tag"><<span class="name">url</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">loc</span>></span>{{ post.permalink | uriencode }}<span class="tag"></<span class="name">loc</span>></span></span><br><span class="line"> {% if post.updated %}</span><br><span class="line"> <span class="tag"><<span class="name">lastmod</span>></span>{{ post.updated | formatDate }}<span class="tag"></<span class="name">lastmod</span>></span></span><br><span class="line"> {% elif post.date %}</span><br><span class="line"> <span class="tag"><<span class="name">lastmod</span>></span>{{ post.date | formatDate }}<span class="tag"></<span class="name">lastmod</span>></span></span><br><span class="line"> {% endif %}</span><br><span class="line"> <span class="tag"><<span class="name">changefreq</span>></span>monthly<span class="tag"></<span class="name">changefreq</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">priority</span>></span>0.6<span class="tag"></<span class="name">priority</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">url</span>></span></span><br><span class="line"> {% endfor %}</span><br><span class="line"></span><br><span class="line"> <span class="tag"><<span class="name">url</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">loc</span>></span>{{ config.url | uriencode }}<span class="tag"></<span class="name">loc</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">lastmod</span>></span>{{ sNow | formatDate }}<span class="tag"></<span class="name">lastmod</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">changefreq</span>></span>daily<span class="tag"></<span class="name">changefreq</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">priority</span>></span>1.0<span class="tag"></<span class="name">priority</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">url</span>></span></span><br><span class="line"></span><br><span class="line"> {% for tag in tags %}</span><br><span class="line"> <span class="tag"><<span class="name">url</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">loc</span>></span>{{ tag.permalink | uriencode }}<span class="tag"></<span class="name">loc</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">lastmod</span>></span>{{ sNow | formatDate }}<span class="tag"></<span class="name">lastmod</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">changefreq</span>></span>weekly<span class="tag"></<span class="name">changefreq</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">priority</span>></span>0.2<span class="tag"></<span class="name">priority</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">url</span>></span></span><br><span class="line"> {% endfor %}</span><br><span class="line"></span><br><span class="line"> {% for cat in categories %}</span><br><span class="line"> <span class="tag"><<span class="name">url</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">loc</span>></span>{{ cat.permalink | uriencode }}<span class="tag"></<span class="name">loc</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">lastmod</span>></span>{{ sNow | formatDate }}<span class="tag"></<span class="name">lastmod</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">changefreq</span>></span>weekly<span class="tag"></<span class="name">changefreq</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">priority</span>></span>0.2<span class="tag"></<span class="name">priority</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">url</span>></span></span><br><span class="line"> {% endfor %}</span><br><span class="line"><span class="tag"></<span class="name">urlset</span>></span></span><br><span class="line"></span><br></pre></td></tr></table></figure><ol start="2"><li>txt模板</li></ol><figure class="highlight text"><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">{% for post in posts %}{{ post.permalink | uriencode }}</span><br><span class="line">{% endfor %}{{ config.url | uriencode }}</span><br><span class="line">{% for tag in tags %}{{ tag.permalink | uriencode }}</span><br><span class="line">{% endfor %}{% for cat in categories %}{{ cat.permalink | uriencode }}</span><br><span class="line">{% endfor %}</span><br></pre></td></tr></table></figure><h3 id="访问">访问</h3><ul><li>你的网站域名/sitemap.xml</li><li>你的网站域名/sitemap.txt</li></ul>]]></content>
<categories>
<category> 技术教程 </category>
</categories>
<tags>
<tag> 搜索引擎 </tag>
</tags>
</entry>
<entry>
<title>好玩的图案分享</title>
<link href="/77f2.html"/>
<url>/77f2.html</url>
<content type="html"><![CDATA[<figure class="highlight plaintext"><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><br><span class="line">┃┗━┓┃┗━┓┃┗━┓</span><br><span class="line">┃┏┓┃┃┏┓┃┃┏┓┃</span><br><span class="line">┃┗┛┃┃┗┛┃┃┗┛┃</span><br><span class="line">┗━━┛┗━━┛┗━━┛</span><br></pre></td></tr></table></figure><hr><figure class="highlight plaintext"><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></pre></td><td class="code"><pre><span class="line"> ⣠⣤⣤⣤⡀⠀⠀⢀⣀⣀⣤⣤⣀⣀⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀</span><br><span class="line">⠀⣾⣻⣻⣻⣻⡿⠚⠉⠉⠀⠀⠀⠀⠀⠀⠈⠙⠲⣴⣻⣻⣻⣷⣄</span><br><span class="line">⢸⣻⣻⣻⣻⠟⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⢻⣻⣻⣻⣻</span><br><span class="line">⠀⠻⣻⣻⠏⠀⠀⠀⠀⣶⠿⠿⢿⣷⣄⢠⡿⠿⠶⠦⠀⢹⣻⣻⣻</span><br><span class="line">⠀⠀⢈⡏⠀⠀⠀⠀⠈⠑⠺⣻⠟⠉⠁⠈⠛⢿⠆⠀⠀⠀⢻⠋⠁</span><br><span class="line">⠀⠀⡼⠀⠀⠀⠀⠀⠀⠀⠀⣀⣤⠂⠀⢀⠀⢠⡄⠀⠀⠀⢸⡀⠀</span><br><span class="line">⢀⣴⡇⠀⠀⠀⠀⠀⠀⠶⢿⣻⣉⣛⣻⣻⣛⣉⡻⣦⠀⠀⠀⣇⠀</span><br><span class="line">⣾⣻⡇⠀⠀⠀⠀⠀⠀⠄⢸⡟⢿⣯⣭⣭⣽⣻⠃⠈⠀⠀⠀⣻⣧</span><br><span class="line">⣻⣻⣻⣦⡀⠀⠀⠀⠀⠈⠿⠶⣭⣭⣬⡭⠁⠀⠀⠀⢀⣼⣻⣻⣧</span><br><span class="line">⣻⣻⣻⣻⣻⣶⣄⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⣠⣴⣻⣻⣻⣻⣻</span><br><span class="line">⣻⣻⣻⣻⣻⣻⣻⣻⣻⣷⣶⣶⣶⣶⣶⣾⣻⣻⣻⣻⣻⣻⣻⣻⣻</span><br></pre></td></tr></table></figure><hr><figure class="highlight plaintext"><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></pre></td><td class="code"><pre><span class="line"> ▅▅</span><br><span class="line"> ▋ ▋ ◢▀ ▀◣</span><br><span class="line"> ▌ ▌ ▌ .▌</span><br><span class="line"> ▌ ▌ ▌ ▌</span><br><span class="line"> ▐ ▌ ▌ ▌</span><br><span class="line"> ▐ ▀■▀ ▌</span><br><span class="line"> ◢◤ ▀▃</span><br><span class="line"> ◢◤ ◥◣</span><br><span class="line"> ▌ ▌</span><br><span class="line"> ▐ ● ● ▌ </span><br><span class="line"> ▌ ▌</span><br><span class="line"> ◥◣ ╳ ◢◤</span><br><span class="line"> ◢▀▅▃▂ ▂▂▃▅▀▅</span><br><span class="line"> ◢◤ ▀▀▀▀▀ ◥◣</span><br><span class="line">▐◣▃▌ ▐▃◢▌ ▌</span><br><span class="line">◥◣▃▌ ▐▃◢◤</span><br><span class="line"> ▀▅▃ ▂▅▀</span><br><span class="line"> ▀■▆▅▅▅▅▅▆■█▀</span><br><span class="line"> ▐▃▃▃▲▃▃▃◢</span><br></pre></td></tr></table></figure><hr><figure class="highlight plaintext"><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><br><span class="line">⠀⠀⠀⠀⣀⣀⣤⠖⠛⠉⠉⠉⠉⠉⠙⠒⠦⣿⣏⣀⠀⠀⠀⠀</span><br><span class="line">⠀⠀⣠⠞⠁⠀⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⢵⡄⠀⠀</span><br><span class="line">⠀⢰⣯⠀⠀⢀⠂⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⠀⠀⣿⠀⠀</span><br><span class="line">⠀⠈⣇⢀⢠⠇⠀⣶⡶⠄⠀⠀⠀⢠⣶⡶⠀⠀⣸⣀⣼⠟⠀⠀</span><br><span class="line">⠀⠀⠙⠛⠾⡆⠀⠙⠛⠃⠀⠀⠀⠀⠙⠋⠀⠀⣹⠟⠁⠀⠀⠀</span><br><span class="line">⢀⡴⠚⠉⠛⢿⠀⠀⠀⠀⢿⣿⠆⠀⠀⠀⠀⢀⣿⠋⠉⠉⢳⡄</span><br><span class="line">⢾⡀⡄⠀⣄⡼⠻⢧⠤⣤⠤⠤⣤⣠⣦⣾⠶⠞⢿⣤⡄⣠⣀⡷</span><br><span class="line">⠈⠙⠛⠋⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠉⠉⠉</span><br></pre></td></tr></table></figure><hr><figure class="highlight plaintext"><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><br><span class="line">⬜️⬜️⬜⬛⬛⬛⬛⬜️⬜️⬜️⬜️⬜</span><br><span class="line">⬜️⬜️⬜️⬛⬛⬛⬛⬜️⬜️⬜️⬜️⬜️</span><br><span class="line">⬜️⬜️⬜️⬜️⬛⬛⬛⬛⬛⬛⬛⬛</span><br><span class="line">⬜️⬜️⬜️⬜️⬛⬛⬜️⬜️⬜️⬜️⬜️⬜️ </span><br><span class="line">⬜️⬜️⬛⬛⬛⬛⬛⬛⬛⬛⬛⬛ </span><br><span class="line">⬜️⬛⬛⬛⬛⬛⬜️⬜️⬜️⬜️⬜️⬜️ </span><br><span class="line">⬜️⬛⬛⬛⬛⬛⬛⬜️⬜️⬜️⬜️⬜️ </span><br><span class="line">⬜️⬜️⬛⬛⬜️⬜️⬛⬛⬜⬜⬜⬜ </span><br><span class="line">⬜️⬜️⬜️⬛⬛⬜️⬜⬛⬛⬜️⬜️⬜️ </span><br><span class="line">⬜️⬜️⬜️⬜️⬛⬜⬜️⬜️⬛⬜⬜️⬜️ </span><br><span class="line">⬜️⬜️⬜️⬜️⬛⬜⬜️⬜️⬛⬜⬜️⬜️ </span><br><span class="line">⬜️⬜️⬜️⬜⬛⬜⬜️⬜⬛⬛⬜⬜ </span><br><span class="line">⬜️⬜️⬜️⬜️⬛⬛⬜⬜⬜️⬜️⬜⬜️</span><br></pre></td></tr></table></figure><hr><figure class="highlight plaintext"><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><br><span class="line">🙂☺️🥚🥚🥚☺️🥚🥚🥚😌</span><br><span class="line">🙃🤓🥚🖲🥚🤤🥚🖲🥚😦</span><br><span class="line">😧🤤🥚🥚🥚😵🥚🥚🥚😑</span><br><span class="line">😲🐽😧😦😑🔑😮🤐😴🐽</span><br><span class="line">😦🤐✒️😧😮😬😑🤭🖋😮</span><br><span class="line">🤐😧😪😬🛴🎩🛴😒😖🙁</span><br><span class="line">😏😕😫😤😳😠😩🙁😔☹️</span><br><span class="line">🧐😖😟😗😚😙🙂🙃🤒😅</span><br><span class="line">☁️☁️☁️☁️🌪️🍎🌪️☁️☁️☁️</span><br><span class="line">🍪🍪🍪🍪🍪🍪🍪🍪🍪🍪</span><br><span class="line">🍪🍪🍪🍪🍪🍪🍪🍪🍪🍪</span><br><span class="line"> 📒 📒</span><br><span class="line"> 📒 📒</span><br><span class="line"> 🕋🐜 🕋🐜</span><br></pre></td></tr></table></figure><hr><figure class="highlight plaintext"><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></pre></td><td class="code"><pre><span class="line"> 🌸🌸🌸🌸</span><br><span class="line"> 🌸🌸🌸🌸🌸🌸</span><br><span class="line">🌸📕📕📕📕📕🌸 🐌 🐌</span><br><span class="line">🌸📕🌸🌸🌸📕🌸 📘 📘</span><br><span class="line">🌸📕🌸📕🌸📕🌸 📘 📘</span><br><span class="line">🌸📕📕📕🌸📕🌸 📘 📘</span><br><span class="line">🌸🌸🌸🌸📕🌸🌸 📘 📘</span><br><span class="line"> 🌸🌸🌸📕🌸🌸🌸 📘📘</span><br><span class="line"> 🌸🌸📕🌸🌸🌸🌸 📘 🍉</span><br><span class="line"> 🛋 🛋️🛋️🛋️🛋️🛋️🛋️📘📘</span><br><span class="line">🍯🍯🍯🍯🍯🍯🍯🍯🍯🍯</span><br></pre></td></tr></table></figure><hr><figure class="highlight plaintext"><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></pre></td><td class="code"><pre><span class="line"> 🧠🧠</span><br><span class="line"> 🧠🧠🧠</span><br><span class="line"> 🧠🧠🧠</span><br><span class="line"> 🧠🧠🏴🏴</span><br><span class="line"> 🧠🧠🧠🧠</span><br><span class="line"> 🧠🧠☁️☁️</span><br><span class="line"> 🧠🧠⌚️⌚️</span><br><span class="line"> 🧠🧠☁️☁️</span><br><span class="line"> 🧠🧠🧠🧠🧠</span><br><span class="line"> 🧠🧠🔨🏴🏴🏴</span><br><span class="line"> 🧠🧠🧠🧠🧠🧠🧠</span><br><span class="line"> 🧠🧠🧠🧠🧠🧠🧠🧠</span><br><span class="line">🧠🧠🧠🧠🧠🧠🧠🧠🧠</span><br><span class="line">🍀🍀🧠🧠🍀🍀🍀🍀🍀🍀</span><br><span class="line">👾🍀🧠🧠🍀🍀🍀👾👾👾</span><br><span class="line">👾👾🧠🍀🍀🍀🍀🍀👾</span><br><span class="line">👾🍀🍀🍀🍀🍀🍀🍀</span><br><span class="line"> 🍀🍀 🍀🍀</span><br><span class="line"> 🧠 🧠</span><br></pre></td></tr></table></figure><hr><figure class="highlight plaintext"><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><br><span class="line">◤ ◥◣ ◢◤ █</span><br><span class="line">▎ ◢█◣ ◥◣◢◤ ◢█ █</span><br><span class="line">◣ ◢◤ ◥◣ ◢◣◥◣ ◢◤</span><br><span class="line">◥██◤ ◢◤ ◥◣</span><br><span class="line"> █ ● ● █</span><br><span class="line"> █ 〃 ▄ 〃 █</span><br><span class="line"> ◥◣ ╚╩╝ ◢◤</span><br><span class="line"> ◥█▅▃▃ ▃▃▅█◤</span><br><span class="line"> ◢◤ ◥◣</span><br><span class="line"> █ █</span><br><span class="line"> ◢◤▕ ▎◥◣</span><br><span class="line"> ▕▃◣◢▅▅▅◣◢▃┃</span><br></pre></td></tr></table></figure><hr><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">我偷了交通工具给你🚗🚕🚙🚌🚎🏎️🚓🚑🚒🚐🚚🚛🚜🛴🚲🛵🏍️🚔🚍🚘🚖🚡🚠🚟🚃🚋🚞🚝🚄🚅🚈🚂🚆🚇🚊🚉✈️🛫🛩️🚀🛸🚁⛵🚤</span><br></pre></td></tr></table></figure><hr><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">我偷一片果园给你🍏🍎🍐🍊🍋🍌🍉🍇🍓🫐🍈🍒🍑🥭🍍🥥🥝</span><br></pre></td></tr></table></figure><hr><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">我偷片森林还你 🌿☘️🎋🌲🌳🌱🍀🌴🌵🌿☘️🎋🌲🌳🌱🍀🌴🌵🌿☘️🎋🌲🌳🌱🍀🌴🌵🌿☘️🎋🌲🌳🌱🍀🌴🌵🌿☘️🎋🌲🌳🌱🍀🌴🌵</span><br></pre></td></tr></table></figure><hr><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">我偷了一套麻将 🀀🀁🀂🀃🀅🀆🀇🀈🀉🀊🀋🀌🀍🀎🀏🀐🀑🀒🀓🀔🀕🀖🀗🀘🀙🀚🀛🀜🀝🀞🀟🀠🀡🀢🀣🀤</span><br></pre></td></tr></table></figure><hr><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">偷点瓜果蔬菜给你 🍏🍎🍅🍊🍑🍒🍓🥭🍍🍋🍐🍈🥝🥑🍆🍉🍌🥕🥦🍇🍆🥜🌰🍠🌽🥔🍄🌶️</span><br></pre></td></tr></table></figure><hr><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">我偷了个宇宙给你⭐🌻 ﹡ . ゜. ☀️· 🛸 🌏 ゜ .🌙·. ˙ .゜˙ 🚀✯。★ ﹡゜ ✈ ゜· . ˙☄ฺ★.·♥★</span><br></pre></td></tr></table></figure><hr><figure class="highlight plaintext"><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">吃自助餐不?40元一位</span><br><span class="line">🍽🍴🥄🥐🥯🍞🥖🥨🧀🥚</span><br><span class="line">🥞🥓🥩🍗🍖🌭🍔🍟🍕🥪</span><br><span class="line">🥙🌮🌯🥗🥘🍝🍜🍲🍛🍣</span><br><span class="line">🍱🥟🍤🍙🍚🍘🍥🥠🥮🍢</span><br><span class="line">🍡🍧🍨🍦🥧🧁🍰🎂🍮🍭</span><br><span class="line">🍬🍫🍿🍩🍪🌰🥜🍯🥛☕️</span><br></pre></td></tr></table></figure><hr><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"> ╭══╮ ┌══════┐ </span><br><span class="line">╭╯去哪 快上车,GOGO~</span><br><span class="line">╰⊙═⊙ ╯└═⊙═⊙══⊙</span><br></pre></td></tr></table></figure><hr><figure class="highlight plaintext"><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><br><span class="line">◥ ███████ ◤ </span><br><span class="line">══╩══╩══我派直升机去接你</span><br></pre></td></tr></table></figure><hr><figure class="highlight plaintext"><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">❤️ ( ⚫︎ー⚫︎ ) balalala~</span><br><span class="line"> / \</span><br><span class="line"> / ○ \</span><br><span class="line">/ / ヽ \</span><br><span class="line">| / \ |</span><br><span class="line"> \Ԏ Ԏ/</span><br><span class="line"> 卜− ―イ</span><br><span class="line"> \ /\ /</span><br><span class="line"> ︶ ︶</span><br></pre></td></tr></table></figure><hr><figure class="highlight plaintext"><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"> |  ̄7 (⌒r⌒7/</span><br><span class="line"> レ \_/ ̄\_」</span><br><span class="line">_/ {</span><br><span class="line">_フ ● ゝ</span><br><span class="line">_人 ο ● ナ</span><br><span class="line"> `ト、_ メ</span><br><span class="line"> /  ̄ ーィ゙</span><br><span class="line"> 〈゚・。。。・゚ 丶</span><br></pre></td></tr></table></figure><hr><figure class="highlight plaintext"><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><br><span class="line">┃|||||||┃</span><br><span class="line">┃ ━ ┃</span><br><span class="line">┃ ┳┛ ┗┳ ┃</span><br><span class="line">┃ ┃</span><br><span class="line">┃ ┻ ┃</span><br><span class="line">┃ ┃</span><br><span class="line">┗━┓ ┏━┛</span><br><span class="line"> ┃ ┃ </span><br><span class="line"> ┃ ┃ </span><br><span class="line"> ┃ ┃ </span><br><span class="line"> ┃ ┃</span><br><span class="line"> ┃ ┗━━━┓</span><br><span class="line"> ┃ ┣┓</span><br><span class="line"> ┃ ┃</span><br><span class="line"> ┗┓┓┏━┳┓┏┛</span><br><span class="line"> ┃┫┫ ┃┫┫</span><br><span class="line"> ┗┻┛ ┗┻┛</span><br></pre></td></tr></table></figure><hr><figure class="highlight plaintext"><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><br><span class="line"> ∧_∧ </span><br><span class="line"> (´・ω⊂ヽ゛</span><br><span class="line"> / _ノ⌒⌒ヽ</span><br><span class="line">、( ̄⊂人 ノシ⌒ ノ</span><br><span class="line">⊂ニニニニニニニニニニニ⊃</span><br></pre></td></tr></table></figure><hr><figure class="highlight plaintext"><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><br><span class="line"> |[]:: | |</span><br><span class="line"> |_____| |</span><br><span class="line"> |[]:: | |</span><br><span class="line"> |_____| |</span><br><span class="line">ガラッ |_____| |</span><br><span class="line">.彡/(´・ω・) /| |</span><br><span class="line"> Γ ̄ ̄ ̄ ̄ | |/</span><br><span class="line"> L____|/</span><br></pre></td></tr></table></figure><hr><figure class="highlight plaintext"><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">\ / 0 \ \</span><br><span class="line"> ( )</span><br><span class="line"> \__T__/</span><br></pre></td></tr></table></figure><hr><figure class="highlight plaintext"><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></pre></td><td class="code"><pre><span class="line">⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀</span><br><span class="line">⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡖⠒⠒⠤⢄⠀⠀⠀</span><br><span class="line">⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⠁⠀⠀⠀⡼⠀⠀⠀⠀ ⠀</span><br><span class="line">⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢶⣲⡴⣗⣲⡦⢤⡏⠀⠀⠀⠀⠀</span><br><span class="line">⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣰⠋⠉⠉⠓⠛⠿⢷⣶⣦⠀⠀⠀</span><br><span class="line">⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⠇⠀⠀⠀⠀⠀⠀⠘⡇⠀⠀⠀⠀</span><br><span class="line">⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡞⠀⠀⠀⠀⠀⠀⠀⢰⠇⠀⠀⠀⠀</span><br><span class="line">⠀⠀⠀⠀⠀⠀⠀⠀⡴⠊⠉⠳⡄⠀⢀⣀⣀⡀⠀⣸⠀⠀⠀⠀⠀</span><br><span class="line">⠀⠀⠀⠀⠀⠀⠀⢸⠃⠀⠰⠆⣿⡞⠉⠀⠀⠉⠲⡏⠀⠀⠀⠀⠀</span><br><span class="line">⠀⠀⠀⠀⠀⠀⠀⠈⢧⡀⣀⡴⠛⡇⠀⠈⠃⠀⠀⡗⠀⠀⠀⠀⠀</span><br><span class="line">⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⣱⠃⡴⠙⠢⠤⣀⠤⡾⠁⠀⠀⠀⠀⠀</span><br><span class="line">⠀⠀⠀⠀⠀⠀⠀⠀⢀⡇⣇⡼⠁⠀⠀⠀⠀⢰⠃⠀⠀⠀⠀⠀⠀</span><br><span class="line">⠀⠀⠀⠀⠀⠀⠀⠀⣸⢠⣉⣀⡴⠙⠀⠀⠀⣼⠀⠀⠀⠀⠀⠀⠀</span><br><span class="line">⠀⠀⠀⠀⠀⠀⠀⠀⡏⠀⠈⠁⠀⠀⠀⠀⢀⡇⠀⠀⠀⠀⠀⠀⠀</span><br><span class="line">⠀⠀⠀⠀⠀⠀⠀⢸⠃⠀⠀⠀⠀⠀⠀⠀⡼⠀⠀⠀⠀⠀⠀⠀⠀</span><br><span class="line">⠀⠀⠀⠀⠀⠀⠀⢸⠀⠀⠀⠀⠀⠀⠀⣰⠃⠀⠀⠀⠀⠀⠀⠀⠀</span><br><span class="line">⠀⠀⠀⠀⠀⣀⠤⠚⣶⡀⢠⠄⡰⠃⣠⣇⠀⠀⠀⠀⠀⠀⠀⠀⠀</span><br><span class="line">⠀⢀⣠⠔⣋⣷⣠⡞⠀⠉⠙⠛⠋⢩⡀⠈⠳⣄⠀⠀⠀⠀⠀⠀⠀</span><br><span class="line">⠀⡏⢴⠋⠁⠀⣸⠁⠀⠀⠀⠀⠀⠀⣹⢦⣶⡛⠳⣄⠀⠀⠀⠀⠀</span><br><span class="line">⠀⠙⣌⠳⣄⠀⡇ ⠀⡏⠀⠀⠈⠳⡌⠀</span><br><span class="line">⠀</span><br></pre></td></tr></table></figure><hr><figure class="highlight plaintext"><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><br><span class="line">┣┫██████┏━┓█┃ </span><br><span class="line">┣┫██████┃秀┃█┃ </span><br><span class="line">┣┫██████┃儿┃█┃ </span><br><span class="line">┣┫██████┃大┃█┃ </span><br><span class="line">┣┫██████┃全┃█┃ </span><br><span class="line">┣┫██████┗━┛█┃ </span><br><span class="line">┣┫██████████┃ </span><br><span class="line">┗┻━━━━━━━━━━┛</span><br></pre></td></tr></table></figure>]]></content>
<categories>
<category> 有趣的知识 </category>
</categories>
<tags>
<tag> 符号的艺术 </tag>
</tags>
</entry>
<entry>
<title>docker学习记录</title>
<link href="/c018.html"/>
<url>/c018.html</url>
<content type="html"><![CDATA[<h1>Docker</h1><h2 id="pmm">pmm</h2><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><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"># admin</span></span><br><span class="line">docker <span class="keyword">run</span><span class="language-bash"> -d --name=pmm --restart=always \</span></span><br><span class="line"><span class="language-bash">-p 2812:2812 -p 2813:80 -p 2814:443 \</span></span><br><span class="line"><span class="language-bash">--privileged=<span class="literal">true</span> \</span></span><br><span class="line"><span class="language-bash">percona/pmm-server:latest</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># client</span></span><br><span class="line">docker <span class="keyword">run</span><span class="language-bash"> -d --net=pxc_network \</span></span><br><span class="line"><span class="language-bash">--name pmm-client \</span></span><br><span class="line"><span class="language-bash">-v /etc/localtime:/etc/localtime \</span></span><br><span class="line"><span class="language-bash">-e PMM_AGENT_SERVER_ADDRESS=10.252.110.188:2814 \</span></span><br><span class="line"><span class="language-bash">-e PMM_AGENT_SERVER_USERNAME=admin \</span></span><br><span class="line"><span class="language-bash">-e PMM_AGENT_SERVER_PASSWORD=admin \</span></span><br><span class="line"><span class="language-bash">-e PMM_AGENT_SERVER_INSECURE_TLS=1 \</span></span><br><span class="line"><span class="language-bash">-e PMM_AGENT_SETUP=1 \</span></span><br><span class="line"><span class="language-bash">-e PMM_AGENT_CONFIG_FILE=config/pmm-agent.yaml \</span></span><br><span class="line"><span class="language-bash">percona/pmm-client:latest </span></span><br><span class="line"></span><br><span class="line">pmm-admin <span class="keyword">add</span><span class="language-bash"> mysql --host=opalpxc3 --port=3306 --username=pmm --password=Mes_opal123 --service-name=pxc3</span></span><br><span class="line"></span><br><span class="line">在安装pmm-client客户端的主机上,添加监控的MySQL实例</span><br><span class="line"> </span><br><span class="line">pmm-admin <span class="keyword">add</span><span class="language-bash"> mysql --username=username --password=password --tls --tls-skip-verify --tls-ca=pathtoca.pem --tls-cert=pathtocert.pem --tls-key=pathtocertkey.pem --server-url=http://admin:admin@172.16.130.12 --query-source=perfschema name 172.16.130.53:3308</span></span><br><span class="line"></span><br><span class="line">pmm-admin <span class="keyword">add</span><span class="language-bash"> proxysql --host=10.252.110.183 --port=6033 --username=mes_opal --password=Mes_opal123 --service-name=proxysql</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">pmm-admin <span class="keyword">add</span><span class="language-bash"> mysql --query-source=perfschema --username=pmm --password=Mes_opal123 --service-name=client_pxc1 --host=10.252.110.180 --port=3306</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">docker exec -it pmm-client bash</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">#查询存在的节点</span></span><br><span class="line">pmm-admin inventory list services --service-type=mysql</span><br></pre></td></tr></table></figure><h2 id="修改容器名">修改容器名</h2><figure class="highlight dockerfile"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker rename pmm-server pmm-server-old</span><br></pre></td></tr></table></figure><h2 id="设置日志大小">设置日志大小</h2><figure class="highlight dockerfile"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker update --log-opt max-size=<span class="number">20</span>m --log-opt max-file=<span class="number">30</span> <container-id></span><br></pre></td></tr></table></figure><h2 id="自动重启容器">自动重启容器</h2><figure class="highlight dockerfile"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker update --restart=always 容器ID(或者容器名)</span><br></pre></td></tr></table></figure><h2 id="docker镜像命令">docker镜像命令</h2><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><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">docker version #显示docker版本信息</span><br><span class="line">docker info #显示docker的系统信息</span><br><span class="line">docker 命令 --hepl #帮助命令</span><br><span class="line"></span><br><span class="line">docker images #查询当前容器中的镜像</span><br><span class="line"><span class="meta prompt_"></span></span><br><span class="line"><span class="meta prompt_">#</span><span class="language-bash">搜索镜像</span></span><br><span class="line">docker search 软件名</span><br><span class="line"><span class="meta prompt_"></span></span><br><span class="line"><span class="meta prompt_">#</span><span class="language-bash">下载镜像,默认下载最新版本---latest</span></span><br><span class="line">docker pull 软件名</span><br><span class="line"><span class="meta prompt_">#</span><span class="language-bash">指定版本下载</span></span><br><span class="line">docker pull 软件名:版本号(指定把版本号时必须保证dockhub中存在)</span><br><span class="line">https://hub.docker.com/</span><br><span class="line"><span class="meta prompt_"></span></span><br><span class="line"><span class="meta prompt_"></span></span><br><span class="line"><span class="meta prompt_">#</span><span class="language-bash">删除镜像</span></span><br><span class="line">docker rmi -f 软件名或者id,多个用空格隔开</span><br><span class="line"><span class="meta prompt_">#</span><span class="language-bash">删除所有</span></span><br><span class="line">docker rmi -f $(docker images) </span><br></pre></td></tr></table></figure><h2 id="docker容器命令">docker容器命令</h2><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><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></pre></td><td class="code"><pre><span class="line"><span class="meta prompt_">#</span><span class="language-bash">下载一个容器</span></span><br><span class="line">docker pull centos</span><br><span class="line"><span class="meta prompt_"></span></span><br><span class="line"><span class="meta prompt_">#</span><span class="language-bash">启动一个容器</span></span><br><span class="line">docker run [参数] 容器名</span><br><span class="line"></span><br><span class="line">--name = "" #容器名称</span><br><span class="line">-d #后台运行</span><br><span class="line">-it #启动并且进入容器</span><br><span class="line">-p #指定端口</span><br><span class="line"> -p ip:主机端口:容器端口</span><br><span class="line"> -p 主机端口:容器端口</span><br><span class="line"> -p 容器端口</span><br><span class="line"> 不指定则随机端口</span><br><span class="line">--rm #用完即删,用于测试</span><br><span class="line"><span class="meta prompt_"></span></span><br><span class="line"><span class="meta prompt_">#</span><span class="language-bash">运行nginx,指定名称为nginx1,后台方式运行,指定主机端口3344,容器端口80</span></span><br><span class="line">docker run -d --name nginx1 -p 3344:80 nginx</span><br><span class="line"><span class="meta prompt_"></span></span><br><span class="line"><span class="meta prompt_">#</span><span class="language-bash">进入正在运行的容器</span></span><br><span class="line">docker exec -it 容器id #进入容器</span><br><span class="line">docker attach 容器id #进入容器正在执行的终端</span><br><span class="line"><span class="meta prompt_"></span></span><br><span class="line"><span class="meta prompt_"></span></span><br><span class="line"><span class="meta prompt_">#</span><span class="language-bash">查询运行的容器</span></span><br><span class="line">docker ps []</span><br><span class="line"> -a #查询运行过的容器</span><br><span class="line"> -n = 1 #显示指定个数</span><br><span class="line"><span class="meta prompt_"></span></span><br><span class="line"><span class="meta prompt_">#</span><span class="language-bash">退出容器</span></span><br><span class="line">exit #退出并且停止</span><br><span class="line">ctrl+p+q #退出不停止</span><br><span class="line"><span class="meta prompt_"></span></span><br><span class="line"><span class="meta prompt_">#</span><span class="language-bash">删除容器</span></span><br><span class="line">docker rm 容器id或名称</span><br><span class="line"> -f #强制删除,无论是否运行</span><br><span class="line"><span class="meta prompt_"></span></span><br><span class="line"><span class="meta prompt_">#</span><span class="language-bash">查看容器的占用情况</span></span><br><span class="line">docker stats 容器id</span><br><span class="line"><span class="meta prompt_"></span></span><br><span class="line"><span class="meta prompt_">#</span><span class="language-bash">启动容器</span></span><br><span class="line">docker start 容器id</span><br><span class="line"><span class="meta prompt_">#</span><span class="language-bash">停止容器</span></span><br><span class="line">docker stop 容器id</span><br><span class="line"><span class="meta prompt_">#</span><span class="language-bash">重启容器</span></span><br><span class="line">docker restart 容器id</span><br><span class="line"><span class="meta prompt_">#</span><span class="language-bash">强制停止</span></span><br><span class="line">docker kill 容器id</span><br></pre></td></tr></table></figure><h2 id="查看日志">查看日志</h2><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></pre></td><td class="code"><pre><span class="line">docker logs [参数] 容器id</span><br><span class="line"> -ft #显示所有日志以及时间戳</span><br><span class="line"> --tail 10 #显示10行</span><br></pre></td></tr></table></figure><h2 id="查看容器中的进程">查看容器中的进程</h2><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker top 容器id</span><br></pre></td></tr></table></figure><h2 id="从容器内拷贝到主机">从容器内拷贝到主机</h2><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker cp 容器id:文件路径 主机路径</span><br></pre></td></tr></table></figure><h2 id="测试">测试</h2><figure class="highlight shell"><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 prompt_">#</span><span class="language-bash">安装nginx</span></span><br><span class="line">docker pull nginx</span><br></pre></td></tr></table></figure><h2 id="可视化-portsiner-文档">可视化(portsiner)<a href="https://docs.portainer.io/start/install/agent/docker/linux">文档</a></h2><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></pre></td><td class="code"><pre><span class="line"><span class="meta prompt_">#</span><span class="language-bash">官方文档</span></span><br><span class="line">[文档](https://docs.portainer.io/start/install/agent/docker/linux)</span><br><span class="line"><span class="meta prompt_"></span></span><br><span class="line"><span class="meta prompt_">#</span><span class="language-bash">安装命令</span></span><br><span class="line">docker run -d -p 9001:9001 --name portainer_agent --restart=always -v /var/run/docker.sock:/var/run/docker.sock -v /var/lib/docker/volumes:/var/lib/docker/volumes portainer/agent:latest</span><br></pre></td></tr></table></figure><h2 id="commit镜像">commit镜像</h2><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></pre></td><td class="code"><pre><span class="line">docker commit -a cb e146099b156 tomcatcb:1.0</span><br><span class="line"> -a #提交作者名称</span><br><span class="line"> -m #提交的内容注释</span><br></pre></td></tr></table></figure><h2 id="容器数据卷">容器数据卷</h2><h3 id="指定路径挂载">指定路径挂载</h3><ul><li>将容器中的数据挂载到主机中,其实就是容器的持久化和同步</li></ul><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></pre></td><td class="code"><pre><span class="line">docker run -it -v 主机目录:容器目录</span><br><span class="line"><span class="meta prompt_"></span></span><br><span class="line"><span class="meta prompt_">#</span><span class="language-bash">将tomcat的webapps目录挂载到主机中</span></span><br><span class="line">docker run -d -p 3344:8080 -v /root/tomcat/:/usr/local/tomcat/webapps tomcatcb:1.0</span><br></pre></td></tr></table></figure><h3 id="匿名挂载">匿名挂载</h3><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><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="meta prompt_">#</span><span class="language-bash">-v时不指定主机目录</span></span><br><span class="line">docker run -d -p 3344:8080 --name niming-tomcat -v /usr/local/tomcat/webapps tomcatcb:1.0</span><br><span class="line"><span class="meta prompt_"></span></span><br><span class="line"><span class="meta prompt_">#</span><span class="language-bash">查看镜像配置</span></span><br><span class="line">docker inspect niming-tomcat</span><br><span class="line"></span><br><span class="line">"Mounts": [</span><br><span class="line"> {</span><br><span class="line"> "Type": "volume",</span><br><span class="line"> "Name": "9001da5b9732a3a17890977ed04e38eedf3db29573c606f674df2673f95b6d37",</span><br><span class="line"> "Source": </span><br><span class="line"> #这里目录为随机目录</span><br><span class="line">"/var/lib/docker/volumes/9001da5b9732a3a17890977ed04e38eedf3db29573c606f674df2673f95b6d37/_data", </span><br><span class="line"> "Destination": "/usr/local/tomcat/webapps",</span><br><span class="line"> "Driver": "local",</span><br><span class="line"> "Mode": "",</span><br><span class="line"> "RW": true,</span><br><span class="line"> "Propagation": ""</span><br><span class="line"> }</span><br><span class="line"> ]</span><br></pre></td></tr></table></figure><h3 id="具名挂载">具名挂载</h3><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><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></pre></td><td class="code"><pre><span class="line"><span class="meta prompt_">#</span><span class="language-bash">-v时指定一个主机名称而不指定目录</span></span><br><span class="line">docker run -d --name jvanming-tomcat -p 3302:8080 -v jvanming-tomcat:/usr/local/tomcat/webapps tomcatcb:1.0</span><br><span class="line"><span class="meta prompt_"></span></span><br><span class="line"><span class="meta prompt_"></span></span><br><span class="line"><span class="meta prompt_">#</span><span class="language-bash">查看镜像配置</span></span><br><span class="line">docker inspect jvanming-tomcat</span><br><span class="line"></span><br><span class="line">"Mounts": [</span><br><span class="line"> {</span><br><span class="line"> "Type": "volume",</span><br><span class="line"> "Name": "jvanming-tomcat",</span><br><span class="line"> "Source": "/var/lib/docker/volumes/jvanming-tomcat/_data", #这里目录为我们指定的目录</span><br><span class="line"> "Destination": "/usr/local/tomcat/webapps",</span><br><span class="line"> "Driver": "local",</span><br><span class="line"> "Mode": "z",</span><br><span class="line"> "RW": true,</span><br><span class="line"> "Propagation": ""</span><br><span class="line"> }</span><br><span class="line"> ]</span><br></pre></td></tr></table></figure><h2 id="扩展">扩展</h2><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></pre></td><td class="code"><pre><span class="line"><span class="meta prompt_">#</span><span class="language-bash">还可以指定权限</span></span><br><span class="line">docker run -v jvming:/etc:[ro|rw]</span><br><span class="line"></span><br><span class="line">ro readOnly 只读</span><br><span class="line">rw readWrite 可读可写</span><br><span class="line">如果为只读那么容器中的配置文件无法修改,只能主机来修改</span><br></pre></td></tr></table></figure><h2 id="安装MySQL并且将数据文件挂载到主机中">安装MySQL并且将数据文件挂载到主机中</h2><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></pre></td><td class="code"><pre><span class="line"><span class="meta prompt_"># </span><span class="language-bash">1.下载mysql</span></span><br><span class="line">docker pull mysql:8</span><br><span class="line"><span class="meta prompt_"></span></span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">2.启动</span></span><br><span class="line">docker run -d -p 3308:3306 </span><br><span class="line">-v /root/dockerData/mysql/conf:/etc/mysql/conf.d #指定挂载目录,配置文件</span><br><span class="line">-v /root/dockerData/mysql/data:/var/lib/mysql #指定挂载目录,数据库文件</span><br><span class="line">-e MYSQL_ROOT_PASSWORD=123456 #指定连接密码</span><br><span class="line">--name mysql01 mysql:8 #指定版本</span><br></pre></td></tr></table></figure><h2 id="DockerFile">DockerFile</h2><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></pre></td><td class="code"><pre><span class="line">FROM # 基础镜像</span><br><span class="line">MAINTAINER # 指定镜像作者</span><br><span class="line">RUN # 镜像构建是需要运行的命令</span><br><span class="line">ADD # 添加内容</span><br><span class="line">WORDDIR # 镜像工作目录</span><br><span class="line">VOLOME # 挂载的目录</span><br><span class="line">EXPOSE # 端口</span><br><span class="line">ONBUILD # 继承镜像时执行该命令</span><br><span class="line">COPY # 类似add。将文件拷贝到镜像中</span><br><span class="line">ENV # 设置环境变量</span><br></pre></td></tr></table></figure><h2 id="配置tomcat环境的DockerFile脚本">配置tomcat环境的DockerFile脚本</h2><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><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></pre></td><td class="code"><pre><span class="line"><span class="meta prompt_"># </span><span class="language-bash">1. 编写dockerfile脚本</span></span><br><span class="line">from centos:8 #初始容器centos8</span><br><span class="line"></span><br><span class="line">maintainer chenbo #作者名称</span><br><span class="line"></span><br><span class="line">copy readme.txt /usr/local/ #拷贝文件</span><br><span class="line"></span><br><span class="line">add apache-tomcat-8.5.79.tar.gz /usr/local #添加依赖</span><br><span class="line">add jdk-8u333-linux-x64.tar.gz /usr/local #添加依赖</span><br><span class="line"></span><br><span class="line">workdir /usr/local #工作目录</span><br><span class="line"></span><br><span class="line">env JAVA_HOME /usr/local/jdk1.8.0_333 #配置环境变量</span><br><span class="line">env CLASSPATH $JAVA_HOME/lib/tools.jar:$JAVA_HOME/lib</span><br><span class="line"></span><br><span class="line">env CATALINA_HOME /usr/local/apache-tomcat-8.5.79</span><br><span class="line">env CATALINA_BASH /usr/local/apache-tomcat-8.5.79</span><br><span class="line"></span><br><span class="line">env PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_BASH/bin</span><br><span class="line"></span><br><span class="line">expose 8080 #端口</span><br><span class="line"><span class="meta prompt_"></span></span><br><span class="line"><span class="meta prompt_"></span></span><br><span class="line"><span class="meta prompt_">#</span><span class="language-bash">启动tomcat脚本</span></span><br><span class="line">cmd /usr/local/apache-tomcat-8.5.79/bin/startup.sh && tail -F /usr/local/apache-tomcat-8.5.79/logs/log.out</span><br><span class="line"><span class="meta prompt_"></span></span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">2.编译脚本文件</span></span><br><span class="line"><span class="meta prompt_">#</span><span class="language-bash">-t指定镜像名称和版本 -f指定脚本文件 .指定当前目录</span></span><br><span class="line">docker build -t mytomcat-diy:1.0 -f my-tomcat-test .</span><br><span class="line"><span class="meta prompt_"></span></span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">启动镜像</span></span><br><span class="line">docker run -d -p 8080:8080 --name chenbotomcatdiy -v /root/dockerData/my-tomcat/jar/:/usr/local/apache-tomcat-8.5.79/webapps/test -v /root/dockerData/my-tomcat/logs:/usr/local/apache-tomcat-8.5.79/logs -it mytomcat-diy:1.0</span><br></pre></td></tr></table></figure><h2 id="提交到远程仓库">提交到远程仓库</h2><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker </span><br></pre></td></tr></table></figure><h2 id="docker-compose">docker-compose</h2><ul><li>容器编排技术</li></ul><h3 id="compose相关命令">compose相关命令</h3><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><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta prompt_"># </span><span class="language-bash">查看当前正在运行的项目</span></span><br><span class="line">docker-compose ps</span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">创建并启动容器</span></span><br><span class="line">docker-compose up</span><br><span class="line"> -f #指定docker-compose文件位置,不指定默认当前位置</span><br><span class="line"> -p #指定项目名称,默认目录名</span><br><span class="line"> -d #后台运行</span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">构建容器</span></span><br><span class="line">docker-compose build</span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">停止</span></span><br><span class="line">docker-compose down</span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">验证并查看 Compose 文件,有错误时会提示行号</span></span><br><span class="line">docker-compose config </span><br></pre></td></tr></table></figure><figure class="highlight yaml"><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><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">version:</span> <span class="string">"3"</span></span><br><span class="line"><span class="attr">services:</span></span><br><span class="line"> <span class="attr">nginx:</span></span><br><span class="line"> <span class="attr">image:</span> <span class="string">nginx:1.21.6</span></span><br><span class="line"> <span class="attr">ports:</span></span><br><span class="line"> <span class="bullet">-</span> <span class="string">"8022:80"</span></span><br><span class="line"> <span class="attr">volumes:</span></span><br><span class="line"> <span class="bullet">-</span> <span class="string">"/docker-project-data/nginx/nginx.conf:/etc/nginx/nginx.conf"</span></span><br><span class="line"></span><br><span class="line"> <span class="attr">rabbitmq:</span></span><br><span class="line"> <span class="attr">image:</span> <span class="string">rabbitmq:3.10.2-management</span></span><br><span class="line"> <span class="attr">ports:</span></span><br><span class="line"> <span class="bullet">-</span> <span class="string">"5672:5672"</span></span><br><span class="line"> <span class="bullet">-</span> <span class="string">"15672:15672"</span></span><br><span class="line"> <span class="attr">environment:</span></span><br><span class="line"> <span class="bullet">-</span> <span class="string">RABBITMQ_DEFAULT_USER:guest</span></span><br><span class="line"> <span class="bullet">-</span> <span class="string">RABBITMQ_DEFAULT_PASS:guest</span></span><br><span class="line"> <span class="bullet">-</span> <span class="string">loopback_users:none</span> <span class="comment">#远程访问</span></span><br><span class="line"> <span class="attr">volumes:</span></span><br><span class="line"> <span class="bullet">-</span> <span class="string">"/docker-project-data/rabbitmq/rabbitmq.conf:/etc/rabbitmq/rabbitmq.conf"</span></span><br><span class="line"></span><br><span class="line"> <span class="attr">redis:</span></span><br><span class="line"> <span class="attr">image:</span> <span class="string">redis:7.0.0</span></span><br><span class="line"> <span class="attr">ports:</span></span><br><span class="line"> <span class="bullet">-</span> <span class="string">"6381:6379"</span></span><br><span class="line"> <span class="attr">volumes:</span></span><br><span class="line"> <span class="bullet">-</span> <span class="string">"/docker-project-data/redis/redis.conf:/usr/local/etc/redis/redis.conf"</span></span><br><span class="line"> <span class="bullet">-</span> <span class="string">"/docker-project-data/redis/data:/data"</span></span><br><span class="line"> <span class="attr">environment:</span></span><br><span class="line"> <span class="bullet">-</span> <span class="string">“appendonly=yes”</span> <span class="comment">#数据持久化</span></span><br><span class="line"> <span class="attr">command:</span></span><br><span class="line"> <span class="string">--requirepass</span> <span class="string">"123456"</span> <span class="comment">#这一行是设置密码</span></span><br><span class="line"></span><br><span class="line"> <span class="attr">mysql:</span></span><br><span class="line"> <span class="attr">image:</span> <span class="string">mysql:8</span></span><br><span class="line"> <span class="attr">ports:</span></span><br><span class="line"> <span class="bullet">-</span> <span class="string">"3307:3306"</span></span><br><span class="line"> <span class="attr">volumes:</span></span><br><span class="line"> <span class="bullet">-</span> <span class="string">"/docker-project-data/mysql/conf.d:/etc/mysql/conf.d"</span> <span class="comment">#指定挂载目录,配置文件</span></span><br><span class="line"> <span class="bullet">-</span> <span class="string">"/docker-project-data/mysql/data:/var/lib/mysql"</span> <span class="comment">#指定挂载目录,数据库文件</span></span><br><span class="line"> <span class="attr">environment:</span></span><br><span class="line"> <span class="bullet">-</span> <span class="string">MYSQL_ROOT_PASSWORD:"123456"</span></span><br><span class="line"></span><br><span class="line"> <span class="attr">jar:</span></span><br><span class="line"> <span class="attr">image:</span> <span class="string">chendd1314/getwebdata-dockerfile:1.0</span></span><br><span class="line"> <span class="attr">volumes:</span></span><br><span class="line"> <span class="bullet">-</span> <span class="string">"/docker-project-data/jar/log/:/log/"</span></span><br><span class="line"> <span class="attr">ports:</span></span><br><span class="line"> <span class="bullet">-</span> <span class="string">"9091:9091"</span></span><br><span class="line"></span><br><span class="line"> <span class="attr">centos:</span></span><br><span class="line"> <span class="attr">image:</span> <span class="string">c</span></span><br></pre></td></tr></table></figure><h2 id="镜像和容器的导入导出">镜像和容器的导入导出</h2><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></pre></td><td class="code"><pre><span class="line"><span class="meta prompt_"># </span><span class="language-bash">导出</span></span><br><span class="line">docker save -o 指定路径 指定镜像名称</span><br><span class="line"><span class="meta prompt_"></span></span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">导入</span></span><br><span class="line">docker load -i 镜像路径</span><br></pre></td></tr></table></figure><p>==容器导入导出==</p><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></pre></td><td class="code"><pre><span class="line"><span class="meta prompt_">#</span><span class="language-bash">导出</span></span><br><span class="line">docker export -o 文件全路径 镜像名称</span><br><span class="line"><span class="meta prompt_"></span></span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">导入</span></span><br><span class="line">docker import 文件全路径</span><br></pre></td></tr></table></figure><blockquote><p>导出是文件后缀为tar</p><p>save保存的是镜像,export保存的是容器<br>load用来载入镜像包,import用来载入容器包,但两者都会恢复为镜像<br>load不能对载入的镜像重命名,而import可以为镜像指定新名称<br>load不能载入容器包,import能载入镜像包,但不能使用</p></blockquote><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo docker run --name xxl-job-admin -d -p 8090:8090 -v /home/datadisk/xxl-job-admin/config/application.properties:/application.properties -v /home/datadisk/xxl-job-admin/log:/data/applogs xuxueli/xxl-job-admin </span><br></pre></td></tr></table></figure>]]></content>
<categories>
<category> 笔记 </category>
</categories>
<tags>
<tag> docker </tag>
</tags>
</entry>
<entry>
<title>常用知识总结</title>
<link href="/4814.html"/>
<url>/4814.html</url>
<content type="html"><![CDATA[<h1>技巧总结</h1><h2 id="linux查找进程">linux查找进程</h2><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></pre></td><td class="code"><pre><span class="line"><span class="meta prompt_"># </span><span class="language-bash">根据端口号查找进程</span></span><br><span class="line">ss -tulnp | grep :端口号</span><br><span class="line"></span><br><span class="line">lsof -i :端口号</span><br><span class="line"><span class="meta prompt_"></span></span><br><span class="line"><span class="meta prompt_">#</span><span class="language-bash">g根据进程名查找进程</span></span><br><span class="line">ps aux | grep 进程名</span><br></pre></td></tr></table></figure><h2 id="fastjson序列化时不忽略为空的字段">fastjson序列化时不忽略为空的字段</h2><figure class="highlight java"><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">JSON.toJSONString(changeEvent, SerializerFeature.WriteNullStringAsEmpty);</span><br><span class="line"><span class="comment">//将为空的字段显示为null</span></span><br><span class="line">JSON.toJSONString(changeEvent, SerializerFeature.WriteMapNullValue)</span><br></pre></td></tr></table></figure><h2 id="nginx正向代理">nginx正向代理</h2><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><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="section">server</span> {</span><br><span class="line"> <span class="attribute">listen</span> <span class="number">8888</span>; <span class="comment"># 选择一个合适的端口号,此处为 8888</span></span><br><span class="line"> <span class="attribute">server_name</span> localhost; <span class="comment"># 可以是本机的 IP 地址或 localhost</span></span><br><span class="line"> <span class="section">location</span> / {</span><br><span class="line"> <span class="attribute">resolver</span> <span class="number">8.8.8.8</span>; <span class="comment"># 使用 Google 的 DNS 服务器,可以根据需要更改</span></span><br><span class="line"> <span class="attribute">proxy_pass</span> http://<span class="variable">$host</span><span class="variable">$request_uri</span>;</span><br><span class="line"> <span class="attribute">proxy_set_header</span> Host <span class="variable">$host</span>;</span><br><span class="line"> <span class="attribute">proxy_set_header</span> X-Real-IP <span class="variable">$remote_addr</span>;</span><br><span class="line"> <span class="attribute">proxy_set_header</span> X-Forwarded-For <span class="variable">$proxy_add_x_forwarded_for</span>;</span><br><span class="line"> <span class="attribute">proxy_set_header</span> X-Forwarded-Proto <span class="variable">$scheme</span>;</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h2 id="git代理">git代理</h2><figure class="highlight bat"><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></pre></td><td class="code"><pre><span class="line"># 设置HTTP代理</span><br><span class="line">git config --global http.proxy http://<span class="number">127</span>.<span class="number">0</span>.<span class="number">0</span>.<span class="number">1</span>:<span class="number">7890</span></span><br><span class="line"></span><br><span class="line"># 设置HTTPS代理</span><br><span class="line">git config --global https.proxy http://<span class="number">127</span>.<span class="number">0</span>.<span class="number">0</span>.<span class="number">1</span>:<span class="number">7890</span></span><br><span class="line"></span><br><span class="line"># 关闭HTTP代理</span><br><span class="line">git config --global --unset http.proxy</span><br><span class="line"></span><br><span class="line"># 关闭HTTPS代理</span><br><span class="line">git config --global --unset https.proxy</span><br><span class="line"></span><br><span class="line"># 查看HTTP代理</span><br><span class="line">git config --global http.proxy</span><br><span class="line"></span><br><span class="line"># 查看HTTPS代理</span><br><span class="line">git config --global https.proxy</span><br></pre></td></tr></table></figure><h2 id="mysql创建触发器">mysql创建触发器</h2><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 class="keyword">CREATE</span> <span class="keyword">TRIGGER</span> trigger_name</span><br><span class="line">{BEFORE <span class="operator">|</span> AFTER} {<span class="keyword">INSERT</span> <span class="operator">|</span> <span class="keyword">UPDATE</span> <span class="operator">|</span> <span class="keyword">DELETE</span>}</span><br><span class="line"><span class="keyword">ON</span> table_name <span class="keyword">FOR</span> <span class="keyword">EACH</span> <span class="type">ROW</span></span><br><span class="line"><span class="keyword">BEGIN</span></span><br><span class="line"> <span class="comment">-- 触发器执行的SQL语句</span></span><br><span class="line"><span class="keyword">END</span>;</span><br></pre></td></tr></table></figure><h2 id="window事件id">window事件id</h2><figure class="highlight plaintext"><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">事件id:</span><br><span class="line">1074 重启</span><br><span class="line">6005 启动</span><br><span class="line">6006 关机</span><br></pre></td></tr></table></figure><h2 id="oracle结束job">oracle结束job</h2><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></pre></td><td class="code"><pre><span class="line"><span class="operator">/</span><span class="operator">/</span>获取正在运行的job</span><br><span class="line"><span class="keyword">select</span> <span class="operator">*</span> <span class="keyword">from</span> dba_jobs_running;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="operator">/</span><span class="operator">/</span>获取正在运行job(<span class="number">24</span>)的详细信息</span><br><span class="line"><span class="keyword">select</span> b.SID,b.SERIAL#,c.SPID</span><br><span class="line"><span class="keyword">from</span> dba_jobs_running a,v$session b,v$process c</span><br><span class="line"><span class="keyword">where</span> a.sid <span class="operator">=</span> b.sid <span class="keyword">and</span> b.PADDR <span class="operator">=</span> c.ADDR <span class="keyword">and</span> a.job<span class="operator">=</span><span class="number">24</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="operator">/</span><span class="operator">/</span>杀死job</span><br><span class="line"><span class="keyword">ALTER</span> <span class="keyword">SYSTEM</span> KILL SESSION <span class="string">'75,46547'</span>;</span><br></pre></td></tr></table></figure><h2 id="mysql查询排序规则">mysql查询排序规则</h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">SELECT table_name, column_name, collation_name FROM information_schema.columns WHERE table_schema = 'your_database_name';</span><br></pre></td></tr></table></figure><h2 id="jar包压缩解压">jar包压缩解压</h2><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></pre></td><td class="code"><pre><span class="line"><span class="meta prompt_"># </span><span class="language-bash">解压</span></span><br><span class="line">jar -xvf *.jar</span><br><span class="line"><span class="meta prompt_"></span></span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">压缩</span></span><br><span class="line">jar -cfM0 name.jar BOOT-INF/ META-INF/ org/</span><br></pre></td></tr></table></figure><h2 id="mysql插入或更新">mysql插入或更新</h2><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></pre></td><td class="code"><pre><span class="line"># 需要有唯一索引或者主键才能判断是否执行插入或更新</span><br><span class="line"><span class="keyword">INSERT</span> <span class="keyword">INTO</span> table_name (column1, column2, ...) <span class="keyword">VALUES</span> (value1, value2, ...)</span><br><span class="line"><span class="keyword">ON</span> DUPLICATE KEY <span class="keyword">UPDATE</span> column1 <span class="operator">=</span> value1, column2 <span class="operator">=</span> value2, ...;</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> t_pm_unmatchalarmpoint (Company_Id, DCS_Code, PrdtCell_Id, Tag, Write_Date)</span><br><span class="line"><span class="keyword">VALUES</span> (<span class="number">25</span>, <span class="number">2</span>, <span class="number">22528</span>, <span class="number">1</span>, <span class="string">'2022-01-01 11:11:11'</span>)</span><br><span class="line"><span class="keyword">ON</span> DUPLICATE KEY <span class="keyword">UPDATE</span> Write_Date <span class="operator">=</span> sysdate();</span><br></pre></td></tr></table></figure><h2 id="oracle强制结束进程">oracle强制结束进程</h2><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">ALTER</span> <span class="keyword">SYSTEM</span> KILL SESSION <span class="string">'1447,9425'</span> immediate; </span><br></pre></td></tr></table></figure><h2 id="oracle创建自增序列">oracle创建自增序列</h2><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">create</span> sequence s_ad_alarmexaminerec</span><br><span class="line"> minvalue <span class="number">1</span> <span class="comment">--增长最小值</span></span><br><span class="line"> maxvalue <span class="number">9999999999</span> <span class="comment">--增长最大值,也可以设置NOMAXvalue -- 不设置最大值</span></span><br><span class="line"> <span class="keyword">start</span> <span class="keyword">with</span> <span class="number">1</span> <span class="comment">--从1=开始计数</span></span><br><span class="line"> increment <span class="keyword">by</span> <span class="number">1</span> <span class="comment">--自增步长为1</span></span><br><span class="line"> cache <span class="number">50</span> <span class="comment">--设置缓存cache个序列,如果系统down掉了或者其它情况将会导致序列不连续,也可以设置为---NOCACHE防止跳号</span></span><br><span class="line"> <span class="keyword">cycle</span>; <span class="comment">--循环,当达到最大值时,不是从start with设置的值开始循环。而是从1开始循环</span></span><br><span class="line"> </span><br><span class="line"><span class="comment">-- 删除</span></span><br><span class="line"><span class="keyword">DROP</span> SEQUENCE s_PM_TAGEXTRAMESSAGE;</span><br><span class="line"></span><br><span class="line"><span class="comment">-- 修改</span></span><br><span class="line"><span class="keyword">ALTER</span> SEQUENCE s_PM_MOBILELIST INCREMENT <span class="keyword">BY</span> <span class="number">10001</span>;</span><br></pre></td></tr></table></figure><h2 id="修改时区">修改时区</h2><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 prompt_">#</span><span class="language-bash">容器</span></span><br><span class="line">docker exec -it -u root 容器名或id /bin/sh</span><br><span class="line">mkdir -p /usr/share/zoneinfo/Asia</span><br><span class="line">exit</span><br><span class="line">docker cp /usr/share/zoneinfo/Asia/Shanghai 容器ID或容器名:/usr/share/zoneinfo/Asia</span><br><span class="line">docker exec -it -u root 容器名或id /bin/sh</span><br><span class="line">cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime</span><br><span class="line"><span class="meta prompt_"></span></span><br><span class="line"><span class="meta prompt_">#</span><span class="language-bash">tomcat</span></span><br><span class="line">vi bin/catalina.sh</span><br><span class="line"></span><br><span class="line">JAVA_OPTS="$JAVA_OPTS -Djava.protocol.handler.pkgs=org.apache.catalina.webresources -Duser.timezone=GMT+08"</span><br></pre></td></tr></table></figure><h2 id="mysql备份恢复">mysql备份恢复</h2><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></pre></td><td class="code"><pre><span class="line">#备份</span><br><span class="line">mysqldump <span class="operator">-</span>h10<span class="number">.252</span><span class="number">.110</span><span class="number">.183</span> <span class="operator">-</span>P6033 <span class="operator">-</span>umes_opal <span class="operator">-</span>pMes_opal123 <span class="comment">--default-character-set gbk --single-transaction mes_opal --no-create-info t_ad_alarmrec -w "alarm_point_id is not null order by alarm_rec_id desc" > D:\chenbo\alarmrec20230411.sql</span></span><br><span class="line"></span><br><span class="line">mysqldump <span class="operator">-</span>h10<span class="number">.252</span><span class="number">.110</span><span class="number">.183</span> <span class="operator">-</span>P6033 <span class="operator">-</span>umes_opal <span class="operator">-</span>pMes_opal123 <span class="comment">--default-character-set gbk --no-create-info mes_opal t_ad_alarmevent -w "alarm_point_id is not null" > D:\chenbo\alarmevent.sql</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">#恢复</span><br><span class="line">mysql <span class="operator">-</span>h10<span class="number">.252</span><span class="number">.110</span><span class="number">.180</span> <span class="operator">-</span>umes_opal <span class="operator">-</span>pMes_opal123</span><br><span class="line">use mes_opal</span><br><span class="line">source D:\chenbo\alarmevent.sql</span><br><span class="line">source D:\chenbo\alarmrec.sql</span><br><span class="line"></span><br><span class="line">#其他命令</span><br><span class="line">–<span class="keyword">no</span><span class="operator">-</span><span class="keyword">create</span><span class="operator">-</span>db, —取消创建数据库<span class="keyword">sql</span>(默认存在)</span><br><span class="line">–<span class="keyword">no</span><span class="operator">-</span><span class="keyword">create</span><span class="operator">-</span>info,—取消创建表<span class="keyword">sql</span>(默认存在)</span><br><span class="line">–<span class="keyword">no</span><span class="operator">-</span>data —不导出数据(默认导出)</span><br><span class="line">–<span class="keyword">add</span><span class="operator">-</span><span class="keyword">drop</span><span class="operator">-</span>database —增加删除数据库<span class="keyword">sql</span>(默认不存在)</span><br><span class="line">–<span class="keyword">skip</span><span class="operator">-</span><span class="keyword">add</span><span class="operator">-</span><span class="keyword">drop</span><span class="operator">-</span><span class="keyword">table</span> —取消每个数据表创建之前添加<span class="keyword">drop</span>数据表语句(默认每个表之前存在<span class="keyword">drop</span>语句)</span><br><span class="line">–<span class="keyword">skip</span><span class="operator">-</span><span class="keyword">add</span><span class="operator">-</span>locks —取消在每个表导出之前增加LOCK TABLES(默认存在锁)</span><br><span class="line">–<span class="keyword">skip</span><span class="operator">-</span>comments —注释信息(默认存在)</span><br><span class="line"></span><br></pre></td></tr></table></figure><h2 id="window自启动jar">window自启动jar</h2><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></pre></td><td class="code"><pre><span class="line"><span class="meta prompt_">#</span><span class="language-bash">新建start.bat</span></span><br><span class="line">java -jar xxx.jar</span><br><span class="line"><span class="meta prompt_">#</span><span class="language-bash">新建start.vbs</span></span><br><span class="line">createobject("wscript.shell").run"C:\testRestartJar\start.bat",0</span><br><span class="line"><span class="meta prompt_"></span></span><br><span class="line"><span class="meta prompt_">#</span><span class="language-bash">window+R打开自启动目录</span></span><br><span class="line">shell:Common Startup</span><br><span class="line"></span><br><span class="line">放入start.vbs的快捷方式</span><br><span class="line"></span><br><span class="line">任务计划程序</span><br></pre></td></tr></table></figure><h2 id="删除重复记录">删除重复记录</h2><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><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><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">delete</span></span><br><span class="line"><span class="keyword">from</span> t_ad_alarmevent</span><br><span class="line"><span class="keyword">where</span> event_id <span class="keyword">in</span> (</span><br><span class="line"> <span class="keyword">SELECT</span> event_id</span><br><span class="line"> <span class="keyword">FROM</span> (</span><br><span class="line"> <span class="keyword">SELECT</span> event_id,</span><br><span class="line"> event_type_id,</span><br><span class="line"> alarm_point_id,</span><br><span class="line"> alarm_flag_id,</span><br><span class="line"> start_time,</span><br><span class="line"> alarm_time,</span><br><span class="line"> priority,</span><br><span class="line"> limit_value,</span><br><span class="line"> in_shelved,</span><br><span class="line"> in_suppressed,</span><br><span class="line"> operator,</span><br><span class="line"> des,</span><br><span class="line"> previous_value,</span><br><span class="line"> now_value,</span><br><span class="line"> <span class="keyword">parameter</span>,</span><br><span class="line"> unit_code,</span><br><span class="line"> prdtcell_id,</span><br><span class="line"> dcs_code,</span><br><span class="line"> tag,</span><br><span class="line"> alarm_flag,</span><br><span class="line"> <span class="built_in">row_number</span>() <span class="keyword">over</span> (</span><br><span class="line"> <span class="keyword">PARTITION</span> <span class="keyword">BY</span> event_type_id,</span><br><span class="line"> alarm_point_id,</span><br><span class="line"> alarm_flag_id,</span><br><span class="line"> start_time,</span><br><span class="line"> alarm_time,</span><br><span class="line"> priority,</span><br><span class="line"> limit_value,</span><br><span class="line"> in_shelved,</span><br><span class="line"> in_suppressed,</span><br><span class="line"> operator,</span><br><span class="line"> des,</span><br><span class="line"> previous_value,</span><br><span class="line"> now_value,</span><br><span class="line"> <span class="keyword">parameter</span>,</span><br><span class="line"> unit_code,</span><br><span class="line"> prdtcell_id,</span><br><span class="line"> dcs_code,</span><br><span class="line"> tag,</span><br><span class="line"> alarm_flag</span><br><span class="line"> <span class="keyword">ORDER</span> <span class="keyword">BY</span></span><br><span class="line"> event_id <span class="keyword">ASC</span></span><br><span class="line"> ) rn</span><br><span class="line"> <span class="keyword">FROM</span> t_ad_alarmevent</span><br><span class="line"> <span class="keyword">WHERE</span> write_time <span class="operator">></span> <span class="string">'2022-09-20 20:00:00'</span></span><br><span class="line"> ) t</span><br><span class="line"> <span class="keyword">WHERE</span> t.rn <span class="operator">></span> <span class="number">1</span></span><br><span class="line">)</span><br></pre></td></tr></table></figure><h2 id="linux端口测试">linux端口测试</h2><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 prompt_"># </span><span class="language-bash">安装</span></span><br><span class="line">yum -y install nc</span><br><span class="line"><span class="meta prompt_"></span></span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">测试udp端口</span></span><br><span class="line">nc -uvz 10.121.2.199 9998</span><br><span class="line"><span class="meta prompt_"></span></span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">测试tcp端口</span></span><br><span class="line">nc -zv 10.121.2.199 8080</span><br></pre></td></tr></table></figure><h2 id="window查看端口占用">window查看端口占用</h2><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></pre></td><td class="code"><pre><span class="line">netstat -aon|findstr "8080"</span><br><span class="line"><span class="meta prompt_"></span></span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">其中-T是包括了子进程,-F是强制</span></span><br><span class="line">taskkill /PID 7452 -T -F</span><br></pre></td></tr></table></figure><h2 id="Java删除集合重复项">Java删除集合重复项</h2><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">protected</span> <span class="keyword">final</span> <T> List<T> <span class="title function_">removeDuplicates</span><span class="params">(List<T> list)</span> {</span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">ArrayList</span><>(<span class="keyword">new</span> <span class="title class_">LinkedHashSet</span><>(list));</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h2 id="oracle解除锁表">oracle解除锁表</h2><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></pre></td><td class="code"><pre><span class="line"># 查询</span><br><span class="line"><span class="keyword">select</span> <span class="operator">*</span> <span class="keyword">from</span> v$session t1, v$locked_object t2 <span class="keyword">where</span> t1.sid <span class="operator">=</span> t2.SESSION_ID;</span><br><span class="line"># 杀死进程</span><br><span class="line"><span class="keyword">alter</span> <span class="keyword">system</span> kill session <span class="string">'sid,serial'</span>;</span><br></pre></td></tr></table></figure><h2 id="git">git</h2><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 prompt_"># </span><span class="language-bash">取消每次push时验证密码</span></span><br><span class="line">git config --global credential.helper store</span><br><span class="line"><span class="meta prompt_"></span></span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">配置仓库地址</span></span><br><span class="line">git clone https://gitee.com/cheebo/note.git</span><br><span class="line"><span class="meta prompt_"></span></span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">强制拉取</span></span><br><span class="line">git pull --rebase origin master</span><br></pre></td></tr></table></figure><h2 id="IAAS,PAAS,SAAS">IAAS,PAAS,SAAS</h2><ul><li><strong>IAAS</strong>(Infrastructure as a Service):基础设施即服务<ul><li>提供基础服务,例如云服务器</li></ul></li><li><strong>PAAS</strong>(Platform as a Service):平台即服务<ul><li>对外提供一项单独的服务,例如支付系统</li></ul></li><li><strong>SAAS</strong>(Software-as-a-Service):软件即服务<ul><li>对外提供一套完善的系统,例如财务系统</li></ul></li></ul>]]></content>
<categories>
<category> 笔记 </category>
</categories>
<tags>
<tag> JAVA </tag>
<tag> linux </tag>
</tags>
</entry>
<entry>
<title>linux下jar启停脚本分享</title>
<link href="/37ef.html"/>
<url>/37ef.html</url>
<content type="html"><![CDATA[<h1>linux下jar启停脚本分享</h1><div class="note info no-icon flat"><ul><li>每次运行脚本都回将启停记录日志保存到脚本目录下的restart.log,方便查看是否重启成功</li><li>执行脚本前奖要启动的jar包放到脚本同目录,改名为app.jar,也可以自行修改名称</li></ul></div><h2 id="启动">启动</h2><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><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="meta prompt_">#</span><span class="language-bash">!/bin/bash</span></span><br><span class="line"><span class="meta prompt_"></span></span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">日志文件路径</span></span><br><span class="line">LOG_FILE="restart.log"</span><br><span class="line"></span><br><span class="line">echo "$(date '+%Y-%m-%d %H:%M:%S') - Starting service" >> $LOG_FILE</span><br><span class="line"></span><br><span class="line">nohup java -jar /home/scapp/imes-pm/app.jar -Xms1024m -Xmx1024m -XX:MaxPermSize=512m > /dev/null 2>&1 &</span><br><span class="line"></span><br><span class="line">if [ $? -eq 0 ]; then</span><br><span class="line"> echo "$(date '+%Y-%m-%d %H:%M:%S') - service started successfully" >> $LOG_FILE</span><br><span class="line">else</span><br><span class="line"> echo "$(date '+%Y-%m-%d %H:%M:%S') - Failed to start service" >> $LOG_FILE</span><br><span class="line">fi</span><br><span class="line"></span><br></pre></td></tr></table></figure><h2 id="停止">停止</h2><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><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="meta prompt_">#</span><span class="language-bash">!/bin/bash</span></span><br><span class="line"><span class="meta prompt_"></span></span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">日志文件路径</span></span><br><span class="line">LOG_FILE="restart.log"</span><br><span class="line"></span><br><span class="line">echo "$(date '+%Y-%m-%d %H:%M:%S') - Stopping service" >> $LOG_FILE</span><br><span class="line"></span><br><span class="line">PID=$(ps ax | grep java | grep service | awk '{print $1}')</span><br><span class="line"></span><br><span class="line">if [ -z "$PID" ]; then</span><br><span class="line"> echo "$(date '+%Y-%m-%d %H:%M:%S') - No service process found" >> $LOG_FILE</span><br><span class="line">else</span><br><span class="line"> kill -9 $PID</span><br><span class="line"> if [ $? -eq 0 ]; then</span><br><span class="line"> echo "$(date '+%Y-%m-%d %H:%M:%S') - service stopped successfully, PID: $PID" >> $LOG_FILE</span><br><span class="line"> else</span><br><span class="line"> echo "$(date '+%Y-%m-%d %H:%M:%S') - Failed to stop service, PID: $PID" >> $LOG_FILE</span><br><span class="line"> fi</span><br><span class="line">fi</span><br><span class="line"></span><br></pre></td></tr></table></figure><h2 id="重启">重启</h2><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><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></pre></td><td class="code"><pre><span class="line"><span class="meta prompt_">#</span><span class="language-bash">!/bin/bash</span></span><br><span class="line"><span class="meta prompt_"></span></span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">日志文件路径</span></span><br><span class="line">LOG_FILE="restart.log"</span><br><span class="line"></span><br><span class="line">echo "$(date '+%Y-%m-%d %H:%M:%S') - Restarting service" >> $LOG_FILE</span><br><span class="line"><span class="meta prompt_"></span></span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">查找 service 进程ID</span></span><br><span class="line">PID=$(ps ax | grep java | grep service | awk '{print $1}')</span><br><span class="line"><span class="meta prompt_"></span></span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">如果进程存在,先停止它</span></span><br><span class="line">if [ -n "$PID" ]; then</span><br><span class="line"> echo "$(date '+%Y-%m-%d %H:%M:%S') - Found running service with PID: $PID. Stopping it..." >> $LOG_FILE</span><br><span class="line"> kill -9 $PID</span><br><span class="line"> if [ $? -eq 0 ]; then</span><br><span class="line"> echo "$(date '+%Y-%m-%d %H:%M:%S') - service stopped successfully, PID: $PID" >> $LOG_FILE</span><br><span class="line"> else</span><br><span class="line"> echo "$(date '+%Y-%m-%d %H:%M:%S') - Failed to stop service, PID: $PID" >> $LOG_FILE</span><br><span class="line"> fi</span><br><span class="line">else</span><br><span class="line"> echo "$(date '+%Y-%m-%d %H:%M:%S') - No running service found" >> $LOG_FILE</span><br><span class="line">fi</span><br><span class="line"><span class="meta prompt_"></span></span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">启动 service</span></span><br><span class="line">echo "$(date '+%Y-%m-%d %H:%M:%S') - Starting service" >> $LOG_FILE</span><br><span class="line"></span><br><span class="line">nohup java -jar /home/scapp/imes-pm/app.jar -Xms1024m -Xmx1024m -XX:MaxPermSize=512m > /dev/null 2>&1 &</span><br><span class="line"></span><br><span class="line">if [ $? -eq 0 ]; then</span><br><span class="line"> echo "$(date '+%Y-%m-%d %H:%M:%S') - service started successfully" >> $LOG_FILE</span><br><span class="line">else</span><br><span class="line"> echo "$(date '+%Y-%m-%d %H:%M:%S') - Failed to start service" >> $LOG_FILE</span><br><span class="line">fi</span><br><span class="line"></span><br></pre></td></tr></table></figure><h2 id="问题">问题</h2><ol><li>执行时如果报如下错误</li></ol><ul><li><strong>-bash: ./restart.sh: /bin/bash^M: bad interpreter: No such file or directory</strong></li></ul><p>这个错误通常是由于Windows使用\r\n表示换行,而Unix/Linux使用\n。这个额外的\r字符会导致解释器无法正确识别脚本文件的起始。</p><figure class="highlight shell"><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 prompt_"># </span><span class="language-bash">执行如下命令替换对应字符即可执行成功</span></span><br><span class="line">sed -i 's/\r$//' restart.sh</span><br></pre></td></tr></table></figure>]]></content>
<categories>
<category> 笔记 </category>
</categories>
<tags>
<tag> JAVA </tag>
<tag> linux </tag>
<tag> 脚本 </tag>
</tags>
</entry>
<entry>
<title>hexo配置文章加密</title>
<link href="/1c94.html"/>
<url>/1c94.html</url>
<content type="html"><![CDATA[<div class="hbe hbe-container" id="hexo-blog-encrypt" data-wpm="Oh, this is an invalid password. Check and try again, please." data-whm="OOPS, these decrypted content may changed, but you can still have a look."> <script id="hbeData" type="hbeData" data-hmacdigest="60e7dbb4997a6040b14c991209356a07021506098d645aaba94f676574c4ccb6">165d50f05814027fb7fe5e4ae8a088d8dca5d23e263e4add04aa89d6cdeb1792429c9bd13dbfc49fe48a925b1747ba8b14b6fb2934fb26c3480327a63662da32aaa6f65a3b6b3d0f97d75dae5d95f4cc67d31306f2f7db390be5dad1ce0c0d2fc4945aa02be4f0f7186520c5af2b87b34927de6be3c545ee206966c9729c6b7f35236f8da2aeb1dd59dbcc85788771409dff2df83a2b0c8942caa393f3a1e12b936930f85f837643c48fbdfd9cd7769deb4129bc11b39b8b74da5cfdcb92af5f2b65e9c123e69f36f5e89f5993627bdee25dca9c1091de889fe5cd34ab9fd85130bc47470d7adc9f60c64435eac632490b130d190fbe8da93b5aaf35f579cfed9cd80bcede530b678bee0b8018846d553c8fc73b6c0655c67e89cdee1787d6eff0d90a2cdf76bf21ea50c9f7ce93d435b06e1875006abae1cd929e1fad83f6bdbb179514d92e860a988b470ea1526f78316c8f1d64824e9e5356eefe649465b7079ab86bd3d336dd345f330f50ffeeedfe67a5f1d2b0d5fb17463beabd321451c84e722c8e3a35e6996b2e5bb0b1787f20f3d5a6413e8f650562ab2d702763f74d14c14e529e6393fe1254d00acd61a7e10c25e09a113e35496c2fc0077c6ff3c02a830cf192e4e1b3c5abf770ad0b0cda8059c0d77bc23d8bb4add2d20c8703300f09fc3c2238c343f37528b3011f12b6b0b31f2441bb23b8dcbf30ac51f16706e2c2bd7769cc73a7870a92b5ea56d2e3676cb3c230c45220dbbfd7ebed560aa501d64b3940f36ce8daac47d9995acd25d532f4b6f0f8cc2c0e6e62695ca40ddc6f718dd246220e039f770fa123008c520147e905598cf149a62615b9c557a954d5fd1c300ac945024f73ee15d612c14d97fdaa849f4e58e2d38a9b3ad431864bf380f8b29099c76a710e428c09d1da5b9bd46646dcc928751fdf871b2aaaf38b601da7e8faedd91655f65e43d6e086a466a917433f59cf40e959c11c4bca6ae310cf47b287d65d63c4ac2a01be42b72e89ef8d43d0cc0fe84c71694f92c2cacb45b638479446d12a3f7e3a8b6b6868199dfdb2b452650e00706b7a75285af7b3c90cbc2f9f69757ce88bf46939967cc8a164d5c3e675ed78b1871f18dbe2cadb96224db0bee75d9d7142ce773bdab3497bcd768cab2bacdd48663015160c0e9643822b92514e1dc2133038133340bedf2711d129df1a2edecb23f1554234c73bc628d6f9f3b2b6804e9fb1dd2c4d3026fbcf70867b04b0e8c262ceda79169597dfdaedab34796e2538b070928ab5896e81be8ff3e1669ef9c79135d6ba7d895b30484a669c46b54272114ae118699f619fb688574354bef2b395d2ac176c7236c073d12cdb868e01e8bd1e0fc7393eaf25042d68af9ef2365a1d47fa1c5608ebe8a58c37b1cde7ae497f341964258b98a4e27cfdcaa14b50838ce2750305689bb4f0834c646c78b50e01e11a589d2a19336e03a4a019fd4e6187d332f29541e8a4b2f94f6ef0c619629a4a79319ac653d5a01bff908001ddf38304716f1d0b9b98420a44f0f0188fc2140ceba9017fcc9052707434cbe3b86d97858114603848613974c67a3c0c06364b7b121335b9bf570f19bcbd5dcbffc9424183796480a1125a9d48da841a97ff8461ef68c90f523356a2880d7e80c8c67f1bc561edb8706628db8d4b4ba897e75da01b94c5aa9fc75852bb594ef8d7bdee49be1b0f845b9daae6996e77969d66887bbf85745b1de92a5b413b9cc19f7b0ce0c8f690f78b9fadb32669e5643f31d0492c50a3277a58e2bbac34a8bafb5af91f41a83861c1e3cf37f29e81b36bc14cab54d66e6927b4a0a3f3259f33034429f299cb75f0395054393d5223cb465d692eb66c639bb8c2c604d41c553d2b479cd4f7a539bdae10e94b45e4f6a6897b99364eff4f3fe125d9fd633e2c386c6b3ce05d06f47c66653f3876ee66fc95e37ccd2ebaf944a8074ebb2b27b2434c2270c54af35728d35ca90f873eaf138e705c4a74ff3612a7dfe41496e29feba11ec7ba69391abdd831baca5deac5a08107d32cb7218c761eb823ee9a422d7254c3fbc81b4d6b18f6f4165ae7ac60939b99acd699a86f7a6ab11c22b5e67d4735a4f869b51f8ab6e857b15ff7a4a10237117f85ad834266402fd5504a7bc34d6a016bdd99cf792a88d7b239343bd726fee6a02c2847ecc09c21230b876e7f1839cbb80636515c6e54b7a9bcef809e6991c48336e03731ae8e691fd46cae79dbb041e048a9e89f424339ced89dc3fea30cc6d30af664480fc803a9474ed9f87fa544f4528737326ec916e6aeec0e33087ce5df86a4786edd5501d5cb4ecbdc6143b7b7bfc407a54e9796b46b26967d698770f0a66a173e9f4ee67e5dc8a25181eea438351bdfea8b2f3ba59eb3de1073188d6175838e4a969057384afc5e1bc76d1c867bd79e83ca8d1a5a9138259b6ca4ea06ad07c861191e947a60416bf791e161d13185d467e7333608b9560332df405000ab2b78696612c59eb4d89fe46026999de88ae9314f7eb47357f2edd03f522e0945d3da9ebb185f3dca8a2f837a930a41cfc138b6216d6a7d98c3d4d9dd09ed05e3cb199c9d869db1b76ba4f32f43ee23ee008f2b0416b20380bda5bd39002d2ffc9634f3b59392a52d0d922c6c52f4382d3bb060691e44c93d469586ccafa557a4fd7e55bf94091ff2d03201cdfe84a3e8579f166fbf5859b2a3e9096ceb0391d30c1c486199555a901a50e7c740bde4afe693b63685505647fdb6e1836180ba6db2f8c1d2535fcaa778187c692a05dc19de796c22b051c3803e7d93390d649aa9f61dcc1b9a90d05724bd72a8e6add83564d98d016f4fab36eba5ad289374fec07dd432077677a2ce4262c63ec7c73582b9c4333120bb81cecf70c462c63fa882eaf6b112bef4897bb76aeaeda641f5f55bb7c010b1ee96b8aacdbb193b7a06f18f023695b3c1a72b6c69696ab5039c824d96edf8d617d3fc72db695c823020afb08136e170a49e258e9e452c56b8cda4b5ec14c2892f8d4a26327c69379cf3e9445e37f1dea290b4b88c41fd3f9eb85593ccc8dc0182420c830d3505e914bd1b0fe6bac57fc876022e41cfb7a9973d01079e837820452bd9c0e959b9746f3f51b4ade8bf6a820b6be13bdf4742f5c27c61edda84bbde3461d72debd1c04c4d89c83a20bc7d588b51d57728d840b0184a09c34bc3c014dd4ea267df8488a2560cc047ba57b7358fce99b764b18c5fdf60e5b9ad6d299fbd544d76d9ab0ccc653b5ae3bc4ee09eed1ba608dcf19dff6a31dd430dde8c28a986e01cee260609701f8c6f85ea279c06262d2c1b51bdb451c129883129b87c28573b7737b469f111b32405699b8698cde03e134a35215c1e94c8c9f942bc87b48a7843608c99c3fcc393410a3bd1fc51d00d98aa550eae20e7d96a13668a65c3b4087c082d478224a9f2231c7af926b6f6bd112eb21a79668d5bf9b7f499960caf183580f890227577609e9124bda0aaccfb9f2c51ec01d19c8ada8e9ac0df5c8e74ede871490df70f1bd32e72ee7b14b65ed6ef3d848f82a6e77bb72b7ac1773210a3fdfaa3adef964b439615945a03e536cedd59c432a1fc43d790eab276f44c299a1b1239befed0f5411beb36703ecb9bf60294ae42673d82e45d5c080c7a8d8f6977165cd5bc43514d6f6f8f82eb74a8ad9b16a7755107c95d716858a5aa81b197acdf1cd5c671e01cf49074523ca3f85da87b096bf5215184242de06b7f16f2d952df6b22be5f2cde991051e2f5c44541ece7694f6ca254f9e31b90ed3f0f78a3b982547452ec360ec4be4f20d399c385c94b5e8b2be6a2a63efaeda7135f1a885db3c48dbb584cedeaca6f32197b5e986b26a93ad5be01184acbef9f2822a7ba2b0aa1d2d906da89b41439893b23c04f71e499c7a57eaf977261d05ee4c7e557501b0bf83960598f93c4079f8e7fb2d0f5296f69f04f16087b9732be709a9adc7eb08794917abb8785a3bda36d6bd2c14e99a23ba69867134da04d92391ca2a214f2fbf6e1d76942d91b83d7418925faf05846439d1ad91c7d12d3d3efb2d3cf4b70513557527f76f5ab4342c8ae918b53acad08b63ba026730c0f38dc8b7891410162155fab158335fb7cfa3be372a9a5db588dea0f3bcf00b130490edbad7b1d4f4ad21b2f9991c1ac2692c85111f2f88e5a8aa49794f62fd9d585e5fa1ec7331ae4571e6c3d4a09dd93d75290a771a1baccd307fb2422821b039d21ec08a19eb8a878e9993bdd0362e1c108b7add62efb4662953846f32d62dbfed007bca73eabd83e61a2b5dab35ba893113a403fc2f3f5bb0f7fba6cb824b3da5834c1e4ceb2f6b0ba09dc80ee9a9c4ce323b67fa9e0c5a8e558957c32cff0ca04237f5cf34026c34d9c124bb39a7f7dc3104879b43e0bebdf884655021d4bcc2c6d5c5b4d3bd36d51690ff18f1d7dc1f79fc27ac8af79baf5015122e3dc5086b6eb3f2347b7e72ba17afe778d34f4ba02160b2343df517f1989faa0be0edba405713fc6987c69f12f701451f00a7e08ccd0579100147876caf55560b6548a9560120dfc3ee1461acc7752a5884a84646565de688057af13cf5a05cc7b58ef33caa651abcb7cfe46ab95102f71d8fc78b84e729a8f8f5c9f3c7c784d838b94b176ca66a3ad0a449ee345463ada588be14d5f7476e70280f307600f8eb39de8b0bb85b2403a66d9b3fdfe4f0ad240c5a071c76fbd26200f667a5f29909739e84b8bb7c024ed366a34d5de1e89de0e1c67d52562f5fe4569cb86d2e1b51cd3e46a2d1f30818602d4e27e298063d0b228114524ab4016cf76c97b00f03b128085a18ffe4aa5d122f0fe788973bbc45e99f04190afce9b9a650f5bb551b517a7bc934bc6c0a47b85d3772eca9ba6e97cdb78acaa2465dd66dfad85066791e584dad88b6283c14ec809bb547edf61c59a198b58a3ed7f8ca81744fc13c6e7146334e938a28ebd20a419aea2e333dc4a5c6645a20be0f45bb796adb4e75f7780536ccc007a896612a799f5a0e34631244abab0c6db47e2c1614e4345713f31902905dea656fb4eca27af8fa900978889e3dd54b29347362eab64ab40b84a74166d74a96cd174e907e5f480908844a5d8347921b4c1f1df15b77fe4bdd29e268dcf79e19181f5f0e2ea72b541d3cc3a4f9984f70b31a9932391a34f83dacae1e0b8519671db8faf20dbf7c8e8b727637b7b9181b024767aa5b341237a6c6aa03ed1fca213a633520c72997d6f172eaa521a7a4d1dba16800961fc95719a1fb98e23043044612aac38b1b91512fca0d07e17a4f14972976d0c3ccd7471e8d605e7bf1108dbfb3cced7ed70bd75be1eb89995f59a0fd420362cad683e114480e7a8d2ebf4a135a50ebe23ab08b713dc630dfb39aae2dc75d951ef7679c043cacb0aaa5816caad13a744e93ac8723483ce31c4ea465982e729802300fe4902a3f9760b86119bfea61d5cd47f9da5e9b9209667edc02b440866519cb4efb4ec4c7c5b63ec1f8f5cd0f5f8c721a1b1e7f605a2d4e309b9e36c933443e0ac8ef91e82a988f907316cca749c80e6f43de4c07933280f0d425c488dcbbf920d9d580516bcff9eef06585f5d7f7f3a78a9607d17a71ba51e59fec633d78d9d496cb2440266f0904fc28d437352ac20cd6c0fac08e5ac9bea18677d7d1c551ee1349c00bd2f48403d45027bc5bce2ecdbe03e2721598a22c53d29871f2a1fd7823a73e0e060b465f22f10d950d7c370b9fc17b010b7d8113c1b9897bdc6410b3561b336a2ea9a776ed828c92d5fb6e198848d88d8ef6b6c7ef99e18918f36fd5816a631a52faf82f811c31327eb3a419eff920d7c013af75663cbd38022186dc1f0c83e142afcbeca88003a42a1fae5944f7917156e46658ba104923cab62d8e9810a92e971a882105f0e8b3ebaa87c32fafa28f8f4a39711eef1fe4f4dc4353d0f4a0ece70fea7066f0b20e91503692e050f51f1d660ae8db0914de4b5e7673dc505c04a893b2bc27826a178f9ab2dca4fad7cbb76a46a0293b16759d4b5791762520ce74c746fa0c839603317909a3df1732870d7e1091376793471d4cf578330fb2c7d95fd9415d7fe6fd65c72453cdfbebd88fa81aa89a4e18f7b46cf25b6af8718d2989184b0bff41748c293204d79c07621415566d61fa512b11182e924089029abf02a16515c5f40d4e92a633d38e6b62a8682dc518da480ec5bc0db231b1f0cb84b8c954bf76cb22a7dbaa7f5ac0d6520e20755e63fbf0679057644e64709192fd5ff5f015e045f79d74d2253edda6bb04662aa9f746c1a74ad7fdfb7f7f6f759e45e0697bc48c883495c47b63917291a832932be35bf070b159664ec656af0bec21f5dca8cd97baf4121c0843a1a53036a71c57617aa4491419a9f3a36b528668f8a36fd61985e57ec6e1d8630710e97b61e447fa51a911b85be5deb65546d3711cec823e8f71e7cbb299f0238ee3e1180821d4d3bb176905930cb9c045373a93096894f9040d13156e704d147656aef92bf757dabd82f54401c22dcfa0df5e112243bac4cf724de6c2997262b6224ab0c3c91d14bb8d5c3d4b3ec71f988f30c97a829a1762dee25e440178570af9355f2ff47c8408a3fed3557eac18ece210a1e44652580570d954bf013148f4e89b8a64d45361cc824ba7b66fe28afc77e8221d9a651bcd4c46f0a5d5f0e146b53046193f857d767b13810f6753df6641ccfa340a5e72dc47a125609bc33dec5e22ec12f4ea6b74117fa854a37e4a6ebc28058a813a4f08cbe8fb47fb099cab6674d5e5a20cb886f6baaf6bbc7dad61f3b485aa487323d033d0a47954f1ef9b38e2fd188ae6058f412d1ac9df3d5db00fb82d7fcccdfb80512c511040eb0aee347ba541850e60565f9084558e76dbd47352ef173c1ae7c5811e32cad4f80e12c6481b41c00fc3ab69a68d62e7f59abaf5e0260a8543212f3f27f7e125c0501d4068dda34c04e5b9ba59b325dd20394ca12b430bbf6d5cddbf2604d1a9d3403f73e9c22d14039b2eacd09bea3450d94481967fc931add96df558e527f9c619fe7e35ebec6b7199f72b04bf977ffe25bb17f4bdab0fd993d6e498be26b77b5d750f584eeaaec44022c666bcad01c01e3f35c433a5bec07e16b05a2704a90097dd29740b5232d794f29ecd96c6d04cbd8dd77e8e2b063df72fa75a46cf0605393938d85e9ca90c39d2624bd96aa9feb97b5046175832af7752d34ed81e3a24ff64b7b46280f2532442db4a081ddddae2b5ecd222ad1553c12ad303fc945d45ea8cc6b6ed6806eeb94314dc6e4a4ba1de040e4a41be58bd1941e8c9ac8a1a05c1cb8630cc471a02bed6da42f3a36d37ada230898bd9444e6d4f378967ce5367a16fb16afe42fea1e659fa0e333bda331f553af154ebee19917bfefd1c48186ccd931c927b67163e7bb50440e1345d369a331a9c201bae61341f9c82f2c8ce67c2acc1979814c466c0a3cd4db888795368805c7f309940390ad63ea41cfafc53345084e457f1856563f4bb27bc5449436468f66244bf7cf0f6465da46b084e2534798876382edfbb517b29125f59911cf1dee76c205b8834b37624226c7c83cd3ecc0361ec62a51503321b4faf630af6e142869fb3c769c3926c5359d69f80ba1e1a7867b82a86a724d216a80411b82c15247304185ed365bd0719d1ed2f71424dc135a5669bea4b87d7784a6275f0b7b1110cf34c077e1f6a3215de18b97feb8414c64d2daf6b9e49b219260c9bb6002ad79ec23a1590c5c4e4f069e62fb6524d3d636007d17cc57b9904d2ea895cc28b606a2df6564730d55122fb3c64adb2904e405cf1885628ddda59a43f9de42f80d99a5d9ee6f614ac4c284ca30ff909ee7d00d9dd3948016aadf739ab89018d59e1e6e54a0d719ffea36cbe7323337dc6e70708d63cf3ce20ca1724012c90ab64706cd01858645768c6f1144f1b2f95724f5f40e7f26b83edfa06dcf03878a3da68961823c73922727c07a24d495c5af8810bcc040456d08c77045ee1911ef61909be56fd3b62d579608531baab83499dc6b67f95b5518d1859eac07b63d46152ece20bca18cb629dd5a22bcbe9bedb92d6bab805ca047bb711f56ec373c14a51d98a350a9266c913e44eb8f208db86d931873582285202a154889e4ea61cc0d81e231481b038c674517a21bfb2c0906d955eff7318e177f43ccdf696a7365d0601f0b3fc249955b79c271d8df5d9b3e4937aff5e10465aced1f1a317283a9b88f67ec59bb04d0ded7dfed5168036a678550c99bee65c15cbff40ce3a52b4953ca8eb39dafa5a3d8c21ea00a24ecf750d65ae6cf4b33dc2ac4b97cc39bea595e22c434d2c1ad282f055052d61cc1ec97449bb186ab76200c0c842e986b7296fd949caf50e4708afbbc08e188e52e1c763207ce3ac11d15a562f38e680ed5b875861f359f4c322cf52f93794b884c82643f64fca32dcbb05777fb2b3f796a62b6df99ff410d7f3fbf35b75414868b214f510459096d3a5e1f90763fced16bddbcdcba9e7fcb380c3b7c6425467145f01b0fc24e015ad5945877c1ccdab13453b7a0ba94a583818a782bb5d4d58d82e7ad15b56c97ffb1394132205581d77f54e89f3649694826845a46d05b1edf4e3516219b5f35118f49f1f9503d26fcc330fc0bfb7618c94d035ee854032c4a1faca5ce81390d8f051880d620024367038dc99dddabd51c3442dca121b0e3c5dc89df44255a15586e88c6a6c1b8e6d18492e6f6881d4c686452c2a8b2386de04f1a243335adae69f659af196e6a9de4ca41858781c9a167bee0b1cec7266bc7cebf27923fb973c0ac4d16099a59f76d7ea3bc0f37bec7b62fb7be2e266ceb94ca2d46e6f5728cec104bbc2ee1609f4e56ca42bba7abe1fecf1ce5f6cb3a4f18fdab71b91384db86996ba9c9b6283d249c0fe405d67d1ac854b803e807afd94f425b2445646d86cf04b9a2c379845d491f53c1ace72d2ea56e1f66ccc658ba9aec53ed4078a8a01271a5fc1acf26d02e3d83864d63cb0aea88f3ca145921ada3bf9f152ebb368843a00c1506d361d029b2056834cc6f37c54eab27a859f836c05603c7c952d9f0b200870c67ef90c565fad6f90db7d3a0ef4d560179dbb345c8d278ed208dc1ec39c2e754a7fd906c79af080ee6f0a610f65ebb4386d401e76169b8bd0f39e5c2895c734e08e432c86bcfa392db8690b2994eee5684d2b5ca0b6f5fc20e5fe9316f8db7a8f12ca93c834d1b57f4e121ab983e53630f7ad8447f4a936400cdf714e0e77a159577148eb38cdc00ec58e79993c088a7fde086ee375c8656bd2b8ef546cda04423b2ceb06f726e29ac40441d64022aefbee9cd74af6d62201ab09a1dd7bd7c7ddfd8918a79da317ae5fadfff99abc446999b146cbddf2f911a405712ab4157c2c584c479b81dc264f5093555f98bca64a6f0ce4c0f8a3ec5e0d23c152810cda97ec003412806215f102648862287ca351b04ac8c10f740aeb843159cf873ee0a1d1a6a186aaed2a6b6dbba678a011a8798820af4ce62211ecb8ca4302815ab4c8e671e32b5a383cb44dd77ebcfa8097fe2774116eb471ad55ac9d3cd2eca49ceaa4c6cd41c8c66dc3e64c53cef6aa3f1988cbf235f4bf98db3f73a1eff9d</script> <div class="hbe hbe-content"> <div class="hbe hbe-input hbe-input-xray"> <input class="hbe hbe-input-field hbe-input-field-xray" type="password" id="hbePass"> <label class="hbe hbe-input-label hbe-input-label-xray" for="hbePass"> <span class="hbe hbe-input-label-content hbe-input-label-content-xray">Hey, password is required here.</span> </label> <svg class="hbe hbe-graphic hbe-graphic-xray" width="300%" height="100%" viewBox="0 0 1200 60" preserveAspectRatio="none"> <path d="M0,56.5c0,0,298.666,0,399.333,0C448.336,56.5,513.994,46,597,46c77.327,0,135,10.5,200.999,10.5c95.996,0,402.001,0,402.001,0"></path> <path d="M0,2.5c0,0,298.666,0,399.333,0C448.336,2.5,513.994,13,597,13c77.327,0,135-10.5,200.999-10.5c95.996,0,402.001,0,402.001,0"></path> </svg> </div> </div></div><script data-pjax src="/lib/hbe.js"></script><link href="/css/hbe.style.css" rel="stylesheet" type="text/css">]]></content>
<categories>
<category> 技术教程 </category>
</categories>
<tags>
<tag> hexo </tag>
</tags>
</entry>
<entry>
<title>hexo配置隐藏文章</title>
<link href="/fb6a.html"/>
<url>/fb6a.html</url>
<content type="html"><![CDATA[<h1>安装</h1><ul><li>在博客根目录执行</li></ul><figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm install hexo<span class="literal">-hide-posts</span> <span class="literal">--save</span></span><br></pre></td></tr></table></figure><h1>配置</h1><ul><li>将如下配置加入<mark class="hl-label purple">_config.yml</mark> 或者<mark class="hl-label orange">主题的配置</mark> 文件中</li></ul><figure class="highlight yaml"><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 class="comment"># hexo-hide-posts</span></span><br><span class="line"><span class="attr">hide_posts:</span></span><br><span class="line"> <span class="comment"># 可以改成其他你喜欢的名字</span></span><br><span class="line"> <span class="attr">filter:</span> <span class="string">hidden</span></span><br><span class="line"> <span class="comment"># 指定你想要传递隐藏文章的位置,比如让所有隐藏文章在存档页面可见</span></span><br><span class="line"> <span class="comment"># 常见的位置有:index, tag, category, archive, sitemap, feed, etc.</span></span><br><span class="line"> <span class="comment"># 留空则默认全部隐藏</span></span><br><span class="line"> <span class="attr">public_generators:</span> []</span><br><span class="line"> <span class="comment"># 为隐藏的文章添加 noindex meta 标签,阻止搜索引擎收录</span></span><br><span class="line"> <span class="attr">noindex:</span> <span class="literal">true</span></span><br></pre></td></tr></table></figure><ul><li>配置成功之后在文章的头部加入如下配置即可实现隐藏</li></ul><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">hidden: true</span><br></pre></td></tr></table></figure><div class="note warning modern"><p>注意这里配置隐藏只是不在博客页面中显示,但是如果知道链接地址的话还是可以打开这篇文章的</p></div>]]></content>
<categories>
<category> 技术教程 </category>
</categories>
<tags>
<tag> hexo </tag>
</tags>
</entry>
<entry>
<title>排序算法详解</title>
<link href="/b78b.html"/>
<url>/b78b.html</url>
<content type="html"><![CDATA[<h1>小知识</h1><h3 id="如何判断一个排序算法是否稳定">如何判断一个排序算法是否稳定</h3><ul><li><strong>稳定</strong>:如果a原本在b前面,而a=b,排序之后a仍然在b的前面;</li><li><strong>不稳定</strong>:如果a原本在b的前面,而a=b,排序之后a可能会出现在b的后面;</li></ul><h3 id="速记">速记</h3><ul><li><strong>不稳定算法</strong>:<wavy>快选堆希</wavy></li></ul><h3 id="排序方式">排序方式</h3><ul><li><strong>In-place(原地算法)</strong>:指算法执行过程中不需要额外的辅助空间,而是在原始数据上进行操作。</li><li><strong>Out-of-place(非原地算法)</strong>:指算法执行过程中需要额外的辅助空间来存储数据,而不会在原始数据上进行直接操作。</li></ul><mark class="hl-label purple">所以非原地算法通常具有较高的空间复杂度</mark> <h3 id="算法策略">算法策略</h3><ul><li><strong>分治法</strong>:快速排序,归并排序</li></ul><h1>算法详解</h1><div class="tabs" id="test1"><ul class="nav-tabs"><button type="button" class="tab active" data-href="test1-1">冒泡排序</button><button type="button" class="tab " data-href="test1-2">选择排序</button><button type="button" class="tab " data-href="test1-3">插入排序</button><button type="button" class="tab " data-href="test1-4">希尔排序</button><button type="button" class="tab " data-href="test1-5">归并排序</button><button type="button" class="tab " data-href="test1-6">快速排序</button><button type="button" class="tab " data-href="test1-7">堆排序</button><button type="button" class="tab " data-href="test1-8">计数排序</button><button type="button" class="tab " data-href="test1-9">桶排序</button><button type="button" class="tab " data-href="test1-10">基数排序</button></ul><div class="tab-contents"><div class="tab-item-content active" id="test1-1"><div class="note info no-icon flat"><p> 冒泡排序(Bubble Sort)也是一种简单直观的排序算法。它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。</p></div><p><strong>基本步骤:</strong></p><ol><li><p>比较相邻的两个元素,如果前一个比后一个大(升序排序)或者小(降序排序),则交换它们的位置。</p></li><li><p>对每一对相邻元素重复步骤1,直到列表末尾。这样一次遍历完成后,最大(或最小)的元素将移动到列表末尾。</p></li><li><p>针对剩下的未排序元素重复以上步骤,直到列表中的所有元素都排好序。</p></li></ol><img src="https://www.runoob.com/wp-content/uploads/2019/03/bubbleSort.gif"/></div><div class="tab-item-content" id="test1-2"><div class="note info no-icon flat"><p> 选择排序是一种简单直观的排序算法,无论什么数据进去都是 O(n²) 的时间复杂度。所以用到它的时候,数据规模越小越好。唯一的好处可能就是不占用额外的内存空间</p></div><p><strong>基本步骤:</strong></p><ol><li><strong>遍历数组</strong>:从未排序部分找到最小(或最大)的元素。</li><li><strong>交换位置</strong>:将找到的最小(或最大)元素与未排序部分的第一个元素交换位置。</li><li><strong>缩小范围</strong>:将未排序部分的范围缩小一个元素,即将排序范围向右移动一个位置。</li><li><strong>重复步骤1至步骤3</strong>,直到所有元素都被排序完成。</li></ol><img src="//www.runoob.com/wp-content/uploads/2019/03/selectionSort.gif"></div><div class="tab-item-content" id="test1-3"><div class="note info no-icon flat"><p> 插入排序的代码实现虽然没有冒泡排序和选择排序那么简单粗暴,但它的原理应该是最容易理解的了,因为只要打过扑克牌的人都应该能够秒懂。插入排序是一种最简单直观的排序算法,它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。</p></div><p><strong>基本步骤:</strong></p><ol><li><strong>初始状态</strong>:将第一个元素视为已排序部分,其余元素视为未排序部分。</li><li><strong>遍历未排序部分</strong>:依次取出未排序部分的元素。</li><li><strong>插入已排序部分</strong>:将取出的元素与已排序部分的元素依次比较,找到合适的位置插入。</li><li><strong>重复步骤2至步骤3</strong>,直到所有元素都被插入到已排序部分。</li></ol><img src="//www.runoob.com/wp-content/uploads/2019/03/insertionSort.gif"></div><div class="tab-item-content" id="test1-4"><div class="note info no-icon flat"><p> 希尔排序,也称递减增量排序算法,是插入排序的一种更高效的改进版本。但希尔排序是非稳定排序算法。</p></div><p><strong>基本步骤:</strong></p><ol><li><strong>确定间隔序列</strong>:选择一个增量序列(也称为间隔序列),该序列的最后一个元素必须为1。常用的增量序列有希尔建议的序列(例如:{n/2, n/4, …, 1})或者Sedgewick序列。</li><li><strong>分组排序</strong>:根据增量序列,将原始列表分割成若干个子列表,对每个子列表分别进行插入排序。</li><li><strong>逐步缩小间隔</strong>:逐渐缩小增量,重复步骤2,直到增量为1。</li><li><strong>最后的插入排序</strong>:当增量为1时,进行最后一次插入排序,此时列表已经被“预排序”,插入排序的效率较高。</li></ol><img decoding="async" src="//www.runoob.com/wp-content/uploads/2019/03/Sorting_shellsort_anim.gif" alt=""></div><div class="tab-item-content" id="test1-5"><div class="note info no-icon flat"><p> 归并排序(Merge sort)是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。</p></div><p><strong>基本步骤:</strong></p><ol><li><strong>分割</strong>:将待排序的列表分成两个子列表,直到每个子列表的长度为1(即列表无法再分割)。</li><li><strong>排序</strong>:对每个子列表进行递归排序。递归的过程就是不断地将列表分割并排序。</li><li><strong>合并</strong>:将两个已排序的子列表合并成一个有序列表。合并过程中,比较两个子列表的头部元素,将较小(或较大)的元素放入合并后的列表中,直到其中一个子列表为空,然后将另一个子列表的剩余部分直接放入合并后的列表中。</li></ol><img decoding="async" src="//www.runoob.com/wp-content/uploads/2019/03/mergeSort.gif"></div><div class="tab-item-content" id="test1-6"><div class="note info no-icon flat"><p> 快速排序是由东尼·霍尔所发展的一种排序算法。在平均状况下,排序 n 个项目要 Ο(nlogn) 次比较。在最坏状况下则需要 Ο(n2) 次比较,但这种状况并不常见。事实上,快速排序通常明显比其他 Ο(nlogn) 算法更快,因为它的内部循环(inner loop)可以在大部分的架构上很有效率地被实现出来。</p></div><p><strong>基本步骤:</strong></p><ol><li><strong>选择基准</strong>:从列表中选择一个元素作为基准元素(一般情况下是选择数组的第一个或最后一个)。</li><li><strong>分区</strong>:将列表中小于基准元素的元素放在基准元素的左边,大于基准元素的元素放在右边,基准元素放在中间。这个过程称为分区操作。</li><li><strong>递归排序</strong>:对左右两个子列表分别进行递归排序,直到列表为空或只包含一个元素。</li><li><strong>合并</strong>:由于快速排序是原地排序算法,不需要显式的合并步骤。</li></ol><p><strong>再详细一点:</strong></p><ol><li>原数组:[3, 5, 1, 9, 7, 2, 8, 4, 6]</li><li>选择基准元素 3,分成左半部分 [1, 2] 和右半部分 [5, 9, 7, 8, 4, 6]</li><li>对左半部分 [1, 2] 递归调用快速排序算法,得到有序数组 [1, 2]</li><li>对右半部分 [5, 9, 7, 8, 4, 6] 选择基准元素 5,分成左半部分 [4] 和右半部分 [9, 7, 8, 6]</li><li>对左半部分 [4] 递归调用快速排序算法,得到有序数组 [4]</li><li>对右半部分 [9, 7, 8, 6] 选择基准元素 9,分成左半部分 [7, 8, 6] 和右半部分 []</li><li>对左半部分 [7, 8, 6] 选择基准元素 7,分成左半部分 [6] 和右半部分 [8]</li><li>对左半部分 [6] 递归调用快速排序算法,得到有序数组 [6]</li><li>对右半部分 [8] 递归调用快速排序算法,得到有序数组 [8]</li><li>将左半部分 [6]、基准元素 7 和右半部分 [8] 拼接起来,得到有序数组 [6, 7, 8]</li><li>将左半部分 [4]、基准元素 5 和右半部分 [6, 7, 8, 9] 拼接起来,得到有序数组 [4, 5, 6, 7, 8, 9]</li><li>将左半部分 [1, 2]、基准元素 3 和右半部分 [4, 5, 6, 7, 8, 9] 拼接起来,得到有序数组 [1, 2, 3, 4, 5, 6, 7, 8, 9]</li></ol><img decoding="async" src="//www.runoob.com/wp-content/uploads/2019/03/quickSort.gif" alt=""></div><div class="tab-item-content" id="test1-7"><div class="note info no-icon flat"><p> 堆排序(Heapsort)是指利用堆这种数据结构所设计的一种排序算法。堆积是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。堆排序可以说是一种利用堆的概念来排序的选择排序。分为两种方法:</p><ul><li>大顶堆:每个节点的值都大于或等于其子节点的值,在堆排序算法中用于升序排列;</li><li>小顶堆:每个节点的值都小于或等于其子节点的值,在堆排序算法中用于降序排列;</li></ul></div><p><strong>基本步骤:</strong></p><ol><li><strong>建立堆</strong>:将待排序的列表构建成一个最大堆。这一步通常是从列表的中间位置开始,自底向上地调整每个节点,使得整个列表满足堆的性质。</li><li><strong>排序</strong>:将最大堆中的根节点(即最大值)与堆中的最后一个元素交换位置,并将堆的大小减1。交换后可能会破坏堆的性质,因此需要进行堆调整操作,使得堆重新满足堆的性质。</li><li><strong>重复步骤2</strong>,直到堆的大小为1,此时整个列表已经排序完成。</li></ol><ul><li><img decoding="async" src="//www.runoob.com/wp-content/uploads/2019/03/heapSort.gif"><img decoding="async" src="//www.runoob.com/wp-content/uploads/2019/03/Sorting_heapsort_anim.gif"></li></ul></div><div class="tab-item-content" id="test1-8"><div class="note info no-icon flat"><p> 计数排序的核心在于将输入的数据值转化为键存储在额外开辟的数组空间中。作为一种线性时间复杂度的排序,计数排序要求输入的数据必须是有确定范围的整数。</p></div><p><strong>基本步骤:</strong></p><ol><li><strong>统计元素出现次数</strong>:遍历待排序的列表,统计每个元素出现的次数,并将统计结果存储在一个额外的计数数组中。计数数组的索引对应于待排序元素的值,而数组中的值对应于该元素出现的次数。</li><li><strong>累加计数</strong>:对计数数组进行累加操作,使得每个索引位置的值等于其前面所有索引位置的值之和。这一步可以使得计数数组中的值表示小于等于该索引值的元素个数。</li><li><strong>输出排序结果</strong>:根据计数数组中的统计结果,将待排序列表中的元素放置到正确的位置上,最终得到排序结果。</li></ol><img decoding="async" src="//www.runoob.com/wp-content/uploads/2019/03/countingSort.gif"></div><div class="tab-item-content" id="test1-9"><div class="note info no-icon flat"><p> 桶排序是计数排序的升级版。它利用了函数的映射关系,高效与否的关键就在于这个映射函数的确定。为了使桶排序更加高效,我们需要做到这两点:</p><p>在额外空间充足的情况下,尽量增大桶的数量<br>使用的映射函数能够将输入的 N 个数据均匀的分配到 K 个桶中</p></div><p><strong>基本步骤:</strong></p><ol><li><strong>划分桶</strong>:根据待排序元素的范围,确定一定数量的桶,并将待排序元素分配到相应的桶中。</li><li><strong>桶内排序</strong>:对每个桶中的元素进行排序。可以使用任何适合的排序算法,如插入排序、快速排序等。</li><li><strong>合并结果</strong>:按照桶的顺序依次取出各个桶中的元素,即可得到有序的结果。</li></ol></div><div class="tab-item-content" id="test1-10"><div class="note info no-icon flat"><p> 基数排序是一种非比较型整数排序算法,其原理是将整数按位数切割成不同的数字,然后按每个位数分别比较。由于整数也可以表达字符串(比如名字或日期)和特定格式的浮点数,所以基数排序也不是只能使用于整数。</p></div><p><strong>基本步骤:</strong></p><ol><li><strong>按位排序</strong>:从最低位开始,对待排序的元素按照当前位数进行排序。可以使用稳定的排序算法,如计数排序或桶排序。</li><li><strong>重复排序</strong>:重复第一步的过程,对每一位进行排序,直到对最高位进行排序。</li><li><strong>合并结果</strong>:完成所有位的排序后,即可得到有序的结果。</li></ol><img decoding="async" src="//www.runoob.com/wp-content/uploads/2019/03/radixSort.gif" alt=""></div></div><div class="tab-to-top"><button type="button" aria-label="scroll to top"><i class="anzhiyufont anzhiyu-icon-arrow-up"></i></button></div></div><h1>总结</h1><table><thead><tr><th style="text-align:center">排序算法</th><th style="text-align:center">平均时间复杂度</th><th style="text-align:center">最好情况</th><th style="text-align:center">最坏情况</th><th style="text-align:center">空间复杂度</th><th style="text-align:center">排序方式</th><th style="text-align:center">稳定性</th></tr></thead><tbody><tr><td style="text-align:center">冒泡排序</td><td style="text-align:center">O(n^2)</td><td style="text-align:center">O(n)</td><td style="text-align:center">O(n)</td><td style="text-align:center">O(1)</td><td style="text-align:center">In-place</td><td style="text-align:center">稳定</td></tr><tr><td style="text-align:center">选择排序</td><td style="text-align:center">O(n^2)</td><td style="text-align:center">O(n^2)</td><td style="text-align:center">O(n^2)</td><td style="text-align:center">O(1)</td><td style="text-align:center">In-place</td><td style="text-align:center">不稳定</td></tr><tr><td style="text-align:center">插入排序</td><td style="text-align:center">O(n^2)</td><td style="text-align:center">O(n)</td><td style="text-align:center">O(n^2)</td><td style="text-align:center">O(1)</td><td style="text-align:center">In-place</td><td style="text-align:center">稳定</td></tr><tr><td style="text-align:center">希尔排序</td><td style="text-align:center">O(n log n)</td><td style="text-align:center">O(n log^2 n)</td><td style="text-align:center">O(n log^2 n)</td><td style="text-align:center">O(1)</td><td style="text-align:center">In-place</td><td style="text-align:center">不稳定</td></tr><tr><td style="text-align:center">归并排序</td><td style="text-align:center">O(n log n)</td><td style="text-align:center">O(n log n)</td><td style="text-align:center">O(n logn)</td><td style="text-align:center">O(n)</td><td style="text-align:center">Out-place</td><td style="text-align:center">稳定</td></tr><tr><td style="text-align:center">快速排序</td><td style="text-align:center">O(n log n)</td><td style="text-align:center">O(n log n)</td><td style="text-align:center">O(n^2)</td><td style="text-align:center">O(log n)</td><td style="text-align:center">In-place</td><td style="text-align:center">不稳定</td></tr><tr><td style="text-align:center">堆排序</td><td style="text-align:center">O(n log n)</td><td style="text-align:center">O(n log n)</td><td style="text-align:center">O(n log n)</td><td style="text-align:center">O(1)</td><td style="text-align:center">In-place</td><td style="text-align:center">不稳定</td></tr><tr><td style="text-align:center">计数排序</td><td style="text-align:center">O(n+k)</td><td style="text-align:center">O(n+k)</td><td style="text-align:center">O(n+k)</td><td style="text-align:center">O(k)</td><td style="text-align:center">Out-place</td><td style="text-align:center">稳定</td></tr><tr><td style="text-align:center">桶排序</td><td style="text-align:center">O(n+k)</td><td style="text-align:center">O(n+k)</td><td style="text-align:center">O(n^2)</td><td style="text-align:center">O(n+k)</td><td style="text-align:center">Out-place</td><td style="text-align:center">稳定</td></tr><tr><td style="text-align:center">基数排序</td><td style="text-align:center">O(n×k)</td><td style="text-align:center">O(n×k)</td><td style="text-align:center">O(n×k)</td><td style="text-align:center">O(n+k)</td><td style="text-align:center">Out-place</td><td style="text-align:center">稳定</td></tr></tbody></table>]]></content>
<categories>
<category> 软考笔记 </category>
</categories>
<tags>
<tag> 软件设计师 </tag>
<tag> 软考 </tag>
<tag> 排序算法 </tag>
</tags>
</entry>
<entry>
<title>一文搞懂波兰表达式</title>
<link href="/ebff.html"/>
<url>/ebff.html</url>
<content type="html"><![CDATA[<h1>1.什么式波兰表达式</h1><p> 波兰表达式(<mark class="hl-label orange">又称逆波兰表达式</mark> )是一种数学和逻辑表达式的表示方法。在波兰表达式中,操作符放在它们所操作的数之前,而不是在它们之间,这样可以消除括号的需求。波兰表达式通过一种前缀或后缀的方式来表示,分别称为前缀波兰表达式和后缀波兰表达式。</p><h1>2.为什么会有这种表达式</h1><p> 在计算机中,要本着能简化就简化的原则来设计,对于一个正常的数学运算表达式,除了有加减乘除之外,还有一些括号来标识运算的优先级,那么对于计算机而言,能不能不写括号就能正常运算这个表达式呢,那么波兰表达式就产生了。</p><h1>3.直接上🌰</h1><p>下面的表达式就是一个比较简单的例子,我们也叫它<mark class="hl-label orange">中缀表达式</mark> </p><p>a + b * (c - d) + e/f</p><p>有了<mark class="hl-label orange">中缀表达式</mark> ,那肯定也有<mark class="hl-label orange">前缀表达式</mark> 和<mark class="hl-label orange">后缀表达式</mark> </p><h2 id="中缀表达式转换">中缀表达式转换</h2><p>首先根据中缀表达式构造一个二叉树</p><pre><code> + + / \ / \ a + + / / \ / \ / \ * / 或者 a * e f / \ / \ / \ b - e f b - / \ / \ c d c d </code></pre><div class="note info no-icon flat"><p>前缀表达式 = 前序遍历 (波兰式)<br>中缀表达式 = 中序遍历<br>后缀表达式 = 后序遍历 (逆波兰式)</p></div><p>所以根据上面的二叉树我们可以知道<br>前缀表达式 = <mark class="hl-label green">+ a + * b - c d / e f</mark> 或 <mark class="hl-label green">+ + a * b - c d / e f</mark> <br>后缀表达式 = <mark class="hl-label green">a b c d - * e f / + +</mark> 或 <mark class="hl-label green">a b c d - * + e f / +</mark> </p><div class="note warning no-icon flat"><p> 通过树基础知识我们知道,树的三种遍历方式中,如果告诉我们任意一种遍历,我们式无法确切的推出另外两种遍历方式的,也就是说我们无法确定这一棵树的形态,所以波兰式也是一样的,一个表达式可能对应多个波兰式</p></div><h1>在计算机中的计算方式</h1><div class="note success no-icon flat"><p> 在计算机中,表达式的计算通常是按照逆波兰式(后缀表达式)进行的。逆波兰式具有很好的计算机解析性质,可以直接通过栈数据结构进行求解</p></div><p>首先将转换后的表达式想象成一个队列,</p><ol><li>从左往右依次出队,</li><li>然后进行入栈,当遇到符号时,将前两个操作数取出,进行运算</li><li>将上一步运算的结果继续入栈</li><li>直到队列中没有操作数,表达式计算完毕</li></ol><hr><img width="200px" src="https://up.ctext.top/article/2024/03/xuexi.png" alt="又是充实的一天!!!" border="0">]]></content>
<categories>
<category> 软考笔记 </category>
</categories>
<tags>
<tag> 软件设计师 </tag>
<tag> 软考 </tag>
</tags>
</entry>
<entry>
<title>自动替换前端node_modules源码</title>
<link href="/7104.html"/>
<url>/7104.html</url>
<content type="html"><![CDATA[<h1>前言</h1><div class="note default no-icon flat"><p> 首先为什么要写这篇文章呢,因为我遇到了一个小问题,前几天在我的博客引入了评论的功能(<mark class="hl-label default">Waline</mark> ),然后呢,就看了一下官方的<a href="https://waline.js.org/">配置文档</a>, 里面有一些自定义的配置,需要在引入<mark class="hl-label default">Waline</mark> 进行配置,然后发现我当前使用的Hexo主题并没有开放这些配置,也就是说我没办法修改<mark class="hl-label default">Waline</mark> 的这些配置,然后就开始慢慢摸索,找到主题对于<mark class="hl-label default">Waline</mark> 的配置的源代码, 然后呢,就出现了一个问题,因为是源码文件,都在node_modules文件夹下,所以修改只能在当前电脑生效,换个电脑是不会同步的…… 然后就有了这篇文章。</p></div><mark class="hl-label pink">然后开始疯狂的搜索资料,终于找到了一个比较完美的解决方案</mark> <h1>下面开始教程</h1><div class="note info no-icon flat"><p>这个教程的思路就是在打包之前执行一段代码,这段代码的作用就是自动替换node_modules对应的文件内容</p></div><p>首先在你的项目根目录创建两个文件夹<mark class="hl-label blue">change_modules</mark> 、<mark class="hl-label blue">script</mark> ,根据名字就能猜到第一个是存放你要替换的源码,第二个就是执行替换的脚本,</p><p>在<mark class="hl-label blue">script</mark> 目录新建一个文件<mark class="hl-label purple">change_modules.js</mark> ,内容如下:</p><figure class="highlight javascript"><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></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"><span class="comment">// 自动替换node_modules指定文件</span></span><br><span class="line"><span class="keyword">const</span> fs = <span class="built_in">require</span>(<span class="string">'fs'</span>)</span><br><span class="line"><span class="keyword">const</span> path = <span class="built_in">require</span>(<span class="string">'path'</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment">// 将 change_modules 内的文件覆盖在node_modules中</span></span><br><span class="line"><span class="keyword">const</span> <span class="variable constant_">REAL_NODE_MODULES</span> = path.<span class="title function_">resolve</span>(<span class="string">'./node_modules'</span>) <span class="comment">// 旧node_modules</span></span><br><span class="line"><span class="keyword">const</span> <span class="variable constant_">MY_NODE_MODULES</span> = path.<span class="title function_">resolve</span>(<span class="string">'./change_modules'</span>) <span class="comment">// 新node_modules</span></span><br><span class="line"><span class="title function_">copy</span>(<span class="variable constant_">MY_NODE_MODULES</span>, <span class="variable constant_">REAL_NODE_MODULES</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> *<span class="doctag">@param</span>{<span class="type">string</span>}需要复制的目录、文件</span></span><br><span class="line"><span class="comment"> *<span class="doctag">@param</span>{<span class="type">string</span>}复制到指定的目录、文件</span></span><br><span class="line"><span class="comment"> *<span class="doctag">@param</span>{<span class="type">function</span>}每次复制前,都会经过一次filterFn,若返回true,则复制。</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">copy</span>(<span class="params">origin, target, filterFn = () => <span class="literal">true</span></span>) {</span><br><span class="line"> <span class="keyword">if</span> (fs.<span class="title function_">statSync</span>(origin).<span class="title function_">isDirectory</span>()) {</span><br><span class="line"> <span class="keyword">if</span> (!fs.<span class="title function_">existsSync</span>(target)) {</span><br><span class="line"> fs.<span class="title function_">mkdirSync</span>(target)</span><br><span class="line"> }</span><br><span class="line"> fs.<span class="title function_">readdirSync</span>(origin).<span class="title function_">forEach</span>(<span class="function"><span class="params">originName</span> =></span> {</span><br><span class="line"> <span class="keyword">const</span> originFilePath = path.<span class="title function_">resolve</span>(origin, originName)</span><br><span class="line"> <span class="keyword">const</span> targetFilePath = path.<span class="title function_">resolve</span>(target, originName)</span><br><span class="line"> <span class="title function_">copy</span>(originFilePath, targetFilePath, filterFn)</span><br><span class="line"> })</span><br><span class="line"> } <span class="keyword">else</span> <span class="keyword">if</span> (<span class="title function_">filterFn</span>(origin, target)) {</span><br><span class="line"> <span class="keyword">const</span> fileName = path.<span class="title function_">basename</span>(origin);</span><br><span class="line"> <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">"替换文件 "</span> + fileName)</span><br><span class="line"> <span class="comment">//执行替换</span></span><br><span class="line"> fs.<span class="title function_">copyFileSync</span>(origin, target)</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>然后找到你项目的<mark class="hl-label purple">package.json</mark> ,找到类似下面代码的地方,就是你项目指定打包命令的地方,例如我这是hexo的打包命令</p><figure class="highlight json"><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="attr">"scripts"</span><span class="punctuation">:</span> <span class="punctuation">{</span></span><br><span class="line"> <span class="attr">"build"</span><span class="punctuation">:</span> <span class="string">"node ./scripts/change_modules.js && hexo generate"</span><span class="punctuation">,</span></span><br><span class="line"> <span class="attr">"clean"</span><span class="punctuation">:</span> <span class="string">"hexo clean"</span><span class="punctuation">,</span></span><br><span class="line"> <span class="attr">"deploy"</span><span class="punctuation">:</span> <span class="string">"node ./scripts/change_modules.js && hexo deploy"</span><span class="punctuation">,</span></span><br><span class="line"> <span class="attr">"server"</span><span class="punctuation">:</span> <span class="string">"node ./scripts/change_modules.js && hexo server"</span></span><br><span class="line"> <span class="punctuation">}</span></span><br></pre></td></tr></table></figure><p>然后在你打包命令之前添加一段命令<mark class="hl-label orange">node ./scripts/change_modules.js</mark> ,用来执行你创建的脚本文件</p><div class="note primary flat"><p>然后最重要的地方来了,复制你想修改的<mark class="hl-label blue">node_modules</mark> 里面的源码文件到<mark class="hl-label blue">change_modules</mark><br><span class='p red'>注意保证路径相同!注意保证路径相同!注意保证路径相同!重要的事情说三遍</span></p></div><p>到这里差不多就结束了,然后当你再次执行打包命令时,就会看到如下的输出:</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">替换文件 ********</span><br></pre></td></tr></table></figure><div class="note success flat"><p>看到这个说明就是成功了</p></div><p>最后呢,在附上我修改的<mark class="hl-label default">Waline</mark> 的一些配置</p><figure class="highlight javascript"><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><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> locale = {</span><br><span class="line"> <span class="attr">nick</span>: <span class="string">'你的专属昵称'</span>,</span><br><span class="line"> <span class="attr">nickError</span>: <span class="string">'昵称太短啦!至少得有3个字符才能算数哦!'</span>,</span><br><span class="line"> <span class="attr">mail</span>: <span class="string">'你的电子小信箱'</span>,</span><br><span class="line"> <span class="attr">mailError</span>: <span class="string">'哎呀,这不是一个合格的邮箱地址哦,请再检查一遍!'</span>,</span><br><span class="line"> <span class="attr">link</span>: <span class="string">'你有个酷酷的网址吗?'</span>,</span><br><span class="line"> <span class="attr">optional</span>: <span class="string">'这个嘛,想填就填,不填也行!'</span>,</span><br><span class="line"> <span class="attr">placeholder</span>: <span class="string">'吐槽一下?'</span>,</span><br><span class="line"> <span class="attr">sofa</span>: <span class="string">'来,坐沙发上,发表你的评论吧!'</span>,</span><br><span class="line"> <span class="attr">submit</span>: <span class="string">'一键发送,让世界听到你的声音!'</span>,</span><br><span class="line"> <span class="attr">like</span>: <span class="string">'点个赞,让TA知道你的心意!'</span>,</span><br><span class="line"> <span class="attr">cancelLike</span>: <span class="string">'哎呀,不小心点错了,取消赞!'</span>,</span><br><span class="line"> <span class="attr">reply</span>: <span class="string">'回复TA,开启一场对话吧!'</span>,</span><br><span class="line"> <span class="attr">cancelReply</span>: <span class="string">'等等,我话还没说完,取消回复!'</span>,</span><br><span class="line"> <span class="attr">comment</span>: <span class="string">'来,说说你的看法,让评论区热闹起来!'</span>,</span><br><span class="line"> <span class="attr">refresh</span>: <span class="string">'刷新一下,看看有啥新动态!'</span>,</span><br><span class="line"> <span class="attr">more</span>: <span class="string">'哇塞,还有更多精彩内容等你来加载!'</span>,</span><br><span class="line"> <span class="attr">preview</span>: <span class="string">'先睹为快,预览一下你的大作吧!'</span>,</span><br><span class="line"> <span class="attr">emoji</span>: <span class="string">'来,加点表情,让你的评论更生动!'</span>,</span><br><span class="line"> <span class="attr">uploadImage</span>: <span class="string">'上传你的美照,让大家一起欣赏!'</span>,</span><br><span class="line"> <span class="attr">seconds</span>: <span class="string">'刚刚才发的,新鲜出炉!'</span>,</span><br><span class="line"> <span class="attr">minutes</span>: <span class="string">'几分钟前,还热乎着呢!'</span>,</span><br><span class="line"> <span class="attr">hours</span>: <span class="string">'几小时前,热度还在哦!'</span>,</span><br><span class="line"> <span class="attr">days</span>: <span class="string">'几天前,但依旧值得一看!'</span>,</span><br><span class="line"> <span class="attr">now</span>: <span class="string">'哇塞,刚刚发的,快抢沙发!'</span>,</span><br><span class="line"> <span class="attr">uploading</span>: <span class="string">'稍等片刻,你的图片正在飞奔而来!'</span>,</span><br><span class="line"> <span class="attr">login</span>: <span class="string">'登录一下,解锁更多功能!'</span>,</span><br><span class="line"> <span class="attr">logout</span>: <span class="string">'拜拜了您嘞,下次再见!'</span>,</span><br><span class="line"> <span class="attr">admin</span>: <span class="string">'博主大人在此,谁敢造次!'</span>,</span><br><span class="line"> <span class="attr">sticky</span>: <span class="string">'置顶一下,让更多人看到你的精彩内容!'</span>,</span><br><span class="line"> <span class="attr">word</span>: <span class="string">'字'</span>,</span><br><span class="line"> <span class="attr">wordHint</span>: <span class="string">'评论字数要在0到1字之间哦!\n现在你已经写了$2个字了,加油!'</span>,</span><br><span class="line"> <span class="attr">anonymous</span>: <span class="string">'神秘人出没,猜猜是谁?'</span>,</span><br><span class="line"> <span class="attr">level0</span>: <span class="string">'潜水员,深藏不露!'</span>,</span><br><span class="line"> <span class="attr">level1</span>: <span class="string">'冒泡小能手,偶尔露个头!'</span>,</span><br><span class="line"> <span class="attr">level2</span>: <span class="string">'吐槽大师,一针见血!'</span>,</span><br><span class="line"> <span class="attr">level3</span>: <span class="string">'活跃分子,无处不在!'</span>,</span><br><span class="line"> <span class="attr">level4</span>: <span class="string">'话痨达人,说个不停!'</span>,</span><br><span class="line"> <span class="attr">level5</span>: <span class="string">'传说级大神,膜拜一下!'</span>,</span><br><span class="line"> <span class="attr">gif</span>: <span class="string">'动态表情包,让你的评论更有趣!'</span>,</span><br><span class="line"> <span class="attr">gifSearchPlaceholder</span>: <span class="string">'快来搜索你喜欢的表情包,让评论更生动!'</span>,</span><br><span class="line"> <span class="attr">profile</span>: <span class="string">'看看我的个人资料,了解一下我吧!'</span>,</span><br><span class="line"> <span class="attr">approved</span>: <span class="string">'审核通过,可以展示啦!'</span>,</span><br><span class="line"> <span class="attr">waiting</span>: <span class="string">'正在等待审核,别急哦!'</span>,</span><br><span class="line"> <span class="attr">spam</span>: <span class="string">'垃圾内容,走开走开!'</span>,</span><br><span class="line"> <span class="attr">unsticky</span>: <span class="string">'换个位置看看!'</span>,</span><br><span class="line"> <span class="attr">oldest</span>: <span class="string">'看看最早的评论!'</span>,</span><br><span class="line"> <span class="attr">latest</span>: <span class="string">'看看最新的动态!'</span>,</span><br><span class="line"> <span class="attr">hottest</span>: <span class="string">'看看哪条评论最火!'</span>,</span><br><span class="line"> <span class="attr">reactionTitle</span>: <span class="string">'快来对这篇文章发表你的看法吧,让博主知道你的想法!😜'</span></span><br><span class="line">};</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> waline = <span class="title class_">Waline</span>.<span class="title function_">init</span>(<span class="title class_">Object</span>.<span class="title function_">assign</span>({</span><br><span class="line"> <span class="comment">//…………</span></span><br><span class="line"> <span class="attr">reaction</span>: <span class="literal">true</span>, </span><br><span class="line"> locale</span><br><span class="line"> }</span><br></pre></td></tr></table></figure><p>这个配置的效果你可以到下面的评论区看看😎</p>]]></content>
<categories>
<category> 前端开发 </category>
</categories>
<tags>
<tag> hexo </tag>
<tag> Waline </tag>
<tag> 魔改 </tag>
</tags>
</entry>
<entry>
<title>一文搞懂奇偶校验、海明码和CRC</title>
<link href="/eaa2.html"/>
<url>/eaa2.html</url>
<content type="html"><![CDATA[<h1>1. 为什么要有校验码?</h1><div class="note default no-icon flat"><p> 因为在数据存取和传送的过程中,由于元器件或者噪音的干扰等原因会出现错误,这个时候我们就需要采取相应的措施,发现并纠正错误,对于错误的检测和校正,大多采取“冗余校验”的思想,即除原数据外,额外增加若干位编码,这些新增的代码称为校验位。</p></div><h1>2. 奇偶校验</h1><div class="note info no-icon flat"><p> 是一种常用的错误检测方法,用于校验代码传输的正确性。它根据被传输的一组二进制代码的数位中“1”的个数是奇数还是偶数来进行校验。如果采用奇数的方式,则称为奇校验;反之,则称为偶校验。</p></div><h2 id="校验位的计算">校验位的计算</h2><ul><li><mark class="hl-label orange">奇校验</mark> :如果数据单元中1的数量已经是奇数,则校验位设置为0;否则,校验位设置为1。 </li><li><mark class="hl-label pink">偶校验</mark> :如果数据单元中1的数量已经是偶数,则校验位设置为0;否则,校验位设置为1。</li></ul><h2 id="举个栗子🌰">举个栗子🌰</h2><p>一个七位数的数据单元1011011</p><ul><li>奇校验编码:<span class='p red'>0</span>1011011</li><li>偶校验编码:<span class='p red'>1</span>1011011</li></ul><div class="note warning no-icon flat"><p>红色是校验位,可以在数据的前面也可以在数据的后面</p></div><h2 id="总结">总结</h2><div class="note info no-icon flat"><p> 奇偶校验是一种简单且易于实现的错误检测技术。虽然它不能解决所有的错误情况,但其低成本和实用性使它成为许多通信和存储系统的首选错误检测方法。随着技术的发展,更复杂的错误检测和纠正算法被开发出来,但奇偶校验仍然是计算机科学教育和初级通信系统中的重要组成部分。</p></div><h1>2. CRC(循环冗余校验)</h1><div class="note default no-icon flat"><p> 循环冗余校验(Cyclic Redundancy Check, CRC)是一种根据网络数据包或计算机文件等数据产生简短固定位数校验码的一种信道编码技术,主要用来检测或校验数据传输或者保存后可能出现的错误。它是利用除法及余数的原理来作错误侦测的。</p></div><h2 id="校验位的计算-v2">校验位的计算</h2><ul><li>首先通过给定的生成多项式来确定除数,然后将要进行校验或者编码的数据进行模2除法(异或),取最后的余数然后与数据为拼接即可</li></ul><h2 id="举个栗子🌰-v2">举个栗子🌰</h2><p>假设要传输的数据为1101011011,给定的生成多项式为G(X)=x<sup>4</sup>+x+1</p><p>根据题目中的生成多项式可以得出除数为10011,下面开始进行计算:</p><div class="note danger no-icon flat"><p>计算是首先要进行补零,零的个数取决于生成多项式的最高次幂</p></div><figure class="highlight plaintext"><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></pre></td><td class="code"><pre><span class="line"> 1100001010</span><br><span class="line"> _______________</span><br><span class="line">10011 ) 11010110110000</span><br><span class="line"> 10011.........</span><br><span class="line"> 1001110110000</span><br><span class="line"> 10011........</span><br><span class="line"> 10110000</span><br><span class="line"> 10011...</span><br><span class="line"> 101000</span><br><span class="line"> 10011.</span><br><span class="line"> 1110</span><br></pre></td></tr></table></figure><p>经过上面的计算得出校验码位1110,所以实际发送的数据为11010110111110</p><p>当客户端收到这个数据之后,要进行CRC校验</p><figure class="highlight plaintext"><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"> 110000101</span><br><span class="line"> _________________</span><br><span class="line">10011 ) 11010110111110</span><br><span class="line"> 10011.........</span><br><span class="line"> 1001110111110</span><br><span class="line"> 10011........</span><br><span class="line"> 10111110</span><br><span class="line"> 10011...</span><br><span class="line"> 100110</span><br><span class="line"> 10011.</span><br><span class="line"> 0</span><br><span class="line"></span><br></pre></td></tr></table></figure><div class="note success no-icon flat"><p>经过计算,得出的余数为0,所以说明这个数据没有差错,这就是CRC整个编码以及检错的过程</p></div><h1>3. 海明校验码</h1><div class="note default no-icon flat"><p> 又称汉明码,是一种在计算机通讯中用于错误检测和纠正的编码方法。它是由理查德·海明于1950年发明的。它的核心原理是将数据分割成固定长度的块,每个块都用二进制表示,并在每个块中添加额外的校验位。这些校验位能够检测和纠正一个或多个位的错误。</p></div><h2 id="校验位与数据位的关系">校验位与数据位的关系</h2><ul><li>2<sup>k</sup>−1>=m+k</li></ul><div class="note info no-icon flat"><p>m代表数据位,k代表校验位,校验位所在的位置是2<sup>n</sup>,其余都是数据位</p></div><h2 id="举个栗子🌰-v3">举个栗子🌰</h2><p>假设原始数据为01101110</p><table><thead><tr><th style="text-align:center">位置</th><th style="text-align:center">8</th><th style="text-align:center">7</th><th style="text-align:center">6</th><th style="text-align:center">5</th><th style="text-align:center">4</th><th style="text-align:center">3</th><th style="text-align:center">2</th><th style="text-align:center">1</th></tr></thead><tbody><tr><td style="text-align:center">原始信息位</td><td style="text-align:center">0</td><td style="text-align:center">1</td><td style="text-align:center">1</td><td style="text-align:center">0</td><td style="text-align:center">1</td><td style="text-align:center">1</td><td style="text-align:center">1</td><td style="text-align:center">0</td></tr></tbody></table><p>根据上述公式,当 m(信息位)=8时,k(校验位)最小可以取 4 ,所以可以得到如下表格:</p><table><thead><tr><th style="text-align:center">位置</th><th style="text-align:center">12</th><th style="text-align:center">11</th><th style="text-align:center">10</th><th style="text-align:center">9</th><th style="text-align:center">8</th><th style="text-align:center">7</th><th style="text-align:center">6</th><th style="text-align:center">5</th><th style="text-align:center">4</th><th style="text-align:center">3</th><th style="text-align:center">2</th><th style="text-align:center">1</th></tr></thead><tbody><tr><td style="text-align:center">新的信息位</td><td style="text-align:center">0</td><td style="text-align:center">1</td><td style="text-align:center">1</td><td style="text-align:center">0</td><td style="text-align:center">H8</td><td style="text-align:center">1</td><td style="text-align:center">1</td><td style="text-align:center">1</td><td style="text-align:center">H4</td><td style="text-align:center">0</td><td style="text-align:center">H2</td><td style="text-align:center">H1</td></tr></tbody></table><p>下面开始计算校验位的值</p><p>十进制对应二进制的数字如下</p><table><thead><tr><th style="text-align:center">位置</th><th style="text-align:center">二进制码</th></tr></thead><tbody><tr><td style="text-align:center">1</td><td style="text-align:center">0001</td></tr><tr><td style="text-align:center">2</td><td style="text-align:center">0010</td></tr><tr><td style="text-align:center">3</td><td style="text-align:center">0011</td></tr><tr><td style="text-align:center">4</td><td style="text-align:center">0100</td></tr><tr><td style="text-align:center">5</td><td style="text-align:center">0101</td></tr><tr><td style="text-align:center">6</td><td style="text-align:center">0110</td></tr><tr><td style="text-align:center">7</td><td style="text-align:center">0111</td></tr><tr><td style="text-align:center">8</td><td style="text-align:center">1000</td></tr><tr><td style="text-align:center">9</td><td style="text-align:center">1001</td></tr><tr><td style="text-align:center">10</td><td style="text-align:center">1010</td></tr><tr><td style="text-align:center">11</td><td style="text-align:center">1011</td></tr><tr><td style="text-align:center">12</td><td style="text-align:center">1100</td></tr></tbody></table><table><thead><tr><th style="text-align:center">海明码</th><th style="text-align:center">出现的位置</th><th style="text-align:center">对应位置上的值异或</th><th style="text-align:center">结果</th></tr></thead><tbody><tr><td style="text-align:center">H1</td><td style="text-align:center">3,5,7,9,11</td><td style="text-align:center">0⊕1⊕1⊕0⊕1</td><td style="text-align:center">1</td></tr><tr><td style="text-align:center">H2</td><td style="text-align:center">3,6,7,10,11</td><td style="text-align:center">0⊕1⊕1⊕1⊕1</td><td style="text-align:center">0</td></tr><tr><td style="text-align:center">H4</td><td style="text-align:center">5,6,7,12</td><td style="text-align:center">1⊕1⊕1⊕0</td><td style="text-align:center">1</td></tr><tr><td style="text-align:center">H8</td><td style="text-align:center">9,10,11,12</td><td style="text-align:center">0⊕1⊕1⊕0</td><td style="text-align:center">0</td></tr></tbody></table><div class="note primary no-icon flat"><p>这里计算的规律是,拿H1举例,H1在第一位,对应的二进制编码就是 1,所以我们要根据上面的进制表,找到第一位也是 1 的对应的位置,有 3,5,7,9,11,然后在找到这几个位置对应的数据位求异或,即可得到H1对应的海明码,其它以此类推……</p></div><p>通过上面的计算,我们就可以得到一个经过编码之后的数据:0110 0111 1001</p><table><thead><tr><th style="text-align:center">位置</th><th style="text-align:center">12</th><th style="text-align:center">11</th><th style="text-align:center">10</th><th style="text-align:center">9</th><th style="text-align:center">8</th><th style="text-align:center">7</th><th style="text-align:center">6</th><th style="text-align:center">5</th><th style="text-align:center">4</th><th style="text-align:center">3</th><th style="text-align:center">2</th><th style="text-align:center">1</th></tr></thead><tbody><tr><td style="text-align:center">最终信息位</td><td style="text-align:center">0</td><td style="text-align:center">1</td><td style="text-align:center">1</td><td style="text-align:center">0</td><td style="text-align:center">0</td><td style="text-align:center">1</td><td style="text-align:center">1</td><td style="text-align:center">1</td><td style="text-align:center">1</td><td style="text-align:center">0</td><td style="text-align:center">0</td><td style="text-align:center">1</td></tr></tbody></table><p>接收端收到对应的数据之后,开始校验数据是否有错误</p><p>假设 0110 0111 1001 ->传输为 011<span class='p red'>1</span> 0111 1001</p><p>继续根据上面的方式,重新计算H1,H2,H4,H8校验位,计算的结果为<span class='p cyan'>1100</span></p><p>然后拿之前的校验码和新算出来的校验码求异或0101 ⊕ <span class='p cyan'>1100</span> = 1001 = 9,所以可以判断出是第9位出现了错误,修改之后就完成了纠错</p><div class="note success no-icon flat"><p>以上就是海明码检错以及纠错的过程</p></div><hr><div class="note warning flat"><p>如果你认真的看到这里,你一定会有一个疑问,如果出现两个以上的错误时,还能纠错吗?下面实践一下</p></div><h2 id="栗子2🌰">栗子2🌰</h2><p>假设出现了两个数据位的错误 0110 0111 1001 ->传输为 01<span class='p red'>01</span> 0111 1001</p><table><thead><tr><th style="text-align:center">位置</th><th style="text-align:center">12</th><th style="text-align:center">11</th><th style="text-align:center">10</th><th style="text-align:center">9</th><th style="text-align:center">8</th><th style="text-align:center">7</th><th style="text-align:center">6</th><th style="text-align:center">5</th><th style="text-align:center">4</th><th style="text-align:center">3</th><th style="text-align:center">2</th><th style="text-align:center">1</th></tr></thead><tbody><tr><td style="text-align:center">最终信息位</td><td style="text-align:center">0</td><td style="text-align:center">1</td><td style="text-align:center"><span class='p red'>0</span></td><td style="text-align:center"><span class='p red'>1</span></td><td style="text-align:center">0</td><td style="text-align:center">1</td><td style="text-align:center">1</td><td style="text-align:center">1</td><td style="text-align:center">1</td><td style="text-align:center">0</td><td style="text-align:center">0</td><td style="text-align:center">1</td></tr></tbody></table><p>再次计算校验位H1,H2,H4,H8为<span class='p cyan'>0110</span><br>再次与之前的校验码求异或 0101 ⊕ <span class='p cyan'>0110</span> = 0011 = 3<br>按照这次的计算结果来看,是第三位数据出现了问题,但是很明显我们出错的是第9,10位,但是,当你把第三位修改之后,再次进行校验,发现没有问题了😗</p><div class="note danger no-icon flat"><p>所以通过上面的第二个例子我们可以直到,海明码只能检测一位错误,当出现两个以上的错误是,纠错结果会变得不准确</p></div><h1>最终总结</h1><table><thead><tr><th style="text-align:left">特点</th><th style="text-align:left">奇偶校验</th><th style="text-align:left">CRC</th><th style="text-align:left">海明码</th></tr></thead><tbody><tr><td style="text-align:left">原理</td><td style="text-align:left">在数据中添加一个额外的校验位,使整个数据的1的个数为奇数(奇校验)或偶数(偶校验),用于检测单个比特的错误。</td><td style="text-align:left">利用除法操作,在发送的数据后面附加一个固定长度的校验码(CRC码),接收端通过相同的除法操作验证数据的完整性。</td><td style="text-align:left">通过在数据中添加冗余位(校验位),使得整个码字中特定位置的位数(1的个数)具有确定的奇偶性,以便检测和纠正错误。</td></tr><tr><td style="text-align:left">错误检测能力</td><td style="text-align:left">只能检测单个比特的错误,对于两个或更多比特的错误可能无法检测。</td><td style="text-align:left">能够检测并纠正多个比特的错误,具体取决于CRC码的长度。</td><td style="text-align:left">可以检测并纠正单个比特的错误,有时还能检测并纠正两个比特的错误。</td></tr><tr><td style="text-align:left">错误纠正能力</td><td style="text-align:left">无错误纠正能力。</td><td style="text-align:left">根据CRC码的长度和算法设计,可以纠正一定数量的错误。</td><td style="text-align:left">可以纠正单个比特的错误。</td></tr><tr><td style="text-align:left">开销</td><td style="text-align:left">仅需添加一个校验位,开销最小。</td><td style="text-align:left">需要添加固定长度的CRC码,开销适中。</td><td style="text-align:left">需要添加多个校验位,开销相对较大。</td></tr><tr><td style="text-align:left">实现复杂度</td><td style="text-align:left">最简单,只需进行简单的位运算。</td><td style="text-align:left">中等复杂度,需要选择合适的CRC多项式和实现除法操作。</td><td style="text-align:left">相对较高,需要设计合适的校验位位置和计算校验位的值。</td></tr><tr><td style="text-align:left">应用场景</td><td style="text-align:left">常用于简单的数据传输和存储系统,对错误检测和纠正要求不高的场合。</td><td style="text-align:left">广泛应用于网络通信、数据存储等领域,用于确保数据的完整性。</td><td style="text-align:left">适用于对错误检测和纠正有较高要求的应用,如内存错误检测。</td></tr></tbody></table><div class="note purple icon-padding disabled"><i class="note-icon far fa-hand-scissors"></i><p>笔记到这里就结束啦,你学会了么😮</p></div>]]></content>
<categories>
<category> 软考笔记 </category>
</categories>
<tags>
<tag> 软件设计师 </tag>
<tag> 软考 </tag>
</tags>
</entry>
<entry>
<title>一文搞懂原码、反码、补码、移码</title>
<link href="/782d.html"/>
<url>/782d.html</url>
<content type="html"><![CDATA[<ul><li>原码:正数是其二进制本身;负数是符号位为1,数值部分取X绝对值的二进制。</li><li>反码:正数的反码和原码相同;负数是符号位为1,其它位是原码取反。</li><li>补码:正数的补码和原码,反码相同;负数是符号位为1,其它位是原码取反,未位加1。(或者说负数的补码是其绝对值反码未位加1)</li><li>移码:将符号位取反的补码(不区分正负)</li></ul><div class="note warning flat"><p>正数的原码、反码、补码相同</p></div><h4 id="举个栗子以一个字节8位说明:">举个栗子以一个字节8位说明:</h4><table><thead><tr><th style="text-align:center">编码(十进制)</th><th style="text-align:center">22</th><th style="text-align:center">-22</th></tr></thead><tbody><tr><td style="text-align:center">原码</td><td style="text-align:center"><span class='p red'>0</span>10110</td><td style="text-align:center"><span class='p red'>1</span>10110</td></tr><tr><td style="text-align:center">反码</td><td style="text-align:center"><span class='p red'>0</span>10110</td><td style="text-align:center"><span class='p red'>1</span>01001</td></tr><tr><td style="text-align:center">补码</td><td style="text-align:center"><span class='p red'>0</span>10110</td><td style="text-align:center"><span class='p red'>1</span>01010</td></tr><tr><td style="text-align:center">移码</td><td style="text-align:center"><span class='p red'>1</span>10110</td><td style="text-align:center"><span class='p red'>0</span>01010</td></tr></tbody></table><p><em>注:<span class='p red'>红色为符号位</span></em></p><h4 id="1-根据补码求原码">1. 根据补码求原码</h4><p>已知一个数的补码,求原码的操作分两种情况:</p><ol><li>如果补码的符号位为“0”,表示是一个正数,所以补码就是该数的原码。</li><li>如果补码的符号位为“1”,表示是一个负数,求原码的操作可以是:符号位为1;其余各位<wavy>取反,然后再加1</wavy>。</li></ol><h4 id="2-补码加、减运算公式">2. 补码加、减运算公式</h4><p>在做补码加减法时,只需将符号位和数值部分一起参与运算,并且将符号位产生的进位丢掉即可</p><ol><li>补码加法公式</li></ol><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">[X+Y]补 = [X]补 + [Y]补</span><br></pre></td></tr></table></figure><ol start="2"><li>补码减法公式</li></ol><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">[X-Y]补 = [X]补-[Y]补 = [X]补 + [-Y]补</span><br></pre></td></tr></table></figure><p>其中:[-Y]补称为负补,求负补的办法是:<wavy>对补码的每一位(包括符合位)求反,且未位加1</wavy>。</p><h4 id="3-为何要使用原码-反码和补码">3. 为何要使用原码, 反码和补码</h4><p>首先我们知道计算机可以用三种编码表示一个数,对于正数:</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">[+1] = [00000001]原 = [00000001]反 = [00000001]补</span><br></pre></td></tr></table></figure><p>不需要过多解释,但是对于负数:</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">[-1] = [10000001]原= [11111110]反= [11111111]补</span><br></pre></td></tr></table></figure><p>可见原码, 反码和补码是完全不同的. 既然原码才是被人脑直接识别并用于计算表示方式, 为何还会有反码和补码呢?</p><p>因为对于人而言可以知道第一位表示符号位,但是对于计算机而言,是无法区别的,想要计算机区别就必须增加一些额外的标记,这样会对设计造成一定的复杂性,<br>于是,<span class='p cyan'>聪明的人们</span>开始探索,能不能将符号位也参与运算呢,首先来看<span class='p green'>原码</span>:</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">1 - 1 = 1 + (-1) = [00000001]原 + [10000001]原= [10000010]原 = -2</span><br></pre></td></tr></table></figure><div class="note danger flat"><p>很显然对于负数的加法,原码计算是错误的,为了解决这个问题,出现了<span class='p green'>反码</span></p></div><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">1 - 1 = 1 + (-1) = [0000 0001]原 + [1000 0001]原= [0000 0001]反+ [1111 1110]反= [1111 1111]反= [1000 0000]原= -0</span><br></pre></td></tr></table></figure><div class="note warning flat"><p>计算之后发现结果貌似没有问题,但是符号位有一点点问题,出现了-0,这就有可能出现+0和-0两个编码,都表示0,这样还是有问题,于是出现了<span class='p green'>补码</span></p></div><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">(-1) + (-127) = [1000 0001]原 + [1111 1111]原 = [1111 1111]补+ [1000 0001]补= [1000 0000]补</span><br></pre></td></tr></table></figure><div class="note success flat"><p>发现用了补码之后,解决了所有问题,并且还比其他两个编码方式多表示了一位负数-128,所以在同样长度的计算机中,补码会比其他两个编码多表示一位数字</p></div><h4 id="4-移码的作用">4.移码的作用</h4><p>移码(又叫增码或偏置码)通常用于表示浮点数的阶码,其表示形式与补码相似,只是其符号位用“1”表示正数,用“0”表示负数,数值部分与补码相同。</p><ol><li>移码的第一个作用就是方便比较大小<table><thead><tr><th style="text-align:center">十进制</th><th style="text-align:center">补码</th><th style="text-align:center">移码</th></tr></thead><tbody><tr><td style="text-align:center">-128</td><td style="text-align:center"><span class='p red'>1</span>0000000</td><td style="text-align:center"><span class='p red'>0</span>0000000</td></tr><tr><td style="text-align:center">-127</td><td style="text-align:center"><span class='p red'>1</span>0000001</td><td style="text-align:center"><span class='p red'>0</span>0000001</td></tr><tr><td style="text-align:center">-126</td><td style="text-align:center"><span class='p red'>1</span>0000010</td><td style="text-align:center"><span class='p red'>0</span>0000010</td></tr><tr><td style="text-align:center">-1</td><td style="text-align:center"><span class='p red'>1</span>1111111</td><td style="text-align:center"><span class='p red'>0</span>1111110</td></tr><tr><td style="text-align:center">0</td><td style="text-align:center"><span class='p red'>0</span>0000000</td><td style="text-align:center"><span class='p red'>1</span>0000000</td></tr><tr><td style="text-align:center">1</td><td style="text-align:center"><span class='p red'>0</span>0000001</td><td style="text-align:center"><span class='p red'>1</span>0000001</td></tr><tr><td style="text-align:center">127</td><td style="text-align:center"><span class='p red'>0</span>1111111</td><td style="text-align:center"><span class='p red'>1</span>1111111</td></tr></tbody></table></li></ol><div class="note primary modern"><p>通过这个表格你会发现当十进制逐渐增大时,只有对应的移码是逐渐增大的(把符号位也当作数值位看,因为计算机不会区分符号位)</p></div><ol start="2"><li>第二个作用就是浮点数的表示</li><li>…………</li></ol><div class="img-wrap"><div class="img-bg"><img class="img" src="https://ice.frostsky.com/2024/03/23/d52083d22a404324708ba4d812c215d1.png"/></div></div><div class="hide-block"><button type="button" class="hide-button" style="">此处省略一万字………… </button><div class="hide-content"><p>其实是我也不会!!!</p></div></div><div class="img-wrap"><div class="img-bg"><img class="img" src="https://blog-ctext.oss-cn-beijing.aliyuncs.com/blog/video/K8pk0.gif"/></div></div>]]></content>
<categories>
<category> 软考笔记 </category>
</categories>
<tags>
<tag> 软件设计师 </tag>
<tag> 二进制 </tag>
</tags>
</entry>
<entry>
<title>hexo博客源码自动备份</title>
<link href="/fe0d.html"/>
<url>/fe0d.html</url>
<content type="html"><![CDATA[<ol><li>在项目的目录打开一个控制台窗口,执行如下命令初始化Git</li></ol><figure class="highlight cmd"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git init</span><br></pre></td></tr></table></figure><ol start="2"><li>在项目目录新建一个 <strong>.gitignore</strong> 文件,如果有直接打开,添加以下代码</li></ol><figure class="highlight cmd"><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">.DS_Store</span><br><span class="line">Thumbs.db</span><br><span class="line">db.json</span><br><span class="line">*.log</span><br><span class="line">node_modules/</span><br><span class="line">public/</span><br><span class="line">.deploy*/</span><br><span class="line">_multiconfig.yml</span><br></pre></td></tr></table></figure><ol start="3"><li>执行完之后到 <strong>GitHub</strong> 或者 <strong>Gitee</strong> 创建一个仓库,然后在刚才的控制台继续执行</li></ol><figure class="highlight cmd"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">git add .</span><br><span class="line"># 你刚才创建的仓库地址</span><br><span class="line">git remote add origin https://github.com/xxxxxxxxxxxxxxx.git</span><br></pre></td></tr></table></figure><ol start="4"><li>然后在你的项目创建一个 <strong>scripts</strong> 目录,在里面创建一个文件 <strong>auto_backup.js</strong> ,将一下代码添加到文件中</li></ol><figure class="highlight javascript"><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="built_in">require</span>(<span class="string">'shelljs/global'</span>);</span><br><span class="line"><span class="keyword">const</span> path = <span class="built_in">require</span>(<span class="string">'path'</span>);</span><br><span class="line"><span class="keyword">try</span> {</span><br><span class="line"> hexo.<span class="title function_">on</span>(<span class="string">'deployAfter'</span>, <span class="keyword">function</span>(<span class="params"></span>) {<span class="comment">//当deploy完成后执行备份</span></span><br><span class="line"> <span class="keyword">const</span> commitMessageIndex = process.<span class="property">argv</span>.<span class="title function_">indexOf</span>(<span class="string">'-m'</span>);</span><br><span class="line"> <span class="keyword">const</span> commitMessage = commitMessageIndex !== -<span class="number">1</span> ? process.<span class="property">argv</span>.<span class="title function_">slice</span>(commitMessageIndex + <span class="number">1</span>).<span class="title function_">join</span>(<span class="string">' '</span>) : <span class="string">"blog auto backup script's commit"</span>;</span><br><span class="line"> <span class="title function_">run</span>(commitMessage);</span><br><span class="line"> });</span><br><span class="line"></span><br><span class="line">} <span class="keyword">catch</span> (e) {</span><br><span class="line"> <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">"产生了一个错误啊<( ̄3 ̄)> !,错误详情为:"</span> + e.<span class="title function_">toString</span>());</span><br><span class="line">}</span><br><span class="line"><span class="keyword">function</span> <span class="title function_">run</span>(<span class="params">commitMessage</span>) {</span><br><span class="line"> <span class="keyword">if</span> (!<span class="title function_">which</span>(<span class="string">'git'</span>)) {</span><br><span class="line"> <span class="title function_">echo</span>(<span class="string">'Sorry, this script requires git'</span>);</span><br><span class="line"> <span class="title function_">exit</span>(<span class="number">1</span>);</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> <span class="title function_">echo</span>(<span class="string">"======================自动备份源码开始======================"</span>);</span><br><span class="line"> <span class="title function_">echo</span>(<span class="string">'当前项目目录:'</span>, path.<span class="title function_">join</span>(__dirname, <span class="string">'..'</span>));</span><br><span class="line"> <span class="title function_">echo</span>(<span class="string">'本次提交信息:'</span>, commitMessage);</span><br><span class="line"> <span class="title function_">cd</span>(path.<span class="title function_">join</span>(__dirname, <span class="string">'..'</span>));</span><br><span class="line"> <span class="keyword">if</span> (<span class="title function_">exec</span>(<span class="string">'git add --all'</span>).<span class="property">code</span> !== <span class="number">0</span>) {</span><br><span class="line"> <span class="title function_">echo</span>(<span class="string">'Error: Git add failed'</span>);</span><br><span class="line"> <span class="title function_">exit</span>(<span class="number">1</span>);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span> (<span class="title function_">exec</span>(<span class="string">'git commit -am "'</span> + commitMessage + <span class="string">'"'</span>).<span class="property">code</span> !== <span class="number">0</span>) {</span><br><span class="line"> <span class="title function_">echo</span>(<span class="string">'Error: Git commit failed'</span>);</span><br><span class="line"> <span class="title function_">exit</span>(<span class="number">1</span>);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span> (<span class="title function_">exec</span>(<span class="string">'git push origin master'</span>).<span class="property">code</span> !== <span class="number">0</span>) {</span><br><span class="line"> <span class="title function_">echo</span>(<span class="string">'Error: Git push failed'</span>);</span><br><span class="line"> <span class="title function_">exit</span>(<span class="number">1</span>);</span><br><span class="line"> }</span><br><span class="line"> <span class="title function_">echo</span>(<span class="string">"======================自动备份源码结束======================"</span>)</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"></span><br></pre></td></tr></table></figure><ol start="5"><li>这个脚本需要安装一个依赖,继续执行</li></ol><figure class="highlight cmd"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm install --save shelljs</span><br></pre></td></tr></table></figure><ol start="6"><li>然后在你执行 <strong>hexo d -g -m ‘提交信息’</strong> 时就会自动开始备份</li></ol><img src="https://ice.frostsky.com/2024/03/16/3a66c8606e295ee40b6e854d67655d2b.png" alt="3a66c8606e295ee40b6e854d67655d2b.png" border="0" /><p>看到这个信息说明你已经成功了😝</p>]]></content>
<categories>
<category> 技术教程 </category>
</categories>
<tags>
<tag> hexo </tag>
</tags>
</entry>
<entry>
<title>改造你的微信传输助手</title>
<link href="/e7aa.html"/>
<url>/e7aa.html</url>
<content type="html"><![CDATA[<p>复制如下代码</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag"><<span class="name">a</span> <span class="attr">href</span>=<span class="string">"weixin://findfriend/verifycontact/wxid"</span>></span></span><br><span class="line">改备注</span><br><span class="line"><span class="tag"></<span class="name">a</span>></span></span><br></pre></td></tr></table></figure><p>发送到你的微信传输助手,你会看到如下信息</p><img src="https://ice.frostsky.com/2024/03/15/ec01bc80d8d96a0ece3f586e97050de1.png" alt="ec01bc80d8d96a0ece3f586e97050de1.png" style="zoom:50%;display: inline"/><p>点击蓝色的字体会跳转到一个添加好友的页面,这个时候吧备注修改成你想要的名字,点击发送<strong>发送</strong>,然后恭喜你得到了不一样的微信传输助手</p><img src="https://ice.frostsky.com/2024/03/15/b87993d2d6c11d1ff71c6e15c46364d6.png" alt="b87993d2d6c11d1ff71c6e15c46364d6.png" border="0" style="zoom:33%;display: inline" /><div class="note warning flat"><p>最后温馨提示:如果你用的是国内版的微信,那么你只有一次修改的机会,第二次修改不会生效,如果是 google 版的就可以修改多次</p></div>]]></content>
<categories>
<category> 有趣的知识 </category>
</categories>
<tags>
<tag> 微信 </tag>
</tags>
</entry>
<entry>
<title>软件设计师考点总结</title>
<link href="/579f.html"/>
<url>/579f.html</url>
<content type="html"><![CDATA[<h1>《软件设计师》考点总结</h1><mark class="hl-label red">为了方便背诵,某些概念做了隐藏,点击即可显示</mark> <div class="hide-block"><button type="button" class="hide-button" style="">查看 </button><div class="hide-content"></div></div><h2 id="CPU主要组成">CPU主要组成</h2><ol><li><p>运算单元:</p><ul><li>包括 ALU、FPU。</li></ul></li><li><p>控制单元:</p><ul><li>包括 指令控制器,时序控制器,总线控制器,中断控制器。</li></ul></li><li><p>存储单元:</p><ul><li>包括 通用寄存器,状态寄存器,cache。</li></ul></li></ol><h2 id="多态">多态</h2><ol><li>参数多态<ul><li>应用广泛、最纯的多态。</li></ul></li><li>包含多态<ul><li>同样的操作可用于一个类型及其子类型。包含多态一般需要进行运行时的类型检查。包含多态在许多语言中都存在,最常见的例子就是子类型化,即一个类型是另外一个类型的子类型。</li><li><div class="hide-block"><button type="button" class="hide-button" style="">查看 </button><div class="hide-content"><p>(<strong>类的继承和接口的实现</strong>)</p></div></div></li></ul></li><li>强制多态:<ul><li>编译程序通过语义操作,把操作对象的类型强行加以变换,以符合函数或操作符的要求。</li><li><div class="hide-block"><button type="button" class="hide-button" style="">查看 </button><div class="hide-content"><p>(<strong>将一个对象强制转换为另一个对象</strong>)</p></div></div></li></ul></li><li>过载多态:<ul><li>同一个名(操作符﹑函数名)在不同的上下文中有不同的类型。 目前软设考查比较多的是过载多态。</li><li><div class="hide-block"><button type="button" class="hide-button" style="">查看 </button><div class="hide-content"><p>(<strong>相同名称在不同上下文中有不同含义</strong>)</p></div></div></li></ul></li></ol><h2 id="软件测试三个阶段">软件测试三个阶段</h2><ol><li>单元测试<ul><li>白盒测试</li><li>测试来源来源于<strong>详细设计</strong></li></ul></li><li>集成测试 (模块间的接口测试)<ul><li>黑盒测试和白盒测试</li><li>测试来源于<strong>概要设计</strong></li></ul></li><li>系统测试 (功能测试)<ul><li>黑盒测试bang</li><li>测试来源于<strong>需求分析</strong></li></ul></li></ol><h2 id="软件四种维护">软件四种维护</h2><ol><li>改正性维护。<ul><li>为了识别和纠正软件错误、改正软件性能上的缺陷、排除实施中的误使用,应当进行的诊断和改正错误的过程就称为改正性维护。</li></ul></li><li>适应性维护。<ul><li>在使用过程中,外部环境(新的硬、软件配置)、数据环境(数据库、数据格式、数据输入/输出方式、数据存储介质)可能发生变化。为使软件适应这种变化,而去修改软件的过程就称为适应性维护。</li></ul></li><li>完善性维护。<ul><li>在软件的使用过程中,用户往往会对软件提出新的功能与性能要求。为了满足这些要求,需要修改或再开发软件,以扩充软件功能、增强软件性能、改进加工效率、提高软件的可维护性。这种情况下进行的维护活动称为完善性维护。</li></ul></li><li>预防性维护。<ul><li>这是指预先提高软件的可维护性、可靠性等,为以后进一步改进软件打下良好基础。</li></ul></li></ol><h2 id="数据库范式理论简单记忆">数据库范式理论简单记忆</h2><ol><li><p><strong>第一范式(1NF)</strong>:</p><ul><li><mark class="hl-label blue">关系中的每个属性都是不可分割的原子项</mark> </li><li>简单来说,就是确保每一列中的数据都是原子性的,没有重复的属性或集合。</li></ul></li><li><p><strong>第二范式(2NF)</strong>:</p><ul><li><mark class="hl-label pink">每一个非主属性完全函数依赖于码</mark> </li><li>换句话说,表中的数据行必须能通过主键唯一标识,并且表中的非主键列不能仅依赖于主键的一部分。</li></ul></li><li><p><strong>第三范式(3NF)</strong>:</p><ul><li><mark class="hl-label orange">非主属性不传递依赖于码</mark> </li><li>这意味着非主键列不能依赖于其他非主键列,每个非主键列都必须直接依赖于主键。</li></ul></li><li><p><strong>BCNF(Boyce-Codd Normal Form)</strong>:</p><ul><li><mark class="hl-label green">所有决定因素(即决定其他属性的属性组合)都必须是候选键</mark> </li><li>设关系模式R<U,F>∈1NF,如果对于R的每个函数依赖X→Y,若Y不属于X,则X必含有超码(属性集A可以唯一地标识关系r中的一个元组,则称属性集A为关系r的一个超码),那么R∈BCNF。</li><li>这进一步减少了数据冗余和更新异常的可能性,确保数据的完整性和一致性。</li></ul></li></ol><h2 id="数据库模式">数据库模式</h2><ol><li>外模式(External Schema)<br>定义:外模式也称为用户模式,它是数据库的最外层,直接面向最终用户或应用程序<ul><li>外模式可以是数据库中的一个子集,包含虚拟<strong>视图</strong>或<strong>表</strong></li></ul></li><li>模式(Conceptual Schema)<br>定义:模式(或概念模式)是数据库的中间层,定义了整个数据库的逻辑结构,是所有外模式的公共基础。<ul><li>概念模式包括所有的<strong>数据表、字段及其关系</strong>,但不包含物理存储的细节</li></ul></li><li>内模式(Internal Schema)<br>定义:内模式是数据库的最底层,直接面向数据库管理系统(DBMS),定义了数据库的物理存储结构和访问方式。<ul><li>内模式包含物理存储的细节,如<strong>数据文件的分布、存取路径、索引设计</strong>等。</li></ul></li></ol><hr><h2 id="函数依赖">函数依赖</h2><h3 id="符号介绍">符号介绍</h3><ul><li>A ⊂ B:A包含B</li><li>A ⊆ B:真子集,A的所有元素都属于B,但B中至少有一个元素不属于A</li><li>X → Y:表示X函数决定Y或Y函数依赖于X</li><li>a ∊ A:元素a属于集合A</li></ul><h3 id="Armstrong公理系统">Armstrong公理系统</h3><ol><li>自反律(Reflexivity Rule<br>若 Y ⊆ X ⊆ U ,则 X → Y 为 F 所蕴涵。</li><li>增广律(augmentation rule)<br>若X→Y为F所蕴涵,且Z⊆U,则XZ→YZ为F所蕴涵。</li><li>传递律(transitivity rule)<br>若X→Y及Y→Z为F所蕴涵,则X→Z为F所蕴涵。</li></ol><h3 id="依赖">依赖</h3><ol><li>平凡函数依赖:<br>平凡函数依赖是指一个属性或一组属性完全地决定了自身。换句话说,如果一个属性 X 完全地决定了属性 Y,那么这种函数依赖被称为平凡函数依赖。例如,如果有 X→X 这样的函数依赖,那么它就是一个平凡函数依赖,因为 X 决定了自身的值。</li><li>非平凡函数依赖:<br>非平凡函数依赖是指一个属性或一组属性不完全地决定自身,而是由其他属性决定。如果一个属性 X 决定了另一个属性 Y,且 X 和 Y 不是同一个属性,那么这种函数依赖就是非平凡函数依赖。例如,如果有 X→Y 这样的函数依赖,其中 X 和 Y 是不同的属性,那么它就是一个非平凡函数依赖。</li><li>完全函数依赖:<br>完全函数依赖是指一个属性组合完全地决定了其他属性,而不能通过去掉其中的任何一个属性来维持该函数依赖。如果一个属性组合 X 完全地决定了属性 Y,但是去掉其中任何一个属性都不能维持该函数依赖,那么这种函数依赖就是完全函数依赖。</li><li>部分函数依赖<br>某些属性决定了另一个属性,但并非所有属性都对其决定。换句话说,如果一个属性组合中的一部分属性能够确定另一个属性的值,而不是整个属性组合。</li></ol><p><strong>个人理解</strong>:如果一个属性不依赖任何一个属性,那么就可以认为这个属性是一个平凡函数依赖;如果两个集合XY,只有X中全部属性才能推导出Y,那么就是完全函数依赖</p><hr><h2 id="树相关的计算公式">树相关的计算公式</h2><ol><li>节点总数</li></ol><ul><li>一个高度(<mark class="hl-label blue">根节点高度为0</mark> )为 h 的二叉树,节点,最多有 2^(h+1) −1 个,最少有 h+1 个</li></ul><ol start="2"><li>叶子节点数量</li></ol><ul><li>一个高度为 n 的二叉树叶子节点,2^h,最少为 1</li></ul><ol start="3"><li>二叉树节点和形态的关系</li></ol><ul><li>节点书为n的二叉树共有 (2n)! / n!(n+1)! 种形态</li><li>假如节点数为4,那么8<em>7</em>6<em>5</em>4<em>3</em>2<em>1/4</em>3<em>2</em>5<em>4</em>3*2 = 14</li></ul><hr><h2 id="软件成熟度模型-CMM-的五个等级">软件成熟度模型(CMM)的五个等级</h2><ol><li>初始级(Initial)<ul><li><strong>特点</strong>:在这一级别,软件过程基本上是无序和混乱的。项目的成功往往依赖于个人的技能和努力,而非系统性的过程。项目管理缺乏标准化和可重复性,工作常常处于救火状态,无法有效预防和解决问题。</li><li><strong>问题</strong>:由于没有明确的软件开发流程,项目的进度、质量和成本往往难以控制。这导致项目的成功率低下,客户满意度不高。</li></ul></li><li>可重复级(Repeatable)<ul><li><strong>特点</strong>:在这一级别,组织开始建立基本的项目管理过程,如需求管理、项目计划、跟踪和监控等。这些过程为项目的执行提供了必要的指导和规范,使得类似的项目可以重复之前的成功经验。</li><li><strong>进步</strong>:通过实施这些基本过程,组织能够更好地控制项目的进度和成本,提高软件的质量。同时,由于过程的可重复性,项目的成功率也得到了提升。</li></ul></li><li>已定义级(Defined)<ul><li><strong>特点</strong>:在这一级别,软件管理和工程两方面的过程都已经文档化、标准化,并整合到组织的标准软件过程中。所有项目都使用经过批准、剪裁的标准软件过程来开发和维护软件。</li><li><strong>优势</strong>:通过文档化和标准化过程,组织能够确保项目的一致性和可预测性。同时,这也为团队成员提供了清晰的指导,使得他们能够更好地理解和执行任务。</li></ul></li><li>已管理级(Managed)<ul><li><strong>特点</strong>:在这一级别,组织能够收集并分析软件过程和产品质量的详细度量数据。这使得组织能够在定量的范围内预测性能,并作出基于客观依据的决策。</li><li><strong>意义</strong>:通过收集和分析度量数据,组织可以深入了解其软件开发过程的优点和不足,从而制定针对性的改进措施。同时,这也为组织提供了持续监控和优化过程的能力。</li></ul></li><li>优化级(Optimizing)<ul><li><strong>特点</strong>:在这一级别,组织通过反馈和持续改进,不断优化其软件开发过程。组织能够利用新技术和先进思想来改进过程,从而提高软件质量和客户满意度。</li><li><strong>成果</strong>:通过持续优化过程,组织能够不断提高其软件开发能力,降低项目的风险和成本。同时,这也使得组织能够更好地满足客户的需求,提高市场竞争力。</li></ul></li></ol><hr><h2 id="七层网络模型">七层网络模型</h2><ol><li><code>物理层(Physical Layer)</code>:<div class="hide-block"><button type="button" class="hide-button" style="">查看 </button><div class="hide-content"><ul><li>功能:这一层处理物理介质和数据传输的基本物理特性,例如电压、电流、光信号等。</li><li>常用协议和设备:Ethernet、USB、光纤、双绞线、集线器(Hub)。</li></ul></div></div></li><li><code>数据链路层(Data Link Layer)</code>:<div class="hide-block"><button type="button" class="hide-button" style="">查看 </button><div class="hide-content"><ul><li>功能:负责数据的帧化、物理地址的解析、流量控制和错误检测和纠正。</li><li>常用协议和设备:Ethernet、Wi-Fi、MAC地址、交换机(Switch)、网桥(Bridge)。</li></ul></div></div></li><li><code>网络层(Network Layer)</code>:<div class="hide-block"><button type="button" class="hide-button" style="">查看 </button><div class="hide-content"><ul><li>功能:路由选择、数据包的寻址、跨不同网络的数据传输。</li><li>常用协议和设备:IP(IPv4、IPv6)、路由器(Router)、OSPF、BGP。</li></ul></div></div></li><li><code>传输层(Transport Layer)</code>:<div class="hide-block"><button type="button" class="hide-button" style="">查看 </button><div class="hide-content"><ul><li>功能:提供端到端的数据传输和可靠性,负责数据的分段和重新组装,错误检测和纠正。</li><li>常用协议:TCP、UDP。</li></ul></div></div></li><li><code>会话层(Session Layer)</code>:<div class="hide-block"><button type="button" class="hide-button" style="">查看 </button><div class="hide-content"><ul><li>功能:管理通信会话,建立、维护和终止连接。</li><li>常用软件:NetBIOS、RPC(Remote Procedure Call)。</li></ul></div></div></li><li><code>表示层(Presentation Layer)</code>:<div class="hide-block"><button type="button" class="hide-button" style="">查看 </button><div class="hide-content"><ul><li>功能:数据格式转换、数据加密、数据压缩、字符编码等,以确保不同系统之间的数据互通。</li><li>常用协议:SSL/TLS、ASCII、EBCDIC。</li></ul></div></div></li><li><code>应用层(Application Layer)</code>:<div class="hide-block"><button type="button" class="hide-button" style="">查看 </button><div class="hide-content"><ul><li>功能:为用户提供网络服务和应用,包括文件传输、电子邮件、网页浏览等。</li><li>常用协议:HTTP、FTP、SMTP、POP3、IMAP、DNS。</li></ul></div></div></li></ol><hr><h2 id="软件设计模型">软件设计模型</h2><ol><li><p>原型模型:</p><div class="hide-block"><button type="button" class="hide-button" style="">查看 </button><div class="hide-content"><p>基于这样一种客观事实:并非所有的需求在系统开发之前都能准确地说明和定义。采用了<code>动态定义需求的方法</code>。它适用于需求不明确的开发环境。</p></div></div></li><li><p>瀑布模型:</p><div class="hide-block"><button type="button" class="hide-button" style="">查看 </button><div class="hide-content"><p><code>严格遵循软件生命周期各阶段的固定顺序</code>,一个阶段完成再进入另一个阶段。其优点是:可以使过程比较规范化,有利于评审;缺点在于:过于理想,缺乏灵活性,容易产生需求偏差。所以瀑布模型的应用场合为:<code>需求明确的项目</code>、二次开发项目以及与原型法配合使用。</p></div></div></li><li><p>演化模型:</p><div class="hide-block"><button type="button" class="hide-button" style="">查看 </button><div class="hide-content"><p>它将软件系统的开发过程比作生物进化,通过多次迭代和演化来构建软件系统。演化模型的一个主要特点是它<code>允许在项目的不同阶段进行变更和扩展</code>,以适应新的需求和发现的问题。这个模型的主要思想是,软件系统不断演化,就像生物进化一样。</p></div></div></li><li><p>增量模型:</p><div class="hide-block"><button type="button" class="hide-button" style="">查看 </button><div class="hide-content"><ul><li>增量模型将项目划分为多个增量,每个增量都包含一个独立的部分功能。</li><li>每个增量都经历完整的开发周期,然后逐渐组合到一个完整的系统中。</li><li><code>适用于大型项目,可以更早地交付部分功能</code>。</li></ul></div></div></li><li><p>螺旋模型:</p><div class="hide-block"><button type="button" class="hide-button" style="">查看 </button><div class="hide-content"><p><code>结合了瀑布模型和演化模型的优点</code>,最主要的特点在于<code>加入了风险分析</code>。它是由制定计划、风险分析、实施工程、客户评估这一循环组成的,它最初从概念项目开始第一个螺旋。</p></div></div></li><li><p>喷泉模型:</p><div class="hide-block"><button type="button" class="hide-button" style="">查看 </button><div class="hide-content"><p>主要用于描述面向对象的开发过程,最核心的特点是迭代。所有的<code>开发活动没有明显的边界</code>,允许各种开发活动交叉进行。</p></div></div></li><li><p>V模型:</p><div class="hide-block"><button type="button" class="hide-button" style="">查看 </button><div class="hide-content"><p><code>强调开发过程中测试贯穿始终</code>;</p></div></div></li><li><p>UP:</p><div class="hide-block"><button type="button" class="hide-button" style="">查看 </button><div class="hide-content"><p>既是一个统一的软件开发过程,是一个通用过程框架,可以应付种类广泛的软件系统、不同的应用领域、不同的组织类型、不同的性能水平和不同的项目规模。UP是基于构件的,这意味着利用它开发的软件系统是由构件构成的,构件之间通过定义良好的接口相互联系。在准备软件系统所有蓝图的时候,UP使用的是统一建模语言UML。与其他软件过程相比,UP具有三个显著的特点:用例驱动、以基本架构为中心、迭代和增量。</p></div></div></li></ol><hr><h2 id="设计模式">设计模式</h2><ol><li>创建型模式(Creational Patterns):<br>这些模式关注对象的创建机制,以确保在系统中适当地创建和配置对象。<ul><li>单例模式(Singleton Pattern):确保一个类只有一个实例,并提供全局访问点。</li><li>工厂方法模式(Factory Method Pattern):定义一个创建对象的接口,但让子类决定具体实例化哪个类。</li><li>抽象工厂模式(Abstract Factory Pattern):提供一个接口,用于创建一系列相关或依赖对象的家族,而不需要指定具体类。</li><li>建造者模式(Builder Pattern):<span class="hide-inline"><button type="button" class="hide-button" style="background-color: ;">查看 </button><span class="hide-content">将一个复杂对象的构建与其表示分离,使相同的构建过程可以创建不同的表示</span></span></li><li>原型模式(Prototype Pattern):<span class="hide-inline"><button type="button" class="hide-button" style="background-color: ;">查看 </button><span class="hide-content">通过复制现有对象创建新对象,而不是创建新的实例</span></span></li></ul></li><li>结构型模式(Structural Patterns):<br>这些模式关注对象之间的组合,以形成更大的结构。<ul><li><code>适配器模式</code>(Adapter Pattern):<span class="hide-inline"><button type="button" class="hide-button" style="background-color: ;">查看 </button><span class="hide-content">将一个接口转换成客户端希望的另一个接口,以便客户端可以调用不同接口的对象</span></span></li><li><code>装饰器模式</code>(Decorator Pattern):<span class="hide-inline"><button type="button" class="hide-button" style="background-color: ;">查看 </button><span class="hide-content">动态地为对象添加额外的职责,而不改变其接口</span></span></li><li>桥接模式(Bridge Pattern):<span class="hide-inline"><button type="button" class="hide-button" style="background-color: ;">查看 </button><span class="hide-content">将抽象部分与其实现部分分离,以便它们可以独立变化</span></span></li><li>组合模式(Composite Pattern):将对象组合成树结构以表示部分-整体层次结构。</li><li>外观模式(Facade Pattern):为子系统提供一个一致的接口,以简化与子系统的交互。</li><li>享元模式(Flyweight Pattern):<span class="hide-inline"><button type="button" class="hide-button" style="background-color: ;">查看 </button><span class="hide-content">共享细粒度对象,以减少内存和提高性能</span></span></li><li>代理模式(Proxy Pattern):为其他对象提供一个代理以控制对这个对象的访问。</li></ul></li><li>行为型模式(Behavioral Patterns):<br>这些模式关注对象之间的职责分配,以及如何在对象之间进行通信。<ul><li><code>责任链模式</code>(Chain of Responsibility Pattern):<span class="hide-inline"><button type="button" class="hide-button" style="background-color: ;">查看 </button><span class="hide-content">通过链式传递请求,解决发送者和接收者之间的耦合</span></span></li><li>命令模式(Command Pattern):将请求封装为对象,以使调用操作的对象参数化、排队、记录和撤销操作。</li><li>解释器模式(Interpreter Pattern):为语言创建解释器,用于解释特定的语法。</li><li><code>迭代器模式</code>(Iterator Pattern):<span class="hide-inline"><button type="button" class="hide-button" style="background-color: ;">查看 </button><span class="hide-content">提供一种方法依次访问聚合对象的元素,而不暴露其内部表示</span></span></li><li><code>中介者模式</code>(Mediator Pattern):<span class="hide-inline"><button type="button" class="hide-button" style="background-color: ;">查看 </button><span class="hide-content">定义一个封装一组对象交互的对象,促进松散耦合</span></span></li><li>备忘录模式(Memento Pattern):在不破坏封装的前提下,捕获和恢复对象的内部状态。</li><li><code>观察者模式</code>(Observer Pattern):<span class="hide-inline"><button type="button" class="hide-button" style="background-color: ;">查看 </button><span class="hide-content">定义对象之间的一对多依赖关系,使一个对象状态改变时,所有依赖对象都得到通知</span></span></li><li>状态模式(State Pattern):允许对象在其内部状态改变时改变其行为。</li><li>策略模式(Strategy Pattern):<span class="hide-inline"><button type="button" class="hide-button" style="background-color: ;">查看 </button><span class="hide-content">定义一系列算法,将其封装成独立的策略对象,并在运行时选择策略</span></span></li><li>模板方法模式(Template Method Pattern):定义算法的骨架,但将一些步骤的实现延迟到子类。</li><li><code>访问者模式</code>(Visitor Pattern):<span class="hide-inline"><button type="button" class="hide-button" style="background-color: ;">查看 </button><span class="hide-content">在不改变对象结构的前提下,定义作用于对象结构中的元素的新操作</span></span></li></ul></li></ol><hr><h2 id="算法策略">算法策略</h2><ol><li><code>分治法(Divide and Conquer)</code>:<ul><li>分治法是一种将问题划分为更小的子问题,然后递归地解决这些子问题,最后将子问题的解合并以得到原问题的解的算法。</li><li>归并排序、快速排序、整数乘法、棋盘覆盖、循环赛日程安排、斐波那契数列</li></ul></li><li><code>动态规划法(Dynamic Programming)</code>:<ul><li>动态规划法是一种通过将问题分解为更小的子问题并存储子问题的解来解决复杂问题的方法。</li><li>背包问题、最长公共子序列、矩阵链乘法、最短路径问题</li></ul></li><li><code>贪心法(Greedy Algorithm)</code>:<ul><li>贪心法是一种每次选择局部最优解的策略,以期望最终获得全局最优解。</li><li>活动选择问题、哈夫曼编码、最小生成树(Kruskal和Prim算法)、单源最短路径(Dijkstra算法)</li></ul></li><li><code>回溯法(Backtracking)</code>:<ul><li>回溯法是一种通过尝试不同的选择并在不满足条件时回溯到先前的状态来解决问题的方法。</li><li>N皇后问题、0-1背包问题、图着色问题、旅行商问题</li></ul></li><li><code>分支限界法(Branch and Bound)</code>:<ul><li>分支限界法是一种通过分支问题并定义上下界来限制搜索空间的方法,以找到最优解。</li><li>0-1背包问题、旅行商问题、作业调度问题、资源分配问题</li></ul></li></ol><hr><h2 id="UML常用图">UML常用图</h2><ul><li>类图:一组对象、接口、写作和他们之间的关系</li><li>对象图:一组对象以及他们之间的关系</li><li>用例图:用力、参与者以及他们之间的关系</li><li>序列图:场景的图像化表示,以时间顺序组织的对象间的交互活动</li><li>通讯图:强调手法消息的对象之间的组织结构</li><li>状态图:展现了一个状态机,由状态、转换、事件和活动组成</li><li>活动图:专注于系统的动态视图,一个活动到另一个活动的流程</li></ul><hr><h2 id="类图">类图</h2><p><strong>泛化(继承):</strong></p><ul><li>是一种继承关系,表示一般与特殊的关系,它指定了子类如何特化父类的所有特征和行为。例如:老虎是动物的一种,即有老虎的特性也有动物的共性。<img src="https://i.miji.bid/2024/02/28/08fd9dce698985dc4e2716aadef84983.png" style="zoom: 33%;float:right" /></li></ul><p><strong>实现:</strong></p><ul><li>在这里插入图片描述是一种类与接口的关系,表示类是接口所有特征和行为的实现.<img src="https://i.miji.bid/2024/02/28/517298e5d8d5a30e1d35515afa56ff8b.png" style="zoom: 33%;float:right" /></li></ul><p><strong>依赖:</strong></p><ul><li>一个类依赖于另一个类的定义。一般而言,依赖关系在Java语言中体现为成员变量、局域变量、方法的形参、方法返回值,或者对静态方法的调用<img src="https://i.miji.bid/2024/02/28/d8b19c84106dd7ce79fa9e0a9e26153e.png" style="zoom: 33%;float:right" /></li></ul><p><strong>关联:</strong></p><ul><li>是一种拥有的关系,它使一个类知道另一个类的属性和方法;如:老师与学生<img src="https://i.miji.bid/2024/02/28/9baa02dd098632812b033011b9fadf2f.png" style="zoom: 33%;float:right" /></li></ul><p><strong>聚合:</strong></p><ul><li>聚合是一种较弱的关联关系,表示一个对象包含另一个对象,<code>但包含的对象的生命周期不一定依赖于包含对象。</code></li><li>例如:<code>一个大学(整体)包含多个学生(部分)</code>。学生可以毕业或转学,但他们的生命周期不仅仅取决于大学的存在。<img src="https://i.miji.bid/2024/02/28/25c04555be15e82377ce04e838e805f9.png" style="zoom: 33%;float:right" /></li></ul><p><strong>组合:</strong></p><ul><li>组合是一种较强的关联关系,表示一个对象包含另一个对象,<code>且包含的对象的生命周期依赖于包含对象</code>。如果包含对象被销毁,那么它所包含的对象也会被销毁。</li><li>例如:<code>一辆汽车(整体)包括引擎、轮胎、座位等部分</code>。如果汽车被销毁,那么引擎、轮胎、座位等部分也将被销毁<img src="https://i.miji.bid/2024/02/28/3195e525595504319cb224444c18bb78.png" style="zoom: 33%;float:right" /></li></ul><hr><h2 id="用例图">用例图</h2><p>1.包含关系(include):</p><ul><li>用例图中的包含关系表示一个用例包含了另一个用例,即包含用例需要在执行过程中引入被包含用例的行为。</li><li>通常用带有虚线箭头的箭头表示,箭头从包含用例指向被包含用例。箭头的标签描述了包含用例的条件。</li><li>这种关系表示被包含用例的执行是可选的,它会在包含用例的执行中根据条件来引入。</li></ul><p>2.扩展关系(extend):</p><ul><li>扩展关系表示一个用例可以在一定条件下扩展另一个用例的行为,即扩展用例提供了在基础用例执行时可能发生的额外行为。</li><li>通常用带有虚线箭头的箭头表示,箭头从扩展用例指向被扩展用例。箭头的标签描述了扩展用例的条件。</li><li>这种关系表示扩展用例的执行是可选的,它只有在满足条件时才会被触发。</li></ul><p>3.泛化关系(generalize):</p><ul><li>泛化关系表示用例之间的继承关系,其中一个用例(子用例)继承了另一个用例(父用例)的行为。</li><li>用实线箭头表示,箭头从子用例指向父用例。</li><li>子用例继承了父用例的特征和行为,通常用于表示用例的层次结构。</li></ul><hr><h2 id="内聚">内聚</h2><p><code>时间聚合</code>:<span class="hide-inline"><button type="button" class="hide-button" style="background-color: ;">查看 </button><span class="hide-content">模块内部的各个组成部分所包含的处理动作必须在同一时间内执行</span></span></p><p><code>过程聚合</code>:<span class="hide-inline"><button type="button" class="hide-button" style="background-color: ;">查看 </button><span class="hide-content">模块内部各个组成部分所要完成的动作虽然没有关系,但必须按特定的次序执行</span></span></p><p><code>通信聚合</code>:<span class="hide-inline"><button type="button" class="hide-button" style="background-color: ;">查看 </button><span class="hide-content">模块的各个组成部分所完成的动作都使用了同一个数据或产生同一输出数据</span></span></p><p><code>顺序聚合</code>:<span class="hide-inline"><button type="button" class="hide-button" style="background-color: ;">查看 </button><span class="hide-content">模块内部的各个部分,前一部分处理动作的最后输出是后一部分处理动作的输入</span></span></p><p><code>功能聚合</code>:<span class="hide-inline"><button type="button" class="hide-button" style="background-color: ;">查看 </button><span class="hide-content">模块内部各个部分全部属于一个整体,并执行同一功能,且各部分对实现该功能都必不可少</span></span></p><p><code>非直接耦合</code>:<span class="hide-inline"><button type="button" class="hide-button" style="background-color: ;">查看 </button><span class="hide-content">两个模块之间没有直接关系,它们的联系完全是通过主模块的控制和调用来实现的</span></span></p><hr><h2 id="耦合">耦合</h2><p><code>数据耦合</code>:<span class="hide-inline"><button type="button" class="hide-button" style="background-color: ;">查看 </button><span class="hide-content">两个模块彼此间通过数据参数交换信息</span></span></p><p><code>标记耦合</code>:<span class="hide-inline"><button type="button" class="hide-button" style="background-color: ;">查看 </button><span class="hide-content">一组模块通过参数表传递记录信息,这个记录是某一个数据结构的子结构,而不是简单变量</span></span></p><p><code>控制耦合</code>:<span class="hide-inline"><button type="button" class="hide-button" style="background-color: ;">查看 </button><span class="hide-content">两个模块彼此间传递的信息中有控制信息</span></span></p><p><code>外部耦合</code>:<span class="hide-inline"><button type="button" class="hide-button" style="background-color: ;">查看 </button><span class="hide-content">一组模块都访问同一全局简单变量而不是同一全局数据结构,而且不是通过参数表传递该全局变量的信息</span></span></p><p><code>公共耦合</code>:<span class="hide-inline"><button type="button" class="hide-button" style="background-color: ;">查看 </button><span class="hide-content">两个模块之间通过一个公共的数据区域传递信息</span></span></p><p><code>内容耦合</code>:<span class="hide-inline"><button type="button" class="hide-button" style="background-color: ;">查看 </button><span class="hide-content">一个模块需要涉及到另一个模块的内部信息</span></span></p><hr><h2 id="常用协议">常用协议</h2><p><strong>带T的除了TFTP,均为TCP 不带T的除了POP3,均为UDP</strong></p><ol><li>FTP:20数据端口/21控制端口,文件传输协议</li><li>HTTP:80端口,超文本传输协议,网页传输</li><li>DHCP:67端口,IP地址自动分配</li><li>SNMP:161端口,简单网络管理协议</li><li>DNS:53端口,域名解析协议,记录域名与IP的映射关系</li><li>TCP:可靠的传输层协议</li><li>UDP:不可靠的传输层协议</li><li>ICMP:因特网控制协议,PING命令来自该协议</li><li>IGMP:组播协议</li><li>ARP:地址解析协议,IP地址转换为MAC地址</li><li>PPP:PPP是一种数据链路层协议,通常用于在两个点之间建立直接连接,例如,个人计算机通过调制解调器拨号连接到互联网服务提供商(ISP)的服务器</li><li>PPPOE:以太网上的点对点协议,是将点对点协议(PPP)封装在以太网(Ethernet)框架中的一种网络隧道协议。</li><li>PPTP:即点对点隧道协议。该协议是在PPP协议的基础上开发的一种新的增强型安全协议,支持多协议虚拟专用网(VPN),可以通过密码验证协议(PAP)、可扩展认证协议(EAP)等方法增强安全性。</li></ol><hr><h2 id="邮件相关">邮件相关</h2><ol><li>SMTP(Simple Mail Transfer Protocol):SMTP是用于发送电子邮件的标准协议。它定义了如何将电子邮件从发件人的邮件服务器传输到接收人的邮件服务器。SMTP通常使用TCP端口25进行通信。</li><li>POP3(Post Office Protocol, Version 3):POP3是用于接收电子邮件的协议。它允许电子邮件客户端从邮件服务器上下载电子邮件,并通常使用TCP端口110。POP3将电子邮件下载到本地设备,并通常将电子邮件从服务器上删除。</li><li>IMAP(Internet Message Access Protocol):IMAP也是用于接收电子邮件的协议,<code>但与POP3不同</code>,它允许电子邮件客户端在邮件服务器上管理电子邮件,而不是直接下载到本地设备。IMAP通常使用TCP端口143。</li><li>SMTPS(SMTP Secure):SMTPS是SMTP的安全版本,使用TLS/SSL来加密SMTP通信,以保护电子邮件的隐私和安全。通常使用TCP端口465或587。</li><li>POP3S和IMAPS:这是安全的POP3和IMAP协议,它们使用TLS/SSL来加密电子邮件客户端与邮件服务器之间的通信,以确保数据的机密性。</li><li>MIME(Multipurpose Internet Mail Extensions):MIME是一种标准,用于在电子邮件中传输多媒体内容、附件和非文本数据。它允许电子邮件包含图像、音频、视频和其他多媒体元素</li></ol><hr><h2 id="对称加密算法:"><strong>对称加密算法</strong>:</h2><ol><li><code>AES (Advanced Encryption Standard)</code>:这是目前广泛使用的对称加密算法之一,具有高度的安全性和性能。</li><li><code>DES (Data Encryption Standard)</code>:虽然已经被认为不安全,但仍然在一些旧系统中使用。</li><li><code>3DES (Triple Data Encryption Standard)</code>:对DES的改进版本,使用多轮加密操作来提高安全性。</li><li><code>RC4 (Rivest Cipher 4)</code>:虽然在过去广泛使用,但由于安全漏洞而不再建议使用。</li></ol><h2 id="非对称加密算法:"><strong>非对称加密算法</strong>:</h2><ol><li><code>RSA (Rivest-Shamir-Adleman)</code>:一种常用的非对称加密算法,广泛用于数字签名和安全通信,<code>https证书常用加密算法</code>。</li><li><code>DSA (Digital Signature Algorithm)</code>:主要用于数字签名,常与其他加密算法一起使用。</li><li><code>ECC (Elliptic Curve Cryptography)</code>:一种使用椭圆曲线密码学的非对称加密方法,具有高度的安全性和效率。</li></ol><h2 id="哈希函数:"><strong>哈希函数</strong>:</h2><ul><li><code>SHA-256和SHA-3</code>:SHA-256是一种安全散列算法,用于生成固定长度的哈希值,通常用于数据完整性检查和密码存储。</li><li><code>MD5</code>:尽管已经不再安全,但在某些应用中仍在使用。</li></ul>]]></content>
<categories>
<category> 软考笔记 </category>
</categories>
<tags>
<tag> 软件设计师 </tag>
</tags>
</entry>
</search>