-
-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathatom.xml
905 lines (690 loc) · 439 KB
/
atom.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
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
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title>攻城狮杰森</title>
<subtitle>董哲朋的博客</subtitle>
<link href="https://pdpeng.github.io/atom.xml" rel="self"/>
<link href="https://pdpeng.github.io/"/>
<updated>2025-03-10T15:12:25.995Z</updated>
<id>https://pdpeng.github.io/</id>
<author>
<name>董哲朋</name>
</author>
<generator uri="https://hexo.io/">Hexo</generator>
<entry>
<title>公众号接入 chatGPT 教程(附源码)</title>
<link href="https://pdpeng.github.io/2023/02/16/chatgpt-for-wechat/"/>
<id>https://pdpeng.github.io/2023/02/16/chatgpt-for-wechat/</id>
<published>2023-02-16T09:51:32.000Z</published>
<updated>2025-03-10T15:12:25.995Z</updated>
<content type="html"><![CDATA[<blockquote><p>声明:本文仅供技术交流使用,阅读本文需具备一定的开发能力</p></blockquote><h1 id="前置准备"><a href="#前置准备" class="headerlink" title="前置准备"></a>前置准备</h1><ol><li>一个域名</li><li>一台服务器</li><li>一个公众号</li></ol><h1 id="域名配置"><a href="#域名配置" class="headerlink" title="域名配置"></a>域名配置</h1><p>在你的域名服务商新建二级域名并绑定服务器主机IP</p><h1 id="服务器配置"><a href="#服务器配置" class="headerlink" title="服务器配置"></a>服务器配置</h1><p>上传下面的python文件到你的服务器,并修改代码段中相应位置代码(token、api-key、port)</p><span id="more"></span><figure class="highlight python"><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><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> time</span><br><span class="line"><span class="keyword">from</span> flask <span class="keyword">import</span> Flask,make_response,request</span><br><span class="line"><span class="keyword">import</span> openai</span><br><span class="line"><span class="keyword">from</span> flask <span class="keyword">import</span> Flask, request</span><br><span class="line"><span class="keyword">from</span> flask_caching <span class="keyword">import</span> Cache</span><br><span class="line"><span class="keyword">import</span> xml.etree.cElementTree <span class="keyword">as</span> ET</span><br><span class="line"><span class="keyword">import</span> hashlib</span><br><span class="line"><span class="keyword">import</span> requests</span><br><span class="line"><span class="keyword">import</span> re</span><br><span class="line"><span class="keyword">import</span> os</span><br><span class="line"></span><br><span class="line">cnt = <span class="number">0</span></span><br><span class="line">my_wx_token = <span class="string">""</span> <span class="comment"># 自定义字母和数字组合即可,后续需要填入公众号后台</span></span><br><span class="line">my_gpt_key = <span class="string">""</span> <span class="comment"># 这里填写你在OpenAI后台创建的API-KEY</span></span><br><span class="line">my_switch_chatgpt = <span class="literal">True</span></span><br><span class="line"></span><br><span class="line">app = Flask(__name__)</span><br><span class="line">env_dist = os.environ</span><br><span class="line">cache = Cache(app, config={<span class="string">'CACHE_TYPE'</span>: <span class="string">'simple'</span>, <span class="string">"CACHE_DEFAULT_TIMEOUT"</span>: <span class="number">30</span>})</span><br><span class="line"></span><br><span class="line"><span class="meta">@app.route(<span class="params"><span class="string">'/'</span>,methods=[<span class="string">'GET'</span>,<span class="string">'POST'</span>]</span>)</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">wechat</span>():</span><br><span class="line"> <span class="keyword">if</span> request.method == <span class="string">'GET'</span>:</span><br><span class="line"> signature = request.args.get(<span class="string">"signature"</span>, <span class="string">""</span>)</span><br><span class="line"></span><br><span class="line"> timestamp= request.args.get(<span class="string">"timestamp"</span>, <span class="string">""</span>)</span><br><span class="line"></span><br><span class="line"> nonce= request.args.get(<span class="string">"nonce"</span>, <span class="string">""</span>)</span><br><span class="line"></span><br><span class="line"> echostr= request.args.get(<span class="string">"echostr"</span>, <span class="string">""</span>)</span><br><span class="line"> <span class="built_in">print</span>(signature, timestamp, nonce, echostr)</span><br><span class="line"></span><br><span class="line"> token=my_wx_token</span><br><span class="line"></span><br><span class="line"> data =[token, timestamp, nonce]</span><br><span class="line"></span><br><span class="line"> data.sort()</span><br><span class="line"></span><br><span class="line"> temp = <span class="string">''</span>.join(data)</span><br><span class="line"></span><br><span class="line"> sha1 = hashlib.sha1(temp.encode(<span class="string">'utf-8'</span>))</span><br><span class="line"></span><br><span class="line"> hashcode=sha1.hexdigest()</span><br><span class="line"> <span class="built_in">print</span>(hashcode)</span><br><span class="line"></span><br><span class="line"> <span class="keyword">if</span> hashcode == signature:</span><br><span class="line"> <span class="built_in">print</span>(<span class="string">"wechat commit check OK"</span>)</span><br><span class="line"> <span class="keyword">return</span> echostr</span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> <span class="built_in">print</span>(<span class="string">"GET error input msg"</span>)</span><br><span class="line"> <span class="keyword">return</span> <span class="string">"error-return\r\n"</span></span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> xmlData = ET.fromstring(request.stream.read())</span><br><span class="line"> msg_type = xmlData.find(<span class="string">'MsgType'</span>).text</span><br><span class="line"> <span class="keyword">if</span> msg_type == <span class="string">'text'</span>:</span><br><span class="line"> ToUserName = xmlData.find(<span class="string">'ToUserName'</span>).text</span><br><span class="line"> FromUserName = xmlData.find(<span class="string">'FromUserName'</span>).text</span><br><span class="line"> CreateTime = xmlData.find(<span class="string">'CreateTime'</span>).text</span><br><span class="line"> </span><br><span class="line"> <span class="built_in">print</span>(ToUserName)</span><br><span class="line"> <span class="built_in">print</span>(FromUserName)</span><br><span class="line"> <span class="built_in">print</span>(CreateTime)</span><br><span class="line"> </span><br><span class="line"> <span class="keyword">global</span> cnt</span><br><span class="line"> cnt += <span class="number">1</span></span><br><span class="line"> <span class="built_in">print</span>(<span class="string">'-------> '</span> + <span class="built_in">str</span>(cnt))</span><br><span class="line"> </span><br><span class="line"> <span class="keyword">return</span> generate_response_xml(FromUserName, ToUserName, xmlData.find(<span class="string">'Content'</span>).text)</span><br><span class="line"> </span><br><span class="line"><span class="keyword">def</span> <span class="title function_">text_reply</span>(<span class="params">FromUserName, ToUserName, output_content</span>):</span><br><span class="line"> reply = <span class="string">'''</span></span><br><span class="line"><span class="string"> <xml></span></span><br><span class="line"><span class="string"> <ToUserName><![CDATA[%s]]></ToUserName></span></span><br><span class="line"><span class="string"> <FromUserName><![CDATA[%s]]></FromUserName></span></span><br><span class="line"><span class="string"> <CreateTime>%s</CreateTime></span></span><br><span class="line"><span class="string"> <MsgType><![CDATA[text]]></MsgType></span></span><br><span class="line"><span class="string"> <Content><![CDATA[%s]]></Content></span></span><br><span class="line"><span class="string"> </xml></span></span><br><span class="line"><span class="string"> '''</span></span><br><span class="line"> response = make_response(reply % (FromUserName, ToUserName, <span class="built_in">str</span>(<span class="built_in">int</span>(time.time())), output_content))</span><br><span class="line"> response.content_type = <span class="string">'application/xml'</span></span><br><span class="line"> <span class="keyword">return</span> response</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">generate_response_xml</span>(<span class="params">FromUserName, ToUserName, input_content</span>):</span><br><span class="line"> output_content = generate_response(input_content)</span><br><span class="line"> <span class="keyword">return</span> text_reply(FromUserName, ToUserName, output_content)</span><br><span class="line"></span><br><span class="line">outofsevice_txt = <span class="string">"抱歉,<a href=\"https://mp.weixin.qq.com/s/0LN37YiERJgMyvIDpzRcAQ\">攻城狮杰森的ChatGPT服务助手</a>正在维护中,暂时无法预估维护持续时间,请明天再来尝试吧。"</span></span><br><span class="line"></span><br><span class="line"><span class="meta">@cache.memoize(<span class="params">timeout=<span class="number">60</span></span>)</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">generate_response</span>(<span class="params">prompt</span>):</span><br><span class="line"> </span><br><span class="line"> <span class="keyword">if</span> <span class="keyword">not</span> my_switch_chatgpt:</span><br><span class="line"> <span class="keyword">return</span> outofsevice_txt</span><br><span class="line"> </span><br><span class="line"> openai.api_key = my_gpt_key</span><br><span class="line"> </span><br><span class="line"> response = openai.Completion.create(</span><br><span class="line"> model=<span class="string">"text-davinci-003"</span>,</span><br><span class="line"> prompt=prompt,</span><br><span class="line"> temperature=<span class="number">0</span>,</span><br><span class="line"> max_tokens=<span class="number">1024</span>,</span><br><span class="line"> top_p=<span class="number">1</span>,</span><br><span class="line"> frequency_penalty=<span class="number">0.0</span>,</span><br><span class="line"> presence_penalty=<span class="number">0.0</span>,</span><br><span class="line"> )</span><br><span class="line"> </span><br><span class="line"> message = response.choices[<span class="number">0</span>].text</span><br><span class="line"> <span class="built_in">print</span>(message)</span><br><span class="line"> </span><br><span class="line"> ans = message.strip()</span><br><span class="line"> <span class="keyword">return</span> ans</span><br><span class="line"> </span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">'__main__'</span>:</span><br><span class="line"> app.run(host=<span class="string">'0.0.0.0'</span>, port=xxxx, debug=<span class="literal">True</span>)<span class="comment">#开放xxxx端口</span></span><br><span class="line"></span><br></pre></td></tr></table></figure><p>使用<strong>宝塔</strong>是比较快捷的配置方式,安装宝塔面板后,进入<strong>软件商店</strong>,安装下面两个插件</p><p><img src="https://img-blog.csdnimg.cn/f2afb78b514c433089ea7eca423c93a1.png"></p><p>打开 <strong>python 项目管理器</strong> ,简单配置下我们要启动的项目</p><p><img src="https://img-blog.csdnimg.cn/45312fd500064250acdcd551b10811d5.png"></p><p>启动后映射项目域名,顶级域和二级域都可以,比如我这里填入的是 <code>chatgpt.coder-jason.cn</code> </p><p><img src="https://img-blog.csdnimg.cn/aef70f2d35f74717a0c8ebcca5ecaff1.png"></p><h1 id="公众号配置"><a href="#公众号配置" class="headerlink" title="公众号配置"></a>公众号配置</h1><p>进入公众号后台,找到<strong>设置与开发</strong>,进入<strong>基本配置</strong>,由于我这里已经配置好了,这里仅演示下怎么添加启用</p><p><img src="https://img-blog.csdnimg.cn/584e6501e75344feb6f1d59b15dd280b.png"></p><p>点击<strong>添加配置</strong></p><p><img src="https://img-blog.csdnimg.cn/53196088a4ec47caa23c0884618b011f.png"></p><p>token 值就是在上述代码段中填入的值,自定义字母和数字组合即可</p><p>点击提交后,如果服务器中的项目启动无误,则会提示 <strong>token校验成功</strong></p><p><img src="https://img-blog.csdnimg.cn/28eeabde89f2455996d74124a0940b7e.png"></p><p>接下来就可以回到公众号和 chatGPT 愉快的交流啦~,欢迎来公粽号 <strong>攻城狮杰森</strong> 体验</p><p><img src="https://img-blog.csdnimg.cn/ef7646192602477a82e129abf7d888c8.jpeg"></p><p>如果你对 chatGPT 感兴趣或配置过程中遇到任何问题,欢迎与我取得联系,vx:jasoni996</p>]]></content>
<summary type="html"><blockquote>
<p>声明:本文仅供技术交流使用,阅读本文需具备一定的开发能力</p>
</blockquote>
<h1 id="前置准备"><a href="#前置准备" class="headerlink" title="前置准备"></a>前置准备</h1><ol>
<li>一个域名</li>
<li>一台服务器</li>
<li>一个公众号</li>
</ol>
<h1 id="域名配置"><a href="#域名配置" class="headerlink" title="域名配置"></a>域名配置</h1><p>在你的域名服务商新建二级域名并绑定服务器主机IP</p>
<h1 id="服务器配置"><a href="#服务器配置" class="headerlink" title="服务器配置"></a>服务器配置</h1><p>上传下面的python文件到你的服务器,并修改代码段中相应位置代码(token、api-key、port)</p></summary>
<category term="程序设计" scheme="https://pdpeng.github.io/categories/%E7%A8%8B%E5%BA%8F%E8%AE%BE%E8%AE%A1/"/>
<category term="Python" scheme="https://pdpeng.github.io/tags/Python/"/>
</entry>
<entry>
<title>恭喜,成功入坑 GitHub 。。。</title>
<link href="https://pdpeng.github.io/2022/07/08/github-connection-refuse/"/>
<id>https://pdpeng.github.io/2022/07/08/github-connection-refuse/</id>
<published>2022-07-07T21:30:00.000Z</published>
<updated>2025-03-10T15:12:25.996Z</updated>
<content type="html"><![CDATA[<p>大家好,我是杰森。<code>GitHub</code> 对大家来说一定不陌生,无论是学习还是<code>交</code>(爬)<code>朋</code>(项)<code>友</code>(目)。但是今天,我好像和它失联了……</p><p><img src="https://img-blog.csdnimg.cn/f57f96bfc3154e3da61c2113adb3358d.png"></p><p>当我像往常一样<code>clone</code>项目时,却得到了这样的报错</p><figure class="highlight bash"><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">$ git <span class="built_in">clone</span> [email protected]:appletdevelop/full-stack.git</span><br><span class="line">Cloning into ‘full-stack’...</span><br><span class="line">ssh: connect to host github.com port 22: Connection refused</span><br><span class="line">fatal: Could not <span class="built_in">read</span> from remote repository.</span><br><span class="line"></span><br><span class="line">Please make sure you have the correct access rights and the repository exists.</span><br></pre></td></tr></table></figure><p>什么都不能阻止打工人搬砖,必须要解决。经过一番排查,终于找到了问题的根源。分享两种解决方案,大家注意避坑。</p><h3 id="方案一:配置-DNS"><a href="#方案一:配置-DNS" class="headerlink" title="方案一:配置 DNS"></a>方案一:配置 DNS</h3><p>因为错误信息显示 <code>Connection refused</code> ,所以我们需要去看看建立连接时发生了什么,为什么会出错。查看日志,果然发现端倪</p><figure class="highlight bash"><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">$ ssh -vT [email protected]</span><br><span class="line">OpenSSH_9.0p1, OpenSSL 1.1.1o 5 July 2022</span><br><span class="line">debug1: Reading configuration data /c/Users/jason/.ssh/config</span><br><span class="line">debug1: Reading configuration data /etc/ssh/ssh_config</span><br><span class="line">debug1: Connecting to github.com [::1] port 22.</span><br><span class="line">debug1: connect to address ::1 port 22: Connection refused</span><br><span class="line">debug1: Connecting to github.com [127.0.0.1] port 22.</span><br><span class="line">debug1: connect to address 127.0.0.1 port 22: Connection refused</span><br><span class="line">ssh: connect to host github.com port 22: Connection refused</span><br></pre></td></tr></table></figure><p>日志显示,<code>IPv6</code> 和 <code>IPv4</code> 的 <code>localhost</code> 地址分别为 <code>::1</code> 和 <code>127.0.0.1</code>,这意味着我们在连接 <code>github</code> 时,其域名将会被解析为 <code>localhost</code> 地址,当然也就无法连接。</p><p>打开<span class="exturl" data-url="aHR0cHM6Ly9pcGFkZHJlc3MuY29tL3dlYnNpdGUvZ2l0aHViLmNvbQ==" title="IP 查询网站">查询网站<i class="fa fa-external-link-alt"></i></span>,找到 <code>github.com</code> 的 <code>IP</code> 地址</p><p><img src="https://img-blog.csdnimg.cn/1a7f4301a95e431198b9fc55211f38df.png" alt="真实 IP 地址"></p><p><code>Windows</code> 下,打开本机 <code>hosts</code> 文件</p><blockquote><p>C:\Windows\System32\drivers\etc</p></blockquote><p>添加域名映射,并在 <code>cmd</code> 窗口刷新 <code>DNS</code> 配置</p><figure class="highlight bash"><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">140.82.112.4 github.com</span><br><span class="line"><span class="comment"># Refreshing DNS configurations</span></span><br><span class="line">$ ipconfig /flushdns</span><br></pre></td></tr></table></figure><p>重新拉取,成功。</p><h3 id="方案二:修改端口号"><a href="#方案二:修改端口号" class="headerlink" title="方案二:修改端口号"></a>方案二:修改端口号</h3><p>从上面的<span class="exturl" data-url="aHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvMTU1ODk2ODIvc3NoLWNvbm5lY3QtdG8taG9zdC1naXRodWItY29tLXBvcnQtMjItY29ubmVjdGlvbi10aW1lZC1vdXQ=" title="22 端口拒绝访问">报错信息<i class="fa fa-external-link-alt"></i></span>中可以发现,重点在这一句</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ssh: connect to host github.com port 22: Connection refused</span><br></pre></td></tr></table></figure><p><code>ssh</code> 连接 <code>GitHub</code> 的 <code>22</code> 号端口被拒绝。但是 <code>ping</code> 一下 <code>github.com</code> 能通,浏览器访问也没有问题,那有可能是该端口被防火墙蔽掉了。既然 <code>22</code> 端口拒绝访问,我们不妨尝试使用 <code>443</code> 端口进行连接。</p><p>使用 <code>vim</code> 指令编辑 <code>ssh</code> 配置文件,添加以下端口信息</p><figure class="highlight bash"><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">$ vim ~/.ssh/config</span><br><span class="line"><span class="comment"># Add the following configuration information</span></span><br><span class="line">Host github.com</span><br><span class="line"> Hostname ssh.github.com</span><br><span class="line"> Port 443</span><br></pre></td></tr></table></figure><p>测试访问是否成功,通常不出意外的话意外就来了……</p><figure class="highlight bash"><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">$ ssh -T [email protected]</span><br><span class="line">The authenticity of host ‘[ssh.github.com]:443([unknown ip address]:443)’ can’t be established.</span><br><span class="line">xxx key fingerprint is xxx:xxx.</span><br><span class="line">This host key is known by the following other names/addresses:</span><br><span class="line"> <span class="comment"># Delete the RSA information in line 8</span></span><br><span class="line"> ~/.ssh/known_hosts:8: github.com</span><br><span class="line">Host key verification failed.</span><br></pre></td></tr></table></figure><p>这与 <code>ssh</code> 的运行机制有关,<code>ssh</code> 会将本机访问过的计算机的 <code>public key</code> 记录在 <code>~/.ssh/known_hosts</code> 下。当下次访问相同计算机时,若公钥不同则会发出警告,避免受到攻击。这里只需要找到 <code>known_hosts</code> 文件中对应 <code>ip</code> 的 <code>RSA</code> 并删除便可解决。</p><p>再次测试,看到以下信息则表示访问成功</p><figure class="highlight bash"><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">$ ssh -T [email protected]</span><br><span class="line">Hi xxx! You’ve successfully authenticated, but GitHub does not provide shell access.</span><br></pre></td></tr></table></figure><p>这样访问 <code>GitHub</code> 时,<code>ssh</code> 就会连接 <code>443</code> 端口,不会报错。</p><p><img src="https://img-blog.csdnimg.cn/ddf31df46a6247f5b36316ec6dfe670d.png" alt="拉取正常"></p><h3 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h3><p>总结下本次踩坑的原因,主要有两点:</p><ul><li>使用了科学上网小工具;</li><li><span class="exturl" data-url="aHR0cDovL3d3dy5kamJoLm5ldC93ZWJkZXYvd2ViL0FjYWRlbWljaWFuQ29sdW1uQWN0aW9uLmRvP3A9Z2V0WXN6bCZpZD04YTgxODI1NjVmZDhiNmI5MDE2MWM3MTY1ODZiMDEzMw==" title="网络劫持原理及影响">运营商劫持<i class="fa fa-external-link-alt"></i></span> 了 <code>DNS</code> 解析;</li></ul><p>总之:“网上冲浪也要注意暗礁,低头走路也要抬头看路”,以上就是本期分享啦,希望可以帮到您!</p>]]></content>
<summary type="html"><p>大家好,我是杰森。<code>GitHub</code> 对大家来说一定不陌生,无论是学习还是<code>交</code>(爬)<code>朋</code>(项)<code>友</code>(目)。但是今天,我好像和它失联了……</p>
<p><img src="https</summary>
<category term="计算机网络" scheme="https://pdpeng.github.io/categories/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/"/>
<category term="DNS" scheme="https://pdpeng.github.io/tags/DNS/"/>
</entry>
<entry>
<title>什么?你居然不会微信分身</title>
<link href="https://pdpeng.github.io/2022/06/20/wechat-rolled/"/>
<id>https://pdpeng.github.io/2022/06/20/wechat-rolled/</id>
<published>2022-06-20T09:26:00.000Z</published>
<updated>2025-03-10T15:12:26.000Z</updated>
<content type="html"><![CDATA[<blockquote><p>👲👲<font color=#a2a837 size=3>作者主页</font>:🔗<span class="exturl" data-url="aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L20wXzUxMjY5OTYx">杰森的博客<i class="fa fa-external-link-alt"></i></span><br>📒📒<font color=#20b9cd size=3>本文摘要</font>:<strong>微信分身(多开)教程</strong><br>💖💖如果本文帮助到你的话,还请各位小伙伴👍点赞➕收藏⭐➕评论💭支持杰森呀✌️</p></blockquote><p><img src="https://img-blog.csdnimg.cn/2ba19d080eb940e99ced56cc6a8ce6e7.png#pic_center"></p><hr><blockquote><p>系统环境:Windows 11</p></blockquote><h1 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h1><p>微信,相信已经是我们生活中离不开的东西之一了,但随着使用时间增多,我们添加的好友也越来越多。本来想着分分类,让工作和生活分离开来。但看着近千人的通讯录列表实在是苦于操作,于是我们注册了另一个账户。亦称,“小号”、“工作号”</p><p>但随之而来的麻烦又来了,电脑只能登录一个微信账户。那这时候就有同学说了:“来回切换账户发消息,不累么?”</p><p>当然,伟大的程序猿们怎么能浪费时间在这种事情上呢!那今天杰森教大家微信分身,一台电脑同时登录<strong>多个</strong>微信账户</p><span id="more"></span><h1 id="微信分身教程"><a href="#微信分身教程" class="headerlink" title="微信分身教程"></a>微信分身教程</h1><h2 id="1-脚本文件"><a href="#1-脚本文件" class="headerlink" title="1.脚本文件"></a>1.脚本文件</h2><p>桌面找到微信快捷方式,快捷键 <code>alt</code> + <code>enter</code> 查看快捷方式 <strong>目标位置</strong> 并复制路径</p><p><img src="https://img-blog.csdnimg.cn/e9dae819b0ab48e19b2a5c2b2cf55d6b.png"></p><p>桌面空白位置右击,新建 <strong>文本文档</strong>,需要同时登录几个微信就复制几条以下命令</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">start C:\IDE\SoftWare\WeChat\WeChat.exe -- 修改为你的微信目标路径</span><br></pre></td></tr></table></figure><p><img src="https://img-blog.csdnimg.cn/34be9a3e56e142a4b64f27dd0099394c.png"></p><p>组合键 <code>ctrl</code>+ <code>shift</code> + <code>s</code> 另存为 <code>WeChat.bat</code>,此处 <strong>注意编码格式</strong></p><p><img src="https://img-blog.csdnimg.cn/add528259ae64b01a1a91f63ad19e4f5.png"></p><h2 id="2-快捷方式"><a href="#2-快捷方式" class="headerlink" title="2.快捷方式"></a>2.快捷方式</h2><p>将 <code>WeChat.bat</code> 文件放在 <strong>除 C 盘外的其他盘符下</strong> ,右键 <code>WeChat.bat</code> 文件选择 <strong>发送到桌面快捷方式</strong> </p><p><img src="https://img-blog.csdnimg.cn/4a2e3aaa676c437ea573696af6f31eef.png"></p><p>找一个自己喜欢的图标文件 (<code>.ico</code> 格式),选中桌面快捷方式, <code>alt</code> + <code>enter</code> 键更改快捷方式图标</p><blockquote><p>网站推荐:</p><ol><li><span class="exturl" data-url="aHR0cHM6Ly93d3cuaWNvbmZvbnQuY24v">阿里巴巴矢量图标库<i class="fa fa-external-link-alt"></i></span></li><li><span class="exturl" data-url="aHR0cHM6Ly93d3cuYWNvbnZlcnQuY29tL2NuL2ljb24vcG5nLXRvLWljby8=">在线图片格式转换<i class="fa fa-external-link-alt"></i></span>(<code>.png</code> ~ <code>.ico</code>)</li></ol></blockquote><p><img src="https://img-blog.csdnimg.cn/f93b037c7c2f436289a31d173571f3f1.png"></p><p>选中快捷方式,<code>F2</code> 重命名,效果如下</p><p><img src="https://img-blog.csdnimg.cn/827eb739f4f24b4bbbe971e743af4673.png"></p><h2 id="3-测试"><a href="#3-测试" class="headerlink" title="3.测试"></a>3.测试</h2><p>双击 <strong>杰森</strong> 图标,拖拽登录框(重叠),分别登录就可以双开啦</p><p><img src="https://img-blog.csdnimg.cn/61c6189e8ac64dbdb7e5c902c07b07dd.png"></p><hr><center><strong><font size=5>🐳又能愉快的和产品经理xx了🐳</font></strong></center><p><img src="https://img-blog.csdnimg.cn/aba090e89e89495d8ca89d882bbb0171.png#pic_center"></p>]]></content>
<summary type="html"><blockquote>
<p>👲👲<font color=#a2a837 size=3>作者主页</font>:🔗<span class="exturl" data-url="aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L20wXzUxMjY5OTYx">杰森的博客<i class="fa fa-external-link-alt"></i></span><br>📒📒<font color=#20b9cd size=3>本文摘要</font>:<strong>微信分身(多开)教程</strong><br>💖💖如果本文帮助到你的话,还请各位小伙伴👍点赞➕收藏⭐➕评论💭支持杰森呀✌️</p>
</blockquote>
<p><img src="https://img-blog.csdnimg.cn/2ba19d080eb940e99ced56cc6a8ce6e7.png#pic_center"></p>
<hr>
<blockquote>
<p>系统环境:Windows 11</p>
</blockquote>
<h1 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h1><p>微信,相信已经是我们生活中离不开的东西之一了,但随着使用时间增多,我们添加的好友也越来越多。本来想着分分类,让工作和生活分离开来。但看着近千人的通讯录列表实在是苦于操作,于是我们注册了另一个账户。亦称,“小号”、“工作号”</p>
<p>但随之而来的麻烦又来了,电脑只能登录一个微信账户。那这时候就有同学说了:“来回切换账户发消息,不累么?”</p>
<p>当然,伟大的程序猿们怎么能浪费时间在这种事情上呢!那今天杰森教大家微信分身,一台电脑同时登录<strong>多个</strong>微信账户</p></summary>
<category term="资源合集" scheme="https://pdpeng.github.io/categories/%E8%B5%84%E6%BA%90%E5%90%88%E9%9B%86/"/>
<category term="解决方案" scheme="https://pdpeng.github.io/tags/%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/"/>
</entry>
<entry>
<title>Hexo 优化配置汇总【GitHub Actions 看板娘 数学公式 标签云 README 转义问题】</title>
<link href="https://pdpeng.github.io/2022/05/16/hexo-github-actions/"/>
<id>https://pdpeng.github.io/2022/05/16/hexo-github-actions/</id>
<published>2022-05-16T13:51:37.000Z</published>
<updated>2025-03-10T15:12:25.996Z</updated>
<content type="html"><![CDATA[<blockquote><p><span class="exturl" data-url="aHR0cHM6Ly9jb2Rlci1qYXNvbi5jbi8=">服务器<i class="fa fa-external-link-alt"></i></span> 快到期了,这几天迁移到 <code>GitHub</code> 上,用免费的 <code>GitHub Pages</code> 重新部署下 <a href="https://pdpeng.github.io/">杰森的博客</a> 。以下样式及优化配置基于 <code>Hexo</code>,主题 <code>Next</code></p></blockquote><h1 id="GitHub-Actions-自动化部署"><a href="#GitHub-Actions-自动化部署" class="headerlink" title="GitHub Actions 自动化部署"></a>GitHub Actions 自动化部署</h1><p><img src="https://img-blog.csdnimg.cn/667f5a66a56f4649a614f24662407fbd.png"></p><p>本文最具价值的配置莫过于此,没有用到 <code>GitHub Actions</code> 前,每次发文需要将 <code>markdown</code> 文件放入 <code>_post</code> 文件夹下,然后执行 <code>hexo clean && hexo g && hexo s && hexo g</code>一连串命令,执行无报错还好说,万一本地环境出现错误,还得花时间找错,非常麻烦</p><p>使用 <code>GitHub Actions</code> 后,发文只需要在博客的源文件仓库中拖拽源文件或者 <code>push</code> 源文件到仓库,<code>GitHub Actions</code> 即可监测仓库状态,自动执行部署操作到指定位置,不必担心本地环境出错等系列问题</p><span id="more"></span><p>效果 <span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL1BEUEVORy9wZHBlbmcuZ2l0aHViLmlvL2FjdGlvbnM=">预览地址<i class="fa fa-external-link-alt"></i></span></p><p><img src="https://img-blog.csdnimg.cn/ac3e2995981745c8b3c1836ba819ffc4.png"></p><p>有关介绍和详细令牌、密钥配置请 <span class="exturl" data-url="aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dic3UyMDA0L2FydGljbGUvZGV0YWlscy8xMjI2NjExMTY=">参考此处<i class="fa fa-external-link-alt"></i></span>,以下主要是 <code>.github/workflows/deploy.yml</code> <span class="exturl" data-url="aHR0cHM6Ly9naXN0LmdpdGh1Yi5jb20vUERQRU5HL2NjNjYyMDcwMTAwMWY4OWI2ZDMwY2Q5NzliZTI3ZWNl">文件<i class="fa fa-external-link-alt"></i></span> 的配置</p><figure class="highlight yml"><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></pre></td><td class="code"><pre><span class="line"><span class="comment"># Action's Name</span></span><br><span class="line"><span class="attr">name:</span> <span class="string">AutoDeploy</span></span><br><span class="line"></span><br><span class="line"><span class="attr">on:</span></span><br><span class="line"> <span class="comment"># Triggering Condition 1 Main Branch Performs The Task After Receiving Push</span></span><br><span class="line"> <span class="attr">push:</span></span><br><span class="line"> <span class="attr">branches:</span></span><br><span class="line"> <span class="bullet">-</span> <span class="string">master</span></span><br><span class="line"> <span class="comment"># Triggering Condition 2 Manual Button</span></span><br><span class="line"> <span class="attr">workflow_dispatch:</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># Putting Environment Variables Here You Need To Replace It With Your Own</span></span><br><span class="line"><span class="attr">env:</span></span><br><span class="line"> <span class="comment"># After Hexo Compiles Use This Git User To Deploy To The Github Warehouse</span></span><br><span class="line"> <span class="attr">GIT_USER:</span> <span class="string">PDPENG</span></span><br><span class="line"> <span class="comment"># After Hexo Compiles Use This Git Mailbox To Deploy To The Github Warehouse</span></span><br><span class="line"> <span class="attr">GIT_EMAIL:</span> <span class="string">[email protected]</span></span><br><span class="line"> <span class="comment"># The Git Hub Warehouse To Be Deployed After Hexo Compiles</span></span><br><span class="line"> <span class="attr">GIT_DEPLOY_REPO:</span> <span class="string">PDPENG/pdpeng.github.io</span></span><br><span class="line"> <span class="comment"># Hexo Compiles The Branch To Deploy After Compilation</span></span><br><span class="line"> <span class="attr">GIT_DEPLOY_BRANCH:</span> <span class="string">master</span></span><br><span class="line"> </span><br><span class="line"> <span class="comment"># After Hexo Compiles Use This Gitee User To Deploy To The Gitee Warehouse</span></span><br><span class="line"> <span class="attr">GITEE_USER:</span> <span class="string">Coder-Jason</span></span><br><span class="line"> <span class="comment"># The Gitee Warehouse To Be Deployed After Hexo Compiles</span></span><br><span class="line"> <span class="attr">GITEE_DEPLOY_REPO:</span> <span class="string">Coder-Jason/Coder-Jason</span></span><br><span class="line"> <span class="comment"># Hexo Compiles The Branch To Deploy After Compilation</span></span><br><span class="line"> <span class="attr">GITEE_DEPLOY_BRANCH:</span> <span class="string">master</span></span><br><span class="line"> </span><br><span class="line"> <span class="comment"># Pay Attention To Replacing Your Github Source Warehouse Address</span></span><br><span class="line"> <span class="attr">GIT_SOURCE_REPO:</span> <span class="string">[email protected]:PDPENG/pdpeng.github.io.git</span></span><br><span class="line"> <span class="comment"># Pay Attention To Replacement To Your Gitee Target Warehouse Address</span></span><br><span class="line"> <span class="attr">GITEE_DESTINATION_REPO:</span> <span class="string">[email protected]:Coder-Jason/coder-jason.git</span></span><br><span class="line"></span><br><span class="line"><span class="attr">jobs:</span></span><br><span class="line"> <span class="attr">build:</span></span><br><span class="line"> <span class="attr">name:</span> <span class="string">Build</span> <span class="string">on</span> <span class="string">node</span> <span class="string">${{</span> <span class="string">matrix.node_version</span> <span class="string">}}</span> <span class="string">and</span> <span class="string">${{</span> <span class="string">matrix.os</span> <span class="string">}}</span></span><br><span class="line"> <span class="attr">runs-on:</span> <span class="string">ubuntu-latest</span></span><br><span class="line"> <span class="attr">if:</span> <span class="string">github.event.repository.owner.id</span> <span class="string">==</span> <span class="string">github.event.sender.id</span></span><br><span class="line"> <span class="attr">strategy:</span></span><br><span class="line"> <span class="attr">matrix:</span></span><br><span class="line"> <span class="attr">os:</span> [<span class="string">ubuntu-latest</span>]</span><br><span class="line"> <span class="attr">node_version:</span> [<span class="number">16.</span><span class="string">x</span>]</span><br><span class="line"></span><br><span class="line"> <span class="attr">steps:</span></span><br><span class="line"> <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Checkout</span></span><br><span class="line"> <span class="attr">uses:</span> <span class="string">actions/checkout@v2</span></span><br><span class="line"></span><br><span class="line"> <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Checkout</span> <span class="string">deploy</span> <span class="string">repo</span></span><br><span class="line"> <span class="attr">uses:</span> <span class="string">actions/checkout@v2</span></span><br><span class="line"> <span class="attr">with:</span></span><br><span class="line"> <span class="attr">repository:</span> <span class="string">${{</span> <span class="string">env.GIT_DEPLOY_REPO</span> <span class="string">}}</span></span><br><span class="line"> <span class="attr">ref:</span> <span class="string">${{</span> <span class="string">env.GIT_DEPLOY_BRANCH</span> <span class="string">}}</span></span><br><span class="line"> <span class="attr">path:</span> <span class="string">.deploy_git</span></span><br><span class="line"></span><br><span class="line"> <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Use</span> <span class="string">Node.js</span> <span class="string">${{</span> <span class="string">matrix.node_version</span> <span class="string">}}</span></span><br><span class="line"> <span class="attr">uses:</span> <span class="string">actions/setup-node@v1</span></span><br><span class="line"> <span class="attr">with:</span></span><br><span class="line"> <span class="attr">node-version:</span> <span class="string">${{</span> <span class="string">matrix.node_version</span> <span class="string">}}</span></span><br><span class="line"></span><br><span class="line"> <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Configuration</span> <span class="string">environment</span></span><br><span class="line"> <span class="attr">env:</span></span><br><span class="line"> <span class="attr">HEXO_DEPLOY_PRI:</span> <span class="string">${{secrets.HEXO_DEPLOY_PRI}}</span></span><br><span class="line"> <span class="attr">run:</span> <span class="string">|</span></span><br><span class="line"><span class="string"> sudo timedatectl set-timezone "Asia/Shanghai"</span></span><br><span class="line"><span class="string"> mkdir -p ~/.ssh/</span></span><br><span class="line"><span class="string"> echo "$HEXO_DEPLOY_PRI" > ~/.ssh/id_rsa</span></span><br><span class="line"><span class="string"> chmod 600 ~/.ssh/id_rsa</span></span><br><span class="line"><span class="string"> ssh-keyscan -t rsa github.com >> ~/.ssh/known_hosts</span></span><br><span class="line"><span class="string"> ssh-keyscan -t rsa gitee.com >> ~/.ssh/known_hosts</span></span><br><span class="line"><span class="string"> git config --global user.name $GIT_USER</span></span><br><span class="line"><span class="string"> git config --global user.email $GIT_EMAIL</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"> <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Install</span> <span class="string">dependencies</span></span><br><span class="line"> <span class="attr">run:</span> <span class="string">|</span></span><br><span class="line"><span class="string"> npm install hexo-cli -g</span></span><br><span class="line"><span class="string"> # Install According To The Components You Installed</span></span><br><span class="line"><span class="string"> npm install - gulp gulp-uglify hexo hexo-deployer-git hexo-generator-archive hexo-generator-category hexo-generator-feed hexo-generator-index hexo-generator-search hexo-generator-searchdb hexo-generator-sitemap hexo-generator-tag hexo-leancloud-counter-security hexo-renderer-ejs hexo-renderer-marked hexo-renderer-pug hexo-renderer-stylus hexo-server hexo-tag-cloud hexo-word-counter readable-stream uglify-es --save</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"> <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Deploy</span> <span class="string">hexo</span></span><br><span class="line"> <span class="attr">run:</span> <span class="string">|</span></span><br><span class="line"><span class="string"> npm run deploy</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"> <span class="comment"># The Following Is The Release To Gitee</span></span><br><span class="line"> <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Sync</span> <span class="string">to</span> <span class="string">Gitee</span></span><br><span class="line"> <span class="attr">uses:</span> <span class="string">wearerequired/git-mirror-action@master</span></span><br><span class="line"> <span class="attr">env:</span></span><br><span class="line"> <span class="comment"># Using Hexo Deploy Pri Directly</span></span><br><span class="line"> <span class="attr">SSH_PRIVATE_KEY:</span> <span class="string">${{</span> <span class="string">secrets.HEXO_DEPLOY_PRI</span> <span class="string">}}</span></span><br><span class="line"> <span class="attr">with:</span></span><br><span class="line"> <span class="comment"># GitHub Source Warehouse Address</span></span><br><span class="line"> <span class="attr">source-repo:</span> <span class="string">${{</span> <span class="string">env.GIT_SOURCE_REPO</span> <span class="string">}}</span></span><br><span class="line"> <span class="comment"># Gitee Target Warehouse Address</span></span><br><span class="line"> <span class="attr">destination-repo:</span> <span class="string">${{</span> <span class="string">env.GITEE_DESTINATION_REPO</span> <span class="string">}}</span></span><br><span class="line"></span><br><span class="line"> <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Build</span> <span class="string">Gitee</span> <span class="string">Pages</span></span><br><span class="line"> <span class="attr">uses:</span> <span class="string">yanglbme/gitee-pages-action@main</span></span><br><span class="line"> <span class="attr">with:</span></span><br><span class="line"> <span class="comment"># Your Gitee Username</span></span><br><span class="line"> <span class="attr">gitee-username:</span> <span class="string">${{</span> <span class="string">env.GITEE_USER</span> <span class="string">}}</span></span><br><span class="line"> <span class="comment"># Note At Settings Secrets Configuration Gitee Password</span></span><br><span class="line"> <span class="attr">gitee-password:</span> <span class="string">${{</span> <span class="string">secrets.GITEE_PASSWORD</span> <span class="string">}}</span></span><br><span class="line"> <span class="comment"># Your Gitee Warehouse The Warehouse Name Is Strictly Distinguished Please Fill In It Accurately Otherwise There Will Be An Error</span></span><br><span class="line"> <span class="attr">gitee-repo:</span> <span class="string">${{</span> <span class="string">env.GITEE_DEPLOY_REPO</span> <span class="string">}}</span></span><br><span class="line"> <span class="comment"># To Deploy Branches The Default Is Master If It Is Other Branches You Need To Specify The Specified Branch Must Exist</span></span><br><span class="line"> <span class="attr">branch:</span> <span class="string">${{</span> <span class="string">env.GITEE_DEPLOY_BRANCH</span> <span class="string">}}</span></span><br></pre></td></tr></table></figure><p>在配置完令牌及密钥后,可以直接复制 <span class="exturl" data-url="aHR0cHM6Ly9naXN0LmdpdGh1Yi5jb20vUERQRU5HL2NjNjYyMDcwMTAwMWY4OWI2ZDMwY2Q5NzliZTI3ZWNl">该文件<i class="fa fa-external-link-alt"></i></span> 使用,如果仅需要同步 <code>Github</code>,则不必配置 <code>Gitee</code> 同步字段配置</p><p>杰森的仓库分布是</p><figure class="highlight bash"><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">https://github.com/PDPENG/MyBlog 私有仓库 (actions 部署位置)</span><br><span class="line">https://github.com/PDPENG/pdpeng.github.io 公共仓库 (actions 部署后推送的位置)</span><br></pre></td></tr></table></figure><p>配置完成后,<code>GitHub Actions</code> 一旦检测到 <code>MyBlog</code> 仓库下的变动后,将会自动部署至 <code>pdpeng.github.io</code> 仓库</p><p><img src="https://img-blog.csdnimg.cn/cb00c000f77e4026852a5b2e2111c748.png"></p><h1 id="RSS-订阅按钮"><a href="#RSS-订阅按钮" class="headerlink" title="RSS 订阅按钮"></a>RSS 订阅按钮</h1><blockquote><p>这里默认您已经添加了 <code>RSS</code> 相关插件,站点已具备生成 <code>atom.xml</code> 文件能力</p></blockquote><p>效果图,<a href="https://pdpeng.github.io/">预览地址</a></p><p><img src="https://img-blog.csdnimg.cn/5f2497af51014b75bc5c21451f76889a.png"></p><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><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="tag"><<span class="name">html</span>></span></span><br><span class="line"><span class="tag"><<span class="name">head</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">style</span>></span><span class="language-css"></span></span><br><span class="line"><span class="language-css"> <span class="selector-class">.rss-button</span> <span class="selector-tag">div</span> {</span></span><br><span class="line"><span class="language-css"> <span class="attribute">display</span>: block;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">margin-top</span>: <span class="number">5px</span>;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">background-color</span>: transparent;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">position</span>: relative;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">font-family</span>: <span class="string">'Lato'</span>, <span class="string">"PingFang SC"</span>, <span class="string">"Microsoft YaHei"</span>, sans-serif;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">font-size</span>: <span class="number">14px</span>;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">line-height</span>: <span class="number">2</span>;</span></span><br><span class="line"><span class="language-css"> }</span></span><br><span class="line"><span class="language-css"></span></span><br><span class="line"><span class="language-css"> <span class="selector-class">.feed-link</span> <span class="selector-tag">a</span> {</span></span><br><span class="line"><span class="language-css"> <span class="attribute">display</span>: inline-block;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">padding</span>: <span class="number">0</span> <span class="number">15px</span>;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">color</span>: <span class="number">#fc6423</span>;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">border</span>: <span class="number">2px</span> solid <span class="number">#fc6423</span>;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">border-radius</span>: <span class="number">6px</span>;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">text-decoration</span>: none;</span></span><br><span class="line"><span class="language-css"> }</span></span><br><span class="line"><span class="language-css"></span></span><br><span class="line"><span class="language-css"> <span class="selector-class">.feed-link</span> <span class="selector-tag">a</span><span class="selector-pseudo">:hover</span> {</span></span><br><span class="line"><span class="language-css"> <span class="attribute">background-color</span>: <span class="number">#fc6423</span>;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">border-bottom-color</span>: <span class="number">#fc6423</span>;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">color</span>: <span class="number">#fff</span>;</span></span><br><span class="line"><span class="language-css"> }</span></span><br><span class="line"><span class="language-css"> </span><span class="tag"></<span class="name">style</span>></span></span><br><span class="line"><span class="tag"></<span class="name">head</span>></span></span><br><span class="line"></span><br><span class="line"><span class="tag"><<span class="name">body</span> <span class="attr">class</span>=<span class="string">"rss-button"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">div</span> <span class="attr">class</span>=<span class="string">"feed-link"</span> <span class="attr">title</span>=<span class="string">"RSS → /atom.xml"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">a</span> <span class="attr">href</span>=<span class="string">"/atom.xml"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">i</span> <span class="attr">class</span>=<span class="string">"fa fa-rss"</span>></span> <span class="tag"></<span class="name">i</span>></span> RSS</span><br><span class="line"> <span class="tag"></<span class="name">a</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">div</span>></span></span><br><span class="line"><span class="tag"></<span class="name">body</span>></span></span><br><span class="line"><span class="tag"></<span class="name">html</span>></span></span><br></pre></td></tr></table></figure><p>插入到 <code>MyBlog\themes\next\layout\_partials\sidebar\site-overview.njk</code> 文件图示位置中</p><p><img src="https://img-blog.csdnimg.cn/eb84ad84439e49e081f8530a69f7927a.png"></p><h1 id="社交图标加入-CSDN"><a href="#社交图标加入-CSDN" class="headerlink" title="社交图标加入 CSDN"></a>社交图标加入 CSDN</h1><p>效果图,<a href="https://pdpeng.github.io/">预览地址</a></p><p><img src="https://img-blog.csdnimg.cn/3bb93c0c807b491886346c95627b0786.png"></p><p><code>Next</code> 最新版的主题,没有找到引用阿里巴巴图标库的方法(总提示请求无效),如果你有不错的解决方案,欢迎评论区留言</p><p>这里给出一个和 <code>CSDN</code> 比较类似的图标</p><p><img src="https://img-blog.csdnimg.cn/7243c70b6334413ca1a26bcc8d7d8a48.png"></p><figure class="highlight yml"><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="attr">social:</span></span><br><span class="line"> <span class="attr">CSDN:</span> <span class="string">https://blog.csdn.net/m0_51269961</span> <span class="string">||</span> <span class="string">fa-solid</span> <span class="string">fa-c</span></span><br></pre></td></tr></table></figure><h1 id="点击头像返回主页效果"><a href="#点击头像返回主页效果" class="headerlink" title="点击头像返回主页效果"></a>点击头像返回主页效果</h1><p>这个比较简单,在头像的位置添加 <code><a></a></code> 标签就好。可能定位比较麻烦,文件位置是 <code>MyBlog\themes\next\layout\_partials\sidebar\site-overview.njk</code></p><p><img src="https://img-blog.csdnimg.cn/49515d713dda41ccbf40642b35b73e9b.png"></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><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">{%- if theme.avatar.url %}</span><br><span class="line"> <span class="tag"><<span class="name">a</span> <span class="attr">href</span>=<span class="string">"/"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">img</span> <span class="attr">class</span>=<span class="string">"site-author-image"</span> <span class="attr">itemprop</span>=<span class="string">"image"</span> <span class="attr">alt</span>=<span class="string">"{{ author }}"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">src</span>=<span class="string">"{{ url_for(theme.avatar.url) }}"</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">a</span>></span></span><br><span class="line">{%- endif %}</span><br></pre></td></tr></table></figure><h1 id="删除社交链接底部横线"><a href="#删除社交链接底部横线" class="headerlink" title="删除社交链接底部横线"></a>删除社交链接底部横线</h1><p>效果图,<a href="https://pdpeng.github.io/">预览地址</a></p><p><img src="https://img-blog.csdnimg.cn/d3511cf402fa471c8d36f27147d5652c.png"><br>文件位置是<code>MyBlog\themes\next\source\css\_schemes\Muse\_sidebar.styl</code> ,找到 <code>a</code> 标签的 css 样式,添加 <code>border-bottom 0px;</code> 即可</p><p><img src="https://img-blog.csdnimg.cn/d9e2b5c5fbee4345a2cdc00041fc2854.png"></p><h1 id="加入看板娘"><a href="#加入看板娘" class="headerlink" title="加入看板娘"></a>加入看板娘</h1><p>效果图,<a href="https://pdpeng.github.io/">预览地址</a></p><p><img src="https://img-blog.csdnimg.cn/82aa7bff9d4e46a68c2fd8833538e370.png"></p><blockquote><p>如果你的站点开启了侧边栏 <strong>始终显示</strong>,在进行下述操作后,请隐藏侧边栏后查看效果</p></blockquote><p>图示路径下</p><p><img src="https://img-blog.csdnimg.cn/acc6d09706a54ccf9e7b63e44a5bb1f4.png"></p><p>加入这段代码</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><script src=<span class="string">"/live2d-widget/autoload.js"</span>></script></span><br></pre></td></tr></table></figure><p>然后在主题配置文件末尾加入下列配置项</p><figure class="highlight yml"><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="comment"># 自定义看板娘 https://github.com/PDPENG/live2d-widget</span></span><br><span class="line"><span class="attr">live2d:</span></span><br><span class="line"> <span class="attr">enable:</span> <span class="literal">true</span></span><br></pre></td></tr></table></figure><p>效果即可显示</p><hr><p>如果你需要更高级的自定义,可继续完成下面的配置</p><p>切换到主题的 <code>source</code> 文件夹下,克隆项目到本地(删除项目 <code>.git</code> 文件,避免推送报错),<span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL3N0ZXZlbmpvZXpoYW5nL2xpdmUyZC13aWRnZXQ=">项目地址<i class="fa fa-external-link-alt"></i></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">git clone https://github.com/stevenjoezhang/live2d-widget</span><br></pre></td></tr></table></figure><p>*注意:<code>live2d_path</code> 参数应使用 <strong>绝对路径</strong></p><p>更多自定义配置参见,<span class="exturl" data-url="aHR0cHM6Ly9ibG9nLjUxY3RvLmNvbS91XzEzNjQwNjI1LzMwMzIzNjQ=">live2d-widget 自定义配置<i class="fa fa-external-link-alt"></i></span></p><hr><h1 id="自定义-404-页面"><a href="#自定义-404-页面" class="headerlink" title="自定义 404 页面"></a>自定义 404 页面</h1><p>效果图,<a href="https://pdpeng.github.io/404">预览地址</a></p><p><img src="https://img-blog.csdnimg.cn/253a05ded9824343873169a96e2459a4.png"></p><p>之前部署在服务器时,站点是配置了 <code>404</code> 页面的,但是在 <code>Github Pages</code> 中只有访问 <code>/404</code> 时,才能定向到页面,并不能实现真正的 <code>404</code> 效果</p><p>查看了官方文档后,实现也比较容易,只需要在站点资源文件夹(<code>source</code> 目录下)添加 <code>404.md</code> 或 <code>404.html</code> 即可</p><p><img src="https://img-blog.csdnimg.cn/5f5a08c3c9984bc1bdc43897c1380dfc.png"></p><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><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><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br></pre></td><td class="code"><pre><span class="line">---</span><br><span class="line">title: 404</span><br><span class="line">date: 2022-01-29 18:14:03</span><br><span class="line">comments: false</span><br><span class="line">layout: false</span><br><span class="line">---</span><br><span class="line"></span><br><span class="line"><span class="meta"><!DOCTYPE <span class="keyword">html</span>></span></span><br><span class="line"><span class="tag"><<span class="name">html</span>></span></span><br><span class="line"><span class="tag"><<span class="name">head</span>></span></span><br><span class="line"><span class="tag"><<span class="name">meta</span> <span class="attr">charset</span>=<span class="string">"UTF-8"</span>></span></span><br><span class="line"><span class="tag"><<span class="name">title</span>></span>页面走丢啦~<span class="tag"></<span class="name">title</span>></span></span><br><span class="line"><span class="tag"><<span class="name">link</span> <span class="attr">rel</span>=<span class="string">"shortcut icon"</span> <span class="attr">href</span>=<span class="string">"/images/favicon-32x32.png"</span> <span class="attr">type</span>=<span class="string">image/x-icon</span>></span></span><br><span class="line"><span class="tag"></<span class="name">head</span>></span></span><br><span class="line"><span class="tag"><<span class="name">style</span> <span class="attr">type</span>=<span class="string">"text/css"</span>></span><span class="language-css"></span></span><br><span class="line"><span class="language-css"><span class="selector-class">.error</span>{</span></span><br><span class="line"><span class="language-css"><span class="attribute">position</span>: absolute;</span></span><br><span class="line"><span class="language-css"><span class="attribute">top</span>:<span class="number">50%</span>;</span></span><br><span class="line"><span class="language-css"><span class="attribute">margin-top</span>:-<span class="number">250px</span>;</span></span><br><span class="line"><span class="language-css"><span class="attribute">width</span>:<span class="number">100%</span>;</span></span><br><span class="line"><span class="language-css"><span class="attribute">height</span>:<span class="number">400px</span>;</span></span><br><span class="line"><span class="language-css"><span class="comment">/*border:1px solid red;*/</span></span></span><br><span class="line"><span class="language-css"><span class="attribute">overflow</span>: hidden;</span></span><br><span class="line"><span class="language-css">}</span></span><br><span class="line"><span class="language-css"><span class="selector-class">.error</span> <span class="selector-tag">img</span>{</span></span><br><span class="line"><span class="language-css"><span class="attribute">display</span>: block;</span></span><br><span class="line"><span class="language-css"><span class="attribute">margin</span>:<span class="number">0</span> auto;</span></span><br><span class="line"><span class="language-css">}</span></span><br><span class="line"><span class="language-css"><span class="selector-class">.error</span> <span class="selector-tag">p</span>{</span></span><br><span class="line"><span class="language-css"><span class="attribute">text-align</span>: center;</span></span><br><span class="line"><span class="language-css"><span class="attribute">font-size</span>: <span class="number">16px</span> ! important;</span></span><br><span class="line"><span class="language-css"><span class="attribute">font-weight</span>: <span class="number">600</span></span></span><br><span class="line"><span class="language-css">}</span></span><br><span class="line"><span class="language-css"><span class="selector-class">.back</span>{</span></span><br><span class="line"><span class="language-css"><span class="attribute">display</span>: block;</span></span><br><span class="line"><span class="language-css"><span class="attribute">width</span>:<span class="number">80px</span>;</span></span><br><span class="line"><span class="language-css"><span class="attribute">text-align</span>: center;</span></span><br><span class="line"><span class="language-css"><span class="attribute">margin</span>:<span class="number">20px</span> auto;</span></span><br><span class="line"><span class="language-css"><span class="attribute">padding</span>:<span class="number">8px</span> <span class="number">0</span>;</span></span><br><span class="line"><span class="language-css"><span class="attribute">border</span>:<span class="number">1px</span> solid <span class="number">#333</span>;</span></span><br><span class="line"><span class="language-css"><span class="attribute">border-radius</span>: <span class="number">100px</span>;</span></span><br><span class="line"><span class="language-css"><span class="attribute">cursor</span>: pointer;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">text-decoration</span>: none;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">color</span>: <span class="number">#666</span>;</span></span><br><span class="line"><span class="language-css">}</span></span><br><span class="line"><span class="language-css"><span class="selector-class">.back</span><span class="selector-pseudo">:hover</span>{</span></span><br><span class="line"><span class="language-css"><span class="attribute">color</span>:<span class="number">#fff</span>;</span></span><br><span class="line"><span class="language-css"><span class="attribute">background</span>: <span class="number">#000000</span>;</span></span><br><span class="line"><span class="language-css"><span class="attribute">border</span>:<span class="number">0px</span> solid <span class="number">#333</span>;</span></span><br><span class="line"><span class="language-css">}</span></span><br><span class="line"><span class="language-css"></span></span><br><span class="line"><span class="language-css"><span class="comment">/* base.css */</span></span></span><br><span class="line"><span class="language-css"></span></span><br><span class="line"><span class="language-css"><span class="selector-tag">body</span>,<span class="selector-tag">html</span>{</span></span><br><span class="line"><span class="language-css"> <span class="attribute">height</span>: <span class="number">100%</span>;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">width</span>: <span class="number">100%</span>;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">min-width</span>: <span class="number">950px</span>;</span></span><br><span class="line"><span class="language-css">}</span></span><br><span class="line"><span class="language-css"></span></span><br><span class="line"><span class="language-css"><span class="selector-tag">html</span>,<span class="selector-tag">body</span>,<span class="selector-tag">div</span>,<span class="selector-tag">span</span>,applet,<span class="selector-tag">object</span>,<span class="selector-tag">iframe</span>,<span class="selector-tag">h1</span>,<span class="selector-tag">h2</span>,<span class="selector-tag">h3</span>,<span class="selector-tag">h4</span>,<span class="selector-tag">h5</span>,<span class="selector-tag">h6</span>,<span class="selector-tag">p</span>,<span class="selector-tag">blockquote</span>,pre,<span class="selector-tag">a</span>,<span class="selector-tag">abbr</span>, acronym,<span class="selector-tag">address</span>,big,<span class="selector-tag">cite</span>,<span class="selector-tag">code</span>,<span class="selector-tag">del</span>,<span class="selector-tag">dfn</span>,<span class="selector-tag">em</span>,<span class="attribute">font</span>,<span class="selector-tag">img</span>,<span class="selector-tag">ins</span>,<span class="selector-tag">kbd</span>,<span class="selector-tag">q</span>,s,<span class="selector-tag">samp</span>,small,strike, sub,<span class="selector-tag">sup</span>,tt,<span class="selector-tag">var</span>,u,<span class="selector-tag">i</span>,center,<span class="selector-tag">dl</span>,<span class="selector-tag">dt</span>,<span class="selector-tag">dd</span>,<span class="selector-tag">ol</span>,<span class="selector-tag">ul</span>,<span class="selector-tag">li</span>,<span class="selector-tag">fieldset</span>,<span class="selector-tag">form</span>,<span class="selector-tag">label</span>,<span class="selector-tag">legend</span>,<span class="selector-tag">table</span>,<span class="selector-tag">caption</span>, <span class="selector-tag">tbody</span>,<span class="selector-tag">tfoot</span>,<span class="selector-tag">thead</span>,<span class="selector-tag">tr</span>,<span class="selector-tag">th</span>,<span class="selector-tag">td</span>,<span class="selector-tag">p</span>,<span class="selector-tag">span</span>{</span></span><br><span class="line"><span class="language-css"> align:baseline;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">background</span>:transparent;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">margin</span>: <span class="number">0</span>;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">padding</span>:<span class="number">0</span>;</span></span><br><span class="line"><span class="language-css"> -moz-<span class="attribute">box-sizing</span>:border-box; <span class="comment">/* Firefox */</span></span></span><br><span class="line"><span class="language-css"> -webkit-<span class="attribute">box-sizing</span>:border-box; <span class="comment">/* Safari */</span></span></span><br><span class="line"><span class="language-css"> <span class="attribute">box-sizing</span>:border-box;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">list-style-type</span>:none;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">font-family</span>: Microsoft YaHei,microsoft yahei ui,微软雅黑,SimSun,楷体,楷体_GB2312;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">font-size</span>: <span class="number">13px</span>;</span></span><br><span class="line"><span class="language-css">}</span></span><br><span class="line"><span class="language-css"></span></span><br><span class="line"><span class="language-css">option,<span class="selector-tag">input</span>,<span class="selector-tag">button</span>,select,<span class="selector-tag">textarea</span>{</span></span><br><span class="line"><span class="language-css"> <span class="attribute">border</span>:<span class="number">0</span>;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">outline</span>:none;</span></span><br><span class="line"><span class="language-css"> appearance:none;</span></span><br><span class="line"><span class="language-css"> -moz-appearance:none;</span></span><br><span class="line"><span class="language-css"> -webkit-appearance:none;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">background</span>: none;</span></span><br><span class="line"><span class="language-css"> webkit-appearance: none;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">background</span>:none;</span></span><br><span class="line"><span class="language-css">}</span></span><br><span class="line"><span class="language-css"><span class="selector-tag">body</span>, <span class="selector-tag">td</span>, <span class="selector-tag">div</span>,<span class="selector-tag">span</span>,<span class="selector-tag">a</span>{</span></span><br><span class="line"><span class="language-css"> <span class="attribute">line-height</span>:<span class="number">1</span>;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">letter-spacing</span>:<span class="number">0</span>; </span></span><br><span class="line"><span class="language-css"> <span class="attribute">margin</span>:<span class="number">0</span>; </span></span><br><span class="line"><span class="language-css"> <span class="attribute">padding</span>:<span class="number">0</span>; </span></span><br><span class="line"><span class="language-css"> -moz-<span class="attribute">font-smoothing</span>:antialiased; </span></span><br><span class="line"><span class="language-css"> -webkit-<span class="attribute">font-smoothing</span>: antialiased;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">font-smoothing</span>:antialiased; </span></span><br><span class="line"><span class="language-css">}</span></span><br><span class="line"><span class="language-css"> <span class="selector-tag">blockquote</span>,<span class="selector-tag">q</span>{</span></span><br><span class="line"><span class="language-css"> <span class="attribute">quotes</span>:none;</span></span><br><span class="line"><span class="language-css">}</span></span><br><span class="line"><span class="language-css"> <span class="selector-tag">blockquote</span><span class="selector-pseudo">:before</span>,<span class="selector-tag">blockquote</span><span class="selector-pseudo">:after</span>,<span class="selector-tag">q</span><span class="selector-pseudo">:before</span>,<span class="selector-tag">q</span><span class="selector-pseudo">:after</span>{</span></span><br><span class="line"><span class="language-css"> <span class="attribute">content</span>:none;</span></span><br><span class="line"><span class="language-css">}</span></span><br><span class="line"><span class="language-css"> <span class="selector-pseudo">:focus</span>{</span></span><br><span class="line"><span class="language-css"> <span class="attribute">outline</span>:<span class="number">0</span>;</span></span><br><span class="line"><span class="language-css">}</span></span><br><span class="line"><span class="language-css"> <span class="selector-tag">ins</span>{</span></span><br><span class="line"><span class="language-css"> <span class="attribute">text-decoration</span>:none;</span></span><br><span class="line"><span class="language-css">}</span></span><br><span class="line"><span class="language-css"> <span class="selector-tag">del</span>{</span></span><br><span class="line"><span class="language-css"> <span class="attribute">text-decoration</span>:line-through;</span></span><br><span class="line"><span class="language-css">}</span></span><br><span class="line"><span class="language-css"> <span class="selector-tag">table</span>{</span></span><br><span class="line"><span class="language-css"> <span class="attribute">border-collapse</span>:collapse;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">border-spacing</span>:<span class="number">0</span>;</span></span><br><span class="line"><span class="language-css">}</span></span><br><span class="line"><span class="language-css"></span></span><br><span class="line"><span class="language-css"><span class="selector-tag">img</span>{</span></span><br><span class="line"><span class="language-css"> <span class="attribute">border</span>:<span class="number">0px</span>;</span></span><br><span class="line"><span class="language-css">}</span></span><br><span class="line"><span class="language-css"><span class="selector-class">.banner</span>{</span></span><br><span class="line"><span class="language-css"> <span class="attribute">width</span>: <span class="number">1004px</span>;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">height</span>:<span class="number">232px</span>;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">margin</span>: <span class="number">10px</span> auto <span class="number">0</span> auto;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">border-radius</span>: <span class="number">6px</span>;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">overflow</span>: hidden;</span></span><br><span class="line"><span class="language-css">}</span></span><br><span class="line"><span class="language-css"><span class="selector-class">.banner</span> <span class="selector-tag">img</span>{</span></span><br><span class="line"><span class="language-css"> <span class="attribute">width</span>: <span class="number">100%</span>;</span></span><br><span class="line"><span class="language-css">}</span></span><br><span class="line"><span class="language-css"><span class="selector-tag">a</span>{ </span></span><br><span class="line"><span class="language-css"> <span class="attribute">text-decoration</span>:none; </span></span><br><span class="line"><span class="language-css"> <span class="attribute">cursor</span>:pointer; </span></span><br><span class="line"><span class="language-css"> <span class="attribute">outline</span>:none; </span></span><br><span class="line"><span class="language-css"> <span class="attribute">text-decoration-line</span>: none;</span></span><br><span class="line"><span class="language-css"> <span class="attribute">color</span>:<span class="number">#666</span>;</span></span><br><span class="line"><span class="language-css">}</span></span><br><span class="line"><span class="language-css"><span class="selector-tag">a</span>, area {</span></span><br><span class="line"><span class="language-css"> <span class="attribute">outline</span>:none; </span></span><br><span class="line"><span class="language-css"> blr:<span class="built_in">expression</span>(this.onFocus=this.<span class="built_in">blur</span>())</span></span><br><span class="line"><span class="language-css">} </span></span><br><span class="line"><span class="language-css"><span class="selector-tag">a</span><span class="selector-pseudo">:hover</span>{ </span></span><br><span class="line"><span class="language-css"> <span class="attribute">text-decoration</span>:none;</span></span><br><span class="line"><span class="language-css">}</span></span><br><span class="line"><span class="language-css"></span></span><br><span class="line"><span class="language-css"></span><span class="tag"></<span class="name">style</span>></span></span><br><span class="line"></span><br><span class="line"><span class="tag"><<span class="name">body</span>></span></span><br><span class="line"><span class="tag"><<span class="name">div</span> <span class="attr">class</span>=<span class="string">"error"</span>></span></span><br><span class="line"><span class="tag"><<span class="name">img</span> <span class="attr">src</span>=<span class="string">"/images/404.png"</span>></span></span><br><span class="line"><span class="tag"><<span class="name">p</span>></span>抱歉!您访问的页面不存在或已删除<span class="tag"></<span class="name">p</span>></span></span><br><span class="line"><span class="tag"><<span class="name">a</span> <span class="attr">class</span>=<span class="string">"back"</span> <span class="attr">href</span>=<span class="string">"/"</span>></span>返回主页<span class="tag"></<span class="name">a</span>></span></span><br><span class="line"><span class="tag"></<span class="name">div</span>></span></span><br><span class="line"><span class="tag"></<span class="name">body</span>></span></span><br><span class="line"><span class="tag"></<span class="name">html</span>></span></span><br></pre></td></tr></table></figure><h1 id="数学公式支持"><a href="#数学公式支持" class="headerlink" title="数学公式支持"></a>数学公式支持</h1><p>效果图,<a href="https://pdpeng.github.io/2022/05/01/projecteuler014/">预览地址</a></p><p><img src="https://img-blog.csdnimg.cn/165f8d7dc7fd4537baec48f7be8f0db6.png"></p><p>主题配置文件中,该字段配置,详情参考 <span class="exturl" data-url="aHR0cHM6Ly90aGVtZS1uZXh0LmpzLm9yZy9kb2NzL3RoaXJkLXBhcnR5LXNlcnZpY2VzL21hdGgtZXF1YXRpb25z">Math Equations<i class="fa fa-external-link-alt"></i></span></p><figure class="highlight yml"><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="comment"># Math Formulas Render Support</span></span><br><span class="line"><span class="comment"># Warning: Please install / uninstall the relevant renderer according to the documentation.</span></span><br><span class="line"><span class="comment"># See: https://theme-next.js.org/docs/third-party-services/math-equations</span></span><br><span class="line"><span class="comment"># Server-side plugin: https://github.com/next-theme/hexo-filter-mathjax</span></span><br><span class="line"><span class="attr">math:</span></span><br><span class="line"> <span class="comment"># Default (false) will load mathjax / katex script on demand.</span></span><br><span class="line"> <span class="comment"># That is it only render those page which has `mathjax: true` in front-matter.</span></span><br><span class="line"> <span class="comment"># If you set it to true, it will load mathjax / katex script EVERY PAGE.</span></span><br><span class="line"> <span class="attr">every_page:</span> <span class="literal">false</span></span><br><span class="line"></span><br><span class="line"> <span class="attr">mathjax:</span></span><br><span class="line"> <span class="attr">enable:</span> <span class="literal">true</span></span><br><span class="line"> <span class="comment"># Available values: none | ams | all</span></span><br><span class="line"> <span class="attr">tags:</span> <span class="string">none</span></span><br><span class="line"></span><br><span class="line"> <span class="attr">katex:</span></span><br><span class="line"> <span class="attr">enable:</span> <span class="literal">true</span></span><br><span class="line"> <span class="comment"># See: https://github.com/KaTeX/KaTeX/tree/master/contrib/copy-tex</span></span><br><span class="line"> <span class="attr">copy_tex:</span> <span class="literal">true</span></span><br></pre></td></tr></table></figure><p>如依照上述配置,日后发文请在需要加载数学公式渲染文章的 <code>front-matter</code> 处添加 <code>mathjax: true</code>。例如</p><p><img src="https://img-blog.csdnimg.cn/b3aee772d39f46e4afd9fa3bb1d90493.png"></p><h1 id="本地搜索功能排错指南"><a href="#本地搜索功能排错指南" class="headerlink" title="本地搜索功能排错指南"></a>本地搜索功能排错指南</h1><p>效果图,<a href="https://pdpeng.github.io/search.xml">预览地址</a></p><p><img src="https://img-blog.csdnimg.cn/58c14cf7890d4145b183ab87710d6122.png"></p><p>部署完成后,发现本地搜索功能失效,直接 <a href="https://pdpeng.github.io/search.xml">访问站点</a> <code>search.xml</code> 浏览器显示</p><p><img src="https://img-blog.csdnimg.cn/ee1749106db94638892761c024f92f22.png"></p><p>这里在保证插件配置正常的前提下,给出排除字符错误的解决方案</p><p>我们将 <code>search.xml</code> 保存到本地用 <code>vscode</code> 打开,根据浏览器报错的行、列指示,发现字符转义错误。在文章页面下删除该类字符后重新部署,搜索功能恢复</p><h1 id="自定义站点页脚"><a href="#自定义站点页脚" class="headerlink" title="自定义站点页脚"></a>自定义站点页脚</h1><p>效果图,<a href="https://pdpeng.github.io/">预览地址</a></p><p><img src="https://img-blog.csdnimg.cn/2f4721596ce94b36a454484b4a20d17a.png"></p><p>路径如图,按需修改</p><p><img src="https://img-blog.csdnimg.cn/aa314236ea9a451e872548a09875f9f2.png"></p><h1 id="加入标签云"><a href="#加入标签云" class="headerlink" title="加入标签云"></a>加入标签云</h1><p>效果图,<a href="https://pdpeng.github.io/2022/01/19/setup-personal-blog/">预览地址</a></p><p><img src="https://img-blog.csdnimg.cn/eba65e08ae2f411b8da1c3bda18f6ac1.png"></p><ul><li>进入到 <code>hexo</code> 的根目录,然后在 <code>package.json</code> 中添加依赖: <code>"hexo-tag-cloud": "2.1.*"</code></li><li>然后执行 <code>npm install</code> 命令</li></ul><p>打开路径 <code>next/layout/_macro/sidebar.swig</code>,添加如下配置</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></pre></td><td class="code"><pre><span class="line">{% <span class="keyword">if</span> site.<span class="property">tags</span>.<span class="property">length</span> > <span class="number">1</span> %}</span><br><span class="line"><script type=<span class="string">"text/javascript"</span> charset=<span class="string">"utf-8"</span> src=<span class="string">"{{ url_for('/js/tagcloud.js') }}"</span>></script></span><br><span class="line"><span class="language-xml"><span class="tag"><<span class="name">script</span> <span class="attr">type</span>=<span class="string">"text/javascript"</span> <span class="attr">charset</span>=<span class="string">"utf-8"</span> <span class="attr">src</span>=<span class="string">"{{ url_for('/js/tagcanvas.js') }}"</span>></span><span class="tag"></<span class="name">script</span>></span></span></span><br><span class="line"><span class="language-xml"><span class="tag"><<span class="name">div</span> <span class="attr">class</span>=<span class="string">"widget-wrap"</span>></span></span></span><br><span class="line"><span class="language-xml"> <span class="tag"><<span class="name">div</span> <span class="attr">id</span>=<span class="string">"myCanvasContainer"</span> <span class="attr">class</span>=<span class="string">"widget tagcloud"</span>></span></span></span><br><span class="line"><span class="language-xml"> <span class="tag"><<span class="name">canvas</span> <span class="attr">width</span>=<span class="string">"250"</span> <span class="attr">height</span>=<span class="string">"250"</span> <span class="attr">id</span>=<span class="string">"resCanvas"</span> <span class="attr">style</span>=<span class="string">"width:100%"</span>></span></span></span><br><span class="line"><span class="language-xml"> {{ list_tags() }}</span></span><br><span class="line"><span class="language-xml"> <span class="tag"></<span class="name">canvas</span>></span></span></span><br><span class="line"><span class="language-xml"> <span class="tag"></<span class="name">div</span>></span></span></span><br><span class="line"><span class="language-xml"><span class="tag"></<span class="name">div</span>></span></span></span><br><span class="line">{% endif %}</span><br></pre></td></tr></table></figure><ul><li>完成安装和显示,可以通过 <code>hexo clean && hexo g && hexo s</code> 来进行本地预览, hexo clean 为必须选项。</li><li>*注:不要使用 <code>hexo g -d 或者 hexo d -g</code> 这类组合命令,<span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL01pa2VDb2Rlci9oZXhvLXRhZy1jbG91ZC9pc3N1ZXMvNw==">详见<i class="fa fa-external-link-alt"></i></span></li></ul><p><span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL0QwbjlYMW4vaGV4by10YWctY2xvdWQvYmxvYi9tYXN0ZXIvUkVBRE1FLlpILm1k">项目地址及详细教程参考<i class="fa fa-external-link-alt"></i></span></p><h1 id="README-转义问题"><a href="#README-转义问题" class="headerlink" title="README 转义问题"></a>README 转义问题</h1><p>效果图,<span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL1BEUEVORy9wZHBlbmcuZ2l0aHViLmlvL2Jsb2IvbWFzdGVyL1JFQURNRS5tZA==">预览地址<i class="fa fa-external-link-alt"></i></span></p><p><img src="https://img-blog.csdnimg.cn/594b078d532348ae88a2c778e8b92eb8.png"></p><p>当我们为项目配置 <code>README.md</code> 文件时,发布后会发现文件会被 <code>hexo</code> 转义成 <code>.html</code> 文件,详见 <span class="exturl" data-url="aHR0cHM6Ly9oZXhvLmlvL3poLWNuL2RvY3MvY29uZmlndXJhdGlvbi5odG1s">Hexo 配置<i class="fa fa-external-link-alt"></i></span></p><p>这里以站点添加中英双语介绍文件为例,将项目 <code>README.md</code> 及 <code>EN.md</code> 放在 <code>source</code> 目录下</p><p>然后在图示位置根据 <code>glob</code> 语法规则添加值即可</p><p><img src="https://img-blog.csdnimg.cn/f78bcc8b15b84813b9a270f98e0705bc.png"></p><p>这样 <code>hexo</code> 就不会渲染匹配到的文件,显示正常</p><hr><p>参考资料:</p><ul><li><span class="exturl" data-url="aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dic3UyMDA0L2FydGljbGUvZGV0YWlscy8xMjI2NjExMTY=">GitHub Actions 自动部署 Hexo 01<i class="fa fa-external-link-alt"></i></span></li><li><span class="exturl" data-url="aHR0cHM6Ly9zYW5vbnouZ2l0aHViLmlvLzIwMjAvZGVwbG95LWEtaGV4by1ibG9nLWZyb20tZ2l0aHViLWFjdGlvbnMv">GitHub Actions 自动部署 Hexo 02<i class="fa fa-external-link-alt"></i></span></li><li><span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL2FtYml0aW9uLWVjaG8vYW1iaXRpb24tZWNoby5naXRodWIuaW8vYmxvYi9tYWluLy5naXRodWIvd29ya2Zsb3dzL2J1aWxkLnltbA==">Actions yml 文件示例<i class="fa fa-external-link-alt"></i></span></li><li><span class="exturl" data-url="aHR0cHM6Ly93d3cucnVhbnlpZmVuZy5jb20vYmxvZy8yMDE5LzA5L2dldHRpbmctc3RhcnRlZC13aXRoLWdpdGh1Yi1hY3Rpb25zLmh0bWw=">GitHub Actions 入门教程<i class="fa fa-external-link-alt"></i></span></li><li><span class="exturl" data-url="aHR0cHM6Ly9ibG9nLjUxY3RvLmNvbS91XzEzNjQwNjI1LzMwMzIzNjQ=">CDN 方式添加看板娘 live2d-widget<i class="fa fa-external-link-alt"></i></span></li><li><span class="exturl" data-url="aHR0cHM6Ly93d3cuc3Fsc2VjLmNvbS8yMDE3LzEyL2hleG9zZWFyY2guaHRtbA==">本地搜索失效终极解决方案<i class="fa fa-external-link-alt"></i></span></li><li><span class="exturl" data-url="aHR0cDovL3d3dy5ydWFueWlmZW5nLmNvbS9ibG9nLzIwMTgvMDkvYmFzaC13aWxkY2FyZHMuaHRtbA==">命令行通配符教程<i class="fa fa-external-link-alt"></i></span></li><li><span class="exturl" data-url="aHR0cHM6Ly93d3cuamlhbnNodS5jb20vcC9kN2E5N2IxN2VlNWE=">Glob 语法及解析<i class="fa fa-external-link-alt"></i></span></li><li><span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL21pY3JvbWF0Y2gvbWljcm9tYXRjaCNleHRlbmRlZC1nbG9iYmluZw==">#extended-globbing<i class="fa fa-external-link-alt"></i></span></li></ul>]]></content>
<summary type="html"><blockquote>
<p><span class="exturl" data-url="aHR0cHM6Ly9jb2Rlci1qYXNvbi5jbi8=">服务器<i class="fa fa-external-link-alt"></i></span> 快到期了,这几天迁移到 <code>GitHub</code> 上,用免费的 <code>GitHub Pages</code> 重新部署下 <a href="https://pdpeng.github.io/">杰森的博客</a> 。以下样式及优化配置基于 <code>Hexo</code>,主题 <code>Next</code></p>
</blockquote>
<h1 id="GitHub-Actions-自动化部署"><a href="#GitHub-Actions-自动化部署" class="headerlink" title="GitHub Actions 自动化部署"></a>GitHub Actions 自动化部署</h1><p><img src="https://img-blog.csdnimg.cn/667f5a66a56f4649a614f24662407fbd.png"></p>
<p>本文最具价值的配置莫过于此,没有用到 <code>GitHub Actions</code> 前,每次发文需要将 <code>markdown</code> 文件放入 <code>_post</code> 文件夹下,然后执行 <code>hexo clean &amp;&amp; hexo g &amp;&amp; hexo s &amp;&amp; hexo g</code>一连串命令,执行无报错还好说,万一本地环境出现错误,还得花时间找错,非常麻烦</p>
<p>使用 <code>GitHub Actions</code> 后,发文只需要在博客的源文件仓库中拖拽源文件或者 <code>push</code> 源文件到仓库,<code>GitHub Actions</code> 即可监测仓库状态,自动执行部署操作到指定位置,不必担心本地环境出错等系列问题</p></summary>
<category term="网站建设" scheme="https://pdpeng.github.io/categories/%E7%BD%91%E7%AB%99%E5%BB%BA%E8%AE%BE/"/>
<category term="Hexo" scheme="https://pdpeng.github.io/tags/Hexo/"/>
</entry>
<entry>
<title>我的一周年创作纪念日</title>
<link href="https://pdpeng.github.io/2022/05/08/anniversary-creation01/"/>
<id>https://pdpeng.github.io/2022/05/08/anniversary-creation01/</id>
<published>2022-05-08T15:37:54.000Z</published>
<updated>2025-03-10T15:12:25.995Z</updated>
<content type="html"><![CDATA[<blockquote><p>👲👲<font color=#a2a837 size=3>作者主页</font>:🔗<span class="exturl" data-url="aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L20wXzUxMjY5OTYx">杰森的博客<i class="fa fa-external-link-alt"></i></span><br>📒📒<font color=#20b9cd size=3>本文摘要</font>:<strong>攻城狮杂谈,谈谈对创作的感受</strong><br>💖💖希望对你有所帮助👍点赞➕收藏⭐➕评论💭支持杰森呀✌️</p></blockquote><center><img src="https://img-blog.csdnimg.cn/e2b2f16a48b14478a8b44222999d4cb5.png" width="320"></center><hr><blockquote><p>今天咱们不聊技术,不谈知识要点,单纯聊聊✒️<strong>写博客</strong>✒️这件事情,分享下我的收获</p></blockquote><span id="more"></span><p>现在是 2022 年 5 月 8 日 23:00:51,为什么是这个时间来写下这篇博客呢?</p><p><img src="https://img-blog.csdnimg.cn/d66549cfc61d4b2db7abc2f4b3ab8757.png#pic_center"></p><p>当然是贴心的 CSDN 官方记录下了杰森的第一篇博客,记得当时是学习 C++ 编程语言时写下的</p><blockquote><p>杰森的第一篇博客:<span class="exturl" data-url="aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L20wXzUxMjY5OTYxL2FydGljbGUvZGV0YWlscy8xMTY1MjUzNzg=">拷贝构造函数剖析【C++】<i class="fa fa-external-link-alt"></i></span></p></blockquote><p>那时的我不会排版,不懂专业知识(虽然现在也不懂,hah),更别说什么 Markdown 了,直接用富文本编辑的文章</p><p>没有炫酷的页面,缺乏逻辑性的文字,构成了残缺的第一篇博客。一路走来,成长、收货了许多……许多……</p><h1 id="🎯机缘巧合"><a href="#🎯机缘巧合" class="headerlink" title="🎯机缘巧合"></a>🎯机缘巧合</h1><p>杰森目前是一名计算机专业在校学生,偶然在学习 C++ 时发现第一个我认为比较重要的问题,并且是争论了好久才搞明白的问题</p><p>然后为了整理思路,就想着以网络笔记的形式写下来。奈何不知道用什么去写,在我学习过程中,浏览器输入任何专业词汇及知识,弹出的前三个标签页中总有一个叫 CSDN</p><p>于是我便注册了账号,在 CSDN 平台下笔耕不辍到现在,一发不可收拾***</p><hr><h1 id="🎯收获所得"><a href="#🎯收获所得" class="headerlink" title="🎯收获所得"></a>🎯收获所得</h1><p>首先是专业知识,我们在学习完一个知识点后,可能自己并不是很清楚。但是如果你可以写下来,并尝试着让别人看懂,那么才是真正的学到了。我也一直在用这样的方法 去巩固专业重点知识,效果那叫一个 NICE !</p><p>然后就是知识面的快速扩充,写博客时你会发现,可能本来是在解决问题 A ,但是解着解着发现 B 问题也不会,这样一连串下去。解决完一个问题后你会发现收获的远远不止这些,无形中触类旁通又学到了很多</p><p>最后就是 CSDN 的社交圈,这个圈子里可以认识到很多大佬,可以和他们一起交流,共同进步。同时也欢迎大家加入 <span class="exturl" data-url="aHR0cHM6Ly9iYnMuY3Nkbi5uZXQvZm9ydW1zL2Z1bGxzdGFjaw==">全栈攻城狮论坛<i class="fa fa-external-link-alt"></i></span>,一起冲击大厂哦!</p><p><img src="https://img-blog.csdnimg.cn/160794a334444ef4960e89d1d15aeb28.png"></p><p>在这个平台中,每天都可以接触到最新的技术,全新的领域内容以及行业大咖独到的看法。时不时还有小伙伴👍点赞➕收藏⭐➕评论💭,激励自己不断学习心的知识</p><p>两年来,在 C 站也收获许多,结识了很多志同道合的朋友。感谢你们,是你们的支持让我继续前行,不断奋斗</p><p><img src="https://img-blog.csdnimg.cn/362e9438bbd7438bb852f922a3e1ed6f.png#pic_center"></p><p>未来杰森也会持续输出,不断向前哒~~</p><hr><h1 id="🎯日常工作"><a href="#🎯日常工作" class="headerlink" title="🎯日常工作"></a>🎯日常工作</h1><p>学习与创作的关系,我觉得他俩更像是好朋友,一个负责输入,另一个负责输出,相辅相成,齐头并进</p><p>目前,有限的学习生活中,创作已经成为日常学习生活中的一部分,不断的正向反馈反向刺激我接触更多的知识领域,学习更多的专业技能</p><p>有限的精力下,如何平衡创作和工作学习??关于这个问题呢,我想引用鱼皮大佬的一句话</p><blockquote><p>相信会有,那么你就真的会有!</p></blockquote><p>确实,我们的精力是有限的,时间也是有限的。但比起每天浑浑噩噩、打打游戏、刷刷剧的平凡生活,我更愿意深耕在专业技能上</p><p>我们真正投下的有价值的筹码,是时间。面对着足以改变你人生轨迹的黄金时间,你是否感到了它的沉重?你又是否想过要如何计划这笔巨额投资?</p><p>如果你是一名乖孩子,每天从早晨开始好好上课,好好做作业,好好预习、复习,直到熄灯时间好好睡觉,过着这种积极健康,平稳中庸的生活,但是缺乏有效自我支配的生活。如果按照学校的规划,你会发现你可以自由支配的业余时间少得可怜。</p><p>那么,你这样退守下去,无异于把自己的青春放在保险箱里让他随着时间而凋谢。摘自《上海交通大学学生生存手册》</p><p>你觉得,他说的对吗?你又是如何看待的呢?欢迎评论区留言📝</p><hr><h1 id="🎯未来憧憬"><a href="#🎯未来憧憬" class="headerlink" title="🎯未来憧憬"></a>🎯未来憧憬</h1><p>一句话:打铁必须自身硬,BAT 更要本领强!</p><p>友友们,一起加油吧,未来有更多的挑战与困难等着你我来攻克👊👊</p><p>现在到了晚上 23:33:52,时间就是海绵里的水,大家都是一天 24h ,想要多学多做,就得多付出,加油鸭!!</p><hr><center><strong><font size=5>💥让我们期待明天会更好💥</font></strong></center><p><img src="https://img-blog.csdnimg.cn/a20625f94d9e43619671c065f629ff97.png"></p>]]></content>
<summary type="html"><blockquote>
<p>👲👲<font color=#a2a837 size=3>作者主页</font>:🔗<span class="exturl" data-url="aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L20wXzUxMjY5OTYx">杰森的博客<i class="fa fa-external-link-alt"></i></span><br>📒📒<font color=#20b9cd size=3>本文摘要</font>:<strong>攻城狮杂谈,谈谈对创作的感受</strong><br>💖💖希望对你有所帮助👍点赞➕收藏⭐➕评论💭支持杰森呀✌️</p>
</blockquote>
<center><img src="https://img-blog.csdnimg.cn/e2b2f16a48b14478a8b44222999d4cb5.png" width="320"></center>
<hr>
<blockquote>
<p>今天咱们不聊技术,不谈知识要点,单纯聊聊✒️<strong>写博客</strong>✒️这件事情,分享下我的收获</p>
</blockquote></summary>
<category term="攻城狮杂谈" scheme="https://pdpeng.github.io/categories/%E6%94%BB%E5%9F%8E%E7%8B%AE%E6%9D%82%E8%B0%88/"/>
<category term="程序人生" scheme="https://pdpeng.github.io/tags/%E7%A8%8B%E5%BA%8F%E4%BA%BA%E7%94%9F/"/>
</entry>
<entry>
<title>IntelliJ Idea 常用快捷键列表</title>
<link href="https://pdpeng.github.io/2022/05/01/idea-shortcut-key/"/>
<id>https://pdpeng.github.io/2022/05/01/idea-shortcut-key/</id>
<published>2022-05-01T13:56:58.000Z</published>
<updated>2025-03-10T15:12:25.997Z</updated>
<content type="html"><![CDATA[<blockquote><p>👲👲<font color=#a2a837 size=3>作者主页</font>:🔗<span class="exturl" data-url="aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L20wXzUxMjY5OTYx">杰森的博客<i class="fa fa-external-link-alt"></i></span><br>📒📒<font color=#20b9cd size=3>本文摘要</font>:<strong>Idea 开发常用快捷键总结,祝你一臂之力,不加班!</strong><br>💖💖感觉本文不错的话,还请各位小伙伴👍点赞➕收藏⭐➕评论💭支持杰森呀✌️</p></blockquote><center><img src="https://img-blog.csdnimg.cn/3941e32c678044b2a71145ea22853854.gif" alt="like"></center><hr><h1 id="🚀1-高频快捷键列表"><a href="#🚀1-高频快捷键列表" class="headerlink" title="🚀1.高频快捷键列表"></a>🚀1.高频快捷键列表</h1><table><thead><tr><th align="center">快捷键</th><th align="center">含义</th></tr></thead><tbody><tr><td align="center">Ctrl+Shift + Enter</td><td align="center">语句完成</td></tr><tr><td align="center">!</td><td align="center">否定完成,输入表达式时 “!”键</td></tr><tr><td align="center">Ctrl+E</td><td align="center">最近文件</td></tr><tr><td align="center">Ctrl+Shift+E</td><td align="center">最近更改的文件</td></tr><tr><td align="center">Shift+Click</td><td align="center">关闭文件</td></tr><tr><td align="center">Ctrl+[ OR ]</td><td align="center">可以跑到大括号的开头与结尾</td></tr><tr><td align="center">Ctrl+F12</td><td align="center">显示当前文件的结构</td></tr><tr><td align="center">Ctrl+F7</td><td align="center">查询当前元素在当前文件中的引用,按 F3 可以选择</td></tr><tr><td align="center">Ctrl+N</td><td align="center">快速打开类</td></tr><tr><td align="center">Ctrl+Shift+N</td><td align="center">快速打开文件</td></tr><tr><td align="center">Alt+Q</td><td align="center">可以看到当前方法的声明</td></tr><tr><td align="center">Alt+Q</td><td align="center">可以看到当前方法的声明</td></tr><tr><td align="center">Ctrl+P</td><td align="center">可以显示参数信息</td></tr><tr><td align="center">Ctrl+Shift+Insert</td><td align="center">可以选择剪贴板内容并插入</td></tr><tr><td align="center">Alt+Insert</td><td align="center">可以生成构造器/Getter/Setter等</td></tr><tr><td align="center">Ctrl+Alt+V</td><td align="center">可以引入变量。例如:new String(); 自动导入变量定义</td></tr><tr><td align="center">Ctrl+Alt+T</td><td align="center">可以把代码包在一个块内 例如:try/catch</td></tr><tr><td align="center">Ctrl+Enter</td><td align="center">导入包,自动修正</td></tr><tr><td align="center">Ctrl+Alt+L</td><td align="center">格式化代码</td></tr><tr><td align="center">Ctrl+Alt+I</td><td align="center">将选中的代码进行自动缩进编排,这个功能在编辑 JSP 文件时也可以工作</td></tr><tr><td align="center">Ctrl+Alt+O</td><td align="center">优化导入的类和包</td></tr><tr><td align="center">Ctrl+R</td><td align="center">替换文本</td></tr><tr><td align="center">Ctrl+F</td><td align="center">查找文本</td></tr><tr><td align="center">Ctrl+Shift+Space</td><td align="center">自动补全代码</td></tr><tr><td align="center">Ctrl+空格</td><td align="center">代码提示(与系统输入法快捷键冲突)</td></tr><tr><td align="center">Ctrl+Shift+Alt+N</td><td align="center">查找类中的方法或变量</td></tr><tr><td align="center">Alt+Shift+C</td><td align="center">最近的更改</td></tr><tr><td align="center">Alt+Shift+Up/Down</td><td align="center">上/下移一行</td></tr><tr><td align="center">Shift+F6</td><td align="center">重构 – 重命名</td></tr><tr><td align="center">Ctrl+X</td><td align="center">删除行</td></tr><tr><td align="center">Ctrl+D</td><td align="center">复制行</td></tr><tr><td align="center">Ctrl+/或Ctrl+Shift+/</td><td align="center">注释(//或者/**/)</td></tr><tr><td align="center">Ctrl+J</td><td align="center">自动代码(例如:serr)</td></tr><tr><td align="center">Ctrl+Alt+J</td><td align="center">用动态模板环绕</td></tr><tr><td align="center">Ctrl+H</td><td align="center">显示类结构图(类的继承层次)</td></tr><tr><td align="center">Ctrl+Q</td><td align="center">显示注释文档</td></tr><tr><td align="center">Alt+F1</td><td align="center">查找代码所在位置</td></tr><tr><td align="center">Alt+1</td><td align="center">快速打开或隐藏工程面板</td></tr><tr><td align="center">Ctrl+Alt+left/right</td><td align="center">返回至上次浏览的位置</td></tr><tr><td align="center">Alt+left/right</td><td align="center">切换代码视图</td></tr><tr><td align="center">Alt+Up/Down</td><td align="center">在方法间快速移动定位</td></tr><tr><td align="center">Ctrl+Shift+Up/Down</td><td align="center">向上/下移动语句</td></tr><tr><td align="center">F2 或 Shift+F2</td><td align="center">高亮错误或警告快速定位</td></tr><tr><td align="center">Tab</td><td align="center">代码标签输入完成后,按 Tab,生成代码</td></tr><tr><td align="center">Ctrl+Shift+F7</td><td align="center">高亮显示所有该文本,按 Esc 高亮消失</td></tr><tr><td align="center">Alt+F3</td><td align="center">逐个往下查找相同文本,并高亮显示</td></tr><tr><td align="center">Ctrl+Up/Down</td><td align="center">光标中转到第一行或最后一行下</td></tr><tr><td align="center">Ctrl+B/Ctrl+Click</td><td align="center">快速打开光标处的类或方法(跳转到定义处)</td></tr><tr><td align="center">Ctrl+Alt+B</td><td align="center">跳转到方法实现处</td></tr><tr><td align="center">Ctrl+Shift+Backspace</td><td align="center">跳转到上次编辑的地方</td></tr><tr><td align="center">Ctrl+O</td><td align="center">重写方法</td></tr><tr><td align="center">Ctrl+Alt+Space</td><td align="center">类名自动完成</td></tr><tr><td align="center">Ctrl+Alt+Up/Down</td><td align="center">快速跳转搜索结果</td></tr><tr><td align="center">Ctrl+Shift+J</td><td align="center">整合两行</td></tr><tr><td align="center">Alt+F8</td><td align="center">计算变量值</td></tr><tr><td align="center">Ctrl+Shift+V</td><td align="center">可以将最近使用的剪贴板内容选择插入到文本</td></tr><tr><td align="center">Ctrl+Alt+Shift+V</td><td align="center">简单粘贴</td></tr><tr><td align="center">Shift+Esc</td><td align="center">不仅可以把焦点移到编辑器上,而且还可以隐藏当前(或最后活动的)工具窗口</td></tr><tr><td align="center">F12</td><td align="center">把焦点从编辑器移到最近使用的工具窗口</td></tr><tr><td align="center">Shift+F1</td><td align="center">要打开编辑器光标字符处使用的类或者方法 Java 文档的浏览器</td></tr><tr><td align="center">Ctrl+W</td><td align="center">可以选择单词继而语句继而行继而函数</td></tr><tr><td align="center">Ctrl+Shift+W</td><td align="center">取消选择光标所在词</td></tr><tr><td align="center">Alt+F7</td><td align="center">查找整个工程中使用地某一个类、方法或者变量的位置</td></tr><tr><td align="center">Ctrl+I</td><td align="center">实现方法</td></tr><tr><td align="center">Ctrl+Shift+U</td><td align="center">大小写转化</td></tr><tr><td align="center">Ctrl+Y</td><td align="center">删除当前行</td></tr><tr><td align="center">Shift+Enter</td><td align="center">向下插入新行</td></tr><tr><td align="center">psvm/sout</td><td align="center">main/System.out.println(); Ctrl+J,查看更多</td></tr><tr><td align="center">Ctrl+Shift+F</td><td align="center">全局查找</td></tr><tr><td align="center">Ctrl+F</td><td align="center">查找/Shift+F3,向上查找/F3,向下查找</td></tr><tr><td align="center">Ctrl+Shift+S</td><td align="center">高级搜索</td></tr><tr><td align="center">Ctrl+U</td><td align="center">转到父类</td></tr><tr><td align="center">Ctrl+Alt+S</td><td align="center">打开设置对话框</td></tr><tr><td align="center">Alt+Shift+Inert</td><td align="center">开启/关闭列选择模式</td></tr><tr><td align="center">Ctrl+Alt+Shift+S</td><td align="center">打开当前项目/模块属性</td></tr><tr><td align="center">Ctrl+G</td><td align="center">定位行</td></tr><tr><td align="center">Alt+Home</td><td align="center">跳转到导航栏</td></tr><tr><td align="center">Ctrl+Enter</td><td align="center">上插一行</td></tr><tr><td align="center">Ctrl+Backspace</td><td align="center">按单词删除</td></tr><tr><td align="center">Ctrl+”+/-”</td><td align="center">当前方法展开、折叠</td></tr><tr><td align="center">Ctrl+Shift+”+/-”</td><td align="center">全部展开、折叠</td></tr></tbody></table><span id="more"></span><h1 id="🚀2-调试与编译"><a href="#🚀2-调试与编译" class="headerlink" title="🚀2.调试与编译"></a>🚀2.调试与编译</h1><table><thead><tr><th align="center">快捷键</th><th align="center">含义</th></tr></thead><tbody><tr><td align="center">Ctrl+F2</td><td align="center">停止</td></tr><tr><td align="center">Alt+Shift+F9</td><td align="center">选择 Debug</td></tr><tr><td align="center">Alt+Shift+F10</td><td align="center">选择 Run</td></tr><tr><td align="center">Ctrl+Shift+F9</td><td align="center">编译</td></tr><tr><td align="center">Ctrl+Shift+F10</td><td align="center">运行</td></tr><tr><td align="center">Ctrl+Shift+F8</td><td align="center">查看断点</td></tr><tr><td align="center">F8</td><td align="center">步过</td></tr><tr><td align="center">F7</td><td align="center">步入</td></tr><tr><td align="center">Shift+F7</td><td align="center">智能步入</td></tr><tr><td align="center">Shift+F8</td><td align="center">步出</td></tr><tr><td align="center">Alt+Shift+F8</td><td align="center">强制步过</td></tr><tr><td align="center">Alt+Shift+F7</td><td align="center">强制步入</td></tr><tr><td align="center">Alt+F9</td><td align="center">运行至光标处</td></tr><tr><td align="center">Ctrl+Alt+F9</td><td align="center">强制运行至光标处</td></tr><tr><td align="center">F9</td><td align="center">恢复程序</td></tr><tr><td align="center">Alt+F10</td><td align="center">定位到断点</td></tr><tr><td align="center">Ctrl+F8</td><td align="center">切换行断点</td></tr><tr><td align="center">Ctrl+F9</td><td align="center">生成项目</td></tr><tr><td align="center">Alt+1</td><td align="center">项目</td></tr><tr><td align="center">Alt+2</td><td align="center">收藏</td></tr><tr><td align="center">Alt+6</td><td align="center">TODO</td></tr><tr><td align="center">Alt+7</td><td align="center">结构</td></tr><tr><td align="center">Ctrl+Shift+C</td><td align="center">复制路径</td></tr><tr><td align="center">Ctrl+Alt+Shift+C</td><td align="center">复制引用,必须选择类名</td></tr><tr><td align="center">Ctrl+Alt+Y</td><td align="center">同步</td></tr><tr><td align="center">Ctrl+~</td><td align="center">快速切换方案(界面外观、代码风格、快捷键映射等菜单)</td></tr><tr><td align="center">Shift+F12</td><td align="center">还原默认布局</td></tr><tr><td align="center">Ctrl+Shift+F12</td><td align="center">隐藏/恢复所有窗口</td></tr><tr><td align="center">Ctrl+F4</td><td align="center">关闭</td></tr><tr><td align="center">Ctrl+Shift+F4</td><td align="center">关闭活动选项卡</td></tr><tr><td align="center">Ctrl+Tab</td><td align="center">转到下一个拆分器</td></tr><tr><td align="center">Ctrl+Shift+Tab</td><td align="center">转到上一个拆分器</td></tr></tbody></table><h1 id="🚀3-重构"><a href="#🚀3-重构" class="headerlink" title="🚀3.重构"></a>🚀3.重构</h1><table><thead><tr><th align="center">快捷键</th><th align="center">含义</th></tr></thead><tbody><tr><td align="center">Ctrl+Alt+Shift+T</td><td align="center">弹出重构菜单</td></tr><tr><td align="center">Shift+F6</td><td align="center">重命名</td></tr><tr><td align="center">F6</td><td align="center">移动</td></tr><tr><td align="center">F5</td><td align="center">复制</td></tr><tr><td align="center">Alt+Delete</td><td align="center">安全删除</td></tr><tr><td align="center">Ctrl+Alt+N</td><td align="center">内联</td></tr></tbody></table><h1 id="🚀4-查找"><a href="#🚀4-查找" class="headerlink" title="🚀4.查找"></a>🚀4.查找</h1><table><thead><tr><th align="center">快捷键</th><th align="center">含义</th></tr></thead><tbody><tr><td align="center">Ctrl+F</td><td align="center">查找</td></tr><tr><td align="center">Ctrl+R</td><td align="center">替换</td></tr><tr><td align="center">F3</td><td align="center">查找下一个</td></tr><tr><td align="center">Shift+F3</td><td align="center">查找上一个</td></tr><tr><td align="center">Ctrl+Shift+F</td><td align="center">在路径中查找</td></tr><tr><td align="center">Ctrl+Shift+R</td><td align="center">在路径中替换</td></tr><tr><td align="center">Ctrl+Shift+S</td><td align="center">搜索结构</td></tr><tr><td align="center">Ctrl+Shift+M</td><td align="center">替换结构</td></tr><tr><td align="center">Alt+F7</td><td align="center">查找用法</td></tr><tr><td align="center">Ctrl+Alt+F7</td><td align="center">显示用法</td></tr><tr><td align="center">Ctrl+F7</td><td align="center">在文件中查找用法</td></tr><tr><td align="center">Ctrl+Shift+F7</td><td align="center">在文件中高亮显示用法</td></tr><tr><td align="center">Alt+left/right</td><td align="center">向后、前</td></tr><tr><td align="center">Ctrl + H</td><td align="center">看类结构</td></tr><tr><td align="center">Ctrl+z</td><td align="center">后退</td></tr></tbody></table><h1 id="🚀5-文本编辑"><a href="#🚀5-文本编辑" class="headerlink" title="🚀5.文本编辑"></a>🚀5.文本编辑</h1><table><thead><tr><th align="center">快捷键</th><th align="center">含义</th></tr></thead><tbody><tr><td align="center">ctr + y</td><td align="center">删除</td></tr><tr><td align="center">ctr + D</td><td align="center">复制</td></tr></tbody></table><h1 id="🚀6-智能提示"><a href="#🚀6-智能提示" class="headerlink" title="🚀6.智能提示"></a>🚀6.智能提示</h1><table><thead><tr><th>快捷键</th><th>含义</th></tr></thead><tbody><tr><td>ctrl+ space</td><td>提示</td></tr><tr><td>ctrl + shift + space</td><td>智能提示</td></tr><tr><td>ctrl + shift + enter</td><td>完成当前语句</td></tr><tr><td>ctrl + alt + P</td><td>建议提示为参数</td></tr><tr><td>ctrl + alt + L</td><td>对代码重新排列格式</td></tr><tr><td>ctrl + alt + O</td><td>对imports进行优化</td></tr></tbody></table><h1 id="🚀7-位置定位"><a href="#🚀7-位置定位" class="headerlink" title="🚀7.位置定位"></a>🚀7.位置定位</h1><table><thead><tr><th align="center">快捷键</th><th align="center">含义</th></tr></thead><tbody><tr><td align="center">F2 / Shift + F2</td><td align="center">定位到下一个或上一个错误</td></tr><tr><td align="center">ctr+G (定位到文件行数)</td><td align="center">定位文件头</td></tr><tr><td align="center">ctr+G</td><td align="center">定位文件尾</td></tr><tr><td align="center">ctr + [</td><td align="center">定位到代码块开始</td></tr><tr><td align="center">ctr + ]</td><td align="center">定位到代码块结束</td></tr><tr><td align="center">F12</td><td align="center">回到最近的窗口</td></tr><tr><td align="center">alt + left</td><td align="center">回到之前的文件</td></tr><tr><td align="center">alt + right</td><td align="center">回到之后的文件</td></tr><tr><td align="center">Ctrl + Shift + Backspace</td><td align="center">定位到最后编辑位置</td></tr><tr><td align="center">esc</td><td align="center">从tool window或其他window切换到文件编辑</td></tr><tr><td align="center">shift + esc</td><td align="center">关闭最近打开的窗口</td></tr></tbody></table><h1 id="🚀8-类、方法、文件定位"><a href="#🚀8-类、方法、文件定位" class="headerlink" title="🚀8.类、方法、文件定位"></a>🚀8.类、方法、文件定位</h1><table><thead><tr><th align="center">快捷键</th><th align="center">含义</th></tr></thead><tbody><tr><td align="center">ctr + N</td><td align="center">查找类</td></tr><tr><td align="center">Ctrl + Shift + N</td><td align="center">查找文件</td></tr><tr><td align="center">Ctrl + Alt + Shift + N</td><td align="center">符号定位</td></tr><tr><td align="center">ctrl + F12</td><td align="center">查看文件结构</td></tr><tr><td align="center">ctr + E</td><td align="center">最近打开的文件</td></tr><tr><td align="center">alt + down</td><td align="center">定位下一个方法</td></tr><tr><td align="center">alt + up</td><td align="center">定位上一个方法</td></tr><tr><td align="center">ctr + p</td><td align="center">查看方法参数信息</td></tr><tr><td align="center">ctr + Q</td><td align="center">查看方法、类的doc</td></tr></tbody></table><h1 id="🚀9-类、方法的结构查看、定位"><a href="#🚀9-类、方法的结构查看、定位" class="headerlink" title="🚀9.类、方法的结构查看、定位"></a>🚀9.类、方法的结构查看、定位</h1><table><thead><tr><th align="center">快捷键</th><th align="center">含义</th></tr></thead><tbody><tr><td align="center">ctr + B</td><td align="center">跳到类或方法的声明</td></tr><tr><td align="center">ctr + U</td><td align="center">定位到类的父类、接口</td></tr><tr><td align="center">ctr + H</td><td align="center">查看类的继承结构</td></tr><tr><td align="center">ctr + shift + H</td><td align="center">查看方法的继承结构</td></tr><tr><td align="center">ctr + alt +H</td><td align="center">查看类或方法被调用情况</td></tr><tr><td align="center">ctrl + shift + I</td><td align="center">原地参看类、方法的声明</td></tr></tbody></table><h1 id="🚀10-运行"><a href="#🚀10-运行" class="headerlink" title="🚀10.运行"></a>🚀10.运行</h1><table><thead><tr><th align="center">快捷键</th><th align="center">含义</th></tr></thead><tbody><tr><td align="center">Ctrl + F9</td><td align="center">Make项目(编译、修改和依赖)</td></tr><tr><td align="center">Ctrl + Shift + F9</td><td align="center">编译选定的文件、包或模块</td></tr><tr><td align="center">Alt + Shift + F10</td><td align="center">选择配置并运行</td></tr><tr><td align="center">Alt + Shift + F9</td><td align="center">选择配置和调试</td></tr><tr><td align="center">Shift + F10</td><td align="center">运行</td></tr><tr><td align="center">Shift + F9</td><td align="center">调试</td></tr><tr><td align="center">Ctrl + Shift + F10</td><td align="center">从编辑器运行上下文配置</td></tr></tbody></table><h1 id="🚀11-调试"><a href="#🚀11-调试" class="headerlink" title="🚀11.调试"></a>🚀11.调试</h1><table><thead><tr><th align="center">快捷键</th><th align="center">含义</th></tr></thead><tbody><tr><td align="center">F8</td><td align="center">跳过</td></tr><tr><td align="center">F7</td><td align="center">进入</td></tr><tr><td align="center">Shift + F7</td><td align="center">自动进入</td></tr><tr><td align="center">Shift + F8</td><td align="center">跳出</td></tr><tr><td align="center">Alt + F9</td><td align="center">运行到光标</td></tr><tr><td align="center">Alt + F8</td><td align="center">计算表达式</td></tr><tr><td align="center">F9</td><td align="center">恢复程序</td></tr><tr><td align="center">Ctrl + F8</td><td align="center">Toggle breakpoint</td></tr><tr><td align="center">Ctrl + Shift + F8</td><td align="center">查看断点</td></tr></tbody></table><blockquote><center><strong>这么详细的总结,记得收藏备用哟</strong></center></blockquote><hr><center><strong><font size=5>💘今晚必须按时下班💘</font></strong></center><p><img src="https://img-blog.csdnimg.cn/88ecd48a2d45449099077a4516f36a9a.png"></p>]]></content>
<summary type="html"><blockquote>
<p>👲👲<font color=#a2a837 size=3>作者主页</font>:🔗<span class="exturl" data-url="aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L20wXzUxMjY5OTYx">杰森的博客<i class="fa fa-external-link-alt"></i></span><br>📒📒<font color=#20b9cd size=3>本文摘要</font>:<strong>Idea 开发常用快捷键总结,祝你一臂之力,不加班!</strong><br>💖💖感觉本文不错的话,还请各位小伙伴👍点赞➕收藏⭐➕评论💭支持杰森呀✌️</p>
</blockquote>
<center><img src="https://img-blog.csdnimg.cn/3941e32c678044b2a71145ea22853854.gif" alt="like"></center>
<hr>
<h1 id="🚀1-高频快捷键列表"><a href="#🚀1-高频快捷键列表" class="headerlink" title="🚀1.高频快捷键列表"></a>🚀1.高频快捷键列表</h1><table>
<thead>
<tr>
<th align="center">快捷键</th>
<th align="center">含义</th>
</tr>
</thead>
<tbody><tr>
<td align="center">Ctrl+Shift + Enter</td>
<td align="center">语句完成</td>
</tr>
<tr>
<td align="center">!</td>
<td align="center">否定完成,输入表达式时 “!”键</td>
</tr>
<tr>
<td align="center">Ctrl+E</td>
<td align="center">最近文件</td>
</tr>
<tr>
<td align="center">Ctrl+Shift+E</td>
<td align="center">最近更改的文件</td>
</tr>
<tr>
<td align="center">Shift+Click</td>
<td align="center">关闭文件</td>
</tr>
<tr>
<td align="center">Ctrl+[ OR ]</td>
<td align="center">可以跑到大括号的开头与结尾</td>
</tr>
<tr>
<td align="center">Ctrl+F12</td>
<td align="center">显示当前文件的结构</td>
</tr>
<tr>
<td align="center">Ctrl+F7</td>
<td align="center">查询当前元素在当前文件中的引用,按 F3 可以选择</td>
</tr>
<tr>
<td align="center">Ctrl+N</td>
<td align="center">快速打开类</td>
</tr>
<tr>
<td align="center">Ctrl+Shift+N</td>
<td align="center">快速打开文件</td>
</tr>
<tr>
<td align="center">Alt+Q</td>
<td align="center">可以看到当前方法的声明</td>
</tr>
<tr>
<td align="center">Alt+Q</td>
<td align="center">可以看到当前方法的声明</td>
</tr>
<tr>
<td align="center">Ctrl+P</td>
<td align="center">可以显示参数信息</td>
</tr>
<tr>
<td align="center">Ctrl+Shift+Insert</td>
<td align="center">可以选择剪贴板内容并插入</td>
</tr>
<tr>
<td align="center">Alt+Insert</td>
<td align="center">可以生成构造器&#x2F;Getter&#x2F;Setter等</td>
</tr>
<tr>
<td align="center">Ctrl+Alt+V</td>
<td align="center">可以引入变量。例如:new String(); 自动导入变量定义</td>
</tr>
<tr>
<td align="center">Ctrl+Alt+T</td>
<td align="center">可以把代码包在一个块内 例如:try&#x2F;catch</td>
</tr>
<tr>
<td align="center">Ctrl+Enter</td>
<td align="center">导入包,自动修正</td>
</tr>
<tr>
<td align="center">Ctrl+Alt+L</td>
<td align="center">格式化代码</td>
</tr>
<tr>
<td align="center">Ctrl+Alt+I</td>
<td align="center">将选中的代码进行自动缩进编排,这个功能在编辑 JSP 文件时也可以工作</td>
</tr>
<tr>
<td align="center">Ctrl+Alt+O</td>
<td align="center">优化导入的类和包</td>
</tr>
<tr>
<td align="center">Ctrl+R</td>
<td align="center">替换文本</td>
</tr>
<tr>
<td align="center">Ctrl+F</td>
<td align="center">查找文本</td>
</tr>
<tr>
<td align="center">Ctrl+Shift+Space</td>
<td align="center">自动补全代码</td>
</tr>
<tr>
<td align="center">Ctrl+空格</td>
<td align="center">代码提示(与系统输入法快捷键冲突)</td>
</tr>
<tr>
<td align="center">Ctrl+Shift+Alt+N</td>
<td align="center">查找类中的方法或变量</td>
</tr>
<tr>
<td align="center">Alt+Shift+C</td>
<td align="center">最近的更改</td>
</tr>
<tr>
<td align="center">Alt+Shift+Up&#x2F;Down</td>
<td align="center">上&#x2F;下移一行</td>
</tr>
<tr>
<td align="center">Shift+F6</td>
<td align="center">重构 – 重命名</td>
</tr>
<tr>
<td align="center">Ctrl+X</td>
<td align="center">删除行</td>
</tr>
<tr>
<td align="center">Ctrl+D</td>
<td align="center">复制行</td>
</tr>
<tr>
<td align="center">Ctrl+&#x2F;或Ctrl+Shift+&#x2F;</td>
<td align="center">注释(&#x2F;&#x2F;或者&#x2F;**&#x2F;)</td>
</tr>
<tr>
<td align="center">Ctrl+J</td>
<td align="center">自动代码(例如:serr)</td>
</tr>
<tr>
<td align="center">Ctrl+Alt+J</td>
<td align="center">用动态模板环绕</td>
</tr>
<tr>
<td align="center">Ctrl+H</td>
<td align="center">显示类结构图(类的继承层次)</td>
</tr>
<tr>
<td align="center">Ctrl+Q</td>
<td align="center">显示注释文档</td>
</tr>
<tr>
<td align="center">Alt+F1</td>
<td align="center">查找代码所在位置</td>
</tr>
<tr>
<td align="center">Alt+1</td>
<td align="center">快速打开或隐藏工程面板</td>
</tr>
<tr>
<td align="center">Ctrl+Alt+left&#x2F;right</td>
<td align="center">返回至上次浏览的位置</td>
</tr>
<tr>
<td align="center">Alt+left&#x2F;right</td>
<td align="center">切换代码视图</td>
</tr>
<tr>
<td align="center">Alt+Up&#x2F;Down</td>
<td align="center">在方法间快速移动定位</td>
</tr>
<tr>
<td align="center">Ctrl+Shift+Up&#x2F;Down</td>
<td align="center">向上&#x2F;下移动语句</td>
</tr>
<tr>
<td align="center">F2 或 Shift+F2</td>
<td align="center">高亮错误或警告快速定位</td>
</tr>
<tr>
<td align="center">Tab</td>
<td align="center">代码标签输入完成后,按 Tab,生成代码</td>
</tr>
<tr>
<td align="center">Ctrl+Shift+F7</td>
<td align="center">高亮显示所有该文本,按 Esc 高亮消失</td>
</tr>
<tr>
<td align="center">Alt+F3</td>
<td align="center">逐个往下查找相同文本,并高亮显示</td>
</tr>
<tr>
<td align="center">Ctrl+Up&#x2F;Down</td>
<td align="center">光标中转到第一行或最后一行下</td>
</tr>
<tr>
<td align="center">Ctrl+B&#x2F;Ctrl+Click</td>
<td align="center">快速打开光标处的类或方法(跳转到定义处)</td>
</tr>
<tr>
<td align="center">Ctrl+Alt+B</td>
<td align="center">跳转到方法实现处</td>
</tr>
<tr>
<td align="center">Ctrl+Shift+Backspace</td>
<td align="center">跳转到上次编辑的地方</td>
</tr>
<tr>
<td align="center">Ctrl+O</td>
<td align="center">重写方法</td>
</tr>
<tr>
<td align="center">Ctrl+Alt+Space</td>
<td align="center">类名自动完成</td>
</tr>
<tr>
<td align="center">Ctrl+Alt+Up&#x2F;Down</td>
<td align="center">快速跳转搜索结果</td>
</tr>
<tr>
<td align="center">Ctrl+Shift+J</td>
<td align="center">整合两行</td>
</tr>
<tr>
<td align="center">Alt+F8</td>
<td align="center">计算变量值</td>
</tr>
<tr>
<td align="center">Ctrl+Shift+V</td>
<td align="center">可以将最近使用的剪贴板内容选择插入到文本</td>
</tr>
<tr>
<td align="center">Ctrl+Alt+Shift+V</td>
<td align="center">简单粘贴</td>
</tr>
<tr>
<td align="center">Shift+Esc</td>
<td align="center">不仅可以把焦点移到编辑器上,而且还可以隐藏当前(或最后活动的)工具窗口</td>
</tr>
<tr>
<td align="center">F12</td>
<td align="center">把焦点从编辑器移到最近使用的工具窗口</td>
</tr>
<tr>
<td align="center">Shift+F1</td>
<td align="center">要打开编辑器光标字符处使用的类或者方法 Java 文档的浏览器</td>
</tr>
<tr>
<td align="center">Ctrl+W</td>
<td align="center">可以选择单词继而语句继而行继而函数</td>
</tr>
<tr>
<td align="center">Ctrl+Shift+W</td>
<td align="center">取消选择光标所在词</td>
</tr>
<tr>
<td align="center">Alt+F7</td>
<td align="center">查找整个工程中使用地某一个类、方法或者变量的位置</td>
</tr>
<tr>
<td align="center">Ctrl+I</td>
<td align="center">实现方法</td>
</tr>
<tr>
<td align="center">Ctrl+Shift+U</td>
<td align="center">大小写转化</td>
</tr>
<tr>
<td align="center">Ctrl+Y</td>
<td align="center">删除当前行</td>
</tr>
<tr>
<td align="center">Shift+Enter</td>
<td align="center">向下插入新行</td>
</tr>
<tr>
<td align="center">psvm&#x2F;sout</td>
<td align="center">main&#x2F;System.out.println(); Ctrl+J,查看更多</td>
</tr>
<tr>
<td align="center">Ctrl+Shift+F</td>
<td align="center">全局查找</td>
</tr>
<tr>
<td align="center">Ctrl+F</td>
<td align="center">查找&#x2F;Shift+F3,向上查找&#x2F;F3,向下查找</td>
</tr>
<tr>
<td align="center">Ctrl+Shift+S</td>
<td align="center">高级搜索</td>
</tr>
<tr>
<td align="center">Ctrl+U</td>
<td align="center">转到父类</td>
</tr>
<tr>
<td align="center">Ctrl+Alt+S</td>
<td align="center">打开设置对话框</td>
</tr>
<tr>
<td align="center">Alt+Shift+Inert</td>
<td align="center">开启&#x2F;关闭列选择模式</td>
</tr>
<tr>
<td align="center">Ctrl+Alt+Shift+S</td>
<td align="center">打开当前项目&#x2F;模块属性</td>
</tr>
<tr>
<td align="center">Ctrl+G</td>
<td align="center">定位行</td>
</tr>
<tr>
<td align="center">Alt+Home</td>
<td align="center">跳转到导航栏</td>
</tr>
<tr>
<td align="center">Ctrl+Enter</td>
<td align="center">上插一行</td>
</tr>
<tr>
<td align="center">Ctrl+Backspace</td>
<td align="center">按单词删除</td>
</tr>
<tr>
<td align="center">Ctrl+”+&#x2F;-”</td>
<td align="center">当前方法展开、折叠</td>
</tr>
<tr>
<td align="center">Ctrl+Shift+”+&#x2F;-”</td>
<td align="center">全部展开、折叠</td>
</tr>
</tbody></table></summary>
<category term="Java" scheme="https://pdpeng.github.io/categories/Java/"/>
<category term="Java" scheme="https://pdpeng.github.io/tags/Java/"/>
</entry>
<entry>
<title>【欧拉计划第 14 题】 最长的考拉兹序列 Longest Collatz sequence</title>
<link href="https://pdpeng.github.io/2022/05/01/projecteuler014/"/>
<id>https://pdpeng.github.io/2022/05/01/projecteuler014/</id>
<published>2022-05-01T01:19:38.000Z</published>
<updated>2025-03-10T15:12:25.998Z</updated>
<content type="html"><![CDATA[<h1 id="Problem-14-Longest-Collatz-sequence"><a href="#Problem-14-Longest-Collatz-sequence" class="headerlink" title="Problem 14 Longest Collatz sequence"></a>Problem 14 Longest Collatz sequence</h1><blockquote><p>The following iterative sequence is defined for the set of positive integers:</p></blockquote><p>$$<br>\large n\rightarrow \frac{n}{2}\ \left ( n\ is\ even \right ) ,n\rightarrow3n+1\ \left ( \ n\ is\ odd \right )<br>$$</p><blockquote><p>Using the rule above and starting with $13$, we generate the following sequence:</p></blockquote><p>$$<br>\large 13\rightarrow40\rightarrow20\rightarrow10\rightarrow5\rightarrow16\rightarrow8\rightarrow4\rightarrow2\rightarrow1<br>$$</p><blockquote><p>It can be seen that this sequence (starting at $13$ and finishing at 1) contains $10$ terms. Although it has not been proved yet (Collatz Problem), it is thought that all starting numbers finish at $1$.<br>Which starting number, under one million, produces the longest chain?<br>NOTE: Once the chain starts the terms are allowed to go above one million.</p></blockquote><span id="more"></span><h1 id="问题-14-最长的考拉兹序列"><a href="#问题-14-最长的考拉兹序列" class="headerlink" title="问题 14 最长的考拉兹序列"></a>问题 14 最长的考拉兹序列</h1><blockquote><p>为所有正整数集定义以下迭代序列:</p></blockquote><p>$$<br>\large n\rightarrow \frac{n}{2}\ \left ( n,是偶数 \right ) ,n\rightarrow3n+1\ \left ( n,是奇数 \right )<br>$$</p><blockquote><p>使用上面的规则并从 $13$ 开始,生成以下序列:</p></blockquote><p>$$<br>\large 13\rightarrow40\rightarrow20\rightarrow10\rightarrow5\rightarrow16\rightarrow8\rightarrow4\rightarrow2\rightarrow1<br>$$</p><blockquote><p>可以看出这个序列从 $13$ 开始并到 $1$ 结束总共包含 $10$ 个数。<br>考拉兹猜想指出使用以上迭代规则,所有正整数都会最终回到一,虽然这个猜想仍未得到证明。<br>求在一百万以下,哪个起始数可以产生最长的考拉兹序列?<br>注意:序列中包含的数的个数可以超过一百万。</p></blockquote><h1 id="解题报告"><a href="#解题报告" class="headerlink" title="解题报告"></a>解题报告</h1><h2 id="考拉兹猜想"><a href="#考拉兹猜想" class="headerlink" title="考拉兹猜想"></a>考拉兹猜想</h2><p>考拉兹猜想(Collatz conjecture),又称为奇偶归一猜想、3n+1 猜想、冰雹猜想、角谷猜想、哈塞猜想、乌拉姆猜想或叙拉古猜想,<strong>是指对于每一个正整数,如果它是奇数,则对它乘 3 再加 1,如果它是偶数,则对它除以 2,如此循环,最终都能够得到 1</strong></p><p>$$<br>\large f\left ( n \right )=\left\{\begin{matrix}\frac{n}{2} \quad\quad\quad if \, n\equiv 0\\3n+1 \quad if \, n\equiv 1\end{matrix}\right.\left .\quad( mod \,\, 2 \right )<br>$$</p><h2 id="思路分析"><a href="#思路分析" class="headerlink" title="思路分析"></a>思路分析</h2><p>其实当你看到题目的时候,不知到你有没有和我想到一块儿去,那必然又是咱滴老朋友<strong>暴力算法</strong>啦</p><p><img src="https://img-blog.csdnimg.cn/b4fe785c36964aceb37914a12f68ce2e.png#pic_center"></p><p>显然,我们只要求算出一到一百万之间所有数字的<strong>考拉兹序列</strong>长度,然后在所有求出的序列长度值中找出最大值就能解决本题</p><p>但是可以做一些优化,比如大家都知道当 <code>n</code> 是奇数时,<code>3n+1</code> 一定是偶数。那我们根本没必要让程序重复执行冗余步骤</p><p>换言之,当 <code>n</code> 是奇数的时候,在其后追加一步,继续计算 <code>(3n+1)/2</code>。便可省去很多中间计算步骤,程序执行效率自然得到提高</p><p>还有一点是参考其他大神写的题解意识到的,就是程序重复计算的问题。较大的数据量在计算过程中可能会产生重复数据,我们是不是可以将所有计算步骤得到的结果做下缓存。这样在下一步遇到重复值时可以直接调用,避免重复计算,提高程序执行效率</p><p>或者也可以使用<strong>递归法</strong>实现本题</p><h1 id="代码实现"><a href="#代码实现" class="headerlink" title="代码实现"></a>代码实现</h1><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><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></pre></td><td class="code"><pre><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment"> * @Author: coder-jason</span></span><br><span class="line"><span class="comment"> * @Date: 2022-05-1 09:00:42</span></span><br><span class="line"><span class="comment"> * @LastEditTime: 2022-05-01 09:13:49</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><bits/stdc++.h></span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std; </span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">cal</span><span class="params">(<span class="type">long</span> <span class="type">long</span> n)</span> </span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line"> <span class="keyword">if</span> (n == <span class="number">1</span>)</span><br><span class="line"> <span class="keyword">return</span> <span class="number">1</span>;</span><br><span class="line"> <span class="keyword">if</span> (n % <span class="number">2</span>)</span><br><span class="line"> <span class="keyword">return</span> <span class="number">1</span> + <span class="built_in">cal</span>(<span class="number">3</span> * n + <span class="number">1</span>);</span><br><span class="line"> <span class="keyword">else</span></span><br><span class="line"> <span class="number">1</span> + <span class="built_in">cal</span>(n / <span class="number">2</span>);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line"> <span class="type">int</span> n = <span class="number">0</span>, ans = <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">1</span>; i < <span class="number">1000000</span>; i++)</span><br><span class="line"> {</span><br><span class="line"> <span class="type">int</span> tmp = <span class="built_in">cal</span>(i);</span><br><span class="line"> <span class="keyword">if</span> (tmp > ans)</span><br><span class="line"> {</span><br><span class="line"> n = i;</span><br><span class="line"> ans = tmp;</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> cout << n << endl;</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="string">'''</span></span><br><span class="line"><span class="string">Author: sorrowise</span></span><br><span class="line"><span class="string">Date: 2022-05-1 08:42:30</span></span><br><span class="line"><span class="string">LastEditTime: 2022-05-01 09:13:19</span></span><br><span class="line"><span class="string">'''</span></span><br><span class="line"> </span><br><span class="line">N=<span class="number">10</span>**<span class="number">6</span></span><br><span class="line">d = {}</span><br><span class="line"><span class="keyword">for</span> x <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">2</span>,N):</span><br><span class="line"> i,n = x,<span class="number">0</span></span><br><span class="line"> <span class="keyword">while</span> x != <span class="number">1</span>:</span><br><span class="line"> <span class="keyword">if</span> x < i:</span><br><span class="line"> n = n + d[x]</span><br><span class="line"> <span class="keyword">break</span></span><br><span class="line"> <span class="keyword">elif</span> x % <span class="number">2</span> == <span class="number">0</span>:</span><br><span class="line"> x = x // <span class="number">2</span></span><br><span class="line"> n += <span class="number">1</span></span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> x = (<span class="number">3</span>*x+<span class="number">1</span>) // <span class="number">2</span></span><br><span class="line"> n += <span class="number">2</span></span><br><span class="line"> d[i] = n</span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">max</span>(d,key=d.get))</span><br></pre></td></tr></table></figure><blockquote><p>答案:837799</p></blockquote><hr><p>参考资料:</p><ul><li><span class="exturl" data-url="aHR0cHM6Ly96aHVhbmxhbi56aGlodS5jb20vcC8xMTA0MjkxMTg=">递归算法<i class="fa fa-external-link-alt"></i></span></li><li><span class="exturl" data-url="aHR0cHM6Ly93d3cuY25ibG9ncy5jb20vanlyb3kvcC8xMDI3NDQxNC5odG1s">记忆化搜索算法优化<i class="fa fa-external-link-alt"></i></span></li><li><span class="exturl" data-url="aHR0cHM6Ly9wZS5tZXRhcXVhbnQub3JnL3BlMDE0Lmh0bWw=">longest Collatz sequence<i class="fa fa-external-link-alt"></i></span></li></ul>]]></content>
<summary type="html"><h1 id="Problem-14-Longest-Collatz-sequence"><a href="#Problem-14-Longest-Collatz-sequence" class="headerlink" title="Problem 14 Longest Collatz sequence"></a>Problem 14 Longest Collatz sequence</h1><blockquote>
<p>The following iterative sequence is defined for the set of positive integers:</p>
</blockquote>
<p>$$<br>\large n\rightarrow \frac{n}{2}\ \left ( n\ is\ even \right ) ,n\rightarrow3n+1\ \left ( \ n\ is\ odd \right )<br>$$</p>
<blockquote>
<p>Using the rule above and starting with $13$, we generate the following sequence:</p>
</blockquote>
<p>$$<br>\large 13\rightarrow40\rightarrow20\rightarrow10\rightarrow5\rightarrow16\rightarrow8\rightarrow4\rightarrow2\rightarrow1<br>$$</p>
<blockquote>
<p>It can be seen that this sequence (starting at $13$ and finishing at 1) contains $10$ terms. Although it has not been proved yet (Collatz Problem), it is thought that all starting numbers finish at $1$.<br>Which starting number, under one million, produces the longest chain?<br>NOTE: Once the chain starts the terms are allowed to go above one million.</p>
</blockquote></summary>
<category term="欧拉计划" scheme="https://pdpeng.github.io/categories/%E6%AC%A7%E6%8B%89%E8%AE%A1%E5%88%92/"/>
<category term="ACM" scheme="https://pdpeng.github.io/tags/ACM/"/>
</entry>
<entry>
<title>JDBC 驱动升级到 Version 8.0.28 连接 MySQL 的踩坑记录</title>
<link href="https://pdpeng.github.io/2022/04/29/jdbc-driver-update/"/>
<id>https://pdpeng.github.io/2022/04/29/jdbc-driver-update/</id>
<published>2022-04-29T13:28:10.000Z</published>
<updated>2025-03-10T15:12:25.997Z</updated>
<content type="html"><![CDATA[<blockquote><p>👲👲<font color=#a2a837 size=3>作者主页</font>:🔗<span class="exturl" data-url="aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L20wXzUxMjY5OTYx">杰森的博客<i class="fa fa-external-link-alt"></i></span><br>📒📒<font color=#20b9cd size=3>本文摘要</font>:<strong>升级驱动到 mysql-connector-java 8.0.28 的注意事项</strong><br>💖💖如果本文对您有帮助的话,还请各位小伙伴👍点赞➕收藏⭐➕评论💭支持杰森呀✌️</p></blockquote><center><img src="https://img-blog.csdnimg.cn/a7dead605e9643a58a286a77bd691970.png" width="450"></center><hr><h1 id="🐛问题描述"><a href="#🐛问题描述" class="headerlink" title="🐛问题描述"></a>🐛问题描述</h1><p>升级驱动到 <code>mysql-connector-java 8.0.28</code> 后,部署执行各种报错,但是把连接器切换到 <code>mysql-connector-java-5.1.48</code> 又没有问题,很是疑惑!</p><p>报错的信息大都是无法找到该类、无法连接</p><span id="more"></span><p>主要是配置好了,就没有留截图,大家主要注意和旧版本不同的地方就好</p><p><span class="exturl" data-url="aHR0cHM6Ly9kZXYubXlzcWwuY29tL2Rvd25sb2Fkcy9jb25uZWN0b3Ivai8=">官方下载地址<i class="fa fa-external-link-alt"></i></span></p><p><img src="https://img-blog.csdnimg.cn/2d32b303c6b14e89b312f73a8a96f934.png"></p><p>历经种种艰难险阻,终于是解决了,成功连接,下面给出解决方案</p><h1 id="💡解决方案"><a href="#💡解决方案" class="headerlink" title="💡解决方案"></a>💡解决方案</h1><p>第一种是菜鸟的示例,较为全面;如果感觉比较麻烦,可以使用第二种方案</p><h2 id="1-🔎完整版"><a href="#1-🔎完整版" class="headerlink" title="1.🔎完整版"></a>1.🔎完整版</h2><blockquote><p>这里引用<strong>菜鸟教程</strong>示例</p></blockquote><h3 id="📡1-数据库环境搭建"><a href="#📡1-数据库环境搭建" class="headerlink" title="📡1.数据库环境搭建"></a>📡1.数据库环境搭建</h3><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">-- 建立数据库 demo1</span></span><br><span class="line"><span class="keyword">CREATE</span> DATABASE IF <span class="keyword">NOT</span> <span class="keyword">EXISTS</span> demo1;</span><br><span class="line"></span><br><span class="line"><span class="comment">-- 建立 websites 表</span></span><br><span class="line"><span class="keyword">CREATE</span> <span class="keyword">TABLE</span> websites (</span><br><span class="line"> id <span class="type">int</span>(<span class="number">11</span>) <span class="keyword">NOT</span> <span class="keyword">NULL</span> AUTO_INCREMENT,</span><br><span class="line"> name <span class="type">char</span>(<span class="number">20</span>) <span class="keyword">NOT</span> <span class="keyword">NULL</span> <span class="keyword">DEFAULT</span> <span class="string">''</span> COMMENT <span class="string">'站点名称'</span>,</span><br><span class="line"> url <span class="type">varchar</span>(<span class="number">255</span>) <span class="keyword">NOT</span> <span class="keyword">NULL</span> <span class="keyword">DEFAULT</span> <span class="string">''</span>,</span><br><span class="line"> alexa <span class="type">int</span>(<span class="number">11</span>) <span class="keyword">NOT</span> <span class="keyword">NULL</span> <span class="keyword">DEFAULT</span> <span class="string">'0'</span> COMMENT <span class="string">'Alexa 排名'</span>,</span><br><span class="line"> country <span class="type">char</span>(<span class="number">10</span>) <span class="keyword">NOT</span> <span class="keyword">NULL</span> <span class="keyword">DEFAULT</span> <span class="string">''</span> COMMENT <span class="string">'国家'</span>,</span><br><span class="line"> <span class="keyword">PRIMARY</span> KEY (id)</span><br><span class="line">) ENGINE<span class="operator">=</span>InnoDB AUTO_INCREMENT<span class="operator">=</span><span class="number">10</span> <span class="keyword">DEFAULT</span> CHARSET<span class="operator">=</span>utf8;</span><br><span class="line"></span><br><span class="line"><span class="comment">-- 写入数据</span></span><br><span class="line"><span class="keyword">INSERT</span> <span class="keyword">INTO</span> websites</span><br><span class="line"><span class="keyword">VALUES</span> (<span class="string">'1'</span>, <span class="string">'Google'</span>, <span class="string">'https://www.google.cm/'</span>, <span class="string">'1'</span>, <span class="string">'USA'</span>), </span><br><span class="line">(<span class="string">'2'</span>, <span class="string">'淘宝'</span>, <span class="string">'https://www.taobao.com/'</span>, <span class="string">'13'</span>, <span class="string">'CN'</span>), </span><br><span class="line">(<span class="string">'3'</span>, <span class="string">'菜鸟教程'</span>, <span class="string">'http://www.runoob.com'</span>, <span class="string">'5892'</span>, <span class="string">''</span>), </span><br><span class="line">(<span class="string">'4'</span>, <span class="string">'微博'</span>, <span class="string">'http://weibo.com/'</span>, <span class="string">'20'</span>, <span class="string">'CN'</span>), </span><br><span class="line">(<span class="string">'5'</span>, <span class="string">'Facebook'</span>, <span class="string">'https://www.facebook.com/'</span>, <span class="string">'3'</span>, <span class="string">'USA'</span>);</span><br></pre></td></tr></table></figure><h3 id="📡2-测试类连接"><a href="#📡2-测试类连接" class="headerlink" title="📡2.测试类连接"></a>📡2.测试类连接</h3><blockquote><p>这里最最重要的就是 MySQL 版本的问题,新版更新了驱动类的名称为 <code>com.mysql.cj.jdbc.Driver</code></p></blockquote><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> java.sql.*;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">JDBCTest</span> {</span><br><span class="line"></span><br><span class="line"> <span class="comment">// MySQL 8.0 以下版本 - JDBC 驱动名及数据库 URL</span></span><br><span class="line"> <span class="comment">// static final String JDBC_DRIVER = "com.mysql.jdbc.Driver";</span></span><br><span class="line"> <span class="comment">// static final String DB_URL = "jdbc:mysql://localhost:3306/RUNOOB";</span></span><br><span class="line"></span><br><span class="line"> <span class="comment">// MySQL 8.0 以上版本 - JDBC 驱动名及数据库 URL</span></span><br><span class="line"> <span class="keyword">static</span> <span class="keyword">final</span> <span class="type">String</span> <span class="variable">JDBC_DRIVER</span> <span class="operator">=</span> <span class="string">"com.mysql.cj.jdbc.Driver"</span>;</span><br><span class="line"> <span class="keyword">static</span> <span class="keyword">final</span> <span class="type">String</span> <span class="variable">DB_URL</span> <span class="operator">=</span> <span class="string">"jdbc:mysql://localhost:3306/demo1?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC&useServerPrepStmts=true"</span>;</span><br><span class="line"> <span class="comment">// 注意修改数据库名 </span></span><br><span class="line"></span><br><span class="line"> <span class="comment">// 数据库的用户名与密码,需要根据自己的设置</span></span><br><span class="line"> <span class="keyword">static</span> <span class="keyword">final</span> <span class="type">String</span> <span class="variable">USER</span> <span class="operator">=</span> <span class="string">"your db login name"</span>;</span><br><span class="line"> <span class="keyword">static</span> <span class="keyword">final</span> <span class="type">String</span> <span class="variable">PASS</span> <span class="operator">=</span> <span class="string">"your db password"</span>;</span><br><span class="line"></span><br><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"> <span class="type">Connection</span> <span class="variable">conn</span> <span class="operator">=</span> <span class="literal">null</span>;</span><br><span class="line"> <span class="type">Statement</span> <span class="variable">stmt</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"> <span class="comment">// 注册 JDBC 驱动</span></span><br><span class="line"> Class.forName(JDBC_DRIVER);</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 打开链接</span></span><br><span class="line"> System.out.println(<span class="string">"连接数据库..."</span>);</span><br><span class="line"> conn = DriverManager.getConnection(DB_URL, USER, PASS);</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 执行查询</span></span><br><span class="line"> System.out.println(<span class="string">" 实例化Statement对象..."</span>);</span><br><span class="line"> stmt = conn.createStatement();</span><br><span class="line"> String sql;</span><br><span class="line"> sql = <span class="string">"SELECT id, name, url FROM websites"</span>;</span><br><span class="line"> <span class="type">ResultSet</span> <span class="variable">rs</span> <span class="operator">=</span> stmt.executeQuery(sql);</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 展开结果集数据库</span></span><br><span class="line"> <span class="keyword">while</span> (rs.next()) {</span><br><span class="line"> <span class="comment">// 通过字段检索</span></span><br><span class="line"> <span class="type">int</span> <span class="variable">id</span> <span class="operator">=</span> rs.getInt(<span class="string">"id"</span>);</span><br><span class="line"> <span class="type">String</span> <span class="variable">name</span> <span class="operator">=</span> rs.getString(<span class="string">"name"</span>);</span><br><span class="line"> <span class="type">String</span> <span class="variable">url</span> <span class="operator">=</span> rs.getString(<span class="string">"url"</span>);</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 输出数据</span></span><br><span class="line"> System.out.print(<span class="string">"ID: "</span> + id);</span><br><span class="line"> System.out.print(<span class="string">", 站点名称: "</span> + name);</span><br><span class="line"> System.out.print(<span class="string">", 站点 URL: "</span> + url);</span><br><span class="line"> System.out.print(<span class="string">"\n"</span>);</span><br><span class="line"> }</span><br><span class="line"> <span class="comment">// 完成后关闭</span></span><br><span class="line"> rs.close();</span><br><span class="line"> stmt.close();</span><br><span class="line"> conn.close();</span><br><span class="line"> } <span class="keyword">catch</span> (SQLException se) {</span><br><span class="line"> <span class="comment">// 处理 JDBC 错误</span></span><br><span class="line"> se.printStackTrace();</span><br><span class="line"> } <span class="keyword">catch</span> (Exception e) {</span><br><span class="line"> <span class="comment">// 处理 Class.forName 错误</span></span><br><span class="line"> e.printStackTrace();</span><br><span class="line"> } <span class="keyword">finally</span> {</span><br><span class="line"> <span class="comment">// 关闭资源</span></span><br><span class="line"> <span class="keyword">try</span> {</span><br><span class="line"> <span class="keyword">if</span> (stmt != <span class="literal">null</span>) stmt.close();</span><br><span class="line"> } <span class="keyword">catch</span> (SQLException se2) {</span><br><span class="line"> }<span class="comment">// 什么都不做</span></span><br><span class="line"> <span class="keyword">try</span> {</span><br><span class="line"> <span class="keyword">if</span> (conn != <span class="literal">null</span>) conn.close();</span><br><span class="line"> } <span class="keyword">catch</span> (SQLException se) {</span><br><span class="line"> se.printStackTrace();</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> System.out.println(<span class="string">"Goodbye!"</span>);</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>执行结果,连接成功</p><p><img src="https://img-blog.csdnimg.cn/78091ccf167c4cc5a6f3a8560fd620e9.png"></p><h2 id="2-🔎精简版"><a href="#2-🔎精简版" class="headerlink" title="2.🔎精简版"></a>2.🔎精简版</h2><blockquote><p>上例考虑全面,使用异常较多,为了方便理解,我们简化下代码量</p></blockquote><h3 id="📡1-数据库环境搭建-1"><a href="#📡1-数据库环境搭建-1" class="headerlink" title="📡1.数据库环境搭建"></a>📡1.数据库环境搭建</h3><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">-- 建立数据库 demo1</span></span><br><span class="line"><span class="keyword">CREATE</span> DATABASE IF <span class="keyword">NOT</span> <span class="keyword">EXISTS</span> demo1;</span><br><span class="line"></span><br><span class="line"><span class="comment">-- 建立数据表 accounts</span></span><br><span class="line"><span class="keyword">CREATE</span> <span class="keyword">TABLE</span> accounts (</span><br><span class="line">id <span class="type">int</span>(<span class="number">3</span>) <span class="keyword">NOT</span> <span class="keyword">NULL</span> <span class="keyword">PRIMARY</span> KEY auto_increment,</span><br><span class="line">name <span class="type">varchar</span>(<span class="number">5</span>),</span><br><span class="line">money <span class="type">FLOAT</span>(<span class="number">4</span>,<span class="number">2</span>)</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="keyword">INSERT</span> <span class="keyword">INTO</span> accounts <span class="keyword">VALUES</span>(<span class="string">'1'</span>,<span class="string">'jason'</span>,<span class="string">'10000'</span>),(<span class="string">'2'</span>,<span class="string">'you'</span>,<span class="string">'99999'</span>);</span><br></pre></td></tr></table></figure><h3 id="📡2-测试类连接-1"><a href="#📡2-测试类连接-1" class="headerlink" title="📡2.测试类连接"></a>📡2.测试类连接</h3><blockquote><p>注意版本、资源释放的顺序(最先调用,最后释放,释放顺序和调用顺序相反)</p></blockquote><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line">package com.jason.jdbc;</span><br><span class="line"></span><br><span class="line">import java.sql.<span class="operator">*</span>;</span><br><span class="line"></span><br><span class="line">public class JDBCDemo {</span><br><span class="line"> public <span class="keyword">static</span> void main(String[] args) throws Exception { <span class="operator">/</span><span class="operator">/</span>psvm 快速生成</span><br><span class="line"> <span class="operator">/</span><span class="operator">/</span><span class="number">1.</span> 注册驱动</span><br><span class="line"> Class.forName("com.mysql.cj.jdbc.Driver");</span><br><span class="line"> <span class="operator">/</span><span class="operator">/</span><span class="number">2.</span> 获取连接</span><br><span class="line"> String url <span class="operator">=</span> "jdbc:mysql://localhost:3306/demo1?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC&useServerPrepStmts=true";</span><br><span class="line"> String username <span class="operator">=</span> "your db login name";</span><br><span class="line"> String password <span class="operator">=</span> "your db password";</span><br><span class="line"> Connection conn <span class="operator">=</span> DriverManager.getConnection(url, username, password);</span><br><span class="line"> <span class="operator">/</span><span class="operator">/</span><span class="number">3.</span> 定义<span class="keyword">sql</span></span><br><span class="line"> String <span class="keyword">sql</span> <span class="operator">=</span> "update accounts set money = 1000 where id = 2";</span><br><span class="line"> <span class="operator">/</span><span class="operator">/</span><span class="number">4.</span> 获取执行<span class="keyword">sql</span>的对象 Statement</span><br><span class="line"> Statement stmt <span class="operator">=</span> conn.createStatement();</span><br><span class="line"> <span class="operator">/</span><span class="operator">/</span><span class="number">5.</span> 执行<span class="keyword">sql</span></span><br><span class="line"> <span class="type">int</span> count <span class="operator">=</span> stmt.executeUpdate(<span class="keyword">sql</span>);<span class="operator">/</span><span class="operator">/</span>受影响的行数</span><br><span class="line"> <span class="operator">/</span><span class="operator">/</span><span class="number">6.</span> 处理结果</span><br><span class="line"> System.out.println("Affected rows: "<span class="operator">+</span>count);</span><br><span class="line"> <span class="operator">/</span><span class="operator">/</span><span class="number">7.</span> 释放资源 Statement 和 Connection 注意释放顺序</span><br><span class="line"> stmt.close();</span><br><span class="line"> conn.close();</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>执行结果,连接成功</p><p><img src="https://img-blog.csdnimg.cn/592143e72c284f479d3e4ddd19ea99c5.png"></p><h1 id="📒总结"><a href="#📒总结" class="headerlink" title="📒总结"></a>📒总结</h1><p>毕竟是更新,多少会有一些改动,我们要学会去看更新了什么、学会去官方找解决方案</p><p>比如这次的报错就可以从最新的 jar 包中找到</p><p><img src="https://img-blog.csdnimg.cn/0b7e6fa61ee14f7cb058813ae22cda22.png"></p><p>在 <code>5.x</code> 版本之后,注册驱动的代码可以省略不写,就是这一段</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//1. 注册驱动</span></span><br><span class="line"><span class="comment">//Class.forName("com.mysql.cj.jdbc.Driver");</span></span><br></pre></td></tr></table></figure><p>原因是:驱动 <code>jar</code> 包下,默认 <code>META-INF services</code> 目录下记录了对应驱动类名,无需再次书写</p><p><img src="https://img-blog.csdnimg.cn/99621f3f15a941ac876e212d7dbea355.png"></p><hr><p>可能是我用的版本太老了,跟不上时代的发展辽~~</p><p><img src="https://img-blog.csdnimg.cn/e49ab973b2f04dfda6df8723346227af.gif"></p>]]></content>
<summary type="html"><blockquote>
<p>👲👲<font color=#a2a837 size=3>作者主页</font>:🔗<span class="exturl" data-url="aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L20wXzUxMjY5OTYx">杰森的博客<i class="fa fa-external-link-alt"></i></span><br>📒📒<font color=#20b9cd size=3>本文摘要</font>:<strong>升级驱动到 mysql-connector-java 8.0.28 的注意事项</strong><br>💖💖如果本文对您有帮助的话,还请各位小伙伴👍点赞➕收藏⭐➕评论💭支持杰森呀✌️</p>
</blockquote>
<center><img src="https://img-blog.csdnimg.cn/a7dead605e9643a58a286a77bd691970.png" width="450"></center>
<hr>
<h1 id="🐛问题描述"><a href="#🐛问题描述" class="headerlink" title="🐛问题描述"></a>🐛问题描述</h1><p>升级驱动到 <code>mysql-connector-java 8.0.28</code> 后,部署执行各种报错,但是把连接器切换到 <code>mysql-connector-java-5.1.48</code> 又没有问题,很是疑惑!</p>
<p>报错的信息大都是无法找到该类、无法连接</p></summary>
<category term="Java" scheme="https://pdpeng.github.io/categories/Java/"/>
<category term="Java" scheme="https://pdpeng.github.io/tags/Java/"/>
</entry>
<entry>
<title>快速计算约数的个数——从基础到高级</title>
<link href="https://pdpeng.github.io/2022/04/29/approximate-number-calculate/"/>
<id>https://pdpeng.github.io/2022/04/29/approximate-number-calculate/</id>
<published>2022-04-29T13:27:45.000Z</published>
<updated>2025-03-10T15:12:25.995Z</updated>
<content type="html"><![CDATA[<blockquote><p>题目来源:<span class="exturl" data-url="aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L20wXzUxMjY5OTYxL2FydGljbGUvZGV0YWlscy8xMjQyODIyNjc=">【欧拉计划第 12 题】 高度可除的三角数 Highly divisible triangular number<i class="fa fa-external-link-alt"></i></span></p></blockquote><p>这道题我们在枚举完三角数后,最重要的是去判断何时某个三角数约数的个数大于 500</p><p>下面我们来看下,针对<strong>计算约数的个数</strong>问题,用不同的算法解决,逐步求得最优解</p><span id="more"></span><h1 id="方法-1"><a href="#方法-1" class="headerlink" title="方法 1"></a>方法 1</h1><p>最简单,更是非常容易理解的方法</p><blockquote><p>复杂度:$\large O_{\left ( n^{2} \right )}$</p></blockquote><p>主要思想:定义变量,使其在小于传入判断值的条件下从 1 开始自增,如果判断值和该变量进行<strong>模取</strong>运算后的值为 0,则说明该变量此时的值是判断值得一个约数。那么,程序计数器自增,记录下此值。循环结束后,输出计数器保存的值即为判断值约数的个数</p><p>这种方法优点除易于理解外,怕是没有优点了。缺点当然就是时间复杂度太高,一个值就需要去从 1 一直判断到该值。试想,如果数据量呈指数增长,这种方法恐怕在一般的计算机上不容易很快得到答案</p><p>实现代码如下</p><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="type">int</span> <span class="title">check</span><span class="params">(<span class="type">long</span> <span class="type">long</span> n)</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line"> <span class="type">int</span> count = <span class="number">0</span>;</span><br><span class="line"> <span class="type">long</span> <span class="type">long</span> i = <span class="number">1</span>; <span class="comment">//注意数据范围</span></span><br><span class="line"> <span class="keyword">while</span> (i <= n)</span><br><span class="line"> {</span><br><span class="line"> <span class="keyword">if</span> (n % i == <span class="number">0</span>) <span class="comment">//成立,这说明此时 i 为 n 的一个约数</span></span><br><span class="line"> {</span><br><span class="line"> count++; <span class="comment">//计数器自增</span></span><br><span class="line"> }</span><br><span class="line"> i++; <span class="comment">//继续判断下一个数字是否为 i 的约数</span></span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> count;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h1 id="方法-2"><a href="#方法-2" class="headerlink" title="方法 2"></a>方法 2</h1><blockquote><p>复杂度:$\large O_{\left ( \sqrt{n} \right )}$</p></blockquote><p>主要思想:对比可以看出,方法一和方法二差别不大,但影响最关键的是它们的复杂度,直接由 $O_{\left ( n^{2} \right )}$ 降至 $O_{\left ( \sqrt{n} \right )}$ </p><p>同样,仍然是<strong>暴力枚举</strong>,只不过这里的判断条件由 <code>i < = n</code> 变为 <code>i * i < = n</code>,复杂度优化了些许。进入 <code>for()</code> 循环后,如果 <code>n % i == 0</code> ,那么说明此时的 <code>i</code> 值是 <code>n</code> 的一个约数</p><p>大家在这里要注意的是 <code>if...else</code> 语句内容,这里主要解释下此处和方法一的差别</p><p>举个例子,如果 <code>n = 4</code> ,<code>i = 2</code>,满足 <code>2 × 2 = 4</code> 的条件,但此时 <code>4</code> 的两个约数 <code>2</code> 相当于一个,程序计数器只能自增 <code>1</code> ,而不是 <code>2</code></p><p>当然,如果进入 <code>for()</code> 循环后,不满足条件 <code>i * i = n</code> ,那么自然是两个不同的约数,此时程序计数器需要增加 <code>2</code>,而不是 <code>1</code></p><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><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="function"><span class="type">int</span> <span class="title">check</span><span class="params">(<span class="type">long</span> <span class="type">long</span> n)</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line"> <span class="type">int</span> count = <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">for</span> (<span class="type">long</span> <span class="type">long</span> i = <span class="number">1</span>; i * i <= n; i++)</span><br><span class="line"> {</span><br><span class="line"> <span class="keyword">if</span> (n % i == <span class="number">0</span>)</span><br><span class="line"> {</span><br><span class="line"> <span class="keyword">if</span> (i * i == n) <span class="comment">// 区别所在,重点理解</span></span><br><span class="line"> count++;</span><br><span class="line"> <span class="keyword">else</span></span><br><span class="line"> count += <span class="number">2</span>;</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> count;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h1 id="方法-3"><a href="#方法-3" class="headerlink" title="方法 3"></a>方法 3</h1><blockquote><p><strong>试除法</strong>求解</p></blockquote><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><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="function">vector<<span class="type">int</span>> <span class="title">get_divisors</span><span class="params">(<span class="type">int</span> n)</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line"> vector<<span class="type">int</span>> res;</span><br><span class="line"> <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">1</span>; i <= n / i; i++)</span><br><span class="line"> <span class="keyword">if</span> (n % i == <span class="number">0</span>)</span><br><span class="line"> {</span><br><span class="line"> res.<span class="built_in">push_back</span>(i);</span><br><span class="line"> <span class="keyword">if</span> (i != n / i)</span><br><span class="line"> res.<span class="built_in">push_back</span>(n / i);</span><br><span class="line"> }</span><br><span class="line"> <span class="built_in">sort</span>(res.<span class="built_in">begin</span>(), res.<span class="built_in">end</span>());</span><br><span class="line"> <span class="keyword">return</span> res;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>LeetCode <span class="exturl" data-url="aHR0cHM6Ly9sZWV0Y29kZS1jbi5jb20vcHJvYmxlbXMvZm91ci1kaXZpc29ycy9zb2x1dGlvbi9zaGktY2h1LWZhLXFpdS15dWUtc2h1LWdlLXNodS15dWUtc2h1LXpoaS1oZS1ieS1obC8=">题解思路<i class="fa fa-external-link-alt"></i></span></p><h1 id="方法四"><a href="#方法四" class="headerlink" title="方法四"></a>方法四</h1><p><strong>约数个数定理</strong></p><p>设一个数可以表示为其素数幂的乘积,即:</p><p>$$<br>\large n={p_{1}}^{e_{1}} \cdot {p_{2}}^{e_{2}} \cdot\cdot\cdot {p_{m}}^{e_{m}}<br>$$</p><p>则该数的约数个数为:</p><p>$$<br>\large \left ( e_{1}+1 \right )\cdot \left ( e_{2}+1 \right )\cdot \cdot \cdot \left ( e_{m}+1 \right )<br>$$</p><p>参考代码:</p><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><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></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><bits/stdc++.h></span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line"> <span class="type">int</span> N, n, i, s, r;</span><br><span class="line"> <span class="keyword">while</span> (<span class="built_in">scanf</span>(<span class="string">"%d"</span>, &N) != EOF)</span><br><span class="line"> {</span><br><span class="line"> <span class="keyword">while</span> (N--)</span><br><span class="line"> {</span><br><span class="line"> cin >> n;</span><br><span class="line"> s = <span class="number">1</span>;</span><br><span class="line"> <span class="keyword">for</span> (i = <span class="number">2</span>; i * i <= n; i++)</span><br><span class="line"> {</span><br><span class="line"> r = <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">while</span> (n % i == <span class="number">0</span>)</span><br><span class="line"> {</span><br><span class="line"> r++;</span><br><span class="line"> n /= i;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span> (r > <span class="number">0</span>)</span><br><span class="line"> {</span><br><span class="line"> r++;</span><br><span class="line"> s *= r;</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span> (n > <span class="number">1</span>)</span><br><span class="line"> s *= <span class="number">2</span>;</span><br><span class="line"> cout << s;</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html"><blockquote>
<p>题目来源:<span class="exturl" data-url="aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L20wXzUxMjY5OTYxL2FydGljbGUvZGV0YWlscy8xMjQyODIyNjc=">【欧拉计划第 12 题】 高度可除的三角数 Highly divisible triangular number<i class="fa fa-external-link-alt"></i></span></p>
</blockquote>
<p>这道题我们在枚举完三角数后,最重要的是去判断何时某个三角数约数的个数大于 500</p>
<p>下面我们来看下,针对<strong>计算约数的个数</strong>问题,用不同的算法解决,逐步求得最优解</p></summary>
<category term="数据结构与算法" scheme="https://pdpeng.github.io/categories/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E4%B8%8E%E7%AE%97%E6%B3%95/"/>
<category term="ACM" scheme="https://pdpeng.github.io/tags/ACM/"/>
</entry>
<entry>
<title>SQL 基础(九)视图与索引实战演练</title>
<link href="https://pdpeng.github.io/2022/04/29/sql-base9/"/>
<id>https://pdpeng.github.io/2022/04/29/sql-base9/</id>
<published>2022-04-29T04:12:08.000Z</published>
<updated>2025-03-10T15:12:26.000Z</updated>
<content type="html"><![CDATA[<h1 id="实验任务-1"><a href="#实验任务-1" class="headerlink" title="实验任务 1"></a>实验任务 1</h1><blockquote><p>在 <code>studen</code> 数据库中,以 <code>tb_student</code>、<code>tb_course</code> 和 <code>tb_score</code> 表为基础完成下列视图的设计与创建</p></blockquote><h1 id="表结构"><a href="#表结构" class="headerlink" title="表结构"></a>表结构</h1><ul><li>tb_student(sno,sn,dept,sex,birthday,polity)</li><li>tb_score(sno,cno,score)</li><li>tb_cource(cno,cn,ct,th)<span id="more"></span><h1 id="任务题解"><a href="#任务题解" class="headerlink" title="任务题解"></a>任务题解</h1><h1 id="任务一"><a href="#任务一" class="headerlink" title="任务一"></a>任务一</h1></li></ul><blockquote><p>创建学生的基本情况视图 V_STU。</p></blockquote><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">CREATE</span> <span class="keyword">VIEW</span> V_STU</span><br><span class="line"><span class="keyword">AS</span></span><br><span class="line"><span class="keyword">SELECT</span> <span class="operator">*</span></span><br><span class="line"><span class="keyword">FROM</span> tb_student</span><br><span class="line"></span><br><span class="line"><span class="keyword">SELECT</span> <span class="operator">*</span> <span class="keyword">FROM</span> V_STU</span><br></pre></td></tr></table></figure><h1 id="任务二"><a href="#任务二" class="headerlink" title="任务二"></a>任务二</h1><blockquote><p>创建视图 V_Sco,显示学生成绩信息。</p></blockquote><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">CREATE</span> <span class="keyword">VIEW</span> V_Sco</span><br><span class="line"><span class="keyword">AS</span></span><br><span class="line"><span class="keyword">SELECT</span> sno,score</span><br><span class="line"><span class="keyword">FROM</span> tb_score</span><br><span class="line"></span><br><span class="line"><span class="keyword">SELECT</span> <span class="operator">*</span> <span class="keyword">FROM</span> V_Sco</span><br></pre></td></tr></table></figure><h1 id="任务三"><a href="#任务三" class="headerlink" title="任务三"></a>任务三</h1><blockquote><p>创建视图 V_SCORE, 要求只显示学生的学号、姓名、系别、课号、课程名称及成绩。</p></blockquote><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">CREATE</span> <span class="keyword">VIEW</span> V_SCORE</span><br><span class="line"><span class="keyword">AS</span></span><br><span class="line"><span class="keyword">SELECT</span> s.sno,sn,dept,sc.cno,cn,score</span><br><span class="line"><span class="keyword">FROM</span> tb_student s,tb_score sc,tb_course co</span><br><span class="line"><span class="keyword">WHERE</span> s.sno<span class="operator">=</span>sc.sno <span class="keyword">AND</span> sc.cno<span class="operator">=</span>co.cno</span><br><span class="line"></span><br><span class="line"><span class="keyword">SELECT</span> <span class="operator">*</span> <span class="keyword">FROM</span> V_SCORE</span><br></pre></td></tr></table></figure><h1 id="任务四"><a href="#任务四" class="headerlink" title="任务四"></a>任务四</h1><blockquote><p>各系学生人数、平均年龄创建视图 V_NUM_AVG。</p></blockquote><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">CREATE</span> <span class="keyword">VIEW</span> V_NUM_AVG</span><br><span class="line"><span class="keyword">AS</span></span><br><span class="line"><span class="keyword">SELECT</span> dept,<span class="built_in">COUNT</span>(<span class="operator">*</span>) <span class="keyword">AS</span> 学生人数, <span class="comment">-- 同时包含聚合函数和基本字段,需要分组 GROUP BY</span></span><br><span class="line"><span class="built_in">AVG</span>(<span class="keyword">year</span>(GETDATE())<span class="operator">-</span><span class="keyword">year</span>(birthday)) <span class="keyword">AS</span> 平均年龄</span><br><span class="line"><span class="keyword">FROM</span> tb_student</span><br><span class="line"><span class="keyword">GROUP</span> <span class="keyword">BY</span> dept</span><br><span class="line"></span><br><span class="line"><span class="keyword">SELECT</span> <span class="operator">*</span> <span class="keyword">FROM</span> V_NUM_AVG</span><br><span class="line"></span><br></pre></td></tr></table></figure><h1 id="任务五"><a href="#任务五" class="headerlink" title="任务五"></a>任务五</h1><blockquote><p>创建一个反映学生出生年份的视图 V_YEAR。</p></blockquote><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">CREATE</span> <span class="keyword">VIEW</span> V_YEAR</span><br><span class="line"><span class="keyword">AS</span></span><br><span class="line"><span class="keyword">SELECT</span> sno,sn,<span class="keyword">YEAR</span>(birthday) <span class="keyword">AS</span> 出生年份 <span class="comment">-- 计算公式</span></span><br><span class="line"><span class="keyword">FROM</span> tb_student</span><br><span class="line"></span><br><span class="line"><span class="keyword">SELECT</span> <span class="operator">*</span> <span class="keyword">FROM</span> V_YEAR</span><br></pre></td></tr></table></figure><h1 id="任务六"><a href="#任务六" class="headerlink" title="任务六"></a>任务六</h1><blockquote><p>将各位学生选修课程的门数及平均成绩创建视图 V_AVG_S_G。</p></blockquote><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">CREATE</span> <span class="keyword">VIEW</span> V_AVG_S_G</span><br><span class="line"><span class="keyword">AS</span></span><br><span class="line"><span class="keyword">SELECT</span> sno,<span class="built_in">COUNT</span>(<span class="operator">*</span>) 选修课程数,<span class="built_in">AVG</span>(score) 平均分 </span><br><span class="line"><span class="keyword">FROM</span> tb_score</span><br><span class="line"><span class="keyword">GROUP</span> <span class="keyword">BY</span> sno</span><br><span class="line"></span><br><span class="line"><span class="keyword">SELECT</span> <span class="operator">*</span> <span class="keyword">FROM</span> V_AVG_S_G</span><br></pre></td></tr></table></figure><h1 id="任务七"><a href="#任务七" class="headerlink" title="任务七"></a>任务七</h1><blockquote><p>将各门课程的选修人数及平均成绩创建视图 V_AVG_C_G。</p></blockquote><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">CREATE</span> <span class="keyword">VIEW</span> V_AVG_C_G</span><br><span class="line"><span class="keyword">AS</span></span><br><span class="line"><span class="keyword">SELECT</span> cno,<span class="built_in">COUNT</span>(<span class="operator">*</span>) 课程选修人数,<span class="built_in">AVG</span>(score) 平均成绩</span><br><span class="line"><span class="keyword">FROM</span> tb_score</span><br><span class="line"><span class="keyword">GROUP</span> <span class="keyword">BY</span> cno</span><br><span class="line"></span><br><span class="line"><span class="keyword">SELECT</span> <span class="operator">*</span> <span class="keyword">FROM</span> V_AVG_C_G</span><br></pre></td></tr></table></figure><h1 id="任务八"><a href="#任务八" class="headerlink" title="任务八"></a>任务八</h1><blockquote><p>创建视图 V_YEAR_RJ,显示软件工程系出生日期在 2001 年之后出生的学生信息。</p></blockquote><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">CREATE</span> <span class="keyword">VIEW</span> V_YEAR_RJ</span><br><span class="line"><span class="keyword">AS</span></span><br><span class="line"><span class="keyword">SELECT</span> <span class="operator">*</span> </span><br><span class="line"><span class="keyword">FROM</span> tb_student</span><br><span class="line"><span class="keyword">WHERE</span> major<span class="operator">=</span><span class="string">'软件工程'</span> <span class="keyword">AND</span> <span class="keyword">YEAR</span>(birthday)<span class="operator">></span><span class="number">2001</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">SELECT</span> <span class="operator">*</span> <span class="keyword">FROM</span> V_YEAR_RJ</span><br></pre></td></tr></table></figure><h1 id="任务九"><a href="#任务九" class="headerlink" title="任务九"></a>任务九</h1><blockquote><p>基于视图 V_STU,创建视图 V_SEX,查看男党员的信息。</p></blockquote><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">CREATE</span> <span class="keyword">VIEW</span> V_SEX</span><br><span class="line"><span class="keyword">AS</span></span><br><span class="line"><span class="keyword">SELECT</span> <span class="operator">*</span> <span class="keyword">FROM</span> V_STU</span><br><span class="line"><span class="keyword">WHERE</span> sex<span class="operator">=</span><span class="string">'男'</span> <span class="keyword">AND</span> polity<span class="operator">=</span><span class="string">'党员'</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">SELECT</span> <span class="operator">*</span> <span class="keyword">FROM</span> V_SEX</span><br></pre></td></tr></table></figure><h1 id="任务十"><a href="#任务十" class="headerlink" title="任务十"></a>任务十</h1><blockquote><p> 修改视图 V_YEAR,显示软件工程系出生日期在 2000 年之前出生的学生信息,并删除视图 V_YEAR。</p></blockquote><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">ALTER</span> <span class="keyword">VIEW</span> V_YEAR</span><br><span class="line"><span class="keyword">AS</span></span><br><span class="line"><span class="keyword">SELECT</span> <span class="operator">*</span> <span class="keyword">FROM</span> tb_student</span><br><span class="line"><span class="keyword">WHERE</span> dept<span class="operator">=</span><span class="string">'软件工程'</span> <span class="keyword">AND</span> <span class="keyword">YEAR</span>(birthday) <span class="operator"><</span> <span class="number">2002</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">SELECT</span> <span class="operator">*</span> <span class="keyword">FROM</span> V_YEAR</span><br><span class="line"></span><br><span class="line"><span class="keyword">DROP</span> <span class="keyword">VIEW</span> V_YEAR</span><br></pre></td></tr></table></figure><h1 id="任务十一"><a href="#任务十一" class="headerlink" title="任务十一"></a>任务十一</h1><blockquote><p>向视图 V_Sco 中添加学号为‘xxx’,课程号为‘10002’,成绩为87 的信息。</p></blockquote><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">INSERT</span> <span class="keyword">INTO</span> V_Sco(sno,cno,score)</span><br><span class="line"><span class="keyword">VALUES</span>(<span class="string">'xxx'</span>,<span class="string">'10002'</span>,<span class="number">87</span>)</span><br></pre></td></tr></table></figure><h1 id="任务十二"><a href="#任务十二" class="headerlink" title="任务十二"></a>任务十二</h1><blockquote><p>修改视图 V_Sco,将学号为‘XXX’的学生,选修的课程号为10002 的成绩更改为 90。</p></blockquote><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">UPDATE</span> <span class="keyword">VIEW</span> V_Sco <span class="comment">-- 修改值,实质为更新视图,关键字 UPDATE</span></span><br><span class="line"><span class="keyword">SET</span> score<span class="operator">=</span><span class="number">90</span></span><br><span class="line"><span class="keyword">WHERE</span> sno<span class="operator">=</span><span class="string">'XXX'</span> <span class="keyword">AND</span> cno<span class="operator">=</span><span class="string">'10002'</span></span><br></pre></td></tr></table></figure><h1 id="任务十三"><a href="#任务十三" class="headerlink" title="任务十三"></a>任务十三</h1><blockquote><p>在视图 V_Sco 中,将学号为‘XXX’的学生,选修的课程号为10002 的记录删除。</p></blockquote><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">DELETE</span> <span class="keyword">FROM</span> V_Sco</span><br><span class="line"><span class="keyword">WHERE</span> sno<span class="operator">=</span><span class="string">'XXX'</span> <span class="keyword">AND</span> cno<span class="operator">=</span><span class="string">'10002'</span></span><br></pre></td></tr></table></figure><h1 id="任务十四"><a href="#任务十四" class="headerlink" title="任务十四"></a>任务十四</h1><blockquote><p>查询以上所建视图结果 </p></blockquote><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><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="comment">-- (1) 查询平均成绩为 90 分以上的学生的学号、姓名和成绩。</span></span><br><span class="line"><span class="comment">-- method1</span></span><br><span class="line"><span class="keyword">SELECT</span> sno,sn,score</span><br><span class="line"><span class="keyword">FROM</span> v_score</span><br><span class="line"><span class="keyword">WHERE</span> sno <span class="keyword">in</span>(<span class="keyword">SELECT</span> sno </span><br><span class="line"> <span class="keyword">FROM</span> V_AVG_S_G</span><br><span class="line"> <span class="keyword">WHERE</span> 平均分<span class="operator">></span><span class="number">85</span>)</span><br><span class="line"> </span><br><span class="line"><span class="comment">-- method2</span></span><br><span class="line"><span class="keyword">SELECT</span> s.sno,s.sn,score</span><br><span class="line"><span class="keyword">FROM</span> v_score s,v_avg_s_g s2</span><br><span class="line"><span class="keyword">WHERE</span> s.sno<span class="operator">=</span>s2.sno <span class="keyword">AND</span> s2.平均分<span class="operator">></span><span class="number">85</span></span><br><span class="line"></span><br><span class="line"><span class="comment">-- (2) 查询各课程成绩均大于平均成绩的学生的学号、姓名、课程和成绩。</span></span><br><span class="line"><span class="keyword">SELECT</span> sno,sn,cno,score</span><br><span class="line"><span class="keyword">FROM</span> v_score</span><br><span class="line"><span class="keyword">WHERE</span> score<span class="operator">></span><span class="keyword">ANY</span>(<span class="keyword">SELECT</span> 平均分 <span class="keyword">FROM</span> v_avg_c_g)</span><br><span class="line"></span><br><span class="line"><span class="comment">-- (3) 按系别统计各系平均成绩在 80 分以上的人数,结果按降序排列。</span></span><br><span class="line"><span class="comment">-- method1</span></span><br><span class="line"><span class="keyword">SELECT</span> dept 系别,<span class="built_in">COUNT</span>(<span class="operator">*</span>) 总人数</span><br><span class="line"><span class="keyword">FROM</span> v_stu</span><br><span class="line"><span class="keyword">WHERE</span> sno <span class="keyword">IN</span>(<span class="keyword">SELECT</span> sno </span><br><span class="line"> <span class="keyword">FROM</span> v_avg_s_g</span><br><span class="line"> <span class="keyword">WHERE</span> 平均分 <span class="operator">></span> <span class="number">80</span>)</span><br><span class="line"><span class="keyword">GROUP</span> <span class="keyword">BY</span> dept</span><br><span class="line"><span class="keyword">ORDER</span> <span class="keyword">BY</span> 人数 <span class="keyword">DESC</span></span><br><span class="line"></span><br><span class="line"><span class="comment">-- method2</span></span><br><span class="line"><span class="keyword">SELECT</span> dept,<span class="built_in">COUNT</span>(<span class="operator">*</span>) 人数</span><br><span class="line"><span class="keyword">from</span> v_stu s,v_avg_s_g s2</span><br><span class="line"><span class="keyword">WHERE</span> s.sno<span class="operator">=</span>s2.sno <span class="keyword">AND</span> s2.平均分 <span class="operator">></span> <span class="number">80</span></span><br><span class="line"><span class="keyword">GROUP</span> <span class="keyword">BY</span> dept</span><br><span class="line"><span class="keyword">ORDER</span> <span class="keyword">BY</span> 人数 <span class="keyword">DESC</span></span><br></pre></td></tr></table></figure><h1 id="实验任务-2"><a href="#实验任务-2" class="headerlink" title="实验任务 2"></a>实验任务 2</h1><blockquote><p>在 <code>student</code> 数据库中,以 <code>tb_student</code>、<code>tb_course</code> 和 <code>tb_score</code> 表为基础完成下列索引的设计与创建。</p></blockquote><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">-- (1) 对学生信息表 tb_student 中的学号 sno 创建聚集索引,并按降序排列。</span></span><br><span class="line"><span class="keyword">CREATE</span> CLUSTERED INDEX IX_SNO <span class="keyword">ON</span> tb_student(sno <span class="keyword">DESC</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment">-- (2) 对学生成绩信息表 tb_score 先按上课编号 cno 升序排列,再按学生成绩 score 降序排列。</span></span><br><span class="line"><span class="keyword">SELECT</span> cno,score</span><br><span class="line"><span class="keyword">FROM</span> tb_score</span><br><span class="line"><span class="keyword">ORDER</span> <span class="keyword">BY</span> cno <span class="keyword">ASC</span> ,score <span class="keyword">desc</span></span><br><span class="line"></span><br><span class="line"><span class="comment">-- (3) 对课程信息表 tb_course 中的课程编号创建唯一索引,并按升序排列。</span></span><br><span class="line"><span class="keyword">CREATE</span> <span class="keyword">UNIQUE</span> INDEX IX_CNO <span class="keyword">ON</span> tb_course(cno <span class="keyword">ASC</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment">-- (4) 在 tb_student 表中的 sn 列创建唯一索引</span></span><br><span class="line"><span class="keyword">CREATE</span> CLUSTERED INDEX IX_SN <span class="keyword">ON</span> tb_student(sn)</span><br></pre></td></tr></table></figure><hr><h1 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h1><p><strong>1.查看与删除索引</strong></p><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></pre></td><td class="code"><pre><span class="line"><span class="comment">-- 查看索引</span></span><br><span class="line">Sp_helpindex name <span class="comment">-- name:数据库表名</span></span><br><span class="line"></span><br><span class="line"><span class="comment">-- 删除索引的方式</span></span><br><span class="line"><span class="comment">-- method1</span></span><br><span class="line"><span class="keyword">DROP</span> INDEX <span class="operator"><</span><span class="keyword">table</span> <span class="keyword">or</span> <span class="keyword">view</span> name<span class="operator">></span>.<span class="operator"><</span>index name<span class="operator">></span></span><br><span class="line"></span><br><span class="line"><span class="comment">-- method2</span></span><br><span class="line"><span class="keyword">DROP</span> INDEX <span class="operator"><</span>index name<span class="operator">></span> <span class="keyword">ON</span> <span class="operator"><</span><span class="keyword">table</span> <span class="keyword">or</span> <span class="keyword">view</span> name<span class="operator">></span></span><br></pre></td></tr></table></figure><p><strong>2.索引类型</strong></p><table><thead><tr><th>类型名称</th><th>关键字</th></tr></thead><tbody><tr><td>普通索引</td><td><code>INDEX</code></td></tr><tr><td>唯一索引</td><td><code>UNIQUE INDEX</code></td></tr><tr><td>聚集索引</td><td><code>CLUSTERED INDEX</code></td></tr><tr><td>非聚集索引</td><td><code>NONCLUSTERED INDEX</code></td></tr><tr><td>全文索引</td><td><code>FULLTEXT</code></td></tr></tbody></table><p><strong>3.索引分析</strong></p><p>索引相当于一本书的目录,优缺点分析如下:</p><p>虽然索引很大程度上提高了查询速度,但同时也会降低更新表的速度,如:对表进行 <code>insert</code>、<code>update</code> 和 <code>delete</code>。这是因为更新表时,不仅要保存数据,还要保存一下索引文件</p><p>索引只是提高效率的一个因素,如果有大数据量的表,则需要花时间研究建立最优秀的索引,或优化查询语句</p><p>建立索引会占用磁盘空间的索引文件。如果在一个大表上创建了多种组合索引,索引文件的增速会很快</p><p><strong>4.查看视图创建源码</strong></p><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">Sp_helptext name <span class="comment">-- name:视图名</span></span><br></pre></td></tr></table></figure>]]></content>
<summary type="html"><h1 id="实验任务-1"><a href="#实验任务-1" class="headerlink" title="实验任务 1"></a>实验任务 1</h1><blockquote>
<p>在 <code>studen</code> 数据库中,以 <code>tb_student</code>、<code>tb_course</code> 和 <code>tb_score</code> 表为基础完成下列视图的设计与创建</p>
</blockquote>
<h1 id="表结构"><a href="#表结构" class="headerlink" title="表结构"></a>表结构</h1><ul>
<li>tb_student(sno,sn,dept,sex,birthday,polity)</li>
<li>tb_score(sno,cno,score)</li>
<li>tb_cource(cno,cn,ct,th)</summary>
<category term="数据库原理" scheme="https://pdpeng.github.io/categories/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%8E%9F%E7%90%86/"/>
<category term="SQLServer" scheme="https://pdpeng.github.io/tags/SQLServer/"/>
</entry>
<entry>
<title>【玩转 RT-Thread】 RT-Thread Studio —— 按键控制电机正反转、蜂鸣器</title>
<link href="https://pdpeng.github.io/2022/04/28/rt-thread01/"/>
<id>https://pdpeng.github.io/2022/04/28/rt-thread01/</id>
<published>2022-04-28T12:08:02.000Z</published>
<updated>2025-03-10T15:12:25.998Z</updated>
<content type="html"><![CDATA[<h1 id="初识RT-Thread"><a href="#初识RT-Thread" class="headerlink" title="初识RT-Thread"></a>初识RT-Thread</h1><p><code>做世界级的 OS,让万物互联,信息畅通无阻。</code><br><code>成为未来 AIoT 领域最为主流的操作系统平台。</code></p><h2 id="简介"><a href="#简介" class="headerlink" title="简介"></a>简介</h2><blockquote><p>RT-Thread 是一个集<code>实时操作系统(RTOS)内核、中间件组件和开发者社区于一体</code>的技术平台,由<code>熊谱翔先生</code>带领并集合开源社区力量开发而成,RT-Thread 也是一个<code>组件完整丰富、高度可伸缩、简易开发、超低功耗、高安全性</code>的<code>物联网操作系统</code>。</p></blockquote><h2 id="前景"><a href="#前景" class="headerlink" title="前景"></a>前景</h2><blockquote><p>RT-Thread 具备一个 IoT OS 平台所需的所有关键组件,例如GUI、网络协议栈、安全传输、低功耗组件等等。经过11年的累积发展,RT-Thread 已经拥有一个<code>国内最大的嵌入式开源社区</code>,同时被广泛应用于能源、车载、医疗、消费电子等多个行业,累积装机量超过 14亿 台,成为国人<code>自主开发</code>、国内最成熟稳定和装机量最大的<code>开源 RTOS</code>。</p></blockquote><h2 id="软件生态"><a href="#软件生态" class="headerlink" title="软件生态"></a>软件生态</h2><blockquote><p>RT-Thread 拥有<code>良好的软件生态</code>,支持市面上所有主流的编译工具如 GCC、Keil、IAR 等,工具链完善、友好,支持各类标准接口,如 POSIX、CMSIS、C++应用环境、Javascript 执行环境等,方便开发者移植各类应用程序。商用支持所有主流MCU架构,如 ARM Cortex-M/R/A, MIPS, X86, Xtensa, C-Sky, RISC-V,几乎支持市场上所有主流的 MCU 和 Wi-Fi 芯片。</p></blockquote><span id="more"></span><h1 id="实验准备"><a href="#实验准备" class="headerlink" title="实验准备"></a>实验准备</h1><ul><li>编程工具:<code>RT-Thread studio</code></li><li>开发板:<code>潘多拉STM32L475</code></li></ul><h1 id="实验需求"><a href="#实验需求" class="headerlink" title="实验需求"></a>实验需求</h1><ul><li>1.使用按键控制蜂鸣器和电机,当按下KEY0 后电机左转,当按下KEY1 后电机<br>右转,当按下KEY2 后电机停止,当按住WK_UP 时蜂鸣器鸣叫,松开WK_UP 后蜂鸣器关闭。</li><li>2.其中KEY0 KEY1 KEY2 三个按键会触发中断,通过pin 设备的中断回调函数控制电机,WK_UP 按键通过轮询的方式控制蜂鸣器鸣叫。</li></ul><h1 id="操作流程"><a href="#操作流程" class="headerlink" title="操作流程"></a>操作流程</h1><h2 id="新建RT-Thread工程"><a href="#新建RT-Thread工程" class="headerlink" title="新建RT-Thread工程"></a>新建RT-Thread工程</h2><p><img src="https://img-blog.csdnimg.cn/85370c1057554323ba75dd83c3d1844f.png"></p><h2 id="RT-Thread-Studio界面介绍"><a href="#RT-Thread-Studio界面介绍" class="headerlink" title="RT-Thread Studio界面介绍"></a>RT-Thread Studio界面介绍</h2><p><img src="https://img-blog.csdnimg.cn/b24064da660f40b5b00e9e0f03d4f1ff.png"></p><h2 id="代码编写"><a href="#代码编写" class="headerlink" title="代码编写"></a>代码编写</h2><p><img src="https://img-blog.csdnimg.cn/c556436b0d44443686dafa3a0f389bd5.png"></p><h2 id="烧录"><a href="#烧录" class="headerlink" title="烧录"></a>烧录</h2><p><img src="https://img-blog.csdnimg.cn/c5ea1524e61e4b92af667e17decd12bb.png"></p><h2 id="串口监视"><a href="#串口监视" class="headerlink" title="串口监视"></a>串口监视</h2><p><img src="https://img-blog.csdnimg.cn/eae3d5a76ae14aa0a7e6a2d00145024d.png"></p><h1 id="代码演示"><a href="#代码演示" class="headerlink" title="代码演示"></a>代码演示</h1><p><code>1.头文件</code></p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><rtthread.h></span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><rtdevice.h></span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><board.h></span></span></span><br></pre></td></tr></table></figure><p><code>2.宏定义</code></p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><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="comment">//按键初始化</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> PIN_KEY0 GET_PIN(D, 10) <span class="comment">// PD10: KEY0 --> KEY</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> PIN_KEY1 GET_PIN(D, 9) <span class="comment">// PD9: KEY1 --> KEY</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> PIN_KEY2 GET_PIN(D, 8) <span class="comment">// PD8: KEY2 --> KEY</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> PIN_WK_UP GET_PIN(C,13)<span class="comment">//PC13:WK_UP</span></span></span><br><span class="line"></span><br><span class="line"><span class="comment">//电机初始化</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> PIN_MOTOR_A GET_PIN(A,1)<span class="comment">//PA1:MOTOR_A</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> PIN_MOTOR_B GET_PIN(A,0)<span class="comment">//PA0:MOTOR_B</span></span></span><br><span class="line"></span><br><span class="line"><span class="comment">//蜂鸣器初始化</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> PIN_BEEP GET_PIN(B,2)<span class="comment">//PB2:BEEP</span></span></span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">enum</span></span></span><br><span class="line"><span class="class">{</span></span><br><span class="line"> MOTOR_STOP,</span><br><span class="line"> MOTOR_LEFT,</span><br><span class="line"> MOTOR_RIGHT</span><br><span class="line">};</span><br></pre></td></tr></table></figure><p><code>3.void motor_ctrl(rt_uint8_t turn) //电机控制函数</code></p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">void</span> <span class="title function_">motor_ctrl</span><span class="params">(<span class="type">rt_uint8_t</span> turn)</span></span><br><span class="line">{</span><br><span class="line"> <span class="keyword">if</span> (turn == MOTOR_STOP)</span><br><span class="line"> {</span><br><span class="line"> rt_pin_write(PIN_MOTOR_A, PIN_LOW);</span><br><span class="line"> rt_pin_write(PIN_MOTOR_B, PIN_LOW);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">else</span> <span class="keyword">if</span> (turn == MOTOR_LEFT)</span><br><span class="line"> {</span><br><span class="line"> rt_pin_write(PIN_MOTOR_A, PIN_LOW);</span><br><span class="line"> rt_pin_write(PIN_MOTOR_B, PIN_HIGH);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">else</span> <span class="keyword">if</span> (turn == MOTOR_RIGHT)</span><br><span class="line"> {</span><br><span class="line"> rt_pin_write(PIN_MOTOR_A, PIN_HIGH);</span><br><span class="line"> rt_pin_write(PIN_MOTOR_B, PIN_LOW);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">else</span></span><br><span class="line"> {</span><br><span class="line"> rt_kprintf(<span class="string">"err parameter ! Please enter 0-2."</span>);</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p><code>4.void beep_ctrl(rt_uint8_t on) //蜂鸣器控制函数</code></p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">void</span> <span class="title function_">beep_ctrl</span><span class="params">(<span class="type">rt_uint8_t</span> on)</span></span><br><span class="line">{</span><br><span class="line"> <span class="keyword">if</span> (on)</span><br><span class="line"> {</span><br><span class="line"> rt_pin_write(PIN_BEEP, PIN_HIGH);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">else</span></span><br><span class="line"> {</span><br><span class="line"> rt_pin_write(PIN_BEEP, PIN_LOW);</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p><code>5.void irq_callback(void *args) // 中断回调函数</code></p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">void</span> <span class="title function_">irq_callback</span><span class="params">(<span class="type">void</span> *args)</span></span><br><span class="line">{</span><br><span class="line"> <span class="type">rt_uint32_t</span> sign = (<span class="type">rt_uint32_t</span>)args;</span><br><span class="line"> <span class="keyword">switch</span> (sign)</span><br><span class="line"> {</span><br><span class="line"> <span class="keyword">case</span> PIN_KEY0:</span><br><span class="line"> motor_ctrl(MOTOR_LEFT);</span><br><span class="line"> rt_kprintf(<span class="string">"KEY0 interrupt. motor turn left."</span>);</span><br><span class="line"> <span class="keyword">break</span>;</span><br><span class="line"> <span class="keyword">case</span> PIN_KEY1:</span><br><span class="line"> motor_ctrl(MOTOR_RIGHT);</span><br><span class="line"> rt_kprintf(<span class="string">"KEY1 interrupt. motor turn right."</span>);</span><br><span class="line"> <span class="keyword">break</span>;</span><br><span class="line"> <span class="keyword">case</span> PIN_KEY2:</span><br><span class="line"> motor_ctrl(MOTOR_STOP);</span><br><span class="line"> rt_kprintf(<span class="string">"KEY2 interrupt. motor stop."</span>);</span><br><span class="line"> <span class="keyword">break</span>;</span><br><span class="line"> <span class="keyword">default</span>:</span><br><span class="line"> rt_kprintf(<span class="string">"error sign= %d !"</span>, sign);</span><br><span class="line"> <span class="keyword">break</span>;</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p><code>6.主函数</code></p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><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></pre></td><td class="code"><pre><span class="line"><span class="type">int</span> <span class="title function_">main</span><span class="params">(<span class="type">void</span>)</span></span><br><span class="line">{</span><br><span class="line"> <span class="type">unsigned</span> <span class="type">int</span> count = <span class="number">1</span>;</span><br><span class="line"></span><br><span class="line"> <span class="comment">/* 设置按键引脚为输入模式*/</span></span><br><span class="line"> rt_pin_mode(PIN_KEY0, PIN_MODE_INPUT_PULLUP);</span><br><span class="line"> rt_pin_mode(PIN_KEY1, PIN_MODE_INPUT_PULLUP);</span><br><span class="line"> rt_pin_mode(PIN_KEY2, PIN_MODE_INPUT_PULLUP);</span><br><span class="line"> rt_pin_mode(PIN_WK_UP, PIN_MODE_INPUT_PULLDOWN);</span><br><span class="line"></span><br><span class="line"> <span class="comment">/* 设置电机控制引脚为输入模式*/</span></span><br><span class="line"> rt_pin_mode(PIN_MOTOR_A, PIN_MODE_OUTPUT);</span><br><span class="line"> rt_pin_mode(PIN_MOTOR_B, PIN_MODE_OUTPUT);</span><br><span class="line"></span><br><span class="line"> <span class="comment">/* 设置蜂鸣器引脚为输出模式*/</span></span><br><span class="line"> rt_pin_mode(PIN_BEEP, PIN_MODE_OUTPUT);</span><br><span class="line"></span><br><span class="line"> <span class="comment">/* 设置按键中断模式与中断回调函数*/</span></span><br><span class="line"> rt_pin_attach_irq(PIN_KEY0, PIN_IRQ_MODE_FALLING , irq_callback , (<span class="type">void</span> *)PIN_KEY0</span><br><span class="line"> );</span><br><span class="line"> rt_pin_attach_irq(PIN_KEY1, PIN_IRQ_MODE_FALLING , irq_callback , (<span class="type">void</span> *)PIN_KEY1</span><br><span class="line"> );</span><br><span class="line"> rt_pin_attach_irq(PIN_KEY2, PIN_IRQ_MODE_FALLING , irq_callback , (<span class="type">void</span> *)PIN_KEY2</span><br><span class="line"> );</span><br><span class="line"></span><br><span class="line"> <span class="comment">/* 使能中断*/</span></span><br><span class="line"> rt_pin_irq_enable(PIN_KEY0, PIN_IRQ_ENABLE);</span><br><span class="line"> rt_pin_irq_enable(PIN_KEY1, PIN_IRQ_ENABLE);</span><br><span class="line"> rt_pin_irq_enable(PIN_KEY2, PIN_IRQ_ENABLE);</span><br><span class="line"> <span class="keyword">while</span> (count > <span class="number">0</span>)</span><br><span class="line"> {</span><br><span class="line"> <span class="keyword">if</span> (rt_pin_read(PIN_WK_UP) == PIN_HIGH)</span><br><span class="line"> {</span><br><span class="line"> rt_thread_mdelay(<span class="number">50</span>);</span><br><span class="line"> <span class="keyword">if</span> (rt_pin_read(PIN_WK_UP) == PIN_HIGH)</span><br><span class="line"> {</span><br><span class="line"> rt_kprintf(<span class="string">"WK_UP pressed. beep on."</span>);</span><br><span class="line"> beep_ctrl(<span class="number">1</span>);</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">else</span></span><br><span class="line"> {</span><br><span class="line"> beep_ctrl(<span class="number">0</span>);</span><br><span class="line"> }</span><br><span class="line"> rt_thread_mdelay(<span class="number">10</span>);</span><br><span class="line"> count++;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h1 id="原理讲解"><a href="#原理讲解" class="headerlink" title="原理讲解"></a>原理讲解</h1><p>通过按键引脚、电机以及蜂鸣器的输入输出模式,并对按键设置中断编写中断回调函数,在使能中断后。<br>1.电机控制:当有外部事件触发引脚状态(按下按键)时,中断回调函数对特定的触发引脚进行判断,并执行相应的操作<br>2.蜂鸣器控制:在主函数中循环执行判断是否WK_UP按键是否按下,按下触发蜂鸣器响,松开停止发声。</p><table><thead><tr><th>按键</th><th>功能</th></tr></thead><tbody><tr><td>KEY0</td><td>电机左转</td></tr><tr><td>KEY1</td><td>电机右转</td></tr><tr><td>KEY2</td><td>电机停止</td></tr><tr><td>WK_UP</td><td>蜂鸣器响</td></tr></tbody></table>]]></content>
<summary type="html"><h1 id="初识RT-Thread"><a href="#初识RT-Thread" class="headerlink" title="初识RT-Thread"></a>初识RT-Thread</h1><p><code>做世界级的 OS,让万物互联,信息畅通无阻。</code><br><code>成为未来 AIoT 领域最为主流的操作系统平台。</code></p>
<h2 id="简介"><a href="#简介" class="headerlink" title="简介"></a>简介</h2><blockquote>
<p>RT-Thread 是一个集<code>实时操作系统(RTOS)内核、中间件组件和开发者社区于一体</code>的技术平台,由<code>熊谱翔先生</code>带领并集合开源社区力量开发而成,RT-Thread 也是一个<code>组件完整丰富、高度可伸缩、简易开发、超低功耗、高安全性</code>的<code>物联网操作系统</code>。</p>
</blockquote>
<h2 id="前景"><a href="#前景" class="headerlink" title="前景"></a>前景</h2><blockquote>
<p>RT-Thread 具备一个 IoT OS 平台所需的所有关键组件,例如GUI、网络协议栈、安全传输、低功耗组件等等。经过11年的累积发展,RT-Thread 已经拥有一个<code>国内最大的嵌入式开源社区</code>,同时被广泛应用于能源、车载、医疗、消费电子等多个行业,累积装机量超过 14亿 台,成为国人<code>自主开发</code>、国内最成熟稳定和装机量最大的<code>开源 RTOS</code>。</p>
</blockquote>
<h2 id="软件生态"><a href="#软件生态" class="headerlink" title="软件生态"></a>软件生态</h2><blockquote>
<p>RT-Thread 拥有<code>良好的软件生态</code>,支持市面上所有主流的编译工具如 GCC、Keil、IAR 等,工具链完善、友好,支持各类标准接口,如 POSIX、CMSIS、C++应用环境、Javascript 执行环境等,方便开发者移植各类应用程序。商用支持所有主流MCU架构,如 ARM Cortex-M&#x2F;R&#x2F;A, MIPS, X86, Xtensa, C-Sky, RISC-V,几乎支持市场上所有主流的 MCU 和 Wi-Fi 芯片。</p>
</blockquote></summary>
<category term="RT-Thread" scheme="https://pdpeng.github.io/categories/RT-Thread/"/>
<category term="RT-Thread" scheme="https://pdpeng.github.io/tags/RT-Thread/"/>
</entry>
<entry>
<title>【玩转 RT-Thread】I2C 内核</title>
<link href="https://pdpeng.github.io/2022/04/28/rt-thread02/"/>
<id>https://pdpeng.github.io/2022/04/28/rt-thread02/</id>
<published>2022-04-28T11:28:34.000Z</published>
<updated>2025-03-10T15:12:25.998Z</updated>
<content type="html"><![CDATA[<h1 id="i2c协议"><a href="#i2c协议" class="headerlink" title="i2c协议"></a>i2c协议</h1><p>由飞利浦公司开发,支持设备间的短距离通信。i2c通信需要的引脚少,硬件实现简单、可扩展性强,被广泛应用在系统内多个集成电路(IC)间的通信。</p><h1 id="i2c物理层"><a href="#i2c物理层" class="headerlink" title="i2c物理层"></a>i2c物理层</h1><ul><li><p>i2c通信总线可连接多个i2c通信设备,支持多个通信主机和多个通信从机。i2c通信只需要两条双向总线——SDA(串行数据线)和SCL(串行时钟线)。<br><code>SDA</code>:用于传输数据<br><code>SCL</code>:用于同步数据收发</p></li><li><p>每个连接到总线的设备都有一个独立地址,共7bit,主机正是利用该地址对设备进行访问</p></li><li><p>i2c支持多主控,任何时间点都只能有一个主控。<br><img src="https://img-blog.csdnimg.cn/01cc1805f0db4842a836a7dae9b11978.png"></p></li><li><p>i2c器件的SDA引脚和SCL引脚是开漏电路形式,因此,SDA和SCL总线都需要连接上拉电阻,当总线空闲时,两条总线均为高电平。</p></li><li><p>各器件的SDA和SCL信号线在总线上都是<code>线与</code>关系。(即连接到总线上的任意器件输出低电平都会将总线信号拉低)</p></li></ul><span id="more"></span><h1 id="i2c协议层"><a href="#i2c协议层" class="headerlink" title="i2c协议层"></a>i2c协议层</h1><p>协议层定义了i2c的通信协议。一个完整的i2c数据传输包含开始信号,器件地址,读写控制,器件内访问地址,有效数据,应答信号和结束信号。</p><h2 id="i2c总线的位传输"><a href="#i2c总线的位传输" class="headerlink" title="i2c总线的位传输"></a>i2c总线的位传输</h2><p>数据传输:当SCL位高电平时,SDA必须保持稳定,SDA上传1位数据。<br>数据改变:当SCL为低电平时,SDA才可以改变电平<br><code>i2c位传输时序图</code><br><img src="https://img-blog.csdnimg.cn/3bcc9522f82841b5a9808703e4c29fa9.png"></p><h2 id="i2c总线的开始和结束信号"><a href="#i2c总线的开始和结束信号" class="headerlink" title="i2c总线的开始和结束信号"></a>i2c总线的开始和结束信号</h2><p><code>开始信号</code>:SCL 为高电平时,主机将SDA 拉低,表示数据传输即将开始。<br><code>结束信号</code>:在SDA 为低电平时,主机将SCL 拉高并保持高电平,然后在将SDA 拉高,表示传输结束。</p><h2 id="i2c应答信号"><a href="#i2c应答信号" class="headerlink" title="i2c应答信号"></a>i2c应答信号</h2><ul><li>在<code>主机</code>发送完每一个字节数据后,释放SDA(保持高电平),被寻址的接收器在成功接收到每一个字节后,必须产生一个应答<code>ACK</code>(从机将SDA拉低,使它在这个时钟脉冲的高电平期间保持稳定的低电平)</li><li>当<code>从机</code>接收不到数据或通信故障时,<code>从机</code>必须使SDA保持高电平,<code>主机</code>产生一个结束信号终止传输或者产生新的传输。</li></ul><h2 id="i2c总线的仲裁机制"><a href="#i2c总线的仲裁机制" class="headerlink" title="i2c总线的仲裁机制"></a>i2c总线的仲裁机制</h2><ul><li>SDA的仲裁也是建立在总线具有<code>线与</code>逻辑功能的原理上的。</li><li>节点在发送1位数据后,比较总线上所呈现的数据与自己发送的是否一致。是,继续发送;否则,退出竞争。</li><li>SDA的仲裁可以保证i2c总线系统在多个主节点上同时企图控制总线时通信正常进行而且数据不丢失(总线系统通过仲裁只允许一个主节点可以继续占据总线)</li><li>当SCL为高电平时,仲裁在SDA上发生。在其他主机发送低电平时,发送高电平的主机将会断开它的数据传输级,因为总线上的电平是<code>线与</code>连接。</li></ul><h1 id="访问i2c总线设备"><a href="#访问i2c总线设备" class="headerlink" title="访问i2c总线设备"></a>访问i2c总线设备</h1><p>一般情况下MCU 的I2C 器件都是作为主机和从机通讯,在RT-Thread 中将I2C 主机虚拟为I2C 总线设备,I2C 从机通过I2C 设备接口和I2C 总线通讯,相关接口如下所示:</p><table><thead><tr><th>函数</th><th>描述</th></tr></thead><tbody><tr><td>rt_device_find()</td><td>根据I2C 总线设备名称查找设备获取设备句柄</td></tr><tr><td>rt_i2c_transfer()</td><td>传输数据</td></tr></tbody></table><h1 id="查找i2c总线设备"><a href="#查找i2c总线设备" class="headerlink" title="查找i2c总线设备"></a>查找i2c总线设备</h1><p>在使用I2C 总线设备前需要根据I2C 总线设备名称获取设备句柄,进而才可以操作I2C 总线设备,查找设备函数如下所示,</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">rt_device_t rt_device_find(const char* name);</span><br></pre></td></tr></table></figure><table><thead><tr><th>参数</th><th>描述</th></tr></thead><tbody><tr><td>name</td><td>i2c总线设备名称</td></tr><tr><td><strong>返回</strong></td><td>–</td></tr><tr><td>设备句柄</td><td>查找到对应设备将返回相应的设备句柄</td></tr><tr><td>RT-NULL</td><td>没有找到相应的设备对象</td></tr></tbody></table><p>一般情况下,注册到系统的I2C 设备名称为i2c0 ,i2c1 等,使用示例如下所示:</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">define</span> AHT10_I2C_BUS_NAME <span class="string">"i2c1"</span> <span class="comment">/* 传感器连接的I2C总线设备名称*/</span></span></span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">rt_i2c_bus_device</span> *<span class="title">i2c_bus</span>;</span> <span class="comment">/* I2C总线设备句柄*/</span></span><br><span class="line"><span class="comment">/* 查找I2C总线设备, 获取I2C总线设备句柄*/</span></span><br><span class="line">i2c_bus = (<span class="keyword">struct</span> rt_i2c_bus_device *)rt_device_find(name);</span><br></pre></td></tr></table></figure><h1 id="数据传输"><a href="#数据传输" class="headerlink" title="数据传输"></a>数据传输</h1><p>获取到I2C 总线设备句柄就可以使用rt_i2c_transfer() 进行数据传输。函数原型如下所示:</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">rt_size_t</span> <span class="title function_">rt_i2c_transfer</span><span class="params">(<span class="keyword">struct</span> rt_i2c_bus_device *bus,</span></span><br><span class="line"><span class="params"><span class="keyword">struct</span> rt_i2c_msg msgs[],</span></span><br><span class="line"><span class="params"><span class="type">rt_uint32_t</span> num)</span>;</span><br></pre></td></tr></table></figure><table><thead><tr><th>参数</th><th>描述</th></tr></thead><tbody><tr><td>bus</td><td>i2c总线设备句柄</td></tr><tr><td>msgs[]</td><td>待传输的消息数组指针</td></tr><tr><td>num</td><td>消息数组的元素个数</td></tr><tr><td><strong>返回</strong></td><td>-</td></tr><tr><td>-</td><td>-</td></tr><tr><td>消息数组的元素个数</td><td>成功</td></tr><tr><td>错误码</td><td>失败</td></tr></tbody></table><ul><li>和SPI 总线的自定义传输接口一样,I2C 总线的自定义传输接口传输的数据也是以一个消息为单位。</li><li>参数msgs[] 指向待传输的消息数组,用户可以自定义每条消息的内容,实现I2C 总线所支持的2 种不同的数据传输模式。如果主设备需要发送重复开始条件,则需要发送2 个消息。<br><code>!!! note “注意事项” 此函数会调用rt_mutex_take(), 不能在中断服务程序里面调用,会导致assertion报错。</code></li></ul><blockquote><p>I2C 消息数据结构原型如下:</p></blockquote><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">rt_i2c_msg</span></span></span><br><span class="line"><span class="class">{</span></span><br><span class="line"><span class="type">rt_uint16_t</span> addr; <span class="comment">/* 从机地址*/</span></span><br><span class="line"><span class="type">rt_uint16_t</span> flags; <span class="comment">/* 读、写标志等*/</span></span><br><span class="line"><span class="type">rt_uint16_t</span> len; <span class="comment">/* 读写数据字节数*/</span></span><br><span class="line"><span class="type">rt_uint8_t</span> *buf; <span class="comment">/* 读写数据缓冲区指针 */</span></span><br><span class="line">}</span><br></pre></td></tr></table></figure><ul><li>从机地址addr:支持7 位和10 位二进制地址,需查看不同设备的数据手册。</li><li>标志flags 可取值为以下宏定义,根据需要可以与其他宏使用位运算“|” 组合起来使用。<br> <code>!!! note “注意事项” RT-Thread I2C 设备接口使用的从机地址均不包含读写位,读写位控制需修改标志flags。</code></li></ul><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">define</span> RT_I2C_WR 0x0000 <span class="comment">/* 写标志*/</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> RT_I2C_RD (1u << 0) <span class="comment">/* 读标志*/</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> RT_I2C_ADDR_10BIT (1u << 2) <span class="comment">/* 10 位地址模式*/</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> RT_I2C_NO_START (1u << 4) <span class="comment">/* 无开始条件*/</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> RT_I2C_IGNORE_NACK (1u << 5) <span class="comment">/* 忽视NACK */</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> RT_I2C_NO_READ_ACK (1u << 6) <span class="comment">/* 读的时候不发送ACK */</span></span></span><br></pre></td></tr></table></figure><blockquote><p>使用示例如下所示:</p></blockquote><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">define</span> AHT10_I2C_BUS_NAME <span class="string">"i2c1"</span> <span class="comment">/* 传感器连接的I2C总线设备名称*/</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> AHT10_ADDR 0x38 <span class="comment">/* 从机地址*/</span></span></span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">rt_i2c_bus_device</span> *<span class="title">i2c_bus</span>;</span> <span class="comment">/* I2C总线设备句柄*/</span></span><br><span class="line"></span><br><span class="line"><span class="comment">/* 查找I2C总线设备, 获取I2C总线设备句柄*/</span></span><br><span class="line">i2c_bus = (<span class="keyword">struct</span> rt_i2c_bus_device *)rt_device_find(name);</span><br><span class="line"></span><br><span class="line"><span class="comment">/* 读传感器寄存器数据*/</span></span><br><span class="line"><span class="type">static</span> <span class="type">rt_err_t</span> <span class="title function_">read_regs</span><span class="params">(<span class="keyword">struct</span> rt_i2c_bus_device *bus, <span class="type">rt_uint8_t</span> len, <span class="type">rt_uint8_t</span></span></span><br><span class="line"><span class="params">*buf)</span></span><br><span class="line">{</span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">rt_i2c_msg</span> <span class="title">msgs</span>;</span></span><br><span class="line">msgs.addr = AHT10_ADDR; <span class="comment">/* 从机地址*/</span></span><br><span class="line">msgs.flags = RT_I2C_RD; <span class="comment">/* 读标志*/</span></span><br><span class="line">msgs.buf = buf; <span class="comment">/* 读写数据缓冲区指针 */</span></span><br><span class="line">msgs.len = len; <span class="comment">/* 读写数据字节数*/</span></span><br><span class="line"><span class="comment">/* 调用I2C设备接口传输数据*/</span></span><br><span class="line"><span class="keyword">if</span> (rt_i2c_transfer(bus, &msgs, <span class="number">1</span>) == <span class="number">1</span>)</span><br><span class="line">{</span><br><span class="line"><span class="keyword">return</span> RT_EOK;</span><br><span class="line">}</span><br><span class="line"><span class="keyword">else</span></span><br><span class="line">{</span><br><span class="line"><span class="keyword">return</span> -RT_ERROR;</span><br><span class="line">}</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h1 id="i2c总线设备使用示例"><a href="#i2c总线设备使用示例" class="headerlink" title="i2c总线设备使用示例"></a>i2c总线设备使用示例</h1><p>I2C 设备的具体使用方式可以参考如下示例代码,示例代码的主要步骤如下:</p><ol><li><pre><code>首先根据I2C 设备名称查找I2C 名称,获取设备句柄,然后初始化aht10 传感器。</code></pre></li><li><pre><code>控制传感器的2 的函数为写传感器寄存器write\_reg\(\) 和读传感器寄存器read\_regs\(\)</code></pre></li></ol><p>这两个函数分别调用了rt_i2c_transfer() 传输数据。读取温湿度信息的函数read_temp_humi() 则是调用这两个函数完成功能。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><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><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment">* 程序清单: 这是一个I2C 设备使用例程</span></span><br><span class="line"><span class="comment">* 例程导出了i2c_aht10_sample 命令到控制终端</span></span><br><span class="line"><span class="comment">* 命令调用格式: i2c_aht10_sample i2c1</span></span><br><span class="line"><span class="comment">* 命令解释: 命令第二个参数是要使用的I2C总线设备名称, 为空则使用默认的I2C总线设备</span></span><br><span class="line"><span class="comment">* 程序功能: 通过I2C 设备读取温湿度传感器aht10 的温湿度数据并打印</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><rtthread.h></span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><rtdevice.h></span></span></span><br><span class="line"></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> AHT10_I2C_BUS_NAME <span class="string">"i2c1"</span> <span class="comment">/* 传感器连接的I2C总线设备名称*/</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> AHT10_ADDR 0x38 <span class="comment">/* 从机地址*/</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> AHT10_CALIBRATION_CMD 0xE1 <span class="comment">/* 校准命令*/</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> AHT10_NORMAL_CMD 0xA8 <span class="comment">/* 一般命令*/</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> AHT10_GET_DATA 0xAC <span class="comment">/* 获取数据命令*/</span></span></span><br><span class="line"></span><br><span class="line"><span class="type">static</span> <span class="class"><span class="keyword">struct</span> <span class="title">rt_i2c_bus_device</span> *<span class="title">i2c_bus</span> =</span> RT_NULL; <span class="comment">/* I2C总线设备句柄*/</span></span><br><span class="line"><span class="type">static</span> <span class="type">rt_bool_t</span> initialized = RT_FALSE; <span class="comment">/* 传感器初始化状态*/</span></span><br><span class="line"></span><br><span class="line"><span class="comment">/* 写传感器寄存器*/</span></span><br><span class="line"><span class="type">static</span> <span class="type">rt_err_t</span> <span class="title function_">write_reg</span><span class="params">(<span class="keyword">struct</span> rt_i2c_bus_device *bus, <span class="type">rt_uint8_t</span> reg, <span class="type">rt_uint8_t</span>*data)</span></span><br><span class="line">{</span><br><span class="line"><span class="type">rt_uint8_t</span> buf[<span class="number">3</span>];</span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">rt_i2c_msg</span> <span class="title">msgs</span>;</span></span><br><span class="line">buf[<span class="number">0</span>] = reg; <span class="comment">//cmd</span></span><br><span class="line">buf[<span class="number">1</span>] = data[<span class="number">0</span>];</span><br><span class="line">buf[<span class="number">2</span>] = data[<span class="number">1</span>];</span><br><span class="line">msgs.addr = AHT10_ADDR;</span><br><span class="line">msgs.flags = RT_I2C_WR;</span><br><span class="line">msgs.buf = buf;</span><br><span class="line">msgs.len = <span class="number">3</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">/* 调用I2C设备接口传输数据*/</span></span><br><span class="line"><span class="keyword">if</span> (rt_i2c_transfer(bus, &msgs, <span class="number">1</span>) == <span class="number">1</span>)</span><br><span class="line">{</span><br><span class="line"><span class="keyword">return</span> RT_EOK;</span><br><span class="line">}</span><br><span class="line"><span class="keyword">else</span></span><br><span class="line">{</span><br><span class="line"><span class="keyword">return</span> -RT_ERROR;</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="type">static</span> <span class="type">rt_err_t</span> <span class="title function_">read_regs</span><span class="params">(<span class="keyword">struct</span> rt_i2c_bus_device *bus, <span class="type">rt_uint8_t</span> len, <span class="type">rt_uint8_t</span>*buf)</span></span><br><span class="line">{</span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">rt_i2c_msg</span> <span class="title">msgs</span>;</span></span><br><span class="line">msgs.addr = AHT10_ADDR;</span><br><span class="line">msgs.flags = RT_I2C_RD;</span><br><span class="line">msgs.buf = buf;</span><br><span class="line">msgs.len = len;</span><br><span class="line"></span><br><span class="line"><span class="comment">/* 调用I2C设备接口传输数据*/</span></span><br><span class="line"><span class="keyword">if</span> (rt_i2c_transfer(bus, &msgs, <span class="number">1</span>) == <span class="number">1</span>)</span><br><span class="line">{</span><br><span class="line"><span class="keyword">return</span> RT_EOK;</span><br><span class="line">}</span><br><span class="line"><span class="keyword">else</span></span><br><span class="line">{</span><br><span class="line"><span class="keyword">return</span> -RT_ERROR;</span><br><span class="line">}</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="type">static</span> <span class="type">void</span> <span class="title function_">read_temp_humi</span><span class="params">(<span class="type">float</span> *cur_temp, <span class="type">float</span> *cur_humi)</span></span><br><span class="line">{</span><br><span class="line"><span class="type">rt_uint8_t</span> temp[<span class="number">6</span>];</span><br><span class="line">write_reg(i2c_bus, AHT10_GET_DATA, <span class="number">0</span>); <span class="comment">/* 发送命令*/</span></span><br><span class="line">rt_thread_mdelay(<span class="number">400</span>);</span><br><span class="line">read_regs(i2c_bus, <span class="number">6</span>, temp); <span class="comment">/* 获取传感器数据*/</span></span><br><span class="line"><span class="comment">/* 湿度数据转换*/</span></span><br><span class="line">*cur_humi = (temp[<span class="number">1</span>] << <span class="number">12</span> | temp[<span class="number">2</span>] << <span class="number">4</span> | (temp[<span class="number">3</span>] & <span class="number">0xf0</span>) >> <span class="number">4</span>) * <span class="number">100.0</span> / (<span class="number">1</span><< <span class="number">20</span>);</span><br><span class="line"><span class="comment">/* 温度数据转换*/</span></span><br><span class="line">*cur_temp = ((temp[<span class="number">3</span>] & <span class="number">0xf</span>) << <span class="number">16</span> | temp[<span class="number">4</span>] << <span class="number">8</span> | temp[<span class="number">5</span>]) * <span class="number">200.0</span> / (<span class="number">1</span> << <span class="number">20</span>)- <span class="number">50</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="type">static</span> <span class="type">void</span> <span class="title function_">aht10_init</span><span class="params">(<span class="type">const</span> <span class="type">char</span> *name)</span></span><br><span class="line">{</span><br><span class="line"><span class="type">rt_uint8_t</span> temp[<span class="number">2</span>] = {<span class="number">0</span>, <span class="number">0</span>};</span><br><span class="line"><span class="comment">/* 查找I2C总线设备, 获取I2C总线设备句柄*/</span></span><br><span class="line">i2c_bus = (<span class="keyword">struct</span> rt_i2c_bus_device *)rt_device_find(name);</span><br><span class="line"><span class="keyword">if</span> (i2c_bus == RT_NULL)</span><br><span class="line">{</span><br><span class="line">rt_kprintf(<span class="string">"can't find %s device!\n"</span>, name);</span><br><span class="line">}</span><br><span class="line"><span class="keyword">else</span></span><br><span class="line">{</span><br><span class="line">write_reg(i2c_bus, AHT10_NORMAL_CMD, temp);</span><br><span class="line">rt_thread_mdelay(<span class="number">400</span>);</span><br><span class="line">temp[<span class="number">0</span>] = <span class="number">0x08</span>;</span><br><span class="line">temp[<span class="number">1</span>] = <span class="number">0x00</span>;</span><br><span class="line">write_reg(i2c_bus, AHT10_CALIBRATION_CMD, temp);</span><br><span class="line">rt_thread_mdelay(<span class="number">400</span>);</span><br><span class="line">initialized = RT_TRUE;</span><br><span class="line">}</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="type">static</span> <span class="type">void</span> <span class="title function_">i2c_aht10_sample</span><span class="params">(<span class="type">int</span> argc, <span class="type">char</span> *argv[])</span></span><br><span class="line">{</span><br><span class="line"><span class="type">float</span> humidity, temperature;</span><br><span class="line"><span class="type">char</span> name[RT_NAME_MAX];</span><br><span class="line">humidity = <span class="number">0.0</span>;</span><br><span class="line">temperature = <span class="number">0.0</span>;</span><br><span class="line"><span class="keyword">if</span> (argc == <span class="number">2</span>)</span><br><span class="line">{</span><br><span class="line">rt_strncpy(name, argv[<span class="number">1</span>], RT_NAME_MAX);</span><br><span class="line">}</span><br><span class="line"><span class="keyword">else</span></span><br><span class="line">{</span><br><span class="line">rt_strncpy(name, AHT10_I2C_BUS_NAME, RT_NAME_MAX);</span><br><span class="line">}</span><br><span class="line"><span class="keyword">if</span> (!initialized)</span><br><span class="line">{</span><br><span class="line"><span class="comment">/* 传感器初始化*/</span></span><br><span class="line">aht10_init(name);</span><br><span class="line">}</span><br><span class="line"><span class="keyword">if</span> (initialized)</span><br><span class="line">{</span><br><span class="line"><span class="comment">/* 读取温湿度数据*/</span></span><br><span class="line">read_temp_humi(&temperature, &humidity);</span><br><span class="line">rt_kprintf(<span class="string">"read aht10 sensor humidity : %d.%d %%\n"</span>, (<span class="type">int</span>)humidity, (<span class="type">int</span>)</span><br><span class="line">(humidity * <span class="number">10</span>) % <span class="number">10</span>);</span><br><span class="line"><span class="keyword">if</span>( temperature >= <span class="number">0</span> )</span><br><span class="line">{</span><br><span class="line">rt_kprintf(<span class="string">"read aht10 sensor temperature: %d.%d°C\n"</span>, (<span class="type">int</span>)temperature,</span><br><span class="line">(<span class="type">int</span>)(temperature * <span class="number">10</span>) % <span class="number">10</span>);</span><br><span class="line">}</span><br><span class="line"><span class="keyword">else</span></span><br><span class="line">{</span><br><span class="line">rt_kprintf(<span class="string">"read aht10 sensor temperature: %d.%d°C\n"</span>, (<span class="type">int</span>)temperature,</span><br><span class="line">(<span class="type">int</span>)(-temperature * <span class="number">10</span>) % <span class="number">10</span>);</span><br><span class="line">}</span><br><span class="line">}</span><br><span class="line"><span class="keyword">else</span></span><br><span class="line">{</span><br><span class="line">rt_kprintf(<span class="string">"initialize sensor failed!\n"</span>);</span><br><span class="line">}</span><br><span class="line">}</span><br><span class="line"><span class="comment">/* 导出到msh 命令列表中*/</span></span><br><span class="line">MSH_CMD_EXPORT(i2c_aht10_sample, i2c aht10 sample);</span><br></pre></td></tr></table></figure><hr><p>参考资料:</p><ul><li><span class="exturl" data-url="aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3d5eDAyMjQvYXJ0aWNsZS9kZXRhaWxzLzgzMzg1MTY4">句柄详解<i class="fa fa-external-link-alt"></i></span></li><li><span class="exturl" data-url="aHR0cHM6Ly9pdGVtLmpkLmNvbS8xMDAyMjMxMjE0NjM0MC5odG1s">《嵌入式系统设计》<i class="fa fa-external-link-alt"></i></span></li><li><span class="exturl" data-url="aHR0cHM6Ly9jbHViLnJ0LXRocmVhZC5vcmcvaW5kZXguaHRtbA==">RT-Thread 官方论坛<i class="fa fa-external-link-alt"></i></span></li><li><span class="exturl" data-url="aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L25ndWxiL2FydGljbGUvZGV0YWlscy84MTE3NDIzMw==">开漏、开集电路详解<i class="fa fa-external-link-alt"></i></span></li><li><span class="exturl" data-url="aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2Z5bXgyMDMvYXJ0aWNsZS9kZXRhaWxzLzg5NDI2NDAz">上拉、下拉电阻的原理和作用<i class="fa fa-external-link-alt"></i></span></li></ul>]]></content>
<summary type="html"><h1 id="i2c协议"><a href="#i2c协议" class="headerlink" title="i2c协议"></a>i2c协议</h1><p>由飞利浦公司开发,支持设备间的短距离通信。i2c通信需要的引脚少,硬件实现简单、可扩展性强,被广泛应用在系统内多个集成电路(IC)间的通信。</p>
<h1 id="i2c物理层"><a href="#i2c物理层" class="headerlink" title="i2c物理层"></a>i2c物理层</h1><ul>
<li><p>i2c通信总线可连接多个i2c通信设备,支持多个通信主机和多个通信从机。i2c通信只需要两条双向总线——SDA(串行数据线)和SCL(串行时钟线)。<br><code>SDA</code>:用于传输数据<br><code>SCL</code>:用于同步数据收发</p>
</li>
<li><p>每个连接到总线的设备都有一个独立地址,共7bit,主机正是利用该地址对设备进行访问</p>
</li>
<li><p>i2c支持多主控,任何时间点都只能有一个主控。<br><img src="https://img-blog.csdnimg.cn/01cc1805f0db4842a836a7dae9b11978.png"></p>
</li>
<li><p>i2c器件的SDA引脚和SCL引脚是开漏电路形式,因此,SDA和SCL总线都需要连接上拉电阻,当总线空闲时,两条总线均为高电平。</p>
</li>
<li><p>各器件的SDA和SCL信号线在总线上都是<code>线与</code>关系。(即连接到总线上的任意器件输出低电平都会将总线信号拉低)</p>
</li>
</ul></summary>
<category term="RT-Thread" scheme="https://pdpeng.github.io/categories/RT-Thread/"/>
<category term="RT-Thread" scheme="https://pdpeng.github.io/tags/RT-Thread/"/>
</entry>
<entry>
<title>【玩转 RT-Thread】线程管理原理</title>
<link href="https://pdpeng.github.io/2022/04/28/rt-thread03/"/>
<id>https://pdpeng.github.io/2022/04/28/rt-thread03/</id>
<published>2022-04-28T11:25:04.000Z</published>
<updated>2025-03-10T15:12:25.999Z</updated>
<content type="html"><![CDATA[<h1 id="序言"><a href="#序言" class="headerlink" title="序言"></a>序言</h1><p>在日常生活中,我们通常会将一个大的问题拆分细化,拆开成若干个小问题,通过逐个解决小问题,大问题也就解决了。<br>同样的在RT-Thread多线程操作系统中,开发人员基于这种分而治之的思想,将一个复杂的应用问题抽象成若干个小的、可调度的、可序列化的程序单元。当合理地划分任务并正确地执行时,这种设计能够让系统满足实时系统的性能及时间的要求。</p><p>下面看一个例子:我们的任务是读取传感器上的数据,并将相关数据显示出来。通过拆分结构,我们可以发现主要有两个任务:</p><blockquote><p>1.读取数据<br>2.显示数据</p></blockquote><p>简单来说,就是一个子任务不间断地读取传感器数据,并将数据写到共享内存中,另外一个子任务周期性的从共享内存中读取数据,并将传感器数据输出到显示屏上。 </p><p><img src="https://img-blog.csdnimg.cn/6d57696f2ffc4e859bf8c8c1ffc0789e.png"> </p><p>在RT-Thread 中,与上述子任务对应的程序实体就是线程,<code>线程是实现任务的载体</code>。<br>它是RT-Thread中<code>最基本的调度单位</code>,它描述了一个任务执行的运行环境,也描述了这个任务所处的优先等级,重要的任务可设置相对较高的<code>优先级</code>,非重要的任务可以设置较低的优先级,不同的任务还可以设置相同的优先级,轮流运行。<br><code>上下文:</code>当线程运行时,它会认为自己是以独占CPU 的方式在运行,线程执行时的运行环境称为上下文,具体来说就是各个变量和数据,包括所有的寄存器变量、堆栈、内存信息等。</p><span id="more"></span><h1 id="线程管理的功能特点"><a href="#线程管理的功能特点" class="headerlink" title="线程管理的功能特点"></a>线程管理的功能特点</h1><p>RT-Thread 线程管理的主要功能是<code>对线程进行管理和调度</code>,系统中总共存在两类线程,分别是<code>系统线程</code>和<code>用户线程</code>。系统线程是由RT-Thread 内核创建的线程,用户线程是由应用程序创建的线程,这两类线程都会从内核对象容器中分配线程对象,当线程被删除时,也会被从对象容器中删除。</p><p>如图所示,每个线程都有重要的属性,如线程控制块、线程栈、入口函数等。 </p><p><img src="https://img-blog.csdnimg.cn/5584a47897de430597897d3a6bddd710.png"></p><ul><li>RT-Thread 的线程调度器是<code>抢占式</code>的,主要的工作就是从就绪线程列表中查找最高优先级线程,保证最高优先级的线程能够被运行,最高优先级的任务一旦就绪,总能得到CPU 的使用权。</li><li>当一个运行着的线程使一个比它优先级高的线程满足运行条件,当前线程的CPU 使用权就被剥夺了,或者说被让出了,高优先级的线程立刻得到了CPU 的使用权。<br>如果是中断服务程序使一个高优先级的线程满足运行条件,中断完成时,被中断的线程挂起,优先级高的线程开始运行。</li><li>当调度器调度线程切换时,先将当前线程上下文保存起来,当再切回到这个线程时,线程调度器将该线程上下文信息恢复。</li></ul><h1 id="线程的工作机制"><a href="#线程的工作机制" class="headerlink" title="线程的工作机制"></a>线程的工作机制</h1><h2 id="线程控制块"><a href="#线程控制块" class="headerlink" title="线程控制块"></a>线程控制块</h2><p>在RT-Thread 中,线程控制块由结构体struct rt_thread 表示,线程控制块是操作系统用于管理线程的一个数据结构,它会存放线程的一些信息,例如优先级、线程名称、线程状态等,也包含线程与线程之间连接用的链表结构,线程等待事件集合等,详细定义如下:</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><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="comment">/* 线程控制块*/</span></span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">rt_thread</span></span></span><br><span class="line"><span class="class">{</span></span><br><span class="line"><span class="comment">/* rt 对象*/</span></span><br><span class="line"><span class="type">char</span> name[RT_NAME_MAX]; <span class="comment">/* 线程名称*/</span></span><br><span class="line"><span class="type">rt_uint8_t</span> type; <span class="comment">/* 对象类型*/</span></span><br><span class="line"><span class="type">rt_uint8_t</span> flags; <span class="comment">/* 标志位*/</span></span><br><span class="line"><span class="type">rt_list_t</span> <span class="built_in">list</span>; <span class="comment">/* 对象列表*/</span></span><br><span class="line"><span class="type">rt_list_t</span> tlist; <span class="comment">/* 线程列表*/</span></span><br><span class="line"></span><br><span class="line"><span class="comment">/* 栈指针与入口指针*/</span></span><br><span class="line"><span class="type">void</span> *sp; <span class="comment">/* 栈指针*/</span></span><br><span class="line"><span class="type">void</span> *entry; <span class="comment">/* 入口函数指针*/</span></span><br><span class="line"><span class="type">void</span> *parameter; <span class="comment">/* 参数*/</span></span><br><span class="line"><span class="type">void</span> *stack_addr; <span class="comment">/* 栈地址指针*/</span></span><br><span class="line"><span class="type">rt_uint32_t</span> stack_size; <span class="comment">/* 栈大小*/</span></span><br><span class="line"></span><br><span class="line"><span class="comment">/* 错误代码*/</span></span><br><span class="line"><span class="type">rt_err_t</span> error; <span class="comment">/* 线程错误代码*/</span></span><br><span class="line"><span class="type">rt_uint8_t</span> stat; <span class="comment">/* 线程状态*/</span></span><br><span class="line"></span><br><span class="line"><span class="comment">/* 优先级*/</span></span><br><span class="line"><span class="type">rt_uint8_t</span> current_priority; <span class="comment">/* 当前优先级*/</span></span><br><span class="line"><span class="type">rt_uint8_t</span> init_priority; <span class="comment">/* 初始优先级*/</span></span><br><span class="line"><span class="type">rt_uint32_t</span> number_mask;</span><br><span class="line">......</span><br><span class="line"><span class="type">rt_ubase_t</span> init_tick; <span class="comment">/* 线程初始化计数值*/</span></span><br><span class="line"><span class="type">rt_ubase_t</span> remaining_tick; <span class="comment">/* 线程剩余计数值*/</span></span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">rt_timer</span> <span class="title">thread_timer</span>;</span> <span class="comment">/* 内置线程定时器*/</span></span><br><span class="line"></span><br><span class="line"><span class="type">void</span> (*cleanup)(<span class="keyword">struct</span> rt_thread *tid); <span class="comment">/* 线程退出清除函数*/</span></span><br><span class="line"><span class="type">rt_uint32_t</span> user_data; <span class="comment">/* 用户数据*/</span></span><br><span class="line">};</span><br></pre></td></tr></table></figure><ul><li><code>其中init_priority 是线程创建时指定的线程优先级,在线程运行过程当中是不会被改变的(除非用户 执行线程控制函数进行手动调整线程优先级)。</code></li><li><code>cleanup 会在线程退出时,被空闲线程回调一次以执行用户设置的清理现场等工作。</code></li><li><code>最后的一个成员user_data 可由用户挂接一些数据信息到线程控制块中,以提供类似线程私有数据的实现。</code></li></ul><h2 id="线程的重要属性"><a href="#线程的重要属性" class="headerlink" title="线程的重要属性"></a>线程的重要属性</h2><h3 id="线程栈"><a href="#线程栈" class="headerlink" title="线程栈"></a>线程栈</h3><ul><li>RT-Thread 线程具有独立的栈,当进行线程切换时,会将当前线程的上下文存在栈中,当线程要恢复运行时,再从栈中读取上下文信息,进行恢复。</li><li>线程栈还用来存放函数中的局部变量:函数中的局部变量从线程栈空间中申请;函数中局部变量初始时从寄存器中分配(ARM 架构),当这个函数再调用另一个函数时,这些局部变量将放入栈中。</li><li>对于线程第一次运行,可以以手工的方式构造这个上下文来设置一些初始的环境:入口函数(PC 寄存器)、入口参数(R0 寄存器)、返回位置(LR 寄存器)、当前机器运行状态(CPSR 寄存器)。</li><li>线程栈的增长方向是芯片构架密切相关的,RT-Thread 3.1.0 以前的版本,均只支持栈由高地址向低地址增长的方式,对于ARM Cortex-M 架构,线程栈可构造如下图所示。<br><img src="https://img-blog.csdnimg.cn/041732b5e1fd43d5a62382931ad50360.png"></li></ul><h3 id="线程状态"><a href="#线程状态" class="headerlink" title="线程状态"></a>线程状态</h3><p>线程运行的过程中,同一时间内只允许一个线程在处理器中运行,从运行的过程上划分,线程有多种不同的运行状态,如初始状态、挂起状态、就绪状态等。<br>在RT-Thread 中,线程包含五种状态,操作系统会自动根据它运行的情况来动态调整它的状态。如下表所示:</p><table><thead><tr><th>状态</th><th>描述</th></tr></thead><tbody><tr><td>初始态</td><td>当线程刚开始创建还没开始运行时就处于初始状态;在初始状态下,线程不参与调度。此状态在RT-Thread 中的宏定义为RT_THREAD_INIT</td></tr><tr><td>就绪态</td><td>在就绪状态下,线程按照优先级排队,等待被执行;一旦当前线程运行完毕让出处理器,操作系统会马上寻找最高优先级的就绪态线程运行。此状态在RT-Thread 中的宏定义为RT_THREAD_READY</td></tr><tr><td>运行态</td><td>线程当前正在运行。在单核系统中,只有rt_thread_self() 函数返回的线程处于运行状态;在多核系统中,可能就不止这一个线程处于运行状态。此状态在RT-Thread 中的宏定义为RT_THREAD_RUNNING</td></tr><tr><td>挂起态</td><td>也称阻塞态。它可能因为资源不可用而挂起等待,或线程主动延时一段时间而挂起。在挂起状态下,线程不参与调度。此状态在RT-Thread 中的宏定义为RT_THREAD_SUSPEND</td></tr><tr><td>关闭态</td><td>当线程运行结束时将处于关闭状态。关闭状态的线程不参与线程的调度。此状态在RT-Thread 中的宏定义为RT_THREAD_CLOSE</td></tr></tbody></table><h3 id="线程优先级"><a href="#线程优先级" class="headerlink" title="线程优先级"></a>线程优先级</h3><ul><li><p>RT-Thread 线程的优先级是表示线程被调度的优先程度。每个线程都具有优先级,线程越重要,赋予的优先级就应越高,线程被调度的可能才会越大。</p></li><li><p>RT-Thread 最大支持256 个线程优先级(0~255),数值越小的优先级越高,0 为最高优先级。在一些资源比较紧张的系统中,可以根据实际情况选择只支持8 个或32 个优先级的系统配置;对于ARM Cortex-M系列,普遍采用32 个优先级。最低优先级默认分配给空闲线程使用,用户一般不使用。在系统中,当有比当前线程优先级更高的线程就绪时,当前线程将立刻被换出,高优先级线程抢占处理器运行。</p></li></ul><h3 id="时间片"><a href="#时间片" class="headerlink" title="时间片"></a>时间片</h3><blockquote><p>每个线程都有时间片这个参数,但时间片仅对优先级相同的就绪态线程有效。系统对优先级相同的就绪态线程采用时间片轮转的调度方式进行调度时,时间片起到约束线程单次运行时长的作用,其单位是一个系统节拍(OS Tick)。</p></blockquote><p>假设有2 个<code>优先级相同的就绪态线程A 与B</code>,A 线程的时间片设置为10,B 线程的时间片设置为5,那么当系统中不存在比A 优先级高的就绪态线程时,系统会在A、B 线程间来回切换执行,并且每次对A 线程执行10 个节拍的时长,对B 线程执行5 个节拍的时长,如下图。 </p><p><img src="https://img-blog.csdnimg.cn/31c4fb41bf8947c1a47864b12b9e602e.png"></p><h3 id="线程的入口函数"><a href="#线程的入口函数" class="headerlink" title="线程的入口函数"></a>线程的入口函数</h3><p>线程控制块中的<code>entry</code>是线程的入口函数,它是线程实现预期功能的函数。</p><p>线程的入口函数由用户设计实现,一般有以下两种代码形式: </p><p>1.<code>无限循环模式</code></p><blockquote><p>在实时系统中,线程通常是被动式的:这个是由实时系统的特性所决定的,实时系统通常总是等待外<br>界事件的发生,而后进行相应的服务:</p></blockquote><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">void</span> <span class="title function_">thread_entry</span><span class="params">(<span class="type">void</span>* paramenter)</span></span><br><span class="line">{</span><br><span class="line"><span class="keyword">while</span> (<span class="number">1</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><br><span class="line">}</span><br></pre></td></tr></table></figure><blockquote><p>作为一个实时系统,一个优先级明确的实时系统,如果一个线程中的程序陷入了死循环操作,那么比它优先级低的线程都将不能够得到执行。<br>所以在实时操作系统中必须注意的一点就是:<strong>线程中不能陷入死循环操作,必须要有让出CPU使用权的动作,如循环中调用延时函数或者主动挂起。用户设计这种无线循环的线程的目的,就是为了让这个线程一直被系统循环调度运行,永不删除。</strong></p></blockquote><p>2.<code>顺序执行或有限次循环模式</code></p><blockquote><p>如简单的顺序语句、do whlie() 或for() 循环等,此类线程不会循环或不会永久循环,可谓是“一次性”线程,一定会被执行完毕。在执行完毕后,线程将被系统自动删除。</p></blockquote><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">static</span> <span class="type">void</span> <span class="title function_">thread_entry</span><span class="params">(<span class="type">void</span>* parameter)</span></span><br><span class="line">{</span><br><span class="line"><span class="comment">/* 处理事务#1 */</span></span><br><span class="line">…</span><br><span class="line"><span class="comment">/* 处理事务#2 */</span></span><br><span class="line">…</span><br><span class="line"><span class="comment">/* 处理事务#3 */</span></span><br><span class="line">}</span><br></pre></td></tr></table></figure><h3 id="常见的线程错误码"><a href="#常见的线程错误码" class="headerlink" title="常见的线程错误码"></a>常见的线程错误码</h3><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">define</span> RT_EOK 0 <span class="comment">/* 无错误*/</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> RT_ERROR 1 <span class="comment">/* 普通错误*/</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> RT_ETIMEOUT 2 <span class="comment">/* 超时错误*/</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> RT_EFULL 3 <span class="comment">/* 资源已满*/</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> RT_EEMPTY 4 <span class="comment">/* 无资源*/</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> RT_ENOMEM 5 <span class="comment">/* 无内存*/</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> RT_ENOSYS 6 <span class="comment">/* 系统不支持*/</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> RT_EBUSY 7 <span class="comment">/* 系统忙*/</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> RT_EIO 8 <span class="comment">/* IO 错误*/</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> RT_EINTR 9 <span class="comment">/* 中断系统调用*/</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> RT_EINVAL 10 <span class="comment">/* 非法参数*/</span></span></span><br></pre></td></tr></table></figure><h2 id="线程状态切换"><a href="#线程状态切换" class="headerlink" title="线程状态切换"></a>线程状态切换</h2><p>RT-Thread 提供一系列的操作系统调用接口,使得线程的状态在这五个状态之间来回切换。几种状态间的转换关系如下图所示:<br><img src="https://img-blog.csdnimg.cn/3c79cc6198144f02b4830d4521384c30.png"></p><blockquote><ul><li>线程通过调用函数<code>rt_thread_create/init()</code> 进入到初始状态<code>(RT_THREAD_INIT)</code>;</li><li>初始状态的线程通过调用函数<code>rt_thread_startup()</code> 进入到就绪状态<code>(RT_THREAD_READY)</code>;</li><li>就绪状态的线程被调度器调度后进入运行状态<code>(RT_THREAD_RUNNING)</code>;</li><li>当处于运行状态的线程调用rt_thread_delay(),rt_sem_take(),rt_mutex_take(),rt_mb_recv() 等函数或者获取不到资源时, 将进入到挂起状态<code>(RT_THREAD_SUSPEND)</code>;</li></ul></blockquote><blockquote><ul><li>处于挂起状态的线程,如果等待超时依然未能获得资源或由于其他线程释放了资源,那么它将返回到就绪状态。</li><li>挂起状态的线程,如果调用<code>rt_thread_delete/detach()</code> 函数,将更改为关闭状态<code>(RT_THREAD_CLOSE)</code>;</li><li>而运行状态的线程,如果运行结束,就会在线程的最后部分执行<code>rt_thread_exit()</code> 函数,将状态更改为关闭状态。</li></ul></blockquote><p><strong><code>!!! note “注意事项” RT-Thread 中,实际上线程并不存在运行状态,就绪状态和运行状态是等同的。</code></strong></p><h2 id="系统线程"><a href="#系统线程" class="headerlink" title="系统线程"></a>系统线程</h2><p>系统线程是指由系统创建的线程,用户线程是由用户程序调用线程管理接口创建的线程,在RT-Thread 内核中的系统线程有空闲线程和主线程。</p><h3 id="空闲线程"><a href="#空闲线程" class="headerlink" title="空闲线程"></a>空闲线程</h3><p><code>空闲线程</code>是系统创建的最低优先级的线程,线程状态<code>永远为就绪态</code>。当系统中无其他就绪线程存在时,调度器将调度到空闲线程,它通常是一个死循环,且永远不能被挂起。</p><p>另外,空闲线程在RT-Thread 也有着它的特殊用途:</p><ul><li>若某线程运行完毕,系统将自动删除线程:自动执行rt_thread_exit() 函数,先将该线程从系统就绪队列中删除,再将该线程的状态更改为关闭状态,不再参与系统调度,然后挂入rt_thread_defunct 僵尸队列(资源未回收、处于关闭状态的线程队列)中,最后空闲线程会回收被删除线程的资源。</li><li>空闲线程也提供了接口来运行用户设置的钩子函数,在空闲线程运行时会调用该钩子函数,适合钩入功耗管理、看门狗喂狗等工作。(关于<span class="exturl" data-url="aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3UwMTAxMzIxNzcvYXJ0aWNsZS9kZXRhaWxzLzExMDcwNDcyMT9vcHNfcmVxdWVzdF9taXNjPSZyZXF1ZXN0X2lkPSZiaXpfaWQ9MTAyJnV0bV90ZXJtPSVFOSU5MiVBOSVFNSVBRCU5MCVFNSU4NyVCRCVFNiU5NSVCMCZ1dG1fbWVkaXVtPWRpc3RyaWJ1dGUucGNfc2VhcmNoX3Jlc3VsdC5ub25lLXRhc2stYmxvZy0yfmFsbH5zb2JhaWR1d2VifmRlZmF1bHQtMC0xMTA3MDQ3MjEubm9uZWNhc2Umc3BtPTEwMTguMjIyNi4zMDAxLjQxODc=">钩子函数<i class="fa fa-external-link-alt"></i></span>和<span class="exturl" data-url="aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2FzNDgwMTMzOTM3L2FydGljbGUvZGV0YWlscy85OTEyMTY0NT9vcHNfcmVxdWVzdF9taXNjPSUyNTdCJTI1MjJyZXF1ZXN0JTI1NUZpZCUyNTIyJTI1M0ElMjUyMjE2NDk4MzcwMDYxNjc4MDI2OTg3OTIxNSUyNTIyJTI1MkMlMjUyMnNjbSUyNTIyJTI1M0ElMjUyMjIwMTQwNzEzLjEzMDEwMjMzNC4uJTI1MjIlMjU3RCZyZXF1ZXN0X2lkPTE2NDk4MzcwMDYxNjc4MDI2OTg3OTIxNSZiaXpfaWQ9MCZ1dG1fbWVkaXVtPWRpc3RyaWJ1dGUucGNfc2VhcmNoX3Jlc3VsdC5ub25lLXRhc2stYmxvZy0yfmFsbH50b3BfcG9zaXRpdmV+ZGVmYXVsdC0xLTk5MTIxNjQ1LjE0MiU1RXY3JTVFYXJ0aWNsZV9zY29yZV9yYW5rLDE1NyU1RXY0JTVFY29udHJvbCZ1dG1fdGVybT0lRTclOUMlOEIlRTklOTclQTglRTclOEIlOTcmc3BtPTEwMTguMjIyNi4zMDAxLjQxODc=">看门狗<i class="fa fa-external-link-alt"></i></span>不懂的可以看这里)</li></ul><h3 id="主线程"><a href="#主线程" class="headerlink" title="主线程"></a>主线程</h3><p>在系统启动时,系统会创建main 线程,它的入口函数为main_thread_entry(),用户的应用入口函数main() 就是从这里真正开始的,系统调度器启动后,main 线程就开始运行。</p><p>过程如下图,用户可以在main() 函数里添加自己的应用程序初始化代码。 </p><p><img src="https://img-blog.csdnimg.cn/b08911ca57334476945d473ab814f006.png"></p><h1 id="线程的管理方式"><a href="#线程的管理方式" class="headerlink" title="线程的管理方式"></a>线程的管理方式</h1><p>可以使用rt_thread_create() 创建一个动态线程,使用rt_thread_init() 初始化一个静态线程。</p><p>动态线程与静态线程的区别是:动态线程是系统自动从动态内存堆上分配栈空间与线程句柄(初始化heap 之后才能使用create 创建动态线程),静态线程是由用户分配栈空间与线程句柄。</p><p>下图描述了线程的相关操作,包含:创建/ 初始化线程、启动线程、运行线程、删除/ 脱离线程。</p><p><img src="https://img-blog.csdnimg.cn/fea91f8134b648ccaefeb5cf201de15f.png"></p><h2 id="创建和删除线程"><a href="#创建和删除线程" class="headerlink" title="创建和删除线程"></a>创建和删除线程</h2><h3 id="创建线程"><a href="#创建线程" class="headerlink" title="创建线程"></a>创建线程</h3><p>一个线程要成为可执行的对象,就必须由操作系统的内核来为它创建一个线程。可以通过如下的接口创建一个动态线程:</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">rt_thread_t</span> <span class="title function_">rt_thread_create</span><span class="params">(<span class="type">const</span> <span class="type">char</span>* name,</span></span><br><span class="line"><span class="params"> <span class="type">void</span> (*entry)(<span class="type">void</span>* parameter),</span></span><br><span class="line"><span class="params"> <span class="type">void</span>* parameter,</span></span><br><span class="line"><span class="params"> <span class="type">rt_uint32_t</span> stack_size,</span></span><br><span class="line"><span class="params"> <span class="type">rt_uint8_t</span> priority,</span></span><br><span class="line"><span class="params"> <span class="type">rt_uint32_t</span> tick)</span>;</span><br></pre></td></tr></table></figure><blockquote><p>调用这个函数时,系统会从动态堆内存中分配一个线程句柄以及按照参数中指定的栈大小从动态堆内存中分配相应的空间。分配出来的栈空间是按照rtconfig.h 中配置的RT_ALIGN_SIZE 方式对齐。</p></blockquote><p>线程创建rt_thread_create() 的参数和返回值见下图: </p><p><img src="https://img-blog.csdnimg.cn/f1ba4c76de384fcc91060025bff4bef7.png"></p><h3 id="删除线程"><a href="#删除线程" class="headerlink" title="删除线程"></a>删除线程</h3><p>对于一些使用rt_thread_create() 创建出来的线程,当不需要使用,或者运行出错时,我们可以使用下面的函数接口来从系统中把线程完全删除掉:</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">rt_err_t</span> <span class="title function_">rt_thread_delete</span><span class="params">(<span class="type">rt_thread_t</span> thread)</span>;</span><br></pre></td></tr></table></figure><p>调用该函数后,线程对象将会被移出线程队列并且从内核对象管理器中删除,线程占用的堆栈空间也会被释放,收回的空间将重新用于其他的内存分配。实际上,用rt_thread_delete() 函数删除线程接口,仅仅是把相应的线程状态更改为RT_THREAD_CLOSE 状态,然后放入到rt_thread_defunct 队列中;而真正的删除动作(释放线程控制块和释放线程栈)需要到下一次执行空闲线程时,由空闲线程完成最后的线程删除动作。</p><p>线程删除rt_thread_delete() 接口的参数和返回值见下图: </p><p><img src="https://img-blog.csdnimg.cn/eb9a07efdd95454c8873506f5178d1ff.png"> </p><p><code>这个函数仅在使能了系统动态堆时才有效(即RT_USING_HEAP 宏定义已经定义了)。</code></p><h2 id="初始化和脱离线程"><a href="#初始化和脱离线程" class="headerlink" title="初始化和脱离线程"></a>初始化和脱离线程</h2><h3 id="初始化线程"><a href="#初始化线程" class="headerlink" title="初始化线程"></a>初始化线程</h3><p><code>线程的初始化</code>可以使用下面的函数接口完成,来初始化静态线程对象:</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">rt_err_t</span> <span class="title function_">rt_thread_init</span><span class="params">(<span class="keyword">struct</span> rt_thread* thread,</span></span><br><span class="line"><span class="params"> <span class="type">const</span> <span class="type">char</span>* name,</span></span><br><span class="line"><span class="params"><span class="type">void</span> (*entry)(<span class="type">void</span>* parameter), <span class="type">void</span>* parameter,</span></span><br><span class="line"><span class="params"><span class="type">void</span>* stack_start, <span class="type">rt_uint32_t</span> stack_size,</span></span><br><span class="line"><span class="params"><span class="type">rt_uint8_t</span> priority, <span class="type">rt_uint32_t</span> tick)</span>;</span><br></pre></td></tr></table></figure><p><img src="https://img-blog.csdnimg.cn/c1e6ca6ef6b84ebe93d0888ff71332af.png"></p><h3 id="脱离线程"><a href="#脱离线程" class="headerlink" title="脱离线程"></a>脱离线程</h3><p>对于用rt_thread_init() 初始化的线程,使用rt_thread_detach() 将使线程对象在线程队列和内核对象管理器中被脱离。线程脱离函数如下:</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">rt_err_t</span> <span class="title function_">rt_thread_detach</span> <span class="params">(<span class="type">rt_thread_t</span> thread)</span>;</span><br></pre></td></tr></table></figure><table><thead><tr><th>参数</th><th>描述</th></tr></thead><tbody><tr><td>thread</td><td>线程句柄,它应该是由rt_thread_init 进行初始化的线程句柄。</td></tr><tr><td>返回</td><td>—</td></tr><tr><td>RT_EOK</td><td>线程脱离成功</td></tr><tr><td>-RT_ERROR</td><td>线程脱离失败</td></tr></tbody></table><h2 id="启动线程"><a href="#启动线程" class="headerlink" title="启动线程"></a>启动线程</h2><p>创建(初始化)的线程状态处于初始状态,并未进入就绪线程的调度队列,我们可以在线程初始化/创建成功后调用下面的函数接口让该线程进入就绪态:</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">rt_err_t</span> <span class="title function_">rt_thread_startup</span><span class="params">(<span class="type">rt_thread_t</span> thread)</span>;</span><br></pre></td></tr></table></figure><p><img src="https://img-blog.csdnimg.cn/431f38ae0feb46dc833f9835ec57577e.png"></p><blockquote><p>当调用这个函数时,将把线程的状态更改为就绪状态,并放到相应优先级队列中等待调度。如果新启<br>动的线程优先级比当前线程优先级高,将立刻切换到这个线程。</p></blockquote><h2 id="获得当前线程"><a href="#获得当前线程" class="headerlink" title="获得当前线程"></a>获得当前线程</h2><p>在程序的运行过程中,相同的一段代码可能会被多个线程执行,在执行的时候可以通过下面的函数接口获得当前执行的线程句柄:</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">rt_thread_t</span> <span class="title function_">rt_thread_self</span><span class="params">(<span class="type">void</span>)</span>;</span><br></pre></td></tr></table></figure><p><img src="https://img-blog.csdnimg.cn/33c1e79ddc8b42c0a28237a91e67b92c.png"></p><h2 id="使线程出让处理器资源"><a href="#使线程出让处理器资源" class="headerlink" title="使线程出让处理器资源"></a>使线程出让处理器资源</h2><blockquote><p>当前线程的时间片用完或者该线程主动要求让出处理器资源时,它将不再占有处理器,调度器会选择相同优先级的下一个线程执行。线程调用这个接口后,这个线程仍然在就绪队列中。</p></blockquote><p>线程让出处理器使用下面的函数接口:</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">rt_err_t</span> <span class="title function_">rt_thread_yield</span><span class="params">(<span class="type">void</span>)</span>;</span><br></pre></td></tr></table></figure><blockquote><p>调用该函数后,当前线程首先把自己从它所在的就绪优先级线程队列中删除,然后把自己挂到这个优先级队列链表的尾部,然后激活调度器进行线程上下文切换(如果当前优先级只有这一个线程,则这个线程继续执行,不进行上下文切换动作)。</p></blockquote><h2 id="使线程睡眠"><a href="#使线程睡眠" class="headerlink" title="使线程睡眠"></a>使线程睡眠</h2><blockquote><p>在实际应用中,我们有时需要让运行的当前线程延迟一段时间,在指定的时间到达后重新运行,这就叫做“线程睡眠”。</p></blockquote><p>线程睡眠可使用以下三个函数接口:</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">rt_err_t</span> <span class="title function_">rt_thread_sleep</span><span class="params">(<span class="type">rt_tick_t</span> tick)</span>;</span><br><span class="line"><span class="type">rt_err_t</span> <span class="title function_">rt_thread_delay</span><span class="params">(<span class="type">rt_tick_t</span> tick)</span>;</span><br><span class="line"><span class="type">rt_err_t</span> <span class="title function_">rt_thread_mdelay</span><span class="params">(<span class="type">rt_int32_t</span> ms)</span>;</span><br></pre></td></tr></table></figure><p><img src="https://img-blog.csdnimg.cn/6ebefaeea61f48a7b26d43e0d6589055.png"></p><h2 id="挂起和恢复线程"><a href="#挂起和恢复线程" class="headerlink" title="挂起和恢复线程"></a>挂起和恢复线程</h2><h3 id="线程挂起"><a href="#线程挂起" class="headerlink" title="线程挂起"></a>线程挂起</h3><blockquote><ul><li>当线程调用rt_thread_delay() 时,线程将主动挂起;当调用rt_sem_take(),rt_mb_recv() 等函数时,资源不可使用也将导致线程挂起。</li><li>处于挂起状态的线程,如果其等待的资源超时(超过其设定的等待时间),那么该线程将不再等待这些资源,并返回到就绪状态;或者,当其他线程释放掉该线程所等待的资源时,该线程也会返回到就绪状态。</li></ul></blockquote><p><code>线程挂起</code>使用下面的函数接口:</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">rt_err_t</span> <span class="title function_">rt_thread_suspend</span> <span class="params">(<span class="type">rt_thread_t</span> thread)</span>;</span><br></pre></td></tr></table></figure><p><img src="https://img-blog.csdnimg.cn/eed2dcfd794040798637c029b253fb87.png"> </p><p><code>!!! note “注意事项” 通常不应该使用这个函数来挂起线程本身, 如果确实需要采用rt_thread_suspend() 函数挂起当前任务, 需要在调用rt_thread_suspend() 函数后立刻调用rt_schedule() 函数进行手动的线程上下文切换。</code></p><h3 id="恢复线程"><a href="#恢复线程" class="headerlink" title="恢复线程"></a>恢复线程</h3><blockquote><p>恢复线程就是让挂起的线程重新进入就绪状态,并将线程放入系统的就绪队列中;如果被恢复线程在<br>所有就绪态线程中,位于最高优先级链表的第一位,那么系统将进行线程上下文的切换。</p></blockquote><p><code>线程恢复</code>使用下面的函数接口:</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">rt_err_t</span> <span class="title function_">rt_thread_resume</span> <span class="params">(<span class="type">rt_thread_t</span> thread)</span>;</span><br></pre></td></tr></table></figure><p><img src="https://img-blog.csdnimg.cn/0640fc789a1645d3b424f605d3aca937.png"></p><h2 id="控制线程"><a href="#控制线程" class="headerlink" title="控制线程"></a>控制线程</h2><p>当需要对线程进行一些其他控制时,例如动态更改线程的优先级,可以调用如下函数接口:</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">rt_err_t</span> <span class="title function_">rt_thread_control</span><span class="params">(<span class="type">rt_thread_t</span> thread, <span class="type">rt_uint8_t</span> cmd, <span class="type">void</span>* arg)</span>;</span><br></pre></td></tr></table></figure><p><img src="https://img-blog.csdnimg.cn/348eb561864549528d9695d8f504af92.png"></p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">指示控制命令cmd 当前支持的命令包括:</span><br><span class="line">•RT_THREAD_CTRL_CHANGE_PRIORITY:动态更改线程的优先级;</span><br><span class="line">•RT_THREAD_CTRL_STARTUP:开始运行一个线程,等同于rt_thread_startup() 函数调用;</span><br><span class="line">•RT_THREAD_CTRL_CLOSE:关闭一个线程,等同于rt_thread_delete() 函数调用。</span><br></pre></td></tr></table></figure><h2 id="设置和删除空闲钩子"><a href="#设置和删除空闲钩子" class="headerlink" title="设置和删除空闲钩子"></a>设置和删除空闲钩子</h2><blockquote><p>空闲钩子函数是空闲线程的钩子函数,如果设置了空闲钩子函数,就可以在系统执行空闲线程时,自动执行空闲钩子函数来做一些其他事情,比如系统指示灯。</p></blockquote><p>设置/ 删除空闲钩子的接口如下:</p><figure class="highlight c"><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="type">rt_err_t</span> <span class="title function_">rt_thread_idle_sethook</span><span class="params">(<span class="type">void</span> (*hook)(<span class="type">void</span>))</span>;</span><br><span class="line"><span class="type">rt_err_t</span> <span class="title function_">rt_thread_idle_delhook</span><span class="params">(<span class="type">void</span> (*hook)(<span class="type">void</span>))</span>;</span><br></pre></td></tr></table></figure><table><thead><tr><th>参数</th><th>描述</th></tr></thead><tbody><tr><td>hook</td><td>设置/删除的钩子函数</td></tr><tr><td>返回</td><td>—</td></tr><tr><td>RT-EOK</td><td>设置/删除成功</td></tr><tr><td>-RT_EFULL</td><td>设置失败</td></tr><tr><td>-RT_ENOSYS</td><td>删除失败</td></tr></tbody></table><p><code>!!! note “注意事项” 空闲线程是一个线程状态永远为就绪态的线程,因此设置的钩子函数必须保证空闲线程在任何时刻都不会处于挂起状态,例如rt_thread_delay(),rt_sem_take() 等可能会导致线程挂起的函数都不能使用。</code></p><h2 id="设置调度器钩子"><a href="#设置调度器钩子" class="headerlink" title="设置调度器钩子"></a>设置调度器钩子</h2><p><code>在整个系统的运行时,系统都处于线程运行、中断触发- 响应中断、切换到其他线程,甚至是线程间的切换过程中,或者说系统的上下文切换是系统中最普遍的事件。有时用户可能会想知道在一个时刻发生了什么样的线程切换,可以通过调用下面的函数接口设置一个相应的钩子函数。</code></p><p>在系统线程切换时,这个钩子函数将被调用:</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">void</span> <span class="title function_">rt_scheduler_sethook</span><span class="params">(<span class="type">void</span> (*hook)(<span class="keyword">struct</span> rt_thread* from, <span class="keyword">struct</span> rt_thread* to))</span>;</span><br></pre></td></tr></table></figure><p><code>设置调度器钩子函数的输入参数</code>如下表所示:</p><table><thead><tr><th>参数</th><th>描述</th></tr></thead><tbody><tr><td>hook</td><td>表示用户定义的钩子函数指针</td></tr></tbody></table><p><code>钩子函数hook() 的声明</code>如下:</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">void hook(struct rt_thread* from, struct rt_thread* to);</span><br></pre></td></tr></table></figure><table><thead><tr><th>参数</th><th>描述</th></tr></thead><tbody><tr><td>from</td><td>表示系统所要切换出的线程控制块指针</td></tr><tr><td>to</td><td>表示系统所要切换到的线程控制块指针</td></tr></tbody></table><p><code>!!! note “注意事项” 请仔细编写你的钩子函数,稍有不慎将很可能导致整个系统运行不正常(在这个 钩子函数中,基本上不允许调用系统API,更不应该导致当前运行的上下文挂起)。</code></p><hr><p>参考资料: </p><ul><li><span class="exturl" data-url="aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2FzNDgwMTMzOTM3L2FydGljbGUvZGV0YWlscy85OTEyMTY0NT9vcHNfcmVxdWVzdF9taXNjPSUyNTdCJTI1MjJyZXF1ZXN0JTI1NUZpZCUyNTIyJTI1M0ElMjUyMjE2NDk4MzcwMDYxNjc4MDI2OTg3OTIxNSUyNTIyJTI1MkMlMjUyMnNjbSUyNTIyJTI1M0ElMjUyMjIwMTQwNzEzLjEzMDEwMjMzNC4uJTI1MjIlMjU3RCZyZXF1ZXN0X2lkPTE2NDk4MzcwMDYxNjc4MDI2OTg3OTIxNSZiaXpfaWQ9MCZ1dG1fbWVkaXVtPWRpc3RyaWJ1dGUucGNfc2VhcmNoX3Jlc3VsdC5ub25lLXRhc2stYmxvZy0yfmFsbH50b3BfcG9zaXRpdmV+ZGVmYXVsdC0xLTk5MTIxNjQ1LjE0MiU1RXY3JTVFYXJ0aWNsZV9zY29yZV9yYW5rLDE1NyU1RXY0JTVFY29udHJvbCZ1dG1fdGVybT0lRTclOUMlOEIlRTklOTclQTglRTclOEIlOTcmc3BtPTEwMTguMjIyNi4zMDAxLjQxODc=">【STM32】HAL库 STM32CubeMX教程五—-看门狗(独立看门狗,窗口看门狗)<i class="fa fa-external-link-alt"></i></span> </li><li><span class="exturl" data-url="aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3UwMTAxMzIxNzcvYXJ0aWNsZS9kZXRhaWxzLzExMDcwNDcyMT9vcHNfcmVxdWVzdF9taXNjPSZyZXF1ZXN0X2lkPSZiaXpfaWQ9MTAyJnV0bV90ZXJtPSVFOSU5MiVBOSVFNSVBRCU5MCVFNSU4NyVCRCVFNiU5NSVCMCZ1dG1fbWVkaXVtPWRpc3RyaWJ1dGUucGNfc2VhcmNoX3Jlc3VsdC5ub25lLXRhc2stYmxvZy0yfmFsbH5zb2JhaWR1d2VifmRlZmF1bHQtMC0xMTA3MDQ3MjEubm9uZWNhc2Umc3BtPTEwMTguMjIyNi4zMDAxLjQxODc=">什么是钩子函数<i class="fa fa-external-link-alt"></i></span> </li><li><span class="exturl" data-url="aHR0cHM6Ly93d3cucnQtdGhyZWFkLm9yZy9kb2N1bWVudC9zaXRlLyMv">RT-Thread文档中心<i class="fa fa-external-link-alt"></i></span></li><li><span class="exturl" data-url="aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzU2OTE0MTQ2L2FydGljbGUvZGV0YWlscy8xMjQxNDUxNTM=">【操作系统】进程上下文和线程上下文<i class="fa fa-external-link-alt"></i></span></li></ul>]]></content>
<summary type="html"><h1 id="序言"><a href="#序言" class="headerlink" title="序言"></a>序言</h1><p>在日常生活中,我们通常会将一个大的问题拆分细化,拆开成若干个小问题,通过逐个解决小问题,大问题也就解决了。<br>同样的在RT-Thread多线程操作系统中,开发人员基于这种分而治之的思想,将一个复杂的应用问题抽象成若干个小的、可调度的、可序列化的程序单元。当合理地划分任务并正确地执行时,这种设计能够让系统满足实时系统的性能及时间的要求。</p>
<p>下面看一个例子:我们的任务是读取传感器上的数据,并将相关数据显示出来。通过拆分结构,我们可以发现主要有两个任务:</p>
<blockquote>
<p>1.读取数据<br>2.显示数据</p>
</blockquote>
<p>简单来说,就是一个子任务不间断地读取传感器数据,并将数据写到共享内存中,另外一个子任务周期性的从共享内存中读取数据,并将传感器数据输出到显示屏上。 </p>
<p><img src="https://img-blog.csdnimg.cn/6d57696f2ffc4e859bf8c8c1ffc0789e.png"> </p>
<p>在RT-Thread 中,与上述子任务对应的程序实体就是线程,<code>线程是实现任务的载体</code>。<br>它是RT-Thread中<code>最基本的调度单位</code>,它描述了一个任务执行的运行环境,也描述了这个任务所处的优先等级,重要的任务可设置相对较高的<code>优先级</code>,非重要的任务可以设置较低的优先级,不同的任务还可以设置相同的优先级,轮流运行。<br><code>上下文:</code>当线程运行时,它会认为自己是以独占CPU 的方式在运行,线程执行时的运行环境称为上下文,具体来说就是各个变量和数据,包括所有的寄存器变量、堆栈、内存信息等。</p></summary>
<category term="RT-Thread" scheme="https://pdpeng.github.io/categories/RT-Thread/"/>
<category term="RT-Thread" scheme="https://pdpeng.github.io/tags/RT-Thread/"/>
</entry>
<entry>
<title>Idea 中图片资源无法加载问题</title>
<link href="https://pdpeng.github.io/2022/04/25/Idea-resource-load-error/"/>
<id>https://pdpeng.github.io/2022/04/25/Idea-resource-load-error/</id>
<published>2022-04-25T10:00:23.000Z</published>
<updated>2025-03-10T15:12:25.995Z</updated>
<content type="html"><![CDATA[<blockquote><p>以下为<strong>新手</strong>错误,大神请绕道,谢谢!</p></blockquote><h1 id="问题描述"><a href="#问题描述" class="headerlink" title="问题描述"></a>问题描述</h1><p>今天在看一个 Java 的小游戏时,遇到项目图片资源无法加载的问题,运行显示界面如图</p><p><img src="https://img-blog.csdnimg.cn/7f110ce32e2e44f8a829cf19d821af3b.png"></p><span id="more"></span><p>但是代码一定是没有问题的,逻辑之类的肯定都是通的,毕竟是人家写好的,咱拿来看看是吧</p><p>最后发现问题原来如此简单!!!大家看到这样的问题,首先应该想到的都是图片资源路径问题</p><p>首先我尝试的是在路径前面加 <code>./ 或 ../</code>,甚至用上了绝对路径(但是不推荐,兼容性太差),发现更改绝对路径后显示是没有问题的</p><p><img src="https://img-blog.csdnimg.cn/dacec60bc49f4f94be4ed2c94083d86a.png"></p><p>然后又回归到了相对路径上,因为在学习数据库部分时,同样遇到过路径问题,那时候是让程序显示当前路径解决的,因为会涉及到<strong>添加包名</strong>的问题</p><p>最后解决</p><h1 id="解决方案"><a href="#解决方案" class="headerlink" title="解决方案"></a>解决方案</h1><p>为了避免路径引用这类的错误,直接复制图片在项目中当前的位置,操作在这里</p><p><img src="https://img-blog.csdnimg.cn/5dcc38836fac48f6b58453c80c50ea29.png"></p><p>查看路径</p><p><img src="https://img-blog.csdnimg.cn/0006cff97f1643b5b6a4bfcd91cc868c.png"></p><p>对比源代码,发现少了 <code>sxt</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"><span class="type">Image</span> <span class="variable">bg</span> <span class="operator">=</span> Toolkit.getDefaultToolkit().getImage(<span class="string">"sxt/imgs/bg.jpg"</span>);</span><br></pre></td></tr></table></figure><hr><p><img src="https://img-blog.csdnimg.cn/1d0685b1590b49898f87e9dc55e7241e.png"></p>]]></content>
<summary type="html"><blockquote>
<p>以下为<strong>新手</strong>错误,大神请绕道,谢谢!</p>
</blockquote>
<h1 id="问题描述"><a href="#问题描述" class="headerlink" title="问题描述"></a>问题描述</h1><p>今天在看一个 Java 的小游戏时,遇到项目图片资源无法加载的问题,运行显示界面如图</p>
<p><img src="https://img-blog.csdnimg.cn/7f110ce32e2e44f8a829cf19d821af3b.png"></p></summary>
<category term="Java" scheme="https://pdpeng.github.io/categories/Java/"/>
<category term="Java" scheme="https://pdpeng.github.io/tags/Java/"/>
</entry>
<entry>
<title>SQL 基础(六)多关系连接查询</title>
<link href="https://pdpeng.github.io/2022/04/22/sql-base6/"/>
<id>https://pdpeng.github.io/2022/04/22/sql-base6/</id>
<published>2022-04-22T02:54:41.000Z</published>
<updated>2025-03-10T15:12:26.000Z</updated>
<content type="html"><![CDATA[<h1 id="多关系表连接查询"><a href="#多关系表连接查询" class="headerlink" title="多关系表连接查询"></a>多关系表连接查询</h1><blockquote><p>连接查询:一个查询需要对多张表操作,查询结果称<strong>表之间的连接</strong>;连接关系通过字段值体现,称为<strong>连接字段</strong></p></blockquote><p>当我们查询的数据、字段值分布在不同的表中时,这种情况下需要使用<strong>多关系表的连接查询</strong></p><p>连接类型:内连接(INNER JOIN)、外连接(OUTER JOIN)、交叉连接()、自然连接()</p><p><strong>连接谓词</strong>:连接两个表的条件</p><span id="more"></span><h2 id="内连接查询"><a href="#内连接查询" class="headerlink" title="内连接查询"></a>内连接查询</h2><blockquote><p>关键字(INNER JOIN),功能:仅返回连接条件为真的行,有 <code>from</code> 和 <code>where</code> 字句两种方式</p></blockquote><p>这里要注意,两张表连接时,同名属性需要使用<strong>前缀</strong>区分(列名唯一不需要)</p><p>实现内连接的三种方式举例:</p><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></pre></td><td class="code"><pre><span class="line"><span class="comment">-- method1</span></span><br><span class="line"><span class="keyword">select</span> t.tno,tn,cno</span><br><span class="line"><span class="keyword">from</span> t,tc</span><br><span class="line"><span class="keyword">where</span> (t.tno<span class="operator">=</span>tc.tno) <span class="keyword">and</span> (tn<span class="operator">=</span><span class="string">'XX'</span>) <span class="comment">-- 连接条件、查询条件</span></span><br><span class="line"></span><br><span class="line"><span class="comment">-- method2</span></span><br><span class="line"><span class="keyword">select</span> t.tno,tn,cno <span class="comment">-- 前缀指名tno为t表属性</span></span><br><span class="line"><span class="keyword">from</span> t <span class="keyword">inner</span> <span class="keyword">join</span> tc <span class="comment">-- inner join 内连接关键字</span></span><br><span class="line"><span class="keyword">on</span> t.tno<span class="operator">=</span>tc.tno <span class="comment">-- 连接条件</span></span><br><span class="line"><span class="keyword">where</span> (tn<span class="operator">=</span><span class="string">'XX'</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment">-- method3</span></span><br><span class="line"><span class="keyword">select</span> r1.tno,r2.tn,r1.cno <span class="comment">-- 授课关系 教师号、教室关系 姓名、授课关系 课程号</span></span><br><span class="line"><span class="keyword">from</span></span><br><span class="line">(<span class="keyword">select</span> tno,cno <span class="keyword">from</span> tc) <span class="keyword">as</span> r1</span><br><span class="line"><span class="keyword">inner</span> <span class="keyword">join</span></span><br><span class="line">(<span class="keyword">select</span> tno,tn <span class="keyword">from</span> t <span class="keyword">where</span> tn<span class="operator">=</span><span class="string">'XX'</span>) <span class="keyword">as</span> r2</span><br><span class="line"><span class="keyword">on</span> r1.tno<span class="operator">=</span>r2.tno</span><br></pre></td></tr></table></figure><p>以上方法中,method1 比较简单且常用 ,建议重点掌握</p><h3 id="两张表连接"><a href="#两张表连接" class="headerlink" title="两张表连接"></a>两张表连接</h3><p>查询每位学生及选修课程信息</p><p><strong>1.from 子句实现</strong></p><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">select</span> <span class="operator">*</span></span><br><span class="line"><span class="keyword">from</span> tb_student <span class="keyword">inner</span> <span class="keyword">join</span> tb_score <span class="comment">-- from 表1名称 连接类型(内连接 inner join) 表2名称</span></span><br><span class="line"><span class="keyword">on</span> tb_student.sno<span class="operator">=</span>tb_score.sno <span class="comment">-- 同名属性需要加表名称(否则会出错,系统无法识别)</span></span><br></pre></td></tr></table></figure><p>以上代码可简化为</p><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">select</span> <span class="operator">*</span></span><br><span class="line"><span class="keyword">from</span> tb_student sc <span class="keyword">inner</span> <span class="keyword">join</span> tb_score s <span class="comment">-- 给表起别名,简化代码量</span></span><br><span class="line"><span class="keyword">on</span> sc.sno<span class="operator">=</span>s.sno</span><br></pre></td></tr></table></figure><p>执行结果中发现存在相同列(学号),说明为等值连接,未删去重复列</p><p><img src="https://img-blog.csdnimg.cn/dd0865c75e69409e8024659b12b2d427.png"></p><p><strong>2.where 子句实现</strong></p><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">select</span> <span class="operator">*</span></span><br><span class="line"><span class="keyword">from</span> tb_student s,tb_score sc</span><br><span class="line"><span class="keyword">where</span> s.sno<span class="operator">=</span>sc.sno</span><br></pre></td></tr></table></figure><p>查询每名同学成绩,包含学号,课程编号,成绩,课程名称信息</p><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">select</span> sno,sc.cno,cn,score</span><br><span class="line"><span class="keyword">from</span> tb_score sc, tb_course c</span><br><span class="line"><span class="keyword">where</span> sc.cno<span class="operator">=</span>c.cno</span><br></pre></td></tr></table></figure><h3 id="多张表连接"><a href="#多张表连接" class="headerlink" title="多张表连接"></a>多张表连接</h3><p><strong>1.from 子句</strong></p><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 class="keyword">select</span> s.sno,sn,cn,score</span><br><span class="line"><span class="keyword">from</span> tb_student s <span class="keyword">join</span> tb_score sc</span><br><span class="line"><span class="keyword">on</span> (s.sno<span class="operator">=</span>sc.sno) <span class="keyword">join</span> tb_course c</span><br><span class="line"><span class="keyword">on</span> (sc.cno<span class="operator">=</span>c.cno)</span><br></pre></td></tr></table></figure><p><strong>2.where 子句</strong></p><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">select</span> s.sno,sn,cn,score</span><br><span class="line"><span class="keyword">from</span> tb_student s,tb_score sc,tb_course c</span><br><span class="line"><span class="keyword">where</span> s.sno<span class="operator">=</span>sc.sno <span class="keyword">and</span> sc.sno<span class="operator">=</span>c.cno</span><br></pre></td></tr></table></figure><h2 id="外连接查询"><a href="#外连接查询" class="headerlink" title="外连接查询"></a>外连接查询</h2><p>外连接中,符合连接条件的数据返回到结果集,不符合连接条件的列会被系统用 <code>NULL</code> 填充,再返回结果集</p><p>*注:<code>bit</code> 类型无 <code>NULL</code> 值,会填充 0 后返回结果集中</p><p>使用主表所在的方向位置判断连接类型,例如:主表在左,即为左外连接</p><p>复习下关系运算中,连接的相关知识</p><p><img src="https://img-blog.csdnimg.cn/71a9ee64bd9c48d981a4fcf8a1cebc74.png"></p><p>那么上图两张表分别进行外、左外、右外连接后的结果为</p><p><img src="https://img-blog.csdnimg.cn/5cd32bde6b54410cacb50f84c7033851.png"></p><p>举例:查询所有学生选课情况,包括未选课学生信息</p><h3 id="左外连接-left-join"><a href="#左外连接-left-join" class="headerlink" title="左外连接 left join"></a>左外连接 left join</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></pre></td><td class="code"><pre><span class="line"><span class="comment">-- left join</span></span><br><span class="line"><span class="keyword">select</span> <span class="operator">*</span> <span class="keyword">from</span> tb_student s <span class="keyword">left</span> <span class="keyword">join</span> tb_score sc</span><br><span class="line"><span class="keyword">on</span> (s.sno<span class="operator">=</span>sc.sno)</span><br></pre></td></tr></table></figure><h3 id="右外连接-right-join"><a href="#右外连接-right-join" class="headerlink" title="右外连接 right join"></a>右外连接 right join</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></pre></td><td class="code"><pre><span class="line"><span class="comment">-- right join</span></span><br><span class="line"><span class="keyword">select</span> <span class="operator">*</span> <span class="keyword">from</span> tb_score sc <span class="keyword">right</span> <span class="keyword">join</span> tb_student s</span><br><span class="line"><span class="keyword">on</span> (sc.sno<span class="operator">=</span>s.sno)</span><br></pre></td></tr></table></figure><h3 id="完全外连接-full-join"><a href="#完全外连接-full-join" class="headerlink" title="完全外连接 full join"></a>完全外连接 full join</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></pre></td><td class="code"><pre><span class="line"><span class="comment">-- full join</span></span><br><span class="line"><span class="keyword">select</span> <span class="operator">*</span> <span class="keyword">from</span> tb_student s <span class="keyword">full</span> <span class="keyword">join</span> tb_score sc</span><br><span class="line"><span class="keyword">on</span> (s.sno<span class="operator">=</span>sc.sno)</span><br></pre></td></tr></table></figure><h2 id="交叉连接查询"><a href="#交叉连接查询" class="headerlink" title="交叉连接查询"></a>交叉连接查询</h2><blockquote><p>又称 “笛卡尔乘积” 连接,实际应用中很少使用</p></blockquote><p>考虑到计算机性能,执行效率也不大相同 </p><p>这里主要知道关键字为 CROSS JOIN,结果集行数为两张表行数乘积,列数为两表列数总和,然后参考下下方示例即可</p><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></pre></td><td class="code"><pre><span class="line"><span class="comment">-- 对学生表和成绩表进行 交叉查询</span></span><br><span class="line"><span class="keyword">select</span> <span class="operator">*</span></span><br><span class="line"><span class="keyword">from</span> tb_student <span class="keyword">cross</span> <span class="keyword">join</span> tb_score</span><br></pre></td></tr></table></figure><h2 id="自连接查询"><a href="#自连接查询" class="headerlink" title="自连接查询"></a>自连接查询</h2><blockquote><p>如果我们要查询的结果集中,所包含的信息均在同一张信息表中,这样的查询方式称为<strong>自连接查询</strong></p></blockquote><p>示例:查询工资表中,所有比 XXX 工资高的同事姓名、工资和 XXX 的工资</p><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></pre></td><td class="code"><pre><span class="line"><span class="comment">-- method1 </span></span><br><span class="line"><span class="keyword">select</span> x.tn,x.sal <span class="keyword">as</span> sal_a,y.sal <span class="keyword">as</span> sal_b</span><br><span class="line"><span class="keyword">from</span> t <span class="keyword">as</span> x,t <span class="keyword">as</span> y <span class="comment">-- self connect</span></span><br><span class="line"><span class="keyword">where</span> x.sal <span class="operator">></span> y.sal <span class="keyword">and</span> y.tn<span class="operator">=</span><span class="string">'XXX'</span></span><br><span class="line"></span><br><span class="line"><span class="comment">-- method2 inner join1</span></span><br><span class="line"><span class="keyword">select</span> x.tn.x.sal,y.sal</span><br><span class="line"><span class="keyword">from</span> t <span class="keyword">as</span> x,t <span class="keyword">as</span> y</span><br><span class="line"><span class="keyword">where</span> (x.sal<span class="operator">></span>y.sal) <span class="keyword">and</span> y.tn<span class="operator">=</span><span class="string">'XXX'</span> <span class="comment">-- where ... and</span></span><br><span class="line"></span><br><span class="line"><span class="comment">-- method3 inner join2</span></span><br><span class="line"><span class="keyword">select</span> x.tn,x.sal,y.sal</span><br><span class="line"><span class="keyword">from</span> t <span class="keyword">as</span> x <span class="keyword">inner</span> <span class="keyword">join</span> t <span class="keyword">as</span> y</span><br><span class="line"><span class="keyword">on</span> x.sal <span class="operator">></span> y.sal <span class="keyword">and</span> y.tn<span class="operator">=</span><span class="string">'XXX'</span> <span class="comment">-- inner join ... on</span></span><br><span class="line"></span><br><span class="line"><span class="comment">-- method4 inner join3</span></span><br><span class="line"><span class="keyword">select</span> r1.tn,r1.sal,r2.sal</span><br><span class="line"><span class="keyword">from</span></span><br><span class="line">(<span class="keyword">select</span> tn,sal <span class="keyword">from</span> t) <span class="keyword">as</span> r1</span><br><span class="line"><span class="keyword">inner</span> <span class="keyword">join</span></span><br><span class="line">(<span class="keyword">select</span> tn,sal <span class="keyword">from</span> t <span class="keyword">where</span> tn<span class="operator">=</span><span class="string">'XXX'</span>) <span class="keyword">as</span> r2</span><br><span class="line"><span class="keyword">on</span> r1.sal <span class="operator">></span> r2.sal <span class="comment">-- inner join ... on</span></span><br></pre></td></tr></table></figure><h1 id="子查询"><a href="#子查询" class="headerlink" title="子查询"></a>子查询</h1><p>又称嵌套查询,形式是在 WHERE 中再次包含 SELECT - FROM - WHERE 的查询</p><p>程序<strong>从内向外</strong>执行 SQL 语句,外部查询称为<strong>父查询</strong>,父查询需要接收子查询(嵌套查询)的结果</p><h2 id="普通子查询"><a href="#普通子查询" class="headerlink" title="普通子查询"></a>普通子查询</h2><p>普通子查询仅<strong>执行一次</strong></p><h3 id="返回一个值"><a href="#返回一个值" class="headerlink" title="返回一个值"></a>返回一个值</h3><p>该例子解释<strong>父级查询需要子查询结果</strong>的概念</p><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">select</span> tno,tn</span><br><span class="line"><span class="keyword">from</span> t</span><br><span class="line"><span class="keyword">where</span> prof<span class="operator">=</span>(<span class="keyword">select</span> prof</span><br><span class="line"><span class="keyword">from</span> t</span><br><span class="line"><span class="keyword">where</span> tn<span class="operator">=</span><span class="string">'XXX'</span>)</span><br></pre></td></tr></table></figure><p>示例中,<code>prof</code> 的值由子查询查出结果后返回给父查询做结果,上述语句等价为</p><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">select</span> tno,tn</span><br><span class="line"><span class="keyword">from</span> t</span><br><span class="line"><span class="keyword">where</span> prof<span class="operator">=</span>‘子查询 prof 值’</span><br></pre></td></tr></table></figure><h3 id="返回一组值"><a href="#返回一组值" class="headerlink" title="返回一组值"></a>返回一组值</h3><p>比较运算符仅适用于查询所需返回值为单个值得情况,当返回结果为集合时不再使用,可使用如下方式</p><h4 id="ANY"><a href="#ANY" class="headerlink" title="ANY"></a>ANY</h4><p>ANY:任何一个</p><p>示例:查询讲授课程号为 c5 的教师姓名</p><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">select</span> tn <span class="comment">-- 姓名</span></span><br><span class="line"><span class="keyword">from</span> t </span><br><span class="line"><span class="keyword">where</span> (tno <span class="operator">=</span> <span class="keyword">ANY</span> (<span class="keyword">select</span> tno <span class="comment">-- 教师号</span></span><br><span class="line"> <span class="keyword">from</span> tc</span><br><span class="line"> <span class="keyword">where</span> cno<span class="operator">=</span><span class="string">'c5'</span>)) <span class="comment">-- 课程号</span></span><br></pre></td></tr></table></figure><p>首先执行子查询,找到讲授 c5 课程的教师号,父级查询根据教师号再查询教师姓名</p><p>意思是,<code>tno</code> 是子查询结果集中的任(ANY)一个</p><h4 id="IN"><a href="#IN" class="headerlink" title="IN"></a>IN</h4><p>和 ANY 一样的例子,我们也可以使用 IN 实现</p><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">select</span> tn <span class="comment">-- 姓名</span></span><br><span class="line"><span class="keyword">from</span> t </span><br><span class="line"><span class="keyword">where</span> (tno <span class="keyword">IN</span> (<span class="keyword">select</span> tno <span class="comment">-- 教师号</span></span><br><span class="line"> <span class="keyword">from</span> tc</span><br><span class="line"> <span class="keyword">where</span> cno<span class="operator">=</span><span class="string">'c5'</span>)) <span class="comment">-- 课程号</span></span><br></pre></td></tr></table></figure><p>这里的意思是,<code>tno</code> 在(IN)子查询结果集中</p><h4 id="ALL"><a href="#ALL" class="headerlink" title="ALL"></a>ALL</h4><p>ALL:全部</p><p>示例:查询其他系中比计算机系所有教师工资都高的教师姓名和工资</p><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">-- 使用 ALL</span></span><br><span class="line"><span class="keyword">select</span> tn,sal <span class="comment">-- 姓名、工资</span></span><br><span class="line"><span class="keyword">from</span> t</span><br><span class="line"><span class="keyword">where</span> (sal <span class="operator">></span> <span class="keyword">ALL</span> (<span class="keyword">select</span> sal</span><br><span class="line"> <span class="keyword">from</span> t</span><br><span class="line"> <span class="keyword">where</span> dept<span class="operator">=</span><span class="string">'计算机'</span>))</span><br><span class="line"> <span class="keyword">and</span> (dept <span class="operator"><></span> <span class="string">'计算机'</span>) <span class="comment">-- 父级条件限制 “其他系” 也即为:不属于 ”计算机系”</span></span><br><span class="line"></span><br><span class="line"><span class="comment">-- 使用聚合函数 MAX()</span></span><br><span class="line"><span class="keyword">select</span> tn,sal </span><br><span class="line"><span class="keyword">from</span> t</span><br><span class="line"><span class="keyword">where</span> (sal <span class="operator">></span> (<span class="keyword">select</span> <span class="built_in">MAX</span>(sal)</span><br><span class="line"> <span class="keyword">from</span> t</span><br><span class="line"> <span class="keyword">where</span> dept<span class="operator">=</span><span class="string">'计算机'</span>))</span><br><span class="line"> <span class="keyword">and</span> (dept <span class="operator"><></span> <span class="string">'计算机'</span>) </span><br></pre></td></tr></table></figure><h2 id="相关子查询"><a href="#相关子查询" class="headerlink" title="相关子查询"></a>相关子查询</h2><p>由上面的内容我们知道,子查询程序执行顺序是<strong>由内到外</strong>,也就是说父级需要子级的消息返回</p><p>但是,我们同样会遇到子查询需要父查询相关信息的情况,这样的情况我们称之为<strong>相关子查询</strong></p><p>示例:查询不讲授课程号为 c5 的课程的教师姓名</p><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></pre></td><td class="code"><pre><span class="line"><span class="comment">-- method1 <> ALL</span></span><br><span class="line"><span class="keyword">select</span> <span class="keyword">distinct</span> tn <span class="comment">-- 姓名去重</span></span><br><span class="line"><span class="keyword">from</span> t</span><br><span class="line"><span class="keyword">where</span> (<span class="string">'c5'</span> <span class="operator"><></span> <span class="keyword">ALL</span> (<span class="keyword">select</span> cno <span class="comment">-- 课程号 </span></span><br><span class="line"><span class="keyword">from</span> tc</span><br><span class="line"><span class="keyword">where</span> tno<span class="operator">=</span>t.tno)) <span class="comment">-- tno 教师号</span></span><br><span class="line"></span><br><span class="line"><span class="comment">-- method2 NOT IN</span></span><br><span class="line"><span class="keyword">select</span> <span class="keyword">distinct</span> tn</span><br><span class="line"><span class="keyword">from</span> t</span><br><span class="line"><span class="keyword">where</span> (<span class="string">'c5'</span> <span class="keyword">NOT</span> <span class="keyword">IN</span> (<span class="keyword">select</span> cno </span><br><span class="line"><span class="keyword">from</span> tc</span><br><span class="line"><span class="keyword">where</span> tno<span class="operator">=</span>t.tno)) </span><br><span class="line"></span><br><span class="line"><span class="comment">-- method3 NOT EXISTS</span></span><br><span class="line"><span class="keyword">select</span> tn</span><br><span class="line"><span class="keyword">from</span> t</span><br><span class="line"><span class="keyword">where</span> <span class="keyword">NOT</span> <span class="keyword">EXISTS</span> (<span class="keyword">select</span> <span class="operator">*</span></span><br><span class="line"> <span class="keyword">from</span> tc</span><br><span class="line"> <span class="keyword">where</span> tno<span class="operator">=</span>t.tno <span class="keyword">and</span> cno<span class="operator">=</span><span class="string">'c5'</span>)</span><br></pre></td></tr></table></figure><p>该例中,子查询判断课程号 cno 时,需要数据表 t 中教师号 tno 信息,为相关子查询</p><h1 id="集合运算查询"><a href="#集合运算查询" class="headerlink" title="集合运算查询"></a>集合运算查询</h1><p>在各个子查询对应数据条目和数据类型一致的条件下,可以使用 <code>UNION</code> 关键字将不同的查询得到的数据组合起来</p><p>且 <code>UNION</code> 会自动删除重复数据行</p><p>使用方法比较简单,给出一个例题供参考</p><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">select</span> sno,<span class="built_in">sum</span>(score)</span><br><span class="line"><span class="keyword">from</span> tb_a</span><br><span class="line"><span class="keyword">where</span>(sno<span class="operator">=</span><span class="string">'001'</span>)</span><br><span class="line"><span class="keyword">group</span> <span class="keyword">by</span> sno</span><br><span class="line"><span class="keyword">UNION</span></span><br><span class="line"><span class="keyword">select</span> sno,<span class="built_in">sum</span>(score)</span><br><span class="line"><span class="keyword">from</span> tb_b</span><br><span class="line"><span class="keyword">where</span>(sno<span class="operator">=</span><span class="string">'002'</span>)</span><br><span class="line"><span class="keyword">group</span> <span class="keyword">by</span> sno</span><br></pre></td></tr></table></figure><p>上面的 <code>SQL</code> 语句实现:将从 <code>tb_a</code> 中查询出学号为 001 同学的学号和总成绩信息和从 <code>tb_b</code> 中查询出学号为 002 同学的学号和总成绩信息<strong>合并为一个结果集</strong></p><h1 id="存储查询结果"><a href="#存储查询结果" class="headerlink" title="存储查询结果"></a>存储查询结果</h1><blockquote><p>此处“<strong>存储</strong>”的含义是指将 A 表中查询的数据结果集存储到其他表,B 表中</p></blockquote><p>我们使用 SQL 语句查询到的结果,仅临时导出让用户(我们)看到,并未真正影响(存储)到对应数据库中,那如何实现查询结果的存储呢?</p><p>语法格式为:</p><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">SELECT</span> ... <span class="keyword">INTO</span> ...</span><br></pre></td></tr></table></figure><p>具体实现如下</p><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">selelct sno,<span class="built_in">sum</span>(score) <span class="comment">-- 学号,总成绩</span></span><br><span class="line"><span class="keyword">into</span> tb_b </span><br><span class="line"><span class="keyword">from</span> tb_a</span><br><span class="line"><span class="keyword">group</span> <span class="keyword">by</span> sno <span class="comment">-- 按照学号分组</span></span><br></pre></td></tr></table></figure><p>上面的 <code>SQL</code> 语句实现从 <code>tb_a</code> 中查询出学号和总成绩信息并存放到 <code>tb_b</code> 表中</p>]]></content>
<summary type="html"><h1 id="多关系表连接查询"><a href="#多关系表连接查询" class="headerlink" title="多关系表连接查询"></a>多关系表连接查询</h1><blockquote>
<p>连接查询:一个查询需要对多张表操作,查询结果称<strong>表之间的连接</strong>;连接关系通过字段值体现,称为<strong>连接字段</strong></p>
</blockquote>
<p>当我们查询的数据、字段值分布在不同的表中时,这种情况下需要使用<strong>多关系表的连接查询</strong></p>
<p>连接类型:内连接(INNER JOIN)、外连接(OUTER JOIN)、交叉连接()、自然连接()</p>
<p><strong>连接谓词</strong>:连接两个表的条件</p></summary>
<category term="数据库原理" scheme="https://pdpeng.github.io/categories/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%8E%9F%E7%90%86/"/>
<category term="SQLServer" scheme="https://pdpeng.github.io/tags/SQLServer/"/>
</entry>
<entry>
<title>SQL 基础(八)数据更新操作实战演练</title>
<link href="https://pdpeng.github.io/2022/04/21/sql-base8/"/>
<id>https://pdpeng.github.io/2022/04/21/sql-base8/</id>
<published>2022-04-21T11:30:01.000Z</published>
<updated>2025-03-10T15:12:26.000Z</updated>
<content type="html"><![CDATA[<h1 id="实验内容"><a href="#实验内容" class="headerlink" title="实验内容"></a>实验内容</h1><blockquote><p>根据数据库 <code>db_student</code> 中的 <code>tb_student</code> 表、<code>tb_score</code>、<code>tb_course</code>,完成下列更新语句</p></blockquote><h1 id="表结构"><a href="#表结构" class="headerlink" title="表结构"></a>表结构</h1><ul><li>tb_student(sno,sn,dept,sex,birthday,polity)</li><li>tb_score(sno,cno,score)</li><li>tb_cource(cno,cn,ct,th)<span id="more"></span><h1 id="任务题解"><a href="#任务题解" class="headerlink" title="任务题解"></a>任务题解</h1><h1 id="任务一"><a href="#任务一" class="headerlink" title="任务一"></a>任务一</h1></li></ul><blockquote><p>向学生表中插入一条记录,学号为 00000000,姓名为 XXX,性别为 X 的记录。</p></blockquote><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">INSERT</span> <span class="keyword">INTO</span> tb_student(sno,sn,sex)</span><br><span class="line"><span class="keyword">VALUES</span>(<span class="string">'00000000'</span>,<span class="string">'XXX'</span>,<span class="string">'X'</span>)</span><br></pre></td></tr></table></figure><h1 id="任务二"><a href="#任务二" class="headerlink" title="任务二"></a>任务二</h1><blockquote><p>向学生有中插入一条记录,各字段值依次为:00000000,name,sex,department,XXXX-XX-XX,polity。</p></blockquote><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">INSERT</span> <span class="keyword">INTO</span> tb_student(sno,sn,sex,dept,birthday,polity)</span><br><span class="line"><span class="keyword">VALUES</span>(<span class="string">'00000000'</span>,<span class="string">'name'</span>,<span class="string">'sex'</span>,<span class="string">'department'</span>,<span class="string">'XXXX-XX-XX'</span>,<span class="string">'polity'</span>)</span><br></pre></td></tr></table></figure><h1 id="任务三"><a href="#任务三" class="headerlink" title="任务三"></a>任务三</h1><blockquote><p>在课程表中添加一门新课程,其信息为:(’C8’,’计算机新技术’,’XXX’)。</p></blockquote><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">ALTER</span> <span class="keyword">TABLE</span> tb_course</span><br><span class="line"><span class="keyword">ADD</span> na <span class="type">varchar</span>(<span class="number">10</span>) <span class="keyword">null</span></span><br><span class="line"><span class="keyword">INSERT</span> <span class="keyword">INTO</span> tb_course(cno,cn,na) </span><br><span class="line"><span class="keyword">VALUES</span>(<span class="string">'c8'</span>,<span class="string">'计算机新技术'</span>,<span class="string">'XXX'</span>)</span><br></pre></td></tr></table></figure><h1 id="任务四"><a href="#任务四" class="headerlink" title="任务四"></a>任务四</h1><blockquote><p>在选修关系表 SC 中添加所有学生对’C8’课程的选修关系记录,成绩暂定为 60,请用一条命令完成本批量添加任务。</p></blockquote><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">INSERT</span> <span class="keyword">INTO</span> tb_score(sno,cno,score) </span><br><span class="line"><span class="keyword">SELECT</span> sno,<span class="string">'c8'</span>,<span class="number">60</span> <span class="comment">-- cno/score 定值</span></span><br><span class="line"><span class="keyword">from</span> tb_student</span><br></pre></td></tr></table></figure><h1 id="任务五"><a href="#任务五" class="headerlink" title="任务五"></a>任务五</h1><blockquote><p>将女生的所有数据形成一张新表,表名为 student_girl。</p></blockquote><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">select</span> <span class="operator">*</span> </span><br><span class="line"><span class="keyword">INTO</span> student_girl </span><br><span class="line"><span class="keyword">FROM</span> tb_student <span class="keyword">WHERE</span> sex<span class="operator">=</span><span class="string">'女'</span></span><br></pre></td></tr></table></figure><h1 id="任务六"><a href="#任务六" class="headerlink" title="任务六"></a>任务六</h1><blockquote><p>将学生表中姓名为 XX 同学,性别改为女,出生日期为 1998-1-1。</p></blockquote><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">UPDATE</span> tb_student</span><br><span class="line"><span class="keyword">SET</span> sex<span class="operator">=</span><span class="string">'女'</span>,birthday<span class="operator">=</span><span class="string">'1998-1-1'</span></span><br><span class="line"><span class="keyword">WHERE</span> sn<span class="operator">=</span><span class="string">'XX'</span></span><br></pre></td></tr></table></figure><h1 id="任务七"><a href="#任务七" class="headerlink" title="任务七"></a>任务七</h1><blockquote><p>将 tb_score 表中的 c04 的课程折合为 60%并加上 40 分。</p></blockquote><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">UPDATE</span> tb_score</span><br><span class="line"><span class="keyword">SET</span> score<span class="operator">=</span>score<span class="operator">*</span><span class="number">0.6</span><span class="operator">+</span><span class="number">40</span></span><br><span class="line"><span class="keyword">WHERE</span> cno<span class="operator">=</span><span class="string">'c04'</span></span><br></pre></td></tr></table></figure><h1 id="任务八"><a href="#任务八" class="headerlink" title="任务八"></a>任务八</h1><blockquote><p>将选修数据结构课程的学生成绩增加 15 分。</p></blockquote><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">UPDATE</span> tb_score</span><br><span class="line"><span class="keyword">SET</span> score<span class="operator">=</span>score<span class="operator">+</span><span class="number">15</span></span><br><span class="line"><span class="keyword">WHERE</span> cno<span class="operator">=</span>(<span class="keyword">SELECT</span> cno </span><br><span class="line"> <span class="keyword">FROM</span> tb_course </span><br><span class="line"> <span class="keyword">WHERE</span> cn<span class="operator">=</span><span class="string">'数据结构'</span>)</span><br></pre></td></tr></table></figure><h1 id="任务九"><a href="#任务九" class="headerlink" title="任务九"></a>任务九</h1><blockquote><p>把选“计算机新技术”课程的男学生的成绩暂全部初始化重新设置为 0。</p></blockquote><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">UPDATE</span> tb_score</span><br><span class="line"><span class="keyword">SET</span> score<span class="operator">=</span><span class="number">0</span></span><br><span class="line"><span class="keyword">WHERE</span> sno <span class="keyword">IN</span> (<span class="keyword">SELECT</span> sno</span><br><span class="line"> <span class="keyword">FROM</span> tb_student</span><br><span class="line"> <span class="keyword">WHERE</span> sex<span class="operator">=</span><span class="string">'男'</span>)</span><br><span class="line"><span class="keyword">AND</span> cno<span class="operator">=</span>(<span class="keyword">SELECT</span> cno <span class="comment">-- 两个并列关系子查询</span></span><br><span class="line"> <span class="keyword">FROM</span> tb_course</span><br><span class="line"> <span class="keyword">WHERE</span> cn<span class="operator">=</span><span class="string">'计算机新技术'</span>)</span><br></pre></td></tr></table></figure><h1 id="任务十"><a href="#任务十" class="headerlink" title="任务十"></a>任务十</h1><blockquote><p> 删除学生表中所有姓张的同学。</p></blockquote><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">DELETE</span> <span class="keyword">FROM</span> tb_student</span><br><span class="line"><span class="keyword">WHERE</span> <span class="keyword">LEFT</span> <span class="keyword">JOIN</span>(sn,<span class="number">1</span>)<span class="operator">=</span><span class="string">'张'</span> <span class="comment">-- 或 WHERE sn LIKE '张%'</span></span><br></pre></td></tr></table></figure><h1 id="任务十一"><a href="#任务十一" class="headerlink" title="任务十一"></a>任务十一</h1><blockquote><p>删除 student 表中不及格同学的所有信息。</p></blockquote><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">DELETE</span> <span class="keyword">FROM</span> tb_student</span><br><span class="line"><span class="keyword">WHERE</span> sno<span class="operator">=</span>(<span class="keyword">SELECT</span> <span class="keyword">DISTINCT</span> sno</span><br><span class="line"> <span class="keyword">FROM</span> tb_score</span><br><span class="line"> <span class="keyword">WHERE</span> score<span class="operator"><</span><span class="number">60</span>)</span><br></pre></td></tr></table></figure><h1 id="任务十二"><a href="#任务十二" class="headerlink" title="任务十二"></a>任务十二</h1><blockquote><p>XXX 同学的学生信息及其选课情况等全部删除。</p></blockquote><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">-- 删除顺序颠倒会导致成绩表中无法找到XXX学生学号</span></span><br><span class="line"><span class="comment">-- 1.删除成绩表XXX成绩信息</span></span><br><span class="line"><span class="keyword">DELETE</span> <span class="keyword">FROM</span> tb_score</span><br><span class="line"><span class="keyword">WHERE</span> sno<span class="operator">=</span>(<span class="keyword">SELECT</span> sno</span><br><span class="line"> <span class="keyword">FROM</span> tb_student</span><br><span class="line"> <span class="keyword">WHERE</span> sn<span class="operator">=</span><span class="string">'XXX'</span>)</span><br><span class="line"><span class="comment">-- 2.删除XXX学生信息 </span></span><br><span class="line"><span class="keyword">DELETE</span> <span class="keyword">FROM</span> tb_student</span><br><span class="line"><span class="keyword">WHERE</span> sn<span class="operator">=</span><span class="string">'XXX'</span></span><br></pre></td></tr></table></figure><h1 id="任务十三"><a href="#任务十三" class="headerlink" title="任务十三"></a>任务十三</h1><blockquote><p>删除学生表中所有学生信息(两种方法)。</p></blockquote><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">-- method1</span></span><br><span class="line"><span class="keyword">DELETE</span> <span class="keyword">FROM</span> tb_student</span><br><span class="line"></span><br><span class="line"><span class="comment">-- method2</span></span><br><span class="line"><span class="keyword">TRUNCATE</span> <span class="keyword">TABLE</span> tb_student</span><br></pre></td></tr></table></figure><hr><p>在修改表信息书写 <code>SQL</code> 语句时,遵循 <code>SET</code>、<code>UPDATE</code>、<code>WHERE</code> 的书写顺序</p><p>即首先设置值,然后选定作用范围,最后增加限制条件。这样思路会更加清晰</p>]]></content>
<summary type="html"><h1 id="实验内容"><a href="#实验内容" class="headerlink" title="实验内容"></a>实验内容</h1><blockquote>
<p>根据数据库 <code>db_student</code> 中的 <code>tb_student</code> 表、<code>tb_score</code>、<code>tb_course</code>,完成下列更新语句</p>
</blockquote>
<h1 id="表结构"><a href="#表结构" class="headerlink" title="表结构"></a>表结构</h1><ul>
<li>tb_student(sno,sn,dept,sex,birthday,polity)</li>
<li>tb_score(sno,cno,score)</li>
<li>tb_cource(cno,cn,ct,th)</summary>
<category term="数据库原理" scheme="https://pdpeng.github.io/categories/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%8E%9F%E7%90%86/"/>
<category term="SQLServer" scheme="https://pdpeng.github.io/tags/SQLServer/"/>
</entry>
<entry>
<title>【欧拉计划第 12 题】 高度可除的三角数 Highly divisible triangular number</title>
<link href="https://pdpeng.github.io/2022/04/21/projecteuler012/"/>
<id>https://pdpeng.github.io/2022/04/21/projecteuler012/</id>
<published>2022-04-21T08:21:17.000Z</published>
<updated>2025-03-10T15:12:25.998Z</updated>
<content type="html"><![CDATA[<h1 id="Problem-12-Highly-divisible-triangular-number"><a href="#Problem-12-Highly-divisible-triangular-number" class="headerlink" title="Problem 12 Highly divisible triangular number"></a>Problem 12 Highly divisible triangular number</h1><blockquote><p>The sequence of triangle numbers is generated by adding the natural numbers. So the 7th triangle number would be $1 + 2 + 3 + 4 + 5 + 6 + 7 = 28$. The first ten terms would be:</p></blockquote><p>$$<br>1, 3, 6, 10, 15, 21, 28, 36, 45, 55, …<br>$$</p><blockquote><p>Let us list the factors of the first seven triangle numbers:</p></blockquote><center><img src="https://img-blog.csdnimg.cn/cf3be2c00a464bcf84f265b57f648408.png"></center><blockquote><p>We can see that $28$ is the first triangle number to have over five divisors.<br>What is the value of the first triangle number to have over five hundred divisors?</p></blockquote><span id="more"></span><h1 id="问题-12-高度可除的三角数"><a href="#问题-12-高度可除的三角数" class="headerlink" title="问题 12 高度可除的三角数"></a>问题 12 高度可除的三角数</h1><blockquote><p>三角数由<strong>依次排列的自然数的和</strong>生成。所以第 $7$ 个三角数是 $1 + 2 + 3 + 4 + 5 + 6 + 7 = 28$。前十项是:</p></blockquote><p>$$<br>1, 3, 6, 10, 15, 21, 28, 36, 45, 55, …<br>$$</p><blockquote><p>让我们列出前七个三角数的因数:</p></blockquote><center><img src="https://img-blog.csdnimg.cn/cf3be2c00a464bcf84f265b57f648408.png"></center><blockquote><p>我们可以看到 $28$ 是第一个有五个以上除数(因子)的三角数。<br>第一个有超过 $500$ 个除数(因子)的三角数的值是多少?</p></blockquote><h1 id="思路分析"><a href="#思路分析" class="headerlink" title="思路分析"></a>思路分析</h1><p>拿到题目,我们首先做的要理解清除题目含义,对于从未听过的陌生概念、术语(一般会举例说明),我们也要试着首先理解示例</p><p>这里解释下题目中的<strong>三角数</strong>是如何得出的,请看下表计算过程</p><table><thead><tr><th>第 x 个</th><th>三角数值</th><th>计算过程</th></tr></thead><tbody><tr><td>1</td><td>1</td><td>1</td></tr><tr><td>2</td><td>3</td><td>1+2=3</td></tr><tr><td>3</td><td>6</td><td>1+2+3=6</td></tr><tr><td>4</td><td>10</td><td>1+2+3+4=10</td></tr><tr><td>5</td><td>15</td><td>1+2+3+4+5=15</td></tr><tr><td>6</td><td>21</td><td>1+2+3+4+5+6=21</td></tr><tr><td>7</td><td>28</td><td>1+2+3+4+5+6+7=28</td></tr><tr><td>…</td><td>…</td><td>…</td></tr></tbody></table><p>依然是老朋友,<strong>暴力枚举</strong>,从 $1$ 开始依次枚举每个数字并<strong>判断它有多少个约数</strong></p><p>当约数个数大于 $500$ 时,退出循环并输出该值</p><h1 id="代码实现"><a href="#代码实现" class="headerlink" title="代码实现"></a>代码实现</h1><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment"> * @Author: coder-jason</span></span><br><span class="line"><span class="comment"> * @Date: 2022-04-19 20:58:43</span></span><br><span class="line"><span class="comment"> * @LastEditTime: 2022-04-19 21:58:30</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><bits/stdc++.h></span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">factor</span><span class="params">(<span class="type">long</span> <span class="type">long</span> n)</span> <span class="comment">// 计算数字 num 因数个数 , 注意数据范围</span></span></span><br><span class="line"><span class="function"></span>{ </span><br><span class="line"> <span class="type">int</span> count = <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">for</span> (<span class="type">long</span> <span class="type">long</span> i = <span class="number">1</span>; i * i <= n; i++)</span><br><span class="line"> {</span><br><span class="line"> <span class="keyword">if</span> (n % i == <span class="number">0</span>)</span><br><span class="line"> {</span><br><span class="line"> <span class="keyword">if</span> (i * i == n)</span><br><span class="line"> count++;</span><br><span class="line"> <span class="keyword">else</span></span><br><span class="line"> count += <span class="number">2</span>;</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> count;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line"> <span class="type">int</span> num = <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">for</span> (<span class="type">long</span> <span class="type">long</span> i = <span class="number">1</span>;; i++)</span><br><span class="line"> {</span><br><span class="line"> num += i; <span class="comment">// 枚举三角数 循环过程可参照末尾注解</span></span><br><span class="line"> <span class="keyword">if</span> (<span class="built_in">factor</span>(num) > <span class="number">500</span>) <span class="comment">// 传值给 facto() 返回 num 因数个数</span></span><br><span class="line"> {</span><br><span class="line"> cout << num << endl; <span class="comment">// 满足条件"第一个有超过 500 个因子"的三角数时,输出 num 值</span></span><br><span class="line"> <span class="keyword">break</span>; <span class="comment">// 循环结束</span></span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">} <span class="comment">// num i num+=i; 过程演示</span></span><br><span class="line"> <span class="comment">// 0 1</span></span><br><span class="line"> <span class="comment">// 1 2</span></span><br><span class="line"> <span class="comment">// 3 3</span></span><br><span class="line"> <span class="comment">// 6 4</span></span><br><span class="line"> <span class="comment">// 10 5</span></span><br><span class="line"></span><br></pre></td></tr></table></figure><blockquote><p>答案:76576500</p></blockquote><hr><p>本题在完成三角数的枚举后,最重要的一步是<strong>如何判断一个数约数的个数</strong></p><p>从基本思想不断优化,降低算法的时间复杂度,详请参考<span class="exturl" data-url="aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L20wXzUxMjY5OTYxL2FydGljbGUvZGV0YWlscy8xMjQzMjQ3MDM=">快速计算约数的个数——从基础到高级<i class="fa fa-external-link-alt"></i></span></p>]]></content>
<summary type="html"><h1 id="Problem-12-Highly-divisible-triangular-number"><a href="#Problem-12-Highly-divisible-triangular-number" class="headerlink" title="Problem 12 Highly divisible triangular number"></a>Problem 12 Highly divisible triangular number</h1><blockquote>
<p>The sequence of triangle numbers is generated by adding the natural numbers. So the 7th triangle number would be $1 + 2 + 3 + 4 + 5 + 6 + 7 &#x3D; 28$. The first ten terms would be:</p>
</blockquote>
<p>$$<br>1, 3, 6, 10, 15, 21, 28, 36, 45, 55, …<br>$$</p>
<blockquote>
<p>Let us list the factors of the first seven triangle numbers:</p>
</blockquote>
<center><img src="https://img-blog.csdnimg.cn/cf3be2c00a464bcf84f265b57f648408.png"></center>
<blockquote>
<p>We can see that $28$ is the first triangle number to have over five divisors.<br>What is the value of the first triangle number to have over five hundred divisors?</p>
</blockquote></summary>
<category term="欧拉计划" scheme="https://pdpeng.github.io/categories/%E6%AC%A7%E6%8B%89%E8%AE%A1%E5%88%92/"/>
<category term="ACM" scheme="https://pdpeng.github.io/tags/ACM/"/>
</entry>
<entry>
<title>【欧拉计划第 13 题】 大数之和 Large sum</title>
<link href="https://pdpeng.github.io/2022/04/21/projecteuler013/"/>
<id>https://pdpeng.github.io/2022/04/21/projecteuler013/</id>
<published>2022-04-21T06:50:39.000Z</published>
<updated>2025-03-10T15:12:25.998Z</updated>
<content type="html"><![CDATA[<h1 id="Problem-13-Large-sum"><a href="#Problem-13-Large-sum" class="headerlink" title="Problem 13 Large sum"></a>Problem 13 Large sum</h1><blockquote><p>Work out the first ten digits of the sum of the following one-hundred $50$-digit numbers.</p></blockquote><p><strong>Data file see end</strong></p><span id="more"></span><h1 id="问题-13-大数之和"><a href="#问题-13-大数之和" class="headerlink" title="问题 13 大数之和"></a>问题 13 大数之和</h1><blockquote><p>计算以下 $100$ 个 $50$ 位数字和的前十位数</p></blockquote><p><strong>数据文件见文末</strong></p><h1 id="思路分析"><a href="#思路分析" class="headerlink" title="思路分析"></a>思路分析</h1><p>大家看到题目,首先不要被这一堆数字给吓到,觉得它很难,我们仔细阅读下题干,发现并不难,所用知识点都比较容易</p><p>将这 $100$ 个 $50$ 位数字写在程序中显得比较冗长,这里我们使用 <code>Python</code> 解决</p><p>直接将数据存入 <code>txt</code> 文本文件中,用 <code>Python</code> 打开文件并读取数据</p><p>求出总和后将<strong>和</strong>转化为字符串,最后截取前十位,得解</p><center><img src="https://img-blog.csdnimg.cn/b790e0cf8f7d43e685b94684fdff6a4c.gif" width=300></center><h1 id="代码实现"><a href="#代码实现" class="headerlink" title="代码实现"></a>代码实现</h1><figure class="highlight python"><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="string">'''</span></span><br><span class="line"><span class="string">Author: coder-jason</span></span><br><span class="line"><span class="string">Date: 2022-04-20 21:37:16</span></span><br><span class="line"><span class="string">LastEditTime: 2022-04-21 14:20:56 </span></span><br><span class="line"><span class="string">'''</span></span><br><span class="line"></span><br><span class="line">Max_num = <span class="built_in">sum</span>(<span class="built_in">map</span>(<span class="built_in">int</span>,<span class="built_in">open</span>(<span class="string">'ProjectEuler/data/013.txt'</span>)))</span><br><span class="line">ans = <span class="built_in">str</span>(Max_num)[:<span class="number">10</span>]</span><br><span class="line"><span class="built_in">print</span>(ans) </span><br></pre></td></tr></table></figure><blockquote><p>答案:5537376230</p></blockquote><p>如果在打开文件时遇到错误 <strong>FileNotFoundError: [Errno 2] No such file or directory</strong>,请<span class="exturl" data-url="aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L20wXzUxMjY5OTYxL2FydGljbGUvZGV0YWlscy8xMjQzMjEwNzU=">查看这里<i class="fa fa-external-link-alt"></i></span></p><h1 id="数据文件"><a href="#数据文件" class="headerlink" title="数据文件"></a>数据文件</h1><figure class="highlight txt"><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></pre></td><td class="code"><pre><span class="line">37107287533902102798797998220837590246510135740250</span><br><span class="line">46376937677490009712648124896970078050417018260538</span><br><span class="line">74324986199524741059474233309513058123726617309629</span><br><span class="line">91942213363574161572522430563301811072406154908250</span><br><span class="line">23067588207539346171171980310421047513778063246676</span><br><span class="line">89261670696623633820136378418383684178734361726757</span><br><span class="line">28112879812849979408065481931592621691275889832738</span><br><span class="line">44274228917432520321923589422876796487670272189318</span><br><span class="line">47451445736001306439091167216856844588711603153276</span><br><span class="line">70386486105843025439939619828917593665686757934951</span><br><span class="line">62176457141856560629502157223196586755079324193331</span><br><span class="line">64906352462741904929101432445813822663347944758178</span><br><span class="line">92575867718337217661963751590579239728245598838407</span><br><span class="line">58203565325359399008402633568948830189458628227828</span><br><span class="line">80181199384826282014278194139940567587151170094390</span><br><span class="line">35398664372827112653829987240784473053190104293586</span><br><span class="line">86515506006295864861532075273371959191420517255829</span><br><span class="line">71693888707715466499115593487603532921714970056938</span><br><span class="line">54370070576826684624621495650076471787294438377604</span><br><span class="line">53282654108756828443191190634694037855217779295145</span><br><span class="line">36123272525000296071075082563815656710885258350721</span><br><span class="line">45876576172410976447339110607218265236877223636045</span><br><span class="line">17423706905851860660448207621209813287860733969412</span><br><span class="line">81142660418086830619328460811191061556940512689692</span><br><span class="line">51934325451728388641918047049293215058642563049483</span><br><span class="line">62467221648435076201727918039944693004732956340691</span><br><span class="line">15732444386908125794514089057706229429197107928209</span><br><span class="line">55037687525678773091862540744969844508330393682126</span><br><span class="line">18336384825330154686196124348767681297534375946515</span><br><span class="line">80386287592878490201521685554828717201219257766954</span><br><span class="line">78182833757993103614740356856449095527097864797581</span><br><span class="line">16726320100436897842553539920931837441497806860984</span><br><span class="line">48403098129077791799088218795327364475675590848030</span><br><span class="line">87086987551392711854517078544161852424320693150332</span><br><span class="line">59959406895756536782107074926966537676326235447210</span><br><span class="line">69793950679652694742597709739166693763042633987085</span><br><span class="line">41052684708299085211399427365734116182760315001271</span><br><span class="line">65378607361501080857009149939512557028198746004375</span><br><span class="line">35829035317434717326932123578154982629742552737307</span><br><span class="line">94953759765105305946966067683156574377167401875275</span><br><span class="line">88902802571733229619176668713819931811048770190271</span><br><span class="line">25267680276078003013678680992525463401061632866526</span><br><span class="line">36270218540497705585629946580636237993140746255962</span><br><span class="line">24074486908231174977792365466257246923322810917141</span><br><span class="line">91430288197103288597806669760892938638285025333403</span><br><span class="line">34413065578016127815921815005561868836468420090470</span><br><span class="line">23053081172816430487623791969842487255036638784583</span><br><span class="line">11487696932154902810424020138335124462181441773470</span><br><span class="line">63783299490636259666498587618221225225512486764533</span><br><span class="line">67720186971698544312419572409913959008952310058822</span><br><span class="line">95548255300263520781532296796249481641953868218774</span><br><span class="line">76085327132285723110424803456124867697064507995236</span><br><span class="line">37774242535411291684276865538926205024910326572967</span><br><span class="line">23701913275725675285653248258265463092207058596522</span><br><span class="line">29798860272258331913126375147341994889534765745501</span><br><span class="line">18495701454879288984856827726077713721403798879715</span><br><span class="line">38298203783031473527721580348144513491373226651381</span><br><span class="line">34829543829199918180278916522431027392251122869539</span><br><span class="line">40957953066405232632538044100059654939159879593635</span><br><span class="line">29746152185502371307642255121183693803580388584903</span><br><span class="line">41698116222072977186158236678424689157993532961922</span><br><span class="line">62467957194401269043877107275048102390895523597457</span><br><span class="line">23189706772547915061505504953922979530901129967519</span><br><span class="line">86188088225875314529584099251203829009407770775672</span><br><span class="line">11306739708304724483816533873502340845647058077308</span><br><span class="line">82959174767140363198008187129011875491310547126581</span><br><span class="line">97623331044818386269515456334926366572897563400500</span><br><span class="line">42846280183517070527831839425882145521227251250327</span><br><span class="line">55121603546981200581762165212827652751691296897789</span><br><span class="line">32238195734329339946437501907836945765883352399886</span><br><span class="line">75506164965184775180738168837861091527357929701337</span><br><span class="line">62177842752192623401942399639168044983993173312731</span><br><span class="line">32924185707147349566916674687634660915035914677504</span><br><span class="line">99518671430235219628894890102423325116913619626622</span><br><span class="line">73267460800591547471830798392868535206946944540724</span><br><span class="line">76841822524674417161514036427982273348055556214818</span><br><span class="line">97142617910342598647204516893989422179826088076852</span><br><span class="line">87783646182799346313767754307809363333018982642090</span><br><span class="line">10848802521674670883215120185883543223812876952786</span><br><span class="line">71329612474782464538636993009049310363619763878039</span><br><span class="line">62184073572399794223406235393808339651327408011116</span><br><span class="line">66627891981488087797941876876144230030984490851411</span><br><span class="line">60661826293682836764744779239180335110989069790714</span><br><span class="line">85786944089552990653640447425576083659976645795096</span><br><span class="line">66024396409905389607120198219976047599490197230297</span><br><span class="line">64913982680032973156037120041377903785566085089252</span><br><span class="line">16730939319872750275468906903707539413042652315011</span><br><span class="line">94809377245048795150954100921645863754710598436791</span><br><span class="line">78639167021187492431995700641917969777599028300699</span><br><span class="line">15368713711936614952811305876380278410754449733078</span><br><span class="line">40789923115535562561142322423255033685442488917353</span><br><span class="line">44889911501440648020369068063960672322193204149535</span><br><span class="line">41503128880339536053299340368006977710650566631954</span><br><span class="line">81234880673210146739058568557934581403627822703280</span><br><span class="line">82616570773948327592232845941706525094512325230608</span><br><span class="line">22918802058777319719839450180888072429661980811197</span><br><span class="line">77158542502016545090413245809786882778948721859617</span><br><span class="line">72107838435069186155435662884062257473692284509516</span><br><span class="line">20849603980134001723930671666823555245252804609722</span><br><span class="line">53503534226472524250874054075591789781264330331690</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html"><h1 id="Problem-13-Large-sum"><a href="#Problem-13-Large-sum" class="headerlink" title="Problem 13 Large sum"></a>Problem 13 Large sum</h1><blockquote>
<p>Work out the first ten digits of the sum of the following one-hundred $50$-digit numbers.</p>
</blockquote>
<p><strong>Data file see end</strong></p></summary>
<category term="欧拉计划" scheme="https://pdpeng.github.io/categories/%E6%AC%A7%E6%8B%89%E8%AE%A1%E5%88%92/"/>
<category term="ACM" scheme="https://pdpeng.github.io/tags/ACM/"/>
</entry>
<entry>
<title>FileNotFoundError: [Errno 2] No such file or directory</title>
<link href="https://pdpeng.github.io/2022/04/21/python-error/"/>
<id>https://pdpeng.github.io/2022/04/21/python-error/</id>
<published>2022-04-21T06:48:28.000Z</published>
<updated>2025-03-10T15:12:25.998Z</updated>
<content type="html"><![CDATA[<h1 id="问题描述"><a href="#问题描述" class="headerlink" title="问题描述"></a>问题描述</h1><p>最近用 Python 解决<span class="exturl" data-url="aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L20wXzUxMjY5OTYxL2FydGljbGUvZGV0YWlscy8xMjQzMDc5MzI=">欧拉计划第十三题<i class="fa fa-external-link-alt"></i></span>时,打开文件时总是报错</p><p><code>FileNotFoundError: [Errno 2] No such file or directory: '/ProjectEuler/data/013.txt'</code></p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">map</span>(<span class="built_in">int</span>,<span class="built_in">open</span>(<span class="string">'data/013.txt'</span>))</span><br></pre></td></tr></table></figure><p><img src="https://img-blog.csdnimg.cn/8c827acbcd1b4067888f945d95c5306a.png"></p><p>后来查了下,发现是和编辑器有关系,涉及到<strong>工作区</strong>的概念,下面给出解决方案</p><span id="more"></span><h1 id="解决方案"><a href="#解决方案" class="headerlink" title="解决方案"></a>解决方案</h1><p>首先给大家看下我的工作区,<code>Vscode</code> 编辑器解析打开的整个文件夹为工作区</p><p><img src="https://img-blog.csdnimg.cn/d7c532c3a2ba4a70ab606efa80ec036b.png"></p><p>什么意思呢?就是说,这里编辑器默认我们的工作区是 <code>algorithms</code> 这一整个文件夹,文件位置分布是这样的</p><figure class="highlight bash"><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">algorithms</span><br><span class="line">|__ProjectEuler</span><br><span class="line">|__data</span><br><span class="line">||__013.txt</span><br><span class="line">|__013.py</span><br></pre></td></tr></table></figure><p>如果我们要让程序正确识别文件位置,应该将路径修改为<strong>相对工作区</strong>的路径,即:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">map</span>(<span class="built_in">int</span>,<span class="built_in">open</span>(<span class="string">'ProjectEuler/data/013.txt'</span>))</span><br></pre></td></tr></table></figure><p>此时再次执行代码,便不会报错</p><p><img src="https://img-blog.csdnimg.cn/03bf9f645c964bea94bf1ec7f24e23bc.png"></p><hr><p>参考资料:</p><ul><li><span class="exturl" data-url="aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3UwMTI1NjExNzYvYXJ0aWNsZS9kZXRhaWxzLzgyMTA3MzUw">Python OSError: Errno 22 Invalid argument:的出现和解决<i class="fa fa-external-link-alt"></i></span></li></ul>]]></content>
<summary type="html"><h1 id="问题描述"><a href="#问题描述" class="headerlink" title="问题描述"></a>问题描述</h1><p>最近用 Python 解决<span class="exturl" data-url="aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L20wXzUxMjY5OTYxL2FydGljbGUvZGV0YWlscy8xMjQzMDc5MzI=">欧拉计划第十三题<i class="fa fa-external-link-alt"></i></span>时,打开文件时总是报错</p>
<p><code>FileNotFoundError: [Errno 2] No such file or directory: &#39;/ProjectEuler/data/013.txt&#39;</code></p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">map</span>(<span class="built_in">int</span>,<span class="built_in">open</span>(<span class="string">&#x27;data/013.txt&#x27;</span>))</span><br></pre></td></tr></table></figure>
<p><img src="https://img-blog.csdnimg.cn/8c827acbcd1b4067888f945d95c5306a.png"></p>
<p>后来查了下,发现是和编辑器有关系,涉及到<strong>工作区</strong>的概念,下面给出解决方案</p></summary>
<category term="Python" scheme="https://pdpeng.github.io/categories/Python/"/>
<category term="Python" scheme="https://pdpeng.github.io/tags/Python/"/>
</entry>
<entry>
<title>超火 3D 照片墙,你学废了吗?</title>
<link href="https://pdpeng.github.io/2022/04/20/3d-pictures-wall/"/>
<id>https://pdpeng.github.io/2022/04/20/3d-pictures-wall/</id>
<published>2022-04-20T04:44:39.000Z</published>
<updated>2025-03-10T15:12:25.995Z</updated>
<content type="html"><![CDATA[<blockquote><p>👲👲<font color=#a2a837 size=3>作者主页</font>:🔗<span class="exturl" data-url="aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L20wXzUxMjY5OTYx">杰森的博客<i class="fa fa-external-link-alt"></i></span><br>📒📒<font color=#20b9cd size=3>本文摘要</font>:<strong>用前端的知识实现<strong>立体滚动照片墙</strong></strong><br>💖💖感觉本文还不错的话,还请各位小伙伴👍点赞➕收藏⭐➕评论💭支持杰森呀✌️</p></blockquote><p><img src="https://img-blog.csdnimg.cn/2d38694568334676a6f610b9735ac426.gif#pic_center"></p><span id="more"></span><hr><p>话不多说,直接上源码!!!</p><h1 id="index-html"><a href="#index-html" class="headerlink" title="index.html"></a>index.html</h1><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><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></pre></td><td class="code"><pre><span class="line"><span class="comment"><!--</span></span><br><span class="line"><span class="comment"> * @Author: coder-jason</span></span><br><span class="line"><span class="comment"> * @Date: 2022-04-20 11:38:07</span></span><br><span class="line"><span class="comment"> * @LastEditTime: 2022-04-20 12:27:05</span></span><br><span class="line"><span class="comment">--></span></span><br><span class="line"><span class="meta"><!DOCTYPE <span class="keyword">html</span>></span></span><br><span class="line"><span class="tag"><<span class="name">html</span> <span class="attr">lang</span>=<span class="string">"en"</span>></span></span><br><span class="line"></span><br><span class="line"><span class="tag"><<span class="name">head</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">meta</span> <span class="attr">charset</span>=<span class="string">"UTF-8"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">meta</span> <span class="attr">http-equiv</span>=<span class="string">"X-UA-Compatible"</span> <span class="attr">content</span>=<span class="string">"IE=edge"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">meta</span> <span class="attr">name</span>=<span class="string">"viewport"</span> <span class="attr">content</span>=<span class="string">"width=device-width, initial-scale=1.0"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">title</span>></span>超火🔥照片墙<span class="tag"></<span class="name">title</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">link</span> <span class="attr">rel</span>=<span class="string">"stylesheet"</span> <span class="attr">href</span>=<span class="string">"./style.css"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">link</span> <span class="attr">rel</span>=<span class="string">"icon"</span> <span class="attr">type</span>=<span class="string">"image/png"</span> <span class="attr">href</span>=<span class="string">"https://coder-jason.cn/images/favicon-32x32.png"</span>></span></span><br><span class="line"><span class="tag"></<span class="name">head</span>></span></span><br><span class="line"></span><br><span class="line"><span class="tag"><<span class="name">body</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">div</span> <span class="attr">class</span>=<span class="string">"perspective"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">div</span> <span class="attr">class</span>=<span class="string">"wrap"</span> <span class="attr">id</span>=<span class="string">"imgwrap"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">img</span> <span class="attr">src</span>=<span class="string">"./img/1.jpg"</span> <span class="attr">alt</span>=<span class="string">"demo"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">img</span> <span class="attr">src</span>=<span class="string">"./img/2.jpg"</span> <span class="attr">alt</span>=<span class="string">"demo"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">img</span> <span class="attr">src</span>=<span class="string">"./img/3.jpg"</span> <span class="attr">alt</span>=<span class="string">"demo"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">img</span> <span class="attr">src</span>=<span class="string">"./img/4.jpg"</span> <span class="attr">alt</span>=<span class="string">"demo"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">img</span> <span class="attr">src</span>=<span class="string">"./img/5.jpg"</span> <span class="attr">alt</span>=<span class="string">"demo"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">img</span> <span class="attr">src</span>=<span class="string">"./img/6.jpg"</span> <span class="attr">alt</span>=<span class="string">"demo"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">img</span> <span class="attr">src</span>=<span class="string">"./img/7.jpg"</span> <span class="attr">alt</span>=<span class="string">"demo"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">img</span> <span class="attr">src</span>=<span class="string">"./img/8.jpg"</span> <span class="attr">alt</span>=<span class="string">"demo"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">img</span> <span class="attr">src</span>=<span class="string">"./img/9.jpg"</span> <span class="attr">alt</span>=<span class="string">"demo"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">img</span> <span class="attr">src</span>=<span class="string">"./img/10.jpg"</span> <span class="attr">alt</span>=<span class="string">"demo"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">img</span> <span class="attr">src</span>=<span class="string">"./img/11.jpg"</span> <span class="attr">alt</span>=<span class="string">"demo"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">img</span> <span class="attr">src</span>=<span class="string">"./img/12.jpg"</span> <span class="attr">alt</span>=<span class="string">"demo"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">img</span> <span class="attr">src</span>=<span class="string">"./img/13.jpg"</span> <span class="attr">alt</span>=<span class="string">"demo"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">img</span> <span class="attr">src</span>=<span class="string">"./img/14.jpg"</span> <span class="attr">alt</span>=<span class="string">"demo"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">img</span> <span class="attr">src</span>=<span class="string">"./img/15.jpg"</span> <span class="attr">alt</span>=<span class="string">"demo"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">img</span> <span class="attr">src</span>=<span class="string">"./img/16.jpg"</span> <span class="attr">alt</span>=<span class="string">"demo"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">img</span> <span class="attr">src</span>=<span class="string">"./img/17.jpg"</span> <span class="attr">alt</span>=<span class="string">"demo"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">img</span> <span class="attr">src</span>=<span class="string">"./img/18.jpg"</span> <span class="attr">alt</span>=<span class="string">"demo"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">img</span> <span class="attr">src</span>=<span class="string">"./img/19.jpg"</span> <span class="attr">alt</span>=<span class="string">"demo"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">img</span> <span class="attr">src</span>=<span class="string">"./img/20.jpg"</span> <span class="attr">alt</span>=<span class="string">"demo"</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">div</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">div</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">script</span> <span class="attr">type</span>=<span class="string">"text/javascript"</span> <span class="attr">src</span>=<span class="string">"script.js"</span>></span><span class="tag"></<span class="name">script</span>></span></span><br><span class="line"><span class="tag"></<span class="name">body</span>></span></span><br><span class="line"></span><br><span class="line"><span class="tag"></<span class="name">html</span>></span></span><br></pre></td></tr></table></figure><h1 id="style-css"><a href="#style-css" class="headerlink" title="style.css"></a>style.css</h1><figure class="highlight css"><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="comment">/* </span></span><br><span class="line"><span class="comment"> * @Author: coder-jason</span></span><br><span class="line"><span class="comment"> * @Date: 2022-04-20 11:38:07</span></span><br><span class="line"><span class="comment"> * @LastEditTime: 2022-04-20 12:27:38</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line">* {</span><br><span class="line"> <span class="attribute">margin</span>: <span class="number">0</span>; </span><br><span class="line"> <span class="attribute">padding</span>: <span class="number">0</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="selector-tag">body</span> {</span><br><span class="line"> <span class="attribute">background</span>: <span class="number">#222</span>;</span><br><span class="line"> <span class="attribute">overflow</span>: hidden;</span><br><span class="line"> user-select: none;</span><br><span class="line"> <span class="attribute">background-image</span>: <span class="built_in">url</span>(<span class="string">./img/bgi.png</span>);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="selector-class">.perspective</span> {</span><br><span class="line"> <span class="attribute">perspective</span>: <span class="number">800px</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="selector-class">.wrap</span> {</span><br><span class="line"> <span class="attribute">width</span>: <span class="number">95px</span>;</span><br><span class="line"> <span class="attribute">height</span>: <span class="number">200px</span>;</span><br><span class="line"> <span class="attribute">margin</span>: <span class="number">100px</span> auto;</span><br><span class="line"> <span class="attribute">position</span>: relative;</span><br><span class="line"> <span class="attribute">transform</span>: <span class="built_in">rotateX</span>(-<span class="number">20deg</span>) <span class="built_in">rotateY</span>(<span class="number">0deg</span>);</span><br><span class="line"> <span class="attribute">transform-style</span>: preserve-<span class="number">3</span>d;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="selector-class">.wrap</span> <span class="selector-tag">img</span> {</span><br><span class="line"> <span class="attribute">display</span>: block;</span><br><span class="line"> <span class="attribute">position</span>: absolute;</span><br><span class="line"> <span class="attribute">width</span>: <span class="number">100%</span>;</span><br><span class="line"> <span class="attribute">height</span>: <span class="number">100%</span>;</span><br><span class="line"> <span class="attribute">transform</span>: <span class="built_in">rotateY</span>(<span class="number">0deg</span>) <span class="built_in">translateZ</span>(<span class="number">0px</span>);</span><br><span class="line"> <span class="attribute">background</span>: transparent;</span><br><span class="line"> <span class="attribute">box-shadow</span>: <span class="number">0</span> <span class="number">0</span> <span class="number">4px</span> <span class="number">#fff</span>;</span><br><span class="line"> <span class="attribute">border-radius</span>: <span class="number">5px</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="selector-class">.wrap</span> <span class="selector-tag">p</span> {</span><br><span class="line"> <span class="attribute">width</span>: <span class="number">1200px</span>;</span><br><span class="line"> <span class="attribute">height</span>: <span class="number">1200px</span>;</span><br><span class="line"> <span class="attribute">background</span>: <span class="built_in">-webkit-radial-gradient</span>(center center, <span class="number">600px</span> <span class="number">600px</span>, <span class="built_in">rgba</span>(<span class="number">122</span>, <span class="number">122</span>, <span class="number">122</span>, .<span class="number">5</span>), <span class="built_in">rgba</span>(<span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>));</span><br><span class="line"> <span class="attribute">position</span>: absolute;</span><br><span class="line"> <span class="attribute">border-radius</span>: <span class="number">50%</span>;</span><br><span class="line"> <span class="attribute">left</span>: <span class="number">50%</span>;</span><br><span class="line"> <span class="attribute">top</span>: <span class="number">100%</span>;</span><br><span class="line"> <span class="attribute">margin-left</span>: -<span class="number">600px</span>;</span><br><span class="line"> <span class="attribute">margin-top</span>: -<span class="number">600px</span>;</span><br><span class="line"> <span class="attribute">transform</span>: <span class="built_in">rotateX</span>(<span class="number">90deg</span>);</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h1 id="script-js"><a href="#script-js" class="headerlink" title="script.js"></a>script.js</h1><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></pre></td><td class="code"><pre><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment"> * @Author: coder-jason</span></span><br><span class="line"><span class="comment"> * @Date: 2022-04-20 12:19:54</span></span><br><span class="line"><span class="comment"> * @LastEditTime: 2022-04-20 12:25:45</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">var</span> oImg = <span class="variable language_">document</span>.<span class="title function_">getElementsByTagName</span>(<span class="string">"img"</span>)</span><br><span class="line"><span class="keyword">var</span> len = oImg.<span class="property">length</span>;</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(len)</span><br><span class="line"><span class="keyword">var</span> deg = <span class="number">360</span> / len;</span><br><span class="line"><span class="keyword">var</span> oWrap = <span class="variable language_">document</span>.<span class="title function_">getElementById</span>(<span class="string">"imgwrap"</span>);</span><br><span class="line"><span class="variable language_">window</span>.<span class="property">onload</span> = <span class="keyword">function</span> (<span class="params"></span>) {</span><br><span class="line"> <span class="title class_">Array</span>.<span class="property"><span class="keyword">prototype</span></span>.<span class="property">forEach</span>.<span class="title function_">call</span>(oImg, <span class="keyword">function</span> (<span class="params">ele, index, self</span>) {</span><br><span class="line"> ele.<span class="property">style</span>.<span class="property">transform</span> = <span class="string">"rotateY("</span> + deg * index + <span class="string">"deg) translateZ(350px)"</span>;</span><br><span class="line"> ele.<span class="property">style</span>.<span class="property">transition</span> = <span class="string">"1s "</span> + (len - index) * <span class="number">0.1</span> + <span class="string">"s"</span>;</span><br><span class="line"> });</span><br><span class="line">}</span><br><span class="line"><span class="keyword">var</span> newX, newY, lastX, lastY, minusX, minusY, rotX = -<span class="number">20</span>, rotY = <span class="number">0</span>;</span><br><span class="line"><span class="variable language_">document</span>.<span class="property">onmousedown</span> = <span class="keyword">function</span> (<span class="params">e</span>) {</span><br><span class="line"> lastX = e.<span class="property">clientX</span>;</span><br><span class="line"> lastY = e.<span class="property">clientY</span>;</span><br><span class="line"> <span class="variable language_">this</span>.<span class="property">onmousemove</span> = <span class="keyword">function</span> (<span class="params">e</span>) {</span><br><span class="line"> newX = e.<span class="property">clientX</span>;</span><br><span class="line"> newY = e.<span class="property">clientY</span>;</span><br><span class="line"> minusX = newX - lastX;</span><br><span class="line"> minusY = newY - lastY;</span><br><span class="line"> rotX -= minusY * <span class="number">0.2</span>;</span><br><span class="line"> rotY += minusX * <span class="number">0.1</span>;</span><br><span class="line"> oWrap.<span class="property">style</span>.<span class="property">transform</span> = <span class="string">"rotateX("</span> + rotX + <span class="string">"deg) rotateY("</span> + rotY + <span class="string">"deg)"</span>;</span><br><span class="line"> lastX = newX;</span><br><span class="line"> lastY = newY;</span><br><span class="line"> }</span><br><span class="line"> <span class="variable language_">this</span>.<span class="property">onmouseup</span> = <span class="keyword">function</span> (<span class="params">e</span>) {</span><br><span class="line"> <span class="variable language_">this</span>.<span class="property">onmousemove</span> = <span class="literal">null</span>;</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>完整项目地址:</p><blockquote><p><span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL1BEUEVORy9zaGFyZS1jb2Rl">https://github.com/PDPENG/share-code<i class="fa fa-external-link-alt"></i></span></p></blockquote>]]></content>
<summary type="html"><blockquote>
<p>👲👲<font color=#a2a837 size=3>作者主页</font>:🔗<span class="exturl" data-url="aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L20wXzUxMjY5OTYx">杰森的博客<i class="fa fa-external-link-alt"></i></span><br>📒📒<font color=#20b9cd size=3>本文摘要</font>:<strong>用前端的知识实现<strong>立体滚动照片墙</strong></strong><br>💖💖感觉本文还不错的话,还请各位小伙伴👍点赞➕收藏⭐➕评论💭支持杰森呀✌️</p>
</blockquote>
<p><img src="https://img-blog.csdnimg.cn/2d38694568334676a6f610b9735ac426.gif#pic_center"></p></summary>
<category term="程序设计" scheme="https://pdpeng.github.io/categories/%E7%A8%8B%E5%BA%8F%E8%AE%BE%E8%AE%A1/"/>
<category term="前端" scheme="https://pdpeng.github.io/tags/%E5%89%8D%E7%AB%AF/"/>
</entry>
</feed>