-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.html
1832 lines (1517 loc) · 181 KB
/
index.html
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
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 7.3.0">
<link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
<link rel="icon" type="image/png" sizes="32x32" href="/images/leaf32.ico">
<link rel="icon" type="image/png" sizes="16x16" href="/images/leaf16.ico">
<link rel="mask-icon" href="/images/logo.svg" color="#222">
<link rel="stylesheet" href="/css/main.css">
<link rel="stylesheet" href="/lib/font-awesome/css/font-awesome.min.css">
<link rel="stylesheet" href="cdn.jsdelivr.net/npm/pace-js@1/themes/blue/pace-theme-minimal.css">
<script src="cdnjs.cloudflare.com/ajax/libs/pace/1.0.2/pace.min.js"></script>
<script id="hexo-configurations">
var NexT = window.NexT || {};
var CONFIG = {"hostname":"curforever.github.io","root":"/","scheme":"Gemini","version":"7.8.0","exturl":false,"sidebar":{"position":"left","display":"post","padding":18,"offset":12,"onmobile":false},"copycode":{"enable":false,"show_result":false,"style":null},"back2top":{"enable":true,"sidebar":true,"scrollpercent":true},"bookmark":{"enable":false,"color":"#222","save":"auto"},"fancybox":false,"mediumzoom":false,"lazyload":false,"pangu":false,"comments":{"style":"tabs","active":null,"storage":true,"lazyload":false,"nav":null},"algolia":{"hits":{"per_page":10},"labels":{"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}},"localsearch":{"enable":true,"trigger":"auto","top_n_per_article":1,"unescape":false,"preload":false},"motion":{"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}},"path":"search.xml"};
</script>
<meta name="description" content="东南大学 软件学院">
<meta property="og:type" content="website">
<meta property="og:title" content="像风一样の博客">
<meta property="og:url" content="https://curforever.github.io/index.html">
<meta property="og:site_name" content="像风一样の博客">
<meta property="og:description" content="东南大学 软件学院">
<meta property="og:locale" content="zh_CN">
<meta property="article:author" content="胡景峰">
<meta name="twitter:card" content="summary">
<link rel="canonical" href="https://curforever.github.io/">
<script id="page-configurations">
// https://hexo.io/docs/variables.html
CONFIG.page = {
sidebar: "",
isHome : true,
isPost : false,
lang : 'zh-CN'
};
</script>
<title>像风一样の博客</title>
<noscript>
<style>
.use-motion .brand,
.use-motion .menu-item,
.sidebar-inner,
.use-motion .post-block,
.use-motion .pagination,
.use-motion .comments,
.use-motion .post-header,
.use-motion .post-body,
.use-motion .collection-header { opacity: initial; }
.use-motion .site-title,
.use-motion .site-subtitle {
opacity: initial;
top: initial;
}
.use-motion .logo-line-before i { left: initial; }
.use-motion .logo-line-after i { right: initial; }
</style>
</noscript>
</head>
<body itemscope itemtype="http://schema.org/WebPage">
<div class="container use-motion">
<div class="headband"></div>
<header class="header" itemscope itemtype="http://schema.org/WPHeader">
<div class="header-inner"><div class="site-brand-container">
<div class="site-nav-toggle">
<div class="toggle" aria-label="切换导航栏">
<span class="toggle-line toggle-line-first"></span>
<span class="toggle-line toggle-line-middle"></span>
<span class="toggle-line toggle-line-last"></span>
</div>
</div>
<div class="site-meta">
<a href="/" class="brand" rel="start">
<span class="logo-line-before"><i></i></span>
<h1 class="site-title">像风一样の博客</h1>
<span class="logo-line-after"><i></i></span>
</a>
<p class="site-subtitle" itemprop="description">無限進步</p>
</div>
<div class="site-nav-right">
<div class="toggle popup-trigger">
<i class="fa fa-search fa-fw fa-lg"></i>
</div>
</div>
</div>
<nav class="site-nav">
<ul id="menu" class="menu">
<li class="menu-item menu-item-home">
<a href="/" rel="section"><i class="fa fa-fw fa-home"></i>首页</a>
</li>
<li class="menu-item menu-item-about">
<a href="/about/" rel="section"><i class="fa fa-fw fa-user"></i>关于</a>
</li>
<li class="menu-item menu-item-categories">
<a href="/categories/" rel="section"><i class="fa fa-fw fa-th"></i>分类<span class="badge">4</span></a>
</li>
<li class="menu-item menu-item-archives">
<a href="/archives/" rel="section"><i class="fa fa-fw fa-archive"></i>归档<span class="badge">7</span></a>
</li>
<li class="menu-item menu-item-search">
<a role="button" class="popup-trigger"><i class="fa fa-search fa-fw"></i>搜索
</a>
</li>
</ul>
</nav>
<div class="search-pop-overlay">
<div class="popup search-popup">
<div class="search-header">
<span class="search-icon">
<i class="fa fa-search"></i>
</span>
<div class="search-input-container">
<input autocomplete="off" autocapitalize="off"
placeholder="搜索..." spellcheck="false"
type="search" class="search-input">
</div>
<span class="popup-btn-close">
<i class="fa fa-times-circle"></i>
</span>
</div>
<div id="search-result">
<div id="no-result">
<i class="fa fa-spinner fa-pulse fa-5x fa-fw"></i>
</div>
</div>
</div>
</div>
</div>
</header>
<main class="main">
<div class="main-inner">
<div class="content-wrap">
<div class="content index posts-expand">
<article itemscope itemtype="http://schema.org/Article" class="post-block" lang="zh-CN">
<link itemprop="mainEntityOfPage" href="https://curforever.github.io/2024/12/24/%E3%80%8A%E5%85%B3%E4%BA%8E%E3%80%90%E4%B8%80%E6%97%A5%E7%94%B7%E5%8F%8B%E3%80%91%E7%9A%84%E5%B9%BB%E6%83%B3%E3%80%81%E6%B2%89%E8%BF%B7%E5%92%8C%E7%A0%B4%E7%81%AD%E3%80%8B%E6%92%AD%E5%AE%A2%E7%AC%94%E8%AE%B0/">
<span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
<meta itemprop="image" content="/images/avatar.png">
<meta itemprop="name" content="胡景峰">
<meta itemprop="description" content="东南大学 软件学院">
</span>
<span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
<meta itemprop="name" content="像风一样の博客">
</span>
<header class="post-header">
<h2 class="post-title" itemprop="name headline">
<a href="/2024/12/24/%E3%80%8A%E5%85%B3%E4%BA%8E%E3%80%90%E4%B8%80%E6%97%A5%E7%94%B7%E5%8F%8B%E3%80%91%E7%9A%84%E5%B9%BB%E6%83%B3%E3%80%81%E6%B2%89%E8%BF%B7%E5%92%8C%E7%A0%B4%E7%81%AD%E3%80%8B%E6%92%AD%E5%AE%A2%E7%AC%94%E8%AE%B0/" class="post-title-link" itemprop="url">《关于【一日男友】的幻想、沉迷和破灭》播客笔记</a>
</h2>
<div class="post-meta">
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="fa fa-calendar-o"></i>
</span>
<span class="post-meta-item-text">发表于</span>
<time title="创建时间:2024-12-24 14:11:17 / 修改时间:14:38:08" itemprop="dateCreated datePublished" datetime="2024-12-24T14:11:17+08:00">2024-12-24</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="fa fa-folder-o"></i>
</span>
<span class="post-meta-item-text">分类于</span>
<span itemprop="about" itemscope itemtype="http://schema.org/Thing">
<a href="/categories/%E6%92%AD%E5%AE%A2%E7%AC%94%E8%AE%B0/" itemprop="url" rel="index"><span itemprop="name">播客笔记</span></a>
</span>
</span>
<br>
<span class="post-meta-item" title="本文字数">
<span class="post-meta-item-icon">
<i class="fa fa-file-word-o"></i>
</span>
<span class="post-meta-item-text">本文字数:</span>
<span>1.2k</span>
</span>
<span class="post-meta-item" title="阅读时长">
<span class="post-meta-item-icon">
<i class="fa fa-clock-o"></i>
</span>
<span class="post-meta-item-text">阅读时长 ≈</span>
<span>2 分钟</span>
</span>
</div>
</header>
<div class="post-body" itemprop="articleBody">
<h1 id="节目:跳进兔子洞"><a href="#节目:跳进兔子洞" class="headerlink" title="节目:跳进兔子洞"></a>节目:跳进兔子洞</h1><h1 id="标题:关于【一日男友】的幻想、沉迷和破灭"><a href="#标题:关于【一日男友】的幻想、沉迷和破灭" class="headerlink" title="标题:关于【一日男友】的幻想、沉迷和破灭"></a>标题:关于【一日男友】的幻想、沉迷和破灭</h1><h2 id="引言"><a href="#引言" class="headerlink" title="引言"></a>引言</h2><p>随着个体需求的多样化和社会关系的复杂化,越来越多的人开始寻求非传统的情感满足方式。其中,“一日男友”这一现象逐渐浮出水面,成为探讨现代情感需求与消费文化交织的一个重要窗口。</p>
<h2 id="一日男友现象概述"><a href="#一日男友现象概述" class="headerlink" title="一日男友现象概述"></a>一日男友现象概述</h2><p>“一日男友”指的是<strong>通过线下委托或线上平台,雇佣他人扮演一天的男朋友角色</strong>,以满足个人的情感需求。这一现象在年轻女性群体中特别普遍,尤其是在那些<strong>渴望与虚拟角色或理想化伴侣建立情感联系的“梦女”群体</strong>中。</p>
<h2 id="委托人的心理需求"><a href="#委托人的心理需求" class="headerlink" title="委托人的心理需求"></a>委托人的心理需求</h2><p>委托人通过<strong>金钱购买爱人</strong>的方式,寻求一种<strong>完全的情感依赖和安全感</strong>。这种需求源自于对稳定关系的渴望,但却难以在现实生活中实现。通过“一日男友”的服务,委托人可以获得:</p>
<ol>
<li><strong>占有欲的满足</strong>:通过拥有一个随时可以控制和依赖的伴侣,委托人获得心理上的满足。</li>
<li><strong>绝对的确定性和安全感</strong>:无需担心关系中的不确定性和风险。</li>
</ol>
<p>然而,这种通过金钱购买的关系缺乏真正的情感交流,容易导致情感上的空虚和依赖性。有时甚至会引发和带来对这种情感的<strong>配得感</strong>的怀疑。</p>
<h2 id="被委托人的角色与挑战"><a href="#被委托人的角色与挑战" class="headerlink" title="被委托人的角色与挑战"></a>被委托人的角色与挑战</h2><p>被委托人扮演“一日男友”的角色,需要具备高度的情感模拟能力和人际交往技巧。他们的工作不仅是表面的陪伴,更涉及深层次的情感交流和关系处理。具体来说:</p>
<ol>
<li><strong>角色还原、提供陪伴</strong>:准确模仿理想中的男友形象,满足委托人的幻想。在情感上给予委托人支持和安慰,成为其情感上的依靠。</li>
<li><strong>关系处理</strong>:被委托人如何处理好营业和非营业状态下的区别和关系处理是一大挑战。</li>
</ol>
<p>这种工作模式对被委托人而言,既是一种情感劳动,也可能带来心理压力,尤其是在面对长期依赖的委托人时。</p>
<h2 id="经济因素与行业现状"><a href="#经济因素与行业现状" class="headerlink" title="经济因素与行业现状"></a>经济因素与行业现状</h2><ul>
<li>300r / 天</li>
<li>10w+ / 月</li>
</ul>
<h2 id="一些思考"><a href="#一些思考" class="headerlink" title="一些思考"></a>一些思考</h2><h3 id="1、幻想、沉迷与破灭的循环"><a href="#1、幻想、沉迷与破灭的循环" class="headerlink" title="1、幻想、沉迷与破灭的循环"></a>1、幻想、沉迷与破灭的循环</h3><p>“一日男友”现象不仅是<strong>个体情感需求</strong>的反映,更是<strong>现代消费文化</strong>与<strong>情感表达方式</strong>的交织。委托人在通过这种服务满足幻想的同时,容易陷入情感上的沉迷。一旦这种依赖无法得到进一步满足,或者服务无法持续提供预期的情感支持,委托人便会经历情感的破灭。这种循环不仅影响个体的心理健康,还可能对现实中的人际关系产生负面影响。长期依赖虚拟或短暂的情感连接,容易导致对真实情感交流的逃避和恐惧,进一步加剧情感上的孤独感。</p>
<p>这让我想到崩坏星穹铁道的<strong>匹诺康尼</strong>的剧情,<strong>如果现实带给你的大部分是痛苦甚至只有痛苦,你会认为一直沉溺在美梦之中不失为一种解脱吗?</strong></p>
<h3 id="2、个人主体性"><a href="#2、个人主体性" class="headerlink" title="2、个人主体性"></a>2、个人主体性</h3><p>委托人需要<strong>保持主体性</strong>,不要沉溺于幻想当中。</p>
<p>被委托人也要<strong>保持主体性</strong>,不被完全物化。</p>
<h2 id="结论"><a href="#结论" class="headerlink" title="结论"></a>结论</h2><p>“一日男友”现象是现代社会情感需求与消费文化交织的产物,反映了个体在复杂社会关系中的情感困境。通过分析其背后的幻想、沉迷与破灭,我们不仅可以更好地理解当代情感需求的多样性,也能反思情感表达方式的健康性与可持续性。未来,随着社会的发展和人际关系的演变,这一现象可能会进一步发展,值得我们持续关注和深入研究。</p>
</div>
<footer class="post-footer">
<div class="post-eof"></div>
</footer>
</article>
<article itemscope itemtype="http://schema.org/Article" class="post-block" lang="zh-CN">
<link itemprop="mainEntityOfPage" href="https://curforever.github.io/2024/12/20/IDEA%E4%BD%BF%E7%94%A8Tomcat%E8%BF%90%E8%A1%8CWeb%E9%A1%B9%E7%9B%AE%E5%8F%8A%E5%85%B6%E5%B8%B8%E8%A7%81%E6%8A%A5%E9%94%99/">
<span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
<meta itemprop="image" content="/images/avatar.png">
<meta itemprop="name" content="胡景峰">
<meta itemprop="description" content="东南大学 软件学院">
</span>
<span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
<meta itemprop="name" content="像风一样の博客">
</span>
<header class="post-header">
<h2 class="post-title" itemprop="name headline">
<a href="/2024/12/20/IDEA%E4%BD%BF%E7%94%A8Tomcat%E8%BF%90%E8%A1%8CWeb%E9%A1%B9%E7%9B%AE%E5%8F%8A%E5%85%B6%E5%B8%B8%E8%A7%81%E6%8A%A5%E9%94%99/" class="post-title-link" itemprop="url">IDEA使用Tomcat运行Web项目及其常见报错</a>
</h2>
<div class="post-meta">
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="fa fa-calendar-o"></i>
</span>
<span class="post-meta-item-text">发表于</span>
<time title="创建时间:2024-12-20 16:31:47 / 修改时间:16:32:26" itemprop="dateCreated datePublished" datetime="2024-12-20T16:31:47+08:00">2024-12-20</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="fa fa-folder-o"></i>
</span>
<span class="post-meta-item-text">分类于</span>
<span itemprop="about" itemscope itemtype="http://schema.org/Thing">
<a href="/categories/%E7%8E%AF%E5%A2%83%E9%85%8D%E7%BD%AE/" itemprop="url" rel="index"><span itemprop="name">环境配置</span></a>
</span>
</span>
<br>
<span class="post-meta-item" title="本文字数">
<span class="post-meta-item-icon">
<i class="fa fa-file-word-o"></i>
</span>
<span class="post-meta-item-text">本文字数:</span>
<span>4.5k</span>
</span>
<span class="post-meta-item" title="阅读时长">
<span class="post-meta-item-icon">
<i class="fa fa-clock-o"></i>
</span>
<span class="post-meta-item-text">阅读时长 ≈</span>
<span>8 分钟</span>
</span>
</div>
</header>
<div class="post-body" itemprop="articleBody">
<p>@[toc]</p>
<h1 id="IDEA使用Tomcat运行Web项目及其常见报错"><a href="#IDEA使用Tomcat运行Web项目及其常见报错" class="headerlink" title="IDEA使用Tomcat运行Web项目及其常见报错"></a>IDEA使用Tomcat运行Web项目及其常见报错</h1><h2 id="一、Project-Structure"><a href="#一、Project-Structure" class="headerlink" title="一、Project Structure"></a>一、Project Structure</h2><blockquote>
<p>目的:让IDEA知道这是个Web项目</p>
</blockquote>
<ol>
<li><p><strong>Modules</strong></p>
<blockquote>
<p>目的:加载Web相关的配置和资源</p>
</blockquote>
<p><code>右键</code>目标模块 - <code>Add</code> - <code>Web</code></p>
<p><strong>Web配置窗口</strong></p>
<ol>
<li><p>确认<code>web.xml</code>路径是否正确,不正确需要手动修改</p>
<blockquote>
<p>web.xml即Deployment Descripters下的Path</p>
</blockquote>
</li>
<li><p>确认<code>Web资源目录</code>是否正确,不正确需要手动修改</p>
<blockquote>
<p><code>web资源目录</code>即<code>WEB-INF</code>上级路径(<code>JSP</code>等放置的位置)</p>
</blockquote>
<blockquote>
<p>应用程序一般默认为<code>web</code>文件夹,但是我的项目为<code>webapp</code>文件夹,改为正确的<code>webapp</code></p>
</blockquote>
</li>
</ol>
</li>
<li><p><strong>Artifacts</strong></p>
<blockquote>
<p>即编译后的Java类,Web资源等的整合,用以测试、部署等工作</p>
<p>白话一点,就是说某个module要如何打包,例如war exploded、war、jar、ear等等这种打包形式</p>
<p>某个module有了 Artifacts 就可以部署到应用服务器中了</p>
</blockquote>
<p><code>+</code> - <code>Add</code> - <code>Web Application: Exploded</code> - <code>From Modules...</code> - 选择我们的项目or模块</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">区分:</span><br><span class="line">(1)jar:Java ARchive,通常聚合Java类文件、相关数据和资源(文本、图片等)到一个文件,以便分发Java平台应用软件或库;</span><br><span class="line">(2)war:Web application ARchive,一种JAR文件,其中包含用来分发的JSP、Java Servlet、Java类、XML文件、标签库、静态网页(HTML和相关文件),以及构成Web应用程序的其他资源;</span><br><span class="line">(3)war exploded:展开,不压缩。直接把文件夹、jsp页面 、classes等移到Tomcat 部署文件夹里面</span><br><span class="line"> 因此这种方式支持热部署,建议在开发的时候使用这种模式,便于修改了文件的效果立刻显现出来</span><br><span class="line"> 热部署:对于Java应用程序来说,热部署就是在运行时更新Java类文件。</span><br></pre></td></tr></table></figure></li>
</ol>
<h2 id="二、Tomcat配置"><a href="#二、Tomcat配置" class="headerlink" title="二、Tomcat配置"></a>二、Tomcat配置</h2><ol>
<li><p>点击IDEA右上方执行的<code>Add Configuration...</code></p>
</li>
<li><p>弹出的窗口中点击<code>+</code>,出现的选项中往下滑,选择<code>Tomcat Server</code> - <code>Local</code></p>
<blockquote>
<p>这步添加Tomcat配置</p>
</blockquote>
</li>
<li><p>点击<code>Deployement</code>页签,点击<code>+</code>,选择<code>Artifact...</code></p>
<blockquote>
<p>这里IDEA会将刚才的<code>项目</code>的<code>artifact</code>放入窗口中</p>
<p>但也有可能存在其他的<code>artifact</code>,选择我们需要的</p>
</blockquote>
</li>
<li><p>修改<code>Application context</code>,可以只保留一个<code>/</code></p>
<blockquote>
<p>IDEA会自动为我们生成项目根路径</p>
<p>如果其他配置没问题结果访问404很可能是因为这个没改</p>
</blockquote>
</li>
<li><p>点击<code>Server</code>页签,检查<code>URL</code>处是否与步骤<code>4</code>中设置的同步</p>
<blockquote>
<p>IDEA会自动同步</p>
</blockquote>
</li>
</ol>
<h2 id="三、Tomcat运行"><a href="#三、Tomcat运行" class="headerlink" title="三、Tomcat运行"></a>三、Tomcat运行</h2><p>给我点那个绿色的<code>Run</code>!!!!</p>
<h3 id="当你点击运行Tomcat时,IDEA在做什么"><a href="#当你点击运行Tomcat时,IDEA在做什么" class="headerlink" title="当你点击运行Tomcat时,IDEA在做什么"></a>当你点击运行Tomcat时,IDEA在做什么</h3><ol>
<li><p><strong>编译</strong>。</p>
<p>IDEA在保存后不会做编译,不像Eclipse的保存即编译,</p>
<p>因此在运行server前会做一次编译,</p>
<p>编译后class文件存放在指定的项目<u>编译输出目录</u>下;</p>
</li>
<li><p>根据artifact中的设定对目录结构进行<strong>创建</strong>;</p>
</li>
<li><p>拷贝<strong>web资源</strong>的根目录下的所有文件到artifact的目录下(见1.2.3);</p>
</li>
<li><p>拷贝<u>编译输出目录</u>下的<strong>classes目录</strong>到artifact下的WEB-INF下(见1.2.2);</p>
</li>
<li><p>拷贝<strong>lib目录</strong>下所需的jar包到artifact下的WEB_INF下;</p>
</li>
<li><p>运行server,运行成功后,如有需要,会自动打开浏览器访问指定url。</p>
</li>
</ol>
<h2 id="四、一些报错及解决"><a href="#四、一些报错及解决" class="headerlink" title="四、一些报错及解决"></a>四、一些报错及解决</h2><h3 id="4-1、org-springframework-xxx不存在"><a href="#4-1、org-springframework-xxx不存在" class="headerlink" title="4.1、org.springframework..xxx不存在"></a>4.1、org.springframework..xxx不存在</h3><h4 id="4-1-1、情况一:pom-xml中的maven的dependency没加载好(红色version)"><a href="#4-1-1、情况一:pom-xml中的maven的dependency没加载好(红色version)" class="headerlink" title="4.1.1、情况一:pom.xml中的maven的dependency没加载好(红色version)"></a>4.1.1、情况一:pom.xml中的maven的dependency没加载好(红色version)</h4><ol>
<li><p><strong>方法一:头铁再试一次</strong></p>
<p><code>右击项目</code> - <code>Maven</code> - <code>Reimport</code></p>
<blockquote>
<p>IDEA将通过网络自动下载相关依赖,并存放在Maven的本地仓库中</p>
</blockquote>
</li>
<li><p><strong>方法二:换个version罢</strong></p>
<p>如果还不行,可能的原因及解决:<br>原因一:你的<code>maven</code>配置了从<code>aliyun</code>镜像下载,而<code>aliyun仓库</code>中恰好没有对应<code>version</code><br>原因二:<code>版本号version</code>暂时用不了(我也不知道是什么缘故),换个<code>版本号</code>就好了<br>解决:访问<code>https://mvnrepository.com/</code>(需要梯子)<br> 搜索需要的<code>artifact</code>,复制其他<code>version</code>的<code>dependency</code>并粘贴到<code>pom.xml</code>中</p>
</li>
<li><p><strong>方法三:你是不是装过不止一个maven</strong></p>
<p>检查<code>File</code> - <code>Settings</code> - <code>Build,Execution,Deployment</code> - <code>Maven</code> </p>
<p><code>Maven home directory</code>选择你本次项目要用的maven</p>
<p><code>User settings file</code>的<code>settings.xml</code>里可能配置了从<code>aliyun</code>下载(自己权衡要不要改)</p>
</li>
<li><p><strong>方法四:手动下载jar包</strong></p>
<p>如果上面的你都尝试过了,还是不行(哦,可怜的人儿):<br>你需要<code>baidu.com</code>搜索对应版本的jar包并下载<br>把<code>jar包</code>放到<code>maven</code>的<code>本地repository文件夹</code>中的对应位置(这个对应位置要<u>点进一个个小文件夹</u>)<br>注意<u>删除</u>最里面那个文件夹里以 .lastUpdated为后缀的文件(下载失败的),然后粘贴<br><u>刷新</u>一下maven依赖</p>
</li>
</ol>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">将Maven的刷新设置为自动,配置方法为:</span><br><span class="line">(1)打开File-Settings-Maven</span><br><span class="line">(2)勾选Import Maven projects automatically</span><br></pre></td></tr></table></figure>
<h4 id="4-2-2、情况二:pom文件相关的依赖明明都下载好了,但运行还是找不到XXX相关的包"><a href="#4-2-2、情况二:pom文件相关的依赖明明都下载好了,但运行还是找不到XXX相关的包" class="headerlink" title="4.2.2、情况二:pom文件相关的依赖明明都下载好了,但运行还是找不到XXX相关的包"></a>4.2.2、情况二:pom文件相关的依赖明明都下载好了,但运行还是找不到XXX相关的包</h4><p><strong>方法一:</strong>删除<code>target文件夹</code>下所有文件,重新编译运行。</p>
<p><strong>方法二:</strong><code>File</code> - <code>Settings</code> - <code>Build,Execution,Deployment</code> - <code>Maven</code> - <code>Runner</code></p>
<pre><code> 勾选`Delegate IDE build/run actions to Maven`
选择自己安装的`JRE的路径`
</code></pre>
<hr>
<h3 id="4-2、java-io-FileNotFoundException-class-path-resource-spring-cannot-be-resolve"><a href="#4-2、java-io-FileNotFoundException-class-path-resource-spring-cannot-be-resolve" class="headerlink" title="4.2、java.io.FileNotFoundException: class path resource [spring/] cannot be resolve"></a>4.2、java.io.FileNotFoundException: class path resource [spring/] cannot be resolve</h3><p><strong>描述:</strong>此异常是说找不到<code>spring</code>的配置文件。</p>
<p><strong>原因:</strong>为了防止<code>mybatis</code>的<code>mapper</code>文件被过滤掉,在<code>pom.xml</code>的<code>build</code>节点下加入了如下代码</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><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="comment"><!--如果不加如下配置maven打包时不会将mapper文件打包进去--></span></span><br><span class="line"><span class="tag"><<span class="name">resources</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">resource</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">directory</span>></span>src/main/java<span class="tag"></<span class="name">directory</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">includes</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">include</span>></span>**/*.properties<span class="tag"></<span class="name">include</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">include</span>></span>**/*.xml<span class="tag"></<span class="name">include</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">includes</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">filtering</span>></span>false<span class="tag"></<span class="name">filtering</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">resource</span>></span></span><br><span class="line"><span class="tag"></<span class="name">resources</span>></span></span><br></pre></td></tr></table></figure>
<p><strong>解决:</strong><code>maven</code>默认扫描<code>src/main/java</code>中的文件但并不理会<code>src/main/resources</code>中的xml文件,</p>
<pre><code> 因此,添加resource节点,使其扫描`src/main/resources`中的xml文件
</code></pre>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"><!--如果不加如下配置maven打包时不会将mapper文件打包进去--></span></span><br><span class="line"><span class="tag"><<span class="name">resources</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">resource</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">directory</span>></span>src/main/java<span class="tag"></<span class="name">directory</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">includes</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">include</span>></span>**/*.properties<span class="tag"></<span class="name">include</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">include</span>></span>**/*.xml<span class="tag"></<span class="name">include</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">includes</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">filtering</span>></span>false<span class="tag"></<span class="name">filtering</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">resource</span>></span></span><br><span class="line"><!--修改后的文件--></span><br><span class="line"><span class="comment"><!--如果不加此节点,resources文件中的spring配置文件将会找不到--></span></span><br><span class="line"> <span class="tag"><<span class="name">resource</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">directory</span>></span>src/main/resources<span class="tag"></<span class="name">directory</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">includes</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">include</span>></span>**/*.properties<span class="tag"></<span class="name">include</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">include</span>></span>**/*.xml<span class="tag"></<span class="name">include</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">includes</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">filtering</span>></span>false<span class="tag"></<span class="name">filtering</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">resource</span>></span></span><br><span class="line"><span class="tag"></<span class="name">resources</span>></span></span><br></pre></td></tr></table></figure>
<hr>
<h3 id="4-3、maven依赖的多个版本依赖冲突"><a href="#4-3、maven依赖的多个版本依赖冲突" class="headerlink" title="4.3、maven依赖的多个版本依赖冲突"></a>4.3、maven依赖的多个版本依赖冲突</h3><p><strong>描述</strong>:当出现下面问题异常的时候,如果clean jar包之后还是无法成功启动项目,可以考虑是这个问题</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">1、NoDefClassException</span><br><span class="line">2、ClassNotFoundException</span><br><span class="line">3、NoSuchMethodError</span><br><span class="line">4、NoSuchFieldError</span><br></pre></td></tr></table></figure>
<p><strong>查看</strong>:在界面右侧可找到<code>Maven</code>,点开,小图标里找到<code>Show Dependencies</code>,</p>
<pre><code> 点击后即可查看当前`maven模块的依赖结构图`,<u>红色的线</u>即为<u>依赖冲突</u>。
</code></pre>
<p><strong>解决:</strong></p>
<ol>
<li><code>File</code> - <code>Settings</code> - <code>Plugins</code> - 搜索 <code>maven helper</code> - <code>install</code></li>
<li>打开<code>pom.xml</code>,在编辑器下方 控制台上方,点击text旁边的<code>Dependency Analyzer</code></li>
<li>左侧为<code>冲突的jar包</code>,挨个点开,把右侧红色的挨个右击<code>exclude</code></li>
</ol>
<h2 id="五、参考博客"><a href="#五、参考博客" class="headerlink" title="五、参考博客"></a>五、参考博客</h2><ol>
<li>IDEA使用Tomcat运行web项目教程:<a target="_blank" rel="noopener" href="http://t.csdn.cn/44qjF">http://t.csdn.cn/44qjF</a></li>
<li>idea运行项目 程序包org.springframework..xxx不存在的解决办法:<a target="_blank" rel="noopener" href="http://t.csdn.cn/kzfyg">http://t.csdn.cn/kzfyg</a></li>
<li>解决idea打开的项目中maven依赖下载失败问题:<a target="_blank" rel="noopener" href="http://t.csdn.cn/6nNLs">http://t.csdn.cn/6nNLs</a></li>
<li>如何将下载到本地的JAR包手动添加到Maven仓库:<a target="_blank" rel="noopener" href="http://t.csdn.cn/82XIn">http://t.csdn.cn/82XIn</a></li>
<li>war和war exploded的区别:<a target="_blank" rel="noopener" href="http://t.csdn.cn/quYCO">http://t.csdn.cn/quYCO</a></li>
<li>IDEA项目运行项目报404错误——org.apache.jasper.servlet.TldScanner.scanJars 至少有一个JAR被扫描用于TLD但尚未包含TLD。:<a target="_blank" rel="noopener" href="http://t.csdn.cn/CY4WI">http://t.csdn.cn/CY4WI</a></li>
<li>IDEA部署项目到tomcat运行成功但是页面404的两种原因:<a target="_blank" rel="noopener" href="http://t.csdn.cn/E3IBU">http://t.csdn.cn/E3IBU</a></li>
<li>java.io.FileNotFoundException: class path resource [spring/] cannot be resolve 《异常信息》:<a target="_blank" rel="noopener" href="http://t.csdn.cn/5JDz8">http://t.csdn.cn/5JDz8</a></li>
<li>idea如何解决jar包冲突:<a target="_blank" rel="noopener" href="http://t.csdn.cn/qyKTp">http://t.csdn.cn/qyKTp</a></li>
</ol>
</div>
<footer class="post-footer">
<div class="post-eof"></div>
</footer>
</article>
<article itemscope itemtype="http://schema.org/Article" class="post-block" lang="zh-CN">
<link itemprop="mainEntityOfPage" href="https://curforever.github.io/2024/12/20/%E6%96%B0%E6%89%8B%E5%85%A5%E9%97%A8%20Git%20&%20GitHub/">
<span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
<meta itemprop="image" content="/images/avatar.png">
<meta itemprop="name" content="胡景峰">
<meta itemprop="description" content="东南大学 软件学院">
</span>
<span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
<meta itemprop="name" content="像风一样の博客">
</span>
<header class="post-header">
<h2 class="post-title" itemprop="name headline">
<a href="/2024/12/20/%E6%96%B0%E6%89%8B%E5%85%A5%E9%97%A8%20Git%20&%20GitHub/" class="post-title-link" itemprop="url">新手入门 Git & GitHub</a>
</h2>
<div class="post-meta">
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="fa fa-calendar-o"></i>
</span>
<span class="post-meta-item-text">发表于</span>
<time title="创建时间:2024-12-20 16:31:06 / 修改时间:16:31:32" itemprop="dateCreated datePublished" datetime="2024-12-20T16:31:06+08:00">2024-12-20</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="fa fa-folder-o"></i>
</span>
<span class="post-meta-item-text">分类于</span>
<span itemprop="about" itemscope itemtype="http://schema.org/Thing">
<a href="/categories/%E8%AE%B2%E8%A7%A3%E6%95%99%E7%A8%8B/" itemprop="url" rel="index"><span itemprop="name">讲解教程</span></a>
</span>
</span>
<br>
<span class="post-meta-item" title="本文字数">
<span class="post-meta-item-icon">
<i class="fa fa-file-word-o"></i>
</span>
<span class="post-meta-item-text">本文字数:</span>
<span>2.2k</span>
</span>
<span class="post-meta-item" title="阅读时长">
<span class="post-meta-item-icon">
<i class="fa fa-clock-o"></i>
</span>
<span class="post-meta-item-text">阅读时长 ≈</span>
<span>4 分钟</span>
</span>
</div>
</header>
<div class="post-body" itemprop="articleBody">
<p>@[TOC](新手入门 Git & GitHub)</p>
<h1 id="零、命令行小抄"><a href="#零、命令行小抄" class="headerlink" title="==零、命令行小抄=="></a>==零、命令行小抄==</h1><blockquote>
<p>本小抄适用于:远程仓库new了repo、本地有(要上传的)文件夹、SSH已绑定好<br>供有一定基础、但不常用的同学(包括我自己)查阅</p>
</blockquote>
<ol>
<li><code>ssh-keygen -t rsa -C "12345678@qq.com"</code>,生成rsa(用于本地电脑和远程仓库绑定,详见下文3.3)</li>
<li>进入要上传的文件夹,<code>git init</code> ,创建本地仓库</li>
<li><code>git remote add origin git@github.com:xxx/yyy.git</code>,本地仓库连接远程仓库</li>
<li>做完修改后,<code>git add .</code>,添加到临时缓冲区</li>
<li><code>git commit -m "添加了/修改了..."</code>,提交到本地仓库</li>
<li><code>git push -u origin master</code>,提交到远程仓库的master分支</li>
<li><code>git log</code>,查看已有的commitID(为7准备)</li>
<li><code>git reset --hard commitID</code>,撤销 commit、撤销 git add . 操作、撤销修改代码(在以下情况常用:(1)添加了一个怎么也传不上去的大文件;(2)push时候发生由于commit引起的不知名error)</li>
<li><code>"ssh:connect to host github.com port 22: Connection timed out"</code>问题的解决<br> 首先,<code>vim ~/.ssh/config</code><br> 其次,添加以下代码 <figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"># Default github user self</span><br><span class="line">Host github.com</span><br><span class="line"> port 443 # 默认是22端口</span><br><span class="line"> HostName ssh.github.com</span><br><span class="line"> IdentityFile ~/.ssh/id_rsa</span><br></pre></td></tr></table></figure>
最后,<code>:wq</code>保存并退出vim模式</li>
</ol>
<h1 id="一、前言"><a href="#一、前言" class="headerlink" title="==一、前言=="></a>==一、前言==</h1><p><strong>学习Git</strong>真的是我学习路上的一道“<strong>槛</strong>”;<br>  一方面,不断接触的信息告诉我“<strong>学习Git很重要</strong>”;<br>  另一方面,每次找到的教程都有那么几步<strong>看不懂</strong>,或是<strong>看懂了记不住</strong>。</p>
<blockquote>
<p>我前前后后学了三四次了,<br>或被GitHub英文劝退, (不会翻墙的时候打开还会很慢)<br>或因安装软件繁琐放弃, (啥是Git??啥是Github??)<br>或成功按部就班实现了一次demo,但没有实践下去于是忘了</p>
</blockquote>
<p>谨以此篇献给想学习并且在学习<strong>Git版本控制</strong>的小白。<br> </p>
<h1 id="二、原理描述"><a href="#二、原理描述" class="headerlink" title="==二、原理描述=="></a>==二、原理描述==</h1><h2 id="2-1-四句话讲明白"><a href="#2-1-四句话讲明白" class="headerlink" title="2.1 四句话讲明白"></a>2.1 四句话讲明白</h2><p><strong>Git</strong> 狭义上来说是一个版本控制软件,广义上简单理解成<code>代码的仓库</code>;<br><strong>GitHub</strong> 一个远程仓库,白话就是<code>程序员专用的“某度网盘”</code>;<br><strong>网盘会用吧?</strong> 从本地的一个文件夹<code>上传</code>到网盘,或从网盘<code>下载</code>到本地。<br><strong>Git你就会了。</strong> 从本地仓库(repository)<code>上传(push)</code>到远程仓库,或从远程仓库<code>下载(pull)</code>到本地。<br> </p>
<h2 id="2-2-补充说明"><a href="#2-2-补充说明" class="headerlink" title="2.2 补充说明"></a>2.2 补充说明</h2><h3 id="(1)本地仓库"><a href="#(1)本地仓库" class="headerlink" title="(1)本地仓库"></a>(1)本地仓库</h3><ol>
<li>电脑上的一个文件夹就是一个本地仓库</li>
<li>只是文件夹当然不行(就像没名没证空有房屋和物资,别人怎么知道是仓库)</li>
<li>下载Git后可以在文件夹下通过命令行输入命令建立仓库(告诉别人,我这个文件夹,是仓库)</li>
</ol>
<h3 id="(2)远程仓库"><a href="#(2)远程仓库" class="headerlink" title="(2)远程仓库"></a>(2)远程仓库</h3><ol>
<li>GitHub就是一个远程仓库</li>
<li>一个GitHub账号对应一个专属于你的仓库</li>
<li>也许你访问GitHub官网会很慢(这需要花点小费翻墙解决)</li>
<li>也许你读不懂英文,但我相信你可以磕磕碰碰注册成功!</li>
</ol>
<h3 id="(3)相互绑定"><a href="#(3)相互绑定" class="headerlink" title="(3)相互绑定"></a>(3)相互绑定</h3><ol>
<li>有了本地和远程仓库还不够(远程仓库怎么知道该不该接收呢,我不认识你)</li>
<li>我们需要一个SSH安全协议(远程仓库把该本地仓库的名字加入联系人名单,可以接收)</li>
</ol>
<h3 id="(4)上传下载"><a href="#(4)上传下载" class="headerlink" title="(4)上传下载"></a>(4)上传下载</h3><ol>
<li>一般该操作在本地仓库进行</li>
<li>我们通过Git提供的命令行命令实现push和pull</li>
<li>远程仓库有时也需要做一些操作(仓库收到物资后也需要整理的嘛)</li>
<li>即对别人提交的修改更新做审核和合并(初学我们不涉及)<br> </li>
</ol>
<h1 id="三、保姆教程"><a href="#三、保姆教程" class="headerlink" title="==三、保姆教程=="></a>==三、保姆教程==</h1><p>我将对步骤进行概述性描述,因为有一位大佬已经发过知乎,<br>我觉得写的很好,也不多赘述,各位循着我的大纲去他那亲自体验就好~<br>(链接我放评论区,欢迎大家去瞅瞅!真的很棒很棒!)</p>
<h2 id="3-1-本地仓库(Git)"><a href="#3-1-本地仓库(Git)" class="headerlink" title="3.1 本地仓库(Git)"></a>3.1 本地仓库(Git)</h2><p>(1)下载安装git提供命令行工具 <code>[对应知乎文章 第六点]</code><br>(2)一个文件夹demo做本地仓库(这个不用教吧??新建文件夹即可)</p>
<h2 id="3-2-远程仓库(GitHub)"><a href="#3-2-远程仓库(GitHub)" class="headerlink" title="3.2 远程仓库(GitHub)"></a>3.2 远程仓库(GitHub)</h2><p>(1)如有需要,付费翻墙(白话就是,通过歪果的节点上外网,没有阻碍速度更快)<br>(2)一个GitHub注册账号 <code>[对应知乎文章 第二点]</code><br>(3)新建一个远程仓库repository <code>[对应知乎文章中 第四点]</code></p>
<h2 id="3-3-相互绑定(SSH)"><a href="#3-3-相互绑定(SSH)" class="headerlink" title="3.3 相互绑定(SSH)"></a>3.3 相互绑定(SSH)</h2><p>(1)在本地生成SSH key <code>[对应知乎文章中 第八点]</code><br>(2)向GitHub添加SSH key <code>[对应知乎文章中 第八点]</code></p>
<h2 id="3-4-上传下载(Git命令介绍)"><a href="#3-4-上传下载(Git命令介绍)" class="headerlink" title="3.4 上传下载(Git命令介绍)"></a>3.4 上传下载(Git命令介绍)</h2><p>(1)本地仓库的更新与整理 <code>[对应知乎文章中 第七点]</code><br>(2)本地仓库通过Git命令行上传下载 <code>[对应知乎文章中 第九点]</code><br>(3)远程仓库查看效果<code>[对应知乎文章中 第九点]</code></p>
<h1 id="结语"><a href="#结语" class="headerlink" title="==结语=="></a>==结语==</h1><p>如果对你有帮助的话给个赞吧,顺带附一张自制的说明图~<br>![在这里插入图片描述](新手入门 Git & GitHub.assets/0f33782c01e099ef1daa513c4129d8f5.png)</p>
</div>
<footer class="post-footer">
<div class="post-eof"></div>
</footer>
</article>
<article itemscope itemtype="http://schema.org/Article" class="post-block" lang="zh-CN">
<link itemprop="mainEntityOfPage" href="https://curforever.github.io/2024/12/20/Esko%20Ukkonen%20On-line%20Construction%20of%20Suffix%20Trees/">
<span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
<meta itemprop="image" content="/images/avatar.png">
<meta itemprop="name" content="胡景峰">
<meta itemprop="description" content="东南大学 软件学院">
</span>
<span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
<meta itemprop="name" content="像风一样の博客">
</span>
<header class="post-header">
<h2 class="post-title" itemprop="name headline">
<a href="/2024/12/20/Esko%20Ukkonen%20On-line%20Construction%20of%20Suffix%20Trees/" class="post-title-link" itemprop="url">Esko Ukkonen On-line Construction of Suffix Trees</a>
</h2>
<div class="post-meta">
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="fa fa-calendar-o"></i>
</span>
<span class="post-meta-item-text">发表于</span>
<time title="创建时间:2024-12-20 16:29:38 / 修改时间:16:30:49" itemprop="dateCreated datePublished" datetime="2024-12-20T16:29:38+08:00">2024-12-20</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="fa fa-folder-o"></i>
</span>
<span class="post-meta-item-text">分类于</span>
<span itemprop="about" itemscope itemtype="http://schema.org/Thing">
<a href="/categories/%E8%AE%B2%E8%A7%A3%E6%95%99%E7%A8%8B/" itemprop="url" rel="index"><span itemprop="name">讲解教程</span></a>
</span>
</span>
<br>
<span class="post-meta-item" title="本文字数">
<span class="post-meta-item-icon">
<i class="fa fa-file-word-o"></i>
</span>
<span class="post-meta-item-text">本文字数:</span>
<span>9.5k</span>
</span>
<span class="post-meta-item" title="阅读时长">
<span class="post-meta-item-icon">
<i class="fa fa-clock-o"></i>
</span>
<span class="post-meta-item-text">阅读时长 ≈</span>
<span>17 分钟</span>
</span>
</div>
</header>
<div class="post-body" itemprop="articleBody">
<h1 id="Esko-Ukkonen-On-line-Construction-of-Suffix-Trees"><a href="#Esko-Ukkonen-On-line-Construction-of-Suffix-Trees" class="headerlink" title="Esko Ukkonen: On-line Construction of Suffix Trees"></a>Esko Ukkonen: On-line Construction of Suffix Trees</h1><p>@[toc]</p>
<h1 id="一、后缀树的概念及应用【详见刘方州同学报告】"><a href="#一、后缀树的概念及应用【详见刘方州同学报告】" class="headerlink" title="一、后缀树的概念及应用【详见刘方州同学报告】"></a>一、后缀树的概念及应用【详见刘方州同学报告】</h1><h2 id="1-1-字典树-Trie"><a href="#1-1-字典树-Trie" class="headerlink" title="1.1 字典树 Trie"></a>1.1 字典树 Trie</h2><p>定义:字典树,又称单词查找树或键树,是一种树形结构,是一种哈希树的变种。<br>用途:用于统计和排序大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计。<br>优点:最大限度地减少无谓的字符串比较,查询效率比哈希表高。<br>核心思想:空间换时间,利用字符串的公共前缀来降低查询时间的开销以达到提高效率的目的。<br>基本性质:<br>(1)根节点不包含字符,除根节点外每一个节点都只包含一个字符。<br>(2)从根节点到某一节点,路径上经过的字符连接起来,为该节点对应的字符串。<br>(3)每个节点的所有子节点包含的字符都不相同。</p>
<h2 id="1-2-后缀树-Suffix-Tree"><a href="#1-2-后缀树-Suffix-Tree" class="headerlink" title="1.2 后缀树 Suffix Tree"></a>1.2 后缀树 Suffix Tree</h2><p>后缀树是一种数据结构,能快速解决很多关于字符串的问题。后缀树的概念最早由Weiner于1973年提出,既而由McCreight在1976年和Ukkonen在1992年和1995年加以改进完善。<br>给定一长度为n的字符串T=T_1 T_2 〖…T〗<em>n和整数i (1<=i<=n),子串T_i T</em>(i+1) 〖…T〗_n便都是字符串T的后缀。以字符串T=abcabxabcd为例,它的长度为10,所以abcabxabcd、bcabxabcd、cabxabcd、…、d都是T的后缀。规定空字串也是后缀。后缀树,就是包含一则字符串所有后缀的压缩字典树,压缩过程如图1所示。把abcabxabcd的所有后缀加入字典树并压缩后,我们得到如图2的后缀树。</p>
<p>![图1 后缀字典树到后缀树的压缩过程](Esko Ukkonen On-line Construction of Suffix Trees.assets/6acacda119cab9dd2e567502e3677939.png)</p>
<p>![图2 abcabxabcd的后缀树](Esko Ukkonen On-line Construction of Suffix Trees.assets/441b6b774ab91a0a40e2b0edd0232d4e.png)</p>
<p>如图2所示,Suffix Tree与Trie的不同在于边不再只代表单个字符,而是每个边可以表示任意的长度,实操过程中用两个指针[from, to]实现,耗费O(1)的空间。</p>
<h2 id="2-后缀树的应用"><a href="#2-后缀树的应用" class="headerlink" title="2 后缀树的应用"></a>2 后缀树的应用</h2><p>2.1 最长重复子串<br>2.2 最长公共子串<br>2.3 最长回文子串</p>
<h1 id="二、朴素后缀树构造方法及问题"><a href="#二、朴素后缀树构造方法及问题" class="headerlink" title="二、朴素后缀树构造方法及问题"></a>二、朴素后缀树构造方法及问题</h1><p>略
</p>
<h1 id="三、线性时间内后缀树在线构造方法"><a href="#三、线性时间内后缀树在线构造方法" class="headerlink" title="三、线性时间内后缀树在线构造方法"></a>三、线性时间内后缀树在线构造方法</h1><p>McCreight最初的构造法原则上要按逆序构造,也就是说字符要从末端开始插入。如此一来便不能作为在线算法, 它变得更加难以应用于实际问题,如数据压缩。<br>20年后,来自赫尔辛基理工大学的Esko Ukkonen把原算法作了一些改动,实现了线性时间内对字符串从左往右的后缀树在线构造方法。<br>对于所给的文本T,由一棵空树开始逐步构造T的后缀树。以abcabxabcd为例,先由a开始,接着是ab,然后abc,…,不断更新直到构造出abcabxabcd的后缀树。</p>
<h2 id="3-1-概念引入"><a href="#3-1-概念引入" class="headerlink" title="3.1 概念引入"></a>3.1 概念引入</h2><h3 id="(1)隐式后缀树-Implicit-Suffix-Tree"><a href="#(1)隐式后缀树-Implicit-Suffix-Tree" class="headerlink" title="(1)隐式后缀树 Implicit Suffix Tree"></a>(1)隐式后缀树 Implicit Suffix Tree</h3><p>按上述方法在线构造abcabxabcd的后缀树的过程中,我们必然会构造出字符串abcab的后缀树,对其所有后缀枚举如下:abcab、bcab、cab、ab、b。观察发现:后缀ab被包含在abcab中作为其前缀;后缀b被包含在bcab中作为其前缀。<br>如果为ab或b单独开辟新的分支,则不符合字典树的性质,即每个节点的所有子节点包含的字符都不相同。因此我们选择暂时认为ab、b隐式包含在已有分支里,这样构造出来的后缀树称为隐式后缀树。<br>在我看来,隐式后缀树是在扫描和构建过程中节省时间的一步操作。因为字符串尚未扫描结束,所以这些操作可以先记录着而暂时不去执行,其代价是需要引入接下来要提及的活动点和剩余后缀数。</p>
<h3 id="(2)终止符"><a href="#(2)终止符" class="headerlink" title="(2)终止符 $"></a>(2)终止符 $</h3><p><strong>问题:如何确定查找后缀树得到的子串是一个后缀还是后缀的一部分?</strong><br>解决:在文本后添加字母表以外的字符,比如$。这样,当查找到ab$或b$就说明这是一个后缀,避免了二义性。对abcab$的所有后缀重新枚举如下:xabxa$、abxa$、bxa$、xa$、a$、$。观察发现:xa$不再是xabxa$的前缀;a$不再是bcab$的前缀。</p>
<h3 id="(3)活动点active-point、剩余后缀数-remainder"><a href="#(3)活动点active-point、剩余后缀数-remainder" class="headerlink" title="(3)活动点active point、剩余后缀数 remainder"></a>(3)活动点active point、剩余后缀数 remainder</h3><p><strong>问题:我们提到了隐式后缀树,隐式什么时候变为显式?怎么变为显式?</strong><br>比喻:隐式就像瘦子躲在胖子后面,瘦子露出马脚的时候就是变为显式的时候。<br>举例:以最终构建abcabx为例。第一阶段,我们从左到右在线构建abc的后缀树,如图3所示。<br> ![在这里插入图片描述](Esko Ukkonen On-line Construction of Suffix Trees.assets/dd57f4da725c038161235b3f84657b20.png)<br>图3 abc的后缀树<br>第二阶段,我们需要构建abcab的后缀树,如图4所示。新增字符a新增字符b的情况下,不必大刀阔斧改变树的结构,只要悄悄在每条边后面追加a追加b即可。枚举abcab的后缀集合:abcab、bcab、cab、ab、b。观察发现,abcab、bcab、cab即为三条边,而ab、b隐式地包含其中。</p>
<p> ![在这里插入图片描述](Esko Ukkonen On-line Construction of Suffix Trees.assets/7bf70b3bdbcbf172481964a86f221193.png)</p>
<p>图4 abcab的后缀树<br>第三阶段,我们需要构建abcabx的后缀树。新增字符x,x就是露出的马脚,因为已有的后缀树的边里没有包含abx的。露出马脚之时就是变为显式之日,通过裂变出新的边变为显式,如图5所示。<br> ![在这里插入图片描述](Esko Ukkonen On-line Construction of Suffix Trees.assets/2a784f64875c60a2bb00befdfcab4329.png)<br>图5 abcabx的后缀树</p>
<p><strong>问题:如何确定裂变的位置?</strong><br>解决:引入活动点active point,用于确定裂变的位置。活动点active point是一个包括(active_node, active_edge, active_length)的三元组。该三元组在每次后缀树的搜索中更新。<br>根据active_node确定结点,根据active_edge确定结点的某一条边,根据active_length确定边上的某个位置。举例来说,如图6所示,active_node为0,即根节点,active_edge为a,即从根节点出发、字符为a的这条边,active_length为2,即该边索引为2的地方,即符号|所在位置。<br> ![在这里插入图片描述](Esko Ukkonen On-line Construction of Suffix Trees.assets/0cd8b06ef3a341b25445a60cac7e6b1c.png)<br>图6 active point的含义解释</p>
<p><strong>问题:裂变具体怎么做?</strong><br>解决:如图7所示,以abcab->abcabx为例,裂变时进行以下操作:<br>① 根据活动点确定裂变位置(ab|cab),在|处添加节点。<br>② 在新增的节点后分裂出一个边为x的节点。</p>
<p>![在这里插入图片描述](Esko Ukkonen On-line Construction of Suffix Trees.assets/33d19f111e79fc01e511eed4fd34410c.png)<br>图7 裂变的过程<br>至此由于添加abx后缀引发的裂变完成。<br><strong>问题:只裂变一次就够了吗?</strong><br>思考:未必够。以abcab到abcabx为例,abcab的后缀树表示如图8所示。<br> ![在这里插入图片描述](Esko Ukkonen On-line Construction of Suffix Trees.assets/916ab767229cd8688ecede1d6214c4df.png)<br>图8 abcab的后缀树<br>已知abcabx的后缀集合:abcabx、bcabx、cabx、abx、bx、x。<br>如果仅在已有的边后面添加x,只能覆盖abcabx、bcabx、cabx,剩下abx、bx、x。由于每次裂变能得到1个新后缀,直觉上来说需要进行3次裂变,事实上也是如此。上述过程只完成了添加abx后缀引发的裂变。<br>解决:引入剩余后缀数remainder,表示还需要插入多少个新的后缀,即还需要裂变几次。remainder=0时,表示当前新增字符处理完毕,继续扩展下一字符。</p>
<h3 id="(4)后缀链接-Suffix-Link"><a href="#(4)后缀链接-Suffix-Link" class="headerlink" title="(4)后缀链接 Suffix Link"></a>(4)后缀链接 Suffix Link</h3><p>根据上述问题思考已经明确了两个事实:<br>① 活动点active point指向要裂变的位置。<br>② 要裂变的位置可能不止一个。<br><strong>问题:每次都重新从根节点搜索下一裂变处吗?</strong><br>解决:不需要。引入后缀链接Suffix Link,用于快速找到下一裂变处。<br><strong>问题:后缀链接怎么创建?</strong><br>规则:每进行一次裂变,会新增非叶节点和新边。后缀链接从该新增的非叶节点出发,指向下一次裂变新增的非叶节点,用虚线连接。<br><strong>问题:为什么后缀链接可以快速找到下一裂变处?</strong><br>观察:后缀链接连接的节点存在的关系:如果有一个从A指向B的后缀链接,那么从根节点到A节点表示的子串剔除第首个字符后得到的即为从根节点到B节点表示的子串。<br>举例:图9中节点4表示字符串ab,节点6表示字符串b,ab剔除掉首个字符a后得到b。实际处理时,每一次裂变意味着一个待添加后缀的成功插入(abx),下一次裂变的工作就是插入下一个待添加后缀(bx),下一个待添加后缀(bx)与当前成功插入的后缀(abx)的关系也是这样。<br>好处:可以方便地从一个后缀跳到另一个后缀,降低算法的时间复杂度。<br>![在这里插入图片描述](Esko Ukkonen On-line Construction of Suffix Trees.assets/adeeca639e49e547a5b54e7b817e1c59.png)</p>
<h2 id="3-2-过程演示"><a href="#3-2-过程演示" class="headerlink" title="3.2 过程演示"></a>3.2 过程演示</h2><p>![图10 后缀树构建过程演示Step 1-空树](Esko Ukkonen On-line Construction of Suffix Trees.assets/76d05959648ed4212fe1c0ccaa09e7cd.png)</p>
<p>![图11 后缀树构建过程演示Step 2-a](Esko Ukkonen On-line Construction of Suffix Trees.assets/e91af3d53f2bb9ee38567cf6045e1cc6.png)</p>
<p>![图12 后缀树构建过程演示Step 3-ab](Esko Ukkonen On-line Construction of Suffix Trees.assets/d3851a90bc2f300a0fc14dffa770f4e5.png)</p>
<p>![图13 后缀树构建过程演示Step 4-abc](Esko Ukkonen On-line Construction of Suffix Trees.assets/53309f726a393bced86746c7a838c6f1.png)</p>
<p>![图14 后缀树构建过程演示Step 5-abca](Esko Ukkonen On-line Construction of Suffix Trees.assets/d45b48924e9a6f7252b6f2b0ce4aad13.png)</p>
<p>注意到已经存在的第一条边前缀中隐式包含了a。隐式包含在实操过程中的做法就是更新活动点active point和剩余后缀数remainder。<br>单就后缀树而言,这颗后缀树没有准确地描述当前读到的字符串abca。如何保证最后扫描结束的时候后缀树可以准确表示呢?回扣前文终结符的引入:在遇到$并做完相应操作后,后缀树可以准确地描述abca$。</p>
<p>![图15 后缀树构建过程演示Step 6-abcab](Esko Ukkonen On-line Construction of Suffix Trees.assets/3e305edbd22d407d460daf5833cba095.png)</p>
<p>更新active point:a后面有b,length+1,往后挪;还在同一条边上,node和edge不变;<br>更新remainder+1=2:表示需要插入两个后缀ab、b。<br><strong>问题:为什么remainder+1?</strong><br>因为上一步的a实际上没有被插入树中,所以它被remain了下来,而后我们又继续处理b了,所以上一步没插入的a延长成了ab。加入的1即需要插入新的后缀b。<br><strong>问题:再看active point和remainder记录信息似乎是缺失的:记录了后缀ab即将添加的位置,记录了2个待添加后缀,却没有记录b即将添加的位置?为什么呢?</strong><br>先说结论:“既然第一条边有ab|cab,那在第一条边后面(也就是第二条第三条边里)一定存在去掉a以b开头的后缀”。<br>再详细解释:回顾一下这里第二条边是如何产生的?正是因为后缀树的逐步构建过程中a后接了b,所以我们先在第一条边的a追加成ab,再为b开辟新的边,即第二条边,所以这个第二条边就是显然的以b开头的后缀。换句话说,即使a后面不是紧跟的b,而是紧跟的是个x,那也会新开一条边以x开头的。</p>
<p>![图16 后缀树构建过程演示Step 7-abcabx-插入abx](Esko Ukkonen On-line Construction of Suffix Trees.assets/a22f32c30e4b711815f8af1b5f9e5f9f.png)</p>
<p>remainder=3,表示有3个待添加的后缀:abx、bx、x<br>我们按之前的逻辑来试图更新active point:ab之后找x,找不到!因此在裂变位置添加新的节点4、新的边x。这一步完成了后缀abx的添加。但是active point怎么更新呢? </p>
<h3 id="Rule-1(活动点更新规则1)"><a href="#Rule-1(活动点更新规则1)" class="headerlink" title="Rule 1(活动点更新规则1)"></a>Rule 1(活动点更新规则1)</h3><p>当active_node = root 时遵循:<br> active_node 保持为 root;<br> active_edge 被设置为即将被插入的新后缀的首字符;<br> active_length 减1;</p>
<p>![图17 后缀树构建过程演示Step 7-abcabx-插入abx后更新active point](Esko Ukkonen On-line Construction of Suffix Trees.assets/a64832fcdb1136281c02cdf2fbdf0854.png)</p>
<p>根据Rule 1规则更新active point:<br> active_node 保持为 root;<br> active_edge 被设置为即将被插入的新后缀bx的首字符b;<br> active_length-1=1;<br>更新remainder:remainder-1=2,表示还有2个后缀待添加:bx、x。</p>
<p>![图18 后缀树构建过程演示Step 8-abcabx-插入bx](Esko Ukkonen On-line Construction of Suffix Trees.assets/63436a9acf538d6d203988fdae7ab973.png)</p>
<p>裂变过程与abx的插入相似,不多赘述。依据Rule 1更新active point为 (0, ‘x’, 0)。<br>更新remainder-1=1,表示还有1个后缀x没有插入。<br>注:图里的remainder=0,我认为其意思是在扫描到x时回头处理之前的ab,但其实并没有真的扫描x,就像一个人往前走路只是把脚伸过去但没有迈过去踩实,所以默认观察到了x并处理了之前遗留的a和b,但尚未处理x,现在remainder=0说明a和b处理好了,开始处理下一个字符x,直接在根节点加边x。<br>除此以外,该步骤还需要创建后缀链接。</p>
<h3 id="Rule-2(后缀链接创建规则)"><a href="#Rule-2(后缀链接创建规则)" class="headerlink" title="Rule 2(后缀链接创建规则)"></a>Rule 2(后缀链接创建规则)</h3><p>如果我们分裂一条边并且插入一个新的节点,并且如果该新节点不是创建的第一个节点,则将先前插入的节点与该新节点通过一个特殊的指针连接,称为后缀链接,通过一条虚线来表示。<br>在图18中,因插入bx新裂变出来的节点6,不是扫描到x后创建的第一个节点了(第一个节点是因插入abx新裂变出来的节点4),因此创建后缀链接:4->6。<br>我的理解是“前人栽树,后人乘凉”,这条后缀链接在下一次碰到ab时会有用。</p>
<p>![图19 后缀树构建过程演示Step 9-abcabx-插入x](Esko Ukkonen On-line Construction of Suffix Trees.assets/241229f58f6858bce3fdc663271d3a02.png)</p>
<p>active point为 (0, x, 0),length=0,所以在根节点创建边x。<br>remainder-1=0,表示可以处理下一个字符了。</p>
<p>![图20 Step 10 后缀树构建过程演示-abcabxa](Esko Ukkonen On-line Construction of Suffix Trees.assets/8d808c8cb610ac0bae0578d2a0f076e4.png)</p>
<p>![图21 后缀树构建过程演示Step 11-abcabxab](Esko Ukkonen On-line Construction of Suffix Trees.assets/1c1968d58f4f4c5bc7683d5b16938455.png)<br>![图22 后缀树构建过程演示Step 12-abcabxabc](Esko Ukkonen On-line Construction of Suffix Trees.assets/c0ae42f9a7da011ee79ddb8dc51b280e.png)</p>
<p>更新active point(4,’c’,1);<br>更新remainder=3,表示需要插入abc、bc、c三个后缀。</p>
<p>![图23 后缀树构建过程演示Step 13-abcabxabcd](Esko Ukkonen On-line Construction of Suffix Trees.assets/2bc2d57804e9482ce96f46ece0d7cf3e.png)</p>
<p>更新remainder = 4,需要插入abcd、bcd、cd、d四个后缀;<br>更新active point:abc之后找d,找不到!因此在裂变位置添加新的节点9、新的边d。<br><strong>问题:此时active point如何更新的?</strong></p>
<h3 id="Rule-3(活动点更新规则2)"><a href="#Rule-3(活动点更新规则2)" class="headerlink" title="Rule 3(活动点更新规则2)"></a>Rule 3(活动点更新规则2)</h3><p>当从active_node从不为root的节点分裂边时,我们沿着后缀链接的方向寻找节点:<br> 如果存在一个节点,则设置该节点为 active_node;<br> 如果不存在,则设置 active_node 为 root。<br>上述两种情况的active_edge 和 active_length 保持不变。</p>
<p>根据Rule 3,图23的active point为(6, c, 1)。<br>更新remainder = 3,并且开始处理下一个剩余后缀bcd。<br>bc后并没有没出现d,裂变。</p>
<p>![图24 后缀树构建过程演示Step 14-abcabxabcd-插入bcd](Esko Ukkonen On-line Construction of Suffix Trees.assets/65e0df16b2dc3965f7e7c0189a225f24.png)</p>
<p>裂变创建了节点11和边d。除了更新之外,根据Rule2创建后缀链接:9->11。<br>此时,我们观察两个后缀链接:<br> 4 (ab) -> 6 (b)<br> 9 (abc) -> 11 (bc)<br>remainder-1=2,表示还需要插入cd、d;<br>根据Rule 3更新active point为(root, c, 1)。</p>
<p>![图25 后缀树构建过程演示Step 15-abcabxabcd-插入cd](Esko Ukkonen On-line Construction of Suffix Trees.assets/386d3504718fddf9b0ce651c7dc86a79.png)</p>
<p>更新active point时:由于找不到后续d,因此裂变:新建节点13和边d;<br>更新remainder-1 = 1;<br>依据Rule 2创建后缀链接:11 -> 13。</p>
<p>![图26 后缀树构建过程演示Step 16-abcabxabcd-插入d](Esko Ukkonen On-line Construction of Suffix Trees.assets/fddc1ff5489a9a7cae0c61c89f034748.png)</p>
<p>更新active point时:由于找不到后续d,因此裂变,新建边d;<br>更新remainder-1=0。</p>
<p>![图27 后缀树构建过程演示Step 17-abcabxabcd$](Esko Ukkonen On-line Construction of Suffix Trees.assets/d892500e7a996e91ed73317b7618ce7b.png)</p>
<p>对树结构的改变仅需在根节点上插入一条新边$。<br>整个后缀树构建完成。</p>
<h2 id="3-3-复杂度分析"><a href="#3-3-复杂度分析" class="headerlink" title="3.3 复杂度分析"></a>3.3 复杂度分析</h2><p>关于隐式后缀树,如果扫描发现要被插入的字符已经存在于树中,则无需修改树的结构。原因是要被插入的字符实际上已经隐式地被包含在了当前的树中。而active point和remainder的更新记录了这部分信息,确保了在后续的操作中会进行处理。</p>
<p><strong>问题:算法结束时remainder > 0的情况存在吗?</strong><br>解决: remainder > 0意味着当前仍为隐式后缀树,虽然隐式包含着后缀信息,但是整个树并没有准确表达所有后缀。<br>我们在字符串末尾添加$以避免这种情况。由于$一定不同于字符串中任一字符的特性,使得在扫描到$时一定将之前所有隐式包含的后缀暴露出来并处理,处理的过程中remainder递减至0,最终完成整个后缀树的构建。<br>remainder记录了还余下多少后缀需要插入。这些插入操作将逐个的与当前位之前的后缀进行对应,我们需要一个接着一个的处理。每次插入需要O(1)时间。active point记录了插入(裂变)的位置。仅需在该位置新增一个字符,因为其他字符都被隐式地包含了。每次插入后:对于remainder,相应减少;对于active point:如果存在后缀连接的node续接至下一个节点;如果不存在则返回root节点;如果已经是在root节点了,则依据Rule1来修改活动点。无论哪种情况,仅需O(1)时间。<br>如果这些插入操作中,如果发现要被插入的字符已经存在于树中,则什么也不做,即使 remainder>0。原因是要被插入的字符实际上已经隐式地被包含在了当前的树中。而 remainder>0 则确保了在后续的操作中会进行处理。</p>
<p><strong>整体算法复杂度是多少?</strong><br>如果输入字符串的长度为n,则有n步需要执行,加上$有n+1步。在每一步中:<br> 要么消耗O(1) 时间更新active point和remainder;<br> 要么消耗O(1) 时间执行裂变插入操作;<br>因此整体算法复杂度为O(n)。</p>
</div>
<footer class="post-footer">
<div class="post-eof"></div>
</footer>
</article>
<article itemscope itemtype="http://schema.org/Article" class="post-block" lang="zh-CN">
<link itemprop="mainEntityOfPage" href="https://curforever.github.io/2024/12/20/%E9%93%BE%E8%A1%A8%E9%80%86%E7%BD%AE%E8%AF%A6%E7%BB%86%E8%AE%B2%E8%A7%A3%EF%BC%88%E5%9B%BE%E6%96%87%EF%BC%89/">
<span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
<meta itemprop="image" content="/images/avatar.png">
<meta itemprop="name" content="胡景峰">
<meta itemprop="description" content="东南大学 软件学院">
</span>
<span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
<meta itemprop="name" content="像风一样の博客">
</span>
<header class="post-header">
<h2 class="post-title" itemprop="name headline">
<a href="/2024/12/20/%E9%93%BE%E8%A1%A8%E9%80%86%E7%BD%AE%E8%AF%A6%E7%BB%86%E8%AE%B2%E8%A7%A3%EF%BC%88%E5%9B%BE%E6%96%87%EF%BC%89/" class="post-title-link" itemprop="url">链表逆置详细讲解(图文)</a>
</h2>
<div class="post-meta">
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="fa fa-calendar-o"></i>
</span>
<span class="post-meta-item-text">发表于</span>
<time title="创建时间:2024-12-20 16:28:07 / 修改时间:16:29:26" itemprop="dateCreated datePublished" datetime="2024-12-20T16:28:07+08:00">2024-12-20</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="fa fa-folder-o"></i>
</span>
<span class="post-meta-item-text">分类于</span>
<span itemprop="about" itemscope itemtype="http://schema.org/Thing">
<a href="/categories/%E8%AE%B2%E8%A7%A3%E6%95%99%E7%A8%8B/" itemprop="url" rel="index"><span itemprop="name">讲解教程</span></a>
</span>
</span>
<br>
<span class="post-meta-item" title="本文字数">
<span class="post-meta-item-icon">
<i class="fa fa-file-word-o"></i>
</span>
<span class="post-meta-item-text">本文字数:</span>
<span>1.4k</span>
</span>
<span class="post-meta-item" title="阅读时长">
<span class="post-meta-item-icon">
<i class="fa fa-clock-o"></i>
</span>
<span class="post-meta-item-text">阅读时长 ≈</span>
<span>3 分钟</span>
</span>
</div>
</header>
<div class="post-body" itemprop="articleBody">
<h1 id="链表逆置"><a href="#链表逆置" class="headerlink" title="链表逆置"></a>链表逆置</h1><p> </p>
<h2 id="前言"><a href="#前言" class="headerlink" title="==前言=="></a>==前言==</h2><p><strong>链表逆置</strong>是初学时有困扰到我的难点.</p>
<p>由于链表<strong>头结点</strong>可放可不放数据,所以写代码时候 <strong>->next</strong> 用的云里雾里。</p>
<p>这里讲解头结点与第一结点区分的情况,即<strong>头结点</strong>你把它看作这个 <strong>链表的“文件名”</strong> 就行。<br>若头结点为L,则第一结点为L->next。</p>
<p> </p>
<h2 id="代码"><a href="#代码" class="headerlink" title="==代码=="></a>==代码==</h2><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">void</span> <span class="title function_">listReverse</span>(<span class="params">linkedList &L</span>)</span><br><span class="line">{</span><br><span class="line"> node *p,*s;</span><br><span class="line"> <span class="comment">//1.</span></span><br><span class="line"> p = L->next;</span><br><span class="line"> L->next = <span class="variable constant_">NULL</span>;</span><br><span class="line"> </span><br><span class="line"> <span class="keyword">while</span>(p)</span><br><span class="line"> {</span><br><span class="line"> <span class="comment">//2.1</span></span><br><span class="line"> s = p; </span><br><span class="line"> p = p->next;</span><br><span class="line"> <span class="comment">//2.2</span></span><br><span class="line"> s->next = L->next; </span><br><span class="line"> L->next = s;</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p><strong>看不懂别慌。我会把代码拆解成三块为你讲解。</strong><br>讲解前,先做一个理解工作,以 L->next 为例,按在表达式<strong>左</strong>边or<strong>右</strong>边分,存在两种情况:</p>
<p><strong>情况一(左):L->next = NULL;</strong></p>
<blockquote>
<p>重点在<strong>next</strong>,即L的<strong>指针域</strong>,该表达式将指针域指向NULL。 </p>
</blockquote>
<p><strong>情况二(右):p = L->next;</strong></p>
<blockquote>
<p>重点在 L->next <strong>整体</strong>, 即 L->next 这个<strong>结点</strong>,->next在这里就是个形式,目的还是为了告诉你是<strong>这个结点</strong>!该表达式将p指针指向结点L->next。</p>
</blockquote>
<p> </p>
<h2 id="讲解"><a href="#讲解" class="headerlink" title="==讲解=="></a>==讲解==</h2><p>我们先看<strong>第一轮</strong>循环做了什么:</p>
<p><strong>建议阅读顺序:黑色(初始)、蓝色(操作)、红色(理解)</strong><br> <br><img src="链表逆置详细讲解(图文).assets/cf3babfba4681baa73937d25b54ab275.jpeg" width="60%" /><br> <br> </p>
<p><strong>第二轮:</strong><br> <br><strong>建议阅读顺序:黑色(初始)、蓝色(操作)、红色(理解)</strong><br><img src="链表逆置详细讲解(图文).assets/b54b1f7f25db0e810e8f91b7476a517a.jpeg" width="60%" /></p>
<p><strong>第三轮省略(可以自己尝试)。</strong><br> <br> </p>
<h2 id="总结"><a href="#总结" class="headerlink" title="==总结=="></a>==总结==</h2><p>不难发现:</p>
<ul>
<li><p>链表逆置利用了<strong>s、p两个指针</strong>的<strong>移动</strong>实现</p>
</li>
<li><p>每一轮循环体执行结束后,<strong>s</strong>指向<strong>刚刚逆置成功</strong>的结点,<strong>p</strong>指向<strong>下一轮待逆置</strong>的结点</p>
</li>
<li><p><strong>为什么需要p?</strong><br> 因为2.2步骤中s->next会<strong>被改写</strong>,<br> 若只有s,会<strong>丢失剩余的结点</strong>,<br> 这时候p起到<strong>暂存</strong>的作用,等待下一轮2.1步骤中的s=p找到它。</p>
</li>
</ul>
<p> <br> </p>
<p><strong>最后给一份带注释的代码~</strong></p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">void</span> <span class="title function_">listReverse</span>(<span class="params">linkedList &L</span>)</span><br><span class="line">{</span><br><span class="line"> node *p,*s;</span><br><span class="line"> <span class="comment">//1.准备工作</span></span><br><span class="line"> p = L->next;</span><br><span class="line"> L->next = <span class="variable constant_">NULL</span>;</span><br><span class="line"> </span><br><span class="line"> <span class="keyword">while</span>(p)</span><br><span class="line"> {</span><br><span class="line"> <span class="comment">//2.1 s记录正在处理的结点,p记录下一轮待处理的结点</span></span><br><span class="line"> s = p; <span class="comment">//s承接上一轮记录的位置</span></span><br><span class="line"> p = p->next; <span class="comment">//p为下一轮记录位置</span></span><br><span class="line"> <span class="comment">//2.2 把s插入 已逆置的部分 中</span></span><br><span class="line"> s->next = L->next; <span class="comment">// L->next代表已逆置的第一结点,s的指针域指向它</span></span><br><span class="line"> L->next = s; <span class="comment">//(头结点的指针域,即)第一结点 设置为s</span></span><br><span class="line"> <span class="comment">//2.2步骤相当于:</span></span><br><span class="line"> <span class="comment">//s 对 队伍(已逆置部分)的队首(已逆置的第一结点)说:你不要排在柜台前了,你排在我后面</span></span><br><span class="line"> <span class="comment">//等队伍排在s后面后,s自己排到了柜台前</span></span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p> <br> <br><strong>有问题可以评论区交流讨论哈~</strong> </p>
</div>
<footer class="post-footer">
<div class="post-eof"></div>
</footer>
</article>
<article itemscope itemtype="http://schema.org/Article" class="post-block" lang="zh-CN">
<link itemprop="mainEntityOfPage" href="https://curforever.github.io/2024/12/20/%E3%80%8A%E8%AE%A4%E7%9F%A5%E8%A7%89%E9%86%92%EF%BC%9A%E5%BC%80%E5%90%AF%E8%87%AA%E6%88%91%E6%94%B9%E5%8F%98%E7%9A%84%E5%8E%9F%E5%8A%A8%E5%8A%9B%E3%80%8B%E8%AF%BB%E4%B9%A6%E7%AC%94%E8%AE%B0/">
<span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
<meta itemprop="image" content="/images/avatar.png">
<meta itemprop="name" content="胡景峰">
<meta itemprop="description" content="东南大学 软件学院">
</span>
<span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
<meta itemprop="name" content="像风一样の博客">
</span>
<header class="post-header">
<h2 class="post-title" itemprop="name headline">
<a href="/2024/12/20/%E3%80%8A%E8%AE%A4%E7%9F%A5%E8%A7%89%E9%86%92%EF%BC%9A%E5%BC%80%E5%90%AF%E8%87%AA%E6%88%91%E6%94%B9%E5%8F%98%E7%9A%84%E5%8E%9F%E5%8A%A8%E5%8A%9B%E3%80%8B%E8%AF%BB%E4%B9%A6%E7%AC%94%E8%AE%B0/" class="post-title-link" itemprop="url">《认知觉醒:开启自我改变的原动力》读书笔记</a>
</h2>
<div class="post-meta">
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="fa fa-calendar-o"></i>
</span>
<span class="post-meta-item-text">发表于</span>
<time title="创建时间:2024-12-20 16:19:24 / 修改时间:16:23:11" itemprop="dateCreated datePublished" datetime="2024-12-20T16:19:24+08:00">2024-12-20</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="fa fa-folder-o"></i>
</span>
<span class="post-meta-item-text">分类于</span>
<span itemprop="about" itemscope itemtype="http://schema.org/Thing">
<a href="/categories/%E8%AF%BB%E4%B9%A6%E7%AC%94%E8%AE%B0/" itemprop="url" rel="index"><span itemprop="name">读书笔记</span></a>
</span>
</span>
<br>
<span class="post-meta-item" title="本文字数">
<span class="post-meta-item-icon">
<i class="fa fa-file-word-o"></i>
</span>
<span class="post-meta-item-text">本文字数:</span>
<span>18k</span>
</span>
<span class="post-meta-item" title="阅读时长">
<span class="post-meta-item-icon">
<i class="fa fa-clock-o"></i>
</span>
<span class="post-meta-item-text">阅读时长 ≈</span>
<span>32 分钟</span>
</span>
</div>
</header>
<div class="post-body" itemprop="articleBody">
<p>认知觉醒:开启自我改变的原动力</p>
<p>周岭</p>
<p>208个笔记</p>
<p>◆ 上篇 内观自己,摆脱焦虑</p>
<p>>> 事实上理智脑很少有主见,大多数时候我们以为自己在思考,其实都是在对自身的行为和欲望进行合理化,这正是人类被称作“自我解释的动物”的原因。</p>
<p>>> 习惯之所以难以改变,就是因为它是自我巩固的——越用越强,越强越用。要想从既有的习惯中跳出来,最好的方法不是依靠自制力,而是依靠知识</p>
<p>◆ 第二节 焦虑:焦虑的根源</p>
<p>>> 读书的“艰难”与买书的“惬意”简直相差十万八千里。</p>
<p>>> 归结起来,焦虑的原因就两条:想同时做很多事,又想立即看到效果。王小波说:人的一切痛苦,本质上都是对自己无能的愤怒。焦虑的本质也契合这一观点:自己的欲望大于能力,又极度缺乏耐心。焦虑就是因为欲望与能力之间差距过大。</p>
<p>◆ 第三节 耐心:得耐心者得天下</p>
<p>>> 很多人虽然嘴上说要保持耐心,但身体却诚实地游走在即时满足的边缘。他们总是从最简单、最舒适的部分开始一天的工作,然后沉迷于娱乐信息、醉心于周边琐事,就是无力去做重要的事情;</p>
<p>>> 从权重上看,改变量﹥行动量﹥思考量﹥学习量</p>
<p>>> 很多人之所以痛苦焦虑,就是因为只盯着表层的学习量。他们读了很多书、报了很多课,天天打卡、日日坚持,努力到感动自己,但就是没有深入关注过自己的思考、行动和改变,所以总是感到学无所获,甚至会认为是自己不够努力,应该继续加大学习量,结果陷入了“越学越焦虑,越焦虑越学”的恶性循环。</p>
<p>>> 一旦觉察自己开始失去耐心了,就温和地对自己说:“你看,我身体里那个原始人又出来了,让他离开丛林到城市生活,确实挺不容易的,要理解他。”</p>
<p>>> 温和地告诉它们:“该有的享受一点都不会少,只是不是现在享受,而是在完成重要的事情之后。”</p>
<p>>> 这种“后娱乐”的好处是,将享乐的快感建立在完成重要任务后的成就感之上,很放松、踏实,就像一种奖赏;而“先娱乐”虽然刚开始很快活,但精力会无限发散,拖延重要的工作,随着时间的流逝,人会空虚、焦虑。</p>
<p>◆ 第二章 潜意识——生命留给我们的彩蛋</p>
<p>>> 反本能成长</p>
<p>>> ·《思考力》一书的作者上田正仁提示:思考力的本质就是“丢弃所有已经消化的信息,让问题的核心浮出水面”;</p>
<p>·《刻意练习》中的核心方法论是:不要重复练习已经会的,要不断寻找那些稍有难度的部分;</p>
<p>·《原则》一书的作者瑞·达利欧罗列了工作和生活中的原则,用以清晰地指导自己行事;</p>
<p>·《超越感觉》一书告诉我们,想拥有清晰的逻辑,就坚持一点:凡事不要凭模糊的感觉判断,要寻找清晰的证据。</p>
<p>>> 提升思考能力的方法正是不断明确核心困难和心得感悟,并专注于此。</p>
<p>>> 优秀的人更倾向于做高耗能的事,比如“学霸”的秘诀往往在他们的错题本上——他们更愿意花时间明确错误,并集中精力攻克。</p>
<p>>> 多数人为了逃避真正的思考,愿意做任何事情。</p>
<p>>> 具体事件一旦变模糊,其边界就会无限扩大,原本并不困难的小事,也会在模糊的潜意识里变得难以解决。</p>
<p>>> 真正的困难总比想象的要小很多。人们拖延、纠结、畏惧、害怕的根本原因往往不是事情本身有多难,而是内心的想法变得模糊。就像在3 000米跑步考核开始前,那种不知名的恐惧会让人紧张得全身发抖,而我们一旦开跑、不得不与这种恐惧正面交锋时,就会发现3 000米考核也不过如此。如果我们再积极些,学会从一开始就主动正视它、拆解它、看清它,或许那种紧张就不困扰自己了,我们甚至能从容地“享受”比赛。</p>
<p>>> 要想不受其困扰,唯一的办法就是正视它、看清它、拆解它、化解它,不给它进入潜意识的机会,不给它变模糊的机会;即使已经进入潜意识,也要想办法将它挖出来。所以,当你感到心里有说不清、道不明的难受的感觉时,赶紧坐下来,向自己提问。</p>
<p>>> ·到底是什么让自己烦躁不安?是上台演讲、会见某人,还是思绪纷乱?</p>
<p>·具体是什么让自己恐惧担忧?是能力不足、准备不够,还是害怕某事发生?</p>
<p>·面对困境,我能做什么?不能做什么?如果做不到或搞砸了,最坏的结果是什么?</p>
<p>>> 恐惧就是一个欺软怕硬的货色,你躲避它,它就张牙舞爪,你正视它,它就原形毕露。一旦把它看得清清楚楚,情绪就会慢慢从潜意识中消散,你的生活将会舒畅无比。</p>
<p>◆ 第二节 感性:顶级的成长竟然是“凭感觉”</p>
<p>>> 先用感性能力帮助自己选择,再用理性能力帮助自己思考。</p>
<p>>> 那些一眼就能看出答案的题目,不用理它;一眼看过去就头痛、不知道在说什么的题目,也不用理它;只有那种大致能看出点思路,但又要动点脑筋的题目,一定要多做。这个就是中间地带,是你能够进步最快的地方。</p>
<p>>> 只取一个全书最触动自己的点,然后尽可能去实践、改变。这样读书不仅收获更大,而且也不会焦虑。</p>
<p>>> 如果你感受到的总是痛苦和无趣,那十有八九是感觉不对——要么在困难区煎熬,要么在舒适区打转。</p>
<p>>> 我们需要用心去感受什么事情让自己最触动,而不是用脑去思考什么事情最有利。</p>
<p>>> 直视死亡可以简化一切事物</p>
<p>◆ 第三章 元认知——人类的终极能能力</p>
<p>>> 元认知能力就是我们习以为常、见怪不怪的反思能力。</p>
<p>>> 如果说学习和反思是静态的,那处于当下的、动态的自已又该如何主动运用元认知呢?很简单,启用你的“灵魂伴侣”啊!让他时刻监控你,就像电脑系统里的杀毒软件,监控着你的每一次操作,一旦发现可疑文件就立即发出警报。</p>
<p>>> 我们总是这样,一开始只想找一根绳子,最后却牵出一头大象。</p>
<p>>> 这些都是元认知能力不足的表现——顺着自己的本性做喜欢和舒服的事,精力发散,缺乏觉知,任何偶发的干扰都会分散注意力。</p>