-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsearch.xml
345 lines (325 loc) · 105 KB
/
search.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
<?xml version="1.0" encoding="utf-8"?>
<search>
<entry>
<title>Hello,World!</title>
<url>/2022/05/12/21-48-48/</url>
<content><![CDATA[<p> 搭建了一晚上,终于完成了博客的搭建,第一篇总得起个好名字吧。想了很久还是叫做“Hello,World”吧,我想对于每个程序员来说搭载好每一个新环境的测试都会是“Hello,World”。</p>
<p> 从吴军的《浪潮之巅》中得知,“Hello,World”最早诞生于贝尔实验室,你可能对这个实验室的名字感到陌生,新一轮技术革命的核心——集成电路、Linux操作系统的前身Unix、编程始祖且长久未衰的C语言、卫星电话……全部出自贝尔实验室。包括我们熟知的Intel、AMD等芯片巨头都与这家实验室有着千丝万缕的联系。毫不夸张的说,贝尔实验室创造了现代科技的半壁江山。有谁能想到就是一家起初做电话的公司发展到拥有史上最牛实验室的科技帝国,又有谁能想到时至今日那个诞生过13名诺奖得主的实验室已沦落成为一个平平无奇的研究机构,更无人能想到主宰下一个百年的技术在何方……</p>
<p> 这就是这个时代,冷酷,但有情。</p>
<p> “Hello,World”,世界你好,世界很好,世界变得更好!</p>
]]></content>
<categories>
<category>发展</category>
</categories>
<tags>
<tag>《浪潮之巅》</tag>
</tags>
</entry>
<entry>
<title>实验一 进程的建立</title>
<url>/2022/05/12/23-19-37/</url>
<content><![CDATA[<h2 id="进程的建立"><a href="#进程的建立" class="headerlink" title="进程的建立"></a>进程的建立</h2><h4 id="实验内容"><a href="#实验内容" class="headerlink" title="实验内容"></a>实验内容</h4><p> 创建两个进程,让子进程读取一个文件,父进程等待子进程读取 完文件后继续执行,实现进程协同工作。进程协同工作就是协调好两个进程,使之安排好先后次序并以此执行,可以用等待函数来实现这一点。当需要等待子进程运行结束 时,可在父进程中调用等待函数。</p>
<h4 id="实验代码"><a href="#实验代码" class="headerlink" title="实验代码"></a>实验代码</h4><figure class="highlight c"><table><tr><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span><span class="string"><sys/unistd.h></span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span><span class="string"><sys/wait.h></span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><unistd.h></span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span><span class="string"><stdio.h></span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span><span class="string"><stdlib.h></span></span></span><br><span class="line"><span class="type">int</span> <span class="title function_">main</span><span class="params">()</span>{</span><br><span class="line"> <span class="type">pid_t</span> fpid=fork();</span><br><span class="line"> <span class="type">int</span> count=<span class="number">0</span>;</span><br><span class="line"> <span class="keyword">if</span>(fpid<<span class="number">0</span>){</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"error"</span>);</span><br><span class="line">}</span><br><span class="line"><span class="keyword">else</span> <span class="keyword">if</span>(fpid==<span class="number">0</span>){</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"子进程:我是子进程,id=%d,开始读取文件:\n"</span>,getpid());</span><br><span class="line"> FILE *fp=fopen(<span class="string">"test1file.txt"</span>,<span class="string">"r"</span>); <span class="comment">//定义文件流</span></span><br><span class="line"> <span class="keyword">if</span>(fp==<span class="literal">NULL</span>){</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"未找到文件\n"</span>);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">else</span>{</span><br><span class="line"> <span class="type">char</span> text[<span class="number">2000</span>];</span><br><span class="line"> <span class="keyword">while</span> (fgets(text,<span class="number">2000</span>,fp)!=<span class="literal">NULL</span>)</span><br><span class="line"> {</span><br><span class="line"> <span class="built_in">puts</span>(text); <span class="comment">//输出文件内容</span></span><br><span class="line"> }</span><br><span class="line"> </span><br><span class="line"> }</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"子进程:读取文件结束\n"</span>);</span><br><span class="line"> <span class="built_in">exit</span>(<span class="number">1</span>);</span><br><span class="line"> }</span><br><span class="line"><span class="keyword">else</span>{</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"父进程:我是父进程id=%d ,我要等待子进程\n"</span>,getpid());</span><br><span class="line"> </span><br><span class="line"> <span class="type">int</span> ret = waitpid(<span class="number">0</span>,<span class="literal">NULL</span>,<span class="number">0</span>);</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"父进程:子进程 已经结束,ret=%d\n"</span>, ret);</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><span class="line"></span><br></pre></td></tr></table></figure>
<h4 id="程序简要分析"><a href="#程序简要分析" class="headerlink" title="程序简要分析"></a>程序简要分析</h4><p> 该程序主要使用了fork()函数创建了子进程,然后让子进程读取文件并输出文件内容,同时父进程等待子进程的执行,这里用到了waitpid()函数。等待子进程运行完成后,父进程继续运行。</p>
<p>主要函数:pid_t fork(void)</p>
<p> pid_t waitpid(pid_t pid,int * status,int options)</p>
]]></content>
<categories>
<category>操作系统</category>
</categories>
<tags>
<tag>上机实验</tag>
<tag>Linux</tag>
</tags>
</entry>
<entry>
<title>魔王语言解释</title>
<url>/2022/05/13/17-39-53/</url>
<content><![CDATA[<p>问题输入<br>一组数据,数据为一个字符串,表示一个待翻译的字符串。<br>问题输出<br>将字符串按规则翻译后输出。<br>输入样例<br>B(pxyzABhij)B<br>输出样例<br>tsaedsaepjpiphptsaedsaepsaepzpypxptsaedsae</p>
<figure class="highlight c"><table><tr><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span><span class="string"><stdio.h></span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span><span class="string"><stdlib.h></span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span><span class="string"><string.h></span></span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> maxsize 100</span></span><br><span class="line"><span class="keyword">typedef</span> <span class="class"><span class="keyword">struct</span>{</span></span><br><span class="line"> <span class="type">char</span> *base;</span><br><span class="line"> <span class="type">char</span> *top;</span><br><span class="line"> <span class="type">int</span> size; </span><br><span class="line">}sqStack; </span><br><span class="line"><span class="comment">//构造栈</span></span><br><span class="line"><span class="type">int</span> <span class="title function_">InitStack</span><span class="params">(sqStack *S)</span>{</span><br><span class="line"> S->base=(<span class="type">char</span> *)<span class="built_in">malloc</span>(<span class="keyword">sizeof</span>(<span class="type">char</span>)*maxsize);</span><br><span class="line"> <span class="keyword">if</span>(!S->base) <span class="built_in">exit</span>(<span class="number">0</span>);</span><br><span class="line"> S->size=maxsize;</span><br><span class="line"> S->top=S->base;</span><br><span class="line"> <span class="keyword">return</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="type">int</span> <span class="title function_">GetTop</span><span class="params">(sqStack *S,<span class="type">char</span> *c)</span>{</span><br><span class="line"> <span class="keyword">if</span>(S->top==S->base) <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">else</span> *c=*--S->top;</span><br><span class="line"> <span class="keyword">return</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="type">int</span> <span class="title function_">Push</span><span class="params">(sqStack *S,<span class="type">char</span> c)</span>{</span><br><span class="line"> *S->top++=c;</span><br><span class="line"> <span class="keyword">return</span> <span class="number">1</span>;</span><br><span class="line">} </span><br><span class="line"><span class="keyword">typedef</span> <span class="class"><span class="keyword">struct</span> <span class="title">QNode</span> * <span class="title">LNode</span>;</span></span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">QNode</span>{</span></span><br><span class="line"> <span class="type">char</span> data;</span><br><span class="line"> LNode next;</span><br><span class="line">};</span><br><span class="line"><span class="keyword">typedef</span> <span class="class"><span class="keyword">struct</span>{</span></span><br><span class="line"> LNode front; <span class="comment">//队头指针 </span></span><br><span class="line"> LNode rear; <span class="comment">//队尾指针 </span></span><br><span class="line">}LinkQueue;</span><br><span class="line"><span class="comment">//构造队列 </span></span><br><span class="line"><span class="type">int</span> <span class="title function_">InitQueue</span><span class="params">(LinkQueue *Q)</span>{</span><br><span class="line"> Q->front=Q->rear=(LNode)<span class="built_in">malloc</span>(<span class="keyword">sizeof</span>(<span class="keyword">struct</span> QNode));</span><br><span class="line"> Q->front->next=<span class="literal">NULL</span>;</span><br><span class="line"> <span class="keyword">return</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="type">int</span> <span class="title function_">PushQueue</span><span class="params">(LinkQueue *Q,<span class="type">char</span> c)</span>{</span><br><span class="line"> LNode p=(LNode)<span class="built_in">malloc</span>(<span class="keyword">sizeof</span>(<span class="keyword">struct</span> QNode));</span><br><span class="line"> p->data=c;</span><br><span class="line"> p->next=<span class="literal">NULL</span>;</span><br><span class="line"> Q->rear->next=p;</span><br><span class="line"> Q->rear=p;</span><br><span class="line"> <span class="keyword">return</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="type">int</span> <span class="title function_">GetQueue</span><span class="params">(LinkQueue *Q,<span class="type">char</span> *c)</span>{</span><br><span class="line"> <span class="keyword">if</span>(Q->rear==Q->front) <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line"> LNode p=Q->front->next;</span><br><span class="line"> *c=p->data;</span><br><span class="line"> Q->front->next=p->next;</span><br><span class="line"> <span class="keyword">if</span>(Q->rear==p) Q->rear=Q->front;</span><br><span class="line"> <span class="keyword">return</span> <span class="number">1</span>;</span><br><span class="line">} </span><br><span class="line"><span class="type">int</span> <span class="title function_">main</span><span class="params">()</span>{</span><br><span class="line"> <span class="type">char</span> st[<span class="number">1000</span>],a;</span><br><span class="line"> <span class="built_in">scanf</span>(<span class="string">"%s"</span>,st);</span><br><span class="line"> <span class="comment">//puts(st);</span></span><br><span class="line"> sqStack S1,S2;</span><br><span class="line"> LinkQueue L;</span><br><span class="line"> InitQueue(&L);</span><br><span class="line"> InitStack(&S1);</span><br><span class="line"> InitStack(&S2);</span><br><span class="line"> <span class="comment">//将字符串从右向左依次入栈 </span></span><br><span class="line"> <span class="keyword">for</span>(<span class="type">int</span> i=(<span class="built_in">strlen</span>(st)<span class="number">-1</span>);i>=<span class="number">0</span>;i--){</span><br><span class="line"> Push(&S1,st[i]);</span><br><span class="line"> } </span><br><span class="line"> <span class="comment">//处理括号内容 </span></span><br><span class="line"> <span class="keyword">while</span>(S1.base!=S1.top){</span><br><span class="line"> <span class="type">char</span> r;</span><br><span class="line"> GetTop(&S1,&r);</span><br><span class="line"> <span class="keyword">if</span>(r!=<span class="string">')'</span>){</span><br><span class="line"> Push(&S2,r);</span><br><span class="line"> } </span><br><span class="line"> <span class="keyword">else</span> <span class="keyword">if</span>(r==<span class="string">')'</span>){</span><br><span class="line"> <span class="type">char</span> C;</span><br><span class="line"> GetTop(&S2,&a);</span><br><span class="line"> <span class="keyword">while</span>(a!=<span class="string">'('</span>){</span><br><span class="line"> PushQueue(&L,a);</span><br><span class="line"> C=a;</span><br><span class="line"> GetTop(&S2,&a);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">while</span>(L.front->next!=L.rear){</span><br><span class="line"> <span class="type">char</span> b;</span><br><span class="line"> GetQueue(&L,&b);</span><br><span class="line"> Push(&S2,C);</span><br><span class="line"> Push(&S2,b);</span><br><span class="line"> }</span><br><span class="line"> Push(&S2,C);</span><br><span class="line"> }</span><br><span class="line"> </span><br><span class="line"> }</span><br><span class="line"> <span class="comment">//B和A转化</span></span><br><span class="line"> <span class="keyword">while</span>(S2.base!=S2.top){</span><br><span class="line"> <span class="type">char</span> n;</span><br><span class="line"> <span class="type">char</span> A[<span class="number">4</span>]=<span class="string">"sae"</span>;</span><br><span class="line"> <span class="type">char</span> B[<span class="number">9</span>]=<span class="string">"tsaedsae"</span>;</span><br><span class="line"> GetTop(&S2,&n);</span><br><span class="line"> <span class="keyword">if</span>(n!=<span class="string">'A'</span>&&n!=<span class="string">'B'</span>){</span><br><span class="line"> Push(&S1,n);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">else</span> <span class="keyword">if</span>(n==<span class="string">'A'</span>){</span><br><span class="line"> <span class="keyword">for</span>(<span class="type">int</span> i=<span class="number">2</span>;i>=<span class="number">0</span>;i--){</span><br><span class="line"> Push(&S1,A[i]);</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">else</span> <span class="keyword">if</span>(n==<span class="string">'B'</span>){</span><br><span class="line"> <span class="keyword">for</span>(<span class="type">int</span> i=<span class="number">7</span>;i>=<span class="number">0</span>;i--){</span><br><span class="line"> Push(&S1,B[i]);</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> } </span><br><span class="line"> <span class="type">char</span> m;</span><br><span class="line"> <span class="keyword">while</span>(S1.base!=S1.top){</span><br><span class="line"> GetTop(&S1,&m);</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"%c"</span>,m);</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>主要是考察栈和队列,建议画图解决。</p>
]]></content>
<categories>
<category>数据结构</category>
</categories>
<tags>
<tag>C语言</tag>
</tags>
</entry>
<entry>
<title>迷宫问题</title>
<url>/2022/05/13/17-51-40/</url>
<content><![CDATA[<h3 id="问题输入"><a href="#问题输入" class="headerlink" title="问题输入"></a>问题输入</h3><p>一组数据,输入数据第1行为两个正整数m和n,m表示迷宫高度,n表示迷宫宽度,m<100,n<100;第2行为两个整数,分表表示起点的行列位置;第3为两个整数,分别表示终点的行列位置;其后为m行数据,每行n个整数,表示迷宫对应位置的状态,0表示通路,1表示障碍。 </p>
<h3 id="问题输出"><a href="#问题输出" class="headerlink" title="问题输出"></a>问题输出</h3><p>以三元组形式(见P105)输出从起点到终点搜索到的第一条通路,没有则输出no </p>
<h3 id="输入样例"><a href="#输入样例" class="headerlink" title="输入样例"></a>输入样例</h3><p>8 8</p>
<p>1 1</p>
<p>8 8</p>
<p>0 0 1 0 0 0 1 0</p>
<p>0 0 1 1 0 0 1 0 </p>
<p>0 0 0 0 1 1 0 0</p>
<p>0 1 1 1 0 0 0 0</p>
<p>0 0 0 1 1 0 0 0</p>
<p>0 1 0 0 0 1 0 0</p>
<p>0 1 1 1 0 1 1 0</p>
<p>1 1 0 0 0 0 0 0</p>
<h3 id="输出样例"><a href="#输出样例" class="headerlink" title="输出样例"></a>输出样例</h3><p>(1,1,1),(1,2,2),(2,2,2),(3,2,3),(3,1,2),(4,1,2),(5,1,1),(5,2,1),(5,3,2),(6,3,1),(6,4,1),(6,5,2),(7,5,2),(8,5,1),(8,6,1),(8,7,1),(8,8,1) </p>
<figure class="highlight c"><table><tr><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span><span class="string"><stdio.h></span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span><span class="string"><stdlib.h></span></span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> Maxsize 10000</span></span><br><span class="line"><span class="type">int</span> **<span class="built_in">map</span>;</span><br><span class="line"><span class="keyword">typedef</span> <span class="class"><span class="keyword">struct</span>{</span></span><br><span class="line"> <span class="type">int</span> x;</span><br><span class="line"> <span class="type">int</span> y;</span><br><span class="line"> <span class="type">int</span> di;</span><br><span class="line">}seat;</span><br><span class="line"><span class="keyword">typedef</span> <span class="class"><span class="keyword">struct</span>{</span></span><br><span class="line"> seat *base;</span><br><span class="line"> seat *top;</span><br><span class="line"> <span class="type">int</span> size;</span><br><span class="line">}sqStack; </span><br><span class="line"><span class="type">int</span> <span class="title function_">InitStack</span><span class="params">(sqStack *S)</span>{</span><br><span class="line"> S->base=(seat *)<span class="built_in">malloc</span>(<span class="keyword">sizeof</span>(seat)*Maxsize);</span><br><span class="line"> <span class="keyword">if</span>(!S->base) <span class="built_in">exit</span>(<span class="number">0</span>);</span><br><span class="line"> S->size=Maxsize;</span><br><span class="line"> S->top=S->base;</span><br><span class="line"> <span class="keyword">return</span> <span class="number">1</span>;</span><br><span class="line">}</span><br><span class="line"><span class="type">int</span> <span class="title function_">Push</span><span class="params">(sqStack *S,seat a)</span>{</span><br><span class="line"> *S->top++=a;</span><br><span class="line"> <span class="keyword">return</span> <span class="number">1</span>;</span><br><span class="line">}</span><br><span class="line"><span class="type">int</span> <span class="title function_">GetTop</span><span class="params">(sqStack *S,seat *a)</span>{</span><br><span class="line"> <span class="keyword">if</span>(S->base==S->top) <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">else</span> *a=*--S->top;</span><br><span class="line"> <span class="keyword">return</span> <span class="number">1</span>;</span><br><span class="line">}</span><br><span class="line"><span class="type">void</span> <span class="title function_">Map</span><span class="params">(<span class="type">int</span> x,<span class="type">int</span> y)</span>{</span><br><span class="line"> <span class="built_in">map</span>=(<span class="type">int</span> **)<span class="built_in">malloc</span>(<span class="keyword">sizeof</span>(<span class="type">int</span> *)*x);</span><br><span class="line"> <span class="keyword">for</span>(<span class="type">int</span> i=<span class="number">0</span>;i<x;i++){</span><br><span class="line"> <span class="built_in">map</span>[i]=(<span class="type">int</span> *)<span class="built_in">malloc</span>(<span class="keyword">sizeof</span>(<span class="type">int</span>)*y);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">for</span>(<span class="type">int</span> i=<span class="number">0</span>;i<x;i++){</span><br><span class="line"> <span class="built_in">map</span>[i][<span class="number">0</span>]=<span class="number">1</span>;</span><br><span class="line"> <span class="built_in">map</span>[i][y<span class="number">-1</span>]=<span class="number">1</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">for</span>(<span class="type">int</span> j=<span class="number">0</span>;j<y;j++){</span><br><span class="line"> <span class="built_in">map</span>[<span class="number">0</span>][j]=<span class="number">1</span>;</span><br><span class="line"> <span class="built_in">map</span>[x<span class="number">-1</span>][j]=<span class="number">1</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">for</span>(<span class="type">int</span> i=<span class="number">1</span>;i<x<span class="number">-1</span>;i++){</span><br><span class="line"> <span class="keyword">for</span>(<span class="type">int</span> j=<span class="number">1</span>;j<y<span class="number">-1</span>;j++){</span><br><span class="line"> <span class="built_in">scanf</span>(<span class="string">"%d"</span>,&<span class="built_in">map</span>[i][j]);</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> </span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="type">int</span> <span class="title function_">findPath</span><span class="params">(<span class="type">int</span> x1,<span class="type">int</span> y1,<span class="type">int</span> x2,<span class="type">int</span> y2)</span>{</span><br><span class="line"> sqStack q;</span><br><span class="line"> InitStack(&q);</span><br><span class="line"> seat a,b,c;</span><br><span class="line"> <span class="type">int</span> d,m,n,f;</span><br><span class="line"> a.x=x1;</span><br><span class="line"> a.y=y1;</span><br><span class="line"> <span class="built_in">map</span>[x1][y1]=<span class="number">-1</span>;</span><br><span class="line"> a.di=<span class="number">0</span>;</span><br><span class="line"> Push(&q,a);</span><br><span class="line"></span><br><span class="line"> <span class="keyword">while</span>(q.top!=q.base){</span><br><span class="line"> <span class="keyword">if</span>((q.top<span class="number">-1</span>)->x==x2&&(q.top<span class="number">-1</span>)->y==y2) <span class="keyword">break</span>;</span><br><span class="line"> d=(q.top<span class="number">-1</span>)->di;</span><br><span class="line"> f=<span class="number">0</span>;</span><br><span class="line"> <span class="keyword">while</span>(d<=<span class="number">4</span>){</span><br><span class="line"> d++;</span><br><span class="line"> <span class="keyword">switch</span>(d){</span><br><span class="line"> <span class="keyword">case</span> <span class="number">1</span>: m=(q.top<span class="number">-1</span>)->x; n=(q.top<span class="number">-1</span>)->y+<span class="number">1</span>; <span class="keyword">break</span>;</span><br><span class="line"> <span class="keyword">case</span> <span class="number">2</span>: m=(q.top<span class="number">-1</span>)->x+<span class="number">1</span>; n=(q.top<span class="number">-1</span>)->y; <span class="keyword">break</span>;</span><br><span class="line"> <span class="keyword">case</span> <span class="number">3</span>: m=(q.top<span class="number">-1</span>)->x; n=(q.top<span class="number">-1</span>)->y<span class="number">-1</span>; <span class="keyword">break</span>;</span><br><span class="line"> <span class="keyword">case</span> <span class="number">4</span>: m=(q.top<span class="number">-1</span>)->x<span class="number">-1</span>; n=(q.top<span class="number">-1</span>)->y; <span class="keyword">break</span>;</span><br><span class="line"> } </span><br><span class="line"> <span class="keyword">if</span>(<span class="built_in">map</span>[m][n]==<span class="number">0</span>){</span><br><span class="line"> <span class="built_in">map</span>[m][n]=<span class="number">-1</span>;</span><br><span class="line"> (q.top<span class="number">-1</span>)->di=d;</span><br><span class="line"> b.x=m;</span><br><span class="line"> b.y=n;</span><br><span class="line"> b.di=<span class="number">0</span>;</span><br><span class="line"> Push(&q,b);</span><br><span class="line"> f=<span class="number">1</span>;</span><br><span class="line"> <span class="keyword">break</span>;</span><br><span class="line"> }</span><br><span class="line"> </span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span>(f==<span class="number">0</span>){</span><br><span class="line"> GetTop(&q,&c);</span><br><span class="line"> <span class="built_in">map</span>[c.x][c.y]=<span class="number">3</span>;</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span>((q.top<span class="number">-1</span>)->x==x2&&(q.top<span class="number">-1</span>)->y==y2){</span><br><span class="line"> <span class="keyword">for</span>(seat *i=q.base;i<(q.top<span class="number">-1</span>);i++){</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"(%d,%d,%d),"</span>,i->x,i->y,i->di);</span><br><span class="line"> }</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"(%d,%d,%d)"</span>,(q.top<span class="number">-1</span>)->x,(q.top<span class="number">-1</span>)->y,<span class="number">1</span>);</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">else</span> <span class="built_in">printf</span>(<span class="string">"no"</span>);</span><br><span class="line">}</span><br><span class="line"><span class="type">int</span> <span class="title function_">main</span><span class="params">()</span>{</span><br><span class="line"> <span class="type">int</span> X,Y,ax,ay,bx,by;</span><br><span class="line"> <span class="built_in">scanf</span>(<span class="string">"%d %d %d %d %d %d"</span>,&X,&Y,&ax,&ay,&bx,&by);</span><br><span class="line"> Map(X+<span class="number">2</span>,Y+<span class="number">2</span>); <span class="comment">//初始化迷宫,把迷宫四周围上1;</span></span><br><span class="line"> findPath(ax,ay,bx,by);</span><br><span class="line">} </span><br></pre></td></tr></table></figure>
]]></content>
<categories>
<category>数据结构</category>
</categories>
<tags>
<tag>C语言</tag>
</tags>
</entry>
<entry>
<title>Intel时代</title>
<url>/2022/05/13/22-40-51/</url>
<content><![CDATA[<p> 之所以要写Intel,是因为近日计组课涉及了指令集的内容,就忽然想到了《浪潮之巅》中对Intel的介绍。如果你有读过《浪潮之巅》,那么你没有必要浪费时间阅读这篇关于Intel的介绍,因为这篇介绍的大部分内容在这本书中都包含。如果你没有读过,那么也强烈希望你能在读完这篇介绍后阅读一下这本书,尤其是计算机从业者。</p>
<h3 id="历史必然选择"><a href="#历史必然选择" class="headerlink" title="历史必然选择"></a>历史必然选择</h3><p> 1968年摩尔和诺伊斯创办了英特尔公司,就是提出摩尔定律(每18个月集成电路复杂度会翻倍,有机会再细讲)的那个男人。起初的英特尔只是一个小婴儿,因为IBM(当时最大的计算机厂商之一)等计算机制造公司都是自己设计处理器,而英特尔设计的都是一些低端的微型处理器。70年代末,英特尔设计出了处理器8086.</p>
<p> 由于IBM公司当时为了与苹果快速抢占个人计算机(PC)市场,就索性直接采用了英特尔的8086,这一用直接奠定了英特尔的“不可撼动”的地位。原因就是IBM的PC机销售远超预期。之后兼容机(其实就是组装机啦)由于价格低廉也有不错的销量,而这些兼容机毫无疑问必须选择8086处理器和Windows才能实现兼容的目的。所以时至今日,IBM已经不再生产PC,但是英特尔和微软的地位无法撼动。</p>
<p> 再后来,英特尔也走上了高端路线,设计了奔腾系、酷睿系、牙膏系(狗头)……</p>
<h3 id="指令集的战争"><a href="#指令集的战争" class="headerlink" title="指令集的战争"></a>指令集的战争</h3><p> 这部分才是这篇想主要介绍的东西,可以作为课程知识的背景。</p>
<p> 先简要了解一下什么是指令集:就是CPU中用来计算和控制计算机系统的一套指令的集合。再了解一下两大指令集CISC(复杂指令集)和RISC(精简指令集)的区别,来自计组课本:</p>
<ol>
<li><p>指令系统 CISC数量多,复杂;RISC数量少,精简。</p>
</li>
<li><p>使用频率 CISC相差大;RISC 接近。毕竟RISC就是选取了使用频率高的指令。</p>
</li>
<li><p>CUP功耗 CISC高;RISC低。</p>
<p>……</p>
</li>
</ol>
<p> 简单对比后就算你不知道什么是指令集你也一定会说RISC比较好。那么恭喜你和当时众多学者想法一样,未来将是RISC的天下。<br> 于是一大堆企业转战RISC,其中包括一些原本只是采购而自己不研发的企业开始自己研发RISC处理器,谁都想在风口上飞起来。英特尔也感受到了危机,但是做出了最正确的选择。英特尔继续坚持自己在基于CISC指令集的CPU上的领先地位,又开始着手RISC指令。之后英特尔开发出来几款RISC产品,但是都不成功。而RISC派这边,基本处于各自为战的状态,群龙无首,做出的机器兼容性可想而知。虽然RISC具有天然的性能优势,但是英特尔已经将自己的CISC优化的非常不错,但是绝大部分消费者在稳定兼容和性能稍稍领先上选择前者。<br> 这里还有一个小故事,在RISC提出之前。有一家企业可以和英特尔抗衡——摩托罗拉。当时IBM选择了英特尔,而苹果选择了摩托罗拉。但是RISC指令提出后由于摩托罗拉做出了错误的决定再加上管理层问题,丢失了以前的大部分订单,基本上放弃了CISC转战RISC,直到最后一棵稻草苹果也放弃它。<br> 虽然那个年代的指令集之争英特尔大获全胜,但是新世纪以来,由于智能手机的快速发展,基于ARM架构(采用RISC指令集)的手机处理器也换代发展迅速。当某一架构的硬件性能达到极限时,只能尝试改变,于是最近英特尔也正在进军RISC-V,毕竟RISC具有天然性能优势。</p>
<h3 id="芯片帝国"><a href="#芯片帝国" class="headerlink" title="芯片帝国"></a>芯片帝国</h3><p> 英特尔毫无疑问已经发展成为了一个芯片帝国,世界上超一半计算机都在采用英特尔芯片。它的成功离不开决策、时机、运气。英特尔历史上唯一的错误决定就是看轻了智能手机时代,将手机芯片拱手相让,错失了一次绝佳良机。现在好似又出现一家看似能和英特尔较量的公司——AMD。但是两者其实根本不在一个水平上,AMD为了抢占英特尔市场也只能跟在英特尔身后做出兼容芯片,起码我们消费者又多了一个非常不错的选择。</p>
<p> </p>
]]></content>
<categories>
<category>发展</category>
</categories>
<tags>
<tag>《浪潮之巅》</tag>
</tags>
</entry>
<entry>
<title>程序员天花板——雷军</title>
<url>/2022/05/20/19-46-53/</url>
<content><![CDATA[<p> 数码圈流传着这样一句话:“你可以不喜欢小米,但是你没有理由不钦佩雷军”。这位每次出现在大众视野基本都是穿着牛仔裤和衬衫标准”程序员“搭配的”雷布斯“,不仅担任着数家上市公司董事长,还是一位极具前瞻性的天使投资人,已经成为程序员天花板。</p>
<h3 id="“有人说我写的代码-如诗一样优雅”"><a href="#“有人说我写的代码-如诗一样优雅”" class="headerlink" title="“有人说我写的代码 如诗一样优雅”"></a>“有人说我写的代码 如诗一样优雅”</h3><p> 这句话是雷军在一段访谈中对自己的称赞,作为程序员出身的雷军对自己的编程能力还是蛮自信的,事实究竟如何?有人扒出了一段雷军在1994年写的一段完整的汇编代码贴在了网上,无数网友回复”跪着读完“。这一段高质量的代码就算在今天也少有人能写的出来。</p>
<p> 1987年雷军进入武汉大学计算机系,他仅使用了两年的时间完成了所有大学内容和毕业设计。大学期间写过的很多代码早已被编入武汉大学的教材……在大学期间他就开始写软件出售来赚取利润。大四那年他开始了人生的第一次创业,仿制金山汉卡。然而他的第一次创业以失败告终,破产清算时仅仅获得了一台电脑。别急,传奇才刚刚开始。</p>
<h3 id="扛起中国软件的大旗——金山"><a href="#扛起中国软件的大旗——金山" class="headerlink" title="扛起中国软件的大旗——金山"></a>扛起中国软件的大旗——金山</h3><p> 谁也没想到,最初靠仿制金山赚钱的雷军一眼被“中国第一程序员”——求伯君看中,力邀他加入金山,几年的时间内,雷军就从一个新员工成为了金山总裁。当时金山面临的最大对手就是微软,微软的office利用与操作系统捆绑的优势成为后起之秀,抢占了WPS的大部分市场。雷军年少轻狂,带领团队做出了新一代产品”盘古“,里面融合了文字处理、词典、事务管理等多种功能,本想凭借这一产品重回巅峰,但惨淡的销售量给了雷军闷头一棒。</p>
<p> 这一盆冷水浇得雷军醒不过来,最后他递交了辞职信。但是求伯君极力挽留,只给他休假。半年后,雷军重回岗位,他这次回来显然已经制定好了转型战略,之后新版WPS强势上场,在微软的歼灭战中夹缝生存,重新赢得了不少的市场占有率。</p>
<p> 直到2007年,金山上市,雷军为这一刻付出了十几年的心血。金山无疑是中国软件的一面旗帜,在遭遇国外产品不公平竞争的时刻依旧逆势而上,并且获得了不菲的成绩!</p>
<h3 id="“所有产品不超过5-的利润”——小米"><a href="#“所有产品不超过5-的利润”——小米" class="headerlink" title="“所有产品不超过5%的利润”——小米"></a>“所有产品不超过5%的利润”——小米</h3><p> 就在金山上市后两个月,雷军宣布离职,这让很多人不能理解。接下来的时间,雷军开始专注自己的投资事业,同时,雷军似乎拥有感应商业机会的本能,他在等待拥抱一个全新时代的到来——移动互联时代。</p>
<p> 在iPhone开始风靡全球的同时,他在思考安卓的开放性是不是更具有可玩性。他找到投资人、“同盟者”,向他们描述他大胆的想法。2010年四月,在北京一家小工作室里,十几个人喝了一锅小米粥,小米诞生。</p>
<p> 2011年,小米第一部手机发布,豪华的配置,1999的价格,赢得了一众好评,出现了一机难求的场面。2013年,红米首款手机发布,以极低的价格终结了山寨机泛滥的市场。</p>
<p> 2019年,小米成为了世界最年轻的500强,并且具有了完整的生态链体系。</p>
<p> 如今,雷军已经开启了自己人生的最后一次伟大创业——小米汽车,我们无法预测结果如何,但可以肯定的是雷军早已成为中国科技界的“传奇”!这位向往纯粹技术的工程师在为实现“科技走进千家万户”而努力。</p>
<h4 id="因为简单纯粹,所以无所畏惧;因为无所畏惧,所以一往无前!——范海涛"><a href="#因为简单纯粹,所以无所畏惧;因为无所畏惧,所以一往无前!——范海涛" class="headerlink" title="因为简单纯粹,所以无所畏惧;因为无所畏惧,所以一往无前!——范海涛"></a>因为简单纯粹,所以无所畏惧;因为无所畏惧,所以一往无前!——范海涛</h4><p> </p>
<p> </p>
]]></content>
<categories>
<category>发展</category>
</categories>
<tags>
<tag>《浪潮之巅》</tag>
</tags>
</entry>
<entry>
<title>实验六 信号量实现进程同步</title>
<url>/2022/08/28/11-08-08/</url>
<content><![CDATA[<h2 id="信号量实现进程同步"><a href="#信号量实现进程同步" class="headerlink" title="信号量实现进程同步"></a>信号量实现进程同步</h2><h5 id="【实验目的】"><a href="#【实验目的】" class="headerlink" title="【实验目的】"></a>【实验目的】</h5><p> 进程同步是操作系统多进程/多线程并发执行的关键之一,进程 同步是并发进程为了完成共同任务采用某个条件来协调他们的活 动,这是进程之间发生的一种直接制约关系。本次试验是利用信号量进行进程同步。</p>
<h5 id="【实验软硬件环境】"><a href="#【实验软硬件环境】" class="headerlink" title="【实验软硬件环境】"></a>【实验软硬件环境】</h5><p> Linux,gcc</p>
<h5 id="【实验内容】"><a href="#【实验内容】" class="headerlink" title="【实验内容】"></a>【实验内容】</h5><p>生产者进程生产产品,消费者进程消费产品。当生产者进程生产产品时,如果没有空缓冲区可用,那么生产者进程必须等待消费者进程释放出一个缓冲区。当消费者进程消费产品时,如果缓冲区中没有产品,那么消费 者进程将被阻塞,直到新的产品被生产出来。</p>
<h5 id="【实验程序及分析】"><a href="#【实验程序及分析】" class="headerlink" title="【实验程序及分析】"></a>【实验程序及分析】</h5><figure class="highlight c"><table><tr><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><sys/mman.h></span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><sys/types.h></span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><sys/sem.h></span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><fcntl.h></span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><unistd.h></span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><stdio.h></span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><errno.h></span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><time.h></span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><stdlib.h></span></span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> MAXSEM 5</span></span><br><span class="line"><span class="class"><span class="keyword">union</span> <span class="title">semun</span></span></span><br><span class="line"><span class="class">{</span></span><br><span class="line"> <span class="type">int</span> val;</span><br><span class="line"> <span class="class"><span class="keyword">struct</span> <span class="title">semid_ds</span> *<span class="title">buf</span>;</span></span><br><span class="line"> <span class="type">unsigned</span> <span class="type">short</span> *<span class="built_in">array</span>;</span><br><span class="line">};</span><br><span class="line"><span class="type">int</span> fullid, emptyid,mutxid; <span class="comment">//f 已有产品量 e 空余量</span></span><br><span class="line"><span class="type">int</span> <span class="title function_">main</span><span class="params">()</span>{</span><br><span class="line"> <span class="class"><span class="keyword">struct</span> <span class="title">sembuf</span> <span class="title">P</span>,<span class="title">V</span>;</span></span><br><span class="line"> <span class="class"><span class="keyword">union</span> <span class="title">semun</span> <span class="title">arg</span>;</span></span><br><span class="line"> <span class="comment">//声明共享主存array, sum, get, set</span></span><br><span class="line"> <span class="type">int</span> *<span class="built_in">array</span>;</span><br><span class="line"> <span class="type">int</span> *sum;</span><br><span class="line"> <span class="type">int</span> *get;</span><br><span class="line"> <span class="type">int</span> *<span class="built_in">set</span>;</span><br><span class="line"> <span class="comment">//将array,sum,set,get映射到共享主存</span></span><br><span class="line"> <span class="built_in">array</span> =(<span class="type">int</span> *)mmap(<span class="literal">NULL</span>,<span class="keyword">sizeof</span>(<span class="type">int</span>)*MAXSEM,PROT_READ|PROT_WRITE,MAP_SHARED|MAP_ANONYMOUS,<span class="number">-1</span>,<span class="number">0</span>);</span><br><span class="line"> sum=(<span class="type">int</span> *)mmap(<span class="literal">NULL</span>,<span class="keyword">sizeof</span>(<span class="type">int</span>),PROT_READ|PROT_WRITE,MAP_SHARED|MAP_ANONYMOUS,<span class="number">-1</span>,<span class="number">0</span>); </span><br><span class="line"> <span class="built_in">set</span>=(<span class="type">int</span> *)mmap(<span class="literal">NULL</span>,<span class="keyword">sizeof</span>(<span class="type">int</span>),PROT_READ|PROT_WRITE,MAP_SHARED|MAP_ANONYMOUS,<span class="number">-1</span>,<span class="number">0</span>);</span><br><span class="line"> get=(<span class="type">int</span> *)mmap(<span class="literal">NULL</span>,<span class="keyword">sizeof</span>(<span class="type">int</span>),PROT_READ|PROT_WRITE,MAP_SHARED|MAP_ANONYMOUS,<span class="number">-1</span>,<span class="number">0</span>);</span><br><span class="line"> <span class="comment">//创建信号量fullid, emptyid,mutxid</span></span><br><span class="line"> fullid=semget(IPC_PRIVATE,<span class="number">1</span>,IPC_CREAT|<span class="number">0666</span>);</span><br><span class="line"> emptyid=semget(IPC_PRIVATE,<span class="number">1</span>,IPC_CREAT|<span class="number">0666</span>);</span><br><span class="line"> mutxid=semget(IPC_PRIVATE,<span class="number">1</span>,IPC_CREAT|<span class="number">0666</span>);</span><br><span class="line"> <span class="comment">//初始化信号量</span></span><br><span class="line"> arg.val=<span class="number">0</span>;</span><br><span class="line"> <span class="keyword">if</span>(semctl(fullid,<span class="number">0</span>,SETVAL,arg)==<span class="number">-1</span>)perror(<span class="string">"semctl setval error"</span>);</span><br><span class="line"> arg.val=MAXSEM;</span><br><span class="line"> <span class="keyword">if</span>(semctl(emptyid,<span class="number">0</span>,SETVAL,arg)==<span class="number">-1</span>)perror(<span class="string">"semctl setval error"</span>);</span><br><span class="line"> arg.val=<span class="number">1</span>;</span><br><span class="line"> <span class="keyword">if</span>(semctl(mutxid,<span class="number">0</span>,SETVAL,arg)==<span class="number">-1</span>)perror(<span class="string">"semctl setval error"</span>);</span><br><span class="line"> <span class="comment">//初始化P,V操作</span></span><br><span class="line"> V.sem_num=<span class="number">0</span>;</span><br><span class="line"> V.sem_op=<span class="number">1</span>;</span><br><span class="line"> V.sem_flg=SEM_UNDO;</span><br><span class="line"> P.sem_num=<span class="number">0</span>;</span><br><span class="line"> P.sem_op=<span class="number">-1</span>;</span><br><span class="line"> P.sem_flg=SEM_UNDO;</span><br><span class="line"> <span class="comment">//创建生产者进程</span></span><br><span class="line"> <span class="type">pid_t</span> fpid1=fork();</span><br><span class="line"> <span class="keyword">if</span>(fpid1==<span class="number">0</span>){</span><br><span class="line"> <span class="type">int</span> i=<span class="number">0</span>;</span><br><span class="line"> <span class="keyword">while</span>(i<<span class="number">100</span>){</span><br><span class="line"> <span class="comment">//对emptyid ,mutxid执行P操作</span></span><br><span class="line"> semop(emptyid,&P,<span class="number">1</span>);</span><br><span class="line"> semop(mutxid,&P,<span class="number">1</span>);</span><br><span class="line"> <span class="built_in">array</span>[*(<span class="built_in">set</span>)%MAXSEM] = i+<span class="number">1</span>; <span class="comment">//生产产品</span></span><br><span class="line"> (*<span class="built_in">set</span>)++;</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"produce %d\n"</span>,i+<span class="number">1</span>);</span><br><span class="line"><span class="comment">//对emptyid, mutxid执行V操作</span></span><br><span class="line"> semop(mutxid,&V,<span class="number">1</span>);</span><br><span class="line"> semop(fullid,&V,<span class="number">1</span>);</span><br><span class="line"> i++;</span><br><span class="line">} </span><br><span class="line"><span class="comment">//休眠一段时间</span></span><br><span class="line"> sleep(<span class="number">1</span>);</span><br><span class="line"><span class="comment">//打印生产者结束</span></span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"producer is over\n"</span>);</span><br><span class="line"> <span class="built_in">exit</span>(<span class="number">0</span>);</span><br><span class="line"> }<span class="keyword">else</span>{</span><br><span class="line"> <span class="comment">//创建消费者进程</span></span><br><span class="line"> <span class="type">pid_t</span> fpid2=fork();</span><br><span class="line"> <span class="keyword">if</span>(fpid2==<span class="number">0</span>){</span><br><span class="line"> <span class="comment">//消费者进程A</span></span><br><span class="line"> <span class="keyword">while</span>(<span class="number">1</span>){</span><br><span class="line"> <span class="comment">//对fuild, mutxid执行P操作</span></span><br><span class="line"> semop(fullid,&P,<span class="number">1</span>);</span><br><span class="line"> semop(mutxid,&P,<span class="number">1</span>);</span><br><span class="line"> <span class="keyword">if</span>(*get == <span class="number">100</span>)</span><br><span class="line"> <span class="keyword">break</span>;</span><br><span class="line"> *sum += <span class="built_in">array</span>[(*get)%MAXSEM];</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"the comsumer A get number %d\n"</span>, <span class="built_in">array</span>[(*get)%MAXSEM]);</span><br><span class="line"> (*get) ++;</span><br><span class="line"> <span class="keyword">if</span>(*get == <span class="number">100</span>)</span><br><span class="line"> {<span class="built_in">printf</span>(<span class="string">"the sum is %d\n"</span>, *sum);</span><br><span class="line"> <span class="keyword">break</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="comment">//对emptyid, mutxid执行V操作</span></span><br><span class="line"> semop(mutxid,&V,<span class="number">1</span>);</span><br><span class="line"> semop(emptyid,&V,<span class="number">1</span>);</span><br><span class="line"> sleep(<span class="number">0.5</span>);</span><br><span class="line"> } </span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"consumer A is over\n"</span>);</span><br><span class="line"> <span class="built_in">exit</span>(<span class="number">0</span>);</span><br><span class="line"> }<span class="keyword">else</span>{</span><br><span class="line"> <span class="comment">//消费者进程B</span></span><br><span class="line"> <span class="keyword">while</span>(<span class="number">1</span>){</span><br><span class="line"> <span class="comment">//对fuild, mutxid执行P操作</span></span><br><span class="line"> semop(fullid,&P,<span class="number">1</span>);</span><br><span class="line"> semop(mutxid,&P,<span class="number">1</span>);</span><br><span class="line"> <span class="keyword">if</span>(*get == <span class="number">100</span>)</span><br><span class="line"> <span class="keyword">break</span>;</span><br><span class="line"> *sum += <span class="built_in">array</span>[(*get)%MAXSEM];</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"the comsumer B get number %d\n"</span>, <span class="built_in">array</span>[(*get)%MAXSEM]);</span><br><span class="line"> (*get) ++;</span><br><span class="line"> <span class="keyword">if</span>(*get == <span class="number">100</span>)</span><br><span class="line"> {<span class="built_in">printf</span>(<span class="string">"the sum is %d\n"</span>, *sum);</span><br><span class="line"> <span class="keyword">break</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="comment">//对emptyid, mutxid执行V操作</span></span><br><span class="line"> semop(mutxid,&V,<span class="number">1</span>);</span><br><span class="line"> semop(emptyid,&V,<span class="number">1</span>);</span><br><span class="line"> sleep(<span class="number">0.5</span>);</span><br><span class="line"> }</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"consumer B is over\n"</span>);</span><br><span class="line"> <span class="built_in">exit</span>(<span class="number">0</span>);</span><br><span class="line"> }</span><br><span class="line"> </span><br><span class="line"> }</span><br><span class="line"> </span><br><span class="line">}</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<h5 id="【程序分析】:"><a href="#【程序分析】:" class="headerlink" title="【程序分析】:"></a>【程序分析】:</h5><p>本次实验创建了一个生产者进程和两个消费者进程,主要是通过共享内存机制通过进行PV操作完成,设置了信号量fullid, emptyid,mutxid来实现对生产者,消费者的操作。生产者总共需要生产100个产品,消费者取出产品并进行输出产品编号。</p>
]]></content>
<categories>
<category>操作系统</category>
</categories>
<tags>
<tag>上机实验</tag>
<tag>Linux</tag>
</tags>
</entry>
<entry>
<title>JavaWeb QQZone项目架构总结</title>
<url>/2022/08/28/21-58-21/</url>
<content><![CDATA[<p>这是学习JavaWeb过程中和以往相比做的比较复杂的小项目,是通过tymeleaf进行渲染的B/S(浏览器/服务器)小项目,课程链接:<a href="https://www.bilibili.com/video/BV1AS4y177xJ?p=1">尚硅谷丨2022版JavaWeb教程(全新技术栈,全程实战)</a>,尚硅谷,yyds!!!<br>由于不想花过多的时间在前端上,所以HTML/CSS/JavaScript页面模板大多直接使用的课程资料,就自己模仿着做了一个添加日志和注册的页面。听视频介绍这个项目的主要目的就是手撕简约版Spring MVC框架,为了后面学习框架相对轻松一点。第一次实现了数据库、后台程序、前端页面的交互,还是很有意思,所以写下来理清自己的思路,为了自己更好的理解,也欢迎大家纠错更正。</p>
<h2 id="一、开发环境:"><a href="#一、开发环境:" class="headerlink" title="一、开发环境:"></a>一、开发环境:</h2><p>jdk8+MySQL8+tomcat8.5(课程中用的数据库是MySQL5,由于版本不同有些细节不同也耽误了不少时间,下面会提到)</p>
<h2 id="二、流程图:"><a href="#二、流程图:" class="headerlink" title="二、流程图:"></a>二、流程图:</h2><p><img src="https://img-blog.csdnimg.cn/0f92b0bf7a334e19b558dd11a9016fcb.png#pic_center" alt="在这里插入图片描述"></p>
<h2 id="三、主要模块"><a href="#三、主要模块" class="headerlink" title="三、主要模块"></a>三、主要模块</h2><h3 id="监听器和IOC容器:"><a href="#监听器和IOC容器:" class="headerlink" title="监听器和IOC容器:"></a>监听器和IOC容器:</h3><p>一旦监听到服务器启动,开始调用BeanFactory创建容器,通过读取配置文件中的标签内容,将后续的Controller类、Service类、DAO类实例化保存。并且建立依赖关系,比如说操作日志相关内容的控制器TopicController里面用到了TopicService,那么直接将刚刚实例化的TopicService赋值到TopicController中,这就是“控制反转”和“依赖注入”。以往我们写程序,一个对象里面需要另一个对象我们就让前者自己直接new出来,但是这样会导致对象依赖和耦合严重,不利于代码维护。为了实现“高内聚,低耦合”的架构,我们现在把创建对象的权利全部交给第三方,即“控制反转”,然后再通过配置文件中的信息进行“依赖注入”,达到解除耦合的目的。</p>
<h3 id="DispatcherServlet"><a href="#DispatcherServlet" class="headerlink" title="DispatcherServlet:"></a>DispatcherServlet:</h3><p>作为核心响应调度,它的工作是拦截获取到浏览器的(A.do?opetate=B)请求,通过字符串处理,在IOC容器中查找到处理该A请求的指定Controller类,再通过反射找到B方法,进行方法参数赋值调用方法。</p>
<p>把MVC中的V即“view‘也放在dispatcherServlet中,控制器进行操作后需要给dispatcherServlet返回一个字符串,dispatcherServlet通过该字符串判断下一步工作,是继续调用其他控制器,还是直接返回页面给浏览器。</p>
<h3 id="Controller、Service、DAO:"><a href="#Controller、Service、DAO:" class="headerlink" title="Controller、Service、DAO:"></a>Controller、Service、DAO:</h3><p>Controller作为控制器提供一些方法供浏览器选择,比如说浏览器端需要执行日志(Topic)添加工作,那需要调用TopicController中的addTopic()方法,再比如需要执行登录操作,当用户点击“登录”按键时浏览器就调用了UserBasicController(UserBasic是用户信息类,登录时需要查询用户信息,所以调用它的Controller)中的login方法。Service就是业务方法,比如说Controller现在整理好了浏览器发来的日志添加内容,需要保存到数据库了,它就调用相应的Service方法,Service再看看有什么需要封装整理的,然后再调用DAO方法,至于DAO就是JDBC中的内容,应该很熟悉了。</p>
<h2 id="四、遇到的主要问题"><a href="#四、遇到的主要问题" class="headerlink" title="四、遇到的主要问题"></a>四、遇到的主要问题</h2><h4 id="1、项目关联包问题"><a href="#1、项目关联包问题" class="headerlink" title="1、项目关联包问题"></a>1、项目关联包问题</h4><p>异常:java.lang.IllegalStateException: 启动子级时出错</p>
<p>注意操作顺序!一定要先关联上lib下的各种驱动包、添加上tomcat、然后再打包成Artifacts进行部署。刚开始就遇到了找不到MySQL驱动器的问题,原因是将新建的项目一开始就打包成了Artifacts,然后再关联,这样的话Artifacts进行部署时里面当然没有我们关联的驱动。出现这样的问题解决很简单,不需要你删除Artifacts后再添加,只需要Project Structer下面的problems就可以解决。</p>
<h4 id="2、类加载器问题"><a href="#2、类加载器问题" class="headerlink" title="2、类加载器问题"></a>2、类加载器问题</h4><p>异常:java.lang.NullPointerException<br> at java.util.Properties$LineReader.readLine(Properties.java:434)<br> at java.util.Properties.load0(Properties.java:353)<br> at java.util.Properties.load(Properties.java:341)</p>
<p>这个问题我解决了好久,抛出的异常就是在获取数据库链接的时候无法读到你的properties配置文件,无法获取链接。就是这一句出了问题:InputStream stream=ClassLoader.getSystemClassLoader().getResourceAsStream(“jdbc.properties”);</p>
<p>于是我做了个单元测试,在idea里面明明可以获取链接,但是到tomcat服务器上就不行。然后我在评论区下发现了一个留言,需要改成:InputStream stream =JDBCUtils.class.getClassLoader().getResourceAsStream(“jdbc.properties”),我一试果然成功,为什么出现这样的情况呢,说到底是路径问题:</p>
<p>你可以尝试在idea下和在tomcat环境下分别执行以上两句,你会发现在idea下两个得到的路径是相同的,都是当前项目的src下:</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">System.out.println(JDBCUtils.class.getClassLoader().getResource(<span class="string">""</span>));</span><br><span class="line">System.out.println(ClassLoader.getSystemClassLoader().getResource(<span class="string">""</span>));</span><br></pre></td></tr></table></figure>
<p><img src="https://img-blog.csdnimg.cn/03615e06056d4441bbbc2d0ccd33dd0f.png#pic_center" alt="在这里插入图片描述"><br>但是同样的代码在tomcat调用时:<br><img src="https://img-blog.csdnimg.cn/43bdac75548147a9a3e7ad63d4bebf91.png#pic_center" alt="在这里插入图片描述"></p>
<p>会发现InputStream stream =JDBCUtils.class.getClassLoader().getResourceAsStream(“jdbc.properties”) 调用的路径是artifacts打包后的“src”目录,是正确的。而InputStream stream=ClassLoader.getSystemClassLoader().getResourceAsStream(“jdbc.properties”);得到的是null。</p>
<h4 id="3、LocalDateTime类转化问题"><a href="#3、LocalDateTime类转化问题" class="headerlink" title="3、LocalDateTime类转化问题"></a>3、LocalDateTime类转化问题</h4><p>异常:java.lang.IllegalArgumentException: Can not set java.util.Date field com.guoliang.qqzone.pojo.Topic.topicDate to java.time.LocalDateTime</p>
<p>当调用DAO时一旦发现异常can not set A to B,就是你不能把B类型赋值给A。</p>
<p>视频中老师讲的时候是没有这个问题的,因为老师用的是MySQL5,这个问题应该是MySQL8驱动引入的。该项目数据库中的Date全部是DateTime,对应的Java中是LocalDateTime或者TimeStamp,而我们Java中设定的全部是Date。</p>
<p>解决方法:1、将pojo类中的Date全部转化为LocalDateTime</p>
<p> 2、BaseDAO中加上以下代码进行转化</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="comment">//LocalDateTime需要转化</span></span><br><span class="line"> <span class="keyword">if</span> (propertyValue.getClass().toString().equals(<span class="string">"class java.time.LocalDateTime"</span>)) {</span><br><span class="line"> propertyValue = Timestamp.valueOf((LocalDateTime) propertyValue);</span><br><span class="line"> }</span><br></pre></td></tr></table></figure>
<h4 id="4、tymeleaf渲染问题"><a href="#4、tymeleaf渲染问题" class="headerlink" title="4、tymeleaf渲染问题"></a>4、tymeleaf渲染问题</h4><p>写好的前端页面展示出来发现与我们所想不一样,这个问题老师也遇到了,再上一个项目中老师一直没有发现,但是这个项目老师成功解决了这个问题。问题根源在于既然使用了tymeleaf,你就不能直接调用网页,必须经过DispactureServlet中的视图模块进行调用渲染,否则你页面上的所有“th:”都无法识别。</p>
<h2 id="六、部分结果展示:"><a href="#六、部分结果展示:" class="headerlink" title="六、部分结果展示:"></a>六、部分结果展示:</h2><p><img src="https://img-blog.csdnimg.cn/578830b8768e4587984ac241200b909b.png#pic_center" alt="登录"><br><img src="https://img-blog.csdnimg.cn/65a6f68cbe8f4e43a2beed5ff4b3bb94.png#pic_center" alt="主页面"><br><img src="https://img-blog.csdnimg.cn/1ec1501953a745419a283053899c3f23.png#pic_center" alt="回复"><br><img src="https://img-blog.csdnimg.cn/f2f6a93c0e3045a9a556fd1d1055301d.png#pic_center" alt="添加日志"></p>
]]></content>
<categories>
<category>Java</category>
</categories>
<tags>
<tag>JavaWeb</tag>
</tags>
</entry>
<entry>
<title>基于SSM的CRUD项目准备工作</title>
<url>/2022/10/04/15-26-41/</url>
<content><![CDATA[<h1 id="基于SSM的CRUD项目准备工作"><a href="#基于SSM的CRUD项目准备工作" class="headerlink" title="基于SSM的CRUD项目准备工作"></a>基于SSM的CRUD项目准备工作</h1><p> 该项目是基于SSM的增删改查项目,前端淘汰了过时的jsp技术,通过Bootstrap+vue+Thymeleaf实现。<a href="https://download.csdn.net/download/weixin_51342637/86734403">完整项目下载链接</a></p>
<h2 id="一、SSM文件配置"><a href="#一、SSM文件配置" class="headerlink" title="一、SSM文件配置"></a>一、SSM文件配置</h2><h4 id="1、web-xml"><a href="#1、web-xml" class="headerlink" title="1、web.xml"></a>1、web.xml</h4><ul>
<li>编码过滤器和处理请求方式过滤器</li>
<li>DispatcherServlet前端控制器(要引入SpringMVC.xml配置文件路径)</li>
<li>引入Spring配置文件路径</li>
<li>Spring监听器ContextConfigLocation</li>
</ul>
<h4 id="2、SpringMVC-xml"><a href="#2、SpringMVC-xml" class="headerlink" title="2、SpringMVC.xml"></a>2、SpringMVC.xml</h4><ul>
<li>扫描控制层组件</li>
<li>视图解析器Thymeleaf</li>
<li>配置默认Servlet处理静态资源</li>
<li>开启MVC注解驱动</li>
<li>配置视图控制器</li>
</ul>
<h4 id="3、Spring-xml"><a href="#3、Spring-xml" class="headerlink" title="3、Spring.xml"></a>3、Spring.xml</h4><ul>
<li>扫描除控制层以外组件</li>
<li>配置数据源(先引用数据库配置文件)</li>
<li>配置SqlSessionFactoryBean</li>
<li>配置mapper接口的扫描</li>
</ul>
<h2 id="二、创建数据表使用逆向工程"><a href="#二、创建数据表使用逆向工程" class="headerlink" title="二、创建数据表使用逆向工程"></a>二、创建数据表使用逆向工程</h2><h4 id="1、创建数据表"><a href="#1、创建数据表" class="headerlink" title="1、创建数据表"></a>1、创建数据表</h4><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">CREATE TABLE `tbl_stu` (</span><br><span class="line"> `stu_id` int NOT NULL AUTO_INCREMENT,</span><br><span class="line"> `stu_name` varchar(2295) DEFAULT NULL,</span><br><span class="line"> `gender` char(9) DEFAULT NULL,</span><br><span class="line"> `email` varchar(2295) DEFAULT NULL,</span><br><span class="line"> `d_id` int DEFAULT NULL,</span><br><span class="line"> PRIMARY KEY (`stu_id`)</span><br><span class="line">)</span><br><span class="line">CREATE TABLE `tbl_dept` (</span><br><span class="line"> `dept_id` int NOT NULL AUTO_INCREMENT,</span><br><span class="line"> `dept_name` varchar(765) DEFAULT NULL,</span><br><span class="line"> PRIMARY KEY (`dept_id`)</span><br><span class="line">)</span><br></pre></td></tr></table></figure>
<h4 id="2、完成逆向工程,更改生成的mapper"><a href="#2、完成逆向工程,更改生成的mapper" class="headerlink" title="2、完成逆向工程,更改生成的mapper"></a>2、完成逆向工程,更改生成的mapper</h4><p> 先完成generatorConfig.xml文件的配置,再使用逆向工程插件生成数据表对应的Pojo、Mapper和sql接口映射文件。因为自动生成的查询学生只能得到他所在的部门id,我们想让每次查询都能直接得到对应的部门信息,所以需要对自动生成的类进行一些修改,步骤如下:</p>
<ul>
<li>Student类中添加Department属性</li>
</ul>
<ul>
<li><p>原mapper接口中有方法</p>
<pre><code><figure class="highlight java"><table><tr><td class="code"><pre><span class="line">List<Student> <span class="title function_">selectByExample</span><span class="params">(StudentExample example)</span>;</span><br><span class="line">Student <span class="title function_">selectByPrimaryKey</span><span class="params">(Integer stuId)</span>;</span><br></pre></td></tr></table></figure>
</code></pre>
</li>
</ul>
<p> 我们再添加两个:</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"> List<Student> <span class="title function_">selectByExampleWithDept</span><span class="params">(StudentExample example)</span>;</span><br><span class="line">Student <span class="title function_">selectByPrimaryKeyWithDept</span><span class="params">(Integer stuId)</span>;</span><br></pre></td></tr></table></figure>
<ul>
<li>StudentMapper.xml中进行修改,其实都是复制原有自动生成的,再进行稍微修改实现分步查询。</li>
</ul>
<figure class="highlight xml"><table><tr><td class="code"><pre><span class="line"> <span class="comment"><!--带上部门后的resultMap--></span></span><br><span class="line"> <span class="tag"><<span class="name">resultMap</span> <span class="attr">id</span>=<span class="string">"BaseResultMapWithDept"</span> <span class="attr">type</span>=<span class="string">"com.guoliang.ssm.pojo.Student"</span> ></span></span><br><span class="line"> <span class="tag"><<span class="name">id</span> <span class="attr">column</span>=<span class="string">"stu_id"</span> <span class="attr">property</span>=<span class="string">"stuId"</span> <span class="attr">jdbcType</span>=<span class="string">"INTEGER"</span> /></span></span><br><span class="line"> <span class="tag"><<span class="name">result</span> <span class="attr">column</span>=<span class="string">"stu_name"</span> <span class="attr">property</span>=<span class="string">"stuName"</span> <span class="attr">jdbcType</span>=<span class="string">"VARCHAR"</span> /></span></span><br><span class="line"> <span class="tag"><<span class="name">result</span> <span class="attr">column</span>=<span class="string">"gender"</span> <span class="attr">property</span>=<span class="string">"gender"</span> <span class="attr">jdbcType</span>=<span class="string">"CHAR"</span> /></span></span><br><span class="line"> <span class="tag"><<span class="name">result</span> <span class="attr">column</span>=<span class="string">"email"</span> <span class="attr">property</span>=<span class="string">"email"</span> <span class="attr">jdbcType</span>=<span class="string">"VARCHAR"</span> /></span></span><br><span class="line"> <span class="tag"><<span class="name">result</span> <span class="attr">column</span>=<span class="string">"d_id"</span> <span class="attr">property</span>=<span class="string">"dId"</span> <span class="attr">jdbcType</span>=<span class="string">"INTEGER"</span> /></span></span><br><span class="line"> <span class="tag"><<span class="name">association</span> <span class="attr">property</span>=<span class="string">"department"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">select</span>=<span class="string">"com.guoliang.ssm.mapper.DepartmentMapper.selectByPrimaryKey"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">column</span>=<span class="string">"d_id"</span>></span><span class="tag"></<span class="name">association</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">resultMap</span>></span></span><br><span class="line"><span class="tag"><<span class="name">select</span> <span class="attr">id</span>=<span class="string">"selectByExampleWithDept"</span> <span class="attr">resultMap</span>=<span class="string">"BaseResultMapWithDept"</span> <span class="attr">parameterType</span>=<span class="string">"com.guoliang.ssm.pojo.StudentExample"</span> ></span></span><br><span class="line"><span class="tag"><<span class="name">select</span> <span class="attr">id</span>=<span class="string">"selectByPrimaryKeyWithDept"</span> <span class="attr">resultMap</span>=<span class="string">"BaseResultMapWithDept"</span> <span class="attr">parameterType</span>=<span class="string">"java.lang.Integer"</span> ></span></span><br></pre></td></tr></table></figure>]]></content>
<categories>
<category>Java</category>
</categories>
<tags>
<tag>JavaWeb</tag>
</tags>
</entry>
<entry>
<title>HuffmanTree</title>
<url>/2022/10/19/16-40-36/</url>
<content><![CDATA[<h1 id="XDOJ-哈夫曼树、Huffman编码"><a href="#XDOJ-哈夫曼树、Huffman编码" class="headerlink" title="XDOJ-哈夫曼树、Huffman编码"></a>XDOJ-哈夫曼树、Huffman编码</h1><h3 id="一、问题描述"><a href="#一、问题描述" class="headerlink" title="一、问题描述"></a>一、问题描述</h3><p>问题描述<br>假设用于通信的电文由n个字符组成,字符在电文中出现的频度(权值)为w1,w2,…,wn,试根据该权值序列构造哈夫曼树,并计算该树的带权路径长度。</p>
<p>输入说明<br>第1行为n的值,第2行为n个整数,表示字符的出现频度。</p>
<p>输出说明<br>输出所构造哈夫曼树的带权路径长度。</p>
<p>输入样例<br>8<br>7 19 2 6 32 3 21 10</p>
<p>输出样例<br>261</p>
<h3 id="二、C代码"><a href="#二、C代码" class="headerlink" title="二、C代码"></a>二、C代码</h3><figure class="highlight c"><table><tr><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span><span class="string"><stdio.h></span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span><span class="string"><stdlib.h></span></span></span><br><span class="line"><span class="keyword">typedef</span> <span class="class"><span class="keyword">struct</span>{</span></span><br><span class="line"> <span class="type">int</span> weight;</span><br><span class="line"> <span class="type">int</span> parent,lchild,rchild;</span><br><span class="line">}HTNOTE,*HuffmanTree;</span><br><span class="line"><span class="comment">//typedef char** HuffmanCode;</span></span><br><span class="line"><span class="type">void</span> <span class="title function_">Select</span><span class="params">(HuffmanTree HT, <span class="type">int</span> n, <span class="type">int</span>* s1, <span class="type">int</span>* s2)</span>;</span><br><span class="line"><span class="type">void</span> <span class="title function_">CreatHuffmanTree</span><span class="params">(HuffmanTree* HT,<span class="type">int</span> *w,<span class="type">int</span> n)</span>{</span><br><span class="line"> <span class="type">int</span> i=<span class="number">0</span>,s1=<span class="number">0</span>,s2=<span class="number">0</span>;</span><br><span class="line"> <span class="keyword">if</span>(n<=<span class="number">1</span>) <span class="keyword">return</span>;</span><br><span class="line"> <span class="type">int</span> m=<span class="number">2</span>*n<span class="number">-1</span>;</span><br><span class="line"> *HT=(HuffmanTree)<span class="built_in">malloc</span>(<span class="keyword">sizeof</span>(HTNOTE)*(m+<span class="number">1</span>));</span><br><span class="line"> <span class="keyword">if</span>(!*HT) <span class="built_in">exit</span>(<span class="number">-1</span>);</span><br><span class="line"> HuffmanTree adjust = <span class="literal">NULL</span>;</span><br><span class="line"> <span class="keyword">for</span>(adjust=*HT+<span class="number">1</span>,i=<span class="number">1</span>;i<=n;i++,adjust++,w++){</span><br><span class="line"> adjust->weight=*w;</span><br><span class="line"> adjust->parent=<span class="number">0</span>;</span><br><span class="line"> adjust->rchild=<span class="number">0</span>;</span><br><span class="line"> adjust->lchild=<span class="number">0</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">for</span>(;i<=m;i++,adjust++){</span><br><span class="line"> adjust->weight=<span class="number">0</span>;</span><br><span class="line"> adjust->parent=<span class="number">0</span>;</span><br><span class="line"> adjust->rchild=<span class="number">0</span>;</span><br><span class="line"> adjust->lchild=<span class="number">0</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">for</span>(i=n+<span class="number">1</span>;i<=m;i++){</span><br><span class="line"> Select(*HT, i<span class="number">-1</span>, &s1, &s2);</span><br><span class="line"> (*HT + s1)->parent = (*HT + s2)->parent = i;</span><br><span class="line"> (*HT + i)->lchild = s1;</span><br><span class="line"> (*HT + i)->rchild = s2;</span><br><span class="line"> (*HT + i)->weight = (*HT + s1)->weight + (*HT + s2)->weight; </span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"><span class="type">int</span> <span class="title function_">Min</span><span class="params">(HuffmanTree HT,<span class="type">int</span> n)</span>{</span><br><span class="line"> <span class="type">int</span> min=<span class="number">1000</span>;</span><br><span class="line"> <span class="type">int</span> flag;</span><br><span class="line"> <span class="keyword">for</span>(<span class="type">int</span> i=<span class="number">1</span>;i<=n;i++){</span><br><span class="line"> <span class="keyword">if</span>((HT+i)->weight<min&&(HT+i)->parent==<span class="number">0</span>){</span><br><span class="line"> flag=i;</span><br><span class="line"> min=(HT+i)->weight;</span><br><span class="line"> } </span><br><span class="line"> }</span><br><span class="line"> (HT+flag)->parent=<span class="number">1</span>;</span><br><span class="line"> <span class="keyword">return</span> flag;</span><br><span class="line">}</span><br><span class="line"><span class="type">void</span> <span class="title function_">Select</span><span class="params">(HuffmanTree HT, <span class="type">int</span> n, <span class="type">int</span>* s1, <span class="type">int</span>* s2)</span> {</span><br><span class="line"> *s1 = Min(HT, n);</span><br><span class="line"> *s2 = Min(HT, n);</span><br><span class="line">}</span><br><span class="line"><span class="type">int</span> <span class="title function_">FindWay</span><span class="params">(HuffmanTree HT,<span class="type">int</span> n,<span class="type">int</span> *w)</span>{</span><br><span class="line"> <span class="type">int</span> sum=<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<=n;i++){</span><br><span class="line"> HuffmanTree q=HT+i;</span><br><span class="line"> <span class="type">int</span> m=<span class="number">0</span>;</span><br><span class="line"> <span class="keyword">while</span>(q->parent!=<span class="number">0</span>){</span><br><span class="line"> q=HT+q->parent;</span><br><span class="line"> m++;</span><br><span class="line"> }</span><br><span class="line"> sum+=m*w[i<span class="number">-1</span>];</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> sum;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"><span class="type">int</span> <span class="title function_">main</span><span class="params">()</span>{</span><br><span class="line"> <span class="type">int</span> n;</span><br><span class="line"> <span class="built_in">scanf</span>(<span class="string">"%d"</span>,&n);</span><br><span class="line"> <span class="type">int</span> w[n];</span><br><span class="line"> <span class="keyword">for</span>(<span class="type">int</span> i=<span class="number">0</span>;i<n;i++){</span><br><span class="line"> <span class="built_in">scanf</span>(<span class="string">"%d"</span>,&w[i]);</span><br><span class="line"> }</span><br><span class="line"> HuffmanTree HT;</span><br><span class="line"> CreatHuffmanTree(&HT,w,n);</span><br><span class="line"> <span class="type">int</span> sum=FindWay(HT,n,w);</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"%d"</span>,sum);</span><br><span class="line"> <span class="comment">/*for(int i=1;i<=2*n-1;i++){</span></span><br><span class="line"><span class="comment"> printf("%d ",(HT+i)->weight);</span></span><br><span class="line"><span class="comment"> }*/</span></span><br><span class="line">}</span><br></pre></td></tr></table></figure>
]]></content>
<categories>
<category>数据结构</category>
</categories>
<tags>
<tag>C语言</tag>
</tags>
</entry>
<entry>
<title>微信早安推送,保姆级教程</title>
<url>/2022/10/20/16-21-19/</url>
<content><![CDATA[<h1 id="【最新敲简单】微信早安推送-页面总控,-JAVA版本,一键部署运行——保姆级教程"><a href="#【最新敲简单】微信早安推送-页面总控,-JAVA版本,一键部署运行——保姆级教程" class="headerlink" title="【最新敲简单】微信早安推送 +页面总控, JAVA版本,一键部署运行——保姆级教程"></a>【最新敲简单】微信早安推送 +页面总控, JAVA版本,一键部署运行——保姆级教程</h1><h2 id="一、项目简介"><a href="#一、项目简介" class="headerlink" title="一、项目简介"></a>一、项目简介</h2><p> 一个浪漫的早安推送小项目,采用Java+SpringBoot框架进行开发,SpringBoot内置tomcat使项目部署运行非常方便。此项目利用微信接口测试号实现了每天早上定时推送模板消息(天气+纪念日+每日一句,也可自己更改模板进行开发)。项目还添加了一个极简的前端页面,可以实现部署到服务器后不停止项目直接更改天气地址和直接点击立即发送。网上的使用Java开发此项目的非常少,<a href="https://blog.csdn.net/qq15347747/article/details/126521774?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522166627722516782428689277%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=166627722516782428689277&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~top_click~default-3-126521774-null-null.142%5Ev59%5Ejs_top,201%5Ev3%5Eadd_ask&utm_term=%E5%BE%AE%E4%BF%A1%E6%8E%A8%E9%80%81&spm=1018.2226.3001.4187">也非常感谢这篇文章让我少绕了很多弯路</a>,其实这个博主写的已经非常详细了,我的消息模板也是搬过来的这位博主的,此文就来丰富一下Java版本的选择吧。先来看几张结果:<br>![Alt](<a href="https://img-blog.csdnimg.cn/98929bdbf4cb42769a930cd0df26486c.png#pic_center#pic_center">https://img-blog.csdnimg.cn/98929bdbf4cb42769a930cd0df26486c.png#pic_center#pic_center</a> =300x400)<img src="https://img-blog.csdnimg.cn/355d14396f4841ae8c114ce7e70af05b.png#pic_center" alt="在这里插入图片描述"></p>
<h2 id="二、本地克隆项目"><a href="#二、本地克隆项目" class="headerlink" title="二、本地克隆项目"></a>二、本地克隆项目</h2><p> 项目仓库在Gitee::link:<a href="https://gitee.com/li-haoaa/romantic-wechat-push%EF%BC%8C%E8%BF%99%E9%87%8C%E6%8F%90%E4%BE%9B%E5%87%A0%E7%A7%8D%E5%85%8B%E9%9A%86%E6%96%B9%E5%BC%8F%EF%BC%9A">https://gitee.com/li-haoaa/romantic-wechat-push,这里提供几种克隆方式:</a></p>
<p>1、直接打开链接,点击下载zip即可,然后解压缩,在idea或者eclipse里面打开项目就好了。</p>
<p>2、利用idea内嵌的组件,依次点击上方VCS、Get From Version Control,在弹框中粘贴上去上方的网址即可。不同版本idea基本一致。eclipse也有此功能,可直接网上搜。这里还是建议大家采用IDEA,在maven上有很大优势。<br>![在这里插入图片描述](<a href="https://img-blog.csdnimg.cn/bb47716806164a30b9f05b5e100ad8f2.png#pic_center">https://img-blog.csdnimg.cn/bb47716806164a30b9f05b5e100ad8f2.png#pic_center</a> =160x200)<br>3、打开\wechatPushing\src\main\resources\application.yml,配置文件如下图:我们接下来要填充下划线部分,记得把纪念日改了。<br><img src="https://img-blog.csdnimg.cn/da9c32fcfaec44068c7a7d0c4731e6e6.png#pic_center" alt="alt"></p>
<h2 id="三、申请各种接口"><a href="#三、申请各种接口" class="headerlink" title="三、申请各种接口"></a>三、申请各种接口</h2><p> 简单介绍一下工作原理,你可以把刚才加载的项目理解为小的后台服务器,我们设定了机制,在每天设定的时间它会自动调用方法去第三方网站获取当日的天气和每日一句名言,没错,就是通过api调用。然后将请求过来的数据进行各种处理,转化成一个微信接口能听懂的语言发送过去,微信再进行模板处理把消息推送出去,我们这一步要做的就是申请这些第三方网站的api和微信接口api。</p>
<h3 id="1、微信接口申请"><a href="#1、微信接口申请" class="headerlink" title="1、微信接口申请"></a>1、微信接口申请</h3><ul>
<li>打开<a href="http://mp.weixin.qq.com/debug/cgi-bin/sandboxinfo?action=showinfo&t=sandbox/index">微信公众平台</a>,扫码登录按照要求完成认证。之后得到这一步:<br><img src="https://img-blog.csdnimg.cn/774f296baf0a42bab142c6e73c5df72a.png#pic_center" alt="在这里插入图片描述"></li>
</ul>
<p>appID和appsecret就是我们需要的填到上方提到的配置文件中。你可以简单理解为接口的账号和密码。</p>
<ul>
<li><p>然后你和要推送的对象(lover)扫码关注,下图中的微信号填到配置文件的receiver中,注意前面的-不要去掉,直接粘贴到双引号中即可。如果有第二个,就把下方的#删除直接粘贴即可。(如果你学过springboot就知道原因)</p>
</li>
<li><p><img src="https://img-blog.csdnimg.cn/7ca787eae60149e58ae94495ae1fe3f9.png#pic_center" alt="在这里插入图片描述"></p>
</li>
<li><p>最后需要给你的微信添加消息模板,这里的模板是用的别人的,有想法的也可以自己修改。直接点击新增测试模板,把下面的复制进去,将生日名字改了就OK,这里面双括号包含的就是根据服务器发来的请求进行动态填充的部分,其他部分是静态不变的。你了解后可以充分想象自定义模板。然后把模板ID填到上面配置文件中的templateId中就好。<br><img src="https://img-blog.csdnimg.cn/31a2b2add1db4866b337c49ed7f631af.png#pic_center" alt="在这里插入图片描述"></p>
</li>
</ul>
<figure class="highlight xml"><table><tr><td class="code"><pre><span class="line">{{first.DATA}}</span><br><span class="line"></span><br><span class="line">城市:{{city.DATA}}</span><br><span class="line"></span><br><span class="line">实况天气:{{weather.DATA}}</span><br><span class="line">气温:{{minTemperature.DATA}} ~ {{maxTemperature.DATA}}</span><br><span class="line">风速:{{wind.DATA}}</span><br><span class="line">湿度:{{wet.DATA}}</span><br><span class="line">今天~后天:{{day1_wea.DATA}},{{day2_wea.DATA}},{{day3_wea.DATA}}</span><br><span class="line"></span><br><span class="line">♥在一起♥: {{togetherDate.DATA}}</span><br><span class="line"></span><br><span class="line">距离XX生日:{{birthDate1.DATA}}</span><br><span class="line">距离XX生日:{{birthDate2.DATA}}</span><br><span class="line"></span><br><span class="line">{{note_En.DATA}}</span><br><span class="line"></span><br><span class="line">{{note_Zh.DATA}}</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<h3 id="2、天气API接口申请"><a href="#2、天气API接口申请" class="headerlink" title="2、天气API接口申请"></a>2、天气API接口申请</h3><p> <a href="https://yikeapi.com/account/index">点击这里跳转去申请</a>,注册成功后会出现<br><img src="https://img-blog.csdnimg.cn/222ee4875f35462c981565087209d83b.png#pic_center" alt="在这里插入图片描述"></p>
<p>把配置文件中的Weather模块appid和appsecret补充上去,把city进行修改,虽然提供了前端页面修改城市,但还是建议大家通过这里修改,因为api原因前端页面修改的有时会出现一些bug,我后期会考虑使用百度的天气api接口替换可以改善这个问题。</p>
<h3 id="3、名言API接口申请"><a href="#3、名言API接口申请" class="headerlink" title="3、名言API接口申请"></a>3、名言API接口申请</h3><p><a href="https://www.apispace.com/eolink/api/myjj/apiDocument?apiStatus=PUBLISH®ister=1">点击这里跳转注册登录</a>,然后点击购买套餐,有一个免费的套餐,新用户也有一个1000次的可以免费购买。之后点击右上角头像,进入这个页面<br><img src="https://img-blog.csdnimg.cn/6f26e2c960634915bf4a192330f97573.png#pic_center" alt="在这里插入图片描述"></p>
<p>复制下来Token,粘贴到配置文件中的名言警句token处,这个网站还提供了历史上的今天等很多实用的api,想要自己改消息模板的都可以使用。</p>
<h2 id="四、项目测试"><a href="#四、项目测试" class="headerlink" title="四、项目测试"></a>四、项目测试</h2><p>如果你本地jdk环境没有问题,idea也没有问题,那么你的项目现在就可以运行了,打开项目中的WechatPushingApplication,点击运行即可。<br><img src="https://img-blog.csdnimg.cn/e54707e2d90b4f849ad1c26e34622c34.png#pic_center" alt="在这里插入图片描述"></p>
<p>然后打开浏览器,输入“<a href="http://localhost:60001/%E2%80%9D%EF%BC%8C%E5%8F%AA%E6%9C%89%E4%BD%A0%E7%9A%84%E9%A1%B9%E7%9B%AE%E8%BF%90%E8%A1%8C%E8%B5%B7%E6%9D%A5%E8%BF%99%E4%B8%AA%E7%95%8C%E9%9D%A2%E6%89%8D%E8%83%BD%E8%AE%BF%E9%97%AE%E8%BF%9B%E5%8E%BB%E3%80%82%E7%82%B9%E5%87%BB%E7%AB%8B%E5%8D%B3%E5%8F%91%E9%80%81%E5%8D%B3%E5%8F%AF%E8%BF%9B%E8%A1%8C%E6%B5%8B%E8%AF%95%E3%80%82%E5%A6%82%E6%9E%9C%E4%BD%A0%E7%9A%84%E5%BE%AE%E4%BF%A1%E8%83%BD%E6%AD%A3%E5%B8%B8%E6%94%B6%E5%88%B0%E6%8E%A8%E9%80%81%E6%B6%88%E6%81%AF%E5%B0%B1%E8%AF%B4%E6%98%8E%E6%B2%A1%E6%9C%89%E9%97%AE%E9%A2%98%E4%BA%86%E3%80%82">http://localhost:60001/”,只有你的项目运行起来这个界面才能访问进去。点击立即发送即可进行测试。如果你的微信能正常收到推送消息就说明没有问题了。</a><br><img src="https://img-blog.csdnimg.cn/c6896d48bf4049e39055853cf9b55076.png#pic_center" alt="在这里插入图片描述"></p>
<p>但是目前你只能手动点击发送,或者让项目在你的电脑上不停运行,每天定时自动推送,定时时间在MessageController中进行修改,下图是项目默认的每天7:30推送。三个数字分别是秒分时,其他的较为复杂的规则大家可以搜索@Scheduled用法。</p>
<p><img src="https://img-blog.csdnimg.cn/ac1c4fd27d754b19b5b9d2e49f82001e.png#pic_center" alt="在这里插入图片描述"></p>
<h2 id="五、云上部署运行"><a href="#五、云上部署运行" class="headerlink" title="五、云上部署运行"></a>五、云上部署运行</h2><p>虽然已经成功,但是目前为止你必须手动点击发送或者让项目不停的在你的电脑上运行实现定时发送,这显然和你预期的“自动定时发送”不一致,要想实现自动定时发送需要我们将项目部署到云服务器上。</p>
<h3 id="1、初始服务器"><a href="#1、初始服务器" class="headerlink" title="1、初始服务器"></a>1、初始服务器</h3><p><a href="https://url.cn/646RdtyS">腾讯云特惠链接</a>,趁着活动可以购买或者体验云服务器,建议选择轻量应用服务器,方便高效还便宜。镜像就选择宝塔Linux就好,宝塔面板自动搭建好非常的方便。<br>![在这里插入图片描述](<a href="https://img-blog.csdnimg.cn/87fcd8b3376e459fbdf1b9d0248dfe2f.png#pic_center">https://img-blog.csdnimg.cn/87fcd8b3376e459fbdf1b9d0248dfe2f.png#pic_center</a> =300x300)</p>
<p>等待几分钟初始化完成进入轻量应用服务器控制台点击你自己的实例就会到这个界面:<br><img src="https://img-blog.csdnimg.cn/770650babc6b44c88594238d47568afc.png#pic_center" alt="在这里插入图片描述"></p>
<h3 id="2、进入宝塔面板管理服务器"><a href="#2、进入宝塔面板管理服务器" class="headerlink" title="2、进入宝塔面板管理服务器"></a>2、进入宝塔面板管理服务器</h3><p>点击登录之后会一键登录到你的远程机,输入命令sudo /etc/init.d/bt default会获取到你的面板账号和密码<br><img src="https://img-blog.csdnimg.cn/6b9c37643ca1419f8b52623f46bc03ee.png#pic_center" alt="在这里插入图片描述"></p>
<p>打开得到的外网面板地址,用账号和密码登录就进入了宝塔面板管理页面,第一次登录需要安装一些软件环境,根据指导安装即可。<br><img src="https://img-blog.csdnimg.cn/5fabfc56a6ff48a4a0d1b95512ed5399.png#pic_center" alt="在这里插入图片描述"></p>
<p>然后进入软件商店,安装Java项目一键部署</p>
<p><img src="https://img-blog.csdnimg.cn/0cd1461ac5ef4595ad57ea301526be72.png#pic_center" alt="在这里插入图片描述"></p>
<p>然后从首页进入一键部署:</p>
<p><img src="https://img-blog.csdnimg.cn/cb476e93c02f490cac6a0170760c7473.png#pic_center" alt="在这里插入图片描述"></p>
<p>进去先安装tomcat8,虽然我们的springboot的jar包已经包含tomcat,我们在这里安装tomcat的目的是他会帮我们自动安装jdk8。<br><img src="https://img-blog.csdnimg.cn/cbad5b823c0048c1bf371fd80394b59c.png#pic_center" alt="在这里插入图片描述"></p>
<h3 id="3、上传项目并部署"><a href="#3、上传项目并部署" class="headerlink" title="3、上传项目并部署"></a>3、上传项目并部署</h3><p>打开idea,右侧maven栏,选择clean和package然后点击上方运行进行打包。之后target中就会出现jar包,右键open in explore在文件夹中打开<br>![在这里插入图片描述](<a href="https://img-blog.csdnimg.cn/96e4552130e34b4486ee57a7186b0a68.png#pic">https://img-blog.csdnimg.cn/96e4552130e34b4486ee57a7186b0a68.png#pic</a> =250x200)![在这里插入图片描述](<a href="https://img-blog.csdnimg.cn/d33fd2380f524d56a331b5806c7b5778.png#pic">https://img-blog.csdnimg.cn/d33fd2380f524d56a331b5806c7b5778.png#pic</a> =250x200)</p>
<p>然后打开宝塔面板的文件,找到/www/wwwroot目录,将刚刚打好的jar包上传。<br><img src="https://img-blog.csdnimg.cn/dde5324cb1724f6ca5a3076e77da5f2e.png#pic_center" alt="在这里插入图片描述"></p>
<p>进入java一键部署页面,选择springboot,添加项目,选择好jdk,记住分配的端口号。(这里有时经常部署不上去,策略一:多试几次,策略二:复制执行命令,自己粘贴到服务器终端执行)<br>![在这里插入图片描述](<a href="https://img-blog.csdnimg.cn/bdd86a32baed4bd7a2f8ef96b7cff7ba.png#pic_center">https://img-blog.csdnimg.cn/bdd86a32baed4bd7a2f8ef96b7cff7ba.png#pic_center</a> =500x400)</p>
<p>最后,进入腾讯云控制台,打开防火墙,将刚刚的端口添加进去即可,大功告成了。<br><img src="https://img-blog.csdnimg.cn/8991ff31f3074537be47646f0c572768.png#pic_center" alt="在这里插入图片描述"></p>
<p>这样就完成了自动推送,如果你想更改天气地址或者立即推送消息,进入:http://公网ip:端口号/,公网ip就是腾讯云控制台顶端的ip地址,端口号是上一步的端口号。这样你可以进入熟悉的页面。<br><img src="https://img-blog.csdnimg.cn/fd5ceffa41154087b34c66f58d1bcaf9.png#pic_center" alt="在这里插入图片描述"><br><img src="https://img-blog.csdnimg.cn/040eb2534ba741c19ec4eec17f357c9c.png#pic_center" alt="在这里插入图片描述"></p>
<h2 id="六、项目完善"><a href="#六、项目完善" class="headerlink" title="六、项目完善"></a>六、项目完善</h2><p>如果你有经验,完全可以丰富这个项目,比如说使用数据库系统,把每次推送记录进去,然后在前端页面做出推送记录模块。也可以自定义修改api,接入一些新的功能……</p>
]]></content>
</entry>
<entry>
<title>Nginx+Nacos2.2.0搭建集群遇坑指南</title>
<url>/2023/01/08/17-13-29/</url>
<content><![CDATA[<h1 id="Nginx-Nacos2-2-0搭建集群遇坑指南"><a href="#Nginx-Nacos2-2-0搭建集群遇坑指南" class="headerlink" title="Nginx+Nacos2.2.0搭建集群遇坑指南"></a>Nginx+Nacos2.2.0搭建集群遇坑指南</h1><p>这几天刚刚开始学习Nacos,恰好重磅升级的Nacos2.2.0正式版刚刚发布不久,我直接忽略了老师讲解使用的1.1.4版本和SpringCloudAlibaba2.2.9版本推荐的2.1.0,直接选择了2.2.0,后者选择2.1.0和2.2.0的关系倒不是很大,但是1.x和2.x有太多的不一样,导致我花了两整天的时间捣鼓遇到的一个又一个坑。</p>
<h2 id="坑一:64位jdk8"><a href="#坑一:64位jdk8" class="headerlink" title="坑一:64位jdk8+"></a>坑一:64位jdk8+</h2><p>启动Nacos后通过start.out看到总是报错,错误信息是:</p>
<figure class="highlight xml"><table><tr><td class="code"><pre><span class="line">org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'instanceOperatorClientImpl'</span><br><span class="line">Caused by: java.lang.UnsatisfiedLinkError: libjawt.so: 无法打开共享对象文件: 没有那个文件或目录</span><br><span class="line">此处省略无数异常 大概都是springboot启动的错误,各种Error creating”</span><br></pre></td></tr></table></figure>
<p>我又安装了Nacos1.1.4尝试,结果成功启动。那这就很可能是环境问题,打开Nacos官网手册一看,首页就是:</p>
<img src="https://img-blog.csdnimg.cn/43c2b1f07f9e4e9a8721f104415ff843.png" alt="image-20230108155841778" style="zoom:70%;" />
<p>然后我就查了我在linux上的环境,也没有什么错误啊,直到过了很久才发现我的jdk是x86即32位,换了x64之后成功启动。</p>
<h2 id="坑2:Nacos2-x使用grpc通信"><a href="#坑2:Nacos2-x使用grpc通信" class="headerlink" title="坑2:Nacos2.x使用grpc通信"></a>坑2:Nacos2.x使用grpc通信</h2><p>在Nacos集群,Nginx反向代理都完成后,我测试了Nacos作为配置中心的功能,结果很完美。就当我测试最后一步作为服务注册中心功能时,微服务又报错:</p>
<figure class="highlight xml"><table><tr><td class="code"><pre><span class="line">com.alibaba.nacos.api.exception.NacosException: Client not connected, current status:STARTING</span><br></pre></td></tr></table></figure>
<p>nginx反向代理配置:</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">upstream nacoscluster{</span><br><span class="line"> server 192.168.241.129:3333;</span><br><span class="line"> server 192.168.241.129:4444;</span><br><span class="line"> server 192.168.241.129:5555;</span><br><span class="line"> }</span><br><span class="line"> server{</span><br><span class="line"> listen 1111;</span><br><span class="line"> server_name 192.168.241.129;</span><br><span class="line"> </span><br><span class="line"> location / {</span><br><span class="line"> proxy_pass http://nacoscluster;</span><br><span class="line"> } </span><br></pre></td></tr></table></figure>
<p>微服务配置:</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">spring:</span><br><span class="line"> application:</span><br><span class="line"> name: nacos-payment-provider</span><br><span class="line"> cloud:</span><br><span class="line"> nacos:</span><br><span class="line"> discovery:</span><br><span class="line"> server-addr: 192.168.241.129:1111</span><br></pre></td></tr></table></figure>
<p>配置看起来和老师一模一样,那就还是版本新特性问题,其实Nacos2.x服务端是支持http2和grpc两种通信方式的,但是我们Maven中导入的客户端版本是2.1.0,client客户端在2.x版本中使用 grpc 调用,那显然我们使用nginx进行http代理是不靠谱的。</p>
<p><img src="https://img-blog.csdnimg.cn/155d968dff4144f585a5f98a67a33887.png" alt="image-20230108161721489"></p>
<h3 id="解决方法一,使用http通信:"><a href="#解决方法一,使用http通信:" class="headerlink" title="解决方法一,使用http通信:"></a>解决方法一,使用http通信:</h3><p>那第一种解决方法就是直接把客户端版本降低,替换成1.x版本,问题成功解决:</p>
<figure class="highlight xml"><table><tr><td class="code"><pre><span class="line"><span class="tag"><<span class="name">dependency</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">groupId</span>></span>com.alibaba.nacos<span class="tag"></<span class="name">groupId</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">artifactId</span>></span>nacos-client<span class="tag"></<span class="name">artifactId</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">version</span>></span>1.4.3<span class="tag"></<span class="name">version</span>></span></span><br><span class="line"><span class="tag"></<span class="name">dependency</span>></span></span><br></pre></td></tr></table></figure>
<p>但是,既然选择了Nacos2.x服务端,那最好还是用对应的2.x客户端,毕竟据官方宣传Nacos2.0的性能相较于1.x提升近10倍,2.x默认使用grpc调用通信原因就是grpc的低延迟和高吞吐量特性。</p>
<h3 id="解决方法二,Nginx使用TCP代理:"><a href="#解决方法二,Nginx使用TCP代理:" class="headerlink" title="解决方法二,Nginx使用TCP代理:"></a>解决方法二,Nginx使用TCP代理:</h3><p>官网有这样一句话<strong>使用VIP/nginx请求时,需要配置成TCP转发,不能配置http2转发,否则连接会被nginx断开。</strong>Nginx如何实现TCP转发有很多博文,这里就不写了,主要是需要添加一个插件–with-stream。</p>
<p>nginx添加配置(http的不用动,浏览器访问依旧需要):</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">stream{</span><br><span class="line"> upstream nacoscluster{</span><br><span class="line"> server 192.168.241.129:4333;</span><br><span class="line"> server 192.168.241.129:5444;</span><br><span class="line"> server 192.168.241.129:6555;</span><br><span class="line"> }</span><br><span class="line"> server{</span><br><span class="line"> listen 2111;</span><br><span class="line"> proxy_pass nacoscluster; </span><br><span class="line">}</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>注意这个stream是和上面的http平级的。至于端口为什么比http里面的多1000,是因为我们上面提到的Nacos2.x客户端和服务端使用grpc调用,这里的端口是grpc端口,GRPC port = 主端口 + grpc端口偏移量,Nacos源码中设置偏移量默认1000。</p>
<p>微服务注册配置是不需要修改的,因为微服务注册配置的是主端口,所以还是1111。</p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">spring:</span><br><span class="line"> application:</span><br><span class="line"> name: nacos-payment-provider</span><br><span class="line"> cloud:</span><br><span class="line"> nacos:</span><br><span class="line"> discovery:</span><br><span class="line"> server-addr: 192.168.241.129:1111</span><br></pre></td></tr></table></figure>
<p>最后,终于完成了Nacos2.2.0+Nginx实现Nacos集群的配置,成功将微服务注册:</p>
<p><img src="https://img-blog.csdnimg.cn/26b85593b744411b80fb894c01e5f2b7.png" alt="image-20230108165109903"></p>
<h2 id="新版本选用问题"><a href="#新版本选用问题" class="headerlink" title="新版本选用问题"></a>新版本选用问题</h2><p>我在使用东西的时候总爱去使用一些较为新的版本,与老师使用的不同,很可能就会导致很多兼容问题。但是我感觉遇到这种问题通过自己一步步的解决可能比使用与老师一样的版本按部就班的要更有意义。因为在微服务时代,性能的优化是非常重要的,新版本肯定在性能上比旧版本有不小提升,就比如Nacos2.x比Nacos1.x有近10倍性能提升,但是新版本也不是随便使用的,你不能使用一个SpringCloudAlibaba低版本与最新的Nacos或者其他组件去搭建,那问题肯定会更多,还是要遵循官方的版本关系建议。</p>
]]></content>
<categories>
<category>Java</category>
</categories>
</entry>
</search>